Index du Forum
IDENTIFICATION SERVEUR : 10.0.97.65 - CLIENT : 54.198.205.145

 FAQFAQ   RechercherRechercher   Liste des MembresListe des Membres   Groupes d'utilisateursGroupes d'utilisateurs   S'enregistrerS'enregistrer 
 ProfilProfil   Se connecter pour vérifier ses messages privésSe connecter pour vérifier ses messages privés   ConnexionConnexion 

Choplifter (Brøderbund, 1982)

 
Poster un nouveau sujet   Répondre au sujet     Index du Forum -> PROTECTION MALEFIQUE
Voir le sujet précédent :: Voir le sujet suivant  
Auteur Message
qkumba



Inscrit le: 29 Jan 2012
Messages: 165

MessagePosté le: Mer 22 Aoû 2012, 0:28    Sujet du message: Choplifter (Brøderbund, 1982) Répondre en citant

Choplifter is a famous Broderbund title, using the same protection method as Operation Apocalypse (a very rare title that I never saw anywhere except on my old drawer).

Already interesting protection - even the bootsector is protected by omitting the tail (DEAAEB).
This is possible because the boot PROM does not check for it due to space limitations
Let's grab the bootsector:

Code:

8600<C600.C6FCM
86F9:69 FF
8600G


Stage 0 loader:

Code:

0800                 .BYTE   1
         ;copy self to $200, continue at $20F
0801                 LDX     #0
0803 loc_803:
0803                 LDA     $800,X
0806                 STA     $200,X
0809                 INX
080A                 BNE     loc_803
080C                 JMP     $20F
080F                 LDY     #$AB
0811 loc_811:
0811                 TYA
0812                 STA     $3C
0814                 LSR     A
0815                 ORA     $3C
0817                 CMP     #$FF
0819                 BNE     loc_824
081B                 CPY     #$D5
081D                 BEQ     loc_824
081F                 TXA
0820                 STA     $800,Y
0823                 INX
0824 loc_824:
0824                 INY
0825                 BNE     loc_811
0827                 STY     $3D
0829                 STY     $26
082B                 LDA     #3
082D                 STA     $27
082F                 LDX     $2B
0831                 JSR     $25D
0834                 JSR     $2D1
0837                 JMP     $301
083A                 .BYTE    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0
084A                 .BYTE    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0
085A                 .BYTE    0,   0,   0
085D loc_85D:
085D                 CLC
085E loc_85E:
085E                 PHP
085F loc_85F:
085F                 LDA     $C08C,X
0862                 BPL     loc_85F
0864 loc_864:
0864                 EOR     #$D5
0866                 BNE     loc_85F
0868 loc_868:
0868                 LDA     $C08C,X
086B                 BPL     loc_868
086D                 CMP     #$AA
086F                 BNE     loc_864
0871                 NOP
0872 loc_872:
0872                 LDA     $C08C,X
0875                 BPL     loc_872
0877                 CMP     #$B5
0879                 BEQ     loc_884
087B                 PLP
087C                 BCC     loc_85D
087E                 EOR     #$AD
0880                 BEQ     loc_8A1
0882                 BNE     loc_85D
0884 loc_884:
0884                 LDY     #3
0886                 STY     $2A
0888 loc_888:
0888                 LDA     $C08C,X
088B                 BPL     loc_888
088D                 ROL     A
088E                 STA     $3C
0890 loc_890:
0890                 LDA     $C08C,X
0893                 BPL     loc_890
0895                 AND     $3C
0897                 DEY
0898                 BNE     loc_888
089A                 PLP
089B                 CMP     $3D
089D                 BNE     loc_85D
089F                 BCS     loc_85E
08A1 loc_8A1:
08A1                 LDY     #$9A
08A3 loc_8A3:
08A3                 STY     $3C
08A5 loc_8A5:
08A5                 LDY     $C08C,X
08A8                 BPL     loc_8A5
08AA                 EOR     $800,Y
08AD                 LDY     $3C
08AF                 DEY
08B0                 STA     $800,Y
08B3                 BNE     loc_8A3
08B5 loc_8B5:
08B5                 STY     $3C
08B7 loc_8B7:
08B7                 LDY     $C08C,X
08BA                 BPL     loc_8B7
08BC                 EOR     $800,Y
08BF                 LDY     $3C
08C1                 STA     ($26),Y
08C3                 INY
08C4                 BNE     loc_8B5
08C6 loc_8C6:
08C6                 LDY     $C08C,X
08C9                 BPL     loc_8C6
08CB                 EOR     $800,Y
08CE                 BNE     loc_85D
08D0                 RTS
08D1                 TAY
08D2 loc_8D2:
08D2                 LDX     #0
08D4 loc_8D4:
08D4                 LDA     $800,Y
08D7                 LSR     A
08D8                 ROL     $3CC,X
08DB                 LSR     A
08DC                 ROL     $399,X
08DF                 STA     $3C
08E1                 LDA     ($26),Y
08E3                 ASL     A
08E4                 ASL     A
08E5                 ASL     A
08E6                 ORA     $3C
08E8                 STA     ($26),Y
08EA                 INY
08EB                 INX
08EC                 CPX     #$33 ; '3'
08EE                 BNE     loc_8D4
08F0                 DEC     $2A
08F2                 BNE     loc_8D2
08F4                 CPY     $300
08F7                 BNE     loc_8FC
08F9                 RTS
08FA                 .BYTE    0,   0
08FC loc_8FC:
08FC                 JMP     $FF2D
08FF                 .BYTE   0


Trace to stage 0.1:

Code:

86F8:A9 5 8D D 8 A9 87 8D E 8 4C 1 8 4C 69 FF
8600G


Now we have code at $200, let's look at $20F.

Code:

         ;build 5-and-3 nibbilisation table
020F loc_20F:
020F                 LDY     #$AB
0211 loc_211:
0211                 TYA
0212                 STA     $3C
0214                 LSR     A
0215                 ORA     $3C
0217                 CMP     #$FF
0219                 BNE     loc_224
021B                 CPY     #$D5
021D                 BEQ     loc_224
021F                 TXA
0220                 STA     $800,Y
0223                 INX
0224 loc_224:
0224                 INY
0225                 BNE     loc_211

         ;prepare to read another sector 0 but different address marker so it's okay
         ;read to $300
0227                 STY     $3D
0229                 STY     $26
022B                 LDA     #3
022D                 STA     $27
022F                 LDX     $2B
0231                 JSR     loc_25D   ;read sector
0234                 JSR     loc_2D1   ;decode sector
0237                 JMP     $301   ;continue boot at stage 1
023A                 .BYTE    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0
024A                 .BYTE    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0
025A                 .BYTE    0,   0,   0

         ;read a sector, D5AAB5 and D5AAAD
025D loc_25D:
025D                 CLC
025E loc_25E:
025E                 PHP
025F loc_25F:
025F                 LDA     $C08C,X
0262                 BPL     loc_25F
0264 loc_264:
0264                 EOR     #$D5
0266                 BNE     loc_25F
0268 loc_268:
0268                 LDA     $C08C,X
026B                 BPL     loc_268
026D                 CMP     #$AA
026F                 BNE     loc_264
0271                 NOP
0272 loc_272:
0272                 LDA     $C08C,X
0275                 BPL     loc_272
0277                 CMP     #$B5
0279                 BEQ     loc_284
027B                 PLP
027C                 BCC     loc_25D
027E                 EOR     #$AD
0280                 BEQ     loc_2A1
0282                 BNE     loc_25D
0284 loc_284:
0284                 LDY     #3
0286                 STY     $2A
0288 loc_288:
0288                 LDA     $C08C,X
028B                 BPL     loc_288
028D                 ROL     A
028E                 STA     $3C
0290 loc_290:
0290                 LDA     $C08C,X
0293                 BPL     loc_290
0295                 AND     $3C
0297                 DEY
0298                 BNE     loc_288
029A                 PLP
029B                 CMP     $3D
029D                 BNE     loc_25D
029F                 BCS     loc_25E
02A1 loc_2A1:
02A1                 LDY     #$9A
02A3 loc_2A3:
02A3                 STY     $3C
02A5 loc_2A5:
02A5                 LDY     $C08C,X
02A8                 BPL     loc_2A5
02AA                 EOR     $800,Y
02AD                 LDY     $3C
02AF                 DEY
02B0                 STA     $800,Y
02B3                 BNE     loc_2A3
02B5 loc_2B5:
02B5                 STY     $3C
02B7 loc_2B7:
02B7                 LDY     $C08C,X
02BA                 BPL     loc_2B7
02BC                 EOR     $800,Y
02BF                 LDY     $3C
02C1                 STA     ($26),Y
02C3                 INY
02C4                 BNE     loc_2B5
02C6 loc_2C6:
02C6                 LDY     $C08C,X
02C9                 BPL     loc_2C6
02CB                 EOR     $800,Y
02CE                 BNE     loc_25D
02D0                 RTS
02D1 loc_2D1:
02D1                 TAY
02D2 loc_2D2:
02D2                 LDX     #0
02D4 loc_2D4:
02D4                 LDA     $800,Y
02D7                 LSR     A
02D8                 ROL     $3CC,X
02DB                 LSR     A
02DC                 ROL     $399,X
02DF                 STA     $3C
02E1                 LDA     ($26),Y
02E3                 ASL     A
02E4                 ASL     A
02E5                 ASL     A
02E6                 ORA     $3C
02E8                 STA     ($26),Y
02EA                 INY
02EB                 INX
02EC                 CPX     #$33
02EE                 BNE     loc_2D4
02F0                 DEC     $2A
02F2                 BNE     loc_2D2
02F4                 CPY     $300
02F7                 BNE     loc_2FC
02F9                 RTS
02FA                 .BYTE    0,   0
02FC loc_2FC:
02FC                 JMP     $FF2D


(continued)


Dernière édition par qkumba le Ven 19 Oct 2012, 20:53; édité 2 fois
Revenir en haut de page
Voir le profil de l'utilisateur Envoyer un message privé Visiter le site web de l'utilisateur
qkumba



Inscrit le: 29 Jan 2012
Messages: 165

MessagePosté le: Mer 22 Aoû 2012, 0:32    Sujet du message: boot-tracing Choplifter Répondre en citant

Trace to stage 1 loader:

Code:

8705:A9 12 8D 38 2 A9 87 8D 39 2 4C F 2 4C 69 FF
8600G


Now we have code at $300, let's look at $301.

Code:

