CON base = $E80 ' ' '*************** '* Interpreter * '*************** ' DAT orgh base org $15B ' ' ' Append word to x - makes $0xxxx or $1xxxx address ' xword rdbytec y,ptra++ xword_ret retd movf x,y rdbytec y,ptra++ movf x,y ' ' ' 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 add dbase,#3 setspb dcall 'get old dcall popb dcall getptra x 'set return pcurr pushb x setptra pbase 'set call pcurr jmpd #getbyte 'loop to getbyte, delayed addptra y shr y,#32-4 'add locals to dcurr addspa y ' ' ' Bitfield addressing, pop and set bitfield parameters ' bitfield popa bshift 'pop range lsb popa 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 bitfield_ret retd 'return, delayed setbc brev,#6 'save reverse flag blmask bmask 'get bitlength mask shl bmask,bshift 'bmask = mask, brev = reverse, bshift = lsb offset ' ' ' Write register, if OUTA..OUTD then update PINA..PIND (x = value) ' writer movd writer_reg,addr movd writer_pin,addr setb writer_pin,#9+3 writer_reg mov $000,x writer_ret retd xor addr,#$1F0 test addr,#$1FC wz writer_pin if_z mov $000,x ' ' ' Do bitfield read (x = value) ' readb and x,bmask jmpd #getbyte shr x,bshift if_c rev x,brev pusha x ' ' ' Do bitfield write (bval = value, writeb_i = write instruction) ' writeb popa 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 pushbr x 'call #writer / pushbr x / 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 jmpd #assign_op 'get math operator and execute, delayed and x,bmask 'extract bitfield for operation shr x,bshift if_c rev x,brev assignb_ret testb brev,#6 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 jmpd #assign_p 'push it (optional), delayed and x,bmask 'extract bitfield for pushing shr x,bshift if_c rev x,brev ' ' ' Do assignment (x = value, assign_i = write instruction, mask = sized mask) ' assign_local mov assign_i,pushbrx 'set local write assign_long mov mask,hFFFFFFFF 'set long mask assign movs jmpback,#assign_ret 'set jmpback address to :ret assign_op rdbytec a,ptra++ 'get math operator and flags setzc a wz,wc 'load flags, operator already in position muxz assign_p,h003C0000 'set push condition to z jmpd #hotbyte 'load and execute math snippet, delayed if_c popa y 'swap args? pusha x if_c pusha y assign_ret popa x 'snippet returns to here, pop value assign_i pushbr x 'write it (call #writer / pushbr x / wrxxxx x,addr) and x,mask 'mask it assign_p pusha 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,ptra++ wz ' get byte code, extended? if_z rdbytec a,ptra++ ' if extended, get extended byte code if_z or a,#$100 ' ...and add offset shl a,#2 ' shift to make long offset hotbyte add a,descbase ' add base address of descriptor longs 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 mov indb++,jmpback '+1 finish in-line code with 'jmp #getbyte' shr x,#25-7 wz,wc '+1 descriptor[31..25] is a value, [24] is C snippet long 0[22] '? execute in-line code snippet, loop ' ' ' Constants ' pushbrx pushbr x callwriter call #writer jmpback jmp #getbyte descbase long @descs-4 'account for $01 offset h0001FFF0 long $0001FFF0 'vbase/pbase mask h003C0000 long $003C0000 'conditional field bits hFFFFFFFF long $FFFFFFFF 'all bits x long 0 'variables y long 0 a long 0 b long 0 addr long 0 'assignment mask long 0 bshift long 0 'bitfield addressing bmask long 0 brev long 0 bval long 0 dcall long 0 ' pointer dbase long 0 ' pointer outa long 0 '@$1F0 OUTA..OUTD outb long 0 '@$1F1 (writes update PINA..PIND) outc long 0 '@$1F2 outd long 0 '@$1F3 vbase long 0 '@$1F4 pointer pbase long 0 '@$1F5 pointer ' ' '************************ '* Bytecode Descriptors * '************************ ' descs ' 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 (23) op_notb long %0000000_0 << 24 + @_notb << 7 + 2 'NOT %x0 op_not long %0000000_0 << 24 + @_not << 7 + 2 '! %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_decod5 long %0000000_0 << 24 + @_decod5 << 7 + 2 '|<, DECOD5(x) %x0 op_decod4 long %0000000_0 << 24 + @_decod4 << 7 + 2 'DECOD4(x) %x0 op_decod3 long %0000000_0 << 24 + @_decod3 << 7 + 2 'DECOD3(x) %x0 op_decod2 long %0000000_0 << 24 + @_decod2 << 7 + 2 'DECOD2(x) %x0 op_blmask long %0000000_0 << 24 + @_blmask << 7 + 2 'BLMASK(x) %x0 op_onecnt long %0000000_0 << 24 + @_onecnt << 7 + 2 'ONECNT(x) %x0 op_zercnt long %0000000_0 << 24 + @_zercnt << 7 + 2 'ZERCNT(x) %x0 op_incpat long %0000000_0 << 24 + @_incpat << 7 + 2 'INCPAT(x) %x0 op_decpat long %0000000_0 << 24 + @_decpat << 7 + 2 'DECPAT(x) %x0 op_bingry long %0000000_0 << 24 + @_bingry << 7 + 2 'BINGRY(x) %x0 op_grybin long %0000000_0 << 24 + @_grybin << 7 + 2 'GRYBIN(x) %x0 op_mergew long %0000000_0 << 24 + @_mergew << 7 + 2 'MERGEW(x) %x0 op_splitw long %0000000_0 << 24 + @_splitw << 7 + 2 'SPLITW(x) %x0 op_seussf long %0000000_0 << 24 + @_seussf << 7 + 2 'SEUSSF(x) %x0 op_seussr long %0000000_0 << 24 + @_seussr << 7 + 2 '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 ' binaries (23) op_andb long %0000000_0 << 24 + @_andb << 7 + 4 'AND %x1 op_orb long %0000000_0 << 24 + @_orb << 7 + 4 'OR %x1 op_xorb long %0000000_0 << 24 + @_xorb << 7 + 5 'XOR %x1 op_andn long %0000000_0 << 24 + @_andn << 7 + 3 '&! %x1 op_and long %0000000_0 << 24 + @_and << 7 + 3 '& %x1 op_or long %0000000_0 << 24 + @_or << 7 + 3 '| %x1 op_xor long %0000000_0 << 24 + @_xor << 7 + 3 '^ %x1 op_ror long %0000000_0 << 24 + @_ror << 7 + 3 '-> %x1 op_rol long %0000000_0 << 24 + @_rol << 7 + 3 '<- %x1 op_shr long %0000000_0 << 24 + @_shr << 7 + 3 '>> %x1 op_shl long %0000000_0 << 24 + @_shl << 7 + 3 '<< %x1 op_sar long %0000000_0 << 24 + @_sar << 7 + 3 '~> %x1 op_sal long %0000000_0 << 24 + @_sal << 7 + 5 '<~ %x1 op_rev long %0000000_0 << 24 + @_rev << 7 + 4 '>< %x1 op_mins long %0000000_0 << 24 + @_mins << 7 + 3 '#> %x1 op_maxs long %0000000_0 << 24 + @_maxs << 7 + 3 '<# %x1 op_add long %0000000_0 << 24 + @_add << 7 + 3 '+ %x1 op_sub long %0000000_0 << 24 + @_sub << 7 + 3 '- %x1 op_mul long %0000000_0 << 24 + @_mul << 7 + 6 '* %x1 op_scl long %0000001_0 << 24 + @_scl << 7 + 6 '** %x1 op_quo 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 + @_b << 7 + 4 '< op_a long %0000000_0 << 24 + @_a << 7 + 4 '> op_ne long %0000000_0 << 24 + @_ne << 7 + 4 '<> op_eq long %0000000_0 << 24 + @_eq << 7 + 4 '== op_be long %0000000_0 << 24 + @_be << 7 + 4 '=< / <= op_ae long %0000000_0 << 24 + @_ae << 7 + 4 '=> / >= ' 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 'sel ? true : false ' math procedures (20) op_mul64 long %0000000_0 << 24 + @_mul64 << 7 + 9 'MUL64(a,b : l,h) op_mulu64 long %0000000_1 << 24 + @_mul64 << 7 + 9 'MUL64U(a,b : l,h) op_div64 long %0000000_0 << 24 + @_div64 << 7 + 11 'DIV64(a,b : l,h) op_divu64 long %0000000_1 << 24 + @_div64 << 7 + 11 'DIV64U(a,b : l,h) 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_setqi long %0000000_1 << 24 + @_div64 << 7 + 1 'SETQI(x) op_clraccs long %0000000_0 << 24 + @_clraccs << 7 + 0 'CLRACCS op_clracca long %0000000_0 << 24 + @_clracca << 7 + 0 'CLRACCA op_clraccb long %0000000_0 << 24 + @_clraccb << 7 + 0 'CLRACCB op_fitaccs long %0000000_0 << 24 + @_fitaccs << 7 + 0 'FITACCS op_fitacca long %0000000_0 << 24 + @_fitacca << 7 + 0 'FITACCA op_fitaccb long %0000000_0 << 24 + @_fitaccb << 7 + 0 'FITACCB op_setacca long %0000000_0 << 24 + @_setacca << 7 + 2 'SETACCA(l,h) op_setaccb long %0000000_0 << 24 + @_setaccb << 7 + 2 'SETACCB(l,h) op_getacca long %0000000_0 << 24 + @_getacca << 7 + 3 'GETACCA(l,h) op_getaccb long %0000000_0 << 24 + @_getaccb << 7 + 3 'GETACCB(l,h) op_maca long %0000000_0 << 24 + @_maca << 7 + 2 'MACA(x,y) op_macb long %0000000_0 << 24 + @_macb << 7 + 2 'MACB(x,y) ' constants (13) op_con1n long %0000000_0 << 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 + @_con8p << 7 + 1 'constant $000000xx op_con9p long %0000000_0 << 24 + @_con9p << 7 + 2 'constant $000001xx op_con8n long %0000000_0 << 24 + @_con8n << 7 + 2 'constant $FFFFFFxx op_con16p long %0000000_0 << 24 + @_con16p << 7 + 3 'constant $0000xxxx op_con17p long %0000000_0 << 24 + @_con17p << 7 + 3 'constant $0001xxxx op_con16n long %0000000_0 << 24 + @_con16n << 7 + 4 'constant $FFFFxxxx op_con24p long %0000000_0 << 24 + @_con24 << 7 + 4 'constant $00xxxxxx op_con24n long %0000000_1 << 24 + @_con24 << 7 + 4 'constant $FFxxxxxx op_con32 long %0000000_0 << 24 + @_con32 << 7 + 4 'constant $xxxxxxxx op_conexp long %0000000_0 << 24 + @_conexp << 7 + 4 'constant 2^n,dec,not ' 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 %0000000_0 << 24 + @_asregb << 7 + 6 'assign register bitfield ' local reads/writes/assigns (54) op_rdloc0 long %0000000_0 << 24 + @_rdloc << 7 + 3 'read local 0 op_rdloc1 long %0000001_0 << 24 + @_rdloc << 7 + 3 'read local 1 op_rdloc2 long %0000010_0 << 24 + @_rdloc << 7 + 3 'read local 2 op_rdloc3 long %0000011_0 << 24 + @_rdloc << 7 + 3 'read local 3 op_rdloc4 long %0000100_0 << 24 + @_rdloc << 7 + 3 'read local 4 op_rdloc5 long %0000101_0 << 24 + @_rdloc << 7 + 3 'read local 5 op_rdloc6 long %0000110_0 << 24 + @_rdloc << 7 + 3 'read local 6 op_rdloc7 long %0000111_0 << 24 + @_rdloc << 7 + 3 'read local 7 op_rdloc8 long %0001000_0 << 24 + @_rdloc << 7 + 3 'read local 8 op_rdloc9 long %0001001_0 << 24 + @_rdloc << 7 + 3 'read local 9 op_rdloc10 long %0001010_0 << 24 + @_rdloc << 7 + 3 'read local 10 op_rdloc11 long %0001011_0 << 24 + @_rdloc << 7 + 3 'read local 11 op_rdloc12 long %0001100_0 << 24 + @_rdloc << 7 + 3 'read local 12 op_rdloc13 long %0001101_0 << 24 + @_rdloc << 7 + 3 'read local 13 op_rdloc14 long %0001110_0 << 24 + @_rdloc << 7 + 3 'read local 14 op_rdloc15 long %0001111_0 << 24 + @_rdloc << 7 + 3 'read local 15 op_wrloc0 long %0000000_0 << 24 + @_wrloc << 7 + 3 'write local 0 op_wrloc1 long %0000001_0 << 24 + @_wrloc << 7 + 3 'write local 1 op_wrloc2 long %0000010_0 << 24 + @_wrloc << 7 + 3 'write local 2 op_wrloc3 long %0000011_0 << 24 + @_wrloc << 7 + 3 'write local 3 op_wrloc4 long %0000100_0 << 24 + @_wrloc << 7 + 3 'write local 4 op_wrloc5 long %0000101_0 << 24 + @_wrloc << 7 + 3 'write local 5 op_wrloc6 long %0000110_0 << 24 + @_wrloc << 7 + 3 'write local 6 op_wrloc7 long %0000111_0 << 24 + @_wrloc << 7 + 3 'write local 7 op_wrloc8 long %0001000_0 << 24 + @_wrloc << 7 + 3 'write local 8 op_wrloc9 long %0001001_0 << 24 + @_wrloc << 7 + 3 'write local 9 op_wrloc10 long %0001010_0 << 24 + @_wrloc << 7 + 3 'write local 10 op_wrloc11 long %0001011_0 << 24 + @_wrloc << 7 + 3 'write local 11 op_wrloc12 long %0001100_0 << 24 + @_wrloc << 7 + 3 'write local 12 op_wrloc13 long %0001101_0 << 24 + @_wrloc << 7 + 3 'write local 13 op_wrloc14 long %0001110_0 << 24 + @_wrloc << 7 + 3 'write local 14 op_wrloc15 long %0001111_0 << 24 + @_wrloc << 7 + 3 'write local 15 op_asloc0 long %0000000_0 << 24 + @_asloc << 7 + 3 'assign local 0 op_asloc1 long %0000001_0 << 24 + @_asloc << 7 + 3 'assign local 1 op_asloc2 long %0000010_0 << 24 + @_asloc << 7 + 3 'assign local 2 op_asloc3 long %0000011_0 << 24 + @_asloc << 7 + 3 'assign local 3 op_asloc4 long %0000100_0 << 24 + @_asloc << 7 + 3 'assign local 4 op_asloc5 long %0000101_0 << 24 + @_asloc << 7 + 3 'assign local 5 op_asloc6 long %0000110_0 << 24 + @_asloc << 7 + 3 'assign local 6 op_asloc7 long %0000111_0 << 24 + @_asloc << 7 + 3 'assign local 7 op_asloc8 long %0001000_0 << 24 + @_asloc << 7 + 3 'assign local 8 op_asloc9 long %0001001_0 << 24 + @_asloc << 7 + 3 'assign local 9 op_asloc10 long %0001010_0 << 24 + @_asloc << 7 + 3 'assign local 10 op_asloc11 long %0001011_0 << 24 + @_asloc << 7 + 3 'assign local 11 op_asloc12 long %0001100_0 << 24 + @_asloc << 7 + 3 'assign local 12 op_asloc13 long %0001101_0 << 24 + @_asloc << 7 + 3 'assign local 13 op_asloc14 long %0001110_0 << 24 + @_asloc << 7 + 3 'assign local 14 op_asloc15 long %0001111_0 << 24 + @_asloc << 7 + 3 'assign local 15 op_rdloci long %0000000_0 << 24 + @_rdloci << 7 + 6 'read local indexed op_wrloci long %0000000_0 << 24 + @_wrloci << 7 + 6 'write local indexed op_asloci long %0000000_0 << 24 + @_asloci << 7 + 6 'assign local indexed op_rdlocb long %0000000_0 << 24 + @_rdlocb << 7 + 5 'read local bitfield op_wrlocb long %0000000_0 << 24 + @_wrlocb << 7 + 6 'write local bitfield op_aslocb long %0000000_0 << 24 + @_aslocb << 7 + 6 '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 + 5 'write byte bitfield op_wrwordb long %0000000_0 << 24 + @_wrwordb << 7 + 5 'write word bitfield op_wrlongb long %0000000_0 << 24 + @_wrlongb << 7 + 5 'write long bitfield op_asbyteb long %0000000_0 << 24 + @_asbyteb << 7 + 6 'assign byte bitfield op_aswordb long %0000000_0 << 24 + @_aswordb << 7 + 7 'assign word bitfield op_aslongb long %0000000_0 << 24 + @_aslongb << 7 + 5 'assign long bitfield ' memory offsets and indexing (7) op_vbase0 long %0000000_0 << 24 + @_base << 7 + 3 'vbase $0xxxx op_pbase0 long %0000000_1 << 24 + @_base << 7 + 3 'pbase $0xxxx op_vbase1 long %0000001_0 << 24 + @_base << 7 + 3 'vbase $1xxxx op_pbase1 long %0000001_1 << 24 + @_base << 7 + 3 '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 (10) op_jmp0 long %0000000_0 << 24 + @_jmp << 7 + 1 'jmp +$0xxxx op_jmp1 long %0000001_0 << 24 + @_jmp << 7 + 1 'jmp +$1xxxx op_jz0 long %0000000_1 << 24 + @_jxz << 7 + 2 'jz +$0xxxx op_jz1 long %0000001_1 << 24 + @_jxz << 7 + 2 'jz +$1xxxx op_jnz0 long %0000000_0 << 24 + @_jxz << 7 + 2 'jnz +$0xxxx op_jnz1 long %0000001_0 << 24 + @_jxz << 7 + 2 'jnz +$1xxxx op_tjz0 long %0000000_0 << 24 + @_tjz << 7 + 3 'tjz +$0xxxx op_tjz1 long %0000001_0 << 24 + @_tjz << 7 + 3 'tjz +$1xxxx op_djnz0 long %0000000_0 << 24 + @_djnz << 7 + 4 'djnz +$0xxxx op_djnz1 long %0000001_0 << 24 + @_djnz << 7 + 4 'djnz +$1xxxx ' anchor drops (4) op_dropt long %0000000_0 << 24 + @_drop << 7 + 6 'drop, \sub op_droptr long %0000001_0 << 24 + @_drop << 7 + 6 'drop, \sub w/result op_drop long %0000010_0 << 24 + @_drop << 7 + 6 'drop, sub op_dropr long %0000011_0 << 24 + @_drop << 7 + 6 'drop, sub w/result ' 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_abort long %0000000_1 << 24 + @_return << 7 + 13 'ABORT op_returnv long %0000001_0 << 24 + @_return << 7 + 13 'RETURN value 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 (5) op_casev0 long %0000000_0 << 24 + @_casev << 7 + 5 'case value, +$0xxxx branch op_casev1 long %0000001_0 << 24 + @_casev << 7 + 5 'case value, +$1xxxx branch op_caser0 long %0000000_0 << 24 + @_caser << 7 + 10 'case range, +$0xxxx branch op_caser1 long %0000001_0 << 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 (6) op_pop long %0000000_0 << 24 + @_pop << 7 + 1 'pop op_clkset long %0000000_0 << 24 + @_clkset << 7 + 1 'clkset op_cogid long %0000000_0 << 24 + @_cogid << 7 + 1 'cogid op_coginit long %0000000_0 << 24 + @_coginit << 7 + 6 'coginit op_coginitp long %0000001_0 << 24 + @_coginit << 7 + 6 'coginit w/push op_cogstop long %0000000_0 << 24 + @_cogstop << 7 + 1 'cogstop ' ' '************ '* Snippets * '************ ' ' ' ' Variable modifiers ' org snippet 'repeat-var loop (assign) _rep popa mask 'pop var popa y 'pop step popa b 'pop terminal popa a 'pop initial popa addr 'pop branch offset cmps b,a wc 'get reverse range into c sumc mask,y 'update var with step rcl x,#1 wz 'get c into nz if_z cmps b,mask wc 'if forward range, check if var > terminal if_nz cmps mask,b wc 'if reverse range, check if var < terminal if_nc subptra addr 'if var within range, branch if_nc addspa #4 '..unpop offset/initial/terminal/step pusha mask 'push new var org snippet 'var~, clear and post-clear (assign) _clr popa x 'clear, pop var (single pop also used by op_writep) _clrpost pusha #0 'post-clear, push 0 (leave var on stack) org snippet 'var~~, set and post-set (assign) _set popa x 'set, pop var _setpost pusha hFFFFFFFF 'post-set, push -1 (leave var on stack) org snippet '++var/--var/var++/var-- (assign) _incdec popa x 'pop var if_nz pusha x 'if nz, push original var sumc x,#1 'inc or dec var by c pusha x 'push new var org snippet 'INCMOD/DECMOD(var,limit) (assign) _idmod setbc :i,#26 'set INCMOD/DECMOD by c popa y 'pop limit popa x 'pop var :i incmod x,y wc 'incmod/decmod, c=limit if_nz_and_nc pusha #0 'push false if nz and nc if_nz_and_c pusha hFFFFFFFF 'push true if nz and c pusha x 'push new var ' ' ' Unary functions ' org snippet _notb popa x wz 'NOT, boolean muxz x,hFFFFFFFF pusha x org snippet _not popa x '!, bitwise not not x pusha x org snippet _neg popa x '-, negate neg x,x pusha x org snippet _abs popa x '||, absolute abs x,x pusha x org snippet _enc popa x '>|, encode (0..32) enc x,x pusha x org snippet _decod5 popa x '|< / DECOD5(x) decod5 x pusha x org snippet _decod4 popa x 'DECOD4(x) decod4 x pusha x org snippet _decod3 popa x 'DECOD3(x) decod3 x pusha x org snippet _decod2 popa x 'DECOD2(x) decod2 x pusha x org snippet _blmask popa x 'BLMASK(x) blmask x pusha x org snippet _onecnt popa x 'ONECNT(x) onecnt x pusha x org snippet _zercnt popa x 'ZERCNT(x) zercnt x pusha x org snippet _incpat popa x 'INCPAT(x) incpat x pusha x org snippet _decpat popa x 'DECPAT(x) decpat x pusha x org snippet _bingry popa x 'BINGRY(x) bingry x pusha x org snippet _grybin popa x 'GRYBIN(x) grybin x pusha x org snippet _mergew popa x 'MERGEW(x) mergew x pusha x org snippet _splitw popa x 'SPLITW(x) splitw x pusha x org snippet _seussf popa x 'SEUSSF(x) seussf x pusha x org snippet _seussr popa x 'SEUSSR(x) seussr x pusha x org snippet _sqrt popa x 'SQRT(x) setsqrl x getsqrt x wc if_nc jmp #$-1 pusha x org snippet _qlogexp popa x 'QLOG(x), c=0 if_nc qlog x 'QEXP(x), c=1 if_c qexp x getqz x wc if_nc jmp #$-1 pusha x ' ' ' Binary functions ' org snippet _andb popa x wz 'AND, boolean if_z popa x if_nz popa x wz muxnz x,hFFFFFFFF pusha x org snippet _orb popa x wz 'OR, boolean if_nz popa x if_z popa x wz muxnz x,hFFFFFFFF pusha x org snippet _xorb popa y wz 'XOR, boolean muxnz y,hFFFFFFFF popa x wz muxnz x,hFFFFFFFF xor x,y pusha x org snippet _andn popa y '&!, bitwise andnot popa x andn x,y pusha x org snippet _and popa y '&, bitwise and popa x and x,y pusha x org snippet _or popa y '|, bitwise or popa x or x,y pusha x org snippet _xor popa y '^, bitwise xor popa x xor x,y pusha x org snippet _ror popa y '->, rotate right popa x ror x,y pusha x org snippet _rol popa y '<-, rotate left popa x rol x,y pusha x org snippet _shr popa y '>>, shift right popa x shr x,y pusha x org snippet _shl popa y '<<, shift left popa x shl x,y pusha x org snippet _sar popa y '~>, shift arithmetic right popa x sar x,y pusha x org snippet _sal popa y '<~, shift arithmetic left popa x rev x,#0 sar x,y rev x,#0 pusha x org snippet _rev popa y '><, reverse bits popa x neg y,y rev x,y pusha x org snippet _mins popa y '|>, limit minimum popa x mins x,y pusha x org snippet _maxs popa y '<|, limit maximum popa x maxs x,y pusha x org snippet _add popa y '+, add popa x add x,y pusha x org snippet _sub popa y '-, sub popa x sub x,y pusha x org snippet _mul popa y '*, multiply and return lower long popa x setmula x setmulb y getmull x wc if_nc jmp #$-1 pusha x org snippet _scl popa y '**, multiply return upper long, unsigned popa x setmulu x setmulb y getmulh x wc if_nc jmp #$-1 pusha x org snippet _divx popa y '/, divide and return quotient, z=1 popa x '//, divide and return remainder, z=0 setdiva x setdivb y getdivq x wc if_nc jmp #$-1 if_nz getdivr x pusha x org snippet _fra popa y '*/, fraction popa x setdivu #0 setdivu x setdivb y getdivq x wc if_nc jmp #$-1 pusha x ' ' ' Equality tests ' org snippet _b popa y '<, test below popa x cmps x,y wc muxc x,hFFFFFFFF pusha x org snippet _a popa y '>, test above popa x cmps y,x wc muxc x,hFFFFFFFF pusha x org snippet _ne popa y '<>, test not equal popa x cmps x,y wz muxnz x,hFFFFFFFF pusha x org snippet _eq popa y '==, test equal popa x cmps x,y wz muxz x,hFFFFFFFF pusha x org snippet _be popa y '=< / <=, test below or equal popa x cmps y,x wc muxnc x,hFFFFFFFF pusha x org snippet _ae popa y '=> / >=, test above or equal popa x cmps x,y wc muxnc x,hFFFFFFFF pusha x ' ' ' Math terms ' org snippet _divh64 popa y 'QUO64(al,ah,b), z=1, c=0 popa x 'QUO64U(al,ah,b), z=1, c=1 popa 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 pusha x org snippet _sqrt64 popa x 'SQRT64(l,h) setsqrh x popa x setsqrl x getsqrt x wc if_nc jmp #$-1 pusha x org snippet _negb popa x wz 'NEGB(x,bool) popa x negnz x,x pusha x org snippet _muxb popa y wz 'MUXB(x,y,bool) popa y popa x muxnz x,y pusha x org snippet _ternary popa y 'a ? x : y popa x popa a wz if_z pusha y if_nz pusha x ' ' ' Math procedures ' org snippet _mul64 popa x 'MUL64(a,b : l,h), c=0 if_nc setmula x 'MUL64U(a,b : l,h), c=1 if_c setmulu x popa x setmulb x getmulh x wc if_nc jmp #$-1 pusha x getmull x pusha x org snippet _div64 popa y 'DIV64(al,ah,b : q,r), c=0 popa x 'DIV64U(al,ah,b : q,r), c=1 popa a if_nc setdiva a if_c setdivu a setdiva x setdivb y getdivr x wc if_nc jmp #$-1 pusha x getdivq x wc pusha x org snippet _qtrig if_z_and_c popa 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 popa y 'QARCTAN(x,y : r,t), z=0 popa 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 pusha x getqx x pusha x org snippet _setqi popa x 'SETQI(i) setqi x org snippet _clraccs clraccs 'CLRACCS org snippet _clracca clracca 'CLRACCA org snippet _clraccb clraccb 'CLRACCB org snippet _fitaccs fitaccs 'FITACCS org snippet _fitacca fitacca 'FITACCA org snippet _fitaccb fitaccb 'FITACCB org snippet _setacca popa y 'SETACCA(l,h) popa x setacca x,y org snippet _setaccb popa y 'SETACCB(l,h) popa x setaccb x,y org snippet _getacca getacca x 'GETACCA(l,h) getacca y pusha y pusha x org snippet _getaccb getaccb x 'GETACCB(l,h) getaccb y pusha y pusha x org snippet _maca popa y 'MACA(x,y) popa x maca x,y org snippet _macb popa y 'MACB(x,y) popa x macb x,y ' ' ' Constants ' org snippet _con8p rdbytec x,ptra++ 'con8p _conxp pusha x 'con0..con3 org snippet _con9p rdbytec x,ptra++ 'con9p setb x,#8 pusha x org snippet _con8n rdbytec x,ptra++ 'con8n _conxn xor x,hFFFFFFFF 'conm1 pusha x org snippet _con16p rdbytec x,ptra++ 'con16p rdbytec y,ptra++ movf x,y pusha x org snippet _con17p rdbytec x,ptra++ 'con17p rdbytec y,ptra++ movf x,y setb x,#16 pusha x org snippet _con16n rdbytec x,ptra++ 'con16n rdbytec y,ptra++ movf x,y xor x,hFFFFFFFF pusha x org snippet _con24 reps #3,#2 'con24p, con24n muxc x,#$FF rdbytec y,ptra++ movf x,y pusha x _con32 reps #4,#2 'con32 nop rdbytec y,ptra++ movf x,y pusha x org snippet _conexp rdbytec x,ptra++ 'conexp decod5 x wz, wc if_z sub x,#1 if_c not x pusha x ' ' ' Register read/write/assign ' org snippet _rdreg popa x 'read register movd :rd,x nop nop :rd pusha $000 org snippet _wrreg popa addr 'write register popa x call #writer org snippet _asreg popa addr 'assign register movs :rd,addr jmpd #assign_long mov assign_i,callwriter :rd mov x,$000 nop org snippet _rdregb call #bitfield 'read register bitfield popa x movs :rd,x jmpd #readb nop :rd mov x,$000 nop org snippet _wrregb call #bitfield 'write register bitfield popa addr movs :rd,addr jmpd #writeb mov writeb_i,callwriter :rd mov bval,$000 nop org snippet _asregb call #bitfield 'assign register bitfield popa addr movs :rd,addr jmpd #assignb_long mov writeb_i,callwriter :rd mov bval,$000 nop ' ' ' Local read/write/assign ' org snippet _rdloci popa y 'read local, indexed rdbytec x,ptra++ add x,y _rdloc add x,dbase 'read local, fixed setspb x popbr x pusha x org snippet _wrloci popa y 'write local, indexed rdbytec x,ptra++ add x,y _wrloc add x,dbase 'write local, fixed setspb x popa x pushb x org snippet _asloci popa y 'assign local, indexed rdbytec x,ptra++ add x,y _asloc jmpd #assign_local 'assign local, fixed add x,dbase setspb x popbr x org snippet _rdlocb call #bitfield 'read local bitfield popa x jmpd #readb add x,dbase setspb x popbr x org snippet _wrlocb call #bitfield 'write local bitfield popa x add x,dbase jmpd #writeb setspb x popbr bval mov writeb_i,pushbrx org snippet _aslocb call #bitfield 'assign local bitfield popa x add x,dbase jmpd #assignb_long setspb x popbr bval mov writeb_i,pushbrx ' ' ' Memory read/write/assign ' org snippet _rdbyte popa x 'read byte rdbyte x,x pusha x org snippet _rdword popa x 'read word rdword x,x pusha x org snippet _rdlong popa x 'read long rdlong x,x pusha x org snippet _wrbyte popa y 'write byte popa x wrbyte x,y org snippet _wrword popa y 'write word popa x wrword x,y org snippet _wrlong popa y 'write long popa x wrlong x,y org snippet _asbyte popa addr 'assign byte jmpd #assign rdbyte x,addr mov assign_i,:i mov mask,#$FF :i wrbyte x,addr org snippet _asword popa addr 'assign word jmpd #assign rdword x,addr mov assign_i,:i mov mask,:m :i wrword x,addr :m long $0000FFFF org snippet _aslong jmpd #assign_long 'assign long popa addr rdlong x,addr mov assign_i,:i :i wrlong x,addr org snippet _rdbyteb call #bitfield 'read byte bitfield popa x rdbyte x,x jmp #readb org snippet _rdwordb call #bitfield 'read word bitfield popa x rdword x,x jmp #readb org snippet _rdlongb call #bitfield 'read long bitfield popa x rdlong x,x jmp #readb org snippet _wrbyteb call #bitfield 'write byte bitfield jmpd #writeb popa addr rdbyte bval,addr mov writeb_i,:wr :wr wrbyte x,addr org snippet _wrwordb call #bitfield 'write word bitfield jmpd #writeb popa addr rdword bval,addr mov writeb_i,:wr :wr wrword x,addr org snippet _wrlongb call #bitfield 'write long bitfield jmpd #writeb popa addr rdlong bval,addr mov writeb_i,:wr :wr wrlong x,addr org snippet _asbyteb call #bitfield 'assign byte bitfield mov mask,#$FF jmpd #assignb popa addr rdbyte bval,addr mov writeb_i,:wr :wr wrbyte x,addr org snippet _aswordb call #bitfield 'assign word bitfield mov mask,:mask jmpd #assignb popa addr rdword bval,addr mov writeb_i,:wr :wr wrword x,addr :mask long $0000FFFF org snippet _aslongb call #bitfield 'assign long bitfield jmpd #assignb_long popa addr rdlong bval,addr mov writeb_i,:wr :wr wrlong x,addr ' ' ' Memory offsets and indexing ' org snippet _base call #xword if_nc add x,vbase 'vbase, c=0 if_c add x,pbase 'pbase, c=1 pusha x org snippet _index popa y 'ibyte, x=0 shl y,x 'iword, x=1 popa x 'ilong, x=2 add x,y pusha x ' ' ' Branch jmp/jz/jnz/tjz/djnz ' org snippet _jmp call #xword 'jmp addptra x org snippet _jxz popa y wz 'jz, c=1 jnz, c=0 call #xword if_z_eq_c addptra x org snippet _tjz popa y wz 'tjz if_nz pusha y call #xword if_z addptra x org snippet _djnz popa y 'djnz sub y,#1 wz if_nz pusha y call #xword if_nz addptra x ' ' ' Drop anchor ' ' \sub x = %00 ' \sub result x = %01 ' sub x = %10 ' sub result x = %11 ' org snippet _drop pusha dcall 'push dcall (later used for pcurr) getspa dcall 'set new dcall pusha dbase 'push return dbase pusha vbase 'push return vbase or x,pbase 'push return pbase w/flags pusha x pusha #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,ptra++ 'get obj byte if_nz popa a 'add any index if_nz add x,a jmpd #call_obj 'jump to handler, delayed rdbytec y,ptra++ 'get sub byte if_c popa a 'add any index if_c add y,a org snippet _callsub jmpd #call_sub 'jump to handler, delayed rdbytec y,ptra++ 'get sub byte if_c popa a 'add any index if_c add y,a org snippet _callptr popa 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 jmpd #call_ptr 'jump to handler, delayed shr a,#16-3 and a,#%000111 or y,a ' ' ' 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 setspa dbase 'if no value, return result if_z popar x if_nz popa x 'if value, pop it :again setspa dbase 'set dbase popa pbase 'pop pbase if_c test pbase,#%10 wc 'if abort and try, return again if_c jmpd #:again popa vbase 'pop vbase popa dbase 'pop dbase popa y 'pop pcurr setptra y 'set ptra to pcurr test pbase,#%01 wc 'push result? andn pbase,#%11 if_c pusha x ' ' ' Get vbase/pbase ' org snippet _basesub mov y,vbase shl y,#16-4 mov x,pbase shr x,#4 or x,y pusha x ' ' ' Get pbase/vbase of obj ' ' obj c=0 ' obj[] c=1 ' org snippet _baseobj rdbytec x,ptra++ 'get obj byte if_c popa 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 pusha x 'push obj vbase/pbase ' ' ' Make subroutine ptr ' ' base.sub c=0 ' base.sub[] c=1 ' org snippet _subptr rdbytec a,ptra++ 'get sub number if_c popa 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 popa x 'pop base vbase/pbase or x,b 'install index into pbase/vbase or x,a pusha x 'push subroutine pointer ' ' ' Case ' org snippet 'case value _casev call #xword 'get branch address popa a 'pop value popa y 'pop target cmp a,y wz 'value = target? if_nz addspa #1 'if mismatch, unpop target if_z addptra x 'if match, branch org snippet 'case range (z=1) _caser call #xword 'get branch address popa b 'pop range end popa a 'pop range begin popa 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 addspa #1 'if mismatch, unpop target if_nc addptra x 'if match, branch org snippet 'case done _casedone popa x 'pop target popa x 'pop address addptra x 'jump to address ' ' ' Lookup/lookdown ' org snippet 'lookup value _lookupv popa a 'pop value popa x 'pop index popa y 'pop target cmp x,y wz 'match if index = target if_nz addspa #1 'if no match, unpop target if_nz add x,#1 '..increment index if_nz pusha x '..push index if_z popa addr 'if match, pop address if_z pusha a '..push result if_z setptra addr '..branch org snippet 'lookup range _lookupr popa b 'pop range end popa a 'pop range begin popa x 'pop index popa 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 addspa #1 'if no match, unpop target if_c addx x,b '..add ||(end - begin) + 1 to index if_c pusha x '..push index if_nc popa addr 'if match, pop address if_nc pusha a '..push result if_nc setptra addr '..branch org snippet 'lookdown value _lookdnv popa a 'pop value popa x 'pop index popa y 'pop target cmp a,y wz 'match if value = target if_nz addspa #1 'if no match, unpop target if_nz add x,#1 '..increment index if_nz pusha x '..push index if_z popa addr 'if match, pop address if_z pusha x '..push result if_z setptra addr '..branch org snippet 'lookdown range _lookdnr popa b 'pop range end popa a 'pop range begin popa x 'pop index popa 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 addspa #1 'if no match, unpop target if_c addx x,b '..add ||(end - begin) + 1 to index if_c pusha x '..push index if_nc popa addr 'if match, pop address if_nc add x,y '..result = index +/- (target - begin) if_nc pusha x '..push result if_nc setptra addr '..branch org snippet 'lookup/lookdown done _lookdone subspa #3 'pop index/target/address pusha #0 'push 0 result ' ' ' Miscellaneous ' org snippet _pop rdbytec x,ptra++ 'pop subspa x org snippet _clkset popa x 'clkset clkset x org snippet _cogid cogid x 'cogid pusha x org snippet _coginit popa y 'coginit popa x popa a setcog a coginit x,y wc if_nz_and_c pusha #0 if_nz_and_nc pusha hFFFFFFFF org snippet _cogstop popa x 'cogstop cogstop x