Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.sys.apple2.programmer > #1300 > unrolled thread

80 column card RAM disk

Started byivan@ivanx.com
First post2014-09-01 15:05 -0700
Last post2014-09-01 20:09 -0400
Articles 9 — 4 participants

Back to article view | Back to comp.sys.apple2.programmer


Contents

  80 column card RAM disk ivan@ivanx.com - 2014-09-01 15:05 -0700
    Re: 80 column card RAM disk dempson@actrix.gen.nz (David Empson) - 2014-09-02 11:41 +1200
      Re: 80 column card RAM disk dempson@actrix.gen.nz (David Empson) - 2014-09-02 11:44 +1200
        Re: 80 column card RAM disk Jeff Blakeney <CUTjeffrey_blakeney@yahoo.ca> - 2014-09-02 07:53 -0400
      Re: 80 column card RAM disk Jeff Blakeney <CUTjeffrey_blakeney@yahoo.ca> - 2014-09-02 07:46 -0400
        Re: 80 column card RAM disk dempson@actrix.gen.nz (David Empson) - 2014-09-03 14:15 +1200
          Re: 80 column card RAM disk Jeff Blakeney <CUTjeffrey_blakeney@yahoo.ca> - 2014-09-02 22:36 -0400
            Re: 80 column card RAM disk Antoine Vignau <antoine.vignau@laposte.net> - 2014-09-05 14:27 -0700
    Re: 80 column card RAM disk Jeff Blakeney <CUTjeffrey_blakeney@yahoo.ca> - 2014-09-01 20:09 -0400

#1300 — 80 column card RAM disk

Fromivan@ivanx.com
Date2014-09-01 15:05 -0700
Subject80 column card RAM disk
Message-ID<96730f4e-8bc7-4603-9159-2f1dbbaaf37f@googlegroups.com>
I found this in section A.5 of the ProDOS 8 Tech Ref manual:

"The Apple lie computer can optionally contain an Extended 80-Column Text Card, giving the computer access to an additional 64K of RAM. (The Apple lie has the equivalent of such a card built in.) ProDOS uses this extra RAM as a volume, just like a small disk volume. This volume is initially given the name /RAM, but it can be renamed. The 64K of RAM on the card is logically partitioned into 127 512-byte blocks of information. The contents of these blocks are:
Blocks 00-01 Unavailable
Block 02 Volume directory
Block 03 Volume bit map
Blocks 04-07 Unavailable
Blocks 08-126 Directories and Files"

I thought it was interesting that blocks 4-7 are unavailable, since ProDOS would certainly allow them to be used for files. Then it occurred to me that maybe this was to protect the text page, so you can still use, you know, 80 columns; seems like a viable theory.

What I don't get is the math. At 512 bytes per block, block 4 would correspond to $800, not $400. And the text page is only 1K, whereas 2K are reserved (I guess that could be for text page 2; is that used)?

Mostly just curious. Anyone have any insight into this?

[toc] | [next] | [standalone]


#1301

Fromdempson@actrix.gen.nz (David Empson)
Date2014-09-02 11:41 +1200
Message-ID<1lrcf76.xrclj41u5dr3tN%dempson@actrix.gen.nz>
In reply to#1300
<ivan@ivanx.com> wrote:

> I found this in section A.5 of the ProDOS 8 Tech Ref manual:
> 
> "The Apple lie computer can optionally contain an Extended 80-Column Text
> Card, giving the computer access to an additional 64K of RAM. (The Apple
> lie [should that be "//c"?] has the equivalent of such a card built in.)
> ProDOS uses this extra RAM as a volume, just like a small disk volume.
> This volume is initially given the name /RAM, but it can be renamed. The
> 64K of RAM on the card is logically partitioned into 127 512-byte blocks
> of information.
> The contents of these blocks are:
> Blocks 00-01 Unavailable
> Block 02 Volume directory
> Block 03 Volume bit map
> Blocks 04-07 Unavailable
> Blocks 08-126 Directories and Files"
> 
> I thought it was interesting that blocks 4-7 are unavailable, since ProDOS
> would certainly allow them to be used for files. Then it occurred to me
> that maybe this was to protect the text page, so you can still use, you
> know, 80 columns; seems like a viable theory.
> 
> What I don't get is the math. At 512 bytes per block, block 4 would
> correspond to $800, not $400. And the text page is only 1K, whereas 2K are
> reserved (I guess that could be for text page 2; is that used)?

The block numbers in /RAM are not linearly mapped to memory addresses.
The first allocatable blocks (8+) are in the hi-res graphics buffer so
applications can use the documented method of reserving the auxiliary
memory hi-res pages by first saving one or two 8 KB files in /RAM (this
allows for the pattern ProDOS uses to grow a file - the first block for
a seedling file goes at $2000, the next block is an index and it goes at
$1000-$11FF, then the next several data blocks cover $2200-$3FFF; the
pattern repeats for $4000-$5FFF with an index block at $1200-$13FF).

Logical block 2 has to to be the key block of the volume directory
because that's where ProDOS looks for it. It is actually stored at
$0E00-$0FFF.

The volume directory must be consecutive blocks and by convention is
followed by the volume bit map. Only one block is made available for the
root directory, so the logical place to put the bitmap is in block 3.

The memory layout of /RAM is documented in ProDOS Technical Note #18.
The layout allows for several reserved areas, including most of
$0000-$0DFF (which covers text page 2) and $FE00-$FFFF (which contains
the interrupt vectors).

