nedoPC.org

Electronics hobbyists community established in 2002
Atom Feed | View unanswered posts | View active topics It is currently 18 Apr 2024 04:56



Reply to topic  [ 295 posts ]  Go to page Previous  1, 2, 3, 4, 5, 6, 7, 8 ... 20  Next
Proteus C++ DLL's 
Author Message
Supreme God
User avatar

Joined: 21 Oct 2009 08:08
Posts: 7777
Location: Россия
Reply with quote
Post 
Поставил я сегодня 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


24 Nov 2012 11:20
Profile
Supreme God
User avatar

Joined: 21 Oct 2009 08:08
Posts: 7777
Location: Россия
Reply with quote
Post 
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:
#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


25 Nov 2012 06:35
Profile
Maniac

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

Хорошая мысля.
Я так и думал, что тема создана для решения этого вопроса.
Кстати на каком-то другом форуме спрашивали про такую модель.
С удовольствием приму посильное участие.


25 Nov 2012 18:21
Profile
Supreme God
User avatar

Joined: 21 Oct 2009 08:08
Posts: 7777
Location: Россия
Reply with quote
Post 
aav8 wrote:
Quote:
Ну что, джентльмены? А не написать ли нам цифровую модель Z80 под Proteus?
Или хотя бы наш любимый К580ВМ80?...

Хорошая мысля.
Я так и думал, что тема создана для решения этого вопроса.
Кстати на каком-то другом форуме спрашивали про такую модель.
С удовольствием приму посильное участие.

Я не обещаю, что всё у нас так сразу и получится, но я тоже очень давно
искал ВЕЗДЕ, где мог, модель i8080 (ну или хотя бы Z80).

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

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

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

Так что - предлагаю начать потихонечку, что у меня есть, я постараюсь в доступном
виде выложить...
Сейчас настраиваю VC++ под эти вопросы, потому что мне пока не совсем понятна
отладка DLL под самим Proteus - но я надеюсь, почитаю и решу этот вопрос...
На Kazus это делали...

HardWareMan wrote:
Голосую за КР580ВМ80А!

Мне тоже он ближе, но Z80 позволит не "гимароицца" со STATUS в первом такте.
Только такое соображение...

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

_________________
iLavr


26 Nov 2012 06:48
Profile
Maniac

Joined: 05 Nov 2008 19:47
Posts: 287
Location: 81.28.208.238
Reply with quote
Post 
Quote:
Z80 не_нужен. Голосую за КР580ВМ80А!

Какая разница, с точки зрения программиста
(в первом приближении) это практически одно и тоже.
Получается этакая линейка x80.
Quote:
отладка DLL под самим Proteus - но я надеюсь, почитаю и решу этот вопрос...

Такие штуки я обычно отлаживаю, изучая log.
А что, если симулятор этого проца оформить в виде DLL?
Тогда ее можно использовать и для других
симуляторов/эмуляторов?
Кстати для i8080 нужна будет модель ГФ24?
Или будет достаточно (довольно геморно) обрабатывать Ф1 и Ф2?


26 Nov 2012 08:22
Profile
Supreme God
User avatar

Joined: 21 Oct 2009 08:08
Posts: 7777
Location: Россия
Reply with quote
Post 
aav8 wrote:
Quote:
отладка DLL под самим Proteus - но я надеюсь, почитаю и решу этот вопрос...

Такие штуки я обычно отлаживаю, изучая log.
А что, если симулятор этого проца оформить в виде DLL?
Тогда ее можно использовать и для других
симуляторов/эмуляторов?

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

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

В "Протезусе" задающие генераторы чисто фиктивные. Тактовая частота задается цифрой
в параметрах модели
.
Поэтому ГФ24 мы моделировать как рабочий генератор не будем.
Но можно сделать его фиктивную модель, которая используется только для
обозначения корпуса и ножек элементов при разводке платы.
В симуляции на такую "пустышку" ставят галочку - "не симулировать".


Слушай, пока мы не ринулись в К580ВМ80 - напиши здесь как в виде ассемблерной вставки
должен выглядеть вызов типа:
Code:
oo->authorize(0xAA,0x55);

я всё же хочу попробовать это в Билдере подправить напоследок.
Я помню только, что в С++ это должно выглядеть как-то так:
Code:
#include <iostream.h>

void myAsmFunc(void);

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

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

.....
....
....
}

_________________
iLavr


26 Nov 2012 09:43
Profile
Maniac

Joined: 05 Nov 2008 19:47
Posts: 287
Location: 81.28.208.238
Reply with quote
Post 
Quote:
Мы так и будем делать - модель "этого проца ... в виде DLL", если, конечно, мы на это решимся...

Надо подумать на счет интерфейса...
Quote:
Поэтому ГФ24 мы моделировать как рабочий генератор не будем.

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

Код примерно такой:
Code:
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:
pop ecx
[/quote]


26 Nov 2012 10:17
Profile
Supreme God
User avatar

Joined: 21 Oct 2009 08:08
Posts: 7777
Location: Россия
Reply with quote
Post 
aav8 wrote:
Quote:
Мы так и будем делать - модель "этого проца ... в виде DLL", если, конечно, мы на это решимся...

Надо подумать на счет интерфейса...

Мне казалось - почти не надо... по крайней мере, у меня и у тебя "пустой мешок" точно есть:

Image

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

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


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

PPS. Ну и я наш путь к выбранной цели потихонечку начал...

_________________
iLavr


26 Nov 2012 10:53
Profile
Maniac

