From bb6cb77863e2b6d0e84c698b5b0530d86b6f985c Mon Sep 17 00:00:00 2001 From: Dimitri Sokolyuk Date: Wed, 25 Apr 2012 23:06:58 +0000 Subject: spec 1.3, work in progress: some new ops are on todo --- emu.c | 370 ++++++++++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 257 insertions(+), 113 deletions(-) (limited to 'emu.c') diff --git a/emu.c b/emu.c index 1d363ca..8752c8f 100644 --- a/emu.c +++ b/emu.c @@ -26,218 +26,358 @@ static unsigned short skip = 0; static unsigned short run = 1; static unsigned short cycle = 0; -void ext(unsigned short *a, unsigned short *b); -void set(unsigned short *a, unsigned short *b); -void add(unsigned short *a, unsigned short *b); -void sub(unsigned short *a, unsigned short *b); -void mul(unsigned short *a, unsigned short *b); -void div(unsigned short *a, unsigned short *b); -void mod(unsigned short *a, unsigned short *b); -void shl(unsigned short *a, unsigned short *b); -void shr(unsigned short *a, unsigned short *b); -void and(unsigned short *a, unsigned short *b); -void bor(unsigned short *a, unsigned short *b); -void xor(unsigned short *a, unsigned short *b); -void ife(unsigned short *a, unsigned short *b); -void ifn(unsigned short *a, unsigned short *b); -void ifg(unsigned short *a, unsigned short *b); -void ifb(unsigned short *a, unsigned short *b); +void +nop(unsigned short *a) +{ + cycle += 1; +} -void (*op[nOpt])(unsigned short *a, unsigned short *b) = { - [EXT] = ext, - [SET] = set, - [ADD] = add, - [SUB] = sub, - [MUL] = mul, - [DIV] = div, - [MOD] = mod, - [SHL] = shl, - [SHR] = shr, - [AND] = and, - [BOR] = bor, - [XOR] = xor, - [IFE] = ife, - [IFN] = ifn, - [IFG] = ifg, - [IFB] = ifb, -}; +void +jsr(unsigned short *a) +{ + mem[--reg[SP]] = reg[PC]; + reg[PC] = *a; + cycle += 3; +} + +void +stop(unsigned short *a) +{ + run = 0; + cycle += 1; +} -void nop(unsigned short *a); -void jsr(unsigned short *a); -void stop(unsigned short *a); + +void +intr(unsigned short *a) +{ + /* TODO */ + cycle += 4; +} + +void +iag(unsigned short *a) +{ + /* TODO */ + cycle += 1; +} + +void +ias(unsigned short *a) +{ + /* TODO */ + cycle += 1; +} + +void +hwn(unsigned short *a) +{ + /* TODO */ + cycle += 2; +} + +void +hwq(unsigned short *a) +{ + /* TODO */ + cycle += 4; +} + +void +hwi(unsigned short *a) +{ + /* TODO */ + cycle += 4; +} void (*extop[nExt])(unsigned short *a) = { [NOP] = nop, [JSR] = jsr, [BRK] = stop, + [INT] = intr, + [IAG] = iag, + [IAS] = ias, + [HWN] = hwn, + [HWQ] = hwq, + [HWI] = hwi, }; void -ext(unsigned short *a, unsigned short *b) +ext(unsigned short *b, unsigned short *a) { - if (*a < nExt) - extop[*a](b); + extop[*b](a); } void -set(unsigned short *a, unsigned short *b) +set(unsigned short *b, unsigned short *a) { - *a = *b; + *b = *a; cycle += 1; } void -add(unsigned short *a, unsigned short *b) +add(unsigned short *b, unsigned short *a) { - int tmp = *a; + int tmp = *b; - tmp += *b; - reg[O] = tmp > 0xFFFF; + tmp += *a; + reg[EX] = (tmp > 0xFFFF) ? 0x0001 : 0; - *a = tmp; + *b = tmp; cycle += 2; } void -sub(unsigned short *a, unsigned short *b) +sub(unsigned short *b, unsigned short *a) { - int tmp = *a; + int tmp = *b; - tmp -= *b; - reg[O] = tmp < 0; + tmp -= *a; + reg[EX] = (tmp < 0) ? 0xFFFF : 0; - *a = tmp; + *b = tmp; cycle += 2; } void -mul(unsigned short *a, unsigned short *b) +mul(unsigned short *b, unsigned short *a) { - int tmp = *a; + unsigned int tmp = *b; - tmp *= *b; - reg[O] = tmp >> 16; + tmp *= *a; + reg[EX] = tmp >> 16; - *a = tmp; + *b = tmp; cycle += 2; } void -div(unsigned short *a, unsigned short *b) +mli(unsigned short *b, unsigned short *a) +{ + int tmp = *b; + + tmp *= *a; + reg[EX] = tmp >> 16; + + *b = tmp; + cycle += 2; +} + +void +div(unsigned short *b, unsigned short *a) +{ + unsigned int tmp = *b; + + if (*a == 0) { + reg[EX] = 0; + *b = 0; + } else { + reg[EX] = ((tmp << 16) / *a); + *b /= *a; + } + cycle += 3; +} + +void +dvi(unsigned short *b, unsigned short *a) { - int tmp = *a; + int tmp = *b; - if (*b == 0) { - reg[O] = 0; - *a = 0; + if (*a == 0) { + reg[EX] = 0; + *b = 0; } else { - reg[O] = ((tmp << 16) / *b); - *a /= *b; + reg[EX] = ((tmp << 16) / *a); + *b /= *a; } cycle += 3; } void -mod(unsigned short *a, unsigned short *b) +mod(unsigned short *b, unsigned short *a) { - if (*b == 0) - *a = 0; + if (*a == 0) + *b = 0; else - *a %= *b; + *b %= *a; cycle += 3; } void -shl(unsigned short *a, unsigned short *b) +and(unsigned short *b, unsigned short *a) { - int tmp = *a; + *b &= *a; + cycle += 1; +} - reg[O] = ((tmp << *b) >> 16); - *a <<= *b; +void +bor(unsigned short *b, unsigned short *a) +{ + *b |= *a; + cycle += 1; +} + +void +xor(unsigned short *b, unsigned short *a) +{ + *b ^= *a; + cycle += 1; +} + +void +shr(unsigned short *b, unsigned short *a) +{ + int tmp = *b; + + /* TODO */ + + reg[EX] = ((tmp << 16) >> *a); + *b >>= *a; cycle += 2; } void -shr(unsigned short *a, unsigned short *b) +asr(unsigned short *b, unsigned short *a) { - int tmp = *a; + int tmp = *b; - reg[O] = ((tmp << 16) >> *b); - *a >>= *b; + /* TODO */ + + reg[EX] = ((tmp << 16) >> *a); + *b >>= *a; cycle += 2; } void -and(unsigned short *a, unsigned short *b) +shl(unsigned short *b, unsigned short *a) { - *a &= *b; - cycle += 1; + int tmp = *b; + + /* TODO */ + + reg[EX] = ((tmp << *a) >> 16); + *b <<= *a; + cycle += 2; } void -bor(unsigned short *a, unsigned short *b) +mvi(unsigned short *b, unsigned short *a) { - *a |= *b; - cycle += 1; + *b = *a; + ++reg[I]; + ++reg[J]; + cycle += 2; } void -xor(unsigned short *a, unsigned short *b) +ifb(unsigned short *b, unsigned short *a) { - *a ^= *b; - cycle += 1; + skip = !(*b & *a); + cycle += 2 + skip; } void -ife(unsigned short *a, unsigned short *b) +ifc(unsigned short *b, unsigned short *a) { - skip = !(*a == *b); + skip = (*b & *a); cycle += 2 + skip; } void -ifn(unsigned short *a, unsigned short *b) +ife(unsigned short *b, unsigned short *a) { - skip = !(*a != *b); + skip = !(*b == *a); cycle += 2 + skip; } void -ifg(unsigned short *a, unsigned short *b) +ifn(unsigned short *b, unsigned short *a) { - skip = !(*a > *b); + skip = (*b == *a); cycle += 2 + skip; } void -ifb(unsigned short *a, unsigned short *b) +ifg(unsigned short *b, unsigned short *a) { - skip = !(*a & *b); + skip = !(*b > *a); cycle += 2 + skip; } void -nop(unsigned short *a) +ifa(unsigned short *b, unsigned short *a) { - cycle += 1; + skip = !((signed short)*b > (signed short)*a); + cycle += 2 + skip; } void -jsr(unsigned short *a) +ifl(unsigned short *b, unsigned short *a) { - mem[--reg[SP]] = reg[PC]; - reg[PC] = *a; - cycle += 2; + skip = !(*b < *a); + cycle += 2 + skip; } void -stop(unsigned short *a) +ifu(unsigned short *b, unsigned short *a) { - run = 0; + skip = !((signed short)*b < (signed short)*a); + cycle += 2 + skip; +} + +void +adx(unsigned short *b, unsigned short *a) +{ + int tmp = *b; + + /* TODO */ + tmp += *a + reg[EX]; + reg[EX] = tmp > 0xFFFF ? 0x0001 : 0; + cycle += 3; } +void +sux(unsigned short *b, unsigned short *a) +{ + int tmp = *b; + + /* TODO */ + tmp -= *a + reg[EX]; + reg[EX] = tmp < 0 ? 0x0001 : 0; + cycle += 3; +} + +void (*op[nOpt])(unsigned short *a, unsigned short *b) = { + [EXT] = ext, + [SET] = set, + [ADD] = add, + [SUB] = sub, + [MUL] = mul, + [MLI] = mli, + [DIV] = div, + [DVI] = dvi, + [MOD] = mod, + [AND] = and, + [BOR] = bor, + [XOR] = xor, + [SHR] = shr, + [ASR] = asr, + [SHL] = shl, + [MVI] = mvi, + [IFB] = ifb, + [IFC] = ifc, + [IFE] = ife, + [IFN] = ifn, + [IFG] = ifg, + [IFA] = ifa, + [IFU] = ifu, + [IFL] = ifl, + [ADX] = adx, + [SUX] = sux, +}; + unsigned short * -fetcharg(int a) +fetcharg(int a, int first) { switch (a) { case 0x00: @@ -272,14 +412,17 @@ fetcharg(int a) cycle += 1; return &mem[mem[reg[PC]++] + reg[a - 0x10]]; case 0x18: - /* pop */ - return &mem[reg[SP]++]; + /* TODO push or pop */ + if (first) + return &mem[reg[SP]++]; /* push */ + else + return &mem[--reg[SP]]; /* pop */ case 0x19: /* peek */ return &mem[reg[SP]]; case 0x1a: - /* push */ - return &mem[--reg[SP]]; + /* pick */ + return &mem[reg[SP] + reg[PC]++]; case 0x1b: /* SP */ return ®[SP]; @@ -287,8 +430,8 @@ fetcharg(int a) /* PC */ return ®[PC]; case 0x1d: - /* O */ - return ®[O]; + /* EX */ + return ®[EX]; case 0x1e: /* [next word] */ cycle += 1; @@ -319,17 +462,18 @@ step(unsigned short *m, unsigned short *r) c = mem[reg[PC]++]; s = reg[SP]; /* store SP */ - o = c & 0x0f; - reg[Aux] = (c >> 4) & 0x3f; + o = c & 0x1f; + /* don't fetch first arg for extended opcodes */ - a = o ? fetcharg(reg[Aux]) : ®[Aux]; - b = fetcharg((c >> 10) & 0x3f); + reg[Aux] = (c >> 5) & 0x1f; + b = o ? fetcharg(reg[Aux], 0) : ®[Aux]; + a = fetcharg((c >> 10) & 0x3f, 1); if (skip) { skip = 0; reg[SP] = s; /* restore SP on skipped opcode */ } else - op[o](a, b); + op[o](b, a); usleep(10 * cycle); /* 100kHz */ -- cgit v1.2.3