OSDN Git Service

[VM][FMTOWNS][MEMORY] Fix setup around memory banks by I/O 0404h and 0480h.
[csp-qt/common_source_project-fm7.git] / source / src / emu_template.h
1 /*
2         Skelton for retropc emulator
3
4         Author : Kyuma.Ohta <whatisthis.sowhat _at_ gmail.com>
5         Date   : 2020.06.21 -
6
7         [ interface for emulation i/f ]
8 */
9 #pragma once
10
11 #include <stdio.h>
12 #include <assert.h>
13 #include "common.h"
14 #include "config.h"
15 // For UIs
16 #include "osdcall_types.h"
17
18 //#include "vm/vm_template.h"
19 #if defined(_USE_QT)
20 #include <memory>
21 #include <pthread.h>
22 #define OSD_QT
23 #elif defined(_USE_SDL)
24 #include <pthread.h>
25 #define OSD_SDL
26 #elif defined(_WIN32)
27 #define OSD_WIN32
28 #else
29 // oops!
30 #endif
31
32 class VM_TEMPLATE;
33 class EMU_TEMPLATE;
34
35 class FIFO;
36 class FILEIO;
37
38 #if defined(OSD_QT)
39 #include "qt/osd_base.h"
40 //class OSD_BASE;
41 class CSP_Logger;
42
43 class CSP_Debugger;
44 class CSP_DebuggerThread;
45
46 class USING_FLAGS;
47 class GLDrawClass;
48 class EmuThreadClass;
49 class DrawThreadClass;
50 #else
51 class OSD;
52 #endif
53
54 //struct bitmap_t;
55
56 #if defined(OSD_QT)
57 typedef struct {
58         EMU_TEMPLATE *emu;
59         OSD_BASE *osd;
60         VM_TEMPLATE *vm;
61         int cpu_index;
62         bool running;
63         bool request_terminate;
64 } debugger_thread_t;
65 #else
66 typedef struct {
67         EMU_TEMPLATE *emu;
68         OSD *osd;
69         VM_TEMPLATE *vm;
70         int cpu_index;
71         bool running;
72         bool request_terminate;
73 } debugger_thread_t;
74 #endif
75 class DLL_PREFIX EMU_TEMPLATE {
76 protected:
77         OSD_BASE* osd;
78 #if defined(OSD_QT)
79         std::shared_ptr<CSP_Logger> csp_logger;
80 #endif
81         _TCHAR app_path[_MAX_PATH];
82         // misc
83         int sound_frequency, sound_latency;
84         int sound_rate, sound_samples;
85
86         int cpu_type;
87         uint32_t dipswitch;
88         int sound_type;
89         int printer_type;
90         int serial_type;
91
92         bool now_suspended;
93         // input
94         FIFO* auto_key_buffer;
95         int auto_key_phase, auto_key_shift;
96         bool shift_pressed;
97
98         uint32_t joy_status[4];
99
100         typedef struct {
101                 _TCHAR path[_MAX_PATH];
102                 bool play;
103                 int bank;
104                 int wait_count;
105         } media_status_t;
106
107         media_status_t cart_status[16];
108         media_status_t floppy_disk_status[16];
109         media_status_t quick_disk_status[16];
110         media_status_t hard_disk_status[16];
111         media_status_t tape_status[16];
112         media_status_t compact_disc_status[16];
113         media_status_t laser_disc_status[16];
114         media_status_t bubble_casette_status[16];
115
116 private:
117         uint8_t dummy_key_buffer[256];
118         uint32_t dummy_joy_buffer[8];
119         int dummy_mouse_buffer[4];
120 public:
121         // ----------------------------------------
122         // initialize
123         // ---------------------------------------
124 #if defined(OSD_QT)
125         EMU_TEMPLATE(class Ui_MainWindow *hwnd, GLDrawClass *hinst, std::shared_ptr<CSP_Logger> p_logger, std::shared_ptr<USING_FLAGS> p)
126 #elif defined(OSD_WIN32)
127         EMU_TEMPLATE(HWND hwnd, HINSTANCE hinst)
128 #else
129         EMU_TEMPLATE()
130 #endif
131         {
132                 memset(dummy_key_buffer, 0x00, sizeof(dummy_key_buffer));
133                 memset(dummy_joy_buffer, 0x00, sizeof(dummy_joy_buffer));
134                 memset(dummy_mouse_buffer, 0x00, sizeof(dummy_mouse_buffer));
135                 memset(message, 0x00, sizeof(message));
136
137                 now_debugging = false;
138                 memset(&debugger_thread_param, 0x00, sizeof(debugger_thread_t));
139
140                 memset(app_path, 0x00, sizeof(app_path));
141
142                 sound_frequency = 44100;
143                 sound_latency = 100;
144                 sound_rate = 44100;
145                 sound_samples = 4410;
146
147                 cpu_type = 0;
148                 dipswitch = 0x00000000;
149                 sound_type = 0;
150                 printer_type = 0;
151                 serial_type = 0;
152
153                 now_suspended = false;
154
155                 auto_key_buffer = NULL;
156                 auto_key_phase = 0;
157                 auto_key_shift = 0;
158                 shift_pressed = false;
159
160                 memset(joy_status, 0x00, sizeof(joy_status));
161                 for(int i = 0; i < 16; i++) {
162                         memset(&(cart_status[i]), 0x00, sizeof(media_status_t));
163                         memset(&(floppy_disk_status[i]), 0x00, sizeof(media_status_t));
164                         memset(&(quick_disk_status[i]), 0x00, sizeof(media_status_t));
165                         memset(&(hard_disk_status[i]), 0x00, sizeof(media_status_t));
166                         memset(&(tape_status[i]), 0x00, sizeof(media_status_t));
167                         memset(&(compact_disc_status[i]), 0x00, sizeof(media_status_t));
168                         memset(&(laser_disc_status[i]), 0x00, sizeof(media_status_t));
169                         memset(&(bubble_casette_status[i]), 0x00, sizeof(media_status_t));
170                 }
171
172 #if defined(OSD_QT)
173                 csp_logger = p_logger;
174                 debugger_thread_id = (pthread_t)0;
175
176                 // ToDo: Multiple debugger 20221105 K.O
177                 hDebugger.reset();
178 #elif defined(OSD_WIN32)
179                 hDebuggerThread = (HANDLE)0;
180 #else
181                 debugger_thread_id = 0;
182 #endif
183
184                 message_count = 0;
185                 debug_log = NULL;
186         }
187         virtual ~EMU_TEMPLATE() {}
188
189         // ----------------------------------------
190         // for windows
191         // ----------------------------------------
192         virtual VM_TEMPLATE *get_vm() { return NULL; }
193         virtual OSD_BASE *get_osd() { return NULL; }
194
195 #ifdef OSD_QT
196         // qt dependent
197         virtual EmuThreadClass *get_parent_handler() { return NULL; }
198         virtual void set_parent_handler(EmuThreadClass *p, DrawThreadClass *q) {}
199         virtual void set_host_cpus(int v) {}
200         virtual int get_host_cpus() { return 1; }
201 #endif
202         virtual double get_frame_rate() { return 59.94; }
203         virtual int get_frame_interval() { return 1; }
204         virtual bool is_frame_skippable() { return false; }
205         virtual const bool is_use_state() { return false; }
206
207         virtual int run() { return 1; }
208
209         virtual void reset() {}
210         virtual void special_reset(int num) {}
211         virtual void notify_power_off() {}
212         virtual void power_off() {}
213         virtual void suspend() {}
214
215         // around locking VM, these are useful for multi-threaded environment.
216         virtual void lock_vm() {}
217         virtual void unlock_vm() {}
218         virtual void force_unlock_vm() {}
219         virtual bool is_vm_locked() { return false; }
220
221         // input
222         // around Keyboard.
223         virtual void key_down(int code, bool extended, bool repeat) {}
224         virtual void key_up(int code, bool extended) {}
225         virtual void key_char(char code) {}
226
227         virtual bool get_caps_locked() { return false; }
228         virtual bool get_kana_locked() { return false; }
229         virtual void key_lost_focus() {}
230         virtual void press_button(int num) {}
231
232         // Auto Key
233         virtual void set_auto_key_list(char *buf, int size) {}
234         virtual void set_auto_key_char(char code) {}
235         virtual void start_auto_key() {}
236         virtual void stop_auto_key() {}
237         virtual bool is_auto_key_running() { return false; }
238         virtual FIFO* get_auto_key_buffer() { return NULL; }
239         // Keyboard
240         virtual const uint8_t* get_key_buffer() { return dummy_key_buffer; }
241         // Joystick buffer should be with locking and sampling.
242         virtual const uint32_t* get_joy_buffer() { return dummy_joy_buffer; }
243         virtual void release_joy_buffer(const uint32_t* ptr) { };
244
245         // Mouse buffer should be with locking and sampling.
246         virtual const int32_t* get_mouse_buffer() { return dummy_mouse_buffer; }
247         virtual const int32_t  get_mouse_button() { return 0; }
248         virtual void release_mouse_buffer(const int32_t* ptr) { };
249         virtual void enable_mouse() {}
250         virtual void disable_mouse() {}
251         virtual void toggle_mouse() {}
252         virtual bool is_mouse_enabled() { return false; }
253
254         // screen
255         virtual double get_window_mode_power(int mode) { return 1.0; }
256         virtual int get_window_mode_width(int mode) { return 640; }
257         virtual int get_window_mode_height(int mode) { return 200; }
258         virtual void set_host_window_size(int window_width, int window_height,
259                                                                           bool window_mode) {}
260         virtual void set_vm_screen_size(int screen_width, int screen_height,
261                                                                         int window_width, int window_height,
262                                                                         int window_width_aspect, int window_height_aspect) {}
263         virtual void set_vm_screen_lines(int lines) {}
264         virtual int get_vm_window_width() { return 640; }
265         virtual int get_vm_window_height() { return 200; }
266         virtual int get_vm_window_width_aspect() { return 640; }
267         virtual int get_vm_window_height_aspect() { return 200; }
268         virtual bool is_screen_changed() { return true; }
269         virtual int draw_screen() { return 1; }
270         virtual scrntype_t* get_screen_buffer(int y) { return NULL;}
271         virtual void screen_skip_line(bool skip_line) {}
272
273         // One-board-micro-computer
274         virtual void get_invalidated_rect(int *left, int *top, int *right, int *bottom) {}
275         virtual void reload_bitmap() {}
276
277 #ifdef OSD_WIN32
278         virtual void invalidate_screen() {}
279         virtual void update_screen(HDC hdc) {}
280 #endif
281         // Screen capture and recording.Will update API.
282         virtual void capture_screen() {}
283         virtual bool start_record_video(int fps) { return false;}
284         virtual void stop_record_video() {}
285         virtual bool is_video_recording() { return false; }
286
287         // sound
288         virtual int get_sound_rate() { return 44100; }
289         virtual void mute_sound() {}
290         virtual void start_record_sound() {}
291         virtual void stop_record_sound() {}
292         virtual bool is_sound_recording() { return false; }
293
294         // video device
295         virtual void get_video_buffer() {}
296         virtual void mute_video_dev(bool l, bool r) {}
297
298         // Movie player.
299         virtual bool open_movie_file(const _TCHAR* file_path) { return false; }
300         virtual void close_movie_file() {}
301         virtual void play_movie() {}
302         virtual void stop_movie() {}
303         virtual void pause_movie() {}
304         virtual double get_movie_frame_rate() { return 29.97; }
305         virtual int get_movie_sound_rate() { return 44100; }
306         virtual void set_cur_movie_frame(int frame, bool relative) {}
307         virtual uint32_t get_cur_movie_frame() { return 0; }
308
309         // Capturing video.
310         virtual int get_cur_capture_dev_index() { return 0; }
311         virtual int get_num_capture_devs() { return 0; }
312         virtual _TCHAR* get_capture_dev_name(int index) { return (_TCHAR*)_T("DUMMY"); }
313         virtual void open_capture_dev(int index, bool pin) {}
314         virtual void close_capture_dev() {}
315         virtual void show_capture_dev_filter() {}
316         virtual void show_capture_dev_pin() {}
317         virtual void show_capture_dev_source() {}
318         virtual void set_capture_dev_channel(int ch) {}
319
320         // Printer
321         virtual void create_bitmap(bitmap_t *bitmap, int width, int height) {}
322         virtual void release_bitmap(bitmap_t *bitmap) {}
323         virtual void create_font(font_t *font,
324                                                          const _TCHAR *family,
325                                                          int width, int height,
326                                                          int rotate, bool bold, bool italic) {}
327         virtual void release_font(font_t *font) {}
328         virtual void create_pen(pen_t *pen, int width,
329                                                         uint8_t r, uint8_t g, uint8_t b) {}
330         virtual void release_pen(pen_t *pen) {}
331         virtual void clear_bitmap(bitmap_t *bitmap,
332                                                           uint8_t r, uint8_t g, uint8_t b) {}
333         virtual int get_text_width(bitmap_t *bitmap,
334                                                            font_t *font, const char *text) { return 16; }
335         virtual void draw_text_to_bitmap(bitmap_t *bitmap, font_t *font,
336                                                                          int x, int y, const char *text,
337                                                                          uint8_t r, uint8_t g, uint8_t b) {}
338         virtual void draw_line_to_bitmap(bitmap_t *bitmap, pen_t *pen,
339                                                                          int sx, int sy, int ex, int ey) {}
340         virtual void draw_rectangle_to_bitmap(bitmap_t *bitmap,
341                                                                                   int x, int y,
342                                                                                   int width, int height,
343                                                                                   uint8_t r, uint8_t g, uint8_t b) {}
344         virtual void draw_point_to_bitmap(bitmap_t *bitmap,
345                                                                           int x, int y,
346                                                                           uint8_t r, uint8_t g, uint8_t b) {}
347         virtual void stretch_bitmap(bitmap_t *dest, int dest_x, int dest_y,
348                                                                 int dest_width, int dest_height,
349                                                                 bitmap_t *source,
350                                                                 int source_x, int source_y, int source_width,
351                                                                 int source_height) {}
352         virtual void write_bitmap_to_file(bitmap_t *bitmap, const _TCHAR *file_path) {}
353
354         // socket
355         virtual SOCKET get_socket(int ch) { return (SOCKET)0; }
356         virtual void notify_socket_connected(int ch) {}
357         virtual void notify_socket_disconnected(int ch) {}
358         virtual bool initialize_socket_tcp(int ch) { return false; }
359         virtual bool initialize_socket_udp(int ch) { return false; }
360
361         virtual bool connect_socket(int ch, uint32_t ipaddr, int port) {return false;}
362         virtual void disconnect_socket(int ch) {}
363
364         virtual bool listen_socket(int ch) { return false; }
365         virtual void send_socket_data_tcp(int ch) {}
366         virtual void send_socket_data_udp(int ch, uint32_t ipaddr, int port) {}
367
368         virtual void send_socket_data(int ch) {}
369         virtual void recv_socket_data(int ch) {}
370
371         // MIDI
372         // Note: OSD's API will be different from upstream.
373         //       Because, will use libPortMidi to access devices,
374         //       seems to need timestamp (to send data).
375         //       See, https://portmedia.sourceforge.net/portmidi/ .
376         //       Optionally, set timestamp for relative usec at VM.
377         // 20230118 K.O
378         virtual void __FASTCALL send_to_midi(uint8_t data, int ch = 0, double timestamp_usec = 0.0) {}
379         virtual bool __FASTCALL recv_from_midi(uint8_t* data, int ch = 0, double timestamp_usec = 0.0) { return false; }
380
381         // Send / Receive with timeout.
382         // If timeout (no connection) , OSD calls EMU::notify_timeout_*_midi(ch) .
383         // If Success to communication, OSD calls ready_*_midi(ch, timestamp).
384         virtual bool __FASTCALL send_to_midi_timeout(uint8_t data, int ch = 0, uint64_t timeout_ms = 0, double timestamp_usec = 0.0) { return true; /* dummy send. */ }
385         virtual bool __FASTCALL recv_from_midi_timeout(uint8_t* data, int ch = 0, uint64_t timeout_ms = 0, double timestamp_usec = 0.0) { return false; }
386
387         //virtual void __FASTCALL notify_timeout_sending_to_midi(int ch = 0) {}
388         //virtual void __FASTCALL notify_timeout_receiving_from_midi(int ch = 0) {}
389
390         // Reset physical midi device(s). nagative value will reset all.
391         virtual void __FASTCALL reset_to_midi(int ch = -1, double timestamp_usec = 0.0) {}
392         // Belows are interface between osd and vm/devices.
393         // Some interface devices on VM may have handshake (maybe via UART).
394         virtual void __FASTCALL initialize_midi_device(bool handshake_from_midi = false,
395                                                                                                    bool handshake_to_midi = false,
396                                                                                                    int ch = 0)
397         {}
398         //virtual void __FASTCALL ready_receive_from_midi(int ch = 0, double timestamp_usec = 0.0) {}
399         virtual void __FASTCALL ready_send_to_midi(int ch = 0, double timestamp_usec = 0.0) {}
400         virtual void __FASTCALL request_stop_to_receive_from_midi(int ch = 0, double timestamp_usec = 0.0) {}
401         //virtual void __FASTCALL request_stop_to_send_to_midi(int ch = 0, double timestamp_usec = 0.0) {}
402
403         // debugger
404         virtual void initialize_debugger() { }
405         virtual void release_debugger() { }
406
407         virtual void open_debugger(int cpu_index) {}
408         virtual void close_debugger(int cpu_index) {}
409         virtual bool is_debugger_enabled(int cpu_index) { return false; }
410
411         bool now_debugging;
412         int debugger_cpu_index, debugger_target_id;
413         int request_save_state, request_load_state;
414         debugger_thread_t debugger_thread_param;
415
416 #if defined(OSD_QT)
417         // ToDo: Multiple debugger 20221105 K.O
418         pthread_t debugger_thread_id;
419         std::shared_ptr<CSP_Debugger>hDebugger;
420 #elif defined(OSD_WIN32)
421         HANDLE hDebuggerThread;
422 #else
423         int debugger_thread_id;
424 #endif
425
426         virtual void start_waiting_in_debugger() {}
427         virtual void finish_waiting_in_debugger() {}
428         virtual void process_waiting_in_debugger() {}
429         bool now_waiting_in_debugger;
430
431         // debug log
432         virtual void out_debug_log(const _TCHAR* format, ...) {}
433         virtual void force_out_debug_log(const _TCHAR* format, ...) {}
434
435         virtual void out_message(const _TCHAR* format, ...) {}
436         int message_count;
437         _TCHAR message[1024];
438
439         // misc
440         virtual void sleep(uint32_t ms) {}
441
442         // debug log
443         virtual void initialize_debug_log() {}
444         virtual void release_debug_log() {}
445         FILE* debug_log;
446
447         // media
448         // floppy disk
449         struct {
450                 _TCHAR path[_MAX_PATH];
451                 _TCHAR disk_name[64][128];  // Convert to UTF8
452                 int bank_num;
453                 int cur_bank;
454         } d88_file[16];
455         virtual bool create_blank_floppy_disk(const _TCHAR* file_path, uint8_t type) { return false;}
456         virtual void open_floppy_disk(int drv, const _TCHAR* file_path, int bank) {}
457         virtual void close_floppy_disk(int drv) {}
458         virtual bool is_floppy_disk_connected(int drv) { return false;}
459         virtual bool is_floppy_disk_inserted(int drv) { return false;}
460         virtual void is_floppy_disk_protected(int drv, bool value) {}
461         virtual bool is_floppy_disk_protected(int drv) { return false;}
462         virtual uint32_t is_floppy_disk_accessed() { return 0x00000000; }
463         virtual uint32_t floppy_disk_indicator_color() { return 0x00000000; }
464
465         // cartridge
466         virtual void open_cart(int drv, const _TCHAR* file_path) {}
467         virtual void close_cart(int drv) {}
468         virtual bool is_cart_inserted(int drv) { return false; }
469
470         // quick disk
471         virtual void open_quick_disk(int drv, const _TCHAR* file_path) {}
472         virtual void close_quick_disk(int drv) {}
473         virtual bool is_quick_disk_connected(int drv) { return false; }
474         virtual bool is_quick_disk_inserted(int drv) { return false; }
475         virtual uint32_t is_quick_disk_accessed() { return 0x00000000; }
476         virtual bool get_quick_disk_status(int drive, _TCHAR* media_name, size_t buflen, bool& play, int& wait_count, int& cur_bank)
477         {
478                 return false;
479         }
480         virtual void is_quick_disk_protected(int drv, bool value) { }
481         virtual bool is_quick_disk_protected(int drv) { return false;}
482
483         // hard disk
484         virtual bool create_blank_hard_disk(const _TCHAR* file_path,
485                                                                                 int sector_size, int sectors,
486                                                                                 int surfaces, int cylinders) { return false; }
487         virtual void open_hard_disk(int drv, const _TCHAR* file_path) {}
488         virtual void close_hard_disk(int drv) {}
489         virtual bool is_hard_disk_inserted(int drv) { return false; }
490         virtual uint32_t is_hard_disk_accessed() { return 0x00000000; }
491         virtual bool get_hard_disk_status(int drive, _TCHAR* media_name, size_t buflen, bool& play, int& wait_count, int& cur_bank)
492         {
493                 return false;
494         }
495
496         // tape (CMT)
497         virtual void play_tape(int drv, const _TCHAR* file_path) {}
498         virtual void rec_tape(int drv, const _TCHAR* file_path) {}
499         virtual void close_tape(int drv) {}
500         virtual bool is_tape_inserted(int drv) { return false; }
501         virtual bool is_tape_playing(int drv) { return false; }
502         virtual bool is_tape_recording(int drv) { return false; }
503         virtual int get_tape_position(int drv) { return 0; }
504         virtual const _TCHAR* get_tape_message(int drv) { return _T(" "); }
505         virtual void push_play(int drv) {}
506         virtual void push_stop(int drv) {}
507         virtual void push_fast_forward(int drv) {}
508         virtual void push_fast_rewind(int drv) {}
509         virtual void push_apss_forward(int drv) {}
510         virtual void push_apss_rewind(int drv) {}
511
512         // compact disc (CD)
513         virtual void open_compact_disc(int drv, const _TCHAR* file_path) {}
514         virtual void close_compact_disc(int drv) {}
515         virtual bool is_compact_disc_inserted(int drv)  { return false; }
516         virtual uint32_t is_compact_disc_accessed() { return 0x00000000; }
517
518         // laser disc (LD)
519         virtual void open_laser_disc(int drv, const _TCHAR* file_path) {}
520         virtual void close_laser_disc(int drv) {}
521         virtual bool is_laser_disc_inserted(int drv)  { return false; }
522         virtual uint32_t is_laser_disc_accessed() { return 0x00000000; }
523
524         // binary file (memory image)
525         virtual void load_binary(int drv, const _TCHAR* file_path) {}
526         virtual void save_binary(int drv, const _TCHAR* file_path) {}
527
528         // bubble casette
529         struct {
530                 _TCHAR path[_MAX_PATH];
531                 _TCHAR bubble_name[16][128];  // Convert to UTF8
532                 int bank_num;
533                 int cur_bank;
534         } b77_file[16];
535         virtual void open_bubble_casette(int drv, const _TCHAR* file_path, int bank) {}
536         virtual void close_bubble_casette(int drv) {}
537         virtual bool is_bubble_casette_inserted(int drv) { return false; }
538         virtual bool is_bubble_casette_protected(int drv) { return false; }
539         virtual void is_bubble_casette_protected(int drv, bool value) {}
540
541         // LED device
542         virtual uint32_t get_led_status() { return 0x00000000; }
543
544         // sound volume
545         virtual void set_sound_device_volume(int ch, int decibel_l, int decibel_r) {}
546
547         // configure
548         virtual void update_config() {}
549
550         // state
551         virtual void save_state(const _TCHAR* file_path) {}
552         virtual void load_state(const _TCHAR* file_path) {}
553         virtual const _TCHAR *state_file_path(int num) { return (const _TCHAR*)_T("."); }
554
555         // messaging proxies.
556         // These are mostly used for replying mounting virtual media.
557         // 20230125 K.O
558         virtual void __FASTCALL osdcall_string(EMU_MEDIA_TYPE::type_t media_type, int drive,  EMU_MESSAGE_TYPE::type_t message_type, _TCHAR* message) {}
559         virtual void __FASTCALL osdcall_int(EMU_MEDIA_TYPE::type_t media_type, int drive,  EMU_MESSAGE_TYPE::type_t message_type, int64_t data) { }
560
561 };