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