e8555c89 Andy McCall 1 month ago
1
#include " MSXPrinterPort.hh"
2
3
#include " DummyPrinterPortDevice.hh"
4
#include " serialize.hh"
5
6
#include " checked_cast.hh"
7
#include " narrow.hh"
8
#include " outer.hh"
9
#include " unreachable.hh"
10
11
#include < cstdint>
12
#include < memory>
13
14
namespace openmsx {
15
16
MSXPrinterPort:: MSXPrinterPort ( const DeviceConfig& config )
17
: MSXDevice ( config )
18
, Connector ( MSXDevice:: getPluggingController ( ) , " printerport" ,
19
std:: make_unique < DummyPrinterPortDevice> ( ) )
20
, debuggable ( getMotherBoard ( ) , MSXDevice:: getName ( ) )
21
, writePortMask ( config. getChildDataAsBool ( " bidirectional" , false ) ? 0x03 : 0x01 )
22
, readPortMask ( config. getChildDataAsBool ( " status_readable_on_all_ports" , false ) ? 0 : writePortMask )
23
, unusedBits ( uint8_t ( config. getChildDataAsInt ( " unused_bits" , 0xFF ) ) )
24
{
25
reset ( getCurrentTime ( ) ) ;
26
}
27
28
void MSXPrinterPort:: reset ( EmuTime time )
29
{
30
writeData ( 0 , time) ;
31
setStrobe ( true , time) ;
32
}
33
34
uint8_t MSXPrinterPort:: readIO ( uint16_t port , EmuTime time )
35
{
36
return peekIO ( port, time ) ;
37
}
38
39
uint8_t MSXPrinterPort:: peekIO ( uint16_t port , EmuTime time ) const
40
{
41
bool showStatus = ( port & readPortMask) == 0 ;
42
if ( ! showStatus) return 0xFF ;
43
44
45
return getPluggedPrintDev ( ) . getStatus ( time )
46
? ( unusedBits | 0b10 ) : ( unusedBits & ~ 0b10 ) ;
47
}
48
49
void MSXPrinterPort:: writeIO ( uint16_t port , uint8_t value , EmuTime time )
50
{
51
switch ( port & writePortMask) {
52
case 0 :
53
setStrobe ( value & 1 , time ) ;
54
break ;
55
case 1 :
56
writeData ( value, time ) ;
57
break ;
58
case 2 :
59
break ;
60
case 3 :
61
break ;
62
default :
63
UNREACHABLE;
64
}
65
}
66
67
void MSXPrinterPort:: setStrobe ( bool newStrobe , EmuTime time )
68
{
69
if ( newStrobe != strobe) {
70
strobe = newStrobe;
71
getPluggedPrintDev ( ) . setStrobe ( strobe, time ) ;
72
}
73
}
74
void MSXPrinterPort:: writeData ( uint8_t newData , EmuTime time )
75
{
76
if ( newData != data) {
77
data = newData;
78
getPluggedPrintDev ( ) . writeData ( data, time ) ;
79
}
80
}
81
82
zstring_view MSXPrinterPort:: getDescription ( ) const
83
{
84
return " MSX Printer port" ;
85
}
86
87
zstring_view MSXPrinterPort:: getClass ( ) const
88
{
89
return " Printer Port" ;
90
}
91
92
void MSXPrinterPort:: plug ( Pluggable& dev , EmuTime time )
93
{
94
Connector:: plug ( dev, time ) ;
95
getPluggedPrintDev ( ) . writeData ( data, time ) ;
96
getPluggedPrintDev ( ) . setStrobe ( strobe, time ) ;
97
}
98
99
PrinterPortDevice& MSXPrinterPort:: getPluggedPrintDev ( ) const
100
{
101
return * checked_cast < PrinterPortDevice* > ( & getPlugged ( ) ) ;
102
}
103
104
105
MSXPrinterPort:: Debuggable:: Debuggable ( MSXMotherBoard& motherBoard_ , const std:: string& name_ )
106
: SimpleDebuggable ( motherBoard_, name_, " Printer Port" , 2 )
107
{
108
}
109
110
uint8_t MSXPrinterPort:: Debuggable:: read ( unsigned address )
111
{
112
const auto & pPort = OUTER ( MSXPrinterPort, debuggable ) ;
113
return ( address == 0 ) ? pPort. strobe : pPort. data ;
114
}
115
116
void MSXPrinterPort:: Debuggable:: write ( unsigned address , uint8_t value )
117
{
118
auto & pPort = OUTER ( MSXPrinterPort, debuggable ) ;
119
pPort. writeIO ( narrow < uint16_t > ( address ) , value, pPort. getCurrentTime ( ) ) ;
120
}
121
122
123
template < typename Archive>
124
void MSXPrinterPort:: serialize ( Archive& ar , unsigned )
125
{
126
ar. template serializeBase < MSXDevice> ( * this ) ;
127
ar. template serializeBase < Connector> ( * this ) ;
128
ar. serialize ( " strobe" , strobe,
129
" data" , data ) ;
130
131
}
132
INSTANTIATE_SERIALIZE_METHODS ( MSXPrinterPort ) ;
133
REGISTER_MSXDEVICE ( MSXPrinterPort, " PrinterPort" ) ;
134
135
}