From 915e3f80069090c147c9eea0562958a78cbaf0d7 Mon Sep 17 00:00:00 2001 From: epetrich Date: Fri, 5 Dec 2003 06:37:18 +0000 Subject: [PATCH] Applied z80 i/o port patch from Peter Townson and fixed some operators 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 | 106 +++++++++++++++++++++++++++++ src/SDCC.y | 22 ++++-- src/SDCCglue.c | 8 ++- src/z80/gen.c | 154 ++++++++++++++++++++++++++++++++++-------- src/z80/gen.h | 8 ++- src/z80/main.c | 70 ++++++++++++------- src/z80/peeph-z80.def | 150 ++++++++++++++++++++++++++++++++++++---- src/z80/peeph.def | 37 ++++++---- src/z80/z80.h | 2 + 9 files changed, 464 insertions(+), 93 deletions(-) create mode 100644 device/include/z180.h diff --git a/device/include/z180.h b/device/include/z180.h new file mode 100644 index 00000000..334fb5a0 --- /dev/null +++ b/device/include/z180.h @@ -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__ */ + diff --git a/src/SDCC.y b/src/SDCC.y index aaee44ac..f4f3f0fb 100644 --- a/src/SDCC.y +++ b/src/SDCC.y @@ -105,7 +105,7 @@ bool uselessDecl = TRUE; %type declarator2_function_attributes while do for critical %type pointer type_specifier_list type_specifier type_name %type storage_class_specifier struct_or_union_specifier -%type declaration_specifiers sfr_reg_bit type_specifier2 +%type declaration_specifiers sfr_reg_bit sfr_attributes type_specifier2 %type function_attribute function_attributes enum_specifier %type abstract_declarator abstract_declarator2 unqualified_pointer %type 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 ; } ; diff --git a/src/SDCCglue.c b/src/SDCCglue.c index 4b636021..0347280d 100644 --- a/src/SDCCglue.c +++ b/src/SDCCglue.c @@ -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"); diff --git a/src/z80/gen.c b/src/z80/gen.c index e9b3302b..00ee1a68 100644 --- a/src/z80/gen.c +++ b/src/z80/gen.c @@ -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); } diff --git a/src/z80/gen.h b/src/z80/gen.h index 3e666177..40ccd0c9 100644 --- a/src/z80/gen.h +++ b/src/z80/gen.h @@ -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 */ diff --git a/src/z80/main.c b/src/z80/main.c index 3545430f..82b8a78d 100644 --- a/src/z80/main.c +++ b/src/z80/main.c @@ -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; } diff --git a/src/z80/peeph-z80.def b/src/z80/peeph-z80.def index 63c89a44..09d8e160 100644 --- a/src/z80/peeph-z80.def +++ b/src/z80/peeph-z80.def @@ -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 } + + diff --git a/src/z80/peeph.def b/src/z80/peeph.def index 7c48663c..1ff4aa80 100644 --- a/src/z80/peeph.def +++ b/src/z80/peeph.def @@ -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 } + diff --git a/src/z80/z80.h b/src/z80/z80.h index 020dbafb..043025f9 100644 --- a/src/z80/z80.h +++ b/src/z80/z80.h @@ -16,6 +16,8 @@ typedef struct { Z80_SUB_PORT sub; int calleeSavesBC; + int port_mode; + int port_back; } Z80_OPTS; -- 2.47.2