starting VGA driver
This commit is contained in:
parent
fcb968beb2
commit
0775fe6193
13 changed files with 1528 additions and 682 deletions
|
|
@ -10,11 +10,13 @@ The processor starts in Real Mode, addressing 1 MB of memory.
|
||||||
| :--- | :--- | :--- | :--- | :--- | :--- |
|
| :--- | :--- | :--- | :--- | :--- | :--- |
|
||||||
| **`0x00000`** | **`0x003FF`** | 1 KB | **IVT** (Interrupt Vector Table) | `0x0000` | `memory.asm` |
|
| **`0x00000`** | **`0x003FF`** | 1 KB | **IVT** (Interrupt Vector Table) | `0x0000` | `memory.asm` |
|
||||||
| **`0x00400`** | **`0x004FF`** | 256 B | **BDA** (BIOS Data Area) Standard | `0x0040` | `memory.asm` |
|
| **`0x00400`** | **`0x004FF`** | 256 B | **BDA** (BIOS Data Area) Standard | `0x0040` | `memory.asm` |
|
||||||
| **`0x00500`** | **`0x005FF`** | 256 B | **Custom BDA** (Driver Data) | `0x0050` | `memory.asm` |
|
| **`0x00500`** | **`0x006FF`** | ~512 B | **Custom BDA** (Driver Data) | `0x0050` | |
|
||||||
| **`0x00600`** | **`0x00AFF`** | 1.25 KB | **GUI RAM** (Widget Allocation) | `0x0060` | `gui/lib.asm` |
|
| **`0x00700`** | **`0x00A6F`** | ~1792 B | **GUI RAM** (Widget Allocation) | **`0x0070`** | `gui/lib-api.asm` |
|
||||||
| **`0x00B00`** | **`0x07FFF`** | 29 KB | **Free** (Low Memory) | | |
|
| **`0x00A70`** | **`0x07FFF`** | ~ 29 KB | **Free** (Low Memory) | | |
|
||||||
| **`0x08000`** | **`0x17FFF`** | 64 KB | **Stack** (Grows downwards) | `0x0800` | `boot.asm` |
|
| **`0x08000`** | **`0x17FFF`** | 64 KB | **Stack** (Grows downwards) | `0x0800` | `boot.asm` |
|
||||||
| **`0x18000`** | **`0x9FFFF`** | 544 KB | **Free** (Conventional RAM) | | |
|
| **`0x18000`** | **`0x1FFFF`** | 32 KB | **Free** | | |
|
||||||
|
| **`0x20000`** | **`0x2FFFF`** | 64 KB | **Heap** (Dynamic Allocation) | `0x2000` | `memory.asm` |
|
||||||
|
| **`0x30000`** | **`0x9FFFF`** | 448 KB | **Free** (Conventional RAM) | | |
|
||||||
| **`0xA0000`** | **`0xAFFFF`** | 64 KB | **VGA RAM** (Graphics Modes) | `0xA000` | `Hardware` |
|
| **`0xA0000`** | **`0xAFFFF`** | 64 KB | **VGA RAM** (Graphics Modes) | `0xA000` | `Hardware` |
|
||||||
| **`0xB0000`** | **`0xB7FFF`** | 32 KB | **MDA RAM** (Monochrome Text) | `0xB000` | `Hardware` |
|
| **`0xB0000`** | **`0xB7FFF`** | 32 KB | **MDA RAM** (Monochrome Text) | `0xB000` | `Hardware` |
|
||||||
| **`0xB8000`** | **`0xBFFFF`** | 32 KB | **VRAM** (CGA / MCGA) | `0xB800` | `generic.asm` |
|
| **`0xB8000`** | **`0xBFFFF`** | 32 KB | **VRAM** (CGA / MCGA) | `0xB800` | `generic.asm` |
|
||||||
|
|
@ -35,11 +37,11 @@ The processor starts in Real Mode, addressing 1 MB of memory.
|
||||||
The project separates the standard IBM BDA from its own variables to avoid conflicts with the VGA BIOS loaded at `0xC000`.
|
The project separates the standard IBM BDA from its own variables to avoid conflicts with the VGA BIOS loaded at `0xC000`.
|
||||||
|
|
||||||
* **Standard BDA (`0040:0000`)**: Used mainly by the VGA BIOS (loaded via QEMU) to store video modes (`0x0049`) and column count (`0x004A`).
|
* **Standard BDA (`0040:0000`)**: Used mainly by the VGA BIOS (loaded via QEMU) to store video modes (`0x0049`) and column count (`0x004A`).
|
||||||
* **Custom BDA (`0050:0000`)**: Defined by `BDA_DATA_SEG`. Stores driver states:
|
* **Custom BDA (`0050:0000`)**: Defined by `BDA_CUSTOM_SEG`. Stores driver states:
|
||||||
* **Mouse**: Input buffer, status, coordinates, background buffer (for cursor).
|
* **Mouse**: Input buffer, status, coordinates, background buffer (for cursor).
|
||||||
* **Gfx**: Text cursor position, attributes.
|
* **Gfx**: Text cursor position, attributes.
|
||||||
* **GUI RAM**: Segment `0x0060` (Physical `0x00600`).
|
* **GUI RAM**: Segment `0x0063` (Physical `0x00630`).
|
||||||
* **Layout**: Located in low memory (`0x0060`) to avoid any collision with the Stack (`0x0800`).
|
* **Layout**: Located in low memory to avoid any collision with the Stack (`0x0800`).
|
||||||
|
|
||||||
#### Stack
|
#### Stack
|
||||||
* **Stack**: Grows downwards from physical address `0xFFFE` (16-bit aligned) of the "Stack Segment" defined by `STACK_SEG`.
|
* **Stack**: Grows downwards from physical address `0xFFFE` (16-bit aligned) of the "Stack Segment" defined by `STACK_SEG`.
|
||||||
|
|
@ -71,11 +73,13 @@ Le processeur démarre en mode réel, adressant 1 Mo de mémoire.
|
||||||
| :--- | :--- | :--- | :--- | :--- | :--- |
|
| :--- | :--- | :--- | :--- | :--- | :--- |
|
||||||
| **`0x00000`** | **`0x003FF`** | 1 KB | **IVT** (Interrupt Vector Table) | `0x0000` | `memory.asm` |
|
| **`0x00000`** | **`0x003FF`** | 1 KB | **IVT** (Interrupt Vector Table) | `0x0000` | `memory.asm` |
|
||||||
| **`0x00400`** | **`0x004FF`** | 256 B | **BDA** (BIOS Data Area) Standard | `0x0040` | `memory.asm` |
|
| **`0x00400`** | **`0x004FF`** | 256 B | **BDA** (BIOS Data Area) Standard | `0x0040` | `memory.asm` |
|
||||||
| **`0x00500`** | **`0x005FF`** | 256 B | **Custom BDA** (Driver Data) | `0x0050` | `memory.asm` |
|
| **`0x00500`** | **`0x006FF`** | ~512 B | **Custom BDA** (Driver Data) | `0x0050` | |
|
||||||
| **`0x00600`** | **`0x00AFF`** | 1.25 KB | **GUI RAM** (Widget Allocation) | `0x0060` | `gui/lib.asm` |
|
| **`0x00700`** | **`0x00A6F`** | ~1792 B | **GUI RAM** (Widget Allocation) | **`0x0070`** | `gui/lib-api.asm` |
|
||||||
| **`0x00B00`** | **`0x07FFF`** | 29 KB | **Free** (Low Memory) | | |
|
| **`0x00A70`** | **`0x07FFF`** | ~ 29 KB | **Free** (Low Memory) | | |
|
||||||
| **`0x08000`** | **`0x17FFF`** | 64 KB | **Stack** (Grows downwards) | `0x0800` | `boot.asm` |
|
| **`0x08000`** | **`0x17FFF`** | 64 KB | **Stack** (Grows downwards) | `0x0800` | `boot.asm` |
|
||||||
| **`0x18000`** | **`0x9FFFF`** | 544 KB | **Free** (Conventional RAM) | | |
|
| **`0x18000`** | **`0x1FFFF`** | 32 KB | **Libre** | | |
|
||||||
|
| **`0x20000`** | **`0x2FFFF`** | 64 KB | **Heap** (Allocation Dynamique) | `0x2000` | `memory.asm` |
|
||||||
|
| **`0x30000`** | **`0x9FFFF`** | 448 KB | **Libre** (RAM Conventionnelle) | | |
|
||||||
| **`0xA0000`** | **`0xAFFFF`** | 64 KB | **VGA RAM** (Graphics Modes) | `0xA000` | `Hardware` |
|
| **`0xA0000`** | **`0xAFFFF`** | 64 KB | **VGA RAM** (Graphics Modes) | `0xA000` | `Hardware` |
|
||||||
| **`0xB0000`** | **`0xB7FFF`** | 32 KB | **MDA RAM** (Monochrome Text) | `0xB000` | `Hardware` |
|
| **`0xB0000`** | **`0xB7FFF`** | 32 KB | **MDA RAM** (Monochrome Text) | `0xB000` | `Hardware` |
|
||||||
| **`0xB8000`** | **`0xBFFFF`** | 32 KB | **VRAM** (CGA / MCGA) | `0xB800` | `generic.asm` |
|
| **`0xB8000`** | **`0xBFFFF`** | 32 KB | **VRAM** (CGA / MCGA) | `0xB800` | `generic.asm` |
|
||||||
|
|
@ -96,11 +100,11 @@ Le processeur démarre en mode réel, adressant 1 Mo de mémoire.
|
||||||
Le projet sépare la BDA standard IBM de ses propres variables pour éviter les conflits avec le BIOS VGA chargé en `0xC000`.
|
Le projet sépare la BDA standard IBM de ses propres variables pour éviter les conflits avec le BIOS VGA chargé en `0xC000`.
|
||||||
|
|
||||||
* **BDA Standard (`0040:0000`)** : Utilisée principalement par le BIOS VGA (chargé via QEMU) pour stocker les modes vidéo (`0x0049`) et le nombre de colonnes (`0x004A`).
|
* **BDA Standard (`0040:0000`)** : Utilisée principalement par le BIOS VGA (chargé via QEMU) pour stocker les modes vidéo (`0x0049`) et le nombre de colonnes (`0x004A`).
|
||||||
* **Custom BDA (`0050:0000`)** : Définie par `BDA_DATA_SEG`. Stocke l'état des drivers :
|
* **Custom BDA (`0050:0000`)** : Définie par `BDA_CUSTOM_SEG`. Stocke l'état des drivers :
|
||||||
* **Souris** : Buffer d'entrée, état, coordonnées, buffer de sauvegarde du fond (pour le curseur).
|
* **Souris** : Buffer d'entrée, état, coordonnées, buffer de sauvegarde du fond (pour le curseur).
|
||||||
* **Gfx** : Position du curseur texte, attributs.
|
* **Gfx** : Position du curseur texte, attributs.
|
||||||
* **GUI RAM** : Segment `0x0060`.
|
* **GUI RAM** : Segment `0x0063` (Physique `0x00630`).
|
||||||
* **Organisation** : Située en mémoire basse (`0x0060`) pour éviter toute collision avec la Pile (`0x0800`).
|
* **Organisation** : Située en mémoire basse pour éviter toute collision avec la Pile (`0x0800`).
|
||||||
|
|
||||||
#### Stack
|
#### Stack
|
||||||
* **Stack** : Grandit vers le bas depuis l'adresse physique `0xFFFE` (Alignement sur 16 bits) du "stack Segment" défini par `STACK_SEG`.
|
* **Stack** : Grandit vers le bas depuis l'adresse physique `0xFFFE` (Alignement sur 16 bits) du "stack Segment" défini par `STACK_SEG`.
|
||||||
|
|
|
||||||
274
src/boot-ok.asm
Normal file
274
src/boot-ok.asm
Normal file
|
|
@ -0,0 +1,274 @@
|
||||||
|
; =============================================================================
|
||||||
|
; Project : Custom BIOS / ROM
|
||||||
|
; File : boot.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 <https://www.gnu.org/licenses/>.
|
||||||
|
;
|
||||||
|
; =============================================================================
|
||||||
|
|
||||||
|
bits 16
|
||||||
|
; ---------------------------------------------------------------------------
|
||||||
|
;
|
||||||
|
; configuration du bios
|
||||||
|
;
|
||||||
|
; ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
; initial stack
|
||||||
|
%define STACK_SEG 0x0800 ; segment de base
|
||||||
|
%define GFX_DRIVERS 'CGA'
|
||||||
|
|
||||||
|
section .text
|
||||||
|
bits 16
|
||||||
|
|
||||||
|
%include "./common/chartable.asm"
|
||||||
|
%include "./common/cursor.asm"
|
||||||
|
%include "./common/patterns.asm"
|
||||||
|
%include "./common/generic.asm"
|
||||||
|
%include "./common/string.asm"
|
||||||
|
|
||||||
|
; definition du BDA
|
||||||
|
%include "./common/bda.asm"
|
||||||
|
|
||||||
|
; drivers
|
||||||
|
%if GFX_DRIVERS == 'VGA'
|
||||||
|
%include "./drivers/gfx_vga.asm"
|
||||||
|
%else
|
||||||
|
; default drivers
|
||||||
|
%include "./drivers/gfx_cgam.asm"
|
||||||
|
%endif
|
||||||
|
|
||||||
|
%include "./drivers/mouse_ps2.asm"
|
||||||
|
%include "./drivers/keyboard_ps2.asm"
|
||||||
|
|
||||||
|
%include "./common/debug_gfx.asm"
|
||||||
|
|
||||||
|
; GUI
|
||||||
|
%include "./gui/lib-api.asm"
|
||||||
|
|
||||||
|
; --- Données texte ---
|
||||||
|
str_quit db "Quitter", 0
|
||||||
|
str_hello db "Hello", 0
|
||||||
|
str_option1 db "option 1", 0
|
||||||
|
str_option2 db "option 2", 0
|
||||||
|
str_option3 db "option 3", 0
|
||||||
|
|
||||||
|
entrycode:
|
||||||
|
cli
|
||||||
|
mov ax, STACK_SEG ; creation du stack par défaut
|
||||||
|
mov ss, ax
|
||||||
|
mov sp, 0xFFFE ; haut du segment (64ko de stack), mot-aligné
|
||||||
|
cld
|
||||||
|
|
||||||
|
call ivt_setup ; configuration d'une table d'interruption "dummy"
|
||||||
|
call bda_setup ; initialisation du BDA
|
||||||
|
|
||||||
|
ISADBG ISA_GREEN, 0x01
|
||||||
|
|
||||||
|
; Install IRQ 0 : timer_isr
|
||||||
|
mov ax,cs
|
||||||
|
mov dx,ax
|
||||||
|
mov bx,timer_isr
|
||||||
|
mov ax,i8259_MASTER_INT
|
||||||
|
|
||||||
|
call ivt_setvector
|
||||||
|
|
||||||
|
ISADBG ISA_GREEN, 0x02
|
||||||
|
|
||||||
|
; initialisation des PIC 8259A
|
||||||
|
call pic_init
|
||||||
|
|
||||||
|
ISADBG ISA_GREEN, 0x04
|
||||||
|
|
||||||
|
; load Roms
|
||||||
|
call setup_load_rom
|
||||||
|
|
||||||
|
ISADBG ISA_GREEN, 0x08
|
||||||
|
|
||||||
|
; on vérifie que le BIOS VGA a installé une INT 10h
|
||||||
|
call setup_check_vga
|
||||||
|
|
||||||
|
ISADBG ISA_GREEN, 0x10
|
||||||
|
|
||||||
|
; enable IRQ 0
|
||||||
|
mov ah,IRQ_ENABLED
|
||||||
|
mov al,0
|
||||||
|
call pic_set_irq_mask
|
||||||
|
|
||||||
|
call kbd_init
|
||||||
|
sti
|
||||||
|
|
||||||
|
DEBUG 0xFADE
|
||||||
|
ISADBG ISA_GREEN, 0x20
|
||||||
|
|
||||||
|
; on active le mode graphique
|
||||||
|
GFX INIT
|
||||||
|
ISADBG ISA_GREEN, 0xFF
|
||||||
|
|
||||||
|
; call mouse_reset
|
||||||
|
call mouse_init
|
||||||
|
|
||||||
|
GFX MOUSE_MOVE
|
||||||
|
GFX MOUSE_SHOW
|
||||||
|
|
||||||
|
ISADBG ISA_RED, 0x81
|
||||||
|
|
||||||
|
xor ax,ax
|
||||||
|
|
||||||
|
.loops:
|
||||||
|
call main_loop
|
||||||
|
|
||||||
|
nop
|
||||||
|
jmp .loops
|
||||||
|
|
||||||
|
; --- Callbacks (Fonctions appelées par le moteur) ---
|
||||||
|
on_click_quit:
|
||||||
|
hlt
|
||||||
|
jmp on_click_quit
|
||||||
|
ret
|
||||||
|
|
||||||
|
on_click_hello:
|
||||||
|
ret
|
||||||
|
|
||||||
|
%define .oldval word [bp-2]
|
||||||
|
%define .my_slider word [bp-4]
|
||||||
|
%define .value word [bp-6]
|
||||||
|
main_loop:
|
||||||
|
push bp
|
||||||
|
mov bp, sp
|
||||||
|
sub sp, 6
|
||||||
|
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
|
||||||
|
DEBUG 1
|
||||||
|
ISADBG ISA_LEFT, 1
|
||||||
|
|
||||||
|
; Init du système GUI
|
||||||
|
call gui_init_system
|
||||||
|
DEBUG 2
|
||||||
|
ISADBG ISA_LEFT, 2
|
||||||
|
|
||||||
|
; --- CRÉATION DYNAMIQUE DES BOUTONS ---
|
||||||
|
|
||||||
|
; Créer Bouton 1 "QUITTER"
|
||||||
|
GUI OBJ_CREATE, OBJ_TYPE_BUTTON_ROUNDED, 10, 10, 80, 16
|
||||||
|
GUI OBJ_SET_TEXT, ax, cs, str_quit
|
||||||
|
; Créer Bouton 2 "HELLO"
|
||||||
|
GUI OBJ_CREATE, OBJ_TYPE_BUTTON_ROUNDED, 100, 50, 80, 16
|
||||||
|
GUI OBJ_SET_TEXT, ax, cs, str_hello
|
||||||
|
|
||||||
|
; Créer 3 checkbox "option"
|
||||||
|
GUI OBJ_CREATE, OBJ_TYPE_CHECKBOX, 200, 50, 100, 15
|
||||||
|
GUI OBJ_SET_TEXT, ax, cs, str_option1
|
||||||
|
|
||||||
|
GUI OBJ_CREATE, OBJ_TYPE_CHECKBOX, 200, 50+16, 100, 15
|
||||||
|
GUI OBJ_SET_TEXT, ax, cs, str_option2
|
||||||
|
|
||||||
|
GUI OBJ_CREATE, OBJ_TYPE_CHECKBOX, 200, 50+16*2, 100, 15
|
||||||
|
GUI OBJ_SET_TEXT, ax, cs, str_option3
|
||||||
|
|
||||||
|
DEBUG 3
|
||||||
|
ISADBG ISA_LEFT, 3
|
||||||
|
|
||||||
|
; Créer Slider (Drag)
|
||||||
|
GUI OBJ_CREATE, OBJ_TYPE_SLIDER, 10, 100, 150, 12
|
||||||
|
GUI OBJ_SET_MODE, ax, SLIDER_HORIZONTAL
|
||||||
|
GUI OBJ_SLIDER_SET_ATTR, ax, 10, 140, 10, 15
|
||||||
|
|
||||||
|
GUI OBJ_CREATE, OBJ_TYPE_SLIDER, 400, 10, 16, 150
|
||||||
|
mov .my_slider, ax
|
||||||
|
|
||||||
|
GUI OBJ_SET_MODE, .my_slider, SLIDER_VERTICAL
|
||||||
|
GUI OBJ_SLIDER_SET_ATTR, .my_slider, 0, 31, 0, 12
|
||||||
|
|
||||||
|
mov .oldval, 0x1256
|
||||||
|
mov .value, 0xFADE
|
||||||
|
|
||||||
|
DEBUG 4
|
||||||
|
ISADBG ISA_LEFT, 4
|
||||||
|
|
||||||
|
.loop:
|
||||||
|
call gui_process_all
|
||||||
|
GUI OBJ_GET_VAL, .my_slider
|
||||||
|
mov .value, ax
|
||||||
|
|
||||||
|
cmp ax,.oldval
|
||||||
|
je .loop
|
||||||
|
|
||||||
|
; debug
|
||||||
|
mov .oldval, ax
|
||||||
|
GFX RECTANGLE_FILL,0,148,50,166, PATTERN_WHITE
|
||||||
|
GFX GOTOXY, 8, 150
|
||||||
|
|
||||||
|
mov ax, .value
|
||||||
|
call print_word_hex
|
||||||
|
; end debug
|
||||||
|
|
||||||
|
; change palette...
|
||||||
|
;and ax, 0x00FF
|
||||||
|
;mov bh, 0x00
|
||||||
|
;mov bl, al
|
||||||
|
;mov ah, 0x0b
|
||||||
|
;mov al, 0x00
|
||||||
|
;int 0x10
|
||||||
|
|
||||||
|
mov dx, CRTC_COLOR_DATA
|
||||||
|
and ax, 0x001F
|
||||||
|
out dx, ax
|
||||||
|
|
||||||
|
jmp .loop
|
||||||
|
leave
|
||||||
|
ret
|
||||||
|
|
||||||
|
; -----------------------------------------------------------
|
||||||
|
; timer ISR (IRQ -> INT)
|
||||||
|
; -----------------------------------------------------------
|
||||||
|
timer_isr:
|
||||||
|
push ax
|
||||||
|
|
||||||
|
push fs
|
||||||
|
mov ax,BDA_CUSTOM_SEG
|
||||||
|
mov fs,ax
|
||||||
|
; exemple de fonctionnement:
|
||||||
|
; inc byte [fs:BDA_TIMER]
|
||||||
|
|
||||||
|
mov al, PIC_EOI ; EOI master
|
||||||
|
out i8259_MASTER_CMD, al
|
||||||
|
pop fs
|
||||||
|
|
||||||
|
pop ax
|
||||||
|
iret
|
||||||
|
|
||||||
|
; ------------------------------------------------------------------
|
||||||
|
; Padding jusqu'au reset vector
|
||||||
|
; ------------------------------------------------------------------
|
||||||
|
times 0xFFF0 - ($ - $$) db 0xFF
|
||||||
|
|
||||||
|
; ------------------------------------------------------------------
|
||||||
|
; RESET VECTOR (exécuté par le CPU)
|
||||||
|
; ------------------------------------------------------------------
|
||||||
|
section .resetvect
|
||||||
|
bits 16
|
||||||
|
global reset_vector
|
||||||
|
|
||||||
|
reset_vector:
|
||||||
|
; code minimal au reset
|
||||||
|
jmp 0xF000:entrycode
|
||||||
|
|
||||||
|
builddate:
|
||||||
|
db __DATE__
|
||||||
|
times 16-($-$$) db 0 ; le stub tient dans 16 octets (ou moins)
|
||||||
105
src/boot.asm
105
src/boot.asm
|
|
@ -29,13 +29,9 @@
|
||||||
|
|
||||||
; initial stack
|
; initial stack
|
||||||
%define STACK_SEG 0x0800 ; segment de base
|
%define STACK_SEG 0x0800 ; segment de base
|
||||||
|
%define GFX_DRIVERS 'VGA'
|
||||||
|
|
||||||
;section .text
|
%define DEBUGER_ENABLED
|
||||||
; bits 16
|
|
||||||
;
|
|
||||||
; db 'EXTRA CODE Section',0
|
|
||||||
;
|
|
||||||
; times 0xFFFF - ($ - $$) db 0xFF
|
|
||||||
|
|
||||||
section .text
|
section .text
|
||||||
bits 16
|
bits 16
|
||||||
|
|
@ -50,15 +46,20 @@ section .text
|
||||||
%include "./common/bda.asm"
|
%include "./common/bda.asm"
|
||||||
|
|
||||||
; drivers
|
; drivers
|
||||||
%include "./drivers/gfx_cgam.asm"
|
%if GFX_DRIVERS == 'VGA'
|
||||||
|
%include "./drivers/gfx_vga.asm"
|
||||||
|
%else
|
||||||
|
; default drivers
|
||||||
|
%include "./drivers/gfx_cgam.asm"
|
||||||
|
%endif
|
||||||
|
|
||||||
%include "./drivers/mouse_ps2.asm"
|
%include "./drivers/mouse_ps2.asm"
|
||||||
%include "./drivers/keyboard_ps2.asm"
|
%include "./drivers/keyboard_ps2.asm"
|
||||||
|
|
||||||
%include "./common/debug_cga.asm"
|
%include "./common/debug_gfx.asm"
|
||||||
|
|
||||||
; GUI
|
; GUI
|
||||||
%include "./gui/lib.asm"
|
; %include "./gui/lib-api.asm"
|
||||||
%include "./gui/draw.asm"
|
|
||||||
|
|
||||||
; --- Données texte ---
|
; --- Données texte ---
|
||||||
str_quit db "Quitter", 0
|
str_quit db "Quitter", 0
|
||||||
|
|
@ -86,24 +87,12 @@ entrycode:
|
||||||
mov ax,i8259_MASTER_INT
|
mov ax,i8259_MASTER_INT
|
||||||
|
|
||||||
call ivt_setvector
|
call ivt_setvector
|
||||||
|
|
||||||
ISADBG ISA_GREEN, 2
|
|
||||||
|
|
||||||
; initialisation des PIC 8259A
|
; initialisation des PIC 8259A
|
||||||
call pic_init
|
call pic_init
|
||||||
|
|
||||||
ISADBG ISA_GREEN, 4
|
|
||||||
|
|
||||||
; load Roms
|
; load Roms
|
||||||
call setup_load_rom
|
call setup_load_rom
|
||||||
|
|
||||||
ISADBG ISA_GREEN, 8
|
|
||||||
|
|
||||||
; on vérifie que le BIOS VGA a installé une INT 10h
|
; on vérifie que le BIOS VGA a installé une INT 10h
|
||||||
call setup_check_vga
|
call setup_check_vga
|
||||||
|
|
||||||
ISADBG ISA_GREEN, 16
|
|
||||||
|
|
||||||
; enable IRQ 0
|
; enable IRQ 0
|
||||||
mov ah,IRQ_ENABLED
|
mov ah,IRQ_ENABLED
|
||||||
mov al,0
|
mov al,0
|
||||||
|
|
@ -112,19 +101,18 @@ entrycode:
|
||||||
call kbd_init
|
call kbd_init
|
||||||
sti
|
sti
|
||||||
|
|
||||||
DEBUG 0xFADE
|
|
||||||
|
|
||||||
ISADBG ISA_GREEN, 32
|
ISADBG ISA_GREEN, 32
|
||||||
|
|
||||||
; on active le mode graphique
|
; on active le mode graphique
|
||||||
GFX INIT
|
GFX INIT
|
||||||
call mouse_init
|
call mouse_reset
|
||||||
|
|
||||||
|
; call mouse_init
|
||||||
|
|
||||||
GFX MOUSE_MOVE
|
GFX MOUSE_MOVE
|
||||||
ISADBG ISA_RED, 0x80
|
ISADBG ISA_RED, 0x80
|
||||||
|
|
||||||
GFX MOUSE_SHOW
|
GFX MOUSE_SHOW
|
||||||
|
|
||||||
ISADBG ISA_RED, 0x81
|
ISADBG ISA_RED, 0x81
|
||||||
|
|
||||||
.loops:
|
.loops:
|
||||||
|
|
@ -155,71 +143,14 @@ main_loop:
|
||||||
ISADBG ISA_LEFT, 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_LEFT, 2
|
ISADBG ISA_LEFT, 2
|
||||||
|
|
||||||
; --- CRÉATION DYNAMIQUE DES BOUTONS ---
|
.loop:
|
||||||
|
; call gui_process_all
|
||||||
; Créer Bouton 1 "QUITTER"
|
|
||||||
GUI OBJ_CREATE, OBJ_TYPE_BUTTON_ROUNDED, 10, 10, 80, 16
|
|
||||||
GUI OBJ_SET_TEXT, ax, cs, str_quit
|
|
||||||
; Créer Bouton 2 "HELLO"
|
|
||||||
GUI OBJ_CREATE, OBJ_TYPE_BUTTON_ROUNDED, 100, 50, 80, 16
|
|
||||||
GUI OBJ_SET_TEXT, ax, cs, str_hello
|
|
||||||
; Créer checkbox 3 "option 1"
|
|
||||||
GUI OBJ_CREATE, OBJ_TYPE_CHECKBOX, 200, 50, 100, 15
|
|
||||||
GUI OBJ_SET_TEXT, ax, cs, str_option1
|
|
||||||
|
|
||||||
GUI OBJ_CREATE, OBJ_TYPE_CHECKBOX, 200, 50+16, 100, 15
|
|
||||||
GUI OBJ_SET_TEXT, ax, cs, str_option2
|
|
||||||
|
|
||||||
GUI OBJ_CREATE, OBJ_TYPE_CHECKBOX, 200, 50+16*2, 100, 15
|
|
||||||
GUI OBJ_SET_TEXT, ax, cs, str_option3
|
|
||||||
|
|
||||||
DEBUG 3
|
|
||||||
ISADBG ISA_LEFT, 3
|
|
||||||
|
|
||||||
; Créer Slider (Drag)
|
|
||||||
GUI OBJ_CREATE, OBJ_TYPE_SLIDER, 10, 100, 150, 12
|
|
||||||
GUI OBJ_SET_MODE, ax, SLIDER_HORIZONTAL
|
|
||||||
GUI OBJ_SLIDER_SET_ATTR, ax, 10, 140, 10, 15
|
|
||||||
|
|
||||||
GUI OBJ_CREATE, OBJ_TYPE_SLIDER, 400, 10, 16, 150
|
|
||||||
mov .my_slider, ax
|
|
||||||
|
|
||||||
GUI OBJ_SET_MODE, .my_slider, SLIDER_VERTICAL
|
|
||||||
GUI OBJ_SLIDER_SET_ATTR, .my_slider, 0, 15, 15, 12
|
|
||||||
|
|
||||||
mov .oldval, 0x1256
|
|
||||||
mov .value, 0xFADE
|
|
||||||
|
|
||||||
DEBUG 4
|
|
||||||
ISADBG ISA_LEFT, 4
|
|
||||||
|
|
||||||
.loop:
|
|
||||||
call gui_process_all
|
|
||||||
GUI OBJ_GET_VAL, .my_slider
|
|
||||||
mov .value, ax
|
|
||||||
|
|
||||||
cmp ax,.oldval
|
|
||||||
je .loop
|
|
||||||
|
|
||||||
; debug
|
|
||||||
mov .oldval, ax
|
|
||||||
GFX RECTANGLE_FILL,0,148,50,166, PATTERN_WHITE
|
|
||||||
GFX GOTOXY, 8, 150
|
|
||||||
|
|
||||||
mov ax, .value
|
|
||||||
call print_word_hex
|
|
||||||
; end debug
|
|
||||||
|
|
||||||
mov dx, 0x3d9
|
|
||||||
mov ax, .value
|
|
||||||
and ax, 0x000F
|
|
||||||
out dx, al
|
|
||||||
|
|
||||||
jmp .loop
|
jmp .loop
|
||||||
leave
|
leave
|
||||||
|
|
@ -232,7 +163,7 @@ timer_isr:
|
||||||
push ax
|
push ax
|
||||||
|
|
||||||
push fs
|
push fs
|
||||||
mov ax,BDA_DATA_SEG
|
mov ax,BDA_CUSTOM_SEG
|
||||||
mov fs,ax
|
mov fs,ax
|
||||||
; exemple de fonctionnement:
|
; exemple de fonctionnement:
|
||||||
; inc byte [fs:BDA_TIMER]
|
; inc byte [fs:BDA_TIMER]
|
||||||
|
|
|
||||||
|
|
@ -24,11 +24,9 @@
|
||||||
; https://wiki.nox-rhea.org/back2root/ibm-pc-ms-dos/hardware/informations/bios_data_area
|
; https://wiki.nox-rhea.org/back2root/ibm-pc-ms-dos/hardware/informations/bios_data_area
|
||||||
;
|
;
|
||||||
|
|
||||||
%define BDA_SEGMENT 0x0040 ; segment BDA
|
%define BDA_SEGMENT 0x0040 ; segment BDA (historically)
|
||||||
|
%define BDA_CUSTOM_SEG 0x0050 ; custom data (mouse, gfx cursor, etc..)
|
||||||
; custom vars
|
%define BDA_GUI_WIDGET 0x0070 ; Segment de données UI (Safe: après Stack, avant Heap)
|
||||||
%define BDA_INFO_MEM_SIZE 0x0014 ; Memory size in Kbytes
|
|
||||||
%define BDA_INFO_MEM_SEG BDA_INFO_MEM_SIZE+2 ; highest Memory Segment
|
|
||||||
|
|
||||||
; video related information (compatible with VGA bios)
|
; video related information (compatible with VGA bios)
|
||||||
%define BDA_VIDEO_CURR_MODE 0x0049
|
%define BDA_VIDEO_CURR_MODE 0x0049
|
||||||
|
|
@ -38,7 +36,8 @@
|
||||||
;
|
;
|
||||||
; information relative à la souris
|
; information relative à la souris
|
||||||
;
|
;
|
||||||
%define BDA_DATA_SEG 0x0050
|
|
||||||
|
%define BDA_BitPP 4
|
||||||
|
|
||||||
%define BKG_DWORDS_PER_LINE 1 ; 1 dword stocké par ligne
|
%define BKG_DWORDS_PER_LINE 1 ; 1 dword stocké par ligne
|
||||||
%define BKG_LINES 16
|
%define BKG_LINES 16
|
||||||
|
|
@ -63,7 +62,8 @@ struc mouse
|
||||||
.cur_ofs resw 1 ;
|
.cur_ofs resw 1 ;
|
||||||
.bkg_saved resb 1 ; background saved
|
.bkg_saved resb 1 ; background saved
|
||||||
alignb 4 ; alignement 4 bytes
|
alignb 4 ; alignement 4 bytes
|
||||||
.bkg_buffer resd 16 ; buffer for saved background
|
; buffer for saved background
|
||||||
|
.bkg_buffer resd 16*BDA_BitPP
|
||||||
endstruc
|
endstruc
|
||||||
|
|
||||||
struc gfx
|
struc gfx
|
||||||
|
|
@ -86,7 +86,7 @@ bda_setup:
|
||||||
pusha
|
pusha
|
||||||
push ds
|
push ds
|
||||||
|
|
||||||
mov ax, BDA_DATA_SEG
|
mov ax, BDA_CUSTOM_SEG
|
||||||
mov es, ax
|
mov es, ax
|
||||||
|
|
||||||
mov ax, 0x5F
|
mov ax, 0x5F
|
||||||
|
|
|
||||||
|
|
@ -42,8 +42,7 @@ dump_ram_words:
|
||||||
call print_word_hex ; Affiche AX sous forme "XXXX"
|
call print_word_hex ; Affiche AX sous forme "XXXX"
|
||||||
|
|
||||||
; (Optionnel) Ajouter un espace entre chaque mot pour la lisibilité
|
; (Optionnel) Ajouter un espace entre chaque mot pour la lisibilité
|
||||||
mov al, ' '
|
GFX PUTCH, ' '
|
||||||
call cga_putc
|
|
||||||
|
|
||||||
pop si ; Restaure SI
|
pop si ; Restaure SI
|
||||||
pop cx ; Restaure CX
|
pop cx ; Restaure CX
|
||||||
|
|
@ -77,9 +76,7 @@ print_word_hex:
|
||||||
|
|
||||||
xor bx, bx
|
xor bx, bx
|
||||||
mov bl, al
|
mov bl, al
|
||||||
push bx
|
GFX PUTCH, bx
|
||||||
call cga_putc
|
|
||||||
add sp, 2
|
|
||||||
loop .next_digit ; Répète 4 fois
|
loop .next_digit ; Répète 4 fois
|
||||||
|
|
||||||
popa
|
popa
|
||||||
|
|
@ -20,16 +20,12 @@
|
||||||
;
|
;
|
||||||
; =============================================================================
|
; =============================================================================
|
||||||
|
|
||||||
%define DISABLE_DEBUGER
|
%ifdef DEBUGER_ENABLED
|
||||||
|
|
||||||
%ifndef DISABLE_DEBUGER
|
|
||||||
|
|
||||||
%macro DEBUG 1
|
%macro DEBUG 1
|
||||||
GFX GOTOXY, 0, 0
|
GFX GOTOXY, 0, 0
|
||||||
mov ax, %1
|
mov ax, %1
|
||||||
call print_word_hex
|
call print_word_hex
|
||||||
%endmacro
|
%endmacro
|
||||||
|
|
||||||
;
|
;
|
||||||
; Debugger for 86Box
|
; Debugger for 86Box
|
||||||
;
|
;
|
||||||
|
|
@ -111,6 +107,26 @@
|
||||||
%define IRQ_ENABLED 0x00
|
%define IRQ_ENABLED 0x00
|
||||||
%define IRQ_DISABLED 0x01
|
%define IRQ_DISABLED 0x01
|
||||||
|
|
||||||
|
; ---------------------------------------------------------------------------
|
||||||
|
; CGA/MDA Controler
|
||||||
|
; ---------------------------------------------------------------------------
|
||||||
|
;
|
||||||
|
; MDA 6845
|
||||||
|
%define CRTC_6845_MONO 0x03b4
|
||||||
|
%define CRTC_6845_MONO_REGISTER 0x03b5
|
||||||
|
;
|
||||||
|
; CGA 6845
|
||||||
|
%define CRTC_6845_COLOR 0x03d4
|
||||||
|
%define CRTC_6845_COLOR_REGISTER 0x03d4
|
||||||
|
%define CRTC_COLOR_REGISTER 0x03d5
|
||||||
|
|
||||||
|
%define CRTC_COLOR_CTRL 0x03d8
|
||||||
|
%define CRTC_COLOR_DATA 0x03d9
|
||||||
|
|
||||||
|
%define EGAVGA_CONTROLLER 0x03ce
|
||||||
|
|
||||||
|
%define VGA_SEQUENCER 0x03c4
|
||||||
|
|
||||||
; ---------------------------------------------------------------------------
|
; ---------------------------------------------------------------------------
|
||||||
; Détection les ROM supplementaires
|
; Détection les ROM supplementaires
|
||||||
; Teste la RAM de 0xC000 jusqu’à 0xE000, par pas de 2KB.
|
; Teste la RAM de 0xC000 jusqu’à 0xE000, par pas de 2KB.
|
||||||
|
|
|
||||||
|
|
@ -13,9 +13,16 @@
|
||||||
|
|
||||||
align 8
|
align 8
|
||||||
pattern_8x8:
|
pattern_8x8:
|
||||||
dq 0x0000000000000000 ; pattern_black (Tout à 0 = Noir)
|
dq 0x0000000000000000 ; 0 : pattern_black (Tout à 0 = Noir)
|
||||||
dq 0x2200880022008800 ; pattern_gray_dark (Majorité de 0)
|
dq 0x2200880022008800 ; 1 : pattern_gray_dark (Majorité de 0)
|
||||||
dq 0x2288228822882288 ; pattern_gray_mid
|
dq 0x2288228822882288 ; 2 : pattern_gray_mid
|
||||||
dq 0xAA55AA55AA55AA55 ; pattern_gray_light (50/50)
|
dq 0xAA55AA55AA55AA55 ; 3 : pattern_gray_light (50/50)
|
||||||
dq 0x77DD77DD77DD77DD ; pattern_white_light (Majorité de 1 = Clair)
|
dq 0x77DD77DD77DD77DD ; 4 : pattern_white_light (Majorité de 1 = Clair)
|
||||||
dq 0xFFFFFFFFFFFFFFFF ; pattern_white (Tout à 1 = Blanc)
|
dq 0xFFFFFFFFFFFFFFFF ; 5 : pattern_white (Tout à 1 = Blanc)
|
||||||
|
|
||||||
|
|
||||||
|
%macro PATTERN_PTR 1
|
||||||
|
mov ax, cs
|
||||||
|
mov ds, ax
|
||||||
|
lea esi, [pattern_8x8 + (%1 * 8)]
|
||||||
|
%endmacro
|
||||||
|
|
@ -31,7 +31,6 @@
|
||||||
|
|
||||||
%define CGA_STRIDE 80
|
%define CGA_STRIDE 80
|
||||||
%define CGA_ODD_BANK 0x2000
|
%define CGA_ODD_BANK 0x2000
|
||||||
|
|
||||||
;
|
;
|
||||||
; bit : descr
|
; bit : descr
|
||||||
; 0 : text color : 0=black, 1=white
|
; 0 : text color : 0=black, 1=white
|
||||||
|
|
@ -78,6 +77,7 @@
|
||||||
%define MOUSE_HIDE 11
|
%define MOUSE_HIDE 11
|
||||||
%define MOUSE_SHOW 12
|
%define MOUSE_SHOW 12
|
||||||
%define MOUSE_MOVE 13
|
%define MOUSE_MOVE 13
|
||||||
|
%define MOUSE_DRAW 14
|
||||||
|
|
||||||
; ------------------------------------------------------------
|
; ------------------------------------------------------------
|
||||||
; COMMENTAIRE SUR LA MÉTHODE D'APPEL
|
; COMMENTAIRE SUR LA MÉTHODE D'APPEL
|
||||||
|
|
@ -105,6 +105,7 @@ graph_driver:
|
||||||
dw cga_mouse_hide ; déplacement du curseur
|
dw cga_mouse_hide ; déplacement du curseur
|
||||||
dw cga_mouse_show ; déplacement du curseur
|
dw cga_mouse_show ; déplacement du curseur
|
||||||
dw cga_mouse_cursor_move ; déplacement du curseur
|
dw cga_mouse_cursor_move ; déplacement du curseur
|
||||||
|
dw cga_cursor_draw
|
||||||
|
|
||||||
; ------------------------------------------------------------
|
; ------------------------------------------------------------
|
||||||
; initialise le mode graphique (via l'int 10h)
|
; initialise le mode graphique (via l'int 10h)
|
||||||
|
|
@ -112,7 +113,7 @@ graph_driver:
|
||||||
; ce mode est entrelacé, un bit/pixel, 8 pixels par octet
|
; ce mode est entrelacé, un bit/pixel, 8 pixels par octet
|
||||||
; ------------------------------------------------------------
|
; ------------------------------------------------------------
|
||||||
cga_init:
|
cga_init:
|
||||||
mov ax, BDA_DATA_SEG
|
mov ax, BDA_CUSTOM_SEG
|
||||||
mov ds, ax
|
mov ds, ax
|
||||||
|
|
||||||
; init graphics mode
|
; init graphics mode
|
||||||
|
|
@ -180,7 +181,7 @@ cga_set_writemode:
|
||||||
|
|
||||||
push fs
|
push fs
|
||||||
push ax
|
push ax
|
||||||
mov ax, BDA_DATA_SEG
|
mov ax, BDA_CUSTOM_SEG
|
||||||
mov fs,ax
|
mov fs,ax
|
||||||
|
|
||||||
mov ax, .mode
|
mov ax, .mode
|
||||||
|
|
@ -211,7 +212,7 @@ cga_set_charpos:
|
||||||
pusha
|
pusha
|
||||||
push fs
|
push fs
|
||||||
|
|
||||||
mov ax,BDA_DATA_SEG
|
mov ax,BDA_CUSTOM_SEG
|
||||||
mov fs,ax
|
mov fs,ax
|
||||||
|
|
||||||
; store x,y en pixel
|
; store x,y en pixel
|
||||||
|
|
@ -314,7 +315,7 @@ cga_putc:
|
||||||
|
|
||||||
mov bx, VIDEO_SEG
|
mov bx, VIDEO_SEG
|
||||||
mov es, bx
|
mov es, bx
|
||||||
mov bx, BDA_DATA_SEG
|
mov bx, BDA_CUSTOM_SEG
|
||||||
mov fs, bx
|
mov fs, bx
|
||||||
|
|
||||||
mov ax, .car
|
mov ax, .car
|
||||||
|
|
@ -1267,7 +1268,7 @@ cga_mouse_hide:
|
||||||
pusha ; 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_CUSTOM_SEG
|
||||||
mov ds, ax
|
mov ds, ax
|
||||||
|
|
||||||
; Décrémenter le compteur
|
; Décrémenter le compteur
|
||||||
|
|
@ -1295,7 +1296,7 @@ cga_mouse_show:
|
||||||
pusha
|
pusha
|
||||||
push ds
|
push ds
|
||||||
|
|
||||||
mov ax, BDA_DATA_SEG
|
mov ax, BDA_CUSTOM_SEG
|
||||||
mov ds, ax
|
mov ds, ax
|
||||||
|
|
||||||
; Incrémenter le compteur
|
; Incrémenter le compteur
|
||||||
|
|
@ -1327,7 +1328,7 @@ cga_mouse_cursor_move:
|
||||||
push es
|
push es
|
||||||
|
|
||||||
; move Data Segment
|
; move Data Segment
|
||||||
mov ax, BDA_DATA_SEG
|
mov ax, BDA_CUSTOM_SEG
|
||||||
mov ds, ax
|
mov ds, ax
|
||||||
|
|
||||||
cmp byte [BDA_MOUSE + mouse.cur_counter], 0
|
cmp byte [BDA_MOUSE + mouse.cur_counter], 0
|
||||||
|
|
@ -1437,10 +1438,7 @@ cga_cursor_restorebg:
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; ============================================================
|
; ============================================================
|
||||||
; gfx_cursor_draw_rm16_i386_self
|
; cga_cursor_draw
|
||||||
; Entrée:
|
|
||||||
; DS = BDA_DATA_SEG
|
|
||||||
; 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 .height word [bp-2]
|
||||||
|
|
@ -1456,24 +1454,23 @@ cga_cursor_draw:
|
||||||
push gs
|
push gs
|
||||||
|
|
||||||
cld ; Sécurité : Direction avant
|
cld ; Sécurité : Direction avant
|
||||||
mov ax, BDA_DATA_SEG
|
mov ax, BDA_CUSTOM_SEG
|
||||||
mov ds, ax
|
mov ds, ax
|
||||||
mov ax, VIDEO_SEG
|
mov ax, VIDEO_SEG
|
||||||
mov es, ax
|
mov es, ax
|
||||||
|
|
||||||
; --- CLIPPING VERTICAL ---
|
; --- CLIPPING VERTICAL ---
|
||||||
mov dx, [ds:BDA_MOUSE + mouse.y]
|
mov dx, [ds:BDA_MOUSE + mouse.y]
|
||||||
cmp dx, 200
|
mov bx, GFX_HEIGHT
|
||||||
|
cmp dx, bx
|
||||||
jae .exit_total
|
jae .exit_total
|
||||||
|
|
||||||
mov ax, 16
|
mov ax, 16
|
||||||
mov bx, 200
|
|
||||||
sub bx, dx ; 200-y
|
sub bx, dx ; 200-y
|
||||||
cmp ax, bx
|
cmp ax, bx
|
||||||
jbe .y_ok ; y<= 200-16
|
jbe .y_ok ; y<= 200-16
|
||||||
|
|
||||||
mov ax, bx
|
mov ax, bx
|
||||||
|
|
||||||
.y_ok:
|
.y_ok:
|
||||||
mov .height, ax
|
mov .height, ax
|
||||||
|
|
||||||
|
|
|
||||||
619
src/drivers/gfx_vga.asm
Normal file
619
src/drivers/gfx_vga.asm
Normal file
|
|
@ -0,0 +1,619 @@
|
||||||
|
; =============================================================================
|
||||||
|
; Project : Custom BIOS / ROM
|
||||||
|
; File : gfx_vga.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 <https://www.gnu.org/licenses/>.
|
||||||
|
;
|
||||||
|
; =============================================================================
|
||||||
|
|
||||||
|
;
|
||||||
|
; graphics drivers pour carte video/mode CGA-Mono (640x200x2)
|
||||||
|
;
|
||||||
|
%define VIDEO_SEG 0A000h
|
||||||
|
|
||||||
|
%define GFX_MODE 0x12 ; VGA HiRes (640x480x16)
|
||||||
|
%define GFX_WIDTH 640
|
||||||
|
%define GFX_HEIGHT 480
|
||||||
|
;
|
||||||
|
; bit : descr
|
||||||
|
; 0 : text color : 0=black, 1=white
|
||||||
|
; 1 : transparent : 1=apply background attribut
|
||||||
|
;
|
||||||
|
%define GFX_TXT_WHITE_TRANSPARENT 00000000b
|
||||||
|
%define GFX_TXT_BLACK_TRANSPARENT 00000001b
|
||||||
|
%define GFX_TXT_WHITE 00000010b
|
||||||
|
%define GFX_TXT_BLACK 00000011b
|
||||||
|
|
||||||
|
%macro GFX 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 INIT 0
|
||||||
|
%define PUTPIXEL 1
|
||||||
|
%define GETPIXEL 2
|
||||||
|
%define GOTOXY 3
|
||||||
|
%define TXT_MODE 4
|
||||||
|
%define PUTCH 5
|
||||||
|
%define WRITE 6
|
||||||
|
%define LINE 7
|
||||||
|
%define RECTANGLE 8
|
||||||
|
%define RECTANGLE_FILL 9
|
||||||
|
%define RECTANGLE_ROUND 10
|
||||||
|
%define MOUSE_HIDE 11
|
||||||
|
%define MOUSE_SHOW 12
|
||||||
|
%define MOUSE_MOVE 13
|
||||||
|
%define MOUSE_DRAW 14
|
||||||
|
|
||||||
|
; ------------------------------------------------------------
|
||||||
|
; 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.
|
||||||
|
; ------------------------------------------------------------
|
||||||
|
align 2
|
||||||
|
graph_driver:
|
||||||
|
dw vga_init ; init de la carte graphique
|
||||||
|
dw vga_putpixel ; dessin d'un pixel
|
||||||
|
dw vga_none ; lecture d'un pixel
|
||||||
|
dw vga_none ; gotoxy
|
||||||
|
dw vga_none ; mode texte
|
||||||
|
dw vga_none ; dessin d'un caractère
|
||||||
|
dw vga_none ; dessin d'une chaine de caractère
|
||||||
|
dw vga_none ; dessin d'une ligne (Bresenham) avec décision horizontale/verticale
|
||||||
|
dw vga_none ; dessin d'un rectangle
|
||||||
|
dw vga_none ; dessin d'un rectangle plein
|
||||||
|
dw vga_none ; dessin d'un rectangle arrondi
|
||||||
|
dw vga_mouse_hide ; cache la souris
|
||||||
|
dw vga_mouse_show ; montre la souris
|
||||||
|
dw vga_mouse_cursor_move ; déplacement du curseur
|
||||||
|
dw vga_cursor_draw
|
||||||
|
|
||||||
|
; ------------------------------------------------------------
|
||||||
|
; dummy function
|
||||||
|
;
|
||||||
|
; cette fonction ne sert a rien, juste a "occuper" l'espace
|
||||||
|
; dans la table pour fonction qui n'existent pas
|
||||||
|
; ------------------------------------------------------------
|
||||||
|
vga_none:
|
||||||
|
ret
|
||||||
|
|
||||||
|
; ------------------------------------------------------------
|
||||||
|
; initialise le mode graphique (via l'int 10h)
|
||||||
|
;
|
||||||
|
; ce mode est entrelacé, un bit/pixel, 8 pixels par octet
|
||||||
|
; ------------------------------------------------------------
|
||||||
|
vga_init:
|
||||||
|
; init graphics mode
|
||||||
|
mov ah, 0x00 ; AH=00h set video mode
|
||||||
|
mov al, GFX_MODE
|
||||||
|
int 0x10
|
||||||
|
|
||||||
|
; dessine un background "check-board"
|
||||||
|
; Les patterns sont dans le segment de code (CS)
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
|
||||||
|
PATTERN_PTR PATTERN_GRAY_LIGHT
|
||||||
|
mov bl, 15
|
||||||
|
call vga_background
|
||||||
|
ISADBG ISA_GREEN, 0x88
|
||||||
|
ret
|
||||||
|
|
||||||
|
; ------------------------------------------------------------
|
||||||
|
; vga_calc_addr
|
||||||
|
; Entrée:
|
||||||
|
; CX = X (0-639)
|
||||||
|
; DX = Y (0-479)
|
||||||
|
; Sortie:
|
||||||
|
; DI = Offset dans le segment A000h
|
||||||
|
; ------------------------------------------------------------
|
||||||
|
vga_calc_addr:
|
||||||
|
push ax
|
||||||
|
push dx
|
||||||
|
|
||||||
|
; Calcul de Y * 80
|
||||||
|
; 80 = 64 + 16 (soit Y<<6 + Y<<4) pour éviter une multiplication lente
|
||||||
|
mov ax, dx ; AX = Y
|
||||||
|
shl ax, 4 ; AX = Y * 16
|
||||||
|
mov di, ax ; DI = Y * 16
|
||||||
|
shl ax, 2 ; AX = (Y * 16) * 4 = Y * 64
|
||||||
|
add di, ax ; DI = (Y * 64) + (Y * 16) = Y * 80
|
||||||
|
|
||||||
|
; Ajout de X / 8
|
||||||
|
shr cx, 3 ; CX = X / 8 (octet horizontal)
|
||||||
|
add di, cx ; DI = (Y * 80) + (X / 8)
|
||||||
|
|
||||||
|
pop dx
|
||||||
|
pop ax
|
||||||
|
ret
|
||||||
|
|
||||||
|
; Entrée: ESI = Pointeur vers le tableau de 8 octets (pattern 8x8)
|
||||||
|
; BL = Couleur de premier plan (0-15)
|
||||||
|
vga_background:
|
||||||
|
; pushad
|
||||||
|
|
||||||
|
; Configuration VGA pour le remplissage de masse
|
||||||
|
mov dx, VGA_SEQUENCER ; Sequencer
|
||||||
|
mov ax, 0F02h ; Map Mask (Index 2) = 0Fh (Tous les plans)
|
||||||
|
out dx, ax
|
||||||
|
|
||||||
|
; Graphics Controller
|
||||||
|
mov dx, EGAVGA_CONTROLLER
|
||||||
|
mov ax, 0305h ; Mode Register (Index 5) = Mode 3
|
||||||
|
out dx, ax
|
||||||
|
|
||||||
|
mov al, 00h ; Set/Reset (Index 0) = Couleur
|
||||||
|
mov ah, bl
|
||||||
|
out dx, ax
|
||||||
|
|
||||||
|
; Initialisation mémoire
|
||||||
|
mov ax, VIDEO_SEG
|
||||||
|
mov es, ax
|
||||||
|
xor edi, edi ; ES:EDI = Début mémoire vidéo
|
||||||
|
movzx esi, si ; Nettoyer ESI (garder SI) pour l'adressage
|
||||||
|
|
||||||
|
; Boucle principale (480 lignes)
|
||||||
|
xor edx, edx ; EDX servira d'index pour le pattern (0-7)
|
||||||
|
mov ecx, 480
|
||||||
|
|
||||||
|
.line_loop:
|
||||||
|
mov al, [esi + edx] ; Charger l'octet du pattern pour la ligne actuelle
|
||||||
|
; Répliquer l'octet AL dans EAX (ex: 0xAA -> 0xAAAAAAAA) pour le 32-bit
|
||||||
|
mov ah, al ; copy byte 0 -> byte 1
|
||||||
|
mov bx, ax ; préserve word
|
||||||
|
shl eax, 16 ; shift low word -> hi word
|
||||||
|
mov ax, bx ; EAX contient maintenant 4 fois le pattern de 8 pixels
|
||||||
|
|
||||||
|
mov bp, 20 ; 80 octets / 4 (32-bit) = 20 itérations par ligne
|
||||||
|
.row_loop:
|
||||||
|
mov bl, [es:di] ; LATCH LOAD : Lecture indispensable en Mode 3
|
||||||
|
stosd
|
||||||
|
;mov [es:edi], eax ; Écrit 32 pixels d'un coup avec le pattern
|
||||||
|
;add edi, 4
|
||||||
|
dec bp
|
||||||
|
jne .row_loop
|
||||||
|
|
||||||
|
; Passer à la ligne suivante du pattern (modulo 8)
|
||||||
|
inc edx
|
||||||
|
and edx, 7 ; Si EDX=8, revient à 0
|
||||||
|
loop .line_loop
|
||||||
|
|
||||||
|
; Cleanup
|
||||||
|
mov dx, EGAVGA_CONTROLLER
|
||||||
|
mov ax, 0005h ; Reset Write Mode 0
|
||||||
|
out dx, ax
|
||||||
|
; popad
|
||||||
|
ret
|
||||||
|
|
||||||
|
; Entrée: AX = X (0-639), BX = Y (0-479), CL = Couleur (0-15)
|
||||||
|
%define .x word [bp+4]
|
||||||
|
%define .y word [bp+6]
|
||||||
|
%define .color byte [bp+8]
|
||||||
|
vga_putpixel:
|
||||||
|
push bp
|
||||||
|
mov bp, sp
|
||||||
|
pusha
|
||||||
|
|
||||||
|
mov bx, .y
|
||||||
|
mov ax, .x
|
||||||
|
mov cl, .color
|
||||||
|
; Calcul de l'offset (Y * 80 + X/8)
|
||||||
|
|
||||||
|
imul di, bx, 80 ; DI = Y * 80
|
||||||
|
mov bx, ax ; Sauvegarde X
|
||||||
|
shr ax, 3 ; AX = X / 8
|
||||||
|
add di, ax ; DI = Offset final
|
||||||
|
|
||||||
|
; Calcul du masque de bit (7 - (X % 8))
|
||||||
|
and bx, 7 ; BX = X % 8
|
||||||
|
mov ah, 80h ; Bit 7 à 1
|
||||||
|
shr ah, cl ; Décale pour pointer le bon pixel (cl = bx ici)
|
||||||
|
; Note: en pratique on utilise souvent une table de pré-calcul pour shr ah, bl
|
||||||
|
|
||||||
|
; Programmation du Graphics Controller
|
||||||
|
mov dx, EGAVGA_CONTROLLER
|
||||||
|
|
||||||
|
; Sélection du Bit Mask (Index 8)
|
||||||
|
mov al, 08h
|
||||||
|
out dx, ax ; AH contient le masque calculé
|
||||||
|
|
||||||
|
; Sélection du Set/Reset (Couleur, Index 0)
|
||||||
|
mov ax, 0000h
|
||||||
|
mov al, 00h
|
||||||
|
mov ah, cl ; Couleur
|
||||||
|
out dx, ax
|
||||||
|
|
||||||
|
; Enable Set/Reset (On active les 4 plans, Index 1)
|
||||||
|
mov ax, 0F01h
|
||||||
|
out dx, ax
|
||||||
|
|
||||||
|
; 4. Écriture (Nécessite une lecture préalable pour charger les Latches)
|
||||||
|
mov ax, VIDEO_SEG
|
||||||
|
mov es, ax
|
||||||
|
mov al, [es:di] ; Lecture bidon pour charger les verrous (latches)
|
||||||
|
mov [es:di], al ; L'écriture applique la couleur via le matériel
|
||||||
|
|
||||||
|
; Reset des registres pour ne pas casser le reste du dessin
|
||||||
|
mov ax, 0FF08h
|
||||||
|
out dx, ax
|
||||||
|
mov ax, 0001h
|
||||||
|
out dx, ax
|
||||||
|
|
||||||
|
popa
|
||||||
|
leave
|
||||||
|
ret
|
||||||
|
; clean defs
|
||||||
|
%undef .x
|
||||||
|
%undef .y
|
||||||
|
%undef .color
|
||||||
|
|
||||||
|
|
||||||
|
; ------------------------------------------------------------
|
||||||
|
; GESTION DU CURSEUR
|
||||||
|
; ------------------------------------------------------------
|
||||||
|
;
|
||||||
|
; ------------------------------------------------------------
|
||||||
|
; gère la demande d'effacement du curseur souris
|
||||||
|
;
|
||||||
|
; ------------------------------------------------------------
|
||||||
|
vga_mouse_hide:
|
||||||
|
pushf ; Sauver l'état des flags (interrupts)
|
||||||
|
cli ; Désactiver les interruptions (CRITIQUE)
|
||||||
|
pusha ; Sauvegarder TOUS les registres 32-bits
|
||||||
|
push ds
|
||||||
|
|
||||||
|
mov ax, BDA_CUSTOM_SEG
|
||||||
|
mov ds, ax
|
||||||
|
|
||||||
|
; Décrémenter le compteur
|
||||||
|
dec byte [BDA_MOUSE + mouse.cur_counter]
|
||||||
|
|
||||||
|
; Vérifier si on vient juste de passer en mode caché (c-à-d on est à -1)
|
||||||
|
cmp byte [BDA_MOUSE + mouse.cur_counter], -1
|
||||||
|
jne .skip_restore ; Si on est à -2, -3... elle est déjà cachée
|
||||||
|
|
||||||
|
call vga_cursor_restorebg
|
||||||
|
|
||||||
|
.skip_restore:
|
||||||
|
pop ds
|
||||||
|
popa
|
||||||
|
popf ; Restaure les interruptions (STI si elles étaient là)
|
||||||
|
ret
|
||||||
|
|
||||||
|
; ------------------------------------------------------------
|
||||||
|
; gère la demande d'affichage du curseur souris
|
||||||
|
;
|
||||||
|
; ------------------------------------------------------------
|
||||||
|
vga_mouse_show:
|
||||||
|
pushf
|
||||||
|
cli
|
||||||
|
pusha
|
||||||
|
push ds
|
||||||
|
|
||||||
|
mov ax, BDA_CUSTOM_SEG
|
||||||
|
mov ds, ax
|
||||||
|
|
||||||
|
; Incrémenter le compteur
|
||||||
|
inc byte [BDA_MOUSE + mouse.cur_counter]
|
||||||
|
|
||||||
|
; Vérifier si on est revenu à 0 (Visible)
|
||||||
|
cmp byte [BDA_MOUSE + mouse.cur_counter], 0
|
||||||
|
jne .skip_draw ; Si on est encore à -1, -2... on reste caché
|
||||||
|
|
||||||
|
; C'est la transition Caché -> Visible : On affiche le curseur
|
||||||
|
; IMPORTANT : On sauve le fond ACTUEL (qui a peut-être changé pendant le hide)
|
||||||
|
call vga_cursor_savebg
|
||||||
|
call vga_cursor_draw
|
||||||
|
|
||||||
|
.skip_draw:
|
||||||
|
pop ds
|
||||||
|
popa
|
||||||
|
popf ; restore également le flag d'interruption
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
; ------------------------------------------------------------
|
||||||
|
; gère le déplacement du curseur souris
|
||||||
|
;
|
||||||
|
; ------------------------------------------------------------
|
||||||
|
vga_mouse_cursor_move:
|
||||||
|
pusha
|
||||||
|
push ds
|
||||||
|
push es
|
||||||
|
|
||||||
|
; BDA Data Segment
|
||||||
|
mov ax, BDA_CUSTOM_SEG
|
||||||
|
mov ds, ax
|
||||||
|
|
||||||
|
cmp byte [BDA_MOUSE + mouse.cur_counter], 0
|
||||||
|
jl .done ; Si < 0, on ne dessine rien !
|
||||||
|
|
||||||
|
cmp byte [BDA_MOUSE + mouse.cur_drawing],0
|
||||||
|
jne .done
|
||||||
|
|
||||||
|
mov byte [BDA_MOUSE + mouse.cur_drawing],1
|
||||||
|
|
||||||
|
call vga_cursor_restorebg
|
||||||
|
call vga_cursor_savebg
|
||||||
|
call vga_cursor_draw
|
||||||
|
mov byte [BDA_MOUSE + mouse.cur_drawing],0
|
||||||
|
.done:
|
||||||
|
pop es
|
||||||
|
pop ds
|
||||||
|
popa
|
||||||
|
ret
|
||||||
|
|
||||||
|
; Buffer requis : 192 octets (16 lignes * 3 octets * 4 plans)
|
||||||
|
; ATTENTION : Vérifiez que mouse.bkg_buffer dans bda.asm est assez grand !
|
||||||
|
vga_cursor_savebg:
|
||||||
|
cmp byte [BDA_MOUSE + mouse.bkg_saved], 0
|
||||||
|
jne .done
|
||||||
|
|
||||||
|
push es
|
||||||
|
mov ax, VIDEO_SEG
|
||||||
|
mov es, ax
|
||||||
|
|
||||||
|
; Calculer l'adresse de départ (y * 80 + x / 8)
|
||||||
|
mov cx, [BDA_MOUSE + mouse.x]
|
||||||
|
mov dx, [BDA_MOUSE + mouse.y]
|
||||||
|
call vga_calc_addr ; Doit retourner DI = offset VRAM
|
||||||
|
mov [BDA_MOUSE + mouse.cur_addr_start], di
|
||||||
|
|
||||||
|
lea si, [BDA_MOUSE + mouse.bkg_buffer]
|
||||||
|
|
||||||
|
mov dx, EGAVGA_CONTROLLER ; Graphics Controller Port
|
||||||
|
mov al, 0x04 ; Read Plane Select Register
|
||||||
|
out dx, al
|
||||||
|
inc dx ; Point sur Data Port (0x03CF)
|
||||||
|
|
||||||
|
xor bl, bl ; BL = Index du plan (0 à 3)
|
||||||
|
.plan_loop:
|
||||||
|
mov al, bl
|
||||||
|
out dx, al ; Sélectionner le plan à lire
|
||||||
|
|
||||||
|
push di ; Sauver l'adresse de départ du curseur
|
||||||
|
mov cx, 16 ; 16 lignes
|
||||||
|
.row_loop:
|
||||||
|
mov ax, [es:di] ; Lit 16 pixels (2 octets)
|
||||||
|
mov [ds:si], ax
|
||||||
|
mov al, [es:di+2] ; Lit le 3eme octet (pour le shift)
|
||||||
|
mov [ds:si+2], al
|
||||||
|
add si, 3
|
||||||
|
add di, 80 ; Ligne suivante (VGA linéaire)
|
||||||
|
loop .row_loop
|
||||||
|
|
||||||
|
pop di ; Revenir en haut pour le plan suivant
|
||||||
|
inc bl
|
||||||
|
cmp bl, 4
|
||||||
|
jne .plan_loop
|
||||||
|
|
||||||
|
; Reset Read Map Select to 0 (Nettoyage)
|
||||||
|
mov dx, 0x3CE
|
||||||
|
mov ax, 0x0004
|
||||||
|
out dx, ax
|
||||||
|
|
||||||
|
pop es
|
||||||
|
mov byte [BDA_MOUSE + mouse.bkg_saved], 1
|
||||||
|
.done:
|
||||||
|
ret
|
||||||
|
|
||||||
|
vga_cursor_restorebg:
|
||||||
|
cmp byte [BDA_MOUSE + mouse.bkg_saved], 0
|
||||||
|
je .done
|
||||||
|
|
||||||
|
push es
|
||||||
|
mov ax, VIDEO_SEG
|
||||||
|
mov es, ax
|
||||||
|
|
||||||
|
mov di, [BDA_MOUSE + mouse.cur_addr_start]
|
||||||
|
lea si, [BDA_MOUSE + mouse.bkg_buffer]
|
||||||
|
|
||||||
|
; Sécurité : S'assurer que ES pointe bien vers la vidéo pour le restore
|
||||||
|
mov ax, VIDEO_SEG
|
||||||
|
mov es, ax
|
||||||
|
|
||||||
|
; Sécurité : Réinitialiser le contrôleur graphique pour l'écriture CPU brute
|
||||||
|
mov dx, EGAVGA_CONTROLLER
|
||||||
|
mov ax, 0x0005 ; Mode 0
|
||||||
|
out dx, ax
|
||||||
|
mov ax, 0x0001 ; Enable Set/Reset = 0 (Important !)
|
||||||
|
out dx, ax
|
||||||
|
mov ax, 0xFF08 ; Bit Mask = 0xFF
|
||||||
|
out dx, ax
|
||||||
|
mov ax, 0x0003 ; Function = Replace
|
||||||
|
out dx, ax
|
||||||
|
|
||||||
|
mov dx, VGA_SEQUENCER ; Sequencer Port
|
||||||
|
mov al, 0x02 ; Map Mask Register
|
||||||
|
out dx, al
|
||||||
|
inc dx ; Data Port (0x03C5)
|
||||||
|
|
||||||
|
mov bl, 1 ; Mask initial : Plan 0 (0001b)
|
||||||
|
.plan_loop:
|
||||||
|
mov al, bl
|
||||||
|
out dx, al ; Activer l'écriture uniquement sur ce plan
|
||||||
|
|
||||||
|
push di
|
||||||
|
mov cx, 16
|
||||||
|
.row_loop:
|
||||||
|
lodsw ; Lit 2 octets
|
||||||
|
mov [es:di], ax
|
||||||
|
lodsb ; Lit le 3eme octet
|
||||||
|
mov [es:di+2], al
|
||||||
|
add di, 80
|
||||||
|
loop .row_loop
|
||||||
|
|
||||||
|
pop di
|
||||||
|
shl bl, 1 ; Plan suivant (1 -> 2 -> 4 -> 8)
|
||||||
|
cmp bl, 16 ; Fini après le plan 3 (8)
|
||||||
|
jne .plan_loop
|
||||||
|
|
||||||
|
; Rétablir le Map Mask sur tous les plans (0x0F)
|
||||||
|
mov dx, VGA_SEQUENCER
|
||||||
|
mov ax, 0x0F02
|
||||||
|
out dx, ax
|
||||||
|
|
||||||
|
pop es
|
||||||
|
mov byte [BDA_MOUSE + mouse.bkg_saved], 0
|
||||||
|
.done:
|
||||||
|
ret
|
||||||
|
|
||||||
|
; ============================================================
|
||||||
|
; vga_cursor_draw
|
||||||
|
; Détruit: registres sauvegardés/restaurés (PUSHA/POPA)
|
||||||
|
; ============================================================
|
||||||
|
vga_cursor_draw:
|
||||||
|
push bp
|
||||||
|
mov bp, sp
|
||||||
|
sub sp, 4 ; [bp-2]: height, [bp-4]: x_bit_offset
|
||||||
|
; local variables
|
||||||
|
%define .height word [bp-2]
|
||||||
|
%define .bit_ofs word [bp-4]
|
||||||
|
|
||||||
|
pushad
|
||||||
|
push ds
|
||||||
|
push es
|
||||||
|
push gs
|
||||||
|
; Note: pushad sauvegarde déjà tous les registres généraux (EAX...EDI)
|
||||||
|
|
||||||
|
cld ; Sécurité : Direction avant
|
||||||
|
mov ax, BDA_CUSTOM_SEG
|
||||||
|
mov ds, ax
|
||||||
|
mov ax, VIDEO_SEG
|
||||||
|
mov es, ax
|
||||||
|
|
||||||
|
; --- CLIPPING VERTICAL ---
|
||||||
|
mov dx, [BDA_MOUSE + mouse.y]
|
||||||
|
mov bx, GFX_HEIGHT
|
||||||
|
cmp dx, bx
|
||||||
|
jae .exit_total
|
||||||
|
|
||||||
|
mov ax, 16
|
||||||
|
sub bx, dx
|
||||||
|
cmp ax, bx
|
||||||
|
jbe .y_ok
|
||||||
|
|
||||||
|
mov ax, bx
|
||||||
|
.y_ok:
|
||||||
|
mov .height, ax
|
||||||
|
|
||||||
|
; --- Calcul Adresse et Shift ---
|
||||||
|
mov ax, [BDA_MOUSE + mouse.x]
|
||||||
|
mov cx, ax
|
||||||
|
and ax, 7 ; Reste (0-7) = décalage de bit
|
||||||
|
mov .bit_ofs, ax
|
||||||
|
call vga_calc_addr ; DI = VRAM Offset
|
||||||
|
|
||||||
|
; --- CONFIG VGA (Write Mode 0, Logic Ops) ---
|
||||||
|
mov dx, VGA_SEQUENCER
|
||||||
|
mov ax, 0x0F02 ; Map Mask = All planes
|
||||||
|
out dx, ax
|
||||||
|
|
||||||
|
mov dx, 0x3CE ; Graphics Controller
|
||||||
|
mov ax, 0x0005 ; Mode 0
|
||||||
|
out dx, ax
|
||||||
|
mov ax, 0x0001 ; Enable Set/Reset = 0 (CPU Data)
|
||||||
|
out dx, ax
|
||||||
|
mov ax, 0xFF08 ; Bit Mask = 0xFF
|
||||||
|
out dx, ax
|
||||||
|
|
||||||
|
; Source du Sprite -> (GS:SI)
|
||||||
|
mov ax, [BDA_MOUSE + mouse.cur_seg]
|
||||||
|
mov gs, ax
|
||||||
|
mov si, [BDA_MOUSE + mouse.cur_ofs]
|
||||||
|
|
||||||
|
.row_loop:
|
||||||
|
; --- PREPARE MASKS ---
|
||||||
|
; On récupère le masque de l'image (AND) et du curseur (XOR)
|
||||||
|
mov ax, [gs:si] ; AX = AND Mask (16 bits)
|
||||||
|
xchg al, ah ; Souvent nécessaire selon l'endianness du sprite
|
||||||
|
xor ebx, ebx
|
||||||
|
mov bx, ax
|
||||||
|
not ebx ; On veut des 1 partout sauf là où le curseur est présent
|
||||||
|
|
||||||
|
; Décalage pour l'alignement au pixel près
|
||||||
|
mov cx, .bit_ofs
|
||||||
|
ror ebx, cl ; Rotation pour ne pas perdre de bits
|
||||||
|
|
||||||
|
; --- CONFIG VGA POUR AND ---
|
||||||
|
mov dx, 0x3CE
|
||||||
|
mov ax, 0x0803 ; Data Rotate/Function Select: AND (bits 3-4 = 01b)
|
||||||
|
out dx, ax
|
||||||
|
|
||||||
|
; Application sur 3 octets (pour couvrir les 16 pixels + le shift)
|
||||||
|
%rep 3
|
||||||
|
mov al, [es:di] ; CHARGE LES LATCHES (Indispensable)
|
||||||
|
mov eax, ebx
|
||||||
|
shr eax, 16 ; Récupère la partie haute (si 32-bit shift utilisé)
|
||||||
|
stosb ; Écrit AL et DI++ (Applique le AND sur les 4 plans)
|
||||||
|
%endrep
|
||||||
|
sub di, 3 ; Revient au début de la ligne pour le XOR
|
||||||
|
|
||||||
|
; --- CONFIG VGA POUR XOR ---
|
||||||
|
mov ax, 0x1803 ; Data Rotate/Function Select: XOR (bits 3-4 = 11b)
|
||||||
|
out dx, ax
|
||||||
|
|
||||||
|
; Récupération du masque XOR (la forme blanche/noire du curseur)
|
||||||
|
mov ax, [gs:si+32]
|
||||||
|
; ... (Appliquer le même décalage et stosb que pour le AND) ...
|
||||||
|
|
||||||
|
; --- NEXT ROW ---
|
||||||
|
add di, 80 - 3 ; Ligne suivante (80 octets par ligne)
|
||||||
|
add si, 2
|
||||||
|
dec word .height
|
||||||
|
jnz .row_loop
|
||||||
|
|
||||||
|
; --- RESTORE VGA ---
|
||||||
|
mov dx, 0x3CE
|
||||||
|
mov ax, 0x0003 ; Function = Replace
|
||||||
|
out dx, ax
|
||||||
|
mov ax, 0xFF08 ; Bit Mask = 0xFF
|
||||||
|
out dx, ax
|
||||||
|
mov ax, 0x0001 ; Enable Set/Reset = 0
|
||||||
|
out dx, ax
|
||||||
|
|
||||||
|
.exit_total:
|
||||||
|
pop gs
|
||||||
|
pop es
|
||||||
|
pop ds
|
||||||
|
popad
|
||||||
|
leave
|
||||||
|
ret
|
||||||
|
%undef .height
|
||||||
|
%undef .mask
|
||||||
|
|
@ -43,7 +43,7 @@
|
||||||
;
|
;
|
||||||
; ------------------------------------------------------------
|
; ------------------------------------------------------------
|
||||||
mouse_reset:
|
mouse_reset:
|
||||||
mov ax, BDA_DATA_SEG
|
mov ax, BDA_CUSTOM_SEG
|
||||||
mov fs,ax
|
mov fs,ax
|
||||||
|
|
||||||
; effacer les variables du drivers
|
; effacer les variables du drivers
|
||||||
|
|
@ -52,8 +52,8 @@ mouse_reset:
|
||||||
mov byte [fs:BDA_MOUSE + mouse.packetlen],3 ; 3 bytes par défaut
|
mov byte [fs:BDA_MOUSE + mouse.packetlen],3 ; 3 bytes par défaut
|
||||||
mov byte [fs:BDA_MOUSE + mouse.status],0
|
mov byte [fs:BDA_MOUSE + mouse.status],0
|
||||||
|
|
||||||
mov word [fs:BDA_MOUSE + mouse.x],320 ; vous pouvez aussi préciser le centre
|
mov word [fs:BDA_MOUSE + mouse.x],GFX_WIDTH / 2
|
||||||
mov word [fs:BDA_MOUSE + mouse.y],100 ; vous pouvez aussi préciser le centre
|
mov word [fs:BDA_MOUSE + mouse.y],GFX_HEIGHT / 2
|
||||||
|
|
||||||
mov word [fs:BDA_MOUSE + mouse.cur_x], 0
|
mov word [fs:BDA_MOUSE + mouse.cur_x], 0
|
||||||
mov word [fs:BDA_MOUSE + mouse.cur_y], 0
|
mov word [fs:BDA_MOUSE + mouse.cur_y], 0
|
||||||
|
|
@ -154,7 +154,7 @@ mouse_init:
|
||||||
;
|
;
|
||||||
; ------------------------------------------------------------
|
; ------------------------------------------------------------
|
||||||
mouse_detect_packet_len:
|
mouse_detect_packet_len:
|
||||||
mov ax, BDA_DATA_SEG
|
mov ax, BDA_CUSTOM_SEG
|
||||||
mov fs,ax
|
mov fs,ax
|
||||||
|
|
||||||
mov byte [fs:BDA_MOUSE + mouse.packetlen], 3
|
mov byte [fs:BDA_MOUSE + mouse.packetlen], 3
|
||||||
|
|
@ -284,7 +284,7 @@ isr_mouse_handler:
|
||||||
push ds
|
push ds
|
||||||
|
|
||||||
; use BDA segment
|
; use BDA segment
|
||||||
mov ax,BDA_DATA_SEG
|
mov ax,BDA_CUSTOM_SEG
|
||||||
mov ds,ax
|
mov ds,ax
|
||||||
|
|
||||||
; lire un octet depuis le contrôleur et le stocker dans le buffer
|
; lire un octet depuis le contrôleur et le stocker dans le buffer
|
||||||
|
|
|
||||||
528
src/gui/lib-api.asm
Normal file
528
src/gui/lib-api.asm
Normal file
|
|
@ -0,0 +1,528 @@
|
||||||
|
; =============================================================================
|
||||||
|
; Project : Custom BIOS / ROM
|
||||||
|
; File : gui/lib.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 <https://www.gnu.org/licenses/>.
|
||||||
|
;
|
||||||
|
; =============================================================================
|
||||||
|
|
||||||
|
; --- Configuration ---
|
||||||
|
%define GUI_MAX_WIDGETS 32 ; Nombre max de widgets simultanés
|
||||||
|
|
||||||
|
; Dimensions
|
||||||
|
%define GUI_CHECKBOX_SIZE 10 ;
|
||||||
|
|
||||||
|
; --- Drapeaux & États ---
|
||||||
|
%define GUI_STATE_FREE 0 ; Le slot est vide (mémoire dispo)
|
||||||
|
%define GUI_STATE_NORMAL 1 ; Affiché, repos
|
||||||
|
%define GUI_STATE_HOVER 2 ; Souris dessus
|
||||||
|
%define GUI_STATE_PRESSED 3 ; Clic enfoncé
|
||||||
|
%define GUI_STATE_DISABLED 4 ; Grisé
|
||||||
|
|
||||||
|
; --- Types de Widgets ---
|
||||||
|
%define OBJ_TYPE_LABEL 0
|
||||||
|
%define OBJ_TYPE_BUTTON 1
|
||||||
|
%define OBJ_TYPE_SLIDER 2
|
||||||
|
%define OBJ_TYPE_BUTTON_ROUNDED 3
|
||||||
|
%define OBJ_TYPE_CHECKBOX 4
|
||||||
|
|
||||||
|
; --- Widgets attributs ---
|
||||||
|
%define BUTTON_DEFAULT 0
|
||||||
|
%define BUTTON_OK 1
|
||||||
|
|
||||||
|
%define SLIDER_HORIZONTAL 1
|
||||||
|
%define SLIDER_VERTICAL 2
|
||||||
|
|
||||||
|
; =============================================================================
|
||||||
|
; SECTION : API ACTIONS
|
||||||
|
; =============================================================================
|
||||||
|
|
||||||
|
%define OBJ_CREATE 0
|
||||||
|
%define OBJ_DESTROY 1
|
||||||
|
%define OBJ_GET_STATE 2
|
||||||
|
%define OBJ_GET_TYPE 3
|
||||||
|
%define OBJ_GET_VAL 4
|
||||||
|
%define OBJ_SET_VAL 5
|
||||||
|
|
||||||
|
%define OBJ_SET_MODE 6
|
||||||
|
%define OBJ_SET_TEXT 7
|
||||||
|
|
||||||
|
%define OBJ_GET_PTR 8
|
||||||
|
|
||||||
|
%define OBJ_SLIDER_SET_ATTR 9
|
||||||
|
|
||||||
|
|
||||||
|
gui_api_table:
|
||||||
|
dw gui_api_create
|
||||||
|
dw gui_api_destroy
|
||||||
|
dw gui_api_get_state
|
||||||
|
dw gui_api_get_type
|
||||||
|
dw gui_api_get_val
|
||||||
|
dw gui_api_set_val
|
||||||
|
dw gui_api_set_mode
|
||||||
|
dw gui_api_set_text
|
||||||
|
dw gui_get_widget_ptr
|
||||||
|
dw gui_api_slider_attr
|
||||||
|
|
||||||
|
|
||||||
|
; --- Structure d'un OBJET (Bouton, etc) ---
|
||||||
|
struc widget
|
||||||
|
.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
|
||||||
|
.x resw 1 ; Position X
|
||||||
|
.y resw 1 ; Position Y
|
||||||
|
.x2 resw 1 ; Position X2 calculée
|
||||||
|
.y2 resw 1 ; Position Y2 calculée
|
||||||
|
.w resw 1 ; Largeur
|
||||||
|
.h resw 1 ; Hauteur
|
||||||
|
.text_ofs resw 1 ; Offset du texte
|
||||||
|
.text_seg resw 1 ; Segment du texte
|
||||||
|
.event_click resw 1 ; adresse de la fonction "on click"
|
||||||
|
.event_drag resw 1 ; adresse de la fonction "on drag"
|
||||||
|
|
||||||
|
.attr_mode resb 1 ; 0=None, 1=Horiz, 2=Vert
|
||||||
|
.attr_min resw 1 ; Valeur/Position Min
|
||||||
|
.attr_max resw 1 ; Valeur/Position Max
|
||||||
|
.attr_val resw 1 ; Valeur/Position Actuelle
|
||||||
|
|
||||||
|
.thumb_pos resw 1 ; Valeur/Position Actuelle en pixel pour le dessin.
|
||||||
|
.thumb_pct resb 1 ; Taille du curseur en % (1-100)
|
||||||
|
|
||||||
|
.attr_anchor resw 1 ; interne Offset pour le drag
|
||||||
|
alignb 2 ; Alignement mémoire pour performance
|
||||||
|
endstruc
|
||||||
|
; actuellement 34 octets
|
||||||
|
|
||||||
|
%macro GUI 1-*
|
||||||
|
%rep %0 - 1
|
||||||
|
%rotate -1
|
||||||
|
push %1
|
||||||
|
%endrep
|
||||||
|
%rotate -1
|
||||||
|
call word [cs:gui_api_table + ((%1)*2)]
|
||||||
|
add sp, (%0 - 1) * 2
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
; -----------------------------------------------------------------------------
|
||||||
|
; 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 ax
|
||||||
|
|
||||||
|
push .id ; ID
|
||||||
|
call gui_get_widget_ptr
|
||||||
|
jc .err
|
||||||
|
|
||||||
|
mov ax, .min
|
||||||
|
mov word [gs:si + widget.attr_min], ax
|
||||||
|
mov ax, .max
|
||||||
|
mov word [gs:si + widget.attr_max], ax
|
||||||
|
mov ax, .val
|
||||||
|
mov word [gs:si + widget.attr_val], ax
|
||||||
|
mov ax, .pct
|
||||||
|
mov byte [gs:si + widget.thumb_pct], al
|
||||||
|
|
||||||
|
call gui_slider_update_pixels
|
||||||
|
|
||||||
|
.err:
|
||||||
|
pop ax
|
||||||
|
leave
|
||||||
|
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 ax
|
||||||
|
|
||||||
|
push .id
|
||||||
|
call gui_get_widget_ptr
|
||||||
|
jc .err
|
||||||
|
|
||||||
|
mov ax, .mode
|
||||||
|
mov byte [gs:si + widget.attr_mode], al
|
||||||
|
|
||||||
|
.err:
|
||||||
|
pop ax
|
||||||
|
leave
|
||||||
|
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 ax
|
||||||
|
|
||||||
|
push .id
|
||||||
|
call gui_get_widget_ptr
|
||||||
|
jc .err
|
||||||
|
|
||||||
|
mov ax, .segmt
|
||||||
|
mov word [gs:si + widget.text_seg], ax
|
||||||
|
mov ax, .oft ; Offset du texte
|
||||||
|
mov word [gs:si + widget.text_ofs], ax
|
||||||
|
|
||||||
|
.err:
|
||||||
|
pop ax
|
||||||
|
leave
|
||||||
|
ret
|
||||||
|
%undef .id
|
||||||
|
%undef .text_ofs
|
||||||
|
%undef .text_seg
|
||||||
|
|
||||||
|
; -----------------------------------------------------------------------------
|
||||||
|
; gui_api_create
|
||||||
|
; Crée un widget et retourne son ID
|
||||||
|
; Out: AX = ID ou -1 si erreur
|
||||||
|
;
|
||||||
|
; parameters : type, x, y, w, h, text_ofs, text_seg
|
||||||
|
;
|
||||||
|
; -----------------------------------------------------------------------------
|
||||||
|
%define .type word [bp+4]
|
||||||
|
%define .x word [bp+6]
|
||||||
|
%define .y word [bp+8]
|
||||||
|
%define .w word [bp+10]
|
||||||
|
%define .h word [bp+12]
|
||||||
|
gui_api_create:
|
||||||
|
push bp
|
||||||
|
mov bp, sp
|
||||||
|
push gs
|
||||||
|
|
||||||
|
mov ax, BDA_GUI_WIDGET
|
||||||
|
mov gs, ax
|
||||||
|
call gui_alloc_widget ; Returns GS:SI
|
||||||
|
mov ax, -1
|
||||||
|
jc .done
|
||||||
|
|
||||||
|
; ID = SI / widget_size
|
||||||
|
mov ax, si
|
||||||
|
xor dx, dx
|
||||||
|
mov cx, widget_size
|
||||||
|
div cx
|
||||||
|
|
||||||
|
mov bx, .type
|
||||||
|
mov byte [gs:si + widget.type], bl
|
||||||
|
mov bx, .x
|
||||||
|
mov word [gs:si + widget.x], bx
|
||||||
|
mov bx, .y
|
||||||
|
mov word [gs:si + widget.y], bx
|
||||||
|
mov bx, .w
|
||||||
|
mov word [gs:si + widget.w], bx
|
||||||
|
mov bx, .h
|
||||||
|
mov word [gs:si + widget.h], bx
|
||||||
|
|
||||||
|
mov byte [gs:si + widget.state], GUI_STATE_NORMAL
|
||||||
|
mov byte [gs:si + widget.oldstate], 0
|
||||||
|
.done:
|
||||||
|
pop gs
|
||||||
|
leave
|
||||||
|
ret
|
||||||
|
%undef .type
|
||||||
|
%undef .x
|
||||||
|
%undef .y
|
||||||
|
%undef .w
|
||||||
|
%undef .h
|
||||||
|
|
||||||
|
; -----------------------------------------------------------------------------
|
||||||
|
; gui_api_get_state
|
||||||
|
; Arg1: ID
|
||||||
|
; Out: AX = State
|
||||||
|
; -----------------------------------------------------------------------------
|
||||||
|
%define .id word [bp+4]
|
||||||
|
gui_api_get_state:
|
||||||
|
push bp
|
||||||
|
mov bp, sp
|
||||||
|
|
||||||
|
mov ax, .id ; ID
|
||||||
|
call gui_get_widget_ptr
|
||||||
|
jc .err
|
||||||
|
|
||||||
|
xor ax, ax
|
||||||
|
mov al, [gs:si + widget.state]
|
||||||
|
jmp .done
|
||||||
|
|
||||||
|
.err:
|
||||||
|
mov ax, -1
|
||||||
|
.done:
|
||||||
|
leave
|
||||||
|
ret
|
||||||
|
%undef .id
|
||||||
|
|
||||||
|
; -----------------------------------------------------------------------------
|
||||||
|
; gui_api_get_type
|
||||||
|
; Arg1: ID
|
||||||
|
; Out: AX = Type
|
||||||
|
; -----------------------------------------------------------------------------
|
||||||
|
%define .id word [bp+4]
|
||||||
|
gui_api_get_type:
|
||||||
|
push bp
|
||||||
|
mov bp, sp
|
||||||
|
|
||||||
|
mov ax, .id ; ID
|
||||||
|
call gui_get_widget_ptr
|
||||||
|
jc .err
|
||||||
|
|
||||||
|
xor ax, ax
|
||||||
|
mov al, [gs:si + widget.type]
|
||||||
|
jmp .done
|
||||||
|
|
||||||
|
.err:
|
||||||
|
mov ax, -1
|
||||||
|
.done:
|
||||||
|
leave
|
||||||
|
ret
|
||||||
|
%undef .id
|
||||||
|
|
||||||
|
; -----------------------------------------------------------------------------
|
||||||
|
; gui_api_get_val
|
||||||
|
; Arg1: ID
|
||||||
|
; Out: AX = Attr Val
|
||||||
|
; -----------------------------------------------------------------------------
|
||||||
|
%define .id word [bp+4]
|
||||||
|
gui_api_get_val:
|
||||||
|
push bp
|
||||||
|
mov bp, sp
|
||||||
|
|
||||||
|
call gui_get_widget_ptr
|
||||||
|
;jc .err
|
||||||
|
|
||||||
|
call gui_slider_update_value
|
||||||
|
mov ax, [gs:si + widget.attr_val]
|
||||||
|
jmp .done
|
||||||
|
|
||||||
|
.err:
|
||||||
|
mov ax, -1
|
||||||
|
.done:
|
||||||
|
leave
|
||||||
|
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
|
||||||
|
|
||||||
|
mov ax, .id ; ID
|
||||||
|
call gui_get_widget_ptr
|
||||||
|
jc .err
|
||||||
|
|
||||||
|
mov ax, .val
|
||||||
|
mov [gs:si + widget.thumb_pos], ax
|
||||||
|
|
||||||
|
.err:
|
||||||
|
leave
|
||||||
|
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]
|
||||||
|
gui_api_destroy:
|
||||||
|
push bp
|
||||||
|
mov bp, sp
|
||||||
|
|
||||||
|
mov ax, .id ; ID
|
||||||
|
call gui_get_widget_ptr
|
||||||
|
jc .err
|
||||||
|
|
||||||
|
call gui_free_widget
|
||||||
|
xor ax, ax
|
||||||
|
jmp .done
|
||||||
|
|
||||||
|
.err:
|
||||||
|
mov ax, -1
|
||||||
|
.done:
|
||||||
|
leave
|
||||||
|
ret
|
||||||
|
%undef .id
|
||||||
|
|
||||||
|
; -----------------------------------------------------------------------------
|
||||||
|
; gui_get_widget_ptr
|
||||||
|
; Helper interne : Convertit ID en Pointeur
|
||||||
|
; In: ID
|
||||||
|
; Out: GS:SI = Ptr, CF=1 if error
|
||||||
|
; -----------------------------------------------------------------------------
|
||||||
|
%define .id word [bp+4]
|
||||||
|
gui_get_widget_ptr:
|
||||||
|
push bp
|
||||||
|
mov bp, sp
|
||||||
|
push ax
|
||||||
|
push cx
|
||||||
|
|
||||||
|
mov ax, .id
|
||||||
|
cmp ax, GUI_MAX_WIDGETS
|
||||||
|
jae .error
|
||||||
|
|
||||||
|
mov cx, widget_size
|
||||||
|
xor dx, dx
|
||||||
|
mul cx ; AX = Offset
|
||||||
|
mov si, ax
|
||||||
|
|
||||||
|
mov ax, BDA_GUI_WIDGET
|
||||||
|
mov gs, ax
|
||||||
|
|
||||||
|
clc
|
||||||
|
jmp .done
|
||||||
|
.error:
|
||||||
|
stc
|
||||||
|
.done:
|
||||||
|
pop cx
|
||||||
|
pop ax
|
||||||
|
leave
|
||||||
|
ret
|
||||||
|
%undef .id
|
||||||
|
|
||||||
|
|
||||||
|
; =============================================================================
|
||||||
|
; SECTION : GESTION MÉMOIRE (ALLOCATION / LIBÉRATION)
|
||||||
|
; =============================================================================
|
||||||
|
|
||||||
|
; -----------------------------------------------------------------------------
|
||||||
|
; gui_init_system
|
||||||
|
; Initialise toute la mémoire des widgets à 0 (Libre)
|
||||||
|
; Entrée : DS doit pointer vers BDA_GUI_WIDGET
|
||||||
|
; -----------------------------------------------------------------------------
|
||||||
|
gui_init_system:
|
||||||
|
push eax
|
||||||
|
push cx
|
||||||
|
push es
|
||||||
|
push di
|
||||||
|
|
||||||
|
mov ax, BDA_GUI_WIDGET
|
||||||
|
mov es, ax
|
||||||
|
|
||||||
|
cld
|
||||||
|
xor di, di
|
||||||
|
mov cx, (widget_size * GUI_MAX_WIDGETS) / 2
|
||||||
|
xor ax, ax
|
||||||
|
rep stosw ; Plus sûr en mode 16 bits pour l'alignement
|
||||||
|
|
||||||
|
pop di
|
||||||
|
pop es
|
||||||
|
pop cx
|
||||||
|
pop eax
|
||||||
|
ret
|
||||||
|
|
||||||
|
; -----------------------------------------------------------------------------
|
||||||
|
; gui_alloc_widget
|
||||||
|
; Cherche un slot vide et retourne son adresse
|
||||||
|
; Sortie :
|
||||||
|
; - Succès : CF=0 (Carry Clear), GS:SI = Offset du widget
|
||||||
|
; - Echec : CF=1 (Carry Set), GS:SI = Indéfini (ou 0)
|
||||||
|
; -----------------------------------------------------------------------------
|
||||||
|
gui_alloc_widget:
|
||||||
|
push ax
|
||||||
|
push cx
|
||||||
|
push bx
|
||||||
|
|
||||||
|
mov ax, BDA_GUI_WIDGET
|
||||||
|
mov gs, ax
|
||||||
|
|
||||||
|
mov si, 0 ; Début du pool
|
||||||
|
mov cx, GUI_MAX_WIDGETS
|
||||||
|
|
||||||
|
.loop_find:
|
||||||
|
cmp byte [gs:si + widget.state], GUI_STATE_FREE
|
||||||
|
je .found ; Si state == 0, c'est libre !
|
||||||
|
|
||||||
|
add si, widget_size ; Sinon on passe au suivant
|
||||||
|
loop .loop_find
|
||||||
|
|
||||||
|
; Pas trouvé (Plein)
|
||||||
|
stc ; set Carry Flag : erreur
|
||||||
|
jmp .done
|
||||||
|
|
||||||
|
.found:
|
||||||
|
; On initialise le slot trouvé
|
||||||
|
mov byte [gs:si + widget.state], GUI_STATE_NORMAL ; Marquer comme occupé
|
||||||
|
mov byte [gs:si + widget.type], OBJ_TYPE_BUTTON ; Type par défaut
|
||||||
|
mov byte [gs:si + widget.oldstate], 0 ; doit etre dessiné
|
||||||
|
|
||||||
|
; Reset des champs critiques pour éviter les déchets
|
||||||
|
mov word [gs:si + widget.event_click], 0
|
||||||
|
mov word [gs:si + widget.event_drag], 0
|
||||||
|
mov byte [gs:si + widget.thumb_pct], 10 ; 10% par défaut
|
||||||
|
|
||||||
|
clc ; Clear Carry Flag
|
||||||
|
.done:
|
||||||
|
pop bx
|
||||||
|
pop cx
|
||||||
|
pop ax
|
||||||
|
ret
|
||||||
|
|
||||||
|
; -----------------------------------------------------------------------------
|
||||||
|
; gui_free_widget
|
||||||
|
; Libère un widget
|
||||||
|
; Entrée : SI = Pointeur widget
|
||||||
|
; -----------------------------------------------------------------------------
|
||||||
|
gui_free_widget:
|
||||||
|
push eax
|
||||||
|
push es
|
||||||
|
|
||||||
|
mov ax, BDA_GUI_WIDGET
|
||||||
|
mov es, ax
|
||||||
|
|
||||||
|
cld
|
||||||
|
mov di, si
|
||||||
|
mov cx, (widget_size)
|
||||||
|
shr cx, 2 ; cx / 4
|
||||||
|
xor eax, eax
|
||||||
|
rep stosd ; Remplit tout de 0
|
||||||
|
|
||||||
|
; On efface le widget
|
||||||
|
mov byte [es:si + widget.state], GUI_STATE_FREE
|
||||||
|
; Pour l'instant on le marque juste libre, il n'est pas retirer de l'écran.
|
||||||
|
|
||||||
|
pop es
|
||||||
|
pop eax
|
||||||
|
ret
|
||||||
|
|
||||||
|
%include "./gui/lib-logic.asm"
|
||||||
|
%include "./gui/lib-draw.asm"
|
||||||
|
|
@ -31,7 +31,7 @@ gui_draw_single_widget:
|
||||||
|
|
||||||
GFX MOUSE_HIDE ; On cache la souris AVANT de commencer le dessin du widget
|
GFX MOUSE_HIDE ; On cache la souris AVANT de commencer le dessin du widget
|
||||||
|
|
||||||
mov ax, GUI_RAM_SEG
|
mov ax, BDA_GUI_WIDGET
|
||||||
mov gs, ax
|
mov gs, ax
|
||||||
|
|
||||||
mov al, [gs:si + widget.state]
|
mov al, [gs:si + widget.state]
|
||||||
|
|
@ -291,12 +291,12 @@ draw_button:
|
||||||
|
|
||||||
.draw_default_style:
|
.draw_default_style:
|
||||||
; Bordure extérieure épaisse (2px)
|
; Bordure extérieure épaisse (2px)
|
||||||
GFX RECTANGLE, ax, bx, cx, dx, 0
|
;GFX RECTANGLE, ax, bx, cx, dx, 0
|
||||||
inc ax
|
inc ax
|
||||||
inc bx
|
inc bx
|
||||||
dec cx
|
dec cx
|
||||||
dec dx
|
dec dx
|
||||||
GFX RECTANGLE, ax, bx, cx, dx, 0
|
;GFX RECTANGLE, ax, bx, cx, dx, 0
|
||||||
|
|
||||||
; Bordure intérieure fine (après un gap de 1px blanc)
|
; Bordure intérieure fine (après un gap de 1px blanc)
|
||||||
add ax, 2
|
add ax, 2
|
||||||
|
|
@ -1,530 +1,3 @@
|
||||||
; =============================================================================
|
|
||||||
; Project : Custom BIOS / ROM
|
|
||||||
; File : gui/lib.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 <https://www.gnu.org/licenses/>.
|
|
||||||
;
|
|
||||||
; =============================================================================
|
|
||||||
|
|
||||||
; --- Configuration ---
|
|
||||||
%define GUI_RAM_SEG 0x080 ; Segment de données UI (Safe: après Stack, avant Heap)
|
|
||||||
%define GUI_MAX_WIDGETS 32 ; Nombre max de widgets simultanés
|
|
||||||
|
|
||||||
; Dimensions
|
|
||||||
%define GUI_CHECKBOX_SIZE 10 ;
|
|
||||||
|
|
||||||
; --- Drapeaux & États ---
|
|
||||||
%define GUI_STATE_FREE 0 ; Le slot est vide (mémoire dispo)
|
|
||||||
%define GUI_STATE_NORMAL 1 ; Affiché, repos
|
|
||||||
%define GUI_STATE_HOVER 2 ; Souris dessus
|
|
||||||
%define GUI_STATE_PRESSED 3 ; Clic enfoncé
|
|
||||||
%define GUI_STATE_DISABLED 4 ; Grisé
|
|
||||||
|
|
||||||
; --- Types de Widgets ---
|
|
||||||
%define OBJ_TYPE_LABEL 0
|
|
||||||
%define OBJ_TYPE_BUTTON 1
|
|
||||||
%define OBJ_TYPE_SLIDER 2
|
|
||||||
%define OBJ_TYPE_BUTTON_ROUNDED 3
|
|
||||||
%define OBJ_TYPE_CHECKBOX 4
|
|
||||||
|
|
||||||
; --- Widgets attributs ---
|
|
||||||
%define BUTTON_DEFAULT 0
|
|
||||||
%define BUTTON_OK 1
|
|
||||||
|
|
||||||
%define SLIDER_HORIZONTAL 1
|
|
||||||
%define SLIDER_VERTICAL 2
|
|
||||||
|
|
||||||
; =============================================================================
|
|
||||||
; SECTION : API ACTIONS
|
|
||||||
; =============================================================================
|
|
||||||
|
|
||||||
%define OBJ_CREATE 0
|
|
||||||
%define OBJ_DESTROY 1
|
|
||||||
%define OBJ_GET_STATE 2
|
|
||||||
%define OBJ_GET_TYPE 3
|
|
||||||
%define OBJ_GET_VAL 4
|
|
||||||
%define OBJ_SET_VAL 5
|
|
||||||
|
|
||||||
%define OBJ_SET_MODE 6
|
|
||||||
%define OBJ_SET_TEXT 7
|
|
||||||
|
|
||||||
%define OBJ_GET_PTR 8
|
|
||||||
|
|
||||||
%define OBJ_SLIDER_SET_ATTR 9
|
|
||||||
|
|
||||||
|
|
||||||
gui_api_table:
|
|
||||||
dw gui_api_create
|
|
||||||
dw gui_api_destroy
|
|
||||||
dw gui_api_get_state
|
|
||||||
dw gui_api_get_type
|
|
||||||
dw gui_api_get_val
|
|
||||||
dw gui_api_set_val
|
|
||||||
dw gui_api_set_mode
|
|
||||||
dw gui_api_set_text
|
|
||||||
dw gui_get_widget_ptr
|
|
||||||
dw gui_api_slider_attr
|
|
||||||
|
|
||||||
|
|
||||||
; --- Structure d'un OBJET (Bouton, etc) ---
|
|
||||||
struc widget
|
|
||||||
.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
|
|
||||||
.x resw 1 ; Position X
|
|
||||||
.y resw 1 ; Position Y
|
|
||||||
.x2 resw 1 ; Position X2 calculée
|
|
||||||
.y2 resw 1 ; Position Y2 calculée
|
|
||||||
.w resw 1 ; Largeur
|
|
||||||
.h resw 1 ; Hauteur
|
|
||||||
.text_ofs resw 1 ; Offset du texte
|
|
||||||
.text_seg resw 1 ; Segment du texte
|
|
||||||
.event_click resw 1 ; adresse de la fonction "on click"
|
|
||||||
.event_drag resw 1 ; adresse de la fonction "on drag"
|
|
||||||
|
|
||||||
.attr_mode resb 1 ; 0=None, 1=Horiz, 2=Vert
|
|
||||||
.attr_min resw 1 ; Valeur/Position Min
|
|
||||||
.attr_max resw 1 ; Valeur/Position Max
|
|
||||||
.attr_val resw 1 ; Valeur/Position Actuelle
|
|
||||||
|
|
||||||
.thumb_pos resw 1 ; Valeur/Position Actuelle en pixel pour le dessin.
|
|
||||||
.thumb_pct resb 1 ; Taille du curseur en % (1-100)
|
|
||||||
|
|
||||||
.attr_anchor resw 1 ; interne Offset pour le drag
|
|
||||||
alignb 2 ; Alignement mémoire pour performance
|
|
||||||
endstruc
|
|
||||||
; actuellement 34 octets
|
|
||||||
|
|
||||||
%macro GUI 1-*
|
|
||||||
%rep %0 - 1
|
|
||||||
%rotate -1
|
|
||||||
push %1
|
|
||||||
%endrep
|
|
||||||
%rotate -1
|
|
||||||
call word [cs:gui_api_table + ((%1)*2)]
|
|
||||||
add sp, (%0 - 1) * 2
|
|
||||||
%endmacro
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
; 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 ax
|
|
||||||
|
|
||||||
push .id ; ID
|
|
||||||
call gui_get_widget_ptr
|
|
||||||
jc .err
|
|
||||||
|
|
||||||
mov ax, .min
|
|
||||||
mov word [gs:si + widget.attr_min], ax
|
|
||||||
mov ax, .max
|
|
||||||
mov word [gs:si + widget.attr_max], ax
|
|
||||||
mov ax, .val
|
|
||||||
mov word [gs:si + widget.attr_val], ax
|
|
||||||
mov ax, .pct
|
|
||||||
mov byte [gs:si + widget.thumb_pct], al
|
|
||||||
|
|
||||||
call gui_slider_update_pixels
|
|
||||||
|
|
||||||
.err:
|
|
||||||
pop ax
|
|
||||||
leave
|
|
||||||
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 ax
|
|
||||||
|
|
||||||
push .id
|
|
||||||
call gui_get_widget_ptr
|
|
||||||
jc .err
|
|
||||||
|
|
||||||
mov ax, .mode
|
|
||||||
mov byte [gs:si + widget.attr_mode], al
|
|
||||||
|
|
||||||
.err:
|
|
||||||
pop ax
|
|
||||||
leave
|
|
||||||
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 ax
|
|
||||||
|
|
||||||
push .id
|
|
||||||
call gui_get_widget_ptr
|
|
||||||
jc .err
|
|
||||||
|
|
||||||
mov ax, .segmt
|
|
||||||
mov word [gs:si + widget.text_seg], ax
|
|
||||||
mov ax, .oft ; Offset du texte
|
|
||||||
mov word [gs:si + widget.text_ofs], ax
|
|
||||||
|
|
||||||
.err:
|
|
||||||
pop ax
|
|
||||||
leave
|
|
||||||
ret
|
|
||||||
%undef .id
|
|
||||||
%undef .text_ofs
|
|
||||||
%undef .text_seg
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
; gui_api_create
|
|
||||||
; Crée un widget et retourne son ID
|
|
||||||
; Out: AX = ID ou -1 si erreur
|
|
||||||
;
|
|
||||||
; parameters : type, x, y, w, h, text_ofs, text_seg
|
|
||||||
;
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
%define .type word [bp+4]
|
|
||||||
%define .x word [bp+6]
|
|
||||||
%define .y word [bp+8]
|
|
||||||
%define .w word [bp+10]
|
|
||||||
%define .h word [bp+12]
|
|
||||||
gui_api_create:
|
|
||||||
push bp
|
|
||||||
mov bp, sp
|
|
||||||
push gs
|
|
||||||
|
|
||||||
mov ax, GUI_RAM_SEG
|
|
||||||
mov gs, ax
|
|
||||||
call gui_alloc_widget ; Returns GS:SI
|
|
||||||
mov ax, -1
|
|
||||||
jc .done
|
|
||||||
|
|
||||||
; ID = SI / widget_size
|
|
||||||
mov ax, si
|
|
||||||
xor dx, dx
|
|
||||||
mov cx, widget_size
|
|
||||||
div cx
|
|
||||||
|
|
||||||
mov bx, .type
|
|
||||||
mov byte [gs:si + widget.type], bl
|
|
||||||
mov bx, .x
|
|
||||||
mov word [gs:si + widget.x], bx
|
|
||||||
mov bx, .y
|
|
||||||
mov word [gs:si + widget.y], bx
|
|
||||||
mov bx, .w
|
|
||||||
mov word [gs:si + widget.w], bx
|
|
||||||
mov bx, .h
|
|
||||||
mov word [gs:si + widget.h], bx
|
|
||||||
|
|
||||||
mov byte [gs:si + widget.state], GUI_STATE_NORMAL
|
|
||||||
mov byte [gs:si + widget.oldstate], 0
|
|
||||||
.done:
|
|
||||||
pop gs
|
|
||||||
leave
|
|
||||||
ret
|
|
||||||
%undef .type
|
|
||||||
%undef .x
|
|
||||||
%undef .y
|
|
||||||
%undef .w
|
|
||||||
%undef .h
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
; gui_api_get_state
|
|
||||||
; Arg1: ID
|
|
||||||
; Out: AX = State
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
%define .id word [bp+4]
|
|
||||||
gui_api_get_state:
|
|
||||||
push bp
|
|
||||||
mov bp, sp
|
|
||||||
|
|
||||||
mov ax, .id ; ID
|
|
||||||
call gui_get_widget_ptr
|
|
||||||
jc .err
|
|
||||||
|
|
||||||
xor ax, ax
|
|
||||||
mov al, [gs:si + widget.state]
|
|
||||||
jmp .done
|
|
||||||
|
|
||||||
.err:
|
|
||||||
mov ax, -1
|
|
||||||
.done:
|
|
||||||
leave
|
|
||||||
ret
|
|
||||||
%undef .id
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
; gui_api_get_type
|
|
||||||
; Arg1: ID
|
|
||||||
; Out: AX = Type
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
%define .id word [bp+4]
|
|
||||||
gui_api_get_type:
|
|
||||||
push bp
|
|
||||||
mov bp, sp
|
|
||||||
|
|
||||||
mov ax, .id ; ID
|
|
||||||
call gui_get_widget_ptr
|
|
||||||
jc .err
|
|
||||||
|
|
||||||
xor ax, ax
|
|
||||||
mov al, [gs:si + widget.type]
|
|
||||||
jmp .done
|
|
||||||
|
|
||||||
.err:
|
|
||||||
mov ax, -1
|
|
||||||
.done:
|
|
||||||
leave
|
|
||||||
ret
|
|
||||||
%undef .id
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
; gui_api_get_val
|
|
||||||
; Arg1: ID
|
|
||||||
; Out: AX = Attr Val
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
%define .id word [bp+4]
|
|
||||||
gui_api_get_val:
|
|
||||||
push bp
|
|
||||||
mov bp, sp
|
|
||||||
|
|
||||||
call gui_get_widget_ptr
|
|
||||||
;jc .err
|
|
||||||
|
|
||||||
call gui_slider_update_value
|
|
||||||
mov ax, [gs:si + widget.attr_val]
|
|
||||||
jmp .done
|
|
||||||
|
|
||||||
.err:
|
|
||||||
mov ax, -1
|
|
||||||
.done:
|
|
||||||
leave
|
|
||||||
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
|
|
||||||
|
|
||||||
mov ax, .id ; ID
|
|
||||||
call gui_get_widget_ptr
|
|
||||||
jc .err
|
|
||||||
|
|
||||||
mov ax, .val
|
|
||||||
mov [gs:si + widget.thumb_pos], ax
|
|
||||||
|
|
||||||
.err:
|
|
||||||
leave
|
|
||||||
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]
|
|
||||||
gui_api_destroy:
|
|
||||||
push bp
|
|
||||||
mov bp, sp
|
|
||||||
|
|
||||||
mov ax, .id ; ID
|
|
||||||
call gui_get_widget_ptr
|
|
||||||
jc .err
|
|
||||||
|
|
||||||
call gui_free_widget
|
|
||||||
xor ax, ax
|
|
||||||
jmp .done
|
|
||||||
|
|
||||||
.err:
|
|
||||||
mov ax, -1
|
|
||||||
.done:
|
|
||||||
leave
|
|
||||||
ret
|
|
||||||
%undef .id
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
; gui_get_widget_ptr
|
|
||||||
; Helper interne : Convertit ID en Pointeur
|
|
||||||
; In: ID
|
|
||||||
; Out: GS:SI = Ptr, CF=1 if error
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
%define .id word [bp+4]
|
|
||||||
gui_get_widget_ptr:
|
|
||||||
push bp
|
|
||||||
mov bp, sp
|
|
||||||
push ax
|
|
||||||
push cx
|
|
||||||
|
|
||||||
mov ax, .id
|
|
||||||
cmp ax, GUI_MAX_WIDGETS
|
|
||||||
jae .error
|
|
||||||
|
|
||||||
mov cx, widget_size
|
|
||||||
xor dx, dx
|
|
||||||
mul cx ; AX = Offset
|
|
||||||
mov si, ax
|
|
||||||
|
|
||||||
mov ax, GUI_RAM_SEG
|
|
||||||
mov gs, ax
|
|
||||||
|
|
||||||
clc
|
|
||||||
jmp .done
|
|
||||||
.error:
|
|
||||||
stc
|
|
||||||
.done:
|
|
||||||
pop cx
|
|
||||||
pop ax
|
|
||||||
leave
|
|
||||||
ret
|
|
||||||
%undef .id
|
|
||||||
|
|
||||||
|
|
||||||
; =============================================================================
|
|
||||||
; SECTION : GESTION MÉMOIRE (ALLOCATION / LIBÉRATION)
|
|
||||||
; =============================================================================
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
; gui_init_system
|
|
||||||
; Initialise toute la mémoire des widgets à 0 (Libre)
|
|
||||||
; Entrée : DS doit pointer vers GUI_RAM_SEG
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
gui_init_system:
|
|
||||||
push eax
|
|
||||||
push cx
|
|
||||||
push es
|
|
||||||
push di
|
|
||||||
|
|
||||||
mov ax, GUI_RAM_SEG
|
|
||||||
mov es, ax
|
|
||||||
|
|
||||||
cld
|
|
||||||
xor di, di
|
|
||||||
mov cx, (widget_size * GUI_MAX_WIDGETS) / 2
|
|
||||||
xor ax, ax
|
|
||||||
rep stosw ; Plus sûr en mode 16 bits pour l'alignement
|
|
||||||
|
|
||||||
pop di
|
|
||||||
pop es
|
|
||||||
pop cx
|
|
||||||
pop eax
|
|
||||||
ret
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
; gui_alloc_widget
|
|
||||||
; Cherche un slot vide et retourne son adresse
|
|
||||||
; Sortie :
|
|
||||||
; - Succès : CF=0 (Carry Clear), GS:SI = Offset du widget
|
|
||||||
; - Echec : CF=1 (Carry Set), GS:SI = Indéfini (ou 0)
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
gui_alloc_widget:
|
|
||||||
push ax
|
|
||||||
push cx
|
|
||||||
push bx
|
|
||||||
|
|
||||||
mov ax, GUI_RAM_SEG
|
|
||||||
mov gs, ax
|
|
||||||
|
|
||||||
mov si, 0 ; Début du pool
|
|
||||||
mov cx, GUI_MAX_WIDGETS
|
|
||||||
|
|
||||||
.loop_find:
|
|
||||||
cmp byte [gs:si + widget.state], GUI_STATE_FREE
|
|
||||||
je .found ; Si state == 0, c'est libre !
|
|
||||||
|
|
||||||
add si, widget_size ; Sinon on passe au suivant
|
|
||||||
loop .loop_find
|
|
||||||
|
|
||||||
; Pas trouvé (Plein)
|
|
||||||
stc ; set Carry Flag : erreur
|
|
||||||
jmp .done
|
|
||||||
|
|
||||||
.found:
|
|
||||||
; On initialise le slot trouvé
|
|
||||||
mov byte [gs:si + widget.state], GUI_STATE_NORMAL ; Marquer comme occupé
|
|
||||||
mov byte [gs:si + widget.type], OBJ_TYPE_BUTTON ; Type par défaut
|
|
||||||
mov byte [gs:si + widget.oldstate], 0 ; doit etre dessiné
|
|
||||||
|
|
||||||
; Reset des champs critiques pour éviter les déchets
|
|
||||||
mov word [gs:si + widget.event_click], 0
|
|
||||||
mov word [gs:si + widget.event_drag], 0
|
|
||||||
mov byte [gs:si + widget.thumb_pct], 10 ; 10% par défaut
|
|
||||||
|
|
||||||
clc ; Clear Carry Flag
|
|
||||||
.done:
|
|
||||||
pop bx
|
|
||||||
pop cx
|
|
||||||
pop ax
|
|
||||||
ret
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
; gui_free_widget
|
|
||||||
; Libère un widget
|
|
||||||
; Entrée : SI = Pointeur widget
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
gui_free_widget:
|
|
||||||
push eax
|
|
||||||
push es
|
|
||||||
|
|
||||||
mov ax, GUI_RAM_SEG
|
|
||||||
mov es, ax
|
|
||||||
|
|
||||||
cld
|
|
||||||
mov di, si
|
|
||||||
mov cx, (widget_size)
|
|
||||||
shr cx, 2 ; cx / 4
|
|
||||||
xor eax, eax
|
|
||||||
rep stosd ; Remplit tout de 0
|
|
||||||
|
|
||||||
; On efface le widget
|
|
||||||
mov byte [es:si + widget.state], GUI_STATE_FREE
|
|
||||||
; Pour l'instant on le marque juste libre, il n'est pas retirer de l'écran.
|
|
||||||
|
|
||||||
pop es
|
|
||||||
pop eax
|
|
||||||
ret
|
|
||||||
|
|
||||||
; =============================================================================
|
; =============================================================================
|
||||||
; SECTION : MOTEUR D'ÉVÉNEMENTS (EVENT LOOP)
|
; SECTION : MOTEUR D'ÉVÉNEMENTS (EVENT LOOP)
|
||||||
; =============================================================================
|
; =============================================================================
|
||||||
|
|
@ -543,12 +16,12 @@ gui_process_all:
|
||||||
push ds
|
push ds
|
||||||
push gs
|
push gs
|
||||||
|
|
||||||
mov ax, GUI_RAM_SEG
|
mov ax, BDA_GUI_WIDGET
|
||||||
mov gs, ax
|
mov gs, ax
|
||||||
|
|
||||||
; Charger l'état de la souris pour toute la passe
|
; Charger l'état de la souris pour toute la passe
|
||||||
push ds
|
push ds
|
||||||
mov ax, BDA_DATA_SEG
|
mov ax, BDA_CUSTOM_SEG
|
||||||
mov ds, ax
|
mov ds, ax
|
||||||
mov bl, [BDA_MOUSE + mouse.status]
|
mov bl, [BDA_MOUSE + mouse.status]
|
||||||
pop ds
|
pop ds
|
||||||
|
|
@ -612,9 +85,9 @@ gui_update_logic:
|
||||||
push ds
|
push ds
|
||||||
push gs
|
push gs
|
||||||
|
|
||||||
mov ax, BDA_DATA_SEG
|
mov ax, BDA_CUSTOM_SEG
|
||||||
mov ds, ax
|
mov ds, ax
|
||||||
mov ax, GUI_RAM_SEG
|
mov ax, BDA_GUI_WIDGET
|
||||||
mov gs, ax
|
mov gs, ax
|
||||||
|
|
||||||
mov al, byte [gs:si + widget.state]
|
mov al, byte [gs:si + widget.state]
|
||||||
|
|
@ -962,7 +435,7 @@ gui_logic_slider:
|
||||||
; 4. Target Pos = MouseX - Anchor
|
; 4. Target Pos = MouseX - Anchor
|
||||||
; On recharge MouseX depuis la BDA pour être sûr
|
; On recharge MouseX depuis la BDA pour être sûr
|
||||||
push ds
|
push ds
|
||||||
mov ax, BDA_DATA_SEG
|
mov ax, BDA_CUSTOM_SEG
|
||||||
mov ds, ax
|
mov ds, ax
|
||||||
mov ax, [BDA_MOUSE + mouse.x]
|
mov ax, [BDA_MOUSE + mouse.x]
|
||||||
pop ds
|
pop ds
|
||||||
|
|
@ -990,7 +463,7 @@ gui_logic_slider:
|
||||||
; 4. Target Pos = MouseY - Anchor
|
; 4. Target Pos = MouseY - Anchor
|
||||||
; On recharge MouseY depuis la BDA pour être sûr
|
; On recharge MouseY depuis la BDA pour être sûr
|
||||||
push ds
|
push ds
|
||||||
mov ax, BDA_DATA_SEG
|
mov ax, BDA_CUSTOM_SEG
|
||||||
mov ds, ax
|
mov ds, ax
|
||||||
mov ax, [BDA_MOUSE + mouse.y]
|
mov ax, [BDA_MOUSE + mouse.y]
|
||||||
pop ds
|
pop ds
|
||||||
Loading…
Reference in a new issue