changeset 20:49fac9474858

separate trace file
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 09 Jul 2018 09:29:33 +0900
parents 84b28178c82f
children 1925cfa982fe
files Makefile io.c os9/Makefile os9/level2/Makefile os9/level2/d0.asm os9/level2/d1.asm trace.c v09.c
diffstat 8 files changed, 370 insertions(+), 302 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile	Mon Jul 09 01:59:17 2018 +0900
+++ b/Makefile	Mon Jul 09 09:29:33 2018 +0900
@@ -20,7 +20,7 @@
 APPS=mon2.s
 
 # will be installed to ".."
-BIN=a09 v09 $(SIM_BIN) v09.rom
+BIN=a09 v09 v09c $(SIM_BIN) v09.rom
 
 TARGETS=$(BIN) $(APPS)
 
@@ -32,11 +32,12 @@
 
 a09: a09.c os9crc.c
 
-v09: v09.o engine.o io.o os9disass.o
-	$(CC) -o v09 $(CFLAGS) v09.o engine.o io.o os9disass.o
+v09: v09.o engine.o io.o os9disass.o trace.o
+	$(CC) -o v09 $(CFLAGS) v09.o engine.o io.o os9disass.o trace.o
 
-v09c: v09.c engine.c io.c os9disass.o
-	$(CC) -o v09c $(CFLAGS) $(V09FLAGS) -DIOPAGE=0xff80 -DUSE_MMU=1 v09.c engine.c io.c os9disass.o
+# with Coco MMU 
+v09c: v09.c engine.c io.c os9disass.o trace.o
+	$(CC) -o v09c $(CFLAGS) $(V09FLAGS) -DIOPAGE=0xff80 -DUSE_MMU=1 v09.c engine.c io.c os9disass.o trace.o
 
 v09.o: v09.c v09.h
 	$(CC) -c $(CFLAGS) $(V09FLAGS) v09.c
@@ -50,6 +51,9 @@
 io.o: io.c v09.h
 	$(CC) -c $(CFLAGS) $(V09FLAGS) io.c
 
+trace.o: trace.c v09.h
+	$(CC) -c $(CFLAGS) $(V09FLAGS) trace.c
+
 v09.rom: makerom monitor.s 
 	./makerom <monitor.s
 
@@ -83,8 +87,10 @@
 	rm -f $(TARGETS) $(OTHER)
 	(cd ..; rm -f $(BIN) )
 
+realclean: cleanall
+
 clean:
-	rm -f core *.BAK *.o *.lst
+	rm -rf core *.BAK *.o *.lst *.dSYM
 
 # ------------------------------------
 
--- a/io.c	Mon Jul 09 01:59:17 2018 +0900
+++ b/io.c	Mon Jul 09 09:29:33 2018 +0900
@@ -84,7 +84,10 @@
 
 int timer = 1;
 struct termios termsetting;
+struct termios newterm;
+struct itimerval timercontrol;
 
+int tflags;
 int xmstat; /* 0= no XMODEM transfer, 1=send, 2=receiver */
 unsigned char xmbuf[132];
 int xidx;
@@ -92,18 +95,19 @@
 int rcvdnak;
 int blocknum;
 
-FILE *logfile;
 FILE *infile;
 FILE *xfile;
+FILE *logfile;
 FILE *disk[] = {0,0};
 
-extern void hexadump( unsigned char *b, int l, int loc, int w);
-extern int disasm(int,int);
 #ifdef USE_MMU
 extern char *prog ;   // for disass
 extern Byte * mem0(Byte *iphymem, Word adr, Byte *immu) ;
 #endif
 
+extern int bpskip ;
+extern int stkskip ;
+extern FILE *logfile;
 
 void do_timer(int,int);
 void do_disk(int,int);
@@ -262,16 +266,6 @@
         }
 }
 
-void restore_term(void) {
-        tcsetattr(0, TCSAFLUSH, &termsetting);
-        fcntl(0, F_SETFL, tflags);
-        signal(SIGALRM, SIG_IGN);
-}
-
-void do_exit(void) {
-        restore_term();
-        exit(0);
-}
 
 void do_timer(int a, int c) {
    struct itimerval timercontrol;
@@ -336,281 +330,6 @@
 #endif 
 }
 
