Scroll the screen sideways, and by less than a cell
The screen could move one way, a cell at a time. Three registers were missing and this adds them: a column origin so the map can be wider than the screen as well as taller, and a pixel remainder for each axis so the step can be one pixel rather than eight. 0x36 Scroll column, in cells, wrapping at 128 0x37 Fine X, 0 to 7 pixels 0x38 Fine Y, 0 to 7 pixels FINE DOES NOT CARRY INTO COARSE. Writing 8 to a fine register writes 0, because only its low three bits mean anything. The alternative was for a write of 8 to step the coarse register, and it was rejected for one reason: a program that scrolls has to know where it has got to, and if the hardware carries then the only way to find out is to read the register back. Keeping them apart means the program already knows, because it did the arithmetic itself. It is also what the machines this one is pretending to be did. The renderer now draws one more row and one more column than fit and clips them, because with a fine offset the screen no longer begins on a cell boundary and the cells at two edges are partly off it. videoPutCell follows the column origin as it has always followed the row - a caller means a cell of the SCREEN, and the screen is a window onto the map. The fine offsets are deliberately not applied there: they move the finished picture by less than a cell, and there is no such thing as less than a cell to write into. So a program may scroll to any pixel without the console's idea of where row three, column five is moving underneath it. Grid now scrolls diagonally, a pixel a frame, in four port writes and two carries. It moved eight pixels every fourth frame before, which reads as the picture jumping rather than travelling. Seven checks, each one the same program with one register changed, so what is compared is where the picture stopped. Breaking fine X, fine Y, the column origin, the three-bit mask, or the console's use of the origin each fails exactly one of them. Grid's own two checks had to be rewritten, and the reason is worth keeping: they asked whether pixel 4 was a grid line, which was really a check that the scroll happened to be at a cell boundary. A picture that moves a pixel a frame can only be asked things that are true at every offset - that it repeats every eight pixels, and that one band of eight rows holds different colours from the next. Also repairs docs.sh, which found the minimal CosmOS application by taking the first asm block in the README. Documenting a program with an example above it made that a different block, and the check complained that the minimal application had no #Base about something that never claimed to be one. It looks under System Services now. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E2JrLzFvuFX9fgi1LDRjrW
This commit is contained in:
co-authored by
Claude Opus 5
parent
848103f5e4
commit
bcd42e75ca
@@ -597,8 +597,11 @@ The high nibble is reserved and should be left at zero, so that a meaning can be
|
||||
| 0x31 | Mode. |
|
||||
| 0x32 | Columns, read only. |
|
||||
| 0x33 | Rows, read only. |
|
||||
| 0x34 | Scroll. |
|
||||
| 0x34 | Scroll row. Which of the map's 128 rows is drawn at the top. |
|
||||
| 0x35 | Control. Bit 0 asks to be interrupted at each frame. |
|
||||
| 0x36 | Scroll column. Which of the map's 128 columns is drawn at the left. |
|
||||
| 0x37 | Fine X. How many pixels into that column the screen begins, 0 to 7. |
|
||||
| 0x38 | Fine Y. How many pixels into that row the screen begins, 0 to 7. |
|
||||
|
||||
| Mode | Screen | Cells |
|
||||
| --- | --- | --- |
|
||||
@@ -648,6 +651,39 @@ Scrolling therefore moves a register and no memory at all. That is not a small s
|
||||
|
||||
And the rows that scrolled off are still in the map, which is where a terminal on this machine gets scrollback without having to keep any.
|
||||
|
||||
**The columns are the same ring the other way.** A map row is 256 bytes and a cell is two, so there are 128 of them whatever the mode shows - 88 more than a 40 column screen displays, and 48 more than an 80. Scroll column says which one is at the left, and screen column *c* shows map column *scroll column + c*, wrapped. A map wider than the screen costs nothing to have, because the map is that wide already.
|
||||
|
||||
### Scrolling By Less Than A Cell:
|
||||
|
||||
The two registers above move the view a whole cell at a time, which is a scrolling text screen rather than a scrolling picture: eight pixels is a long way to jump sixty times a second. **Fine X and Fine Y are the remainder** - how far into the cell at the origin the screen actually starts. Together the four registers place the view anywhere in the map to the pixel.
|
||||
|
||||
The screen no longer begins on a cell boundary when a fine register is not zero, so the cells at two edges are partly off it. That is the device's problem and not a program's: it draws one more row and one more column than fit and clips them.
|
||||
|
||||
**Fine does not carry into coarse.** Writing 8 to a fine register is writing 0, because only the low three bits of it mean anything - it is not one cell along. A program scrolling past a cell edge advances the coarse register itself:
|
||||
|
||||
```asm
|
||||
; One pixel to the left, carrying when it runs out of cell.
|
||||
SETD.0 FineX
|
||||
LDA.0
|
||||
INCA
|
||||
INIB 0x07
|
||||
AND
|
||||
STQ.0
|
||||
BNQ scrolled ; Still inside the cell.
|
||||
SETD.0 CoarseX
|
||||
LDA.0
|
||||
INCA
|
||||
STA.0
|
||||
OUTA 0x36
|
||||
scrolled:
|
||||
```
|
||||
|
||||
The alternative was to let a write of 8 step the column and set the fine part to zero, and it was rejected for one reason: a program that scrolls has to know where it has got to, and if the hardware carries then the only way to find out is to read the register back. Keeping them apart means the program already knows, because it did the arithmetic.
|
||||
|
||||
**The fine registers move the picture and nothing else.** Writing a character still lands in a whole cell, because there is no such thing as less than a cell to write into - so a program may scroll to any pixel and the console's idea of where row three, column five is does not move underneath it. The coarse registers are the ones the console follows, and it has always followed the row.
|
||||
|
||||
**None of the four does anything in bitmap mode**, which has no map to slide.
|
||||
|
||||
### Writing On The Screen:
|
||||
|
||||
A console on a machine with a screen sends every byte to both, because a machine with a screen and a serial line is an ordinary machine and there is one console driving both.
|
||||
|
||||
Reference in New Issue
Block a user