changeset 4:6159cc57d44e

on going ...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Wed, 04 Jul 2018 19:33:22 +0900
parents 831ac057ea86
children 35028b396a35
files engine.c io.c v09.c v09.h
diffstat 4 files changed, 214 insertions(+), 162 deletions(-) [+]
line wrap: on
line diff
--- a/engine.c	Wed Jul 04 14:03:56 2018 +0900
+++ b/engine.c	Wed Jul 04 19:33:22 2018 +0900
@@ -39,23 +39,31 @@
 static int tracetrick=0;
 extern int romstart;
 
-#define GETWORD(a) (mem[a]<<8|mem[(a)+1])
-#define SETBYTE(a,n) {if(!(a>=romstart))mem[a]=n;}
-#define SETWORD(a,n) if(!(a>=romstart)){mem[a]=(n)>>8;mem[(a)+1]=n;}
+#ifdef USE_MMU
+inline Byte * mem0(Word adr, Byte *immu) { return & iphymem[ ( immu[ (adr) >> 13 ] <<13 ) + ((adr) & 0x1fff )] }
+#define mem(adr) mem0(adr,immu)
+#else
+#define mem(adr) mem[adr]
+#endif
+
+
+#define GETWORD(a) (mem(a)<<8|mem((a)+1))
+#define SETBYTE(a,n) {if(!(a>=romstart))mem(a)=n;}
+#define SETWORD(a,n) if(!(a>=romstart)){mem(a)=(n)>>8;mem((a)+1)=n;}
 /* Two bytes of a word are fetched separately because of
    the possible wrap-around at address $ffff and alignment
 */
 
-#define IMMBYTE(b) b=mem[ipcreg++];
+#define IMMBYTE(b) b=mem(ipcreg++);
 #define IMMWORD(w) {w=GETWORD(ipcreg);ipcreg+=2;}
 
 #define PUSHBYTE(b) {--isreg;SETBYTE(isreg,b)}
 #define PUSHWORD(w) {isreg-=2;SETWORD(isreg,w)}
-#define PULLBYTE(b) b=mem[isreg++];
+#define PULLBYTE(b) b=mem(isreg++);
 #define PULLWORD(w) {w=GETWORD(isreg);isreg+=2;}
 #define PSHUBYTE(b) {--iureg;SETBYTE(iureg,b)}
 #define PSHUWORD(w) {iureg-=2;SETWORD(iureg,w)}
-#define PULUBYTE(b) b=mem[iureg++];
+#define PULUBYTE(b) b=mem(iureg++);
 #define PULUWORD(w) {w=GETWORD(iureg);iureg+=2;}
 
 #define SIGNED(b) ((Word)(b&0x80?b|0xff00:b))
@@ -125,7 +133,7 @@
 
 /* Macros for load and store of accumulators. Can be modified to check
    for port addresses */
-#define LOADAC(reg) if((eaddr&0xff00)!=IOPAGE)reg=mem[eaddr];else\
+#define LOADAC(reg) if((eaddr&0xff00)!=IOPAGE)reg=mem(eaddr);else\
            reg=do_input(eaddr&0xff);
 #define STOREAC(reg) if((eaddr&0xff00)!=IOPAGE)SETBYTE(eaddr,reg)else\
 	   do_output(eaddr&0xff,reg);
@@ -134,13 +142,13 @@
  iureg=ureg;isreg=sreg;\
  ipcreg=pcreg;\
  iareg=*areg;ibreg=*breg;\
- idpreg=dpreg;iccreg=ccreg;
+ idpreg=dpreg;iccreg=ccreg;immu=mmu;
 
 #define SAVEREGS xreg=ixreg;yreg=iyreg;\
  ureg=iureg;sreg=isreg;\
  pcreg=ipcreg;\
  *areg=iareg;*breg=ibreg;\
- dpreg=idpreg;ccreg=iccreg;
+ dpreg=idpreg;ccreg=iccreg;mmu=immu;
 
 
 unsigned char haspostbyte[] = {
@@ -172,6 +180,12 @@
  Byte ireg; /* instruction register */
  Byte iflag; /* flag to indicate $10 or $11 prebyte */
  Byte tb;Word tw;
+ Byte *immu = 0; 
+#ifdef USE_MMU
+ const int imemsize = memsize;
+ Byte *iphymem = (Byte *)phymem;
+ immu = iphymem + imemsize - 0x10000 + 0xffa0;
+#endif 
  LOADREGS
  for(;;){
   if(attention) {
@@ -204,9 +218,9 @@
   }
   iflag=0;
  flaginstr:  /* $10 and $11 instructions return here */
-  ireg=mem[ipcreg++];
+  ireg=mem(ipcreg++);
   if(haspostbyte[ireg]) {
-   Byte postbyte=mem[ipcreg++];
+   Byte postbyte=mem(ipcreg++);
    switch(postbyte) {
     case 0x00: eaddr=ixreg;break;
     case 0x01: eaddr=ixreg+1;break;
@@ -475,38 +489,38 @@
    }
   }
   switch(ireg) {
-   case 0x00: /*NEG direct*/ DIRECT tw=-mem[eaddr];SETSTATUS(0,mem[eaddr],tw)
+   case 0x00: /*NEG direct*/ DIRECT tw=-mem(eaddr);SETSTATUS(0,mem(eaddr),tw)
                              SETBYTE(eaddr,tw)break;
    case 0x01: break;/*ILLEGAL*/
    case 0x02: break;/*ILLEGAL*/
-   case 0x03: /*COM direct*/ DIRECT  tb=~mem[eaddr];SETNZ8(tb);SEC CLV
+   case 0x03: /*COM direct*/ DIRECT  tb=~mem(eaddr);SETNZ8(tb);SEC CLV
                              SETBYTE(eaddr,tb)break;
-   case 0x04: /*LSR direct*/ DIRECT tb=mem[eaddr];if(tb&0x01)SEC else CLC
+   case 0x04: /*LSR direct*/ DIRECT tb=mem(eaddr);if(tb&0x01)SEC else CLC
                              if(tb&0x10)SEH else CLH tb>>=1;SETNZ8(tb)
                              SETBYTE(eaddr,tb)break;
    case 0x05: break;/* ILLEGAL*/
    case 0x06: /*ROR direct*/ DIRECT tb=(iccreg&0x01)<<7;
-                             if(mem[eaddr]&0x01)SEC else CLC
-                             tw=(mem[eaddr]>>1)+tb;SETNZ8(tw)
+                             if(mem(eaddr)&0x01)SEC else CLC
+                             tw=(mem(eaddr)>>1)+tb;SETNZ8(tw)
                              SETBYTE(eaddr,tw)
                        	     break;
-   case 0x07: /*ASR direct*/ DIRECT tb=mem[eaddr];if(tb&0x01)SEC else CLC
+   case 0x07: /*ASR direct*/ DIRECT tb=mem(eaddr);if(tb&0x01)SEC else CLC
                              if(tb&0x10)SEH else CLH tb>>=1;
                              if(tb&0x40)tb|=0x80;SETBYTE(eaddr,tb)SETNZ8(tb)
                              break;
-   case 0x08: /*ASL direct*/ DIRECT tw=mem[eaddr]<<1;
-                             SETSTATUS(mem[eaddr],mem[eaddr],tw)
+   case 0x08: /*ASL direct*/ DIRECT tw=mem(eaddr)<<1;
+                             SETSTATUS(mem(eaddr),mem(eaddr),tw)
                              SETBYTE(eaddr,tw)break;
-   case 0x09: /*ROL direct*/ DIRECT tb=mem[eaddr];tw=iccreg&0x01;
+   case 0x09: /*ROL direct*/ DIRECT tb=mem(eaddr);tw=iccreg&0x01;
                              if(tb&0x80)SEC else CLC
                              if((tb&0x80)^((tb<<1)&0x80))SEV else CLV
                              tb=(tb<<1)+tw;SETNZ8(tb) SETBYTE(eaddr,tb)break;
-   case 0x0A: /*DEC direct*/ DIRECT tb=mem[eaddr]-1;if(tb==0x7F)SEV else CLV
+   case 0x0A: /*DEC direct*/ DIRECT tb=mem(eaddr)-1;if(tb==0x7F)SEV else CLV
    			     SETNZ8(tb) SETBYTE(eaddr,tb)break;
    case 0x0B: break; /*ILLEGAL*/
-   case 0x0C: /*INC direct*/ DIRECT tb=mem[eaddr]+1;if(tb==0x80)SEV else CLV
+   case 0x0C: /*INC direct*/ DIRECT tb=mem(eaddr)+1;if(tb==0x80)SEV else CLV
    			     SETNZ8(tb) SETBYTE(eaddr,tb)break;
-   case 0x0D: /*TST direct*/ DIRECT tb=mem[eaddr];SETNZ8(tb) break;
+   case 0x0D: /*TST direct*/ DIRECT tb=mem(eaddr);SETNZ8(tb) break;
    case 0x0E: /*JMP direct*/ DIRECT ipcreg=eaddr;break;
    case 0x0F: /*CLR direct*/ DIRECT SETBYTE(eaddr,0);CLN CLV SEZ CLC break;
    case 0x10: /* flag10 */ iflag=1;goto flaginstr;
@@ -718,81 +732,81 @@
    case 0x5D: /*TSTB*/  SETNZ8(ibreg) break;
    case 0x5E: break; /*ILLEGAL*/
    case 0x5F: /*CLRB*/  ibreg=0;CLN CLV SEZ CLC break;
-   case 0x60: /*NEG indexed*/  tw=-mem[eaddr];SETSTATUS(0,mem[eaddr],tw)
+   case 0x60: /*NEG indexed*/  tw=-mem(eaddr);SETSTATUS(0,mem(eaddr),tw)
                              SETBYTE(eaddr,tw)break;
    case 0x61: break;/*ILLEGAL*/
    case 0x62: break;/*ILLEGAL*/
-   case 0x63: /*COM indexed*/   tb=~mem[eaddr];SETNZ8(tb);SEC CLV
+   case 0x63: /*COM indexed*/   tb=~mem(eaddr);SETNZ8(tb);SEC CLV
                              SETBYTE(eaddr,tb)break;
-   case 0x64: /*LSR indexed*/  tb=mem[eaddr];if(tb&0x01)SEC else CLC
+   case 0x64: /*LSR indexed*/  tb=mem(eaddr);if(tb&0x01)SEC else CLC
                              if(tb&0x10)SEH else CLH tb>>=1;SETNZ8(tb)
                              SETBYTE(eaddr,tb)break;
    case 0x65: break;/* ILLEGAL*/
    case 0x66: /*ROR indexed*/  tb=(iccreg&0x01)<<7;
-                             if(mem[eaddr]&0x01)SEC else CLC
-                             tw=(mem[eaddr]>>1)+tb;SETNZ8(tw)
+                             if(mem(eaddr)&0x01)SEC else CLC
+                             tw=(mem(eaddr)>>1)+tb;SETNZ8(tw)
                              SETBYTE(eaddr,tw)
                        	     break;
-   case 0x67: /*ASR indexed*/  tb=mem[eaddr];if(tb&0x01)SEC else CLC
+   case 0x67: /*ASR indexed*/  tb=mem(eaddr);if(tb&0x01)SEC else CLC
                              if(tb&0x10)SEH else CLH tb>>=1;
                              if(tb&0x40)tb|=0x80;SETBYTE(eaddr,tb)SETNZ8(tb)
                              break;
-   case 0x68: /*ASL indexed*/  tw=mem[eaddr]<<1;
-                             SETSTATUS(mem[eaddr],mem[eaddr],tw)
+   case 0x68: /*ASL indexed*/  tw=mem(eaddr)<<1;
+                             SETSTATUS(mem(eaddr),mem(eaddr),tw)
                              SETBYTE(eaddr,tw)break;
-   case 0x69: /*ROL indexed*/  tb=mem[eaddr];tw=iccreg&0x01;
+   case 0x69: /*ROL indexed*/  tb=mem(eaddr);tw=iccreg&0x01;
                              if(tb&0x80)SEC else CLC
                              if((tb&0x80)^((tb<<1)&0x80))SEV else CLV
                              tb=(tb<<1)+tw;SETNZ8(tb) SETBYTE(eaddr,tb)break;
-   case 0x6A: /*DEC indexed*/  tb=mem[eaddr]-1;if(tb==0x7F)SEV else CLV
+   case 0x6A: /*DEC indexed*/  tb=mem(eaddr)-1;if(tb==0x7F)SEV else CLV
    			     SETNZ8(tb) SETBYTE(eaddr,tb)break;
    case 0x6B: break; /*ILLEGAL*/
-   case 0x6C: /*INC indexed*/  tb=mem[eaddr]+1;if(tb==0x80)SEV else CLV
+   case 0x6C: /*INC indexed*/  tb=mem(eaddr)+1;if(tb==0x80)SEV else CLV
    			     SETNZ8(tb) SETBYTE(eaddr,tb)break;
-   case 0x6D: /*TST indexed*/  tb=mem[eaddr];SETNZ8(tb) break;
+   case 0x6D: /*TST indexed*/  tb=mem(eaddr);SETNZ8(tb) break;
    case 0x6E: /*JMP indexed*/  ipcreg=eaddr;break;
    case 0x6F: /*CLR indexed*/  SETBYTE(eaddr,0)CLN CLV SEZ CLC break;
-   case 0x70: /*NEG ext*/ EXTENDED tw=-mem[eaddr];SETSTATUS(0,mem[eaddr],tw)
+   case 0x70: /*NEG ext*/ EXTENDED tw=-mem(eaddr);SETSTATUS(0,mem(eaddr),tw)
                              SETBYTE(eaddr,tw)break;
    case 0x71: break;/*ILLEGAL*/
    case 0x72: break;/*ILLEGAL*/
-   case 0x73: /*COM ext*/ EXTENDED  tb=~mem[eaddr];SETNZ8(tb);SEC CLV
+   case 0x73: /*COM ext*/ EXTENDED  tb=~mem(eaddr);SETNZ8(tb);SEC CLV
                             SETBYTE(eaddr,tb)break;
-   case 0x74: /*LSR ext*/ EXTENDED tb=mem[eaddr];if(tb&0x01)SEC else CLC
+   case 0x74: /*LSR ext*/ EXTENDED tb=mem(eaddr);if(tb&0x01)SEC else CLC
                              if(tb&0x10)SEH else CLH tb>>=1;SETNZ8(tb)
                              SETBYTE(eaddr,tb)break;
    case 0x75: break;/* ILLEGAL*/
    case 0x76: /*ROR ext*/ EXTENDED tb=(iccreg&0x01)<<7;
-                             if(mem[eaddr]&0x01)SEC else CLC
-                             tw=(mem[eaddr]>>1)+tb;SETNZ8(tw)
+                             if(mem(eaddr)&0x01)SEC else CLC
+                             tw=(mem(eaddr)>>1)+tb;SETNZ8(tw)
                              SETBYTE(eaddr,tw)
                        	     break;
-   case 0x77: /*ASR ext*/ EXTENDED tb=mem[eaddr];if(tb&0x01)SEC else CLC
+   case 0x77: /*ASR ext*/ EXTENDED tb=mem(eaddr);if(tb&0x01)SEC else CLC
                              if(tb&0x10)SEH else CLH tb>>=1;
                              if(tb&0x40)tb|=0x80;SETBYTE(eaddr,tb)SETNZ8(tb)
                              break;
-   case 0x78: /*ASL ext*/ EXTENDED tw=mem[eaddr]<<1;
-                             SETSTATUS(mem[eaddr],mem[eaddr],tw)
+   case 0x78: /*ASL ext*/ EXTENDED tw=mem(eaddr)<<1;
+                             SETSTATUS(mem(eaddr),mem(eaddr),tw)
                              SETBYTE(eaddr,tw)break;
-   case 0x79: /*ROL ext*/ EXTENDED tb=mem[eaddr];tw=iccreg&0x01;
+   case 0x79: /*ROL ext*/ EXTENDED tb=mem(eaddr);tw=iccreg&0x01;
                              if(tb&0x80)SEC else CLC
                              if((tb&0x80)^((tb<<1)&0x80))SEV else CLV
                              tb=(tb<<1)+tw;SETNZ8(tb) SETBYTE(eaddr,tb)break;
-   case 0x7A: /*DEC ext*/ EXTENDED tb=mem[eaddr]-1;if(tb==0x7F)SEV else CLV
+   case 0x7A: /*DEC ext*/ EXTENDED tb=mem(eaddr)-1;if(tb==0x7F)SEV else CLV
    			     SETNZ8(tb) SETBYTE(eaddr,tb)break;
    case 0x7B: break; /*ILLEGAL*/
-   case 0x7C: /*INC ext*/ EXTENDED tb=mem[eaddr]+1;if(tb==0x80)SEV else CLV
+   case 0x7C: /*INC ext*/ EXTENDED tb=mem(eaddr)+1;if(tb==0x80)SEV else CLV
    			     SETNZ8(tb) SETBYTE(eaddr,tb)break;
-   case 0x7D: /*TST ext*/ EXTENDED tb=mem[eaddr];SETNZ8(tb) break;
+   case 0x7D: /*TST ext*/ EXTENDED tb=mem(eaddr);SETNZ8(tb) break;
    case 0x7E: /*JMP ext*/ EXTENDED ipcreg=eaddr;break;
    case 0x7F: /*CLR ext*/ EXTENDED SETBYTE(eaddr,0)CLN CLV SEZ CLC break;
-   case 0x80: /*SUBA immediate*/ IMM8 tw=iareg-mem[eaddr];
-                                 SETSTATUS(iareg,mem[eaddr],tw)
+   case 0x80: /*SUBA immediate*/ IMM8 tw=iareg-mem(eaddr);
+                                 SETSTATUS(iareg,mem(eaddr),tw)
                                  iareg=tw;break;
-   case 0x81: /*CMPA immediate*/ IMM8 tw=iareg-mem[eaddr];
-   				 SETSTATUS(iareg,mem[eaddr],tw) break;
-   case 0x82: /*SBCA immediate*/ IMM8 tw=iareg-mem[eaddr]-(iccreg&0x01);
-   				 SETSTATUS(iareg,mem[eaddr],tw)
+   case 0x81: /*CMPA immediate*/ IMM8 tw=iareg-mem(eaddr);
+   				 SETSTATUS(iareg,mem(eaddr),tw) break;
+   case 0x82: /*SBCA immediate*/ IMM8 tw=iareg-mem(eaddr)-(iccreg&0x01);
+   				 SETSTATUS(iareg,mem(eaddr),tw)
    				 iareg=tw;break;
    case 0x83: /*SUBD (CMPD CMPU) immediate*/ IMM16
                                  {unsigned long res,dreg,breg;
@@ -802,23 +816,23 @@
                                  SETSTATUSD(dreg,breg,res)
                                  if(iflag==0) SETDREG(res)
                                  }break;
-   case 0x84: /*ANDA immediate*/ IMM8 iareg=iareg&mem[eaddr];SETNZ8(iareg)
+   case 0x84: /*ANDA immediate*/ IMM8 iareg=iareg&mem(eaddr);SETNZ8(iareg)
    				 CLV break;
-   case 0x85: /*BITA immediate*/ IMM8 tb=iareg&mem[eaddr];SETNZ8(tb)
+   case 0x85: /*BITA immediate*/ IMM8 tb=iareg&mem(eaddr);SETNZ8(tb)
    				 CLV break;
    case 0x86: /*LDA immediate*/ IMM8 LOADAC(iareg) CLV SETNZ8(iareg)
                                  break;
    case 0x87: /*STA immediate (for the sake of orthogonality) */ IMM8
                                  SETNZ8(iareg) CLV STOREAC(iareg) break;
-   case 0x88: /*EORA immediate*/ IMM8 iareg=iareg^mem[eaddr];SETNZ8(iareg)
+   case 0x88: /*EORA immediate*/ IMM8 iareg=iareg^mem(eaddr);SETNZ8(iareg)
    				 CLV break;
-   case 0x89: /*ADCA immediate*/ IMM8 tw=iareg+mem[eaddr]+(iccreg&0x01);
-                                 SETSTATUS(iareg,mem[eaddr],tw)
+   case 0x89: /*ADCA immediate*/ IMM8 tw=iareg+mem(eaddr)+(iccreg&0x01);
+                                 SETSTATUS(iareg,mem(eaddr),tw)
                                  iareg=tw;break;
-   case 0x8A: /*ORA immediate*/  IMM8 iareg=iareg|mem[eaddr];SETNZ8(iareg)
+   case 0x8A: /*ORA immediate*/  IMM8 iareg=iareg|mem(eaddr);SETNZ8(iareg)
    				 CLV break;
-   case 0x8B: /*ADDA immediate*/ IMM8 tw=iareg+mem[eaddr];
-   				 SETSTATUS(iareg,mem[eaddr],tw)
+   case 0x8B: /*ADDA immediate*/ IMM8 tw=iareg+mem(eaddr);
+   				 SETSTATUS(iareg,mem(eaddr),tw)
    				 iareg=tw;break;
    case 0x8C: /*CMPX (CMPY CMPS) immediate */ IMM16
                                  {unsigned long dreg,breg,res;
@@ -835,13 +849,13 @@
    case 0x8F:  /* STX (STY) immediate (orthogonality) */ IMM16
                                   if(!iflag) tw=ixreg; else tw=iyreg;
                                   CLV SETNZ16(tw) SETWORD(eaddr,tw) break;
-   case 0x90: /*SUBA direct*/ DIRECT tw=iareg-mem[eaddr];
-                                 SETSTATUS(iareg,mem[eaddr],tw)
+   case 0x90: /*SUBA direct*/ DIRECT tw=iareg-mem(eaddr);
+                                 SETSTATUS(iareg,mem(eaddr),tw)
                                  iareg=tw;break;
-   case 0x91: /*CMPA direct*/ DIRECT tw=iareg-mem[eaddr];
-   				 SETSTATUS(iareg,mem[eaddr],tw) break;
-   case 0x92: /*SBCA direct*/ DIRECT tw=iareg-mem[eaddr]-(iccreg&0x01);
-   				 SETSTATUS(iareg,mem[eaddr],tw)
+   case 0x91: /*CMPA direct*/ DIRECT tw=iareg-mem(eaddr);
+   				 SETSTATUS(iareg,mem(eaddr),tw) break;
+   case 0x92: /*SBCA direct*/ DIRECT tw=iareg-mem(eaddr)-(iccreg&0x01);
+   				 SETSTATUS(iareg,mem(eaddr),tw)
    				 iareg=tw;break;
    case 0x93: /*SUBD (CMPD CMPU) direct*/ DIRECT
                                  {unsigned long res,dreg,breg;
@@ -851,23 +865,23 @@
                                  SETSTATUSD(dreg,breg,res)
                                  if(iflag==0) SETDREG(res)
                                  }break;
-   case 0x94: /*ANDA direct*/ DIRECT iareg=iareg&mem[eaddr];SETNZ8(iareg)
+   case 0x94: /*ANDA direct*/ DIRECT iareg=iareg&mem(eaddr);SETNZ8(iareg)
    				 CLV break;
-   case 0x95: /*BITA direct*/ DIRECT tb=iareg&mem[eaddr];SETNZ8(tb)
+   case 0x95: /*BITA direct*/ DIRECT tb=iareg&mem(eaddr);SETNZ8(tb)
    				 CLV break;
    case 0x96: /*LDA direct*/ DIRECT LOADAC(iareg) CLV SETNZ8(iareg)
                                  break;
    case 0x97: /*STA direct */ DIRECT
                                  SETNZ8(iareg) CLV STOREAC(iareg) break;
-   case 0x98: /*EORA direct*/ DIRECT iareg=iareg^mem[eaddr];SETNZ8(iareg)
+   case 0x98: /*EORA direct*/ DIRECT iareg=iareg^mem(eaddr);SETNZ8(iareg)
    				 CLV break;
-   case 0x99: /*ADCA direct*/ DIRECT tw=iareg+mem[eaddr]+(iccreg&0x01);
-                                 SETSTATUS(iareg,mem[eaddr],tw)
+   case 0x99: /*ADCA direct*/ DIRECT tw=iareg+mem(eaddr)+(iccreg&0x01);
+                                 SETSTATUS(iareg,mem(eaddr),tw)
                                  iareg=tw;break;
-   case 0x9A: /*ORA direct*/  DIRECT iareg=iareg|mem[eaddr];SETNZ8(iareg)
+   case 0x9A: /*ORA direct*/  DIRECT iareg=iareg|mem(eaddr);SETNZ8(iareg)
    				 CLV break;
-   case 0x9B: /*ADDA direct*/ DIRECT tw=iareg+mem[eaddr];
-   				 SETSTATUS(iareg,mem[eaddr],tw)
+   case 0x9B: /*ADDA direct*/ DIRECT tw=iareg+mem(eaddr);
+   				 SETSTATUS(iareg,mem(eaddr),tw)
    				 iareg=tw;break;
    case 0x9C: /*CMPX (CMPY CMPS) direct */ DIRECT
                                  {unsigned long dreg,breg,res;
@@ -884,13 +898,13 @@
    case 0x9F:  /* STX (STY) direct */ DIRECT
                                   if(!iflag) tw=ixreg; else tw=iyreg;
                                   CLV SETNZ16(tw) SETWORD(eaddr,tw) break;
-   case 0xA0: /*SUBA indexed*/  tw=iareg-mem[eaddr];
-                                 SETSTATUS(iareg,mem[eaddr],tw)
+   case 0xA0: /*SUBA indexed*/  tw=iareg-mem(eaddr);
+                                 SETSTATUS(iareg,mem(eaddr),tw)
                                  iareg=tw;break;
-   case 0xA1: /*CMPA indexed*/  tw=iareg-mem[eaddr];
-   				 SETSTATUS(iareg,mem[eaddr],tw) break;
-   case 0xA2: /*SBCA indexed*/  tw=iareg-mem[eaddr]-(iccreg&0x01);
-   				 SETSTATUS(iareg,mem[eaddr],tw)
+   case 0xA1: /*CMPA indexed*/  tw=iareg-mem(eaddr);
+   				 SETSTATUS(iareg,mem(eaddr),tw) break;
+   case 0xA2: /*SBCA indexed*/  tw=iareg-mem(eaddr)-(iccreg&0x01);
+   				 SETSTATUS(iareg,mem(eaddr),tw)
    				 iareg=tw;break;
    case 0xA3: /*SUBD (CMPD CMPU) indexed*/
                                  {unsigned long res,dreg,breg;
@@ -900,23 +914,23 @@
                                  SETSTATUSD(dreg,breg,res)
                                  if(iflag==0) SETDREG(res)
                                  }break;
-   case 0xA4: /*ANDA indexed*/  iareg=iareg&mem[eaddr];SETNZ8(iareg)
+   case 0xA4: /*ANDA indexed*/  iareg=iareg&mem(eaddr);SETNZ8(iareg)
    				 CLV break;
-   case 0xA5: /*BITA indexed*/  tb=iareg&mem[eaddr];SETNZ8(tb)
+   case 0xA5: /*BITA indexed*/  tb=iareg&mem(eaddr);SETNZ8(tb)
    				 CLV break;
    case 0xA6: /*LDA indexed*/  LOADAC(iareg) CLV SETNZ8(iareg)
                                  break;
    case 0xA7: /*STA indexed */
                                  SETNZ8(iareg) CLV STOREAC(iareg) break;
-   case 0xA8: /*EORA indexed*/  iareg=iareg^mem[eaddr];SETNZ8(iareg)
+   case 0xA8: /*EORA indexed*/  iareg=iareg^mem(eaddr);SETNZ8(iareg)
    				 CLV break;
-   case 0xA9: /*ADCA indexed*/  tw=iareg+mem[eaddr]+(iccreg&0x01);
-                                 SETSTATUS(iareg,mem[eaddr],tw)
+   case 0xA9: /*ADCA indexed*/  tw=iareg+mem(eaddr)+(iccreg&0x01);
+                                 SETSTATUS(iareg,mem(eaddr),tw)
                                  iareg=tw;break;
-   case 0xAA: /*ORA indexed*/   iareg=iareg|mem[eaddr];SETNZ8(iareg)
+   case 0xAA: /*ORA indexed*/   iareg=iareg|mem(eaddr);SETNZ8(iareg)
    				 CLV break;
-   case 0xAB: /*ADDA indexed*/  tw=iareg+mem[eaddr];
-   				 SETSTATUS(iareg,mem[eaddr],tw)
+   case 0xAB: /*ADDA indexed*/  tw=iareg+mem(eaddr);
+   				 SETSTATUS(iareg,mem(eaddr),tw)
    				 iareg=tw;break;
    case 0xAC: /*CMPX (CMPY CMPS) indexed */
                                  {unsigned long dreg,breg,res;
@@ -933,13 +947,13 @@
    case 0xAF:  /* STX (STY) indexed */
                                   if(!iflag) tw=ixreg; else tw=iyreg;
                                   CLV SETNZ16(tw) SETWORD(eaddr,tw) break;
-   case 0xB0: /*SUBA ext*/ EXTENDED tw=iareg-mem[eaddr];
-                                 SETSTATUS(iareg,mem[eaddr],tw)
+   case 0xB0: /*SUBA ext*/ EXTENDED tw=iareg-mem(eaddr);
+                                 SETSTATUS(iareg,mem(eaddr),tw)
                                  iareg=tw;break;
-   case 0xB1: /*CMPA ext*/ EXTENDED tw=iareg-mem[eaddr];
-   				 SETSTATUS(iareg,mem[eaddr],tw) break;
-   case 0xB2: /*SBCA ext*/ EXTENDED tw=iareg-mem[eaddr]-(iccreg&0x01);
-   				 SETSTATUS(iareg,mem[eaddr],tw)
+   case 0xB1: /*CMPA ext*/ EXTENDED tw=iareg-mem(eaddr);
+   				 SETSTATUS(iareg,mem(eaddr),tw) break;
+   case 0xB2: /*SBCA ext*/ EXTENDED tw=iareg-mem(eaddr)-(iccreg&0x01);
+   				 SETSTATUS(iareg,mem(eaddr),tw)
    				 iareg=tw;break;
    case 0xB3: /*SUBD (CMPD CMPU) ext*/ EXTENDED
                                  {unsigned long res,dreg,breg;
@@ -949,23 +963,23 @@
                                  SETSTATUSD(dreg,breg,res)
                                  if(iflag==0) SETDREG(res)
                                  }break;
-   case 0xB4: /*ANDA ext*/ EXTENDED iareg=iareg&mem[eaddr];SETNZ8(iareg)
+   case 0xB4: /*ANDA ext*/ EXTENDED iareg=iareg&mem(eaddr);SETNZ8(iareg)
    				 CLV break;
-   case 0xB5: /*BITA ext*/ EXTENDED tb=iareg&mem[eaddr];SETNZ8(tb)
+   case 0xB5: /*BITA ext*/ EXTENDED tb=iareg&mem(eaddr);SETNZ8(tb)
    				 CLV break;
    case 0xB6: /*LDA ext*/ EXTENDED LOADAC(iareg) CLV SETNZ8(iareg)
                                  break;
    case 0xB7: /*STA ext */ EXTENDED
                                  SETNZ8(iareg) CLV STOREAC(iareg) break;
-   case 0xB8: /*EORA ext*/ EXTENDED iareg=iareg^mem[eaddr];SETNZ8(iareg)
+   case 0xB8: /*EORA ext*/ EXTENDED iareg=iareg^mem(eaddr);SETNZ8(iareg)
    				 CLV break;
-   case 0xB9: /*ADCA ext*/ EXTENDED tw=iareg+mem[eaddr]+(iccreg&0x01);
-                                 SETSTATUS(iareg,mem[eaddr],tw)
+   case 0xB9: /*ADCA ext*/ EXTENDED tw=iareg+mem(eaddr)+(iccreg&0x01);
+                                 SETSTATUS(iareg,mem(eaddr),tw)
                                  iareg=tw;break;
-   case 0xBA: /*ORA ext*/  EXTENDED iareg=iareg|mem[eaddr];SETNZ8(iareg)
+   case 0xBA: /*ORA ext*/  EXTENDED iareg=iareg|mem(eaddr);SETNZ8(iareg)
    				 CLV break;
-   case 0xBB: /*ADDA ext*/ EXTENDED tw=iareg+mem[eaddr];
-   				 SETSTATUS(iareg,mem[eaddr],tw)
+   case 0xBB: /*ADDA ext*/ EXTENDED tw=iareg+mem(eaddr);
+   				 SETSTATUS(iareg,mem(eaddr),tw)
    				 iareg=tw;break;
    case 0xBC: /*CMPX (CMPY CMPS) ext */ EXTENDED
                                  {unsigned long dreg,breg,res;
@@ -982,13 +996,13 @@
    case 0xBF:  /* STX (STY) ext */ EXTENDED
                                   if(!iflag) tw=ixreg; else tw=iyreg;
                                   CLV SETNZ16(tw) SETWORD(eaddr,tw) break;
-   case 0xC0: /*SUBB immediate*/ IMM8 tw=ibreg-mem[eaddr];
-                                 SETSTATUS(ibreg,mem[eaddr],tw)
+   case 0xC0: /*SUBB immediate*/ IMM8 tw=ibreg-mem(eaddr);
+                                 SETSTATUS(ibreg,mem(eaddr),tw)
                                  ibreg=tw;break;
-   case 0xC1: /*CMPB immediate*/ IMM8 tw=ibreg-mem[eaddr];
-   				 SETSTATUS(ibreg,mem[eaddr],tw) break;
-   case 0xC2: /*SBCB immediate*/ IMM8 tw=ibreg-mem[eaddr]-(iccreg&0x01);
-   				 SETSTATUS(ibreg,mem[eaddr],tw)
+   case 0xC1: /*CMPB immediate*/ IMM8 tw=ibreg-mem(eaddr);
+   				 SETSTATUS(ibreg,mem(eaddr),tw) break;
+   case 0xC2: /*SBCB immediate*/ IMM8 tw=ibreg-mem(eaddr)-(iccreg&0x01);
+   				 SETSTATUS(ibreg,mem(eaddr),tw)
    				 ibreg=tw;break;
    case 0xC3: /*ADDD immediate*/ IMM16
                                  {unsigned long res,dreg,breg;
@@ -998,23 +1012,23 @@
                                  SETSTATUSD(dreg,breg,res)
                                  SETDREG(res)
                                  }break;
-   case 0xC4: /*ANDB immediate*/ IMM8 ibreg=ibreg&mem[eaddr];SETNZ8(ibreg)
+   case 0xC4: /*ANDB immediate*/ IMM8 ibreg=ibreg&mem(eaddr);SETNZ8(ibreg)
    				 CLV break;
-   case 0xC5: /*BITB immediate*/ IMM8 tb=ibreg&mem[eaddr];SETNZ8(tb)
+   case 0xC5: /*BITB immediate*/ IMM8 tb=ibreg&mem(eaddr);SETNZ8(tb)
    				 CLV break;
    case 0xC6: /*LDB immediate*/ IMM8 LOADAC(ibreg) CLV SETNZ8(ibreg)
                                  break;
    case 0xC7: /*STB immediate (for the sake of orthogonality) */ IMM8
                                  SETNZ8(ibreg) CLV STOREAC(ibreg) break;
-   case 0xC8: /*EORB immediate*/ IMM8 ibreg=ibreg^mem[eaddr];SETNZ8(ibreg)
+   case 0xC8: /*EORB immediate*/ IMM8 ibreg=ibreg^mem(eaddr);SETNZ8(ibreg)
    				 CLV break;
-   case 0xC9: /*ADCB immediate*/ IMM8 tw=ibreg+mem[eaddr]+(iccreg&0x01);
-                                 SETSTATUS(ibreg,mem[eaddr],tw)
+   case 0xC9: /*ADCB immediate*/ IMM8 tw=ibreg+mem(eaddr)+(iccreg&0x01);
+                                 SETSTATUS(ibreg,mem(eaddr),tw)
                                  ibreg=tw;break;
-   case 0xCA: /*ORB immediate*/  IMM8 ibreg=ibreg|mem[eaddr];SETNZ8(ibreg)
+   case 0xCA: /*ORB immediate*/  IMM8 ibreg=ibreg|mem(eaddr);SETNZ8(ibreg)
    				 CLV break;
-   case 0xCB: /*ADDB immediate*/ IMM8 tw=ibreg+mem[eaddr];
-   				 SETSTATUS(ibreg,mem[eaddr],tw)
+   case 0xCB: /*ADDB immediate*/ IMM8 tw=ibreg+mem(eaddr);
+   				 SETSTATUS(ibreg,mem(eaddr),tw)
    				 ibreg=tw;break;
    case 0xCC: /*LDD immediate */ IMM16 tw=GETWORD(eaddr);SETNZ16(tw)
    			         CLV SETDREG(tw) break;
@@ -1027,13 +1041,13 @@
    case 0xCF:  /* STU (STS) immediate (orthogonality) */ IMM16
                                   if(!iflag) tw=iureg; else tw=isreg;
                                   CLV SETNZ16(tw) SETWORD(eaddr,tw) break;
-   case 0xD0: /*SUBB direct*/ DIRECT tw=ibreg-mem[eaddr];
-                                 SETSTATUS(ibreg,mem[eaddr],tw)
+   case 0xD0: /*SUBB direct*/ DIRECT tw=ibreg-mem(eaddr);
+                                 SETSTATUS(ibreg,mem(eaddr),tw)
                                  ibreg=tw;break;
-   case 0xD1: /*CMPB direct*/ DIRECT tw=ibreg-mem[eaddr];
-   				 SETSTATUS(ibreg,mem[eaddr],tw) break;
-   case 0xD2: /*SBCB direct*/ DIRECT tw=ibreg-mem[eaddr]-(iccreg&0x01);
-   				 SETSTATUS(ibreg,mem[eaddr],tw)
+   case 0xD1: /*CMPB direct*/ DIRECT tw=ibreg-mem(eaddr);
+   				 SETSTATUS(ibreg,mem(eaddr),tw) break;
+   case 0xD2: /*SBCB direct*/ DIRECT tw=ibreg-mem(eaddr)-(iccreg&0x01);
+   				 SETSTATUS(ibreg,mem(eaddr),tw)
    				 ibreg=tw;break;
    case 0xD3: /*ADDD direct*/ DIRECT
                                  {unsigned long res,dreg,breg;
@@ -1043,23 +1057,23 @@
                                  SETSTATUSD(dreg,breg,res)
                                  SETDREG(res)
                                  }break;
-   case 0xD4: /*ANDB direct*/ DIRECT ibreg=ibreg&mem[eaddr];SETNZ8(ibreg)
+   case 0xD4: /*ANDB direct*/ DIRECT ibreg=ibreg&mem(eaddr);SETNZ8(ibreg)
    				 CLV break;
-   case 0xD5: /*BITB direct*/ DIRECT tb=ibreg&mem[eaddr];SETNZ8(tb)
+   case 0xD5: /*BITB direct*/ DIRECT tb=ibreg&mem(eaddr);SETNZ8(tb)
    				 CLV break;
    case 0xD6: /*LDB direct*/ DIRECT LOADAC(ibreg) CLV SETNZ8(ibreg)
                                  break;
    case 0xD7: /*STB direct  */ DIRECT
                                  SETNZ8(ibreg) CLV STOREAC(ibreg) break;
-   case 0xD8: /*EORB direct*/ DIRECT ibreg=ibreg^mem[eaddr];SETNZ8(ibreg)
+   case 0xD8: /*EORB direct*/ DIRECT ibreg=ibreg^mem(eaddr);SETNZ8(ibreg)
    				 CLV break;
-   case 0xD9: /*ADCB direct*/ DIRECT tw=ibreg+mem[eaddr]+(iccreg&0x01);
-                                 SETSTATUS(ibreg,mem[eaddr],tw)
+   case 0xD9: /*ADCB direct*/ DIRECT tw=ibreg+mem(eaddr)+(iccreg&0x01);
+                                 SETSTATUS(ibreg,mem(eaddr),tw)
                                  ibreg=tw;break;
-   case 0xDA: /*ORB direct*/  DIRECT ibreg=ibreg|mem[eaddr];SETNZ8(ibreg)
+   case 0xDA: /*ORB direct*/  DIRECT ibreg=ibreg|mem(eaddr);SETNZ8(ibreg)
    				 CLV break;
-   case 0xDB: /*ADDB direct*/ DIRECT tw=ibreg+mem[eaddr];
-   				 SETSTATUS(ibreg,mem[eaddr],tw)
+   case 0xDB: /*ADDB direct*/ DIRECT tw=ibreg+mem(eaddr);
+   				 SETSTATUS(ibreg,mem(eaddr),tw)
    				 ibreg=tw;break;
    case 0xDC: /*LDD direct */ DIRECT tw=GETWORD(eaddr);SETNZ16(tw)
    			         CLV SETDREG(tw) break;
@@ -1072,13 +1086,13 @@
    case 0xDF:  /* STU (STS) direct  */ DIRECT
                                   if(!iflag) tw=iureg; else tw=isreg;
                                   CLV SETNZ16(tw) SETWORD(eaddr,tw) break;
-   case 0xE0: /*SUBB indexed*/  tw=ibreg-mem[eaddr];
-                                 SETSTATUS(ibreg,mem[eaddr],tw)
+   case 0xE0: /*SUBB indexed*/  tw=ibreg-mem(eaddr);
+                                 SETSTATUS(ibreg,mem(eaddr),tw)
                                  ibreg=tw;break;
-   case 0xE1: /*CMPB indexed*/  tw=ibreg-mem[eaddr];
-   				 SETSTATUS(ibreg,mem[eaddr],tw) break;
-   case 0xE2: /*SBCB indexed*/  tw=ibreg-mem[eaddr]-(iccreg&0x01);
-   				 SETSTATUS(ibreg,mem[eaddr],tw)
+   case 0xE1: /*CMPB indexed*/  tw=ibreg-mem(eaddr);
+   				 SETSTATUS(ibreg,mem(eaddr),tw) break;
+   case 0xE2: /*SBCB indexed*/  tw=ibreg-mem(eaddr)-(iccreg&0x01);
+   				 SETSTATUS(ibreg,mem(eaddr),tw)
    				 ibreg=tw;break;
    case 0xE3: /*ADDD indexed*/
                                  {unsigned long res,dreg,breg;
@@ -1088,23 +1102,23 @@
                                  SETSTATUSD(dreg,breg,res)
                                  SETDREG(res)
                                  }break;
-   case 0xE4: /*ANDB indexed*/  ibreg=ibreg&mem[eaddr];SETNZ8(ibreg)
+   case 0xE4: /*ANDB indexed*/  ibreg=ibreg&mem(eaddr);SETNZ8(ibreg)
    				 CLV break;
-   case 0xE5: /*BITB indexed*/  tb=ibreg&mem[eaddr];SETNZ8(tb)
+   case 0xE5: /*BITB indexed*/  tb=ibreg&mem(eaddr);SETNZ8(tb)
    				 CLV break;
    case 0xE6: /*LDB indexed*/  LOADAC(ibreg) CLV SETNZ8(ibreg)
                                  break;
    case 0xE7: /*STB indexed  */
                                  SETNZ8(ibreg) CLV STOREAC(ibreg) break;
-   case 0xE8: /*EORB indexed*/  ibreg=ibreg^mem[eaddr];SETNZ8(ibreg)
+   case 0xE8: /*EORB indexed*/  ibreg=ibreg^mem(eaddr);SETNZ8(ibreg)
    				 CLV break;
-   case 0xE9: /*ADCB indexed*/  tw=ibreg+mem[eaddr]+(iccreg&0x01);
-                                 SETSTATUS(ibreg,mem[eaddr],tw)
+   case 0xE9: /*ADCB indexed*/  tw=ibreg+mem(eaddr)+(iccreg&0x01);
+                                 SETSTATUS(ibreg,mem(eaddr),tw)
                                  ibreg=tw;break;
-   case 0xEA: /*ORB indexed*/   ibreg=ibreg|mem[eaddr];SETNZ8(ibreg)
+   case 0xEA: /*ORB indexed*/   ibreg=ibreg|mem(eaddr);SETNZ8(ibreg)
    				 CLV break;
-   case 0xEB: /*ADDB indexed*/  tw=ibreg+mem[eaddr];
-   				 SETSTATUS(ibreg,mem[eaddr],tw)
+   case 0xEB: /*ADDB indexed*/  tw=ibreg+mem(eaddr);
+   				 SETSTATUS(ibreg,mem(eaddr),tw)
    				 ibreg=tw;break;
    case 0xEC: /*LDD indexed */  tw=GETWORD(eaddr);SETNZ16(tw)
    			         CLV SETDREG(tw) break;
@@ -1117,13 +1131,13 @@
    case 0xEF:  /* STU (STS) indexed  */
                                   if(!iflag) tw=iureg; else tw=isreg;
                                   CLV SETNZ16(tw) SETWORD(eaddr,tw) break;
-   case 0xF0: /*SUBB ext*/ EXTENDED tw=ibreg-mem[eaddr];
-                                 SETSTATUS(ibreg,mem[eaddr],tw)
+   case 0xF0: /*SUBB ext*/ EXTENDED tw=ibreg-mem(eaddr);
+                                 SETSTATUS(ibreg,mem(eaddr),tw)
                                  ibreg=tw;break;
-   case 0xF1: /*CMPB ext*/ EXTENDED tw=ibreg-mem[eaddr];
-   				 SETSTATUS(ibreg,mem[eaddr],tw) break;
-   case 0xF2: /*SBCB ext*/ EXTENDED tw=ibreg-mem[eaddr]-(iccreg&0x01);
-   				 SETSTATUS(ibreg,mem[eaddr],tw)
+   case 0xF1: /*CMPB ext*/ EXTENDED tw=ibreg-mem(eaddr);
+   				 SETSTATUS(ibreg,mem(eaddr),tw) break;
+   case 0xF2: /*SBCB ext*/ EXTENDED tw=ibreg-mem(eaddr)-(iccreg&0x01);
+   				 SETSTATUS(ibreg,mem(eaddr),tw)
    				 ibreg=tw;break;
    case 0xF3: /*ADDD ext*/ EXTENDED
                                  {unsigned long res,dreg,breg;
@@ -1133,23 +1147,23 @@
                                  SETSTATUSD(dreg,breg,res)
                                  SETDREG(res)
                                  }break;
-   case 0xF4: /*ANDB ext*/ EXTENDED ibreg=ibreg&mem[eaddr];SETNZ8(ibreg)
+   case 0xF4: /*ANDB ext*/ EXTENDED ibreg=ibreg&mem(eaddr);SETNZ8(ibreg)
    				 CLV break;
-   case 0xF5: /*BITB ext*/ EXTENDED tb=ibreg&mem[eaddr];SETNZ8(tb)
+   case 0xF5: /*BITB ext*/ EXTENDED tb=ibreg&mem(eaddr);SETNZ8(tb)
    				 CLV break;
    case 0xF6: /*LDB ext*/ EXTENDED LOADAC(ibreg) CLV SETNZ8(ibreg)
                                  break;
    case 0xF7: /*STB ext  */ EXTENDED
                                  SETNZ8(ibreg) CLV STOREAC(ibreg) break;
-   case 0xF8: /*EORB ext*/ EXTENDED ibreg=ibreg^mem[eaddr];SETNZ8(ibreg)
+   case 0xF8: /*EORB ext*/ EXTENDED ibreg=ibreg^mem(eaddr);SETNZ8(ibreg)
    				 CLV break;
-   case 0xF9: /*ADCB ext*/ EXTENDED tw=ibreg+mem[eaddr]+(iccreg&0x01);
-                                 SETSTATUS(ibreg,mem[eaddr],tw)
+   case 0xF9: /*ADCB ext*/ EXTENDED tw=ibreg+mem(eaddr)+(iccreg&0x01);
+                                 SETSTATUS(ibreg,mem(eaddr),tw)
                                  ibreg=tw;break;
-   case 0xFA: /*ORB ext*/  EXTENDED ibreg=ibreg|mem[eaddr];SETNZ8(ibreg)
+   case 0xFA: /*ORB ext*/  EXTENDED ibreg=ibreg|mem(eaddr);SETNZ8(ibreg)
    				 CLV break;
-   case 0xFB: /*ADDB ext*/ EXTENDED tw=ibreg+mem[eaddr];
-   				 SETSTATUS(ibreg,mem[eaddr],tw)
+   case 0xFB: /*ADDB ext*/ EXTENDED tw=ibreg+mem(eaddr);
+   				 SETSTATUS(ibreg,mem(eaddr),tw)
    				 ibreg=tw;break;
    case 0xFC: /*LDD ext */ EXTENDED tw=GETWORD(eaddr);SETNZ16(tw)
    			         CLV SETDREG(tw) break;
--- a/io.c	Wed Jul 04 14:03:56 2018 +0900
+++ b/io.c	Wed Jul 04 19:33:22 2018 +0900
@@ -98,6 +98,7 @@
 
 void do_timer(int,int);
 void do_disk(int,int);
+void do_mmu(int,int);
 
 int char_input(void) {
         int c, w, sum;
@@ -243,10 +244,12 @@
                                 xidx = 0;
                         }
                 }
-        } else if ((a&0xf0) == 0x10) { /* timer */
+        } else if (a >= 0x90) { /* mmu */
+             do_mmu(a,c);
+        } else if (a >= 0x20) { /* disk */
+             do_disk(a,c);
+        } else if (a >= 0x10) { /* disk */
              do_timer(a,c);
-        } else if ((a&0xf0) == 0x20) { /* disk */
-             do_disk(a,c);
         }
 }
 
@@ -309,6 +312,24 @@
    mem[IOPAGE+0x20] = 0xff;
 }
 
+void do_mmu(int a, int c)
+{
+#ifdef USE_MMU
+
+   if (a==0x91) {
+       if (c&0) {
+           mmu = phymem+memsize-0x10000+0xffa0;
+       } else {
+           mmu = phymem+memsize-0x10000+0xffa8;
+       }
+       mem[IOPAGE+a] = c;
+   } if (0xa0 <= a && a <= 0xaf) {
+       mem[IOPAGE+a] = c;
+   }
+
+#endif 
+}
+
 typedef struct bp {
   int address;
   int count;
--- a/v09.c	Wed Jul 04 14:03:56 2018 +0900
+++ b/v09.c	Wed Jul 04 19:33:22 2018 +0900
@@ -101,6 +101,7 @@
  char *imagename=0;
  int i;
  int setterm = 1;
+ memsize = 512*1024;
  escchar='\x1d'; 
  tracelo=0;tracehi=0xffff;
  for(i=1;i<argc;i++) {
@@ -136,14 +137,23 @@
    } else if (strcmp(argv[i],"-nt")==0) {  // start debugger at the start
      attention = escape = 1;
      timer = 0;   // no timer
+   } else if (strcmp(argv[i],"-m")==0) {
+     i++;
+     memsize=strtol(argv[i],(char**)0,0) & ~0xffff;
+     if (memsize < 512*1024) memsize = 512*1024;
    } else usage();
  }   
+ #ifdef USE_MMU
+    phymem = malloc(memsize);
+    mem    = phymem + memsize - 0x10000 ;
+ #else
  #ifdef MSDOS
  if((mem=farmalloc(65535))==0) { 
    fprintf(stderr,"Not enough memory\n");
    exit(2);
  } 
  #endif
+ #endif
  read_image(); 
  if (setterm) set_term(escchar);
  pcreg=(mem[0xfffe]<<8)+mem[0xffff]; 
--- a/v09.h	Wed Jul 04 14:03:56 2018 +0900
+++ b/v09.h	Wed Jul 04 19:33:22 2018 +0900
@@ -18,12 +18,19 @@
 extern Word *dreg;
 extern Byte *breg,*areg;
 
+engine long memsize;
+engine Byte * mmu;
 /* 6809 memory space */
+#ifdef USE_MMU
+engine Byte * phymem;
+engine Byte * mem;
+#else
 #ifdef MSDOS
  engine Byte * mem;
 #else
  engine Byte mem[65536];
 #endif
+#endif
 
 engine volatile int tracing,attention,escape,irq;
 engine Word tracehi,tracelo;