Skip to content

Commit e1c987b

Browse files
committed
CPU 6502 implementation
Full implementation of 6502 CPU
1 parent 44fc64f commit e1c987b

File tree

8 files changed

+1754
-1
lines changed

8 files changed

+1754
-1
lines changed

65C02.csproj

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net5.0</TargetFramework>
6+
<RootNamespace>CPU6502</RootNamespace>
7+
<AssemblyName>CPU6502</AssemblyName>
8+
</PropertyGroup>
9+
10+
</Project>

65C02.sln

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio Version 16
4+
VisualStudioVersion = 16.0.32126.315
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "65C02", "65C02.csproj", "{D31177AD-0E61-4B06-91E3-B790A57B84AE}"
7+
EndProject
8+
Global
9+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
10+
Debug|Any CPU = Debug|Any CPU
11+
Release|Any CPU = Release|Any CPU
12+
EndGlobalSection
13+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
14+
{D31177AD-0E61-4B06-91E3-B790A57B84AE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15+
{D31177AD-0E61-4B06-91E3-B790A57B84AE}.Debug|Any CPU.Build.0 = Debug|Any CPU
16+
{D31177AD-0E61-4B06-91E3-B790A57B84AE}.Release|Any CPU.ActiveCfg = Release|Any CPU
17+
{D31177AD-0E61-4B06-91E3-B790A57B84AE}.Release|Any CPU.Build.0 = Release|Any CPU
18+
EndGlobalSection
19+
GlobalSection(SolutionProperties) = preSolution
20+
HideSolutionNode = FALSE
21+
EndGlobalSection
22+
GlobalSection(ExtensibilityGlobals) = postSolution
23+
SolutionGuid = {DC9F3E9D-93B8-40B4-A031-9301A693934A}
24+
EndGlobalSection
25+
EndGlobal

ANTIC.cs

+232
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,232 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
7+
namespace Emulators
8+
{
9+
/*
10+
* https://en.wikipedia.org/wiki/ANTIC
11+
*/
12+
public class ANTIC
13+
{
14+
public enum GraphicMode
15+
{
16+
Null,
17+
}
18+
19+
//When CPU writes value to RAM ANTIC reads that value from RAM
20+
//For below table we need to:
21+
//- read value for 'Write' registers
22+
//- write value for 'Read' registers
23+
/*
24+
DMACTL | Direct Memory Access Control | Write | $D400 | 54272 | SDMCTL | $022F | 559
25+
CHACTL | Character Control | Write | $D401 | 54273 | CHART | $02F3 | 755
26+
DLISTL | Display List Pointer (low byte) | Write | $D402 | 54274 | SDLSTL | $0230 | 560
27+
DLISTH | Display List Pointer (high byte) | Write | $D403 | 54275 | SDLSTH | $0231 | 561
28+
HSCROL | Horizontal Fine Scroll | Write | $D404 | 54276
29+
VSCROL | Vertical Fine Scroll | Write | $D405 | 54277
30+
PMBASE | Player/Missile Base Address | Write | $D407 | 54279
31+
CHBASE | Character Set Base Address | Write | $D409 | 54281 | CHBAS | $02F4 | 756
32+
WSYNC | Wait for Horizontal Sync | Write | $D40A | 54282
33+
VCOUNT | Vertical Line Counter | Read | $D40B | 54283
34+
PENH | Light Pen Horizontal Position | Read | $D40C | 54284 | LPENH | $0234 | 564
35+
PENV | Light Pen Vertical Position | Read | $D40D | 54285 | LPENV | $0235 | 565
36+
NMIEN | Non-Maskable Interrupt (NMI) Enable | Write | $D40E | 54286
37+
NMIRES | Non-Maskable Interrupt (NMI) Reset | Write | $D40F | 54287
38+
NMIST | Non-Maskable Interrupt (NMI) Status | Read | $D40F | 54287
39+
*/
40+
41+
//ANTIC registers
42+
//direct memory acces control, write, 0xd400
43+
byte DMACTL
44+
{
45+
set
46+
{
47+
//TODO: _bus.Write(0xd400, Value);
48+
}
49+
get
50+
{
51+
return _bus.Read(0xd400);
52+
}
53+
}
54+
55+
//character control, write, 0xd401
56+
byte CHACTL
57+
{
58+
set
59+
{
60+
//TODO: _bus.Write(0xd401, Value);
61+
}
62+
get
63+
{
64+
//TODO: _bus.Read(0xd400);
65+
return 0x00;
66+
}
67+
}
68+
69+
//display list pointer (low byte), write, 0xd402
70+
byte DLISTL
71+
{
72+
get
73+
{
74+
return _bus.Read(0xd402);
75+
}
76+
}
77+
78+
//display list pointer (high byte), write, 0xd403
79+
byte DLISTH
80+
{
81+
get
82+
{
83+
return _bus.Read(0xd403);
84+
}
85+
}
86+
87+
//horizontal fine scroll, write, 0xd404
88+
byte HSCROL
89+
{
90+
set
91+
{
92+
//TODO: _bus.Write(0xd404, Value);
93+
}
94+
get
95+
{
96+
//TODO: _bus.Read(0xd404);
97+
return 0x00;
98+
}
99+
}
100+
101+
//vertical fine scroll, write, 0xd405
102+
byte VSCROL
103+
{
104+
set
105+
{
106+
//TODO: _bus.Write(0xd405, Value);
107+
}
108+
get
109+
{
110+
//TODO: _bus.Read(0xd405);
111+
return 0x00;
112+
}
113+
}
114+
115+
//player/missile base address, write, 0xd407
116+
byte PMBASE
117+
{
118+
set
119+
{
120+
//TODO: _bus.Write(0xd407, Value);
121+
}
122+
get
123+
{
124+
//TODO: _bus.Read(0xd407);
125+
return 0x00;
126+
}
127+
}
128+
129+
//character set base address, write, 0xd409
130+
byte CHBASE
131+
{
132+
set
133+
{
134+
//TODO: _bus.Write(0xd409, Value);
135+
}
136+
get
137+
{
138+
//TODO: _bus.Read(0xd409);
139+
return 0x00;
140+
}
141+
}
142+
143+
//wait for sync, write, 0xd40a
144+
byte WSYNC
145+
{
146+
set
147+
{
148+
//TODO: _bus.Write(0xd40a, Value);
149+
}
150+
get
151+
{
152+
//TODO: _bus.Read(0xd40a);
153+
return 0x00;
154+
}
155+
}
156+
157+
//verctical line counter, read, 0xd40b
158+
byte VCOUNT
159+
{
160+
get
161+
{
162+
//TODO: _bus.Read(0xd40b);
163+
return 0x00;
164+
}
165+
}
166+
167+
//light pen horizontal position, read, 0xd40c
168+
//write to ram to be able to read by CPU
169+
byte PENH
170+
{
171+
get
172+
{
173+
//TODO: _bus.Read(0xd40c);
174+
return 0x00;
175+
}
176+
}
177+
178+
//light pen vertical position, read, 0xd40d
179+
//write to ram to be able to read by CPU
180+
byte PENV
181+
{
182+
set
183+
{
184+
_bus.Write(0xd40d, value);
185+
}
186+
}
187+
188+
//nmi enable, write, 0xd40e
189+
//read from ram after CPU writes the value
190+
byte NMIEN
191+
{
192+
get
193+
{
194+
return _bus.Read(0xd40e);
195+
}
196+
}
197+
198+
//nmi reset, write, 0xd40f
199+
//read from ram after CPU writes the value
200+
byte NMIRES
201+
{
202+
get
203+
{
204+
return _bus.Read(0xd40f);
205+
}
206+
}
207+
//nmi status, read
208+
//write to ram to be able to read by CPU
209+
210+
byte NMIST
211+
{
212+
set
213+
{
214+
_bus.Write(0xd40f, value);
215+
}
216+
}
217+
218+
private IBus _bus;
219+
220+
//Link ANTIC with system Bus
221+
public void ConnectBus(ref IBus bus)
222+
{
223+
_bus = bus;
224+
}
225+
226+
public void Tick()
227+
{
228+
ushort dlist_addr = (ushort)((DLISTH << 8) | DLISTL);
229+
Console.WriteLine("dlist: ${0:X4}", dlist_addr);
230+
}
231+
}
232+
}

Bus.cs

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
5+
namespace Emulators
6+
{
7+
public class Bus : IBus
8+
{
9+
private byte _size = 0;
10+
public byte Size
11+
{
12+
get => _size;
13+
set
14+
{
15+
if (value <= 64)
16+
{
17+
_size = value;
18+
ram = new byte[_size * 1024];
19+
ClearRam();
20+
}
21+
}
22+
}
23+
24+
private void ClearRam()
25+
{
26+
Array.Clear(ram, 0, _size * 1024);
27+
}
28+
29+
//ram
30+
byte[] ram;
31+
32+
public Bus(byte size)
33+
{
34+
Size = size;
35+
}
36+
37+
//read/write methods
38+
public void Write(ushort addr, byte data)
39+
{
40+
if (addr >= 0x0000 && addr < _size * 1024)
41+
ram[addr] = data;
42+
}
43+
44+
public byte Read(ushort addr)
45+
{
46+
if (addr >= 0x0000 && addr < _size * 1024)
47+
return ram[addr];
48+
else
49+
return 0x00;
50+
}
51+
}
52+
}

0 commit comments

Comments
 (0)