Skip to content

Commit

Permalink
#2 VIC-II, added registers, moved some logic, mapped VIC-II in bus
Browse files Browse the repository at this point in the history
  • Loading branch information
hagronnestad committed Oct 13, 2019
1 parent e8a8b8f commit 5867389
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 67 deletions.
11 changes: 6 additions & 5 deletions ComputerSystems/Commodore64/C64.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public class C64 {


public Cia Cia { get; private set; }
public VicIi Vic { get; private set; }
public C64Bus Memory { get; private set; }
public Cpu Cpu { get; private set; }

Expand All @@ -34,7 +35,8 @@ public void Initialize() {
RemoveEventHandlers();

Cia = new Cia();
Memory = new C64Bus(Cia);
Vic = new VicIi();
Memory = new C64Bus(Cia, Vic);
Cpu = new Cpu(Memory);

AddEventHandlers();
Expand All @@ -61,13 +63,12 @@ public void PowerOn() {
// Clock CIA 1
Cia.Clock();

// Cycle VIC-II
Vic.Cycle();

// Cycle the CPU
Cpu.Cycle();

// I have to work out how to properly time this
Memory[C64MemoryLocations.CURRENT_RASTER_LINE] =
Memory[C64MemoryLocations.CURRENT_RASTER_LINE] == 0 ? (byte)1 : (byte)0;

swCpuClock.Restart();
}
}
Expand Down
124 changes: 74 additions & 50 deletions ComputerSystems/Commodore64/C64Bus.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,17 @@ public class C64Bus : MemoryBase<byte> {
private MemoryBase<byte> _romKernal;

private Cia _cia;
private readonly VicIi _vic;

public C64Bus(Cia cia) : base(0x10000) {
public C64Bus(Cia cia, VicIi vic) : base(0x10000) {
_memory.FillWithRandomData();

_romBasic = new MemoryBase<byte>(File.ReadAllBytes("basic.rom")) { IsReadOnly = true };
_romCharacter = new MemoryBase<byte>(File.ReadAllBytes("char.rom")) { IsReadOnly = true };
_romKernal = new MemoryBase<byte>(File.ReadAllBytes("kernal.rom")) { IsReadOnly = true };

_cia = cia;
_vic = vic;

// Intialize processor addressing mode with default values
// http://sta.c64.org/cbm64mem.html
Expand Down Expand Up @@ -182,7 +184,49 @@ public override byte Read(int address) {

// I/O
if (processorPortMemoryConfiguration == 0b101 || processorPortMemoryConfiguration == 0b111 || processorPortMemoryConfiguration == 0b110) {
//Debug.WriteLine($"Trying to read unimplemented I/O at address: {address:X4}");

// VIC-II (0xD000 - 0xD3FF, VIC-II register images repeated every $40, 64 bytes)
if (address >= 0xD000 && address <= 0xD3FF) {

// The VIC-II class has its own indexer which makes it easy to map
// addresses into the VIC-II. The `% 0x40` makes sure that the
// registers available in the VIC-II are mirrored all the way up to
// 0xD3FF.
return _vic[(address - 0xD000) % 0x40];

}


// CIA 1
if (address >= 0xDC00 && address <= 0xDCFF) {

switch (address) {
case 0xDC09:
return _cia.TimeOfDaySecondsBcd;
case 0xDC0A:
return _cia.TimeOfDayMinutesBcd;
case 0xDC0B:
return _cia.TimeOfDayHoursBcd;

default:
// The CIA class has its own indexer which makes it easy to map
// addresses into the CIA. The `% 0x10` makes sure that the
// 16 registers available in the CIA are mirrored all the way up to
// 0xDCFF.
return _cia[(address - 0xDC00) % 0x10];
}

}



// CIA 2
if (address >= 0xDD00 && address <= 0xDDFF) {
return 0;
}


// throw new Exception($"Trying to read unimplemented I/O at address: {address:X4}");
}


Expand Down Expand Up @@ -237,27 +281,6 @@ public override byte Read(int address) {

//// Everything else is I/O

// CIA 1
if (address >= 0xDC00 && address <= 0xDCFF) {

switch (address) {
case 0xDC09:
return _cia.TimeOfDaySecondsBcd;
case 0xDC0A:
return _cia.TimeOfDayMinutesBcd;
case 0xDC0B:
return _cia.TimeOfDayHoursBcd;

default:
// The CIA class has its own indexer which makes it easy to map
// addresses into the CIA. The `% 0x10` makes sure that the
// 16 registers available in the CIA are mirrored all the way up to
// 0xDCFF.
return _cia[(address - 0xDC00) % 0x10];
}

}

//Debug.WriteLine($"Trying to read unimplemented I/O at address: {address:X4}");
}

Expand Down Expand Up @@ -317,35 +340,36 @@ public override byte Read(int address) {
}

public override void Write(int address, byte value) {
//if (address == 0x0801) Debug.WriteLine($"Value: 0x{value:X2} written to Address: 0x{address:X4}");
//if (address == 0x0802) Debug.WriteLine($"Value: 0x{value:X2} written to Address: 0x{address:X4}");
//if (address == 0x0803) Debug.WriteLine($"Value: 0x{value:X2} written to Address: 0x{address:X4}");
//if (address == 0x0804) Debug.WriteLine($"Value: 0x{value:X2} written to Address: 0x{address:X4}");
//if (address == 0x0805) Debug.WriteLine($"Value: 0x{value:X2} written to Address: 0x{address:X4}");
//if (address == 0x0806) Debug.WriteLine($"Value: 0x{value:X2} written to Address: 0x{address:X4}");
//if (address == 0x0807) Debug.WriteLine($"Value: 0x{value:X2} written to Address: 0x{address:X4}");
//if (address == 0x0808) Debug.WriteLine($"Value: 0x{value:X2} written to Address: 0x{address:X4}");
//if (address == 0x0809) Debug.WriteLine($"Value: 0x{value:X2} written to Address: 0x{address:X4}");
//if (address == 0x080A) Debug.WriteLine($"Value: 0x{value:X2} written to Address: 0x{address:X4}");
//if (address == 0x080B) Debug.WriteLine($"Value: 0x{value:X2} written to Address: 0x{address:X4}");
//if (address == 0x080C) Debug.WriteLine($"Value: 0x{value:X2} written to Address: 0x{address:X4}");
//if (address == 0x080D) Debug.WriteLine($"Value: 0x{value:X2} written to Address: 0x{address:X4}");
//if (address == 0x080E) Debug.WriteLine($"Value: 0x{value:X2} written to Address: 0x{address:X4}");
//if (address == 0x080F) Debug.WriteLine($"Value: 0x{value:X2} written to Address: 0x{address:X4}");

//if (address == 0x0001) Debug.WriteLine($"Value: 0x{value:X2} written to Address: 0x{address:X4}");


// CIA 1
if (address >= 0xDC00 && address <= 0xDCFF) {
// The CIA class has its own indexer which makes it easy to map
// addresses into the CIA. The `% 0x10` makes sure that the
// 16 registers available in the CIA are mirrored all the way up to
// 0xDCFF.
_cia[(address - 0xDC00) % 0x10] = value;
return;
var processorPortMemoryConfiguration = _memory[1] & 0b00000111;

// I/O
if (processorPortMemoryConfiguration == 0b101 || processorPortMemoryConfiguration == 0b111 || processorPortMemoryConfiguration == 0b110) {

// VIC-II (0xD000 - 0xD3FF, VIC-II register images repeated every $40, 64 bytes)
if (address >= 0xD000 && address <= 0xD3FF) {

// The VIC-II class has its own indexer which makes it easy to map
// addresses into the VIC-II. The `% 0x40` makes sure that the
// registers available in the VIC-II are mirrored all the way up to
// 0xD3FF.
_vic[(address - 0xD000) % 0x40] = value;

}

// CIA 1
if (address >= 0xDC00 && address <= 0xDCFF) {
// The CIA class has its own indexer which makes it easy to map
// addresses into the CIA. The `% 0x10` makes sure that the
// 16 registers available in the CIA are mirrored all the way up to
// 0xDCFF.
_cia[(address - 0xDC00) % 0x10] = value;
return;
}

}


base.Write(address, value);
}
}
Expand Down
32 changes: 20 additions & 12 deletions ComputerSystems/Commodore64/VicIi.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,20 @@
using Hardware.Memory;
using System.Drawing;
using System.Drawing;

namespace Commodore64 {
public class VicIi {

private byte[] _registers = new byte[47];

public byte this[int index] {
get {
return _registers[index];
}
set {
_registers[index] = value;
}
}


public enum TvSystem {
NTSC,
PAL
Expand All @@ -28,14 +39,12 @@ public enum TvSystem {

public Color[] ScreenBufferPixels = new Color[USABLE_WIDTH_BORDER * USABLE_HEIGHT_BORDER];

public bool ScreenOn => (Read(0xD011) & 0b00010000) == 1;

public bool ScreenOn => (this[0x11] & 0b00010000) == 1;

private readonly IMemory<byte> _bus;
//public bool IsInBorder =>

public VicIi() {

public VicIi(IMemory<byte> bus) {
_bus = bus;
}

public void Cycle() {
Expand All @@ -48,7 +57,7 @@ public void Cycle() {

CurrentLine++;

if ((CurrentTvSystem == TvSystem.PAL && CurrentLine == FULL_HEIGHT_PAL) ||
if ((CurrentTvSystem == TvSystem.PAL && CurrentLine == FULL_HEIGHT_PAL) ||
(CurrentTvSystem == TvSystem.NTSC && CurrentLine == FULL_HEIGHT_NTSC)) {

CurrentLine = 0;
Expand All @@ -57,15 +66,14 @@ public void Cycle() {

UpdateScreenBufferPixels();

// TODO: Implement this properly (Raster Counter)
this[0x12] = this[0x12] == 0 ? (byte)1 : (byte)0;

TotalCycles++;
}

private void UpdateScreenBufferPixels() {

}

public byte Read(int address) {
return _bus[address];
}
}
}

0 comments on commit 5867389

Please sign in to comment.