- [CHG] mode berserk passa a per Fast Tape. sistema de Opcions.
- [NEW] Opció per a parar execució al acabar de carregar una cinta. - [NEW] Opció per a parar l'execució al trobar una instrucció del Z80 no vàlida - [NEW] Savestate del Fernando Martin, per a provar més ràpid. - [NEW] Treballant en el sistema d'anàlisi visual del codi
This commit is contained in:
34
main.cpp
34
main.cpp
@@ -10,6 +10,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
#include "ui_menu.h"
|
#include "ui_menu.h"
|
||||||
|
#include "z80analyze.h"
|
||||||
|
|
||||||
uint8_t memory[65536];
|
uint8_t memory[65536];
|
||||||
uint32_t time = 0;
|
uint32_t time = 0;
|
||||||
@@ -24,10 +25,16 @@ namespace actions
|
|||||||
zxscreen::refresh(dt);
|
zxscreen::refresh(dt);
|
||||||
}
|
}
|
||||||
|
|
||||||
int berserk(int value)
|
int fastload(int value)
|
||||||
{
|
{
|
||||||
zx_tape::setberserk(!zx_tape::getberserk());
|
zx_tape::toggleOption(ZXTAPE_OPTION_FAST_LOAD);
|
||||||
return zx_tape::getberserk();
|
return zx_tape::getOption(ZXTAPE_OPTION_FAST_LOAD);
|
||||||
|
}
|
||||||
|
|
||||||
|
int stopatend(int value)
|
||||||
|
{
|
||||||
|
zx_tape::toggleOption(ZXTAPE_OPTION_STOP_AT_END);
|
||||||
|
return zx_tape::getOption(ZXTAPE_OPTION_STOP_AT_END);
|
||||||
}
|
}
|
||||||
|
|
||||||
int decZoom(int value)
|
int decZoom(int value)
|
||||||
@@ -47,6 +54,12 @@ namespace actions
|
|||||||
zxscreen::toggleFullscreen();
|
zxscreen::toggleFullscreen();
|
||||||
return zxscreen::getFullscreen();
|
return zxscreen::getFullscreen();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int showAnalyzer(int value)
|
||||||
|
{
|
||||||
|
z80analyze::show();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
@@ -73,13 +86,18 @@ int main(int argc, char *argv[])
|
|||||||
ui::menu::addoption(menu, "SAVE STATE", nullptr);
|
ui::menu::addoption(menu, "SAVE STATE", nullptr);
|
||||||
|
|
||||||
menu = ui::menu::addsubmenu("TAPE");
|
menu = ui::menu::addsubmenu("TAPE");
|
||||||
ui::menu::addbooloption(menu, "BERSERK MODE", zx_tape::getberserk(), actions::berserk);
|
ui::menu::addbooloption(menu, "BERSERK MODE", zx_tape::getOption(ZXTAPE_OPTION_FAST_LOAD), actions::fastload);
|
||||||
|
ui::menu::addbooloption(menu, "STOP AT END", zx_tape::getOption(ZXTAPE_OPTION_STOP_AT_END), actions::stopatend);
|
||||||
|
|
||||||
menu = ui::menu::addsubmenu("SCREEN");
|
menu = ui::menu::addsubmenu("SCREEN");
|
||||||
ui::menu::addoption(menu, "DEC ZOOM", actions::decZoom);
|
ui::menu::addoption(menu, "DEC ZOOM", actions::decZoom);
|
||||||
ui::menu::addoption(menu, "INC ZOOM", actions::incZoom);
|
ui::menu::addoption(menu, "INC ZOOM", actions::incZoom);
|
||||||
ui::menu::addbooloption(menu, "FULLSCREEN", zxscreen::getFullscreen(), actions::fullscreen);
|
ui::menu::addbooloption(menu, "FULLSCREEN", zxscreen::getFullscreen(), actions::fullscreen);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
zx_ula::sound_init();
|
zx_ula::sound_init();
|
||||||
|
|
||||||
zx_tape::load("fernandomartin.tap");
|
zx_tape::load("fernandomartin.tap");
|
||||||
@@ -206,9 +224,9 @@ int main(int argc, char *argv[])
|
|||||||
zxscreen::redraw();
|
zxscreen::redraw();
|
||||||
} else {
|
} else {
|
||||||
//if (z80::getPC()==0x05C8) zx_tape::go_berserk();
|
//if (z80::getPC()==0x05C8) zx_tape::go_berserk();
|
||||||
bool berserk=false;
|
bool fastload=false;
|
||||||
if (zx_tape::getplaying() && zx_tape::getberserk()) { berserk=true; time = SDL_GetTicks(); }
|
if (zx_tape::getplaying() && zx_tape::getOption(ZXTAPE_OPTION_FAST_LOAD)) { fastload=true; time = SDL_GetTicks(); }
|
||||||
while (zx_tape::getplaying() && zx_tape::getberserk())
|
while (zx_tape::getplaying() && zx_tape::getOption(ZXTAPE_OPTION_FAST_LOAD))
|
||||||
{
|
{
|
||||||
// zx_tape::update(z80::step());
|
// zx_tape::update(z80::step());
|
||||||
uint8_t dt = z80::step();
|
uint8_t dt = z80::step();
|
||||||
@@ -221,7 +239,7 @@ int main(int argc, char *argv[])
|
|||||||
//zx_ula::sound_update(dt);
|
//zx_ula::sound_update(dt);
|
||||||
//zxscreen::refresh(dt);
|
//zxscreen::refresh(dt);
|
||||||
}
|
}
|
||||||
if (berserk) { printf("%i\n", SDL_GetTicks()-time); t_states=0; }
|
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
|
||||||
for (int i=0;i<5;++i) {
|
for (int i=0;i<5;++i) {
|
||||||
uint8_t dt = z80::step();
|
uint8_t dt = z80::step();
|
||||||
|
|||||||
19
z80.cpp
19
z80.cpp
@@ -9,6 +9,7 @@ namespace z80
|
|||||||
static uint8_t memtag[65536];
|
static uint8_t memtag[65536];
|
||||||
static uint32_t t = 0;
|
static uint32_t t = 0;
|
||||||
static uint16_t current_opcode_address = 0;
|
static uint16_t current_opcode_address = 0;
|
||||||
|
bool options[Z80_NUM_OPTIONS] = { true };
|
||||||
|
|
||||||
int (*in_ports[256])(int);
|
int (*in_ports[256])(int);
|
||||||
void (*out_ports[256])(int, int);
|
void (*out_ports[256])(int, int);
|
||||||
@@ -1032,9 +1033,8 @@ namespace z80
|
|||||||
|
|
||||||
void INVALID(uint8_t opcode)
|
void INVALID(uint8_t opcode)
|
||||||
{
|
{
|
||||||
// [TODO]
|
|
||||||
printf("INVALID OPCODE AT: %04x\n", current_opcode_address);
|
printf("INVALID OPCODE AT: %04x\n", current_opcode_address);
|
||||||
z80debug::stop();
|
if (options[Z80_OPTION_STOP_ON_INVALID]) z80debug::stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset(uint8_t* mem)
|
void reset(uint8_t* mem)
|
||||||
@@ -2738,4 +2738,19 @@ namespace z80
|
|||||||
|
|
||||||
uint8_t getMemTag(const uint16_t addr) { return memtag[addr]; };
|
uint8_t getMemTag(const uint16_t addr) { return memtag[addr]; };
|
||||||
|
|
||||||
|
const bool getOption(const int option)
|
||||||
|
{
|
||||||
|
return options[option];
|
||||||
|
}
|
||||||
|
|
||||||
|
void setOption(const int option, const bool value)
|
||||||
|
{
|
||||||
|
options[option] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void toggleOption(const int option)
|
||||||
|
{
|
||||||
|
options[option] = !options[option];
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
7
z80.h
7
z80.h
@@ -9,6 +9,9 @@ namespace z80
|
|||||||
#define MEMTAG_CODE 2
|
#define MEMTAG_CODE 2
|
||||||
#define MEMTAG_DATA 3
|
#define MEMTAG_DATA 3
|
||||||
|
|
||||||
|
#define Z80_OPTION_STOP_ON_INVALID 0
|
||||||
|
#define Z80_NUM_OPTIONS 1
|
||||||
|
|
||||||
void reset(uint8_t* mem);
|
void reset(uint8_t* mem);
|
||||||
void connect_port(int num, int (*in_ptr)(int), void (*out_ptr)(int,int));
|
void connect_port(int num, int (*in_ptr)(int), void (*out_ptr)(int,int));
|
||||||
void interrupt();
|
void interrupt();
|
||||||
@@ -34,4 +37,8 @@ namespace z80
|
|||||||
|
|
||||||
void setPC(const uint16_t addr);
|
void setPC(const uint16_t addr);
|
||||||
uint8_t getMemTag(const uint16_t addr);
|
uint8_t getMemTag(const uint16_t addr);
|
||||||
|
|
||||||
|
const bool getOption(const int option);
|
||||||
|
void setOption(const int option, const bool value);
|
||||||
|
void toggleOption(const int option);
|
||||||
}
|
}
|
||||||
43
z80analyze.cpp
Normal file
43
z80analyze.cpp
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
#include "z80analyze.h"
|
||||||
|
#include "z80.h"
|
||||||
|
#include <SDL2/SDL.h>
|
||||||
|
|
||||||
|
namespace z80analyze
|
||||||
|
{
|
||||||
|
SDL_Window *win = nullptr;
|
||||||
|
SDL_Renderer *ren = nullptr;
|
||||||
|
SDL_Texture *tex = nullptr;
|
||||||
|
|
||||||
|
void show()
|
||||||
|
{
|
||||||
|
if (!win)
|
||||||
|
{
|
||||||
|
win = SDL_CreateWindow("Z80 Analyzer", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 256, 256, SDL_WINDOW_SHOWN);
|
||||||
|
ren = SDL_CreateRenderer(win, -1, 0);
|
||||||
|
tex = SDL_CreateTexture(ren, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, 256, 256);
|
||||||
|
}
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
void refresh()
|
||||||
|
{
|
||||||
|
Uint32 *pixels;
|
||||||
|
int pitch;
|
||||||
|
SDL_LockTexture(tex, NULL, (void**)&pixels, &pitch);
|
||||||
|
for (int i=0; i<65536; ++i)
|
||||||
|
{
|
||||||
|
uint8_t tag = z80::getMemTag(i);
|
||||||
|
pixels[i] = tag==MEMTAG_NONE ? 0x808080 : tag==MEMTAG_DATA ? 0x0000FF : 0x00FF00;
|
||||||
|
}
|
||||||
|
SDL_UnlockTexture(tex);
|
||||||
|
SDL_RenderCopy(ren, tex, NULL, NULL);
|
||||||
|
SDL_RenderPresent(ren);
|
||||||
|
}
|
||||||
|
|
||||||
|
void hide()
|
||||||
|
{
|
||||||
|
SDL_DestroyTexture(tex);
|
||||||
|
SDL_DestroyRenderer(ren);
|
||||||
|
SDL_DestroyWindow(win);
|
||||||
|
}
|
||||||
|
}
|
||||||
8
z80analyze.h
Normal file
8
z80analyze.h
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace z80analyze
|
||||||
|
{
|
||||||
|
void show();
|
||||||
|
void refresh();
|
||||||
|
void hide();
|
||||||
|
}
|
||||||
@@ -181,7 +181,7 @@ namespace zxscreen
|
|||||||
|
|
||||||
void redraw(const bool present)
|
void redraw(const bool present)
|
||||||
{
|
{
|
||||||
if (zx_tape::getplaying() && zx_tape::getberserk()) return;
|
if (zx_tape::getplaying() && zx_tape::getOption(ZXTAPE_OPTION_FAST_LOAD)) return;
|
||||||
|
|
||||||
Uint32* pixels;
|
Uint32* pixels;
|
||||||
int pitch;
|
int pitch;
|
||||||
|
|||||||
23
zx_tape.cpp
23
zx_tape.cpp
@@ -1,6 +1,7 @@
|
|||||||
#include "zx_tape.h"
|
#include "zx_tape.h"
|
||||||
#include "zx_ula.h"
|
#include "zx_ula.h"
|
||||||
#include "zx_screen.h"
|
#include "zx_screen.h"
|
||||||
|
#include "z80debug.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@@ -34,7 +35,7 @@ namespace zx_tape
|
|||||||
|
|
||||||
bool playing = false;
|
bool playing = false;
|
||||||
bool loaded = false;
|
bool loaded = false;
|
||||||
bool berserk_mode = true;
|
bool options[ZXTAPE_NUM_OPTIONS] = { true, true };
|
||||||
|
|
||||||
std::vector<block_t> blocks;
|
std::vector<block_t> blocks;
|
||||||
uint8_t current_block = 0;
|
uint8_t current_block = 0;
|
||||||
@@ -80,7 +81,7 @@ namespace zx_tape
|
|||||||
void stop()
|
void stop()
|
||||||
{
|
{
|
||||||
playing = false;
|
playing = false;
|
||||||
berserk_mode = false;
|
//berserk_mode = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void rewind()
|
void rewind()
|
||||||
@@ -220,6 +221,7 @@ namespace zx_tape
|
|||||||
printf("end\n");
|
printf("end\n");
|
||||||
stop();
|
stop();
|
||||||
rewind();
|
rewind();
|
||||||
|
if (options[ZXTAPE_OPTION_STOP_AT_END]) z80debug::stop();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -232,8 +234,6 @@ namespace zx_tape
|
|||||||
zx_ula::set_ear(pulse_level);
|
zx_ula::set_ear(pulse_level);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setberserk(const bool value) { berserk_mode = value; }
|
|
||||||
const bool getberserk() { return berserk_mode; }
|
|
||||||
const bool getplaying() { return playing; }
|
const bool getplaying() { return playing; }
|
||||||
|
|
||||||
void report()
|
void report()
|
||||||
@@ -242,4 +242,19 @@ namespace zx_tape
|
|||||||
const int percent = (float(block_pos)/float(blocks[current_block].length))*100;
|
const int percent = (float(block_pos)/float(blocks[current_block].length))*100;
|
||||||
printf("tape loading: %i%\n", percent);
|
printf("tape loading: %i%\n", percent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const bool getOption(const int option)
|
||||||
|
{
|
||||||
|
return options[option];
|
||||||
|
}
|
||||||
|
|
||||||
|
void setOption(const int option, const bool value)
|
||||||
|
{
|
||||||
|
options[option] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void toggleOption(const int option)
|
||||||
|
{
|
||||||
|
options[option] = !options[option];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
10
zx_tape.h
10
zx_tape.h
@@ -3,13 +3,19 @@
|
|||||||
|
|
||||||
namespace zx_tape
|
namespace zx_tape
|
||||||
{
|
{
|
||||||
|
#define ZXTAPE_OPTION_FAST_LOAD 0
|
||||||
|
#define ZXTAPE_OPTION_STOP_AT_END 1
|
||||||
|
#define ZXTAPE_NUM_OPTIONS 2
|
||||||
|
|
||||||
void load(const char* filename);
|
void load(const char* filename);
|
||||||
void play();
|
void play();
|
||||||
void stop();
|
void stop();
|
||||||
void rewind();
|
void rewind();
|
||||||
void update(const uint8_t dt);
|
void update(const uint8_t dt);
|
||||||
void setberserk(const bool value);
|
|
||||||
const bool getberserk();
|
|
||||||
const bool getplaying();
|
const bool getplaying();
|
||||||
void report();
|
void report();
|
||||||
|
|
||||||
|
const bool getOption(const int option);
|
||||||
|
void setOption(const int option, const bool value);
|
||||||
|
void toggleOption(const int option);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user