]> git.gag.com Git - fw/sdcc/commitdiff
Applied z80 i/o port patch from Peter Townson and fixed some operators
authorepetrich <epetrich@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Fri, 5 Dec 2003 06:37:18 +0000 (06:37 +0000)
committerepetrich <epetrich@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Fri, 5 Dec 2003 06:37:18 +0000 (06:37 +0000)
to better handle operands in A register.
* device/include/z180.h
* src/SDCC.y
* src/SDCCglue.c
* src/z80/gen.c
* src/z80/gen.h
* src/z80/main.c
* src/z80/peeph-z80.def
* src/z80/peeph.def
* src/z80/z80.h

git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@3040 4a8a32a2-be11-0410-ad9d-d568d2c75423

device/include/z180.h [new file with mode: 0644]
src/SDCC.y
src/SDCCglue.c
src/z80/gen.c
src/z80/gen.h
src/z80/main.c
src/z80/peeph-z80.def
src/z80/peeph.def
src/z80/z80.h

diff --git a/device/include/z180.h b/device/include/z180.h
new file mode 100644 (file)
index 0000000..334fb5a
--- /dev/null
@@ -0,0 +1,106 @@
+#if !defined( __Z180_H__ )
+    #define   __Z180_H__ 
+/*
+ *---------------------------------------------------------------------------
+ *
+ *  FILE   : Z180.H
+ *
+ *  PURPOSE: definitions on the built in I/O ports for the Z180/HD64180
+ *           for use with SDCC
+ *
+ *           Makes use of the newly included Z80 I/O support in SDCC
+ *
+ *  AUTHOR : Peter Townson 2003
+ *
+ *---------------------------------------------------------------------------
+ */
+#if !defined( Z180_IO_BASE )
+    #define   Z180_IO_BASE  0  /* zero is the Reset default */
+#endif
+
+/* will want this to be the case by default (I think) */
+#pragma portmode=z180
+
+static void _ENABLE_Z180_ASSEMBLER_(void) _naked { _asm .hd64 _endasm; }
+
+/*
+ *---------------------------------------------------------------------------
+ *      Z180/HD64180 internal port addresses
+ */
+sfr at (Z180_IO_BASE+0x00) CNTLA0;  /* ASCI control register A channel 0 */
+sfr at (Z180_IO_BASE+0x01) CNTLA1;  /* ASCI control register A channel 1 */
+sfr at (Z180_IO_BASE+0x02) CNTLB0;  /* ASCI control register B channel 0 */
+sfr at (Z180_IO_BASE+0x03) CNTLB1;  /* ASCI control register B channel 0 */
+sfr at (Z180_IO_BASE+0x04) STAT0 ;  /* ASCI status register    channel 0 */
+sfr at (Z180_IO_BASE+0x05) STAT1 ;  /* ASCI status register    channel 1 */
+sfr at (Z180_IO_BASE+0x06) TDR0  ;  /* ASCI transmit data reg, channel 0 */
+sfr at (Z180_IO_BASE+0x07) TDR1  ;  /* ASCI transmit data reg, channel 1 */
+sfr at (Z180_IO_BASE+0x08) RDR0  ;  /* ASCI receive data reg,  channel 0 */
+sfr at (Z180_IO_BASE+0x09) RDR1  ;  /* ASCI receive data reg,  channel 0 */
+sfr at (Z180_IO_BASE+0x0A) CNTR  ;  /* CSI/0 control register */
+sfr at (Z180_IO_BASE+0x0B) TRDR  ;  /* CSI/0 transmit/receive data reg */
+
+sfr at (Z180_IO_BASE+0x0C) TMDR0L;  /* Timer data register,    channel 0L */
+sfr at (Z180_IO_BASE+0x0D) TMDR0H;  /* Timer data register,    channel 0H */
+sfr at (Z180_IO_BASE+0x0E) RLDR0L;  /* Timer reload register,  channel 0L */
+sfr at (Z180_IO_BASE+0x0F) RLDR0H;  /* Timer reload register,  channel 0H */
+sfr at (Z180_IO_BASE+0x10) TCR   ;  /* Timer control register */
+sfr at (Z180_IO_BASE+0x14) TMDR1L;  /* Timer data register,    channel 1L */
+sfr at (Z180_IO_BASE+0x15) TMDR1H;  /* Timer data register,    channel 1H */
+sfr at (Z180_IO_BASE+0x16) RLDR1L;  /* Timer reload register,  channel 1L */
+sfr at (Z180_IO_BASE+0x17) RLDR1H;  /* Timer reload register,  channel 1H */
+sfr at (Z180_IO_BASE+0x18) FRC   ;  /* Timer Free running counter */
+
+sfr at (Z180_IO_BASE+0x20) SAR0L ;  /* DMA source address reg, channel 0L */
+sfr at (Z180_IO_BASE+0x21) SAR0H ;  /* DMA source address reg, channel 0H */
+sfr at (Z180_IO_BASE+0x22) SAR0B ;  /* DMA source address reg, channel 0B */
+sfr at (Z180_IO_BASE+0x23) DAR0L ;  /* DMA dest address reg,   channel 0L */
+sfr at (Z180_IO_BASE+0x24) DAR0H ;  /* DMA dest address reg,   channel 0H */
+sfr at (Z180_IO_BASE+0x25) DAR0B ;  /* DMA dest address reg,   channel 0B */
+sfr at (Z180_IO_BASE+0x26) BCR0L ;  /* DMA byte count reg,     channel 0L */
+sfr at (Z180_IO_BASE+0x27) BCR0H ;  /* DMA byte count reg,     channel 0H */
+sfr at (Z180_IO_BASE+0x28) MAR1L ;  /* DMA memory address reg, channel 1L */
+sfr at (Z180_IO_BASE+0x29) MAR1H ;  /* DMA memory address reg, channel 1H */
+sfr at (Z180_IO_BASE+0x2A) MAR1B ;  /* DMA memory address reg, channel 1B */
+sfr at (Z180_IO_BASE+0x2B) IAR1L ;  /* DMA I/O address reg,    channel 1L */
+sfr at (Z180_IO_BASE+0x2C) IAR1H ;  /* DMA I/O address reg,    channel 1H */
+sfr at (Z180_IO_BASE+0x2E) BCR1L ;  /* DMA byte count reg,     channel 1L */
+sfr at (Z180_IO_BASE+0x2F) BCR1H ;  /* DMA byte count reg,     channel 1H */
+sfr at (Z180_IO_BASE+0x30) DSTAT ;  /* DMA status register */
+sfr at (Z180_IO_BASE+0x31) DMODE ;  /* DMA mode register */
+sfr at (Z180_IO_BASE+0x32) DCNTL ;  /* DMA/WAIT control register */
+
+sfr at (Z180_IO_BASE+0x33) IL    ;  /* Interrupt vector low register */
+sfr at (Z180_IO_BASE+0x34) ITC   ;  /* INT/TRAP control register */
+
+sfr at (Z180_IO_BASE+0x36) RCR   ;  /* Refresh control register */
+
+sfr at (Z180_IO_BASE+0x38) CBR   ;  /* MMU common base register */
+sfr at (Z180_IO_BASE+0x39) BBR   ;  /* MMU bank base register */
+sfr at (Z180_IO_BASE+0x3A) CBAR  ;  /* MMU common/bank area register */
+
+sfr at (Z180_IO_BASE+0x3E) OMCR  ;  /* Operation mode control register */
+
+sfr at               0x3F  ICR   ;  /* I/O base control register - does not move */
+
+/*
+ *---------------------------------------------------------------------------
+ *      Interrupt vectors (offsets) for Z180/HD64180 internal interrupts
+ */
+#define INT1_VECTOR     0x00    /* external /INT1 */
+#define INT2_VECTOR     0x02    /* external /INT2 */
+#define PRT0_VECTOR     0x04    /* PRT channel 0 */
+#define PRT1_VECTOR     0x06    /* PRT channel 1 */
+#define DMA0_VECTOR     0x08    /* DMA channel 0 */ /* ???? */
+#define DMA1_VECTOR     0x0A    /* DMA Channel 1 */
+#define CSIO_VECTOR     0x0C    /* Clocked serial I/O */
+#define ASCI0_VECTOR    0x0E    /* Async channel 0 */
+#define ASCI1_VECTOR    0x10    /* Async channel 1 */
+#define INCAP_VECTOR    0x12    /* input capture */
+#define OUTCMP_VECTOR   0x14    /* output compare */
+#define TIMOV_VECTOR    0x16    /* timer overflow */
+/*
+ *---------------------------------------------------------------------------
+ */
+#endif  /* __Z180_H__ */
+
index aaee44acb5b22e6710ba173db6133b08bc60db42..f4f3f0fb301fdb6d11c90869bbb4d3e516dc50c9 100644 (file)
@@ -105,7 +105,7 @@ bool uselessDecl = TRUE;
 %type <sym> declarator2_function_attributes while do for critical
 %type <lnk> pointer type_specifier_list type_specifier type_name
 %type <lnk> storage_class_specifier struct_or_union_specifier
-%type <lnk> declaration_specifiers  sfr_reg_bit type_specifier2
+%type <lnk> declaration_specifiers sfr_reg_bit sfr_attributes type_specifier2
 %type <lnk> function_attribute function_attributes enum_specifier
 %type <lnk> abstract_declarator abstract_declarator2 unqualified_pointer
 %type <val> parameter_type_list parameter_list parameter_declaration opt_assign_expr
@@ -686,11 +686,23 @@ sfr_reg_bit
                SPEC_NOUN($$) = V_SBIT;
                SPEC_SCLS($$) = S_SBIT;
             }
-   |  SFR   {
+   |  sfr_attributes
+   ;
+
+sfr_attributes
+   : SFR    {
+               $$ = newLink(SPECIFIER) ;
+               FUNC_REGBANK($$) = 0;
+               SPEC_NOUN($$)    = V_CHAR;
+               SPEC_SCLS($$)    = S_SFR ;
+               SPEC_USIGN($$)   = 1 ;
+            }
+   | SFR BANKED {
                $$ = newLink(SPECIFIER) ;
-               SPEC_NOUN($$) = V_CHAR;
-               SPEC_SCLS($$) = S_SFR ;
-              SPEC_USIGN($$) = 1 ;
+               FUNC_REGBANK($$) = 1;
+               SPEC_NOUN($$)    = V_CHAR;
+               SPEC_SCLS($$)    = S_SFR ;
+               SPEC_USIGN($$)   = 1 ;
             }
    ;
 
index 4b63602144e1d771f7f06f0e5424b52f012408a4..0347280d6f284fcd9356ddcf18a25997d27097c4 100644 (file)
@@ -1657,14 +1657,18 @@ glue (void)
   if (port->assembler.externGlobal)
     printExterns (asmFile);
 
-  if(mcs51_like)
+  if(( mcs51_like )
+   ||( TARGET_IS_Z80 )) /*.p.t.20030924 need to output SFR table for Z80 as well */
   {
       /* copy the sfr segment */
       fprintf (asmFile, "%s", iComments2);
       fprintf (asmFile, "; special function registers\n");
       fprintf (asmFile, "%s", iComments2);
       copyFile (asmFile, sfr->oFile);
-
+  }
+  
+  if(mcs51_like)
+  {
       /* copy the sbit segment */
       fprintf (asmFile, "%s", iComments2);
       fprintf (asmFile, "; special function bits \n");
index e9b3302b73642afb8922c51d0a4763b158635b14..00ee1a68ae2bac398f493743eda15a60f8be5630 100644 (file)
@@ -790,18 +790,34 @@ aopForSym (iCode * ic, symbol * sym, bool result, bool requires_a)
       return aop;
     }
 
-  if (IS_GB)
+  if( IN_REGSP( space ))
+  { /*.p.t.20030716 minor restructure to add SFR support to the Z80 */
+    if (IS_GB)
     {
       /* if it is in direct space */
-      if (IN_REGSP (space) && !requires_a)
-       {
-         sym->aop = aop = newAsmop (AOP_SFR);
-         aop->aopu.aop_dir = sym->rname;
-         aop->size = getSize (sym->type);
+      if( !requires_a )
+      {
+        sym->aop = aop = newAsmop (AOP_SFR);
+        aop->aopu.aop_dir = sym->rname;
+        aop->size = getSize (sym->type);
          emitDebug ("; AOP_SFR for %s", sym->rname);
-         return aop;
-       }
+        return aop;
+      }
+    }
+    else
+    { /*.p.t.20030716 adding SFR support to the Z80 port */
+      aop = newAsmop (AOP_SFR);
+      sym->aop          = aop;
+      aop->aopu.aop_dir = sym->rname;
+      aop->size         = getSize( sym->type );
+      aop->paged        = FUNC_REGBANK(sym->type);
+      aop->bcInUse      = isPairInUse( PAIR_BC, ic );
+      aop->deInUse      = isPairInUse( PAIR_DE, ic );
+      emitDebug( ";Z80 AOP_SFR for %s banked:%d bc:%d de:%d", sym->rname, FUNC_REGBANK(sym->type), aop->bcInUse, aop->deInUse );
+
+      return( aop );
     }
+  }
 
   /* only remaining is far space */
   /* in which case DPTR gets the address */
@@ -994,6 +1010,11 @@ aopOp (operand * op, iCode * ic, bool result, bool requires_a)
   /* if already has a asmop then continue */
   if (op->aop)
     {
+      if (op->aop->type == AOP_SFR)
+        {
+          op->aop->bcInUse = isPairInUse( PAIR_BC, ic );
+          op->aop->deInUse = isPairInUse( PAIR_DE, ic );
+        }
       return;
     }
 
@@ -1001,6 +1022,11 @@ aopOp (operand * op, iCode * ic, bool result, bool requires_a)
   if (IS_SYMOP (op) && OP_SYMBOL (op)->aop)
     {
       op->aop = OP_SYMBOL (op)->aop;
+      if (op->aop->type == AOP_SFR)
+        {
+          op->aop->bcInUse = isPairInUse( PAIR_BC, ic );
+          op->aop->deInUse = isPairInUse( PAIR_DE, ic );
+        }
       return;
     }
 
@@ -1646,11 +1672,41 @@ aopGet (asmop * aop, int offset, bool bit16)
       return traceAlloc(&_G.trace.aops, Safe_strdup(buffer));
 
     case AOP_SFR:
-      wassert (IS_GB);
-      emit2 ("ldh a,(%s+%d)", aop->aopu.aop_dir, offset);
-      SNPRINTF (buffer, sizeof(buffer), "a");
+      if( IS_GB )
+      {
+        // wassert (IS_GB);
+        emit2 ("ldh a,(%s+%d)", aop->aopu.aop_dir, offset);
+        SNPRINTF (buffer, sizeof(buffer), "a");
 
-      return traceAlloc(&_G.trace.aops, Safe_strdup(buffer));
+        return traceAlloc(&_G.trace.aops, Safe_strdup(buffer));
+      }
+      else
+      { /*.p.t.20030716 handling for i/o port read access for Z80 */
+        if( aop->paged )
+        { /* banked mode */
+          if( aop->bcInUse )  emit2( "push bc" );
+
+          emit2( "ld bc,#%s", aop->aopu.aop_dir );
+          emit2( "in a,(c)" );
+
+          if( aop->bcInUse )
+            emit2( "pop bc" );
+          else
+            spillPair (PAIR_BC);
+        }
+        else if( z80_opts.port_mode == 180 )
+        { /* z180 in0/out0 mode */
+          emit2( "in0 a,(%s)", aop->aopu.aop_dir );
+        }
+        else
+        { /* 8 bit mode */
+          emit2( "in a,(%s)", aop->aopu.aop_dir );
+        }
+        
+        SNPRINTF (buffer, sizeof(buffer), "a");
+
+        return traceAlloc(&_G.trace.aops, Safe_strdup(buffer));
+      }
 
     case AOP_REG:
       return aop->aopu.aop_reg[offset]->name;
@@ -1815,10 +1871,49 @@ aopPut (asmop * aop, const char *s, int offset)
       break;
 
     case AOP_SFR:
-      wassert (IS_GB);
-      if (strcmp (s, "a"))
-       emit2 ("ld a,%s", s);
-      emit2 ("ldh (%s+%d),a", aop->aopu.aop_dir, offset);
+      if( IS_GB )
+      {
+        //  wassert (IS_GB);
+        if (strcmp (s, "a"))
+          emit2 ("ld a,%s", s);
+        emit2 ("ldh (%s+%d),a", aop->aopu.aop_dir, offset);
+      }
+      else
+      { /*.p.t.20030716 handling for i/o port read access for Z80 */
+        if( aop->paged )
+        { /* banked mode */
+          if( aop->bcInUse )  emit2( "push bc" );
+
+          emit2( "ld bc,#%s", aop->aopu.aop_dir );
+
+          if(( s[0] == '#'    ) /* immediate number */
+           ||( s[0] == '('    ) /* indirect register (ix or iy ??)*/
+           ||( isdigit( s[0] )))/* indirect register with offset (ix or iy ??)*/
+          {
+            emit2( "ld a,%s", s );
+            emit2( "out (c),a"  );
+          }
+          else
+          {
+            emit2( "out (c),%s", s );
+          }
+        
+          if( aop->bcInUse )
+            emit2( "pop bc"    );
+          else
+            spillPair (PAIR_BC);
+        }
+        else if( z80_opts.port_mode == 180 )
+        { /* z180 in0/out0 mode */
+          emit2( "ld a,%s", s );
+          emit2( "out0 (%s),a", aop->aopu.aop_dir );
+        }
+        else
+        { /* 8 bit mode */
+          emit2( "ld a,%s", s );
+          emit2( "out (%s),a", aop->aopu.aop_dir );
+        }
+      }
       break;
 
     case AOP_REG:
@@ -1974,7 +2069,7 @@ aopPut (asmop * aop, const char *s, int offset)
 #define AOP(op) op->aop
 #define AOP_TYPE(op) AOP(op)->type
 #define AOP_SIZE(op) AOP(op)->size
-#define AOP_NEEDSACC(x) (AOP(x) && (AOP_TYPE(x) == AOP_CRY))
+#define AOP_NEEDSACC(x) (AOP(x) && ((AOP_TYPE(x) == AOP_CRY) || (AOP_TYPE(x) == AOP_SFR)))
 
 static void
 commitPair (asmop * aop, PAIR_ID id)
@@ -3102,8 +3197,9 @@ genFunction (iCode * ic)
     emit2 ("!enterxl", sym->stack);
   else if (sym->stack)
     emit2 ("!enterx", sym->stack);
-  else
+  else if( !FUNC_ISNAKED( sym->type )) /*.p.t.20030716 - now supporting Naked funcitons */
     emit2 ("!enter");
+
   _G.stack.offset = sym->stack;
 }
 
