diff --git a/Makefile b/Makefile index 2254f7a..145eee5 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,9 @@ -all: +all: $(patsubst %.cpp,%.elf,$(wildcard example/*.cpp)) + +phony: + +example/arm/%.bin: phony + make -C example/arm $*.bin include common.mk @@ -7,3 +12,5 @@ geometry/%.hpp: geometry/%.obj mv $@.tmp $@ include example/example.mk + +.PHONY: phony diff --git a/base.mk b/base.mk index f28e5a6..2b555ea 100644 --- a/base.mk +++ b/base.mk @@ -4,7 +4,8 @@ AFLAGS += --fatal-warnings CFLAGS += -falign-functions=4 -ffunction-sections -fdata-sections -fshort-enums -ffreestanding -nostdlib CFLAGS += -Wall -Werror -Wfatal-errors -CFLAGS += -Wno-error=narrowing -Wno-error=unused-variable -Wno-error=array-bounds= -Wno-array-bounds +CFLAGS += -Wno-array-bounds +#CFLAGS += -Wno-error=narrowing -Wno-error=unused-variable -Wno-error=array-bounds= CXXFLAGS += -fno-exceptions -fno-non-call-exceptions -fno-rtti -fno-threadsafe-statics diff --git a/common.mk b/common.mk index 4e7986e..6dba415 100644 --- a/common.mk +++ b/common.mk @@ -79,7 +79,9 @@ sine.pcm: common.mk /1ST_READ.BIN=./$< \ /=./COPYRIGH.TXT \ /=./ABSTRACT.TXT \ - /=./BIBLIOGR.TXT + /=./BIBLIOGR.TXT \ + /DUNE.PCM=./dune.pcm \ + /REIGN.PCM=./reign.pcm %.cdi: %.iso ./cdi4dc $< $@ >/dev/null diff --git a/example/aica_gdrom.cpp b/example/aica_gdrom.cpp index 803a672..dc8232e 100644 --- a/example/aica_gdrom.cpp +++ b/example/aica_gdrom.cpp @@ -1,4 +1,6 @@ #include "memorymap.hpp" +#include "sh7091/sh7091.hpp" +#include "sh7091/sh7091_bits.hpp" #include "sh7091/serial.hpp" #include "systembus.hpp" #include "systembus_bits.hpp" @@ -73,6 +75,10 @@ void aica_init(uint32_t& chunk_index, const uint32_t * src_chunk) chunk_index = (chunk_index + 1) % 2; aica_wait_write(); aica_sound.common.vreg_armrst = aica::vreg_armrst::ARMRST(0); + + { // send arm interrupt + aica_sound.common.scipd = scipd__arm_interrupt; + } } void aica_step(uint32_t& chunk_index, const uint32_t * src_chunk) @@ -83,6 +89,8 @@ void aica_step(uint32_t& chunk_index, const uint32_t * src_chunk) aica_wait_write(); aica_sound.common.mcire = mcipd__sh4_interrupt; } + const uint32_t step_start = sh7091.TMU.TCNT0; + { // fill the requested chunk aica_fill_chunk(&(*chunk)[chunk_index][0], src_chunk, @@ -90,6 +98,16 @@ void aica_step(uint32_t& chunk_index, const uint32_t * src_chunk) chunk_index = (chunk_index + 1) % 2; } + + { // send arm interrupt + aica_sound.common.scipd = scipd__arm_interrupt; + } + + + const uint32_t step_end = sh7091.TMU.TCNT0; + const uint32_t step_time = step_start - step_end; + serial::string("step: "); + serial::integer(step_time); } // gdrom @@ -175,19 +193,21 @@ uint32_t gdrom_cd_read2(uint16_t * buf, //serial::integer(next_address); gdrom_pio_data(packet._data()); + while ((gdrom::status::bsy(gdrom_if.status)) != 0); // wait for drive to become not-busy + uint32_t length = 0; while ((gdrom::status::drq(gdrom_if.status)) != 0) { const uint32_t byte_count = gdrom_if.byte_count(); length += byte_count; gdrom_read_data(buf, byte_count); - serial::string("read status: "); + serial::string("status: "); serial::integer(gdrom_if.status); while ((gdrom::status::bsy(gdrom_if.status)) != 0); // wait for drive to become not-busy } - serial::string("read length: "); + serial::string("length: "); serial::integer(length); return length; } @@ -237,11 +257,11 @@ struct extent gdrom_find_file() const uint32_t primary_volume_descriptor = fad + 16; uint16_t buf[2048 / 2]; - const uint32_t length0 = gdrom_cd_read2(buf, - primary_volume_descriptor, // starting address - 1, // one sector; 2048 bytes - primary_volume_descriptor + 1 // next address - ); + gdrom_cd_read2(buf, + primary_volume_descriptor, // starting address + 1, // one sector; 2048 bytes + primary_volume_descriptor + 1 // next address + ); serial::character('\n'); auto pvd = reinterpret_cast(&buf[0]); @@ -260,11 +280,11 @@ struct extent gdrom_find_file() serial::character('\n'); const uint32_t root_directory_extent = root_dr->location_of_extent.get(); - const uint32_t length1 = gdrom_cd_read2(buf, - root_directory_extent + 150, // 150? - 1, // one sector; 2048 bytes - root_directory_extent + 151 // 150? - ); + gdrom_cd_read2(buf, + root_directory_extent + 150, // 150? + 1, // one sector; 2048 bytes + root_directory_extent + 151 // 150? + ); serial::character('\n'); auto buf8 = reinterpret_cast(buf); @@ -311,11 +331,18 @@ struct extent gdrom_find_file() void gdrom_read_chunk(uint32_t * buf, const uint32_t extent, const uint32_t num_extents) { - const uint32_t length1 = gdrom_cd_read2(reinterpret_cast(buf), - extent + 150, // 150? - num_extents, // one sector; 2048 bytes - extent + 150 + num_extents // 150? - ); + const uint32_t gdrom_start = sh7091.TMU.TCNT0; + + gdrom_cd_read2(reinterpret_cast(buf), + extent + 150, // 150? + num_extents, // one sector; 2048 bytes + extent + 150 + num_extents // 150? + ); + + const uint32_t gdrom_end = sh7091.TMU.TCNT0; + const uint32_t gdrom_time = gdrom_start - gdrom_end; + serial::string("time: "); + serial::integer(gdrom_time); } void next_segment(const struct extent& extent, uint32_t& segment_index) @@ -327,6 +354,13 @@ void next_segment(const struct extent& extent, uint32_t& segment_index) void main() { + sh7091.TMU.TSTR = 0; // stop all timers + sh7091.TMU.TOCR = tmu::tocr::tcoe::tclk_is_external_clock_or_input_capture; + sh7091.TMU.TCR0 = tmu::tcr0::tpsc::p_phi_256; // 256 / 50MHz = 5.12 μs ; underflows in ~1 hour + sh7091.TMU.TCOR0 = 0xffff'ffff; + sh7091.TMU.TCNT0 = 0xffff'ffff; + sh7091.TMU.TSTR = tmu::tstr::str0::counter_start; + uint32_t chunk_index = 0; uint32_t segment_index = 0; @@ -338,13 +372,12 @@ void main() aica_init(chunk_index, &gdrom_buf[0]); - serial::string("aica wave memory:\n"); - while (aica_wave_memory[0] == 0xeaffffff) { aica_wait_read(); }; - aica_wait_read(); serial::integer(aica_wave_memory[0]); - aica_wait_read(); serial::integer(aica_wave_memory[1]); + //serial::string("aica wave memory:\n"); + //while (aica_wave_memory[0] == 0xeaffffff) { aica_wait_read(); }; + //aica_wait_read(); serial::integer(aica_wave_memory[0]); + //aica_wait_read(); serial::integer(aica_wave_memory[1]); while (1) { - //serial::integer(chunk_index); gdrom_read_chunk(gdrom_buf, extent.location + segment_index, sectors_per_chunk); next_segment(extent, segment_index); diff --git a/example/arm/sh4_interrupt.cpp b/example/arm/sh4_interrupt.cpp index 04cb4ad..66c3703 100644 --- a/example/arm/sh4_interrupt.cpp +++ b/example/arm/sh4_interrupt.cpp @@ -39,20 +39,25 @@ void main() aica_sound.channel[0].LPCTL(1); aica_sound.channel[0].PCMS(0); aica_sound.channel[0].LSA(0); - aica_sound.channel[0].LEA(chunk_size / 2); + aica_sound.channel[0].LEA((chunk_size / 2) * 2); aica_sound.channel[0].D2R(0x0); aica_sound.channel[0].D1R(0x0); - aica_sound.channel[0].RR(0x0); + aica_sound.channel[0].RR(0x1f); aica_sound.channel[0].AR(0x1f); - aica_sound.channel[0].OCT(0); - aica_sound.channel[0].FNS(0); + aica_sound.channel[0].OCT(0xf); + aica_sound.channel[0].FNS(0x7d); aica_sound.channel[0].DISDL(0xf); aica_sound.channel[0].DIPAN(0x0); aica_sound.channel[0].Q(0b00100); aica_sound.channel[0].TL(0); - aica_sound.channel[0].LPOFF(1); + aica_sound.channel[0].LPOFF(0); + aica_sound.channel[0].FLV0(0x1ff8); + aica_sound.channel[0].FLV1(0x1ff8); + aica_sound.channel[0].FLV2(0x1ff8); + aica_sound.channel[0].FLV3(0x1ff8); + aica_sound.channel[0].FLV4(0x1ff8); aica_sound.common.mono_mem8mb_dac18b_ver_mvol = aica::mono_mem8mb_dac18b_ver_mvol::MONO(0) // enable panpots @@ -61,33 +66,51 @@ void main() | aica::mono_mem8mb_dac18b_ver_mvol::MVOL(0xf) // 15/15 volume ; - constexpr uint32_t tactl = 7; // increment once every 1 samples - constexpr uint32_t tima = 256 - 128; // interrupt after 128 samples + //constexpr uint32_t tactl = 6; // increment once every 1 samples + //constexpr uint32_t tima = 0; // interrupt after 128 samples dram[0] = reinterpret_cast(&chunk[0][0]); dram[1] = reinterpret_cast(&chunk[1][0]); - uint32_t next_chunk = 0; - aica_sound.channel[0].SA(reinterpret_cast(&chunk[next_chunk][0])); + aica_sound.channel[0].SA(reinterpret_cast(&chunk[0][0])); aica_sound.channel[0].KYONEX(1); - next_chunk = (next_chunk + 1) % 2; - request_chunk(); - constexpr uint32_t timer_a_interrupt = (1 << 6); - aica_sound.common.tactl_tima = aica::tactl_tima::TACTL(tactl) - | aica::tactl_tima::TIMA(tima); - aica_sound.common.scire = timer_a_interrupt; + //constexpr uint32_t scipd__arm_interrupt = (1 << 5); + //constexpr uint32_t timer_a_interrupt = (1 << 6); + + uint8_t next_chunk = 1; - uint32_t sample = 0; while (1) { - if (aica_sound.common.SCIPD() & timer_a_interrupt) { + // detect buffer underrun + /* + if (!(aica_sound.common.SCIPD() & scipd__arm_interrupt)) { + //aica_sound.channel[0].KYONB(0); + aica_sound.channel[0].KYONEX(1); + while (!(aica_sound.common.SCIPD() & scipd__arm_interrupt)); + aica_sound.channel[0].KYONB(1); aica_sound.channel[0].SA(reinterpret_cast(&chunk[next_chunk][0])); - aica_sound.common.tactl_tima = aica::tactl_tima::TACTL(tactl) - | aica::tactl_tima::TIMA(tima); - next_chunk = (next_chunk + 1) % 2; - request_chunk(); + aica_sound.channel[0].KYONEX(1); + aica_sound.channel[0].SA(reinterpret_cast(&chunk[0][0])); + } + aica_sound.common.scire = scipd__arm_interrupt; + */ - aica_sound.common.scire = timer_a_interrupt; + next_chunk = !next_chunk; + request_chunk(); + + uint32_t sample = 0; + const uint32_t target = 16384 + (16384 * 10 / 12); + constexpr uint32_t sample_interval = (1 << 10); + while (sample < target) { + //aica_sound.common.tactl_tima = aica::tactl_tima::TACTL(tactl) + // | aica::tactl_tima::TIMA(tima); + + //while (!(aica_sound.common.SCIPD() & timer_a_interrupt)); + //aica_sound.common.scire = timer_a_interrupt; + while (!(aica_sound.common.SCIPD() & sample_interval)); + aica_sound.common.scire = sample_interval; + + sample++; } } } diff --git a/example/dump_ram.cpp b/example/dump_ram.cpp index 985e78f..2eacbd0 100644 --- a/example/dump_ram.cpp +++ b/example/dump_ram.cpp @@ -7,7 +7,7 @@ void dump_ram(const volatile uint32_t * mem, const uint32_t len) { uint32_t sum = 0; - for (uint32_t i = 0; i < ; i++) { + for (uint32_t i = 0; i < len; i++) { uint8_t n = mem[i]; sum += n; serial::hexlify(n); diff --git a/example/gdrom_iso9660.cpp b/example/gdrom_iso9660.cpp index e03e5cd..5998d06 100644 --- a/example/gdrom_iso9660.cpp +++ b/example/gdrom_iso9660.cpp @@ -116,10 +116,10 @@ void main() const uint32_t primary_volume_descriptor = fad + 16; uint16_t buf[2048 / 2]; - const uint32_t length0 = cd_read(buf, - primary_volume_descriptor, - 1 // one sector; 2048 bytes - ); + cd_read(buf, + primary_volume_descriptor, + 1 // one sector; 2048 bytes + ); serial::character('\n'); auto pvd = reinterpret_cast(&buf[0]); @@ -148,10 +148,10 @@ void main() serial::character('\n'); const uint32_t root_directory_extent = root_dr->location_of_extent.get(); - const uint32_t length1 = cd_read(buf, - root_directory_extent + 150, // 150? - 1 // one sector; 2048 bytes - ); + cd_read(buf, + root_directory_extent + 150, // 150? + 1 // one sector; 2048 bytes + ); serial::character('\n'); auto buf8 = reinterpret_cast(buf); @@ -182,10 +182,10 @@ void main() const uint32_t extent = dr->location_of_extent.get(); uint16_t buf2[2048 / 2]; - const uint32_t length1 = cd_read(buf2, - extent + 150, // 150? - 1 // one sector; 2048 bytes - ); + cd_read(buf2, + extent + 150, // 150? + 1 // one sector; 2048 bytes + ); auto file = reinterpret_cast(&buf2[0]); serial::string("---begin file content---\n"); diff --git a/example/gdrom_test.cpp b/example/gdrom_test.cpp index 26dc028..9f92f19 100644 --- a/example/gdrom_test.cpp +++ b/example/gdrom_test.cpp @@ -60,9 +60,9 @@ void pio_data(const uint8_t * data) serial::string("status2: "); serial::integer(gdrom_if.status); - serial::string("byte_control: "); - serial::integer(gdrom_if.byte_control_high, ' '); - serial::integer(gdrom_if.byte_control_low); + serial::string("byte_count: "); + serial::integer(gdrom_if.byte_count_high, ' '); + serial::integer(gdrom_if.byte_count_low); } void read_data(uint32_t length) @@ -148,7 +148,7 @@ void get_toc() serial::string("\nget_toc\n"); pio_data(data); - const uint32_t length = (gdrom_if.byte_control_high << 8) | (gdrom_if.byte_control_low << 0); + const uint32_t length = (gdrom_if.byte_count_high << 8) | (gdrom_if.byte_count_low << 0); // 102 entries ; 4 bytes per entry, 408 bytes (0x0198) read_data(length); } @@ -210,14 +210,14 @@ void cd_read2() serial::string("offset: "); serial::integer(read); - const uint32_t length = (gdrom_if.byte_control_high << 8) | (gdrom_if.byte_control_low << 0); + const uint32_t length = (gdrom_if.byte_count_high << 8) | (gdrom_if.byte_count_low << 0); // 102 entries ; 4 bytes per entry, 408 bytes (0x0198) read_data(length); read += length; - serial::string("byte_control: "); - serial::integer(gdrom_if.byte_control_high, ' '); - serial::integer(gdrom_if.byte_control_low); + serial::string("byte_count: "); + serial::integer(gdrom_if.byte_count_high, ' '); + serial::integer(gdrom_if.byte_count_low); } serial::string("read bytes: "); serial::integer(read); diff --git a/example/interrupt.cpp b/example/interrupt.cpp index 29c9e0f..ca2756b 100644 --- a/example/interrupt.cpp +++ b/example/interrupt.cpp @@ -1,9 +1,9 @@ #include -#include "serial.hpp" +#include "sh7091/serial.hpp" -#include "sh7095.hpp" -#include "sh7095_bits.hpp" +#include "sh7091/sh7091.hpp" +#include "sh7091/sh7091_bits.hpp" void main() { diff --git a/example/maple_controller.cpp b/example/maple_controller.cpp index 3d02c66..78f277f 100644 --- a/example/maple_controller.cpp +++ b/example/maple_controller.cpp @@ -1,8 +1,9 @@ #include -#include "holly/video_output.hpp" #include "align.hpp" - +#include "holly/video_output.hpp" +#include "holly/core_bits.hpp" +#include "holly/holly.hpp" #include "maple/maple.hpp" #include "maple/maple_impl.hpp" #include "maple/maple_bus_bits.hpp" @@ -85,8 +86,8 @@ void do_device_request() receive_buf, maple::sizeof_command(host_response)); for (uint8_t port = 0; port < 4; port++) { - auto& bus_data = response[port].bus_data; - auto& data_fields = response[port].bus_data.data_fields; + auto& bus_data = host_response[port].bus_data; + auto& data_fields = host_response[port].bus_data.data_fields; if (bus_data.command_code != device_status::command_code) { // the controller is disconnected } else { @@ -110,7 +111,8 @@ void main() video_output::set_mode_vga(); while (1) { - v_sync_in(); + while (!spg_status::vsync(holly.SPG_STATUS)); + while (spg_status::vsync(holly.SPG_STATUS)); do_device_request(); }; } diff --git a/example/maple_device_request.cpp b/example/maple_device_request.cpp index 15826c2..9781b9c 100644 --- a/example/maple_device_request.cpp +++ b/example/maple_device_request.cpp @@ -29,7 +29,7 @@ void main() serial::integer(port); for (uint32_t i = 0; i < host_response_size; i++) { - serial::integer(buf[port * command_response_size + i]); + serial::integer(buf[port * host_response_size + i]); } serial::character('\n'); } diff --git a/example/maple_vibrator.cpp b/example/maple_vibrator.cpp index 16f2d34..c86f8f9 100644 --- a/example/maple_vibrator.cpp +++ b/example/maple_vibrator.cpp @@ -1,8 +1,9 @@ #include -#include "holly/video_output.hpp" #include "align.hpp" - +#include "holly/video_output.hpp" +#include "holly/core_bits.hpp" +#include "holly/holly.hpp" #include "maple/maple.hpp" #include "maple/maple_impl.hpp" #include "maple/maple_bus_bits.hpp" @@ -188,8 +189,8 @@ void main() while (1) { for (int i = 0; i < 120; i++) { - v_sync_out(); - v_sync_in(); + while (!spg_status::vsync(holly.SPG_STATUS)); + while (spg_status::vsync(holly.SPG_STATUS)); } do_device_request(); }; diff --git a/example/sprite.cpp b/example/sprite.cpp index aca0ab2..8670980 100644 --- a/example/sprite.cpp +++ b/example/sprite.cpp @@ -114,8 +114,6 @@ void main() , .punch_through = 0 }; - constexpr uint32_t tiles = (640 / 32) * (480 / 32); - holly.SOFTRESET = softreset::pipeline_soft_reset | softreset::ta_soft_reset; holly.SOFTRESET = 0; diff --git a/holly/core.cpp b/holly/core.cpp index d54a911..65e35d0 100644 --- a/holly/core.cpp +++ b/holly/core.cpp @@ -82,8 +82,6 @@ void core_start_render(uint32_t frame_ix, uint32_t num_frames) frame_ix, num_frames); } -static bool flycast_bug = 0; - void core_wait_end_of_render_video() { /*