Compare commits

...

10 Commits

31 changed files with 621 additions and 137 deletions

1
.envrc 100644
View File

@ -0,0 +1 @@
use flake

View File

@ -12,56 +12,30 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: cachix/install-nix-action@v22
with:
submodules: true
github_access_token: ${{ secrets.GITHUB_TOKEN }}
- name: Download latest fox32asm artifact
uses: dawidd6/action-download-artifact@v2
with:
repo: fox32-arch/fox32asm
workflow: fox32asm-unstable-linux.yml
workflow_conclusion: success
- name: Build fox32os
run: nix build -L .#fox32os -o result-fox32os
- name: Download latest fox32rom artifact
uses: dawidd6/action-download-artifact@v2
with:
repo: fox32-arch/fox32rom
workflow: fox32rom-unstable.yml
workflow_conclusion: success
- name: Download latest tools artifact
uses: dawidd6/action-download-artifact@v2
with:
repo: fox32-arch/tools
workflow: tools-unstable-linux.yml
workflow_conclusion: success
- name: Install lua5.4
run: |
sudo apt update
sudo apt install -y lua5.4
- name: Build
run: |
mkdir ../fox32rom
cp fox32rom.def/fox32rom.def ../fox32rom/
chmod +x fox32asm/fox32asm gfx2inc/gfx2inc
make FOX32ASM=fox32asm/fox32asm GFX2INC=gfx2inc/gfx2inc
- name: Build fox32os-dev
run: nix build -L .#fox32os-dev -o result-fox32os-dev
- name: Upload fox32os.img
uses: actions/upload-artifact@v3
with:
name: fox32os.img
path: fox32os.img
path: result-fox32os/bin/fox32os.img
- name: Upload romdisk.img
uses: actions/upload-artifact@v3
with:
name: romdisk.img
path: romdisk.img
path: result-fox32os/bin/romdisk.img
- name: Upload fox32os.def
uses: actions/upload-artifact@v3
with:
name: fox32os.def
path: fox32os.def
path: result-fox32os-dev/dev/fox32os.def

6
.gitignore vendored
View File

@ -11,4 +11,8 @@
**/fox32os.img.tmp
**/romdisk.img
**/romdisk.img.tmp
**/startup.cfg
**/startup.bat
**/result
**/.direnv/
fox32rom/

View File

@ -1,7 +1,7 @@
RYFS := $(CURDIR)/meta/ryfs/ryfs.py
FOX32ASM := ../fox32asm/target/release/fox32asm
OKAMERON := $(CURDIR)/meta/okameron/okameron.lua
GFX2INC := ../tools/gfx2inc/target/release/gfx2inc
RYFS ?= $(CURDIR)/meta/ryfs/ryfs.py
FOX32ASM ?= $(CURDIR)fox32asm/target/release/fox32asm
OKAMERON ?= $(CURDIR)/meta/okameron/okameron.lua
GFX2INC ?= $(CURDIR)/tools/gfx2inc/target/release/gfx2inc
IMAGE_SIZE := 16777216
ROM_IMAGE_SIZE := 65536
@ -64,13 +64,13 @@ applications/launcher/icons.inc: applications/launcher/icons.png
bootloader/bootloader.bin: bootloader/main.asm $(wildcard bootloader/*.asm)
$(FOX32ASM) $< $@
base_image/startup.cfg: base_image/startup.cfg.default
base_image/startup.bat: base_image/startup.bat.default
cp $< $@
ICONS := \
applications/icons/cfg_icon.inc \
applications/icons/dsk_icon.inc \
applications/icons/fxf_icon.inc
applications/icons/dsk.inc \
applications/icons/fxf.inc \
applications/icons/msc.inc
applications/icons/%.inc: applications/icons/%.png
$(GFX2INC) 32 32 $< $@
@ -78,7 +78,7 @@ base_image/icons.res: applications/icons/icons.res.asm $(ICONS)
$(FOX32ASM) $< $@
FILES = \
base_image/startup.cfg \
base_image/startup.bat \
base_image/icons.res \
base_image/kernel.fxf \
base_image/sh.fxf \
@ -93,7 +93,7 @@ FILES = \
base_image/launcher.fxf
ROM_FILES = \
base_image/startup.cfg \
base_image/startup.bat \
base_image/icons.res \
base_image/kernel.fxf \
base_image/sh.fxf \

View File

@ -10,9 +10,9 @@ Stable releases are available on the [Releases page](https://github.com/fox32-ar
Prebuilt images of the latest commit are also available on the [GitHub Actions page](https://github.com/fox32-arch/fox32os/actions).
### Building
### Building (without nix)
- Download [tools](https://github.com/fox32-arch/tools) and [fox32asm](https://github.com/fox32-arch/fox32asm).
- Download [tools](https://github.com/fox32-arch/tools) and [fox32asm](https://github.com/fox32-arch/fox32asm) into the current directory.
Either use the pre-built binaries or build them.
- Run `make`

View File

@ -91,5 +91,5 @@ minute_less_than_10:
second_counter: data.8 0
active_window_struct_ptr: data.32 0
#include "../../../fox32rom/fox32rom.def"
#include "../../fox32rom/fox32rom.def"
#include "../../fox32os.def"

View File

@ -23,5 +23,5 @@
bg_file_name: data.strz "bg.raw"
bg_file_struct: data.fill 0, 32
#include "../../../fox32rom/fox32rom.def"
#include "../../fox32rom/fox32rom.def"
#include "../../fox32os.def"

View File

@ -1,5 +1,5 @@
MODULE About;
IMPORT OS;
IMPORT OS, Browser;
VAR aboutRunning: CHAR;
aboutWindow: ARRAY WINDOW_STRUCT_SIZE OF CHAR;
@ -26,11 +26,18 @@ MODULE About;
PROCEDURE DrawAboutWindow();
VAR overlay: INT;
tempAbtResPtr: PTR;
BEGIN
overlay := get_window_overlay_number(PTROF(aboutWindow));
fill_overlay(0FF674764H, overlay);
draw_str_to_overlay("fox32", 16, 16, 0FFFFFFFFH, 0FF674764H, overlay);
draw_str_to_overlay("the computer made with love", 16, 32, 0FFFFFFFFH, 0FF674764H, overlay);
draw_filled_rectangle_to_overlay(4, 56, 248, 2, 0FFFFFFFFH, overlay);
tempAbtResPtr := get_resource(browserIconsResPtr, "abt", 64);
IF tempAbtResPtr THEN
draw_str_to_overlay(tempAbtResPtr, 16, 176, 0FFFFFFFFH, 0FF674764H, overlay);
free_memory(tempAbtResPtr);
END;
END;
END.

View File

@ -148,6 +148,13 @@ MODULE Browser;
set_tilemap(tempFileIconResPtr, 32, 32);
draw_tile_to_overlay(0, icon^.x, icon^.y, overlay);
free_memory(tempFileIconResPtr);
ELSE
tempFileIconResPtr := get_resource(browserIconsResPtr, "msc", 4096);
IF tempFileIconResPtr THEN
set_tilemap(tempFileIconResPtr, 32, 32);
draw_tile_to_overlay(0, icon^.x, icon^.y, overlay);
free_memory(tempFileIconResPtr);
END;
END;
i := i + 1;
END;

View File

@ -23,8 +23,8 @@ MODULE Fetcher;
hasIcons := 1;
END;
IF (terminalStreamPtr = 0) & (arg0Ptr = 0) THEN
(* probably launched from startup.cfg *)
IF (CompareString("boot", arg0Ptr)) THEN
(* launched from startup.bat *)
DesktopMain(hasIcons, iconsRes);
ELSIF (CompareString("open", arg0Ptr)) & (arg1Ptr # 0) & (arg2Ptr # 0) THEN
(* launched from an application wanting to open a file *)

View File

@ -88,5 +88,5 @@ menu_items_system_list:
data.8 7 ; menu width (usually longest item + 2)
data.8 5 data.strz "About" ; text length, text, null-terminator
#include "../../../fox32rom/fox32rom.def"
#include "../../fox32rom/fox32rom.def"
#include "../../fox32os.def"

View File

@ -392,5 +392,5 @@ is_drawing: data.8 0
brush_size: data.8 4
color: data.32 0xFFFFFFFF
#include "../../../fox32rom/fox32rom.def"
#include "../../fox32rom/fox32rom.def"
#include "../../fox32os.def"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

View File

@ -1,16 +1,19 @@
const ICON_SIZE: 4096
; format: "RES" magic bytes, version, number of resource IDs
data.str "RES" data.8 0 data.8 3
data.str "RES" data.8 0 data.8 4
; format: 3 character null-terminated ID, pointer to data, size
data.strz "cfg" data.32 cfg_icon data.32 ICON_SIZE
data.strz "dsk" data.32 dsk_icon data.32 ICON_SIZE
data.strz "fxf" data.32 fxf_icon data.32 ICON_SIZE
data.strz "abt" data.32 abt data.32 20
data.strz "dsk" data.32 dsk data.32 ICON_SIZE
data.strz "fxf" data.32 fxf data.32 ICON_SIZE
data.strz "msc" data.32 msc data.32 ICON_SIZE
cfg_icon:
#include "cfg_icon.inc"
dsk_icon:
#include "dsk_icon.inc"
fxf_icon:
#include "fxf_icon.inc"
abt:
data.strz "icons by horsesnoot"
dsk:
#include "dsk.inc"
fxf:
#include "fxf.inc"
msc:
#include "msc.inc"

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

View File

@ -110,5 +110,5 @@ button_text: data.strz " "
icons:
#include "icons.inc"
#include "../../../fox32rom/fox32rom.def"
#include "../../fox32rom/fox32rom.def"
#include "../../fox32os.def"

View File

@ -65,5 +65,5 @@ menu_items_color_list:
data.8 5 data.strz "Green" ; text length, text, null-terminator
data.8 4 data.strz "Blue" ; text length, text, null-terminator
#include "../../../fox32rom/fox32rom.def"
#include "../../fox32rom/fox32rom.def"
#include "../../fox32os.def"

View File

@ -67,5 +67,5 @@ stream_write_special:
pop r0
ret
#include "../../../fox32rom/fox32rom.def"
#include "../../fox32rom/fox32rom.def"
#include "../../fox32os.def"

View File

@ -0,0 +1,54 @@
; batch file routines
; run a batch file whose name is pointed to by [shell_batch_filename_ptr]
; the batch file must end with `exit;`
; inputs:
; none
; outputs:
; none (does not return)
shell_run_batch:
; open the batch file
call get_current_disk_id
mov r1, r0
mov r0, [shell_batch_filename_ptr]
mov r2, shell_batch_file_struct
call open
cmp r0, 0
ifz jmp shell_run_batch_failed_to_open
shell_run_batch_next:
cmp.8 [shell_redirect_next], 0
ifnz mov [shell_stream_struct_ptr], [shell_old_stream_struct_ptr]
ifnz dec.8 [shell_redirect_next]
call shell_clear_buffer
shell_run_batch_loop:
; read a character from the file
mov r0, 1
mov r1, shell_batch_file_struct
mov r2, shell_batch_file_char_buffer
call read
; if it isn't a semicolon or linefeed, push it to the command buffer
; if it is a semicolon, run the command
movz.8 r0, [shell_batch_file_char_buffer]
cmp.8 r0, ';'
ifz jmp shell_run_batch_end_of_line
cmp.8 r0, 10
ifnz call shell_push_character
call yield_task
rjmp shell_run_batch_loop
shell_run_batch_end_of_line:
mov r0, 0
call shell_push_character
call shell_parse_line
rjmp shell_run_batch_next
shell_run_batch_failed_to_open:
mov r0, shell_run_batch_failed_to_open_string
call print_str_to_terminal
call end_current_task
shell_batch_file_struct: data.fill 0, 32
shell_batch_file_char_buffer: data.8 0
shell_run_batch_failed_to_open_string: data.str "failed to open batch file" data.8 10 data.8 0

View File

@ -15,13 +15,24 @@ launch_fxf:
call copy_memory_bytes
pop r0
launch_fxf_check_suspend_prefix:
; if the name was prefixed with a '*' character then
; clear a flag to have the shell return control immediately
cmp.8 [r0], '*'
ifnz mov.8 [launch_fxf_yield_should_suspend], 1
ifnz jmp launch_fxf_no_prefix
ifnz jmp launch_fxf_check_debug_prefix
inc r0
mov.8 [launch_fxf_yield_should_suspend], 0
jmp launch_fxf_no_prefix
launch_fxf_check_debug_prefix:
; if the name was prefixed with a '%' character then
; set a flag to cause a breakpoint at the beginning of the
; program
cmp.8 [r0], '%'
ifnz mov.8 [launch_fxf_debug_mode], 0
ifnz jmp launch_fxf_no_prefix
inc r0
mov.8 [launch_fxf_debug_mode], 1
launch_fxf_no_prefix:
; copy the name into the launch_fxf_name buffer
mov r1, launch_fxf_name
@ -66,6 +77,9 @@ launch_fxf_name_loop_done:
; push the argument pointers and terminal stream struct pointer to the task's stack
call shell_parse_arguments
mov r4, rsp
; disable interrupts, because if an interrupt tried to use the stack
; during this then that probably wouldn't end well
icl
mov rsp, [launch_fxf_stack_ptr]
add rsp, 65536 ; point to the end of the stack (stack grows down!!)
push r3
@ -73,13 +87,28 @@ launch_fxf_name_loop_done:
push r1
push r0
push [shell_stream_struct_ptr]
sub rsp, 65516
mov [launch_fxf_stack_ptr], rsp
; if we are in debug mode, push interrupt return info onto the stack
cmp.8 [launch_fxf_debug_mode], 0
ifz jmp launch_fxf_skip_push_reti_info
push 0 ; return address, will be filled in once we have start address
mov r1, rsp ; save address of return address to fill in later
push.8 0x04 ; enable interrupts upon return
push 0 ; don't care about exception parameter
launch_fxf_skip_push_reti_info:
mov rsp, r4
ise
; relocate the binary
mov r0, [launch_fxf_binary_ptr]
call parse_fxf_binary
; if we are in debug mode, fill in the return adress with the relocation
; address of the loaded binary
cmp.8 [launch_fxf_debug_mode], 0
ifz jmp launch_fxf_skip_fill_reti_addr
mov [r1], r0
; set initial ip to launch_fxf_debug_start
mov r0, launch_fxf_debug_start
launch_fxf_skip_fill_reti_addr:
; create a new task
mov r1, r0
@ -87,6 +116,9 @@ launch_fxf_name_loop_done:
mov.8 [launch_fxf_task_id], r0
mov r2, [launch_fxf_stack_ptr]
add r2, 65516 ; point to the end of the stack (stack grows down!!)
; if we are in debug mode, there are 9 extra bytes on top of the stack
cmp.8 [launch_fxf_debug_mode], 0
ifnz sub r2, 9
mov r3, [launch_fxf_binary_ptr]
mov r4, [launch_fxf_stack_ptr]
call new_task
@ -96,7 +128,8 @@ launch_fxf_name_loop_done:
; loop until the launched task ends
launch_fxf_yield_loop:
cmp.8 [launch_fxf_yield_should_suspend], 0
ifz jmp shell_task_return
ifz pop r0 ; pop our return addr off the stack so we return 2 levels up. this is cursed
ifz ret
movz.8 r0, [launch_fxf_task_id]
call is_task_id_used
ifz jmp shell_task_return
@ -108,6 +141,12 @@ allocate_error:
call print_str_to_terminal
ret
; entry point for a program started in debug mode
launch_fxf_debug_start:
icl
; jump indirect through system exception vector
jmp [0x00000410]
launch_fxf_name: data.str " fxf"
launch_fxf_spaces: data.str " "
launch_fxf_struct: data.fill 0, 32
@ -116,5 +155,6 @@ launch_fxf_binary_ptr: data.32 0
launch_fxf_stack_ptr: data.32 0
launch_fxf_yield_should_suspend: data.8 0
launch_fxf_debug_mode: data.8 0
out_of_memory_string: data.str "failed to allocate for new task!" data.8 10 data.8 0

View File

@ -9,9 +9,15 @@ const SET_COLOR: 0xF2
const REDRAW_LINE: 0xFE
pop [shell_stream_struct_ptr]
pop [shell_batch_filename_ptr]
cmp [shell_stream_struct_ptr], 0
ifz call end_current_task
; before dropping to an interactive prompt,
; check if an argument was passed
cmp [shell_batch_filename_ptr], 0
ifnz jmp shell_run_batch
shell_task_return:
cmp.8 [shell_redirect_next], 0
ifnz mov [shell_stream_struct_ptr], [shell_old_stream_struct_ptr]
@ -322,11 +328,13 @@ shell_stream_struct_ptr: data.32 0
shell_old_stream_struct_ptr: data.32 0
shell_redirect_next: data.8 0
shell_redirect_stream_struct: data.fill 0, 32
shell_batch_filename_ptr: data.32 0
shell_char_buffer: data.32 0
#include "batch.asm"
#include "commands/commands.asm"
#include "launch.asm"
; include system defs
#include "../../../fox32rom/fox32rom.def"
#include "../../fox32rom/fox32rom.def"
#include "../../fox32os.def"

View File

@ -140,5 +140,5 @@ stream_struct:
#include "text.asm"
; include system defs
#include "../../../fox32rom/fox32rom.def"
#include "../../fox32rom/fox32rom.def"
#include "../../fox32os.def"

View File

@ -0,0 +1,5 @@
*bg;
*barclock;
*fetcher boot;
*terminal;
exit;

View File

@ -1,4 +0,0 @@
bg fxf
barclockfxf
fetcher fxf
terminalfxf

327
flake.lock 100644
View File

@ -0,0 +1,327 @@
{
"nodes": {
"flake-utils": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1694529238,
"narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "ff7b65b44d01cf9ba6a71320833626af21126384",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"flake-utils_2": {
"inputs": {
"systems": "systems_2"
},
"locked": {
"lastModified": 1694529238,
"narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "ff7b65b44d01cf9ba6a71320833626af21126384",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"flake-utils_3": {
"inputs": {
"systems": "systems_3"
},
"locked": {
"lastModified": 1694529238,
"narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "ff7b65b44d01cf9ba6a71320833626af21126384",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"flake-utils_4": {
"inputs": {
"systems": "systems_4"
},
"locked": {
"lastModified": 1694529238,
"narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "ff7b65b44d01cf9ba6a71320833626af21126384",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"flake-utils_5": {
"inputs": {
"systems": "systems_5"
},
"locked": {
"lastModified": 1694529238,
"narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "ff7b65b44d01cf9ba6a71320833626af21126384",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"fox32asm": {
"inputs": {
"flake-utils": "flake-utils_2",
"nixpkgs": "nixpkgs"
},
"locked": {
"lastModified": 1707042298,
"narHash": "sha256-3sAOFd6y7Qrd/FTO/w+G4VfZeaScAoZFKY4IiVd8cqo=",
"ref": "refs/heads/main",
"rev": "4d8d3d1c48852f35031de2a37bc32766da2833f4",
"revCount": 68,
"type": "git",
"url": "https://githug.xyz/xenia/fox32asm"
},
"original": {
"type": "git",
"url": "https://githug.xyz/xenia/fox32asm"
}
},
"fox32asm_2": {
"inputs": {
"flake-utils": "flake-utils_4",
"nixpkgs": "nixpkgs_2"
},
"locked": {
"lastModified": 1707042298,
"narHash": "sha256-3sAOFd6y7Qrd/FTO/w+G4VfZeaScAoZFKY4IiVd8cqo=",
"ref": "refs/heads/main",
"rev": "4d8d3d1c48852f35031de2a37bc32766da2833f4",
"revCount": 68,
"type": "git",
"url": "https://githug.xyz/xenia/fox32asm"
},
"original": {
"type": "git",
"url": "https://githug.xyz/xenia/fox32asm"
}
},
"fox32rom": {
"inputs": {
"flake-utils": "flake-utils_3",
"fox32asm": "fox32asm_2",
"nixpkgs": "nixpkgs_3"
},
"locked": {
"lastModified": 1706972604,
"narHash": "sha256-r5R3aoFtrctpPoQIE3ynLet9L34WUFlj2PRSKRgQAYg=",
"ref": "refs/heads/main",
"rev": "f4a7e18b2803ff65eb4182a248028bef6cda7546",
"revCount": 181,
"type": "git",
"url": "https://githug.xyz/xenia/fox32rom"
},
"original": {
"type": "git",
"url": "https://githug.xyz/xenia/fox32rom"
}
},
"foxtools": {
"inputs": {
"flake-utils": "flake-utils_5",
"nixpkgs": "nixpkgs_4"
},
"locked": {
"lastModified": 1707042981,
"narHash": "sha256-RJwtT0BUBM0XlpzUymrwvI5JAsP1drjggIjDJcnWq8o=",
"ref": "refs/heads/main",
"rev": "f690eb07c46d59c9430bc004f72f6fba271e2415",
"revCount": 43,
"type": "git",
"url": "https://githug.xyz/xenia/fox-tools"
},
"original": {
"type": "git",
"url": "https://githug.xyz/xenia/fox-tools"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1697009197,
"narHash": "sha256-viVRhBTFT8fPJTb1N3brQIpFZnttmwo3JVKNuWRVc3s=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "01441e14af5e29c9d27ace398e6dd0b293e25a54",
"type": "github"
},
"original": {
"id": "nixpkgs",
"type": "indirect"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1697009197,
"narHash": "sha256-viVRhBTFT8fPJTb1N3brQIpFZnttmwo3JVKNuWRVc3s=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "01441e14af5e29c9d27ace398e6dd0b293e25a54",
"type": "github"
},
"original": {
"id": "nixpkgs",
"type": "indirect"
}
},
"nixpkgs_3": {
"locked": {
"lastModified": 1697009197,
"narHash": "sha256-viVRhBTFT8fPJTb1N3brQIpFZnttmwo3JVKNuWRVc3s=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "01441e14af5e29c9d27ace398e6dd0b293e25a54",
"type": "github"
},
"original": {
"id": "nixpkgs",
"type": "indirect"
}
},
"nixpkgs_4": {
"locked": {
"lastModified": 1697009197,
"narHash": "sha256-viVRhBTFT8fPJTb1N3brQIpFZnttmwo3JVKNuWRVc3s=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "01441e14af5e29c9d27ace398e6dd0b293e25a54",
"type": "github"
},
"original": {
"id": "nixpkgs",
"type": "indirect"
}
},
"nixpkgs_5": {
"locked": {
"lastModified": 1697009197,
"narHash": "sha256-viVRhBTFT8fPJTb1N3brQIpFZnttmwo3JVKNuWRVc3s=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "01441e14af5e29c9d27ace398e6dd0b293e25a54",
"type": "github"
},
"original": {
"id": "nixpkgs",
"type": "indirect"
}
},
"root": {
"inputs": {
"flake-utils": "flake-utils",
"fox32asm": "fox32asm",
"fox32rom": "fox32rom",
"foxtools": "foxtools",
"nixpkgs": "nixpkgs_5"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"systems_2": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"systems_3": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"systems_4": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"systems_5": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
}
},
"root": "root",
"version": 7
}

79
flake.nix 100644
View File

@ -0,0 +1,79 @@
{
description = "fox32os";
inputs = {
fox32asm.url = "git+https://githug.xyz/xenia/fox32asm";
fox32rom.url = "git+https://githug.xyz/xenia/fox32rom";
foxtools.url = "git+https://githug.xyz/xenia/fox-tools";
flake-utils.url = "github:numtide/flake-utils";
};
outputs = { self, nixpkgs, fox32asm, fox32rom, foxtools, flake-utils }:
flake-utils.lib.eachDefaultSystem (sys:
let pkgs = import nixpkgs { system = sys; };
asm = fox32asm.packages.${sys}.fox32asm;
gfx2inc = foxtools.packages.${sys}.gfx2inc;
rom-dev = fox32rom.packages.${sys}.fox32rom-dev;
deps = [ pkgs.lua5_4_compat pkgs.python311 ]; # lua needed for Okameron, python for ryfs.py
okameron = pkgs.fetchFromGitHub {
owner = "TalonFloof";
repo = "okameron";
rev = "c7499dff866bb6100cc4d5e688c39d1d853389f8";
hash = "sha256-VQ/ABkiPMFZtA8XKLW2oQTihVkLmq5+gL8IVe5Kfv/I=";
};
ryfs = pkgs.fetchFromGitHub {
owner = "ry755";
repo = "ryfs";
rev = "e5034f4e11250a626388d7e9c1bcbf9af53f5702";
hash = "sha256-wA89XLHhinxpiaKzGKKqLuRQ6Q4x4uw/NwGK8Hs2+MQ=";
};
fox32os = pkgs.stdenv.mkDerivation {
name = "fox32os";
src = ./.;
nativeBuildInputs = deps;
preBuild = ''
mkdir -p ./fox32rom
cp ${rom-dev}/dev/fox32rom.def ./fox32rom/fox32rom.def
'';
FOX32ASM = "${asm}/bin/fox32asm";
GFX2INC = "${gfx2inc}/bin/gfx2inc";
OKAMERON = "${okameron}/okameron.lua";
RYFS = "${ryfs}/ryfs.py";
installPhase = ''
mkdir -p "$out/bin"
cp fox32os.img romdisk.img "$out/bin"
'';
dontFixup = true;
};
fox32os-dev = pkgs.runCommand "fox32os-dev" {} ''
mkdir -p $out/dev
cp ${./fox32os.def} $out/dev/fox32os.def
'';
in rec {
packages.fox32os = fox32os;
packages.fox32os-dev = fox32os-dev;
packages.default = fox32os;
devShells.default = pkgs.mkShell {
packages = deps ++ [ asm gfx2inc okameron ] ;
shellHook = ''
export FOX32ASM="${asm}/bin/fox32asm";
export GFX2INC="${gfx2inc}/bin/gfx2inc";
export OKAMERON="${okameron}/okameron.lua";
export RYFS="${ryfs}/ryfs.py";
mkdir -p ./fox32rom
cp ${rom-dev}/dev/fox32rom.def ./fox32rom/fox32rom.def
'';
};
}
);
}

View File

@ -183,67 +183,33 @@ draw_bottom_bar_loop:
call copy_memory_bytes
; check if a disk is inserted as disk 1
; if so, skip checking startup.cfg and just run disk 1
; if so, skip checking startup.bat and just run disk 1
in r31, 0x80001001
cmp r31, 0
ifnz jmp boot_disk_1
try_startup:
; open startup.cfg
call get_current_disk_id
mov r1, r0
mov r0, startup_cfg
mov r2, startup_cfg_struct
call ryfs_open
mov r0, serial_stream
mov r2, serial_stream_struct
call open
mov r0, startup_bat
movz.8 r1, [boot_disk_id]
mov r2, startup_bat_check_struct
call open
cmp r0, 0
ifz jmp startup_error
ifz jmp emergency_shell
; load a startup task
load_startup_task:
; load 11 bytes of startup.cfg into startup_file
mov r0, 11
mov r1, startup_cfg_struct
mov r2, startup_file
call ryfs_read
; open the actual startup file
call get_current_disk_id
mov r1, r0
mov r0, startup_file
mov r2, startup_file_struct
call ryfs_open
cmp r0, 0
ifz jmp startup_error
; create a new task and yield to it
mov r0, startup_file_struct
mov r1, 0
mov r2, 0
mov r3, 0
; run `sh startup.bat` with IO redirected to :serial
mov r0, sh_fxf
movz.8 r1, [boot_disk_id]
mov r2, serial_stream_struct
mov r3, startup_bat
mov r4, 0
mov r5, 0
mov r6, 0
call launch_fxf_from_open_file
; when the startup file yields for the first time, we'll end up back here
; now, check to see if startup.cfg has any other entries
; we do this by checking to see if the size of startup.cfg is less than or equal to 12 * next_task bytes
inc.8 [next_task]
mov r0, startup_cfg_struct
call get_size
movz.8 r1, [next_task]
mul r1, 12
cmp r0, r1
iflteq jmp no_other_tasks
; seek forward one byte to skip the linefeed
mov r0, startup_cfg_struct
call ryfs_tell
inc r0
mov r1, startup_cfg_struct
call ryfs_seek
; load the next task
jmp load_startup_task
call launch_fxf_from_disk
cmp r0, 0xFFFFFFFF
ifz jmp startup_error
no_other_tasks:
; start the event manager task
@ -256,6 +222,19 @@ no_other_tasks:
; this does not return.
call end_current_task_no_mark_no_free
emergency_shell:
mov r0, sh_fxf
movz.8 r1, [boot_disk_id]
mov r2, serial_stream_struct
mov r3, 0
mov r4, 0
mov r5, 0
mov r6, 0
call launch_fxf_from_disk
cmp r0, 0xFFFFFFFF
ifz jmp startup_error
jmp no_other_tasks
; try loading the raw contents of disk 1 as an FXF binary
; if disk 1 is not inserted, then fail
boot_disk_1:
@ -387,7 +366,7 @@ get_os_api_version:
bottom_bar_str_0: data.strz "FOX"
bottom_bar_str_1: data.strz "32"
bottom_bar_str_2: data.strz " OS version %u.%u.%u "
startup_error_str: data.strz "fox32 - OS version %u.%u.%u - startup.cfg is invalid!"
startup_error_str: data.strz "fox32 - OS version %u.%u.%u - sh.fxf is missing?"
memory_error_str: data.strz "fox32 - OS version %u.%u.%u - not enough memory to perform operation!"
api_error_str: data.strz "fox32 - OS version %u.%u.%u - fox32rom API version too low!"
kernelception_error_str: data.strz "Error: kernelception?"
@ -428,14 +407,14 @@ bottom_bar_patterns:
data.32 0xFFFFFFFF
data.32 0xFF674764
next_task: data.8 0
current_disk_id: data.8 0
boot_disk_id: data.8 0
startup_cfg: data.str "startup cfg"
startup_cfg_struct: data.fill 0, 32
startup_file: data.str " "
startup_file_struct: data.fill 0, 32
sh_fxf: data.strz "sh.fxf"
startup_bat: data.strz "startup.bat"
startup_bat_check_struct: data.fill 0, 32
serial_stream: data.strz ":serial"
serial_stream_struct: data.fill 0, 32
#include "../../fox32rom/fox32rom.def"
#include "../fox32rom/fox32rom.def"
kernel_bottom: