From: bernhardheld Date: Sun, 4 Nov 2001 21:09:53 +0000 (+0000) Subject: * sdcc/sim/ucsim/s51.src/uc390cl.h: Improvement for ds390 to run regression tests X-Git-Url: https://git.gag.com/?a=commitdiff_plain;h=ce5fa739043ecbb50518db6bb7f0a415df0e776d;p=fw%2Fsdcc * sdcc/sim/ucsim/s51.src/uc390cl.h: Improvement for ds390 to run regression tests * sdcc/sim/ucsim/s51.src/uc390.h: Improvement for ds390 to run regression tests * sdcc/sim/ucsim/s51.src/regs51.h: Improvement for ds390 to run regression tests * sdcc/sim/ucsim/s51.src/glob.cc: Improvement for ds390 to run regression tests * sdcc/support/regression/tests/bug-460010.c: Small change for ds390 git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@1501 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- diff --git a/ChangeLog b/ChangeLog index 141bbd52..6922a4a2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2001-11-04 Bernhard Held + + * sdcc/sim/ucsim/s51.src/uc390cl.h: Improvement for ds390 to run regression tests + + * sdcc/sim/ucsim/s51.src/uc390.h: Improvement for ds390 to run regression tests + + * sdcc/sim/ucsim/s51.src/regs51.h: Improvement for ds390 to run regression tests + + * sdcc/sim/ucsim/s51.src/glob.cc: Improvement for ds390 to run regression tests + + * sdcc/support/regression/tests/bug-460010.c: Small change for ds390 + 2001-11-04 Michael Hope * src/z80/peeph-gbz80.def: Removed a bad sub optimisation. diff --git a/sim/ucsim/s51.src/glob.cc b/sim/ucsim/s51.src/glob.cc index 5baf152a..cd3f47a8 100644 --- a/sim/ucsim/s51.src/glob.cc +++ b/sim/ucsim/s51.src/glob.cc @@ -308,6 +308,7 @@ struct name_entry sfr_tab51[]= {CPU_ALL_51|CPU_ALL_52|CPU_251, 0x81, "SP"}, {CPU_ALL_51|CPU_ALL_52|CPU_251, 0x82, "DPL"}, {CPU_ALL_51|CPU_ALL_52|CPU_251, 0x83, "DPH"}, + {CPU_251|CPU_DS390F, 0x93, "DPX"}, {CPU_ALL_51|CPU_ALL_52|CPU_251, 0x80, "P0"}, {CPU_ALL_51|CPU_ALL_52|CPU_251, 0x90, "P1"}, {CPU_ALL_51|CPU_ALL_52|CPU_251, 0xa0, "P2"}, @@ -321,7 +322,9 @@ struct name_entry sfr_tab51[]= {CPU_ALL_51|CPU_ALL_52|CPU_251, 0x8d, "TH1"}, {CPU_ALL_51|CPU_ALL_52|CPU_251, 0x8b, "TL1"}, {CPU_ALL_51|CPU_ALL_52|CPU_251, 0x98, "SCON"}, - {CPU_ALL_51|CPU_ALL_52|CPU_251, 0x99, "SBUF"}, + {CPU_ALL_51|CPU_ALL_52, 0x99, "SBUF"}, + {CPU_251, 0x99, "SBUF0"}, + {CPU_251, 0xC1, "SBUF1"}, {CPU_ALL_51|CPU_ALL_52|CPU_251, 0x87, "PCON"}, {CPU_ALL_52|CPU_251, 0xc8, "T2CON"}, {CPU_ALL_52|CPU_251, 0xcd, "TH2"}, @@ -362,7 +365,9 @@ struct name_entry sfr_tab51[]= {CPU_89C51R|CPU_251, 0xfc, "CCAP2H"}, {CPU_89C51R|CPU_251, 0xfd, "CCAP3H"}, {CPU_89C51R|CPU_251, 0xfe, "CCAP4H"}, - {CPU_89C51R, 0xa2, "AUXR1"}, + {CPU_89C51R, 0xa2, "AUXR1"}, + {CPU_DS390F, 0x9B, "ESP"}, + {CPU_DS390F, 0x9D, "ACON"}, {0, 0, NULL} }; diff --git a/sim/ucsim/s51.src/regs51.h b/sim/ucsim/s51.src/regs51.h index 247ecefe..4155c1a0 100644 --- a/sim/ucsim/s51.src/regs51.h +++ b/sim/ucsim/s51.src/regs51.h @@ -65,6 +65,10 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #define DPL1 0x84 /* 2nd Data Pointer Low byte */ #define DPH1 0x85 /* 2nd Data Pointer High byte */ #define DPS 0x86 /* DPS 1H=DPTR is DPL1/DPH1,... */ +#define DPX 0x93 /* Data Pointer HHigh byte */ +#define DPX1 0x95 /* Data Pointer HHigh byte */ +#define ESP 0x9B /* Extended Stack Pointer */ +#define ACON 0x9D /* */ #define WDTRST 0xa6 /* */ #define IE0 0xa8 /* */ #define SADDR 0xa9 /* */ @@ -75,6 +79,11 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #define SPH 0xbd /* */ #define T2MOD 0xc9 /* */ #define PSW1 0xd1 /* */ +#define MCNT0 0xd1 +#define MCNT1 0xd2 +#define MA 0xd3 /* MA register from math accelerator */ +#define MB 0xd4 /* MA register from math accelerator */ +#define MC 0xd5 /* MA register from math accelerator */ #define CCON 0xd8 /* */ #define CMOD 0xd9 /* */ #define CCAPM0 0xda /* */ diff --git a/sim/ucsim/s51.src/uc390.cc b/sim/ucsim/s51.src/uc390.cc index 38531068..5fbfb867 100644 --- a/sim/ucsim/s51.src/uc390.cc +++ b/sim/ucsim/s51.src/uc390.cc @@ -2,7 +2,7 @@ * Simulator of microcontrollers (uc390.cc) * * Copyright (C) 1999,99 Drotos Daniel, Talker Bt. - * + * * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu * * uc390.cc - module created by Karl Bongers 2001, karl@turbobit.com @@ -30,6 +30,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include #include +#include #include "i_string.h" #include "glob.h" @@ -39,8 +40,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA /* * Names of instructions */ - -struct dis_entry disass_390f[]= { + +struct dis_entry disass_390f[] = { { 0x00, 0xff, ' ', 1, "NOP"}, { 0x01, 0xff, 'A', 3, "AJMP %A"}, { 0x02, 0xff, 'L', 4, "LJMP %l"}, @@ -75,7 +76,7 @@ struct dis_entry disass_390f[]= { { 0x1f, 0xff, ' ', 1, "DEC R7"}, { 0x20, 0xff, 'R', 3, "JB %b,%R"}, { 0x21, 0xff, 'A', 3, "AJMP %A"}, - { 0x22, 0xff, '_', 1, "RET"}, + { 0x22, 0xff, '_', 1, "RET"}, { 0x23, 0xff, ' ', 1, "RL A"}, { 0x24, 0xff, ' ', 2, "ADD A,#%d"}, { 0x25, 0xff, ' ', 2, "ADD A,%a"}, @@ -91,7 +92,7 @@ struct dis_entry disass_390f[]= { { 0x2f, 0xff, ' ', 1, "ADD A,R7"}, { 0x30, 0xff, 'R', 3, "JNB %b,%R"}, { 0x31, 0xff, 'a', 3, "ACALL %A"}, - { 0x32, 0xff, '_', 1, "RETI"}, + { 0x32, 0xff, '_', 1, "RETI"}, { 0x33, 0xff, ' ', 1, "RLC A"}, { 0x34, 0xff, ' ', 2, "ADDC A,#%d"}, { 0x35, 0xff, ' ', 2, "ADDC A,%a"}, @@ -185,7 +186,7 @@ struct dis_entry disass_390f[]= { { 0x8d, 0xff, ' ', 2, "MOV %a,R5"}, { 0x8e, 0xff, ' ', 2, "MOV %a,R6"}, { 0x8f, 0xff, ' ', 2, "MOV %a,R7"}, - { 0x90, 0xff, ' ', 4, "MOV DPTR,#%6"}, + { 0x90, 0xff, ' ', 4, "MOV DPTR,#%l"}, { 0x91, 0xff, 'a', 3, "ACALL %A"}, { 0x92, 0xff, ' ', 2, "MOV %b,C"}, { 0x93, 0xff, ' ', 1, "MOVC A,@A+DPTR"}, @@ -233,7 +234,7 @@ struct dis_entry disass_390f[]= { { 0xbd, 0xff, 'R', 3, "CJNE R5,#%d,%R"}, { 0xbe, 0xff, 'R', 3, "CJNE R6,#%d,%R"}, { 0xbf, 0xff, 'R', 3, "CJNE R7,#%d,%R"}, - { 0xc0, 0xff, ' ', 2, "PUSH %a"}, + { 0xc0, 0xff, ' ', 2, "PUSH %a"}, { 0xc1, 0xff, 'A', 3, "AJMP %A"}, { 0xc2, 0xff, ' ', 2, "CLR %b"}, { 0xc3, 0xff, ' ', 1, "CLR C"}, @@ -249,7 +250,7 @@ struct dis_entry disass_390f[]= { { 0xcd, 0xff, ' ', 1, "XCH A,R5"}, { 0xce, 0xff, ' ', 1, "XCH A,R6"}, { 0xcf, 0xff, ' ', 1, "XCH A,R7"}, - { 0xd0, 0xff, ' ', 2, "POP %a"}, + { 0xd0, 0xff, ' ', 2, "POP %a"}, { 0xd1, 0xff, 'a', 3, "ACALL %A"}, { 0xd2, 0xff, ' ', 2, "SETB %b"}, { 0xd3, 0xff, ' ', 1, "SETB C"}, @@ -304,15 +305,153 @@ struct dis_entry disass_390f[]= { * Making an 390 CPU object */ -t_uc390::t_uc390(int Itype, int Itech, class cl_sim *asim): - t_uc52(Itype, Itech, asim) +t_uc390::t_uc390 (int Itype, int Itech, class cl_sim *asim): + t_uc52 (Itype, Itech, asim) +{ + if (Itype == CPU_DS390F) + { + printf ("FLAT24 MODE SET, warning: experimental code\n"); + flat24_flag = 1; + } +} + + // strcpy (mem(MEM_ROM) ->addr_format, "0x%06x"); + // strcpy (mem(MEM_XRAM)->addr_format, "0x%06x"); + +t_addr +t_uc390::get_mem_size (enum mem_class type) +{ + //if ((sfr->get (ACON) & 0x3) == 2) + if (!flat24_flag) + return t_uc52::get_mem_size (type); + switch (type) + { + case MEM_ROM: + return 128*1024; // 4*1024*1024; 4 Meg possible + case MEM_XRAM: + return 128*1024 + 1024; // 4*1024*1024 + 1024; 4 Meg + 1k possible + case MEM_IRAM: + return 256; + case MEM_SFR: + return 256; + case MEM_TYPES: + default: + return 0; + } + return 0; +} + +ulong +t_uc390::read_mem(enum mem_class type, t_mem addr) +{ + //if ((sfr->get (ACON) & 0x3) == 2) + + if (type == MEM_XRAM && + flat24_flag && + addr >= 0x400000) + addr -= 0x400000 - get_mem_size (MEM_XRAM) + 1024; +/* + addr -= 0x400000; + addr += get_mem_size (MEM_XRAM); + addr -= 1024; +*/ + return t_uc51::read_mem (type, addr); +} + +ulong +t_uc390::get_mem (enum mem_class type, t_addr addr) +{ + if (type == MEM_XRAM && + flat24_flag && + addr >= 0x400000) + addr -= 0x400000 - get_mem_size (MEM_XRAM) + 1024; + return t_uc51::get_mem (type, addr); +} + +void +t_uc390::write_mem (enum mem_class type, t_addr addr, t_mem val) +{ + if (type == MEM_XRAM && + flat24_flag && + addr >= 0x400000) + addr -= 0x400000 - get_mem_size (MEM_XRAM) + 1024; + t_uc51::write_mem (type, addr, val); +} + +void +t_uc390::set_mem (enum mem_class type, t_addr addr, t_mem val) +{ + if (type == MEM_XRAM && + flat24_flag && + addr >= 0x400000) + addr -= 0x400000 - get_mem_size (MEM_XRAM) + 1024; + t_uc51::set_mem (type, addr, val); +} + +/* + *____________________________________________________________________________ + */ + +int +t_uc390::push_byte (uchar uc) { - if (Itype == CPU_DS390F) { - printf("FLAT24 MODE SET, warning: experimental code\n"); - flat24_flag = 1; - } + int res; + + sfr->add (SP, 1); + if (sfr->get (ACON) & 0x04) /* SA: 10 bit stack */ + { + uint sp10; + + if (get_mem (MEM_SFR, SP) == 0x00) /* overflow SP */ + sfr->add (ESP, 1); + sp10 = (get_mem (MEM_SFR, ESP) & 0x3) * 256 + + get_mem (MEM_SFR, SP); + write_mem (MEM_XRAM, sp10 + 0x400000, uc); + res = 0; + } + else + { + uchar *sp; + + sp = get_indirect (sfr->get (SP), &res); + if (res != resGO) + res = resSTACK_OV; + *sp = uc; + } + return res; } +// proc_write_sp (*aof_SP); TODO + +uchar +t_uc390::pop_byte (int *Pres) +{ + uchar uc; + + if (sfr->get (ACON) & 0x04) /* SA: 10 bit stack */ + { + uint sp10; + + sp10 = (get_mem (MEM_SFR, ESP) & 0x3) * 256 + + get_mem (MEM_SFR, SP); + sfr->add (SP, -1); + if (get_mem (MEM_SFR, SP) == 0xff) /* underflow SP */ + sfr->add (ESP, -1); + uc = get_mem (MEM_XRAM, sp10 + 0x400000); + *Pres = 0; + } + else + { + uchar *sp; + + sp = get_indirect (get_mem (MEM_SFR, SP), Pres); + if (*Pres != resGO) + *Pres = resSTACK_OV; + sfr->add (SP, -1); + uc = *sp; + } + return uc; +} /* * 0x05 2 12 INC addr @@ -320,23 +459,22 @@ t_uc390::t_uc390(int Itype, int Itech, class cl_sim *asim): * */ int -t_uc390::inst_inc_addr(uchar code) +t_uc390::inst_inc_addr (uchar code) { uchar *addr; - addr= get_direct(fetch(), &event_at.wi, &event_at.ws); + addr = get_direct (fetch (), &event_at.wi, &event_at.ws); /* mask off the 2Hex bit adjacent to the 1H bit which selects which DPTR we use. This is a feature of 80C390. You can do INC DPS and it only effects bit 1. */ - if (code == DPS) + if (code == DPS) (*addr) ^= 1; /* just toggle */ - else { + else (*addr)++; - } - proc_write(addr); - return(resGO); + proc_write (addr); + return resGO; } /* @@ -346,41 +484,45 @@ t_uc390::inst_inc_addr(uchar code) */ int -t_uc390::inst_inc_dptr(uchar code) +t_uc390::inst_inc_dptr (uchar code) { - uint dptr; - - unsigned char pl,ph,dps; - - dps = sfr->get(DPS); - if (dps & 1) { - pl = DPL1; - ph = DPH1; - } else { - pl = DPL; - ph = DPH; - } - - if (dps & 1) { /* alternate DPTR */ - if (dps & 0x80) /* decr set */ - dptr= sfr->get(ph)*256 + sfr->get(pl) - 1; - else - dptr= sfr->get(ph)*256 + sfr->get(pl) + 1; - } else { - if (dps & 0x40) /* decr set */ - dptr= sfr->get(ph)*256 + sfr->get(pl) - 1; - else - dptr= sfr->get(ph)*256 + sfr->get(pl) + 1; - } - - sfr->set(event_at.ws= ph, (dptr >> 8) & 0xff); - sfr->set(pl, dptr & 0xff); - - if (dps & 0x20) { /* auto-switch dptr */ - sfr->set(DPS, (dps ^ 1)); /* toggle dual-dptr switch */ - } - tick(1); - return(resGO); + ulong dptr; + + uchar pl, ph, px, dps; + + dps = sfr->get (DPS); + if (dps & 1) + { + pl = DPL1; + ph = DPH1; + px = DPX1; + } + else + { + pl = DPL; + ph = DPH; + px = DPX; + } + + dptr = sfr->get (ph) * 256 + sfr->get (pl); + //if ((sfr->get (ACON) & 0x3) == 2) + if (flat24_flag) + dptr += sfr->get (px) *256*256; + if (dps & 0x80) /* decr set */ + dptr--; + else + dptr++; + + //if ((sfr->get (ACON) & 0x3) == 2) + if (flat24_flag) + sfr->set (px, (dptr >> 16) & 0xff); + sfr->set (event_at.ws = ph, (dptr >> 8) & 0xff); + sfr->set (pl, dptr & 0xff); + + if (dps & 0x20) /* auto-switch dptr */ + sfr->set (DPS, (dps ^ 1)); /* toggle dual-dptr switch */ + tick (1); + return resGO; } /* @@ -390,25 +532,33 @@ t_uc390::inst_inc_dptr(uchar code) */ int -t_uc390::inst_jmp_$a_dptr(uchar code) +t_uc390::inst_jmp_$a_dptr (uchar code) { - unsigned char pl,ph,dps; + uchar pl, ph, px, dps; - dps = sfr->get(DPS); - if (dps & 1) { + dps = sfr->get (DPS); + if (dps & 1) + { pl = DPL1; ph = DPH1; - } else { + px = DPX1; + } + else + { pl = DPL; ph = DPH; + px = DPX; } - PC= (sfr->get(ph)*256 + sfr->get(pl) + - read_mem(MEM_SFR, ACC)) & + PC = (sfr->get (ph) * 256 + sfr->get (pl) + + read_mem (MEM_SFR, ACC)) & (EROM_SIZE - 1); + //if ((sfr->get (ACON) & 0x3) == 2) + if (flat24_flag) + PC += sfr->get (px) * 256*256; - tick(1); - return(resGO); + tick (1); + return resGO; } /* @@ -418,33 +568,35 @@ t_uc390::inst_jmp_$a_dptr(uchar code) */ int -t_uc390::inst_mov_dptr_$data(uchar code) +t_uc390::inst_mov_dptr_$data (uchar code) { - unsigned char pl,ph,dps; + uchar pl, ph, px, dps; - dps = sfr->get(DPS); - if (dps & 1) { + dps = sfr->get (DPS); + if (dps & 1) + { pl = DPL1; ph = DPH1; - } else { + px = DPX1; + } + else + { pl = DPL; ph = DPH; + px = DPX; } - //if ((sfr->get(ACON) & 0x3) == 2) - if (flat24_flag) { - fetch(); /* throw away msb of address for now */ - } + //if ((sfr->get (ACON) & 0x3) == 2) + if (flat24_flag) + sfr->set (px, fetch ()); + sfr->set (event_at.ws = ph, fetch ()); + sfr->set (pl, fetch ()); - sfr->set(event_at.ws= ph, fetch()); - sfr->set(pl, fetch()); + if (dps & 0x20) /* auto-switch dptr */ + sfr->set (DPS, (dps ^ 1)); /* toggle dual-dptr switch */ - if (dps & 0x20) { /* auto-switch dptr */ - sfr->set(DPS, (dps ^ 1)); /* toggle dual-dptr switch */ - } - - tick(1); - return(resGO); + tick (1); + return resGO; } @@ -455,31 +607,81 @@ t_uc390::inst_mov_dptr_$data(uchar code) */ int -t_uc390::inst_movc_a_$a_dptr(uchar code) +t_uc390::inst_movc_a_$a_dptr (uchar code) { - unsigned char pl,ph,dps; + uchar pl, ph, px, dps; - dps = sfr->get(DPS); - if (dps & 1) { + dps = sfr->get (DPS); + if (dps & 1) + { pl = DPL1; ph = DPH1; - } else { + px = DPX1; + } + else + { pl = DPL; ph = DPH; + px = DPX; } - sfr->set(ACC, get_mem(MEM_ROM, event_at.rc= - (sfr->get(ph)*256+sfr->get(pl) + - sfr->get(ACC)) & (EROM_SIZE-1))); + //if ((sfr->get (ACON) & 0x3) == 2) + if (flat24_flag) + sfr->set (ACC, get_mem (MEM_ROM, + event_at.rc = + (sfr->get (px) * 256*256 + sfr->get (ph) * 256 + sfr->get (pl) + + sfr->get (ACC)) & (EROM_SIZE-1))); + else + sfr->set (ACC, get_mem (MEM_ROM, event_at.rc = + (sfr->get (ph) * 256 + sfr->get (pl) + + sfr->get (ACC)) & (EROM_SIZE-1))); - if (dps & 0x20) { /* auto-switch dptr */ - sfr->set(DPS, (dps ^ 1)); /* toggle dual-dptr switch */ - } + if (dps & 0x20) /* auto-switch dptr */ + sfr->set (DPS, (dps ^ 1)); /* toggle dual-dptr switch */ + + tick (1); + return resGO; +} + +/* + * 0xc0 2 24 PUSH addr + *____________________________________________________________________________ + * + */ + +int +t_uc390::inst_push (uchar code) +{ + uchar *addr; + int res; + + addr = get_direct (fetch (), &event_at.wi, &event_at.ws); + res = push_byte (read (addr)); + tick (1); + return res; +} + + +/* + * 0xd0 2 24 POP addr + *____________________________________________________________________________ + * + */ + +int +t_uc390::inst_pop (uchar code) +{ + uchar *addr; + int res; - tick(1); - return(resGO); + addr = get_direct (fetch (), &event_at.wi, &event_at.ws); + *addr = pop_byte (&res); + proc_write (addr); + tick (1); + return res; } + /* * 0xe0 1 24 MOVX A,@DPTR *____________________________________________________________________________ @@ -487,27 +689,39 @@ t_uc390::inst_movc_a_$a_dptr(uchar code) */ int -t_uc390::inst_movx_a_$dptr(uchar code) +t_uc390::inst_movx_a_$dptr (uchar code) { - unsigned char pl,ph,dps; + uchar pl, ph, px, dps; - dps = sfr->get(DPS); - if (dps & 1) { + dps = sfr->get (DPS); + if (dps & 1) + { pl = DPL1; ph = DPH1; - } else { + px = DPX1; + } + else + { pl = DPL; ph = DPH; + px = DPX; } - sfr->set(event_at.ws= ACC, - get_mem(MEM_XRAM, event_at.rx=sfr->get(ph)*256+sfr->get(pl))); + //if ((sfr->get (ACON) & 0x3) == 2) + if (flat24_flag) + sfr->set (event_at.ws = ACC, + get_mem (MEM_XRAM, + event_at.rx = sfr->get (px) * 256*256 + sfr->get (ph) * 256 + sfr->get (pl))); + else + sfr->set (event_at.ws = ACC, + get_mem (MEM_XRAM, + event_at.rx = sfr->get (ph) * 256 + sfr->get (pl))); - if (dps & 0x20) { /* auto-switch dptr */ - sfr->set(DPS, (dps ^ 1)); /* toggle dual-dptr switch */ - } - tick(1); - return(resGO); + if (dps & 0x20) /* auto-switch dptr */ + sfr->set (DPS, (dps ^ 1)); /* toggle dual-dptr switch */ + + tick (1); + return resGO; } /* @@ -517,27 +731,39 @@ t_uc390::inst_movx_a_$dptr(uchar code) */ int -t_uc390::inst_movx_$dptr_a(uchar code) +t_uc390::inst_movx_$dptr_a (uchar code) { - unsigned char pl,ph,dps; + uchar pl, ph, px, dps; - dps = sfr->get(DPS); - if (dps & 1) { + dps = sfr->get (DPS); + if (dps & 1) + { pl = DPL1; ph = DPH1; - } else { + px = DPX1; + } + else + { pl = DPL; ph = DPH; + px = DPX; } - set_mem(MEM_XRAM, event_at.wx= sfr->get(ph)*256+sfr->get(pl), - sfr->get(event_at.rs= ACC)); + //if ((sfr->get (ACON) & 0x3) == 2) + if (flat24_flag) + set_mem (MEM_XRAM, + event_at.wx = sfr->get (px) * 256*256 + sfr->get (ph) * 256 + sfr->get (pl), + sfr->get (event_at.rs = ACC)); + else + set_mem (MEM_XRAM, + event_at.wx = sfr->get (ph) * 256 + sfr->get (pl), + sfr->get (event_at.rs = ACC)); - if (dps & 0x20) { /* auto-switch dptr */ - sfr->set(DPS, (dps ^ 1)); /* toggle dual-dptr switch */ - } - tick(1); - return(resGO); + if (dps & 0x20) /* auto-switch dptr */ + sfr->set (DPS, (dps ^ 1)); /* toggle dual-dptr switch */ + + tick (1); + return resGO; } /* @@ -547,25 +773,26 @@ t_uc390::inst_movx_$dptr_a(uchar code) */ int -t_uc390::inst_ajmp_addr(uchar code) +t_uc390::inst_ajmp_addr (uchar code) { - uchar h, l; - - if (flat24_flag) { - /* throw away high address byte for now... */ - h= (code >> 5) & 0x07; - h= fetch(); - l= fetch(); - PC= (PC & 0xf800) | (h*256 + l); - } else - { - h= (code >> 5) & 0x07; - l= fetch(); - PC= (PC & 0xf800) | (h*256 + l); - } - tick(1); - - return(resGO); + uchar x, h, l; + + //if ((sfr->get (ACON) & 0x3) == 2) + if (flat24_flag) + { + x = (code >> 5) & 0x07; + h = fetch (); + l = fetch (); + PC = (PC & 0xf800) | (x * 256*256 + h * 256 + l); + } + else + { + h = (code >> 5) & 0x07; + l = fetch (); + PC = (PC & 0xf800) | (h * 256 + l); + } + tick (1); + return resGO; } /* @@ -575,17 +802,26 @@ t_uc390::inst_ajmp_addr(uchar code) */ int -t_uc390::inst_ljmp(uchar code) +t_uc390::inst_ljmp (uchar code) { - if (flat24_flag) { - fetch(); /* throw away msb of address for now */ - - PC= fetch()*256 + fetch(); - } else { - PC= fetch()*256 + fetch(); - } - tick(1); - return(resGO); + uchar x, h, l; + + //if ((sfr->get (ACON) & 0x3) == 2) + if (flat24_flag) + { + x = fetch (); + h = fetch (); + l = fetch (); + PC = x * 256*256 + h * 256 + l; + } + else + { + h = fetch (); + l = fetch (); + PC = h * 256 + l; + } + tick (1); + return resGO; } /* @@ -595,63 +831,51 @@ t_uc390::inst_ljmp(uchar code) */ int -t_uc390::inst_acall_addr(uchar code) +t_uc390::inst_acall_addr (uchar code) { - uchar h, l, *sp, *aof_SP; + uchar x, h, l, *sp, *aof_SP; int res; - if (flat24_flag) { - /* throw away msb of address for now */ - h= (code >> 5) & 0x07; - - h= fetch(); - l= fetch(); - - aof_SP= &((sfr->umem8)[SP]); - //MEM(MEM_SFR)[SP]++; - (*aof_SP)++; - proc_write_sp(*aof_SP); - sp= get_indirect(*aof_SP/*sfr->get(SP)*/, &res); - if (res != resGO) - res= resSTACK_OV; - (*sp)= PC & 0xff; // push low byte - - //MEM(MEM_SFR)[SP]++; - (*aof_SP)++; - proc_write_sp(*aof_SP); - sp= get_indirect(*aof_SP/*sfr->get(SP)*/, &res); - if (res != resGO) - res= resSTACK_OV; - (*sp)= (PC >> 8) & 0xff; // push high byte - PC= (PC & 0xf800) | (h*256 + l); - - // need to push msb, skip for now... - - } else { - /* stock mcs51 mode */ - h= (code >> 5) & 0x07; - l= fetch(); - aof_SP= &((sfr->umem8)[SP]); - //MEM(MEM_SFR)[SP]++; - (*aof_SP)++; - proc_write_sp(*aof_SP); - sp= get_indirect(*aof_SP/*sfr->get(SP)*/, &res); - if (res != resGO) - res= resSTACK_OV; - (*sp)= PC & 0xff; // push low byte - - //MEM(MEM_SFR)[SP]++; - (*aof_SP)++; - proc_write_sp(*aof_SP); - sp= get_indirect(*aof_SP/*sfr->get(SP)*/, &res); - if (res != resGO) - res= resSTACK_OV; - (*sp)= (PC >> 8) & 0xff; // push high byte - PC= (PC & 0xf800) | (h*256 + l); - } - - tick(1); - return(res); + //if ((sfr->get (ACON) & 0x3) == 2) + if (flat24_flag) + { + x = (code >> 5) & 0x07; + h = fetch (); + l = fetch (); + + res = push_byte ( PC & 0xff); /* push low byte */ + res = push_byte ((PC >> 8) & 0xff); /* push high byte */ + res = push_byte ((PC >> 16) & 0xff); /* push x byte */ + + PC = (PC & 0xf800) | (x * 256*256 + h * 256 + l); + } + else + { + /* stock mcs51 mode */ + h = (code >> 5) & 0x07; + l = fetch (); + aof_SP = &((sfr->umem8)[SP]); + + //MEM(MEM_SFR)[SP]++; + (*aof_SP)++; + proc_write_sp (*aof_SP); + sp = get_indirect (*aof_SP/*sfr->get (SP)*/, &res); + if (res != resGO) + res = resSTACK_OV; + *sp = PC & 0xff; // push low byte + + //MEM(MEM_SFR)[SP]++; + (*aof_SP)++; + proc_write_sp (*aof_SP); + sp = get_indirect (*aof_SP/*sfr->get (SP)*/, &res); + if (res != resGO) + res = resSTACK_OV; + *sp = (PC >> 8) & 0xff; // push high byte + + PC = (PC & 0xf800) | (h * 256 + l); + } + tick (1); + return res; } @@ -662,50 +886,41 @@ t_uc390::inst_acall_addr(uchar code) */ int -t_uc390::inst_lcall(uchar code, uint addr) +t_uc390::inst_lcall (uchar code, uint addr) { - uchar h= 0, l= 0, *sp, *aof_SP; + uchar x = 0, h = 0, l = 0; int res; if (!addr) - { - /* this is a normal lcall */ - if (flat24_flag) { - fetch(); /* drop for now */ - h= fetch(); - l= fetch(); - } else { - h= fetch(); - l= fetch(); - } + { /* this is a normal lcall */ + //if ((sfr->get (ACON) & 0x3) == 2) + if (flat24_flag) + x = fetch (); + h = fetch (); + l = fetch (); } /* else, this is interrupt processing */ - aof_SP= &((sfr->umem8)[SP]); - //MEM(MEM_SFR)[SP]++; - (*aof_SP)++; - proc_write_sp(*aof_SP); - sp= get_indirect(*aof_SP/*sfr->get(SP)*/, &res); - if (res != resGO) - res= resSTACK_OV; - (*sp)= PC & 0xff; // push low byte - if (!addr) - tick(1); - - //MEM(MEM_SFR)[SP]++; - (*aof_SP)++; - proc_write_sp(*aof_SP); - sp= get_indirect(*aof_SP/*sfr->get(SP)*/, &res); - if (res != resGO) - res= resSTACK_OV; - (*sp)= (PC >> 8) & 0xff; // push high byte - if (addr) - PC= addr; - else - PC= h*256 + l; - + res = push_byte ( PC & 0xff); /* push low byte */ + res = push_byte ((PC >> 8) & 0xff); /* push high byte */ - return(res); + //if ((sfr->get (ACON) & 0x3) == 2) + if (flat24_flag) + { + res = push_byte ((PC >> 16) & 0xff); /* push x byte */ + if (addr) + PC = addr & 0xfffful; /* if interrupt: x-Byte is 0 */ + else + PC = x * 256*256 + h * 256 + l; + } + else + { + if (addr) + PC = addr; + else + PC = h * 256 + l; + } + return res; } /* @@ -715,35 +930,29 @@ t_uc390::inst_lcall(uchar code, uint addr) */ int -t_uc390::inst_ret(uchar code) +t_uc390::inst_ret (uchar code) { - uchar h, l, *sp, *aof_SP; + uchar x = 0, h, l; int res; - aof_SP= &((sfr->umem8)[SP]); - sp= get_indirect(*aof_SP/*sfr->get(SP)*/, &res); - if (res != resGO) - res= resSTACK_OV; - h= *sp; - //MEM(MEM_SFR)[SP]--; - (*aof_SP)--; - proc_write_sp(*aof_SP); - tick(1); - - sp= get_indirect(*aof_SP/*sfr->get(SP)*/, &res); - if (res != resGO) - res= resSTACK_OV; - l= *sp; - //MEM(MEM_SFR)[SP]--; - (*aof_SP)--; - proc_write_sp(*aof_SP); - PC= h*256 + l; - - if (flat24_flag) { - tick(1); - } - - return(res); + //if ((sfr->get (ACON) & 0x3) == 2) + if (flat24_flag) + x = pop_byte (&res); + h = pop_byte (&res); + l = pop_byte (&res); + + tick (1); + + //if ((sfr->get (ACON) & 0x3) == 2) + if (flat24_flag) + { + tick (1); + PC = x * 256*256 + h * 256 + l; + } + else + PC = h * 256 + l; + + return res; } /* @@ -753,44 +962,38 @@ t_uc390::inst_ret(uchar code) */ int -t_uc390::inst_reti(uchar code) +t_uc390::inst_reti (uchar code) { - uchar h, l, *sp, *aof_SP; + uchar x = 0, h, l; int res; - aof_SP= &((sfr->umem8)[SP]); - sp= get_indirect(*aof_SP/*sfr->get(SP)*/, &res); - if (res != resGO) - res= resSTACK_OV; - h= *sp; - //MEM(MEM_SFR)[SP]--; - (*aof_SP)--; - proc_write_sp(*aof_SP); - tick(1); - - sp= get_indirect(*aof_SP/*sfr->get(SP)*/, &res); - if (res != resGO) - res= resSTACK_OV; - l= *sp; - //MEM(MEM_SFR)[SP]--; - (*aof_SP)--; - proc_write_sp(*aof_SP); - PC= h*256 + l; - - if (flat24_flag) { - tick(1); - } - - was_reti= DD_TRUE; - class it_level *il= (class it_level *)(it_levels->top()); + //if ((sfr->get (ACON) & 0x3) == 2) + if (flat24_flag) + if (flat24_flag) + x = pop_byte (&res); + h = pop_byte (&res); + l = pop_byte (&res); + tick (1); + + //if ((sfr->get (ACON) & 0x3) == 2) + if (flat24_flag) + { + tick (1); + PC = x * 256*256 + h * 256 + l; + } + else + PC = h * 256 + l; + + was_reti = DD_TRUE; + class it_level *il = (class it_level *) (it_levels->top ()); if (il && il->level >= 0) { - il= (class it_level *)(it_levels->pop()); + il = (class it_level *) (it_levels->pop ()); delete il; } - return(res); + return res; } /* @@ -798,134 +1001,180 @@ t_uc390::inst_reti(uchar code) */ struct dis_entry * -t_uc390::dis_tbl(void) +t_uc390::dis_tbl (void) { - if (!flat24_flag) { - return(disass_51); - //t_uc51::dis_tbl(); - } + //if ((sfr->get (ACON) & 0x3) == 2) + if (!flat24_flag) + return disass_51; + //t_uc51::dis_tbl (); - return(disass_390f); + return disass_390f; } char * -t_uc390::disass(t_addr addr, char *sep) +t_uc390::disass (t_addr addr, char *sep) { char work[256], temp[20], c[2]; char *buf, *p, *b, *t; t_mem code; - if (!flat24_flag) { - t_uc51::disass(addr, sep); - } + //if ((sfr->get (ACON) & 0x3) == 2) + if (!flat24_flag) + return t_uc51::disass (addr, sep); + code = get_mem (MEM_ROM, addr); - code= get_mem(MEM_ROM, addr); - p= work; - b= dis_tbl()[code].mnemonic; + p = work; + b = dis_tbl ()[code].mnemonic; while (*b) { if (*b == '%') - { - b++; - switch (*(b++)) - { - case 'A': // absolute address - // stock: - //sprintf(temp, "%04lx", - // (addr&0xf800)| - // (((code>>5)&0x07)*256 + - // get_mem(MEM_ROM, addr+1))); - - sprintf(temp, "%06lx", - (addr&0xf80000)| - (((code>>5)&0x07)*(256*256) + - (get_mem(MEM_ROM, addr+1) * 256) + - get_mem(MEM_ROM, addr+2))); - break; - case 'l': // long address - sprintf(temp, "%06lx", - get_mem(MEM_ROM, addr+1)*(256*256) + get_mem(MEM_ROM, addr+1)*256 - + get_mem(MEM_ROM, addr+2)); - //get_mem(MEM_ROM, addr+1)*256 + get_mem(MEM_ROM, addr+2)); - break; - case 'a': // addr8 (direct address) at 2nd byte - if (!get_name(get_mem(MEM_ROM, addr+1), sfr_tbl(), temp)) - sprintf(temp, "%02lx", get_mem(MEM_ROM, addr+1)); - break; - case '8': // addr8 (direct address) at 3rd byte - if (!get_name(get_mem(MEM_ROM, addr+2), sfr_tbl(), temp)) - sprintf(temp, "%02lx", get_mem(MEM_ROM, addr+1)); - sprintf(temp, "%02lx", get_mem(MEM_ROM, addr+2)); - break; - case 'b': // bitaddr at 2nd byte - if (get_name(get_mem(MEM_ROM, addr+1), bit_tbl(), temp)) - break; - if (get_name(get_bitidx(get_mem(MEM_ROM, addr+1)), - sfr_tbl(), temp)) - { - strcat(temp, "."); - sprintf(c, "%1ld", get_mem(MEM_ROM, addr+1)&0x07); - strcat(temp, c); - break; - } - sprintf(temp, "%02x.%ld", - get_bitidx(get_mem(MEM_ROM, addr+1)), - get_mem(MEM_ROM, addr+1)&0x07); - break; - case 'r': // rel8 address at 2nd byte - sprintf(temp, "%04lx", - addr+2+(signed char)(get_mem(MEM_ROM, addr+1))); - break; - case 'R': // rel8 address at 3rd byte - sprintf(temp, "%04lx", - addr+3+(signed char)(get_mem(MEM_ROM, addr+2))); - break; - case 'd': // data8 at 2nd byte - sprintf(temp, "%02lx", get_mem(MEM_ROM, addr+1)); - break; - case 'D': // data8 at 3rd byte - sprintf(temp, "%02lx", get_mem(MEM_ROM, addr+2)); - break; - case '6': // data24 at 2nd(HH)-3rd(H)-4th(L) byte - sprintf(temp, "%06lx", - get_mem(MEM_ROM, addr+1)*256*256 + get_mem(MEM_ROM, addr+2)*256 + - get_mem(MEM_ROM, addr+3)); - default: - strcpy(temp, "?"); - break; - } - t= temp; - while (*t) - *(p++)= *(t++); - } + { + b++; + switch (*(b++)) + { + case 'A': // absolute address + // stock: + // sprintf (temp, "%04lx", + // (addr & 0xf800)| + // (((code >> 5) & 0x07) * 256 + + // get_mem (MEM_ROM, addr + 1))); + + sprintf (temp, "%06lx", + (addr & 0xf80000) | + (((code >> 5) & 0x07) * (256 * 256) + + (get_mem (MEM_ROM, addr + 1) * 256) + + get_mem (MEM_ROM, addr + 2))); + break; + case 'l': // long address + sprintf (temp, "%06lx", + get_mem (MEM_ROM, addr + 1) * (256*256) + + get_mem (MEM_ROM, addr + 2) * 256 + + get_mem (MEM_ROM, addr + 3)); + // get_mem (MEM_ROM, addr + 1) * 256 + get_mem (MEM_ROM, addr + 2)); + break; + case 'a': // addr8 (direct address) at 2nd byte + if (!get_name (get_mem (MEM_ROM, addr + 1), sfr_tbl (), temp)) + sprintf (temp, "%02lx", get_mem (MEM_ROM, addr + 1)); + break; + case '8': // addr8 (direct address) at 3rd byte + if (!get_name (get_mem (MEM_ROM, addr + 2), sfr_tbl (), temp)) + sprintf (temp, "%02lx", get_mem (MEM_ROM, addr + 1)); + sprintf (temp, "%02lx", get_mem (MEM_ROM, addr + 2)); + break; + case 'b': // bitaddr at 2nd byte + if (get_name (get_mem (MEM_ROM, addr + 1), bit_tbl (), temp)) + break; + if (get_name (get_bitidx (get_mem (MEM_ROM, addr + 1)), + sfr_tbl (), temp)) + { + strcat (temp, "."); + sprintf (c, "%1ld", get_mem (MEM_ROM, addr + 1) & 0x07); + strcat (temp, c); + break; + } + sprintf (temp, "%02x.%ld", + get_bitidx (get_mem (MEM_ROM, addr + 1)), + get_mem (MEM_ROM, addr + 1) & 0x07); + break; + case 'r': // rel8 address at 2nd byte + sprintf (temp, "%04lx", + addr + 2 + (signed char) (get_mem (MEM_ROM, addr + 1))); + break; + case 'R': // rel8 address at 3rd byte + sprintf (temp, "%04lx", + addr + 3 + (signed char) (get_mem (MEM_ROM, addr + 2))); + break; + case 'd': // data8 at 2nd byte + sprintf (temp, "%02lx", get_mem (MEM_ROM, addr + 1)); + break; + case 'D': // data8 at 3rd byte + sprintf (temp, "%02lx", get_mem (MEM_ROM, addr + 2)); + break; + default: + strcpy (temp, "?"); + break; + } + t = temp; + while (*t) + *p++ = *t++; + } else - *(p++)= *(b++); + *p++ = *b++; } - *p= '\0'; + *p = '\0'; - p= strchr(work, ' '); + p = strchr (work, ' '); if (!p) { - buf= strdup(work); - return(buf); + buf = strdup (work); + return buf; } if (sep == NULL) - buf= (char *)malloc(6+strlen(p)+1); + buf = (char *) malloc (6 + strlen (p) + 1); else - buf= (char *)malloc((p-work)+strlen(sep)+strlen(p)+1); - for (p= work, b= buf; *p != ' '; p++, b++) - *b= *p; + buf = (char *) malloc ((p - work) + strlen (sep) + strlen (p) + 1); + for (p = work, b = buf; *p != ' '; p++, b++) + *b = *p; p++; - *b= '\0'; + *b = '\0'; if (sep == NULL) + while (strlen (buf) < 6) + strcat (buf, " "); + else + strcat (buf, sep); + strcat (buf, p); + return buf; +} + +void +t_uc390::print_regs(class cl_console *con) +{ + t_addr start; + uchar data; + + //if ((sfr->get (ACON) & 0x3) == 2) + if (!flat24_flag) { - while (strlen(buf) < 6) - strcat(buf, " "); + t_uc51::print_regs (con); + return; } + start = sfr->get (PSW) & 0x18; + //dump_memory(iram, &start, start+7, 8, /*sim->cmd_out()*/con, sim); + iram->dump (start, start + 7, 8, con); + start = sfr->get (PSW) & 0x18; + data = iram->get (iram->get (start)); + con->printf ("%06x %02x %c", + iram->get (start), data, isprint (data) ? data : '.'); + con->printf (" ACC= 0x%02x %3d %c B= 0x%02x", + sfr->get (ACC), sfr->get (ACC), + isprint (sfr->get (ACC)) ? (sfr->get (ACC)) : '.', sfr->get (B)); + eram2xram (); + data = get_mem (MEM_XRAM, + sfr->get (DPX) * 256*256 + sfr->get (DPH) * 256 + sfr->get (DPL)); + con->printf (" DPTR= 0x%02x%02x%02x @DPTR= 0x%02x %3d %c\n", + sfr->get (DPX), sfr->get (DPH), sfr->get (DPL), + data, data, isprint (data) ? data : '.'); + data = iram->get (iram->get (start + 1)); + con->printf ("%06x %02x %c", iram->get (start + 1), data, + isprint (data) ? data : '.'); + data= sfr->get (PSW); + con->printf (" PSW= 0x%02x CY=%c AC=%c OV=%c P=%c ", + data, + (data & bmCY) ? '1' : '0', (data & bmAC) ? '1' : '0', + (data & bmOV) ? '1' : '0', (data & bmP ) ? '1' : '0' + ); + /* show stack pointer */ + if (sfr->get (ACON) & 0x04) + /* SA: 10 bit stack */ + con->printf ("SP10 0x%03x %3d\n", + (sfr->get (ESP) & 3) * 256 + sfr->get (SP), + get_mem (MEM_XRAM, (sfr->get (ESP) & 3) * 256 + sfr->get (SP) + 0x400000) + ); else - strcat(buf, sep); - strcat(buf, p); - return(buf); + con->printf ("SP 0x%02x %3d\n", + sfr->get (SP), + iram->get (sfr->get (SP)) + ); + print_disass (PC, con); } - /* End of s51.src/uc390.cc */ diff --git a/sim/ucsim/s51.src/uc390cl.h b/sim/ucsim/s51.src/uc390cl.h index b30700b7..8cd93fb7 100644 --- a/sim/ucsim/s51.src/uc390cl.h +++ b/sim/ucsim/s51.src/uc390cl.h @@ -2,7 +2,7 @@ * Simulator of microcontrollers (uc390cl.h) * * Copyright (C) 1999,99 Drotos Daniel, Talker Bt. - * + * * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu * * uc390cl.h - implemented by Karl Bongers, karl@turbobit.com @@ -39,28 +39,46 @@ public: t_uc390(int Itype, int Itech, class cl_sim *asim); int flat24_flag; /* true if flat24 mode code: ((ACON:9Dh & 3) == 0x2) */ -/* mods for dual-dptr */ -virtual int inst_inc_addr(uchar code); -virtual int inst_inc_dptr(uchar code); -virtual int inst_jmp_$a_dptr(uchar code); -virtual int inst_mov_dptr_$data(uchar code); -virtual int inst_movc_a_$a_dptr(uchar code); -virtual int inst_movx_a_$dptr(uchar code); -virtual int inst_movx_$dptr_a(uchar code); - -/* mods for flat24 */ -virtual int inst_ajmp_addr(uchar code); -virtual int inst_ljmp(uchar code); -virtual int inst_acall_addr(uchar code); -virtual int inst_lcall(uchar code, uint addr); -virtual int inst_ret(uchar code); -virtual int inst_reti(uchar code); - -/* mods for disassembly of flat24 */ -virtual struct dis_entry *dis_tbl(void); -virtual char * disass(t_addr addr, char *sep); + // making objects + virtual t_addr get_mem_size (enum mem_class type); + + // manipulating memories + virtual ulong read_mem (enum mem_class type, t_mem addr); + virtual ulong get_mem (enum mem_class type, t_addr addr); + virtual void write_mem (enum mem_class type, t_addr addr, t_mem val); + virtual void set_mem (enum mem_class type, t_addr addr, t_mem val); + + /* mods for dual-dptr */ + virtual int inst_inc_addr(uchar code); + virtual int inst_inc_dptr(uchar code); + virtual int inst_jmp_$a_dptr(uchar code); + virtual int inst_mov_dptr_$data(uchar code); + virtual int inst_movc_a_$a_dptr(uchar code); + virtual int inst_movx_a_$dptr(uchar code); + virtual int inst_movx_$dptr_a(uchar code); + + /* mods for flat24 */ + virtual int inst_ajmp_addr(uchar code); + virtual int inst_ljmp(uchar code); + virtual int inst_acall_addr(uchar code); + virtual int inst_lcall(uchar code, uint addr); + virtual int inst_ret(uchar code); + virtual int inst_reti(uchar code); + + /* mods for 10 bit stack */ + virtual int inst_push (uchar code); + virtual int inst_pop (uchar code); + /* mods for disassembly of flat24 */ + virtual struct dis_entry *dis_tbl(void); + virtual char * disass(t_addr addr, char *sep); + virtual void print_regs(class cl_console *con); + +protected: + virtual int push_byte (uchar uc); + virtual uchar pop_byte (int *Pres); }; -#endif /* End of s51.src/uc390cl.h */ + +#endif diff --git a/support/regression/tests/bug-460010.c b/support/regression/tests/bug-460010.c index abf31678..8d300ff5 100644 --- a/support/regression/tests/bug-460010.c +++ b/support/regression/tests/bug-460010.c @@ -2,7 +2,7 @@ */ #include -#ifdef __mcs51 +#if defined __mcs51 || defined __ds390 #define XDATA xdata #else #define XDATA