From a5d7e68af96d9b62821d8fd47f5039c5bae5d421 Mon Sep 17 00:00:00 2001 From: Reiner Herrmann Date: Fri, 10 Feb 2012 14:25:38 +0100 Subject: added original sam_player code --- c64/tape.c | 172 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 172 insertions(+) create mode 100644 c64/tape.c (limited to 'c64/tape.c') diff --git a/c64/tape.c b/c64/tape.c new file mode 100644 index 0000000..725bf2f --- /dev/null +++ b/c64/tape.c @@ -0,0 +1,172 @@ +// tape.c +// +// 20060803 Markku Alén + +#include "tape.h" +#include "cpu.h" +#include "mem.h" + +#include "prg_file.h" + +#define STATUS (ram[0x90]) +#define VERCKK (ram[0x93]) + +#define EAL (ram[0xae] | (ram[0xaf] << 8)) + +#define TBUFFR (ram[0xb2] | (ram[0xb3] << 8)) + +#define FNLEN (ram[0xb7]) +#define FNADR (ram[0xbb] | (ram[0xbc] << 8)) + +#define STAL (ram[0xc1] | (ram[0xc2] << 8)) + +#define IRQTMP (ram[0x2a0]) + +#define OFFSET_TYPE 0 +#define OFFSET_START_ADDR 1 +#define OFFSET_END_ADDR 3 +#define OFFSET_NAME 5 + +#define TYPE_PRG 1 /* Binary Program */ +#define TYPE_BAS 3 /* Relocatable Program */ +#define TYPE_DATA 4 /* Data Record */ +#define TYPE_EOF 5 /* End of Tape marker */ + +#define FIND_RET 0xF732 +#define WRITE_RET 0xF7C1 +#define TRANSFER_RET 0xFC93 + +#define WRITE_LEADER 0x0a +#define WRITE_BLOCK 0x08 +#define READ_BLOCK 0x0e + +#define EOF 0x40 + +static void copy_to_ram(int addr, int len, const void *buf) +{ + while(len-- > 0) + ram[addr + len] = ((char *)buf)[len]; +} + +static void setup_tape_hdr(int type, const char *filename, int start_addr, int stop_addr) +{ + int i; + char c, *p; + p = &ram[TBUFFR]; + for(i = 0;i < 16;i++) + { + c = *filename; + if(c != '\0') + filename++; + p[OFFSET_NAME + i] = c; + } + p[OFFSET_TYPE] = type; + p[OFFSET_START_ADDR + 0] = start_addr % 256; + p[OFFSET_START_ADDR + 1] = start_addr / 256; + p[OFFSET_END_ADDR + 0] = stop_addr % 256; + p[OFFSET_END_ADDR + 1] = stop_addr / 256; +} + +static char filename[15 + 1]; + +static void get_filename(void) +{ + int i; + char c, *p; + p = &ram[FNADR]; + for(i = 0;i < (sizeof(filename) - 1);i++) + { + c = *(p++); + if(c < '0' || c > '9') + { + if(c < 'A' || c > 'Z') + { + if(c < 'a' || c > 'z') + { + if(c != '.' && c != '_') + c = '.'; + } + } + } + filename[i] = c; + } + if(i > FNLEN) + i = FNLEN; + filename[i] = '\0'; +} + +static int find_header(void) +{ + int err; + err = 0; + get_filename(); + if(prg_load(filename) != 0) + err = -1; + if(err == 0) + setup_tape_hdr(TYPE_BAS, filename, prg_addr, prg_addr + prg_len); + STATUS = 0x00; + VERCKK = 0x00; + IRQTMP = 0x00; + set_c_flag(err != 0); + set_z_flag(0); + set_pc(FIND_RET); + return 0; +} + +static int write_header(void) +{ + int i; + i=0; +} + +static int tape_transfer(void) +{ + int i; + int err; + int start, end, len; + int st; + err = 0; + start = STAL; + end = EAL; + len = end - start; + st = 0x00; + switch(get_x()) + { + case WRITE_LEADER: + break; + case WRITE_BLOCK: +// if (fwrite(ram + start, len, 1, tape->FileDs) == 1) { +// st |= 0x40; /* EOF */ +// } +// else { +// st |= 0xB4; /* All possible errors... */ +// +// fprintf(stderr, "Error: Tape write failed.\n"); +// } +// break; + i=0; + case READ_BLOCK: + copy_to_ram(start, len, prg_data); + st |= EOF; + break; + default: + err = -1; + } + IRQTMP = 0x00; + STATUS |= st; + set_c_flag(err != 0); + set_pc(TRANSFER_RET); + return 0; +} + +static trap_t traps[] = +{ + TRAP_INIT(0xF72F, 0x20, 0x41, 0xF8, &find_header), + TRAP_INIT(0xF7BE, 0x20, 0x6B, 0xF8, &write_header), + TRAP_INIT(0xF8A1, 0x20, 0xBD, 0xFC, &tape_transfer), +}; + +void init_tape(void) +{ + install_traps(sizeof(traps) / sizeof(traps[0]), traps, &poke, &peek); +} -- cgit v1.2.3