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