0300                 .BYTE $99      ;checksum
0301                 LDX     #$2E
0303                 TXS
0304                 STY     $48
0306                 LDX     #0
0308 loc_308:
0308                 LDY     $300,X
030B                 DEY
030C                 LDA     #$EA
030E                 JSR     loc_326
0311                 INY
0312                 LDA     $48
0314                 JSR     loc_326
0317                 DEY
0318                 LDA     $48
031A                 JSR     loc_326
031D                 DEY
031E                 TYA
031F loc_31F:
031F                 STA     $100,X   ;nasty stack usage
0322                 INX
0323                 BNE     loc_308
0325                 RTS
0326 loc_326:
0326                 STA     0
0328                 TYA
0329                 EOR     0      ;a decoder!
032B                 TAY
032C                 RTS

         ;encoded bytes
032D                 .BYTE  $EA, $FF, $C6, $EF, $4C, $B6, $68, $E9, $EF, $76, $16, $4C, $EA, $6A,   6, $70
033D                 .BYTE  $1F, $74, $47, $76, $7F,   6, $2E, $26, $15, $10, $1F, $33, $1F, $27, $E6, $66
034D                 .BYTE  $1F, $4B, $6F, $56, $4B, $6F, $56, $47, $26, $53, $1F, $5F,   6, $7F,   6, $2E
035D                 .BYTE  $26, $17, $10, $1F, $26,   3, $33, $C5, $A4, $A4, $A4, $A4, $E7, $56, $62, $12
036D                 .BYTE  $E9, $6B, $1B, $E9, $62, $1C, $ED, $6B, $1D, $ED, $A7, $33, $6B, $1A, $ED, $4B
037D                 .BYTE  $6C, $56, $4B, $BF, $56, $4B, $A3, $56, $4B, $96, $56, $F6, $66, $EF, $47, $EA
038D                 .BYTE  $AE, $AE, $B6, $4C, $EA, $76, $16, $6A, $11, $70, $1E, $70, $14, $50, $C5, $F6
039D                 .BYTE    3, $EF, $27, $23, $26, $17, $F6,   3, $EF, $27, $3B, $26,   3, $F6,   3, $EF
03AD                 .BYTE  $27, $23, $26,   3, $5B, $62, $56, $E6, $15, $C4, $53, $17, $5B, $62, $56, $E6
03BD                 .BYTE  $15, $B3, $17, $7F, $11, $2E, $26,   2, $E8, $16, $56, $5B, $62, $56, $E6, $15
03CD                 .BYTE  $27, $3B, $26, $29, $10, $1E, $30, $14, $26, $34, $F6,   3, $EF, $53, $1C, $F6
03DD                 .BYTE    3, $EF, $53, $1F, $F6,   3, $EF, $53,   6, $F6,   3, $EF, $53, $1D, $F6,   3
03ED                 .BYTE  $EF, $13,   6,   6, $E7, $82, $1C, $ED, $5B, $62, $56, $E6, $15, $B6, $48, $73
03FD                 .BYTE  $D3, $74, $16


This is a particularly tricky one because we can't jump to the monitor anymore without destroying the decoded code.
We also don't have enough bytes to patch a jump after the decoding finishes.
It might seem like we can just redirect the write at $31F to another memory location so that we can intercept the end of the decoding and examine the code...
but this is Broderbund, you know that we can't do that, either. The data on the stack are checksummed later, if we patch the routine, the checksum will change.
Let's copy it to $6300 instead, and redirect the load at $308.

Code:

8712:A2 0 BD 0 3 9D 0 63 E8 D0 F7 A9 63 8D A 3 A9 4C 8D 1F 3 A9 34 8D 20 3 A9 87 8D 21 3 4C 1 3
8734:9D 0 61 E8 F0 3 4C 8 3 4C 69 FF
8600G


Now we have our decoded code at $6100 instead of $100, but we'll use the original address to that the routines match.

Code:

0100                 .BYTE  $6F, $4C, $C8, $74, $6A, $AE, $4C, $16, $52, $16, $F5, $6E, $3F,   4, $F6, $D0
0110                 .BYTE  $F5, $2E, $4B, $AE, $F6, $D0, $F5, $6E, $4B, $AE, $F6, $D0, $F5, $6E, $7E, $73
0120                 .BYTE  $16, $E7,  $E, $26, $15, $B6, $6B, $16, $7E, $AB, $16, $4E, $B6,   4, $11, $30
0130                 .BYTE    1, $A2, $60, $8E, $FF,   1, $A0,   0, $A2,   4, $84, $F0, $86, $F1, $9A, $A9
0140                 .BYTE  $A0, $91, $F0, $C8, $D0, $FB, $E6, $F1, $A5, $F1, $C9, $10, $90, $F1, $AD, $81
0150                 .BYTE  $C0, $AD, $81, $C0, $A9, $D0, $85, $F1, $B1, $F0, $91, $F0, $C8, $D0, $F9, $E6
0160                 .BYTE  $F1, $D0, $F5, $A5, $2B, $4A, $4A, $4A, $4A,   9, $C0, $8C, $FC, $FF, $8D, $FD
0170                 .BYTE  $FF, $8C, $F2,   3, $8D, $F3,   3, $49, $A5, $8D, $F4,   3, $AD, $82, $C0, $AD
0180                 .BYTE  $51, $C0, $AD, $55, $C0, $AD, $80, $C0, $20, $90,   1, $A9,   4, $48, $48, $60
0190                 .BYTE  $A2,   4, $A0,   0, $84, $F7, $86, $F8, $86, $FA, $A6, $2B, $20, $F5,   1, $C9
01A0                 .BYTE  $D5, $D0, $F9, $20, $F5,   1, $C9, $DD, $D0, $F5, $20, $F5,   1, $C9, $D5, $D0
01B0                 .BYTE  $F5, $BD, $8C, $C0, $10, $FB, $2A, $85, $F9, $BD, $8C, $C0, $10, $FB, $25, $F9
01C0                 .BYTE  $91, $F7, $C8, $D0, $EC,  $E,   0, $C0, $BD, $8C, $C0, $10, $FB, $C9, $DD, $D0
01D0                 .BYTE  $BF, $E6, $F8, $C6, $FA, $D0, $DA, $20, $F5,   1, $85, $F2, $20, $F5,   1, $85
01E0                 .BYTE  $F1, $20, $F5,   1, $85, $F0, $20, $F5,   1, $85, $F3, $20, $F5,   1, $C5, $F0
01F0                 .BYTE  $F0,   9, $6C, $F2,   3, $BD, $8C, $C0, $10, $FB, $60, $AE, $65,   5, $9A,   0


Stack pointer was #$2E, which is 1 less than the address that's fetched during RTS, so we read $12F to see where to go next.

Code:

12F                  .WORD $130


So return address is $130, which is also 1 less than the address that's used, so we continue from $131.

Code:

0131                 LDX     #$60
0133                 STX     byte_1FF   ;place RTS because the decoder couldn't do it
0136                 LDY     #0
0138                 LDX     #4
013A                 STY     $F0
013C                 STX     $F1
013E                 TXS
013F loc_13F:
013F                 LDA     #$A0
0141 loc_141:
0141                 STA     ($F0),Y   ;clear text screens and some other memory
0143                 INY
0144                 BNE     loc_141
0146                 INC     $F1
0148                 LDA     $F1
014A                 CMP     #$10
014C                 BCC     loc_13F
014E                 LDA     $C081
0151                 LDA     $C081
0154                 LDA     #$D0
0156                 STA     $F1
0158 loc_158:
0158                 LDA     ($F0),Y
015A                 STA     ($F0),Y
015C                 INY
015D                 BNE     loc_158
015F                 INC     $F1
0161                 BNE     loc_158   ;enable 64k support
0163                 LDA     $2B
0165                 LSR     A
0166                 LSR     A
0167                 LSR     A
0168                 LSR     A
0169                 ORA     #$C0
016B                 STY     $FFFC
016E                 STA     $FFFD
0171                 STY     $3F2
0174                 STA     $3F3
0177                 EOR     #$A5
0179                 STA     $3F4   ;point reset and break vectors to boot PROM
017C                 LDA     $C082
017F                 LDA     $C051
0182                 LDA     $C055   ;select second text screen to hide first one
0185                 LDA     $C080
0188                 JSR     loc_190
018B                 LDA     #4
018D                 PHA
018E                 PHA
018F                 RTS

         ;prepare to 4x large sector to $400-7FF
0190 loc_190:
0190                 LDX     #4
0192                 LDY     #0
0194                 STY     $F7
0196                 STX     $F8
0198                 STX     $FA
019A                 LDX     $2B

         ;read address marker (D5DDD5)
         ;address marker identifies the sector
019C loc_19C:
019C                 JSR     sub_1F5
019F loc_19F:
019F                 CMP     #$D5
01A1                 BNE     loc_19C
01A3                 JSR     sub_1F5
01A6 loc_1A6:
01A6                 CMP     #$DD
01A8                 BNE     loc_19F
01AA                 JSR     sub_1F5
01AD                 CMP     #$D5
01AF                 BNE     loc_1A6

         ;4-and-4 read/decode
01B1 loc_1B1:
01B1                 LDA     $C08C,X
01B4                 BPL     loc_1B1
01B6                 ROL     A
01B7                 STA     $F9
01B9 loc_1B9:
01B9                 LDA     $C08C,X
01BC                 BPL     loc_1B9
01BE                 AND     $F9
01C0                 STA     ($F7),Y
01C2                 INY
01C3                 BNE     loc_1B1
01C5                 ASL     $C000

         ;tail check and select next sector if okay
01C8 loc_1C8:
01C8                 LDA     $C08C,X
01CB                 BPL     loc_1C8
01CD                 CMP     #$DD
01CF                 BNE     loc_190
01D1                 INC     $F8
01D3                 DEC     $FA
01D5                 BNE     loc_1B1

         ;read next address marker and tail comparison bytes
         ;this means that each sector is depending on the previous one
         ;so if one sector is bad then entire disk is useless
01D7                 JSR     sub_1F5
01DA                 STA     $F2
01DC                 JSR     sub_1F5
01DF                 STA     $F1
01E1                 JSR     sub_1F5
01E4                 STA     $F0
01E6                 JSR     sub_1F5
01E9                 STA     $F3
01EB                 JSR     sub_1F5
01EE                 CMP     $F0
01F0                 BEQ     loc_1FB
01F2                 JMP     ($3F2)
01F5 loc_1F5:
01F5                 LDA     $C08C,X
01F8                 BPL     loc_1F5
01FA                 RTS
01FB loc_1FB:
01FB                 LDX     $565
01FE                 TXS
01FF byte_1FF:       .BYTE 0   ;replaced by RTS from above


