A2osX/SYS/KM.RAMWORKS.S.txt
2020-12-15 14:23:22 +01:00

673 lines
15 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.

NEW
AUTO 3,1
.LIST OFF
.OP 65C02
.OR $2000
.TF sys/km.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
*--------------------------------------
RW.SAVEZP0 .EQ $800
RW.SAVEZP1 .EQ $900
*--------------------------------------
RW.BLOCK .EQ $A00
*--------------------------------------
* A2OSX.SYSTEM relocated at $1000 !!!
*--------------------------------------
RWBankSelect .EQ $C073
*--------------------------------------
RW.Init >LDYAI RW.MSG
jsr PrintFYA
jsr RW.Detect1
bcs .10
>LDYAI RW.MSG.OK
jsr PrintFYA
rts
.10 jsr RW.Detect2
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.Detect1 jsr MLI
.DA #MLIONLINE
.DA RW.ONLINE
rts
*--------------------------------------
RW.ONLINE .DA #2
.DA #$B0 Slot 3,Drive 2
.DA RW.ONLINEBUFFER
RW.ONLINEBUFFER .BS 16
*--------------------------------------
RW.Detect2 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
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 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 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 #$B0 Slot 3,Drive 2,0=Not Removable, 0=no int, 00=1 Volume
sta DEVLST,x
lda #RWDRV.START
sta DEVPTRS3D2
lda /RWDRV.START
sta 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 #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)
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 #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 #$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 .AZ "RAMWorks (I,II,III,z-Ram) Driver For A2osX\n"
RW.MSG.OK .AZ "/RAM3 Device Already Installed.\n"
RW.MSG.OK1 .AZ "%D KB Detected (%d Pages), %D KB (%d Pages) Available for RamDrive.\n"
RW.MSG.KO1 .AZ "Not Detected.\n"
RW.MSG.OK2 .AZ "RamWorks Driver Installed.\n"
RW.MSG.KO2 .AZ "RamWorks Driver Install Error.\n"
RW.MSG.OK3 .AZ "RamWorks Drive Formatted as /RAM3.\n"
RW.MSG.KO3 .AZ "RamWorks Drive Format Error.\n"
*--------------------------------------
* 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
* 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
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 RD80STORE save 80 Store status
php Disable IRQ as no vector set in RW Banks
sei
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
*--------------------------------------
sta RWBankSelect Select RAMWorks Bank
sta CLR80STORE make sure SETREADAUX/SETWRITEAUX effective everywhere
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 SETREADAUX
ldx #DRV.A2L READ:copy from RAM to BUFF
lda #DRV.BUFF
bra RWDRV.RW
RWDRV.W sta 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 CLRREADAUX
sta CLRWRITEAUX
plp restore IRQ
bpl RMDRV.CMDSTATUS
sta 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 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
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
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
.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
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 CLRALTZP
jsr RWDRV.XM.RUN+RWDRVX.XM.SRCLC-RWDRVX.XM.START
sta $C000,x select proper Main/Aux ZP/LC
sta RWBankSelect
ldx #0
RWDRVX.XM.SRC lda $FFFF,x
sta RMDRVX.TMP,x
inx
bne RWDRVX.XM.SRC
sta CLRALTZP
jsr RWDRV.XM.RUN+RWDRVX.XM.DSTLC-RWDRVX.XM.START
sta $C000,x select proper Main/Aux ZP/LC
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 CLRALTZP
stz RWBankSelect
*--------------------------------------
RWDRVX.XM.MNLC bit RRAMWRAMBNK1 ProDOS always uses LCBANK1
* bit RRAMWRAMBNK1
lda #0
ldx #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 lda #$FF
bmi RWDRVX.XM.BANK
bit RRAMWRAMBNK2
* bit RRAMWRAMBNK2
RWDRVX.XM.BANK lda #$FF
ldx #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/KM.RAMWORKS.S
ASM