URL
https://opencores.org/ocsvn/zipcpu/zipcpu/trunk
Subversion Repositories zipcpu
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 33 to Rev 34
- ↔ Reverse comparison
Rev 33 → Rev 34
/zipcpu/trunk/bench/cpp/zippy_tb.cpp
59,6 → 59,8
#define CMD_INT (1<<7) |
#define CMD_RESET (1<<6) |
|
#define KEY_ESCAPE 27 |
#define KEY_RETURN 10 |
|
// No particular "parameters" need definition or redefinition here. |
class ZIPPY_TB : public TESTB<Vzipsystem> { |
68,12 → 70,14
// QSPIFLASHSIM m_flash; |
FILE *dbg_fp; |
bool dbg_flag, bomb; |
int m_cursor; |
|
ZIPPY_TB(void) : m_mem_size(1<<20), m_mem(m_mem_size) { |
//dbg_fp = fopen("dbg.txt", "w"); |
// dbg_fp = fopen("dbg.txt", "w"); |
dbg_fp = NULL; |
dbg_flag = false; |
bomb = false; |
m_cursor = 0; |
} |
|
void reset(void) { |
86,29 → 90,38
return true; |
} |
|
void showval(int y, int x, const char *lbl, unsigned int v) { |
mvprintw(y,x, "%s: 0x%08x", lbl, v); |
void showval(int y, int x, const char *lbl, unsigned int v, bool c) { |
if (c) |
mvprintw(y,x, ">%s> 0x%08x<", lbl, v); |
else |
mvprintw(y,x, " %s: 0x%08x ", lbl, v); |
} |
|
void dispreg(int y, int x, const char *n, unsigned int v) { |
void dispreg(int y, int x, const char *n, unsigned int v, bool c) { |
// 4,4,8,1 = 17 of 20, +3 = 19 |
mvprintw(y, x, "%s: 0x%08x", n, v); |
if (c) |
mvprintw(y, x, ">%s> 0x%08x<", n, v); |
else |
mvprintw(y, x, " %s: 0x%08x ", n, v); |
} |
|
void showreg(int y, int x, const char *n, int r) { |
void showreg(int y, int x, const char *n, int r, bool c) { |
// 4,4,8,1 = 17 of 20, +3 = 19 |
mvprintw(y, x, "%s: 0x%08x", n, m_core->v__DOT__thecpu__DOT__regset[r]); |
if (c) |
mvprintw(y, x, ">%s> 0x%08x", n, m_core->v__DOT__thecpu__DOT__regset[r]); |
else |
mvprintw(y, x, " %s: 0x%08x", n, m_core->v__DOT__thecpu__DOT__regset[r]); |
addch( ((r == m_core->v__DOT__thecpu__DOT__dcdA) |
&&(m_core->v__DOT__thecpu__DOT__dcdvalid) |
&&(m_core->v__DOT__thecpu__DOT__dcdA_rd)) |
?'a':' '); |
?'a':((c)?'<':' ')); |
addch( ((r == m_core->v__DOT__thecpu__DOT__dcdB) |
&&(m_core->v__DOT__thecpu__DOT__dcdvalid) |
&&(m_core->v__DOT__thecpu__DOT__dcdB_rd)) |
?'b':' '); |
?'b':((c)?'<':' ')); |
addch( ((r == m_core->v__DOT__thecpu__DOT__wr_reg_id) |
&&(m_core->v__DOT__thecpu__DOT__wr_reg_ce)) |
?'W':' '); |
?'W':((c)?'<':' ')); |
} |
|
void showins(int y, const char *lbl, const int ce, const int valid, |
174,22 → 187,22
&&(m_core->v__DOT__sys_addr == 0))?"W":" ", |
(m_core->v__DOT__trap_int)?"I":" "); |
*/ |
showval(ln, 1, "PIC ", m_core->v__DOT__pic_data); |
showval(ln,21, "WDT ", m_core->v__DOT__watchdog__DOT__r_value); |
showval(ln,41, "CACH", m_core->v__DOT__manualcache__DOT__cache_base); |
showval(ln,61, "PIC2", m_core->v__DOT__ctri__DOT__r_int_state); |
showval(ln, 0, "PIC ", m_core->v__DOT__pic_data, (m_cursor==0)); |
showval(ln,20, "WDT ", m_core->v__DOT__watchdog__DOT__r_value, (m_cursor==1)); |
showval(ln,40, "CACH", m_core->v__DOT__manualcache__DOT__cache_base, (m_cursor==2)); |
showval(ln,60, "PIC2", m_core->v__DOT__ctri__DOT__r_int_state, (m_cursor==3)); |
|
ln++; |
showval(ln, 1, "TMRA", m_core->v__DOT__timer_a__DOT__r_value); |
showval(ln,21, "TMRB", m_core->v__DOT__timer_b__DOT__r_value); |
showval(ln,41, "TMRB", m_core->v__DOT__timer_c__DOT__r_value); |
showval(ln,61, "JIF ", m_core->v__DOT__jiffies__DOT__r_counter); |
showval(ln, 0, "TMRA", m_core->v__DOT__timer_a__DOT__r_value, (m_cursor==4)); |
showval(ln,20, "TMRB", m_core->v__DOT__timer_b__DOT__r_value, (m_cursor==5)); |
showval(ln,40, "TMRB", m_core->v__DOT__timer_c__DOT__r_value, (m_cursor==6)); |
showval(ln,60, "JIF ", m_core->v__DOT__jiffies__DOT__r_counter, (m_cursor==7)); |
|
ln++; |
showval(ln, 1, "UTSK", m_core->v__DOT__utc_data); |
showval(ln,21, "UOST", m_core->v__DOT__uoc_data); |
showval(ln,41, "UPST", m_core->v__DOT__upc_data); |
showval(ln,61, "UICT", m_core->v__DOT__uic_data); |
showval(ln, 0, "UTSK", m_core->v__DOT__utc_data, (m_cursor==8)); |
showval(ln,20, "UOST", m_core->v__DOT__uoc_data, (m_cursor==9)); |
showval(ln,40, "UPST", m_core->v__DOT__upc_data, (m_cursor==10)); |
showval(ln,60, "UICT", m_core->v__DOT__uic_data, (m_cursor==11)); |
|
ln++; |
mvprintw(ln, 40, "%s %s", |
207,24 → 220,24
mvprintw(ln, 0, "Supervisor Registers"); |
ln++; |
|
showreg(ln, 1, "sR0 ", 0); |
showreg(ln,21, "sR1 ", 1); |
showreg(ln,41, "sR2 ", 2); |
showreg(ln,61, "sR3 ", 3); ln++; |
showreg(ln, 0, "sR0 ", 0, (m_cursor==12)); |
showreg(ln,20, "sR1 ", 1, (m_cursor==13)); |
showreg(ln,40, "sR2 ", 2, (m_cursor==14)); |
showreg(ln,60, "sR3 ", 3, (m_cursor==15)); ln++; |
|
showreg(ln, 1, "sR4 ", 4); |
showreg(ln,21, "sR5 ", 5); |
showreg(ln,41, "sR6 ", 6); |
showreg(ln,61, "sR7 ", 7); ln++; |
showreg(ln, 0, "sR4 ", 4, (m_cursor==16)); |
showreg(ln,20, "sR5 ", 5, (m_cursor==17)); |
showreg(ln,40, "sR6 ", 6, (m_cursor==18)); |
showreg(ln,60, "sR7 ", 7, (m_cursor==19)); ln++; |
|
showreg(ln, 1, "sR8 ", 8); |
showreg(ln,21, "sR9 ", 9); |
showreg(ln,41, "sR10", 10); |
showreg(ln,61, "sR11", 11); ln++; |
showreg(ln, 0, "sR8 ", 8, (m_cursor==20)); |
showreg(ln,20, "sR9 ", 9, (m_cursor==21)); |
showreg(ln,40, "sR10", 10, (m_cursor==22)); |
showreg(ln,60, "sR11", 11, (m_cursor==23)); ln++; |
|
showreg(ln, 1, "sR12", 12); |
showreg(ln,21, "sSP ", 13); |
mvprintw(ln,41, "sCC :%s%s%s%s%s%s%s%s", |
showreg(ln, 0, "sR12", 12, (m_cursor==24)); |
showreg(ln,20, "sSP ", 13, (m_cursor==25)); |
mvprintw(ln,40, "sCC :%s%s%s%s%s%s%s%s", |
(m_core->v__DOT__thecpu__DOT__trap)?"TRP":" ", |
(m_core->v__DOT__thecpu__DOT__step)?"STP":" ", |
(m_core->v__DOT__thecpu__DOT__sleep)?"SLP":" ", |
233,7 → 246,7
(m_core->v__DOT__thecpu__DOT__iflags&4)?"N":" ", |
(m_core->v__DOT__thecpu__DOT__iflags&2)?"C":" ", |
(m_core->v__DOT__thecpu__DOT__iflags&1)?"Z":" "); |
mvprintw(ln,61, "sPC : 0x%08x", m_core->v__DOT__thecpu__DOT__ipc); |
showval(ln,60, "sPC ", m_core->v__DOT__thecpu__DOT__ipc, (m_cursor==27)); |
ln++; |
|
if (m_core->v__DOT__thecpu__DOT__gie) |
241,24 → 254,24
else |
attroff(A_BOLD); |
mvprintw(ln, 0, "User Registers"); ln++; |
showreg(ln, 1, "uR0 ", 16); |
showreg(ln,21, "uR1 ", 17); |
showreg(ln,41, "uR2 ", 18); |
showreg(ln,61, "uR3 ", 19); ln++; |
showreg(ln, 0, "uR0 ", 16, (m_cursor==28)); |
showreg(ln,20, "uR1 ", 17, (m_cursor==29)); |
showreg(ln,40, "uR2 ", 18, (m_cursor==30)); |
showreg(ln,60, "uR3 ", 19, (m_cursor==31)); ln++; |
|
showreg(ln, 1, "uR4 ", 20); |
showreg(ln,21, "uR5 ", 21); |
showreg(ln,41, "uR6 ", 22); |
showreg(ln,61, "uR7 ", 23); ln++; |
showreg(ln, 0, "uR4 ", 20, (m_cursor==32)); |
showreg(ln,20, "uR5 ", 21, (m_cursor==33)); |
showreg(ln,40, "uR6 ", 22, (m_cursor==34)); |
showreg(ln,60, "uR7 ", 23, (m_cursor==35)); ln++; |
|
showreg(ln, 1, "uR8 ", 24); |
showreg(ln,21, "uR9 ", 25); |
showreg(ln,41, "uR10", 26); |
showreg(ln,61, "uR11", 27); ln++; |
showreg(ln, 0, "uR8 ", 24, (m_cursor==36)); |
showreg(ln,20, "uR9 ", 25, (m_cursor==37)); |
showreg(ln,40, "uR10", 26, (m_cursor==38)); |
showreg(ln,60, "uR11", 27, (m_cursor==39)); ln++; |
|
showreg(ln, 1, "uR12", 28); |
showreg(ln,21, "uSP ", 29); |
mvprintw(ln,41, "uCC :%s%s%s%s%s%s%s%s", |
showreg(ln, 0, "uR12", 28, (m_cursor==40)); |
showreg(ln,20, "uSP ", 29, (m_cursor==41)); |
mvprintw(ln,40, "uCC :%s%s%s%s%s%s%s%s", |
(m_core->v__DOT__thecpu__DOT__trap)?"TRP":" ", |
(m_core->v__DOT__thecpu__DOT__step)?"STP":" ", |
(m_core->v__DOT__thecpu__DOT__sleep)?"SLP":" ", |
267,7 → 280,7
(m_core->v__DOT__thecpu__DOT__flags&4)?"N":" ", |
(m_core->v__DOT__thecpu__DOT__flags&2)?"C":" ", |
(m_core->v__DOT__thecpu__DOT__flags&1)?"Z":" "); |
mvprintw(ln,61, "uPC : 0x%08x", m_core->v__DOT__thecpu__DOT__upc); |
showval(ln,60, "uPC ", m_core->v__DOT__thecpu__DOT__upc, (m_cursor==43)); |
|
attroff(A_BOLD); |
ln+=1; |
397,6 → 410,17
return v; |
} |
|
void cmd_write(unsigned int a, int v) { |
if ((a&0x0f)==0x0f) |
dbg_flag = true; |
wb_write(CMD_REG, CMD_HALT|(a&0x3f)); |
while((wb_read(CMD_REG) & CMD_STALL) == 0) |
; |
if (dbg_flag) |
fprintf(dbg_fp, "CMD-WRITE(%d) <= 0x%08x\n", a, v); |
wb_write(CMD_DATA, v); |
} |
|
bool halted(void) { |
return (m_core->v__DOT__cmd_halt != 0); |
} |
403,23 → 427,46
|
void read_state(void) { |
int ln= 0; |
bool gie; |
|
mvprintw(ln,0, "Peripherals-RS"); ln++; |
showval(ln, 1, "PIC ", cmd_read(32+ 0)); |
showval(ln,21, "WDT ", cmd_read(32+ 1)); |
showval(ln,41, "CACH", cmd_read(32+ 2)); |
showval(ln,61, "PIC2", cmd_read(32+ 3)); |
if (m_cursor < 0) |
m_cursor = 0; |
else if (m_cursor >= 44) |
m_cursor = 43; |
|
mvprintw(ln,0, "Peripherals-RS"); |
mvprintw(ln,40,"%-40s", "CPU State: "); |
{ |
unsigned int v = wb_read(CMD_REG); |
mvprintw(ln,51, ""); |
if (v & 0x010000) |
printw("EXT-INT "); |
if ((v & 0x003000) == 0x03000) |
printw("Halted "); |
else if (v & 0x001000) |
printw("Sleeping "); |
else if (v & 0x002000) |
printw("Supervisor Mod "); |
if (v & 0x008000) |
printw("Break-Enabled "); |
if (v & 0x000080) |
printw("PIC Enabled "); |
} ln++; |
showval(ln, 0, "PIC ", cmd_read(32+ 0), (m_cursor==0)); |
showval(ln,20, "WDT ", cmd_read(32+ 1), (m_cursor==1)); |
showval(ln,40, "CACH", cmd_read(32+ 2), (m_cursor==2)); |
showval(ln,60, "PIC2", cmd_read(32+ 3), (m_cursor==3)); |
ln++; |
showval(ln, 1, "TMRA", cmd_read(32+ 4)); |
showval(ln,21, "TMRB", cmd_read(32+ 5)); |
showval(ln,41, "TMRC", cmd_read(32+ 6)); |
showval(ln,61, "JIF ", cmd_read(32+ 7)); |
showval(ln, 0, "TMRA", cmd_read(32+ 4), (m_cursor==4)); |
showval(ln,20, "TMRB", cmd_read(32+ 5), (m_cursor==5)); |
showval(ln,40, "TMRC", cmd_read(32+ 6), (m_cursor==6)); |
showval(ln,60, "JIF ", cmd_read(32+ 7), (m_cursor==7)); |
|
ln++; |
showval(ln, 1, "UTSK", cmd_read(32+12)); |
showval(ln,21, "UMST", cmd_read(32+13)); |
showval(ln,41, "UPST", cmd_read(32+14)); |
showval(ln,61, "UAST", cmd_read(32+15)); |
showval(ln, 0, "UTSK", cmd_read(32+12), (m_cursor==8)); |
showval(ln,20, "UMST", cmd_read(32+13), (m_cursor==9)); |
showval(ln,40, "UPST", cmd_read(32+14), (m_cursor==10)); |
showval(ln,60, "UICT", cmd_read(32+15), (m_cursor==11)); |
|
ln++; |
ln++; |
426,7 → 473,8
unsigned int cc = cmd_read(14); |
if (dbg_fp) fprintf(dbg_fp, "CC = %08x, gie = %d\n", cc, |
m_core->v__DOT__thecpu__DOT__gie); |
if (cc & 0x020) |
gie = (cc & 0x020); |
if (gie) |
attroff(A_BOLD); |
else |
attron(A_BOLD); |
433,67 → 481,71
mvprintw(ln, 0, "Supervisor Registers"); |
ln++; |
|
dispreg(ln, 1, "sR0 ", cmd_read(0)); |
dispreg(ln,21, "sR1 ", cmd_read(1)); |
dispreg(ln,41, "sR2 ", cmd_read(2)); |
dispreg(ln,61, "sR3 ", cmd_read(3)); ln++; |
dispreg(ln, 0, "sR0 ", cmd_read(0), (m_cursor==12)); |
dispreg(ln,20, "sR1 ", cmd_read(1), (m_cursor==13)); |
dispreg(ln,40, "sR2 ", cmd_read(2), (m_cursor==14)); |
dispreg(ln,60, "sR3 ", cmd_read(3), (m_cursor==15)); ln++; |
|
dispreg(ln, 1, "sR4 ", cmd_read(4)); |
dispreg(ln,21, "sR5 ", cmd_read(5)); |
dispreg(ln,41, "sR6 ", cmd_read(6)); |
dispreg(ln,61, "sR7 ", cmd_read(7)); ln++; |
dispreg(ln, 0, "sR4 ", cmd_read(4), (m_cursor==16)); |
dispreg(ln,20, "sR5 ", cmd_read(5), (m_cursor==17)); |
dispreg(ln,40, "sR6 ", cmd_read(6), (m_cursor==18)); |
dispreg(ln,60, "sR7 ", cmd_read(7), (m_cursor==19)); ln++; |
|
dispreg(ln, 1, "sR8 ", cmd_read( 8)); |
dispreg(ln,21, "sR9 ", cmd_read( 9)); |
dispreg(ln,41, "sR10", cmd_read(10)); |
dispreg(ln,61, "sR11", cmd_read(11)); ln++; |
dispreg(ln, 0, "sR8 ", cmd_read( 8), (m_cursor==20)); |
dispreg(ln,20, "sR9 ", cmd_read( 9), (m_cursor==21)); |
dispreg(ln,40, "sR10", cmd_read(10), (m_cursor==22)); |
dispreg(ln,60, "sR11", cmd_read(11), (m_cursor==23)); ln++; |
|
dispreg(ln, 1, "sR12", cmd_read(12)); |
dispreg(ln,21, "sSP ", cmd_read(13)); |
dispreg(ln, 0, "sR12", cmd_read(12), (m_cursor==24)); |
dispreg(ln,20, "sSP ", cmd_read(13), (m_cursor==25)); |
|
mvprintw(ln,41, "sCC :%s%s%s%s%s%s%s", |
(cc & 0x040)?"STP":" ", |
(cc & 0x020)?"GIE":" ", |
(cc & 0x010)?"SLP":" ", |
mvprintw(ln,40, "%ssCC :%s%s%s%s%s%s%s%s", |
(m_cursor==26)?">":" ", |
(cc & 0x100)?"TP":" ", |
(cc & 0x040)?"ST":" ", |
(cc & 0x020)?"IE":" ", |
(cc & 0x010)?"SL":" ", |
(cc&8)?"V":" ", |
(cc&4)?"N":" ", |
(cc&2)?"C":" ", |
(cc&1)?"Z":" "); |
mvprintw(ln,61, "sPC : 0x%08x", cmd_read(15)); |
dispreg(ln,60, "sPC ", cmd_read(15), (m_cursor==27)); |
ln++; |
|
if (cc & 0x020) |
if (gie) |
attron(A_BOLD); |
else |
attroff(A_BOLD); |
mvprintw(ln, 0, "User Registers"); ln++; |
dispreg(ln, 1, "uR0 ", cmd_read(16)); |
dispreg(ln,21, "uR1 ", cmd_read(17)); |
dispreg(ln,41, "uR2 ", cmd_read(18)); |
dispreg(ln,61, "uR3 ", cmd_read(19)); ln++; |
dispreg(ln, 0, "uR0 ", cmd_read(16), (m_cursor==28)); |
dispreg(ln,20, "uR1 ", cmd_read(17), (m_cursor==29)); |
dispreg(ln,40, "uR2 ", cmd_read(18), (m_cursor==30)); |
dispreg(ln,60, "uR3 ", cmd_read(19), (m_cursor==31)); ln++; |
|
dispreg(ln, 1, "uR4 ", cmd_read(20)); |
dispreg(ln,21, "uR5 ", cmd_read(21)); |
dispreg(ln,41, "uR6 ", cmd_read(22)); |
dispreg(ln,61, "uR7 ", cmd_read(23)); ln++; |
dispreg(ln, 0, "uR4 ", cmd_read(20), (m_cursor==32)); |
dispreg(ln,20, "uR5 ", cmd_read(21), (m_cursor==33)); |
dispreg(ln,40, "uR6 ", cmd_read(22), (m_cursor==34)); |
dispreg(ln,60, "uR7 ", cmd_read(23), (m_cursor==35)); ln++; |
|
dispreg(ln, 1, "uR8 ", cmd_read(24)); |
dispreg(ln,21, "uR9 ", cmd_read(25)); |
dispreg(ln,41, "uR10", cmd_read(26)); |
dispreg(ln,61, "uR11", cmd_read(27)); ln++; |
dispreg(ln, 0, "uR8 ", cmd_read(24), (m_cursor==36)); |
dispreg(ln,20, "uR9 ", cmd_read(25), (m_cursor==37)); |
dispreg(ln,40, "uR10", cmd_read(26), (m_cursor==38)); |
dispreg(ln,60, "uR11", cmd_read(27), (m_cursor==39)); ln++; |
|
dispreg(ln, 1, "uR12", cmd_read(28)); |
dispreg(ln,21, "uSP ", cmd_read(29)); |
dispreg(ln, 0, "uR12", cmd_read(28), (m_cursor==40)); |
dispreg(ln,20, "uSP ", cmd_read(29), (m_cursor==41)); |
cc = cmd_read(30); |
mvprintw(ln,41, "uCC :%s%s%s%s%s%s%s", |
(cc&0x040)?"STP":" ", |
(cc&0x020)?"GIE":" ", |
(cc&0x010)?"SLP":" ", |
mvprintw(ln,40, "%cuCC :%s%s%s%s%s%s%s%s", |
(m_cursor == 42)?">":" ", |
(cc&0x100)?"TP":" ", |
(cc&0x040)?"ST":" ", |
(cc&0x020)?"IE":" ", |
(cc&0x010)?"SL":" ", |
(cc&8)?"V":" ", |
(cc&4)?"N":" ", |
(cc&2)?"C":" ", |
(cc&1)?"Z":" "); |
mvprintw(ln,61, "uPC : 0x%08x", cmd_read(31)); |
dispreg(ln,60, "uPC ", cmd_read(31), (m_cursor==43)); |
|
attroff(A_BOLD); |
ln+=2; |
625,6 → 677,13
m_core->v__DOT__thecpu__DOT__op_break); |
} |
|
if (dbg_fp) { |
if(m_core->v__DOT__thecpu__DOT__clear_pipeline) |
fprintf(dbg_fp, "\tClear Pipeline\n"); |
if(m_core->v__DOT__thecpu__DOT__new_pc) |
fprintf(dbg_fp, "\tNew PC\n"); |
} |
|
TESTB<Vzipsystem>::tick(); |
if ((dbg_fp)&&(gie != m_core->v__DOT__thecpu__DOT__gie)) { |
fprintf(dbg_fp, "SWITCH FROM %s to %s: sPC = 0x%08x uPC = 0x%08x pf_pc = 0x%08x\n", |
714,8 → 773,141
return v; |
} |
|
void cursor_up(void) { |
if (m_cursor > 3) |
m_cursor -= 4; |
} void cursor_down(void) { |
if (m_cursor < 40) |
m_cursor += 4; |
} void cursor_left(void) { |
if (m_cursor > 0) |
m_cursor--; |
else m_cursor = 43; |
} void cursor_right(void) { |
if (m_cursor < 43) |
m_cursor++; |
else m_cursor = 0; |
} |
|
int cursor(void) { return m_cursor; } |
}; |
|
void get_value(ZIPPY_TB *tb) { |
int wy, wx, ra; |
int c = tb->cursor(); |
|
wx = (c & 0x03) * 20 + 9; |
wy = (c>>2); |
if (wy >= 3+4) |
wy++; |
if (wy > 3) |
wy += 2; |
wy++; |
|
if (c >= 12) |
ra = c - 12; |
else |
ra = c + 32; |
|
bool done = false; |
char str[16]; |
int pos = 0; str[pos] = '\0'; |
while(!done) { |
int chv = getch(); |
switch(chv) { |
case KEY_ESCAPE: |
pos = 0; str[pos] = '\0'; done = true; |
break; |
case KEY_RETURN: case KEY_ENTER: case KEY_UP: case KEY_DOWN: |
done = true; |
break; |
case KEY_LEFT: case KEY_BACKSPACE: |
if (pos > 0) pos--; |
break; |
case KEY_CLEAR: |
pos = 0; |
break; |
case '0': case ' ': str[pos++] = '0'; break; |
case '1': str[pos++] = '1'; break; |
case '2': str[pos++] = '2'; break; |
case '3': str[pos++] = '3'; break; |
case '4': str[pos++] = '4'; break; |
case '5': str[pos++] = '5'; break; |
case '6': str[pos++] = '6'; break; |
case '7': str[pos++] = '7'; break; |
case '8': str[pos++] = '8'; break; |
case '9': str[pos++] = '9'; break; |
case 'A': case 'a': str[pos++] = 'A'; break; |
case 'B': case 'b': str[pos++] = 'B'; break; |
case 'C': case 'c': str[pos++] = 'C'; break; |
case 'D': case 'd': str[pos++] = 'D'; break; |
case 'E': case 'e': str[pos++] = 'E'; break; |
case 'F': case 'f': str[pos++] = 'F'; break; |
} |
|
if (pos > 8) |
pos = 8; |
str[pos] = '\0'; |
|
attron(A_NORMAL | A_UNDERLINE); |
mvprintw(wy, wx, "%-8s", str); |
if (pos > 0) { |
attron(A_NORMAL | A_UNDERLINE | A_BLINK); |
mvprintw(wy, wx+pos-1, "%c", str[pos-1]); |
} |
attrset(A_NORMAL); |
} |
|
if (pos > 0) { |
int v; |
v = strtoul(str, NULL, 16); |
if (!tb->halted()) { |
switch(ra) { |
case 15: |
tb->m_core->v__DOT__thecpu__DOT__ipc = v; |
if (!tb->m_core->v__DOT__thecpu__DOT__gie) { |
tb->m_core->v__DOT__thecpu__DOT__pf_pc = v; |
tb->m_core->v__DOT__thecpu__DOT__new_pc = 1; |
tb->m_core->v__DOT__thecpu__DOT__clear_pipeline = 1; |
tb->m_core->v__DOT__thecpu__DOT__alu_pc_valid = 0; |
tb->m_core->v__DOT__thecpu__DOT__dcd_ce = 0; |
tb->m_core->v__DOT__thecpu__DOT__dcdvalid = 0; |
tb->m_core->v__DOT__thecpu__DOT__opvalid = 0; |
} |
break; |
case 31: |
tb->m_core->v__DOT__thecpu__DOT__upc = v; |
if (tb->m_core->v__DOT__thecpu__DOT__gie) { |
tb->m_core->v__DOT__thecpu__DOT__pf_pc = v; |
tb->m_core->v__DOT__thecpu__DOT__new_pc = 1; |
tb->m_core->v__DOT__thecpu__DOT__clear_pipeline = 1; |
tb->m_core->v__DOT__thecpu__DOT__alu_pc_valid = 0; |
tb->m_core->v__DOT__thecpu__DOT__dcd_ce = 0; |
tb->m_core->v__DOT__thecpu__DOT__dcdvalid = 0; |
tb->m_core->v__DOT__thecpu__DOT__opvalid = 0; |
} |
break; |
case 32: tb->m_core->v__DOT__pic_data = v; break; |
case 33: tb->m_core->v__DOT__watchdog__DOT__r_value = v; break; |
case 34: tb->m_core->v__DOT__manualcache__DOT__cache_base = v; break; |
case 35: tb->m_core->v__DOT__ctri__DOT__r_int_state = v; break; |
case 36: tb->m_core->v__DOT__timer_a__DOT__r_value = v; break; |
case 37: tb->m_core->v__DOT__timer_b__DOT__r_value = v; break; |
case 38: tb->m_core->v__DOT__timer_c__DOT__r_value = v; break; |
case 39: tb->m_core->v__DOT__jiffies__DOT__r_counter = v; break; |
case 44: tb->m_core->v__DOT__utc_data = v; break; |
case 45: tb->m_core->v__DOT__uoc_data = v; break; |
case 46: tb->m_core->v__DOT__upc_data = v; break; |
case 47: tb->m_core->v__DOT__uic_data = v; break; |
default: |
tb->m_core->v__DOT__thecpu__DOT__regset[ra] = v; |
break; |
} |
} else |
tb->cmd_write(ra, v); |
} |
} |
|
void usage(void) { |
printf("USAGE: zippy_tb [-a] <testfile.out>\n"); |
printf("\n"); |
793,10 → 985,12
// tb->m_core->v__DOT__cmd_halt = 0; |
// tb->m_core->v__DOT__cmd_step = 0; |
|
/* |
printf("PC = %08x:%08x (%08x)\n", |
tb->m_core->v__DOT__thecpu__DOT__ipc, |
tb->m_core->v__DOT__thecpu__DOT__upc, |
tb->m_core->v__DOT__thecpu__DOT__alu_pc); |
*/ |
|
done = (tb->test_success())||(tb->test_failure()); |
} |
845,21 → 1039,30
erase(); |
break; |
case 's': case 'S': |
if (manual) |
if (!halted) |
erase(); |
tb->wb_write(CMD_REG, CMD_STEP); |
manual = false; |
halted = true; |
break; |
case 't': case 'T': |
if (!manual) |
if ((!manual)||(halted)) |
erase(); |
manual = true; |
halted = false; |
// tb->m_core->v__DOT__thecpu__DOT__step = 0; |
// tb->m_core->v__DOT__cmd_halt = 0; |
// tb->m_core->v__DOT__cmd_step = 0; |
tb->tick(); |
break; |
case ERR: |
case KEY_IC: case KEY_ENTER: case KEY_RETURN: |
get_value(tb); |
break; |
case KEY_UP: tb->cursor_up(); break; |
case KEY_DOWN: tb->cursor_down(); break; |
case KEY_LEFT: tb->cursor_left(); break; |
case KEY_RIGHT: tb->cursor_right(); break; |
case ERR: case KEY_CLEAR: |
default: |
if (!manual) |
tb->tick(); |
/zipcpu/trunk/rtl/core/zipcpu.v
270,7 → 270,7
// |
// PIPELINE STAGE #2 :: Instruction Decode |
// Calculate stall conditions |
assign dcd_ce = (pf_valid)&&(~dcd_stalled); |
assign dcd_ce = (pf_valid)&&(~dcd_stalled)&&(~clear_pipeline); |
assign dcd_stalled = (dcdvalid)&&( |
(op_stall) |
||((dcdA_stall)||(dcdB_stall)||(dcdF_stall)) |
764,6 → 764,9
break_en <= 1'b0; |
else if ((wr_reg_ce)&&(~wr_reg_id[4])&&(wr_write_cc)) |
break_en <= wr_reg_vl[`CPU_BREAK_BIT]; |
else if ((i_halt)&&(i_dbg_we) |
&&(i_dbg_reg == { 1'b0, `CPU_CC_REG })) |
break_en <= i_dbg_data[`CPU_BREAK_BIT]; |
assign o_break = ((break_en)||(~op_gie))&&(op_break)&&(~alu_valid)&&(~mem_valid)&&(~mem_busy); |
|
|
886,7 → 889,7
else if ((wr_reg_ce)&&(wr_reg_id[4] == gie)&&(wr_write_pc)) |
pf_pc <= wr_reg_vl; |
else if ((i_halt)&&(i_dbg_we) |
&&(wr_reg_id[4:0] == { gie, `CPU_PC_REG})) |
&&(i_dbg_reg[4:0] == { gie, `CPU_PC_REG})) |
pf_pc <= i_dbg_data; |
else if (dcd_ce) |
pf_pc <= pf_pc + 1; |
902,7 → 905,7
else if ((wr_reg_ce)&&(wr_reg_id[4] == gie)&&(wr_write_pc)) |
new_pc <= 1'b1; |
else if ((i_halt)&&(i_dbg_we) |
&&(wr_reg_id[4:0] == { gie, `CPU_PC_REG})) |
&&(i_dbg_reg[4:0] == { gie, `CPU_PC_REG})) |
new_pc <= 1'b1; |
else |
new_pc <= 1'b0; |
/zipcpu/trunk/rtl/zipsystem.v
134,7 → 134,8
// Wishbone slave interface for debugging purposes |
i_dbg_cyc, i_dbg_stb, i_dbg_we, i_dbg_addr, i_dbg_data, |
o_dbg_ack, o_dbg_stall, o_dbg_data); |
parameter RESET_ADDRESS=32'h0100000; |
parameter RESET_ADDRESS=32'h0100000, START_HALTED=1, |
EXTERNAL_INTERRUPTS=1; |
input i_clk, i_rst; |
// Wishbone master |
output wire o_wb_cyc, o_wb_stb, o_wb_we; |
143,7 → 144,7
input i_wb_ack, i_wb_stall; |
input [31:0] i_wb_data; |
// Incoming interrupts |
input i_ext_int; |
input [(EXTERNAL_INTERRUPTS-1):0] i_ext_int; |
// Outgoing interrupt |
output wire o_ext_int; |
// Wishbone slave |
211,7 → 212,7
initial cmd_halt = 1'b1; |
always @(posedge i_clk) |
if (i_rst) |
cmd_halt <= 1'b1; |
cmd_halt <= (START_HALTED == 1)? 1'b1 : 1'b0; |
else if (dbg_cmd_write) |
cmd_halt <= dbg_idata[10]; |
else if ((cmd_step)||(cpu_break)) |
234,16 → 235,16
cmd_addr <= dbg_idata[5:0]; |
|
wire cpu_reset; |
assign cpu_reset = (i_rst)||(cmd_reset)||(wdt_reset); |
assign cpu_reset = (cmd_reset)||(wdt_reset); |
|
wire cpu_halt, cpu_dbg_stall; |
assign cpu_halt = (cmd_halt)&&(~cmd_step); |
assign cpu_halt = (i_rst)||((cmd_halt)&&(~cmd_step)); |
wire [31:0] pic_data; |
wire [31:0] cmd_data; |
// Values: |
// 0x0003f -> cmd_addr mask |
// 0x00040 -> reset |
// 0x00080 -> interrrupts enabled |
// 0x00080 -> PIC interrrupts enabled |
// 0x00100 -> cmd_step |
// 0x00200 -> cmd_stall |
// 0x00400 -> cmd_halt |
251,7 → 252,8
// 0x01000 -> cc.sleep |
// 0x02000 -> cc.gie |
// 0x10000 -> External interrupt line is high |
assign cmd_data = { 15'h00, i_ext_int, 2'b00, cpu_dbg_cc, |
assign cmd_data = { 7'h00, {(9-EXTERNAL_INTERRUPTS){1'b0}}, i_ext_int, |
2'b00, cpu_dbg_cc, |
1'b0, cmd_halt, (~cpu_dbg_stall), 1'b0, |
pic_data[15], cpu_reset, cmd_addr }; |
|
454,10 → 456,10
// The programmable interrupt controller peripheral |
// |
wire pic_interrupt; |
wire [6:0] int_vector; |
wire [(5+EXTERNAL_INTERRUPTS):0] int_vector; |
assign int_vector = { i_ext_int, ctri_int, tma_int, tmb_int, tmc_int, |
jif_int, cache_int }; |
icontrol #(7) pic(i_clk, cpu_reset, |
icontrol #(6+EXTERNAL_INTERRUPTS) pic(i_clk, cpu_reset, |
(sys_cyc)&&(sys_stb)&&(sys_we) |
&&(sys_addr==`INTCTRL), |
sys_data, pic_data, |
/zipcpu/trunk/rtl/aux/busdelay.v
90,6 → 90,6
// Our only non-delayed line, yet still really delayed. Perhaps |
// there's a way to register this? |
// o_wb_stall <= (i_wb_cyc)&&(i_wb_stb) ... or some such? |
assign o_wb_stall = ((i_wb_cyc)&&(o_dly_cyc)&&(i_dly_stall)&&(~o_dly_stb)); |
assign o_wb_stall = ((i_wb_cyc)&&(o_dly_cyc)&&(i_dly_stall)&&(o_dly_stb)); |
|
endmodule |
/zipcpu/trunk/sw/zasm/test.S
83,7 → 83,7
#define SHIFT_TEST |
#define TRAP_TEST |
#define MPY_TEST |
// #define PUSH_TEST |
#define PUSH_TEST |
test: |
#ifdef DO_TEST_ASSEMBLER |
; We start out by testing our assembler. We give it some instructions, which |
164,7 → 164,17
lod dead_beef.values(r10),r10 ; r10 now equals 0xdeadbeef |
cmp r10,r9 |
bnz test_failure |
|
|
; Test whether or not our operator precedence rules work |
ldi 5+3*8,r0 |
ldi 3*8+5,r1 |
cmp r0,r1 |
bnz test_failure |
ldi (5+3)*8,r0 |
ldi 8*(3+5),r1 |
cmp r0,r1 |
bnz test_failure |
|
; Test whether or not we can properly decode OCTAL values |
clr r0 ; Re-clear our register set first |
clr r1 |
267,6 → 277,7
ldi $c0000000h,r12 ; Set R12 to point to our peripheral address |
mov r12,ur12 |
mov test_start(pc),upc |
mov stack(pc),usp |
ldi 0x8000ffff,r0 ; Clear interrupts, turn all vectors off |
sto r0,(r12) |
rtu |
493,7 → 504,18
cmp r0,r1 |
trap.ne r11 |
#endif |
|
|
#ifdef PUSH_TEST |
ldi $0x0e000,r11 // Mark our test |
ldi 0x01248cab,r0 |
ldi 0xd5312480,r1 // Let's see if we can preserve this as well |
mov r1,r7 |
JSR(reverse_bit_order,R4); // *SP = 0x010013d |
cmp r0,r1 |
trap.ne r11 |
cmp r0,r7 |
trap.ne r11 |
#endif |
// Return success / Test the trap interrupt |
clr r11 |
trap r11 |
512,6 → 534,7
PUSH(R2,SP) |
LDI 32,R1 |
CLR R2 |
reverse_bit_order_loop: |
LSL 1,R2 |
LSR 1,R0 |
OR.C 1,R2 |
523,5 → 546,5
RET |
#endif |
fill 512,0 |
stack: |
stack: // Must point to a valid word initially |
word 0 |
/zipcpu/trunk/sw/zasm/zasm.y
82,6 → 82,7
%left BOOLEANAND |
%left BITWISEOR BITWISEXOR |
%left BITWISEAND |
%left '%' |
%left PLUS MINUS |
%left TIMES '/' |
|
383,15 → 384,17
|
expr: |
value { $$ = $1; } |
| MINUS value { $$ = new AST_BRANCH('-',new AST_NUMBER(0), $2); } |
| expr PLUS value { $$ = new AST_BRANCH('+',$1,$3); } |
| expr MINUS value { $$ = new AST_BRANCH('-',$1,$3); } |
| expr TIMES value { $$ = new AST_BRANCH('*',$1,$3); } |
| expr BOOLEANOR value { $$ = new AST_BRANCH('o',$1,$3); } |
| expr BITWISEOR value { $$ = new AST_BRANCH('|',$1,$3); } |
| expr BOOLEANAND value { $$ = new AST_BRANCH('a',$1,$3); } |
| expr BITWISEAND value { $$ = new AST_BRANCH('&',$1,$3); } |
| expr BITWISEXOR value { $$ = new AST_BRANCH('^',$1,$3); } |
| MINUS value %prec TIMES { $$ = new AST_BRANCH('-',new AST_NUMBER(0), $2); } |
| expr PLUS expr { $$ = new AST_BRANCH('+',$1,$3); } |
| expr MINUS expr { $$ = new AST_BRANCH('-',$1,$3); } |
| expr TIMES expr { $$ = new AST_BRANCH('*',$1,$3); } |
| expr '/' expr { $$ = new AST_BRANCH('/',$1,$3); } |
| expr '%' expr { $$ = new AST_BRANCH('%',$1,$3); } |
| expr BOOLEANOR expr { $$ = new AST_BRANCH('o',$1,$3); } |
| expr BITWISEOR expr { $$ = new AST_BRANCH('|',$1,$3); } |
| expr BOOLEANAND expr { $$ = new AST_BRANCH('a',$1,$3); } |
| expr BITWISEAND expr { $$ = new AST_BRANCH('&',$1,$3); } |
| expr BITWISEXOR expr { $$ = new AST_BRANCH('^',$1,$3); } |
| '(' expr ')' { $$ = $2; } |
; |
/* expr OR (|) value */ |
/zipcpu/trunk/sw/zasm/asmdata.cpp
557,7 → 557,10
fprintf(fp, "\tTLINE OP = (Unrecognized, %d)\n", m_opcode); |
break; |
} |
fprintf(fp, "\tTLINE COND = %d\n", m_cond); |
if (m_cond == 0) |
fprintf(fp, "\tTLINE COND = (Always)\n"); |
else |
fprintf(fp, "\tTLINE COND = %s\n", zop_ccstr[m_cond&0x07]); |
if (m_imm == NULL) |
fprintf(fp, "\tTLINE imm = (NULL)\n"); |
else if (!m_imm->isdefined()) { |
567,8 → 570,10
fprintf(fp, "\n"); |
} else |
fprintf(fp, "\tTLINE imm = %d\n", m_imm->eval()); |
fprintf(fp, "\tTLINE opb = %d\n", m_opb); |
fprintf(fp, "\tTLINE opa = %d\n", m_opa); |
if (m_opb != ZPARSER::ZIP_Rnone) |
fprintf(fp, "\tTLINE opb = %d\n", m_opb); |
if (m_opa != ZPARSER::ZIP_Rnone) |
fprintf(fp, "\tTLINE opa = %d\n", m_opa); |
} |
} |
|
/zipcpu/trunk/sw/zasm/zpp.l
46,6 → 46,8
#include <ctype.h> |
#include <stdio.h> |
#include <list> |
#include <vector> |
#include <assert.h> |
|
using namespace std; |
|
58,6 → 60,10
int ndef = 0, structno = 0; |
char *structid = NULL; |
void stb_define(const char *str); |
bool stb_current(const char *str); |
bool stb_hasargs(const char *str); |
void stb_expand(FILE *fout, const char *str); |
std::string stb_expand(const char *str); |
void stb_args(const char *str); |
void stb_macro(const char *value); |
void stb_addmacro(const char *value); |
91,6 → 97,7
<INITIAL,INDEF>^"#define"[ \t]+ { yy_push_state(DEF); } |
/* <*>^"#line"[ \t]+(0-9)+[ \t]+["][^"]*["][ \t]*\n { } */ |
<DEF>{IDDOT}/[^(] { |
// fprintf(stderr, "Defining \'%s\'\n", yytext); |
stb_define(yytext); |
BEGIN DFV; |
} |
100,10 → 107,61
stb_args(yytext); |
BEGIN DFV; |
} |
<DFV>[ \t]+ { /* Ignore initial spaces */ } |
<DFV>[^ \t\n]* {/* Parse to end of line, get value for our define */ |
<DFV>^[ \t]+ { stb_macro(yytext); /* Replicate initial spaces */ } |
<DFV>[ \t]+ { stb_macro(" "); /* Ignore all but one internal space */ } |
<DFV>{ID} {/* Parse to end of line, get value for our define */ |
// fprintf(stderr, "%s may be a macro, line %d\n", yytext, yylineno); |
if ((!stb_current(yytext))&&(stb_isdefined(yytext))) { |
// fprintf(stderr, "Recursive MACRO!\n"); |
stb_macro(stb_getdefn(yytext)); |
} else { |
// fprintf(stderr, "But it is not defined\n"); |
stb_macro(yytext); |
} |
} |
<DFV>{ID}[ \t]*[(][ \t]*{ID}[ \t]*(,[ \t]*{ID}[ \t]*)*[)] { |
// fprintf(stderr, "%s may be a macro within a macro!\n", yytext); |
if ((!stb_current(yytext))&&(stb_isdefined(yytext))) { |
if (stb_hasargs(yytext)) { |
std::string str = stb_expand(yytext); |
stb_macro(str.c_str()); |
} else { |
char *dup = strdup(yytext), *ptr; |
ptr = strchr(dup, '('); |
*ptr = '\0'; |
stb_macro(stb_getdefn(dup)); |
free(dup); |
yyless(strchr(yytext,'(')-yytext); |
} |
} else { |
char *dup = strdup(yytext), *ptr; |
ptr = strchr(dup, '('); |
*ptr = '\0'; |
stb_macro(stb_getdefn(dup)); |
free(dup); |
yyless(strchr(yytext,'(')-yytext); |
} |
} |
<DFV>[^a-zA-Z_0-9 \t\n]+ {/* Parse to end of line, get value for our define */ |
// fprintf(stderr, "A: Adding to macro %s\n", yytext); |
stb_macro(yytext); |
} |
<DFV>0[xX][0-9A-Fa-f]+ {/* Get any hexadecimal constants */ |
// fprintf(stderr, "B: Adding to macro %s\n", yytext); |
stb_macro(yytext); |
} |
<DFV>[0-9A-Fa-f]+[hH] {/* Get any hexadecimal constants */ |
// fprintf(stderr, "C: Adding to macro %s\n", yytext); |
stb_macro(yytext); |
} |
<DFV>[0-7]+[oO] {/* Get any hexadecimal constants */ |
// fprintf(stderr, "D: Adding to macro %s\n", yytext); |
stb_macro(yytext); |
} |
<DFV>[0-9]+ {/* Get any hexadecimal constants */ |
// fprintf(stderr, "E: Adding to macro %s\n", yytext); |
stb_macro(yytext); |
} |
<DFV>[ \t]*((;|"//").*)?$ {/* Parse to end of line, get value for our define */ |
yy_pop_state(); |
} |
159,6 → 217,26
else |
fprintf(yyout, "%s", yytext); |
} |
<INITIAL,INDEF>{ID}([ \t]*) { |
if (stb_isdefined(yytext)) |
fprintf(yyout, "%s", stb_getdefn(yytext)); |
else |
fprintf(yyout, "%s", yytext); |
} |
<INITIAL,INDEF>{ID}[ \t]*[(][ \t]*{ID}[ \t]*(,[ \t]*{ID}[ \t]*)*[)] { |
// fprintf(stderr, "%s may be a macro!\n", yytext); |
if (stb_isdefined(yytext)) { |
if (stb_hasargs(yytext)) { |
stb_expand(yyout, yytext); |
} else { |
fprintf(yyout, "%s", stb_getdefn(yytext)); |
yyless(strchr(yytext,'(')-yytext); |
} |
} else { |
// fprintf(stderr, "But it is not defined\n"); |
fprintf(yyout, "%s", yytext); |
} |
} |
<*>[ \t]*"//".*$ { /* Ignore (trailing) comment only lines */ } |
<*>[ \t]*";".*$ { /* Ignore (trailing) comment only lines */ } |
<*>"#warning".*$ { fprintf(stderr, "WARNING: %s\n", &yytext[8]); } |
178,8 → 256,16
|
%% |
|
class SYMTABLE_ACTION { |
public: |
// Types: 0 (end of actions), 1-X, argument number, <0 raw string |
int m_type; |
std::string m_str; // if m_type < 0, have m_str |
}; |
|
class SYMTABLE_ENTRY { |
private: |
bool m_reduced; |
std::string &trim(std::string &s) { |
std::string::iterator ptr = s.end(); |
|
191,8 → 277,10
|
public: |
std::string m_name, m_value, m_args; |
std::vector<SYMTABLE_ACTION> m_actions; |
SYMTABLE_ENTRY(const char *str) : m_name(str) { |
trim(m_name); |
m_reduced = false; |
} |
SYMTABLE_ENTRY &operator+=(const char *str) { |
const char *start = str; |
202,9 → 290,7
if (m_value.length()!=0) |
m_value += " "; |
|
std::string trimd(start); |
trim(trimd); |
m_value += trimd; |
m_value += str; |
|
/* |
printf("ENTRY::SYMBOL \'%s\' NOW = \'%s\'\n", |
220,6 → 306,153
const std::string &getdefn(void) { |
return m_value; |
} |
|
bool hasargs(void) { |
return (m_args.size()>0); |
} |
|
void reduce(void) { |
if (m_reduced) |
return; |
|
// fprintf(stderr, "Reducing %s ( %s ) \n", m_name.c_str(), m_args.c_str()); |
std::vector<std::string> alist; |
int i=0, bg, en; |
do { |
if ((m_args[i] == ',')||(m_args[i] == '(')) |
i++; |
while((m_args[i])&&(isspace(m_args[i]))) |
i++; |
bg = i; |
while((m_args[i])&&( |
(isalpha(m_args[i])) |
||(m_args[i]==':') |
||(m_args[i]=='_') |
||(isdigit(m_args[i])))) |
i++; |
en = i; |
while((m_args[i])&&(isspace(m_args[i]))) |
i++; |
|
alist.push_back(m_args.substr(bg,en-bg)); |
// printf("Found argument %2ld of %s: \'%s\'\n", |
// alist.size(), |
// m_name.c_str(), |
// m_args.substr(bg,en-bg).c_str()); |
} while((m_args[i])&&(m_args[i] == ',')); |
|
assert(m_args[i] == ')'); |
|
// Now that we know our arguments, lets look for these |
// arguments in our macro definition |
std::string building; |
i = 0; |
while(m_value[i]) { |
int nxti = m_value.size(), nxtv; |
for(int a=0; a<alist.size(); a++) { |
const char *ptr; |
ptr = strstr(m_value.c_str()+i, alist[a].c_str()); |
while((ptr)&&(ptr-m_value.c_str() < nxti)) { |
int loc = ptr-m_value.c_str(); |
const char *pre = ptr-1; |
const char *pst = ptr+alist[a].size(); |
if ((loc < nxti)&&( |
(loc == i) |
||((!isalpha(*pre) |
&&(*pre != '_') |
&&(*pre != ':') |
&&(!isdigit(*pre))))) |
&&((*pst=='\0') |
||( (!isalpha(*pst)) |
&&(*pst != '_') |
&&(*pst != ':') |
&&(!isdigit(*pst))))) |
{ |
nxti = loc; |
nxtv = a; |
break; |
} else { |
ptr = strstr(m_value.c_str()+loc, alist[a].c_str()); |
loc = ptr-m_value.c_str(); |
} |
} |
} |
|
if (nxti < m_value.size()) { |
// Found an argument!! |
SYMTABLE_ACTION act; |
if (nxti > i) { |
act.m_type = -1; |
act.m_str = m_value.substr(i,nxti-i); |
// printf("ACTION: \'%s\'\n", act.m_str.c_str()); |
m_actions.push_back(act); |
} |
act.m_type = nxtv; |
act.m_str = ""; |
m_actions.push_back(act); |
// printf("ACTION[%2d]: \'%s\'\n", nxtv, alist[nxtv].c_str()); |
|
i = nxti+alist[nxtv].size(); |
} else break; // No more arguments |
} if (i<m_value.size()) { |
SYMTABLE_ACTION act; |
act.m_type = -1; |
act.m_str = m_value.substr(i); |
// printf("ACTION: \'%s\'\n", act.m_str.c_str()); |
m_actions.push_back(act); |
} |
m_reduced = true; |
} |
|
std::string expand(std::string args) { |
if (!m_reduced) |
reduce(); |
std::vector<std::string> alist; |
std::string result; |
|
// printf("Expanding %s\n", args.c_str()); |
int i=0, bg, en, nest=-1; |
do { |
if ((args[i] == '(')||(args[i] == ',')) { |
if (args[i] =='(') |
nest++; |
i++; |
} |
while((args[i])&&(isspace(args[i]))) |
i++; |
bg = i; |
while((args[i])&&(args[i] != ',')&&((args[i] != ')')||(nest != 0))) { |
if (args[i] == '(') |
nest++; |
else if (args[i] == ')') |
nest--; |
i++; |
} en = i-1; |
while((en>0)&&(isspace(args[en]))) |
en--; |
alist.push_back(args.substr(bg,en+1-bg)); |
// printf("Argument %2ld of %s maps to \'%s\'\n", |
// alist.size(), |
// m_name.c_str(), |
// args.substr(bg,en+1-bg).c_str()); |
} while((args[i])&&(args[i] == ',')); |
|
// printf("At end, args[i] = \'%s\'\n", &args[i]); |
assert(args[i] == ')'); |
|
// printf("Filling in %ld actions\n", m_actions.size()); |
for(i=0; i<m_actions.size(); i++) { |
if((m_actions[i].m_type >= 0)&&(m_actions[i].m_type < alist.size())) |
result += alist[m_actions[i].m_type].c_str(); |
else if (m_actions[i].m_type < 0) |
result += m_actions[i].m_str.c_str(); |
// else { |
// fprintf(fout, "m_type = %d, size = %ld\n", m_actions[i].m_type, alist.size()); |
// } |
} |
|
return result; |
} |
}; |
|
class SYMBOL_TABLE { |
247,7 → 480,7
; |
m_tbl.insert(i, v); |
|
// printf("SYMS::Defining SYMBOL: \'%s\'\n", str); |
// fprintf(stderr, "SYMS::Defining SYMBOL: \'%s\'\n", str); |
} |
|
bool defined(const char *str) { |
281,6 → 514,12
fprintf(stderr, "INTERNAL ERR, %s NOT DEFINED!\n", name); |
} (*i)->setargs(str); |
} |
bool hasargs(const char *name) { |
TBLT::iterator i = lookup(name); |
if (i == m_tbl.end()) { |
return false; |
} return (*i)->hasargs(); |
} |
const char *getdefn(const char *name) { |
TBLT::iterator i = lookup(name); |
if (i == m_tbl.end()) { |
288,6 → 527,13
return NULL; |
} (*i)->getdefn().c_str(); |
} |
|
std::string expand(const char *name, const char *ptr) { |
TBLT::iterator i = lookup(name); |
if (i==m_tbl.end()) |
return std::string(""); |
return (*i)->expand(std::string(ptr)); |
} |
|
}; |
|
296,6 → 542,12
std::string last_define; |
|
void stb_define(const char *str) { |
/* |
if (last_define.size()>0) { |
fprintf(stderr, "LAST-DEFINE(%s): %s\n", last_define.c_str(), |
stb_getdefn(last_define.c_str())); |
} */ |
|
if (syms.defined(str)) { |
fprintf(stderr, "WARNING! Symbol \'%s\' is already defined!\n", str); |
syms.undefine(str); |
318,7 → 570,19
} |
|
bool stb_isdefined(const char *str) { |
return syms.defined(str); |
const char *ptr; |
if ((ptr = strchr(str, '('))!=NULL) { |
// fprintf(stderr, "Checking whether %s needs to be expanded\n",str); |
char *dup = strdup(str), *chr; |
chr = strchr(dup, '('); |
*chr = '\0'; |
// fprintf(stderr, "\tLooking it up by the name \'%s\'\n", dup); |
bool r = (syms.defined(dup)); |
free(dup); |
return r; |
} else { |
return syms.defined(str); |
} |
} |
|
const char *stb_getdefn(const char *str) { |
325,6 → 589,47
return syms.getdefn(str); |
} |
|
bool stb_current(const char *str) { |
return (strcmp(str, last_define.c_str())==0); |
} |
|
bool stb_hasargs(const char *str) { |
const char *ptr; |
if ((ptr = strchr(str, '('))!=NULL) { |
char *dup = strdup(str), *chr; |
chr = strchr(dup, '('); |
*chr = '\0'; |
bool r = (syms.hasargs(dup)); |
// fprintf(stderr, "\t%s has %sarguments\n", dup, (r)?"":"no "); |
free(dup); |
return r; |
} else { |
return syms.hasargs(str); |
} |
} |
|
std::string stb_expand(const char *macro) { |
const char *ptr; |
std::string str; |
ptr = strchr(macro, '('); |
assert(ptr); |
ptr--; |
while((ptr>macro)&&(isspace(*ptr))) |
ptr--; |
char *nam = strndup(macro, ptr+1-macro); |
ptr = strchr(ptr, '('); |
// fprintf(stderr, "Requesting an expansion of %s -- %s\n", nam, ptr); |
str = syms.expand(nam, ptr); |
free(nam); |
|
return str; |
} |
|
void stb_expand(FILE *fout, const char *macro) { |
std::string str = stb_expand(macro); |
fprintf(fout, "%s", str.c_str()); |
} |
|
class BUFSTACK { |
public: |
FILE *m_fp; |
/zipcpu/trunk/sw/zasm/zasm.l
189,6 → 189,7
"^" { return BITWISEXOR; } |
":" { return COLON; } |
"." { return DOT; } |
"%" { return '%'; } |
[ \t]+ { } |
[(] { return '('; } |
[)] { return ')'; } |
/zipcpu/trunk/sw/zasm/sys.i
107,8 → 107,8
|
; Now, some macros |
#define PUSH(RG,SP) SUB 1,SP \ |
STO RG,-1(SP) |
#define POP(RG,SP) LOD -1(SP),RG \ |
STO RG,1(SP) |
#define POP(RG,SP) LOD 1(SP),RG \ |
ADD 1,SP |
#define FJSR(LBL,RG) MOV __here__+2(PC),RG \ |
JMP LBL |
115,76 → 115,76
#define FRET(RG) MOV RG,PC |
#define JSR(LBL,RG) SUB 1,SP \ |
MOV __here__+3(PC),RG \ |
STO RG,-1(SP) \ |
STO RG,1(SP) \ |
JMP LBL \ |
ADD 1,SP |
#define RET LOD -1(SP),PC |
#define RET LOD 1(SP),PC |
#define SAVE_USER_CONTEXT(DR,AR) \ |
MOV -16(uSP),AR \ |
MOV uPC,DR \ |
STO DR,-16(AR) \ |
STO DR,16(AR) \ |
MOV uCC,DR \ |
STO DR,-15(AR) \ |
STO DR,15(AR) \ |
MOV uSP,DR \ |
STO DR,-14(AR) \ |
STO DR,14(AR) \ |
MOV uR12,DR \ |
STO DR,-13(AR) \ |
STO DR,13(AR) \ |
MOV uR11,DR \ |
STO DR,-12(AR) \ |
STO DR,12(AR) \ |
MOV uR10,DR \ |
STO DR,-11(AR) \ |
STO DR,11(AR) \ |
MOV uR9,DR \ |
STO DR,-10(AR) \ |
STO DR,10(AR) \ |
MOV uR8,DR \ |
STO DR,-9(AR) \ |
STO DR,9(AR) \ |
MOV uR7,DR \ |
STO DR,-8(AR) \ |
STO DR,8(AR) \ |
MOV uR6,DR \ |
STO DR,-7(AR) \ |
STO DR,7(AR) \ |
MOV uR5,DR \ |
STO DR,-6(AR) \ |
STO DR,6(AR) \ |
MOV uR4,DR \ |
STO DR,-5(AR) \ |
STO DR,5(AR) \ |
MOV uR3,DR \ |
STO DR,-4(AR) \ |
STO DR,4(AR) \ |
MOV uR2,DR \ |
STO DR,-3(AR) \ |
STO DR,3(AR) \ |
MOV uR1,DR \ |
STO DR,-2(AR) \ |
STO DR,2(AR) \ |
MOV uR0,DR \ |
STO DR,-1(AR) |
STO DR,1(AR) |
#define RESTORE_USER_CONTEXT(DR,AR) \ |
LOD -1(AR),DR \ |
LOD 1(AR),DR \ |
MOV DR,uR0 \ |
LOD -2(AR),DR \ |
LOD 2(AR),DR \ |
MOV DR,uR1 \ |
LOD -3(AR),DR \ |
LOD 3(AR),DR \ |
MOV DR,uR2 \ |
LOD -4(AR),DR \ |
LOD 4(AR),DR \ |
MOV DR,uR3 \ |
LOD -5(AR),DR \ |
LOD 5(AR),DR \ |
MOV DR,uR4 \ |
LOD -6(AR),DR \ |
LOD 6(AR),DR \ |
MOV DR,uR5 \ |
LOD -7(AR),DR \ |
LOD 7(AR),DR \ |
MOV DR,uR6 \ |
LOD -8(AR),DR \ |
LOD 8(AR),DR \ |
MOV DR,uR7 \ |
LOD -9(AR),DR \ |
LOD 9(AR),DR \ |
MOV DR,uR8 \ |
LOD -10(AR),DR \ |
LOD 10(AR),DR \ |
MOV DR,uR9 \ |
LOD -11(AR),DR \ |
LOD 11(AR),DR \ |
MOV DR,uR10 \ |
LOD -12(AR),DR \ |
LOD 12(AR),DR \ |
MOV DR,uR11 \ |
LOD -13(AR),DR \ |
LOD 13(AR),DR \ |
MOV DR,uR12 \ |
LOD -14(AR),DR \ |
LOD 14(AR),DR \ |
MOV DR,uSP \ |
LOD -15(AR),DR \ |
LOD 15(AR),DR \ |
MOV DR,uCC \ |
LOD -16(AR),DR \ |
LOD 16(AR),DR \ |
MOV DR,uPC |
#define READ_USER_TRAP(RG) \ |
MOV uCC,RG \ |
/zipcpu/trunk/sw/zasm/Makefile
95,7 → 95,7
|
.PHONY: test |
test: dumpd.txt |
z.out: test.S zasm zdump zpp |
z.out: test.S sys.i zasm zdump zpp |
./zasm test.S -o z.out |
dumpd.txt: z.out zdump |
./zdump z.out > dumpd.txt |