commit 243031f

zzo38  ·  2022-11-10 03:50:19 +0000 UTC
parent 318a7a4
More enhancements of assembler.
2 files changed,  +18, -4
+11, -2
 1@@ -87,12 +87,14 @@ The following nonstandard tokens are available:
 2 
 3  \~ and a file name will include the contents of the binary file.
 4 
 5+ \. or \, is like . or , but excluding the LIT instruction.
 6+
 7  \ and a number pushes the number to the special stack (which is a stack
 8  which exists only at compile-time).
 9 
10  \: and a name will push the address of the name to the special stack.
11  The label must come before this command; forward references cannot be
12- used with this command.
13+ used with this command, and & also cannot be used.
14 
15  \@ and a name will pop an address from the special stack and define a
16  label whose address is the address which has been popped in this way.
17@@ -123,7 +125,11 @@ that it is interpreted the same as for a & command.
18 
19 Each instruction is a single character.
20 
21-Numbers 0 to 9 push that number to the special stack.
22+Numbers 0 to 9 and a to f push that number to the special stack.
23+
24+'  ( y z -- yz )  Calculates z+(y<<4).
25+
26+"  ( w x y z -- wxyz )  Calculates z+(y<<4)+(x<<8)+(w<<12).
27 
28 _  ( -- )  Set loop point.
29 
30@@ -164,6 +170,9 @@ g  ( address -- value )  Read 8-bits from memory.
31 
32 G  ( address -- value )  Read 16-bits from memory.
33 
34+k  ( count -- count? )  Similar to o (below) but ends the loop if the new
35+count is zero instead of the old count.
36+
37 o  ( count -- count? )  If count is nonzero, decrement and go back to the
38 beginning; if it is already zero then just discards it and continues the
39 execution from here instead.
+7, -2
 1@@ -283,6 +283,9 @@ static int special_calc(const char*w) {
 2   while(*w) switch(*w++) {
 3     case '_': loop=w+1; break;
 4     case '0' ... '9': if(ssptr>255) return 0; sstack[ssptr++]=w[-1]-'0'; break;
 5+    case 'a' ... 'f': if(ssptr>255) return 0; sstack[ssptr++]=w[-1]+10-'a'; break;
 6+    case '\'': if(ssptr<2) return 0; a=sstack[--ssptr]; a+=sstack[--ssptr]<<4; sstack[ssptr++]=a; break;
 7+    case '\"': if(ssptr<4) return 0; a=sstack[--ssptr]; a+=sstack[--ssptr]<<4; a+=sstack[--ssptr]<<8; a+=sstack[--ssptr]<<12; sstack[ssptr++]=a; break;
 8     case '!': if(ssptr<1) return 0; p.ptr=sstack[--ssptr]; break;
 9     case '@': if(ssptr>255) return 0; sstack[ssptr++]=p.ptr; break;
10     case '#': if(ssptr<1) return 0; p.length=sstack[--ssptr]; break;
11@@ -302,14 +305,15 @@ static int special_calc(const char*w) {
12     case 'E': if(ssptr) fprintf(stderr,"User error #%x\n",sstack[ssptr-1]); return 0;
13     case 'g': if(ssptr<1) return 0; a=sstack[--ssptr]; sstack[ssptr++]=p.data[a]; break;
14     case 'G': if(ssptr<1) return 0; a=sstack[--ssptr]; if(a==0xFFFF) return 0; sstack[ssptr++]=(p.data[a]<<8)|p.data[a+1]; break;
15+    case 'k': if(ssptr<1) return 0; if(--sstack[ssptr-1]) w=loop; else --ssptr; break;
16     case 'o': if(ssptr<1) return 0; if(sstack[ssptr-1]--) w=loop; else --ssptr; break;
17     case 'p': if(ssptr<2) return 0; a=sstack[--ssptr]; b=sstack[--ssptr]; p.data[a]=b; break;
18     case 'P': if(ssptr<2) return 0; a=sstack[--ssptr]; b=sstack[--ssptr]; if(a==0xFFFF) return 0; p.data[a]=b>>8; p.data[a+1]=b&255; break;
19     case 'w': if(ssptr<1) return 0; a=sstack[--ssptr]; writebyte(a); break;
20     case 'W': if(ssptr<1) return 0; a=sstack[--ssptr]; writeshort(a,0); break;
21-    case '(': if(ssptr<2) return 0; if(!sstack[--ssptr]) break; while(*w && *w!=')') w++; break;
22+    case '(': if(ssptr<1) return 0; if(!sstack[--ssptr]) break; while(*w && *w!=')') w++; break;
23     case ')': /* do nothing */ break;
24-    case '[': if(ssptr<2) return 0; if(sstack[--ssptr]) break; while(*w && *w!=']') w++; break;
25+    case '[': if(ssptr<1) return 0; if(sstack[--ssptr]) break; while(*w && *w!=']') w++; break;
26     case ']': /* do nothing */ break;
27     default: fprintf(stderr,"Unrecognized special calculation command: %c\n",w[-1]); return 0;
28   }
29@@ -399,6 +403,7 @@ parse(char *w, FILE *f)
30 		switch(w[1]) {
31 		  case '\\': line_comment=1; break;
32 		  case '~': if(!doinclude_binary(w+2)) return error("Invalid include",w); break;
33+		  case '.': case ',': makereference(p.scope,w+1,p.ptr-1); if(!writebyte(0xff)) return 0; break;
34 		  case ':': spec_ref:
35 		    if(!(l=findlabel(w+2))) return error("Invalid reference",w);
36 		    if(ssptr==256) return error("Stack overflow",w);