- Enorme reestructuració del codi per a que el fluxe comence a ser mes racional
- [NEW] mòdul zx_system per a gestionar la vida i canvi de systemes (48K, 128K...)
This commit is contained in:
@@ -19,8 +19,7 @@
|
||||
|
||||
namespace audio
|
||||
{
|
||||
#define SAMPLING_FREQ 44100
|
||||
#define AUDIO_BUFFER_SIZE 2048
|
||||
bool enabled = false;
|
||||
float cycles_per_sample;
|
||||
|
||||
uint8_t volume_table[16] {0,2,3,4,6,8,11,16,23,32,45,64,90,128,180,255};
|
||||
@@ -122,12 +121,14 @@ namespace audio
|
||||
|
||||
void reset()
|
||||
{
|
||||
enabled = true;
|
||||
selected_register = 0;
|
||||
for (int i=0; i<16;++i) registers[i]=0;
|
||||
}
|
||||
|
||||
void update(uint32_t dt)
|
||||
{
|
||||
if (!enabled) return;
|
||||
//dt = dt >> 1;
|
||||
|
||||
// Oscillate (0-1) channel A tone level given its frequency
|
||||
|
||||
118
main.cpp
118
main.cpp
@@ -1,5 +1,6 @@
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include "zx_system.h"
|
||||
#include "z80.h"
|
||||
#include "z80dis.h"
|
||||
#include "z80debug.h"
|
||||
@@ -14,8 +15,6 @@
|
||||
#include "z80analyze.h"
|
||||
#include "ui_window.h"
|
||||
#include "zx_mem.h"
|
||||
//#include "zx_48mem.h"
|
||||
//#include "zx_128mem.h"
|
||||
#include "z80viewer.h"
|
||||
//#include "zx_128bankviewer.h"
|
||||
//#include "zx_128pageviewer.h"
|
||||
@@ -23,7 +22,6 @@
|
||||
#include "ay_viewer.h"
|
||||
#include "file.h"
|
||||
|
||||
//uint8_t memory[65536];
|
||||
uint32_t time = 0;
|
||||
uint32_t t_states = 0;
|
||||
|
||||
@@ -77,43 +75,34 @@ namespace actions
|
||||
z80analyze::show();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mode48K(int value)
|
||||
{
|
||||
zx_system::reset(ZX_48K);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mode128K(int value)
|
||||
{
|
||||
zx_system::reset(ZX_128K);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int reset(int value)
|
||||
{
|
||||
z80::reset();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int exit(int value)
|
||||
{
|
||||
zx_system::shutdown();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
void init_menu()
|
||||
{
|
||||
//const uint32_t clock = 3500000;
|
||||
const uint32_t clock = 3546900;
|
||||
const uint32_t update_freq = clock / 10;
|
||||
|
||||
file::setConfigFolder("z80");
|
||||
|
||||
//new zx_48mem();
|
||||
//new zx_128mem();
|
||||
mem::init(ZX_128K);
|
||||
|
||||
z80dis::loadSymbols();
|
||||
z80::setClock(clock);
|
||||
z80::reset();
|
||||
z80::connect_port(0xfe, 0x0001, zx_ula::port_in, zx_ula::port_out);
|
||||
audio::init();
|
||||
|
||||
SDL_Init(SDL_INIT_EVERYTHING);
|
||||
z80debug::init();
|
||||
//zxscreen::init(SCREEN_MODE_48K);
|
||||
zxscreen::init(SCREEN_MODE_128K);
|
||||
|
||||
//ay_viewer *v = new ay_viewer();
|
||||
//v->show();
|
||||
//z80viewer::registerViewer("AY", v);
|
||||
|
||||
//z80viewer *v = new zx_128bankviewer();
|
||||
//v->show();
|
||||
//z80viewer::registerViewer("128BANK", v);
|
||||
|
||||
//v = new zx_128pageviewer();
|
||||
//v->show();
|
||||
//z80viewer::registerViewer("128PAGE", v);
|
||||
|
||||
ui::menu::init();
|
||||
ui::menu::setexitcallback(actions::exitMenu);
|
||||
|
||||
@@ -123,6 +112,14 @@ int main(int argc, char *argv[])
|
||||
ui::menu::addseparator(menu);
|
||||
ui::menu::addoption(menu, "LOAD STATE", nullptr);
|
||||
ui::menu::addoption(menu, "SAVE STATE", nullptr);
|
||||
ui::menu::addseparator(menu);
|
||||
ui::menu::addoption(menu, "EXIT", actions::exit);
|
||||
|
||||
menu = ui::menu::addsubmenu("SYSTEM");
|
||||
ui::menu::addoption(menu, "ZX 48K", actions::mode48K);
|
||||
ui::menu::addoption(menu, "ZX 128K/+2", actions::mode128K);
|
||||
ui::menu::addseparator(menu);
|
||||
ui::menu::addoption(menu, "RESET", actions::reset);
|
||||
|
||||
menu = ui::menu::addsubmenu("TAPE");
|
||||
ui::menu::addbooloption(menu, "FAST LOAD", zx_tape::getOption(ZXTAPE_OPTION_FAST_LOAD), actions::fastload);
|
||||
@@ -138,30 +135,36 @@ int main(int argc, char *argv[])
|
||||
menu = ui::menu::addsubmenu("EMULATION");
|
||||
ui::menu::addbooloption(menu, "STOP ON INVALID OP", z80::getOption(Z80_OPTION_STOP_ON_INVALID), actions::decZoom);
|
||||
ui::menu::addoption(menu, "SHOW ANALYZER", actions::showAnalyzer);
|
||||
}
|
||||
|
||||
speaker::init();
|
||||
speaker::register_source(zx_ula::get_sample);
|
||||
speaker::register_source(audio::get_sample);
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
file::setConfigFolder("z80");
|
||||
SDL_Init(SDL_INIT_EVERYTHING);
|
||||
init_menu();
|
||||
z80debug::init();
|
||||
|
||||
//uint32_t update_freq =
|
||||
zx_system::init(ZX_48K);
|
||||
|
||||
zx_tape::load("ROBOCOP1.TAP");
|
||||
|
||||
if (argc==3) { z80debug::loadngo(argv[1], argv[2]); }
|
||||
//if (argc==3) { z80debug::loadngo(argv[1], argv[2]); }
|
||||
|
||||
z80debug::stop();
|
||||
//z80debug::stop();
|
||||
|
||||
bool should_exit = false;
|
||||
SDL_Event e;
|
||||
|
||||
time = SDL_GetTicks();
|
||||
t_states = 0;
|
||||
|
||||
while (!should_exit)
|
||||
while (!zx_system::shuttingDown())
|
||||
{
|
||||
while (SDL_PollEvent(&e))
|
||||
{
|
||||
bool result = true;
|
||||
|
||||
if (e.type == SDL_QUIT) { should_exit=true; break; }
|
||||
if (e.type == SDL_QUIT) { zx_system::shutdown(); break; }
|
||||
if (e.type == SDL_MOUSEBUTTONDOWN) result = ui::window::sendEvent(e.button.windowID, &e);
|
||||
if (e.type == SDL_MOUSEBUTTONUP) result = ui::window::sendEvent(e.button.windowID, &e);
|
||||
if (e.type == SDL_MOUSEMOTION) result = ui::window::sendEvent(e.motion.windowID, &e);
|
||||
@@ -224,10 +227,11 @@ int main(int argc, char *argv[])
|
||||
if (e.type == SDL_MOUSEBUTTONUP && e.button.button==1) ui::setClicked(true);
|
||||
|
||||
if (!result)
|
||||
should_exit = true; break;
|
||||
zx_system::shutdown(); break;
|
||||
}
|
||||
|
||||
if (!z80debug::debugging() && !z80debug::paused()) {
|
||||
/*
|
||||
//if (z80::getPC()==0x05C8) zx_tape::go_berserk();
|
||||
bool fastload=false;
|
||||
if (zx_tape::getplaying() && zx_tape::getOption(ZXTAPE_OPTION_FAST_LOAD)) { fastload=true; time = SDL_GetTicks(); }
|
||||
@@ -245,7 +249,9 @@ int main(int argc, char *argv[])
|
||||
//zxscreen::refresh(dt);
|
||||
}
|
||||
if (fastload) { printf("%i\n", SDL_GetTicks()-time); t_states=0; }
|
||||
// En cada bucle fem 10 pasos de la CPU, sino s'ofega
|
||||
*/
|
||||
|
||||
// En cada bucle fem 10 pasos de la CPU, sino s'ofega (jo en veig 5)
|
||||
for (int i=0;i<5;++i) {
|
||||
if (z80debug::isbreak(z80::getPC(), 9)) {
|
||||
z80debug::stop();
|
||||
@@ -254,23 +260,21 @@ int main(int argc, char *argv[])
|
||||
} else {
|
||||
uint8_t dt = z80::step();
|
||||
t_states += dt;
|
||||
zx_tape::update(dt);
|
||||
audio::update(dt);
|
||||
speaker::update(dt);
|
||||
zx_system::update(dt);
|
||||
//zx_tape::update(dt);
|
||||
//audio::update(dt);
|
||||
//speaker::update(dt);
|
||||
zxscreen::refresh(dt);
|
||||
if (z80debug::debugging()) break;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t update_freq = z80::getClock()/10;
|
||||
if (t_states>=update_freq)
|
||||
{
|
||||
//if (SDL_GetTicks()>=time+1000)
|
||||
//printf("%i\n", SDL_GetTicks()-(time+1000));
|
||||
//else
|
||||
// printf("%i\n", SDL_GetTicks()-(time+1000));
|
||||
//t_states = 0;
|
||||
//printf("%i: %i\n", SDL_GetTicks()-(time+1000), t_states);
|
||||
// Esperem a que es compleixca el temps corresponent als t states executats
|
||||
while (SDL_GetTicks()<time+100) {}
|
||||
|
||||
t_states -= update_freq;
|
||||
time = SDL_GetTicks();
|
||||
z80analyze::refresh();
|
||||
@@ -279,7 +283,7 @@ int main(int argc, char *argv[])
|
||||
z80analyze::refresh(true);
|
||||
|
||||
|
||||
} else if (!z80debug::debugging() && z80debug::paused()) {
|
||||
} else if (/*!z80debug::debugging() &&*/ z80debug::paused()) {
|
||||
zxscreen::redraw(false);
|
||||
ui::menu::show();
|
||||
zxscreen::present();
|
||||
|
||||
21
z80.cpp
21
z80.cpp
@@ -1150,22 +1150,27 @@ namespace z80
|
||||
if (options[Z80_OPTION_STOP_ON_INVALID]) z80debug::stop();
|
||||
}
|
||||
|
||||
void init(uint32_t freq)
|
||||
{
|
||||
setClock(freq);
|
||||
reset();
|
||||
clearPorts();
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
for (int i=0; i<256; ++i)
|
||||
{
|
||||
ports.clear();
|
||||
//in_ports[i] = nullptr;
|
||||
//out_ports[i] = nullptr;
|
||||
}
|
||||
|
||||
mem::reset();
|
||||
//mem::reset();
|
||||
|
||||
rPC = iff1 = iff2 = im = 0;
|
||||
rAF = rAF2 = rBC = rBC2 = rDE = rDE2 = rHL = rHL2 = rIX = rIY = rSP = 0xffff;
|
||||
t = 0;
|
||||
}
|
||||
|
||||
void clearPorts()
|
||||
{
|
||||
ports.clear();
|
||||
}
|
||||
|
||||
void setClock(uint32_t freq)
|
||||
{
|
||||
clock = freq;
|
||||
|
||||
2
z80.h
2
z80.h
@@ -9,7 +9,9 @@ namespace z80
|
||||
#define Z80_OPTION_BREAK_ON_RET 2
|
||||
#define Z80_NUM_OPTIONS 3
|
||||
|
||||
void init(uint32_t freq);
|
||||
void reset();
|
||||
void clearPorts();
|
||||
void setClock(uint32_t freq);
|
||||
uint32_t getClock();
|
||||
|
||||
|
||||
11
z80debug.cpp
11
z80debug.cpp
@@ -816,10 +816,13 @@ namespace z80debug
|
||||
|
||||
if (strcmp(cmd, "s")==0 || strcmp(cmd, "step")==0) {
|
||||
uint8_t dt = z80::step();
|
||||
zx_tape::update(dt);
|
||||
audio::update(dt);
|
||||
speaker::update(dt);
|
||||
|
||||
zx_system::update(dt);
|
||||
//zx_tape::update(dt);
|
||||
//audio::update(dt);
|
||||
//speaker::update(dt);
|
||||
zxscreen::fullrefresh();
|
||||
|
||||
z80analyze::refresh();
|
||||
} else if (strcmp(cmd, "c")==0 || strcmp(cmd, "cont")==0) {
|
||||
z80::step();
|
||||
@@ -827,7 +830,7 @@ namespace z80debug
|
||||
z80analyze::refresh();
|
||||
} else if (strcmp(cmd, "r")==0 || strcmp(cmd, "reset")==0) {
|
||||
z80::reset();
|
||||
z80::connect_port(0xfe, 0x0001, zx_ula::port_in, zx_ula::port_out);
|
||||
//z80::connect_port(0xfe, 0x0001, zx_ula::port_in, zx_ula::port_out);
|
||||
history::reset();
|
||||
z80debug::refresh();
|
||||
z80analyze::refresh();
|
||||
|
||||
@@ -25,14 +25,14 @@ namespace mem
|
||||
void init(uint8_t mode)
|
||||
{
|
||||
mem::mode = mode;
|
||||
if (ram) free(ram);
|
||||
if (rom) free(rom);
|
||||
|
||||
reset();
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
if (ram) free(ram);
|
||||
if (rom) free(rom);
|
||||
|
||||
FILE* f;
|
||||
switch(mode)
|
||||
{
|
||||
|
||||
6
zx_mem.h
6
zx_mem.h
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include "zx_system.h"
|
||||
|
||||
#define MEMTAG_NONE 0x00
|
||||
#define MEMTAG_DATA 0x01
|
||||
@@ -16,11 +17,6 @@
|
||||
#define MEMTAG_KNOWN 0x07
|
||||
#define MEMTAG_TOUCHED 0x70
|
||||
|
||||
#define ZX_48K 0x00
|
||||
#define ZX_128K 0x01
|
||||
#define ZX_2A_3 0x02
|
||||
#define ZX_NEXT 0x03
|
||||
|
||||
namespace mem
|
||||
{
|
||||
void init(uint8_t mode);
|
||||
|
||||
@@ -26,6 +26,7 @@ namespace zxscreen
|
||||
uint32_t t_states_total = 69888;
|
||||
uint32_t t_states_per_scanline = 224;
|
||||
uint32_t vsync_lines = 16;
|
||||
bool interrupt_enabled = true;
|
||||
|
||||
uint8_t zoom = 2;
|
||||
bool fullscreen = false;
|
||||
@@ -39,8 +40,6 @@ namespace zxscreen
|
||||
uint8_t t_flash = 0;
|
||||
bool flash = false;
|
||||
|
||||
int pixels_draw = 0;
|
||||
|
||||
uint32_t pixel_base_addr = 0x4000;
|
||||
uint32_t color_base_addr = 0x5800;
|
||||
|
||||
@@ -235,6 +234,9 @@ namespace zxscreen
|
||||
}
|
||||
|
||||
create_tables();
|
||||
ptr_pixel = zx_pixels;
|
||||
t_screen = t_flash = 0;
|
||||
flash = false;
|
||||
reinit();
|
||||
}
|
||||
|
||||
@@ -247,7 +249,7 @@ namespace zxscreen
|
||||
}
|
||||
}
|
||||
|
||||
void refresh(const uint32_t dt, const bool full)
|
||||
void refresh(const uint32_t dt)
|
||||
{
|
||||
const uint8_t* pixel_mem = mem::rawPtr(pixel_base_addr);
|
||||
const uint8_t* color_mem = mem::rawPtr(color_base_addr);
|
||||
@@ -272,17 +274,15 @@ namespace zxscreen
|
||||
mask>>=1;
|
||||
*(ptr_pixel++)=(block&mask) ? c1 : c2;
|
||||
}
|
||||
pixels_draw+=2;
|
||||
}
|
||||
t_screen++;
|
||||
if (t_screen>=t_states_total) {
|
||||
pixels_draw=0;
|
||||
t_flash++;
|
||||
if (t_flash==16) { t_flash=0; flash = !flash; }
|
||||
t_screen=0;
|
||||
ptr_pixel = zx_pixels;
|
||||
redraw();
|
||||
if (!full) z80::interrupt();
|
||||
if (interrupt_enabled) z80::interrupt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -293,7 +293,9 @@ namespace zxscreen
|
||||
t_screen = 0;
|
||||
uint8_t * tmp_ptr = ptr_pixel;
|
||||
ptr_pixel = zx_pixels;
|
||||
refresh(t_states_total, true);
|
||||
interrupt_enabled = false;
|
||||
refresh(t_states_total);
|
||||
interrupt_enabled = true;
|
||||
ptr_pixel = tmp_ptr;
|
||||
t_screen = tmp;
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace zxscreen
|
||||
void setBaseAddresses(const uint32_t pixeladdr, const uint32_t coloraddr);
|
||||
void reinit();
|
||||
void focus();
|
||||
void refresh(const uint32_t dt, const bool full=false);
|
||||
void refresh(const uint32_t dt);
|
||||
void fullrefresh();
|
||||
void debugrefresh();
|
||||
void redraw(const bool present=true);
|
||||
|
||||
@@ -5,24 +5,46 @@
|
||||
|
||||
namespace speaker
|
||||
{
|
||||
#define SAMPLING_FREQ 44100
|
||||
#define AUDIO_BUFFER_SIZE 2048
|
||||
SDL_AudioDeviceID sdlAudioDevice;
|
||||
uint8_t sound_buffer[AUDIO_BUFFER_SIZE];
|
||||
uint16_t sampling_freq = 44100;
|
||||
uint16_t audio_buffer_size = 2048;
|
||||
SDL_AudioDeviceID sdlAudioDevice = 0;
|
||||
uint8_t *sound_buffer = nullptr;
|
||||
uint16_t sound_pos=0;
|
||||
uint16_t t_sound=0;
|
||||
std::vector<uint8_t(*)()> sources;
|
||||
|
||||
float cycles_per_sample;
|
||||
|
||||
void init()
|
||||
void init(const uint16_t freq, const uint16_t buffer_size)
|
||||
{
|
||||
SDL_AudioSpec audioSpec{SAMPLING_FREQ, AUDIO_U8, 1, 0, AUDIO_BUFFER_SIZE>>2, 0, 0, NULL, NULL};
|
||||
if (sound_buffer || sdlAudioDevice) quit();
|
||||
|
||||
sampling_freq = freq;
|
||||
audio_buffer_size = buffer_size;
|
||||
|
||||
SDL_AudioSpec audioSpec{sampling_freq, AUDIO_U8, 1, 0, (uint16_t)(audio_buffer_size>>2), 0, 0, NULL, NULL};
|
||||
sdlAudioDevice = SDL_OpenAudioDevice(NULL, 0, &audioSpec, NULL, 0);
|
||||
cycles_per_sample = z80::getClock() / SAMPLING_FREQ;
|
||||
|
||||
cycles_per_sample = z80::getClock() / sampling_freq;
|
||||
sound_buffer = (uint8_t*)malloc(audio_buffer_size);
|
||||
|
||||
enable();
|
||||
}
|
||||
|
||||
void quit()
|
||||
{
|
||||
disable();
|
||||
sources.clear();
|
||||
if (sound_buffer) {
|
||||
free(sound_buffer);
|
||||
sound_buffer = nullptr;
|
||||
}
|
||||
if (sdlAudioDevice) {
|
||||
SDL_CloseAudioDevice(sdlAudioDevice);
|
||||
sdlAudioDevice = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void enable()
|
||||
{
|
||||
SDL_PauseAudioDevice(sdlAudioDevice, 0);
|
||||
@@ -38,7 +60,7 @@ namespace speaker
|
||||
sources.push_back(callback);
|
||||
}
|
||||
|
||||
void update(const uint8_t dt)
|
||||
void update(const uint32_t dt)
|
||||
{
|
||||
t_sound += dt;
|
||||
if (t_sound>=cycles_per_sample) {
|
||||
@@ -48,12 +70,12 @@ namespace speaker
|
||||
for (auto callback : sources) sample += callback();
|
||||
sample /= sources.size();
|
||||
|
||||
sound_buffer[(sound_pos++)&(AUDIO_BUFFER_SIZE-1)] = sample;
|
||||
sound_buffer[(sound_pos++)&(audio_buffer_size-1)] = sample;
|
||||
}
|
||||
if (sound_pos>=1000) {
|
||||
SDL_QueueAudio(sdlAudioDevice, sound_buffer, sound_pos);
|
||||
sound_pos = 0;
|
||||
while (SDL_GetQueuedAudioSize(sdlAudioDevice) > 4096 ) {}
|
||||
while (SDL_GetQueuedAudioSize(sdlAudioDevice) > (audio_buffer_size<<1) ) {}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,9 +3,10 @@
|
||||
|
||||
namespace speaker
|
||||
{
|
||||
void init();
|
||||
void init(const uint16_t freq = 44100, const uint16_t buffer_size = 2048);
|
||||
void quit();
|
||||
void enable();
|
||||
void disable();
|
||||
void register_source(uint8_t(*callback)());
|
||||
void update(const uint8_t dt);
|
||||
void update(const uint32_t dt);
|
||||
}
|
||||
|
||||
101
zx_system.cpp
Normal file
101
zx_system.cpp
Normal file
@@ -0,0 +1,101 @@
|
||||
#include "zx_system.h"
|
||||
#include "z80.h"
|
||||
#include "zx_mem.h"
|
||||
#include "zx_ula.h"
|
||||
#include "zx_screen.h"
|
||||
#include "zx_tape.h"
|
||||
#include "zx_speaker.h"
|
||||
#include "ay-3-8912.h"
|
||||
#include <vector>
|
||||
|
||||
namespace zx_system
|
||||
{
|
||||
bool resetting = true;
|
||||
bool shutting_down = false;
|
||||
uint8_t current_mode = ZX_48K;
|
||||
uint8_t new_mode = ZX_48K;
|
||||
std::vector<void(*)(uint32_t)> updatables;
|
||||
|
||||
int init(const uint8_t mode)
|
||||
{
|
||||
updatables.clear();
|
||||
z80::clearPorts();
|
||||
resetting = false;
|
||||
switch(mode)
|
||||
{
|
||||
case ZX_NOCHANGE:
|
||||
{
|
||||
z80::reset();
|
||||
break;
|
||||
|
||||
}
|
||||
case ZX_48K:
|
||||
{
|
||||
const uint32_t clock = 3500000;
|
||||
z80::init(clock);
|
||||
z80::connect_port(0xfe, 0x0001, zx_ula::port_in, zx_ula::port_out);
|
||||
mem::init(ZX_48K);
|
||||
zxscreen::init(SCREEN_MODE_48K);
|
||||
speaker::init();
|
||||
speaker::register_source(zx_ula::get_sample);
|
||||
|
||||
registerUpdatable(zx_tape::update);
|
||||
registerUpdatable(speaker::update);
|
||||
//registerUpdatable(zxscreen::refresh);
|
||||
|
||||
return clock / 10;
|
||||
break;
|
||||
}
|
||||
case ZX_128K:
|
||||
{
|
||||
const uint32_t clock = 3546900;
|
||||
z80::init(clock);
|
||||
z80::connect_port(0xfe, 0x0001, zx_ula::port_in, zx_ula::port_out);
|
||||
mem::init(ZX_128K);
|
||||
zxscreen::init(SCREEN_MODE_128K);
|
||||
audio::init();
|
||||
speaker::init();
|
||||
speaker::register_source(zx_ula::get_sample);
|
||||
speaker::register_source(audio::get_sample);
|
||||
|
||||
registerUpdatable(zx_tape::update);
|
||||
registerUpdatable(audio::update);
|
||||
registerUpdatable(speaker::update);
|
||||
//registerUpdatable(zxscreen::refresh);
|
||||
|
||||
return clock / 10;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void reset(const uint8_t mode)
|
||||
{
|
||||
new_mode = mode;
|
||||
resetting = true;
|
||||
}
|
||||
|
||||
void shutdown()
|
||||
{
|
||||
shutting_down = true;
|
||||
}
|
||||
|
||||
const bool shuttingDown()
|
||||
{
|
||||
if (resetting) init(new_mode);
|
||||
return shutting_down;
|
||||
}
|
||||
|
||||
void registerUpdatable(void(*callback)(uint32_t))
|
||||
{
|
||||
updatables.push_back(callback);
|
||||
}
|
||||
|
||||
void update(uint32_t dt)
|
||||
{
|
||||
for (auto& call : updatables) call(dt);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
19
zx_system.h
Normal file
19
zx_system.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
#define ZX_NOCHANGE 0x00
|
||||
#define ZX_48K 0x01
|
||||
#define ZX_128K 0x02
|
||||
#define ZX_2A_3 0x03
|
||||
#define ZX_NEXT 0x04
|
||||
|
||||
namespace zx_system
|
||||
{
|
||||
int init(const uint8_t mode);
|
||||
void reset(const uint8_t mode);
|
||||
void shutdown();
|
||||
const bool shuttingDown();
|
||||
|
||||
void registerUpdatable(void(*callback)(uint32_t));
|
||||
void update(uint32_t dt);
|
||||
}
|
||||
@@ -95,7 +95,7 @@ namespace zx_tape
|
||||
pulse_level = 1;
|
||||
}
|
||||
|
||||
void update(const uint8_t dt)
|
||||
void update(const uint32_t dt)
|
||||
{
|
||||
if (!playing) return;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user