Навигация
Главная
Поиск
Форум
FAQ's
Ссылки
Карта сайта
Чат программистов

Статьи
-Delphi
-C/C++
-Turbo Pascal
-Assembler
-Java/JS
-PHP
-Perl
-DHTML
-Prolog
-GPSS
-Сайтостроительство
-CMS: PHP Fusion
-Инвестирование

Файлы
-Для программистов
-Компонеты для Delphi
-Исходники на Delphi
-Исходники на C/C++
-Книги по Delphi
-Книги по С/С++
-Книги по JAVA/JS
-Книги по Basic/VB/.NET
-Книги по PHP/MySQL
-Книги по Assembler
-PHP Fusion MOD'ы
-by Kest
Professional Download System
Реклама
Услуги

Автоматическое добавление статей на сайты на Wordpress, Joomla, DLE
Заказать продвижение сайта
Программа для рисования блок-схем
Инженерный калькулятор онлайн
Таблица сложения онлайн
Популярные статьи
OpenGL и Delphi... 65535
Форум на вашем ... 65535
21 ошибка прогр... 65535
HACK F.A.Q 65535
Бип из системно... 65535
Гостевая книга ... 65535
Invision Power ... 65535
Пример работы с... 65535
Содержание сайт... 65535
ТЕХНОЛОГИИ ДОСТ... 65535
Организация зап... 65535
Вызов хранимых ... 65535
Создание отчето... 65535
Имитационное мо... 65535
Программируемая... 65535
Эмулятор микроп... 65535
Подключение Mic... 65535
Создание потоко... 65535
Приложение «Про... 65535
Оператор выбора... 65535
Реклама
Английская снасть Рыболовный магазин www.pf-fishing.ru.
Сейчас на сайте
Гостей: 6
На сайте нет зарегистрированных пользователей

Пользователей: 13,361
новичок: uehuat
Новости
Реклама
Выполняем курсовые и лабораторные по разным языкам программирования
Подробнее - курсовые и лабораторные на заказ
Delphi, Turbo Pascal, Assembler, C, C++, C#, Visual Basic, Java, GPSS, Prolog, 3D MAX, Компас 3D
Заказать программу для Windows Mobile, Symbian

Метод конечных разностей для интерполяции/экстраполяции на Delphi
Моделирование литейного цеха на GPSS + Пояснительная записка
База данных склада на Delphi + Схема БД

Эмулятор микропроцессора K580
Общие сведения о программе

Программа KP580BM80 моделирует работу микропроцессора К580 при выполнении команд обмена между памятью и регистрами, логических операций, арифметических операций, команд передачи управления и команд управления процессором.

Для ввода программного кода можно использовать упрощенный язык ассемблера или вводить программу непосредственно в машинных кодах в ячейки памяти. При использовании языка ассемблера можно заранее подготовить текст, например в «Блокноте» (Note Book), и загрузить этот код в память. Можно также написать программу на языке ассемблера воспользовавшись полем редактирования кода в окне программы.

Выполнение введенной программы осуществляется по шагам. При этом результат выполнения каждого шага отображается в поле вывода результатов трассировки.

Скриншот программы:
Эмулятор микропроцессора K580

Текст программы:

KP580BM80.dpr
program KP580BM80;

uses
Forms,
MainForm in 'MainForm.pas' {K580MainForm},
AsmUnit in 'AsmUnit.pas',
MPUnit in 'MPUnit.pas';

{$R *.res}

begin
Application.Initialize;
Application.HelpFile := '\Help\KP580BM80.HLP';
Application.Title := 'Эмулятор микропроцессора К580';
Application.CreateForm(TK580MainForm, K580MainForm);
Application.Run;
end.





MainForm.pas
unit MainForm;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Menus, Grids, ComCtrls, MPUnit, AsmUnit, ToolWin,
ImgList, ActnList;

