                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
                140           STA   $BF10,X    ; write to driver table
                141           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    #<DRIVER   ; LSB of driver
                247
                248  ********************************
                249  *
                250  * Initialize SD card
                251  *
                252  * C Clear - No error
                253  *   Set   - Error
                254  * A $00   - No error
                255  *   $27   - I/O error - Init failed
                256  *   $2F   - No card inserted
                257  *
                258  ********************************
                259
C800: D8        260  INIT     CLD
C801: A9 03     261           LDA   #$03       ; set SPI mode 3
C803: 9D 81 C0  262           STA   CTRL,X
C806: BD 83 C0  263           LDA   SS,X
C809: 09 01     264           ORA   #SS0       ; set CS high
C80B: 9D 83 C0  265           STA   SS,X
C80E: A9 07     266           LDA   #7
C810: 9D 82 C0  267           STA   DIV,X
C813: A0 0A     268           LDY   #10
C815: A9 FF     269           LDA   #DUMMY
                270
C817: 9D 80 C0  271  :LOOP    STA   DATA,X
C81A: 3C 81 C0  272  :WAIT    BIT   CTRL,X
C81D: 10 FB     273           BPL   :WAIT
C81F: 88        274           DEY
C820: D0 F5     275           BNE   :LOOP      ; do 10 times
C822: BD 83 C0  276           LDA   SS,X
C825: 29 FE     277           AND   #$FF!SS0   ; set CS low
C827: 9D 83 C0  278           STA   SS,X
                279
C82A: A9 31     280           LDA   #<CMD0     ; send CMD0
C82C: 85 40     281           STA   CMDLO
C82E: A9 CB     282           LDA   #>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     ; send CMD8
C83E: 85 40     290           STA   CMDLO
C840: A9 CB     291           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
C850: 85 40     300           STA   CMDLO
C852: A9 CB     301           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
C85E: 85 40     306           STA   CMDLO
C860: A9 CB     307           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
C87A: 85 40     322           STA   CMDLO
C87C: A9 CB     323           LDA   #>CMD55
C87E: 85 41     324           STA   CMDHI
C880: 20 EB C8  325           JSR   CMD        ; ignore response
C883: A9 55     326           LDA   #<ACMD410
C885: 85 40     327           STA   CMDLO
C887: A9 CB     328           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
C89E: 85 40     340           STA   CMDLO
C8A0: A9 CB     341           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
C8B4: 85 40     352           STA   CMDLO
C8B6: A9 CB     353           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
