Вам нужно просто вывернуть на изнанку простой эмулятор процессора. Когда-то давным-давно я так и сделал. Не смотрите на реализацию и код - я тогда зеленым был. Просто поймите идею.
Code: Select all
Unit VM80;
{**Эмуляция КР580ВМ80А**
Виртуальный чип}
interface
  uses dos,new_crt;
  procedure vm_step;
  procedure vm_reset;
{Hardware - интерфейс обмена с железом}
{vm_adres -> адрес ввода вывода (память/порт) устанавливает проц.}
{vm_data -> регистр данных; vm_tmpx -> времянка для команды}
{vm_readlen -> количество считанных байт;}
{vm_comlen -> количество байт в команде;}
 var   vm_adres,vm_start:word;
       vm_data,vm_macro,vm_tmpa,vm_tmpb,vm_tmpc:byte;
       vm_read,vm_write,vm_halt,vm_ram,vm_port,vm_machine:boolean;
       vm_stack,vm_inta,vm_intr:boolean;
{Слово состояния проца}
{D0 - Read; D1 - Write; D2 - Mem; D3 - Port;}
{D4 - mach; D5 - stack; D6 - halt; D7 - macro;}
       vm_sync:byte;
{Регистры}
{vm_f - регистр флагов:}
{D0 - 'C'  D1 - 'N'  D2 - 'P' D3 - '0'}
{D4 - 'AC' D5 - '0'  D6 - 'Z' D7 - 'S'}
       vm_b,vm_c,vm_d,vm_e,vm_h,vm_l,vm_m,vm_a,vm_f:byte;
       vm_sp,vm_pc:word;
{Служебные для АЛУ}
       origin,result:word;
       zero,carry,negative,parity,advcarry,sign:byte;
implementation
{vm_f - регистр флагов:}
{D0 - 'C'  D1 - 'N'  D2 - 'P' D3 - '0'}
{D4 - 'AC' D5 - '0'  D6 - 'Z' D7 - 'S'}
{АЛУ процессора}
function vm_alu(act,dest,surc:byte):byte;
procedure vm_setzero;
var    r:word;
var    b_ptr:^byte;
       b_ofs:word;
       b_seg:word;
begin
     new(b_ptr);
     b_seg:=seg(b_ptr);
     b_ofs:=ofs(b_ptr);
       r:=result;
       asm push ds;
           push dx;
           mov  dx,b_seg;
           mov  ds,dx;
           mov  dx,b_ofs;
           mov  di,dx;
           pop  dx;
           mov ax,r;
           xor dl,dl;
           cmp al,0;
           jnz @zero;
           mov dl,1;
     @zero:mov [ds:di],dl;
           pop ds;
       end;
       zero:=b_ptr^;
       dispose(b_ptr);
end;
procedure vm_setparity;
begin
       parity:=(result and 1) xor 1;
end;
procedure vm_setoverflow;
begin
       if (origin and $FF00)=(result and $FF00) then parity:=0
                                                else parity:=1;
end;
procedure vm_setcarry;
begin
       if (origin and $FF00)=(result and $FF00) then carry:=0
                                                else carry:=1;
end;
procedure vm_setsign;
begin
       if (dest xor $80)<(surc xor $80) then sign:=1
                                        else sign:=0;
end;
procedure vm_sethalf(a,b,c:byte);
begin
       case negative of
       0 : if ((a and $0F)+(b and $0F)+c)>9 then advcarry:=1
                                            else advcarry:=0;
       1 : if (a and $0F)<((b and $0F)+c) then advcarry:=1
                                          else advcarry:=0;
       end;
end;
{======}
begin
       carry:=vm_f and $01; parity:=(vm_f and $04) shr 2;
       advcarry:=(vm_f and $10) shr 4; zero:=(vm_f and $40) shr 6;
       sign:=(vm_f and $80) shr 7; negative:=(vm_f and $2) shr 1;
       origin:=$8000;
       case act of
{ADD}  00 : begin result:=origin+dest+surc; end;
{ADC}  01 : begin result:=origin+dest+surc+carry; end;
{SUB}  02 : begin result:=origin+dest-surc; end;
{SBC}  03 : begin result:=origin+dest-surc-carry; end;
{AND}  04 : begin result:=dest and surc; end;
{OR}   06 : begin result:=dest or surc; end;
{XOR}  05 : begin result:=dest xor surc; end;
{CPI}  07 : begin result:=origin+dest-surc; end;
{RLC}  08 : begin asm mov al,dest; rol al,1; mov dest,al; end; result:=dest; end;
{RRC}  09 : begin asm mov al,dest; ror al,1; mov dest,al; end; result:=dest; end;
{RAL}  10 : begin asm mov al,dest; mov ah,carry; rol ah,7; rol ax,1;
                      mov dest,al; mov carry,ah; end; carry:=carry and 1; result:=dest; end;
{RAR}  11 : begin asm mov al,dest; mov ah,carry; ror ax,1; mov dest,al;
                      ror ah,7; mov carry,ah; end; carry:=carry and 1; result:=dest; end;
{DAA}  12 : begin if advcarry=0 then result:=dest
                                else case negative of
                                     0 : if advcarry<>0 then result:=dest+6;
                                     1 : if advcarry<>0 then result:=dest-6;
                                     end;
            end;
{CMA}  13 : begin asm mov al,dest; xor al,$FF; mov dest,al; end; result:=dest; end;
       end;
{Установка флажков по маске}
{00-обнулить, 01-установить, 10-подсчитать, 11-нетрогать.}
       case act of
{ADD}  00 : begin vm_setzero; vm_setoverflow; vm_setcarry; vm_setsign;
                  negative:=0; vm_sethalf(dest,surc,0); end;
{ADC}  01 : begin vm_setzero; vm_setoverflow; vm_setcarry; vm_setsign;
                  negative:=0; vm_sethalf(dest,surc,carry); end;
{SUB}  02 : begin vm_setzero; vm_setoverflow; vm_setcarry; vm_setsign;
                  negative:=1; vm_sethalf(dest,surc,0); end;
{SBC}  03 : begin vm_setzero; vm_setoverflow; vm_setcarry; vm_setsign;
                  negative:=1; vm_sethalf(dest,surc,carry); end;
{AND}  04 : begin vm_setzero; vm_setparity; carry:=0; vm_setsign;
                  negative:=0; advcarry:=1; end;
{OR}   06 : begin vm_setzero; vm_setparity; carry:=0; vm_setsign;
                  negative:=0; advcarry:=0; end;
{XOR}  05 : begin vm_setzero; vm_setparity; carry:=0; vm_setsign;
                  negative:=0; advcarry:=0; end;
{CPI}  07 : begin vm_setzero; vm_setoverflow; vm_setcarry; vm_setsign;
                  negative:=1; vm_sethalf(dest,surc,0); result:=dest; end;
{RLC}  08 : begin carry:=0; if (dest and $80)<>0 then carry:=1; end;
{RRC}  09 : begin carry:=0; if (dest and $80)<>0 then carry:=1; end;
       end;
       vm_alu:=result and $00FF;
       carry:=carry and $01; parity:=(parity and $01) shl 2;
       advcarry:=(advcarry and $01) shl 4; zero:=(zero and $01) shl 6;
       sign:=(sign and $01) shl 7; negative:=(negative and 1) shl 1; vm_f:=$00;
       vm_f:=carry or parity or advcarry or zero or sign or negative;
end;
{Оптимизация}
{Взять первый байт из стека}
procedure vm_popfirst;
begin
       vm_sp:=vm_sp+1; vm_adres:=vm_sp; vm_sync:=$25;
end;
{Взять второй байт из стека}
procedure vm_popsecond;
begin
       vm_sp:=vm_sp+1; vm_tmpb:=vm_data; vm_adres:=vm_sp; vm_sync:=$25;
end;
{Коррекция указателя на стек}
procedure vm_popthird;
begin
       vm_tmpc:=vm_data;
end;
{Прыжок}
procedure vm_jump;
begin
       vm_pc:=vm_tmpc*256+vm_tmpb; vm_sync:=$95;
end;
{Завершение RET}
procedure vm_return;
begin
       vm_tmpc:=vm_data; vm_jump;
end;
{Занесение в стек первого байта}
procedure vm_pushlow;
begin  vm_adres:=vm_sp; vm_sp:=vm_sp-1; vm_data:=hi(vm_pc);
       vm_sync:=$26;
end;
{Занесение в стек второго байта}
procedure vm_pushhigh;
begin
       vm_data:=lo(vm_pc); vm_adres:=vm_sp; vm_sp:=vm_sp-1;
       vm_sync:=$26;
end;
{=============================>>>Циклы<<<================================}
{Сброс аппаратуры}
procedure vm_reset;
begin
       vm_inta:=false; vm_intr:=false; vm_f:=$00; vm_pc:=vm_start;
       vm_b:=0; vm_c:=0; vm_d:=0; vm_e:=0; vm_h:=0; vm_l:=0; vm_a:=0;
       vm_sp:=$FFFF; vm_sync:=$15; vm_adres:=vm_pc;
       vm_read:=boolean(vm_sync and 1);
       vm_write:=boolean((vm_sync shr 1) and 1);
       vm_ram:=boolean((vm_sync shr 2) and 1);
       vm_port:=boolean((vm_sync shr 3) and 1);
       vm_machine:=boolean((vm_sync shr 4) and 1);
       vm_stack:=boolean((vm_sync shr 5) and 1);
       vm_halt:=boolean((vm_sync shr 6) and 1);
       vm_macro:=1;
end;
{Запрос на прерывание}
procedure vm_intreq;
begin
       vm_halt:=false;