There is at least one error in my copy (November 1988) - it says blocks
$70-$7F occupy $E000-$EFFF, but that range should end at $FFFF, and
block $7F doesn't exist (the volume size is 127 blocks, so the last
block number is $7E).

Not fully explained there, but if I remember right, Block 3 is stored as
a partial block in the $0280-$02FF area, or somewhere near that (it only
needs 16 bytes).

-- 
David Empson
dempson@actrix.gen.nz

[toc] | [prev] | [next] | [standalone]


#1302

Fromdempson@actrix.gen.nz (David Empson)
Date2014-09-02 11:44 +1200
Message-ID<1lrcgip.y6uy66xszhbtN%dempson@actrix.gen.nz>
In reply to#1301
David Empson <dempson@actrix.gen.nz> wrote:

> <ivan@ivanx.com> wrote:
> 
> > I found this in section A.5 of the ProDOS 8 Tech Ref manual:
> > 
> > "The Apple lie computer can optionally contain an Extended 80-Column Text
> > Card, giving the computer access to an additional 64K of RAM. (The Apple
> > lie [should that be "//c"?] has the equivalent of such a card built in.)
> > ProDOS uses this extra RAM as a volume, just like a small disk volume.
> > This volume is initially given the name /RAM, but it can be renamed. The
> > 64K of RAM on the card is logically partitioned into 127 512-byte blocks
> > of information.
> > The contents of these blocks are:
> > Blocks 00-01 Unavailable
> > Block 02 Volume directory
> > Block 03 Volume bit map
> > Blocks 04-07 Unavailable
> > Blocks 08-126 Directories and Files"
> > 
> > I thought it was interesting that blocks 4-7 are unavailable, since ProDOS
> > would certainly allow them to be used for files. Then it occurred to me
> > that maybe this was to protect the text page, so you can still use, you
> > know, 80 columns; seems like a viable theory.
> > 
> > What I don't get is the math. At 512 bytes per block, block 4 would
> > correspond to $800, not $400. And the text page is only 1K, whereas 2K are
> > reserved (I guess that could be for text page 2; is that used)?
> 
> The block numbers in /RAM are not linearly mapped to memory addresses.
> The first allocatable blocks (8+) are in the hi-res graphics buffer so
> applications can use the documented method of reserving the auxiliary
> memory hi-res pages by first saving one or two 8 KB files in /RAM (this
> allows for the pattern ProDOS uses to grow a file - the first block for
> a seedling file goes at $2000, the next block is an index and it goes at
> $1000-$11FF, then the next several data blocks cover $2200-$3FFF; the
> pattern repeats for $4000-$5FFF with an index block at $1200-$13FF).
> 
> Logical block 2 has to to be the key block of the volume directory
> because that's where ProDOS looks for it. It is actually stored at
> $0E00-$0FFF.
> 
> The volume directory must be consecutive blocks and by convention is
> followed by the volume bit map. Only one block is made available for the
> root directory, so the logical place to put the bitmap is in block 3.
> 
> The memory layout of /RAM is documented in ProDOS Technical Note #18.
> The layout allows for several reserved areas, including most of
> $0000-$0DFF (which covers text page 2) and $FE00-$FFFF (which contains
> the interrupt vectors).
> 
> There is at least one error in my copy (November 1988) - it says blocks
> $70-$7F occupy $E000-$EFFF, but that range should end at $FFFF, and
> block $7F doesn't exist (the volume size is 127 blocks, so the last
> block number is $7E).
> 
> Not fully explained there, but if I remember right, Block 3 is stored as
> a partial block in the $0280-$02FF area, or somewhere near that (it only
> needs 16 bytes).

One other point I forgot to mention: I expect that the main reason
blocks 4-7 are reserved is to deal with software which expects most of
those to be the root directory and volume bitmap, and so that some of
the memory addresses line up nicely (once you get beyond the complex
remapping).

-- 
David Empson
dempson@actrix.gen.nz

[toc] | [prev] | [next] | [standalone]


#1306

FromJeff Blakeney <CUTjeffrey_blakeney@yahoo.ca>
Date2014-09-02 07:53 -0400
Message-ID<lu4b31$m60$1@dont-email.me>
In reply to#1302
On 01/09/2014 7:44 PM, David Empson wrote:
> One other point I forgot to mention: I expect that the main reason
> blocks 4-7 are reserved is to deal with software which expects most of
> those to be the root directory and volume bitmap, and so that some of
> the memory addresses line up nicely (once you get beyond the complex
> remapping).

Except that one every other ProDOS volume that is less than 2 MB in 
size, the first block available for storing files is block 7, not block 
8, so I still don't understand why block 7 is marked as used.

Perhaps simply because they needed to drop another block as they didn't 
have another 512 byte chunk of memory to use so tossed a coin to 
determine whether to drop block 7 or block 125.  Or perhaps someone said 
that the first 7 blocks were already used (blocks 0 to 6) and someone 
else assumed that meant that the first available block would be 8.  :)

[toc] | [prev] | [next] | [standalone]


#1305

FromJeff Blakeney <CUTjeffrey_blakeney@yahoo.ca>
Date2014-09-02 07:46 -0400
Message-ID<lu4am1$jam$1@dont-email.me>
In reply to#1301
On 01/09/2014 7:41 PM, David Empson wrote:
> The block numbers in /RAM are not linearly mapped to memory addresses.
> The first allocatable blocks (8+) are in the hi-res graphics buffer so
> applications can use the documented method of reserving the auxiliary
> memory hi-res pages by first saving one or two 8 KB files in /RAM (this
> allows for the pattern ProDOS uses to grow a file - the first block for
> a seedling file goes at $2000, the next block is an index and it goes at
> $1000-$11FF, then the next several data blocks cover $2200-$3FFF; the
> pattern repeats for $4000-$5FFF with an index block at $1200-$13FF).

Ah, that makes sense and explains why my second one block file save went 
to $1000 instead of $2200 like I thought it would.  Didn't even consider 
the index block for seedling files.

> Logical block 2 has to to be the key block of the volume directory
> because that's where ProDOS looks for it. It is actually stored at
> $0E00-$0FFF.

 From my poking around in memory I saw the directory (block 2) at $0C00 
to $0DFF.

> The volume directory must be consecutive blocks and by convention is
> followed by the volume bit map. Only one block is made available for the
> root directory, so the logical place to put the bitmap is in block 3.

Except that some software may go directly to block 6 to look for a 
volume bit map as that is where it starts on every other ProDOS volume.

> The memory layout of /RAM is documented in ProDOS Technical Note #18.
> The layout allows for several reserved areas, including most of
> $0000-$0DFF (which covers text page 2) and $FE00-$FFFF (which contains
> the interrupt vectors).

Gary B. Little's "Exploring Apple GS/OS and ProDOS 8" says that most of 
$0000 to $0BFF and $FE00-$FFFF are reserved.  More details in my other 
post in this thread including quotes from the book.

> There is at least one error in my copy (November 1988) - it says blocks
> $70-$7F occupy $E000-$EFFF, but that range should end at $FFFF, and
> block $7F doesn't exist (the volume size is 127 blocks, so the last
> block number is $7E).

So the maximum block number should be $7E so that means the address 
range should be $E000-$FDFF.  Wow, they really did mess that one up. 
Two mistakes in one spot.

> Not fully explained there, but if I remember right, Block 3 is stored as
> a partial block in the $0280-$02FF area, or somewhere near that (it only
> needs 16 bytes).

 From my poking around in memory I saw the volume bit map (block 3) at 
$0E00 - $0FFF.  The bits of the bitmap appear to use the first 16 bytes 
so really only $0E00 to $0E0F.

[toc] | [prev] | [next] | [standalone]


#1307

Fromdempson@actrix.gen.nz (David Empson)
Date2014-09-03 14:15 +1200
Message-ID<1lre6bi.jjkxpn1h98rvzN%dempson@actrix.gen.nz>
In reply to#1305
Jeff Blakeney <CUTjeffrey_blakeney@yahoo.ca> wrote:

> On 01/09/2014 7:41 PM, David Empson wrote:
> > The block numbers in /RAM are not linearly mapped to memory addresses.
> > The first allocatable blocks (8+) are in the hi-res graphics buffer so
> > applications can use the documented method of reserving the auxiliary
> > memory hi-res pages by first saving one or two 8 KB files in /RAM (this
> > allows for the pattern ProDOS uses to grow a file - the first block for
> > a seedling file goes at $2000, the next block is an index and it goes at
> > $1000-$11FF, then the next several data blocks cover $2200-$3FFF; the
> > pattern repeats for $4000-$5FFF with an index block at $1200-$13FF).
> 
> Ah, that makes sense and explains why my second one block file save went
> to $1000 instead of $2200 like I thought it would.  Didn't even consider
> the index block for seedling files.

Minor correction: it is a seedling file (one data block, no index block)
when initially created, but it gets converted to a sapling file (one
index block and up to 256 data blocks) when the length is set to 8192
bytes. That causes the index block to be allocated, then the rest of HGR
page 1 to be allocated as data blocks.

> > Logical block 2 has to to be the key block of the volume directory
> > because that's where ProDOS looks for it. It is actually stored at
> > $0E00-$0FFF.
> 
>  From my poking around in memory I saw the directory (block 2) at $0C00
> to $0DFF.

In that case either Apple changed the implementation details in a ProDOS
version after November 1988 or there is another error in the tech note.

It did seem odd that $0C00-$0DFF appeared to be reserved, as there is no
hardware associated with that area.

> > The volume directory must be consecutive blocks and by convention is
> > followed by the volume bit map. Only one block is made available for the
> > root directory, so the logical place to put the bitmap is in block 3.
> 
> Except that some software may go directly to block 6 to look for a 
> volume bit map as that is where it starts on every other ProDOS volume.

That would be a bad choice since /RAM has probably been arranged this
way since ProDOS was introduced, and the volume bitmap should be located
via the directory header.

I'd only expect this sort of behaviour from directory repair utilities,
and there probably isn't much call for repairing /RAM (if it is even
available - the utility might need to disable /RAM to use auxiliary
memory itself).

> > The memory layout of /RAM is documented in ProDOS Technical Note #18.
> > The layout allows for several reserved areas, including most of
> > $0000-$0DFF (which covers text page 2) and $FE00-$FFFF (which contains
> > the interrupt vectors).
> 
> Gary B. Little's "Exploring Apple GS/OS and ProDOS 8" says that most of
> $0000 to $0BFF and $FE00-$FFFF are reserved.  More details in my other
> post in this thread including quotes from the book.

