Karateka (Broderbund, 1984), by LoGo from http://www.hackzapple.com/phpBB2/viewtopic.php?t=420 The first masterpiece of Jordan Mechner! This is for educational purposes only as the game is heavily on-disk protected: a real challenge! PROTECTION TYPE The disk cannot be copied with Locksmith Fast disk backup. It relocated code in memory all the time, especially in the annoying areas: $0200 (keyboard buffer), $0300 (the vectors area), $0400 (text area) And, it uses a sort of spiralling we will detail with the code at $4000! BOOT TRACE - 9600loadADR STY $02 STA $03 L1038 LDA $C08C,X BPL L1038 L103D CMP #$F5 BNE L1038 L1041 LDA $C08C,X BPL L1041 L1046 CMP #$D5 BNE L103D L104A LDA $C08C,X BPL L104A CMP #$DA BNE L1046 L1053 LDA $C08C,X BPL L1053 ROL STA $00 L105B LDA $C08C,X BPL L105B AND $00 STA ($02),Y INY BNE L1053 ASL $FFFF L106A LDA $C08C,X BPL L106A CMP #$FB BNE L102C INC $03 DEC $01 BNE L1053 * * MOVE ARM AND GO TO NEXT BOOT PHASE * LDA #$02 ; MOVE ARM JSR L10B2 JMP L0300 L10B2 STA $26 L10B4 LDA $FF STA $27 SEC SBC $26 BEQ L10E9 BCS L10C3 INC $FF BCC L10C5 L10C3 DEC $FF L10C5 JSR L10DE JSR L10EA LDA $27 AND #$03 ASL ORA $2B TAY LDA $C080,Y JSR L10EA BEQ L10B4 JSR L10EA L10DE LDA $FF AND #$03 ASL ORA $2B TAY LDA $C081,Y L10E9 RTS L10EA LDA #$28 JMP WAIT * * Karateka * (c) Broderbund, 1984 * (k) the Hackzapple team, 2011 * * Update boot4 phase to load phase5 loadADR2 = $4000 L0300 = * L0342 LDX #slot16 LDA #nbSEC STA $01 LDY #loadADR2 STY $02 STA $03 L034E LDA $C08C,X BPL L034E L0353 CMP #$F5 BNE L034E L0357 LDA $C08C,X BPL L0357 L035C CMP #$D5 BNE L0353 L0360 LDA $C08C,X BPL L0360 CMP #$DA BNE L035C L0369 LDA $C08C,X BPL L0369 ROL STA $00 L0371 LDA $C08C,X BPL L0371 AND $00 STA ($02),Y INY BNE L0369 ASL $FFFF ; IRQV+1 L0380 LDA $C08C,X BPL L0380 CMP #$FB BNE L0342 INC $03 DEC $01 BNE L0369 rts BOOT 4 @ $4000 This is where the smart code resides, a sort of spiralling! It loads the next boot phase at $5000 and executes it... Boring, isn't it? TYP BIN ORG $004000 MX %11 L4000 PHA LDA #$02 ; We are on track 1 (or phase 2) STA $1F LDA #$04 ; We want track 2 (or phase 4) JSR L40BA ; MOVE ARM LDY #$00 STY $04 L400E STY $05 LDA L4040,Y ; Table of @ to load BEQ L401D ; There's only one at $5000 JSR L4021 ; READ DATA LDY $05 INY BNE L400E L401D PLA JMP $5000 ; AND JUMPS TO NEXT PHASE * * READ DATA * L4021 LDY #$00 L4023 STY $06 PHA JSR L4042 ; Read nibbles LDY $06 CLC LDA $1F ADC L4148,Y ; Determine phase order +/- JSR L40BD ; And move arm PLA CLC ADC #$02 LDY $06 INY CPY #$04 BCC L4023 RTS L4040 HEX 5000 * READ DATA L4042 PHA ; Sets all markers LDA $04 AND #$07 TAY LDA L414C,Y STA $00 LDA $04 LSR ORA #$AA STA $01 LDA $04 ORA #$AA STA $02 LDA L4154 STA $03 PLA INC $04 LDX #$02 STA $07 ; Where to load STX L4069+1 L4069 LDX #$02 STX $0A LDY #$00 LDA $07 STY $08 STA $09 LDX $0306 L4078 LDA $C08C,X BPL L4078 L407D CMP $00 BNE L4078 L4081 LDA $C08C,X BPL L4081 L4086 CMP $01 BNE L407D L408A LDA $C08C,X BPL L408A CMP $02 BNE L4086 L4093 LDA $C08C,X BPL L4093 ROL STA $0B L409B LDA $C08C,X BPL L409B AND $0B STA ($08),Y INY BNE L4093 ASL $FFFF L40AA LDA $C08C,X BPL L40AA CMP $03 BNE L4069 INC $09 DEC $0A BNE L4093 RTS * * SMART MOVE ARM * L40BA LDX #$13 DB $2C L40BD LDX #$0A STX L4122+1 STA L4145 CMP $1F BEQ L411E LDA #$00 STA L4146 L40CE LDA $1F STA L4147 SEC SBC L4145 BEQ L410E BCS L40E1 EOR #$FF INC $1F BCC L40E5 L40E1 ADC #$FE DEC $1F L40E5 CMP L4146 BCC L40ED LDA L4146 L40ED CMP #$0C BCS L40F2 TAY L40F2 SEC JSR L4112 LDA L412D,Y JSR L4122 LDA L4147 CLC JSR L4114 LDA L4139,Y JSR L4122 INC L4146 BNE L40CE L410E JSR L4122 CLC L4112 LDA $1F L4114 AND #$03 ROL ORA $0306 TAX LDA $C080,X L411E LDX $0306 RTS L4122 LDX #$13 L4124 DEX BNE L4124 SEC SBC #$01 BNE L4122 RTS * THE DISK II TEMPOS L412D HEX 01302824201E1D1C1C1C1C1C L4139 HEX 702C26221F1E1D1C1C1C1C1C * L4145 DB $00 L4146 DB $00 L4147 DB $00 * L4148 HEX 01FF0101 * L414C HEX D5B5B7BCDFD4B4DB * L4154 DB $F5 DS $A6 DB $39 DB $00 DB $12 DB $40 DB $20 BOOT 4 @ $4000 REWRITTEN We need to get the code at $5000. That is the "raison d'ĂȘtre" of the following code... * * Karateka * (c) Broderbund, 1984 * (k) the Hackzapple team, 2011 * * Update boot4 phase to load phase5 MX %11 TYP BIN ORG $004000 LST OFF slot16 = $60 L4000 PHA ; save A LDA #$02 ; Tell we are on phase 2 STA $1F LDA #$04 ; We want phase 4 JSR L40BA LDY #$00 STY $04 L400E STY $05 LDA L4040,Y BEQ L401D JSR L4021 LDY $05 INY BNE L400E L401D PLA * JMP $5000 ; Next boot phase JMP $FF59 L4021 LDY #$00 L4023 STY $06 PHA JSR L4042 LDY $06 CLC LDA $1F ADC L4148,Y JSR L40BD PLA CLC ADC #$02 LDY $06 INY CPY #$04 BCC L4023 RTS L4040 HEX 5000 L4042 PHA LDA $04 AND #$07 TAY LDA L414C,Y STA $00 LDA $04 LSR ORA #$AA STA $01 LDA $04 ORA #$AA STA $02 LDA L4154 STA $03 PLA INC $04 LDX #$02 STA $07 STX L4069+1 L4069 LDX #$02 STX $0A LDY #$00 LDA $07 STY $08 STA $09 * LDX $0306 LDX #slot16 L4078 LDA $C08C,X BPL L4078 L407D CMP $00 BNE L4078 L4081 LDA $C08C,X BPL L4081 L4086 CMP $01 BNE L407D L408A LDA $C08C,X BPL L408A CMP $02 BNE L4086 L4093 LDA $C08C,X BPL L4093 ROL STA $0B L409B LDA $C08C,X BPL L409B AND $0B STA ($08),Y INY BNE L4093 ASL $FFFF L40AA LDA $C08C,X BPL L40AA CMP $03 BNE L4069 INC $09 DEC $0A BNE L4093 RTS L40BA LDX #$13 DB $2C L40BD LDX #$0A STX L4122+1 STA L4145 CMP $1F BEQ L411E LDA #$00 STA L4146 L40CE LDA $1F STA L4147 SEC SBC L4145 BEQ L410E BCS L40E1 EOR #$FF INC $1F BCC L40E5 L40E1 ADC #$FE DEC $1F L40E5 CMP L4146 BCC L40ED LDA L4146 L40ED CMP #$0C BCS L40F2 TAY L40F2 SEC JSR L4112 LDA L412D,Y JSR L4122 LDA L4147 CLC JSR L4114 LDA L4139,Y JSR L4122 INC L4146 BNE L40CE L410E JSR L4122 CLC L4112 LDA $1F L4114 AND #$03 ROL * ORA $0306 ORA #slot16 TAX LDA $C080,X *L411E LDX $0306 L411E LDX #slot16 RTS L4122 LDX #$13 L4124 DEX BNE L4124 SEC SBC #$01 BNE L4122 RTS L412D HEX 01302824201E1D1C1C1C1C1C L4139 HEX 702C26221F1E1D1C1C1C1C1C L4145 DB $00 L4146 DB $00 L4147 DB $00 L4148 HEX 01FF0101 L414C HEX D5B5B7BCDFD4B4DB L4154 DB $F5 DS $A6 DB $39 DB $00 DB $12 DB $40 DB $20 BOOT 5 @ $5000 Now, we have the code at $5000, let's analyze it... There's a lot of garbage I think! * * Karateka * (c) Broderbund, 1984 * (k) the Hackzapple team, 2011 * * Boot5 at $5000 MX %11 TYP BIN ORG $005000 LST OFF slot16 = $60 * * $001F : current phase * $0306 : slot * 16 * * * A on entry * <80 : phase to start load from * =>80 : initial load * * Y on entry * contains index in load table * L5000 BPL L5005 ; check Acc JMP L5300 ; initial load L5005 CMP #$10 BEQ L5014 ASL ASL ASL ADC #$0E LDY #$30 JMP L501D DB $00 L5014 LDA #$08 LDY #$00 NOP NOP NOP NOP NOP L501D JSR L5500 PLA PLA ; Change return address LDX #$00 ; Copy ZP L5024 LDA $4F00,X STA $00,X INX BNE L5024 LDY #$00 ; Clear parts of HGR2 LDA #$40 LDX #$20 STY $3C STA $3D LDA #$00 L5038 LDY #$78 L503A STA ($3C),Y INY BPL L503A LDY #$F8 L5041 STA ($3C),Y INY BNE L5041 INC $3D DEX BNE L5038 LDA #$00 ; Oh, A = 0 RTS ; Return * * ONLY GARBAGE * DS $B2 L5100 HEX CED004A5CFF011A5DA85CAA5DB85CB20 HEX 2CF120FDFEA6D860203AFF4C15F1A0CE HEX 843CC8843EA000843D843F60B5CA953C HEX B44C943ECA10F5A53ED002C63FC63E60 HEX 86D838A2FFB54DF5CB95CFE8F0F7201E HEX F120CDFEA201202CF1A91A20CFFEA6D8 HEX 6020C4E34C3AFFA5FCD0034CA5E8C6FC HEX 60A9FF85A06046A06024A01019A9A320 HEX EDFDA001B1DCAAC8B1DC201BE5A9A04C HEX EDFDA5DCA4DD60C1007FD1CCC7CFCEC5 HEX 9A988D969593BFB232120FBCB0ACBE35 HEX 0C6130100BDDFBA00020C7E7A9A04CED HEX FD0000000000000000A44AA54B48C4DA HEX E5DBB01C6884D085D1A0FFC8B1D030FB HEX C940F0F7C8C8B1D04888B1D0A868D0DD HEX 68A000B1D030054AF008A9A420EDFDC8 HEX D0F1A9BD4CEDFD91DAE8B59FF0304CD5 HEX F3A03007A5DCA4DD207DF120C9F1A6D8 HEX 4CB7F1E8E8B59FF01F4CE0F33007A5DC HEX A4DD207DF120C9F1A6D84C09F4E86020 HEX 15E7E6CED002E6CF60205BF2D0152053 HEX F2D0102082E7206FE750032082E72059 HEX E756504C36E720C9EF154F100520C9EF HEX 354F955010ED4CC9EF2015E7A4FBA5CE HEX 995F01A5CF4C66E9995001883051B940 HEX 01D550D0F6B95001D578D0EFC6FBB941 HEX 01994001B95101995001B9C10199C001 HEX B9D10199D001B96101996001B9710199 HEX 7001B98101998001B99101999001B9A1 HEX 0199A001B9A10199A001C8C4FB90BF60 HEX E8A90048B55038E90385CEB578E90085 HEX CF68A00091CEE860C985B0034CC0E4A0 * * INITIAL LOAD * L5300 LDX #$FF ; Stack pointer TXS LDY #$70 ; index in load table LDA #$36 ; and target phase JSR L5500 LDX #$00 ; clear ZP TXA L530D STA $00,X INX BNE L530D LDA #$01 ; And some inits STA $86 STA $4F LDA #$00 STA $D0 LDA #$FF STA $D2 JMP $0200 ; Next please DS $DD * * LOAD INDEX * * Y=0 * A=10 L5400 HEX A0A1A2A3A4A5A6A7A8A9AAAB HEX ACADAEAFB0B1B2B3B4B5B6B7 HEX B8B9BABBBCBDBEBF40404040 HEX 000000000000000000000000 * Y=30 * A=A*8+E L5430 HEX 101112131415161718191A1B HEX 1C1D1E1FA0A1A2A3A4A5A6A7 HEX A8A9AAABACADAEAFB0B1B2B3 HEX B4B5B6B7B8B9BABBBCBDBEBF HEX 000000000000000000000000 HEX 00000000 * Y=70 * A=36 L5470 HEX 08090A0B0C0D0E0F60616263 HEX 6465666768696A6B6C6D6E6F HEX 707172737475767778797A7B HEX 7C7D7E7F8081828384858687 HEX 88898A8B8C8D8E8F90919293 HEX 9495969798999A9B9C9D9E9F HEX 000000000000000000000000 HEX 000000000000000000000000 HEX 000000000000000000000000 HEX 000000000000000000000000 HEX 000000000000000000000000 HEX 000000000000000000000000 * * * L5500 PHA ; Save phase STY $88 ; Save index JSR L5700 ; Move arm LDX #$00 ; Copy load table LDY $88 L550A LDA L5400,Y STA L5703,X INY INX CPX #$0C BCC L550A JSR L5530 ; Load data LDA $88 ; Next load table CLC ADC #$0C TAY LDA L5400,Y ; Unless we reached the end BEQ L552B PLA CLC ADC #$02 BNE L5500 DB $00 L552B JMP L5550 PLA RTS * * Set markers * L5530 LDA |$001F ; Set markers LSR LDX #$03 L5536 AND #$0F TAY LDA L5610,Y STA $A0,X INY TYA DEX BPL L5536 JMP L570F ; And load DB $00 DB $00 DB $00 DB $00 DB $00 DB $00 DB $00 DB $00 DB $00 DB $00 * * End of process * L5550 LDA #$02 ; Move to phase 2 again JSR L5700 LDX $0306 LDA $C088,X PLA RTS ; And say bye bye HEX 3D208EF8AABD00FAC542D013BDC0F9C5 HEX 43D00CA544A42EC09DF088C52EF09FC6 HEX 3DD0DCE644C635F0D6A43498AA204AF9 HEX A9DE20EDFD203AFFA9A185332067FD20 HEX C7FFAD0002C9A0F013C8C9A4F0928820 HEX A7FFC993D0D58AF0D22078FEA903853D HEX 2034F60AE9BEC9C290C10A0AA2040A26 HEX 422643CA10F8C63DF0F410E4A2052034 HEX F68434DDB4F9D0132034F6DDBAF9F00D HEX BDBAF9F007C9A4F003A43418882644E0 HEX 03D00D * * Marker, Chris! * HEX BEBAD5FDBBF5B7F6FAEEEFAEDADDAABD L5610 HEX FBF7EDEBEADFDEDBD7D6BFB6B5AFADAB DS $8A * Deniblize table * We have 4*4 nibbles, table begins at offset $AA L56AA HEX 0E0D00010B0400000000000603060000 HEX 0104000F000000000000000000000000 HEX 00000000000000000000000200040000 HEX 0C0E000D030200000000000000000000 HEX 0B070007090A00000000000507080000 HEX 080200030000 * * Move and load nibbles * L5700 JMP L576F ; First move arm L5703 DB $00 ; High-mem ptr DB $00 ; table DB $00 DB $00 DB $00 DB $00 DB $00 DB $00 DB $00 DB $00 DB $00 DB $00 * * Load table * L570F LDX #$0C ; Number of pages STX $A4 LDY #$00 ; Low mem STY L5756+1 STY $A5 ; Page index LDX $0306 ; Slot L571D LDA $C08C,X BPL L571D CMP $A0 BNE L571D L5726 LDA $C08C,X BPL L5726 CMP $A1 BNE L571D L572F LDA $C08C,X BPL L572F CMP $A2 BNE L571D L5738 LDY $A5 ; High mem ptr LDA L5703,Y STA L5756+2 INC $A5 ; Next page index L5742 LDY $C08C,X BPL L5742 * From 4*4 to a byte LDA L56AA-$AA,Y ASL ASL ASL ASL L574E LDY $C08C,X BPL L574E ORA L56AA-$AA,Y L5756 STA $FF00 INC L5756+1 BNE L5742 INC L5756+2 L5761 LDA $C08C,X BPL L5761 CMP $A3 BNE L570F DEC $A4 BNE L5738 RTS * * MOVE ARM * L576F STA $A6 CMP |$001F BEQ L57CB LDA #$00 STA $A7 L577A LDA |$001F STA $A8 SEC SBC $A6 BEQ L57B7 BCS L578D EOR #$FF INC |$001F BCC L5792 L578D ADC #$FE DEC |$001F L5792 CMP $A7 BCC L5798 LDA $A7 L5798 CMP #$0C BCS L579D TAY L579D SEC JSR L57BB LDA L57D7,Y JSR L57CC LDA $A8 CLC JSR L57BE LDA L57E3,Y JSR L57CC INC $A7 BNE L577A L57B7 JSR L57CC CLC L57BB LDA |$001F L57BE AND #$03 ROL ORA $0306 ; Slot TAX LDA $C080,X LDX $0306 ; Slot L57CB RTS L57CC LDX #$13 L57CE DEX BNE L57CE SEC SBC #$01 BNE L57CC RTS L57D7 HEX 01302824201E1D1C1C1C1C1C L57E3 HEX 702C26221F1E1D1C1C1C1C1C DS $11 BOOT 5 @ $5000 REWRITTEN I wrote earlier "too much garbage", I have now rewritten the routine... * * Karateka * (c) Broderbund, 1984 * (k) the Hackzapple team, 2011 * * Boot5 at $5000 MX %11 TYP BIN ORG $005000 LST OFF slot16 = $60 * * $001F : current phase * $0306 : slot * 16 * * * A on entry * <80 : phase to start load from * =>80 : initial load * * Y on entry * contains index in load table * L5000 BPL L5005 ; check Acc JMP L5300 ; initial load L5005 CMP #$10 BEQ L5014 ASL ASL ASL ADC #$0E LDY #$30 JMP L501D SLOT16 DB $60 L5014 LDA #$08 LDY #$00 NOP NOP NOP NOP NOP L501D JSR L5500 JMP $FF59 * * ONLY GARBAGE * DS \ * * INITIAL LOAD * L5300 LDX #$FF ; Stack pointer TXS LDY #$70 ; index in load table LDA #$36 ; and target phase JSR L5500 JMP $FF59 DS \ * * LOAD INDEX * * Y=0 * A=10 L5400 HEX A0A1A2A3A4A5A6A7A8A9AAAB HEX ACADAEAFB0B1B2B3B4B5B6B7 HEX B8B9BABBBCBDBEBF40404040 HEX 000000000000000000000000 * Y=30 * A=A*8+E L5430 HEX 101112131415161718191A1B HEX 1C1D1E1FA0A1A2A3A4A5A6A7 HEX A8A9AAABACADAEAFB0B1B2B3 HEX B4B5B6B7B8B9BABBBCBDBEBF HEX 000000000000000000000000 HEX 00000000 * Y=70 * A=36 L5470 HEX 08090A0B0C0D0E0F60616263 HEX 6465666768696A6B6C6D6E6F HEX 707172737475767778797A7B HEX 7C7D7E7F8081828384858687 HEX 88898A8B8C8D8E8F90919293 HEX 9495969798999A9B9C9D9E9F HEX 000000000000000000000000 HEX 000000000000000000000000 HEX 000000000000000000000000 HEX 000000000000000000000000 HEX 000000000000000000000000 HEX 000000000000000000000000 * * * L5500 PHA ; Save phase STY $88 ; Save index JSR L5700 ; Move arm LDX #$00 ; Copy load table LDY $88 L550A LDA L5400,Y STA L5703,X INY INX CPX #$0C BCC L550A JSR L5530 ; Load data LDA $88 ; Next load table CLC ADC #$0C TAY LDA L5400,Y ; Unless we reached the end BEQ L552B PLA CLC ADC #$02 BNE L5500 DB $00 L552B JMP L5550 * * Set markers * L5530 LDA |$001F ; Set markers LSR LDX #$03 L5536 AND #$0F TAY LDA L5610,Y STA $A0,X INY TYA DEX BPL L5536 JMP L570F ; And load * * End of process * L5550 LDA #$02 ; Move to phase 2 again JSR L5700 LDX SLOT16 LDA $C088,X PLA RTS ; And say bye bye DS \ * * Marker, Chris! * HEX BEBAD5FDBBF5B7F6FAEEEFAEDADDAABD L5610 HEX FBF7EDEBEADFDEDBD7D6BFB6B5AFADAB DS $8A * Deniblize table * We have 4*4 nibbles, table begins at offset $AA L56AA HEX 0E0D00010B0400000000000603060000 HEX 0104000F000000000000000000000000 HEX 00000000000000000000000200040000 HEX 0C0E000D030200000000000000000000 HEX 0B070007090A00000000000507080000 HEX 080200030000 * * Move and load nibbles * L5700 JMP L576F ; First move arm L5703 DB $00 ; High-mem ptr DB $00 ; table DB $00 DB $00 DB $00 DB $00 DB $00 DB $00 DB $00 DB $00 DB $00 DB $00 * * Load table * L570F LDX #$0C ; Number of pages STX $A4 LDY #$00 ; Low mem STY L5756+1 STY $A5 ; Page index LDX SLOT16 ; Slot L571D LDA $C08C,X BPL L571D CMP $A0 BNE L571D L5726 LDA $C08C,X BPL L5726 CMP $A1 BNE L571D L572F LDA $C08C,X BPL L572F CMP $A2 BNE L571D L5738 LDY $A5 ; High mem ptr LDA L5703,Y STA L5756+2 INC $A5 ; Next page index L5742 LDY $C08C,X BPL L5742 * From 4*4 to a byte LDA L56AA-$AA,Y ASL ASL ASL ASL L574E LDY $C08C,X BPL L574E ORA L56AA-$AA,Y L5756 STA $FF00 INC L5756+1 BNE L5742 INC L5756+2 L5761 LDA $C08C,X BPL L5761 CMP $A3 BNE L570F DEC $A4 BNE L5738 RTS * * MOVE ARM * L576F STA $A6 CMP |$001F BEQ L57CB LDA #$00 STA $A7 L577A LDA |$001F STA $A8 SEC SBC $A6 BEQ L57B7 BCS L578D EOR #$FF INC |$001F BCC L5792 L578D ADC #$FE DEC |$001F L5792 CMP $A7 BCC L5798 LDA $A7 L5798 CMP #$0C BCS L579D TAY L579D SEC JSR L57BB LDA L57D7,Y JSR L57CC LDA $A8 CLC JSR L57BE LDA L57E3,Y JSR L57CC INC $A7 BNE L577A L57B7 JSR L57CC CLC L57BB LDA |$001F L57BE AND #$03 ROL ORA SLOT16 ; Slot TAX LDA $C080,X LDX SLOT16 ; Slot L57CB RTS L57CC LDX #$13 L57CE DEX BNE L57CE SEC SBC #$01 BNE L57CC RTS L57D7 HEX 01302824201E1D1C1C1C1C1C L57E3 HEX 702C26221F1E1D1C1C1C1C1C WHAT IS WHERE ON THE DISKETTE AND IN RAM? OK. We have studied the first routines, it is time to rest a little bit and tell what is where on the disk and in RAM sectors are loaded. Track Phase RAM @ 00 00 08 03 02 03 04 05 06 07 01 02 40 02 04 50 52 54 56 03 06 51 53 55 57 04 08 A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB 05 0A AC AD AE AF B0 B1 B2 B3 B4 B5 B6 B7 06 0C B8 B9 BA BB BC BD BE BF 40 40 40 40 07 0E 10 11 12 13 14 15 16 17 18 19 1A 1B 08 10 1C 1D 1E 1F A0 A1 A2 A3 A4 A5 A6 A7 09 12 A8 A9 AA AB AC AD AE AF B0 B1 B2 B3 0A 14 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF 0B 16 10 11 12 13 14 15 16 17 18 19 1A 1B 0C 18 1C 1D 1E 1F A0 A1 A2 A3 A4 A5 A6 A7 0D 1A A8 A9 AA AB AC AD AE AF B0 B1 B2 B3 0E 1C B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF 0F 1E 10 11 12 13 14 15 16 17 18 19 1A 1B 10 20 1C 1D 1E 1F A0 A1 A2 A3 A4 A5 A6 A7 11 22 A8 A9 AA AB AC AD AE AF B0 B1 B2 B3 12 24 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF 13 26 10 11 12 13 14 15 16 17 18 19 1A 1B 14 28 1C 1D 1E 1F A0 A1 A2 A3 A4 A5 A6 A7 15 2A A8 A9 AA AB AC AD AE AF B0 B1 B2 B3 16 2C B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF 17 2E 10 11 12 13 14 15 16 17 18 19 1A 1B 18 30 1C 1D 1E 1F A0 A1 A2 A3 A4 A5 A6 A7 19 32 A8 A9 AA AB AC AD AE AF B0 B1 B2 B3 1A 34 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF 1B 36 08 09 0A 0B 0C 0D 0E 0F 60 61 62 63 1C 38 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 1D 3A 70 71 72 73 74 75 76 77 78 79 7A 7B 1E 3C 7C 7D 7E 7F 80 81 82 83 84 85 86 87 1F 3E 88 89 8A 8B 8C 8D 8E 8F 90 91 92 93 20 40 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F 21 42 ? 22 44 ? AND NOW? Rewrite the $5000 routine and load data beginning on phase $0E and above. What we will do is send a parameter in the accumulator with the following values: E, 16, 1E, 26, 2E, 36. The A value will be the starting phase. What we will also do is change the RAM @ pointers: we will begin at $1000 and increment the value by 1. Let's try... ...tested and validated. The idea is to keep the C sectors per track therefore we will load at $1000..$1BFF then $2000..$2BFF, etc. For information, with Y=0 and A=10, we load the beautiful temple image. Let's now do the work... ...work done, I now have all data from phase E to phase 40 Let's see the code... * * Karateka * (c) Broderbund, 1984 * (k) the Hackzapple team, 2011 * MX %11 TYP BIN ORG $008000 LST OFF slot16 = $60 * * $001F : current phase * * * A on entry * <80 : phase to start load from * =>80 : initial load * * Y on entry * contains index in load table * L5000 PHA LDA #0 ; Tell we are on phase 0 STA $1F PLA BPL L5005 ; check Acc JMP L5300 ; initial load L5005 CMP #$10 BEQ L5014 ASL ASL ASL ADC #$0E LDY #$30 JMP L501D SLOT16 DB $60 L5014 LDA #$08 LDY #$00 NOP NOP NOP NOP NOP L501D JSR L5500 JMP $FF59 * * ONLY GARBAGE * DS \ * * INITIAL LOAD * L5300 LDY #$70 ; index in load table LDA #$36 ; and target phase JSR L5500 JMP $FF59 DS \ * * LOAD INDEX * * Y=0 * A=10 L5400 HEX 101112131415161718191A1B HEX 202122232425262728292A2B HEX 303132333435363738393A3B HEX 000000000000000000000000 * Y=30 * A=A*8+E WITH A=0..4 L5430 HEX 101112131415161718191A1B HEX 202122232425262728292A2B HEX 303132333435363738393A3B HEX 404142434445464748494A4B HEX 000000000000000000000000 HEX 00000000 * Y=70 * A=36 L5470 HEX 101112131415161718191A1B HEX 202122232425262728292A2B HEX 303132333435363738393A3B HEX 404142434445464748494A4B HEX 505152535455565758595A5B HEX 606162636465666768696A6B DS \ * * * L5500 PHA ; Save phase STY $88 ; Save index JSR L5700 ; Move arm LDX #$00 ; Copy load table LDY $88 L550A LDA L5400,Y STA L5703,X INY INX CPX #$0C BCC L550A JSR L5530 ; Load data LDA $88 ; Next load table CLC ADC #$0C TAY LDA L5400,Y ; Unless we reached the end BEQ L552B PLA CLC ADC #$02 BNE L5500 DB $00 L552B JMP $FF59 * * Set markers * L5530 LDA |$001F ; Set markers LSR LDX #$03 L5536 AND #$0F TAY LDA L5610,Y STA $A0,X INY TYA DEX BPL L5536 JMP L570F ; And load * * End of process * L5550 LDA #$00 ; Move to phase 0 again JSR L5700 LDX SLOT16 LDA $C088,X PLA RTS ; And say bye bye DS \ * * Marker, Chris! * HEX BEBAD5FDBBF5B7F6FAEEEFAEDADDAABD L5610 HEX FBF7EDEBEADFDEDBD7D6BFB6B5AFADAB DS $8A * Deniblize table * We have 4*4 nibbles, table begins at offset $AA L56AA HEX 0E0D00010B0400000000000603060000 HEX 0104000F000000000000000000000000 HEX 00000000000000000000000200040000 HEX 0C0E000D030200000000000000000000 HEX 0B070007090A00000000000507080000 HEX 080200030000 * * Move and load nibbles * L5700 JMP L576F ; First move arm L5703 DB $00 ; High-mem ptr DB $00 ; table DB $00 DB $00 DB $00 DB $00 DB $00 DB $00 DB $00 DB $00 DB $00 DB $00 * * Load table * L570F LDX #$0C ; Number of pages STX $A4 LDY #$00 ; Low mem STY L5756+1 STY $A5 ; Page index LDX SLOT16 ; Slot L571D LDA $C08C,X BPL L571D CMP $A0 BNE L571D L5726 LDA $C08C,X BPL L5726 CMP $A1 BNE L571D L572F LDA $C08C,X BPL L572F CMP $A2 BNE L571D L5738 LDY $A5 ; High mem ptr LDA L5703,Y STA L5756+2 INC $A5 ; Next page index L5742 LDY $C08C,X BPL L5742 * From 4*4 to a byte LDA L56AA-$AA,Y ASL ASL ASL ASL L574E LDY $C08C,X BPL L574E ORA L56AA-$AA,Y L5756 STA $FF00 INC L5756+1 BNE L5742 INC L5756+2 L5761 LDA $C08C,X BPL L5761 CMP $A3 BNE L570F DEC $A4 BNE L5738 RTS * * MOVE ARM * L576F STA $A6 CMP |$001F BEQ L57CB LDA #$00 STA $A7 L577A LDA |$001F STA $A8 SEC SBC $A6 BEQ L57B7 BCS L578D EOR #$FF INC |$001F BCC L5792 L578D ADC #$FE DEC |$001F L5792 CMP $A7 BCC L5798 LDA $A7 L5798 CMP #$0C BCS L579D TAY L579D SEC JSR L57BB LDA L57D7,Y JSR L57CC LDA $A8 CLC JSR L57BE LDA L57E3,Y JSR L57CC INC $A7 BNE L577A L57B7 JSR L57CC CLC L57BB LDA |$001F L57BE AND #$03 ROL ORA SLOT16 ; Slot TAX LDA $C080,X LDX SLOT16 ; Slot L57CB RTS L57CC LDX #$13 L57CE DEX BNE L57CE SEC SBC #$01 BNE L57CC RTS L57D7 HEX 01302824201E1D1C1C1C1C1C L57E3 HEX 702C26221F1E1D1C1C1C1C1C A DECODED IMAGE? Yes, there's one @ http://www.brutaldeluxe.fr/crack/KARATEKA_DECODED.dsk At 10:50pm, there's an updated version. I had forgotten the BOOT2 at $0300. Now the version is correct. Yeah! Antoine Boot1 is rewritten. It loads T0/S0 to T0/S8 starting at $0F00. It jumps to $1000 which relocates $1100..$17FF to $0200..$07FF. It then moves head to T1 and jumps to $0300. At $0300, it loads the first two sectors of that track at $4000 and jumps there. I had fun finding room in the different memory areas to put code! Funny game! Antoine ----- Edit - 24/JUL/2011 morning Code at $4000 is now rewritten. It loads data at $5000 and jumps to it. Remaining code, the one at $5000. ----- Edit - 24/JUL/2011 afternoon Code at $5000 is now rewritten. It loads data and jumps to the game. Remaining action: play, play and play. Yyyyyeeeeeaaaaahhhhhhhhhhhhhhhhhh !!!!!! A PLAYABLE VERSION? Yes, there's one but I'd like to rewrite the $4000 routine... Play with it from http://www.brutaldeluxe.fr/crack/KARATEKA_S1_NEARLYFINAL.dsk ---- EDIT 24/JUL/2011 evening Routines at $300 and $4000 rewritten: game is great! http://www.brutaldeluxe.fr/crack/KARATEKA_S1.dsk Now... attacking side 2... ...and now... the famous side 2: http://www.brutaldeluxe.fr/crack/KARATEKA_S2.dsk Enjoy, Antoine 7/2011 THE REWRITTEN BOOT1 @ $0800 * * Karateka * (c) Broderbund, 1984 * (k) The Hackzapple team, 2011 * TYP BIN ORG $000800 MX %11 LST OFF INIT EQU $FB2F SETKBD EQU $FE89 SETVID EQU $FE93 L0800 HEX 01 LDA $27 CMP #$09 BNE L081F LDA $2B LSR LSR LSR LSR ORA #$C0 STA $3E+1 LDA #$5C STA $3E CLC LDA L08FD+1 ADC L08FF STA L08FD+1 L081F LDX L08FF BMI L0839 LDA tblINTER,X STA $3D DEC L08FF LDA L08FD+1 STA $27 DEC L08FD+1 LDX $2B JMP ($003E) L0839 INC L08FD+1 INC L08FD+1 JSR SETKBD JSR SETVID JSR INIT LDX $2B JMP (L08FD) tblINTER HEX 000D0B09070503010E0C0A080604020F DS 3 DS $10 ASC ' LOGO ' ASC ' 7 2011 ' DS $7D L08FD DA $0F00 L08FF HEX 08 THE REWRITTEN BOOT2 @ $0300/$1000 The code is loaded by BOOT1 and it now limits its action to moving code above $1100 at $0200. * * Karateka * (c) Broderbund, 1984 * (k) the Hackzapple team, 2011 * TYP BIN ORG $001000 MX %11 LST OFF RDBANK2 EQU $C080 LCBANK2 EQU $C083 WAIT EQU $FCA8 RESETV EQU $FFFC IRQV EQU $FFFE L0200 = $0200 L0300 = L0200+$100 L0400 = L0300+$100 L0500 = L0400+$100 L0600 = L0500+$100 L0700 = L0600+$100 GO0300 = $0300 idxPHASE = $26 savPHASE = $27 tgtPHASE = $2A theSLOT = $2B curPHASE = $FF * * * L1000 LDY #$00 ; CLEAR HGR1 LDX #$20 STY $3C STX $3D TYA L1009 STA ($3C),Y INY BNE L1009 INC $3D DEX BNE L1009 STX curPHASE ; 0: CURRENT PHASE L1015 LDY L1020,X ; HOW TO SET SW! STA $C000,Y BEQ L102A INX BNE L1015 L1020 HEX 5F575254500C08040200 * * RELOCATE 6 PAGES AT $0200 * L102A LDX #0 ]LP LDA PAGE1,X STA L0200,X LDA PAGE2,X STA L0300,X LDA PAGE3,X STA L0400,X LDA PAGE4,X STA L0500,X LDA PAGE5,X STA L0600,X LDA PAGE6,X STA L0700,X INX BNE ]LP LDX $2B STX $0306 ; SLOT16 TXA LSR LSR LSR LSR ORA #$C0 STA $0308 ; AND SLOT * LDA #$02 ; MOVE ARM JSR moveARM LDA #$80 ; NEXT BOOT PHASE JMP GO0300 * * * moveARM STA tgtPHASE ; a PHASE not a track CMP curPHASE BEQ LB9FC LDA #$00 STA idxPHASE LB9AD LDA curPHASE ; Calculate STA savPHASE ; how the arm SEC ; must be moved SBC tgtPHASE ; to track $22 BEQ LB9EA ; or track $00 BCS LB9C0 EOR #$FF INC curPHASE BCC LB9C5 LB9C0 ADC #$FE DEC curPHASE LB9C5 CMP idxPHASE BCC LB9CB LDA idxPHASE LB9CB CMP #$0C BCS LB9D0 TAY LB9D0 SEC JSR LB9EE LDA tblTEMPO1,Y JSR LBA00 LDA savPHASE CLC JSR LB9F1 LDA tblTEMPO2,Y JSR LBA00 INC idxPHASE BNE LB9AD LB9EA JSR LBA00 CLC LB9EE LDA curPHASE ; Move one phase LB9F1 AND #$03 ROL ORA theSLOT TAX LDA $C080,X LDX theSLOT LB9FC RTS LBA00 LDX #$11 ; WAIT LBA02 DEX BNE LBA02 INC $46 BNE LBA0B INC $47 LBA0B SEC SBC #$01 BNE LBA00 RTS tblTEMPO1 HEX 01302824201E1D1C1C1C1C1C tblTEMPO2 HEX 702C26221F1E1D1C1C1C1C1C DS \ * * * PAGE1 = * PAGE2 = PAGE1+$100 PAGE3 = PAGE2+$100 PAGE4 = PAGE3+$100 PAGE5 = PAGE4+$100 PAGE6 = PAGE5+$100 THE REWRITTEN BOOT3 @ $0200 * * Karateka * (c) Broderbund, 1984 * (k) The Hackzapple team, 2011 * TYP BIN ORG $000200 MX %11 LST OFF dpNIBBLE = $00 dpNBSEC = $01 dpBUFFER = $02 dpINDEX = $04 NIB0300 = $4200 NIB0356 = NIB0300+$56 L4000 = $4000 GO4000 = $4000 IVERSION EQU $BFFD MINKVERS EQU $BFFE KVERSION EQU $BFFF KBD EQU $C000 KBDSTROBE EQU $C010 RDVBLBAR EQU $C019 SPKR EQU $C030 TXTPAGE1 EQU $C054 TXTPAGE2 EQU $C055 BUTN0 EQU $C061 BUTN1 EQU $C062 ROMIN2 EQU $C081 RDROM2 EQU $C082 INIT EQU $FB2F VERSION EQU $FBB3 HOME EQU $FC58 WAIT EQU $FCA8 IRQV EQU $FFFE * * * L0200 JMP L020C JMP L025E JMP L02A2 JMP L0237 L020C LDA $D0 JSR L0300 BNE L020C LDA KVERSION EOR #$49 CMP $D0 BNE L020C LDA MINKVERS EOR #$3B CMP $D0 BNE L020C LDA IVERSION CMP $D0 BNE L020C L022C LDA $D0 STA $D2 LDA #$40 STA $07 JMP $BFFA L0237 JSR $1900 LDA $07 CMP #$20 BEQ L0246 JSR $7609 JSR $1900 L0246 JSR $7609 L0249 DEC $D2 JSR L0303 BNE L0249 JSR $1012 LDA #$01 STA $D0 LDA #$00 STA $DC JMP L020C L025E JSR L02CB LDX #$00 LDY #$00 LDA KBDSTROBE L0268 LDA $C4 BEQ L0278 LDA KBD BMI L02B4 LDA KBD BMI L02B4 BPL L0286 L0278 BNE L0286 LDA BUTN0 BMI L02B4 LDA BUTN1 BMI L02B4 BPL L0286 L0286 LDA KBD BMI L02B4 DEY BNE L0268 DEX BNE L0268 L0291 JSR $7609 LDA $D2 BNE L029B JMP L022C L029B LDA #$00 STA $D0 JMP L020C L02A2 JSR $1900 LDA $07 CMP #$20 BEQ L0291 JSR $7609 JSR $1900 JMP L0291 L02B4 JSR $7609 LDA $D2 CMP #$01 BNE L02C2 STA $DC JMP L022C L02C2 LDA #$01 STA $DC STA $D0 JMP L020C L02CB JSR $1900 JSR L02E7 JSR $7609 JSR $1900 LDA $07 CMP #$20 BEQ L02E6 JSR L02E7 JSR $7609 JSR $1900 L02E6 RTS L02E7 LDA #$74 STA $03 LDA #$9A STA $04 LDA #$0F STA $05 LDA #$5A STA $06 LDA #$01 STA $0F JMP $1903 DB $19 DB $DF * * * L0300 JMP L0338 L0303 JMP L03A5 L0306 DB $60 L0307 DA $C600 * * REBOOT * *L0309 LDA #$D2 ; R * DB $2C *L030C LDA #$D0 ; P * PHA * JSR INIT * JSR HOME * PLA * STA L0400 *L0319 LDY #$00 * TYA *L031C STA $0800,Y * INY * BNE L031C * BIT SPKR * INC L031C+2 * LDA L031C+2 * CMP #$C0 * BCC L0319 * JSR L03DC * INC L03F4 * JMP (L0307) * * LOAD * L0338 PHA JSR L0393 ; SAVE ZP LDX L0306 ; SLOT JSR motorON ; TURN MOTOR ON LDY #$00 STY dpINDEX STY dpBUFFER LDX #$03 JSR makeNIBBLE L0342 LDA #$02 ; LOAD 2 PAGES AT $4000 STA dpNBSEC LDA #>L4000 STA dpBUFFER+1 * * AV * readHEADER CLC readDATA PHP LDX L0306 ; dpSLOT read1 LDA $C08C,X BPL *-3 read2 EOR #$D5 BNE read1 LDA $C08C,X BPL *-3 CMP #$AA BNE read2 LDA $C08C,X BPL *-3 CMP #$96 BEQ doHEADER PLP BCC readHEADER EOR #$AD BEQ doDATA BNE readHEADER * Read header doHEADER LDY #$03 ]lp LDA $C08C,X BPL *-3 ROL STA dpNIBBLE LDA $C08C,X BPL *-3 AND dpNIBBLE DEY BNE ]lp PLP LDX dpINDEX CMP tblINTER,X ; Right sector ? BNE readHEADER SEC BCS readDATA ; read data * Read data doDATA LDY #$56 ]lp STY dpNIBBLE LDY $C08C,X BPL *-3 EOR NIB0356-$80,Y LDY dpNIBBLE DEY STA NIB0300,Y BNE ]lp ]lp STY dpNIBBLE LDY $C08C,X BPL *-3 EOR NIB0356-$80,Y LDY dpNIBBLE STA (dpBUFFER),Y INY BNE ]lp * Deniblize doNIBBLE1 LDX #$56 ; Y equals 0 ;-) ]lp DEX BMI doNIBBLE1 LDA (dpBUFFER),Y LSR NIB0300,X ROL LSR NIB0300,X ROL STA (dpBUFFER),Y INY BNE ]lp * NEXT SECTOR INC dpBUFFER+1 INC dpINDEX DEC dpNBSEC BEQ doEND JMP readHEADER doEND PLA JSR GO4000 ; $4000 * * END AV * *L034E LDA $C08C,X * BPL L034E *L0353 CMP #$F5 * BNE L034E *L0357 LDA $C08C,X * BPL L0357 *L035C CMP #$D5 * BNE L0353 *L0360 LDA $C08C,X * BPL L0360 * CMP #$DA * BNE L035C *L0369 LDA $C08C,X * BPL L0369 * ROL * STA $00 *L0371 LDA $C08C,X * BPL L0371 * AND $00 * STA ($02),Y * INY * BNE L0369 * ASL $FFFF ; IRQV+1 *L0380 LDA $C08C,X * BPL L0380 * CMP #$FB * BNE L0342 * * INC $03 * DEC $01 * BNE L0369 * PLA * JSR $4000 L0393 LDX #$00 L0395 LDA $00,X LDY $4F00,X STA $4F00,X STY $00,X INX BNE L0395 LDA #$00 RTS * * NEXT STEP * L03A5 LDA #$10 ; Load temple JSR L0338 LDA #$40 ; Clear page 2 STA $07 JSR $1900 LDA TXTPAGE2 LDA #$A0 ; Move to HGR1 LDY #$20 LDX #$20 * JSR L03C3 * * COPY MEMORY * L03C3 STA $3D STY $3F LDY #$00 STY $3C STY $3E L03CD LDA ($3C),Y STA ($3E),Y INY BNE L03CD INC $3D INC $3F DEX BNE L03CD * RTS LDA TXTPAGE1 ; Show HGR1 LDA #$00 ; and exit RTS * * BOOT4: ENTRY POINT - To Be Removed! * *L03DC BIT ROMIN2 ; FORCE ROM * BIT ROMIN2 * LDA #$D0 * TAY * LDX #$30 * JSR L03C3 * STA RDROM2 * RTS * * DB $00 * DB $00 * * DA L030C ; 3F0 * DA L0309 ; 3F2 *L03F4 DB $A6 DS \ lst on L0400 DB $0A lst off DB $02 DB $80 DB $80 DB $80 DB $80 DB $98 DB $80 DB $B0 DB $80 DB $E0 DB $80 DB $F0 DB $80 DB $CC DB $80 DB $C6 DB $81 DB $E6 DB $81 DB $9C DB $83 DB $0A DB $02 DB $80 DB $80 DB $80 DB $80 DB $F6 DB $81 DB $9C DB $83 DB $8C DB $83 DB $FC DB $81 DB $8C DB $83 DB $8C DB $86 DB $8C DB $87 DB $FC DB $83 DB $0A DB $02 DB $80 DB $80 DB $80 DB $80 DB $F8 DB $80 DB $C4 DB $83 DB $86 DB $81 DB $86 DB $80 DB $86 DB $80 DB $86 DB $83 DB $8C DB $83 DB $F8 DB $80 DB $0A DB $02 DB $80 DB $80 DB $90 DB $80 DB $B8 DB $80 DB $F0 DB $80 DB $E8 DB $81 DB $C4 DB $83 DB $86 DB $83 DB $86 DB $83 DB $8C DB $83 DB $F8 DB $80 DB $0A DB $02 DB $80 DB $80 DB $80 DB $80 DB $F8 DB $81 DB $84 DB $83 DB $86 DB $80 DB $FE DB $80 DB $86 DB $80 DB $86 DB $80 DB $8C DB $83 DB $F8 DB $81 DB $0C DB $02 DB $80 DB $80 DB $F0 DB $80 DB $C8 DB $81 DB $8C DB $80 DB $8C DB $80 DB $8C DB $80 DB $8C DB $80 DB $8C DB $80 DB $FE DB $80 DB $8C DB $80 DB $8C DB $80 DB $8C DB $80 DB $0C DB $02 DB $80 DB $80 DB $80 DB $80 DB $F8 DB $80 DB $C4 DB $83 DB $86 DB $81 DB $86 DB $80 DB $C6 DB $83 DB $86 DB $83 DB $8C DB $83 DB $F8 DB $83 DB $80 DB $83 DB $C0 DB $81 DB $0A DB $02 DB $8E DB $80 DB $8C DB $80 DB $8C DB $80 DB $EC DB $83 DB $9C DB $86 DB $8C DB $86 DB $8C DB $86 DB $8C DB $86 DB $8C DB $83 DB $8C DB $87 DB $0A DB $02 DB $80 DB $80 DB $80 DB $80 DB $FC DB $8F DB $84 DB $87 DB $C0 DB $83 DB $E0 DB $81 DB $F0 DB $80 DB $B8 DB $80 DB $9C DB $88 DB $FE DB $8F DB $B6 DB $9C DB $0A DB $02 DB $8E DB $80 DB $8C DB $80 DB $8C DB $82 DB $8C DB $81 DB $CC DB $80 DB $AC DB $80 DB $FC DB $80 DB $CC DB $81 DB $8C DB $83 DB $8C DB $86 DB $0A DB $01 DB $8E DB $8C DB $8C DB $8C DB $8C DB $8C DB $8C DB $8C DB $8C DB $FC DB $0A DB $02 DB $80 DB $80 DB $80 DB $80 DB $EE DB $9D DB $DC DB $B7 DB $8C DB $E3 DB $8C DB $E3 DB $8C DB $E3 DB $8C DB $E3 DB $8C DB $B3 DB $8C DB $F3 DB $0A DB $02 DB $80 DB $80 DB $80 DB $80 DB $CE DB $83 DB $BC DB $86 DB $8C DB $86 DB $8C DB $86 DB $8C DB $86 DB $8C DB $86 DB $8C DB $83 DB $8C DB $87 DB $0A DB $02 DB $80 DB $80 DB $80 DB $80 DB $F8 DB $80 DB $C4 DB $83 DB $86 DB $87 DB $86 DB $86 DB $86 DB $86 DB $8E DB $86 DB $9C DB $82 DB $F0 DB $81 DB $0C DB $02 DB $80 DB $80 DB $80 DB $80 DB $EE DB $83 DB $9C DB $86 DB $8C DB $8C DB $8C DB $8C DB $8C DB $8C DB $8C DB $8C DB $9C DB $84 DB $EC DB $83 DB $8C DB $80 DB $8C DB $80 DB $0C DB $02 DB $80 DB $80 DB $80 DB $80 DB $F8 DB $87 DB $84 DB $87 DB $86 DB $86 DB $86 DB $86 DB $86 DB $86 DB $86 DB $86 DB $8E DB $87 DB $F8 DB $86 DB $80 DB $86 DB $80 DB $86 DB $0A DB $02 DB $80 DB $80 DB $80 DB $80 DB $EE DB $83 DB $9C DB $8E DB $8C DB $8C DB $8C DB $8C DB $8C DB $86 DB $FC DB $81 DB $CC DB $83 DB $8C DB $8E DB $0A DB $02 DB $80 DB $80 DB $80 DB $80 DB $F0 DB $80 DB $CC DB $81 DB $8C DB $80 DB $B8 DB $80 DB $F0 DB $80 DB $C0 DB $81 DB $CC DB $81 DB $F8 DB $80 DB $0A DB $02 DB $A0 DB $80 DB $B0 DB $84 DB $FE DB $87 DB $B2 DB $80 DB $B0 DB $80 DB $B0 DB $80 DB $B0 DB $80 DB $B0 DB $80 DB $B0 DB $86 DB $E0 DB $83 DB $0A DB $02 DB $80 DB $80 DB $80 DB $80 DB $86 DB $83 DB $86 DB $83 DB $86 DB $83 DB $86 DB $83 DB $86 DB $83 DB $86 DB $83 DB $C4 DB $87 DB $B8 DB $82 DB $0A DB $02 DB $80 DB $80 DB $80 DB $80 DB $8E DB $8C DB $8C DB $84 DB $98 DB $82 DB $98 DB $82 DB $B0 DB $81 DB $F0 DB $81 DB $E0 DB $80 DB $E0 DB $80 DB $0A DB $03 DB $80 DB $80 DB $80 DB $80 DB $80 DB $80 DB $8E DB $87 DB $86 DB $8C DB $86 DB $82 DB $98 DB $8C DB $81 DB $98 DB $8E DB $81 DB $B0 DB $D9 DB $80 DB $F0 DB $F9 DB $80 DB $E0 DB $B0 DB $80 DB $E0 DB $B0 DB $80 DB $0A DB $02 DB $80 DB $80 DB $80 DB $80 DB $86 DB $82 DB $8C DB $81 DB $D8 DB $80 DB $B0 DB $80 DB $F0 DB $80 DB $C8 DB $81 DB $84 DB $83 DB $82 DB $86 DB $0C DB $02 DB $80 DB $80 DB $80 DB $80 DB $8E DB $8C DB $8C DB $84 DB $98 DB $82 DB $98 DB $82 DB $B0 DB $81 DB $F0 DB $81 DB $C0 DB $80 DB $A0 DB $80 DB $AC DB $80 DB $98 DB $80 DB $0A DB $01 DB $80 DB $80 DB $8E DB $8C DB $8C DB $8C DB $8C DB $8C DB $8C DB $8C DB $0C DB $01 DB $80 DB $80 DB $BC DB $B0 DB $B0 DB $B0 DB $B0 DB $B0 DB $B0 DB $B0 DB $B6 DB $9C DB $0A DB $01 DB $80 DB $80 DB $80 DB $80 DB $80 DB $80 DB $80 DB $80 DB $8C DB $8C DB $0C DB $01 DB $80 DB $80 DB $80 DB $80 DB $80 DB $80 DB $80 DB $80 DB $86 DB $86 DB $84 DB $82 DB $0C DB $01 DB $80 DB $80 DB $80 DB $80 DB $86 DB $86 DB $80 DB $86 DB $86 DB $80 DB $80 DB $80 DB $0A DB $01 DB $80 DB $80 DB $80 DB $80 DB $80 DB $BC DB $BC DB $80 DB $80 DB $80 DB $E6 DB $F2 DB $08 DB $1E DB $34 DB $4E DB $68 DB $7E DB $94 DB $AA DB $C0 DB $D6 L0680 DB $00 DB $00 DB $16 DB $2C DB $42 DB $58 DB $6E DB $88 DB $A2 DB $26 DB $32 DB $D0 DB $E6 DB $F2 DB $08 DB $1E DB $34 DB $4E DB $68 DB $7E DB $94 DB $AA DB $C0 DB $D6 DB $F6 DB $0C DB $B8 DB $40 DB $4C DB $5A DB $68 DB $00 L06A0 DB $00 DB $00 DB $00 DB $00 DB $00 DB $00 DB $00 DB $00 DB $00 DB $02 DB $02 DB $00 DB $00 DB $00 DB $01 DB $01 DB $01 DB $01 DB $01 DB $01 DB $01 DB $01 DB $01 DB $01 DB $01 DB $02 DB $00 DB $02 DB $02 DB $02 DB $02 DB $00 L06C0 DB $01 DB $01 DB $01 DB $01 DB $01 DB $01 DB $01 DB $01 DB $01 DB $00 DB $00 DB $01 DB $01 DB $02 DB $01 DB $01 DB $01 DB $01 DB $01 DB $01 DB $01 DB $01 DB $01 DB $02 DB $01 DB $01 DB $01 DB $01 DB $00 DB $01 DB $01 DB $00 L06E0 DB $00 DB $01 DB $03 DB $02 DB $02 DB $02 DB $00 DB $02 DB $03 DB $04 DB $06 DB $02 DB $00 DB $00 DB $03 DB $03 DB $04 DB $04 DB $04 DB $01 DB $03 DB $03 DB $04 DB $03 DB $03 DB $03 DB $03 DB $00 DB $03 DB $00 DB $00 DB $00 * * * lst on L0700 LDY #$00 lst off STY $0F LDA ($E5),Y STA $05 INY LDA ($E5),Y STA $10 L070D INY LDA ($E5),Y SEC SBC #$60 BMI L0762 TAX LDA L0680,X STA $03 LDA L06A0,X CLC ADC #$04 STA $04 CPX #$00 BEQ L0746 STY $E0 LDY #$00 LDA ($03),Y STA $E1 CLC ADC $06 CMP #$C1 BCC L073D LDA #$C0 SEC SBC $06 STA ($03),Y L073D JSR $1903 LDA $E1 STA ($03),Y LDY $E0 L0746 LDA L06C0,X CLC ADC $05 STA $05 LDA L06E0,X CLC ADC $10 CMP #$07 BCC L075D INC $05 SEC SBC #$07 L075D STA $10 JMP L070D L0762 RTS * * LoGo - 15 bytes (can be reduced to 13) tblINTER HEX 000D0B0907050301 HEX 0E0C0A08060402 * TURN MOTOR ON * 14 bytes motorON LDX L0306 LDA $C089,X LDA #$00 JSR WAIT JMP WAIT * DB $09 * DB $03 * DB $80 * DB $C0 * DB $FB * DB $80 * DB $F0 * DB $FF * DB $80 * DB $FC * DB $FF * DB $80 * DB $FE * DB $F9 * DB $80 * DB $FE * DB $FB * DB $80 * DB $EE * DB $FB * DB $80 * DB $EE * DB $FB * DB $80 * DB $EE * DB $FB * DB $80 * DB $8C * DB $FB lst on L0780 JMP L0786 lst off JMP L0799 L0786 LDX #$00 L0788 JSR L07B9 LDY #$27 L078D LDA ($E2),Y STA ($E0),Y DEY BPL L078D CPX #$BE BCC L0788 RTS L0799 LDA $07 CMP #$40 BEQ L07AC STA $E4 LDA #$40 STA $07 JSR L07D7 LDA TXTPAGE1 RTS L07AC STA $E4 LDA #$20 STA $07 JSR L07D7 LDA TXTPAGE2 RTS L07B9 LDA $0800,X STA $E0 LDA $08C0,X CLC ADC $07 STA $E1 INX INX LDA $0800,X STA $E2 LDA $08C0,X CLC ADC $E4 STA $E3 DEX RTS * 13 bytes L07D7 LDA VERSION CMP #$06 BNE L07E3 L07DE LDA RDVBLBAR BMI L07DE L07E3 RTS * 28 bytes * DB $90 * DB $80 * DB $00 * DB $A0 * DB $81 * DB $80 * DB $00 * DB $A0 * DB $95 * DB $80 * DB $00 * DB $A0 * DB $FD * DB $80 * DB $00 * DB $80 * DB $D5 * DB $80 * DB $00 * DB $80 * DB $85 * DB $80 * DB $4C * DB $60 * DB $B7 * DB $00 * DB $3B * DB $49 * Make nibble table makeNIBBLE = * ]lp STX dpNIBBLE TXA ASL BIT dpNIBBLE BEQ L461E ORA dpNIBBLE EOR #$FF AND #$7E L4614 BCS L461E LSR BNE L4614 TYA STA NIB0356,X INY L461E INX BPL ]lp RTS lst on ICI = * lst off THE REWRITTEN BOOT4 @ $4000 * * Karateka * (c) Broderbund, 1984 * (k) the Hackzapple team, 2011 * * Update boot4 phase to load phase5 MX %11 TYP BIN ORG $004000 LST OFF dpNIBBLE = $00 dpNBSEC = $01 dpBUFFER = $02 dpINDEX = $04 NIB0300 = $4200 NIB0356 = NIB0300+$56 L5000 = $5000 GO5000 = $5000 idxPHASE = $26 savPHASE = $27 tgtPHASE = $2A theSLOT = $306 curPHASE = $1F * * * L4000 PHA ; save A LDA #$02 ; Tell we are on phase 2 STA curPHASE LDA #$04 ; We want phase 4 JSR moveARM LDA #0 STA dpINDEX LDA #8 ; LOAD 8 PAGES AT $5000 STA dpNBSEC LDY #L5000 STY dpBUFFER STA dpBUFFER+1 JSR loadDATA PLA JMP GO5000 ; Next boot phase * * AV * loadDATA = * readHEADER CLC readDATA PHP LDX theSLOT ; dpSLOT read1 LDA $C08C,X BPL *-3 read2 EOR #$D5 BNE read1 LDA $C08C,X BPL *-3 CMP #$AA BNE read2 LDA $C08C,X BPL *-3 CMP #$96 BEQ doHEADER PLP BCC readHEADER EOR #$AD BEQ doDATA BNE readHEADER * Read header doHEADER LDY #$03 ]lp LDA $C08C,X BPL *-3 ROL STA dpNIBBLE LDA $C08C,X BPL *-3 AND dpNIBBLE DEY BNE ]lp PLP LDX dpINDEX CMP tblINTER,X ; Right sector ? BNE readHEADER SEC BCS readDATA ; read data * Read data doDATA LDY #$56 ]lp STY dpNIBBLE LDY $C08C,X BPL *-3 EOR NIB0356-$80,Y LDY dpNIBBLE DEY STA NIB0300,Y BNE ]lp ]lp STY dpNIBBLE LDY $C08C,X BPL *-3 EOR NIB0356-$80,Y LDY dpNIBBLE STA (dpBUFFER),Y INY BNE ]lp * Deniblize doNIBBLE1 LDX #$56 ; Y equals 0 ;-) ]lp DEX BMI doNIBBLE1 LDA (dpBUFFER),Y LSR NIB0300,X ROL LSR NIB0300,X ROL STA (dpBUFFER),Y INY BNE ]lp * NEXT SECTOR INC dpBUFFER+1 INC dpINDEX DEC dpNBSEC BEQ doEND JMP readHEADER doEND RTS DS \ * * * moveARM STA tgtPHASE ; a PHASE not a track CMP curPHASE BEQ LB9FC LDA #$00 STA idxPHASE LB9AD LDA curPHASE ; Calculate STA savPHASE ; how the arm SEC ; must be moved SBC tgtPHASE ; to track $22 BEQ LB9EA ; or track $00 BCS LB9C0 EOR #$FF INC curPHASE BCC LB9C5 LB9C0 ADC #$FE DEC curPHASE LB9C5 CMP idxPHASE BCC LB9CB LDA idxPHASE LB9CB CMP #$0C BCS LB9D0 TAY LB9D0 SEC JSR LB9EE LDA tblTEMPO1,Y JSR LBA00 LDA savPHASE CLC JSR LB9F1 LDA tblTEMPO2,Y JSR LBA00 INC idxPHASE BNE LB9AD LB9EA JSR LBA00 CLC LB9EE LDA curPHASE ; Move one phase LB9F1 AND #$03 ROL ORA theSLOT TAX LDA $C080,X LDX theSLOT LB9FC RTS LBA00 LDX #$11 ; WAIT LBA02 DEX BNE LBA02 INC $46 BNE LBA0B INC $47 LBA0B SEC SBC #$01 BNE LBA00 RTS tblTEMPO1 HEX 01302824201E1D1C1C1C1C1C tblTEMPO2 HEX 702C26221F1E1D1C1C1C1C1C tblINTER HEX 000D0B0907050301 HEX 0E0C0A08060402 DS \ THE REWRITTEN BOOT5 @ $5000 * * Karateka * (c) Broderbund, 1984 * (k) the Hackzapple team, 2011 * * Boot5 at $5000 MX %11 TYP BIN ORG $005000 LST OFF dpNIBBLE = $a0 dpNBSEC = $a4 dpBUFFER = $a1 dpINDEX = $a5 NIB0300 = $4200 NIB0356 = NIB0300+$56 idxPHASE = $26 savPHASE = $27 tgtPHASE = $A6 theSLOT = $306 curPHASE = $1F * * $001F : current phase * $0306 : slot * 16 * * * A on entry * <80 : phase to start load from * =>80 : initial load * * Y on entry * contains index in load table * L5000 BPL L5005 ; check Acc JMP L5300 ; initial load L5005 CMP #$10 BEQ L5014 ASL ASL ASL ADC #$0E LDY #$30 JMP L501D DB $00 L5014 LDA #$08 LDY #$00 NOP NOP NOP NOP NOP L501D JSR L5500 PLA PLA ; Change return address LDX #$00 ; Copy ZP L5024 LDA $4F00,X STA $00,X INX BNE L5024 LDY #$00 ; Clear parts of HGR2 LDA #$40 LDX #$20 STY $3C STA $3D LDA #$00 L5038 LDY #$78 L503A STA ($3C),Y INY BPL L503A LDY #$F8 L5041 STA ($3C),Y INY BNE L5041 INC $3D DEX BNE L5038 LDA #$00 ; Oh, A = 0 RTS ; Return * * ONLY GARBAGE * DS $B2 L5100 HEX CED004A5CFF011A5DA85CAA5DB85CB20 HEX 2CF120FDFEA6D860203AFF4C15F1A0CE HEX 843CC8843EA000843D843F60B5CA953C HEX B44C943ECA10F5A53ED002C63FC63E60 HEX 86D838A2FFB54DF5CB95CFE8F0F7201E HEX F120CDFEA201202CF1A91A20CFFEA6D8 HEX 6020C4E34C3AFFA5FCD0034CA5E8C6FC HEX 60A9FF85A06046A06024A01019A9A320 HEX EDFDA001B1DCAAC8B1DC201BE5A9A04C HEX EDFDA5DCA4DD60C1007FD1CCC7CFCEC5 HEX 9A988D969593BFB232120FBCB0ACBE35 HEX 0C6130100BDDFBA00020C7E7A9A04CED HEX FD0000000000000000A44AA54B48C4DA HEX E5DBB01C6884D085D1A0FFC8B1D030FB HEX C940F0F7C8C8B1D04888B1D0A868D0DD HEX 68A000B1D030054AF008A9A420EDFDC8 HEX D0F1A9BD4CEDFD91DAE8B59FF0304CD5 HEX F3A03007A5DCA4DD207DF120C9F1A6D8 HEX 4CB7F1E8E8B59FF01F4CE0F33007A5DC HEX A4DD207DF120C9F1A6D84C09F4E86020 HEX 15E7E6CED002E6CF60205BF2D0152053 HEX F2D0102082E7206FE750032082E72059 HEX E756504C36E720C9EF154F100520C9EF HEX 354F955010ED4CC9EF2015E7A4FBA5CE HEX 995F01A5CF4C66E9995001883051B940 HEX 01D550D0F6B95001D578D0EFC6FBB941 HEX 01994001B95101995001B9C10199C001 HEX B9D10199D001B96101996001B9710199 HEX 7001B98101998001B99101999001B9A1 HEX 0199A001B9A10199A001C8C4FB90BF60 HEX E8A90048B55038E90385CEB578E90085 HEX CF68A00091CEE860C985B0034CC0E4A0 * * INITIAL LOAD * LST ON L5300 LDX #$FF ; Stack pointer LST OFF TXS LDY #$70 ; index in load table LDA #$36 ; and target phase JSR L5500 LDX #$00 ; clear ZP TXA L530D STA $00,X INX BNE L530D LDA #$01 ; And some inits STA $86 STA $4F LDA #$00 STA $D0 LDA #$FF STA $D2 JMP $0200 ; Next please * We have room here! DS $DD * * LOAD INDEX * * Y=0 * A=10 L5400 HEX A0A1A2A3A4A5A6A7A8A9AAAB HEX ACADAEAFB0B1B2B3B4B5B6B7 HEX B8B9BABBBCBDBEBF40404040 HEX 000000000000000000000000 * Y=30 * A=A*8+E L5430 HEX 101112131415161718191A1B HEX 1C1D1E1FA0A1A2A3A4A5A6A7 HEX A8A9AAABACADAEAFB0B1B2B3 HEX B4B5B6B7B8B9BABBBCBDBEBF HEX 000000000000000000000000 HEX 00000000 * Y=70 * A=36 L5470 HEX 08090A0B0C0D0E0F60616263 HEX 6465666768696A6B6C6D6E6F HEX 707172737475767778797A7B HEX 7C7D7E7F8081828384858687 HEX 88898A8B8C8D8E8F90919293 HEX 9495969798999A9B9C9D9E9F HEX 000000000000000000000000 DS \ * * * LST ON L5500 PHA ; Save phase LST OFF STY $88 ; Save index JSR moveARM ; Move arm LDX #$00 ; Copy load table LDY $88 L550A LDA L5400,Y STA L5703,X INY INX CPX #$0C BCC L550A * JSR L5530 ; Load data JSR loadDATA LDA $88 ; Next load table CLC ADC #$0C TAY LDA L5400,Y ; Unless we reached the end BEQ L552B PLA CLC ADC #$02 BNE L5500 DB $00 L552B JMP L5550 PLA RTS * * Set markers * *L5530 LDA |$001F ; Set markers * LSR * LDX #$03 *L5536 AND #$0F * TAY * LDA L5610,Y * STA $A0,X * INY * TYA * DEX * BPL L5536 * JMP loadDATA ; And load DB $00 DB $00 DB $00 DB $00 DB $00 DB $00 DB $00 DB $00 DB $00 DB $00 * * End of process * L5550 LDA #$02 ; Move to phase 2 again JSR moveARM LDX $0306 LDA $C088,X PLA RTS ; And say bye bye HEX 3D208EF8AABD00FAC542D013BDC0F9C5 HEX 43D00CA544A42EC09DF088C52EF09FC6 HEX 3DD0DCE644C635F0D6A43498AA204AF9 HEX A9DE20EDFD203AFFA9A185332067FD20 HEX C7FFAD0002C9A0F013C8C9A4F0928820 HEX A7FFC993D0D58AF0D22078FEA903853D HEX 2034F60AE9BEC9C290C10A0AA2040A26 HEX 422643CA10F8C63DF0F410E4A2052034 HEX F68434DDB4F9D0132034F6DDBAF9F00D HEX BDBAF9F007C9A4F003A43418882644E0 HEX 03D00D DS \ * * Marker, Chris! * * HEX BEBAD5FDBBF5B7F6FAEEEFAEDADDAABD *L5610 HEX FBF7EDEBEADFDEDBD7D6BFB6B5AFADAB * DS $8A * Deniblize table * We have 4*4 nibbles, table begins at offset $AA *L56AA HEX 0E0D00010B0400000000000603060000 * HEX 0104000F000000000000000000000000 * HEX 00000000000000000000000200040000 * HEX 0C0E000D030200000000000000000000 * HEX 0B070007090A00000000000507080000 * HEX 080200030000 * now $5600 lst on L57CC LDX #$13 lst off L57CE DEX BNE L57CE SEC SBC #$01 BNE L57CC RTS tblINTER HEX 000D0B0907050301 HEX 0E0C0A08060402 L57D7 HEX 01302824201E1D1C1C1C1C1C L57E3 HEX 702C26221F1E1D1C1C1C1C1C L5703 DB $00 ; High-mem ptr DB $00 ; table DB $00 DB $00 DB $00 DB $00 DB $00 DB $00 DB $00 DB $00 DB $00 DB $00 DS \ * * Move and load nibbles * lst on moveARM JMP L576F ; First move arm lst off * * Load table * loadDATA LDX #$0C ; Number of pages STX dpNBSEC LDY #$00 ; Low mem STY dpBUFFER STY dpINDEX ; Page index readHEADER CLC readDATA PHP LDX theSLOT ; dpSLOT read1 LDA $C08C,X BPL *-3 read2 EOR #$D5 BNE read1 LDA $C08C,X BPL *-3 CMP #$AA BNE read2 LDA $C08C,X BPL *-3 CMP #$96 BEQ doHEADER PLP BCC readHEADER EOR #$AD BEQ doDATA BNE readHEADER * Read header doHEADER LDY #$03 ]lp LDA $C08C,X BPL *-3 ROL STA dpNIBBLE LDA $C08C,X BPL *-3 AND dpNIBBLE DEY BNE ]lp PLP LDX dpINDEX CMP tblINTER,X ; Right sector ? BNE readHEADER LDA L5703,X STA dpBUFFER+1 INC dpINDEX ; Next page index SEC BCS readDATA ; read data * Read data doDATA LDY #$56 ]lp STY dpNIBBLE LDY $C08C,X BPL *-3 EOR NIB0356-$80,Y LDY dpNIBBLE DEY STA NIB0300,Y BNE ]lp ]lp STY dpNIBBLE LDY $C08C,X BPL *-3 EOR NIB0356-$80,Y LDY dpNIBBLE STA (dpBUFFER),Y INY BNE ]lp * Deniblize doNIBBLE1 LDX #$56 ; Y equals 0 ;-) ]lp DEX BMI doNIBBLE1 LDA (dpBUFFER),Y LSR NIB0300,X ROL LSR NIB0300,X ROL STA (dpBUFFER),Y INY BNE ]lp * NEXT SECTOR DEC dpNBSEC BEQ doEND JMP readHEADER doEND RTS * * MOVE ARM * L576F STA tgtPHASE CMP |curPHASE BEQ L57CB LDA #$00 STA $A7 L577A LDA |curPHASE STA $A8 SEC SBC tgtPHASE BEQ L57B7 BCS L578D EOR #$FF INC |curPHASE BCC L5792 L578D ADC #$FE DEC |curPHASE L5792 CMP $A7 BCC L5798 LDA $A7 L5798 CMP #$0C BCS L579D TAY L579D SEC JSR L57BB LDA L57D7,Y JSR L57CC LDA $A8 CLC JSR L57BE LDA L57E3,Y JSR L57CC INC $A7 BNE L577A L57B7 JSR L57CC CLC L57BB LDA curPHASE L57BE AND #$03 ROL ORA theSLOT ; Slot TAX LDA $C080,X LDX theSLOT ; Slot L57CB RTS DS \ Please find the disk images of both sides @ http://www.brutaldeluxe.fr/crack/ Side 1: http://www.brutaldeluxe.fr/crack/KARATEKA_S1.dsk Side 2: http://www.brutaldeluxe.fr/crack/KARATEKA_S2.dsk I like that game! Antoine 7/2011