From: Alan Cox Date: Sat, 3 Oct 2015 10:03:03 +0000 (+0100) Subject: trs80: update devgfx test code X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=8f97e439d0cc9046e9b3efb5e1456a1f494932d4;p=FUZIX.git trs80: update devgfx test code Correct for 16bit co-ordinates Add GFX_READ/WRITE test implementation --- diff --git a/Kernel/platform-trs80/devgfx.c b/Kernel/platform-trs80/devgfx.c index 603a4d51..07b9f90c 100644 --- a/Kernel/platform-trs80/devgfx.c +++ b/Kernel/platform-trs80/devgfx.c @@ -1,8 +1,8 @@ /* * 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 + * FIXME: - turn the gfx on/off when we switch tty + * - tie gfx to one tty and report EBUSY for the other on enable */ #include @@ -12,6 +12,7 @@ #include static const struct display trsdisplay = { + 0, 640, 240, 1024, 256, 1, 1, /* Need adding to ioctls */ @@ -19,7 +20,7 @@ static const struct display trsdisplay = { HW_TRS80GFX, GFX_ENABLE|GFX_MAPPABLE|GFX_OFFSCREEN, /* Can in theory do pans */ 32, - GFX_DRAW /* FIXME: do GFX_READ */ + GFX_DRAW|GFX_READ|GFX_WRITE }; /* Assumes a Tandy board */ @@ -34,10 +35,49 @@ static const struct videomap trsmap = { __sfr __at 0x83 gfx_ctrl; +static int gfx_draw_op(uarg_t arg, char *ptr, uint8_t *buf) +{ + int l; + int c = 8; /* 4 x uint16_t */ + uint16_t *p = (uint16_t *)buf; + l = ugetw(ptr); + if (l < 6 || l > 512) + return EINVAL; + if (arg != GFXIOC_READ) + c = l; + if (uget(buf, ptr + 2, c)) + return EFAULT; + switch(arg) { + case GFXIOC_DRAW: + /* TODO + if (draw_validate(ptr, l, 1024, 256)) + return EINVAL */ + video_cmd(buf); + break; + case GFXIOC_WRITE: + case GFXIOC_READ: + if (l < 8) + return EINVAL; + l -= 8; + if (p[0] > 128 || p[1] > 255 || p[2] > 128 || p[3] > 255 || + p[0] + p[2] > 128 || p[1] + p[3] > 255 || + (p[2] * p[3]) > l) + return -EFAULT; + if (arg == GFXIOC_READ) { + video_read(buf); + if (uput(buf + 8, ptr, l)) + return EFAULT; + return 0; + } + video_write(buf); + } + return 0; +} + int gfx_ioctl(uint8_t minor, uarg_t arg, char *ptr) { uint8_t *tmp; - uint16_t l; + int err; if (arg >> 8 != 0x03) return vt_ioctl(minor, arg, ptr); @@ -57,25 +97,18 @@ int gfx_ioctl(uint8_t minor, uarg_t arg, char *ptr) case GFXIOC_MAP: return uput(&trsmap, ptr, sizeof(trsmap)); case GFXIOC_DRAW: + case GFXIOC_READ: + case GFXIOC_WRITE: tmp = (uint8_t *)tmpbuf(); - l = ugetw(ptr); - if (l < 2 || l > 512) - goto bad; - if (uget(tmp, ptr + 2, l)) - goto bad2; - /* TODO - if (draw_validate(ptr, l, 1024, 256)) - goto bad; */ - video_cmd(tmp); + err = gfx_draw_op(arg, ptr, tmp); brelse((bufptr) tmp); - return 0; + if (err) { + udata.u_error = err; + err = -1; + } + return err; default: udata.u_error = EINVAL; return -1; } -bad: - udata.u_error = EINVAL; -bad2: - brelse((bufptr) tmp); - return -1; } diff --git a/Kernel/platform-trs80/trs80.s b/Kernel/platform-trs80/trs80.s index 114ff6c3..1719f1b3 100644 --- a/Kernel/platform-trs80/trs80.s +++ b/Kernel/platform-trs80/trs80.s @@ -19,6 +19,8 @@ ; video .globl _video_cmd + .globl _video_read + .globl _video_write ; exported debugging tools .globl _trap_monitor @@ -188,7 +190,10 @@ _video_cmd: push de ld e,(hl) ; X byte, Y line inc hl ; The hardware does the conversion + inc hl ld d,(hl) ; for us + inc hl ; skip high bytes + inc hl ld a, #0x43 ; auto incremeent X on write only out (0x83), a ; set the register up nextline: @@ -214,9 +219,45 @@ oploop: inc hl jr nextop endline: pop de - inc d ; down a scan line (easy peasy) + inc d ; down a scan line (easy peasy) inc hl xor a cp (hl) ; 0 0 = end (for blank lines just do 01 ff 00) jr nz, nextline ret + +_video_write: + ld a, #0xB3 + ld (patch_io + 1), a ; OTIR + ld a, #0x43 +video_do: + out (0x83), a ; autoincrement on write + pop de + pop iy + push iy + push de + push iy + pop hl + ld de, #8 + add hl, de ; Data start into HL + ld e, (iy) ; x + ld d, 2(iy) ; y +next_rw: + ld c, #0x80 + out (c), e ; x + inc c + out (c), d ; y + inc c ; to data + ld b, 4(iy) ; count of bytes per line +patch_io: + otir ; wheee... + inc d ; next line + dec 6(iy) ; height + jr nz, next_rw + ret + +_video_read: + ld a, #0xB2 ; inir + ld (patch_io + 1), a + ld a, #0x13 ; autoincrement on read + jr video_do