Proteus C++ DLL's

Использование и разработка софта (преимущественно на ПЦ)

Moderator: Shaos

User avatar
Lavr
Supreme God
Posts: 16676
Joined: 21 Oct 2009 08:08
Location: Россия

Post by Lavr »

Поставил я сегодня MS Visual C++ 5.0 - посмотрю, как он справится с
компиляцией Proteus C++ DLL's...

Ну и он меня сразу же рассмешил до невозможности!... :lol:
После установки при первом запуске - он мне предлжил:
"Не желаете ознакомиться с новыми возможностями MS Visual C++ 5.0 ?"
Я думаю - ну ладно... давай вспомню... давно это было... нажимаю...

Тут он мне типа излагает:"А вот и не покажу! Потому что MSDN у Вас -
на третьем диске!
" :roll:

Вот за это я его, урода, и уволил давным давно... без MSDN он ничего не способен... :wink:

А у Борланда - развитые как контекстная справка, так и полный HELP по Win API
имеется!...

Ну да ладно - потерплю... лишь бы этот MS Visual C++ 5.0 компилировал,
как надо...
iLavr
User avatar
Lavr
Supreme God
Posts: 16676
Joined: 21 Oct 2009 08:08
Location: Россия

Post by Lavr »

Lavr wrote:Поставил я сегодня MS Visual C++ 5.0 - посмотрю, как она справится с
компиляцией Proteus C++ DLL's...
Справилась нормально... (я уж грешным делом подумал, что надо было MS Visual C++ 4.1
поставить - всё время под руками мешалась, пока я диск с MS Visual C++ 5.0 искал...
). :lol:

Единственное, что MS Visual C++ 5.0 не знала, это опять же - что такое NULL,
хотя стандартные заголовочные файлы подключены... :(

Не стал "посылать её далеко"... :wink: прямо в vsm.hpp сообщил студии, что:

Code: Select all

#ifndef NULL
#ifdef __cplusplus
#define NULL    0
#else
#define NULL    ((void *)0)
#endif
#endif
Теперь надо подумать, как бы подсократить студию и вытрясти из неё лишний мусор...
Иначе две C++ студии и Борланд Билдер - многовато на одном компьютере... :-?

Может я пока ошибаюсь, но MS Visual C++ 5.0 не создаёт сама make-файл, как
это делает Борланд Билдер... но - посмотрю настройки...

Ну что, джентльмены? :D А не написать ли нам цифровую модель Z80 под Proteus?
Или хотя бы наш любимый К580ВМ80?... Раз уж Labcenter Electronics этому противится,
а по другому - у нас не случилось... :wink:
iLavr
aav8
Maniac
Posts: 287
Joined: 05 Nov 2008 19:47
Location: 81.28.208.238

Post by aav8 »

Ну что, джентльмены? А не написать ли нам цифровую модель Z80 под Proteus?
Или хотя бы наш любимый К580ВМ80?... Раз уж Labcenter Electronics этому противится,
а по другому - у нас не случилось...
Хорошая мысля.
Я так и думал, что тема создана для решения этого вопроса.
Кстати на каком-то другом форуме спрашивали про такую модель.
С удовольствием приму посильное участие.
User avatar
Lavr
Supreme God
Posts: 16676
Joined: 21 Oct 2009 08:08
Location: Россия

Post by Lavr »

aav8 wrote:
Ну что, джентльмены? А не написать ли нам цифровую модель Z80 под Proteus?
Или хотя бы наш любимый К580ВМ80?...
Хорошая мысля.
Я так и думал, что тема создана для решения этого вопроса.
Кстати на каком-то другом форуме спрашивали про такую модель.
С удовольствием приму посильное участие.
Я не обещаю, что всё у нас так сразу и получится, но я тоже очень давно
искал ВЕЗДЕ, где мог, модель i8080 (ну или хотя бы Z80).

Я совершенно точно знаю, что Labcenter Electronics эти модели не сделает никогда,
поскольку по заявлению их представителя - эти процы раритетные и спроса на них нет.

Поскольку я набрал достаточно, как мне кажется, материалов по разработке цифровых
моделей в виде DLL, то единственный выход - попробовать сделать это самим...

За время пока я искал (а это лет пять), - ни один "дядя" ничего не сделал...
Я предлагаю - попробовать... как говаривал Мао - "Всё в наших руках!" :wink:

Так что - предлагаю начать потихонечку, что у меня есть, я постараюсь в доступном
виде выложить...
Сейчас настраиваю VC++ под эти вопросы, потому что мне пока не совсем понятна
отладка DLL под самим Proteus - но я надеюсь, почитаю и решу этот вопрос...
На Kazus это делали...
HardWareMan wrote:Голосую за КР580ВМ80А!
Мне тоже он ближе, но Z80 позволит не "гимароицца" со STATUS в первом такте.
Только такое соображение...

Почему я надеюсь, что у нас может получиться - потому что, как я это вижу, вся проблема
в том, чтобы удачно "раскланяться" с Proteus-ом по его интерфейсу - а внутри,... многие из
нас имеют опыт написания собственных эмуляторов - так вот это там нам и понадобится...
iLavr
aav8
Maniac
Posts: 287
Joined: 05 Nov 2008 19:47
Location: 81.28.208.238

Post by aav8 »

Z80 не_нужен. Голосую за КР580ВМ80А!
Какая разница, с точки зрения программиста
(в первом приближении) это практически одно и тоже.
Получается этакая линейка x80.
отладка DLL под самим Proteus - но я надеюсь, почитаю и решу этот вопрос...
Такие штуки я обычно отлаживаю, изучая log.
А что, если симулятор этого проца оформить в виде DLL?
Тогда ее можно использовать и для других
симуляторов/эмуляторов?
Кстати для i8080 нужна будет модель ГФ24?
Или будет достаточно (довольно геморно) обрабатывать Ф1 и Ф2?
User avatar
Lavr
Supreme God
Posts: 16676
Joined: 21 Oct 2009 08:08
Location: Россия

Post by Lavr »

aav8 wrote:
отладка DLL под самим Proteus - но я надеюсь, почитаю и решу этот вопрос...
Такие штуки я обычно отлаживаю, изучая log.
А что, если симулятор этого проца оформить в виде DLL?
Тогда ее можно использовать и для других
симуляторов/эмуляторов?
Мы так и будем делать - модель "этого проца ... в виде DLL", если, конечно, мы на это решимся...
Но я-то сам буду это делать однозначно, поскольку я не вижу уже принципиальных трудностей,
хотя мелкие трудности, безусловно будут...
И я привык отладку делать прямо Борландовским встроенным Дебаггером. :wink: Он у меня в Венду
вписан как стандартный...

Ты мне помог с последней принципиальной трудностью - почему DLL из-под Билдера не работает
с "Протезусом"
.
Хотя я и привык работать в Билдере - ну прилажусь к VC++. Я в нём тоже работал, но очень давно...
aav8 wrote:Кстати для i8080 нужна будет модель ГФ24?
Или будет достаточно (довольно геморно) обрабатывать Ф1 и Ф2?
В "Протезусе" задающие генераторы чисто фиктивные. Тактовая частота задается цифрой
в параметрах модели
.
Поэтому ГФ24 мы моделировать как рабочий генератор не будем.
Но можно сделать его фиктивную модель, которая используется только для
обозначения корпуса и ножек элементов при разводке платы.
В симуляции на такую "пустышку" ставят галочку - "не симулировать".


Слушай, пока мы не ринулись в К580ВМ80 - напиши здесь как в виде ассемблерной вставки
должен выглядеть вызов типа:

Code: Select all

oo->authorize(0xAA,0x55);
я всё же хочу попробовать это в Билдере подправить напоследок.
Я помню только, что в С++ это должно выглядеть как-то так:

Code: Select all

#include <iostream.h>

void myAsmFunc(void);

int main(void)
{
 myAsmFunc();
 return 0;
}

void myAsmFunc(void)
{
 __asm push ebp
 __asm mov ebp,esp

.....
....
....
}
iLavr
aav8
Maniac
Posts: 287
Joined: 05 Nov 2008 19:47
Location: 81.28.208.238

Post by aav8 »

Мы так и будем делать - модель "этого проца ... в виде DLL", если, конечно, мы на это решимся...
Надо подумать на счет интерфейса...
Поэтому ГФ24 мы моделировать как рабочий генератор не будем.
А как-же прерывания и сброс - они вроде проходят через нее?
Хотя в принципе можно и обойтись
Слушай, пока мы не ринулись в К580ВМ80 - напиши здесь как в виде ассемблерной вставки
должен выглядеть вызов типа:
Код примерно такой:

Code: Select all

ils->authorize(0x5555,0xAAAA); 
1001286E  mov         esi,esp  
10012870  push        0AAAAh  
10012875  push        5555h  
1001287A  mov         eax,dword ptr [ils]  
1001287D  mov         edx,dword ptr [eax]  
1001287F  mov         ecx,dword ptr [ils]  
10012882  mov         eax,dword ptr [edx]  
10012884  call        eax  
10012886  cmp         esi,esp  
10012888  call        @ILT+390(__RTC_CheckEsp) (1001118Bh)
Я думаю можно в Билдере сделать ASM,
в нем подправить код, а потом этот ASM опять в Билдер...
Наверное достаточно будет сделать

Code: Select all

pop ecx
[/quote]
User avatar
Lavr
Supreme God
Posts: 16676
Joined: 21 Oct 2009 08:08
Location: Россия

Post by Lavr »

aav8 wrote:
Мы так и будем делать - модель "этого проца ... в виде DLL", если, конечно, мы на это решимся...
Надо подумать на счет интерфейса...
Мне казалось - почти не надо... по крайней мере, у меня и у тебя "пустой мешок" точно есть:

Image

Надо только сделать под него цифровую модель в виде DLL.
Поэтому навскидку я назвал именно Z80, а не i8080...

С этой целью я сейчас упорно почитываю VSM SDK, помечаю нужные нам моменты,
и даже перевожу переводчиком, чтобы был удобный рабочий документ...
Но сам понимаешь, хелпы и по-русски пишут довольно косноязычно...


PS. Я вижу единственную трудёмкость: в отличие от чисто программной эмуляции,
нам придётся довольно точно соблюсти растактовки и времянки...
Но в этом вопросе - у нас Хардыч просто бог!
:kruto:
aav8 wrote:А как-же прерывания и сброс - они вроде проходят через нее? (ГФ24)
Ну мы то знаем, что это просто привязка к такту Ф2 - ну и учтём это программно.

PPS. Ну и я наш путь к выбранной цели потихонечку начал...
iLavr
aav8
Maniac
Posts: 287
Joined: 05 Nov 2008 19:47
Location: 81.28.208.238

Post by aav8 »

Немного сегодня позанимался в этом направлении.
Взял пустышку из proteusa и подключил свою DLL.
Подключил адреса, данные, сброс, BUSRQ.
Парочку кнопок.
BUSRQ переводит адреса в 3-е состояние,
сброс просто увеличивает адрес.
А теперь пусть проц сам работает.
Для начала, думаю, пусть просто перебирает адреса.
И в этом месте появился огромный вопрос:
PS. Я вижу единственную трудёмкость: в отличие от чисто программной эмуляции,
нам придётся довольно точно соблюсти растактовки и времянки...
каким образом это организовать?
1. Одна и мыслей была - организовать еще один поток, для
процессора, и в нужные моменты его останавливать
(хотя он должен сам себя останавливать, в соответсвии
с временными диаграммами). Типа такого - процессор
спрашивает симулятора - "выдай мне данные с такого-то
адреса, мне для обработки понадобится столько-то времени".
2. Организовать между процессором и симулятором некий
объект, в котором будет хранится состояние выводов.
Симулятор в него складывает состояние, и вызывает процессор.
Процессор это дело обрабатывает, изменяет состояние
этого промежуточного объекта. И возвращает управление
симулятору. В этом промежуточном объекте будет содержаться
информация о затраченном времени и о том, что делать с этими
данными (записать или не записывать).
В первом случае все более-менее прозрачно, но смущает
многопоточность, т.к. должен исполняться только один из потоков,
и в принципе она не нужна. И к томуже затраты на переключение.
Второй случай в этом отношении как-бы лучше. Но есче не понятно.
User avatar
HardWareMan
Banned
Posts: 2139
Joined: 20 Mar 2005 13:41
Location: От туда

Post by HardWareMan »

Вам нужно просто вывернуть на изнанку простой эмулятор процессора. Когда-то давным-давно я так и сделал. Не смотрите на реализацию и код - я тогда зеленым был. Просто поймите идею.

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.
User avatar
Lavr
Supreme God
Posts: 16676
Joined: 21 Oct 2009 08:08
Location: Россия

Post by Lavr »

HardWareMan wrote:Вам нужно просто вывернуть на изнанку простой эмулятор процессора.
А тебе типа того - не нужно? Типа, - вы в паскале тут поковыряйтесь, что я в децтве написал?

На мой взгляд, нам ничего не надо выворачивать наизнанку. Нам надо сделать интерфейс
от состояния выводов модели Протезуса к коду симулятора, а результат симуляции
вывести как состояние выходов модели ЦПУ.

А исходники i8080 и на С у нас тут на форуме имеются... :-?


PS. Продолжил потихоньку наш договор о намерениях...
iLavr
User avatar
Lavr
Supreme God
Posts: 16676
Joined: 21 Oct 2009 08:08
Location: Россия

Post by Lavr »

aav8 wrote:И в этом месте появился огромный вопрос:
PS. Я вижу единственную трудёмкость: в отличие от чисто программной эмуляции,
нам придётся довольно точно соблюсти растактовки и времянки...
каким образом это организовать?
Если ты не возражаешь, я всё же допишу теоретическую часть создания моделей,
поскольку это многим интересно и не совсем понятно.
И выложу там же код DLL-модели с примером создания времянок с комментариями.

Если ты торопишься, то всё написано в примере, на который я сослался уже не один
раз: Creation VSM - Modelos Digitales.PDF...
iLavr
aav8
Maniac
Posts: 287
Joined: 05 Nov 2008 19:47
Location: 81.28.208.238

Post by aav8 »

Вам нужно просто вывернуть на изнанку простой эмулятор процессора
Я тоже склоняусь к похожей мысли.
Да и скорее всего придется еще и моделировать конечный аппарат.
Т.е. машинные циклы и такты.
И еще я думаю все-таки про внешнее
тактирование - а как-же любители Спекрумов и Специалистов?
Понятно что в этом случае для i8080 достаточно будет подать Ф2.
Если ты не возражаешь, я всё же допишу теоретическую часть создания моделей,
поскольку это многим интересно и не совсем понятно.
Хорошее описание. И почерпнул кое-чего нового.
User avatar
Lavr
Supreme God
Posts: 16676
Joined: 21 Oct 2009 08:08
Location: Россия

Post by Lavr »

aav8 wrote:И еще я думаю все-таки про внешнее тактирование - а как-же любители Спекрумов и Специалистов?
Понятно что в этом случае для i8080 достаточно будет подать Ф2.
Ну в принципе - да, Ф2 используется для синхронизации внешних процессов с времянками ЦПУ.

Я разбирался давно уже, как в проекте взаимодействуют два проца, если нет внешней синхронизации
от общего источника...

Получается довольно забавная вещь - у нам ВСЕ устройства в одном проекте синхронизируются
от одного источника - это минимальный интервал - 1 пикосекунда!
Все же модели подсчитывают эти пикосекунды, чтобы реализовать свои задержки,
так что получается без явных связей цифровая схема работает совершенно синхронно.
iLavr
aav8
Maniac
Posts: 287
Joined: 05 Nov 2008 19:47
Location: 81.28.208.238

Post by aav8 »

Получается довольно забавная вещь - у нам ВСЕ устройства в одном проекте синхронизируются
от одного источника - это минимальный интервал - 1 пикосекунда!
И VSM.HPP тип для времени определен как _int64 ...