Character definitions; Boot message; VDU tables - 1216 bytes (7.4%)
- §1. Character definitions
- §2. Screen initialisation on reset
- §3. The boot message
- §4. Four colour conversion table
- §5. Sixteen colour conversion table
- §6. Table of addresses (low byte) to handle VDU N
- §7. Table of addresses (high byte) to handle VDU N
- §8. Multiplication tables
- §9. Screen MODE dimensions
- §10. Video Control Register of the VideoULA
- §11. Pixel tables
- §12. gcolPlotOptionsTable
- §13. Solid colour tables
- §14. Hardware scroll tables
- §15. VDU Line Plotting
- §16. Converting characters in Teletext
- §17. Soft character table offsets
This is the start of the OS, located at $C000. The shape of each printable character (ASCII codes 32-126) is defined below. They are used to draw text in all non-teletext MODEs 0-6 (see .displayACharacter). Character 127 (DELETE) is not a printable character, but is given a definition here anyway as a solid block of set pixels. It's drawn in the background colour to erase the character at the graphics cursor. Characters already drawn can be read from the screen, to retrieve the ASCII code from the pattern of pixels on screen. The OS itself uses this when in cursor editing mode (the two cursor editing with READ and WRITE cursors, as seen in the BASIC line editor and user text input in general). See .osbyte135EntryPoint. Historical note: The BBC Micro was Acorn's first computer to contain a character set in ROM, unless you count the seven-segment LED settings for the hex digits 0 to F in the tiny Acorn System 1. The System 2 used teletext graphics akin to the BBC's Mode 7, and the Atom's rather smaller set of symbols (which lacked lower-case letters) were similarly generated directly in the video circuitry rather than being plotted from symbols in ROM.
* = $C000 .characterDefinitions = $c000 !byte %........ !byte %........ !byte %........ !byte %........ !byte %........ !byte %........ !byte %........ !byte %........ !byte %...##... !byte %...##... !byte %...##... !byte %...##... !byte %...##... !byte %........ !byte %...##... !byte %........ !byte %.##.##.. !byte %.##.##.. !byte %.##.##.. !byte %........ !byte %........ !byte %........ !byte %........ !byte %........ !byte %..##.##. !byte %..##.##. !byte %.####### !byte %..##.##. !byte %.####### !byte %..##.##. !byte %..##.##. !byte %........ !byte %....##.. !byte %..###### !byte %.##.#... !byte %..#####. !byte %....#.## !byte %.######. !byte %...##... !byte %........ !byte %.##..... !byte %.##..##. !byte %....##.. !byte %...##... !byte %..##.... !byte %.##..##. !byte %.....##. !byte %........ !byte %..###... !byte %.##.##.. !byte %.##.##.. !byte %..###... !byte %.##.##.# !byte %.##..##. !byte %..###.## !byte %........ !byte %....##.. !byte %...##... !byte %..##.... !byte %........ !byte %........ !byte %........ !byte %........ !byte %........ !byte %....##.. !byte %...##... !byte %..##.... !byte %..##.... !byte %..##.... !byte %...##... !byte %....##.. !byte %........ !byte %..##.... !byte %...##... !byte %....##.. !byte %....##.. !byte %....##.. !byte %...##... !byte %..##.... !byte %........ !byte %........ !byte %...##... !byte %.######. !byte %..####.. !byte %.######. !byte %...##... !byte %........ !byte %........ !byte %........ !byte %...##... !byte %...##... !byte %.######. !byte %...##... !byte %...##... !byte %........ !byte %........ !byte %........ !byte %........ !byte %........ !byte %........ !byte %........ !byte %...##... !byte %...##... !byte %..##.... !byte %........ !byte %........ !byte %........ !byte %.######. !byte %........ !byte %........ !byte %........ !byte %........ !byte %........ !byte %........ !byte %........ !byte %........ !byte %........ !byte %...##... !byte %...##... !byte %........ !byte %........ !byte %.....##. !byte %....##.. !byte %...##... !byte %..##.... !byte %.##..... !byte %........ !byte %........ !byte %..####.. !byte %.##..##. !byte %.##.###. !byte %.######. !byte %.###.##. !byte %.##..##. !byte %..####.. !byte %........ !byte %...##... !byte %..###... !byte %...##... !byte %...##... !byte %...##... !byte %...##... !byte %.######. !byte %........ !byte %..####.. !byte %.##..##. !byte %.....##. !byte %....##.. !byte %...##... !byte %..##.... !byte %.######. !byte %........ !byte %..####.. !byte %.##..##. !byte %.....##. !byte %...###.. !byte %.....##. !byte %.##..##. !byte %..####.. !byte %........ !byte %....##.. !byte %...###.. !byte %..####.. !byte %.##.##.. !byte %.######. !byte %....##.. !byte %....##.. !byte %........ !byte %.######. !byte %.##..... !byte %.#####.. !byte %.....##. !byte %.....##. !byte %.##..##. !byte %..####.. !byte %........ !byte %...###.. !byte %..##.... !byte %.##..... !byte %.#####.. !byte %.##..##. !byte %.##..##. !byte %..####.. !byte %........ !byte %.######. !byte %.....##. !byte %....##.. !byte %...##... !byte %..##.... !byte %..##.... !byte %..##.... !byte %........ !byte %..####.. !byte %.##..##. !byte %.##..##. !byte %..####.. !byte %.##..##. !byte %.##..##. !byte %..####.. !byte %........ !byte %..####.. !byte %.##..##. !byte %.##..##. !byte %..#####. !byte %.....##. !byte %....##.. !byte %..###... !byte %........ !byte %........ !byte %........ !byte %...##... !byte %...##... !byte %........ !byte %...##... !byte %...##... !byte %........ !byte %........ !byte %........ !byte %...##... !byte %...##... !byte %........ !byte %...##... !byte %...##... !byte %..##.... !byte %....##.. !byte %...##... !byte %..##.... !byte %.##..... !byte %..##.... !byte %...##... !byte %....##.. !byte %........ !byte %........ !byte %........ !byte %.######. !byte %........ !byte %.######. !byte %........ !byte %........ !byte %........ !byte %..##.... !byte %...##... !byte %....##.. !byte %.....##. !byte %....##.. !byte %...##... !byte %..##.... !byte %........ !byte %..####.. !byte %.##..##. !byte %....##.. !byte %...##... !byte %...##... !byte %........ !byte %...##... !byte %........ !byte %..####.. !byte %.##..##. !byte %.##.###. !byte %.##.#.#. !byte %.##.###. !byte %.##..... !byte %..####.. !byte %........ !byte %..####.. !byte %.##..##. !byte %.##..##. !byte %.######. !byte %.##..##. !byte %.##..##. !byte %.##..##. !byte %........ !byte %.#####.. !byte %.##..##. !byte %.##..##. !byte %.#####.. !byte %.##..##. !byte %.##..##. !byte %.#####.. !byte %........ !byte %..####.. !byte %.##..##. !byte %.##..... !byte %.##..... !byte %.##..... !byte %.##..##. !byte %..####.. !byte %........ !byte %.####... !byte %.##.##.. !byte %.##..##. !byte %.##..##. !byte %.##..##. !byte %.##.##.. !byte %.####... !byte %........ !byte %.######. !byte %.##..... !byte %.##..... !byte %.#####.. !byte %.##..... !byte %.##..... !byte %.######. !byte %........ !byte %.######. !byte %.##..... !byte %.##..... !byte %.#####.. !byte %.##..... !byte %.##..... !byte %.##..... !byte %........ !byte %..####.. !byte %.##..##. !byte %.##..... !byte %.##.###. !byte %.##..##. !byte %.##..##. !byte %..####.. !byte %........ !byte %.##..##. !byte %.##..##. !byte %.##..##. !byte %.######. !byte %.##..##. !byte %.##..##. !byte %.##..##. !byte %........ !byte %.######. !byte %...##... !byte %...##... !byte %...##... !byte %...##... !byte %...##... !byte %.######. !byte %........ !byte %..#####. !byte %....##.. !byte %....##.. !byte %....##.. !byte %....##.. !byte %.##.##.. !byte %..###... !byte %........ !byte %.##..##. !byte %.##.##.. !byte %.####... !byte %.###.... !byte %.####... !byte %.##.##.. !byte %.##..##. !byte %........ !byte %.##..... !byte %.##..... !byte %.##..... !byte %.##..... !byte %.##..... !byte %.##..... !byte %.######. !byte %........ !byte %.##...## !byte %.###.### !byte %.####### !byte %.##.#.## !byte %.##.#.## !byte %.##...## !byte %.##...## !byte %........ !byte %.##..##. !byte %.##..##. !byte %.###.##. !byte %.######. !byte %.##.###. !byte %.##..##. !byte %.##..##. !byte %........ !byte %..####.. !byte %.##..##. !byte %.##..##. !byte %.##..##. !byte %.##..##. !byte %.##..##. !byte %..####.. !byte %........ !byte %.#####.. !byte %.##..##. !byte %.##..##. !byte %.#####.. !byte %.##..... !byte %.##..... !byte %.##..... !byte %........ !byte %..####.. !byte %.##..##. !byte %.##..##. !byte %.##..##. !byte %.##.#.#. !byte %.##.##.. !byte %..##.##. !byte %........ !byte %.#####.. !byte %.##..##. !byte %.##..##. !byte %.#####.. !byte %.##.##.. !byte %.##..##. !byte %.##..##. !byte %........ !byte %..####.. !byte %.##..##. !byte %.##..... !byte %..####.. !byte %.....##. !byte %.##..##. !byte %..####.. !byte %........ !byte %.######. !byte %...##... !byte %...##... !byte %...##... !byte %...##... !byte %...##... !byte %...##... !byte %........ !byte %.##..##. !byte %.##..##. !byte %.##..##. !byte %.##..##. !byte %.##..##. !byte %.##..##. !byte %..####.. !byte %........ !byte %.##..##. !byte %.##..##. !byte %.##..##. !byte %.##..##. !byte %.##..##. !byte %..####.. !byte %...##... !byte %........ !byte %.##...## !byte %.##...## !byte %.##.#.## !byte %.##.#.## !byte %.####### !byte %.###.### !byte %.##...## !byte %........ !byte %.##..##. !byte %.##..##. !byte %..####.. !byte %...##... !byte %..####.. !byte %.##..##. !byte %.##..##. !byte %........ !byte %.##..##. !byte %.##..##. !byte %.##..##. !byte %..####.. !byte %...##... !byte %...##... !byte %...##... !byte %........ !byte %.######. !byte %.....##. !byte %....##.. !byte %...##... !byte %..##.... !byte %.##..... !byte %.######. !byte %........ !byte %.#####.. !byte %.##..... !byte %.##..... !byte %.##..... !byte %.##..... !byte %.##..... !byte %.#####.. !byte %........ !byte %........ !byte %.##..... !byte %..##.... !byte %...##... !byte %....##.. !byte %.....##. !byte %........ !byte %........ !byte %..#####. !byte %.....##. !byte %.....##. !byte %.....##. !byte %.....##. !byte %.....##. !byte %..#####. !byte %........ !byte %...##... !byte %..####.. !byte %.##..##. !byte %.#....#. !byte %........ !byte %........ !byte %........ !byte %........ !byte %........ !byte %........ !byte %........ !byte %........ !byte %........ !byte %........ !byte %........ !byte %######## !byte %...###.. !byte %..##.##. !byte %..##.... !byte %.#####.. !byte %..##.... !byte %..##.... !byte %.######. !byte %........ !byte %........ !byte %........ !byte %..####.. !byte %.....##. !byte %..#####. !byte %.##..##. !byte %..#####. !byte %........ !byte %.##..... !byte %.##..... !byte %.#####.. !byte %.##..##. !byte %.##..##. !byte %.##..##. !byte %.#####.. !byte %........ !byte %........ !byte %........ !byte %..####.. !byte %.##..##. !byte %.##..... !byte %.##..##. !byte %..####.. !byte %........ !byte %.....##. !byte %.....##. !byte %..#####. !byte %.##..##. !byte %.##..##. !byte %.##..##. !byte %..#####. !byte %........ !byte %........ !byte %........ !byte %..####.. !byte %.##..##. !byte %.######. !byte %.##..... !byte %..####.. !byte %........ !byte %...###.. !byte %..##.... !byte %..##.... !byte %.#####.. !byte %..##.... !byte %..##.... !byte %..##.... !byte %........ !byte %........ !byte %........ !byte %..#####. !byte %.##..##. !byte %.##..##. !byte %..#####. !byte %.....##. !byte %..####.. !byte %.##..... !byte %.##..... !byte %.#####.. !byte %.##..##. !byte %.##..##. !byte %.##..##. !byte %.##..##. !byte %........ !byte %...##... !byte %........ !byte %..###... !byte %...##... !byte %...##... !byte %...##... !byte %..####.. !byte %........ !byte %...##... !byte %........ !byte %..###... !byte %...##... !byte %...##... !byte %...##... !byte %...##... !byte %.###.... !byte %.##..... !byte %.##..... !byte %.##..##. !byte %.##.##.. !byte %.####... !byte %.##.##.. !byte %.##..##. !byte %........ !byte %..###... !byte %...##... !byte %...##... !byte %...##... !byte %...##... !byte %...##... !byte %..####.. !byte %........ !byte %........ !byte %........ !byte %..##.##. !byte %.####### !byte %.##.#.## !byte %.##.#.## !byte %.##...## !byte %........ !byte %........ !byte %........ !byte %.#####.. !byte %.##..##. !byte %.##..##. !byte %.##..##. !byte %.##..##. !byte %........ !byte %........ !byte %........ !byte %..####.. !byte %.##..##. !byte %.##..##. !byte %.##..##. !byte %..####.. !byte %........ !byte %........ !byte %........ !byte %.#####.. !byte %.##..##. !byte %.##..##. !byte %.#####.. !byte %.##..... !byte %.##..... !byte %........ !byte %........ !byte %..#####. !byte %.##..##. !byte %.##..##. !byte %..#####. !byte %.....##. !byte %.....### !byte %........ !byte %........ !byte %.##.##.. !byte %.###.##. !byte %.##..... !byte %.##..... !byte %.##..... !byte %........ !byte %........ !byte %........ !byte %..#####. !byte %.##..... !byte %..####.. !byte %.....##. !byte %.#####.. !byte %........ !byte %..##.... !byte %..##.... !byte %.#####.. !byte %..##.... !byte %..##.... !byte %..##.... !byte %...###.. !byte %........ !byte %........ !byte %........ !byte %.##..##. !byte %.##..##. !byte %.##..##. !byte %.##..##. !byte %..#####. !byte %........ !byte %........ !byte %........ !byte %.##..##. !byte %.##..##. !byte %.##..##. !byte %..####.. !byte %...##... !byte %........ !byte %........ !byte %........ !byte %.##...## !byte %.##.#.## !byte %.##.#.## !byte %.####### !byte %..##.##. !byte %........ !byte %........ !byte %........ !byte %.##..##. !byte %..####.. !byte %...##... !byte %..####.. !byte %.##..##. !byte %........ !byte %........ !byte %........ !byte %.##..##. !byte %.##..##. !byte %.##..##. !byte %..#####. !byte %.....##. !byte %..####.. !byte %........ !byte %........ !byte %.######. !byte %....##.. !byte %...##... !byte %..##.... !byte %.######. !byte %........ !byte %....##.. !byte %...##... !byte %...##... !byte %.###.... !byte %...##... !byte %...##... !byte %....##.. !byte %........ !byte %...##... !byte %...##... !byte %...##... !byte %........ !byte %...##... !byte %...##... !byte %...##... !byte %........ !byte %..##.... !byte %...##... !byte %...##... !byte %....###. !byte %...##... !byte %...##... !byte %..##.... !byte %........ !byte %..##...# !byte %.##.#.## !byte %.#...##. !byte %........ !byte %........ !byte %........ !byte %........ !byte %........ !byte %######## !byte %######## !byte %######## !byte %######## !byte %######## !byte %######## !byte %######## !byte %########
§2. Screen initialisation on reset.
[This is an oddity, since there's no real reason for this JMP instruction to be here. The only caller (see .skipSpeech) could have equally used 'JSR .initialiseVDUVariablesAndSetMODE' instead of 'JSR .initialiseScreenOnReset' saving three bytes and three cycles.]
.vduBaseAddress = $c300 .initialiseScreenOnReset = $c300 JMP .initialiseVDUVariablesAndSetMODE
Here a BBC Micro Model B has booted up, displaying the 32K version of its welcome message. The Acorn Disk Filing System, installed on this machine as a sideways ROM, also identifies itself, after which the MOS enters the language ROM, BBC BASIC. It's BASIC, not the MOS, which displays the ">" prompt and receives commands. The screen is in MODE 7, so the text uses Teletext characters rather than being rendered in the raster font above. The startup sound has random variation in the first tone(s) as the sound chip starts playing random data on reset until the audio is silenced (See .resetClearAllSounds), and the second tone is the familiar .charBELL sound from the boot message below. Teletext characters look smoother than the regular raster font, thanks to the hardware's diagonal smoothing algorithm, giving them an effective resolution of 10x18 pixels instead of 8x8 in other MODEs. See https://en.wikipedia.org/wiki/Pixel-art_scaling_algorithms#SAA5050_'diagonal_smoothing'. Historical note: All of Acorn's early computers booted up with brief identifications like this, then a skipped line, then a prompt. For the System 2, it was "Acorn Cos", referring to its "cassette operating system"; for the Atom, which had only upper case characters, the ident was "ACORN ATOM". What is perhaps most notable about the ident on the original BBC Micro is that it mentions the BBC, but not Acorn (unless additional ROMs such as the disc filing system are also plugged in). Subsequent models did not follow this pattern: the BBC Master ident is "Acorn MOS", and the B+ is "Acorn OS" plus a RAM size.
.bootMessage = $c303 !text .charRETURN, "BBC Computer ", 0 .bootMessageMemory16 = $c312 !text "16K", .charBELL, 0 .bootMessageMemory32 = $c317 !text "32K", .charBELL, 0 .bootMessageEnding = $c31c !text .charBACKSPACE, .charRETURN, .charRETURN overlaps by one byte into the following table for the zero terminator
§4. Four colour conversion table.
Used when drawing characters to the screen. The index into the table is a pattern of four bits (%0000-%1111) representing half of the eight bit text character row definition. The value of the array entry is the byte value required to write that pattern of white pixels on screen.
.fourColourMODEByteMaskTable = $c31f !byte $00, $11, $22, $33, $44, $55, $66, $77 !byte $88, $99, $AA, $BB, $CC, $DD, $EE, $FF
§5. Sixteen colour conversion table.
Used when drawing characters to the screen. The index into the table is a pattern of two bits (%00-%11) representing a quarter of the eight bit text character row definition. The value of the array entry is the byte value required to write that pattern of white pixels on screen.
.sixteenColourMODEByteMaskTable = $c32f !byte $00, $55, $AA, $FF
§6. Table of addresses (low byte) to handle VDU N.
This table stores the low byte of the address of the routine to handle VDU n. It holds values for VDU 0-31 and 127.
.vduEntryPointTableLow = $c333 !byte <.vdu0EntryPoint Does nothing !byte <.vdu1EntryPoint Send next character to printer only !byte <.vdu2EntryPoint Enable printer !byte <.vdu3EntryPoint Disable printer !byte <.vdu4EntryPoint Write text at text cursor !byte <.vdu5EntryPoint Write text at graphics cursor !byte <.vdu6EntryPoint Enable VDU drivers !byte <.vdu7EntryPoint Make a short beep !byte <.vdu8EntryPoint Move cursor left !byte <.vdu9EntryPoint Move cursor right !byte <.vdu10EntryPoint Move cursor down !byte <.vdu11EntryPoint Move cursor up !byte <.vdu12EntryPoint Clear text window !byte <.vdu13EntryPoint Move cursor to start of current line !byte <.vdu14EntryPoint Paged mode on !byte <.vdu15EntryPoint Paged mode off !byte <.vdu16EntryPoint Clear graphics window !byte <.vdu17EntryPoint Define text colour !byte <.vdu18EntryPoint Define graphics colour !byte <.vdu19EntryPoint Change palette colour !byte <.vdu20EntryPoint Restore default palette !byte <.vdu21EntryPoint Disable VDU drivers / delete line !byte <.vdu22EntryPoint Select screen MODE !byte <.vdu23EntryPoint Define character shape (etc) !byte <.vdu24EntryPoint Define graphics window !byte <.vdu25EntryPoint PLOT !byte <.vdu26EntryPoint Restore default windows !byte <.vdu27EntryPoint Does nothing !byte <.vdu28EntryPoint Define text window !byte <.vdu29EntryPoint Define graphics origin !byte <.vdu30EntryPoint Move text cursor to top left !byte <.vdu31EntryPoint Move text cursor to X,Y .vduEntryPointTableDelete = $c353 !byte <.vdu127EntryPoint Delete
§7. Table of addresses (high byte) to handle VDU N.
The previous table holds the lower byte. This table holds values for VDU 0-31 and 127. If parameters are required then the top bit is clear, (16 - number of parameters) is stored in the lower 4 bits, and the remaining three of the top four bits holds the high byte of the offset from .vduBaseAddress. We only have three bits to store the offset's high byte, so the offset must be less than $800. For this reason, VDU calls with parameters are stored near the start of the ROM. The top bit set indicates that no parameters are required, so the entry just holds the high byte of the address directly.
.vduEntryPointTableHigh = $c354 !byte >.vdu0EntryPoint Does nothing !byte (>(.vdu1EntryPoint - .vduBaseAddress))*16 + (16 - 1) Send next character to printer only (1 parameter) !byte >.vdu2EntryPoint Enable printer !byte >.vdu3EntryPoint Disable printer !byte >.vdu4EntryPoint Write text at text cursor !byte >.vdu5EntryPoint Write text at graphics cursor !byte >.vdu6EntryPoint Enable VDU drivers !byte >.vdu7EntryPoint Make a short beep !byte >.vdu8EntryPoint Move cursor left !byte >.vdu9EntryPoint Move cursor right !byte >.vdu10EntryPoint Move cursor down !byte >.vdu11EntryPoint Move cursor up !byte >.vdu12EntryPoint Clear text area !byte >.vdu13EntryPoint Move cursor to start of current line !byte >.vdu14EntryPoint Paged mode on !byte >.vdu15EntryPoint Paged mode off !byte >.vdu16EntryPoint Clear graphics window !byte (>(.vdu17EntryPoint - .vduBaseAddress))*16 + (16 - 1) Define text colour (1 parameter) !byte (>(.vdu18EntryPoint - .vduBaseAddress))*16 + (16 - 2) Define graphics colour (2 parameters) !byte (>(.vdu19EntryPoint - .vduBaseAddress))*16 + (16 - 5) Define palette colour (5 parameters) !byte >.vdu20EntryPoint Restore default palette !byte >.vdu21EntryPoint Disable VDU drivers / delete current line !byte (>(.vdu22EntryPoint - .vduBaseAddress))*16 + (16 - 1) Select screen MODE (1 parameter) !byte (>(.vdu23EntryPoint - .vduBaseAddress))*16 + (16 - 9) Define character shape (etc) (9 parameters) !byte (>(.vdu24EntryPoint - .vduBaseAddress))*16 + (16 - 8) Define graphics window (8 parameters) !byte (>(.vdu25EntryPoint - .vduBaseAddress))*16 + (16 - 5) PLOT (5 parameters) !byte >.vdu26EntryPoint Restore default windows !byte >.vdu27EntryPoint Does nothing !byte (>(.vdu28EntryPoint - .vduBaseAddress))*16 + (16 - 4) Define text window (4 parameters) !byte (>(.vdu29EntryPoint - .vduBaseAddress))*16 + (16 - 4) Define graphics origin (4 parameters) !byte >.vdu30EntryPoint Move text cursor to top left !byte (>(.vdu31EntryPoint - .vduBaseAddress))*16 + (16 - 2) Move text cursor to X,Y (2 parameters) !byte >.vdu127EntryPoint Delete
Used for calculating screen addresses
.multiplyBy640Table = $c375 !be16 0 * 640 !be16 1 * 640 !be16 2 * 640 !be16 3 * 640 !be16 4 * 640 !be16 5 * 640 !be16 6 * 640 !be16 7 * 640 !be16 8 * 640 !be16 9 * 640 !be16 10 * 640 !be16 11 * 640 !be16 12 * 640 !be16 13 * 640 !be16 14 * 640 !be16 15 * 640 !be16 16 * 640 !be16 17 * 640 !be16 18 * 640 !be16 19 * 640 !be16 20 * 640 !be16 21 * 640 !be16 22 * 640 !be16 23 * 640 !be16 24 * 640 !be16 25 * 640 !be16 26 * 640 !be16 27 * 640 !be16 28 * 640 !be16 29 * 640 !be16 30 * 640 !be16 31 * 640 .multiplyBy40Table = $c3b5 !be16 0 * 40 !be16 1 * 40 !be16 2 * 40 !be16 3 * 40 !be16 4 * 40 !be16 5 * 40 !be16 6 * 40 !be16 7 * 40 !be16 8 * 40 !be16 9 * 40 !be16 10 * 40 !be16 11 * 40 !be16 12 * 40 !be16 13 * 40 !be16 14 * 40 !be16 15 * 40 !be16 16 * 40 !be16 17 * 40 !be16 18 * 40 !be16 19 * 40 !be16 20 * 40 !be16 21 * 40 !be16 22 * 40 !be16 23 * 40 !be16 24 * 40
The maximum text row and column number in each MODE.
.textWindowBottomRowTable Maximum text row number !byte 31 MODE 0 (32 rows) !byte 31 MODE 1 (32 rows) !byte 31 MODE 2 (32 rows) !byte 24 MODE 3 (25 rows) !byte 31 MODE 4 (32 rows) !byte 31 MODE 5 (32 rows) !byte 24 MODE 6 (25 rows) !byte 24 MODE 7 (25 rows) .textWindowRightColumnTable Maximum text column number !byte 79 MODE 0 (80 columns) !byte 39 MODE 1 (40 columns) !byte 19 MODE 2 (20 columns) !byte 79 MODE 3 (80 columns) !byte 39 MODE 4 (40 columns) !byte 19 MODE 5 (20 columns) !byte 39 MODE 6 (40 columns) !byte 39 MODE 7 (40 columns)
§10. Video Control Register of the VideoULA.
bit 0 - Flash colour select (which of the flashing colours is displayed) 1 - Teletext select 2 - } These two bits determine the number of characters per row 3 - } from this table: %00 = 10 characters per row %01 = 20 characters per row %10 = 40 characters per row %11 = 80 characters per row 4 - CRTC clock rate select: %0 = low frequency clock for MODEs 4-7 %1 = high frequency clock for MODEs 0-3 5 - } These two bits determine the width of cursor in bytes 6 - } from this table: %00 = 1 (MODEs 0,3,4,6) %01 = - undefined %10 = 2 (MODEs 1,5,7) %11 = 4 (MODE 2) 7 - Master cursor width. If set, causes a larger cursor to be displayed
.videoULAVideoControlRegisterDefaultValuesPerMODE = $c3f7 !byte %10011100 MODE 0 !byte %11011000 MODE 1 !byte %11110100 MODE 2 !byte %10011100 MODE 3 !byte %10001000 MODE 4 !byte %11000100 MODE 5 !byte %10001000 MODE 6 !byte %01001011 MODE 7 .bytesPerCharacter = $c3ff !byte 8 MODE 0 !byte 16 MODE 1 !byte 32 MODE 2 !byte 8 MODE 3 !byte 8 MODE 4 !byte 16 MODE 5 !byte 8 MODE 6 !byte 1 MODE 7
A 16 colour MODE (MODE 2) has two pixels per byte. The first table gives the byte values required to set each pixel in a byte to white (leaving the remainder black). The second table is the equivalent for four colour MODEs (four pixels per byte). The third table is the equivalent for two colour MODEs (eight pixels per byte, dual use with .fontMaskTable)
.sixteenColourMODEMaskTable = $c407 !byte %10101010, %01010101 2 pixels per byte (MODE 2) .fourColourMODEMaskTable = $c409 !byte %10001000, %01000100, %00100010, %00010001 4 pixels per byte (MODE 1 or 5) .fontMaskTable 8 pixels per byte (MODE 0 or 4) This array is dual purpose - used both as the 8 pixels per byte MODE mask table and also to interrogate a particular bit in the vduFontByte. !byte $80, $40, $20, $10, $08, $04, $02 The next byte overlaps (being the last byte in this table and the first byte in the next) .numberOfColoursMinusOneInMODETable = $c414 !byte 1 MODE 0 !byte 3 MODE 1 !byte 15 MODE 2 !byte 1 MODE 3 !byte 1 MODE 4 !byte 3 MODE 5 !byte 1 MODE 6 !byte 0 MODE 7
This table is used when setting .vduGraphicsColourByteOR and .vduGraphicsColourByteEOR in .setGraphicsColourMaskXY. This table is used to help implement the GCOL Mode. GCOL Mode: 0=Normal, 1=OR, 2=AND, 3=EOR, 4=Invert See .setGraphicsColourMaskXY
.gcolPlotOptionsTable = $c41c !byte $FF Underflow: The last byte of the !byte $00 previous table (zero) is accessed as !byte $00 part of the calculations. !byte $FF !byte $FF !byte $FF !byte $FF !byte $00 Overflow: The following byte in the next table (zero) is accessed as part of the calculations.
The following tables hold the byte values required to write a full solid byte of COLOUR N on screen (N being the offset into the table). One table for the 2 colour MODEs, one for 4 colour MODEs, and one for 16 colour MODEs. See .vdu18EntryPoint.
.twoColourMODEParameterTable = $c424 !byte %00000000 !byte %11111111 .fourColourMODEParameterTable = $c426 !byte %00000000 !byte %00001111 !byte %11110000 !byte %11111111 .sixteenColourMODEParameterTable = $c42a !byte %00000000 !byte %00000011 !byte %00001100 !byte %00001111 !byte %00110000 !byte %00110011 !byte %00111100 !byte %00111111 !byte %11000000 !byte %11000011 !byte %11001100 !byte %11001111 !byte %11110000 !byte %11110011 !byte %11111100 !byte %11111111 .pixelsPerByteMinusOneInMODETable = $c43a !byte 7 MODE 0 !byte 3 MODE 1 !byte 1 MODE 2 !byte 0 MODE 3 !byte 7 MODE 4 !byte 3 MODE 5 Overflow: the first two bytes of the next table are accessed as the last two bytes of this table (zero for MODE 6 and 7 values). This table describes how much memory each MODE takes. Eight byte table (one byte for each MODE), overlapping with the next two tables. .screenDisplayMemoryIndexTable = $c440 !byte 0 MODE 0 Sound pitch offsets table: Notes played on different sound channels are offset in pitch slightly from each other (perhaps to reduce phase shift effects when the same note is played on two or more different channels). This is four bytes long (in the middle of the previous table!). .soundPitchOffsetByChannelTable Dual use: screen memory sound pitch offsets ----------------------------------- !byte 0 MODE 1 Channel 0 !byte 0 MODE 2 Channel 1 !byte 1 MODE 3 Channel 2 !byte 2 MODE 4 Channel 3 !byte 2 MODE 5 !byte 3 MODE 6 Overflow: the first byte of the next table is accessed for: MODE 7 - next byte, value 4 Table of offsets into the VDU variables, used when line plotting .vduGraphicsWindowBoundariesTable = $c447 !byte .vduGraphicsWindowPixelsRightLow - .vduVariablesStart } offsets into the VDU !byte .vduGraphicsWindowPixelsLeftLow - .vduVariablesStart } variables of the !byte .vduGraphicsWindowPixelsTopLow - .vduVariablesStart } graphics window edges !byte .vduGraphicsWindowPixelsBottomLow - .vduVariablesStart }
Stores which System VIA Register B registers to write, see .systemVIARegisterB
.systemVIAHardwareScrollTable1 Which System VIA register to write to set the hardware scrolling, for each MODE group. !byte 13 20k (MODE 0,1,2) !byte 5 16k (MODE 3) !byte 13 10k (MODE 4,5) !byte 5 8k (MODE 6) Overflows one byte into next table 1k (MODE 7) Which System VIA register to write to set the hardware scrolling, for each MODE group. .systemVIAHardwareScrollTable2 = $c44f !byte 4 20k (MODE 0,1,2) !byte 4 16k (MODE 3) !byte 12 10k (MODE 4,5) !byte 12 8k (MODE 6) !byte 4 1k (MODE 7) Low byte of the address to clear the screen in each MODE group .clearScreenRoutineEntryPointLow = $c454 !byte <.clearScreenRoutineEntryPointMODE012 MODE 0,1,2 !byte <.clearScreenRoutineEntryPointMODE3 MODE 3 !byte <.clearScreenRoutineEntryPointMODE45 MODE 4,5 !byte <.clearScreenRoutineEntryPointMODE6 MODE 6 !byte <.clearScreenRoutineEntryPointMODE7 MODE 7 screen size (high byte) for each MODE group .screenMemorySizeInBytesHigh = $c459 !byte $50 MODEs 0,1,2 ($5000 = 20k) !byte $40 MODE 3 ($4000 = 16k) !byte $28 MODEs 4,5 ($2800 = 10k) !byte $20 MODE 6 ($2000 = 8k) !byte $04 MODE 7 ($0400 = 1k) screen start address (high byte) for each MODE group .screenMemoryStartHigh = $c45e !byte $30 MODEs 0,1,2 ($3000) %00110000 !byte $40 MODE 3 ($4000) %01000000 !byte $58 MODEs 4,5 ($5800) %01011000 !byte $60 MODE 6 ($6000) %01100000 !byte $7C MODE 7 ($7C00) %01111100 number of bytes in each row .bytesPerRowLow = $c463 !byte <40 MODE 7 40 bytes per row !byte <320 MODE 4,5,6 320 bytes per row !byte <640 MODE 0,1,2,3 640 bytes per row Which multiplication table to use (low byte of address, assumes the multiplication tables are in the same page) .multiplicationTabletoUseLow = $c466 !byte <.multiplyBy40Table MODE 7 !byte <.multiplyBy640Table MODE 4,5,6 !byte <.multiplyBy640Table MODE 0,1,2,3 Offset to CRTC cursor end register in each MODE group .crtcCursorEndRegisterTable = $c469 !byte .crtcMODEs012CursorEndRegister - .crtcRegisters0to11ForMODEs012 MODEs 0,1,2 !byte .crtcMODE3CursorEndRegister - .crtcRegisters0to11ForMODEs012 MODE 3 !byte .crtcMODE45CursorEndRegister - .crtcRegisters0to11ForMODEs012 MODEs 4,5 !byte .crtcMODE6CursorEndRegister - .crtcRegisters0to11ForMODEs012 MODE 6 !byte .crtcMODE7CursorEndRegister - .crtcRegisters0to11ForMODEs012 MODE 7 default CRTC register values .crtcRegisters0to11ForMODEs012 = $c46e !byte 127 R0 = Horizontal total register !byte 80 R1 = Horizontal displayed register !byte 98 R2 = Horizontal sync position register !byte $28 R3 = The sync width register !byte 38 R4 = Vertical total register !byte 0 R5 = Vertical total adjust register !byte 32 R6 = Vertical displayed register (number of visible character rows) !byte 34 R7 = Vertical sync position !byte %00000001 R8 = Interlace and delay register !byte 7 R9 = Scan lines per character !byte $67 R10 = Cursor start register .crtcMODEs012CursorEndRegister = $c479 !byte 8 R11 = The cursor end register .crtcRegisters0to11ForMODE3 = $c47a !byte 127 R0 = Horizontal total register !byte 80 R1 = Horizontal displayed register !byte 98 R2 = Horizontal sync position register !byte $28 R3 = The sync width register !byte $1E R4 = Vertical total register !byte $02 R5 = Vertical total adjust register !byte $19 R6 = Vertical displayed register (number of visible character rows) !byte $1B R7 = Vertical sync position !byte $01 R8 = Interlace and delay register !byte $09 R9 = Scan lines per character !byte $67 R10 = Cursor start register .crtcMODE3CursorEndRegister = $c485 !byte $09 R11 = The cursor end register .crtcRegisters0to11ForMODEs45 = $c486 !byte $3F R0 = Horizontal total register !byte $28 R1 = Horizontal displayed register !byte $31 R2 = Horizontal sync position register !byte $24 R3 = The sync width register !byte $26 R4 = Vertical total register !byte $00 R5 = Vertical total adjust register !byte $20 R6 = Vertical displayed register (number of visible character rows) !byte $22 R7 = Vertical sync position !byte $01 R8 = Interlace and delay register !byte $07 R9 = Scan lines per character !byte $67 R10 = Cursor start register .crtcMODE45CursorEndRegister = $c491 !byte $08 R11 = The cursor end register .crtcRegisters0to11ForMODE6 = $c492 !byte $3F R0 = Horizontal total register !byte $28 R1 = Horizontal displayed register !byte $31 R2 = Horizontal sync position register !byte $24 R3 = The sync width register !byte $1E R4 = Vertical total register !byte $02 R5 = Vertical total adjust register !byte $19 R6 = Vertical displayed register (number of visible character rows) !byte $1B R7 = Vertical sync position !byte $01 R8 = Interlace and delay register !byte $09 R9 = Scan lines per character !byte $67 R10 = Cursor start register .crtcMODE6CursorEndRegister = $c49d !byte $09 R11 = The cursor end register .crtcRegisters0to11ForMODE7 = $c49e !byte $3F R0 = Horizontal total register !byte $28 R1 = Horizontal displayed register !byte $33 R2 = Horizontal sync position register !byte $24 R3 = The sync width register !byte $1E R4 = Vertical total register !byte $02 R5 = Vertical total adjust register !byte $19 R6 = Vertical displayed register (number of visible character rows) !byte $1B R7 = Vertical sync position !byte $93 R8 = Interlace and delay register !byte $12 R9 = Scan lines per character !byte $72 R10 = Cursor start register .crtcMODE7CursorEndRegister = $c4a9 !byte $13 R11 = The cursor end register
.vduPlotLineRoutineAddresses = $c4aa !word .plotLineMoveToNextColumnRight if X axis is dominant, move right !word .plotLineMoveToNextRowUp if Y axis is dominant, move up .vduRoutineBranchVectorAddressesLow = $c4ae !byte <.plotLineDominantYAxisSameSign !byte <.plotLineDominantYAxisDifferentSign !byte <.plotLineDominantXAxisSameSign !byte <.plotLineDominantXAxisDifferentSign .vduRoutineBranchVectorAddressesHigh = $c4b2 !byte >.plotLineDominantYAxisSameSign !byte >.plotLineDominantYAxisDifferentSign !byte >.plotLineDominantXAxisSameSign !byte >.plotLineDominantXAxisDifferentSign
§16. Converting characters in Teletext.
Writing printable characters (32-126) directly to the display memory in MODE 7 gives different results in three cases to printing via OSWRCH. In particular: Value Write to Screen Write to screen Memory Directly via OSWRCH ---------------------------------------------- $23 £ # $5F # long dash $60 long dash £ ----------------------------------------------
.teletextCharacterConversionTable = $c4b6 !byte $23 when writing a character in MODE 7, replace each byte here with the next in the table !byte $5F when reading the character from the screen, replace each byte with the previous in the table !byte $60 !byte $23
§17. Soft character table offsets.
Converts the OSBYTE 20 parameter 1-6 (how much of the character set to 'explode', i.e. which range of character definitions can be redefined) into the offset into the .vduFontZoneAddressesHigh1 table, which stores the page addresses used to define characters in an 'exploded' soft character set. See .osbyte20EntryPoint
.softCharacterRamAllocationTable = $c4ba !byte $04 1 -> 4 = range of characters 128-159 !byte $05 2 -> 5 = range of characters 160-191 !byte $06 3 -> 6 = range of characters 192-223 !byte $00 4 -> 0 = range of characters 32-63 !byte $01 5 -> 1 = range of characters 64-95 !byte $02 6 -> 2 = range of characters 96-127