Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
cf303a1
コア移植の下準備: UI互換ヘルパー追加とi825x最小互換対応
bubio Feb 12, 2026
a008114
コア移植の互換層を拡張: device/disk/upd765aの受け口を追加
bubio Feb 13, 2026
870de98
FDC/DISK互換APIを追加し次段移植の受け口を整備
bubio Feb 13, 2026
3654fce
upd765aのセクタ探索条件を整理しFM/MFM判定を共通化
bubio Feb 13, 2026
ef4b101
upd765aのセクタ選択とエラー判定をcommon側に近づける
bubio Feb 13, 2026
08e3dc8
upd765aのread_id/write_idの結果整合を調整
bubio Feb 13, 2026
e8a37bd
devをマージしてPR競合を解消
bubio Feb 13, 2026
b00e7ae
noise/vm_templateを現行xm8向けに整備しビルドへ追加
bubio Feb 13, 2026
6d1dd9b
pc8801/upd765aにFDDノイズ配線を追加しseek時に再生
bubio Feb 13, 2026
9874ac4
Windowsプロジェクトにnoise.cpp/noise.hを追加してリンクエラーを解消
bubio Feb 13, 2026
40904db
upd765aにヘッドロード/アンロード制御を移植しFDDヘッドノイズを再生
bubio Feb 13, 2026
9d3fec5
EVENTのサウンド登録上限超過を修正しゲーム音消失を解消
bubio Feb 13, 2026
084cf46
diskのtrack_mfm管理を導入しwrite_idのFM/MFM反映を修正
bubio Feb 13, 2026
994b016
upd765aの診断読込判定とサイズ計算をcommon互換へ調整
bubio Feb 13, 2026
8bb6308
upd765a: INDEX信号幅と現在位置計算を最新実装寄りに調整
bubio Feb 13, 2026
c843f0d
upd1990a: STBラッチ判定をCLK非依存に修正
bubio Feb 13, 2026
d82dffd
upd1990a: RTCデバイス名を明示設定
bubio Feb 13, 2026
684a5ab
i8251: リセット時のTXEN初期値を最新挙動に合わせる
bubio Feb 13, 2026
f863149
i8251: デバイス名を明示設定
bubio Feb 13, 2026
7a7d1ae
i8253: デバイス名を明示設定
bubio Feb 13, 2026
93312be
i8255: デバイス名を明示設定
bubio Feb 13, 2026
2102c67
dev取り込み時の競合を解消(disk/upd765a)
bubio Feb 13, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
159 changes: 94 additions & 65 deletions Source/ePC-8801MA/vm/disk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -397,11 +397,12 @@ void DISK::close()
}
ejected = true;
}
inserted = write_protected = false;
file_size.d = 0;
sector_size.sd = sector_num.sd = 0;
sector = NULL;
}
inserted = write_protected = false;
file_size.d = 0;
sector_size.sd = sector_num.sd = 0;
sector = NULL;
track_mfm = drive_mfm;
}

bool DISK::get_track(int trk, int side)
{
Expand Down Expand Up @@ -429,36 +430,53 @@ bool DISK::get_track(int trk, int side)
return false;
}

// track found
sector = buffer + offset.d;
sector_num.read_2bytes_le_from(sector + 4);
pair data_size;
data_size.read_2bytes_le_from(sector + 14);

// create each sector position in track
int sync_size = drive_mfm ? 12 : 6;
int am_size = drive_mfm ? 3 : 0;
int gap0_size = drive_mfm ? 80 : 40;
int gap1_size = drive_mfm ? 50 : 26;
int gap2_size = drive_mfm ? 22 : 11;
int gap3_size = 0, gap4_size;

