| Code: 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.
| |