2 FUJITSU FMR-30 Emulator 'eFMR-30'
\r
3 FUJITSU FMR-50 Emulator 'eFMR-50'
\r
4 FUJITSU FMR-60 Emulator 'eFMR-60'
\r
6 Author : Takeda.Toshiya
\r
13 #include "../disk.h"
\r
14 #include "../../fileio.h"
\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
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
64 #define CMOS_SIZE 0x2000
\r
65 #define VRAM_SIZE 0x20000
\r
66 #define IPL_SIZE 0x10000
\r
68 #elif defined(_FMR50)
\r
70 #define CMOS_SIZE 0x800
\r
71 #define VRAM_SIZE 0x40000
\r
72 #define IPL_SIZE 0x4000
\r
74 #elif defined(_FMR60)
\r
76 #define CMOS_SIZE 0x800
\r
77 #define VRAM_SIZE 0x80000
\r
78 #define IPL_SIZE 0x4000
\r
82 #define BLOCK_SIZE 512
\r
84 static const int iotable[][2] = {
\r
86 {0x0100, 0x19}, // pic
\r
96 {0x0042, 0x00}, // timer
\r
100 {0x000b, 0x02}, // sio
\r
106 {0x001d, 0x02}, // memory
\r
108 {0x0040, 0x9f}, // psg
\r
112 {0x0300, 0x01}, // lcdc
\r
136 {0x0060, 0x00}, // timer
\r
137 {0x0604, 0x00}, // keyboard
\r
138 {0x0000, 0x19}, // pic
\r
149 {0x0046, 0x36}, // pit
\r
152 {0x0404, 0x00}, // memory
\r
153 {0x0500, 0x00}, // crtc
\r
193 {0xfd98, 0x00}, // palette
\r
201 {0xfda0, 0x0f}, // video
\r
207 static const uint8 cmos_t[] = {
\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
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
235 // FMR-30: cmos $1fd0-
\r
236 // FMR-50: cmos $7d0-
\r
237 static const uint8 cmos_b[] = {
\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
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
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
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
265 void BIOS::initialize()
\r
268 disk_pc1 = disk_pc2 = cmos_pc = wait_pc = -1;
\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
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
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
296 register_frame_event(this);
\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
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
326 for(int i = 0; i < MAX_DRIVE; i++) {
\r
327 access_fdd[i] = false;
\r
329 access_scsi = false;
\r
335 void BIOS::event_frame()
\r
340 bool BIOS::bios_call(uint32 PC, uint16 regs[], uint16 sregs[], int32* ZeroFlag, int32* CarryFlag)
\r
342 uint8 *regs8 = (uint8 *)regs;
\r
343 int drv = AL & 0xf;
\r
345 if(PC == 0xfffc4 || PC == disk_pc1 || PC == disk_pc2) {
\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
350 // if(!((AL & 0xf0) == 0x20 || (AL & 0xf0) == 0x50 || (AL & 0xf0) == 0xb0)) {
\r
351 // target drive is not floppy, memcard and scsi hard drive
\r
356 if((AL & 0xf0) == 0x20) {
\r
358 if(!(drv < MAX_DRIVE && disk[drv]->inserted)) {
\r
360 CX = ERR_FDD_NOTREADY;
\r
366 if(disk[drv]->write_protected) {
\r
373 if((AL & 0xf0) == 0x50) {
\r
375 if(!(drv < MAX_MEMCARD && memcard_blocks[drv])) {
\r
377 CX = ERR_MEMCARD_NOTREADY;
\r
383 DL = memcard_protected[drv] ? 2 : 0;
\r
388 if((AL & 0xf0) == 0xb0) {
\r
390 if(!(drv < MAX_SCSI && scsi_blocks[drv])) {
\r
392 CX = ERR_SCSI_NOTCONNECTED;
\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
407 } else if(AH == 3 || AH == 4) {
\r
409 if((AL & 0xf0) == 0x20) {
\r
411 if(!(drv < MAX_DRIVE && disk[drv]->inserted)) {
\r
413 CX = ERR_FDD_NOTREADY;
\r
422 if((AL & 0xf0) == 0xb0) {
\r
424 if(!(drv < MAX_SCSI && scsi_blocks[drv])) {
\r
426 CX = ERR_SCSI_NOTCONNECTED;
\r
438 } else if(AH == 5) {
\r
440 if((AL & 0xf0) == 0x20) {
\r
442 if(!(drv < MAX_DRIVE && disk[drv]->inserted)) {
\r
444 CX = ERR_FDD_NOTREADY;
\r
448 // get initial c/h/r
\r
449 int ofs = DS * 16 + DI;
\r
455 disk[drv]->get_track(trk, hed);
\r
456 access_fdd[drv] = true;
\r
458 if(!disk[drv]->get_sector(trk, hed, sct - 1)) {
\r
460 CX = ERR_FDD_NOTFOUND;
\r
464 // check deleted mark
\r
465 if(disk[drv]->deleted) {
\r
467 CX = ERR_FDD_DELETED;
\r
472 for(int i = 0; i < disk[drv]->sector_size; i++) {
\r
473 d_mem->write_data8(ofs++, disk[drv]->sector[i]);
\r
477 if(disk[drv]->status) {
\r
479 CX = ERR_FDD_CRCERROR;
\r
484 if(++sct > disk[drv]->sector_num) {
\r
497 if((AL & 0xf0) == 0x50) {
\r
499 if(!(drv < MAX_MEMCARD && memcard_blocks[drv])) {
\r
501 CX = ERR_MEMCARD_NOTREADY;
\r
505 FILEIO* fio = new FILEIO();
\r
506 if(!fio->Fopen(memcard_path[drv], FILEIO_READ_BINARY)) {
\r
508 CX = ERR_MEMCARD_NOTREADY;
\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
519 if(!(block++ < memcard_blocks[drv])) {
\r
521 CX = ERR_MEMCARD_PARAMERROR;
\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
541 if((AL & 0xf0) == 0xb0) {
\r
543 if(!(drv < MAX_SCSI && scsi_blocks[drv])) {
\r
545 CX = ERR_SCSI_NOTCONNECTED;
\r
549 FILEIO* fio = new FILEIO();
\r
550 if(!fio->Fopen(scsi_path[drv], FILEIO_READ_BINARY)) {
\r
552 CX = ERR_SCSI_NOTREADY;
\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
563 access_scsi = true;
\r
564 if(!(block++ < scsi_blocks[drv])) {
\r
566 CX = ERR_SCSI_PARAMERROR;
\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
589 } else if(AH == 6) {
\r
591 if((AL & 0xf0) == 0x20) {
\r
593 if(!(drv < MAX_DRIVE && disk[drv]->inserted)) {
\r
595 CX = ERR_FDD_NOTREADY;
\r
599 if(disk[drv]->write_protected) {
\r
601 CX = ERR_FDD_PROTECTED;
\r
605 // get initial c/h/r
\r
606 int ofs = DS * 16 + DI;
\r
612 disk[drv]->get_track(trk, hed);
\r
613 access_fdd[drv] = true;
\r
615 if(!disk[drv]->get_sector(trk, hed, sct - 1)) {
\r
617 CX = ERR_FDD_NOTFOUND;
\r
622 for(int i = 0; i < disk[drv]->sector_size; i++) {
\r
623 disk[drv]->sector[i] = d_mem->read_data8(ofs++);
\r
626 // clear deleted mark and crc error
\r
627 disk[drv]->deleted = 0;
\r
628 disk[drv]->status = 0;
\r
630 if(++sct > disk[drv]->sector_num) {
\r
643 if((AL & 0xf0) == 0x50) {
\r
645 if(!(drv < MAX_MEMCARD && memcard_blocks[drv])) {
\r
647 CX = ERR_MEMCARD_NOTREADY;
\r
651 if(memcard_protected[drv]) {
\r
653 CX = ERR_MEMCARD_PROTECTED;
\r
657 FILEIO* fio = new FILEIO();
\r
658 if(!fio->Fopen(memcard_path[drv], FILEIO_READ_WRITE_BINARY)) {
\r
660 CX = ERR_MEMCARD_NOTREADY;
\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
671 access_scsi = true;
\r
672 if(!(block++ < scsi_blocks[drv])) {
\r
674 CX = ERR_MEMCARD_PARAMERROR;
\r
681 for(int i = 0; i < BLOCK_SIZE; i++) {
\r
682 buffer[i] = d_mem->read_data8(ofs++);
\r
684 fio->Fwrite(buffer, BLOCK_SIZE, 1);
\r
694 if((AL & 0xf0) == 0xb0) {
\r
696 if(!(drv < MAX_SCSI && scsi_blocks[drv])) {
\r
698 CX = ERR_SCSI_NOTCONNECTED;
\r
702 FILEIO* fio = new FILEIO();
\r
703 if(!fio->Fopen(scsi_path[drv], FILEIO_READ_WRITE_BINARY)) {
\r
705 CX = ERR_SCSI_NOTREADY;
\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
716 access_scsi = true;
\r
717 if(!(block++ < scsi_blocks[drv])) {
\r
719 CX = ERR_SCSI_PARAMERROR;
\r
726 for(int i = 0; i < BLOCK_SIZE; i++) {
\r
727 buffer[i] = d_mem->read_data8(ofs++);
\r
729 fio->Fwrite(buffer, BLOCK_SIZE, 1);
\r
742 } else if(AH == 7) {
\r
744 if((AL & 0xf0) == 0x20) {
\r
746 if(!(drv < MAX_DRIVE && disk[drv]->inserted)) {
\r
748 CX = ERR_FDD_NOTREADY;
\r
752 // get initial c/h/r
\r
758 disk[drv]->get_track(trk, hed);
\r
759 access_fdd[drv] = true;
\r
761 if(!disk[drv]->get_sector(trk, hed, sct - 1)) {
\r
763 CX = ERR_FDD_NOTFOUND;
\r
769 if(disk[drv]->status) {
\r
771 CX = ERR_FDD_CRCERROR;
\r
776 if(++sct > disk[drv]->sector_num) {
\r
789 if((AL & 0xf0) == 0xb0) {
\r
791 if(!(drv < MAX_SCSI && scsi_blocks[drv])) {
\r
793 CX = ERR_SCSI_NOTCONNECTED;
\r
798 int block = (CL << 16) | DX;
\r
801 access_scsi = true;
\r
802 if(!(block++ < scsi_blocks[drv])) {
\r
804 CX = ERR_SCSI_PARAMERROR;
\r
818 } else if(AH == 8) {
\r
819 // reset hard drive controller
\r
824 } else if(AH == 9) {
\r
826 if((AL & 0xf0) == 0x20) {
\r
828 if(!(drv < MAX_DRIVE && disk[drv]->inserted)) {
\r
830 CX = ERR_FDD_NOTREADY;
\r
835 int ofs = DS * 16 + DI;
\r
839 disk[drv]->get_track(trk, hed);
\r
840 access_fdd[drv] = true;
\r
841 if(++secnum > disk[drv]->sector_num) {
\r
844 if(!disk[drv]->get_sector(trk, hed, secnum - 1)) {
\r
846 CX = ERR_FDD_NOTFOUND;
\r
850 for(int i = 0; i < 6; i++) {
\r
851 d_mem->write_data8(ofs++, disk[drv]->id[i]);
\r
861 } else if(AH == 0xa) {
\r
863 if((AL & 0xf0) == 0x20) {
\r
865 if(!(drv < MAX_DRIVE && disk[drv]->inserted)) {
\r
867 CX = ERR_FDD_NOTREADY;
\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
891 } else if(AH == 0xd) {
\r
897 } else if(AH == 0xe) {
\r
899 if((AL & 0xf0) == 0x20) {
\r
901 if(!(drv < MAX_DRIVE && disk[drv]->inserted)) {
\r
910 DL = disk[drv]->changed ? 1 : 0;
\r
911 disk[drv]->changed = false;
\r
915 if((AL & 0xf0) == 0xb0) {
\r
917 if(!(drv < MAX_SCSI && scsi_blocks[drv])) {
\r
932 } else if(AH == 0xfa) {
\r
934 if((AL & 0xf0) == 0x20) {
\r
941 if((AL & 0xf0) == 0xb0) {
\r
943 if(!(drv < MAX_SCSI && scsi_blocks[drv])) {
\r
945 CX = ERR_SCSI_NOTCONNECTED;
\r
957 } else if(AH == 0xfd) {
\r
959 if((AL & 0xf0) == 0x20) {
\r
966 if((AL & 0xf0) == 0xb0) {
\r
968 if(!(drv < MAX_SCSI && scsi_blocks[drv])) {
\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
989 d_io->write_io8(iotable[i][0], iotable[i][1]);
\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
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
1003 memset(vram, 0, VRAM_SIZE);
\r
1005 memset(cvram, 0, 0x2000);
\r
1006 memset(avram, 0, 0x2000);
\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
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
1023 disk[0]->get_track(0, 0);
\r
1024 access_fdd[0] = true;
\r
1025 if(!disk[0]->get_sector(0, 0, 0)) {
\r
1029 for(int i = 0; i < disk[0]->sector_size; i++) {
\r
1030 buffer[i] = disk[0]->sector[i];
\r
1033 if(!(buffer[0] == 'I' && buffer[1] == 'P' && buffer[2] == 'L' && buffer[3] == IPL_ID)) {
\r
1038 for(int i = 0; i < disk[0]->sector_size; i++) {
\r
1039 d_mem->write_data8(0xb0000 + i, buffer[i]);
\r
1043 memset(cvram, 0, 0x2000);
\r
1044 memset(avram, 0, 0x2000);
\r
1046 memset(cvram, 0, 0x1000);
\r
1047 memset(kvram, 0, 0x1000);
\r
1056 } else if(AH == 0x82) {
\r
1057 // pseudo bios: boot from scsi-hdd #0
\r
1059 if(!scsi_blocks[0]) {
\r
1063 FILEIO* fio = new FILEIO();
\r
1064 if(!fio->Fopen(scsi_path[drv], FILEIO_READ_BINARY)) {
\r
1070 access_scsi = true;
\r
1071 fio->Fread(buffer, BLOCK_SIZE * 4, 1);
\r
1075 if(!(buffer[0] == 'I' && buffer[1] == 'P' && buffer[2] == 'L' && buffer[3] == IPL_ID)) {
\r
1080 for(int i = 0; i < BLOCK_SIZE * 4; i++) {
\r
1081 d_mem->write_data8(0xb0000 + i, buffer[i]);
\r
1085 memset(cvram, 0, 0x2000);
\r
1086 memset(avram, 0, 0x2000);
\r
1088 memset(cvram, 0, 0x1000);
\r
1089 memset(kvram, 0, 0x1000);
\r
1099 } else if(PC == cmos_pc) {
\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
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
1110 BX = cmos[0xa2] | (cmos[0xa3] << 8);
\r
1111 } else if(AH == 10) {
\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
1120 } else if(AH == 11) {
\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
1129 } else if(AH == 20) {
\r
1130 // check block header
\r
1136 } else if(PC == wait_pc) {
\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
1147 bool BIOS::bios_int(int intnum, uint16 regs[], uint16 sregs[], int32* ZeroFlag, int32* CarryFlag)
\r
1149 uint8 *regs8 = (uint8 *)regs;
\r
1151 if(intnum == 0x93) {
\r
1153 return bios_call(0xfffc4, regs, sregs, ZeroFlag, CarryFlag);
\r
1154 } else if(intnum == 0xaa) {
\r
1155 // power management bios
\r
1166 } else if(AH == 1) {
\r
1168 AL = BL = powmode;
\r
1176 uint32 BIOS::read_signal(int ch)
\r
1178 // get access status
\r
1180 for(int i = 0; i < MAX_DRIVE; i++) {
\r
1181 if(access_fdd[i]) {
\r
1184 access_fdd[i] = false;
\r
1189 access_scsi = false;
\r