Скачиваний:
19
Добавлен:
03.06.2014
Размер:
296.45 Кб
Скачать

4. Структура выводов кристаллов

  • AD – совмещенная шина адреса и данных;

  • ALE – сигналALE используется для фиксации адреса на внешнем регистре – защелке;

  • HLD – запрос прямого доступа;

  • HLDA – подверждение прямого доступа;

  • INT – 16 входов запросов на прерывание;

  • INTA – подтверждение запроса на прерывание;

  • RD,WR – линии управляют чтением и записью в память;

  • IN,OUT – линии для управлением чтением и записью в порт;

  • СС0, СС1 – линии служат для сихронизации работыCPU и FPA

(00 нет операций, 01 выборкаданных, 10 запись команды в буфер, 11 запись данных);

  • WAIT – устанавливается в 1, когда сопроцессор закончил вычисления;

  • RESET –сигнал сброса;

  • CLC – синхронизация;

  • FPINT – прерывание особой ситуации сопроцессора;

  • FPBUSY – сигнал занятости сопроцессора.

5. Временные диаграммы выполнения основных операций на шине

Чтение из памяти.

Чтение из порта.

Запись в память.

Запись в порт.

Прерывание.

Захват шины.

Чтение блоками из памяти.

Запись блоками в память.

Запись команды в сопроцессор.

Команда передается из ЦП в сопроцессор частями. В такты 2, 3 передаются биты команды с 16 по 31, в такты 4, 5 передаются первые шестнадцать бит команды.

Выборка данных из сопроцессора и запись данных в сопроцессор.

Данные разбиваются на четыре группы и пересылаются по шине адреса-данных начиная со старших разрядов.

6. Описание функционирования автоматов

Исполнительный автомат.

7. Текст программы - модели процессора (Borland C++Builder)

#include <vcl\vcl.h>

#include <io.h>

#include <fcntl.h>

#include <limits.h>

#include "RISCMAIN.h"

#include "Contens.h"

#include "Register.h"

#include "Progcode.h"

#include "About.h"

#pragma hdrstop

#pragma link "Grids"

#pragma resource "*.dfm"

#define E(X) X->Enabled = true;

#define D(X) X->Enabled = false;

TForm1 *Form1;

__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { }

HINSTANCE MemManager;

char *Command[]={

"LB", "Прочитать байт", "REC <- <SR1+Imm>",

"LBU", "Прочитать байт без знака", "REC <- <SR1+Imm>",

"LW", "Прочитать слово", "REC <- <SR1+Imm>",

"LWU", "Прочитать слово без знака", "REC <- <SR1+Imm>",

"LDW", "Прочитать двойное слово", "REC <- <SR1+Imm>",

"SDW", "Записать двойное слово", "<SR1+Imm> <- SR2",

"SW", "Записать слово", "<SR1+Imm> <- SR2",

"SB", "Записать байт", "<SR1+Imm> <- SR2",

"ADD", "Сложение", "REC <- SR1+SR2",

"ADDC", "Сложение с переносом", "REC <- SR1+SR2",

"SUB", "Вычитание", "REC <- SR1-SR2",

"SUBB", "Вычитание с заемом", "REC <- SR1-SR2",

"MUL", "Беззнаковое умножение", "SR3 : REC <- SR1*SR2",

"MULS", "Умножение со знаком", "SR3 : REC <- SR1*SR2",

"DDIV", "Беззнаковое деление", "REC <- SR3 : SR1/SR2",

"DDIVS","Деление со знаком", "REC <- SR3 : SR1/SR2",

"DIV", "Беззнаковое деление", "REC <- SR1/SR2",

"DIVS", "Деление со знаком", "REC <- SR1/SR2",

"AND", "Логическое И", "REC <- SR1 & SR2",

"OR", "Логическое ИЛИ", "REC <- SR1 OR SR2",

"XOR", "Логическое Исключающее ИЛИ", "REC <- SR1 XOR SR2",

"NOR", "НЕ-ИЛИ", "REC <- NOT(SR1 OR SR2)",

"SLL", "Логический сдвиг влево на Imm и на SR2", "",

"SAL", "Арифметический сдвиг влево на Imm и на SR2", "",

"SLR", "Логический сдвиг вправо на Imm и на SR2", "",

"SAR", "Арифметический сдвиг вправо на Imm и на SR2", "",

"MOV", "Переслать данные", "REC <- SR1",

"MOVL", "Записать Imm в четверть, определяемую P, нижнюю половину (биты 0-31) REC", "REC <- Imm",

"MOVH", "Записать Imm в четверть, определяемую P, верхнюю половину (биты 32-63) REC", "REC <- Imm",

"J", "Переход, код условия задается вместо REC", "PC <- SR1",

"JI", "Относительный переход", "PC <- PC+Imm",

"IN", "Прочитать значение из порта SR1 в регистр REC", "",

"OUT", "Записать в порт SR1 значение из SR2", "",

"MFFL", "Прочитать состояние регистра флажков", "REC <- FL",

"MTFL", "Записать состояние регистра флажков", "FL <- SR1",

"LTR", "Загрузить указатель на TSS текущей задачи по адресу SR1", "<SR1> <- TSS",

"LIDT", "Загрузить указатель на таблицу дескрипторов прерывания (IDT) из SR1", "IDT <- SR1",

"OTSS", "Записывает в REC TSS задачи, работающей перед текущей", "REC <- TSS",

"EAR", "Прочитать неправильный адрес виртуальной памяти", "REC <- EA",

"WAIT", "Ожидать завершения вычисления сопроцессора", "",

"INT", "Вызов прерывания", ""}, *Flags[]={

"-","-","-","-","-","-","-","17",

"-","-","-","-","-","-","-","",

"-","-","-","-","-","-","-","",

"-","-","-","-","-","-","-","",

"-","-","-","-","-","-","-","",

"-","-","-","-","-","-","-","",

"-","-","-","-","-","-","-","",

"-","-","-","-","-","-","-","24",

"+","+","+","+","-","-","-","03",

"+","?+","+","+","-","-","-","04",

"+","+","+","+","-","-","-","05",

"+","?+","+","+","-","-","-","06",

"+","+","+","+","-","-","-","07",

"+","+","+","+","-","-","-","",

"+","+","+","+","-","-","-","",

"+","+","+","+","-","-","-","",

"+","+","+","+","-","-","-","",

"+","+","+","+","-","-","-","",

"+","0","+","0","-","-","-","13",

"+","0","+","0","-","-","-","14",

"+","0","+","0","-","-","-","15",

"+","0","+","0","-","-","-","16",

"+","+","+","-","-","-","-","",

"+","+","+","-","-","-","-","",

"+","+","+","-","-","-","-","",

"+","+","+","-","-","-","-","",

"-","-","-","-","-","-","-","02",

"-","-","-","-","-","-","-","00",

"-","-","-","-","-","-","-","01",

"?","?","?","?","-","+","-","",

"?","?","?","?","-","-","-","",

"-","-","-","-","-","1","-","",

"-","-","-","-","-","1","-","",

"?","?","?","?","?","?","-","",

"+","+","+","+","+","?+","-","",

"-","-","-","-","-","1","-","",

"-","-","-","-","-","1","-","",

"-","-","-","-","-","1","-","",

"-","-","-","-","-","1","-","",

"-","-","-","-","-","-","-","",

"-","-","-","+","+","-","-",""}, q[2];

void __fastcall TForm2::FormActivate(TObject *Sender)

{ int i;

Button1->Left = Width / 2 + 162;

StringGrid1->Cells[0][0] = "№";

StringGrid1->Cells[1][0] = "Мнемоника";

StringGrid1->Cells[2][0] = "Название";

StringGrid1->Cells[3][0] = "Содержание";

StringGrid1->Cells[4][0] = "Z";

StringGrid1->Cells[5][0] = "C";

StringGrid1->Cells[6][0] = "S";

StringGrid1->Cells[7][0] = "O";

StringGrid1->Cells[8][0] = "I";

StringGrid1->Cells[9][0] = "T";

StringGrid1->Cells[10][0] = "U";

StringGrid1->Cells[11][0] = "Код";

for (i=0; i<123; i+=3)

{ sprintf(q, " %d", (i+1)/3+1);

StringGrid1->Cells[0][(i+1)/3+1] = q;

StringGrid1->Cells[1][(i+1)/3+1] = Command[i];

StringGrid1->Cells[2][(i+1)/3+1] = Command[i+1];

StringGrid1->Cells[3][(i+1)/3+1] = Command[i+2];

}

for (i=0; i<328; i+=8)

{ StringGrid1->Cells[4][(i+1)/8+1] = Flags[i];

StringGrid1->Cells[5][(i+1)/8+1] = Flags[i+1];

StringGrid1->Cells[6][(i+1)/8+1] = Flags[i+2];

StringGrid1->Cells[7][(i+1)/8+1] = Flags[i+3];

StringGrid1->Cells[8][(i+1)/8+1] = Flags[i+4];

StringGrid1->Cells[9][(i+1)/8+1] = Flags[i+5];

StringGrid1->Cells[10][(i+1)/8+1] = Flags[i+6];

StringGrid1->Cells[11][(i+1)/8+1] = Flags[i+7];

}

}

void __fastcall TForm2::FormResize(TObject *Sender)

{ Button1->Left = Width / 2 + 162; }

void __fastcall TForm2::Button1Click(TObject *Sender)

{ Close(); }

class Register

{ private:

char HexValue[17];// 64-битное значение регистра (Hex)

__int64 DecValue; // 64-битное значение регистра (Dec)

public:

__fastcall Register() {};

__fastcall ~Register() {};

void __fastcall Clear(void); // Очистка регистра

void __fastcall ShowReg(int, int, int, TStringGrid*);// Показать содержимое регистра

void __fastcall ShowReg1(int, int, int, TStringGrid*);

void __fastcall LoadReg(unsigned __int64, int); // Загрузить регистр значением

void __fastcall CopyReg(Register); // Копировать значение одного регистра в другой

char* __fastcall GetHexValue(void); // Значение регистра (Hex)

__int64 __fastcall GetDecValue(int); // Значение регистра (Dec)

};

class CPU_Command

{ private:

char BinV[33]; // Двоичное представление команды

char c[30]; // Текстовое представление команды

char *ptr;

int CCode; // Код команды

public:

__fastcall CPU_Command() {};

__fastcall ~CPU_Command() {};

int __fastcall TranslateCommand(char*); // Трансляция команды (в bin-виде)

int __fastcall RegNumber(char*); // Номер регистра

int __fastcall ARegNumber(char*); // Номер регистра (в команде обращения к памяти)

int __fastcall ImmNumber(char*); // Непосредственный операнд

int __fastcall AImmNumber(char*); // Непосредственный операнд (в команде обращения к памяти)

void __fastcall TextCom(char, int);

char __fastcall TextCom(int);

char* __fastcall TextCom(void); // Текст команды

char* __fastcall Mnemonics(char*); // Выделение мнемоники из команды

char* __fastcall ComCode(void); // Команда в bin-коде

void __fastcall Code(int, int, int);

void __fastcall Execute(TStringGrid*, TStringGrid*, TStringGrid*, TRadioGroup*, TCheckBox*);

};

CPU_Command Com[100];// Максимум - программа из 100 команд

Register Reg[64]; // 32 регистра CPU и 32 регистра FPU

int CurCom, NumCom; // Номер текущей команды и число команд

char FN[100], b[100];

char StatusFlag[7], FPA_Flag[7];// Флаги: Status - Z,C,S,O,I,T,U

// FPA - B,Z,S,O,I,RC

typedef short int (__stdcall *write_byte)(unsigned long, char);

typedef char (__stdcall *read_byte)(unsigned long);

#define SaveByte(Address, Val)\

((write_byte)GetProcAddress(MemManager, "WriteByte"))(Address, Val);

#define LoadByte(Address)\

((read_byte)GetProcAddress(MemManager, "ReadByte"))(Address);

#define _Caption\

sprintf(b, "RISC CPU Modeling 1.01 - %s", FN);\

Caption = b;

// Очистка регистра

void __fastcall Register::Clear(void)

{ int i;

for (DecValue = i = 0; i < 16; i++)

HexValue[i] = '0';

}

// Показать содержимое регистра

void __fastcall Register::ShowReg(int n, int d, int s, TStringGrid *a)

{ char x[21];

if (d) // Dec

{ if (s) // Signed

sprintf(x, "%Ld", DecValue);

else // Unsigned

sprintf(x, "%Lu", DecValue);

a->Cells[1][n%32+1] = x;

}

else // Hex

a->Cells[1][n%32+1] = HexValue;

}

// Загрузить регистр значением

void __fastcall Register::LoadReg(unsigned __int64 x, int f)

{ int i;

char a[16] = {"0123456789ABCDEF"}, b;

for (i = 15; i >= 0; i--)

{ b = a[(int)(x % 16)];

HexValue[i] = f? (b == '0'? HexValue[i]: b): b;

x >>= 4;

}

DecValue = GetDecValue(64);

}

// Значение регистра (Hex)

char* __fastcall Register::GetHexValue(void)

{ return HexValue; }

// Вычисление функции 16^x

unsigned __int64 __fastcall F3(int x)

{ unsigned __int64 p = 1;

for (int i=0; i<x; i++)

p *= 16;

return p;

}

// Преобразование Hex -> Dec

int __fastcall HexDec(char s)

{ int p;

switch (s)

{ case '0': p = 0; break;

case '1': p = 1; break;

case '2': p = 2; break;

case '3': p = 3; break;

case '4': p = 4; break;

case '5': p = 5; break;

case '6': p = 6; break;

case '7': p = 7; break;

case '8': p = 8; break;

case '9': p = 9; break;

case 'A': p = 10; break;

case 'B': p = 11; break;

case 'C': p = 12; break;

case 'D': p = 13; break;

case 'E': p = 14; break;

case 'F': p = 15;

}

return p;

}

// Значение регистра (Dec) с заданным числом бит

__int64 __fastcall Register::GetDecValue(int NumberOfBits)

{ __int64 v = 0;

for (int i=0; i < (NumberOfBits >> 2); i++)

v += (unsigned __int64)(HexDec(HexValue[15 - i]) * F3(i));

return v;

}

// Копировать значение регистра Source в регистр Target

void __fastcall Register::CopyReg(Register Source)

{ for (int i=0; i<16; i++)

HexValue[i] = Source.GetHexValue()[i];

DecValue = Source.GetDecValue(64);

}

int __fastcall F(int x, int n, int f)

{ int a, i, k=0;

for (i=f; i>0; i>>=1, k++)

if (x == i)

{ a = n + k;

break;

}

return a;

}

void __fastcall CPU_Command::TextCom(char s, int x)

{ c[x] = s;

}

char __fastcall CPU_Command::TextCom(int x)

{ return c[x];

}

char* __fastcall CPU_Command::TextCom(void)

{ return c;

}

// Выделение мнемоники из команды

char* __fastcall CPU_Command::Mnemonics(char *c)

{ char *s;

int i;

ptr = c;

s = new char[6];

for (i=0; i<6; i++)

{ s[i] = *(ptr++);

if (s[i] == ' ')

{ s[i] = 0;

break;

}

}

if (i==6)

return NULL;

return s;

}

void __fastcall CPU_Command::Code(int c, int n, int f)

{ int i;

switch (f)

{ case 1: f = 2; break;

case 4: f = 16; break;

case 5: f = 32; break;

case 7: f = 128; break;

case 9: f = 512; break;

case 14: f = 16384;

}

for (i=f; i>0; i>>=1)

{ BinV[F(i,n,f)] = (char)(48+c/i);

c %= i;

}

}

// Номер регистра

int __fastcall CPU_Command::RegNumber(char *c)

{ char s[20];

int j, i = 0;

while(*ptr != 'R')

{ if (*ptr != ' ')

return -1;

ptr++;

}

ptr++;

do

s[i++] = *(ptr++);

while(s[i-1] != ',' && s[i-1] != ':' && s[i-1]);

s[--i] = 0;

for (j = 0; j < i; j++)

if (s[j] != ' ' && (s[j] < '0' || s[j] > '9'))

return -1;

return atoi(s);

}

// Номер регистра (в команде обращения к памяти)

int __fastcall CPU_Command::ARegNumber(char *c)

{ char s[20];

int j, i = 0;

while(*ptr != 'R')

{ if (*ptr != ' ' && *ptr != '(')

return -1;

ptr++;

}

ptr++;

do

s[i++] = *(ptr++);

while(s[i-1] != '+' && s[i-1]);

if (s[i-1] != '+')

return -1;

s[--i] = 0;

for (j = 0; j < i; j++)

if (s[j] != ' ' && (s[j] < '0' || s[j] > '9'))

return -1;

return atoi(s);

}

// Непосредственный операнд

int __fastcall CPU_Command::ImmNumber(char *c)

{ char s[4];

int i = 0, k;

while(*ptr == ' ' || *ptr == ',')

ptr++;

while (*ptr != ' ' && *ptr != ',' && *ptr)

s[i++] = *(ptr++);

s[i]=0;

for (k=0; k<i; k++)

if (s[k]<'0' || s[k]>'9')

return -1;

return atoi(s);

}

// Непосредственный операнд (в команде обращения к памяти)

int __fastcall CPU_Command::AImmNumber(char *c)

{ char s[4];

int i = 0, k;

while(*ptr == ' ' || *ptr == '+')

ptr++;

while (*ptr != ' ' && *ptr != ')' && *ptr)

s[i++] = *(ptr++);

s[i]=0;

while (*ptr != ',' && *ptr)

ptr++;

ptr++;

for (k=0; k<i; k++)

if (s[k]<'0' || s[k]>'9')

return -1;

return atoi(s);

}

#define CheckRegisterRange if (x<0 || x>31) return 1;

#define CODE(Q) y = 1; CCode = Q; Code(CCode,1,5); BinV[0] = '0';

// Трансляция команды (в bin-виде)

int __fastcall CPU_Command::TranslateCommand(char *c)

{ char *s;

int x, y = 0;

s = Mnemonics(c);

if (!s)

return 1;

if (!strcmp(s, "movl")) // ------------------ movl

{ CODE(0)

x = RegNumber(c);

CheckRegisterRange

Code(x,7,4);

Code(0,12,4);

Code(0,17,4);

x = ImmNumber(c);

if (x<0 || x>255)

return 1;

Code(x,24,7);

x = ImmNumber(c);

if (x<0 || x>3)

return 1;

Code(x,22,1);

}

if (!strcmp(s, "movh")) // ------------------ movh

{ CODE(1)

x = RegNumber(c);

CheckRegisterRange

Code(x,7,4);

Code(0,12,4);

Code(0,17,4);

x = ImmNumber(c);

if (x<0 || x>255)

return 1;

Code(x,24,7);

x = ImmNumber(c);

if (x<0 || x>3)

return 1;

Code(x,22,1);

}

if (!strcmp(s, "mov")) // ------------------ mov

{ CODE(2)

x = RegNumber(c);

CheckRegisterRange

Code(x,7,4);

x = RegNumber(c);

CheckRegisterRange

Code(x,12,4);

Code(0,17,14);

} // -------- add, addc

if (!strcmp(s, "add") || !strcmp(s, "addc"))

{ CODE(!strcmp(s, "add")? 3: 4)

x = RegNumber(c);

CheckRegisterRange

Code(x,7,4);

x = RegNumber(c);

CheckRegisterRange

Code(x,12,4);

x = RegNumber(c);

CheckRegisterRange

Code(x,17,4);

Code(0,22,9);

} // -------- sub, subb

if (!strcmp(s, "sub") || !strcmp(s, "subb"))

{ CODE(!strcmp(s, "sub")? 5: 6)

x = RegNumber(c);

CheckRegisterRange

Code(x,7,4);

x = RegNumber(c);

CheckRegisterRange

Code(x,12,4);

x = RegNumber(c);

CheckRegisterRange

Code(x,17,4);

Code(0,22,9);

}

if (!strcmp(s, "mul")) // ------------------ mul

{ CODE(7)

x = RegNumber(c);

CheckRegisterRange

Code(x,22,4);

x = RegNumber(c);

CheckRegisterRange

Code(x,7,4);

x = RegNumber(c);

CheckRegisterRange

Code(x,12,4);

x = RegNumber(c);

CheckRegisterRange

Code(x,17,4);

Code(0,27,4);

} // ------------------ and, or, xor, nor

if (!strcmp(s, "and") || !strcmp(s, "or") || !strcmp(s, "xor") || !strcmp(s, "nor"))

{ CODE(!strcmp(s, "and")? 13: !strcmp(s, "or")? 14: !strcmp(s, "xor")? 15: 16);

x = RegNumber(c);

CheckRegisterRange

Code(x,7,4);

x = RegNumber(c);

CheckRegisterRange

Code(x,12,4);

x = RegNumber(c);

CheckRegisterRange

Code(x,17,4);

Code(0,22,9);

}

if (!strcmp(s, "sb")) // ------------------ sb

{ CODE(24)

Code(0,7,4);

x = ARegNumber(c);

CheckRegisterRange

Code(x,12,4);

x = AImmNumber(c);

if (x<0 || x>1023)

return 1;

Code(x,22,9);

x = RegNumber(c);

CheckRegisterRange

Code(x,17,4);

}

if (!strcmp(s, "lb")) // ------------------ lb

{ CODE(17)

x = RegNumber(c);

CheckRegisterRange

Code(x,7,4);

x = ARegNumber(c);

CheckRegisterRange

Code(x,12,4);

Code(0,17,4);

x = AImmNumber(c);

if (x<0 || x>1023)

return 1;

Code(x,22,9);

}

if (!y)

return 1;

BinV[32] = 0;

return 0;

}

// Команда в bin-коде

char* __fastcall CPU_Command::ComCode(void)

{ return BinV;

}

// Вычисление функции 2^x

unsigned long __fastcall F1(int x)

{ unsigned long p = 1L;

int i;

for (i=0; i<x; i++)

p *= 2L;

return p;

}

// Сохранить текст RISC CPU программы

void __fastcall TForm1::SaveButtonClick(TObject *Sender)

{ if (strcmp(OpenDialog1->FileName.c_str(), ""))

Memo1->Lines->SaveToFile(OpenDialog1->FileName);

}

// Выход из программы

void __fastcall TForm1::FileExitClick(TObject *Sender)

{ Application->Terminate();

}

void __fastcall TForm1::HelpContentsClick(TObject *Sender)

{ Form2->Button1->Left = 360 + (Form2->Width - 480) / 2;

Form2->ShowModal();

}

void __fastcall TForm1::HelpAboutClick(TObject *Sender)

{ Form5->Show();

}

void __fastcall TForm5::Button1Click(TObject *Sender)

{ Form5->Close();

}

// Загрузка текста RISC CPU программы из файла

