mirror of
https://codeberg.org/hkzlab/TK2000_floppicator.git
synced 2025-12-25 09:02:28 +11:00
Base version of the floppicator
This commit is contained in:
parent
5c6994b253
commit
2abdb84acc
8 changed files with 181 additions and 22 deletions
4
Makefile
4
Makefile
|
|
@ -12,8 +12,8 @@ PRG=master
|
|||
# Libraries
|
||||
LIBS=clib-6502.a
|
||||
|
||||
ASM_SRCS = tk2k_startup.s preserve_zero_pages.s disk2.s
|
||||
C_SRCS = main.c graphics.c utility.c line_data.c
|
||||
ASM_SRCS = tk2k_startup.s preserve_zero_pages.s disk2.s sound.s
|
||||
C_SRCS = main.c graphics.c utility.c line_data.c input.c
|
||||
|
||||
# Object files
|
||||
OBJS = $(ASM_SRCS:%.s=%.o) $(C_SRCS:%.c=%.o)
|
||||
|
|
|
|||
|
|
@ -3,9 +3,9 @@
|
|||
(section registers zpage zzpage))
|
||||
(memory firstPage (address (#x100 . #x1ff)) (section stack))
|
||||
(memory reserved (address (#x200 . #x7ff)) (type ram))
|
||||
(memory program (address (#x800 . #x15ff)) (type ram)
|
||||
(memory program (address (#x800 . #x187f)) (type ram)
|
||||
(section (programStart #x800) (dii_critical_wr_code #x803) (dii_critical_rd_code #x90b) startup code switch idata cdata data_init_table))
|
||||
(memory dataMem (address (#x1600 . #x1fff)) (type ram) (section cstack zdata data heap zpsave))
|
||||
(memory dataMem (address (#x1880 . #x1fff)) (type ram) (section cstack zdata data heap zpsave))
|
||||
(memory displayPage1 (address (#x2000 . #x3fff)) (type ram))
|
||||
(memory upperMem (address (#x4000 . #xbbff)) (type ram))
|
||||
(memory diskBuffer (address (#xbc00 . #xbeff)) (type ram)) ;;; This memory will be used by the disk II routines as buffer
|
||||
|
|
|
|||
|
|
@ -67,3 +67,28 @@ void draw_chars(uint8_t x, uint8_t y, uint8_t invert, uint8_t *buf, uint8_t len
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
void draw_char(uint8_t x, uint8_t y, uint8_t invert, uint8_t ch) {
|
||||
for(uint8_t row = 0; row < CHAR_HEIGHT && (row + y) < SCREEN_HEIGHT; row++) {
|
||||
uint16_t offset = line_offset_map[row + y];
|
||||
|
||||
front_buf[offset + x] = invert ? (~CHARSET[(ch * CHAR_HEIGHT) + row]) & 0x7F : CHARSET[(ch * CHAR_HEIGHT) + row];
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t convert_string(uint8_t *buf, uint8_t buf_len, char *str) {
|
||||
uint8_t size = 0;
|
||||
|
||||
while(*str && size < buf_len) { // Yeah yeah. Unsafe.
|
||||
char ch = *str;
|
||||
if(ch >= 64 && ch <= 95) buf[size] = ch - 64;
|
||||
else if (ch >= 97 && ch <= 122) buf[size] = ch - 96; // Uppercase conversion
|
||||
else if (ch >= 32 && ch <= 63) buf[size] = ch; // As is
|
||||
else buf[size] = 0x20; // For everything else, insert a space.
|
||||
|
||||
str++;
|
||||
size++;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@ void initialize_display_buffer(void);
|
|||
void clear_display_buffer(void);
|
||||
void draw_number(uint16_t n, uint8_t len, uint8_t x, uint8_t y);
|
||||
void clear_box(uint8_t w, uint8_t h, uint8_t off_x, uint8_t off_y);
|
||||
void draw_char(uint8_t x, uint8_t y, uint8_t invert, uint8_t ch);
|
||||
void draw_chars(uint8_t x, uint8_t y, uint8_t invert, uint8_t *buf, uint8_t len);
|
||||
uint8_t convert_string(uint8_t *buf, uint8_t buf_len, char *str);
|
||||
|
||||
#endif /* _GRAPHICS_HEADER_ */
|
||||
|
|
|
|||
157
src/main.c
157
src/main.c
|
|
@ -9,7 +9,10 @@
|
|||
#include "mem_map.h"
|
||||
#include "mem_registers.h"
|
||||
#include "graphics.h"
|
||||
#include "sound.h"
|
||||
#include "disk2.h"
|
||||
#include "input.h"
|
||||
#include "charset.h"
|
||||
|
||||
// External initialization requirements
|
||||
#pragma require __preserve_zp
|
||||
|
|
@ -17,7 +20,20 @@
|
|||
|
||||
#define DEFAULT_DRIVE_CONTROLLER_OFFSET 0x10
|
||||
|
||||
#define TOT_FLOPPY_TRACKS 35
|
||||
#define SECTORS_PER_TRACK 16
|
||||
#define SECTOR_SIZE 256
|
||||
#define TRACKS_AT_ONCE 7
|
||||
#define TRACK_PARTS (TOT_FLOPPY_TRACKS / TRACKS_AT_ONCE)
|
||||
|
||||
static uint8_t *track_buffer = (uint8_t*)TRACK_BUFFER_START;
|
||||
static uint8_t *crc_buffer = (uint8_t*)CRC_BUFFER_START;
|
||||
|
||||
static uint8_t str_conv_buffer[SCREEN_CHAR_WIDTH];
|
||||
|
||||
static void init(void);
|
||||
static void draw_sector_map(void);
|
||||
static void reseat_floppy_heads(void);
|
||||
|
||||
// Low level initialization
|
||||
static void init(void) {
|
||||
|
|
@ -34,27 +50,144 @@ static void init(void) {
|
|||
clear_display_buffer();
|
||||
}
|
||||
|
||||
#define MAP_TOP_OFFSET 2
|
||||
static void draw_sector_map(void) {
|
||||
uint8_t str_len;
|
||||
|
||||
str_len = convert_string(str_conv_buffer, SCREEN_CHAR_WIDTH, "00000000000000001111111111111111222");
|
||||
draw_chars(1, CHAR_HEIGHT * (MAP_TOP_OFFSET + 0), 1, str_conv_buffer, str_len);
|
||||
str_len = convert_string(str_conv_buffer, SCREEN_CHAR_WIDTH, "0123456789ABCDEF0123456789ABCDEF012");
|
||||
draw_chars(1, CHAR_HEIGHT * (MAP_TOP_OFFSET + 1), 1, str_conv_buffer, str_len);
|
||||
|
||||
for(uint8_t row = 0; row < 0x10; row++) {
|
||||
draw_char(0, CHAR_HEIGHT * (MAP_TOP_OFFSET + 2 + row), 1, str_conv_buffer[row]);
|
||||
}
|
||||
|
||||
str_len = convert_string(str_conv_buffer, SCREEN_CHAR_WIDTH, "...................................");
|
||||
for(uint8_t row = 0; row < 0x10; row++) {
|
||||
draw_chars(1, CHAR_HEIGHT * (MAP_TOP_OFFSET + 2 + row), 0, str_conv_buffer, str_len);
|
||||
}
|
||||
}
|
||||
|
||||
static void reseat_floppy_heads(void) {
|
||||
dii_power_on(DEFAULT_DRIVE_CONTROLLER_OFFSET, 0);
|
||||
dii_head_reposition(DEFAULT_DRIVE_CONTROLLER_OFFSET, 96, 0);
|
||||
dii_power_off(DEFAULT_DRIVE_CONTROLLER_OFFSET);
|
||||
|
||||
dii_power_on(DEFAULT_DRIVE_CONTROLLER_OFFSET, 1);
|
||||
dii_head_reposition(DEFAULT_DRIVE_CONTROLLER_OFFSET, 96, 0);
|
||||
dii_power_off(DEFAULT_DRIVE_CONTROLLER_OFFSET);
|
||||
}
|
||||
|
||||
__task int main(void) {
|
||||
uint8_t cur_trk_1, cur_trk_2 = 0;
|
||||
uint8_t keep_going = 1;
|
||||
uint8_t trk_pos_1 = 0, trk_pos_2 = 0;
|
||||
uint16_t errors = 0;
|
||||
uint8_t *temp_crc_buf;
|
||||
|
||||
__disable_interrupts();
|
||||
|
||||
init();
|
||||
|
||||
uint8_t str_len = convert_string(str_conv_buffer, SCREEN_CHAR_WIDTH, "THE FLOPPICATOR");
|
||||
draw_chars(12, 32, 0, str_conv_buffer, str_len);
|
||||
|
||||
str_len = convert_string(str_conv_buffer, SCREEN_CHAR_WIDTH, "PRESS ANY KEY TO CONTINUE");
|
||||
draw_chars(7, 176, 1, str_conv_buffer, str_len);
|
||||
|
||||
while(!read_any_key());
|
||||
snd_mod_button();
|
||||
|
||||
clear_display_buffer();
|
||||
|
||||
draw_sector_map();
|
||||
|
||||
str_len = convert_string(str_conv_buffer, SCREEN_CHAR_WIDTH, "ERRORS: 000");
|
||||
draw_chars(0, CHAR_HEIGHT * (MAP_TOP_OFFSET + 19), 0, str_conv_buffer, str_len);
|
||||
|
||||
reseat_floppy_heads();
|
||||
|
||||
temp_crc_buf = crc_buffer;
|
||||
for(uint8_t part = 0; part < TRACK_PARTS; part++) {
|
||||
uint8_t start_track = part * TRACKS_AT_ONCE;
|
||||
|
||||
dii_power_on(DEFAULT_DRIVE_CONTROLLER_OFFSET, 0);
|
||||
|
||||
for(uint8_t cur_trk = 0; cur_trk < TRACKS_AT_ONCE; cur_trk++) {
|
||||
dii_head_reposition(DEFAULT_DRIVE_CONTROLLER_OFFSET, trk_pos_1 << 1, (start_track + cur_trk) << 1);
|
||||
trk_pos_1 = (start_track + cur_trk);
|
||||
|
||||
for(uint8_t sec = 0; sec < SECTORS_PER_TRACK; sec++) {
|
||||
uint8_t read_res = dii_read_sector(DEFAULT_DRIVE_CONTROLLER_OFFSET, trk_pos_1, sec, track_buffer + (cur_trk * SECTORS_PER_TRACK * SECTOR_SIZE) + (sec * SECTOR_SIZE), 0);
|
||||
*(temp_crc_buf++) = calculate_crc8(track_buffer + (cur_trk * SECTORS_PER_TRACK * SECTOR_SIZE) + (sec * SECTOR_SIZE), SECTOR_SIZE);
|
||||
draw_char((start_track + cur_trk) + 1, CHAR_HEIGHT * (MAP_TOP_OFFSET + 2 + sec), read_res ? 0 : 1, read_res ? 18 : 24);
|
||||
|
||||
if(!read_res) {
|
||||
errors++;
|
||||
draw_number(errors, 3, 8, CHAR_HEIGHT * (MAP_TOP_OFFSET + 19));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dii_power_off(DEFAULT_DRIVE_CONTROLLER_OFFSET);
|
||||
|
||||
dii_power_on(DEFAULT_DRIVE_CONTROLLER_OFFSET, 1);
|
||||
|
||||
for(uint8_t cur_trk = 0; cur_trk < TRACKS_AT_ONCE; cur_trk++) {
|
||||
dii_head_reposition(DEFAULT_DRIVE_CONTROLLER_OFFSET, trk_pos_2 << 1, (start_track + cur_trk) << 1);
|
||||
trk_pos_2 = (start_track + cur_trk);
|
||||
|
||||
for(uint8_t sec = 0; sec < SECTORS_PER_TRACK; sec++) {
|
||||
dii_encode_gcr62_data(track_buffer + (cur_trk * SECTORS_PER_TRACK * SECTOR_SIZE) + (sec * SECTOR_SIZE), (uint8_t*)WRITE_SIXES_BUFFER_DEFAULT_ADDRESS, (uint8_t*)WRITE_TWOS_BUFFER_DEFAULT_ADDRESS);
|
||||
uint8_t write_res = dii_write_sector(DEFAULT_DRIVE_CONTROLLER_OFFSET, trk_pos_2, sec);
|
||||
draw_char((start_track + cur_trk) + 1, CHAR_HEIGHT * (MAP_TOP_OFFSET + 2 + sec), write_res ? 1 : 0, write_res ? 24 : 23);
|
||||
|
||||
if(write_res) {
|
||||
errors++;
|
||||
draw_number(errors, 3, 8, CHAR_HEIGHT * (MAP_TOP_OFFSET + 19));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dii_power_off(DEFAULT_DRIVE_CONTROLLER_OFFSET);
|
||||
}
|
||||
|
||||
|
||||
if(!errors) { // No errors up to now, check what we have written
|
||||
dii_power_on(DEFAULT_DRIVE_CONTROLLER_OFFSET, 1);
|
||||
|
||||
// Now, time to check that we wrote things that make sense...
|
||||
temp_crc_buf = crc_buffer;
|
||||
for(uint8_t cur_trk = 0; cur_trk < TOT_FLOPPY_TRACKS; cur_trk++) {
|
||||
dii_head_reposition(DEFAULT_DRIVE_CONTROLLER_OFFSET, trk_pos_2 << 1, cur_trk << 1);
|
||||
trk_pos_2 = cur_trk;
|
||||
|
||||
for(uint8_t sec = 0; sec < SECTORS_PER_TRACK; sec++) {
|
||||
uint8_t read_res = dii_read_sector(DEFAULT_DRIVE_CONTROLLER_OFFSET, trk_pos_2, sec, track_buffer, 0);
|
||||
draw_char(cur_trk + 1, CHAR_HEIGHT * (MAP_TOP_OFFSET + 2 + sec), 0, read_res ? 102 : 24);
|
||||
uint8_t crc_check = (calculate_crc8(track_buffer, SECTOR_SIZE) == *(temp_crc_buf++));
|
||||
draw_char(cur_trk + 1, CHAR_HEIGHT * (MAP_TOP_OFFSET + 2 + sec), crc_check ? 0 : 1, crc_check ? 22 : 24);
|
||||
|
||||
if(!read_res) {
|
||||
errors++;
|
||||
draw_number(errors, 3, 8, CHAR_HEIGHT * (MAP_TOP_OFFSET + 19));
|
||||
}
|
||||
|
||||
if(!crc_check) {
|
||||
errors++;
|
||||
draw_number(errors, 3, 8, CHAR_HEIGHT * (MAP_TOP_OFFSET + 19));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dii_power_off(DEFAULT_DRIVE_CONTROLLER_OFFSET);
|
||||
}
|
||||
|
||||
__enable_interrupts();
|
||||
|
||||
uint8_t chars[] = {1, 2, 3, 32, 4};
|
||||
if(errors) snd_sad_scale();
|
||||
else snd_festive();
|
||||
|
||||
draw_chars(0, 0, 1, chars, 5);
|
||||
draw_chars(1, 8, 0, chars, 5);
|
||||
draw_chars(2, 16, 1, chars, 5);
|
||||
|
||||
do {
|
||||
|
||||
} while(keep_going);
|
||||
|
||||
__asm volatile(" brk\n":::);
|
||||
while(1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,8 +7,7 @@
|
|||
|
||||
#define ROMRAM_BANK 0xC100
|
||||
|
||||
#define SHARED_PAGE 0x9B00
|
||||
#define STATE_PAGE 0x9A00
|
||||
#define MODULE_PAGE 0x4000
|
||||
#define TRACK_BUFFER_START 0x4000
|
||||
#define CRC_BUFFER_START 0xB000
|
||||
|
||||
#endif /* _MEMORY_MAP_HEADER_ */
|
||||
|
|
|
|||
|
|
@ -45,10 +45,10 @@ uint16_t lfsr_update(void) {
|
|||
}
|
||||
|
||||
#define CRC8RDALLAS_POLY 0x31
|
||||
uint8_t calculate_crc8(uint8_t* data, uint8_t len) {
|
||||
uint8_t calculate_crc8(uint8_t* data, uint16_t len) {
|
||||
uint8_t crc = 0;
|
||||
|
||||
for(uint8_t data_idx = 0; data_idx < len; data_idx++) {
|
||||
for(uint16_t data_idx = 0; data_idx < len; data_idx++) {
|
||||
uint8_t carry;
|
||||
uint8_t d = data[data_idx];
|
||||
|
||||
|
|
|
|||
|
|
@ -29,6 +29,6 @@ uint8_t bit_reverse(uint8_t b);
|
|||
uint8_t bit_count(uint8_t b);
|
||||
void lfsr_init(uint16_t reg);
|
||||
uint16_t lfsr_update(void);
|
||||
uint8_t calculate_crc8(uint8_t* data, uint8_t len);
|
||||
uint8_t calculate_crc8(uint8_t* data, uint16_t len);
|
||||
|
||||
#endif /* _UTILITY_HEADER_ */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue