(module ;; Import device functions from JavaScript. (import "bedrock" "dget1" (func $dget1 (param $p i32) (result i32))) (import "bedrock" "dset1" (func $dset1 (param $p i32) (param $v i32) (result i32))) ;; We instantiate and export two pages of memory (65536*2 bytes). ;; The first 65535 bytes are program memory, the next 256 bytes are the ;; working stack, and the following 256 bytes are the return stack. ;; Stacks will be downward-growing so that we can push and pop doubles ;; at a time with a single 16-bit instruction (access is little-endian). (memory (export "memory") 2) ;; Cycle counter and pointer declarations. Stack pointers are downward-growing ;; and point to the highest byte on the stack, not to the next empty byte. (global $cc (mut i64) (i64.const 0)) (global $ip (mut i32) (i32.const 0)) (global $wp (mut i32) (i32.const 0x10100)) (global $rp (mut i32) (i32.const 0x10200)) ;; Memory offset constants. (global $ip-base i32 (i32.const 0)) (global $wp-base i32 (i32.const 0x10100)) (global $rp-base i32 (i32.const 0x10200)) ;; Signal constants. (global $SIGNAL.BREAK i32 (i32.const 0)) (global $SIGNAL.HALT i32 (i32.const 1)) (global $SIGNAL.DB1 i32 (i32.const 2)) (global $SIGNAL.DB2 i32 (i32.const 3)) (global $SIGNAL.DB3 i32 (i32.const 4)) (global $SIGNAL.DB4 i32 (i32.const 5)) (global $SIGNAL.DB5 i32 (i32.const 6)) (global $SIGNAL.DB6 i32 (i32.const 7)) (global $SIGNAL.SLEEP i32 (i32.const 8)) (global $SIGNAL.RESET i32 (i32.const 9)) (global $SIGNAL.FORK i32 (i32.const 10)) ;; Re-initialise pointers. (func (export "reset") (global.set $cc (i64.const 0)) (global.set $ip (global.get $ip-base)) (global.set $wp (global.get $wp-base)) (global.set $rp (global.get $rp-base)) ) ;; Provide external access to normal pointer values. (func (export "cc") (result i64) global.get $cc ) (func (export "ip") (result i32) global.get $ip ) (func (export "wp") (result i32) (i32.sub (global.get $wp-base) (global.get $wp)) ) (func (export "rp") (result i32) (i32.sub (global.get $rp-base) (global.get $rp)) ) ;; Push value micro-instructions. (func $wpsh1 (export "wpsh1") (param $v i32) (global.set $wp (i32.sub (global.get $wp) (i32.const 1))) (i32.store8 (global.get $wp) (local.get $v)) ) (func $wpsh2 (export "wpsh2") (param $v i32) (global.set $wp (i32.sub (global.get $wp) (i32.const 2))) (i32.store16 (global.get $wp) (local.get $v)) ) (func $rpsh1 (export "rpsh1") (param $v i32) (global.set $rp (i32.sub (global.get $rp) (i32.const 1))) (i32.store8 (global.get $rp) (local.get $v)) ) (func $rpsh2 (export "rpsh2") (param $v i32) (global.set $rp (i32.sub (global.get $rp) (i32.const 2))) (i32.store16 (global.get $rp) (local.get $v)) ) (func $wpshb (export "wpshb") (param $b i32) (select (i32.const 0xFF) (i32.const 0) (local.get $b)) (call $wpsh1) ) (func $rpshb (export "rpshb") (param $b i32) (select (i32.const 0xFF) (i32.const 0) (local.get $b)) (call $rpsh1) ) ;; Pop value micro-instructions. (func $wpop1 (export "wpop1") (result i32) (i32.load8_u (global.get $wp)) (global.set $wp (i32.add (global.get $wp) (i32.const 1))) ) (func $wpop2 (export "wpop2") (result i32) (i32.load16_u (global.get $wp)) (global.set $wp (i32.add (global.get $wp) (i32.const 2))) ) (func $rpop1 (export "rpop1") (result i32) (i32.load8_u (global.get $rp)) (global.set $rp (i32.add (global.get $rp) (i32.const 1))) ) (func $rpop2 (export "rpop2") (result i32) (i32.load16_u (global.get $rp)) (global.set $rp (i32.add (global.get $rp) (i32.const 2))) ) (func $mpop1 (export "mpop1") (result i32) (i32.load8_u (global.get $ip)) (global.set $ip (i32.add (global.get $ip) (i32.const 1))) ) (func $mpop2 (export "mpop2") (result i32) (i32.shl (i32.load8_u (global.get $ip)) (i32.const 8)) (i32.load8_u (i32.add (global.get $ip) (i32.const 1))) (i32.or) (global.set $ip (i32.add (global.get $ip) (i32.const 2))) ) ;; Get value micro-instructions. (func $wget1 (export "wget1") (result i32) (i32.load8_u (global.get $wp)) ) (func $wget2 (export "wget2") (result i32) (i32.load16_u (global.get $wp)) ) (func $rget1 (export "rget1") (result i32) (i32.load8_u (global.get $rp)) ) (func $rget2 (export "rget2") (result i32) (i32.load16_u (global.get $rp)) ) (func $mget1 (export "mget1") (param $a i32) (result i32) (i32.load8_u (local.get $a)) ) (func $mget2 (export "mget2") (param $a i32) (result i32) (i32.shl (i32.load8_u (local.get $a)) (i32.const 8)) (i32.load8_u (i32.add (local.get $a) (i32.const 1))) (i32.or) ) (func $dget2 (export "dget2") (param $p i32) (result i32) (i32.shl (call $dget1 (local.get $p)) (i32.const 8)) (call $dget1 (i32.add (local.get $p) (i32.const 1))) (i32.or) ) ;; Set value micro-instructions. (func $mset1 (export "mset1") (param $a i32) (param $v i32) (i32.store8 (local.get $a) (local.get $v)) ) (func $mset2 (export "mset2") (param $a i32) (param $v i32) (i32.store8 (local.get $a) (i32.shr_u (local.get $v) (i32.const 8))) (i32.store8 (i32.add (local.get $a) (i32.const 1)) (i32.and (local.get $v) (i32.const 0xFF))) ) (func $dset2 (export "dset2") (param $p i32) (param $v i32) (result i32) (call $dset1 (local.get $p) (i32.shr_u (local.get $v) (i32.const 8))) (call $dset1 (i32.add (local.get $p) (i32.const 1)) (i32.and (local.get $v) (i32.const 0xFF))) (i32.or) ) ;; TODO: Signals are or'd together, at least one must be zero for this to work. ;; Pointer movement micro-instructions. (func $ipmov (export "ipmov") (param $d i32) (global.set $ip (i32.add (global.get $ip) (local.get $d))) ) (func $wpmov (export "wpmov") (param $d i32) (global.set $wp (i32.sub (global.get $wp) (local.get $d))) ) (func $rpmov (export "rpmov") (param $d i32) (global.set $rp (i32.sub (global.get $rp) (local.get $d))) ) ;; Math operations (func $rol1 (export "rol1") (param $v i32) (param $d i32) (result i32) (local.set $d (i32.and (local.get $d) (i32.const 0x7))) (i32.shl (local.get $v) (local.get $d)) (i32.shr_u (local.get $v) (i32.sub (i32.const 8) (local.get $d))) (i32.or) ) (func $ror1 (export "ror1") (param $v i32) (param $d i32) (result i32) (local.set $d (i32.and (local.get $d) (i32.const 0x7))) (i32.shl (local.get $v) (i32.sub (i32.const 8) (local.get $d))) (i32.shr_u (local.get $v) (local.get $d)) (i32.or) ) (func $rol2 (export "rol2") (param $v i32) (param $d i32) (result i32) (local.set $d (i32.and (local.get $d) (i32.const 0xF))) (i32.shl (local.get $v) (local.get $d)) (i32.shr_u (local.get $v) (i32.sub (i32.const 16) (local.get $d))) (i32.or) ) (func $ror2 (export "ror2") (param $v i32) (param $d i32) (result i32) (local.set $d (i32.and (local.get $d) (i32.const 0xF))) (i32.shl (local.get $v) (i32.sub (i32.const 16) (local.get $d))) (i32.shr_u (local.get $v) (local.get $d)) (i32.or) ) ;; TODO: Add a max-cycles parameter, and also keep track of total cycles with an i64. (func (export "eval") (param $c i32) (result i32) ;; Declare local variables. (local $m i64) ;; end mark (local $x i32) ;; register (local.set $m (i64.add (global.get $cc) (i64.extend_i32_u (local.get $c)))) (loop $loop (block $break ;; Increment the cycle counter if we haven't reached our mark. (if (i64.eq (local.get $m) (global.get $cc)) (then (br $break))) (global.set $cc (i64.add (global.get $cc) (i64.const 1))) ;; Switch statement for every instruction variant. The list is in reverse order. (block $NOTr*: (block $ANDr*: (block $XORr*: (block $IORr*: (block $RORr*: (block $ROLr*: (block $SHRr*: (block $SHLr*: (block $NQKr*: (block $EQUr*: (block $GTHr*: (block $LTHr*: (block $DECr*: (block $INCr*: (block $SUBr*: (block $ADDr*: (block $STDr*: (block $LDDr*: (block $STAr*: (block $LDAr*: (block $JCSr*: (block $JCNr*: (block $JMSr*: (block $JMPr*: (block $ROTr*: (block $SWPr*: (block $OVRr*: (block $DUPr*: (block $CPYr*: (block $POPr*: (block $PSHr*: (block $DB6 (block $NOTr* (block $ANDr* (block $XORr* (block $IORr* (block $RORr* (block $ROLr* (block $SHRr* (block $SHLr* (block $NQKr* (block $EQUr* (block $GTHr* (block $LTHr* (block $DECr* (block $INCr* (block $SUBr* (block $ADDr* (block $STDr* (block $LDDr* (block $STAr* (block $LDAr* (block $JCSr* (block $JCNr* (block $JMSr* (block $JMPr* (block $ROTr* (block $SWPr* (block $OVRr* (block $DUPr* (block $CPYr* (block $POPr* (block $PSHr* (block $DB5 (block $NOTr: (block $ANDr: (block $XORr: (block $IORr: (block $RORr: (block $ROLr: (block $SHRr: (block $SHLr: (block $NQKr: (block $EQUr: (block $GTHr: (block $LTHr: (block $DECr: (block $INCr: (block $SUBr: (block $ADDr: (block $STDr: (block $LDDr: (block $STAr: (block $LDAr: (block $JCSr: (block $JCNr: (block $JMSr: (block $JMPr: (block $ROTr: (block $SWPr: (block $OVRr: (block $DUPr: (block $CPYr: (block $POPr: (block $PSHr: (block $DB4 (block $NOTr (block $ANDr (block $XORr (block $IORr (block $RORr (block $ROLr (block $SHRr (block $SHLr (block $NQKr (block $EQUr (block $GTHr (block $LTHr (block $DECr (block $INCr (block $SUBr (block $ADDr (block $STDr (block $LDDr (block $STAr (block $LDAr (block $JCSr (block $JCNr (block $JMSr (block $JMPr (block $ROTr (block $SWPr (block $OVRr (block $DUPr (block $CPYr (block $POPr (block $PSHr (block $DB3 (block $NOT*: (block $AND*: (block $XOR*: (block $IOR*: (block $ROR*: (block $ROL*: (block $SHR*: (block $SHL*: (block $NQK*: (block $EQU*: (block $GTH*: (block $LTH*: (block $DEC*: (block $INC*: (block $SUB*: (block $ADD*: (block $STD*: (block $LDD*: (block $STA*: (block $LDA*: (block $JCS*: (block $JCN*: (block $JMS*: (block $JMP*: (block $ROT*: (block $SWP*: (block $OVR*: (block $DUP*: (block $CPY*: (block $POP*: (block $PSH*: (block $DB2 (block $NOT* (block $AND* (block $XOR* (block $IOR* (block $ROR* (block $ROL* (block $SHR* (block $SHL* (block $NQK* (block $EQU* (block $GTH* (block $LTH* (block $DEC* (block $INC* (block $SUB* (block $ADD* (block $STD* (block $LDD* (block $STA* (block $LDA* (block $JCS* (block $JCN* (block $JMS* (block $JMP* (block $ROT* (block $SWP* (block $OVR* (block $DUP* (block $CPY* (block $POP* (block $PSH* (block $DB1 (block $NOT: (block $AND: (block $XOR: (block $IOR: (block $ROR: (block $ROL: (block $SHR: (block $SHL: (block $NQK: (block $EQU: (block $GTH: (block $LTH: (block $DEC: (block $INC: (block $SUB: (block $ADD: (block $STD: (block $LDD: (block $STA: (block $LDA: (block $JCS: (block $JCN: (block $JMS: (block $JMP: (block $ROT: (block $SWP: (block $OVR: (block $DUP: (block $CPY: (block $POP: (block $PSH: (block $NOP (block $NOT (block $AND (block $XOR (block $IOR (block $ROR (block $ROL (block $SHR (block $SHL (block $NQK (block $EQU (block $GTH (block $LTH (block $DEC (block $INC (block $SUB (block $ADD (block $STD (block $LDD (block $STA (block $LDA (block $JCS (block $JCN (block $JMS (block $JMP (block $ROT (block $SWP (block $OVR (block $DUP (block $CPY (block $POP (block $PSH (block $HLT ;; Branch based on the instruction on the stack. (br_table $HLT $PSH $POP $CPY $DUP $OVR $SWP $ROT $JMP $JMS $JCN $JCS $LDA $STA $LDD $STD $ADD $SUB $INC $DEC $LTH $GTH $EQU $NQK $SHL $SHR $ROL $ROR $IOR $XOR $AND $NOT $NOP $PSH: $POP: $CPY: $DUP: $OVR: $SWP: $ROT: $JMP: $JMS: $JCN: $JCS: $LDA: $STA: $LDD: $STD: $ADD: $SUB: $INC: $DEC: $LTH: $GTH: $EQU: $NQK: $SHL: $SHR: $ROL: $ROR: $IOR: $XOR: $AND: $NOT: $DB1 $PSH* $POP* $CPY* $DUP* $OVR* $SWP* $ROT* $JMP* $JMS* $JCN* $JCS* $LDA* $STA* $LDD* $STD* $ADD* $SUB* $INC* $DEC* $LTH* $GTH* $EQU* $NQK* $SHL* $SHR* $ROL* $ROR* $IOR* $XOR* $AND* $NOT* $DB2 $PSH*: $POP*: $CPY*: $DUP*: $OVR*: $SWP*: $ROT*: $JMP*: $JMS*: $JCN*: $JCS*: $LDA*: $STA*: $LDD*: $STD*: $ADD*: $SUB*: $INC*: $DEC*: $LTH*: $GTH*: $EQU*: $NQK*: $SHL*: $SHR*: $ROL*: $ROR*: $IOR*: $XOR*: $AND*: $NOT*: $DB3 $PSHr $POPr $CPYr $DUPr $OVRr $SWPr $ROTr $JMPr $JMSr $JCNr $JCSr $LDAr $STAr $LDDr $STDr $ADDr $SUBr $INCr $DECr $LTHr $GTHr $EQUr $NQKr $SHLr $SHRr $ROLr $RORr $IORr $XORr $ANDr $NOTr $DB4 $PSHr: $POPr: $CPYr: $DUPr: $OVRr: $SWPr: $ROTr: $JMPr: $JMSr: $JCNr: $JCSr: $LDAr: $STAr: $LDDr: $STDr: $ADDr: $SUBr: $INCr: $DECr: $LTHr: $GTHr: $EQUr: $NQKr: $SHLr: $SHRr: $ROLr: $RORr: $IORr: $XORr: $ANDr: $NOTr: $DB5 $PSHr* $POPr* $CPYr* $DUPr* $OVRr* $SWPr* $ROTr* $JMPr* $JMSr* $JCNr* $JCSr* $LDAr* $STAr* $LDDr* $STDr* $ADDr* $SUBr* $INCr* $DECr* $LTHr* $GTHr* $EQUr* $NQKr* $SHLr* $SHRr* $ROLr* $RORr* $IORr* $XORr* $ANDr* $NOTr* $DB6 $PSHr*: $POPr*: $CPYr*: $DUPr*: $OVRr*: $SWPr*: $ROTr*: $JMPr*: $JMSr*: $JCNr*: $JCSr*: $LDAr*: $STAr*: $LDDr*: $STDr*: $ADDr*: $SUBr*: $INCr*: $DECr*: $LTHr*: $GTHr*: $EQUr*: $NQKr*: $SHLr*: $SHRr*: $ROLr*: $RORr*: $IORr*: $XORr*: $ANDr*: $NOTr*: ;; Load an instruction from memory. (call $mpop1) ) ) (; HLT ;) (return (global.get $SIGNAL.HALT)) ) (; PSH ;) (call $rpop1) (call $wpsh1) (br $loop) ) (; POP ;) (call $wpmov (i32.const -1)) (br $loop) ) (; CPY ;) (call $rget1) (call $wpsh1) (br $loop) ) (; DUP ;) (call $wget1) (call $wpsh1) (br $loop) ) (; OVR ;) (call $wpop1) (call $wget1) (local.set $x) (call $wpsh1) (local.get $x) (call $wpsh1) (br $loop) ) (; SWP ;) (call $wpop1) (call $wpop1) (local.set $x) (call $wpsh1) (local.get $x) (call $wpsh1) (br $loop) ) (; ROT ;) (call $wpop1) (call $wpop1) (call $wpop1) (local.set $x) (call $wpsh1) (call $wpsh1) (local.get $x) (call $wpsh1) (br $loop) ) (; JMP ;) (call $wpop2) (global.set $ip) (br $loop) ) (; JMS ;) (call $wpop2) (global.get $ip) (call $rpsh2) (global.set $ip) (br $loop) ) (; JCN ;) (call $wpop2) (local.set $x) (if (call $wpop1) (then (local.get $x) (global.set $ip))) (br $loop) ) (; JCS ;) (call $wpop2) (local.set $x) (if (call $wpop1) (then (global.get $ip) (call $rpsh2) (local.get $x) (global.set $ip))) (br $loop) ) (; LDA ;) (call $wpop2) (call $mget1) (call $wpsh1) (br $loop) ) (; STA ;) (call $wpop2) (call $wpop1) (call $mset1) (br $loop) ) (; LDD ;) (call $wpop1) (call $dget1) (call $wpsh1) (br $loop) ) (; STD ;) (call $wpop1) (call $wpop1) (call $dset1) (local.set $x) (if (local.get $x) (then (return (local.get $x)))) (br $loop) ) (; ADD ;) (call $wpop1) (call $wpop1) (i32.add) (call $wpsh1) (br $loop) ) (; SUB ;) (call $wpop1) (local.set $x) (call $wpop1) (local.get $x) (i32.sub) (call $wpsh1) (br $loop) ) (; INC ;) (call $wpop1) (i32.add (i32.const 1)) (call $wpsh1) (br $loop) ) (; DEC ;) (call $wpop1) (i32.sub (i32.const 1)) (call $wpsh1) (br $loop) ) (; LTH ;) (call $wpop1) (call $wpop1) (i32.gt_u) (call $wpshb) (br $loop) ) (; GTH ;) (call $wpop1) (call $wpop1) (i32.lt_u) (call $wpshb) (br $loop) ) (; EQU ;) (call $wpop1) (call $wpop1) (i32.eq) (call $wpshb) (br $loop) ) (; NQK ;) (call $wpop1) (local.tee $x) (call $wget1) (local.get $x) (call $wpsh1) (i32.ne) (call $wpshb) (br $loop) ) (; SHL ;) (call $wpop1) (local.set $x) (call $wpop1) (local.get $x) (i32.shl) (call $wpsh1) (br $loop) ) (; SHR ;) (call $wpop1) (local.set $x) (call $wpop1) (local.get $x) (i32.shr_u) (call $wpsh1) (br $loop) ) (; ROL ;) (call $wpop1) (local.set $x) (call $wpop1) (local.get $x) (call $rol1) (call $wpsh1) (br $loop) ) (; ROR ;) (call $wpop1) (local.set $x) (call $wpop1) (local.get $x) (call $ror1) (call $wpsh1) (br $loop) ) (; IOR ;) (call $wpop1) (call $wpop1) (i32.or) (call $wpsh1) (br $loop) ) (; XOR ;) (call $wpop1) (call $wpop1) (i32.xor) (call $wpsh1) (br $loop) ) (; AND ;) (call $wpop1) (call $wpop1) (i32.and) (call $wpsh1) (br $loop) ) (; NOT ;) (call $wpop1) (i32.xor (i32.const 0xFF)) (call $wpsh1) (br $loop) ) (; NOP ;) (br $loop) ) (; PSH: ;) (call $mpop1) (call $wpsh1) (br $loop) ) (; POP: ;) (call $ipmov (i32.const 1)) (br $loop) ) (; CPY: ;) (call $mpop1) (local.tee $x) (call $wpsh1) (local.get $x) (call $rpsh1) (br $loop) ) (; DUP: ;) (call $mpop1) (local.tee $x) (call $wpsh1) (local.get $x) (call $wpsh1) (br $loop) ) (; OVR: ;) (call $mpop1) (call $wget1) (local.set $x) (call $wpsh1) (local.get $x) (call $wpsh1) (br $loop) ) (; SWP: ;) (call $mpop1) (call $wpop1) (local.set $x) (call $wpsh1) (local.get $x) (call $wpsh1) (br $loop) ) (; ROT: ;) (call $mpop1) (call $wpop1) (call $wpop1) (local.set $x) (call $wpsh1) (call $wpsh1) (local.get $x) (call $wpsh1) (br $loop) ) (; JMP: ;) (call $mpop2) (global.set $ip) (br $loop) ) (; JMS: ;) (call $mpop2) (global.get $ip) (call $rpsh2) (global.set $ip) (br $loop) ) (; JCN: ;) (call $mpop2) (local.set $x) (if (call $wpop1) (then (local.get $x) (global.set $ip))) (br $loop) ) (; JCS: ;) (call $mpop2) (local.set $x) (if (call $wpop1) (then (global.get $ip) (call $rpsh2) (local.get $x) (global.set $ip))) (br $loop) ) (; LDA: ;) (call $mpop2) (call $mget1) (call $wpsh1) (br $loop) ) (; STA: ;) (call $mpop2) (call $wpop1) (call $mset1) (br $loop) ) (; LDD: ;) (call $mpop1) (call $dget1) (call $wpsh1) (br $loop) ) (; STD: ;) (call $mpop1) (call $wpop1) (call $dset1) (local.set $x) (if (local.get $x) (then (return (local.get $x)))) (br $loop) ) (; ADD: ;) (call $mpop1) (call $wpop1) (i32.add) (call $wpsh1) (br $loop) ) (; SUB: ;) (call $mpop1) (local.set $x) (call $wpop1) (local.get $x) (i32.sub) (call $wpsh1) (br $loop) ) (; INC: ;) (call $mpop1) (i32.add (i32.const 1)) (call $wpsh1) (br $loop) ) (; DEC: ;) (call $mpop1) (i32.sub (i32.const 1)) (call $wpsh1) (br $loop) ) (; LTH: ;) (call $mpop1) (call $wpop1) (i32.gt_u) (call $wpshb) (br $loop) ) (; GTH: ;) (call $mpop1) (call $wpop1) (i32.lt_u) (call $wpshb) (br $loop) ) (; EQU: ;) (call $mpop1) (call $wpop1) (i32.eq) (call $wpshb) (br $loop) ) (; NQK: ;) (call $mpop1) (local.tee $x) (call $wget1) (local.get $x) (call $wpsh1) (i32.ne) (call $wpshb) (br $loop) ) (; SHL: ;) (call $mpop1) (local.set $x) (call $wpop1) (local.get $x) (i32.shl) (call $wpsh1) (br $loop) ) (; SHR: ;) (call $mpop1) (local.set $x) (call $wpop1) (local.get $x) (i32.shr_u) (call $wpsh1) (br $loop) ) (; ROL: ;) (call $mpop1) (local.set $x) (call $wpop1) (local.get $x) (call $rol1) (call $wpsh1) (br $loop) ) (; ROR: ;) (call $mpop1) (local.set $x) (call $wpop1) (local.get $x) (call $ror1) (call $wpsh1) (br $loop) ) (; IOR: ;) (call $mpop1) (call $wpop1) (i32.or) (call $wpsh1) (br $loop) ) (; XOR: ;) (call $mpop1) (call $wpop1) (i32.xor) (call $wpsh1) (br $loop) ) (; AND: ;) (call $mpop1) (call $wpop1) (i32.and) (call $wpsh1) (br $loop) ) (; NOT: ;) (call $mpop1) (i32.xor (i32.const 0xFF)) (call $wpsh1) (br $loop) ) (; DB1* ;) (return (global.get $SIGNAL.DB1)) ) (; PSH* ;) (call $rpop2) (call $wpsh2) (br $loop) ) (; POP* ;) (call $wpmov (i32.const -2)) (br $loop) ) (; CPY* ;) (call $rget2) (call $wpsh2) (br $loop) ) (; DUP* ;) (call $wget2) (call $wpsh2) (br $loop) ) (; OVR* ;) (call $wpop2) (call $wget2) (local.set $x) (call $wpsh2) (local.get $x) (call $wpsh2) (br $loop) ) (; SWP* ;) (call $wpop2) (call $wpop2) (local.set $x) (call $wpsh2) (local.get $x) (call $wpsh2) (br $loop) ) (; ROT* ;) (call $wpop2) (call $wpop2) (call $wpop2) (local.set $x) (call $wpsh2) (call $wpsh2) (local.get $x) (call $wpsh2) (br $loop) ) (; JMP* ;) (call $wpop2) (global.set $ip) (br $loop) ) (; JMS* ;) (call $wpop2) (global.get $ip) (call $rpsh2) (global.set $ip) (br $loop) ) (; JCN* ;) (call $wpop2) (local.set $x) (if (call $wpop2) (then (local.get $x) (global.set $ip))) (br $loop) ) (; JCS* ;) (call $wpop2) (local.set $x) (if (call $wpop2) (then (global.get $ip) (call $rpsh2) (local.get $x) (global.set $ip))) (br $loop) ) (; LDA* ;) (call $wpop2) (call $mget2) (call $wpsh2) (br $loop) ) (; STA* ;) (call $wpop2) (call $wpop2) (call $mset2) (br $loop) ) (; LDD* ;) (call $wpop1) (call $dget2) (call $wpsh2) (br $loop) ) (; STD* ;) (call $wpop1) (call $wpop2) (call $dset2) (local.set $x) (if (local.get $x) (then (return (local.get $x)))) (br $loop) ) (; ADD* ;) (call $wpop2) (call $wpop2) (i32.add) (call $wpsh2) (br $loop) ) (; SUB* ;) (call $wpop2) (local.set $x) (call $wpop2) (local.get $x) (i32.sub) (call $wpsh2) (br $loop) ) (; INC* ;) (call $wpop2) (i32.add (i32.const 1)) (call $wpsh2) (br $loop) ) (; DEC* ;) (call $wpop2) (i32.sub (i32.const 1)) (call $wpsh2) (br $loop) ) (; LTH* ;) (call $wpop2) (call $wpop2) (i32.gt_u) (call $wpshb) (br $loop) ) (; GTH* ;) (call $wpop2) (call $wpop2) (i32.lt_u) (call $wpshb) (br $loop) ) (; EQU* ;) (call $wpop2) (call $wpop2) (i32.eq) (call $wpshb) (br $loop) ) (; NQK* ;) (call $wpop2) (local.tee $x) (call $wget2) (local.get $x) (call $wpsh2) (i32.ne) (call $wpshb) (br $loop) ) (; SHL* ;) (call $wpop1) (local.set $x) (call $wpop2) (local.get $x) (i32.shl) (call $wpsh2) (br $loop) ) (; SHR* ;) (call $wpop1) (local.set $x) (call $wpop2) (local.get $x) (i32.shr_u) (call $wpsh2) (br $loop) ) (; ROL* ;) (call $wpop1) (local.set $x) (call $wpop2) (local.get $x) (call $rol2) (call $wpsh2) (br $loop) ) (; ROR* ;) (call $wpop1) (local.set $x) (call $wpop2) (local.get $x) (call $ror2) (call $wpsh2) (br $loop) ) (; IOR* ;) (call $wpop2) (call $wpop2) (i32.or) (call $wpsh2) (br $loop) ) (; XOR* ;) (call $wpop2) (call $wpop2) (i32.xor) (call $wpsh2) (br $loop) ) (; AND* ;) (call $wpop2) (call $wpop2) (i32.and) (call $wpsh2) (br $loop) ) (; NOT* ;) (call $wpop2) (i32.xor (i32.const 0xFFFF)) (call $wpsh2) (br $loop) ) (; DB2 ;) (return (global.get $SIGNAL.DB2)) ) (; PSH*: ;) (call $mpop2) (call $wpsh2) (br $loop) ) (; POP*: ;) (call $ipmov (i32.const 2)) (br $loop) ) (; CPY*: ;) (call $mpop2) (local.tee $x) (call $wpsh2) (local.get $x) (call $rpsh2) (br $loop) ) (; DUP*: ;) (call $mpop2) (local.tee $x) (call $wpsh2) (local.get $x) (call $wpsh2) (br $loop) ) (; OVR*: ;) (call $mpop2) (call $wget2) (local.set $x) (call $wpsh2) (local.get $x) (call $wpsh2) (br $loop) ) (; SWP*: ;) (call $mpop2) (call $wpop2) (local.set $x) (call $wpsh2) (local.get $x) (call $wpsh2) (br $loop) ) (; ROT*: ;) (call $mpop2) (call $wpop2) (call $wpop2) (local.set $x) (call $wpsh2) (call $wpsh2) (local.get $x) (call $wpsh2) (br $loop) ) (; JMP*: ;) (call $mpop2) (global.set $ip) (br $loop) ) (; JMS*: ;) (call $mpop2) (global.get $ip) (call $rpsh2) (global.set $ip) (br $loop) ) (; JCN*: ;) (call $mpop2) (local.set $x) (if (call $wpop2) (then (local.get $x) (global.set $ip))) (br $loop) ) (; JCS*: ;) (call $mpop2) (local.set $x) (if (call $wpop2) (then (global.get $ip) (call $rpsh2) (local.get $x) (global.set $ip))) (br $loop) ) (; LDA*: ;) (call $mpop2) (call $mget2) (call $wpsh2) (br $loop) ) (; STA*: ;) (call $mpop2) (call $wpop2) (call $mset2) (br $loop) ) (; LDD*: ;) (call $mpop1) (call $dget2) (call $wpsh2) (br $loop) ) (; STD*: ;) (call $mpop1) (call $wpop2) (call $dset2) (local.set $x) (if (local.get $x) (then (return (local.get $x)))) (br $loop) ) (; ADD*: ;) (call $mpop2) (call $wpop2) (i32.add) (call $wpsh2) (br $loop) ) (; SUB*: ;) (call $mpop2) (local.set $x) (call $wpop2) (local.get $x) (i32.sub) (call $wpsh2) (br $loop) ) (; INC*: ;) (call $mpop2) (i32.add (i32.const 1)) (call $wpsh2) (br $loop) ) (; DEC*: ;) (call $mpop2) (i32.sub (i32.const 1)) (call $wpsh2) (br $loop) ) (; LTH*: ;) (call $mpop2) (call $wpop2) (i32.gt_u) (call $wpshb) (br $loop) ) (; GTH*: ;) (call $mpop2) (call $wpop2) (i32.lt_u) (call $wpshb) (br $loop) ) (; EQU*: ;) (call $mpop2) (call $wpop2) (i32.eq) (call $wpshb) (br $loop) ) (; NQK*: ;) (call $mpop2) (local.tee $x) (call $wget2) (local.get $x) (call $wpsh2) (i32.ne) (call $wpshb) (br $loop) ) (; SHL*: ;) (call $mpop1) (local.set $x) (call $wpop2) (local.get $x) (i32.shl) (call $wpsh2) (br $loop) ) (; SHR*: ;) (call $mpop1) (local.set $x) (call $wpop2) (local.get $x) (i32.shr_u) (call $wpsh2) (br $loop) ) (; ROL*: ;) (call $mpop1) (local.set $x) (call $wpop2) (local.get $x) (call $rol2) (call $wpsh2) (br $loop) ) (; ROR*: ;) (call $mpop1) (local.set $x) (call $wpop2) (local.get $x) (call $ror2) (call $wpsh2) (br $loop) ) (; IOR*: ;) (call $mpop2) (call $wpop2) (i32.or) (call $wpsh2) (br $loop) ) (; XOR*: ;) (call $mpop2) (call $wpop2) (i32.xor) (call $wpsh2) (br $loop) ) (; AND*: ;) (call $mpop2) (call $wpop2) (i32.and) (call $wpsh2) (br $loop) ) (; NOT*: ;) (call $mpop2) (i32.xor (i32.const 0xFFFF)) (call $wpsh2) (br $loop) ) (; DB3 ;) (return (global.get $SIGNAL.DB3)) ) (; PSHr ;) (call $wpop1) (call $rpsh1) (br $loop) ) (; POPr ;) (call $rpmov (i32.const -1)) (br $loop) ) (; CPYr ;) (call $wget1) (call $rpsh1) (br $loop) ) (; DUPr ;) (call $rget1) (call $rpsh1) (br $loop) ) (; OVRr ;) (call $rpop1) (call $rget1) (local.set $x) (call $rpsh1) (local.get $x) (call $rpsh1) (br $loop) ) (; SWPr ;) (call $rpop1) (call $rpop1) (local.set $x) (call $rpsh1) (local.get $x) (call $rpsh1) (br $loop) ) (; ROTr ;) (call $rpop1) (call $rpop1) (call $rpop1) (local.set $x) (call $rpsh1) (call $rpsh1) (local.get $x) (call $rpsh1) (br $loop) ) (; JMPr ;) (call $rpop2) (global.set $ip) (br $loop) ) (; JMSr ;) (call $rpop2) (global.get $ip) (call $wpsh2) (global.set $ip) (br $loop) ) (; JCNr ;) (call $rpop2) (local.set $x) (if (call $rpop1) (then (local.get $x) (global.set $ip))) (br $loop) ) (; JCSr ;) (call $rpop2) (local.set $x) (if (call $rpop1) (then (global.get $ip) (call $wpsh2) (local.get $x) (global.set $ip))) (br $loop) ) (; LDAr ;) (call $rpop2) (call $mget1) (call $rpsh1) (br $loop) ) (; STAr ;) (call $rpop2) (call $rpop1) (call $mset1) (br $loop) ) (; LDDr ;) (call $rpop1) (call $dget1) (call $rpsh1) (br $loop) ) (; STDr ;) (call $rpop1) (call $rpop1) (call $dset1) (local.set $x) (if (local.get $x) (then (return (local.get $x)))) (br $loop) ) (; ADDr ;) (call $rpop1) (call $rpop1) (i32.add) (call $rpsh1) (br $loop) ) (; SUBr ;) (call $rpop1) (local.set $x) (call $rpop1) (local.get $x) (i32.sub) (call $rpsh1) (br $loop) ) (; INCr ;) (call $rpop1) (i32.add (i32.const 1)) (call $rpsh1) (br $loop) ) (; DECr ;) (call $rpop1) (i32.sub (i32.const 1)) (call $rpsh1) (br $loop) ) (; LTHr ;) (call $rpop1) (call $rpop1) (i32.gt_u) (call $rpshb) (br $loop) ) (; GTHr ;) (call $rpop1) (call $rpop1) (i32.lt_u) (call $rpshb) (br $loop) ) (; EQUr ;) (call $rpop1) (call $rpop1) (i32.eq) (call $rpshb) (br $loop) ) (; NQKr ;) (call $rpop1) (local.tee $x) (call $rget1) (local.get $x) (call $rpsh1) (i32.ne) (call $rpshb) (br $loop) ) (; SHLr ;) (call $rpop1) (local.set $x) (call $rpop1) (local.get $x) (i32.shl) (call $rpsh1) (br $loop) ) (; SHRr ;) (call $rpop1) (local.set $x) (call $rpop1) (local.get $x) (i32.shr_u) (call $rpsh1) (br $loop) ) (; ROLr ;) (call $rpop1) (local.set $x) (call $rpop1) (local.get $x) (call $rol1) (call $rpsh1) (br $loop) ) (; RORr ;) (call $rpop1) (local.set $x) (call $rpop1) (local.get $x) (call $ror1) (call $rpsh1) (br $loop) ) (; IORr ;) (call $rpop1) (call $rpop1) (i32.or) (call $rpsh1) (br $loop) ) (; XORr ;) (call $rpop1) (call $rpop1) (i32.xor) (call $rpsh1) (br $loop) ) (; ANDr ;) (call $rpop1) (call $rpop1) (i32.and) (call $rpsh1) (br $loop) ) (; NOTr ;) (call $rpop1) (i32.xor (i32.const 0xFF)) (call $rpsh1) (br $loop) ) (; DB4 ;) (return (global.get $SIGNAL.DB4)) ) (; PSHr: ;) (call $mpop1) (call $rpsh1) (br $loop) ) (; POPr: ;) (call $ipmov (i32.const 1)) (br $loop) ) (; CPYr: ;) (call $mpop1) (local.tee $x) (call $rpsh1) (local.get $x) (call $wpsh1) (br $loop) ) (; DUPr: ;) (call $mpop1) (local.tee $x) (call $rpsh1) (local.get $x) (call $rpsh1) (br $loop) ) (; OVRr: ;) (call $mpop1) (call $rget1) (local.set $x) (call $rpsh1) (local.get $x) (call $rpsh1) (br $loop) ) (; SWPr: ;) (call $mpop1) (call $rpop1) (local.set $x) (call $rpsh1) (local.get $x) (call $rpsh1) (br $loop) ) (; ROTr: ;) (call $mpop1) (call $rpop1) (call $rpop1) (local.set $x) (call $rpsh1) (call $rpsh1) (local.get $x) (call $rpsh1) (br $loop) ) (; JMPr: ;) (call $mpop2) (global.set $ip) (br $loop) ) (; JMSr: ;) (call $mpop2) (global.get $ip) (call $wpsh2) (global.set $ip) (br $loop) ) (; JCNr: ;) (call $mpop2) (local.set $x) (if (call $rpop1) (then (local.get $x) (global.set $ip))) (br $loop) ) (; JCSr: ;) (call $mpop2) (local.set $x) (if (call $rpop1) (then (global.get $ip) (call $wpsh2) (local.get $x) (global.set $ip))) (br $loop) ) (; LDAr: ;) (call $mpop2) (call $mget1) (call $rpsh1) (br $loop) ) (; STAr: ;) (call $mpop2) (call $rpop1) (call $mset1) (br $loop) ) (; LDDr: ;) (call $mpop1) (call $dget1) (call $rpsh1) (br $loop) ) (; STDr: ;) (call $mpop1) (call $rpop1) (call $dset1) (local.set $x) (if (local.get $x) (then (return (local.get $x)))) (br $loop) ) (; ADDr: ;) (call $mpop1) (call $rpop1) (i32.add) (call $rpsh1) (br $loop) ) (; SUBr: ;) (call $mpop1) (local.set $x) (call $rpop1) (local.get $x) (i32.sub) (call $rpsh1) (br $loop) ) (; INCr: ;) (call $mpop1) (i32.add (i32.const 1)) (call $rpsh1) (br $loop) ) (; DECr: ;) (call $mpop1) (i32.sub (i32.const 1)) (call $rpsh1) (br $loop) ) (; LTHr: ;) (call $mpop1) (call $rpop1) (i32.gt_u) (call $rpshb) (br $loop) ) (; GTHr: ;) (call $mpop1) (call $rpop1) (i32.lt_u) (call $rpshb) (br $loop) ) (; EQUr: ;) (call $mpop1) (call $rpop1) (i32.eq) (call $rpshb) (br $loop) ) (; NQKr: ;) (call $mpop1) (local.tee $x) (call $rget1) (local.get $x) (call $rpsh1) (i32.ne) (call $rpshb) (br $loop) ) (; SHLr: ;) (call $mpop1) (local.set $x) (call $rpop1) (local.get $x) (i32.shl) (call $rpsh1) (br $loop) ) (; SHRr: ;) (call $mpop1) (local.set $x) (call $rpop1) (local.get $x) (i32.shr_u) (call $rpsh1) (br $loop) ) (; ROLr: ;) (call $mpop1) (local.set $x) (call $rpop1) (local.get $x) (call $rol1) (call $rpsh1) (br $loop) ) (; RORr: ;) (call $mpop1) (local.set $x) (call $rpop1) (local.get $x) (call $ror1) (call $rpsh1) (br $loop) ) (; IORr: ;) (call $mpop1) (call $rpop1) (i32.or) (call $rpsh1) (br $loop) ) (; XORr: ;) (call $mpop1) (call $rpop1) (i32.xor) (call $rpsh1) (br $loop) ) (; ANDr: ;) (call $mpop1) (call $rpop1) (i32.and) (call $rpsh1) (br $loop) ) (; NOTr: ;) (call $mpop1) (i32.xor (i32.const 0xFF)) (call $rpsh1) (br $loop) ) (; DB5 ;) (return (global.get $SIGNAL.DB5)) ) (; PSHr* ;) (call $wpop2) (call $rpsh2) (br $loop) ) (; POPr* ;) (call $rpmov (i32.const -2)) (br $loop) ) (; CPYr* ;) (call $wget2) (call $rpsh2) (br $loop) ) (; DUPr* ;) (call $rget2) (call $rpsh2) (br $loop) ) (; OVRr* ;) (call $rpop2) (call $rget2) (local.set $x) (call $rpsh2) (local.get $x) (call $rpsh2) (br $loop) ) (; SWPr* ;) (call $rpop2) (call $rpop2) (local.set $x) (call $rpsh2) (local.get $x) (call $rpsh2) (br $loop) ) (; ROTr* ;) (call $rpop2) (call $rpop2) (call $rpop2) (local.set $x) (call $rpsh2) (call $rpsh2) (local.get $x) (call $rpsh2) (br $loop) ) (; JMPr* ;) (call $rpop2) (global.set $ip) (br $loop) ) (; JMSr* ;) (call $rpop2) (global.get $ip) (call $wpsh2) (global.set $ip) (br $loop) ) (; JCNr* ;) (call $rpop2) (local.set $x) (if (call $rpop2) (then (local.get $x) (global.set $ip))) (br $loop) ) (; JCSr* ;) (call $rpop2) (local.set $x) (if (call $rpop2) (then (global.get $ip) (call $wpsh2) (local.get $x) (global.set $ip))) (br $loop) ) (; LDAr* ;) (call $rpop2) (call $mget2) (call $rpsh2) (br $loop) ) (; STAr* ;) (call $rpop2) (call $rpop2) (call $mset2) (br $loop) ) (; LDDr* ;) (call $rpop1) (call $dget2) (call $rpsh2) (br $loop) ) (; STDr* ;) (call $rpop1) (call $rpop2) (call $dset2) (local.set $x) (if (local.get $x) (then (return (local.get $x)))) (br $loop) ) (; ADDr* ;) (call $rpop2) (call $rpop2) (i32.add) (call $rpsh2) (br $loop) ) (; SUBr* ;) (call $rpop2) (local.set $x) (call $rpop2) (local.get $x) (i32.sub) (call $rpsh2) (br $loop) ) (; INCr* ;) (call $rpop2) (i32.add (i32.const 1)) (call $rpsh2) (br $loop) ) (; DECr* ;) (call $rpop2) (i32.sub (i32.const 1)) (call $rpsh2) (br $loop) ) (; LTHr* ;) (call $rpop2) (call $rpop2) (i32.gt_u) (call $rpshb) (br $loop) ) (; GTHr* ;) (call $rpop2) (call $rpop2) (i32.lt_u) (call $rpshb) (br $loop) ) (; EQUr* ;) (call $rpop2) (call $rpop2) (i32.eq) (call $rpshb) (br $loop) ) (; NQKr* ;) (call $rpop2) (local.tee $x) (call $rget2) (local.get $x) (call $rpsh2) (i32.ne) (call $rpshb) (br $loop) ) (; SHLr* ;) (call $rpop1) (local.set $x) (call $rpop2) (local.get $x) (i32.shl) (call $rpsh2) (br $loop) ) (; SHRr* ;) (call $rpop1) (local.set $x) (call $rpop2) (local.get $x) (i32.shr_u) (call $rpsh2) (br $loop) ) (; ROLr* ;) (call $rpop1) (local.set $x) (call $rpop2) (local.get $x) (call $rol2) (call $rpsh2) (br $loop) ) (; RORr* ;) (call $rpop1) (local.set $x) (call $rpop2) (local.get $x) (call $ror2) (call $rpsh2) (br $loop) ) (; IORr* ;) (call $rpop2) (call $rpop2) (i32.or) (call $rpsh2) (br $loop) ) (; XORr* ;) (call $rpop2) (call $rpop2) (i32.xor) (call $rpsh2) (br $loop) ) (; ANDr* ;) (call $rpop2) (call $rpop2) (i32.and) (call $rpsh2) (br $loop) ) (; NOTr* ;) (call $rpop2) (i32.xor (i32.const 0xFFFF)) (call $rpsh2) (br $loop) ) (; DB6 ;) (return (global.get $SIGNAL.DB6)) ) (; PSHr*: ;) (call $mpop2) (call $rpsh2) (br $loop) ) (; POPr*: ;) (call $ipmov (i32.const 2)) (br $loop) ) (; CPYr*: ;) (call $mpop2) (local.tee $x) (call $rpsh2) (local.get $x) (call $wpsh2) (br $loop) ) (; DUPr*: ;) (call $mpop2) (local.tee $x) (call $rpsh2) (local.get $x) (call $rpsh2) (br $loop) ) (; OVRr*: ;) (call $mpop2) (call $rget2) (local.set $x) (call $rpsh2) (local.get $x) (call $rpsh2) (br $loop) ) (; SWPr*: ;) (call $mpop2) (call $rpop2) (local.set $x) (call $rpsh2) (local.get $x) (call $rpsh2) (br $loop) ) (; ROTr*: ;) (call $mpop2) (call $rpop2) (call $rpop2) (local.set $x) (call $rpsh2) (call $rpsh2) (local.get $x) (call $rpsh2) (br $loop) ) (; JMPr*: ;) (call $mpop2) (global.set $ip) (br $loop) ) (; JMSr*: ;) (call $mpop2) (global.get $ip) (call $wpsh2) (global.set $ip) (br $loop) ) (; JCNr*: ;) (call $mpop2) (local.set $x) (if (call $rpop2) (then (local.get $x) (global.set $ip))) (br $loop) ) (; JCSr*: ;) (call $mpop2) (local.set $x) (if (call $rpop2) (then (global.get $ip) (call $wpsh2) (local.get $x) (global.set $ip))) (br $loop) ) (; LDAr*: ;) (call $mpop2) (call $mget2) (call $rpsh2) (br $loop) ) (; STAr*: ;) (call $mpop2) (call $rpop2) (call $mset2) (br $loop) ) (; LDDr*: ;) (call $mpop1) (call $dget2) (call $rpsh2) (br $loop) ) (; STDr*: ;) (call $mpop1) (call $rpop2) (call $dset2) (local.set $x) (if (local.get $x) (then (return (local.get $x)))) (br $loop) ) (; ADDr*: ;) (call $mpop2) (call $rpop2) (i32.add) (call $rpsh2) (br $loop) ) (; SUBr*: ;) (call $mpop2) (local.set $x) (call $rpop2) (local.get $x) (i32.sub) (call $rpsh2) (br $loop) ) (; INCr*: ;) (call $mpop2) (i32.add (i32.const 1)) (call $rpsh2) (br $loop) ) (; DECr*: ;) (call $mpop2) (i32.sub (i32.const 1)) (call $rpsh2) (br $loop) ) (; LTHr*: ;) (call $mpop2) (call $rpop2) (i32.gt_u) (call $rpshb) (br $loop) ) (; GTHr*: ;) (call $mpop2) (call $rpop2) (i32.lt_u) (call $rpshb) (br $loop) ) (; EQUr*: ;) (call $mpop2) (call $rpop2) (i32.eq) (call $rpshb) (br $loop) ) (; NQKr*: ;) (call $mpop2) (local.tee $x) (call $rget2) (local.get $x) (call $rpsh2) (i32.ne) (call $rpshb) (br $loop) ) (; SHLr*: ;) (call $mpop1) (local.set $x) (call $rpop2) (local.get $x) (i32.shl) (call $rpsh2) (br $loop) ) (; SHRr*: ;) (call $mpop1) (local.set $x) (call $rpop2) (local.get $x) (i32.shr_u) (call $rpsh2) (br $loop) ) (; ROLr*: ;) (call $mpop1) (local.set $x) (call $rpop2) (local.get $x) (call $rol2) (call $rpsh2) (br $loop) ) (; RORr*: ;) (call $mpop1) (local.set $x) (call $rpop2) (local.get $x) (call $ror2) (call $rpsh2) (br $loop) ) (; IORr*: ;) (call $mpop2) (call $rpop2) (i32.or) (call $rpsh2) (br $loop) ) (; XORr*: ;) (call $mpop2) (call $rpop2) (i32.xor) (call $rpsh2) (br $loop) ) (; ANDr*: ;) (call $mpop2) (call $rpop2) (i32.and) (call $rpsh2) (br $loop) ) (; NOTr*: ;) (call $mpop2) (i32.xor (i32.const 0xFFFF)) (call $rpsh2) (br $loop) ) ) (; break ;) ;; Default return signal. (return (global.get $SIGNAL.BREAK)) ) )