diff options
Diffstat (limited to 'doc')
| -rw-r--r-- | doc/dynamic-screens.txt | 110 |
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 |
