NEW AUTO 3,1 .LIST OFF .OP 65C02 .OR $2000 .TF sys/pm.ramworks *-------------------------------------- .INB inc/macros.i .INB inc/io.i .INB inc/monitor.i .INB inc/mli.i .INB inc/mli.e.i *-------------------------------------- TmpPtr1 .EQ $0 TmpPtr2 .EQ $2 Type .EQ $4 *-------------------------------------- RW.SAVEZP0 .EQ $2800 RW.SAVEZP1 .EQ $2900 *-------------------------------------- RW.BLOCK .EQ $2A00 RW.ONLINEBUFFER .EQ $2C00 *-------------------------------------- * A2OSX.SYSTEM relocated at $1000 !!! *-------------------------------------- SEBankSelect .EQ $C071 RWBankSelect .EQ $C073 *-------------------------------------- RW.Init >LDYAI RW.MSG jsr PrintFYA jsr RW.CheckRAM3 bcs .5 >LDYAI RW.MSG.RAM3OK jsr PrintFYA rts .5 jsr RW.DisableRAM bcc .10 >LDYAI RW.MSG.RAMDISKO jsr PrintFYA rts .10 >LDYAI RW.MSG.RAMDISOK jsr PrintFYA lda #RWBankSelect jsr RW.DetectHW bcc .1 lda #SEBankSelect jsr RW.DetectHW bcc .1 >LDYAI RW.MSG.KO1 bra .9 .1 tay save RAM drive pages pha lsr divide by 4 to compute KB size ror .12+1 lsr ror .12+1 .12 ldx #$00 X,A = RAM drive size phx Push Kbyte LO pha Push Kbyte HI tya inc + 1 page AUX mem pha Total page detected lsr divide by 4 to compute KB size ror .11+1 lsr ror .11+1 .11 ldx #$00 X,A = Total KB detected phx Push Kbyte LO pha Push Kbyte HI >LDYAI RW.MSG.OK1 jsr PrintFYA jsr RW.Install bcc .2 >LDYAI RW.MSG.KO2 bra .9 .2 >LDYAI RW.MSG.OK2 jsr PrintFYA jsr RW.Format bcc .3 >LDYAI RW.MSG.KO3 bra .9 .3 >LDYAI RW.MSG.OK3 .9 jsr PrintFYA rts *-------------------------------------- RW.CheckRAM3 jsr RW.ONLINE MLI Online at S3D2 bcs .9 lda RW.ONLINEBUFFER and #$0F cmp #4 'RAM3' ? sec bne .9 tax .1 lda RW.ONLINEBUFFER,x eor RW.MSG.RAM3OK,x asl ignore b7 bne .9 dex bne .1 clc .9 rts *-------------------------------------- RW.DisableRAM lda GP.DEVPTRS3D2 cmp GP.DEVPTRS S0D1=NOVEV bne .1 lda GP.DEVPTRS3D2+1 cmp GP.DEVPTRS+1 S0D1=NODEV beq .8 S3D2=NODEV, nothing to do .1 ldx GP.DEVCNT .2 lda GP.DEVLST,x LOOKING FOR $BF, $BB, $B7, $B3 and #$F3 cmp #$B3 beq .3 dex bpl .2 sec No device found, exit with error rts .3 cpx GP.DEVCNT beq .5 .4 lda GP.DEVLST+1,x sta GP.DEVLST,x inx cpx GP.DEVCNT bne .4 .5 ldx GP.DEVCNT stz GP.DEVLST,x dec GP.DEVCNT lda GP.DEVPTRS sta GP.DEVPTRS3D2 lda GP.DEVPTRS+1 sta GP.DEVPTRS3D2+1 jsr RW.ONLINE .8 clc Success!! rts *-------------------------------------- RW.ONLINE jsr MLI .DA #MLI.ONLINE .DA RW.ONLINEPARAM rts *-------------------------------------- RW.ONLINEPARAM .DA #2 .DA #$B0 Slot 3,Drive 2 .DA RW.ONLINEBUFFER *-------------------------------------- RW.DetectHW php sei sta Type sta .1+1 sta .2+1 sta .3+1 sta .6+1 sta IO.SETALTZP ldx #0 start detection at page $00 .1 stx RWBankSelect lda 0 sta RW.SAVEZP0,x save Bank 0 $0000 to prevent ALTZP trash lda 1 sta RW.SAVEZP1,x inx bpl .1 lda #0 .2 sta RWBankSelect *-------------------------------------- * Added after David Finnigan from macgui.com testing sessions * pha pla * * to address possibly a timing issue with Accelerators *-------------------------------------- sta 0 eor #$FF sta 1 eor #$FF inc bpl .2 ldx #0 .3 stx RWBankSelect *-------------------------------------- * Added after David Finnigan from macgui.com testing sessions * pha pla * * to address possibly a timing issue with Accelerators *-------------------------------------- lda 0 tay eor #$ff cmp 1 bne .4 inx cpy #127 bne .3 .4 ldy #127 X = detected page count .6 sty RWBankSelect lda RW.SAVEZP0,y sta 0 lda RW.SAVEZP1,y sta 1 dey bpl .6 sta IO.CLRALTZP plp txa PGCNT > 0 ? beq .9 dec minus 1 for AUX mem beq .9 sta RW.PGCNT PGCNT = last detected page clc rts .9 sec rts *-------------------------------------- RW.Install lda IO.RRAMWRAMBNK1 lda IO.RRAMWRAMBNK1 ldx #RWDRV.SIZE .1 lda RWDRV.B.START-1,x sta RWDRV.START-1,x dex bne .1 lda RW.PGCNT lsr sta RWDRV.MAXHI+1 lda #0 ror sta RWDRV.MAXLO+1 lda Type sta RWDRV.IO1+1 sta RWDRV.EXIT+1 lda IO.RROMBNK1 sta IO.SETWRITEAUX ldx #RWDRVX.SIZE .2 lda RWDRVX.B.START-1,x sta RWDRVX.START-1,x dex bne .2 lda Type sta RWDRVX.XM.IO1+1 sta RWDRVX.XM.IO2+1 sta RWDRVX.XM.IO3+1 sta IO.CLRWRITEAUX inc GP.DEVCNT ldx GP.DEVCNT lda #$B0 Slot 3,Drive 2,0=Not Removable, 0=no int, 00=1 Volume sta GP.DEVLST,x lda #RWDRV.START sta GP.DEVPTRS3D2 lda /RWDRV.START sta GP.DEVPTRS3D2+1 clc rts *-------------------------------------- RW.Format jsr RW.BLOCK.SET00 lda RW.PGCNT lsr sta RW.BLOCK2.TB+1 lda #0 ror sta RW.BLOCK2.TB jsr MLI .DA #MLI.GETTIME .DA 0 ldx #3 .1 lda GP.DATE,x sta RW.BLOCK2.CT,x dex bpl .1 ldx #RW.BLOCK2.END-RW.BLOCK2 .2 lda RW.BLOCK2-1,x sta RW.BLOCK-1,x dex bne .2 jsr MLI Write Block 2,First VOL directory block .DA #MLI.WRITEBLOCK .DA RW.MLIWRITEBLOCK bcc .22 rts *-------------------------------------- .22 jsr RW.BLOCK.SET00 lda #2 sta RW.BLOCK LO byte of previous block pointer inc RW.MLIWRITEBLOCK.BLK jsr MLI Write Block 3,Last VOL directory block .DA #MLI.WRITEBLOCK .DA RW.MLIWRITEBLOCK bcc .33 rts *-------------------------------------- .33 lda RW.PGCNT divide RW.PGCNT by 32 to get how many bitmap lsr blocks we need : lsr 1 page = 128 blocks = 16 bytes lsr 32 pages = 512 bytes = 1 Block lsr lsr sta RW.FBITMAPCNT store FULL bitmap block count needed tax lda RW.PGCNT and #$1F need an extra incomplete bitmap block? beq .3 inx .3 stx RW.BITMAPCNT store TOTAL bitmap block needed .4 lda RW.FBITMAPCNT beq .49 dec RW.FBITMAPCNT jsr RW.BLOCK.SETFF bra .5 .49 jsr RW.BLOCK.SET00 lda RW.PGCNT and #$1F compute incomplete bitmap block asl asl asl asl times 16 for byte count tay lda #$FF bcc .42 first half of block only ldx #0 .40 sta RW.BLOCK,x inx bne .40 cpy #0 beq .5 .41 sta RW.BLOCK+$ff,y dey bne .41 bra .5 .42 sta RW.BLOCK-1,y dey bne .42 .5 inc RW.MLIWRITEBLOCK.BLK lda RW.MLIWRITEBLOCK.BLK cmp #4 Are we writing first volume bitmap ? bne .63 no, regular one * lda #$CF Mark Block 0 & 1 free, 2,3 used (vol hdr) lda #$0F sta RW.BLOCK ldy #0 lda #$8 Start a BLOCK 4 (%00001000) ldx RW.BITMAPCNT .62 pha eor RW.BLOCK,y Mark bitmap blocks as "used" sta RW.BLOCK,y pla dex beq .63 lsr bne .62 lda #$80 iny bra .62 .63 jsr MLI Write Block 4,5... .DA #MLI.WRITEBLOCK .DA RW.MLIWRITEBLOCK bcs .9 dec RW.BITMAPCNT another bitmap block needed ? bne .4 clc .9 rts *-------------------------------------- RW.BLOCK.SETFF lda #$FF .HS 2C BIT ABS RW.BLOCK.SET00 lda #$00 ldx #0 .1 sta RW.BLOCK,x sta RW.BLOCK+$100,x inx bne .1 rts *-------------------------------------- RW.MLIWRITEBLOCK .DA #3 .DA #$B0 Slot 3,Drive 2 .DA RW.BLOCK RW.MLIWRITEBLOCK.BLK .DA 2 Start writing block at #2 *-------------------------------------- RW.PGCNT .BS 1 RW.FBITMAPCNT .BS 1 RW.BITMAPCNT .BS 1 *-------------------------------------- RW.BLOCK2 .DA 0 pointer to previous block .DA 3 pointer to next block .DA #$F4 $F=Vol Dir Header, 4=name len .AS 'RAM3' .BS 11 (RAM3 len=4, fill to 15) .HS 0000000000000000 RW.BLOCK2.CT .BS 4 Creation time .HS 0100C3270D version/min version/access/EL/EPB .DA 0 File Count .DA 4 bitmap pointer (Block 2&3 are Volume directory) RW.BLOCK2.TB .BS 2 Total Blocks RW.BLOCK2.END .EQ * *-------------------------------------- .INB usr/src/shared/x.printf.s *-------------------------------------- RW.MSG .CZ "SuperExpander E, RAMWorks (I,II,III,z-Ram) Driver For A2osX\r" RW.MSG.RAMDISOK .CZ "/RAM Device Disabled/Not Present.\r" RW.MSG.RAMDISKO .CZ "Problem Disabling /RAM Device.\r" RW.MSG.RAM3OK .CZ "/RAM3 Device Already Installed.\r" RW.MSG.OK1 .CZ "%D KB Detected (%d Pages), %D KB (%d Pages) Available for RamDrive.\r" RW.MSG.KO1 .CZ "Not Detected.\r" RW.MSG.OK2 .CZ "RamWorks Driver Installed.\r" RW.MSG.KO2 .CZ "RamWorks Driver Install Error.\r" RW.MSG.OK3 .CZ "RamWorks Drive Formatted as /RAM3.\r" RW.MSG.KO3 .CZ "RamWorks Drive Format Error.\r" *-------------------------------------- * Driver for Ramworks in main LC * $FF00 -> $FF9A (Inclusive) * $FF58 MUST BE $60 (RTS) * DO NOT trash DRV.COMMAND...DRV.BLKNUM as ProDOS * reuses it after Block operation * A1,A2 are used by Disk II Driver, * so we use it safely as Tmp Ptr *-------------------------------------- DRV.A2L .EQ $3E DRV.A2H .EQ $3F DRV.COMMAND .EQ $42 DRV.BUFF .EQ $44 DRV.BLKNUM .EQ $46 *-------------------------------------- RWDRV.B.START .PH $FF00 RWDRV.START ldy DRV.COMMAND 0 = Status ? beq RMDRV.CMDSTATUS cpy #3 beq RWDRV.EXITOK 3 = Format : nothing to do, exit with no error bcs RWDRV.IOERR > 3 = Invalid OP, IO error ldx DRV.BLKNUM cpx RWDRV.MAXLO+1 lda DRV.BLKNUM+1 sbc RWDRV.MAXHI+1 bcs RWDRV.IOERR DRV.BLKNUM >= RW.DRV.SIZE, IO error bit IO.RD80STORE save 80 Store status php Disable IRQ as no vector set in RW Banks sei sta IO.CLR80STORE make sure SETREADAUX/SETWRITEAUX effective everywhere txa Get Back DRV.BLKNUM asl compute PAGE = blocknumLO *2 pha lda DRV.BLKNUM+1 compute BANK = blocknumHI *2 rol inc +1 for skipping Aux BANK 0 plx move page into X beq RWDRV.GOAUX move from/to aux page0/1 cpx #$C0 bcs RWDRV.GOAUX move from/to aux LC *-------------------------------------- * X=Page($02 -> $BF),A=Bank,Y=CMD *-------------------------------------- RWDRV.IO1 sta RWBankSelect Select RAMWorks Bank inx second 256 bytes first stx DRV.A2H Use DRV.A1L/H for RAM PTR stz DRV.A2L inc DRV.BUFF+1 dey Y=CMD, zero if read bne RWDRV.W non zero, go write sta IO.SETREADAUX ldx #DRV.A2L READ:copy from RAM to BUFF lda #DRV.BUFF bra RWDRV.RW RWDRV.W sta IO.SETWRITEAUX ldx #DRV.BUFF lda #DRV.A2L WRITE:copy from BUFF to RAM dey Make sure Y=0 for main loop below RWDRV.RW stx RWDRV.RW.SRC+1 sta RWDRV.RW.DST+1 * clc 2 pages to copy .HS B0 BCS RWDRV.RW.LOOP sec RWDRV.RW.SRC lda ($FF),y RWDRV.RW.DST sta ($FF),y iny bne RWDRV.RW.SRC dec DRV.BUFF+1 dec DRV.A2H bcc RWDRV.RW.LOOP RWDRV.EXIT stz RWBankSelect sta IO.CLRREADAUX sta IO.CLRWRITEAUX plp restore IRQ bpl RMDRV.CMDSTATUS sta IO.SET80STORE RMDRV.CMDSTATUS RWDRV.MAXLO ldx #$FF return device block count in X,Y... RWDRV.MAXHI ldy #$FF RWDRV.EXITOK lda #0 make A=0 clc rts RWDRV.IOERR lda #MLI.E.IO Carry already set rts *-------------------------------------- * X=Page(0/1 or LC),A=Bank *-------------------------------------- RWDRV.GOAUX pha save BANK sta IO.SETWRITEAUX ldy #RWDRVX.XM.SIZE Backup begining of $300 to generate move code .1 lda RWDRV.XM.RUN-1,y sta RWDRVX.XM.SAVE-1,y dey bne .1 pla restore BANK sta IO.SETREADAUX jsr RWDRVX.START Setup Code in main mem at $300 for data move * returns : CC=WRITE, CS=READ sta IO.CLRREADAUX IO.CLRWRITEAUX already triggered by code copy jsr RWDRV.XM.RUN Now execute generated code in main memory sta IO.SETREADAUX jmp RWDRVX.RESTORE RWDRV.END .EP RWDRV.B.END .LIST ON RWDRV.SIZE .EQ RWDRV.B.END-RWDRV.B.START .LIST OFF *-------------------------------------- * Driver for Ramworks in aux memory * $0200 -> $02FF TMP buffer for PAGE copy * $0300 -> $03FD (Inclusive) * do not trash $03FE-$03FF (IRQ Vector) * X=Page(0/1 or LC),A=Bank *-------------------------------------- RMDRVX.TMP .EQ $200 RWDRV.XM.RUN .EQ $300 *-------------------------------------- RWDRVX.B.START .PH $0300 RWDRVX.START sta RWDRVX.XM.BANK+1 setup BANK lda DRV.COMMAND DRV.COMMAND: 1=READ,2=WRITE lsr php ldy #IO.RRAMWRAMBNK1 txa beq .1 page 0/1, no need to check BANK cmp #$D0 $C0 <= PAGE < $D0 ? bcs .1 no, store in BNK1 ora #$10 Remap $C0 page to $D0 BNK2 ldy #IO.RRAMWRAMBNK2 .1 sty RWDRVX.XM.RWLC+1 Save to select proper RW bank later ldy DRV.BUFF ldx DRV.BUFF+1 plp bcc .2 CC=WRITE, CS=READ stz RWDRVX.XM.SRC+1 READ from src LO = 0 sta RWDRVX.XM.SRC+2 READ from src HI = PAGE sty RWDRVX.XM.DST+1 WRITE to DRV.BUFF stx RWDRVX.XM.DST+2 bra .3 .2 sty RWDRVX.XM.SRC+1 READ from DRV.BUFF stx RWDRVX.XM.SRC+2 stz RWDRVX.XM.DST+1 WRITE to dst LO = 0 sta RWDRVX.XM.DST+2 WRITE to dst HI = PAGE .3 sta IO.CLRWRITEAUX ldy #RWDRVX.XM.SIZE .4 lda RWDRVX.XM.START-1,y sta RWDRV.XM.RUN-1,y dey bne .4 rts *-------------------------------------- * Called form Main LC after RWDRVX.XM execution *-------------------------------------- RWDRVX.RESTORE ldy #RWDRVX.XM.SIZE Now, restore begining of $300 .1 lda RWDRVX.XM.SAVE-1,y sta RWDRV.XM.RUN-1,y dey bne .1 jmp RWDRV.EXIT *-------------------------------------- * LC Copy Code, moved from Aux to main $300 * $0200 -> $02FF TMP buffer for 2 steps move between LCs * CC=WRITE : * CS=READ : *-------------------------------------- RWDRVX.XM.START ldy #2 2 pages to copy RWDRVX.XM.COPY sta IO.CLRALTZP jsr RWDRV.XM.RUN+RWDRVX.XM.SRCLC-RWDRVX.XM.START sta $C000,x select proper Main/Aux ZP/LC RWDRVX.XM.IO1 sta RWBankSelect ldx #0 RWDRVX.XM.SRC lda $FFFF,x sta RMDRVX.TMP,x inx bne RWDRVX.XM.SRC sta IO.CLRALTZP jsr RWDRV.XM.RUN+RWDRVX.XM.DSTLC-RWDRVX.XM.START sta $C000,x select proper Main/Aux ZP/LC RWDRVX.XM.IO2 sta RWBankSelect ldx #0 RWDRVX.XM.2 lda RMDRVX.TMP,x RWDRVX.XM.DST sta $FFFF,x inx bne RWDRVX.XM.2 inc RWDRV.XM.RUN+RWDRVX.XM.SRC+2-RWDRVX.XM.START inc RWDRV.XM.RUN+RWDRVX.XM.DST+2-RWDRVX.XM.START dey bne RWDRVX.XM.COPY sta IO.CLRALTZP RWDRVX.XM.IO3 stz RWBankSelect *-------------------------------------- RWDRVX.XM.MNLC bit IO.RRAMWRAMBNK1 ProDOS always uses LCBANK1 lda #0 ldx #IO.CLRALTZP rts *-------------------------------------- RWDRVX.XM.SRCLC bcc RWDRVX.XM.MNLC CC=WRITE,CS=READ? .HS 2C BIT ABS RWDRVX.XM.DSTLC bcs RWDRVX.XM.MNLC CC=WRITE,CS=READ? *-------------------------------------- RWDRVX.XM.RWLC bit $C000 RWDRVX.XM.BANK lda #$FF ldx #IO.SETALTZP rts *-------------------------------------- .LIST ON RWDRVX.XM.SIZE .EQ *-RWDRVX.XM.START .LIST OFF *-------------------------------------- RWDRVX.XM.SAVE .BS RWDRVX.XM.SIZE *-------------------------------------- .EP *-------------------------------------- RWDRVX.B.END .LIST ON RWDRVX.SIZE .EQ RWDRVX.B.END-RWDRVX.B.START .LIST OFF *-------------------------------------- * CONTROL SECTION : *-------------------------------------- .DO RWDRV.SIZE>$9B ERROR:RWDRV.SIZE too big .FIN .DO RWDRVX.SIZE>$FE ERROR:RWDRVX.SIZE too big .FIN .DO RWDRVX.XM.SIZE>$F0 ERROR:RWDRVX.XM.SIZE too big .FIN *-------------------------------------- MAN SAVE usr/src/sys/pm.ramworks.s ASM