array ops 2 allot array optypes 2 allot var currop : op1 ops @ ; : op2 ops 1 + @ ; 0 const OP_NONE 1 const OP_REG8 2 const OP_REG16 3 const OP_SREG 4 const OP_IMM : op! ( op type ) currop @ >r optypes r@ + ! ops r@ + ! 1 r> + currop ! ; : assembled 0 currop ! ; : mkreg makedo , does> @ swap makedo , , does> dup @ swap 1 + @ op! ; OP_REG8 mkreg reg8 OP_REG16 mkreg reg16 OP_SREG mkreg sreg 0 reg16 ax 0 reg8 al 4 reg8 ah 1 reg16 cx 1 reg8 cl 5 reg8 ch 2 reg16 dx 2 reg8 dl 6 reg8 dh 3 reg16 bx 3 reg8 bl 7 reg8 bh 4 reg16 sp 5 reg16 bp 6 reg16 si 7 reg16 di 0 sreg es 1 sreg cs 2 sreg ss 3 sreg ds : # OP_IMM op! ; : read-impl ( p -- next cp optypes ) dup @ swap dup 1 + @ swap 2 + ; : match-impl ( optypes opcount -- b ) begin dup 0 > while 1 - 2dup + @ over optypes + @ != if drop drop 0 ret then repeat drop drop 1 ; : inst ( opcount -- ) makedo , 0 , does> dup @ currop @ != if 0 message yelp ret then 1 + @ begin dup while read-impl currop @ match-impl if execute drop assembled ret else drop then repeat drop 1 message yelp ; : inst-nextimpl do.data 1 + ; : inst-opcount do.data @ ; : impl ( [optype...] cp cpinst -- ) here >r >r ( r: impl inst ) r@ inst-nextimpl @ , , r@ inst-opcount begin dup while 1 - swap , repeat drop r> inst-nextimpl r> swap ! ; : int &hcd outb! outb! assembled ; 2 inst mov 2 inst movb OP_IMM OP_REG16 :noname &hb8 op1 + outb! op2 outw! ; ' mov impl OP_IMM OP_REG8 :noname &hb0 op1 + outb! op2 outb! ; ' movb impl 1 inst push OP_SREG :noname &h06 op1 8 * + outb! ; ' push impl OP_REG16 :noname &h50 op1 + outb! ; ' push impl 1 inst pop OP_SREG :noname &h07 op1 8 * + outb! ; ' pop impl OP_REG16 :noname &h58 op1 + outb! ; ' pop impl