Skip to content

Commit d64d602

Browse files
committed
spectranext: implement launcher
1 parent f95740a commit d64d602

8 files changed

Lines changed: 129 additions & 0 deletions

File tree

fusepb/FuseX.xcodeproj/project.pbxproj

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,8 @@
307307
FE2DAC7B2F32A500009AC45A /* httpc.c in Sources */ = {isa = PBXBuildFile; fileRef = FE2DAC7A2F32A500009AC45A /* httpc.c */; };
308308
FE2DAC802F32AB6C009AC45A /* vfile_ext.c in Sources */ = {isa = PBXBuildFile; fileRef = FE2DAC7F2F32AB6C009AC45A /* vfile_ext.c */; };
309309
FE2DAC812F32AB6C009AC45A /* vfile.c in Sources */ = {isa = PBXBuildFile; fileRef = FE2DAC7D2F32AB6C009AC45A /* vfile.c */; };
310+
FE3079E82FC4F69E0044EB9A /* boot.zx in Resources */ = {isa = PBXBuildFile; fileRef = FE3079E52FC4F69E0044EB9A /* boot.zx */; };
311+
FE3079E92FC4F69E0044EB9A /* launcher.bin in Resources */ = {isa = PBXBuildFile; fileRef = FE3079E62FC4F69E0044EB9A /* launcher.bin */; };
310312
FE3FF185294F1220009F571F /* spectranet.rom in Resources */ = {isa = PBXBuildFile; fileRef = FE3FF184294F1220009F571F /* spectranet.rom */; };
311313
FE9443BC2F881C540059A578 /* engine_argv.c in Sources */ = {isa = PBXBuildFile; fileRef = FE9443B72F881C540059A578 /* engine_argv.c */; };
312314
FE9443BD2F881C540059A578 /* lexer.c in Sources */ = {isa = PBXBuildFile; fileRef = FE9443B02F881C540059A578 /* lexer.c */; };
@@ -896,6 +898,8 @@
896898
FE2DAC7D2F32AB6C009AC45A /* vfile.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = vfile.c; sourceTree = "<group>"; };
897899
FE2DAC7E2F32AB6C009AC45A /* vfile_ext.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = vfile_ext.h; sourceTree = "<group>"; };
898900
FE2DAC7F2F32AB6C009AC45A /* vfile_ext.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = vfile_ext.c; sourceTree = "<group>"; };
901+
FE3079E52FC4F69E0044EB9A /* boot.zx */ = {isa = PBXFileReference; lastKnownFileType = file; path = boot.zx; sourceTree = "<group>"; };
902+
FE3079E62FC4F69E0044EB9A /* launcher.bin */ = {isa = PBXFileReference; lastKnownFileType = archive.macbinary; path = launcher.bin; sourceTree = "<group>"; };
899903
FE3FF184294F1220009F571F /* spectranet.rom */ = {isa = PBXFileReference; lastKnownFileType = file; name = spectranet.rom; path = ../roms/spectranet.rom; sourceTree = "<group>"; };
900904
FE9443AD2F881C540059A578 /* ast.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ast.h; sourceTree = "<group>"; };
901905
FE9443AE2F881C540059A578 /* ast.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = ast.c; sourceTree = "<group>"; };
@@ -1656,6 +1660,7 @@
16561660
F559854A038920FD01A804BA /* roms */ = {
16571661
isa = PBXGroup;
16581662
children = (
1663+
FE3079E72FC4F69E0044EB9A /* spectranext-launcher */,
16591664
FE3FF184294F1220009F571F /* spectranet.rom */,
16601665
F559854D0389212301A804BA /* 128-0.rom */,
16611666
F559854E0389212301A804BA /* 128-1.rom */,
@@ -1802,6 +1807,16 @@
18021807
path = http;
18031808
sourceTree = "<group>";
18041809
};
1810+
FE3079E72FC4F69E0044EB9A /* spectranext-launcher */ = {
1811+
isa = PBXGroup;
1812+
children = (
1813+
FE3079E52FC4F69E0044EB9A /* boot.zx */,
1814+
FE3079E62FC4F69E0044EB9A /* launcher.bin */,
1815+
);
1816+
name = "spectranext-launcher";
1817+
path = "../roms/spectranext-launcher";
1818+
sourceTree = SOURCE_ROOT;
1819+
};
18051820
FE9443B52F881C540059A578 /* jsonpath */ = {
18061821
isa = PBXGroup;
18071822
children = (
@@ -1982,6 +1997,8 @@
19821997
B61F462F09121DF100C8096C /* tap.icns in Resources */,
19831998
B61F463009121DF100C8096C /* trd.icns in Resources */,
19841999
B61F463109121DF100C8096C /* tzx.icns in Resources */,
2000+
FE3079E82FC4F69E0044EB9A /* boot.zx in Resources */,
2001+
FE3079E92FC4F69E0044EB9A /* launcher.bin in Resources */,
19852002
B61F463209121DF100C8096C /* z80.icns in Resources */,
19862003
B6F0481B0952B5FD006D8005 /* zxs.icns in Resources */,
19872004
FE3FF185294F1220009F571F /* spectranet.rom in Resources */,

peripherals/fs/xfs_worker.c

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "memory_pages.h"
2020
#include "ui/ui.h"
2121
#include "compat.h"
22+
#include "utils.h"
2223

2324
volatile struct xfs_registers_t xfs_registers = {};
2425

@@ -42,6 +43,44 @@ bool xfs_debug_is_enabled(void)
4243
// XFS base directory path
4344
char xfs_base_path[512];
4445

46+
static int xfs_copy_spectranext_launcher_file(const char *filename)
47+
{
48+
char source_name[PATH_MAX];
49+
char destination_path[PATH_MAX];
50+
utils_file source_file;
51+
52+
if (snprintf(source_name, sizeof(source_name), "spectranext-launcher/%s", filename) >=
53+
(int)sizeof(source_name))
54+
return 1;
55+
56+
if (snprintf(destination_path, sizeof(destination_path), "%s" FUSE_DIR_SEP_STR "%s",
57+
xfs_base_path, filename) >= (int)sizeof(destination_path))
58+
return 1;
59+
60+
if (utils_read_auxiliary_file(source_name, &source_file, UTILS_AUXILIARY_ROM) != 0 &&
61+
utils_read_auxiliary_file(filename, &source_file, UTILS_AUXILIARY_ROM) != 0)
62+
return 1;
63+
64+
const int error = utils_write_file(destination_path, source_file.buffer, source_file.length);
65+
utils_close_file(&source_file);
66+
return error;
67+
}
68+
69+
static void xfs_seed_spectranext_launcher_files(void)
70+
{
71+
char boot_path[PATH_MAX];
72+
73+
if (snprintf(boot_path, sizeof(boot_path), "%s" FUSE_DIR_SEP_STR "boot.zx", xfs_base_path) >=
74+
(int)sizeof(boot_path))
75+
return;
76+
77+
if (compat_file_exists(boot_path))
78+
return;
79+
80+
xfs_copy_spectranext_launcher_file("boot.zx");
81+
xfs_copy_spectranext_launcher_file("launcher.bin");
82+
}
83+
4584
void xfs_init()
4685
{
4786
snprintf(xfs_base_path, sizeof(xfs_base_path), "%s/xfs", compat_get_config_path());
@@ -56,6 +95,7 @@ void xfs_init()
5695
ui_error( UI_ERROR_WARNING, "xfs: failed to create xfs directory: %s\n", strerror(errno) );
5796
}
5897

98+
xfs_seed_spectranext_launcher_files();
5999
XFS_DEBUG("xfs: initialized with base path: %s\n", xfs_base_path ? xfs_base_path : "(null)");
60100
}
61101

peripherals/nic/spectranext.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ enum spectranext_cmd_t
1717
SPECTRANEXT_CMD_WIFI_DISCONNECT = 4,
1818
SPECTRANEXT_CMD_DNS_GETHOSTBYNAME = 5,
1919
SPECTRANEXT_CMD_ENGINECALL = 6,
20+
SPECTRANEXT_CMD_GET_MESSAGE = 7,
2021
};
2122

2223
#define WIFI_CONTROLLER_STATUS_OFFLINE (0u)
@@ -43,6 +44,8 @@ enum spectranext_cmd_t
4344

4445
#define SPECTRANEXT_SCAN_AP_MAX 64
4546

47+
#define SPECTRANEXT_MESSAGE_MAX 128
48+
4649
#define SPECTRANEXT_CMD_REG_IDLE 0xFFu
4750

4851
#pragma pack(push, 1)
@@ -129,6 +132,15 @@ typedef union spectranext_workspace
129132
} io;
130133
} enginecall;
131134

135+
struct
136+
{
137+
struct
138+
{
139+
char message[SPECTRANEXT_MESSAGE_MAX];
140+
uint8_t pending;
141+
} out;
142+
} get_message;
143+
132144
char page[4096 - 2];
133145
} spectranext_workspace_t;
134146

peripherals/nic/spectranext_controller.c

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ spectranext_state_t spectranext_state = {
2929
static char scan_ap_names[SPECTRANEXT_SCAN_AP_MAX][64];
3030
static uint8_t scan_ap_count;
3131

32+
static char pending_message[SPECTRANEXT_MESSAGE_MAX];
33+
static bool message_pending;
34+
3235
volatile struct spectranext_controller_t spectranext_controller = {
3336
.command = SPECTRANEXT_CMD_REG_IDLE,
3437
.status = SPECTRANEXT_STATUS_SUCCESS,
@@ -57,6 +60,52 @@ static void spectranext_set_status(uint8_t status)
5760
spectranext_controller.status = status;
5861
}
5962

63+
bool spectranext_controller_post_message_bytes(const uint8_t *message, size_t length)
64+
{
65+
if (message == NULL && length != 0u)
66+
return false;
67+
68+
if (length >= SPECTRANEXT_MESSAGE_MAX)
69+
length = SPECTRANEXT_MESSAGE_MAX - 1u;
70+
71+
if (length != 0u)
72+
memcpy(pending_message, message, length);
73+
pending_message[length] = '\0';
74+
message_pending = true;
75+
76+
return true;
77+
}
78+
79+
bool spectranext_controller_post_message(const char *message)
80+
{
81+
if (message == NULL)
82+
return false;
83+
84+
return spectranext_controller_post_message_bytes((const uint8_t *)message, strlen(message));
85+
}
86+
87+
void spectranext_controller_clear_messages(void)
88+
{
89+
pending_message[0] = '\0';
90+
message_pending = false;
91+
}
92+
93+
static void spectranext_controller_get_message(void)
94+
{
95+
memset((void *)&spectranext_controller.workspace.get_message.out, 0,
96+
sizeof(spectranext_controller.workspace.get_message.out));
97+
98+
if (message_pending)
99+
{
100+
memcpy((void *)spectranext_controller.workspace.get_message.out.message, pending_message,
101+
sizeof(spectranext_controller.workspace.get_message.out.message));
102+
spectranext_controller.workspace.get_message.out.pending = 1u;
103+
spectranext_controller_clear_messages();
104+
}
105+
106+
spectranext_set_status(SPECTRANEXT_STATUS_SUCCESS);
107+
}
108+
60109
static void spectranext_controller_process_command(void)
61110
{
62111
const uint8_t cmd = spectranext_controller.command;
@@ -188,6 +237,10 @@ static void spectranext_controller_process_command(void)
188237
spectranext_set_status((uint8_t)(int8_t)spectranext_enginecall_args.result);
189238
break;
190239

240+
case SPECTRANEXT_CMD_GET_MESSAGE:
241+
spectranext_controller_get_message();
242+
break;
243+
191244
default:
192245
spectranext_set_status(SPECTRANEXT_STATUS_ERROR);
193246
break;
@@ -202,6 +255,7 @@ void spectranext_controller_init(void)
202255
spectranext_state.connection_status = WIFI_CONNECT_CONNECT_IP_OBTAINED;
203256
spectranext_state.ipv4_host = 0x7f000001u;
204257
scan_ap_count = 0;
258+
spectranext_controller_post_message("FuseX: OK\n");
205259
}
206260

207261
libspectrum_byte spectranext_controller_read(memory_page *page, libspectrum_word address)

peripherals/nic/spectranext_controller.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#pragma once
22

3+
#include <stdbool.h>
4+
#include <stddef.h>
35
#include <stdint.h>
46
#include "libspectrum.h"
57
#include "memory_pages.h"
@@ -9,5 +11,9 @@ extern volatile struct spectranext_controller_t spectranext_controller;
911

1012
extern void spectranext_controller_init(void);
1113

14+
bool spectranext_controller_post_message(const char *message);
15+
bool spectranext_controller_post_message_bytes(const uint8_t *message, size_t length);
16+
void spectranext_controller_clear_messages(void);
17+
1218
libspectrum_byte spectranext_controller_read(memory_page *page, libspectrum_word address);
1319
void spectranext_controller_write(memory_page *page, libspectrum_word address, libspectrum_byte b);

roms/spectranet.rom

0 Bytes
Binary file not shown.

roms/spectranext-launcher/boot.zx

82 Bytes
Binary file not shown.
5.28 KB
Binary file not shown.

0 commit comments

Comments
 (0)