vga Drivers +Mouse
This commit is contained in:
parent
0775fe6193
commit
7c9ad48b19
10 changed files with 730 additions and 404 deletions
200
src/boot-vga.asm
Normal file
200
src/boot-vga.asm
Normal file
|
|
@ -0,0 +1,200 @@
|
||||||
|
; =============================================================================
|
||||||
|
; 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 'VGA'
|
||||||
|
|
||||||
|
%define DEBUGER_ENABLED
|
||||||
|
|
||||||
|
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"
|
||||||
|
%include "./common/debug_txt.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, 1
|
||||||
|
|
||||||
|
; Install IRQ 0 : timer_isr
|
||||||
|
mov ax,cs
|
||||||
|
mov dx,ax
|
||||||
|
mov bx,timer_isr
|
||||||
|
mov ax,i8259_MASTER_INT
|
||||||
|
|
||||||
|
call ivt_setvector
|
||||||
|
; initialisation des PIC 8259A
|
||||||
|
call pic_init
|
||||||
|
; load Roms
|
||||||
|
call setup_load_rom
|
||||||
|
; on vérifie que le BIOS VGA a installé une INT 10h
|
||||||
|
call setup_check_vga
|
||||||
|
; enable IRQ 0
|
||||||
|
mov ah,IRQ_ENABLED
|
||||||
|
mov al,0
|
||||||
|
call pic_set_irq_mask
|
||||||
|
|
||||||
|
call kbd_init
|
||||||
|
sti
|
||||||
|
; on active le mode graphique
|
||||||
|
GFX INIT
|
||||||
|
call mouse_init
|
||||||
|
GFX MOUSE_SHOW
|
||||||
|
|
||||||
|
.loops:
|
||||||
|
call main_loop
|
||||||
|
jmp .loops
|
||||||
|
|
||||||
|
; --- Callbacks (Fonctions appelées par le moteur) ---
|
||||||
|
on_click_quit:
|
||||||
|
hlt
|
||||||
|
jmp on_click_quit
|
||||||
|
ret
|
||||||
|
|
||||||
|
on_click_hello:
|
||||||
|
ret
|
||||||
|
|
||||||
|
main_loop:
|
||||||
|
push bp
|
||||||
|
mov bp, sp
|
||||||
|
%define .oldval word [bp-2]
|
||||||
|
%define .my_slider word [bp-4]
|
||||||
|
%define .value word [bp-6]
|
||||||
|
sub sp, 6
|
||||||
|
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
|
||||||
|
GFX GOTOXY, 5,5
|
||||||
|
GFX WRITE, str_hello
|
||||||
|
|
||||||
|
|
||||||
|
; Init du système GUI
|
||||||
|
; call gui_init_system
|
||||||
|
|
||||||
|
.loop:
|
||||||
|
; call gui_process_all
|
||||||
|
|
||||||
|
mov dh, 1
|
||||||
|
mov dl, 10
|
||||||
|
call scr_gotoxy
|
||||||
|
|
||||||
|
mov ax, BDA_CUSTOM_SEG
|
||||||
|
mov fs, ax
|
||||||
|
mov ax, word [fs:PTR_MOUSE + mouse.x]
|
||||||
|
call scr_puthex16
|
||||||
|
|
||||||
|
mov al, ' '
|
||||||
|
call scr_putc
|
||||||
|
|
||||||
|
mov ax, word [fs:PTR_MOUSE + mouse.y]
|
||||||
|
call scr_puthex16
|
||||||
|
|
||||||
|
nop
|
||||||
|
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)
|
||||||
176
src/boot.asm
176
src/boot.asm
|
|
@ -19,178 +19,4 @@
|
||||||
; along with this program. If not, see <https://www.gnu.org/licenses/>.
|
; along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
;
|
;
|
||||||
; =============================================================================
|
; =============================================================================
|
||||||
|
%include "./boot-vga.asm"
|
||||||
bits 16
|
|
||||||
; ---------------------------------------------------------------------------
|
|
||||||
;
|
|
||||||
; configuration du bios
|
|
||||||
;
|
|
||||||
; ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
; initial stack
|
|
||||||
%define STACK_SEG 0x0800 ; segment de base
|
|
||||||
%define GFX_DRIVERS 'VGA'
|
|
||||||
|
|
||||||
%define DEBUGER_ENABLED
|
|
||||||
|
|
||||||
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, 1
|
|
||||||
|
|
||||||
; Install IRQ 0 : timer_isr
|
|
||||||
mov ax,cs
|
|
||||||
mov dx,ax
|
|
||||||
mov bx,timer_isr
|
|
||||||
mov ax,i8259_MASTER_INT
|
|
||||||
|
|
||||||
call ivt_setvector
|
|
||||||
; initialisation des PIC 8259A
|
|
||||||
call pic_init
|
|
||||||
; load Roms
|
|
||||||
call setup_load_rom
|
|
||||||
; on vérifie que le BIOS VGA a installé une INT 10h
|
|
||||||
call setup_check_vga
|
|
||||||
; enable IRQ 0
|
|
||||||
mov ah,IRQ_ENABLED
|
|
||||||
mov al,0
|
|
||||||
call pic_set_irq_mask
|
|
||||||
|
|
||||||
call kbd_init
|
|
||||||
sti
|
|
||||||
|
|
||||||
ISADBG ISA_GREEN, 32
|
|
||||||
|
|
||||||
; on active le mode graphique
|
|
||||||
GFX INIT
|
|
||||||
call mouse_reset
|
|
||||||
|
|
||||||
; call mouse_init
|
|
||||||
|
|
||||||
GFX MOUSE_MOVE
|
|
||||||
ISADBG ISA_RED, 0x80
|
|
||||||
|
|
||||||
GFX MOUSE_SHOW
|
|
||||||
ISADBG ISA_RED, 0x81
|
|
||||||
|
|
||||||
.loops:
|
|
||||||
call main_loop
|
|
||||||
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
|
|
||||||
|
|
||||||
.loop:
|
|
||||||
; call gui_process_all
|
|
||||||
|
|
||||||
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)
|
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,9 @@
|
||||||
%define BDA_CUSTOM_SEG 0x0050 ; custom data (mouse, gfx cursor, etc..)
|
%define BDA_CUSTOM_SEG 0x0050 ; custom data (mouse, gfx cursor, etc..)
|
||||||
%define BDA_GUI_WIDGET 0x0070 ; Segment de données UI (Safe: après Stack, avant Heap)
|
%define BDA_GUI_WIDGET 0x0070 ; Segment de données UI (Safe: après Stack, avant Heap)
|
||||||
|
|
||||||
|
%define PTR_MOUSE 0x0000
|
||||||
|
%define PTR_GFX (PTR_MOUSE + mouse_size)
|
||||||
|
|
||||||
; 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
|
||||||
%define BDA_VIDEO_COLUMNS 0x004A
|
%define BDA_VIDEO_COLUMNS 0x004A
|
||||||
|
|
@ -37,7 +40,7 @@
|
||||||
; information relative à la souris
|
; information relative à la souris
|
||||||
;
|
;
|
||||||
|
|
||||||
%define BDA_BitPP 4
|
%define BDA_BitPPixel 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
|
||||||
|
|
@ -45,55 +48,52 @@
|
||||||
%define BKG_TOTAL_BYTES (BKG_TOTAL_DWORDS * 4) ; 64
|
%define BKG_TOTAL_BYTES (BKG_TOTAL_DWORDS * 4) ; 64
|
||||||
|
|
||||||
struc mouse
|
struc mouse
|
||||||
.buffer resb 4 ; i8042 input buffer
|
.buffer resb 4 ; i8042 input buffer
|
||||||
.idx resb 1 ; index in the buffer
|
.idx resb 1 ; index in the buffer
|
||||||
.packetlen resb 1 ; max buffer len (3 ou 4)
|
.packetlen resb 1 ; max buffer len (3 ou 4)
|
||||||
.status resb 1 ; mouse status (button etc)
|
.status resb 1 ; mouse status (button etc)
|
||||||
.wheel resb 1 ; if a packet size is 4; experimental
|
.wheel resb 1 ; if a packet size is 4; experimental
|
||||||
.x resw 1 ;
|
.x resw 1 ;
|
||||||
.y resw 1 ;
|
.y resw 1 ;
|
||||||
; cursor management
|
; cursor management
|
||||||
.cur_x resw 1 ; preservation des x,y du background
|
.cur_x resw 1 ; preservation des x,y du background
|
||||||
.cur_y resw 1 ;
|
.cur_y resw 1 ;
|
||||||
.cur_addr_start resw 1 ; adresse de départ de la sauvegarde
|
.cur_addr_start resw 1 ; adresse de départ de la sauvegarde
|
||||||
.cur_drawing resb 1 ;
|
.cur_drawing resb 1 ;
|
||||||
.cur_counter resb 1 ; compteur de fois que le curseur a été caché (0 = visible, <0 = invisible)
|
.cur_counter resb 1 ; compteur de fois que le curseur a été caché (0 = visible, <0 = invisible)
|
||||||
.cur_seg resw 1 ; segment / offset of the pointer
|
.cur_seg resw 1 ; segment / offset of the pointer
|
||||||
.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
|
||||||
; buffer for saved background
|
; buffer for saved background
|
||||||
.bkg_buffer resd 16*BDA_BitPP
|
.bkg_buffer resd 16*BDA_BitPPixel
|
||||||
endstruc
|
endstruc
|
||||||
|
|
||||||
struc gfx
|
struc gfx
|
||||||
.cur_x resw 1 ; x,y en pixel
|
.cur_x resw 1 ; x,y en pixel
|
||||||
.cur_y resw 1
|
.cur_y resw 1
|
||||||
.cur_offset resw 1 ; offset calculé pour le prochain caractère
|
.cur_offset resw 1 ; offset calculé pour le prochain caractère
|
||||||
.cur_line_ofs resw 1 ; "interligne" +2000h ou -2000h
|
.cur_line_ofs resw 1 ; "interligne" +2000h ou -2000h
|
||||||
.cur_shift resb 1 ; x&7 (0..7)
|
.cur_shift resb 1 ; x&7 (0..7)
|
||||||
.cur_mode resb 1 ;
|
.cur_mode resb 1 ;
|
||||||
endstruc
|
endstruc
|
||||||
|
|
||||||
%define BDA_MOUSE 0x0000
|
|
||||||
%define BDA_GFX (BDA_MOUSE + mouse_size)
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------------
|
; -----------------------------------------------------------------------------------
|
||||||
; bda_setup
|
; bda_setup
|
||||||
; Initialise la BDA à zéro
|
; Initialise la BDA à zéro
|
||||||
; -----------------------------------------------------------------------------------
|
; -----------------------------------------------------------------------------------
|
||||||
bda_setup:
|
bda_setup:
|
||||||
pusha
|
pusha
|
||||||
push ds
|
push ds
|
||||||
|
|
||||||
mov ax, BDA_CUSTOM_SEG
|
mov ax, BDA_CUSTOM_SEG
|
||||||
mov es, ax
|
mov es, ax
|
||||||
|
|
||||||
mov ax, 0x5F
|
mov ax, 0x5F
|
||||||
mov cx,0xFF
|
mov cx,0xFF
|
||||||
xor di, di
|
xor di, di
|
||||||
rep stosb ; clear BDA area
|
rep stosb ; clear BDA area
|
||||||
|
|
||||||
pop ds
|
pop ds
|
||||||
popa
|
popa
|
||||||
ret
|
ret
|
||||||
|
|
@ -21,6 +21,7 @@ mouse_arrow:
|
||||||
dw 1111110000111111b ; 0xFC3F
|
dw 1111110000111111b ; 0xFC3F
|
||||||
dw 1111111000111111b ; 0xFE3F
|
dw 1111111000111111b ; 0xFE3F
|
||||||
dw 0000000000000000b ; 0x0000
|
dw 0000000000000000b ; 0x0000
|
||||||
|
|
||||||
dw 0010000000000000b ; 0x2000
|
dw 0010000000000000b ; 0x2000
|
||||||
dw 0011000000000000b ; 0x3000
|
dw 0011000000000000b ; 0x3000
|
||||||
dw 0011100000000000b ; 0x3800
|
dw 0011100000000000b ; 0x3800
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@
|
||||||
%define DEBUG_PORT 0xe9 ; 0x402 ou 0xe9
|
%define DEBUG_PORT 0xe9 ; 0x402 ou 0xe9
|
||||||
|
|
||||||
debug_puts:
|
debug_puts:
|
||||||
.next:
|
.next:
|
||||||
push dx
|
push dx
|
||||||
mov dx, DEBUG_PORT
|
mov dx, DEBUG_PORT
|
||||||
lodsb ; AL = *SI++
|
lodsb ; AL = *SI++
|
||||||
|
|
@ -31,7 +31,7 @@ debug_puts:
|
||||||
jz .done
|
jz .done
|
||||||
out dx, al
|
out dx, al
|
||||||
jmp .next
|
jmp .next
|
||||||
.done:
|
.done:
|
||||||
pop dx
|
pop dx
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
@ -49,9 +49,9 @@ debug_puthex4:
|
||||||
jbe .num
|
jbe .num
|
||||||
add al, 'A' - 10
|
add al, 'A' - 10
|
||||||
jmp .pout
|
jmp .pout
|
||||||
.num:
|
.num:
|
||||||
add al, '0'
|
add al, '0'
|
||||||
.pout:
|
.pout:
|
||||||
call debug_putc
|
call debug_putc
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
@ -88,6 +88,8 @@ scr_gotoxy:
|
||||||
|
|
||||||
scr_putc:
|
scr_putc:
|
||||||
mov ah, 0x0E
|
mov ah, 0x0E
|
||||||
|
mov bh, 0x00
|
||||||
|
mov bl, 0x0f
|
||||||
int 10h
|
int 10h
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
@ -98,12 +100,14 @@ scr_puthex4:
|
||||||
jbe .num ; yes
|
jbe .num ; yes
|
||||||
add al, 'A' - 10 ; convert to 'A'..'F'
|
add al, 'A' - 10 ; convert to 'A'..'F'
|
||||||
jmp .pout
|
jmp .pout
|
||||||
.num:
|
.num:
|
||||||
add al, '0' ; convert to '0'..'9'
|
add al, '0' ; convert to '0'..'9'
|
||||||
.pout:
|
.pout:
|
||||||
mov ah, 0x0E
|
mov ah, 0x0e
|
||||||
|
mov bh, 0x00
|
||||||
|
mov bl, 0x0f
|
||||||
int 10h
|
int 10h
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; AL = byte -> print 2 hex digits
|
; AL = byte -> print 2 hex digits
|
||||||
scr_puthex8:
|
scr_puthex8:
|
||||||
|
|
|
||||||
|
|
@ -172,13 +172,12 @@ cga_calc_addr:
|
||||||
; si le mode n'est pas transparent, la couleur de fond
|
; si le mode n'est pas transparent, la couleur de fond
|
||||||
; est l'inverse de la couleur du texte
|
; est l'inverse de la couleur du texte
|
||||||
; ---------------------------------------------------------------------------
|
; ---------------------------------------------------------------------------
|
||||||
|
; --- Définition des arguments ---
|
||||||
|
%define .mode word [bp+4]
|
||||||
cga_set_writemode:
|
cga_set_writemode:
|
||||||
push bp
|
push bp
|
||||||
mov bp, sp
|
mov bp, sp
|
||||||
|
|
||||||
; --- Définition des arguments ---
|
|
||||||
%define .mode word [bp+4]
|
|
||||||
|
|
||||||
push fs
|
push fs
|
||||||
push ax
|
push ax
|
||||||
mov ax, BDA_CUSTOM_SEG
|
mov ax, BDA_CUSTOM_SEG
|
||||||
|
|
@ -186,12 +185,13 @@ cga_set_writemode:
|
||||||
|
|
||||||
mov ax, .mode
|
mov ax, .mode
|
||||||
|
|
||||||
mov byte [fs:BDA_GFX + gfx.cur_mode], al
|
mov byte [fs:PTR_GFX + gfx.cur_mode], al
|
||||||
|
|
||||||
pop ax
|
pop ax
|
||||||
pop fs
|
pop fs
|
||||||
leave
|
leave
|
||||||
ret
|
ret
|
||||||
|
%undef .mode
|
||||||
|
|
||||||
; ---------------------------------------------------------------------------
|
; ---------------------------------------------------------------------------
|
||||||
; gfx_set_charpos (x,y)
|
; gfx_set_charpos (x,y)
|
||||||
|
|
@ -219,12 +219,12 @@ cga_set_charpos:
|
||||||
mov cx, .x
|
mov cx, .x
|
||||||
mov dx, .y
|
mov dx, .y
|
||||||
|
|
||||||
mov [fs:BDA_GFX + gfx.cur_x], cx
|
mov [fs:PTR_GFX + gfx.cur_x], cx
|
||||||
mov [fs:BDA_GFX + gfx.cur_y], dx
|
mov [fs:PTR_GFX + gfx.cur_y], dx
|
||||||
|
|
||||||
mov ax, cx
|
mov ax, cx
|
||||||
and ax, 0x07
|
and ax, 0x07
|
||||||
mov [fs:BDA_GFX + gfx.cur_shift], al
|
mov [fs:PTR_GFX + gfx.cur_shift], al
|
||||||
|
|
||||||
; calcul de l'offset de la position 'x,y':
|
; calcul de l'offset de la position 'x,y':
|
||||||
; si 'y' est paire, DI < 0x2000 & add = 0x2000
|
; si 'y' est paire, DI < 0x2000 & add = 0x2000
|
||||||
|
|
@ -247,8 +247,8 @@ cga_set_charpos:
|
||||||
neg ax
|
neg ax
|
||||||
add ax, CGA_STRIDE
|
add ax, CGA_STRIDE
|
||||||
.even:
|
.even:
|
||||||
mov [fs:BDA_GFX + gfx.cur_line_ofs], ax
|
mov [fs:PTR_GFX + gfx.cur_line_ofs], ax
|
||||||
mov [fs:BDA_GFX + gfx.cur_offset], bx
|
mov [fs:PTR_GFX + gfx.cur_offset], bx
|
||||||
|
|
||||||
pop fs
|
pop fs
|
||||||
|
|
||||||
|
|
@ -323,10 +323,10 @@ cga_putc:
|
||||||
call get_glyph_offset
|
call get_glyph_offset
|
||||||
|
|
||||||
; Base offset VRAM pour la scanline Y
|
; Base offset VRAM pour la scanline Y
|
||||||
mov di, [fs:BDA_GFX + gfx.cur_offset]
|
mov di, [fs:PTR_GFX + gfx.cur_offset]
|
||||||
mov bx, [fs:BDA_GFX + gfx.cur_line_ofs]
|
mov bx, [fs:PTR_GFX + gfx.cur_line_ofs]
|
||||||
mov ch, [fs:BDA_GFX + gfx.cur_mode]
|
mov ch, [fs:PTR_GFX + gfx.cur_mode]
|
||||||
mov cl, [fs:BDA_GFX + gfx.cur_shift]
|
mov cl, [fs:PTR_GFX + gfx.cur_shift]
|
||||||
|
|
||||||
mov .cpt, 4
|
mov .cpt, 4
|
||||||
|
|
||||||
|
|
@ -391,8 +391,8 @@ cga_putc:
|
||||||
jnz .row_loop
|
jnz .row_loop
|
||||||
|
|
||||||
; Avancer curseur d'un caractère (8 pixels)
|
; Avancer curseur d'un caractère (8 pixels)
|
||||||
inc word [fs:BDA_GFX + gfx.cur_offset]
|
inc word [fs:PTR_GFX + gfx.cur_offset]
|
||||||
add word [fs:BDA_GFX + gfx.cur_x], 8
|
add word [fs:PTR_GFX + gfx.cur_x], 8
|
||||||
|
|
||||||
call cga_mouse_show ; Restauration souris
|
call cga_mouse_show ; Restauration souris
|
||||||
|
|
||||||
|
|
@ -1272,10 +1272,10 @@ cga_mouse_hide:
|
||||||
mov ds, ax
|
mov ds, ax
|
||||||
|
|
||||||
; Décrémenter le compteur
|
; Décrémenter le compteur
|
||||||
dec byte [BDA_MOUSE + mouse.cur_counter]
|
dec byte [PTR_MOUSE + mouse.cur_counter]
|
||||||
|
|
||||||
; Vérifier si on vient juste de passer en mode caché (c-à-d on est à -1)
|
; Vérifier si on vient juste de passer en mode caché (c-à-d on est à -1)
|
||||||
cmp byte [BDA_MOUSE + mouse.cur_counter], -1
|
cmp byte [PTR_MOUSE + mouse.cur_counter], -1
|
||||||
jne .skip_restore ; Si on est à -2, -3... elle est déjà cachée
|
jne .skip_restore ; Si on est à -2, -3... elle est déjà cachée
|
||||||
|
|
||||||
call cga_cursor_restorebg
|
call cga_cursor_restorebg
|
||||||
|
|
@ -1300,10 +1300,10 @@ cga_mouse_show:
|
||||||
mov ds, ax
|
mov ds, ax
|
||||||
|
|
||||||
; Incrémenter le compteur
|
; Incrémenter le compteur
|
||||||
inc byte [BDA_MOUSE + mouse.cur_counter]
|
inc byte [PTR_MOUSE + mouse.cur_counter]
|
||||||
|
|
||||||
; Vérifier si on est revenu à 0 (Visible)
|
; Vérifier si on est revenu à 0 (Visible)
|
||||||
cmp byte [BDA_MOUSE + mouse.cur_counter], 0
|
cmp byte [PTR_MOUSE + mouse.cur_counter], 0
|
||||||
jne .skip_draw ; Si on est encore à -1, -2... on reste caché
|
jne .skip_draw ; Si on est encore à -1, -2... on reste caché
|
||||||
|
|
||||||
; C'est la transition Caché -> Visible : On affiche le curseur
|
; C'est la transition Caché -> Visible : On affiche le curseur
|
||||||
|
|
@ -1331,13 +1331,13 @@ cga_mouse_cursor_move:
|
||||||
mov ax, BDA_CUSTOM_SEG
|
mov ax, BDA_CUSTOM_SEG
|
||||||
mov ds, ax
|
mov ds, ax
|
||||||
|
|
||||||
cmp byte [BDA_MOUSE + mouse.cur_counter], 0
|
cmp byte [PTR_MOUSE + mouse.cur_counter], 0
|
||||||
jl .done ; Si < 0, on ne dessine rien !
|
jl .done ; Si < 0, on ne dessine rien !
|
||||||
|
|
||||||
cmp byte [BDA_MOUSE + mouse.cur_drawing],0
|
cmp byte [PTR_MOUSE + mouse.cur_drawing],0
|
||||||
jne .done
|
jne .done
|
||||||
|
|
||||||
mov byte [BDA_MOUSE + mouse.cur_drawing],1
|
mov byte [PTR_MOUSE + mouse.cur_drawing],1
|
||||||
|
|
||||||
mov ax, VIDEO_SEG
|
mov ax, VIDEO_SEG
|
||||||
mov es, ax
|
mov es, ax
|
||||||
|
|
@ -1347,7 +1347,7 @@ cga_mouse_cursor_move:
|
||||||
call cga_cursor_savebg
|
call cga_cursor_savebg
|
||||||
|
|
||||||
call cga_cursor_draw
|
call cga_cursor_draw
|
||||||
mov byte [BDA_MOUSE + mouse.cur_drawing],0
|
mov byte [PTR_MOUSE + mouse.cur_drawing],0
|
||||||
.done:
|
.done:
|
||||||
pop es
|
pop es
|
||||||
pop ds
|
pop ds
|
||||||
|
|
@ -1360,7 +1360,7 @@ cga_mouse_cursor_move:
|
||||||
; Stocke 16 DWORDs: chaque DWORD contient les 4 bytes de la ligne
|
; Stocke 16 DWORDs: chaque DWORD contient les 4 bytes de la ligne
|
||||||
; ------------------------------------------------------------
|
; ------------------------------------------------------------
|
||||||
cga_cursor_savebg:
|
cga_cursor_savebg:
|
||||||
cmp byte [BDA_MOUSE + mouse.bkg_saved], 0 ; le buffer n'a pas encore été restauré
|
cmp byte [PTR_MOUSE + mouse.bkg_saved], 0 ; le buffer n'a pas encore été restauré
|
||||||
jne .done
|
jne .done
|
||||||
|
|
||||||
push es
|
push es
|
||||||
|
|
@ -1368,16 +1368,16 @@ cga_cursor_savebg:
|
||||||
mov es, ax
|
mov es, ax
|
||||||
|
|
||||||
; mémoriser position courante (utilisée pour restore)
|
; mémoriser position courante (utilisée pour restore)
|
||||||
mov cx, [BDA_MOUSE + mouse.x]
|
mov cx, [PTR_MOUSE + mouse.x]
|
||||||
mov dx, [BDA_MOUSE + mouse.y]
|
mov dx, [PTR_MOUSE + mouse.y]
|
||||||
mov [BDA_MOUSE + mouse.cur_x], cx
|
mov [PTR_MOUSE + mouse.cur_x], cx
|
||||||
mov [BDA_MOUSE + mouse.cur_y], dx
|
mov [PTR_MOUSE + mouse.cur_y], dx
|
||||||
|
|
||||||
; calcule ES:DI pour (x,y)
|
; calcule ES:DI pour (x,y)
|
||||||
call cga_calc_addr
|
call cga_calc_addr
|
||||||
|
|
||||||
mov [BDA_MOUSE + mouse.cur_addr_start], di
|
mov [PTR_MOUSE + mouse.cur_addr_start], di
|
||||||
lea si, [BDA_MOUSE + mouse.bkg_buffer]
|
lea si, [PTR_MOUSE + mouse.bkg_buffer]
|
||||||
|
|
||||||
mov cx,16
|
mov cx,16
|
||||||
|
|
||||||
|
|
@ -1398,7 +1398,7 @@ cga_cursor_savebg:
|
||||||
pop es
|
pop es
|
||||||
|
|
||||||
.done:
|
.done:
|
||||||
mov byte [BDA_MOUSE + mouse.bkg_saved], 1 ; Flag mis à jour après la copie
|
mov byte [PTR_MOUSE + mouse.bkg_saved], 1 ; Flag mis à jour après la copie
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; ------------------------------------------------------------
|
; ------------------------------------------------------------
|
||||||
|
|
@ -1406,7 +1406,7 @@ cga_cursor_savebg:
|
||||||
; Restaure 16 lignes sauvegardées.
|
; Restaure 16 lignes sauvegardées.
|
||||||
; ------------------------------------------------------------
|
; ------------------------------------------------------------
|
||||||
cga_cursor_restorebg:
|
cga_cursor_restorebg:
|
||||||
cmp byte [BDA_MOUSE + mouse.bkg_saved], 0
|
cmp byte [PTR_MOUSE + mouse.bkg_saved], 0
|
||||||
je .done
|
je .done
|
||||||
|
|
||||||
push es
|
push es
|
||||||
|
|
@ -1414,8 +1414,8 @@ cga_cursor_restorebg:
|
||||||
mov es, ax
|
mov es, ax
|
||||||
|
|
||||||
; restaurer depuis la dernière position sauvegardée
|
; restaurer depuis la dernière position sauvegardée
|
||||||
mov di, [BDA_MOUSE + mouse.cur_addr_start]
|
mov di, [PTR_MOUSE + mouse.cur_addr_start]
|
||||||
lea si, [BDA_MOUSE + mouse.bkg_buffer]
|
lea si, [PTR_MOUSE + mouse.bkg_buffer]
|
||||||
mov cx, 16
|
mov cx, 16
|
||||||
|
|
||||||
.row_loop:
|
.row_loop:
|
||||||
|
|
@ -1434,18 +1434,20 @@ cga_cursor_restorebg:
|
||||||
|
|
||||||
pop es
|
pop es
|
||||||
.done:
|
.done:
|
||||||
mov byte [BDA_MOUSE + mouse.bkg_saved], 0 ; Flag mis à jour après la restauration
|
mov byte [PTR_MOUSE + mouse.bkg_saved], 0 ; Flag mis à jour après la restauration
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; ============================================================
|
; ============================================================
|
||||||
; cga_cursor_draw
|
; cga_cursor_draw
|
||||||
; Détruit: registres sauvegardés/restaurés (PUSHA/POPA)
|
; Détruit: registres sauvegardés/restaurés (PUSHA/POPA)
|
||||||
; ============================================================
|
; ============================================================
|
||||||
%define .height word [bp-2]
|
|
||||||
%define .mask dword [bp-6]
|
|
||||||
cga_cursor_draw:
|
cga_cursor_draw:
|
||||||
push bp
|
push bp
|
||||||
mov bp, sp
|
mov bp, sp
|
||||||
|
|
||||||
|
; variables
|
||||||
|
%define .height word [bp-2]
|
||||||
|
%define .mask dword [bp-6]
|
||||||
sub sp, 6 ; Reserve space for locals
|
sub sp, 6 ; Reserve space for locals
|
||||||
|
|
||||||
pushad
|
pushad
|
||||||
|
|
@ -1460,7 +1462,7 @@ cga_cursor_draw:
|
||||||
mov es, ax
|
mov es, ax
|
||||||
|
|
||||||
; --- CLIPPING VERTICAL ---
|
; --- CLIPPING VERTICAL ---
|
||||||
mov dx, [ds:BDA_MOUSE + mouse.y]
|
mov dx, [ds:PTR_MOUSE + mouse.y]
|
||||||
mov bx, GFX_HEIGHT
|
mov bx, GFX_HEIGHT
|
||||||
cmp dx, bx
|
cmp dx, bx
|
||||||
jae .exit_total
|
jae .exit_total
|
||||||
|
|
@ -1478,7 +1480,7 @@ cga_cursor_draw:
|
||||||
; X est en bits (0-639). X >> 3 donne l'octet de départ (0-79).
|
; X est en bits (0-639). X >> 3 donne l'octet de départ (0-79).
|
||||||
; Si StartByte >= 77, on déborde.
|
; Si StartByte >= 77, on déborde.
|
||||||
|
|
||||||
mov cx, [BDA_MOUSE + mouse.x]
|
mov cx, [PTR_MOUSE + mouse.x]
|
||||||
shr cx, 3 ; CX = Byte Offset (0-79)
|
shr cx, 3 ; CX = Byte Offset (0-79)
|
||||||
xor esi, esi ; ESI = Masque de protection (0 = tout dessiner)
|
xor esi, esi ; ESI = Masque de protection (0 = tout dessiner)
|
||||||
|
|
||||||
|
|
@ -1508,17 +1510,17 @@ cga_cursor_draw:
|
||||||
mov .mask, esi
|
mov .mask, esi
|
||||||
|
|
||||||
; --- ADRESSAGE ---
|
; --- ADRESSAGE ---
|
||||||
mov cx, [BDA_MOUSE + mouse.x]
|
mov cx, [PTR_MOUSE + mouse.x]
|
||||||
mov dx, [BDA_MOUSE + mouse.y]
|
mov dx, [PTR_MOUSE + mouse.y]
|
||||||
call cga_calc_addr ; DI = Offset VRAM
|
call cga_calc_addr ; DI = Offset VRAM
|
||||||
|
|
||||||
mov ax, [BDA_MOUSE + mouse.cur_seg]
|
mov ax, [PTR_MOUSE + mouse.cur_seg]
|
||||||
mov gs, ax
|
mov gs, ax
|
||||||
mov si, [BDA_MOUSE + mouse.cur_ofs]
|
mov si, [PTR_MOUSE + mouse.cur_ofs]
|
||||||
|
|
||||||
; --- CALCUL de l'offset entre 2 lignes +0x2000 ou -0x2000 ---
|
; --- CALCUL de l'offset entre 2 lignes +0x2000 ou -0x2000 ---
|
||||||
mov ax, 0x2000 ; Banque +1
|
mov ax, 0x2000 ; Banque +1
|
||||||
mov cx, [BDA_MOUSE + mouse.y]
|
mov cx, [PTR_MOUSE + mouse.y]
|
||||||
test cx, 1
|
test cx, 1
|
||||||
jz .setup_done
|
jz .setup_done
|
||||||
neg ax ; banque -1
|
neg ax ; banque -1
|
||||||
|
|
@ -1529,28 +1531,20 @@ cga_cursor_draw:
|
||||||
.row_loop:
|
.row_loop:
|
||||||
; --- CONSTRUCTION DES MASQUES (EAX/EBX) ---
|
; --- CONSTRUCTION DES MASQUES (EAX/EBX) ---
|
||||||
push cx ; préserver la banque "suivante"
|
push cx ; préserver la banque "suivante"
|
||||||
mov cl, [BDA_MOUSE + mouse.x]
|
mov cl, [PTR_MOUSE + mouse.x]
|
||||||
and cl, 0x07
|
and cl, 0x07
|
||||||
|
|
||||||
; --- MASQUE AND (EAX) ---
|
; --- MASQUE AND (EAX) ---
|
||||||
mov eax, 0xFFFFFFFF
|
|
||||||
mov ax, [gs:si] ; masque AND
|
mov ax, [gs:si] ; masque AND
|
||||||
xchg al, ah ; Redresser pour l'ordre des pixels CGA
|
|
||||||
;bswap eax ; equivalence i386+
|
|
||||||
xchg ah, al ; Échange les octets de poids faible (AL <-> AH)
|
|
||||||
rol eax, 16 ; Bascule les 16 bits de poids fort vers le bas
|
rol eax, 16 ; Bascule les 16 bits de poids fort vers le bas
|
||||||
|
mov ax, 0xFFFF
|
||||||
xchg ah, al ; Échange les nouveaux octets de poids faible
|
xchg ah, al ; Échange les nouveaux octets de poids faible
|
||||||
; fin bswap eax equivalence i386+
|
|
||||||
|
|
||||||
ror eax, cl
|
ror eax, cl
|
||||||
|
|
||||||
or eax, .mask ; Force les bits clippés à 1 (garde le fond)
|
or eax, .mask ; Force les bits clippés à 1 (garde le fond)
|
||||||
|
|
||||||
; --- MASQUE XOR (EBX) ---
|
; --- MASQUE XOR (EBX) ---
|
||||||
xor ebx, ebx
|
xor ebx, ebx
|
||||||
mov bx, [gs:si+32] ; masque XOR
|
mov bx, [gs:si+32] ; masque XOR
|
||||||
;xchg bl, bh
|
|
||||||
;bswap ebx
|
|
||||||
rol ebx, 16
|
rol ebx, 16
|
||||||
xchg bh, bl
|
xchg bh, bl
|
||||||
ror ebx, cl
|
ror ebx, cl
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@
|
||||||
%define GFX_MODE 0x12 ; VGA HiRes (640x480x16)
|
%define GFX_MODE 0x12 ; VGA HiRes (640x480x16)
|
||||||
%define GFX_WIDTH 640
|
%define GFX_WIDTH 640
|
||||||
%define GFX_HEIGHT 480
|
%define GFX_HEIGHT 480
|
||||||
|
%define GFX_OFFSET 80
|
||||||
;
|
;
|
||||||
; bit : descr
|
; bit : descr
|
||||||
; 0 : text color : 0=black, 1=white
|
; 0 : text color : 0=black, 1=white
|
||||||
|
|
@ -74,7 +75,6 @@
|
||||||
%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
|
||||||
|
|
@ -91,10 +91,10 @@ graph_driver:
|
||||||
dw vga_init ; init de la carte graphique
|
dw vga_init ; init de la carte graphique
|
||||||
dw vga_putpixel ; dessin d'un pixel
|
dw vga_putpixel ; dessin d'un pixel
|
||||||
dw vga_none ; lecture d'un pixel
|
dw vga_none ; lecture d'un pixel
|
||||||
dw vga_none ; gotoxy
|
dw vga_set_charpos ; gotoxy
|
||||||
dw vga_none ; mode texte
|
dw vga_set_writemode ; mode texte
|
||||||
dw vga_none ; dessin d'un caractère
|
dw vga_putc ; dessin d'un caractère
|
||||||
dw vga_none ; dessin d'une chaine de caractère
|
dw vga_write ; 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'une ligne (Bresenham) avec décision horizontale/verticale
|
||||||
dw vga_none ; dessin d'un rectangle
|
dw vga_none ; dessin d'un rectangle
|
||||||
dw vga_none ; dessin d'un rectangle plein
|
dw vga_none ; dessin d'un rectangle plein
|
||||||
|
|
@ -102,7 +102,6 @@ graph_driver:
|
||||||
dw vga_mouse_hide ; cache la souris
|
dw vga_mouse_hide ; cache la souris
|
||||||
dw vga_mouse_show ; montre la souris
|
dw vga_mouse_show ; montre la souris
|
||||||
dw vga_mouse_cursor_move ; déplacement du curseur
|
dw vga_mouse_cursor_move ; déplacement du curseur
|
||||||
dw vga_cursor_draw
|
|
||||||
|
|
||||||
; ------------------------------------------------------------
|
; ------------------------------------------------------------
|
||||||
; dummy function
|
; dummy function
|
||||||
|
|
@ -116,7 +115,7 @@ vga_none:
|
||||||
; ------------------------------------------------------------
|
; ------------------------------------------------------------
|
||||||
; initialise le mode graphique (via l'int 10h)
|
; initialise le mode graphique (via l'int 10h)
|
||||||
;
|
;
|
||||||
; ce mode est entrelacé, un bit/pixel, 8 pixels par octet
|
; ce mode est divisé en bitplane; 4 bits/pixel, 8 pixels par octet
|
||||||
; ------------------------------------------------------------
|
; ------------------------------------------------------------
|
||||||
vga_init:
|
vga_init:
|
||||||
; init graphics mode
|
; init graphics mode
|
||||||
|
|
@ -132,7 +131,6 @@ vga_init:
|
||||||
PATTERN_PTR PATTERN_GRAY_LIGHT
|
PATTERN_PTR PATTERN_GRAY_LIGHT
|
||||||
mov bl, 15
|
mov bl, 15
|
||||||
call vga_background
|
call vga_background
|
||||||
ISADBG ISA_GREEN, 0x88
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; ------------------------------------------------------------
|
; ------------------------------------------------------------
|
||||||
|
|
@ -190,7 +188,7 @@ vga_background:
|
||||||
|
|
||||||
; Boucle principale (480 lignes)
|
; Boucle principale (480 lignes)
|
||||||
xor edx, edx ; EDX servira d'index pour le pattern (0-7)
|
xor edx, edx ; EDX servira d'index pour le pattern (0-7)
|
||||||
mov ecx, 480
|
mov ecx, GFX_HEIGHT
|
||||||
|
|
||||||
.line_loop:
|
.line_loop:
|
||||||
mov al, [esi + edx] ; Charger l'octet du pattern pour la ligne actuelle
|
mov al, [esi + edx] ; Charger l'octet du pattern pour la ligne actuelle
|
||||||
|
|
@ -221,6 +219,259 @@ vga_background:
|
||||||
; popad
|
; popad
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
; ---------------------------------------------------------------------------
|
||||||
|
; gfx_set_writemode (mode)
|
||||||
|
; Défini le mode d'écriture :
|
||||||
|
;
|
||||||
|
; bit : descr
|
||||||
|
; 0 : text color : 0=black, 1=white
|
||||||
|
; 1 : transparent : 1=apply background attribut
|
||||||
|
;
|
||||||
|
; si le mode n'est pas transparent, la couleur de fond
|
||||||
|
; est l'inverse de la couleur du texte
|
||||||
|
; ---------------------------------------------------------------------------
|
||||||
|
; --- Définition des arguments ---
|
||||||
|
%define .mode word [bp+4]
|
||||||
|
vga_set_writemode:
|
||||||
|
push bp
|
||||||
|
mov bp, sp
|
||||||
|
|
||||||
|
push fs
|
||||||
|
push ax
|
||||||
|
mov ax, BDA_CUSTOM_SEG
|
||||||
|
mov fs,ax
|
||||||
|
|
||||||
|
mov ax, .mode
|
||||||
|
|
||||||
|
mov byte [fs:PTR_GFX + gfx.cur_mode], al
|
||||||
|
|
||||||
|
pop ax
|
||||||
|
pop fs
|
||||||
|
leave
|
||||||
|
ret
|
||||||
|
%undef .mode
|
||||||
|
|
||||||
|
; ---------------------------------------------------------------------------
|
||||||
|
; gfx_set_charpos (x,y)
|
||||||
|
; In : CX = x (pixels), DX = y (pixels)
|
||||||
|
; Out: variables DS:GFX_CUR_*
|
||||||
|
; Notes:
|
||||||
|
; - calcule l'offset VRAM de la scanline y: base = (y&1?2000:0) + (y>>1)*80 + (x>>3)
|
||||||
|
; - stocke aussi shift = x&7
|
||||||
|
; ---------------------------------------------------------------------------
|
||||||
|
; --- Définition des arguments ---
|
||||||
|
%define .x word [bp+4]
|
||||||
|
%define .y word [bp+6]
|
||||||
|
vga_set_charpos:
|
||||||
|
push bp
|
||||||
|
mov bp, sp
|
||||||
|
|
||||||
|
pusha
|
||||||
|
push fs
|
||||||
|
|
||||||
|
mov ax,BDA_CUSTOM_SEG
|
||||||
|
mov fs,ax
|
||||||
|
|
||||||
|
; store x,y en pixel
|
||||||
|
mov cx, .x
|
||||||
|
mov dx, .y
|
||||||
|
|
||||||
|
mov [fs:PTR_GFX + gfx.cur_x], cx
|
||||||
|
mov [fs:PTR_GFX + gfx.cur_y], dx
|
||||||
|
|
||||||
|
mov ax, cx
|
||||||
|
and ax, 0x07
|
||||||
|
mov [fs:PTR_GFX + gfx.cur_shift], al
|
||||||
|
|
||||||
|
call vga_calc_addr
|
||||||
|
|
||||||
|
mov [fs:PTR_GFX + gfx.cur_offset], bx
|
||||||
|
pop fs
|
||||||
|
|
||||||
|
popa
|
||||||
|
leave
|
||||||
|
ret
|
||||||
|
; clean defs
|
||||||
|
%undef .x
|
||||||
|
%undef .y
|
||||||
|
|
||||||
|
; ---------------------------------------------------------------------------
|
||||||
|
; get_glyph_offset
|
||||||
|
; In : AL = char (ASCII)
|
||||||
|
; Out: CS:SI -> 8 bytes
|
||||||
|
; ---------------------------------------------------------------------------
|
||||||
|
get_glyph_offset:
|
||||||
|
cmp al, 0x20
|
||||||
|
jb .qmark ; al < 20h (' '
|
||||||
|
cmp al, 0x7E
|
||||||
|
ja .qmark ; al > 7Eh ('~')
|
||||||
|
sub al, 0x20
|
||||||
|
jmp .ok
|
||||||
|
|
||||||
|
.qmark:
|
||||||
|
mov al, '?'
|
||||||
|
sub al, 0x20
|
||||||
|
|
||||||
|
.ok:
|
||||||
|
xor ah, ah
|
||||||
|
mov si, ax
|
||||||
|
shl si, 3
|
||||||
|
add si, font8x8
|
||||||
|
ret
|
||||||
|
|
||||||
|
; ---------------------------------------------------------------------------
|
||||||
|
; cga_putc_unalign (car)
|
||||||
|
; - x non aligné (x&7 != 0)
|
||||||
|
; - écrit sur 2 bytes (di et di+1) dans chaque banque
|
||||||
|
; ---------------------------------------------------------------------------
|
||||||
|
; convert al -> AX aligned with "cl"
|
||||||
|
%macro ALIGN_BYTE 0
|
||||||
|
mov ah,al
|
||||||
|
xor al,al
|
||||||
|
shr ax,cl
|
||||||
|
xchg ah,al
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
; --- Définition des arguments ---
|
||||||
|
%define .car word [bp+4]
|
||||||
|
vga_putc:
|
||||||
|
push bp
|
||||||
|
mov bp, sp
|
||||||
|
; --- Définition des variables locales ---
|
||||||
|
%define .cpt word [bp-2]
|
||||||
|
sub sp, 2 ; 1 word variable locale
|
||||||
|
|
||||||
|
pusha
|
||||||
|
push fs
|
||||||
|
push es
|
||||||
|
|
||||||
|
call vga_mouse_hide ; Protection souris
|
||||||
|
|
||||||
|
mov bx, VIDEO_SEG
|
||||||
|
mov es, bx
|
||||||
|
mov bx, BDA_CUSTOM_SEG
|
||||||
|
mov fs, bx
|
||||||
|
|
||||||
|
mov ax, .car
|
||||||
|
call get_glyph_offset
|
||||||
|
|
||||||
|
; Base offset VRAM pour la scanline Y
|
||||||
|
mov di, [fs:PTR_GFX + gfx.cur_offset]
|
||||||
|
mov ch, [fs:PTR_GFX + gfx.cur_mode]
|
||||||
|
mov cl, [fs:PTR_GFX + gfx.cur_shift]
|
||||||
|
mov bx, GFX_OFFSET
|
||||||
|
|
||||||
|
mov .cpt, 4
|
||||||
|
|
||||||
|
.row_loop:
|
||||||
|
; gestion du fond de texte
|
||||||
|
test ch, 00000010b ; transparent background ?
|
||||||
|
jz .skip_attribut ; oui
|
||||||
|
|
||||||
|
test ch, 00000001b ; background blanc ?
|
||||||
|
je .bkg_black
|
||||||
|
|
||||||
|
; background = white
|
||||||
|
mov ax, 0xFF00
|
||||||
|
shr ax, cl
|
||||||
|
xchg al, ah
|
||||||
|
or [es:di], ax
|
||||||
|
or [es:di+bx], ax
|
||||||
|
jmp .skip_attribut
|
||||||
|
|
||||||
|
.bkg_black: ; OK
|
||||||
|
; background = black
|
||||||
|
mov ax, 0xFF00
|
||||||
|
shr ax, cl
|
||||||
|
xchg al, ah
|
||||||
|
not ax
|
||||||
|
and [es:di], ax
|
||||||
|
and [es:di+bx], ax
|
||||||
|
|
||||||
|
.skip_attribut:
|
||||||
|
; ligne "paire" du gylphe
|
||||||
|
xor ax, ax
|
||||||
|
mov al, [cs:si]
|
||||||
|
inc si
|
||||||
|
ALIGN_BYTE
|
||||||
|
mov dx, ax
|
||||||
|
|
||||||
|
; ligne "impaire" du gylphe
|
||||||
|
mov al, [cs:si]
|
||||||
|
inc si
|
||||||
|
ALIGN_BYTE
|
||||||
|
xchg ax, dx
|
||||||
|
|
||||||
|
test ch,00000001b
|
||||||
|
jz .black_text
|
||||||
|
|
||||||
|
; white text
|
||||||
|
not ax
|
||||||
|
not dx
|
||||||
|
and [es:di], ax
|
||||||
|
and [es:di+bx], dx
|
||||||
|
|
||||||
|
jmp .next
|
||||||
|
|
||||||
|
.black_text:
|
||||||
|
or [es:di], ax
|
||||||
|
or [es:di+bx], dx
|
||||||
|
|
||||||
|
.next:
|
||||||
|
; add di,CGA_STRIDE
|
||||||
|
|
||||||
|
dec .cpt
|
||||||
|
jnz .row_loop
|
||||||
|
|
||||||
|
; Avancer curseur d'un caractère (8 pixels)
|
||||||
|
inc word [fs:PTR_GFX + gfx.cur_offset]
|
||||||
|
add word [fs:PTR_GFX + gfx.cur_x], 8
|
||||||
|
|
||||||
|
call vga_mouse_show ; Restauration souris
|
||||||
|
|
||||||
|
pop es
|
||||||
|
pop fs
|
||||||
|
popa
|
||||||
|
leave
|
||||||
|
ret
|
||||||
|
%undef .car
|
||||||
|
%undef .cpt
|
||||||
|
|
||||||
|
;
|
||||||
|
; write string from [DS:SI] to screen
|
||||||
|
;
|
||||||
|
; --- Définition des arguments ---
|
||||||
|
%define .txt_seg word [bp+4]
|
||||||
|
%define .txt_ofs word [bp+6]
|
||||||
|
vga_write:
|
||||||
|
push bp
|
||||||
|
mov bp, sp
|
||||||
|
push ax
|
||||||
|
push ds
|
||||||
|
|
||||||
|
mov ax, .txt_seg
|
||||||
|
mov ds, ax
|
||||||
|
mov si, .txt_ofs
|
||||||
|
cld
|
||||||
|
|
||||||
|
.loops:
|
||||||
|
lodsb
|
||||||
|
cmp al,0
|
||||||
|
je .done
|
||||||
|
push ax
|
||||||
|
call vga_putc
|
||||||
|
jmp .loops
|
||||||
|
|
||||||
|
.done:
|
||||||
|
pop ds
|
||||||
|
pop ax
|
||||||
|
leave
|
||||||
|
ret
|
||||||
|
%undef .txt_seg
|
||||||
|
%undef .txt_ofs
|
||||||
|
|
||||||
|
|
||||||
; Entrée: AX = X (0-639), BX = Y (0-479), CL = Couleur (0-15)
|
; Entrée: AX = X (0-639), BX = Y (0-479), CL = Couleur (0-15)
|
||||||
%define .x word [bp+4]
|
%define .x word [bp+4]
|
||||||
%define .y word [bp+6]
|
%define .y word [bp+6]
|
||||||
|
|
@ -302,10 +553,10 @@ vga_mouse_hide:
|
||||||
mov ds, ax
|
mov ds, ax
|
||||||
|
|
||||||
; Décrémenter le compteur
|
; Décrémenter le compteur
|
||||||
dec byte [BDA_MOUSE + mouse.cur_counter]
|
dec byte [PTR_MOUSE + mouse.cur_counter]
|
||||||
|
|
||||||
; Vérifier si on vient juste de passer en mode caché (c-à-d on est à -1)
|
; Vérifier si on vient juste de passer en mode caché (c-à-d on est à -1)
|
||||||
cmp byte [BDA_MOUSE + mouse.cur_counter], -1
|
cmp byte [PTR_MOUSE + mouse.cur_counter], -1
|
||||||
jne .skip_restore ; Si on est à -2, -3... elle est déjà cachée
|
jne .skip_restore ; Si on est à -2, -3... elle est déjà cachée
|
||||||
|
|
||||||
call vga_cursor_restorebg
|
call vga_cursor_restorebg
|
||||||
|
|
@ -330,10 +581,10 @@ vga_mouse_show:
|
||||||
mov ds, ax
|
mov ds, ax
|
||||||
|
|
||||||
; Incrémenter le compteur
|
; Incrémenter le compteur
|
||||||
inc byte [BDA_MOUSE + mouse.cur_counter]
|
inc byte [PTR_MOUSE + mouse.cur_counter]
|
||||||
|
|
||||||
; Vérifier si on est revenu à 0 (Visible)
|
; Vérifier si on est revenu à 0 (Visible)
|
||||||
cmp byte [BDA_MOUSE + mouse.cur_counter], 0
|
cmp byte [PTR_MOUSE + mouse.cur_counter], 0
|
||||||
jne .skip_draw ; Si on est encore à -1, -2... on reste caché
|
jne .skip_draw ; Si on est encore à -1, -2... on reste caché
|
||||||
|
|
||||||
; C'est la transition Caché -> Visible : On affiche le curseur
|
; C'est la transition Caché -> Visible : On affiche le curseur
|
||||||
|
|
@ -361,18 +612,18 @@ vga_mouse_cursor_move:
|
||||||
mov ax, BDA_CUSTOM_SEG
|
mov ax, BDA_CUSTOM_SEG
|
||||||
mov ds, ax
|
mov ds, ax
|
||||||
|
|
||||||
cmp byte [BDA_MOUSE + mouse.cur_counter], 0
|
cmp byte [PTR_MOUSE + mouse.cur_counter], 0
|
||||||
jl .done ; Si < 0, on ne dessine rien !
|
jl .done ; Si < 0, on ne dessine rien !
|
||||||
|
|
||||||
cmp byte [BDA_MOUSE + mouse.cur_drawing],0
|
cmp byte [PTR_MOUSE + mouse.cur_drawing],0
|
||||||
jne .done
|
jne .done
|
||||||
|
|
||||||
mov byte [BDA_MOUSE + mouse.cur_drawing],1
|
mov byte [PTR_MOUSE + mouse.cur_drawing],1
|
||||||
|
|
||||||
call vga_cursor_restorebg
|
call vga_cursor_restorebg
|
||||||
call vga_cursor_savebg
|
call vga_cursor_savebg
|
||||||
call vga_cursor_draw
|
call vga_cursor_draw
|
||||||
mov byte [BDA_MOUSE + mouse.cur_drawing],0
|
mov byte [PTR_MOUSE + mouse.cur_drawing],0
|
||||||
.done:
|
.done:
|
||||||
pop es
|
pop es
|
||||||
pop ds
|
pop ds
|
||||||
|
|
@ -382,7 +633,7 @@ vga_mouse_cursor_move:
|
||||||
; Buffer requis : 192 octets (16 lignes * 3 octets * 4 plans)
|
; Buffer requis : 192 octets (16 lignes * 3 octets * 4 plans)
|
||||||
; ATTENTION : Vérifiez que mouse.bkg_buffer dans bda.asm est assez grand !
|
; ATTENTION : Vérifiez que mouse.bkg_buffer dans bda.asm est assez grand !
|
||||||
vga_cursor_savebg:
|
vga_cursor_savebg:
|
||||||
cmp byte [BDA_MOUSE + mouse.bkg_saved], 0
|
cmp byte [PTR_MOUSE + mouse.bkg_saved], 0
|
||||||
jne .done
|
jne .done
|
||||||
|
|
||||||
push es
|
push es
|
||||||
|
|
@ -390,12 +641,12 @@ vga_cursor_savebg:
|
||||||
mov es, ax
|
mov es, ax
|
||||||
|
|
||||||
; Calculer l'adresse de départ (y * 80 + x / 8)
|
; Calculer l'adresse de départ (y * 80 + x / 8)
|
||||||
mov cx, [BDA_MOUSE + mouse.x]
|
mov cx, [PTR_MOUSE + mouse.x]
|
||||||
mov dx, [BDA_MOUSE + mouse.y]
|
mov dx, [PTR_MOUSE + mouse.y]
|
||||||
call vga_calc_addr ; Doit retourner DI = offset VRAM
|
call vga_calc_addr ; Doit retourner DI = offset VRAM
|
||||||
mov [BDA_MOUSE + mouse.cur_addr_start], di
|
mov [PTR_MOUSE + mouse.cur_addr_start], di
|
||||||
|
|
||||||
lea si, [BDA_MOUSE + mouse.bkg_buffer]
|
lea si, [PTR_MOUSE + mouse.bkg_buffer]
|
||||||
|
|
||||||
mov dx, EGAVGA_CONTROLLER ; Graphics Controller Port
|
mov dx, EGAVGA_CONTROLLER ; Graphics Controller Port
|
||||||
mov al, 0x04 ; Read Plane Select Register
|
mov al, 0x04 ; Read Plane Select Register
|
||||||
|
|
@ -429,20 +680,20 @@ vga_cursor_savebg:
|
||||||
out dx, ax
|
out dx, ax
|
||||||
|
|
||||||
pop es
|
pop es
|
||||||
mov byte [BDA_MOUSE + mouse.bkg_saved], 1
|
mov byte [PTR_MOUSE + mouse.bkg_saved], 1
|
||||||
.done:
|
.done:
|
||||||
ret
|
ret
|
||||||
|
|
||||||
vga_cursor_restorebg:
|
vga_cursor_restorebg:
|
||||||
cmp byte [BDA_MOUSE + mouse.bkg_saved], 0
|
cmp byte [PTR_MOUSE + mouse.bkg_saved], 0
|
||||||
je .done
|
je .done
|
||||||
|
|
||||||
push es
|
push es
|
||||||
mov ax, VIDEO_SEG
|
mov ax, VIDEO_SEG
|
||||||
mov es, ax
|
mov es, ax
|
||||||
|
|
||||||
mov di, [BDA_MOUSE + mouse.cur_addr_start]
|
mov di, [PTR_MOUSE + mouse.cur_addr_start]
|
||||||
lea si, [BDA_MOUSE + mouse.bkg_buffer]
|
lea si, [PTR_MOUSE + mouse.bkg_buffer]
|
||||||
|
|
||||||
; Sécurité : S'assurer que ES pointe bien vers la vidéo pour le restore
|
; Sécurité : S'assurer que ES pointe bien vers la vidéo pour le restore
|
||||||
mov ax, VIDEO_SEG
|
mov ax, VIDEO_SEG
|
||||||
|
|
@ -490,7 +741,7 @@ vga_cursor_restorebg:
|
||||||
out dx, ax
|
out dx, ax
|
||||||
|
|
||||||
pop es
|
pop es
|
||||||
mov byte [BDA_MOUSE + mouse.bkg_saved], 0
|
mov byte [PTR_MOUSE + mouse.bkg_saved], 0
|
||||||
.done:
|
.done:
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
@ -498,13 +749,16 @@ vga_cursor_restorebg:
|
||||||
; vga_cursor_draw
|
; vga_cursor_draw
|
||||||
; Détruit: registres sauvegardés/restaurés (PUSHA/POPA)
|
; Détruit: registres sauvegardés/restaurés (PUSHA/POPA)
|
||||||
; ============================================================
|
; ============================================================
|
||||||
|
%define BYTES_SHIFT 3
|
||||||
|
|
||||||
vga_cursor_draw:
|
vga_cursor_draw:
|
||||||
push bp
|
push bp
|
||||||
mov bp, sp
|
mov bp, sp
|
||||||
sub sp, 4 ; [bp-2]: height, [bp-4]: x_bit_offset
|
; local variables
|
||||||
; local variables
|
%define .height word [bp-2]
|
||||||
%define .height word [bp-2]
|
%define .bit_ofs word [bp-4]
|
||||||
%define .bit_ofs word [bp-4]
|
%define .mask dword [bp-6]
|
||||||
|
sub sp, 8 ; [bp-2]: height, [bp-4]: x_bit_offset
|
||||||
|
|
||||||
pushad
|
pushad
|
||||||
push ds
|
push ds
|
||||||
|
|
@ -519,7 +773,7 @@ vga_cursor_draw:
|
||||||
mov es, ax
|
mov es, ax
|
||||||
|
|
||||||
; --- CLIPPING VERTICAL ---
|
; --- CLIPPING VERTICAL ---
|
||||||
mov dx, [BDA_MOUSE + mouse.y]
|
mov dx, [PTR_MOUSE + mouse.y]
|
||||||
mov bx, GFX_HEIGHT
|
mov bx, GFX_HEIGHT
|
||||||
cmp dx, bx
|
cmp dx, bx
|
||||||
jae .exit_total
|
jae .exit_total
|
||||||
|
|
@ -533,8 +787,41 @@ vga_cursor_draw:
|
||||||
.y_ok:
|
.y_ok:
|
||||||
mov .height, ax
|
mov .height, ax
|
||||||
|
|
||||||
|
; --- CLIPPING HORIZONTAL ---
|
||||||
|
; On calcule si les 4 octets vont dépasser la ligne (80 octets)
|
||||||
|
; X est en bits (0-639). X >> 3 donne l'octet de départ (0-79).
|
||||||
|
; Si StartByte >= 77, on déborde.
|
||||||
|
|
||||||
|
mov cx, [PTR_MOUSE + mouse.x]
|
||||||
|
shr cx, 3 ; CX = Byte Offset (0-79)
|
||||||
|
xor eax, eax ; ESI = Masque de protection (0 = tout dessiner)
|
||||||
|
|
||||||
|
cmp cx, 76 ; 76 est le dernier offset sûr (76,77,78,79)
|
||||||
|
jbe .mask_ready ; Si <= 76, pas de débordement
|
||||||
|
|
||||||
|
; Calcul du débordement
|
||||||
|
; Si CX=77 (Déborde 1 byte) -> Masque 0x000000FF (LSB car bswap)
|
||||||
|
; Si CX=78 (Déborde 2 bytes)-> Masque 0x0000FFFF
|
||||||
|
; Si CX=79 (Déborde 3 bytes)-> Masque 0x00FFFFFF
|
||||||
|
cmp cx, 77
|
||||||
|
jne .check_78
|
||||||
|
mov eax, 0x000000FF
|
||||||
|
jmp .mask_ready
|
||||||
|
|
||||||
|
.check_78:
|
||||||
|
cmp cx, 78
|
||||||
|
jne .check_79
|
||||||
|
mov eax, 0x0000FFFF
|
||||||
|
jmp .mask_ready
|
||||||
|
|
||||||
|
.check_79:
|
||||||
|
mov eax, 0x00FFFFFF ; Cas extrême (bord droit)
|
||||||
|
|
||||||
|
.mask_ready:
|
||||||
|
mov .mask, eax
|
||||||
|
|
||||||
; --- Calcul Adresse et Shift ---
|
; --- Calcul Adresse et Shift ---
|
||||||
mov ax, [BDA_MOUSE + mouse.x]
|
mov ax, [PTR_MOUSE + mouse.x]
|
||||||
mov cx, ax
|
mov cx, ax
|
||||||
and ax, 7 ; Reste (0-7) = décalage de bit
|
and ax, 7 ; Reste (0-7) = décalage de bit
|
||||||
mov .bit_ofs, ax
|
mov .bit_ofs, ax
|
||||||
|
|
@ -545,7 +832,7 @@ vga_cursor_draw:
|
||||||
mov ax, 0x0F02 ; Map Mask = All planes
|
mov ax, 0x0F02 ; Map Mask = All planes
|
||||||
out dx, ax
|
out dx, ax
|
||||||
|
|
||||||
mov dx, 0x3CE ; Graphics Controller
|
mov dx, EGAVGA_CONTROLLER
|
||||||
mov ax, 0x0005 ; Mode 0
|
mov ax, 0x0005 ; Mode 0
|
||||||
out dx, ax
|
out dx, ax
|
||||||
mov ax, 0x0001 ; Enable Set/Reset = 0 (CPU Data)
|
mov ax, 0x0001 ; Enable Set/Reset = 0 (CPU Data)
|
||||||
|
|
@ -554,53 +841,65 @@ vga_cursor_draw:
|
||||||
out dx, ax
|
out dx, ax
|
||||||
|
|
||||||
; Source du Sprite -> (GS:SI)
|
; Source du Sprite -> (GS:SI)
|
||||||
mov ax, [BDA_MOUSE + mouse.cur_seg]
|
mov ax, [PTR_MOUSE + mouse.cur_seg]
|
||||||
mov gs, ax
|
mov gs, ax
|
||||||
mov si, [BDA_MOUSE + mouse.cur_ofs]
|
mov si, [PTR_MOUSE + mouse.cur_ofs]
|
||||||
|
|
||||||
.row_loop:
|
.row_loop:
|
||||||
; --- PREPARE MASKS ---
|
mov dx, EGAVGA_CONTROLLER
|
||||||
; 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)
|
mov ax, 0x0803 ; Data Rotate/Function Select: AND (bits 3-4 = 01b)
|
||||||
out dx, ax
|
out dx, ax
|
||||||
|
|
||||||
; Application sur 3 octets (pour couvrir les 16 pixels + le shift)
|
; --- PASSE 1 : MASQUE AND (Effacement du fond) ---
|
||||||
%rep 3
|
mov ax, [gs:si] ; Charger 16 pixels (0=curseur, 1=fond)
|
||||||
mov al, [es:di] ; CHARGE LES LATCHES (Indispensable)
|
shl eax, 16 ; décalage de AX vers le poid for: XXXX0000
|
||||||
mov eax, ebx
|
mov ax, 0xFFFF
|
||||||
shr eax, 16 ; Récupère la partie haute (si 32-bit shift utilisé)
|
mov cx, .bit_ofs
|
||||||
stosb ; Écrit AL et DI++ (Applique le AND sur les 4 plans)
|
ror eax, cl ; Décaler : 1 là où on veut effacer (0 ailleurs)
|
||||||
%endrep
|
or eax, .mask ; Appliquer le masque de clipping à droite
|
||||||
sub di, 3 ; Revient au début de la ligne pour le XOR
|
|
||||||
|
|
||||||
|
mov ebx, eax ; EBX contient le masque AND sur 3 octets
|
||||||
|
mov cx, BYTES_SHIFT ; Appliquer sur 3 octets (24 pixels potentiels)
|
||||||
|
.block_AND:
|
||||||
|
mov al, [es:di] ; Charger les latches VGA
|
||||||
|
rol ebx, 8 ; Extraire l'octet suivant (poids fort d'abord)
|
||||||
|
mov al, bl
|
||||||
|
stosb ; Écrire et DI++
|
||||||
|
loop .block_AND
|
||||||
|
sub di, BYTES_SHIFT ; Revenir 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)
|
mov ax, 0x1803 ; Data Rotate/Function Select: XOR (bits 3-4 = 11b)
|
||||||
out dx, ax
|
out dx, ax
|
||||||
|
|
||||||
; Récupération du masque XOR (la forme blanche/noire du curseur)
|
; --- PASSE 2 : MASQUE XOR (Dessin du curseur) ---
|
||||||
mov ax, [gs:si+32]
|
xor eax, eax
|
||||||
; ... (Appliquer le même décalage et stosb que pour le AND) ...
|
mov ax, [gs:si+32] ; Charger 16 pixels (1=blanc, 0=transparent)
|
||||||
|
movzx eax, ax ; S'assurer que le reste est à 0
|
||||||
|
shl eax, 16 ; Aligner
|
||||||
|
mov cx, .bit_ofs
|
||||||
|
shr eax, cl ; Décaler (les bits de padding restent à 0)
|
||||||
|
mov ebx, .mask ; Appliquer le masque de clipping à droite
|
||||||
|
not ebx
|
||||||
|
and eax, ebx ; Appliquer le masque de clipping à droite
|
||||||
|
|
||||||
|
mov ebx, eax ; EBX contient le masque XOR sur 3 octets
|
||||||
|
mov cx, BYTES_SHIFT
|
||||||
|
.block_XOR:
|
||||||
|
mov al, [es:di] ; Charger les latches
|
||||||
|
rol ebx, 8
|
||||||
|
mov al, bl
|
||||||
|
stosb
|
||||||
|
loop .block_XOR
|
||||||
|
|
||||||
; --- NEXT ROW ---
|
; --- NEXT ROW ---
|
||||||
add di, 80 - 3 ; Ligne suivante (80 octets par ligne)
|
add di, 80 - BYTES_SHIFT ; Ligne suivante en VRAM (80 octets/ligne)
|
||||||
add si, 2
|
add si, 2
|
||||||
dec word .height
|
dec word .height
|
||||||
jnz .row_loop
|
jnz .row_loop
|
||||||
|
|
||||||
; --- RESTORE VGA ---
|
; --- RESTORE VGA ---
|
||||||
mov dx, 0x3CE
|
mov dx, EGAVGA_CONTROLLER
|
||||||
mov ax, 0x0003 ; Function = Replace
|
mov ax, 0x0003 ; Function = Replace
|
||||||
out dx, ax
|
out dx, ax
|
||||||
mov ax, 0xFF08 ; Bit Mask = 0xFF
|
mov ax, 0xFF08 ; Bit Mask = 0xFF
|
||||||
|
|
@ -614,6 +913,8 @@ vga_cursor_draw:
|
||||||
pop ds
|
pop ds
|
||||||
popad
|
popad
|
||||||
leave
|
leave
|
||||||
|
%undef .height
|
||||||
|
%undef .bit_ofs
|
||||||
|
%undef .mask
|
||||||
ret
|
ret
|
||||||
%undef .height
|
|
||||||
%undef .mask
|
|
||||||
|
|
|
||||||
|
|
@ -47,28 +47,28 @@ mouse_reset:
|
||||||
mov fs,ax
|
mov fs,ax
|
||||||
|
|
||||||
; effacer les variables du drivers
|
; effacer les variables du drivers
|
||||||
mov byte [fs:BDA_MOUSE + mouse.idx],0
|
mov byte [fs:PTR_MOUSE + mouse.idx],0
|
||||||
mov dword [fs:BDA_MOUSE + mouse.buffer],0
|
mov dword [fs:PTR_MOUSE + mouse.buffer],0
|
||||||
mov byte [fs:BDA_MOUSE + mouse.packetlen],3 ; 3 bytes par défaut
|
mov byte [fs:PTR_MOUSE + mouse.packetlen],3 ; 3 bytes par défaut
|
||||||
mov byte [fs:BDA_MOUSE + mouse.status],0
|
mov byte [fs:PTR_MOUSE + mouse.status],0
|
||||||
|
|
||||||
mov word [fs:BDA_MOUSE + mouse.x],GFX_WIDTH / 2
|
mov word [fs:PTR_MOUSE + mouse.x],GFX_WIDTH / 2
|
||||||
mov word [fs:BDA_MOUSE + mouse.y],GFX_HEIGHT / 2
|
mov word [fs:PTR_MOUSE + mouse.y],GFX_HEIGHT / 2
|
||||||
|
|
||||||
mov word [fs:BDA_MOUSE + mouse.cur_x], 0
|
mov word [fs:PTR_MOUSE + mouse.cur_x], 0
|
||||||
mov word [fs:BDA_MOUSE + mouse.cur_y], 0
|
mov word [fs:PTR_MOUSE + mouse.cur_y], 0
|
||||||
|
|
||||||
|
|
||||||
mov byte [BDA_MOUSE + mouse.cur_counter], -1 ; Force l'état caché au départ
|
mov byte [fs:PTR_MOUSE + mouse.cur_counter], -1 ; Force l'état caché au départ
|
||||||
mov byte [BDA_MOUSE + mouse.cur_drawing], 0 ; Reset du verrou de dessin
|
mov byte [fs:PTR_MOUSE + mouse.cur_drawing], 0 ; Reset du verrou de dessin
|
||||||
mov byte [BDA_MOUSE + mouse.bkg_saved],0 ; flag image saved
|
mov byte [fs:PTR_MOUSE + mouse.bkg_saved],0 ; flag image saved
|
||||||
|
|
||||||
mov ax, cs
|
mov ax, cs
|
||||||
mov word [fs:BDA_MOUSE + mouse.cur_seg], ax
|
mov word [fs:PTR_MOUSE + mouse.cur_seg], ax
|
||||||
mov word [fs:BDA_MOUSE + mouse.cur_ofs], mouse_arrow
|
mov word [fs:PTR_MOUSE + mouse.cur_ofs], mouse_arrow
|
||||||
|
|
||||||
; experiemntal
|
; experiemntal
|
||||||
mov byte [fs:BDA_MOUSE + mouse.wheel],0
|
mov byte [fs:PTR_MOUSE + mouse.wheel],0
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; ------------------------------------------------------------
|
; ------------------------------------------------------------
|
||||||
|
|
@ -157,7 +157,7 @@ mouse_detect_packet_len:
|
||||||
mov ax, BDA_CUSTOM_SEG
|
mov ax, BDA_CUSTOM_SEG
|
||||||
mov fs,ax
|
mov fs,ax
|
||||||
|
|
||||||
mov byte [fs:BDA_MOUSE + mouse.packetlen], 3
|
mov byte [fs:PTR_MOUSE + mouse.packetlen], 3
|
||||||
|
|
||||||
; SET_RATE + 200
|
; SET_RATE + 200
|
||||||
mov bl, MOUSE_SET_RATE
|
mov bl, MOUSE_SET_RATE
|
||||||
|
|
@ -188,7 +188,7 @@ mouse_detect_packet_len:
|
||||||
je .is4
|
je .is4
|
||||||
ret
|
ret
|
||||||
.is4:
|
.is4:
|
||||||
mov byte [fs:BDA_MOUSE + mouse.packetlen], 4
|
mov byte [fs:PTR_MOUSE + mouse.packetlen], 4
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; ------------------------------------------------------------
|
; ------------------------------------------------------------
|
||||||
|
|
@ -280,7 +280,7 @@ mouse_sendcmd:
|
||||||
; ------------------------------------------------------------
|
; ------------------------------------------------------------
|
||||||
isr_mouse_handler:
|
isr_mouse_handler:
|
||||||
; sauvegarder tout les registres
|
; sauvegarder tout les registres
|
||||||
pusha
|
pushad
|
||||||
push ds
|
push ds
|
||||||
|
|
||||||
; use BDA segment
|
; use BDA segment
|
||||||
|
|
@ -290,7 +290,7 @@ isr_mouse_handler:
|
||||||
; 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
|
||||||
in al, i8042_PS2_DATA ; lire octet souris
|
in al, i8042_PS2_DATA ; lire octet souris
|
||||||
|
|
||||||
movzx bx, byte [BDA_MOUSE + mouse.idx]
|
movzx bx, byte [PTR_MOUSE + mouse.idx]
|
||||||
cmp bl,0
|
cmp bl,0
|
||||||
jne .read_packet
|
jne .read_packet
|
||||||
|
|
||||||
|
|
@ -298,88 +298,88 @@ isr_mouse_handler:
|
||||||
test al, 00001000b ; bit 3 = 1
|
test al, 00001000b ; bit 3 = 1
|
||||||
jz .done_eoi ; allignement erroné
|
jz .done_eoi ; allignement erroné
|
||||||
|
|
||||||
.read_packet:
|
.read_packet:
|
||||||
mov byte [BDA_MOUSE + mouse.buffer + bx], al
|
mov byte [PTR_MOUSE + mouse.buffer + bx], al
|
||||||
inc byte [BDA_MOUSE + mouse.idx]
|
inc byte [PTR_MOUSE + mouse.idx]
|
||||||
|
|
||||||
; vérifier si le packet est complet
|
; vérifier si le packet est complet
|
||||||
mov al, [BDA_MOUSE + mouse.packetlen]
|
mov al, byte [PTR_MOUSE + mouse.packetlen]
|
||||||
cmp byte [BDA_MOUSE + mouse.idx], al
|
cmp byte [PTR_MOUSE + mouse.idx], al
|
||||||
jb .done_eoi
|
jb .done_eoi
|
||||||
|
|
||||||
; packet complet, on decode les données (ou on jette si c'est incorrect)
|
; packet complet, on decode les données (ou on jette si c'est incorrect)
|
||||||
mov byte [BDA_MOUSE + mouse.idx], 0 ; reset de l'index de lecture
|
mov byte [PTR_MOUSE + mouse.idx], 0 ; reset de l'index de lecture
|
||||||
|
|
||||||
; debut du décodage des données
|
; debut du décodage des données
|
||||||
mov bl, [BDA_MOUSE + mouse.buffer] ; status
|
mov bl, byte [PTR_MOUSE + mouse.buffer] ; status
|
||||||
|
|
||||||
; --- BOUTONS ---
|
; --- BOUTONS ---
|
||||||
mov al,bl ; extraction des boutons
|
mov al, bl ; extraction des boutons
|
||||||
and al, 00000111b ; Bits 0, 1, 2 = Gauche, Droite, Milieu
|
and al, 00000111b ; Bits 0, 1, 2 = Gauche, Droite, Milieu
|
||||||
mov [BDA_MOUSE + mouse.status], al
|
mov [PTR_MOUSE + mouse.status], al
|
||||||
|
|
||||||
xor ax,ax
|
xor ax,ax
|
||||||
mov al, byte [BDA_MOUSE + mouse.buffer+1] ; delta X
|
mov al, byte [PTR_MOUSE + mouse.buffer+1] ; delta X
|
||||||
test bl,00010000b ; signe X (4eme bit)
|
test bl, 00010000b ; signe X (4eme bit)
|
||||||
jz .x_pos
|
jz .x_pos
|
||||||
mov ah,0xff ; X est négatif
|
mov ah,0xff ; X est négatif
|
||||||
.x_pos:
|
.x_pos:
|
||||||
add [BDA_MOUSE + mouse.x], ax
|
add [PTR_MOUSE + mouse.x], ax
|
||||||
|
|
||||||
xor ax,ax
|
xor ax,ax
|
||||||
mov al, byte [BDA_MOUSE + mouse.buffer+2] ; delta Y
|
mov al, byte [PTR_MOUSE + mouse.buffer+2] ; delta Y
|
||||||
test bl,00100000b ; signe Y (5eme bit)
|
test bl, 00100000b ; signe Y (5eme bit)
|
||||||
jz .y_pos
|
jz .y_pos
|
||||||
mov ah,0xff ; y est négatif
|
mov ah, 0xff ; y est négatif
|
||||||
.y_pos:
|
.y_pos:
|
||||||
sub [BDA_MOUSE + mouse.y], ax
|
sub [PTR_MOUSE + mouse.y], ax
|
||||||
|
|
||||||
; --- CLAMPING X ---
|
; --- CLAMPING X ---
|
||||||
; Check minimum (0)
|
; Check minimum (0)
|
||||||
cmp word [BDA_MOUSE + mouse.x], 0
|
cmp word [PTR_MOUSE + mouse.x], 0
|
||||||
jge .check_x_max
|
jge .check_x_max
|
||||||
mov word [BDA_MOUSE + mouse.x], 0
|
mov word [PTR_MOUSE + mouse.x], 0
|
||||||
jmp .done_x
|
jmp .done_x
|
||||||
.check_x_max:
|
.check_x_max:
|
||||||
; Check maximum (e.g., 639 for graphics, or pixel width)
|
; Check maximum (e.g., 639 for graphics, or pixel width)
|
||||||
cmp word [BDA_MOUSE + mouse.x], GFX_WIDTH-1 ; Replace with variable or define
|
cmp word [PTR_MOUSE + mouse.x], GFX_WIDTH-1 ; Replace with variable or define
|
||||||
jle .done_x
|
jle .done_x
|
||||||
mov word [BDA_MOUSE + mouse.x], GFX_WIDTH-1
|
mov word [PTR_MOUSE + mouse.x], GFX_WIDTH-1
|
||||||
.done_x:
|
.done_x:
|
||||||
|
|
||||||
; --- CLAMPING Y ---
|
; --- CLAMPING Y ---
|
||||||
; Check minimum (0)
|
; Check minimum (0)
|
||||||
cmp word [BDA_MOUSE + mouse.y], 0
|
cmp word [PTR_MOUSE + mouse.y], 0
|
||||||
jge .check_y_max
|
jge .check_y_max
|
||||||
mov word [BDA_MOUSE + mouse.y], 0
|
mov word [PTR_MOUSE + mouse.y], 0
|
||||||
jmp .done_y
|
jmp .done_y
|
||||||
.check_y_max:
|
.check_y_max:
|
||||||
; Check maximum
|
; Check maximum
|
||||||
cmp word [BDA_MOUSE + mouse.y], GFX_HEIGHT-1 ; Replace with variable or define
|
cmp word [PTR_MOUSE + mouse.y], GFX_HEIGHT-1 ; Replace with variable or define
|
||||||
jle .done_y
|
jle .done_y
|
||||||
mov word [BDA_MOUSE + mouse.y], GFX_HEIGHT-1
|
mov word [PTR_MOUSE + mouse.y], GFX_HEIGHT-1
|
||||||
.done_y:
|
.done_y:
|
||||||
|
|
||||||
; check si il y a un 4eme byte a traiter
|
; check si il y a un 4eme byte a traiter
|
||||||
mov al, [BDA_MOUSE + mouse.packetlen]
|
mov al, [PTR_MOUSE + mouse.packetlen]
|
||||||
cmp al,4
|
cmp al,4
|
||||||
jne .done
|
jne .done
|
||||||
|
|
||||||
; si packetlen = 4, gérer la molette; experimental et non fonctionnel
|
; si packetlen = 4, gérer la molette; experimental et non fonctionnel
|
||||||
movsx ax, byte [BDA_MOUSE + mouse.buffer+3] ; delta Wheel
|
movsx ax, byte [PTR_MOUSE + mouse.buffer+3] ; delta Wheel
|
||||||
add word [BDA_MOUSE + mouse.wheel], ax
|
add word [PTR_MOUSE + mouse.wheel], ax
|
||||||
|
|
||||||
.done:
|
.done:
|
||||||
; update la position du curseur sur l'écran
|
; update la position du curseur sur l'écran
|
||||||
; en ce moment c'est commented out (debug)
|
; en ce moment c'est commented out (debug)
|
||||||
; call cga_mouse_cursor_move
|
; call cga_mouse_cursor_move
|
||||||
GFX MOUSE_MOVE
|
GFX MOUSE_MOVE
|
||||||
.done_eoi:
|
.done_eoi:
|
||||||
mov al, 0x20
|
mov al, 0x20
|
||||||
out i8259_SLAVE_CMD, al ; EOI PIC esclave
|
out i8259_SLAVE_CMD, al ; EOI PIC esclave
|
||||||
out i8259_MASTER_CMD, al ; EOI PIC maître
|
out i8259_MASTER_CMD, al ; EOI PIC maître
|
||||||
|
|
||||||
; restaurer tous les registres
|
; restaurer tous les registres
|
||||||
pop ds
|
pop ds
|
||||||
popa
|
popad
|
||||||
iret
|
iret
|
||||||
|
|
@ -23,7 +23,7 @@ gui_process_all:
|
||||||
push ds
|
push ds
|
||||||
mov ax, BDA_CUSTOM_SEG
|
mov ax, BDA_CUSTOM_SEG
|
||||||
mov ds, ax
|
mov ds, ax
|
||||||
mov bl, [BDA_MOUSE + mouse.status]
|
mov bl, [PTR_MOUSE + mouse.status]
|
||||||
pop ds
|
pop ds
|
||||||
|
|
||||||
mov si, 0 ; Pointeur début tableau
|
mov si, 0 ; Pointeur début tableau
|
||||||
|
|
@ -97,8 +97,8 @@ gui_update_logic:
|
||||||
xor ax, ax
|
xor ax, ax
|
||||||
|
|
||||||
; les macros peuvent modifer les registres cx, dx & bx
|
; les macros peuvent modifer les registres cx, dx & bx
|
||||||
mov cx, [BDA_MOUSE + mouse.x]
|
mov cx, [PTR_MOUSE + mouse.x]
|
||||||
mov dx, [BDA_MOUSE + mouse.y]
|
mov dx, [PTR_MOUSE + mouse.y]
|
||||||
|
|
||||||
; --- Hit Test ---
|
; --- Hit Test ---
|
||||||
cmp cx, [gs:si + widget.x]
|
cmp cx, [gs:si + widget.x]
|
||||||
|
|
@ -115,7 +115,7 @@ gui_update_logic:
|
||||||
cmp dx, bx
|
cmp dx, bx
|
||||||
ja .miss ; mouse.y >= widget.y ?
|
ja .miss ; mouse.y >= widget.y ?
|
||||||
|
|
||||||
mov bl, [BDA_MOUSE + mouse.status]
|
mov bl, [PTR_MOUSE + mouse.status]
|
||||||
|
|
||||||
.case_0:
|
.case_0:
|
||||||
cmp byte [gs:si + widget.type], OBJ_TYPE_LABEL
|
cmp byte [gs:si + widget.type], OBJ_TYPE_LABEL
|
||||||
|
|
@ -437,7 +437,7 @@ gui_logic_slider:
|
||||||
push ds
|
push ds
|
||||||
mov ax, BDA_CUSTOM_SEG
|
mov ax, BDA_CUSTOM_SEG
|
||||||
mov ds, ax
|
mov ds, ax
|
||||||
mov ax, [BDA_MOUSE + mouse.x]
|
mov ax, [PTR_MOUSE + mouse.x]
|
||||||
pop ds
|
pop ds
|
||||||
|
|
||||||
sub ax, [gs:si + widget.attr_anchor]
|
sub ax, [gs:si + widget.attr_anchor]
|
||||||
|
|
@ -465,7 +465,7 @@ gui_logic_slider:
|
||||||
push ds
|
push ds
|
||||||
mov ax, BDA_CUSTOM_SEG
|
mov ax, BDA_CUSTOM_SEG
|
||||||
mov ds, ax
|
mov ds, ax
|
||||||
mov ax, [BDA_MOUSE + mouse.y]
|
mov ax, [PTR_MOUSE + mouse.y]
|
||||||
pop ds
|
pop ds
|
||||||
|
|
||||||
sub ax, [gs:si + widget.attr_anchor]
|
sub ax, [gs:si + widget.attr_anchor]
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue