trs80: update for gfx changes
authorAlan Cox <alan@linux.intel.com>
Fri, 2 Oct 2015 20:00:47 +0000 (21:00 +0100)
committerAlan Cox <alan@linux.intel.com>
Fri, 2 Oct 2015 20:00:47 +0000 (21:00 +0100)
Kernel/platform-trs80/devgfx.c
Kernel/platform-trs80/trs80.s

index 6cb385b..603a4d5 100644 (file)
@@ -17,10 +17,9 @@ static const struct display trsdisplay = {
   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 */
@@ -33,16 +32,16 @@ static const struct videomap trsmap = {
   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));
@@ -57,15 +56,26 @@ int gfx_ioctl(uint8_t minor, uarg_t arg, char *ptr)
      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;
 }
index 4b7d5ce..114ff6c 100644 (file)
@@ -18,9 +18,7 @@
            .globl _hd_page
 
            ; video
-           .globl _video_setpixel
-           .globl _video_op
-           .globl _video_attr
+           .globl _video_cmd
 
             ; exported debugging tools
             .globl _trap_monitor
@@ -183,72 +181,42 @@ _hd_xfer_out:
 ;
 ;      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