This commit is contained in:
julianb0 2019-06-19 13:47:10 +02:00
parent f1eae1be22
commit d6716d3112
No known key found for this signature in database
GPG Key ID: DDF8325C95299A62
11 changed files with 256 additions and 150 deletions

View File

@ -11,16 +11,16 @@ kas: kpc as/regs.lst as/k-as.py
DOSK = $(shell find ka -name '*.k')
vm/a.out: $(DOSK)
@cd ka && ../as/k-as.py dos.k 0x100000 ../vm/a.out
vm/a.out: $(DOSK) kas
@cd ka && ../as/k-as.py dos.k 0x100000 ../vm/a.out ../vm/a.sym
.PHONY: clean
clean:
@cd vm && make clean --no-print-directory
@rm -f vm/a.out vm/k.exe vm/stdout.txt as/instrs.lst
@rm -f vm/a.out vm/a.out.sym vm/k.exe vm/stdout.txt as/instrs.lst
test: kas vm/a.out
@vm/k.exe vm/a.out > vm/stdout.txt
test: vm/a.out
@vm/k.exe vm/a.out vm/a.sym > vm/stdout.txt
@rm -f vm/a.out
@echo "output:"
@echo ">>>>>>>>"
@ -29,6 +29,6 @@ test: kas vm/a.out
@echo "<<<<<<<<"
@echo
wc:
wc: clean
@cat $(shell find -name *.[kch]) $(shell find -name *.py) | wc -l

View File

