F256 port working. Still needs status bar. Dev port broken.
This commit is contained in:
parent
e750c41ba6
commit
f491abb894
16 changed files with 240 additions and 72 deletions
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
35
include/text.h
Normal 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
|
|
@ -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
|
||||
)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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: [");
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
10
src/portme.c
10
src/portme.c
|
@ -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;
|
||||
}
|
||||
|
|
13
src/story.c
13
src/story.c
|
@ -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
126
src/text.c
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue