7 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
5 changed files with 87 additions and 114 deletions

View File

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

View File

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

View File

@@ -25,14 +25,9 @@ ALIGN 4, db 0x90
InitFATDriver: InitFATDriver:
__CDECL16_PROC_ENTRY __CDECL16_PROC_ENTRY
.func: .func:
mov ax, FAT32_State_t_size
push ax ; length of fat32_state structure __CDECL16_CALL_ARGS fat32_state, 0x0000, FAT32_State_t_size
xor ax, ax __CDECL16_CALL kmemset, 3
push ax ; init fat32_state with zero
mov ax, fat32_state
push ax ; address of structure
call kmemset
add sp, 0x6
.calc_active_part: .calc_active_part:
mov ax, word [partition_offset] mov ax, word [partition_offset]
@@ -106,16 +101,17 @@ ALIGN 4, db 0x90
SearchFATDIR: SearchFATDIR:
__CDECL16_PROC_ENTRY __CDECL16_PROC_ENTRY
.file_lookup: .file_lookup:
print_string SearchFATDIR_info __CDECL16_CALL_ARGS SearchFATDIR_info
__CDECL16_CALL PrintString, 1
mov bx, fat32_state mov bx, fat32_state
.load_first_dir: .load_first_dir:
mov eax, dword [bx + FAT32_State_t.curr_dir_cluster_32]
push dword eax ; cluster ; uint8_t ReadFATCluster(uint16_t seg, uint16_t offset, uint32_t cluster)
mov ax, dir_buffer push dword [bx + FAT32_State_t.curr_dir_cluster_32] ; cluster
push ax ; offset push dir_buffer ; offset
xor ax, ax push 0x0000 ; segment
push ax ; segment call ReadFATCluster
call ReadFATCluster ; uint8_t ReadFATCluster(uint16_t seg, uint16_t offset, uint32_t cluster)
add sp, 0x8 add sp, 0x8
mov si, dir_buffer mov si, dir_buffer
@@ -124,10 +120,10 @@ SearchFATDIR:
.load_next_dir: .load_next_dir:
; if eax >= 0x0FFFFFF8 then there are no more clusters (end of chain) ; 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 ; if eax == 0x0FFFFFF7 then this is a cluster that is marked as bad
mov eax, dword [bx + FAT32_State_t.curr_dir_cluster_32] ; uint32_t NextCluster(uint32_t active_cluster);
push dword eax push dword [bx + FAT32_State_t.curr_dir_cluster_32]
call NextCluster ; uint32_t NextCluster(uint32_t active_cluster); call NextCluster
add sp, 0x4 add sp, 0x4
cmp eax, 0x0fff_fff7 cmp eax, 0x0fff_fff7
@@ -137,16 +133,14 @@ SearchFATDIR:
.load_next_dir_next_OK: .load_next_dir_next_OK:
; load 512 bytes of directory entries from data sector ; 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 ; uint8_t ReadFATCluster(uint16_t seg, uint16_t offset, uint32_t cluster)
push ax ; offset push dword [bx + FAT32_State_t.curr_dir_cluster_32] ; cluster
push dir_buffer ; offset
xor ax, ax push 0x0000 ; segment
push ax ; segment call ReadFATCluster
call ReadFATCluster ; uint8_t ReadFATCluster(uint16_t seg, uint16_t offset, uint32_t cluster)
add sp, 0x8 add sp, 0x8
.empty_dir_entry: .empty_dir_entry:
; check for 0x0 in first byte, if true then there are no more files ; 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 ; 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 ; TODO: move this to a seperate string search function
.parse_dir: .parse_dir:
print_string MaybeFound_Boot_info __CDECL16_CALL_ARGS MaybeFound_Boot_info
__CDECL16_CALL PrintString, 1
.lfn_check: .lfn_check:
; check for ATTR_READ_ONLY | ATTR_HIDDEN | ATTR_SYSTEM | ATTR_VOLUME_ID (0x0F) in offset 11 ; 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 ; TODO: going to skip LFN for now, since all valid volumes will have SFN's
@@ -212,18 +208,13 @@ ALIGN 4, db 0x90
NextCluster: NextCluster:
__CDECL16_PROC_ENTRY __CDECL16_PROC_ENTRY
.func: .func:
print_string NextFATCluster_info __CDECL16_CALL_ARGS NextFATCluster_info
__CDECL16_CALL PrintString, 1
mov ax, FAT32_NextClusterData_t_size __CDECL16_CALL_ARGS fat32_nc_data, 0x0000, FAT32_NextClusterData_t_size
push ax ; length __CDECL16_CALL kmemset, 3
xor ax, ax
push ax ; init with zero
mov ax, fat32_nc_data
push ax ; address of structure
call kmemset
add sp, 0x6
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 si, fat32_nc_data ; instead of push/pop and moving the data back
mov di, fat32_bpb ; load si & di then use xchg mov di, fat32_bpb ; load si & di then use xchg
mov bx, fat32_state mov bx, fat32_state
@@ -270,10 +261,11 @@ NextCluster:
; uint32_t lba, ; uint32_t lba,
; uint16_t count, uint16_t drive_num) ; uint16_t count, uint16_t drive_num)
.read_cluster: .read_cluster:
; next_cluster = fat_buffer[entry_offset] ; next_cluster = fat_buffer[entry_offset]
mov ebx, dword [si + FAT32_NextClusterData_t.entry_offset] mov ebx, dword [si + FAT32_NextClusterData_t.entry_offset]
mov si, fat_buffer mov si, fat_buffer
mov eax, dword [bx+si+0] mov eax, dword [bx+si+0]
; BUG: ???
.endp: .endp:
__CDECL16_PROC_EXIT __CDECL16_PROC_EXIT
ret ret
@@ -285,7 +277,8 @@ ALIGN 4, db 0x90
ReadFATCluster: ReadFATCluster:
__CDECL16_PROC_ENTRY __CDECL16_PROC_ENTRY
.func: .func:
print_string ReadFATCluster_info __CDECL16_CALL_ARGS ReadFATCluster_info
__CDECL16_CALL PrintString, 1
mov bx, fat32_bpb mov bx, fat32_bpb
mov si, fat32_ebpb 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)" echo "[2/7] Write DOS partition table (single FAT32 LBA @ 2048)"
"$SF" --no-reread "$disk_img" < /tmp/pt.sfdisk "$SF" --no-reread "$disk_img" < /tmp/pt.sfdisk
echo "[3/7] Make FAT32 filesystem in partition image" # BUG: the default disk img is 256MiB which mkfs.fat wants to create
"$MKFS" -v -F32 -s 1 -n 'STEVIAFS' "$part_img" # 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)" echo "[4/7] Patch VBR inside partition image (preserve BPB)"

View File

@@ -34,13 +34,6 @@
%include "early_mem.inc" %include "early_mem.inc"
%include "error_codes.inc" %include "error_codes.inc"
%macro print_string 1
mov ax, %1
push ax
call PrintString
add sp, 0x2
%endmacro
section .text section .text
begin_text: begin_text:
; dl = byte boot_drive ; dl = byte boot_drive
@@ -135,60 +128,54 @@ main:
je main.stage2_main je main.stage2_main
ERROR STAGE2_SIGNATURE_MISSING ERROR STAGE2_SIGNATURE_MISSING
.stage2_main: .stage2_main:
mov ax, PartTable_t_size ; copy partition table data to .data section in stage2
push ax ; len = PartTable_t_size __CDECL16_CALL_ARGS partition_table, word [vbr_part_table_ptr], PartTable_t_size
mov ax, word [vbr_part_table_ptr] ; src = ptr to vbr partition_table __CDECL16_CALL kmemcpy, 3
push ax
mov ax, partition_table ; dst
push ax
call kmemcpy ; copy partition table data to .data section in stage2
add sp, 0x6
mov ax, (FAT32_bpb_t_size + FAT32_ebpb_t_size) ; len ; copy bpb & ebpb to memory
push ax __CDECL16_CALL_ARGS fat32_bpb, word [vbr_fat32_bpb_ptr], (FAT32_bpb_t_size + FAT32_ebpb_t_size)
mov ax, word [vbr_fat32_bpb_ptr] ; src __CDECL16_CALL kmemcpy, 3
push ax
mov ax, fat32_bpb ; dst
push ax
call kmemcpy ; copy bpb & ebpb to memory
add sp, 0x6
call SetTextMode call SetTextMode
call disable_cursor_bios call disable_cursor_bios
print_string HelloPrompt_info
; 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 HelloPrompt_info
__CDECL16_CALL PrintString, 1
; setup the early heap
__CDECL16_CALL_ARGS early_heap_state
; enable A20 gate ; enable A20 gate
call EnableA20 call EnableA20
print_string A20_Enabled_OK_info __CDECL16_CALL_ARGS A20_Enabled_OK_info
__CDECL16_CALL PrintString, 1
; get system memory map ; get system memory map
call GetMemoryMap 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) ; 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) ; 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 ; 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 ; NOTE: if you modify a segment register you will need to re-unreal it
call EnterUnrealMode call EnterUnrealMode
print_string UnrealMode_OK_info __CDECL16_CALL_ARGS UnrealMode_OK_info
__CDECL16_CALL PrintString, 1
; FAT Driver setup ; FAT Driver setup
call InitFATDriver call InitFATDriver
print_string InitFATSYS_OK_info __CDECL16_CALL_ARGS InitFATSYS_OK_info
__CDECL16_CALL PrintString, 1
; ;
; Find first cluster of bootable file ; Find first cluster of bootable file
call SearchFATDIR call SearchFATDIR
push dword eax ; save first cluster of bootable file 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 pop dword eax
push dword eax ; print Cluster of boot file push dword eax ; print Cluster of boot file
call PrintDWORD ; void PrintDWORD(uint32_t dword) call PrintDWORD ; void PrintDWORD(uint32_t dword)