void __fastcall TForm1::OpenButtonClick(TObject *Sender)

{ OpenDialog1->FileName = "";

OpenDialog1->Execute();

if (strcmp(OpenDialog1->FileName.c_str(), ""))

{ strcpy(FN, OpenDialog1->FileName.c_str());

_Caption

Memo1->Lines->LoadFromFile(OpenDialog1->FileName);

if (Memo1->Lines->Count)

{ E(Button4) E(TProg) E(SButton4)

}

else

{ D(Button4) D(TProg) D(SButton4)

}

}

}

// Загрузка текста RISC CPU программы из файла и ее трансляция

void __fastcall TForm1::SpeedButton1Click(TObject *Sender)

{ OpenDialog1->FileName = "";

OpenDialog1->Execute();

if (strcmp(OpenDialog1->FileName.c_str(), ""))

{ strcpy(FN, OpenDialog1->FileName.c_str());

_Caption

Memo1->Lines->LoadFromFile(OpenDialog1->FileName);

if (Memo1->Lines->Count)

{ E(Button4) E(TProg) E(SButton4)

}

else

{ D(Button4) D(TProg) D(SButton4)

}

}

Button4Click(Sender);

}

void __fastcall TForm1::Memo1Change(TObject *Sender)

{ if (Memo1->Lines->Count)

{ E(Button4) E(TProg) E(SButton4)

}

else

{ D(Button4) D(TProg) D(SButton4)

}

}

// Отобразить значения флагов

void __fastcall ShowFlags(TStringGrid *b, TStringGrid *a)

{ for (int i=0; i<13; i++)

if (i>6)

a->Cells[1][i-6] = FPA_Flag[i-6];

else

b->Cells[1][i+1] = StatusFlag[i+1];

sprintf(q, "%c%c", FPA_Flag[5], FPA_Flag[6]);

a->Cells[1][6] = q;

}

void __fastcall TForm1::FormCreate(TObject *Sender)

{ int i;

char q[4], *x[] = {"Z","C","S","O","I","T","U","B","Z","S","O","I","RC"};

MemManager = LoadLibrary("memman.dll");

if(!MemManager)

{ MessageBox(NULL, "MEMMAN.DLL not found!", "Error", 0);

Application->Terminate();

}

else

GetProcAddress(MemManager, "InitialMemory")();

strcpy(StatusFlag, "0000000");

strcpy(FPA_Flag, "0000000");

StringGrid1->Cells[0][0] = " R";

StringGrid2->Cells[0][0] = " R";

StringGrid1->Cells[1][0] = " Value";

StringGrid2->Cells[1][0] = " Value";

for (i=0; i<64; i++)

{ sprintf(q, "%2d", i);

if (i>31)

StringGrid2->Cells[0][i-31] = q;

else

StringGrid1->Cells[0][i+1] = q;

Reg[i].Clear();

Reg[i].ShowReg(i, RadioGroup1->ItemIndex, CheckBox1->Checked, i>31? StringGrid2: StringGrid1);

}

for (i=0; i<13; i++)

if (i>6)

StringGrid4->Cells[0][i-6] = x[i];

else

StringGrid3->Cells[0][i+1] = x[i];

ShowFlags(StringGrid3, StringGrid4);

}

void __fastcall TForm4::Button1Click(TObject *Sender)

{ Close(); }

// Трансляция программы

void __fastcall TForm1::Button4Click(TObject *Sender)

{ int i, f, len, ErrorStatus;

char q[20];

CurCom = 0;

len = strlen(Memo1->Lines->Text.c_str());

for (NumCom = f = i = 0; i<len; i++)

{ Com[NumCom].TextCom(Memo1->Lines->Text.c_str()[i], f);

if (Com[NumCom].TextCom(f) == 0x0d)

{ Com[NumCom++].TextCom(0, f);

i++;

f = -1;

}

f++;

}

for (ErrorStatus = i = 0; i < NumCom; i++)

if (Com[i].TranslateCommand(Com[i].TextCom()))

{ ErrorStatus = 1;

break;

}

if (ErrorStatus) // Есть ошибка

{ sprintf(q, "Error in lines %d", i+1);

ListBox1->Clear();

Edit5->Text = q;

Edit1->Text = ""; Edit2->Text = "";

Edit3->Text = ""; Edit4->Text = "";

D(ListBox1)

D(RunF9) D(RunButton) D(Button7)

D(Button5) D(Programcode1) D(SButton5)

D(TopButton) D(FCom) D(Button6)

D(EndButton) D(LCom)

D(PreviousButton) D(BitBtn1) D(PCom)

D(NextButton) D(BitBtn2) D(NCom)

D(ExecuteButton) D(Button1) D(EC1)

}

else // Нет ошибок

{ sprintf(q, "Error not found");

Edit5->Text = q;

E(ListBox1)

ListBox1->Clear();

E(RunF9) E(RunButton) E(Button7)

E(Button5) E(Programcode1) E(SButton5)

for (i=0; i<NumCom; i++)

ListBox1->Items->Add(Com[i].TextCom());

Edit1->Text = ""; Edit3->Text = "";

Edit2->Text = Com[0].TextCom();

Edit4->Text = Com[0].ComCode();

E(ExecuteButton) E(Button1) E(EC1)

E(TopButton) E(FCom) E(Button6)

E(EndButton) E(LCom)

if (NumCom == 1)

{ D(TopButton) D(FCom) D(Button6)

D(EndButton) D(LCom)

}

if (!NumCom)

{ Edit1->Text = ""; Edit2->Text = "";

Edit3->Text = ""; Edit4->Text = "";

D(TopButton) D(FCom) D(Button6)

D(EndButton) D(LCom)

D(PreviousButton) D(BitBtn1)

D(NextButton) D(BitBtn2)

D(ExecuteButton) D(Button1) D(EC1)

}

D(PreviousButton) D(BitBtn1) D(PCom)

D(NextButton) D(BitBtn2) D(NCom)

if (NumCom > 1)

{ E(NextButton) E(BitBtn2) E(NCom)

Edit3->Text = Com[1].TextCom();

}

}

}

void __fastcall TForm1::SaveAs1Click(TObject *Sender)

{ SaveDialog1->FileName = "";

SaveDialog1->Execute();

if (strcmp(SaveDialog1->FileName.c_str(), ""))

{ Memo1->Lines->SaveToFile(SaveDialog1->FileName);

strcpy(FN, SaveDialog1->FileName.c_str());

_Caption

}

}

// Программный код

void __fastcall TForm1::Button5Click(TObject *Sender)

{ char a[4] = {0,0,0,0};

int i;

Form3->Show();

Form3->StringGrid2->RowCount = NumCom + 1;

Form3->StringGrid2->Cells[0][0] = "№";

Form3->StringGrid2->Cells[1][0] = "Program text";

Form3->StringGrid2->Cells[2][0] = "Program code";

for (i = 0; i < NumCom; i++)

{ sprintf(a, "%3d", i+1);

Form3->StringGrid2->Cells[0][i+1] = a;

Form3->StringGrid2->Cells[1][i+1] = Com[i].TextCom();

Form3->StringGrid2->Cells[2][i+1] = Com[i].ComCode();

}

}

void __fastcall TForm3::Button1Click(TObject *Sender)

{ Close();

}

// Преобразование бинарного числа в десятичное

// a - начало, n - количество бит

int F2(int a, int n, char *c)

{ int i, k = 0;

for (i=n-1; i>=0; i--)

k += (c[a++]-48)*(int)F1(i);

return k;

}

// Выполнение текущей команды

void __fastcall CPU_Command::Execute(TStringGrid *A, TStringGrid *B, TStringGrid *C, TRadioGroup *D, TCheckBox *E)

{ int REC, SR1, SR2, SR3, P, Imm;

__int64 sign;

char value;

unsigned __int64 rec, sr1, sr2, t;

unsigned long address;

long double overflow;

switch (CCode)

{ case 0: // ------------------------------------ movl

{ REC = F2(7,5,BinV);

P = F2(22,2,BinV);

Imm = F2(24,8,BinV);

Reg[REC].LoadReg(Imm << (P << 3), 1);

Reg[REC].ShowReg(REC, D->ItemIndex, E->Checked, A);

} break;

case 1: // ------------------------------------ movh

{ REC = F2(7,5,BinV);

P = F2(22,2,BinV);

Imm = F2(24,8,BinV);

Reg[REC].LoadReg((__int64)Imm << 32 << (P << 3), 1);

Reg[REC].ShowReg(REC, D->ItemIndex, E->Checked, A);

} break;

case 2: // ------------------------------------ mov

{ REC = F2(7,5,BinV);

SR1 = F2(12,5,BinV);

Reg[REC].CopyReg(Reg[SR1]);

Reg[REC].ShowReg(REC, D->ItemIndex, E->Checked, A);

} break;

case 3: // ------------------------------------ add

{ REC = F2(7,5,BinV);

SR1 = F2(12,5,BinV);

SR2 = F2(17,5,BinV);

sr1 = Reg[SR1].GetDecValue(64);

sr2 = Reg[SR2].GetDecValue(64);

rec = sr1 + sr2;

overflow = (long double) sr1 + (long double) sr2;

Reg[REC].LoadReg(rec, 0);

Reg[REC].ShowReg(REC, D->ItemIndex, E->Checked, A);

StatusFlag[1] = rec? '0': '1'; // нулевой результат (Z)

StatusFlag[4] = overflow > 18446744073709551615L? '1': '0'; // переполнение (O)

ShowFlags(B, C);

} break;

case 4: // ------------------------------------ addc

{ REC = F2(7,5,BinV);

SR1 = F2(12,5,BinV);

SR2 = F2(17,5,BinV);

sr1 = Reg[SR1].GetDecValue(64);

sr2 = Reg[SR2].GetDecValue(64);

rec = sr1 + sr2 + (__int64)(StatusFlag[2] - 48);

overflow = (long double) sr1 + (long double) sr2 + (long double)(StatusFlag[2] - 48);

Reg[REC].LoadReg(rec, 0);

Reg[REC].ShowReg(REC, D->ItemIndex, E->Checked, A);

StatusFlag[1] = rec? '0': '1'; // нулевой результат (Z)

StatusFlag[4] = overflow > 18446744073709551615L? '1': '0'; // переполнение (O)

ShowFlags(B, C);

} break;

case 5: // ------------------------------------ sub

{ REC = F2(7,5,BinV);

SR1 = F2(12,5,BinV);

SR2 = F2(17,5,BinV);

sr1 = Reg[SR1].GetDecValue(64);

sr2 = Reg[SR2].GetDecValue(64);

rec = sr1 - sr2;

sign = (__int64)sr1 - (__int64)sr2;

Reg[REC].LoadReg(rec, 0);

Reg[REC].ShowReg(REC, D->ItemIndex, E->Checked, A);

StatusFlag[1] = rec? '0': '1'; // нулевой результат (Z)

StatusFlag[3] = sign>0? '0': '1'; // знак (S)

ShowFlags(B, C);

} break;

case 6: // ------------------------------------ subb

{ REC = F2(7,5,BinV);

SR1 = F2(12,5,BinV);

SR2 = F2(17,5,BinV);

sr1 = Reg[SR1].GetDecValue(64);

sr2 = Reg[SR2].GetDecValue(64);

rec = sr1 - sr2 - (__int64)(StatusFlag[2] - 48);

sign = (__int64)sr1 - (__int64)sr2 - (__int64)(StatusFlag[2] - 48);

Reg[REC].LoadReg(rec, 0);

Reg[REC].ShowReg(REC, D->ItemIndex, E->Checked, A);

StatusFlag[1] = rec? '0': '1'; // нулевой результат (Z)

StatusFlag[3] = sign>0? '0': '1'; // знак (S)

ShowFlags(B, C);

} break;

case 7: // ------------------------------------ mul

{ REC = F2(7,5,BinV);

SR1 = F2(12,5,BinV);

SR2 = F2(17,5,BinV);

SR3 = F2(22,5,BinV);

sr1 = Reg[SR1].GetDecValue(64);

sr2 = Reg[SR2].GetDecValue(64);

rec = sr1 * sr2;

overflow = (long double) sr1 * (long double) sr2;

t = rec / F3(8);

Reg[SR3].LoadReg(t, 0);

Reg[REC].LoadReg(rec - t * F3(8), 0);

Reg[REC].ShowReg(REC, D->ItemIndex, E->Checked, A);

Reg[SR3].ShowReg(SR3, D->ItemIndex, E->Checked, A);

StatusFlag[1] = rec? '0': '1'; // нулевой результат (Z)

StatusFlag[4] = overflow > 18446744073709551615L? '1': '0'; // переполнение (O)

ShowFlags(B, C);

} break;

#define Logic1\

REC = F2(7,5,BinV);\

SR1 = F2(12,5,BinV);\

SR2 = F2(17,5,BinV);\

sr1 = Reg[SR1].GetDecValue(64);\

sr2 = Reg[SR2].GetDecValue(64);

#define Logic2\

Reg[REC].LoadReg(rec, 0);\

Reg[REC].ShowReg(REC, D->ItemIndex, E->Checked, A);\

StatusFlag[1] = rec? '0': '1'; /* нулевой результат (Z) */\

StatusFlag[2] = '0'; /* перенос из старшего разряда (C) */\

StatusFlag[4] = '0'; /* переполнение (O) */\

ShowFlags(B, C);

case 13: // ------------------------------------ and

{ Logic1

rec = sr1 & sr2;

Logic2

} break;

case 14: // ------------------------------------ or

{ Logic1

rec = sr1 | sr2;

Logic2

} break;

case 15: // -7----------------------------------- xor

{ Logic1

rec = sr1 ^ sr2;

Logic2

} break;

case 16: // ------------------------------------ nor

{ Logic1

rec = ~(sr1 | sr2);

Logic2

} break;

case 24: // ------------------------------------ sb

{ SR1 = F2(12,5,BinV);

SR2 = F2(17,5,BinV);

Imm = F2(22,10,BinV);

sr1 = Reg[SR1].GetDecValue(32);

sr2 = Reg[SR2].GetDecValue(8);

value = (char)sr2;

address = (unsigned long)((unsigned __int64)Imm + sr1);

SaveByte(address, value);

} break;

case 17: // ------------------------------------ lb

{ REC = F2(7,5,BinV);

SR1 = F2(12,5,BinV);

Imm = F2(22,10,BinV);

sr1 = Reg[SR1].GetDecValue(32);

address = (unsigned long)((unsigned __int64)Imm + sr1);

value = LoadByte(address);

Reg[REC].LoadReg(value, 0);

Reg[REC].ShowReg(REC, D->ItemIndex, E->Checked, A);

} break;

}

}