-typedef struct bp {
-  int address;
-  int count;
-  struct bp *next;
-} BP, *BPTR;
-
-BPTR breakpoint = 0;
-int bpskip = 0;
-int trskip = 0;
-int stkskip = 0;
-
-int getarg(char *buf, char** next) {
-        return strtol(buf,(char**)next,0);
-}
-
-void printhelp(void)
-{
-  printf( 
-     "  s [count]  one step trace\n"
-     "  n          step over\n"
-     "  f          finish this call (until stack pop)\n"
-     "  b [adr]    set break point\n"
-     "  l          break point list\n"
-     "  d [n]      delte break point list\n"
-     "  c  [count] continue;\n"
-     "  x  [adr]   dump\n"
-#ifdef USE_MMU
-     "  xp [adr]   dump physical memory\n"
-#endif
-     "  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"
-     "  q  exit\n"
-     "  U  file    upload from srecord file \n"
-     "  D  file    download to srecord file \n"
-     "  R  do reset\n"
-     "  h,?  print this\n"
-    );
-}
-
-void do_escape(void) {
-        char s[80];
-        int adr,skip;
-        if (bpskip) { // skip unbreak instruction
-            bpskip--;
-            for(BPTR b = breakpoint; b ; b=b->next) {
-                if (pcreg==b->address) {
-                    if (b->count) b->count--;
-                    if (b->count==0) {
-                        goto restart0;
-                    }
-                }
-            }
-            return;
-        }
-        if (stkskip) { // skip until return
-           if (sreg < stkskip ) return;
-        }
-restart0:
-        stkskip = 0;
-        restore_term();
-#ifdef USE_MMU
-        Byte *phyadr = mem0(phymem,pcreg,mmu);
-        prog = (char*)phyadr - pcreg;
-#endif
-        do_trace(stdout);
-        if (trskip>1) { // show trace and step
-            trskip--;
-            set_term(escchar);
-            return; 
-        }
-restart:
-        printf("v09>");
-        fgets(s, 80, stdin);
-        if (s[0])
-                s[strlen(s) - 1] = 0;
-        switch (s[0]) {
-        case 's':   // one step trace
-                trskip = 1;
-                if (s[1]) {
-                   trskip = getarg(s+1,0);
-                }
-                bpskip = 0;
-                attention = escape = 1;
-                break;
-        case 'n':   // step over
-                stkskip = sreg;
-                attention = escape = 1;
-                break;
-        case 'f':   // finish this call (until stack pop)
-                stkskip = sreg + 2;
-                attention = escape = 1;
-                break;
-        case 'b':   // set break point
-                {
-                  BPTR bp = calloc(1,sizeof(BP));
-                  bp->next = breakpoint;
-                  breakpoint = bp;
-                  bp->count = 1;
-                  if (s[1]) {
-                     char *next;
-                     bp->address = getarg(s+1,&next);
-                     if (next[0]) {
-                         bp->count = getarg(next,&next);
-                     }
-                  } else {
-                     bp->address = pcreg;
-                  }
-                }
-                bpskip = -1;
-                goto restart;
-        case 'l':   // break point list
-                for(BPTR bp = breakpoint; bp ; bp = bp->next) {
-                    printf("%x %i\n", bp->address, bp->count);
-                }
-                goto restart;
-        case 'd':   // delte break point list
-                if (s[1]) {
-                   int trskip = getarg(s+1,0);
-                   BPTR *prev = &breakpoint;
-                   for(BPTR bp = breakpoint; bp ; bp = bp->next) {
-                       if (trskip-- == 0) {
-                          if (bp) {
-                              *prev = bp->next;
-                          }
-                          break;
-                       }
-                       prev = &bp->next;
-                   }
-                }
-                goto restart;
-        case 'c':   // continue;
-                bpskip = -1;
-                attention = escape = 1;
-                if (s[1]) {
-                   bpskip = getarg(s+1,0);
-                }
-                break;
-        case 'x':   // dump
-                skip = 1;
-                if (s[1]=='i') skip=2;
-                if (s[1]=='p') skip=2;
-                if (s[skip]) {
-                   char *next;
-                   int adr = getarg(s+skip,&next);
-                   int len = 32;
-                   if (next[0]) {
-                      len =  getarg(next,&next);
-                   }
-                   if (skip==2 && s[1]=='i') {
-                     Word end = adr + len;
-                     while(adr < end) {
-#ifdef USE_MMU
-                        Byte *phyadr = mem0(phymem,adr,mmu);
-                        prog = (char*)phyadr - adr  ;
-                        if (phyadr > phymem+memsize) goto restart;
-#endif
-                        int len = adr+16<end? 16 : end-adr -1 ;
-                        adr = disasm(adr,adr+len);
-                      }
-                   } else {
-#ifdef USE_MMU
-                     for(int i=0; len > 0 ; i+=16, len-=16) {
-                        if (skip==2 && s[1]=='p') {
-                            if (adr+i > memsize) goto restart;
-                            hexadump(phymem+adr+i,len>16?16:len,adr+i,16);
-                        } else {
-                            Byte *phyadr = mem0(phymem,adr+i,mmu);
-                            if (phyadr > phymem+memsize) goto restart;
-                            hexadump(phyadr,len>16?16:len,adr+i,16);
-                        }
-                     }
-#else
-                     for(int i=0; len > 0 ; i+=16, len-=16) {
-                        hexadump(mem+adr+i,len>16?16:len,adr+i,16);
-                     }
-#endif
-                   }
-                } else 
-                   disasm(pcreg,pcreg+32);
-                goto restart;
-        case 'L':
-                if (logfile)
-                        fclose(logfile);
-                logfile = 0;
-                if (s[1]) {
-                        int i=1; while(s[i]==' ') i++;
-                        logfile = fopen(s + i, "w");
-                }
-                break;
-        case 'S':
-                if (infile)
-                        fclose(infile);
-                infile = 0;
-                if (s[1]) {
-                        int i=1; while(s[i]==' ') i++;
-                        infile = fopen(s + i, "r");
-                }
-                break;
-        case 'h':
-        case '?':
-                printhelp();
-                goto restart;
-        case 'X':
-        case 'q':
-                if (!xmstat)
-                        do_exit();
-                else {
-                        xmstat = 0;
-                        fclose(xfile);
-                        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]) {
-                        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;
-                else
-                        xmstat = 0;
-                xidx = 0;
-                acknak = 21;
-                rcvdnak = EOF;
-                blocknum = 1;
-                break;
-        case 'D':
-                if (xfile)
-                        fclose(xfile);
-                xfile = 0;
-                if (s[1]) {
-                        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;
-                else
-                        xmstat = 0;
-                xidx = 0;
-                acknak = 21;
-                blocknum = 1;
-                break;
-        case 'R':
-                pcreg = (mem[0xfffe] << 8) + mem[0xffff];
-                bpskip = 0;
-                attention = escape = 1;
-                break;
-        }
-        if (tracing||breakpoint||trskip||bpskip||stkskip) { attention = escape = 1; }
-        else attention = 0;
-        set_term(escchar);
-}
-
 void timehandler(int sig) {
         attention = 1;
         irq = 2;
@@ -624,14 +343,16 @@
         stkskip = 0;
 }
 
+void init_term(void) {
+        tcgetattr(0, &termsetting);
+        tflags = fcntl(0, F_GETFL, 0);
+}
+
 void set_term(char c) {
-        struct termios newterm;
-        struct itimerval timercontrol;
         signal(SIGQUIT, SIG_IGN);
         signal(SIGTSTP, SIG_IGN);
         signal(SIGINT, handler);
         signal(SIGUSR1, handler);
-        tcgetattr(0, &termsetting);
         newterm = termsetting;
         newterm.c_iflag = newterm.c_iflag & ~INLCR & ~ICRNL;
         newterm.c_lflag = newterm.c_lflag & ~ECHO & ~ICANON;
@@ -639,7 +360,6 @@
         newterm.c_cc[VMIN] = 1;
         newterm.c_cc[VINTR] = escchar;
         tcsetattr(0, TCSAFLUSH, &newterm);
-        tflags = fcntl(0, F_GETFL, 0);
         fcntl(0, F_SETFL, tflags | O_NDELAY); /* Make input from stdin non-blocking */
         signal(SIGALRM, timehandler);
         timercontrol.it_interval.tv_sec = 0;
@@ -649,3 +369,13 @@
         if (timer)
             setitimer(ITIMER_REAL, &timercontrol, NULL);
 }
+
+void restore_term(void) {
+        tcsetattr(0, TCSAFLUSH, &termsetting);
+        fcntl(0, F_SETFL, tflags);
+        signal(SIGALRM, SIG_IGN);
+}
+
+
+
+
--- a/os9/Makefile	Mon Jul 09 01:59:17 2018 +0900
+++ b/os9/Makefile	Mon Jul 09 09:29:33 2018 +0900
@@ -25,4 +25,4 @@
 	./makerom -o os9d.rom  modules/Shell modules/init.b modules/mdir modules/dir.b modules/SysGo modules/IOMan modules/pty-dd.b modules/pty.b modules/pdisk.b modules/d0.b modules/d1.b modules/clock.b modules/SCF modules/rbf.b modules/OS9p2 modules/OS9
    
 os9lv2.rom : makerom level2/init
-	./makerom -o os9lv2.rom -2  level2/Shell  level2/mdir  level2/d0 level2/d1 level2/ioman  level2/os9p3_perr level2/os9p4_regdump  level2/pipe level2/piper level2/pipeman  level2/scf level2/rbf level2/os9p2 level2/sysgo level2/pdisk level2/pty level2/term level2/init level2/boot level2/os9p1 
+	./makerom -o os9lv2.rom -2  level2/Shell  level2/dir  level2/d0 level2/d1 level2/ioman  level2/os9p3_perr level2/os9p4_regdump  level2/pipe level2/piper level2/pipeman  level2/scf level2/rbf level2/os9p2 level2/sysgo level2/pdisk level2/pty level2/term level2/init level2/boot level2/os9p1 
--- a/os9/level2/Makefile	Mon Jul 09 01:59:17 2018 +0900
+++ b/os9/level2/Makefile	Mon Jul 09 09:29:33 2018 +0900
@@ -10,7 +10,8 @@
 	rm -f ioman pdisk init os9p1 os9p2 os9p3_perr os9p4_regdump pipe pipeman pipeman_named piper rbf scf term pty d0 d1 clock vector boot shell dir mdir
 
 pdisk : 
-	$(A09) ../modules/pdisk.asm -o pdisk
+	$(A09) pdisk.asm -o pdisk
+#	$(A09) ../modules/pdisk.asm -o pdisk
 
 boot : boot.asm
 	$(A09) boot.asm -o boot
--- a/os9/level2/d0.asm	Mon Jul 09 01:59:17 2018 +0900
+++ b/os9/level2/d0.asm	Mon Jul 09 09:29:33 2018 +0900
@@ -25,7 +25,7 @@
          mod   eom,name,tylg,atrv,mgrnam,drvnam
          fcb   $FF mode byte
          fcb   $00  extended controller address
-         fdb   $f8c0  physical controller address
+         fdb   $ffc0  physical controller address
          fcb   initsize-*-1  initilization table size
          fcb   $01 device type:0=scf,1=rbf,2=pipe,3=scf
          fcb   $00 drive number
--- a/os9/level2/d1.asm	Mon Jul 09 01:59:17 2018 +0900
+++ b/os9/level2/d1.asm	Mon Jul 09 09:29:33 2018 +0900
@@ -25,7 +25,7 @@
          mod   eom,name,tylg,atrv,mgrnam,drvnam
          fcb   $FF mode byte
          fcb   $00  extended controller address
-         fdb   $f8c0  physical controller address
+         fdb   $ffc0  physical controller address
          fcb   initsize-*-1  initilization table size
          fcb   $01 device type:0=scf,1=rbf,2=pipe,3=scf
          fcb   $01 drive number
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/trace.c	Mon Jul 09 09:29:33 2018 +0900
@@ -0,0 +1,328 @@
+/* 6808 Simulator V092
+ *
+ * tracer
+
+*/
+
+#include<stdio.h>
+#include<stdlib.h>
+#include<ctype.h>
+#include<signal.h>
+#include<sys/time.h>
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <time.h>
+
+#ifdef USE_TERMIOS
+#include <termios.h>
+#endif
+
+#define engine extern
+#include "v09.h"
+
+struct termios termsetting;
+
+int xmstat; /* 0= no XMODEM transfer, 1=send, 2=receiver */
+unsigned char xmbuf[132];
+int xidx;
+int acknak;
+int rcvdnak;
+int blocknum;
+
+extern FILE *logfile;
+extern FILE *infile;
+extern FILE *xfile;
+extern FILE *disk[];
+
+extern void hexadump( unsigned char *b, int l, int loc, int w);
+extern int disasm(int,int);
+extern void restore_term(void) ;
+
+#ifdef USE_MMU
+extern char *prog ;   // for disass
+extern Byte * mem0(Byte *iphymem, Word adr, Byte *immu) ;
+#endif
+
+void do_exit(void) {
+        restore_term();
+        exit(0);
+}
+
+
+typedef struct bp {
+  int address;
+  int count;
+  struct bp *next;
+} BP, *BPTR;
+
+BPTR breakpoint = 0;
+int bpskip = 0;
+int trskip = 0;
+int stkskip = 0;
+
+int getarg(char *buf, char** next) {
+        return strtol(buf,(char**)next,0);
+}
+
+void printhelp(void)
+{
+  printf( 
+     "  s [count]  one step trace\n"
+     "  n          step over\n"
+     "  f          finish this call (until stack pop)\n"
+     "  b [adr]    set break point\n"
+     "  l          break point list\n"
+     "  d [n]      delte break point list\n"
+     "  c  [count] continue;\n"
+     "  x  [adr]   dump\n"
+#ifdef USE_MMU
+     "  xp [adr]   dump physical memory\n"
+#endif
+     "  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"
+     "  q  exit\n"
+     "  U  file    upload from srecord file \n"
+     "  D  file    download to srecord file \n"
+     "  R  do reset\n"
+     "  h,?  print this\n"
+    );
+}
+
+void do_escape(void) {
+        char s[80];
+        int adr,skip;
+        if (bpskip) { // skip unbreak instruction
+            bpskip--;
+            for(BPTR b = breakpoint; b ; b=b->next) {
+                if (pcreg==b->address) {
+                    if (b->count) b->count--;
+                    if (b->count==0) {
+                        goto restart0;
+                    }
+                }
+            }
+            return;
+        }
+        if (stkskip) { // skip until return
+           if (sreg < stkskip ) return;
+        }
+restart0:
+        stkskip = 0;
+        restore_term();
+#ifdef USE_MMU
+        Byte *phyadr = mem0(phymem,pcreg,mmu);
+        prog = (char*)phyadr - pcreg;
+#endif
+        do_trace(stdout);
+        if (trskip>1) { // show trace and step
+            trskip--;
+            set_term(escchar);
+            return; 
+        }
+restart:
+        printf("v09>");
+        fgets(s, 80, stdin);
+        if (s[0])
+                s[strlen(s) - 1] = 0;
+        switch (s[0]) {
+        case 's':   // one step trace
+                trskip = 1;
+                if (s[1]) {
+                   trskip = getarg(s+1,0);
+                }
+                bpskip = 0;
+                attention = escape = 1;
+                break;
+        case 'n':   // step over
+                stkskip = sreg;
+                attention = escape = 1;
+                break;
+        case 'f':   // finish this call (until stack pop)
+                stkskip = sreg + 2;
+                attention = escape = 1;
+                break;
+        case 'b':   // set break point
+                {
+                  BPTR bp = calloc(1,sizeof(BP));
+                  bp->next = breakpoint;
+                  breakpoint = bp;
+                  bp->count = 1;
+                  if (s[1]) {
+                     char *next;
+                     bp->address = getarg(s+1,&next);
+                     if (next[0]) {
+                         bp->count = getarg(next,&next);
+                     }
+                  } else {
+                     bp->address = pcreg;
+                  }
+                }
+                bpskip = -1;
+                goto restart;
+        case 'l':   // break point list
+                for(BPTR bp = breakpoint; bp ; bp = bp->next) {
+                    printf("%x %i\n", bp->address, bp->count);
+                }
+                goto restart;
+        case 'd':   // delte break point list
+                if (s[1]) {
+                   int trskip = getarg(s+1,0);
+                   BPTR *prev = &breakpoint;
+                   for(BPTR bp = breakpoint; bp ; bp = bp->next) {
+                       if (trskip-- == 0) {
+                          if (bp) {
+                              *prev = bp->next;
+                          }
+                          break;
+                       }
+                       prev = &bp->next;
+                   }
+                }
+                goto restart;
+        case 'c':   // continue;
+                bpskip = -1;
+                attention = escape = 1;
+                if (s[1]) {
+                   bpskip = getarg(s+1,0);
+                }
+                break;
+        case 'x':   // dump
+                skip = 1;
+                if (s[1]=='i') skip=2;
+                if (s[1]=='p') skip=2;
+                if (s[skip]) {
+                   char *next;
+                   int adr = getarg(s+skip,&next);
+                   int len = 32;
+                   if (next[0]) {
+                      len =  getarg(next,&next);
+                   }
+                   if (skip==2 && s[1]=='i') {
+                     Word end = adr + len;
+                     while(adr < end) {
+#ifdef USE_MMU
+                        Byte *phyadr = mem0(phymem,adr,mmu);
+                        prog = (char*)phyadr - adr  ;
+                        if (phyadr > phymem+memsize) goto restart;
+#endif
+                        int len = adr+16<end? 16 : end-adr -1 ;
+                        adr = disasm(adr,adr+len);
+                      }
+                   } else {
+#ifdef USE_MMU
+                     for(int i=0; len > 0 ; i+=16, len-=16) {
+                        if (skip==2 && s[1]=='p') {
+                            if (adr+i > memsize) goto restart;
+                            hexadump(phymem+adr+i,len>16?16:len,adr+i,16);
+                        } else {
+                            Byte *phyadr = mem0(phymem,adr+i,mmu);
+                            if (phyadr > phymem+memsize) goto restart;
+                            hexadump(phyadr,len>16?16:len,adr+i,16);
+                        }
+                     }
+#else
+                     for(int i=0; len > 0 ; i+=16, len-=16) {
+                        hexadump(mem+adr+i,len>16?16:len,adr+i,16);
+                     }
+#endif
+                   }
+                } else 
+                   disasm(pcreg,pcreg+32);
+                goto restart;
+        case 'L':
+                if (logfile)
+                        fclose(logfile);
+                logfile = 0;
+                if (s[1]) {
+                        int i=1; while(s[i]==' ') i++;
+                        logfile = fopen(s + i, "w");
+                }
+                break;
+        case 'S':
+                if (infile)
+                        fclose(infile);
+                infile = 0;
+                if (s[1]) {
+                        int i=1; while(s[i]==' ') i++;
+                        infile = fopen(s + i, "r");
+                }
+                break;
+        case 'h':
+        case '?':
+                printhelp();
+                goto restart;
+        case 'X':
+        case 'q':
+                if (!xmstat)
+                        do_exit();
+                else {
+                        xmstat = 0;
+                        fclose(xfile);
+                        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]) {
+                        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;
+                else
+                        xmstat = 0;
+                xidx = 0;
+                acknak = 21;
+                rcvdnak = EOF;
+                blocknum = 1;
+                break;
+        case 'D':
+                if (xfile)
+                        fclose(xfile);
+                xfile = 0;
+                if (s[1]) {
+                        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;
+                else
+                        xmstat = 0;
+                xidx = 0;
+                acknak = 21;
+                blocknum = 1;
+                break;
+        case 'R':
+                pcreg = (mem[0xfffe] << 8) + mem[0xffff];
+                bpskip = 0;
+                attention = escape = 1;
+                break;
+        }
+        if (tracing||breakpoint||trskip||bpskip||stkskip) { attention = escape = 1; }
+        else attention = 0;
+        set_term(escchar);
+}
+
--- a/v09.c	Mon Jul 09 01:59:17 2018 +0900
+++ b/v09.c	Mon Jul 09 09:29:33 2018 +0900
@@ -43,6 +43,8 @@
 extern char *prog;    // for disasm
 extern void disasm(int,int);
 extern void do_mmu(Word,Byte);
+extern void init_term(void) ;
+
 
 void do_trace(FILE *tracefile)
 {
@@ -164,6 +166,7 @@
  } 
  #endif
  read_image(); 
+ init_term();
  if (setterm) set_term(escchar);
  pcreg=(mem[0xfffe]<<8)+mem[0xffff]; 
  prog = (char*)mem;  // for disasm