diff --git a/Makefile b/Makefile index 9794455..ea88ccd 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ CFLAGS = -Isaturn OPT ?= -Og LIB = ./saturn -SRC = main.o +SRC = main.o input.o DEP = $(patsubst %.o,%.d,$(SRC)) res = $(subst pokered/,res/,$(patsubst %.$(1),%.$(1).o,$(wildcard $(2)*.$(1)))) diff --git a/input.cpp b/input.cpp new file mode 100644 index 0000000..23d8050 --- /dev/null +++ b/input.cpp @@ -0,0 +1,73 @@ +#include + +#include "smpc.h" + +#include "input.hpp" +#include "common/intback.hpp" + +constexpr int input_arr = 10; +constexpr int input_das = 20; +constexpr int input_debounce = 2; + +static inline void +input_count(count_flop_t& button, const uint32_t input, const uint32_t mask) +{ + if ((input & mask) == 0) { + if (button.count < input_debounce) + button.count += 1; + else + button.das += 1; + } else { + if (button.count == 0) { + button.flop = 0; + button.das = 0; + button.repeat = 0; + } + else if (button.count > 0) + button.count -= 1; + } +} + +static inline int32_t +input_flopped(count_flop_t& button) +{ + if (button.count == input_debounce && button.flop == 0) { + button.flop = 1; + return 1; + } else if (button.flop == 1 && button.das == input_das && button.repeat == 0) { + button.repeat = 1; + button.das = 0; + return 2; + } else if (button.repeat == 1 && (button.das == input_arr)) { + button.das = 0; + return 2; + } else { + return 0; + } +} + +input_t input = { 0 }; + +void digital_callback(uint8_t fsm_state, uint8_t data) +{ + switch (fsm_state) { + case intback::DATA1: + input_count(input.right, data, DIGITAL__1__RIGHT); + input_count(input.left, data, DIGITAL__1__LEFT); + input_count(input.down, data, DIGITAL__1__DOWN); + input_count(input.up, data, DIGITAL__1__UP); + input_count(input.start, data, DIGITAL__1__START); + input_count(input.a, data, DIGITAL__1__A); + input_count(input.c, data, DIGITAL__1__C); + input_count(input.b, data, DIGITAL__1__B); + break; + case intback::DATA2: + input_count(input.r, data, DIGITAL__2__R); + input_count(input.x, data, DIGITAL__2__X); + input_count(input.y, data, DIGITAL__2__Y); + input_count(input.z, data, DIGITAL__2__Z); + input_count(input.l, data, DIGITAL__2__L); + break; + default: break; + } +} diff --git a/input.hpp b/input.hpp new file mode 100644 index 0000000..c2d7574 --- /dev/null +++ b/input.hpp @@ -0,0 +1,30 @@ +#pragma once + +#include + +struct count_flop_t { + int8_t count; + uint8_t flop; + uint8_t das; + uint8_t repeat; +}; + +struct input_t { + count_flop_t right; + count_flop_t left; + count_flop_t down; + count_flop_t up; + count_flop_t start; + count_flop_t a; + count_flop_t b; + count_flop_t c; + count_flop_t r; + count_flop_t x; + count_flop_t y; + count_flop_t z; + count_flop_t l; +}; + +void digital_callback(uint8_t fsm_state, uint8_t data); + +extern input_t input; diff --git a/main.cpp b/main.cpp index 586918d..782d576 100644 --- a/main.cpp +++ b/main.cpp @@ -1,11 +1,16 @@ #include #include "vdp2.h" +#include "scu.h" +#include "smpc.h" +#include "sh2.h" #include "common/copy.hpp" #include "common/vdp2_func.hpp" +#include "common/intback.hpp" #include "test.cpp" +#include "input.hpp" constexpr inline uint16_t rgb15(int32_t r, int32_t g, int32_t b) { @@ -88,6 +93,25 @@ void render(const uint32_t base_pattern) } } +static uint32_t base_pattern; + +extern "C" +void v_blank_in_int(void) __attribute__ ((interrupt_handler)); +void v_blank_in_int() +{ + render(base_pattern); +} + +extern "C" +void smpc_int(void) __attribute__ ((interrupt_handler)); +void smpc_int(void) +{ + scu.reg.IST &= ~(IST__SMPC); + scu.reg.IMS = ~(IMS__SMPC | IMS__V_BLANK_IN); + + intback::fsm(digital_callback, nullptr); +} + void main() { v_blank_in(); @@ -122,11 +146,6 @@ void main() constexpr int page_size = 64 * 64 * 2; // N0PNB__1WORD (16-bit) constexpr int plane_size = page_size * 1; - vdp2.reg.CYCA0 = 0xeeeeeeee; - vdp2.reg.CYCA1 = 0xeeeeeeee; - vdp2.reg.CYCB0 = 0xeeeeeeee; - vdp2.reg.CYCB1 = 0xeeeeeeee; - vdp2.reg.MPOFN = MPOFN__N0MP(0); // bits 8~6 vdp2.reg.MPABN0 = MPABN0__N0MPB(0) | MPABN0__N0MPA(plane_a); // bits 5~0 vdp2.reg.MPCDN0 = MPABN0__N0MPD(0) | MPABN0__N0MPC(0); // bits 5~0 @@ -134,16 +153,26 @@ void main() uint32_t top = (sizeof (union vdp2_vram)); palette_data(); uint32_t base_address = top = cell_data(tilesets[tileset_t::overworld].tileset, top); - uint32_t base_pattern = base_address / 32; + base_pattern = base_address / 32; /* use 1-word (16-bit) pattern names */ vdp2.reg.PNCN0 = PNCN0__N0PNB__1WORD | PNCN0__N0CNSM | PNCN0__N0SCN((base_pattern >> 10) & 0x1f); //vdp2.reg.PNCN0 = PNCN0__N0PNB__2WORD | PNCN0__N0CNSM; - render(base_pattern); - vdp2.reg.CYCA0 = 0x0fff'ffff; vdp2.reg.CYCA1 = 0xffff'ffff; vdp2.reg.CYCB0 = 0xffff'ffff; vdp2.reg.CYCB1 = 0x4fff'ffff; + + // initialize smpc + smpc.reg.DDR1 = 0; // INPUT + smpc.reg.DDR2 = 0; // INPUT + smpc.reg.IOSEL = 0; // SMPC control + smpc.reg.EXLE = 0; // + + sh2_vec[SCU_VEC__SMPC] = (u32)(&smpc_int); + sh2_vec[SCU_VEC__V_BLANK_IN] = (u32)(&v_blank_in_int); + + scu.reg.IST = 0; + scu.reg.IMS = ~(IMS__SMPC | IMS__V_BLANK_IN); }