PR#3 PREFIX /DATA/A2OSX NEW INC 1 AUTO 6 .LIST OFF .OP 65C02 *-------------------------------------- RWBankSelect .EQ $C073 *-------------------------------------- RWDetect jsr MLI .DA #MLIONLINE .DA RW.ONLINE rts *-------------------------------------- RW.ONLINE .DA #2 .DA #$30 Slot 3,Drive 1 .DA RW.ONLINEBUFFER RW.ONLINEBUFFER .BS 16 *-------------------------------------- RWInit php sei sta 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 bne .1 lda #0 .2 sta RWBankSelect sta 0 eor #$FF sta 1 eor #$FF inc bne .2 ldx #0 .3 txa sta RWBankSelect cmp 0 bne .4 eor #$FF cmp 1 bne .4 inx bne .3 dex we reached 0,last detected page was 255 .4 ldy #255 X = detected page count .6 sty RWBankSelect lda RW.SAVEZP0,y sta 0 lda RW.SAVEZP1,y sta 1 dey bne .6 stz RWBankSelect lda RW.SAVEZP0 Don't forget to restore Bank 0 sta 0 lda RW.SAVEZP1 sta 1 txa stx RW.PGCNT PGCNT = last detected page, as we do -1 for AuxMem sta CLRALTZP plp lda RW.PGCNT beq .9 clc rts .9 sec rts *-------------------------------------- * *-------------------------------------- RWInstall lda RRAMWRAMBNK1 lda 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 RROMBNK1 sta SETWRITEAUX ldx #RWDRVX.SIZE .2 lda RWDRVX.B.START-1,x sta RWDRVX.START-1,x dex bne .2 sta CLRWRITEAUX inc DEVCNT ldx DEVCNT lda #$30 Slot 3,Drive 1 sta DEVLST,x lda #RWDRV.START sta DEVPTRS3D1 lda /RWDRV.START sta DEVPTRS3D1+1 clc rts *-------------------------------------- * *-------------------------------------- RWFormat jsr RW.BLOCK.SET00 lda RW.PGCNT lsr sta RW.BLOCK2.TB+1 lda #0 ror sta RW.BLOCK2.TB jsr MLI .DA #MLIGETTIME .DA 0 ldx #3 .1 lda DATELO,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 #MLIWRITEBLOCK .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 #MLIWRITEBLOCK .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) 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 #MLIWRITEBLOCK .DA RW.MLIWRITEBLOCK bcs .9 dec RW.BITMAPCNT another bitmap block needed ? bne .4 clc .9 rts *-------------------------------------- RW.BLOCK.SETFF lda #$FF bra RW.BLOCK.SET RW.BLOCK.SET00 lda #$00 RW.BLOCK.SET ldx #0 .1 sta RW.BLOCK,x sta RW.BLOCK+$100,x inx bne .1 rts *-------------------------------------- RW.MLIWRITEBLOCK .DA #3 .DA #$30 Slot 3,Drive 1 .DA RW.BLOCK RW.MLIWRITEBLOCK.BLK .DA 2 Start writing block at #2 *-------------------------------------- RW.RAM31 .DA #$30 .DA #5 len=5 chars .AS 'RAM31' *-------------------------------------- RW.PGCNT .BS 1 RW.FBITMAPCNT .BS 1 RW.BITMAPCNT .BS 1 RW.SAVEZP0 .BS 256 RW.SAVEZP1 .BS 256 *-------------------------------------- RW.BLOCK2 .DA 0 pointer to previous block .DA 3 pointer to next block .DA #$F5 $F=Vol Dir Header, 5=name len .AS 'RAM31' .BS 10 (RAM31 len=5, 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 * *-------------------------------------- RW.BLOCK .BS 512 *-------------------------------------- * Driver for Ramworks in main LC * $FF00 -> $FF9A (Inclusive) * $FF58 MUST BE $60 (RTS) * DO NOT trash DRV.BLKNUM as ProDOS * reuses it after Block operation *-------------------------------------- DRV.COMMAND .EQ $42 DRV.BUFF .EQ $44 DRV.BLKNUM .EQ $46 *-------------------------------------- RWDRV.B.START .PH $FF00 RWDRV.START cld ProDOS will check that byte!!! 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 lda DRV.BLKNUM sec sbc RWDRV.MAXLO+1 lda DRV.BLKNUM+1 sbc RWDRV.MAXHI+1 bcs RWDRV.IOERR DRV.BLKNUM >= RW.DRV.SIZE, IO error lda DRV.BLKNUM compute PAGE = blocknumLO *2 asl 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 *-------------------------------------- php sei Disable IRQ as no vector set in RW Banks sta RWBankSelect Select RAMWorks Bank sta CLR80STORE make sure SETREADAUX/SETWRITEAUX effective everywhere stx DRV.COMMAND+1 Reuse DRV.COMMAND for RAM PTR stz DRV.COMMAND dey Y=CMD, zero if read bne RWDRV.W CC, go write sta SETREADAUX ldx #DRV.COMMAND READ:copy from RAM to BUFF ldy #DRV.BUFF bra RWDRV.RW RWDRV.W sta SETWRITEAUX ldx #DRV.BUFF ldy #DRV.COMMAND WRITE:copy from BUFF to RAM RWDRV.RW stx RWDRV.RW.SRC+1 sty RWDRV.RW.DST+1 ldx #2 2 pages to copy ldy #0 RWDRV.RW.SRC lda ($FF),y RWDRV.RW.DST sta ($FF),y iny bne RWDRV.RW.SRC .HS 24 BIT Zero Page to skip RTS RWDRV.RTS rts $FF58 Must Be RTS inc DRV.BUFF+1 inc DRV.COMMAND+1 dex bne RWDRV.RW.SRC stz RWBankSelect sta CLRREADAUX sta CLRWRITEAUX plp 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.ERR.IO Carry already set rts *-------------------------------------- * X=Page(0/1 or LC),A=Bank *-------------------------------------- RWDRV.GOAUX pha save BANK sta 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 SETREADAUX jsr RWDRVX.START Setup Code in main mem at $300 for data move * returns : CC=WRITE, CS=READ sta CLRREADAUX CLRWRITEAUX already triggered by code copy jsr RWDRV.XM.RUN Now execute generated code in main memory sta SETREADAUX jsr RWDRVX.RESTORE sta CLRREADAUX rts A & carry setup properly by RWDRVX.RESTORE RWDRV.END .EP RWDRV.B.END RWDRV.SIZE .EQ RWDRV.B.END-RWDRV.B.START *-------------------------------------- * 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 txa beq .1 page 0/1, no need to check BANK cmp #$D0 $C0 <= PAGE < $D0 ? bcc .1 no, store in BNK1 ora #$10 Remap $C0 page to $D0 BNK2 .1 ror RWDRVX.XM.RWLC+1 Save Carry to select proper RW bank later ldy DRV.BUFF ldx DRV.BUFF+1 lsr DRV.COMMAND DRV.COMMAND: 1=READ,2=WRITE 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 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 tya setup A=0 and CC for exit with non error clc rts *-------------------------------------- * "auXMove" Code, moved from Aux to main $300 * $0200 -> $02FF TMP buffer for 2 steps moving between LCs * CC=WRITE : * CS=READ : *-------------------------------------- RWDRVX.XM.START php sei ldx #0 ldy #2 2 pages to copy RWDRVX.XM.COPY jsr RWDRV.XM.RUN+RWDRVX.XM.MNLC-RWDRVX.XM.START WRITE:copy from MAIN to TMP bcc RWDRVX.XM.SRC CC=WRITE,CS=READ? jsr RWDRV.XM.RUN+RWDRVX.XM.RWLC-RWDRVX.XM.START READ:copy from BANK to TMP sta SETALTZP RWDRVX.XM.SRC lda $FFFF,x sta RMDRVX.TMP,x inx bne RWDRVX.XM.SRC sta CLRALTZP jsr RWDRV.XM.RUN+RWDRVX.XM.MNLC-RWDRVX.XM.START READ:copy from TMP to MAIN bcs RWDRVX.XM.1 CC=WRITE,CS=READ? jsr RWDRV.XM.RUN+RWDRVX.XM.RWLC-RWDRVX.XM.START WRITE:copy from TMP to BANK sta SETALTZP RWDRVX.XM.1 lda RMDRVX.TMP,x RWDRVX.XM.DST sta $FFFF,x inx bne RWDRVX.XM.1 sta CLRALTZP 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 plp RWDRVX.XM.MNLC stz RWBankSelect ProDOS always uses LCBANK1 bit RRAMWRAMBNK1 bit RRAMWRAMBNK1 rts RWDRVX.XM.RWLC lda #$FF bpl RWDRVX.XM.BANK bit RRAMWRAMBNK2 bit RRAMWRAMBNK2 RWDRVX.XM.BANK lda #$FF sta RWBankSelect rts RWDRVX.XM.END *-------------------------------------- RWDRVX.XM.SIZE .EQ RWDRVX.XM.END-RWDRVX.XM.START *-------------------------------------- RWDRVX.XM.SAVE .BS RWDRVX.XM.SIZE *-------------------------------------- .EP *-------------------------------------- RWDRVX.B.END RWDRVX.SIZE .EQ RWDRVX.B.END-RWDRVX.B.START *-------------------------------------- * CONTROL SECTION : *-------------------------------------- .DO RWDRV.RTS=$FF58 .ELSE ERROR:RWDRV.RTS <> $FF58 .FIN .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 A2OSX.S.RW LOAD A2OSX.S ASM