Apple also documents reserved areas of auxiliary memory, some of which
only apply when /RAM is disabled. It is in the ProDOS 8 Technical
Reference, if I remember right (don't have mine on hand to confirm, and
I didn't spot it in the technotes).

> > There is at least one error in my copy (November 1988) - it says blocks
> > $70-$7F occupy $E000-$EFFF, but that range should end at $FFFF, and
> > block $7F doesn't exist (the volume size is 127 blocks, so the last
> > block number is $7E).
> 
> So the maximum block number should be $7E so that means the address 
> range should be $E000-$FDFF.  Wow, they really did mess that one up. 
> Two mistakes in one spot.
> 
> > Not fully explained there, but if I remember right, Block 3 is stored as
> > a partial block in the $0280-$02FF area, or somewhere near that (it only
> > needs 16 bytes).
> 
>  From my poking around in memory I saw the volume bit map (block 3) at
> $0E00 - $0FFF.  The bits of the bitmap appear to use the first 16 bytes
> so really only $0E00 to $0E0F.

That increases my suspicion that the tech note is out of date and the
implementation details changed at some point.

My copy of the tech note has an asterisk and footnote saying that block
3 is synthesized. That wouldn't be necessary if they allocated a full
512 bytes to it.

-- 
David Empson
dempson@actrix.gen.nz

[toc] | [prev] | [next] | [standalone]


#1308

FromJeff Blakeney <CUTjeffrey_blakeney@yahoo.ca>
Date2014-09-02 22:36 -0400
Message-ID<lu5urj$ddu$1@dont-email.me>
In reply to#1307
On 02/09/2014 10:15 PM, David Empson wrote:
> Minor correction: it is a seedling file (one data block, no index block)
> when initially created, but it gets converted to a sapling file (one
> index block and up to 256 data blocks) when the length is set to 8192
> bytes. That causes the index block to be allocated, then the rest of HGR
> page 1 to be allocated as data blocks.

Whoops.  My bad.  I did mean sapling file but either my brain or my 
fingers decided to use seedling instead.  :)

> That would be a bad choice since /RAM has probably been arranged this
> way since ProDOS was introduced, and the volume bitmap should be located
> via the directory header.
>
> I'd only expect this sort of behaviour from directory repair utilities,
> and there probably isn't much call for repairing /RAM (if it is even
> available - the utility might need to disable /RAM to use auxiliary
> memory itself).

It is unfortunate that /RAM has to be handled as a special case but that 
is the way it is.  Programs that assume that the root directory is four 
blocks long and uses blocks 2-5 or assume that the volume bit map starts 
at block 6 will always have problems with /RAM.  Not to mention that 
anything that tries to write to blocks 0, 1 and 4-7 will be surprised to 
find that their data has disappeared if they didn't get an error from 
trying to do so in the first place.  :)

> That increases my suspicion that the tech note is out of date and the
> implementation details changed at some point.
>
> My copy of the tech note has an asterisk and footnote saying that block
> 3 is synthesized. That wouldn't be necessary if they allocated a full
> 512 bytes to it.

I'm not sure where my tech notes are at present but I'll have to look 
them up again.  It might be that block 3 only uses the first 16 bytes of 
$0E00-$0FFF as I seem to recall a lot of random stuff in there when I 
looked at it.  Unlike the directory block that was zeroed out.

[toc] | [prev] | [next] | [standalone]


#1313

FromAntoine Vignau <antoine.vignau@laposte.net>
Date2014-09-05 14:27 -0700
Message-ID<877e19ba-58dd-47a8-b78f-ac5e44b658cf@googlegroups.com>
In reply to#1308
P8 RAM driver source code:


;	This EdAsm/Asm816 source code file was converted to AsmIIGS
;	by EdAsmCVTIIGS version 1.0D3 on 1/24/89 at 10:49:37 AM

* Converted and reformatted by Monte Benaresh -- February 1989



	;these are ZERO PAGE locations!	 
CMD		equ	$42		;command from ProDOS
UNIT		equ	$43		;unitnum from ProDOS
BUFPTR		equ	$44		;User Buffer pointer
BLOCK		equ	$46		;block requested

		MACHINE	M6502

		longa	off
		longi	off

PRODOS		EQU	0
EDNET		EQU	1
OS		EQU	PRODOS
*
* Creates 3 object files 
*
XDIOERR		EQU	$27
XDWPERR		EQU	$2B		;write protect error
A1L		EQU	$3C
A1H		EQU	$3D		;SOURCE OF TRANSFER
A2L		EQU	$3E
A2H		EQU	$3F		;END OF SOURCE
A3L		EQU	$40
A3H		EQU	$41
A4L		EQU	$42
A4H		EQU	$43		;DESTINATION OF TRANSFER
*
MOVE		EQU	$C311		;monitor move data routine
XFER		EQU	$C314		;monitor XFER control
*
ENBLRAM2	EQU	$C083		;enable 2nd bank of LC
ENBLRAM1	EQU	$C08B		;enable 1st bank of LC
*
STORE80OFF	EQU	$C000
STORE80ON	EQU	$C001
STORE80SW	EQU	$C018
WRMAINRAM	EQU	$C004		;Write data to main ram
WRCARDRAM	EQU	$C005		;Write data to card ram
ALTZP		EQU	$C009		;enable alternate ZP,STK,LC
REGZP		EQU	$C008		;enable regular ZP,STK,LC
*
ABUF1		EQU	$C00		;temporary buffer
VBLOCK1		EQU	$E00		;where the Vdir goes
*
ENTERCARD	EQU	$200		;card entry point
PASSIT		EQU	$3ED		;XFER param 
*

		Eject
************************************************************
*                                                          *
*            PRODOS 8 KERNEL 59.5K RAMDISK (REV-E)         *
*                                                          *
*            COPYRIGHT APPLE COMPUTER, INC., 1983-86       *
*                                                          *
*                     ALL RIGHTS RESERVED                  *
*                                                          *
************************************************************

