|
pico9918-core 1.3.0
TMS9918A / F18A video display processor emulation in C99
|
pico9918-core - core interface More...
#include "pico9918_build_config.h"#include <stdint.h>#include <stdbool.h>
Include dependency graph for pico9918.h:
This graph shows which files directly or indirectly include this file:Go to the source code of this file.
Macros | |
| #define | PICO9918_LINKAGE extern |
| #define | PICO9918_DLLEXPORT PICO9918_LINKAGE |
| the linkage every public entry point carries - see LINKAGE MODES above | |
| #define | PICO9918_INST_ARG pico9918_t *tms9918, |
| declare the instance ahead of other parameters | |
| #define | PICO9918_INST_ONLY_ARG pico9918_t* tms9918 |
| declare the instance as the only parameter | |
| #define | PICO9918_INST tms9918, |
| pass the instance ahead of other arguments | |
| #define | PICO9918_INST_ONLY tms9918 |
| pass the instance as the only argument | |
| #define | PICO9918_CHIP_MAX PICO9918_CHIP_PICO9918_PRO |
| the highest personality this build can be, and what a new instance is | |
| #define | PICO9918_SR0_INT 0x80 |
| status register 0 bits. | |
| #define | PICO9918_SR0_5S 0x40 |
| more sprites on a line than the limit allows | |
| #define | PICO9918_SR0_COLLISION 0x20 |
| two sprites overlapped on an opaque pixel | |
| #define | PICO9918_SR0_SPRITE_NUM 0x1f |
| the fifth sprite's number, or the highest seen | |
| #define | PICO9918_SR1_HF 0x01 |
| status register 1 bits. | |
| #define | PICO9918_SR1_BLANK 0x02 |
| the raster is in blanking | |
| #define | TMS_R0_MODE_GRAPHICS_I 0x00 |
| register 0 bits: mode selection and the external VDP input. | |
| #define | TMS_R0_MODE_GRAPHICS_II 0x02 |
| Graphics II - the only mode R0 selects. | |
| #define | TMS_R0_MODE_MULTICOLOR 0x00 |
| Multicolor - selected in R1. | |
| #define | TMS_R0_MODE_TEXT 0x00 |
| 40-column text - selected in R1 | |
| #define | TMS_R0_MODE_TEXT_80 0x04 |
| 80-column text, with R1's text mode. | |
| #define | TMS_R0_EXT_VDP_ENABLE 0x01 |
| take video from the external VDP input | |
| #define | TMS_R0_EXT_VDP_DISABLE 0x00 |
| ignore the external VDP input | |
| #define | TMS_R0_DOUBLE_ROWS 0x08 |
| PICO9918 only: twice the rows, drawn interlaced. | |
| #define | TMS_R0_INT_SCANLINE 0x10 |
| assert /INT when the raster reaches the line in R19. | |
| #define | TMS_R1_RAM_16K 0x80 |
| register 1 bits: VRAM size, blanking, interrupt, mode and sprite size | |
| #define | TMS_R1_RAM_4K 0x00 |
| 4KB of VRAM | |
| #define | TMS_R1_DISP_BLANK 0x00 |
| blank the display; the border still draws | |
| #define | TMS_R1_DISP_ACTIVE 0x40 |
| render the active display | |
| #define | TMS_R1_INT_ENABLE 0x20 |
| assert /INT at end of frame | |
| #define | TMS_R1_INT_DISABLE 0x00 |
| leave /INT alone | |
| #define | TMS_R1_MODE_GRAPHICS_I 0x00 |
| Graphics I - no bit of its own in R1. | |
| #define | TMS_R1_MODE_GRAPHICS_II 0x00 |
| Graphics II - selected in R0. | |
| #define | TMS_R1_MODE_MULTICOLOR 0x08 |
| Multicolor. | |
| #define | TMS_R1_MODE_TEXT 0x10 |
| 40-column text | |
| #define | TMS_R1_SPRITE_8 0x00 |
| 8x8 sprite patterns | |
| #define | TMS_R1_SPRITE_16 0x02 |
| 16x16 sprite patterns | |
| #define | TMS_R1_SPRITE_MAG1 0x00 |
| sprites drawn at their pattern size | |
| #define | TMS_R1_SPRITE_MAG2 0x01 |
| sprites drawn at twice their pattern size | |
| #define | PICO9918_R24_SPRITE_PS 0x30 |
| register 24 bits: the sub-palette each layer takes | |
| #define | PICO9918_R24_TILE_PS 0x0f |
| tile palette select, layer 2 high and layer 1 low | |
| #define | PICO9918_R24_TILE2_PS 0x0c |
| tile layer 2 palette select | |
| #define | PICO9918_R24_TILE1_PS 0x03 |
| tile layer 1 palette select | |
| #define | PICO9918_R29_SPRITE_STRIDE 0xc0 |
| register 29 fields: scroll page sizes, and the stride between ECM pattern planes | |
| #define | PICO9918_R29_PAGE2_HORZ 0x20 |
| tile layer 2 scrolls across two pages | |
| #define | PICO9918_R29_PAGE2_VERT 0x10 |
| tile layer 2 scrolls down two pages | |
| #define | PICO9918_R29_TILE_STRIDE 0x0c |
| tile pattern plane stride, 0x800 >> n | |
| #define | PICO9918_R29_PAGE1_HORZ 0x02 |
| tile layer 1 scrolls across two pages | |
| #define | PICO9918_R29_PAGE1_VERT 0x01 |
| tile layer 1 scrolls down two pages | |
| #define | PICO9918_R31_BML_ENABLE 0x80 |
| register 31 bits: the bitmap layer | |
| #define | PICO9918_R31_BML_PRIORITY 0x40 |
| bitmap layer above the tile layers | |
| #define | PICO9918_R31_BML_TRANSP 0x20 |
| pixel value 0 is transparent | |
| #define | PICO9918_R31_BML_FAT 0x10 |
| two bits a pixel, drawn double width | |
| #define | PICO9918_R31_BML_PS 0x0f |
| bitmap layer palette select | |
| #define | PICO9918_R47_DATA_PORT 0x80 |
| register 47 bits: the palette data port | |
| #define | PICO9918_R47_AUTO_INC 0x40 |
| step the palette index after each entry | |
| #define | PICO9918_R47_INDEX 0x3f |
| first palette index to write | |
| #define | PICO9918_R49_TILE2_ENABLE 0x80 |
| register 49 bits: tile layer 2, row count, and the enhanced colour modes | |
| #define | PICO9918_R49_ROW30 0x40 |
| 30 rows of tiles rather than 24 | |
| #define | PICO9918_R49_ECM_TILE 0x30 |
| tile ECM level field | |
| #define | PICO9918_R49_ECM_TILE_1 0x10 |
| tiles take one bitplane, two colours | |
| #define | PICO9918_R49_ECM_TILE_2 0x20 |
| tiles take two bitplanes, four colours | |
| #define | PICO9918_R49_ECM_TILE_3 0x30 |
| tiles take three bitplanes, eight colours | |
| #define | PICO9918_R49_Y_REAL 0x08 |
| sprite Y is the real row, not row minus one | |
| #define | PICO9918_R49_ECM_SPRITE 0x03 |
| sprite ECM level field | |
| #define | PICO9918_R49_ECM_SPRITE_1 0x01 |
| sprites take one bitplane, two colours | |
| #define | PICO9918_R49_ECM_SPRITE_2 0x02 |
| sprites take two bitplanes, four colours | |
| #define | PICO9918_R49_ECM_SPRITE_3 0x03 |
| sprites take three bitplanes, eight colours | |
| #define | PICO9918_R50_RESET 0x80 |
| register 50 bits: GPU triggers and the remaining layer controls | |
| #define | PICO9918_R50_GPU_HSYNC 0x40 |
| trigger the GPU every scanline | |
| #define | PICO9918_R50_GPU_VSYNC 0x20 |
| trigger the GPU every frame | |
| #define | PICO9918_R50_TILE1_OFF 0x10 |
| stop drawing tile layer 1 | |
| #define | PICO9918_R50_REPORT_MAX 0x08 |
| S0's sprite number reports the highest seen. | |
| #define | PICO9918_R50_VSCANLINES 0x04 |
| F18A only: dim every second raster line. | |
| #define | PICO9918_R50_POS_ATTR 0x02 |
| tile attributes come per position, not per tile | |
| #define | PICO9918_R50_T2_PRIORITY 0x01 |
| tile layer 2 above tile layer 1 | |
| #define | PICO9918_R56_GPU_RUN 0x01 |
| register 56 bit: the GPU trigger | |
| #define | PICO9918_R57_UNLOCK 0x1c |
| the value register 57 takes, twice in a row, to unlock | |
| #define | PICO9918_R15_COUNTER_RESET 0x40 |
| register 15 bits: the counter controls, and which status register S1 reads | |
| #define | PICO9918_R15_COUNTER_SNAP 0x20 |
| latch the counters for reading | |
| #define | PICO9918_R15_COUNTER_EN 0x10 |
| let the counters run | |
| #define | PICO9918_R15_STATUS_NUM 0x0f |
| which status register S1 reads back | |
| #define | TMS9918_PIXELS_X 256 |
| active display width, every mode | |
| #define | TMS9918_PIXELS_Y 384 |
| tallest active display any mode reaches; a TMS9918A draws 192 | |
| #define | PICO9918_SCANLINE_BYTES_MAX (PICO9918_BUILD_TEXT80_8BPP ? TMS9918_PIXELS_X * 2 : TMS9918_PIXELS_X) |
| the widest active line this build renders, in bytes | |
| #define | PICO9918_SCANLINE_BUFFER_SIZE (PICO9918_SCANLINE_BYTES_MAX + 8) |
| the library's line buffer size - the active pixels plus the eight bytes past them that a fine-h-scrolled tile layer's last quad can reach | |
Typedefs | |
| typedef void(* | pico9918_config_applied_fn) (pico9918_t *tms9918, void *userdata) |
| typedef void(* | pico9918_config_reload_fn) (pico9918_t *tms9918, void *userdata) |
| typedef void(* | pico9918_gpu_flash_fn) (pico9918_t *tms9918, void *userdata) |
| typedef void(* | pico9918_gpu_config_save_fn) (pico9918_t *tms9918, uint8_t *config, uint8_t key, void *userdata) |
Enumerations | |
| enum | pico9918_mode_t { TMS_MODE_GRAPHICS_I , TMS_MODE_GRAPHICS_II , TMS_MODE_TEXT , TMS_MODE_MULTICOLOR , TMS_MODE_TEXT80 , TMS_MODE_COUNT } |
| the display modes the VDP can be in, TMS9918A modes and F18A alike More... | |
| enum | pico9918_chip_t { PICO9918_CHIP_TMS9918 = 0 , PICO9918_CHIP_TMS9918A = 1 , PICO9918_CHIP_F18A = 2 , PICO9918_CHIP_PICO9918 = 3 , PICO9918_CHIP_PICO9918_PRO = 4 } |
| which chip an instance answers as More... | |
| enum | pico9918_color_t { TMS_TRANSPARENT = 0 , TMS_BLACK , TMS_MED_GREEN , TMS_LT_GREEN , TMS_DK_BLUE , TMS_LT_BLUE , TMS_DK_RED , TMS_CYAN , TMS_MED_RED , TMS_LT_RED , TMS_DK_YELLOW , TMS_LT_YELLOW , TMS_DK_GREEN , TMS_MAGENTA , TMS_GREY , TMS_WHITE } |
| the sixteen TMS9918 colours, in palette-index order More... | |
| enum | pico9918_register_t { TMS_REG_0 = 0 , TMS_REG_1 , TMS_REG_2 , TMS_REG_3 , TMS_REG_4 , TMS_REG_5 , TMS_REG_6 , TMS_REG_7 , TMS_NUM_REGISTERS , TMS_REG_NAME_TABLE = TMS_REG_2 , TMS_REG_COLOR_TABLE = TMS_REG_3 , TMS_REG_PATTERN_TABLE = TMS_REG_4 , TMS_REG_SPRITE_ATTR_TABLE = TMS_REG_5 , TMS_REG_SPRITE_PATT_TABLE = TMS_REG_6 , TMS_REG_FG_BG_COLOR = TMS_REG_7 , PICO9918_REG_NAME_TABLE2 = 10 , PICO9918_REG_COLOR_TABLE2 = 11 , PICO9918_REG_STATUS_SELECT = 15 , PICO9918_REG_HORZ_INT_LINE = 19 , PICO9918_REG_PALETTE_SELECT = 24 , PICO9918_REG_T2_HSCROLL = 25 , PICO9918_REG_T2_VSCROLL = 26 , PICO9918_REG_T1_HSCROLL = 27 , PICO9918_REG_T1_VSCROLL = 28 , PICO9918_REG_PAGE_SIZE = 29 , PICO9918_REG_MAX_SCAN_SPRITES = 30 , PICO9918_REG_BML_CONTROL = 31 , PICO9918_REG_BML_BASE = 32 , PICO9918_REG_BML_X = 33 , PICO9918_REG_BML_TOP_ROW = 34 , PICO9918_REG_BML_WIDTH = 35 , PICO9918_REG_BML_HEIGHT = 36 , PICO9918_REG_PALETTE_CONTROL = 47 , PICO9918_REG_VRAM_INC = 48 , PICO9918_REG_ENHANCED1 = 49 , PICO9918_REG_ENHANCED2 = 50 , PICO9918_REG_MAX_SPRITES = 51 , PICO9918_REG_GPU_PC_MSB = 54 , PICO9918_REG_GPU_PC_LSB = 55 , PICO9918_REG_GPU_CONTROL = 56 , PICO9918_REG_UNLOCK = 57 , PICO9918_REG_CONFIG_INDEX = 58 , PICO9918_REG_CONFIG_VALUE = 59 , PICO9918_REG_FLASH_CONTROL = 63 } |
| the eight TMS9918 registers, by number and by what each one holds More... | |
| enum | pico9918_status_register_t { PICO9918_SR_STATUS = 0 , PICO9918_SR_IDENT = 1 , PICO9918_SR_GPU = 2 , PICO9918_SR_RASTER_LINE = 3 , PICO9918_SR_NANOS_LSB = 4 , PICO9918_SR_NANOS_MSB = 5 , PICO9918_SR_MICROS_LSB = 6 , PICO9918_SR_MICROS_MSB = 7 , PICO9918_SR_MILLIS_LSB = 8 , PICO9918_SR_MILLIS_MSB = 9 , PICO9918_SR_SECONDS_LSB = 10 , PICO9918_SR_SECONDS_MSB = 11 , PICO9918_SR_CONFIG_VALUE = 12 , PICO9918_SR_TEMPERATURE = 13 , PICO9918_SR_VERSION = 14 , PICO9918_SR_REG_VALUE = 15 } |
| the status registers, by number and by what each one reports More... | |
Functions | |
| pico9918_t * | pico9918_new (void) |
| create a new TMS9918 | |
| void | pico9918_set_chip (pico9918_t *tms9918, pico9918_chip_t chip) |
| select which chip this instance answers as | |
| pico9918_chip_t | pico9918_chip (pico9918_t *tms9918) |
| which chip this instance answers as | |
| void | pico9918_reset (pico9918_t *tms9918) |
| reset the TMS9918 | |
| void | pico9918_destroy (pico9918_t *tms9918) |
| destroy a TMS9918 and release everything it owns | |
| void | pico9918_write_addr (pico9918_t *tms9918, uint8_t data) |
| write an address (mode = 1) to the tms9918 - the data byte DB0 -> DB7 | |
| void | pico9918_write_data (pico9918_t *tms9918, uint8_t data) |
| write data (mode = 0) to the tms9918 - the data byte DB0 -> DB7 | |
| uint8_t | pico9918_read_status (pico9918_t *tms9918) |
| read from the status register | |
| uint8_t | pico9918_peek_status (pico9918_t *tms9918) |
| read from the status register without resetting it | |
| uint8_t | pico9918_read_data (pico9918_t *tms9918) |
| read data (mode = 0) from the tms9918 | |
| uint8_t | pico9918_read_data_no_inc (pico9918_t *tms9918) |
| read data (mode = 0) without incrementing the address pointer | |
| bool | pico9918_interrupt_status (pico9918_t *tms9918) |
| true if both the INT status and the INT control bit are set | |
| void | pico9918_interrupt_set (pico9918_t *tms9918) |
| set the interrupt flag | |
| void | pico9918_set_status (pico9918_t *tms9918, uint8_t status) |
| set the status flags | |
| uint8_t | pico9918_scan_line (pico9918_t *tms9918, uint16_t y) |
| generate a scanline | |
| uint8_t | pico9918_reg_value (pico9918_t *tms9918, pico9918_register_t reg) |
| return a register value | |
| uint8_t | pico9918_status_value (pico9918_t *tms9918, pico9918_status_register_t reg) |
| return a status register value, without the side effects of reading it | |
| uint8_t | pico9918_vram_value (pico9918_t *tms9918, uint16_t addr) |
| return a value from vram | |
| bool | pico9918_display_enabled (pico9918_t *tms9918) |
| check the BLANK flag | |
| pico9918_mode_t | pico9918_display_mode (pico9918_t *tms9918) |
| the current display mode | |
| uint32_t | pico9918_line_bytes (pico9918_t *tms9918) |
| how many bytes of the line the current mode fills: 256, or 512 for unlocked 80-column text on a board built with the 8bpp tier | |
| const uint8_t * | pico9918_line_source (pico9918_t *tms9918) |
| where the scanline just generated actually is - the arbitration buffer, or a tile layer's own buffer on a line that needed no compositing | |
| uint16_t | pico9918_default_palette (int index) |
| a default palette value, 0x0rgb | |
pico9918-core - core interface
Copyright (c) 2021 Troy Schrapel
This code is licensed under the MIT license
https://github.com/visrealm/pico9918-core
Definition in file pico9918.h.
| #define PICO9918_LINKAGE extern |
Definition at line 28 of file pico9918.h.
| #define PICO9918_DLLEXPORT PICO9918_LINKAGE |
the linkage every public entry point carries - see LINKAGE MODES above
Definition at line 41 of file pico9918.h.
| #define PICO9918_INST_ARG pico9918_t *tms9918, |
declare the instance ahead of other parameters
Definition at line 71 of file pico9918.h.
| #define PICO9918_INST_ONLY_ARG pico9918_t* tms9918 |
declare the instance as the only parameter
Definition at line 72 of file pico9918.h.
| #define PICO9918_INST tms9918, |
pass the instance ahead of other arguments
Definition at line 73 of file pico9918.h.
| #define PICO9918_INST_ONLY tms9918 |
pass the instance as the only argument
Definition at line 74 of file pico9918.h.
| #define PICO9918_CHIP_MAX PICO9918_CHIP_PICO9918_PRO |
the highest personality this build can be, and what a new instance is
The ceiling is PRO only where the build carries the wide 80-column line, because that is a buffer width rather than a runtime choice: PICO9918_TEXT80_8BPP doubles the scanline buffer, so a narrow build has nowhere to put the pixels. Ask for PRO there and pico9918_set_chip clamps to PICO9918, which is the contract it already states - read pico9918_chip() back to find out which you got.
Definition at line 168 of file pico9918.h.
| #define PICO9918_SR0_INT 0x80 |
status register 0 bits.
The low five are the sprite number end of frame reached. Cleared by reading SR0
Definition at line 275 of file pico9918.h.
| #define PICO9918_SR0_5S 0x40 |
more sprites on a line than the limit allows
Definition at line 276 of file pico9918.h.
| #define PICO9918_SR0_COLLISION 0x20 |
two sprites overlapped on an opaque pixel
Definition at line 277 of file pico9918.h.
| #define PICO9918_SR0_SPRITE_NUM 0x1f |
the fifth sprite's number, or the highest seen
Definition at line 278 of file pico9918.h.
| #define PICO9918_SR1_HF 0x01 |
status register 1 bits.
The high three are the chip identity the line in R19 was reached. Cleared by reading SR1
Definition at line 281 of file pico9918.h.
| #define PICO9918_SR1_BLANK 0x02 |
the raster is in blanking
Definition at line 282 of file pico9918.h.
| #define TMS_R0_MODE_GRAPHICS_I 0x00 |
register 0 bits: mode selection and the external VDP input.
The three modes register 1 selects are 0 here, so a mode is the pair of writes. Graphics I - no bit of its own in R0
Definition at line 286 of file pico9918.h.
| #define TMS_R0_MODE_GRAPHICS_II 0x02 |
Graphics II - the only mode R0 selects.
Definition at line 287 of file pico9918.h.
| #define TMS_R0_MODE_MULTICOLOR 0x00 |
Multicolor - selected in R1.
Definition at line 288 of file pico9918.h.
| #define TMS_R0_MODE_TEXT 0x00 |
40-column text - selected in R1
Definition at line 289 of file pico9918.h.
| #define TMS_R0_MODE_TEXT_80 0x04 |
| #define TMS_R0_EXT_VDP_ENABLE 0x01 |
take video from the external VDP input
Definition at line 291 of file pico9918.h.
| #define TMS_R0_EXT_VDP_DISABLE 0x00 |
ignore the external VDP input
Definition at line 292 of file pico9918.h.
| #define TMS_R0_DOUBLE_ROWS 0x08 |
PICO9918 only: twice the rows, drawn interlaced.
Sprites stay low-res
Definition at line 293 of file pico9918.h.
| #define TMS_R0_INT_SCANLINE 0x10 |
assert /INT when the raster reaches the line in R19.
The F18A's IE1
Definition at line 294 of file pico9918.h.
| #define TMS_R1_RAM_16K 0x80 |
register 1 bits: VRAM size, blanking, interrupt, mode and sprite size
16KB of VRAM
Definition at line 297 of file pico9918.h.
| #define TMS_R1_RAM_4K 0x00 |
4KB of VRAM
Definition at line 298 of file pico9918.h.
| #define TMS_R1_DISP_BLANK 0x00 |
blank the display; the border still draws
Definition at line 299 of file pico9918.h.
| #define TMS_R1_DISP_ACTIVE 0x40 |
render the active display
Definition at line 300 of file pico9918.h.
| #define TMS_R1_INT_ENABLE 0x20 |
assert /INT at end of frame
Definition at line 301 of file pico9918.h.
| #define TMS_R1_INT_DISABLE 0x00 |
leave /INT alone
Definition at line 302 of file pico9918.h.
| #define TMS_R1_MODE_GRAPHICS_I 0x00 |
Graphics I - no bit of its own in R1.
Definition at line 303 of file pico9918.h.
| #define TMS_R1_MODE_GRAPHICS_II 0x00 |
Graphics II - selected in R0.
Definition at line 304 of file pico9918.h.
| #define TMS_R1_MODE_MULTICOLOR 0x08 |
Multicolor.
Definition at line 305 of file pico9918.h.
| #define TMS_R1_MODE_TEXT 0x10 |
40-column text
Definition at line 306 of file pico9918.h.
| #define TMS_R1_SPRITE_8 0x00 |
8x8 sprite patterns
Definition at line 307 of file pico9918.h.
| #define TMS_R1_SPRITE_16 0x02 |
16x16 sprite patterns
Definition at line 308 of file pico9918.h.
| #define TMS_R1_SPRITE_MAG1 0x00 |
sprites drawn at their pattern size
Definition at line 309 of file pico9918.h.
| #define TMS_R1_SPRITE_MAG2 0x01 |
sprites drawn at twice their pattern size
Definition at line 310 of file pico9918.h.
| #define PICO9918_R24_SPRITE_PS 0x30 |
register 24 bits: the sub-palette each layer takes
sprite palette select
Definition at line 316 of file pico9918.h.
| #define PICO9918_R24_TILE_PS 0x0f |
tile palette select, layer 2 high and layer 1 low
Definition at line 317 of file pico9918.h.
| #define PICO9918_R24_TILE2_PS 0x0c |
tile layer 2 palette select
Definition at line 318 of file pico9918.h.
| #define PICO9918_R24_TILE1_PS 0x03 |
tile layer 1 palette select
Definition at line 319 of file pico9918.h.
| #define PICO9918_R29_SPRITE_STRIDE 0xc0 |
register 29 fields: scroll page sizes, and the stride between ECM pattern planes
sprite pattern plane stride, 0x800 >> n
Definition at line 322 of file pico9918.h.
| #define PICO9918_R29_PAGE2_HORZ 0x20 |
tile layer 2 scrolls across two pages
Definition at line 323 of file pico9918.h.
| #define PICO9918_R29_PAGE2_VERT 0x10 |
tile layer 2 scrolls down two pages
Definition at line 324 of file pico9918.h.
| #define PICO9918_R29_TILE_STRIDE 0x0c |
tile pattern plane stride, 0x800 >> n
Definition at line 325 of file pico9918.h.
| #define PICO9918_R29_PAGE1_HORZ 0x02 |
tile layer 1 scrolls across two pages
Definition at line 326 of file pico9918.h.
| #define PICO9918_R29_PAGE1_VERT 0x01 |
tile layer 1 scrolls down two pages
Definition at line 327 of file pico9918.h.
| #define PICO9918_R31_BML_ENABLE 0x80 |
| #define PICO9918_R31_BML_PRIORITY 0x40 |
bitmap layer above the tile layers
Definition at line 331 of file pico9918.h.
| #define PICO9918_R31_BML_TRANSP 0x20 |
pixel value 0 is transparent
Definition at line 332 of file pico9918.h.
| #define PICO9918_R31_BML_FAT 0x10 |
two bits a pixel, drawn double width
Definition at line 333 of file pico9918.h.
| #define PICO9918_R31_BML_PS 0x0f |
bitmap layer palette select
Definition at line 334 of file pico9918.h.
| #define PICO9918_R47_DATA_PORT 0x80 |
register 47 bits: the palette data port
route data port writes to palette RAM
Definition at line 337 of file pico9918.h.
| #define PICO9918_R47_AUTO_INC 0x40 |
step the palette index after each entry
Definition at line 338 of file pico9918.h.
| #define PICO9918_R47_INDEX 0x3f |
first palette index to write
Definition at line 339 of file pico9918.h.
| #define PICO9918_R49_TILE2_ENABLE 0x80 |
register 49 bits: tile layer 2, row count, and the enhanced colour modes
draw tile layer 2
Definition at line 342 of file pico9918.h.
| #define PICO9918_R49_ROW30 0x40 |
30 rows of tiles rather than 24
Definition at line 343 of file pico9918.h.
| #define PICO9918_R49_ECM_TILE 0x30 |
tile ECM level field
Definition at line 344 of file pico9918.h.
| #define PICO9918_R49_ECM_TILE_1 0x10 |
tiles take one bitplane, two colours
Definition at line 345 of file pico9918.h.
| #define PICO9918_R49_ECM_TILE_2 0x20 |
tiles take two bitplanes, four colours
Definition at line 346 of file pico9918.h.
| #define PICO9918_R49_ECM_TILE_3 0x30 |
tiles take three bitplanes, eight colours
Definition at line 347 of file pico9918.h.
| #define PICO9918_R49_Y_REAL 0x08 |
sprite Y is the real row, not row minus one
Definition at line 348 of file pico9918.h.
| #define PICO9918_R49_ECM_SPRITE 0x03 |
sprite ECM level field
Definition at line 349 of file pico9918.h.
| #define PICO9918_R49_ECM_SPRITE_1 0x01 |
sprites take one bitplane, two colours
Definition at line 350 of file pico9918.h.
| #define PICO9918_R49_ECM_SPRITE_2 0x02 |
sprites take two bitplanes, four colours
Definition at line 351 of file pico9918.h.
| #define PICO9918_R49_ECM_SPRITE_3 0x03 |
sprites take three bitplanes, eight colours
Definition at line 352 of file pico9918.h.
| #define PICO9918_R50_RESET 0x80 |
register 50 bits: GPU triggers and the remaining layer controls
reset the VDP
Definition at line 355 of file pico9918.h.
| #define PICO9918_R50_GPU_HSYNC 0x40 |
trigger the GPU every scanline
Definition at line 356 of file pico9918.h.
| #define PICO9918_R50_GPU_VSYNC 0x20 |
trigger the GPU every frame
Definition at line 357 of file pico9918.h.
| #define PICO9918_R50_TILE1_OFF 0x10 |
stop drawing tile layer 1
Definition at line 358 of file pico9918.h.
| #define PICO9918_R50_REPORT_MAX 0x08 |
S0's sprite number reports the highest seen.
Definition at line 359 of file pico9918.h.
| #define PICO9918_R50_VSCANLINES 0x04 |
F18A only: dim every second raster line.
Definition at line 360 of file pico9918.h.
| #define PICO9918_R50_POS_ATTR 0x02 |
tile attributes come per position, not per tile
Definition at line 361 of file pico9918.h.
| #define PICO9918_R50_T2_PRIORITY 0x01 |
tile layer 2 above tile layer 1
Definition at line 362 of file pico9918.h.
| #define PICO9918_R56_GPU_RUN 0x01 |
register 56 bit: the GPU trigger
1 starts the GPU, 0 loads the PC without starting
Definition at line 365 of file pico9918.h.
| #define PICO9918_R57_UNLOCK 0x1c |
the value register 57 takes, twice in a row, to unlock
low two bits ignored; any other value locks again
Definition at line 368 of file pico9918.h.
| #define PICO9918_R15_COUNTER_RESET 0x40 |
register 15 bits: the counter controls, and which status register S1 reads
reset the frame/scanline counters
Definition at line 371 of file pico9918.h.
| #define PICO9918_R15_COUNTER_SNAP 0x20 |
latch the counters for reading
Definition at line 372 of file pico9918.h.
| #define PICO9918_R15_COUNTER_EN 0x10 |
let the counters run
Definition at line 373 of file pico9918.h.
| #define PICO9918_R15_STATUS_NUM 0x0f |
which status register S1 reads back
Definition at line 374 of file pico9918.h.
| #define TMS9918_PIXELS_X 256 |
active display width, every mode
Definition at line 376 of file pico9918.h.
| #define TMS9918_PIXELS_Y 384 |
tallest active display any mode reaches; a TMS9918A draws 192
Definition at line 377 of file pico9918.h.
| #define PICO9918_SCANLINE_BYTES_MAX (PICO9918_BUILD_TEXT80_8BPP ? TMS9918_PIXELS_X * 2 : TMS9918_PIXELS_X) |
the widest active line this build renders, in bytes
From the width the library was COMPILED at, not the includer's flags: an 8bpp 80-column build renders two bytes a pixel, and a consumer that derived this from its own flags would get half of what the renderer writes. pico9918_line_bytes() is the runtime answer for one line; this is the widest any mode here reaches.
Definition at line 508 of file pico9918.h.
| #define PICO9918_SCANLINE_BUFFER_SIZE (PICO9918_SCANLINE_BYTES_MAX + 8) |
the library's line buffer size - the active pixels plus the eight bytes past them that a fine-h-scrolled tile layer's last quad can reach
The allocation, where PICO9918_SCANLINE_BYTES_MAX is the picture inside it.
Definition at line 517 of file pico9918.h.
| typedef void(* pico9918_config_applied_fn) (pico9918_t *tms9918, void *userdata) |
Definition at line 96 of file pico9918.h.
| typedef void(* pico9918_config_reload_fn) (pico9918_t *tms9918, void *userdata) |
Definition at line 97 of file pico9918.h.
| typedef void(* pico9918_gpu_flash_fn) (pico9918_t *tms9918, void *userdata) |
Definition at line 98 of file pico9918.h.
| typedef void(* pico9918_gpu_config_save_fn) (pico9918_t *tms9918, uint8_t *config, uint8_t key, void *userdata) |
Definition at line 99 of file pico9918.h.
| enum pico9918_mode_t |
the display modes the VDP can be in, TMS9918A modes and F18A alike
Definition at line 103 of file pico9918.h.
| enum pico9918_chip_t |
which chip an instance answers as
A capability ladder, ordered least to most, so one value compares them all.
TMS9918 the pre-A part. It does not decode M3, so it has no Graphics II. TMS9918A adds Graphics II. The unlock write is still refused, so the register file stays eight wide, there is no GPU to start, and the enhanced renderer folds away exactly as it does on a locked device. F18A unlockable: the full register file, the enhanced modes and the GPU. None of the PICO9918's own extensions - a real F18A has no config port and no overlays - and it identifies as a real one in SR1. PICO9918 an F18A plus this board's extensions: the VR58/59 config port, the firmware-update register, and the splash and diagnostics overlays. PRO the RP2350 board: 80-column text at a byte a pixel, which brings the tile palette select, ECM and the bitmap layer to TEXT80, and its own splash. It answers software the same way a PICO9918 does - SR1 reads 0xE8 for both, so nothing probing for the chip can tell the tiers apart.
One behaviour runs the other way, because it is a quirk rather than a capability: the two TMS9918s drive DRAM, so R1's 4K/16K bit moves where a CPU-side access lands. The F18A has SRAM and the bit means nothing to it.
Declared only where the library was built PICO9918_RUNTIME_CHIP=ON, which a board does not: what the build fixes either way is the memory map, and a firmware that is one chip has nothing to select. See PICO9918_BUILD_RUNTIME_CHIP.
Definition at line 149 of file pico9918.h.
| enum pico9918_color_t |
the sixteen TMS9918 colours, in palette-index order
Definition at line 176 of file pico9918.h.
| enum pico9918_register_t |
the eight TMS9918 registers, by number and by what each one holds
Definition at line 197 of file pico9918.h.
the status registers, by number and by what each one reports
Which one a status read returns is selected by the low four bits of R15, so all but the first need the F18A personality unlocked. The counters are pairs, low byte first.
Definition at line 254 of file pico9918.h.
| pico9918_t * pico9918_new | ( | void | ) |
create a new TMS9918
NOTE - multi-instance limitations. Instances are independent for bus access, VRAM, registers and status. Rendering is not fully independent:
Driving a single instance - the overwhelmingly common case - is unaffected.
| void pico9918_set_chip | ( | pico9918_t * | tms9918, |
| pico9918_chip_t | chip | ||
| ) |
select which chip this instance answers as
Clamped to PICO9918_CHIP_MAX, so a request the build cannot honour comes back as the highest it can rather than as a half-honoured one - read pico9918_chip() to find out which you got. Stepping down from an unlocked personality relocks the device, because the register file it would otherwise leave visible is not one a TMS9918A has.
A reset preserves it: the personality is the chip on the board, not state the bus can clear. A new instance starts at PICO9918_CHIP_MAX, which is what a consumer that never calls this keeps.
Definition at line 276 of file pico9918.c.
References chipFeatures(), PICO9918_CHIP_MAX, PICO9918_CHIP_PICO9918_PRO, PICO9918_REG_GPU_CONTROL, pico9918_splash_select_pro(), and PICO9918_SR_IDENT.
Referenced by PICO9918_SECTION_SCRATCH_X().
| pico9918_chip_t pico9918_chip | ( | pico9918_t * | tms9918 | ) |
which chip this instance answers as
Definition at line 310 of file pico9918.c.
| void pico9918_reset | ( | pico9918_t * | tms9918 | ) |
reset the TMS9918
reset the TMS9918
Definition at line 318 of file pico9918.c.
References pico9918_frame_reset_int_impl(), PICO9918_INST_ONLY, pico9918_splash_reset(), PICO9918_SR_IDENT, PICO9918_SR_STATUS, and PICO9918_SR_VERSION.
Referenced by PICO9918_SECTION_SCRATCH_X().
| void pico9918_destroy | ( | pico9918_t * | tms9918 | ) |
destroy a TMS9918 and release everything it owns
destroy a TMS9918 and release everything it owns
tms9918: tms9918 object to destroy / clean up
Definition at line 360 of file pico9918.c.
| void pico9918_write_addr | ( | pico9918_t * | tms9918, |
| uint8_t | data | ||
| ) |
write an address (mode = 1) to the tms9918 - the data byte DB0 -> DB7
The port is a two-byte latch, and the SECOND byte says which pair it was: bit 7 set writes a register, and the first byte was its value; bit 7 clear sets the VRAM address, low byte first, with bit 14 of the address selecting a write rather than a read. Both orders put the payload first and the selector second.
pico9918_util.h already writes both sequences down - pico9918_write_register_value() and pico9918_set_address_read() / _write(). Prefer them to open-coding a pair: the order is easy to reverse, and reversing it addresses a different register rather than failing.
A pair is not atomic, and the latch is per instance rather than per caller. Inject a write from outside the guest's own stream while the guest is between its two bytes and the injected first byte completes the GUEST's pair as its selector, leaving the injected selector to be read as the next value: both writes land somewhere neither caller asked for. An out-of-band caller has to know the guest is at rest.
write an address (mode = 1) to the tms9918 - the data byte DB0 -> DB7
data: the data (DB0 -> DB7) to send
Definition at line 373 of file pico9918.c.
References PICO9918_INST, and pico9918_write_addr_impl().
Referenced by pico9918_set_address_read(), and pico9918_write_register_value().
| void pico9918_write_data | ( | pico9918_t * | tms9918, |
| uint8_t | data | ||
| ) |
write data (mode = 0) to the tms9918 - the data byte DB0 -> DB7
write data (mode = 0) to the tms9918 - the data byte DB0 -> DB7
data: the data (DB0 -> DB7) to send
Definition at line 395 of file pico9918.c.
References PICO9918_INST, and pico9918_write_data_impl().
Referenced by clearTmsRam(), pico9918_initialise_gfx_ii(), pico9918_write_byte_rpt(), pico9918_write_bytes(), pico9918_write_string(), and pico9918_write_string_offset().
| uint8_t pico9918_read_status | ( | pico9918_t * | tms9918 | ) |
read from the status register
Definition at line 379 of file pico9918.c.
References PICO9918_INST_ONLY, and pico9918_read_status_impl().
| uint8_t pico9918_peek_status | ( | pico9918_t * | tms9918 | ) |
read from the status register without resetting it
Definition at line 385 of file pico9918.c.
References PICO9918_INST_ONLY, and pico9918_peek_status_impl().
| uint8_t pico9918_read_data | ( | pico9918_t * | tms9918 | ) |
read data (mode = 0) from the tms9918
Definition at line 402 of file pico9918.c.
References PICO9918_INST_ONLY, and pico9918_read_data_impl().
| uint8_t pico9918_read_data_no_inc | ( | pico9918_t * | tms9918 | ) |
read data (mode = 0) without incrementing the address pointer
read data (mode = 0) without incrementing the address pointer
Definition at line 408 of file pico9918.c.
References PICO9918_INST_ONLY, and pico9918_read_data_no_inc_impl().
| bool pico9918_interrupt_status | ( | pico9918_t * | tms9918 | ) |
true if both the INT status and the INT control bit are set
true if both the INT status and the INT control bit are set
Definition at line 414 of file pico9918.c.
References PICO9918_INST_ONLY, and pico9918_interrupt_status_impl().
| void pico9918_interrupt_set | ( | pico9918_t * | tms9918 | ) |
set the interrupt flag
set the interrupt flag
Definition at line 420 of file pico9918.c.
References PICO9918_INST_ONLY, and pico9918_interrupt_set_impl().
| void pico9918_set_status | ( | pico9918_t * | tms9918, |
| uint8_t | status | ||
| ) |
set the status flags
set the status flags
Definition at line 427 of file pico9918.c.
References PICO9918_INST, and pico9918_set_status_impl().
| uint8_t pico9918_scan_line | ( | pico9918_t * | tms9918, |
| uint16_t | y | ||
| ) |
generate a scanline
Read it back with pico9918_line_source and pico9918_line_bytes: how wide a line is and which buffer holds it are both properties of the mode and the build, so the library owns the memory.
Definition at line 3256 of file pico9918.c.
References graphics_i_scan_line(), PICO9918_INST, PICO9918_INST_ONLY, pico9918_line_bytes(), PICO9918_R24_TILE1_PS, PICO9918_REG_PALETTE_SELECT, text_scan_line(), TMS_R1_DISP_ACTIVE, and tmsMainBgColor().
Referenced by pico9918_frame_scanline().
| uint8_t pico9918_reg_value | ( | pico9918_t * | tms9918, |
| pico9918_register_t | reg | ||
| ) |
return a register value
The guest's view, so a LOCKED device decodes three address bits and nothing more: reg 30 reads R6, exactly as a write to it would land on R6. Reading the register a locked device cannot address is TMS_REGISTER on the Impl surface.
return a register value
Definition at line 3329 of file pico9918.c.
| uint8_t pico9918_status_value | ( | pico9918_t * | tms9918, |
| pico9918_status_register_t | reg | ||
| ) |
return a status register value, without the side effects of reading it
The whole status file, non-destructively: no flag is cleared, no sprite number is restored and /INT is left where it is - none of which is true of pico9918_read_status(), which is the guest's destructive read of whichever register R15 selects.
NOT masked the way pico9918_reg_value() is. A locked device has no three-bit status address to model: R15 is above the registers it admits, so a locked guest can reach SR0 and nothing else. The mask here is the width of R15's own select field.
return a status register value, without the side effects of reading it
Definition at line 3336 of file pico9918.c.
References PICO9918_R15_STATUS_NUM.
| uint8_t pico9918_vram_value | ( | pico9918_t * | tms9918, |
| uint16_t | addr | ||
| ) |
return a value from vram
Definition at line 3485 of file pico9918.c.
| bool pico9918_display_enabled | ( | pico9918_t * | tms9918 | ) |
check the BLANK flag
check the BLANK flag
Definition at line 3492 of file pico9918.c.
References TMS_R1_DISP_ACTIVE.
| pico9918_mode_t pico9918_display_mode | ( | pico9918_t * | tms9918 | ) |
the current display mode
the current display mode
Definition at line 3499 of file pico9918.c.
Referenced by pico9918_diag_update().
| uint32_t pico9918_line_bytes | ( | pico9918_t * | tms9918 | ) |
how many bytes of the line the current mode fills: 256, or 512 for unlocked 80-column text on a board built with the 8bpp tier
how many bytes of the line the current mode fills: 256, or 512 for unlocked 80-column text on a board built with the 8bpp tier
Every mode is 256 but unlocked 80-column text on a board with the 8bpp tier, which is 512 - so the palette expansion, the backdrop fill and anything reading the line ask here rather than each deciding it again.
Definition at line 3518 of file pico9918.c.
References TMS9918_PIXELS_X.
Referenced by pico9918_scan_line().
| const uint8_t * pico9918_line_source | ( | pico9918_t * | tms9918 | ) |
where the scanline just generated actually is - the arbitration buffer, or a tile layer's own buffer on a line that needed no compositing
Valid until the next scanline, and the only way to read the line back. Always word-aligned, so it can be read a word at a time.
where the scanline just generated actually is - the arbitration buffer, or a tile layer's own buffer on a line that needed no compositing
Usually the buffer that was passed in, but on a line with nothing to arbitrate it is a tile layer's own buffer and the passed one holds only the backdrop fill - so read the line from here rather than from what was handed over.
Definition at line 3529 of file pico9918.c.
| uint16_t pico9918_default_palette | ( | int | index | ) |
a default palette value, 0x0rgb
a default palette value, 0x0rgb
Definition at line 3536 of file pico9918.c.
Referenced by pico9918_config_defaults().