diff --git a/mach/i80/libem/pro.s b/mach/i80/libem/pro.s index 05976358e..0c5fa3f22 100644 --- a/mach/i80/libem/pro.s +++ b/mach/i80/libem/pro.s @@ -21,8 +21,8 @@ .probyte: pop h push b - mvi e, 0xff - mov d, m + mvi d, 0xff + mov e, m inx h jmp .pron diff --git a/mach/i80/libem/rst.s b/mach/i80/libem/rst.s new file mode 100644 index 000000000..c0d5984d8 --- /dev/null +++ b/mach/i80/libem/rst.s @@ -0,0 +1,54 @@ +# +.sect .text +.sect .rom +.sect .data +.sect .bss +.sect .text + +.define .rst_init +.rst_init: + mvi a, 0xc3 ! jmp + sta 0x08 + sta 0x10 + lxi h, rst1 + shld 0x09 + lxi h, rst2 + shld 0x11 + ret + + ! de = [bc+const1] (remember bc is the frame pointer) +rst1: + pop h + mov a, m + inx h + push h + + mov l, a + ral + sbb a + mov h, a + + dad b + mov e, m + inx h + mov d, m + ret + + ! [bc+const1] = de (remember bc is the frame pointer) +rst2: + pop h + mov a, m + inx h + push h + + mov l, a + ral + sbb a + mov h, a + + dad b + mov m, e + inx h + mov m, d + ret + diff --git a/mach/i80/ncg/mach.c b/mach/i80/ncg/mach.c index a01c11eec..30682eb82 100644 --- a/mach/i80/ncg/mach.c +++ b/mach/i80/ncg/mach.c @@ -4,18 +4,13 @@ * */ -#ifndef NORCSID -static char rcsid[] = "$Id$"; -#endif - /* * machine dependent back end routines for the Intel 8080. */ #include /* atol */ -void con_part(sz, w) register sz; -word w; +void con_part(int sz, word w) { while (part_size % sz) diff --git a/mach/i80/ncg/table b/mach/i80/ncg/table index 0368b31e3..0e3864a44 100644 --- a/mach/i80/ncg/table +++ b/mach/i80/ncg/table @@ -82,6 +82,8 @@ INSTRUCTIONS /* cpo label:ro cost(3,14). */ /* cz label:ro cost(3,14). */ /* daa kills a:cc cost(1, 4). */ + data1 ".data1" const1:ro. + data2 ".data2" const2:ro. dad b_d_h_sp:ro kills hl:cc cost(1,10). dcr reg+lbreg:rw:cc cost(1, 5). dcr m:rw:cc cost(1, 7). @@ -129,7 +131,7 @@ INSTRUCTIONS /* rpe cost(1, 8). */ /* rpo cost(1, 8). */ rrc kills a:cc cost(1, 4). -/* rst const1:ro cost(1,11). */ + rst const1:ro cost(1,11). /* rz cost(1, 8). */ sbb reg1:ro kills a:cc cost(1, 4). /* sbi const1:ro kills a:cc cost(2, 7). */ @@ -241,12 +243,23 @@ pat loc yields {const2,$1} pat ldc yields {const2,highw($1)} {const2,loww($1)} +#ifdef USE_I80_RSTS + pat lol sfit($1, 8) + uses hlreg, areg, dereg + gen + rst {const1, 1} + data1 {const1, $1} + yields de +#endif + pat lol -uses hlreg={const2,$1}, dereg -gen dad lb - mov e,{m} - inx hl - mov d,{m} yields de + uses hlreg={const2, $1}, dereg + gen + dad lb + mov e,{m} + inx hl + mov d,{m} + yields de pat loe uses hlreg @@ -446,13 +459,23 @@ uses hl_or_de={label,$1} yields %a pat stl lol $1==$2 with dereg yields de de leaving stl $1 +#ifdef USE_I80_RSTS + pat stl sfit($1, 8) + with dereg + uses hlreg, areg + gen + rst {const1, 2} + data1 {const1, $1} +#endif + pat stl -with dereg -uses hlreg={const2,$1} -gen dad lb - mov {m},e - inx hl - mov {m},d + with dereg + uses hlreg={const2, $1} + gen + dad lb + mov {m}, e + inx hl + mov {m}, d pat ste loe $1==$2 with hlreg yields hl hl leaving ste $1 diff --git a/mach/proto/ncg/salloc.c b/mach/proto/ncg/salloc.c index 71fe20c3d..0f9fa28f8 100644 --- a/mach/proto/ncg/salloc.c +++ b/mach/proto/ncg/salloc.c @@ -34,7 +34,7 @@ int nstab=0; static void chkstr(string, char *); -string myalloc(size) { +string myalloc(int size) { string p; p = (string) calloc((unsigned)size, 1); diff --git a/mach/proto/ncg/types.h b/mach/proto/ncg/types.h index 35b848e82..825d2e42d 100644 --- a/mach/proto/ncg/types.h +++ b/mach/proto/ncg/types.h @@ -44,6 +44,7 @@ void in_init(char *); void in_start(void); void fillemlines(void); void swtxt(void); +void dopseudo(void); /* gencode.c */ void out_init(char *); void out_finish(void); diff --git a/plat/cpm/boot.s b/plat/cpm/boot.s index 960dc400d..40ab0d775 100644 --- a/plat/cpm/boot.s +++ b/plat/cpm/boot.s @@ -48,6 +48,12 @@ begtext: lxi sp, stack + STACKSIZE + ! Initialise the rsts (if desired). + + #ifdef USE_I80_RSTS + call .rst_init + #endif + ! C-ify the command line at 0x0080. lxi h, 0x0080 diff --git a/plat/cpm/build-pkg.lua b/plat/cpm/build-pkg.lua index 0a4da3be0..59c9f806a 100644 --- a/plat/cpm/build-pkg.lua +++ b/plat/cpm/build-pkg.lua @@ -4,7 +4,10 @@ include("lang/build.lua") ackfile { name = "boot", srcs = { "./boot.s" }, - vars = { plat = "cpm" } + vars = { + plat = "cpm", + ["+ackcflags"] = "-DUSE_I80_RSTS", + } } build_plat_libs { diff --git a/plat/cpm/build-tools.lua b/plat/cpm/build-tools.lua index 383cf8c17..25d1b1327 100644 --- a/plat/cpm/build-tools.lua +++ b/plat/cpm/build-tools.lua @@ -8,6 +8,9 @@ build_as { build_ncg { name = "ncg", arch = "i80", + vars = { + ["+cflags"] = "-DUSE_I80_RSTS" + } } build_top { diff --git a/plat/cpm/emu/dis8080.c b/plat/cpm/emu/dis8080.c index 1adf2bc26..a667c6347 100644 --- a/plat/cpm/emu/dis8080.c +++ b/plat/cpm/emu/dis8080.c @@ -343,24 +343,36 @@ static struct insn insns[0x100] = uint16_t i8080_disassemble(char* buffer, size_t bufsiz, uint16_t pc) { - uint8_t opcode = i8080_read(pc++); + uint8_t opcode = i8080_read(pc); + uint8_t p1 = i8080_read(pc+1); + uint8_t p2 = i8080_read(pc+2); struct insn* insn = &insns[opcode]; uint16_t value = 0; + const char* left = ""; + + snprintf(buffer, bufsiz, "%04x : ", pc); + pc++; + switch (insn->operand) { case NOTHING: + left = "%02x : "; break; case CONST8: - value = i8080_read(pc++); + left = "%02x %02x : "; + value = p1; + pc++; break; case CONST16: - value = i8080_read(pc++); - value |= i8080_read(pc++) << 8; + left = "%02x %02x %02x : "; + value = p1 | (p2<<8); + pc += 2; break; } - snprintf(buffer, bufsiz, insn->name, value); + snprintf(buffer + 7, bufsiz - 7, left, opcode, p1, p2); + snprintf(buffer + 18, bufsiz - 18, insn->name, value); return pc; } diff --git a/plat/cpm/emu/emulator.c b/plat/cpm/emu/emulator.c index 5f8dd1c43..eb192dbf8 100644 --- a/plat/cpm/emu/emulator.c +++ b/plat/cpm/emu/emulator.c @@ -23,6 +23,8 @@ static bool tracing = false; static bool singlestepping = true; static bool bdosbreak = false; +static const char* delimiters = " \t\n\r"; + uint8_t i8080_read(uint16_t addr) { return ram[addr]; @@ -65,13 +67,13 @@ void showregs(void) int tstates; uint16_t pc = i8080_read_reg16(PC); i8080_disassemble(buffer, sizeof(buffer), pc); - printf("%04x : %s\n", pc, buffer); + puts(buffer); } static void cmd_register(void) { - char* w1 = strtok(NULL, " "); - char* w2 = strtok(NULL, " "); + char* w1 = strtok(NULL, delimiters); + char* w2 = strtok(NULL, delimiters); if (w1 && w2) { @@ -102,7 +104,7 @@ static void cmd_register(void) static void cmd_break(void) { - char* w1 = strtok(NULL, " "); + char* w1 = strtok(NULL, delimiters); if (w1) { uint16_t breakpc = strtoul(w1, NULL, 16); @@ -128,7 +130,7 @@ static void cmd_break(void) static void cmd_watch(void) { - char* w1 = strtok(NULL, " "); + char* w1 = strtok(NULL, delimiters); if (w1) { uint16_t watchaddr = strtoul(w1, NULL, 16); @@ -158,7 +160,7 @@ static void cmd_watch(void) static void cmd_delete_breakpoint(void) { - char* w1 = strtok(NULL, " "); + char* w1 = strtok(NULL, delimiters); if (w1) { uint16_t breakpc = strtoul(w1, NULL, 16); @@ -176,7 +178,7 @@ static void cmd_delete_breakpoint(void) static void cmd_delete_watchpoint(void) { - char* w1 = strtok(NULL, " "); + char* w1 = strtok(NULL, delimiters); if (w1) { uint16_t address = strtoul(w1, NULL, 16); @@ -195,8 +197,8 @@ static void cmd_delete_watchpoint(void) static void cmd_memory(void) { - char* w1 = strtok(NULL, " "); - char* w2 = strtok(NULL, " "); + char* w1 = strtok(NULL, delimiters); + char* w2 = strtok(NULL, delimiters); if (!w2) w2 = "100"; @@ -241,9 +243,30 @@ static void cmd_memory(void) } } +static void cmd_unassemble(void) +{ + char* w1 = strtok(NULL, delimiters); + char* w2 = strtok(NULL, delimiters); + uint16_t startaddr = i8080_read_reg16(PC); + uint16_t endaddr; + + if (w1) + startaddr = strtoul(w1, NULL, 16); + endaddr = startaddr + 0x20; + if (w2) + endaddr = startaddr + strtoul(w2, NULL, 16); + + while (startaddr < endaddr) + { + char buffer[80]; + startaddr = i8080_disassemble(buffer, sizeof(buffer), startaddr); + puts(buffer); + } +} + static void cmd_bdos(void) { - char* w1 = strtok(NULL, " "); + char* w1 = strtok(NULL, delimiters); if (w1) bdosbreak = !!strtoul(w1, NULL, 16); else @@ -252,7 +275,7 @@ static void cmd_bdos(void) static void cmd_tracing(void) { - char* w1 = strtok(NULL, " "); + char* w1 = strtok(NULL, delimiters); if (w1) tracing = !!strtoul(w1, NULL, 16); else @@ -270,10 +293,11 @@ static void cmd_help(void) " w set watchpoint\n" " dw delete watchpoint\n" " m show memory\n" + " u unassemble memory\n" " s single step\n" " g continue\n" " bdos 0|1 enable break on bdos entry\n" - " trace 0|1 enable tracing\n" + " tracing 0|1 enable tracing\n" ); } @@ -289,7 +313,7 @@ static void debug(void) if (!fgets(cmdline, sizeof(cmdline), stdin)) exit(0); - char* token = strtok(cmdline, " \n\r\t"); + char* token = strtok(cmdline, delimiters); if (token != NULL) { if (strcmp(token, "?") == 0) @@ -306,6 +330,8 @@ static void debug(void) cmd_delete_watchpoint(); else if (strcmp(token, "m") == 0) cmd_memory(); + else if (strcmp(token, "u") == 0) + cmd_unassemble(); else if (strcmp(token, "s") == 0) { singlestepping = true; diff --git a/plat/cpm/libsys/brk.c b/plat/cpm/libsys/brk.c index 0b83b2523..6c139dd2a 100644 --- a/plat/cpm/libsys/brk.c +++ b/plat/cpm/libsys/brk.c @@ -31,13 +31,25 @@ int brk(void* newend) void* sbrk(int increment) { char* old; + char* new; if (increment == 0) return current; old = current; - if (brk(old + increment) < 0) - return OUT_OF_MEMORY; - + new = old + increment; + + if ((increment > 0) && (new <= old)) + goto out_of_memory; + else if ((increment < 0) && (new >= old)) + goto out_of_memory; + + if (brk(new) < 0) + goto out_of_memory; + return old; + +out_of_memory: + errno = ENOMEM; + return OUT_OF_MEMORY; }