X-Git-Url: https://scm.lunaixsky.com/lunaix-os.git/blobdiff_plain/6f6da1abb22dff69dbb710bd2fd9d95f083f2b43..8b8f49b713d64065775fe538232f8639083601bd:/lunaix-os/hal/gfxa/vga/vga_mmio_ops.c diff --git a/lunaix-os/hal/gfxa/vga/vga_mmio_ops.c b/lunaix-os/hal/gfxa/vga/vga_mmio_ops.c new file mode 100644 index 0000000..4ec8c3e --- /dev/null +++ b/lunaix-os/hal/gfxa/vga/vga_mmio_ops.c @@ -0,0 +1,90 @@ +#include "vga.h" + +typedef volatile u8_t vga_reg8; + +#define regaddr(type, i, vga) \ + ((vga_reg8*)(vga_gfx_regmap[type][i] + (vga)->io_off)) + +#define arx_reset(v) (void)(*regaddr(VGA_STATX, 1, v)) + +// Port IO Address - 0x3C0 +static u32_t vga_gfx_regmap[][2] = { + [VGA_ARX] = { 0x0, 0x1 }, [VGA_SRX] = { 0x04, 0x05 }, + [VGA_GRX] = { 0x0E, 0x0F }, [VGA_CRX] = { 0x14, 0x15 }, + [VGA_DACX] = { 0x08, 0x09 }, [VGA_MISCX] = { 0x02, 0x0C }, + [VGA_STATX] = { 0x02, 0x1A } +}; + +static u32_t +vga_mmio_read(struct vga* v, u32_t type, u32_t index, u32_t mask) +{ + vga_reg8* reg_ix = regaddr(type, VGA_REG_X, v); + vga_reg8* reg_rd = regaddr(type, VGA_REG_D, v); + *reg_ix = (u8_t)index; + return ((u32_t)*reg_rd) & mask; +} + +static void +vga_mmio_write(struct vga* v, u32_t type, u32_t index, u32_t val, u32_t mask) +{ + index = index & 0xff; + val = val & mask; + vga_reg8* reg_ix = regaddr(type, VGA_REG_X, v); + if (type == VGA_ARX) { + // reset ARX filp-flop + arx_reset(v); + *reg_ix = ((u8_t)index) | 0x20; + *reg_ix = val; + return; + } else if (type == VGA_MISCX) { + *reg_ix = val; + return; + } + + *((u16_t*)reg_ix) = (u16_t)(((val) << 8) | index); +} + +static void +vga_mmio_set_regs(struct vga* v, u32_t type, size_t off, u32_t* seq, size_t len) +{ + vga_reg8* reg_ix = regaddr(type, VGA_REG_X, v); + if (type == VGA_ARX) { + arx_reset(v); + for (size_t i = 0; i < len; i++) { + *reg_ix = (u8_t)(off + i) | 0x20; + *reg_ix = seq[i]; + } + + } else { + for (size_t i = 0; i < len; i++) { + *((u16_t*)reg_ix) = (u16_t)((seq[i] << 8) | ((off + i) & 0xff)); + } + } +} + +static void +vga_mmio_set_dacp(struct vga* v) +{ +#define R(c) (u8_t)(((c) & 0xff0000) >> 16) +#define G(c) (u8_t)(((c) & 0x00ff00) >> 8) +#define B(c) (u8_t)(((c) & 0x0000ff)) + + vga_reg8* reg_ix = regaddr(VGA_DACX, VGA_REG_X, v); + vga_reg8* reg_dat = regaddr(VGA_DACX, VGA_REG_D, v); + + u32_t* color_map = v->lut.colors; + + *reg_ix = 0; + for (size_t i = 0; i < v->lut.len; i++) { + u32_t color = color_map[i]; + *reg_dat = R(color); + *reg_dat = G(color); + *reg_dat = B(color); + } +} + +struct vga_regops vga_default_mmio_ops = { .read = vga_mmio_read, + .write = vga_mmio_write, + .set_seq = vga_mmio_set_regs, + .set_dac_palette = + vga_mmio_set_dacp }; \ No newline at end of file