Joined: 05 Nov 2008 19:47
Posts: 287
Location: 81.28.208.238
Reply with quote
Post 
Немного сегодня позанимался в этом направлении.
Взял пустышку из proteusa и подключил свою DLL.
Подключил адреса, данные, сброс, BUSRQ.
Парочку кнопок.
BUSRQ переводит адреса в 3-е состояние,
сброс просто увеличивает адрес.
А теперь пусть проц сам работает.
Для начала, думаю, пусть просто перебирает адреса.
И в этом месте появился огромный вопрос:
Quote:
PS. Я вижу единственную трудёмкость: в отличие от чисто программной эмуляции,
нам придётся довольно точно соблюсти растактовки и времянки...

каким образом это организовать?
1. Одна и мыслей была - организовать еще один поток, для
процессора, и в нужные моменты его останавливать
(хотя он должен сам себя останавливать, в соответсвии
с временными диаграммами). Типа такого - процессор
спрашивает симулятора - "выдай мне данные с такого-то
адреса, мне для обработки понадобится столько-то времени".
2. Организовать между процессором и симулятором некий
объект, в котором будет хранится состояние выводов.
Симулятор в него складывает состояние, и вызывает процессор.
Процессор это дело обрабатывает, изменяет состояние
этого промежуточного объекта. И возвращает управление
симулятору. В этом промежуточном объекте будет содержаться
информация о затраченном времени и о том, что делать с этими
данными (записать или не записывать).
В первом случае все более-менее прозрачно, но смущает
многопоточность, т.к. должен исполняться только один из потоков,
и в принципе она не нужна. И к томуже затраты на переключение.
Второй случай в этом отношении как-бы лучше. Но есче не понятно.


27 Nov 2012 10:47
Profile
Banned
User avatar

Joined: 20 Mar 2005 13:41
Posts: 2141
Location: От туда
Reply with quote
Post 
Вам нужно просто вывернуть на изнанку простой эмулятор процессора. Когда-то давным-давно я так и сделал. Не смотрите на реализацию и код - я тогда зеленым был. Просто поймите идею.
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.


27 Nov 2012 12:00
Profile
Supreme God
User avatar

Joined: 21 Oct 2009 08:08
Posts: 7777
Location: Россия
Reply with quote
Post 
HardWareMan wrote:
Вам нужно просто вывернуть на изнанку простой эмулятор процессора.

А тебе типа того - не нужно? Типа, - вы в паскале тут поковыряйтесь, что я в децтве написал?

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

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


PS. Продолжил потихоньку наш договор о намерениях...

_________________
iLavr


27 Nov 2012 16:07
Profile
Supreme God
User avatar

Joined: 21 Oct 2009 08:08
Posts: 7777
Location: Россия
Reply with quote
Post 
aav8 wrote:
И в этом месте появился огромный вопрос:
Quote:
PS. Я вижу единственную трудёмкость: в отличие от чисто программной эмуляции,
нам придётся довольно точно соблюсти растактовки и времянки...

каким образом это организовать?

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

Если ты торопишься, то всё написано в примере, на который я сослался уже не один
раз: Creation VSM - Modelos Digitales.PDF...

_________________
iLavr


27 Nov 2012 17:20
Profile
Maniac

Joined: 05 Nov 2008 19:47
Posts: 287
Location: 81.28.208.238
Reply with quote
Post 
Quote:
Вам нужно просто вывернуть на изнанку простой эмулятор процессора

Я тоже склоняусь к похожей мысли.
Да и скорее всего придется еще и моделировать конечный аппарат.
Т.е. машинные циклы и такты.
И еще я думаю все-таки про внешнее
тактирование - а как-же любители Спекрумов и Специалистов?
Понятно что в этом случае для i8080 достаточно будет подать Ф2.
Quote:
Если ты не возражаешь, я всё же допишу теоретическую часть создания моделей,
поскольку это многим интересно и не совсем понятно.

Хорошее описание. И почерпнул кое-чего нового.


27 Nov 2012 18:29
Profile
Supreme God
User avatar

Joined: 21 Oct 2009 08:08
Posts: 7777
Location: Россия
Reply with quote
Post 
aav8 wrote:
И еще я думаю все-таки про внешнее тактирование - а как-же любители Спекрумов и Специалистов?
Понятно что в этом случае для i8080 достаточно будет подать Ф2.

Ну в принципе - да, Ф2 используется для синхронизации внешних процессов с времянками ЦПУ.

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

Получается довольно забавная вещь - у нам ВСЕ устройства в одном проекте синхронизируются
от одного источника - это минимальный интервал - 1 пикосекунда!
Все же модели подсчитывают эти пикосекунды, чтобы реализовать свои задержки,
так что получается без явных связей цифровая схема работает совершенно синхронно.

_________________
iLavr


27 Nov 2012 18:42
Profile
Maniac

Joined: 05 Nov 2008 19:47
Posts: 287
Location: 81.28.208.238
Reply with quote
Post 
Quote:
Получается довольно забавная вещь - у нам ВСЕ устройства в одном проекте синхронизируются
от одного источника - это минимальный интервал - 1 пикосекунда!

И VSM.HPP тип для времени определен как _int64 ...


28 Nov 2012 00:13
Profile
Display posts from previous:  Sort by  
Reply to topic   [ 295 posts ]  Go to page Previous  1, 2, 3, 4, 5, 6, 7, 8 ... 20  Next

Who is online

Users browsing this forum: No registered users and 22 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group
Designed by ST Software.