NEW
  AUTO 3,1
object code = ram_0
* /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

ofsR0	.EQ	ramsrc-ramdest		offset to /RAM driver org

ramsrc   lda   rd80col                  read 80 store
         pha                            save for later
         sta	store80off              turn off 80 store
         ldx   #$04                     move the parameters for use:
L5109    lda   A4L,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   bloknml			save R01 during format.
         lda   #>vblock1                block to be cleared.
         jsr   clrbuf1                  clears all buffers.
         ldy   #$03			format volume in 2 chunks.
L511F    lda   VDIR,y
         sta   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   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	.EQ	*-ofsR0
         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   altram			turn on main $D000
         sta   altram
L5179    sta   R01                      restore R1.
         lda   R2H                      save R2 for later
         pha
         ldx   R2L
         sta   setaltzp                 use alternate zero page/stack
         lda   #>dbuf                   set R2 to dbuf
         sta   R2H
         lda   #<dbuf
         sta   R2L
         jsr   setptr                   set pointers
         tay                            A > 0 from setptr
L5194    lda   (A1L),y                  move A1,A2 to A4,A3
         sta   (A4L),y
         lda   (A2L),y
         sta   (A3L),y
         dey
         bne   L5194
         sta   setstdzp                 use main zero page/stack
L51A2    stx   R2L
         pla                            restore R2
         sta   R2H
         plp                            get direction.
L51AA    bcs   L51B5                    write, done with move.
         sta   ramin			switch in MLI part of LC
         sta   ramin
         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 .EQ	*-ofsR0			set up R1 = dbuf
         lda   #>dbuf
blockdo1 .EQ	*-ofsR0
         sta   R01
blockdo	.EQ	*-ofsR0
         jsr   setptr                   set pointers.
         bcs   L51DB                    it's a write.
         sta   wrmainram                transfer buffer directly to main.
         tay                            0 left from setptr.
L51CC    lda   (A1L),y                  transfer A1,A2 to A4,A3
         sta   (A4L),y
         lda   (A2L),y
         sta   (A3L),y
         dey
         bne   L51CC
         sta   wrcardram                back the way it was.
donewrt	.EQ	*-ofsR0			mainwrt returns here
         rts
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	.EQ	*-ofsR0
         lda   tcmd			is it read or write ?
         lsr   a
         bcs   L5208                    taken if write.
         lda   R2H                      destination page
         sta   A4L+1
         sta   A3L+1
         lda   R2L
         sta   A4L
         sta   A3L
         lda   R01			source page
         sta   A1L+1
         sta   A2L+1
         lda   #$00                     source page aligned
         sta   A1L
         sta   A2L
         beq   L5223
L5208    lda   R2H			source page
         sta   A1L+1
         sta   A2L+1
         lda   R2L
         sta   A1L
         sta   A2L
         lda   R01			destination page
         sta   A4L+1
         sta   A3L+1
         lda   #$00			destination page aligned
         sta   A4L
         sta   A3L
L5223    inc   A2L+1
         inc   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	.EQ	*-ofsR0
         lda   #>dbuf			dbuf is temp buffer.
clrbuf1	.EQ	*-ofsR0
         sta   R01                      assign to block.
clrbuf2	.EQ	*-ofsR0
         jsr   setptr                   set pointers
         tay				acc = 0
L523A    sta   (A1L),y
         sta   (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	.EQ	*-ofsR0
         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   bloknml                  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
                .DA #00'                    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   L5285			multiply by 2.
L5273    inx                            iteration + 1.
         txa                            page = 2 * (16 + 8x)
         asl   a
         asl   a
         asl   a
         asl   a
         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	.EQ	*-ofsR0                  
L5285    asl   a                        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	.EQ	*-ofsR0
         lda   #>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   (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   (A4L),y                  (pointer set by setptr)
         sta   BITMAP,y
         dey
         bpl   L52B1
         jmp   exitcard

formatflg .EQ	*-ofsR0
                .DA #00'			not formatted yet
tcmd	.EQ	*-ofsR0
        dc	h'00'			command
         dc	h'00'                    unit (not used)
R2L	.EQ	*-ofsR0
	dc	h'00'			R2 = user buffer
R2H	.EQ	*-ofsR0
         dc	h'00'
R01	.EQ	*-ofsR0
         dc	h'00'			page requested
BITMAP	.EQ	*-ofsR0
         dc	h'00FFFFFF'		blocks 0-7 used
                .DA #FFFFFFFF'
         dc	h'FFFFFFFF'
                .DA #FFFFFFFE'
VDIR	.EQ	*-ofsR0                  start of vdir.
	dc	h'F3'			storage type = F, name length = 3
	msb	off
         dc    c'RAM'
access	.EQ	*-ofsR0
                .DA #C3'			destroy, rename, read enabled
         dc	h'27'                    entry length
         dc	h'0D'
         dc	h'0000'
         dc	h'0300'                  block 3
         dc	h'7F'                    128 blocks

exitcard .EQ	*-ofsR0
         lda   ramin			restore language card
         lda   ramin
         pla                            get 80store
         bpl   L52EA                    80store wasn't on
         sta   store80on                enable 80store
L52EA    jmp   bypass			jump around passit
passit	.EQ	*-ofsR0
                .DA #0000'
bypass	.EQ	*-ofsR0
         lda   #<noerr			set up return to noerr
         sta   passit
         lda   #>noerr
ex1	.EQ	*-ofsR0
         sta   passit+1			also used by blockwrite
         clc                            transfer card to main
         clv                            use standard zeropage/stack
         jmp   xfer			jmp back from language card.

* NOTE: the previous section of code MUST NOT use $3FE or $3FF
*       since the interrupt vector must go there if aux interrupts
*       are to be used. no room for expansion here !!

                .DA #0000'			$3FE-$3FF

* end of obj ram_0
*--------------------------------------
MAN
LOAD USR/SRC/PRODOS.203/PRODOS.S.RAMI
SAVE USR/SRC/PRODOS.203/PRODOS.S
ASM