@@ -3139,7 +3235,7 @@ genEndFunction (iCode * ic)
         {
           emit2 ("!leavex", _G.stack.offset);
         }
-      else
+      else if( !FUNC_ISNAKED( sym->type )) /*.p.t.20030716 - now supporting Naked funcitons */
         {
           emit2 ("!leave");
         }
@@ -3535,7 +3631,7 @@ genPlus (iCode * ic)
      in ACC */
 
   if ((AOP_TYPE (IC_LEFT (ic)) == AOP_LIT) ||
-      (AOP_NEEDSACC (IC_LEFT (ic))) ||
+      (AOP_NEEDSACC (IC_RIGHT (ic))) ||
       AOP_TYPE (IC_RIGHT (ic)) == AOP_ACC)
     {
       operand *t = IC_RIGHT (ic);
@@ -4901,7 +4997,7 @@ genAnd (iCode * ic, iCode * ifx)
 
   /* if left is a literal & right is not then exchange them */
   if ((AOP_TYPE (left) == AOP_LIT && AOP_TYPE (right) != AOP_LIT) ||
-      AOP_NEEDSACC (left))
+      (AOP_NEEDSACC (right) && !AOP_NEEDSACC (left)))
     {
       operand *tmp = right;
       right = left;
@@ -5091,7 +5187,7 @@ genOr (iCode * ic, iCode * ifx)
 
   /* if left is a literal & right is not then exchange them */
   if ((AOP_TYPE (left) == AOP_LIT && AOP_TYPE (right) != AOP_LIT) ||
-      AOP_NEEDSACC (left))
+      (AOP_NEEDSACC (right) && !AOP_NEEDSACC (left)))
     {
       operand *tmp = right;
       right = left;
@@ -5249,7 +5345,7 @@ genXor (iCode * ic, iCode * ifx)
 
   /* if left is a literal & right is not then exchange them */
   if ((AOP_TYPE (left) == AOP_LIT && AOP_TYPE (right) != AOP_LIT) ||
-      AOP_NEEDSACC (left))
+      (AOP_NEEDSACC (right) && !AOP_NEEDSACC (left)))
     {
       operand *tmp = right;
       right = left;
@@ -5326,9 +5422,9 @@ genXor (iCode * ic, iCode * ifx)
                continue;
              else
                {
-                 _moveA (aopGet (AOP (right), offset, FALSE));
+                 _moveA (aopGet (AOP (left), offset, FALSE));
                  emit2 ("xor a,%s",
-                           aopGet (AOP (left), offset, FALSE));
+                           aopGet (AOP (right), offset, FALSE));
                  aopPut (AOP (result), "a", offset);
                }
            }
@@ -5340,9 +5436,9 @@ genXor (iCode * ic, iCode * ifx)
                 }
              else
                {
-                 _moveA (aopGet (AOP (right), offset, FALSE));
+                 _moveA (aopGet (AOP (left), offset, FALSE));
                  emit2 ("xor a,%s",
-                           aopGet (AOP (left), offset, FALSE));
+                           aopGet (AOP (right), offset, FALSE));
                  aopPut (AOP (result), "a", offset);
                }
            }
@@ -5378,9 +5474,9 @@ genXor (iCode * ic, iCode * ifx)
               }
            else
              {
-               _moveA (aopGet (AOP (right), offset, FALSE));
+               _moveA (aopGet (AOP (left), offset, FALSE));
                emit2 ("xor a,%s",
-                         aopGet (AOP (left), offset, FALSE));
+                         aopGet (AOP (right), offset, FALSE));
              }
            aopPut (AOP (result), "a", offset);
          }
index 3e666177e8adf28cdb6461a2619f43928fa73df4..40ccd0c940c7945a5aa78e89173a581753cdc4b5 100644 (file)
@@ -71,9 +71,11 @@ typedef struct asmop
     AOP_TYPE type;
     short coff;                 /* current offset */
     short size;                 /* total size */
-    bool code;                  /* is in Code space */
-    bool paged;                 /* in paged memory  */
-    bool freed;                 /* already freed    */
+    unsigned  code:1;               /* is in Code space */
+    unsigned  paged:1;              /* in paged memory  */
+    unsigned  freed:1;              /* already freed    */
+    unsigned  bcInUse:1;
+    unsigned  deInUse:1;
     union
       {
         value *aop_lit;         /* if literal */
index 3545430f3500f6351e94603041991bd5535e5cec..82b8a78d5d23084df9efe554dbf6348ea984e350 100644 (file)
@@ -45,8 +45,9 @@ Z80_OPTS z80_opts;
 
 static OPTION _z80_options[] = 
   {
-    { 0,   "--callee-saves-bc", &z80_opts.calleeSavesBC, "Force a called function to always save BC" },
-    { 0, NULL }
+    {  0,   "--callee-saves-bc", &z80_opts.calleeSavesBC, "Force a called function to always save BC" },
+    { 80,   "--portmode",        &z80_opts.port_mode,     "Determine PORT I/O mode (z80/z180)" },
+    {  0, NULL }
   };
 
 typedef enum
@@ -72,6 +73,8 @@ static char *_keywords[] =
   "sfr",
   "nonbanked",
   "banked",
+  "at",       //.p.t.20030714 adding support for 'sfr at ADDR' construct
+  "_naked",   //.p.t.20030714 adding support for '_naked' functions
   NULL
 };
 
@@ -127,33 +130,32 @@ _reg_parm (sym_link * l)
         }
     }
 }
-
 static int
 _process_pragma (const char *sz)
 {
-  if (startsWith (sz, "bank="))
+  if( startsWith( sz, "bank=" ))
+  {
+    char buffer[128];
+    strcpy (buffer, sz + 5);
+    chomp (buffer);
+    if (isdigit (buffer[0]))
     {
-      char buffer[128];
-      strcpy (buffer, sz + 5);
-      chomp (buffer);
-      if (isdigit (buffer[0]))
-       {
 
-       }
-      else if (!strcmp (buffer, "BASE"))
-       {
-         strcpy (buffer, "HOME");
-       }
-      if (isdigit (buffer[0]))
-       {
+    }
+    else if (!strcmp (buffer, "BASE"))
+    {
+      strcpy (buffer, "HOME");
+    }
+    if (isdigit (buffer[0]))
+    {
          /* Arg was a bank number.  Handle in an ASM independent
             way. */
-         char num[128];
-         strcpy (num, sz + 5);
-         chomp (num);
+      char num[128];
+      strcpy (num, sz + 5);
+      chomp (num);
 
-         switch (_G.asmType)
-           {
+      switch (_G.asmType)
+      {
            case ASM_TYPE_ASXXXX:
              sprintf (buffer, "CODE_%s", num);
              break;
@@ -166,12 +168,28 @@ _process_pragma (const char *sz)
              break;
            default:
              wassert (0);
-           }
-       }
-      gbz80_port.mem.code_name = Safe_strdup (buffer);
-      code->sname = gbz80_port.mem.code_name;
-      return 0;
+      }
     }
+    gbz80_port.mem.code_name = Safe_strdup (buffer);
+    code->sname = gbz80_port.mem.code_name;
+    return 0;
+  }
+  else if( startsWith( sz, "portmode=" ))
+  { /*.p.t.20030716 - adding pragma to manipulate z80 i/o port addressing modes */
+    char bfr[128];
+
+    strcpy( bfr, sz + 9 );
+    chomp( bfr );
+
+    if     ( !strcmp( bfr, "z80"     )){ z80_opts.port_mode =  80; }
+    else if( !strcmp( bfr, "z180"    )){ z80_opts.port_mode = 180; }
+    else if( !strcmp( bfr, "save"    )){ z80_opts.port_back = z80_opts.port_mode; }
+    else if( !strcmp( bfr, "restore" )){ z80_opts.port_mode = z80_opts.port_back; }
+    else                                 return( 1 );
+
+    return( 0 );
+  }
+
   return 1;
 }
 
index 63c89a44e18ccf4087ba132d937af645417b868b..09d8e160bf9de11df6b80cad7aec0789b4be567d 100644 (file)
@@ -7,20 +7,20 @@ replace restart {
        jp      %4,%5
 }
 replace {
-       ld      %1,%2)
-       ld      a,%2)
+       ld      %1,%2
+       ld      a,%2
 } by {
-        ld      %1,%2)
-        ld      a,%1
+       ld      %1,%2
+       ld      a,%1
 }
 replace {
-       ld      %1),a
+       ld      %1,a
        xor     a,a
-       or      a,%1)
+       or      a,%1
        jp      z,%2
 } by {
-        ld      %1),a
-        or      a,a
+       ld      %1,a
+       or      a,a
        jp      z,%2
 }
 replace {
@@ -29,17 +29,141 @@ replace {
        rla
 } by {
        rlca
-        and     a,#0x01
+       and     a,#0x01
 }
 replace {
        ld      %3,a
-       ld      l,%1)
-       ld      h,%2)
+       ld      l,%1
+       ld      h,%2
        ld      l,(hl)
        ld      a,%3
 } by {
        ld      %3,a
-       ld      l,%1)
-       ld      h,%2)
+       ld      l,%1
+       ld      h,%2
        ld      l,(hl)
