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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
|
// license:BSD-3-Clause
// copyright-holders:Paul Daniels
/**********************************************************************
machine.c
Functions to emulate general aspects of the machine (RAM, ROM, interrups,
I/O ports)
**********************************************************************/
#include "emu.h"
#include "includes/p2000t.h"
#define P2000M_101F_CASDAT 0x01
#define P2000M_101F_CASCMD 0x02
#define P2000M_101F_CASREW 0x04
#define P2000M_101F_CASFOR 0x08
#define P2000M_101F_KEYINT 0x40
#define P2000M_101F_PRNOUT 0x80
#define P2000M_202F_PINPUT 0x01
#define P2000M_202F_PREADY 0x02
#define P2000M_202F_STRAPN 0x04
#define P2000M_202F_CASENB 0x08
#define P2000M_202F_CASPOS 0x10
#define P2000M_202F_CASEND 0x20
#define P2000M_202F_CASCLK 0x40
#define P2000M_202F_CASDAT 0x80
#define P2000M_303F_VIDEO 0x01
#define P2000M_707F_DISA 0x01
/*
Keyboard port 0x0x
If the keyboard interrupt is enabled, all keyboard matrix rows are
connected and reading from either of these ports will give the
keyboard status (FF=no key pressed)
If the keyboard interrupt is disabled, reading one of these ports
will read the corresponding keyboard matrix row
*/
uint8_t p2000t_state::p2000t_port_000f_r(offs_t offset)
{
if (m_port_101f & P2000M_101F_KEYINT)
{
return (m_keyboard[0]->read() & m_keyboard[1]->read() & m_keyboard[2]->read()
& m_keyboard[3]->read() & m_keyboard[4]->read() & m_keyboard[5]->read()
& m_keyboard[6]->read() & m_keyboard[7]->read() & m_keyboard[8]->read()
& m_keyboard[9]->read());
}
else if (offset < 10)
{
return m_keyboard[offset]->read();
}
else
return 0xff;
}
/*
Input port 0x2x
bit 0 - Printer input
bit 1 - Printer ready
bit 2 - Strap N (daisy/matrix)
bit 3 - Cassette write enabled, 0 = Write enabled
bit 4 - Cassette in position, 0 = Cassette in position
bit 5 - Begin/end of tape 0 = Beginning or End of tap
bit 6 - Cassette read clock Flips when a bit is available.
bit 7 - Cassette read data
Note: bit 6 & 7 are swapped when the cassette is moving in reverse.
*/
uint8_t p2000t_state::p2000t_port_202f_r()
{
uint8_t data = 0x00;
data |= !m_mdcr->wen() << 3;
data |= !m_mdcr->cip() << 4;
data |= !m_mdcr->bet() << 5;
data |= m_mdcr->rdc() << 6;
data |= !m_mdcr->rda() << 7;
return data;
}
/*
Output Port 0x1x
bit 0 - Cassette write data
bit 1 - Cassette write command
bit 2 - Cassette rewind
bit 3 - Cassette forward
bit 4 - Unused
bit 5 - Unused
bit 6 - Keyboard interrupt enable
bit 7 - Printer output
*/
void p2000t_state::p2000t_port_101f_w(uint8_t data)
{
m_port_101f = data;
m_mdcr->wda(BIT(data, 0));
m_mdcr->wdc(BIT(data, 1));
m_mdcr->rev(BIT(data, 2));
m_mdcr->fwd(BIT(data, 3));
}
/*
Scroll Register 0x3x (P2000T only)
bit 0 - /
bit 1 - |
bit 2 - | Index of the first character
bit 3 - | to be displayed
bit 4 - |
bit 5 - |
bit 6 - \
bit 7 - Video disable (0 = enabled)
*/
void p2000t_state::p2000t_port_303f_w(uint8_t data) { m_port_303f = data; }
/*
Beeper 0x5x
bit 0 - Beeper
bit 1 - Unused
bit 2 - Unused
bit 3 - Unused
bit 4 - Unused
bit 5 - Unused
bit 6 - Unused
bit 7 - Unused
*/
void p2000t_state::p2000t_port_505f_w(uint8_t data) { m_speaker->level_w(BIT(data, 0)); }
/*
DISAS 0x7x (P2000M only)
bit 0 - Unused
bit 1 - DISAS enable
bit 2 - Unused
bit 3 - Unused
bit 4 - Unused
bit 5 - Unused
bit 6 - Unused
bit 7 - Unused
When the DISAS is active, the CPU has the highest priority and
video refresh is disabled when the CPU accesses video memory
*/
void p2000t_state::p2000t_port_707f_w(uint8_t data) { m_port_707f = data; }
void p2000t_state::p2000t_port_888b_w(uint8_t data) {}
void p2000t_state::p2000t_port_8c90_w(uint8_t data) {}
void p2000t_state::p2000t_port_9494_w(uint8_t data) {
// The memory region E000-FFFF (8k) is bank switched
int available_banks = (m_ram->size() - 0xe000) / 0x2000;
if (data < available_banks)
m_bank->set_entry(data);
}
void p2000t_state::machine_start()
{
auto program = &m_maincpu->space(AS_PROGRAM);
auto ramsize = m_ram->size();
switch(ramsize) {
case 0x4000: // 16kb
program->unmap_readwrite(0xa000, 0xffff);
break;
case 0x8000: // 32kb
program->unmap_readwrite(0xe000, 0xffff);
break;
default: // more.. (48kb, 64kb, 102kb)
// In this case we have a set of 8kb memory banks.
uint8_t *ram = m_ram->pointer();
auto available_banks = (ramsize - 0xe000) / 0x2000;
for(int i = 0; i < available_banks; i++)
m_bank->configure_entry(i, ram + (i * 0x2000));
break;
}
}
|