// Выполнить текущую команду

void __fastcall TForm1::Button1Click(TObject *Sender)

{ Com[CurCom].Execute(StringGrid1, StringGrid3, StringGrid4, RadioGroup1, CheckBox1);

if (CurCom < NumCom - 1)

{ Edit1->Text = Com[CurCom++].TextCom();

Edit2->Text = Com[CurCom].TextCom();

Edit4->Text = Com[CurCom].ComCode();

if (CurCom == NumCom-1)

{ Edit3->Text = "";

D(NextButton) D(BitBtn2) D(NCom)

}

else

{ Edit3->Text = Com[CurCom+1].TextCom();

E(PreviousButton) E(BitBtn1) E(PCom)

}

}

}

// Перейти к первой команде

void __fastcall TForm1::TopButtonClick(TObject *Sender)

{ CurCom = 1;

Edit3->Text = Com[CurCom--].TextCom();

Edit2->Text = Com[CurCom].TextCom();

Edit4->Text = Com[CurCom].ComCode();

Edit1->Text = "";

D(PreviousButton) D(BitBtn1) D(PCom)

E(NextButton) E(BitBtn2) E(NCom)

}

// Перейти к последней команде

void __fastcall TForm1::EndButtonClick(TObject *Sender)

{ CurCom = NumCom-2;

Edit1->Text = Com[CurCom++].TextCom();

Edit2->Text = Com[CurCom].TextCom();

Edit4->Text = Com[CurCom].ComCode();

Edit3->Text = "";

D(NextButton) D(BitBtn2) D(NCom)

E(PreviousButton) E(BitBtn1) E(PCom)

}

// Перейти к предыдущей команде

void __fastcall TForm1::BitBtn1Click(TObject *Sender)

{ Edit3->Text = Com[CurCom--].TextCom();

Edit2->Text = Com[CurCom].TextCom();

Edit4->Text = Com[CurCom].ComCode();

if (!CurCom)

{ Edit1->Text = "";

D(PreviousButton) D(BitBtn1) D(PCom)

if (NumCom > 1)

{ E(NextButton) E(BitBtn2) E(NCom)

}

}

else

{ Edit1->Text = Com[CurCom-1].TextCom();

E(NextButton) E(BitBtn2) E(NCom)

}

}

// Перейти к следующей команде

void __fastcall TForm1::BitBtn2Click(TObject *Sender)

