1 /*
2 * hardware.cpp - Atari hardware emulation
3 *
4 * Copyright (c) 2001-2004 Petr Stehlik of ARAnyM dev team (see AUTHORS)
5 *
6 * This file is part of the ARAnyM project which builds a new and powerful
7 * TOS/FreeMiNT compatible virtual machine running on almost any hardware.
8 *
9 * ARAnyM is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * ARAnyM is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with ARAnyM; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24
25 #include "sysdeps.h"
26 #include "hardware.h"
27 #include "cpu_emulation.h"
28 #include "memory-uae.h"
29 #include "icio.h"
30 #include "acsifdc.h"
31 #include "rtc.h"
32 #include "blitter.h"
33 #include "ide.h"
34 #include "mmu.h"
35 #include "hostscreen.h"
36 #include "midi_file.h"
37 #include "midi_sequencer.h"
38 #include "videl.h"
39 #include "videl_zoom.h"
40 #include "joypads.h"
41
42 #define DEBUG 0
43 #include "debug.h"
44
45 #define debug_print_IO(a) "unknown"
46
47 MFP *mfp;
48 MMU *mmu;
49 IKBD *ikbd;
50 MIDI *midi;
51 ACSIFDC *fdc;
52 RTC *rtc;
53 IDE *ide;
54 DSP *dsp;
55 BLITTER *blitter;
56 VIDEL *videl;
57 YAMAHA *yamaha;
58 ARADATA *aradata;
59 AUDIODMA *audiodma;
60 CROSSBAR *crossbar;
61 JOYPADS *joypads;
62 SCC *scc;
63
64 enum {iMFP = 0, iMMU, iIKBD, iMIDI, iFDC, iRTC, iIDE, iDSP, iBLITTER, iVIDEL,
65 iYAMAHA, iARADATA, iAUDIODMA, iCROSSBAR, iSCC, iCARTRIDGE, iJOYPADS,
66 /* the iITEMS must be the last one in the enum */
67 iITEMS};
68
69 BASE_IO *arhw[iITEMS];
70
HWInit()71 void HWInit()
72 {
73 arhw[iMFP] = mfp = new MFP(0xfffa00, 0x30);
74 arhw[iMMU] = mmu = new MMU(0xff8000, 8);
75 arhw[iIKBD] = ikbd = new IKBD(0xfffc00, 4);
76 #ifdef ENABLE_MIDI_SEQUENCER
77 if (strcmp("sequencer", bx_options.midi.type)==0)
78 midi = new MidiSequencer(0xfffc04, 4);
79 else
80 #endif
81 midi = new MidiFile(0xfffc04, 4);
82 arhw[iMIDI] = midi;
83 arhw[iFDC] = fdc = new ACSIFDC(0xff8600, 0x10);
84 arhw[iRTC] = rtc = new RTC(0xff8960, 4);
85 arhw[iIDE] = ide = new IDE(0xf00000, 0x3a);
86 arhw[iDSP] = dsp = new DSP(0xffa200, 8);
87 arhw[iBLITTER] = blitter = new BLITTER(0xff8A00, 0x3e);
88 arhw[iVIDEL] = videl = new VidelZoom(0xff8200, 0xc4);
89 arhw[iYAMAHA] = yamaha = new YAMAHA(0xff8800, 4);
90 arhw[iARADATA] = aradata = new ARADATA(0xf90000, 18);
91 arhw[iAUDIODMA] = audiodma = new AUDIODMA(0xff8900, 0x22);
92 arhw[iCROSSBAR] = crossbar = new CROSSBAR(0xff8930, 0x14);
93 arhw[iJOYPADS] = joypads = new JOYPADS(0xff9200, 0x24);
94
95 arhw[iSCC] = scc = new SCC(0xff8c81, 8);
96 arhw[iCARTRIDGE] = new BASE_IO(0xfa0000, 0x20000);
97 }
98 // {"DMA/SCSI", 0xff8700, 0x16, &fake_io},
99 // {"SCSI", 0xff8780, 0x10, &fake_io},
100 // {"MicroWire", 0xff8922, 0x4},
101 // {"DMA/SCC", 0xff8C00, 0x16},
102 // {"VME", 0xff8e00, 0x0c},
103 // {"STFPC", 0xfffa40, 8},
104 // {"RTC", 0xfffc20, 0x20}
105
HWExit()106 void HWExit()
107 {
108 for(int i=0; i<iITEMS; i++) {
109 delete arhw[i];
110 }
111 }
112
HWReset()113 void HWReset()
114 {
115 for(int i=0; i<iITEMS; i++) {
116 arhw[i]->reset();
117 }
118 }
119
getModule(memptr addr)120 BASE_IO *getModule(memptr addr)
121 {
122 for(int i=0; i<iITEMS; i++) {
123 if (arhw[i]->isMyHWRegister(addr))
124 return arhw[i];
125 }
126 D(bug("HW register %08x not emulated", addr));
127 return NULL;
128 }
129
getARADATA()130 ARADATA* getARADATA(){ return aradata; /* (ARADATA*)arhw[ARADATA];*/ }
getMFP()131 MFP* getMFP() { return mfp; }
getIKBD()132 IKBD* getIKBD() { return ikbd; }
getMIDI()133 MIDI* getMIDI() { return midi; }
getYAMAHA()134 YAMAHA* getYAMAHA() { return yamaha; }
getVIDEL()135 VIDEL* getVIDEL() { return videl; }
getDSP()136 DSP* getDSP() { return dsp; }
getFDC()137 ACSIFDC *getFDC() { return fdc; }
getIDE()138 IDE *getIDE() { return ide; }
getAUDIODMA()139 AUDIODMA *getAUDIODMA() { return audiodma; }
getCROSSBAR()140 CROSSBAR *getCROSSBAR() { return crossbar; }
getJOYPADS()141 JOYPADS *getJOYPADS() { return joypads; }
getSCC()142 SCC* getSCC() { return scc; }
143
HWget_l(uaecptr addr)144 uae_u32 HWget_l (uaecptr addr) {
145 D(bug("HWget_l %x <- %s at %08x", addr, debug_print_IO(addr), showPC()));
146 BASE_IO *ptr = getModule(addr);
147 if (ptr != NULL) {
148 return ptr->handleReadL(addr);
149 }
150 BUS_ERROR(addr);
151 }
152
HWget_w(uaecptr addr)153 uae_u16 HWget_w (uaecptr addr) {
154 D(bug("HWget_w %x <- %s at %08x", addr, debug_print_IO(addr), showPC()));
155 BASE_IO *ptr = getModule(addr);
156 if (ptr != NULL) {
157 return ptr->handleReadW(addr);
158 }
159 BUS_ERROR(addr);
160 }
161
HWget_b(uaecptr addr)162 uae_u8 HWget_b (uaecptr addr) {
163 D(bug("HWget_b %x <- %s at %08x", addr, debug_print_IO(addr), showPC()));
164 BASE_IO *ptr = getModule(addr);
165 if (ptr != NULL) {
166 return ptr->handleRead(addr);
167 }
168 BUS_ERROR(addr);
169 }
170
HWput_l(uaecptr addr,uae_u32 value)171 void HWput_l (uaecptr addr, uae_u32 value) {
172 D(bug("HWput_l %x,%d ($%08x) -> %s at %08x", addr, value, value, debug_print_IO(addr), showPC()));
173 BASE_IO *ptr = getModule(addr);
174 if (ptr != NULL) {
175 ptr->handleWriteL(addr, value);
176 return;
177 }
178 BUS_ERROR(addr);
179 }
180
HWput_w(uaecptr addr,uae_u16 value)181 void HWput_w (uaecptr addr, uae_u16 value) {
182 D(bug("HWput_w %x,%d ($%04x) -> %s at %08x", addr, value, value, debug_print_IO(addr), showPC()));
183 BASE_IO *ptr = getModule(addr);
184 if (ptr != NULL) {
185 ptr->handleWriteW(addr, value);
186 return;
187 }
188 BUS_ERROR(addr);
189 }
190
HWput_b(uaecptr addr,uae_u8 value)191 void HWput_b (uaecptr addr, uae_u8 value) {
192 D(bug("HWput_b %x,%u ($%02x) -> %s at %08x", addr, value, value, debug_print_IO(addr), showPC()));
193 BASE_IO *ptr = getModule(addr);
194 if (ptr != NULL) {
195 ptr->handleWrite(addr, value);
196 return;
197 }
198 BUS_ERROR(addr);
199 }
200