Skip to content

Instantly share code, notes, and snippets.

@lpproj
Created September 6, 2025 11:23
Show Gist options
  • Save lpproj/7f42ba172f890bb408ef3afaed89f402 to your computer and use it in GitHub Desktop.
Save lpproj/7f42ba172f890bb408ef3afaed89f402 to your computer and use it in GitHub Desktop.
patch against Microsoft BASIC M6502 C-port edition (https://github.com/YosAwed/M6502)
* remove nested funciton feature for generic C99 (OpenWatcom, clang)
* configurable virtual memory size for PEEK/POKE (mostly for 16bit environment)
to build 16bit MS-DOS executable with OpenWatcom v2 beta and GNUmake:
make CC="owcc -b dos -mcmodel=l -mstack-size=4096"
diff --git a/basic.h b/basic.h
index d7e39e8..efe8406 100644
--- a/basic.h
+++ b/basic.h
@@ -1,6 +1,7 @@
#ifndef BASIC_H
#define BASIC_H
+#include <limits.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
@@ -8,6 +9,15 @@
#include <string.h>
#include <math.h>
+#ifndef VIRTUAL_MEMORY_MAX
+// quick check 16 or 32+bits platform
+#if UINT_MAX <= 65535U
+#define VIRTUAL_MEMORY_MAX 4096
+#else
+#define VIRTUAL_MEMORY_MAX 65536
+#endif
+#endif
+
// バージョン情報
#define BASIC_VERSION_MAJOR 1
#define BASIC_VERSION_MINOR 1
diff --git a/parser.c b/parser.c
index 55fe414..5304403 100644
--- a/parser.c
+++ b/parser.c
@@ -425,11 +425,17 @@ int basic_execute_line(basic_state_t* state, const char* line) {
return 0;
}
+
+#ifndef USE_NESTED_FUNCTIONS
+#define USE_NESTED_FUNCTIONS (defined(__GNUC__))
+#endif
+
int cmd_print(basic_state_t* state, parser_state_t* parser) {
bool trailing_semicolon = false;
bool first = true;
const int zone = 14; // Microsoft BASIC print zone width
+#if USE_NESTED_FUNCTIONS
// local helper to output and track terminal column
auto void put_text_and_track(const char* s) {
if (!s) return;
@@ -444,6 +450,19 @@ int cmd_print(basic_state_t* state, parser_state_t* parser) {
for (int i = 0; i < n; i++) putchar(' ');
state->trmpos = (uint8_t)((state->trmpos + (unsigned)n) % 255);
};
+#else
+ #define put_text_and_track(s) \
+ if ((s) != NULL) do { \
+ fputs(s, stdout); \
+ state->trmpos = (uint8_t)((state->trmpos + (unsigned)strlen(s)) % 255); \
+ } while(0)
+
+ #define put_spaces_and_track(n) \
+ if ((n) > 0) do { \
+ for (int i = 0; i < n; i++) putchar(' '); \
+ state->trmpos = (uint8_t)((state->trmpos + (unsigned)(n)) % 255); \
+ } while(0)
+#endif
while (1) {
// Allow bare EOL
uint16_t pos0 = parser->position;
diff --git a/system_functions.c b/system_functions.c
index 840a0f0..d67e287 100644
--- a/system_functions.c
+++ b/system_functions.c
@@ -11,7 +11,7 @@ extern token_t get_next_token(basic_state_t* state, parser_state_t* parser);
extern eval_result_t evaluate_expression(basic_state_t* state, parser_state_t* parser);
// 仮想メモリ(元の6502メモリをシミュレート)
-static uint8_t virtual_memory[65536];
+static uint8_t virtual_memory[VIRTUAL_MEMORY_MAX];
static bool memory_initialized = false;
// メモリ初期化
@@ -25,6 +25,9 @@ void init_virtual_memory(void) {
// PEEK関数 - メモリ読み取り
numeric_value_t func_peek(uint16_t address) {
init_virtual_memory();
+#if VIRTUAL_MEMORY_MAX < (UINT16_MAX)
+ if (address >= VIRTUAL_MEMORY_MAX) return double_to_numeric(255.0);
+#endif
return double_to_numeric((double)virtual_memory[address]);
}
@@ -52,6 +55,9 @@ int cmd_poke(basic_state_t* state, parser_state_t* parser_ptr) {
uint16_t address = (uint16_t)numeric_to_double(addr_result.value.num);
uint8_t value = (uint8_t)numeric_to_double(value_result.value.num);
+#if VIRTUAL_MEMORY_MAX < (UINT16_MAX)
+ if (address >= VIRTUAL_MEMORY_MAX) return 0;
+#endif
init_virtual_memory();
virtual_memory[address] = value;
@@ -327,11 +333,12 @@ int cmd_wait(basic_state_t* state, parser_state_t* parser_ptr) {
// 条件を満たしている場合は即座に復帰
return 0;
}
-
+
+#if defined(__unix__) || defined(__MINGW64_VERSION_MAJOR) || (defined(HAVE_NANOSLEEP) && (HAVE_NANOSLEEP))
// 簡易実装:短時間待機
struct timespec ts = {0, 10000000}; // 10ms
nanosleep(&ts, NULL);
-
+#endif
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment