trs80m1: initial (not yet working right) stringy support
authorAlan Cox <alan@linux.intel.com>
Wed, 4 Jul 2018 00:49:23 +0000 (01:49 +0100)
committerAlan Cox <alan@linux.intel.com>
Wed, 4 Jul 2018 00:49:23 +0000 (01:49 +0100)
Kernel/platform-trs80m1/devstringy.c
Kernel/platform-trs80m1/devstringy.h
Kernel/platform-trs80m1/discard.c
Kernel/platform-trs80m1/stringy.s

index a7c91db..4885618 100644 (file)
  *     Stringy tape wrapper. Note that the asm code uses the ROM which
  *     also uses some values in 0x40xx (40B1 and 401A in particular)
  */
-static uint8_t fileid = 255;
+static uint8_t fileid = 1;
 static uint8_t mode;
 static uint8_t inpos = 0;              /* in position */
 static uint8_t inio = 0;
+static uint8_t curtape = 255;
 static int busy = 0;
 uint8_t tape_err;
 
@@ -25,6 +26,9 @@ static int tape_error(void)
     /* EOF on read */
     if (a & 0x80)
         return 0;
+    /* Write protected */
+    if (a & 0x01)
+        udata.u_error = EROFS;
     /* BREAK */        
     if (a & 0x02)
         udata.u_error = EINTR;
@@ -37,6 +41,7 @@ static int tape_error(void)
     else
         udata.u_error = EIO;
     kprintf("tape: error %x\n", a);
+    inpos = inio = 0;
     return -1;
 }
 
@@ -54,6 +59,7 @@ static int tape_rewind(void)
 int tape_open(uint8_t minor, uint16_t flag)
 {
     minor; flag;
+    uint8_t unit;
 
     /* Check for the floppy tape ROM */
     if (*((uint16_t *)0x3034) != 0x3C3C) {
@@ -65,10 +71,13 @@ int tape_open(uint8_t minor, uint16_t flag)
         return -1;
     }
 
-    if (minor > 15 || tape_op(minor & 0x07, TAPE_SELECT)) {
+    unit = minor  & 7;
+
+    if (unit != curtape && tape_op(unit, TAPE_SELECT)) {
         udata.u_error = ENODEV;
         return -1;
     }
+
     /* Can't open for mixed read/write at the same time */
     if (O_ACCMODE(flag) == O_RDWR) {
         udata.u_error = EINVAL;
@@ -76,36 +85,51 @@ int tape_open(uint8_t minor, uint16_t flag)
     }
     mode = O_ACCMODE(flag);
 
-    if ((minor & 0x08) || fileid == 255)
+    if (minor & 0x08)
         if (tape_rewind())
             return -1;
     /* Only one drive can be used at a time */
     busy = 1;
-    inio = 0;
-    tape_err = 0;
+    if (unit != curtape) {
+        inio = 0;
+        tape_err = 0;
+        fileid = 1;
+        curtape = unit;
+    }
     return 0;
 }
 
 int tape_close(uint8_t minor)
 {
     minor;
+    busy = 0;
+    inio = 0;
     if (mode == O_WRONLY)
         if (tape_op(fileid, TAPE_CLOSEW))
             return tape_error();
+    if (fileid < 99)
+        fileid++;
     return 0;
 }
 
 static int tape_rw(uint8_t op)
 {
+    uint8_t pos = fileid;
+
     if (!inpos) {
-        if (tape_op(fileid, TAPE_FIND) == 0)
-            inpos = 1;
-        else 
-            return tape_error();
-            
+            pos--;
+            kprintf("find %d\n", pos);
+            if (!pos &&  tape_rewind() == 0)
+                inpos = 1;
+            else if (pos && tape_op(pos, TAPE_FIND) == 0)
+                inpos = 1;
+            else
+                return tape_error();
     }
+    kprintf("do tapeop %d %d\n", fileid, op);
     inio = 1;
     udata.u_done = tape_op(fileid, op);
+    kprintf("read %d\n", udata.u_done);
     if (tape_err)
         return tape_error();
     return udata.u_done;
@@ -130,7 +154,7 @@ int tape_write(uint8_t minor, uint8_t rawflag, uint8_t flag)
 static struct mtstatus tapei = {
     MT_TYPE_EXATRON,
     0,
-    ~0
+    ~0UL
 };
 
 int tape_ioctl(uint8_t minor, uarg_t op, char *ptr)
@@ -142,7 +166,7 @@ int tape_ioctl(uint8_t minor, uarg_t op, char *ptr)
             if (inpos)
                 tapei.mt_file = fileid;
             else
-                tapei.mt_file = ~0;
+                tapei.mt_file = 0xFFFF;
             return uput(&tapei, ptr, sizeof(tapei));
     }
     /* Now calls we can only make when not mid stream */
@@ -183,3 +207,8 @@ bad:
     udata.u_error = EINVAL;
     return -1;
 }
+
+void tape_init(void)
+{
+    *(uint16_t*)0x40b1 = 0x4000;       /* Somewhere to put the tape variables */
+}
index d79cf45..6fd066d 100644 (file)
@@ -14,8 +14,7 @@ extern int tape_write(uint8_t minor, uint8_t rawflag, uint8_t flag);
 extern int tape_ioctl(uint8_t minor, uarg_t op, char *ptr);
 extern int tape_open(uint8_t minor, uint16_t flag);
 extern int tape_close(uint8_t minor);
+extern void tape_init(void);
 
 extern int tape_op(uint8_t id, uint8_t op);
 
-
-
index f51b7e7..f80f909 100644 (file)
@@ -15,6 +15,7 @@ void device_init(void)
   floppy_setup();
   hd_probe();
   gfx_init();
+  tape_init();
 }
 
 void map_init(void)
index eb3a95f..7ab58b4 100644 (file)
        .globl go_slow
        .globl go_fast
 
+       .globl map_process_always
+       .globl map_kernel_restore
+
 _tape_op:
        call go_slow
-       pop bc
-       pop de
-       push de         ; file ID in D op in E
-       push bc
-       ld hl,(U_DATA__U_BASE)
-       ld bc,(U_DATA__U_COUNT)
+       call map_process_always
+       call do_tape_op
+       push af
+       call map_kernel_restore
+       call go_fast
+       pop af
+       ret
+
+do_tape_op:
        xor a
        ld (_tape_err),a
-       ld a,e
+
+       ld hl,#6                ; SP + 6
+       add hl,sp
+       ld d,(hl)
+       inc hl
+       ld a,(hl)
+
+       ld hl,(U_DATA__U_BASE)
+       ld bc,(U_DATA__U_COUNT)
        or a
        jr z, write_op
        dec a
@@ -39,7 +53,6 @@ _tape_op:
        dec a
        jr z, erase_op
        ld hl,#0xFFFF
-       call go_fast
        ret
 find_op:
        ld a,d
@@ -53,9 +66,6 @@ seekf_op:
        ld a,d
        call 0x300F             ; find file A
 tape_error:
-       push af
-       call go_fast
-       pop af
        ld hl,#0                ; return 0 if good or -1 if bad and save err
        ret z
        dec hl
@@ -71,9 +81,6 @@ rewind_op:
        jr tape_error           ; file 0 itself)
 read_op:
        call 0x3003
-       push af
-       call go_fast
-       pop af
        ld h,b
        ld l,c                  ; actual bytes fetched
        ret z
@@ -83,9 +90,6 @@ rwerr:
        ret
 write_op:
        call 0x3006
-       push af
-       call go_fast
-       pop af
        ld hl,(U_DATA__U_COUNT)
        ret z
        jr rwerr