**** Note that the "os" variable must be updated depending on
**** the system you are building.


RAM1		PROC	Org $200
procstart
max_size	equ	$1FE		;allowed to grow to $3FD


		IMPORT	NOERR
		IMPORT	MAINWRT
		EXPORT	DONEWRT
*
* After the main routine has determined that the command
* is ok, and the block to be read/written is within
* range, it tranfers control to this routine.  This routine
* 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
*                 $5-$5F :returns card blocks $5-$5F
*                $60-$67 :returns blocks $68-$7F in bank 1 of
*                           card's language card
*                $68-$7F :returns blocks $68-$7F in bank 2
*                           of card's language card
*
DOCMD		LDA	STORE80SW	;Read 80STORE
		PHA			;SAVE for later
		STA	STORE80OFF	;turn off 80STORE

		LDX	#4		;move the params for our use  
DOCMD1		LDA	<CMD,X		;CMD,UNIT,BUFPTR,&BLOCK(lo)
		STA	TCMD,X		;->TCMD,TUNIT,R2L,R2,R1 
		DEX
		BPL	DOCMD1
		AND	FORMATFLAG	;Format the volume first time 
		BNE	DOCOMMAND	;thru, or when requested 

DOFORMAT	LDX	<BLOCK		;save R1 during format
		LDA	#>VBLOCK1	;block to be cleared
		JSR	CLRBUF1		;ClrBuf clears all buffers
		LDY	#$3		;Format volume in 2 chunks 
DF2		LDA	VDIR,Y
		STA	VBLOCK1+4,Y
		DEY
		BPL	DF2

		LDA	#$FE		;Set last block as unusable to protect vectors
		STA	BITMAP+$F
		TYA			;SET bitmap bits to $FF
		LDY	#$E		;15 bytes to set
DF2_1		STA	BITMAP,Y	 
		DEY
		BNE	DF2_1
		STY	BITMAP		;first byte=0

		LDY	#$7		;do other chunk
DF3		LDA	ACCESS,Y
		STA	VBLOCK1+34,Y
		DEY
		BPL	DF3	 
		LDA	FORMATFLAG	;if 0, set to FF 
		BNE	DFX		;else exitcard
		STY	FORMATFLAG	;Y=FF, won't format next time 
		STX	R1		;restore R1

* Now use the requested block number to determine
* which routine performs the transfer

DOCOMMAND	ASL	R1		;block requested->page requested
		LDA	R1		;get page requested
		CMP	#$BF		;in Language card?
		BCS	TLC1		;yes, do it
CB1		CMP	#6		;bit map?
		BNE	CB2	 
		JMP	TBMAP		;yes, transfer bitmap
CB2		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 two-stage move: into the temp
* buffer and then to its real destination.

TLC1		TAX			;SAVE R1 for later
		JSR	SETPTR		;get direction
		PHP			;SAVE direction
		BCS	LCWRT		;it is a write
LCRD		TXA			;GET R1 back
		CMP	#$CF		;which bank is it in
		BCS	TLC2		;in main bank

		ORA	#$10		;in secondary bank
		BNE	TLC3		;branch always

TLC2		STA	ENBLRAM2	;turn on main $D000
		STA	ENBLRAM2

TLC3		STA	R1		;restore R1
		LDA	R2		;save R2 for later
		PHA
		LDX	R2L	 
		STA	ALTZP		;now switch to other ZP
		LDA	#>ABUF1		;set R2 to Abuf 
		STA	R2	 
		LDA	#<ABUF1	  
		STA	R2L
		JSR	SETPTR		;set pointers
		TAY			;A>0 from SETPTR
TLC4		LDA	(A1L),Y		;move A1,A2 to A4,A3
		STA	(A4L),Y
		LDA	(A2L),Y
		STA	(A3L),Y
		DEY
		BNE	TLC4

		STA	REGZP		;restore normal ZP    
		STX	R2L	 
		PLA			;RESTORE R2
		STA	R2
		PLP			;GET direction
DFX		BCS	XLCWRT		;write, done with move

		STA	ENBLRAM1	;now switch MLI part of LC in
		STA	ENBLRAM1
		JSR	BLOCKDO0	;read, transfer Abuf to main
XLCWRT		JMP	EXITCARD

LCWRT		JSR	BLOCKDO0	;transfer main to Abuf
		JMP	LCRD		;transfer Abuf to Lang card

* BLOCKDO 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	#>ABUF1		;set up R1 = Abuf 
BLOCKDO1	STA	R1
BLOCKDO		JSR	SETPTR		;set pointers
		BCS	BLOCKWRITE	;it's a write
		STA	WRMAINRAM	;transfer buffer directly to main ram
		TAY			;0 left from SETPTR
BD1		LDA	(A1L),Y		;transfer A1,A2 to A4,A3
		STA	(A4L),Y
		LDA	(A2L),Y
		STA	(A3L),Y
		DEY
		BNE	BD1
		STA	WRCARDRAM	;back the way it was
DONEWRT		RTS			;MAINWRT returns here 

BLOCKWRITE	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 to detect read or write.

SETPTR		LDA	TCMD		;the rest depends on read 
		LSR	A		;or write.  Which is it?
		BCS	CMDWRT		;it's write

