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
