mirror of
https://github.com/Spritetm/minimacplus.git
synced 2024-12-01 10:50:34 +00:00
First commit
This commit is contained in:
commit
ad726c6e80
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
rom.bin
|
||||||
|
rom/
|
||||||
|
*.o
|
||||||
|
tme
|
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
[submodule "Musashi"]
|
||||||
|
path = musashi
|
||||||
|
url = https://github.com/kstenerud/Musashi.git
|
19
Makefile
Normal file
19
Makefile
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
TARGET:=tme
|
||||||
|
MUSASHI_GEN_SRC:=musashi/m68kops.c musashi/m68kopac.c musashi/m68kopdm.c musashi/m68kopnz.c
|
||||||
|
OBJ:=$(MUSASHI_GEN_SRC:%.x=%.o) musashi/m68kcpu.o main.o emu.o disp.o
|
||||||
|
#musashi/m68kdasm.o
|
||||||
|
CFLAGS=-Wall -I. -I./musashi -ggdb
|
||||||
|
LDFLAGS=
|
||||||
|
|
||||||
|
$(TARGET): $(OBJ)
|
||||||
|
$(CC) -o $(@) $(CFLAGS) $(LDFLAGS) $^
|
||||||
|
|
||||||
|
$(MUSASHI_GEN_SRC): musashi/m68kmake
|
||||||
|
cd musashi; ../$(^)
|
||||||
|
|
||||||
|
musashi/m68kmake: musashi/m68kmake.c
|
||||||
|
$(CC) -o $@ $^
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(MUSASHI_GEN_SRC) musashi/m68kmake
|
||||||
|
rm -f $(OBJ) $(TARGET)
|
5
config.h
Normal file
5
config.h
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
|
||||||
|
|
||||||
|
#define TME_ROMSIZE (64*1024)
|
||||||
|
|
||||||
|
#define TME_RAMSIZE (128*1024)
|
43
disp.c
Normal file
43
disp.c
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <SDL/SDL.h>
|
||||||
|
|
||||||
|
const int SCREEN_WIDTH = 512;
|
||||||
|
const int SCREEN_HEIGHT = 342;
|
||||||
|
|
||||||
|
SDL_Window* win = NULL;
|
||||||
|
SDL_Surface* surf = NULL;
|
||||||
|
SDL_Surface* drwsurf=NULL;
|
||||||
|
|
||||||
|
void sdlDie() {
|
||||||
|
printf("SDL could not initialize! SDL_Error: %s\n", SDL_GetError() );
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void dispInit() {
|
||||||
|
if (SDL_Init( SDL_INIT_VIDEO ) < 0 ) sdlDie();
|
||||||
|
win=SDL_CreateWindow( "TME", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN );
|
||||||
|
if (win==0) sdlDie();
|
||||||
|
surf=SDL_GetWindowSurface(win);
|
||||||
|
drwsurf=SDL_CreateRGBSurfaceWithFormat(0, SCREEN_WIDTH, SCREEN_HEIGHT, 32, SDL_PIXELFORMAT_RGBA32);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dispDraw(char *mem) {
|
||||||
|
int x, y, z;
|
||||||
|
uint32_t pixels=drwsurf->pixels;
|
||||||
|
SDL_LockSurface(drwsurf);
|
||||||
|
for (y=0; y<SCREEN_HEIGHT; y++) {
|
||||||
|
for (x=0; x<SCREEN_WIDTH; x+=8) {
|
||||||
|
for (z=1; z!=0x100; z++) {
|
||||||
|
if (*mem&z) *pixels=0xFFFFFF; else *pixels=0;
|
||||||
|
pixels++;
|
||||||
|
}
|
||||||
|
mem++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SDL_UnlockSurface(drwsurf);
|
||||||
|
SDL_BlitSurface(drwsurf, NULL, surf, NULL);
|
||||||
|
SDL_UpdateWindowSurface(win);
|
||||||
|
}
|
||||||
|
|
85
emu.c
Normal file
85
emu.c
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "emu.h"
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include "config.h"
|
||||||
|
#include "m68k.h"
|
||||||
|
#include "disp.h"
|
||||||
|
|
||||||
|
unsigned char *macRom;
|
||||||
|
unsigned char *macRam;
|
||||||
|
|
||||||
|
int rom_remap;
|
||||||
|
|
||||||
|
unsigned int m68k_read_memory_8(unsigned int address) {
|
||||||
|
unsigned int ret;
|
||||||
|
unsigned int pc=m68k_get_reg(NULL, M68K_REG_PC);
|
||||||
|
if (rom_remap && address < TME_ROMSIZE) {
|
||||||
|
ret=macRom[address];
|
||||||
|
} else if (address < TME_RAMSIZE) {
|
||||||
|
ret=macRam[address];
|
||||||
|
} else if (address>0x400000 && address<0x41FFFF) {
|
||||||
|
int romAdr=address-0x400000;
|
||||||
|
if (romAdr>TME_ROMSIZE) printf("PC %x:Huh? Read from ROM mirror (%x)\n", pc, address);
|
||||||
|
ret=macRom[romAdr&(TME_ROMSIZE-1)];
|
||||||
|
} else {
|
||||||
|
printf("PC %x: Read from %x\n", pc, address);
|
||||||
|
ret=0xff;
|
||||||
|
}
|
||||||
|
// printf("Rd %x = %x\n", address, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void m68k_write_memory_8(unsigned int address, unsigned int value) {
|
||||||
|
unsigned int pc=m68k_get_reg(NULL, M68K_REG_PC);
|
||||||
|
if (address < TME_RAMSIZE) {
|
||||||
|
macRam[address]=value;
|
||||||
|
} else {
|
||||||
|
printf("PC %x: Write to %x: %x\n", pc, address, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void tmeStartEmu(void *rom) {
|
||||||
|
macRom=rom;
|
||||||
|
macRam=malloc(TME_RAMSIZE);
|
||||||
|
rom_remap=1;
|
||||||
|
m68k_init();
|
||||||
|
m68k_set_cpu_type(M68K_CPU_TYPE_68000);
|
||||||
|
m68k_pulse_reset();
|
||||||
|
dispInit();
|
||||||
|
while(1) {
|
||||||
|
m68k_execute(8000000/60);
|
||||||
|
dispDraw(&macRam[0x1A700]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Mac uses an 68008, which has an external 8-bit bus. Hence, it should be okay to do everything using 8-bit
|
||||||
|
//reads/writes.
|
||||||
|
unsigned int m68k_read_memory_32(unsigned int address) {
|
||||||
|
unsigned int ret;
|
||||||
|
ret=m68k_read_memory_16(address)<<16;
|
||||||
|
ret|=m68k_read_memory_16(address+2);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int m68k_read_memory_16(unsigned int address) {
|
||||||
|
unsigned int ret;
|
||||||
|
ret=m68k_read_memory_8(address)<<8;
|
||||||
|
ret|=m68k_read_memory_8(address+1);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void m68k_write_memory_32(unsigned int address, unsigned int value) {
|
||||||
|
m68k_write_memory_16(address, value>>16);
|
||||||
|
m68k_write_memory_16(address+2, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void m68k_write_memory_16(unsigned int address, unsigned int value) {
|
||||||
|
m68k_write_memory_8(address, (value>>8)&0xff);
|
||||||
|
m68k_write_memory_8(address+1, value&0xff);
|
||||||
|
}
|
187
m68kconf.h
Executable file
187
m68kconf.h
Executable file
@ -0,0 +1,187 @@
|
|||||||
|
/* ======================================================================== */
|
||||||
|
/* ========================= LICENSING & COPYRIGHT ======================== */
|
||||||
|
/* ======================================================================== */
|
||||||
|
/*
|
||||||
|
* MUSASHI
|
||||||
|
* Version 3.4
|
||||||
|
*
|
||||||
|
* A portable Motorola M680x0 processor emulation engine.
|
||||||
|
* Copyright 1998-2001 Karl Stenerud. All rights reserved.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef M68KCONF__HEADER
|
||||||
|
#define M68KCONF__HEADER
|
||||||
|
|
||||||
|
|
||||||
|
/* Configuration switches.
|
||||||
|
* Use OPT_SPECIFY_HANDLER for configuration options that allow callbacks.
|
||||||
|
* OPT_SPECIFY_HANDLER causes the core to link directly to the function
|
||||||
|
* or macro you specify, rather than using callback functions whose pointer
|
||||||
|
* must be passed in using m68k_set_xxx_callback().
|
||||||
|
*/
|
||||||
|
#define OPT_OFF 0
|
||||||
|
#define OPT_ON 1
|
||||||
|
#define OPT_SPECIFY_HANDLER 2
|
||||||
|
|
||||||
|
|
||||||
|
/* ======================================================================== */
|
||||||
|
/* ============================== MAME STUFF ============================== */
|
||||||
|
/* ======================================================================== */
|
||||||
|
|
||||||
|
/* If you're compiling this for MAME, only change M68K_COMPILE_FOR_MAME
|
||||||
|
* to OPT_ON and use m68kmame.h to configure the 68k core.
|
||||||
|
*/
|
||||||
|
#ifndef M68K_COMPILE_FOR_MAME
|
||||||
|
#define M68K_COMPILE_FOR_MAME OPT_OFF
|
||||||
|
#endif /* M68K_COMPILE_FOR_MAME */
|
||||||
|
|
||||||
|
|
||||||
|
#if M68K_COMPILE_FOR_MAME == OPT_OFF
|
||||||
|
|
||||||
|
|
||||||
|
/* ======================================================================== */
|
||||||
|
/* ============================= CONFIGURATION ============================ */
|
||||||
|
/* ======================================================================== */
|
||||||
|
|
||||||
|
/* Turn ON if you want to use the following M68K variants */
|
||||||
|
#define M68K_EMULATE_010 OPT_ON
|
||||||
|
#define M68K_EMULATE_EC020 OPT_ON
|
||||||
|
#define M68K_EMULATE_020 OPT_ON
|
||||||
|
|
||||||
|
|
||||||
|
/* If ON, the CPU will call m68k_read_immediate_xx() for immediate addressing
|
||||||
|
* and m68k_read_pcrelative_xx() for PC-relative addressing.
|
||||||
|
* If off, all read requests from the CPU will be redirected to m68k_read_xx()
|
||||||
|
*/
|
||||||
|
#define M68K_SEPARATE_READS OPT_OFF
|
||||||
|
|
||||||
|
/* If ON, the CPU will call m68k_write_32_pd() when it executes move.l with a
|
||||||
|
* predecrement destination EA mode instead of m68k_write_32().
|
||||||
|
* To simulate real 68k behavior, m68k_write_32_pd() must first write the high
|
||||||
|
* word to [address+2], and then write the low word to [address].
|
||||||
|
*/
|
||||||
|
#define M68K_SIMULATE_PD_WRITES OPT_OFF
|
||||||
|
|
||||||
|
/* If ON, CPU will call the interrupt acknowledge callback when it services an
|
||||||
|
* interrupt.
|
||||||
|
* If off, all interrupts will be autovectored and all interrupt requests will
|
||||||
|
* auto-clear when the interrupt is serviced.
|
||||||
|
*/
|
||||||
|
#define M68K_EMULATE_INT_ACK OPT_OFF
|
||||||
|
#define M68K_INT_ACK_CALLBACK(A) your_int_ack_handler_function(A)
|
||||||
|
|
||||||
|
|
||||||
|
/* If ON, CPU will call the breakpoint acknowledge callback when it encounters
|
||||||
|
* a breakpoint instruction and it is running a 68010+.
|
||||||
|
*/
|
||||||
|
#define M68K_EMULATE_BKPT_ACK OPT_OFF
|
||||||
|
#define M68K_BKPT_ACK_CALLBACK() your_bkpt_ack_handler_function()
|
||||||
|
|
||||||
|
|
||||||
|
/* If ON, the CPU will monitor the trace flags and take trace exceptions
|
||||||
|
*/
|
||||||
|
#define M68K_EMULATE_TRACE OPT_OFF
|
||||||
|
|
||||||
|
|
||||||
|
/* If ON, CPU will call the output reset callback when it encounters a reset
|
||||||
|
* instruction.
|
||||||
|
*/
|
||||||
|
#define M68K_EMULATE_RESET OPT_OFF
|
||||||
|
#define M68K_RESET_CALLBACK() your_reset_handler_function()
|
||||||
|
|
||||||
|
|
||||||
|
/* If ON, CPU will call the set fc callback on every memory access to
|
||||||
|
* differentiate between user/supervisor, program/data access like a real
|
||||||
|
* 68000 would. This should be enabled and the callback should be set if you
|
||||||
|
* want to properly emulate the m68010 or higher. (moves uses function codes
|
||||||
|
* to read/write data from different address spaces)
|
||||||
|
*/
|
||||||
|
#define M68K_EMULATE_FC OPT_OFF
|
||||||
|
#define M68K_SET_FC_CALLBACK(A) your_set_fc_handler_function(A)
|
||||||
|
|
||||||
|
|
||||||
|
/* If ON, CPU will call the pc changed callback when it changes the PC by a
|
||||||
|
* large value. This allows host programs to be nicer when it comes to
|
||||||
|
* fetching immediate data and instructions on a banked memory system.
|
||||||
|
*/
|
||||||
|
#define M68K_MONITOR_PC OPT_OFF
|
||||||
|
#define M68K_SET_PC_CALLBACK(A) your_pc_changed_handler_function(A)
|
||||||
|
|
||||||
|
|
||||||
|
/* If ON, CPU will call the instruction hook callback before every
|
||||||
|
* instruction.
|
||||||
|
*/
|
||||||
|
#define M68K_INSTRUCTION_HOOK OPT_OFF
|
||||||
|
#define M68K_INSTRUCTION_CALLBACK() your_instruction_hook_function()
|
||||||
|
|
||||||
|
|
||||||
|
/* If ON, the CPU will emulate the 4-byte prefetch queue of a real 68000 */
|
||||||
|
#define M68K_EMULATE_PREFETCH OPT_OFF
|
||||||
|
|
||||||
|
|
||||||
|
/* If ON, the CPU will generate address error exceptions if it tries to
|
||||||
|
* access a word or longword at an odd address.
|
||||||
|
* NOTE: This is only emulated properly for 68000 mode.
|
||||||
|
*/
|
||||||
|
#define M68K_EMULATE_ADDRESS_ERROR OPT_OFF
|
||||||
|
|
||||||
|
|
||||||
|
/* Turn ON to enable logging of illegal instruction calls.
|
||||||
|
* M68K_LOG_FILEHANDLE must be #defined to a stdio file stream.
|
||||||
|
* Turn on M68K_LOG_1010_1111 to log all 1010 and 1111 calls.
|
||||||
|
*/
|
||||||
|
#define M68K_LOG_ENABLE OPT_OFF
|
||||||
|
#define M68K_LOG_1010_1111 OPT_OFF
|
||||||
|
#define M68K_LOG_FILEHANDLE stderr
|
||||||
|
|
||||||
|
|
||||||
|
/* ----------------------------- COMPATIBILITY ---------------------------- */
|
||||||
|
|
||||||
|
/* The following options set optimizations that violate the current ANSI
|
||||||
|
* standard, but will be compliant under the forthcoming C9X standard.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* If ON, the enulation core will use 64-bit integers to speed up some
|
||||||
|
* operations.
|
||||||
|
*/
|
||||||
|
#define M68K_USE_64_BIT OPT_OFF
|
||||||
|
|
||||||
|
|
||||||
|
/* Set to your compiler's static inline keyword to enable it, or
|
||||||
|
* set it to blank to disable it.
|
||||||
|
* If you define INLINE in the makefile, it will override this value.
|
||||||
|
* NOTE: not enabling inline functions will SEVERELY slow down emulation.
|
||||||
|
*/
|
||||||
|
#ifndef INLINE
|
||||||
|
#define INLINE static __inline__
|
||||||
|
#endif /* INLINE */
|
||||||
|
|
||||||
|
#endif /* M68K_COMPILE_FOR_MAME */
|
||||||
|
|
||||||
|
|
||||||
|
/* ======================================================================== */
|
||||||
|
/* ============================== END OF FILE ============================= */
|
||||||
|
/* ======================================================================== */
|
||||||
|
|
||||||
|
#endif /* M68KCONF__HEADER */
|
22
main.c
Normal file
22
main.c
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "emu.h"
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
|
||||||
|
static void *loadRom(char *file) {
|
||||||
|
char *ret=malloc(TME_ROMSIZE);
|
||||||
|
int f=open(file, O_RDONLY);
|
||||||
|
read(f, ret, TME_ROMSIZE);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
void *rom=loadRom("rom.bin");
|
||||||
|
tmeStartEmu(rom);
|
||||||
|
}
|
1
musashi
Submodule
1
musashi
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit 15a51d1c83b609f9878bf2550a711f567379571a
|
Loading…
Reference in New Issue
Block a user