v99xx: add vdp driver
authorgeijoenr <enric.geijo@gmail.com>
Mon, 16 Mar 2015 10:24:10 +0000 (10:24 +0000)
committergeijoenr <enric.geijo@gmail.com>
Mon, 16 Mar 2015 20:32:32 +0000 (20:32 +0000)
for now minimal functionality to support VT in TEXT2 mode

Kernel/dev/v99xx.c [new file with mode: 0644]
Kernel/dev/v99xx.h [new file with mode: 0644]

diff --git a/Kernel/dev/v99xx.c b/Kernel/dev/v99xx.c
new file mode 100644 (file)
index 0000000..c920231
--- /dev/null
@@ -0,0 +1,220 @@
+/*
+ * v99xx video display processor driver
+ *
+ * (tms9918a, v9938 and v9958)
+ */
+
+#include <v99xx.h>
+#include <kernel.h>
+
+/* 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 (file)
index 0000000..9fbe33c
--- /dev/null
@@ -0,0 +1,131 @@
+#ifndef _V99xx_H_
+#define _V99xx_H_
+
+#include <kernel.h>
+
+#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