uxn.c (4249B)
1 #include "uxn.h" 2 3 /* 4 Copyright (u) 2022-2024 Devine Lu Linvega, Andrew Alderwick, Andrew Richards 5 6 Permission to use, copy, modify, and distribute this software for any 7 purpose with or without fee is hereby granted, provided that the above 8 copyright notice and this permission notice appear in all copies. 9 10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 WITH REGARD TO THIS SOFTWARE. 12 */ 13 14 #define OPC(opc, init, body) {\ 15 case 0x00|opc: {const int _2=0,_r=0;init body;} break;\ 16 case 0x20|opc: {const int _2=1,_r=0;init body;} break;\ 17 case 0x40|opc: {const int _2=0,_r=1;init body;} break;\ 18 case 0x60|opc: {const int _2=1,_r=1;init body;} break;\ 19 case 0x80|opc: {const int _2=0,_r=0,k=uxn.wst.ptr;init uxn.wst.ptr=k;body;} break;\ 20 case 0xa0|opc: {const int _2=1,_r=0,k=uxn.wst.ptr;init uxn.wst.ptr=k;body;} break;\ 21 case 0xc0|opc: {const int _2=0,_r=1,k=uxn.rst.ptr;init uxn.rst.ptr=k;body;} break;\ 22 case 0xe0|opc: {const int _2=1,_r=1,k=uxn.rst.ptr;init uxn.rst.ptr=k;body;} break;\ 23 } 24 25 /* Microcode */ 26 27 #define JMI a = uxn.ram[pc] << 8 | uxn.ram[pc + 1], pc += a + 2; 28 #define REM if(_r) uxn.rst.ptr -= 1 + _2; else uxn.wst.ptr -= 1 + _2; 29 #define INC(s) uxn.s.dat[uxn.s.ptr++] 30 #define DEC(s) uxn.s.dat[--uxn.s.ptr] 31 #define JMP(x) { if(_2) pc = x; else pc += (Sint8)x; } 32 #define PO1(o) { o = _r ? DEC(rst) : DEC(wst);} 33 #define PO2(o) { if(_r) o = DEC(rst), o |= DEC(rst) << 8; else o = DEC(wst), o |= DEC(wst) << 8; } 34 #define POx(o) { if(_2) PO2(o) else PO1(o) } 35 #define PU1(i) { if(_r) INC(rst) = i; else INC(wst) = i; } 36 #define RP1(i) { if(_r) INC(wst) = i; else INC(rst) = i; } 37 #define PUx(i) { if(_2) { c = (i); PU1(c >> 8) PU1(c) } else PU1(i) } 38 #define GET(o) { if(_2) PO1(o[1]) PO1(o[0]) } 39 #define PUT(i) { PU1(i[0]) if(_2) PU1(i[1]) } 40 #define DEI(i,o) o[0] = emu_dei(i); if(_2) o[1] = emu_dei(i + 1); PUT(o) 41 #define DEO(i,j) emu_deo(i, j[0]); if(_2) emu_deo(i + 1, j[1]); 42 #define PEK(i,o,m) o[0] = uxn.ram[i]; if(_2) o[1] = uxn.ram[(i + 1) & m]; PUT(o) 43 #define POK(i,j,m) uxn.ram[i] = j[0]; if(_2) uxn.ram[(i + 1) & m] = j[1]; 44 45 int 46 uxn_eval(Uint16 pc) 47 { 48 unsigned int a, b, c, x[2], y[2], z[2], step; 49 if(!pc || uxn.dev[0x0f]) return 0; 50 for(step = STEP_MAX; step; step--) { 51 switch(uxn.ram[pc++]) { 52 /* BRK */ case 0x00: return 1; 53 /* JCI */ case 0x20: if(DEC(wst)) { JMI break; } pc += 2; break; 54 /* JMI */ case 0x40: JMI break; 55 /* JSI */ case 0x60: c = pc + 2; INC(rst) = c >> 8; INC(rst) = c; JMI break; 56 /* LI2 */ case 0xa0: INC(wst) = uxn.ram[pc++]; /* fall-through */ 57 /* LIT */ case 0x80: INC(wst) = uxn.ram[pc++]; break; 58 /* L2r */ case 0xe0: INC(rst) = uxn.ram[pc++]; /* fall-through */ 59 /* LIr */ case 0xc0: INC(rst) = uxn.ram[pc++]; break; 60 /* INC */ OPC(0x01,POx(a),PUx(a + 1)) 61 /* POP */ OPC(0x02,REM ,{}) 62 /* NIP */ OPC(0x03,GET(x) REM ,PUT(x)) 63 /* SWP */ OPC(0x04,GET(x) GET(y),PUT(x) PUT(y)) 64 /* ROT */ OPC(0x05,GET(x) GET(y) GET(z),PUT(y) PUT(x) PUT(z)) 65 /* DUP */ OPC(0x06,GET(x),PUT(x) PUT(x)) 66 /* OVR */ OPC(0x07,GET(x) GET(y),PUT(y) PUT(x) PUT(y)) 67 /* EQU */ OPC(0x08,POx(a) POx(b),PU1(b == a)) 68 /* NEQ */ OPC(0x09,POx(a) POx(b),PU1(b != a)) 69 /* GTH */ OPC(0x0a,POx(a) POx(b),PU1(b > a)) 70 /* LTH */ OPC(0x0b,POx(a) POx(b),PU1(b < a)) 71 /* JMP */ OPC(0x0c,POx(a),JMP(a)) 72 /* JCN */ OPC(0x0d,POx(a) PO1(b),if(b) JMP(a)) 73 /* JSR */ OPC(0x0e,POx(a),RP1(pc >> 8) RP1(pc) JMP(a)) 74 /* STH */ OPC(0x0f,GET(x),RP1(x[0]) if(_2) RP1(x[1])) 75 /* LDZ */ OPC(0x10,PO1(a),PEK(a, x, 0xff)) 76 /* STZ */ OPC(0x11,PO1(a) GET(y),POK(a, y, 0xff)) 77 /* LDR */ OPC(0x12,PO1(a),PEK(pc + (Sint8)a, x, 0xffff)) 78 /* STR */ OPC(0x13,PO1(a) GET(y),POK(pc + (Sint8)a, y, 0xffff)) 79 /* LDA */ OPC(0x14,PO2(a),PEK(a, x, 0xffff)) 80 /* STA */ OPC(0x15,PO2(a) GET(y),POK(a, y, 0xffff)) 81 /* DEI */ OPC(0x16,PO1(a),DEI(a, x)) 82 /* DEO */ OPC(0x17,PO1(a) GET(y),DEO(a, y)) 83 /* ADD */ OPC(0x18,POx(a) POx(b),PUx(b + a)) 84 /* SUB */ OPC(0x19,POx(a) POx(b),PUx(b - a)) 85 /* MUL */ OPC(0x1a,POx(a) POx(b),PUx(b * a)) 86 /* DIV */ OPC(0x1b,POx(a) POx(b),PUx(a ? b / a : 0)) 87 /* AND */ OPC(0x1c,POx(a) POx(b),PUx(b & a)) 88 /* ORA */ OPC(0x1d,POx(a) POx(b),PUx(b | a)) 89 /* EOR */ OPC(0x1e,POx(a) POx(b),PUx(b ^ a)) 90 /* SFT */ OPC(0x1f,PO1(a) POx(b),PUx(b >> (a & 0xf) << (a >> 4))) 91 } 92 } 93 return 0; 94 }