mirror of
https://codeberg.org/hkzlab/TK2048.git
synced 2026-01-02 21:09:25 +11:00
Merged dii_refactoring, modularize code for 2.0
This commit is contained in:
parent
5d739383aa
commit
cfc455f1ca
37 changed files with 2101 additions and 249 deletions
185
src/master_main.c
Normal file
185
src/master_main.c
Normal file
|
|
@ -0,0 +1,185 @@
|
|||
#include <stubs.h>
|
||||
|
||||
#include <calypsi/intrinsics6502.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "shared_page.h"
|
||||
#include "state_page.h"
|
||||
#include "monitor_subroutines.h"
|
||||
#include "utility.h"
|
||||
#include "mem_map.h"
|
||||
#include "mem_registers.h"
|
||||
#include "disk2.h"
|
||||
#include "dos_floppy.h"
|
||||
|
||||
// External initialization requirements
|
||||
#pragma require __data_initialization_needed
|
||||
|
||||
// Require the exported function table to be present
|
||||
//#pragma require __exported_func_table
|
||||
|
||||
#define DEFAULT_DRIVE_CONTROLLER_OFFSET 0x10
|
||||
|
||||
static uint8_t *module_page = (uint8_t*)MODULE_PAGE;
|
||||
static shared_page_data * shared_page = (shared_page_data*)SHARED_PAGE;
|
||||
|
||||
#define FILE_LIST_LEN 5
|
||||
#define FNAME_LEN 6
|
||||
#define STATE_FILE_IDX 1
|
||||
|
||||
#define AUTOLOAD_FILES 3 // Autoload the first 3 files
|
||||
|
||||
// We'll limit ourselves to files with a name of max 5 chars, to save some memory
|
||||
static const uint8_t file_table[FILE_LIST_LEN][FNAME_LEN] = {
|
||||
{ 0x80 | 'L', 0x80 | 'O', 0x80 | 'A', 0x80 | 'D', 0x80 | 'S', 0x00}, // LOADS (this is not an executable, but will be used to show the loading screen).
|
||||
{ 0x80 | 'S', 0x80 | 'T', 0x80 | 'A', 0x80 | 'T', 0x80 | 'E', 0x00}, // STATE (this is not an executable, but will be used to save/load the game and scores).
|
||||
{ 0x80 | 'I', 0x80 | 'N', 0x80 | 'T', 0x80 | 'R', 0x80 | 'O', 0x00}, // INTRO (this executable will show the initial presentation picture)
|
||||
{ 0x80 | 'D', 0x80 | 'L', 0x80 | 'O', 0x80 | 'G', 0xA0, 0x00}, // DLOG (startup, win, lose dialogs)
|
||||
{ 0x80 | 'G', 0x80 | 'A', 0x80 | 'M', 0x80 | 'E', 0xA0, 0x00}, // GAME (the actual game)
|
||||
};
|
||||
|
||||
static uint8_t file_trksec[FILE_LIST_LEN][2]; // This will hold track/sector for initial ts list sector for every one of the listed files. Populated at startup.
|
||||
static uint16_t file_load_address[FILE_LIST_LEN] = { // This will hold the load address for the files
|
||||
DISPLAY_PAGE_1,
|
||||
STATE_PAGE,
|
||||
MODULE_PAGE,
|
||||
MODULE_PAGE,
|
||||
MODULE_PAGE,
|
||||
};
|
||||
|
||||
static void init(void);
|
||||
static void init_floppy_data(uint8_t *cur_trk, uint8_t *cur_file);
|
||||
static uint8_t fill_trksec_list(uint8_t* cur_trk);
|
||||
static uint8_t calculate_crc8(uint8_t* data, uint8_t len);
|
||||
|
||||
// Low level initialization
|
||||
static void init(void) {
|
||||
POKE(P3_PWRDUP, 0); // Dirty the value checked by the reset vector
|
||||
PEEK(IO_ROMSEL); // Make sure the ROM is selected
|
||||
PEEK(DISPLAY_PAGE_1); // Select display page 1
|
||||
PEEK(IO_DISPLAY_BW); // Disable colors
|
||||
|
||||
// Generate the decoding table
|
||||
dii_generate_6bit_decoding_mapping_table((uint8_t*)DECODING_MAPPING_TABLE_DEFAULT_ADDRESS);
|
||||
// Generate the encoding table
|
||||
dii_generate_6bit_encoding_mapping_table((uint8_t*)ENCODING_MAPPING_TABLE_DEFAULT_ADDRESS);
|
||||
}
|
||||
|
||||
static uint8_t fill_trksec_list(uint8_t* cur_trk) {
|
||||
uint8_t file_counter = 0;
|
||||
|
||||
for(uint8_t file_idx = 0; file_idx < FILE_LIST_LEN; file_idx++) {
|
||||
FDE* f_desc = df_search_file(DEFAULT_DRIVE_CONTROLLER_OFFSET, file_table[file_idx], cur_trk);
|
||||
if(f_desc) {
|
||||
file_trksec[file_idx][0] = f_desc->tsl_trk;
|
||||
file_trksec[file_idx][1] = f_desc->tsl_sec;
|
||||
|
||||
file_counter++;
|
||||
} else {
|
||||
file_trksec[file_idx][0] = 0;
|
||||
file_trksec[file_idx][1] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return file_counter;
|
||||
}
|
||||
|
||||
// Load the info we need from floppy
|
||||
static void init_floppy_data(uint8_t *cur_trk, uint8_t *cur_file) {
|
||||
uint8_t initialized_correctly = 0;
|
||||
|
||||
// Power on the drive and reset the head
|
||||
dii_power_on(DEFAULT_DRIVE_CONTROLLER_OFFSET, 0);
|
||||
dii_head_reposition(DEFAULT_DRIVE_CONTROLLER_OFFSET, 96, 0); // Head bang back to track 0!
|
||||
|
||||
|
||||
// Build a table that maps every file we're interested in to the track/sector of the first T/S list entry.
|
||||
initialized_correctly = fill_trksec_list(cur_trk) == FILE_LIST_LEN;
|
||||
|
||||
// Load the first files to autoload
|
||||
for(uint8_t file_num = 0; file_num < AUTOLOAD_FILES && initialized_correctly; file_num++) {
|
||||
initialized_correctly = df_read_file(DEFAULT_DRIVE_CONTROLLER_OFFSET, file_trksec[file_num][0], file_trksec[file_num][1], (uint8_t*)file_load_address[file_num], cur_trk) && initialized_correctly;
|
||||
*cur_file = file_num;
|
||||
shared_page->next_module_idx = file_num;
|
||||
}
|
||||
|
||||
// Power off
|
||||
dii_power_off(DEFAULT_DRIVE_CONTROLLER_OFFSET);
|
||||
|
||||
// Check the CRC for the state page
|
||||
uint8_t crc = calculate_crc8((uint8_t*)file_load_address[STATE_FILE_IDX], sizeof(state_page_data) - 1);
|
||||
if(((state_page_data*)file_load_address[STATE_FILE_IDX])->crc != crc) {
|
||||
memset(((void*)file_load_address[STATE_FILE_IDX]), 0, sizeof(state_page_data));
|
||||
}
|
||||
|
||||
// If something went wrong, trigger a break
|
||||
if (!initialized_correctly) __asm volatile(" brk\n":::);
|
||||
}
|
||||
|
||||
#define CRC8RDALLAS_POLY 0x31
|
||||
static uint8_t calculate_crc8(uint8_t* data, uint8_t len) {
|
||||
uint8_t crc = 0;
|
||||
|
||||
for(uint8_t data_idx = 0; data_idx < len; data_idx++) {
|
||||
uint8_t carry;
|
||||
uint8_t d = data[data_idx];
|
||||
|
||||
for (uint8_t i = 8; i > 0; i--) {
|
||||
carry = (crc & 0x80);
|
||||
crc <<= 1;
|
||||
if (d & 1) crc |= 1;
|
||||
d >>= 1;
|
||||
if (carry) crc ^= CRC8RDALLAS_POLY;
|
||||
}
|
||||
}
|
||||
|
||||
return crc;
|
||||
}
|
||||
|
||||
__task int main(void) {
|
||||
uint8_t cur_trk = 0;
|
||||
uint8_t cur_file = 0;
|
||||
uint8_t keep_going = 1;
|
||||
|
||||
__disable_interrupts();
|
||||
|
||||
init();
|
||||
init_floppy_data(&cur_trk, &cur_file);
|
||||
|
||||
__enable_interrupts();
|
||||
|
||||
|
||||
do {
|
||||
if((cur_file != shared_page->next_module_idx) || (shared_page->master_command == MASTER_COMMAND_SAVE)) {
|
||||
__disable_interrupts();
|
||||
dii_power_on(DEFAULT_DRIVE_CONTROLLER_OFFSET, 0);
|
||||
|
||||
// Check if we need to load another module
|
||||
if(cur_file != shared_page->next_module_idx) {
|
||||
cur_file = shared_page->next_module_idx;
|
||||
// Read the next module
|
||||
keep_going = df_read_file(DEFAULT_DRIVE_CONTROLLER_OFFSET, file_trksec[cur_file][0], file_trksec[cur_file][1], (uint8_t*)file_load_address[cur_file], &cur_trk);
|
||||
}
|
||||
|
||||
// Check if we need to save the state page
|
||||
if (shared_page->master_command == MASTER_COMMAND_SAVE) {
|
||||
uint8_t crc = calculate_crc8((uint8_t*)file_load_address[STATE_FILE_IDX], sizeof(state_page_data) - 1);
|
||||
((state_page_data*)file_load_address[STATE_FILE_IDX])->crc = crc;
|
||||
keep_going = keep_going && df_overwrite_file(DEFAULT_DRIVE_CONTROLLER_OFFSET, file_trksec[STATE_FILE_IDX][0], file_trksec[STATE_FILE_IDX][1], (uint8_t*)file_load_address[STATE_FILE_IDX], &cur_trk);
|
||||
}
|
||||
|
||||
dii_power_off(DEFAULT_DRIVE_CONTROLLER_OFFSET);
|
||||
__enable_interrupts();
|
||||
}
|
||||
|
||||
shared_page->master_command = MASTER_COMMAND_NONE;
|
||||
|
||||
// Execute the module
|
||||
(((void (*)(void))(MODULE_PAGE))());
|
||||
} while(keep_going);
|
||||
|
||||
__asm volatile(" brk\n":::);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue