DraCo Amiga HD disk support, PC disk write/format support, keyboard repeat support.

This commit is contained in:
Toni Wilen 2024-01-14 15:43:50 +02:00
parent 49e4c1dd7b
commit 76ac1b50fc
6 changed files with 377 additions and 213 deletions

View File

@ -20,6 +20,7 @@
#include "zfile.h"
#include "keybuf.h"
#include "rommgr.h"
#include "disk.h"
static int maxcnt = 100;
@ -650,43 +651,56 @@ static void draco_1wire_reset(void)
#endif
}
static uae_u16 draco_floppy_data;
static int draco_floppy_bits, draco_floppy_rate;
// draco reads amiga disks by polling register
// that returns time since last flux change.
static uae_u8 draco_floppy_get_data(void)
{
static uae_u16 data;
static int bits;
if (bits < 8) {
uae_u16 t = floppy_get_raw_data();
data |= (t & 0xff) << (8 - bits);
bits += 8;
if (draco_floppy_bits < 8) {
uae_u16 t = floppy_get_raw_data(&draco_floppy_rate);
draco_floppy_data |= (t & 0xff) << (8 - draco_floppy_bits);
draco_floppy_bits += 8;
}
int bit1 = (data & 0x8000);
int bit2 = (data & 0x4000);
int bit3 = (data & 0x2000);
int bit4 = (data & 0x1000);
int bit1 = (draco_floppy_data & 0x8000);
int bit2 = (draco_floppy_data & 0x4000);
int bit3 = (draco_floppy_data & 0x2000);
int bit4 = (draco_floppy_data & 0x1000);
int v = 0;
if (bit1) {
data <<= 1;
bits--;
return 8;
draco_floppy_data <<= 1;
draco_floppy_bits--;
v = 8;
} else if (bit2) {
draco_floppy_data <<= 2;
draco_floppy_bits -= 2;
v = 24;
} else if (bit3) {
draco_floppy_data <<= 3;
draco_floppy_bits -= 3;
v = 40;
} else if (bit4) {
draco_floppy_data <<= 4;
draco_floppy_bits -= 4;
v = 56;
}
if (bit2) {
data <<= 2;
bits -= 2;
return 24;
switch (draco_floppy_rate) {
case FLOPPY_RATE_250K:
// above values are in 250Kbs
break;
case FLOPPY_RATE_500K:
v /= 2;
break;
case FLOPPY_RATE_300K:
v = v * 30 / 25;
break;
case FLOPPY_RATE_1M:
v /= 4;
break;
}
if (bit3) {
data <<= 3;
bits -= 3;
return 40;
}
if (bit4) {
data <<= 4;
bits -= 4;
return 56;
}
return 0;
return v;
}
static void vmotion_write(uaecptr addr, uae_u8 v)
@ -1184,7 +1198,7 @@ void draco_ext_interrupt(bool i6)
draco_irq();
}
void draco_keycode(uae_u8 scancode, uae_u8 state)
void draco_keycode(uae_u16 scancode, uae_u8 state)
{
if (currprefs.cs_compatible == CP_DRACO && (currprefs.cpuboard_settings & 0x10)) {
if (draco_kbd_buffer_len == 0 && !(draco_reg[3] & DRSTAT_KBDRECV)) {
@ -1300,6 +1314,8 @@ void draco_reset(int hardreset)
draco_superio_cfg[6] = 0xff;
draco_superio_cfg[13] = 0x65;
draco_superio_cfg[14] = 1;
draco_floppy_data = 0;
draco_floppy_bits = 0;
memset(draco_reg, 0, sizeof(draco_reg));
draco_reg[1] = DRCNTRL_FDCINTENA | DRCNTRL_KBDINTENA;
draco_reg[5] = 0xff;

View File

@ -6,4 +6,4 @@ void draco_free(void);
bool draco_mouse(int port, int x, int y, int z, int b);
void draco_bustimeout(uaecptr addr);
void draco_ext_interrupt(bool);
void draco_keycode(uae_u8 scancode, uae_u8 state);
void draco_keycode(uae_u16 scancode, uae_u8 state);

View File

@ -199,6 +199,9 @@ static int temp_uid_cnt[IDTYPE_MAX];
static int gp_swappeddevices[MAX_INPUT_DEVICES][IDTYPE_MAX];
static int osk_state;
extern int draco_keyboard_get_rate(void);
static int draco_keybord_repeat_cnt, draco_keybord_repeat_code;
bool osk_status(void)
{
return osk_state != 0;
@ -4382,6 +4385,17 @@ void inputdevice_hsync (bool forceread)
maybe_read_input();
}
}
if (draco_keybord_repeat_cnt > 0) {
draco_keybord_repeat_cnt--;
if (draco_keybord_repeat_cnt == 0) {
int rate = draco_keyboard_get_rate();
int b = (rate >> 3) & 3;
int d = (rate >> 0) & 7;
float r = ((1 << b) * (d + 8) / 240.0f) * 1000.0f;
draco_keybord_repeat_cnt = (int)(vblank_hz * maxvpos * r / 1000);
draco_keycode(draco_keybord_repeat_code, 1);
}
}
}
static uae_u16 POTDAT (int joy)
@ -5800,6 +5814,7 @@ void inputdevice_reset (void)
lightpen_trigger2 = 0;
cubo_flag = 0;
alg_flag &= 1;
draco_keybord_repeat_cnt = 0;
}
static int getoldport (struct uae_input_device *id)
@ -10458,9 +10473,18 @@ void inputdevice_draco_key(int kc)
if (events[i].data == kc && events[i].data2 && events[i].allow_mask == AM_K) {
int code = events[i].data2;
if ((code & 0xff00) == 0xe000) {
draco_keycode((code & 0xff) | 0x100, state);
code = (code & 0xff) | 0x100;
} else {
draco_keycode(code & 0xff, state);
code &= 0xff;
}
draco_keycode(code, state);
if (state) {
int rate = draco_keyboard_get_rate();
int init = ((rate >> 5) & 3) * 250 + 250;
draco_keybord_repeat_cnt = (int)(vblank_hz * maxvpos * init / 1000);
draco_keybord_repeat_code = code;
} else {
draco_keybord_repeat_code = 0;
}
}
}

