commit 8855b57
zzo38
·
2023-02-12 20:26:05 +0000 UTC
parent 4392e93
Implement JCI, JMI, JSI opcodes.
M
asm.doc
+12,
-5
1@@ -78,6 +78,10 @@ The following standard tokens are available:
2
3 _ and a name is like , but without the LIT opcode.
4
5+ ? and a name will make a JCI instruction jumping to that label.
6+
7+ ! and a name will make a JMI instruction jumping to that label.
8+
9 " and any characters (other than whitespaces) will emit that sequence of
10 characters without any opcodes or delimiters. (If you need spaces, then
11 you must use separate tokens such as 20 for spaces.)
12@@ -85,7 +89,10 @@ The following standard tokens are available:
13 An instruction opcode consists of three uppercase letters, optionally
14 followed by any combination of instruction flags which can be "2" for
15 16-bit operands, "r" to work with the other stack, and/or "k" to keep
16- the input operands in the stack.
17+ the input operands in the stack. (You cannot code the JCI, JMI, and JSI
18+ instructions in this way, although BRK can be coded in this way.)
19+
20+ A name by itself to make a JSI instruction.
21
22 The following nonstandard tokens are available:
23
24@@ -123,11 +130,11 @@ The following nonstandard tokens are available:
25 ]@ will make a anonymous label which the matching [ before it will
26 reference it.
27
28- [, [. [; [: will act like a , . ; : referencing the anonymous label
29- defined by the matching ]@ command.
30+ [, [. [; [: [? [! will act like a , . ; : ? ! referencing the anonymous
31+ label defined by the matching ]@ command.
32
33- ], ]. ]; ]: will act like a , . ; : referencing the anonymous label
34- defined by the matching [@ command.
35+ ], ]. ]; ]: ]? ]! will act like a , . ; : ? ! referencing the anonymous
36+ label defined by the matching [@ command.
37
38 ]\ acts like \: for the matching [@ command.
39
M
main.c
+6,
-2
1@@ -271,8 +271,7 @@ static void run(Uint16 pc) {
2 if(pc==breakpoint && use_screen) goto stop;
3 s=(v&0x40?&rs:&ds);
4 k=s->p;
5- switch(v&0x1F) {
6- case 0x00: Push8(mem[pc++]); if(v&0x20) Push8(mem[pc++]); break;
7+ switch(v&0x1F?:v) {
8 case 0x01: Pop(x); Push(x+1); break;
9 case 0x02: Pop(x); break;
10 case 0x03: Pop(x); Pop(y); Push(x); break;
11@@ -322,6 +321,11 @@ static void run(Uint16 pc) {
12 case 0x1D: Pop(x); Pop(y); Push(y|x); break;
13 case 0x1E: Pop(x); Pop(y); Push(y^x); break;
14 case 0x1F: Pop8(x); Pop(y); z=x>>4; x&=15; Push((y>>x)<<z); break;
15+ case 0x20: Pop8(x); pc+=x?GET16(mem+pc)+2:2; break;
16+ case 0x40: pc+=GET16(mem+pc)+2; break;
17+ case 0x60: Push16(pc+2); pc+=GET16(mem+pc)+2; break;
18+ case 0x80: case 0xC0: Push8(mem[pc++]); break;
19+ case 0xA0: case 0xE0: Push8(mem[pc++]); Push8(mem[pc++]); break;
20 }
21 continue;
22 stash:
M
uxn.doc
+15,
-3
1@@ -118,7 +118,21 @@ but if 8-bits then it is a signed relative address.
2 This instruction must have the high (keep) bit set. It will push a
3 following one-byte or two-byte number to the stack, which are skipped.
4
5-Instructions 0x20, 0x40, and 0x60 have undefined behaviour.
6+A few instructions must have the exact opcode number and do not use the mode
7+bits in the usual way. With the exception of BRK, a 16-bit relative address
8+is read and skipped past. This relative address is relative to the PC
9+address immediately after, the two bytes giving the address, modulo 65536.
10+
11+00 BRK ( -- )
12+ Stops execution. Execution will continue when a vector is called.
13+20 JCI ( cond8 -- )
14+ If the value received from the stack is nonzero, jump to that relative
15+ address, otherwise continue from here.
16+40 JMI ( -- )
17+ Unconditionally jump to a relative address.
18+60 JSI ( -- <old_addr> )
19+ Unconditionally jump to a relative address, but also push the return
20+ address to the return stack.
21
22
23 === Execution ===
24@@ -132,7 +146,5 @@ vector is zero, then that event is ignored.) Events will never interrupt
25 the program; if it is already running then it will wait until BRK before
26 the next event is processed.
27
28-
29 Stacks and memory are retained between events.
30
31-
M
uxnasm.c
+24,
-5
1@@ -6,7 +6,7 @@ exit
2 #include <stdio.h>
3
4 /*
5-Copyright (c) 2021 Devine Lu Linvega
6+Copyright (c) 2021-2023 Devine Lu Linvega, Andrew Alderwick
7
8 Permission to use, copy, modify, and distribute this software for any
9 purpose with or without fee is hereby granted, provided that the above
10@@ -445,6 +445,12 @@ parse(char *w, FILE *f)
11 while((c = w[++i]))
12 if(!writebyte(c)) return 0;
13 break;
14+ case '?': /* JCI */
15+ makereference(p.scope, w, p.ptr + 1);
16+ return writebyte(0x20) && writeshort(0xffff, 0);
17+ case '!': /* JMI */
18+ makereference(p.scope, w, p.ptr + 1);
19+ return writebyte(0x40) && writeshort(0xffff, 0);
20 case '\\': /* specials */
21 switch(w[1]) {
22 case '\\': line_comment=1; break;
23@@ -475,7 +481,7 @@ parse(char *w, FILE *f)
24 case '[':
25 case ']':
26 if(slen(w) == 1) break;
27- if((w[1]=='.' || w[1]==',' || w[1]==':' || w[1]==';' || w[1]=='@' || w[1]=='\\') && !w[2]) {
28+ if((w[1]=='.' || w[1]==',' || w[1]==':' || w[1]==';' || w[1]=='@' || w[1]=='\\' || w[1]=='?' || w[1]=='!') && !w[2]) {
29 if(*w=='[') {
30 if(bsptr==256) return error("Stack overflow",w);
31 bstack[bsptr++]=i=bcnt++;
32@@ -512,8 +518,13 @@ parse(char *w, FILE *f)
33 return 0;
34 line_comment=0;
35 return 1;
36- } else
37- return error("Unknown token", w);
38+ } else {
39+ *word='!';
40+ scpy(w,word+1,62);
41+ makereference(p.scope, word, p.ptr + 1);
42+ return writebyte(0x60) && writeshort(0xffff, 0);
43+ // return error("Unknown token", w);
44+ }
45 }
46 return 1;
47 }
48@@ -522,7 +533,7 @@ static int
49 resolve(void)
50 {
51 Label *l;
52- int i;
53+ int i,a;
54 for(i = 0; i < p.rlen; i++) {
55 Reference *r = &p.refs[i];
56 switch(r->rune) {
57@@ -568,6 +579,14 @@ resolve(void)
58 p.data[r->addr + 1] = l->addr & 0xff;
59 l->refs++;
60 break;
61+ case '!': case '?':
62+ if(!(l = findlabel(r->name)))
63+ return error("Unknown instant jump reference", r->name);
64+ a = l->addr - r->addr - 2;
65+ p.data[r->addr] = a >> 0x8;
66+ p.data[r->addr + 1] = a & 0xff;
67+ l->refs++;
68+ break;
69 default:
70 return error("Unknown reference", r->name);
71 }