A2osX/A2osX.S.RW.txt

623 lines
14 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

PR#3
PREFIX /DATA/A2OSX
NEW
INC 1
AUTO 6
.LIST OFF
.OP 65C02
*--------------------------------------
RWBankSelect .EQ $C073
*--------------------------------------
A2osX.RamWorks >LDAXI MSG.RW
jsr PrintCStrAX
jsr RWDetect
bcs .10
>LDAXI MSG.RW.OK
jsr PrintCStrAX
bra A2osX.Z80
.10 jsr RWInit
bcc .1
>LDAXI MSG.RW.KO1
jsr PrintCStrAX
bra A2osX.Z80
.1 pha
>LDAXI MSG.RW.OK1
jsr PrintCStrAX
jsr RWInstall
bcc .2
>LDAXI MSG.RW.KO2
jsr PrintCStrAX
bra A2osX.Z80
.2 >LDAXI MSG.RW.OK2
jsr PrintCStrAX
jsr RWFormat
bcc .3
>LDAXI MSG.RW.KO3
jsr PrintCStrAX
bra A2osX.Z80
.3 >LDAXI MSG.RW.OK3
jsr PrintCStrAX
*--------------------------------------
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
*--------------------------------------
MSG.RW >CSTRING "Detecting Ramworks Card..."
MSG.RW.OK >CSTRING "Already Installed as /RAM31.\n"
MSG.RW.OK1 >CSTRING "%d Pages Detected.\n"
MSG.RW.OK2 >CSTRING "RamWorks Driver Installed.\n"
MSG.RW.OK3 >CSTRING "RamWorks Drive Formatted.\n"
MSG.RW.KO1 >CSTRING "Not Detected.\n"
MSG.RW.KO2 >CSTRING "RamWorks Driver Install Error.\n"
MSG.RW.KO3 >CSTRING "RamWorks Drive Format Error.\n"
*--------------------------------------
* 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