aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/dynamic-screens.txt110
1 files changed, 35 insertions, 75 deletions
diff --git a/doc/dynamic-screens.txt b/doc/dynamic-screens.txt
index f6a0c89..5ed333e 100644
--- a/doc/dynamic-screens.txt
+++ b/doc/dynamic-screens.txt
@@ -1,9 +1,6 @@
Dynamic screen memory for FujiNetChat
-------------------------------------
-This *doesn't exist* yet, even if I speak of it in the present tense
-in this document!
-
Goals:
- Maximize use of available memory for scrollback. This means variable
@@ -17,9 +14,8 @@ Goals:
a bunch of memory reserved for the screens you don't use. You'll only
pay for what you use.
-- Compatible with 48K, 64K (using RAM under OS), 130XE, and at least
- 256K or 320K upgraded memory. It will be able to use as much RAM as
- you have, up to some limit (U1MB?).
+- Compatible with 48K, 64K (using RAM under OS), 130XE, and up to 1MB
+ of extended RAM (1088K total).
- *Not* require the 130XE's separate ANTIC access mode. While this
might be helpful, there's a large installed base of expanded 800XLs
@@ -95,90 +91,56 @@ Screen height - the total number of lines in a screen (includes all
its chunks). The minimum height of a screen, upon creation, is
actually 0: it has no lines until it's written to.
-Line - 42 bytes of memory that store 40 characters (one GR.0 line) of
+Line - 43 bytes of memory that store 40 characters (one GR.0 line) of
text, plus a 2-byte pointer to the next line (in the screen, or in
- the free line list). Lines in a screen are stored in a linked list
- (each points to the next), in reverse order of how they're displayed
- (bottom-most points to the 2nd-to-bottom, etc, and the top one in
- a screen points to the End Marker). Lines in the free list are also
- stored as a linked list, associated with the pool, not any screen.
- Lines can cross 4K boundaries because they're not directly displayed
- by ANTIC.
+ the free line list) and the bank of the next line. Lines in a
+ screen are stored in a linked list (each points to the next), in
+ reverse order of how they're displayed (bottom-most points to the
+ 2nd-to-bottom, etc, and the top one in a screen points to the End
+ Marker). Lines in the free list are also stored as a linked list,
+ associated with the pool, not any screen. Lines can cross 4K
+ boundaries because they're not directly displayed by ANTIC.
Free Line - a line that isn't being used by any screen. All the
free lines in a pool are a linked list: initializing the pool
sets up the pointers in all the lines. Closing a screen releases
all its used lines into the pool's free line list.
-Pool - A (possibly non-contiguous) region of memory available for lines.
- Each pool has a bank number, a count of unused lines, and a linked
- list of the unused lines in the pool. Pool 0 is in main memory,
- is always at least 16K, and can be up to 26880 bytes in size (using
- 4K of under-the-OS RAM for an XL/XE, plus any space from MEMLO
- to $2000 if DOS is not booted, or if a DOS with low MEMLO is
- booted). The other pools consist of entire banks, 16K apiece, one
- per bank. Each screen is created in one pool and cannot be moved to
- another pool.
+Pool - The list of free lines. Spans banks (which is why the lines
+ have a bank in addition to the next pointer). There is only
+ one pool. There's no requirement for memory in the pool to be
+ contiguous.
+
+Visible Buffer - A 920-byte (23-line) area of display memory in main
+ memory (outside the banking window). Since lines can be in any
+ memory bank, this is what gets displayed. Every time the current
+ screen changes (has new text added to it, or you switch to a
+ different screen), this gets updated.
Initialization:
-At startup, FujiNetChat detects the amount of memory (number of
-extended banks) and creates a pool for each bank. Bank 0's pool can
-include extra memory beyond 16K: whatever's not in use by the client,
-or by DOS (if you booted with one, even). Also pool 0 might have some
-of the RAM under the OS on XL/XE (because FujiNetChat doesn't use the
-two 1K ROM fonts or the 2K math pack, so we get 4K "for free"). All other
-pools (1 and up) will be 16K.
+The FujiNetChat config detects the amount of memory (number of
+extended banks). It stores the total number of banks (up to 64)
+at $06bf, and the list of banks at $06c0.
+
+The client creates the pool using the info at $06bf-$06ff. This
+must happen *before* edbox_clear() is called for the first time,
+since this clears page 6.
At startup, the [server] and [private] screens will be created. Also
autojoin channels/queries will each get a screen created.
-When creating screens, they're assigned to pools in round-robin
-style. Suppose we have 5 banks of memory (0 through 4), with one pool
-each. The first screen is created in bank 0. The second screen will be
-created in bank 1, 3rd in bank 3, etc. After all pools have one screen
-in them, the next screen creation will use pools 0 again (so now
-we have two screens in one pools). This can continue until we reach
-whatever the limit is: 15 screens? 20? Maybe calculated based on the
-number of banks, so we can guarantee that when all memory is in use,
-each screen will have a minimum of 23 lines. With a 130XE, this would
-be a stupid amount of screens: 17 per bank for the 4 extended banks,
-and at least 17 for bank 0 (so 85 of them, that's too many). Maybe
-limit it to 28, which guarantees each screen can be 3 chunks (69
-lines) tall?
-
-The reason for the round-robin creation: Suppose you're only going to
-use 3 screens (server, private, and one channel). It makes more sense
-for each of those 3 to be in its own bank, so each one can grow to
-16K (around 390 lines, or ~17 chunks). If we created them all in bank 0,
-they'd compete with each other for memory, which is silly when there's
-plenty of free RAM in the other (unused) banks.
+When creating a screen, no lines are allocated at first. Lines
+only get added to a screen when needed (when a new line of text is
+printed).
Writing text to a screen consists of...
-- Find a free line in the screen's pool (see below).
-- Fill the line with the new text.
-- Make the line's 'next' pointer point to the screen's 'head' pointed to.
+- Find a free line in the pool (see below).
+- Make the line's 'next' pointer point to what the screen's 'head'
+ pointed to.
- Make the screen's 'head' point to the new line.
-
-The lines in a screen are stored as a textbook example of a linked list.
-
-What happens if we're displaying a screen in one bank, and need
-to add text to a screen that's in a different bank? Well, we have
-to bankswitch to write to the new bank. But doing so will make that
-bank replace the screen memory for the screen we were looking at. So,
-bankswitching and writing has to take place during the vertical blank
-interval, when ANTIC is done displaying the screen and no longer
-reading from RAM.
-
-*Careful*, without writing the code I don't yet know if there's enough
-time in one VBLANK to write a huge (up to 510 bytes) IRC message in
-one go. It'll be OK if it takes more than one frame, but not more than
-maybe 4 or 5 (that'll make the app feel sluggish). Assembly optimization
-is a must for this. Also, we don't have to wait for the VBLANK interrupt
-to happen: we can start after the last visible scanline and work through
-until just before the start of the first visible scanline on the next
-frame.
+- Fill the line with the new text.
Finding a free line:
@@ -219,12 +181,10 @@ lines) or the status bar (one GR.0 line, one GR.1). The top LMS points
to a 920-byte (23 line) buffer in main (non-bankable) memory. This
buffer gets line data copied to it from the screen's lines.
-Switch to the screen's bank, then...
-
Starting at the screen's 'head' line, walk the linked list [scroll
height] times (0 if we're not scrolled up, 23 if we're scrolled up
one chunk, etc). This brings us to the first line that should be
-displayed.
+displayed. Note that walking the list includes switching banks!
When we've walked to the first (bottom-most) line to display (which will
be the 'head' one, if we weren't scrolled back), copy its data to the