OSDN Git Service

[INITIAL] Import 20141226 version of http://homepage3.nifty.com/takeda-toshiya/common...
[csp-qt/common_source_project-fm7.git] / source / src / vm / fmr50 / bios.cpp
1 /*\r
2         FUJITSU FMR-30 Emulator 'eFMR-30'\r
3         FUJITSU FMR-50 Emulator 'eFMR-50'\r
4         FUJITSU FMR-60 Emulator 'eFMR-60'\r
5 \r
6         Author : Takeda.Toshiya\r
7         Date   : 2008.10.06 -\r
8 \r
9         [ bios ]\r
10 */\r
11 \r
12 #include "bios.h"\r
13 #include "../disk.h"\r
14 #include "../../fileio.h"\r
15 \r
16 // regs\r
17 #define AX      regs[0]\r
18 #define CX      regs[1]\r
19 #define DX      regs[2]\r
20 #define BX      regs[3]\r
21 #define SP      regs[4]\r
22 #define BP      regs[5]\r
23 #define SI      regs[6]\r
24 #define DI      regs[7]\r
25 \r
26 #define AL      regs8[0]\r
27 #define AH      regs8[1]\r
28 #define CL      regs8[2]\r
29 #define CH      regs8[3]\r
30 #define DL      regs8[4]\r
31 #define DH      regs8[5]\r
32 #define BL      regs8[6]\r
33 #define BH      regs8[7]\r
34 #define SPL     regs8[8]\r
35 #define SPH     regs8[9]\r
36 #define BPL     regs8[10]\r
37 #define BPH     regs8[11]\r
38 #define SIL     regs8[12]\r
39 #define SIH     regs8[13]\r
40 #define DIL     regs8[14]\r
41 #define DIH     regs8[15]\r
42 \r
43 // sregs\r
44 #define ES      sregs[0]\r
45 #define CS      sregs[1]\r
46 #define SS      sregs[2]\r
47 #define DS      sregs[3]\r
48 \r
49 // error\r
50 #define ERR_FDD_NOTREADY        1\r
51 #define ERR_FDD_PROTECTED       2\r
52 #define ERR_FDD_DELETED         4\r
53 #define ERR_FDD_NOTFOUND        8\r
54 #define ERR_FDD_CRCERROR        0x10\r
55 #define ERR_SCSI_NOTREADY       1\r
56 #define ERR_SCSI_PARAMERROR     2\r
57 #define ERR_SCSI_NOTCONNECTED   4\r
58 #define ERR_MEMCARD_NOTREADY    1\r
59 #define ERR_MEMCARD_PROTECTED   2\r
60 #define ERR_MEMCARD_PARAMERROR  0x200\r
61 \r
62 #if defined(_FMR30)\r
63 // FMR-30\r
64 #define CMOS_SIZE       0x2000\r
65 #define VRAM_SIZE       0x20000\r
66 #define IPL_SIZE        0x10000\r
67 #define IPL_ID          '2'\r
68 #elif defined(_FMR50)\r
69 // FMR-50\r
70 #define CMOS_SIZE       0x800\r
71 #define VRAM_SIZE       0x40000\r
72 #define IPL_SIZE        0x4000\r
73 #define IPL_ID          '1'\r
74 #elif defined(_FMR60)\r
75 // FMR-60\r
76 #define CMOS_SIZE       0x800\r
77 #define VRAM_SIZE       0x80000\r
78 #define IPL_SIZE        0x4000\r
79 #define IPL_ID          '1'\r
80 #endif\r
81 \r
82 #define BLOCK_SIZE      512\r
83 \r
84 static const int iotable[][2] = {\r
85 #ifdef _FMR30\r
86         {0x0100, 0x19}, // pic\r
87         {0x0101, 0x40},\r
88         {0x0101, 0x80},\r
89         {0x0101, 0x01},\r
90         {0x0101, 0xff},\r
91         {0x0108, 0x19},\r
92         {0x010a, 0x48},\r
93         {0x010a, 0x07},\r
94         {0x010a, 0x01},\r
95         {0x010a, 0xff},\r
96         {0x0042, 0x00}, // timer\r
97         {0x0133, 0x30},\r
98         {0x0130, 0xa0},\r
99         {0x0130, 0x86},\r
100         {0x000b, 0x02}, // sio\r
101         {0x0009, 0x00},\r
102         {0x0009, 0x50},\r
103         {0x0009, 0x7f},\r
104         {0x0009, 0x15},\r
105         {0x0013, 0x02},\r
106         {0x001d, 0x02}, // memory\r
107         {0x001e, 0x00},\r
108         {0x0040, 0x9f}, // psg\r
109         {0x0040, 0xbf},\r
110         {0x0040, 0xdf},\r
111         {0x0040, 0xff},\r
112         {0x0300, 0x01}, // lcdc\r
113         {0x0302, 0x50},\r
114         {0x0300, 0x09},\r
115         {0x0302, 0x0f},\r
116         {0x0300, 0x0a},\r
117         {0x0302, 0x20},\r
118         {0x0300, 0x0b},\r
119         {0x0302, 0x0d},\r
120         {0x0300, 0x0c},\r
121         {0x0302, 0x00},\r
122         {0x0300, 0x0d},\r
123         {0x0302, 0x00},\r
124         {0x0300, 0x0e},\r
125         {0x0302, 0x00},\r
126         {0x0300, 0x0f},\r
127         {0x0302, 0x00},\r
128         {0x0300, 0x11},\r
129         {0x0302, 0xc7},\r
130         {0x0300, 0x1d},\r
131         {0x0302, 0x00},\r
132         {0x0308, 0x63},\r
133         {0x0309, 0x00},\r
134         {0x030a, 0x00},\r
135 #else\r
136         {0x0060, 0x00}, // timer\r
137         {0x0604, 0x00}, // keyboard\r
138         {0x0000, 0x19}, // pic\r
139         {0x0002, 0x40},\r
140         {0x0002, 0x80},\r
141         {0x0002, 0x0d},\r
142         {0x0002, 0xfe},\r
143         {0x0010, 0x19},\r
144         {0x0012, 0x48},\r
145         {0x0012, 0x87},\r
146         {0x0012, 0x09},\r
147         {0x0012, 0xff},\r
148         {0x0000, 0x20},\r
149         {0x0046, 0x36}, // pit\r
150         {0x0040, 0x00},\r
151         {0x0040, 0x78},\r
152         {0x0404, 0x00}, // memory\r
153         {0x0500, 0x00}, // crtc\r
154         {0x0502, 0x35},\r
155         {0x0500, 0x01},\r
156         {0x0502, 0x28},\r
157         {0x0500, 0x02},\r
158         {0x0502, 0x2c},\r
159         {0x0500, 0x03},\r
160         {0x0502, 0x04},\r
161         {0x0500, 0x04},\r
162         {0x0502, 0x1a},\r
163         {0x0500, 0x05},\r
164         {0x0502, 0x08},\r
165         {0x0500, 0x06},\r
166         {0x0502, 0x19},\r
167         {0x0500, 0x07},\r
168         {0x0502, 0x19},\r
169         {0x0500, 0x08},\r
170         {0x0502, 0x00},\r
171         {0x0500, 0x09},\r
172         {0x0502, 0x0f},\r
173         {0x0500, 0x0a},\r
174         {0x0502, 0x20},\r
175         {0x0500, 0x0b},\r
176         {0x0502, 0x1e},\r
177         {0x0500, 0x0c},\r
178         {0x0502, 0x00},\r
179         {0x0500, 0x0d},\r
180         {0x0502, 0x00},\r
181         {0x0500, 0x0e},\r
182         {0x0502, 0x00},\r
183         {0x0500, 0x0f},\r
184         {0x0502, 0x00},\r
185         {0x0500, 0x10},\r
186         {0x0502, 0x00},\r
187         {0x0500, 0x11},\r
188         {0x0502, 0x00},\r
189         {0x0500, 0x1e},\r
190         {0x0502, 0x00},\r
191         {0x0500, 0x1f},\r
192         {0x0502, 0x00},\r
193         {0xfd98, 0x00}, // palette\r
194         {0xfd99, 0x01},\r
195         {0xfd9a, 0x02},\r
196         {0xfd9b, 0x03},\r
197         {0xfd9c, 0x04},\r
198         {0xfd9d, 0x05},\r
199         {0xfd9e, 0x06},\r
200         {0xfd9f, 0x07},\r
201         {0xfda0, 0x0f}, // video\r
202 #endif\r
203         {-1, -1}\r
204 };\r
205 \r
206 // cmos: $000-\r
207 static const uint8 cmos_t[] = {\r
208 #ifdef _FMR30\r
209         0x01,0xff,0x42,0x4f,0x4f,0x54,0xa8,0x00,0x40,0x00,0x01,0xfe,0x53,0x45,0x54,0x55,\r
210         0xe8,0x00,0x00,0x01,0x01,0xfd,0x4c,0x4f,0x47,0x20,0xe8,0x01,0x10,0x03,0x01,0xfc,\r
211         0x4f,0x41,0x53,0x59,0xf8,0x04,0x20,0x00,0x01,0xfb,0x44,0x45,0x42,0x20,0x18,0x05,\r
212         0x00,0x01,0x01,0xfa,0x44,0x45,0x53,0x4b,0x18,0x06,0x32,0x00,0x00,0x00,0x00,0x00,\r
213         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\r
214         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\r
215         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\r
216         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\r
217         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\r
218         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\r
219         0x4a,0x06,0x7b,0x19,0x97,0x62,0x79,0x41\r
220 #else\r
221         0x01,0xff,0x42,0x4f,0x4f,0x54,0xa8,0x00,0x40,0x00,0x01,0xfe,0x53,0x45,0x54,0x55,\r
222         0xe8,0x00,0x00,0x01,0x01,0xfd,0x4c,0x4f,0x47,0x20,0xe8,0x01,0x10,0x03,0x01,0xfc,\r
223         0x4f,0x41,0x53,0x59,0xf8,0x04,0x20,0x00,0x01,0xfb,0x58,0x45,0x4e,0x49,0x18,0x05,\r
224         0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\r
225         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\r
226         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\r
227         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\r
228         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\r
229         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\r
230         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\r
231 //      0x28,0x05,0x99,0x02,0xe1,0xe1,0x79,0x41\r
232         0x28,0x05,0x99,0x02,0x00,0x00,0x79,0x41\r
233 #endif\r
234 };\r
235 // FMR-30: cmos $1fd0-\r
236 // FMR-50: cmos $7d0-\r
237 static const uint8 cmos_b[] = {\r
238 #ifdef _FMR30\r
239         0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0xff,0xff,0xff,0xff,0xff,\r
240         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\r
241         0x7f,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff\r
242 #else\r
243         0x00,0x00,0x01,0x02,0x03,0x04,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\r
244         0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\r
245         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00\r
246 #endif\r
247 };\r
248 \r
249 // boot message\r
250 static const uint8 msg_c[] = {\r
251         0xff,0x47,0xff,0x07,0xff,0x47,0xff,0x07,0xff,0x47,0xff,0x07,0xff,0x47,0xff,0x07,\r
252         0xff,0x47,0xff,0x07,0xff,0x47,0xff,0x07,0xff,0x47,0xff,0x07,0xff,0x47,0xff,0x07,\r
253         0xff,0x47,0xff,0x07,0xff,0x47,0xff,0x07,0xff,0x47,0xff,0x07,0xff,0x47,0xff,0x07,\r
254         0xff,0x47,0xff,0x07,0xff,0x47,0xff,0x07,0xff,0x47,0xff,0x07\r
255 };\r
256 \r
257 // '\83V\83X\83e\83\80\82ð\83Z\83b\83g\82µ\82Ä\82­\82¾\82³\82¢'\r
258 static const uint8 msg_k[] = {\r
259         0x25,0x37,0x00,0x00,0x25,0x39,0x00,0x00,0x25,0x46,0x00,0x00,0x25,0x60,0x00,0x00,\r
260         0x24,0x72,0x00,0x00,0x25,0x3b,0x00,0x00,0x25,0x43,0x00,0x00,0x25,0x48,0x00,0x00,\r
261         0x24,0x37,0x00,0x00,0x24,0x46,0x00,0x00,0x24,0x2f,0x00,0x00,0x24,0x40,0x00,0x00,\r
262         0x24,0x35,0x00,0x00,0x24,0x24,0x00,0x00,0x21,0x21,0x00,0x00\r
263 };\r
264 \r
265 void BIOS::initialize()\r
266 {\r
267         // check ipl\r
268         disk_pc1 = disk_pc2 = cmos_pc = wait_pc = -1;\r
269         \r
270         FILEIO* fio = new FILEIO();\r
271         if(fio->Fopen(emu->bios_path(_T("IPL.ROM")), FILEIO_READ_BINARY)) {\r
272                 fio->Fread(buffer, sizeof(buffer), 1);\r
273                 fio->Fclose();\r
274                 \r
275                 uint32 addr = 0xfffc4;\r
276                 if(buffer[addr & (IPL_SIZE - 1)] == 0xea) {\r
277                         int ofs = buffer[++addr & (IPL_SIZE - 1)];\r
278                         ofs |= buffer[++addr & (IPL_SIZE - 1)] << 8;\r
279                         int seg = buffer[++addr & (IPL_SIZE - 1)];\r
280                         seg |= buffer[++addr & (IPL_SIZE - 1)] << 8;\r
281                         disk_pc1 = addr = ofs + (seg << 4);\r
282                 }\r
283                 if(buffer[addr & (IPL_SIZE - 1)] == 0xea) {\r
284                         int ofs = buffer[++addr & (IPL_SIZE - 1)];\r
285                         ofs |= buffer[++addr & (IPL_SIZE - 1)] << 8;\r
286                         int seg = buffer[++addr & (IPL_SIZE - 1)];\r
287                         seg |= buffer[++addr & (IPL_SIZE - 1)] << 8;\r
288                         disk_pc2 = ofs + (seg << 4);\r
289                 }\r
290         } else {\r
291                 // use pseudo ipl\r
292                 cmos_pc = 0xfffc9;\r
293                 wait_pc = 0xfffd3;\r
294                 \r
295                 // register event\r
296                 register_frame_event(this);\r
297         }\r
298         \r
299         // init scsi\r
300         memset(scsi_blocks, 0, sizeof(scsi_blocks));\r
301         for(int i = 0; i < MAX_SCSI; i++) {\r
302                 _stprintf(scsi_path[i], _T("%sSCSI%d.DAT"), emu->application_path(), i);\r
303                 if(fio->Fopen(scsi_path[i], FILEIO_READ_BINARY)) {\r
304                         fio->Fseek(0, FILEIO_SEEK_END);\r
305                         scsi_blocks[i] = fio->Ftell() / BLOCK_SIZE;\r
306                         fio->Fclose();\r
307                 }\r
308         }\r
309         \r
310         // init memcard\r
311         memset(memcard_blocks, 0, sizeof(memcard_blocks));\r
312         for(int i = 0; i < MAX_MEMCARD; i++) {\r
313                 _stprintf(memcard_path[i], _T("%sMEMCARD%d.DAT"), emu->application_path(), i);\r
314                 if(fio->Fopen(memcard_path[i], FILEIO_READ_BINARY)) {\r
315                         fio->Fseek(0, FILEIO_SEEK_END);\r
316                         memcard_blocks[i] = fio->Ftell() / BLOCK_SIZE;\r
317                         memcard_protected[i] = fio->IsProtected(memcard_path[i]);\r
318                         fio->Fclose();\r
319                 }\r
320         }\r
321         delete fio;\r
322 }\r
323 \r
324 void BIOS::reset()\r
325 {\r
326         for(int i = 0; i < MAX_DRIVE; i++) {\r
327                 access_fdd[i] = false;\r
328         }\r
329         access_scsi = false;\r
330         secnum = 1;\r
331         powmode = 0;\r
332         timeout = 0;\r
333 }\r
334 \r
335 void BIOS::event_frame()\r
336 {\r
337         timeout++;\r
338 }\r
339 \r
340 bool BIOS::bios_call(uint32 PC, uint16 regs[], uint16 sregs[], int32* ZeroFlag, int32* CarryFlag)\r
341 {\r
342         uint8 *regs8 = (uint8 *)regs;\r
343         int drv = AL & 0xf;\r
344         \r
345         if(PC == 0xfffc4 || PC == disk_pc1 || PC == disk_pc2) {\r
346                 // disk bios\r
347 #ifdef _DEBUG_LOG\r
348                 emu->out_debug_log(_T("%6x\tDISK BIOS: AH=%2x,AL=%2x,CX=%4x,DX=%4x,BX=%4x,DS=%2x,DI=%2x\n"), get_cpu_pc(0), AH,AL,CX,DX,BX,DS,DI);\r
349 #endif\r
350 //              if(!((AL & 0xf0) == 0x20 || (AL & 0xf0) == 0x50 || (AL & 0xf0) == 0xb0)) {\r
351                         // target drive is not floppy, memcard and scsi hard drive\r
352 //                      return false;\r
353 //              }\r
354                 if(AH == 2) {\r
355                         // drive status\r
356                         if((AL & 0xf0) == 0x20) {\r
357                                 // floppy\r
358                                 if(!(drv < MAX_DRIVE && disk[drv]->inserted)) {\r
359                                         AH = 0x80;\r
360                                         CX = ERR_FDD_NOTREADY;\r
361                                         *CarryFlag = 1;\r
362                                         return true;\r
363                                 }\r
364                                 AH = 0;\r
365                                 DL = 4;\r
366                                 if(disk[drv]->write_protected) {\r
367                                         DL |= 2;\r
368                                 }\r
369                                 CX = 0;\r
370                                 *CarryFlag = 0;\r
371                                 return true;\r
372                         }\r
373                         if((AL & 0xf0) == 0x50) {\r
374                                 // memcard\r
375                                 if(!(drv < MAX_MEMCARD && memcard_blocks[drv])) {\r
376                                         AH = 0x80;\r
377                                         CX = ERR_MEMCARD_NOTREADY;\r
378                                         *CarryFlag = 1;\r
379                                         return true;\r
380                                 }\r
381                                 AH = 0;\r
382                                 AL = 2;\r
383                                 DL = memcard_protected[drv] ? 2 : 0;\r
384                                 CX = 0;\r
385                                 *CarryFlag = 0;\r
386                                 return true;\r
387                         }\r
388                         if((AL & 0xf0) == 0xb0) {\r
389                                 // scsi\r
390                                 if(!(drv < MAX_SCSI && scsi_blocks[drv])) {\r
391                                         AH = 0x80;\r
392                                         CX = ERR_SCSI_NOTCONNECTED;\r
393                                         *CarryFlag = 1;\r
394                                         return true;\r
395                                 }\r
396                                 AH = 0;\r
397                                 AL = (BLOCK_SIZE == 128) ? 0 : (BLOCK_SIZE == 256) ? 1 : (BLOCK_SIZE == 512) ? 2 : 3;\r
398                                 BX = scsi_blocks[drv] >> 16;\r
399                                 DX = scsi_blocks[drv] & 0xffff;\r
400                                 CX = 0;\r
401                                 *CarryFlag = 0;\r
402                                 return true;\r
403                         }\r
404                         AH = 2;\r
405                         *CarryFlag = 1;\r
406                         return true;\r
407                 } else if(AH == 3 || AH == 4) {\r
408                         // resture/seek\r
409                         if((AL & 0xf0) == 0x20) {\r
410                                 // floppy\r
411                                 if(!(drv < MAX_DRIVE && disk[drv]->inserted)) {\r
412                                         AH = 0x80;\r
413                                         CX = ERR_FDD_NOTREADY;\r
414                                         *CarryFlag = 1;\r
415                                         return true;\r
416                                 }\r
417                                 AH = 0;\r
418                                 CX = 0;\r
419                                 *CarryFlag = 0;\r
420                                 return true;\r
421                         }\r
422                         if((AL & 0xf0) == 0xb0) {\r
423                                 // scsi\r
424                                 if(!(drv < MAX_SCSI && scsi_blocks[drv])) {\r
425                                         AH = 0x80;\r
426                                         CX = ERR_SCSI_NOTCONNECTED;\r
427                                         *CarryFlag = 1;\r
428                                         return true;\r
429                                 }\r
430                                 AH = 0;\r
431                                 CX = 0;\r
432                                 *CarryFlag = 0;\r
433                                 return true;\r
434                         }\r
435                         AH = 2;\r
436                         *CarryFlag = 1;\r
437                         return true;\r
438                 } else if(AH == 5) {\r
439                         // read sectors\r
440                         if((AL & 0xf0) == 0x20) {\r
441                                 // floppy\r
442                                 if(!(drv < MAX_DRIVE && disk[drv]->inserted)) {\r
443                                         AH = 0x80;\r
444                                         CX = ERR_FDD_NOTREADY;\r
445                                         *CarryFlag = 1;\r
446                                         return true;\r
447                                 }\r
448                                 // get initial c/h/r\r
449                                 int ofs = DS * 16 + DI;\r
450                                 int trk = CX;\r
451                                 int hed = DH & 1;\r
452                                 int sct = DL;\r
453                                 while(BX > 0) {\r
454                                         // search sector\r
455                                         disk[drv]->get_track(trk, hed);\r
456                                         access_fdd[drv] = true;\r
457                                         secnum = sct;\r
458                                         if(!disk[drv]->get_sector(trk, hed, sct - 1)) {\r
459                                                 AH = 0x80;\r
460                                                 CX = ERR_FDD_NOTFOUND;\r
461                                                 *CarryFlag = 1;\r
462                                                 return true;\r
463                                         }\r
464                                         // check deleted mark\r
465                                         if(disk[drv]->deleted) {\r
466                                                 AH = 0x80;\r
467                                                 CX = ERR_FDD_DELETED;\r
468                                                 *CarryFlag = 1;\r
469                                                 return true;\r
470                                         }\r
471                                         // data transfer\r
472                                         for(int i = 0; i < disk[drv]->sector_size; i++) {\r
473                                                 d_mem->write_data8(ofs++, disk[drv]->sector[i]);\r
474                                         }\r
475                                         BX--;\r
476                                         // check crc error\r
477                                         if(disk[drv]->status) {\r
478                                                 AH = 0x80;\r
479                                                 CX = ERR_FDD_CRCERROR;\r
480                                                 *CarryFlag = 1;\r
481                                                 return true;\r
482                                         }\r
483                                         // update c/h/r\r
484                                         if(++sct > disk[drv]->sector_num) {\r
485                                                 sct = 1;\r
486                                                 if(++hed > 1) {\r
487                                                         hed = 0;\r
488                                                         ++trk;\r
489                                                 }\r
490                                         }\r
491                                 }\r
492                                 AH = 0;\r
493                                 CX = 0;\r
494                                 *CarryFlag = 0;\r
495                                 return true;\r
496                         }\r
497                         if((AL & 0xf0) == 0x50) {\r
498                                 // memcard\r
499                                 if(!(drv < MAX_MEMCARD && memcard_blocks[drv])) {\r
500                                         AH = 0x80;\r
501                                         CX = ERR_MEMCARD_NOTREADY;\r
502                                         *CarryFlag = 1;\r
503                                         return true;\r
504                                 }\r
505                                 FILEIO* fio = new FILEIO();\r
506                                 if(!fio->Fopen(memcard_path[drv], FILEIO_READ_BINARY)) {\r
507                                         AH = 0x80;\r
508                                         CX = ERR_MEMCARD_NOTREADY;\r
509                                         *CarryFlag = 1;\r
510                                         delete fio;\r
511                                         return true;\r
512                                 }\r
513                                 // get params\r
514                                 int ofs = DS * 16 + DI;\r
515                                 int block = (CL << 16) | DX;\r
516                                 fio->Fseek(block * BLOCK_SIZE, FILEIO_SEEK_SET);\r
517                                 while(BX > 0) {\r
518                                         // check block\r
519                                         if(!(block++ < memcard_blocks[drv])) {\r
520                                                 AH = 0x80;\r
521                                                 CX = ERR_MEMCARD_PARAMERROR;\r
522                                                 *CarryFlag = 1;\r
523                                                 fio->Fclose();\r
524                                                 delete fio;\r
525                                                 return true;\r
526                                         }\r
527                                         // data transfer\r
528                                         fio->Fread(buffer, BLOCK_SIZE, 1);\r
529                                         for(int i = 0; i < BLOCK_SIZE; i++) {\r
530                                                 d_mem->write_data8(ofs++, buffer[i]);\r
531                                         }\r
532                                         BX--;\r
533                                 }\r
534                                 AH = 0;\r
535                                 CX = 0;\r
536                                 *CarryFlag = 0;\r
537                                 fio->Fclose();\r
538                                 delete fio;\r
539                                 return true;\r
540                         }\r
541                         if((AL & 0xf0) == 0xb0) {\r
542                                 // scsi\r
543                                 if(!(drv < MAX_SCSI && scsi_blocks[drv])) {\r
544                                         AH = 0x80;\r
545                                         CX = ERR_SCSI_NOTCONNECTED;\r
546                                         *CarryFlag = 1;\r
547                                         return true;\r
548                                 }\r
549                                 FILEIO* fio = new FILEIO();\r
550                                 if(!fio->Fopen(scsi_path[drv], FILEIO_READ_BINARY)) {\r
551                                         AH = 0x80;\r
552                                         CX = ERR_SCSI_NOTREADY;\r
553                                         *CarryFlag = 1;\r
554                                         delete fio;\r
555                                         return true;\r
556                                 }\r
557                                 // get params\r
558                                 int ofs = DS * 16 + DI;\r
559                                 int block = (CL << 16) | DX;\r
560                                 fio->Fseek(block * BLOCK_SIZE, FILEIO_SEEK_SET);\r
561                                 while(BX > 0) {\r
562                                         // check block\r
563                                         access_scsi = true;\r
564                                         if(!(block++ < scsi_blocks[drv])) {\r
565                                                 AH = 0x80;\r
566                                                 CX = ERR_SCSI_PARAMERROR;\r
567                                                 *CarryFlag = 1;\r
568                                                 fio->Fclose();\r
569                                                 delete fio;\r
570                                                 return true;\r
571                                         }\r
572                                         // data transfer\r
573                                         fio->Fread(buffer, BLOCK_SIZE, 1);\r
574                                         for(int i = 0; i < BLOCK_SIZE; i++) {\r
575                                                 d_mem->write_data8(ofs++, buffer[i]);\r
576                                         }\r
577                                         BX--;\r
578                                 }\r
579                                 AH = 0;\r
580                                 CX = 0;\r
581                                 *CarryFlag = 0;\r
582                                 fio->Fclose();\r
583                                 delete fio;\r
584                                 return true;\r
585                         }\r
586                         AH = 2;\r
587                         *CarryFlag = 1;\r
588                         return true;\r
589                 } else if(AH == 6) {\r
590                         // write sectors\r
591                         if((AL & 0xf0) == 0x20) {\r
592                                 // floppy\r
593                                 if(!(drv < MAX_DRIVE && disk[drv]->inserted)) {\r
594                                         AH = 0x80;\r
595                                         CX = ERR_FDD_NOTREADY;\r
596                                         *CarryFlag = 1;\r
597                                         return true;\r
598                                 }\r
599                                 if(disk[drv]->write_protected) {\r
600                                         AH = 0x80;\r
601                                         CX = ERR_FDD_PROTECTED;\r
602                                         *CarryFlag = 1;\r
603                                         return true;\r
604                                 }\r
605                                 // get initial c/h/r\r
606                                 int ofs = DS * 16 + DI;\r
607                                 int trk = CX;\r
608                                 int hed = DH & 1;\r
609                                 int sct = DL;\r
610                                 while(BX > 0) {\r
611                                         // search sector\r
612                                         disk[drv]->get_track(trk, hed);\r
613                                         access_fdd[drv] = true;\r
614                                         secnum = sct;\r
615                                         if(!disk[drv]->get_sector(trk, hed, sct - 1)) {\r
616                                                 AH = 0x80;\r
617                                                 CX = ERR_FDD_NOTFOUND;\r
618                                                 *CarryFlag = 1;\r
619                                                 return true;\r
620                                         }\r
621                                         // data transfer\r
622                                         for(int i = 0; i < disk[drv]->sector_size; i++) {\r
623                                                 disk[drv]->sector[i] = d_mem->read_data8(ofs++);\r
624                                         }\r
625                                         BX--;\r
626                                         // clear deleted mark and crc error\r
627                                         disk[drv]->deleted = 0;\r
628                                         disk[drv]->status = 0;\r
629                                         // update c/h/r\r
630                                         if(++sct > disk[drv]->sector_num) {\r
631                                                 sct = 1;\r
632                                                 if(++hed > 1) {\r
633                                                         hed = 0;\r
634                                                         ++trk;\r
635                                                 }\r
636                                         }\r
637                                 }\r
638                                 AH = 0;\r
639                                 CX = 0;\r
640                                 *CarryFlag = 0;\r
641                                 return true;\r
642                         }\r
643                         if((AL & 0xf0) == 0x50) {\r
644                                 // memcard\r
645                                 if(!(drv < MAX_MEMCARD && memcard_blocks[drv])) {\r
646                                         AH = 0x80;\r
647                                         CX = ERR_MEMCARD_NOTREADY;\r
648                                         *CarryFlag = 1;\r
649                                         return true;\r
650                                 }\r
651                                 if(memcard_protected[drv]) {\r
652                                         AH = 0x80;\r
653                                         CX = ERR_MEMCARD_PROTECTED;\r
654                                         *CarryFlag = 1;\r
655                                         return true;\r
656                                 }\r
657                                 FILEIO* fio = new FILEIO();\r
658                                 if(!fio->Fopen(memcard_path[drv], FILEIO_READ_WRITE_BINARY)) {\r
659                                         AH = 0x80;\r
660                                         CX = ERR_MEMCARD_NOTREADY;\r
661                                         *CarryFlag = 1;\r
662                                         delete fio;\r
663                                         return true;\r
664                                 }\r
665                                 // get params\r
666                                 int ofs = DS * 16 + DI;\r
667                                 int block = (CL << 16) | DX;\r
668                                 fio->Fseek(block * BLOCK_SIZE, FILEIO_SEEK_SET);\r
669                                 while(BX > 0) {\r
670                                         // check block\r
671                                         access_scsi = true;\r
672                                         if(!(block++ < scsi_blocks[drv])) {\r
673                                                 AH = 0x80;\r
674                                                 CX = ERR_MEMCARD_PARAMERROR;\r
675                                                 *CarryFlag = 1;\r
676                                                 fio->Fclose();\r
677                                                 delete fio;\r
678                                                 return true;\r
679                                         }\r
680                                         // data transfer\r
681                                         for(int i = 0; i < BLOCK_SIZE; i++) {\r
682                                                 buffer[i] = d_mem->read_data8(ofs++);\r
683                                         }\r
684                                         fio->Fwrite(buffer, BLOCK_SIZE, 1);\r
685                                         BX--;\r
686                                 }\r
687                                 AH = 0;\r
688                                 CX = 0;\r
689                                 *CarryFlag = 0;\r
690                                 fio->Fclose();\r
691                                 delete fio;\r
692                                 return true;\r
693                         }\r
694                         if((AL & 0xf0) == 0xb0) {\r
695                                 // scsi\r
696                                 if(!(drv < MAX_SCSI && scsi_blocks[drv])) {\r
697                                         AH = 0x80;\r
698                                         CX = ERR_SCSI_NOTCONNECTED;\r
699                                         *CarryFlag = 1;\r
700                                         return true;\r
701                                 }\r
702                                 FILEIO* fio = new FILEIO();\r
703                                 if(!fio->Fopen(scsi_path[drv], FILEIO_READ_WRITE_BINARY)) {\r
704                                         AH = 0x80;\r
705                                         CX = ERR_SCSI_NOTREADY;\r
706                                         *CarryFlag = 1;\r
707                                         delete fio;\r
708                                         return true;\r
709                                 }\r
710                                 // get params\r
711                                 int ofs = DS * 16 + DI;\r
712                                 int block = (CL << 16) | DX;\r
713                                 fio->Fseek(block * BLOCK_SIZE, FILEIO_SEEK_SET);\r
714                                 while(BX > 0) {\r
715                                         // check block\r
716                                         access_scsi = true;\r
717                                         if(!(block++ < scsi_blocks[drv])) {\r
718                                                 AH = 0x80;\r
719                                                 CX = ERR_SCSI_PARAMERROR;\r
720                                                 *CarryFlag = 1;\r
721                                                 fio->Fclose();\r
722                                                 delete fio;\r
723                                                 return true;\r
724                                         }\r
725                                         // data transfer\r
726                                         for(int i = 0; i < BLOCK_SIZE; i++) {\r
727                                                 buffer[i] = d_mem->read_data8(ofs++);\r
728                                         }\r
729                                         fio->Fwrite(buffer, BLOCK_SIZE, 1);\r
730                                         BX--;\r
731                                 }\r
732                                 AH = 0;\r
733                                 CX = 0;\r
734                                 *CarryFlag = 0;\r
735                                 fio->Fclose();\r
736                                 delete fio;\r
737                                 return true;\r
738                         }\r
739                         AH = 2;\r
740                         *CarryFlag = 1;\r
741                         return true;\r
742                 } else if(AH == 7) {\r
743                         // verify sectors\r
744                         if((AL & 0xf0) == 0x20) {\r
745                                 // floppy\r
746                                 if(!(drv < MAX_DRIVE && disk[drv]->inserted)) {\r
747                                         AH = 0x80;\r
748                                         CX = ERR_FDD_NOTREADY;\r
749                                         *CarryFlag = 1;\r
750                                         return true;\r
751                                 }\r
752                                 // get initial c/h/r\r
753                                 int trk = CX;\r
754                                 int hed = DH & 1;\r
755                                 int sct = DL;\r
756                                 while(BX > 0) {\r
757                                         // search sector\r
758                                         disk[drv]->get_track(trk, hed);\r
759                                         access_fdd[drv] = true;\r
760                                         secnum = sct;\r
761                                         if(!disk[drv]->get_sector(trk, hed, sct - 1)) {\r
762                                                 AH = 0x80;\r
763                                                 CX = ERR_FDD_NOTFOUND;\r
764                                                 *CarryFlag = 1;\r
765                                                 return true;\r
766                                         }\r
767                                         BX--;\r
768                                         // check crc error\r
769                                         if(disk[drv]->status) {\r
770                                                 AH = 0x80;\r
771                                                 CX = ERR_FDD_CRCERROR;\r
772                                                 *CarryFlag = 1;\r
773                                                 return true;\r
774                                         }\r
775                                         // update c/h/r\r
776                                         if(++sct > disk[drv]->sector_num) {\r
777                                                 sct = 1;\r
778                                                 if(++hed > 1) {\r
779                                                         hed = 0;\r
780                                                         ++trk;\r
781                                                 }\r
782                                         }\r
783                                 }\r
784                                 AH = 0;\r
785                                 CX = 0;\r
786                                 *CarryFlag = 0;\r
787                                 return true;\r
788                         }\r
789                         if((AL & 0xf0) == 0xb0) {\r
790                                 // scsi\r
791                                 if(!(drv < MAX_SCSI && scsi_blocks[drv])) {\r
792                                         AH = 0x80;\r
793                                         CX = ERR_SCSI_NOTCONNECTED;\r
794                                         *CarryFlag = 1;\r
795                                         return true;\r
796                                 }\r
797                                 // get params\r
798                                 int block = (CL << 16) | DX;\r
799                                 while(BX > 0) {\r
800                                         // check block\r
801                                         access_scsi = true;\r
802                                         if(!(block++ < scsi_blocks[drv])) {\r
803                                                 AH = 0x80;\r
804                                                 CX = ERR_SCSI_PARAMERROR;\r
805                                                 *CarryFlag = 1;\r
806                                                 return true;\r
807                                         }\r
808                                         BX--;\r
809                                 }\r
810                                 AH = 0;\r
811                                 CX = 0;\r
812                                 *CarryFlag = 0;\r
813                                 return true;\r
814                         }\r
815                         AH = 2;\r
816                         *CarryFlag = 1;\r
817                         return true;\r
818                 } else if(AH == 8) {\r
819                         // reset hard drive controller\r
820                         AH = 0;\r
821                         CX = 0;\r
822                         *CarryFlag = 0;\r
823                         return true;\r
824                 } else if(AH == 9) {\r
825                         // read id\r
826                         if((AL & 0xf0) == 0x20) {\r
827                                 // floppy\r
828                                 if(!(drv < MAX_DRIVE && disk[drv]->inserted)) {\r
829                                         AH = 0x80;\r
830                                         CX = ERR_FDD_NOTREADY;\r
831                                         *CarryFlag = 1;\r
832                                         return true;\r
833                                 }\r
834                                 // get initial c/h\r
835                                 int ofs = DS * 16 + DI;\r
836                                 int trk = CX;\r
837                                 int hed = DH & 1;\r
838                                 // search sector\r
839                                 disk[drv]->get_track(trk, hed);\r
840                                 access_fdd[drv] = true;\r
841                                 if(++secnum > disk[drv]->sector_num) {\r
842                                         secnum = 1;\r
843                                 }\r
844                                 if(!disk[drv]->get_sector(trk, hed, secnum - 1)) {\r
845                                         AH = 0x80;\r
846                                         CX = ERR_FDD_NOTFOUND;\r
847                                         *CarryFlag = 1;\r
848                                         return true;\r
849                                 }\r
850                                 for(int i = 0; i < 6; i++) {\r
851                                         d_mem->write_data8(ofs++, disk[drv]->id[i]);\r
852                                 }\r
853                                 AH = 0;\r
854                                 CX = 0;\r
855                                 *CarryFlag = 0;\r
856                                 return true;\r
857                         }\r
858                         AH = 2;\r
859                         *CarryFlag = 1;\r
860                         return true;\r
861                 } else if(AH == 0xa) {\r
862                         // format track\r
863                         if((AL & 0xf0) == 0x20) {\r
864                                 // floppy\r
865                                 if(!(drv < MAX_DRIVE && disk[drv]->inserted)) {\r
866                                         AH = 0x80;\r
867                                         CX = ERR_FDD_NOTREADY;\r
868                                         *CarryFlag = 1;\r
869                                         return true;\r
870                                 }\r
871                                 // get initial c/h\r
872                                 int trk = CX;\r
873                                 int hed = DH & 1;\r
874                                 // search sector\r
875                                 disk[drv]->get_track(trk, hed);\r
876                                 access_fdd[drv] = true;\r
877                                 for(int i = 0; i < disk[drv]->sector_num; i++) {\r
878                                         disk[drv]->get_sector(trk, hed, i);\r
879                                         memset(disk[drv]->sector, 0xe5, disk[drv]->sector_size);\r
880                                         disk[drv]->deleted = 0;\r
881                                         disk[drv]->status = 0;\r
882                                 }\r
883                                 AH = 0;\r
884                                 CX = 0;\r
885                                 *CarryFlag = 0;\r
886                                 return true;\r
887                         }\r
888                         AH = 2;\r
889                         *CarryFlag = 1;\r
890                         return true;\r
891                 } else if(AH == 0xd) {\r
892                         // read error\r
893                         AH = 0;\r
894                         CX = 0;\r
895                         *CarryFlag = 0;\r
896                         return true;\r
897                 } else if(AH == 0xe) {\r
898                         // disk change ???\r
899                         if((AL & 0xf0) == 0x20) {\r
900                                 // floppy\r
901                                 if(!(drv < MAX_DRIVE && disk[drv]->inserted)) {\r
902                                         AH = 0;\r
903                                         CX = 0;\r
904                                         DL = 1;\r
905                                         *CarryFlag = 0;\r
906                                         return true;\r
907                                 }\r
908                                 AH = 0;\r
909                                 CX = 0;\r
910                                 DL = disk[drv]->changed ? 1 : 0;\r
911                                 disk[drv]->changed = false;\r
912                                 *CarryFlag = 0;\r
913                                 return true;\r
914                         }\r
915                         if((AL & 0xf0) == 0xb0) {\r
916                                 // scsi\r
917                                 if(!(drv < MAX_SCSI && scsi_blocks[drv])) {\r
918                                         AH = 3; // ???\r
919                                         CX = 0;\r
920                                         *CarryFlag = 1;\r
921                                         return true;\r
922                                 }\r
923                                 AH = 0;\r
924                                 CX = 0;\r
925                                 *CarryFlag = 0;\r
926                                 return true;\r
927                         }\r
928                         AH = 2;\r
929                         CX = 0;\r
930                         *CarryFlag = 1;\r
931                         return true;\r
932                 } else if(AH == 0xfa) {\r
933                         // unknown\r
934                         if((AL & 0xf0) == 0x20) {\r
935                                 // floppy\r
936                                 AH = 1;\r
937                                 CX = 0;\r
938                                 *CarryFlag = 1;\r
939                                 return true;\r
940                         }\r
941                         if((AL & 0xf0) == 0xb0) {\r
942                                 // scsi\r
943                                 if(!(drv < MAX_SCSI && scsi_blocks[drv])) {\r
944                                         AH = 0x80;\r
945                                         CX = ERR_SCSI_NOTCONNECTED;\r
946                                         *CarryFlag = 1;\r
947                                         return true;\r
948                                 }\r
949                                 AH = 0;\r
950                                 CX = 0;\r
951                                 *CarryFlag = 0;\r
952                                 return true;\r
953                         }\r
954                         AH = 2;\r
955                         *CarryFlag = 1;\r
956                         return true;\r
957                 } else if(AH == 0xfd) {\r
958                         // unknown\r
959                         if((AL & 0xf0) == 0x20) {\r
960                                 // floppy\r
961                                 AH = 1;\r
962                                 CX = 0;\r
963                                 *CarryFlag = 1;\r
964                                 return true;\r
965                         }\r
966                         if((AL & 0xf0) == 0xb0) {\r
967                                 // scsi\r
968                                 if(!(drv < MAX_SCSI && scsi_blocks[drv])) {\r
969                                         AH = 0;\r
970                                         CX = 0x200;     // ???\r
971                                         *CarryFlag = 0;\r
972                                         return true;\r
973                                 }\r
974                                 AH = 2;\r
975                                 CX = 0;\r
976                                 *CarryFlag = 1;\r
977                                 return true;\r
978                         }\r
979                         AH = 2;\r
980                         CX = 0;\r
981                         *CarryFlag = 1;\r
982                         return true;\r
983                 } else if(AH == 0x80) {\r
984                         // pseudo bios: init i/o\r
985                         for(int i = 0;; i++) {\r
986                                 if(iotable[i][0] < 0) {\r
987                                         break;\r
988                                 }\r
989                                 d_io->write_io8(iotable[i][0], iotable[i][1]);\r
990                         }\r
991                         // init cmos\r
992                         memset(cmos, 0, CMOS_SIZE);\r
993                         memcpy(cmos, cmos_t, sizeof(cmos_t));\r
994                         memcpy(cmos + CMOS_SIZE - sizeof(cmos_b), cmos_b, sizeof(cmos_b));\r
995                         // init int vector\r
996                         for(int i = 0, ofs = 0; i < 256; i++) {\r
997                                 // int vector = ffff:0008\r
998                                 d_mem->write_data16(ofs + 0, 0x0008);\r
999                                 d_mem->write_data16(ofs + 2, 0xffff);\r
1000                                 ofs += 4;\r
1001                         }\r
1002                         // init screen\r
1003                         memset(vram, 0, VRAM_SIZE);\r
1004 #ifdef _FMR60\r
1005                         memset(cvram, 0, 0x2000);\r
1006                         memset(avram, 0, 0x2000);\r
1007 #else\r
1008                         memset(cvram, 0, 0x1000);\r
1009                         memset(kvram, 0, 0x1000);\r
1010                         memcpy(cvram + 0xf00, msg_c, sizeof(msg_c));\r
1011                         memcpy(kvram + 0xf00, msg_k, sizeof(msg_k));\r
1012 #endif\r
1013                         *CarryFlag = 0;\r
1014                         return true;\r
1015                 } else if(AH == 0x81) {\r
1016                         // pseudo bios: boot from fdd #0\r
1017                         *ZeroFlag = (timeout > (int)(FRAMES_PER_SEC * 4));\r
1018                         if(!disk[0]->inserted) {\r
1019                                 *CarryFlag = 1;\r
1020                                 return true;\r
1021                         }\r
1022                         // load ipl\r
1023                         disk[0]->get_track(0, 0);\r
1024                         access_fdd[0] = true;\r
1025                         if(!disk[0]->get_sector(0, 0, 0)) {\r
1026                                 *CarryFlag = 1;\r
1027                                 return true;\r
1028                         }\r
1029                         for(int i = 0; i < disk[0]->sector_size; i++) {\r
1030                                 buffer[i] = disk[0]->sector[i];\r
1031                         }\r
1032                         // check ipl\r
1033                         if(!(buffer[0] == 'I' && buffer[1] == 'P' && buffer[2] == 'L' && buffer[3] == IPL_ID)) {\r
1034                                 *CarryFlag = 1;\r
1035                                 return true;\r
1036                         }\r
1037                         // data transfer\r
1038                         for(int i = 0; i < disk[0]->sector_size; i++) {\r
1039                                 d_mem->write_data8(0xb0000 + i, buffer[i]);\r
1040                         }\r
1041                         // clear screen\r
1042 #ifdef _FMR60\r
1043                         memset(cvram, 0, 0x2000);\r
1044                         memset(avram, 0, 0x2000);\r
1045 #else\r
1046                         memset(cvram, 0, 0x1000);\r
1047                         memset(kvram, 0, 0x1000);\r
1048 #endif\r
1049                         // set result\r
1050                         AX = 0xff;\r
1051                         CX = 0;\r
1052                         BX = 2;\r
1053                         *ZeroFlag = 1;\r
1054                         *CarryFlag = 0;\r
1055                         return true;\r
1056                 } else if(AH == 0x82) {\r
1057                         // pseudo bios: boot from scsi-hdd #0\r
1058                         timeout = 0;\r
1059                         if(!scsi_blocks[0]) {\r
1060                                 *CarryFlag = 1;\r
1061                                 return true;\r
1062                         }\r
1063                         FILEIO* fio = new FILEIO();\r
1064                         if(!fio->Fopen(scsi_path[drv], FILEIO_READ_BINARY)) {\r
1065                                 *CarryFlag = 1;\r
1066                                 delete fio;\r
1067                                 return true;\r
1068                         }\r
1069                         // load ipl\r
1070                         access_scsi = true;\r
1071                         fio->Fread(buffer, BLOCK_SIZE * 4, 1);\r
1072                         fio->Fclose();\r
1073                         delete fio;\r
1074                         // check ipl\r
1075                         if(!(buffer[0] == 'I' && buffer[1] == 'P' && buffer[2] == 'L' && buffer[3] == IPL_ID)) {\r
1076                                 *CarryFlag = 1;\r
1077                                 return true;\r
1078                         }\r
1079                         // data transfer\r
1080                         for(int i = 0; i < BLOCK_SIZE * 4; i++) {\r
1081                                 d_mem->write_data8(0xb0000 + i, buffer[i]);\r
1082                         }\r
1083                         // clear screen\r
1084 #ifdef _FMR60\r
1085                         memset(cvram, 0, 0x2000);\r
1086                         memset(avram, 0, 0x2000);\r
1087 #else\r
1088                         memset(cvram, 0, 0x1000);\r
1089                         memset(kvram, 0, 0x1000);\r
1090 #endif\r
1091                         // set result\r
1092                         AX = 0xffff;\r
1093                         CX = 0;\r
1094                         BX = 1;\r
1095                         *ZeroFlag = 1;\r
1096                         *CarryFlag = 0;\r
1097                         return true;\r
1098                 }\r
1099         } else if(PC == cmos_pc) {\r
1100                 // cmos\r
1101 #ifdef _DEBUG_LOG\r
1102                 emu->out_debug_log(_T("%6x\tCMOS BIOS: AH=%2x,AL=%2x,CX=%4x,DX=%4x,BX=%4x,DS=%2x,DI=%2x\n"), get_cpu_pc(0), AH,AL,CX,DX,BX,DS,DI);\r
1103 #endif\r
1104                 if(AH == 0) {\r
1105                         // init cmos\r
1106                         memcpy(cmos, cmos_t, sizeof(cmos_t));\r
1107                         memcpy(cmos + CMOS_SIZE - sizeof(cmos_b), cmos_b, sizeof(cmos_b));\r
1108                 } else if(AH == 5) {\r
1109                         // get $a2\r
1110                         BX = cmos[0xa2] | (cmos[0xa3] << 8);\r
1111                 } else if(AH == 10) {\r
1112                         // memory to cmos\r
1113                         int block = AL * 10;\r
1114                         int len = cmos[block + 6] | (cmos[block + 7] << 8);\r
1115                         int dst = cmos[block + 8] | (cmos[block + 9] << 8);\r
1116                         int src = DS * 16 + DI;\r
1117                         for(int i = 0; i < len; i++) {\r
1118                                 cmos[dst++] = d_mem->read_data8(src++);\r
1119                         }\r
1120                 } else if(AH == 11) {\r
1121                         // cmos to memory\r
1122                         int block = AL * 10;\r
1123                         int len = cmos[block + 6] | (cmos[block + 7] << 8);\r
1124                         int src = cmos[block + 8] | (cmos[block + 9] << 8);\r
1125                         int dst = DS * 16 + DI;\r
1126                         for(int i = 0; i < len; i++) {\r
1127                                 d_mem->write_data8(dst++, cmos[src++]);\r
1128                         }\r
1129                 } else if(AH == 20) {\r
1130                         // check block header\r
1131                         BX = 0;\r
1132                 }\r
1133                 AH = 0;\r
1134                 *CarryFlag = 0;\r
1135                 return true;\r
1136         } else if(PC == wait_pc) {\r
1137                 // wait\r
1138 #ifdef _DEBUG_LOG\r
1139                 emu->out_debug_log(_T("%6x\tWAIT BIOS: AH=%2x,AL=%2x,CX=%4x,DX=%4x,BX=%4x,DS=%2x,DI=%2x\n"), get_cpu_pc(0), AH,AL,CX,DX,BX,DS,DI);\r
1140 #endif\r
1141                 *CarryFlag = 0;\r
1142                 return true;\r
1143         }\r
1144         return false;\r
1145 }\r
1146 \r
1147 bool BIOS::bios_int(int intnum, uint16 regs[], uint16 sregs[], int32* ZeroFlag, int32* CarryFlag)\r
1148 {\r
1149         uint8 *regs8 = (uint8 *)regs;\r
1150         \r
1151         if(intnum == 0x93) {\r
1152                 // disk bios\r
1153                 return bios_call(0xfffc4, regs, sregs, ZeroFlag, CarryFlag);\r
1154         } else if(intnum == 0xaa) {\r
1155                 // power management bios\r
1156                 if(AH == 0) {\r
1157                         if(AL > 2) {\r
1158                                 AH = 2;\r
1159                                 *CarryFlag = 1;\r
1160                                 return true;\r
1161                         }\r
1162                         powmode = AL;\r
1163                         AH = 0;\r
1164                         *CarryFlag = 0;\r
1165                         return true;\r
1166                 } else if(AH == 1) {\r
1167                         AH = 0;\r
1168                         AL = BL = powmode;\r
1169                         *CarryFlag = 0;\r
1170                         return true;\r
1171                 }\r
1172         }\r
1173         return false;\r
1174 }\r
1175 \r
1176 uint32 BIOS::read_signal(int ch)\r
1177 {\r
1178         // get access status\r
1179         uint32 stat = 0;\r
1180         for(int i = 0; i < MAX_DRIVE; i++) {\r
1181                 if(access_fdd[i]) {\r
1182                         stat |= 1 << i;\r
1183                 }\r
1184                 access_fdd[i] = false;\r
1185         }\r
1186         if(access_scsi) {\r
1187                 stat |= 0x10;\r
1188         }\r
1189         access_scsi = false;\r
1190         return stat;\r
1191 }\r
1192 \r