Changeset 5


Ignore:
Timestamp:
Apr 18, 2026, 7:24:02 PM (9 days ago)
Author:
chronos
Message:
  • Added: Some I/O ports handling.
  • Added: Messages form for capturing error messages.
  • Added: Go to address action.
  • Added: Allow to view all used memory areas in Memory window.
  • Added: Allow to reset CPU execution.
  • Modified: Improved memory mapping for MZ-700 and MZ-800 modes.
  • Fixed: Focusing currently executed instruction position.
  • Fixed: Wrong order or 8-bit registers in 16-bit pair.
Location:
trunk
Files:
5 added
15 edited

Legend:

Unmodified
Added
Removed
  • trunk/Core.lfm

    r2 r5  
    1919      Category = 'View'
    2020      Caption = 'Memory'
     21      ShortCut = 113
    2122      OnExecute = AViewMemoryExecute
    22       ShortCut = 113
    2323    end
    2424    object AViewDissssembler: TAction
    2525      Category = 'View'
    2626      Caption = 'Disassembler'
     27      ShortCut = 114
    2728      OnExecute = AViewDissssemblerExecute
    28       ShortCut = 114
    2929    end
    3030    object AStepIn: TAction
     31      Category = 'Debug'
    3132      Caption = 'Step in'
     33      ShortCut = 118
    3234      OnExecute = AStepInExecute
    33       ShortCut = 118
    3435    end
    3536    object AStepOver: TAction
     37      Category = 'Debug'
    3638      Caption = 'Step over'
     39      ShortCut = 119
    3740      OnExecute = AStepOverExecute
    38       ShortCut = 119
    3941    end
    4042    object ARunToCursor: TAction
     43      Category = 'Debug'
    4144      Caption = 'Run to cursor'
    4245      ShortCut = 115
    4346    end
    4447    object APause: TAction
     48      Category = 'Debug'
    4549      Caption = 'Pause'
     50      ShortCut = 16504
    4651      OnExecute = APauseExecute
    47       ShortCut = 16504
    4852    end
    4953    object ARun: TAction
     54      Category = 'Debug'
    5055      Caption = 'Run'
     56      ShortCut = 120
    5157      OnExecute = ARunExecute
    52       ShortCut = 120
    5358    end
    5459    object AStepOut: TAction
     60      Category = 'Debug'
    5561      Caption = 'Step out'
     62      ShortCut = 8311
    5663      OnExecute = AStepOutExecute
    57       ShortCut = 8311
    5864    end
    5965    object AStop: TAction
     66      Category = 'Debug'
    6067      Caption = 'Stop'
     68      ShortCut = 8312
    6169      OnExecute = AStopExecute
    62       ShortCut = 8312
    6370    end
    6471    object AViewCpu: TAction
    6572      Category = 'View'
    6673      Caption = 'CPU'
     74      ShortCut = 116
    6775      OnExecute = AViewCpuExecute
    68       ShortCut = 116
    6976    end
    7077    object AViewScreen: TAction
     
    7279      Caption = 'Screen'
    7380      OnExecute = AViewScreenExecute
     81    end
     82    object AReset: TAction
     83      Category = 'Debug'
     84      Caption = 'Reset'
     85      OnExecute = AResetExecute
     86    end
     87    object AGoToAddress: TAction
     88      Category = 'Edit'
     89      Caption = 'Go to address'
     90      ShortCut = 16455
     91      OnExecute = AGoToAddressExecute
     92    end
     93    object AViewMessages: TAction
     94      Category = 'View'
     95      Caption = 'Messages'
     96      OnExecute = AViewMessagesExecute
    7497    end
    7598  end
  • trunk/Core.pas

    r4 r5  
    55uses
    66  Classes, SysUtils, ActnList, Controls, FormMain, Forms, ExtCtrls, FormMemory,
    7   SharpMz800, FormDisassembler, FormCpu, FormScreen;
     7  SharpMz800, FormDisassembler, FormCpu, FormScreen, FormMessages;
    88
    99type
     
    1212
    1313  TCore = class(TDataModule)
     14    AViewMessages: TAction;
     15    AGoToAddress: TAction;
     16    AReset: TAction;
    1417    AViewScreen: TAction;
    1518    AViewCpu: TAction;
     
    2831    TimerUpdate: TTimer;
    2932    procedure AExitExecute(Sender: TObject);
     33    procedure AGoToAddressExecute(Sender: TObject);
    3034    procedure APauseExecute(Sender: TObject);
     35    procedure AResetExecute(Sender: TObject);
    3136    procedure ARunExecute(Sender: TObject);
    3237    procedure AStepInExecute(Sender: TObject);
     
    3742    procedure AViewDissssemblerExecute(Sender: TObject);
    3843    procedure AViewMemoryExecute(Sender: TObject);
     44    procedure AViewMessagesExecute(Sender: TObject);
    3945    procedure AViewScreenExecute(Sender: TObject);
    4046    procedure DataModuleCreate(Sender: TObject);
     
    4955    FormCpu: TFormCpu;
    5056    FormScreen: TFormScreen;
     57    FormMessages: TFormMessages;
    5158    SharpMz800: TSharpMz800;
    5259    procedure UpdateDisassemblerPos;
     
    6370
    6471uses
    65   CpuZ80;
     72  CpuZ80, FormGoToAddress;
    6673
    6774{ TCore }
     
    6976procedure TCore.DataModuleCreate(Sender: TObject);
    7077begin
     78  LastPc := $ffff;
    7179  SharpMz800 := TSharpMz800.Create;
    7280//  SharpMz800.PowerOn;
     
    8088end;
    8189
     90procedure TCore.AGoToAddressExecute(Sender: TObject);
     91var
     92  FormGoToAddress: TFormGoToAddress;
     93  Address: LongInt;
     94begin
     95  FormGoToAddress := TFormGoToAddress.Create(nil);
     96  try
     97    if FormGoToAddress.ShowModal = mrOk then begin
     98      if TryStrToInt(FormGoToAddress.EditAddress.Text, Address) then
     99        FormDisassembler.SelectAddress(Address);
     100    end;
     101  finally
     102    FormGoToAddress.Free;
     103  end;
     104end;
     105
    82106procedure TCore.APauseExecute(Sender: TObject);
    83107begin
    84108  SharpMz800.Cpu.Running := False;
     109  UpdateInterface;
     110end;
     111
     112procedure TCore.AResetExecute(Sender: TObject);
     113var
     114  IsRunning: Boolean;
     115begin
     116  IsRunning := SharpMz800.Cpu.Running;
     117  SharpMz800.Cpu.Running := False;
     118  SharpMz800.Cpu.Reset;
     119  SharpMz800.Cpu.Running := IsRunning;
    85120  UpdateInterface;
    86121end;
     
    142177  if not Assigned(FormMemory) then begin
    143178    FormMemory := TFormMemory.Create(nil);
    144     FormMemory.Size := SharpMz800.MappedMemory.Size;
    145     FormMemory.Memory := SharpMz800.MappedMemory;
     179    FormMemory.Areas.Add(SharpMz800.Memory);
     180    FormMemory.Areas.Add(SharpMz800.BaseRom);
     181    FormMemory.Areas.Add(SharpMz800.ExtendedRom);
     182    FormMemory.Areas.Add(SharpMz800.VideoRam);
     183    FormMemory.Areas.Add(SharpMz800.CharacterRom);
     184    FormMemory.Areas.Add(SharpMz800.MappedIO);
    146185  end;
    147186  FormMemory.Show;
     187end;
     188
     189procedure TCore.AViewMessagesExecute(Sender: TObject);
     190begin
     191  if not Assigned(FormMessages) then begin
     192    FormMessages := TFormMessages.Create(nil);
     193    SharpMz800.OnMessage := FormMessages.AddMessage;
     194  end;
     195  FormMessages.Show;
    148196end;
    149197
     
    162210  if Assigned(FormMemory) then FreeAndNil(FormMemory);
    163211  if Assigned(FormScreen) then FreeAndNil(FormScreen);
     212  if Assigned(FormMessages) then FreeAndNil(FormMessages);
    164213  FreeAndNil(FormMain);
    165214  FreeAndNil(SharpMz800);
  • trunk/CpuZ80.pas

    r2 r5  
    44
    55uses
    6   Classes, SysUtils, Memory;
     6  Classes, SysUtils, Memory, Base;
    77
    88type
    9   TReadEvent = function (Address: Word): Byte of object;
    10   TWriteEvent = procedure (Address: Word; Data: Byte) of object;
    11 
    129  TInstruction = (inNop = 0, inLdBcNn = $1, inLdBcIndirectA = $2,
    1310    inIncBc = $3, inIncB = $4, inDecB = $5, inLdBN = $6, inRlca = $7,
     
    3835  TRegBC = record
    3936    case Byte of
    40       0: (B, C: Byte);
     37      0: (C, B: Byte);
    4138      1: (Value: Word);
    4239  end;
     
    4441  TRegDE = record
    4542    case Byte of
    46       0: (D, E: Byte);
     43      0: (E, D: Byte);
    4744      1: (Value: Word);
    4845  end;
     
    5047  TRegHL = record
    5148    case Byte of
    52       0: (H, L: Byte);
     49      0: (L, H: Byte);
    5350      1: (Value: Word);
    5451  end;
     
    6158  private
    6259    FOnInput: TReadEvent;
     60    FOnMessage: TMessageEvent;
    6361    FOnOutput: TWriteEvent;
    6462    FOnRead: TReadEvent;
     
    6765    FThread: TCpuThread;
    6866    Instruction: TInstruction;
     67    MessageText: string;
    6968    procedure SetRunning(AValue: Boolean);
    7069    function DoRead(Address: Word): Byte;
     
    7271    function DoInput(Address: Word): Byte;
    7372    procedure DoOutput(Address: Word; Data: Byte);
     73    procedure DoMessage(Text: string);
     74    procedure DoMessageSync;
    7475    function ReadByte: Byte;
    7576    function ReadWord: Word;
    76     procedure PushWord(Data: Word); inline;
    77     function PopWord: Word; inline;
    78     procedure Call(Address: Word); inline;
    79     procedure Cp(Data: Byte); inline;
    80     procedure Jr(Condition: Boolean); inline;
    81     procedure Jp(Condition: Boolean); inline;
     77    procedure PushWord(Data: Word);
     78    function PopWord: Word;
     79    procedure Call(Address: Word);
     80    procedure Cp(Data: Byte);
     81    procedure Jr(Condition: Boolean);
     82    procedure Jp(Condition: Boolean);
     83    procedure Halt;
    8284  public
    8385    A: Byte;
     
    104106    property OnInput: TReadEvent read FOnInput write FOnInput;
    105107    property OnOutput: TWriteEvent read FOnOutput write FOnOutput;
    106   end;
     108    property OnMessage: TMessageEvent read FOnMessage write FOnMessage;
     109  end;
     110
    107111
    108112implementation
     
    164168end;
    165169
     170procedure TCpuZ80.DoMessage(Text: string);
     171begin
     172  MessageText := Text;
     173  FThread.Synchronize(DoMessageSync);
     174  MessageText := '';
     175end;
     176
     177procedure TCpuZ80.DoMessageSync;
     178begin
     179  if Assigned(FOnMessage) then FOnMessage(MessageText);
     180end;
     181
    166182function TCpuZ80.ReadByte: Byte;
    167183begin
     
    206222procedure TCpuZ80.Jr(Condition: Boolean);
    207223var
    208   Temp: Byte;
    209 begin
    210   Temp := ReadByte;
     224  Temp: ShortInt;
     225begin
     226  Temp := ShortInt(ReadByte);
    211227  if Condition then
    212     PC := PC + ShortInt(Temp);
     228    PC := PC + Temp;
    213229end;
    214230
     
    219235  Temp := ReadWord;
    220236  if Condition then PC := Temp;
     237end;
     238
     239procedure TCpuZ80.Halt;
     240begin
     241  FThread.Terminate;
    221242end;
    222243
     
    293314    inRst28: Call($28);
    294315    inRst30: Call($30);
    295     inRst38: Call($08);
     316    inRst38: Call($38);
    296317    inDi: InterruptEnabled := False;
    297318    inEi: InterruptEnabled := True;
     
    315336    inJrNzD: Jr(not Zero);
    316337    inJrNcD: Jr(not Carry);
    317     else raise Exception.Create('Unsupported instruction ' + IntToHex(Word(Instruction), 4));
     338    else begin
     339      Dec(PC);
     340      DoMessage('Unsupported instruction ' + IntToHex(Word(Instruction), 4) + ' on address ' + IntToHex(Word(PC), 4));
     341      Halt;
     342    end;
    318343  end;
    319344  Ticks := Cardinal(Ticks + 1);
  • trunk/Disassembler.pas

    r2 r5  
    2424  TDecodedInstructions = class(TObjectList<TDecodedInstruction>)
    2525    function SearchAddress(Address: Word): TDecodedInstruction;
     26    function SearchAddressIndex(Address: Word): Integer;
    2627  end;
    2728
     
    5253  if I < Count then Result := Items[I]
    5354    else Result := nil;
     55end;
     56
     57function TDecodedInstructions.SearchAddressIndex(Address: Word): Integer;
     58var
     59  I: Integer;
     60begin
     61  I := 0;
     62  while (I < Count) and (Items[I].Address <> Address) do Inc(I);
     63  if I < Count then Result := I
     64    else Result := -1;
    5465end;
    5566
  • trunk/Forms/FormCpu.pas

    r2 r5  
    2020  end;
    2121
     22
    2223implementation
    2324
  • trunk/Forms/FormDisassembler.lfm

    r2 r5  
    88  ClientWidth = 1056
    99  DesignTimePPI = 144
     10  LCLVersion = '4.6.0.0'
    1011  OnClose = FormClose
    1112  OnCreate = FormCreate
    1213  OnDestroy = FormDestroy
    1314  OnShow = FormShow
    14   LCLVersion = '2.2.6.0'
    1515  object ListView1: TListView
    1616    Left = 0
  • trunk/Forms/FormDisassembler.pas

    r2 r5  
    7171  Item: TListItem;
    7272  DecodedInstruction: TDecodedInstruction;
     73  Index: Integer;
    7374begin
    74   DecodedInstruction := Disassembler.DecodedInstructions.SearchAddress(Address);
    75   if Assigned(DecodedInstruction) then begin
    76     Item := ListView1.Items[Disassembler.DecodedInstructions.IndexOf(DecodedInstruction)];
     75  Index := Disassembler.DecodedInstructions.SearchAddressIndex(Address);
     76  if Index >= 0 then begin
     77    DecodedInstruction := Disassembler.DecodedInstructions[Index];
     78    Item := ListView1.Items[Index];
    7779    if Assigned(Item) then begin
    7880      Item.MakeVisible(False);
    79       Item.Focused := True;
    80       Item.Selected := True;
     81      //Item.Focused := False;
     82      //Item.Selected := False;
     83      //Item.Focused := True;
     84      //Item.Selected := True;
     85      ListView1.ItemIndex := Index;
     86      ListView1.Selected := ListView1.Items[Index];
     87      ListView1.Items[Index].Focused := True;
    8188    end;
    8289  end;
  • trunk/Forms/FormMain.lfm

    r2 r5  
    55  Width = 1061
    66  Caption = 'SHARP MZ-800 emulator'
    7   ClientHeight = 682
     7  ClientHeight = 716
    88  ClientWidth = 1061
    99  DesignTimePPI = 144
    1010  Menu = MainMenu1
     11  LCLVersion = '4.6.0.0'
    1112  OnClose = FormClose
    1213  OnCreate = FormCreate
    1314  OnDestroy = FormDestroy
    1415  OnShow = FormShow
    15   LCLVersion = '2.2.6.0'
    1616  object PanelLeft: TPanel
    1717    Left = 0
    18     Height = 682
     18    Height = 716
    1919    Top = 0
    2020    Width = 231
     
    2525  object PanelRight: TPanel
    2626    Left = 806
    27     Height = 682
     27    Height = 716
    2828    Top = 0
    2929    Width = 255
     
    3434  object Splitter1: TSplitter
    3535    Left = 231
    36     Height = 682
     36    Height = 716
    3737    Top = 0
    3838    Width = 8
     
    4040  object Splitter2: TSplitter
    4141    Left = 798
    42     Height = 682
     42    Height = 716
    4343    Top = 0
    4444    Width = 8
     
    4848  object PanelCenter: TPanel
    4949    Left = 239
    50     Height = 682
     50    Height = 716
    5151    Top = 0
    5252    Width = 559
    5353    Align = alClient
    5454    BevelOuter = bvNone
     55    ClientHeight = 716
     56    ClientWidth = 559
    5557    TabOrder = 4
     58    object PanelBottom: TPanel
     59      Left = 0
     60      Height = 164
     61      Top = 552
     62      Width = 559
     63      Align = alBottom
     64      BevelOuter = bvNone
     65      TabOrder = 0
     66    end
    5667  end
    5768  object MainMenu1: TMainMenu
    5869    Left = 216
    5970    Top = 64
    60     object MenuItem1: TMenuItem
     71    object MenuItemFile: TMenuItem
    6172      Caption = 'File'
    6273      object MenuItem4: TMenuItem
     
    6475      end
    6576    end
    66     object MenuItem5: TMenuItem
     77    object MenuItemEdit: TMenuItem
     78      Caption = 'Edit'
     79      object MenuItem1: TMenuItem
     80        Action = Core.AGoToAddress
     81      end
     82    end
     83    object MenuItemView: TMenuItem
    6784      Caption = 'View'
    6885      object MenuItem6: TMenuItem
     
    7996      end
    8097    end
    81     object MenuItem2: TMenuItem
     98    object MenuItemDebug: TMenuItem
    8299      Caption = 'Debug'
    83100      object MenuItem3: TMenuItem
     
    86103      object MenuItem8: TMenuItem
    87104        Action = Core.APause
     105      end
     106      object MenuItem2: TMenuItem
     107        Action = Core.AReset
     108      end
     109      object Separator1: TMenuItem
     110        Caption = '-'
    88111      end
    89112      object MenuItem13: TMenuItem
  • trunk/Forms/FormMain.pas

    r2 r5  
    1313    MainMenu1: TMainMenu;
    1414    MenuItem1: TMenuItem;
     15    MenuItem2: TMenuItem;
     16    Separator1: TMenuItem;
     17    MenuItemFile: TMenuItem;
    1518    MenuItem10: TMenuItem;
    1619    MenuItem11: TMenuItem;
     
    1922    MenuItem14: TMenuItem;
    2023    MenuItem15: TMenuItem;
    21     MenuItem2: TMenuItem;
     24    MenuItemEdit: TMenuItem;
     25    MenuItemDebug: TMenuItem;
    2226    MenuItem3: TMenuItem;
    2327    MenuItem4: TMenuItem;
    24     MenuItem5: TMenuItem;
     28    MenuItemView: TMenuItem;
    2529    MenuItem6: TMenuItem;
    2630    MenuItem7: TMenuItem;
    2731    MenuItem8: TMenuItem;
    2832    MenuItem9: TMenuItem;
     33    PanelBottom: TPanel;
    2934    PanelLeft: TPanel;
    3035    PanelRight: TPanel;
     
    6671  Core.Core.AViewScreen.Execute;
    6772  Core.Core.AViewDissssembler.Execute;
     73  Core.Core.AViewMessages.Execute;
    6874  DockForm(Core.Core.FormScreen, PanelCenter);
    6975  DockForm(Core.Core.FormCpu, PanelRight);
    7076  DockForm(Core.Core.FormDisassembler, PanelLeft);
     77  DockForm(Core.Core.FormMessages, PanelBottom);
    7178end;
    7279
  • trunk/Forms/FormMemory.lfm

    r2 r5  
    88  ClientWidth = 1150
    99  DesignTimePPI = 144
     10  LCLVersion = '4.6.0.0'
     11  OnCreate = FormCreate
     12  OnDestroy = FormDestroy
    1013  OnShow = FormShow
    11   LCLVersion = '2.2.6.0'
    1214  object ListViewMemory: TListView
    13     Left = 8
    14     Height = 850
    15     Top = 8
    16     Width = 1134
    17     Align = alClient
     15    Left = 0
     16    Height = 810
     17    Top = 48
     18    Width = 1142
     19    Align = alCustom
    1820    Anchors = [akTop, akLeft, akBottom]
    1921    BorderSpacing.Around = 8
     
    2931      item
    3032        Caption = 'ASCII'
    31         Width = 356
     33        Width = 364
    3234      end>
    3335    Font.Height = -20
     
    3941    OnData = ListViewMemoryData
    4042  end
     43  object Label1: TLabel
     44    Left = 8
     45    Height = 26
     46    Top = 8
     47    Width = 44
     48    Caption = 'Area:'
     49  end
     50  object ComboBoxArea: TComboBox
     51    Left = 104
     52    Height = 42
     53    Top = 0
     54    Width = 334
     55    ItemHeight = 0
     56    Style = csDropDownList
     57    TabOrder = 1
     58    OnSelect = ComboBoxAreaSelect
     59  end
    4160  object Timer1: TTimer
    4261    Interval = 500
  • trunk/Forms/FormMemory.pas

    r2 r5  
    55uses
    66  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ComCtrls, ExtCtrls,
    7   Memory;
     7  StdCtrls, Memory, Generics.Collections;
    88
    99type
     
    1313
    1414  TFormMemory = class(TForm)
     15    ComboBoxArea: TComboBox;
     16    Label1: TLabel;
    1517    ListViewMemory: TListView;
    1618    Timer1: TTimer;
     19    procedure ComboBoxAreaSelect(Sender: TObject);
     20    procedure FormCreate(Sender: TObject);
     21    procedure FormDestroy(Sender: TObject);
    1722    procedure FormShow(Sender: TObject);
    1823    procedure ListViewMemoryData(Sender: TObject; Item: TListItem);
    1924    procedure Timer1Timer(Sender: TObject);
    20   public
     25  private
    2126    Memory: TMemory;
    2227    Size: Integer;
     28  public
     29    Areas: TObjectList<TMemory>;
     30    procedure ReloadAreas;
    2331    procedure Reload;
    2432  end;
     
    6573procedure TFormMemory.FormShow(Sender: TObject);
    6674begin
     75  ReloadAreas;
     76  ComboBoxAreaSelect(nil);
     77end;
     78
     79procedure TFormMemory.FormCreate(Sender: TObject);
     80begin
     81  Areas := TObjectList<TMemory>.Create(False);
     82end;
     83
     84procedure TFormMemory.ComboBoxAreaSelect(Sender: TObject);
     85begin
     86  if ComboBoxArea.ItemIndex >= 0 then begin
     87    Memory := TMemory(ComboBoxArea.Items.Objects[ComboBoxArea.ItemIndex]);
     88    Size := Memory.Size;
     89  end else begin
     90    Memory := nil;
     91    Size := 0;
     92  end;
    6793  Reload;
     94end;
     95
     96procedure TFormMemory.FormDestroy(Sender: TObject);
     97begin
     98  FreeAndNil(Areas);
    6899end;
    69100
     
    73104end;
    74105
     106procedure TFormMemory.ReloadAreas;
     107var
     108  I: Integer;
     109begin
     110  ComboBoxArea.Items.BeginUpdate;
     111  try
     112    while ComboBoxArea.Items.Count > Areas.Count do
     113      ComboBoxArea.Items.Delete(ComboBoxArea.Items.Count - 1);
     114    while ComboBoxArea.Items.Count < Areas.Count do
     115      ComboBoxArea.Items.Add('');
     116    for I := 0 to Areas.Count - 1 do begin
     117      ComboBoxArea.Items.Strings[I] := Areas[I].Title;
     118      ComboBoxArea.Items.Objects[I] := Areas[I];
     119    end;
     120    if (ComboBoxArea.ItemIndex = -1) and (ComboBoxArea.Items.Count > 0) then
     121      ComboBoxArea.ItemIndex := 0;
     122  finally
     123    ComboBoxArea.Items.EndUpdate;
     124  end;
     125end;
     126
    75127end.
    76128
  • trunk/Memory.pas

    r2 r5  
    44
    55uses
    6   Classes, SysUtils, Generics.Collections;
     6  Classes, SysUtils, Generics.Collections, Base;
    77
    88type
     
    1515    procedure SetSize(AValue: Integer); virtual;
    1616  public
     17    Title: string;
    1718    Position: Integer;
    1819    function Read(Address: Word): Byte; virtual;
     
    3435    procedure Write(Address: Word; Data: Byte); override;
    3536    procedure LoadFromFile(FileName: string); override;
     37  end;
     38
     39  { TMemoryIO }
     40
     41  TMemoryIO = class(TMemory)
     42  private
     43    FOnInput: TReadEvent;
     44    FOnOutput: TWriteEvent;
     45    FSize: Integer;
     46  public
     47    BasePort: Byte;
     48    function GetSize: Integer; override;
     49    procedure SetSize(AValue: Integer); override;
     50    function Read(Address: Word): Byte; override;
     51    procedure Write(Address: Word; Data: Byte); override;
     52    property OnInput: TReadEvent read FOnInput write FOnInput;
     53    property OnOutput: TWriteEvent read FOnOutput write FOnOutput;
    3654  end;
    3755
     
    166184end;
    167185
     186{ TMemoryIO }
     187
     188function TMemoryIO.GetSize: Integer;
     189begin
     190  Result := FSize;
     191end;
     192
     193procedure TMemoryIO.SetSize(AValue: Integer);
     194begin
     195  FSize := AVAlue;
     196end;
     197
     198function TMemoryIO.Read(Address: Word): Byte;
     199begin
     200  if Assigned(FOnInput) then FOnInput(BasePort + Address);
     201end;
     202
     203procedure TMemoryIO.Write(Address: Word; Data: Byte);
     204begin
     205  if Assigned(FOnOutput) then FOnOutput(BasePort + Address, Data);
     206end;
     207
    168208{ TMemory }
    169209
  • trunk/SharpMz800.pas

    r4 r5  
    44
    55uses
    6   Classes, SysUtils, CpuZ80, Memory;
     6  Classes, SysUtils, CpuZ80, Memory, Base;
    77
    88type
     9  TMode = (md800, md700);
     10  TResolution = (rs320x200, rs640x200);
     11
    912  { TSharpMz800 }
    1013
    1114  TSharpMz800 = class
    1215  private
     16    WriteFormatRegister: Byte; // WF
     17    ReadFormatRegister: Byte; // RF
     18    DisplayModeRegister: Byte; // DMD
     19    MemoryBankControl: array[0..6] of Byte;
     20    FOnMessage: TMessageEvent;
     21    Mode: TMode;
     22    Resolution: TResolution;
     23    procedure CpuWrite(Address: Word; Data: Byte);
     24    function CpuRead(Address: Word): Byte;
     25    function CpuInput(Address: Word): Byte;
     26    procedure CpuOutput(Address: Word; Data: Byte);
     27    procedure MesssageExecute(Text: string);
     28    procedure UpdateMemoryMapping;
    1329  public
    1430    Cpu: TCpuZ80;
     
    1935    CharacterRom: TMemoryData;
    2036    MappedMemory: TMemoryMapped;
    21     procedure CpuWrite(Address: Word; Data: Byte);
    22     function CpuRead(Address: Word): Byte;
     37    MappedIO: TMemoryIO;
    2338    procedure PowerOn;
    2439    procedure PowerOff;
    2540    constructor Create;
    2641    destructor Destroy; override;
     42    property OnMessage: TMessageEvent read FOnMessage write FOnMessage;
    2743  end;
    2844
     
    4258end;
    4359
     60function TSharpMz800.CpuInput(Address: Word): Byte;
     61begin
     62  Result := 0;
     63end;
     64
     65procedure TSharpMz800.CpuOutput(Address: Word; Data: Byte);
     66begin
     67  case Address of
     68    $cc: WriteFormatRegister := Data;
     69    $cd: ReadFormatRegister := Data;
     70    $ce: begin
     71      DisplayModeRegister := Data;
     72      if (DisplayModeRegister and 8) <> 0 then Mode := md700 else Mode := md800;
     73      if (DisplayModeRegister and 4) <> 0 then Resolution := rs320x200 else Resolution := rs640x200;
     74      UpdateMemoryMapping;
     75    end;
     76    $e0..$e6: MemoryBankControl[Address - $e0] := Data;
     77  end;
     78end;
     79
     80procedure TSharpMz800.MesssageExecute(Text: string);
     81begin
     82  if Assigned(FOnMessage) then FOnMessage(Text);
     83end;
     84
     85procedure TSharpMz800.UpdateMemoryMapping;
     86begin
     87  MappedMemory.Areas.Clear;
     88  MappedMemory.Areas.AddNew($0, BaseRom);
     89  case Mode of
     90    md700: begin
     91      MappedMemory.Areas.AddNew($d000, VideoRam);
     92      VideoRam.Size := $1000;
     93      MappedMemory.Areas.AddNew($e000, MappedIO);
     94      MappedMemory.Areas.AddNew($e010, ExtendedRom);
     95    end;
     96    md800: begin
     97      MappedMemory.Areas.AddNew($1000, CharacterRom);
     98      MappedMemory.Areas.AddNew($8000, VideoRam);
     99      VideoRam.Size := $1000;
     100      MappedMemory.Areas.AddNew($e000, ExtendedRom);
     101    end;
     102  end;
     103  MappedMemory.Areas.AddNew($0, Memory);
     104end;
     105
    44106procedure TSharpMz800.PowerOn;
    45107begin
     
    56118  RomSubDir = 'ROM';
    57119begin
     120  Mode := md800;
     121  Resolution := rs320x200;
    58122  Memory := TMemoryData.Create;
     123  Memory.Title := 'Main memory';
    59124  Memory.Size := 65536; // $10000
    60125  BaseRom := TMemoryData.Create;
     126  BaseRom.Title := 'Base ROM';
    61127  BaseRom.LoadFromFile(RomSubDir + DirectorySeparator + 'MZ700A.ROM');
    62128  ExtendedRom := TMemoryData.Create;
     129  ExtendedRom.Title := 'Extended ROM';
    63130  ExtendedRom.LoadFromFile(RomSubDir + DirectorySeparator + '9Z_504M.ROM');
    64131  CharacterRom := TMemoryData.Create;
     132  CharacterRom.Title := 'Character ROM (CGROM)';
    65133  CharacterRom.LoadFromFile(RomSubDir + DirectorySeparator + 'CGROM.ROM');
    66134  VideoRam := TMemoryData.Create;
     135  VideoRam.Title := 'Video memory (VRAM)';
    67136  VideoRam.Size := 4096; // $1000
    68137  MappedMemory := TMemoryMapped.Create;
    69138  MappedMemory.Size := $10000;
    70   MappedMemory.Areas.AddNew($0, BaseRom);
    71   MappedMemory.Areas.AddNew($1000, CharacterRom);
    72   MappedMemory.Areas.AddNew($e000, ExtendedRom);
    73   MappedMemory.Areas.AddNew($0, Memory);
     139  MappedIO := TMemoryIO.Create;
     140  MappedIO.Title := 'Mapped I/O';
     141  MappedIO.Size := 8;
     142  MappedIO.BasePort := $d0;
     143  UpdateMemoryMapping;
    74144  Cpu := TCpuZ80.Create;
    75145  Cpu.Memory := MappedMemory;
    76146  Cpu.OnRead := CpuRead;
    77147  Cpu.OnWrite := CpuWrite;
     148  Cpu.OnInput := CpuInput;
     149  Cpu.OnOutput := CpuOutput;
     150  Cpu.OnMessage := MesssageExecute;
    78151end;
    79152
     
    87160  FreeAndNil(ExtendedRom);
    88161  FreeAndNil(Memory);
     162  FreeAndNil(MappedIO);
    89163  inherited;
    90164end;
  • trunk/mzxemu.lpi

    r3 r5  
    139139        <ResourceBaseClass Value="Form"/>
    140140      </Unit>
     141      <Unit>
     142        <Filename Value="Forms/FormGoToAddress.pas"/>
     143        <IsPartOfProject Value="True"/>
     144        <ComponentName Value="FormGoToAddress"/>
     145        <ResourceBaseClass Value="Form"/>
     146      </Unit>
     147      <Unit>
     148        <Filename Value="Forms/FormMessages.pas"/>
     149        <IsPartOfProject Value="True"/>
     150        <ComponentName Value="FormMessages"/>
     151        <ResourceBaseClass Value="Form"/>
     152      </Unit>
     153      <Unit>
     154        <Filename Value="Forms/Base.pas"/>
     155        <IsPartOfProject Value="True"/>
     156      </Unit>
    141157    </Units>
    142158  </ProjectOptions>
  • trunk/mzxemu.lpr

    r3 r5  
    1212  SysUtils, Interfaces, // this includes the LCL widgetset
    1313  Forms, FormMain, FormMemory, FormDisassembler, CpuZ80, SharpMz800, Memory,
    14   Core, Instructions, Disassembler, FormCpu, FormScreen
     14  Core, Instructions, Disassembler, FormCpu, FormScreen, FormGoToAddress,
     15FormMessages, Base
    1516  { you can add units after this };
    1617
Note: See TracChangeset for help on using the changeset viewer.