259 lines
5.8 KiB
ArmAsm
259 lines
5.8 KiB
ArmAsm
;*******************************
|
|
;
|
|
; Apple][Sd Firmware
|
|
; Version 1.2.3
|
|
; ProDOS functions
|
|
;
|
|
; (c) Florian Reitz, 2017 - 2021
|
|
;
|
|
; X register usually contains SLOT16
|
|
; Y register is used for counting or SLOT
|
|
;
|
|
;*******************************
|
|
|
|
.export PRODOS
|
|
.export STATUS
|
|
.export READ
|
|
.export WRITE
|
|
|
|
.import COMMAND
|
|
.import SDCMD
|
|
.import GETBLOCK
|
|
.import CARDDET
|
|
.import INITED
|
|
.import INIT
|
|
.import WRPROT
|
|
.import GETR1
|
|
.import GETR3
|
|
|
|
.include "AppleIISd.inc"
|
|
.segment "EXTROM"
|
|
|
|
|
|
;*******************************
|
|
;
|
|
; ProDOS command dispatcher
|
|
;
|
|
; $42-$47 MLI input locations
|
|
; X Slot*16
|
|
; Y Slot
|
|
;
|
|
; C Clear - No error
|
|
; Set - Error
|
|
; A $00 - No error
|
|
; $01 - Unknown command
|
|
;
|
|
;*******************************
|
|
|
|
PRODOS: LDA DCMD ; get command
|
|
BEQ @STATUS ; branch if cmd is 0
|
|
CMP #1
|
|
BEQ @READ
|
|
CMP #2
|
|
BEQ @WRITE
|
|
LDA #ERR_BADCMD ; unknown command
|
|
SEC
|
|
RTS
|
|
|
|
@STATUS: JMP STATUS
|
|
@READ: JMP READ
|
|
@WRITE: JMP WRITE
|
|
|
|
|
|
;*******************************
|
|
;
|
|
; Status request
|
|
; $43 Unit number DSSS000
|
|
; $44-45 Unused
|
|
; $46-47 Unused
|
|
;
|
|
; C Clear - No error
|
|
; Set - Error
|
|
; A $00 - No error
|
|
; $28 - No card inserted
|
|
; $2B - Card write protected
|
|
; X - Blocks avail (low byte)
|
|
; Y - Blocks avail (high byte)
|
|
;
|
|
;*******************************
|
|
|
|
STATUS: LDA #NO_ERR ; Thanks for this one, Antoine!
|
|
JSR CARDDET
|
|
BCC @WRPROT
|
|
LDA #ERR_NODRIVE; no card inserted
|
|
BNE @DONE
|
|
|
|
@WRPROT: JSR WRPROT
|
|
BCC @DONE
|
|
LDA #ERR_NOWRITE; card write protected
|
|
|
|
@DONE: LDX #$FF ; 32 MB partition
|
|
LDY #$FF
|
|
RTS
|
|
|
|
|
|
;*******************************
|
|
;
|
|
; 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
|
|
;
|
|
;*******************************
|
|
|
|
READ: JSR CARDDET ; check for card
|
|
BCS @NDERROR ; no card
|
|
|
|
JSR INITED ; check for initialization
|
|
BCC @GETBLOCK
|
|
|
|
JSR INIT ; initialize card
|
|
BCS @NDERROR ; init failed
|
|
|
|
@GETBLOCK: JSR GETBLOCK ; calc block address
|
|
|
|
LDA SS,X ; enable /CS
|
|
AND #<~SS0
|
|
STA SS,X
|
|
LDA #$51 ; send CMD17
|
|
JSR COMMAND ; send command
|
|
CMP #0
|
|
BNE @IOERROR ; check for error
|
|
|
|
@GETTOK: LDA #DUMMY ; get data token
|
|
STA DATA,X
|
|
LDA DATA,X ; get response
|
|
CMP #$FE
|
|
BNE @GETTOK ; wait for $FE
|
|
|
|
LDA CTRL,X ; enable FRX
|
|
ORA #FRX
|
|
STA CTRL,X
|
|
LDA #DUMMY
|
|
STA DATA,X
|
|
|
|
LDY #0
|
|
@LOOP1: LDA DATA,X ; read data from card
|
|
STA (BUFFER),Y
|
|
INY
|
|
BNE @LOOP1
|
|
INC BUFFER+1 ; inc msb on page boundary
|
|
@LOOP2: LDA DATA,X
|
|
STA (BUFFER),Y
|
|
INY
|
|
BNE @LOOP2
|
|
DEC BUFFER+1
|
|
|
|
@CRC: LDA DATA,X ; read two bytes crc
|
|
LDA DATA,X ; and ignore
|
|
LDA DATA,X ; read a dummy byte
|
|
|
|
LDA CTRL,X ; disable FRX
|
|
AND #<~FRX
|
|
STA CTRL,X
|
|
CLC ; no error
|
|
LDA #NO_ERR
|
|
|
|
@DONE: PHP
|
|
PHA
|
|
LDA SS,X
|
|
ORA #SS0
|
|
STA SS,X ; disable /CS
|
|
PLA
|
|
PLP
|
|
RTS
|
|
|
|
@IOERROR: SEC ; an error occured
|
|
LDA #ERR_IOERR
|
|
BRA @DONE
|
|
|
|
@NDERROR: SEC ; an error occured
|
|
LDA #ERR_NODRIVE
|
|
BRA @DONE
|
|
|
|
|
|
;*******************************
|
|
;
|
|
; Write 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 - I/O error or bad block number
|
|
; $2B - Card write protected
|
|
;
|
|
;*******************************
|
|
|
|
WRITE: JSR WRPROT
|
|
BCS @WPERROR ; card write protected
|
|
|
|
JSR GETBLOCK ; calc block address
|
|
|
|
LDA SS,X ; enable /CS
|
|
AND #<~SS0
|
|
STA SS,X
|
|
LDA #$58 ; send CMD24
|
|
JSR COMMAND ; send command
|
|
CMP #0
|
|
BNE @IOERROR ; check for error
|
|
|
|
LDA #DUMMY
|
|
STA DATA,X ; send dummy
|
|
LDA #$FE
|
|
STA DATA,X ; send data token
|
|
|
|
LDY #0
|
|
@LOOP1: LDA (BUFFER),Y
|
|
STA DATA,X
|
|
INY
|
|
BNE @LOOP1
|
|
INC BUFFER+1
|
|
@LOOP2: LDA (BUFFER),Y
|
|
STA DATA,X
|
|
INY
|
|
BNE @LOOP2
|
|
DEC BUFFER+1
|
|
|
|
@CRC: LDA #DUMMY
|
|
STA DATA,X ; send 2 dummy crc bytes
|
|
STA DATA,X
|
|
|
|
STA DATA,X ; get data response
|
|
LDA DATA,X
|
|
AND #$1F
|
|
CMP #$05
|
|
BNE @IOERROR ; check for write error
|
|
CLC ; no error
|
|
LDA #NO_ERR
|
|
|
|
@DONE: PHP
|
|
PHA
|
|
@WAIT: LDA #DUMMY
|
|
STA DATA,X ; wait for write cycle
|
|
LDA DATA,X ; to complete
|
|
BEQ @WAIT
|
|
|
|
LDA SS,X ; disable /CS
|
|
ORA #SS0
|
|
STA SS,X
|
|
PLA
|
|
PLP
|
|
RTS
|
|
|
|
@IOERROR: SEC ; an error occured
|
|
LDA #ERR_IOERR
|
|
BRA @DONE
|
|
|
|
@WPERROR: SEC
|
|
LDA #ERR_NOWRITE
|
|
BRA @DONE
|