mirror of
https://github.com/MiSTer-devel/CDi_MiSTer.git
synced 2026-04-19 03:04:19 +00:00
CDIC: Rewritten audio state machine
- Changes based on findings of the CDIC_BlackBoxAnalyzer project
- Removed side channel for audio coding
- A real CDIC reads the audio coding always from RAM
- Removed the concept of the audio tick found in MAME
- A real CDIC performs audio playback asynchronous to the CD reading
- Seek time now 19 sectors
- Fixes audio glitch in "Help cutscene" in "Zelda - Wand of Gamelon"
"Remember, tools can only be used..."
- Fixes audio regression during "Hotel Mario" score screen
- Fixed spurious IRQ caused by sector data interrupt after reading stopped
- Should fix hang on shopkeeper cutscene in "Zelda - Wand of Gamelon"
(Cannot be reproduced or is very unlikely now)
This commit is contained in:
4
.vscode/settings.json
vendored
4
.vscode/settings.json
vendored
@@ -68,6 +68,8 @@
|
||||
"system_error": "cpp",
|
||||
"text_encoding": "cpp",
|
||||
"thread": "cpp",
|
||||
"typeindex": "cpp"
|
||||
"typeindex": "cpp",
|
||||
"iterator": "cpp",
|
||||
"random": "cpp"
|
||||
}
|
||||
}
|
||||
32
README.md
32
README.md
@@ -23,27 +23,22 @@ CD images can be stored as CHD or CUE/BIN format.
|
||||
|
||||
Core Utilization:
|
||||
|
||||
Logic utilization (in ALMs) 13,431 / 41,910 ( 32 % )
|
||||
Total registers 15619
|
||||
Logic utilization (in ALMs) 13,425 / 41,910 ( 32 % )
|
||||
Total registers 15587
|
||||
Total block memory bits 630,471 / 5,662,720 ( 11 % )
|
||||
Total DSP Blocks 66 / 112 ( 59 % )
|
||||
|
||||
### TODOs in order of priority
|
||||
|
||||
* Fix audio regression during Hotel Mario Score Screen (was ok in 250214)
|
||||
* Investigate hangup during Wand of Gamelon Shopkeeper cutscene
|
||||
* Find a better solution for reducing CPU speed
|
||||
* Fix regression: Audio hiccups during Philips Logo in Burn:Cycle
|
||||
* A workaround is CPU overclocking
|
||||
* Investigate mysterious non loading behavior
|
||||
* Investigate "Zelda's Adventure" sound hiccups
|
||||
* During stop of audiomap and switch to audio channel playback
|
||||
the audio channel mask is set one sector too late.
|
||||
* Investigate sound hiccups in both 2D Zelda games
|
||||
* Occurs during "Help-Cutscene" when SFX is played
|
||||
* Probably the same as with "Zelda's Adventure"
|
||||
* Investigate input responsiveness (skipped events?)
|
||||
* Investigate graphical glitch on the left edge in "Alice in Wonderland" and "Laser Lords"
|
||||
* Investigate graphical glitch at the bottom of the screen in Kether during pause
|
||||
* Investigate screeching sound effect in the menu of "Golf Tips"
|
||||
* Fix hang on audio track stop or change
|
||||
* Fix hang on audio track stop or change in media player
|
||||
* Investigate "Gray border glitch" at the top of "Myst" gameplay (seems to be only one plane)
|
||||
* Fix reset behaviour (Core is sometimes hanging after reset)
|
||||
* Add auto start of titles using front panel "Play" button
|
||||
@@ -103,9 +98,22 @@ by emulation errors but are also present on the real machine.
|
||||
The video data is changed while it is displayed.
|
||||
* When I load a save game in "Burn:Cycle" it plays a short and unclean loop of noise until I do something
|
||||
* I thought that was a bug in the core at first too. However, it is actually like this on a real CD-i too.
|
||||
* The music of Burn:Cycle sometimes has "pops" and "clicks"
|
||||
* This game is special. It doesn't play music from CD like most games for this system would do.
|
||||
* Small loops of sampled music are loaded from CD, stored in memory and randomly concatenated together
|
||||
to create the background music. These samples are sometimes not very "loopable" creating a pop at looping points.
|
||||
* This issue is reproducible on a real 210/05 as well
|
||||
* The music during the Philips Logo animation of Burn:Cycle has broken audio
|
||||
* This issue is reproducible on a real 210/05 as well
|
||||
* The problem can be fixed by overclocking the CPU
|
||||
* Burn:Cycle - Random flickering animated text in front of the "Psychic Roulette" credit card terminal
|
||||
* This actually happens on the real machine. I also thought this might be a CPU speed issue, considering that
|
||||
the flickering disappears if the CPU is slightly overclocked.
|
||||
* Flashback: The audio and video during the intro are asynchronous
|
||||
* This curiously happens on the real machine as well and doesn't depend on 50 or 60 Hz.
|
||||
* This curiously happens on the real machine as well and doesn't depend on 50 or 60 Hz
|
||||
* When dying in "Zelda's Adventure" the accompanying sound effect doesn't match the audio data on CD
|
||||
* Good catch! This is a programming error which can be reproduced on a real CD-i 210/05 as well,
|
||||
which causes the audio playback to start one sector too late.
|
||||
* The same phenomenon exists in the "Help cutscene" of "Zelda - Wand of Gamelon"
|
||||
* It is not audible in that game, because of silence in the beginning
|
||||
|
||||
|
||||
@@ -22,10 +22,8 @@ module audiodecoder (
|
||||
audiostream.source out,
|
||||
output bit sample_channel,
|
||||
|
||||
input use_external_coding, // don't read coding from memory, use parameter
|
||||
input header_coding_s cd_audio_coding, // used when external_coding set
|
||||
input cdda_mode, // don't read coding from memory, just go for CDDA
|
||||
input start_playback,
|
||||
input audio_tick, // CD sector tick rate 75 Hz
|
||||
output header_coding_s playback_coding_out,
|
||||
input [12:0] playback_addr,
|
||||
|
||||
@@ -38,7 +36,6 @@ module audiodecoder (
|
||||
// XA ADPCM handling
|
||||
DETECT_CODING,
|
||||
DETECT_CODING2,
|
||||
WAIT_AUDIO_TICKS,
|
||||
EVALHEADER,
|
||||
EVALHEADER2,
|
||||
READ_SAMPLE,
|
||||
@@ -195,16 +192,17 @@ module audiodecoder (
|
||||
stop_playback_latch <= 0;
|
||||
if (start_playback) begin
|
||||
// Coding can be read from memory or forced
|
||||
if (use_external_coding) begin
|
||||
if (cdda_mode) begin
|
||||
// Don't read coding from memory.
|
||||
// Use cd_audio_coding
|
||||
|
||||
block_cnt <= 0;
|
||||
group_cnt <= 0;
|
||||
$display("EXTERNAL CODING %x", cd_audio_coding);
|
||||
playback_coding.rate <= k44Khz;
|
||||
playback_coding.bps <= k16Bps;
|
||||
playback_coding.chan <= kStereo;
|
||||
|
||||
playback_coding <= cd_audio_coding;
|
||||
decoder_state <= (cd_audio_coding.bps == k16Bps) ? CDDA_READ : WAIT_AUDIO_TICKS;
|
||||
decoder_state <= CDDA_READ;
|
||||
end else begin
|
||||
// Read coding from sector header
|
||||
decoder_state <= DETECT_CODING;
|
||||
@@ -249,14 +247,6 @@ module audiodecoder (
|
||||
|
||||
end
|
||||
end
|
||||
WAIT_AUDIO_TICKS: begin
|
||||
if (audio_tick) decoder_state <= EVALHEADER;
|
||||
|
||||
if (stop_playback_latch) begin
|
||||
decoder_state <= IDLE;
|
||||
stop_playback_latch <= 0;
|
||||
end
|
||||
end
|
||||
EVALHEADER: begin
|
||||
if (mem_ack) begin
|
||||
data_addr <= block_addr + data_offset;
|
||||
|
||||
@@ -5,7 +5,8 @@ module audiofifo (
|
||||
input reset,
|
||||
audiostream.sink in,
|
||||
audiostream.source out,
|
||||
output nearly_full
|
||||
output nearly_full,
|
||||
output nearly_empty
|
||||
);
|
||||
|
||||
bit signed [15:0] mem[64];
|
||||
@@ -20,12 +21,13 @@ module audiofifo (
|
||||
bit indizes_equal_during_write_d;
|
||||
bit indizes_equal_during_write_q;
|
||||
|
||||
assign out.write = count != 0 && !reset && !indizes_equal_during_write_q;
|
||||
assign in.strobe = count < 60 && !reset && in.write;
|
||||
assign out.write = count != 0 && !reset && !indizes_equal_during_write_q;
|
||||
assign in.strobe = count < 60 && !reset && in.write;
|
||||
|
||||
// Always a minimum of 28 XA samples per block
|
||||
// We go for 48 just to be safe
|
||||
assign nearly_full = count >= 48;
|
||||
assign nearly_empty = count <= 3;
|
||||
|
||||
always_comb begin
|
||||
read_index_d = read_index_q;
|
||||
|
||||
@@ -6,7 +6,6 @@ module audioplayer (
|
||||
input clk,
|
||||
input sample_tick37,
|
||||
input sample_tick44,
|
||||
input audio_tick,
|
||||
input reset,
|
||||
|
||||
output bit [12:0] mem_addr,
|
||||
@@ -15,18 +14,15 @@ module audioplayer (
|
||||
input mem_ack,
|
||||
input mem_ack_q,
|
||||
|
||||
input header_coding_s cd_audio_coding,
|
||||
input start_playback, // flag starts CD sector playback at playback_addr
|
||||
input abort_playback_request,
|
||||
input enable_audiomap,
|
||||
input disable_audiomap,
|
||||
input [12:0] playback_addr,
|
||||
input start_playback,
|
||||
input stop_playback,
|
||||
input cdda_mode,
|
||||
output bit playback_active,
|
||||
output bit finished_buffer_playback,
|
||||
output decoder_disable_audiomap,
|
||||
|
||||
output bit signed [15:0] audio_left,
|
||||
output bit signed [15:0] audio_right,
|
||||
output bit audiomap_active,
|
||||
output bit audiomap_finished_playback,
|
||||
output decoder_disable_audiomap
|
||||
output bit signed [15:0] audio_right
|
||||
);
|
||||
|
||||
audiostream xa_out ();
|
||||
@@ -42,7 +38,6 @@ module audioplayer (
|
||||
header_coding_s current_active_coding;
|
||||
|
||||
wire decoder_idle;
|
||||
bit playback_request;
|
||||
bit [12:0] playback_request_addr /*verilator public_flat_rd*/;
|
||||
bit decoder_start /*verilator public_flat_rd*/ = 0;
|
||||
|
||||
@@ -52,8 +47,6 @@ module audioplayer (
|
||||
.clk(clk),
|
||||
.reset(reset),
|
||||
.reset_filter_on_start(reset_filter_on_start),
|
||||
.stop_playback(disable_audiomap),
|
||||
.audio_tick(audio_tick),
|
||||
.mem_addr(mem_addr),
|
||||
.mem_data(mem_data),
|
||||
.mem_rd(mem_rd),
|
||||
@@ -63,55 +56,57 @@ module audioplayer (
|
||||
.out(xa_out),
|
||||
.sample_channel(xa_channel),
|
||||
|
||||
.use_external_coding(!audiomap_active),
|
||||
.cd_audio_coding(cd_audio_coding),
|
||||
.start_playback(decoder_start),
|
||||
.stop_playback(stop_playback),
|
||||
.cdda_mode,
|
||||
.playback_coding_out(current_active_coding),
|
||||
.playback_addr(playback_request_addr),
|
||||
.idle(decoder_idle),
|
||||
.disable_audiomap(decoder_disable_audiomap)
|
||||
);
|
||||
|
||||
wire [1:0] fifo_nearly_full;
|
||||
wire [1:0] fifo_nearly_empty;
|
||||
bit fifo_nearly_empty_q;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
decoder_start <= 0;
|
||||
fifo_nearly_empty_q <= fifo_nearly_empty[0];
|
||||
finished_buffer_playback <= 0;
|
||||
|
||||
if (reset) begin
|
||||
playback_request <= 0;
|
||||
audiomap_active <= 0;
|
||||
playback_active <= 0;
|
||||
playback_request_addr <= 0;
|
||||
end else begin
|
||||
// Only start playback when decoder is idle
|
||||
if (decoder_idle && !decoder_start) begin
|
||||
playback_request <= 0;
|
||||
decoder_start <= playback_request || (audiomap_active && !decoder_disable_audiomap);
|
||||
end
|
||||
|
||||
// CD Sector playback
|
||||
if (start_playback) begin
|
||||
playback_request <= 1;
|
||||
playback_request_addr <= playback_addr;
|
||||
if (decoder_idle && !decoder_start && fifo_nearly_empty[0]) begin
|
||||
decoder_start <= playback_active && !decoder_disable_audiomap;
|
||||
finished_buffer_playback <= finished_buffer_playback_latched;
|
||||
end
|
||||
|
||||
// To react on audiomap activation change
|
||||
if (enable_audiomap) audiomap_active <= 1;
|
||||
if (disable_audiomap || decoder_disable_audiomap) audiomap_active <= 0;
|
||||
if (stop_playback || decoder_disable_audiomap) begin
|
||||
playback_active <= 0;
|
||||
end
|
||||
|
||||
if (disable_audiomap || abort_playback_request) playback_request <= 0;
|
||||
// Buffer playback
|
||||
if (start_playback && !playback_active) begin
|
||||
playback_active <= 1;
|
||||
// ADPCM playback always starts at 0x2800
|
||||
// For CDDA this might not be accurate
|
||||
playback_request_addr <= cdda_mode ? 13'h0f00 : 13'h1400;
|
||||
end
|
||||
|
||||
// after the decoder was started, change address to the next buffer
|
||||
if (audiomap_active && decoder_start) begin
|
||||
playback_request_addr <= playback_request_addr == 13'h1400 ? 13'h1900 : 13'h1400;
|
||||
if (decoder_start && playback_active) begin
|
||||
if (cdda_mode)
|
||||
playback_request_addr <= playback_request_addr == 13'h0a00 ? 13'h0f00 : 13'h0a00;
|
||||
else
|
||||
playback_request_addr <= playback_request_addr == 13'h1400 ? 13'h1900 : 13'h1400;
|
||||
end
|
||||
|
||||
// Store playback_request_addr from extern only at start
|
||||
if (enable_audiomap && !audiomap_active) begin
|
||||
playback_request_addr <= playback_addr;
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
wire [1:0] fifo_nearly_full;
|
||||
|
||||
always_comb begin
|
||||
// Mono is default. Write to both FIFOs and ignore the channel
|
||||
@@ -139,26 +134,28 @@ module audioplayer (
|
||||
.reset,
|
||||
.in(xa_fifo_in[0]),
|
||||
.out(xa_fifo_out[0]),
|
||||
.nearly_full(fifo_nearly_full[0])
|
||||
.nearly_full(fifo_nearly_full[0]),
|
||||
.nearly_empty(fifo_nearly_empty[0])
|
||||
);
|
||||
audiofifo fifo_right (
|
||||
.clk,
|
||||
.reset,
|
||||
.in(xa_fifo_in[1]),
|
||||
.out(xa_fifo_out[1]),
|
||||
.nearly_full(fifo_nearly_full[1])
|
||||
.nearly_full(fifo_nearly_full[1]),
|
||||
.nearly_empty(fifo_nearly_empty[1])
|
||||
);
|
||||
|
||||
bit playback_active = 0;
|
||||
bit audio_fifo_output_enabled = 0;
|
||||
bit sample_toggle18 = 0;
|
||||
bit decoder_idle_q;
|
||||
|
||||
assign reset_filter_on_start = !playback_active;
|
||||
assign reset_filter_on_start = !audio_fifo_output_enabled;
|
||||
|
||||
bit strobe_fifo;
|
||||
always_comb begin
|
||||
strobe_fifo = 0;
|
||||
if (playback_active) begin
|
||||
if (audio_fifo_output_enabled) begin
|
||||
if (current_active_coding.rate == k44Khz && sample_tick44) strobe_fifo = 1;
|
||||
if (current_active_coding.rate == k37Khz && sample_tick37) strobe_fifo = 1;
|
||||
if (current_active_coding.rate == k18Khz && sample_tick37 && sample_toggle18)
|
||||
@@ -174,20 +171,21 @@ module audioplayer (
|
||||
// One would have been enough, but let's be sure.
|
||||
// Not having this results into pops especially percievible
|
||||
// with Tetris
|
||||
bit playback_active_next_sample_tick;
|
||||
bit audio_fifo_output_enabled_next_sample_tick;
|
||||
|
||||
bit finished_buffer_playback_latched;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
dc_bias_cnt <= !dc_bias_cnt;
|
||||
|
||||
audiomap_finished_playback <= 0;
|
||||
decoder_idle_q <= decoder_idle;
|
||||
|
||||
xa_fifo_out[0].strobe <= 0;
|
||||
xa_fifo_out[1].strobe <= 0;
|
||||
|
||||
if (reset) begin
|
||||
playback_active <= 0;
|
||||
playback_active_next_sample_tick <= 0;
|
||||
audio_fifo_output_enabled <= 0;
|
||||
audio_fifo_output_enabled_next_sample_tick <= 0;
|
||||
xa_fifo_out[0].strobe <= 0;
|
||||
xa_fifo_out[1].strobe <= 0;
|
||||
end else begin
|
||||
@@ -195,20 +193,24 @@ module audioplayer (
|
||||
if (fifo_nearly_full == 2'b11 &&
|
||||
((current_active_coding.rate != k44Khz && sample_tick37) ||
|
||||
(current_active_coding.rate == k44Khz && sample_tick44))) begin
|
||||
playback_active_next_sample_tick <= 1;
|
||||
playback_active <= playback_active_next_sample_tick;
|
||||
audio_fifo_output_enabled_next_sample_tick <= 1;
|
||||
audio_fifo_output_enabled <= audio_fifo_output_enabled_next_sample_tick;
|
||||
end
|
||||
|
||||
if (playback_active && decoder_idle && !decoder_idle_q && audiomap_active) begin
|
||||
audiomap_finished_playback <= 1;
|
||||
if (audio_fifo_output_enabled && decoder_idle && !decoder_idle_q) begin
|
||||
finished_buffer_playback_latched <= 1;
|
||||
end
|
||||
|
||||
if (finished_buffer_playback || stop_playback) begin
|
||||
finished_buffer_playback_latched <= 0;
|
||||
end
|
||||
|
||||
if (xa_fifo_out[0].write == 0 && xa_fifo_out[0].write == 0) begin
|
||||
playback_active <= 0;
|
||||
playback_active_next_sample_tick <= 0;
|
||||
audio_fifo_output_enabled <= 0;
|
||||
audio_fifo_output_enabled_next_sample_tick <= 0;
|
||||
end
|
||||
|
||||
if (playback_active) begin
|
||||
if (audio_fifo_output_enabled) begin
|
||||
if (strobe_fifo) begin
|
||||
xa_fifo_out[0].strobe <= 1;
|
||||
xa_fifo_out[1].strobe <= 1;
|
||||
|
||||
122
rtl/cdic.sv
122
rtl/cdic.sv
@@ -61,18 +61,16 @@ module cdic (
|
||||
bit [31:0] channel_register = 0;
|
||||
|
||||
// MODE2 Channel Audio Mask
|
||||
// If matching, disables audiomap and plays sector
|
||||
// directly without waiting for CPU?
|
||||
// The data is delivered to one of the ADPCM buffers?
|
||||
// If matching, the data is delivered to one of the ADPCM buffers
|
||||
bit [15:0] audio_channel_register = 0;
|
||||
|
||||
bit [15:0] command_register = 0;
|
||||
|
||||
// DBUF @ 303FFE
|
||||
// Bit 0 is toggled on every received sector
|
||||
// Bit 0 is toggled on every received sector and
|
||||
// points to the just refreshed buffer
|
||||
// Bit 2 is reset on data sector
|
||||
// Bit 2 is set on audio sector
|
||||
// Bit 14 is set on every received sector
|
||||
// Bit 15 starts the CD reading and parses command register
|
||||
// Resetting Bit 14 stops CD reading
|
||||
// Buffer of the stored sector is visible here
|
||||
@@ -94,6 +92,7 @@ module cdic (
|
||||
// ABUF @ 303FF4
|
||||
// Bit 15 causes IRQ
|
||||
// Bit 15 is set when an audio buffer was played
|
||||
// when bit 13 of AUDCTL is set
|
||||
// Reading register clears bit 15 after the read
|
||||
// The CPU still gets the set bit
|
||||
bit [15:0] audio_buffer_register = 0;
|
||||
@@ -108,17 +107,12 @@ module cdic (
|
||||
bit [15:0] dma_control_register = 0;
|
||||
|
||||
// AUDCTL @ 303FFA (called Z buffer in MAME)
|
||||
// Bit 0 toggles on every read when no audio is played?
|
||||
// The toggled result is the one returned
|
||||
// to the CPU?
|
||||
// Resetting bit 13 stops audio map playback? Or is it bit 11?
|
||||
// Bit 0 is set when the audiomap has finished playback
|
||||
// with 0xff coding
|
||||
// Resetting bit 11 stops audio map playback directly.
|
||||
// CPU does write 0x0000 to do so, ignoring the previous content
|
||||
// Setting bit 13 starts audio map playback? Or is it bit 11?
|
||||
// CPU does write 0x2800 to do so, ignoring the previous content
|
||||
// CPU writes 0x0800 to this register when unmuting
|
||||
// It does so only if bit 11 is not set but bit 0 is set
|
||||
// after a CDIC IRQ
|
||||
// This is also the address for playback of audio
|
||||
// Setting bit 11 starts audio map playback at ADPCM buffer 0
|
||||
// Bit 13 activates IRQs when a single ADPCM buffer was played
|
||||
bit [15:0] audio_control_register = 0;
|
||||
|
||||
// Matching value for File in MODE2 header
|
||||
@@ -153,6 +147,11 @@ module cdic (
|
||||
wire sector_tick_audio = sector75counter == 0;
|
||||
wire sample_tick37 /*verilator public_flat_rd*/;
|
||||
wire sample_tick44 /*verilator public_flat_rd*/;
|
||||
|
||||
`ifdef VERILATOR
|
||||
wire sample_tick /*verilator public_flat_rd*/ = read_cdda ? sample_tick44 : sample_tick37;
|
||||
`endif
|
||||
|
||||
wire sector_tick;
|
||||
flag_cross_domain cross1 (
|
||||
.clk_a(clk_audio),
|
||||
@@ -237,16 +236,6 @@ module cdic (
|
||||
.q_b(mem_cdic_readout)
|
||||
);
|
||||
|
||||
// Flag is set after a full sector is received
|
||||
// which had audio data and matching audio channel and
|
||||
// needs to be played back now
|
||||
bit cd_audio_start_playback;
|
||||
bit cd_audio_abort_playback_request;
|
||||
|
||||
// Address of CD sector to play back
|
||||
// Should be 13'h1900 or 13'h1400
|
||||
// Can be either an audiomap or coming directly from CD
|
||||
bit [12:0] audio_playback_addr;
|
||||
|
||||
bit [12:0] mem_cd_audio_addr; // Address for CDIC memory
|
||||
bit mem_cd_audio_rd;
|
||||
@@ -272,18 +261,16 @@ module cdic (
|
||||
assign audio_left = adpcm_left;
|
||||
assign audio_right = adpcm_right;
|
||||
|
||||
wire audiomap_active;
|
||||
bit adpcm_enable_audiomap; // Flag when audio_control_register[13] is set
|
||||
bit adpcm_disable_audiomap; // Flag when audio_control_register[13] is reset
|
||||
wire audiomap_finished_playback;
|
||||
bit audio_start_playback /*verilator public_flat_rd*/;
|
||||
bit audio_stop_playback;
|
||||
wire audio_playback_active /*verilator public_flat_rd*/;
|
||||
wire finished_audio_buffer_playback;
|
||||
wire decoder_disable_audiomap;
|
||||
|
||||
header_coding_s cd_audio_coding;
|
||||
audioplayer adpcm (
|
||||
.clk(clk),
|
||||
.sample_tick37,
|
||||
.sample_tick44,
|
||||
.audio_tick(sector_tick),
|
||||
.reset(reset),
|
||||
.mem_addr(mem_cd_audio_addr),
|
||||
.mem_data(mem_cdic_readout),
|
||||
@@ -291,14 +278,11 @@ module cdic (
|
||||
.mem_ack(mem_cd_audio_ack),
|
||||
.mem_ack_q(mem_cd_audio_ack_q),
|
||||
|
||||
.cd_audio_coding(cd_audio_coding),
|
||||
.start_playback(cd_audio_start_playback),
|
||||
.abort_playback_request(cd_audio_abort_playback_request),
|
||||
.enable_audiomap(adpcm_enable_audiomap),
|
||||
.disable_audiomap(adpcm_disable_audiomap),
|
||||
.playback_addr(audio_playback_addr),
|
||||
.audiomap_active(audiomap_active),
|
||||
.audiomap_finished_playback(audiomap_finished_playback),
|
||||
.start_playback(audio_start_playback),
|
||||
.stop_playback(audio_stop_playback),
|
||||
.cdda_mode(read_cdda),
|
||||
.playback_active(audio_playback_active),
|
||||
.finished_buffer_playback(finished_audio_buffer_playback),
|
||||
.decoder_disable_audiomap(decoder_disable_audiomap),
|
||||
|
||||
.audio_left (adpcm_left),
|
||||
@@ -310,28 +294,6 @@ module cdic (
|
||||
bit data_target_buffer;
|
||||
bit audio_target_buffer;
|
||||
|
||||
always_comb begin
|
||||
`ifdef VERILATOR
|
||||
audio_playback_addr = 0; // better visibility in waveform
|
||||
`else
|
||||
audio_playback_addr = audio_control_register[13:1]; // optimize LUTs
|
||||
`endif
|
||||
|
||||
if (adpcm_enable_audiomap) audio_playback_addr = audio_control_register[13:1];
|
||||
|
||||
// CD Audio Playback
|
||||
if (cd_audio_start_playback) begin
|
||||
if (header_mode2) begin
|
||||
audio_playback_addr = !audio_target_buffer ? 13'h1900 : 13'h1400;
|
||||
$display("ADPCM at %x", {audio_playback_addr, 1'b0});
|
||||
end else begin
|
||||
assert (read_cdda);
|
||||
audio_playback_addr = data_target_buffer ? 13'h0f00 : 13'h0a00;
|
||||
$display("CDDA at %x", {audio_playback_addr, 1'b0});
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
bit reset_write_timecode1;
|
||||
bit reset_write_timecode2;
|
||||
bit write_timecode1 = 0;
|
||||
@@ -424,7 +386,8 @@ module cdic (
|
||||
localparam bit [5:0] kSeekTime = 1;
|
||||
`else
|
||||
// Seeking on a real 210/05 takes about 200ms
|
||||
localparam bit [5:0] kSeekTime = 14;
|
||||
// But 19 (250ms) seems to be more stable
|
||||
localparam bit [5:0] kSeekTime = 19;
|
||||
`endif
|
||||
// Simulates reading time. Remaining sectors to wait.
|
||||
bit [5:0] start_cd_reading_cnt = 0;
|
||||
@@ -445,7 +408,7 @@ module cdic (
|
||||
end
|
||||
`endif
|
||||
|
||||
assign intreq = x_buffer_register[15] | audio_buffer_register[15];
|
||||
assign intreq = (x_buffer_register[15] & data_buffer_register[14]) | audio_buffer_register[15];
|
||||
assign req = dma_control_register[15];
|
||||
|
||||
localparam kSectorHeader_Mode = 15 / 2; // Low Byte
|
||||
@@ -459,14 +422,12 @@ module cdic (
|
||||
always_ff @(posedge clk) begin
|
||||
bus_ack <= 0;
|
||||
rdy <= 0;
|
||||
cd_audio_start_playback <= 0;
|
||||
cd_audio_abort_playback_request <= 0;
|
||||
cd_hps_data_valid_q2 <= cd_hps_data_valid_q;
|
||||
cd_hps_data_valid_q <= cd_hps_data_valid;
|
||||
cd_hps_ack_q <= cd_hps_ack;
|
||||
|
||||
adpcm_enable_audiomap <= 0;
|
||||
adpcm_disable_audiomap <= 0;
|
||||
audio_start_playback <= 0;
|
||||
audio_stop_playback <= 0;
|
||||
|
||||
if (reset_write_timecode1) write_timecode1 <= 0;
|
||||
if (reset_write_timecode2) write_timecode2 <= 0;
|
||||
@@ -615,7 +576,6 @@ module cdic (
|
||||
header_timecode1[7:0], header_timecode2[15:8]);
|
||||
|
||||
cd_data_target_adr <= audio_target_buffer ? 13'h1904 : 13'h1404;
|
||||
cd_audio_coding <= header_coding;
|
||||
end else if (use_sector_data && sector_word_index == 10 && !read_raw) begin
|
||||
$display("Use sector %x %x %x for data in buffer %x", header_timecode1[15:8],
|
||||
header_timecode1[7:0], header_timecode2[15:8], {
|
||||
@@ -636,7 +596,7 @@ module cdic (
|
||||
end
|
||||
|
||||
// Audio map finished? Cause an IRQ to inform the CPU
|
||||
if (audiomap_finished_playback) begin
|
||||
if (finished_audio_buffer_playback && audio_control_register[13]) begin
|
||||
audio_buffer_register[15] <= 1;
|
||||
end
|
||||
|
||||
@@ -700,9 +660,6 @@ module cdic (
|
||||
// Bit 2 is set on audio sector
|
||||
data_buffer_register[2] <= header_submode.audio && audio_channel_match && header_mode2;
|
||||
|
||||
// Bit 14 is set on every received sector
|
||||
data_buffer_register[14] <= 1'b1;
|
||||
|
||||
// Bit 15 is set when a sector is stored
|
||||
// This causes an IRQ to occur
|
||||
x_buffer_register[15] <= 1'b1;
|
||||
@@ -713,19 +670,9 @@ module cdic (
|
||||
cd_reading_active <= 0;
|
||||
|
||||
if (header_submode.audio && audio_channel_match && header_mode2) begin
|
||||
cd_audio_start_playback <= 1;
|
||||
// Resetting this bit, causes the CDIC driver to unmute the mixer
|
||||
audio_control_register[11] <= 0;
|
||||
data_buffer_register[0] <= audio_target_buffer;
|
||||
audio_target_buffer <= !audio_target_buffer;
|
||||
end
|
||||
|
||||
if (read_cdda) begin
|
||||
cd_audio_start_playback <= 1;
|
||||
cd_audio_coding.rate <= k44Khz;
|
||||
cd_audio_coding.bps <= k16Bps;
|
||||
cd_audio_coding.chan <= kStereo;
|
||||
end
|
||||
end
|
||||
|
||||
// Request the next sector from HPS if the last one
|
||||
@@ -754,8 +701,8 @@ module cdic (
|
||||
read_mode2 <= 1;
|
||||
end
|
||||
16'h2b: begin
|
||||
$display("CDIC Command: Stop CDDA");
|
||||
cd_reading_active <= 0;
|
||||
// Unknown purpose
|
||||
$display("CDIC Command: Stop CDDA?");
|
||||
end
|
||||
16'h2e: begin
|
||||
$display("CDIC Command: Update");
|
||||
@@ -884,9 +831,8 @@ module cdic (
|
||||
$display("CDIC Write Z Buffer Register / Audio Control Register %x %x",
|
||||
address[13:1], din);
|
||||
audio_control_register <= din;
|
||||
|
||||
adpcm_enable_audiomap <= din[13];
|
||||
adpcm_disable_audiomap <= din == 0;
|
||||
audio_start_playback <= din[11];
|
||||
audio_stop_playback <= !din[11];
|
||||
end
|
||||
13'h1FFE: begin // 0x3FFC IVEC Interrupt Vector register
|
||||
$display("CDIC Write Interrupt Vector Register %x %x", address[13:1],
|
||||
@@ -912,7 +858,6 @@ module cdic (
|
||||
audio_control_register[0] <= 0;
|
||||
sector_word_index <= 0;
|
||||
start_cd_reading_cnt <= 0;
|
||||
cd_audio_abort_playback_request <= 1;
|
||||
end
|
||||
end
|
||||
default: begin
|
||||
@@ -1013,6 +958,7 @@ module cdic (
|
||||
end
|
||||
13'h1FFD: begin // 0x3FFA AUDCTL Audio control register
|
||||
dout = audio_control_register;
|
||||
dout[11] = audio_playback_active;
|
||||
end
|
||||
13'h1FFE: begin // 0x3FFC IVEC Interrupt Vector register
|
||||
dout = interrupt_vector_register;
|
||||
|
||||
@@ -268,10 +268,10 @@ module cditop (
|
||||
.uds(uds),
|
||||
.bus_ack(bus_ack),
|
||||
.bus_err,
|
||||
.int1(vdsc_int),
|
||||
.int1(vdsc_int), // Video IRQ
|
||||
.int2(1'b0), // unconnected in CDi MONO1
|
||||
.in2(!in2in), // TODO fix polarity
|
||||
.in4(in4in),
|
||||
.in2(in2in), // Slave IRQ
|
||||
.in4(in4in), // CDIC IRQ
|
||||
.in5(1'b0),
|
||||
.iack2(iack2),
|
||||
.iack4(iack4),
|
||||
@@ -345,7 +345,9 @@ module cditop (
|
||||
|
||||
wire dtackslaven = ddrb[6] ? portb_out[6] : 1'b1;
|
||||
assign slave_rts = ddrb[4] ? portb_out[4] : 1'b1;
|
||||
assign in2in = ddrb[5] ? portb_out[5] : 1'b1;
|
||||
|
||||
// The polarity must be altered as a real SCC68070 is low active
|
||||
assign in2in = !(ddrb[5] ? portb_out[5] : 1'b1);
|
||||
|
||||
wire datadac = ddrb[0] ? portb_out[0] : 1'b0;
|
||||
wire clkdac = ddrb[1] ? portb_out[1] : 1'b0;
|
||||
@@ -353,7 +355,7 @@ module cditop (
|
||||
wire csdac2n = ddrb[3] ? portb_out[3] : 1'b1;
|
||||
|
||||
bit dtackslaven_q = 0;
|
||||
bit in2in_q = 1;
|
||||
bit in2in_q = 0;
|
||||
|
||||
bit slave_irq;
|
||||
|
||||
@@ -431,14 +433,14 @@ module cditop (
|
||||
if (reset) begin
|
||||
attex_cs_slave_q <= 0;
|
||||
dtackslaven_q <= 0;
|
||||
in2in_q <= 1;
|
||||
in2in_q <= 0;
|
||||
end else begin
|
||||
attex_cs_slave_q <= attex_cs_slave;
|
||||
dtackslaven_q <= dtackslaven;
|
||||
in2in_q <= in2in;
|
||||
|
||||
if (!in2in && in2in_q) $display("SLAVE IRQ2 1");
|
||||
if (in2in && !in2in_q) $display("SLAVE IRQ2 0");
|
||||
if (!in2in && in2in_q) $display("SLAVE IRQ2 0");
|
||||
if (in2in && !in2in_q) $display("SLAVE IRQ2 1");
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
2
sim2/.gitignore
vendored
2
sim2/.gitignore
vendored
@@ -5,3 +5,5 @@ log*
|
||||
*.BIN
|
||||
*.rom
|
||||
|
||||
*.wav
|
||||
*.vcd
|
||||
|
||||
@@ -34,14 +34,14 @@ play_audiomap:
|
||||
jsr waitforirq
|
||||
move.b #'A',$80002019
|
||||
move.w #$8a00,d0
|
||||
move.w #$b200,d1
|
||||
move.w #$a800,d1 ; 0x2800
|
||||
jsr movedata
|
||||
|
||||
move.b #'1',$80002019
|
||||
jsr waitforirq
|
||||
move.b #'B',$80002019
|
||||
move.w #$8000,d0
|
||||
move.w #$a800,d1
|
||||
move.w #$b200,d1; 0x3200
|
||||
jsr movedata
|
||||
|
||||
jsr waitforirq
|
||||
@@ -79,10 +79,15 @@ play_some_cd_sectors:
|
||||
; Wait for the music to play back some sectors
|
||||
|
||||
jsr waitforirq
|
||||
|
||||
move.w #$0800,$303FFA ; Start playback
|
||||
|
||||
jsr waitforirq
|
||||
jsr waitforirq
|
||||
|
||||
move.w #$0000,$303FFE ; Stop CD reading
|
||||
move.w #$0000,$303FFA ; Stop playback
|
||||
|
||||
rts
|
||||
|
||||
main:
|
||||
@@ -176,7 +181,7 @@ movedata:
|
||||
move.w $303200,d7
|
||||
move.w $303202,d7
|
||||
|
||||
move.w #$3200,$303FFA ; Start Audiomap at 0x3200
|
||||
move.w #$2800,$303FFA ; Start Audiomap at 0x2800
|
||||
rts
|
||||
|
||||
wait:
|
||||
|
||||
@@ -17,6 +17,8 @@ main:
|
||||
|
||||
move.w #$2480,$303FFC ; Interrupt Vector
|
||||
move.w #$0028,$303C00 ; Play CDDA
|
||||
;move.w #$0027,$303C00 ; Fetch TOC
|
||||
|
||||
; Apprentice - Level 1
|
||||
move.l #$19468000,$303C02 ; Timer Register
|
||||
|
||||
@@ -26,6 +28,9 @@ main:
|
||||
move.w #$C000,$303FFE ; Start the Read by setting bit 15 of the data buffer
|
||||
|
||||
jsr waitforirq
|
||||
|
||||
move.w #$0800,$303FFA ; Start playback
|
||||
|
||||
jsr waitforirq
|
||||
jsr waitforirq
|
||||
jsr waitforirq
|
||||
|
||||
@@ -34,6 +34,12 @@ main:
|
||||
move.w #$4000,$303C0C ; Audio Channel Register
|
||||
move.l #$07494800,$303C02 ; Timer Register
|
||||
|
||||
; Apprentice USA Philips Logo
|
||||
move.w #$0000,$303C06 ; File Register
|
||||
move.l #$8000,$303C08 ; Channel Register
|
||||
move.w #$8000,$303C0C ; Audio Channel Register
|
||||
move.l #$12215300,$303C02 ; Timer Register
|
||||
|
||||
; Tetris 00 35 68 00356800 Philips Logo Coding 01, 2 channels, 4 bits, 000093a8 frequency
|
||||
; Tetris 01 42 67 01426700 Main Menu Coding 05, 2 channels, 4 bits, 000049d4 frequency
|
||||
; Tetris 55 50 33 55503300 Intro Coding 05, 2 channels, 4 bits, 000049d4 frequency
|
||||
@@ -44,11 +50,17 @@ main:
|
||||
move.w #$C000,$303FFE ; Start the Read by setting bit 15 of the data buffer
|
||||
|
||||
jsr waitforirq
|
||||
|
||||
move.w #$0800,$303FFA ; Start playback
|
||||
|
||||
jsr waitforirq
|
||||
jsr waitforirq
|
||||
jsr waitforirq
|
||||
jsr waitforirq
|
||||
|
||||
move.w #$0000,$303FFA ; Stop playback
|
||||
|
||||
|
||||
;move.w #$0000,$303FFE ; Deactivate cd reading
|
||||
|
||||
endless:
|
||||
|
||||
4
sim2/create_wav.sh
Executable file
4
sim2/create_wav.sh
Executable file
@@ -0,0 +1,4 @@
|
||||
sox -M \
|
||||
-r 37800 -e signed-integer -b 16 -c 1 -t raw $1/audio_left.bin \
|
||||
-r 37800 -e signed-integer -b 16 -c 1 -t raw $1/audio_right.bin \
|
||||
$1_audio.wav
|
||||
@@ -9,12 +9,13 @@ vasmm68k_mot -Fbin -m68000 byte_word_test.asm -o byte_word_test.rom
|
||||
vasmm68k_mot -Fbin -m68000 slavetest.asm -o slavetest.rom
|
||||
vasmm68k_mot -Fbin -m68000 cdic_audiomap.asm -o cdic_audiomap.rom
|
||||
vasmm68k_mot -Fbin -m68000 cdic_cdda_play.asm -o cdic_cdda_play.rom
|
||||
vasmm68k_mot -Fbin -m68000 cdic_xa_play.asm -o cdic_xa_play.rom
|
||||
vasmm68k_mot -Fbin -m68000 cdic_data.asm -o cdic_data.rom
|
||||
vasmm68k_mot -Fbin -m68000 uarttest.asm -o uarttest.rom
|
||||
vasmm68k_mot -Fbin -m68000 nvram_backup_restore.asm -o nvram_backup_restore.rom
|
||||
vasmm68k_mot -Fbin -m68000 nvramsender.asm -o nvramsender.rom
|
||||
vasmm68k_mot -Fbin -m68000 cdic_sector_send.asm -o cdic_sector_send.rom
|
||||
|
||||
xxd -p -c2 cdic_cdda_play.rom cdi200.mem
|
||||
xxd -p -c2 cdic_xa_play.rom cdi200.mem
|
||||
xxd -p -c1 ../sim/cdimono1/zx405042p__cdi_slave_2.0__b43t__zzmk9213.mc68hc705c8a_withtestrom.7206 slave.mem
|
||||
#dd if=/dev/urandom of=save.bin count=16
|
||||
|
||||
121
sim2/sim_top.cpp
121
sim2/sim_top.cpp
@@ -130,8 +130,10 @@ void subcode_data(int lba, struct subcode &out) {
|
||||
s = fake_lba / 75;
|
||||
f = fake_lba % 75;
|
||||
|
||||
if (lba < toc_entry_count) {
|
||||
auto &toc_entry = toc_buffer[lba];
|
||||
int toc_entry_index = lba + 0x10000;
|
||||
if (lba < 0 && toc_entry_index < toc_entry_count) {
|
||||
|
||||
auto &toc_entry = toc_buffer[toc_entry_index];
|
||||
|
||||
out.control = htons(toc_entry.control);
|
||||
out.track = 0; // Track 0 for TOC
|
||||
@@ -146,8 +148,8 @@ void subcode_data(int lba, struct subcode &out) {
|
||||
out.mode1_crc0 = htons(0xff);
|
||||
out.mode1_crc1 = htons(0xff);
|
||||
|
||||
// printf("toc lba=%d %02x %02x %02x %02x %02x\n", lba, out.control, out.index, out.mode1_amins,
|
||||
// out.mode1_asecs, out.mode1_afrac);
|
||||
// printf("toc lba=%d %02x %02x %02x %02x %02x\n", toc_entry_index, out.control, out.index, out.mode1_amins,
|
||||
// out.mode1_asecs, out.mode1_afrac);
|
||||
} else {
|
||||
int track = 1;
|
||||
out.control = htons(0x01);
|
||||
@@ -266,7 +268,6 @@ class CDi {
|
||||
}
|
||||
|
||||
void clock() {
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
dut.rootp->emu__DOT__clk_sys = (sim_time & 1);
|
||||
dut.rootp->emu__DOT__clk_audio = (sim_time & 1);
|
||||
@@ -584,7 +585,7 @@ class CDi {
|
||||
}
|
||||
|
||||
// Simulate Audio
|
||||
if (dut.rootp->emu__DOT__cditop__DOT__cdic_inst__DOT__sample_tick44) {
|
||||
if (dut.rootp->emu__DOT__cditop__DOT__cdic_inst__DOT__sample_tick) {
|
||||
int16_t sample_l = dut.rootp->emu__DOT__cditop__DOT__cdic_inst__DOT__adpcm__DOT__fifo_out_left;
|
||||
int16_t sample_r = dut.rootp->emu__DOT__cditop__DOT__cdic_inst__DOT__adpcm__DOT__fifo_out_right;
|
||||
fwrite(&sample_l, 2, 1, f_audio_left);
|
||||
@@ -629,7 +630,7 @@ class CDi {
|
||||
}
|
||||
|
||||
dut.eval();
|
||||
// do_trace = false;
|
||||
do_trace = false;
|
||||
dut.rootp->emu__DOT__debug_uart_fake_space = false;
|
||||
dut.rootp->emu__DOT__img_size = 4096;
|
||||
|
||||
@@ -688,6 +689,86 @@ class CDi {
|
||||
}
|
||||
};
|
||||
|
||||
void prepare_apprentice_usa_toc() {
|
||||
toc_buffer[0] = {1, 1, 21, 34, 1};
|
||||
toc_buffer[1] = {1, 1, 21, 34, 0};
|
||||
toc_buffer[2] = {1, 1, 21, 34, 34};
|
||||
toc_buffer[3] = {1, 2, 25, 68, 21};
|
||||
toc_buffer[4] = {1, 2, 25, 68, 2};
|
||||
toc_buffer[5] = {1, 2, 25, 68, 1};
|
||||
toc_buffer[6] = {1, 3, 35, 85, 0};
|
||||
toc_buffer[7] = {1, 3, 35, 85, 68};
|
||||
toc_buffer[8] = {1, 3, 35, 85, 35};
|
||||
toc_buffer[9] = {1, 4, 36, 86, 3};
|
||||
toc_buffer[10] = {1, 4, 36, 86, 1};
|
||||
toc_buffer[11] = {1, 4, 36, 86, 0};
|
||||
toc_buffer[12] = {1, 5, 41, 66, 86};
|
||||
toc_buffer[13] = {1, 5, 41, 66, 36};
|
||||
toc_buffer[14] = {1, 5, 41, 66, 4};
|
||||
toc_buffer[15] = {1, 6, 48, 67, 1};
|
||||
toc_buffer[16] = {1, 6, 48, 67, 0};
|
||||
toc_buffer[17] = {1, 6, 48, 67, 66};
|
||||
toc_buffer[18] = {1, 7, 53, 49, 41};
|
||||
toc_buffer[19] = {1, 7, 53, 49, 6};
|
||||
toc_buffer[20] = {1, 7, 53, 49, 1};
|
||||
toc_buffer[21] = {1, 8, 54, 55, 0};
|
||||
toc_buffer[22] = {1, 8, 54, 55, 67};
|
||||
toc_buffer[23] = {1, 8, 54, 55, 53};
|
||||
toc_buffer[24] = {1, 9, 65, 18, 7};
|
||||
toc_buffer[25] = {1, 9, 65, 18, 1};
|
||||
toc_buffer[26] = {1, 9, 65, 18, 0};
|
||||
toc_buffer[27] = {1, 16, 66, 21, 55};
|
||||
toc_buffer[28] = {1, 16, 66, 21, 54};
|
||||
toc_buffer[29] = {1, 16, 66, 21, 8};
|
||||
toc_buffer[30] = {1, 17, 70, 37, 1};
|
||||
toc_buffer[31] = {1, 17, 70, 37, 0};
|
||||
toc_buffer[32] = {1, 17, 70, 37, 18};
|
||||
toc_buffer[33] = {1, 18, 71, 32, 65};
|
||||
toc_buffer[34] = {1, 18, 71, 32, 16};
|
||||
toc_buffer[35] = {1, 18, 71, 32, 1};
|
||||
toc_buffer[36] = {1, 19, 81, 54, 0};
|
||||
toc_buffer[37] = {1, 19, 81, 54, 21};
|
||||
toc_buffer[38] = {1, 19, 81, 54, 70};
|
||||
toc_buffer[39] = {1, 20, 82, 54, 17};
|
||||
toc_buffer[40] = {1, 20, 82, 54, 1};
|
||||
toc_buffer[41] = {1, 20, 82, 54, 0};
|
||||
toc_buffer[42] = {1, 21, 83, 69, 32};
|
||||
toc_buffer[43] = {1, 21, 83, 69, 71};
|
||||
toc_buffer[44] = {1, 21, 83, 69, 18};
|
||||
toc_buffer[45] = {1, 22, 86, 85, 1};
|
||||
toc_buffer[46] = {1, 22, 86, 85, 0};
|
||||
toc_buffer[47] = {1, 22, 86, 85, 54};
|
||||
toc_buffer[48] = {1, 23, 87, 5, 81};
|
||||
toc_buffer[49] = {1, 23, 87, 5, 20};
|
||||
toc_buffer[50] = {1, 23, 87, 5, 1};
|
||||
toc_buffer[51] = {1, 24, 89, 2, 0};
|
||||
toc_buffer[52] = {1, 24, 89, 2, 54};
|
||||
toc_buffer[53] = {1, 24, 89, 2, 83};
|
||||
toc_buffer[54] = {1, 25, 89, 37, 21};
|
||||
toc_buffer[55] = {1, 25, 89, 37, 1};
|
||||
toc_buffer[56] = {1, 25, 89, 37, 0};
|
||||
toc_buffer[57] = {1, 32, 96, 0, 85};
|
||||
toc_buffer[58] = {1, 32, 96, 0, 86};
|
||||
toc_buffer[59] = {1, 32, 96, 0, 22};
|
||||
toc_buffer[60] = {1, 33, 96, 34, 1};
|
||||
toc_buffer[61] = {1, 33, 96, 34, 0};
|
||||
toc_buffer[62] = {1, 33, 96, 34, 5};
|
||||
toc_buffer[63] = {1, 34, 96, 87, 87};
|
||||
toc_buffer[64] = {1, 34, 96, 87, 24};
|
||||
toc_buffer[65] = {1, 34, 96, 87, 1};
|
||||
toc_buffer[66] = {1, 160, 1, 0, 0};
|
||||
toc_buffer[67] = {1, 160, 1, 0, 2};
|
||||
toc_buffer[68] = {1, 160, 1, 0, 89};
|
||||
toc_buffer[69] = {1, 161, 34, 0, 25};
|
||||
toc_buffer[70] = {1, 161, 34, 0, 1};
|
||||
toc_buffer[71] = {1, 161, 34, 0, 0};
|
||||
toc_buffer[72] = {1, 162, 21, 34, 0};
|
||||
toc_buffer[73] = {1, 162, 21, 34, 96};
|
||||
toc_buffer[74] = {1, 162, 21, 34, 32};
|
||||
|
||||
toc_entry_count = 75;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
// Initialize Verilators variables
|
||||
Verilated::commandArgs(argc, argv);
|
||||
@@ -727,39 +808,19 @@ int main(int argc, char **argv) {
|
||||
f_cd_bin = fopen("images/Zelda's Adventure (Europe).bin", "rb");
|
||||
break;
|
||||
case 6:
|
||||
f_cd_bin = fopen("images/tetris.bin", "rb");
|
||||
f_cd_bin = fopen("images/audiocd.bin", "rb");
|
||||
break;
|
||||
case 7:
|
||||
f_cd_bin = fopen("images/Flashback (Europe).bin", "rb");
|
||||
break;
|
||||
case 8:
|
||||
f_cd_bin = fopen("images/Earth Command (Germany).bin", "rb");
|
||||
f_cd_bin = fopen("images/Apprentice_USA_single.bin", "rb");
|
||||
prepare_apprentice_usa_toc();
|
||||
break;
|
||||
}
|
||||
|
||||
assert(f_cd_bin);
|
||||
|
||||
toc_buffer[0] = {1, 1, 0, 0, 0};
|
||||
toc_buffer[1] = {1, 1, 0, 0, 0};
|
||||
toc_buffer[2] = {1, 1, 0, 0, 0};
|
||||
toc_buffer[3] = {1, 2, 3, 38, 69};
|
||||
toc_buffer[4] = {1, 2, 3, 38, 69};
|
||||
toc_buffer[5] = {1, 2, 3, 38, 69};
|
||||
toc_buffer[6] = {1, 3, 7, 1, 96};
|
||||
toc_buffer[7] = {1, 3, 7, 1, 96};
|
||||
toc_buffer[8] = {1, 3, 7, 1, 96};
|
||||
toc_buffer[9] = {1, 4, 18, 16, 71};
|
||||
toc_buffer[10] = {1, 4, 18, 16, 71};
|
||||
toc_buffer[11] = {1, 4, 18, 16, 71};
|
||||
toc_buffer[12] = {1, 160, 1, 0, 0};
|
||||
toc_buffer[13] = {1, 160, 1, 0, 0};
|
||||
toc_buffer[14] = {1, 160, 1, 0, 0};
|
||||
toc_buffer[15] = {1, 161, 4, 0, 0};
|
||||
toc_buffer[16] = {1, 161, 4, 0, 0};
|
||||
toc_buffer[17] = {1, 161, 4, 0, 0};
|
||||
toc_buffer[18] = {1, 162, 0, 0, 0};
|
||||
toc_entry_count=19;
|
||||
|
||||
CDi machine(machineindex);
|
||||
|
||||
while (status == 0) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
verilator --top-module emu \
|
||||
--trace --trace-fst --trace-structs --cc --assert --exe --timing --build \
|
||||
--trace --trace-fst --trace-structs --cc --assert --exe --build \
|
||||
--build-jobs 8 sim_top.cpp -I../rtl \
|
||||
../rtl/*.sv ../CDi.sv ../rtl/*.v \
|
||||
tg68kdotc_verilog_wrapper.v ur6805.v \
|
||||
|
||||
Reference in New Issue
Block a user