A successful read sets a new stack pointer from the value at $565.
A wrong value at that location will cause the RTS at $1FF to jump to somewhere unexpected.
So the load at $1FB would be a good place to patch next.

(continued)
Revenir en haut de page
Voir le profil de l'utilisateur Envoyer un message privé Visiter le site web de l'utilisateur
qkumba



Inscrit le: 29 Jan 2012
Messages: 165

MessagePosté le: Mer 22 Aoû 2012, 0:35    Sujet du message: boot-tracing Choplifter Répondre en citant

First we undo the redirection so the stack will be written as intended:

Code:

8736:1


Then we have to redirect the next read so that it doesn't go to the screen anymore. Let's use $6400.
We have to set the number of sectors ourselves. Then we add add our new patch.

Code:

873D:A9 64 8D 91 1 A9 EA 8D 98 1 8D 99 1 A9 4 85 FA A9 4C 8D FB 1 A9 60 8D FC 1 A9 87 8D FD 1 4C 31 1 4C 60 87
8600G


We can't jump to the monitor anymore, so we just hang the system after the read.
If we insert a blank disk and hit ctrl-reset, we can reboot and keep the read memory.

Stage 2 loader:

Code:

0400 loc_400:
0400
0400                 PLA
0401                 CLC
0402                 ADC     $48
0404                 STA     $48
0406                 DEX
0407                 BNE     loc_400
0409                 LDA     #$14
040B                 JSR     loc_772
040E                 LDX     #1
0410                 LDA     #5
0412                 JSR     loc_700
0415                 LDA     #$16
0417                 JSR     loc_772
041A                 LDA     $48
041C                 EOR     $195
041F                 TAX
0420                 TXS
0421                 JMP     ($200)
0424 loc_424:
0424                 LDA     $C08C,X
0427                 BPL     loc_424
0429                 CMP     #$D5
042B                 BNE     loc_424
042D loc_42D:
042D                 LDA     $C08C,X
0430                 BPL     loc_42D
0432                 CMP     #$FF
0434                 BNE     loc_424
0436                 RTS
0437                 JSR     loc_424
043A                 JMP     loc_424
043D                 JMP     ($200)
0440                 LDX     $2B
0442                 STX     $202
0445                 LDX     #$20
0447                 LDA     #0
0449 loc_449:
0449
0449                 STA     $2000
044C                 INC     loc_449+1
044F                 BNE     loc_449
0451                 INC     loc_449+2
0454                 DEX
0455                 BNE     loc_449
0457                 LDA     $C052
045A                 LDA     $C057
045D                 LDA     $C054
0460                 LDA     $C050
0463                 NOP
0464                 NOP
0465                 NOP
0466                 NOP
0467                 STX     $F4
0469                 LDA     #$20
046B loc_46B:
046B                 PHA
046C                 LDA     #2
046E                 JSR     loc_7F0
0471                 PLA
0472                 PHA
0473 loc_473:
0473                 LDX     #8
0475                 JSR     loc_700
0478                 PLA
0479                 CLC
047A                 ADC     loc_473+1
047D                 CMP     #$60
047F                 BCC     loc_46B
0481                 LDA     #2
0483                 JSR     loc_7F0
0486                 LDA     #$60
0488                 LDX     #4
048A loc_48A:
048A                 JSR     loc_700
048D                 DEC     loc_48A+2
0490                 DEC     loc_48A+2
0493                 DEC     loc_48A+2
0496                 LDX     #0
0498                 JMP     (loc_48A+1)
049B                 LDX     loc_599
049E                 LDY     #$9A
04A0                 LDA     #$FF
04A2                 STA     $A0
04A5 loc_4A5:
04A5                 LDA     $500,Y
04A8                 STA     $200,Y
04AB                 CPY     #$F0
04AD                 BCS     loc_4B5
04AF                 LDA     $600,Y
04B2                 STA     $300,Y
04B5 loc_4B5:
04B5                 INY
04B6                 BNE     loc_4A5
04B8                 LDA     #3
04BA                 LDX     #$20
04BC                 JSR     $3A3
04BF                 LDX     #$26
04C1                 STX     $36
04C3                 STA     $37
04C5                 STX     $38
04C7                 STA     $39
04C9                 STX     $3F0
04CC                 STA     $3F1
04CF                 LDX     #$FF
04D1                 JSR     loc_4E2
04D4                 JSR     loc_4E0
04D7                 LDA     $185
04DA                 AND     #$5F
04DC                 TAX
04DD                 JMP     loc_61D
04E0 loc_4E0:
04E0                 LDX     #0
04E2 loc_4E2:
04E2                 LDY     #0
04E4                 LDA     #$C
04E6                 STY     0
04E8                 STA     1
04EA loc_4EA:
04EA                 TXA
04EB loc_4EB:
04EB                 STA     (0),Y
04ED                 CMP     (0),Y
04EF                 BNE     loc_4FD
04F1                 INY
04F2                 BPL     loc_4EB
04F4                 INC     1
04F6                 LDA     1
04F8                 CMP     #$C0
04FA                 BCC     loc_4EA
04FC                 RTS
04FD loc_4FD:
04FD                 JMP     $323
0500                 .WORD $6300
0502                 .WORD $4060
0504                 .WORD $42
0506                 .BYTE 0
0507                 LDX     $202
050A                 LDA     $C089,X
050D                 LDA     #0
050F                 JSR     $311
0512                 LDA     #$42
0514                 JSR     $2CD
0517                 LDA     #$40
0519                 STA     $203
051C loc_51C:
051C                 DEY
051D                 BNE     loc_527
051F                 DEC     $203
0522                 BNE     loc_527
0524                 JMP     $2B8
0527 loc_527:
0527                 LDA     $C08C,X
052A                 BPL     loc_527
052C loc_52C:
052C                 CMP     #$D5
052E                 BNE     loc_51C
0530 loc_530:
0530                 LDA     $C08C,X
0533                 BPL     loc_530
0535 loc_535:
0535                 CMP     #$FF
0537                 BNE     loc_52C
0539 loc_539:
0539                 LDA     $C08C,X
053C                 BPL     loc_539
053E                 CMP     #$DD
0540                 BNE     loc_535
0542                 LDA     #$44
0544                 JSR     $2CD
0547                 LDY     #$FF
0549                 LDA     $C08D,X
054C                 LDA     $C08E,X
054F                 STA     $C08F,X
0552                 ORA     $C08C,X
0555                 LDA     #$80
0557                 JSR     $311
055A                 JSR     $311
055D                 LDA     $C08D,X
0560                 LDA     $C08E,X
0563                 TYA
0564                 STA     $C08F,X
0567                 ORA     $C08C,X
056A                 PHA
056B                 PLA
056C loc_56C:
056C                 CMP     (0,X)
056E                 CMP     (0,X)
0570                 NOP
0571                 INY
0572                 STA     $C08D,X
0575                 ORA     $C08C,X
0578                 LDA     $2BE,Y
057B                 BNE     loc_56C
057D                 TAY
057E                 NOP
057F                 NOP
0580 loc_580:
0580                 LDA     0,Y
0583                 PHA
0584                 LSR     A
0585                 ORA     #$AA
0587                 STA     $C08D,X
058A                 CMP     $C08C,X
058D                 CMP     (0,X)
058F                 NOP
0590                 NOP
0591                 PHA
0592                 PLA
0593                 PLA
0594                 ORA     #$AA
0596                 STA     $C08D,X
0599 loc_599:
0599                 CMP     $C08C,X
059C                 PHA
059D                 PLA
059E                 INY
059F                 BNE     loc_580
05A1                 LDA     #$D5
05A3                 CMP     (0,X)
05A5                 NOP
05A6                 NOP
05A7                 STA     $C08D,X
05AA                 ORA     $C08C,X
05AD                 LDA     #8
05AF                 JSR     $311
05B2                 LDA     $C08E,X
05B5                 LDA     $C08C,X
05B8                 LDA     $C088,X
05BB                 NOP
05BC                 NOP
05BD                 RTS
05BE                 .WORD $3FFF,$F3CF,$FFFC,$CF3F,$FCF3,$D5FF,$DDFF
05CC                 .BYTE   0
05CD                 STA     $205
05D0 loc_5D0:
05D0                 LDA     $204
05D3                 STA     $206
05D6                 SEC
05D7                 SBC     $205
05DA                 BEQ     locret_60E
05DC                 BCS     loc_5E3
05DE                 INC     $204
05E1                 BCC     loc_5E6
05E3 loc_5E3:
05E3                 DEC     $204
05E6 loc_5E6:
05E6                 JSR     $301
05E9                 JSR     $30F
05EC                 LDA     $206
05EF                 AND     #3
05F1                 ASL     A
05F2                 ORA     $202
05F5                 TAY
05F6                 LDA     $C080,Y
05F9                 JSR     $30F
05FC                 BEQ     loc_5D0
05FE                 JSR     $30F
0601                 LDA     $204
0604                 AND     #3
0606                 ASL     A
0607                 ORA     $202
060A                 TAY
060B                 LDA     $C081,Y
060E locret_60E:
060E                 RTS
060F                 LDA     #$30
0611                 SEC
0612 loc_612:
0612                 PHA
0613 loc_613:
0613                 SBC     #1
0615                 BNE     loc_613
0617                 PLA
0618                 SBC     #1
061A                 BNE     loc_612
061C                 RTS
061D loc_61D:
061D                 JMP     loc_6FC
0620                 LDA     #$D2
0622                 .BYTE $2C
0623                 LDA     #$A1
0625                 .BYTE $2C
0626                 LDA     #$D0
0628                 .BYTE $2C
0629                 LDA     #$CC
062B                 .BYTE $2C
062C                 LDA     #$C4
062E                 .BYTE $2C
062F                 LDA     #$CD
0631                 STA     $205
0634                 LDX     #4
0636                 LDY     #0
0638                 STY     0
063A                 STX     1
063C                 LDA     #$A0
063E loc_63E:
063E                 STA     (0),Y
0640                 INY
0641                 BNE     loc_63E
0643                 INC     1
0645                 DEX
0646                 BNE     loc_63E
0648                 LDA     $205
064B                 STA     loc_400
064E                 JSR     $FB2F
0651                 LDA     #0
0653 loc_653:
0653                 STA     $800
0656                 INC     $354
0659                 BNE     loc_653
065B                 INC     $355
065E                 LDY     $355
0661                 CPY     #$50
0663                 BNE     loc_66E
0665 loc_665:
0665                 BIT     $C030
0668 loc_668:
0668                 DEX
0669                 BNE     loc_668
066B                 DEY
066C                 BNE     loc_665
066E loc_66E:
066E                 CPY     #$C0
0670                 BCC     loc_653
0672 loc_672:
0672                 STA     0,X
0674                 STA     $102,X
0677                 STA     $204,X
067A                 INX
067B                 BNE     loc_672
067D                 LDA     $202
0680                 LSR     A
0681                 LSR     A
0682                 LSR     A
0683                 LSR     A
0684                 ORA     #$C0
0686                 STA     $3A2
0689                 JSR     $3A3
068C                 LDY     #$F5
068E                 TXA
068F loc_68F:
068F                 STA     $300,Y
0692                 INY
0693                 CPY     #$90
0695                 BNE     loc_68F
0697                 JSR     $FE89
069A                 JSR     $FE93
069D                 JSR     $FE84
06A0                 JMP     $C600
06A3                 LDY     $C083
06A6                 LDY     $C083
06A9                 STX     $3F2
06AC                 STA     $3F3
06AF                 STX     $FFFC
06B2                 STA     $FFFD
06B5                 PHA
06B6                 EOR     #$A5
06B8                 STA     $3F4
06BB                 PLA
06BC                 RTS
06BD                 .BYTE    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0
06CD                 .BYTE    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0
06DD                 .BYTE    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0
06ED                 .BYTE    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0
06FC loc_6FC:
06FC                 DEX
06FD                 DEX
06FE                 TXS
06FF                 RTS
0700 loc_700:
0700                 STX     $FA
0702                 STA     $F7
0704 loc_704:
0704                 LDX     $FA
0706                 STX     $FC
0708                 LDY     #0
070A                 LDA     $F7
070C                 STY     $F8
070E                 STA     $F9
0710                 LDX     $2B
0712 loc_712:
0712                 JSR     loc_76C
0715 loc_715:
0715                 CMP     $F0
0717                 BNE     loc_712
0719                 JSR     loc_76C
071C loc_71C:
071C                 CMP     $F1
071E                 BNE     loc_715
0720                 JSR     loc_76C
0723                 CMP     $F2
0725                 BNE     loc_71C
0727 loc_727:
0727                 LDA     $C08C,X
072A                 BPL     loc_727
072C                 ROL     A
072D                 STA     $FB
072F loc_72F:
072F                 LDA     $C08C,X
0732                 BPL     loc_72F
0734                 AND     $FB
0736                 STA     ($F8),Y
0738                 INY
0739                 BNE     loc_727
073B                 ASL     $C000
073E loc_73E:
073E                 LDA     $C08C,X
0741                 BPL     loc_73E
0743                 CMP     $F3
0745                 BNE     loc_704
0747                 INC     $F9
0749                 DEC     $FC
074B                 BNE     loc_727

         ;read address marker and tail comparison bytes for next sector