type
TK580MainForm = class(TForm)
MainMenu: TMainMenu;
FileMenu: TMenuItem;
LoadMenu: TMenuItem;
LoadDialog: TOpenDialog;
MemGrid: TDrawGrid;
MemLabel: TLabel;
ComEditLabel: TLabel;
StatusBar: TStatusBar;
RegLabel: TLabel;
RegGrid: TDrawGrid;
PCSPGrid: TStringGrid;
CodeMemo: TMemo;
RezMemo: TMemo;
SaveMenu: TMenuItem;
JustDoItMenu: TMenuItem;
TraseMenu: TMenuItem;
ApplyMenu: TMenuItem;
AboutMenu: TMenuItem;
HelpMenu: TMenuItem;
SaveDialog: TSaveDialog;
SimpleLine1: TMenuItem;
ExitMenu: TMenuItem;
SaveCodeMenu: TMenuItem;
PortsGrid: TDrawGrid;
PortsLabel: TLabel;
ToolBar: TToolBar;
LoadBtn: TToolButton;
SaveCodeBtn: TToolButton;
SaveBtn: TToolButton;
Separator1: TToolButton;
ApplyBtn: TToolButton;
TraceBtn: TToolButton;
Separator2: TToolButton;
ExecBtn: TToolButton;
BreakMenu: TMenuItem;
ExecMenu: TMenuItem;
SimpleLine2: TMenuItem;
BreakBtn: TToolButton;
Separator3: TToolButton;
HelpBtn: TToolButton;
ToolImageList: TImageList;
ActionList: TActionList;
LoadAction: TAction;
SaveCodeAction: TAction;
SaveAction: TAction;
ExitAction: TAction;
ApplyAction: TAction;
TraceAction: TAction;
ExecAction: TAction;
BreakAction: TAction;
HelpAction: TAction;
SimpleLine3: TMenuItem;
ClearRezultsMenu: TMenuItem;
ClearRezultsAction: TAction;
ClearRezultsBtn: TToolButton;
ClearMemMenu: TMenuItem;
ClearMemAction: TAction;
ClearMemBtn: TToolButton;
procedure MainFormClose(Sender: TObject; var Action: TCloseAction);
procedure MainFormCreate(Sender: TObject);
procedure MainFormDestroy(Sender: TObject);
procedure GridKeyPress(Sender: TObject; var Key: Char);
procedure MemGridDraw(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
procedure MemGridGetEditMask(Sender: TObject; ACol, ARow: Integer;
var Value: String);
procedure MemGridGetEditText(Sender: TObject; ACol, ARow: Integer;
var Value: String);
procedure MemGridSetEditText(Sender: TObject; ACol, ARow: Integer;
const Value: String);
procedure MemGridSelectCell(Sender: TObject; ACol, ARow: Integer;
var CanSelect: Boolean);
procedure RegGridDraw(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
procedure RegGridGetEditMask(Sender: TObject; ACol, ARow: Integer;
var Value: String);
procedure RegGridGetEditText(Sender: TObject; ACol, ARow: Integer;
var Value: String);
procedure RegGridSetEditText(Sender: TObject; ACol, ARow: Integer;
const Value: String);
procedure RegGridSelectSell(Sender: TObject; ACol, ARow: Integer;
var CanSelect: Boolean);
procedure PCSPGridDraw(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
procedure PCSPGridGetEditMask(Sender: TObject; ACol, ARow: Integer;
var Value: String);
procedure PCSPGridGetEditText(Sender: TObject; ACol, ARow: Integer;
var Value: String);
procedure PCSPGridSetEditText(Sender: TObject; ACol, ARow: Integer;
const Value: String);
procedure PortsGridDraw(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
procedure PortsGridGetEditMask(Sender: TObject; ACol, ARow: Integer;
var Value: String);
procedure PortsGridGetEditText(Sender: TObject; ACol, ARow: Integer;
var Value: String);
procedure PortsGridSetEditText(Sender: TObject; ACol, ARow: Integer;
const Value: String);
procedure LoadMenuClick(Sender: TObject);
procedure ApplyMenuClick(Sender: TObject);
procedure SaveMenuClick(Sender: TObject);
procedure HelpMenuClick(Sender: TObject);
procedure SaveCodeMenuClick(Sender: TObject);
procedure MainFormCloseClick(Sender: TObject);
procedure TraceMenuClick(Sender: TObject);
procedure BreakMenuClick(Sender: TObject);
procedure ExecMenuClick(Sender: TObject);
procedure ClearRezultsMenuClick(Sender: TObject);
procedure ClearMemMenuClick(Sender: TObject);
private
Reg: TK580Regs;
Mem: PByteList;
Ports: PByteList;
Run: Boolean;
Int: Boolean;
CmdInfo: TCmdInfo;
{ Private declarations }
public
function GetWordFromMem(Addr: Word): Word;//Получить слово из памяти.
function GetNextWordFromMem(Addr: Word): Word;//Получить следующие после Addr слово.
function GetRunString: string;
function GetIntString: string;
function GetUseMem: Boolean;
function GetWordMem: Boolean;
function GetMemAddr: Word;
function HexToInt(Hex: string): Integer;
function IntToBin(Int: Byte): string; overload;
function IntToBin(Int: Word): string; overload;
procedure RunThreadTerminate(Sender: TObject);
{ Public declarations }
end;

var
K580MainForm: TK580MainForm;
K580Thread: TK580MP;

implementation

{$R *.dfm}

function TK580MainForm.GetWordFromMem(Addr: Word): Word;
begin
if Addr < 65535
then
GetWordFromMem := (Mem[Addr + 1] shl 8) + Mem[Addr]
else
GetWordFromMem := (Mem[0] shl 8) + Mem[Addr];
end;

function TK580MainForm.GetNextWordFromMem(Addr: Word): Word;
begin
if Addr = 65535
then Addr := 0
else Addr := Addr + 1;
GetNextWordFromMem := GetWordFromMem(Addr);
end;

function TK580MainForm.GetRunString: string;
begin
if Run
then GetRunString := 'Running'
else GetRunString := 'Stopped';
end;

function TK580MainForm.GetIntString: string;
begin
if Int
then GetIntString := 'Yes'
else GetIntString := 'No';
end;

function TK580MainForm.GetUseMem: Boolean;
begin
GetUseMem := CmdInfo.UseMem;
end;

function TK580MainForm.GetWordMem: Boolean;
begin
GetWordMem := CmdInfo.WordMem;
end;

function TK580MainForm.GetMemAddr: Word;
begin
GetMemAddr := CmdInfo.MemAddr;
end;

function TK580MainForm.HexToInt(Hex: string): Integer;
var
N, A, i, Len: Integer;
Chr: Char;
begin
N := 0;
Len := Length(Hex);
for i := 1 to Len do
begin
Chr := UpCase(Hex[i]);
if (Chr >= '0') and (Chr <= '9')
then A := Ord(Chr) - Ord('0')
else
if (Chr >= 'A') and (Chr <= 'F')
then A := Ord(Chr) - Ord('A') + 10
else A := 0;
N := (N shl 4) + A;
end;
HexToInt := N;
end;

function TK580MainForm.IntToBin(Int: Byte): string;
var
i, R: Integer;
Str: string;
begin
Str := '0000 0000';
i := 9;
while Int <> 0 do
begin
R := Int and $01;
if R = 1
then Str[i] := '1';
Int := Int shr 1;
i := i - 1;
if i = 5 then i := 4;
end;
IntToBin := Str;
end;

function TK580MainForm.IntToBin(Int: Word): string;
var
i, R: Integer;
Str: string;
begin
Str := '0000 0000 0000 0000';
i := 21;
while Int <> 0 do
begin
R := Int and $01;
if R = 1
then Str[i] := '1';
Int := Int shr 1;
i := i - 1;
if (i = 5) or (i = 17)
then i := i - 1
else
if (i = 12)
then i := 9;
end;
IntToBin := Str;
end;

procedure TK580MainForm.MainFormClose(Sender: TObject;
var Action: TCloseAction);
begin
Application.Terminate;
end;

procedure TK580MainForm.MainFormCreate(Sender: TObject);
begin
CmdInfo.LastAddr := 0;
CmdInfo.LastCmd := 0;
CmdInfo.LastTag := 0;
CmdInfo.UseMem := False;
CmdInfo.WordMem := False;
CmdInfo.Contents := '';
Reg.PC := 0;
Reg.SP := 0;
Reg.PSW := 0;
Reg.BC := 0;
Reg.DE := 0;
Reg.HL := 0;
Run := False;
Int := True;
SetLength(Mem,65536);
SetLength(Ports,256);

MemGrid.ColWidths[0] := 16;
MemGrid.ColWidths[1] := 80;
MemGrid.ColWidths[2] := 32;
MemGrid.ColWidths[3] := 32;
MemGrid.ColWidths[4] := 48;
MemGrid.Col := 4;
RegGrid.ColWidths[0] := 32;
RegGrid.ColWidths[1] := 87;
RegGrid.ColWidths[2] := 87;
PCSPGrid.ColWidths[0] := 32;
PCSPGrid.ColWidths[1] := 175;
PortsGrid.ColWidths[0] := 32;
PortsGrid.ColWidths[1] := 32;
StatusBar.Panels[2].Text := GetRunString;
StatusBar.Panels[3].Text := GetIntString;

BreakAction.Enabled := False;
end;

procedure TK580MainForm.MainFormDestroy(Sender: TObject);
begin
if K580Thread <> nil
then K580Thread.Terminate;
Mem := nil;
Ports := nil;
CmdInfo.Contents := '';
end;

procedure TK580MainForm.GridKeyPress(Sender: TObject; var Key: Char);
begin
if ((Key > 'F') and (Key <= 'Z')) or ((Key > 'f') and (Key <= 'z'))
or (Key > #127)
then Key := #0;
end;

procedure TK580MainForm.MemGridDraw(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
begin
if ARow > 0
then
begin
if (ACol > 1) and (ACol < 4)
then
begin
MemGrid.Canvas.Pen.Color := clRed;
if GetUseMem
then
if (((ARow - 1) shl 1) + ACol - 2) = GetMemAddr
then
begin
MemGrid.Canvas.Pen.Color := clYellow;
MemGrid.Canvas.Brush.Color := clYellow;
MemGrid.Canvas.Rectangle(Rect);
end
else
if ((((ARow - 1) shl 1) + ACol - 3) = GetMemAddr) and
GetWordMem
then
begin
MemGrid.Canvas.Pen.Color := clYellow;
MemGrid.Canvas.Brush.Color := clYellow;
MemGrid.Canvas.Rectangle(Rect);
end;
if (((ARow - 1) shl 1) + ACol - 2) = Reg.PC
then
begin
MemGrid.Canvas.Brush.Color := clRed;
MemGrid.Canvas.Rectangle(Rect);
end;
end;
case ACol of
1:
MemGrid.Canvas.TextOut(Rect.Left + 8, Rect.Top + 1,
IntToHex((ARow shl 1) - 2, 4) + ':' + IntToHex((ARow shl 1) - 1, 4));
2:
MemGrid.Canvas.TextOut(Rect.Left + 8, Rect.Top + 1,
IntToHex(Mem[(ARow shl 1) - 2], 2));
3:
MemGrid.Canvas.TextOut(Rect.Left + 8, Rect.Top + 1,
IntToHex(Mem[(ARow shl 1) - 1], 2));
4:
begin
if (((ARow - 1) shl 1) = GetMemAddr) and
GetWordMem
then
begin
MemGrid.Canvas.Pen.Color := clYellow;
MemGrid.Canvas.Brush.Color := clYellow;
MemGrid.Canvas.Rectangle(Rect);
end;
MemGrid.Canvas.TextOut(Rect.Left + 8, Rect.Top + 1,
IntToHex(((Mem[(ARow shl 1) - 1] shl 8) +
Mem[(ARow shl 1) - 2]), 4));
end;
else
if ARow = (Reg.PC shr 1) + 1
then
begin
MemGrid.Canvas.Pen.Color := clBlue;
MemGrid.Canvas.Brush.Color := clBlue;
MemGrid.Canvas.Polygon([Point(Rect.Left + 6, Rect.Top + 5),
Point(Rect.Left + 6, Rect.Bottom - 5),
Point(Rect.Right - 6, Rect.Top + 8)]);
end
else
if ARow = (Reg.SP shr 1) + 1
then
begin
MemGrid.Canvas.Pen.Color := clGreen;
MemGrid.Canvas.Brush.Color := clGreen;
MemGrid.Canvas.Polygon([Point(Rect.Left + 6, Rect.Top + 5),
Point(Rect.Left + 6, Rect.Bottom - 5),
Point(Rect.Right - 6, Rect.Top + 8)]);
end;
end;
end
else
case ACol of
1: MemGrid.Canvas.TextOut(Rect.Left + 16, Rect.Top + 1, 'Address');
2: MemGrid.Canvas.TextOut(Rect.Left + 10, Rect.Top + 1, 'Lo');
3: MemGrid.Canvas.TextOut(Rect.Left + 10, Rect.Top + 1, 'Hi');
4: MemGrid.Canvas.TextOut(Rect.Left + 10, Rect.Top + 1, 'Word');
end;
end;

procedure TK580MainForm.MemGridGetEditMask(Sender: TObject; ACol,
ARow: Integer; var Value: String);
begin
if (ACol = 2) or (ACol = 3)
then Value := 'aa;1;0'
else
if ACol = 4
then Value := 'aaaa;1;0';
end;

procedure TK580MainForm.MemGridGetEditText(Sender: TObject; ACol,
ARow: Integer; var Value: String);
begin
if ACol = 2
then
Value := IntToHex(Mem[(ARow shl 1) - 2], 2)
else
if ACol = 3
then
Value := IntToHex(Mem[(ARow shl 1) - 1], 2)
else
if ACol = 4
then
Value := IntToHex(((Mem[(ARow shl 1) - 1] shl 8) +
Mem[(ARow shl 1) - 2]), 4);
end;

procedure TK580MainForm.MemGridSetEditText(Sender: TObject; ACol,
ARow: Integer; const Value: String);
var
IntVal: Integer;
CanSelect: Boolean;
begin
IntVal := HexToInt(Value);
if ACol = 2
then Mem[(ARow shl 1) - 2] := Byte(IntVal)
else
if ACol = 3
then Mem[(ARow shl 1) - 1] := Byte(IntVal)
else
begin
Mem[(ARow shl 1) - 2] := Byte(IntVal);
Mem[(ARow shl 1) - 1] := Byte(IntVal shr 8);
end;
MemGrid.Repaint;
CanSelect := True;
MemGridSelectCell(Sender, ACol, ARow, CanSelect);
end;

procedure TK580MainForm.MemGridSelectCell(Sender: TObject; ACol,
ARow: Integer; var CanSelect: Boolean);
var
Str: string;
Pos: Word;
begin
if ACol = 4
then Pos := (ARow - 1) shl 1
else Pos := ((ARow - 1) shl 1) + ACol - 2;
GetCmdStr(Mem[Pos], GetNextWordFromMem(Pos), Str);
StatusBar.Panels[1].Text := Str;
end;

procedure TK580MainForm.RegGridDraw(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
begin
case ACol of
0:
case ARow of
0: RegGrid.Canvas.TextOut(Rect.Left + 6, Rect.Top + 1, 'PSW');
1: RegGrid.Canvas.TextOut(Rect.Left + 10, Rect.Top + 1, 'BC');
2: RegGrid.Canvas.TextOut(Rect.Left + 10, Rect.Top + 1, 'DE');
3: RegGrid.Canvas.TextOut(Rect.Left + 10, Rect.Top + 1, 'HL');
end;
1:
case ARow of
0: RegGrid.Canvas.TextOut(Rect.Left + 8, Rect.Top + 1,
'A:' + IntToBin(Reg.A));
1: RegGrid.Canvas.TextOut(Rect.Left + 8, Rect.Top + 1,
'B:' + IntToBin(Reg.B));
2: RegGrid.Canvas.TextOut(Rect.Left + 8, Rect.Top + 1,
'D:' + IntToBin(Reg.D));
3: RegGrid.Canvas.TextOut(Rect.Left + 8, Rect.Top + 1,
'H:' + IntToBin(Reg.H));
end;
2:
case ARow of
0: RegGrid.Canvas.TextOut(Rect.Left + 4, Rect.Top + 1,
'F:' + IntToBin(Reg.F));
1: RegGrid.Canvas.TextOut(Rect.Left + 4, Rect.Top + 1,
'C:' + IntToBin(Reg.C));
2: RegGrid.Canvas.TextOut(Rect.Left + 4, Rect.Top + 1,
'E:' + IntToBin(Reg.E));
3: RegGrid.Canvas.TextOut(Rect.Left + 4, Rect.Top + 1,
'L:' + IntToBin(Reg.L));
end;
end;
end;

procedure TK580MainForm.RegGridGetEditMask(Sender: TObject; ACol,
ARow: Integer; var Value: String);
begin
Value := 'aa;1;0';
end;

procedure TK580MainForm.RegGridGetEditText(Sender: TObject; ACol,
ARow: Integer; var Value: String);
begin
case ACol of
1:
case ARow of
0: Value := IntToHex(Reg.A, 2);
1: Value := IntToHex(Reg.B, 2);
2: Value := IntToHex(Reg.D, 2);
3: Value := IntToHex(Reg.H, 2);
end;
2:
case ARow of
0: Value := IntToHex(Reg.F, 2);
1: Value := IntToHex(Reg.C, 2);
2: Value := IntToHex(Reg.E, 2);
3: Value := IntToHex(Reg.L, 2);
end;
end;
end;

procedure TK580MainForm.RegGridSetEditText(Sender: TObject; ACol,
ARow: Integer; const Value: String);
begin
case ACol of
1:
case ARow of
0: Reg.A := HexToInt(Value);
1: Reg.B := HexToInt(Value);
2: Reg.D := HexToInt(Value);
3: Reg.H := HexToInt(Value);
end;
2:
case ARow of
0: Reg.F := HexToInt(Value);
1: Reg.C := HexToInt(Value);
2: Reg.E := HexToInt(Value);
3: Reg.L := HexToInt(Value);
end;
end;
RegGrid.Repaint;
end;

procedure TK580MainForm.RegGridSelectSell(Sender: TObject; ACol,
ARow: Integer; var CanSelect: Boolean);
begin
if (ARow = 0) and (ACol = 2)
then CanSelect := False;
end;

procedure TK580MainForm.PCSPGridDraw(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
begin
if ACol = 0
then
if ARow = 0
then PCSPGrid.Canvas.TextOut(Rect.Left + 8, Rect.Top + 1, 'SP')
else PCSPGrid.Canvas.TextOut(Rect.Left + 8, Rect.Top + 1, 'PC')
else
if ARow = 0
then PCSPGrid.Canvas.TextOut(Rect.Left + 1, Rect.Top + 1,
'SP:' + IntToBin(Reg.SP))
else PCSPGrid.Canvas.TextOut(Rect.Left + 1, Rect.Top + 1,
'PC:' + IntToBin(Reg.PC));
end;

procedure TK580MainForm.PCSPGridGetEditMask(Sender: TObject; ACol,
ARow: Integer; var Value: String);
begin
Value := 'aaaa;1;0'
end;

procedure TK580MainForm.PCSPGridGetEditText(Sender: TObject; ACol,
ARow: Integer; var Value: String);
begin
if ARow = 0
then Value := IntToHex(Reg.SP, 4)
else Value := IntToHex(Reg.PC, 4);
end;

procedure TK580MainForm.PCSPGridSetEditText(Sender: TObject; ACol,
ARow: Integer; const Value: String);
begin
if ARow = 0
then Reg.SP := HexToInt(Value)
else Reg.PC := HexToInt(Value);
PCSPGrid.Repaint;
MemGrid.Repaint;
end;

procedure TK580MainForm.PortsGridDraw(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
begin
if ARow > 0
then
if ACol = 0
then
PortsGrid.Canvas.TextOut(Rect.Left + 8, Rect.Top + 1,
IntToHex(ARow - 1,2))
else
PortsGrid.Canvas.TextOut(Rect.Left + 8, Rect.Top + 1,
IntToHex(Ports[ARow -1],2))
else
if ACol = 0
then
PortsGrid.Canvas.TextOut(Rect.Left + 6, Rect.Top + 1, 'Num')
else
PortsGrid.Canvas.TextOut(Rect.Left + 2, Rect.Top + 1,'Port');
end;

procedure TK580MainForm.PortsGridGetEditMask(Sender: TObject; ACol,
ARow: Integer; var Value: String);
begin
Value := 'aa;1;0';
end;

procedure TK580MainForm.PortsGridGetEditText(Sender: TObject; ACol,
ARow: Integer; var Value: String);
begin
if ACol = 1
then
Value := IntToHex(Ports[ARow - 1], 2);
end;

procedure TK580MainForm.PortsGridSetEditText(Sender: TObject; ACol,
ARow: Integer; const Value: String);
var
IntVal: Integer;
begin
IntVal := HexToInt(Value);
if ACol = 1
then Ports[ARow - 1] := Byte(IntVal);
PortsGrid.Repaint;
end;

procedure TK580MainForm.LoadMenuClick(Sender: TObject);
begin
if LoadDialog.Execute
then
begin
CodeMemo.Lines.LoadFromFile(LoadDialog.FileName);
K580MainForm.ApplyMenuClick(Sender);
end;
end;

procedure TK580MainForm.ApplyMenuClick(Sender: TObject);
var
Rezult: string;
SntLst: PSentence;
LNLst: TStringList;
Pos: Integer;
CanSelect: Boolean;
begin
SntLst := nil;
Rezult := '';
LNLst := TStringList.Create;
if ReadProgList(CodeMemo.Lines, Rezult, SntLst)
then
if GenerateLNList(SntLst, Rezult, LNLst)
then
if (MemGrid.Row > 0) and (MemGrid.Col > 1)
then
begin
if MemGrid.Col = 4
then Pos := (MemGrid.Row - 1) shl 1
else Pos := ((MemGrid.Row - 1) shl 1) + MemGrid.Col - 2;
Reg.PC := Pos;
Reg.SP := Pos;
WriteProgToMem(SntLst, LNLst, Pos, Mem, Rezult);
end;
MemGrid.Repaint;
PCSPGrid.Repaint;
StatusBar.Panels[0].Text := Rezult;
FreeListObj(LNLst);
LNLst.Free;
DisposeSntList(SntLst);
CanSelect := True;
MemGridSelectCell(Sender, MemGrid.Col, MemGrid.Row, CanSelect);
end;

procedure TK580MainForm.SaveMenuClick(Sender: TObject);
begin
SaveDialog.FilterIndex := 0;
if SaveDialog.Execute
then RezMemo.Lines.SaveToFile(SaveDialog.FileName);
end;

procedure TK580MainForm.HelpMenuClick(Sender: TObject);
begin
Application.HelpCommand(Help_Contents, 0)
end;

procedure TK580MainForm.SaveCodeMenuClick(Sender: TObject);
begin
SaveDialog.FilterIndex := 1;
if SaveDialog.Execute
then CodeMemo.Lines.SaveToFile(SaveDialog.FileName);
end;

procedure TK580MainForm.MainFormCloseClick(Sender: TObject);
begin
K580MainForm.Close;
end;

procedure TK580MainForm.TraceMenuClick(Sender: TObject);
begin
StatusBar.Panels[2].Text := GetRunString;
K580Thread := TK580MP.Create(@Reg, Mem, Ports, @Run, @Int, @CmdInfo,
RegGrid,
PCSPGrid,
MemGrid,
PortsGrid,
StatusBar.Panels[3],
RezMemo.Lines);
K580Thread.OnTerminate := RunThreadTerminate;
end;

procedure TK580MainForm.ExecMenuClick(Sender: TObject);
begin
CodeMemo.Enabled := False;
LoadAction.Enabled := False;
SaveCodeAction.Enabled := False;
SaveAction.Enabled := False;
ApplyAction.Enabled := False;
ClearMemAction.Enabled := False;
TraceAction.Enabled := False;
ExecAction.Enabled := False;
BreakAction.Enabled := True;
Run := True;
StatusBar.Panels[2].Text := GetRunString;
K580Thread := TK580MP.Create(@Reg, Mem, Ports, @Run, @Int, @CmdInfo,
RegGrid,
PCSPGrid,
MemGrid,
PortsGrid,
StatusBar.Panels[3],
RezMemo.Lines);
K580Thread.OnTerminate := RunThreadTerminate;
end;

procedure TK580MainForm.BreakMenuClick(Sender: TObject);
begin
K580Thread.Terminate;
end;

procedure TK580MainForm.RunThreadTerminate(Sender: TObject);
begin
Run := False;
CodeMemo.Enabled := True;
LoadAction.Enabled := True;
SaveCodeAction.Enabled := True;
SaveAction.Enabled := True;
ApplyAction.Enabled := True;
ClearMemAction.Enabled := True;
TraceAction.Enabled := True;
ExecAction.Enabled := True;
BreakAction.Enabled := False;
StatusBar.Panels[2].Text := GetRunString;
MemGrid.Row := (Reg.PC shr 1) + 1;
MemGrid.Col := (Reg.PC and $0001) + 2
end;

procedure TK580MainForm.ClearRezultsMenuClick(Sender: TObject);
begin
RezMemo.Lines.Clear;
RezMemo.Lines.Add(' АДР | МНЕМОНИКА |A B C D E H L |C Z M P A| ПАМЯТЬ |СОДЕРЖАНИЕ');
end;

procedure TK580MainForm.ClearMemMenuClick(Sender: TObject);
var
i: Integer;
begin
for i := 0 to 65535 do
Mem[i] := 0;
CmdInfo.UseMem := False;
CmdInfo.WordMem := False;
MemGrid.Repaint;
end;

end.





Модуль MPUnit разработан Милашовым М. В.
В модуле определен класс TK580MP предназначенный для
программной эмуляции арифметических команд микропроцессорра КР580ВМ60.

MPUnit.pas
unit MPUnit;
{
Модуль MPUnit разработан Милашовым М. В.
В модуле определен класс TK580MP предназначенный для
программной эмуляции арифметических команд микропроцессорра КР580ВМ60.
}
interface

uses SysUtils, Classes, Controls, ComCtrls, AsmUnit;

type
{Регистры микропроцессора.}
TK580Regs = record
PC: Word;
SP: Word;
case Integer of
0: (F, A, C, B, E, D, L, H: Byte);
1: (PSW, BC, DE, HL: Word);
end;

PK580Regs = ^TK580Regs;

{Информация о последней выполненной команде.}
TCmdInfo = record
LastAddr: Word;//Адрес последней выполненной команды.
LastCmd: Byte;//Код последней выполненной команды.
LastTag: Word;//2-й и 3-й байты последней выполненной команды.
UseMem: Boolean;//Признак обращения к памяти.
WordMem: Boolean;//Признак обращения к слову в памяти.
MemAddr: Word;//Адрес ячейки памяти.
MemValue: Word;//Содержимое ячейки памяти после выполнения команды.
Contents: string;//Информация о команде.
end;

PCmdInfo = ^TCmdInfo;

BBoolean = ^Boolean;

{Класс "Микропроцессор К580".}
TK580MP = class(TThread)
protected
Reg: PK580Regs;//Регистры микропроцессора.
Mem: PByteList;//Память.
Ports: PByteList;//Порты ввода-вывода.
Run: PBoolean;//Флаг запуска программы.
Int: PBoolean;//Флаг запрета/разрешения прерывания.
CmdInfo: PCmdInfo;//Информация о последней выполненной команде
RegGrid: TWinControl;
PCSPGrid: TWinControl;
MemGrid: TWinControl;
PortsGrid: TWinControl;
IntStatus: TStatusPanel;
RezStrings: TStrings;
function GetCY: Byte;
function GetZ: Byte;
function GetM: Byte;
function GetP: Byte;
procedure SetZMP(Rez: Byte);//Установка флагов Z, M и P по результату операции.
procedure SetCY(Op1: Byte; Op2: Byte); overload;//Установка флага CY по
procedure SetCY(Op1: Word; Op2: Word); overload;//передаваемым операндам.
procedure SetCY(Op1: Byte; Op2: Byte; Op3: Byte); overload;
procedure SetAC(Op1: Byte; Op2: Byte); overload;//Установка флага AC.
procedure SetAC(Op1: Byte; Op2: Byte; Op3: Byte); overload;
function GetSSS(Code: Byte): Byte;//Получить содержимое регистра источника по коду команды.
function GetDDD(Code: Byte): Byte;//ПолучитьСодержимое регистра приемника.
procedure SetDDD(Code: Byte; Data: Byte);//Записать данные в регистр приемник.
function GetDataPort: Byte;//Получить 8-ми разрядный литерал или адрес порта.
function GetData16Addr: Word;//Получить 16-ти разрядный литерал или адрес памяти.
function GetWordFromMem(Addr: Word): Word;//Получить слово из памяти.
procedure SetWordToMem(Addr: Word; Data: Word);//Записать слово в память.
function GetRun: Boolean;
procedure SetRun(RunStop: Boolean);
function GetInt: Boolean;
procedure SetInt(IntNotInt: Boolean);
function GetIntString: string;
function GetRezString: string;//Получить строку с информацией о последней выполненной команде.
procedure JMP(Addr: Word);
procedure CALL(Addr: Word);
procedure RET;
procedure DefaultTrace;//Начальная установка информации о последней выполненной команде.
procedure ExchangeTrace;//Выполнение команд обмена данными между памятью и регистрами.
procedure LogicTrace;//Выполнение логических команд.
procedure ArifhmTrace;//Выполнение арифметических команд.
procedure JmpTrace;//Выполнение команд перехода.
procedure MPTrace;//Выполнение команд микропроцессора.
procedure TraceProg; overload;//Трассировка (можно переопределить в классах потомках).
procedure RunProg; overload;//Выполнение (можно переопределить в классах потомках).
procedure Execute; override;
{ Protected declarations }
public
constructor Create(PReg: PK580Regs;
PMem: PByteList;
PPorts: PByteList;
PRun: PBoolean;
PInt: PBoolean;
PCmdInf: PCmdInfo;
PRegGrid: TWinControl;
PPCSPGrid: TWinControl;
PMemGrid: TWinControl;
PPortsGrid: TWinControl;
PIntStatus: TStatusPanel;
PRezStrings: TStrings);
{ Public declarations }
end;

implementation

constructor TK580MP.Create(PReg: PK580Regs;
PMem: PByteList;
PPorts: PByteList;
PRun: PBoolean;
PInt: PBoolean;
PCmdInf: PCmdInfo;
PRegGrid: TWinControl;
PPCSPGrid: TWinControl;
PMemGrid: TWinControl;
PPortsGrid: TWinControl;
PIntStatus: TStatusPanel;
PRezStrings: TStrings);
begin
inherited Create(False);
Reg := PReg;
Mem := PMem;
Ports := PPorts;
Run := PRun;
Int := PInt;
CmdInfo := PCmdInf;
RegGrid := PRegGrid;
PCSPGrid := PPCSPGrid;
MemGrid := PMemGrid;
PortsGrid := PPortsGrid;
IntStatus := PIntStatus;
RezStrings := PRezStrings;
FreeOnTerminate := True;
end;

procedure TK580MP.Execute;
begin
while not Terminated do
Synchronize(RunProg);
end;

function TK580MP.GetCY: Byte;
begin
GetCY := Reg^.F and $01;
end;

function TK580MP.GetZ: Byte;
begin
GetZ := (Reg^.F and $40) shr 6;
end;

function TK580MP.GetM: Byte;
begin
GetM := (Reg^.F and $80) shr 7;
end;

function TK580MP.GetP: Byte;
begin
GetP := (Reg^.F and $04) shr 2;
end;

procedure TK580MP.SetZMP(Rez: Byte);
var
P: Byte;
begin
if Rez = 0
then Reg^.F := Reg^.F or $40
else Reg^.F := Reg^.F and $BF;
if (Rez and $80) = 0
then Reg^.F := Reg^.F and $7F
else Reg^.F := Reg^.F or $80;
P := 0;
while Rez <> 0 do
begin
P := P xor (Rez and $01);
Rez := Rez shr 1;
end;
if P = 0
then Reg^.F := Reg^.F or $04
else Reg^.F := Reg^.F and $FB;
end;

procedure TK580MP.SetCY(Op1: Byte; Op2: Byte);
begin
if ((Op1 + Op2) and $0100) <> 0
then Reg^.F := Reg^.F or $01
else Reg^.F := Reg^.F and $FE;
end;

procedure TK580MP.SetCY(Op1: Word; Op2: Word);
begin
if ((Op1 + Op2) and $010000) <> 0
then Reg^.F := Reg^.F or $01
else Reg^.F := Reg^.F and $FE;
end;

procedure TK580MP.SetCY(Op1: Byte; Op2: Byte; Op3: Byte);
begin
if ((Op1 + Op2 + Op3) and $0100) <> 0
then Reg^.F := Reg^.F or $01
else Reg^.F := Reg^.F and $FE;
end;

procedure TK580MP.SetAC(Op1: Byte; Op2: Byte);
begin
if (((Op1 and $0F) + (Op2 and $0F)) and $10) <> 0
then Reg^.F := Reg^.F or $10
else Reg^.F := Reg^.F and $EF;
end;

procedure TK580MP.SetAC(Op1: Byte; Op2: Byte; Op3: Byte);
begin
if (((Op1 and $0F) + (Op2 and $0F) + (Op3 and $0F)) and $10) <> 0
then Reg^.F := Reg^.F or $10
else Reg^.F := Reg^.F and $EF;
end;

function TK580MP.GetSSS(Code: Byte): Byte;
var
SSS: Byte;
begin
SSS := Code and $07;
case SSS of
0: GetSSS := Reg^.B;
1: GetSSS := Reg^.C;
2: GetSSS := Reg^.D;
3: GetSSS := Reg^.E;
4: GetSSS := Reg^.H;
5: GetSSS := Reg^.L;
else GetSSS := Reg^.A;
end;
end;

function TK580MP.GetDDD(Code: Byte): Byte;
var
DDD: Byte;
begin
DDD := (Code and $38) shr 3;
GetDDD := GetSSS(DDD);
end;

procedure TK580MP.SetDDD(Code: Byte; Data: Byte);
var
DDD: Byte;
begin
DDD := (Code and $38) shr 3;
case DDD of
0: Reg^.B := Data;
1: Reg^.C := Data;
2: Reg^.D := Data;
3: Reg^.E := Data;
4: Reg^.H := Data;
5: Reg^.L := Data;
6: ;
else Reg^.A := Data;
end;
end;

function TK580MP.GetDataPort: Byte;
begin
if Reg^.PC < 65535
then
GetDataPort := Mem[Reg^.PC + 1]
else
GetDataPort := Mem[0];
end;

function TK580MP.GetData16Addr: Word;
begin
if Reg^.PC < 65534
then
GetData16Addr := (Mem[Reg^.PC + 2] shl 8) + Mem[Reg^.PC + 1]
else
if Reg^.PC < 65535
then
GetData16Addr := (Mem[0] shl 8) + Mem[Reg^.PC + 1]
else
GetData16Addr := (Mem[1] shl 8) + Mem[0];
end;

function TK580MP.GetWordFromMem(Addr: Word): Word;
begin
if Addr < 65535
then
GetWordFromMem := (Mem[Addr + 1] shl 8) + Mem[Addr]
else
GetWordFromMem := (Mem[0] shl 8) + Mem[Addr];
end;

procedure TK580MP.SetWordToMem(Addr: Word; Data: Word);
begin
if Addr < 65535
then
begin
Mem[Addr + 1] := (Data and $FF00) shr 8;
Mem[Addr] := Data and $FF;
end
else
begin
Mem[0] := (Data and $FF00) shr 8;
Mem[Addr] := Data and $FF;
end;
end;

function TK580MP.GetRun: Boolean;
begin
GetRun := Run^;
end;

procedure TK580MP.SetRun(RunStop: Boolean);
begin
Run^ := RunStop;
end;

function TK580MP.GetInt: Boolean;
begin
GetInt := Int^;
end;

procedure TK580MP.SetInt(IntNotInt: Boolean);
begin
Int^ := IntNotInt;
end;

function TK580MP.GetIntString: string;
begin
if GetInt
then GetIntString := 'Yes'
else GetIntString := 'No';
end;

function TK580MP.GetRezString: string;
var
Str, TmpStr: string;
begin
Str := IntToHex(CmdInfo^.LastAddr, 4) + ': ';
GetCmdStr(CmdInfo^.LastCmd, CmdInfo^.LastTag, TmpStr);
while Length(TmpStr) < 12 do
TmpStr := TmpStr + ' ';
Str := Str + TmpStr + ' ' + IntToHex(Reg^.A, 2) +
' ' + IntToHex(Reg^.B, 2) + ' ' + IntToHex(Reg^.C, 2) +
' ' + IntToHex(Reg^.D, 2) + ' ' + IntToHex(Reg^.E, 2) +
' ' + IntToHex(Reg^.H, 2) + ' ' + IntToHex(Reg^.L, 2) + ' ';
TmpStr := '0 0 0 0 0 ';
if (Reg^.F and $01) = $01
then TmpStr[1] := '1';
if (Reg^.F and $40) = $40
then TmpStr[3] := '1';
if (Reg^.F and $80) = $80
then TmpStr[5] := '1';
if (Reg^.F and $04) = $04
then TmpStr[7] := '1';
if (Reg^.F and $10) = $10
then TmpStr[9] := '1';
Str := Str + TmpStr;
if CmdInfo^.UseMem
then
begin
TmpStr := '(' + IntToHex(CmdInfo^.MemAddr, 4) + ')';
if CmdInfo^.WordMem
then TmpStr := TmpStr + IntToHex(CmdInfo^.MemValue, 4)
else TmpStr := TmpStr + IntToHex(CmdInfo^.MemValue, 2) + ' ';
end
else TmpStr := ' ';
Str := Str + TmpStr + ' ' + CmdInfo^.Contents;
GetRezString := Str;
end;

procedure TK580MP.DefaultTrace;
begin
CmdInfo^.LastAddr := Reg^.PC;
CmdInfo^.LastCmd := Mem[Reg^.PC];
CmdInfo^.LastTag := GetData16Addr;
CmdInfo^.UseMem := False;
CmdInfo^.WordMem := False;
CmdInfo^.Contents := '';
end;

procedure TK580MP.ExchangeTrace;
var
Addr, Data: Word;
S: Byte;
begin
case Mem[Reg^.PC] of
$40..$45, $47..$4D, $4F..$55, $57..$5D, $5F..$65, $67..$6D, $6F, $78..$7D, $7F:
begin
S := GetSSS(Mem[Reg^.PC]);
SetDDD(Mem[Reg^.PC],S);
Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := 'dst <- src';
end;
$46, $4E, $56, $5E, $66, $6E, $7E:
begin
CmdInfo^.UseMem := True;
CmdInfo^.MemAddr := Reg^.HL;
SetDDD(Mem[Reg^.PC],Mem[Reg^.HL]);
CmdInfo^.MemValue := Mem[Reg^.HL];
Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := 'dst <- (HL)';
end;
$70..$75, $77:
begin
CmdInfo^.UseMem := True;
CmdInfo^.MemAddr := Reg^.HL;
Mem[Reg^.HL] := GetSSS(Mem[Reg^.PC]);
CmdInfo^.MemValue := Mem[Reg^.HL];
Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := '(HL) <- src';
end;
$06, $0E, $16, $1E, $26, $2E, $3E:
begin
SetDDD(Mem[Reg^.PC],GetDataPort);
Reg^.PC := Reg^.PC + 2;
CmdInfo^.Contents := 'dst <- data';
end;
$36:
begin
CmdInfo^.UseMem := True;
CmdInfo^.MemAddr := Reg^.HL;
Mem[Reg^.HL] := GetDataPort;
CmdInfo^.MemValue := Mem[Reg^.HL];
Reg^.PC := Reg^.PC + 2;
CmdInfo^.Contents := '(HL) <- data';
end;
$3A:
begin
Addr := GetData16Addr;
CmdInfo^.UseMem := True;
CmdInfo^.MemAddr := Addr;
Reg^.A := Mem[Addr];
CmdInfo^.MemValue := Mem[Addr];
Reg^.PC := Reg^.PC + 3;
CmdInfo^.Contents := 'A <- (addr)';
end;
$32:
begin
Addr := GetData16Addr;
CmdInfo^.UseMem := True;
CmdInfo^.MemAddr := Addr;
Mem[Addr] := Reg^.A;
CmdInfo^.MemValue := Mem[Addr];
Reg^.PC := Reg^.PC + 3;
CmdInfo^.Contents := '(addr) <- A';
end;
$0A:
begin
CmdInfo^.UseMem := True;
CmdInfo^.MemAddr := Reg^.BC;
Reg^.A := Mem[Reg^.BC];
CmdInfo^.MemValue := Mem[Reg^.BC];
Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := 'A <- (BC)';
end;
$1A:
begin
CmdInfo^.UseMem := True;
CmdInfo^.MemAddr := Reg^.DE;
Reg^.A := Mem[Reg^.DE];
CmdInfo^.MemValue := Mem[Reg^.DE];
Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := 'A <- (DE)';
end;
$02:
begin
CmdInfo^.UseMem := True;
CmdInfo^.MemAddr := Reg^.BC;
Mem[Reg^.BC] := Reg^.A;
CmdInfo^.MemValue := Mem[Reg^.BC];
Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := '(BC) <- A';
end;
$12:
begin
CmdInfo^.UseMem := True;
CmdInfo^.MemAddr := Reg^.DE;
Mem[Reg^.DE] := Reg^.A;
CmdInfo^.MemValue := Mem[Reg^.DE];
Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := '(DE) <- A';
end;
$01:
begin
Reg^.BC := GetData16Addr;
Reg^.PC := Reg^.PC + 3;
CmdInfo^.Contents := 'BC <- data16';
end;
$11:
begin
Reg^.DE := GetData16Addr;
Reg^.PC := Reg^.PC + 3;
CmdInfo^.Contents := 'DE <- data16';
end;
$21:
begin
Reg^.HL := GetData16Addr;
Reg^.PC := Reg^.PC + 3;
CmdInfo^.Contents := 'HL <- data16';
end;
$31:
begin
Reg^.SP := GetData16Addr;
Reg^.PC := Reg^.PC + 3;
CmdInfo^.Contents := 'SP <- data16';
end;
$2A:
begin
Addr := GetData16Addr;
CmdInfo^.UseMem := True;
CmdInfo^.WordMem := True;
CmdInfo^.MemAddr := Addr;
Data := GetWordFromMem(Addr);
Reg^.HL := Data;
CmdInfo^.MemValue := Data;
Reg^.PC := Reg^.PC + 3;
CmdInfo^.Contents := 'HL <- (addr)';
end;
$22:
begin
Addr := GetData16Addr;
CmdInfo^.UseMem := True;
CmdInfo^.WordMem := True;
CmdInfo^.MemAddr := Addr;
Data := Reg^.HL;
SetWordToMem(Addr, Data);
CmdInfo^.MemValue := Data;
Reg^.PC := Reg^.PC + 3;
CmdInfo^.Contents := 'HL <- (addr)';
end;
$F9:
begin
Reg^.SP := Reg^.HL;
Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := 'SP <- HL';
end;
$C5:
begin
CmdInfo^.UseMem := True;
CmdInfo^.WordMem := True;
Reg^.SP := Reg^.SP - 2;
CmdInfo^.MemAddr := Reg^.SP;
Data := Reg^.BC;
SetWordToMem(Reg^.SP, Data);
CmdInfo^.MemValue := Data;
Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := '-(SP) <- BC';
end;
$D5:
begin
CmdInfo^.UseMem := True;
CmdInfo^.WordMem := True;
Reg^.SP := Reg^.SP - 2;
CmdInfo^.MemAddr := Reg^.SP;
Data := Reg^.DE;
SetWordToMem(Reg^.SP, Data);
CmdInfo^.MemValue := Data;
Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := '-(SP) <- DE';
end;
$E5:
begin
CmdInfo^.UseMem := True;
CmdInfo^.WordMem := True;
Reg^.SP := Reg^.SP - 2;
CmdInfo^.MemAddr := Reg^.SP;
Data := Reg^.HL;
SetWordToMem(Reg^.SP, Data);
CmdInfo^.MemValue := Data;
Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := '-(SP) <- HL';
end;
$F5:
begin
CmdInfo^.UseMem := True;
CmdInfo^.WordMem := True;
Reg^.SP := Reg^.SP - 2;
CmdInfo^.MemAddr := Reg^.SP;
Data := Reg^.PSW;
SetWordToMem(Reg^.SP, Data);
CmdInfo^.MemValue := Data;
Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := '-(SP) <- PSW';
end;
$C1:
begin
CmdInfo^.UseMem := True;
CmdInfo^.WordMem := True;
CmdInfo^.MemAddr := Reg^.SP;
Data := GetWordFromMem(Reg^.SP);
Reg^.BC := Data;
Reg^.SP := Reg^.SP + 2;
CmdInfo^.MemValue := Data;
Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := 'BC <- (SP)+';
end;
$D1:
begin
CmdInfo^.UseMem := True;
CmdInfo^.WordMem := True;
CmdInfo^.MemAddr := Reg^.SP;
Data := GetWordFromMem(Reg^.SP);
Reg^.DE := Data;
Reg^.SP := Reg^.SP + 2;
CmdInfo^.MemValue := Data;
Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := 'DE <- (SP)+';
end;
$E1:
begin
CmdInfo^.UseMem := True;
CmdInfo^.WordMem := True;
CmdInfo^.MemAddr := Reg^.SP;
Data := GetWordFromMem(Reg^.SP);
Reg^.HL := Data;
Reg^.SP := Reg^.SP + 2;
CmdInfo^.MemValue := Data;
Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := 'HL <- (SP)+';
end;
$F1:
begin
CmdInfo^.UseMem := True;
CmdInfo^.WordMem := True;
CmdInfo^.MemAddr := Reg^.SP;
Data := GetWordFromMem(Reg^.SP);
Reg^.PSW := Data;
Reg^.SP := Reg^.SP + 2;
CmdInfo^.MemValue := Data;
Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := 'PSW <- (SP)+';
end;
$EB:
begin
Data := Reg^.DE;
Reg^.DE := Reg^.HL;
Reg^.HL := Data;
Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := 'DE <-> HL';
end;
$E3:
begin
CmdInfo^.UseMem := True;
CmdInfo^.WordMem := True;
CmdInfo^.MemAddr := Reg^.SP;
Data := GetWordFromMem(Reg^.SP);
SetWordToMem(Reg^.SP,Reg^.HL);
Reg^.HL := Data;
CmdInfo^.MemValue := Reg^.HL;
Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := '(SP) <-> HL';
end;
end;
end;

procedure TK580MP.LogicTrace;
var
S, Data: Byte;
CY: Word;
begin
case Mem[Reg^.PC] of
$A0..$A5, $A7:
begin
Reg^.F := Reg^.F and $FE;
Reg^.F := Reg^.F and $EF;
S := GetSSS(Mem[Reg^.PC]);
Reg^.A := Reg^.A and S;
SetZMP(Reg^.A);
Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := 'A <- A AND src';
end;
$A8..$AD, $AF:
begin
Reg^.F := Reg^.F and $FE;
Reg^.F := Reg^.F and $EF;
S := GetSSS(Mem[Reg^.PC]);
Reg^.A := Reg^.A xor S;
SetZMP(Reg^.A);
Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := 'A <- A XOR src';
end;
$B0..$B5, $B7:
begin
Reg^.F := Reg^.F and $FE;
Reg^.F := Reg^.F and $EF;
S := GetSSS(Mem[Reg^.PC]);
Reg^.A := Reg^.A or S;
SetZMP(Reg^.A);
Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := 'A <- A OR src';
end;
$B8..$BD, $BF:
begin
S := GetSSS(Mem[Reg^.PC]);
SetCY(Reg^.A, Byte(-S));
SetAC(Reg^.A, Byte(-S));
SetZMP(Reg^.A - S);
Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := 'A-src';
end;
$A6:
begin
CmdInfo^.UseMem := True;
CmdInfo^.MemAddr := Reg^.HL;
Reg^.F := Reg^.F and $FE;
Reg^.F := Reg^.F and $EF;
Reg^.A := Reg^.A and Mem[Reg^.HL];
SetZMP(Reg^.A);
CmdInfo^.MemValue := Mem[Reg^.HL];
Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := 'A <- A AND (HL)';
end;
$AE:
begin
CmdInfo^.UseMem := True;
CmdInfo^.MemAddr := Reg^.HL;
Reg^.F := Reg^.F and $FE;
Reg^.F := Reg^.F and $EF;
Reg^.A := Reg^.A xor Mem[Reg^.HL];
SetZMP(Reg^.A);
CmdInfo^.MemValue := Mem[Reg^.HL];
Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := 'A <- A XOR (HL)';
end;
$B6:
begin
CmdInfo^.UseMem := True;
CmdInfo^.MemAddr := Reg^.HL;
Reg^.F := Reg^.F and $FE;
Reg^.F := Reg^.F and $EF;
Reg^.A := Reg^.A or Mem[Reg^.HL];
SetZMP(Reg^.A);
CmdInfo^.MemValue := Mem[Reg^.HL];
Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := 'A <- A OR (HL)';
end;
$BE:
begin
CmdInfo^.UseMem := True;
CmdInfo^.MemAddr := Reg^.HL;
SetCY(Reg^.A, Byte(-Mem[Reg^.HL]));
SetAC(Reg^.A, Byte(-Mem[Reg^.HL]));
SetZMP(Reg^.A - Mem[Reg^.HL]);
CmdInfo^.MemValue := Mem[Reg^.HL];
Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := 'A-(HL)';
end;
$E6:
begin
Data := GetDataPort;
Reg^.F := Reg^.F and $FE;
Reg^.F := Reg^.F and $EF;
Reg^.A := Reg^.A and Data;
SetZMP(Reg^.A);
Reg^.PC := Reg^.PC + 2;
CmdInfo^.Contents := 'A <- A AND data';
end;
$EE:
begin
Data := GetDataPort;
Reg^.F := Reg^.F and $FE;
Reg^.F := Reg^.F and $EF;
Reg^.A := Reg^.A xor Data;
SetZMP(Reg^.A);
Reg^.PC := Reg^.PC + 2;
CmdInfo^.Contents := 'A <- A XOR data';
end;
$F6:
begin
Data := GetDataPort;
Reg^.F := Reg^.F and $FE;
Reg^.F := Reg^.F and $EF;
Reg^.A := Reg^.A or Data;
SetZMP(Reg^.A);
Reg^.PC := Reg^.PC + 2;
CmdInfo^.Contents := 'A <- A OR data';
end;
$FE:
begin
Data := GetDataPort;
SetCY(Reg^.A, Byte(-Data));
SetAC(Reg^.A, Byte(-Data));
SetZMP(Reg^.A - Data);
Reg^.PC := Reg^.PC + 2;
CmdInfo^.Contents := 'A-data';
end;
$07:
begin
if (Reg^.A and $80) <> 0 then
begin
Reg^.F := Reg^.F or $01;
Reg^.A := ((Reg^.A shl 1) and $FE) + 1;
end
else
begin
Reg^.F := Reg^.F and $FE;
Reg^.A := ((Reg^.A shl 1) and $FE);
end;
Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := 'A7 <- A6 <- ... <- A0 <- A7';
end;
$0F:
begin
if (Reg^.A and $01) <> 0 then
begin
Reg^.F := Reg^.F or $01;
Reg^.A := ((Reg^.A shr 1) and $7F) + $80;
end
else
begin
Reg^.F := Reg^.F and $FE;
Reg^.A := ((Reg^.A shr 1) and $7F);
end;
Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := 'A0 <- A1 <- ... <- A7 <- A0';
end;
$17:
begin
CY := GetCY;
if (Reg^.A and $80) <> 0 then
begin
Reg^.F := Reg^.F or $01;
Reg^.A := ((Reg^.A shl 1) and $FE) + CY;
end
else
begin
Reg^.F := Reg^.F and $FE;
Reg^.A := ((Reg^.A shl 1) and $FE) + CY;
end;
Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := 'A7 <- A6 <- ... <- A0 <- CY <- A7';
end;
$1F:
begin
CY := GetCY shl 7;
if (Reg^.A and $01) <> 0 then
begin
Reg^.F := Reg^.F or $01;
Reg^.A := ((Reg^.A shr 1) and $7F) + CY;
end
else
begin
Reg^.F := Reg^.F and $FE;
Reg^.A := ((Reg^.A shr 1) and $7F) + CY;
end;
Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := 'A0 <- A1 <- ... <- A7 <- CY <- A0';
end;
$2E:
begin
Reg^.A := not Reg^.A;
Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := 'A <- NOT A';
end;
$3F:
begin
if (Reg^.F and $01) <> 0
then
Reg^.F := Reg^.F and $FE
else
Reg^.F := Reg^.F or $01;
Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := 'CY <- NOT CY';
end;
$37:
begin
Reg^.F := Reg^.F or $01;
Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := 'CY <- 1';
end;
end;
end;

procedure TK580MP.ArifhmTrace;
var
S, CY, Data: Byte;
begin
case Mem[Reg^.PC] of
$80..$85, $87:
begin
S := GetSSS(Mem[Reg^.PC]);
SetCY(Reg^.A, S);
SetAC(Reg^.A, S);
Reg^.A := Reg^.A + S;
SetZMP(Reg^.A);
Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := 'A <- A + src';
end;
$88..$8D, $8F:
begin
S := GetSSS(Mem[Reg^.PC]);
CY := Reg^.F and $01;
SetCY(Reg^.A, S, CY);
SetAC(Reg^.A, S, CY);
Reg^.A := Reg^.A + S + CY;
SetZMP(Reg^.A);
Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := 'A <- A + src + CY';
end;
$90..$95, $97:
begin
S := GetSSS(Mem[Reg^.PC]);
SetCY(Reg^.A, Byte(-S));
SetAC(Reg^.A, Byte(-S));
Reg^.A := Reg^.A - S;
SetZMP(Reg^.A);
Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := 'A <- A - src';
end;
$98..$9D, $9F:
begin
S := GetSSS(Mem[Reg^.PC]);
CY := GetCY;
SetCY(Reg^.A, Byte(-S), Byte(-CY));
SetAC(Reg^.A, Byte(-S), Byte(-CY));
Reg^.A := Reg^.A - S - CY;
SetZMP(Reg^.A);
Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := 'A <- A - src - CY';
end;
$86:
begin
CmdInfo^.UseMem := True;
CmdInfo^.MemAddr := Reg^.HL;
SetCY(Reg^.A, Mem[Reg^.HL]);
SetAC(Reg^.A, Mem[Reg^.HL]);
Reg^.A := Reg^.A + Mem[Reg^.HL];
SetZMP(Reg^.A);
CmdInfo^.MemValue := Mem[Reg^.HL];
Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := 'A <- A + (HL)';
end;
$8E:
begin
CmdInfo^.UseMem := True;
CmdInfo^.MemAddr := Reg^.HL;
CY := GetCY;
SetCY(Reg^.A, Mem[Reg^.HL], CY);
SetAC(Reg^.A, Mem[Reg^.HL], CY);
Reg^.A := Reg^.A + Mem[Reg^.HL] + CY;
SetZMP(Reg^.A);
CmdInfo^.MemValue := Mem[Reg^.HL];
Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := 'A <- A + (HL) + CY';
end;
$96:
begin
CmdInfo^.UseMem := True;
CmdInfo^.MemAddr := Reg^.HL;
SetCY(Reg^.A, Byte(-Mem[Reg^.HL]));
SetAC(Reg^.A, Byte(-Mem[Reg^.HL]));
Reg^.A := Reg^.A - Mem[Reg^.HL];
SetZMP(Reg^.A);
CmdInfo^.MemValue := Mem[Reg^.HL];
Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := 'A <- A - (HL)';
end;
$9E:
begin
CmdInfo^.UseMem := True;
CmdInfo^.MemAddr := Reg^.HL;
CY := GetCY;
SetCY(Reg^.A, Byte(-Mem[Reg^.HL]), Byte(-CY));
SetAC(Reg^.A, Byte(-Mem[Reg^.HL]), Byte(-CY));
Reg^.A := Reg^.A - Mem[Reg^.HL] - CY;
SetZMP(Reg^.A);
CmdInfo^.MemValue := Mem[Reg^.HL];
Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := 'A <- A - (HL) - CY';
end;
$C6:
begin
Data := GetDataPort;
SetCY(Reg^.A, Data);
SetAC(Reg^.A, Data);
Reg^.A := Reg^.A + Data;
SetZMP(Reg^.A);
Reg^.PC := Reg^.PC + 2;
CmdInfo^.Contents := 'A <- A + data';
end;
$CE:
begin
CY := GetCY;
Data := GetDataPort;
SetCY(Reg^.A, Data, CY);
SetAC(Reg^.A, Data, CY);
Reg^.A := Reg^.A + Data + CY;
SetZMP(Reg^.A);
Reg^.PC := Reg^.PC + 2;
CmdInfo^.Contents := 'A <- A + data + CY';
end;
$D6:
begin
Data := GetDataPort;
SetCY(Reg^.A, Byte(-Data));
SetAC(Reg^.A, Byte(-Data));
Reg^.A := Reg^.A - Data;
SetZMP(Reg^.A);
Reg^.PC := Reg^.PC + 2;
CmdInfo^.Contents := 'A <- A - data';
end;
$DE:
begin
Data := GetDataPort;
CY := GetCY;
SetCY(Reg^.A, Byte(-Data), Byte(-CY));
SetAC(Reg^.A, Byte(-Data), Byte(-CY));
Reg^.A := Reg^.A - Data - CY;
SetZMP(Reg^.A);
Reg^.PC := Reg^.PC + 2;
CmdInfo^.Contents := 'A <- A - data - CY';
end;
$04, $0C, $14, $1C, $24, $2C, $3C:
begin
S := GetDDD(Mem[Reg^.PC]);
SetAC(S, 1);
S := S + 1;
SetDDD(Mem[Reg^.PC],S);
SetZMP(S);
Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := 'dst <- dst + 1';
end;
$05, $0D, $15, $1D, $25, $2D, $3D:
begin
S := GetDDD(Mem[Reg^.PC]);
SetAC(S, Byte(-1));
S := S - 1;
SetDDD(Mem[Reg^.PC],S);
SetZMP(S);
Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := 'dst <- dst - 1';
end;
$34:
begin
CmdInfo^.UseMem := True;
CmdInfo^.MemAddr := Reg^.HL;
SetAC(Mem[Reg^.HL], 1);
Mem[Reg^.HL] := Mem[Reg^.HL] + 1;
SetZMP(Mem[Reg^.HL]);
CmdInfo^.MemValue := Mem[Reg^.HL];
Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := '(HL) <- (HL) + 1';
end;
$35:
begin
CmdInfo^.UseMem := True;
CmdInfo^.MemAddr := Reg^.HL;
SetAC(Mem[Reg^.HL], Byte(-1));
Mem[Reg^.HL] := Mem[Reg^.HL] - 1;
SetZMP(Mem[Reg^.HL]);
CmdInfo^.MemValue := Mem[Reg^.HL];
Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := '(HL) <- (HL) - 1';
end;
$27:
begin
if (Reg^.A and $0F) > $09
then
begin
Reg^.F := Reg^.F or $10;
Reg^.A := Reg^.A + $06;
end
else Reg^.F := Reg^.F and $EF;
if (Reg^.A and $F0) > $90
then
begin
Reg^.F := Reg^.F or $01;
Reg^.A := Reg^.A + $60;
end
else Reg^.F := Reg^.F and $FE;
SetZMP(Reg^.A);
Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := 'A <- 2/10 коррекция A';
end;
$09:
begin
SetCY(Reg^.HL, Reg^.BC);
Reg^.HL := Reg^.HL + Reg^.BC;
Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := 'HL <- HL + BC';
end;
$19:
begin
SetCY(Reg^.HL, Reg^.DE);
Reg^.HL := Reg^.HL + Reg^.DE;
Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := 'HL <- HL + DE';
end;
$29:
begin
SetCY(Reg^.HL, Reg^.HL);
Reg^.HL := Reg^.HL + Reg^.HL;
Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := 'HL <- HL + HL';
end;
$39:
begin
SetCY(Reg^.HL, Reg^.SP);
Reg^.HL := Reg^.HL + Reg^.SP;
Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := 'HL <- HL + SP';
end;
$03:
begin
Reg^.BC := Reg^.BC + 1;
Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := 'BC <- BC + 1';
end;
$13:
begin
Reg^.DE := Reg^.DE + 1;
Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := 'DE <- DE + 1';
end;
$23:
begin
Reg^.HL := Reg^.HL + 1;
Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := 'HL <- HL + 1';
end;
$33:
begin
Reg^.SP := Reg^.SP + 1;
Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := 'SP <- SP + 1';
end;
$0B:
begin
Reg^.BC := Reg^.BC - 1;
Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := 'BC <- BC - 1';
end;
$1B:
begin
Reg^.DE := Reg^.DE - 1;
Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := 'DE <- DE - 1';
end;
$2B:
begin
Reg^.HL := Reg^.HL - 1;
Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := 'HL <- HL - 1';
end;
$3B:
begin
Reg^.SP := Reg^.SP - 1;
Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := 'SP <- SP - 1';
end;
end;
end;

procedure TK580MP.JMP(Addr: Word);
begin
Reg^.PC := Addr;
end;

procedure TK580MP.CALL(Addr: Word);
begin
Reg^.SP := Reg^.SP - 2;
SetWordToMem(Reg^.SP, Word(Reg^.PC + 3));
Reg^.PC := Addr;
end;

procedure TK580MP.RET;
begin
Reg^.PC := GetWordFromMem(Reg^.SP);
Reg^.SP := Reg^.SP + 2
end;

procedure TK580MP.JmpTrace;
begin
case Mem[Reg^.PC] of
$E9:
begin
Reg^.PC := Reg^.HL;
CmdInfo^.Contents := 'PC <- HL';
end;
$C3:
begin
JMP(GetData16Addr);
CmdInfo^.Contents := 'PC <- addr';
end;
$DA:
begin
if GetCY = 1
then JMP(GetData16Addr)
else Reg^.PC := Reg^.PC + 3;
CmdInfo^.Contents := 'Если CY = 1, то JMP addr';
end;
$D2:
begin
if GetCY = 0
then JMP(GetData16Addr)
else Reg^.PC := Reg^.PC + 3;
CmdInfo^.Contents := 'Если CY = 0, то JMP addr';
end;
$CA:
begin
if GetZ = 1
then JMP(GetData16Addr)
else Reg^.PC := Reg^.PC + 3;
CmdInfo^.Contents := 'Если Z = 1, то JMP addr';
end;
$C2:
begin
if GetZ = 0
then JMP(GetData16Addr)
else Reg^.PC := Reg^.PC + 3;
CmdInfo^.Contents := 'Если Z = 0, то JMP addr';
end;
$FA:
begin
if GetM = 1
then JMP(GetData16Addr)
else Reg^.PC := Reg^.PC + 3;
CmdInfo^.Contents := 'Если M = 1, то JMP addr';
end;
$F2:
begin
if GetM = 0
then JMP(GetData16Addr)
else Reg^.PC := Reg^.PC + 3;
CmdInfo^.Contents := 'Если M = 0, то JMP addr';
end;
$EA:
begin
if GetP = 1
then JMP(GetData16Addr)
else Reg^.PC := Reg^.PC + 3;
CmdInfo^.Contents := 'Если P = 1, то JMP addr';
end;
$E2:
begin
if GetP = 0
then JMP(GetData16Addr)
else Reg^.PC := Reg^.PC + 3;
CmdInfo^.Contents := 'Если P = 0, то JMP addr';
end;
$CD:
begin
CALL(GetData16Addr);
CmdInfo^.Contents := '-(SP) <- PC <- addr';
end;
$DC:
begin
if GetCY = 1
then CALL(GetData16Addr)
else Reg^.PC := Reg^.PC + 3;
CmdInfo^.Contents := 'Если CY = 1, то CALL addr';
end;
$D4:
begin
if GetCY = 0
then CALL(GetData16Addr)
else Reg^.PC := Reg^.PC + 3;
CmdInfo^.Contents := 'Если CY = 0, то CALL addr';
end;
$CC:
begin
if GetZ = 1
then CALL(GetData16Addr)
else Reg^.PC := Reg^.PC + 3;
CmdInfo^.Contents := 'Если Z = 1, то CALL addr';
end;
$C4:
begin
if GetZ = 0
then CALL(GetData16Addr)
else Reg^.PC := Reg^.PC + 3;
CmdInfo^.Contents := 'Если Z = 0, то CALL addr';
end;
$FC:
begin
if GetM = 1
then CALL(GetData16Addr)
else Reg^.PC := Reg^.PC + 3;
CmdInfo^.Contents := 'Если M = 1, то CALL addr';
end;
$F4:
begin
if GetM = 0
then CALL(GetData16Addr)
else Reg^.PC := Reg^.PC + 3;
CmdInfo^.Contents := 'Если M = 0, то CALL addr';
end;
$EC:
begin
if GetP = 1
then CALL(GetData16Addr)
else Reg^.PC := Reg^.PC + 3;
CmdInfo^.Contents := 'Если P = 1, то CALL addr';
end;
$E4:
begin
if GetP = 0
then CALL(GetData16Addr)
else Reg^.PC := Reg^.PC + 3;
CmdInfo^.Contents := 'Если P = 0, то CALL addr';
end;
$C9:
begin
RET;
CmdInfo^.Contents := 'PC <- (SP)+';
end;
$D8:
begin
if GetCY = 1
then RET
else Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := 'Если CY = 1, то RET addr';
end;
$D0:
begin
if GetCY = 0
then RET
else Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := 'Если CY = 0, то RET addr';
end;
$C8:
begin
if GetZ = 1
then RET
else Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := 'Если Z = 1, то RET addr';
end;
$C0:
begin
if GetZ = 0
then RET
else Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := 'Если Z = 0, то RET addr';
end;
$F8:
begin
if GetM = 1
then RET
else Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := 'Если M = 1, то CALL addr';
end;
$F0:
begin
if GetM = 0
then RET
else Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := 'Если M = 0, то RET addr';
end;
$E8:
begin
if GetP = 1
then RET
else Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := 'Если P = 1, то RET addr';
end;
$E0:
begin
if GetP = 0
then RET
else Reg^.PC := Reg^.PC + 3;
CmdInfo^.Contents := 'Если P = 0, то RET addr';
end;
end;
end;

procedure TK580MP.MPTrace;
var
NNN: Byte;
begin
case Mem[Reg^.PC] of
$DB:
begin
Reg^.A := Ports[GetDataPort];
Reg^.PC := Reg^.PC + 2;
CmdInfo^.Contents := 'A <- IOSEG(port)';
end;
$D3:
begin
Ports[GetDataPort] := Reg^.A;
Reg^.PC := Reg^.PC + 2;
CmdInfo^.Contents := 'IOSEG(port) <- A';
end;
$C7, $CF, $D7, $DF, $E7, $EF, $F7, $FF:
begin
if GetInt
then
begin
NNN := (Mem[Reg^.PC] and $38) shr 3;
Reg^.SP := Reg^.SP - 1;
Mem[Reg^.SP] := Reg^.PC;
Reg^.PC := 8 * NNN;
CmdInfo^.Contents := '-(SP) <- PC <- 8*n';
end
else
begin
Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := 'Прерывания запрещены';
end;
end;
$FB:
begin
Int^ := True;
Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := 'Разрешение прерываний';
end;
$F3:
begin
Int^ := False;
Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := 'Запрет прерываний';
end;
$76:
begin
SetRun(False);
Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := 'Останов';
end;
$00:
begin
Reg^.PC := Reg^.PC + 1;
CmdInfo^.Contents := 'Нет операции';
end;
end;
end;

procedure TK580MP.TraceProg;
begin
DefaultTrace;
case Mem[Reg^.PC] of
$40..$75, $77..$7F,
$06, $0E, $16, $1E, $26, $2E, $3E,
$36, $3A, $32, $0A, $1A, $02, $12, $01, $21, $31, $2A, $22, $F9,
$C5, $D5, $E5, $F5, $C1, $D1, $E1, $F1, $EB, $E3:
ExchangeTrace;
$A0..$BF,
$E6, $EE, $F6, $FE, $07, $0F, $17, $1F, $2F, $3F, $37:
LogicTrace;
$80..$9F,
$C6, $CE, $D6, $DE,
$04, $0C, $14, $1C, $24, $2C, $3C, $05, $0D, $15, $1D, $25, $2D, $3D,
$34, $35, $27, $09, $19, $29, $39, $03, $13, $23, $33, $0B, $1B, $2B, $3B:
ArifhmTrace;
$E9, $C3, $DA, $D2, $CA, $C2, $FA, $F2, $EA, $E2,
$CD, $DC, $D4, $CC, $C4, $FC, $F4, $EC, $E4, $C9,
$D8, $D0, $C8, $C0, $F8, $F0, $E8, $E0:
JmpTrace;
$DB, $D3, $FB, $F3, $76, $00,
$C7, $CF, $D7, $DF, $E7, $EF, $F7, $FF:
MPTrace;
end;
RegGrid.Repaint;
PCSPGrid.Repaint;
MemGrid.Repaint;
PortsGrid.Repaint;
IntStatus.Text := GetIntString;
RezStrings.Add(GetRezString);
Terminate;
end;

procedure TK580MP.RunProg;
begin
DefaultTrace;
case Mem[Reg^.PC] of
$40..$75, $77..$7F,
$06, $0E, $16, $1E, $26, $2E, $3E,
$36, $3A, $32, $0A, $1A, $02, $12, $01, $21, $31, $2A, $22, $F9,
$C5, $D5, $E5, $F5, $C1, $D1, $E1, $F1, $EB, $E3:
ExchangeTrace;
$A0..$BF,
$E6, $EE, $F6, $FE, $07, $0F, $17, $1F, $2F, $3F, $37:
LogicTrace;
$80..$9F,
$C6, $CE, $D6, $DE,
$04, $0C, $14, $1C, $24, $2C, $3C, $05, $0D, $15, $1D, $25, $2D, $3D,
$34, $35, $27, $09, $19, $29, $39, $03, $13, $23, $33, $0B, $1B, $2B, $3B:
ArifhmTrace;
$E9, $C3, $DA, $D2, $CA, $C2, $FA, $F2, $EA, $E2,
$CD, $DC, $D4, $CC, $C4, $FC, $F4, $EC, $E4, $C9,
$D8, $D0, $C8, $C0, $F8, $F0, $E8, $E0:
JmpTrace;
$DB, $D3, $FB, $F3, $76, $00,
$C7, $CF, $D7, $DF, $E7, $EF, $F7, $FF:
MPTrace;
end;
RegGrid.Repaint;
PCSPGrid.Repaint;
MemGrid.Repaint;
PortsGrid.Repaint;
IntStatus.Text := GetIntString;
RezStrings.Add(GetRezString);
if not GetRun
then Terminate;
end;

end.





ThrdUnit.pas
unit ThrdUnit;

interface

uses Classes, Controls, ComCtrls, AsmUnit, MPUnit;

type

TMPThread = class(TThread)
private
// RegGrid: TWinControl;
// PCSPGrid: TWinControl;
// MemGrid: TWinControl;
// PortsGrid: TWinControl;
// RunStatus: TStatusPanel;
// IntStatus: TStatusPanel;
// RezMemo: TMemo;
// Trace: Boolean;
{ Private declarations }
protected
MicroProc: TK580MP;
procedure DoWork;
procedure Execute; override;
{ Protected declarations }
public
constructor Create(PReg: PK580Regs; PMem: PByteList; PPorts: PByteList;
PRun: PBoolean; PInt: PBoolean; PComandInfo: PCmdInfo);
// PRegGrid: TWinControl; PPCSPGrid: TWinControl;
// PMemGrid: TWinControl; PPortsGrid: TWinControl;
// PRunStatus: TStatusPanel; PIntStatus: TStatusPanel;
// PRezStrings: TStrings; TraceRun: Boolean);
{ Public declarations }
end;

implementation

constructor TMPThread.Create(PReg: PK580Regs; PMem: PByteList; PPorts: PByteList;
PRun: PBoolean; PInt: PBoolean; PComandInfo: PCmdInfo);
// PRegGrid: TWinControl; PPCSPGrid: TWinControl;
// PMemGrid: TWinControl; PPortsGrid: TWinControl;
// PRunStatus: TStatusPanel; PIntStatus: TStatusPanel;
// PRezMemo: TMemo; TraceRun: Boolean);
begin
inherited Create(False);
MicroProc.Create(PReg, PMem, PPorts, PRun, PInt, PComandInfo);
// RegGrid := PRegGrid;
// PCSPGrid := PPCSPGrid;
// MemGrid := PMemGrid;
// PortsGrid := PPortsGrid;
// RunStatus := PRunStatus;
// IntStatus := PIntStatus;
// RezMemo := PRezMemo;
// Trace := TraceRun;
FreeOnTerminate := True;
end;

procedure TMPThread.DoWork;
begin
MicroProc.TraceProg;
// RegGrid.Repaint;
// PCSPGrid.Repaint;
// MemGrid.Repaint;
// PortsGrid.Repaint;
// RunStatus.Text := MicroProc.GetRunString;
// IntStatus.Text := MicroProc.GetIntString;
// RezMemo.Lines.Ad
Опубликовал Kest December 01 2009 13:22:18 · 0 Комментариев · 65535 Прочтений · Для печати

• Не нашли ответ на свой вопрос? Тогда задайте вопрос в комментариях или на форуме! •


Комментарии
Нет комментариев.
Добавить комментарий
Имя:



smiley smiley smiley smiley smiley smiley smiley smiley smiley
Запретить смайлики в комментариях

Введите проверочный код:* =
Рейтинги
Рейтинг доступен только для пользователей.

Пожалуйста, залогиньтесь или зарегистрируйтесь для голосования.

Нет данных для оценки.
Гость
Имя

Пароль



Вы не зарегистрированны?
Нажмите здесь для регистрации.

Забыли пароль?
Запросите новый здесь.
Поделиться ссылкой
Фолловь меня в Твиттере! • Смотрите канал о путешествияхКак приготовить мидии в тайланде?
Загрузки
Новые загрузки
iChat v.7.0 Final...
iComm v.6.1 - выв...
Visual Studio 200...
CodeGear RAD Stud...
Шаблон для новост...

Случайные загрузки
Blobs [Исходник н...
Domen Name IP
NetGraph [Исходни...
oTextrackBar
Система баннеро...
Еext Editor
CS:Source - монит...
Программа рисует ...
Программирование ...
PDA версия сайта
Mass Photo Upload
Info
Добавление басса ...
Рисование PopupMenu
Основы программир...
Популярные загрузки
Zoom [Исходник на...
CoolControls v3.0...
Последние загруж...
Расширенный загру...

Топ загрузок
Приложение Клие... 100771
Delphi 7 Enterp... 97788
Converter AMR<-... 20259
GPSS World Stud... 17014
Borland C++Buil... 14186
Borland Delphi ... 10267
Turbo Pascal fo... 7372
Калькулятор [Ис... 5968
Visual Studio 2... 5205
Microsoft SQL S... 3661
Случайные статьи
League for Program...
Некоторые встроенн...
ДЫРЯВЫЕ АБСТРАКЦИИ
Построение символь...
Эпилог ко второму ...
ИЗЯЩНОЕ ВОССТАНОВЛ...
Ассортимент игрово...
Безопасный и удобн...
Гостевая книга шаг...
Играйте в игровые ...
Клуб Вулкан онлайн...
БЛУЖДАНИЯ БЕЗ ОРИЕ...
Типы данных. Общие...
EAV (ОБЪЕКТ-АТРИБУ...
Как узнать свой снилс
6.5. Создание стр...
10 основных способ...
Программа выводит ...
Многопоточные очереди
НЕ ВСЕГДА БАЗА ДАН...
Стандарты программ...
Вызов кодов драйвера
Этап 3 - сколемизация
Краткий обзор пото...
Новый шаблон прави...
Статистика



Друзья сайта
Программы, игры


Полезно
В какую объединенную сеть входит классовая сеть? Суммирование маршрутов Занимают ли таблицы память маршрутизатора?