This commit is contained in:
Jeroen Domburg 2017-09-03 16:02:16 +08:00
parent fd6cda6124
commit 6d04d3b857
9 changed files with 246 additions and 51 deletions

View File

@ -62,7 +62,7 @@ int adns9500_init() {
.pin_bit_mask=(1<<ADNS_MISO),
.mode=GPIO_MODE_INPUT,
.pull_up_en=GPIO_PULLUP_ENABLE,
.pull_down_en=GPIO_PULLDOWN_DISABLE,
// .pull_down_en=GPIO_PULLDOWN_DISABLE,
.intr_type=GPIO_PIN_INTR_DISABLE
}
};

View File

@ -5,7 +5,7 @@
#include "ncr.h"
#include "hd.h"
#include "esp_partition.h"
#include "esp_heap_alloc_caps.h"
#include "hexdump.h"
typedef struct {
const esp_partition_t* part;
@ -25,18 +25,23 @@ const uint8_t inq_resp[95]={
'1','.','0',' ',' ',' ',' ',' ', //prod rev lvl
};
static uint8_t bouncebuffer[512];
static int hdScsiCmd(SCSITransferData *data, unsigned int cmd, unsigned int len, unsigned int lba, void *arg) {
int ret=0;
static uint8_t *bb=NULL;
HdPriv *hd=(HdPriv*)arg;
if (cmd==0x8 || cmd==0x28) { //read
printf("HD: Read %d bytes from LBA %d.\n", len*512, lba);
for (int i=0; i<len; i++) {
esp_partition_read(hd->part, (lba+i)*512, bouncebuffer, 512);
memcpy(&data->data[i*512], bouncebuffer, len*512);
}
#if 0 //spi ram read/write does not play well with flash reads
assert(esp_partition_read(hd->part, lba*512, data->data, len*512)==ESP_OK);
#else
uint8_t *buf;
spi_flash_mmap_handle_t handle;
esp_partition_mmap(hd->part, lba*512, len*512, SPI_FLASH_MMAP_DATA, &buf, &handle);
memcpy(data->data, buf, len*512);
spi_flash_munmap(handle);
#endif
// hexdump(data->data, len*512);
ret=len*512;
} else if (cmd==0x12) { //inquiry
printf("HD: Inquery\n");

View File

@ -25,12 +25,7 @@ unsigned char *romdata;
void emuTask(void *pvParameters)
{
void *ram=malloc(TME_RAMSIZE);
if (ram==NULL) {
printf("Couldn't allocate main ram.\n");
abort();
}
tmeStartEmu(ram, romdata);
tmeStartEmu(romdata);
}

View File

@ -4,9 +4,9 @@ TARGET:=tme
MUSASHI_GEN_SRC:=musashi/m68kopac.c musashi/m68kopdm.c musashi/m68kopnz.c
MUSASHI_OP_PREGEN_SRC:=musashi/m68kops_pre.c
OBJ:=$(MUSASHI_GEN_SRC:%.x=%.o) $(MUSASHI_OP_PREGEN_SRC:%.x=%.o) musashi/m68kcpu.o sdl/main.o sdl/disp.o sdl/hd.o \
emu.o iwm.o via.o rtc.o ncr.o scc.o mouse.o
emu.o iwm.o via.o rtc.o ncr.o scc.o mouse.o hostbuild/espspiramemu.o
#musashi/m68kdasm.o
CFLAGS=-Wall -I. -I./musashi -Og -ggdb `sdl2-config --cflags`
CFLAGS=-Wall -I. -I./musashi -I./hostbuild -Og -ggdb `sdl2-config --cflags`
LDFLAGS=`sdl2-config --libs`
$(TARGET): $(OBJ)

View File

@ -1,11 +1,13 @@
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "emu.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/time.h>
#include <string.h>
#include "tmeconfig.h"
#include "m68k.h"
#include "disp.h"
@ -19,9 +21,20 @@
#include <stdbool.h>
#include "esp_heap_caps.h"
#include <byteswap.h>
#include "esp_spiram.h"
unsigned char *macRom;
#if (TME_CACHESIZE!=0)
#define USE_EXTERNAL_RAM 1
#else
#define USE_EXTERNAL_RAM 0
unsigned char *macRam;
#endif
#define MEMADDR_DUMMY_CACHE (void*)1
int rom_remap, video_remap=0, audio_remap=0;
@ -106,12 +119,12 @@ typedef struct {
#define MEMMAP_ES 0x20000 //entry size
#define MEMMAP_MAX_ADDR 0x1000000
//Memmap describing 128 128K blocks of memory, from 0 to 0x1000000 (16MiB).
MemmapEnt memmap[128];
MemmapEnt memmap[MEMMAP_MAX_ADDR/MEMMAP_ES];
static void regenMemmap(int remapRom) {
int i;
//Default handler
for (i=0; i<128; i++) {
for (i=0; i<MEMMAP_MAX_ADDR/MEMMAP_ES; i++) {
memmap[i].memAddr=0;
memmap[i].cb=unhandledAccessCb;
}
@ -128,7 +141,11 @@ static void regenMemmap(int remapRom) {
}
} else {
for (i=0; i<0x400000/MEMMAP_ES; i++) {
#if USE_EXTERNAL_RAM
memmap[i].memAddr=MEMADDR_DUMMY_CACHE;
#else
memmap[i].memAddr=&macRam[(i*MEMMAP_ES)&(TME_RAMSIZE-1)];
#endif
memmap[i].flags=0;
}
}
@ -150,7 +167,11 @@ static void regenMemmap(int remapRom) {
//0x600000-0x700000 is RAM
for (i=0x600000/MEMMAP_ES; i<0x700000/MEMMAP_ES; i++) {
#if USE_EXTERNAL_RAM
memmap[i].memAddr=MEMADDR_DUMMY_CACHE;
#else
memmap[i].memAddr=&macRam[(i*MEMMAP_ES)&(TME_RAMSIZE-1)];
#endif
memmap[i].flags=0;
}
@ -172,27 +193,166 @@ static void regenMemmap(int remapRom) {
}
}
uint8_t *macFb[2];
#if (USE_EXTERNAL_RAM)
//Keep these things powers-of-2 please.
#define CACHESIZE TME_CACHESIZE
#define CACHEITEMSIZE (1*1024)
#define CACHEENTCNT ((TME_RAMSIZE)/CACHEITEMSIZE)
#define CACHESLOTCNT (CACHESIZE/CACHEITEMSIZE)
#define FBSLOTCNT ((22*1024+(CACHEITEMSIZE-1))/CACHEITEMSIZE)
typedef struct {
uint8_t *mem;
int ent;
} CacheSlot;
#define NO_ENT 0xFF
static uint8_t cacheEnt[CACHEENTCNT];
static CacheSlot cacheSlot[CACHESLOTCNT+FBSLOTCNT*2];
static int cacheSwapPos=0;
#define MMAP_RAM_PTR(ent, addr) ((ent->memAddr==MEMADDR_DUMMY_CACHE)?getRamPtr(addr&(TME_RAMSIZE-1)):&ent->memAddr[addr&(MEMMAP_ES-1)])
/*
Warning: This malfunctions if e.g. a 32-bit val starting at an address [1-3] from the end of the region is requested.
Luckily, on the 68000 itself this leads to an exception and should never happen.
*/
static inline uint8_t *getRamPtr(const unsigned int address) {
assert(address<TME_RAMSIZE);
uint16_t slot=cacheEnt[address/CACHEITEMSIZE];
if (slot==NO_ENT) {
//Invalid entry. Find oldest entry, swap to RAM, load this entry, return ptr.
//We use a stupid round-robin exchange thing for killing old pages for now... ToDo: make more intelligent.
cacheSwapPos++;
if (cacheSwapPos>=CACHESLOTCNT) cacheSwapPos=0;
slot=cacheSwapPos;
//Write old data.
int oldaddr=cacheSlot[slot].ent*CACHEITEMSIZE;
esp_spiram_write(oldaddr, cacheSlot[slot].mem, CACHEITEMSIZE);
cacheEnt[cacheSlot[slot].ent]=NO_ENT;
//Read new data.
cacheSlot[slot].ent=address/CACHEITEMSIZE;
int newaddr=cacheSlot[slot].ent*CACHEITEMSIZE;;
esp_spiram_read(newaddr, cacheSlot[slot].mem, CACHEITEMSIZE);
cacheEnt[address/CACHEITEMSIZE]=slot;
// printf("CACHE SWAPOUT: slot %d address %x -> address %x\n", slot, oldaddr, newaddr);
}
return cacheSlot[slot].mem+(address&(CACHEITEMSIZE-1));
}
static void ramInit() {
printf("Using external SPI memory as Mac RAM\n");
#if 1
char obuf[128], ibuf[128];
for (int i=0; i<128; i++) obuf[i]=rand();
esp_spiram_write(0, obuf, 128);
esp_spiram_read(0, ibuf, 128);
if (memcmp(obuf, ibuf, 128)!=0) {
printf("Error: External SPI ram is not stable.\n");
abort();
}
#endif
for (int x=0; x<CACHEENTCNT; x++) {
cacheEnt[x]=NO_ENT;
}
//Initialize the cache to point to the first few slots of memory.
for (int x=0; x<CACHESLOTCNT; x++) {
cacheEnt[x]=x;
cacheSlot[x].ent=x;
cacheSlot[x].mem=malloc(CACHEITEMSIZE);
if (!cacheSlot[x].mem) {
printf("Could not allocate memory for cache slot %d\n", x);
abort();
}
memset(cacheSlot[x].mem, 0, CACHEITEMSIZE);
}
//Framebuffer is dedicated memory. Allocate and set in cache set.
int sz=FBSLOTCNT*CACHEITEMSIZE;
macFb[0]=malloc(sz);
macFb[1]=malloc(sz);
if (!macFb[0] || !macFb[1]) {
printf("Couldn't allocate framebuffer memory!\n");
abort();
}
memset(macFb[0], 0xF0, sz);
memset(macFb[1], 0x0F, sz);
for (int i=0; i<FBSLOTCNT; i++) {
cacheSlot[CACHESLOTCNT+i].mem=macFb[0]+i*CACHEITEMSIZE;
cacheEnt[(TME_SCREENBUF/CACHEITEMSIZE)+i]=CACHESLOTCNT+i;
cacheSlot[CACHESLOTCNT+FBSLOTCNT+i].mem=macFb[1]+i*CACHEITEMSIZE;
cacheEnt[(TME_SCREENBUF_ALT/CACHEITEMSIZE)+i]=CACHESLOTCNT+FBSLOTCNT+i;
}
//Fbs probably are aligned with cache page size, but de-aligned with visibe image. Fix that.
macFb[0]=getRamPtr(TME_SCREENBUF);
macFb[1]=getRamPtr(TME_SCREENBUF_ALT);
#if 0
printf("Doing mem/cache test\n");
srand(0);
for (int i=0; i<TME_RAMSIZE; i+=4) {
uint32_t *p=(uint32_t*)getRamPtr(i^0x25A500);
*p=rand();
}
printf("Readback...\n");
srand(0);
for (int i=0; i<TME_RAMSIZE; i+=4) {
uint32_t *p=(uint32_t*)getRamPtr(i^0x25A500);
uint32_t ex=rand();
if (*p!=ex) {
printf("Error!= Addr %x expected %x got %x\n", i, ex, *p);
}
*p=0;
}
#endif
}
#else
#define MMAP_RAM_PTR(ent, addr) &ent->memAddr[addr&(MEMMAP_ES-1)]
static void ramInit() {
printf("Using internal memory as Mac RAM\n");
macRam=malloc(TME_RAMSIZE);
macFb[0]=&macRam[TME_SCREENBUF];
macFb[1]=&macRam[TME_SCREENBUF_ALT];
printf("Clearing ram...\n");
for (int x=0; x<TME_RAMSIZE; x++) macRam[x]=rand();
}
#endif
const inline static MemmapEnt *getMmmapEnt(const unsigned int address) {
if (address>=MEMMAP_MAX_ADDR) return &memmap[127];
return &memmap[address/MEMMAP_ES];
}
unsigned int m68k_read_memory_8(unsigned int address) {
unsigned int m68k_read_memory_8(unsigned int address) {
const MemmapEnt *mmEnt=getMmmapEnt(address);
if (mmEnt->memAddr) {
uint8_t *p;
p=&mmEnt->memAddr[address&(MEMMAP_ES-1)];
p=(uint8_t*)MMAP_RAM_PTR(mmEnt, address);
return *p;
} else {
return mmEnt->cb(address, 0, 0);
}
}
unsigned int m68k_read_memory_16(unsigned int address) {
unsigned int m68k_read_memory_16(unsigned int address) {
const MemmapEnt *mmEnt=getMmmapEnt(address);
if ((address&1)!=0) printf("%s: Unaligned access to %x!\n", __FUNCTION__, address);
if (mmEnt->memAddr) {
uint16_t *p;
p=&mmEnt->memAddr[address&(MEMMAP_ES-1)];
p=(uint16_t*)MMAP_RAM_PTR(mmEnt, address);
return __bswap_16(*p);
} else {
unsigned int ret;
@ -202,11 +362,13 @@ unsigned int m68k_read_memory_16(unsigned int address) {
}
}
unsigned int m68k_read_memory_32(unsigned int address) {
#if 0
unsigned int m68k_read_memory_32(unsigned int address) {
const MemmapEnt *mmEnt=getMmmapEnt(address);
if ((address&3)!=0) printf("%s: Unaligned access to %x!\n", __FUNCTION__, address);
if (mmEnt->memAddr) {
uint32_t *p;
p=&mmEnt->memAddr[address&(MEMMAP_ES-1)];
p=(uint32_t*)MMAP_RAM_PTR(mmEnt, address);
return __bswap_32(*p);
} else {
unsigned int ret;
@ -217,12 +379,19 @@ unsigned int m68k_read_memory_32(unsigned int address) {
return ret;
}
}
#else
unsigned int m68k_read_memory_32(unsigned int address) {
uint16_t a=m68k_read_memory_16(address);
uint16_t b=m68k_read_memory_16(address+2);
return (a<<16)|b;
}
#endif
void m68k_write_memory_8(unsigned int address, unsigned int value) {
const MemmapEnt *mmEnt=getMmmapEnt(address);
if (mmEnt->memAddr) {
uint8_t *p;
p=&mmEnt->memAddr[address&(MEMMAP_ES-1)];
p=(uint8_t*)MMAP_RAM_PTR(mmEnt, address);
*p=value;
} else {
mmEnt->cb(address, value, 1);
@ -231,9 +400,10 @@ void m68k_write_memory_8(unsigned int address, unsigned int value) {
void m68k_write_memory_16(unsigned int address, unsigned int value) {
const MemmapEnt *mmEnt=getMmmapEnt(address);
if ((address&1)!=0) printf("%s: Unaligned access to %x!\n", __FUNCTION__, address);
if (mmEnt->memAddr) {
uint16_t *p;
p=&mmEnt->memAddr[address&(MEMMAP_ES-1)];
p=(uint16_t*)MMAP_RAM_PTR(mmEnt, address);
*p=__bswap_16(value);
} else {
mmEnt->cb(address, (value>>8)&0xff, 1);
@ -241,12 +411,13 @@ void m68k_write_memory_16(unsigned int address, unsigned int value) {
}
}
#if 0
void m68k_write_memory_32(unsigned int address, unsigned int value) {
const MemmapEnt *mmEnt=getMmmapEnt(address);
if ((address&3)!=0) printf("%s: Unaligned access to %x!\n", __FUNCTION__, address);
if (mmEnt->memAddr) {
uint32_t *p;
p=&mmEnt->memAddr[address&(MEMMAP_ES-1)];
p=(uint32_t*)MMAP_RAM_PTR(mmEnt, address);
*p=__bswap_32(value);
} else {
mmEnt->cb(address, (value>>24)&0xff, 1);
@ -255,7 +426,12 @@ void m68k_write_memory_32(unsigned int address, unsigned int value) {
mmEnt->cb(address+3, (value>>0)&0xff, 1);
}
}
#else
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);
}
#endif
//Should be called every second.
void printFps() {
@ -272,13 +448,11 @@ void printFps() {
oldtv.tv_usec=tv.tv_usec;
}
void tmeStartEmu(void *ram, void *rom) {
void tmeStartEmu(void *rom) {
int ca1=0, ca2=0;
int x, m=0, frame=0;
macRom=rom;
macRam=ram;
printf("Clearing ram...\n");
for (int x=0; x<TME_RAMSIZE; x++) macRam[x]=0;
ramInit();
rom_remap=1;
regenMemmap(1);
printf("Creating HD and registering it...\n");
@ -312,7 +486,7 @@ void tmeStartEmu(void *ram, void *rom) {
m=0;
}
}
dispDraw(&macRam[video_remap?TME_SCREENBUF_ALT:TME_SCREENBUF]);
dispDraw(macFb[video_remap?1:0]);
frame++;
ca1^=1;
viaControlWrite(VIA_CA1, ca1);

View File

@ -1,4 +1,4 @@
void tmeStartEmu(void *rom, void *ram);
void tmeStartEmu(void *rom);
void tmeMouseMovement(int dx, int dy, int btn);

View File

@ -23,6 +23,5 @@ static void *loadRom(char *file) {
int main(int argc, char **argv) {
void *rom=loadRom("rom.bin");
void *ram=malloc(TME_RAMSIZE);
tmeStartEmu(ram, rom);
tmeStartEmu(rom);
}

View File

@ -1,18 +1,30 @@
#include <sdkconfig.h>
#define TME_ROMSIZE (128*1024)
#define TME_MAC128K
#ifdef CONFIG_SPIRAM_SUPPORT
#ifndef TME_MAC128K
#if 1
//Emulate an 4MiB MacPlus
#define TME_CACHESIZE (96*1024)
#define TME_RAMSIZE (4*1024*1024)
#define TME_SCREENBUF 0x3FA700
#define TME_SCREENBUF_ALT 0x3F2700
#define TME_RAMSIZE (1024*1024)
#define TME_SCREENBUF (TME_RAMSIZE-0x5900)
#define TME_SCREENBUF_ALT (TME_RAMSIZE-0xD900)
#else
//Emulate a 512K MacPlus
#define TME_RAMSIZE (512*1024)
#define TME_SCREENBUF 0x7A700
#define TME_SCREENBUF_ALT 0x72700
#endif
#else
//Emulate a 128KiB MacPlus/Mac128K hybrid
#define TME_CACHESIZE 0
#define TME_RAMSIZE (128*1024)
#define TME_SCREENBUF 0x1A700
#define TME_SCREENBUF_ALT 0x12700

View File

@ -19,6 +19,7 @@ CONFIG_LOG_BOOTLOADER_LEVEL_INFO=y
# CONFIG_LOG_BOOTLOADER_LEVEL_DEBUG is not set
# CONFIG_LOG_BOOTLOADER_LEVEL_VERBOSE is not set
CONFIG_LOG_BOOTLOADER_LEVEL=3
CONFIG_BOOTLOADER_SPI_WP_PIN=7
# CONFIG_BOOTLOADER_LTO is not set
#
@ -39,22 +40,22 @@ CONFIG_ESPTOOLPY_BAUD_921600B=y
CONFIG_ESPTOOLPY_BAUD_OTHER_VAL=115200
CONFIG_ESPTOOLPY_BAUD=921600
CONFIG_ESPTOOLPY_COMPRESSED=y
# CONFIG_FLASHMODE_QIO is not set
CONFIG_FLASHMODE_QIO=y
# CONFIG_FLASHMODE_QOUT is not set
CONFIG_FLASHMODE_DIO=y
# CONFIG_FLASHMODE_DIO is not set
# CONFIG_FLASHMODE_DOUT is not set
CONFIG_ESPTOOLPY_FLASHMODE="dio"
# CONFIG_ESPTOOLPY_FLASHFREQ_80M is not set
CONFIG_ESPTOOLPY_FLASHFREQ_40M=y
CONFIG_ESPTOOLPY_FLASHFREQ_80M=y
# CONFIG_ESPTOOLPY_FLASHFREQ_40M is not set
# CONFIG_ESPTOOLPY_FLASHFREQ_26M is not set
# CONFIG_ESPTOOLPY_FLASHFREQ_20M is not set
CONFIG_ESPTOOLPY_FLASHFREQ="40m"
CONFIG_ESPTOOLPY_FLASHFREQ="80m"
# CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set
CONFIG_ESPTOOLPY_FLASHSIZE_2MB=y
# CONFIG_ESPTOOLPY_FLASHSIZE_4MB is not set
# CONFIG_ESPTOOLPY_FLASHSIZE_2MB is not set
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
# CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set
# CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set
CONFIG_ESPTOOLPY_FLASHSIZE="2MB"
CONFIG_ESPTOOLPY_FLASHSIZE="4MB"
CONFIG_ESPTOOLPY_FLASHSIZE_DETECT=y
CONFIG_ESPTOOLPY_BEFORE_RESET=y
# CONFIG_ESPTOOLPY_BEFORE_NORESET is not set
@ -118,7 +119,16 @@ CONFIG_BT_RESERVE_DRAM=0
CONFIG_ESP32_DEFAULT_CPU_FREQ_240=y
CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ=240
CONFIG_MEMMAP_SMP=y
# CONFIG_SPIRAM_SUPPORT is not set
CONFIG_SPIRAM_SUPPORT=y
#
# SPI SRAM config
#
CONFIG_SPIRAM_USE_SPITRANSFER=y
CONFIG_MEMMAP_SPIRAM_TYPE_ESPPSRAM32=y
CONFIG_SPIRAM_SIZE=4194304
CONFIG_SPIRAM_SPEED_40M=y
# CONFIG_SPIRAM_SPEED_80M is not set
# CONFIG_MEMMAP_TRACEMEM is not set
# CONFIG_MEMMAP_TRACEMEM_TWOBANKS is not set
# CONFIG_ESP32_TRAX is not set