NEW AUTO 3,1 *-------------------------------------- RAMX.DBuf .EQ $0C00 RAMX.vblock1 .EQ $0E00 ramdisk directory block *-------------------------------------- * /RAM driver (aux bank portion) * this code is packed into $200 length with no room for expansion !! * (see note at end of this obj) * after the main /RAM routine has determined that the command is ok and the * block to be read/written is within range, it transfers control to this * aux /RAM routine which remaps the block requested as follows: * request blocks 0,1: invalid * 2: returns VDIR (card block 3) * 3: returns BITMAP (synthesized) * 4: returns card block 0 * $05-$5F: returns card blocks $05-$5F * $60-$67: returns blocks $68-$7F in bank 1 of language card * $68-$7F: returns blocks $68-$7F in bank 2 of language card *-------------------------------------- RAMX.START .PH RAMX RAMX.START1 lda IO.RD80STORE read 80 store pha save for later sta IO.CLR80STORE turn off 80 store ldx #$04 move the parameters for use: L5109 lda ZP.CMDNUM,x cmd, unit, bufptr and block (lo) sta tcmd,x -> tcmd, tunit, R2L, R2H, R01 dex bpl L5109 and formatflg format the volume first time bne L514F thru, or when requested. ldx ZP.BLKNUM save R01 during format. lda /RAMX.vblock1 block to be cleared. jsr clrbuf1 clears all buffers. ldy #$03 format volume in 2 chunks. L511F lda VDIR,y sta RAMX.vblock1+4,y dey bpl L511F lda #$FE set last block as unusable sta BITMAP+15 to protect vectors. tya set bitmap bits to $FF. ldy #$0E 15 bytes to set L5130 sta BITMAP,y dey bne L5130 sty BITMAP first byte = 0. ldy #$07 do other chunk L513B lda access,y sta RAMX.vblock1+34,y dey bpl L513B lda formatflg if 0, set to $FF bne L51AA else exitcard. sty formatflg y = $FF, won't format next time. stx R01 restore R01 * use the requested block number to determine * which routine performs the transfer L514F asl R01 block requested -> page requested. lda R01 get page requested. cmp #$BF in language card ? bcs L5163 yes, do it. cmp #$06 bitmap ? bne L5160 jmp tbmap yes, transfer bitmap L5160 jmp treg else normal transfer. * when a block between $60 and $7F is requested, it must be spirited into/from * the language card area of the 64k card. this requires a 2 stage move: * into the temp buffer and then to it's real destination. L5163 tax save R1 for later. jsr setptr get direction php and save it. bcs L51B8 if it's a write. lcrd txa get R1 back cmp #$CF which bank is it in ? bcs L5173 in main bank. ora #$10 in secondary bank. bne L5179 branch always. L5173 sta IO.RRAMWRAMBNK2 turn on main $D000 sta IO.RRAMWRAMBNK2 L5179 sta R01 restore R1. lda R2H save R2 for later pha ldx R2L sta IO.SETALTZP use alternate zero page/stack lda /RAMX.DBuf set R2 to dbuf sta R2H lda #RAMX.DBuf sta R2L jsr setptr set pointers tay A > 0 from setptr L5194 lda (ZP.A1L),y move A1,A2 to A4,A3 sta (ZP.A4L),y lda (ZP.A2L),y sta (ZP.A3L),y dey bne L5194 sta IO.CLRALTZP use main zero page/stack L51A2 stx R2L pla restore R2 sta R2H plp get direction. L51AA bcs L51B5 write, done with move. sta IO.RRAMWRAMBNK1 switch in MLI part of LC sta IO.RRAMWRAMBNK1 jsr blockdo0 read, transfer dbuf to main L51B5 jmp exitcard L51B8 jsr blockdo0 transfer main to dbuf. jmp lcrd transfer dbuf to language card * blockdo0 transfers a block between main memory and the 64k card. R1 contains * the page address of the block in the card; R2 contains the page address of * the block in main memory. the address in main memory is always in the * language card, so the language card is always switched in. if cmd is 2, a * write is done (R2->R1); if cmd is 1, a read is done (R1->R2). blockdo0 lda /RAMX.DBuf set up R1 = dbuf blockdo1 sta R01 blockdo jsr setptr set pointers. bcs L51DB it's a write. sta IO.CLRWRITEAUX transfer buffer directly to main. tay 0 left from setptr. L51CC lda (ZP.A1L),y transfer A1,A2 to A4,A3 sta (ZP.A4L),y lda (ZP.A2L),y sta (ZP.A3L),y dey bne L51CC sta IO.SETWRITEAUX back the way it was. donewrt rts mainwrt returns here L51DB lda #mainwrt pointers set up, sta passit pass control to main ram lda /mainwrt jmp ex1 set passit+1 and transfer * setptr is used by other routines to set up pointers and dtect read or write setptr lda tcmd is it read or write ? lsr bcs L5208 taken if write. lda R2H destination page sta ZP.A4L+1 sta ZP.A3L+1 lda R2L sta ZP.A4L sta ZP.A3L lda R01 source page sta ZP.A1L+1 sta ZP.A2L+1 lda #$00 source page aligned sta ZP.A1L sta ZP.A2L beq L5223 L5208 lda R2H source page sta ZP.A1L+1 sta ZP.A2L+1 lda R2L sta ZP.A1L sta ZP.A2L lda R01 destination page sta ZP.A4L+1 sta ZP.A3L+1 lda #$00 destination page aligned sta ZP.A4L sta ZP.A3L L5223 inc ZP.A2L+1 inc ZP.A3L+1 rts * tzip is called if blocks 0,1,4,5 are requested. * on write it does nothing, on read it returns 0's. tzip jsr clrbuf0 fill dbuf with 0's jsr blockdo transfer the 0's jmp exitcard and return * clrbuf fills the buffer indicated by R01 to 0's. * should only be called on a read or format. clrbuf0 lda /RAMX.DBuf dbuf is temp buffer. clrbuf1 sta R01 assign to block. clrbuf2 jsr setptr set pointers tay acc = 0 L523A sta (ZP.A1L),y sta (ZP.A2L),y dey bne L523A rts * treg maps the requested block into the aux card * so that 8k data files will be contiguous (the index * blocks will not be placed within data). treg cmp #$04 page 4 = vdir bne L524A not vdir, continue lda #$07 else transfer block 7 bne L5258 L524A cmp #$0F if any page < $F (block 8) requested, bcc tzip it is invalid. ldx #$00 x = # of iterations. lda ZP.BLKNUM use true block #. cmp #$5D beyond 8k blocks ? bcc L525B no, do normal sbc #$50 else subtract offset L5258 jmp times2 and multiply by 2 * determine which 8k chunk it is in, place in x; * block offset into chunk goes into y. L525B sec sbc #$08 block=block-6 L525E cmp #$11 if <=17 then done bcc L5268 sbc #$11 else block=block-17. inx iteration count. bpl L525E should branch always brk otherwise crash !!! L5268 tay remainder in y * if remainder is 1 then it's an index block: * start index blocks at $1000,$2000...$19FF. * if remainder is 0 then it is first data block * in 8k chunk. page is 32 + (16 * x). * otherwise, it is some other data block. * page is 32 + (16 * x) + (2 * y) cpy #$01 is it index block ? bne L5273 no. txa index = 2 * (8 + x) clc adc #$08 bne times2 multiply by 2. L5273 inx iteration + 1. txa page = 2 * (16 + 8x) asl asl asl asl sta R01 tya get offset into 8k chunk beq L5281 if 0, no offset dey else offset = 2 * y tya L5281 clc adc R01 times2 asl acc = 2 * acc jsr blockdo1 store in R01 and transfer jmp exitcard and return * when block 3 is requested, the bitmap is returned. the real bitmap is only * 16 bytes long; the rest of the block is synthesized. the temporary buffer * at $800 is used to build/read a full size bitmap block. tbmap lda /RAMX.DBuf use temp buffer as block sta R01 jsr setptr set pointers, test read/write. bcs L52A9 branch if it's write. jsr clrbuf2 ldy #$0F put real bitmap there L529B lda BITMAP,y sta (ZP.A1L),y dey bpl L529B jsr blockdo move temp buf to user buf jmp exitcard L52A9 jsr blockdo move user buf to temp buf jsr setptr ldy #$0F move temp buf to bitmap. L52B1 lda (ZP.A4L),y (pointer set by setptr) sta BITMAP,y dey bpl L52B1 jmp exitcard formatflg .HS 00 not formatted yet tcmd .HS 00 command .HS 00 unit (not used) R2L .HS 00 R2 = user buffer R2H .HS 00 R01 .HS 00 page requested BITMAP .HS 00FFFFFF blocks 0-7 used .HS FFFFFFFF .HS FFFFFFFF .HS FFFFFFFE block 127 used (IRQV) VDIR .HS F3 storage type = F, name length = 3 .AS "RAM" access .DA #$C3 destroy, rename, read enabled .HS 27 entry length .HS 0D .HS 0000 .HS 0300 block 3 .DA #128 128 blocks exitcard lda IO.RRAMWRAMBNK1 restore language card lda IO.RRAMWRAMBNK1 pla get 80store bpl L52EA 80store wasn't on sta IO.SET80STORE enable 80store L52EA jmp bypass jump around passit passit .HS 0000 bypass lda #noerr set up return to noerr sta passit lda /noerr ex1 sta passit+1 also used by blockwrite clc transfer card to main clv use standard zeropage/stack jmp ROM.XFER jmp back from language card. *-------------------------------------- .EP *-------------------------------------- RAMX.LEN .EQ *-RAMX.START *-------------------------------------- MAN SAVE usr/src/prodos.fx/prodos.s.ramx LOAD usr/src/prodos.fx/prodos.s ASM