Автор работы: Пользователь скрыл имя, 21 Мая 2013 в 20:54, курсовая работа
Курсовая работа посвящена изучению структуры и работы цифровой вычислительной машины, изучению и использованию модуля Graph Турбо Паскаля, знакомство с основами языка ассемблера и машинного языка, освоению техники разработки и отладки многофайлового программного продукта на примере создания программной модели ЦВМ.
[+] - В режиме "Ввод": Увеличить значение элемента,
в режиме "Демо": Ускорить скорость демонстрации
[-] - В режиме "Ввод": Уменьшить значение элемента,
в режиме "Демо": Замедлить скорость демонстрации
[Alt]-[X] - Выход
Листинг программы
MBM.pas
Program MBM;
uses MBMData,MBMInOut,MBMCpu, Crt, Graph;
var
UserCmnd:Char;
begin
{Init Graph}
InitMBM;
SetWriteMode(XORPut);
repeat OutValues;
RectangDoubl; {vivod double ramka}
repeat { vipolnene mashinoj comandy}
OutTime;
ExecuteProgram;
until KeyPressed;
RectangDoubl; {odinrnaya ramka}
UserCmnd:=GetUserCmnd; {poluchena directiva}
Case UserCmnd of
{Tab} #9:CurrentReg:=(CurrentReg+1) mod MaxCurrReg;
{F7} ^T:Sost:=Takt;
{F8} ^K:Begin Sost:=Cmnd; EndCmnd:=False; end;
{Ctrl-F9} ^A: begin Sost:=Avto; EndProg:=False; End;
{F9} ^D: begin Sost:=Demo; EndProg:=False; end;
{Esc} #27:Sost:=Vvod;
{+} #43: begin
if Sost = Vvod then
if CurrentReg=5 then
inc(Shag)
else
with ArrReg[CurrentReg] do
Value^:= Value^ + Shag;
if Sost = Demo then
Speed:= Speed + Shag;
end;
{-} #45: begin
if Sost = Vvod then
if CurrentReg=5 then
dec(shag)
else
with ArrReg[CurrentReg] do
Value^:= Value^ - Shag;
if Sost = Demo then
Speed:= Speed - Shag;
end;
end;
until UserCmnd=CmndExit; {Alt-X}
closeGraph;
end.
GrapgLib.pas
unit GraphLib;
interface
type
String4 = string[4];
{ ochischaem }
procedure ClearBar(Left, Top, Right, Bottom: integer);
{ vivesti celoe v 16 sisteme schislenija }
procedure OutHexXY(X,Y: integer; Lens: byte; Val: word);
{ vivesti celoe s chislom simvolov Lens }
procedure OutIntegerXY(X, Y, Lens: integer; IntVal: word);
{ celoe v 16richnoy stroky }
function WordToHex(N: word; Lens: byte): String4;
implementation
uses Graph;
{Clear Bar }
{ ochistit prjamoygolnik v graficheskih koordinatah }
procedure ClearBar(Left, Top, Right, Bottom: integer);
begin
SetFillStyle(EmptyFill, Black);
Bar(Left, Top, Right, Bottom);
end; {Clear Bar }
{WordToHex }
{ preobrazovenie celoe v 16richnyu stroky }
function WordToHex(N:word; Lens:byte): String4;
const
HexDigit: array[0..15] of char='0123456789ABCDEF';
var
S : String4;
Pos : byte;
Ost : word;
begin
S := '0000';
S[0] := Chr(Lens);
for Pos:=Lens downto 1 do begin
Ost := N mod 16;
N := N div 16;
S[Pos] := HexDigit[Ost];
end;
WordToHex:=S;
end; {WordToHex }
{OutHex }
{ vivesti celoe znachenie v 16oi sisteme schislenija }
procedure OutHexXY(X,Y:integer; Lens:byte; Val:word);
begin
ClearBar(X,Y, X+TextWidth('0')*(Lens+1), Y+TextHeight('0') );
OutTextXY(X,Y, '$'+WordToHex(Val,Lens) );
end; {OutHex }
{OutInteger }
{ vivesti celoe znachenie s chislom simvolov Lens }
procedure OutIntegerXY(X,Y,Lens:integer; IntVal:word);
var
Str7: string[7];
begin
Str(IntVal:Lens, Str7);
ClearBar(X,Y, X+TextWidth(Str7), Y+TextHeight(Str7) );
OutTextXY(X,Y, Str7);
end; {OutIntegerXY }
end.
MBMData.pas
unit MBMData;
interface
type
TSost = (Vvod, Avto, Demo, Takt, Cmnd);
const { sostojanie modeli }
Sost: TSost = Vvod;
SostName: array[TSost] of string[4] =
('‚ў®¤', 'Ђўв®', '„Ґ¬®', '’ Єв', 'Љ¬¤');
type { atribyti nadpisi }
TMsgTV = record
X, Y : integer;
Msg : string[17];
end;
const { kol-vo i massiv nadpisej }
CountMsg = 56;
ArrMsg : array[0..CountMsg-1] of TMsgTV = (
(X:74 ; Y:78; Msg:'Процессор'),
(X:352; Y:78; Msg:'Память'),
(X:376; Y:94; Msg:'Ячейки ОЗУ'),
(X:12 ; Y:90; Msg:'АЛУ'),
(X:192; Y:90; Msg:'УУ'),
(X:222; Y:126; Msg:'Адрес'),
(X:216; Y:265; Msg:'Данные'),
(X:228; Y:85; Msg:'R/W'),
(X:295; Y:113; Msg:'РгА'),
(X: 65; Y:113; Msg:'РгФ'),
(X:135; Y:113; Msg:'СчК'),
(X: 65; Y:253; Msg:'АКК’),
(X:135; Y:253; Msg:'РгК'),
(X:295; Y:253; Msg:'РгД'),
(X:445; Y:115; Msg:'Seven'),
(X:445; Y:145; Msg:'One'),
(X:445; Y:175; Msg:'Zero'),
(X:445; Y:205; Msg:'A'),
(X:445; Y:235; Msg:'C'),
(X:445; Y:255; Msg:'D'),
(X:445; Y:265; Msg:'F'),
(X:445; Y:295; Msg:'Func'),
(X:442; Y:325; Msg:'FuncA'),
(X:442; Y:355; Msg:'LoaXA'),
(X:236; Y:97; Msg:'>'),
(X:278; Y:134; Msg:'>'),
(X:373; Y:134; Msg:'>'),
(X:373; Y:275; Msg:'>'),
(X:355; Y:275; Msg:'<'),
(X:278; Y:275; Msg:'>'),
(X:180; Y:210; Msg:'>'),
(X:130; Y:210; Msg:'>'),
(X:40 ; Y:210; Msg:'<'),
(X:194; Y:205; Msg:'+'),
(X:29 ; Y:385; Msg:'Скорость'),
(X:25; Y:395; Msg:'Демонстрации'),
(X:140; Y:395; Msg:'Шаг изменения'),
(X:305; Y:395; Msg:'Такт'),
(X:395; Y:395; Msg:'Режим'),
(X:520; Y:100; Msg:'Справка'),
(X:493; Y:112; Msg:'Esc -Прерывание'),
(X:493; Y:124; Msg:'Tab –выбрать сле-'),
(X:493; Y:136; Msg:'дующий элемент'),
(X:493; Y:148; Msg:'F7 –Режим «Такт»'),
(X:493; Y:160; Msg:'F8 –Режим «Коман-'),
(X:493; Y:172; Msg:'да»'),
(X:493; Y:184; Msg:'F9 –Режим «Демо»'),
(X:493; Y:196; Msg:'Ctrl-F9 -Режим'),
(X:493; Y:208; Msg:'"Автомат"'),
(X:493; Y:220; Msg:'+,- -Если режим:'),
(X:493; Y:232; Msg:' Ввод: изменить'),
(X:493; Y:244; Msg:'следующий элемент'),
(X:493; Y:256; Msg:' Демо: изменить'),
(X:493; Y:268; Msg:'скорость),
(X:493; Y:280; Msg:'Alt-X -Выход'),
(X:285; Y:295; Msg:'15'),
(X:347; Y:295; Msg:'0')
type { atribyti linij }
TLineTV = record
X, Y : integer;
Len : integer;
Dir : (Down, Right);
end;
const { registri }
Flags : word = 0; { RgF }
Akk : word = 0; { Akk }
PC : word = $2008; { C4k }
Command: word = 0; { RgK }
Adres : word = 0; { RgA }
Data : word = 0; { RgD }
Shag : word = 1; { shag izmenenijа }
Speed : word = 10; { 1 operacija v sec }
COP : word = 0; { kod operacii }
ADR : word = 0; { adresnaja chast komandi }
NumTakt: word = 0; { nomer takta }
Aisp : word = 0; { ispolnitelnij adres }
EndProg: Boolean = FALSE; { programma zavershena ? }
EndCmnd: Boolean = FALSE; { komanda zavershena ? }
ZF:boolean=false;
CF:boolean=false;
AkkTemp:longint=0;
const { mashinii kod }
MEM: array[$2000..$2021] of word = (
{ F = (X+2)-Y-X+1
KOP: Add - 1
Sub - 2
Loa - 3
Sto - 4
Jz - 5
Jmp - 6
.End- 7 }
{Adres .Asm Kod}
{ $2000 Seven} 7,
{ $2001 One} 1,
{ $2002 Zero} 0,
{ $2003 A} 10,
{ $2004 C} 11,
{ $2004 D} 12,
{ $2005 F} 0,
{ $2006 FundAddr} $2008,
{ $2007 Loa_XAddr} $2010,
{ Func:}
{ $2008 Loa A} $0303,
{ $2009 Add Seven} $0100,
{ $200A Sto F} $0405,
{ $200B Loa Y} $0304,
{ $200C Jz IncZeroX} $051A,
{ $200D Loa F} $0305,
{ $200E Sub C} $0204,
{ $200F Sto F} $0405,
{ Loa_X:}
{ $2010 Loa D} $0303,
{ $2011 Jz IncZeroY} $051E,
{ $2012 Loa F} $0305,
{ $2013 Sub C} $0203,
{ $2014 Sto F} $0405,
{ $2015 Loa One} $0301,
{ $2016 Loa F} $0305,
{ $2017 Add One} $0101,
{ $2018 Sto F} $0405,
{ $2019 .End Func} $0706,
{IncZeroY:}
{ $201A Loa Zero} $0302,
{ $201B Add One} $0101,
{ $201C Sto Zero} $0402,
{ $201D Jmp Loa_X} $0607 ,
{IncZeroX}
{ $201E Loa Zero} $0302,
{ $201F Add One} $0101,
{ $2020 Sto Zero} $0402,
{ $2021 .End Func} $0706);
const { kol-vo i massiv linij }
CountLine = 18;
ArrLine : array[0..CountLine-1] of TLineTV = (
(X:210; Y:100; Len: 60; Dir: Right),
(X:195; Y:137; Len: 90; Dir: Right),
(X:355; Y:137; Len: 25; Dir: Right),
(X:203; Y:278; Len: 81; Dir: Right),
(X:355; Y:278; Len: 25; Dir: Right),
(X: 18; Y:321; Len:185; Dir: Right),
(X: 18; Y:213; Len: 44; Dir: Right),
(X:110; Y:213; Len: 50; Dir: Right),
(X:175; Y:213; Len: 27; Dir: Right),
(X: 18; Y:213; Len:108; Dir: Down ),
(X: 62; Y:213; Len: 50; Dir: Down ),
(X: 62; Y:293; Len: 28; Dir: Down ),
(X:110; Y:213; Len:108; Dir: Down ),
(X:160; Y:153; Len: 60; Dir: Down ),
(X:160; Y:293; Len: 28; Dir: Down ),
(X:175; Y:153; Len:110; Dir: Down ),
(X:203; Y:138; Len: 75; Dir: Down ),
(X:203; Y:278; Len: 43; Dir: Down )
type { atribyti ramki }
TRegTV = record
X, Y : integer;
W, H : integer;
Value: ^word;
end;
const { ramki }
CountReg = 22;
ArrReg : array[0..CountReg-1] of TRegTV = (
{0 C4k } (X:125; Y:123; W: 70; H: 30; Value:@PC ),
{1 Zero } (X:380; Y:163; W: 60; H: 30; Value:@Mem[$2002]),
{2 X } (X:380; Y:193; W: 60; H: 30; Value:@Mem[$2003]),
{3 Y } (X:380; Y:223; W: 60; H: 30; Value:@Mem[$2004]),
{4 F } (X:380; Y:253; W: 60; H: 30; Value:@Mem[$2005]),
{5 shag } (X:125; Y:405; W: 70; H: 30; Value:@Shag ),
{6 speed } (X:25; Y:405; W: 70; H: 30; Value:@Speed ),
{7 takt } (X:285; Y:405; W: 70; H: 30; Value:@NumTakt ),
{8 RgF } (X: 25; Y:123; W: 70; H: 30; Value:@Flags ),
{9 RgA } (X:285; Y:123; W: 70; H: 30; Value:@Adres ),
{10 RgD } (X:285; Y:263; W: 70; H: 30; Value:@Data ),
{11 RgK } (X:125; Y:263; W: 70; H: 30; Value:@Command ),
{12 AKK } (X: 25; Y:263; W: 70; H: 30; Value:@Akk ),
{13 YY } (X: 10; Y:88; W:200; H:290; Value:nil ),
{14 O3Y } (X:270; Y:88; W:214; H:290; Value:nil ),
{15 Help } (X:490; Y:95; W:140; H:200; Value:nil ),
{16 two } (X:380; Y:103; W: 60; H: 30; Value:@Mem[$2000]),
{17 One } (X:380; Y:133; W: 60; H: 30; Value:@Mem[$2001]),
{18 Func } (X:380; Y:283; W: 60; H: 30; Value:@Mem[$2008]),
{19 FuncAd} (X:380; Y:313; W: 60; H: 30; Value:@Mem[$2006]),
{20 LoaXAd} (X:380; Y:343; W: 60; H: 30; Value:@Mem[$2007]),
{21 Sost } (X:380; Y:405; W: 70; H: 30; Value:nil )
CurrentReg: word = 0; { nomer vibranoj ramki }
MaxCurrReg: word = 7; { kol-vo vibiraemih ramok }
const
CmndExit = ^X; { Alt-X }
implementation
end.
MBMCpu.pas
unit MBMCpu;
interface
{ vipolnit mashinyu programmy po taktam }
procedure ExecuteProgram;
implementation
uses Crt, MBMData, MBMInOut;
const
MaxTakt: array[0..7] of word = (5,11,11,11,10,8,10,11);
{ NOp, Add, Sub, Loa, Sto, JZ, Jmp, .End }
{ExecADD }
procedure ExecAdd;
begin
case NumTakt of
7: Adres := Aisp;
8: Data := MEM[Adres];
9: begin
AkkTemp:=Akk + Data;
Akk := Akk + Data;
end;
10: begin
if Data = 0 then ZF:=true else ZF:=false;
if (AkkTemp > $FFFF)
or (((Akk mod 16)+(Data mod 16))>15)
or ( (((Akk div 16) mod 16)+((Data div 16) mod 16))>15)
or ( (((Akk div 256) mod 16)+((Data div 256) mod 16))>15)
or ( ((Akk div 4096)+(Data div 4096))>15) then CF:=true else
CF:=false;
if CF then
if ZF then Flags:=17 else Flags:=1
else
if ZF then Flags:=16 else Flags:=0;
end;
{ set ZF }
end;
end; {ExecADD }
{ExecSUB }
procedure ExecSub;
begin
case NumTakt of
7: Adres := Aisp;
8: Data := MEM[Adres];
9: Akk := Akk - Data;
10: begin
if ((Akk mod 16)<(Data mod 16)) or (((Akk div 16)mod 16)<((Data div 16)mod 16)) or
( ((Akk div 256)mod 16) < ((Data div 256)mod 16) ) or ((Akk div 4096)<(Data div 4096)) then CF:=true
else CF:=false;
if Data = 0 then ZF:=true else ZF:=false;
if CF then
if ZF then Flags:=17 else Flags:=1
else
if ZF then Flags:=16 else Flags:=0;
end;
{ set ZF }
end;
end; {ExecSUB }
{ExecLOA }
procedure ExecLoa;
begin
case NumTakt of
7: Adres := Aisp;
8: Data := MEM[Adres];
9: Akk := Data;
10: if Data = 0 then Flags:=16
else Flags:=0;
{ set ZF }
end;
end; {ExecLOA }
{ExecSTO }
procedure ExecSto;
begin
case NumTakt of
7: Adres := Aisp;
8: Data := Akk;
9: MEM[Adres] := Data;
end;
end; {ExecSTO }
{ExecJZ }
procedure ExecJZ;
begin
if (Flags=16) or (Flags=17) then
case NumTakt of
7: PC:=Aisp;
end;
end; {ExecJZ }
{ExecJmp }
procedure ExecJmp;
begin
case NumTakt of
7: Adres := Aisp;
8: Data := MEM[Adres];
9: PC := Data;
end;
end; {ExecJmp }
{ExecEND }
procedure ExecEnd;
begin
case NumTakt of
7: Adres := Aisp;
8: Data := MEM[Adres];
9: PC := Data;
10: EndProg := True;
end;
end; {ExecEND }
{ExecOperation }
procedure ExecOperation;
begin
case COP of
1: ExecAdd;
2: ExecSub;
3: ExecLoa;
4: ExecSto;
5: ExecJZ;
6: ExecJmp;
7: ExecEnd;
end;
end; {ExecOperation }
{ExecTakt }
procedure ExecTakt;
begin
case NumTakt of
0: Adres := PC;
1: Data := MEM[Adres];
2: Command := Data;
3: Inc(PC);
4: COP := Command shr 8;
5: ADR := Command and $00FF;
6: Aisp := PC and $FF00 or ADR;
7..10: ExecOperation;
end;
NumTakt := (NumTakt+1) mod MaxTakt[COP];
if NumTakt = 0 then EndCmnd:=True;
end; {ExecTakt }
{ExecuteProgram }
procedure ExecuteProgram;
begin
if Sost <> Vvod then begin
ExecTakt;
OutValues;
case Sost of
Takt: Sost:=Vvod;
Cmnd: if EndCmnd then Sost:=Vvod;
Avto: if EndProg then Sost:=Vvod;
Demo: begin {vipolnit zaderzhky}
if Speed <> 0 then
Delay(10000 div Speed);
if EndProg then Sost:=Vvod;
end;
end; {case}
OutSost;
end; {if}
end; {ExecuteProgram }
end.
MBMInOut.pas
unit MBMInOut;
interface
procedure OutValues;
{ vivesti znachenija registrov i jacheek}
procedure RectangDoubl;
{ vivesti/pogasit dvoinyu ramky }
procedure InitMBM;
{ inicializacija grafiki i vivod stryktyri MBM }
function GetUserCmnd: char;
{ prochitat rasshirenij kod klavishi i preobrazovat
ego v kod direktivi polzovatelja }
procedure OutTime;
{ vivod vremeni }
procedure OutSost;
{ vivod rezhima }
implementation
uses TPDate, Crt, Graph, MBMData, GraphLib;
{OutStructure }
procedure OutStructure;
var
I: byte;
begin
for i:=0 to CountMsg-1 do
with ArrMsg[i] do
OutTextXY(X, Y, Msg);
OutTextXY(1, 40, 'Тарасов Дмитрий');
OutTextXY(10,456,'C');
Circle(13,459,6);
OutTextXY(25,456, 'Группа ИВТ-21-11');
OutTextXY(10,466, '2.03.2012-22.05.2012');
for i:=0 to CountLine-1 do
with ArrLine[i] do
case Dir of
Right: Line(X,Y, X+Len, Y);
Down : Line(X,Y, X, Y+Len);
end;
for i:=0 to CountReg-1 do
with ArrReg[i] do
Rectangle(X,Y, X+W, Y+H);
end; { OutStructure }
{OutValues }
procedure OutValues;
var
i: byte;
S: String4;
begin
for i:=0 to CountReg-1 do
with ArrReg[i] do
if Value <> nil then
if i = 6 then { vivod skorosti demonstracii }
OutIntegerXY(X+15, Y+8, 6, Value^)
else begin
if i = 11 {RgK} then begin
ClearBar(X+5, Y+5, X+W-5, Y+H-5);
OutHexXY(X+15, Y+11, 4, Value^);
ClearBar(X+5, Y+5, X+W-5, Y+H-5);
S := WordToHex( Hi(Value^), 4 );
S := S[3]+S[4];
OutTextXY(X+8, Y+11, '$'+S);
S := WordToHex( Lo(Value^), 4 );
S := S[3]+S[4];
OutTextXY(X+37, Y+11, '$'+S);
end
else
OutHexXY(X+15, Y+11, 4, Value^);
end;
end; {OutValues }
{RectangDoubl }
procedure RectangDoubl;
begin
with ArrReg[CurrentReg] do
Rectangle(X+3, Y+3, X+W-3, Y+H-3);
end; {RectangDoubl }
const
NewTime : Time = 0;
OldTime : Time = 1;
{CurrentTime }
function CurrentTime: Time;