1, 1, /* Need adding to ioctls */
FMT_MONO_BW,
HW_TRS80GFX,
- GFX_ENABLE|GFX_MAPPABLE|GFX_OFFSCREEN,
+ GFX_ENABLE|GFX_MAPPABLE|GFX_OFFSCREEN, /* Can in theory do pans */
32,
- GFX_SETPIXEL,
- 0
+ GFX_DRAW /* FIXME: do GFX_READ */
};
/* Assumes a Tandy board */
MAP_PIO
};
-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)
{
+ uint8_t *tmp;
+ uint16_t l;
+
if (arg >> 8 != 0x03)
return vt_ioctl(minor, arg, ptr);
+
switch(arg) {
case GFXIOC_GETINFO:
return uput(&trsdisplay, ptr, sizeof(trsdisplay));
card directly */
case GFXIOC_MAP:
return uput(&trsmap, ptr, sizeof(trsmap));
- 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();
+ case GFXIOC_DRAW:
+ 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);
+ brelse((bufptr) tmp);
return 0;
default:
udata.u_error = EINVAL;
return -1;
}
+bad:
+ udata.u_error = EINVAL;
+bad2:
+ brelse((bufptr) tmp);
+ return -1;
}
.globl _hd_page
; video
- .globl _video_setpixel
- .globl _video_op
- .globl _video_attr
+ .globl _video_cmd
; exported debugging tools
.globl _trap_monitor
;
; 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
+_video_cmd:
+ pop de
+ pop hl
+ push hl
+ push de
+ ld e,(hl) ; X byte, Y line
+ inc hl ; The hardware does the conversion
+ ld d,(hl) ; for us
+ ld a, #0x43 ; auto incremeent X on write only
+ out (0x83), a ; set the register up
+nextline:
+ push de
+ ld c, #0x80
+ out (c), e ; X
+ inc c
+ out (c), d ; Y
+nextop:
+ xor a
+ ld b, (hl)
+ cp b
+ jr z, endline
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)
+ ld c,(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)
+oploop:
+ in a, (0x82) ; read data
+ and c
+ xor (hl)
+ out (0x82), a ; autoincrements X
+ djnz oploop
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
+ jr nextop
+endline: pop de
+ 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