1 ******************************** 2 * 3 * Apple][Sd Firmware 4 * Version 0.7 5 * 6 * (c) Florian Reitz, 2017 7 * 8 * X register usually contains SLOT16 9 * Y register is used for counting or SLOT 10 * 11 ******************************** 12 16-OCT-17 23:58 14 15 XC ; enable 65C02 code 16 DEBUG = 0 17 DO DEBUG 18 ORG $8000 19 ELSE 20 ORG $C800 ; Expansion ROM 21 FIN 22 23 * Memory defines 24 25 SLOT16 = $2B ; $s0 -> slot * 16 26 WORK = $3C 27 SLOT = $3D ; $0s 28 CMDLO = $40 29 CMDHI = $41 30 31 DCMD = $42 ; Command code 32 BUFFER = $44 ; Buffer address 33 BLOCK = $46 ; Block number 34 35 CURSLOT = $07F8 ; $Cs 36 DATA = $C080 37 CTRL = DATA+1 38 DIV = DATA+2 39 SS = DATA+3 40 R30 = $0478 41 R31 = $04F8 42 R32 = $0578 43 R33 = $05F8 44 45 * Constants 46 47 DUMMY = $FF 48 FRX = $10 ; CTRL register 49 ECE = $04 50 SS0 = $01 ; SS register 51 WP = $20 52 CD = $40 53 INITED = $80 54 55 56 ******************************** 57 * 58 * Initialize SD card 59 * 60 * C Clear - No error 61 * Set - Error 62 * A $00 - No error 63 * $27 - I/O error - Init failed 64 * $2F - No card inserted 65 * 66 ******************************** 67 C800: D8 68 INIT CLD C801: A9 03 69 LDA #$03 ; set SPI mode 3 C803: 9D 81 C0 70 STA CTRL,X C806: BD 83 C0 71 LDA SS,X C809: 09 01 72 ORA #SS0 ; set CS high C80B: 9D 83 C0 73 STA SS,X C80E: A9 07 74 LDA #7 C810: 9D 82 C0 75 STA DIV,X C813: A0 0A 76 LDY #10 C815: A9 FF 77 LDA #DUMMY 78 C817: 9D 80 C0 79 :LOOP STA DATA,X C81A: 3C 81 C0 80 :WAIT BIT CTRL,X C81D: 10 FB 81 BPL :WAIT C81F: 88 82 DEY C820: D0 F5 83 BNE :LOOP ; do 10 times C822: BD 83 C0 84 LDA SS,X C825: 29 FE 85 AND #$FF!SS0 ; set CS low C827: 9D 83 C0 86 STA SS,X 87 C82A: A9 C5 88 LDA #CMD0 C830: 85 41 91 STA CMDHI C832: 20 F0 C8 92 JSR CMD C835: 20 04 C9 93 JSR GETR1 ; get response C838: C9 01 94 CMP #$01 C83A: D0 39 95 BNE :ERROR1 ; error! 96 C83C: A9 D1 97 LDA #CMD8 C842: 85 41 100 STA CMDHI C844: 20 F0 C8 101 JSR CMD C847: 20 1F C9 102 JSR GETR3 C84A: C9 01 103 CMP #$01 C84C: D0 2A 104 BNE :SDV1 ; may be SD Ver. 1 105 106 * check for $01aa match! C84E: A9 DD 107 :SDV2 LDA #CMD55 C854: 85 41 110 STA CMDHI C856: 20 F0 C8 111 JSR CMD C859: 20 04 C9 112 JSR GETR1 C85C: A9 E3 113 LDA #ACMD4140 C862: 85 41 116 STA CMDHI C864: 20 F0 C8 117 JSR CMD C867: 20 04 C9 118 JSR GETR1 C86A: C9 01 119 CMP #$01 C86C: F0 E0 120 BEQ :SDV2 ; wait for ready C86E: C9 00 121 CMP #$00 C870: D0 03 122 BNE :ERROR1 ; error! 123 * send CMD58 124 * SD Ver. 2 initialized! C872: 4C B2 C8 125 JMP :BLOCKSZ 126 C875: 4C DE C8 127 :ERROR1 JMP :IOERROR ; needed for far jump 128 C878: A9 DD 129 :SDV1 LDA #CMD55 C87E: 85 41 132 STA CMDHI C880: 20 F0 C8 133 JSR CMD ; ignore response C883: A9 E9 134 LDA #ACMD410 C889: 85 41 137 STA CMDHI C88B: 20 F0 C8 138 JSR CMD C88E: 20 04 C9 139 JSR GETR1 C891: C9 01 140 CMP #$01 C893: F0 E3 141 BEQ :SDV1 ; wait for ready C895: C9 00 142 CMP #$00 C897: D0 03 143 BNE :MMC ; may be MMC card 144 * SD Ver. 1 initialized! C899: 4C B2 C8 145 JMP :BLOCKSZ 146 C89C: A9 CB 147 :MMC LDA #CMD1 C8A2: 85 41 150 STA CMDHI C8A4: 20 F0 C8 151 :LOOP1 JSR CMD C8A7: 20 04 C9 152 JSR GETR1 C8AA: C9 01 153 CMP #$01 C8AC: F0 F6 154 BEQ :LOOP1 ; wait for ready C8AE: C9 00 155 CMP #$00 C8B0: D0 2C 156 BNE :IOERROR ; error! 157 * MMC Ver. 3 initialized! 158 C8B2: A9 D7 159 :BLOCKSZ LDA #CMD16 C8B8: 85 41 162 STA CMDHI C8BA: 20 F0 C8 163 JSR CMD C8BD: 20 04 C9 164 JSR GETR1 C8C0: C9 00 165 CMP #$00 C8C2: D0 1A 166 BNE :IOERROR ; error! 167 C8C4: BD 83 C0 168 :END LDA SS,X C8C7: 09 80 169 ORA #INITED ; initialized C8C9: 9D 83 C0 170 STA SS,X C8CC: BD 81 C0 171 LDA CTRL,X C8CF: 09 04 172 ORA #ECE ; enable 7MHz C8D1: 9D 81 C0 173 STA CTRL,X C8D4: 18 174 CLC ; all ok C8D5: A0 00 175 LDY #0 C8D7: 90 08 176 BCC :END1 C8D9: 38 177 :CDERROR SEC C8DA: A0 2F 178 LDY #$2F ; no card error C8DC: B0 03 179 BCS :END1 C8DE: 38 180 :IOERROR SEC C8DF: A0 27 181 LDY #$27 ; init error C8E1: BD 83 C0 182 :END1 LDA SS,X ; set CS high C8E4: 09 01 183 ORA #SS0 C8E6: 9D 83 C0 184 STA SS,X C8E9: A9 00 185 LDA #0 ; set div to 2 C8EB: 9D 82 C0 186 STA DIV,X C8EE: 98 187 TYA ; retval in A C8EF: 60 188 RTS 189 190 191 ******************************** 192 * 193 * Send SD command 194 * Call with command in CMDHI and CMDLO 195 * 196 ******************************** 197 C8F0: 5A 198 CMD PHY C8F1: A0 00 199 LDY #0 C8F3: B1 40 200 :LOOP LDA (CMDLO),Y C8F5: 9D 80 C0 201 STA DATA,X C8F8: 3C 81 C0 202 :WAIT BIT CTRL,X ; TC is in N C8FB: 10 FB 203 BPL :WAIT C8FD: C8 204 INY C8FE: C0 06 205 CPY #6 C900: 90 F1 206 BCC :LOOP C902: 7A 207 PLY C903: 60 208 RTS 209 210 211 ******************************** 212 * 213 * Get R1 214 * R1 is in A 215 * 216 ******************************** 217 C904: A9 FF 218 GETR1 LDA #DUMMY C906: 9D 80 C0 219 STA DATA,X C909: 3C 81 C0 220 :WAIT BIT CTRL,X C90C: 10 FB 221 BPL :WAIT C90E: BD 80 C0 222 LDA DATA,X ; get response C911: 85 3C 223 STA WORK ; save R1 C913: 29 80 224 AND #$80 C915: D0 ED 225 BNE GETR1 ; wait for MSB=0 C917: A9 FF 226 LDA #DUMMY C919: 9D 80 C0 227 STA DATA,X ; send another dummy C91C: A5 3C 228 LDA WORK ; restore R1 C91E: 60 229 RTS 230 231 232 ******************************** 233 * 234 * Get R3 235 * R1 is in A 236 * R3 is in scratchpad ram 237 * 238 ******************************** 239 C91F: 20 04 C9 240 GETR3 JSR GETR1 ; get R1 first C922: 48 241 PHA ; save R1 C923: 5A 242 PHY ; save Y C924: A0 04 243 LDY #04 ; load counter C926: A9 FF 244 :LOOP LDA #DUMMY ; send dummy C928: 9D 80 C0 245 STA DATA,X C92B: 3C 81 C0 246 :WAIT BIT CTRL,X C92E: 10 FB 247 BPL :WAIT C930: BD 80 C0 248 LDA DATA,X C933: 48 249 PHA C934: 88 250 DEY C935: D0 EF 251 BNE :LOOP ; do 4 times C937: A4 3D 252 LDY SLOT C939: 68 253 PLA C93A: 99 F8 05 254 STA R33,Y ; save R3 C93D: 68 255 PLA C93E: 99 78 05 256 STA R32,Y C941: 68 257 PLA C942: 99 F8 04 258 STA R31,Y C945: 68 259 PLA C946: 99 78 04 260 STA R30,Y C949: 7A 261 PLY ; restore Y C94A: A9 FF 262 LDA #DUMMY C94C: 9D 80 C0 263 STA DATA,X ; send another dummy C94F: 68 264 PLA ; restore R1 C950: 60 265 RTS 266 267 268 ******************************** 269 * 270 * Calculate block address 271 * Unit number is in $43 DSSS0000 272 * Block no is in $46-47 273 * Address is in R30-R33 274 * 275 ******************************** 276 C951: DA 277 GETBLOCK PHX ; save X C952: 5A 278 PHY ; save Y C953: A6 3D 279 LDX SLOT C955: A5 46 280 LDA BLOCK ; store block num C957: 9D F8 05 281 STA R33,X ; in R30-R33 C95A: A5 47 282 LDA BLOCK+1 C95C: 9D 78 05 283 STA R32,X C95F: A9 00 284 LDA #0 C961: 9D F8 04 285 STA R31,X C964: 9D 78 04 286 STA R30,X 287 C967: A9 80 288 LDA #$80 ; drive number C969: 24 43 289 BIT $43 C96B: F0 05 290 BEQ :SHIFT ; D1 C96D: A9 01 291 LDA #1 ; D2 C96F: 9D F8 04 292 STA R31,X 293 C972: A0 09 294 :SHIFT LDY #9 ; ASL can't be used with Y C974: 1E F8 05 295 :LOOP ASL R33,X ; mul block num C977: 3E 78 05 296 ROL R32,X ; by 512 to get C97A: 3E F8 04 297 ROL R31,X ; real address C97D: 3E 78 04 298 ROL R30,X C980: 88 299 DEY C981: D0 F1 300 BNE :LOOP C983: 7A 301 PLY ; restore Y C984: FA 302 PLX ; restore X C985: 60 303 RTS 304 305 306 ******************************** 307 * 308 * Send SD command 309 * Cmd is in A 310 * 311 ******************************** 312 C986: 5A 313 COMMAND PHY ; save Y C987: A4 3D 314 LDY SLOT C989: 9D 80 C0 315 STA DATA,X ; send command C98C: B9 78 04 316 LDA R30,Y ; get arg from R30 on C98F: 9D 80 C0 317 STA DATA,X C992: B9 F8 04 318 LDA R31,Y C995: 9D 80 C0 319 STA DATA,X C998: B9 78 05 320 LDA R32,Y C99B: 9D 80 C0 321 STA DATA,X C99E: B9 F8 05 322 LDA R33,Y C9A1: 9D 80 C0 323 STA DATA,X C9A4: A9 FF 324 LDA #DUMMY C9A6: 9D 80 C0 325 STA DATA,X ; dummy crc C9A9: 20 04 C9 326 JSR GETR1 C9AC: 7A 327 PLY ; restore Y C9AD: 60 328 RTS 329 330 331 ******************************** 332 * 333 * Check for card detect 334 * 335 * C Clear - card in slot 336 * Set - no card in slot 337 * 338 ******************************** 339 C9AE: 48 340 CARDDET PHA C9AF: A9 40 341 LDA #CD ; 0: card in C9B1: 3C 83 C0 342 BIT SS,X ; 1: card out C9B4: 18 343 CLC C9B5: F0 01 344 BEQ :DONE ; card is in C9B7: 38 345 SEC ; card is out C9B8: 68 346 :DONE PLA C9B9: 60 347 RTS 348 349 350 ******************************** 351 * 352 * Check for write protect 353 * 354 * C Clear - card not protected 355 * Set - card write protected 356 * 357 ******************************** 358 C9BA: 48 359 WRPROT PHA C9BB: A9 20 360 LDA #WP ; 0: write enabled C9BD: 3C 83 C0 361 BIT SS,X ; 1: write disabled C9C0: 18 362 CLC C9C1: F0 01 363 BEQ :DONE C9C3: 38 364 SEC C9C4: 68 365 :DONE PLA C9C5: 60 366 RTS 367 368 369 ******************************** 370 * 371 * Status request 372 * $43 Unit number DSSS000 373 * $44-45 Unused 374 * $46-47 Unused 375 * 376 * C Clear - No error 377 * Set - Error 378 * A $00 - No error 379 * $2B - Card write protected 380 * $2F - No card inserted 381 * X - Blocks avail (low byte) 382 * Y - Blocks avail (high byte) 383 * 384 ******************************** 385 C9C6: A9 00 386 STATUS LDA #0 ; no error C9C8: A2 FF 387 LDX #$FF ; 32 MB partition C9CA: A0 FF 388 LDY #$FF 389 C9CC: 20 AE C9 390 JSR CARDDET C9CF: 90 04 391 BCC :WRPROT C9D1: A9 2F 392 LDA #$2F ; no card inserted C9D3: 80 07 393 BRA :DONE 394 C9D5: 20 BA C9 395 :WRPROT JSR WRPROT C9D8: 90 02 396 BCC :DONE C9DA: A9 2B 397 LDA #$2B ; card write protected 398 C9DC: 60 399 :DONE RTS 400 401 402 ******************************** 403 * 404 * Read 512 byte block 405 * $43 Unit number DSSS0000 406 * $44-45 Address (LO/HI) of buffer 407 * $46-47 Block number (LO/HI) 408 * 409 * C Clear - No error 410 * Set - Error 411 * A $00 - No error 412 * $27 - Bad block number 413 * $28 - No card inserted 414 * 415 ******************************** 416 C9DD: 20 AE C9 417 READ JSR CARDDET C9E0: B0 64 418 BCS :ERROR ; no card inserted 419 C9E2: 20 51 C9 420 JSR GETBLOCK ; calc block address 421 C9E5: BD 83 C0 422 LDA SS,X ; enable /CS C9E8: 29 FE 423 AND #$FF!SS0 C9EA: 9D 83 C0 424 STA SS,X C9ED: A9 51 425 LDA #$51 ; send CMD17 C9EF: 20 86 C9 426 JSR COMMAND ; send command 427 C9F2: C9 00 428 CMP #0 ; check for error C9F4: D0 50 429 BNE :ERROR 430 C9F6: A9 FF 431 :GETTOK LDA #DUMMY ; get data token C9F8: 9D 80 C0 432 STA DATA,X C9FB: BD 80 C0 433 LDA DATA,X ; get response C9FE: C9 FE 434 CMP #$FE CA00: D0 F4 435 BNE :GETTOK ; wait for $FE 436 CA02: A0 02 437 LDY #2 ; read data from card CA04: BD 81 C0 438 LDA CTRL,X ; enable FRX CA07: 09 10 439 ORA #FRX CA09: 9D 81 C0 440 STA CTRL,X CA0C: A9 FF 441 LDA #DUMMY CA0E: 9D 80 C0 442 STA DATA,X CA11: 64 3C 443 :LOOPY STZ WORK CA13: BD 80 C0 444 :LOOPW LDA DATA,X CA16: 92 44 445 STA (BUFFER) CA18: E6 44 446 INC BUFFER CA1A: D0 02 447 BNE :INW CA1C: E6 45 448 INC BUFFER+1 ; inc msb on page boundary CA1E: E6 3C 449 :INW INC WORK CA20: D0 F1 450 BNE :LOOPW CA22: 88 451 DEY CA23: D0 EC 452 BNE :LOOPY 453 CA25: BD 80 C0 454 :CRC LDA DATA,X ; read two bytes crc CA28: BD 80 C0 455 LDA DATA,X ; and ignore CA2B: BD 80 C0 456 LDA DATA,X ; read a dummy byte 457 CA2E: BD 81 C0 458 LDA CTRL,X ; disable FRX CA31: 29 EF 459 AND #$FF!FRX CA33: 9D 81 C0 460 STA CTRL,X CA36: 18 461 CLC ; no error CA37: A9 00 462 LDA #0 463 CA39: 08 464 :DONE PHP CA3A: 48 465 PHA CA3B: BD 83 C0 466 LDA SS,X CA3E: 09 01 467 ORA #SS0 CA40: 9D 83 C0 468 STA SS,X ; disable /CS CA43: 68 469 PLA CA44: 28 470 PLP CA45: 60 471 RTS 472 CA46: 38 473 :ERROR SEC ; an error occured CA47: A9 27 474 LDA #$27 CA49: 80 EE 475 BRA :DONE 476 477 478 ******************************** 479 * 480 * Write 512 byte block 481 * $43 Unit number DSSS0000 482 * $44-45 Address (LO/HI) of buffer 483 * $46-47 Block number (LO/HI) 484 * 485 * C Clear - No error 486 * Set - Error 487 * A $00 - No error 488 * $27 - I/O error or bad block number 489 * $2B - Card write protected 490 * 491 ******************************** 492 CA4B: 20 AE C9 493 WRITE JSR CARDDET CA4E: B0 67 494 BCS :IOERROR ; no card inserted 495 CA50: 20 BA C9 496 JSR WRPROT CA53: B0 67 497 BCS :WPERROR ; card write protected 498 CA55: 20 51 C9 499 JSR GETBLOCK ; calc block address 500 CA58: BD 83 C0 501 LDA SS,X ; enable /CS CA5B: 29 FE 502 AND #$FF!SS0 CA5D: 9D 83 C0 503 STA SS,X CA60: A9 58 504 LDA #$58 ; send CMD24 CA62: 20 86 C9 505 JSR COMMAND ; send command 506 CA65: C9 00 507 CMP #0 ; check for error CA67: D0 4E 508 BNE :IOERROR 509 CA69: A9 FF 510 LDA #DUMMY CA6B: 9D 80 C0 511 STA DATA,X ; send dummy CA6E: A9 FE 512 LDA #$FE CA70: 9D 80 C0 513 STA DATA,X ; send data token 514 CA73: A0 02 515 LDY #2 ; send data to card CA75: 64 3C 516 :LOOPY STZ WORK CA77: B2 44 517 :LOOPW LDA (BUFFER) CA79: 9D 80 C0 518 STA DATA,X CA7C: E6 44 519 INC BUFFER CA7E: D0 02 520 BNE :INW CA80: E6 45 521 INC BUFFER+1 ; inc msb on page boundary CA82: E6 3C 522 :INW INC WORK CA84: D0 F1 523 BNE :LOOPW CA86: 88 524 DEY CA87: D0 EC 525 BNE :LOOPY 526 CA89: 9D 80 C0 527 :CRC STA DATA,X ; send 2 dummy crc bytes CA8C: 9D 80 C0 528 STA DATA,X 529 CA8F: 9D 80 C0 530 STA DATA,X ; get data response CA92: BD 80 C0 531 LDA DATA,X CA95: 29 1F 532 AND #$1F CA97: C9 05 533 CMP #$05 CA99: D0 1C 534 BNE :IOERROR ; check for write error CA9B: 18 535 CLC ; no error CA9C: A9 00 536 LDA #0 537 CA9E: 08 538 :DONE PHP CA9F: 48 539 PHA CAA0: A9 FF 540 :WAIT LDA #DUMMY CAA2: 9D 80 C0 541 STA DATA,X ; wait for write cycle CAA5: BD 80 C0 542 LDA DATA,X ; to complete CAA8: C9 00 543 CMP #$00 CAAA: F0 F4 544 BEQ :WAIT 545 CAAC: BD 83 C0 546 LDA SS,X ; disable /CS CAAF: 09 01 547 ORA #SS0 CAB1: 9D 83 C0 548 STA SS,X CAB4: 68 549 PLA CAB5: 28 550 PLP CAB6: 60 551 RTS 552 CAB7: 38 553 :IOERROR SEC ; an error occured CAB8: A9 27 554 LDA #$27 CABA: 80 E2 555 BRA :DONE 556 CABC: 38 557 :WPERROR SEC CABD: A9 2B 558 LDA #$2B CABF: 80 DD 559 BRA :DONE 560 561 562 563 ******************************** 564 * 565 * Format 566 * not supported! 567 * 568 ******************************** 569 CAC1: 38 570 FORMAT SEC CAC2: A9 01 571 LDA #$01 ; invalid command CAC4: 60 572 RTS 573 574 575 ******************************** 576 * 577 * Test routine 578 * 579 ******************************** 580 581 DO DEBUG 582 TEST 583 584 * get buffer 585 LDA #2 ; get 512 byte buffer 586 JSR $BEF5 ; call GETBUFR 587 BCS :ERROR 588 STA BUFADD+1 589 STA BUFFER+1 590 STZ BUFADD 591 STZ BUFFER 592 593 * fill buffer 594 LDY #0 595 :LOOP TYA 596 STA (BUFFER),Y 597 INY 598 BNE :LOOP 599 INC BUFFER+1 600 :LOOP1 TYA 601 STA (BUFFER),Y 602 INY 603 BNE :LOOP1 604 605 * write to card 606 LDA #2 ; write cmd 607 STA DCMD 608 LDA BUFADD ; buffer address 609 STA BUFFER 610 LDA BUFADD+1 611 STA BUFFER+1 612 STZ BLOCK ; block number 613 STZ BLOCK+1 614 LDX SLOT16 615 JSR DRIVER 616 BCS :ERROR 617 618 * read from card 619 LDA #1 ; read cmd 620 STA DCMD 621 LDA BUFADD ; buffer address 622 STA BUFFER 623 LDA BUFADD+1 624 STA BUFFER+1 625 STZ BLOCK ; block number 626 STZ BLOCK+1 627 LDX SLOT16 628 JSR DRIVER 629 BCS :ERROR 630 631 * check for errors 632 LDA BUFADD ; buffer address 633 STA BUFFER 634 LDA BUFADD+1 635 STA BUFFER+1 636 LDY #0 637 :LOOP2 TYA 638 CMP (BUFFER),Y 639 BNE :ERRCMP ; error in buffer 640 INY 641 BNE :LOOP2 642 INC BUFFER+1 643 :LOOP3 TYA 644 CMP (BUFFER),Y 645 BNE :ERRCMP 646 INY 647 BNE :LOOP3 648 649 * free buffer 650 JSR $BEF8 ; call FREEBUFR 651 CLC 652 LDA #0 653 RTS 654 655 :ERROR BRK 656 :ERRCMP BRK 657 658 BUFADD DW 0 659 FIN 660 661 CAC5: 40 00 00 662 CMD0 HEX 400000 CAC8: 00 00 95 663 HEX 000095 CACB: 41 00 00 664 CMD1 HEX 410000 CACE: 00 00 F9 665 HEX 0000F9 CAD1: 48 00 00 666 CMD8 HEX 480000 CAD4: 01 AA 87 667 HEX 01AA87 CAD7: 50 00 00 668 CMD16 HEX 500000 CADA: 02 00 FF 669 HEX 0200FF CADD: 77 00 00 670 CMD55 HEX 770000 CAE0: 00 00 65 671 HEX 000065 CAE3: 69 40 00 672 ACMD4140 HEX 694000 CAE6: 00 00 77 673 HEX 000077 CAE9: 69 00 00 674 ACMD410 HEX 690000 CAEC: 00 00 FF 675 HEX 0000FF 676 677 678 ******************************** 679 * 680 * This region is mapped to 681 * the $CsXX space. On the ROM 682 * it must appear at address $700 683 * 684 ******************************** 685 686 DO DEBUG-1 CAEF: 00 00 00 687 DS \ CAF2: 00 00 00 00 CAF6: 00 00 00 00 CAFA: 00 00 00 00 CAFE: 00 00 CB00: 00 00 00 688 DS $400 CB03: 00 00 00 00 CB07: 00 00 00 00 CB0B: 00 00 00 00 CB0F: 00 00 00 00 CB13: 00 00 00 00 CB17: 00 00 00 00 CB1B: 00 00 00 00 CB1F: 00 00 00 00 CB23: 00 00 00 00 CB27: 00 00 00 00 CB2B: 00 00 00 00 CB2F: 00 00 00 00 CB33: 00 00 00 00 CB37: 00 00 00 00 CB3B: 00 00 00 00 CB3F: 00 00 00 00 CB43: 00 00 00 00 CB47: 00 00 00 00 CB4B: 00 00 00 00 CB4F: 00 00 00 00 CB53: 00 00 00 00 CB57: 00 00 00 00 CB5B: 00 00 00 00 CB5F: 00 00 00 00 CB63: 00 00 00 00 CB67: 00 00 00 00 CB6B: 00 00 00 00 CB6F: 00 00 00 00 CB73: 00 00 00 00 CB77: 00 00 00 00 CB7B: 00 00 00 00 CB7F: 00 00 00 00 CB83: 00 00 00 00 CB87: 00 00 00 00 CB8B: 00 00 00 00 CB8F: 00 00 00 00 CB93: 00 00 00 00 CB97: 00 00 00 00 CB9B: 00 00 00 00 CB9F: 00 00 00 00 CBA3: 00 00 00 00 CBA7: 00 00 00 00 CBAB: 00 00 00 00 CBAF: 00 00 00 00 CBB3: 00 00 00 00 CBB7: 00 00 00 00 CBBB: 00 00 00 00 CBBF: 00 00 00 00 CBC3: 00 00 00 00 CBC7: 00 00 00 00 CBCB: 00 00 00 00 CBCF: 00 00 00 00 CBD3: 00 00 00 00 CBD7: 00 00 00 00 CBDB: 00 00 00 00 CBDF: 00 00 00 00 CBE3: 00 00 00 00 CBE7: 00 00 00 00 CBEB: 00 00 00 00 CBEF: 00 00 00 00 CBF3: 00 00 00 00 CBF7: 00 00 00 00 CBFB: 00 00 00 00 CBFF: 00 00 00 00 CC03: 00 00 00 00 CC07: 00 00 00 00 CC0B: 00 00 00 00 CC0F: 00 00 00 00 CC13: 00 00 00 00 CC17: 00 00 00 00 CC1B: 00 00 00 00 CC1F: 00 00 00 00 CC23: 00 00 00 00 CC27: 00 00 00 00 CC2B: 00 00 00 00 CC2F: 00 00 00 00 CC33: 00 00 00 00 CC37: 00 00 00 00 CC3B: 00 00 00 00 CC3F: 00 00 00 00 CC43: 00 00 00 00 CC47: 00 00 00 00 CC4B: 00 00 00 00 CC4F: 00 00 00 00 CC53: 00 00 00 00 CC57: 00 00 00 00 CC5B: 00 00 00 00 CC5F: 00 00 00 00 CC63: 00 00 00 00 CC67: 00 00 00 00 CC6B: 00 00 00 00 CC6F: 00 00 00 00 CC73: 00 00 00 00 CC77: 00 00 00 00 CC7B: 00 00 00 00 CC7F: 00 00 00 00 CC83: 00 00 00 00 CC87: 00 00 00 00 CC8B: 00 00 00 00 CC8F: 00 00 00 00 CC93: 00 00 00 00 CC97: 00 00 00 00 CC9B: 00 00 00 00 CC9F: 00 00 00 00 CCA3: 00 00 00 00 CCA7: 00 00 00 00 CCAB: 00 00 00 00 CCAF: 00 00 00 00 CCB3: 00 00 00 00 CCB7: 00 00 00 00 CCBB: 00 00 00 00 CCBF: 00 00 00 00 CCC3: 00 00 00 00 CCC7: 00 00 00 00 CCCB: 00 00 00 00 CCCF: 00 00 00 00 CCD3: 00 00 00 00 CCD7: 00 00 00 00 CCDB: 00 00 00 00 CCDF: 00 00 00 00 CCE3: 00 00 00 00 CCE7: 00 00 00 00 CCEB: 00 00 00 00 CCEF: 00 00 00 00 CCF3: 00 00 00 00 CCF7: 00 00 00 00 CCFB: 00 00 00 00 CCFF: 00 00 00 00 CD03: 00 00 00 00 CD07: 00 00 00 00 CD0B: 00 00 00 00 CD0F: 00 00 00 00 CD13: 00 00 00 00 CD17: 00 00 00 00 CD1B: 00 00 00 00 CD1F: 00 00 00 00 CD23: 00 00 00 00 CD27: 00 00 00 00 CD2B: 00 00 00 00 CD2F: 00 00 00 00 CD33: 00 00 00 00 CD37: 00 00 00 00 CD3B: 00 00 00 00 CD3F: 00 00 00 00 CD43: 00 00 00 00 CD47: 00 00 00 00 CD4B: 00 00 00 00 CD4F: 00 00 00 00 CD53: 00 00 00 00 CD57: 00 00 00 00 CD5B: 00 00 00 00 CD5F: 00 00 00 00 CD63: 00 00 00 00 CD67: 00 00 00 00 CD6B: 00 00 00 00 CD6F: 00 00 00 00 CD73: 00 00 00 00 CD77: 00 00 00 00 CD7B: 00 00 00 00 CD7F: 00 00 00 00 CD83: 00 00 00 00 CD87: 00 00 00 00 CD8B: 00 00 00 00 CD8F: 00 00 00 00 CD93: 00 00 00 00 CD97: 00 00 00 00 CD9B: 00 00 00 00 CD9F: 00 00 00 00 CDA3: 00 00 00 00 CDA7: 00 00 00 00 CDAB: 00 00 00 00 CDAF: 00 00 00 00 CDB3: 00 00 00 00 CDB7: 00 00 00 00 CDBB: 00 00 00 00 CDBF: 00 00 00 00 CDC3: 00 00 00 00 CDC7: 00 00 00 00 CDCB: 00 00 00 00 CDCF: 00 00 00 00 CDD3: 00 00 00 00 CDD7: 00 00 00 00 CDDB: 00 00 00 00 CDDF: 00 00 00 00 CDE3: 00 00 00 00 CDE7: 00 00 00 00 CDEB: 00 00 00 00 CDEF: 00 00 00 00 CDF3: 00 00 00 00 CDF7: 00 00 00 00 CDFB: 00 00 00 00 CDFF: 00 00 00 00 CE03: 00 00 00 00 CE07: 00 00 00 00 CE0B: 00 00 00 00 CE0F: 00 00 00 00 CE13: 00 00 00 00 CE17: 00 00 00 00 CE1B: 00 00 00 00 CE1F: 00 00 00 00 CE23: 00 00 00 00 CE27: 00 00 00 00 CE2B: 00 00 00 00 CE2F: 00 00 00 00 CE33: 00 00 00 00 CE37: 00 00 00 00 CE3B: 00 00 00 00 CE3F: 00 00 00 00 CE43: 00 00 00 00 CE47: 00 00 00 00 CE4B: 00 00 00 00 CE4F: 00 00 00 00 CE53: 00 00 00 00 CE57: 00 00 00 00 CE5B: 00 00 00 00 CE5F: 00 00 00 00 CE63: 00 00 00 00 CE67: 00 00 00 00 CE6B: 00 00 00 00 CE6F: 00 00 00 00 CE73: 00 00 00 00 CE77: 00 00 00 00 CE7B: 00 00 00 00 CE7F: 00 00 00 00 CE83: 00 00 00 00 CE87: 00 00 00 00 CE8B: 00 00 00 00 CE8F: 00 00 00 00 CE93: 00 00 00 00 CE97: 00 00 00 00 CE9B: 00 00 00 00 CE9F: 00 00 00 00 CEA3: 00 00 00 00 CEA7: 00 00 00 00 CEAB: 00 00 00 00 CEAF: 00 00 00 00 CEB3: 00 00 00 00 CEB7: 00 00 00 00 CEBB: 00 00 00 00 CEBF: 00 00 00 00 CEC3: 00 00 00 00 CEC7: 00 00 00 00 CECB: 00 00 00 00 CECF: 00 00 00 00 CED3: 00 00 00 00 CED7: 00 00 00 00 CEDB: 00 00 00 00 CEDF: 00 00 00 00 CEE3: 00 00 00 00 CEE7: 00 00 00 00 CEEB: 00 00 00 00 CEEF: 00 00 00 00 CEF3: 00 00 00 00 CEF7: 00 00 00 00 CEFB: 00 00 00 00 CEFF: 00 689 ERR *-1/$CF00 ; must be at $CF00 690 FIN 691 692 * signature bytes 693 CF00: A2 20 694 START LDX #$20 CF02: A0 00 695 LDY #$00 CF04: A2 03 696 LDX #$03 CF06: A0 FF 697 LDY #$FF ; neither 5.25 nor Smartport 698 699 * find slot nr 700 701 DO DEBUG 702 LDA #$04 703 STA SLOT 704 LDA #$C4 705 STA CURSLOT 706 LDA #$40 707 708 ELSE CF08: 20 58 FF 709 JSR $FF58 CF0B: BA 710 TSX CF0C: BD 00 01 711 LDA $0100,X CF0F: 8D F8 07 712 STA CURSLOT ; $Cs CF12: 29 0F 713 AND #$0F CF14: 85 3D 714 STA SLOT ; $0s CF16: 0A 715 ASL A CF17: 0A 716 ASL A CF18: 0A 717 ASL A CF19: 0A 718 ASL A 719 FIN 720 CF1A: 85 2B 721 STA SLOT16 ; $s0 CF1C: AA 722 TAX ; X holds now SLOT16 CF1D: 2C FF CF 723 BIT $CFFF CF20: 20 AE C9 724 JSR CARDDET CF23: 90 03 725 BCC :INIT CF25: A9 27 726 LDA #$27 ; no card inserted CF27: 00 727 BRK 728 CF28: 20 00 C8 729 :INIT JSR INIT 730 731 732 ******************************** 733 * 734 * Install SD card driver 735 * 736 ******************************** 737 738 DO DEBUG 739 740 * see if slot has a driver already 741 742 LDX $BF31 ; get devcnt 743 INSTALL LDA $BF32,X ; get a devnum 744 AND #$70 ; isolate slot 745 CMP SLOT16 ; slot? 746 BEQ :INSOUT ; yes, skip it 747 DEX 748 BPL INSTALL ; keep up the search 749 750 * restore the devnum to the list 751 752 LDX $BF31 ; get devcnt again 753 CPX #$0D ; device table full? 754 BNE :INST2 755 756 JSR $FF3A ; bell 757 JMP :INSOUT ; do something! 758 759 :INST2 LDA $BF32-1,X ; move all entries down 760 STA $BF32,X ; to make room at front 761 DEX ; for a new entry 762 BNE :INST2 763 LDA #$04 ; ProFile type device 764 ORA SLOT16 765 STA $BF32 ; slot, drive 1 at top of list 766 INC $BF31 ; update devcnt 767 768 * now insert the device driver vector 769 770 LDA SLOT 771 ASL 772 TAX 773 LDA #DRIVER 776 STA $BF11,X 777 :INSOUT RTS 778 779 780 ******************************** 781 * 782 * Boot from SD card 783 * 784 ******************************** 785 786 ELSE 787 CF2B: C9 00 788 BOOT CMP #0 ; check for error CF2D: F0 01 789 BEQ :BOOT1 CF2F: 00 790 BRK 791 CF30: A9 01 792 :BOOT1 LDA #$01 CF32: 85 42 793 STA DCMD ; load command CF34: A6 2B 794 LDX SLOT16 CF36: 85 43 795 STA $43 ; slot number CF38: 64 44 796 STZ BUFFER ; buffer lo CF3A: A9 08 797 LDA #$08 CF3C: 85 45 798 STA BUFFER+1 ; buffer hi CF3E: 64 46 799 STZ BLOCK ; block lo CF40: 64 47 800 STZ BLOCK+1 ; block hi CF42: 2C FF CF 801 BIT $CFFF CF45: 20 DD C9 802 JSR READ ; call driver CF48: 4C 01 08 803 JMP $801 ; goto bootloader 804 805 FIN 806 807 808 ******************************** 809 * 810 * Jump table 811 * 812 ******************************** 813 CF4B: D8 814 DRIVER CLD 815 816 DO DEBUG 817 LDA #$04 818 STA SLOT 819 LDA #$C4 820 STA CURSLOT 821 LDA #$40 822 823 ELSE CF4C: 20 58 FF 824 JSR $FF58 ; find slot nr CF4F: BA 825 TSX CF50: BD 00 01 826 LDA $0100,X CF53: 8D F8 07 827 STA CURSLOT ; $Cs CF56: 29 0F 828 AND #$0F CF58: 85 3D 829 STA SLOT ; $0s CF5A: 0A 830 ASL A CF5B: 0A 831 ASL A CF5C: 0A 832 ASL A CF5D: 0A 833 ASL A 834 FIN 835 CF5E: 85 2B 836 STA SLOT16 ; $s0 CF60: AA 837 TAX ; X holds now SLOT16 CF61: 2C FF CF 838 BIT $CFFF CF64: 20 AE C9 839 JSR CARDDET CF67: 90 04 840 BCC :INITED CF69: A9 27 841 LDA #$27 ; no card inserted CF6B: 80 1B 842 BRA :DONE 843 CF6D: A9 80 844 :INITED LDA #INITED ; check for init CF6F: 3C 83 C0 845 BIT SS,X CF72: F0 22 846 BEQ :INIT 847 CF74: A5 42 848 :CMD LDA DCMD ; get command CF76: C9 00 849 CMP #0 CF78: F0 10 850 BEQ :STATUS CF7A: C9 01 851 CMP #1 CF7C: F0 0F 852 BEQ :READ CF7E: C9 02 853 CMP #2 CF80: F0 0E 854 BEQ :WRITE CF82: C9 03 855 CMP #3 CF84: F0 0D 856 BEQ :FORMAT 857 DO DEBUG 858 CMP #$FF 859 BEQ :TEST 860 FIN CF86: A9 01 861 LDA #1 ; unknown command 862 CF88: 38 863 :DONE SEC CF89: 60 864 RTS 865 CF8A: 4C C6 C9 866 :STATUS JMP STATUS CF8D: 4C DD C9 867 :READ JMP READ CF90: 4C 4B CA 868 :WRITE JMP WRITE CF93: 4C C1 CA 869 :FORMAT JMP FORMAT CF96: 20 00 C8 870 :INIT JSR INIT CF99: B0 ED 871 BCS :DONE ; init failure CF9B: 80 D7 872 BRA :CMD 873 874 DO DEBUG 875 :TEST JMP TEST ; do device test 876 FIN 877 878 879 * Signature bytes 880 CF9D: 00 00 00 881 DS \ ; fill with zeroes CFA0: 00 00 00 00 CFA4: 00 00 00 00 CFA8: 00 00 00 00 CFAC: 00 00 00 00 CFB0: 00 00 00 00 CFB4: 00 00 00 00 CFB8: 00 00 00 00 CFBC: 00 00 00 00 CFC0: 00 00 00 00 CFC4: 00 00 00 00 CFC8: 00 00 00 00 CFCC: 00 00 00 00 CFD0: 00 00 00 00 CFD4: 00 00 00 00 CFD8: 00 00 00 00 CFDC: 00 00 00 00 CFE0: 00 00 00 00 CFE4: 00 00 00 00 CFE8: 00 00 00 00 CFEC: 00 00 00 00 CFF0: 00 00 00 00 CFF4: 00 00 00 00 CFF8: 00 00 00 00 CFFC: 00 00 00 00 882 DS -4 ; locate to $xxFC CFFC: FF FF 883 DW $FFFF ; 65535 blocks CFFE: 17 884 DB $17 ; Status bits CFFF: 4B 885 DB #