Xemu [doxygen]  hyppo 0a42be3a057156924bc1b626a687bd6e27349c45 @ Sat 19 Mar 02:15:11 CET 2022
recpm.c
Go to the documentation of this file.
1 /* Re-CP/M: CP/M-like own implementation + Z80 emulator
2  Part of the Xemu project, please visit: https://github.com/lgblgblgb/xemu
3  Copyright (C)2016-2019,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 #define RECPM_MAIN_SCOPE
20 
21 #include "xemu/emutools.h"
22 #include "xemu/emutools_files.h"
23 #include "xemu/emutools_config.h"
24 #include "recpm.h"
25 #include "hardware.h"
26 #include "bios.h"
27 #include "bdos.h"
28 #include "console.h"
29 #include "cpmfs.h"
30 
31 #define FRAME_RATE 25
32 
33 
34 static void emulation_loop ( void )
35 {
37  if (console_input() == 32)
38  exit(0);
39  } else {
40  if (XEMU_UNLIKELY(trace)) {
41  char disasm_buffer[128];
43  z80_custom_disasm(Z80_PC, disasm_buffer, sizeof disasm_buffer);
44  if (*disasm_buffer)
45  puts(disasm_buffer);
47  }
48  } else {
51  }
53 #if 0
54  if (emu_cost_cycles) {
56  emu_cost_cycles = 0;
57  }
58  if (emu_cost_usecs) {
60  emu_cost_usecs = 0;
61  }
62 #endif
63  }
67 }
68 
69 
71 {
72  DEBUGPRINT("%s() is here!" NL, __func__);
73  cpmfs_uninit();
74 }
75 
76 
77 #if 0
78 int cpmprg_prepare_psp ( int argc, char **argv )
79 {
80  memset(memory + 8, 0, 0x100 - 8);
81  memset(memory + 0x5C + 1, 32, 11);
82  memset(memory + 0x6C + 1, 32, 11);
83  for (int a = 0; a < argc; a++) {
84  if (a <= 1)
85  write_filename_to_fcb(a == 0 ? 0x5C : 0x6C, argv[a]);
86  if (memory[0x81])
87  strcat((char*)memory + 0x81, " ");
88  strcat((char*)memory + 0x81, argv[a]);
89  if (strlen((char*)memory + 0x81) > 0x7F)
90  return CPMPRG_STOP(1, "Too long command line for the CP/M program");
91  }
92  memory[0x80] = strlen((char*)memory + 0x81);
93  return 0;
94 }
95 #endif
96 
97 static int load ( const char *fn )
98 {
99  if (!fn)
100  return 0;
101  if (!*fn)
102  FATAL("Empty string for loading program.");
103  // the last parameter for mounting drive will instruct CPM-FS to get the drive path as the dirname part of "fn"
104  if (cpmfs_mount_drive(0, fn, 1))
105  return 1;
106  cpmfs_mount_drive(1, "/", 0);
107  int tpa_size = memory[6] + (memory[7] << 8) - 0x100;
108  DEBUGPRINT("LOAD: trying to load program \"%s\", max allowed size = %d bytes." NL, fn, tpa_size);
109  int size = xemu_load_file(fn, memory + 0x100, 1, tpa_size, "Cannot load program");
110  if (size < 0)
111  return 1;
112  DEBUGPRINT("LOAD: Program loaded, %d bytes, %d bytes TPA remained free" NL, size, tpa_size - size);
113  Z80_PC = 0x100;
114  cpm_dma = 0x80; // default DMA
115  Z80_C = 0; // FIXME: should be the same as zero page loc 4, drive + user number ...
116  memset(memory + 8, 0, 0x100 - 8);
117  memset(memory + 0x5C + 1, 32, 11);
118  memset(memory + 0x6C + 1, 32, 11);
119  return 0;
120 }
121 
122 
123 static struct {
126  int baud;
127  int mapvideo;
128  char *load;
129 } configdb;
130 
131 
132 int main ( int argc, char **argv )
133 {
134  int memtop = 0x10000;
135  xemu_pre_init(APP_ORG, TARGET_NAME, "Re-CP/M");
136  xemucfg_define_switch_option("fullscreen", "Start in fullscreen mode", &configdb.fullscreen);
137  xemucfg_define_switch_option("syscon", "Keep system console open (Windows-specific effect only)", &configdb.fullscreen);
138  xemucfg_define_num_option("width", 80, "Terminal width in character columns", &configdb.term_width, 38, 160);
139  xemucfg_define_num_option("height", 25, "Terminal height in character rows", &configdb.term_height, 20, 60);
140  xemucfg_define_num_option("zoom", 100, "Zoom the window by the given percentage (50%-200%)", &configdb.zoom, 50, 200);
141  //xemucfg_define_num_option("cpmsize", 64, "Size of the CP/M system");
142  xemucfg_define_num_option("clock", 4, "Rough Z80 emulation speed in MHz with 'emulation cost'", &cpu_mhz, 1, 33);
143  xemucfg_define_num_option("baud", 0, "Emulate serial terminal with about the given baud rate [0=disable]", &configdb.baud, 0, 1000000);
144  xemucfg_define_str_option("load", NULL, "Load and run a CP/M program", &configdb.load);
145  xemucfg_define_switch_option("trace", "Trace the program, VERY spammy!", &trace);
146  xemucfg_define_switch_option("mapvideo", "Map video+colour RAM into the end of addr space", &configdb.mapvideo);
147  if (xemucfg_parse_all(argc, argv))
148  return 1;
149  if (configdb.baud && configdb.baud < 300)
150  configdb.baud = 300;
151  memset(memory, 0, sizeof memory);
152  memset(modded, 0, sizeof modded);
153  if (console_init(
154  configdb.term_width,
155  configdb.term_height,
156  configdb.zoom,
157  configdb.mapvideo ? &memtop : NULL,
158  configdb.baud
159  ))
160  return 1;
161  memtop &= ~0xFF;
162  DEBUGPRINT("System RAM size: %d Kbytes." NL, memtop >> 10);
163  bios_install(memtop - 0x100);
164  bdos_install(memtop - 0x200);
165  cpmfs_init();
167  /* Intialize memory and load ROMs */
168  clear_emu_events(); // also resets the keyboard
169  cpu_cycles_per_frame = (1000000 * cpu_mhz) / FRAME_RATE;
170  DEBUGPRINT("Z80: setting CPU speed to %dMHz, %d CPU cycles per refresh-rate (=%dHz)" NL, cpu_mhz, cpu_cycles_per_frame, FRAME_RATE);
171  z80ex_init();
172  if (!configdb.syscon)
173  sysconsole_close(NULL);
174  Z80_PC = 0;
175  Z80_SP = 0x100;
176  if (load(configdb.load))
177  return 1;
178  conputs("re-CP/M\r\n");
180  xemu_timekeeping_start(); // we must call this once, right before the start of the emulation
181  XEMU_MAIN_LOOP(emulation_loop, FRAME_RATE, 1);
182  return 0;
183 }
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)
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
bdos_install
void bdos_install(int addr)
Definition: bdos.c:34
load
char * load
Definition: recpm.c:128
cpmfs.h
main
int main(int argc, char **argv)
Definition: recpm.c:132
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
bdos.h
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
FRAME_RATE
#define FRAME_RATE
Definition: recpm.c:31
z80ex_step
int z80ex_step(void)
Definition: z80ex.c:47
recpm_shutdown_callback
void recpm_shutdown_callback(void)
Definition: recpm.c:70
xemucfg_define_num_option
void xemucfg_define_num_option(const char *optname, const int defval, const char *help, int *storage, int min, int max)
cpm_dma
int cpm_dma
Definition: bdos.c:27
fn
const char * fn
Definition: roms.c:42
xemucfg_parse_all
int xemucfg_parse_all(int argc, char **argv)
osd_init_with_defaults
int osd_init_with_defaults(void)
Definition: osd.c:131
stop_emulation
int stop_emulation
Definition: hardware.c:30
xemu_set_full_screen
void xemu_set_full_screen(int setting)
Definition: emutools.c:311
bios.h
trace
int trace
Definition: hardware.c:34
TARGET_NAME
#define TARGET_NAME
Definition: xemu-target.h:1
cpmfs_uninit
void cpmfs_uninit(void)
Definition: cpmfs.c:91
emutools_files.h
APP_ORG
#define APP_ORG
Definition: emutools.h:50
DEBUGPRINT
#define DEBUGPRINT(...)
Definition: emutools_basicdefs.h:171
syscon
int syscon
Definition: recpm.c:124
zoom
int zoom
Definition: recpm.c:125
modded
Uint8 modded[0x10000]
Definition: hardware.c:29
baud
int baud
Definition: recpm.c:126
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_timekeeping_start
void xemu_timekeeping_start(void)
Definition: emutools.c:1122
Z80_C
#define Z80_C
Definition: z80ex.h:80
configdb_st::syscon
int syscon
Definition: configdb.h:34
size
int size
Definition: inject.c:37
hardware.h
clear_emu_events
void clear_emu_events(void)
Definition: commodore_65.c:193
recpm.h
configdb_st::fullscreen
int fullscreen
Definition: configdb.h:34
Z80_PC
#define Z80_PC
Definition: z80ex.h:121
fullscreen
int fullscreen
Definition: recpm.c:124
cpmfs_mount_drive
int cpmfs_mount_drive(int drive, const char *dir_path, int dirbase_part_only)
Definition: cpmfs.c:101
console_init
int console_init(int width, int height, int zoom_percent, Uint8 *video_mapped, Uint8 *color_mapped, int sdlrenderquality)
Definition: console.c:279
term_width
int term_width
Definition: recpm.c:125
console_iteration
void console_iteration(void)
Definition: console.c:185
bios_install
void bios_install(int addr)
Definition: bios.c:31
xemucfg_define_switch_option
void xemucfg_define_switch_option(const char *optname, const char *help, int *storage)
term_height
int term_height
Definition: recpm.c:125
emu_cost_cycles
int emu_cost_cycles
Definition: hardware.c:30
conputs
void conputs(const char *s)
Definition: console.c:140
FATAL
#define FATAL(...)
Definition: xep128.h:117
cpmfs_init
void cpmfs_init(void)
Definition: cpmfs.c:67
console.h
XEMU_UNLIKELY
#define XEMU_UNLIKELY(__x__)
Definition: emutools_basicdefs.h:125
console_cursor_blink
void console_cursor_blink(int delay)
Definition: console.c:172
mapvideo
int mapvideo
Definition: recpm.c:127