1 ******************************** 2 * 3 * Apple][Sd Firmware 4 * Version 0.8 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 1-NOV-17 16:06 14 15 XC ; enable 65C02 code 16 DEBUG = 0 17 DO DEBUG 18 ORG $8000 19 ELSE 20 ORG $C700 ; Expansion ROM 21 FIN 22 23 * Memory defines 24 25 SLOT16 = $2B ; $s0 -> slot * 16 26 SLOT = $3D ; $0s 27 CMDLO = $40 28 CMDHI = $41 29 30 DCMD = $42 ; Command code 31 BUFFER = $44 ; Buffer address 32 BLOCK = $46 ; Block number 33 34 CURSLOT = $07F8 ; $Cs 35 DATA = $C080 36 CTRL = DATA+1 37 DIV = DATA+2 38 SS = DATA+3 39 R30 = $0478 40 R31 = $04F8 41 R32 = $0578 42 R33 = $05F8 43 44 * Constants 45 46 DUMMY = $FF 47 FRX = $10 ; CTRL register 48 ECE = $04 49 SS0 = $01 ; SS register 50 WP = $20 51 CD = $40 52 INITED = $80 53 54 55 * signature bytes 56 C700: A2 20 57 LDX #$20 C702: A0 00 58 LDY #$00 C704: A2 03 59 LDX #$03 C706: A0 FF 60 LDY #$FF ; neither 5.25 nor Smartport 61 62 * find slot nr 63 64 DO DEBUG 65 LDA #$04 66 STA SLOT 67 LDA #$C4 68 STA CURSLOT 69 LDA #$40 70 71 ELSE C708: 20 58 FF 72 JSR $FF58 C70B: BA 73 TSX C70C: BD 00 01 74 LDA $0100,X C70F: 8D F8 07 75 STA CURSLOT ; $Cs C712: 29 0F 76 AND #$0F C714: 85 3D 77 STA SLOT ; $0s C716: 0A 78 ASL A C717: 0A 79 ASL A C718: 0A 80 ASL A C719: 0A 81 ASL A 82 FIN 83 C71A: 85 2B 84 STA SLOT16 ; $s0 C71C: AA 85 TAX ; X holds now SLOT16 C71D: 2C FF CF 86 BIT $CFFF C720: 20 A7 C9 87 JSR CARDDET C723: 90 03 88 BCC :INIT C725: A9 2F 89 LDA #$2F ; no card inserted C727: 00 90 BRK 91 C728: 20 00 C8 92 :INIT JSR INIT 93 94 95 ******************************** 96 * 97 * Install SD card driver 98 * 99 ******************************** 100 101 DO DEBUG 102 103 * see if slot has a driver already 104 105 LDX $BF31 ; get devcnt 106 INSTALL LDA $BF32,X ; get a devnum 107 AND #$70 ; isolate slot 108 CMP SLOT16 ; slot? 109 BEQ :INSOUT ; yes, skip it 110 DEX 111 BPL INSTALL ; keep up the search 112 113 * restore the devnum to the list 114 115 LDX $BF31 ; get devcnt again 116 CPX #$0D ; device table full? 117 BNE :INST2 118 119 JSR $FF3A ; bell 120 JMP :INSOUT ; do something! 121 122 :INST2 LDA $BF32-1,X ; move all entries down 123 STA $BF32,X ; to make room at front 124 DEX ; for a new entry 125 BNE :INST2 126 LDA #$04 ; ProFile type device 127 ORA SLOT16 128 STA $BF32 ; slot, drive 1 at top of list 129 INC $BF31 ; update devcnt 130 131 * now insert the device driver vector 132 133 LDA SLOT 134 ASL 135 TAX 136 LDA #DRIVER 139 STA $BF11,X 140 :INSOUT RTS 141 142 143 ******************************** 144 * 145 * Boot from SD card 146 * 147 ******************************** 148 149 ELSE 150 C72B: F0 01 151 BOOT BEQ :BOOT1 ; check for error C72D: 00 152 BRK 153 C72E: A9 01 154 :BOOT1 LDA #$01 C730: 85 42 155 STA DCMD ; load command C732: A6 2B 156 LDX SLOT16 C734: 85 43 157 STA $43 ; slot number C736: A9 08 158 LDA #$08 C738: 85 45 159 STA BUFFER+1 ; buffer hi C73A: 64 44 160 STZ BUFFER ; buffer lo C73C: 64 47 161 STZ BLOCK+1 ; block hi C73E: 64 46 162 STZ BLOCK ; block lo C740: 2C FF CF 163 BIT $CFFF C743: 20 CD C9 164 JSR READ ; call driver C746: 4C 01 08 165 JMP $801 ; goto bootloader 166 167 FIN 168 169 170 ******************************** 171 * 172 * Jump table 173 * 174 ******************************** 175 C749: D8 176 DRIVER CLD 177 C74A: 48 178 :SAVEZP PHA ; make room for retval C74B: A5 2B 179 LDA SLOT16 ; save all ZP locations C74D: 48 180 PHA C74E: A5 3D 181 LDA SLOT C750: 48 182 PHA C751: A5 40 183 LDA CMDLO C753: 48 184 PHA C754: A5 41 185 LDA CMDHI C756: 48 186 PHA 187 188 DO DEBUG 189 LDA #$04 190 STA SLOT 191 LDA #$C4 192 STA CURSLOT 193 LDA #$40 194 195 ELSE C757: 20 58 FF 196 JSR $FF58 ; find slot nr C75A: BA 197 TSX C75B: BD 00 01 198 LDA $0100,X C75E: 8D F8 07 199 STA CURSLOT ; $Cs C761: 29 0F 200 AND #$0F C763: 85 3D 201 STA SLOT ; $0s C765: 0A 202 ASL A C766: 0A 203 ASL A C767: 0A 204 ASL A C768: 0A 205 ASL A 206 FIN 207 C769: 85 2B 208 STA SLOT16 ; $s0 C76B: AA 209 TAX ; X holds now SLOT16 C76C: 2C FF CF 210 BIT $CFFF C76F: 20 A7 C9 211 JSR CARDDET C772: 90 05 212 BCC :INITED C774: A9 2F 213 LDA #$2F ; no card inserted C776: 38 214 SEC C777: 80 40 215 BRA :RESTZP 216 C779: A9 80 217 :INITED LDA #INITED ; check for init C77B: 3C 83 C0 218 BIT SS,X C77E: F0 34 219 BEQ :INIT 220 C780: A5 42 221 :CMD LDA DCMD ; get command C782: C9 00 222 CMP #0 C784: F0 15 223 BEQ :STATUS C786: C9 01 224 CMP #1 C788: F0 16 225 BEQ :READ C78A: C9 02 226 CMP #2 C78C: F0 17 227 BEQ :WRITE C78E: C9 03 228 CMP #3 C790: F0 18 229 BEQ :FORMAT C792: C9 FF 230 CMP #$FF C794: F0 19 231 BEQ :TEST C796: A9 01 232 LDA #1 ; unknown command C798: 38 233 SEC C799: 80 1E 234 BRA :RESTZP 235 C79B: 20 BF C9 236 :STATUS JSR STATUS C79E: 80 19 237 BRA :RESTZP C7A0: 20 CD C9 238 :READ JSR READ C7A3: 80 14 239 BRA :RESTZP C7A5: 20 34 CA 240 :WRITE JSR WRITE C7A8: 80 0F 241 BRA :RESTZP C7AA: 20 A3 CA 242 :FORMAT JSR FORMAT C7AD: 80 0A 243 BRA :RESTZP C7AF: 20 A7 CA 244 :TEST JSR TEST ; do device test C7B2: 80 05 245 BRA :RESTZP C7B4: 20 00 C8 246 :INIT JSR INIT C7B7: 90 C7 247 BCC :CMD ; init ok 248 C7B9: BA 249 :RESTZP TSX C7BA: 9D 05 01 250 STA $105,X ; save retval on stack C7BD: 68 251 PLA ; restore all ZP locations C7BE: 85 41 252 STA CMDHI C7C0: 68 253 PLA C7C1: 85 40 254 STA CMDLO C7C3: 68 255 PLA C7C4: 85 3D 256 STA SLOT C7C6: 68 257 PLA C7C7: 85 2B 258 STA SLOT16 C7C9: 68 259 PLA ; get retval C7CA: 60 260 RTS 261 262 263 * Signature bytes 264 C7CB: 00 00 00 265 DS \ ; fill with zeroes C7CE: 00 00 00 00 C7D2: 00 00 00 00 C7D6: 00 00 00 00 C7DA: 00 00 00 00 C7DE: 00 00 00 00 C7E2: 00 00 00 00 C7E6: 00 00 00 00 C7EA: 00 00 00 00 C7EE: 00 00 00 00 C7F2: 00 00 00 00 C7F6: 00 00 00 00 C7FA: 00 00 00 00 C7FE: 00 00 266 DS -4 ; locate to $xxFC C7FC: FF FF 267 DW $FFFF ; 65535 blocks C7FE: 17 268 DB $17 ; Status bits C7FF: 49 269 DB #CMD0 C830: 85 41 306 STA CMDHI C832: 20 EB C8 307 JSR SDCMD C835: 20 FF C8 308 JSR GETR1 ; get response C838: C9 01 309 CMP #$01 C83A: D0 39 310 BNE :ERROR1 ; error! 311 C83C: A9 0B 312 LDA #CMD8 C842: 85 41 315 STA CMDHI C844: 20 EB C8 316 JSR SDCMD C847: 20 18 C9 317 JSR GETR3 C84A: C9 01 318 CMP #$01 C84C: D0 2A 319 BNE :SDV1 ; may be SD Ver. 1 320 321 * check for $01aa match! C84E: A9 17 322 :SDV2 LDA #CMD55 C854: 85 41 325 STA CMDHI C856: 20 EB C8 326 JSR SDCMD C859: 20 FF C8 327 JSR GETR1 C85C: A9 1D 328 LDA #ACMD4140 C862: 85 41 331 STA CMDHI C864: 20 EB C8 332 JSR SDCMD C867: 20 FF C8 333 JSR GETR1 C86A: C9 01 334 CMP #$01 C86C: F0 E0 335 BEQ :SDV2 ; wait for ready C86E: C9 00 336 CMP #0 C870: D0 03 337 BNE :ERROR1 ; error! 338 * send CMD58 339 * SD Ver. 2 initialized! C872: 4C B2 C8 340 JMP :BLOCKSZ 341 C875: 4C D9 C8 342 :ERROR1 JMP :IOERROR ; needed for far jump 343 C878: A9 17 344 :SDV1 LDA #CMD55 C87E: 85 41 347 STA CMDHI C880: 20 EB C8 348 JSR SDCMD ; ignore response C883: A9 23 349 LDA #ACMD410 C889: 85 41 352 STA CMDHI C88B: 20 EB C8 353 JSR SDCMD C88E: 20 FF C8 354 JSR GETR1 C891: C9 01 355 CMP #$01 C893: F0 E3 356 BEQ :SDV1 ; wait for ready C895: C9 00 357 CMP #0 C897: D0 03 358 BNE :MMC ; may be MMC card 359 * SD Ver. 1 initialized! C899: 4C B2 C8 360 JMP :BLOCKSZ 361 C89C: A9 05 362 :MMC LDA #CMD1 C8A2: 85 41 365 STA CMDHI C8A4: 20 EB C8 366 :LOOP1 JSR SDCMD C8A7: 20 FF C8 367 JSR GETR1 C8AA: C9 01 368 CMP #$01 C8AC: F0 F6 369 BEQ :LOOP1 ; wait for ready C8AE: C9 00 370 CMP #0 C8B0: D0 27 371 BNE :IOERROR ; error! 372 * MMC Ver. 3 initialized! 373 C8B2: A9 11 374 :BLOCKSZ LDA #CMD16 C8B8: 85 41 377 STA CMDHI C8BA: 20 EB C8 378 JSR SDCMD C8BD: 20 FF C8 379 JSR GETR1 C8C0: C9 00 380 CMP #0 C8C2: D0 15 381 BNE :IOERROR ; error! 382 C8C4: BD 83 C0 383 :END LDA SS,X C8C7: 09 80 384 ORA #INITED ; initialized C8C9: 9D 83 C0 385 STA SS,X C8CC: BD 81 C0 386 LDA CTRL,X C8CF: 09 04 387 ORA #ECE ; enable 7MHz C8D1: 9D 81 C0 388 STA CTRL,X C8D4: 18 389 CLC ; all ok C8D5: A0 00 390 LDY #0 C8D7: 90 03 391 BCC :END1 C8D9: 38 392 :IOERROR SEC C8DA: A0 27 393 LDY #$27 ; init error C8DC: BD 83 C0 394 :END1 LDA SS,X ; set CS high C8DF: 09 01 395 ORA #SS0 C8E1: 9D 83 C0 396 STA SS,X C8E4: A9 00 397 LDA #0 ; set div to 2 C8E6: 9D 82 C0 398 STA DIV,X C8E9: 98 399 TYA ; retval in A C8EA: 60 400 RTS 401 402 403 ******************************** 404 * 405 * Send SD command 406 * Call with command in CMDHI and CMDLO 407 * 408 ******************************** 409 C8EB: 5A 410 SDCMD PHY C8EC: A0 00 411 LDY #0 C8EE: B1 40 412 :LOOP LDA (CMDLO),Y C8F0: 9D 80 C0 413 STA DATA,X C8F3: 3C 81 C0 414 :WAIT BIT CTRL,X ; TC is in N C8F6: 10 FB 415 BPL :WAIT C8F8: C8 416 INY C8F9: C0 06 417 CPY #6 C8FB: 90 F1 418 BCC :LOOP C8FD: 7A 419 PLY C8FE: 60 420 RTS 421 422 423 ******************************** 424 * 425 * Get R1 426 * R1 is in A 427 * 428 ******************************** 429 C8FF: A9 FF 430 GETR1 LDA #DUMMY C901: 9D 80 C0 431 STA DATA,X C904: 3C 81 C0 432 :WAIT BIT CTRL,X C907: 10 FB 433 BPL :WAIT C909: BD 80 C0 434 LDA DATA,X ; get response C90C: 89 80 435 BIT #$80 C90E: D0 EF 436 BNE GETR1 ; wait for MSB=0 C910: 48 437 PHA C911: A9 FF 438 LDA #DUMMY C913: 9D 80 C0 439 STA DATA,X ; send another dummy C916: 68 440 PLA ; restore R1 C917: 60 441 RTS 442 443 ******************************** 444 * 445 * Get R3 446 * R1 is in A 447 * R3 is in scratchpad ram 448 * 449 ******************************** 450 C918: 20 FF C8 451 GETR3 JSR GETR1 ; get R1 first C91B: 48 452 PHA ; save R1 C91C: 5A 453 PHY ; save Y C91D: A0 04 454 LDY #04 ; load counter C91F: A9 FF 455 :LOOP LDA #DUMMY ; send dummy C921: 9D 80 C0 456 STA DATA,X C924: 3C 81 C0 457 :WAIT BIT CTRL,X C927: 10 FB 458 BPL :WAIT C929: BD 80 C0 459 LDA DATA,X C92C: 48 460 PHA C92D: 88 461 DEY C92E: D0 EF 462 BNE :LOOP ; do 4 times C930: A4 3D 463 LDY SLOT C932: 68 464 PLA C933: 99 F8 05 465 STA R33,Y ; save R3 C936: 68 466 PLA C937: 99 78 05 467 STA R32,Y C93A: 68 468 PLA C93B: 99 F8 04 469 STA R31,Y C93E: 68 470 PLA C93F: 99 78 04 471 STA R30,Y C942: 7A 472 PLY ; restore Y C943: A9 FF 473 LDA #DUMMY C945: 9D 80 C0 474 STA DATA,X ; send another dummy C948: 68 475 PLA ; restore R1 C949: 60 476 RTS 477 478 479 ******************************** 480 * 481 * Calculate block address 482 * Unit number is in $43 DSSS0000 483 * Block no is in $46-47 484 * Address is in R30-R33 485 * 486 ******************************** 487 C94A: DA 488 GETBLOCK PHX ; save X C94B: 5A 489 PHY ; save Y C94C: A6 3D 490 LDX SLOT C94E: A5 46 491 LDA BLOCK ; store block num C950: 9D F8 05 492 STA R33,X ; in R30-R33 C953: A5 47 493 LDA BLOCK+1 C955: 9D 78 05 494 STA R32,X C958: A9 00 495 LDA #0 C95A: 9D F8 04 496 STA R31,X C95D: 9D 78 04 497 STA R30,X 498 C960: A9 80 499 LDA #$80 ; drive number C962: 24 43 500 BIT $43 C964: F0 05 501 BEQ :SHIFT ; D1 C966: A9 01 502 LDA #1 ; D2 C968: 9D F8 04 503 STA R31,X 504 C96B: A0 09 505 :SHIFT LDY #9 ; ASL can't be used with Y C96D: 1E F8 05 506 :LOOP ASL R33,X ; mul block num C970: 3E 78 05 507 ROL R32,X ; by 512 to get C973: 3E F8 04 508 ROL R31,X ; real address C976: 3E 78 04 509 ROL R30,X C979: 88 510 DEY C97A: D0 F1 511 BNE :LOOP C97C: 7A 512 PLY ; restore Y C97D: FA 513 PLX ; restore X C97E: 60 514 RTS 515 516 517 ******************************** 518 * 519 * Send SD command 520 * Cmd is in A 521 * 522 ******************************** 523 C97F: 5A 524 COMMAND PHY ; save Y C980: A4 3D 525 LDY SLOT C982: 9D 80 C0 526 STA DATA,X ; send command C985: B9 78 04 527 LDA R30,Y ; get arg from R30 on C988: 9D 80 C0 528 STA DATA,X C98B: B9 F8 04 529 LDA R31,Y C98E: 9D 80 C0 530 STA DATA,X C991: B9 78 05 531 LDA R32,Y C994: 9D 80 C0 532 STA DATA,X C997: B9 F8 05 533 LDA R33,Y C99A: 9D 80 C0 534 STA DATA,X C99D: A9 FF 535 LDA #DUMMY C99F: 9D 80 C0 536 STA DATA,X ; dummy crc C9A2: 20 FF C8 537 JSR GETR1 C9A5: 7A 538 PLY ; restore Y C9A6: 60 539 RTS 540 541 542 ******************************** 543 * 544 * Check for card detect 545 * 546 * C Clear - card in slot 547 * Set - no card in slot 548 * 549 ******************************** 550 C9A7: 48 551 CARDDET PHA C9A8: A9 40 552 LDA #CD ; 0: card in C9AA: 3C 83 C0 553 BIT SS,X ; 1: card out C9AD: 18 554 CLC C9AE: F0 01 555 BEQ :DONE ; card is in C9B0: 38 556 SEC ; card is out C9B1: 68 557 :DONE PLA C9B2: 60 558 RTS 559 560 561 ******************************** 562 * 563 * Check for write protect 564 * 565 * C Clear - card not protected 566 * Set - card write protected 567 * 568 ******************************** 569 C9B3: 48 570 WRPROT PHA C9B4: A9 20 571 LDA #WP ; 0: write enabled C9B6: 3C 83 C0 572 BIT SS,X ; 1: write disabled C9B9: 18 573 CLC C9BA: F0 01 574 BEQ :DONE C9BC: 38 575 SEC C9BD: 68 576 :DONE PLA C9BE: 60 577 RTS 578 579 580 ******************************** 581 * 582 * Status request 583 * $43 Unit number DSSS000 584 * $44-45 Unused 585 * $46-47 Unused 586 * 587 * C Clear - No error 588 * Set - Error 589 * A $00 - No error 590 * $2B - Card write protected 591 * $2F - No card inserted 592 * X - Blocks avail (low byte) 593 * Y - Blocks avail (high byte) 594 * 595 ******************************** 596 C9BF: A9 00 597 STATUS LDA #0 ; no error C9C1: A2 FF 598 LDX #$FF ; 32 MB partition C9C3: A0 FF 599 LDY #$FF 600 C9C5: 20 B3 C9 601 JSR WRPROT C9C8: 90 02 602 BCC :DONE C9CA: A9 2B 603 LDA #$2B ; card write protected 604 C9CC: 60 605 :DONE RTS 606 607 608 ******************************** 609 * 610 * Read 512 byte block 611 * $43 Unit number DSSS0000 612 * $44-45 Address (LO/HI) of buffer 613 * $46-47 Block number (LO/HI) 614 * 615 * C Clear - No error 616 * Set - Error 617 * A $00 - No error 618 * $27 - Bad block number 619 * 620 ******************************** 621 C9CD: 20 4A C9 622 READ JSR GETBLOCK ; calc block address 623 C9D0: BD 83 C0 624 LDA SS,X ; enable /CS C9D3: 29 FE 625 AND #$FF!SS0 C9D5: 9D 83 C0 626 STA SS,X C9D8: A9 51 627 LDA #$51 ; send CMD17 C9DA: 20 7F C9 628 JSR COMMAND ; send command C9DD: D0 50 629 BNE :ERROR ; check for error 630 C9DF: A9 FF 631 :GETTOK LDA #DUMMY ; get data token C9E1: 9D 80 C0 632 STA DATA,X C9E4: BD 80 C0 633 LDA DATA,X ; get response C9E7: C9 FE 634 CMP #$FE C9E9: D0 F4 635 BNE :GETTOK ; wait for $FE 636 C9EB: BD 81 C0 637 LDA CTRL,X ; enable FRX C9EE: 09 10 638 ORA #FRX C9F0: 9D 81 C0 639 STA CTRL,X C9F3: A9 FF 640 LDA #DUMMY C9F5: 9D 80 C0 641 STA DATA,X 642 C9F8: A0 00 643 LDY #0 C9FA: BD 80 C0 644 :LOOP1 LDA DATA,X ; read data from card C9FD: 91 44 645 STA (BUFFER),Y C9FF: C8 646 INY CA00: D0 F8 647 BNE :LOOP1 CA02: E6 45 648 INC BUFFER+1 ; inc msb on page boundary CA04: BD 80 C0 649 :LOOP2 LDA DATA,X CA07: 91 44 650 STA (BUFFER),Y CA09: C8 651 INY CA0A: D0 F8 652 BNE :LOOP2 CA0C: C6 45 653 DEC BUFFER+1 654 CA0E: BD 80 C0 655 :CRC LDA DATA,X ; read two bytes crc CA11: BD 80 C0 656 LDA DATA,X ; and ignore CA14: BD 80 C0 657 LDA DATA,X ; read a dummy byte 658 CA17: BD 81 C0 659 LDA CTRL,X ; disable FRX CA1A: 29 EF 660 AND #$FF!FRX CA1C: 9D 81 C0 661 STA CTRL,X CA1F: 18 662 CLC ; no error CA20: A9 00 663 LDA #0 664 CA22: 08 665 :DONE PHP CA23: 48 666 PHA CA24: BD 83 C0 667 LDA SS,X CA27: 09 01 668 ORA #SS0 CA29: 9D 83 C0 669 STA SS,X ; disable /CS CA2C: 68 670 PLA CA2D: 28 671 PLP CA2E: 60 672 RTS 673 CA2F: 38 674 :ERROR SEC ; an error occured CA30: A9 27 675 LDA #$27 CA32: 80 EE 676 BRA :DONE 677 678 679 ******************************** 680 * 681 * Write 512 byte block 682 * $43 Unit number DSSS0000 683 * $44-45 Address (LO/HI) of buffer 684 * $46-47 Block number (LO/HI) 685 * 686 * C Clear - No error 687 * Set - Error 688 * A $00 - No error 689 * $27 - I/O error or bad block number 690 * $2B - Card write protected 691 * 692 ******************************** 693 CA34: 20 B3 C9 694 WRITE JSR WRPROT CA37: B0 65 695 BCS :WPERROR ; card write protected 696 CA39: 20 4A C9 697 JSR GETBLOCK ; calc block address 698 CA3C: BD 83 C0 699 LDA SS,X ; enable /CS CA3F: 29 FE 700 AND #$FF!SS0 CA41: 9D 83 C0 701 STA SS,X CA44: A9 58 702 LDA #$58 ; send CMD24 CA46: 20 7F C9 703 JSR COMMAND ; send command CA49: D0 4E 704 BNE :IOERROR ; check for error 705 CA4B: A9 FF 706 LDA #DUMMY CA4D: 9D 80 C0 707 STA DATA,X ; send dummy CA50: A9 FE 708 LDA #$FE CA52: 9D 80 C0 709 STA DATA,X ; send data token 710 CA55: A0 00 711 LDY #0 CA57: B1 44 712 :LOOP1 LDA (BUFFER),Y CA59: 9D 80 C0 713 STA DATA,X : send data to card CA5C: C8 714 INY CA5D: D0 F8 715 BNE :LOOP1 CA5F: E6 45 716 INC BUFFER+1 : inc msb on page boundary CA61: B1 44 717 :LOOP2 LDA (BUFFER),Y CA63: 9D 80 C0 718 STA DATA,X CA66: C8 719 INY CA67: D0 F8 720 BNE :LOOP2 CA69: C6 45 721 DEC BUFFER+1 722 CA6B: A9 FF 723 :CRC LDA #DUMMY CA6D: 9D 80 C0 724 STA DATA,X ; send 2 dummy crc bytes CA70: 9D 80 C0 725 STA DATA,X 726 CA73: 9D 80 C0 727 STA DATA,X ; get data response CA76: BD 80 C0 728 LDA DATA,X CA79: 29 1F 729 AND #$1F CA7B: C9 05 730 CMP #$05 CA7D: D0 1A 731 BNE :IOERROR ; check for write error CA7F: 18 732 CLC ; no error CA80: A9 00 733 LDA #0 734 CA82: 08 735 :DONE PHP CA83: 48 736 PHA CA84: A9 FF 737 :WAIT LDA #DUMMY CA86: 9D 80 C0 738 STA DATA,X ; wait for write cycle CA89: BD 80 C0 739 LDA DATA,X ; to complete CA8C: F0 F6 740 BEQ :WAIT 741 CA8E: BD 83 C0 742 LDA SS,X ; disable /CS CA91: 09 01 743 ORA #SS0 CA93: 9D 83 C0 744 STA SS,X CA96: 68 745 PLA CA97: 28 746 PLP CA98: 60 747 RTS 748 CA99: 38 749 :IOERROR SEC ; an error occured CA9A: A9 27 750 LDA #$27 CA9C: 80 E4 751 BRA :DONE 752 CA9E: 38 753 :WPERROR SEC CA9F: A9 2B 754 LDA #$2B CAA1: 80 DF 755 BRA :DONE 756 757 758 759 ******************************** 760 * 761 * Format 762 * not supported! 763 * 764 ******************************** 765 CAA3: 38 766 FORMAT SEC CAA4: A9 01 767 LDA #$01 ; invalid command CAA6: 60 768 RTS 769 770 771 ******************************** 772 * 773 * Test routine 774 * 775 ******************************** 776 CAA7: A5 2B 777 TEST LDA SLOT16 CAA9: 48 778 PHA CAAA: A5 3D 779 LDA SLOT CAAC: 48 780 PHA 781 782 * get buffer CAAD: A9 02 783 LDA #2 ; get 512 byte buffer CAAF: 20 F5 BE 784 JSR $BEF5 ; call GETBUFR CAB2: B0 49 785 BCS :ERROR CAB4: 85 45 786 STA BUFFER+1 CAB6: 64 44 787 STZ BUFFER CAB8: 68 788 PLA CAB9: 85 3D 789 STA SLOT CABB: 68 790 PLA CABC: 85 2B 791 STA SLOT16 792 793 * fill buffer CABE: A0 00 794 LDY #0 CAC0: 98 795 :LOOP TYA CAC1: 91 44 796 STA (BUFFER),Y CAC3: C8 797 INY CAC4: D0 FA 798 BNE :LOOP CAC6: E6 45 799 INC BUFFER+1 CAC8: 98 800 :LOOP1 TYA CAC9: 91 44 801 STA (BUFFER),Y CACB: C8 802 INY CACC: D0 FA 803 BNE :LOOP1 CACE: C6 45 804 DEC BUFFER+1 805 CAD0: 64 46 806 STZ BLOCK ; block number CAD2: 64 47 807 STZ BLOCK+1 CAD4: A6 2B 808 LDX SLOT16 809 811 * write to card CAD6: 20 34 CA 812 JSR WRITE CAD9: B0 22 813 BCS :ERROR 814 815 * read from card CADB: 20 CD C9 816 JSR READ CADE: B0 1D 817 BCS :ERROR 818 819 * check for errors CAE0: A0 00 820 LDY #0 CAE2: 98 821 :LOOP2 TYA CAE3: D1 44 822 CMP (BUFFER),Y CAE5: D0 17 823 BNE :ERRCMP ; error in buffer CAE7: C8 824 INY CAE8: D0 F8 825 BNE :LOOP2 CAEA: E6 45 826 INC BUFFER+1 CAEC: 98 827 :LOOP3 TYA CAED: D1 44 828 CMP (BUFFER),Y CAEF: D0 0D 829 BNE :ERRCMP CAF1: C8 830 INY CAF2: D0 F8 831 BNE :LOOP3 CAF4: C6 45 832 DEC BUFFER+1 833 834 * free buffer CAF6: 20 F8 BE 835 JSR $BEF8 ; call FREEBUFR CAF9: 18 836 CLC CAFA: A9 00 837 LDA #0 CAFC: 60 838 RTS 839 CAFD: 00 840 :ERROR BRK CAFE: 00 841 :ERRCMP BRK 842 843 CAFF: 40 00 00 844 CMD0 HEX 400000 CB02: 00 00 95 845 HEX 000095 CB05: 41 00 00 846 CMD1 HEX 410000 CB08: 00 00 F9 847 HEX 0000F9 CB0B: 48 00 00 848 CMD8 HEX 480000 CB0E: 01 AA 87 849 HEX 01AA87 CB11: 50 00 00 850 CMD16 HEX 500000 CB14: 02 00 FF 851 HEX 0200FF CB17: 77 00 00 852 CMD55 HEX 770000 CB1A: 00 00 65 853 HEX 000065 CB1D: 69 40 00 854 ACMD4140 HEX 694000 CB20: 00 00 77 855 HEX 000077 CB23: 69 00 00 856 ACMD410 HEX 690000 CB26: 00 00 FF 857 HEX 0000FF --End assembly, 1065 bytes, Errors: 0 Symbol table - alphabetical order: ACMD410 =$CB23 ACMD4140=$CB1D BLOCK =$46 ? BOOT =$C72B BUFFER =$44 CARDDET =$C9A7 CD =$40 CMD0 =$CAFF CMD1 =$CB05 CMD16 =$CB11 CMD55 =$CB17 CMD8 =$CB0B CMDHI =$41 CMDLO =$40 COMMAND =$C97F CTRL =$C081 CURSLOT =$07F8 DATA =$C080 DCMD =$42 DEBUG =$00 DIV =$C082 DRIVER =$C749 DUMMY =$FF ECE =$04 FORMAT =$CAA3 FRX =$10 GETBLOCK=$C94A GETR1 =$C8FF GETR3 =$C918 INIT =$C800 INITED =$80 R30 =$0478 R31 =$04F8 R32 =$0578 R33 =$05F8 READ =$C9CD SDCMD =$C8EB SLOT =$3D SLOT16 =$2B SS =$C083 SS0 =$01 STATUS =$C9BF TEST =$CAA7 WP =$20 WRITE =$CA34 WRPROT =$C9B3 Symbol table - numerical order: DEBUG =$00 SS0 =$01 ECE =$04 FRX =$10 WP =$20 SLOT16 =$2B SLOT =$3D CMDLO =$40 CD =$40 CMDHI =$41 DCMD =$42 BUFFER =$44 BLOCK =$46 INITED =$80 DUMMY =$FF R30 =$0478 R31 =$04F8 R32 =$0578 R33 =$05F8 CURSLOT =$07F8 DATA =$C080 CTRL =$C081 DIV =$C082 SS =$C083 ? BOOT =$C72B DRIVER =$C749 INIT =$C800 SDCMD =$C8EB GETR1 =$C8FF GETR3 =$C918 GETBLOCK=$C94A COMMAND =$C97F CARDDET =$C9A7 WRPROT =$C9B3 STATUS =$C9BF READ =$C9CD WRITE =$CA34 FORMAT =$CAA3 TEST =$CAA7 CMD0 =$CAFF CMD1 =$CBΤΑ ΣΜΟΤ±Ά±Ωγλ ξυνβεςζζεςͺ =$CB11 CMD55 =$CB17 ACMD4140=$CB1D ACMD410 =$CB23 31 =$04F8 R32 =$0578 R33 =$05F8 RAM0 =$0678 RAM1 =$068 READ =$82CF SLOT =$3D SLOT16 =$2B S ΠΑՍ =$C083 SS0 =$01 STATUS =$82C1 TEST =$83AD WORK =$3C WP =$20 WRITE =$8338 WRPROT =$82B5 Symbol table - numerical order: DEBUG =$01 SS0 =$01 ECE =$04 FRX =$10 WP =$20 SLOT16 =$2B WORK =$3C SLOT =$3D CMDLO =$40 CD =$40 CMDHI =$41 DCMD =$42 BUFFER =$44 BLOCK =$46 INITED =$80 DUMMY =$FF R30 =$0478 R31 =$04F8 R32 =$0578 R33 =$05F8 RAM0 =$0678 RAM1 =$06F8 CURSLOT =$07F8 INSTALL =$8027 DRIVER =$8062 INIT =$8100 CMD =$81EB GETR1 =$81FF GETR3 =$821A GETBLOCK=$824C COMMAND =$8281 CARDDET =$82A9 WRPROT =$82B5 STATUS =$82C1 READ =$82CF WRITE =$8338 FORMAT =$83A9 TEST =$83AD CMD0 =$8431 CMD1 =$8437 CMD8 =$843D CMD16 =$8443 CMD55 =$8449 ACMD4140=$844F ACMD410 =$8455 DATA =$C080 CTRL =$C081 DIV =$C082 SS =$C083