forked from Apple-2-HW/AppleIISd
Merlin 8 source added
This commit is contained in:
parent
596e7c3f1f
commit
475a41b5de
591
AppleIISd.asm
Normal file
591
AppleIISd.asm
Normal file
@ -0,0 +1,591 @@
|
|||||||
|
********************************
|
||||||
|
*
|
||||||
|
* Initialize SD card
|
||||||
|
*
|
||||||
|
********************************
|
||||||
|
|
||||||
|
XC
|
||||||
|
ORG $C800
|
||||||
|
|
||||||
|
SLOT16 = $2B ; s0 -> slot * 16
|
||||||
|
CURSLOT = $07F8 ; Cs
|
||||||
|
DATA = $C0C0 ; slot 4
|
||||||
|
CTRL = DATA+1
|
||||||
|
DIV = DATA+2
|
||||||
|
SS = DATA+3
|
||||||
|
R30 = $0478
|
||||||
|
R31 = $04F8
|
||||||
|
R32 = $0578
|
||||||
|
R33 = $05F8
|
||||||
|
CMDLO = $FA
|
||||||
|
CMDHI = $FB
|
||||||
|
WORK = $3C
|
||||||
|
*
|
||||||
|
FROM = $FA ; + $fb
|
||||||
|
TO = $FC ; + $fd
|
||||||
|
SIZE = $FE ; + $ff
|
||||||
|
*
|
||||||
|
SSNONE = $0F
|
||||||
|
SS0 = $0E
|
||||||
|
TC = $80
|
||||||
|
DUMMY = $FF
|
||||||
|
|
||||||
|
|
||||||
|
********************************
|
||||||
|
*
|
||||||
|
* Install SD card driver
|
||||||
|
*
|
||||||
|
********************************
|
||||||
|
|
||||||
|
* signature bytes
|
||||||
|
|
||||||
|
LDX #$20
|
||||||
|
LDY #$00
|
||||||
|
LDX #$03
|
||||||
|
STX WORK
|
||||||
|
|
||||||
|
* find slot nr
|
||||||
|
|
||||||
|
JSR $FF58
|
||||||
|
TSX
|
||||||
|
LDA $0100,X
|
||||||
|
AND #$0F
|
||||||
|
ORA #$C0
|
||||||
|
STA CURSLOT ; $Cs
|
||||||
|
ASL A
|
||||||
|
ASL A
|
||||||
|
ASL A
|
||||||
|
ASL A
|
||||||
|
STA SLOT16 ; $s0
|
||||||
|
|
||||||
|
BIT $CFFF
|
||||||
|
JSR INIT
|
||||||
|
|
||||||
|
*
|
||||||
|
* TODO: check for init error
|
||||||
|
*
|
||||||
|
|
||||||
|
* see if slot has a driver already
|
||||||
|
|
||||||
|
INSTALL LDX $BF31 ; get devcnt
|
||||||
|
INSLP LDA $BF32,X ; get a devnum
|
||||||
|
AND #$70 ; isolate slot
|
||||||
|
CMP SLOT16 ; slot?
|
||||||
|
BEQ INSOUT ; yes, skip it
|
||||||
|
DEX
|
||||||
|
BPL INSLP ; keep up the search
|
||||||
|
|
||||||
|
* restore the devnum to the list
|
||||||
|
|
||||||
|
LDX $BF31 ; get devcnt again
|
||||||
|
CPX #$0D device table full?
|
||||||
|
BNE INSLP2
|
||||||
|
|
||||||
|
ERROR JMP INSOUT ; do something!
|
||||||
|
|
||||||
|
INSLP2 LDA $BF32-1,X ; move all entries down
|
||||||
|
STA $BF32,X ; to make room at front
|
||||||
|
DEX ; for a new entry
|
||||||
|
BNE INSLP2
|
||||||
|
LDA #$04 ; ProFile type device
|
||||||
|
ORA SLOT16
|
||||||
|
STA $BF32 ; slot, drive 1 at top of list
|
||||||
|
INC $BF31 ; update devcnt
|
||||||
|
|
||||||
|
* now insert the device driver vector
|
||||||
|
|
||||||
|
LDA CURSLOT
|
||||||
|
AND #$0F
|
||||||
|
TXA
|
||||||
|
LDA #<DRIVER
|
||||||
|
STA $BF10,X
|
||||||
|
LDA CURSLOT
|
||||||
|
STA $BF11,X
|
||||||
|
|
||||||
|
INSOUT RTS
|
||||||
|
|
||||||
|
|
||||||
|
********************************
|
||||||
|
*
|
||||||
|
* Jump table
|
||||||
|
*
|
||||||
|
********************************
|
||||||
|
|
||||||
|
DRIVER CLD
|
||||||
|
BIT $CFFF
|
||||||
|
LDA $42 ; get command
|
||||||
|
CMP #$00
|
||||||
|
BEQ :STATUS
|
||||||
|
CMP #$01
|
||||||
|
BEQ :READ
|
||||||
|
CMP #$02
|
||||||
|
BEQ :WRITE
|
||||||
|
CMP #$03
|
||||||
|
BEQ :FORMAT
|
||||||
|
SEC ; unknown command
|
||||||
|
LDA #$01
|
||||||
|
RTS
|
||||||
|
|
||||||
|
:STATUS JMP STATUS
|
||||||
|
:READ JMP READ
|
||||||
|
:WRITE JMP WRITE
|
||||||
|
:FORMAT JMP FORMAT
|
||||||
|
|
||||||
|
ORG $C8FC
|
||||||
|
DW $FFFF ; 65535 blocks
|
||||||
|
DB $47 ; Status bits
|
||||||
|
DB #<DRIVER ; LSB of driver
|
||||||
|
|
||||||
|
ORG $C900
|
||||||
|
|
||||||
|
********************************
|
||||||
|
*
|
||||||
|
* Initialize SD card
|
||||||
|
*
|
||||||
|
* C Clear - No error
|
||||||
|
* Set - Error
|
||||||
|
* A $00 - No error
|
||||||
|
* $27 - I/O error - Init failed
|
||||||
|
* $28 - No card inserted
|
||||||
|
*
|
||||||
|
********************************
|
||||||
|
|
||||||
|
INIT CLD
|
||||||
|
LDA #$03 ; set SPI mode 3
|
||||||
|
STA CTRL
|
||||||
|
LDA #SSNONE
|
||||||
|
STA SS
|
||||||
|
LDA #7
|
||||||
|
STA DIV
|
||||||
|
LDX #10
|
||||||
|
LDA #DUMMY
|
||||||
|
|
||||||
|
:LOOP STA DATA
|
||||||
|
:WAIT BIT CTRL
|
||||||
|
BPL :WAIT
|
||||||
|
DEX
|
||||||
|
BNE :LOOP ; do 10 times
|
||||||
|
LDA #SS0 ; set CS low
|
||||||
|
STA SS
|
||||||
|
|
||||||
|
LDA #<CMD0 ; send CMD0
|
||||||
|
STA CMDLO
|
||||||
|
LDA #>CMD0
|
||||||
|
STA CMDHI
|
||||||
|
JSR CMD
|
||||||
|
JSR GETR1 ; get response
|
||||||
|
CMP #$01
|
||||||
|
BNE ERROR1 ; error!
|
||||||
|
|
||||||
|
LDA #<CMD8 ; send CMD8
|
||||||
|
STA CMDLO
|
||||||
|
LDA #>CMD8
|
||||||
|
STA CMDHI
|
||||||
|
JSR CMD
|
||||||
|
JSR GETR3
|
||||||
|
CMP #$01
|
||||||
|
BNE SDV1 ; may be SD Ver. 1
|
||||||
|
|
||||||
|
* check for $01aa match!
|
||||||
|
|
||||||
|
SDV2 LDA #<CMD55
|
||||||
|
STA CMDLO
|
||||||
|
LDA #>CMD55
|
||||||
|
STA CMDHI
|
||||||
|
JSR CMD
|
||||||
|
JSR GETR1
|
||||||
|
LDA #<ACMD41_40
|
||||||
|
STA CMDLO
|
||||||
|
LDA #>ACMD41_40
|
||||||
|
STA CMDHI
|
||||||
|
JSR CMD
|
||||||
|
JSR GETR1
|
||||||
|
CMP #$01
|
||||||
|
BEQ SDV2 ; wait for ready
|
||||||
|
CMP #$00
|
||||||
|
BNE ERROR1 ; error!
|
||||||
|
* send CMD58
|
||||||
|
* SD Ver. 2 initialized!
|
||||||
|
JMP BLOCKSZ
|
||||||
|
|
||||||
|
ERROR1 JMP IOERROR ; needed for far jump
|
||||||
|
|
||||||
|
SDV1 LDA #<CMD55
|
||||||
|
STA CMDLO
|
||||||
|
LDA #>CMD55
|
||||||
|
STA CMDHI
|
||||||
|
JSR CMD ; ignore response
|
||||||
|
LDA #<ACMD41_0
|
||||||
|
STA CMDLO
|
||||||
|
LDA #>ACMD41_0
|
||||||
|
STA CMDHI
|
||||||
|
JSR CMD
|
||||||
|
JSR GETR1
|
||||||
|
CMP #$01
|
||||||
|
BEQ SDV1 ; wait for ready
|
||||||
|
CMP #$00
|
||||||
|
BNE MMC ; may be MMC card
|
||||||
|
* SD Ver. 1 initialized!
|
||||||
|
JMP BLOCKSZ
|
||||||
|
|
||||||
|
MMC LDA #<CMD1
|
||||||
|
STA CMDLO
|
||||||
|
LDA #>CMD1
|
||||||
|
STA CMDHI
|
||||||
|
:LOOP JSR CMD
|
||||||
|
JSR GETR1
|
||||||
|
CMP #$01
|
||||||
|
BEQ :LOOP ; wait for ready
|
||||||
|
CMP #$00
|
||||||
|
BNE IOERROR ; error!
|
||||||
|
* MMC Ver. 3 initialized!
|
||||||
|
|
||||||
|
BLOCKSZ LDA #<CMD16
|
||||||
|
STA CMDLO
|
||||||
|
LDA #>CMD16
|
||||||
|
STA CMDHI
|
||||||
|
JSR CMD
|
||||||
|
JSR GETR1
|
||||||
|
CMP #$00
|
||||||
|
BNE IOERROR ; error!
|
||||||
|
|
||||||
|
END CLC ; all ok
|
||||||
|
LDY #0
|
||||||
|
BCC END1
|
||||||
|
CDERROR SEC
|
||||||
|
LDY #$28 ; no card error
|
||||||
|
BCS END1
|
||||||
|
IOERROR SEC
|
||||||
|
LDY #$27 ; init error
|
||||||
|
END1 LDA #SSNONE ; deselect card
|
||||||
|
STA SS
|
||||||
|
LDA #0
|
||||||
|
STA DIV
|
||||||
|
TYA ; retval in A
|
||||||
|
RTS
|
||||||
|
|
||||||
|
|
||||||
|
********************************
|
||||||
|
*
|
||||||
|
* Send SD command
|
||||||
|
* Call with command in CMDHI and CMDLO
|
||||||
|
*
|
||||||
|
********************************
|
||||||
|
|
||||||
|
CMD LDY #0
|
||||||
|
:LOOP LDA (CMDLO),Y
|
||||||
|
STA DATA
|
||||||
|
:WAIT BIT CTRL ; TC is in N
|
||||||
|
BPL :WAIT
|
||||||
|
INY
|
||||||
|
CPY #6
|
||||||
|
BCC :LOOP
|
||||||
|
RTS
|
||||||
|
|
||||||
|
|
||||||
|
********************************
|
||||||
|
*
|
||||||
|
* Get R1
|
||||||
|
* R1 is in A
|
||||||
|
*
|
||||||
|
********************************
|
||||||
|
|
||||||
|
GETR1 LDA #DUMMY
|
||||||
|
STA DATA
|
||||||
|
:WAIT BIT CTRL
|
||||||
|
BPL :WAIT
|
||||||
|
LDA DATA ; get response
|
||||||
|
STA R30+SLOT ; save R1
|
||||||
|
AND #$80
|
||||||
|
BNE GETR1 ; wait for MSB=0
|
||||||
|
LDA #DUMMY
|
||||||
|
STA DATA ; send another dummy
|
||||||
|
LDA R30+SLOT ; restore R1
|
||||||
|
RTS
|
||||||
|
|
||||||
|
|
||||||
|
********************************
|
||||||
|
*
|
||||||
|
* Get R3
|
||||||
|
* R1 is in A
|
||||||
|
* R3 is in scratchpad ram
|
||||||
|
*
|
||||||
|
********************************
|
||||||
|
|
||||||
|
GETR3 JSR GETR1 ; get R1 first
|
||||||
|
PHA ; save R1
|
||||||
|
PHY ; save Y
|
||||||
|
LDY #04
|
||||||
|
:LOOP LDA #DUMMY ; send dummy
|
||||||
|
STA DATA
|
||||||
|
:WAIT BIT CTRL
|
||||||
|
BPL :WAIT
|
||||||
|
LDA DATA
|
||||||
|
PHA
|
||||||
|
DEY
|
||||||
|
BNE :LOOP ; do 4 times
|
||||||
|
PLA
|
||||||
|
STA R33+SLOT ; save R3
|
||||||
|
PLA
|
||||||
|
STA R32+SLOT
|
||||||
|
PLA
|
||||||
|
STA R31+SLOT
|
||||||
|
PLA
|
||||||
|
STA R30+SLOT
|
||||||
|
PLY ; restore Y
|
||||||
|
LDA #DUMMY
|
||||||
|
STA DATA ; send another dummy
|
||||||
|
PLA ; restore R1
|
||||||
|
RTS
|
||||||
|
|
||||||
|
|
||||||
|
********************************
|
||||||
|
*
|
||||||
|
* Status request
|
||||||
|
* $43 Unt number DSSS000
|
||||||
|
* $44-45 Unused
|
||||||
|
* $46-47 Unused
|
||||||
|
*
|
||||||
|
* C Clear - No error
|
||||||
|
* Set - Error
|
||||||
|
* A $00 - No error
|
||||||
|
* $27 - I/O error
|
||||||
|
* $28 - No card inserted / no init
|
||||||
|
* $2B - Card write protected
|
||||||
|
* X - Blocks avail (low byte)
|
||||||
|
* Y - Blocks avail (high byte)
|
||||||
|
*
|
||||||
|
********************************
|
||||||
|
|
||||||
|
STATUS CLC ; no error
|
||||||
|
LDA #0
|
||||||
|
LDX #$FF ; 32 MB partition
|
||||||
|
LDY #$FF
|
||||||
|
RTS
|
||||||
|
|
||||||
|
*
|
||||||
|
* TODO: check for card detect and write protect!
|
||||||
|
*
|
||||||
|
|
||||||
|
|
||||||
|
********************************
|
||||||
|
*
|
||||||
|
* Read 512 byte block
|
||||||
|
* $43 Unit number DSSS0000
|
||||||
|
* $44-45 Address (LO/HI) of buffer
|
||||||
|
* $46-47 Block number (LO/HI)
|
||||||
|
*
|
||||||
|
* C Clear - No error
|
||||||
|
* Set - Error
|
||||||
|
* A $00 - No error
|
||||||
|
* $27 - Bad block number
|
||||||
|
* $28 - No card inserted
|
||||||
|
*
|
||||||
|
********************************
|
||||||
|
|
||||||
|
*
|
||||||
|
* TODO: check for card detect!
|
||||||
|
*
|
||||||
|
|
||||||
|
READ LDA #SS0 ; enable /CS
|
||||||
|
STA SS
|
||||||
|
|
||||||
|
LDA $46 ; store block num
|
||||||
|
STA R33+SLOT ; in R30-R33
|
||||||
|
LDA $47
|
||||||
|
STA R32+SLOT
|
||||||
|
STZ R31+SLOT
|
||||||
|
STZ R30+SLOT
|
||||||
|
LDY #9
|
||||||
|
:LOOP ASL R33+SLOT ; mul block num
|
||||||
|
ROL R32+SLOT ; by 512 to get
|
||||||
|
ROL R31+SLOT ; real address
|
||||||
|
ROL R30+SLOT
|
||||||
|
DEY
|
||||||
|
BNE :LOOP
|
||||||
|
|
||||||
|
LDA #$51 ; send CMD17
|
||||||
|
STA DATA
|
||||||
|
:WAIT BIT CTRL
|
||||||
|
BPL :WAIT
|
||||||
|
:ARG LDA R30+SLOT ; get arg from R30 on
|
||||||
|
STA DATA
|
||||||
|
:WAIT1 BIT CTRL
|
||||||
|
BPL :WAIT1
|
||||||
|
LDA R31+SLOT
|
||||||
|
STA DATA
|
||||||
|
:WAIT11 BIT CTRL
|
||||||
|
BPL :WAIT11
|
||||||
|
LDA R32+SLOT
|
||||||
|
STA DATA
|
||||||
|
:WAIT12 BIT CTRL
|
||||||
|
BPL :WAIT12
|
||||||
|
LDA R33+SLOT
|
||||||
|
STA DATA
|
||||||
|
:WAIT13 BIT CTRL
|
||||||
|
BPL :WAIT13
|
||||||
|
LDA #DUMMY
|
||||||
|
STA DATA ; dummy crc
|
||||||
|
:WAIT2 BIT CTRL
|
||||||
|
BPL :WAIT2
|
||||||
|
:GETR1 LDA #DUMMY
|
||||||
|
STA DATA ; get R1
|
||||||
|
:WAIT3 BIT CTRL
|
||||||
|
BPL :WAIT3
|
||||||
|
LDA DATA ; get response
|
||||||
|
*
|
||||||
|
* TODO: check for error!
|
||||||
|
*
|
||||||
|
CMP #$FE
|
||||||
|
BNE :GETR1 ; wait for $FE
|
||||||
|
|
||||||
|
LDX #2 ; read data from card
|
||||||
|
:LOOPX LDY #0
|
||||||
|
:LOOPY LDA #DUMMY
|
||||||
|
STA DATA
|
||||||
|
:WAIT4 BIT CTRL
|
||||||
|
BPL :WAIT4
|
||||||
|
LDA DATA
|
||||||
|
STA ($44)
|
||||||
|
INC $44
|
||||||
|
BNE :INY
|
||||||
|
INC $45 ; inc msb on page boundary
|
||||||
|
:INY INY
|
||||||
|
BNE :LOOPY
|
||||||
|
DEX
|
||||||
|
BNE :LOOPX
|
||||||
|
|
||||||
|
:OK JSR GETR3 ; read 2 bytes crc
|
||||||
|
LDA #SSNONE
|
||||||
|
STA SS ; disable /CS
|
||||||
|
CLC ; no error
|
||||||
|
LDA #$00
|
||||||
|
RTS
|
||||||
|
|
||||||
|
:ERROR LDA #SSNONE
|
||||||
|
STA SS ; disable /CS
|
||||||
|
SEC ; an error occured
|
||||||
|
LDA #$27
|
||||||
|
RTS
|
||||||
|
|
||||||
|
|
||||||
|
********************************
|
||||||
|
*
|
||||||
|
* Write 512 byte block
|
||||||
|
* $43 Unit number DSSS000
|
||||||
|
* $44-45 Address (LO/HI) of buffer
|
||||||
|
* $46-47 Block number (LO/HI)
|
||||||
|
*
|
||||||
|
* C Clear - No error
|
||||||
|
* Set - Error
|
||||||
|
* A $00 - No error
|
||||||
|
* $27 - Bad block number
|
||||||
|
* $28 - No card inserted
|
||||||
|
*
|
||||||
|
********************************
|
||||||
|
|
||||||
|
*
|
||||||
|
* TODO: check for card detect and write protect!
|
||||||
|
*
|
||||||
|
|
||||||
|
WRITE LDA #SS0 ; enable /CS
|
||||||
|
STA SS
|
||||||
|
|
||||||
|
LDA $46 ; store block num
|
||||||
|
STA R33+SLOT
|
||||||
|
LDA $47
|
||||||
|
STA R32+SLOT
|
||||||
|
STZ R31+SLOT
|
||||||
|
STZ R30+SLOT
|
||||||
|
LDY #9
|
||||||
|
:LOOP ASL R33+SLOT ; mul block num
|
||||||
|
ROL R32+SLOT ; by 512 to get
|
||||||
|
ROL R31+SLOT ; real address
|
||||||
|
ROL R30+SLOT
|
||||||
|
DEY
|
||||||
|
BNE :LOOP
|
||||||
|
|
||||||
|
LDA #$58 ; send CMD24
|
||||||
|
STA DATA
|
||||||
|
:WAIT BIT CTRL
|
||||||
|
BPL :WAIT
|
||||||
|
:ARG LDA R30+SLOT ; get arg from R30 on
|
||||||
|
STA DATA
|
||||||
|
:WAIT1 BIT CTRL
|
||||||
|
BPL :WAIT1
|
||||||
|
LDA R31+SLOT
|
||||||
|
STA DATA
|
||||||
|
:WAIT11 BIT CTRL
|
||||||
|
BPL :WAIT11
|
||||||
|
LDA R32+SLOT
|
||||||
|
STA DATA
|
||||||
|
:WAIT12 BIT CTRL
|
||||||
|
BPL :WAIT12
|
||||||
|
LDA R33+SLOT
|
||||||
|
STA DATA
|
||||||
|
:WAIT13 BIT CTRL
|
||||||
|
BPL :WAIT13
|
||||||
|
LDA #DUMMY
|
||||||
|
STA DATA ; dummy crc
|
||||||
|
:WAIT2 BIT CTRL
|
||||||
|
BPL :WAIT2
|
||||||
|
:GETR1 LDA #DUMMY
|
||||||
|
STA DATA ; get R1
|
||||||
|
:WAIT3 BIT CTRL
|
||||||
|
BPL :WAIT3
|
||||||
|
LDA DATA : get response
|
||||||
|
*
|
||||||
|
* TODO: check for error!
|
||||||
|
*
|
||||||
|
CMP #$FE
|
||||||
|
BNE :GETR1 ; wait for $FE
|
||||||
|
LDX #2 ; send data to card
|
||||||
|
:LOOPX LDY #0
|
||||||
|
:LOOPY LDA ($44)
|
||||||
|
STA DATA
|
||||||
|
:WAIT4 BIT CTRL
|
||||||
|
BPL :WAIT4
|
||||||
|
INC $44
|
||||||
|
BNE :INY
|
||||||
|
INC $45 ; inc msb on page boundary
|
||||||
|
:INY INY
|
||||||
|
BNE :LOOPY
|
||||||
|
DEX
|
||||||
|
BNE :LOOPX
|
||||||
|
|
||||||
|
LDY #2 ; send 2 dummy crc bytes
|
||||||
|
:CRC STA DATA
|
||||||
|
:WAIT5 BIT CTRL
|
||||||
|
BPL :WAIT5
|
||||||
|
DEY
|
||||||
|
BNE :CRC
|
||||||
|
|
||||||
|
:OK LDA #SSNONE ; disable /CS
|
||||||
|
STA SS
|
||||||
|
CLC ; no error
|
||||||
|
LDA #0
|
||||||
|
RTS
|
||||||
|
|
||||||
|
|
||||||
|
********************************
|
||||||
|
*
|
||||||
|
* Format
|
||||||
|
* not supported!
|
||||||
|
*
|
||||||
|
********************************
|
||||||
|
|
||||||
|
FORMAT SEC
|
||||||
|
LDA #$01 ; invalid command
|
||||||
|
RTS
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
CMD0 HEX 400000000095
|
||||||
|
CMD1 HEX 4100000000F9
|
||||||
|
CMD8 HEX 48000001AA87
|
||||||
|
CMD16 HEX 5000000200FF
|
||||||
|
CMD55 HEX 770000000065
|
||||||
|
ACMD41_40 HEX 694000000077
|
||||||
|
ACMD41_0 HEX 6900000000FF
|
||||||
|
|
||||||
|
DRIVEND = *
|
Loading…
Reference in New Issue
Block a user