Working on F256 again!
This commit is contained in:
parent
88b4a6850a
commit
62db64dcd5
17 changed files with 311 additions and 85 deletions
|
@ -26,11 +26,12 @@
|
|||
|
||||
|
||||
#include <stdint.h>
|
||||
#include "mapper.h"
|
||||
|
||||
|
||||
//#define DEBUGGING
|
||||
|
||||
#define STACK_SIZE 2048 //***TODO*** How big does this really need to be? Old games are 1024, new...?
|
||||
#define STACK_SIZE 512 //***TODO*** How big does this really need to be? Old games are 1024, new...?
|
||||
|
||||
|
||||
#ifdef DEBUGGING
|
||||
|
|
29
include/mapper.h
Normal file
29
include/mapper.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
Special mapper macros for the F256 + mos-llvm, so we can put code
|
||||
anywhere in physical ram
|
||||
|
||||
Currently only blocks 8-23 are defined in the linker file
|
||||
|
||||
If you need to go beyond the 128k of extra code, just add more definitions
|
||||
into f256.ld
|
||||
*/
|
||||
|
||||
#if defined(__F256K__) && __F256K__ && 0
|
||||
|
||||
/*
|
||||
$$JGA TODO, sort out how to mark an entire file
|
||||
*/
|
||||
|
||||
#define CODE_BLOCK(index) __attribute__((noinline, section(".block"#index)))
|
||||
#define DATA_BLOCK(index) __attribute__((section(".block"#index)))
|
||||
|
||||
#define PAGEIN(_function_BLOCK) POKE(SWAP_SLOT, _function_BLOCK)
|
||||
|
||||
#else
|
||||
|
||||
#define CODE_BLOCK(index)
|
||||
#define DATA_BLOCK(index)
|
||||
|
||||
#define PAGEIN(_function_BLOCK)
|
||||
|
||||
#endif
|
|
@ -35,16 +35,17 @@
|
|||
#define MSG_INT_OBJECT0_REF "Object 0 referenced!"
|
||||
#define MSG_INT_OBJECT_BAD_ID "Invalid object ID!"
|
||||
#define MSG_INT_PARSE_BUFFER_TOO_SMALL "Parse buffer too small for reading."
|
||||
#define MSG_INT_REF_UNALLOCATED_LOCAL "Referenced unallocated local variable!"
|
||||
#define MSG_INT_STACK_OVERFLOW "Stack overflow!"
|
||||
#define MSG_INT_STACK_UNDERFLOW "Stack underflow!"
|
||||
#define MSG_INT_STACK_UNDERFLOW "Int Stack underflow!"
|
||||
#define MSG_INT_UNIMPLEMENTED_OPCODE "Unimplemented opcode! %s %d"
|
||||
#define MSG_INT_V12_SHIFT "Add V1/V2 shifting."
|
||||
#define MSG_INT_V12_SHIFT_LOCK "Add V1/V2 shift locking."
|
||||
#define MSG_MEM_BUFFER "Unable to allocate memory buffer."
|
||||
#define MSG_STA_CANNOT_ALLOCATE_STACK "Cannot allocate stack!"
|
||||
#define MSG_VAR_REF_UNALLOCATED_LOCAL "Referenced unallocated local variable!"
|
||||
#define MSG_VAR_STACK_OVERFLOW "Var Stack overflow!"
|
||||
#define MSG_VAR_STACK_UNDERFLOW "Var Stack underflow!"
|
||||
#define MSG_OP_CALL_TOO_MANY_LOCALS "Too many local variables! (%d)"
|
||||
#define MSG_OP_CALL_STACK_OVERFLOW "Stack overflow!"
|
||||
#define MSG_OP_CALL_STACK_OVERFLOW "OP Call Stack overflow!"
|
||||
#define MSG_OP_INPUT_BUFFER_TOO_SMALL "Text buffer too small for reading."
|
||||
#define MSG_OP_OBJ_MISSING_PROPERTY "Missing object property."
|
||||
#define MSG_OP_WIN_NO_SPLITTING "Window splitting is not supported."
|
||||
|
@ -56,14 +57,15 @@
|
|||
#define MSG_INT_OBJECT0_REF ""
|
||||
#define MSG_INT_OBJECT_BAD_ID ""
|
||||
#define MSG_INT_PARSE_BUFFER_TOO_SMALL ""
|
||||
#define MSG_INT_REF_UNALLOCATED_LOCAL ""
|
||||
#define MSG_INT_STACK_OVERFLOW ""
|
||||
#define MSG_INT_STACK_UNDERFLOW ""
|
||||
#define MSG_INT_UNIMPLEMENTED_OPCODE ""
|
||||
#define MSG_INT_V12_SHIFT ""
|
||||
#define MSG_INT_V12_SHIFT_LOCK ""
|
||||
#define MSG_MEM_BUFFER ""
|
||||
#define MSG_STA_CANNOT_ALLOCATE_STACK ""
|
||||
#define MSG_VAR_REF_UNALLOCATED_LOCAL ""
|
||||
#define MSG_VAR_STACK_OVERFLOW ""
|
||||
#define MSG_VAR_STACK_UNDERFLOW ""
|
||||
#define MSG_OP_CALL_TOO_MANY_LOCALS ""
|
||||
#define MSG_OP_CALL_STACK_OVERFLOW ""
|
||||
#define MSG_OP_INPUT_BUFFER_TOO_SMALL ""
|
||||
|
|
|
@ -27,6 +27,12 @@
|
|||
|
||||
#include "common.h"
|
||||
|
||||
// Needed by port layer.
|
||||
#include "memory.h"
|
||||
#include "state.h"
|
||||
#include "story.h"
|
||||
#include "ui.h"
|
||||
|
||||
|
||||
void portAttributeSet(byte attribute);
|
||||
uint8_t portByteGet(uint32_t address);
|
||||
|
|
|
@ -30,11 +30,11 @@
|
|||
|
||||
|
||||
typedef struct stateS {
|
||||
uint16_t *stack;
|
||||
uint16_t *stack; // Must be first entry!
|
||||
bool quit;
|
||||
uint32_t pc; // Program Counter
|
||||
uint16_t sp; // Stack Pointer
|
||||
uint16_t bp; // Base Pointer
|
||||
uint32_t pc; // Program Counter
|
||||
uint16_t sp; // Stack Pointer
|
||||
uint16_t bp; // Base Pointer
|
||||
opcodeT opcodes[256];
|
||||
opcodeT extOpcodes[30];
|
||||
uint8_t operandCount;
|
||||
|
|
|
@ -109,13 +109,15 @@
|
|||
#define storyAlphabetTableAddress() portWordGet(0x34)
|
||||
#define storyHeaderExtensionTableAddress() portWordGet(0x36)
|
||||
|
||||
#define storyHXWordsInTable() portWordGet(storyHeaderExtensionTableAddress())
|
||||
#define storyHXMouseXClick() portWordGet(storyHeaderExtensionTableAddress() + 2)
|
||||
#define storyHXMouseYClick() portWordGet(storyHeaderExtensionTableAddress() + 4)
|
||||
#define storyHXUnicodeTranslationTableAddress() portWordGet(storyHeaderExtensionTableAddress() + 6)
|
||||
#define storyHXFlags3() portWordGet(storyHeaderExtensionTableAddress() + 8)
|
||||
#define storyHXTrueDefaultForegroundColor() portWordGet(storyHeaderExtensionTableAddress() + 10)
|
||||
#define storyHXTrueDefaultBackgroundColor() portWordGet(storyHeaderExtensionTableAddress() + 12)
|
||||
#define storyHXWordsInTable() portWordGet(storyHeaderExtensionTableAddress())
|
||||
#define storyHXMouseXClick() portWordGet(storyHeaderExtensionTableAddress() + 2)
|
||||
#define storyHXMouseYClick() portWordGet(storyHeaderExtensionTableAddress() + 4)
|
||||
#define storyHXUnicodeTranslationTableAddress() portWordGet(storyHeaderExtensionTableAddress() + 6)
|
||||
#define storyHXFlags3() portWordGet(storyHeaderExtensionTableAddress() + 8)
|
||||
#define storyHXTrueDefaultForegroundColor() portWordGet(storyHeaderExtensionTableAddress() + 10)
|
||||
#define storyHXTrueDefaultBackgroundColor() portWordGet(storyHeaderExtensionTableAddress() + 12)
|
||||
|
||||
#define storyAddToChecksum(index,value) __state.checksum += (index < 64 ? 0 : value)
|
||||
|
||||
|
||||
void storyChecksumCalculate(void);
|
||||
|
|
|
@ -244,6 +244,7 @@ void portScreenClear(void) {
|
|||
|
||||
void portStoryLoad(char *story, uint32_t *length) {
|
||||
FILE *in;
|
||||
uint32_t i;
|
||||
|
||||
in = fopen(story, "rb");
|
||||
if (!in) portDie("Unable to open %s!\n", story);
|
||||
|
@ -261,6 +262,8 @@ void portStoryLoad(char *story, uint32_t *length) {
|
|||
}
|
||||
|
||||
fclose(in);
|
||||
|
||||
for (i=0; i<*length; i++) storyAddToChecksum(i, _RAM[i]);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ set(HEADERS
|
|||
common.h
|
||||
interpreter.h
|
||||
lib.h
|
||||
mapper.h
|
||||
memory.h
|
||||
messages.h
|
||||
object.h
|
||||
|
|
|
@ -24,38 +24,31 @@
|
|||
|
||||
|
||||
PROJECT=f256zip
|
||||
START=0x300
|
||||
|
||||
F256=$(pwd)/../../../f256
|
||||
LLVM=${F256}/llvm-mos
|
||||
SETTINGS=${LLVM}/mos-platform/f256k/lib/settings.ld
|
||||
PATH=${LLVM}/bin:${PATH}
|
||||
|
||||
echo "__f256_start = ${START};" > ${SETTINGS}
|
||||
|
||||
CLANG="mos-f256k-clang -I${F256}/include -I../../../include -I${F256}/f256lib -Os"
|
||||
|
||||
[[ -d .builddir ]] && rm -rf .builddir
|
||||
mkdir -p .builddir
|
||||
pushd .builddir
|
||||
|
||||
${F256}/overlayhelper ../../../src/ui.c > overlay.ld
|
||||
${F256}/overlayhelper ../f256zip.c >> overlay.ld
|
||||
|
||||
${CLANG} -c ${F256}/f256lib/f256.c
|
||||
${CLANG} -c ../../zip.c
|
||||
${CLANG} -c ../${PROJECT}.c
|
||||
${CLANG} -o ${PROJECT} zip.o f256.o ${PROJECT}.o
|
||||
${CLANG} -T../f256.ld -o ${PROJECT} zip.o f256.o ${PROJECT}.o
|
||||
|
||||
mv -f ${PROJECT} ${PROJECT}.bin
|
||||
llvm-nm ${PROJECT}.elf > ${PROJECT}.lst
|
||||
llvm-objdump -d --print-imm-hex ${PROJECT}.elf > ${PROJECT}.lst
|
||||
python ${F256}/pgz-thunk.py f256zip
|
||||
|
||||
${F256}/header \
|
||||
pgz 24 \
|
||||
../${PROJECT}.pgz \
|
||||
${START} \
|
||||
${PROJECT}.bin ${START}
|
||||
# ../../../stories/zork1-r119-s880429.z3 0x10000
|
||||
# ../../../tests/testers/czech/czech.z3 0x10000
|
||||
mv -f ${PROJECT} ../${PROJECT}.pgz
|
||||
|
||||
#llvm-nm ${PROJECT}.elf > ${PROJECT}.lst
|
||||
#llvm-objdump -d --print-imm-hex ${PROJECT}.elf > ${PROJECT}.lst
|
||||
#hexdump -C ../${PROJECT}.pgz > ${PROJECT}.hex
|
||||
|
||||
popd
|
||||
|
|
120
ports/f256/f256-banked.ld
Normal file
120
ports/f256/f256-banked.ld
Normal file
|
@ -0,0 +1,120 @@
|
|||
/* F256 Banking Linker Script
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/* fake C Stack */
|
||||
PROVIDE(__stack = 0xA000);
|
||||
/* entry point to my program */
|
||||
PROVIDE(__f256_start = 0x300);
|
||||
/* page size of a block of memory */
|
||||
PROVIDE(__BLOCK_SIZE = 0x2000);
|
||||
/* swappable block address */
|
||||
PROVIDE(__SLOT_ADDR = 0xA000);
|
||||
|
||||
/* f256k uses first 16 bytes of ZP for mmu control? */
|
||||
__rc0 = 0x10;
|
||||
INCLUDE imag-regs.ld
|
||||
ASSERT(__rc0 == 0x10, "Inconsistent zero page map.")
|
||||
ASSERT(__rc31 == 0x2f, "Inconsistent zero page map.")
|
||||
|
||||
MEMORY {
|
||||
/* kernel uses 0xf0-0xff for parameter passing */
|
||||
zp : ORIGIN = __rc31 + 1, LENGTH = 0xF0 - (__rc31 + 1)
|
||||
ram (rw) : ORIGIN = __f256_start, LENGTH = 0xA000-__f256_start
|
||||
}
|
||||
|
||||
/* LMAs */
|
||||
__block8_lma = ( 8<<24)|__SLOT_ADDR;
|
||||
__block9_lma = ( 9<<24)|__SLOT_ADDR;
|
||||
__block10_lma = (10<<24)|__SLOT_ADDR;
|
||||
__block11_lma = (11<<24)|__SLOT_ADDR;
|
||||
__block12_lma = (12<<24)|__SLOT_ADDR;
|
||||
__block13_lma = (13<<24)|__SLOT_ADDR;
|
||||
__block14_lma = (14<<24)|__SLOT_ADDR;
|
||||
__block15_lma = (15<<24)|__SLOT_ADDR;
|
||||
__block16_lma = (16<<24)|__SLOT_ADDR;
|
||||
__block17_lma = (17<<24)|__SLOT_ADDR;
|
||||
__block18_lma = (18<<24)|__SLOT_ADDR;
|
||||
__block19_lma = (19<<24)|__SLOT_ADDR;
|
||||
__block20_lma = (20<<24)|__SLOT_ADDR;
|
||||
__block21_lma = (21<<24)|__SLOT_ADDR;
|
||||
__block22_lma = (22<<24)|__SLOT_ADDR;
|
||||
__block23_lma = (23<<24)|__SLOT_ADDR;
|
||||
|
||||
MEMORY {
|
||||
block8 : ORIGIN = __block8_lma, LENGTH = __BLOCK_SIZE
|
||||
block9 : ORIGIN = __block9_lma, LENGTH = __BLOCK_SIZE
|
||||
block10 : ORIGIN = __block10_lma, LENGTH = __BLOCK_SIZE
|
||||
block11 : ORIGIN = __block11_lma, LENGTH = __BLOCK_SIZE
|
||||
block12 : ORIGIN = __block12_lma, LENGTH = __BLOCK_SIZE
|
||||
block13 : ORIGIN = __block13_lma, LENGTH = __BLOCK_SIZE
|
||||
block14 : ORIGIN = __block14_lma, LENGTH = __BLOCK_SIZE
|
||||
block15 : ORIGIN = __block15_lma, LENGTH = __BLOCK_SIZE
|
||||
block16 : ORIGIN = __block16_lma, LENGTH = __BLOCK_SIZE
|
||||
block17 : ORIGIN = __block17_lma, LENGTH = __BLOCK_SIZE
|
||||
block18 : ORIGIN = __block18_lma, LENGTH = __BLOCK_SIZE
|
||||
block19 : ORIGIN = __block19_lma, LENGTH = __BLOCK_SIZE
|
||||
block20 : ORIGIN = __block20_lma, LENGTH = __BLOCK_SIZE
|
||||
block21 : ORIGIN = __block21_lma, LENGTH = __BLOCK_SIZE
|
||||
block22 : ORIGIN = __block22_lma, LENGTH = __BLOCK_SIZE
|
||||
block23 : ORIGIN = __block23_lma, LENGTH = __BLOCK_SIZE
|
||||
}
|
||||
|
||||
REGION_ALIAS("c_writeable", ram)
|
||||
/* REGION_ALIAS("c_readonly", fixed) */
|
||||
/* I want to use the lower 40k */
|
||||
REGION_ALIAS("c_readonly", ram)
|
||||
|
||||
SECTIONS {
|
||||
|
||||
INCLUDE c.ld
|
||||
|
||||
.binarydata : { *(.binarydata .binarydata.*) } >binarydata end_binarydata = .;
|
||||
|
||||
.block8 : { *(.block8 .block8.*) } >block8 end_block8 = .;
|
||||
.block9 : { *(.block9 .block9.*) } >block9 end_block9 = .;
|
||||
.block10 : { *(.block10 .block10.*) } >block10 end_block10 = .;
|
||||
.block11 : { *(.block11 .block11.*) } >block11 end_block11 = .;
|
||||
.block12 : { *(.block12 .block12.*) } >block12 end_block12 = .;
|
||||
.block13 : { *(.block13 .block13.*) } >block13 end_block13 = .;
|
||||
.block14 : { *(.block14 .block14.*) } >block14 end_block14 = .;
|
||||
.block15 : { *(.block15 .block15.*) } >block15 end_block15 = .;
|
||||
.block16 : { *(.block16 .block16.*) } >block16 end_block16 = .;
|
||||
.block17 : { *(.block17 .block17.*) } >block17 end_block17 = .;
|
||||
.block18 : { *(.block18 .block18.*) } >block18 end_block18 = .;
|
||||
.block19 : { *(.block19 .block19.*) } >block19 end_block19 = .;
|
||||
.block20 : { *(.block20 .block20.*) } >block20 end_block20 = .;
|
||||
.block21 : { *(.block21 .block21.*) } >block21 end_block21 = .;
|
||||
.block22 : { *(.block22 .block22.*) } >block22 end_block22 = .;
|
||||
.block23 : { *(.block23 .block23.*) } >block23 end_block23 = .;
|
||||
}
|
||||
|
||||
/* Trick linker into exposing symbols with values larger than 16 bits */
|
||||
INCLUDE overlay.ld
|
||||
|
||||
/* OUTPUT_FORMAT { FULL(cart_rom) } */
|
||||
OUTPUT_FORMAT {
|
||||
BYTE(0x5A) /* pgZ */
|
||||
|
||||
/* ram segment */
|
||||
|
||||
SHORT(ORIGIN(ram)) /* where to load it, 24 bits */
|
||||
BYTE(0x00)
|
||||
SHORT(__bss_start-ORIGIN(ram)) /* size to load */
|
||||
BYTE(0x00)
|
||||
TRIM(ram)
|
||||
|
||||
/* block8 */
|
||||
SHORT(8*0x2000)
|
||||
BYTE(8/8) /* block#/8 = the actual system high byte */
|
||||
SHORT(end_block8 - __block8_lma)
|
||||
BYTE(0x00)
|
||||
TRIM(block8)
|
||||
|
||||
/* Launch the program, at _start */
|
||||
SHORT(_start)
|
||||
LONG(0)
|
||||
|
||||
}
|
||||
|
45
ports/f256/f256.ld
Normal file
45
ports/f256/f256.ld
Normal file
|
@ -0,0 +1,45 @@
|
|||
/* F256 Linker Script */
|
||||
|
||||
|
||||
/* fake C Stack */
|
||||
PROVIDE(__stack = 0xC000);
|
||||
/* entry point to my program */
|
||||
PROVIDE(__f256_start = 0x300);
|
||||
/* swappable block address */
|
||||
PROVIDE(__SLOT_ADDR = 0xC000);
|
||||
|
||||
/* f256k uses first 16 bytes of ZP for mmu control? */
|
||||
__rc0 = 0x10;
|
||||
INCLUDE imag-regs.ld
|
||||
ASSERT(__rc0 == 0x10, "Inconsistent zero page map.")
|
||||
ASSERT(__rc31 == 0x2f, "Inconsistent zero page map.")
|
||||
|
||||
MEMORY {
|
||||
/* kernel uses 0xf0-0xff for parameter passing */
|
||||
zp : ORIGIN = __rc31 + 1, LENGTH = 0xF0 - (__rc31 + 1)
|
||||
ram (rw) : ORIGIN = __f256_start, LENGTH = 0xC000-__f256_start
|
||||
}
|
||||
|
||||
REGION_ALIAS("c_writeable", ram)
|
||||
REGION_ALIAS("c_readonly", ram)
|
||||
|
||||
SECTIONS {
|
||||
INCLUDE c.ld
|
||||
}
|
||||
|
||||
OUTPUT_FORMAT {
|
||||
BYTE(0x5A) /* pgZ */
|
||||
|
||||
/* ram segment */
|
||||
|
||||
SHORT(ORIGIN(ram)) /* where to load it, 24 bits */
|
||||
BYTE(0x00)
|
||||
SHORT(__bss_start-ORIGIN(ram)) /* size to load */
|
||||
BYTE(0x00)
|
||||
TRIM(ram)
|
||||
|
||||
/* Launch the program, at _start */
|
||||
SHORT(_start)
|
||||
LONG(0)
|
||||
}
|
||||
|
|
@ -35,11 +35,11 @@
|
|||
*/
|
||||
|
||||
|
||||
#define WITHOUT_GRAPHICS
|
||||
#define WITHOUT_MATH
|
||||
#include "f256.h"
|
||||
|
||||
#include "portme.h"
|
||||
#include "memory.h"
|
||||
#include "ui.h"
|
||||
|
||||
#include "../../include/text.h"
|
||||
|
||||
|
@ -69,12 +69,15 @@ void portAttributeSet(byte attribute) {
|
|||
|
||||
|
||||
uint8_t portByteGet(uint32_t address) {
|
||||
return FAR_PEEK(BASE_ADDRESS + address);
|
||||
uint8_t r = FAR_PEEK(BASE_ADDRESS + address);
|
||||
POKE(MMU_MEM_BANK_5, SWAP_SLOT - 8);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
void portByteSet(uint32_t address, uint8_t value) {
|
||||
FAR_POKE(BASE_ADDRESS + address, value);
|
||||
POKE(MMU_MEM_BANK_5, SWAP_SLOT - 8);
|
||||
}
|
||||
|
||||
|
||||
|
@ -164,21 +167,20 @@ uint32_t portFWrite(void *ptr, uint32_t size, uint32_t nmemb, void *stream) {
|
|||
}
|
||||
|
||||
|
||||
void portFileLister(void) {
|
||||
CODE_BLOCK(8) void portFileLister(void) {
|
||||
DIR *dir;
|
||||
struct dirent *dirent;
|
||||
uint32_t l;
|
||||
|
||||
if ((dir = opendir("0:"))) {
|
||||
for (;;) {
|
||||
if ((dirent = readdir(dir))) {
|
||||
// Is this a file?
|
||||
if (_DE_ISREG(dirent->d_type)) {
|
||||
// Add it to the story chooser.
|
||||
uiFileAdd(dirent->d_name, dirent->d_blocks * 256);
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
dirent = readdir(dir);
|
||||
if (dirent == 0) break;
|
||||
// Is this a file?
|
||||
if (_DE_ISREG(dirent->d_type)) {
|
||||
// Add it to the story chooser.
|
||||
// ***TODO*** d_blocks * 256 isn't right.
|
||||
uiFileAdd(dirent->d_name, dirent->d_blocks * 256);
|
||||
}
|
||||
}
|
||||
closedir(dir);
|
||||
|
@ -219,9 +221,12 @@ void portScreenClear(void) {
|
|||
void portStoryLoad(char *story, uint32_t *length) {
|
||||
FILE *in;
|
||||
uint32_t i;
|
||||
byte j;
|
||||
byte r;
|
||||
byte b;
|
||||
uint32_t newLength;
|
||||
char *buffer;
|
||||
|
||||
buffer = (char *)malloc(255);
|
||||
if (buffer == 0) portDie("M0");
|
||||
|
||||
in = fopen(story, "rb");
|
||||
if (!in) portDie("Unable to open %s!\n", story);
|
||||
|
@ -229,19 +234,24 @@ void portStoryLoad(char *story, uint32_t *length) {
|
|||
// The F256 only returns file sizes in blocks of 256.
|
||||
// We load what we can until we get an error and then
|
||||
// see if we're within 256 to determine success.
|
||||
i = BASE_ADDRESS;
|
||||
|
||||
i = 0;
|
||||
do {
|
||||
r = fread(&b, 1, 1, in);
|
||||
if (r == 1) ZPOKE(i++, b);
|
||||
} while (r == 1);
|
||||
r = fread(buffer, 1, 255, in);
|
||||
if (r > 0) {
|
||||
for (j=0; j<r; j++) {
|
||||
storyAddToChecksum(i, buffer[j]);
|
||||
ZPOKE(i++, buffer[j]);
|
||||
}
|
||||
}
|
||||
} while (r == 255);
|
||||
|
||||
fclose(in);
|
||||
|
||||
newLength = *length - (i - BASE_ADDRESS);
|
||||
if (newLength > 256) portDie("Unable to read %s!\n", story);
|
||||
free(buffer);
|
||||
|
||||
// Update story length.
|
||||
*length = newLength;
|
||||
*length = i;
|
||||
}
|
||||
|
||||
|
||||
|
@ -267,12 +277,16 @@ char *portSymbolsGet(void) {
|
|||
|
||||
|
||||
uint16_t portWordGet(uint32_t address) {
|
||||
return SWAP_UINT16(FAR_PEEKW(BASE_ADDRESS + address));
|
||||
uint16_t r = FAR_PEEKW(BASE_ADDRESS + address);
|
||||
POKE(MMU_MEM_BANK_5, SWAP_SLOT - 8);
|
||||
return SWAP_UINT16(r);
|
||||
}
|
||||
|
||||
|
||||
void portWordSet(uint32_t address, uint16_t value) {
|
||||
FAR_POKEW(BASE_ADDRESS + address, SWAP_UINT16(value));
|
||||
uint16_t v = SWAP_UINT16(value);
|
||||
FAR_POKEW(BASE_ADDRESS + address, v);
|
||||
POKE(MMU_MEM_BANK_5, SWAP_SLOT - 8);
|
||||
}
|
||||
|
||||
|
||||
|
@ -328,6 +342,7 @@ int main(void) {
|
|||
portCharGet();
|
||||
*/
|
||||
|
||||
PAGEIN(8);
|
||||
uiSizeSet(80, 30);
|
||||
uiGameSelect();
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ void opcodes_call(void) {
|
|||
#endif
|
||||
if (numLocals > 15) portDie(MSG_OP_CALL_TOO_MANY_LOCALS, numLocals);
|
||||
|
||||
if (__state.sp + 5 + numLocals >= sizeof(__state.stack)) portDie(MSG_OP_CALL_STACK_OVERFLOW);
|
||||
if (__state.sp + 5 + numLocals >= STACK_SIZE) portDie(MSG_OP_CALL_STACK_OVERFLOW);
|
||||
|
||||
// Save where we should store the call's result.
|
||||
__state.stack[__state.sp++] = storeId;
|
||||
|
|
|
@ -40,8 +40,10 @@ void stateReset(void) {
|
|||
_stackAllocated = true;
|
||||
}
|
||||
|
||||
// Zero out all state data.
|
||||
libMemSet((byte *)&__state, 0, sizeof(stateT));
|
||||
// Zero out all state data, skipping stack address.
|
||||
libMemSet((byte *)&__state + sizeof(uint16_t *), 0, sizeof(stateT));
|
||||
// Zero out stack.
|
||||
libMemSet((byte *)__state.stack, 0, sizeof(uint16_t) * STACK_SIZE);
|
||||
|
||||
__state.outputting = true;
|
||||
}
|
||||
|
|
|
@ -28,16 +28,7 @@
|
|||
|
||||
|
||||
void storyChecksumCalculate(void) {
|
||||
uint32_t i;
|
||||
|
||||
__state.checksum = 0;
|
||||
for (i=64; i<storyLength(); i++) __state.checksum += ZPEEK(i);
|
||||
|
||||
__state.checksum %= 0x10000;
|
||||
|
||||
#ifdef DEBUGGING
|
||||
printf("\n\nChecksum = %u Header = %d\n\n", __state.checksum, storyChecksum());
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
|
42
src/ui.c
42
src/ui.c
|
@ -59,7 +59,7 @@ static fileListT *_selected = 0;
|
|||
static uint16_t _gameCount = 0;
|
||||
|
||||
|
||||
static void uiBox(byte x, byte y, byte w, byte h) {
|
||||
CODE_BLOCK(8) static void uiBox(byte x, byte y, byte w, byte h) {
|
||||
byte i;
|
||||
byte j;
|
||||
char *b = portSymbolsGet();
|
||||
|
@ -83,7 +83,7 @@ static void uiBox(byte x, byte y, byte w, byte h) {
|
|||
}
|
||||
|
||||
|
||||
static void uiCenter(char *m) {
|
||||
CODE_BLOCK(8) static void uiCenter(char *m) {
|
||||
byte x;
|
||||
byte y;
|
||||
byte w = 80;
|
||||
|
@ -96,7 +96,7 @@ static void uiCenter(char *m) {
|
|||
}
|
||||
|
||||
|
||||
static void uiDialog(byte fc, byte bc, byte tc, byte y, char *message) {
|
||||
CODE_BLOCK(8) static void uiDialog(byte fc, byte bc, byte tc, byte y, char *message) {
|
||||
byte l;
|
||||
byte x;
|
||||
|
||||
|
@ -109,7 +109,7 @@ static void uiDialog(byte fc, byte bc, byte tc, byte y, char *message) {
|
|||
}
|
||||
|
||||
|
||||
void uiFileAdd(char *filename, uint32_t size) {
|
||||
CODE_BLOCK(8) void uiFileAdd(char *filename, uint32_t size) {
|
||||
uint32_t l;
|
||||
byte v;
|
||||
fileListT *newGame;
|
||||
|
@ -127,9 +127,9 @@ void uiFileAdd(char *filename, uint32_t size) {
|
|||
|
||||
// Create new game entry.
|
||||
newGame = (fileListT *)portMalloc(sizeof(fileListT));
|
||||
if (newGame == 0) portDie(MSG_UI_CANNOT_ALLOCATE, sizeof(fileListT));
|
||||
if (newGame == 0) portDie("M1"); // portDie(MSG_UI_CANNOT_ALLOCATE, sizeof(fileListT));
|
||||
newGame->filename = (char *)portMalloc(l + 1);
|
||||
if (newGame->filename == 0) portDie(MSG_UI_CANNOT_ALLOCATE, l + 1);
|
||||
if (newGame->filename == 0) portDie("M2"); // portDie(MSG_UI_CANNOT_ALLOCATE, l + 1);
|
||||
for (v=0; v<l+1; v++) newGame->filename[v] = filename[v];
|
||||
newGame->filesize = size;
|
||||
newGame->filenameLen = l;
|
||||
|
@ -154,7 +154,7 @@ void uiFileAdd(char *filename, uint32_t size) {
|
|||
}
|
||||
|
||||
|
||||
void uiGameSelect(void) {
|
||||
CODE_BLOCK(8) void uiGameSelect(void) {
|
||||
byte x;
|
||||
byte y;
|
||||
byte h;
|
||||
|
@ -162,6 +162,7 @@ void uiGameSelect(void) {
|
|||
byte l;
|
||||
uint16_t i;
|
||||
fileListT *g;
|
||||
fileListT *t;
|
||||
byte c;
|
||||
uint16_t top;
|
||||
uint16_t selector;
|
||||
|
@ -261,13 +262,23 @@ void uiGameSelect(void) {
|
|||
_saveName[_selected->filenameLen ] = 'v';
|
||||
_saveName[_selected->filenameLen + 1] = 0;
|
||||
|
||||
// Dump game list, except selected game.
|
||||
g = _games;
|
||||
while (g) {
|
||||
if (g == _selected) {
|
||||
g = g->next;
|
||||
} else {
|
||||
portFree(g->filename);
|
||||
t = g;
|
||||
g = g->next;
|
||||
portFree(t);
|
||||
}
|
||||
}
|
||||
|
||||
// Get ready.
|
||||
stateReset();
|
||||
// uiStringPrint("stateReset()\n");
|
||||
portStoryLoad(_selected->filename, &_selected->filesize);
|
||||
// uiStringPrint("portStoryLoad()\n");
|
||||
storyChecksumCalculate();
|
||||
// uiStringPrint("storyChecksumCalculate()\n");
|
||||
opcodesSetup();
|
||||
storySetup();
|
||||
|
||||
|
@ -281,6 +292,11 @@ void uiGameSelect(void) {
|
|||
|
||||
// Start the game!
|
||||
interpreterRun();
|
||||
|
||||
// Free selected game info.
|
||||
portFree(_selected->filename);
|
||||
portFree(_selected);
|
||||
portFree(_saveName);
|
||||
}
|
||||
|
||||
|
||||
|
@ -295,7 +311,7 @@ void uiSizeGet(byte *w, byte *h) {
|
|||
}
|
||||
|
||||
|
||||
void uiSizeSet(byte w, byte h) {
|
||||
CODE_BLOCK(8) void uiSizeSet(byte w, byte h) {
|
||||
_screenWidth = w;
|
||||
_screenHeight = h;
|
||||
}
|
||||
|
@ -311,13 +327,13 @@ uint32_t uiStorySizeGet(void) {
|
|||
}
|
||||
|
||||
|
||||
static void uiStringPrint(char *s) {
|
||||
CODE_BLOCK(8) static void uiStringPrint(char *s) {
|
||||
byte i = 0;
|
||||
while (s[i] != 0) portCharPrint(s[i++]);
|
||||
}
|
||||
|
||||
|
||||
static void uiTitleDraw(void) {
|
||||
CODE_BLOCK(8) static void uiTitleDraw(void) {
|
||||
|
||||
portColorSet(9, 0);
|
||||
portScreenClear();
|
||||
|
|
|
@ -60,7 +60,7 @@ uint8_t variableAddress(uint8_t var, bool writing) {
|
|||
if (var == 0) {
|
||||
if (writing) {
|
||||
|
||||
if (__state.sp >= sizeof(__state.stack)) portDie(MSG_INT_STACK_OVERFLOW);
|
||||
if (__state.sp >= STACK_SIZE) portDie(MSG_VAR_STACK_OVERFLOW);
|
||||
#ifdef DEBUGGINGx
|
||||
printf("Push stack\n");
|
||||
#endif
|
||||
|
@ -68,9 +68,9 @@ uint8_t variableAddress(uint8_t var, bool writing) {
|
|||
|
||||
} else {
|
||||
|
||||
if (__state.sp == 0) portDie(MSG_INT_STACK_UNDERFLOW);
|
||||
if (__state.sp == 0) portDie(MSG_VAR_STACK_UNDERFLOW);
|
||||
numLocals = __state.bp ? __state.stack[__state.bp - 1] : 0;
|
||||
if ((__state.bp + numLocals) >= sizeof(__state.stack)) portDie(MSG_INT_STACK_UNDERFLOW);
|
||||
if ((__state.bp + numLocals) >= STACK_SIZE) portDie(MSG_VAR_STACK_UNDERFLOW);
|
||||
#ifdef DEBUGGINGx
|
||||
printf("Pop stack\n");
|
||||
#endif
|
||||
|
@ -81,7 +81,7 @@ uint8_t variableAddress(uint8_t var, bool writing) {
|
|||
|
||||
// Local var.
|
||||
if ((var >= 0x1) && (var <= 0xf)) {
|
||||
if (__state.stack[__state.bp - 1] <= (var - 1)) portDie(MSG_INT_REF_UNALLOCATED_LOCAL);
|
||||
if (__state.stack[__state.bp - 1] <= (var - 1)) portDie(MSG_VAR_REF_UNALLOCATED_LOCAL);
|
||||
return __state.bp + (var - 1);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue