;**************************************** ;* ;* SIDRIVE (SERIAL INTERFACE DRIVE) ROM ;* ;**************************************** ;DEBUG = 1 .DEFINE EQU = .DEFINE DB .BYTE .DEFINE DW .WORD .DEFINE PAGE .ALIGN 256 .DEFINE ORG .ORG .CODE ;* ;* ACIA REGISTERS ;* ACIADR EQU $C088 ACIASR EQU $C089 ACIACR EQU $C08A ACIAMR EQU $C08B ;* ;* APPLE I/O LOCATIONS ;* INDCTR EQU $0400 KEYBD EQU $C000 STROBE EQU $C010 XROMOFF EQU $CFFF ROMEN EQU $C082 ;* ;* DRIVER SCRATCHSCRTCH ;* SCRTCH0 EQU $0478 SCRTCH1 EQU $04F8 ; SYNCED FLAG SCRTCH2 EQU $0578 SCRTCH3 EQU $05F8 SCRTCH4 EQU $0678 SCRTCH5 EQU $06F8 SCRTCH6 EQU $0778 SCRTCH7 EQU $07F8 CMDACK EQU SCRTCH0 SYNCED EQU SCRTCH1 SAVE16 EQU SCRTCH2 IOSLOT EQU $07F8 ; CURRENT SLOT FOR IRQ HANDLING ;* ;* UTIL ROUTINES ;* COUT EQU $FDED CROUT EQU $FD8E PRBYTE EQU $FDDA PRHEX EQU $FDE3 PRNTAX EQU $F941 RDKEY EQU $FD0C RDCHAR EQU $FD35 GETLN EQU $FD6A MONITOR EQU $FF69 ;* ;* ZERO PAGE PARAMETERS ;* SLOT16 EQU $3C PDCMD EQU $42 PDUNIT EQU $43 PDBUFF EQU $44 PDBUFL EQU $44 PDBUFH EQU $45 PDBLKL EQU $46 PDBLKH EQU $47 ;* ;* PRODOS COMMANDS ;* PDSTAT EQU 0 PDREAD EQU 1 PDWRITE EQU 2 PDFORMT EQU 3 ;* ;* PRODOS ERRORS ;* PDNOERR EQU $00 PDIOERR EQU $27 PDNODEV EQU $28 PDWRPRT EQU $2B ;* ;* SIDRIVE SYNC and SYNC_ACK ;* SYNC_REQ EQU $80 SYNC_ACK EQU $81 ;**************************************** ;* ;* OPTION ROM SPACE @ $C800 ;* ;**************************************** ORG $C800 ;* ;* RETURN SLOT*16 IN X REG, SLOT IN Y REG ;* GETSLOT: TSX LDA $102,X ; GET MSB OF RETURN ADDRESS STA IOSLOT AND #$0F TAY LDA SLOT16 STA SAVE16,Y ; SAVE SLOT16 LOCATION TYA ASL ASL ASL ASL STA SLOT16 TAX RTS ;* ;* OUTPUT BYTE TO ACIA ;* SENDACC: PHA LDA SLOT16 ORA #$89+1 ; ACIASR TAX SENDWT: LDA $C000-1,X AND #$10 BEQ SENDWT DEX ; ACIADR PLA STA $C000-1,X ; AVOID PHANTOM READ OF DATA REG RTS ;* ;* INPUT BYTE FROM ACIA ;* RECVACC: LDX SLOT16 RECVWT: LDA ACIASR,X AND #$08 BEQ RECVWT LDA ACIADR,X RTS ;* ;* WAIT FOR DELAY ;* WAIT: SEC WAIT2: PHA WAIT3: SBC #$01 BNE WAIT3 PLA SBC #$01 BNE WAIT2 RTS ;* ;* SYNC WITH HOST ;* SYNC: LDA INDCTR PHA LDX SLOT16 LDA #$0B STA ACIASR,X ; RESET STATUS REGISTER STA ACIACR,X ; SET CONTROL REGISTER LDA #$10 STA ACIAMR,X ; SET COMMAND REGISTER (115K BAUD) LDA #$80 JSR WAIT STA STROBE ; CLEAR KEYBOARD STROBE SYNCLP: LDA #SYNC_REQ JSR SENDACC INY TYA AND #$07 TAY LDA SPIN,Y STA INDCTR LDA #$FF JSR WAIT LDA KEYBD BPL CHKRSP STA STROBE PLA .IFNDEF DEBUG STA INDCTR .ENDIF NODEV: LDA #PDNODEV RTS SPIN: DB $A1, $AF, $AD, $DC, $A1, $AF, $AD, $DC CHKRSP: LDX SLOT16 LDA ACIASR,X AND #$08 BEQ SYNCLP LDA ACIADR,X CMP #SYNC_ACK BNE SYNCLP LDA IOSLOT AND #$0F TAY LDA #SYNC_ACK STA SYNCED,Y PLA .IFNDEF DEBUG STA INDCTR .ENDIF ;* ;* DO STATUS, READ, WRITE COMMAND ;* DOCMD: LDA SYNCED,Y ; CHECK FOR ANY REASON TO RESYNC CMP #SYNC_ACK BNE SYNC LDA ACIACR,X CMP #$0B BNE SYNC LDA ACIAMR,X CMP #$10 BNE SYNC LDA PDUNIT ; FORMAT COMMAND FOR SIDRIVE AND SEND IT ASL LDA PDCMD ROL ASL ORA #$A0 JSR SENDACC CLC ADC #$01 STA CMDACK,Y LDA PDBLKL JSR SENDACC LDA PDBLKH JSR SENDACC CHKACK: JSR RECVACC ; WAIT FOR CORRECT ACK (MAY BE OUTSTANDING A2PI REQUESTS) CMP CMDACK,Y BNE CHKACK ;* ;* BRANCH TO COMMAND HANDLER ;* LDY PDCMD ; CPY #PDSTATUS BEQ STATUS DEY ; CPY #PDREAD BEQ RDBLK DEY ; CPY #PDWRITE BEQ WRBLK .IFDEF DEBUG LDA #'?' STA INDCTR+6 .ENDIF IOERR: LDA #PDIOERR RTS ;* ;* SIDRIVE STATUS - RETURN NUMBER OF BLOCKS OR NODEV ;* STATUS: .IFDEF DEBUG LDA #'S'-$40 STA INDCTR+3 .ENDIF LDA IOSLOT AND #$0F TAY JSR RECVACC STA SCRTCH6,Y JSR RECVACC STA SCRTCH7,Y JSR RECVACC PHA LDX SCRTCH6,Y LDA SCRTCH7,Y TAY PLA RTS ;* ;* READ A BLOCK (512 BYTES) FROM SIDRIVE ;* RDBLK: .IFDEF DEBUG LDA #'R'-$40 ; LDY #$00 STA INDCTR+4 .ENDIF RDBLKL: JSR RECVACC STA (PDBUFF),Y INY BNE RDBLKL INC PDBUFH RDBLKH: JSR RECVACC STA (PDBUFF),Y INY BNE RDBLKH JMP RECVACC ;* ;* WRITE A BLOCK (512 BYTES) TO SIDRIVE ;* WRBLK: .IFDEF DEBUG LDA #'W'-$40 ; LDY #$00 STA INDCTR+5 .ENDIF WRBLKL: LDA (PDBUFF),Y JSR SENDACC INY BNE WRBLKL INC PDBUFH WRBLKH: LDA (PDBUFF),Y JSR SENDACC INY BNE WRBLKH JMP RECVACC ;* ;* FILL REMAINING ROM WITH 0'S ;* .REPEAT $CF00-* DB $00 .ENDREP .ASSERT * = $CF00, error, "Code not page size" ;**************************************** ;* ;* SLOT INDEPENDENT ROM CODE @ $Cn00 ;* ;**************************************** ORG $C700 ; EASY SLOT ADDRESS TO ASSEMBLE ;* ;* AUTOSTART BOOT SIGNATURE ;* LDX #$20 LDY #$00 LDX #$03 STX $3C ;* ;* AUTOSTART/PR# ENTRYPOINT ;* .IFDEF DEBUG LDA #'*' STA INDCTR+7 .ENDIF PHP SEI STA XROMOFF JSR GETSLOT LDA #$00 STA SYNCED,Y ; CLEAR SYNCED FLAG ;* ;* CREATE COMMAND BUFFER FOR BOOT BLOCK ;* STX PDUNIT ; SLOT * 16, DEV 0 LDX #$00 STX PDBLKL STX PDBLKH STX PDBUFL INX ; LDX #PDREAD STX PDCMD LDX #$08 STX PDBUFH JSR SYNC BEQ BOOT PLP LDA $00 BEQ CONT RTS CONT: JMP $FABA ; JUMP BACK TO AUTOSTART BOOT SCANNER ROM BOOT: PLP JMP $801 ;* ;* PRODOS INTELLIGENT DEVICE ENTRYPOINT ;* CMDENTRY: PHP SEI STA XROMOFF JSR GETSLOT .IFDEF DEBUG LDA PDCMD ORA #'0' STA INDCTR+1 .ENDIF JSR DOCMD PLP PHA ; RESTORE ORIGINAL SLOT16 VALUE TYA PHA LDA IOSLOT AND #$0F TAY LDA SAVE16,Y ; SAVED ORIGINAL SLOT16 VALUE STA SLOT16 PLA TAY PLA ;* ;* CHECK FOR ERROR ;* BNE CMDERR CLC ; ALL GOOD, CLEAR ERROR FLAG RTS CMDERR: .IFDEF DEBUG PHA STA $2FF LDA #'E'-$40 STA INDCTR+2 : LDA KEYBD BPL :- STA STROBE CMP #'M'+$80 BNE :+ LDA ROMEN JMP MONITOR : PLA .ENDIF SEC ; SET ERROR FLAG RTS ENDCMD: .REPEAT $C700+250-* DB $00 .ENDREP DB "SI" ; SIGNATURE DW 0 ; USE STATUS TO GET SIZE DB $97 ; REMOVEABLE, 2 DEVICES, R/W DB