if(media_type == MEDIA_TYPE_144 || media_type == MEDIA_TYPE_2HD) {
if(drive_mfm) {
if(data_size.sd == 256 && sector_num.sd == 26) gap3_size = 54;
if(data_size.sd == 512 && sector_num.sd == 15) gap3_size = 84;
if(data_size.sd == 1024 && sector_num.sd == 8) gap3_size = 116;
} else {
if(data_size.sd == 128 && sector_num.sd == 26) gap3_size = 27;
// track found
sector = buffer + offset.d;
sector_num.read_2bytes_le_from(sector + 4);
pair data_size;
data_size.read_2bytes_le_from(sector + 14);

// detect actual density from sector headers in this track.
track_mfm = false;
if(sector_num.sd == 0) {
track_mfm = drive_mfm;
} else {
uint8* t = sector;
for(int i = 0; i < sector_num.sd; i++) {
data_size.read_2bytes_le_from(t + 14);
// t[6]: 0x00 = MFM(double-density), 0x40 = FM(single-density)
if(t[6] == 0x00) {
track_mfm = true;
break;
}
t += data_size.sd + 0x10;
}
}

// create each sector position in track
int sync_size = track_mfm ? 12 : 6;
int am_size = track_mfm ? 3 : 0;
int gap0_size = track_mfm ? 80 : 40;
int gap1_size = track_mfm ? 50 : 26;
int gap2_size = track_mfm ? 22 : 11;
int gap3_size = 0, gap4_size;

if(media_type == MEDIA_TYPE_144 || media_type == MEDIA_TYPE_2HD) {
if(track_mfm) {
if(data_size.sd == 256 && sector_num.sd == 26) gap3_size = 54;
if(data_size.sd == 512 && sector_num.sd == 15) gap3_size = 84;
if(data_size.sd == 1024 && sector_num.sd == 8) gap3_size = 116;
} else {
if(data_size.sd == 128 && sector_num.sd == 26) gap3_size = 27;
if(data_size.sd == 256 && sector_num.sd == 15) gap3_size = 42;
if(data_size.sd == 512 && sector_num.sd == 8) gap3_size = 58;
}
} else {
if(drive_mfm) {
if(data_size.sd == 256 && sector_num.sd == 16) gap3_size = 51;
if(data_size.sd == 512 && sector_num.sd == 9) gap3_size = 80;
if(data_size.sd == 1024 && sector_num.sd == 5) gap3_size = 116;
} else {
if(track_mfm) {
if(data_size.sd == 256 && sector_num.sd == 16) gap3_size = 51;
if(data_size.sd == 512 && sector_num.sd == 9) gap3_size = 80;
if(data_size.sd == 1024 && sector_num.sd == 5) gap3_size = 116;
} else {
if(data_size.sd == 128 && sector_num.sd == 16) gap3_size = 27;
if(data_size.sd == 256 && sector_num.sd == 9) gap3_size = 42;
if(data_size.sd == 512 && sector_num.sd == 5) gap3_size = 58;
Expand Down Expand Up @@ -524,11 +542,11 @@ bool DISK::make_track(int trk, int side)
return false;
}

// make track image
int sync_size = drive_mfm ? 12 : 6;
int am_size = drive_mfm ? 3 : 0;
int gap2_size = drive_mfm ? 22 : 11;
uint8 gap_data = drive_mfm ? 0x4e : 0xff;
// make track image
int sync_size = track_mfm ? 12 : 6;
int am_size = track_mfm ? 3 : 0;
int gap2_size = track_mfm ? 22 : 11;
uint8 gap_data = track_mfm ? 0x4e : 0xff;

// preamble
memset(track, gap_data, track_size);
Expand Down Expand Up @@ -753,10 +771,11 @@ bool DISK::format_track(int trk, int side)
offset.d = DISK_BUFFER_SIZE;
offset.write_4bytes_le_to(buffer + 0x20 + trkside * 4);

trim_required = true;
sector_num.sd = 0;
return true;
}
trim_required = true;
sector_num.sd = 0;
track_mfm = drive_mfm;
return true;
}

void DISK::insert_sector(uint8 c, uint8 h, uint8 r, uint8 n, bool deleted, bool crc_error, uint8 fill_data, int length)
{
Expand All @@ -776,7 +795,7 @@ void DISK::insert_sector(uint8 c, uint8 h, uint8 r, uint8 n, bool deleted, bool
t[3] = n;
t[4] = sector_num.b.l;
t[5] = sector_num.b.h;
t[6] = drive_mfm ? 0 : 0x40;
t[6] = track_mfm ? 0 : 0x40;
t[7] = deleted ? 0x10 : 0;
t[8] = crc_error ? 0xb0 : t[7]; // FIXME: always data crc error ?
t[14] = (length >> 0) & 0xff;
Expand Down Expand Up @@ -881,12 +900,12 @@ int DISK::get_max_tracks()

int DISK::get_track_size()
{
if(inserted) {
return media_type == MEDIA_TYPE_144 ? 12500 : media_type == MEDIA_TYPE_2HD ? 10410 : drive_mfm ? 6250 : 3100;
} else {
return drive_type == DRIVE_TYPE_144 ? 12500 : drive_type == DRIVE_TYPE_2HD ? 10410 : drive_mfm ? 6250 : 3100;
}
}
if(inserted) {
return media_type == MEDIA_TYPE_144 ? 12500 : media_type == MEDIA_TYPE_2HD ? 10410 : track_mfm ? 6250 : 3100;
} else {
return drive_type == DRIVE_TYPE_144 ? 12500 : drive_type == DRIVE_TYPE_2HD ? 10410 : drive_mfm ? 6250 : 3100;
}
}

double DISK::get_usec_per_bytes(int bytes)
{
Expand Down Expand Up @@ -1553,11 +1572,11 @@ bool DISK::standard_to_d88(int type, int ncyl, int nside, int nsec, int size)
return true;
}

#define STATE_VERSION 4
#define STATE_VERSION 5

void DISK::save_state(FILEIO* state_fio)
{
state_fio->FputUint32(STATE_VERSION);
void DISK::save_state(FILEIO* state_fio)
{
state_fio->FputUint32(STATE_VERSION);

state_fio->Fwrite(buffer, sizeof(buffer), 1);
state_fio->Fwrite(orig_path, sizeof(orig_path), 1);
Expand All @@ -1576,10 +1595,11 @@ void DISK::save_state(FILEIO* state_fio)
state_fio->FputInt32(is_special_disk);
state_fio->Fwrite(track, sizeof(track), 1);
state_fio->FputInt32(sector_num.sd);
state_fio->FputBool(invalid_format);
state_fio->FputBool(no_skew);
state_fio->Fwrite(sync_position, sizeof(sync_position), 1);
state_fio->Fwrite(id_position, sizeof(id_position), 1);
state_fio->FputBool(invalid_format);
state_fio->FputBool(no_skew);
state_fio->FputBool(track_mfm);
state_fio->Fwrite(sync_position, sizeof(sync_position), 1);
state_fio->Fwrite(id_position, sizeof(id_position), 1);
state_fio->Fwrite(data_position, sizeof(data_position), 1);
state_fio->FputInt32(sector ? (int)(sector - buffer) : -1);
state_fio->FputInt32(sector_size.sd);
Expand All @@ -1594,9 +1614,10 @@ void DISK::save_state(FILEIO* state_fio)

bool DISK::load_state(FILEIO* state_fio)
{
if(state_fio->FgetUint32() != STATE_VERSION) {
return false;
}
uint32 state_version = state_fio->FgetUint32();
if(state_version < 4 || state_version > STATE_VERSION) {
return false;
}
state_fio->Fread(buffer, sizeof(buffer), 1);
state_fio->Fread(orig_path, sizeof(orig_path), 1);
state_fio->Fread(dest_path, sizeof(dest_path), 1);
Expand All @@ -1613,11 +1634,16 @@ bool DISK::load_state(FILEIO* state_fio)
is_fdi_image = state_fio->FgetBool();
is_special_disk = state_fio->FgetInt32();
state_fio->Fread(track, sizeof(track), 1);
sector_num.sd = state_fio->FgetInt32();
invalid_format = state_fio->FgetBool();
no_skew = state_fio->FgetBool();
state_fio->Fread(sync_position, sizeof(sync_position), 1);
state_fio->Fread(id_position, sizeof(id_position), 1);
sector_num.sd = state_fio->FgetInt32();
invalid_format = state_fio->FgetBool();
no_skew = state_fio->FgetBool();
if(state_version >= 5) {
track_mfm = state_fio->FgetBool();
} else {
track_mfm = true;
}
state_fio->Fread(sync_position, sizeof(sync_position), 1);
state_fio->Fread(id_position, sizeof(id_position), 1);
state_fio->Fread(data_position, sizeof(data_position), 1);
int offset = state_fio->FgetInt32();
sector = (offset != -1) ? buffer + offset : NULL;
Expand All @@ -1626,9 +1652,12 @@ bool DISK::load_state(FILEIO* state_fio)
density = state_fio->FgetUint8();
deleted = state_fio->FgetBool();
crc_error = state_fio->FgetBool();
drive_type = state_fio->FgetUint8();
drive_rpm = state_fio->FgetInt32();
drive_type = state_fio->FgetUint8();
drive_rpm = state_fio->FgetInt32();
drive_mfm = state_fio->FgetBool();
if(state_version < 5) {
track_mfm = drive_mfm;
}
return true;
}

Expand Down
26 changes: 14 additions & 12 deletions Source/ePC-8801MA/vm/disk.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,12 +151,13 @@ class DISK
file_size.d = 0;
sector_size.sd = sector_num.sd = 0;
sector = NULL;
drive_type = DRIVE_TYPE_UNK;
drive_rpm = 0;
drive_mfm = true;
static int num = 0;
drive_num = num++;
}
drive_type = DRIVE_TYPE_UNK;
drive_rpm = 0;
drive_mfm = true;
track_mfm = true;
static int num = 0;
drive_num = num++;
}
~DISK()
{
if(inserted) {
Expand Down Expand Up @@ -215,12 +216,13 @@ class DISK
// track
uint8 track[TRACK_BUFFER_SIZE];
pair sector_num;
bool invalid_format;
bool no_skew;
int cur_track, cur_side;

int sync_position[256];
int id_position[256];
bool invalid_format;
bool no_skew;
int cur_track, cur_side;
bool track_mfm;

int sync_position[256];
int id_position[256];
int data_position[256];

// sector
Expand Down
14 changes: 8 additions & 6 deletions Source/ePC-8801MA/vm/event.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
#include "../emu.h"
#include "device.h"

#define MAX_CPU 8
#define MAX_SOUND 8
#define MAX_CPU 8
#define MAX_SOUND 16
#define MAX_LINES 1024
#define MAX_EVENT 64
#define NO_EVENT -1
Expand Down Expand Up @@ -201,10 +201,12 @@ class EVENT : public DEVICE
{
set_context_cpu(device, CPU_CLOCKS);
}
void set_context_sound(DEVICE* device)
{
d_sound[dcount_sound++] = device;
}
void set_context_sound(DEVICE* device)
{
if(dcount_sound < MAX_SOUND) {
d_sound[dcount_sound++] = device;
}
}
bool now_skip();
#ifdef SDL
void abort_main_cpu() { d_cpu[0].device->write_signal(SIG_CPU_FIRQ, 1, 1); }
Expand Down
10 changes: 6 additions & 4 deletions Source/ePC-8801MA/vm/i8251.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,12 @@ void I8251::reset()
#else
recv = 0xff;
#endif // SDL
// dont reset dsr
status &= DSR;
status |= TXRDY | TXE;
txen = rxen = loopback = false;
// dont reset dsr
status &= DSR;
status |= TXRDY | TXE;
// XM8 v1.10 behavior: transmitter remains enabled after reset.
txen = true;
rxen = loopback = false;

recv_buffer->clear();
send_buffer->clear();
Expand Down
1 change: 1 addition & 0 deletions Source/ePC-8801MA/vm/i8251.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ class I8251 : public DEVICE
init_output_signals(&outputs_dtr);
init_output_signals(&outputs_rst);
init_output_signals(&outputs_rts);
set_device_name(_T("8251 SIO"));
}
~I8251() {}

Expand Down
1 change: 1 addition & 0 deletions Source/ePC-8801MA/vm/i8253.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ class I8253 : public DEVICE
counter[i].freq = 0;
}
device_model = INTEL_8253;
set_device_name(_T("8253 PIT"));
}
~I8253() {}

Expand Down
13 changes: 7 additions & 6 deletions Source/ePC-8801MA/vm/i8255.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,13 @@ class I8255 : public DEVICE
public:
I8255(VM* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu)
{
for(int i = 0; i < 3; i++) {
init_output_signals(&port[i].outputs);
port[i].wreg = port[i].rreg = 0;//0xff;
}
clear_ports_by_cmdreg = false;
}
for(int i = 0; i < 3; i++) {
init_output_signals(&port[i].outputs);
port[i].wreg = port[i].rreg = 0;//0xff;
}
clear_ports_by_cmdreg = false;
set_device_name(_T("8255 PIO"));
}
~I8255() {}

// common functions
Expand Down
7 changes: 4 additions & 3 deletions Source/ePC-8801MA/vm/upd1990a.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,10 @@ void UPD1990A::write_signal(int id, uint32 data, uint32 mask)
#endif
}
clk = next;
} else if(id == SIG_UPD1990A_STB) {
bool next = ((data & mask) != 0);
if(!stb && next && !clk) {
} else if(id == SIG_UPD1990A_STB) {
bool next = ((data & mask) != 0);
// Accept strobe on rising edge regardless of current CLK level.
if(!stb && next) {
#ifdef HAS_UPD4990A
if(cmd == 7) {
mode = shift_cmd | 0x80;
Expand Down
11 changes: 7 additions & 4 deletions Source/ePC-8801MA/vm/upd1990a.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,13 @@ class UPD1990A : public DEVICE
hold = false;
dout = 0;
dout_changed = false;
#ifdef HAS_UPD4990A
shift_cmd = 0;
#endif
}
#ifdef HAS_UPD4990A
shift_cmd = 0;
set_device_name(_T("uPD4990A RTC"));
#else
set_device_name(_T("uPD1990A RTC"));
#endif
}
~UPD1990A() {}

// common functions
Expand Down
Loading