+} if notVolatile %3
+
+;
+;--------------------------
+;
+replace restart {
+       pop     %1
+       push    %1
+       ld      %1,%2
+} by {
+       ;       z80 removed redundant pop/push
+       ld      %1,%2
+}
+;
+;replace restart {
+       ld      a,%1
+       add     a,#0x01
+       ld      l,a
+} by {
+       ;       z80 improved usage of 'inc'
+       ld      l,%1
+       inc     l
+       ld      a,l
+}
+
+replace restart {
+       ld      a,%1
+       add     a,#0xFF
+       ld      l,a
+} by {
+       ;       z80 improved usage of 'dec'
+       ld      l,%1
+       dec     l
+       ld      a,l
+}
+
+replace restart {
+       ld      l,a
+       ld      c,%1
+       ld      a,l
+} by {
+       ld      l,a
+       ld      c,%1
+}
+
+replace restart {
+       ld      c,l
+       ld      a,c
+       and     a,#%1
+       ld      c,a
+       or      a,a
+} by {
+       ;       z80 stream lining 'and' logic
+       ld      a,#%1
+       and     a,l
+       ld      c,a
+}
+
+replace restart {
+       ld      a,c
+       and     a,#%1
+       ld      c,a
+       or      a,a
+} by {
+       ;       z80 stream lining 'and' logic
+       ld      a,#%1
+       and     a,c
+       ld      c,a
+}
+
+replace restart {
+       ld      a,c
+       or      a,#%1
+       ld      c,a
+} by {
+       ;       z80 stream lining 'or' logic
+       ld      a,#%1
+       or      a,c
+       ld      c,a
+}
+
+; I don't think this works. neg does a unary minus of A, not HL  -- EEP
+;
+;replace {
+;      ld      a,c
+;      sub     a,%1
+;      ld      l,a
+;      ld      a,b
+;      sbc     a,%2
+;      ld      h,a
+;} by {
+;      ;       z80/z180 peephole byte pointer subtraction
+;      xor     a
+;      ld      h,%1
+;      ld      l,%2
+;      sbc     hl,bc
+;      neg
+;}
+
+replace {
+%1:
+       in0     a,(%2)
+       and     a,#%3
+       jp      z,%4
+%5:
+       jp      %6
+%4:
+       call    %7
+       jp      %1
+%6:
+       ret
+} by {
+%1:
+       in0     a,(%2)
+       and     a,#%3
+       jp      nz,%5
+%4:
+       call    %7
+       jp      %1
+%5:
+%6:
+       ret
 }
