headless zx working

pull/15/head
virgesmith 2022-05-12 22:01:47 +01:00
rodzic 464a0e5d3a
commit b96f70bfa0
6 zmienionych plików z 176 dodań i 145 usunięć

4
.gitignore vendored 100644
Wyświetl plik

@ -0,0 +1,4 @@
build
pico-sdk*
spectrum-roms*
*.inl

Wyświetl plik

@ -23,8 +23,8 @@ include_directories(tft_t)
include_directories(psram)
set(PICO81_SOURCES
pico81/Z80.c
set(PICO81_SOURCES
pico81/Z80.c
pico81/AY8910.c
pico81/zx81.c
pico81/emuapi.cpp
@ -32,8 +32,8 @@ set(PICO81_SOURCES
pico81/AudioPlaySystem.cpp
)
set(PICOSPECCY_SOURCES
picospeccy/Z80.c
set(PICOSPECCY_SOURCES
picospeccy/Z80.c
picospeccy/AY8910.c
picospeccy/spec.c
picospeccy/zx_filetyp_z80.c
@ -42,8 +42,8 @@ set(PICOSPECCY_SOURCES
picospeccy/AudioPlaySystem.cpp
)
set(PICO800_SOURCES
pico800/antic.c
set(PICO800_SOURCES
pico800/antic.c
pico800/atari800.c
pico800/cpu.c
pico800/crc32.c
@ -57,8 +57,8 @@ set(PICO800_SOURCES
pico800/pico800.cpp
)
set(PICO5200_SOURCES
pico5200/antic.c
set(PICO5200_SOURCES
pico5200/antic.c
pico5200/atari5200.c
pico5200/cpu.c
pico5200/crc32.c
@ -70,7 +70,7 @@ set(PICO5200_SOURCES
pico5200/pico5200.cpp
)
set(PICO20_SOURCES
set(PICO20_SOURCES
pico20/IC.cpp
# pico20/MOS6502.cpp
# pico20/Register8.cpp
@ -86,8 +86,8 @@ set(PICO20_SOURCES
pico20/pico20.cpp
)
set(PICO64_SOURCES
pico64/c64.cpp
set(PICO64_SOURCES
pico64/c64.cpp
pico64/cia1.cpp
pico64/cia2.cpp
pico64/cpu.cpp
@ -103,8 +103,8 @@ set(PICO64_SOURCES
pico64/pico64.cpp
)
set(PICOCOLEM_SOURCES
picocolem/Z80.c
set(PICOCOLEM_SOURCES
picocolem/Z80.c
picocolem/SN76489.c
picocolem/Colem.c
picocolem/emuapi.cpp
@ -112,8 +112,8 @@ set(PICOCOLEM_SOURCES
picocolem/AudioPlaySystem.cpp
)
set(PICOO2EM_SOURCES
picoo2em/audio.c
set(PICOO2EM_SOURCES
picoo2em/audio.c
picoo2em/cpu.c
picoo2em/crc32.c
picoo2em/cset.c
@ -128,8 +128,8 @@ set(PICOO2EM_SOURCES
picoo2em/AudioPlaySystem.cpp
)
set(PICOVCS_SOURCES
picovcs/At2600.c
set(PICOVCS_SOURCES
picovcs/At2600.c
picovcs/Collision.c
picovcs/Cpu.c
picovcs/Display.c
@ -147,8 +147,8 @@ set(PICOVCS_SOURCES
picovcs/AudioPlaySystem.cpp
)
set(PICONOFRENDO_SOURCES
piconofrendo/bitmap.c
set(PICONOFRENDO_SOURCES
piconofrendo/bitmap.c
piconofrendo/config.c
piconofrendo/event.c
piconofrendo/log.c
@ -211,8 +211,8 @@ set(PICONOFRENDO_SOURCES
piconofrendo/AudioPlaySystem.cpp
)
set(PICO8086_SOURCES
pico8086/cpu.cpp
set(PICO8086_SOURCES
pico8086/cpu.cpp
pico8086/disk.cpp
pico8086/network.cpp
pico8086/ports.cpp
@ -224,7 +224,7 @@ set(PICO8086_SOURCES
pico8086/AudioPlaySystem.cpp
)
set(PICOSND_SOURCES
set(PICOSND_SOURCES
# picosnd/LibFC14/Dump.cpp
# picosnd/LibFC14/FC_Data.cpp
# picosnd/LibFC14/FC.cpp
@ -246,8 +246,8 @@ set(PICOSND_SOURCES
picosnd/picosnd.cpp
)
set(PICOVALIDATION_SOURCES
picovalidation/c64.cpp
set(PICOVALIDATION_SOURCES
picovalidation/c64.cpp
picovalidation/cia1.cpp
picovalidation/cia2.cpp
picovalidation/cpu.cpp
@ -263,44 +263,44 @@ set(PICOVALIDATION_SOURCES
picovalidation/pico64.cpp
)
set(VGA_T4_SOURCES
set(VGA_T4_SOURCES
vga_t4/VGA_t4.cpp
vga_t4/scanvideo.c
)
set(PICOVGA_T4_SOURCES
set(PICOVGA_T4_SOURCES
picovga_t4/VGA_t4.cpp
picovga_t4/vga.cpp
picovga_t4/vga_vmode.cpp
)
set(PSRAM_SOURCES
set(PSRAM_SOURCES
psram/psram_t.cpp
)
set(TFT_T_SOURCES
set(TFT_T_SOURCES
tft_t/tft_t_dma.cpp
)
set(GFXENGINE_SOURCES
set(GFXENGINE_SOURCES
gfxengine/gfxengine.cpp
)
set(TESTIO_SOURCES
set(TESTIO_SOURCES
testio/testio.cpp
testio/emuapi.cpp
)
set(TESTVGA_SOURCES
set(TESTVGA_SOURCES
testvga/testvga.cpp
)
set(TESTKEYMAX_SOURCES
set(TESTKEYMAX_SOURCES
testkeymax/testkeymax.cpp
testkeymax/emuapi.cpp
)
set(TESTPSRAM_SOURCES
set(TESTPSRAM_SOURCES
testpsram/testpsram.cpp
testpsram/emuapi.cpp
)
@ -311,7 +311,7 @@ set(TESTPSRAM_SOURCES
add_executable(mcume
# ${GFXENGINE_SOURCES}
# ${PICO20_SOURCES}
${PICO64_SOURCES}
# ${PICO64_SOURCES}
# ${PICO81_SOURCES}
# ${PICO800_SOURCES}
# ${PICO5200_SOURCES}
@ -319,7 +319,7 @@ add_executable(mcume
# ${PICOCOLEM_SOURCES}
# ${PICOO2EM_SOURCES}
# ${PICOVCS_SOURCES}
# ${PICOSPECCY_SOURCES}
${PICOSPECCY_SOURCES}
# ${PICONOFRENDO_SOURCES}
# ${PICOSND_SOURCES}
# ${TESTIO_SOURCES}
@ -329,7 +329,7 @@ add_executable(mcume
# ${PICOVALIDATION_SOURCES}
# ${PSRAM_SOURCES}
# ${VGA_T4_SOURCES}
${PICOVGA_T4_SOURCES}
# ${PICOVGA_T4_SOURCES}
${TFT_T_SOURCES}
)
@ -344,7 +344,7 @@ target_link_libraries(mcume pico_multicore
# pico_scanvideo_dpi
hardware_adc
hardware_pio
hardware_pwm
hardware_pwm
)

Wyświetl plik

@ -1,21 +1,21 @@
#ifndef _PLATFORM_CONFIG_H_
#define _PLATFORM_CONFIG_H_
// MCUME_REV2 is new layout with VGA+TFT+AnalogJoy+3buttons+Sound
// MCUME_REV1 had only support for VGA+AnalogJoy+3buttons+Sound
// PICOMPUTER has support for TFT+keymatrix+Sound
// MCUME_REV2 is new layout with VGA+TFT+AnalogJoy+3buttons+Sound
// MCUME_REV1 had only support for VGA+AnalogJoy+3buttons+Sound
// PICOMPUTER has support for TFT+keymatrix+Sound
//#define PICOMPUTER 1
#define PICOMPUTER 1
//#define PICOMPUTERMAX 1
//#define PICORETROVGA 1
//#define MCUME_REV1 1
#define MCUME_REV2 1
//#define MCUME_REV2 1
#ifdef PICOMPUTER
//#define SWAP_ALT_DEL 1
#define ST7789 1
#define LOHRES 1
//#define LOHRES 1
#define FLIP_SCREEN 1
#define INVX 1
#define HAS_SND 1

Wyświetl plik

@ -2,8 +2,8 @@
#include "pico/stdlib.h"
extern "C" {
#include "iopins.h"
#include "emuapi.h"
#include "iopins.h"
#include "emuapi.h"
}
#include "keyboard_osd.h"
@ -21,12 +21,12 @@ volatile bool vbl=true;
bool repeating_timer_callback(struct repeating_timer *t) {
uint16_t bClick = emu_DebounceLocalKeys();
emu_Input(bClick);
emu_Input(bClick);
if (vbl) {
vbl = false;
} else {
vbl = true;
}
}
return true;
}
TFT_T_DMA tft;
@ -38,40 +38,50 @@ static int skip=0;
int main(void) {
// vreg_set_voltage(VREG_VOLTAGE_1_05);
// set_sys_clock_khz(125000, true);
// set_sys_clock_khz(150000, true);
// set_sys_clock_khz(133000, true);
// set_sys_clock_khz(200000, true);
// set_sys_clock_khz(210000, true);
set_sys_clock_khz(230000, true);
// set_sys_clock_khz(225000, true);
// set_sys_clock_khz(250000, true);
// set_sys_clock_khz(125000, true);
// set_sys_clock_khz(150000, true);
// set_sys_clock_khz(133000, true);
// set_sys_clock_khz(200000, true);
// set_sys_clock_khz(210000, true);
set_sys_clock_khz(230000, true);
// set_sys_clock_khz(225000, true);
// set_sys_clock_khz(250000, true);
stdio_init_all();
#ifdef USE_VGA
#ifdef USE_VGA
tft.begin(VGA_MODE_320x240);
#else
tft.begin();
#endif
emu_init();
// in adbsence of keyboard/sd card load the default rom
toggleMenu(false);
emu_start();
emu_Init(nullptr);
tft.fillScreenNoDma( RGBVAL16(0x00,0x00,0x00) );
tft.startDMA();
struct repeating_timer timer;
add_repeating_timer_ms(5, repeating_timer_callback, NULL, &timer);
while (true) {
if (menuActive()) {
uint16_t bClick = emu_DebounceLocalKeys();
int action = handleMenu(bClick);
char * filename = menuSelection();
char * filename = menuSelection();
if (action == ACTION_RUNTFT) {
toggleMenu(false);
emu_start();
emu_Init(filename);
emu_start();
emu_Init(filename);
tft.fillScreenNoDma( RGBVAL16(0x00,0x00,0x00) );
tft.startDMA();
tft.startDMA();
struct repeating_timer timer;
add_repeating_timer_ms(5, repeating_timer_callback, NULL, &timer);
}
add_repeating_timer_ms(5, repeating_timer_callback, NULL, &timer);
}
tft.waitSync();
}
else {
emu_Step();
else {
emu_Step();
}
//int c = getchar_timeout_us(0);
//switch (c) {
@ -89,7 +99,7 @@ void emu_SetPaletteEntry(unsigned char r, unsigned char g, unsigned char b, int
{
if (index<PALETTE_SIZE) {
palette8[index] = RGBVAL8(r,g,b);
palette16[index] = RGBVAL16(r,g,b);
palette16[index] = RGBVAL16(r,g,b);
}
}
@ -97,54 +107,54 @@ void emu_DrawVsync(void)
{
skip += 1;
skip &= VID_FRAME_SKIP;
volatile bool vb=vbl;
volatile bool vb=vbl;
while (vbl==vb) {};
#ifdef USE_VGA
// tft.waitSync();
#else
// volatile bool vb=vbl;
#ifdef USE_VGA
// tft.waitSync();
#else
// volatile bool vb=vbl;
// while (vbl==vb) {};
#endif
}
void emu_DrawLine(unsigned char * VBuf, int width, int height, int line)
void emu_DrawLine(unsigned char * VBuf, int width, int height, int line)
{
if (skip == 0) {
#ifdef USE_VGA
#ifdef USE_VGA
tft.writeLine(width,height,line, VBuf, palette8);
#else
tft.writeLine(width,height,line, VBuf, palette16);
#endif
}
}
#endif
}
}
void emu_DrawLine8(unsigned char * VBuf, int width, int height, int line)
void emu_DrawLine8(unsigned char * VBuf, int width, int height, int line)
{
if (skip == 0) {
#ifdef USE_VGA
#ifdef USE_VGA
tft.writeLine(width,height,line, VBuf);
#endif
#endif
}
}
}
void emu_DrawLine16(unsigned short * VBuf, int width, int height, int line)
void emu_DrawLine16(unsigned short * VBuf, int width, int height, int line)
{
if (skip == 0) {
#ifdef USE_VGA
#ifdef USE_VGA
tft.writeLine16(width,height,line, VBuf);
#endif
#endif
}
}
}
void emu_DrawScreen(unsigned char * VBuf, int width, int height, int stride)
void emu_DrawScreen(unsigned char * VBuf, int width, int height, int stride)
{
if (skip == 0) {
#ifdef USE_VGA
#ifdef USE_VGA
tft.writeScreen(width,height-TFT_VBUFFER_YCROP,stride, VBuf+(TFT_VBUFFER_YCROP/2)*stride, palette8);
#endif
}
}
}
int emu_FrameSkip(void)
{
@ -153,7 +163,7 @@ int emu_FrameSkip(void)
void * emu_LineBuffer(int line)
{
return (void*)tft.getLineBuffer(line);
return (void*)tft.getLineBuffer(line);
}
@ -161,25 +171,25 @@ void * emu_LineBuffer(int line)
#include "AudioPlaySystem.h"
AudioPlaySystem mymixer;
#include "hardware/pwm.h"
void emu_sndInit() {
void emu_sndInit() {
tft.begin_audio(256, mymixer.snd_Mixer);
mymixer.start();
//gpio_init(AUDIO_PIN);
//gpio_set_dir(AUDIO_PIN, GPIO_OUT);
//gpio_set_dir(AUDIO_PIN, GPIO_OUT);
}
void emu_sndPlaySound(int chan, int volume, int freq)
{
if (chan < 6) {
mymixer.sound(chan, freq, volume);
mymixer.sound(chan, freq, volume);
}
}
void emu_sndPlayBuzz(int size, int val) {
#ifndef CUSTOM_SND
#ifndef CUSTOM_SND
//gpio_put(AUDIO_PIN, (val?1:0));
pwm_set_gpio_level(AUDIO_PIN, (val?255:128));
#endif
#endif
}
#endif

Wyświetl plik

@ -88,7 +88,7 @@ static byte kempston_ram; // Kempston-Joystick Buffer
static int v_border=0;
static int h_border=32;
static int bordercolor=0;
static byte * XBuf=0;
static byte * XBuf=0;
static int ik;
static int ihk;
@ -111,12 +111,12 @@ void displayscanline(int y, int f_flash)
dir_p = ((y & 0xC0) << 5) + ((y & 0x07) << 8) + ((y & 0x38) << 2);
dir_a = 0x1800 + (32 * (y >> 3));
for (x = 0; x < 32; x++)
{
pixeles= VRAM[dir_p++];
atributos=VRAM[dir_a++];
if (((atributos & 0x80) == 0) || (f_flash == 0))
{
tinta = (atributos & 0x07) + ((atributos & 0x40) >> 3);
@ -140,12 +140,12 @@ void displayscanline(int y, int f_flash)
for (x = 0; x < h_border; x++) {
XBuf[col++] = bordercolor;
}
emu_DrawLine(XBuf, WIDTH, HEIGHT, y);
}
#ifdef HAS_SND
#ifdef CUSTOM_SND
#ifdef CUSTOM_SND
#define SAMSIZE 32768
static unsigned char sam[SAMSIZE];
static int rdsam=0;
@ -157,7 +157,7 @@ static int lastBuzzCycle=0;
static byte lastBuzzVal;
#ifdef HAS_SND
#ifdef CUSTOM_SND
#ifdef CUSTOM_SND
void SND_Process( short * stream, int len )
{
len = len >> 1;
@ -168,10 +168,10 @@ void SND_Process( short * stream, int len )
rdsam &= SAMSIZE-1;
*stream++ = (short)(s);
*stream++ = (short)(s);
}
}
}
#endif
#endif
#endif
static void displayScreen(void) {
int y;
@ -181,43 +181,43 @@ static void displayScreen(void) {
f_flash = 1;
else
f_flash = 0;
for (y = 0; y < HEIGHT; y++)
displayscanline (y, f_flash);
emu_DrawVsync();
emu_DrawVsync();
}
static void InitKeyboard(void){
memset(key_ram, 0xff, sizeof(key_ram));
memset(key_ram, 0xff, sizeof(key_ram));
}
static void UpdateKeyboard (void)
{
//int k = ik; //emu_GetPad();
int hk = ihk; //emu_ReadI2CKeyboard();
int hk = ihk; //emu_ReadI2CKeyboard();
//if ( hk == 0 ) {
memset(key_ram, 0xff, sizeof(key_ram));
memset(key_ram, 0xff, sizeof(key_ram));
//}
//else
//else
{
//if (k & MASK_KEY_USER1) hk = 39;
int shift = hk;
if (hk >=128) hk -= 128;
else if (hk >=64) hk -= 64;
else if (hk >=64) hk -= 64;
// scan all possibilities
for (int j=0;j<8;j++) {
for(int i=0;i<5;i++){
if ( /*(k == map_qw[j][i]) ||*/ (hk == map_qw[j][i]) ) {
key_ram[j] &= ~ (1<<(4-i));
}
}
}
if (shift >=128) key_ram[0] &= ~ (1<<0); // SHift
else if (shift >=64) key_ram[7] &= ~ (1<<1); // SHift symboles
}
}
}
}
if (shift >=128) key_ram[0] &= ~ (1<<0); // SHift
else if (shift >=64) key_ram[7] &= ~ (1<<1); // SHift symboles
}
}
@ -234,7 +234,7 @@ int endsWith(const char * s, const char * suffix)
retval = 1;
}
}
return (retval);
return (retval);
}
@ -245,19 +245,25 @@ void emu_KeyboardOnUp(int keymodifer, int key) {
}
void spec_Start(char * filename) {
if (!filename) {
#include "zxspectrum48rom.inl" // defines
ZX_ReadFromFlash_Z80(&myCPU, zxspectrum48rom, sizeof(zxspectrum48_rom) / sizeof(unsigned char));
}
memset(Z80_RAM, 0, 0xC000);
if ( (endsWith(filename, "SNA")) || (endsWith(filename, "sna")) ) {
ZX_ReadFromFlash_SNA(&myCPU, filename);
}
ZX_ReadFromFlash_SNA(&myCPU, filename);
}
else if ( (endsWith(filename, "Z80")) || (endsWith(filename, "z80")) ) {
unsigned char * game = emu_Malloc(MAX_Z80SIZE);
int size = emu_LoadFile(filename, game, MAX_Z80SIZE);
ZX_ReadFromFlash_Z80(&myCPU, game,size);
emu_Free(game);
int size = emu_LoadFile(filename, game, MAX_Z80SIZE);
ZX_ReadFromFlash_Z80(&myCPU, game,size);
emu_Free(game);
}
#ifdef HAS_SND
emu_sndInit();
#endif
emu_sndInit();
#endif
}
@ -269,21 +275,21 @@ void spec_Init(void) {
/* Set up the palette */
for(J=0;J<16;J++)
emu_SetPaletteEntry(Palette[J].R,Palette[J].G,Palette[J].B, J);
InitKeyboard();
Reset8910(&ay,3500000,0);
if (XBuf == 0) XBuf = (byte *)emu_Malloc(WIDTH);
VRAM = Z80_RAM;
memset(Z80_RAM, 0, sizeof(Z80_RAM));
ResetZ80(&myCPU, CYCLES_PER_FRAME);
#if ALT_Z80CORE
myCPU.RAM = Z80_RAM;
#if ALT_Z80CORE
myCPU.RAM = Z80_RAM;
Z80FlagTables();
#endif
#endif
}
#include "emuapi.h"
@ -294,10 +300,10 @@ void spec_Step(void) {
lastBuzzCycle=0;
ExecZ80(&myCPU,CYCLES_PER_STEP); // 3.5MHz ticks for 6 lines @ 30 kHz = 700 cycles
#ifdef HAS_SND
#ifdef CUSTOM_SND
#ifdef CUSTOM_SND
buzz(lastBuzzVal, CYCLES_PER_STEP);
#endif
#endif
#endif
//busy_wait_us(1);
//sleep_us(1);
}
@ -310,7 +316,7 @@ void spec_Step(void) {
displayScreen();
int k=ik; //emu_GetPad();
kempston_ram = 0x00;
if (k & MASK_JOY2_BTN)
kempston_ram |= 0x10; //Fire
@ -325,7 +331,7 @@ void spec_Step(void) {
UpdateKeyboard();
Loop8910(&ay,20);
}
@ -342,7 +348,7 @@ void WrZ80(register word Addr,register byte Value)
byte RdZ80(register word Addr)
{
if (Addr<BASERAM)
if (Addr<BASERAM)
return rom_zx48_rom[Addr];
else
return Z80_RAM[Addr-BASERAM];
@ -354,29 +360,29 @@ void buzz(int val, int currentTstates)
{
int pulse_size = (currentTstates-lastBuzzCycle);
#ifdef HAS_SND
#ifdef CUSTOM_SND
#ifdef CUSTOM_SND
for (int i = 0; i<pulse_size; i++ ) {
sam[wrsam] = lastBuzzVal?0:1;
wrsam += 1;
wrsam &= SAMSIZE-1;
}
}
lastBuzzCycle = currentTstates;
lastBuzzVal = val;
lastBuzzVal = val;
#else
emu_sndPlayBuzz(pulse_size,val);
#endif
#endif
#endif
}
void OutZ80(register word Port,register byte Value)
{
if ((Port & 0xC002) == 0xC000) {
WrCtrl8910(&ay,(Value &0x0F));
}
}
else if ((Port & 0xC002) == 0x8000) {
WrData8910(&ay,Value);
}
}
else if (!(Port & 0x01)) {
bordercolor = (Value & 0x07);
byte mic = (Value & 0x08);
@ -389,11 +395,11 @@ void OutZ80(register word Port,register byte Value)
}
byte InZ80(register word port)
{
{
if (port == 0xFFFD) {
return (RdData8910(&ay));
}
if((port&0xFF)==0x1F) {
// kempston RAM
return kempston_ram;
@ -410,18 +416,18 @@ byte InZ80(register word port)
case 0xBF : return key_ram[6]; break;
case 0x7F : return key_ram[7]; break;
}
}
}
if ((port & 0xFF) == 0xFF) {
if ((port & 0xFF) == 0xFF) {
if (hwopt.port_ff == 0xFF) {
return 0xFF;
return 0xFF;
}
else {
//code = 1;
//if (code == 0xFF) code = 0x00;
return 1;
}
}
}
return 0xFF;
}

11
rom2c.py 100644
Wyświetl plik

@ -0,0 +1,11 @@
# loads a zx rom and dumps it into a C array
rom_file = "spectrum-roms/48.rom"
name = "zxspectrum48rom"
code_file = f"MCUME_pico/picospeccy/{name}.inl"
with open(rom_file, "rb") as ifd, open(code_file, "w") as ofd:
rom = [str(b) for b in ifd.read()]
#print(int.from_bytes(rom[0], "little"))
ofd.write(f"unsigned char {name}[] = {{{','.join(rom)}}};\n")