Xemu [doxygen]  hyppo 0a42be3a057156924bc1b626a687bd6e27349c45 @ Sat 19 Mar 02:15:11 CET 2022
rc2014.c
Go to the documentation of this file.
1 /* RC2014 and generic Z80 SBC emulator
2  Part of the Xemu project, please visit: https://github.com/lgblgblgb/xemu
3  Copyright (C)2020-2021 LGB (Gábor Lénárt) <lgblgblgb@gmail.com>
4 
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9 
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
18 
19 
20 #include "xemu/emutools.h"
21 #include "xemu/emutools_files.h"
22 #include "xemu/emutools_config.h"
23 #include "hardware.h"
24 #include "console.h"
25 #include "uart.h"
26 
27 
28 #define FRAME_RATE 25
29 
30 static const char default_rom_fn[] = "#rc2014.rom";
31 
32 static struct {
35  int zoom;
36  double cpu_mhz;
37  char *load;
38  char *rom;
39  double baudcrystal;
40  int baudrate;
42 } configdb;
43 
44 
45 
46 static void emulation_loop ( void )
47 {
49  if (console_input() == 32)
50  exit(0);
51  } else {
52  if (XEMU_UNLIKELY(trace)) {
53  char disasm_buffer[128];
55  z80_custom_disasm(Z80_PC, disasm_buffer, sizeof disasm_buffer);
56  if (*disasm_buffer)
57  puts(disasm_buffer);
58  io_cycles = 0;
60  }
61  } else {
63  io_cycles = 0;
65  }
66  }
68 #if 0
69  if (emu_cost_cycles) {
71  emu_cost_cycles = 0;
72  }
73  if (emu_cost_usecs) {
75  emu_cost_usecs = 0;
76  }
77 #endif
78  }
82 }
83 
84 
85 void rc_shutdown_callback ( void )
86 {
87  DEBUGPRINT("%s() is here!" NL, __func__);
88 }
89 
90 
91 static int load_rom ( const char *fn )
92 {
93  if (!fn)
94  return 0;
95  if (!strcmp(fn, "-")) {
97  DEBUGPRINT("ROM: using built-in ROM by request");
98  return 0;
99  }
100  use_internal_rom(0);
101  DEBUGPRINT("ROM: trying to load \"%s\" as ROM" NL, fn);
102  int size = xemu_load_file(fn, NULL, 1, 0x8000, "Cannot load ROM");
103  if (size < 0)
104  return 1;
105  memset(memory, 0xFF, 0x8000);
106  memcpy(memory, xemu_load_buffer_p, size);
107  free(xemu_load_buffer_p);
108  DEBUGPRINT("ROM: loaded, %d bytes" NL, size);
109  z80ex_reset();
110  Z80_PC = 0x0000;
111  Z80_SP = 0xFFFF;
112  return 0;
113 }
114 
115 
116 static int load_prg ( const char *fn )
117 {
118  if (!fn)
119  return 0;
120  if (!*fn)
121  FATAL("Empty string for loading program.");
122  DEBUGPRINT("LOAD: trying to load program \"%s\" to $8000" NL, fn);
123  int size = xemu_load_file(fn, NULL, 1, 0x8000, "Cannot load program");
124  if (size < 0)
125  return 1;
126  memset(memory + 0x8000, 0xFF, 0x8000);
127  memcpy(memory + 0x8000, xemu_load_buffer_p, size);
128  free(xemu_load_buffer_p);
129  DEBUGPRINT("LOAD: Program loaded, %d bytes, %d bytes remained free" NL, size, 0x8000 - size);
130  z80ex_reset();
131  Z80_PC = 0x8000;
132  Z80_SP = 0xFFFF;
133  return 0;
134 }
135 
136 
137 
138 
139 int main ( int argc, char **argv )
140 {
141  xemu_pre_init(APP_ORG, TARGET_NAME, "Generic, simple RC2014 SBC emulation from LGB");
142  xemucfg_define_switch_option("fullscreen", "Start in fullscreen mode", &configdb.fullscreen);
143  xemucfg_define_switch_option("syscon", "Keep system console open (Windows-specific effect only)", &configdb.syscon);
144  xemucfg_define_num_option("width", 80, "Terminal width in character columns", &configdb.term_width, 38, 120);
145  xemucfg_define_num_option("height", 25, "Terminal height in character rows", &configdb.term_height, 20, 60);
146  xemucfg_define_num_option("zoom", 100, "Zoom the window by the given percentage (50%-200%)", &configdb.zoom, 50, 200);
147  xemucfg_define_float_option("clock", 4, "Select Z80 clock speed in MHz", &configdb.cpu_mhz, 1.0, 33.0);
148  xemucfg_define_float_option("baudcrystal", 1.718, "Crystal frequency for the UART chip in MHz", &configdb.baudcrystal, 1.0, 8.0);
149  xemucfg_define_num_option("baudrate", 56400, "Initial serial baudrate (may be modified if no exact match with -baudcrystal)", &configdb.baudrate, 30, 500000);
150  xemucfg_define_str_option("load", NULL, "Load and run program from $8000 directly", &configdb.load);
151  xemucfg_define_str_option("rom", default_rom_fn, "Load ROM from $0000 (use file name '-' for built-in one)", &configdb.rom);
152  xemucfg_define_switch_option("trace", "Trace the program, VERY spammy!", &trace);
153  xemucfg_define_switch_option("besure", "Skip asking \"are you sure?\" on RESET or EXIT", &i_am_sure_override);
154  xemucfg_define_num_option("sdlrenderquality", RENDER_SCALE_QUALITY, "Setting SDL hint for scaling method/quality on rendering (0, 1, 2)", &configdb.sdlrenderquality, 0, 2);
155 
156  if (xemucfg_parse_all(argc, argv))
157  return 1;
158  memset(memory, 0xFF, sizeof memory);
159  if (console_init(
160  configdb.term_width,
161  configdb.term_height,
162  configdb.zoom,
163  NULL,
164  NULL,
166  ))
167  return 1;
169  clear_emu_events(); // also resets the keyboard
170  cpu_cycles_per_frame = (1000000.0 * configdb.cpu_mhz) / (double)FRAME_RATE;
171  uart_init(
172  (int)(configdb.baudcrystal * 1000000.0),
173  configdb.baudrate,
174  (int)(configdb.cpu_mhz * 1000000.0)
175  );
176  DEBUGPRINT("Z80: setting CPU speed to %.2fMHz, %d CPU cycles per refresh-rate (=%dHz)" NL, configdb.cpu_mhz, cpu_cycles_per_frame, FRAME_RATE);
177  z80ex_init();
178  if (!configdb.syscon)
179  sysconsole_close(NULL);
180  z80ex_reset();
181  Z80_SP = 0xFFFF;
182  if (load_rom(configdb.rom)) {
183  if (strcmp(configdb.rom, default_rom_fn))
184  return 1;
185  else {
186  DEBUGPRINT("ROM: default ROM could not be loaded. Using simple, built-in one." NL);
187  use_internal_rom(1);
188  }
189  }
190  if (load_prg(configdb.load))
191  return 1;
193  xemu_timekeeping_start(); // we must call this once, right before the start of the emulation
194  XEMU_MAIN_LOOP(emulation_loop, FRAME_RATE, 1);
195  return 0;
196 }
cpu_cycles_per_frame
int cpu_cycles_per_frame
Definition: hardware.c:33
cpu_cycles
int cpu_cycles
Definition: hardware.c:32
xemu_pre_init
void xemu_pre_init(const char *app_organization, const char *app_name, const char *slogan)
Definition: emutools.c:651
z80ex_init
void z80ex_init(void)
Definition: z80ex.c:175
xemucfg_define_str_option
void xemucfg_define_str_option(const char *optname, const char *defval, const char *help, char **storage)
load
char * load
Definition: rc2014.c:37
cpu_mhz
double cpu_mhz
Definition: rc2014.c:36
console_input
int console_input(void)
Definition: console.c:157
emu_cost_usecs
int emu_cost_usecs
Definition: hardware.h:25
xemu_timekeeping_delay
void xemu_timekeeping_delay(int td_em)
Definition: emutools.c:405
emutools.h
sysconsole_close
void sysconsole_close(const char *waitmsg)
Definition: emutools.c:1393
XEMU_MAIN_LOOP
#define XEMU_MAIN_LOOP(func, p1, p2)
Definition: emutools.h:58
Z80_SP
#define Z80_SP
Definition: z80ex.h:117
z80_custom_disasm
int z80_custom_disasm(int addr, char *buf, int buf_size)
Definition: hardware.c:193
fullscreen
int fullscreen
Definition: rc2014.c:33
term_height
int term_height
Definition: rc2014.c:34
z80ex_step
int z80ex_step(void)
Definition: z80ex.c:47
xemucfg_define_num_option
void xemucfg_define_num_option(const char *optname, const int defval, const char *help, int *storage, int min, int max)
i_am_sure_override
int i_am_sure_override
Definition: emutools.c:74
use_internal_rom
void use_internal_rom(int yes)
Definition: hardware.c:56
configdb_st::rom
char * rom
Definition: configdb.h:32
hardware.h
fn
const char * fn
Definition: roms.c:42
xemucfg_parse_all
int xemucfg_parse_all(int argc, char **argv)
term_width
int term_width
Definition: rc2014.c:34
osd_init_with_defaults
int osd_init_with_defaults(void)
Definition: osd.c:131
sdlrenderquality
int sdlrenderquality
Definition: rc2014.c:41
z80ex_reset
void z80ex_reset(void)
Definition: z80ex.c:156
uart_init
void uart_init(int baud_crystal_hz, int baud_rate, int cpu_hz)
Definition: uart.c:28
stop_emulation
int stop_emulation
Definition: hardware.c:30
xemu_set_full_screen
void xemu_set_full_screen(int setting)
Definition: emutools.c:311
FRAME_RATE
#define FRAME_RATE
Definition: rc2014.c:28
baudrate
int baudrate
Definition: rc2014.c:40
configdb_st::sdlrenderquality
int sdlrenderquality
Definition: configdb.h:35
uart.h
zoom
int zoom
Definition: rc2014.c:35
trace
int trace
Definition: hardware.c:34
TARGET_NAME
#define TARGET_NAME
Definition: xemu-target.h:1
emutools_files.h
APP_ORG
#define APP_ORG
Definition: emutools.h:50
DEBUGPRINT
#define DEBUGPRINT(...)
Definition: emutools_basicdefs.h:171
rc_shutdown_callback
void rc_shutdown_callback(void)
Definition: rc2014.c:85
baudcrystal
double baudcrystal
Definition: rc2014.c:39
main
int main(int argc, char **argv)
Definition: rc2014.c:139
NL
#define NL
Definition: fat32.c:37
emutools_config.h
configdb
struct configdb_st configdb
Definition: configdb.c:34
memory
Uint8 memory[0x100000]
Definition: commodore_65.c:43
xemu_load_file
int xemu_load_file(const char *filename, void *store_to, int min_size, int max_size, const char *cry)
Definition: emutools_files.c:674
xemu_load_buffer_p
void * xemu_load_buffer_p
Definition: emutools_files.c:34
xemu_timekeeping_start
void xemu_timekeeping_start(void)
Definition: emutools.c:1122
configdb_st::syscon
int syscon
Definition: configdb.h:34
size
int size
Definition: inject.c:37
io_cycles
int io_cycles
Definition: hardware.c:35
clear_emu_events
void clear_emu_events(void)
Definition: commodore_65.c:193
configdb_st::fullscreen
int fullscreen
Definition: configdb.h:34
Z80_PC
#define Z80_PC
Definition: z80ex.h:121
xemucfg_define_float_option
void xemucfg_define_float_option(const char *optname, const double defval, const char *help, double *storage, double min, double max)
console_init
int console_init(int width, int height, int zoom_percent, Uint8 *video_mapped, Uint8 *color_mapped, int sdlrenderquality)
Definition: console.c:279
RENDER_SCALE_QUALITY
#define RENDER_SCALE_QUALITY
Definition: commodore_65.h:27
console.h
console_iteration
void console_iteration(void)
Definition: console.c:185
xemucfg_define_switch_option
void xemucfg_define_switch_option(const char *optname, const char *help, int *storage)
emu_cost_cycles
int emu_cost_cycles
Definition: hardware.c:30
FATAL
#define FATAL(...)
Definition: xep128.h:117
XEMU_UNLIKELY
#define XEMU_UNLIKELY(__x__)
Definition: emutools_basicdefs.h:125
syscon
int syscon
Definition: rc2014.c:33
rom
char * rom
Definition: rc2014.c:38
console_cursor_blink
void console_cursor_blink(int delay)
Definition: console.c:172