123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209 |
- #include "SVIPPI.hh"
- #include "MSXMotherBoard.hh"
- #include "Reactor.hh"
- #include "CassettePort.hh"
- #include "JoystickPort.hh"
- #include "GlobalSettings.hh"
- #include "serialize.hh"
- // Keyboard Matrix
- //
- // Column/ | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
- // Line | | | | | | | | |
- // --------+-----+-----+-----+-----+-----+-----+-----+-----|
- // 0 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
- // 1 | 8 | 9 | : | ' | , | = | . | / |
- // 2 | - | A | B | C | D | E | F | G |
- // 3 | H | I | J | K | L | M | N | O |
- // 4 | P | Q | R | S | T | U | V | W |
- // 5 | X | Y | Z | [ | \ | ] | BS | UP |
- // 6 |SHIFT|CTRL |LGRAP|RGRAP| ESC |STOP |ENTER|LEFT |
- // 7 | F1 | F2 | F3 | F4 | F5 | CLS | INS |DOWN |
- // 8 |SPACE| TAB | DEL |CAPS | SEL |PRINT| |RIGHT|
- // 9* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
- // 10* | 8 | 9 | + | - | * | / | . | , |
- // ---------------------------------------------------------
- // * Numerical keypad (SVI-328 only)
- // PPI Port A Input (98H)
- // Bit Name Description
- // 0 TA Paddle or tablet 1, /SENSE
- // 1 TB Paddle or tablet 1, EOC
- // 2 TC Paddle or tablet 2, /SENSE
- // 3 TD Paddle or tablet 2, EOC
- // 4 /TRIGGER1 Joystick 1, Trigger
- // 5 /TRIGGER2 Joystick 2, Trigger
- // 6 /READY Cassette, Ready
- // 7 CASR Cassette, Read data
- //
- // PPI Port B Input (99H)
- // Bit Name Description
- // 0 IN0 Keyboard, Column status of selected line
- // 1 IN1 Keyboard, Column status of selected line
- // 2 IN2 Keyboard, Column status of selected line
- // 3 IN3 Keyboard, Column status of selected line
- // 4 IN4 Keyboard, Column status of selected line
- // 5 IN5 Keyboard, Column status of selected line
- // 6 IN6 Keyboard, Column status of selected line
- // 7 IN7 Keyboard, Column status of selected line
- //
- // PPI Port C Output (96H)
- // Bit Name Description
- // 0 KB0 Keyboard, Line select 0
- // 1 KB1 Keyboard, Line select 1
- // 2 KB2 Keyboard, Line select 2
- // 3 KB3 Keyboard, Line select 3
- // 4 CASON Cassette, Motor relay control (0=on, 1=off)
- // 5 CASW Cassette, Write data
- // 6 CASAUD Cassette, Audio control (1=enable other channel in, 0=disable channel)
- // 7 SOUND Keyboard, Click sound bit (pulse)
- //
- // PPI Mode control, Output (97H)
- //
- // PPI Port C, Input (9AH)
- namespace openmsx {
- // MSXDevice
- SVIPPI::SVIPPI(const DeviceConfig& config)
- : MSXDevice(config)
- , cassettePort(getMotherBoard().getCassettePort())
- , i8255(*this, getCurrentTime(), config.getGlobalSettings().getInvalidPpiModeSetting())
- , click(config)
- , keyboard(
- config.getMotherBoard(),
- config.getMotherBoard().getScheduler(),
- config.getMotherBoard().getCommandController(),
- config.getMotherBoard().getReactor().getEventDistributor(),
- config.getMotherBoard().getMSXEventDistributor(),
- config.getMotherBoard().getStateChangeDistributor(),
- Keyboard::MATRIX_SVI, config)
- , prevBits(15)
- , selectedRow(0)
- {
- ports[0] = &getMotherBoard().getJoystickPort(0);
- ports[1] = &getMotherBoard().getJoystickPort(1);
- auto time = getCurrentTime();
- ports[0]->write(0, time); // TODO correct? Bit2 must be 0 otherwise
- ports[1]->write(0, time); // e.g. KeyJoystick doesn't work
- reset(time);
- }
- void SVIPPI::reset(EmuTime::param time)
- {
- i8255.reset(time);
- click.reset(time);
- }
- byte SVIPPI::readIO(word port, EmuTime::param time)
- {
- return i8255.read(port & 0x03, time);
- }
- byte SVIPPI::peekIO(word port, EmuTime::param time) const
- {
- return i8255.peek(port & 0x03, time);
- }
- void SVIPPI::writeIO(word port, byte value, EmuTime::param time)
- {
- i8255.write(port & 0x03, value, time);
- }
- // I8255Interface
- byte SVIPPI::readA(EmuTime::param time)
- {
- byte triggers = ((ports[0]->read(time) & 0x10) ? 0x10 : 0) |
- ((ports[1]->read(time) & 0x10) ? 0x20 : 0);
- //byte cassetteReady = cassettePort.Ready() ? 0 : 0x40;
- byte cassetteReady = 0; // ready
- byte cassetteInput = cassettePort.cassetteIn(time) ? 0x80 : 0x00;
- return triggers | cassetteReady | cassetteInput;
- }
- byte SVIPPI::peekA(EmuTime::param /*time*/) const
- {
- return 0; // TODO
- }
- void SVIPPI::writeA(byte /*value*/, EmuTime::param /*time*/)
- {
- }
- byte SVIPPI::readB(EmuTime::param time)
- {
- return peekB(time);
- }
- byte SVIPPI::peekB(EmuTime::param /*time*/) const
- {
- auto& keyb = const_cast<Keyboard&>(keyboard);
- return keyb.getKeys()[selectedRow];
- }
- void SVIPPI::writeB(byte /*value*/, EmuTime::param /*time*/)
- {
- }
- nibble SVIPPI::readC1(EmuTime::param time)
- {
- return peekC1(time);
- }
- nibble SVIPPI::peekC1(EmuTime::param /*time*/) const
- {
- return 15; // TODO check this
- }
- nibble SVIPPI::readC0(EmuTime::param time)
- {
- return peekC0(time);
- }
- nibble SVIPPI::peekC0(EmuTime::param /*time*/) const
- {
- return selectedRow;
- }
- void SVIPPI::writeC1(nibble value, EmuTime::param time)
- {
- if ((prevBits ^ value) & 1) {
- cassettePort.setMotor((value & 1) == 0, time); // 0=0n, 1=Off
- }
- if ((prevBits ^ value) & 2) {
- cassettePort.cassetteOut((value & 2) != 0, time);
- }
- //if ((prevBits ^ value) & 4) {
- // cassetteDevice.Mute(); // CASAUD, mute case speker (1=enable, 0=disable)
- //}
- if ((prevBits ^ value) & 8) {
- click.setClick((value & 8) != 0, time);
- }
- prevBits = value;
- }
- void SVIPPI::writeC0(nibble value, EmuTime::param /*time*/)
- {
- selectedRow = value;
- }
- template<typename Archive>
- void SVIPPI::serialize(Archive& ar, unsigned /*version*/)
- {
- ar.template serializeBase<MSXDevice>(*this);
- ar.serialize("i8255", i8255);
- // merge prevBits and selectedRow into one byte
- byte portC = (prevBits << 4) | (selectedRow << 0);
- ar.serialize("portC", portC);
- if (ar.isLoader()) {
- selectedRow = (portC >> 0) & 0xF;
- nibble bits = (portC >> 4) & 0xF;
- writeC1(bits, getCurrentTime());
- }
- ar.serialize("keyboard", keyboard);
- }
- INSTANTIATE_SERIALIZE_METHODS(SVIPPI);
- REGISTER_MSXDEVICE(SVIPPI, "SVI-328 PPI");
- } // namespace openmsx
|