8 Commits

Author SHA1 Message Date
528e3d69fe update github workflow since github includes firefox & snaps in the default runner image, which causes the build to fail.
All checks were successful
Daily Build and trunk tester / debian_update (push) Successful in 1m11s
going to need a custom runner I guess...might as well only do actions on gitea.
2025-09-16 08:34:22 -04:00
9a6fea658d bugs
All checks were successful
Daily Build and trunk tester / debian_update (push) Successful in 51s
2025-09-07 18:43:03 -04:00
891bff9509 use __CDECL16 macros and clean up a few proc calls 2025-09-07 17:38:21 -04:00
1e181bc22c remove print_string macro 2025-09-07 16:25:08 -04:00
68c8200aa4 remove invoke macro for now 2025-09-07 16:21:19 -04:00
766c67c041 first calls to use the new cdecl16 macros 2025-09-07 16:11:18 -04:00
49d82be0e8 use rotate instead of stack context in macros 2025-09-07 16:10:59 -04:00
69bd7d8f56 small clean up and use configured segment for return to real mode 2025-09-07 14:50:40 -04:00
5 changed files with 88 additions and 118 deletions

View File

@@ -3,7 +3,7 @@ on:
push:
branches: [ $default-branch ]
schedule:
- cron: "0 7 * * *" # daily 07:00
- cron: "0 7 * * 1" # mondays at 07:00
workflow_dispatch: {}
jobs:

View File

