unit Logic; interface uses SysUtils,StdCtrls,Classes,Math; type byteWord = class private value:LongWord; function getText():string; procedure setText(input:string); function getDec():LongWord; procedure setHex(input:LongWord); public property Text:string read getText write setText; property Hex:LongWord read getDec write setHex; constructor Create(); overload; constructor Create(input:string); overload; constructor Create(input:LongWord); overload; end; ByteProc = function(number:byteWord):Boolean of object; flag = class private value:Boolean; flagLabel:TLabel; checkProc:ByteProc; function getState():Boolean; procedure setState(state:Boolean); procedure setLabel(); function checkOverflow(number:byteWord):Boolean; function checkZero(number:byteWord):Boolean; function checkHighOne(number:byteWord):Boolean; function checkParity(number:byteWord):Boolean; public property State:Boolean read getState write setState; property Check:ByteProc read checkProc write checkProc; constructor Create(flagLabel:TLabel); procedure refresh(number:byteWord); end; flagV = class(flag) constructor Create(flagLabel:TLabel); end; flagZ = class(flag) constructor Create(flagLabel:TLabel); end; flagN = class(flag) constructor Create(flagLabel:TLabel); end; flagP = class(flag) constructor Create(flagLabel:TLabel); end; TAbstractRegister = class private value:byteWord; regFlag:array of flag; procedure refreshFlags(); procedure refreshInterface();virtual;abstract; function getValue():byteWord; procedure setValue(value:byteWord); public property Number:byteWord read getValue write setValue; procedure setDecValue(decValue:LongWord); //procedure setTextValue(textValue:ShortString); procedure setHexValue(hexValue:ShortString); end; TRegister = class (TAbstractRegister) private ID:Integer; procedure refreshInterface();override; public function getID():Integer; constructor Create(ID:Integer); end; TAbstractCommand = class public name: string; class function calculation(n1,n2:byteWord):byteWord;virtual;abstract; constructor Create(name:string); end; TCommandAdd = class(TAbstractCommand) class function calculation(n1,n2:byteWord):byteWord;override; constructor Create(); end; TCommandSubst = class(TAbstractCommand) class function calculation(n1,n2:byteWord):byteWord;override; constructor Create(); end; TCommandAnd = class(TAbstractCommand) class function calculation(n1,n2:byteWord):byteWord;override; constructor Create(); end; TCommandOr = class(TAbstractCommand) class function calculation(n1,n2:byteWord):byteWord;override; constructor Create(); end; TCommandXor = class(TAbstractCommand) class function calculation(n1,n2:byteWord):byteWord;override; constructor Create(); end; TCalculator = class private N1:TRegister; N2:TRegister; Command:TAbstractCommand; public procedure Add(N1:TRegister;N2:TRegister;Command:TAbstractCommand); procedure process(); constructor Create(); end; TAbstractProcessor = class private regs:array of TRegister; commands:array of TAbstractCommand; public function getRegister(Index: Integer):TRegister; function getCommand(Index: Integer):TAbstractCommand; procedure initState();virtual;abstract; procedure calculate();virtual;abstract; end; TProcessor = class(TAbstractProcessor) private calc:TCalculator; public property REG1: TRegister index 0 read getRegister; property REG2: TRegister index 1 read getRegister; property REG3: TRegister index 2 read getRegister; property REG4: TRegister index 3 read getRegister; procedure calculate();override; procedure initState();override; function getRegisterIDs():TStrings; constructor Create(); end; TFind = class(TComponent) public function findFlag(regID:Integer;flagID:Integer):TLabel; function findValueLabel(regID:Integer;labelType:ShortString):TLabel; function findHeader(regID:Integer):TLabel; end; function convertDecToBin(number:LongWord):ShortString; function convertBinToDec(number:ShortString):LongWord; implementation uses Unit1; function convertDecToBin(number:LongWord):ShortString; var md:LongWord; begin Result:=''; repeat md:=number mod 2; number:=number div 2; Result:=IntToStr(md)+Result; until number<1 end; function convertBinToDec(number:ShortString):LongWord; var i:Integer; begin Result:=0; for i:=Length(number) downto 1 do Result:=Result+StrToInt(number[i])*Trunc(Power(2,Length(number)-i)); end; function byteWord.getText():string; begin getText:=IntToHex(getDec,4); end; procedure byteWord.setText(input:string); begin setHex(StrToInt('$'+input)); end; function byteWord.getDec():LongWord; begin getDec:=value; end; procedure byteWord.setHex(input:LongWord); begin value:=input; end; constructor byteWord.Create(); begin setText('FFFF'); end; constructor byteWord.Create(input:string); begin if input<>'' then setText(input) else Create; end; constructor byteWord.Create(input:LongWord); begin setHex(Input); end; constructor flag.Create(flagLabel:TLabel); begin Self.flagLabel:=flagLabel; setState(false); end; procedure flag.setState(state:Boolean); begin value:=state; setLabel; end; function flag.getState():Boolean; begin getState:=value; end; procedure flag.setLabel(); begin flagLabel.Enabled:=getState; end; procedure flag.refresh(number:byteWord); begin State:=check(number); end; function flag.checkOverflow(number:byteWord):Boolean; begin if number.Hex>$FFFF then checkOverflow:=True else checkOverflow:=false; end; function flag.checkZero(number:byteWord):Boolean; begin if number.Hex=$0 then checkZero:=True else checkZero:=false; end; function flag.checkHighOne(number:byteWord):Boolean; begin if number.Hex>$7FFF then checkHighOne:=True else checkHighOne:=false; end; function flag.checkParity(number:byteWord):Boolean; var binStr:ShortString; i,count:integer; begin count:=0; binStr:=convertDecToBin(number.Hex); for i:=0 to Length(binStr) do if binStr[i]='1' then Inc(count); if (count mod 2)=0 then checkParity:=True else checkParity:=false; end; constructor flagV.Create(flagLabel:TLabel); begin inherited Create(flagLabel); flagLabel.Caption:='V'; Check:=checkOverflow; end; constructor flagZ.Create(flagLabel:TLabel); begin inherited Create(flagLabel); flagLabel.Caption:='Z'; Check:=checkZero; end; constructor flagN.Create(flagLabel:TLabel); begin inherited Create(flagLabel); flagLabel.Caption:='N'; Check:=checkHighOne; end; constructor flagP.Create(flagLabel:TLabel); begin inherited Create(flagLabel); flagLabel.Caption:='P'; Check:=checkParity; end; function TAbstractRegister.getValue():byteWord; begin getValue:=value; end; procedure TAbstractRegister.setDecValue(decValue:LongWord); begin Number:=byteWord.Create(decValue); end; procedure TAbstractRegister.setHexValue(hexValue:ShortString); begin Number:=byteWord.Create(hexValue); end; procedure TAbstractRegister.refreshFlags(); var i:integer; begin for i:=0 to High(regFlag) do regFlag[i].refresh(Number); end; procedure TAbstractRegister.setValue(value:byteWord); begin Self.value:=value; refreshFlags(); refreshInterface(); end; constructor TRegister.Create(ID:Integer); var finder:TFind; begin Self.ID:=ID; finder:=TFind.Create(Unit1.Form1); SetLength(regFlag,4); regFlag[0]:=flagN.Create(finder.findFlag(ID,1)); regFlag[1]:=flagP.Create(finder.findFlag(ID,2)); regFlag[2]:=flagV.Create(finder.findFlag(ID,3)); regFlag[3]:=flagZ.Create(finder.findFlag(ID,4)); setValue(byteWord.Create()); finder.findHeader(ID).Caption:='REGISTER '+IntToStr(ID); end; procedure TRegister.refreshInterface(); var finder:TFind; begin if regFlag[2].State then value.Text:='FFFF'; finder:=TFind.Create(Unit1.Form1); finder.findValueLabel(ID,'Bin').Caption:=convertDecToBin(Number.Hex); finder.findValueLabel(ID,'Dec').Caption:=IntToStr(Number.Hex); finder.findValueLabel(ID,'Hex').Caption:=Number.Text; end; function TRegister.getID():Integer; begin getID:=ID; end; function TAbstractProcessor.getRegister(Index: Integer):TRegister; begin getRegister:=regs[index]; end; function TAbstractProcessor.getCommand(Index: Integer):TAbstractCommand; begin getCommand:=commands[index]; end; constructor TProcessor.Create(); var i:Integer; begin SetLength(regs,4); for i:=0 to High(regs) do regs[i]:=TRegister.Create(i+1); SetLength(commands,5); commands[0]:=TCommandAdd.Create; commands[1]:=TCommandSubst.Create; commands[2]:=TCommandAnd.Create; commands[3]:=TCommandOr.Create; commands[4]:=TCommandXor.Create; calc:=TCalculator.Create(); initState; end; procedure TProcessor.initState(); var i:Integer; begin REG1.setDecValue(1); REG2.setHexValue('8001'); REG3.setHexValue('FFFF'); REG4.setDecValue(256); with Unit1.Form1 do begin cbbRegList1.Items:=getRegisterIDs; cbbRegList1.ItemIndex:=0; cbbRegList1.Enabled:=True; cbbRegList2.Items:=getRegisterIDs; cbbRegList2.ItemIndex:=1; cbbRegList2.Enabled:=True; btnSetReg.Enabled:=True; btnSelectReg.Enabled:=True; cbbSetReg.Items:=getRegisterIDs; cbbSetReg.ItemIndex:=0; cbbSetReg.Enabled:=True; cbbOperList.Items.Clear; for i:=0 to High(commands) do cbbOperList.Items.Add(getCommand(i).name); cbbOperList.ItemIndex:=0; cbbOperList.Enabled:=True; end; end; function TProcessor.getRegisterIDs():TStrings; var list:TStrings;i:integer; finder:TFind; begin finder:=TFind.Create(Unit1.Form1); list:=TStringList.Create; for i:=0 to High(regs) do list.Add(finder.findHeader(regs[i].getID).Caption); Result:=list; end; procedure TProcessor.calculate(); begin with Unit1.Form1 do if (cbbRegList1.ItemIndex<>-1) and (cbbRegList2.ItemIndex<>-1) and (cbbOperList.ItemIndex<>-1) then calc.Add(getRegister(cbbRegList1.ItemIndex), getRegister(cbbRegList2.ItemIndex), getCommand(cbbOperList.ItemIndex)); calc.process; end; constructor TAbstractCommand.Create(name:string); begin Self.name:=name; end; constructor TCommandAdd.Create(); begin inherited Create('ADD'); end; class function TCommandAdd.calculation(n1,n2:byteWord):byteWord; begin Result:=byteWord.Create(n1.Hex+n2.Hex); end; constructor TCommandSubst.Create(); begin inherited Create('SUB'); end; class function TCommandSubst.calculation(n1,n2:byteWord):byteWord; var temp:byteWord; begin temp:=byteWord.Create; if n1.Hex>n2.Hex then temp.Hex:=n1.Hex-n2.Hex else temp.Hex:=$0; Result:=temp; end; constructor TCommandAnd.Create(); begin inherited Create('AND'); end; class function TCommandAnd.calculation(n1,n2:byteWord):byteWord; begin Result:=byteWord.Create(n1.Hex and n2.Hex); end; constructor TCommandOr.Create(); begin inherited Create('OR'); end; class function TCommandOr.calculation(n1,n2:byteWord):byteWord; begin Result:=byteWord.Create(n1.Hex or n2.Hex); end; constructor TCommandXor.Create(); begin inherited Create('XOR'); end; class function TCommandXor.calculation(n1,n2:byteWord):byteWord; begin Result:=byteWord.Create(n1.Hex xor n2.Hex); end; constructor TCalculator.Create(); begin end; procedure TCalculator.Add(N1:TRegister;N2:TRegister;Command:TAbstractCommand); begin Self.N1:=N1; Self.N2:=N2; Self.Command:=Command; end; procedure TCalculator.process(); begin Unit1.Form1.TStringGridOut.Cells[0,0]:=N1.Number.Text; Unit1.Form1.TStringGridOut.Cells[1,0]:=Command.name; Unit1.Form1.TStringGridOut.Cells[2,0]:=N2.Number.Text; Unit1.Form1.TStringGridOut.Cells[0,1]:='REG'+IntToStr(N1.getID); Unit1.Form1.TStringGridOut.Cells[1,1]:=Command.name; Unit1.Form1.TStringGridOut.Cells[2,1]:='REG'+IntToStr(N2.getID); N2.Number:=Command.calculation(N1.Number,N2.Number); Unit1.Form1.TStringGridOut.Cells[3,0]:=':'+N2.Number.Text; Unit1.Form1.TStringGridOut.Cells[3,1]:=':REG'+IntToStr(N2.getID); end; function TFind.findFlag(regID:Integer;flagID:Integer):TLabel; begin findFlag:=TLabel( Unit1.Form1.FindComponent('lblFlag'+IntToStr(flagID)+'_'+IntToStr(regID)) ); end; function TFind.findValueLabel(regID:Integer;labelType:ShortString):TLabel; begin findValueLabel:=TLabel( Unit1.Form1.FindComponent('lbl'+labelType+'REG'+IntToStr(regID)) ); end; function TFind.findHeader(regID:Integer):TLabel; begin findHeader:=TLabel( Unit1.Form1.FindComponent('lblNameREG'+IntToStr(regID)) ); end; end.