-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathio.cpp
More file actions
162 lines (145 loc) · 2.64 KB
/
io.cpp
File metadata and controls
162 lines (145 loc) · 2.64 KB
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
#include <stdint.h>
#include <stddef.h>
#include <machine.h>
#include <memory.h>
#include <CPU.h>
#include <display.h>
#include <serial_kbd.h>
#include <serial_dsp.h>
#include <hardware.h>
#include <debugging.h>
#include "banked_memory.h"
#include "io.h"
void IO::reset() {
_kbd.reset();
_dsp.reset();
dsk_reset();
}
uint8_t IO::kbd_poll() {
uint8_t c;
do {
_machine->yield();
c = _kbd.read();
} while (c == 0xff);
return c;
}
uint8_t IO::clk_data() {
uint32_t s = millis() / 1000;
switch (clkcmd) {
case 0:
return s % 60;
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
DBG_EMU("IO: unhandled clk_data(%u)", clkcmd);
break;
}
return 0x00;
}
void IO::clk_cmd(uint8_t cmd) {
clkcmd = cmd;
if (cmd == 0xff)
clkfmt = !clkfmt;
}
uint8_t IO::in(uint16_t port) {
port &= 0xff;
switch (port) {
case CON_ST:
return _kbd.available()? 0xff: 0x00;
case CON_IN:
return kbd_poll();
case FDC_STATUS:
return dsk_status;
case FDC_IODONE:
return 1;
case FDC_GETSEC_L:
return setsec & 0xff;
case FDC_GETSEC_H:
return (setsec & 0xff00) >> 8;
case FDC_GETTRK:
return settrk;
case MEM_INIT:
return _mem.num_banks();
case MEM_SELECT:
return _mem.selected();
case MEM_BANKSIZE:
return _mem.bank_size();
case MEM_WP_COMMON:
return _mem.wp_common();
case CLK_DATA:
return clk_data();
case CLK_CMD:
return clkfmt;
case TIMER:
return timer? 1: 0;
case CON1_ST:
case CON2_ST:
case NET1_ST:
return 0x00; // ignore
default:
DBG_EMU("IO: unhandled IN(%u)", port);
break;
}
return 0x00;
}
void IO::out(uint16_t port, uint8_t a) {
port &= 0xff;
switch(port) {
case FDC_SELDSK:
dsk_status = dsk_select(a);
break;
case FDC_SETTRK:
dsk_status = dsk_settrk(a);
break;
case FDC_SETSEC_L:
dsk_status = dsk_setsec((setsec & 0xff00) | a);
break;
case FDC_SETSEC_H:
dsk_status = dsk_setsec(a << 8 | (setsec & 0xff));
break;
case FDC_SETDMA_L:
setdma = (setdma & 0xff00) | a;
break;
case FDC_SETDMA_H:
setdma = (a << 8) | (setdma & 0xff);
break;
case FDC_IO:
dsk_status = (a? dsk_write(): dsk_read());
break;
case CON_OUT:
_dsp.write(a);
break;
case MEM_INIT:
_mem.begin(a);
break;
case MEM_SELECT:
_mem.select(a);
break;
case MEM_BANKSIZE:
_mem.bank_size(a);
break;
case MEM_WP_COMMON:
_mem.wp_common(a);
break;
case TIMER:
if (timer && !a) {
_machine->cancel_timer(timer);
timer = 0;
} else if (!timer && a && tick_handler)
timer = _machine->interval_timer(10, tick_handler);
break;
case CLK_CMD:
clk_cmd(a);
break;
case MONITOR:
ERR("IO: monitor(%02x)", a);
break;
default:
DBG_EMU("IO: unhandled OUT(%u, %u)", port, a);
break;
}
}