074D                 JSR     loc_76C
0750                 STA     $F2
0752                 JSR     loc_76C
0755                 STA     $F1
0757                 JSR     loc_76C
075A                 STA     $F0
075C                 JSR     loc_76C
075F                 STA     $F3
0761                 JSR     loc_76C
0764                 CMP     $F0
0766                 BNE     loc_769
0768                 RTS
0769 loc_769:
0769                 JMP     $32C
076C loc_76C:
076C                 LDA     $C08C,X
076F                 BPL     loc_76C
0771                 RTS
0772 loc_772:
0772                 STA     $FD
0774                 CMP     $F4
0776                 BEQ     locret_7C7
0778                 LDA     #0
077A                 STA     $F5
077C loc_77C:
077C                 LDA     $F4
077E                 STA     $F6
0780                 SEC
0781                 SBC     $FD
0783                 BEQ     loc_7B6
0785                 BCS     loc_78D
0787                 EOR     #$FF
0789                 INC     $F4
078B                 BCC     loc_791
078D loc_78D:
078D                 ADC     #$FE
078F                 DEC     $F4
0791 loc_791:
0791                 CMP     $F5
0793                 BCC     loc_797
0795                 LDA     $F5
0797 loc_797:
0797                 CMP     #$C
0799                 BCS     loc_79C
079B                 TAY
079C loc_79C:
079C                 SEC
079D                 JSR     loc_7BA
07A0                 LDA     byte_7D3,Y
07A3                 JSR     loc_7C8
07A6                 LDA     $F6
07A8                 CLC
07A9                 JSR     loc_7BC
07AC                 LDA     byte_7DF,Y
07AF                 JSR     loc_7C8
07B2                 INC     $F5
07B4                 BNE     loc_77C
07B6 loc_7B6:
07B6                 JSR     loc_7C8
07B9                 CLC
07BA loc_7BA:
07BA                 LDA     $F4
07BC loc_7BC:
07BC                 AND     #3
07BE                 ROL     A
07BF                 ORA     $2B
07C1                 TAX
07C2                 LDA     $C080,X
07C5                 LDX     $2B
07C7 locret_7C7:
07C7                 RTS
07C8 loc_7C8:
07C8                 LDX     #$13
07CA loc_7CA:
07CA                 DEX
07CB                 BNE     loc_7CA
07CD                 SEC
07CE                 SBC     #1
07D0                 BNE     loc_7C8
07D2                 RTS
07D3 byte_7D3:       .BYTE    1, $30, $28, $24, $20, $1E, $1D, $1C, $1C, $1C, $1C, $1C
07DF byte_7DF:       .BYTE  $70, $2C, $26, $22, $1F, $1E, $1D, $1C, $1C, $1C, $1C, $1C
07EB                 .BYTE    0,   0,   0,   0,   0
07F0 loc_7F0:
07F0                 CLC
07F1                 ADC     $F4
07F3                 JMP     loc_772
07F6                 .BYTE    0,   0,   0,   0,   0,   0,   0,   0,   0,   0


Let's check that stack pointer again. $565 is #$8F, which is 1 less than the address that's fetched during RTS, so we read $190 to see where to go next.

Code:

190                  .WORD $64A2


That's the location of our redirection, so it's in the $64xx range instead of the $4xx range, but the effect is the same.
So return address is really $4A2, which is also 1 less than the address that's used, so we continue at $4A3.
If you look in the original disassembly, you won't see 04A3 there, only 04A2 and 04A5.
That's because there's an anti-disassembly trick, which is hiding the LDY instruction. :-)

Code:

         ;copy miscellaneous routines to $200-3EF
04A3                 LDY     #0
04A5 loc_4A5:
04A5                 LDA     $500,Y
04A8                 STA     $200,Y
04AB                 CPY     #$F0
04AD                 BCS     loc_4B5
04AF                 LDA     $600,Y
04B2                 STA     $300,Y
04B5 loc_4B5:
04B5                 INY
04B6                 BNE     loc_4A5

         ;point reset and break vectors to $320 ($6620)
04B8                 LDA     #3
04BA                 LDX     #$20
04BC                 JSR     $3A3

         ;point CSW, KSW, and ROM break vectors to $326 ($6626)
04BF                 LDX     #$26
04C1                 STX     $36
04C3                 STA     $37
04C5                 STX     $38
04C7                 STA     $39
04C9                 STX     $3F0
04CC                 STA     $3F1

         ;write memory pattern
         ;this is a particular problem because it will destroy our code
         ;unless... there's a weakness that we can exploit
         ;and of course there is
         ;the pattern is written only to the first #$80 bytes
         ;so if we write our code in the address range $xx80-xxff
         ;then we won't be touched
04CF                 LDX     #$FF
04D1                 JSR     loc_4E2
04D4                 JSR     loc_4E0
04D7                 LDA     $185
04DA                 AND     #$5F
04DC                 TAX
04DD                 JMP     loc_61D
04E0 loc_4E0:
04E0                 LDX     #0
04E2 loc_4E2:
04E2                 LDY     #0
04E4                 LDA     #$C
04E6                 STY     0
04E8                 STA     1
04EA loc_4EA:
04EA                 TXA
04EB loc_4EB:
04EB                 STA     (0),Y
04ED                 CMP     (0),Y
04EF                 BNE     loc_4FD
04F1                 INY
04F2                 BPL     loc_4EB
04F4                 INC     1
04F6                 LDA     1
04F8                 CMP     #$C0
04FA                 BCC     loc_4EA
04FC                 RTS
04FD loc_4FD:
04FD                 JMP     $323
...
061D loc_61D:
061D                 JMP     loc_6FC
...
06FC loc_6FC:
06FC                 DEX
06FD                 DEX
06FE                 TXS
06FF                 RTS


Regardless of the memory pattern problem, we are interested in the value at $185 (from $4D7) to know where to go next.
$185 is #$AD, then there's the AND #$5F, which gives us #$0D. The jump at $4DD reaches $6FC which decrements the value to #$0B.
As before, that's 1 less than the address that's fetched during RTS, so we read $10C to see where to go next.

Code:

10C                  .WORD $43F


As usual, it's 1 less than the address that's used, so we continue at $440.

Code:

0440                 LDX     $2B
0442                 STX     $202

         ;erase first graphics screen
0445                 LDX     #$20
0447                 LDA     #0
0449 loc_449:
0449
0449                 STA     $2000
044C                 INC     loc_449+1
044F                 BNE     loc_449
0451                 INC     loc_449+2
0454                 DEX
0455                 BNE     loc_449

         ;enable graphics mode
0457                 LDA     $C052
045A                 LDA     $C057
045D                 LDA     $C054
0460                 LDA     $C050
0463                 NOP
0464                 NOP
0465                 NOP
0466                 NOP
0467                 STX     $F4

         ;prepare to read to $2000-5FFF (title screen and other code)
0469                 LDA     #$20
046B loc_46B:
046B                 PHA

         ;seek to next half track
046C                 LDA     #2
046E                 JSR     loc_7F0
0471                 PLA
0472                 PHA

         ;read 8 sectors
0473 loc_473:
0473                 LDX     #8
0475                 JSR     loc_700
0478                 PLA
0479                 CLC
047A                 ADC     loc_473+1
047D                 CMP     #$60
047F                 BCC     loc_46B

         ;seek to next half track
0481                 LDA     #2
0483                 JSR     loc_7F0

         ;read 4 sectors to $6000-63FF
         ;the loaded routine is a misguided attempt to detect mods
0486                 LDA     #$60
0488                 LDX     #4
048A loc_48A:
048A                 JSR     loc_700

         ;adjust next pointer and jump
