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 the boot + text test](/doc/assets/Capture-2026-01-29-210122.png) +![Screenshot of the boot + text test](doc/assets/Capture-2026-01-29-210122.png) Screenshot of early boot version + Text functions -![Screenshot WIP - Buttons & Sliders](/doc/assets/Capture-2026-02-03-213148.png) +![Screenshot WIP - Buttons & Sliders](doc/assets/Capture-2026-02-03-213148.png) Screenshot of early buttons & sliders -![Screenshot WIP - Rounded Buttons & Checkboxes ](/doc/assets/Capture-2026-02-06-232336.png) +![Screenshot WIP - Rounded Buttons & Checkboxes ](doc/assets/Capture-2026-02-06-232336.png) 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 86Box](/doc/assets/Capture-86Box.png) +![Screenshot 86Box](doc/assets/Capture-86Box.png) Screenshot from a CGA Hi res test on 86Box. -![Screenshot QEMU VGA](/doc/assets/Screenshot-VGA.png) +![Screenshot QEMU VGA](doc/assets/Screenshot-VGA.png) 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 86Box](/doc/assets/Capture-86Box.png) +![Screenshot 86Box](doc/assets/Capture-86Box.png) Screenshot d'un EcranCGA Hi res test sur 86Box. -![Screenshot QEMU VGA](/doc/assets/Screenshot-VGA.png) +![Screenshot QEMU VGA](doc/assets/Screenshot-VGA.png) 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