CON int_org = $147 ' ' '*************** '* Interpreter * '*************** ' DAT orgh $E80 org _vbase long 0 'vbase (nop) - modified by compiler _pbase long 0 'pbase (nop) - modified by compiler _pcurr long 0 'pcurr (nop) - modified by compiler _dlocs long 0 'dcurr (nop) - modified by compiler reps #int_res-int_org,#1 'move interpreter into position setinds #int_res-1,#int_obj+int_res-int_org-1 mov indb--,inda-- reps #$200-int_res,#1 'clear high regs (leaves indb at $000) setindb #int_res mov indb++,#0 reps #$100,#1 'clear stack endaddr long @endcode '(nop) pushbr #0 pushbr endaddr 'push return pcurr, points to 'cogstop(cogid)' subspb #3 'push 3 locations (0's) getspb dbase 'set dbase subspb _dlocs 'set dcurr mov vbase,_vbase 'set vbase mov pbase,_pbase 'set pbase setptrb _pcurr 'set pcurr jmp #a 'clear low regs, start interpreter endcode byte (@op_get - @descriptors) >> 2, $01 'cogid byte (@op_set1 - @descriptors) >> 2, $03 'cogstop ' ' ' Interpreter start ' int_obj org int_org ' ' ' Constants/variables ' descriptor_base long @descriptors h003C0000 long $003C0000 'conditional field bits hFFFFFFFF long $FFFFFFFF 'all bits callwrites call #writes callwriter call #writer a reps #int_org,#1 'initially executes, becomes 'a' h0001FFF0 long $0001FFF0 'vbase/pbase mask (nop) b mov indb++,#0 'initially executes, becomes 'b' jmpback jmp #getbyte ' ' ' Pre-move pops and check ' premove popbr a popbr y popbr x tjz a,#getbyte sub a,#1 premove_ret ret ' ' ' Get sign-extended byte (c=0), used to make -$80..+$7F offset ' Get and append word to x (c=1), used to make $0xxxx or $1xxxx offset ' xword rdbytec y,ptrb++ shl x,#8 or x,y if_c rdbytec y,ptrb++ if_c shl x,#8 if_c or x,y if_nc shl x,#24 if_nc sar x,#24 xword_ret ret ' ' ' call obj.sub ' call obj.sub[] ' call obj[].sub ' call obj[].sub[] ' call sub ' call sub[] ' call ptr ' call_obj shl x,#2 'lookup obj vbase/pbase offsets add x,pbase rdlong x,x call_ptr rol x,#4 'set relative pbase add pbase,x and pbase,h0001FFF0 ror x,#16 'set relative vbase add vbase,x and vbase,h0001FFF0 call_sub shl y,#2 'lookup locals/pbase offsets add y,pbase rdlong y,y mov dbase,dcall 'set call dbase sub dbase,#3 setspb dcall 'get old dcall popbr dcall getptrb x 'set return pcurr pushbr x setptrb pbase 'set call pcurr addptrb y shr y,#32-4 'sub locals from dcurr subspb y jmp #getbyte 'loop to getbyte ' ' ' Bitfield addressing, pop and set bitfield parameters ' bitfield popbr bshift 'pop range lsb popbr bmask 'pop range msb and bshift,#$1F 'trim lsb/msb and bmask,#$1F cmp bmask,bshift wc 'reverse range? if_c xor bshift,bmask 'if reverse range, swap msb/lsb if_c xor bmask,bshift if_c xor bshift,bmask sub bmask,bshift 'get number of bits add bmask,#1 neg brev,bmask 'get rev count setbc brev,#5 'save reverse flag blmask bmask 'get bitlength mask shl bmask,bshift 'bmask = mask, brev = reverse, bshift = lsb offset bitfield_ret ret 'return ' ' ' Write register (addr = address, x = value) ' ' if OUTA..OUTD then update PINA..PIND ' if DRVA..DRVD then update DIRA..DIRD ' writer movd :mov,addr and addr,#$1FF 'check for OUTA..OUTD/DRVA..DRVD cmp addr,#$1E8 wc if_nc cmpr addr,#$1EF wc :mov if_c mov $000,x 'normal register if_c jmp writer_ret movs :xors,addr 'set OUTA..OUTD/DRVA..DRVD addresses movd :xord,addr movd :xor,addr setb :xor,#9+4 :xors xor x,$1E8 'update OUTx/DRVx shadow register :xord xor $1E8,x :xor xor $1F8,x 'update PINx/DIRX atomically writer_ret ret ' ' ' Write stack/local (addr = address, x = value) ' writes getspb y setspb addr pushb x setspb y writes_ret ret ' ' ' Do bitfield read (x = value) ' readb and x,bmask shr x,bshift if_c rev x,brev pushbr x jmp #getbyte ' ' ' Do bitfield write (bval = value, writeb_i = write instruction) ' writeb popbr x 'pop value to write if_c rev x,brev 'reverse bits? shl x,bshift 'shift into position and x,bmask 'mask bits andn bval,bmask 'mask away original bits or x,bval 'merge bits writeb_i call #writer 'call #writer / call #writes / wrxxxx x,addr writeb_ret jmp #getbyte ' ' ' Do bitfield assignment (bval = value, assignb_i = write instruction, mask = sized mask) ' assignb_long mov mask,hFFFFFFFF 'set long mask assignb movs jmpback,#assignb_ret 'set jmpback address to assignb_ret mov x,bval 'save original value and x,bmask 'extract bitfield for operation shr x,bshift if_c rev x,brev jmp #assign_op 'get math operator and execute assignb_ret testb brev,#5 wc 'snippet returns to here, get reverse flag into c call #writeb 'write bitfield movs writeb_ret,#getbyte 'restore jump to getbyte and x,mask 'mask it and x,bmask 'extract bitfield for pushing shr x,bshift if_c rev x,brev jmp #assign_p 'push it (optional) ' ' ' Do assignment (x = value, assign_i = write instruction, mask = sized mask) ' assign_long mov mask,hFFFFFFFF 'set long mask assign movs jmpback,#assign_ret 'set jmpback address to :ret assign_op rdbytec a,ptrb++ 'get math operator and flags setzc a wz,wc 'load flags, operator already in position muxz assign_p,h003C0000 'set push condition to z if_c popbr y 'swap args? pushbr x if_c pushbr y jmp #hotbyte 'load and execute math snippet assign_ret popbr x 'snippet returns to here, pop value assign_i call #writer 'call #writer / call #writes / wrxxxx x,addr and x,mask 'mask it assign_p pushbr x 'push it (optional) movs jmpback,#getbyte 'replace jmpback address, getbyte next ' ' ' Get byte code, look up descriptor long, load code longs in-line, execute, repeat ' getbyte rdbytec a,ptrb++ ' get byte code shl a,#2 ' shift to make long offset hotbyte add a,descriptor_base ' add base address of descriptor longs getptrb y ' save ptrb rdlong x,a '..2 get descriptor long movd :reps,x '3 descriptor[8..0] holds code longs minus 1 shr x,#7 '4 descriptor[23..7] is code offset setptrb x '5 point PTRB to code longs :reps reps #1,#1 '6 ready for fast in-line code load setindb #snippet '7 point INDB to in-line code rdlongc indb++,ptrb++ '0.. load code longs in-line using cached read setptrb y ' restore ptrb mov indb++,jmpback ' finish in-line code with 'jmp #getbyte' shr x,#25-7 wz,wc ' descriptor[31..25] is a value, [24] is C ' ' ' Reserved registers ' int_res snippet res 18 ' executable in-line code snippet, loops x res 1 y res 1 dcall res 1 dbase res 1 vbase res 1 pbase res 1 _outa res 1 '@$1E8 OUTA..OUTD _outb res 1 '@$1E9 (writes update PINA..PIND at $1F8..$1FB) _outc res 1 '@$1EA _outd res 1 '@$1EB _drva res 1 '@$1EC DRVA..DRVD _drvb res 1 '@$1ED (writes update DIRA..DIRD at $1FC..$1FD) _drvc res 1 '@$1EE _drvd res 1 '@$1EF bshift res 1 '@$1F0 bitfield addressing bmask res 1 '@$1F1 brev res 1 '@$1F2 bval res 1 '@$1F3 addr res 1 '@$1F4 assignment addressing mask res 1 '@$1F5 ' ' '************************ '* Bytecode Descriptors * '************************ ' descriptors ' variable modifiers (14) op_writep long %0000000_0 << 24 + @_clr << 7 + 0 'write w/push %10 push op_rep long %0000000_0 << 24 + @_rep << 7 + 12 'repeat var %00 no op_clr long %0000000_0 << 24 + @_clr << 7 + 1 'clear %00 no op_clrpost long %0000000_0 << 24 + @_clrpost << 7 + 0 'clear post %00 push op_set long %0000000_0 << 24 + @_set << 7 + 1 'set %00 no op_setpost long %0000000_0 << 24 + @_setpost << 7 + 0 'set post %00 push op_incpre long %0000000_0 << 24 + @_incdec << 7 + 3 'inc pre / inc %10 push / %00 no op_incpost long %0000001_0 << 24 + @_incdec << 7 + 3 'inc post %00 push op_decpre long %0000000_1 << 24 + @_incdec << 7 + 3 'dec pre / dec %10 push / %00 no op_decpost long %0000001_1 << 24 + @_incdec << 7 + 3 'dec post %00 push op_incmod long %0000000_0 << 24 + @_idmod << 7 + 6 'incmod %00 no op_incmodp long %0000001_0 << 24 + @_idmod << 7 + 6 'incmod w/push %00 push op_decmod long %0000000_1 << 24 + @_idmod << 7 + 6 'decmod %00 no op_decmodp long %0000001_1 << 24 + @_idmod << 7 + 6 'decmod w/push %00 push ' unaries (27) op_notb long %0000000_0 << 24 + @_notb << 7 + 2 'NOT %x0 op_not long %0100101_0 << 24 + @_una << 7 + 4 '! %x0 op_neg long %0000000_0 << 24 + @_neg << 7 + 2 '- %x0 op_abs long %0000000_0 << 24 + @_abs << 7 + 2 '|| %x0 op_enc long %0000000_0 << 24 + @_enc << 7 + 2 '>| %x0 op_decod2 long %0100000_0 << 24 + @_una << 7 + 4 'DECOD2(x) %x0 op_decod3 long %0100001_0 << 24 + @_una << 7 + 4 'DECOD3(x) %x0 op_decod4 long %0100010_0 << 24 + @_una << 7 + 4 'DECOD4(x) %x0 op_decod5 long %0100011_0 << 24 + @_una << 7 + 4 'DECOD5(x), |< %x0 op_blmask long %0100100_0 << 24 + @_una << 7 + 4 'BLMASK(x) %x0 op_onecnt long %0100110_0 << 24 + @_una << 7 + 4 'ONECNT(x) %x0 op_zercnt long %0100111_0 << 24 + @_una << 7 + 4 'ZERCNT(x) %x0 op_incpat long %0101000_0 << 24 + @_una << 7 + 4 'INCPAT(x) %x0 op_decpat long %0101001_0 << 24 + @_una << 7 + 4 'DECPAT(x) %x0 op_bingry long %0101010_0 << 24 + @_una << 7 + 4 'BINGRY(x) %x0 op_grybin long %0101011_0 << 24 + @_una << 7 + 4 'GRYBIN(x) %x0 op_mergew long %0101100_0 << 24 + @_una << 7 + 4 'MERGEW(x) %x0 op_splitw long %0101101_0 << 24 + @_una << 7 + 4 'SPLITW(x) %x0 op_seussf long %0101110_0 << 24 + @_una << 7 + 4 'SEUSSF(x) %x0 op_seussr long %0101111_0 << 24 + @_una << 7 + 4 'SEUSSR(x) %x0 op_sqrt long %0000000_0 << 24 + @_sqrt << 7 + 4 'SQRT(x) %x0 op_qlog long %0000000_0 << 24 + @_qlogexp << 7 + 5 'QLOG(x) %x0 op_qexp long %0000000_1 << 24 + @_qlogexp << 7 + 5 'QEXP(x) %x0 op_rndf long %0000000_0 << 24 + @_rnd << 7 + 8 'RNDF(x) %x0 op_rndr long %0000000_1 << 24 + @_rnd << 7 + 8 'RNDR(x) %x0 op_subcnt long %0001100_0 << 24 + @_una << 7 + 4 'SUBCNT(x) %x0 op_getpix long %0000000_0 << 24 + @_getpix << 7 + 4 'GETPIX(x) %x0 ' binaries (23) op_andb long %0000000_0 << 24 + @_andorb << 7 + 4 'AND %x1 op_orb long %0000000_1 << 24 + @_andorb << 7 + 4 'OR %x1 op_xorb long %0000000_0 << 24 + @_xorb << 7 + 5 'XOR %x1 op_andn long %0011001_0 << 24 + @_bin << 7 + 5 '&! %x1 op_and long %0011000_0 << 24 + @_bin << 7 + 5 '& %x1 op_or long %0011010_0 << 24 + @_bin << 7 + 5 '| %x1 op_xor long %0011011_0 << 24 + @_bin << 7 + 5 '^ %x1 op_ror long %0001000_0 << 24 + @_bin << 7 + 5 '-> %x1 op_rol long %0001001_0 << 24 + @_bin << 7 + 5 '<- %x1 op_shr long %0001010_0 << 24 + @_bin << 7 + 5 '>> %x1 op_shl long %0001011_0 << 24 + @_bin << 7 + 5 '<< %x1 op_sar long %0001110_0 << 24 + @_bin << 7 + 5 '~> %x1 op_sal long %0000000_0 << 24 + @_sal << 7 + 5 '<~ %x1 op_rev long %0000000_0 << 24 + @_rev << 7 + 4 '>< %x1 op_min long %0010000_0 << 24 + @_bin << 7 + 5 '#> %x1 op_max long %0010001_0 << 24 + @_bin << 7 + 5 '<# %x1 op_add long %0100000_0 << 24 + @_bin << 7 + 5 '+ %x1 op_sub long %0100001_0 << 24 + @_bin << 7 + 5 '- %x1 op_mul long %0000000_0 << 24 + @_mul << 7 + 6 '* %x1 op_scl long %0000000_0 << 24 + @_scl << 7 + 6 '** %x1 op_div long %0000000_0 << 24 + @_divx << 7 + 7 '/ %x1 op_rem long %0000001_0 << 24 + @_divx << 7 + 7 '// %x1 op_fra long %0000000_0 << 24 + @_fra << 7 + 7 '*/ %x1 ' equality tests (6) op_b long %0000000_0 << 24 + @_m << 7 + 6 '< op_a long %0000000_1 << 24 + @_m << 7 + 6 '> op_ne long %0000000_0 << 24 + @_e << 7 + 4 '<> op_eq long %0000000_1 << 24 + @_e << 7 + 4 '== op_be long %0000001_1 << 24 + @_m << 7 + 6 '=< / <= op_ae long %0000001_0 << 24 + @_m << 7 + 6 '=> / >= ' math terms (8) op_quo64 long %0000000_0 << 24 + @_divh64 << 7 + 10 'QUO64(al,ah,b) op_quo64u long %0000000_1 << 24 + @_divh64 << 7 + 10 'QUO64U(al,ah,b) op_rem64 long %0000001_0 << 24 + @_divh64 << 7 + 10 'REM64(al,ah,b) op_rem64u long %0000001_1 << 24 + @_divh64 << 7 + 10 'REM64U(al,ah,b) op_sqrt64 long %0000000_0 << 24 + @_sqrt64 << 7 + 6 'SQRT64(l,h) op_negb long %0000000_0 << 24 + @_negb << 7 + 3 'NEGB(x,bool) op_muxb long %0000000_0 << 24 + @_muxb << 7 + 4 'MUXB(x,y,bool) op_ternary long %0000000_0 << 24 + @_ternary << 7 + 4 'select ? true : false ' math procedures (9) op_mul64 long %0000000_0 << 24 + @_mul64 << 7 + 9 'MUL64(a,b : l,h) op_mul64u long %0000000_1 << 24 + @_mul64 << 7 + 9 'MUL64U(a,b : l,h) op_div64 long %0000000_0 << 24 + @_div64 << 7 + 11 'DIV64(al,ah,b : q,r) op_div64u long %0000000_1 << 24 + @_div64 << 7 + 11 'DIV64U(al,ah,b : q,r) op_qsincos long %0000000_0 << 24 + @_qtrig << 7 + 12 'QSINCOS(r,t : x,y) op_qarctan long %0000001_0 << 24 + @_qtrig << 7 + 12 'QARCTAN(x,y : r,t) op_qrotate long %0000000_1 << 24 + @_qtrig << 7 + 12 'QROTATE(x,y,t : x,y) op_getacca long %0000000_0 << 24 + @_getacca << 7 + 3 'GETACCA(l,h) op_getaccb long %0000000_0 << 24 + @_getaccb << 7 + 3 'GETACCB(l,h) ' constants (9) op_con1n long %0000000_1 << 24 + @_conxn << 7 + 1 'constant -1 op_con0 long %0000000_0 << 24 + @_conxp << 7 + 0 'constant 0 op_con1 long %0000001_0 << 24 + @_conxp << 7 + 0 'constant 1 op_con8p long %0000000_0 << 24 + @_con8 << 7 + 2 'constant $000000xx +1 byte op_con8n long %0000000_1 << 24 + @_con8 << 7 + 2 'constant $FFFFFFxx +1 op_conexp long %0000000_0 << 24 + @_conexp << 7 + 4 'constant 2^n,dec,not +1 op_con16p long %0000000_0 << 24 + @_con16 << 7 + 5 'constant $0000xxxx +2 op_con16n long %0000000_1 << 24 + @_con16 << 7 + 5 'constant $FFFFxxxx +2 op_con32 long %0000000_0 << 24 + @_con32 << 7 + 5 'constant $xxxxxxxx +4 ' inter-memory moves (19) op_reg2reg long %0000000_0 << 24 + @_reg2reg << 7 + 10 'REG_TO_REG(@reg,@reg,longs) op_reg2stk long %0000000_0 << 24 + @_reg2stk << 7 + 7 'REG_TO_STK(@reg,@stk,longs) op_reg2loc long %0000000_0 << 24 + @_reg2loc << 7 + 8 'REG_TO_LOC(@reg,@loc,longs) op_reg2mem long %0000000_0 << 24 + @_reg2mem << 7 + 7 'REG_TO_MEM(@reg,@mem,longs) op_stk2reg long %0000000_0 << 24 + @_stk2reg << 7 + 7 'STK_TO_REG(@stk,@reg,longs) op_stk2stk long %0000000_0 << 24 + @_stk2stk << 7 + 14 'STK_TO_STK(@stk,@stk,longs) op_stk2loc long %0000000_0 << 24 + @_stk2loc << 7 + 11 'STK_TO_LOC(@stk,@loc,longs) op_stk2mem long %0000000_0 << 24 + @_stk2mem << 7 + 8 'STK_TO_MEM(@stk,@mem,longs) op_loc2reg long %0000000_0 << 24 + @_loc2reg << 7 + 8 'LOC_TO_REG(@loc,@reg,longs) op_loc2stk long %0000000_0 << 24 + @_loc2stk << 7 + 11 'LOC_TO_STK(@loc,@stk,longs) op_loc2loc long %0000000_0 << 24 + @_loc2loc << 7 + 16 'LOC_TO_LOC(@loc,@loc,longs) op_loc2mem long %0000000_0 << 24 + @_loc2mem << 7 + 8 'LOC_TO_MEM(@loc,@mem,longs) op_mem2reg long %0000000_0 << 24 + @_mem2reg << 7 + 7 'MEM_TO_REG(@mem,@reg,longs) op_mem2stk long %0000000_0 << 24 + @_mem2stk << 7 + 9 'MEM_TO_STK(@mem,@stk,longs) op_mem2loc long %0000000_0 << 24 + @_mem2loc << 7 + 10 'MEM_TO_LOC(@mem,@loc,longs) op_mem2mem long %0000010_0 << 24 + @_xmove << 7 + 15 'MEM_TO_MEM(@mem,@mem,longs), LONGMOVE(from,to,count) op_bytemove long %0000000_0 << 24 + @_xmove << 7 + 15 'BYTEMOVE(from,to,count) op_wordmove long %0000001_0 << 24 + @_xmove << 7 + 15 'WORDMOVE(from,to,count) op_quadmove long %0000100_1 << 24 + @_qmove << 7 + 9 'QUADMOVE(from,to,count) ' register reads/writes/assigns (6) op_rdreg long %0000000_0 << 24 + @_rdreg << 7 + 4 'read register op_wrreg long %0000000_0 << 24 + @_wrreg << 7 + 2 'write register op_asreg long %0000000_0 << 24 + @_asreg << 7 + 5 'assign register op_rdregb long %0000000_0 << 24 + @_rdregb << 7 + 6 'read register bitfield op_wrregb long %0000000_0 << 24 + @_wrregb << 7 + 6 'write register bitfield op_asregb long %0000001_0 << 24 + @_wrregb << 7 + 7 'assign register bitfield ' stack reads/writes/assigns (6) op_rdstk long %0000000_0 << 24 + @_rdstk << 7 + 5 'read stack op_wrstk long %0000000_0 << 24 + @_wrstk << 7 + 5 'write stack op_asstk long %0000000_0 << 24 + @_asstk << 7 + 8 'assign stack op_rdstkb long %0000000_0 << 24 + @_rdstkb << 7 + 6 'read stack bitfield op_wrstkb long %0000000_0 << 24 + @_wrstkb << 7 + 9 'write stack bitfield op_asstkb long %0000001_0 << 24 + @_wrstkb << 7 + 10 'assign stack bitfield ' local reads/writes/assigns (30) op_rdloc0 long %0000000_0 << 24 + @_rdlocx << 7 + 5 'read local 0 op_rdloc1 long %0000001_0 << 24 + @_rdlocx << 7 + 5 'read local 1 op_rdloc2 long %0000010_0 << 24 + @_rdlocx << 7 + 5 'read local 2 op_rdloc3 long %0000011_0 << 24 + @_rdlocx << 7 + 5 'read local 3 op_rdloc4 long %0000100_0 << 24 + @_rdlocx << 7 + 5 'read local 4 op_rdloc5 long %0000101_0 << 24 + @_rdlocx << 7 + 5 'read local 5 op_rdloc6 long %0000110_0 << 24 + @_rdlocx << 7 + 5 'read local 6 op_wrloc0 long %0000000_0 << 24 + @_wrlocx << 7 + 5 'write local 0 op_wrloc1 long %0000001_0 << 24 + @_wrlocx << 7 + 5 'write local 1 op_wrloc2 long %0000010_0 << 24 + @_wrlocx << 7 + 5 'write local 2 op_wrloc3 long %0000011_0 << 24 + @_wrlocx << 7 + 5 'write local 3 op_wrloc4 long %0000100_0 << 24 + @_wrlocx << 7 + 5 'write local 4 op_wrloc5 long %0000101_0 << 24 + @_wrlocx << 7 + 5 'write local 5 op_wrloc6 long %0000110_0 << 24 + @_wrlocx << 7 + 5 'write local 6 op_asloc0 long %0000000_0 << 24 + @_aslocx << 7 + 7 'assign local 0 op_asloc1 long %0000001_0 << 24 + @_aslocx << 7 + 7 'assign local 1 op_asloc2 long %0000010_0 << 24 + @_aslocx << 7 + 7 'assign local 2 op_asloc3 long %0000011_0 << 24 + @_aslocx << 7 + 7 'assign local 3 op_asloc4 long %0000100_0 << 24 + @_aslocx << 7 + 7 'assign local 4 op_asloc5 long %0000101_0 << 24 + @_aslocx << 7 + 7 'assign local 5 op_asloc6 long %0000110_0 << 24 + @_aslocx << 7 + 7 'assign local 6 op_rdloc long %0000000_0 << 24 + @_rdloc << 7 + 7 'read local op_wrloc long %0000000_0 << 24 + @_wrloc << 7 + 7 'write local op_asloc long %0000000_0 << 24 + @_asloc << 7 + 9 'assign local op_rdloci long %0000000_1 << 24 + @_rdloci << 7 + 8 'read local indexed op_wrloci long %0000000_1 << 24 + @_wrloci << 7 + 8 'write local indexed op_asloci long %0000000_1 << 24 + @_asloci << 7 + 10 'assign local indexed op_rdlocb long %0000000_0 << 24 + @_rdlocb << 7 + 7 'read local bitfield op_wrlocb long %0000000_0 << 24 + @_wrlocb << 7 + 9 'write local bitfield op_aslocb long %0000001_0 << 24 + @_wrlocb << 7 + 10 'assign local bitfield ' memory reads/writes/assigns (18) op_rdbyte long %0000000_0 << 24 + @_rdbyte << 7 + 2 'read byte op_rdword long %0000000_0 << 24 + @_rdword << 7 + 2 'read word op_rdlong long %0000000_0 << 24 + @_rdlong << 7 + 2 'read long op_wrbyte long %0000000_0 << 24 + @_wrbyte << 7 + 2 'write byte op_wrword long %0000000_0 << 24 + @_wrword << 7 + 2 'write word op_wrlong long %0000000_0 << 24 + @_wrlong << 7 + 2 'write long op_asbyte long %0000000_0 << 24 + @_asbyte << 7 + 5 'assign byte op_asword long %0000000_0 << 24 + @_asword << 7 + 6 'assign word op_aslong long %0000000_0 << 24 + @_aslong << 7 + 4 'assign long op_rdbyteb long %0000000_0 << 24 + @_rdbyteb << 7 + 3 'read byte bitfield op_rdwordb long %0000000_0 << 24 + @_rdwordb << 7 + 3 'read word bitfield op_rdlongb long %0000000_0 << 24 + @_rdlongb << 7 + 3 'read long bitfield op_wrbyteb long %0000000_0 << 24 + @_wrbyteb << 7 + 7 'write byte bitfield op_wrwordb long %0000000_0 << 24 + @_wrwordb << 7 + 8 'write word bitfield op_wrlongb long %0000000_0 << 24 + @_wrlongb << 7 + 6 'write long bitfield op_asbyteb long %0000001_0 << 24 + @_wrbyteb << 7 + 7 'assign byte bitfield op_aswordb long %0000001_0 << 24 + @_wrwordb << 7 + 8 'assign word bitfield op_aslongb long %0000001_0 << 24 + @_wrlongb << 7 + 6 'assign long bitfield ' memory offsets and indexing (9) op_vbase long %0000000_0 << 24 + @_vbaseo << 7 + 2 'vbase -$80..+$7F op_vbase0 long %0000000_1 << 24 + @_vbaseo << 7 + 2 'vbase $0xxxx op_vbase1 long %0000001_1 << 24 + @_vbaseo << 7 + 2 'vbase $1xxxx op_pbase long %0000000_0 << 24 + @_pbaseo << 7 + 2 'pbase -$80..+$7F op_pbase0 long %0000000_1 << 24 + @_pbaseo << 7 + 2 'pbase $0xxxx op_pbase1 long %0000001_1 << 24 + @_pbaseo << 7 + 2 'pbase $1xxxx op_ibyte long %0000000_0 << 24 + @_index << 7 + 4 'byte index op_iword long %0000001_0 << 24 + @_index << 7 + 4 'word index op_ilong long %0000010_0 << 24 + @_index << 7 + 4 'long index ' branches jmp/jz/jnz/tjz/djnz (15) op_jmp long %0000000_0 << 24 + @_jmp << 7 + 1 'jmp -$80..+$7F op_jmp0 long %0000000_1 << 24 + @_jmp << 7 + 1 'jmp +$0xxxx op_jmp1 long %0000001_1 << 24 + @_jmp << 7 + 1 'jmp +$1xxxx op_jz long %0000000_0 << 24 + @_jz << 7 + 2 'jz -$80..+$7F op_jz0 long %0000000_1 << 24 + @_jz << 7 + 2 'jz +$0xxxx op_jz1 long %0000001_1 << 24 + @_jz << 7 + 2 'jz +$1xxxx op_jnz long %0000000_0 << 24 + @_jnz << 7 + 2 'jnz -$80..+$7F op_jnz0 long %0000000_1 << 24 + @_jnz << 7 + 2 'jnz +$0xxxx op_jnz1 long %0000001_1 << 24 + @_jnz << 7 + 2 'jnz +$1xxxx op_tjz long %0000000_0 << 24 + @_tjz << 7 + 3 'tjz -$80..+$7F op_tjz0 long %0000000_1 << 24 + @_tjz << 7 + 3 'tjz +$0xxxx op_tjz1 long %0000001_1 << 24 + @_tjz << 7 + 3 'tjz +$1xxxx op_djnz long %0000000_0 << 24 + @_djnz << 7 + 4 'djnz -$80..+$7F op_djnz0 long %0000000_1 << 24 + @_djnz << 7 + 4 'djnz +$0xxxx op_djnz1 long %0000001_1 << 24 + @_djnz << 7 + 4 'djnz +$1xxxx ' anchor drops (4) op_drop long %0000010_0 << 24 + @_drop << 7 + 6 'drop, sub op_dropp long %0000011_0 << 24 + @_drop << 7 + 6 'drop, sub w/push op_dropt long %0000000_0 << 24 + @_drop << 7 + 6 'drop, \sub op_droptp long %0000001_0 << 24 + @_drop << 7 + 6 'drop, \sub w/push ' calls (7) op_callos long %0000000_0 << 24 + @_callobj << 7 + 6 'call obj.sub op_callosi long %0000000_1 << 24 + @_callobj << 7 + 6 'call obj.sub[] op_callois long %0000001_0 << 24 + @_callobj << 7 + 6 'call obj[].sub op_calloisi long %0000001_1 << 24 + @_callobj << 7 + 6 'call obj[].sub[] op_calls long %0000000_0 << 24 + @_callsub << 7 + 3 'call sub op_callsi long %0000000_1 << 24 + @_callsub << 7 + 3 'call sub[] op_callp long %0000000_0 << 24 + @_callptr << 7 + 10 'call ptr ' returns (4) op_return long %0000000_0 << 24 + @_return << 7 + 13 'RETURN op_returnv long %0000001_0 << 24 + @_return << 7 + 13 'RETURN value op_abort long %0000000_1 << 24 + @_return << 7 + 13 'ABORT op_abortv long %0000001_1 << 24 + @_return << 7 + 13 'ABORT value ' call pointer generation (5) op_basesub long %0000000_0 << 24 + @_basesub << 7 + 5 'vbase/pbase of current op_baseobj long %0000000_0 << 24 + @_baseobj << 7 + 16 'vbase/pbase of obj op_baseobji long %0000000_1 << 24 + @_baseobj << 7 + 16 'vbase/pbase of obj[] op_subptr long %0000000_0 << 24 + @_subptr << 7 + 11 'base.sub op_subptri long %0000000_1 << 24 + @_subptr << 7 + 11 'base.sub[] ' case (7) op_casev long %0000000_0 << 24 + @_casev << 7 + 5 'case value, -$80..+$7F branch op_casev0 long %0000000_1 << 24 + @_casev << 7 + 5 'case value, +$0xxxx branch op_casev1 long %0000001_1 << 24 + @_casev << 7 + 5 'case value, +$1xxxx branch op_caser long %0000000_0 << 24 + @_caser << 7 + 10 'case range, -$80..+$7F branch op_caser0 long %0000000_1 << 24 + @_caser << 7 + 10 'case range, +$0xxxx branch op_caser1 long %0000001_1 << 24 + @_caser << 7 + 10 'case range, +$1xxxx branch op_casedone long %0000000_0 << 24 + @_casedone << 7 + 2 'case done ' lookup/lookdown (5) op_lookupv long %0000000_0 << 24 + @_lookupv << 7 + 9 'lookup value op_lookupr long %0000000_0 << 24 + @_lookupr << 7 + 14 'lookup range op_lookdnv long %0000000_0 << 24 + @_lookdnv << 7 + 9 'lookdown value op_lookdnr long %0000000_0 << 24 + @_lookdnr << 7 + 15 'lookdown range op_lookdone long %0000000_0 << 24 + @_lookdone << 7 + 1 'lookup/lookdown done ' miscellaneous (25) +231 op_acc long %0000000_0 << 24 + @_acc << 7 + 4 'acc (CLRACCA/CLRACCB/CLRACCS/FITACCA/FITACCB/FITACCS) op_ctr long %0000000_0 << 24 + @_gen << 7 + 4 'ctr (SYNCTRA/CAPCTRA/SYNCTRB/CAPCTRB) op_pol long %0000000_0 << 24 + @_gen << 7 + 6 'pol (POLVID/POLCTRA/POLCTRB) op_get long %0000000_0 << 24 + @_get << 7 + 5 'get (COGID/GETCNT/GETLFSR/GETPHSA/GETPHZA/GETCOSA/GETSINA/GETPHSB/GETPHZB/GETCOSB/GETSINB) op_set1 long %0000000_1 << 24 + @_gen << 7 + 4 'set1 (CLKSET/COGSTOP/LOCKRET/LOCKSET/LOCKCLR/PASSCNT/SNDSER/NOP/SETPIXx/SETF/SETTASK/CFGDACx/SETDACx/CFGDACS/SETDACS/SETPORx..) op_set1r long %0000000_1 << 24 + @_gen << 7 + 6 'set1p (LOCKSET/LOCKCLR/SNDSER w/push, CMPCNT) op_set2 long %0000000_0 << 24 + @_set2 << 7 + 6 'set2 (SETACCA/SETACCB/MACA/MACB/CFGPINS/WAITVID/WAITCNT/WAITPEQ/WAITPNE) op_set2r long %0000000_0 << 24 + @_set2r << 7 + 5 'set2r (MUL/MOVF/SCL/MIN/MAX/MOVS/MOVD/MOVI) op_coginit long %0000000_0 << 24 + @_coginit << 7 + 5 'COGINIT(cog,pgm,ptr) op_cognew long %0000000_1 << 24 + @_coginit << 7 + 5 'COGNEW(pgm,ptr) op_cognewp long %0000000_1 << 24 + @_coginit << 7 + 7 'COGNEW(pgm,ptr) w/push op_locknew long %0000000_0 << 24 + @_locknew << 7 + 2 'LOCKNEW op_rcvser long %0000000_0 << 24 + @_rcvser << 7 + 3 'RCVSER(var) op_rcvserp long %0000000_1 << 24 + @_rcvser << 7 + 3 'RCVSER(var) w/push op_getcnth long %0000000_0 << 24 + @_getcnth << 7 + 2 'GETCNTH op_jmptask long %0000000_0 << 24 + @_jmptask << 7 + 5 'JMPTASK(addr,mask) op_callb long %0000000_0 << 24 + @_callb << 7 + 3 'CALLB(addr) op_strsize long %0000000_0 << 24 + @_strsize << 7 + 6 'STRSIZE(@str) op_strcomp long %0000000_0 << 24 + @_strcomp << 7 + 10 'STRCOMP(@stra,@strb) op_bytefill long %0000000_0 << 24 + @_xfill << 7 + 15 'BYTEFILL(value,to,count) op_wordfill long %0000001_0 << 24 + @_xfill << 7 + 15 'WORDFILL(value,to,count) op_longfill long %0000010_0 << 24 + @_xfill << 7 + 15 'LONGFILL(value,to,count) op_quadfill long %0000100_1 << 24 + @_xfill << 7 + 15 'QUADFILL(value,to,count) op_pushcopy long %0000000_0 << 24 + @_pushcopy << 7 + 2 'push copy op_pop long %0000000_0 << 24 + @_pop << 7 + 1 'pop ' ' '************ '* Snippets * '************ ' ' ' ' Variable modifiers ' org snippet 'repeat-var loop (assign) _rep popbr :w 'pop var popbr y 'pop step popbr b 'pop terminal popbr a 'pop initial popbr :v 'pop branch offset cmps b,a wc 'get reverse range into c sumc :w,y 'update var with step rcl x,#1 wz 'get c into nz if_z cmps b,:w wc 'if forward range, check if var > terminal if_nz cmps :w,b wc 'if reverse range, check if var < terminal if_nc subptrb :v 'if var within range, branch if_nc addspb #4 '..unpop offset/initial/terminal/step pushbr :w 'push new var res 1 '(jmpback) :v res 1 :w res 1 org snippet 'var~, clear and post-clear (assign) _clr popbr x 'clear, pop var (single pop also used by op_writep) _clrpost pushbr #0 'post-clear, push 0 (leave var on stack) org snippet 'var~~, set and post-set (assign) _set popbr x 'set, pop var _setpost pushbr hFFFFFFFF 'post-set, push -1 (leave var on stack) org snippet '++var/--var/var++/var-- (assign) _incdec popbr x 'pop var if_nz pushbr x 'if nz, push original var sumc x,#1 'inc or dec var by c pushbr x 'push new var org snippet 'INCMOD/DECMOD(var,value) (assign) _idmod setbc :i,#26 'set INCMOD/DECMOD popbr x 'pop var popbr y 'pop value :i incmod x,y wc 'INCMOD/DECMOD if_nz_and_nc pushbr #0 'push false if nz and nc if_nz_and_c pushbr hFFFFFFFF 'push true if nz and c pushbr x 'push new var ' ' ' Unary functions ' org snippet _notb popbr x wz 'NOT, boolean muxz x,hFFFFFFFF pushbr x org snippet _una movs :inst,x '!, bitwise not..SUBCNT(x) popbr x nop :inst long %000011_001_1_1111<<18 + x<<9 pushbr x org snippet _neg popbr x '-, negate neg x,x pushbr x org snippet _abs popbr x '||, absolute abs x,x pushbr x org snippet _enc popbr x '>|, encode (0..32) enc x,x pushbr x org snippet _sqrt popbr x 'SQRT(x) setsqrl x getsqrt x wc if_nc jmp #$-1 pushbr x org snippet _qlogexp popbr x 'QLOG(x), c=0 if_nc qlog x 'QEXP(x), c=1 if_c qexp x getqz x wc if_nc jmp #$-1 pushbr x org snippet _rnd popbr x 'RNDF(x), c=0 mov y,#%10111 'RNDR(x), c=1 if_c ror y,#1 if_c setb :rot,#26 reps #32,#2 min x,#1 test x,y wc :rot rcr x,#1 'rcr/rcl pushbr x org snippet _getpix popbr x 'GETPIX(x) nop #2 nop #2 getpix x pushbr x ' ' ' Binary functions ' org snippet _andorb popbr x wz 'AND, boolean (c=0) if_z_ne_c popbr x 'OR, boolean (c=1) if_z_eq_c popbr x wz muxnz x,hFFFFFFFF pushbr x org snippet _xorb popbr y wz 'XOR, boolean muxnz y,hFFFFFFFF popbr x wz muxnz x,hFFFFFFFF xor x,y pushbr x org snippet _bin shl x,#26 '&! (bitwise andnot) .. - (sub) or :inst,x popbr y popbr x :inst long %000000_001_0_1111<<18 + x<<9 + y pushbr x org snippet _sal popbr y '<~, shift arithmetic left popbr x rev x,#0 sar x,y rev x,#0 pushbr x org snippet _rev popbr y '><, reverse bits popbr x neg y,y rev x,y pushbr x org snippet _mul popbr y '*, multiply and return lower long popbr x setmula x setmulb y getmull x wc if_nc jmp #$-1 pushbr x org snippet _scl popbr y '**, multiply return upper long, unsigned popbr x setmulu x setmulb y getmulh x wc if_nc jmp #$-1 pushbr x org snippet _divx popbr y '/, divide and return quotient, z=1 popbr x '//, divide and return remainder, z=0 setdiva x setdivb y getdivq x wc if_nc jmp #$-1 if_nz getdivr x pushbr x org snippet _fra popbr y '*/, fraction popbr x setdivu #0 setdivu x setdivb y getdivq x wc if_nc jmp #$-1 pushbr x ' ' ' Equality tests ' org snippet _e popbr y '<>, test not equal, c=0 popbr a ' =, test equal, c=1 cmp a,y wz if_z_eq_c not x pushbr x org snippet _m if_nc popbr y ' <, test below, z=1, c=0 popbr x ' >, test above, z=1, c=1 if_c popbr y '=> / >=, test above or equal, z=0, c=0 cmps x,y wc '=< / <=, test below or equal, z=0, c=1 muxc x,hFFFFFFFF if_nz not x pushbr x ' ' ' Math terms ' org snippet _divh64 popbr y 'QUO64(al,ah,b), z=1, c=0 popbr x 'QUO64U(al,ah,b), z=1, c=1 popbr a 'REM64(al,ah,b), z=0, c=0 if_nc setdiva a 'REM64U(al,ah,b), z=0, c=1 if_c setdivu a setdiva x setdivb y getdivq x wc if_nc jmp #$-1 if_nz getdivr x wc pushbr x org snippet _sqrt64 popbr x 'SQRT64(l,h) setsqrh x popbr x setsqrl x getsqrt x wc if_nc jmp #$-1 pushbr x org snippet _negb popbr x wz 'NEGB(x,bool) popbr x negnz x,x pushbr x org snippet _muxb popbr y wz 'MUXB(x,y,bool) popbr y popbr x muxnz x,y pushbr x org snippet _ternary popbr y 'a ? x : y popbr x popbr a wz if_nz pushbr x if_z pushbr y ' ' ' Math procedures ' org snippet _mul64 popbr x 'MUL64(a,b : l,h), c=0 if_nc setmula x 'MUL64U(a,b : l,h), c=1 if_c setmulu x popbr x setmulb x getmulh x wc if_nc jmp #$-1 pushbr x getmull x pushbr x org snippet _div64 popbr y 'DIV64(al,ah,b : q,r), c=0 popbr x 'DIV64U(al,ah,b : q,r), c=1 popbr a if_nc setdiva a if_c setdivu a setdiva x setdivb y getdivr x wc if_nc jmp #$-1 pushbr x getdivq x wc pushbr x org snippet _qtrig if_z_and_c popbr x 'QSINCOS(r,t : x,y), z=1, c=0 if_z_and_c setqz x 'QROTATE(x,y,t : x,y), z=1, c=1 popbr y 'QARCTAN(x,y : r,t), z=0 popbr x if_z_and_nc qsincos y,x if_z_and_c qrotate x,y if_nz qarctan x,y getqz x wc if_nc jmp #$-1 if_z getqy x pushbr x getqx x pushbr x org snippet _getacca getacca x 'GETACCA(l,h) getacca y pushbr y pushbr x org snippet _getaccb getaccb x 'GETACCB(l,h) getaccb y pushbr y pushbr x ' ' ' Constants ' org snippet _con8 rdbytec x,ptrb++ 'con8p/con8n _conxn if_c not x 'conm1 _conxp pushbr x 'con0..con3 org snippet _conexp rdbytec x,ptrb++ 'conexp decod5 x wz, wc if_z sub x,#1 if_c not x pushbr x org snippet _con16 rdbytec x,ptrb++ 'con16p/con16n rdbytec y,ptrb++ shl x,#8 or x,y if_c not x pushbr x org snippet _con32 reps #4,#3 'con32 nop rdbytec y,ptrb++ shl x,#8 or x,y pushbr x ' ' ' Inter-memory moves ' org snippet _reg2reg call #premove 'reg2reg cmp x,y wc if_c add x,a repd a,#4 if_c add y,a movs :move,x movd :move,y :step long 1<<9 + 1 '(nop) nop :move mov 0,0 sumc :move,:step org snippet _reg2stk call #premove 'reg2stk movd :set,x repd a,#1 getspb b setspb y :set setindb #0 pushb indb++ setspb b org snippet _reg2loc call #premove 'reg2loc movd :set,x subr y,dbase repd a,#1 getspb b setspb y :set setindb #0 pushbr indb++ setspb b org snippet _reg2mem call #premove 'reg2mem movd :set,x repd a,#1 getptrb b setptrb y :set setindb #0 wrlong indb++,ptrb++ setptrb b org snippet _stk2reg call #premove 'stk2reg movd :set,y repd a,#1 getspb b setspb x :set setindb #0 popbr indb++ setspb b org snippet _stk2stk call #premove 'stk2stk cmp x,y wc if_c add x,a if_c add y,a repd a,#6 if_c xor :rd,#%10 if_c xor :wr,#%10 getspb b setspb x :rd popbr a getspb x setspb y :wr pushb a getspb y setspb b org snippet _stk2loc call #premove 'stk2loc repd a,#6 nop subr y,dbase getspb b setspb x popbr a getspb x setspb y pushbr a getspb y setspb b org snippet _stk2mem call #premove 'stk2mem repd a,#3 getspb b setspb x nop popbr x wrlong x,y add y,#4 setspb b org snippet _loc2reg call #premove 'loc2reg subr x,dbase movd :set,y repd a,#1 getspb b setspb x :set setindb #0 popb indb++ setspb b org snippet _loc2stk call #premove 'loc2stk repd a,#6 nop subr x,dbase getspb b setspb x popb a getspb x setspb y pushb a getspb y setspb b org snippet _loc2loc call #premove 'loc2loc cmp x,y wc if_c add x,a if_c add y,a subr x,dbase subr y,dbase repd a,#6 if_c xor :rd,#%10 if_c xor :wr,#%10 getspb b setspb x :rd popb a getspb x setspb y :wr pushbr a getspb y setspb b org snippet _loc2mem call #premove 'loc2mem repd a,#3 subr x,dbase getspb b setspb x :loop popb x wrlong x,y add y,#4 setspb b org snippet _mem2reg call #premove 'mem2reg movd :set,y repd a,#1 getptrb b setptrb x :set setindb #0 rdlongc indb++,ptrb++ setptrb b org snippet _mem2stk call #premove 'mem2stk getspb b setspb y repd a,#2 getptrb a setptrb x rdlongc x,ptrb++ pushb x setptrb a setspb b org snippet _mem2loc call #premove 'mem2loc subr y,dbase getspb b setspb y repd a,#2 getptrb a setptrb x rdlongc x,ptrb++ pushbr x setptrb a setspb b org snippet _xmove mov b,x 'mem2mem/bytemove/wordmove/longmove decod5 b or :shl,x shl x,#26 or :rd,x or :wr,x call #premove cmp x,y wc repd a,#4 :shl if_c shl a,#0 if_c add x,a if_c add y,a :rd rdbytec a,x :wr wrbyte a,y sumc x,b sumc y,b org snippet _qmove call #premove 'quadmove cmp x,y wc repd a,#4 if_c shl a,#4 if_c add x,a if_c add y,a rdquad x wrquad y sumc x,#16 sumc y,#16 ' ' ' Register read/write/assign ' org snippet _rdreg popbr a 'read register movd :rd,a nop nop :rd pushbr $000 org snippet _wrreg popbr addr 'write register popbr x call #writer org snippet _asreg popbr addr 'assign register movs :rd,addr mov assign_i,callwriter nop :rd mov x,$000 jmp #assign_long org snippet _rdregb call #bitfield 'read register bitfield popbr a movs :rd,a nop nop :rd mov x,$000 jmp #readb org snippet _wrregb call #bitfield 'write/assign register bitfield popbr addr movs :rd,addr mov writeb_i,callwriter nop :rd mov bval,$000 if_z jmp #writeb 'write, z=1 jmp #assignb_long 'assign, z=0 ' ' ' Stack read/write/assign ' org snippet _rdstk popbr a 'read stack getspb y setspb a popbr x setspb y pushbr x org snippet _wrstk popbr a 'write stack popbr x getspb y setspb a pushb x setspb y org snippet _asstk popbr a 'assign stack getspb y setspb a popbr x subspb #1 getspb addr setspb y mov assign_i,callwrites jmp #assign_long org snippet _rdstkb call #bitfield 'read stack bitfield popbr a getspb y setspb a popbr x setspb y jmp #readb org snippet _wrstkb call #bitfield 'write/assign stack bitfield popbr a getspb y add a,#1 setspb a popb bval getspb addr setspb y mov writeb_i,callwrites if_z jmp #writeb 'write, z=1 jmp #assignb_long 'assign, z=0 ' ' ' Local read/write/assign ' org snippet _rdloci popbr y 'read local, indexed _rdloc rdbytec x,ptrb++ 'read local if_c add x,y _rdlocx getspb y 'read local, fixed setspb dbase subspb x popb x setspb y pushbr x org snippet _wrloci popbr y 'write local, indexed _wrloc rdbytec x,ptrb++ 'write local if_c add x,y _wrlocx popbr a 'write local, fixed getspb y setspb dbase subspb x pushbr a setspb y org snippet _asloci popbr y 'assign local, indexed _asloc rdbytec x,ptrb++ 'assign local if_c add x,y _aslocx getspb y 'assign local, fixed setspb dbase subspb x popb x getspb addr setspb y mov assign_i,callwrites jmp #assign_long org snippet _rdlocb call #bitfield 'read local bitfield popbr x getspb y setspb dbase subspb x popb x setspb y jmp #readb org snippet _wrlocb call #bitfield 'write/assign local bitfield popbr x getspb y setspb dbase subspb x popb bval getspb addr setspb y mov writeb_i,callwrites if_z jmp #writeb 'write, z=1 jmp #assignb_long 'assign, z=0 ' ' ' Memory read/write/assign ' org snippet _rdbyte popbr x 'read byte rdbyte x,x pushbr x org snippet _rdword popbr x 'read word rdword x,x pushbr x org snippet _rdlong popbr x 'read long rdlong x,x pushbr x org snippet _wrbyte popbr a 'write byte popbr x wrbyte x,a org snippet _wrword popbr a 'write word popbr x wrword x,a org snippet _wrlong popbr a 'write long popbr x wrlong x,a org snippet _asbyte popbr addr 'assign byte rdbyte x,addr mov assign_i,:i mov mask,#$FF jmp #assign :i wrbyte x,addr org snippet _asword popbr addr 'assign word rdword x,addr mov assign_i,:i mov mask,:m jmp #assign :i wrword x,addr :m long $0000FFFF org snippet _aslong popbr addr 'assign long rdlong x,addr mov assign_i,:i jmp #assign_long :i wrlong x,addr org snippet _rdbyteb call #bitfield 'read byte bitfield popbr x rdbyte x,x jmp #readb org snippet _rdwordb call #bitfield 'read word bitfield popbr x rdword x,x jmp #readb org snippet _rdlongb call #bitfield 'read long bitfield popbr x rdlong x,x jmp #readb org snippet _wrbyteb call #bitfield 'write/assign byte bitfield popbr addr rdbyte bval,addr mov writeb_i,:wr if_z jmp #writeb 'write, z=1 mov mask,#$FF 'assign, z=0 jmp #assignb :wr wrbyte x,addr org snippet _wrwordb call #bitfield 'write/assign word bitfield popbr addr rdword bval,addr mov writeb_i,:wr if_z jmp #writeb 'write, z=1 mov mask,:mask 'assign, z=0 jmp #assignb :wr wrword x,addr :mask long $0000FFFF org snippet _wrlongb call #bitfield 'write/assign long bitfield popbr addr rdlong bval,addr mov writeb_i,:wr if_z jmp #writeb 'write, z=1 jmp #assignb_long 'assign, z=0 :wr wrlong x,addr ' ' ' Memory offsets and indexing ' org snippet _vbaseo call #xword add x,vbase pushbr x org snippet _pbaseo call #xword add x,pbase pushbr x org snippet _index popbr y 'ibyte, x=0 shl y,x 'iword, x=1 popbr x 'ilong, x=2 add x,y pushbr x ' ' ' Branch jmp/jz/jnz/tjz/djnz ' org snippet _jmp call #xword 'jmp addptrb x org snippet _jz popbr y wz 'jz call #xword if_z addptrb x org snippet _jnz popbr y wz 'jnz call #xword if_nz addptrb x org snippet _tjz popbr y wz 'tjz if_nz pushbr y call #xword if_z addptrb x org snippet _djnz popbr y 'djnz sub y,#1 wz if_nz pushbr y call #xword if_nz addptrb x ' ' ' Drop anchor ' ' \sub x = %00 ' \sub result x = %01 ' sub x = %10 ' sub result x = %11 ' org snippet _drop pushbr dcall 'push dcall (later used for pcurr) getspb dcall 'set new dcall pushbr dbase 'push return dbase pushbr vbase 'push return vbase or x,pbase 'push return pbase w/flags pushbr x pushbr #0 'init 'result' to 0 ' ' ' Call ' ' obj.sub z=1, c=0 ' obj.sub[] z=1, c=1 ' obj[].sub z=0, c=0 ' obj[].sub[] z=0, c=1 ' sub c=0 ' sub[] c=1 ' ptr ' org snippet _callobj rdbytec x,ptrb++ 'get obj byte if_nz popbr a 'add any obj index if_nz add x,a rdbytec y,ptrb++ 'get sub byte if_c popbr a 'add any sub index if_c add y,a jmp #call_obj 'jump to handler org snippet _callsub rdbytec y,ptrb++ 'get sub byte if_c popbr a 'add any index if_c add y,a jmp #call_sub 'jump to handler org snippet _callptr popbr x 'get sub [31..29]/[15..13], vbase [28..16], pbase [12..0] mov vbase,#0 'clear vbase/pbase mov pbase,#0 mov y,x 'get sub (6-bits) mov a,x shr y,#32-3-3 and y,#%111000 shr a,#16-3 and a,#%000111 or y,a jmp #call_ptr 'jump to handler ' ' ' RETURN/ABORT ' ' RETURN z=1, c=0 ' ABORT z=1, c=1 ' RETURN value z=0, c=0 ' ABORT value z=0, c=1 ' org snippet _return if_z setspb dbase 'if no value, return result if_z popb x if_nz popbr x 'if value, pop it :again setspb dbase 'set dbase popbr pbase 'pop pbase popbr vbase 'pop vbase popbr dbase 'pop dbase popbr y 'pop pcurr if_c test pbase,#%10 wc 'if abort and try, return again if_c jmp #:again setptrb y 'set ptrb to pcurr test pbase,#%01 wc 'push result? andn pbase,#%11 if_c pushbr x ' ' ' Get vbase/pbase ' org snippet _basesub mov y,vbase shl y,#16-4 mov x,pbase shr x,#4 or x,y pushbr x ' ' ' Get pbase/vbase of obj ' ' obj c=0 ' obj[] c=1 ' org snippet _baseobj rdbytec x,ptrb++ 'get obj byte if_c popbr y 'handle index if_c add x,y shl x,#2 'scale offset add x,pbase 'get obj pbase/vbase offset rdlong x,x mov y,x 'get obj vbase shr y,#16-4 add y,vbase and y,h0001FFF0 shl y,#16-4 shl x,#4 'get obj pbase add x,pbase and x,h0001FFF0 shr x,#4 or x,y 'merge vbase/pbase pushbr x 'push obj vbase/pbase ' ' ' Make subroutine ptr ' ' base.sub c=0 ' base.sub[] c=1 ' org snippet _subptr rdbytec a,ptrb++ 'get sub number if_c popbr b 'handle sub index if_c add a,b mov b,a 'split 6-bit index and b,#%111000 'top 3 bits into [31..29] shl b,#32-6 and a,#%000111 'bottom 3 bits into [15..13] shl a,#16-3 popbr x 'pop base vbase/pbase or x,b 'install index into pbase/vbase or x,a pushbr x 'push subroutine pointer ' ' ' Case ' org snippet 'case value _casev call #xword 'get branch address popbr a 'pop value popbr y 'pop target cmp a,y wz 'value = target? if_nz subspb #1 'if mismatch, unpop target if_z addptrb x 'if match, branch org snippet 'case range (z=1) _caser call #xword 'get branch address popbr b 'pop range end popbr a 'pop range begin popbr y 'pop target sub b,a '||(end - begin), c=1 if reverse range abs b,b wc sub y,a '+/-(target - begin) negc y,y cmp b,y wc 'match if ||(end - begin) => +/-(target - begin) if_c subspb #1 'if mismatch, unpop target if_nc addptrb x 'if match, branch org snippet 'case done _casedone popbr x 'pop target popbr x 'pop address setptrb x 'jump to address ' ' ' Lookup/lookdown ' org snippet 'lookup value _lookupv popbr a 'pop value popbr x 'pop index popbr y 'pop target cmp x,y wz 'match if index = target if_nz subspb #1 'if no match, unpop target if_nz add x,#1 '..increment index if_nz pushbr x '..push index if_z popbr addr 'if match, pop address if_z pushbr a '..push result if_z setptrb addr '..branch org snippet 'lookup range _lookupr popbr b 'pop range end popbr a 'pop range begin popbr x 'pop index popbr y 'pop target sub b,a 'end - begin abs b,b wc '||(end - begin), c=1 if reverse range sub y,x 'target - index sumc a,y 'result = begin +/- (target - index) cmp b,y wc 'match if ||(end - begin) => (target - index) if_c subspb #1 'if no match, unpop target if_c addx x,b '..add ||(end - begin) + 1 to index if_c pushbr x '..push index if_nc popbr addr 'if match, pop address if_nc pushbr a '..push result if_nc setptrb addr '..branch org snippet 'lookdown value _lookdnv popbr a 'pop value popbr x 'pop index popbr y 'pop target cmp a,y wz 'match if value = target if_nz subspb #1 'if no match, unpop target if_nz add x,#1 '..increment index if_nz pushbr x '..push index if_z popbr addr 'if match, pop address if_z pushbr x '..push result if_z setptrb addr '..branch org snippet 'lookdown range _lookdnr popbr b 'pop range end popbr a 'pop range begin popbr x 'pop index popbr y 'pop target sub b,a '||(end - begin), c=1 if reverse range abs b,b wc sub y,a '+/-(target - begin) negc y,y cmp b,y wc 'match if ||(end - begin) => +/-(target - begin) if_c subspb #1 'if no match, unpop target if_c addx x,b '..add ||(end - begin) + 1 to index if_c pushbr x '..push index if_nc popbr addr 'if match, pop address if_nc add x,y '..result = index +/- (target - begin) if_nc pushbr x '..push result if_nc setptrb addr '..branch org snippet 'lookup/lookdown done _lookdone addspb #3 'pop index/target/address pushbr #0 'push 0 result ' ' ' Miscellaneous ' org snippet _acc rdbyte a,ptrb++ 'acc movd :inst,a nop nop :inst long %000011_000_1_1111_000000000_000001000 org snippet _gen rdbyte a,ptrb++ 'gen movs :inst,a if_c popbr x nop :inst long %000011_010_1_1111<<18 + x<<9 if_nc pushbr #0 if_c pushbr hFFFFFFFF org snippet _get rdbyte a,ptrb++ 'get movs :inst,a nop nop :inst long %000011_001_1_1111<<18 + x<<9 pushbr x org snippet _set2 rdbyte a,ptrb++ 'set2 shl a,#24 sar a,#1 or :inst,a popbr y popbr x :inst long %000000_000_0_1111<<18 + x<<9 + y org snippet _set2r rdbyte a,ptrb++ 'set2r movi :inst,a popbr y popbr x :inst long %000000_000_0_1111<<18 + x<<9 + y pushbr x org snippet _coginit popbr y 'COGINIT(cog,pgm,par) / COGNEW(pgm,par) popbr x if_nc popbr a if_c mov a,#8 setcog a coginit x,y wc,wr if_c mov x,hFFFFFFFF pushbr x org snippet _locknew locknew x wc 'LOCKNEW if_c mov x,hFFFFFFFF pushbr x org snippet _rcvser rcvser x wc 'RCVSER(var) if_c muxc y,hFFFFFFFF if_c pushbr y pushbr x org snippet _getcnth getcnt x 'GETCNTH getcnt x pushbr x org snippet _jmptask popbr y 'JMPTASK(addr,mask) and y,#%1111 or :inst,y popbr x nop :inst jmptask x,#0 org snippet _callb popbr x 'CALLB(addr) subspb #1 callb x addspb #1 org snippet _strsize popbr x 'STRSIZE(@str) mov y,x :loop rdbytec a,x wz if_nz add x,#1 if_nz jmp #:loop sub x,y pushbr x org snippet _strcomp popbr y 'STRCOMP(@stra,@strb) popbr x :loop rdbytec a,x rdbyte b,y add x,#1 add y,#1 cmp a,b wz if_z tjz a,#:got if_z jmp #:loop :got muxz x,hFFFFFFFF pushbr x org snippet _xfill shl x,#26 'BYTEFILL/WORDFILL/LONGFILL/QUADFILL(value,addr,count) or :wr,x shr x,#26 decod5 x popbr y wz popbr a popbr b setquad #_xfill reps #4,#1 setindb #_xfill mov indb++,b :wr if_nz_and_nc wrbyte b,a if_nz_and_c wrquad a if_nz add a,x if_nz djnz y,#:wr setquad #$1FF org snippet _pushcopy popbr x 'push copy pushbr x pushbr x org snippet _pop rdbytec x,ptrb++ 'pop addspb x