;******************************* ; ; Apple][Sd Firmware ; Version 1.2.3 ; Smartport functions ; ; (c) Florian Reitz, 2017 - 2021 ; ; X register usually contains SLOT16 ; Y register is used for counting or SLOT ; ;******************************* .export SMARTPORT .import READ .import WRITE .import CARDDET .import WRPROT .include "AppleIISd.inc" .segment "EXTROM" ;******************************* ; ; Smartport 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 ; ;******************************* SMARTPORT: LDY #SMZPSIZE-1 ; save zeropage area for Smarport @SAVEZP: LDA SMZPAREA,Y PHA DEY BPL @SAVEZP TSX ; get call address LDA $103+PDZPSIZE+SMZPSIZE,X STA SMPARAMLIST ; store temporarily CLC ADC #3 ; adjust return address STA $103+PDZPSIZE+SMZPSIZE,X LDA $104+PDZPSIZE+SMZPSIZE,X STA SMPARAMLIST+1 ADC #0 STA $104+PDZPSIZE+SMZPSIZE,X LDY #1 ; get command code LDA (SMPARAMLIST),Y STA SMCMD INY LDA (SMPARAMLIST),Y TAX INY LDA (SMPARAMLIST),Y STA SMPARAMLIST+1 ; is now parameter list STX SMPARAMLIST LDA #ERR_BADCMD ; suspect bad command LDX SMCMD CPX #$09+1 ; command too large BCS @END LDA (SMPARAMLIST) ; parameter count CMP REQPARAMCOUNT,X BNE @COUNTMISMATCH LDY #1 ; get drive number LDA (SMPARAMLIST),Y LDY SLOT STA DRVNUM,Y TXA ; SMCMD ASL A ; shift for use of word addresses TAX JSR @JMPSPCOMMAND ; Y holds SLOT BCS @END ; jump on error LDA #NO_ERR @END: TAX ; save retval LDY #0 ; restore zeropage @RESTZP: PLA STA SMZPAREA,Y INY CPY #SMZPSIZE BCC @RESTZP TXA ;warum feste anzahl an bytes f�r return wert? LDY #2 ; highbyte of # bytes transferred LDX #0 ; low byte of # bytes transferred ;warum wird mit #1 verglichen? CMP #1 ; C=1 if A != NO_ERR RTS @COUNTMISMATCH: LDA #ERR_BADPCNT BRA @END @JMPSPCOMMAND: ; use offset from cmd*2 JMP (SPDISPATCH,X) ; Smartport Status command ; SMSTATUS: JSR GETCSLIST LDY SLOT LDA DRVNUM,Y BNE @PARTITION ; status call for a partition LDA SMCSCODE BEQ @STATUS00 ; status call 0 for the bus LDA #ERR_BADCTL ; calls other than 0 are not allowed SEC RTS ; TODO support partitions based on card size @STATUS00: LDA #4 ; support 4 partitions STA (SMCMDLIST) LDY #7 @LOOP00: LDA STATUS00DATA-1,Y STA (SMCMDLIST),Y DEY BNE @LOOP00 CLC RTS @PARTITION: LDX SMCSCODE BEQ @STATUS03 ; 0: device status DEX BEQ @GETDCB ; 1: get DCB DEX DEX BEQ @STATUS03 ; 3: get DIB LDA #ERR_BADCTL SEC RTS @GETDCB: LDA #1 ; return 'empty' DCB, one byte STA (SMCMDLIST) TAY LDA #NO_ERR STA (SMCMDLIST),Y CLC RTS @STATUS03: LDA #$E8 ; block device, read, write, format, ; not online, no write-protect LDX SLOT16 JSR CARDDET BCS @WRPROT ORA #$10 ; card inserted @WRPROT: JSR WRPROT BCC @STATUSBYTE ORA #$04 ; SD card write-protected @STATUSBYTE:STA (SMCMDLIST) LDY #1 ; block count, always $00FFFF LDA #$FF STA (SMCMDLIST),Y INY STA (SMCMDLIST),Y INY LDA #0 STA (SMCMDLIST),Y LDA SMCSCODE BEQ @DONE ; done if code 0, else get DIB, 21 bytes LDY #4 @LOOP: LDA STATUS3DATA-4,Y STA (SMCMDLIST),Y INY CPY #21+4 BCC @LOOP @DONE: CLC RTS ; Smartport Control command ; ; no controls supported, yet ; SMCONTROL: JSR GETCSLIST LDX SMCSCODE BEQ @RESET ; 0: Reset DEX BEQ @SETDCB ; 1: SetDCB DEX BEQ @NEWLINE ; 2: SetNewLine DEX BEQ @IRQ ; 3: ServiceInterrupt DEX BEQ @EJECT ; 4: Eject @NEWLINE: LDA #ERR_BADCTL SEC @RESET: @SETDCB: @EJECT: LDA #NO_ERR ; only return OK CLC RTS @IRQ: LDA #ERR_NOINT ; interrupts not supported SEC RTS ; Get control/status list pointer and code ; GETCSLIST: LDY #2 LDA (SMPARAMLIST),Y STA SMCMDLIST ; get buffer pointer INY LDA (SMPARAMLIST),Y STA SMCMDLIST+1 INY LDA (SMPARAMLIST),Y STA SMCSCODE ; get status/control code RTS ; Smartport Read Block command ; ; reads a 512-byte block using the ProDOS function ; SMREADBLOCK: JSR TRANSLATE BCC @READ RTS @READ: LDX SLOT16 LDY SLOT JMP READ ; call ProDOS read ; Smartport Write Block command ; ; writes a 512-byte block using the ProDOS function ; SMWRITEBLOCK: JSR TRANSLATE BCC @WRITE RTS @WRITE: LDX SLOT16 LDY SLOT JMP WRITE ; call ProDOS write ; Translates the Smartport unit number to a ProDOS device ; and prepares the block number ; ; Unit 0: entire chain, not supported ; Unit 1: this slot, drive 0 ; Unit 2: this slot, drive 1 ; Unit 3: phantom slot, drive 0 ; Unit 4: phantom slot, drive 1 ; TRANSLATE: LDA DRVNUM,Y BEQ @BADUNIT ; not supportd for unit 0 CMP #1 BEQ @UNIT1 CMP #2 BEQ @UNIT2 CMP #3 BEQ @UNIT3 CMP #4 BEQ @UNIT4 BRA @BADUNIT ; only 4 partitions are supported @UNIT1: LDA SLOT16 ; this slot BRA @STORE @UNIT2: LDA SLOT16 ORA #$80 ; drive 1 BRA @STORE @UNIT3: LDA SLOT16 DEC A ; phantom slot BRA @STORE @UNIT4: LDA SLOT16 DEC A ; phantom slot ORA #$80 ; drive 1 @STORE: STA DSNUMBER ; store in ProDOS variable LDY #2 ; get buffer pointer LDA (SMPARAMLIST),Y STA BUFFER INY LDA (SMPARAMLIST),Y STA BUFFER+1 INY ; get block number LDA (SMPARAMLIST),Y STA BLOCKNUM INY LDA (SMPARAMLIST),Y STA BLOCKNUM+1 INY LDA (SMPARAMLIST),Y BNE @BADBLOCK ; bit 23-16 need to be 0 CLC RTS @BADUNIT: LDA #ERR_BADUNIT SEC RTS @BADBLOCK: LDA #ERR_BADBLOCK SEC RTS ; Smartport Format command ; ; supported, but doesn't do anything ; unit number must not be 0 ; SMFORMAT: LDA DRVNUM,Y BEQ @ERROR LDA #NO_ERR CLC RTS @ERROR: LDA #ERR_BADUNIT SEC RTS ; Smartport Init comand ; ; supported, but doesn't do anything ; unit number must be 0 ; SMINIT: LDA DRVNUM,Y CLC BEQ @END ; error if not 0 LDA #ERR_BADUNIT SEC @END: RTS ; Smartport Open and Close commands ; ; supported for character devices, only ; SMOPEN: SMCLOSE: LDA #ERR_BADCMD SEC RTS ; Smartport Read Character and Write Character ; ; only 512-byte block operations are supported ; SMREADCHAR: SMWRITECHAR: LDA #ERR_IOERR SEC RTS ; Required parameter counts for the commands REQPARAMCOUNT: .byt 3 ; 0 = status .byt 3 ; 1 = read block .byt 3 ; 2 = write block .byt 1 ; 3 = format .byt 3 ; 4 = control .byt 1 ; 5 = init .byt 1 ; 6 = open .byt 1 ; 7 = close .byt 4 ; 8 = read char .byt 4 ; 9 = write char ; Command jump table SPDISPATCH: .word SMSTATUS .word SMREADBLOCK .word SMWRITEBLOCK .word SMFORMAT .word SMCONTROL .word SMINIT .word SMOPEN .word SMCLOSE .word SMREADCHAR .word SMWRITECHAR ; Status 00 command data STATUS00DATA: .byt $40 ; no interrupts .word $0000 ; unknown vendor .word SMDRIVERVER ; driver version .byt $00, $00 ; reserved .assert(*-STATUS00DATA)=7, error, "STATUS00DATA must be 7 bytes long" ; Status 3 command data STATUS3DATA: .byt 16, "APPLE][SD " ; ID length and string, padded .byt $02 ; hard disk .byt $00 ; removable hard disk .word SMDRIVERVER ; driver version .assert (*-STATUS3DATA)=21, error, "STATUS3DATA must be 21 bytes long"