diff --git a/.gitignore b/.gitignore
index 4a395c6..7a5bd8d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,5 +8,4 @@ build/
gfx/
roms/
tools/
-doc/generated/
-fonts/
+doc/generated/
\ No newline at end of file
diff --git a/doc/API.md b/doc/API.md
index f1a5416..1b3dff5 100644
--- a/doc/API.md
+++ b/doc/API.md
@@ -4,7 +4,7 @@ Le système utilise plusieurs macro *GFX*,*GUI*, etc pour appeler les fonctions
Les arguments sont passés sur la pile (Convention C : dernier argument empilé en premier, nettoyage par l'appelant géré par la macro).
- * [CGA](/doc/API_CGA.md) : controleur graphique CGA
- * [MEMORY](/doc/API_MEMORY.md) : controleur graphique CGA
+ * [CGA](doc/API_CGA.md) : controleur graphique CGA
+ * [MEMORY](doc/API_MEMORY.md) : controleur graphique CGA
- * [MEMORY MAP](/doc/MEMORY_MAP.md) : Plan de la mémoire
\ No newline at end of file
+ * [MEMORY MAP](doc/MEMORY_MAP.md) : Plan de la mémoire
\ No newline at end of file
diff --git a/doc/assets/screenshot.md b/doc/assets/screenshot.md
index a221cc3..de5bd62 100644
--- a/doc/assets/screenshot.md
+++ b/doc/assets/screenshot.md
@@ -1,12 +1,11 @@
-
-
+
Screenshot of early boot version + Text functions
-
+
Screenshot of early buttons & sliders
-
+
Screenshot of rounded buttons & checkboxes
\ No newline at end of file
diff --git a/readme.md b/readme.md
index ce02a66..edb301b 100644
--- a/readme.md
+++ b/readme.md
@@ -10,15 +10,15 @@ This project aims to design and implement a **PC-compatible BIOS/ROM from scratc
Rather than booting an operating system from disk, the PC starts **directly from the ROM** into a **minimalist graphical interface**, using **CGA High-Resolution Monochrome (640×200)** mode.
-
+
Screenshot from a CGA Hi res test on 86Box.
-
+
Screenshot from a VGA Hi res test on QEMU with "italic Font".
-You may want to get a look at the [Older screenshots](/doc/assets/screenshot.md)
+You may want to get a look at the [Older screenshots](doc/assets/screenshot.md)
The project is intentionally educational, experimental, and minimalist.
@@ -80,13 +80,13 @@ To build and run this project, the following tools and components are required:
### API
-Get a look at the [API](/doc/API.md) for more information.
+Get a look at the [API](doc/API.md) for more information.
---
### Build and Run
-[read detailed step to compile an run](/doc/build.md)
+[read detailed step to compile an run](doc/build.md)
### Non-Goals
@@ -108,15 +108,15 @@ 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)**.
-
+
Screenshot d'un EcranCGA Hi res test sur 86Box.
-
+
screenshot d'un ecran VGA Hi res test avec police Italique sur QEMU.
-You may want to get a look at the [Older screenshots](/doc/assets/screenshot.md)
+You may want to get a look at the [Older screenshots](doc/assets/screenshot.md)
---
@@ -176,14 +176,14 @@ Le BIOS VGA standard de QEMU (vgabios.bin) est utilisé pour initialiser le mat
### API
-Consultez la documentation de l'[API](/doc/API.md) pour plus d'informations.
+Consultez la documentation de l'[API](doc/API.md) pour plus d'informations.
---
### Compilation et exécution
-[read detailed step to compile an run](/doc/build.md)
+[read detailed step to compile an run](doc/build.md)
### Hors périmètre
diff --git a/src/boot.asm b/src/boot.asm
index 43958f0..5b6ef65 100644
--- a/src/boot.asm
+++ b/src/boot.asm
@@ -204,19 +204,12 @@ main_loop:
mov .value, 0xFADE
.loop:
-
- ISADBG ISA_RIGHT, 0x11
-
call gui_process_all
+ GUI OBJ_GET_VAL, .my_slider
+ mov .value, ax
- ; --- TRACE 12 : GUI traitée ---
- ISADBG ISA_RIGHT, 0x12
-
- ; GUI OBJ_GET_VAL, .my_slider
- ;mov .value, ax
-
- ;cmp ax,.oldval
- ;je .loop
+ cmp ax,.oldval
+ je .loop
; debug
;mov .oldval, ax
@@ -235,9 +228,9 @@ main_loop:
;mov al, 0x00
;int 0x10
- ;mov dx, CRTC_COLOR_DATA
- ;and ax, 0x001F
- ;out dx, ax
+ mov dx, CRTC_COLOR_DATA
+ and ax, 0x001F
+ out dx, ax
jmp .loop
leave
diff --git a/src/common/bda.asm b/src/common/bda.asm
index d9d9b7b..68aa575 100644
--- a/src/common/bda.asm
+++ b/src/common/bda.asm
@@ -30,9 +30,7 @@
%define PTR_MOUSE 0x0000
%define PTR_GFX (PTR_MOUSE + mouse_size)
-%define PTR_GUI (PTR_GFX + gfx_size)
-;
; video related information (compatible with VGA bios)
%define BDA_VIDEO_CURR_MODE 0x0049
%define BDA_VIDEO_COLUMNS 0x004A
@@ -78,10 +76,7 @@ struc gfx
.cur_offset resw 1 ; offset calculé pour le prochain caractère
.cur_line_ofs resw 1 ; "interligne" +2000h ou -2000h
.cur_shift resb 1 ; x&7 (0..7)
-endstruc
-struc gui
- .wm_active_window_id resb 1 ; ID de la fenêtre active
endstruc
; -----------------------------------------------------------------------------------
diff --git a/src/drivers/mouse_ps2.asm b/src/drivers/mouse_ps2.asm
index ab40dd9..9b3c9ab 100644
--- a/src/drivers/mouse_ps2.asm
+++ b/src/drivers/mouse_ps2.asm
@@ -291,7 +291,6 @@ isr_mouse_handler:
in al, i8042_PS2_DATA ; lire octet souris
movzx bx, byte [PTR_MOUSE + mouse.idx]
-
cmp bl,0
jne .read_packet
@@ -300,7 +299,6 @@ isr_mouse_handler:
jz .done_eoi ; allignement erroné
.read_packet:
-
mov byte [PTR_MOUSE + mouse.buffer + bx], al
inc byte [PTR_MOUSE + mouse.idx]
@@ -373,8 +371,9 @@ isr_mouse_handler:
.done:
; update la position du curseur sur l'écran
+ ; en ce moment c'est commented out (debug)
+ ; call cga_mouse_cursor_move
GFX MOUSE_MOVE
-
.done_eoi:
mov al, 0x20
out i8259_SLAVE_CMD, al ; EOI PIC esclave
diff --git a/src/gui/lib-api.asm b/src/gui/lib-api.asm
index dd33295..d173e67 100644
--- a/src/gui/lib-api.asm
+++ b/src/gui/lib-api.asm
@@ -86,11 +86,11 @@ gui_api_table:
; --- Structure d'un OBJET (Bouton, etc) ---
struc widget
+ .header resw 1 ; HEADER
.state resb 1 ; État (0=libre, >0=utilisé)
.type resb 1 ; Type (0=Button, 1=Slider...)
.oldstate resb 1 ; widget a-t-il été modifié ?
.user_id resb 1 ; ID unique utilisateur
- .win_id resb 1 ; ID de la fenêtre propriétaire
.x resw 1 ; Position Xevent_drag
.y resw 1 ; Position Y
.w resw 1 ; Largeur
@@ -133,18 +133,17 @@ endstruc
; -----------------------------------------------------------------------------
; gui_api_slider_attr
+; -----------------------------------------------------------------------------
%define .id word [bp+4]
%define .min word [bp+6]
%define .max word [bp+8]
%define .val word [bp+10]
%define .pct word [bp+12]
-; -----------------------------------------------------------------------------
gui_api_slider_attr:
push bp
mov bp, sp
push gs
push ax
- push si
mov ax, .id
call gui_get_widget_ptr_internal
@@ -162,29 +161,23 @@ gui_api_slider_attr:
call gui_slider_update_pixels
.err:
- pop si
pop ax
pop gs
leave
- %undef .id
- %undef .min
- %undef .max
- %undef .val
- %undef .pct
ret
-
+%undef .id
+%undef .mode
; -----------------------------------------------------------------------------
; gui_api_set_mode
+; -----------------------------------------------------------------------------
%define .id word [bp+4]
%define .mode word [bp+6]
-; -----------------------------------------------------------------------------
gui_api_set_mode:
push bp
mov bp, sp
push gs
push ax
- push si
mov ax, .id
call gui_get_widget_ptr_internal
@@ -194,26 +187,24 @@ gui_api_set_mode:
mov byte [gs:si + widget.attr_mode], al
.err:
- pop si
- pop ax
pop gs
+ pop ax
leave
- %undef .id
- %undef .mode
ret
+%undef .id
+%undef .mode
; -----------------------------------------------------------------------------
; gui_api_set_text
+; -----------------------------------------------------------------------------
%define .id word [bp+4]
%define .segmt word [bp+6]
%define .oft word [bp+8]
-; -----------------------------------------------------------------------------
gui_api_set_text:
push bp
mov bp, sp
push gs
push ax
- push si
mov ax, .id
call gui_get_widget_ptr_internal
@@ -225,15 +216,13 @@ gui_api_set_text:
mov word [gs:si + widget.text_ofs], ax
.err:
- pop si
- pop ax
pop gs
+ pop ax
leave
- %undef .id
- %undef .text_ofs
- %undef .text_seg
ret
-
+%undef .id
+%undef .text_ofs
+%undef .text_seg
; -----------------------------------------------------------------------------
; gui_api_create
@@ -265,6 +254,9 @@ gui_api_create:
mov cx, widget_size
div cx
+ mov bx, 0xDEAD
+ mov word [gs:si + widget.header], bx
+
mov bx, .type
mov byte [gs:si + widget.type], bl
mov bx, .x
@@ -293,13 +285,12 @@ gui_api_create:
; gui_api_get_state
; Arg1: ID
; Out: AX = State
-%define .id word [bp+4]
; -----------------------------------------------------------------------------
+%define .id word [bp+4]
gui_api_get_state:
push bp
mov bp, sp
push gs
- push si
mov ax, .id
call gui_get_widget_ptr_internal
@@ -312,23 +303,21 @@ gui_api_get_state:
.err:
mov ax, -1
.done:
- pop si
pop gs
leave
- %undef .id
ret
+%undef .id
; -----------------------------------------------------------------------------
; gui_api_get_type
; Arg1: ID
; Out: AX = Type
-%define .id word [bp+4]
; -----------------------------------------------------------------------------
+%define .id word [bp+4]
gui_api_get_type:
push bp
mov bp, sp
push gs
- push si
mov ax,.id
call gui_get_widget_ptr_internal
@@ -341,7 +330,6 @@ gui_api_get_type:
.err:
mov ax, -1
.done:
- pop si
pop gs
leave
ret
@@ -351,14 +339,12 @@ gui_api_get_type:
; gui_api_get_val
; Arg1: ID
; Out: AX = Attr Val
-%define .id word [bp+4]
; -----------------------------------------------------------------------------
+%define .id word [bp+4]
gui_api_get_val:
push bp
mov bp, sp
push gs
- push si
-
mov ax,.id
call gui_get_widget_ptr_internal
@@ -371,25 +357,22 @@ gui_api_get_val:
.err:
mov ax, -1
.done:
- pop si
pop gs
leave
- %undef .id
ret
-
+%undef .id
; -----------------------------------------------------------------------------
; gui_api_set_val
; Arg1: ID
; Arg2: Value
+; -----------------------------------------------------------------------------
%define .id word [bp+4]
%define .val word [bp+6]
-; -----------------------------------------------------------------------------
gui_api_set_val:
push bp
mov bp, sp
push gs
- push si
mov ax,.id
call gui_get_widget_ptr_internal
@@ -399,25 +382,23 @@ gui_api_set_val:
mov [gs:si + widget.thumb_pos], ax
.err:
- pop si
pop gs
leave
- %undef .id
- %undef .val
ret
+%undef .id
+%undef .val
; -----------------------------------------------------------------------------
; gui_api_destroy
; Détruit un widget via son ID
; Arg1: ID
; Out: AX = 0 (OK), -1 (Error)
-%define .id word [bp+4]
; -----------------------------------------------------------------------------
+%define .id word [bp+4]
gui_api_destroy:
push bp
mov bp, sp
push gs
- push si
mov ax,.id
call gui_get_widget_ptr_internal
@@ -430,12 +411,10 @@ gui_api_destroy:
.err:
mov ax, -1
.done:
- pop si
pop gs
leave
- %undef .id
ret
-
+%undef .id
; -----------------------------------------------------------------------------
; gui_get_widget_ptr
@@ -451,8 +430,8 @@ gui_get_widget_ptr:
call gui_get_widget_ptr_internal
pop ax
leave
- %undef .id
ret
+%undef .id
; -----------------------------------------------------------------------------
; gui_get_widget_ptr_internal
@@ -493,7 +472,7 @@ gui_get_widget_ptr_internal:
; Entrée : DS doit pointer vers SEG_GUI
; -----------------------------------------------------------------------------
gui_init_system:
- push ax
+ push eax
push cx
push es
push di
@@ -510,7 +489,7 @@ gui_init_system:
pop di
pop es
pop cx
- pop ax
+ pop eax
ret
; -----------------------------------------------------------------------------
diff --git a/src/gui/lib-draw.asm b/src/gui/lib-draw.asm
index 9b9945b..d435cb5 100644
--- a/src/gui/lib-draw.asm
+++ b/src/gui/lib-draw.asm
@@ -522,7 +522,7 @@ draw_text:
push ax ; Sauve X original
mov ax, [gs:si + widget.w]
sub ax, cx
- sar ax, 1
+ shr ax, 1
pop dx ; Récupère X original (poussé depuis AX)
add ax, dx ; AX = X final centré
diff --git a/src/gui/lib-logic.asm b/src/gui/lib-logic.asm
index b33d88b..dbfeebd 100644
--- a/src/gui/lib-logic.asm
+++ b/src/gui/lib-logic.asm
@@ -26,9 +26,6 @@ gui_process_all:
mov bl, [PTR_MOUSE + mouse.status]
pop ds
- ; Récupérer l'ID de la fenêtre active
- mov dl, [PTR_GUI + gui.wm_active_window_id]
-
mov si, 0 ; Pointeur début tableau
mov di, GUI_MAX_WIDGETS ; Compteur
@@ -37,15 +34,9 @@ gui_process_all:
cmp byte [gs:si + widget.state], GUI_STATE_FREE
je .next_widget
- mov ax, di
- ISADBG ISA_LEFT, al
-
; --- Logique Widget ---
push bx ; Sauver état boutons souris
-
- ISADBG ISA_RIGHT, 0x20 ; Avant logic
call gui_update_logic ; Vérifier collision/clic
- ISADBG ISA_RIGHT, 0x21 ; Avant logic
; Si AL=1 (Clic relâché validé), exécuter le callback
cmp al, 1
@@ -69,15 +60,10 @@ gui_process_all:
; Dessiner (si l'état a changé ou pour refresh)
- ISADBG ISA_RIGHT, 0x22 ; Avant dessin
-
cmp al,ah
je .next_widget ; Si != 0, le widget est à jour, on passe.
call gui_draw_single_widget
- ISADBG ISA_RIGHT, 0x23 ; Avant dessin
-
-
.next_widget:
add si, widget_size
dec di
diff --git a/src/gui/lib-wm.asm b/src/gui/lib-wm.asm
deleted file mode 100644
index b5ad4ee..0000000
--- a/src/gui/lib-wm.asm
+++ /dev/null
@@ -1,121 +0,0 @@
-; =============================================================================
-; Project : Custom BIOS / ROM
-; File : gui/window.asm
-; Author : frater
-;
-; License : GNU General Public License v3.0 or later (GPL-3.0+)
-;
-; This program is free software: you can redistribute it and/or modify
-; it under the terms of the GNU General Public License as published by
-; the Free Software Foundation, either version 3 of the License, or
-; (at your option) any later version.
-;
-; This program is distributed in the hope that it will be useful,
-; but WITHOUT ANY WARRANTY; without even the implied warranty of
-; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-; GNU General Public License for more details.
-;
-; You should have received a copy of the GNU General Public License
-; along with this program. If not, see .
-;
-; =============================================================================
-
-; =============================================================================
-; Project : Custom BIOS / ROM
-; File : gui/window-manager.asm
-; Description : Gestionnaire de fenêtres (Window Manager)
-; =============================================================================
-
-%define MAX_WINDOWS 8
-
-; --- États d'une fenêtre ---
-%define WIN_STATE_FREE 0 ; Slot libre en mémoire
-%define WIN_STATE_INACTIVE 1 ; Affichée en arrière-plan
-%define WIN_STATE_ACTIVE 2 ; Au premier plan (focus)
-%define WIN_STATE_HIDDEN 3 ; Invisible
-
-struc window
- .state resb 1 ; État de la fenêtre
- .id resb 1 ; Identifiant unique
- .x resw 1
- .y resw 1
- .w resw 1
- .h resw 1
- .title_ofs resw 1 ; Pointeur texte du titre
- .title_seg resw 1
- .process_cb resw 1 ; NOUVEAU : Offset du callback (processus de la fenêtre)
- .process_seg resw 1 ; Segment du callback
-endstruc
-
-%define window_size 16
-
-; Variables globales du WM (à placer dans le segment BDA_CUSTOM ou SEG_GUI)
-wm_active_window_id db 0 ; ID de la fenêtre actuellement active
-
-; -----------------------------------------------------------------------------
-; wm_process_all
-; Remplace la boucle principale. Gère les processus de fenêtre puis la GUI.
-; -----------------------------------------------------------------------------
-wm_process_all:
- pusha
- push ds
- push gs
-
- mov ax, SEG_GUI
- mov gs, ax
-
- ; 1. Gérer les processus des fenêtres
- mov si, 0 ; On suppose que le pool window commence à l'offset 0 d'une zone dédiée
- mov cx, MAX_WINDOWS
-
- .loop_windows:
- cmp byte [gs:si + window.state], WIN_STATE_FREE
- je .next_window
-
- ; VÉRIFICATION : Est-ce que la fenêtre est ACTIVE ?
- ; Selon votre règle : on n'appelle pas le processus si elle n'est pas active.
- cmp byte [gs:si + window.state], WIN_STATE_ACTIVE
- jne .next_window
-
- ; La fenêtre est active, a-t-elle un processus (callback) défini ?
- cmp word [gs:si + window.process_cb], 0
- je .next_window
-
- ; Exécution du processus spécifique à la fenêtre active
- pusha
- ; Appel inter-segment (Far Call) ou intra-segment (Near Call) selon l'architecture
- ; Ici on simule un near call si tout est dans CS
- call word [gs:si + window.process_cb]
- popa
-
- .next_window:
- add si, window_size
- loop .loop_windows
-
- ; 2. Appeler le moteur d'événements des widgets (lib-logic)
- call gui_process_all
-
- pop gs
- pop ds
- popa
- ret
-
-; -----------------------------------------------------------------------------
-; wm_set_active
-; Change la fenêtre active (Focus)
-; In: AL = window_id
-; -----------------------------------------------------------------------------
-wm_set_active:
- push gs
- push bx
-
- ; Sauvegarder le nouvel ID actif
- mov [wm_active_window_id], al
-
- ; Note : Ici vous pourriez rajouter une boucle pour passer toutes les
- ; autres fenêtres en WIN_STATE_INACTIVE et redessiner le tout pour
- ; mettre la fenêtre active au premier plan (Z-Order).
-
- pop bx
- pop gs
- ret
\ No newline at end of file
diff --git a/src/gui/lib-wm-draw.asm b/src/gui/window.asm
similarity index 78%
rename from src/gui/lib-wm-draw.asm
rename to src/gui/window.asm
index 5d22443..da6d9bd 100644
--- a/src/gui/lib-wm-draw.asm
+++ b/src/gui/window.asm
@@ -1,3 +1,63 @@
+; =============================================================================
+; Project : Custom BIOS / ROM
+; File : gui/window.asm
+; Author : frater
+;
+; License : GNU General Public License v3.0 or later (GPL-3.0+)
+;
+; This program is free software: you can redistribute it and/or modify
+; it under the terms of the GNU General Public License as published by
+; the Free Software Foundation, either version 3 of the License, or
+; (at your option) any later version.
+;
+; This program is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with this program. If not, see .
+;
+; =============================================================================
+
+%macro GUI 1-*
+ ; %1 est l'index de la fonction
+ ; On itère sur les arguments suivants en sens inverse (Convention C)
+
+ %rep %0 - 1 ; Répéter pour (Nombre d'args - 1)
+ %rotate -1 ; Prend le dernier argument
+ push %1 ; L'empile
+ %endrep
+
+ %rotate -1 ; On revient au premier argument (l'index de fonction)
+ call word [cs:graph_driver + ((%1)*2)]
+
+ ; Nettoyage de la pile (Convention CDECL: l'appelant nettoie)
+ ; Chaque argument = 2 octets (1 word).
+ add sp, (%0 - 1) * 2
+%endmacro
+
+; ------------------------------------------------------------
+; TABLE DE SAUT (VECTEURS API)
+; Cette table doit être située au début du driver pour être
+; accessible par la GUI à des offsets fixes.
+; ------------------------------------------------------------
+%define WINDOW 0
+
+; ------------------------------------------------------------
+; COMMENTAIRE SUR LA MÉTHODE D'APPEL
+;
+; GFX FUNCTION, Arg1, Arg2, Arg3
+;
+; GFX GFX_PUTPIXEL, 320, 100, 1
+;
+; Si vous changez le code du driver, tant que la table au début
+; ne change pas d'ordre, la GUI n'a pas besoin d'être recompilée.
+; ------------------------------------------------------------
+
+gui_driver:
+ dw draw_window
+
; =============================================================================
; Fonction : draw_window
; Description : Dessine une fenêtre style Mac System 1.0