048D                 DEC     loc_48A+2
0490                 DEC     loc_48A+2
0493                 DEC     loc_48A+2
0496                 LDX     #0
0498                 JMP     (loc_48A+1)
...
0772 loc_772:
0772                 STA     $FD
0774                 CMP     $F4
0776                 BEQ     locret_7C7
0778                 LDA     #0
077A                 STA     $F5
077C loc_77C:
077C                 LDA     $F4
077E                 STA     $F6
0780                 SEC
0781                 SBC     $FD
0783                 BEQ     loc_7B6
0785                 BCS     loc_78D
0787                 EOR     #$FF
0789                 INC     $F4
078B                 BCC     loc_791
078D loc_78D:
078D                 ADC     #$FE
078F                 DEC     $F4
0791 loc_791:
0791                 CMP     $F5
0793                 BCC     loc_797
0795                 LDA     $F5
0797 loc_797:
0797                 CMP     #$C
0799                 BCS     loc_79C
079B                 TAY
079C loc_79C:
079C                 SEC
079D                 JSR     loc_7BA
07A0                 LDA     byte_7D3,Y
07A3                 JSR     loc_7C8
07A6                 LDA     $F6
07A8                 CLC
07A9                 JSR     loc_7BC
07AC                 LDA     byte_7DF,Y
07AF                 JSR     loc_7C8
07B2                 INC     $F5
07B4                 BNE     loc_77C
07B6 loc_7B6:
07B6                 JSR     loc_7C8
07B9                 CLC
07BA loc_7BA:
07BA                 LDA     $F4
07BC loc_7BC:
07BC                 AND     #3
07BE                 ROL     A
07BF                 ORA     $2B
07C1                 TAX
07C2                 LDA     $C080,X
07C5                 LDX     $2B
07C7 locret_7C7:
07C7                 RTS
07C8 loc_7C8:
07C8                 LDX     #$13
07CA loc_7CA:
07CA                 DEX
07CB                 BNE     loc_7CA
07CD                 SEC
07CE                 SBC     #1
07D0                 BNE     loc_7C8
07D2                 RTS
07D3 byte_7D3:       .BYTE    1, $30, $28, $24, $20, $1E, $1D, $1C, $1C, $1C, $1C, $1C
07DF byte_7DF:       .BYTE  $70, $2C, $26, $22, $1F, $1E, $1D, $1C, $1C, $1C, $1C, $1C
07EB                 .BYTE    0,   0,   0,   0,   0
07F0 loc_7F0:
07F0                 CLC
07F1                 ADC     $F4
07F3                 JMP     loc_772


The decrements at $48D change the 7 to a 4, so the jump at $498 goes to $400.

Code:

         ;checksum routine
         ;sums the entire stack
0400 loc_400:
0400
0400                 PLA
0401                 CLC
0402                 ADC     $48
0404                 STA     $48
0406                 DEX
0407                 BNE     loc_400

         ;seek track 10
0409                 LDA     #$14
040B                 JSR     loc_772

         ;read 1 sector to $500
040E                 LDX     #1
0410                 LDA     #5
0412                 JSR     loc_700

         ;seek track 11
0415                 LDA     #$16
0417                 JSR     loc_772

         ;use the checksum as the stack pointer
041A                 LDA     $48
041C                 EOR     $195
041F                 TAX
0420                 TXS
0421                 JMP     ($200)


The value at $200 (from $421) comes from $500 because it was copied by the routine at $4A3.
The read value is $6300.
So we need to patch the jump at $421 so that we can look at the routine at $6300.
We also need to patch the address at $410 so that can see what was read there. We'll use $6500 for that.
We don't need the screen redirection anymore, so we remove that.
However, are affected by the memory pattern at $4CF, so we have to start writing at $8780 to protect future code.

(continued)
Revenir en haut de page
Voir le profil de l'utilisateur Envoyer un message privé Visiter le site web de l'utilisateur
qkumba



Inscrit le: 29 Jan 2012
Messages: 165

MessagePosté le: Mer 22 Aoû 2012, 0:39    Sujet du message: boot-tracing Choplifter Répondre en citant

Code:

873D:A9 4C 8D FB 1 A9 4F 8D FC 1 A9 87 8D FD 1 4C 31 1
874F:A9 AE 8D FB 1 A9 65 8D FC 1 A9 5 8D FD 1 A9 4C 8D 21 4 A9 80 8D 22 4 A9 87 8D 23 4 A9 65 8D 11 4 4C FB 1
8780:8E 0 64 4C 80 87
8600G


Once again, we just hang the system after the read.
Insert a blank disk and hit ctrl-reset, so we can see what was loaded.
We need to know the stack pointer for later, it's stored at $6400 right now.
Here's the routine that was loaded to $6000-63FF.

Code:

         ;format is address, count, data
         ;0 terminates
6000 loc_6000:
6000                 .WORD $FA62
6002                 .BYTE $38
6003                 .BYTE  $D8, $20, $84, $FE, $20, $2F, $FB, $20, $93, $FE, $20, $89, $FE, $AD, $58, $C0
6013                 .BYTE  $AD, $5A, $C0, $AD, $5D, $C0, $AD, $5F, $C0, $AD, $FF, $CF, $2C, $10, $C0, $D8
6023                 .BYTE  $20, $3A, $FF, $AD, $F3,   3, $49, $A5, $CD, $F4,   3, $D0, $17, $AD, $F2,   3
6033                 .BYTE  $D0,  $F, $A9, $E0, $CD, $F3,   3, $D0,   8
603C                 .WORD $FAA3
603E                 .BYTE 2
603F                 .BYTE  $6C, $F2,   3
6042                 .WORD $FB2F
6044                 .BYTE $10
6045                 .BYTE  $A9,   0, $85, $48, $AD, $56, $C0, $AD, $54, $C0, $AD, $51, $C0, $A9,   0, $F0
6055                 .BYTE   $B
6056                 .WORD $FB4B
6058                 .BYTE $14
6059                 .BYTE  $85, $22, $A9,   0, $85, $20, $A9, $28, $85, $21, $A9, $18, $85, $23, $A9, $17
6069                 .BYTE  $85, $25, $4C, $22, $FC
606E                 .WORD $FBC1
6070                 .BYTE $2E
6071                 .BYTE  $48, $4A, $29,   3,   9,   4, $85, $29, $68, $29, $18, $90,   2, $69, $7F, $85
6081                 .BYTE  $28,  $A,  $A,   5, $28, $85, $28, $60, $C9, $87, $D0, $12, $A9, $40, $20, $A8
6091                 .BYTE  $FC, $A0, $C0, $A9,  $C, $20, $A8, $FC, $AD, $30, $C0, $88, $D0, $F5, $60
60A0                 .WORD $FBFD
60A2                 .BYTE $12
60A3                 .BYTE  $C9, $A0, $B0, $EF, $A8, $10, $EC, $C9, $8D, $F0, $5A, $C9, $8A, $F0, $5A, $C9
60B3                 .BYTE  $88, $D0, $C9
60B6                 .WORD $FC22
60B8                 .BYTE 9
60B9                 .BYTE  $A5, $25, $20, $C1, $FB, $65, $20, $85, $28, $60
60C3                 .WORD $FCA8
60C5                 .BYTE $B
60C6                 .BYTE  $38, $48, $E9,   1, $D0, $FC, $68, $E9,   1, $D0, $F6, $60
60D2                 .WORD $FDED
60D4                 .BYTE $B
60D5                 .BYTE  $6C, $36,   0, $C9, $A0, $90,   2, $25, $32, $84, $35, $48
60E1                 .WORD $FE84
60E3                 .BYTE $29
60E4                 .BYTE  $A0, $FF, $84, $32, $60, $A9,   0, $85, $3E, $A2, $38, $A0, $1B, $D0,   8, $A9
60F4                 .BYTE    0, $85, $3E, $A2, $36, $A0, $F0, $A5, $3E, $29,  $F, $F0,   6,   9, $C0, $A0
6104                 .BYTE    0, $F0,   2, $A9, $FD, $94,   0, $95,   1, $60
610E                 .WORD $FF3A
6110                 .BYTE 4
6111                 .BYTE  $A9, $87, $4C, $ED, $FD
6116                 .WORD $FBB4
6118                 .BYTE 0
6119                 .BYTE    8, $78, $2C, $15, $C0,   8, $8D,   7, $C0, $4C,   0, $C1
6125                 .BYTE    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0
6135                 .BYTE    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0
6145                 .BYTE    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0
6150 loc_6150:
6150                 .WORD $FB2F
6152                 .BYTE $10
6153                 .BYTE  $A9,   0, $85, $48, $AD, $56, $C0, $AD, $54, $C0, $AD, $51, $C0, $A9,   0, $F0
6163                 .BYTE   $B
6164                 .WORD $FB4B
6166                 .BYTE $14
6167                 .BYTE  $85, $22, $A9,   0, $85, $20, $A9, $28, $85, $21, $A9, $18, $85, $23, $A9, $17
6177                 .BYTE  $85, $25, $4C, $22, $FC
617C                 .WORD $FBC1
617E                 .BYTE $2E
617F                 .BYTE  $48, $4A, $29,   3,   9,   4, $85, $29, $68, $29, $18, $90,   2, $69, $7F, $85
618F                 .BYTE  $28,  $A,  $A,   5, $28, $85, $28, $60, $C9, $87, $D0, $12, $A9, $40, $20, $A8
619F                 .BYTE  $FC, $A0, $C0, $A9,  $C, $20, $A8, $FC, $AD, $30, $C0, $88, $D0, $F5, $60
61AE                 .WORD $FBFD
61B0                 .BYTE $12
61B1                 .BYTE  $C9, $A0, $B0, $EF, $A8, $10, $EC, $C9, $8D, $F0, $5A, $C9, $8A, $F0, $5A, $C9
61C1                 .BYTE  $88, $D0, $C9
61C4                 .WORD $FC22
61C6                 .BYTE 9
61C7                 .BYTE  $A5, $25, $20, $C1, $FB, $65, $20, $85, $28, $60
61D1                 .WORD $FCA8
61D3                 .BYTE $B
61D4                 .BYTE  $38, $48, $E9,   1, $D0, $FC, $68, $E9,   1, $D0, $F6, $60
61E0                 .WORD $FD0C
61E2                 .BYTE $30
61E3                 .BYTE  $A4, $24, $B1, $28, $48, $29, $3F,   9, $40, $91, $28, $68, $6C, $38,   0, $E6
61F3                 .BYTE  $4E, $D0,   2, $E6, $4F, $2C,   0, $C0, $10, $F5, $91, $28, $AD,   0, $C0, $2C
6203                 .BYTE  $10, $C0, $60, $20,  $C, $FD, $20, $2C, $FC, $20,  $C, $FD, $C9, $9B, $F0, $F3
6213                 .BYTE  $60
6214                 .WORD $FD64
6216                 .BYTE $13
6217                 .BYTE  $20, $ED, $FD, $20, $8E, $FD, $A5, $33, $20, $ED, $FD, $A2,   1, $8A, $F0, $F3
6227                 .BYTE  $CA, $20, $35, $FD
622B                 .WORD $FDED
622D                 .BYTE $12
622E                 .BYTE  $6C, $36,   0, $C9, $A0, $90,   2, $25, $32, $84, $35, $48, $20, $FD, $FB, $68
623E                 .BYTE  $A4, $35, $60
6241                 .WORD $FE84
6243                 .BYTE $29
6244                 .BYTE  $A0, $FF, $84, $32, $60, $A9,   0, $85, $3E, $A2, $38, $A0, $1B, $D0,   8, $A9
6254                 .BYTE    0, $85, $3E, $A2, $36, $A0, $F0, $A5, $3E, $29,  $F, $F0,   6,   9, $C0, $A0
6264                 .BYTE    0, $F0,   2, $A9, $FD, $94,   0, $95,   1, $60
626E                 .WORD $FF3A
6270                 .BYTE 4
6271                 .BYTE  $A9, $87, $4C, $ED, $FD
6276                 .WORD $FF59
6278                 .BYTE $16
6279                 .BYTE  $20, $84, $FE, $20, $2F, $FB, $20, $93, $FE, $20, $89, $FE, $D8, $20, $3A, $FF
6289                 .BYTE  $A9, $AA, $85, $33, $20, $67, $FD
6290                 .BYTE    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0

         ;detect ROM version and check integrity
