ARTICLES
6 / 31 |
The Hexagon Protection
Cette protection est une évolution de la protection Alkatraz.
SPECIFICITES :
La protection HEXAGON créé en 1989 est basée sur des secteurs de taille 6 (pouvant contenir théoriquement 8 Ko de données, mais sur Amstrad CPC une piste ne peux pas dépasser les 6 Ko de données, nous ne chipoterons pas pour quelques octets, mais la limite pratique est située entre 6144 octets et 6300 octets environ, au delà, c'est impossible a lire) sur toutes les pistes sauf bien entendu en piste 0 (Pour le Catalogue et le chargeur). La protection a été créé sur un ordinateur PCW avec un lecteur 3 pouces spécial.
Un seul fichier est présent sur la disquette (le loader), le reste des données est accessible en sectoriel.
La table de correspondance des fichiers est caché dans les secteurs de taille 6.
Le gros avantage de ce type de protection, c'est la quantité de données pouvant être inscrite sur une seule face de disquette.
En temps normal, un formattage classique permet d'avoir 178 Ko par face. Ici, si les pistes 1 a 41 sont en taille 6, ça nous donne 6 ko max * 41 pistes = 246 Ko, sans oublier notre piste 0 qui contient 10 secteurs de taille 2 (512 octets * 10 secteurs = 5 Ko), ce qui nous donne au final un total de 251 Ko sur une seule face. Le gain par rapport a nos 178 Ko de base est de +73 Ko.
Un détournement du catalogue est présent sur la disquette :
- Soit avec le message contenant le nom de la protection de caché, visible uniquement si on change l'encre 3
- Soit visible directement (HEXAGON DISK PROTECTION (c) 1989 A.R.P)
EDITEURS L'AYANT UTILISES SUR CPC :
Activision / Codemasters / U.S.GOLD
Listing des programmes utilisant cette protection
NIVEAU DE PROTECTION :
Copiable difficilement a cause des secteurs de taille 6.
Si votre copieur réécrit intégralement le secteur de taille 6 (8 Ko), il reviendra au début de votre piste pour écrire les 2Ko restant et écrasera par la même occasion les premières informations. La seule solution est d'avoir une routine qui est capable d'écrire les 6ko et d'arrêter le moteur pour ne pas écrire les 2 Ko restants.
Commentaire de Dlfrsilver :
On voit clairement que ce système est tiré du fonctionnement d'une disquette plombé de type amiga.
Ici le loader "DISK.BIN" est comme le bootblock sur une disquette amiga, ensuite la table de correspondance des fichiers s'ensuit une fois les premières boucles de décodage passées, puis les données sont chargées par du readtrack (lecture de piste) puisque un fichier peut commencer au milieu d'un secteur et finir 3 pistes plus loin.
Exemple de protection HEXAGON désassemblé et commenté ; il s'agit du loader du jeu Ghostbuster II
;; HEXAGON disc protection
;;
;; this example comes from "Ghost Busters 2"
;;
;; details:
;;
;; - when disc is catalogued, a hexagon of "*" characters is shown
;; with "HEXAGON. Protection c 1989 A.R.P" inside, with
;; "To play this game type : RUN "disc" and
;; "Then Press RETURN" displayed underneath.
;;
;; - the first track is formatted using standard "DATA" format.
;;
;; - there is a single binary file called "DISC.BIN":
;; a) loads to &170 in RAM,
;; b) length of &3F1 bytes
;; c) it is encrypted
;;
;; - the remaining tracks are formatted using 6k/8k sectors
;; a) 1 sector per track with N of 6
;; b) &1800 bytes maximum actually used
;; c) sector has data error when reading
;; (these tracks are almost impossible to copy on a CPC)
;; - files are stored in a single continuous block
;; often spanning multiple tracks and sectors
;;
;; - files can start and end within a sector; therefore
;; files are not defined in sector sizes. The sizes
;; are defined in bytes.
;;
;; - a "directory" is loaded from the disc, this describes
;; the starting track, offset of data in sector, length in bytes,
;; decryption information for every file
;;
;; - directory is stored at offset 0 on first track with 6k/8k sector
;; (track 1 in this case)
;; - directory and data is encrypted
;;
;; - data may be compressed using "run-length encoding" compression scheme
;;
;; - data has a one byte XOR checksum
;;===============================================================
;; deprotection routines
0170 f3 di
0171 218401 ld hl,$0184
0174 01dd03 ld bc,$03dd
0177 3e25 ld a,$25
0179 7e ld a,(hl)
017a a8 xor b
017b a9 xor c
017c ad xor l
017d ac xor h
017e 77 ld (hl),a
017f 23 inc hl
0180 0b dec bc
0181 78 ld a,b
0182 b1 or c
0183 20f4 jr nz,$0179
0185 216005 ld hl,$0560
0188 01c803 ld bc,$03c8
018b 1eb4 ld e,$b4
018d cb1b rr e
018f cb16 rl (hl)
0191 cb13 rl e
0193 2b dec hl
0194 0b dec bc
0195 78 ld a,b
0196 b1 or c
0197 20f4 jr nz,$018d
0199 21aa01 ld hl,$01aa
019c 01b703 ld bc,$03b7
019f 3e45 ld a,$45
01a1 7e ld a,(hl)
01a2 ed44 neg
01a4 77 ld (hl),a
01a5 23 inc hl
01a6 0b dec bc
01a7 78 ld a,b
01a8 b1 or c
01a9 20f6 jr nz,$01a1
01ab 216005 ld hl,$0560
01ae 01a403 ld bc,$03a4
01b1 1ea3 ld e,$a3
01b3 7e ld a,(hl)
01b4 ab xor e
01b5 77 ld (hl),a
01b6 5f ld e,a
01b7 2b dec hl
01b8 0b dec bc
01b9 78 ld a,b
01ba b1 or c
01bb 20f6 jr nz,$01b3
01bd 216005 ld hl,$0560
01c0 019003 ld bc,$0390
01c3 1e35 ld e,$35
01c5 cb1b rr e
01c7 cb16 rl (hl)
01c9 cb13 rl e
01cb 2b dec hl
01cc 0b dec bc
01cd 78 ld a,b
01ce b1 or c
01cf 20f4 jr nz,$01c5
01d1 21e101 ld hl,$01e1
01d4 018003 ld bc,$0380
01d7 3e2f ld a,$2f
01d9 7e ld a,(hl)
01da ad xor l
01db 77 ld (hl),a
01dc 23 inc hl
01dd 0b dec bc
01de 78 ld a,b
01df b1 or c
01e0 20f7 jr nz,$01d9
01e2 21f401 ld hl,$01f4
01e5 016d03 ld bc,$036d
01e8 1ea1 ld e,$a1
01ea 7e ld a,(hl)
01eb ad xor l
01ec ac xor h
01ed ab xor e
01ee 77 ld (hl),a
01ef 23 inc hl
01f0 0b dec bc
01f1 78 ld a,b
01f2 b1 or c
01f3 20f5 jr nz,$01ea
01f5 210802 ld hl,$0208
01f8 015903 ld bc,$0359
01fb 3e6f ld a,$6f
01fd 7e ld a,(hl)
01fe 0f rrca
01ff 0f rrca
0200 0f rrca
0201 0f rrca
0202 77 ld (hl),a
0203 23 inc hl
0204 0b dec bc
0205 78 ld a,b
0206 b1 or c
0207 20f4 jr nz,$01fd
0209 211a02 ld hl,$021a
020c 014703 ld bc,$0347
020f 3e80 ld a,$80
0211 7e ld a,(hl)
0212 ad xor l
0213 ac xor h
0214 77 ld (hl),a
0215 23 inc hl
0216 0b dec bc
0217 78 ld a,b
0218 b1 or c
0219 20f6 jr nz,$0211
021b 216005 ld hl,$0560
021e 013303 ld bc,$0333
0221 1ee6 ld e,$e6
0223 7e ld a,(hl)
0224 57 ld d,a
0225 ab xor e
0226 77 ld (hl),a
0227 5a ld e,d
0228 2b dec hl
0229 0b dec bc
022a 78 ld a,b
022b b1 or c
022c 20f5 jr nz,$0223
022e 214102 ld hl,$0241
0231 012003 ld bc,$0320
0234 3eee ld a,$ee
0236 7e ld a,(hl)
0237 0f rrca
0238 0f rrca
0239 0f rrca
023a 0f rrca
023b 77 ld (hl),a
023c 23 inc hl
023d 0b dec bc
023e 78 ld a,b
023f b1 or c
0240 20f4 jr nz,$0236
0242 215602 ld hl,$0256
0245 010b03 ld bc,$030b
0248 1ea4 ld e,$a4
024a 0b dec bc
024b 7e ld a,(hl)
024c 23 inc hl
024d ae xor (hl)
024e 2b dec hl
024f ab xor e
0250 77 ld (hl),a
0251 23 inc hl
0252 0b dec bc
0253 78 ld a,b
0254 b1 or c
0255 20f4 jr nz,$024b
0257 216005 ld hl,$0560
025a 01f602 ld bc,$02f6
025d 1e24 ld e,$24
025f cb1b rr e
0261 cb16 rl (hl)
0263 cb13 rl e
0265 2b dec hl
0266 0b dec bc
0267 78 ld a,b
0268 b1 or c
0269 20f4 jr nz,$025f
026b 217c02 ld hl,$027c
026e 01e502 ld bc,$02e5
0271 3eca ld a,$ca
0273 7e ld a,(hl)
0274 ed44 neg
0276 77 ld (hl),a
0277 23 inc hl
0278 0b dec bc
0279 78 ld a,b
027a b1 or c
027b 20f6 jr nz,$0273
027d 216005 ld hl,$0560
0280 01d102 ld bc,$02d1
0283 1eb9 ld e,$b9
0285 0b dec bc
0286 7e ld a,(hl)
0287 2b dec hl
0288 ae xor (hl)
0289 ab xor e
028a 77 ld (hl),a
028b 0b dec bc
028c 78 ld a,b
028d b1 or c
028e 20f6 jr nz,$0286
0290 21a202 ld hl,$02a2
0293 01bf02 ld bc,$02bf
0296 1e83 ld e,$83
0298 7e ld a,(hl)
0299 57 ld d,a
029a ab xor e
029b 77 ld (hl),a
029c 5a ld e,d
029d 23 inc hl
029e 0b dec bc
029f 78 ld a,b
02a0 b1 or c
02a1 20f5 jr nz,$0298
02a3 21b402 ld hl,$02b4
02a6 01ad02 ld bc,$02ad
02a9 1e3f ld e,$3f
02ab 7e ld a,(hl)
02ac ab xor e
02ad 77 ld (hl),a
02ae 5f ld e,a
02af 23 inc hl
02b0 0b dec bc
02b1 78 ld a,b
02b2 b1 or c
02b3 20f6 jr nz,$02ab
02b5 216005 ld hl,$0560
02b8 019802 ld bc,$0298
02bb 1efd ld e,$fd
02bd cb1b rr e
02bf cb16 rl (hl)
02c1 cb13 rl e
02c3 2b dec hl
02c4 0b dec bc
02c5 78 ld a,b
02c6 b1 or c
02c7 20f4 jr nz,$02bd
02c9 21d902 ld hl,$02d9
02cc 018802 ld bc,$0288
02cf 3ea1 ld a,$a1
02d1 7e ld a,(hl)
02d2 2f cpl
02d3 77 ld (hl),a
02d4 23 inc hl
02d5 0b dec bc
02d6 78 ld a,b
02d7 b1 or c
02d8 20f7 jr nz,$02d1
02da 21eb02 ld hl,$02eb
02dd 017602 ld bc,$0276
02e0 3e8d ld a,$8d
02e2 7e ld a,(hl)
02e3 ed44 neg
02e5 77 ld (hl),a
02e6 23 inc hl
02e7 0b dec bc
02e8 78 ld a,b
02e9 b1 or c
02ea 20f6 jr nz,$02e2
;;.
;;.
;;.
;; this is the remainder of the loader after it has been moved to it's destination location
;; copys loader from &2ec to &8000
8000 3e00 ld a,$00
8002 21e1e9 ld hl,$e9e1 ;; POP HL: JP (HL)
8005 220080 ld ($8000),hl
8008 cd0080 call $8000 ;; pulls &800B from the stack and jumps to it
;; HL = &800B
800b 116902 ld de,$0269 ;; length of data following jp &801a
800e 19 add hl,de
800f 117482 ld de,$8274 ;; destination + length
8012 017502 ld bc,$0275 ;; length
8015 edb8 lddr ;; copy backwards
8017 c31a80 jp $801a ;; execute
;;============================================================
801a 3100c0 ld sp,$c000
801d f5 push af
;; set mode 0
801e 3e00 ld a,$00
8020 cd0ebc call $bc0e ;; firmware function: scr set mode
;; set border colour to black
8023 010000 ld bc,$0000
8026 cd38bc call $bc38 ;; firmware function: scr set border
;; setup colours
8029 cd5180 call $8051
802c f1 pop af
802d 4f ld c,a
802e e60f and $0f
8030 32cd80 ld ($80cd),a
;; load file 1
8033 3e01 ld a,$01
8035 dd2100b0 ld ix,$b000
8039 cd6980 call $8069
;; load file 2
803c 3e02 ld a,$02
803e dd2100b2 ld ix,$b200
8042 cd6980 call $8069
8045 3acd80 ld a,($80cd)
8048 3202b2 ld ($b202),a
804b 3100c0 ld sp,$c000
804e c300b0 jp $b000
;;========================================================
;; initialise colours
;; set all colours to black
8051 3e10 ld a,$10
8053 010000 ld bc,$0000
8056 3d dec a
8057 f5 push af
8058 cd32bc call $bc32 ;; firmware function: scr set ink
805b f1 pop af
805c 20f5 jr nz,$8053
;; wait for firmware to set the colours
805e cd41bc call $bc41 ;; firmware function: scr get flashing
8061 2c inc l
8062 45 ld b,l
;; wait for B frames
8063 cd19bd call $bd19 ;; firmware function: mc wait flyback
8066 10fb djnz $8063
8068 c9 ret
;;===============================================================
;; A = file identification id
;; IX = load address
8069 f3 di
806a 32cc80 ld ($80cc),a
806d 3e05 ld a,$05
806f 327382 ld ($8273),a ;; set retry count
8072 cd5981 call $8159 ;; motor on
8075 dde5 push ix
8077 dde5 push ix
8079 017efb ld bc,$fb7e
;; wait for disc drive to become ready
807c cdf681 call $81f6 ;; read id
807f 7e ld a,(hl) ;; check fdc status register 0 from result phase
;; if 0, then read id completed successfully
;; (implies drive was ready)
;; otherwise it is assumed drive is not ready
8080 b7 or a
8081 20f9 jr nz,$807c
;; is directory loaded?
8083 3a7482 ld a,($8274)
8086 b7 or a
8087 2039 jr nz,$80c2
;; no
8089 3d dec a
;;------------------------------------------------------------------
;; find first track with 6k/8k protection
;; this track will hold the directory
808a 3c inc a
808b cddb81 call $81db ;; move to track
808e cdf681 call $81f6 ;; read id
8091 3a7282 ld a,($8272) ;; N from result phase
8094 fe06 cp $06
8096 3a6b82 ld a,($826b) ;; track number
8099 20ef jr nz,$808a
;; found track...
;; load directory
;; A = track
809b 2100a0 ld hl,$a000 ;; load directory to this address
809e e5 push hl
809f e5 push hl
80a0 010000 ld bc,$0000 ;; skip
80a3 11f801 ld de,$01f8 ;; length of directory
80a6 cd9781 call $8197 ;; read data
80a9 fde1 pop iy
80ab e1 pop hl
;; deprotect directory
80ac 1e24 ld e,$24
80ae 0e0e ld c,$0e
80b0 fd5605 ld d,(iy+$05)
80b3 41 ld b,c
80b4 7e ld a,(hl)
80b5 aa xor d
80b6 77 ld (hl),a
80b7 23 inc hl
80b8 10fa djnz $80b4
80ba fd7205 ld (iy+$05),d
80bd fd09 add iy,bc
80bf 1d dec e
80c0 20ee jr nz,$80b0
;; set flag to indicate directory has been loaded
80c2 3e01 ld a,$01
80c4 327482 ld ($8274),a
;;------------------------------------------------
;; find file in directory
80c7 dd2100a0 ld ix,$a000 ;; the directory
80cb 110100 ld de,$0001
80ce 010000 ld bc,$0000
;;---------------------------------------
;; find entry
80d1 dd09 add ix,bc ;; go to next file description
80d3 0e0e ld c,$0e ;; size of file description
80d5 dd7e00 ld a,(ix+$00)
80d8 e60f and $0f
80da ba cp d ;; file id code
80db 20f4 jr nz,$80d1
80dd dd7e01 ld a,(ix+$01)
80e0 bb cp e
80e1 20ee jr nz,$80d1
;;----------------------------------------
;; found entry
80e3 dd7e0b ld a,(ix+$0b) ; decryption initial code
80e6 326581 ld ($8165),a
80e9 dd6e0c ld l,(ix+$0c) ; instructions for decryption
80ec dd660d ld h,(ix+$0d)
80ef 226781 ld ($8167),hl
80f2 e1 pop hl
80f3 dd7e06 ld a,(ix+$06) ; run-length encoding marker
80f6 327381 ld ($8173),a
80f9 dd7e05 ld a,(ix+$05) ; checksum
80fc f5 push af
80fd dd7e00 ld a,(ix+$00) ; file code+flags
8100 327581 ld ($8175),a
8103 dd5e07 ld e,(ix+$07) ; uncompressed size
8106 dd5608 ld d,(ix+$08)
; x2
8109 17 rla ; compressed?
810a 300a jr nc,$8116
;; compressed
810c a7 and a
810d ed52 sbc hl,de
810f dd4e09 ld c,(ix+$09)
8112 dd460a ld b,(ix+$0a)
8115 09 add hl,bc
;; each entry is 14 bytes
;; offset length function
;; 0 1 bit 7: 1: uses run-length compression,
;; 0: uncompressed
;; bits 3..0: file code
;; 1 1 ?????
;; 2 1 track number
;; 3 2 skip in bytes
;; 5 1 checksum
;; 6 1 run-length encoding marker
;; 7 2 length in bytes (uncompressed), length of compressed data (compressed)
;; 9 2 length in bytes when uncompressed?
;; 11 1 decryption initial code
;; 12,13 2 decryption Z80 instructions
8116 dd7e02 ld a,(ix+$02) ;; track
8119 dd4e03 ld c,(ix+$03) ;; skip
811c dd4604 ld b,(ix+$04)
811f e5 push hl
8120 d5 push de
8121 cd9781 call $8197 ;; read data
8124 d1 pop de
8125 e1 pop hl
8126 d5 push de
8127 e5 push hl
;;------------------------------------------
;; checksum loaded data
;; HL = location
;; DE = length
8128 0e00 ld c,$00
812a 7e ld a,(hl)
812b a9 xor c
812c 4f ld c,a
812d 23 inc hl
812e 1b dec de
812f 7a ld a,d
8130 b3 or e
8131 20f7 jr nz,$812a
8133 e1 pop hl
8134 d1 pop de
8135 f1 pop af
8136 dde1 pop ix
8138 91 sub c
8139 2824 jr z,$815f
813b 217382 ld hl,$8273 ;; retry count
813e 35 dec (hl) ;; decrement
813f c27580 jp nz,$8075
;; failed!
8142 214f81 ld hl,$814f
8145 e5 push hl
8146 1100bf ld de,$bf00
8149 010900 ld bc,$0009
814c edb0 ldir
814e c9 ret
;;==================================================
;; error
;; stop disc motor
814f cd5881 call $8158
;; enable lower rom
8152 01807f ld bc,$7f80
8155 ed49 out (c),c
;; jump to &0000 (restarts CPC)
8157 c7 rst $00
;;==================================================
;; stop disc motor
8158 97 sub a
;;==================================================
;; set disc motor state
8159 017efa ld bc,$fa7e
815c ed79 out (c),a
815e c9 ret
;;==================================================
;; stop motor
815f cd5881 call $8158
;; decrypt data
8162 d5 push de
8163 e5 push hl
8164 0e00 ld c,$00
8166 7e ld a,(hl)
8167 00 nop
8168 00 nop
8169 77 ld (hl),a
816a 23 inc hl
816b 1b dec de
816c 7a ld a,d
816d b3 or e
816e 20f6 jr nz,$8166
8170 e1 pop hl
8171 d1 pop de
8172 0e00 ld c,$00 ;; run-length encoding marker
8174 3e00 ld a,$00 ;; bit 7 into carry. if set, run-length encoding is used
8176 17 rla
8177 d0 ret nc
;; C = run-length encoding marker
;;
;; decompress forwards
;;
;; byte!=marker -> output byte
;; byte==marker -> marker, 0 -> marker
;; byte==marker -> marker, count, byte -> byte * count
8178 0601 ld b,$01 ;; repeat count
817a 7e ld a,(hl) ;; get byte
817b b9 cp c ;; run-length encoding marker?
817c 200b jr nz,$8189 ;; no, output byte direct
;; it is run-length encoding marker
817e 23 inc hl
817f 1b dec de
8180 7e ld a,(hl) ;; get byte
8181 b7 or a
8182 79 ld a,c
8183 2804 jr z,$8189
8185 46 ld b,(hl) ;; count
8186 23 inc hl
8187 1b dec de
8188 7e ld a,(hl) ;; byte
;; B = count
;; A = data byte
8189 dd7700 ld (ix+$00),a
818c dd23 inc ix
818e 10f9 djnz $8189
8190 23 inc hl
8191 1b dec de
8192 7a ld a,d
8193 b3 or e
8194 20e2 jr nz,$8178
8196 c9 ret
;;-------------------------------------------------------------------------------
;; A = track
;; BC = initial skip
;; HL = load address
;; DE = total length
8197 326b82 ld ($826b),a
819a ed430982 ld ($8209),bc
819e 222382 ld ($8223),hl
81a1 ed53ba81 ld ($81ba),de
81a5 017efb ld bc,$fb7e
81a8 3a6b82 ld a,($826b) ;; track
81ab cddb81 call $81db ;; move to track
81ae 210018 ld hl,$1800 ;; length of useable data in a 6k/8k sector
81b1 ed5b0982 ld de,($8209) ;; skip
81b5 a7 and a
81b6 ed52 sbc hl,de ;; length of data remaining in sector
81b8 eb ex de,hl
81b9 210000 ld hl,$0000 ;; current length
81bc ed52 sbc hl,de ;; amount remaining in sector
81be 3005 jr nc,$81c5
;; amount remaining is less than amount remaining in sector
81c0 19 add hl,de
81c1 eb ex de,hl
;; this is the last sector for this directory
81c2 97 sub a
81c3 67 ld h,a
81c4 6f ld l,a
81c5 22ba81 ld ($81ba),hl ;; update length
81c8 ed532682 ld ($8226),de ;; length of data to transfer from this sector
81cc f5 push af
81cd 215b82 ld hl,$825b ;; read data
81d0 cdf981 call $81f9
81d3 216b82 ld hl,$826b ;; track number
81d6 34 inc (hl) ;; increment
81d7 f1 pop af
;; A = 0 if last block of data has been read
;; otherwise A!=0
81d8 20ce jr nz,$81a8
81da c9 ret
;;-------------------------------------------------------------------------------
;; A = track
81db 326b82 ld ($826b),a
81de 325e82 ld ($825e),a
81e1 216882 ld hl,$8268 ;; seek
81e4 cdf981 call $81f9
81e7 215982 ld hl,$8259 ;; sense interrupt status
81ea cdf981 call $81f9
81ed cb6e bit 5,(hl)
81ef 28f6 jr z,$81e7
81f1 cb5e bit 3,(hl)
81f3 20ec jr nz,$81e1
81f5 c9 ret
81f6 216582 ld hl,$8265 ;; read id
;;========================================================================
;; write command to fdc
81f9 5e ld e,(hl) ;; get number of bytes in command
81fa 23 inc hl
81fb ed78 in a,(c) ;; read main status register of fdc
81fd 87 add a,a
81fe 30fb jr nc,$81fb
8200 7e ld a,(hl) ;; get command byte
8201 0c inc c
8202 ed79 out (c),a ;; write command byte to fdc
8204 0d dec c
8205 1d dec e
8206 20f2 jr nz,$81fa
;;========================================================================
;; execution phase of fdc command
;;------------------------------
;; skip bytes
;; HL = number of bytes to skip
8208 211000 ld hl,$0010
820b 180e jr $821b
820d ed78 in a,(c) ;; read main status register of fdc
820f f20d82 jp p,$820d
8212 e620 and $20 ;; execution phase?
8214 282b jr z,$8241
8216 0c inc c
8217 ed78 in a,(c) ;; read data byte from FDC
8219 0d dec c
821a 2b dec hl ;; decrement skip count
821b 7c ld a,h
821c b5 or l
821d 20ee jr nz,$820d
;; update skip (set to 0)
821f 220982 ld ($8209),hl
;;------------------------------
;; read bytes
;; HL = address to load data to
;; DE = length
8222 2100b0 ld hl,$b000
8225 110000 ld de,$0000
8228 180b jr $8235
822a 7a ld a,d ;; finished reading all bytes?
822b b3 or e
822c 2807 jr z,$8235
822e 1b dec de ;; decrement length count
822f 0c inc c
8230 ed78 in a,(c) ;; read data byte from FDC
8232 0d dec c
8233 77 ld (hl),a ;; store it
8234 23 inc hl ;; update memory pointer
8235 ed78 in a,(c) ;; read main status register
8237 f23582 jp p,$8235
823a e620 and $20 ;; execution phase
823c 20ec jr nz,$822a
;; HL = current memory pointer
823e 222382 ld ($8223),hl
;; if (skip+length)
;; overrun error as the remaining data bytes are not read by
;; this protection system
;;-------------------------------
;; read result phase data
8241 216c82 ld hl,$826c ;; buffer for result phase data
8244 e5 push hl
8245 ed78 in a,(c) ;; read fdc main status register
8247 cb67 bit 4,a ;; fdc busy?
8249 280c jr z,$8257
824b fec0 cp $c0
824d 38f6 jr c,$8245
824f 0c inc c
8250 ed78 in a,(c) ;; read result byte from fdc
8252 0d dec c
8253 77 ld (hl),a ;; store
8254 23 inc hl
8255 18ee jr $8245
8257 e1 pop hl
8258 c9 ret
8259 defb &01, &08 ;; sense interrupt status
825b defb &09, &46, &00,&02,&00,&01,&06,&01,&2a,&ff ;; read data
8265 defb &02,&4a,&00 ;; read id
8268 defb &03,&0f,&00,&03 ;; seek
;; result
826c defs 7
8273 defb 0 ;; retry count
8274 defb 0 ;; directory loaded flag: 0 = not loaded, !=0 = loaded
Article créé le : | Jeudi 18 Février 2016 à 20 h 51 |
Dernière mise à jour le : | Jeudi 18 Février 2016 à 21 h 25 |