Mercurial > repos > blastem
diff cdd_mcu.h @ 2061:7c1760b5b3e5 segacd
Implemented basic TOC functionality of CDD MCU
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Thu, 27 Jan 2022 00:33:41 -0800 |
parents | |
children | 07ed42bd7b4c |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cdd_mcu.h Thu Jan 27 00:33:41 2022 -0800 @@ -0,0 +1,164 @@ +#ifndef CDD_MCU_H_ +#define CDD_MCU_H_ +#include "system.h" + + +typedef enum { + SF_ABSOLUTE, + SF_RELATIVE, + SF_TRACK, + SF_TOCO, + SF_TOCT, + SF_TOCN, + SF_E, + SF_NOTREADY = 0xF +} status_format; + +typedef enum { + CMD_NOP, + CMD_STOP, + CMD_REPORT_REQUEST, + CMD_READ, + CMD_SEEK, + CMD_INVALID, + CMD_PAUSE, + CMD_PLAY, + CMD_FFWD, + CMD_RWD, + CMD_TRACK_SKIP, + CMD_TRACK_CUE, + CMD_DOOR_CLOSE, + CMD_DOOR_OPEN +} host_cmd; + +typedef enum { + DS_STOP, + DS_PLAY, + DS_SEEK, + DS_SCAN, + DS_PAUSE, + DS_DOOR_OPEN, + DS_SUM_ERROR, + DS_CMD_ERROR, + DS_FUNC_ERROR, + DS_TOC_READ, + DS_TRACKING, + DS_NO_DISC, + DS_DISC_LEADOUT, + DS_DISC_LEADIN, + DS_TRAY_MOVING, +} drive_status; + + +typedef struct { + uint8_t status; + uint8_t format; + union { + struct { + uint8_t min_high; + uint8_t min_low; + uint8_t sec_high; + uint8_t sec_low; + uint8_t frame_high; + uint8_t frame_low; + uint8_t flags; + } time; + struct { + uint8_t track_high; + uint8_t track_low; + uint8_t padding0; + uint8_t padding1; + uint8_t control; + uint8_t padding2; + uint8_t flags; + } track; + struct { + uint8_t first_track_high; + uint8_t first_track_low; + uint8_t last_track_high; + uint8_t last_track_low; + uint8_t version; + uint8_t padding; + uint8_t flags; + } toct; + struct { + uint8_t min_high; + uint8_t min_low; + uint8_t sec_high; + uint8_t sec_low; + uint8_t frame_high; + uint8_t frame_low; + uint8_t track_low; + } tocn; + struct { + } error; + } b; + uint8_t checksum; +} cdd_status; + +typedef struct { + uint8_t cmd_type; + uint8_t must_be_zero; + union { + struct { + uint8_t min_high; + uint8_t min_low; + uint8_t sec_high; + uint8_t sec_low; + uint8_t frame_high; + uint8_t frame_low; + } time; + struct { + uint8_t padding; + uint8_t status_type; + uint8_t track_high; + uint8_t track_low; + } format; + struct { + uint8_t padding; + uint8_t direction; + uint8_t tracks_highest; + uint8_t tracks_midhigh; + uint8_t tracks_midlow; + uint8_t tracks_lowest; + } skip; + struct { + uint8_t track_high; + uint8_t track_low; + } track; + } b; + uint8_t padding; + uint8_t checksum; +} cdd_cmd; + +typedef struct { + system_media *media; + uint32_t cycle; //this is in CD block CLKS + uint32_t next_int_cycle; //this is in SCD MCLKS + uint32_t last_subcode_cycle; + uint32_t last_nibble_cycle; + int current_status_nibble; + int current_cmd_nibble; + uint32_t head_pba; + uint32_t seek_pba; + cdd_status status_buffer; + cdd_cmd cmd_buffer; + status_format requested_format; + drive_status status; + drive_status error_status; + uint8_t requested_track; + uint8_t cmd_recv_wait; + uint8_t cmd_recv_pending; + uint8_t int_pending; + uint8_t toc_valid; + uint8_t seeking; +} cdd_mcu; + +void cdd_mcu_init(cdd_mcu *context, system_media *media); +void cdd_mcu_run(cdd_mcu *context, uint32_t cycle, uint16_t *gate_array); +void cdd_hock_enabled(cdd_mcu *context); +void cdd_hock_disabled(cdd_mcu *context); +void cdd_mcu_start_cmd_recv(cdd_mcu *context, uint16_t *gate_array); +void cdd_mcu_adjust_cycle(cdd_mcu *context, uint32_t deduction); + +#endif //CD_MCU_H_