{ Edit1->Text = Com[CurCom++].TextCom();

Edit2->Text = Com[CurCom].TextCom();

Edit4->Text = Com[CurCom].ComCode();

if (CurCom == NumCom-1)

{ Edit3->Text = "";

D(NextButton) D(BitBtn2) D(NCom)

if (NumCom > 1)

{ E(PreviousButton) E(BitBtn1) E(PCom)

}

}

else

{ Edit3->Text = Com[CurCom+1].TextCom();

E(PreviousButton) E(BitBtn1) E(PCom)

}

}

// Reset registers

void __fastcall TForm1::Button3Click(TObject *Sender)

{ for (int i=0; i<64; i++)

{ Reg[i].Clear();

Reg[i].ShowReg(i, RadioGroup1->ItemIndex, CheckBox1->Checked, i>31? StringGrid2: StringGrid1);

}

}

// Run - запуск программы на выполнение

// Останов по Breakpoint

void __fastcall TForm1::RunButtonClick(TObject *Sender)

{ int i;

for (i=CurCom; i<NumCom && !ListBox1->Selected[i]; i++)

{ Com[CurCom].Execute(StringGrid1, StringGrid3, StringGrid4, RadioGroup1, CheckBox1);

if (CurCom < NumCom - 1)

{ Edit1->Text = Com[CurCom++].TextCom();

Edit2->Text = Com[CurCom].TextCom();

Edit4->Text = Com[CurCom].ComCode();

if (CurCom == NumCom-1)

{ Edit3->Text = "";

D(NextButton) D(BitBtn2) D(NCom)

if (NumCom > 1)

{ E(PreviousButton) E(BitBtn1) E(PCom)

}

}

else

{ Edit3->Text = Com[CurCom+1].TextCom();

E(PreviousButton) E(BitBtn1) E(PCom)

}

}

}

}

void __fastcall TForm3::StringGrid2Click(TObject *Sender)

{ int i, j, n = Form3->StringGrid2->Row - 1;

char a[3] = {0,0,0};

for (i=0; i<32; i++)

StringGrid1->Cells[i][0] = Com[n].ComCode()[i];

for (i=j=0; j<6; j++)

i += int(Com[n].ComCode()[j+1]-48) << (5-j);

HeaderControl1->Visible = (i==7)? false: true;

sprintf(a, "%d", i);

Edit1->Text = a;

}

void __fastcall TForm1::RadioGroup1Click(TObject *Sender)

{ if (!RadioGroup1->ItemIndex)

D(CheckBox1)

else

E(CheckBox1)

for (int i=0; i<64; i++)

Reg[i].ShowReg(i, RadioGroup1->ItemIndex, CheckBox1->Checked, i>31? StringGrid2: StringGrid1);

GroupBox1->Caption = RadioGroup1->ItemIndex? (AnsiString)"CPU Registers (Dec 64-bit)": (AnsiString)"CPU Registers (Hex 64-bit)";

GroupBox3->Caption = RadioGroup1->ItemIndex? (AnsiString)"FPU Registers (Dec 64-bit)": (AnsiString)"FPU Registers (Hex 64-bit)";

}

// Показать содержимое регистра

void __fastcall Register::ShowReg1(int n, int d, int s, TStringGrid *a)

{ char x[21];

if (d) // Dec

{ if (s) // Signed

sprintf(x, "%Ld", DecValue);

else // Unsigned

sprintf(x, "%Lu", DecValue);

a->Cells[1][n%16+1] = x;

}

else // Hex

a->Cells[1][n%16+1] = HexValue;

}

void __fastcall TForm4::RadioGroup1Click(TObject *Sender)

{ int i;

if (!RadioGroup1->ItemIndex)

D(CheckBox1)

else

E(CheckBox1)

for (i=0; i<32; i++)

Reg[i].ShowReg1(i, RadioGroup1->ItemIndex, CheckBox1->Checked, i>15? StringGrid2: StringGrid1);

for (i=32; i<64; i++)

Reg[i].ShowReg1(i, RadioGroup1->ItemIndex, CheckBox1->Checked, i>47? StringGrid4: StringGrid3);

GroupBox1->Caption = RadioGroup1->ItemIndex? "CPU Registers (Dec 64-bit)": "CPU Registers (Hex 64-bit)";

GroupBox2->Caption = RadioGroup1->ItemIndex? "FPU Registers (Dec 64-bit)": "FPU Registers (Hex 64-bit)";

}

void __fastcall TForm4::CheckBox1Click(TObject *Sender)

{ int i;

for (i=0; i<32; i++)

Reg[i].ShowReg1(i, RadioGroup1->ItemIndex, CheckBox1->Checked, i>15? StringGrid2: StringGrid1);

for (i=32; i<64; i++)

Reg[i].ShowReg1(i, RadioGroup1->ItemIndex, CheckBox1->Checked, i>47? StringGrid4: StringGrid3);

}

void __fastcall TForm1::CheckBox1Click(TObject *Sender)

{ for (int i=0; i<64; i++)

Reg[i].ShowReg(i, RadioGroup1->ItemIndex, CheckBox1->Checked, i>31? StringGrid2: StringGrid1);

}

// CPU и FPU регистры (полный вид)

void __fastcall TForm1::Button2Click(TObject *Sender)

{ int i;

char q[4];

Form4->Show();

Form4->RadioGroup1Click(Sender);

for (i=0; i<64; i++)

{ sprintf(q, "R%d", i);

if (i<16) Form4->StringGrid1->Cells[0][i+1] = q;

if (i>=16 && i<32) Form4->StringGrid2->Cells[0][i-15] = q;

if (i>=32 && i<48) Form4->StringGrid3->Cells[0][i-31] = q;

if (i>=48) Form4->StringGrid4->Cells[0][i-47] = q;

}

Form4->StringGrid1->Cells[1][0] = " Value";

Form4->StringGrid2->Cells[1][0] = " Value";

Form4->StringGrid3->Cells[1][0] = " Value";

Form4->StringGrid4->Cells[1][0] = " Value";

}

Соседние файлы в папке Материалы по Архитектуре