--- /dev/null
+#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__ */
+
%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
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 ;
}
;
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");
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 */
/* 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;
}
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;
}
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;
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:
#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)
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;
}
{
emit2 ("!leavex", _G.stack.offset);
}
- else
+ else if( !FUNC_ISNAKED( sym->type )) /*.p.t.20030716 - now supporting Naked funcitons */
{
emit2 ("!leave");
}
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);
/* 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;
/* 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;
/* 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;
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);
}
}
}
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);
}
}
}
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);
}
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 */
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
"sfr",
"nonbanked",
"banked",
+ "at", //.p.t.20030714 adding support for 'sfr at ADDR' construct
+ "_naked", //.p.t.20030714 adding support for '_naked' functions
NULL
};
}
}
}
-
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;
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;
}
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 {
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
}
+
+
replace restart {
ld %1,%1
} by {
- ; Removed redundent load
+ ; Removed redundent load
}
replace restart {
xor a,a
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
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
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
ld %1,%2
ld %3,%4
}
+
{
Z80_SUB_PORT sub;
int calleeSavesBC;
+ int port_mode;
+ int port_back;
}
Z80_OPTS;