mirror of
https://github.com/Dennis1000/mos6502-delphi.git
synced 2025-07-02 13:23:50 +00:00
Implemented changes made in the C++ implementation for the MOS Technology 6502 CPU by Gianluca Ghettini.
Updated TestSuite for Lazarus Updated C64 for Lazarus (still not running with Lazarus) Updated VIC-20
This commit is contained in:
@ -1,15 +1,28 @@
|
||||
unit C64;
|
||||
unit C64;
|
||||
|
||||
{$IFDEF FPC}
|
||||
{$MODE Delphi}
|
||||
{$ENDIF}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
System.Classes, WinApi.Messages, MOS6502;
|
||||
{$IFnDEF FPC}
|
||||
WinApi.Messages, System.Classes,
|
||||
{$ELSE}
|
||||
Messages, Classes,
|
||||
{$ENDIF}
|
||||
MOS6502;
|
||||
|
||||
const
|
||||
WM_SCREEN_WRITE = WM_USER + 0;
|
||||
|
||||
CIA1 = $DC00;
|
||||
KEY_TRANSLATION = '1<EFBFBD>+9753'#8+#8'*piyrw'#13+#0';ljgda'#0+'2'#0'-0864'#0+' '#0'.mbcz'#0+#0'=:khfs'#0+'q'#0'@oute'#0+
|
||||
{ KEY_TRANSLATION = '1£+9753'#8+#8'*piyrw'#13+#0';ljgda'#0+'2'#0'-0864'#0+' '#0'.mbcz'#0+#0'=:khfs'#0+'q'#0'@oute'#0+
|
||||
#0'/,nvx'#0#0+'!'#0#0')'#39'%#'+#0+#0#0#0#0#0#0#0#13+#0']'#0#0#0#0#0#0+'"'#0#0#0'(&$'#0+' '#0'>'#0#0#0#0#0+
|
||||
#0#0'['#0#0#0#0#0+#0#0#0#0#0#0#0#0+#0'?<';
|
||||
}
|
||||
KEY_TRANSLATION = '1'#0'+9753'#8+#8'*piyrw'#13+#0';ljgda'#0+'2'#0'-0864'#0+' '#0'.mbcz'#0+#0'=:khfs'#0+'q'#0'@oute'#0+
|
||||
#0'/,nvx'#0#0+'!'#0#0')'#39'%#'+#0+#0#0#0#0#0#0#0#13+#0']'#0#0#0#0#0#0+'"'#0#0#0'(&$'#0+' '#0'>'#0#0#0#0#0+
|
||||
#0#0'['#0#0#0#0#0+#0#0#0#0#0#0#0#0+#0'?<';
|
||||
|
||||
@ -49,7 +62,12 @@ type
|
||||
implementation
|
||||
|
||||
uses
|
||||
System.SysUtils, Winapi.Windows, WinApi.MMSystem;
|
||||
{$IFnDEF FPC}
|
||||
Winapi.Windows, System.SysUtils, WinApi.MMSystem;
|
||||
{$ELSE}
|
||||
Windows, SysUtils, MMSystem;
|
||||
{$ENDIF}
|
||||
|
||||
|
||||
{ TC64 }
|
||||
|
||||
@ -111,6 +129,7 @@ begin
|
||||
Timekillevent(TimerHandle);
|
||||
Thread.Terminate;
|
||||
Thread.WaitFor;
|
||||
Thread.Free;
|
||||
FreeMem(Memory);
|
||||
inherited;
|
||||
end;
|
||||
|
@ -1,7 +1,15 @@
|
||||
program C64Emu;
|
||||
|
||||
{$IFDEF FPC}
|
||||
{$MODE Delphi}
|
||||
{$ENDIF}
|
||||
|
||||
uses
|
||||
{$IFnDEF FPC}
|
||||
Vcl.Forms,
|
||||
{$ELSE}
|
||||
Forms, Interfaces,
|
||||
{$ENDIF }
|
||||
FormC64 in 'FormC64.pas' {FrmC64},
|
||||
C64 in 'C64.pas',
|
||||
MOS6502 in '..\..\Source\MOS6502.pas';
|
||||
|
@ -1,10 +1,18 @@
|
||||
unit FormC64;
|
||||
|
||||
{$IFDEF FPC}
|
||||
{$MODE Delphi}
|
||||
{$ENDIF}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
|
||||
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, C64;
|
||||
{$IFnDEF FPC}
|
||||
Vcl.Forms, Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Dialogs,
|
||||
{$ELSE}
|
||||
Forms, Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Dialogs,
|
||||
{$ENDIF}
|
||||
C64;
|
||||
|
||||
const
|
||||
ScreenZoom = 2;
|
||||
@ -33,9 +41,15 @@ var
|
||||
|
||||
implementation
|
||||
|
||||
{$R *.dfm}
|
||||
{$IFnDEF FPC}
|
||||
{$R *.dfm}
|
||||
{$ELSE}
|
||||
{$R *.lfm}
|
||||
{$ENDIF}
|
||||
|
||||
procedure TFrmC64.FormCreate(Sender: TObject);
|
||||
var
|
||||
fp : String;
|
||||
begin
|
||||
ClientWidth := ScreenWidth;
|
||||
ClientHeight := ScreenHeight;
|
||||
@ -46,8 +60,13 @@ begin
|
||||
|
||||
C64 := TC64.Create;
|
||||
C64.WndHandle := Handle;
|
||||
C64.LoadROM('..\ROMs\basic.901226-01.bin', $A000);
|
||||
C64.LoadROM('..\ROMs\kernal.901227-03.bin', $E000);
|
||||
fp := IncludeTrailingPathDelimiter(ExtractFilePath(Application.ExeName));
|
||||
{$IFDEF FPC}
|
||||
fp := fp + '..\..\';
|
||||
{$ENDIF}
|
||||
|
||||
C64.LoadROM(fp+'..\ROMs\basic.901226-01.bin', $A000);
|
||||
C64.LoadROM(fp+'..\ROMs\kernal.901227-03.bin', $E000);
|
||||
C64.Exec;
|
||||
end;
|
||||
|
||||
@ -77,6 +96,9 @@ var
|
||||
Flag: Cardinal;
|
||||
Q1: Byte;
|
||||
Sc: Char;
|
||||
PxX, PxY, ChrWH : Integer;
|
||||
sz : TSize;
|
||||
|
||||
begin
|
||||
Addr := Msg.WParam;
|
||||
Value := Msg.LParam;
|
||||
@ -90,7 +112,16 @@ begin
|
||||
|
||||
Canvas.Font.Color := ColorTable[1 - Flag];
|
||||
Canvas.Brush.Color := ColorTable[Flag];
|
||||
Canvas.TextOut(X * (8*ScreenZoom), Y * (8*ScreenZoom), Sc);
|
||||
Canvas.Pen.Style := psClear;
|
||||
PxX := X * (8*ScreenZoom);
|
||||
PxY := Y * (8*ScreenZoom);
|
||||
ChrWH := 8*ScreenZoom;
|
||||
Canvas.Rectangle(PxX,PxY,PxX+ChrWH+1,PxY+ChrWH+1);
|
||||
if (Sc <> #0) and (Sc <> ' ') then
|
||||
begin
|
||||
sz := Canvas.TextExtent(Sc);
|
||||
Canvas.TextOut(PxX+(ChrWH-sz.cx) div 2, PxY, Sc);
|
||||
end;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,11 +1,19 @@
|
||||
program TestSuite;
|
||||
|
||||
{$IFDEF FPC}
|
||||
{$MODE Delphi}
|
||||
{$ENDIF}
|
||||
|
||||
{$APPTYPE CONSOLE}
|
||||
|
||||
{$R *.res}
|
||||
{.$R *.res}
|
||||
|
||||
uses
|
||||
{$IFnDEF FPC}
|
||||
System.Classes, System.SysUtils,
|
||||
{$ELSE}
|
||||
Classes, SysUtils,
|
||||
{$ENDIF}
|
||||
MOS6502 in '..\..\Source\MOS6502.pas';
|
||||
|
||||
type
|
||||
@ -86,13 +94,18 @@ end;
|
||||
|
||||
var
|
||||
MOS6502: TMOS6502TestSuite;
|
||||
|
||||
fp : String;
|
||||
begin
|
||||
try
|
||||
MOS6502 := TMOS6502TestSuite.Create;
|
||||
try
|
||||
// load test bin
|
||||
MOS6502.Load('..\Test-Files\6502_functional_test.bin');
|
||||
fp := '..\Test-Files\';
|
||||
{$IFDEF FPC}
|
||||
fp := '..\..\'+ fp;
|
||||
{$ENDIF}
|
||||
|
||||
MOS6502.Load(fp+'6502_functional_test.bin');
|
||||
|
||||
// set reset vectors to $0400
|
||||
MOS6502.Memory[$FFFC] := 0;
|
||||
|
@ -126,12 +126,10 @@ type
|
||||
TimerHandle: Integer;
|
||||
LastKey: Char;
|
||||
FMemoryMap : TV20MemRangeArr;
|
||||
procedure BusWrite(Adr: Word; Value: Byte);
|
||||
function BusRead(Adr: Word): Byte;
|
||||
function GetMemoryMapKind(Index : Integer): TVC20MemKind;
|
||||
procedure OnBusWrite(Adr: Word; Value: Byte);
|
||||
function OnBusRead(Adr: Word): Byte;
|
||||
function KeyRead: Byte;
|
||||
function GetMemKind(AMemAddr : Word) : TVC20MemKind;
|
||||
procedure SetMemoryMapKind(Index : Integer; AValue: TVC20MemKind);
|
||||
protected
|
||||
KeyMatrix: Array[0 .. 7, 0 .. 7] of Byte;
|
||||
Memory: PByte;
|
||||
@ -146,7 +144,7 @@ type
|
||||
property MemKind[AMemAddr : Word] : TVC20MemKind read GetMemKind;
|
||||
property MemoryMapItemCount : Integer read GetMemoryMapItemCount;
|
||||
property MemoryMapItems[Index : Integer] : TV20MemRange read GetMemoryMapItems;
|
||||
property MemoryMapKinds[Index : Integer] : TVC20MemKind read GetMemoryMapKind write SetMemoryMapKind;
|
||||
property MemoryMapKinds[Index : Integer] : TVC20MemKind read GetMemoryMapKinds write SetMemoryMapKinds;
|
||||
constructor Create;
|
||||
destructor Destroy; override;
|
||||
procedure LoadROM(Filename: String; Addr: Word);
|
||||
@ -173,12 +171,12 @@ var
|
||||
begin
|
||||
VC20 := TVC20(dwUser);
|
||||
|
||||
if VC20.Status and VC20.INTERRUPT = 0 then // if IRQ allowed then set irq
|
||||
if VC20.Status and VC20.INTERRUPT_FLAG = 0 then // if IRQ allowed then set irq
|
||||
VC20.InterruptRequest := True;
|
||||
end;
|
||||
|
||||
|
||||
function TVC20.BusRead(Adr: Word): Byte;
|
||||
function TVC20.OnBusRead(Adr: Word): Byte;
|
||||
var
|
||||
memk : TVC20MemKind;
|
||||
begin
|
||||
@ -187,13 +185,7 @@ begin
|
||||
if memk = mkUnimplemented then
|
||||
Result := $FF;
|
||||
end;
|
||||
|
||||
function TVC20.GetMemoryMapKind(Index : Integer): TVC20MemKind;
|
||||
begin
|
||||
|
||||
end;
|
||||
|
||||
procedure TVC20.BusWrite(Adr: Word; Value: Byte);
|
||||
procedure TVC20.OnBusWrite(Adr: Word; Value: Byte);
|
||||
var
|
||||
memk : TVC20MemKind;
|
||||
begin
|
||||
@ -203,6 +195,8 @@ begin
|
||||
case Adr of
|
||||
CIA1:
|
||||
begin
|
||||
memk := MemKind[Adr];
|
||||
|
||||
// Handle keyboard reading
|
||||
Memory[Adr] := Value;
|
||||
Memory[CIA1 + 1] := KeyRead;
|
||||
@ -226,7 +220,7 @@ end;
|
||||
|
||||
constructor TVC20.Create;
|
||||
begin
|
||||
inherited Create(BusRead, BusWrite);
|
||||
inherited Create(OnBusRead, OnBusWrite);
|
||||
|
||||
// create 64kB memory table
|
||||
GetMem(Memory, 65536);
|
||||
@ -261,7 +255,7 @@ begin
|
||||
Cols := Memory[CIA1];
|
||||
for Col := 0 to 7 do
|
||||
begin
|
||||
if Cols and (1 shl Col) = 0 then // a 0 indicates a column read
|
||||
if Cols and (1 shl Col) = 0 then // FA 0 indicates FA column FBusRead
|
||||
begin
|
||||
for Row := 0 to 7 do
|
||||
begin
|
||||
@ -288,15 +282,10 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TVC20.SetMemoryMapKind(Index : Integer; AValue: TVC20MemKind);
|
||||
begin
|
||||
|
||||
end;
|
||||
|
||||
procedure TVC20.SetupMemoryMap;
|
||||
begin
|
||||
SetLength(FMemoryMap,15);
|
||||
// 0000-03FF 0-1023 Zero Page, 1K Ram
|
||||
// 0000-03FF 0-1023 ZERO_FLAG Page, 1K Ram
|
||||
FMemoryMap[0].MemDescr:= 'ZERO - System Variables';
|
||||
FMemoryMap[0].MemKind:= mkRAM;
|
||||
FMemoryMap[0].MemStartAddr:= $0000;
|
||||
@ -339,28 +328,28 @@ begin
|
||||
// 9000-93FF 36864-37887 I/O BLOCK 0 (VIC, VIA)
|
||||
FMemoryMap[8].MemDescr:= 'IOBLK0 - VIC, VIA';
|
||||
FMemoryMap[8].MemKind:= mkRegister;
|
||||
FMemoryMap[8].MemStartAddr:= $8000;
|
||||
FMemoryMap[8].MemStopAddr:= $8FFF;
|
||||
FMemoryMap[8].MemStartAddr:= $9000;
|
||||
FMemoryMap[8].MemStopAddr:= $93FF;
|
||||
// 9400-97FF 37888-38911 I/O BLOCK 1 (COLOR Nibbles)
|
||||
FMemoryMap[9].MemDescr:= 'IOBLK1 - Color Nibbles';
|
||||
FMemoryMap[9].MemKind:= mkRAM;
|
||||
FMemoryMap[9].MemStartAddr:= $8000;
|
||||
FMemoryMap[9].MemStopAddr:= $8FFF;
|
||||
FMemoryMap[9].MemStartAddr:= $9400;
|
||||
FMemoryMap[9].MemStopAddr:= $97FF;
|
||||
// 9800-9BFF 38912-39935 I/O BLOCK 2
|
||||
FMemoryMap[10].MemDescr:= 'IOBLK2';
|
||||
FMemoryMap[10].MemKind:= mkUnimplemented;
|
||||
FMemoryMap[10].MemStartAddr:= $8000;
|
||||
FMemoryMap[10].MemStopAddr:= $8FFF;
|
||||
FMemoryMap[10].MemStartAddr:= $9800;
|
||||
FMemoryMap[10].MemStopAddr:= $9BFF;
|
||||
// 9C00-9FFF 39936-40959 I/O BLOCK 3
|
||||
FMemoryMap[11].MemDescr:= 'IOBLK3';
|
||||
FMemoryMap[11].MemKind:= mkUnimplemented;
|
||||
FMemoryMap[11].MemStartAddr:= $8000;
|
||||
FMemoryMap[11].MemStopAddr:= $8FFF;
|
||||
FMemoryMap[11].MemStartAddr:= $9C00;
|
||||
FMemoryMap[11].MemStopAddr:= $9FFF;
|
||||
// A000-BFFF 40960-49152 BLK 4 <20> ROM expansion (cartridges)
|
||||
FMemoryMap[12].MemDescr:= 'BLK4 - 8K Optional ROM';
|
||||
FMemoryMap[12].MemKind:= mkUnimplemented;
|
||||
FMemoryMap[12].MemStartAddr:= $8000;
|
||||
FMemoryMap[12].MemStopAddr:= $8FFF;
|
||||
FMemoryMap[12].MemStartAddr:= $A000;
|
||||
FMemoryMap[12].MemStopAddr:= $BFFF;
|
||||
// C000-DFFF 149152-57343 BASIC <20> 8K ROM
|
||||
FMemoryMap[13].MemDescr:= 'BASICSYS <20> 8K ROM';
|
||||
FMemoryMap[13].MemKind:= mkUnimplemented; // Will be set to mkROM in the LoadROM method
|
||||
|
Reference in New Issue
Block a user