Skip to content

Commit

Permalink
#2 Raster interrupt work
Browse files Browse the repository at this point in the history
  • Loading branch information
hagronnestad committed Oct 13, 2019
1 parent 5867389 commit 73c6e53
Showing 1 changed file with 70 additions and 7 deletions.
77 changes: 70 additions & 7 deletions ComputerSystems/Commodore64/VicIi.cs
Original file line number Diff line number Diff line change
@@ -1,19 +1,70 @@
using System.Drawing;
using System;
using System.Drawing;
using Extensions.Byte;
using Extensions.Enums;

namespace Commodore64 {
public class VicIi {

public event EventHandler OnGenerateRasterLineInterrupt;

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

private const byte REGISTER_SCREEN_CONTROL_0x11 = 0x11;
private const byte REGISTER_CURRENT_RASTER_LINE_0x12 = 0x12;
private const byte REGISTER_RASTER_LINE_IRQ_0x12 = 0x12;

private const byte REGISTER_INTERRUPT_STATUS_0x19 = 0x19;
private const byte REGISTER_INTERRUPT_CONTROL_0x1A = 0x1A;

private int _rasterLineToGenerateInterruptAt = 0;

public byte this[int index] {
get {
return _registers[index];
switch (index) {


case REGISTER_SCREEN_CONTROL_0x11:
// Bit #7 og 0x11 is set if current raster line > 255
_registers[index].SetBit(BitFlag.BIT_7, CurrentLine > 255);

return _registers[index];

// Current raster line (bits #0-#7).
// There's an additional bit used (bit #7) in 0x11 for values > 255
case REGISTER_CURRENT_RASTER_LINE_0x12:
return CurrentLine > 255 ? (byte)(CurrentLine - 255) : (byte)CurrentLine;

default:
return _registers[index];
}
}
set {
_registers[index] = value;
switch (index) {

case REGISTER_SCREEN_CONTROL_0x11:
_registers[index] = value;
UpdateRasterLineToGenerateInterruptAt();
break;

// Raster line to generate interrupt at (bits #0-#7).
// There's an additional bit used (bit #7) in 0x11 for values > 255
case REGISTER_RASTER_LINE_IRQ_0x12:
_registers[index] = value;
UpdateRasterLineToGenerateInterruptAt();
break;

default:
_registers[index] = value;
break;
}
}
}

private void UpdateRasterLineToGenerateInterruptAt() {
_rasterLineToGenerateInterruptAt = _registers[REGISTER_RASTER_LINE_IRQ_0x12];
if (_registers[REGISTER_SCREEN_CONTROL_0x11].IsBitSet(BitFlag.BIT_7)) _rasterLineToGenerateInterruptAt += 255;
}

public enum TvSystem {
NTSC,
Expand All @@ -32,14 +83,25 @@ public enum TvSystem {
public const int FULL_HEIGHT_PAL = 312;
public const int USABLE_HEIGHT = 200;
public const int USABLE_HEIGHT_BORDER = 284;

public int CurrentLine = 0;
public int CurrentLineCycle = 0;

public int TotalCycles = 0;

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

public bool ScreenOn => (this[0x11] & 0b00010000) == 1;
// Screen control register
public bool ScreenControlRegisterScreenHeight => this[REGISTER_SCREEN_CONTROL_0x11].IsBitSet(BitFlag.BIT_3); // False = 24 rows, True = 25 rows
public bool ScreenControlRegisterScreenOffOn => this[REGISTER_SCREEN_CONTROL_0x11].IsBitSet(BitFlag.BIT_4);
public bool ScreenControlRegisterTextModeBitmapMode => this[REGISTER_SCREEN_CONTROL_0x11].IsBitSet(BitFlag.BIT_5); // False = Text mode, True = Bitmap mode
public bool ScreenControlRegisterExtendedBackgroundModeOn => this[REGISTER_SCREEN_CONTROL_0x11].IsBitSet(BitFlag.BIT_6); // True = Extended background mode on

// Interrupt control register
public bool InterruptControlRegisterRasterInterruptEnabled => this[REGISTER_INTERRUPT_CONTROL_0x1A].IsBitSet(BitFlag.BIT_0);
public bool InterruptControlRegisterSpriteBackgroundCollisionInterruptEnabled => this[REGISTER_INTERRUPT_CONTROL_0x1A].IsBitSet(BitFlag.BIT_1);
public bool InterruptControlRegisterSpriteSpriteCollisionInterruptEnabled => this[REGISTER_INTERRUPT_CONTROL_0x1A].IsBitSet(BitFlag.BIT_2);
public bool InterruptControlRegisterLightPenInterruptEnabled => this[REGISTER_INTERRUPT_CONTROL_0x1A].IsBitSet(BitFlag.BIT_3);

//public bool IsInBorder =>

Expand All @@ -57,6 +119,10 @@ public void Cycle() {

CurrentLine++;

if (InterruptControlRegisterRasterInterruptEnabled && (CurrentLine == _rasterLineToGenerateInterruptAt)) {
OnGenerateRasterLineInterrupt?.Invoke(this, null);
}

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

Expand All @@ -66,9 +132,6 @@ public void Cycle() {

UpdateScreenBufferPixels();

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

TotalCycles++;
}

Expand Down

0 comments on commit 73c6e53

Please sign in to comment.