2 Common Source Code Project
3 MSX Series (experimental)
5 Origin : src/vm/msx/memory.cpp
13 #include "memory_ex.h"
16 #include "../tms9918a.h"
18 #if defined(FDD_PATCH_SLOT)
20 #if defined(MSX_FDD_PATCH_WITH_2HD)
21 #define MSX_SECTOR_SIZE (disk[drv]->sector_size.sd)
23 #define MSX_SECTOR_SIZE 512
26 #if defined(FDD_PATCH_SLOT) && defined(_MSX_VDP_MESS)
34 #define EVENT_ROMTYPE 1
35 #define ROMTYPE_NONE (-1)
36 static struct s_typestr {
40 {ROM_ASCII8, _T("ASCII8")},
41 {ROM_ASCII16, _T("ASCII16")},
42 {ROM_KONAMI, _T("KONAMI")},
43 {ROM_KONAMI_SCC, _T("KONAMI_SCC")},
44 {ROMTYPE_NONE, _T("NONE")}
54 #define SET_BANK(s, e, w, r) { \
55 int sb = (s) >> 13, eb = (e) >> 13; \
56 for(int i = sb; i <= eb; i++) { \
57 if(((uintptr_t)w) == ((uintptr_t)wdmy)) { \
60 wbank[i] = (w) + 0x2000 * (i - sb); \
62 if(((uintptr_t)r) == ((uintptr_t)rdmy)) { \
65 rbank[i] = (r) + 0x2000 * (i - sb); \
70 #if defined(FDD_PATCH_SLOT)
73 uint8_t heads, names, per_track, per_fat, per_cluster;
75 { 720, 1, 112, 9, 2, 2 },
76 { 1440, 2, 112, 9, 3, 2 },
77 { 640, 1, 112, 8, 1, 2 },
78 { 1280, 2, 112, 8, 2, 2 },
79 { 360, 1, 64, 9, 2, 1 },
80 { 720, 2, 112, 9, 2, 2 },
81 { 320, 1, 64, 8, 1, 1 },
82 { 640, 2, 112, 8, 1, 2 }
85 static const uint8_t boot_block[] = {
86 0xeb, 0xfe, 0x90, 0x56, 0x46, 0x42, 0x2d, 0x31, 0x39, 0x38, 0x39, 0x00, 0x02, 0x02, 0x01, 0x00,
87 0x02, 0x70, 0x00, 0xa0, 0x05, 0xf9, 0x03, 0x00, 0x09, 0x00, 0x02, 0x00, 0x00, 0x00, 0xd0, 0xed,
88 0x53, 0x58, 0xc0, 0x32, 0xc2, 0xc0, 0x36, 0x55, 0x23, 0x36, 0xc0, 0x31, 0x1f, 0xf5, 0x11, 0x9d,
89 0xc0, 0x0e, 0x0f, 0xcd, 0x7d, 0xf3, 0x3c, 0x28, 0x28, 0x11, 0x00, 0x01, 0x0e, 0x1a, 0xcd, 0x7d,
90 0xf3, 0x21, 0x01, 0x00, 0x22, 0xab, 0xc0, 0x21, 0x00, 0x3f, 0x11, 0x9d, 0xc0, 0x0e, 0x27, 0xcd,
91 0x7d, 0xf3, 0xc3, 0x00, 0x01, 0x57, 0xc0, 0xcd, 0x00, 0x00, 0x79, 0xe6, 0xfe, 0xfe, 0x02, 0x20,
92 0x07, 0x3a, 0xc2, 0xc0, 0xa7, 0xca, 0x22, 0x40, 0x11, 0x77, 0xc0, 0x0e, 0x09, 0xcd, 0x7d, 0xf3,
93 0x0e, 0x07, 0xcd, 0x7d, 0xf3, 0x18, 0xb4, 0x42, 0x6f, 0x6f, 0x74, 0x20, 0x65, 0x72, 0x72, 0x6f,
94 0x72, 0x0d, 0x0a, 0x50, 0x72, 0x65, 0x73, 0x73, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x6b, 0x65, 0x79,
95 0x20, 0x66, 0x6f, 0x72, 0x20, 0x72, 0x65, 0x74, 0x72, 0x79, 0x0d, 0x0a, 0x24, 0x00, 0x4d, 0x53,
96 0x58, 0x44, 0x4f, 0x53, 0x20, 0x20, 0x53, 0x59, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
97 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
98 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x2a,
99 0x51, 0xf3, 0x11, 0x00, 0x01, 0x19, 0x01, 0x00, 0x01, 0x11, 0x00, 0xc1, 0xed, 0xb0, 0x3a, 0xee,
100 0xc0, 0x47, 0x11, 0xef, 0xc0, 0x21, 0x00, 0x00, 0xcd, 0x51, 0x52, 0xf3, 0x76, 0xc9, 0x18, 0x64,
101 0x3a, 0xaf, 0x80, 0xf9, 0xca, 0x6d, 0x48, 0xd3, 0xa5, 0x0c, 0x8c, 0x2f, 0x9c, 0xcb, 0xe9, 0x89,
102 0xd2, 0x00, 0x32, 0x26, 0x40, 0x94, 0x61, 0x19, 0x20, 0xe6, 0x80, 0x6d, 0x8a, 0x00, 0x00, 0x00,
103 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
104 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
105 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
106 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
107 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
108 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
109 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
110 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
111 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
112 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
113 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
114 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
115 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
116 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
117 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
120 static int DSKIO = -1, DSKCHG = -1, GETDPB = -1, DSKFMT = -1;
123 bool SLOT_CART::load_cart(const _TCHAR *file_path/*, uint8_t *rom*/)
126 FILEIO* fio = new FILEIO();
127 if(fio->Fopen(file_path, FILEIO_READ_BINARY)) {
128 memset(rom, 0xff, 0x10000);
130 fio->Fseek(0, FILEIO_SEEK_END);
131 uint32_t file_size = fio->Ftell();
132 fio->Fseek(0, FILEIO_SEEK_SET);
136 SET_BANK(0x0000, 0xffff, wdmy, rom);
138 d_sound->disable_all();
140 if(file_size <= 0x2000) {
142 fio->Fread(rom, 0x2000, 1);
143 memcpy(rom + 0x2000, rom, 0x2000);
144 memcpy(rom + 0x4000, rom, 0x4000);
145 memcpy(rom + 0x8000, rom, 0x8000);
146 } else if(file_size <= 0x4000) {
148 fio->Fread(rom, 0x4000, 1);
149 memcpy(rom + 0x4000, rom, 0x4000);
150 memcpy(rom + 0x8000, rom, 0x8000);
151 } else if(file_size <= 0x8000) {
153 fio->Fread(rom + 0x4000, 0x8000, 1);
154 memcpy(rom + 0x0000, rom + 0x4000, 0x4000);
155 memcpy(rom + 0xc000, rom + 0x8000, 0x4000);
158 if(file_size > 0x10000) {
159 if(file_size > sizeof(rom)) file_size = sizeof(rom);
160 fio->Fread(rom, file_size, 1);
161 type = hashRomType(rom, file_size);
162 if (ROMTYPE_NONE == type) type = guessRomType(rom, file_size);
173 //register_event(this, EVENT_ROMTYPE, 1000000.0 * 5, false, NULL);
174 if (-1 != event_register_id) {
175 cancel_event(this, event_register_id);
176 event_register_id = -1;
178 register_event(this, EVENT_ROMTYPE, 1000000.0 * 5, true, &event_register_id);
179 SET_BANK(0x0000, 0x3fff, wdmy, rdmy);
180 SET_BANK(0xc000, 0xffff, wdmy, rdmy);
181 SET_BANK(0x4000, 0xbfff, wdmy, rom);
182 if(file_size <= 0x20000) {
183 memcpy(rom + 0x20000, rom, 0x20000);
185 if(file_size <= 0x40000) {
186 memcpy(rom + 0x40000, rom, 0x40000);
188 if(file_size <= 0x80000) {
189 memcpy(rom + 0x80000, rom, 0x80000);
191 if(file_size <= 0x100000) {
192 memcpy(rom + 0x100000, rom, 0x100000);
194 if(file_size <= 0x200000) {
195 memcpy(rom + 0x200000, rom, 0x200000);
198 if (ROM_KONAMI_SCC == type) {
199 d_sound->enable_c(SOUND_CHIP_SCC, true);
201 // for IKARI(ASCII 16Kb)
202 if (ROM_ASCII16 == type) {
203 SET_BANK(0x4000, 0x7fff, wdmy, rom+0x2000*(0*2));
204 SET_BANK(0x8000, 0xbfff, wdmy, rom+0x2000*(0*2));
209 fio->Fread(rom, 0x10000, 1);
213 fio->Fread(rom, 0x10000, 1);
224 // or MAIN ROM 32K + MAIN RAM 32K
226 void SLOT_MAINROM::initialize()
228 memset(rom, 0xff, sizeof(rom));
229 #ifdef MAINROM_PLUS_RAM_32K
230 memset(ram, 0, sizeof(ram));
232 FILEIO* fio = new FILEIO();
233 #if defined(_MSX2P_VARIANTS)
234 if(fio->Fopen(create_local_path(_T("MSX2P.ROM")), FILEIO_READ_BINARY) ||
235 #elif defined(_MSX2_VARIANTS)
236 if(fio->Fopen(create_local_path(_T("MSX2J.ROM")), FILEIO_READ_BINARY) ||
237 fio->Fopen(create_local_path(_T("MSX2.ROM" )), FILEIO_READ_BINARY) ||
239 if(fio->Fopen(create_local_path(_T("MSXJ.ROM")), FILEIO_READ_BINARY) ||
240 fio->Fopen(create_local_path(_T("MSX.ROM" )), FILEIO_READ_BINARY) ||
242 fio->Fopen(create_local_path(_T("BASIC.ROM")), FILEIO_READ_BINARY)) {
243 fio->Fread(rom, sizeof(rom), 1);
248 SET_BANK(0x0000, 0x7fff, wdmy, rom);
249 #ifdef MAINROM_PLUS_RAM_32K
250 SET_BANK(0x8000, 0xffff, ram, ram);
252 SET_BANK(0x8000, 0xffff, wdmy, rdmy);
256 void SLOT_MAINROM::write_data8(uint32_t addr, uint32_t data)
258 wbank[addr >> 13][addr & 0x1fff] = data;
261 uint32_t SLOT_MAINROM::read_data8(uint32_t addr)
263 return rbank[addr >> 13][addr & 0x1fff];
266 #define SLOT_MAINROM_STATE_VERSION 1
268 bool SLOT_MAINROM::process_state(FILEIO* state_fio, bool loading)
270 if(!state_fio->StateCheckUint32(SLOT_MAINROM_STATE_VERSION)) {
273 if(!state_fio->StateCheckInt32(this_device_id)) {
276 #ifdef MAINROM_PLUS_RAM_32K
277 state_fio->StateArray(ram, sizeof(ram), 1);
284 void SLOT_CART::initialize()
286 memset(rdmy, 0xff, sizeof(rdmy));
290 void SLOT_CART::write_data8(uint32_t addr, uint32_t data)
293 if (ROM_KONAMI == type) {
294 // Konami without SCC
296 if ((0x6000 <=addr) && (addr < 0x8000)) {
297 SET_BANK(0x6000, 0x7fff, wdmy, rom+0x2000*(data));
299 if ((0x8000 <=addr) && (addr < 0xa000)) {
300 SET_BANK(0x8000, 0x9fff, wdmy, rom+0x2000*(data));
302 if ((0xa000 <=addr) && (addr < 0xc000)) {
303 SET_BANK(0xa000, 0xbfff, wdmy, rom+0x2000*(data));
305 //wbank[addr >> 13][addr & 0x1fff] = data;
307 else if (ROM_KONAMI_SCC == type) {
310 if ((0x5000 <=addr) && (addr < 0x5800)) {
311 SET_BANK(0x4000, 0x5fff, wdmy, rom+0x2000*(data));
313 if ((0x7000 <=addr) && (addr < 0x7800)) {
314 SET_BANK(0x6000, 0x7fff, wdmy, rom+0x2000*(data));
316 if ((0x9000 <=addr) && (addr < 0x9800)) {
317 SET_BANK(0x8000, 0x9fff, wdmy, rom+0x2000*(data));
318 bank_scc = ((data&0x3F)==0x3F);
320 if ((0xb000 <=addr) && (addr < 0xb800)) {
321 SET_BANK(0xa000, 0xbfff, wdmy, rom+0x2000*(data));
323 if ((bank_scc) && (0x9000 <=addr) && (addr < 0x9900)) {
324 d_sound->write_data8_c(SOUND_CHIP_SCC, addr & 0xFFFF, data);
326 //wbank[addr >> 13][addr & 0x1fff] = data;
328 else if (ROM_ASCII8 == type) {
331 if ((0x6000 <=addr) && (addr < 0x6800)) {
332 SET_BANK(0x4000, 0x5fff, wdmy, rom+0x2000*(data));
334 if ((0x6800 <=addr) && (addr < 0x7000)) {
335 SET_BANK(0x6000, 0x7fff, wdmy, rom+0x2000*(data));
337 if ((0x7000 <=addr) && (addr < 0x7800)) {
338 SET_BANK(0x8000, 0x9fff, wdmy, rom+0x2000*(data));
340 if ((0x7800 <=addr) && (addr < 0x8000)) {
341 SET_BANK(0xa000, 0xbfff, wdmy, rom+0x2000*(data));
343 //wbank[addr >> 13][addr & 0x1fff] = data;
345 else if (ROM_ASCII16 == type) {
349 if ((0x6000 <=addr) && (addr < 0x6800)) {
350 //SET_BANK(0x4000, 0x5fff, wdmy, rom+0x2000*(data*2));
351 //SET_BANK(0x6000, 0x7fff, wdmy, rom+0x2000*(data*2+1));
352 SET_BANK(0x4000, 0x7fff, wdmy, rom+0x2000*(data*2));
354 if ((0x7000 <=addr) && (addr < 0x7800)) {
355 //SET_BANK(0x8000, 0x9fff, wdmy, rom+0x2000*(data*2));
356 //SET_BANK(0xa000, 0xbfff, wdmy, rom+0x2000*(data*2+1));
357 SET_BANK(0x8000, 0xbfff, wdmy, rom+0x2000*(data*2));
359 //wbank[addr >> 13][addr & 0x1fff] = data;
361 else /*if (ROMTYPE_NONE == type)*/ {
362 wbank[addr >> 13][addr & 0x1fff] = data;
365 wbank[addr >> 13][addr & 0x1fff] = data;
369 uint32_t SLOT_CART::read_data8(uint32_t addr)
373 if ((ROM_KONAMI_SCC == type) && (bank_scc) && (0x9000 <=addr) && (addr < 0x9900)) {
374 return d_sound->read_data8_c(SOUND_CHIP_SCC, addr & 0xFFFF);
377 return rbank[addr >> 13][addr & 0x1fff];
380 return rbank[addr >> 13][addr & 0x1fff];
384 void SLOT_CART::open_cart(const _TCHAR *file_path)
386 if(load_cart(file_path/*, rom*/)) {
387 // SET_BANK(0x0000, 0xffff, wdmy, rom);
392 void SLOT_CART::close_cart()
396 // SET_BANK(0x0000, 0xffff, wdmy, rom);
398 d_sound->disable_all();
400 SET_BANK(0x0000, 0xffff, wdmy, rdmy);
406 void SLOT_CART::event_callback(int event_id, int err)
408 if(event_id == EVENT_ROMTYPE) {
412 if ((typestr[i].type == type) || (typestr[i].type == ROMTYPE_NONE)) {
418 if (-1 != event_register_id) {
419 cancel_event(this, event_register_id);
420 event_register_id = -1;
426 #define SLOT_CART_STATE_VERSION 1
428 bool SLOT_CART::process_state(FILEIO* state_fio, bool loading)
430 if(!state_fio->StateCheckUint32(SLOT_CART_STATE_VERSION)) {
433 if(!state_fio->StateCheckInt32(this_device_id)) {
436 state_fio->StateValue(inserted);
438 state_fio->StateValue(type);
439 state_fio->StateValue(bank_scc);
440 /* Todo: MEGA ROM bank select */
444 SET_BANK(0x0000, 0xffff, wdmy, rom);
446 i32 = state_fio->FgetInt32_LE() ; rbank[0] = ((i32 == -1) ? rdmy : rom + i32);
447 i32 = state_fio->FgetInt32_LE() ; rbank[1] = ((i32 == -1) ? rdmy : rom + i32);
448 i32 = state_fio->FgetInt32_LE() ; rbank[2] = ((i32 == -1) ? rdmy : rom + i32);
449 i32 = state_fio->FgetInt32_LE() ; rbank[3] = ((i32 == -1) ? rdmy : rom + i32);
450 i32 = state_fio->FgetInt32_LE() ; rbank[4] = ((i32 == -1) ? rdmy : rom + i32);
451 i32 = state_fio->FgetInt32_LE() ; rbank[5] = ((i32 == -1) ? rdmy : rom + i32);
452 i32 = state_fio->FgetInt32_LE() ; rbank[6] = ((i32 == -1) ? rdmy : rom + i32);
453 i32 = state_fio->FgetInt32_LE() ; rbank[7] = ((i32 == -1) ? rdmy : rom + i32);
455 SET_BANK(0x0000, 0xffff, wdmy, rdmy);
459 state_fio->FputInt32_LE(rbank[0]==rdmy ? (-1) : (int)(rbank[0] - rom));
460 state_fio->FputInt32_LE(rbank[1]==rdmy ? (-1) : (int)(rbank[1] - rom));
461 state_fio->FputInt32_LE(rbank[2]==rdmy ? (-1) : (int)(rbank[2] - rom));
462 state_fio->FputInt32_LE(rbank[3]==rdmy ? (-1) : (int)(rbank[3] - rom));
463 state_fio->FputInt32_LE(rbank[4]==rdmy ? (-1) : (int)(rbank[4] - rom));
464 state_fio->FputInt32_LE(rbank[5]==rdmy ? (-1) : (int)(rbank[5] - rom));
465 state_fio->FputInt32_LE(rbank[6]==rdmy ? (-1) : (int)(rbank[6] - rom));
466 state_fio->FputInt32_LE(rbank[7]==rdmy ? (-1) : (int)(rbank[7] - rom));
473 SET_BANK(0x0000, 0xffff, wdmy, rom);
475 SET_BANK(0x0000, 0xffff, wdmy, rdmy);
483 #if defined(MSXDOS2_SLOT)
484 void SLOT_MSXDOS2::initialize()
486 memset(rdmy, 0xff, sizeof(rdmy));
488 SET_BANK(0x0000, 0xffff, wdmy, rdmy);
489 mapper[0] = mapper[1] = 4;
490 FILEIO* fio = new FILEIO();
491 if(fio->Fopen(create_local_path(_T("MSXDOS2.ROM")), FILEIO_READ_BINARY)) {
492 fio->Fread(rom, sizeof(rom), 1);
496 SET_BANK(0x4000, 0x7fff, wdmy, rom + mapper[0] * 0x4000);
497 SET_BANK(0x8000, 0xbfff, wdmy, rom + mapper[1] * 0x4000);
502 void SLOT_MSXDOS2::write_data8(uint32_t addr, uint32_t data)
504 if(addr >= 0x4000 && addr < 0xc000 && mapper[0] < 4) {
508 if(mapper[addr] != data) {
510 SET_BANK(addr * 0x4000 + 0x4000, addr * 0x4000 + 0x7fff, wdmy, rom + data * 0x4000);
514 wbank[addr >> 13][addr & 0x1fff] = data;
517 uint32_t SLOT_MSXDOS2::read_data8(uint32_t addr)
519 return rbank[addr >> 13][addr & 0x1fff];
522 #define SLOT_MSXDOS2_STATE_VERSION 1
524 bool SLOT_MSXDOS2::process_state(FILEIO* state_fio, bool loading)
526 if(!state_fio->StateCheckUint32(SLOT_MSXDOS2_STATE_VERSION)) {
529 if(!state_fio->StateCheckInt32(this_device_id)) {
532 state_fio->StateArray(mapper, sizeof(mapper), 1);
537 SET_BANK(0x0000, 0x3fff, wdmy, rdmy);
538 SET_BANK(0x4000, 0x7fff, wdmy, rom + mapper[0] * 0x4000);
539 SET_BANK(0x8000, 0xbfff, wdmy, rom + mapper[1] * 0x4000);
540 SET_BANK(0xc000, 0xffff, wdmy, rdmy);
542 SET_BANK(0x0000, 0xffff, wdmy, rdmy);
552 #if defined(LDC_SLOT)
553 void SLOT_LDC::initialize()
555 memset(rom, 0xff, sizeof(rom));
556 memset(rdmy, 0xff, sizeof(rdmy));
558 FILEIO* fio = new FILEIO();
559 if(fio->Fopen(create_local_path(_T("PX7EXT.ROM")), FILEIO_READ_BINARY) ||
560 fio->Fopen(create_local_path(_T("EXT.ROM") ), FILEIO_READ_BINARY)) {
561 fio->Fread(rom, sizeof(rom), 1);
566 SET_BANK(0x0000, 0x3fff, wdmy, rdmy);
567 SET_BANK(0x4000, 0x5fff, wdmy, rom);
568 SET_BANK(0x6000, 0xffff, wdmy, rdmy);
570 clock = exv = ack = false;
572 register_event(this, EVENT_CLOCK, 1000000.0 / 7812.5, true, NULL);
575 void SLOT_LDC::reset()
577 super_impose = false;
580 mute_l = mute_r = true;
582 d_ldp->write_signal(SIG_LD700_MUTE_L, 1, 1);
583 d_ldp->write_signal(SIG_LD700_MUTE_R, 1, 1);
584 d_vdp->write_signal(SIG_TMS9918A_SUPER_IMPOSE, 0, 0);
587 void SLOT_LDC::write_data8(uint32_t addr, uint32_t data)
590 d_ldp->write_signal(SIG_LD700_REMOTE, data, 1);
591 } else if(addr == 0x7fff) {
593 bool prev_super_impose = super_impose;
594 super_impose = ((data & 1) == 0);
596 if(req_intr && !prev_super_impose) {
597 d_cpu->write_signal(SIG_CPU_IRQ, 1, 1);
600 d_cpu->write_signal(SIG_CPU_IRQ, 0, 0);
602 d_vdp->write_signal(SIG_TMS9918A_SUPER_IMPOSE, super_impose ? 1 : 0, 1);
605 bool prev_mute_l = mute_l;
606 mute_l = ((data & 0x80) == 0);
607 if(!prev_mute_l && mute_l) {
610 d_ldp->write_signal(SIG_LD700_MUTE_L, mute_l ? 1 : 0, 1);
611 d_ldp->write_signal(SIG_LD700_MUTE_R, mute_r ? 1 : 0, 1);
613 wbank[addr >> 13][addr & 0x1fff] = data;
617 uint32_t SLOT_LDC::read_data8(uint32_t addr)
620 return (clock ? 0 : 1) | (ack ? 0 : 0x80) | 0x7e;
621 } else if(addr == 0x7fff) {
622 uint32_t data = (req_intr ? 1 : 0) | (exv ? 0 : 0x80) | 0x7e;
624 d_cpu->write_signal(SIG_CPU_IRQ, 0, 0);
627 return rbank[addr >> 13][addr & 0x1fff];
631 void SLOT_LDC::write_signal(int id, uint32_t data, uint32_t mask)
633 if(id == SIG_LDC_EXV) {
635 exv = ((data & mask) != 0);
639 d_cpu->write_signal(SIG_CPU_IRQ, 1, 1);
642 } else if(id == SIG_LDC_ACK) {
643 ack = ((data & mask) != 0);
644 } else if(id == SIG_LDC_MUTE) {
645 pc4 = ((data & mask) != 0);
649 void SLOT_LDC::event_callback(int event_id, int err)
651 if(event_id == EVENT_CLOCK) {
656 #define SLOT_LDC_STATE_VERSION 1
658 bool SLOT_LDC::process_state(FILEIO* state_fio, bool loading)
660 if(!state_fio->StateCheckUint32(SLOT_LDC_STATE_VERSION)) {
663 if(!state_fio->StateCheckInt32(this_device_id)) {
666 state_fio->StateValue(clock);
667 state_fio->StateValue(exv);
668 state_fio->StateValue(ack);
669 state_fio->StateValue(super_impose);
670 state_fio->StateValue(req_intr);
671 state_fio->StateValue(pc4);
672 state_fio->StateValue(mute_l);
673 state_fio->StateValue(mute_r);
680 #if defined(SUBROM_SLOT)
681 void SLOT_SUBROM::initialize()
683 memset(rom, 0xff, sizeof(rom));
684 memset(rdmy, 0xff, sizeof(rdmy));
686 FILEIO* fio = new FILEIO();
687 #if defined(_MSX2_VARIANTS)
688 if(fio->Fopen(create_local_path(_T("MSX2JEXT.ROM")), FILEIO_READ_BINARY) ||
689 fio->Fopen(create_local_path(_T("MSX2EXT.ROM" )), FILEIO_READ_BINARY)) {
690 fio->Fread(rom, sizeof(rom), 1);
693 #elif defined(_MSX2P_VARIANTS)
694 if(fio->Fopen(create_local_path(_T("MSX2PEXT.ROM" )), FILEIO_READ_BINARY)) {
695 fio->Fread(rom, sizeof(rom), 1);
698 if(fio->Fopen(create_local_path(_T("KNJDRV.ROM" )), FILEIO_READ_BINARY)) {
699 fio->Fread(rom + 0x4000, sizeof(rom) - 0x4000, 1);
705 SET_BANK(0x4000, 0xffff, wdmy, rdmy);
706 #if defined(_MSX2_VARIANTS)
707 SET_BANK(0x0000, 0x3fff, wdmy, rom);
708 #elif defined(_MSX2P_VARIANTS)
709 SET_BANK(0x0000, 0xbfff, wdmy, rom);
713 void SLOT_SUBROM::write_data8(uint32_t addr, uint32_t data)
715 wbank[addr >> 13][addr & 0x1fff] = data;
718 uint32_t SLOT_SUBROM::read_data8(uint32_t addr)
720 return rbank[addr >> 13][addr & 0x1fff];
724 // FDD with ROM-PATCH
726 #if defined(FDD_PATCH_SLOT)
727 void SLOT_FDD_PATCH::initialize()
729 memset(rom, 0xff, sizeof(rom));
730 memset(rdmy, 0xff, sizeof(rdmy));
732 FILEIO* fio = new FILEIO();
733 if(fio->Fopen(create_local_path(_T("DISK.ROM")), FILEIO_READ_BINARY)) {
734 fio->Fread(rom, sizeof(rom), 1);
739 // patch for pseudo disk bios
740 if(rom[0x0010] == 0xc3) {
741 rom[(DSKIO = rom[0x0011] + (int)rom[0x0012] * 256) - 0x4000] = 0xc9;
743 if(rom[0x0013] == 0xc3) {
744 rom[(DSKCHG = rom[0x0014] + (int)rom[0x0015] * 256) - 0x4000] = 0xc9;
746 if(rom[0x0016] == 0xc3) {
747 rom[(GETDPB = rom[0x0017] + (int)rom[0x0018] * 256) - 0x4000] = 0xc9;
749 if(rom[0x001c] == 0xc3) {
750 rom[(DSKFMT = rom[0x001d] + (int)rom[0x001e] * 256) - 0x4000] = 0xc9;
752 if(rom[0x001f] == 0xc3) {
753 rom[( rom[0x0020] + (int)rom[0x0021] * 256) - 0x4000] = 0xc9;
755 SET_BANK(0x0000, 0xffff, wdmy, rdmy);
756 SET_BANK(0x4000, 0x7fff, wdmy, rom);
759 void SLOT_FDD_PATCH::write_data8(uint32_t addr, uint32_t data)
761 wbank[addr >> 13][addr & 0x1fff] = data;
764 uint32_t SLOT_FDD_PATCH::read_data8(uint32_t addr)
766 return rbank[addr >> 13][addr & 0x1fff];
772 #if defined(MAPPERRAM_SLOT)
773 void SLOT_MAPPERRAM::initialize()
775 memset(ram, 0xff, sizeof(ram));
777 for(int i = 0; i < 4; i++) {
780 SET_BANK(0x0000, 0xffff, ram, ram);
783 void SLOT_MAPPERRAM::write_data8(uint32_t addr, uint32_t data)
785 wbank[addr >> 13][addr & 0x1fff] = data;
788 uint32_t SLOT_MAPPERRAM::read_data8(uint32_t addr)
790 return rbank[addr >> 13][addr & 0x1fff];
793 void SLOT_MAPPERRAM::write_io8(uint32_t addr, uint32_t data)
795 switch(addr & 0xff) {
801 data &= MAPPERRAM_MASK;
802 if(mapper[addr] != data) {
804 SET_BANK(addr * 0x4000, addr * 0x4000 + 0x3fff, ram + data * 0x4000, ram + data * 0x4000);
810 #define SLOT_MAPPERRAM_STATE_VERSION 1
812 bool SLOT_MAPPERRAM::process_state(FILEIO* state_fio, bool loading)
814 if(!state_fio->StateCheckUint32(SLOT_MAPPERRAM_STATE_VERSION)) {
817 if(!state_fio->StateCheckInt32(this_device_id)) {
820 state_fio->StateArray(ram, sizeof(ram), 1);
821 state_fio->StateArray(mapper, sizeof(mapper), 1);
825 SET_BANK(0x0000, 0x3fff, ram + mapper[0] * 0x4000, ram + mapper[0] * 0x4000);
826 SET_BANK(0x4000, 0x7fff, ram + mapper[1] * 0x4000, ram + mapper[1] * 0x4000);
827 SET_BANK(0x8000, 0xbfff, ram + mapper[2] * 0x4000, ram + mapper[2] * 0x4000);
828 SET_BANK(0xc000, 0xffff, ram + mapper[3] * 0x4000, ram + mapper[3] * 0x4000);
836 #if defined(RAM64K_SLOT)
837 void SLOT_RAM64K::initialize()
839 memset(ram, 0xff, sizeof(ram));
842 void SLOT_RAM64K::write_data8(uint32_t addr, uint32_t data)
844 ram[addr & 0xffff] = data;
847 uint32_t SLOT_RAM64K::read_data8(uint32_t addr)
849 return ram[addr & 0xffff];
852 #define SLOT_RAM64K_STATE_VERSION 1
854 bool SLOT_RAM64K::process_state(FILEIO* state_fio, bool loading)
856 if(!state_fio->StateCheckUint32(SLOT_RAM64K_STATE_VERSION)) {
859 if(!state_fio->StateCheckInt32(this_device_id)) {
862 state_fio->StateArray(ram, sizeof(ram), 1);
869 #if defined(FIRMWARE32K1_SLOT)
870 void SLOT_FIRMWARE32K::initialize()
872 memset(rom, 0xff, sizeof(rom));
873 memset(rdmy, 0xff, sizeof(rdmy));
875 FILEIO* fio = new FILEIO();
876 if(fio->Fopen(create_local_path(m_filename), FILEIO_READ_BINARY)) {
877 fio->Fread(rom, sizeof(rom), 1);
882 SET_BANK(0x0000, 0xffff, wdmy, rdmy);
883 SET_BANK(0x4000, 0xbfff, wdmy, rom);
886 void SLOT_FIRMWARE32K::write_data8(uint32_t addr, uint32_t data)
888 wbank[addr >> 13][addr & 0x1fff] = data;
891 uint32_t SLOT_FIRMWARE32K::read_data8(uint32_t addr)
893 return rbank[addr >> 13][addr & 0x1fff];
899 #if defined(MSXMUSIC_SLOT)
900 void SLOT_MSXMUSIC::initialize()
902 memset(rom, 0xff, sizeof(rom));
903 memset(rdmy, 0xff, sizeof(rdmy));
905 SET_BANK(0x0000, 0xffff, wdmy, rom);
906 FILEIO* fio = new FILEIO();
907 if (fio->Fopen(create_local_path(_T("FMBIOS.ROM")), FILEIO_READ_BINARY)) {
908 fio->Fread(rom, sizeof(rom), 1);
910 SET_BANK(0x0000, 0x3fff, wdmy, rdmy);
911 SET_BANK(0x4000, 0x7fff, wdmy, rom);
912 SET_BANK(0x8000, 0xffff, wdmy, rdmy);
916 void SLOT_MSXMUSIC::write_data8(uint32_t addr, uint32_t data)
918 wbank[addr >> 13][addr & 0x1fff] = data;
921 uint32_t SLOT_MSXMUSIC::read_data8(uint32_t addr)
923 return rbank[addr >> 13][addr & 0x1fff];
929 #if defined(FDD_PATCH_SLOT)
930 void MEMORY_EX::initialize()
932 for(int i = 0; i < MAX_DRIVE; i++) {
933 disk[i] = new DISK(emu);
934 disk[i]->set_device_name(_T("%s/Disk #%d"), this_device_name, i + 1);
935 disk[i]->drive_type = DRIVE_TYPE_2DD;
939 void MEMORY_EX::release()
941 for(int i = 0; i < MAX_DRIVE; i++) {
950 void MEMORY_EX::reset()
952 #if defined(FDD_PATCH_SLOT)
953 for(int i = 0; i < MAX_DRIVE; i++) {
957 ssl[0] = ssl[1] = ssl[2] = ssl[3] = 0;
958 // update_map((0 << 0) | (1 << 2) | (2 << 4) | (3 << 6));
962 void MEMORY_EX::write_data8(uint32_t addr, uint32_t data)
965 if ((addr != 0xffff) || !expanded[(psl>>6)&3]) {
966 d_map[addr >> 14]->write_data8(addr, data);
969 ssl[(psl>>6)&3] = data;
974 uint32_t MEMORY_EX::read_data8(uint32_t addr)
977 if ((addr != 0xffff) || !expanded[(psl>>6)&3]) {
978 return d_map[addr >> 14]->read_data8(addr);
981 return 0xff ^ ssl[(psl>>6)&3];
985 uint32_t MEMORY_EX::fetch_op(uint32_t addr, int* wait)
988 return read_data8(addr);
991 void MEMORY_EX::write_io8(uint32_t addr, uint32_t data)
993 #if defined(MAPPERRAM_SLOT)
994 // if(d_map[3] == d_slot[3]) {
995 d_mapper->write_io8(addr, data);
1000 void MEMORY_EX::write_signal(int id, uint32_t data, uint32_t mask)
1002 if(id == SIG_MEMORY_SEL) {
1003 if(psl != (data & mask)) {
1004 update_map(data & mask);
1009 void MEMORY_EX::update_map(uint32_t val)
1011 d_map[0] = d_slot[((val >> 0) & 3) | (expanded[(val >> 0) & 3] ? ((ssl[((val >> 0) & 3)] << 2) & 0x0c) : 0)];
1012 d_map[1] = d_slot[((val >> 2) & 3) | (expanded[(val >> 2) & 3] ? ((ssl[((val >> 2) & 3)] >> 0) & 0x0c) : 0)];
1013 d_map[2] = d_slot[((val >> 4) & 3) | (expanded[(val >> 4) & 3] ? ((ssl[((val >> 4) & 3)] >> 2) & 0x0c) : 0)];
1014 d_map[3] = d_slot[((val >> 6) & 3) | (expanded[(val >> 6) & 3] ? ((ssl[((val >> 6) & 3)] >> 4) & 0x0c) : 0)];
1018 #if defined(FDD_PATCH_SLOT)
1019 static int get_track_number(int desc, int sector)
1021 int trkside = sector / info[desc].per_track;
1022 return trkside >> (info[desc].heads - 1);
1025 static int get_side_number(int desc, int sector)
1027 int trkside = sector / info[desc].per_track;
1028 return trkside & (info[desc].heads - 1);
1031 static bool get_track(DISK *disk, int desc, int sector)
1033 return disk->get_track(get_track_number(desc, sector), get_side_number(desc, sector));
1036 static bool get_sector(DISK *disk, int desc, int sector)
1038 static int last_index = 0;
1039 if(get_track(disk, desc, sector)) {
1040 for(int i = 0; i < disk->sector_num.sd; i++) {
1041 int j = (last_index + 2 + i) % (disk->sector_num.sd);
1042 disk->get_sector(-1, -1, j);
1043 if(disk->id[2] == (sector % info[desc].per_track) + 1) {
1052 static bool get_boot_sector(DISK *disk)
1054 if(disk->get_track(0, 0)) {
1055 for(int i = 0; i < disk->sector_num.sd; i++) {
1056 disk->get_sector(0, 0, i);
1057 if(disk->id[2] == 1) {
1065 #if defined(MSX_FDD_PATCH_WITH_2HD)
1066 static bool get_sector_2(DISK *disk, int sector)
1068 if(get_boot_sector(disk)) {
1069 if (512 != disk->sector_size.sd) return false;
1070 int per_track = (int)disk->sector[0x19] * 256 + disk->sector[0x18];
1071 if (per_track <= 0) return false;
1072 int heads = (int)disk->sector[0x1b] * 256 + disk->sector[0x1a];
1073 if ((heads != 2)/* && (heads != 1)*/) return false;
1074 int trkside = sector / per_track;
1075 int track_number = trkside >> (heads - 1);
1076 int side_number = trkside & (heads - 1);
1077 if(disk->get_track(track_number, side_number)) {
1078 for(int i = 0; i < disk->sector_num.sd; i++) {
1079 disk->get_sector(-1, -1, i);
1080 if(disk->id[2] == (sector % per_track) + 1) {
1090 uint32_t MEMORY_EX::read_signal(int id)
1093 for(int i = 0; i < MAX_DRIVE; i++) {
1102 bool MEMORY_EX::bios_ret_z80(uint16_t PC, pair32_t* af, pair32_t* bc, pair32_t* de, pair32_t* hl, pair32_t* ix, pair32_t* iy, uint8_t* iff1)
1119 if(d_map[1] == d_fdpat) {
1120 // pseudo disk bios from fMSX
1122 #if defined(_MSX_VDP_MESS)
1123 d_vdp->write_signal(SIG_VDP_COMMAND_COMPLETION, 1, 1);
1125 // read/write sectors
1130 if(!(drv < MAX_DRIVE && disk[drv]->inserted)) {
1131 AF = 0x0201; // not ready
1135 if(disk[drv]->write_protected) {
1136 AF = 0x0001; // write protected
1139 for(int sector = DE; B != 0; sector++) {
1140 #if defined(MSX_FDD_PATCH_WITH_2HD)
1141 if((MEDIA_TYPE_2HD == disk[drv]->media_type) || (MEDIA_TYPE_144 == disk[drv]->media_type)) {
1142 if(!get_sector_2(disk[drv], sector)) {
1143 AF = 0x0801; // record not found
1147 else if(!get_sector(disk[drv], desc, sector)) {
1148 AF = 0x0801; // record not found
1152 if(!get_sector(disk[drv], desc, sector)) {
1153 AF = 0x0801; // record not found
1159 if(disk[drv]->addr_crc_error && !disk[drv]->ignore_crc()) {
1160 AF = 0x0801; // record not found
1163 if(addr + MSX_SECTOR_SIZE/*disk[drv]->sector_size.sd*/ > 0xffff) {
1167 d_map[1] = d_slot[read_data8(0xf342) & 0x0f];
1168 for(int i = 0; i < MSX_SECTOR_SIZE/*disk[drv]->sector_size.sd*/; i++) {
1169 disk[drv]->sector[i] = read_data8(addr++);
1175 for(int sector = DE; B != 0; sector++) {
1176 #if defined(MSX_FDD_PATCH_WITH_2HD)
1177 if((MEDIA_TYPE_2HD == disk[drv]->media_type) || (MEDIA_TYPE_144 == disk[drv]->media_type)) {
1178 if(!get_sector_2(disk[drv], sector)) {
1179 AF = 0x0801; // record not found
1183 else if(!get_sector(disk[drv], desc, sector)) {
1184 AF = 0x0801; // record not found
1188 if(!get_sector(disk[drv], desc, sector)) {
1189 AF = 0x0801; // record not found
1195 if(disk[drv]->addr_crc_error && !disk[drv]->ignore_crc()) {
1196 AF = 0x0801; // record not found
1199 if(addr + MSX_SECTOR_SIZE/*disk[drv]->sector_size.sd*/ > 0xffff) {
1203 d_map[1] = d_slot[read_data8(0xf342) & 0x0f];
1204 for(int i = 0; i < MSX_SECTOR_SIZE/*disk[drv]->sector_size.sd*/; i++) {
1205 write_data8(addr++, disk[drv]->sector[i]);
1209 if(disk[drv]->data_crc_error && !disk[drv]->ignore_crc()) {
1210 AF = 0x0401; // data crc error
1217 } else if(PC == DSKCHG) {
1218 // detect disk changed
1221 if(!(drv < MAX_DRIVE && disk[drv]->inserted)) {
1222 AF = 0x0201; // not ready
1225 B = disk[drv]->changed ? 0xff : 0x01;
1226 disk[drv]->changed = false;
1229 } else if(PC == GETDPB) {
1230 // get drive parameter block
1232 if(!(drv < MAX_DRIVE && disk[drv]->inserted)) {
1233 AF = 0x0201; // not ready
1236 if(!get_boot_sector(disk[drv])) {
1237 AF = 0x0c01; // other error
1242 if(disk[drv]->data_crc_error && !disk[drv]->ignore_crc()) {
1243 AF = 0x0401; // data crc error
1246 int bytes_per_sector = (int)disk[drv]->sector[0x0c] * 256 + disk[drv]->sector[0x0b];
1247 int sectors_per_disk = (int)disk[drv]->sector[0x14] * 256 + disk[drv]->sector[0x13];
1248 int sectors_per_fat = (int)disk[drv]->sector[0x17] * 256 + disk[drv]->sector[0x16];
1249 int reserved_sectors = (int)disk[drv]->sector[0x0f] * 256 + disk[drv]->sector[0x0e];
1250 int addr = HL + 1, num, bits;
1251 d_map[1] = d_slot[read_data8(0xf342) & 0x0f];
1252 write_data8(addr++, disk[drv]->sector[0x15]); // format id [f8h-ffh]
1253 write_data8(addr++, disk[drv]->sector[0x0b]); // sector size
1254 write_data8(addr++, disk[drv]->sector[0x0c]);
1255 num = (bytes_per_sector >> 5) - 1;
1256 for(bits = 0; num & (1 << bits); bits++);
1257 write_data8(addr++, num); // directory mask/shft
1258 write_data8(addr++, bits);
1259 num = disk[drv]->sector[0x0d] - 1;
1260 for(bits = 0; num & (1 << bits); bits++);
1261 write_data8(addr++, num); // cluster mask/shift
1262 write_data8(addr++, bits + 1);
1263 write_data8(addr++, disk[drv]->sector[0x0e]); // sector # of 1st fat
1264 write_data8(addr++, disk[drv]->sector[0x0f]);
1265 write_data8(addr++, disk[drv]->sector[0x10]); // number of fats
1266 write_data8(addr++, disk[drv]->sector[0x11]); // number of dirent-s
1267 num = reserved_sectors + disk[drv]->sector[0x10] * sectors_per_fat;
1268 num += 32 * disk[drv]->sector[0x11] / bytes_per_sector;
1269 write_data8(addr++, num & 0xff); // sector # of data
1270 write_data8(addr++, (num >> 8) & 0xff);
1271 num = (sectors_per_disk - num) / disk[drv]->sector[0x0d];
1272 write_data8(addr++, num & 0xff); // number of clusters
1273 write_data8(addr++, (num >> 8) & 0xff);
1274 write_data8(addr++, disk[drv]->sector[0x16]); // sectors per fat
1275 num = reserved_sectors + disk[drv]->sector[0x10] * sectors_per_fat;
1276 write_data8(addr++, num & 0xff); // sector # of dir.
1277 write_data8(addr, (num >> 8) & 0xff);
1281 } else if(PC == DSKFMT) {
1284 // int desc = 2 - A;
1285 int desc = A - 1; // A: 1=single-side 2=double-side
1287 if(desc != 0 && desc != 1) {
1288 AF = 0x0c01; // bad parameter
1291 if(!(drv < MAX_DRIVE && disk[drv]->inserted)) {
1292 AF = 0x0201; // not ready
1295 if(disk[drv]->write_protected) {
1296 AF = 0x0001; // write protected
1302 int max_trkside = info[desc].sectors / info[desc].per_track;
1303 for(int trkside = 0; trkside < max_trkside; trkside++) {
1304 int trk = trkside >> (info[desc].heads - 1);
1305 int side = trkside & (info[desc].heads - 1);
1306 disk[drv]->format_track(trk, side);
1307 for(int sct = 0; sct < info[desc].per_track; sct++) {
1308 disk[drv]->insert_sector(trk, side, sct + 1, 2, false, false, 0, 512);
1311 // fill boot block with data:
1313 get_sector(disk[drv], desc, sector++);
1314 memcpy(disk[drv]->sector, boot_block, 512);
1315 uint8_t *ptr = disk[drv]->sector + 3;
1316 memcpy(ptr, "fMSXdisk", 8); ptr += 10; // manufacturer's id
1317 *ptr = info[desc].per_cluster; ptr += 4; // sectors per cluster
1318 *ptr++ = info[desc].names; *ptr++ = 0x00; // number of names
1319 *ptr++ = info[desc].sectors & 0xff; // number of sectors
1320 *ptr++ = (info[desc].sectors >> 8) & 0xff;
1321 *ptr++ = desc + 0xf8; // format id [f8h-ffh]
1322 *ptr++ = info[desc].per_fat; *ptr++ = 0x00; // sectors per fat
1323 *ptr++ = info[desc].per_track; *ptr++ = 0x00; // sectors per track
1324 *ptr++ = info[desc].heads; *ptr = 0x00; // number of heads
1326 for(int j = 0; j < 2; j++) {
1327 get_sector(disk[drv], desc, sector++);
1328 memset(disk[drv]->sector, 0x00, 512);
1329 disk[drv]->sector[0] = desc + 0xf8;
1330 disk[drv]->sector[1] = disk[drv]->sector[2] = 0xff;
1331 for(int i = info[desc].per_fat; i > 1; i--) {
1332 get_sector(disk[drv], desc, sector++);
1333 memset(disk[drv]->sector, 0x00, 512);
1336 for(int i = info[desc].names / 16; i; i--) {
1337 get_sector(disk[drv], desc, sector++);
1338 memset(disk[drv]->sector, 0x00, 512);
1340 for(int i = info[desc].sectors - 2 * info[desc].per_fat - info[desc].names / 16 - 1; i; i--) {
1341 get_sector(disk[drv], desc, sector++);
1342 memset(disk[drv]->sector, 0xff, 512);
1351 void MEMORY_EX::open_disk(int drv, const _TCHAR* file_path, int bank)
1353 if(drv < MAX_DRIVE) {
1354 disk[drv]->open(file_path, bank);
1358 void MEMORY_EX::close_disk(int drv)
1360 if(drv < MAX_DRIVE && disk[drv]->inserted) {
1365 bool MEMORY_EX::is_disk_inserted(int drv)
1367 if(drv < MAX_DRIVE) {
1368 return disk[drv]->inserted;
1373 void MEMORY_EX::is_disk_protected(int drv, bool value)
1375 if(drv < MAX_DRIVE) {
1376 disk[drv]->write_protected = value;
1380 bool MEMORY_EX::is_disk_protected(int drv)
1382 if(drv < MAX_DRIVE) {
1383 return disk[drv]->write_protected;
1390 #define STATE_VERSION 1
1392 bool MEMORY_EX::process_state(FILEIO* state_fio, bool loading)
1394 if(!state_fio->StateCheckUint32(STATE_VERSION)) {
1397 if(!state_fio->StateCheckInt32(this_device_id)) {
1400 #if defined(FDD_PATCH_SLOT)
1401 for(int i = 0; i < MAX_DRIVE; i++) {
1402 if(!disk[i]->process_state(state_fio, loading)) {
1407 state_fio->StateValue(psl);
1408 state_fio->StateValue(ssl[0]);
1409 state_fio->StateValue(ssl[1]);
1410 state_fio->StateValue(ssl[2]);
1411 state_fio->StateValue(ssl[3]);