CMDRD		LDA	R2		;get dest page
		STA	A4H		;1st dest page (MOVE)
		STA	A3H		;2nd dest page
		LDA	R2L		;low byte dest page
		STA	A4L		;1st dest page low
		STA	A3L		;2nd dest page low
		LDA	R1		;get source page
		STA	A1H		;1st source page
		STA	A2H		;2nd source page
		LDA	#0		;source page aligned
		STA	A1L		;1st source page
		STA	A2L		;2nd source page
		BEQ	CMDBOTH		;update second pages

CMDWRT		LDA	R2		;get source page
		STA	A1H		;1st source page
		STA	A2H		;2nd source page
		LDA	R2L		;get source page low
		STA	A1L		;1st source page low
		STA	A2L		;2nd source page low
		LDA	R1		;get dest page
		STA	A4H		;1st dest page
		STA	A3H		;2nd dest page
		LDA	#0		;dest page aligned
		STA	A4L		;1st dest page
		STA	A3L		;2nd dest page

CMDBOTH		INC	A2H		;update 2nd source page 
		INC	A3H		;update 2nd dest page
		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 ABUF with 0's
		JSR	BLOCKDO		;transfer them 0's
ZIPOUT		JMP	EXITCARD	;and return

* CLRBUF fills the buffer indicated by R1 to 0's
* Should only be called on a read or format. 

CLRBUF0		LDA	#>ABUF1		;ABUF is temp buffer
CLRBUF1		STA	R1		;assign to BLOCK
CLRBUF2		JSR	SETPTR		;set pointers
		TAY			;A set to 0 by setptr 
CLRBUF3		STA	(A1L),Y
		STA	(A2L),Y
		DEY
		BNE	CLRBUF3	 
		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	#4		;page 4 = vdir  
		BNE	T1		;not vdir, continue
		LDA	#$7		;else xfer block 7 
		BNE	GOTIMES2

***************** See Rev Note #43 ********************

T1		CMP	#$F		;if any page<f (<block 8) requested
*******************************************************
		BCC	TZIP		;it is invalid

TREG1		LDX	#0		;X contains number of iterations
		LDA	<BLOCK		;use true block number
		CMP	#$5D		;beyond 8K blocks?
		BCC	TR1		;no, do normal
		SBC	#$50		;else subtract offset
GOTIMES2	JMP	TIMES2		;and multiply by 2

* Determine which 8K chunk it is in, place in X;
* block offset into chunk goes into Y.

TR1		SEC
		SBC	#$8		;block = block -6
TR2		CMP	#$11		;if <=17, done
		BCC	TR3		;yup, got iteration
		SBC	#$11		;else block =block -17
		INX			;COUNT iteration
		BPL	TR2		;branch always
		DC.B	$00		;just in case
TR3		TAY			;REMAINDER in Y

* If remainder is 1 it's an index block: start index
* blocks at $1000,$2000..$19FF) 
*    If remainder is 0, 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	#1		;is it index block?
		BNE	TR4		;no
		TXA			;INDEX = 2*(8+X)
		CLC
		ADC	#8	 
		BNE	TIMES2		;multiply by 2
TR4		INX			;NEED iteration+1
		TXA			;PAGE = 2 * (16 + 8X)      
		ASL	A
		ASL	A	 
		ASL	A
		ASL	A
		STA	R1
		TYA			;GET offset into 8K chunk
		BEQ	TR5		;if 0, no offset
		DEY			;ELSE offset = 2 * Y
		TYA
TR5		CLC
		ADC	R1
TIMES2		ASL	A		;acc=2*acc
		JSR	BLOCKDO1	;store in R1 and xfer
		JMP	EXITCARD	;and return

* When Block 3 is requested, the bitmap is returned.  The
* Real bitmap is only 16 bytes long (BITMAP); the rest of
* the block is synthesized.  The temporary buffer at $800
* is used to build/read a full size bitmap block.

TBMAP		LDA	#>ABUF1		;use temporary buffer as BLOCK
		STA	R1
		JSR	SETPTR		;Set pointers/test read-write 
		BCS	BITWRT		;its a write!

BITRD		JSR	CLRBUF2	 

		LDY	#$F		;now put real bitmap there
BITRD2		LDA	BITMAP,Y
		STA	(A1L),Y
		DEY
		BPL	BITRD2
		JSR	BLOCKDO		;move temp buf to user buf
		JMP	EXITCARD

BITWRT		JSR	BLOCKDO		;move user buf to temp buf
		JSR	SETPTR		;Set pointers
		LDY	#$F		;move temp buf to bitmap
BITWRT1		LDA	(A4L),Y		;(pointer set by SETPTR) 
		STA	BITMAP,Y
		DEY
		BPL	BITWRT1
		JMP	EXITCARD

FORMATFLAG	DC.B	0		;not formatted yet

TCMD		DS.B	1 		;command byte
TUNIT		DS.B	1 		;unit byte (not used)
R2L		DS.B	1 		;low byte of user buffer
R2		DS.B	1 		;hi byte of user buffer
R1		DS.B	1 		;page requested

BITMAP		DC.B	$00,$FF,$FF,$FF	;blocks 0-7 used 
		DC.B	$FF,$FF,$FF,$FF
		DC.B	$FF,$FF,$FF,$FF
		DC.B	$FF,$FF,$FF,$FE

VDIR					;start of vdir
TYPE_NAMEL	DC.B	$F3		;storage type F, namelength 3
		MSB	OFF
VNAME		DC.B	'RAM'

ACCESS		DC.B	$C3		;Destroy, Rename, Read enabled
ENTRY_LEN	DC.B	$27		;entry length
ENTRIES_PER_BLOCK DC.B	$0D	 
FILE_COUNT	DC.B	0,0
MAP_POINTER	DC.B	3,0		;Block 3 
TOTAL_BLOCKS	DC.B	$7F		;128 blocks 

