F256 port working. Still needs status bar. Dev port broken.

This commit is contained in:
Scott Duensing 2024-02-03 17:24:13 -06:00
parent e750c41ba6
commit f491abb894
16 changed files with 240 additions and 72 deletions

View file

@ -24,6 +24,7 @@ set(HEADERS
state.h
stddclmr.h
story.h
text.h
variable.h
zscii.h
# czech.z3.h
@ -50,6 +51,7 @@ set(SOURCE
portme.c
state.c
story.c
text.c
variable.c
zscii.c
)
@ -58,6 +60,8 @@ list(TRANSFORM SOURCE PREPEND "${CMAKE_CURRENT_SOURCE_DIR}/src/")
add_executable(${CMAKE_PROJECT_NAME}
${HEADERS}
${SOURCE}
src/text.c
include/text.h
)
target_include_directories(${CMAKE_PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)

View file

@ -28,7 +28,9 @@
#include <stdint.h>
#define DEBUGGING
//#define DEBUGGING
#define STACK_SIZE 2048 //***TODO*** How big does this really need to be? Old games are 1024, new...?
#ifdef DEBUGGING

View file

@ -28,17 +28,19 @@
#include "common.h"
uint8_t portByteGet(uint16_t address);
void portByteSet(uint16_t address, uint8_t value);
uint8_t portByteGet(uint32_t address);
void portByteSet(uint32_t address, uint8_t value);
void portCharPrint(char c);
char portCharGet(void);
void portCharGetPos(byte *x, byte *y);
void portCharSetPos(byte x, byte y);
void portDie(char *fmt, ...);
bool portFileRestore(void);
bool portFileSave(void);
void portInput(uint32_t ramAddr, uint8_t length);
uint16_t portRandomGet(int16_t range);
void portStoryLoad(void);
uint16_t portWordGet(uint16_t address);
void portWordSet(uint16_t address, uint16_t value);
uint16_t portWordGet(uint32_t address);
void portWordSet(uint32_t address, uint16_t value);
#endif // PORTME_H

View file

@ -30,7 +30,7 @@
typedef struct stateS {
uint16_t stack[2048]; //***TODO*** How big does this really need to be? Old games are 1024, new...?
uint16_t stack[STACK_SIZE];
bool quit;
uint32_t pc; // Program Counter
uint16_t sp; // Stack Pointer

View file

@ -117,8 +117,8 @@
#define storyHXTrueDefaultBackgroundColor() portWordGet(storyHeaderExtensionTableAddress() + 12)
uint32_t storyLength();
void storySetup(void);
uint32_t storyLength(void);
void storySetup(byte width, byte height);
#endif // STORY_H

35
include/text.h Normal file
View file

@ -0,0 +1,35 @@
/*
* Copyright (c) 2024 Scott Duensing, scott@kangaroopunch.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef TEXT_H
#define TEXT_H
#include "common.h"
void textCharPrint(char c);
void textInput(uint32_t ramAddr, uint8_t length);
#endif // TEXT_H

View file

@ -24,6 +24,7 @@ set(HEADERS
state.h
stddclmr.h
story.h
text.h
variable.h
zscii.h
# czech.z3.h
@ -49,6 +50,7 @@ set(SOURCE
opcodes.c
state.c
story.c
text.c
variable.c
zscii.c
)

View file

@ -47,16 +47,27 @@
#define BASE_ADDRESS 0x10000
uint8_t portByteGet(uint16_t address) {
uint8_t portByteGet(uint32_t address) {
return FAR_PEEK(BASE_ADDRESS + address);
}
void portByteSet(uint16_t address, uint8_t value) {
void portByteSet(uint32_t address, uint8_t value) {
FAR_POKE(BASE_ADDRESS + address, value);
}
void portCharGetPos(byte *x, byte *y) {
byte tx;
byte ty;
textGetXY(&tx, &ty);
// ZIP uses 1-based coordinates.
*x = tx + 1;
*y = ty + 1;
}
void portCharPrint(char c) {
static char ch[2] = { 0, 0 };
ch[0] = c;
@ -64,6 +75,12 @@ void portCharPrint(char c) {
}
void portCharSetPos(byte x, byte y) {
// ZIP uses 1-based coordinates.
textGotoXY(x - 1, y - 1);
}
void portDie(char *fmt, ...) {
#ifdef DEBUGGING
printf("%s\n", fmt); // Yeah, this isn't right.
@ -135,39 +152,8 @@ bool portFileSave(void) {
}
void portInput(uint32_t ramAddr, uint8_t length) {
uint8_t i;
char c[2] = { 0, 0 };
byte x;
byte y;
for (i=0; i<length; i++) {
c[0] = getchar();
// Delete/Backspace.
if ((c[0] == 8) || (c[0] == 127)) {
if (i > 0) {
textGetXY(&x, &y);
if (x > 0) {
x--;
} else {
x = 0;
y--;
}
textGotoXY(x, y);
textPrint(" ");
textGotoXY(x, y);
i--;
}
} else {
ZPOKE(ramAddr + i, c[0]);
// Enter/Return.
if ((c[0] == 13) || (c[0] == 10)) {
textPrint("\n");
break;
}
textPrint(c);
}
}
char portCharGet(void) {
return getchar();
}
@ -188,28 +174,20 @@ uint16_t portRandomGet(int16_t range) {
void portStoryLoad(void) {
// On the F256, the story is loaded into RAM along with the ZIP.
// Later, we probably want to see if the user has a memory expansion
// installed. If they do, we can use it and then use the lower memory
// for graphics and sound.
ZPOKE(STORY_SCREEN_WIDTH_CHARACTERS, 80);
ZPOKE(STORY_SCREEN_HEIGHT_LINES, 30);
// Currently no status bar.
ZPOKE(STORY_FLAG_V3, ZPEEK(STORY_FLAG_V3) | STORY_FLAG_V3_STATUS_LINE_NOT_AVAILABLE);
// Uncomment for status bar and window splitting.
//POKE(STORY_FLAG_V3, PEEK(STORY_FLAG_V3) & ~STORY_FLAG_V3_STATUS_LINE_NOT_AVAILABLE);
//POKE(STORY_FLAG_V3, PEEK(STORY_FLAG_V3) | STORY_FLAG_V3_SCREEN_SPLITTING);
}
uint16_t portWordGet(uint16_t address) {
uint16_t portWordGet(uint32_t address) {
return SWAP_UINT16(FAR_PEEKW(BASE_ADDRESS + address));
}
void portWordSet(uint16_t address, uint16_t value) {
void portWordSet(uint32_t address, uint16_t value) {
FAR_POKEW(BASE_ADDRESS + address, SWAP_UINT16(value));
}
@ -223,7 +201,7 @@ int main(void) {
stateReset();
portStoryLoad();
opcodesSetup();
storySetup();
storySetup(80, 30);
interpreterRun();
return 0;

View file

@ -39,5 +39,6 @@
#include "../src/opcodes.c"
#include "../src/state.c"
#include "../src/story.c"
#include "../src/text.c"
#include "../src/variable.c"
#include "../src/zscii.c"

View file

@ -27,6 +27,7 @@
#include "memory.h"
#include "messages.h"
#include "interpreter.h"
#include "text.h"
void opcodes_read(void) {
@ -45,7 +46,7 @@ void opcodes_read(void) {
interpreterUpdateStatusBar();
// Read input from user.
portInput(input, inputLen);
textInput(input, inputLen);
#ifdef DEBUGGING
printf("Input: [");

View file

@ -30,10 +30,11 @@
#include "object.h"
#include "messages.h"
#include "interpreter.h"
#include "text.h"
void opcodes_new_line(void) {
portCharPrint('\n');
textCharPrint('\n');
}
@ -49,7 +50,7 @@ void opcodes_print_addr(void) {
void opcodes_print_char(void) {
char c = zsciiDecodeChar(__state.operands[0]);
if (c) portCharPrint(c);
if (c) textCharPrint(c);
}
@ -59,7 +60,7 @@ void opcodes_print_num_r(int32_t val) {
opcodes_print_num_r(val / 10);
}
portCharPrint('0' + (val % 10));
textCharPrint('0' + (val % 10));
}
@ -67,7 +68,7 @@ void opcodes_print_num(void) {
int32_t n = (int16_t)__state.operands[0];
if (n < 0) {
portCharPrint('-');
textCharPrint('-');
n = -n;
}
opcodes_print_num_r(n);
@ -97,6 +98,6 @@ void opcodes_print_paddr(void) {
void opcodes_print_ret(void) {
__state.pc += zsciiPrint(__state.pc, 0);
portCharPrint('\n');
textCharPrint('\n');
interpreterDoReturn(1);
}

View file

@ -27,6 +27,7 @@
#include "portme.h"
#include "story.h"
#include "opcodes.h"
#include "memory.h"
void opcodes_save(void) {
@ -35,10 +36,13 @@ void opcodes_save(void) {
void opcodes_restart(void) {
byte width = ZPEEK(STORY_SCREEN_WIDTH_CHARACTERS);
byte height = ZPEEK(STORY_SCREEN_HEIGHT_LINES);
stateReset();
portStoryLoad();
opcodesSetup();
storySetup();
storySetup(width, height);
}

View file

@ -42,12 +42,12 @@
static uint8_t _RAM[1024 * (512 - 64)];
uint8_t portByteGet(uint16_t address) {
uint8_t portByteGet(uint32_t address) {
return _RAM[address];
}
void portByteSet(uint16_t address, uint8_t value) {
void portByteSet(uint32_t address, uint8_t value) {
_RAM[address] = value;
}
@ -148,7 +148,7 @@ void portInput(uint32_t ramAddr, uint8_t length) {
if ((c == 8) || (c == 127)) {
if (i > 0) {
printf("\b \b");
i--;
i -=2;
}
} else {
ZPOKE(ramAddr + i, c);
@ -191,12 +191,12 @@ void portStoryLoad(void) {
}
uint16_t portWordGet(uint16_t address) {
uint16_t portWordGet(uint32_t address) {
return ((uint16_t)_RAM[address] << 8) | ((uint16_t)_RAM[address + 1]);
}
void portWordSet(uint16_t address, uint16_t value) {
void portWordSet(uint32_t address, uint16_t value) {
_RAM[address] = (value >> 8) & 0xff; // MSB first.
_RAM[address + 1] = value & 0xff;
}

View file

@ -23,6 +23,7 @@
#include "story.h"
#include "state.h"
#include "memory.h"
uint32_t storyLength() {
@ -40,10 +41,20 @@ uint32_t storyLength() {
}
void storySetup(void) {
void storySetup(byte width, byte height) {
char *p;
uint16_t i;
ZPOKE(STORY_SCREEN_WIDTH_CHARACTERS, width);
ZPOKE(STORY_SCREEN_HEIGHT_LINES, height);
// Currently no status bar.
ZPOKE(STORY_FLAG_V3, ZPEEK(STORY_FLAG_V3) | STORY_FLAG_V3_STATUS_LINE_NOT_AVAILABLE);
// Uncomment for status bar and window splitting.
//POKE(STORY_FLAG_V3, PEEK(STORY_FLAG_V3) & ~STORY_FLAG_V3_STATUS_LINE_NOT_AVAILABLE);
//POKE(STORY_FLAG_V3, PEEK(STORY_FLAG_V3) | STORY_FLAG_V3_SCREEN_SPLITTING);
// V6+ this is the address of main(), not just a raw starting address.
__state.pc = storyInitialPC();
__state.sp = 0;

126
src/text.c Normal file
View file

@ -0,0 +1,126 @@
/*
* Copyright (c) 2024 Scott Duensing, scott@kangaroopunch.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "text.h"
#include "portme.h"
#include "memory.h"
#include "story.h"
void textCharPrint(char c) {
static char lineBuffer[256];
static uint16_t lineWidth = 0;
byte width = ZPEEK(STORY_SCREEN_WIDTH_CHARACTERS);
byte height = ZPEEK(STORY_SCREEN_HEIGHT_LINES);
byte space;
byte i;
byte x;
byte y;
// Do we need to word wrap?
if (lineWidth == width - 1) {
// Are we printing a space or CR? If so, just go to next line.
if ((c == ' ') || (c == '\n')) {
c = '\n';
} else {
// Scan the line backwards for the first space.
for (space=lineWidth-1; space>0; space--) {
if (lineBuffer[space] == ' ') break;
}
// Did we find a space?
if (space == 0) {
// No. Just wrap.
portCharPrint('\n');
lineWidth = 0;
} else {
// Move to after space.
space++;
// Erase text to move to next line from this line.
portCharGetPos(&x, &y);
portCharSetPos(space, y);
for (i=space; i<=lineWidth; i++) {
portCharPrint(' ');
}
// Wrap display.
portCharPrint('\n');
// Move erased characters to front of buffer & redisplay.
portCharGetPos(&x, &y);
portCharSetPos(1, y);
x = 0;
for (i=space; i<=lineWidth; i++) {
lineBuffer[x++] = lineBuffer[i];
portCharPrint(lineBuffer[i]);
}
// Wrap buffer.
lineWidth = 0;
}
}
}
// Display it.
portCharPrint(c);
// Update buffer.
if (c == '\n') {
// New line.
lineWidth = 0;
} else {
lineBuffer[lineWidth++] = c;
}
}
void textInput(uint32_t ramAddr, uint8_t length) {
uint8_t i;
char c;
byte x;
byte y;
for (i=0; i<length; i++) {
c = portCharGet();
// Delete/Backspace.
if ((c == 8) || (c == 127)) {
if (i > 0) {
portCharGetPos(&x, &y);
if (x > 1) {
x--;
} else {
x = 1;
y--;
}
portCharSetPos(x, y);
portCharPrint(' ');
portCharSetPos(x, y);
i -= 2;
}
} else {
ZPOKE(ramAddr + i, c);
// Enter/Return.
if ((c == 13) || (c == 10)) {
portCharPrint('\n');
break;
}
portCharPrint(c);
}
}
}

View file

@ -27,6 +27,7 @@
#include "story.h"
#include "state.h"
#include "memory.h"
#include "text.h"
char zsciiDecodeChar(uint16_t z) {
@ -87,7 +88,7 @@ uint32_t zsciiPrint(uint32_t zstr, bool abbr) {
printVal = zsciiDecodeChar(zsciiCode);
if (printVal) {
decodedChars++;
portCharPrint(printVal);
textCharPrint(printVal);
}
alphabet = 0;
useAbbrTable = 0;
@ -157,7 +158,7 @@ uint32_t zsciiPrint(uint32_t zstr, bool abbr) {
if (printVal) {
decodedChars++;
portCharPrint(printVal);
textCharPrint(printVal);
}
if (alphabet && !newShift) alphabet = 0;