PR#3 PREFIX /A2OSX.SRC NEW INC 1 AUTO 6 .LIST OFF .OP 65C02 .OR $2000 .TF /A2OSX.BOOT/SYS/KM.VSDRIVE *-------------------------------------- .INB /A2OSX.DEV/INC/MACROS.I .INB /A2OSX.DEV/INC/IO.I .INB /A2OSX.DEV/INC/MONITOR.I .INB /A2OSX.DEV/INC/PRODOS.I *-------------------------------------- TmpPtr1 .EQ $0 TmpPtr2 .EQ $2 VS.CMD .EQ $C5 "E": Virtual Drive Command Envelope DRV.EntryPoint .EQ $BF41 *-------------------------------------- .INB DRV/X.SER.6551.S *-------------------------------------- VSDRIVE.Init >LDAXI VSDRIVE.MSG0 jsr PrintCStrAX jsr VSDRIVE.Check bcc .1 >LDAXI VSDRIVE.MSG1 jsr PrintCStrAX rts .1 jsr SSC.Detect bcc .2 >LDAXI VSDRIVE.MSG2 jsr PrintCStrAX rts .2 sta DRV+2 DRV.Slotn0 lsr lsr lsr lsr pha >LDAXI VSDRIVE.MSG3 jsr PrintCStrAX jsr VSDRIVE.SetSlot bcc .3 >LDAXI VSDRIVE.MSG4 jsr PrintCStrAX rts .3 pha save slot pha 2 times >LDAXI VSDRIVE.MSG5 jsr PrintCStrAX jsr VSDRIVE.Install >LDAXI VSDRIVE.MSG6 jsr PrintCStrAX >DEBUG rts *-------------------------------------- VSDRIVE.Check bit RRAMWRAMBNK2 bit RRAMWRAMBNK2 clc lda $D001 eor DRV bne .8 lda $D002 eor DRV+1 bne .8 sec .8 bit RROMBNK1 rts *-------------------------------------- SSC.Detect stz TmpPtr1 lda #$C1 sta TmpPtr1+1 .1 ldx #DEVSIG.Value-DEVSIG.Offset-1 .2 ldy DEVSIG.Offset,x lda (TmpPtr1),y cmp DEVSIG.Value,x bne .3 dex bpl .2 lda TmpPtr1+1 asl asl asl asl tax stz SSC.RESET,x lda #SSC.CTL.B115200+SSC.CTL.8D+SSC.CTL.1S+SSC.CMD.NOP sta SSC.CTL,x lda #SSC.CMD.RIRQDIS sta SSC.CMD,x txa clc rts .3 inc TmpPtr1+1 no match, try next slot.... lda TmpPtr1+1 cmp #$C8 bne .1 .9 sec rts *-------------------------------------- VSDRIVE.Ping clc rts *-------------------------------------- * Find 2 free slots in DEVPTRS (D1 & D2) *-------------------------------------- VSDRIVE.SetSlot ldx #2 Starts at Slot1 .1 lda DEVPTRS,x Drive1 cmp DEVPTRS pointing to S0D1 NODEV ? bne .2 lda DEVPTRS+1,x cmp DEVPTRS+1 bne .2 lda DEVPTRS+16,x Drive2 cmp DEVPTRS bne .2 lda DEVPTRS+17,x cmp DEVPTRS+1 bne .2 lda #DRV.EntryPoint sta DEVPTRS,x sta DEVPTRS+16,x lda /DRV.EntryPoint sta DEVPTRS+1,x sta DEVPTRS+17,x txa asl asl asl ldy DEVCNT iny sta DEVLST,y add Drv1 ora #$80 iny sta DEVLST,y add Drv2 sty DEVCNT txa lsr clc rts .2 inx inx cpx #16 bne .1 rts sec from CPX *-------------------------------------- VSDRIVE.Install ldx #9 .1 lda ProDOS.PATCH,x sta DRV.EntryPoint,x dex bpl .1 bit RRAMWRAMBNK2 bit RRAMWRAMBNK2 ldx #DRV.SIZE .2 lda DRV-1,x sta $D000,x dex bne .2 bit RROMBNK1 clc rts *-------------------------------------- .INB X.PRINTF.S *-------------------------------------- DEVSIG.Offset .HS 05070B0C DEVSIG.Value .HS 38180131 VSDRIVE.MSG0 >CSTR "VSDRIVE (ADT Vitual Serial Hard Drive) Driver For A2osX\n" VSDRIVE.MSG1 >CSTR "VSDRIVE (Or other custom Driver) Already Installed.\n" VSDRIVE.MSG2 >CSTR "SSC Not Detected.\n" VSDRIVE.MSG3 >CSTR "SCC Found At Slot %d.\n" VSDRIVE.MSG4 >CSTR "No ProDOS device slot available.\n" VSDRIVE.MSG5 >CSTR "VSDRIVE Installed 2 devices at S%dD1 & S%dD2.\n" VSDRIVE.MSG6 >CSTR "VSDRIVE Driver Successfully Installed.\n" *-------------------------------------- * ProDOS $BE41->$BE4B Patch for switching to BANK2 (10 bytes) *-------------------------------------- ProDOS.PATCH .PH DRV.EntryPoint bit RRAMWRAMBNK2 jsr $D001 bit RRAMWRAMBNK1 rts .EP *-------------------------------------- * Driver *-------------------------------------- * OP = 2 : Write drv1 * OP = 3 : Read drv1 * OP = 4 : Write drv2 * OP = 5 : Read drv2 * CMD = $C5+OP+BLKLO+BLKHI+CHKSUM * DO NOT trash DRV.COMMAND...DRV.BLKNUM as ProDOS * reuses them after Block operation * A1,A2 are used by Disk II Driver, * so we use it safely as Tmp Ptr *-------------------------------------- DRV.A1L .EQ $3C DRV.A1H .EQ $3D DRV.A2L .EQ $3E DRV.A2H .EQ $3F DRV.COMMAND .EQ $42 DRV.UNITNUM .EQ $43 DRV.BUFF .EQ $44 DRV.BLKNUM .EQ $46 *-------------------------------------- DRV .EQ * .PH $D001 Main LC Bnk 2 $D001->$DFFF cld DRV.Slotn0 ldx #$ff Self Modified lda DRV.COMMAND S=0,R=1,W=2,F=3 beq .8 Status cmp #3 beq .81 Format .... bcs .9 more....IO error ora #2 W=2,R=3 ldx DRV.UNITNUM bpl .1 adc #2 CC from bcs .9 .1 jsr DRV.DO.CMD bcs .9 .8 ldx #$ff return Status ldy #$ff .81 lda #0 clc rts .9 lda #MLI.ERR.IO rts *-------------------------------------- DRV.DO.CMD sta DRV.CmdBuf.Cmd store cmd eor #VS.CMD eor DRV.BLKNUM eor DRV.BLKNUM+1 sta DRV.CmdBuf.Sum Compute & store CheckSum lda DRV.BLKNUM sta DRV.CmdBuf.BlkLo lda DRV.BLKNUM+1 sta DRV.CmdBuf.BlkHi lda DRV.BUFF sta DRV.A1L lda DRV.BUFF+1 inc sta DRV.A1H * send CMD+CS ldy #4 Send 5 bytes including Sum .1 lda DRV.CmdBuf.Sum,y jsr DRV.SSCSend bcs .9 dey bpl .1 * read back CMD ldy #3 Read Back and check 4 bytes .2 jsr DRV.SSCGet bcs .9 cmp DRV.CmdBuf.BlkHi,y bne .9 dey bpl .2 * Get ProDOS Date/time send from server if READ (3 or 5) lda DRV.COMMAND dec 1-1=0 if read bne .6 go write * Read block : Discard ProDOS time recieved from Server (4 bytes) ldy #4 Read 4 bytes .3 jsr DRV.SSCGet bcs .9 eor DRV.CmdBuf.Sum sta DRV.CmdBuf.Sum dey bne .3 * recieve Header Sum and check jsr DRV.SSCGet bcs .9 eor DRV.CmdBuf.Sum bne .9 * tay Y=0 from dey/bne .4 jsr DRV.SSCGet bcs .9 sta (DRV.BUFF),y iny bne .4 .5 jsr DRV.SSCGet bcs .9 sta (DRV.A1L),y iny bne .5 jsr DRV.BufCheckSum sta DRV.CmdBuf.Sum jsr DRV.SSCGet bcs .9 eor DRV.CmdBuf.Sum bne .9 rts A=0,CC from bcs .9 * Write Block .6 ldy #0 .7 lda (DRV.BUFF),y jsr DRV.SSCSend bcs .9 iny bne .7 .8 lda (DRV.A1L),y jsr DRV.SSCSend bcs .9 iny bne .8 jsr DRV.BufCheckSum sta DRV.CmdBuf.Sum Save Block CheckSum for comparing later jsr DRV.SSCSend bcs .9 ldy #4 Read 5 bytes (echo from server) .81 jsr DRV.SSCGet bcs .9 eor DRV.CmdBuf.Sum,y Check 5 bytes (including block Sum) bne .9 dey bpl .81 rts .9 DRV.CS sec rts *-------------------------------------- DRV.CmdBuf.Sum .BS 1 Reverse order for dey DRV.CmdBuf.BlkHi .BS 1 DRV.CmdBuf.BlkLo .BS 1 DRV.CmdBuf.Cmd .BS 1 DRV.CmdBuf.Env .DA #VS.CMD *-------------------------------------- DRV.BufCheckSum lda #0 tay .1 eor (DRV.BUFF),y eor (DRV.A2L),y iny bne .1 rts *-------------------------------------- DRV.SSCSend sta .2+1 .1 lda SSC.STATUS,x bit #SSC.STATUS.DCD+SSC.STATUS.DSR beq DRV.CS and #SSC.STATUS.TDRE Outgoing char? beq .1 .2 lda #$ff sta SSC.DATA,x clc rts *-------------------------------------- DRV.SSCGet .1 lda SSC.STATUS,x bit #SSC.STATUS.DCD+SSC.STATUS.DSR beq DRV.CS and #SSC.STATUS.RDRF incoming char? beq .1 lda SSC.DATA,x clc rts *-------------------------------------- .EP *-------------------------------------- .LIST ON DRV.SIZE .EQ *-DRV .LIST OFF *-------------------------------------- * CONTROL SECTION : *-------------------------------------- .DO DRV.SIZE>255 * ERROR:DRV.SIZE too big .FIN *-------------------------------------- MAN SAVE SYS/KM.VSDRIVE.S ASM