From 82c95c1997f633782d5535c9db48051cd1ca25d2 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Tue, 3 Jul 2018 00:51:18 +0100 Subject: [PATCH] trs80m1: fill in the graphics basics Not yet tested --- Kernel/platform-trs80m1/devgfx.c | 149 +++++++++++++++++++++++++++--- Kernel/platform-trs80m1/devgfx.h | 5 +- Kernel/platform-trs80m1/discard.c | 3 + 3 files changed, 138 insertions(+), 19 deletions(-) diff --git a/Kernel/platform-trs80m1/devgfx.c b/Kernel/platform-trs80m1/devgfx.c index 0542fcc3..24f459a4 100644 --- a/Kernel/platform-trs80m1/devgfx.c +++ b/Kernel/platform-trs80m1/devgfx.c @@ -9,8 +9,18 @@ #include #include #include +#include "trs80.h" -static const struct display trsdisplay[1] = { +__sfr __at 0x00 hrg_off; +__sfr __at 0x04 hrg_data; +__sfr __at 0x82 gfx_data; +__sfr __at 0x83 gfx_ctrl; +__sfr __at 0xFF ioctrl; + +static uint8_t max_mode = 0; + +static struct display trsdisplay[4] = { + /* Text mode */ { 0, 128, 48, @@ -21,26 +31,91 @@ static const struct display trsdisplay[1] = { GFX_MAPPABLE|GFX_MULTIMODE|GFX_TEXT, 1, 0 + }, + /* Tandy Graphics */ + { + 1, + 640, 240, + 640, 240, + 255, 255, + FMT_MONO_BW, + HW_TRS80GFX, + GFX_MULTIMODE|GFX_MAPPABLE, + 32, + 0 /* For now lets just worry about map */ + }, + /* Microlabs Graphyx */ + { + 1, + 512, 192, + 512, 192, + 255, 255, + FMT_MONO_BW, + HW_MICROLABS, + GFX_MULTIMODE|GFX_MAPPABLE, + 12, + 0 + }, + /* HRG1B */ + { + 1, + 384, 192, + 384, 192, + 255, 255, + FMT_MONO_BW, + HW_HRG1B, + GFX_MULTIMODE|GFX_MAPPABLE, + 9, + 0 } }; -/* Assumes a Tandy board */ -static const struct videomap trsmap = { - 0, - 0, - 0x3C00, - 0x0400, /* Directly mapped */ - 0, 0, /* No segmentation */ - 1, /* Standard spacing */ - MAP_FBMEM_SIMPLE|MAP_FBMEM +static struct videomap trsmap[4] = { + { + 0, + 0, + 0x3C00, + 0x0400, /* Directly mapped */ + 0, 0, /* No segmentation */ + 1, /* Standard spacing */ + MAP_FBMEM_SIMPLE|MAP_FBMEM + }, + /* Tandy board */ + { + 0, + 0x80, /* I/O ports.. 80-83 + 8C-8E */ + 0, 0, /* Not mapped into main memory */ + 0, 0, /* No segmentation */ + 1, /* Standard spacing */ + MAP_PIO + }, + /* Microlabs */ + { + 0, + 0xFF, + 0x3C00, 0x0400, + 0, 0, + 1, + MAP_FBMEM|MAP_PIO + }, + /* HRG1B */ + { + 0, + 0x00, /* I/O ports.. 0-5 */ + 0, 0, /* Not mapped into main memory */ + 0, 0, /* No segmentation */ + 1, /* Standard spacing */ + MAP_PIO + }, }; static uint8_t vmode; +static uint8_t displaymap[2] = {0, 0}; +/* TODO: Arbitrate graphics between tty 1 and tty 2 */ int gfx_ioctl(uint8_t minor, uarg_t arg, char *ptr) { uint8_t m; - int err; if (minor > 2 || (arg >> 8 != 0x03)) return vt_ioctl(minor, arg, ptr); @@ -51,20 +126,64 @@ int gfx_ioctl(uint8_t minor, uarg_t arg, char *ptr) case GFXIOC_GETMODE: case GFXIOC_SETMODE: m = ugetc(ptr); - if (m != 0) + if (m > max_mode) break; + m = displaymap[m]; if (arg == GFXIOC_GETMODE) return uput(&trsdisplay[m], ptr, sizeof(struct display)); vmode = m; + /* Going back to text mode we need to turn off graphics cards. Going the + other way we let the applications handle it as they may want to do + memory wipes and the like first */ + if (vmode == 0) { + if (displaymap[1] == 1) + gfx_ctrl = 0; + else if (displaymap[1] == 2) + ioctrl = 0x20; + else if (displaymap[1] == 3) + hrg_off = 1; + } return 0; case GFXIOC_UNMAP: return 0; /* Users can "map" 8) the framebuffer into their process and use the card directly */ case GFXIOC_MAP: - if (vmode == 0) - break; - return uput(&trsmap, ptr, sizeof(trsmap)); + return uput(&trsmap[vmode], ptr, sizeof(struct videomap)); } return -1; } + +void gfx_init(void) +{ + if (trs80_model == TRS80_MODEL1 || trs80_model == VIDEOGENIE) { + /* HRG1B support. Might be good to also support 80-Grafix as a UDG + module */ + if (hrg_data != 0xFF) { /* We ought to test more carefully */ + max_mode = 1; + displaymap[1] = 3; + } + } else if (trs80_model == TRS80_MODEL3) { + /* The model 3 might have an 80-Grafix UDG card, or a Graphyx + or a Tandy card */ + if (gfx_data != 0xFF) { + max_mode = 1; + displaymap[1] = 1; + } else { + uint8_t *fb = 0x3C00; + uint8_t c = *fb; + *fb = 128; + ioctrl = 0xB2; + if (*fb != 128) { + /* Hopeful */ + *fb = 128; + if (*fb == 128) { /* 80 Grafix only has 6bit wide RAM but wants + the top bit set on writes.. */ + displaymap[1] = 2; + max_mode = 1; + } /* else add UDG support FIXME */ + } + *fb = c; + } + } +} diff --git a/Kernel/platform-trs80m1/devgfx.h b/Kernel/platform-trs80m1/devgfx.h index c29616d8..db1ac10f 100644 --- a/Kernel/platform-trs80m1/devgfx.h +++ b/Kernel/platform-trs80m1/devgfx.h @@ -4,9 +4,6 @@ #include extern int gfx_ioctl(uint8_t minor, uarg_t arg, char *ptr); -extern void video_cmd(uint8_t *ptr); -extern void video_read(uint8_t *ptr); -extern void video_write(uint8_t *ptr); -extern void video_exg(uint8_t *ptr); +extern void gfx_init(void); #endif diff --git a/Kernel/platform-trs80m1/discard.c b/Kernel/platform-trs80m1/discard.c index 2861247c..f51b7e72 100644 --- a/Kernel/platform-trs80m1/discard.c +++ b/Kernel/platform-trs80m1/discard.c @@ -3,6 +3,8 @@ #include #include #include +#include "devfd3.h" +#include "devgfx.h" void device_init(void) { @@ -12,6 +14,7 @@ void device_init(void) #endif floppy_setup(); hd_probe(); + gfx_init(); } void map_init(void) -- 2.34.1