Fixed 86Box stack issues
This commit is contained in:
parent
a29c6940d5
commit
4b581d497d
10 changed files with 1274 additions and 1243 deletions
BIN
doc/assets/86box-machine.png
Normal file
BIN
doc/assets/86box-machine.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 46 KiB |
BIN
doc/assets/86box-video.png
Normal file
BIN
doc/assets/86box-video.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 38 KiB |
BIN
doc/assets/Capture-86Box.png
Normal file
BIN
doc/assets/Capture-86Box.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 34 KiB |
BIN
doc/assets/Capture-QEMU.png
Normal file
BIN
doc/assets/Capture-QEMU.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 25 KiB |
12
doc/assets/screenshot.md
Normal file
12
doc/assets/screenshot.md
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Screenshot of early boot version + Text functions
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Screenshot of early buttons & sliders
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Screenshot of rounded buttons & checkboxes
|
||||||
65
doc/build.md
Normal file
65
doc/build.md
Normal file
|
|
@ -0,0 +1,65 @@
|
||||||
|
### Build & Run
|
||||||
|
|
||||||
|
#### Compilation
|
||||||
|
|
||||||
|
From the project root:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd src
|
||||||
|
nasm -f bin boot.asm -o ..\build\bios.bin
|
||||||
|
```
|
||||||
|
|
||||||
|
This produces a raw BIOS ROM image (bios.bin) suitable for direct execution by QEMU.
|
||||||
|
|
||||||
|
#### QEMU Execution
|
||||||
|
|
||||||
|
The QEMU VGA BIOS must be copied into a local rom/ directory.
|
||||||
|
|
||||||
|
Default locations of `vgabios.bin`:
|
||||||
|
|
||||||
|
Windows
|
||||||
|
`C:\Program Files\qemu\share\vgabios.bin`
|
||||||
|
|
||||||
|
Linux
|
||||||
|
`/usr/share/qemu/vgabios.bin`
|
||||||
|
|
||||||
|
You can use an video bios from the 86box's project:
|
||||||
|
|
||||||
|
https://github.com/86Box/roms
|
||||||
|
|
||||||
|
Copy it to: `roms/vgabios.bin`
|
||||||
|
|
||||||
|
Then run QEMU with:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
qemu-system-i386 \
|
||||||
|
-bios build/bios.bin \
|
||||||
|
-device loader,file=roms/vgabios.bin,addr=0xC0000,force-raw=on \
|
||||||
|
-device isa-debugcon,chardev=myconsole \
|
||||||
|
-chardev stdio,id=myconsole \
|
||||||
|
-k be \
|
||||||
|
-display sdl
|
||||||
|
```
|
||||||
|
|
||||||
|
This command:
|
||||||
|
|
||||||
|
- Loads the custom BIOS as the system ROM
|
||||||
|
- Injects the VGA BIOS at 0xC0000
|
||||||
|
- Redirects debug output to the console
|
||||||
|
- Displays graphics using SDL
|
||||||
|
|
||||||
|
#### 86Box Execution
|
||||||
|
|
||||||
|
This is a bit tricky since 86box doesn't allow to pick custom BIOS file. You'll have to choose an existing computer and replace the original BIOS file with the compliled one.
|
||||||
|
|
||||||
|
create a new configuration:
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
- save the configuration
|
||||||
|
- go to the 86Box's `roms\machines\vli486sv2g\` folder
|
||||||
|
- rename the `0402.001` file (it's the original machine's BIOS);
|
||||||
|
- copy the `build\bios.bin` into the 86Bos's `roms\machines\vli486sv2g\` folder and rename as `0402.001`
|
||||||
|
|
||||||
|
|
||||||
74
readme.md
74
readme.md
|
|
@ -12,17 +12,9 @@ Rather than booting an operating system from disk, the PC starts **directly from
|
||||||
|
|
||||||
The project is intentionally educational, experimental, and minimalist.
|
The project is intentionally educational, experimental, and minimalist.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
Screenshot of early boot version + Text functions
|
You may want to get a look at the [Older screenshots](/doc/assets/screenshot.md)
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
Screenshot of early buttons & sliders
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
Screenshot of rounded buttons & checkboxes
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -82,53 +74,7 @@ Get a look at the [API](/doc/API.md) for more information.
|
||||||
|
|
||||||
### Build and Run
|
### Build and Run
|
||||||
|
|
||||||
#### Compilation
|
[read detailed step to compile an run](/doc/build.md)
|
||||||
|
|
||||||
From the project root:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd src
|
|
||||||
nasm -f bin boot.asm -o ..\build\bios.bin
|
|
||||||
```
|
|
||||||
|
|
||||||
This produces a raw BIOS ROM image (bios.bin) suitable for direct execution by QEMU.
|
|
||||||
|
|
||||||
#### Execution
|
|
||||||
|
|
||||||
The QEMU VGA BIOS must be copied into a local rom/ directory.
|
|
||||||
|
|
||||||
Default locations of `vgabios.bin`:
|
|
||||||
|
|
||||||
Windows
|
|
||||||
`C:\Program Files\qemu\share\vgabios.bin`
|
|
||||||
|
|
||||||
Linux
|
|
||||||
`/usr/share/qemu/vgabios.bin`
|
|
||||||
|
|
||||||
You can use an video bios from the 86box's project:
|
|
||||||
|
|
||||||
https://github.com/86Box/roms
|
|
||||||
|
|
||||||
Copy it to: `roms/vgabios.bin`
|
|
||||||
|
|
||||||
Then run QEMU with:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
qemu-system-i386 \
|
|
||||||
-bios build/bios.bin \
|
|
||||||
-device loader,file=roms/vgabios.bin,addr=0xC0000,force-raw=on \
|
|
||||||
-device isa-debugcon,chardev=myconsole \
|
|
||||||
-chardev stdio,id=myconsole \
|
|
||||||
-k be \
|
|
||||||
-display sdl
|
|
||||||
```
|
|
||||||
|
|
||||||
This command:
|
|
||||||
|
|
||||||
- Loads the custom BIOS as the system ROM
|
|
||||||
- Injects the VGA BIOS at 0xC0000
|
|
||||||
- Redirects debug output to the console
|
|
||||||
- Displays graphics using SDL
|
|
||||||
|
|
||||||
### Non-Goals
|
### Non-Goals
|
||||||
|
|
||||||
|
|
@ -149,20 +95,6 @@ Ce projet consiste à concevoir et développer un **BIOS/ROM PC compatible enti
|
||||||
|
|
||||||
Au lieu de charger un système d’exploitation depuis un disque, le PC **démarre directement depuis la ROM** vers une **interface graphique minimaliste**, utilisant le mode **CGA Haute Résolution Monochrome (640×200)**.
|
Au lieu de charger un système d’exploitation depuis un disque, le PC **démarre directement depuis la ROM** vers une **interface graphique minimaliste**, utilisant le mode **CGA Haute Résolution Monochrome (640×200)**.
|
||||||
|
|
||||||
Le projet est volontairement **éducatif, expérimental et minimaliste**.
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
Screenshot of early boot version + Text functions
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
Screenshot of early buttons & sliders
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
Screenshot of rounded buttons & checkboxes
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Objectifs
|
### Objectifs
|
||||||
|
|
|
||||||
|
|
@ -152,14 +152,14 @@ main_loop:
|
||||||
pop ds
|
pop ds
|
||||||
|
|
||||||
DEBUG 1
|
DEBUG 1
|
||||||
ISADBG ISA_RED, 1
|
ISADBG ISA_LEFT, 1
|
||||||
|
|
||||||
; Init du système GUI
|
; Init du système GUI
|
||||||
call gui_init_system
|
call gui_init_system
|
||||||
|
|
||||||
|
|
||||||
DEBUG 2
|
DEBUG 2
|
||||||
ISADBG ISA_RED, 2
|
ISADBG ISA_LEFT, 2
|
||||||
|
|
||||||
; --- CRÉATION DYNAMIQUE DES BOUTONS ---
|
; --- CRÉATION DYNAMIQUE DES BOUTONS ---
|
||||||
|
|
||||||
|
|
@ -180,7 +180,7 @@ main_loop:
|
||||||
GUI OBJ_SET_TEXT, ax, cs, str_option3
|
GUI OBJ_SET_TEXT, ax, cs, str_option3
|
||||||
|
|
||||||
DEBUG 3
|
DEBUG 3
|
||||||
ISADBG ISA_RED, 3
|
ISADBG ISA_LEFT, 3
|
||||||
|
|
||||||
; Créer Slider (Drag)
|
; Créer Slider (Drag)
|
||||||
GUI OBJ_CREATE, OBJ_TYPE_SLIDER, 10, 100, 150, 12
|
GUI OBJ_CREATE, OBJ_TYPE_SLIDER, 10, 100, 150, 12
|
||||||
|
|
@ -197,7 +197,7 @@ main_loop:
|
||||||
mov .value, 0xFADE
|
mov .value, 0xFADE
|
||||||
|
|
||||||
DEBUG 4
|
DEBUG 4
|
||||||
ISADBG ISA_RED, 4
|
ISADBG ISA_LEFT, 4
|
||||||
|
|
||||||
.loop:
|
.loop:
|
||||||
call gui_process_all
|
call gui_process_all
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,10 @@
|
||||||
;
|
;
|
||||||
; =============================================================================
|
; =============================================================================
|
||||||
|
|
||||||
|
%define DISABLE_DEBUGER
|
||||||
|
|
||||||
|
%ifndef DISABLE_DEBUGER
|
||||||
|
|
||||||
%macro DEBUG 1
|
%macro DEBUG 1
|
||||||
GFX GOTOXY, 0, 0
|
GFX GOTOXY, 0, 0
|
||||||
mov ax, %1
|
mov ax, %1
|
||||||
|
|
@ -59,6 +63,16 @@
|
||||||
pop ax
|
pop ax
|
||||||
pop dx
|
pop dx
|
||||||
%endmacro
|
%endmacro
|
||||||
|
%else
|
||||||
|
%macro DEBUG 1
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
%macro ISADBG 2
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
%macro ISADBG_RESET 0
|
||||||
|
%endmacro
|
||||||
|
%endif
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------------
|
; -----------------------------------------------------------------------------------
|
||||||
; PC components I/O ports
|
; PC components I/O ports
|
||||||
|
|
|
||||||
|
|
@ -1264,7 +1264,7 @@ cga_draw_rounded_frame:
|
||||||
cga_mouse_hide:
|
cga_mouse_hide:
|
||||||
pushf ; Sauver l'état des flags (interrupts)
|
pushf ; Sauver l'état des flags (interrupts)
|
||||||
cli ; Désactiver les interruptions (CRITIQUE)
|
cli ; Désactiver les interruptions (CRITIQUE)
|
||||||
pushad ; Sauvegarder TOUS les registres 32-bits
|
pusha ; Sauvegarder TOUS les registres 32-bits
|
||||||
push ds
|
push ds
|
||||||
|
|
||||||
mov ax, BDA_DATA_SEG
|
mov ax, BDA_DATA_SEG
|
||||||
|
|
@ -1281,7 +1281,7 @@ cga_mouse_hide:
|
||||||
|
|
||||||
.skip_restore:
|
.skip_restore:
|
||||||
pop ds
|
pop ds
|
||||||
popad
|
popa
|
||||||
popf ; Restaure les interruptions (STI si elles étaient là)
|
popf ; Restaure les interruptions (STI si elles étaient là)
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
@ -1292,7 +1292,7 @@ cga_mouse_hide:
|
||||||
cga_mouse_show:
|
cga_mouse_show:
|
||||||
pushf
|
pushf
|
||||||
cli
|
cli
|
||||||
pushad
|
pusha
|
||||||
push ds
|
push ds
|
||||||
|
|
||||||
mov ax, BDA_DATA_SEG
|
mov ax, BDA_DATA_SEG
|
||||||
|
|
@ -1312,7 +1312,7 @@ cga_mouse_show:
|
||||||
|
|
||||||
.skip_draw:
|
.skip_draw:
|
||||||
pop ds
|
pop ds
|
||||||
popad
|
popa
|
||||||
popf ; restore également le flag d'interruption
|
popf ; restore également le flag d'interruption
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
@ -1443,12 +1443,19 @@ cga_cursor_restorebg:
|
||||||
; Sortie: rien
|
; Sortie: rien
|
||||||
; Détruit: registres sauvegardés/restaurés (PUSHA/POPA)
|
; Détruit: registres sauvegardés/restaurés (PUSHA/POPA)
|
||||||
; ============================================================
|
; ============================================================
|
||||||
|
%define .height word [bp-2]
|
||||||
|
%define .mask dword [bp-6]
|
||||||
cga_cursor_draw:
|
cga_cursor_draw:
|
||||||
|
push bp
|
||||||
|
mov bp, sp
|
||||||
|
sub sp, 6 ; Reserve space for locals
|
||||||
|
|
||||||
pushad
|
pushad
|
||||||
push ds
|
push ds
|
||||||
push es
|
push es
|
||||||
push gs
|
push gs
|
||||||
|
|
||||||
|
cld ; Sécurité : Direction avant
|
||||||
mov ax, BDA_DATA_SEG
|
mov ax, BDA_DATA_SEG
|
||||||
mov ds, ax
|
mov ds, ax
|
||||||
mov ax, VIDEO_SEG
|
mov ax, VIDEO_SEG
|
||||||
|
|
@ -1459,15 +1466,17 @@ cga_cursor_draw:
|
||||||
cmp dx, 200
|
cmp dx, 200
|
||||||
jae .exit_total
|
jae .exit_total
|
||||||
|
|
||||||
mov bp, 16
|
mov ax, 16
|
||||||
mov ax, 200
|
mov bx, 200
|
||||||
sub ax, dx ; 200-y
|
sub bx, dx ; 200-y
|
||||||
cmp bp, ax
|
cmp ax, bx
|
||||||
jbe .y_ok ; y<= 200-16
|
jbe .y_ok ; y<= 200-16
|
||||||
|
|
||||||
mov bp, ax
|
mov ax, bx
|
||||||
|
|
||||||
.y_ok:
|
.y_ok:
|
||||||
|
mov .height, ax
|
||||||
|
|
||||||
; On calcule si les 4 octets vont dépasser la ligne (80 octets)
|
; On calcule si les 4 octets vont dépasser la ligne (80 octets)
|
||||||
; X est en bits (0-639). X >> 3 donne l'octet de départ (0-79).
|
; X est en bits (0-639). X >> 3 donne l'octet de départ (0-79).
|
||||||
; Si StartByte >= 77, on déborde.
|
; Si StartByte >= 77, on déborde.
|
||||||
|
|
@ -1499,9 +1508,7 @@ cga_cursor_draw:
|
||||||
mov esi, 0x00FFFFFF ; Cas extrême (bord droit)
|
mov esi, 0x00FFFFFF ; Cas extrême (bord droit)
|
||||||
|
|
||||||
.mask_ready:
|
.mask_ready:
|
||||||
; On sauvegarde ce masque pour l'utiliser dans la boucle
|
mov .mask, esi
|
||||||
; On utilise la pile pour libérer les registres
|
|
||||||
push esi ; [ESP] contient maintenant le masque
|
|
||||||
|
|
||||||
; --- ADRESSAGE ---
|
; --- ADRESSAGE ---
|
||||||
mov cx, [BDA_MOUSE + mouse.x]
|
mov cx, [BDA_MOUSE + mouse.x]
|
||||||
|
|
@ -1540,7 +1547,7 @@ cga_cursor_draw:
|
||||||
|
|
||||||
ror eax, cl
|
ror eax, cl
|
||||||
|
|
||||||
or eax, [esp+2] ; Force les bits clippés à 1 (garde le fond)
|
or eax, .mask ; Force les bits clippés à 1 (garde le fond)
|
||||||
|
|
||||||
; --- MASQUE XOR (EBX) ---
|
; --- MASQUE XOR (EBX) ---
|
||||||
xor ebx, ebx
|
xor ebx, ebx
|
||||||
|
|
@ -1551,7 +1558,7 @@ cga_cursor_draw:
|
||||||
xchg bh, bl
|
xchg bh, bl
|
||||||
ror ebx, cl
|
ror ebx, cl
|
||||||
|
|
||||||
mov edx, [esp+2] ; charge le masque de protection
|
mov edx, .mask ; charge le masque de protection
|
||||||
not edx ; inverse le masque de protection
|
not edx ; inverse le masque de protection
|
||||||
and ebx, edx ; applique le masque de protection
|
and ebx, edx ; applique le masque de protection
|
||||||
|
|
||||||
|
|
@ -1582,14 +1589,15 @@ cga_cursor_draw:
|
||||||
.next_line:
|
.next_line:
|
||||||
neg cx ; prochaine banque = -banque
|
neg cx ; prochaine banque = -banque
|
||||||
add si, 2 ; Prochaine ligne du sprite
|
add si, 2 ; Prochaine ligne du sprite
|
||||||
dec bp
|
dec .height
|
||||||
jnz .row_loop
|
jnz .row_loop
|
||||||
|
|
||||||
pop esi
|
|
||||||
|
|
||||||
.exit_total:
|
.exit_total:
|
||||||
pop gs
|
pop gs
|
||||||
pop es
|
pop es
|
||||||
pop ds
|
pop ds
|
||||||
popad
|
popad
|
||||||
|
leave
|
||||||
ret
|
ret
|
||||||
|
%undef .height
|
||||||
|
%undef .mask
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue