Skip to content

Commit

Permalink
fdd: implement write for fdd and upd765
Browse files Browse the repository at this point in the history
  • Loading branch information
karlvr committed Dec 31, 2024
1 parent c09d958 commit cf51bff
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 9 deletions.
23 changes: 23 additions & 0 deletions chips/fdd.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,8 @@ int fdd_seek_track(fdd_t* fdd, int track);
int fdd_seek_sector(fdd_t* fdd, int side, uint8_t c, uint8_t h, uint8_t r, uint8_t n);
// read the next byte from the seeked-to sector, return FDD_RESULT_*
int fdd_read(fdd_t* fdd, int side, uint8_t* out_data);
// write the next byte to the seeked-to sector, return FDD_RESULT_*
int fdd_write(fdd_t* fdd, int side, uint8_t data);

#ifdef __cplusplus
} /* extern "C" */
Expand Down Expand Up @@ -292,4 +294,25 @@ int fdd_read(fdd_t* fdd, int side, uint8_t* out_data) {
return FDD_RESULT_NOT_READY;
}

int fdd_write(fdd_t* fdd, int side, uint8_t data) {
CHIPS_ASSERT(fdd && (side >= 0) && (side < FDD_MAX_SIDES));
if (fdd->has_disc & fdd->motor_on) {
fdd->cur_side = side;
const fdd_sector_t* sector = &fdd->disc.tracks[side][fdd->cur_track_index].sectors[fdd->cur_sector_index];
if (fdd->cur_sector_pos < sector->data_size) {
const int data_offset = sector->data_offset + fdd->cur_sector_pos;
fdd->data[data_offset] = data;
fdd->cur_sector_pos++;
if (fdd->cur_sector_pos < sector->data_size) {
return FDD_RESULT_SUCCESS;
}
else {
return FDD_RESULT_END_OF_SECTOR;
}
}
return FDD_RESULT_NOT_FOUND;
}
return FDD_RESULT_NOT_READY;
}

#endif /* CHIPS_IMPL */
39 changes: 30 additions & 9 deletions chips/upd765.h
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,8 @@ typedef int (*upd765_seektrack_cb)(int drive, int track, void* user_data);
typedef int (*upd765_seeksector_cb)(int drive, int side, upd765_sectorinfo_t* inout_info, void* user_data);
/* callback to read the next sector data byte */
typedef int (*upd765_read_cb)(int drive, int side, void* user_data, uint8_t* out_data);
/* callback to write the next sector data byte */
typedef int (*upd765_write_cb)(int drive, int side, void* user_data, uint8_t data);
/* callback to read info about first sector on current reack */
typedef int (*upd765_trackinfo_cb)(int drive, int side, void* user_data, upd765_sectorinfo_t* out_info);
/* callback to get info about disk drive (called on SENSE_DRIVE_STATUS command) */
Expand All @@ -219,6 +221,7 @@ typedef struct {
upd765_seektrack_cb seektrack_cb;
upd765_seeksector_cb seeksector_cb;
upd765_read_cb read_cb;
upd765_write_cb write_cb;
upd765_trackinfo_cb trackinfo_cb;
upd765_driveinfo_cb driveinfo_cb;
void* user_data;
Expand All @@ -242,6 +245,7 @@ typedef struct {
upd765_seektrack_cb seektrack_cb;
upd765_seeksector_cb seeksector_cb;
upd765_read_cb read_cb;
upd765_write_cb write_cb;
upd765_trackinfo_cb trackinfo_cb;
upd765_driveinfo_cb driveinfo_cb;
void* user_data;
Expand Down Expand Up @@ -394,6 +398,7 @@ static void _upd765_cmd(upd765_t* upd) {
CHIPS_ASSERT(upd->phase == UPD765_PHASE_COMMAND);
switch (upd->cmd) {
case UPD765_CMD_READ_DATA:
case UPD765_CMD_WRITE_DATA:
{
upd->st[0] = upd->fifo[1] & 7; /* HD, US1, US0 */
upd->sector_info.c = upd->fifo[2];
Expand Down Expand Up @@ -528,7 +533,6 @@ static void _upd765_cmd(upd765_t* upd) {
break;

case UPD765_CMD_READ_DELETED_DATA:
case UPD765_CMD_WRITE_DATA:
case UPD765_CMD_WRITE_DELETED_DATA:
case UPD765_CMD_READ_A_TRACK:
case UPD765_CMD_FORMAT_A_TRACK:
Expand Down Expand Up @@ -575,9 +579,27 @@ static uint8_t _upd765_exec_rd(upd765_t* upd) {

/* called when a byte is written during the exec phase */
static void _upd765_exec_wr(upd765_t* upd, uint8_t data) {
// FIXME
(void)upd;
(void)data;
CHIPS_ASSERT(upd->phase == UPD765_PHASE_EXEC);
switch (upd->cmd) {
case UPD765_CMD_WRITE_DATA:
{
/* write next sector data byte to FDD */
const int fdd_index = upd->st[0] & 3;
const int side = (upd->st[0] & 4) >> 2;
const int res = upd->write_cb(fdd_index, side, upd->user_data, data);
if (res != UPD765_RESULT_SUCCESS) {
if (res & UPD765_RESULT_NOT_READY) {
upd->st[0] |= UPD765_ST0_NR;
}
_upd765_to_phase_result(upd);
}
}
break;
default:
/* shouldn't happen */
CHIPS_ASSERT(false);
break;
}
}

/* write a data byte to the upd765 */
Expand Down Expand Up @@ -627,9 +649,7 @@ static inline uint8_t _upd765_read_status(upd765_t* upd) {
for between 2us and 50us, for now just indicate
that we're always ready during the command and result phase
*/
/* FIXME: data direction is currently always set as FDC->CPU,
since the emulation doesn't support write operations
*/
const int dio = upd->cmd == UPD765_CMD_READ_DATA ? UPD765_STATUS_DIO : 0;
switch (upd->phase) {
case UPD765_PHASE_IDLE:
status |= UPD765_STATUS_RQM;
Expand All @@ -638,10 +658,10 @@ static inline uint8_t _upd765_read_status(upd765_t* upd) {
status |= UPD765_STATUS_CB|UPD765_STATUS_RQM;
break;
case UPD765_PHASE_EXEC:
status |= UPD765_STATUS_CB|UPD765_STATUS_EXM|UPD765_STATUS_DIO|UPD765_STATUS_RQM;
status |= UPD765_STATUS_CB|UPD765_STATUS_EXM|dio|UPD765_STATUS_RQM;
break;
case UPD765_PHASE_RESULT:
status |= UPD765_STATUS_CB|UPD765_STATUS_DIO|UPD765_STATUS_RQM;
status |= UPD765_STATUS_CB|dio|UPD765_STATUS_RQM;
break;
}
return status;
Expand All @@ -658,6 +678,7 @@ void upd765_init(upd765_t* upd, const upd765_desc_t* desc) {
upd->seektrack_cb = desc->seektrack_cb;
upd->seeksector_cb = desc->seeksector_cb;
upd->read_cb = desc->read_cb;
upd->write_cb = desc->write_cb;
upd->trackinfo_cb = desc->trackinfo_cb;
upd->driveinfo_cb = desc->driveinfo_cb;
upd->user_data = desc->user_data;
Expand Down
11 changes: 11 additions & 0 deletions systems/cpc.h
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ static void _cpc_bankswitch(uint8_t ram_config, uint8_t rom_enable, uint8_t rom_
static int _cpc_fdc_seektrack(int drive, int track, void* user_data);
static int _cpc_fdc_seeksector(int drive, int side, upd765_sectorinfo_t* inout_info, void* user_data);
static int _cpc_fdc_read(int drive, int side, void* user_data, uint8_t* out_data);
static int _cpc_fdc_write(int drive, int side, void* user_data, uint8_t data);
static int _cpc_fdc_trackinfo(int drive, int side, void* user_data, upd765_sectorinfo_t* out_info);
static void _cpc_fdc_driveinfo(int drive, void* user_data, upd765_driveinfo_t* out_info);

Expand Down Expand Up @@ -302,6 +303,7 @@ void cpc_init(cpc_t* sys, const cpc_desc_t* desc) {
.seektrack_cb = _cpc_fdc_seektrack,
.seeksector_cb = _cpc_fdc_seeksector,
.read_cb = _cpc_fdc_read,
.write_cb = _cpc_fdc_write,
.trackinfo_cb = _cpc_fdc_trackinfo,
.driveinfo_cb = _cpc_fdc_driveinfo,
.user_data = sys,
Expand Down Expand Up @@ -984,6 +986,15 @@ static int _cpc_fdc_read(int drive, int side, void* user_data, uint8_t* out_data
}
}

static int _cpc_fdc_write(int drive, int side, void* user_data, uint8_t data) {
if (0 == drive) {
cpc_t* sys = (cpc_t*) user_data;
return fdd_write(&sys->fdd, side, data);
} else {
return UPD765_RESULT_NOT_READY;
}
}

static int _cpc_fdc_trackinfo(int drive, int side, void* user_data, upd765_sectorinfo_t* out_info) {
CHIPS_ASSERT((side >= 0) && (side < 2));
if (0 == drive) {
Expand Down

0 comments on commit cf51bff

Please sign in to comment.