45 #include "../include/vga.h" 54 #define VGA_TICK_SHIFT 18 56 #define MAX_RETRACE_SCANLINES 420 57 #define N_IS1_READ_THRESHOLD 50 59 #define GFX_ADDR_WINDOW 0x18000 61 #define VGA_FB_ADDR 0x1c00000000ULL 63 #define MODE_CHARCELL 1 64 #define MODE_GRAPHICS 2 66 #define GRAPHICS_MODE_8BIT 1 67 #define GRAPHICS_MODE_4BIT 2 152 static void recalc_cursor_position(
struct vga_data *d)
169 static void register_reset(
struct vga_data *d)
177 recalc_cursor_position(d);
191 static void c_putstr(
struct vga_data *d,
const char *s)
201 static void reset_palette(
struct vga_data *d,
int grayscale)
206 for (i=16; i<256; i++)
215 for (b=0; b<2; b++) {
223 (r+g+b) * 0xaa / 3 + 0x55;
231 for (b=0; b<2; b++) {
239 for (b=0; b<2; b++) {
256 struct vga_data *d,
int base,
int start,
int end)
259 int i, oldcolor = -1, printed_last = 0;
261 for (i=start; i<=end; i+=2) {
264 int bg = (d->
charcells[base+i+1] >> 4) & 15;
266 int x = (i/2) % d->
max_x;
267 int y = (i/2) / d->
max_x;
278 if (!printed_last || x == 0) {
279 snprintf(s,
sizeof(s),
"\033[%i;%iH", y + 1, x + 1);
282 if (oldcolor < 0 || (bg<<4)+fg != oldcolor || !printed_last) {
283 snprintf(s,
sizeof(s),
"\033[0;"); c_putstr(d, s);
286 case 0: c_putstr(d,
"30");
break;
287 case 1: c_putstr(d,
"34");
break;
288 case 2: c_putstr(d,
"32");
break;
289 case 3: c_putstr(d,
"36");
break;
290 case 4: c_putstr(d,
"31");
break;
291 case 5: c_putstr(d,
"35");
break;
292 case 6: c_putstr(d,
"33");
break;
293 case 7: c_putstr(d,
"37");
break;
299 case 0: c_putstr(d,
"40");
break;
300 case 1: c_putstr(d,
"44");
break;
301 case 2: c_putstr(d,
"42");
break;
302 case 3: c_putstr(d,
"46");
break;
303 case 4: c_putstr(d,
"41");
break;
304 case 5: c_putstr(d,
"45");
break;
305 case 6: c_putstr(d,
"43");
break;
306 case 7: c_putstr(d,
"47");
break;
312 if (ch >= 0x20 && ch != 127)
315 oldcolor = (bg << 4) + fg;
332 static void vga_update_graphics(
struct machine *machine,
struct vga_data *d,
333 int x1,
int y1,
int x2,
int y2)
336 unsigned char pixel[3];
338 for (y=y1; y<=y2; y++)
339 for (x=x1; x<=x2; x++) {
352 c = d->
gfx_mem[addr >> 1] >> 4;
354 c = d->
gfx_mem[addr >> 1] & 0xf;
360 for (iy=y*ry; iy<(y+1)*ry; iy++)
361 for (ix=x*rx; ix<(x+1)*rx; ix++) {
367 pixel,
sizeof(pixel),
381 static void vga_update_text(
struct machine *machine,
struct vga_data *d,
382 int x1,
int y1,
int x2,
int y2)
384 int fg, bg, x,y, subx, line;
385 size_t i, start, end, base;
391 fatal(
"[ too large font ]\n");
396 start = (d->
max_x * y1 + x1) * 2;
397 end = (d->
max_x * y2 + x2) * 2;
409 vga_update_textmode(machine, d, base, start, end);
411 for (i=start; i<=end; i+=2) {
412 unsigned char ch = d->
charcells[i + base];
422 bg = (d->
charcells[i+base + 1] >> 4) & 7;
426 int tmp = fg; fg = bg; bg = tmp;
429 x = (i/2) % d->
max_x; x *= font_width;
430 y = (i/2) / d->
max_x; y *= font_size;
433 for (line = 0; line < font_size; line++) {
435 unsigned char rgb_line[3 * 8 * 8];
450 if (d->
font[ch * font_size + line] &
458 ix) * 3, &pal[color_index * 3], 3);
467 machine->
memory, addr, rgb_line,
479 static void vga_update_cursor(
struct machine *machine,
struct vga_data *d)
507 int64_t low = -1, high;
513 (uint64_t *) &low, (uint64_t *) &high);
518 int new_u_y1, new_u_y2;
519 debug(
"[ dev_vga_tick: dyntrans access, %" PRIx64
" .. %" 520 PRIx64
" ]\n", (uint64_t) low, (uint64_t) high);
525 new_u_y1 = (low/2) / d->
max_x;
526 new_u_y2 = ((high/2) / d->
max_x) + 1;
560 vga_update_textmode(
cpu->
machine, d, 0, 2, 0);
590 int j, x=0, y=0, x2=0, y2=0,
modified = 0;
601 y = relative_addr / d->
max_x;
602 x = relative_addr % d->
max_x;
603 y2 = (relative_addr+len-1) / d->
max_x;
604 x2 = (relative_addr+len-1) % d->
max_x;
613 y = relative_addr * 8 / d->
max_x;
614 x = relative_addr * 8 % d->
max_x;
615 y2 = ((relative_addr+len)*8-1) / d->
max_x;
616 x2 = ((relative_addr+len)*8-1) % d->
max_x;
622 for (i=0; i<len; i++)
623 for (j=0; j<8; j++) {
624 int pixelmask = 1 << (7-j);
625 int b =
data[i] & pixelmask;
628 uint32_t addr = (y * d->
max_x + x +
649 fatal(
"TODO: 4 bit graphics read, mask=0x%02x\n",
651 for (i=0; i<len; i++)
655 default:
fatal(
"dev_vga: Unimplemented graphics mode %i\n",
666 if (x2 < d->update_x1) d->
update_x1 = x2;
668 if (y2 < d->update_y1) d->
update_y1 = y2;
685 uint64_t idata = 0, odata = 0;
686 int x, y, x2, y2, r, base;
694 r = relative_addr - base;
695 y = r / (d->
max_x * 2);
696 x = (r/2) % d->
max_x;
697 y2 = (r+len-1) / (d->
max_x * 2);
698 x2 = ((r+len-1)/2) % d->
max_x;
702 for (i=0; i<len; i++) {
703 int old = d->
charcells[relative_addr + i];
704 if (old !=
data[i]) {
716 if (x2 < d->update_x1) d->
update_x1 = x2;
718 if (y2 < d->update_y1) d->
update_y1 = y2;
731 switch (relative_addr) {
734 debug(
"[ vga: read from 0x%08lx ]\n",
735 (
long)relative_addr);
737 debug(
"[ vga: write to 0x%08lx: 0x%08x ]\n",
738 (
long)relative_addr, idata);
754 static void vga_crtc_reg_write(
struct machine *machine,
struct vga_data *d,
755 int regnr,
int idata)
770 recalc_cursor_position(d);
774 recalc_cursor_position(d);
848 fatal(
"TODO! video mode change hack (mode 0x%02x)\n",
866 for (i=0; i<machine->
ncpus; i++)
888 reset_palette(d, grayscale);
891 default:
fatal(
"[ vga_crtc_reg_write: regnr=0x%02x idata=0x%02x ]\n",
902 static void vga_sequencer_reg_write(
struct machine *machine,
struct vga_data *d,
903 int regnr,
int idata)
909 debug(
"[ vga_sequencer_reg_write: select %i: TODO ]\n", regnr);
911 default:
fatal(
"[ vga_sequencer_reg_write: select %i ]\n", regnr);
922 static void vga_graphcontr_reg_write(
struct machine *machine,
923 struct vga_data *d,
int regnr,
int idata)
930 debug(
"[ vga_graphcontr_reg_write: select %i: TODO ]\n", regnr);
932 default:
fatal(
"[ vga_graphcontr_reg_write: select %i ]\n", regnr);
943 static void vga_attribute_reg_write(
struct machine *machine,
struct vga_data *d,
944 int regnr,
int idata)
947 if (regnr >= 0 && regnr <= 0xf)
951 default:
fatal(
"[ vga_attribute_reg_write: select %i ]\n", regnr);
966 uint64_t idata = 0, odata = 0;
968 for (i=0; i<len; i++) {
973 switch (relative_addr) {
994 fatal(
"[ dev_vga: WARNING: Write to " 995 "VGA_ATTRIBUTE_DATA_READ? ]\n");
998 fatal(
"[ dev_vga: WARNING: Read from " 999 "VGA_ATTRIBUTE_DATA_READ, but no" 1000 " register selected? ]\n");
1039 debug(
"[ dev_vga: WARNING: Read from " 1040 "VGA_DAC_ADDR_READ? TODO ]\n");
1053 fatal(
"[ dev_vga: WARNING: Read from " 1054 "VGA_DAC_ADDR_WRITE? ]\n");
1060 int new_ = (idata & 63) << 2;
1141 (
unsigned char *) malloc(
1162 debug(
"[ vga_ctrl: read from 0x%08lx ]\n",
1163 (
long)relative_addr);
1165 debug(
"[ vga_ctrl: write to 0x%08lx: 0x%08x" 1166 " ]\n", (
long)relative_addr, (
int)idata);
1191 size_t allocsize, i;
1194 memset(d, 0,
sizeof(
struct vga_data));
1248 32, dev_vga_ctrl_access, d,
DM_DEFAULT, NULL);
1254 reset_palette(d, 0);
1267 vga_update_cursor(machine, d);
#define VGA_INPUT_STATUS_1
uint64_t memory_readmax64(struct cpu *cpu, unsigned char *buf, int len)
void fatal(const char *fmt,...)
unsigned char * charcells
char palette_write_subindex
#define VGA_SEQUENCER_ADDR
#define VGA_MISC_OUTPUT_IOAS
#define VGA_CRTC_CURSOR_LOCATION_HIGH
struct vfb_data * dev_fb_init(struct machine *machine, struct memory *mem, uint64_t baseaddr, int vfb_type, int visible_xsize, int visible_ysize, int xsize, int ysize, int bit_depth, const char *name)
unsigned char crtc_reg[256]
void dev_vga_init(struct machine *machine, struct memory *mem, uint64_t videomem_base, uint64_t control_base, const char *name)
unsigned char crtc_reg_select
unsigned char graphcontr_reg[256]
#define VGA_GRAPHCONTR_MISC
unsigned char * charcells_drawn
#define VGA_MISC_OUTPUT_W
void console_putchar(int handle, int ch)
unsigned char attribute_reg[256]
#define VGA_GRAPHCONTR_MASK
#define VGA_ATTRIBUTE_DATA_READ
#define VGA_DAC_ADDR_WRITE
#define CHECK_ALLOCATION(ptr)
#define VGA_GRAPHCONTR_READMAPSELECT
DEVICE_ACCESS(vga_graphics)
#define MAX_RETRACE_SCANLINES
#define VGA_GRAPHCONTR_GRAPHICSMODE
unsigned char * retrace_palette
#define VGA_CRTC_START_ADDR_LOW
#define DM_READS_HAVE_NO_SIDE_EFFECTS
#define VGA_ATTRIBUTE_ADDR
#define GRAPHICS_MODE_8BIT
unsigned char graphcontr_reg_select
#define DM_DYNTRANS_WRITE_OK
unsigned char sequencer_reg[256]
#define VGA_GRAPHCONTR_DATA
#define VGA_CRTC_CURSOR_SCANLINE_END
unsigned char sequencer_reg_select
#define VGA_CRTC_START_ADDR_HIGH
#define VGA_IS1_DISPLAY_DISPLAY_DISABLE
#define VGA_MISC_OUTPUT_R
#define VGA_SEQ_SEQUENCER_MEMORY_MODE
unsigned char attribute_reg_select
char palette_read_subindex
#define VGA_CRTC_CURSOR_LOCATION_LOW
unsigned char * charcells_outputed
void memory_writemax64(struct cpu *cpu, unsigned char *buf, int len, uint64_t data)
#define VGA_IS1_DISPLAY_VRETRACE
int dev_vga_access(struct cpu *cpu, struct memory *mem, uint64_t relative_addr, unsigned char *data, size_t len, int writeflag, void *)
int dev_fb_access(struct cpu *cpu, struct memory *mem, uint64_t relative_addr, unsigned char *data, size_t len, int writeflag, void *)
void dev_fb_resize(struct vfb_data *d, int new_xsize, int new_ysize)
#define VGA_GRAPHCONTR_ADDR
int console_start_slave(struct machine *machine, const char *consolename, int use_for_input)
void memory_device_register(struct memory *mem, const char *, uint64_t baseaddr, uint64_t len, int(*f)(struct cpu *, struct memory *, uint64_t, unsigned char *, size_t, int, void *), void *extra, int flags, unsigned char *dyntrans_data)
#define GRAPHICS_MODE_4BIT
#define N_IS1_READ_THRESHOLD
#define VGA_SEQUENCER_DATA
void memory_device_dyntrans_access(struct cpu *, struct memory *mem, void *extra, uint64_t *low, uint64_t *high)
addr & if(addr >=0x24 &&page !=NULL)
void machine_add_tickfunction(struct machine *machine, void(*func)(struct cpu *, void *), void *extra, int clockshift)
unsigned char palette_write_index
unsigned char misc_output_reg
unsigned char rgb_palette[256 *3]
#define VGA_CRTC_CURSOR_SCANLINE_START
#define CONSOLE_OUTPUT_ONLY
unsigned char palette_read_index
void dev_fb_setcursor(struct vfb_data *d, int cursor_x, int cursor_y, int on, int cursor_xsize, int cursor_ysize)
#define VGA_DAC_ADDR_READ
void(* invalidate_translation_caches)(struct cpu *, uint64_t paddr, int flags)