sd:mode_10
Differences
This shows you the differences between two versions of the page.
| Next revision | Previous revision | ||
| sd:mode_10 [2026/09/07 08:07] – created - external edit 127.0.0.1 | sd:mode_10 [2026/09/07 10:22] (current) – external edit 127.0.0.1 | ||
|---|---|---|---|
| Line 61: | Line 61: | ||
| | '' | | '' | ||
| | '' | | '' | ||
| - | | '' | + | | '' |
| + | | '' | ||
| | '' | | '' | ||
| | '' | | '' | ||
| Line 73: | Line 74: | ||
| ==== Why stride is separate from columns ==== | ==== Why stride is separate from columns ==== | ||
| - | '' | + | '' |
| - | smaller it is silently raised to the column count. Making it **larger** is the | + | sets it that way when you select it — and if you set it smaller it is silently |
| + | raised to the column count. **Mode 10 is the exception: it leaves the stride | ||
| + | alone**, so a wider buffer survives being selected. Making it **larger** is the | ||
| interesting case: it gives you a text buffer wider than the screen, with the | interesting case: it gives you a text buffer wider than the screen, with the | ||
| extra columns sitting off-stage to the right. Advancing '' | extra columns sitting off-stage to the right. Advancing '' | ||
| Line 105: | Line 108: | ||
| * mode 6 — 80x25, 9x16 cells, 720x400 (see [[#three kinds of mode]]) | * mode 6 — 80x25, 9x16 cells, 720x400 (see [[#three kinds of mode]]) | ||
| - | From Stellar BASIC, '' | + | From Stellar BASIC, '' |
| - | ('' | + | same thing ('' |
| These presets write the whole descriptor for you. Everything below is about | These presets write the whole descriptor for you. Everything below is about | ||
| Line 113: | Line 116: | ||
| ===== Programming mode 10 ===== | ===== Programming mode 10 ===== | ||
| - | Mode 10 writes no preset. It renders | + | Mode 10 writes no preset |
| - | the sequence is always the same: | + | are left exactly as the program set them. Selecting |
| + | that is all it does. The sequence is always the same: | ||
| - fill in the descriptor registers | - fill in the descriptor registers | ||
| Line 139: | Line 143: | ||
| STELM [@VIDEO_COLOR_BASE] | STELM [@VIDEO_COLOR_BASE] | ||
| - | ; VIDEO_FONT_BASE is left alone here, so the system font is used | + | ; VIDEO_FONT_BASE is not written |
| + | ; selected stays in effect -- after boot that is the system font | ||
| LDA $400A ; AH=$40 set mode, AL=$0A (10) | LDA $400A ; AH=$40 set mode, AL=$0A (10) | ||
| Line 172: | Line 177: | ||
| | '' | | '' | ||
| | '' | | '' | ||
| - | | '' | + | | '' |
| ===== Character and colour data ===== | ===== Character and colour data ===== | ||
| Line 223: | Line 228: | ||
| '' | '' | ||
| exactly the same way as yours. | exactly the same way as yours. | ||
| + | |||
| + | ==== The font base is sticky ==== | ||
| + | |||
| + | '' | ||
| + | pointed at '' | ||
| + | '' | ||
| + | follow from that: | ||
| + | |||
| + | * Leaving it alone gives you **whatever font was last selected**, not | ||
| + | specifically the system font. Immediately after boot those are the same | ||
| + | thing, which is why the example above works. | ||
| + | * A font you install **stays installed across mode changes**. Set a custom | ||
| + | font in mode 10, switch to mode 1, and mode 1 will draw with your font. | ||
| + | |||
| + | If you intend to put the system font back afterwards, **save the old pointer | ||
| + | before you overwrite it**. There is currently no call that will tell you what | ||
| + | it was: AH='' | ||
| + | '' | ||
| + | |||
| + | <code asm> | ||
| + | LDELM [@VIDEO_FONT_BASE] | ||
| + | STELM [@saved_font] | ||
| + | |||
| + | LDELM @my_font | ||
| + | STELM [@VIDEO_FONT_BASE] | ||
| + | ; ... | ||
| + | |||
| + | LDELM [@saved_font] | ||
| + | STELM [@VIDEO_FONT_BASE] | ||
| + | </ | ||
| To change a single character rather than the whole set, INT '' | To change a single character rather than the whole set, INT '' | ||
| Line 228: | Line 263: | ||
| ('' | ('' | ||
| convenient one to call from BASIC. | convenient one to call from BASIC. | ||
| + | |||
| + | ===== Using a font file instead of a bitmap ===== | ||
| + | |||
| + | A text mode's glyphs can come from RAM or from a font file on the host, and | ||
| + | '' | ||
| + | only the thing it points //at// changes: | ||
| + | |||
| + | ^ '' | ||
| + | | 0 | glyph bitmaps, in the layout above | | ||
| + | | 1 | a NUL-terminated filename | | ||
| + | |||
| + | <code asm> | ||
| + | ; ---- 80x25 with 9x16 cells, drawn with a real VGA typeface ---- | ||
| + | LDAL #80 | ||
| + | STAL [@VIDEO_COLUMNS] | ||
| + | LDAL #25 | ||
| + | STAL [@VIDEO_ROWS] | ||
| + | LDAL #9 | ||
| + | STAL [@VIDEO_CHAR_WIDTH] | ||
| + | LDAL #16 | ||
| + | STAL [@VIDEO_CHAR_HEIGHT] | ||
| + | |||
| + | LDELM @font_name | ||
| + | STELM [@VIDEO_FONT_BASE] | ||
| + | LDAL #1 ; 1 = the pointer is a filename | ||
| + | STAL [@VIDEO_FONT_KIND] | ||
| + | |||
| + | LDA $400A | ||
| + | INT $10 | ||
| + | ... | ||
| + | |||
| + | font_name: | ||
| + | .bytes " | ||
| + | </ | ||
| + | |||
| + | Notes on file fonts: | ||
| + | |||
| + | * The **point size follows '' | ||
| + | governs layout; glyphs are clipped or padded into the cell, so the two do | ||
| + | not have to agree perfectly. | ||
| + | * The name is a **plain filename, looked for in the assets directory**. Any | ||
| + | directory part is discarded — a program cannot reach elsewhere on the host. | ||
| + | * The font is rendered **once** and cached. It is rebuilt only when the | ||
| + | filename or the cell size changes; rasterising 256 glyphs is far too slow | ||
| + | to do per frame. | ||
| + | * If the font cannot be loaded the reason is reported once and the previous | ||
| + | frame stays on screen, rather than the display going blank. | ||
| + | |||
| + | Internally a file font is converted into exactly the bitmap layout described | ||
| + | above, so nothing else about the mode behaves differently. | ||
| ===== Rules the descriptor must satisfy ===== | ===== Rules the descriptor must satisfy ===== | ||
| Line 250: | Line 335: | ||
| ^ Kind ^ Where glyphs/ | ^ Kind ^ Where glyphs/ | ||
| - | | Text, RAM font | '' | + | | Text, RAM font | '' |
| - | | Text, file font | a TrueType file on the host | 6 | | + | | Text, file font | '' |
| + | | Text, file font (fixed) | ||
| | Framebuffer | pixel data in RAM | 3, 4, 5, 7, 8 | | | Framebuffer | pixel data in RAM | 3, 4, 5, 7, 8 | | ||
| Line 258: | Line 344: | ||
| glyphs are rasterised from '' | glyphs are rasterised from '' | ||
| RAM. That is a feature, not an oversight: it is how you get a real VGA | RAM. That is a feature, not an oversight: it is how you get a real VGA | ||
| - | typeface. | + | typeface. |
| + | |||
| + | Mode 6 still names its font inside the emulator rather than through the | ||
| + | descriptor, so it remains a mode of its own. Mode 10 can now reach the same | ||
| + | place under program control: set 9x16 cells, point '' | ||
| + | filename and set '' | ||
| Framebuffer modes are a separate discussion and are not covered here. | Framebuffer modes are a separate discussion and are not covered here. | ||
| Line 297: | Line 388: | ||
| descriptor registers directly. | descriptor registers directly. | ||
| - | ===== Current status | + | ===== Current status ===== |
| - | + | ||
| - | What works today: | + | |
| * modes 1, 2 and 10 all run through the descriptor-driven renderer | * modes 1, 2 and 10 all run through the descriptor-driven renderer | ||
| - | * mode 10 is reachable | + | * mode 10 is selectable |
| - | | + | BASIC ('' |
| + | * every preset mode writes '' | ||
| * fonts may be relocated and redefined through '' | * fonts may be relocated and redefined through '' | ||
| + | * a text mode may draw with a host font file via '' | ||
| + | * AH='' | ||
| - | What is not finished: | + | Still to come: |
| - | * **Mode 10 does not clear the screen.** '' | ||
| - | recognise 10 yet, so it stores the mode number and returns without running | ||
| - | the clear-and-home path. Clear the screen yourself after switching, or the | ||
| - | previous mode's characters will still be sitting there. | ||
| - | * **Only mode 1 writes '' | ||
| - | found it. Every current path still renders correctly because a stride | ||
| - | smaller than the column count is corrected up, but do not rely on it — | ||
| - | write the stride yourself when you write the rest of the descriptor. | ||
| - | * **AH='' | ||
| - | '' | ||
| * There is no single call that installs a whole descriptor. A convenience | * There is no single call that installs a whole descriptor. A convenience | ||
| function (AH='' | function (AH='' | ||
| - | | + | registers. |
| + | * Mode changes do not restore the font. Only boot writes | ||
| + | '' | ||
| + | Whether presets should reset it is undecided — see [[#the font base is sticky]]. | ||
| + | * Mode 6 still names its font inside the emulator rather than through the | ||
| + | descriptor. | ||
sd/mode_10.1788768473.txt.gz · Last modified: by 127.0.0.1