62A0 sub_62A0:
62A0                 JSR     sub_6380

         ;select appropriate table first
         ;$6000 if $FFFC-FFFD=$FA62, $6150 if $FFFC-FFFD=$FF59, else reboot
62A3                 LDA     $FFFD
62A6                 LDX     #$60
62A8                 CPY     #$62
62AA                 BNE     loc_62B2
62AC                 EOR     #$FA
62AE                 BNE     loc_62F5
62B0                 BEQ     loc_62BD
62B2 loc_62B2:
62B2                 CPY     #$59
62B4                 BNE     loc_62F5
62B6                 CMP     #$FF
62B8                 BNE     loc_62F5
62BA                 INX
62BB                 LDA     #$50
62BD loc_62BD:
62BD                 STA     0
62BF                 STX     1

         ;perform check of ROM code
         ;Choplifter does not work on some systems because of this
         ;we'll patch it so that it works everywhere
62C1 loc_62C1:
62C1                 LDY     #2
62C3 loc_62C3:
62C3                 LDA     (0),Y
62C5                 STA     2,Y
62C8                 DEY
62C9                 BPL     loc_62C3
62CB                 LDA     #3
62CD                 CLC
62CE                 ADC     0
62D0                 STA     0
62D2                 BCC     loc_62D6
62D4                 INC     1
62D6 loc_62D6:
62D6                 LDY     4
62D8                 BEQ     locret_62F3
62DA loc_62DA:
62DA                 LDA     (0),Y
62DC                 CMP     (2),Y
62DE                 BNE     loc_62F4
62E0                 DEY
62E1                 BPL     loc_62DA
62E3                 LDY     4
62E5                 INY
62E6                 TYA
62E7                 CLC
62E8                 ADC     0
62EA                 STA     0
62EC                 BCC     loc_62F0
62EE                 INC     1
62F0 loc_62F0:
62F0                 CLC
62F1                 BCC     loc_62C1
62F3 locret_62F3:
62F3                 RTS
62F4 loc_62F4:
62F4                 NOP
62F5 loc_62F5:
62F5                 LDX     $13
62F7                 LDA     $C081,X
62FA                 JMP     $32F
62FD                 .BYTE    0,   0,   0

         ;probe slots for cards
6300 loc_6300:
6300                 JSR     sub_6366
6303                 LDY     #0
6305                 LDA     #$F8
6307                 STY     $11
6309                 STA     $12
630B loc_630B:
630B                 LDA     ($11),Y
630D                 STA     ($11),Y
630F                 INY
6310                 BNE     loc_630B
6312                 INC     $12
6314                 BNE     loc_630B
6316                 JSR     sub_6366

         ;check for known ROM
6319                 JSR     sub_62A0
631C                 LDY     #7
631E loc_631E:
631E                 STY     $10
6320                 JSR     sub_633B
6323                 BCC     loc_6332
6325                 STX     $13
6327                 LDA     $C080,X
632A                 JSR     sub_62A0
632D                 LDX     $13
632F                 LDA     $C081,X
6332 loc_6332:
6332                 LDY     $10
6334                 DEY
6335                 BPL     loc_631E
6337                 LDA     $C080
633A                 RTS
633B sub_633B:
633B                 TYA
633C                 PHA
633D                 LDX     #0
633F                 ORA     #$C0
6341                 STX     $11
6343                 STA     $12
6345                 ASL     A
6346                 ASL     A
6347                 ASL     A
6348                 ASL     A
6349                 TAX
634A                 BEQ     loc_6362
634C                 LDY     #0
634E loc_634E:
634E                 LDA     ($11),Y
6350                 STA     $B000,Y
6353                 INY
6354                 BNE     loc_634E
6356 loc_6356:
6356                 LDA     $B000,Y
6359                 CMP     ($11),Y
635B                 BNE     loc_6362
635D                 INY
635E                 BNE     loc_6356
6360                 CLC
6361                 .BYTE $24
6362 loc_6362:
6362                 SEC
6363                 PLA
6364                 TAY
6365                 RTS

         ;probe each slot looking for cards
6366 loc_6366:
6366                 LDY     #7
6368 loc_6368:
6368                 JSR     sub_633B
636B                 BCC     loc_6373
636D                 LDA     $C081,X
6370                 LDA     $C081,X
6373 loc_6373:
6373                 DEY
6374                 BPL     loc_6368
6376                 RTS
6377                 .BYTE    0,   0,   0,   0,   0,   0,   0,   0,   0

         ;apply version-specific patches
         ;select appropriate table first
         ;$63E0 if ROM "A" ($FBB5=#$78), else $63C0
6380 loc_6380:
6380                 LDX     #$C0
6382                 LDA     $FBB5
6385                 EOR     #$78
6387                 BNE     loc_638B
6389                 LDX     #$E0
638B loc_638B:
638B                 LDY     #2
638D loc_638D:
638D                 LDA     $6300,X
6390                 STA     0,Y
6393                 INX
6394                 DEY
6395                 BPL     loc_638D
6397                 LDY     #0
6399 loc_6399:
6399                 DEC     2
639B                 BMI     loc_63A6
639D                 LDA     $6300,X
63A0                 STA     (0),Y
63A2                 INX
63A3                 INY
63A4                 BNE     loc_6399
63A6 loc_63A6:
63A6                 BIT     1
63A8                 BPL     loc_638B
63AA                 LDY     $FFFC
63AD                 RTS
63AE                 .BYTE    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0
63BE                 .BYTE    0,   0

         ;format is count, big-endian address, data
         ;FF terminates the list
63C0 loc_63C0:
63C0                 .BYTE 1
63C1                 .BYTE  $61, $18
63C3                 .BYTE 0
63C4                 .BYTE 6
63C5                 .BYTE  $60, $16
63C7                 .BYTE  $AD, $5D, $C0, $AD, $5F, $C0
63CD                 .BYTE 4
63CE                 .BYTE  $60, $5F
63D0                 .BYTE  $A9, $28, $85, $21
63D4                 .BYTE $FF
63D5                 .BYTE  $FF, $FF
63D7                 .BYTE    0,   0,   0,   0,   0,   0,   0,   0,   0
63E0 loc_63E0:
63E0                 .BYTE 1
63E1                 .BYTE  $61, $18
63E3                 .BYTE $B
63E4                 .BYTE 6
63E5                 .BYTE  $60, $16
63E7                 .BYTE  $A0,   5, $20, $B4, $FB, $EA
63ED                 .BYTE 4
63EE                 .BYTE  $60, $5F
63F0                 .BYTE  $A0,   8, $D0, $5F
63F4                 .BYTE $FF
63F5                 .BYTE  $FF, $FF
63F7                 .BYTE    0,   0,   0,   0,   0,   0,   0,   0,   0


The return at $633A is using the stack pointer that comes from the checksum routine at $400.
We stored it at $6400 so that we can see it.
The value is #$FB, which is 1 less than the address that's fetched during RTS, so we read $1FC to see where to go next.

Code:

1FC                  .WORD $565


So return address is $565, which is also 1 less than the address that's used, so we continue from $566.
Here's the routine that was loaded to $500.

Code:

0500 loc_500:
0500                 LDA     #$FF
0502                 JSR     loc_537

         ;read sector (DDF5D5)
0505 loc_505:
0505                 CMP     #$DD
0507                 BNE     loc_500
0509                 JSR     loc_539
050C loc_50C:
050C                 CMP     #$F5
050E                 BNE     loc_505
0510                 JSR     loc_539
0513                 CMP     #$D5
0515                 BNE     loc_50C

         ;tricky routine here
         ;reads 4-and-4 data twice for an address and once for a value
         ;writes value to address, can be anywhere in memory
         ;one of those writes replaces the jump at $544
0517 loc_517:
0517                 JSR     loc_530
051A                 STA     loc_526+1
051D                 JSR     loc_530
0520                 STA     loc_526+2
0523                 JSR     loc_530
0526 loc_526:
0526                 STA     $FFFF
0529                 CMP     #$EA
052B                 BNE     loc_517
052D                 JMP     loc_541
0530 loc_530:
0530                 LDA     $C08C,X
0533                 BPL     loc_530
0535                 SEC
0536                 ROL     A
0537 loc_537:
0537                 STA     $FF
0539 loc_539:
0539                 LDA     $C08C,X
053C                 BPL     loc_539
053E                 AND     $FF
0540                 RTS
0541 loc_541:
0541                 LDA     $C088,X
0544                 JMP     ($3F2)
0547                 .BYTE    0,   0,   0,   0,   0,   0,   0,   0,   0

         ;point reset and break vectors to $320
0550 loc_550:
0550                 LDX     #$20
0552                 LDA     #3
0554                 JSR     $3A3
0557                 LDX     $2B
0559                 JMP     loc_500
055C                 .BYTE    0,   0,   0,   0,   0,   0,   0,   0,   0,   0

         ;clear stack
0566 loc_566:
0566                 LDX     #0
0568                 TXA
0569 loc_569:
0569                 PHA
056A                 DEX
056B                 BNE     loc_569
056D                 LDX     #$FF
056F                 TXS
0570                 JMP     loc_550
0573                 LDX     $2B
0575                 LDA     $C089,X
0578                 LDY     #$80
057A loc_57A:
057A                 DEX
057B                 BNE     loc_57A
057D                 DEY
057E                 BNE     loc_57A
0580                 LDA     #$17
0582                 JSR     $772
0585 loc_585:
0585                 LDA     #8
0587 loc_587:
0587                 PHA
0588                 CLC
0589                 LDA     $F4
058B                 ADC     #1
058D                 JSR     $772
0590                 LDX     #4
0592                 PLA
0593                 PHA
0594                 JSR     $700
0597                 PLA
0598                 CLC
0599                 ADC     #4
059B loc_59B:
059B                 CMP     #$20
059D                 BCC     loc_587
059F                 BIT     loc_59B+1
05A2                 BMI     loc_5B0
05A4                 LDA     #$40
05A6                 STA     loc_585+1
05A9                 LDA     #$C0
05AB                 STA     loc_59B+1
05AE                 BMI     loc_585
05B0 loc_5B0:
05B0                 LDA     #$40
05B2                 JSR     $772
05B5                 LDX     #1
05B7                 LDA     #6
05B9                 JSR     $700
05BC                 LDA     #5
05BE                 PHA
05BF                 LDA     #$FF
05C1                 PHA
05C2                 RTS
05C3                 .BYTE    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0
05D3                 .BYTE    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0


Now we want to know where $544 points to after the read. We also have to disable the ROM check.
We'll write the result to $6000-6001 and then hang the system.

Code:

8600<C600.C6FCM
86F8:A9 5 8D D 8 A9 87 8D E 8 4C 1 8
8705:A9 12 8D 38 2 A9 87 8D 39 2 4C F 2
8712:A2 0 BD 0 3 9D 0 63 E8 D0 F7 A9 63 8D A 3 A9 4C 8D 1F 3 A9 34 8D 20 3 A9 87 8D 21 3 4C 1 3
8734:9D 0 1 E8 F0 3 4C 8 3
873D:A9 4C 8D FB 1 A9 4F 8D FC 1 A9 87 8D FD 1 4C 31 1
874F:A9 AE 8D FB 1 A9 65 8D FC 1 A9 5 8D FD 1 A9 4C 8D 21 4 A9 80 8D 22 4 A9 87 8D 23 4 4C FB 1
8780:A9 0 8D DF 62 A9 92 8D 2E 5 A9 87 8D 2F 5 4C 0 63
8792:AD 45 5 8D 0 60 AD 46 5 8D 1 60 4C 9E 87
8600G


And here's our answer:

Code:

6000                 .WORD $4000


When did $4000 get loaded? At the same time as the title screen ($469). What's there?

Code:

4000                 LDX     #$40
4002                 TXS
4003                 RTS


Ha! Oh, and some text, perhaps a bit of source code from memory.

Code:

4004                 .BYTE ':',$D
4006                 .BYTE 2
4007                 .BYTE ';',$D
4009                 .BYTE $1E
400A                 .BYTE '; START LIKE NEW GAME, BUT NO',$D
4028                 .BYTE $19
4029                 .BYTE '; CONTR',0


Okay, back to our stack.
#$40 is 1 less than the address that's fetched during RTS, so we read $141 to see where to go next...
but wait, isn't the stack is empty from $566? No, it was written by $517. Here are all of the values:

Code:

;address marker and tail comparison bytes for the first sector to read
0020:D5
0021:AA
0022:D4
0023:B5
;update addresses to use $20-23 instead of $F0-F3
0716:20
075B:20
0765:20
071D:21
0756:21
0724:22
0751:22
0744:23
0760:23
;change jump
0544:4C
0545:00
0546:40
;disable read for second round
0570:E8
0571:E8
0572:E8
;set new return address
0141:65
0142:05
;end
0000:EA


So...

Code:

141                  .WORD $565


So return address is $565, which is also 1 less than the address that's used, so we continue from $566.
Since $544-546 were altered, we reach $573 this time.

Code:

         ;turn on the drive and wait
0573                 LDX     $2B
0575                 LDA     $C089,X
0578                 LDY     #$80
057A loc_57A:
057A                 DEX
057B                 BNE     loc_57A
057D                 DEY
057E                 BNE     loc_57A

         ;seek track 11.5
0580                 LDA     #$17
0582                 JSR     $772

         ;prepare to read to $800-1FFF
0585 loc_585:
0585                 LDA     #8
0587 loc_587:
0587                 PHA
0588                 CLC

         ;seek to next half track
0589                 LDA     $F4
058B                 ADC     #1
058D                 JSR     $772

         ;read 4 sectors
0590                 LDX     #4
0592                 PLA
0593                 PHA
0594                 JSR     $700
0597                 PLA
0598                 CLC
0599                 ADC     #4
059B loc_59B:
059B                 CMP     #$20
059D                 BCC     loc_587
059F                 BIT     loc_59B+1
05A2                 BMI     loc_5B0

         ;then $4000-BFFF
05A4                 LDA     #$40
05A6                 STA     loc_585+1
05A9                 LDA     #$C0
05AB                 STA     loc_59B+1
05AE                 BMI     loc_585

         ;seek to track 32
05B0 loc_5B0:
05B0                 LDA     #$40
05B2                 JSR     $772

         ;read 1 sector to $600-6FF
05B5                 LDX     #1
05B7                 LDA     #6
05B9                 JSR     $700

         ;jmp to $600
05BC                 LDA     #5
05BE                 PHA
05BF                 LDA     #$FF
05C1                 PHA
05C2                 RTS


Almost done! We want to know what was read to $600 by $5B5, so we will redirect $5B7 to $6600 and then hang the system again.

Code:

8600<C600.C6FCM
86F8:A9 5 8D D 8 A9 87 8D E 8 4C 1 8
8705:A9 12 8D 38 2 A9 87 8D 39 2 4C F 2
8712:A2 0 BD 0 3 9D 0 63 E8 D0 F7 A9 63 8D A 3 A9 4C 8D 1F 3 A9 34 8D 20 3 A9 87 8D 21 3 4C 1 3
8734:9D 0 1 E8 F0 3 4C 8 3
873D:A9 4C 8D FB 1 A9 4F 8D FC 1 A9 87 8D FD 1 4C 31 1
874F:A9 AE 8D FB 1 A9 65 8D FC 1 A9 5 8D FD 1 A9 4C 8D 21 4 A9 80 8D 22 4 A9 87 8D 23 4 4C FB 1
8780:A9 0 8D DF 62 A9 92 8D 2E 5 A9 87 8D 2F 5 4C 0 63
8792:A9 66 8D B8 5 A9 BB 8D C0 5 4C 41 5
8600G


Unfortunately, at this point, my disk does not read properly, and I was unable to find a working .nib image.
If someone has a working .nib image to share, I would be happy to finish this work.
However, at this point, we have the entire game in memory.
The code at $600 sets some zero-page entries and then jumps to $800, which is the main game code.
Revenir en haut de page
Voir le profil de l'utilisateur Envoyer un message privé Visiter le site web de l'utilisateur
qkumba



Inscrit le: 29 Jan 2012
Messages: 165

MessagePosté le: Mer 22 Aoû 2012, 0:40    Sujet du message: boot-tracing Choplifter Répondre en citant

So that's it for the boot-trace. In the 80s, such a thing would have taken me several days. Now I can do it in several hours. ;-)
Next time: cracking the protection using a minimal number of changes.
Revenir en haut de page
Voir le profil de l'utilisateur Envoyer un message privé Visiter le site web de l'utilisateur
toinet
Site Admin


Inscrit le: 15 Juin 2007
Messages: 2789
Localisation: Le Chesnay, France

MessagePosté le: Lun 27 Aoû 2012, 21:59    Sujet du message: Répondre en citant

Wouah! Congratulations, Sir! Your explanations rock, I am flabbergasted Smile

If only I had a NIB generator...
antoine
Revenir en haut de page
Voir le profil de l'utilisateur Envoyer un message privé Visiter le site web de l'utilisateur
qkumba



Inscrit le: 29 Jan 2012
Messages: 165

MessagePosté le: Lun 22 Oct 2012, 21:58    Sujet du message: Répondre en citant

So, now we know how to capture the image in memory. We have two options.
One is to modify the disk to make it workable. The other is to save it to a file.
Let's look at the disk modification version first.
The first change that we make is to copy ourselves to $BC00 as well as $200.
The reason will be clear later.

We go from this:

Code:
0800    .BYTE    1
0801       LDX    #0
0803 loc_803:
0803       LDA    $800,X
0806       STA    $200,X
0809       INX
080A       BNE    loc_803
080C       JMP    $20F


to this:

Code:
0800 byte_800:    .BYTE 1
0801       LDX    #0
0803 loc_803:
0803       LDA    byte_800,X
0806       STA    $200,X
0809       STA    $BC00,X
080C       INX
080D       BNE    loc_803
080F       JMP    $212


Now we want to copy the 6-and-2 nibblisation table that the boot PROM created, so that we don't have to do it ourselves.
We go from this:

Code:
080F       LDY    #$AB
...
081D       BEQ    loc_824
081F       TXA
0820       STA    $800,Y
...
0825       BNE    loc_811
0827       STY    $3D
0829       STY    $26
...
0834       JSR    $2D1


to this:

Code:
0212       LDY    #$95
...
0220       LDA    byte_2D6,Y
0223       STA    $BAD6,Y
...
0228       BNE    loc_220
022A       NOP
0234       LDA    byte_2D1


Just a few bytes, no additional space needed.
We don't have any post-nibble routine at $2D1 anymore, so the JSR was changed to a LDA.
All we needed was to replace the read routine at $25D. There are some spare bytes at $240-25C which we use, too.
The code is the regular boot PROM code, restructured so that the addresses match, and to take care of some special cases.
Of particular interest is that when the previous read was #$BA, the next reads will overwrite our critical data (nibblisation table and read routine), so we have to relocate them first, and redirect the calls to the new location.
That's the check at $25D.

Code:
0240 loc_240:
0240       LDY    #3
0242       STY    $2A
0244 loc_244:
0244       LDA    $C08C,X
0247       BPL    loc_244
0249       ROL    A
024A       STA    $3C
024C loc_24C:
024C       LDA    $C08C,X
024F       BPL    loc_24C
0251       AND    $3C
0253       DEY
0254       BNE    loc_244
0256       PLP
0257       CMP    $3D
0259       BNE    loc_289
025B       BCS    loc_28A
025D loc_25D:
025D       CMP    #$BA
025F       BNE    loc_289
0261 loc_261:
0261       LDA    $BB00,Y
0264       STA    $200,Y
0267       LDA    $BC00,Y
026A       STA    $400,Y
026D       INY
026E       BNE    loc_261
0270       INY
0271       STY    byte_4BB
0274       STY    byte_4CD
0277       STY    byte_4DC
027A       INY
027B       STY    byte_4C1
027E       STY    byte_4E9
0281       STY    byte_4ED
0284       LDY    #4
0286       STY    byte_73D
0289 loc_289:
0289       CLC
028A loc_28A:
028A       PHP
028B loc_28B:
028B       LDA    $C08C,X
028E       BPL    loc_28B
0290 loc_290:
0290       EOR    #$D5
0292       BNE    loc_28B
0294 loc_294:
0294       LDA    $C08C,X
0297       BPL    loc_294
0299       CMP    #$AA
029B       BNE    loc_290
029D       NOP
029E loc_29E:
029E       LDA    $C08C,X
02A1       BPL    loc_29E
02A3       CMP    #$96
02A5       BEQ    loc_240
02A7       PLP
02A8       BCC    loc_289
02AA       EOR    #$AD
02AC       BNE    loc_289
02AE       LDA    #0
02B0       LDY    #$56
02B2 loc_2B2:
02B2       STY    $3C
02B4 loc_2B4:
02B4       LDY    $C08C,X
02B7       BPL    loc_2B4
02B9       EOR    $BAD6,Y
02BC       LDY    $3C
02BE       DEY
02BF       STA    $BB00,Y
02C2       BNE    loc_2B2
02C4 loc_2C4:
02C4       STY    $3C
02C6 loc_2C6:
02C6       LDY    $C08C,X
02C9       BPL    loc_2C6
02CB       EOR    $BAD6,Y
02CE       LDY    $3C
02D0 loc_2D0:
02D0       STA    ($26),Y
02D2       INY
02D3       BNE    loc_2C4
02D5 loc_2D5:
02D5       LDY    $C08C,X
02D8       BPL    loc_2D5
02DA       EOR    $BAD6,Y
02DD       BNE    loc_28B
02DF       TAY
02E0 loc_2E0:
02E0       LDX    #$56
02E2 loc_2E2:
02E2       DEX
02E3       BMI    loc_2E0
02E5       LDA    ($26),Y
02E7       LSR    $BB00,X
02EA       ROL    A
02EB       LSR    $BB00,X
02EE       ROL    A
02EF       STA    ($26),Y
02F1       INY
02F2       BNE    loc_2E2
02F4       LDY    #$99
02F6       LDX    $2B
02F8       RTS
Revenir en haut de page
Voir le profil de l'utilisateur Envoyer un message privé Visiter le site web de l'utilisateur
qkumba



Inscrit le: 29 Jan 2012
Messages: 165

MessagePosté le: Lun 22 Oct 2012, 22:00    Sujet du message: Répondre en citant

Now we move to the stack code.
We make a minor change for compatibility with our read routine, and disable the header checks because we will read the whole sector ourselves, from this:

Code:
0194       STY    $F7
0196       STX    $F8
...
01A1       BNE    loc_19C
...
01A8       BNE    loc_19F
...
01AF       BNE    loc_1A6
...
01C3       BNE    loc_1B1
01C5       ASL    $C000
...
01CF       BNE    loc_190
01D1       INC    $F8
...
01EE       CMP    $F0
01F0       BEQ    loc_1FB


to this:

Code:
0194       STY    $27
0196       STX    $3D
...
01A1       BNE    loc_1A3
...
01A8       BNE    loc_1AA
...
01AF       BNE    loc_1B1
...
01C3       BNE    loc_1C5
01C5       JSR    $025D      ;read whole sector
...
01CF       INC    $27
01D1       INC    $3D
...
01EE       CMP    $F0
01F0       BVC    loc_1FB   ;always taken


We are lucky with the code at $400, because we're aligned to a whole track, so the seeks and reads didn't need to change.
All we needed is to fix the stack checksum, from this:

Code:
041A       LDA    $48
041C       EOR    $195


to this:

Code:
041A       LDA    #$DC
041C       EOR    $195


The current value at $48 can't be used with the value at $195, because neither of them can produce the required value.
There also isn't any value in the $1xx range that can be used instead, so we hardcode the required value (#$DC).
This bring us to the code at $6000, which we patch to allow all ROMs. This was described already.
Then we jump back to the code at $573, which needs a few changes.
Here's the routine for reading the game code.

Code:
      ;seek track 11.5
0580       LDA    #$17
...
058B       ADC    #1 ;the comment should have been "seek by half track"
...
      ;read 4 sectors
0590       LDX    #4
...
0599       ADC    #4
...
059F       BIT    loc_59B+1
05A2       BMI    loc_5B0

      ;then $4000-BFFF
05A4       LDA    #$40
05A6       STA    loc_585+1
05A9       LDA    #$C0
05AB       STA    loc_59B+1
05AE       BMI    loc_585


which we change like this:

Code:
      ;seek track 11
0580       LDA    #$16
...
058B       ADC    #2 ;seek by whole track
...
      ;read 8 sectors at a time, otherwise we run out of disk
0590       LDX    #8
...
0599       ADC    #8
...

      ;double next read address and size
      ;very conveniently same size code
059F       PHA
05A0       ASL    $0591
05A3       ASL    $059A
05A6       LDA    #$C0
05A8       STA    loc_59B+1
05AB       PLA
05AC       ASL
05AD       BPL    loc_587


And here's the new code at $600. I never did find a working .nib.

Code:
0600       LDA    #$9B
0602       STA    $4E
0604       LDA    #$30
0606       STA    $FC
0608       LDA    #6
060A       STA    $FD
060C       LDY    #0
060E       STY    $FF
0610       LDX    #$B
0612       STX    $4F
0614       LDA    #$20
0616       JSR    sub_625
0619       LDX    #3
061B       LDA    #$2E
061D       JSR    sub_625
0620       LDA    #$31
0622       JMP    ($20)
0625 sub_625:
0625       STA    $FE
0627 loc_627:
0627       LDA    ($FC),Y
0629       STA    ($FE),Y
062B       INY
062C       DEX
062D       BPL    loc_627
062F       RTS
0630       .BYTE    0,   8,   0,   0, $92,  $C,   0,   0, $1F,   8, $C7,   9
063C       .BYTE  $5F,  $B, $13,  $C


All done. We have a working disk.
Next time, we'll look at converting to a file.
Revenir en haut de page
Voir le profil de l'utilisateur Envoyer un message privé Visiter le site web de l'utilisateur
toinet
Site Admin


Inscrit le: 15 Juin 2007
Messages: 2789
Localisation: Le Chesnay, France

MessagePosté le: Mar 23 Oct 2012, 3:07    Sujet du message: Répondre en citant

Very good.

Now that "i'm fEDD up" is available and as I own the original disk of Choplifter, I can try to generate to NIB of it.

Which parameters do you want me to set to make a NIB image: number of tracks, step?

Antoine
Revenir en haut de page
Voir le profil de l'utilisateur Envoyer un message privé Visiter le site web de l'utilisateur
qkumba



Inscrit le: 29 Jan 2012
Messages: 165

MessagePosté le: Mer 24 Oct 2012, 20:47    Sujet du message: Répondre en citant

First thing is for you to test if your disk actually works. :-)
This tutorial was created using the .nib that you sent to me at the start of the year.
Revenir en haut de page
Voir le profil de l'utilisateur Envoyer un message privé Visiter le site web de l'utilisateur
toinet
Site Admin


