Started implementing signed operations

This commit is contained in:
neauoire 2021-02-12 16:18:52 -08:00
parent 34d4695db4
commit 24e67d34da
9 changed files with 83 additions and 45 deletions

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
View File

@ -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;

2
uxn.h
View File

@ -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;
#define FLAG_HALT 0x01
#define FLAG_SHORT 0x02