+
+
index 7c48663c27ce2a4ecab24826f32d1e33a166d7ea..1ff4aa80724b561c4a236ad278e6d9154edc894d 100644 (file)
@@ -6,7 +6,7 @@ replace {
 replace restart {
        ld %1,%1
 } by {
-        ; Removed redundent load
+       ; Removed redundent load
 }
 replace restart {
        xor a,a
@@ -94,26 +94,32 @@ replace restart {
        xor     a,a
        ld      a,#0x00
 } by {
-        xor     a,a
+       xor     a,a
 }
 replace {
-        ld      e,#0x00
-        ld      d,#0x00
+       ld      e,#0x00
+       ld      d,#0x00
 } by {
-        ld      de,#0x0000
+       ld      de,#0x0000
 }
 replace {
        ld      l,#0x00
        ld      h,#0x00
 } by {
-        ld      hl,#0x0000
+       ld      hl,#0x0000
+}
+replace {
+       ld      c,#0x00
+       ld      b,#0x00
+} by {
+       ld      bc,#0x0000
 }
 replace restart {
        ld      %1,a
        ld      a,%1
 } by {
-        ld     %1,a
-}
+       ld      %1,a
+} if notVolatile %1
 replace restart {
        jp      %1,%2
        jr      %3
@@ -133,14 +139,14 @@ replace {
        ld      h,b
        push    hl
 } by {
-        push   de
-        push    bc
+       push    de
+       push    bc
 }
 replace {
        and     a,#%1
        or      a,a
 } by {
-        and     a,#%1
+       and     a,#%1
 }
 replace {
        ld      b,l
@@ -167,16 +173,16 @@ replace {
        push    af
        inc     sp
 } by {
-        push    bc
-        inc     sp
+       push    bc
+       inc     sp
 }
 replace {
        ld      a,d
        push    af
        inc     sp
 } by {
-        push    de
-        inc     sp
+       push    de
+       inc     sp
 }
 replace {
        ld      a,%1
@@ -210,3 +216,4 @@ replace {
        ld      %1,%2
        ld      %3,%4
 }
+
index 020dbafb918cc4170f05aeb3d5bbcec176391c73..043025f9f3dea39ea99104051e194e0ae3488ac6 100644 (file)
@@ -16,6 +16,8 @@ typedef struct
   {
     Z80_SUB_PORT sub;
     int calleeSavesBC;
+    int port_mode;
+    int port_back;
   }
 Z80_OPTS;