1 2 ; LST OFF 3 ORG $C700 ; change $Cx00, x=slot 4 5 ******************************** 6 * * 7 * Pseudo-Disk ][ ROM * 8 * Version v0.6a * 9 * By Alex Freed, VladiTX, * 10 * Deckard and Others * 11 * (ProDOS mode) * 12 * * 13 * Merlin-8 Source by Deckard * 14 * * 15 ******************************** 16 17 * Device driver parameters 18 19 P_CMD EQU $42 ; command: status, read, write 20 P_UNIT EQU $43 ; DSSS0000 D[0=drive 1,1=drive 2], SSS=slot 21 P_BUFL EQU $44 ; low I/O buffer 22 P_BUFH EQU $45 ; high 23 P_BLKL EQU $46 ; low block number 24 P_BLKH EQU $47 ; high 25 26 * Page 0 27 28 SLOT16 EQU $2B ; slot * 16 (boot sector relies on this) 29 CHKSUM EQU $FF ; checksum for read block 30 31 * Ram 32 33 STACK EQU $0100 34 35 * Rom 36 37 RDBTN0 EQU $C061 ; open apple/apple key 38 39 * Disk II Rom 40 41 WAIT_DATA EQU $C080 ; wait to have MSB high 42 MTROFF EQU $C088 ; motor off 43 MTRON EQU $C089 ; motor on 44 DR0 EQU $C08A ; drive 1 45 DR1 EQU $C08B ; drive 2 46 Q6L EQU $C08C ; read bytes 47 Q6H EQU $C08D ; send command to AVR 48 Q7L EQU $C08E 49 Q7H EQU $C08F 50 51 PD8CMD = Q6H 52 PD8RDAT = Q6L 53 PD8WDAT = Q6H 54 55 * Rom 56 57 KNOWN_RTS EQU $FF58 ; RTS 58 59 * Device command code 60 61 P_STAT = 0 62 P_READ = 1 63 P_WRITE = 2 64 P_FMT = 3 65 P_CORIG = 8 ; change origin 66 P_ZERO = $AA ; image_start_sector = 0 67 68 * PD8 interface 69 70 C_BLK = $02 ; set block address 71 C_WBUF = $04 ; write to buffer 72 C_MODPD = $81 ; set ProDOS mode 73 C_READ = $82 ; read block 74 C_WRITE = $A2 ; write block (from buffer) 75 C_DRV = $C0 ; $C0 = drive #1, $C1 = drive #2 76 77 * ProDOS errors 78 79 ERR_IO = $27 : I/O error 80 ERR_DEV = $28 ; no device connected 81 ERR_WP = $2B ; write protect error 82 83 * Conditional pseudo ops 84 85 WAIT1 = 1 ; set to fix initialization timing 86 WAIT2 = 1 ; set to fix block-address timing 87 CHKBERR = 1 ; set to check for buffer-transfer errors 88 CHKRERR = 0 ; set to check for media errors on read 89 CHKWERR = 1 ; set to check for media errors on write 90 91 * Macros 92 93 PD8WAIT MAC 94 LDA WAIT_DATA,X 95 BPL *-3 96 <<< 97 98 ******************************** 99 100 * What happens if you type: PR#slot? 101 * 102 * 1) Exec INIT0: set parms for block $0000 103 * 2) Exec ENTRY: set parms for read block 104 * 3) Exec DO_READ : load block $0000 into memory ($0800) 105 * 4) RTS : JMP $0801 106 107 INIT0 C700: A9 20 108 LDA #$20 ; $Cx01 = $20 -> unique disk device signature C702: A2 00 109 LDX #$00 ; $Cx03 = $00 -> ProDOS disk device C704: A9 03 110 LDA #$03 ; $Cx05 = $03 -> ProDOS disk device C706: A9 3C 111 LDA #$3C ; $Cx07 = $3C -> ProDOS disk device 112 113 ; X=0 C708: 86 46 114 STX P_BLKL ; prepare block 0 to be read at $0800 C70A: 86 47 115 STX P_BLKH C70C: 86 44 116 STX P_BUFL ; #<$0800 117 C70E: A9 08 118 LDA #>$0800 C710: 85 45 119 STA P_BUFH 120 ; after sector is read, will return to $0801 with 121 ; X = slot * 16 C712: 48 122 PHA ; return address -1 (high) C713: 8A 123 TXA C714: 48 124 PHA ; return address -1 (low) 125 C715: E8 126 INX ; P_READ C716: 86 42 127 STX P_CMD 128 C718: 20 58 FF 129 JSR KNOWN_RTS ; method: get slot C71B: BA 130 TSX C71C: BD 00 01 131 LDA STACK,X ; high $Cx?? C71F: 0A 132 ASL ; *16 C720: 0A 133 ASL C721: 0A 134 ASL C722: 0A 135 ASL C723: AA 136 TAX ; index C724: 85 2B 137 STA SLOT16 C726: 85 43 138 STA P_UNIT ; same slot, drive 1 139 140 * Put PD8 into known state 141 C728: BD 8E C0 142 LDA Q7L,X 143 DO WAIT1 C72B: EA 144 NOP 145 FIN 146 C72C: BD 8C C0 147 LDA Q6L,X 148 DO WAIT1 C72F: EA 149 NOP 150 FIN 151 C730: BD 8A C0 152 LDA DR0,X 153 DO WAIT1 C733: EA 154 NOP 155 FIN 156 C734: BD 89 C0 157 LDA MTRON,X 158 DO WAIT1 C737: EA 159 NOP 160 FIN 161 C738: A9 81 162 LDA #C_MODPD ; set ProDOS mode C73A: 9D 8D C0 163 STA PD8CMD,X 164 C73D: AD 61 C0 165 LDA RDBTN0 ; OA pressed? C740: 10 0A 166 BPL ENTRY ; no 167 168 ; restart C742: A9 08 169 LDA #P_CORIG ; change origin C744: 9D 8D C0 170 STA PD8CMD,X C747: A9 AA 171 LDA #P_ZERO C749: 9D 8D C0 172 STA PD8CMD,X 173 174 175 *==============================* 176 * * 177 * PRODOS ENTRY POINT * 178 * * 179 *==============================* 180 C74C: A5 43 181 ENTRY LDA P_UNIT C74E: 29 70 182 AND #%01110000 ; remove drive # C750: AA 183 TAX ; slot*16 184 C751: A5 43 185 LDA P_UNIT C753: 2A 186 ROL ; drive # in carry C754: A9 C0 187 LDA #C_DRV ; select drive C756: 69 00 188 ADC #0 ; add carry C758: 9D 8D C0 189 STA PD8CMD,X 190 191 DO WAIT2 C75B: 48 192 PHA C75C: 68 193 PLA 194 FIN 195 C75D: A9 02 196 LDA #C_BLK ; set block address C75F: 9D 8D C0 197 STA PD8CMD,X 198 199 DO WAIT2 C762: 48 200 PHA C763: 68 201 PLA 202 FIN 203 C764: A5 47 204 LDA P_BLKH ; high block C766: 9D 8D C0 205 STA PD8WDAT,X 206 207 DO WAIT2 C769: 48 208 PHA C76A: 68 209 PLA 210 FIN 211 C76B: A5 46 212 LDA P_BLKL ; low block C76D: 9D 8D C0 213 STA PD8WDAT,X 214 215 * Dispatch ProDOS command 216 C770: 38 217 SEC C771: A4 42 218 LDY P_CMD ; get ProDOS command C773: F0 46 219 BEQ DO_STAT ; P_STAT 220 C775: 88 221 DEY C776: F0 49 222 BEQ DO_READ ; P_READ 223 C778: 88 224 DEY ; P_WRITE? C779: D0 3C 225 BNE DO_ERR ; sorry man, no format cmd! 226 227 228 *==============================* 229 * * 230 * WRITE REQUEST * 231 * * 232 *==============================* 233 234 * Out: carry = 0 : no err 235 * carry = 1 : err & acc=err number 236 C77B: A9 04 237 DO_WRITE LDA #C_WBUF ; write to buf C77D: 9D 8D C0 238 STA PD8CMD,X 239 C780: A5 FF 240 LDA CHKSUM ; save memory C782: 48 241 PHA 242 ; Y=0 C783: 84 FF 243 STY CHKSUM ; chksum=0 244 ; carry=1 C785: 24 245 DFB $24 ; bit C786: 18 246 :2 CLC ; device ready/no err & stop writing 247 C787: B1 44 248 :1 LDA (P_BUFL),Y ; write 256 bytes C789: 9D 8D C0 249 STA PD8WDAT,X C78C: 45 FF 250 EOR CHKSUM C78E: 85 FF 251 STA CHKSUM C790: C8 252 INY C791: D0 F4 253 BNE :1 254 ; Y=0 C793: 90 04 255 BCC :3 ; end writing 256 C795: E6 45 257 INC P_BUFH ; next page of memory C797: B0 ED 258 BCS :2 ; 2nd part of the block 259 C799: C6 45 260 :3 DEC P_BUFH ; restore previous user value 261 262 * Send checksum to AVR (not written on the card!) 263 C79B: 9D 8D C0 264 STA PD8WDAT,X 265 C79E: 68 266 PLA ; restore memory C79F: 85 FF 267 STA CHKSUM 268 269 DO CHKBERR C7A1: BD 80 C0 270 LDA WAIT_DATA,X C7A4: 29 7F 271 AND #%01111111 ; errors? C7A6: D0 D3 272 BNE DO_WRITE ; retry 273 FIN 274 C7A8: A9 A2 275 LDA #C_WRITE ; write buffer C7AA: 9D 8D C0 276 STA PD8CMD,X 277 PD8WAIT C7AD: BD 80 C0 277 LDA WAIT_DATA,X C7B0: 10 FB 277 BPL *-3 277 <<< 278 279 DO CHKWERR C7B2: 29 7F 280 AND #%01111111 ; errors? C7B4: D0 01 281 BNE DO_ERR 282 FIN 283 C7B6: 60 284 RTS 285 286 287 *==============================* 288 * * 289 * ERRORS * 290 * * 291 *==============================* 292 293 DO CHKRERR 294 DO_ERRCS 295 PLA ; restore memory 296 STA CHKSUM 297 FIN 298 DO_ERR C7B7: A9 27 299 LDA #ERR_IO ; I/O err C7B9: 38 300 SEC C7BA: 60 301 RTS ; return to ProDOS 302 303 304 *==============================* 305 * * 306 * STATUS REQUEST * 307 * * 308 *==============================* 309 C7BB: 98 310 DO_STAT TYA ; Y=acc=0 C7BC: AA 311 TAX ; X=0 C7BD: 88 312 DEY ; Y=$FF high blocks available C7BE: CA 313 DEX ; X=$FF low blocks available C7BF: 18 314 CLC ; device ready/no err C7C0: 60 315 RTS 316 317 318 *==============================* 319 * * 320 * READ REQUEST * 321 * * 322 *==============================* 323 324 * Out: carry = 0 : no err 325 * carry = 1 : err & acc=err number 326 C7C1: A5 FF 327 DO_READ LDA CHKSUM ; save memory C7C3: 48 328 PHA 329 C7C4: A9 82 330 :1 LDA #C_READ ; read block C7C6: 9D 8D C0 331 STA PD8CMD,X 332 PD8WAIT C7C9: BD 80 C0 332 LDA WAIT_DATA,X C7CC: 10 FB 332 BPL *-3 332 <<< 333 334 DO CHKRERR 335 AND #%01111111 ; errors? 336 BNE DO_ERRCS 337 FIN 338 C7CE: 84 FF 339 STY CHKSUM ; checksum=0 340 ; carry=1 C7D0: 24 341 DFB $24 ; bit C7D1: 18 342 :3 CLC ; device ready/no err & stop reading 343 C7D2: BD 8C C0 344 :2 LDA PD8RDAT,X ; fetch sector data (read 256 bytes) C7D5: 91 44 345 STA (P_BUFL),Y C7D7: 45 FF 346 EOR CHKSUM C7D9: 85 FF 347 STA CHKSUM C7DB: C8 348 INY C7DC: D0 F4 349 BNE :2 350 C7DE: 90 04 351 BCC :4 ; end reading 352 ; Y=0 C7E0: E6 45 353 INC P_BUFH ; next page of memory C7E2: B0 ED 354 BCS :3 ; 2nd part of the block 355 C7E4: C6 45 356 :4 DEC P_BUFH ; restore previous user value 357 358 * Read checksum from AVR (not a byte from the card!) 359 C7E6: BD 8C C0 360 LDA PD8RDAT,X 361 DO CHKBERR C7E9: 45 FF 362 EOR CHKSUM ; bus errors? C7EB: D0 D7 363 BNE :1 ; retry 364 FIN 365 C7ED: 68 366 PLA C7EE: 85 FF 367 STA CHKSUM ; restore memory C7F0: 60 368 RTS 369 370 *------------------------------- 371 C7F1: 00 00 00 372 DS 11,0 C7F4: 00 00 00 00 C7F8: 00 00 00 00 373 374 ******************************** 375 376 * ProDOS conventions 377 C7FC: 00 00 378 HCXFC DFB 0,0 ; 0 blocks = check status C7FE: 17 379 HCXFE DFB %00010111 ; read/write/status 380 * %1....... ; removable media 381 * %.1...... ; interruptable device 382 * %..nn.... ; number of volumes on device-1 383 * %....1... ; format allowed 384 * %.....1.. ; write allowed 385 * %......1. ; read allowed 386 * %.......1 ; status read allowed 387 C7FF: 4C 388 HCXFF DFB #