Rewrote hello world to not use the stack
This commit is contained in:
parent
a693d4ef90
commit
89952e8112
25
README.md
25
README.md
|
@ -58,40 +58,43 @@ evaluxn(u, u->vframe); /* Each frame
|
||||||
- `+21 -03 MULS`, signed operators have the cond flag `S`.
|
- `+21 -03 MULS`, signed operators have the cond flag `S`.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
( comment )
|
||||||
|
|
||||||
:dev/w fff9 ( const write port )
|
:dev/w fff9 ( const write port )
|
||||||
;i 1 ( var iterator )
|
|
||||||
|
|
||||||
|0100 @RESET
|
|0100 @RESET
|
||||||
|
|
||||||
#00 ,dev/w STR ( set dev/write to console )
|
#00 ,dev/w STR ( set dev/write to console )
|
||||||
|
,string ( add string pointer to stack )
|
||||||
@word1 "hello_world ( len: 0x0b )
|
|
||||||
|
|
||||||
@loop
|
@loop
|
||||||
IOW ( write to device#0 )
|
DUP2 LDR IOW ( write pointer value to console )
|
||||||
,i LDR #01 ADD ,i STR ( increment itr )
|
#0001 ADD2 ( increment string pointer )
|
||||||
,i LDR ( a = i )
|
DUP2 LDR #00 NEQ ,loop ROT JMP? POP2 ( while *ptr!=0 goto loop )
|
||||||
,word1 ,strlen JSR ( b = string length )
|
|
||||||
NEQ ,loop ROT JSR? POP^ ( a != b ? loop )
|
|
||||||
|
|
||||||
BRK
|
BRK
|
||||||
|
|
||||||
@strlen #0001 ADD2 LDR RTS
|
@string " Hello World " ( add string to memory )
|
||||||
|
|
||||||
|c000 @FRAME BRK
|
|c000 @FRAME BRK
|
||||||
|d000 @ERROR BRK
|
|d000 @ERROR BRK
|
||||||
|
|
||||||
|FFFA .RESET .FRAME .ERROR
|
|FFFA .RESET .FRAME .ERROR
|
||||||
```
|
```
|
||||||
|
|
||||||
## TODOs
|
## TODOs
|
||||||
|
|
||||||
|
- Li1 short mode
|
||||||
|
- Defines?
|
||||||
|
- LDR/STR helpers
|
||||||
|
- Keyboard example
|
||||||
|
- PPU chr device
|
||||||
- Line routine
|
- Line routine
|
||||||
- On-screen debugger.
|
- On-screen debugger.
|
||||||
- Auto-advance ldr?
|
- Auto-advance ldr?
|
||||||
- Getting rid of IOR/IOW would be nice..
|
- Getting rid of IOR/IOW would be nice..
|
||||||
- Sending from the wst to the rst, balance mode/flag?
|
- Sending from the wst to the rst, balance mode/flag?
|
||||||
- Device that works like an extra memory bank
|
- Device that works like an extra memory bank
|
||||||
- Draw a chr sprite.
|
- [debug]Print unused labels
|
||||||
|
|
||||||
## Refs
|
## Refs
|
||||||
|
|
||||||
|
|
83
assembler.c
83
assembler.c
|
@ -33,7 +33,7 @@ Program p;
|
||||||
/* clang-format off */
|
/* clang-format off */
|
||||||
|
|
||||||
char ops[][4] = {
|
char ops[][4] = {
|
||||||
"BRK", "NOP", "LI1", "LIX", "IOR", "IOW", "LDR", "STR",
|
"BRK", "NOP", "LIT", "LIX", "IOR", "IOW", "LDR", "STR",
|
||||||
"JMP", "JSR", "RTI", "RTS", "---", "---", "---", "---",
|
"JMP", "JSR", "RTI", "RTS", "---", "---", "---", "---",
|
||||||
"POP", "DUP", "SWP", "OVR", "ROT", "AND", "ORA", "ROL",
|
"POP", "DUP", "SWP", "OVR", "ROT", "AND", "ORA", "ROL",
|
||||||
"ADD", "SUB", "MUL", "DIV", "EQU", "NEQ", "GTH", "LTH"
|
"ADD", "SUB", "MUL", "DIV", "EQU", "NEQ", "GTH", "LTH"
|
||||||
|
@ -43,7 +43,6 @@ int scmp(char *a, char *b) { int i = 0; while(a[i] == b[i]) if(!a[i++]) return 1
|
||||||
int slen(char *s) { int i = 0; while(s[i] && s[++i]) ; return i; } /* string length */
|
int slen(char *s) { int i = 0; while(s[i] && s[++i]) ; return i; } /* string length */
|
||||||
int sihx(char *s) { int i = 0; char c; while((c = s[i++])) if(!(c >= '0' && c <= '9') && !(c >= 'a' && c <= 'f') && !(c >= 'A' && c <= 'F')) return 0; return 1; } /* string is hexadecimal */
|
int sihx(char *s) { int i = 0; char c; while((c = s[i++])) if(!(c >= '0' && c <= '9') && !(c >= 'a' && c <= 'f') && !(c >= 'A' && c <= 'F')) return 0; return 1; } /* string is hexadecimal */
|
||||||
int shex(char *s) { int n = 0, i = 0; char c; while((c = s[i++])) if(c >= '0' && c <= '9') n = n * 16 + (c - '0'); else if(c >= 'A' && c <= 'F') n = n * 16 + 10 + (c - 'A'); else if(c >= 'a' && c <= 'f') n = n * 16 + 10 + (c - 'a'); return n; } /* string to num */
|
int shex(char *s) { int n = 0, i = 0; char c; while((c = s[i++])) if(c >= '0' && c <= '9') n = n * 16 + (c - '0'); else if(c >= 'A' && c <= 'F') n = n * 16 + 10 + (c - 'A'); else if(c >= 'a' && c <= 'f') n = n * 16 + 10 + (c - 'a'); return n; } /* string to num */
|
||||||
int cmnt(char *w, int *skip) { if(w[0] == ')') { *skip = 0; return 1; } if(w[0] == '(') *skip = 1; if(*skip) return 1; return 0; } /* comment helper */
|
|
||||||
char *scpy(char *src, char *dst, int len) { int i = 0; while((dst[i] = src[i]) && i < len - 2) i++; dst[i + 1] = '\0'; return dst; } /* string copy */
|
char *scpy(char *src, char *dst, int len) { int i = 0; while((dst[i] = src[i]) && i < len - 2) i++; dst[i + 1] = '\0'; return dst; } /* string copy */
|
||||||
|
|
||||||
#pragma mark - Helpers
|
#pragma mark - Helpers
|
||||||
|
@ -63,24 +62,12 @@ pushbyte(Uint8 b, int lit)
|
||||||
void
|
void
|
||||||
pushshort(Uint16 s, int lit)
|
pushshort(Uint16 s, int lit)
|
||||||
{
|
{
|
||||||
if(lit) {
|
if(lit)
|
||||||
pushbyte(0x03, 0);
|
pushbyte(0x22, 0);
|
||||||
pushbyte(0x02, 0);
|
|
||||||
}
|
|
||||||
pushbyte((s >> 8) & 0xff, 0);
|
pushbyte((s >> 8) & 0xff, 0);
|
||||||
pushbyte(s & 0xff, 0);
|
pushbyte(s & 0xff, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
pushtext(char *w)
|
|
||||||
{
|
|
||||||
int i = slen(w);
|
|
||||||
pushbyte(0x03, 0);
|
|
||||||
pushbyte(slen(w), 0);
|
|
||||||
while(i > 0)
|
|
||||||
pushbyte(w[--i], 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
Label *
|
Label *
|
||||||
findlabel(char *s)
|
findlabel(char *s)
|
||||||
{
|
{
|
||||||
|
@ -156,15 +143,62 @@ makevariable(char *id, Uint16 *addr, FILE *f)
|
||||||
return makelabel(id, origin);
|
return makelabel(id, origin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
skipcomment(char *w, int *cap)
|
||||||
|
{
|
||||||
|
if(w[0] == ')') {
|
||||||
|
*cap = 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if(w[0] == '(') *cap = 1;
|
||||||
|
if(*cap) return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
skipstring(char *w, int *cap, Uint16 *addr)
|
||||||
|
{
|
||||||
|
if(w[0] == '"') {
|
||||||
|
if(*cap)
|
||||||
|
*addr += 1;
|
||||||
|
*cap = !(*cap);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if(*cap) {
|
||||||
|
*addr += slen(w) + 1;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
capturestring(char *w, int *cap)
|
||||||
|
{
|
||||||
|
if(w[0] == '"') {
|
||||||
|
if(*cap)
|
||||||
|
pushbyte(0x00, 0);
|
||||||
|
*cap = !(*cap);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if(*cap) {
|
||||||
|
int i;
|
||||||
|
for(i = 0; i < slen(w); ++i)
|
||||||
|
pushbyte(w[i], 0);
|
||||||
|
pushbyte(' ', 0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
pass1(FILE *f)
|
pass1(FILE *f)
|
||||||
{
|
{
|
||||||
int skip = 0;
|
int ccmnt = 0, cstrg = 0;
|
||||||
Uint16 addr = 0;
|
Uint16 addr = 0;
|
||||||
char w[64];
|
char w[64];
|
||||||
while(fscanf(f, "%s", w) == 1) {
|
while(fscanf(f, "%s", w) == 1) {
|
||||||
if(cmnt(w, &skip))
|
if(skipcomment(w, &ccmnt)) continue;
|
||||||
continue;
|
if(skipstring(w, &cstrg, &addr)) continue;
|
||||||
if(w[0] == '@') {
|
if(w[0] == '@') {
|
||||||
if(!makelabel(w + 1, addr))
|
if(!makelabel(w + 1, addr))
|
||||||
return error("Pass1 failed", w);
|
return error("Pass1 failed", w);
|
||||||
|
@ -179,12 +213,11 @@ pass1(FILE *f)
|
||||||
else {
|
else {
|
||||||
switch(w[0]) {
|
switch(w[0]) {
|
||||||
case '|': addr = shex(w + 1); break;
|
case '|': addr = shex(w + 1); break;
|
||||||
case '"': addr += slen(w + 1) + 2; break;
|
|
||||||
case '.': addr += 2; break;
|
case '.': addr += 2; break;
|
||||||
case ',': addr += 4; break;
|
case ',': addr += 3; break;
|
||||||
case '+': /* signed positive */
|
case '+': /* signed positive */
|
||||||
case '-': /* signed negative */
|
case '-': /* signed negative */
|
||||||
case '#': addr += (slen(w + 1) == 2 ? 2 : 4); break;
|
case '#': addr += (slen(w + 1) == 2 ? 2 : 3); break;
|
||||||
default: return error("Unknown label in first pass", w);
|
default: return error("Unknown label in first pass", w);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -196,13 +229,14 @@ pass1(FILE *f)
|
||||||
int
|
int
|
||||||
pass2(FILE *f)
|
pass2(FILE *f)
|
||||||
{
|
{
|
||||||
int skip = 0;
|
int ccmnt = 0, cstrg = 0;
|
||||||
char w[64];
|
char w[64];
|
||||||
while(fscanf(f, "%s", w) == 1) {
|
while(fscanf(f, "%s", w) == 1) {
|
||||||
Uint8 op = 0;
|
Uint8 op = 0;
|
||||||
Label *l;
|
Label *l;
|
||||||
if(w[0] == '@') continue;
|
if(w[0] == '@') continue;
|
||||||
if(cmnt(w, &skip)) continue;
|
if(skipcomment(w, &ccmnt)) continue;
|
||||||
|
if(capturestring(w, &cstrg)) continue;
|
||||||
/* clang-format off */
|
/* clang-format off */
|
||||||
if(w[0] == '|') p.ptr = shex(w + 1);
|
if(w[0] == '|') p.ptr = shex(w + 1);
|
||||||
else if((op = findopcode(w)) || scmp(w, "BRK")) pushbyte(op, 0);
|
else if((op = findopcode(w)) || scmp(w, "BRK")) pushbyte(op, 0);
|
||||||
|
@ -214,7 +248,6 @@ pass2(FILE *f)
|
||||||
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) == 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) == 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] == '-' && sihx(w + 1) && slen(w + 1) == 4) pushshort((Sint16)(shex(w + 1) * -1), 1);
|
||||||
else if(w[0] == '"') pushtext(w + 1);
|
|
||||||
else if((l = findlabel(w + 1))) pushshort(l->addr, w[0] == ',');
|
else if((l = findlabel(w + 1))) pushshort(l->addr, w[0] == ',');
|
||||||
else return error("Unknown label in second pass", w);
|
else return error("Unknown label in second pass", w);
|
||||||
/* clang-format on */
|
/* clang-format on */
|
||||||
|
|
|
@ -9,51 +9,35 @@
|
||||||
|0100 @RESET
|
|0100 @RESET
|
||||||
|
|
||||||
( set dev/write to screen )
|
( set dev/write to screen )
|
||||||
,01 ,dev/w STR
|
#01 ,dev/w STR
|
||||||
|
|
||||||
,01 ,color STR
|
#01 ,color STR
|
||||||
( fill rect x y w h )
|
( fill rect x y w h )
|
||||||
,0020 ,0020 ,0060 ,0040 ,fillrect JSR
|
#0020 #0020 #0060 #0040 ,fillrect JSR
|
||||||
|
|
||||||
,02 ,color STR
|
#02 ,color STR
|
||||||
( fill rect x y w h )
|
( fill rect x y w h )
|
||||||
,0030 ,0030 ,0040 ,0060 ,fillrect JSR
|
#0030 #0030 #0040 #0060 ,fillrect JSR
|
||||||
|
|
||||||
,03 ,color STR
|
#03 ,color STR
|
||||||
( fill rect x y w h )
|
( fill rect x y w h )
|
||||||
,0040 ,0040 ,0060 ,0040 ,fillrect JSR
|
#0040 #0040 #0060 #0040 ,fillrect JSR
|
||||||
|
|
||||||
,01 ,color STR
|
#01 ,color STR
|
||||||
( fill rect x y w h )
|
( fill rect x y w h )
|
||||||
,00a0 ,0010 ,0020 ,0020 ,fillrect JSR
|
#00a0 #0010 #0020 #0020 ,fillrect JSR
|
||||||
|
|
||||||
,02 ,color STR
|
#02 ,color STR
|
||||||
( fill rect x y w h )
|
( fill rect x y w h )
|
||||||
,00b0 ,0040 ,0020 ,0020 ,linerect JSR
|
#00b0 #0040 #0020 #0020 ,linerect JSR
|
||||||
|
|
||||||
,03 ,color STR
|
#03 ,color STR
|
||||||
( fill rect x y w h )
|
( fill rect x y w h )
|
||||||
,0058 ,0028 ,0050 ,0050 ,linerect JSR
|
#0058 #0028 #0050 #0050 ,linerect JSR
|
||||||
|
|
||||||
,01 ,color STR
|
#01 ,color STR
|
||||||
( fill rect x y w h )
|
( fill rect x y w h )
|
||||||
,0028 ,0038 ,0050 ,0030 ,linerect JSR
|
#0028 #0038 #0050 #0030 ,linerect JSR
|
||||||
|
|
||||||
( positive )
|
|
||||||
,01 ,color STR
|
|
||||||
+0030 ,x0 STR2 +0040 ,y0 STR2
|
|
||||||
+0100 ,x1 STR2 +0060 ,y1 STR2
|
|
||||||
,line JSR
|
|
||||||
|
|
||||||
,02 ,color STR
|
|
||||||
+0020 ,x0 STR2 +0010 ,y0 STR2
|
|
||||||
+0090 ,x1 STR2 +0070 ,y1 STR2
|
|
||||||
,line JSR
|
|
||||||
|
|
||||||
,03 ,color STR
|
|
||||||
+0010 ,x0 STR2 +0040 ,y0 STR2
|
|
||||||
+0070 ,x1 STR2 +0060 ,y1 STR2
|
|
||||||
,line JSR
|
|
||||||
|
|
||||||
,redraw JSR
|
,redraw JSR
|
||||||
|
|
||||||
|
@ -66,9 +50,9 @@ BRK
|
||||||
,x LDR2 ,x_ STR2
|
,x LDR2 ,x_ STR2
|
||||||
@fillrectcol
|
@fillrectcol
|
||||||
( draw ) ,x_ LDR2 ,y_ LDR2 ,putpixel JSR
|
( draw ) ,x_ LDR2 ,y_ LDR2 ,putpixel JSR
|
||||||
,x_ LDR2 ,0001 ADD2 ,x_ STR2
|
,x_ LDR2 #0001 ADD2 ,x_ STR2
|
||||||
,x_ LDR2 ,w LDR2 ,x LDR2 ADD2 LTH2 ,fillrectcol ROT JMP? POP2
|
,x_ LDR2 ,w LDR2 ,x LDR2 ADD2 LTH2 ,fillrectcol ROT JMP? POP2
|
||||||
,y_ LDR2 ,0001 ADD2 ,y_ STR2
|
,y_ LDR2 #0001 ADD2 ,y_ STR2
|
||||||
,y_ LDR2 ,h LDR2 ,y LDR2 ADD2 LTH2 ,fillrectrow ROT JMP? POP2
|
,y_ LDR2 ,h LDR2 ,y LDR2 ADD2 LTH2 ,fillrectrow ROT JMP? POP2
|
||||||
RTS
|
RTS
|
||||||
|
|
||||||
|
@ -78,33 +62,13 @@ BRK
|
||||||
@linerectcol
|
@linerectcol
|
||||||
( draw ) ,x LDR2 ,y_ LDR2 ,putpixel JSR
|
( draw ) ,x LDR2 ,y_ LDR2 ,putpixel JSR
|
||||||
( draw ) ,x LDR2 ,w LDR2 ADD2 ,y_ LDR2 ,putpixel JSR
|
( draw ) ,x LDR2 ,w LDR2 ADD2 ,y_ LDR2 ,putpixel JSR
|
||||||
,y_ LDR2 ,0001 ADD2 ,y_ STR2
|
,y_ LDR2 #0001 ADD2 ,y_ STR2
|
||||||
,y_ LDR2 ,h LDR2 ,y LDR2 ADD2 LTH2 ,linerectcol ROT JMP? POP2
|
,y_ LDR2 ,h LDR2 ,y LDR2 ADD2 LTH2 ,linerectcol ROT JMP? POP2
|
||||||
@linerectrow
|
@linerectrow
|
||||||
( draw ) ,x_ LDR2 ,y LDR2 ,putpixel JSR
|
( draw ) ,x_ LDR2 ,y LDR2 ,putpixel JSR
|
||||||
( draw ) ,x_ LDR2 ,y LDR2 ,h LDR2 ADD2 ,putpixel JSR
|
( draw ) ,x_ LDR2 ,y LDR2 ,h LDR2 ADD2 ,putpixel JSR
|
||||||
,x_ LDR2 ,0001 ADD2 ,x_ STR2
|
,x_ LDR2 #0001 ADD2 ,x_ STR2
|
||||||
,x_ LDR2 ,w LDR2 ,x LDR2 ADD2 ,0001 ADD2 LTH2 ,linerectrow ROT JMP? POP2
|
,x_ LDR2 ,w LDR2 ,x LDR2 ADD2 #0001 ADD2 LTH2 ,linerectrow ROT JMP? POP2
|
||||||
RTS
|
|
||||||
|
|
||||||
@line
|
|
||||||
,x0 LDR2 ,x_ STR2 ,y0 LDR2 ,y_ STR2 ( start at x0,y0 )
|
|
||||||
,x1 LDR2 ,x0 LDR2 ,diff16sub JSR ,dx STR2 ( int dx = abs[x1 - x0] )
|
|
||||||
,y1 LDR2 ,y0 LDR2 ,diff16sub JSR -0001 MULS2 ,dy STR2 ( int dy = -abs[y1 - y0] )
|
|
||||||
,dx LDR2 ,dy LDR2 ADDS2 ,err1 STR2 ( int err1 = dx + dy, e2; )
|
|
||||||
@lineloop
|
|
||||||
,x_ LDR2 ,y_ LDR2 ,putpixel JSR ( draw )
|
|
||||||
@line-x
|
|
||||||
,err1 LDR2 +0002 MULS2 ,err2 STR2 ( e2 = 2 * err; )
|
|
||||||
,err2 LDR2 ,dy LDR2 LTHS2 ,line-y ROT JMP? POP2 ( e2 >= dy )
|
|
||||||
,err1 LDR2 ,dy LDR2 ADDS2 ,err1 STR2 ( err1 += dy; )
|
|
||||||
,x_ LDR2 +0001 ADDS2 ,x_ STR2 ( y0 += y0 < y1 ? 1 : -1; )
|
|
||||||
@line-y
|
|
||||||
,err2 LDR2 ,dx LDR2 GTHS2 ,line-end ROT JMP? POP2 ( e2 <= dx )
|
|
||||||
,err1 LDR2 ,dx LDR2 ADDS2 ,err1 STR2 ( err1 += dx; )
|
|
||||||
,y_ LDR2 +0001 ADDS2 ,y_ STR2 ( y0 += y0 < y1 ? 1 : -1; )
|
|
||||||
@line-end
|
|
||||||
,x_ LDR2 ,x1 LDR2 NEQS2 ,lineloop ROT JMP? POP2 ( loop )
|
|
||||||
RTS
|
RTS
|
||||||
|
|
||||||
@diff16
|
@diff16
|
||||||
|
@ -113,17 +77,17 @@ BRK
|
||||||
RTS
|
RTS
|
||||||
|
|
||||||
@redraw
|
@redraw
|
||||||
,0000 IOW2
|
#0000 IOW2
|
||||||
,0000 IOW2
|
#0000 IOW2
|
||||||
,00 IOW
|
#00 IOW
|
||||||
,01 IOW
|
#01 IOW
|
||||||
RTS
|
RTS
|
||||||
|
|
||||||
@putpixel
|
@putpixel
|
||||||
IOW2 ( y short )
|
IOW2 ( y short )
|
||||||
IOW2 ( x short )
|
IOW2 ( x short )
|
||||||
,color LDR IOW ( color byte )
|
,color LDR IOW ( color byte )
|
||||||
,00 IOW ( redraw byte )
|
#00 IOW ( redraw byte )
|
||||||
RTS
|
RTS
|
||||||
|
|
||||||
|c000 @FRAME BRK
|
|c000 @FRAME BRK
|
||||||
|
|
|
@ -1,25 +1,21 @@
|
||||||
( hello world, to console )
|
( comment )
|
||||||
|
|
||||||
:dev/w fff9 ( const write port )
|
:dev/w fff9 ( const write port )
|
||||||
;i 1 ( var iterator )
|
|
||||||
|
|
||||||
|0100 @RESET
|
|0100 @RESET
|
||||||
|
|
||||||
#00 ,dev/w STR ( set dev/write to console )
|
#00 ,dev/w STR ( set dev/write to console )
|
||||||
|
,string ( add string pointer to stack )
|
||||||
@word1 "hello_world ( len: 0x0b )
|
|
||||||
|
|
||||||
@loop
|
@loop
|
||||||
IOW ( write to device#0 )
|
DUP2 LDR IOW ( write pointer value to console )
|
||||||
,i LDR #01 ADD ,i STR ( increment itr )
|
#0001 ADD2 ( increment string pointer )
|
||||||
,i LDR ( a = i )
|
DUP2 LDR #00 NEQ ,loop ROT JMP? POP2 ( while *ptr!=0 goto loop )
|
||||||
,word1 ,strlen JSR ( b = string length )
|
|
||||||
NEQ ,loop ROT JSR? POP^ ( a != b ? loop )
|
|
||||||
|
|
||||||
BRK
|
BRK
|
||||||
|
|
||||||
@strlen #0001 ADD2 LDR RTS
|
@string " Hello World " ( add string to memory )
|
||||||
|
|
||||||
|c000 @FRAME BRK
|
|c000 @FRAME BRK
|
||||||
|d000 @ERROR BRK
|
|d000 @ERROR BRK
|
||||||
|
|
||||||
|FFFA .RESET .FRAME .ERROR
|
|FFFA .RESET .FRAME .ERROR
|
||||||
|
|
|
@ -1,16 +1,21 @@
|
||||||
( comment )
|
( comment )
|
||||||
|
|
||||||
:const abcd
|
:dev/w fff9 ( const write port )
|
||||||
;byte 1
|
|
||||||
;short 2
|
|
||||||
|
|
||||||
|0100 @RESET
|
|0100 @RESET
|
||||||
|
|
||||||
12 34 ADD
|
#00 ,dev/w STR ( set dev/write to console )
|
||||||
1234 0001 ADD2
|
,string ( add string pointer to stack )
|
||||||
|
@loop
|
||||||
|
DUP2 LDR IOW ( write pointer value to console )
|
||||||
|
#0001 ADD2 ( increment string pointer )
|
||||||
|
DUP2 LDR #00 NEQ ,loop ROT JMP? POP2 ( while *ptr!=0 goto loop )
|
||||||
|
|
||||||
BRK
|
BRK
|
||||||
|
|
||||||
|
@string " Hello World " ( add string to memory )
|
||||||
|
|
||||||
|c000 @FRAME BRK
|
|c000 @FRAME BRK
|
||||||
|d000 @ERROR BRK
|
|d000 @ERROR BRK
|
||||||
|
|
||||||
|FFFA .RESET .FRAME .ERROR
|
|FFFA .RESET .FRAME .ERROR
|
||||||
|
|
7
uxn.c
7
uxn.c
|
@ -31,7 +31,7 @@ Uint16 pop16(St8 *s) { return pop8(s) + (pop8(s) << 8); }
|
||||||
Uint16 peek16(St8 *s, Uint8 a) { return peek8(s, a * 2) + (peek8(s, a * 2 + 1) << 8); }
|
Uint16 peek16(St8 *s, Uint8 a) { return peek8(s, a * 2) + (peek8(s, a * 2 + 1) << 8); }
|
||||||
/* I/O */
|
/* I/O */
|
||||||
void op_brk(Uxn *u) { setflag(&u->status,FLAG_HALT, 1); }
|
void op_brk(Uxn *u) { setflag(&u->status,FLAG_HALT, 1); }
|
||||||
void op_li1(Uxn *u) { u->literal += 1; }
|
void op_lit(Uxn *u) { u->literal += 1; }
|
||||||
void op_lix(Uxn *u) { u->literal += u->ram.dat[u->ram.ptr++]; }
|
void op_lix(Uxn *u) { u->literal += u->ram.dat[u->ram.ptr++]; }
|
||||||
void op_nop(Uxn *u) { printf("0x%02x ", 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_ior(Uxn *u) { Device *dev = &u->dev[mempeek8(&u->ram, u->devr)]; if(dev) push8(&u->wst, dev->read(dev, pop8(&u->wst))); }
|
||||||
|
@ -61,6 +61,7 @@ void op_neq(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst,
|
||||||
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_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_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_lit16(Uxn *u) { u->literal += 2; }
|
||||||
void op_nop16(Uxn *u) { printf("%04x\n", pop16(&u->wst)); }
|
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)); }
|
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)); }
|
||||||
void op_iow16(Uxn *u) { Uint8 a = pop8(&u->wst); Uint8 b = pop8(&u->wst); Device *dev = &u->dev[mempeek8(&u->ram, u->devw)]; if(dev) { dev->write(dev, b); dev->write(dev, a); } }
|
void op_iow16(Uxn *u) { Uint8 a = pop8(&u->wst); Uint8 b = pop8(&u->wst); Device *dev = &u->dev[mempeek8(&u->ram, u->devw)]; if(dev) { dev->write(dev, b); dev->write(dev, a); } }
|
||||||
|
@ -86,12 +87,12 @@ void op_gth16(Uxn *u) { Uint16 a = pop16(&u->wst), b = pop16(&u->wst); push8(&u-
|
||||||
void op_lth16(Uxn *u) { Uint16 a = pop16(&u->wst), b = pop16(&u->wst); push8(&u->wst, getflag(&u->status, FLAG_SIGN) ? (Sint16)b < (Sint16)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) ? (Sint16)b < (Sint16)a : b < a); }
|
||||||
|
|
||||||
void (*ops[])(Uxn *u) = {
|
void (*ops[])(Uxn *u) = {
|
||||||
op_brk, op_nop, op_li1, op_lix, op_ior, op_iow, op_ldr, op_str,
|
op_brk, op_nop, op_lit, op_lix, op_ior, op_iow, op_ldr, op_str,
|
||||||
op_jmp, op_jsr, op_nop, op_rts, op_nop, op_nop, op_nop, op_nop,
|
op_jmp, op_jsr, op_nop, op_rts, op_nop, op_nop, op_nop, op_nop,
|
||||||
op_pop, op_dup, op_swp, op_ovr, op_rot, op_and, op_ora, op_rol,
|
op_pop, op_dup, op_swp, op_ovr, op_rot, op_and, op_ora, op_rol,
|
||||||
op_add, op_sub, op_mul, op_div, op_equ, op_neq, op_gth, op_lth,
|
op_add, op_sub, op_mul, op_div, op_equ, op_neq, op_gth, op_lth,
|
||||||
/* 16-bit */
|
/* 16-bit */
|
||||||
op_brk, op_nop16, op_li1, op_lix, op_ior16, op_iow16, op_ldr16, op_str16,
|
op_brk, op_nop16, op_lit16, op_lix, op_ior16, op_iow16, op_ldr16, op_str16,
|
||||||
op_jmp, op_jsr, op_nop, op_rts, op_nop, op_nop, op_nop, op_nop,
|
op_jmp, op_jsr, op_nop, op_rts, op_nop, op_nop, op_nop, op_nop,
|
||||||
op_pop16, op_dup16, op_swp16, op_ovr16, op_rot16, op_and16, op_ora16, op_rol16,
|
op_pop16, op_dup16, op_swp16, op_ovr16, op_rot16, op_and16, op_ora16, op_rol16,
|
||||||
op_add16, op_sub16, op_mul16, op_div16, op_equ16, op_neq16, op_gth16, op_lth16
|
op_add16, op_sub16, op_mul16, op_div16, op_equ16, op_neq16, op_gth16, op_lth16
|
||||||
|
|
Loading…
Reference in New Issue