Files
WizzardSK 1e0de94dc7 Sega CD: run Mode 1 cartridges with and without the BIOS (fixes #39) (#78)
* Sega CD: report no disc to a TOC request, and run CD-aware cartridges without the BIOS

Attack of the PETSCII Robots (issue #39) lists the Sega CD among its devices,
so BlastEm attaches one; it uses it for music when it is there and runs
without it otherwise.

With no Sega CD BIOS the load failed outright. A cartridge that only wants a
Sega CD now runs without one when the BIOS cannot be loaded, as it does on a
console with no Sega CD attached, and says so in the log. A CD image still
requires the BIOS.

With the BIOS the screen stayed black. The game asks the BIOS for the drive
status and waits while it reads 'reading TOC'; the drive had no disc, but
while the BIOS asked for a TOC format the drive reported TOC_READ regardless
of its state, so the BIOS never saw 'no disc' and the game waited forever. A
drive with no disc now reports no disc, and the game reaches its 'enable Mode
1?' prompt; answering No starts the game. With a disc in the drive nothing
changes: an audio CD boots to the same frames, bit for bit, as before.

* Sega CD: restart the drive's status reports when the host drops HOCK

With the Sega CD attached, Attack of the PETSCII Robots (issue #39) froze
after 'Yes' at its 'enable Mode 1?' prompt, and took 20 s to reach the
prompt at all. The game resets the sub CPU twice, loading the BIOS and its
own program into PRG-RAM each time, and only the first time did its program
ever run.

During init the BIOS drops HOCK, raises it again and expects the drive to
report STOP with every other nibble zero, as it does at power on; anything
else it takes for a drive error, and it starts over. The drive sends zeroes
only until its first command, and it never went back to that state, so after
the second reset it kept sending its last status - format 'not ready' and the
mute flag - and the BIOS restarted itself every few frames without ever
calling the game's program. The drive now goes back to sending zeroes while
HOCK is low.

The prompt now comes up after 2 s, and 'Yes' goes on through the game's
music screen to its title menu (silent with no audio CD in the drive, since
the music is CD audio). An audio CD boots to the same frames, bit for bit,
as before.
2026-09-26 15:36:44 -05:00

77 lines
2.6 KiB
C

#ifndef SEGACD_H_
#define SEGACD_H_
#include <stdint.h>
#include "genesis.h"
#include "cdd_mcu.h"
#include "rf5c164.h"
#include "serialize.h"
typedef struct {
m68k_context *m68k;
system_media *media;
genesis_context *genesis;
uint16_t gate_array[0xC0];
uint16_t *rom; //unaltered ROM, needed for mirrored locations
uint16_t *rom_mut; //ROM with low 16-bit of HINT vector modified by register write
uint16_t *prog_ram;
uint16_t *word_ram;
uint8_t *bram;
uint8_t *bram_cart;
uint32_t stopwatch_cycle;
uint32_t int2_cycle;
uint32_t graphics_int_cycle;
uint32_t periph_reset_cycle;
uint32_t last_refresh_cycle;
uint32_t graphics_cycle;
uint32_t base;
uint32_t m68k_pc;
uint32_t speed_percent;
uint32_t graphics_x;
uint32_t graphics_y;
uint32_t graphics_dx;
uint32_t graphics_dy;
uint16_t graphics_dst_x;
uint16_t vdp_dma_value;
uint8_t graphics_pixels[4];
uint8_t graphics_debug_window;
uint8_t timer_pending;
uint8_t timer_value;
uint8_t busreq;
uint8_t busack;
uint8_t reset;
uint8_t need_reset;
uint8_t memptr_start_index;
uint8_t cdc_dst_low;
uint8_t cdc_int_ack;
uint8_t graphics_step;
uint8_t graphics_dst_y;
uint8_t enter_debugger;
uint8_t main_has_word2m;
uint8_t main_swap_request;
uint8_t bank_toggle;
uint8_t sub_paused_wordram;
uint8_t bram_cart_write_enabled;
uint8_t bram_cart_id;
uint8_t has_vdp_dma_value;
rf5c164 pcm;
lc8951 cdc;
cdd_mcu cdd;
cdd_fader fader;
} segacd_context;
uint8_t segacd_bios_available(uint8_t force_region, rom_info *info);
segacd_context *alloc_configure_segacd(system_media *media, uint32_t opts, uint8_t force_region, rom_info *info);
void free_segacd(segacd_context *cd);
memmap_chunk *segacd_main_cpu_map(segacd_context *cd, uint8_t cart_boot, uint32_t *num_chunks);
uint32_t gen_cycle_to_scd(uint32_t cycle, genesis_context *gen);
void scd_run(segacd_context *cd, uint32_t cycle);
void scd_adjust_cycle(segacd_context *cd, uint32_t deduction);
void scd_toggle_graphics_debug(segacd_context *cd);
void segacd_set_speed_percent(segacd_context *cd, uint32_t percent);
void segacd_serialize(segacd_context *cd, serialize_buffer *buf, uint8_t all);
void segacd_register_section_handlers(segacd_context *cd, deserialize_buffer *buf);
void segacd_format_bram(uint8_t *buffer, size_t size);
void segacd_config_updated(segacd_context *cd);
#endif //SEGACD_H_