EXITCARD	LDA	ENBLRAM1	;restore lang card
		LDA	ENBLRAM1	 
		PLA			;GET 80STORE
		BPL	EX0		;80STORE wasn't on
		STA	STORE80ON
EX0		JMP	$3EF		;Jump around PassIt (3ED,3EE)
		DS.B	($3EF - $200) - (* - procstart)	 ;pad thru $3EE 
		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 zp/stk
		JMP	XFER		;there's no place like home...

*  NOTE: The previous section of code MUST NOT use $3FE & $3FF
*        since the Interrupt Vector must go there if AUX interrupts
*        are to be used.
	if (*-procstart) > max_size then
		aerror	'Aux bank /RAM driver segment too large.'
	endif
		ENDP

		Eject
RAM2		proc	Org $2C80
procstart
max_size	equ	$80

* Transfer card part of the driver to the card
* Transfer front part of the driver to lang.card

RAMDEST		EQU	$0200
LCDEST		EQU	$FF00	 


RAMSRC		EQU	$5100		;address of Aux Bank driver within P8 image
LCSRC		EQU	$2D00		;address of Main Bank driver within P8 image

DEVNUM		EQU	$B0		;Slot 3, Drive 2 ($30 + hi bit set)
DEVADR		EQU	$BF10		;Base of Device addresses 
DEVCNT		EQU	$BF31
DEVLST		EQU	$BF32

* Move LCSrc to LCDest

		LDY	#$99		;move $9A bytes 
MVLC		LDA	LCSRC,Y		;get a byte of source
		STA	LCDEST,Y
		DEY
		CPY	#$FF
		BNE	MVLC

* Move RAMSrc to RAMDest

		LDX	#<RAMSRC
		STX	<A1L		;source low
		DEX			;SOURCE end low
		STX	<A2L
		LDX	#>RAMSRC	;source high
		STX	<A1H
		INX
		STX	<A2H		;end high
		LDA	#<RAMDEST
		STA	<A4L
		LDA	#>RAMDEST
		STA	<A4H
		SEC			;RAM to Card
		JSR	MOVE

* Now install it into the system

		LDA	#<LCDEST	;put LC address into
		STA	$BF26		;slot 3, drive 2 
		LDA	#>LCDEST
		STA	$BF26+1
		INC	DEVCNT
		LDX	DEVCNT
		LDA	#DEVNUM+$F	;unit num of /RAM
		STA	DEVLST,X
		RTS

	if (*-procstart) > max_size then
		aerror	'/RAM driver installer segment too large.'
	endif
		ENDP

		Eject
RAM3		proc	Org $FF00
procstart
		IMPORT	DONEWRT
		EXPORT	NOERR
		EXPORT	MAINWRT

max_size	equ	$9B

ENTERRAM				;/RAM entry point
		CLD

		LDX	#$B		;save 13 bytes of params
SAVPARMS	LDA	<A1L,X	  
		STA	A1L1,X
		DEX
		BPL	SAVPARMS

		LDX	#1		;save XFER Vectors too 
SVP1		LDA	PASSIT,X
		STA	SP1,X
		DEX
		BPL	SVP1

		LDA	<CMD		;get command
		BEQ	STAT		;0=STATUS
		CMP	#4		;check for command too high
		BCS	IOERR		;if it is, IO ERR
		EOR	#$3		;0=FORMAT,2=READ,1=WRITE
		STA	<CMD		;CMD=>0=Format,2=Read,1=Write
		BEQ	FORMAT		;format the volume
		LDY	<BLOCK+1	;check for enormous blocknum
		BNE	IOERR		;io error if too big
		LDA	<BLOCK		;get the block number
		BMI	IOERR		;largest block is $7F

* At this point, control is passed to the code in the
* alternate 64K.  It is used for read, write, and 
* format.  After the request is completed, control
* is always passed back to NoErr.

FORMAT
		LDA	#<ENTERCARD	;card entry point
		STA	PASSIT		;figure it out on card
		LDA	#>ENTERCARD
GOCARD		STA	PASSIT+1	;also used by MainWrt 
		SEC			;RAM->>CARD

		CLV			;START with original z.p.
		JMP	XFER		;transfer control


IOERR		LDA	#XDIOERR	;get err num
		BNE	ERROUT		;and return
WPERR		LDA	#XDWPERR	;write protect err
ERROUT		SEC			;FLAG error
		BCS	RESTORE		;restore cmd and unitnum

STAT
NOERR		LDA	#0		;no error
		CLC			;FLAG no error
RESTORE		PHP			;SAVE status
		PHA			;SAVE error code

		LDX	#$B		;restore 13 bytes of params
RSTPRMS		LDA	A1L1,X	 
		STA	<A1L,X	  
		DEX
		BPL	RSTPRMS

		LDA	SP1		;restore XFER params
		BIT	$6060		;This instruction is to put an RTS at $FF58 as in ROM
		STA	PASSIT
		LDA	SP1+1
		STA	PASSIT+1

; -------------------- See rev note 21 -----------------------
		PLA			;GET error
		PLP			;GET status
; ------------------------------------------------------------
		RTS			;AND return

MAINWRT		STA	WRCARDRAM	;xfer data to card
		LDY	#0
