Add LEM1802, keyboard and clock. Fix indirect argument encoding in assembler.

This commit is contained in:
Maurizio Porrato 2020-04-23 08:41:15 +01:00
parent d13d72ce8b
commit 2148ba60aa
3 changed files with 50 additions and 78 deletions

View File

@ -1,10 +1,16 @@
.PHONY: all clean reformat .PHONY: all clean reformat
CFLAGS=-Wall -Werror -pedantic -std=c99 -O2 -mtune=native CFLAGS=-Wall -Werror -pedantic -std=c99 -g3 # -O2 -mtune=native
CFLAGS+=-DDEV_DEBUG -DDEV_LEM1802 -DDEV_CLOCK
CFLAGS+=$(shell pkg-config --cflags sdl2)
LDLIBS+=$(shell pkg-config --libs sdl2)
REFORMAT=astyle --style=linux REFORMAT=astyle --style=linux
DEVICES=$(patsubst %.c,%.o,$(wildcard dev_*.c))
all: dsim all: dsim
dsim: dsim.o device.o $(DEVICES)
clean: clean:
$(RM) *~ *% *.o *.orig $(RM) *~ *% *.o *.orig
$(RM) dsim $(RM) dsim

6
asm.py
View File

@ -53,10 +53,10 @@ class ASM(SimpleNamespace):
if arg.reg == 'SP': if arg.reg == 'SP':
sp = getattr(arg, 'sp', None) sp = getattr(arg, 'sp', None)
if sp is None: if sp is None:
if disp == 0: if arg.disp == 0:
return (0x19, None) return (0x19, None)
else: else:
return (0x1a, disp) return (0x1a, arg.disp)
else: else:
if (sp, is_a) not in (('inc', True), ('dec', False)): if (sp, is_a) not in (('inc', True), ('dec', False)):
raise SyntaxError() raise SyntaxError()
@ -83,7 +83,7 @@ class ASM(SimpleNamespace):
else: else:
b_bits, b_extra = self.addr(self.b, False) b_bits, b_extra = self.addr(self.b, False)
r = [o | (a_bits << 10) | (b_bits << 5)] r = [o | (a_bits << 10) | (b_bits << 5)]
for e in b_extra, a_extra: for e in a_extra, b_extra:
if e is not None: if e is not None:
r.append(e) r.append(e)
print("Assembing: %s %r, %r -> %r" % (self.op, self.b, self.a, r)) print("Assembing: %s %r, %r -> %r" % (self.op, self.b, self.a, r))

114
dsim.c
View File

@ -8,8 +8,9 @@
#include <fcntl.h> #include <fcntl.h>
#include <unistd.h> #include <unistd.h>
#define EMU_ID 0xed6f #include <sys/time.h>
#define EMU_VER 0x0000
#include "device.h"
uint16_t ram[0x10000]; uint16_t ram[0x10000];
uint16_t ra, rb, rc, rx, ry, rz, ri, rj; uint16_t ra, rb, rc, rx, ry, rz, ri, rj;
@ -25,27 +26,8 @@ bool intq_en;
uint16_t intq[MAX_INTQ_SIZE]; uint16_t intq[MAX_INTQ_SIZE];
unsigned int intq_size; unsigned int intq_size;
uint8_t intq_head; uint8_t intq_head;
uint16_t hwn;
void dumpregs() struct timeval time;
{
printf("%4s %4s %4s %4s %4s %4s %4s %4s %4s %4s %4s %4s\n",
"PC","SP","A","B","C","X","Y","Z","I","J","EX","IA");
printf("%04hx %04hx %04hx %04hx %04hx %04hx %04hx %04hx %04hx %04hx %04hx %04hx\n",
rpc, rsp, ra, rb, rc, rx, ry, rz, ri, rj, rex, ria);
}
void dump_ram(uint16_t addr, uint16_t count)
{
uint16_t i, a;
for (i=0; i<count; i++) {
a = (addr + i) % sizeof(ram);
if ((i % 8) == 0)
printf("\n%04x: ", a);
printf("%04x ", ram[a]);
}
printf("\n");
}
void intq_push(uint16_t v) void intq_push(uint16_t v)
{ {
@ -59,7 +41,7 @@ void intq_push(uint16_t v)
uint16_t intq_pop() uint16_t intq_pop()
{ {
if (intq_size > 0) { if (intq_size > 0) {
return intq[(intq_head-intq_size--) % MAX_INTQ_SIZE]; return intq[(intq_head+MAX_INTQ_SIZE-intq_size--) % MAX_INTQ_SIZE];
} else } else
return 0xffff; return 0xffff;
} }
@ -78,47 +60,22 @@ void reset()
trace = false; trace = false;
running = true; running = true;
for (hwn = 0; iodevs[hwn] != NULL; hwn++)
if (iodevs[hwn]->init)
iodevs[hwn]->init();
printf("Initialized %d devices\n", hwn);
} }
struct dev_entry { void shutdown()
uint32_t vendor;
uint32_t product;
uint16_t version;
void (*irqh)();
void (*init)();
void (*free)();
void (*tick)();
};
void debug_irqh()
{ {
switch (ra) { int i;
case 0x0000: for (i = 0; i < hwn; i++)
running = false; if (iodevs[i]->free)
break; iodevs[i]->free();
case 0x0001:
dumpregs();
break;
case 0x0002:
dump_ram(ry, rx);
break;
case 0x0004:
trace = false;
break;
case 0x0005:
trace = true;
break;
case 0xffff:
rx = EMU_ID;
ry = EMU_VER;
break;
}
} }
struct dev_entry iodevs[] = {
{ 0x6d53647c, 0x62e037d3, 0x00000000, debug_irqh, NULL, NULL, NULL }, /* Debug device */
};
uint16_t *val(int operand, bool is_a) uint16_t *val(int operand, bool is_a)
{ {
switch (operand) { switch (operand) {
@ -441,19 +398,19 @@ void oIAQ(uint16_t *a, uint16_t *b)
void oHWN(uint16_t *a, uint16_t *b) void oHWN(uint16_t *a, uint16_t *b)
{ {
*a = sizeof(iodevs) / sizeof(struct dev_entry); *a = hwn;
} }
void oHWQ(uint16_t *a, uint16_t *b) void oHWQ(uint16_t *a, uint16_t *b)
{ {
uint16_t idx = *a; uint16_t idx = *a;
if (idx < sizeof(iodevs) / sizeof(struct dev_entry)) { if (idx < hwn) {
ra = iodevs[idx].product & 0xffff; ra = iodevs[idx]->product & 0xffff;
rb = (iodevs[idx].product >> 16) & 0xffff; rb = (iodevs[idx]->product >> 16) & 0xffff;
rc = iodevs[idx].version; rc = iodevs[idx]->version;
rx = iodevs[idx].vendor & 0xffff; rx = iodevs[idx]->vendor & 0xffff;
ry = (iodevs[idx].vendor >> 16) & 0xffff; ry = (iodevs[idx]->vendor >> 16) & 0xffff;
} else { } else {
ra = rb = rc = rx = ry = 0; ra = rb = rc = rx = ry = 0;
} }
@ -463,9 +420,9 @@ void oHWI(uint16_t *a, uint16_t *b)
{ {
uint16_t idx = *a; uint16_t idx = *a;
if (idx < sizeof(iodevs) / sizeof(struct dev_entry)) { if (idx < hwn) {
if (iodevs[idx].irqh) if (iodevs[idx]->irqh)
iodevs[idx].irqh(); iodevs[idx]->irqh();
} }
} }
@ -493,9 +450,12 @@ void next()
op_t f; op_t f;
uint16_t i; uint16_t i;
gettimeofday(&time, NULL);
if ((!intq_en) && (intq_size > 0) && (!skip_next)) { if ((!intq_en) && (intq_size > 0) && (!skip_next)) {
i = intq_pop(); i = intq_pop();
if (ria != 0) { if (ria != 0) {
printf("Firing interrupt with message 0x%04x\n", i);
intq_en = true; intq_en = true;
ram[--rsp] = rpc; ram[--rsp] = rpc;
ram[--rsp] = ra; ram[--rsp] = ra;
@ -503,10 +463,10 @@ void next()
ra = i; ra = i;
} }
} }
/*
if (trace) if (trace)
dumpregs(); dumpregs();
*/
ir = ram[rpc++]; ir = ram[rpc++];
opcode = ir & 0x001f; opcode = ir & 0x001f;
@ -528,6 +488,10 @@ void next()
else else
skip_next = ((opcode & 0x18) == 0x10); /* Skip chained conditionals */ skip_next = ((opcode & 0x18) == 0x10); /* Skip chained conditionals */
for (i = 0; iodevs[i] != NULL; i++)
if (iodevs[i]->tick)
iodevs[i]->tick();
ticks++; ticks++;
} }
@ -538,6 +502,7 @@ int load_image(char *filename)
ssize_t pos; ssize_t pos;
uint8_t *buf; uint8_t *buf;
printf("Loading %s ...\n", filename);
fd = open(filename, O_RDONLY); fd = open(filename, O_RDONLY);
if (fd < 0) if (fd < 0)
return fd; return fd;
@ -562,6 +527,7 @@ int main(int argc, char *argv[])
load_image(argv[1]); load_image(argv[1]);
reset(); reset();
while (running) next(); while (running) next();
shutdown();
} }
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }