Lazarus compatibility, bug fixes VIC-20 Keyboard problem, Memory leak and Display grids, "{$R-}" in emulator for better debugging.

This commit is contained in:
Ekkehard Domning
2025-04-30 12:03:36 +02:00
parent 6056b482b2
commit e36f564e00
4 changed files with 165 additions and 43 deletions

View File

@@ -27,6 +27,10 @@
}
unit MOS6502;
{$IFDEF FPC}
{$MODE Delphi}
{$ENDIF}
interface
type
@@ -889,7 +893,7 @@ begin
if (Offset and $80) <> 0 then
Offset := Offset or $FF00;
Addr := Pc + Offset;
{$R-}Addr := Pc + Offset;{$R+}
Result := Addr;
end;
@@ -1081,7 +1085,7 @@ var
begin
M := Read(Src);
SET_CARRY((M and $80) <> 0);
M := M shl 1;
{$R-}M := M shl 1;{$R+}
M := M and $FF;
SET_NEGATIVE((M and $80) <> 0);
SET_ZERO(M = 0);
@@ -1094,7 +1098,7 @@ var
begin
M := A;
SET_CARRY((M and $80) <> 0);
M := M shl 1;
{$R-}M := M shl 1;{$R+}
M := M and $FF;
SET_NEGATIVE((M and $80) <> 0);
SET_ZERO(M = 0);
@@ -1195,7 +1199,7 @@ procedure TMOS6502.Op_CMP(Src: Word);
var
Tmp: Cardinal;
begin
Tmp := A - Read(Src);
{$R-}Tmp := A - Read(Src);{$R+}
SET_CARRY(Tmp < $100);
SET_NEGATIVE((Tmp and $80) <> 0);
SET_ZERO((Tmp and $FF)=0);
@@ -1205,7 +1209,7 @@ procedure TMOS6502.Op_CPX(Src: Word);
var
Tmp: Cardinal;
begin
Tmp := X - Read(Src);
{$R-}Tmp := X - Read(Src);{$R+}
SET_CARRY(Tmp < $100);
SET_NEGATIVE((Tmp and $80) <> 0);
SET_ZERO((Tmp and $FF)=0);
@@ -1215,7 +1219,7 @@ procedure TMOS6502.Op_CPY(Src: Word);
var
Tmp: Cardinal;
begin
Tmp := Y - Read(Src);
{$R-}Tmp := Y - Read(Src);{$R+}
SET_CARRY(Tmp < $100);
SET_NEGATIVE((Tmp and $80) <> 0);
SET_ZERO((Tmp and $FF)=0);
@@ -1226,7 +1230,7 @@ var
M: Byte;
begin
M := Read(Src);
M := M - 1;
{$R-}M := M - 1;{$R+}
SET_NEGATIVE((M and $80) <> 0);
SET_ZERO(M = 0);
Write(Src, M);
@@ -1237,7 +1241,7 @@ var
M: Byte;
begin
M := X;
M := M - 1;
{$R-}M := M - 1;{$R+}
SET_NEGATIVE((M and $80) <> 0);
SET_ZERO(M = 0);
X := M;
@@ -1248,7 +1252,7 @@ var
M: Byte;
begin
M := Y;
M := M - 1;
{$R-}M := M - 1;{$R+}
SET_NEGATIVE((M and $80) <> 0);
SET_ZERO(M = 0);
Y := M;
@@ -1259,7 +1263,7 @@ var
M: Byte;
begin
M := Read(Src);
M := A xor M;
{$R-}M := A xor M;{$R+}
SET_NEGATIVE((M and $80) <> 0);
SET_ZERO(M = 0);
A := M;
@@ -1270,7 +1274,7 @@ var
M: Byte;
begin
M := Read(Src);
M := M + 1;
{$R-}M := M + 1;{$R+}
SET_NEGATIVE((M and $80) <> 0);
SET_ZERO(M = 0);
Write(Src, M);
@@ -1281,7 +1285,7 @@ var
M: Byte;
begin
M := X;
M := M + 1;
{$R-}M := M + 1;{$R+}
SET_NEGATIVE((M and $80) <> 0);
SET_ZERO(M = 0);
X := M;
@@ -1292,7 +1296,7 @@ var
M: Byte;
begin
M := Y;
M := M + 1;
{$R-}M := M + 1;{$R+}
SET_NEGATIVE((M and $80) <> 0);
SET_ZERO(M = 0);
Y := M;
@@ -1527,7 +1531,7 @@ var
Tmp: Word;
begin
M := Read(Src);
Tmp := A - M - (1-IF_CARRY);
{$R-}Tmp := A - M - (1-IF_CARRY);{$R+}
SET_NEGATIVE((Tmp and $80) <> 0);

View File

@@ -1,10 +1,18 @@
unit FormV20;
{$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, VIC20, Vcl.StdCtrls, Vcl.ExtCtrls;
{$IFnDEF FPC}
Vcl.Forms, Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls,
{$ELSE}
Forms, Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Dialogs, StdCtrls, ExtCtrls,
{$ENDIF}
VIC20;
const
ScreenZoom = 2;
@@ -14,6 +22,9 @@ const
ColorTable: array [0 .. 2] of Cardinal = ($801010, $D0A0A0, $D0A0A0);
type
{ TFrmVC20 }
TFrmVC20 = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
@@ -33,9 +44,15 @@ var
implementation
{$R *.dfm}
{$IFnDEF FPC}
{$R *.dfm}
{$ELSE}
{$R *.lfm}
{$ENDIF}
procedure TFrmVC20.FormCreate(Sender: TObject);
var
fp : String;
begin
ClientWidth := ScreenWidth;
ClientHeight := ScreenHeight;
@@ -46,8 +63,14 @@ begin
VC20 := TVC20.Create;
VC20.WndHandle := Handle;
VC20.LoadROM('..\ROMs\kernal.901486-06.bin', $E000); // E000-FFFF
VC20.LoadROM('..\ROMs\basic.901486-01.bin', $C000); // C000-DFFF
fp := IncludeTrailingPathDelimiter(ExtractFilePath(Application.ExeName));
{$IFDEF FPC}
fp := fp + '..\..\';
{$ENDIF}
VC20.LoadROM(fp+'..\ROMs\kernal.901486-07.bin', $E000); // E000-FFFF
VC20.LoadROM(fp+'..\ROMs\basic.901486-01.bin', $C000); // C000-DFFF
VC20.LoadROM(fp+'..\ROMs\characters.901460-03.bin', $8000); // 8000-8FFF
VC20.Exec;
end;
@@ -77,6 +100,8 @@ var
Flag: Cardinal;
Q1: Byte;
Sc: Char;
PxX, PxY, ChrWH : Integer;
sz : TSize;
begin
Addr := Msg.WParam;
Value := Msg.LParam;
@@ -90,7 +115,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.

View File

@@ -1,9 +1,18 @@
unit VIC20;
{$IFDEF FPC}
{$MODE Delphi}
{$ENDIF}
interface
uses
System.Classes, WinApi.Messages, MOS6502;
{$IFnDEF FPC}
WinApi.Messages, System.Classes,
{$ELSE}
Windows, Classes,
{$ENDIF}
MOS6502;
const
WM_SCREEN_WRITE = WM_USER + 0;
@@ -11,23 +20,82 @@ const
CIA1 = $9120; // $DC00;
// VIC-20 keyboard matrix
KEY_TRANSLATION = '2q'#0' '#27#0#0'1'+
'4esz'#0'aw3'+
'6tfcxdr5'+
'8uhbvgy7'+
'0okmnji9'+
'-@:.,lp+'+
#0#0'='#0'/;*<2A>'+
#0#0#0#0#0#0#13#8+
{
Found at: https://www.lemon64.com/forum/viewtopic.php?t=68210
'"'#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'[><l'#0#0+
#0#0'='#0'?]'#0#0+
#0#0#0#0#0#0#13#8;
VIC20 Keyboard Matrix
Write to Port B($9120)column
Read from Port A($9121)row
7 6 5 4 3 2 1 0
--------------------------------
7| F7 F5 F3 F1 CDN CRT RET DEL CRT=Cursor-Right, CDN=Cursor-Down
|
6| HOM UA = RSH / ; * BP BP=British Pound, RSH=Should be Right-SHIFT,
| UA=Up Arrow
5| - @ : . , L P +
|
4| 0 O K M N J I 9
|
3| 8 U H B V G Y 7
|
2| 6 T F C X D R 5
|
1| 4 E S Z LSH A W 3 LSH=Should be Left-SHIFT
|
0| 2 Q CBM SPC STP CTL LA 1 LA=Left Arrow, CTL=Should be CTRL, STP=RUN/STOP
| CBM=Commodore key
C64/VIC20 Keyboard Layout
LA 1 2 3 4 5 6 7 8 9 0 + - BP HOM DEL F1
CTRL Q W E R T Y U I O P @ * UA RESTORE F3
STOP SL A S D F G H J K L : ; = RETURN F5
C= SHIFT Z X C V B N M , . / SHIFT CDN CRT F7
[ SPACE BAR ]
Keyboard Connector
Pin Desc.
1 Ground
2 [key]
3 RESTORE key
4 +5 volts
5 Column 7, Joy 3
6 Column 6
7 Column 5
8 Column 4
9 Column 3, Tape Write(E5)
10 Column 2
11 Column 1
12 Column 0
13 Row 7
14 Row 6
15 Row 5
16 Row 4
17 Row 3
18 Row 2
19 Row 1
20 Row 0
}
KEY_TRANSLATION = '2'+'q'+#00+' '+#27+#00+#00+'1'+ // $00..$07 0
'4'+'e'+'s'+'z'+#00+'a'+'w'+'3'+ // $08..$0f
'6'+'t'+'f'+'c'+'x'+'d'+'r'+'5'+ // $10..$17
'8'+'u'+'h'+'b'+'v'+'g'+'y'+'7'+ // $18..$1f
'0'+'o'+'k'+'m'+'n'+'j'+'i'+'9'+ // $20..$27
'-'+'@'+':'+'.'+','+'l'+'p'+'+'+ // $28..$2f
#00+#00+'='+#00+'/'+';'+'*'+#00+ // $30..$37 // '<27>' is not working
#00+#00+#00+#00+#00+#00+#13+#08+ // $38..$3f 63
'"'+#00+#00+#00+#00+#00+#00+'!'+ // $40..$47 64
'$'+#00+#00+#00+#00+#00+#00+'#'+ // $48..$4f
'&'+#00+#00+#00+#00+#00+#00+'%'+ // $50..$57
'('+#00+#00+#00+#00+#00+#00+''''+ // $58..$5f
'0'+#00+#00+#00+#00+#00+#00+')'+ // $60..$67
'_'+#00+'['+'>'+'<'+'l'+#00+#00+ // $68..$6f
#00+#00+'='+#00+'?'+']'+#00+#00+ // $70..$77
#00+#00+#00+#00+#00+#00+#13+#08; // $78..$7f 127
type
TVC20 = class;
@@ -65,7 +133,12 @@ type
implementation
uses
System.SysUtils, Winapi.Windows, WinApi.MMSystem;
{$IFnDEF FPC}
Winapi.Windows, System.SysUtils, WinApi.MMSystem;
{$ELSE}
SysUtils, MMSystem;
{$ENDIF}
{ TVC20 }
@@ -127,6 +200,7 @@ begin
Timekillevent(TimerHandle);
Thread.Terminate;
Thread.WaitFor;
Thread.Free;
FreeMem(Memory);
inherited;
end;
@@ -144,10 +218,16 @@ begin
Result := 0;
Cols := Memory[CIA1];
for Col := 0 to 7 do
begin
if Cols and (1 shl Col) = 0 then // a 0 indicates a column read
begin
for Row := 0 to 7 do
begin
if KeyMatrix[7 - Col, Row] = 1 then
Result := Result + (1 shl Row);
end;
end;
end;
Result := not Result;
end;

View File

@@ -1,11 +1,15 @@
program VIC20Emu;
uses
Vcl.Forms,
FormV20 in 'FormV20.pas' {FrmVC20},
VIC20 in 'VIC20.pas',
MOS6502 in '..\..\Source\MOS6502.pas';
{$IFnDEF FPC}
Vcl.Forms,
{$ELSE}
Forms, Interfaces,
{$ENDIF}
FormV20 in 'FormV20.pas' {FrmVC20},
VIC20 in 'VIC20.pas',
MOS6502 in '..\..\Source\MOS6502.pas';
{$R *.res}
begin