+2/25/2018
+
+[VM/DISK] improve for case 2D/2DD disk is inserted to 2DD/2D drive
+
+[FMR30/FLOPPY] support to change drive type 2DD/2HD
+[FMR30/FLOPPY] support to get media type 2D/2DD/2HD
+[FMR50/BIOS] suppoert int 93h, ah=00h/01h to set/get drive type
+[FMR50/BIOS] improve int 93h, ah=02h to get sector size and media type
+[FMR50/FLOPPY] support to change drive type 2DD/2HD
+[MZ80A] support to select floppy drive type 2D/2DD
+[MZ80B] support to select floppy drive type 2D/2DD
+[MZ80B] support to select cpu clock 4MHz/6MHz
+[MZ800] support to select floppy drive type 2D/2DD
+[MZ1500] support to select floppy drive type 2D/2DD
+[MZ2200] support to select floppy drive type 2D/2DD
+[MZ2200] support to select cpu clock 4MHz/6MHz
+[MZ2800/FLOPPY] support to change drive type 2DD/2HD
+[PC100] support to select floppy drive type 2D/2DD
+[PC100/IOCTRL] improve dipswitch value for floppy drive type 2D/2DD
+[X1TURBO] support to select floppy drive type 2D/2DD/2HD
+[X1TURBO/FLOPPY] support to change drive type 2D/2DD/2HD
+
+
2/23/2018
[VM/DISK] support two side
config.full_speed = false;
// control
-
#if defined(USE_BOOT_MODE) && defined(BOOT_MODE_DEFAULT)
config.boot_mode = BOOT_MODE_DEFAULT;
#endif
END
POPUP "Device"
BEGIN
+ POPUP "Drive"
+ BEGIN
+ MENUITEM "Floppy Drive 2D", ID_VM_DRIVE_TYPE0
+ MENUITEM "Floppy Drive 2DD", ID_VM_DRIVE_TYPE1
+ END
POPUP "Sound"
BEGIN
MENUITEM "Play FDD Noise", ID_VM_SOUND_NOISE_FDD
BEGIN
POPUP "Control"
BEGIN
- MENUITEM "Reset", ID_SPECIAL_RESET
MENUITEM "IPL Reset", ID_RESET
+ MENUITEM "Reset", ID_SPECIAL_RESET
MENUITEM SEPARATOR
MENUITEM "CPU x1", ID_CPU_POWER0
MENUITEM "CPU x2", ID_CPU_POWER1
END
POPUP "Device"
BEGIN
+ POPUP "CPU"
+ BEGIN
+ MENUITEM "4MHz", ID_VM_CPU_TYPE0
+ MENUITEM "6MHz", ID_VM_CPU_TYPE1
+ END
+ POPUP "Drive"
+ BEGIN
+ MENUITEM "Floppy Drive 2D", ID_VM_DRIVE_TYPE0
+ MENUITEM "Floppy Drive 2DD", ID_VM_DRIVE_TYPE1
+ END
POPUP "Sound"
BEGIN
MENUITEM "Play FDD Noise", ID_VM_SOUND_NOISE_FDD
BEGIN
POPUP "Control"
BEGIN
- MENUITEM "Reset", ID_SPECIAL_RESET
MENUITEM "IPL Reset", ID_RESET
+ MENUITEM "Reset", ID_SPECIAL_RESET
MENUITEM SEPARATOR
MENUITEM "CPU x1", ID_CPU_POWER0
MENUITEM "CPU x2", ID_CPU_POWER1
MENUITEM "MZ-800" ID_VM_BOOT_MODE0
MENUITEM "MZ-700" ID_VM_BOOT_MODE1
END
+ POPUP "Drive"
+ BEGIN
+ MENUITEM "Floppy Drive 2D", ID_VM_DRIVE_TYPE0
+ MENUITEM "Floppy Drive 2DD", ID_VM_DRIVE_TYPE1
+ END
POPUP "Sound"
BEGIN
MENUITEM "Play FDD Noise", ID_VM_SOUND_NOISE_FDD
END
POPUP "Device"
BEGIN
+ POPUP "Drive"
+ BEGIN
+ MENUITEM "Floppy Drive 2D", ID_VM_DRIVE_TYPE0
+ MENUITEM "Floppy Drive 2DD", ID_VM_DRIVE_TYPE1
+ END
POPUP "Option"
BEGIN
MENUITEM "PCG-8000", ID_VM_DIPSWITCH0
BEGIN
POPUP "Control"
BEGIN
- MENUITEM "Reset", ID_SPECIAL_RESET
MENUITEM "IPL Reset", ID_RESET
+ MENUITEM "Reset", ID_SPECIAL_RESET
MENUITEM SEPARATOR
MENUITEM "CPU x1", ID_CPU_POWER0
MENUITEM "CPU x2", ID_CPU_POWER1
END
POPUP "Device"
BEGIN
+ POPUP "CPU"
+ BEGIN
+ MENUITEM "4MHz", ID_VM_CPU_TYPE0
+ MENUITEM "6MHz", ID_VM_CPU_TYPE1
+ END
+ POPUP "Drive"
+ BEGIN
+ MENUITEM "Floppy Drive 2D", ID_VM_DRIVE_TYPE0
+ MENUITEM "Floppy Drive 2DD", ID_VM_DRIVE_TYPE1
+ END
POPUP "Sound"
BEGIN
MENUITEM "Play FDD Noise", ID_VM_SOUND_NOISE_FDD
END
POPUP "Device"
BEGIN
+ POPUP "Drive"
+ BEGIN
+ MENUITEM "Floppy Drive 2D", ID_VM_DRIVE_TYPE0
+ MENUITEM "Floppy Drive 2DD", ID_VM_DRIVE_TYPE1
+ END
POPUP "Sound"
BEGIN
MENUITEM "Play FDD Noise", ID_VM_SOUND_NOISE_FDD
POPUP "Drive"
BEGIN
MENUITEM "Floppy Drive 2D", ID_VM_DRIVE_TYPE0
- MENUITEM "Floppy Drive 2HD", ID_VM_DRIVE_TYPE1
+ MENUITEM "Floppy Drive 2DD", ID_VM_DRIVE_TYPE1
+ MENUITEM "Floppy Drive 2HD", ID_VM_DRIVE_TYPE2
END
POPUP "Keyboard"
BEGIN
POPUP "Drive"
BEGIN
MENUITEM "Floppy Drive 2D", ID_VM_DRIVE_TYPE0
- MENUITEM "Floppy Drive 2HD", ID_VM_DRIVE_TYPE1
+ MENUITEM "Floppy Drive 2DD", ID_VM_DRIVE_TYPE1
+ MENUITEM "Floppy Drive 2HD", ID_VM_DRIVE_TYPE2
END
POPUP "Keyboard"
BEGIN
bool DISK::get_track(int trk, int side)
{
+ if(media_type == MEDIA_TYPE_2D && drive_type == DRIVE_TYPE_2DD) {
+ trk >>= 1;
+ } else if(media_type == MEDIA_TYPE_2DD && drive_type == DRIVE_TYPE_2D) {
+ trk <<= 1;
+ }
+ return get_track_tmp(trk, side);
+}
+
+bool DISK::get_track_tmp(int trk, int side)
+{
sector_size.sd = sector_num.sd = 0;
invalid_format = false;
// no_skew = true;
bool DISK::make_track(int trk, int side)
{
+ if(media_type == MEDIA_TYPE_2D && drive_type == DRIVE_TYPE_2DD) {
+ trk >>= 1;
+ } else if(media_type == MEDIA_TYPE_2DD && drive_type == DRIVE_TYPE_2D) {
+ trk <<= 1;
+ }
+ return make_track_tmp(trk, side);
+}
+
+bool DISK::make_track_tmp(int trk, int side)
+{
int track_size = get_track_size();
- if(!get_track(trk, side)) {
+ if(!get_track_tmp(trk, side)) {
// create a dummy track
for(int i = 0; i < track_size; i++) {
track[i] = rand();
bool DISK::get_sector(int trk, int side, int index)
{
+ if(media_type == MEDIA_TYPE_2D && drive_type == DRIVE_TYPE_2DD) {
+ trk >>= 1;
+ } else if(media_type == MEDIA_TYPE_2DD && drive_type == DRIVE_TYPE_2D) {
+ trk <<= 1;
+ }
+ return get_sector_tmp(trk, side, index);
+}
+
+bool DISK::get_sector_tmp(int trk, int side, int index)
+{
sector_size.sd = sector_num.sd = 0;
sector = NULL;
bool DISK::format_track(int trk, int side)
{
+ if(media_type == MEDIA_TYPE_2D && drive_type == DRIVE_TYPE_2DD) {
+ trk >>= 1;
+ } else if(media_type == MEDIA_TYPE_2DD && drive_type == DRIVE_TYPE_2D) {
+ trk <<= 1;
+ }
+ return format_track_tmp(trk, side);
+}
+
+bool DISK::format_track_tmp(int trk, int side)
+{
// disk not inserted or invalid media type
if(!(inserted && check_media_type())) {
return false;
memcpy(buffer, tmp_buffer, min(sizeof(buffer), file_size.d));
}
+int DISK::get_max_tracks()
+{
+ if(drive_type != DRIVE_TYPE_UNK) {
+ return (drive_type != DRIVE_TYPE_2D) ? 84 : 42;
+ } else if(inserted) {
+ return (drive_type != MEDIA_TYPE_2D) ? 84 : 42;
+ } else {
+ return 84; // 2DD or 2HD
+ }
+}
+
int DISK::get_rpm()
{
if(drive_rpm != 0) {
{
switch(drive_type) {
case DRIVE_TYPE_2D:
- if(type_fm77av_2dd) {
return (media_type == MEDIA_TYPE_2D || media_type == MEDIA_TYPE_2DD);
- } else {
- return (media_type == MEDIA_TYPE_2D);
- }
case DRIVE_TYPE_2DD:
return (media_type == MEDIA_TYPE_2D || media_type == MEDIA_TYPE_2DD);
case DRIVE_TYPE_2HD:
bool solid_to_d88(FILEIO *fio, int type, int ncyl, int nside, int nsec, int size, bool mfm);
void setup_fd_formats(void);
+ // internal routines for track
+ bool get_track_tmp(int trk, int side);
+ bool make_track_tmp(int trk, int side);
+ bool get_sector_tmp(int trk, int side, int index);
+ bool format_track_tmp(int trk, int side);
+
public:
#ifndef _ANY2D88
DISK(EMU* parent_emu) : emu(parent_emu)
void insert_sector(uint8_t c, uint8_t h, uint8_t r, uint8_t n, bool deleted, bool data_crc_error, uint8_t fill_data, int length);
void sync_buffer();
+ int get_max_tracks();
int get_rpm();
int get_track_size();
double get_usec_per_track();
#include "../device.h"
#include "../event.h"
+#include "../disk.h"
#include "../i8251.h"
#include "../i8253.h"
#include "../i8255.h"
delete device;
device = next_device;
}
+ for(int i = 0; i < MAX_DRIVE; i++) {
+ fdc->set_drive_type(i, DRIVE_TYPE_2D);
+ }
}
DEVICE* VM::get_device(int id)
*/
#include "floppy.h"
+#include "../disk.h"
#include "../i8259.h"
#include "../mb8877.h"
changed[0] = changed[1] = changed[2] = changed[3] = false;
}
+void FLOPPY::reset()
+{
+ for(int i = 0; i < MAX_DRIVE; i++) {
+ d_fdc->set_drive_type(i, DRIVE_TYPE_2HD);
+ }
+}
+
void FLOPPY::write_io8(uint32_t addr, uint32_t data)
{
switch(addr & 0xffff) {
fdst = changed[drvsel] ? 1 : 0;
changed[drvsel] = false;
}
+ if((drvsel & 2) ? (data & 0x80) : (data & 0x40)) {
+ d_fdc->set_drive_type(drvsel, DRIVE_TYPE_2DD);
+ } else {
+ d_fdc->set_drive_type(drvsel, DRIVE_TYPE_2HD);
+ }
d_fdc->write_signal(SIG_MB8877_MOTOR, 1, 1);
break;
case 0x36:
case 0x34:
return fdcr;
case 0x35:
- return fdsl;
+ {
+ uint32_t value = fdsl & 0x3f;
+ if(d_fdc->media_type(drvsel) == MEDIA_TYPE_2D || d_fdc->media_type(drvsel) == MEDIA_TYPE_2DD) {
+ drvsel |= (drvsel & 2) ? 0x80 : 0x40;
+ }
+ return value;
+ }
case 0x36:
return fdst;
}
#define SIG_FLOPPY_IRQ 0
+class MB8877;
+
class FLOPPY : public DEVICE
{
private:
- DEVICE *d_fdc, *d_pic;
+ MB8877 *d_fdc;
+ DEVICE *d_pic;
uint8_t fdcr, fdsl, fdst;
int drvsel;
// common functions
void initialize();
+ void reset();
void write_io8(uint32_t addr, uint32_t data);
uint32_t read_io8(uint32_t addr);
void write_signal(int id, uint32_t data, uint32_t mask);
bool load_state(FILEIO* state_fio);
// unique functions
- void set_context_fdc(DEVICE* device)
+ void set_context_fdc(MB8877* device)
{
d_fdc = device;
}
{
for(int i = 0; i < MAX_DRIVE; i++) {
access_fdd[i] = false;
+ drive_mode1[i] = 0x03; // MFM, 2HD, 1024B
+ drive_mode2[i] = 0x208; // 2 Heads, 8 sectors
}
for(int i = 0; i < MAX_SCSI; i++) {
access_scsi[i] = false;
// 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);
//printf(_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);
//#endif
- if(AH == 2) {
+ if(AH == 0) {
+ // set drive mode
+ if(!(drv < MAX_DRIVE)) {
+ AH = 2;
+ *CarryFlag = 1;
+ return true;
+ }
+ AH = 0;
+ drive_mode1[drv] = DL;
+ drive_mode2[drv] = BX;
+ switch(DL & 0x30) {
+ case 0x00: disk[drv]->drive_type = DRIVE_TYPE_2HD; break;
+ case 0x10: disk[drv]->drive_type = DRIVE_TYPE_2DD; break;
+ case 0x20: disk[drv]->drive_type = DRIVE_TYPE_2D ; break;
+ }
+ *CarryFlag = 0;
+ return true;
+ } else if(AH == 1) {
+ // get drive mode
+ if(!(drv < MAX_DRIVE)) {
+ AH = 2;
+ *CarryFlag = 1;
+ return true;
+ }
+ AH = 0;
+ DL = drive_mode1[drv];
+ BX = drive_mode2[drv];
+ *CarryFlag = 0;
+ return true;
+ } else if(AH == 2) {
// drive status
if((AL & 0xf0) == 0x20) {
// floppy
return true;
}
AH = 0;
- DL = 4;
+ if(disk[drv]->get_track(0, 0) && disk[drv]->get_sector(0, 0, 0)) {
+ switch(disk[drv]->sector_size.sd) {
+ case 128: AH = 0; break;
+ case 256: AH = 1; break;
+ case 512: AH = 2; break;
+ default : AH = 3; break; // 1024
+ }
+ }
+ DL = 0;
if(disk[drv]->write_protected) {
DL |= 2;
}
+ if(disk[drv]->two_side) {
+ DL |= 4;
+ }
+// if(disk[drv]->drive_type == DRIVE_TYPE_2D || disk[drv]->drive_type == DRIVE_TYPE_2DD) {
+ if(disk[drv]->media_type == MEDIA_TYPE_2D || disk[drv]->media_type == MEDIA_TYPE_2DD) {
+ DL |= 0x10;
+ }
CX = 0;
*CarryFlag = 0;
return true;
int sct = DL;
while(BX > 0) {
// search sector
- disk[drv]->get_track(trk, hed);
+ if(!disk[drv]->get_track(trk, hed)) {
+ AH = 0x80;
+ CX = ERR_FDD_NOTFOUND;
+ *CarryFlag = 1;
+ return true;
+ }
access_fdd[drv] = true;
secnum = sct;
if(!disk[drv]->get_sector(trk, hed, sct - 1)) {
int sct = DL;
while(BX > 0) {
// search sector
- disk[drv]->get_track(trk, hed);
+ if(!disk[drv]->get_track(trk, hed)) {
+ AH = 0x80;
+ CX = ERR_FDD_NOTFOUND;
+ *CarryFlag = 1;
+ return true;
+ }
access_fdd[drv] = true;
secnum = sct;
if(!disk[drv]->get_sector(trk, hed, sct - 1)) {
int sct = DL;
while(BX > 0) {
// search sector
- disk[drv]->get_track(trk, hed);
+ if(!disk[drv]->get_track(trk, hed)) {
+ AH = 0x80;
+ CX = ERR_FDD_NOTFOUND;
+ *CarryFlag = 1;
+ return true;
+ }
access_fdd[drv] = true;
secnum = sct;
if(!disk[drv]->get_sector(trk, hed, sct - 1)) {
int trk = CX;
int hed = DH & 1;
// search sector
- disk[drv]->get_track(trk, hed);
+ if(!disk[drv]->get_track(trk, hed)) {
+ AH = 0x80;
+ CX = ERR_FDD_NOTFOUND;
+ *CarryFlag = 1;
+ return true;
+ }
access_fdd[drv] = true;
if(++secnum > disk[drv]->sector_num.sd) {
secnum = 1;
return true;
}
// load ipl
- disk[0]->get_track(0, 0);
+ if(!disk[0]->get_track(0, 0)) {
+ *CarryFlag = 1;
+ return true;
+ }
access_fdd[0] = true;
if(!disk[0]->get_sector(0, 0, 0)) {
*CarryFlag = 1;
return stat;
}
-#define STATE_VERSION 3
+#define STATE_VERSION 4
void BIOS::save_state(FILEIO* state_fio)
{
}
state_fio->FputInt32(secnum);
state_fio->FputInt32(timeout);
+ state_fio->Fwrite(drive_mode1, sizeof(drive_mode1), 1);
+ state_fio->Fwrite(drive_mode2, sizeof(drive_mode2), 1);
+ state_fio->Fwrite(scsi_blocks, sizeof(scsi_blocks), 1);
}
bool BIOS::load_state(FILEIO* state_fio)
}
secnum = state_fio->FgetInt32();
timeout = state_fio->FgetInt32();
+ state_fio->Fread(drive_mode1, sizeof(drive_mode1), 1);
+ state_fio->Fread(drive_mode2, sizeof(drive_mode2), 1);
+ state_fio->Fread(scsi_blocks, sizeof(scsi_blocks), 1);
return true;
}
// disk bios
bool access_fdd[MAX_DRIVE], access_scsi[MAX_SCSI];
+ uint8_t drive_mode1[MAX_DRIVE];
+ uint16_t drive_mode2[MAX_DRIVE];
int scsi_blocks[MAX_SCSI];
public:
*/
#include "floppy.h"
+#include "../disk.h"
#include "../i8259.h"
#include "../mb8877.h"
changed[0] = changed[1] = changed[2] = changed[3] = false;
}
+void FLOPPY::reset()
+{
+ for(int i = 0; i < MAX_DRIVE; i++) {
+ d_fdc->set_drive_type(i, DRIVE_TYPE_2HD);
+ }
+}
+
void FLOPPY::write_io8(uint32_t addr, uint32_t data)
{
int nextdrv = drvsel;
// drive control register
irqmsk = ((data & 1) != 0);
update_intr();
+ // note: bit5 is CLKSEL, but 0 is set while seeking
+/*
+ for(int i = 0; i < MAX_DRIVE; i++) {
+ if(data & 0x20) {
+ d_fdc->set_drive_type(i, DRIVE_TYPE_2DD);
+ } else {
+ d_fdc->set_drive_type(i, DRIVE_TYPE_2HD);
+ }
+ }
+*/
d_fdc->write_signal(SIG_MB8877_MOTOR, data, 0x10);
d_fdc->write_signal(SIG_MB8877_SIDEREG, data, 4);
break;
case 0x20c:
// drive select register
- if(data & 1) {
- nextdrv = 0;
- } else if(data & 2) {
- nextdrv = 1;
- } else if(data & 4) {
- nextdrv = 2;
- } else if(data & 8) {
- nextdrv = 3;
- }
- if(drvsel != nextdrv) {
- d_fdc->write_signal(SIG_MB8877_DRIVEREG, drvsel = nextdrv, 3);
+ if(data & 0x0f) {
+ if(data & 1) {
+ nextdrv = 0;
+ } else if(data & 2) {
+ nextdrv = 1;
+ } else if(data & 4) {
+ nextdrv = 2;
+ } else if(data & 8) {
+ nextdrv = 3;
+ }
+ if(drvsel != nextdrv) {
+ d_fdc->write_signal(SIG_MB8877_DRIVEREG, drvsel = nextdrv, 3);
+ }
+ for(int i = 0; i < MAX_DRIVE; i++) {
+ if((data & 0xc0) == 0x00) {
+ d_fdc->set_drive_type(i, DRIVE_TYPE_2DD); // 300rpm
+ } else if((data & 0xc0) == 0x40) {
+ d_fdc->set_drive_type(i, DRIVE_TYPE_2HD); // 360rpm
+ }
+ }
}
drvreg = data;
break;
// common functions
void initialize();
+ void reset();
void write_io8(uint32_t addr, uint32_t data);
uint32_t read_io8(uint32_t addr);
void write_signal(int id, uint32_t data, uint32_t mask);
#include "../event.h"
#include "../beep.h"
+#include "../disk.h"
#include "../hd146818p.h"
#include "../i8255.h"
//#include "../mc6800.h"
for(DEVICE* device = first_device; device; device = device->next_device) {
device->initialize();
}
+ for(int i = 0; i < MAX_DRIVE; i++) {
+ fdc_tf20->set_drive_type(i, DRIVE_TYPE_2D);
+ }
}
VM::~VM()
//seektrk = (uint8_t)(fdc[drvreg].track + datareg - trkreg); // Seek target is differ when drive's track != trkreg.Thanks to Haserin and Ryu Takegami.
seektrk = (int)((int8_t)datareg);
//#if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || defined(_FM77AV20) || defined(_FM77AV20EX)
- if(type_fm77av_2dd) {
- if(disk[drvreg]->drive_type != DRIVE_TYPE_2D) {
- seektrk = (seektrk > 83) ? 83 : (seektrk < 0) ? 0 : seektrk;
- } else {
- seektrk = (seektrk > 41) ? 41 : (seektrk < 0) ? 0 : seektrk;
- }
- } else if(disk[drvreg]->media_type != MEDIA_TYPE_2D){
- seektrk = (seektrk > 83) ? 83 : (seektrk < 0) ? 0 : seektrk;
- } else {
- seektrk = (seektrk > 41) ? 41 : (seektrk < 0) ? 0 : seektrk;
- }
+ if(seektrk >= disk[drvreg]->get_max_tracks()) {
+ seektrk = disk[drvreg]->get_max_tracks() - 1;
+ } else if(seektrk < 0) {
+ seektrk = 0;
+ }
seekvct = !(seektrk > fdc[drvreg].track);
// Update track register by data register.Thanks to Ryu Takegami. 20180224 K.O
}
seektrk = fdc[drvreg].track + 1;
- if(type_fm77av_2dd) {
- if(disk[drvreg]->drive_type != DRIVE_TYPE_2D) {
- seektrk = (seektrk > 83) ? 83 : (seektrk < 0) ? 0 : seektrk;
- } else {
- seektrk = (seektrk > 41) ? 41 : (seektrk < 0) ? 0 : seektrk;
- }
- } else if(disk[drvreg]->media_type != MEDIA_TYPE_2D){
- seektrk = (seektrk > 83) ? 83 : (seektrk < 0) ? 0 : seektrk;
- } else {
- seektrk = (seektrk > 41) ? 41 : (seektrk < 0) ? 0 : seektrk;
- }
+ if(seektrk >= disk[drvreg]->get_max_tracks()) {
+ seektrk = disk[drvreg]->get_max_tracks() - 1;
+ } else if(seektrk < 0) {
+ seektrk = 0;
+ }
seekvct = false;
set_irq(false);
set_drq(false);
}
seektrk = fdc[drvreg].track - 1;
- if(type_fm77av_2dd) {
- if(disk[drvreg]->drive_type != DRIVE_TYPE_2D) {
- seektrk = (seektrk > 83) ? 83 : (seektrk < 0) ? 0 : seektrk;
- } else {
- seektrk = (seektrk > 41) ? 41 : (seektrk < 0) ? 0 : seektrk;
- }
- } else if(disk[drvreg]->media_type != MEDIA_TYPE_2D){
- seektrk = (seektrk > 83) ? 83 : (seektrk < 0) ? 0 : seektrk;
- } else {
- seektrk = (seektrk > 41) ? 41 : (seektrk < 0) ? 0 : seektrk;
- }
+ if(seektrk >= disk[drvreg]->get_max_tracks()) {
+ seektrk = disk[drvreg]->get_max_tracks() - 1;
+ } else if(seektrk < 0) {
+ seektrk = 0;
+ }
seekvct = true;
register_seek_event();
}
{
// get track
int track = fdc[drvreg].track;
+#if 0 // ToDo: Test and REMOVE.
//#if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || defined(_FM77AV20) || defined(_FM77AV20EX)
if(type_fm77av_2dd) {
if(disk[drvreg]->media_type == MEDIA_TYPE_2D) {
}
}
//#endif
+#endif
+
if(!disk[drvreg]->get_track(track, sidereg)){
return FDC_ST_SEEKERR;
}
// get track
int track = fdc[drvreg].track;
+#if 0 // ToDo: Test and REMOVE.
//#if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || defined(_FM77AV20) || defined(_FM77AV20EX)
if(type_fm77av_2dd) {
if(disk[drvreg]->media_type == MEDIA_TYPE_2D) {
}
}
//#endif
+#endif
+
if(!disk[drvreg]->get_track(track, sidereg)) {
return FDC_ST_RECNFND;
}
{
// get track
int track = fdc[drvreg].track;
+#if 0 // ToDo: Test and REMOVE.
//#if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || defined(_FM77AV20) || defined(_FM77AV20EX)
if(type_fm77av_2dd) {
if(disk[drvreg]->media_type == MEDIA_TYPE_2D) {
}
}
//#endif
+#endif
+
if(!disk[drvreg]->get_track(track, sidereg)) {
return FDC_ST_RECNFND;
}
return false;
}
+uint8_t MB8877::media_type(int drv)
+{
+ if(drv < MAX_DRIVE) {
+ if(disk[drv]->inserted) {
+ return disk[drv]->media_type;
+ }
+ }
+ return MEDIA_TYPE_UNK;
+}
+
void MB8877::set_drive_type(int drv, uint8_t type)
{
if(drv < _max_drive) {
bool is_disk_inserted(int drv);
void is_disk_protected(int drv, bool value);
bool is_disk_protected(int drv);
+ uint8_t media_type(int drv);
void set_drive_type(int drv, uint8_t type);
uint8_t get_drive_type(int drv);
void set_drive_rpm(int drv, int rpm);
for(int i = 0; i < MAX_DRIVE; i++) {
disk[i] = new DISK(emu);
disk[i]->set_device_name(_T("%s/Disk #%d"), this_device_name, i + 1);
+ disk[i]->drive_type = DRIVE_TYPE_2DD;
}
}
for(int i = 0; i < MAX_DRIVE; i++) {
disk[i] = new DISK(emu);
disk[i]->set_device_name(_T("%s/Disk #%d"), this_device_name, i + 1);
+ disk[i]->drive_type = DRIVE_TYPE_2DD;
}
}
#endif
// set contexts
- event->set_context_cpu(cpu);
+ event->set_context_cpu(cpu, config.cpu_type ? CPU_CLOCKS_HIGH : CPU_CLOCKS);
#ifdef SUPPORT_16BIT_BOARD
event->set_context_cpu(cpu_16, 5000000);
#endif
for(DEVICE* device = first_device; device; device = device->next_device) {
device->initialize();
}
- for(int i = 0; i < MAX_DRIVE; i++) {
- fdc->set_drive_type(i, DRIVE_TYPE_2DD);
-// fdc->set_drive_type(i, DRIVE_TYPE_2D);
- }
}
VM::~VM()
for(DEVICE* device = first_device; device; device = device->next_device) {
device->reset();
}
+ for(int i = 0; i < MAX_DRIVE; i++) {
+ if(config.drive_type) {
+ fdc->set_drive_type(i, DRIVE_TYPE_2DD);
+ } else {
+ fdc->set_drive_type(i, DRIVE_TYPE_2D);
+ }
+ }
}
void VM::special_reset()
#define FRAMES_PER_SEC 60
#define LINES_PER_FRAME 262
#define CPU_CLOCKS 4000000
+#define CPU_CLOCKS_HIGH 6000000
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 400
#define WINDOW_HEIGHT_ASPECT 480
// device informations for win32
#define USE_SPECIAL_RESET
+#define USE_CPU_TYPE 2
+#define USE_DRIVE_TYPE 2
#define USE_FD1
#define USE_FD2
#define USE_FD3
#include "floppy.h"
#include "../mb8877.h"
+#include "../disk.h"
+
+void FLOPPY::reset()
+{
+ for(int i = 0; i < 4; i++) {
+ d_fdc->set_drive_type(i, DRIVE_TYPE_2HD);
+ }
+}
void FLOPPY::write_io8(uint32_t addr, uint32_t data)
{
// side reg
d_fdc->write_signal(SIG_MB8877_SIDEREG, data, 1);
break;
+ case 0xde:
+ break;
+ case 0xdf:
+ for(int i = 0; i < 4; i++) {
+ if(data & 1) {
+ d_fdc->set_drive_type(i, DRIVE_TYPE_2HD);
+ } else {
+ d_fdc->set_drive_type(i, DRIVE_TYPE_2DD);
+ }
+ }
+ break;
}
}
#include "../../emu.h"
#include "../device.h"
+class MB8877;
+
class FLOPPY : public DEVICE
{
private:
- DEVICE* d_fdc;
+ MB8877* d_fdc;
public:
FLOPPY(VM* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu)
}
~FLOPPY() {}
- // common function
+ // common functions
+ void reset();
void write_io8(uint32_t addr, uint32_t data);
// unique function
- void set_context_fdc(DEVICE* device)
+ void set_context_fdc(MB8877* device)
{
d_fdc = device;
}
device->initialize();
}
for(int i = 0; i < 4; i++) {
- fdc->set_drive_type(i, DRIVE_TYPE_2DD);
+ fdc->set_drive_type(i, DRIVE_TYPE_2D);
}
// GDC clock (mz3500sm p.33,34)
if(config.monitor_type == 0 || config.monitor_type == 1) {
for(DEVICE* device = first_device; device; device = device->next_device) {
device->initialize();
}
- //pcm->set_realtime_render(true);
-#if defined(_MZ800) || defined(_MZ1500)
- for(int i = 0; i < MAX_DRIVE; i++) {
- fdc->set_drive_type(i, DRIVE_TYPE_2DD);
- }
-#endif
}
VM::~VM()
for(DEVICE* device = first_device; device; device = device->next_device) {
device->reset();
}
+#if defined(_MZ800) || defined(_MZ1500)
+ for(int i = 0; i < MAX_DRIVE; i++) {
+ if(config.drive_type) {
+ fdc->set_drive_type(i, DRIVE_TYPE_2DD);
+ } else {
+ fdc->set_drive_type(i, DRIVE_TYPE_2D);
+ }
+ }
+#endif
and_int->write_signal(SIG_AND_BIT_0, 0, 1); // CLOCK = L
and_int->write_signal(SIG_AND_BIT_1, 1, 1); // INTMASK = H
#if defined(_MZ800) || defined(_MZ1500)
#define USE_TAPE1
#define USE_TAPE_BUTTON
#if defined(_MZ800) || defined(_MZ1500)
+#define USE_DRIVE_TYPE 2
#define USE_QD1
#define USE_FD1
#define USE_FD2
for(DEVICE* device = first_device; device; device = device->next_device) {
device->initialize();
}
-#if defined(SUPPORT_MZ80AIF)
- for(int i = 0; i < MAX_DRIVE; i++) {
- fdc->set_drive_type(i, DRIVE_TYPE_2DD);
- }
-#elif defined(SUPPORT_MZ80FIO)
- for(int i = 0; i < MAX_DRIVE; i++) {
- fdc->set_drive_type(i, DRIVE_TYPE_2D);
-// fdc->set_drive_mfm(i, false);
- }
-#endif
-
}
VM::~VM()
for(DEVICE* device = first_device; device; device = device->next_device) {
device->reset();
}
+#if defined(SUPPORT_MZ80AIF)
+ for(int i = 0; i < MAX_DRIVE; i++) {
+ if(config.drive_type) {
+ fdc->set_drive_type(i, DRIVE_TYPE_2DD);
+ } else {
+ fdc->set_drive_type(i, DRIVE_TYPE_2D);
+ }
+ }
+#elif defined(SUPPORT_MZ80FIO)
+ for(int i = 0; i < MAX_DRIVE; i++) {
+ fdc->set_drive_type(i, DRIVE_TYPE_2D);
+// fdc->set_drive_mfm(i, false);
+ }
+#endif
#if defined(_MZ1200) || defined(_MZ80A)
and_int->write_signal(SIG_AND_BIT_0, 0, 1); // CLOCK = L
and_int->write_signal(SIG_AND_BIT_1, 1, 1); // INTMASK = H
#define USE_PRINTER_TYPE 4
#define USE_DEBUGGER
#define USE_STATE
+#if defined(SUPPORT_MZ80AIF)
+#define USE_DRIVE_TYPE 2
+#endif
#if defined(SUPPORT_MZ80AIF) || defined(SUPPORT_MZ80FIO)
#define USE_FD1
#define USE_FD2
update_key();
return key_val;
case 0x22:
- if(config.monitor_type) {
- return key_mouse | 0x0d; // virt monitor
- } else {
- return key_mouse | 0x2d; // horiz monitor
+ // bit1: 0 = Color Mode, 1 = Monochrome Mode
+ // bit2: 1 = Double FDD, 0 = Single FDD
+ // bit3: 1 = 2D, 0 = 2DD
+ // bit4: 1 = KD, 0 = MD
+ // bit5: 1 = Horizontal Monitor, 0 = Virtical Monitor
+ {
+ uint32_t value = key_mouse | 0x05;
+ if(!config.drive_type) {
+ value |= 0x08; // 2D
+ }
+ if(!config.monitor_type) {
+ value |= 0x20; // Horizontal Monitor
+ }
+ return value;
}
}
return 0xff;
for(DEVICE* device = first_device; device; device = device->next_device) {
device->initialize();
}
- for(int i = 0; i < 4; i++) {
- fdc->set_drive_type(i, DRIVE_TYPE_2D);
- }
}
VM::~VM()
for(DEVICE* device = first_device; device; device = device->next_device) {
device->reset();
}
+ for(int i = 0; i < 4; i++) {
+ if(config.drive_type) {
+ fdc->set_drive_type(i, DRIVE_TYPE_2DD);
+ } else {
+ fdc->set_drive_type(i, DRIVE_TYPE_2D);
+ }
+ }
}
void VM::run()
#define IO_ADDR_MAX 0x10000
// device informations for win32
+#define USE_DRIVE_TYPE 2
#define USE_FD1
#define USE_FD2
#define NOTIFY_KEY_DOWN
for(int i = 0; i < 2; i++) {
disk[i] = new DISK(emu);
disk[i]->set_device_name(_T("%s/Disk #%d"), this_device_name, i + 1);
+ disk[i]->drive_type = DRIVE_TYPE_2D;
}
if(d_noise_seek != NULL) {
d_noise_seek->set_device_name(_T("Noise Player (FDD Seek)"));
for(int i = 0; i < 2; i++) {
disk[i] = new DISK(emu);
disk[i]->set_device_name(_T("%s/Disk #%d"), this_device_name, i + 1);
+ disk[i]->drive_type = DRIVE_TYPE_2D;
}
if(d_noise_seek != NULL) {
d_noise_seek->set_device_name(_T("Noise Player (FDD Seek)"));
*/
#include "floppy.h"
+#include "../disk.h"
#include "../upd765a.h"
void FLOPPY::reset()
{
+/*
+ for(int i = 0; i < 4; i++) {
+ d_fdc->set_drive_type(i, DRIVE_TYPE_2HD);
+ }
+*/
ctrlreg = 0x80;
modereg = 0x03;
}
ctrlreg = data;
break;
case 0xbe:
+/*
+ if(!(modereg & 2) && (data & 2)) {
+ d_fdc->set_drive_type(0, DRIVE_TYPE_2HD);
+ d_fdc->set_drive_type(1, DRIVE_TYPE_2HD);
+ } else if((modereg & 2) && !(data & 2)) {
+ d_fdc->set_drive_type(0, DRIVE_TYPE_2DD);
+ d_fdc->set_drive_type(1, DRIVE_TYPE_2DD);
+ }
+*/
modereg = data;
break;
}
for(int i = 0; i < __MAX_DRIVE; i++) {
disk[i] = new DISK(emu);
disk[i]->set_device_name(_T("%s/Disk #%d"), this_device_name, i + 1);
+ disk[i]->drive_type = DRIVE_TYPE_2D;
}
}
void FLOPPY::reset()
{
register_id = -1;
+#ifdef _X1TURBO_FEATURE
+ select_2dd = false;
+#endif
}
void FLOPPY::write_io8(uint32_t addr, uint32_t data)
switch(addr) {
case 0xffc: // FM
// d_fdc->set_drive_mfm(prev & 3, false);
+ select_2dd = false;
return 0xff;
case 0xffd: // MFM
// d_fdc->set_drive_mfm(prev & 3, true);
+ select_2dd = false;
return 0xff;
case 0xffe: // 2HD
d_fdc->set_drive_type(prev & 3, DRIVE_TYPE_2HD);
// d_fdc->set_drive_rpm(prev & 3, 360);
return 0xff;
case 0xfff: // 2D/2DD
- d_fdc->set_drive_type(prev & 3, DRIVE_TYPE_2DD);
+ if(!select_2dd) {
+ d_fdc->set_drive_type(prev & 3, DRIVE_TYPE_2D);
+ } else {
+ d_fdc->set_drive_type(prev & 3, DRIVE_TYPE_2DD);
+ }
+ select_2dd = !select_2dd;
// d_fdc->set_drive_rpm(prev & 3, 300);
return 0xff;
}
register_id = -1;
}
-#define STATE_VERSION 1
+#define STATE_VERSION 2
void FLOPPY::save_state(FILEIO* state_fio)
{
state_fio->FputInt32(this_device_id);
state_fio->FputInt32(prev);
+#ifdef _X1TURBO_FEATURE
+ state_fio->FputBool(select_2dd);
+#endif
state_fio->FputBool(motor_on);
state_fio->FputInt32(register_id);
}
return false;
}
prev = state_fio->FgetInt32();
+#ifdef _X1TURBO_FEATURE
+ select_2dd = state_fio->FgetBool();
+#endif
motor_on = state_fio->FgetBool();
register_id = state_fio->FgetInt32();
return true;
private:
MB8877 *d_fdc;
int prev;
+#ifdef _X1TURBO_FEATURE
+ bool select_2dd;
+#endif
bool motor_on;
int register_id;
}
}
for(int i = 0; i < MAX_DRIVE; i++) {
-#ifdef _X1TURBO_FEATURE
- fdc->set_drive_type(i, DRIVE_TYPE_2DD);
-#else
+//#ifdef _X1TURBO_FEATURE
+// fdc->set_drive_type(i, DRIVE_TYPE_2DD);
+//#else
fdc->set_drive_type(i, DRIVE_TYPE_2D);
-#endif
+//#endif
// fdc->set_drive_rpm(i, 300);
// fdc->set_drive_mfm(i, true);
}
void VM::update_dipswitch()
{
// bit0 0=High 1=Standard
- // bit2 0=5"2D 1=5"2HD
- io->set_iovalue_single_r(0x1ff0, (config.monitor_type & 1) | ((config.drive_type & 1) << 2));
+ // bit1-3 000=5"2D 001=5"2DD 010=5"2HD
+ io->set_iovalue_single_r(0x1ff0, (config.monitor_type & 1) | ((config.drive_type & 7) << 1));
}
#endif
#define USE_KEYBOARD_TYPE 2
// Keyboard mode B
#define KEYBOARD_TYPE_DEFAULT 1
-#define USE_DRIVE_TYPE 2
+#define USE_DRIVE_TYPE 3
#endif
#define USE_FD1
#define USE_FD2