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

RAMX.START		lda RD80STORE			read 80 store
				pha						save for later
				sta	CLR80STORE			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			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 RRAMWRAMBNK2		turn on main $D000
				sta RRAMWRAMBNK2
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 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 RRAMWRAMBNK1		switch in MLI part of LC
				sta 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 /dbuf				set up R1 = dbuf
blockdo1 		sta R01
blockdo			jsr setptr			 	set pointers.
				bcs L51DB			 	it's a write.
				sta CLRWRITEAUX			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 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 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			lda /dbuf				dbuf is temp buffer.
clrbuf1			sta R01			  		assign to block.
clrbuf2			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			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
				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 /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 		.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
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
				.HS 7F			  		128 blocks

exitcard 		lda RRAMWRAMBNK1		restore language card
				lda RRAMWRAMBNK1
				pla		 				get 80store
				bpl L52EA			  	80store wasn't on
				sta 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 xfer				jmp back from language card.
*--------------------------------------
RAMX.LEN		.EQ *-RAMX.START
MAN
SAVE USR/SRC/PRODOS.FX/PRODOS.S.RAMX
LOAD USR/SRC/PRODOS.FX/PRODOS.S
ASM
