-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
--- /dev/null
+/*
+ * 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 <kernel.h>
+#include <kdata.h>
+#include <vt.h>
+#include <graphics.h>
+#include <devgfx.h>
+
+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;
+ }
+}
#include <devlpr.h>
#include <vt.h>
#include <devtty.h>
+#include <devgfx.h>
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) */
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
; 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
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