From 4728fdbfc8ea6174f4a5378daea26e6b22d3b539 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Tue, 31 Mar 2015 22:53:48 +0100 Subject: [PATCH] trs80: add initial prototype graphics card support --- Kernel/platform-trs80/Makefile | 2 +- Kernel/platform-trs80/devgfx.c | 56 +++++++++++++++++++++++ Kernel/platform-trs80/devices.c | 3 +- Kernel/platform-trs80/fuzix.lnk | 1 + Kernel/platform-trs80/trs80.s | 78 +++++++++++++++++++++++++++++++++ 5 files changed, 138 insertions(+), 2 deletions(-) create mode 100644 Kernel/platform-trs80/devgfx.c diff --git a/Kernel/platform-trs80/Makefile b/Kernel/platform-trs80/Makefile index d28ab0d9..82c1e02f 100644 --- a/Kernel/platform-trs80/Makefile +++ b/Kernel/platform-trs80/Makefile @@ -1,5 +1,5 @@ -CSRCS = devlpr.c devtty.c devfd.c devhd.c +CSRCS = devlpr.c devtty.c devfd.c devhd.c devgfx.c CSRCS += devices.c main.c DISCARD_CSRCS = discard.c devhd_discard.c diff --git a/Kernel/platform-trs80/devgfx.c b/Kernel/platform-trs80/devgfx.c new file mode 100644 index 00000000..b8ba5be1 --- /dev/null +++ b/Kernel/platform-trs80/devgfx.c @@ -0,0 +1,56 @@ +/* + * Graphics logic for the TRS80 graphics add on board + * + * FIXME: GETPIXEL, direct raw I/O access, scrolling, rects and + * aligned blit are probably the basic set we should go for + */ + +#include +#include +#include +#include +#include + +static struct display trsdisplay = { + 640, 240, + 1024, 256, + 1, 1, /* Need adding to ioctls */ + FMT_MONO_BW, + HW_UNACCEL, + GFX_ENABLE, + 32, + GFX_SETPIXEL, + 0 +}; + +uint16_t video_op[GFX_BUFLEN]; + +__sfr __at 0x83 gfx_ctrl; + +struct attribute video_attr; /* Shared with asm code */ + +int gfx_ioctl(uint8_t minor, uarg_t arg, char *ptr) +{ + if (arg >> 8 != 0x03) + return vt_ioctl(minor, arg, ptr); + switch(arg) { + case GFXIOC_GETINFO: + return uput(&trsdisplay, ptr, sizeof(trsdisplay)); + case GFXIOC_ENABLE: + gfx_ctrl = 3; /* we might want 1 for special cases */ + return 0; + case GFXIOC_DISABLE: + gfx_ctrl = 0; /* we might want 1 for special cases */ + return 0; + case GFXIOC_SETATTR: + return uget(&video_attr, ptr, sizeof(video_attr)); + case GFXIOC_SETPIXEL: + if (uget(&video_op, ptr, sizeof(video_op))) + return -1; + video_setpixel(); + return 0; + default: + udata.u_error = EINVAL; + return -1; + } +} diff --git a/Kernel/platform-trs80/devices.c b/Kernel/platform-trs80/devices.c index 6a9792dd..f633f8f4 100644 --- a/Kernel/platform-trs80/devices.c +++ b/Kernel/platform-trs80/devices.c @@ -8,6 +8,7 @@ #include #include #include +#include struct devsw dev_tab[] = /* The device driver switch table */ { @@ -16,7 +17,7 @@ struct devsw dev_tab[] = /* The device driver switch table */ /* 1: /dev/hd Hard disc block devices */ { hd_open, no_close, hd_read, hd_write, no_ioctl }, /* 2: /dev/tty TTY devices */ - { tty_open, trstty_close, tty_read, tty_write, vt_ioctl }, + { tty_open, trstty_close, tty_read, tty_write, gfx_ioctl }, /* 3: /dev/lpr Printer devices */ { lpr_open, lpr_close, no_rdwr, lpr_write, no_ioctl }, /* 4: /dev/mem etc System devices (one offs) */ diff --git a/Kernel/platform-trs80/fuzix.lnk b/Kernel/platform-trs80/fuzix.lnk index bca84f3d..210e6910 100644 --- a/Kernel/platform-trs80/fuzix.lnk +++ b/Kernel/platform-trs80/fuzix.lnk @@ -20,6 +20,7 @@ platform-trs80/devfd.rel platform-trs80/floppy.rel platform-trs80/devhd.rel platform-trs80/devhd_discard.rel +platform-trs80/devgfx.rel platform-trs80/devices.rel devio.rel filesys.rel diff --git a/Kernel/platform-trs80/trs80.s b/Kernel/platform-trs80/trs80.s index fc22d6d2..ae5ca7af 100644 --- a/Kernel/platform-trs80/trs80.s +++ b/Kernel/platform-trs80/trs80.s @@ -24,6 +24,11 @@ ; and the page from the C code .globl _hd_page + ; video + .globl _video_setpixel + .globl _video_op + .globl _video_attr + ; exported debugging tools .globl _trap_monitor .globl outchar @@ -275,3 +280,76 @@ _hd_xfer_out: otir call map_kernel ret + +; +; Graphics card +; +setpixel_optab: + nop ; + or b ; COPY + nop + or b ; SET + cpl ; complement pixel mask + and b ; CLEAR by anding with mask + nop + xor b ; INVERT +setpixel_bittab: + .db 128,64,32,16,8,4,2,1 + +_video_setpixel: + ld a, (_video_attr + 2) ; mode + or a ; copy ? + jr nz, setpixel_notdraw + ld a, (_video_attr) ; ink + or a ; white ? + jr nz, setpixel_notdraw ; a = 1 = set so good + ld a, #2 ; clear +setpixel_notdraw: + ld e, a + ld d, #0 + ld hl, #setpixel_optab + add hl, de + ld a, (hl) + ld (setpixel_opcode), a ; Self modifying + inc hl + ld a, (hl) + ld (setpixel_opcode), a ; Self modifying + ld bc, (_video_op) ; B is the count + ld a, b + and #0x1f ; max 31 pixels per op + ret z + push bc +setpixel_loop: + ld hl, #_video_op + 2 ; co-ordinate pairs + ld a, (hl) ; low bits of X + and #7 + ld c, a + ld a, (hl) + inc hl + ld b, (hl) ; high bits of X + srl b + rra + srl b + rra + srl b + rra + and #0x7F + out (0x80), a + ld a, (hl) ; y low (no y high needed) + inc hl + inc hl ; next point pair + push hl + out (0x81), a + ld hl, #setpixel_bittab + ld b, #0 + add hl, bc + ld b, (hl) ; our pixel mask + in a, (0x82) ; pixel from screen +setpixel_opcode: + nop ; nop or cpl + or b + out (0x82), a + pop hl + pop bc + djnz setpixel_loop + ret -- 2.34.1