-
Notifications
You must be signed in to change notification settings - Fork 1
/
Vdp.cs
95 lines (88 loc) · 2.72 KB
/
Vdp.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
namespace z80bench
{
/// <summary>
/// Emulates very little of the Sega VDP as fond in the Sega Master System and related consoles.
/// All we do here is implement the ability to read and write VRAM.
/// </summary>
internal class Vdp
{
private bool _latched;
private int _address;
private enum Mode
{
Read = 0,
Write = 1,
// RegisterWrite = 2,
// PaletteWrite = 3
}
private Mode _mode;
private byte _readBuffer;
/// <summary>
/// The contents of video memory
/// </summary>
public byte[] Vram { get; } = new byte[0x4000];
public byte ReadData()
{
// Every time the data port is read (regardless
// of the code register) the contents of a buffer are returned. The VDP will
// then read a byte from VRAM at the current address, and increment the address
// register. In this way data for the next data port read is ready with no
// delay while the VDP reads VRAM.
var value = _readBuffer;
BufferRead();
_latched = false;
return value;
}
public void WriteData(byte value)
{
if (_mode == Mode.Write)
{
Vram[_address++] = value;
_address &= 0x3fff;
}
// An additional quirk is that writing to the
// data port will also load the buffer with the value written.
_readBuffer = value;
_latched = false;
}
public void WriteControl(byte value)
{
if (!_latched)
{
// First byte
// Update address immediately
_address &= 0b111111_00000000;
_address |= value;
// Set latch
_latched = true;
}
else
{
// Second byte
// Apply bits to address
_address &= 0b000000_11111111;
_address |= (value & 0b111111) << 8;
// Clear latch
_latched = false;
// Set mode
_mode = (Mode) (value >> 6);
// Pre-buffer on read
if (_mode == Mode.Read)
{
BufferRead();
}
}
}
private void BufferRead()
{
_readBuffer = Vram[_address++];
_address &= 0x3fff;
}
public byte ReadControl()
{
_latched = false;
// We always return the same value...
return 0b10000000;
}
}
}