From: geijoenr Date: Mon, 16 Mar 2015 10:24:10 +0000 (+0000) Subject: v99xx: add vdp driver X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=5a5e42681ef280bdfc76a434f7d9a7a7af567999;p=FUZIX.git v99xx: add vdp driver for now minimal functionality to support VT in TEXT2 mode --- diff --git a/Kernel/dev/v99xx.c b/Kernel/dev/v99xx.c new file mode 100644 index 00000000..c9202318 --- /dev/null +++ b/Kernel/dev/v99xx.c @@ -0,0 +1,220 @@ +/* + * v99xx video display processor driver + * + * (tms9918a, v9938 and v9958) + */ + +#include +#include + +/* v99xx doesn't support register read + * need to keep a local copy to change bits */ +static uint8_t v99xx_regs[V99xx_NREGS]; + +void v99xx_write_reg(uint8_t reg, uint8_t val) +{ + v99xx_regs[reg]=val; + __asm + pop hl + pop de + push de + push hl + ld bc, (_vdpport) + out (c), d + ld a,e + or #0x80 + out (c), a + __endasm; +} + +/* + * v99xx can address up to 128Kb of VRAM + * via page selection (up to 8 pages) in register #14 + */ +void v99xx_set_vram_page(uint8_t page) +{ + v99xx_write_reg(V99xx_SET_VRAM_PAGE, page & 0x7); +} + +/* + * write byte in current ram page + * (only 14 bits of address are used) + */ +void v99xx_write_vram(uint16_t addr, uint8_t val) +{ + used(addr); + used(val); + + __asm + pop bc + pop hl + pop de + push de + push hl + push bc + ld bc, (_vdpport) + ld b,e + out (c),l + ld a, h + or #0x40 + out (c),a + dec c + out (c),b + __endasm; +} + +/* + * read byte from current ram page + * (only 14 bits of address are used) + */ +uint8_t v99xx_read_vram(uint16_t addr) +{ + used(addr); + __asm + pop bc + pop hl + push hl + push bc + ld bc, (_vdpport) + out (c),l + out (c),h + dec c + in a,(c) + __endasm; + return 0; +} + +/* + * memset to vram current page (up to 16Kb) + */ +void v99xx_memset_vram(uint16_t addr, uint8_t value, uint16_t size) +{ + used(addr); + used(value); + used(size); + + __asm + pop ix + pop hl + pop de + dec sp + ld bc, (_vdpport) + ld b,e + pop de + push bc + push de + inc sp + push hl + push ix + out (c),l + ld a, h + or #0x40 + out (c),a + dec c +memset_loop: + out (c),b + dec de + ld a,d + or e + jr nz,memset_loop + __endasm; + +} + +/* + * Copy from vram current page (up to 16Kb) + */ +void v99xx_copy_from_vram(uint8_t *dst, uint16_t vaddr, uint16_t size) +{ + used(vaddr); + used(dst); + used(size); + + __asm + pop iy + pop hl + pop de + ld bc, (_vdpport) + out (c),e + out (c),d + pop de + push de + push de + push hl + push iy + dec c +cpfvram_loop: + ini + dec de + ld a,d + or e + jr nz,cpfvram_loop + __endasm; +} + +/* + * Copies to vram current page (up to 16Kb) + */ +void v99xx_copy_to_vram(uint16_t vaddr, uint8_t *src, uint16_t size) +{ + used(vaddr); + used(src); + used(size); + + __asm + pop iy + pop de + ld bc, (_vdpport) + out (c),e + ld a,d + or #0x40 + out (c),a + pop hl + pop de + push de + push hl + push de + push iy + dec c +cptvram_loop: + outi + dec de + ld a,d + or e + jr nz,cptvram_loop + __endasm; +} + + +void v99xx_set_mode(unsigned char mode) +{ + switch (mode) + { + case MODE_TEXT2: + /* default TEXT2 configuration same as in bios */ + v99xx_write_reg(V99xx_REG_MODE0,0x04); + v99xx_write_reg(V99xx_REG_MODE1,0x70); + v99xx_write_reg(V99xx_REG_PTRN_LAYOUT_BASE,0x03); + v99xx_write_reg(V99xx_REG_COLOR_BASE_H, 0x27); + v99xx_write_reg(V99xx_REG_COLOR_BASE_L, 0); + v99xx_write_reg(V99xx_REG_PATRN_GEN_BASE, 2); + break; + } +} + +void v99xx_set_color(uint8_t fg, uint8_t bg) +{ + v99xx_write_reg(V99xx_REG_COLOR1, (fg << 4) | (bg & 0xf)); +} + +void v99xx_set_blink_color(uint8_t fg, uint8_t bg) +{ + v99xx_write_reg(V99xx_REG_COLOR2, (fg << 4) | (bg & 0xf)); +} + +void v99xx_set_blink_period(uint8_t fg, uint8_t bg) +{ + v99xx_write_reg(V99xx_REG_BLINK_PERIOD, (fg << 4) | (bg & 0xf)); +} + + diff --git a/Kernel/dev/v99xx.h b/Kernel/dev/v99xx.h new file mode 100644 index 00000000..9fbe33cd --- /dev/null +++ b/Kernel/dev/v99xx.h @@ -0,0 +1,131 @@ +#ifndef _V99xx_H_ +#define _V99xx_H_ + +#include + +#define V99xx_NREGS 0x1B + +/* mode registers */ +#define V99xx_REG_MODE0 0x00 +#define V99xx_REG_MODE1 0x01 + +#define V99xx_REG_MODE1_BL_MASK (1 << 6) +#define V99xx_REG_MODE1_IE0 (1 << 5) + +#define V99xx_REG_MODE2 0x08 +#define V99xx_REG_MODE3 0x09 + +/* table base address registers */ +#define V99xx_REG_PTRN_LAYOUT_BASE 0x02 +#define V99xx_REG_COLOR_BASE_H 0x03 +#define V99xx_REG_COLOR_BASE_L 0x0A +#define V99xx_REG_PATRN_GEN_BASE 0x04 +#define V99xx_REG_SPRITE_ATTR_L 0x05 +#define V99xx_REG_SPRITE_ATTR_H 0x0B +#define V99xx_REG_SPRITE_PATRN 0x06 + +/* color registers */ +#define V99xx_REG_COLOR1 0x07 +#define V99xx_REG_COLOR2 0x0C +#define V99xx_REG_BLINK_PERIOD 0x0D +#define V99xx_REG_COLOR_BURST1 0x14 +#define V99xx_REG_COLOR_BURST2 0x15 +#define V99xx_REG_COLOR_BURST3 0x16 + +/* display registers */ +#define V99xx_REG_DISP_CENTER 0x12 +#define V99xx_REG_VERT_OFFSET 0x17 +#define V99xx_REG_INT_LINE 0x13 + +/* access registers */ +#define V99xx_SET_VRAM_PAGE 0x0E +#define V99xx_SET_STATUS_REG 0x0F +#define V99xx_SET_PALETTE_REG 0x10 +#define V99xx_SET_CONTROL_REG 0x11 + +/* command registers */ +#define V99xx_REG_CMD_SRC_XL 0x20 +#define V99xx_REG_CMD_SRC_XH 0x21 +#define V99xx_REG_CMD_SRC_YL 0x22 +#define V99xx_REG_CMD_SRC_YH 0x23 +#define V99xx_REG_CMD_DST_XL 0x24 +#define V99xx_REG_CMD_DST_XH 0x25 +#define V99xx_REG_CMD_DST_YL 0x26 +#define V99xx_REG_CMD_DST_YH 0x27 +#define V99xx_REG_CMD_SIZE_XL 0x28 +#define V99xx_REG_CMD_SIZE_XH 0x29 +#define V99xx_REG_CMD_SIZE_YL 0x2A +#define V99xx_REG_CMD_SIZE_YH 0x2B +#define V99xx_REG_CMD_COLOR 0x2C +#define V99xx_REG_CMD_ARG 0x2D +#define V99xx_REG_CMD_OP 0x2E + +/* extended registers V9958 */ +#define V99xx_REG_MODE4 0x19 +#define V99xx_REG_HOR_OFFSET1 0x1A +#define V99xx_REG_HOR_OFFSET2 0x1B + +#define MODE_EXTEND_CMD 0x40 + +/* vram access flags */ +#define REG_VRAM_ADDR_MASK 1 +#define REG_VRAM_WRITE_FLAG 0x40 +#define REG_VRAM_READ_FLAG 0x3F + +/* mode flags */ +#define MODE_MASK_MODE0 1 + +/* M1 and M2 are bits 4 and 3 */ +#define MODE_MASK_REG_MODE1(x) (((x) & 0x1C) >> 1) +#define MODE_MASK_REG_MODE0(x) (((x) & 0x7) << 1) + +#define MODE_TEXT1 0x01 +#define MODE_TEXT2 0x09 +#define MODE_G1 0x00 +#define MODE_G2 0x04 +#define MODE_G3 0x08 +#define MODE_G4 0x0C +#define MODE_G5 0x10 +#define MODE_G6 0x14 +#define MODE_G7 0x1C + +/* commands */ +#define CMD_HMMC 0xF +#define CMD_YMMM 0xE +#define CMD_HMMM 0xD +#define CMD_HMMV 0xC +#define CMD_LMMC 0xB +#define CMD_LMCM 0xA +#define CMD_LMMM 0x9 +#define CMD_LMMV 0x8 +#define CMD_LINE 0x7 +#define CMD_SRCH 0x6 +#define CMD_PSET 0x5 +#define CMD_POINT 0x4 +#define CMD_STOP 0x0 + +/* comand logic ops */ +#define CMD_IMP 0x0 +#define CMD_AND 0x1 +#define CMD_OR 0x2 +#define CMD_XOR 0x3 +#define CMD_NOT 0x4 +#define CMD_TIMP 0x8 +#define CMD_TAND 0x9 +#define CMD_TOR 0xA +#define CMD_TXOR 0xB +#define CMD_TNOT 0xC + +void v99xx_write_reg(uint8_t reg, uint8_t val); +void v99xx_set_vram_page(uint8_t page); +void v99xx_write_vram(uint16_t addr, uint8_t val); +void v99xx_memset_vram(uint16_t addr, uint8_t value, uint16_t size); +void v99xx_copy_to_vram(uint16_t vaddr, uint8_t *src, uint16_t size); +void v99xx_copy_from_vram(uint8_t *dst, uint16_t vaddr, uint16_t size); +uint8_t v99xx_read_vram(uint16_t addr); +void v99xx_set_mode(uint8_t mode); +void v99xx_set_color(uint8_t fg, uint8_t bg); +void v99xx_set_blink_color(uint8_t fg, uint8_t bg); +void v99xx_set_blink_period(uint8_t fg, uint8_t bg); + +#endif