trs80: test implementation of "exchange" operator
authorAlan Cox <alan@etchedpixels.co.uk>
Sun, 25 Oct 2015 14:13:15 +0000 (14:13 +0000)
committerAlan Cox <alan@etchedpixels.co.uk>
Sun, 25 Oct 2015 14:13:15 +0000 (14:13 +0000)
On the TRS80 at least it should be much faster than read/write

Kernel/platform-trs80/devgfx.c
Kernel/platform-trs80/devgfx.h
Kernel/platform-trs80/trs80.s

index 82ce21c..d803d8e 100644 (file)
@@ -73,6 +73,7 @@ static int gfx_draw_op(uarg_t arg, char *ptr, uint8_t *buf)
     break;
   case GFXIOC_WRITE:
   case GFXIOC_READ:
+  case GFXIOC_EXG:
     if (l < 8)
       return EINVAL;
     l -= 8;
@@ -80,13 +81,17 @@ static int gfx_draw_op(uarg_t arg, char *ptr, uint8_t *buf)
       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;
 }
@@ -123,6 +128,7 @@ int gfx_ioctl(uint8_t minor, uarg_t arg, char *ptr)
   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);
index d58afe7..c29616d 100644 (file)
@@ -7,5 +7,6 @@ extern int gfx_ioctl(uint8_t minor, uarg_t arg, char *ptr);
 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
index 52a9a8f..40f7178 100644 (file)
@@ -21,6 +21,7 @@
            .globl _video_cmd
            .globl _video_read
            .globl _video_write
+           .globl _video_exg
 
             ; exported debugging tools
             .globl _trap_monitor
@@ -267,3 +268,38 @@ _video_read:
            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