Post by Chris TobarI'll admit I'm still pretty lost with the terminology about memory though.
There is a LOT of terminology with the Apple 2 -- you'll pick it up over time.
I'm assuming you are referring to the phrase "memory mapped non-linear framebuffer with screen holes" ?
Let's break this down in byte-sized chunks that more digestable:
= Memory Mapped =
The text and graphics screens are basically an array of bytes. From BASIC we can "POKE" (set) values and they will show up as characters (text screen) or pixels (graphics screen)
In C this would look like:
char TextScreen1[ 24 ][ 40 ];
For example
TEXT:HOME
Will set text mode (40x24) and clear it.
POKE 1024,1
Will show an "inverse" A.
POKE 1025,65
Will show an "flashing" A and
POKE 1026,65+128
will show a normal A.
You could think of a POKE is directly doing this:
C:
TextScreen1[ 0 ] = 'A';
Applesoft:
POKE 1024,65
You can find a list of ASCII values and a memory map with the famous "Beagle Bros Peeks, Pokes, and Pointers" side B poster:
Loading Image...Now this probably begs the question: Why are the values:
* 1 inverse,
* 65 flashing, and
* 193 normal?
That has to do with the "character set" built into the Apple. Here is an example:
Loading Image...Woz decided to have the hardware support different "text styles" based on what values the characters were.
* $00..$3F Inverse
* $40..$7F Flashing
* $80..$FF Normal
Setting values in specific memory locations, $400 .. $7FF corresponds to the Text Page 1 area.
In case you aren't familiar with the $ prefix -- that is the character most Apple 2 programmers use to refer to hex values. In VB6 it is the &H.
i.e. The "A" character is 65 decimal or 41 in hex:
Apple 2 notation:
$41
Basic notation:
&H41
C notation:
0x41
= Page Flipping =
There are also two "pages" of which only 1 is visible. This means we can do smooth "page flipping" animation.
I.e. We can show the 1st, draw on the 2nd, then "flip" to showing the 2nd, draw on the 1st, repeat.
For example:
CALL-151
C055
C054
E003G
When you typed C055 <RETURN> it shows a screen full of "Junk".
What you were looking at was Text Page 2 -- which normally contains your Applesoft program.
= Framebuffer =
This just means that of the 64K (65,536 bytes) in an Apple 2 that there are:
* 1,024 are reserved for the Text Page 1
* 1,024 are reserved for the Text Page 2
* 8,192 are reserved for the High Resolution Graphics Page 1 (280x192)
* 8,192 are reserved for the High Resolution Graphics Page 2 (280x192)
Now you may be asking -- what happened to the Low Resolution Graphics (GR) memory areas? They are _shared_ with the Text Page.
For example:
GR:POKE 1024,65:POKE 2000,65
Will plot TWO vertical pixels -- red and green respectively AND a flashing A in the bottom left.
Then if we type:
TEXT
Notice how the text screen is filled with inverse '@' ? This is because in GR mode the value $00 are two black pixels, but in TEXT mode shows up as an inverse '@'.
This value $A0 shows up BLACK on top of GREY in GR mode but as a space in TEXT mode.
i.e.
TEXT:CALL-151
C050
FC58G
E003G
TEXT
= Non-Linear =
In any modern system we would normally have something like this for a 40x24 screen:
char TextScreen1[ 24 ][ 40 ];
This is called a "linear" layout, because ALL the memory is contiguous.
When Woz designed the Apple he decided to break the screen layout into triads. What we really have is this layout:
struct Text40x24
{
char rows00_08_16[ 40 ];
char pad0[ 8 ];
char rows01_09_17[ 40 ];
char pad1[ 8 ];
char rows02_10_18[ 40 ];
char pad2[ 8 ];
char rows03_11_19[ 40 ];
char pad3[ 8 ];
char rows04_12_20[ 40 ];
char pad4[ 8 ];
char rows05_13_21[ 40 ];
char pad5[ 8 ];
char rows06_14_22[ 40 ];
char pad6[ 8 ];
char rows07_15_23[ 40 ];
char pad7[ 8 ];
};
This is called "non-linear" because _inbetween_ each "row" are 8 bytes of padding.
= Screen Holes =
The "pad" section are also called "screen holes" because they are NEVER displayed. To prove this:
TEXT:HOME:POKE 1143,255:POKE 1144,255
There are a total of ...
$478 .. $47F
$4F8 .. $4FF
$578 .. $57F
$5F8 .. $5FF
$678 .. $67F
$6F8 .. $6FF
$778 .. $77F
$7F8 .. $7FF
... 8x8 = 64 memory locations that are NOT used. You can "POKE" whatever values you want into them and they will never show up.
The operatoring sytem (DOS3.3, ProDOS, etc.) and the Peripherals are free to use these values as "scratch" memory locations.
= Saving / Loading =
Normally we would just "BSAVE" the entire 1,024 chunks of of the TEXT (or GR) memory via:
BSAVE DRAWING1.GR,A$400,L$400
But due to a "fluke "of DOS3.3 dumb design and the Text memory layout -- the last 8 bytes of $7F8 .. $7FF are never displayed -- we can (b)save the TEXT (or GR) screen via:
BSAVE DRAWING1.GR,A$400,L$3F8
to take up 1 less sector on disk.
Similarly, to load a TEXT (or GR) screen that had been previously saved:
BLOAD DRAWING1.GR,A$400
On disk our graphics file has this layout ...
+--------------+
| rows00_08_16 |
| pad0 |
| rows01_09_17 |
| pad1 |
| rows02_10_18 |
| pad2 |
| rows03_11_19 |
| pad3 |
| rows04_12_20 |
| pad4 |
| rows05_13_21 |
| pad5 |
| rows06_14_22 |
| pad6 |
| rows07_15_23 |
| pad7 |
+--------------+
Since we _don't_ want to touch the screen holes AND don't want to waste space storing them we really want to (b)save this layout:
+--------------+
| rows00_08_16 |
| rows01_09_17 |
| rows02_10_18 |
| rows03_11_19 |
| rows04_12_20 |
| rows05_13_21 |
| rows06_14_22 |
| rows07_15_23 |
+--------------+
This means we need TWO areas:
1) The non-linear TEXT (or GR) region
2) A linear BUFFER
The "Pack" and "Unpack" mentioned into the earlier emails do this:
* "Pack" (Copy) the TEXT (or GR) framebuffer to a buffer located in the HGR region
* "Unpack" (Copy) the HGR region back into the TEXT (or GR) framebuffer.
Hope this helps clear up how the GR memory is layed out in the Apple 2.
Michael