Started implementing signed operations
This commit is contained in:
parent
34d4695db4
commit
24e67d34da
|
@ -34,6 +34,8 @@ evaluxn(u, u->vframe); /* Each frame
|
|||
|
||||
- `,literal`, push label value to stack, prefixed with `LIT LEN`.
|
||||
- `.pointer`, push label value to stack.
|
||||
- `+1234`, push positive lit signed value to stack.
|
||||
- `-abcd`, push negative lit signed value to stack.
|
||||
|
||||
### Special
|
||||
|
||||
|
@ -82,14 +84,12 @@ BRK
|
|||
|
||||
## TODOs
|
||||
|
||||
- Implement signed flag to operators.
|
||||
- Line routine
|
||||
- On-screen debugger.
|
||||
- Auto-advance ldr?
|
||||
- Getting rid of IOR/IOW would be nice..
|
||||
- Sending from the wst to the rst, balance mode/flag?
|
||||
- Device that works like an extra memory bank
|
||||
- Line routine
|
||||
- LineRect routine
|
||||
- Draw a chr sprite.
|
||||
|
||||
## Refs
|
||||
|
|
45
assembler.c
45
assembler.c
|
@ -12,7 +12,9 @@ WITH REGARD TO THIS SOFTWARE.
|
|||
*/
|
||||
|
||||
typedef unsigned char Uint8;
|
||||
typedef signed char Sint8;
|
||||
typedef unsigned short Uint16;
|
||||
typedef signed short Sint16;
|
||||
|
||||
typedef struct {
|
||||
int ptr;
|
||||
|
@ -61,6 +63,7 @@ pushbyte(Uint8 b, int lit)
|
|||
void
|
||||
pushshort(Uint16 s, int lit)
|
||||
{
|
||||
printf("%04x[%d]\n", s, lit);
|
||||
if(lit) {
|
||||
pushbyte(0x03, 0);
|
||||
pushbyte(0x02, 0);
|
||||
|
@ -100,7 +103,7 @@ findoperator(char *s)
|
|||
continue;
|
||||
while(s[3 + m]) {
|
||||
if(s[3 + m] == '^') i |= (1 << 5); /* mode: 16 bits */
|
||||
if(s[3 + m] == '~') i |= (1 << 6); /* mode: signed */
|
||||
if(s[3 + m] == '!') i |= (1 << 6); /* mode: signed */
|
||||
if(s[3 + m] == '?') i |= (1 << 7); /* mode: conditional */
|
||||
m++;
|
||||
}
|
||||
|
@ -124,6 +127,8 @@ makelabel(char *name, Uint16 addr)
|
|||
Label *l;
|
||||
if(findlabel(name))
|
||||
return error("Label duplicate", name);
|
||||
if(sihx(name))
|
||||
return error("Label name is hex number", name);
|
||||
l = &labels[labelslen++];
|
||||
l->addr = addr;
|
||||
scpy(name, l->name, 64);
|
||||
|
@ -176,6 +181,8 @@ pass1(FILE *f)
|
|||
case '"': addr += slen(w + 1) + 2; break;
|
||||
case '#': addr += 4; break;
|
||||
case '.': addr += 2; break;
|
||||
case '+': /* signed positive */
|
||||
case '-': /* signed negative */
|
||||
case ',':
|
||||
addr += (sihx(w + 1) && slen(w + 1) == 2 ? 1 : 2);
|
||||
addr += (sihx(w + 1) ? slen(w + 1) / 2 : 2);
|
||||
|
@ -198,26 +205,22 @@ pass2(FILE *f)
|
|||
Label *l;
|
||||
if(w[0] == '@') continue;
|
||||
if(cmnt(w, &skip)) continue;
|
||||
if(w[0] == '|')
|
||||
p.ptr = shex(w + 1);
|
||||
else if(w[0] == ':')
|
||||
fscanf(f, "%s", w);
|
||||
else if(w[0] == ';')
|
||||
fscanf(f, "%s", w);
|
||||
else if(w[0] == '"')
|
||||
pushtext(w + 1);
|
||||
else if(w[0] == '#')
|
||||
pushshort(shex(w + 1) & 0xff, 1);
|
||||
else if((l = findlabel(w + 1)))
|
||||
pushshort(l->addr, w[0] == ',');
|
||||
else if((op = findoperator(w)) || scmp(w, "BRK"))
|
||||
pushbyte(op, 0);
|
||||
else if(sihx(w + 1) && slen(w + 1) == 2)
|
||||
pushbyte(shex(w + 1), w[0] == ',');
|
||||
else if(sihx(w + 1) && slen(w + 1) == 4)
|
||||
pushshort(shex(w + 1), w[0] == ',');
|
||||
else
|
||||
return error("Unknown label", w);
|
||||
/* clang-format off */
|
||||
if(w[0] == '|') p.ptr = shex(w + 1);
|
||||
else if(w[0] == ':') fscanf(f, "%s", w);
|
||||
else if(w[0] == ';') fscanf(f, "%s", w);
|
||||
else if(w[0] == '+' && sihx(w + 1) && slen(w + 1) == 2) pushbyte((Sint8)shex(w + 1), 1);
|
||||
else if(w[0] == '+' && sihx(w + 1) && slen(w + 1) == 4) pushshort((Sint16)shex(w + 1), 1);
|
||||
else if(w[0] == '-' && sihx(w + 1) && slen(w + 1) == 2) pushbyte((Sint8)(shex(w + 1) * -1), 1);
|
||||
else if(w[0] == '-' && sihx(w + 1) && slen(w + 1) == 4) pushshort((Sint16)(shex(w + 1) * -1), 1);
|
||||
else if(w[0] == '"') pushtext(w + 1);
|
||||
else if(w[0] == '#') pushshort(shex(w + 1) & 0xff, 1);
|
||||
else if((l = findlabel(w + 1))) pushshort(l->addr, w[0] == ',');
|
||||
else if((op = findoperator(w)) || scmp(w, "BRK")) pushbyte(op, 0);
|
||||
else if(sihx(w + 1) && slen(w + 1) == 2) pushbyte(shex(w + 1), w[0] == ',');
|
||||
else if(sihx(w + 1) && slen(w + 1) == 4) pushshort(shex(w + 1), w[0] == ',');
|
||||
else return error("Unknown label", w);
|
||||
/* clang-format on */
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
|
2
build.sh
2
build.sh
|
@ -24,5 +24,5 @@ rm -f ./bin/emulator
|
|||
cc -std=c89 -DDEBUG -Wall -Wno-unknown-pragmas -Wpedantic -Wshadow -Wextra -Werror=implicit-int -Werror=incompatible-pointer-types -Werror=int-conversion -Wvla -g -Og -fsanitize=address -fsanitize=undefined uxn.c emulator.c -L/usr/local/lib -lSDL2 -o bin/emulator
|
||||
|
||||
# run
|
||||
./bin/assembler examples/test.usm bin/boot.rom
|
||||
./bin/assembler examples/line.usm bin/boot.rom
|
||||
./bin/emulator bin/boot.rom
|
||||
|
|
|
@ -21,6 +21,12 @@ contexts:
|
|||
- match: '\|(\S+)\s?'
|
||||
scope: punctuation.definition
|
||||
pop: true
|
||||
- match: '\+(\S+)\s?'
|
||||
scope: keyword.control
|
||||
pop: true
|
||||
- match: '\-(\S+)\s?'
|
||||
scope: keyword.control
|
||||
pop: true
|
||||
|
||||
strings:
|
||||
- match: '\:(\S+)\s?'
|
||||
|
@ -35,6 +41,9 @@ contexts:
|
|||
- match: '\,(\S+)\s?'
|
||||
scope: keyword.control
|
||||
pop: true
|
||||
- match: '\#(\S+)\s?'
|
||||
scope: keyword.control
|
||||
pop: true
|
||||
- match: '\.(\S+)\s?'
|
||||
scope: keyword.control
|
||||
pop: true
|
||||
|
|
|
@ -22,6 +22,18 @@
|
|||
,1234 ,1233 GTH^ #0e STR
|
||||
,1234 ,1235 LTH^ #0f STR
|
||||
|
||||
BRK
|
||||
|
||||
@diff8 ( result of abs sub )
|
||||
OVR OVR GTH ,diff8sub ROT JMP? POP^
|
||||
SWP @diff8sub SUB
|
||||
RTS
|
||||
|
||||
@diff16 ( result of abs sub16 )
|
||||
OVR^ OVR^ GTH^ ,diff16sub ROT JMP? POP^
|
||||
SWP^ @diff16sub SUB^
|
||||
RTS
|
||||
|
||||
|c000 @FRAME BRK
|
||||
|d000 @ERROR BRK
|
||||
|FFFA .RESET .FRAME .ERROR
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
|
||||
;x_ 2 ;y_ 2 ;x0 2 ;y0 2 ;x1 2 ;y1 2 ;color 1
|
||||
|
||||
;dx 2 ;dy 2 ;err 2 ;err2 2
|
||||
|
||||
|0100 @RESET
|
||||
|
||||
( set dev/write to screen )
|
||||
|
@ -13,9 +15,10 @@
|
|||
|
||||
( init positions )
|
||||
,0020 ,x0 STR^ ,0018 ,y0 STR^
|
||||
,0030 ,x1 STR^ ,0048 ,y1 STR^
|
||||
,0060 ,x1 STR^ ,0048 ,y1 STR^
|
||||
,x0 LDR^ ,x_ STR^ ,y0 LDR^ ,y_ STR^
|
||||
|
||||
|
||||
( draw control points )
|
||||
,02 ,color STR
|
||||
,x0 LDR^ ,y0 LDR^ ,putpixel JSR
|
||||
|
@ -39,6 +42,11 @@ BRK
|
|||
,00 IOW ( redraw byte )
|
||||
RTS
|
||||
|
||||
@diff16
|
||||
OVR^ OVR^ GTH^ ,diff16sub ROT JMP? POP^
|
||||
SWP^ @diff16sub SUB^
|
||||
RTS
|
||||
|
||||
|c000 @FRAME BRK
|
||||
|d000 @ERROR BRK
|
||||
|FFFA .RESET .FRAME .ERROR
|
||||
|
|
|
@ -3,13 +3,17 @@
|
|||
:dev/r fff8 ( std read port )
|
||||
:dev/w fff9 ( std write port )
|
||||
|
||||
;x 2
|
||||
|
||||
|0100 @RESET
|
||||
|
||||
,00 ,dev/w STR ( set dev/write to console )
|
||||
|
||||
-12 +02 LTH!
|
||||
|
||||
BRK
|
||||
|
||||
|
||||
|c000 @FRAME BRK
|
||||
|d000 @ERROR BRK
|
||||
|FFFA .RESET .FRAME .ERROR
|
||||
|
|
36
uxn.c
36
uxn.c
|
@ -33,7 +33,7 @@ Uint16 peek16(St8 *s, Uint8 a) { return peek8(s, a * 2) + (peek8(s, a * 2 + 1) <
|
|||
void op_brk(Uxn *u) { setflag(&u->status,FLAG_HALT, 1); }
|
||||
void op_li1(Uxn *u) { u->literal += 1; }
|
||||
void op_lix(Uxn *u) { u->literal += u->ram.dat[u->ram.ptr++]; }
|
||||
void op_nop(Uxn *u) { printf("%02x\n", pop8(&u->wst)); }
|
||||
void op_nop(Uxn *u) { printf("0x%02x ", pop8(&u->wst)); }
|
||||
void op_ior(Uxn *u) { Device *dev = &u->dev[mempeek8(&u->ram, u->devr)]; if(dev) push8(&u->wst, dev->read(dev, pop8(&u->wst))); }
|
||||
void op_iow(Uxn *u) { Uint8 a = pop8(&u->wst); Device *dev = &u->dev[mempeek8(&u->ram, u->devw)]; if(dev) dev->write(dev, a); }
|
||||
void op_ldr(Uxn *u) { Uint16 a = pop16(&u->wst); push8(&u->wst, mempeek8(&u->ram, a)); }
|
||||
|
@ -52,14 +52,14 @@ void op_and(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst,
|
|||
void op_ora(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst, b | a); }
|
||||
void op_rol(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst, b << a); }
|
||||
/* Arithmetic */
|
||||
void op_add(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst, b + a); }
|
||||
void op_sub(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst, b - a); }
|
||||
void op_mul(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst, b * a); }
|
||||
void op_div(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst, b / a); }
|
||||
void op_equ(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst, b == a); }
|
||||
void op_neq(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst, b != a); }
|
||||
void op_gth(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst, b > a); }
|
||||
void op_lth(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst, b < a); }
|
||||
void op_add(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst, getflag(&u->status, FLAG_SIGN) ? (Sint8)b + (Sint8)a : b + a); }
|
||||
void op_sub(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst, getflag(&u->status, FLAG_SIGN) ? (Sint8)b - (Sint8)a : b - a); }
|
||||
void op_mul(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst, getflag(&u->status, FLAG_SIGN) ? (Sint8)b * (Sint8)a : b * a); }
|
||||
void op_div(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst, getflag(&u->status, FLAG_SIGN) ? (Sint8)b / (Sint8)a : b / a); }
|
||||
void op_equ(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst, getflag(&u->status, FLAG_SIGN) ? (Sint8)b == (Sint8)a : b == a); }
|
||||
void op_neq(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst, getflag(&u->status, FLAG_SIGN) ? (Sint8)b != (Sint8)a : b != a); }
|
||||
void op_gth(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst, getflag(&u->status, FLAG_SIGN) ? (Sint8)b > (Sint8)a : b > a); }
|
||||
void op_lth(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst, getflag(&u->status, FLAG_SIGN) ? (Sint8)b < (Sint8)a : b < a); }
|
||||
/* --- */
|
||||
void op_nop16(Uxn *u) { printf("%04x\n", pop16(&u->wst)); }
|
||||
void op_ior16(Uxn *u) { Uint8 a = pop8(&u->wst); Device *dev = &u->dev[mempeek8(&u->ram, u->devr)]; if(dev) push16(&u->wst, (dev->read(dev, a) << 8) + dev->read(dev, a + 1)); }
|
||||
|
@ -76,14 +76,14 @@ void op_and16(Uxn *u) { Uint16 a = pop16(&u->wst), b = pop16(&u->wst); push16(&u
|
|||
void op_ora16(Uxn *u) { Uint16 a = pop16(&u->wst), b = pop16(&u->wst); push16(&u->wst, b | a); }
|
||||
void op_rol16(Uxn *u) { Uint16 a = pop16(&u->wst), b = pop16(&u->wst); push16(&u->wst, b << a); }
|
||||
/* Arithmetic(16-bits) */
|
||||
void op_add16(Uxn *u) { Uint16 a = pop16(&u->wst), b = pop16(&u->wst); push16(&u->wst, b + a); }
|
||||
void op_sub16(Uxn *u) { Uint16 a = pop16(&u->wst), b = pop16(&u->wst); push16(&u->wst, b - a); }
|
||||
void op_mul16(Uxn *u) { Uint16 a = pop16(&u->wst), b = pop16(&u->wst); push16(&u->wst, b * a); }
|
||||
void op_div16(Uxn *u) { Uint16 a = pop16(&u->wst), b = pop16(&u->wst); push16(&u->wst, b / a); }
|
||||
void op_equ16(Uxn *u) { Uint16 a = pop16(&u->wst), b = pop16(&u->wst); push8(&u->wst, b == a); }
|
||||
void op_neq16(Uxn *u) { Uint16 a = pop16(&u->wst), b = pop16(&u->wst); push8(&u->wst, b != a); }
|
||||
void op_gth16(Uxn *u) { Uint16 a = pop16(&u->wst), b = pop16(&u->wst); push8(&u->wst, b > a); }
|
||||
void op_lth16(Uxn *u) { Uint16 a = pop16(&u->wst), b = pop16(&u->wst); push8(&u->wst, b < a); }
|
||||
void op_add16(Uxn *u) { Uint16 a = pop16(&u->wst), b = pop16(&u->wst); push16(&u->wst, getflag(&u->status, FLAG_SIGN) ? (Sint8)b + (Sint8)a : b + a); }
|
||||
void op_sub16(Uxn *u) { Uint16 a = pop16(&u->wst), b = pop16(&u->wst); push16(&u->wst, getflag(&u->status, FLAG_SIGN) ? (Sint8)b - (Sint8)a : b - a); }
|
||||
void op_mul16(Uxn *u) { Uint16 a = pop16(&u->wst), b = pop16(&u->wst); push16(&u->wst, getflag(&u->status, FLAG_SIGN) ? (Sint8)b * (Sint8)a : b * a); }
|
||||
void op_div16(Uxn *u) { Uint16 a = pop16(&u->wst), b = pop16(&u->wst); push16(&u->wst, getflag(&u->status, FLAG_SIGN) ? (Sint8)b / (Sint8)a : b / a); }
|
||||
void op_equ16(Uxn *u) { Uint16 a = pop16(&u->wst), b = pop16(&u->wst); push8(&u->wst, getflag(&u->status, FLAG_SIGN) ? (Sint8)b == (Sint8)a : b == a); }
|
||||
void op_neq16(Uxn *u) { Uint16 a = pop16(&u->wst), b = pop16(&u->wst); push8(&u->wst, getflag(&u->status, FLAG_SIGN) ? (Sint8)b != (Sint8)a : b != a); }
|
||||
void op_gth16(Uxn *u) { Uint16 a = pop16(&u->wst), b = pop16(&u->wst); push8(&u->wst, getflag(&u->status, FLAG_SIGN) ? (Sint8)b > (Sint8)a : b > a); }
|
||||
void op_lth16(Uxn *u) { Uint16 a = pop16(&u->wst), b = pop16(&u->wst); push8(&u->wst, getflag(&u->status, FLAG_SIGN) ? (Sint8)b < (Sint8)a : b < a); }
|
||||
|
||||
void (*ops[])(Uxn *u) = {
|
||||
op_brk, op_nop, op_li1, op_lix, op_ior, op_iow, op_ldr, op_str,
|
||||
|
@ -133,7 +133,7 @@ opcuxn(Uxn *u, Uint8 instr)
|
|||
{
|
||||
Uint8 op = instr & 0x1f;
|
||||
setflag(&u->status, FLAG_SHORT, (instr >> 5) & 1);
|
||||
setflag(&u->status, FLAG_SIGN, (instr >> 6) & 1); /* usused */
|
||||
setflag(&u->status, FLAG_SIGN, (instr >> 6) & 1);
|
||||
setflag(&u->status, FLAG_COND, (instr >> 7) & 1);
|
||||
if(getflag(&u->status, FLAG_SHORT))
|
||||
op += 32;
|
||||
|
|
Loading…
Reference in New Issue