User Tools

Site Tools


sd:mode_10

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
sd:mode_10 [2026/09/07 08:07] – created - external edit 127.0.0.1sd:mode_10 [2026/09/07 10:22] (current) – external edit 127.0.0.1
Line 61: Line 61:
 | ''VIDEO_CHAR_WIDTH''  | ''$01EF03'' | 1 | Character cell width in pixels | | ''VIDEO_CHAR_WIDTH''  | ''$01EF03'' | 1 | Character cell width in pixels |
 | ''VIDEO_CHAR_HEIGHT'' | ''$01EF04'' | 1 | Character cell height in pixels | | ''VIDEO_CHAR_HEIGHT'' | ''$01EF04'' | 1 | Character cell height in pixels |
-| ''VIDEO_FONT_BASE''   | ''$01EEF6'' | 3 | **NEW.** Address of the glyph data |+| ''VIDEO_FONT_BASE''   | ''$01EEF6'' | 3 | **NEW.** Where the font is (see ''VIDEO_FONT_KIND'') | 
 +| ''VIDEO_FONT_KIND''   | ''$01EF7F'' | 1 | **NEW.** 0 = glyph bitmaps at that address, 1 = font //filename// at that address |
 | ''VIDEO_ROW_STRIDE''  | ''$01EEF9'' | 2 | **NEW.** Bytes from one text row to the next | | ''VIDEO_ROW_STRIDE''  | ''$01EEF9'' | 2 | **NEW.** Bytes from one text row to the next |
 | ''VIDEO_TEXT_BASE''   | ''$01EF63'' | 3 | Address of the character plane | | ''VIDEO_TEXT_BASE''   | ''$01EF63'' | 3 | Address of the character plane |
Line 73: Line 74:
 ==== Why stride is separate from columns ==== ==== Why stride is separate from columns ====
  
-''VIDEO_ROW_STRIDE'' is normally equal to ''VIDEO_COLUMNS''and if you set it +''VIDEO_ROW_STRIDE'' is normally equal to ''VIDEO_COLUMNS'' — every preset mode 
-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 ''VIDEO_TEXT_BASE'' by extra columns sitting off-stage to the right. Advancing ''VIDEO_TEXT_BASE'' by
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, ''MODE 1'', ''MODE 2'' and ''MODE 6'' do the same thing +From Stellar BASIC, ''MODE 1'', ''MODE 2''''MODE 6'' and ''MODE 10'' do the 
-(''MODE 40'' and ''MODE 80'' are accepted as aliases for 1 and 2).+same thing (''MODE 40'' and ''MODE 80'' are accepted as aliases for 1 and 2).
  
 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 the descriptor exactly as it standsso +Mode 10 writes no preset — geometry, both planes, the row stride and the font 
-the sequence is always the same:+are left exactly as the program set them. Selecting it clears the screenand 
 +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 here, so whatever font is currently 
 +    ; 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:
 | ''$45'' | pointer to the colour plane | | ''$45'' | pointer to the colour plane |
 | ''$46'' | is this a text mode? | | ''$46'' | is this a text mode? |
-| ''$47''character ROM / glyph base |+| ''$47''ELM = ''VIDEO_FONT_BASE'', AL = ''VIDEO_FONT_KIND'' (clobbers A) |
  
 ===== Character and colour data ===== ===== Character and colour data =====
Line 223: Line 228:
 ''VIDEO_FONT_BASE'' is pointed at it during boot, so it is redefinable in ''VIDEO_FONT_BASE'' is pointed at it during boot, so it is redefinable in
 exactly the same way as yours. exactly the same way as yours.
 +
 +==== The font base is sticky ====
 +
 +''VIDEO_FONT_BASE'' is written **exactly once**, during boot, where it is
 +pointed at ''petscii_data''. No mode change ever writes it — not
 +''int10_set_video_mode'', not any of the per-mode setup routines. Two things
 +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=''$47'' reports a fixed per-mode address rather than
 +''VIDEO_FONT_BASE''.
 +
 +<code asm>
 +    LDELM [@VIDEO_FONT_BASE]    ; save the current font
 +    STELM [@saved_font]
 +
 +    LDELM @my_font              ; install ours
 +    STELM [@VIDEO_FONT_BASE]
 +    ; ...
 +
 +    LDELM [@saved_font]         ; put it back
 +    STELM [@VIDEO_FONT_BASE]
 +</code>
  
 To change a single character rather than the whole set, INT ''$10'' AH=''$48'' To change a single character rather than the whole set, INT ''$10'' AH=''$48''
Line 228: Line 263:
 (''glyph_pack'') builds a glyph from an 8x8 grid of characters, which is the (''glyph_pack'') builds a glyph from an 8x8 grid of characters, which is the
 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
 +''VIDEO_FONT_KIND'' says which. ''VIDEO_FONT_BASE'' is a pointer either way —
 +only the thing it points //at// changes:
 +
 +^ ''VIDEO_FONT_KIND'' ^ ''VIDEO_FONT_BASE'' points at ^
 +| 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            ; -> "PxPlus_IBM_VGA_9x16.ttf", 0
 +    STELM [@VIDEO_FONT_BASE]
 +    LDAL #1                     ; 1 = the pointer is a filename
 +    STAL [@VIDEO_FONT_KIND]
 +
 +    LDA $400A
 +    INT $10
 +    ...
 +
 +font_name:
 +    .bytes "PxPlus_IBM_VGA_9x16.ttf", 0
 +</code>
 +
 +Notes on file fonts:
 +
 +  * The **point size follows ''VIDEO_CHAR_HEIGHT''**. The cell size still
 +    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/pixels come from ^ Modes ^ ^ Kind ^ Where glyphs/pixels come from ^ Modes ^
-| Text, RAM font | ''VIDEO_FONT_BASE'' | 1, 2, 10 | +| Text, RAM font | ''VIDEO_FONT_BASE'', ''VIDEO_FONT_KIND=0'' | 1, 2, 10 | 
-| Text, file font | a TrueType file on the host | 6 |+| Text, file font | ''VIDEO_FONT_BASE'', ''VIDEO_FONT_KIND=1'' | 10 | 
 +| Text, file font (fixed) | a TrueType file named in the emulator | 6 |
 | 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 ''PxPlus_IBM_VGA_9x16.ttf'' rather than read from glyphs are rasterised from ''PxPlus_IBM_VGA_9x16.ttf'' rather than read 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. It simply means ''VIDEO_FONT_BASE'' does not apply to it.+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 ''VIDEO_FONT_BASE'' at the 
 +filename and set ''VIDEO_FONT_KIND'' to 1.
  
 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 and limitations ===== +===== 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 from a program: write the registers, then either set +  * mode 10 is selectable from a program (''LDA $400A'' ''INT $10''), from 
-    ''VIDEO_MODE'' to 10 or call INT ''$10'' with ''AL=$0A''+    BASIC (''MODE 10''), and clears the screen like any other mode 
 +  * every preset mode writes ''VIDEO_ROW_STRIDE''; mode 10 preserves it
   * fonts may be relocated and redefined through ''VIDEO_FONT_BASE''   * fonts may be relocated and redefined through ''VIDEO_FONT_BASE''
 +  * a text mode may draw with a host font file via ''VIDEO_FONT_KIND=1''
 +  * AH=''$47'' reports the real font pointer and its kind, in every mode
  
-What is not finished:+Still to come:
  
-  * **Mode 10 does not clear the screen.** ''int10_set_video_mode'' does not 
-    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 ''VIDEO_ROW_STRIDE''.** Modes 2 and 6 leave it as they 
-    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=''$47'' still reports a per-mode fixed address** rather than 
-    ''VIDEO_FONT_BASE'', so it will not tell you the truth in mode 10. 
   * 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=''$4A'') has been proposed but not written; for now, write the     function (AH=''$4A'') has been proposed but not written; for now, write the
-    nine registers.+    registers
 +  * Mode changes do not restore the font. Only boot writes 
 +    ''VIDEO_FONT_BASE'', so a custom font survives a switch back to mode 1. 
 +    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

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki