Xemu [doxygen]  hyppo 0a42be3a057156924bc1b626a687bd6e27349c45 @ Sat 19 Mar 02:15:11 CET 2022
enterprise128.c
Go to the documentation of this file.
1 /* Minimalistic Enterprise-128 emulator with focus on "exotic" hardware
2  Part of the Xemu project, please visit: https://github.com/lgblgblgb/xemu
3  Copyright (C)2015-2017,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_config.h"
22 #include "xemu/emutools_gui.h"
23 #include "xemu/emutools_hid.h"
24 #include "xemu/z80.h"
25 
26 #include "enterprise128.h"
27 
28 #include "configdb.h"
29 #include "dave.h"
30 #include "nick.h"
31 #include "sdext.h"
32 #include "exdos_wd.h"
33 #include "roms.h"
34 #include "input_devices.h"
35 #include "cpu.h"
36 #include "primoemu.h"
37 #include "emu_rom_interface.h"
38 #include "epnet.h"
39 #include "zxemu.h"
40 #include "printer.h"
41 #include "emu_monitor.h"
42 #include "rtc.h"
43 #include "fileio.h"
44 #include "snapshot.h"
45 
46 #include <string.h>
47 #include <stdlib.h>
48 #include <sys/time.h>
49 #include <time.h>
50 #include <unistd.h>
51 
52 
53 int paused = 0;
55 static int cpu_cycles_for_dave_sync = 0;
56 static double balancer;
57 static double SCALER;
58 static int sram_ready = 0;
59 time_t unix_time;
60 static char emulator_speed_title[32] = "";
61 
62 
63 
64 
65 static void shutdown_callback(void)
66 {
67  monitor_stop();
68  sdext_shutdown();
69  audio_close();
70  printer_close();
71 #ifdef CONFIG_EPNET_SUPPORT
72  epnet_uninit();
73 #endif
74 #ifdef CONFIG_EXDOS_SUPPORT
76 #endif
77  if (sram_ready)
79  DEBUGPRINT("Shutdown callback, return." NL);
80 }
81 
82 
83 void clear_emu_events ( void )
84 {
85  //hid_reset_events(1);
86  kbd_matrix_reset(); // also reset the keyboard matrix as it seems some keys can be detected "stucked" ...
87  mouse_reset_button(); // ... and also the mouse buttons :)
88 }
89 
90 
91 int set_cpu_clock ( int hz )
92 {
93  CPU_CLOCK = hz;
94  SCALER = (double)NICK_SLOTS_PER_SEC / (double)CPU_CLOCK;
95  DEBUG("CPU: clock = %d scaler = %f" NL, CPU_CLOCK, SCALER);
97  sprintf(emulator_speed_title, "%.2fMHz", hz / 1000000.0);
98  return hz;
99 }
100 
101 
103 {
104  hz = set_cpu_clock(hz);
105  OSD(-1, -1, "CPU speed: %.2f MHz", hz / 1000000.0);
106  return hz;
107 }
108 
109 
110 // called by nick.c
111 static int emu_one_frame_rasters = -1;
112 static int emu_one_frame_frameskip = 0;
113 
114 void emu_one_frame(int rasters, int frameskip)
115 {
116  emu_one_frame_rasters = rasters;
117  emu_one_frame_frameskip = frameskip;
118 }
119 
120 
121 static void __emu_one_frame(int rasters, int frameskip)
122 {
124  if (!frameskip) {
125 #ifdef XEMU_FILES_SCREENSHOT_SUPPORT
128  screenshot();
129  }
130 #endif
131  //screen_present_frame(ep_pixels); // this should be after the event handler, as eg screenshot function needs locked texture state if this feature is used at all
133  }
136  xemu_timekeeping_delay((1000000.0 * rasters * 57.0) / (double)NICK_SLOTS_PER_SEC);
137 }
138 
139 
140 static void xep128_emulation ( void )
141 {
142  //emu_timekeeping_check();
143  rtc_update_trigger = 1;
144  for (;;) {
145  int t;
146  if (XEMU_UNLIKELY(paused && !z80ex.prefix)) {
147  /* Paused is non-zero for special cases, like pausing emulator :) or single-step execution mode
148  We only do this if z80ex.prefix is non-zero, ie not in the "middle" of a prefixed Z80 opcode or so ... */
149  __emu_one_frame(312, 0); // keep UI stuffs (and some timing) intact ... with a faked about 312 scanline (normal frame) timing needed ...
150  return;
151  }
152  if (XEMU_UNLIKELY(nmi_pending)) {
153  t = z80ex_nmi();
154  DEBUG("NMI: %d" NL, t);
155  if (t)
156  nmi_pending = 0;
157  } else
158  t = 0;
159  //if (XEMU_UNLIKELY((dave_int_read & 0xAA) && t == 0)) {
160  if ((dave_int_read & 0xAA) && t == 0) {
161  t = z80ex_int();
162  if (t)
163  DEBUG("CPU: int and accepted = %d" NL, t);
164  } else
165  t = 0;
166  if (XEMU_LIKELY(!t))
167  t = z80ex_step();
168  cpu_cycles_for_dave_sync += t;
169  //DEBUG("DAVE: SYNC: CPU cycles = %d, Dave sync val = %d, limit = %d" NL, t, cpu_cycles_for_dave_sync, cpu_cycles_per_dave_tick);
170  while (cpu_cycles_for_dave_sync >= cpu_cycles_per_dave_tick) {
171  dave_tick();
172  cpu_cycles_for_dave_sync -= cpu_cycles_per_dave_tick;
173  }
174  balancer += t * SCALER;
175  //DEBUG("%s [balance=%f t=%d]" NL, buffer, balancer, t);
176  while (balancer >= 0.5) {
178  balancer -= 1.0;
179  if (XEMU_UNLIKELY(emu_one_frame_rasters != -1)) {
180  __emu_one_frame(
181  emu_one_frame_rasters,
182  emu_one_frame_frameskip
183  );
184  emu_one_frame_rasters = -1;
185  return;
186  }
187  }
188  //DEBUG("[balance=%f t=%d]" NL, balancer, t);
189  }
190 }
191 
192 
193 int main (int argc, char *argv[])
194 {
195  xemu_pre_init(APP_ORG, TARGET_NAME, "The Enterprise-128 \"old XEP128 within the Xemu project now\" emulator from LGB");
197  if (xemucfg_parse_all(argc, argv))
198  return 1;
200  if (xemu_post_init(
201  TARGET_DESC APP_DESC_APPEND, // window title
202  1, // resizable window
203  SCREEN_WIDTH, SCREEN_HEIGHT, // texture sizes
204  SCREEN_WIDTH, SCREEN_HEIGHT * 2,// logical size (used with keeping aspect ratio by the SDL render stuffs)
205  SCREEN_WIDTH, SCREEN_HEIGHT * 2,// window size
206  SCREEN_FORMAT, // pixel format
207  0, // we have *NO* pre-defined colours as with more simple machines (too many we need). we want to do this ourselves!
208  NULL, // -- "" --
209  NULL, // -- "" --
210  configdb.sdlrenderquality, // render scaling quality
211  USE_LOCKED_TEXTURE, // 1 = locked texture access
212  shutdown_callback // registered shutdown function
213  ))
214  return 1;
215  xemugui_init(configdb.gui_selection); // allow to fail (do not exit if it fails). Some targets may not have X running
216  hid_init(
219  SDL_ENABLE // joystick events
220  );
222  fileio_init(
223 #ifdef XEMU_ARCH_HTML
224  "/",
225 #else
226  sdl_pref_dir,
227 #endif
228  "files");
230  z80ex_init();
232  if (nick_init())
233  return 1;
234  //const char *snapshot = xemucfg_get_str("snapshot");
235  if (configdb.snapshot) {
238  } // else
239  if (!configdb.snapshot) {
240  if (roms_load())
241  return 1;
244  }
246  ep_reset();
248 #ifdef CONFIG_SDEXT_SUPPORT
249  if (!configdb.snapshot)
250  sdext_init(configdb.sdimg);
251 #endif
252 #ifdef CONFIG_EXDOS_SUPPORT
253  wd_exdos_reset();
255 #endif
256 #ifdef CONFIG_EPNET_SUPPORT
257  epnet_init(NULL);
258 #endif
259  balancer = 0;
260  set_cpu_clock((int)(configdb.clock * 1000000.0));
261  audio_start();
263  sram_ready = 1;
264  if (configdb.primo && !configdb.snapshot) {
265  if (primo_rom_seg != -1) {
267  OSD(-1, -1, "Primo Emulator Mode");
268  } else
269  ERROR_WINDOW("Primo mode was requested, but PRIMO ROM was not loaded.\nRefusing Primo mode");
270  }
271  if (configdb.snapshot)
273  if (!configdb.syscon && !configdb.monitor)
274  sysconsole_close(NULL);
275  if (configdb.monitor)
276  monitor_start();
279  DEBUGPRINT(NL "EMU: entering into main emulation loop" NL);
280  // emscripten_set_main_loop(xep128_emulation, 50, 1);
281  XEMU_MAIN_LOOP(xep128_emulation, 50, 1);
282  return 0;
283 }
wd_attach_disk_image
int wd_attach_disk_image(const char *fn)
Definition: exdos_wd.c:126
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
zxemu.h
USE_LOCKED_TEXTURE
#define USE_LOCKED_TEXTURE
Definition: commodore_65.h:26
main
int main(int argc, char *argv[])
Definition: enterprise128.c:193
sdext.h
nick_init
int nick_init(void)
Definition: nick.c:115
TARGET_DESC
#define TARGET_DESC
Definition: xemu-target.h:2
ep_reset
void ep_reset(void)
Definition: cpu.c:621
unix_time
time_t unix_time
Definition: enterprise128.c:59
ep128_key_map
const struct KeyMappingDefault ep128_key_map[]
Definition: input_devices.c:42
ep128snap_set_cpu_and_io
void ep128snap_set_cpu_and_io(void)
Definition: snapshot.c:203
configdb_st::fullscreen_requested
int fullscreen_requested
Definition: configdb.h:35
primoemu.h
clear_emu_events
void clear_emu_events(void)
Definition: enterprise128.c:83
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
emu_monitor.h
wd_exdos_reset
void wd_exdos_reset(void)
Definition: exdos_wd.c:163
configdb_st::monitor
int monitor
Definition: configdb.h:41
z80ex_step
int z80ex_step(void)
Definition: z80ex.c:47
configdb_st::audio
int audio
Definition: configdb.h:38
SCREEN_WIDTH
#define SCREEN_WIDTH
Definition: vic3.h:29
configdb_st::clock
double clock
Definition: configdb.h:37
xemu_update_screen
void xemu_update_screen(void)
Definition: emutools.c:1184
monitor_stop
int monitor_stop(void)
Definition: emu_monitor.c:897
set_ep_cpu
void set_ep_cpu(int type)
Definition: cpu.c:74
register_screenshot_request
int register_screenshot_request
Definition: enterprise128.c:54
emu_rom_interface.h
set_cpu_clock_with_osd
int set_cpu_clock_with_osd(int hz)
Definition: enterprise128.c:102
monitor_process_queued
void monitor_process_queued(void)
Definition: emu_monitor.c:766
NICK_SLOTS_PER_SEC
#define NICK_SLOTS_PER_SEC
Definition: nick.h:24
hid_handle_all_sdl_events
void hid_handle_all_sdl_events(void)
Definition: emutools_hid.c:613
printer_close
void printer_close(void)
Definition: printer.c:61
xemucfg_parse_all
int xemucfg_parse_all(int argc, char **argv)
emutools_gui.h
configdb_st::snapshot
char * snapshot
Definition: configdb.h:44
roms_load
int roms_load(void)
Definition: roms.c:140
z80ex_int
int z80ex_int(void)
Definition: z80ex.c:225
osd_init_with_defaults
int osd_init_with_defaults(void)
Definition: osd.c:131
hid_init
void hid_init(const struct KeyMappingDefault *key_map_in, Uint8 virtual_shift_pos_in, int joy_enable)
Definition: emutools_hid.c:300
fileio.h
paused
int paused
Definition: enterprise128.c:53
epnet.h
xemu_set_full_screen
void xemu_set_full_screen(int setting)
Definition: emutools.c:311
set_cpu_clock
int set_cpu_clock(int hz)
Definition: enterprise128.c:91
kbd_matrix_reset
void kbd_matrix_reset(void)
Definition: dave.c:199
configdb_st::wd_img_path
char * wd_img_path
Definition: configdb.h:49
nick_render_slot
void nick_render_slot(void)
Definition: nick.c:550
configdb_st::sdlrenderquality
int sdlrenderquality
Definition: configdb.h:35
configdb_define_emulator_options
void configdb_define_emulator_options(void)
Definition: configdb.c:36
xemugui_init
int xemugui_init(const char *name)
Definition: emutools_gui.c:82
screenshot
void screenshot(void)
Definition: nick.c:97
TARGET_NAME
#define TARGET_NAME
Definition: xemu-target.h:1
z80.h
APP_ORG
#define APP_ORG
Definition: emutools.h:50
DEBUGPRINT
#define DEBUGPRINT(...)
Definition: emutools_basicdefs.h:171
roms.h
primo_rom_seg
int primo_rom_seg
Definition: primoemu.c:32
printer.h
dave_tick
void dave_tick(void)
Definition: dave.c:254
CPU_Z80
#define CPU_Z80
Definition: cpu.h:24
VIRTUAL_SHIFT_POS
#define VIRTUAL_SHIFT_POS
Definition: commodore_lcd.c:84
mouse_reset_button
void mouse_reset_button(void)
Definition: input_devices.c:255
configdb_st::ram_setup_str
char * ram_setup_str
Definition: configdb.h:42
ERROR_WINDOW
#define ERROR_WINDOW(...)
Definition: xep128.h:116
fileio_init
void fileio_init(const char *dir, const char *subdir)
Definition: fileio.c:55
ep128snap_load
int ep128snap_load(const char *fn)
Definition: snapshot.c:68
XEMU_LIKELY
#define XEMU_LIKELY(__x__)
Definition: emutools_basicdefs.h:124
cpu.h
NL
#define NL
Definition: fat32.c:37
emutools_config.h
configdb
struct configdb_st configdb
Definition: configdb.c:34
wd_detach_disk_image
void wd_detach_disk_image(void)
Definition: exdos_wd.c:114
configdb.h
xemu_post_init
int xemu_post_init(const char *window_title, int is_resizable, int texture_x_size, int texture_y_size, int logical_x_size, int logical_y_size, int win_x_size, int win_y_size, Uint32 pixel_format, int n_colours, const Uint8 *colours, Uint32 *store_palette, int render_scale_quality, int locked_texture_update, void(*shutdown_callback)(void))
Definition: emutools.c:908
audio_init
void audio_init(int enable)
Definition: dave.c:153
emulator_speed_title
char emulator_speed_title[]
Definition: commodore_65.c:78
audio_start
void audio_start(void)
Definition: dave.c:123
_z80_cpu_context::prefix
Z80EX_BYTE prefix
Definition: z80ex.h:163
audio_close
void audio_close(void)
Definition: dave.c:143
dave.h
primo_emulator_execute
void primo_emulator_execute(void)
Definition: primoemu.c:211
primo_search_rom
int primo_search_rom(void)
Definition: primoemu.c:158
xemu_timekeeping_start
void xemu_timekeeping_start(void)
Definition: emutools.c:1122
configdb_st::primo
int primo
Definition: configdb.h:40
configdb_st::syscon
int syscon
Definition: configdb.h:34
input_devices.h
configdb_st::mousemode
int mousemode
Definition: configdb.h:39
dave_set_clock
void dave_set_clock(void)
Definition: dave.c:182
SCREEN_HEIGHT
#define SCREEN_HEIGHT
Definition: vic3.h:30
CPU_CLOCK
#define CPU_CLOCK
Definition: tvc.h:30
rtc_update_trigger
int rtc_update_trigger
Definition: rtc.c:31
SCREEN_FORMAT
#define SCREEN_FORMAT
Definition: commodore_65.h:25
snapshot.h
OSD
#define OSD(...)
Definition: xep128.h:100
monitor_start
int monitor_start(void)
Definition: emu_monitor.c:873
configdb_st::sdimg
char * sdimg
Definition: configdb.h:45
APP_DESC_APPEND
#define APP_DESC_APPEND
Definition: emutools.h:52
exdos_wd.h
xemugui_iteration
int xemugui_iteration(void)
Definition: emutools_gui.c:120
emu_one_frame
void emu_one_frame(int rasters, int frameskip)
Definition: enterprise128.c:114
emutools_hid.h
rtc.h
cpu_cycles_per_dave_tick
int cpu_cycles_per_dave_tick
Definition: dave.c:36
enterprise128.h
z80ex
Z80EX_CONTEXT z80ex
Definition: primo.c:37
DEBUG
#define DEBUG(...)
Definition: emutools_basicdefs.h:167
configdb_st::gui_selection
char * gui_selection
Definition: configdb.h:43
sdl_pref_dir
char * sdl_pref_dir
Definition: emutools.c:97
z80ex_nmi
int z80ex_nmi(void)
Definition: z80ex.c:192
window_title_info_addon
char * window_title_info_addon
Definition: emutools.c:91
ep_set_ram_config
int ep_set_ram_config(const char *spec)
Definition: cpu.c:131
XEMU_UNLIKELY
#define XEMU_UNLIKELY(__x__)
Definition: emutools_basicdefs.h:125
dave_int_read
Uint8 dave_int_read
Definition: dave.c:29
frameskip
int frameskip
Definition: vic3.c:75
mouse_setup
int mouse_setup(int cfg)
Definition: input_devices.c:500
xemucfg_set_str
void xemucfg_set_str(char **ptr, const char *value)
nick.h
sram_save_all_segments
int sram_save_all_segments(void)
Definition: roms.c:87
nmi_pending
int nmi_pending
Definition: cpu.c:47