break;
case GFXIOC_WRITE:
case GFXIOC_READ:
+ case GFXIOC_EXG:
if (l < 8)
return EINVAL;
l -= 8;
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))
+ if (arg == GFXIOC_WRITE)
+ video_write(buf);
+ else {
+ if (arg == GFXIOC_READ)
+ video_read(buf);
+ else
+ video_exg(buf);
+ if (uput(buf + 10, ptr, l - 2))
return EFAULT;
return 0;
}
- video_write(buf);
}
return 0;
}
case GFXIOC_DRAW:
case GFXIOC_READ:
case GFXIOC_WRITE:
+ case GFXIOC_EXG:
if (vmode == 1) {
uint8_t *tmp = (uint8_t *)tmpbuf();
err = gfx_draw_op(arg, ptr, tmp);
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);
#endif
.globl _video_cmd
.globl _video_read
.globl _video_write
+ .globl _video_exg
; exported debugging tools
.globl _trap_monitor
ld (patch_io + 1), a
ld a, #0x13 ; autoincrement on read
jr video_do
+
+_video_exg: ; not quite worth self modifying
+ ld a, #0xB3 ; this one too
+ ld (patch_io + 1), a ; OTIR
+ ld a, #0x43
+ 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_ex:
+ ld c, #0x80
+ out (c), e ; x
+ inc c
+ out (c), d ; y
+ ld b, 4(iy) ; count of bytes per line
+ex_line:
+ in a, (0x82) ; faster than in a,(c)
+ ex af,af' ; icky but no free registers
+ ld a, (hl)
+ out (0x82), a ; write and inc
+ ex af, af
+ ld (hl), a
+ inc hl
+ djnz ex_line
+ inc d ; next line
+ dec 6(iy) ; height
+ jr nz, next_ex
+ ret