end;
{1 шаг (примерно 4 такта)}
procedure vm_step;
begin
       if (vm_halt=false) then begin
          if vm_machine=true then begin
             vm_pc:=vm_pc+1;
{Реакция на команду}
             case vm_macro of
             1 : begin if vm_machine then vm_tmpa:=vm_data;
                 case vm_tmpa of
{NOP}            $00 : vm_sync:=$95;
{LXI B,}         $01 : vm_sync:=$15;
{STAX B}         $02 : begin vm_adres:=vm_b*256+vm_c; vm_data:=vm_a; vm_sync:=$06; end;
{INX B}          $03 : begin asm mov al,vm_c; mov ah,vm_b; add ax,1;
                                 mov vm_c,al; mov vm_b,ah; end; vm_sync:=$95; end;
{INR B}          $04 : begin vm_b:=vm_alu(0,vm_b,1); vm_sync:=$95; end;
{DCR B}          $05 : begin vm_b:=vm_alu(2,vm_b,1); vm_sync:=$95; end;
{MVI B,}         $06 : vm_sync:=$15;
{RLC A}          $07 : begin vm_a:=vm_alu(8,vm_a,vm_a); vm_sync:=$95; end;
{----}           $08 : vm_sync:=$95;
{DAD B}          $09 : begin asm mov al,vm_l; mov ah,vm_h; mov bl,vm_c; mov bh,vm_b;
                                 add ax,bx; mov vm_l,al; mov vm_h,ah; end; vm_sync:=$95; end;
{LDAX B}         $0A : begin vm_adres:=vm_b*256+vm_c; vm_sync:=$05; end;
{DCX B}          $0B : begin asm mov al,vm_c; mov ah,vm_b; sub ax,1;
                                 mov vm_c,al; mov vm_b,ah; end; vm_sync:=$95; end;
{INR C}          $0C : begin vm_c:=vm_alu(0,vm_c,1); vm_sync:=$95; end;
{DCR C}          $0D : begin vm_c:=vm_alu(2,vm_c,1); vm_sync:=$95; end;
{MVI C,}         $0E : vm_sync:=$15;
{RRC A}          $0F : begin vm_a:=vm_alu(9,vm_a,vm_a); vm_sync:=$95; end;
{----}           $10 : vm_sync:=$95;
{LXI D,}         $11 : vm_sync:=$15;
{STAX D}         $12 : begin vm_adres:=vm_d*256+vm_e; vm_data:=vm_a;
                             vm_sync:=$06; end;
{INX D}          $13 : begin asm mov al,vm_e; mov ah,vm_d; add ax,1;
                                 mov vm_e,al; mov vm_d,ah; end; vm_sync:=$95; end;
{INR D}          $14 : begin vm_d:=vm_alu(0,vm_d,1); vm_sync:=$95; end;
{DCR D}          $15 : begin vm_d:=vm_alu(2,vm_d,1); vm_sync:=$95; end;
{MVI D,}         $16 : vm_sync:=$15;
{RAL A}          $17 : begin vm_a:=vm_alu(10,vm_a,vm_a); vm_sync:=$95; end;
{----}           $18 : vm_sync:=$95;
{DAD D}          $19 : begin asm mov al,vm_l; mov ah,vm_h; mov bl,vm_e; mov bh,vm_d;
                                 add ax,bx; mov vm_l,al; mov vm_h,ah; end; vm_sync:=$95; end;
{LDAX D}         $1A : begin vm_adres:=vm_d*256+vm_e; vm_sync:=$05; end;
{DCX D}          $1B : begin asm mov al,vm_e; mov ah,vm_d; sub ax,1;
                                 mov vm_e,al; mov vm_d,ah; end; vm_sync:=$95; end;
{INR E}          $1C : begin vm_e:=vm_alu(0,vm_e,1); vm_sync:=$95; end;
{DCR E}          $1D : begin vm_e:=vm_alu(2,vm_e,1); vm_sync:=$95; end;
{MVI E,}         $1E : vm_sync:=$15;
{RAR A}          $1F : begin vm_a:=vm_alu(11,vm_a,vm_a); vm_sync:=$95; end;
{----}           $20 : vm_sync:=$95;
{LXI H,}         $21 : vm_sync:=$15;
{SHLD }          $22 : vm_sync:=$15;
{INX H}          $23 : begin asm mov al,vm_l; mov ah,vm_h; add ax,1;
                                 mov vm_l,al; mov vm_h,ah; end; vm_sync:=$95; end;
{INR H}          $24 : begin vm_h:=vm_alu(0,vm_h,1); vm_sync:=$95; end;
{DCR H}          $25 : begin vm_h:=vm_alu(2,vm_h,1); vm_sync:=$95; end;
{MVI H,}         $26 : vm_sync:=$15;
{DAA}            $27 : begin vm_a:=vm_alu(12,vm_a,vm_a); vm_sync:=$95; end;
{----}           $28 : vm_sync:=$95;
{DAD H}          $29 : begin asm mov al,vm_l; mov ah,vm_h; add ax,ax;
                                 mov vm_l,al; mov vm_h,ah; end; vm_sync:=$95; end;
{LHLD }          $2A : vm_sync:=$15;
{DCX H}          $2B : begin asm mov al,vm_l; mov ah,vm_h; sub ax,1;
                                 mov vm_l,al; mov vm_h,ah; end; vm_sync:=$95; end;
{INR L}          $2C : begin vm_l:=vm_alu(0,vm_l,1); vm_sync:=$95; end;
{DCR L}          $2D : begin vm_l:=vm_alu(2,vm_l,1); vm_sync:=$95; end;
{MVI L,}         $2E : vm_sync:=$15;
{CMA}            $2F : begin vm_a:=vm_alu(13,vm_a,vm_a); vm_sync:=$95; end;
{----}           $30 : vm_sync:=$95;
{LXI SP,}        $31 : vm_sync:=$15;
{STA }           $32 : vm_sync:=$15;
{INX SP}         $33 : begin asm mov ax,vm_sp; add ax,1; mov vm_sp,ax; end; vm_sync:=$95; end;
{INR M}          $34 : begin vm_adres:=vm_h*256+vm_l; vm_sync:=$05; end;
{DCR M}          $35 : begin vm_adres:=vm_h*256+vm_l; vm_sync:=$05; end;
{MVI M,}         $36 : vm_sync:=$15;
{STC}            $37 : begin vm_f:=vm_f or 1; vm_sync:=$95; end;
{----}           $38 : vm_sync:=$95;
{DAD SP}         $39 : begin asm mov al,vm_l; mov ah,vm_h; mov bx,vm_sp;
                                 add ax,bx; mov vm_l,al; mov vm_h,ah; end; vm_sync:=$95; end;
{LDA }           $3A : vm_sync:=$15;
{DCX SP}         $3B : begin asm mov ax,vm_sp; sub ax,1; mov vm_sp,ax; end; vm_sync:=$95; end;
{INR A}          $3C : begin vm_a:=vm_alu(0,vm_a,1); vm_sync:=$95; end;
{DCR A}          $3D : begin vm_a:=vm_alu(2,vm_a,1); vm_sync:=$95; end;
{MVI A,}         $3E : vm_sync:=$15;
{CMC}            $3F : begin vm_f:=vm_f xor 1; vm_sync:=$95; end;
{MOV B,B}        $40 : begin vm_b:=vm_b; vm_sync:=$95; end;
{MOV B,C}        $41 : begin vm_b:=vm_c; vm_sync:=$95; end;
{MOV B,D}        $42 : begin vm_b:=vm_d; vm_sync:=$95; end;
{MOV B,E}        $43 : begin vm_b:=vm_e; vm_sync:=$95; end;
{MOV B,H}        $44 : begin vm_b:=vm_h; vm_sync:=$95; end;
{MOV B,L}        $45 : begin vm_b:=vm_l; vm_sync:=$95; end;
{MOV A,M}        $46 : begin vm_adres:=vm_h*256+vm_l; vm_sync:=$05; end;
{MOV B,A}        $47 : begin vm_b:=vm_a; vm_sync:=$95; end;
{MOV C,B}        $48 : begin vm_c:=vm_b; vm_sync:=$95; end;
{MOV C,C}        $49 : begin vm_c:=vm_c; vm_sync:=$95; end;
{MOV C,D}        $4A : begin vm_c:=vm_d; vm_sync:=$95; end;
{MOV C,E}        $4B : begin vm_c:=vm_e; vm_sync:=$95; end;
{MOV C,H}        $4C : begin vm_c:=vm_h; vm_sync:=$95; end;
{MOV C,L}        $4D : begin vm_c:=vm_l; vm_sync:=$95; end;
{MOV C,M}        $4E : begin vm_adres:=vm_h*256+vm_l; vm_sync:=$05; end;
{MOV C,A}        $4F : begin vm_c:=vm_a; vm_sync:=$95; end;
{MOV D,B}        $50 : begin vm_d:=vm_b; vm_sync:=$95; end;
{MOV D,C}        $51 : begin vm_d:=vm_c; vm_sync:=$95; end;
{MOV D,D}        $52 : begin vm_d:=vm_d; vm_sync:=$95; end;
{MOV D,E}        $53 : begin vm_d:=vm_e; vm_sync:=$95; end;
{MOV D,H}        $54 : begin vm_d:=vm_h; vm_sync:=$95; end;
{MOV D,L}        $55 : begin vm_d:=vm_l; vm_sync:=$95; end;
{MOV D,M}        $56 : begin vm_adres:=vm_h*256+vm_l; vm_sync:=$05; end;
{MOV D,A}        $57 : begin vm_d:=vm_a; vm_sync:=$95; end;
{MOV E,B}        $58 : begin vm_e:=vm_b; vm_sync:=$95; end;
{MOV E,C}        $59 : begin vm_e:=vm_c; vm_sync:=$95; end;
{MOV E,D}        $5A : begin vm_e:=vm_d; vm_sync:=$95; end;
{MOV E,E}        $5B : begin vm_e:=vm_e; vm_sync:=$95; end;
{MOV E,H}        $5C : begin vm_e:=vm_h; vm_sync:=$95; end;
{MOV E,L}        $5D : begin vm_e:=vm_l; vm_sync:=$95; end;
{MOV E,M}        $5E : begin vm_adres:=vm_h*256+vm_l; vm_sync:=$05; end;
{MOV E,A}        $5F : begin vm_e:=vm_a; vm_sync:=$95; end;
{MOV H,B}        $60 : begin vm_h:=vm_b; vm_sync:=$95; end;
{MOV H,C}        $61 : begin vm_h:=vm_c; vm_sync:=$95; end;
{MOV H,D}        $62 : begin vm_h:=vm_d; vm_sync:=$95; end;
{MOV H,E}        $63 : begin vm_h:=vm_e; vm_sync:=$95; end;
{MOV H,H}        $64 : begin vm_h:=vm_h; vm_sync:=$95; end;
{MOV H,L}        $65 : begin vm_h:=vm_l; vm_sync:=$95; end;
{MOV H,M}        $66 : begin vm_adres:=vm_h*256+vm_l; vm_sync:=$05; end;
{MOV H,A}        $67 : begin vm_h:=vm_a; vm_sync:=$95; end;
{MOV L,B}        $68 : begin vm_l:=vm_b; vm_sync:=$95; end;
{MOV L,C}        $69 : begin vm_l:=vm_c; vm_sync:=$95; end;
{MOV L,D}        $6A : begin vm_l:=vm_d; vm_sync:=$95; end;
{MOV L,E}        $6B : begin vm_l:=vm_e; vm_sync:=$95; end;
{MOV L,H}        $6C : begin vm_l:=vm_h; vm_sync:=$95; end;
{MOV L,L}        $6D : begin vm_l:=vm_l; vm_sync:=$95; end;
{MOV L,M}        $6E : begin vm_adres:=vm_h*256+vm_l; vm_sync:=$05; end;
{MOV L,A}        $6F : begin vm_l:=vm_a; vm_sync:=$95; end;
{MOV M,B}        $70 : begin vm_adres:=vm_h*256+vm_l; vm_data:=vm_b;
                             vm_m:=vm_b; vm_sync:=$06; end;
{MOV M,C}        $71 : begin vm_adres:=vm_h*256+vm_l; vm_data:=vm_c;
                             vm_m:=vm_c; vm_sync:=$06; end;
{MOV M,D}        $72 : begin vm_adres:=vm_h*256+vm_l; vm_data:=vm_d;
                             vm_m:=vm_d; vm_sync:=$06; end;
{MOV M,E}        $73 : begin vm_adres:=vm_h*256+vm_l; vm_data:=vm_e;
                             vm_m:=vm_e; vm_sync:=$06; end;
{MOV M,H}        $74 : begin vm_adres:=vm_h*256+vm_l; vm_data:=vm_h;
                             vm_m:=vm_h; vm_sync:=$06; end;
{MOV M,L}        $75 : begin vm_adres:=vm_h*256+vm_l; vm_data:=vm_l;
                             vm_m:=vm_l; vm_sync:=$06; end;
{HALT}           $76 : begin vm_sync:=$40; end;
{MOV M,A}        $77 : begin vm_adres:=vm_h*256+vm_l; vm_data:=vm_a;
                             vm_m:=vm_a; vm_sync:=$06; end;
{MOV A,B}        $78 : begin vm_a:=vm_b; vm_sync:=$95; end;
{MOV A,C}        $79 : begin vm_a:=vm_c; vm_sync:=$95; end;
{MOV A,D}        $7A : begin vm_a:=vm_d; vm_sync:=$95; end;
{MOV A,E}        $7B : begin vm_a:=vm_e; vm_sync:=$95; end;
{MOV A,H}        $7C : begin vm_a:=vm_h; vm_sync:=$95; end;
{MOV A,L}        $7D : begin vm_a:=vm_l; vm_sync:=$95; end;
{MOV A,M}        $7E : begin vm_adres:=vm_h*256+vm_l; vm_sync:=$05; end;
{MOV A,A}        $7F : begin vm_a:=vm_a; vm_sync:=$95; end;
{ADD B}          $80 : begin vm_a:=vm_alu(0,vm_a,vm_b); vm_sync:=$95; end;
{ADD C}          $81 : begin vm_a:=vm_alu(0,vm_a,vm_c); vm_sync:=$95; end;
{ADD D}          $82 : begin vm_a:=vm_alu(0,vm_a,vm_d); vm_sync:=$95; end;
{ADD E}          $83 : begin vm_a:=vm_alu(0,vm_a,vm_e); vm_sync:=$95; end;
{ADD H}          $84 : begin vm_a:=vm_alu(0,vm_a,vm_h); vm_sync:=$95; end;
{ADD L}          $85 : begin vm_a:=vm_alu(0,vm_a,vm_l); vm_sync:=$95; end;
{ADD M}          $86 : begin vm_adres:=vm_h*256+vm_l; vm_sync:=$05; end;
{ADD A}          $87 : begin vm_a:=vm_alu(0,vm_a,vm_a); vm_sync:=$95; end;
{ADC B}          $88 : begin vm_a:=vm_alu(1,vm_a,vm_b); vm_sync:=$95; end;
{ADC C}          $89 : begin vm_a:=vm_alu(1,vm_a,vm_c); vm_sync:=$95; end;
{ADC D}          $8A : begin vm_a:=vm_alu(1,vm_a,vm_d); vm_sync:=$95; end;
{ADC E}          $8B : begin vm_a:=vm_alu(1,vm_a,vm_e); vm_sync:=$95; end;
{ADC H}          $8C : begin vm_a:=vm_alu(1,vm_a,vm_h); vm_sync:=$95; end;
{ADC L}          $8D : begin vm_a:=vm_alu(1,vm_a,vm_l); vm_sync:=$95; end;
{ADC M}          $8E : begin vm_adres:=vm_h*256+vm_l; vm_sync:=$05; end;
{ADC A}          $8F : begin vm_a:=vm_alu(1,vm_a,vm_a); vm_sync:=$95; end;
{SUB B}          $90 : begin vm_a:=vm_alu(2,vm_a,vm_b); vm_sync:=$95; end;
{SUB C}          $91 : begin vm_a:=vm_alu(2,vm_a,vm_c); vm_sync:=$95; end;
{SUB D}          $92 : begin vm_a:=vm_alu(2,vm_a,vm_d); vm_sync:=$95; end;
{SUB E}          $93 : begin vm_a:=vm_alu(2,vm_a,vm_e); vm_sync:=$95; end;
{SUB H}          $94 : begin vm_a:=vm_alu(2,vm_a,vm_h); vm_sync:=$95; end;
{SUB L}          $95 : begin vm_a:=vm_alu(2,vm_a,vm_l); vm_sync:=$95; end;
{SUB M}          $96 : begin vm_adres:=vm_h*256+vm_l; vm_sync:=$05; end;
{SUB A}          $97 : begin vm_a:=vm_alu(2,vm_a,vm_a); vm_sync:=$95; end;
{SBB B}          $98 : begin vm_a:=vm_alu(3,vm_a,vm_b); vm_sync:=$95; end;
{SBB C}          $99 : begin vm_a:=vm_alu(3,vm_a,vm_c); vm_sync:=$95; end;
{SBB D}          $9A : begin vm_a:=vm_alu(3,vm_a,vm_d); vm_sync:=$95; end;
{SBB E}          $9B : begin vm_a:=vm_alu(3,vm_a,vm_e); vm_sync:=$95; end;
{SBB H}          $9C : begin vm_a:=vm_alu(3,vm_a,vm_h); vm_sync:=$95; end;
{SBB L}          $9D : begin vm_a:=vm_alu(3,vm_a,vm_l); vm_sync:=$95; end;
{SBB M}          $9E : begin vm_adres:=vm_h*256+vm_l; vm_sync:=$05; end;
{SBB A}          $9F : begin vm_a:=vm_alu(3,vm_a,vm_a); vm_sync:=$95; end;
{ANA B}          $A0 : begin vm_a:=vm_alu(4,vm_a,vm_b); vm_sync:=$95; end;
{ANA C}          $A1 : begin vm_a:=vm_alu(4,vm_a,vm_c); vm_sync:=$95; end;
{ANA D}          $A2 : begin vm_a:=vm_alu(4,vm_a,vm_d); vm_sync:=$95; end;
{ANA E}          $A3 : begin vm_a:=vm_alu(4,vm_a,vm_e); vm_sync:=$95; end;
{ANA H}          $A4 : begin vm_a:=vm_alu(4,vm_a,vm_h); vm_sync:=$95; end;
{ANA L}          $A5 : begin vm_a:=vm_alu(4,vm_a,vm_l); vm_sync:=$95; end;
{ANA M}          $A6 : begin vm_adres:=vm_h*256+vm_l; vm_sync:=$05; end;
{ANA A}          $A7 : begin vm_a:=vm_alu(4,vm_a,vm_a); vm_sync:=$95; end;
{XRA B}          $A8 : begin vm_a:=vm_alu(5,vm_a,vm_b); vm_sync:=$95; end;
{XRA C}          $A9 : begin vm_a:=vm_alu(5,vm_a,vm_c); vm_sync:=$95; end;
{XRA D}          $AA : begin vm_a:=vm_alu(5,vm_a,vm_d); vm_sync:=$95; end;
{XRA E}          $AB : begin vm_a:=vm_alu(5,vm_a,vm_e); vm_sync:=$95; end;
{XRA H}          $AC : begin vm_a:=vm_alu(5,vm_a,vm_h); vm_sync:=$95; end;
{XRA L}          $AD : begin vm_a:=vm_alu(5,vm_a,vm_l); vm_sync:=$95; end;
{XRA M}          $AE : begin vm_adres:=vm_h*256+vm_l; vm_sync:=$05; end;
{XRA A}          $AF : begin vm_a:=vm_alu(5,vm_a,vm_a); vm_sync:=$95; end;
{ORA B}          $B0 : begin vm_a:=vm_alu(6,vm_a,vm_b); vm_sync:=$95; end;
{ORA C}          $B1 : begin vm_a:=vm_alu(6,vm_a,vm_c); vm_sync:=$95; end;
{ORA D}          $B2 : begin vm_a:=vm_alu(6,vm_a,vm_d); vm_sync:=$95; end;
{ORA E}          $B3 : begin vm_a:=vm_alu(6,vm_a,vm_e); vm_sync:=$95; end;
{ORA H}          $B4 : begin vm_a:=vm_alu(6,vm_a,vm_h); vm_sync:=$95; end;
{ORA L}          $B5 : begin vm_a:=vm_alu(6,vm_a,vm_l); vm_sync:=$95; end;
{ORA M}          $B6 : begin vm_adres:=vm_h*256+vm_l; vm_sync:=$05; end;
{ORA A}          $B7 : begin vm_a:=vm_alu(6,vm_a,vm_a); vm_sync:=$95; end;
{CMP B}          $B8 : begin vm_a:=vm_alu(7,vm_a,vm_b); vm_sync:=$95; end;
{CMP C}          $B9 : begin vm_a:=vm_alu(7,vm_a,vm_c); vm_sync:=$95; end;
{CMP D}          $BA : begin vm_a:=vm_alu(7,vm_a,vm_d); vm_sync:=$95; end;
{CMP E}          $BB : begin vm_a:=vm_alu(7,vm_a,vm_e); vm_sync:=$95; end;
{CMP H}          $BC : begin vm_a:=vm_alu(7,vm_a,vm_h); vm_sync:=$95; end;
{CMP L}          $BD : begin vm_a:=vm_alu(7,vm_a,vm_l); vm_sync:=$95; end;
{CMP M}          $BE : begin vm_adres:=vm_h*256+vm_l; vm_sync:=$05; end;
{CMP A}          $BF : begin vm_a:=vm_alu(7,vm_a,vm_a); vm_sync:=$95; end;
{RNZ }           $C0 : if (vm_f and $40)=$40 then vm_sync:=$95
                                             else vm_popfirst;
{POP B}          $C1 : vm_popfirst;
{JNZ }           $C2 : vm_sync:=$15;
{JMP }           $C3 : vm_sync:=$15;
{CNZ }           $C4 : vm_sync:=$15;
{PUSH B}         $C5 : begin vm_adres:=vm_sp; vm_data:=vm_b;
                       vm_sync:=$26; end;
{ADI }           $C6 : vm_sync:=$15;
{RST 0}          $C7 : begin vm_tmpc:=0; vm_tmpb:=0; vm_pushlow; end;
{RZ }            $C8 : if (vm_f and $40)=$00 then vm_sync:=$95
                                             else vm_popfirst;
{RET }           $C9 : vm_popfirst;
{JZ }            $CA : vm_sync:=$15;
{---}            $CB : begin vm_sync:=$95; end;
{CZ }            $CC : vm_sync:=$15;
{CALL }          $CD : vm_sync:=$15;
{ACI }           $CE : vm_sync:=$15;
{RST 1}          $CF : begin vm_tmpc:=0; vm_tmpb:=8; vm_pushlow; end;
{RNC }           $D0 : if (vm_f and $01)=$01 then vm_sync:=$95
                                             else vm_popfirst;
{POP D}          $D1 : vm_popfirst;
{JNC }           $D2 : vm_sync:=$15;
{OUT }           $D3 : vm_sync:=$15;
{CNC }           $D4 : vm_sync:=$15;
{PUSH D}         $D5 : begin vm_adres:=vm_sp; vm_data:=vm_d;
                       vm_sync:=$26; end;
{SUI }           $D6 : vm_sync:=$15;
{RST 2}          $D7 : begin vm_tmpc:=0; vm_tmpb:=16; vm_pushlow; end;
{RC }            $D8 : if (vm_f and $01)=$00 then vm_sync:=$95
                                             else vm_popfirst;
{---}            $D9 : begin vm_sync:=$95; end;
{JC }            $DA : vm_sync:=$15;
{IN }            $DB : vm_sync:=$15;
{CC }            $DC : vm_sync:=$15;
{---}            $DD : begin vm_sync:=$95; end;
{SBI }           $DE : vm_sync:=$15;
{RST 3}          $DF : begin vm_tmpc:=0; vm_tmpb:=24; vm_pushlow; end;
{RPO }           $E0 : if (vm_f and $04)=$01 then vm_sync:=$95
                                             else vm_popfirst;
{POP H}          $E1 : vm_popfirst;
{JPO }           $E2 : vm_sync:=$15;
{XTHL }          $E3 : begin vm_adres:=vm_sp+1; vm_sync:=$25; end;
{CPO }           $E4 : vm_sync:=$15;
{PUSH H}         $E5 : begin vm_adres:=vm_sp; vm_data:=vm_h;
                       vm_sync:=$26; end;
{ANI }           $E6 : vm_sync:=$15;
{RST 4}          $E7 : begin vm_tmpc:=0; vm_tmpb:=32; vm_pushlow; end;
{RPE }           $E8 : if (vm_f and $04)=$00 then vm_sync:=$95
                                             else vm_popfirst;
{PCHL }          $E9 : begin vm_tmpb:=vm_l; vm_tmpc:=vm_h; vm_jump; end;
{JPE }           $EA : vm_sync:=$15;
{XCHG }          $EB : begin vm_tmpb:=vm_l; vm_tmpc:=vm_h; vm_l:=vm_e;
                             vm_h:=vm_d; vm_e:=vm_tmpb; vm_d:=vm_tmpc;
                             vm_sync:=$95; end;
{CPE }           $EC : vm_sync:=$15;
{---}            $ED : begin vm_sync:=$95; end;
{XRI }           $EE : vm_sync:=$15;
{RST 5}          $EF : begin vm_tmpc:=0; vm_tmpb:=40; vm_pushlow; end;
{RP }            $F0 : if (vm_f and $80)=$80 then vm_sync:=$95
                                             else vm_popfirst;
{POP PSW}        $F1 : vm_popfirst;
{JP }            $F2 : vm_sync:=$15;
{DI }            $F3 : begin vm_inta:=false; vm_sync:=$95; end;
{CP }            $F4 : vm_sync:=$15;
{PUSH PSW}       $F5 : begin vm_adres:=vm_sp; vm_data:=vm_f;
                       vm_sync:=$26; end;
{ORI }           $F6 : vm_sync:=$15;
{RST 6}          $F7 : begin vm_tmpc:=0; vm_tmpb:=48; vm_pushlow; end;
{RM }            $F8 : if (vm_f and $80)=$00 then vm_sync:=$95
                                             else vm_popfirst;
{SPHL }          $F9 : begin vm_sp:=vm_h*256+vm_l; vm_sync:=$95; end;
{JM }            $FA : vm_sync:=$15;
{EI }            $FB : begin vm_inta:=true; vm_sync:=$95; end;
{CM }            $FC : vm_sync:=$15;
{---}            $FD : begin vm_sync:=$95; end;
{CPI }           $FE : vm_sync:=$15;
{RST 7}          $FF : begin vm_tmpc:=0; vm_tmpb:=56; vm_pushlow; end;
                 end;
                 end;
             2 : begin if vm_machine then vm_tmpb:=vm_data;
                 case vm_tmpa of
{LXI B,}         $01 : vm_sync:=$15;
{MVI B,}         $06 : begin vm_b:=vm_tmpb; vm_sync:=$95; end;
{MVI C,}         $0E : begin vm_c:=vm_tmpb; vm_sync:=$95; end;
{LXI D,}         $11 : vm_sync:=$15;
{MVI D,}         $16 : begin vm_d:=vm_tmpb; vm_sync:=$95; end;
{MVI E,}         $1E : begin vm_e:=vm_tmpb; vm_sync:=$95; end;
{LXI H,}         $21 : vm_sync:=$15;
{SHLD }          $22 : vm_sync:=$15;
{MVI H,}         $26 : begin vm_h:=vm_tmpb; vm_sync:=$95; end;
{LHLD }          $2A : vm_sync:=$15;
{MVI L,}         $2E : begin vm_l:=vm_tmpb; vm_sync:=$95; end;
{LXI SP,}        $31 : vm_sync:=$15;
{STA }           $32 : vm_sync:=$15;
{MVI M,}         $36 : begin vm_adres:=vm_h*256+vm_l; vm_m:=vm_tmpb;
                             vm_data:=vm_m; vm_sync:=$06; end;
{LDA }           $3A : vm_sync:=$15;
{MVI A,}         $3E : begin vm_a:=vm_tmpb; vm_sync:=$95; end;
{JNZ }           $C2 : vm_sync:=$15;
{JMP }           $C3 : vm_sync:=$15;
{CNZ }           $C4 : vm_sync:=$15;
{ADI }           $C6 : begin vm_a:=vm_alu(0,vm_a,vm_tmpb); vm_sync:=$95; end;
{JZ }            $CA : vm_sync:=$15;
{CZ }            $CC : vm_sync:=$15;
{CALL }          $CD : vm_sync:=$15;
{ACI }           $CE : begin vm_a:=vm_alu(1,vm_a,vm_tmpb); vm_sync:=$95; end;
{JNC }           $D2 : vm_sync:=$15;
{OUT }           $D3 : begin vm_adres:=vm_tmpb*256+vm_tmpb; vm_data:=vm_a; vm_sync:=$0A; end;
{CNC }           $D4 : vm_sync:=$15;
{SUI }           $D6 : begin vm_a:=vm_alu(2,vm_a,vm_tmpb); vm_sync:=$95; end;
{JC }            $DA : vm_sync:=$15;
{IN }            $DB : begin vm_adres:=vm_tmpb*256+vm_tmpb; vm_sync:=$09; end;
{CC }            $DC : vm_sync:=$15;
{SBI }           $DE : begin vm_a:=vm_alu(3,vm_a,vm_tmpb); vm_sync:=$95; end;
{JPO }           $E2 : vm_sync:=$15;
{CPO }           $E4 : vm_sync:=$15;
{ANI }           $E6 : begin vm_a:=vm_alu(4,vm_a,vm_tmpb); vm_sync:=$95; end;
{JPE }           $EA : vm_sync:=$15;
{CPE }           $EC : vm_sync:=$15;
{XRI }           $EE : begin vm_a:=vm_alu(5,vm_a,vm_tmpb); vm_sync:=$95; end;
{JP }            $F2 : vm_sync:=$15;
{CP }            $F4 : vm_sync:=$15;
{ORI }           $F6 : begin vm_a:=vm_alu(6,vm_a,vm_tmpb); vm_sync:=$95; end;
{JM }            $FA : vm_sync:=$15;
{CM }            $FC : vm_sync:=$15;
{CPI }           $FE : begin vm_a:=vm_alu(7,vm_a,vm_tmpb); vm_sync:=$95; end;
                 end;
                 end;
             3 : begin if vm_machine then vm_tmpc:=vm_data;
                 case vm_tmpa of
{LXI B,}         $01 : begin vm_b:=vm_tmpc; vm_c:=vm_tmpb; vm_sync:=$95; end;
{LXI D,}         $11 : begin vm_d:=vm_tmpc; vm_e:=vm_tmpb; vm_sync:=$95; end;
{LXI H,}         $21 : begin vm_h:=vm_tmpc; vm_l:=vm_tmpb; vm_sync:=$95; end;
{SHLD }          $22 : begin vm_adres:=vm_tmpc*256+vm_tmpb; vm_data:=vm_l; vm_sync:=$06; end;
{LHLD }          $2A : begin vm_adres:=vm_tmpc*256+vm_tmpb; vm_sync:=$05; end;
{LXI SP,}        $31 : begin vm_sp:=vm_tmpc*256+vm_tmpb; vm_sync:=$95; end;
{STA }           $32 : begin vm_adres:=vm_tmpc*256+vm_tmpb; vm_data:=vm_a; vm_sync:=$06; end;
{LDA }           $3A : begin vm_adres:=vm_tmpc*256+vm_tmpb; vm_sync:=$05; end;
{JNZ }           $C2 : if (vm_f and $40)=$40 then vm_sync:=$95
                                             else vm_jump;
{JMP }           $C3 : vm_jump;
{CNZ }           $C4 : if (vm_f and $40)=$40 then vm_sync:=$95
                                             else vm_pushlow;
{JZ }            $CA : if (vm_f and $40)=$00 then vm_sync:=$95
                                             else vm_jump;
{CZ }            $CC : if (vm_f and $40)=$00 then vm_sync:=$95
                                             else vm_pushlow;
{CALL }          $CD : vm_pushlow;
{JNC }           $D2 : if (vm_f and $01)=$01 then vm_sync:=$95
                                             else vm_jump;
{CNC }           $D4 : if (vm_f and $01)=$01 then vm_sync:=$95
                                             else vm_pushlow;
{JC }            $DA : if (vm_f and $01)=$00 then vm_sync:=$95
                                             else vm_jump;
{CC }            $DC : if (vm_f and $01)=$00 then vm_sync:=$95
                                             else vm_pushlow;
{JPO }           $E2 : if (vm_f and $04)=$04 then vm_sync:=$95
                                             else vm_jump;
{CPO }           $E4 : if (vm_f and $04)=$04 then vm_sync:=$95
                                             else vm_pushlow;
{JPE }           $EA : if (vm_f and $04)=$00 then vm_sync:=$95
                                             else vm_jump;
{CPE }           $EC : if (vm_f and $04)=$00 then vm_sync:=$95
                                             else vm_pushlow;
{JP }            $F2 : if (vm_f and $80)=$80 then vm_sync:=$95
                                             else vm_jump;
{CP }            $F4 : if (vm_f and $80)=$80 then vm_sync:=$95
                                             else vm_pushlow;
{JM }            $FA : if (vm_f and $80)=$00 then vm_sync:=$95
                                             else vm_jump;
{CM }            $FC : if (vm_f and $80)=$00 then vm_sync:=$95
                                             else vm_pushlow;
                 end;
                 end;
             end;
             end
             else begin case vm_macro of
                  2 : case vm_tmpa of
{STAX B}              $02 : vm_sync:=$95;
{LDAX B}              $0A : begin vm_a:=vm_data; vm_sync:=$95; end;
{STAX D}              $12 : vm_sync:=$95;
{LDAX D}              $1A : begin vm_a:=vm_data; vm_sync:=$95; end;
{INR M}               $34 : begin vm_m:=vm_data; vm_m:=vm_alu(0,vm_m,1);
                                  vm_data:=vm_m; vm_sync:=$06; end;
{DCR M}               $35 : begin vm_m:=vm_data; vm_m:=vm_alu(2,vm_m,1);
                                  vm_data:=vm_m; vm_sync:=$06; end;
{MOV B,M}             $46 : begin vm_m:=vm_data; vm_b:=vm_m; vm_sync:=$95; end;
{MOV C,M}             $4E : begin vm_m:=vm_data; vm_c:=vm_m; vm_sync:=$95; end;
{MOV D,M}             $56 : begin vm_m:=vm_data; vm_d:=vm_m; vm_sync:=$95; end;
{MOV E,M}             $5E : begin vm_m:=vm_data; vm_e:=vm_m; vm_sync:=$95; end;
{MOV H,M}             $66 : begin vm_m:=vm_data; vm_h:=vm_m; vm_sync:=$95; end;
{MOV L,M}             $6E : begin vm_m:=vm_data; vm_l:=vm_m; vm_sync:=$95; end;
{MOV M,B}             $70 : vm_sync:=$95;
{MOV M,C}             $71 : vm_sync:=$95;
{MOV M,D}             $72 : vm_sync:=$95;
{MOV M,E}             $73 : vm_sync:=$95;
{MOV M,H}             $74 : vm_sync:=$95;
{MOV M,L}             $75 : vm_sync:=$95;
{MOV M,A}             $77 : vm_sync:=$95;
{MOV A,M}             $7E : begin vm_m:=vm_data; vm_a:=vm_m; vm_sync:=$95; end;
{ADD M}               $86 : begin vm_m:=vm_data; vm_a:=vm_alu(0,vm_a,vm_m);
                                  vm_sync:=$95; end;
{ADC M}               $8E : begin vm_m:=vm_data; vm_a:=vm_alu(1,vm_a,vm_m);
                                  vm_sync:=$95; end;
{SUB M}               $96 : begin vm_m:=vm_data; vm_a:=vm_alu(2,vm_a,vm_m);
                                  vm_sync:=$95; end;
{SBB M}               $9E : begin vm_m:=vm_data; vm_a:=vm_alu(3,vm_a,vm_m);
                                  vm_sync:=$95; end;
{ANA M}               $A6 : begin vm_m:=vm_data; vm_a:=vm_alu(4,vm_a,vm_m);
                                  vm_sync:=$95; end;
{XRA M}               $AE : begin vm_m:=vm_data; vm_a:=vm_alu(5,vm_a,vm_m);
                                  vm_sync:=$95; end;
{ORA M}               $B6 : begin vm_m:=vm_data; vm_a:=vm_alu(6,vm_a,vm_m);
                                  vm_sync:=$95; end;
{CMP M}               $BE : begin vm_m:=vm_data; vm_a:=vm_alu(7,vm_a,vm_m);
                                  vm_sync:=$95; end;
{RNZ }                $C0 : vm_popsecond;
{POP B}               $C1 : vm_popsecond;
{PUSH B}              $C5 : begin vm_sp:=vm_sp-1; vm_adres:=vm_sp; vm_data:=vm_c; vm_sync:=$26; end;
{RST 0}               $C7 : vm_pushhigh;
{RZ }                 $C8 : vm_popsecond;
{RET }                $C9 : vm_popsecond;
{RST 1}               $CF : vm_pushhigh;
{RNC }                $D0 : vm_popsecond;
{POP D}               $D1 : vm_popsecond;
{PUSH D}              $D5 : begin vm_sp:=vm_sp-1; vm_adres:=vm_sp; vm_data:=vm_e; vm_sync:=$26; end;
{RST 2}               $D7 : vm_pushhigh;
{RC }                 $D8 : vm_popsecond;
{RST 3}               $DF : vm_pushhigh;
{RPO }                $E0 : vm_popsecond;
{POP H}               $E1 : vm_popsecond;
{XTHL }               $E3 : begin vm_tmpb:=vm_h; vm_h:=vm_data; vm_data:=vm_tmpb;
                                  vm_adres:=vm_sp+1; vm_sync:=$26; end;
{PUSH H}              $E5 : begin vm_sp:=vm_sp-1; vm_adres:=vm_sp; vm_data:=vm_l; vm_sync:=$26; end;
{RST 4}               $E7 : vm_pushhigh;
{RPE }                $E8 : vm_popsecond;
{RST 5}               $EF : vm_pushhigh;
{RP }                 $F0 : vm_popsecond;
{POP PSW}             $F1 : vm_popsecond;
{PUSH PSW}            $F5 : begin vm_sp:=vm_sp-1; vm_adres:=vm_sp; vm_data:=vm_a; vm_sync:=$26; end;
{RST 6}               $F7 : vm_pushhigh;
{RM }                 $F8 : vm_popsecond;
{RST 7}               $FF : vm_pushhigh;
                      end;
                  3 : case vm_tmpa of
{INR M}               $34 : vm_sync:=$95;
{DCR M}               $35 : vm_sync:=$95;
{MVI M,}              $36 : vm_sync:=$95;
{RNZ }                $C0 : vm_return;
{POP B}               $C1 : begin vm_popthird; vm_b:=vm_tmpc; vm_c:=vm_tmpb; vm_sync:=$95; end;
{PUSH B}              $C5 : begin vm_sp:=vm_sp-1; vm_sync:=$95; end;
{RST 0}               $C7 : vm_jump;
{RZ }                 $C8 : vm_return;
{RET }                $C9 : vm_return;
{RST 1}               $CF : vm_jump;
{RNC }                $D0 : vm_return;
{POP D}               $D1 : begin vm_popthird; vm_d:=vm_tmpc; vm_e:=vm_tmpb; vm_sync:=$95; end;
{OUT }                $D3 : vm_sync:=$95;
{PUSH D}              $D5 : begin vm_sp:=vm_sp-1; vm_sync:=$95; end;
{RST 2}               $D7 : vm_jump;
{RC }                 $D8 : vm_return;
{IN }                 $DB : vm_sync:=$95;
{RST 3}               $DF : vm_jump;
{RPO }                $E0 : vm_return;
{POP H}               $E1 : begin vm_popthird; vm_h:=vm_tmpc; vm_l:=vm_tmpb; vm_sync:=$95; end;
{XTHL }               $E3 : begin vm_adres:=vm_sp; vm_sync:=$25; end;
{PUSH H}              $E5 : begin vm_sp:=vm_sp-1; vm_sync:=$95; end;
{RST 4}               $E7 : vm_jump;
{RPE }                $E8 : vm_return;
{RST 5}               $EF : vm_jump;
{RP }                 $F0 : vm_return;
{POP PSW}             $F1 : begin vm_popthird; vm_f:=vm_tmpc; vm_a:=vm_tmpb; vm_sync:=$95; end;
{PUSH PSW}            $F5 : begin vm_sp:=vm_sp-1; vm_sync:=$95; end;
{RST 6}               $F7 : vm_jump;
{RM }                 $F8 : vm_return;
{RST 7}               $FF : vm_jump;
                      end;
                  4 : case vm_tmpa of
{SHLD }               $22 : begin vm_adres:=vm_tmpc*256+vm_tmpb+1; vm_data:=vm_h; vm_sync:=$06; end;
{LHLD }               $2A : begin vm_l:=vm_data; vm_adres:=vm_tmpc*256+vm_tmpb+1; vm_sync:=$05; end;
{STA }                $32 : vm_sync:=$95;
{LDA }                $3A : begin vm_a:=vm_data; vm_sync:=$95; end;
{CNZ }                $C4 : vm_pushhigh;
{CZ }                 $CC : vm_pushhigh;
{CALL }               $CD : vm_pushhigh;
{CNC }                $D4 : vm_pushhigh;
{CC }                 $DC : vm_pushhigh;
{XTHL }               $E3 : begin vm_tmpb:=vm_l; vm_l:=vm_data; vm_data:=vm_tmpb;
                                  vm_adres:=vm_sp; vm_sync:=$26; end;
{CPO }                $E4 : vm_pushhigh;
{CPE }                $EC : vm_pushhigh;
{CP }                 $F4 : vm_pushhigh;
{CM }                 $FC : vm_pushhigh;
                      end;
                  5 : case vm_tmpa of
{SHLD }               $22 : vm_sync:=$95;
{LHLD }               $2A : begin vm_h:=vm_data; vm_sync:=$95; end;
{CNZ }                $C4 : vm_jump;
{CZ }                 $CC : vm_jump;
{CALL }               $CD : vm_jump;
{CNC }                $D4 : vm_jump;
{CC }                 $DC : vm_jump;
{XTHL }               $E3 : vm_sync:=$95;
{CPO }                $E4 : vm_jump;
{CPE }                $EC : vm_jump;
{CP }                 $F4 : vm_jump;
{CM }                 $FC : vm_jump;
                      end;
                  end;
             end;
          end;
{Слово состояния проца}
{D0 - Read; D1 - Write; D2 - Mem; D3 - Port;}
{D4 - mach; D5 - stack; D6 - halt; D7 - macro;}
          vm_macro:=vm_macro+1;
          vm_read:=boolean(vm_sync and 1);
          vm_write:=boolean((vm_sync shr 1) and 1);
          vm_ram:=boolean((vm_sync shr 2) and 1);
          vm_port:=boolean((vm_sync shr 3) and 1);
          vm_machine:=boolean((vm_sync shr 4) and 1);
          vm_stack:=boolean((vm_sync shr 5) and 1);
          vm_halt:=boolean((vm_sync shr 6) and 1);
          if (vm_sync and 128)<>0 then begin vm_macro:=1;
             vm_sync:=vm_sync and 127;
             end;
          if vm_machine then vm_adres:=vm_pc;
end;
{Hardware Init}
begin
     vm_reset;
end.