From 26e94d295720112c3ad7bc679fcf35e6e37a73d7 Mon Sep 17 00:00:00 2001 From: hkz Date: Mon, 13 Oct 2025 11:43:41 +0200 Subject: [PATCH] Begin wiring in the VDP code in the game module --- Makefile | 4 +- src/game_vdp_graphics.h | 8 +++ src/game_vdp_graphics.s | 6 +++ src/mem_registers.h | 99 +++++++++++++++++----------------- src/vdgam_main.c | 114 ++++++++++++++++++++++++++-------------- 5 files changed, 142 insertions(+), 89 deletions(-) diff --git a/Makefile b/Makefile index 90a6e45..85761ea 100644 --- a/Makefile +++ b/Makefile @@ -41,8 +41,8 @@ VDPIN_C_SRCS = vdpin_main.c utility.c VDDLG_ASM_SRCS = tk2k_startup_module.s preserve_zero_pages.s sound.s vdp.s vdp_utils.s game_vdp_graphics.s VDDLG_C_SRCS = vddlg_main.c input.c utility.c -VDGAM_ASM_SRCS = tk2k_startup_module.s preserve_zero_pages.s input_asm.s sound.s -VDGAM_C_SRCS = vdgam_main.c input.c utility.c game_hgr_graphics.c hgr_line_data.c game_logic.c arrows_pic.c tiles.c hgr_graph_misc_data.c +VDGAM_ASM_SRCS = tk2k_startup_module.s preserve_zero_pages.s input_asm.s sound.s vdp.s vdp_utils.s game_vdp_graphics.s +VDGAM_C_SRCS = vdgam_main.c input.c utility.c game_logic.c VDDEM_ASM_SRCS = tk2k_startup_module.s preserve_zero_pages.s input_asm.s sound.s VDDEM_C_SRCS = vddem_main.c input.c utility.c game_hgr_graphics_demo.c hgr_line_data.c game_logic.c arrows_pic.c tiles.c hgr_graph_misc_data.c diff --git a/src/game_vdp_graphics.h b/src/game_vdp_graphics.h index 7aa3be8..e659301 100644 --- a/src/game_vdp_graphics.h +++ b/src/game_vdp_graphics.h @@ -3,9 +3,17 @@ #include +#define JS_POS_CENTER 0 +#define JS_POS_UP 1 +#define JS_POS_DOWN 2 +#define JS_POS_LEFT 3 +#define JS_POS_RIGHT 4 + + void vdp_clear_gamegrid(void); void vdp_clear_dialog(void); uint8_t vdp_draw_numtile(uint8_t type, uint8_t x, uint8_t y); +void vdp_redraw_tiles(void); void vdp_draw_joystick(uint8_t position); #endif /* _GAME_VDP_GRAPHICS_HEADER_ */ diff --git a/src/game_vdp_graphics.s b/src/game_vdp_graphics.s index 9fb8d17..1825f93 100644 --- a/src/game_vdp_graphics.s +++ b/src/game_vdp_graphics.s @@ -10,6 +10,10 @@ NUM_TILE_OFFSET: .equ 0x14 .section code,text +vdp_redraw_tiles: + ;;; TODO + rts + vdp_draw_joystick: T_NT_IDX$: .equ _Zp+4 P_POS$: .equ _Zp+2 @@ -235,4 +239,6 @@ TileNum_Y_Map: .public vdp_draw_numtile .public vdp_clear_gamegrid .public vdp_clear_dialog + .public vdp_redraw_tiles + .public vdp_draw_joystick \ No newline at end of file diff --git a/src/mem_registers.h b/src/mem_registers.h index 5ca2394..5c11921 100644 --- a/src/mem_registers.h +++ b/src/mem_registers.h @@ -1,48 +1,51 @@ -#ifndef _MEM_REGISTERS_HEADER_ -#define _MEM_REGISTERS_HEADER_ - -#include - -#define ROM_MONITOR 0xFF61 - -#define ZP_WNDLFT 0x0020 // 0, left column of scroll window -#define ZP_WNDWDTH 0x0021 // 40, width of scroll window -#define ZP_WNDTOP 0x0022 // 0, top line of the scroll window -#define ZP_WNDBTM 0x0023 // 24, bottom line of the scroll window - -#define ZP_CH 0x0024 // Displacement from window left for the cursor -#define ZP_CV 0x0025 // Displacement from top of screen (not window!) for the cursor - -#define ZP_INVFLAG 0x0032 // Either 0x00 or 0x7F, set text color inversion -#define ZP_PROMPT 0x0033 // Prompt character - -#define ZP_RND 0x004E // Note that this is a 16bit register incremented by the RDKEY func - -#define P3_PWRDUP_REF 0x03F3 -#define P3_PWRDUP 0x03F4 // Already-powered-up indicator. If it is set to the content of 0x03F3 XOR'd with 0xA5, the soft reset vector is considered valid - - -#define DATAIN_KB_MASK 0x3F -#define DATAIN_PRNT_MASK 0x40 -#define DATAIN_TAPEIN_MASK 0x80 - -#define IO_DATAOUT 0xC000 // (W) To keyboard and printer port -#define IO_DATAIN 0xC010 // (R) Data input from keyboard (0:5), printer (6) and tape (7) -#define IO_TAPEOUT 0xC020 // (R) Data output for tape, read from here to output bit on tape -#define IO_SPEAKER 0xC030 // (R) Speaker toggle -#define IO_DISPLAY_COLOR 0xC050 // (R / W) Access here to enable the colorburst -#define IO_DISPLAY_BW 0xC051 // (R / W) Access here to disable the colorburst -#define IO_MTA_OFF 0xC052 // (?) -#define IO_MTA_ON 0xC053 // (?) -#define IO_DISPLAY_PAGE1 0xC054 // (R / W) Access here to select the primary display page -#define IO_DISPLAY_PAGE2 0xC055 // (R / W) Access here to select the secondary display page -#define IO_MTB_OFF 0xC056 // (?) -#define IO_MTB_ON 0xC057 // (?) -#define IO_PRNT_STRB_LO 0xC058 // (R / W) Access LO/HI/LO or HI/LO/HI consecutively depending on the type of strobe pulse to create -#define IO_PRNT_STRB_HI 0xC059 // (R / W) -#define IO_ROMSEL 0xC05A // (R / W) Access here will make region C100-FFFF a ROM area -#define IO_RAMSEL 0xC05B // (R / W) Access here will make region C100-FFFF a RAM area -#define IO_KB_CTRL_LOW 0xC05E // (R / W) Set the CTRL line to 0, access is through DATAIN -#define IO_KB_CTRL_HI 0xC05F // (R / W) Set the CTRL line to 1 - -#endif /* _MEM_REGISTERS_HEADER_ */ +#ifndef _MEM_REGISTERS_HEADER_ +#define _MEM_REGISTERS_HEADER_ + +#include + +#define NMI_HANDLER_ADDRESS 0x03FB +#define IRQ_HANDLER_ADDRESS 0x03FE + +#define ROM_MONITOR 0xFF61 + +#define ZP_WNDLFT 0x0020 // 0, left column of scroll window +#define ZP_WNDWDTH 0x0021 // 40, width of scroll window +#define ZP_WNDTOP 0x0022 // 0, top line of the scroll window +#define ZP_WNDBTM 0x0023 // 24, bottom line of the scroll window + +#define ZP_CH 0x0024 // Displacement from window left for the cursor +#define ZP_CV 0x0025 // Displacement from top of screen (not window!) for the cursor + +#define ZP_INVFLAG 0x0032 // Either 0x00 or 0x7F, set text color inversion +#define ZP_PROMPT 0x0033 // Prompt character + +#define ZP_RND 0x004E // Note that this is a 16bit register incremented by the RDKEY func + +#define P3_PWRDUP_REF 0x03F3 +#define P3_PWRDUP 0x03F4 // Already-powered-up indicator. If it is set to the content of 0x03F3 XOR'd with 0xA5, the soft reset vector is considered valid + + +#define DATAIN_KB_MASK 0x3F +#define DATAIN_PRNT_MASK 0x40 +#define DATAIN_TAPEIN_MASK 0x80 + +#define IO_DATAOUT 0xC000 // (W) To keyboard and printer port +#define IO_DATAIN 0xC010 // (R) Data input from keyboard (0:5), printer (6) and tape (7) +#define IO_TAPEOUT 0xC020 // (R) Data output for tape, read from here to output bit on tape +#define IO_SPEAKER 0xC030 // (R) Speaker toggle +#define IO_DISPLAY_COLOR 0xC050 // (R / W) Access here to enable the colorburst +#define IO_DISPLAY_BW 0xC051 // (R / W) Access here to disable the colorburst +#define IO_MTA_OFF 0xC052 // (?) +#define IO_MTA_ON 0xC053 // (?) +#define IO_DISPLAY_PAGE1 0xC054 // (R / W) Access here to select the primary display page +#define IO_DISPLAY_PAGE2 0xC055 // (R / W) Access here to select the secondary display page +#define IO_MTB_OFF 0xC056 // (?) +#define IO_MTB_ON 0xC057 // (?) +#define IO_PRNT_STRB_LO 0xC058 // (R / W) Access LO/HI/LO or HI/LO/HI consecutively depending on the type of strobe pulse to create +#define IO_PRNT_STRB_HI 0xC059 // (R / W) +#define IO_ROMSEL 0xC05A // (R / W) Access here will make region C100-FFFF a ROM area +#define IO_RAMSEL 0xC05B // (R / W) Access here will make region C100-FFFF a RAM area +#define IO_KB_CTRL_LOW 0xC05E // (R / W) Set the CTRL line to 0, access is through DATAIN +#define IO_KB_CTRL_HI 0xC05F // (R / W) Set the CTRL line to 1 + +#endif /* _MEM_REGISTERS_HEADER_ */ diff --git a/src/vdgam_main.c b/src/vdgam_main.c index 2ae6867..f4ea8da 100644 --- a/src/vdgam_main.c +++ b/src/vdgam_main.c @@ -3,16 +3,19 @@ #include +#include "vdp_utils.h" +#include "game_vdp_graphics.h" + #include "monitor_subroutines.h" #include "utility.h" #include "mem_map.h" +#include "mem_registers.h" #include "shared_page.h" #include "state_page.h" #include "dlog_data.h" #include "game_data.h" #include "input.h" #include "game_logic.h" -#include "game_hgr_graphics.h" #include "monitor_subroutines.h" #include "sound.h" #include "module_list.h" @@ -21,36 +24,41 @@ #pragma require __preserve_zp #pragma require __data_initialization_needed -#define MOVES_TEXT_X 32 -#define MOVES_TEXT_Y 61 -#define MOVES_TEXT_WIDTH 5 +#define HSCORE_TEXT_X 27 +#define HSCORE_TEXT_Y 13 -#define SCORE_TEXT_X 32 -#define SCORE_TEXT_Y 29 -#define SCORE_TEXT_WIDTH 5 +#define SCORE_TEXT_X 27 +#define SCORE_TEXT_Y 8 -#define HIGH_TEXT_X 32 -#define HIGH_TEXT_Y 107 +#define MOVES_TEXT_X 27 +#define MOVES_TEXT_Y 4 #define WIN_SCORE_BONUS 10000 static state_page_data* state_page = (state_page_data*)STATE_PAGE; static shared_page_data *shared_page = (shared_page_data*)SHARED_PAGE; +static uint8_t text_buf[7] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; void main(void) { uint16_t moves_count = 0; uint16_t score = 0; int8_t done = 0; + __disable_interrupts(); // Make sure the interrupts are disabled + // By default, once we return from this, return to the DLOG module and give the master no command to execute shared_page->master_command = MASTER_COMMAND_NONE; - shared_page->next_module_idx = MODULE_DLOG; // Go to the DLOG module + shared_page->next_module_idx = MODULE_DLOG_VDP; // Go to the dialog module dlog_data *dld = (dlog_data *)(shared_page->module_data); dlog_data *gad = (dlog_data *)(shared_page->module_data); // Make sure the buffers are pointing to the correct memory and are clear - clear_display_buffers(); + vdp_clear_gamegrid(); + vdp_switch_nt(0); // Make sure VDP shows the gamegrid + + // Setup the IRQ handler + POKEW(IRQ_HANDLER_ADDRESS, (uint16_t)vdp_irq_handler); // Reset the game, calculate the initial score depending on which tiles we randomly get score = reset_game(); @@ -68,37 +76,59 @@ void main(void) { } // Draw the initial state of the game - draw_game_background(state_page->hi_score); - draw_number(moves_count, MOVES_TEXT_WIDTH, MOVES_TEXT_X, MOVES_TEXT_Y); - draw_number(score, SCORE_TEXT_WIDTH, SCORE_TEXT_X, SCORE_TEXT_Y); - draw_tiles(); + num_to_decbuf(state_page->hi_score, 6, text_buf); // High score + decbuf_to_ascii(6, text_buf); + vdp_print_string(0, HSCORE_TEXT_X, HSCORE_TEXT_Y, (char*)text_buf); + + num_to_decbuf(moves_count, 6, text_buf); // Moves count + decbuf_to_ascii(6, text_buf); + vdp_print_string(0, MOVES_TEXT_X, MOVES_TEXT_Y, (char*)text_buf); + + num_to_decbuf(score, 6, text_buf); // Score + decbuf_to_ascii(6, text_buf); + vdp_print_string(0, SCORE_TEXT_X, SCORE_TEXT_Y, (char*)text_buf); + + vdp_draw_joystick(JS_POS_CENTER); // Center the joystick + + vdp_redraw_tiles(); - // Swap graphical buffers - swap_display_buffers(); + __enable_interrupts(); while(1) { // Game loop lfsr_update(); + __disable_interrupts(); + vdp_draw_joystick(JS_POS_CENTER); + __enable_interrupts(); + switch(read_kb()) { case K_UP: SND_TAP(); done = step_game(GAME_STEP_UP); - ddraw_direction_arrows(GRAPH_ARROW_UP); + __disable_interrupts(); + vdp_draw_joystick(JS_POS_UP); + __enable_interrupts(); break; case K_DOWN: SND_TAP(); done = step_game(GAME_STEP_DOWN); - ddraw_direction_arrows(GRAPH_ARROW_DOWN); + __disable_interrupts(); + vdp_draw_joystick(JS_POS_DOWN); + __enable_interrupts(); break; case K_LEFT: SND_TAP(); done = step_game(GAME_STEP_LEFT); - ddraw_direction_arrows(GRAPH_ARROW_LEFT); + __disable_interrupts(); + vdp_draw_joystick(JS_POS_LEFT); + __enable_interrupts(); break; case K_RIGHT: SND_TAP(); done = step_game(GAME_STEP_RIGHT); - ddraw_direction_arrows(GRAPH_ARROW_RIGHT); + __disable_interrupts(); + vdp_draw_joystick(JS_POS_RIGHT); + __enable_interrupts(); break; case K_CTRL_R: snd_mod_button(); @@ -112,9 +142,9 @@ void main(void) { shared_page->master_command = MASTER_COMMAND_SAVE; case K_CTRL_L: snd_mod_button(); - sync_display1_buffer(); shared_page->next_module_idx = MODULE_GAME; gad->mode = GAME_MODE_LOAD; + __disable_interrupts(); return; default: continue; // Do nothing, loop again @@ -123,17 +153,22 @@ void main(void) { // Increase the count of moves we made (unless we lost or reset the game) if(done >= 0) moves_count++; - // Draw the number of moves - draw_number(moves_count, MOVES_TEXT_WIDTH, MOVES_TEXT_X, MOVES_TEXT_Y); - - // Draw the moved tiles - draw_tiles(); + num_to_decbuf(moves_count, 6, text_buf); // Moves count + decbuf_to_ascii(6, text_buf); + __disable_interrupts(); + vdp_print_string(0, MOVES_TEXT_X, MOVES_TEXT_Y, (char*)text_buf); + __enable_interrupts(); // If we have won, or we got a reset request, break out of this loop if(done) { score += (done > 0) ? WIN_SCORE_BONUS : 0; - draw_number(score, SCORE_TEXT_WIDTH, SCORE_TEXT_X, SCORE_TEXT_Y); - swap_display_buffers(); // Make sure we show the latest changes + + num_to_decbuf(score, 6, text_buf); // Score + decbuf_to_ascii(6, text_buf); + __disable_interrupts(); + vdp_print_string(0, SCORE_TEXT_X, SCORE_TEXT_Y, (char*)text_buf); + __enable_interrupts(); + break; } @@ -147,20 +182,21 @@ void main(void) { score = calculate_score(); // Draw the score - draw_number(score, SCORE_TEXT_WIDTH, SCORE_TEXT_X, SCORE_TEXT_Y); - - swap_display_buffers(); - - // Draw the new tile directly on the front buffer, this way we make it appear with an "animation" - ddraw_single_tile(random_tile_off - 1); + num_to_decbuf(score, 6, text_buf); // Score + decbuf_to_ascii(6, text_buf); + __disable_interrupts(); + vdp_print_string(0, SCORE_TEXT_X, SCORE_TEXT_Y, (char*)text_buf); + vdp_redraw_tiles(); + __enable_interrupts(); } - - // Sync the display buffers - sync_display1_buffer(); - + dld->mode = (done > 0) ? DLOG_MODE_WIN : DLOG_MODE_LOSE; dld->score = score; + __disable_interrupts(); + + // One last update to the tiles + vdp_redraw_tiles(); return; }