Documentation ¶
Overview ¶
Package vcs represents the areas of memory that are internal to the VCS hardware. Compare with the cartridge package which represents memory (ROM and sometimes RAM) peripheral to the VCS.
Index ¶
- Constants
- type RAM
- func (ram *RAM) Peek(address uint16) (uint8, error)
- func (ram *RAM) Poke(address uint16, value uint8) error
- func (ram *RAM) Read(address uint16) (uint8, uint8, error)
- func (ram *RAM) Reset()
- func (ram *RAM) Snapshot() *RAM
- func (ram *RAM) String() string
- func (ram *RAM) Write(address uint16, data uint8) error
- type RIOTMemory
- func (mem *RIOTMemory) ChipHasChanged() (chipbus.ChangedRegister, bool)
- func (mem *RIOTMemory) ChipRefer(reg chipbus.Register) uint8
- func (mem *RIOTMemory) ChipWrite(reg chipbus.Register, data uint8)
- func (mem *RIOTMemory) LastReadAddress() (bool, uint16)
- func (mem *RIOTMemory) Peek(address uint16) (uint8, error)
- func (mem *RIOTMemory) Poke(address uint16, value uint8) error
- func (mem *RIOTMemory) Read(address uint16) (uint8, uint8, error)
- func (mem *RIOTMemory) Reset()
- func (mem *RIOTMemory) Snapshot() *RIOTMemory
- func (mem *RIOTMemory) Write(address uint16, data uint8) error
- type TIAMemory
- func (mem *TIAMemory) ChipHasChanged() (chipbus.ChangedRegister, bool)
- func (mem *TIAMemory) ChipRefer(reg chipbus.Register) uint8
- func (mem *TIAMemory) ChipWrite(reg chipbus.Register, data uint8)
- func (mem *TIAMemory) LastReadAddress() (bool, uint16)
- func (mem *TIAMemory) Peek(address uint16) (uint8, error)
- func (mem *TIAMemory) Poke(address uint16, value uint8) error
- func (mem *TIAMemory) Read(address uint16) (uint8, uint8, error)
- func (mem *TIAMemory) Reset()
- func (mem *TIAMemory) Snapshot() *TIAMemory
- func (mem *TIAMemory) Write(address uint16, data uint8) error
Constants ¶
const TIADrivenPins = uint8(0b11000000)
All TIA addresses when read by the CPU should be masked by the TIADrivenPins value. This is because only the pin 6 and 7 are connected to the data bus.
Note that although the "Stella's Programmer's Guide" suggests that the CXBLPF and CXPPMM only have pin 7 connected, in actual fact they are wired just like the other collision registers.
Similarly for the INPTx reguisters. As reported in this bug report: https://github.com/JetSetIlly/Gopher2600/issues/16#issue-1083935291
the last two address location in TIA memory are "undefined" according to the "Stella Programmer's Guide" but they are readable anyway and are wired the same as the collision and INPTx registers.
Explanation of how the TIADrivenPins mask affects the read value ----------------------------------------------------------------
If the CPU wants to read the contents of the CXM1P register, it can use the address 0x0d to do so.
LDA 0x01
If there are no collisions (between missile 1 and either player, in this case) than the value of the most significant bits are zero. The lower six bits are not part of the CXM1P register and are left undefined by the TIA when the data is put on the bus. The lower bits of the LDA operation are in fact "left over" from the address. In our example, the lowest six bits are
0bxx000001
meaning the the returned data is in fact 0x01 and not 0x00, as you might expect. Things get interesting when we use mirrored addresses. If instead of 0x01 we used the mirror address 0x11, the lowest six bits are:
0bxx01001
meaning that the returned value is 0x11 and not (again, as you might expect) 0x00 or even 0x01.
So what happens if there is sprite collision information in the register? Meaning that the top bits are not necessarily zero. Let's say there is a collusion between missile 1 and player 0, the data before masking will be
0b01000000
If we used address 0x11 to load this value, we would in fact, get this pattern (0x51 in hex):
0b01010001
Now, if all ROMs read and interpreted chip registers only as they're supposed to (defails in the 2600 programmer's guide) then none of this would matter but some ROMs do make use of the extra bits, and so we must account for it in emulation.
It's worth noting that the above is implicitly talking about zero-page addressing; but masking also occurs with regular two-byte addressing. The key to understanding is that the masking is applied to the most recent byte of the address to be put on the address bus*. In all cases, this is the most-significant byte. So, if the requested address is 0x171, the bit pattern for the address is:
0x0000000101110001
the most significant byte in this pattern is 0x00000001 and so the data retreived is AND-ed with that. The mapped address for 0x171 incidentally, is 0x01, which is the CXM1P register also used in the examples above.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type RAM ¶
type RAM struct { RAM []uint8 // contains filtered or unexported fields }
RAM represents the 128bytes of RAM in the PIA 6532 chip, found in the Atari VCS.
func NewRAM ¶
func NewRAM(env *environment.Environment) *RAM
NewRAM is the preferred method of initialisation for the RAM memory area.
type RIOTMemory ¶ added in v0.16.0
type RIOTMemory struct {
// contains filtered or unexported fields
}
func NewRIOTMemory ¶ added in v0.16.0
func NewRIOTMemory(env *environment.Environment) *RIOTMemory
NewRIOTMemory is the preferred method of initialisation for the RIOT memory mem.
func (*RIOTMemory) ChipHasChanged ¶ added in v0.16.0
func (mem *RIOTMemory) ChipHasChanged() (chipbus.ChangedRegister, bool)
ChipRead is an implementation of memory.ChipBus.
func (*RIOTMemory) ChipRefer ¶ added in v0.16.0
func (mem *RIOTMemory) ChipRefer(reg chipbus.Register) uint8
ChipRefer is an implementation of memory.ChipBus.
func (*RIOTMemory) ChipWrite ¶ added in v0.16.0
func (mem *RIOTMemory) ChipWrite(reg chipbus.Register, data uint8)
ChipWrite is an implementation of memory.ChipBus
func (*RIOTMemory) LastReadAddress ¶ added in v0.16.0
func (mem *RIOTMemory) LastReadAddress() (bool, uint16)
LastReadAddress is an implementation of memory.ChipBus.
func (*RIOTMemory) Peek ¶ added in v0.16.0
func (mem *RIOTMemory) Peek(address uint16) (uint8, error)
Peek is an implementation of memory.DebugBus. Address must be normalised.
func (*RIOTMemory) Poke ¶ added in v0.16.0
func (mem *RIOTMemory) Poke(address uint16, value uint8) error
Poke is an implementation of memory.DebugBus. Address must be normalised.
func (*RIOTMemory) Read ¶ added in v0.16.0
func (mem *RIOTMemory) Read(address uint16) (uint8, uint8, error)
Read is an implementation of memory.CPUBus. Address must be normalised.
func (*RIOTMemory) Reset ¶ added in v0.16.0
func (mem *RIOTMemory) Reset()
Reset contents of RIOTRegisters.
func (*RIOTMemory) Snapshot ¶ added in v0.16.0
func (mem *RIOTMemory) Snapshot() *RIOTMemory
Snapshot creates a copy of RIOTRegisters in its current state.
type TIAMemory ¶ added in v0.16.0
type TIAMemory struct {
// contains filtered or unexported fields
}
TIAMemory defines the information for and operations allowed for those memory mems accessed by the VCS chips as well as the CPU.
func NewTIAMemory ¶ added in v0.16.0
func NewTIAMemory(env *environment.Environment) *TIAMemory
NewTIAMemory is the preferred method of initialisation for the TIA memory chip.
func (*TIAMemory) ChipHasChanged ¶ added in v0.16.0
func (mem *TIAMemory) ChipHasChanged() (chipbus.ChangedRegister, bool)
ChipRead is an implementation of memory.ChipBus.
func (*TIAMemory) LastReadAddress ¶ added in v0.16.0
LatsReadAddress is an implementation of memory.ChipBus.
func (*TIAMemory) Peek ¶ added in v0.16.0
Peek is an implementation of memory.DebugBus. Address must be normalised.
func (*TIAMemory) Poke ¶ added in v0.16.0
Poke is an implementation of memory.DebugBus. Address must be normalised.
func (*TIAMemory) Read ¶ added in v0.16.0
Read is an implementation of memory.CPUBus. Address must be mapped.
Returned data should be masked and randomised as appropriate according to the TIADrivenPins mask.
func (*TIAMemory) Reset ¶ added in v0.16.0
func (mem *TIAMemory) Reset()
Reset contents of TIARegisters.