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:
Ekkehard Domning
2025-05-01 19:25:53 +02:00
parent 74eb9e2fc4
commit da1e39784c
6 changed files with 605 additions and 262 deletions

View File

@ -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;

View File

@ -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';

View File

@ -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

View File

@ -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;

View File

@ -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