1 /*
2  *  Copyright (C) 2006-2014  Anders Gavare.  All rights reserved.
3  *
4  *  Redistribution and use in source and binary forms, with or without
5  *  modification, are permitted provided that the following conditions are met:
6  *
7  *  1. Redistributions of source code must retain the above copyright
8  *     notice, this list of conditions and the following disclaimer.
9  *  2. Redistributions in binary form must reproduce the above copyright
10  *     notice, this list of conditions and the following disclaimer in the
11  *     documentation and/or other materials provided with the distribution.
12  *  3. The name of the author may not be used to endorse or promote products
13  *     derived from this software without specific prior written permission.
14  *
15  *  THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  *  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  *  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  *  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  *  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  *  OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  *  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  *  SUCH DAMAGE.
26  *
27  *
28  *  COMMENT: SEGA Dreamcast
29  */
30 
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <sstream>
35 #include <string>
36 
37 #include "cpu.h"
38 #include "device.h"
39 #include "devices.h"
40 #include "machine.h"
41 #include "memory.h"
42 #include "misc.h"
43 
44 
45 using namespace std;
46 
47 
MACHINE_SETUP(dreamcast)48 MACHINE_SETUP(dreamcast)
49 {
50 	machine->machine_name = strdup("Dreamcast");
51 
52 	if (machine->emulated_hz == 0)
53 		machine->emulated_hz = 200000000;
54 
55 	/*  50 MHz SH4 PCLOCK:  */
56 	machine->cpus[0]->cd.sh.pclock = 50000000;
57 
58 	if (!machine->x11_md.in_use)
59 		fprintf(stderr, "-------------------------------------"
60 		    "------------------------------------------\n"
61 		    "\n  WARNING!  You are emulating a Dreamcast without -X."
62 		    "\n            You will miss graphical output!\n\n"
63 		    "-------------------------------------"
64 		    "------------------------------------------\n");
65 
66 	/*
67 	 *  Physical address layout on the Dreamcast, according to a
68 	 *  combination of sources:  NetBSD sources, KallistiOS sources,
69 	 *  http://www.boob.co.uk/docs/Dreamcast_memory.txt, and
70 	 *  http://www.ludd.luth.se/~jlo/dc/memory.txt, and possibly some
71 	 *  others:
72 	 *
73 	 *  0x00000000 - 0x001fffff	Boot ROM (2 MB)
74 	 *  0x00200000 - 0x0021ffff	Flash (128 KB) (perhaps multiple images afterwards?)
75 	 *				The bytes read by the Dreamcast PROM during
76 	 *				boot are:
77 	 *				    Offset 0x1a000 .. 0x1a004 = 5 bytes debug/startup state?
78 	 *					hex digits (maybe limited to 0x30, 0x31, 0x32, or 0x33)
79 	 *				    Offset 0x1a02d .. 0x1a037 = date/time values.
80 	 *				    Offset 0x1a056 .. 0x1a05d = 8 bytes serial number / machine ID.
81 	 *  0x005f0000 - ...            ???
82 	 *  0x005f6800 - ...		PowerVR2 DMA registers
83 	 *  0x005f6900 - ...		ASIC registers
84 	 *  0x005f6c00 - ...		Maple registers (controller ports)
85 	 *  0x005f7000 - ...		GDROM registers
86 	 *  0x005f7400 - ...		(G2 External DMA registers? Or GDROM?)
87 	 *  0x005f74e4 - ...		GDROM re-enable disabled drive (?)
88 	 *  0x005f7800 - ...		G2 External DMA registers
89 	 *  0x005f7c00 - ...		DMA (?) for some device (PVR related?)
90 	 *  0x005f8000 - 0x005f9fff	PVR registers (graphics)
91 	 *  0x00600000 - 0x006007ff	G2 bus: Modem
92 	 *  0x00600400 - 0x0060047f	G2 bus: LAN Adapter (MB86967) registers?
93 	 *  0x00620000 - 0x00623fff	G2 bus: Expansion port?
94 	 *  0x00606900 - ...		???
95 	 *  0x00700000 - ...		SPU registers (sound)
96 	 *  0x00702800 - 0x007028ff	???
97 	 *  0x00702c00 -		Cable select and AICA (?) (*3)
98 	 *  0x00703xxx - ...		AICA something
99 	 *  0x00710000 - 0x00710007	RTC registers
100 	 *  0x00800000 - 0x009fffff	AICA (Sound) RAM (2 MB) (*4)
101 	 *  0x01000000 - 0x01ffffff	G2 bus or Parallel port registers?
102 	 *  0x02000000 - ...		CD-ROM port registers
103 	 *  0x03000000 - 0x03ffffff	G2 bus (?)
104 	 *  0x04000000 - 0x047fffff	Video RAM (*)     (64-bit)
105 	 *  0x05000000 - 0x057fffff	Video RAM (8 MB)  (32-bit)
106 	 *  0x06000000 - 0x067fffff	Video RAM (*)     (64-bit) (copy)
107 	 *  0x07000000 - 0x077fffff	Video RAM (8 MB)  (32-bit) (copy)
108 	 *  0x0c000000 - 0x0cffffff	RAM (16 MB)
109 	 *  0x0e000000 - 0x0effffff	Copy of RAM? (*2)
110 	 *  0x10000000 - 0x107fffff	Tile Accelerator: command area
111 	 *  0x10800000 - 0x10ffffff	Tile Accelerator: YUV data
112 	 *  0x11000000 - 0x11ffffff	Tile Accelerator: Texture data
113 	 *  0x14000000 - 0x17ffffff	G2 bus (?)
114 	 *
115 	 *  (*1) = with banks 0 and 1 switched; 64-bit read/write access...
116 	 *  (*2) The "luftvarg" 4KB intro uses memory at paddr 0x0ef00000...
117 	 *  (*3) = See VOUTC in Linux' drivers/video/pvr2fb.c.
118 	 *  (*4) = It seems that ARM machine code is placed here.
119 	 */
120 
121 	dev_ram_init(machine, 0x00000000, 2 * 1024 * 1024,
122 	    DEV_RAM_RAM /* | DEV_RAM_TRACE_ALL_ACCESSES */, 0x0, "bootrom");
123 
124 	dev_ram_init(machine, 0x00200000, 128 * 1024,
125 	    DEV_RAM_RAM /* | DEV_RAM_TRACE_ALL_ACCESSES */, 0x0, "flash");
126 
127 	dev_ram_init(machine, 0x00600004, 4, DEV_RAM_RAM, 0);
128 	dev_ram_init(machine, 0x00700000, 0x27ff, DEV_RAM_RAM, 0);
129 	dev_ram_init(machine, 0x00702800, 256, DEV_RAM_RAM, 0);
130 	dev_ram_init(machine, 0x00702c00, 4, DEV_RAM_RAM, 0);
131 	dev_ram_init(machine, 0x00703000, 0x1fff, DEV_RAM_RAM, 0);
132 
133 	/*  Sound RAM:  */
134 	dev_ram_init(machine, 0x00800000, 2 * 1048576, DEV_RAM_RAM, 0, "sound_ram");
135 
136 	/*
137 	 *  HACK!  TODO: Remove this device at 0x00a00000 once NetBSD has
138 	 *  been fixed to not clear 6 MB beyound the sound RAM area.
139 	 */
140 	dev_ram_init(machine, 0x00a00000, 6 * 1048576, DEV_RAM_RAM, 0, "hack_for_netbsd");
141 
142 	/*  RAM:  */
143 	dev_ram_init(machine, 0x0c000000, 16 * 1048576, DEV_RAM_RAM, 0x0);
144 
145 	/*  Image of RAM:  */
146 	dev_ram_init(machine, 0x0e000000, 16 * 1048576, DEV_RAM_MIRROR
147 		| DEV_RAM_MIGHT_POINT_TO_DEVICES, 0x0c000000, "ram_mirror");
148 
149 	device_add(machine, "pvr");
150 /*	device_add(machine, "mb8696x addr=0x600400 addr_mult=4");  */
151 	device_add(machine, "dreamcast_asic");
152 	device_add(machine, "dreamcast_g2");
153 	device_add(machine, "dreamcast_gdrom");
154 	device_add(machine, "dreamcast_maple");
155 	device_add(machine, "dreamcast_rtc");
156 
157 	// Add devices as symbols, so that they show up in disassembly/runtime.
158 	struct memory *mem = cpu->mem;
159 	for (int i = 0; i < mem->n_mmapped_devices; i++) {
160 		// Add everything which is not called "ram" (for now).
161 		if (strcmp(mem->devices[i].name, "ram") == 0) {
162 			continue;
163 		}
164 
165 		stringstream ss;
166 		ss.flags(ios::hex);
167 		ss << "(" << mem->devices[i].name << "@0x" << mem->devices[i].baseaddr << ")";
168 		string name = ss.str();
169 
170 		add_symbol_name(
171 		    &machine->symbol_context,
172 		    mem->devices[i].baseaddr | 0x80000000U,
173 		    mem->devices[i].length,
174 		    name.c_str(),
175 		    0, 0);
176 
177 		add_symbol_name(
178 		    &machine->symbol_context,
179 		    mem->devices[i].baseaddr | 0xa0000000U,
180 		    mem->devices[i].length,
181 		    name.c_str(),
182 		    0, 0);
183 	}
184 
185 	if (!machine->prom_emulation)
186 		return;
187 
188 	dreamcast_machine_setup(machine);
189 }
190 
191 
MACHINE_DEFAULT_CPU(dreamcast)192 MACHINE_DEFAULT_CPU(dreamcast)
193 {
194 	// Hitachi SH4, 200 MHz.  (Or probably an "SH4a".)
195 	machine->cpu_name = strdup("SH7750");
196 }
197 
198 
MACHINE_DEFAULT_RAM(dreamcast)199 MACHINE_DEFAULT_RAM(dreamcast)
200 {
201 	// Note: This is the size of the boot ROM area, since the
202 	// Dreamcast's RAM isn't located at physical address zero.
203 	machine->physical_ram_in_mb = 2;
204 }
205 
206 
MACHINE_REGISTER(dreamcast)207 MACHINE_REGISTER(dreamcast)
208 {
209 	MR_DEFAULT(dreamcast, "Dreamcast", ARCH_SH, MACHINE_DREAMCAST);
210 	me->set_default_ram = machine_default_ram_dreamcast;
211 	machine_entry_add_alias(me, "dreamcast");
212 }
213 
214