View File

@ -196,7 +196,7 @@ DEFEVENTKB(KEY_ALT_LEFT,_T("Left Alt"),AM_K,AK_LALT,0x38)
DEFEVENTKB(KEY_AMIGA_LEFT,_T("Left Amiga"),AM_K,AK_LAMI,0xe05b)
DEFEVENTKB(KEY_AMIGA_RIGHT,_T("Right Amiga"),AM_K,AK_RAMI,0xe05c)
DEFEVENTKB(KEY_ALT_RIGHT,_T("Right Alt"),AM_K,AK_RALT,0xe038)
DEFEVENTKB(KEY_SHIFT_RIGHT,_T("Right Shift"),AM_K,AK_RSH,0x59)
DEFEVENTKB(KEY_SHIFT_RIGHT,_T("Right Shift"),AM_K,AK_RSH,0x36)
DEFEVENTKB(KEY_SPACE,_T("Space"),AM_K,AK_SPC,0x39)
DEFEVENTKB(KEY_CURSOR_UP,_T("Cursor Up"),AM_K,AK_UP,0xe048)
DEFEVENTKB(KEY_CURSOR_DOWN,_T("Cursor Down"),AM_K,AK_DN,0xe050)

View File

@ -25,6 +25,8 @@
Bits 0 - 1 = scan code set. */
uint8_t keyboard_mode = 0x02;
extern void write_log(const char *, ...);
void draco_kdb_queue_add(void *d, uint8_t val, int state);
void kbc_at_dev_reset(void *d, int r)
@ -32,6 +34,12 @@ void kbc_at_dev_reset(void *d, int r)
}
void keyboard_at_log(const char *txt, ...)
{
char buffer[256];
va_list parms;
va_start(parms, txt);
vsprintf(buffer, txt, parms);
write_log(buffer);
va_end(parms);
}
void fatalx(const char *txt, ...)
{
@ -1155,6 +1163,13 @@ draco_key_process(uint16_t scan, int down)
void *draco_keyboard_init(void)
{
draco_kbd.type = 10;
draco_kbd.name = "draco";
memset(oldkey, 0, sizeof(oldkey));
keyboard_at_set_defaults(&draco_kbd);
return &draco_kbd;
}
int draco_keyboard_get_rate(void)
{
return draco_kbd.rate;
}

469
x86.cpp
View File

@ -573,7 +573,7 @@ static bool floppy_did_reset;
static bool floppy_irq;
static bool floppy_specify_pio;
static uae_u8 *floppy_pio_buffer;
static int floppy_pio_len, floppy_pio_cnt;
static int floppy_pio_len, floppy_pio_cnt, floppy_pio_active;
static uae_s8 floppy_rate;
#define PC_SEEK_DELAY 50
@ -750,6 +750,201 @@ static bool floppy_valid_rate(struct floppy_reserved *fr)
return fr->rate == floppy_rate || floppy_rate < 0;
}
static void floppy_format(struct x86_bridge *xb, bool real)
{
uae_u8 cmd = floppy_cmd[0];
struct pc_floppy *pcf = &floppy_pc[floppy_num];
struct floppy_reserved fr = { 0 };
bool valid_floppy = disk_reserved_getinfo(floppy_num, &fr);
#if FLOPPY_DEBUG
write_log(_T("Floppy%d %s format MF=%d N=%d:SC=%d:GPL=%d:D=%d\n"),
floppy_num, real ? _T("real") : _T("sim"), (floppy_cmd[0] & 0x40) ? 1 : 0,
floppy_cmd[2], floppy_cmd[3], floppy_cmd[4], floppy_cmd[5]);
write_log(_T("DMA addr %08x len %04x\n"), dma[2].page | dma[2].ac, dma[2].cb);
write_log(_T("IMG: Secs=%d Heads=%d\n"), fr.secs, fr.heads);
#endif
int secs = floppy_cmd[3];
int sector = pcf->sector;
int head = pcf->head;
int cyl = pcf->cyl;
if (valid_floppy && fr.img) {
// TODO: CHRN values totally ignored
pcf->head = (floppy_cmd[1] & 4) ? 1 : 0;
uae_u8 buf[512];
memset(buf, floppy_cmd[5], sizeof buf);
uae_u8 *pioptr = floppy_pio_buffer;
for (int i = 0; i < secs && i < fr.secs && !fr.wrprot; i++) {
uae_u8 cx = 0, hx = 0, rx = 0, nx = 0;
if (floppy_specify_pio) {
if (real) {
cx = *pioptr++;
hx = *pioptr++;
rx = *pioptr++;
nx = *pioptr++;
floppy_pio_cnt += 4;
} else {
floppy_pio_len += 4;
}
} else {
if (real) {
cx = dma_channel_read(2);
hx = dma_channel_read(2);
rx = dma_channel_read(2);
nx = dma_channel_read(2);
}
}
pcf->sector = rx - 1;
#if FLOPPY_DEBUG
write_log(_T("Floppy%d %d/%d: C=%d H=%d R=%d N=%d\n"), floppy_num, i, fr.secs, cx, hx, rx, nx);
#endif
if (real) {
zfile_fseek(fr.img, (pcf->cyl * fr.secs * fr.heads + pcf->head * fr.secs + pcf->sector) * 512, SEEK_SET);
zfile_fwrite(buf, 1, 512, fr.img);
}
pcf->sector++;
}
} else {
floppy_status[0] |= 0x40; // abnormal termination
floppy_status[0] |= 0x10; // equipment check
}
floppy_cmd_len = 7;
if (fr.wrprot) {
floppy_status[0] |= 0x40; // abnormal termination
floppy_status[1] |= 0x02; // not writable
}
floppy_result[0] = floppy_status[0];
floppy_result[1] = floppy_status[1];
floppy_result[2] = floppy_status[2];
floppy_result[3] = pcf->cyl;
floppy_result[4] = pcf->head;
floppy_result[5] = pcf->sector + 1;
floppy_result[6] = floppy_cmd[2];
if (real) {
floppy_delay_hsync = 10;
disk_reserved_setinfo(floppy_num, pcf->cyl, pcf->head, 1);
} else {
pcf->cyl = cyl;
pcf->sector = sector;
pcf->head = head;
}
}
static void floppy_write(struct x86_bridge *xb, bool real)
{
uae_u8 cmd = floppy_cmd[0];
struct pc_floppy *pcf = &floppy_pc[floppy_num];
struct floppy_reserved fr = { 0 };
bool valid_floppy = disk_reserved_getinfo(floppy_num, &fr);
#if FLOPPY_DEBUG
write_log(_T("Floppy%d %s write MT=%d MF=%d C=%d:H=%d:R=%d:N=%d:EOT=%d:GPL=%d:DTL=%d\n"),
floppy_num, real ? _T("real") : _T("sim"), (floppy_cmd[0] & 0x80) ? 1 : 0, (floppy_cmd[0] & 0x40) ? 1 : 0,
floppy_cmd[2], floppy_cmd[3], floppy_cmd[4], floppy_cmd[5],
floppy_cmd[6], floppy_cmd[7], floppy_cmd[8]);
write_log(_T("DMA addr %08x len %04x\n"), dma[2].page | dma[2].ac, dma[2].ab);
#endif
floppy_delay_hsync = 50;
int eot = floppy_cmd[6];
bool mt = (floppy_cmd[0] & 0x80) != 0;
int sector = pcf->sector;
int head = pcf->head;
int cyl = pcf->cyl;
if (valid_floppy) {
if (fr.img && pcf->cyl != floppy_cmd[2]) {
floppy_status[0] |= 0x40; // abnormal termination
floppy_status[2] |= 0x20; // wrong cylinder
} else if (fr.img) {
int end = 0;
pcf->sector = floppy_cmd[4] - 1;
pcf->head = (floppy_cmd[1] & 4) ? 1 : 0;
uae_u8 *pioptr = floppy_pio_buffer;
while (!end && !fr.wrprot) {
int len = 128 << floppy_cmd[5];
uae_u8 buf[512] = { 0 };
if (floppy_specify_pio) {
for (int i = 0; i < 512 && i < len; i++) {
if (real) {
if (floppy_pio_cnt >= floppy_pio_len) {
end = 1;
break;
}
int v = *pioptr++;
buf[i] = v;
floppy_pio_cnt++;
} else {
floppy_pio_len++;
}
}
} else {
for (int i = 0; i < 512 && i < len; i++) {
if (real) {
int v = dma_channel_read(2);
if (v < 0) {
end = -1;
break;
}
buf[i] = v;
if (v >= 0x10000) {
end = 1;
break;
}
}
}
}
#if FLOPPY_DEBUG
write_log(_T("LEN=%d END=%d C=%d H=%d S=%d. IMG S=%d H=%d\n"), len, end, pcf->cyl, pcf->head, pcf->sector, fr.secs, fr.heads);
#endif
if (end < 0)
break;
if (real) {
zfile_fseek(fr.img, (pcf->cyl * fr.secs * fr.heads + pcf->head * fr.secs + pcf->sector) * 512, SEEK_SET);
zfile_fwrite(buf, 1, 512, fr.img);
}
pcf->sector++;
if (pcf->sector == eot) {
if (mt) {
pcf->sector = 0;
if (pcf->head)
pcf->cyl++;
pcf->head ^= 1;
} else {
break;
}
}
if (pcf->sector >= fr.secs) {
pcf->sector = 0;
pcf->head ^= 1;
break;
}
}
floppy_result[3] = cyl;
floppy_result[4] = pcf->head;
floppy_result[5] = pcf->sector + 1;
floppy_result[6] = floppy_cmd[5];
} else {
floppy_status[0] |= 0x40; // abnormal termination
floppy_status[0] |= 0x10; // equipment check
}
}
floppy_cmd_len = 7;
if (fr.wrprot) {
floppy_status[0] |= 0x40; // abnormal termination
floppy_status[1] |= 0x02; // not writable
}
floppy_result[0] = floppy_status[0];
floppy_result[1] = floppy_status[1];
floppy_result[2] = floppy_status[2];
if (real) {
floppy_delay_hsync = 10;
disk_reserved_setinfo(floppy_num, pcf->cyl, pcf->head, 1);
} else {
pcf->cyl = cyl;
pcf->sector = sector;
pcf->head = head;
}
}
static void floppy_do_cmd(struct x86_bridge *xb)
{
uae_u8 cmd = floppy_cmd[0];
@ -834,87 +1029,7 @@ static void floppy_do_cmd(struct x86_bridge *xb)
case 5:
{
#if FLOPPY_DEBUG
write_log(_T("Floppy%d write MT=%d MF=%d C=%d:H=%d:R=%d:N=%d:EOT=%d:GPL=%d:DTL=%d\n"),
floppy_num, (floppy_cmd[0] & 0x80) ? 1 : 0, (floppy_cmd[0] & 0x40) ? 1 : 0,
floppy_cmd[2], floppy_cmd[3], floppy_cmd[4], floppy_cmd[5],
floppy_cmd[6], floppy_cmd[7], floppy_cmd[8]);
write_log(_T("DMA addr %08x len %04x\n"), dma[2].page | dma[2].ac, dma[2].ab);
#endif
floppy_delay_hsync = 50;
int eot = floppy_cmd[6];
bool mt = (floppy_cmd[0] & 0x80) != 0;
int cyl = pcf->cyl;
if (valid_floppy) {
if (fr.img && pcf->cyl != floppy_cmd[2]) {
floppy_status[0] |= 0x40; // abnormal termination
floppy_status[2] |= 0x20; // wrong cylinder
} else if (fr.img) {
int end = 0;
pcf->sector = floppy_cmd[4] - 1;
pcf->head = (floppy_cmd[1] & 4) ? 1 : 0;
while (!end && !fr.wrprot) {
int len = 128 << floppy_cmd[5];
uae_u8 buf[512] = { 0 };
if (floppy_specify_pio) {
end = -1;
} else {
for (int i = 0; i < 512 && i < len; i++) {
int v = dma_channel_read(2);
if (v < 0) {
end = -1;
break;
}
buf[i] = v;
if (v >= 0x10000) {
end = 1;
break;
}
}
}
#if FLOPPY_DEBUG
write_log(_T("LEN=%d END=%d C=%d H=%d S=%d. IMG S=%d H=%d\n"), len, end, pcf->cyl, pcf->head, pcf->sector, fr.secs, fr.heads);
#endif
if (end < 0)
break;
zfile_fseek(fr.img, (pcf->cyl * fr.secs * fr.heads + pcf->head * fr.secs + pcf->sector) * 512, SEEK_SET);
zfile_fwrite(buf, 1, 512, fr.img);
pcf->sector++;
if (pcf->sector == eot) {
if (mt) {
pcf->sector = 0;
if (pcf->head)
pcf->cyl++;
pcf->head ^= 1;
} else {
break;
}
}
if (pcf->sector >= fr.secs) {
pcf->sector = 0;
pcf->head ^= 1;
break;
}
}
floppy_result[3] = cyl;
floppy_result[4] = pcf->head;
floppy_result[5] = pcf->sector + 1;
floppy_result[6] = floppy_cmd[5];
} else {
floppy_status[0] |= 0x40; // abnormal termination
floppy_status[0] |= 0x10; // equipment check
}
}
floppy_cmd_len = 7;
if (fr.wrprot) {
floppy_status[0] |= 0x40; // abnormal termination
floppy_status[1] |= 0x02; // not writable
}
floppy_result[0] = floppy_status[0];
floppy_result[1] = floppy_status[1];
floppy_result[2] = floppy_status[2];
floppy_delay_hsync = 10;
disk_reserved_setinfo(floppy_num, pcf->cyl, pcf->head, 1);
floppy_write(xb, true);
}
break;
@ -957,6 +1072,7 @@ static void floppy_do_cmd(struct x86_bridge *xb)
memcpy(pioptr, buf, 512);
pioptr += 512;
floppy_pio_len += 512;
floppy_pio_active = 1;
} else {
for (int i = 0; i < 512 && i < len; i++) {
int v = dma_channel_write(2, buf[i]);
@ -1036,56 +1152,13 @@ static void floppy_do_cmd(struct x86_bridge *xb)
pcf->sector %= fr.secs;
}
floppy_delay_hsync = 10;
floppy_delay_hsync = maxvpos * 20;
disk_reserved_setinfo(floppy_num, pcf->cyl, pcf->head, 1);
break;
case 13:
{
#if FLOPPY_DEBUG
write_log(_T("Floppy%d format MF=%d N=%d:SC=%d:GPL=%d:D=%d\n"),
floppy_num, (floppy_cmd[0] & 0x40) ? 1 : 0,
floppy_cmd[2], floppy_cmd[3], floppy_cmd[4], floppy_cmd[5]);
write_log(_T("DMA addr %08x len %04x\n"), dma[2].page | dma[2].ac, dma[2].cb);
write_log(_T("IMG: Secs=%d Heads=%d\n"), fr.secs, fr.heads);
#endif
int secs = floppy_cmd[3];
if (valid_floppy && fr.img) {
// TODO: CHRN values totally ignored
pcf->head = (floppy_cmd[1] & 4) ? 1 : 0;
uae_u8 buf[512];
memset(buf, floppy_cmd[5], sizeof buf);
for (int i = 0; i < secs && i < fr.secs && !fr.wrprot; i++) {
uae_u8 cx = dma_channel_read(2);
uae_u8 hx = dma_channel_read(2);
uae_u8 rx = dma_channel_read(2);
uae_u8 nx = dma_channel_read(2);
pcf->sector = rx - 1;
#if FLOPPY_DEBUG
write_log(_T("Floppy%d %d/%d: C=%d H=%d R=%d N=%d\n"), floppy_num, i, fr.secs, cx, hx, rx, nx);
#endif
zfile_fseek(fr.img, (pcf->cyl * fr.secs * fr.heads + pcf->head * fr.secs + pcf->sector) * 512, SEEK_SET);
zfile_fwrite(buf, 1, 512, fr.img);
pcf->sector++;
}
} else {
floppy_status[0] |= 0x40; // abnormal termination
floppy_status[0] |= 0x10; // equipment check
}
floppy_cmd_len = 7;
if (fr.wrprot) {
floppy_status[0] |= 0x40; // abnormal termination
floppy_status[1] |= 0x02; // not writable
}
floppy_result[0] = floppy_status[0];
floppy_result[1] = floppy_status[1];
floppy_result[2] = floppy_status[2];
floppy_result[3] = pcf->cyl;
floppy_result[4] = pcf->head;
floppy_result[5] = pcf->sector + 1;
floppy_result[6] = floppy_cmd[2];
floppy_delay_hsync = 10;
disk_reserved_setinfo(floppy_num, pcf->cyl, pcf->head, 1);
floppy_format(xb, true);
}
break;
@ -1169,62 +1242,96 @@ static void outfloppy(struct x86_bridge *xb, int portnum, uae_u8 v)
}
break;
case 0x3f5: // data reg
floppy_cmd[floppy_idx] = v;
if (floppy_idx == 0) {
floppy_cmd_len = -1;
switch(v & 31)
{
case 3: // specify
floppy_cmd_len = 3;
break;
case 4: // sense drive status
floppy_cmd_len = 2;
break;
case 5: // write data
floppy_cmd_len = 9;
break;
case 6: // read data
floppy_cmd_len = 9;
break;
case 7: // recalibrate
floppy_cmd_len = 2;
break;
case 8: // sense interrupt status
floppy_cmd_len = 1;
break;
case 10: // read id
floppy_cmd_len = 2;
break;
case 12: // perpendiculaor mode
if (xb->type < 0) {
if (floppy_pio_len > 0 && floppy_pio_cnt < floppy_pio_len && floppy_pio_active) {
floppy_pio_buffer[floppy_pio_cnt++] = v;
if (floppy_pio_cnt >= floppy_pio_len) {
floppy_pio_cnt = 0;
floppy_pio_active = 0;
floppy_clear_irq();
floppy_do_cmd(xb);
floppy_pio_cnt = 0;
floppy_pio_len = 0;
}
} else {
floppy_cmd[floppy_idx] = v;
if (floppy_idx == 0) {
floppy_cmd_len = -1;
switch(v & 31)
{
case 3: // specify
floppy_cmd_len = 3;
break;
case 4: // sense drive status
floppy_cmd_len = 2;
break;
case 5: // write data
floppy_cmd_len = 9;
break;
case 6: // read data
floppy_cmd_len = 9;
break;
case 7: // recalibrate
floppy_cmd_len = 2;
break;
case 8: // sense interrupt status
floppy_cmd_len = 1;
break;
case 10: // read id
floppy_cmd_len = 2;
break;
case 12: // perpendiculaor mode
if (xb->type < 0) {
floppy_cmd_len = 2;
}
break;
case 13: // format track
floppy_cmd_len = 6;
break;
case 15: // seek
floppy_cmd_len = 3;
break;
case 16: // get versionm
if (xb->type < 0) {
floppy_cmd_len = 1;
}
break;
case 19: // configure
if (xb->type < 0) {
floppy_cmd_len = 4;
}
break;
}
break;
case 13: // format track
floppy_cmd_len = 6;
break;
case 15: // seek
floppy_cmd_len = 3;
break;
case 16: // get versionm
if (xb->type < 0) {
if (floppy_cmd_len < 0) {
write_log(_T("Floppy unimplemented command %02x\n"), v);
floppy_cmd_len = 1;
}
break;
case 19: // configure
if (xb->type < 0) {
floppy_cmd_len = 4;
}
floppy_idx++;
if (floppy_idx >= floppy_cmd_len) {
if (floppy_specify_pio && (floppy_cmd[0] & 31) == 5) {
floppy_write(xb, false);
floppy_pio_cnt = 0;
floppy_pio_active = 0;
if (floppy_pio_len > 0) {
floppy_delay_hsync = 10;
floppy_pio_active = 1;
} else {
floppy_write(xb, true);
}
} else if (floppy_specify_pio && (floppy_cmd[0] & 31) == 13) {
floppy_format(xb, false);
floppy_pio_cnt = 0;
floppy_pio_active = 0;
if (floppy_pio_len > 0) {
floppy_delay_hsync = 10;
floppy_pio_active = 1;
} else {
floppy_format(xb, true);
}
} else {
floppy_do_cmd(xb);
}
break;
}
if (floppy_cmd_len < 0) {
write_log(_T("Floppy unimplemented command %02x\n"), v);
floppy_cmd_len = 1;
}
}
floppy_idx++;
if (floppy_idx >= floppy_cmd_len) {
floppy_do_cmd(xb);
}
break;
case 0x3f7: // configuration control
@ -1276,9 +1383,9 @@ static uae_u8 infloppy(struct x86_bridge *xb, int portnum)
v = 0;
if (!floppy_delay_hsync && (floppy_dpc & 4))
v |= 0x80;
if (floppy_idx || floppy_delay_hsync || floppy_pio_len) {
if (floppy_idx || floppy_delay_hsync || floppy_pio_active) {
v |= 0x10;
if (floppy_pio_len)
if (floppy_pio_active)
v |= 0x20;
}
if ((v & 0x80) && floppy_dir)
@ -1293,6 +1400,7 @@ static uae_u8 infloppy(struct x86_bridge *xb, int portnum)
v = floppy_pio_buffer[floppy_pio_cnt++];
if (floppy_pio_cnt >= floppy_pio_len) {
floppy_pio_len = 0;
floppy_pio_active = 0;
floppy_clear_irq();
floppy_delay_hsync = 50;
}
@ -1335,10 +1443,11 @@ static uae_u8 infloppy(struct x86_bridge *xb, int portnum)
return v;
}
uae_u16 floppy_get_raw_data(void)
uae_u16 floppy_get_raw_data(int *rate)
{
struct floppy_reserved fr = { 0 };
bool valid_floppy = disk_reserved_getinfo(floppy_num, &fr);
*rate = fr.rate;
if (valid_floppy) {
return DSKBYTR_fake(fr.num);
}