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 22-OCT-17 20:21 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 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 RAM0 = $0678 45 RAM1 = $06F8 46 47 * Constants 48 49 DUMMY = $FF 50 FRX = $10 ; CTRL register 51 ECE = $04 52 SS0 = $01 ; SS register 53 WP = $20 54 CD = $40 55 INITED = $80 56 57 58 * signature bytes 59 C700: A2 20 60 LDX #$20 C702: A0 00 61 LDY #$00 C704: A2 03 62 LDX #$03 C706: A0 FF 63 LDY #$FF ; neither 5.25 nor Smartport 64 65 * find slot nr 66 67 DO DEBUG 68 LDA #$04 69 STA SLOT 70 LDA #$C4 71 STA CURSLOT 72 LDA #$40 73 74 ELSE C708: 20 58 FF 75 JSR $FF58 C70B: BA 76 TSX C70C: BD 00 01 77 LDA $0100,X C70F: 8D F8 07 78 STA CURSLOT ; $Cs C712: 29 0F 79 AND #$0F C714: 85 3D 80 STA SLOT ; $0s C716: 0A 81 ASL A C717: 0A 82 ASL A C718: 0A 83 ASL A C719: 0A 84 ASL A 85 FIN 86 C71A: 85 2B 87 STA SLOT16 ; $s0 C71C: AA 88 TAX ; X holds now SLOT16 C71D: 2C FF CF 89 BIT $CFFF C720: 20 A9 C9 90 JSR CARDDET C723: 90 03 91 BCC :INIT C725: A9 2F 92 LDA #$2F ; no card inserted C727: 00 93 BRK 94 C728: 20 00 C8 95 :INIT JSR INIT 96 97 98 ******************************** 99 * 100 * Install SD card driver 101 * 102 ******************************** 103 104 DO DEBUG 105 106 * see if slot has a driver already 107 108 LDX $BF31 ; get devcnt 109 INSTALL LDA $BF32,X ; get a devnum 110 AND #$70 ; isolate slot 111 CMP SLOT16 ; slot? 112 BEQ :INSOUT ; yes, skip it 113 DEX 114 BPL INSTALL ; keep up the search 115 116 * restore the devnum to the list 117 118 LDX $BF31 ; get devcnt again 119 CPX #$0D ; device table full? 120 BNE :INST2 121 122 JSR $FF3A ; bell 123 JMP :INSOUT ; do something! 124 125 :INST2 LDA $BF32-1,X ; move all entries down 126 STA $BF32,X ; to make room at front 127 DEX ; for a new entry 128 BNE :INST2 129 LDA #$04 ; ProFile type device 130 ORA SLOT16 131 STA $BF32 ; slot, drive 1 at top of list 132 INC $BF31 ; update devcnt 133 134 * now insert the device driver vector 135 136 LDA SLOT 137 ASL 138 TAX 139 LDA #DRIVER 142 STA $BF11,X 143 :INSOUT RTS 144 145 146 ******************************** 147 * 148 * Boot from SD card 149 * 150 ******************************** 151 152 ELSE 153 C72B: C9 00 154 BOOT CMP #0 ; check for error C72D: F0 01 155 BEQ :BOOT1 C72F: 00 156 BRK 157 C730: A9 01 158 :BOOT1 LDA #$01 C732: 85 42 159 STA DCMD ; load command C734: A6 2B 160 LDX SLOT16 C736: 85 43 161 STA $43 ; slot number C738: 64 44 162 STZ BUFFER ; buffer lo C73A: A9 08 163 LDA #$08 C73C: 85 45 164 STA BUFFER+1 ; buffer hi C73E: 64 46 165 STZ BLOCK ; block lo C740: 64 47 166 STZ BLOCK+1 ; block hi C742: 2C FF CF 167 BIT $CFFF C745: 20 CF C9 168 JSR READ ; call driver C748: 4C 01 08 169 JMP $801 ; goto bootloader 170 171 FIN 172 173 174 ******************************** 175 * 176 * Jump table 177 * 178 ******************************** 179 C74B: D8 180 DRIVER CLD 181 182 DO DEBUG 183 LDA #$04 184 STA SLOT 185 LDA #$C4 186 STA CURSLOT 187 LDA #$40 188 189 ELSE C74C: 20 58 FF 190 JSR $FF58 ; find slot nr C74F: BA 191 TSX C750: BD 00 01 192 LDA $0100,X C753: 8D F8 07 193 STA CURSLOT ; $Cs C756: 29 0F 194 AND #$0F C758: 85 3D 195 STA SLOT ; $0s C75A: 0A 196 ASL A C75B: 0A 197 ASL A C75C: 0A 198 ASL A C75D: 0A 199 ASL A 200 FIN 201 C75E: 85 2B 202 STA SLOT16 ; $s0 C760: AA 203 TAX ; X holds now SLOT16 C761: 2C FF CF 204 BIT $CFFF C764: 20 A9 C9 205 JSR CARDDET C767: 90 04 206 BCC :INITED C769: A9 2F 207 LDA #$2F ; no card inserted C76B: 80 1F 208 BRA :DONE 209 C76D: A9 80 210 :INITED LDA #INITED ; check for init C76F: 3C 83 C0 211 BIT SS,X C772: F0 29 212 BEQ :INIT 213 C774: A5 42 214 :CMD LDA DCMD ; get command C776: C9 00 215 CMP #0 C778: F0 14 216 BEQ :STATUS C77A: C9 01 217 CMP #1 C77C: F0 13 218 BEQ :READ C77E: C9 02 219 CMP #2 C780: F0 12 220 BEQ :WRITE C782: C9 03 221 CMP #3 C784: F0 11 222 BEQ :FORMAT C786: C9 FF 223 CMP #$FF C788: F0 10 224 BEQ :TEST C78A: A9 01 225 LDA #1 ; unknown command 226 C78C: 38 227 :DONE SEC C78D: 60 228 RTS 229 C78E: 4C C1 C9 230 :STATUS JMP STATUS C791: 4C CF C9 231 :READ JMP READ C794: 4C 38 CA 232 :WRITE JMP WRITE C797: 4C A9 CA 233 :FORMAT JMP FORMAT C79A: 4C AD CA 234 :TEST JMP TEST ; do device test C79D: 20 00 C8 235 :INIT JSR INIT C7A0: B0 EA 236 BCS :DONE ; init failure C7A2: 80 D0 237 BRA :CMD 238 239 240 * Signature bytes 241 C7A4: 00 00 00 242 DS \ ; fill with zeroes C7A7: 00 00 00 00 C7AB: 00 00 00 00 C7AF: 00 00 00 00 C7B3: 00 00 00 00 C7B7: 00 00 00 00 C7BB: 00 00 00 00 C7BF: 00 00 00 00 C7C3: 00 00 00 00 C7C7: 00 00 00 00 C7CB: 00 00 00 00 C7CF: 00 00 00 00 C7D3: 00 00 00 00 C7D7: 00 00 00 00 C7DB: 00 00 00 00 C7DF: 00 00 00 00 C7E3: 00 00 00 00 C7E7: 00 00 00 00 C7EB: 00 00 00 00 C7EF: 00 00 00 00 C7F3: 00 00 00 00 C7F7: 00 00 00 00 C7FB: 00 00 00 00 C7FF: 00 243 DS -4 ; locate to $xxFC C7FC: FF FF 244 DW $FFFF ; 65535 blocks C7FE: 17 245 DB $17 ; Status bits C7FF: 4B 246 DB #CMD0 C830: 85 41 283 STA CMDHI C832: 20 EB C8 284 JSR CMD C835: 20 FF C8 285 JSR GETR1 ; get response C838: C9 01 286 CMP #$01 C83A: D0 39 287 BNE :ERROR1 ; error! 288 C83C: A9 3D 289 LDA #CMD8 C842: 85 41 292 STA CMDHI C844: 20 EB C8 293 JSR CMD C847: 20 1A C9 294 JSR GETR3 C84A: C9 01 295 CMP #$01 C84C: D0 2A 296 BNE :SDV1 ; may be SD Ver. 1 297 298 * check for $01aa match! C84E: A9 49 299 :SDV2 LDA #CMD55 C854: 85 41 302 STA CMDHI C856: 20 EB C8 303 JSR CMD C859: 20 FF C8 304 JSR GETR1 C85C: A9 4F 305 LDA #ACMD4140 C862: 85 41 308 STA CMDHI C864: 20 EB C8 309 JSR CMD C867: 20 FF C8 310 JSR GETR1 C86A: C9 01 311 CMP #$01 C86C: F0 E0 312 BEQ :SDV2 ; wait for ready C86E: C9 00 313 CMP #$00 C870: D0 03 314 BNE :ERROR1 ; error! 315 * send CMD58 316 * SD Ver. 2 initialized! C872: 4C B2 C8 317 JMP :BLOCKSZ 318 C875: 4C D9 C8 319 :ERROR1 JMP :IOERROR ; needed for far jump 320 C878: A9 49 321 :SDV1 LDA #CMD55 C87E: 85 41 324 STA CMDHI C880: 20 EB C8 325 JSR CMD ; ignore response C883: A9 55 326 LDA #ACMD410 C889: 85 41 329 STA CMDHI C88B: 20 EB C8 330 JSR CMD C88E: 20 FF C8 331 JSR GETR1 C891: C9 01 332 CMP #$01 C893: F0 E3 333 BEQ :SDV1 ; wait for ready C895: C9 00 334 CMP #$00 C897: D0 03 335 BNE :MMC ; may be MMC card 336 * SD Ver. 1 initialized! C899: 4C B2 C8 337 JMP :BLOCKSZ 338 C89C: A9 37 339 :MMC LDA #CMD1 C8A2: 85 41 342 STA CMDHI C8A4: 20 EB C8 343 :LOOP1 JSR CMD C8A7: 20 FF C8 344 JSR GETR1 C8AA: C9 01 345 CMP #$01 C8AC: F0 F6 346 BEQ :LOOP1 ; wait for ready C8AE: C9 00 347 CMP #$00 C8B0: D0 27 348 BNE :IOERROR ; error! 349 * MMC Ver. 3 initialized! 350 C8B2: A9 43 351 :BLOCKSZ LDA #CMD16 C8B8: 85 41 354 STA CMDHI C8BA: 20 EB C8 355 JSR CMD C8BD: 20 FF C8 356 JSR GETR1 C8C0: C9 00 357 CMP #$00 C8C2: D0 15 358 BNE :IOERROR ; error! 359 C8C4: BD 83 C0 360 :END LDA SS,X C8C7: 09 80 361 ORA #INITED ; initialized C8C9: 9D 83 C0 362 STA SS,X C8CC: BD 81 C0 363 LDA CTRL,X C8CF: 09 04 364 ORA #ECE ; enable 7MHz C8D1: 9D 81 C0 365 STA CTRL,X C8D4: 18 366 CLC ; all ok C8D5: A0 00 367 LDY #0 C8D7: 90 03 368 BCC :END1 C8D9: 38 369 :IOERROR SEC C8DA: A0 27 370 LDY #$27 ; init error C8DC: BD 83 C0 371 :END1 LDA SS,X ; set CS high C8DF: 09 01 372 ORA #SS0 C8E1: 9D 83 C0 373 STA SS,X C8E4: A9 00 374 LDA #0 ; set div to 2 C8E6: 9D 82 C0 375 STA DIV,X C8E9: 98 376 TYA ; retval in A C8EA: 60 377 RTS 378 379 380 ******************************** 381 * 382 * Send SD command 383 * Call with command in CMDHI and CMDLO 384 * 385 ******************************** 386 C8EB: 5A 387 CMD PHY C8EC: A0 00 388 LDY #0 C8EE: B1 40 389 :LOOP LDA (CMDLO),Y C8F0: 9D 80 C0 390 STA DATA,X C8F3: 3C 81 C0 391 :WAIT BIT CTRL,X ; TC is in N C8F6: 10 FB 392 BPL :WAIT C8F8: C8 393 INY C8F9: C0 06 394 CPY #6 C8FB: 90 F1 395 BCC :LOOP C8FD: 7A 396 PLY C8FE: 60 397 RTS 398 399 400 ******************************** 401 * 402 * Get R1 403 * R1 is in A 404 * 405 ******************************** 406 C8FF: A9 FF 407 GETR1 LDA #DUMMY C901: 9D 80 C0 408 STA DATA,X C904: 3C 81 C0 409 :WAIT BIT CTRL,X C907: 10 FB 410 BPL :WAIT C909: BD 80 C0 411 LDA DATA,X ; get response C90C: 85 3C 412 STA WORK ; save R1 C90E: 29 80 413 AND #$80 C910: D0 ED 414 BNE GETR1 ; wait for MSB=0 C912: A9 FF 415 LDA #DUMMY C914: 9D 80 C0 416 STA DATA,X ; send another dummy C917: A5 3C 417 LDA WORK ; restore R1 C919: 60 418 RTS 419 420 421 ******************************** 422 * 423 * Get R3 424 * R1 is in A 425 * R3 is in scratchpad ram 426 * 427 ******************************** 428 C91A: 20 FF C8 429 GETR3 JSR GETR1 ; get R1 first C91D: 48 430 PHA ; save R1 C91E: 5A 431 PHY ; save Y C91F: A0 04 432 LDY #04 ; load counter C921: A9 FF 433 :LOOP LDA #DUMMY ; send dummy C923: 9D 80 C0 434 STA DATA,X C926: 3C 81 C0 435 :WAIT BIT CTRL,X C929: 10 FB 436 BPL :WAIT C92B: BD 80 C0 437 LDA DATA,X C92E: 48 438 PHA C92F: 88 439 DEY C930: D0 EF 440 BNE :LOOP ; do 4 times C932: A4 3D 441 LDY SLOT C934: 68 442 PLA C935: 99 F8 05 443 STA R33,Y ; save R3 C938: 68 444 PLA C939: 99 78 05 445 STA R32,Y C93C: 68 446 PLA C93D: 99 F8 04 447 STA R31,Y C940: 68 448 PLA C941: 99 78 04 449 STA R30,Y C944: 7A 450 PLY ; restore Y C945: A9 FF 451 LDA #DUMMY C947: 9D 80 C0 452 STA DATA,X ; send another dummy C94A: 68 453 PLA ; restore R1 C94B: 60 454 RTS 455 456 457 ******************************** 458 * 459 * Calculate block address 460 * Unit number is in $43 DSSS0000 461 * Block no is in $46-47 462 * Address is in R30-R33 463 * 464 ******************************** 465 C94C: DA 466 GETBLOCK PHX ; save X C94D: 5A 467 PHY ; save Y C94E: A6 3D 468 LDX SLOT C950: A5 46 469 LDA BLOCK ; store block num C952: 9D F8 05 470 STA R33,X ; in R30-R33 C955: A5 47 471 LDA BLOCK+1 C957: 9D 78 05 472 STA R32,X C95A: A9 00 473 LDA #0 C95C: 9D F8 04 474 STA R31,X C95F: 9D 78 04 475 STA R30,X 476 C962: A9 80 477 LDA #$80 ; drive number C964: 24 43 478 BIT $43 C966: F0 05 479 BEQ :SHIFT ; D1 C968: A9 01 480 LDA #1 ; D2 C96A: 9D F8 04 481 STA R31,X 482 C96D: A0 09 483 :SHIFT LDY #9 ; ASL can't be used with Y C96F: 1E F8 05 484 :LOOP ASL R33,X ; mul block num C972: 3E 78 05 485 ROL R32,X ; by 512 to get C975: 3E F8 04 486 ROL R31,X ; real address C978: 3E 78 04 487 ROL R30,X C97B: 88 488 DEY C97C: D0 F1 489 BNE :LOOP C97E: 7A 490 PLY ; restore Y C97F: FA 491 PLX ; restore X C980: 60 492 RTS 493 494 495 ******************************** 496 * 497 * Send SD command 498 * Cmd is in A 499 * 500 ******************************** 501 C981: 5A 502 COMMAND PHY ; save Y C982: A4 3D 503 LDY SLOT C984: 9D 80 C0 504 STA DATA,X ; send command C987: B9 78 04 505 LDA R30,Y ; get arg from R30 on C98A: 9D 80 C0 506 STA DATA,X C98D: B9 F8 04 507 LDA R31,Y C990: 9D 80 C0 508 STA DATA,X C993: B9 78 05 509 LDA R32,Y C996: 9D 80 C0 510 STA DATA,X C999: B9 F8 05 511 LDA R33,Y C99C: 9D 80 C0 512 STA DATA,X C99F: A9 FF 513 LDA #DUMMY C9A1: 9D 80 C0 514 STA DATA,X ; dummy crc C9A4: 20 FF C8 515 JSR GETR1 C9A7: 7A 516 PLY ; restore Y C9A8: 60 517 RTS 518 519 520 ******************************** 521 * 522 * Check for card detect 523 * 524 * C Clear - card in slot 525 * Set - no card in slot 526 * 527 ******************************** 528 C9A9: 48 529 CARDDET PHA C9AA: A9 40 530 LDA #CD ; 0: card in C9AC: 3C 83 C0 531 BIT SS,X ; 1: card out C9AF: 18 532 CLC C9B0: F0 01 533 BEQ :DONE ; card is in C9B2: 38 534 SEC ; card is out C9B3: 68 535 :DONE PLA C9B4: 60 536 RTS 537 538 539 ******************************** 540 * 541 * Check for write protect 542 * 543 * C Clear - card not protected 544 * Set - card write protected 545 * 546 ******************************** 547 C9B5: 48 548 WRPROT PHA C9B6: A9 20 549 LDA #WP ; 0: write enabled C9B8: 3C 83 C0 550 BIT SS,X ; 1: write disabled C9BB: 18 551 CLC C9BC: F0 01 552 BEQ :DONE C9BE: 38 553 SEC C9BF: 68 554 :DONE PLA C9C0: 60 555 RTS 556 557 558 ******************************** 559 * 560 * Status request 561 * $43 Unit number DSSS000 562 * $44-45 Unused 563 * $46-47 Unused 564 * 565 * C Clear - No error 566 * Set - Error 567 * A $00 - No error 568 * $2B - Card write protected 569 * $2F - No card inserted 570 * X - Blocks avail (low byte) 571 * Y - Blocks avail (high byte) 572 * 573 ******************************** 574 C9C1: A9 00 575 STATUS LDA #0 ; no error C9C3: A2 FF 576 LDX #$FF ; 32 MB partition C9C5: A0 FF 577 LDY #$FF 578 C9C7: 20 B5 C9 579 JSR WRPROT C9CA: 90 02 580 BCC :DONE C9CC: A9 2B 581 LDA #$2B ; card write protected 582 C9CE: 60 583 :DONE RTS 584 585 586 ******************************** 587 * 588 * Read 512 byte block 589 * $43 Unit number DSSS0000 590 * $44-45 Address (LO/HI) of buffer 591 * $46-47 Block number (LO/HI) 592 * 593 * C Clear - No error 594 * Set - Error 595 * A $00 - No error 596 * $27 - Bad block number 597 * 598 ******************************** 599 C9CF: 20 4C C9 600 READ JSR GETBLOCK ; calc block address 601 C9D2: BD 83 C0 602 LDA SS,X ; enable /CS C9D5: 29 FE 603 AND #$FF!SS0 C9D7: 9D 83 C0 604 STA SS,X C9DA: A9 51 605 LDA #$51 ; send CMD17 C9DC: 20 81 C9 606 JSR COMMAND ; send command 607 C9DF: C9 00 608 CMP #0 ; check for error C9E1: D0 50 609 BNE :ERROR 610 C9E3: A9 FF 611 :GETTOK LDA #DUMMY ; get data token C9E5: 9D 80 C0 612 STA DATA,X C9E8: BD 80 C0 613 LDA DATA,X ; get response C9EB: C9 FE 614 CMP #$FE C9ED: D0 F4 615 BNE :GETTOK ; wait for $FE 616 C9EF: A0 02 617 LDY #2 ; read data from card C9F1: BD 81 C0 618 LDA CTRL,X ; enable FRX C9F4: 09 10 619 ORA #FRX C9F6: 9D 81 C0 620 STA CTRL,X C9F9: A9 FF 621 LDA #DUMMY C9FB: 9D 80 C0 622 STA DATA,X C9FE: 64 3C 623 :LOOPY STZ WORK CA00: BD 80 C0 624 :LOOPW LDA DATA,X CA03: 92 44 625 STA (BUFFER) CA05: E6 44 626 INC BUFFER CA07: D0 02 627 BNE :INW CA09: E6 45 628 INC BUFFER+1 ; inc msb on page boundary CA0B: E6 3C 629 :INW INC WORK CA0D: D0 F1 630 BNE :LOOPW CA0F: 88 631 DEY CA10: D0 EC 632 BNE :LOOPY 633 CA12: BD 80 C0 634 :CRC LDA DATA,X ; read two bytes crc CA15: BD 80 C0 635 LDA DATA,X ; and ignore CA18: BD 80 C0 636 LDA DATA,X ; read a dummy byte 637 CA1B: BD 81 C0 638 LDA CTRL,X ; disable FRX CA1E: 29 EF 639 AND #$FF!FRX CA20: 9D 81 C0 640 STA CTRL,X CA23: 18 641 CLC ; no error CA24: A9 00 642 LDA #0 643 CA26: 08 644 :DONE PHP CA27: 48 645 PHA CA28: BD 83 C0 646 LDA SS,X CA2B: 09 01 647 ORA #SS0 CA2D: 9D 83 C0 648 STA SS,X ; disable /CS CA30: 68 649 PLA CA31: 28 650 PLP CA32: 60 651 RTS 652 CA33: 38 653 :ERROR SEC ; an error occured CA34: A9 27 654 LDA #$27 CA36: 80 EE 655 BRA :DONE 656 657 658 ******************************** 659 * 660 * Write 512 byte block 661 * $43 Unit number DSSS0000 662 * $44-45 Address (LO/HI) of buffer 663 * $46-47 Block number (LO/HI) 664 * 665 * C Clear - No error 666 * Set - Error 667 * A $00 - No error 668 * $27 - I/O error or bad block number 669 * $2B - Card write protected 670 * 671 ******************************** 672 CA38: 20 B5 C9 673 WRITE JSR WRPROT CA3B: B0 67 674 BCS :WPERROR ; card write protected 675 CA3D: 20 4C C9 676 JSR GETBLOCK ; calc block address 677 CA40: BD 83 C0 678 LDA SS,X ; enable /CS CA43: 29 FE 679 AND #$FF!SS0 CA45: 9D 83 C0 680 STA SS,X CA48: A9 58 681 LDA #$58 ; send CMD24 CA4A: 20 81 C9 682 JSR COMMAND ; send command 683 CA4D: C9 00 684 CMP #0 ; check for error CA4F: D0 4E 685 BNE :IOERROR 686 CA51: A9 FF 687 LDA #DUMMY CA53: 9D 80 C0 688 STA DATA,X ; send dummy CA56: A9 FE 689 LDA #$FE CA58: 9D 80 C0 690 STA DATA,X ; send data token 691 CA5B: A0 02 692 LDY #2 ; send data to card CA5D: 64 3C 693 :LOOPY STZ WORK CA5F: B2 44 694 :LOOPW LDA (BUFFER) CA61: 9D 80 C0 695 STA DATA,X CA64: E6 44 696 INC BUFFER CA66: D0 02 697 BNE :INW CA68: E6 45 698 INC BUFFER+1 ; inc msb on page boundary CA6A: E6 3C 699 :INW INC WORK CA6C: D0 F1 700 BNE :LOOPW CA6E: 88 701 DEY CA6F: D0 EC 702 BNE :LOOPY 703 CA71: 9D 80 C0 704 :CRC STA DATA,X ; send 2 dummy crc bytes CA74: 9D 80 C0 705 STA DATA,X 706 CA77: 9D 80 C0 707 STA DATA,X ; get data response CA7A: BD 80 C0 708 LDA DATA,X CA7D: 29 1F 709 AND #$1F CA7F: C9 05 710 CMP #$05 CA81: D0 1C 711 BNE :IOERROR ; check for write error CA83: 18 712 CLC ; no error CA84: A9 00 713 LDA #0 714 CA86: 08 715 :DONE PHP CA87: 48 716 PHA CA88: A9 FF 717 :WAIT LDA #DUMMY CA8A: 9D 80 C0 718 STA DATA,X ; wait for write cycle CA8D: BD 80 C0 719 LDA DATA,X ; to complete CA90: C9 00 720 CMP #$00 CA92: F0 F4 721 BEQ :WAIT 722 CA94: BD 83 C0 723 LDA SS,X ; disable /CS CA97: 09 01 724 ORA #SS0 CA99: 9D 83 C0 725 STA SS,X CA9C: 68 726 PLA CA9D: 28 727 PLP CA9E: 60 728 RTS 729 CA9F: 38 730 :IOERROR SEC ; an error occured CAA0: A9 27 731 LDA #$27 CAA2: 80 E2 732 BRA :DONE 733 CAA4: 38 734 :WPERROR SEC CAA5: A9 2B 735 LDA #$2B CAA7: 80 DD 736 BRA :DONE 737 738 739 740 ******************************** 741 * 742 * Format 743 * not supported! 744 * 745 ******************************** 746 CAA9: 38 747 FORMAT SEC CAAA: A9 01 748 LDA #$01 ; invalid command CAAC: 60 749 RTS 750 751 752 ******************************** 753 * 754 * Test routine 755 * 756 ******************************** 757 758 TEST 759 760 * get buffer CAAD: A4 3D 761 LDY SLOT CAAF: A9 02 762 LDA #2 ; get 512 byte buffer CAB1: 20 F5 BE 763 JSR $BEF5 ; call GETBUFR CAB4: B0 79 764 BCS :ERROR CAB6: 99 F8 06 765 STA RAM1,Y CAB9: 85 45 766 STA BUFFER+1 CABB: A9 00 767 LDA #0 CABD: 99 78 06 768 STA RAM0,Y CAC0: 85 44 769 STA BUFFER 770 771 * fill buffer CAC2: A0 00 772 LDY #0 CAC4: 98 773 :LOOP TYA CAC5: 91 44 774 STA (BUFFER),Y CAC7: C8 775 INY CAC8: D0 FA 776 BNE :LOOP CACA: E6 45 777 INC BUFFER+1 CACC: 98 778 :LOOP1 TYA CACD: 91 44 779 STA (BUFFER),Y CACF: C8 780 INY CAD0: D0 FA 781 BNE :LOOP1 782 783 * write to card CAD2: A9 02 784 LDA #2 ; write cmd CAD4: A4 3D 785 LDY SLOT CAD6: 85 42 786 STA DCMD CAD8: AD 78 06 787 LDA RAM0 ; buffer address CADB: 85 44 788 STA BUFFER CADD: B9 F8 06 789 LDA RAM1,Y CAE0: 85 45 790 STA BUFFER+1 CAE2: 64 46 791 STZ BLOCK ; block number CAE4: 64 47 792 STZ BLOCK+1 CAE6: A6 2B 793 LDX SLOT16 CAE8: 20 4B C7 794 JSR DRIVER CAEB: B0 42 795 BCS :ERROR 796 797 * read from card CAED: A9 01 798 LDA #1 ; read cmd CAEF: A4 3D 799 LDY SLOT CAF1: 85 42 800 STA DCMD CAF3: B9 78 06 801 LDA RAM0,Y ; buffer address CAF6: 85 44 802 STA BUFFER CAF8: B9 F8 06 803 LDA RAM1,Y CAFB: 85 45 804 STA BUFFER+1 CAFD: 64 46 805 STZ BLOCK ; block number CAFF: 64 47 806 STZ BLOCK+1 CB01: A6 2B 807 LDX SLOT16 CB03: 20 4B C7 808 JSR DRIVER CB06: B0 27 809 BCS :ERROR 810 811 * check for errors CB08: A4 3D 812 LDY SLOT CB0A: B9 78 06 813 LDA RAM0,Y ; buffer address CB0D: 85 44 814 STA BUFFER CB0F: B9 F8 06 815 LDA RAM1,Y CB12: 85 45 816 STA BUFFER+1 CB14: A0 00 817 LDY #0 CB16: 98 818 :LOOP2 TYA CB17: D1 44 819 CMP (BUFFER),Y CB19: D0 15 820 BNE :ERRCMP ; error in buffer CB1B: C8 821 INY CB1C: D0 F8 822 BNE :LOOP2 CB1E: E6 45 823 INC BUFFER+1 CB20: 98 824 :LOOP3 TYA CB21: D1 44 825 CMP (BUFFER),Y CB23: D0 0B 826 BNE :ERRCMP CB25: C8 827 INY CB26: D0 F8 828 BNE :LOOP3 829 830 * free buffer CB28: 20 F8 BE 831 JSR $BEF8 ; call FREEBUFR CB2B: 18 832 CLC CB2C: A9 00 833 LDA #0 CB2E: 60 834 RTS 835 CB2F: 00 836 :ERROR BRK CB30: 00 837 :ERRCMP BRK 838 839 CB31: 40 00 00 840 CMD0 HEX 400000 CB34: 00 00 95 841 HEX 000095 CB37: 41 00 00 842 CMD1 HEX 410000 CB3A: 00 00 F9 843 HEX 0000F9 CB3D: 48 00 00 844 CMD8 HEX 480000 CB40: 01 AA 87 845 HEX 01AA87 CB43: 50 00 00 846 CMD16 HEX 500000 CB46: 02 00 FF 847 HEX 0200FF CB49: 77 00 00 848 CMD55 HEX 770000 CB4C: 00 00 65 849 HEX 000065 CB4F: 69 40 00 850 ACMD4140 HEX 694000 CB52: 00 00 77 851 HEX 000077 CB55: 69 00 00 852 ACMD410 HEX 690000 CB58: 00 00 FF 853 HEX 0000FF --End assembly, 1115 bytes, Errors: 0 Symbol table - alphabetical order: ACMD410 =$CB55 ACMD4140=$CB4F BLOCK =$46 ? BOOT =$C72B BUFFER =$44 CARDDET =$C9A9 CD =$40 CMD =$C8EB CMD0 =$CB31 CMD1 =$CB37 CMD16 =$CB43 CMD55 =$CB49 CMD8 =$CB3D CMDHI =$41 CMDLO =$40 COMMAND =$C981 CTRL =$C081 CURSLOT =$07F8 DATA =$C080 DCMD =$42 DEBUG =$00 DIV =$C082 DRIVER =$C74B DUMMY =$FF ECE =$04 FORMAT =$CAA9 FRX =$10 GETBLOCK=$C94C GETR1 =$C8FF GETR3 =$C91A INIT =$C800 INITED =$80 R30 =$0478 R31 =$04F8 R32 =$0578 R33 =$05F8 RAM0 =$0678 RAM1 =$06F8 READ =$C9CF SLOT =$3D SLOT16 =$2B SS =$C083 SS0 =$01 STATUS =$C9C1 TEST =$CAAD WORK =$3C WP =$20 WRITE =$CA38 WRPROT =$C9B5 Symbol table - numerical order: DEBUG =$00 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 DATA =$C080 CTRL =$C081 DIV =$C082 SS =$C083 ? BOOT =$C72B DRIVER =$C74B INIT =$C800 CMD =$C8EB GETR1 =$C8FF GETR3 =$C91A GETBLOCK=$C94C COMMAND =$C981 CARDDET =$C9A9 WRPROT =$C9B5 STATUS =$C9C1 READ =$C9CF WRITE =$CA38 FORMAT =$CAA9 TEST =$CAAD CMD0 =$CB31 CMD1 =$CB37 CMD8 =$CB3D CMD16 =$CB43 CMD55 =$CB49 ACMD4140=$CB4F ACMD410 =$CB55