openMSX
SVIPSG.cc
Go to the documentation of this file.
1#include "SVIPSG.hh"
2#include "LedStatus.hh"
3#include "MSXCPUInterface.hh"
4#include "MSXMotherBoard.hh"
5#include "JoystickPort.hh"
6#include "serialize.hh"
7#include "stl.hh"
8
9// Slot 0 Slot 1 Slot 2 Slot 3
10// FFFF +---------+---------+---------+---------+
11// | Bank 2 | Bank 12 | Bank 22 | Bank 32 | Page 3
12// | RAM |ROM Cart | RAM | RAM |
13// 8000 |00000000 |01010000 |10100000 |11110000 | Page 2
14// +---------+---------+---------+---------+
15// 7FFF | Bank 1 | Bank 11 | Bank 21 | Bank 31 | Page 1
16// |ROM BASIC|ROM Cart | RAM | RAM |
17// |00000000 |00000101 |00001010 |00001111 | Page 0
18// 0000 +---------+---------+---------+---------+
19//
20// PSG Port A Input
21// Bit Name Description
22// 0 FWD1 Joystick 1, Forward
23// 1 BACK1 Joystick 1, Back
24// 2 LEFT1 Joystick 1, Left
25// 3 RIGHT1 Joystick 1, Right
26// 4 FWD2 Joystick 2, Forward
27// 5 BACK2 Joystick 2, Back
28// 6 LEFT2 Joystick 2, Left
29// 7 RIGHT2 Joystick 2, Right
30//
31// PSG Port B Output
32// Bit Name Description
33// 0 /CART Memory bank 11, ROM 0000-7FFF (cartridge /CCS1, /CCS2)
34// 1 /BK21 Memory bank 21, RAM 0000-7FFF
35// 2 /BK22 Memory bank 22, RAM 8000-FFFF
36// 3 /BK31 Memory bank 31, RAM 0000-7FFF
37// 4 /BK32 Memory bank 32, RAM 8000-7FFF
38// 5 CAPS Caps-Lock LED
39// 6 /ROMEN0 Memory bank 12, ROM 8000-BFFF* (cartridge /CCS3)
40// 7 /ROMEN1 Memory bank 12, ROM C000-FFFF* (cartridge /CCS4)
41//
42// * The /CART signal must be active for any effect,
43// then all banks of RAM are disabled.
44
45namespace openmsx {
46
47// MSXDevice
48
50 : MSXDevice(config)
51 , ports(generate_array<2>([&](auto i) { return &getMotherBoard().getJoystickPort(unsigned(i)); }))
52 , ay8910("PSG", *this, config, getCurrentTime())
53{
54 reset(getCurrentTime());
55}
56
58{
59 powerDown(EmuTime::dummy());
60}
61
62void SVIPSG::reset(EmuTime::param time)
63{
64 registerLatch = 0;
65 ay8910.reset(time);
66}
67
68void SVIPSG::powerDown(EmuTime::param /*time*/)
69{
71}
72
73byte SVIPSG::readIO(word /*port*/, EmuTime::param time)
74{
75 return ay8910.readRegister(registerLatch, time);
76}
77
78byte SVIPSG::peekIO(word /*port*/, EmuTime::param time) const
79{
80 return ay8910.peekRegister(registerLatch, time);
81}
82
83void SVIPSG::writeIO(word port, byte value, EmuTime::param time)
84{
85 switch (port & 0x07) {
86 case 0:
87 registerLatch = value & 0x0F;
88 break;
89 case 4:
90 ay8910.writeRegister(registerLatch, value, time);
91 break;
92 }
93}
94
95// AY8910Periphery
96
97byte SVIPSG::readA(EmuTime::param time)
98{
99 return byte(((ports[1]->read(time) & 0x0F) << 4) |
100 ((ports[0]->read(time) & 0x0F) << 0));
101}
102
103void SVIPSG::writeB(byte value, EmuTime::param /*time*/)
104{
105 getMotherBoard().getLedStatus().setLed(LedStatus::CAPS, (value & 0x20) != 0);
106
107 // Default to bank 1 and 2
108 byte psReg = 0;
109 switch (~value & 0x14) {
110 case 0x04: // bk22
111 psReg = 0xa0;
112 break;
113 case 0x10: // bk32
114 psReg = 0xf0;
115 break;
116 }
117 switch (~value & 0x0B) {
118 case 1: // bk12 (cart)?
119 if ((~value & 0x80) || (~value & 0x40)) {
120 psReg = 0x50;
121 }
122 // bk11 (cart)
123 psReg |= 0x05;
124 break;
125 case 2: // bk21
126 psReg |= 0x0a;
127 break;
128 case 8: // bk31
129 psReg |= 0x0f;
130 break;
131 }
133
134 prev = value;
135}
136
137template<typename Archive>
138void SVIPSG::serialize(Archive& ar, unsigned /*version*/)
139{
140 ar.template serializeBase<MSXDevice>(*this);
141 ar.serialize("ay8910", ay8910,
142 "registerLatch", registerLatch);
143 byte portB = prev;
144 ar.serialize("portB", portB);
145 if constexpr (Archive::IS_LOADER) {
146 writeB(portB, getCurrentTime());
147 }
148}
151
152} // namespace openmsx
#define REGISTER_MSXDEVICE(CLASS, NAME)
Definition MSXDevice.hh:356
uint8_t readRegister(unsigned reg, EmuTime::param time)
Definition AY8910.cc:523
void reset(EmuTime::param time)
Definition AY8910.cc:510
void writeRegister(unsigned reg, uint8_t value, EmuTime::param time)
Definition AY8910.cc:567
uint8_t peekRegister(unsigned reg, EmuTime::param time) const
Definition AY8910.cc:548
void setLed(Led led, bool status)
Definition LedStatus.cc:44
void setPrimarySlots(byte value)
An MSXDevice is an emulated hardware component connected to the bus of the emulated MSX.
Definition MSXDevice.hh:36
MSXMotherBoard & getMotherBoard() const
Get the mother board this device belongs to.
Definition MSXDevice.cc:70
EmuTime::param getCurrentTime() const
Definition MSXDevice.cc:125
MSXCPUInterface & getCPUInterface()
JoystickPortIf & getJoystickPort(unsigned port)
void powerDown(EmuTime::param time) override
This method is called when MSX is powered down.
Definition SVIPSG.cc:68
SVIPSG(const DeviceConfig &config)
Definition SVIPSG.cc:49
~SVIPSG() override
Definition SVIPSG.cc:57
byte peekIO(word port, EmuTime::param time) const override
Read a byte from a given IO port.
Definition SVIPSG.cc:78
void serialize(Archive &ar, unsigned version)
Definition SVIPSG.cc:138
byte readIO(word port, EmuTime::param time) override
Read a byte from an IO port at a certain time from this device.
Definition SVIPSG.cc:73
void writeIO(word port, byte value, EmuTime::param time) override
Write a byte to a given IO port at a certain time to this device.
Definition SVIPSG.cc:83
void reset(EmuTime::param time) override
This method is called on reset.
Definition SVIPSG.cc:62
This file implemented 3 utility functions:
Definition Autofire.cc:11
uint8_t byte
8 bit unsigned integer
Definition openmsx.hh:26
uint16_t word
16 bit unsigned integer
Definition openmsx.hh:29
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)