MW1		LDA	(A1L),Y		;pointers set in card by SETPTR
		STA	(A4L),Y	 
		LDA	(A2L),Y
		STA	(A3L),Y
		DEY
		BNE	MW1
		STA	WRMAINRAM	;done writing Card

		LDA	#<DONEWRT
		STA	PASSIT
		LDA	#>DONEWRT
		JMP	GOCARD

SP1		DS.B	2	
A1L1		DS.B	$C		;13 bytes of storage
FRONTLEN	EQU	*-ENTERRAM

***************** See Rev Note #EN1 ******************

;	IF OS-EDNET = 0 THEN
;	LDA	$C083		; Switch in bank 2.
;	JSR	$D400		; Go do RWTS.
;	STA	$C08B		; Switch bank 1 back in preserving status!
;	RTS			; Back to caller.
WHEREAREWE
;	ENDIF
*****************************************************

	if (*-procstart) > max_size then
		aerror	'Main bank /RAM driver segment too large.'
	endif
		ENDP

		END

[toc] | [prev] | [next] | [standalone]


#1303

FromJeff Blakeney <CUTjeffrey_blakeney@yahoo.ca>
Date2014-09-01 20:09 -0400
Message-ID<lu31rv$607$1@dont-email.me>
In reply to#1300
On 01/09/2014 6:05 PM, ivan@ivanx.com wrote:
> I found this in section A.5 of the ProDOS 8 Tech Ref manual:
>
> "The Apple lie computer can optionally contain an Extended 80-Column
> Text Card, giving the computer access to an additional 64K of RAM.
> (The Apple lie has the equivalent of such a card built in.) ProDOS
> uses this extra RAM as a volume, just like a small disk volume. This
> volume is initially given the name /RAM, but it can be renamed. The
> 64K of RAM on the card is logically partitioned into 127 512-byte
> blocks of information. The contents of these blocks are:
 > Blocks 00-01 Unavailable
 > Block 02 Volume directory
 > Block 03 Volume bit map
 > Blocks 04-07 Unavailable
 > Blocks 08-126 Directories and Files"
>
> I thought it was interesting that blocks 4-7 are unavailable, since
> ProDOS would certainly allow them to be used for files. Then it
> occurred to me that maybe this was to protect the text page, so you
> can still use, you know, 80 columns; seems like a viable theory.
>
> What I don't get is the math. At 512 bytes per block, block 4 would
> correspond to $800, not $400. And the text page is only 1K, whereas
> 2K are reserved (I guess that could be for text page 2; is that
> used)?
>
> Mostly just curious. Anyone have any insight into this?

I've not really looked into this before but I do know that the /RAM 
driver does some strange things so I'm pretty sure nothing maps 
directly.  I know that the first file you save to /RAM gets stored 
starting at $2000 so that you can protect the hi-res area in case you 
are going to use double hi-res.

/RAM is not bootable so there is no need to have blocks 0 and 1 taking 
up memory so they aren't used at all.  /RAM also only uses a single 
directory block for the root directory instead of the usual 4 blocks and 
has moved the start block of the volume bit map from block 6 down to 
block 3.

I decided to look into it a bit and discovered that the directory block 
(block 2) is stored at $0E00 - $0FFF and the volume bit map block (block 
3) is stored at $0C00 - $0DFF.

I couldn't come up with a reasonable reason why blocks 4 to 7 are 
unavailable so I grabbed my copy of "Exploring Apple GS/OS and ProDOS 8" 
by Gary B. Little.  Here is what he has to say about the missing blocks:

      'When ProDOS 8 initializes the /RAM volume, 119 blocks are 
available for file storage.  (They are numbered from 8 to 126.)  Since a 
64K space is normally capable of holding 128 512-byte blocks, you might 
be wondering about the "missing" 9 blocks.  Two of these are relatively 
easy to track down:  One is used for the volume directory (block 2) and 
another for the volume bit map (block 3).  There is no room in auxiliary 
memory for the other seven blocks (0, 1, 4-7, and 127) because space 
must be reserved to support the /RAM disk driver itself ($0000-$03FF), 
the 80-column text screen ($0400-$07FF), the keyboard and serial input 
buffers on the Apple IIc ($0800-$08FF), and the auxiliary memory 
interrupt vectors ($FFFA-$FFFF). Thus these seven blocks are marked as 
"in use" in the /RAM volume bit map.'

He also states that $00-$3B, $44-$FF, $0900-$0BFF and $FE00-$FFF9 are 
not used but should be considered reserved.  The area from $0800-$08FF 
are only reserved on the IIc.

I don't know if anyone has ever done a memory map showing where each 
block is stored in /RAM.  That might be an interesting thing to see as 
from reading Mr. Little's section on /RAM, it turns out that first two 8 
KB files stored will use $2000-$3FFF and $4000-$5FFF by default so that 
you can protect hi-res pages 1 and 2.  However, I just checked and if 
you save a 1 block Applesoft file, it stores it in block 8 starting at 
$2000 but if you save a second 1 block Applesoft file it will store it 
in block 9 but puts it at $1000 instead of $2200 like I thought it might.

/RAM definitely does some weird stuff.  I don't know why they use blocks 
numbered 8 to 126 and skip 4 to 7.  I could see them skipping 4 to 6 as 
those blocks are normally used for file storage on standard ProDOS 
volumes.  Having blocks 7 to 125 for file storage on /RAM would make 
some sense to me as would leaving the volume bit map at block 6 and 
simply making blocks 3 to 5 unavailable.

Anyway, thanks for the fun little diversion.  :)

[toc] | [prev] | [standalone]


Back to top | Article view | comp.sys.apple2.programmer


csiph-web