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 <iostream>
21 #include <iomanip>
22 
23 #include "kc/system.h"
24 
25 #include "kc/kc.h"
26 #include "kc/ctc_fdc.h"
27 #include "kc/z80_fdc.h"
28 
29 #include "libdbg/dbg.h"
30 
31 /*
32  *  quoting the D004 programming manual:
33  *
34  *  Alle vier Kan�le des CTC sind hardwarem��ig kaskadiert. Die
35  *  Z�hlereingangsfrequenz des Kanals 0 betr�gt 500kHz. Der Kanal 3 ist
36  *  vom Betriebssystem interruptm��ig zur Laufwerksteuerung belegt. Die
37  *  Kan�le 0 und 1 werden von der Systemuhr verwendet. Kanal 1 arbeitet
38  *  dabei interruptgesteuert.
39  *
40  *  Die Adressen der Interruptserviceroutinen sind folgender Tabelle zu
41  *  entnehmen:
42  *
43  *  CTC-Kanal  Adresse  Wert
44  *
45  *   0          FBE0h   0000h
46  *   1          FBE2h   F0e4h
47  *   2          FBE4h   0000h
48  *   3          FBE6h   F4C8h
49  */
50 
CTC_FDC(void)51 CTC_FDC::CTC_FDC(void) : CTC("CTC (FDC)")
52 {
53 }
54 
~CTC_FDC(void)55 CTC_FDC::~CTC_FDC(void)
56 {
57 }
58 
59 long long
get_counter()60 CTC_FDC::get_counter()
61 {
62   return fdc_z80->get_counter();
63 }
64 
65 void
trigger_irq(int channel)66 CTC_FDC::trigger_irq(int channel)
67 {
68   fdc_z80->trigger_irq(getIRQVector(channel));
69 }
70 
71 void
add_callback(unsigned long long offset,Callback * cb,void * data)72 CTC_FDC::add_callback(unsigned long long offset, Callback *cb, void *data)
73 {
74   fdc_z80->add_callback(offset, cb, data);
75 }
76 
77 byte_t
in(word_t addr)78 CTC_FDC::in(word_t addr)
79 {
80   DBG(2, form("KCemu/CTC/FDC/in",
81               "CTC_FDC::in(): addr = %04x\n",
82               addr));
83 
84   switch (addr & 3)
85     {
86     case 0:
87       return c_in(0);
88     case 1:
89       return c_in(1);
90     case 2:
91       return c_in(2);
92     case 3:
93       return c_in(3);
94     }
95 
96   return 0; // shouldn't be reached
97 }
98 
99 void
out(word_t addr,byte_t val)100 CTC_FDC::out(word_t addr, byte_t val)
101 {
102   DBG(2, form("KCemu/CTC/FDC/out",
103               "CTC_FDC::out(): addr = %04x, val = %02x\n",
104               addr, val));
105   switch (addr & 3)
106     {
107     case 0:
108       c_out(0, val);
109       break;
110     case 1:
111       c_out(1, val);
112       break;
113     case 2:
114       c_out(2, val);
115       break;
116     case 3:
117       c_out(3, val);
118       break;
119     }
120 }
121 
122 bool
irq_0(void)123 CTC_FDC::irq_0(void)
124 {
125   DBG(2, form("KCemu/CTC_FDC/irq/0",
126 	      "CTC::irq_0()\n"));
127   trigger(1);
128   return true;
129 }
130 
131 bool
irq_1(void)132 CTC_FDC::irq_1(void)
133 {
134   DBG(2, form("KCemu/CTC_FDC/irq/1",
135 	      "CTC::irq_1()\n"));
136   return true;
137 }
138 
139 bool
irq_2(void)140 CTC_FDC::irq_2(void)
141 {
142   DBG(2, form("KCemu/CTC_FDC/irq/2",
143 	      "CTC::irq_2()\n"));
144   return true;
145 }
146 
147 bool
irq_3(void)148 CTC_FDC::irq_3(void)
149 {
150   DBG(2, form("KCemu/CTC_FDC/irq/3",
151 	      "CTC::irq_3()\n"));
152   return true;
153 }
154 
155 long
counter_value_0(void)156 CTC_FDC::counter_value_0(void)
157 {
158   return 0;
159 }
160 
161 long
counter_value_1(void)162 CTC_FDC::counter_value_1(void)
163 {
164   return 0;
165 }
166 
167 long
counter_value_2(void)168 CTC_FDC::counter_value_2(void)
169 {
170   return 0;
171 }
172 
173 long
counter_value_3(void)174 CTC_FDC::counter_value_3(void)
175 {
176   return 0;
177 }
178