@@ -44,11 +44,13 @@
; for use inside of function bodies
%ifnmacro __CDECL16_PROC_ARGS
%macro __CDECL16_PROC_ARGS 1
%push __CDECL16_PROC_ARGS
%assign %$__i 1
%rep %1
%xdefine %$arg%$__i [bp + 4 + 2*(%$__i-1)]
%assign %$__i %$__i + 1
%endrep
%pop
%endmacro
%endif
@@ -56,10 +58,9 @@
; handles pushing values to the stack in the correct order
%ifnmacro __CDECL16_CALL_ARGS
%macro __CDECL16_CALL_ARGS 1-*
%assign %$__i %0
%rep %0
push %[%$__i]
%assign %$__i %$__i - 1
%rotate -1 ; move the last argument into %1
push %1 ; push last, then next-to-last, ...
%endrep
%endmacro
%endif
@@ -79,57 +80,46 @@
; count the stack frame to restore later!
%ifnmacro __CDECL16_CALL_ARGS_SIZED
%macro __CDECL16_CALL_ARGS_SIZED 2-*
%push __CDECL16_CALL_ARGS_SIZED
call %1
%assign %$__sum 0
%assign %$__i 2
%rep %0-1
%assign %$__sum %$__sum + %[%$__i]
%assign %$__sum %$__sum + %[%$__i] ; sizes may be expressions
%assign %$__i %$__i + 1
%endrep
%if %$__sum & 1
%error "__CDECL16_CALL_ARGS_SIZED: total size is odd; pushes must sum to whole bytes actually pushed (usually even)."
%endif
add sp, %$__sum
%endmacro
%endif
; __CDECL16_INVOKE func, arg1[, arg2 ...]
; pushes args right-to-left, calls, then add sp by (#args)*2
; !!! warning for word sized args only !!!
%ifnmacro __CDECL16_INVOKE
%macro __CDECL16_INVOKE 1-*
%assign %$__argc %0-1
%if %$__argc > 0
; push args right-to-left
%assign %$__i %0
%rep %$__argc
push %[%$__i]
%assign %$__i %$__i - 1
%endrep
call %1
add sp, %$__argc*2
%else
call %1
%endif
%pop
%endmacro
%endif
%ifnmacro __CDECL16_CLOB
; e.g CLOB ax dx ... inside func entry, then UNCLOB ax dx at all exits
; ordering is already taken care of
; i.e if you CLOB ax cx dx then UNCLOB ax cx dx, the unclob is reversed
; Save registers in the order listed. Supports "flags" as a pseudo-reg.
%macro __CDECL16_CLOB 1-*
%assign %$i 1
%rep %0
push %[%$i]
%assign %$i %$i+1
%ifidni %1, flags
pushf
%else
push %1
%endif
%rotate 1
%endrep
%endmacro
%endif
%ifnmacro __CDECL16_UNCLOB
; Restore in reverse order of CLOB. Supports "flags".
%macro __CDECL16_UNCLOB 1-*
%assign %$i %0
%rep %0
pop %[%$i]
%assign %$i %$i-1
%rotate -1
%ifidni %1, flags
popf
%else
pop %1
%endif
%endrep
%endmacro
%endif

View File

@@ -25,14 +25,9 @@ ALIGN 4, db 0x90
InitFATDriver:
__CDECL16_PROC_ENTRY
.func:
mov ax, FAT32_State_t_size
push ax ; length of fat32_state structure
xor ax, ax
push ax ; init fat32_state with zero
mov ax, fat32_state
push ax ; address of structure
call kmemset
add sp, 0x6
__CDECL16_CALL_ARGS fat32_state, 0x0000, FAT32_State_t_size
__CDECL16_CALL kmemset, 3
.calc_active_part:
mov ax, word [partition_offset]
@@ -106,16 +101,17 @@ ALIGN 4, db 0x90
SearchFATDIR:
__CDECL16_PROC_ENTRY
.file_lookup:
print_string SearchFATDIR_info
__CDECL16_CALL_ARGS SearchFATDIR_info
__CDECL16_CALL PrintString, 1
mov bx, fat32_state
.load_first_dir:
mov eax, dword [bx + FAT32_State_t.curr_dir_cluster_32]
push dword eax ; cluster
mov ax, dir_buffer
push ax ; offset
xor ax, ax
push ax ; segment
call ReadFATCluster ; uint8_t ReadFATCluster(uint16_t seg, uint16_t offset, uint32_t cluster)
; uint8_t ReadFATCluster(uint16_t seg, uint16_t offset, uint32_t cluster)
push dword [bx + FAT32_State_t.curr_dir_cluster_32] ; cluster
push dir_buffer ; offset
push 0x0000 ; segment
call ReadFATCluster
add sp, 0x8
mov si, dir_buffer
@@ -125,9 +121,9 @@ SearchFATDIR:
; if eax >= 0x0FFFFFF8 then there are no more clusters (end of chain)
; if eax == 0x0FFFFFF7 then this is a cluster that is marked as bad
mov eax, dword [bx + FAT32_State_t.curr_dir_cluster_32]
push dword eax
call NextCluster ; uint32_t NextCluster(uint32_t active_cluster);
; uint32_t NextCluster(uint32_t active_cluster);
push dword [bx + FAT32_State_t.curr_dir_cluster_32]
call NextCluster
add sp, 0x4
cmp eax, 0x0fff_fff7
@@ -137,16 +133,14 @@ SearchFATDIR:
.load_next_dir_next_OK:
; load 512 bytes of directory entries from data sector
mov eax, [bx + FAT32_State_t.curr_dir_cluster_32]
push dword eax ; cluster
mov ax, dir_buffer
push ax ; offset
xor ax, ax
push ax ; segment
call ReadFATCluster ; uint8_t ReadFATCluster(uint16_t seg, uint16_t offset, uint32_t cluster)
; uint8_t ReadFATCluster(uint16_t seg, uint16_t offset, uint32_t cluster)
push dword [bx + FAT32_State_t.curr_dir_cluster_32] ; cluster
push dir_buffer ; offset
push 0x0000 ; segment
call ReadFATCluster
add sp, 0x8
.empty_dir_entry:
; check for 0x0 in first byte, if true then there are no more files
; if true we did not find the file, we should error here
@@ -176,7 +170,9 @@ SearchFATDIR:
; TODO: move this to a seperate string search function
.parse_dir:
print_string MaybeFound_Boot_info
__CDECL16_CALL_ARGS MaybeFound_Boot_info
__CDECL16_CALL PrintString, 1
.lfn_check:
; check for ATTR_READ_ONLY | ATTR_HIDDEN | ATTR_SYSTEM | ATTR_VOLUME_ID (0x0F) in offset 11
; TODO: going to skip LFN for now, since all valid volumes will have SFN's
@@ -212,18 +208,13 @@ ALIGN 4, db 0x90
NextCluster:
__CDECL16_PROC_ENTRY
.func:
print_string NextFATCluster_info
__CDECL16_CALL_ARGS NextFATCluster_info
__CDECL16_CALL PrintString, 1
mov ax, FAT32_NextClusterData_t_size
push ax ; length
xor ax, ax
push ax ; init with zero
mov ax, fat32_nc_data
push ax ; address of structure
call kmemset
add sp, 0x6
__CDECL16_CALL_ARGS fat32_nc_data, 0x0000, FAT32_NextClusterData_t_size
__CDECL16_CALL kmemset, 3
mov edx, dword [bp + 4]
mov edx, dword [bp + 4] ; active_cluster
mov si, fat32_nc_data ; instead of push/pop and moving the data back
mov di, fat32_bpb ; load si & di then use xchg
mov bx, fat32_state
@@ -274,6 +265,7 @@ NextCluster:
mov ebx, dword [si + FAT32_NextClusterData_t.entry_offset]
mov si, fat_buffer
mov eax, dword [bx+si+0]
; BUG: ???
.endp:
__CDECL16_PROC_EXIT
ret
@@ -285,7 +277,8 @@ ALIGN 4, db 0x90
ReadFATCluster:
__CDECL16_PROC_ENTRY
.func:
print_string ReadFATCluster_info
__CDECL16_CALL_ARGS ReadFATCluster_info
__CDECL16_CALL PrintString, 1
mov bx, fat32_bpb
mov si, fat32_ebpb

View File

@@ -124,8 +124,11 @@ if [[ "$OSTYPE" == "linux-gnu"* ]]; then
echo "[2/7] Write DOS partition table (single FAT32 LBA @ 2048)"
"$SF" --no-reread "$disk_img" < /tmp/pt.sfdisk
echo "[3/7] Make FAT32 filesystem in partition image"
"$MKFS" -v -F32 -s 1 -n 'STEVIAFS' "$part_img"
# BUG: the default disk img is 256MiB which mkfs.fat wants to create
# a FAT16 FS by default. it needs to be at least 2GiB to to 'lock out'
# FAT16 as an option. Force FAT32 here, might(?) break some things.
echo "[3/7] Make FAT filesystem in partition image"
"$MKFS" -F32 -v -n 'STEVIAFS' "$part_img"
echo "[4/7] Patch VBR inside partition image (preserve BPB)"

View File

@@ -34,13 +34,6 @@
%include "early_mem.inc"
%include "error_codes.inc"
%macro print_string 1
mov ax, %1
push ax
call PrintString
add sp, 0x2
%endmacro
section .text
begin_text:
; dl = byte boot_drive
@@ -135,59 +128,53 @@ main:
je main.stage2_main
ERROR STAGE2_SIGNATURE_MISSING
.stage2_main:
mov ax, PartTable_t_size
push ax ; len = PartTable_t_size
mov ax, word [vbr_part_table_ptr] ; src = ptr to vbr partition_table
push ax
mov ax, partition_table ; dst
push ax
call kmemcpy ; copy partition table data to .data section in stage2
add sp, 0x6
; copy partition table data to .data section in stage2
__CDECL16_CALL_ARGS partition_table, word [vbr_part_table_ptr], PartTable_t_size
__CDECL16_CALL kmemcpy, 3
mov ax, (FAT32_bpb_t_size + FAT32_ebpb_t_size) ; len
push ax
mov ax, word [vbr_fat32_bpb_ptr] ; src
push ax
mov ax, fat32_bpb ; dst
push ax
call kmemcpy ; copy bpb & ebpb to memory
add sp, 0x6
; copy bpb & ebpb to memory
__CDECL16_CALL_ARGS fat32_bpb, word [vbr_fat32_bpb_ptr], (FAT32_bpb_t_size + FAT32_ebpb_t_size)
__CDECL16_CALL kmemcpy, 3
call SetTextMode
call disable_cursor_bios
print_string HelloPrompt_info
__CDECL16_CALL_ARGS HelloPrompt_info
__CDECL16_CALL PrintString, 1
; setup the early heap
mov ax, early_heap_state
push ax ; address in bss of state structure
call arena_init
add sp, 0x2
__CDECL16_CALL_ARGS early_heap_state
; enable A20 gate
call EnableA20
print_string A20_Enabled_OK_info
__CDECL16_CALL_ARGS A20_Enabled_OK_info
__CDECL16_CALL PrintString, 1
; get system memory map
call GetMemoryMap
print_string MemoryMap_OK_info
__CDECL16_CALL_ARGS MemoryMap_OK_info
__CDECL16_CALL PrintString, 1
; enter unreal mode (enter PM w/ 16 bit code, 32 bit flat memory model & return to real)
; ds, es will be set to the 64KiB STAGE2_SEGMENT, fs/gs will be flat/huge memory (4GiB)
; use __REFLAT macros to re-flat ds/es for easy transfers to >1MiB
; NOTE: if you modify a segment register you will need to re-unreal it
call EnterUnrealMode
print_string UnrealMode_OK_info
__CDECL16_CALL_ARGS UnrealMode_OK_info
__CDECL16_CALL PrintString, 1
; FAT Driver setup
call InitFATDriver
print_string InitFATSYS_OK_info
__CDECL16_CALL_ARGS InitFATSYS_OK_info
__CDECL16_CALL PrintString, 1
;
; Find first cluster of bootable file
call SearchFATDIR
push dword eax ; save first cluster of bootable file
print_string FileFound_OK_info
__CDECL16_CALL_ARGS FileFound_OK_info
__CDECL16_CALL PrintString, 1
pop dword eax
push dword eax ; print Cluster of boot file
@@ -274,9 +261,6 @@ EnterUnrealMode:
; set cs to a pm code segment (0x8) w/ the following
jmp 0x0008:EnterUnrealMode.set_segs
;db 0xEA ; jmp far imm16:imm16
;dw EnterUnrealMode.set_segs ; error_far_ptr
;dw 0x0008 ; error_far_seg
.set_segs:
mov ax, 0x10 ; select descriptor 2
mov ds, ax ; 10h = 0001_0000b
@@ -291,7 +275,7 @@ EnterUnrealMode:
mov eax, cr0
and eax, ~1 ; toggle bit 1 of cr0
mov cr0, eax ; back to realmode
jmp 0x0000:EnterUnrealMode.endp
jmp __STAGE2_SEGMENT:EnterUnrealMode.endp
.endp:
sti ; re-enable interupts