1 /*
2 * KCemu -- The emulator for the KC85 homecomputer series and much more.
3 * Copyright (C) 1997-2010 Torsten Paul
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #include <ctype.h>
21
22 #include "kc/system.h"
23
24 #include "kc/fdc4.h"
25 #include "kc/z80_fdc.h"
26
27 #include "libdbg/dbg.h"
28
FDC4(void)29 FDC4::FDC4(void)
30 {
31 fdc_z80->register_ic(this);
32 }
33
~FDC4(void)34 FDC4::~FDC4(void)
35 {
36 fdc_z80->unregister_ic(this);
37 }
38
39 long long
get_counter()40 FDC4::get_counter()
41 {
42 return fdc_z80->get_counter();
43 }
44
45 void
add_callback(unsigned long long offset,Callback * cb,void * data)46 FDC4::add_callback(unsigned long long offset, Callback *cb, void *data)
47 {
48 fdc_z80->add_callback(offset, cb, data);
49 }
50
51 byte_t
in(word_t addr)52 FDC4::in(word_t addr)
53 {
54 byte_t val = 0;
55
56 word_t pc = fdc_z80->getPC();
57
58 switch (addr & 0xff)
59 {
60 case 0xf0: // D004 (KC85/4)
61 /* CS-FDC (Chipselect) */
62 val = get_msr();
63 DBG(2, form("KCemu/FDC/in_F0",
64 "FDC::in(): %04xh addr = %04x, val = %02x [%c]\n",
65 pc, addr, val, isprint(val) ? val : '.'));
66 break;
67 case 0xf1: // D004 (KC85/4)
68 val = in_data(addr);
69 DBG(2, form("KCemu/FDC/in_F1",
70 "FDC::in(): %04xh addr = %04x, val = %02x [%c]\n",
71 pc, addr, val, isprint(val) ? val : '.'));
72 break;
73 case 0xf2: // D004 (KC85/4)
74 /* DAK-FDC (DMA-Acknowledge) */
75 val = read_byte();
76 DBG(2, form("KCemu/FDC/in_F2",
77 "FDC::in(): %04xh addr = %04x, val = %02x [%c]\n",
78 pc, addr, val, isprint(val) ? val : '.'));
79 break;
80 case 0xf4: // D004 (KC85/4)
81 /*
82 * Input-Gate:
83 *
84 * Bit 7 DRQ (DMA-Request)
85 * Bit 6 INT (Interrupt)
86 * Bit 5 RDY (Drive-Ready)
87 * Bit 4 IDX (Index - Spuranfang)
88 */
89 val = get_input_gate();
90 DBG(2, form("KCemu/FDC/in_F4",
91 "FDC::in(): %04xh addr = %04x, val = %02x [%c]\n",
92 pc, addr, val, isprint(val) ? val : '.'));
93 break;
94 case 0xf6: // D004 (KC85/4)
95 /* Select-Latch */
96 val = 0x00;
97 DBG(2, form("KCemu/FDC/in_F6",
98 "FDC::in(): %04xh addr = %04x, val = %02x [%c]\n",
99 pc, addr, val, isprint(val) ? val : '.'));
100 break;
101 case 0xf8: // D004 (KC85/4)
102 /* TC-FDC (Terminalcount) - End of DMA Transfer */
103 val = 0x00;
104 DBG(2, form("KCemu/FDC/in_F8",
105 "FDC::in(): %04xh addr = %04x, val = %02x [%c]\n",
106 pc, addr, val, isprint(val) ? val : '.'));
107 break;
108 }
109
110 DBG(2, form("KCemu/FDC/in",
111 "FDC::in(): %04xh addr = %04x, val = %02x\n",
112 pc, addr, val));
113
114 return val;
115 }
116
117 void
out(word_t addr,byte_t val)118 FDC4::out(word_t addr, byte_t val)
119 {
120 word_t pc = fdc_z80->getPC();
121
122 DBG(2, form("KCemu/FDC/out",
123 "FDC::out(): %04xh (I=%02x): addr = %04x, val = %02x [%c]\n",
124 pc, fdc_z80->getI(), addr, val, isprint(val) ? val : '.'));
125
126 switch (addr & 0xff)
127 {
128 case 0xf1: // D004 (KC85/4)
129 DBG(2, form("KCemu/FDC/out_F1",
130 "FDC::out(): %04xh addr = %04x, val = %02x [%c]\n",
131 pc, addr, val, isprint(val) ? val : '.'));
132 out_data(addr, val);
133 break;
134 case 0xf2: // D004 (KC85/4)
135 DBG(2, form("KCemu/FDC/out_F2",
136 "FDC::out(): %04xh addr = %04x, val = %02x [%c]\n",
137 pc, addr, val, isprint(val) ? val : '.'));
138 write_byte(val);
139 break;
140 case 0xf6: // D004 (KC85/4)
141 DBG(2, form("KCemu/FDC/out_F6",
142 "FDC::out(): %04xh addr = %04x, val = %02x [%c]\n",
143 pc, addr, val, isprint(val) ? val : '.'));
144 drive_select(val & 0x0f);
145 break;
146 case 0xf8: // D004 (KC85/4)
147 DBG(2, form("KCemu/FDC/out_F8",
148 "FDC::out(): %04xh Terminal Count %02x\n",
149 pc, val));
150
151 set_state(FDC_STATE_RESULT);
152 set_input_gate(0x40, 0x00);
153 break;
154 default:
155 DBG(2, form("KCemu/FDC/out_unhandled",
156 "FDC::out(): %04xh addr = %04x, val = %02x [%c]\n",
157 pc, addr, val, isprint(val) ? val : '.'));
158 break;
159 }
160 }
161