diff io.c @ 1:3c736a81b886

add disk
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 02 Jul 2018 19:07:39 +0900
parents 9a224bd9b45f
children 31d96e2b364e
line wrap: on
line diff
--- a/io.c	Mon Jul 02 02:12:31 2018 +0900
+++ b/io.c	Mon Jul 02 19:07:39 2018 +0900
@@ -34,6 +34,7 @@
 #include <unistd.h>
 #include <fcntl.h>
 #include <string.h>
+#include <time.h>
 
 #ifdef USE_TERMIOS
 #include <termios.h>
@@ -42,6 +43,29 @@
 #define engine extern
 #include "v09.h"
 
+/*
+ *      IO Map
+ *
+ *   0xe000 - 0xe100
+ *
+ *   0xe000   ACIA  control
+ *   0xe001   ACIA  data
+ *
+ *   0xe010   Timer control       0x8f start timer/0x80 stop timer/0x04 update date
+ *   0xe011-  YY/MM/DD/HH/MM/SS
+ *
+ *   0xe020   Disk control        0x81 read/0x55 write   0 ... ok / 0xff .. error
+ *   0xe021   drive no
+ *   0xe022   LSN2
+ *   0xe023   LSN1
+ *   0xe024   LSN0
+ *   0xe025   ADR2
+ *   0xe026   ADR1
+ *
+ */
+
+#define SECSIZE 256
+
 int tflags;
 int timer = 1;
 struct termios termsetting;
@@ -56,10 +80,13 @@
 FILE *logfile;
 FILE *infile;
 FILE *xfile;
+FILE *disk[] = {0,0};
 
 extern void hexadump( unsigned char *b, int l, int loc, int w);
 extern void disasm(int,int);
 
+void do_timer(int,int);
+void do_disk(int,int);
 
 int char_input(void) {
         int c, w, sum;
@@ -151,6 +178,10 @@
                         f = EOF;
                 }
                 return c;
+        } else if ((a&0xf0) == 0x10) { /* timer */
+                return mem[IOPAGE + a];
+        } else if ((a&0xf0) == 0x20) { /* disk */
+                return mem[IOPAGE + a];
         }
         return 0;
 }
@@ -203,6 +234,10 @@
                                 xidx = 0;
                         }
                 }
+        } else if ((a&0xf0) == 0x10) { /* timer */
+             do_timer(a,c);
+        } else if ((a&0xf0) == 0x20) { /* disk */
+             do_disk(a,c);
         }
 }
 
@@ -217,6 +252,54 @@
         exit(0);
 }
 
+void do_timer(int a, int c) {
+   struct itimerval timercontrol;
+   if (a==0x10 && c==0x8f) {
+        timercontrol.it_interval.tv_sec = 0;
+        timercontrol.it_interval.tv_usec = 20000;
+        timercontrol.it_value.tv_sec = 0;
+        timercontrol.it_value.tv_usec = 20000;
+        setitimer(ITIMER_REAL, &timercontrol, NULL);
+   } else if (a==0x10 && c==0x80) {
+        timercontrol.it_interval.tv_sec = 0;
+        timercontrol.it_interval.tv_usec = 0;
+        setitimer(ITIMER_REAL, &timercontrol, NULL);
+   } else if (a==0x10 && c==0x04) {
+      time_t tm = time(0);
+      struct tm *t = localtime(&tm);
+      mem[IOPAGE+0x11] = t->tm_year;
+      mem[IOPAGE+0x12] = t->tm_mon;
+      mem[IOPAGE+0x13] = t->tm_mday;
+      mem[IOPAGE+0x14] = t->tm_hour;
+      mem[IOPAGE+0x15] = t->tm_min;
+      mem[IOPAGE+0x16] = t->tm_sec;
+   } else {
+      mem[IOPAGE+a]=c;
+   }
+}
+
+void do_disk(int a, int c) {
+   if (a!=0x20) {
+      mem[IOPAGE+a]=c;
+      return;
+   }
+   int drv = mem[IOPAGE+0x21];
+   int lsn = (mem[IOPAGE+0x22]<<16) + (mem[IOPAGE+0x23]<<8) + mem[IOPAGE+0x24];
+   int buf = (mem[IOPAGE+0x25]<<8) + mem[IOPAGE+0x26];
+   if (drv > 1 || disk[drv]==0) goto error;
+   if (c==0x81) {
+      if (lseek(fileno(disk[drv]),lsn*SECSIZE,SEEK_SET)==-1) goto error;
+      if (read(fileno(disk[drv]),&mem[buf],SECSIZE)==-1) goto error;
+   } else if (c==0x55) {
+      if (lseek(fileno(disk[drv]),lsn*SECSIZE,SEEK_SET)==-1) goto error;
+      if (write(fileno(disk[drv]),&mem[buf],SECSIZE)==-1) goto error;
+   }
+   mem[IOPAGE+0x20] = 0;
+   return;
+error :
+   mem[IOPAGE+0x20] = 0xff;
+}
+
 typedef struct bp {
   int address;
   int count;
@@ -244,6 +327,8 @@
      "  c  [count] continue;\n"
      "  x  [adr]   dump\n"
      "  xi [adr]   disassemble\n"
+     "  0  file    disk drive 0 image\n"
+     "  1  file    disk drive 1 image\n"
      "  L  file    start log to file\n"
      "  S  file    set input file\n"
      "  X  exit\n"
@@ -374,7 +459,8 @@
                         fclose(logfile);
                 logfile = 0;
                 if (s[1]) {
-                        logfile = fopen(s + 1, "w");
+                        int i=1; while(s[i]==' ') i++;
+                        logfile = fopen(s + i, "w");
                 }
                 break;
         case 'S':
@@ -382,7 +468,8 @@
                         fclose(infile);
                 infile = 0;
                 if (s[1]) {
-                        infile = fopen(s + 1, "r");
+                        int i=1; while(s[i]==' ') i++;
+                        infile = fopen(s + i, "r");
                 }
                 break;
         case 'h':
@@ -399,12 +486,27 @@
                         xfile = 0;
                 }
                 break;
+        case '0':
+        case '1':
+                {   FILE **drv = &disk[ s[0]-'0'] ;
+                if (*drv)
+                        fclose(*drv);
+                *drv = 0;
+                if (s[1]) {
+                        int i=1; while(s[i]==' ') i++;
+                        *drv = fopen(s + i, "r+b");
+                        if ( *drv == 0 ) { printf("can't open %s\n", &s[i]); }
+                }
+                }
+                break;
         case 'U':
                 if (xfile)
                         fclose(xfile);
                 xfile = 0;
                 if (s[1]) {
-                        xfile = fopen(s + 1, "rb");
+                        int i=1; while(s[i]==' ') i++;
+                        xfile = fopen(s + i, "rb");
+                        if ( xfile == 0 ) { printf("can't open %s\n", &s[i]); }
                 }
                 if (xfile)
                         xmstat = 1;
@@ -420,7 +522,9 @@
                         fclose(xfile);
                 xfile = 0;
                 if (s[1]) {
-                        xfile = fopen(s + 1, "wb");
+                        int i=1; while(s[i]==' ') i++;
+                        xfile = fopen(s + i, "wb");
+                        if ( xfile == 0 ) { printf("can't open %s\n", &s[i]); }
                 }
                 if (xfile)
                         xmstat = 2;