OSDN Git Service

[VM][FAMILYBASIC][WIP] Fix wrong string for romaji-kana (and auto key).Still imcoplet...
[csp-qt/common_source_project-fm7.git] / source / src / vm / familybasic / familybasic.h
1 /*
2         Nintendo Family BASIC Emulator 'eFamilyBASIC'
3
4         Origin : nester
5         Author : Takeda.Toshiya
6         Date   : 2010.08.11-
7
8         [ virtual machine ]
9 */
10
11 #ifndef _FAMILYBASIC_H_
12 #define _FAMILYBASIC_H_
13
14 #define DEVICE_NAME             "Nintendo Family BASIC"
15 #define CONFIG_NAME             "familybasic"
16
17 // device informations for virtual machine
18 #define FRAMES_PER_SEC          59.98
19 //#define LINES_PER_FRAME       262
20 #define LINES_PER_FRAME         525 // 262.5*2
21 #define CPU_CLOCKS              1789772
22 #define SCREEN_WIDTH            256
23 #define SCREEN_HEIGHT           240
24 // pixel aspect should be 8:7
25 #define WINDOW_HEIGHT_ASPECT    210
26 #define HAS_N2A03
27
28 // device informations for win32
29 #define SUPPORT_TV_RENDER
30 #define USE_BOOT_MODE           6
31 #define USE_TAPE                1
32 #define USE_AUTO_KEY            5
33 #define USE_AUTO_KEY_RELEASE    8
34 #define USE_AUTO_KEY_NO_CAPS
35 #define USE_SOUND_VOLUME        4
36 #define USE_JOYSTICK
37 #define USE_JOY_BUTTON_CAPTIONS
38 #define USE_DEBUGGER
39 #define USE_STATE
40 #define USE_CPU_N2A03
41 #define USE_VM_AUTO_KEY_TABLE
42 #define USE_TWO_STROKE_AUTOKEY_HANDAKUON
43 #define USE_TWO_STROKE_AUTOKEY_DAKUON
44
45 #include "../../common.h"
46 #include "../../fileio.h"
47 #include "../vm_template.h"
48
49 #ifdef USE_SOUND_VOLUME
50 static const _TCHAR *sound_device_caption[] = {
51         _T("APU"), _T("VRC7"), _T("CMT (Signal)"), _T("Noise (CMT)"),
52 };
53 #endif
54
55 #ifdef USE_JOY_BUTTON_CAPTIONS
56 static const _TCHAR *joy_button_captions[] = {
57         _T("Up"),
58         _T("Down"),
59         _T("Left"),
60         _T("Right"),
61         _T("Button #1"),
62         _T("Button #2"),
63         _T("Select"),
64         _T("Start"),
65 };
66 #endif
67
68 #ifdef USE_VM_AUTO_KEY_TABLE
69 static const int vm_auto_key_table_base[][2] = {
70         // A,I,U,E,O -> 1,2,3,4,5
71         {0xb1, 0x200 | 0x31},
72         {0xb2, 0x200 | 0x32},
73         {0xb3, 0x200 | 0x33},
74         {0xb4, 0x200 | 0x34},
75         {0xb5, 0x200 | 0x35},
76         // KA,KI,KU,KE,KO -> Q,W,E,R,T
77         {0xb6, 0x200 | ((int)'Q')},
78         {0xb7, 0x200 | ((int)'W')},
79         {0xb8, 0x200 | ((int)'E')},
80         {0xb9, 0x200 | ((int)'R')},
81         {0xba, 0x200 | ((int)'T')},
82         // SA,SI,SU,SE,SO -> A,S,D,F,G
83         {0xbb, 0x200 | ((int)'A')},
84         {0xbc, 0x200 | ((int)'S')},
85         {0xbd, 0x200 | ((int)'D')},
86         {0xbe, 0x200 | ((int)'F')},
87         {0xbf, 0x200 | ((int)'G')},
88         // TA,TI,TU,TE,TO -> Z, X, C, V, B
89         {0xc0, 0x200 | ((int)'Z')},
90         {0xc1, 0x200 | ((int)'X')},
91         {0xc2, 0x200 | ((int)'C')},
92         {0xc3, 0x200 | ((int)'V')},
93         {0xc4, 0x200 | ((int)'B')},
94         // NA,NI,NU,NE,NO -> 6,7,8,9,0
95         {0xc5, 0x200 | 0x36},
96         {0xc6, 0x200 | 0x37},
97         {0xc7, 0x200 | 0x38},
98         {0xc8, 0x200 | 0x39},
99         {0xc9, 0x200 | 0x30},
100         // HA,HI,HU,HE,HO -> Y,U,I,O,P
101         {0xca, 0x200 | ((int)'Y')},
102         {0xcb, 0x200 | ((int)'U')},
103         {0xcc, 0x200 | ((int)'I')},
104         {0xcd, 0x200 | ((int)'O')},
105         {0xce, 0x200 | ((int)'P')},
106         // MA,MI,MU,ME,MO -> H,J,K,L,;
107         {0xcf, 0x200 | ((int)'H')},
108         {0xd0, 0x200 | ((int)'J')},
109         {0xd1, 0x200 | ((int)'K')},
110         {0xd2, 0x200 | ((int)'L')},
111         {0xd3, 0x200 | ((int)';')},
112         // YA,YU,YO,WA,W0,NN -> N,M,,,.,/,_
113         {0xd4, 0x200 | ((int)'N')},
114         {0xd5, 0x200 | ((int)'M')},
115         {0xd6, 0x200 | 0xbc},
116         {0xdc, 0x200 | 0xbe},
117         {0xa6, 0x200 | 0xbf},
118         {0xdd, 0x200 | 0xe2},
119         // RA,RI,RU,RE,RO -> -, ^, ¥, @, [
120         {0xd7, 0x200 | 0xbd},
121         {0xd8, 0x200 | 0xde},
122         {0xd9, 0x200 | 0xdc},
123         {0xda, 0x200 | 0xc0},
124         {0xdb, 0x200 | 0xdb},
125         // XA,XI,XU,XE,XO -> SHIFT+1, SHIFT+2, SHIFT+3, SHIFT+4, SHIFT+5
126         {0xa7, 0x300 | 0x31},
127         {0xa8, 0x300 | 0x32},
128         {0xa9, 0x300 | 0x33},
129         {0xaa, 0x300 | 0x34},
130         {0xab, 0x300 | 0x35},
131         // XYA,XYU,XYO -> SHIFT+N,SHIFT+M,SHIFT+,
132         {0xac, 0x300 | ((int)'N')},
133         {0xad, 0x300 | ((int)'M')},
134         {0xae, 0x300 | 0xbc},
135         // XTU -> SHIFT + C
136         {0xaf, 0x300 | ((int)'C')},
137         // _, MARU -> :, ]
138         {0x5f, 0x200 | 0xbd},
139         {0xa1, 0x200 | 0xdd},
140         // KAGIKAKKO
141         {0xa2, 0x300 | 0xbd},
142         {0xa3, 0x300 | 0xdd},
143         // '゙' -> Double Quotation
144 //      {0xde,  0x100 | 0x32},  
145         {-1, -1}
146 };
147 #endif
148 #ifdef USE_TWO_STROKE_AUTOKEY_HANDAKUON
149 static const int kana_handakuon_keyboard_table[][6] = {
150         // PA,PI,PU,PE,PO -> Y,U,I,O,P
151         {0xca, 0x300 | ((int)'Y'), 0x00, 0x00, 0x00, 0x00},
152         {0xcb, 0x300 | ((int)'U'), 0x00, 0x00, 0x00, 0x00},
153         {0xcc, 0x300 | ((int)'I'), 0x00, 0x00, 0x00, 0x00},
154         {0xcd, 0x300 | ((int)'O'), 0x00, 0x00, 0x00, 0x00},
155         {0xce, 0x300 | ((int)'P'), 0x00, 0x00, 0x00, 0x00},
156         {-1, -1}
157 };
158 #endif
159 #ifdef USE_TWO_STROKE_AUTOKEY_DAKUON
160 static const int kana_dakuon_keyboard_table[][6] = {
161         // GA,GI,GU,GE,GO -> Q,W,E,R,T
162         {0xb6, 0x1000 | 0x12, 0x200 | ((int)'Q'), 0x2000 | 0x12, 0x00, 0x00},
163         {0xb7, 0x1000 | 0x12, 0x200 | ((int)'W'), 0x2000 | 0x12, 0x00, 0x00},
164         {0xb8, 0x1000 | 0x12, 0x200 | ((int)'E'), 0x2000 | 0x12, 0x00, 0x00},
165         {0xb9, 0x1000 | 0x12, 0x200 | ((int)'R'), 0x2000 | 0x12, 0x00, 0x00},
166         {0xba, 0x1000 | 0x12, 0x200 | ((int)'T'), 0x2000 | 0x12, 0x00, 0x00},
167         // ZA,ZI,ZU,ZE,ZO -> A,S,D,F,G
168         {0xbb, 0x1000 | 0x12, 0x200 | ((int)'A'), 0x2000 | 0x12, 0x00, 0x00},
169         {0xbc, 0x1000 | 0x12, 0x200 | ((int)'S'), 0x2000 | 0x12, 0x00, 0x00},
170         {0xbd, 0x1000 | 0x12, 0x200 | ((int)'D'), 0x2000 | 0x12, 0x00, 0x00},
171         {0xbe, 0x1000 | 0x12, 0x200 | ((int)'F'), 0x2000 | 0x12, 0x00, 0x00},
172         {0xbf, 0x1000 | 0x12, 0x200 | ((int)'G'), 0x2000 | 0x12, 0x00, 0x00},
173         // DA,DI,DU,DE,DO -> Z, X, C, V, B
174         {0xc0, 0x1000 | 0x12, 0x200 | ((int)'Z'), 0x2000 | 0x12, 0x00, 0x00},
175         {0xc1, 0x1000 | 0x12, 0x200 | ((int)'X'), 0x2000 | 0x12, 0x00, 0x00},
176         {0xc2, 0x1000 | 0x12, 0x200 | ((int)'C'), 0x2000 | 0x12, 0x00, 0x00},
177         {0xc3, 0x1000 | 0x12, 0x200 | ((int)'V'), 0x2000 | 0x12, 0x00, 0x00},
178         {0xc4, 0x1000 | 0x12, 0x200 | ((int)'B'), 0x2000 | 0x12, 0x00, 0x00},
179         // BA,BI,BU,BE,BO -> Y,U,I,O,P
180         {0xca, 0x1000 | 0x12, 0x200 | ((int)'Y'), 0x2000 | 0x12, 0x00, 0x00},
181         {0xcb, 0x1000 | 0x12, 0x200 | ((int)'U'), 0x2000 | 0x12, 0x00, 0x00},
182         {0xcc, 0x1000 | 0x12, 0x200 | ((int)'I'), 0x2000 | 0x12, 0x00, 0x00},
183         {0xcd, 0x1000 | 0x12, 0x200 | ((int)'O'), 0x2000 | 0x12, 0x00, 0x00},
184         {0xce, 0x1000 | 0x12, 0x200 | ((int)'P'), 0x2000 | 0x12, 0x00, 0x00},
185         {-1, -1}
186 };
187 #endif
188         
189 typedef struct header_s {
190         uint8_t id[3];  // 'NES'
191         uint8_t ctrl_z; // control-z
192         uint8_t dummy;
193         uint8_t num_8k_vrom_banks;
194         uint8_t flags_1;
195         uint8_t flags_2;
196         uint8_t reserved[8];
197         uint32_t num_16k_rom_banks()
198         {
199                 return (dummy != 0) ? dummy : 256;
200         }
201         uint32_t num_8k_rom_banks()
202         {
203                 return num_16k_rom_banks() * 2;
204         }
205         uint8_t mapper()
206         {
207                 return (flags_1 >> 4) | (flags_2 & 0xf0);
208         }
209 } header_t;
210
211 class EMU;
212 class DEVICE;
213 class EVENT;
214
215 class DATAREC;
216 class N2A03;
217 class YM2413;
218
219 namespace FAMILYBASIC {
220         class MEMORY;
221         class APU;
222         class PPU;
223 }
224
225 class VM : public VM_TEMPLATE
226 {
227 protected:
228         //EMU* emu;
229         //csp_state_utils* state_entry;
230         
231         // devices
232         //EVENT* event;
233         
234         DATAREC* drec;
235         N2A03* cpu;
236         YM2413* opll;
237         
238         FAMILYBASIC::MEMORY* memory;
239         FAMILYBASIC::APU* apu;
240         FAMILYBASIC::PPU* ppu;
241         
242         int boot_mode;
243         
244 public:
245         // ----------------------------------------
246         // initialize
247         // ----------------------------------------
248         
249         VM(EMU* parent_emu);
250         ~VM();
251         
252         // ----------------------------------------
253         // for emulation class
254         // ----------------------------------------
255         
256         // drive virtual machine
257         void reset();
258         void run();
259         double get_frame_rate()
260         {
261                 return FRAMES_PER_SEC;
262         }
263         
264 #ifdef USE_DEBUGGER
265         // debugger
266         DEVICE *get_cpu(int index);
267 #endif
268         
269         // draw screen
270         void draw_screen();
271         
272         // sound generation
273         void initialize_sound(int rate, int samples);
274         uint16_t* create_sound(int* extra_frames);
275         int get_sound_buffer_ptr();
276 #ifdef USE_SOUND_VOLUME
277         void set_sound_device_volume(int ch, int decibel_l, int decibel_r);
278 #endif
279         
280         // user interface
281         void play_tape(int drv, const _TCHAR* file_path);
282         void rec_tape(int drv, const _TCHAR* file_path);
283         void close_tape(int drv);
284         bool is_tape_inserted(int drv);
285         bool is_tape_playing(int drv);
286         bool is_tape_recording(int drv);
287         int get_tape_position(int drv);
288         const _TCHAR* get_tape_message(int drv);
289         void push_play(int drv);
290         void push_stop(int drv);
291         void push_fast_forward(int drv);
292         void push_fast_rewind(int drv);
293         void push_apss_forward(int drv) {}
294         void push_apss_rewind(int drv) {}
295         bool is_frame_skippable();
296         
297         void update_config();
298         bool process_state(FILEIO* state_fio, bool loading);
299         
300         // ----------------------------------------
301         // for each device
302         // ----------------------------------------
303         
304         // devices
305         DEVICE* get_device(int id);
306         //DEVICE* dummy;
307         //DEVICE* first_device;
308         //DEVICE* last_device;
309 };
310
311 #endif