Inscrit le: 15 Juin 2007
Messages: 2789
Localisation: Le Chesnay, France

MessagePosté le: Jeu 25 Oct 2012, 6:30    Sujet du message: Répondre en citant

qkumba a écrit:
First thing is for you to test if your disk actually works. Smile
This tutorial was created using the .nib that you sent to me at the start of the year.


oops, bad memory. sorry.
I'll have to test on a 8-bit machine. the program does not load on my IIgs
av
Revenir en haut de page
Voir le profil de l'utilisateur Envoyer un message privé Visiter le site web de l'utilisateur
qkumba



Inscrit le: 29 Jan 2012
Messages: 165

MessagePosté le: Jeu 25 Oct 2012, 7:55    Sujet du message: Répondre en citant

toinet a écrit:
the program does not load on my IIgs


right, it's the ROM check that's failing.
you could try using the tutorial to boot-trace the code and disable the ROM check, then you can let it run and see what happens.
Revenir en haut de page
Voir le profil de l'utilisateur Envoyer un message privé Visiter le site web de l'utilisateur
qkumba



Inscrit le: 29 Jan 2012
Messages: 165

MessagePosté le: Mer 07 Nov 2012, 4:19    Sujet du message: Répondre en citant

so we know how to create a working disk, but how about a file?
Choplifter is quite a big game ($800-$bfff), which leaves no room for DOS.
Even if we could save such a large file, we could not load it back into memory.
So we need to compress it, but first, we should look a bit closer at the memory map...
Yes, $4000-$5fff is identical to $2000-$3fff. We just saved ourselves 8kb instantly.
This is great, because we can compress in two stages and we don't need to use special memory regions like the stack page or high memory (particularly, the crack should not require more memory than the original).
We can actually compress in one part, but the experience is not good in that case - the title screen would take a long time until it showed, and that's not how the original version behaved.
If we compress in two parts and decompress the low memory part first (and backwards) then the title screen is the first thing to appear, and the user won't mind waiting quite as much. :-)
So, we compress $6000-$bfff first, and then $800-$3fff, and place all that data starting at $4000. The compressed low memory is unpacked first, and that leaves plenty of room for the other region to unpack.
Finally, we jump to $fe2c to copy $2000-$3fff to $4000-$5fff and everything works.
I used aPLib for the purpose, the result is an 18kb file, about half the size of every other version that I have seen (the others use RLE compression).
Revenir en haut de page
Voir le profil de l'utilisateur Envoyer un message privé Visiter le site web de l'utilisateur
Montrer les messages depuis:   
Poster un nouveau sujet   Répondre au sujet     Index du Forum -> PROTECTION MALEFIQUE Toutes les heures sont au format GMT + 1 Heure
Page 1 sur 1

 
Sauter vers:  
Vous ne pouvez pas poster de nouveaux sujets dans ce forum
Vous ne pouvez pas répondre aux sujets dans ce forum
Vous ne pouvez pas éditer vos messages dans ce forum
Vous ne pouvez pas supprimer vos messages dans ce forum
Vous ne pouvez pas voter dans les sondages de ce forum


Powered by phpBB © 2001, 2005 phpBB Group
Traduction par : phpBB-fr.com