@ -8,11 +8,12 @@ import sys
import subprocess
from array import array
from tempfile import TemporaryFile
from collections import OrderedDict
WANT_DISASM = False
if len(sys.argv) != 4:
print("Usage: {} (output file) (memory entry point) (source file)"
if len(sys.argv) != 5:
print("Usage: {} (output file) (memory entry point) (source file) (symbols file)"
.format(sys.argv[0]))
sys.exit(1)
@ -26,6 +27,7 @@ lst_instrs = open(os.path.join(sys.path[0], "instrs.lst"))
main_src = open(sys.argv[1])
b_out = open(sys.argv[3], "wb")
b_sym = open(sys.argv[4], "w")
start_addr = int(sys.argv[2], base=0)
@ -33,6 +35,7 @@ def leave():
source.close()
instrs.close()
b_out.close()
b_sym.close()
b_data.close()
b_text.close()
main_src.close()
@ -51,8 +54,8 @@ pregs = list()
pinstrs = list()
# labels
plabels_text = dict()
plabels_data = dict()
plabels_text = OrderedDict()
plabels_data = OrderedDict()
# size of .data section
pdata = 0
@ -65,9 +68,6 @@ plastlabel = ''
# after parse() is done, pdata and ptext are never modified
# padding bytes between .text and .data
pdata_pad = 0
#-------------------------------------------------------------------------------
def name_valid(name):
@ -179,6 +179,7 @@ def parse():
if line[0] == ' ' or line[0] == '\t':
line = line.lstrip()
instrs.write(hex(ptext + start_addr) + ' ')
ptext += parse_instr(line)
instrs.write("\n")
@ -676,19 +677,19 @@ special_syms = {
}
def gentext():
instrs.seek(0)
if WANT_DISASM:
int(instrs.read())
instrs.seek(0)
text_start = 0x100000
text_start = start_addr
data_start = text_start + ptext
data_start += (8 - data_start % 8)
instrs.seek(0)
for _, line in enumerate(instrs):
tok = line.strip().split()
#print(tok)
if WANT_DISASM:
print(tok)
tok = tok[1:]
for word in tok:
if len(word) == 0:
@ -722,7 +723,7 @@ def gentext():
continue
if word in plabels_data:
addr = data_start + plabels_data[word] + pdata_pad
addr = data_start + plabels_data[word]
b_text.write(addr.to_bytes(8, byteorder='little', signed=False))
continue
@ -756,6 +757,28 @@ def gentext():
#-------------------------------------------------------------------------------
def sort_by_list(dict_, list_):
for key in list_:
dict_.move_to_end(key)
def gensym():
text_start = start_addr
data_start = text_start + ptext
data_start += (8 - data_start % 8)
for label in plabels_text:
plabels_text[label] += text_start
for label in plabels_data:
plabels_data[label] += data_start
plabels_all = OrderedDict(list(plabels_text.items()) + list(plabels_data.items()))
for key, value in sorted(plabels_all.items(), key=lambda item: item[1]):
b_sym.write("{} {}\n".format(key, value))
#-------------------------------------------------------------------------------
def genout():
b_text.seek(0)
b_data.seek(0)
@ -776,5 +799,6 @@ do_includes(main_src)
parse()
gentext()
genout()
gensym()
leave()
sys.exit(0)

View File

@ -5,6 +5,6 @@
; Main function
;
main:
call cpudev_test
call showoff
ret

94
vm/a.sym Normal file
View File

@ -0,0 +1,94 @@
_start 1048576
_start.1 1048610
itoa 1048626
utoa 1048652
_itoa 1048678
_itoa.conv 1048840
_itoa.nondec 1048928
_itoa.next 1048942
_itoa.fini 1048976
_itoa.bad 1049048
_itoa.zero 1049086
_doprnt 1049120
_doprnt.main_loop 1049250
_doprnt.print_regular 1049286
_doprnt.check_modf 1049344
_doprnt.modf_s 1049640
_doprnt.print_string 1049678
_doprnt.modf_c 1049736
_doprnt.modf_p 1049778
_doprnt.modf_x 1049830
_doprnt.modf_u 1049870
_doprnt.modf_d 1049910
_doprnt.modf_o 1049944
_doprnt.modf_b 1049984
_doprnt.print_number 1050024
_doprnt.print_itoa_buf 1050084
_doprnt.modf_percent 1050156
_doprnt.bad_modifier 1050194
_doprnt.nullstring 1050258
_doprnt.epilogue 1050426
_doprnt.doput 1050512
putc 1050568
printf 1050586
print 1050644
print.1 1050658
print.2 1050702
print_n 1050706
print_n.1 1050714
strnlen 1050742
strlen 1050784
strrev 1050810
strrev.2 1050878
strrev2 1050938
strrev2.2 1050992
strrev2.3 1051044
strcpy 1051048
strncpy 1051074
strnzcpy 1051098
strnzcpy.1 1051136
strcmp 1051154
strncmp 1051180
strchrnul 1051242
strchr 1051276
RFS.GetMaxIdx 1051336
RFS.GetUsage 1051360
RFS.GetCurIdx 1051384
RFS.GetLeastAvail 1051408
RFS.IsFrameActive 1051432
RFS.ActivateFrame 1051456
RFS.DeactivateFrame 1051480
RFS.CopyFrame 1051504
RFS.MoveFrame 1051528
RFS.SwitchFrame 1051552
RFS.LoadArgs 1051576
RFS.LoadReg 1051600
RFS.StoreReg 1051624
IDT.AddHandler 1051648
IDT.DelHandler 1051672
IDT.QueryHandler 1051696
IDT.DoneHandling 1051716
MEM.GetMemOff 1051740
MEM.GetMemSize 1051764
cpudev_test 1051788
trap0_test 1052008
showoff 1052080
printf_test 1052180
strchr_test 1052332
bswap_test 1052396
ramdev_test 1052466
movzx_test 1052502
itoa_test 1052600
devtest 1052764
str_test 1052848
main 1053184
errno 1053208
trap0_test.msg 1053216
printf_test.fmt 1053239
printf_test.str 1053287
strchr_test.str 1053295
itoa_test.buf 1053311
devtest.buf 1053351
str_test.msg 1053391
str_test.buf1 1053407
str_test.buf2 1053447

View File

@ -79,6 +79,7 @@ void enable_stdin_echoing(void);
void disable_stdin_echoing(void);
#include <pc/mem.h>
#include <pc/sym.h>
#include <pc/regs.h>
#include <pc/decd.h>
#include <pc/except.h>

View File

@ -181,30 +181,27 @@ void decode(ctx_t *ctx)
if (w1 >= NINSTRS)
{
illmsg = "No such INSTR";
goto ill;
_except(ctx, E_ILL, "No such INSTR: 0x%hX", w1);
}
in = &ctx->i[w1];
if (nomore)
goto skip_w2;
if (!nomore)
{
//
// Process second word
//
//
// Process second word
//
w2 = ctx->get(ctx);
w2 = ctx->get(ctx);
// REP and COND
rep = !!(w2 & PREF_REP);
cond = (w2 & BITS_COND) >> COND_SHIFT;
// REP and COND
rep = !!(w2 & PREF_REP);
cond = (w2 & BITS_COND) >> COND_SHIFT;
// F1 and F2
f1 = (w2 >> F1_SHIFT) & Fx_MASK;
f2 = w2 & Fx_MASK;
skip_w2:
// F1 and F2
f1 = (w2 >> F1_SHIFT) & Fx_MASK;
f2 = w2 & Fx_MASK;
}
//
// Deal with operand 1

View File

@ -35,37 +35,12 @@ void dump_instr(ctx_t *ctx,
log("%s", in->name);
#if _ATT_STYLE == 1
if (p1 || p2)
{
int l1 = 8, l2 = 8;
if (p1 && ACC_IS_MEM(p1)) {
l1 = p1->mlen;
}
if (p2 && ACC_IS_MEM(p2)) {
l2 = p2->mlen;
}
log("%c", getmempref(l1<l2 ? l1 : l2));
}
#endif
if (rep)
#if _ATT_STYLE == 0
log(".rep");
#else
log("$rep");
#endif
if (cond)
{
#if _ATT_STYLE == 0
log(".");
#else
log("?");
#endif
if (cond & (1 << 4))
{
@ -78,40 +53,27 @@ void dump_instr(ctx_t *ctx,
log("%s", cond_suffixes[cond]);
}
if (!rep
#if _ATT_STYLE == 1
&& cond != CD_CXZ
#endif
) log("\t\t");
if (!rep) log("\t\t");
else
log("\t");
if (p1)
{
#if _ATT_STYLE == 0
dump_acc(ctx, p1);
if (p2) {
log(", ");
dump_acc(ctx, p2);
}
#else
if (p2) {
dump_acc(ctx, p2);
log(", ");
}
dump_acc(ctx, p1);
#endif
}
log("\n");
}
#if _ATT_STYLE == 0
void dump_acc(ctx_t *ctx, acc_t *p)
{
uint mfmt;
sym_t *sym;
if (p->type == A_REG)
log("%s", ctx->r[p->reg].name);
@ -122,7 +84,14 @@ void dump_acc(ctx_t *ctx, acc_t *p)
log("%lu", p->val);
else
log("0x%lX", p->val);
{
sym = find_sym_by_addr(p->val);
if (sym)
log("$%s(0x%lX)", sym->name, sym->addr);
else
log("0x%lX", p->val);
}
}
else
@ -167,63 +136,3 @@ void dump_acc(ctx_t *ctx, acc_t *p)
}
}
#else
void dump_acc(ctx_t *ctx, acc_t *p)
{
uint mfmt;
if (p->type == A_REG)
log("%%%s", ctx->r[p->reg].name);
else if (p->type == A_IMM64)
{
if (p->val < 0xA)
log("$%lu", p->val);
else
log("$0x%lX", p->val);
}
else
{
mfmt = p->type & AM_MFMT_MASK;
if (mfmt == AM_IMM64)
log("($0x%lX)", p->addr);
else if (mfmt == AM_RR)
{
if (p->reg1 && p->reg2)
log("(%%%s,%%%s)", ctx->r[p->reg1].name, ctx->r[p->reg2].name);
else log("(%%%s)", ctx->r[p->reg1 ? p->reg1 : p->reg2].name);
}
else if (mfmt == AM_RRI)
{
if (p->reg1 && p->reg2)
log("%hd(%%%s,%%%s)", p->imm2, ctx->r[p->reg1].name,
ctx->r[p->reg2].name);
else log("%hd(%%%s)", p->imm2,
ctx->r[p->reg1 ? p->reg1 : p->reg2].name);
}
else if (mfmt == AM_RRII)
{
if (p->reg1)
log("%hd(%s,%s,$%u)", p->imm2,
ctx->r[p->reg1].name,
ctx->r[p->reg2].name,
p->imm1);
else
log("%hd(*,%s,$%u)", p->imm2,
ctx->r[p->reg2].name,
p->imm1);
}
}
}
#endif

View File

@ -14,14 +14,6 @@ ushort bget(ctx_t *ctx)
{
ulong addr = rip + cr1;
/*
if (addr % 2) {
_except(ctx, E_ALI, "Misaligned RIP and/or CR1: "
"rip=0x%lX cr1=0x%lX",
rip, cr1);
}
*/
if (addr2real(addr) >= ctx->mz) {
_except(ctx, E_ACC, "Executing out of memory: "
"rip=0x%lX cr1=0x%lX",
@ -30,6 +22,8 @@ ushort bget(ctx_t *ctx)
ushort c = ctx->mp[addr2real(addr)];
//log("bget 0x%lX: 0x%lX\n", addr, c);
rip += 2;
return c;
@ -99,11 +93,13 @@ int main(int argc, char **argv)
//
// Load program
//
if (argc < 2) {
if (argc < 3) {
log("Not enough arguments\n");
exit(-3);
}
create_symtab(argv[2]);
fwfile = fopen(argv[1], "rb");
if (!fwfile) {

View File

@ -145,6 +145,8 @@ void writemem(ctx_t *ctx, ulong val, ulong addr, uint len)
GETREAL();
CHK_RANGE();
// log("writemem: 0x%lX: 0x%lX (%d)\n", addr, val, len);
switch (len) {
case 1: writemem8(ctx, val, real, addr); break;
case 2: writemem16(ctx, val, real, addr); break;

64
vm/pc/sym.c Normal file
View File

@ -0,0 +1,64 @@
// The OS/K Team licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#include <pc/arch.h>
sym_t symtab[SYMTAB_LEN] = { 0 };
int create_symtab(const char *name)
{
FILE *tab = fopen(name, "r");
ulong addr, prev_addr = 0;
char buf[SYMLEN_MAX] = { 0 };
size_t it = 0;
if (!tab)
{
log("Couldn't open symtab\n");
return -1;
}
while (fscanf(tab, "%s %lu\n", buf, &addr) > 0 && it < SYMTAB_LEN)
{
// log("SYM: '%.*s' '%lu'\n", SYMLEN_MAX, buf, addr);
if (prev_addr >= addr)
{
log("Symbol addresses in symbol table not in increasing order\n");
log("Previous symbol: '%s' '%lu'\n", symtab[it-1].name, prev_addr);
log("Current symbol: '%s' '%lu'\n", buf, addr);
exit(-55);
}
prev_addr = addr;
symtab[it].addr = addr;
strcpy(symtab[it].name, buf);
it++;
}
fclose(tab);
return 0;
}
sym_t *find_sym_by_addr(ulong addr)
{
ulong it;
sym_t *sym;
for (it = 0; it < SYMTAB_LEN; it++)
{
sym = &symtab[it];
if (sym->addr == addr)
return sym;
// Addresses in symtab are in increasing order
if (sym->addr == 0 || sym->addr > addr)
return NULL;
}
return NULL;
}

19
vm/pc/sym.h Normal file
View File

@ -0,0 +1,19 @@
// The OS/K Team licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#define SYMLEN_MAX 32
#define SYMTAB_LEN 4096
typedef struct sym_t sym_t;
struct sym_t
{
ulong addr;
char name[SYMLEN_MAX];
};
extern sym_t symtab[SYMTAB_LEN];
int create_symtab(const char *name);
sym_t *find_sym_by_addr(ulong addr);