corrrection of draw cursor
This commit is contained in:
parent
91881695fb
commit
073e6e6fbf
11 changed files with 2790 additions and 230 deletions
2
.gdb_history
Normal file
2
.gdb_history
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
quit
|
||||||
|
quit
|
||||||
|
|
@ -1,11 +1,72 @@
|
||||||
@echo off
|
@echo off
|
||||||
|
setlocal enabledelayedexpansion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
set "MSYS=C:\msys64"
|
||||||
|
set "NASM=C:\Program Files\NASM\nasm.exe"
|
||||||
|
|
||||||
|
"%MSYS%\usr\bin\bash.exe" -lc ^
|
||||||
|
"set -e; cd '%~dp0'; \
|
||||||
|
mkdir -p build; \
|
||||||
|
echo assembling; \
|
||||||
|
'%NASM%' -f elf32 -g -F dwarf src/boot.asm -o build/bios.o; \
|
||||||
|
echo linking; \
|
||||||
|
/usr/bin/ld -m elf_i386 -T link.ld -o build/bios.elf build/bios.o; \
|
||||||
|
echo objcopy; \
|
||||||
|
/usr/bin/objcopy -O binary build/bios.elf build/bios.bin; \
|
||||||
|
echo done"
|
||||||
|
|
||||||
|
pause
|
||||||
|
exit /b %errorlevel%
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
exit 0
|
||||||
|
|
||||||
|
rem Outils
|
||||||
|
set NASM="C:\Program Files\NASM\nasm.exe"
|
||||||
|
set "LD=C:\msys64\usr\bin\ld.exe"
|
||||||
|
set "OBJCOPY=C:\msys64\mingw64\bin\objcopy.exe"
|
||||||
|
|
||||||
|
rem Se placer dans le dossier du .bat
|
||||||
|
pushd "%~dp0"
|
||||||
|
|
||||||
if not exist build mkdir build
|
if not exist build mkdir build
|
||||||
cd src
|
cd src
|
||||||
echo compiling
|
echo compiling ELF file
|
||||||
"C:\Program Files\NASM\nasm.exe" -f elf32 -g -F dwarf boot.asm -o ..\build\bios.o
|
%NASM% -f elf32 -g -F dwarf boot.asm -o ..\build\bios-elf.o
|
||||||
echo LD
|
echo compiling ROM file
|
||||||
ld -m elf_i386 -T link.ld -o build\bios.elf build\bios.o
|
%NASM% -f bin boot.asm -o ..\build\bios.bin
|
||||||
echo ObjectCopy
|
echo Linking
|
||||||
objcopy -O binary build\bios.elf build\bios.bin
|
%LD% -m elf_i386 -T link.ld -o ..\build\bios.elf ..\build\bios-elf.o
|
||||||
cd ..
|
echo ObjCopy
|
||||||
|
%OBJCOPY% -O binary ..\build\bios.elf ..\build\bios-elf.bin
|
||||||
|
|
||||||
|
popd
|
||||||
|
|
||||||
|
pause
|
||||||
10
build.sh
Normal file
10
build.sh
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
mkdir -p build
|
||||||
|
|
||||||
|
cd src
|
||||||
|
nasm -f elf32 -g -F dwarf boot.asm -o ../build/bios.o
|
||||||
|
cd ..
|
||||||
|
ld -m elf_i386 -T link.ld -o build/bios.elf build/bios.o
|
||||||
|
objcopy -O binary build/bios.elf build/bios.bin
|
||||||
17
link.ld
Normal file
17
link.ld
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
OUTPUT_FORMAT(elf32-i386)
|
||||||
|
ENTRY(reset_vector)
|
||||||
|
|
||||||
|
ROM_SIZE = 0x10000;
|
||||||
|
ROM_BASE = 0x100000000 - ROM_SIZE; /* 0xFFFF0000 */
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
. = ROM_BASE;
|
||||||
|
|
||||||
|
.text : { *(.text*) *(.rodata*) *(.data*) }
|
||||||
|
|
||||||
|
/* Place le reset vector à 0xFFFFFFF0 (16 octets avant 4GB) */
|
||||||
|
.reset 0xFFFFFFF0 : { KEEP(*(.reset)) }
|
||||||
|
|
||||||
|
/DISCARD/ : { *(.eh_frame*) *(.comment*) }
|
||||||
|
}
|
||||||
12
readme.md
12
readme.md
|
|
@ -91,14 +91,14 @@ You can use an video bios from the 86box's project:
|
||||||
|
|
||||||
https://github.com/86Box/roms
|
https://github.com/86Box/roms
|
||||||
|
|
||||||
Copy it to: `rom/vgabios.bin`
|
Copy it to: `roms/vgabios.bin`
|
||||||
|
|
||||||
Then run QEMU with:
|
Then run QEMU with:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
qemu-system-x86_64 \
|
qemu-system-i386 \
|
||||||
-bios build/bios.bin \
|
-bios build/bios.bin \
|
||||||
-device loader,file=rom/vgabios.bin,addr=0xC0000,force-raw=on \
|
-device loader,file=roms/vgabios.bin,addr=0xC0000,force-raw=on \
|
||||||
-device isa-debugcon,chardev=myconsole \
|
-device isa-debugcon,chardev=myconsole \
|
||||||
-chardev stdio,id=myconsole \
|
-chardev stdio,id=myconsole \
|
||||||
-k be \
|
-k be \
|
||||||
|
|
@ -210,14 +210,14 @@ Vous pouvez aussi utiliser un bios video du projet de 86box
|
||||||
|
|
||||||
https://github.com/86Box/roms
|
https://github.com/86Box/roms
|
||||||
|
|
||||||
À copier vers : `rom/vgabios.bin`
|
À copier vers : `roms/vgabios.bin`
|
||||||
|
|
||||||
Puis lancer QEMU avec la commande suivante :
|
Puis lancer QEMU avec la commande suivante :
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
qemu-system-x86_64 \
|
qemu-system-i386 \
|
||||||
-bios build/bios.bin \
|
-bios build/bios.bin \
|
||||||
-device loader,file=rom/vgabios.bin,addr=0xC0000,force-raw=on \
|
-device loader,file=roms/vgabios.bin,addr=0xC0000,force-raw=on \
|
||||||
-device isa-debugcon,chardev=myconsole \
|
-device isa-debugcon,chardev=myconsole \
|
||||||
-chardev stdio,id=myconsole \
|
-chardev stdio,id=myconsole \
|
||||||
-k be \
|
-k be \
|
||||||
|
|
|
||||||
|
|
@ -69,4 +69,5 @@
|
||||||
%define BDA_CURSOR_BITOFF 0x0017 ; byte 0..7 bits d'offset (x&7)
|
%define BDA_CURSOR_BITOFF 0x0017 ; byte 0..7 bits d'offset (x&7)
|
||||||
%define BDA_CURSOR_BYTES 0x0019 ; byte 2 ou 3 bytes as source for cursor image
|
%define BDA_CURSOR_BYTES 0x0019 ; byte 2 ou 3 bytes as source for cursor image
|
||||||
%define BDA_CURSOR_SAVED 0x001A ; flag if image saved
|
%define BDA_CURSOR_SAVED 0x001A ; flag if image saved
|
||||||
%define BDA_CURSOR_BG 0x001B ; 48 bytes max (3*16)
|
%define BDA_CURSOR_PTR 0x001B ; pointeur vers l'image du curseur
|
||||||
|
%define BDA_CURSOR_BG 0x0020 ; 48 bytes max (3*16)
|
||||||
|
|
|
||||||
53
src/boot.asm
53
src/boot.asm
|
|
@ -20,9 +20,7 @@
|
||||||
;
|
;
|
||||||
; =============================================================================
|
; =============================================================================
|
||||||
|
|
||||||
BITS 16
|
bits 16
|
||||||
org 0
|
|
||||||
|
|
||||||
; ---------------------------------------------------------------------------
|
; ---------------------------------------------------------------------------
|
||||||
;
|
;
|
||||||
; configuration du bios
|
; configuration du bios
|
||||||
|
|
@ -40,7 +38,8 @@ org 0
|
||||||
%define MEM_SEG_STEP 0x0040 ; 1KB = 0x400 bytes = 0x40 paragraphs
|
%define MEM_SEG_STEP 0x0040 ; 1KB = 0x400 bytes = 0x40 paragraphs
|
||||||
|
|
||||||
|
|
||||||
|
section .text
|
||||||
|
bits 16
|
||||||
jmp reset ; ce jump n'est pas sensé être executer, il est présent uniquement pour le debug
|
jmp reset ; ce jump n'est pas sensé être executer, il est présent uniquement pour le debug
|
||||||
|
|
||||||
; definition du BDA
|
; definition du BDA
|
||||||
|
|
@ -84,24 +83,26 @@ reset:
|
||||||
; on active le mode graphique
|
; on active le mode graphique
|
||||||
call gfx_init
|
call gfx_init
|
||||||
|
|
||||||
; test a line
|
call mouse_reset
|
||||||
mov cx,50
|
|
||||||
.bcl: ; mov dx,cx
|
|
||||||
mov bl,0
|
|
||||||
push cx
|
|
||||||
call gfx_putpixel
|
|
||||||
pop cx
|
|
||||||
inc cx
|
|
||||||
cmp cx,150
|
|
||||||
jle .bcl
|
|
||||||
|
|
||||||
call mouse_init
|
call mouse_init
|
||||||
|
|
||||||
mov ax,cs
|
|
||||||
mov ds,ax
|
|
||||||
|
|
||||||
mov si, err_end
|
; test a line
|
||||||
call debug_puts
|
; mov cx,50
|
||||||
|
;.bcl: ; mov dx,cx
|
||||||
|
; mov bl,0
|
||||||
|
; push cx
|
||||||
|
; call gfx_putpixel
|
||||||
|
; pop cx
|
||||||
|
; inc cx
|
||||||
|
; cmp cx,150
|
||||||
|
; jle .bcl
|
||||||
|
;
|
||||||
|
; mov ax,cs
|
||||||
|
; mov ds,ax
|
||||||
|
;
|
||||||
|
; mov si, err_end
|
||||||
|
; call debug_puts
|
||||||
|
|
||||||
endless: nop
|
endless: nop
|
||||||
jmp endless
|
jmp endless
|
||||||
|
|
@ -114,8 +115,14 @@ times 0xFFF0 - ($ - $$) db 0xFF
|
||||||
; ------------------------------------------------------------------
|
; ------------------------------------------------------------------
|
||||||
; RESET VECTOR (exécuté par le CPU)
|
; RESET VECTOR (exécuté par le CPU)
|
||||||
; ------------------------------------------------------------------
|
; ------------------------------------------------------------------
|
||||||
reset_vector:
|
section .resetvect
|
||||||
jmp far 0xF000:reset
|
bits 16
|
||||||
; filling
|
global reset_vector
|
||||||
builddate db '06/01/2026',0
|
|
||||||
|
reset_vector:
|
||||||
|
; code minimal au reset
|
||||||
|
jmp 0xF000:reset
|
||||||
|
builddate db '06/01/2026'
|
||||||
|
times 16-($-$$) db 0 ; le stub tient dans 16 octets (ou moins)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,19 +23,53 @@
|
||||||
|
|
||||||
debug_puts:
|
debug_puts:
|
||||||
.next:
|
.next:
|
||||||
|
push dx
|
||||||
|
mov dx, DEBUG_PORT
|
||||||
lodsb ; AL = *SI++
|
lodsb ; AL = *SI++
|
||||||
test al, al
|
test al, al
|
||||||
jz .done
|
jz .done
|
||||||
|
|
||||||
mov dx, DEBUG_PORT
|
|
||||||
|
|
||||||
out dx, al
|
out dx, al
|
||||||
jmp .next
|
jmp .next
|
||||||
.done:
|
.done:
|
||||||
|
pop dx
|
||||||
ret
|
ret
|
||||||
|
|
||||||
debug_putc:
|
debug_putc:
|
||||||
.next:
|
push dx
|
||||||
mov dx, DEBUG_PORT
|
mov dx, DEBUG_PORT
|
||||||
out dx, al
|
out dx, al
|
||||||
|
pop dx
|
||||||
|
ret
|
||||||
|
|
||||||
|
; AL = 0..15 -> print hex digit
|
||||||
|
debug_puthex4:
|
||||||
|
and al, 0Fh
|
||||||
|
cmp al, 9
|
||||||
|
jbe .num
|
||||||
|
add al, 'A' - 10
|
||||||
|
jmp .pout
|
||||||
|
.num:
|
||||||
|
add al, '0'
|
||||||
|
.pout:
|
||||||
|
call debug_putc
|
||||||
|
ret
|
||||||
|
|
||||||
|
; AL = byte -> print 2 hex digits
|
||||||
|
debug_puthex8:
|
||||||
|
push ax
|
||||||
|
mov ah, al
|
||||||
|
shr al, 4
|
||||||
|
call debug_puthex4
|
||||||
|
mov al, ah
|
||||||
|
call debug_puthex4
|
||||||
|
pop ax
|
||||||
|
ret
|
||||||
|
|
||||||
|
; AX = word -> print 4 hex digits
|
||||||
|
debug_puthex16:
|
||||||
|
push ax
|
||||||
|
mov al, ah
|
||||||
|
call debug_puthex8
|
||||||
|
pop ax
|
||||||
|
call debug_puthex8
|
||||||
ret
|
ret
|
||||||
|
|
@ -43,7 +43,7 @@ gfx_init:
|
||||||
mov al, GFX_MODE
|
mov al, GFX_MODE
|
||||||
int 0x10
|
int 0x10
|
||||||
|
|
||||||
mov [BDA_CURSOR_SAVED],0 ; flag image saved
|
mov byte [BDA_CURSOR_SAVED],0 ; flag image saved
|
||||||
|
|
||||||
; dessine un background "check-board"
|
; dessine un background "check-board"
|
||||||
call gfx_background
|
call gfx_background
|
||||||
|
|
@ -159,7 +159,7 @@ gfx_background:
|
||||||
gfx_cursor_calc_align:
|
gfx_cursor_calc_align:
|
||||||
mov al, cl
|
mov al, cl
|
||||||
and al, 7 ; offset = x&7
|
and al, 7 ; offset = x&7
|
||||||
mov [BDA_CURSOR_BITOFF], al
|
mov byte [BDA_CURSOR_BITOFF], al
|
||||||
cmp al, 0
|
cmp al, 0
|
||||||
jne .unaligned
|
jne .unaligned
|
||||||
mov byte [BDA_CURSOR_BYTES], 2
|
mov byte [BDA_CURSOR_BYTES], 2
|
||||||
|
|
@ -168,156 +168,6 @@ gfx_cursor_calc_align:
|
||||||
mov byte [BDA_CURSOR_BYTES], 3
|
mov byte [BDA_CURSOR_BYTES], 3
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; ------------------------------------------------------------
|
|
||||||
; Sauvegarde le background (24x16) sous le curseur (cx=X,dx=Y)
|
|
||||||
;
|
|
||||||
; utilise les variables du BDA pour stocker
|
|
||||||
; ------------------------------------------------------------
|
|
||||||
gfx_cursor_savebg:
|
|
||||||
pusha ; sauvegarde registres
|
|
||||||
|
|
||||||
mov ax, BDA_MOUSE_SEG
|
|
||||||
mov ds, ax
|
|
||||||
|
|
||||||
mov ax, VIDEO_SEG
|
|
||||||
mov es, ax
|
|
||||||
|
|
||||||
cmp [BDA_CURSOR_SAVED], 0
|
|
||||||
jne .done ; déjà sauvé
|
|
||||||
|
|
||||||
mov [BDA_CURSOR_SAVED], 1 ; flag image saved
|
|
||||||
|
|
||||||
mov [BDA_CURSOR_NEWX], cx ; sauvegarde la nouvelle position
|
|
||||||
mov [BDA_CURSOR_NEWY], dx
|
|
||||||
|
|
||||||
call gfx_calc_addr ; ES:DI = byteaddr pour (X,Y)
|
|
||||||
mov dx,0x2000 ; offset pour lignes impaire
|
|
||||||
cmp di,dx
|
|
||||||
jl .no_odd_bank
|
|
||||||
neg dx ; Y est déja une ligne impaire, on retire l'offset
|
|
||||||
.no_odd_bank:
|
|
||||||
|
|
||||||
mov si, BDA_CURSOR_BG ; DS:SI = buffer de sauvegarde
|
|
||||||
mov bx, 8
|
|
||||||
|
|
||||||
and cx,0x0007 ; alignement X
|
|
||||||
jnz .row3
|
|
||||||
|
|
||||||
.row3: ; sauve 3 bytes/ligne
|
|
||||||
mov [BDA_CURSOR_BYTES], 3 ; 3 bytes/ligne
|
|
||||||
; ligne 'y', peut etre paire ou impaire
|
|
||||||
mov ax, word [es:di] ; charge first word
|
|
||||||
mov word [ds:si], ax ; sauvegarde
|
|
||||||
mov al, byte [es:di+2] ; charge 3ème byte
|
|
||||||
mov byte [ds:si+2], al
|
|
||||||
add si, 3
|
|
||||||
|
|
||||||
; ligne 'y'+1; si paire +0x2000, si impaire -0x2000
|
|
||||||
add di, dx ; charge first word other bank (+0x2000 ou -0x2000)
|
|
||||||
mov ax, word [es:di]
|
|
||||||
mov word [ds:si], ax
|
|
||||||
mov al, byte [es:di+2]
|
|
||||||
mov byte [ds:si+2], al
|
|
||||||
add si, 3
|
|
||||||
sub di, dx
|
|
||||||
add di, CGA_STRIDE
|
|
||||||
dec bx
|
|
||||||
jnz .row3
|
|
||||||
jmp .done
|
|
||||||
|
|
||||||
.row2: ; sauve 2 bytes/ligne
|
|
||||||
mov [BDA_CURSOR_BYTES], 2 ; par défaut
|
|
||||||
; ligne 'y', peut etre paire ou impaire
|
|
||||||
mov ax, word [es:di] ; charge first word
|
|
||||||
mov word [ds:si], ax ; sauvegarde
|
|
||||||
add si, 2
|
|
||||||
|
|
||||||
; ligne 'y'+1; si paire +0x2000, si impaire -0x2000
|
|
||||||
add di, dx ; charge first word other bank (+0x2000 ou -0x2000)
|
|
||||||
mov ax, word [es:di]
|
|
||||||
mov word [ds:si], ax
|
|
||||||
add si, 2
|
|
||||||
sub di, dx
|
|
||||||
add di, CGA_STRIDE
|
|
||||||
dec bx
|
|
||||||
jnz .row3
|
|
||||||
.done:
|
|
||||||
popa
|
|
||||||
ret
|
|
||||||
|
|
||||||
; ------------------------------------------------------------
|
|
||||||
; restore le background (24x16)
|
|
||||||
;
|
|
||||||
; utilise les variables du BDA pour stocker
|
|
||||||
; ------------------------------------------------------------
|
|
||||||
gfx_cursor_restorebg:
|
|
||||||
pusha ; sauvegarde registres
|
|
||||||
|
|
||||||
mov ax, BDA_MOUSE_SEG
|
|
||||||
mov ds, ax
|
|
||||||
|
|
||||||
mov ax, VIDEO_SEG
|
|
||||||
mov es, ax
|
|
||||||
|
|
||||||
cmp [BDA_CURSOR_SAVED], 0 ; pas de background sauvé
|
|
||||||
je .done
|
|
||||||
|
|
||||||
mov cx,[BDA_CURSOR_OLDX] ; restore de la position
|
|
||||||
mov dx,[BDA_CURSOR_OLDY]
|
|
||||||
mov [BDA_CURSOR_SAVED], 0 ; le background a été restauré
|
|
||||||
|
|
||||||
call gfx_calc_addr ; ES:DI = byteaddr pour (X,Y)
|
|
||||||
mov dx,0x2000 ; offset pour lignes impaire
|
|
||||||
cmp di,dx
|
|
||||||
jl .no_odd_bank
|
|
||||||
neg dx ; Y est déja une ligne impaire, on retire l'offset
|
|
||||||
.no_odd_bank:
|
|
||||||
mov si, BDA_CURSOR_BG ; DS:SI = buffer de sauvegarde
|
|
||||||
mov bx, 8
|
|
||||||
|
|
||||||
cmp [BDA_CURSOR_BYTES], 2 ; si la sauvegarde est en 2 bytes/ligne
|
|
||||||
je .row2
|
|
||||||
|
|
||||||
.row3: ; restore en 3 bytes/ligne
|
|
||||||
; ligne 'y', peut etre paire ou impaire
|
|
||||||
mov ax,word [ds:si] ; recupère le 1er word
|
|
||||||
mov word [es:di],ax
|
|
||||||
mov al,byte [ds:si+2] ; charge 3ème byte
|
|
||||||
mov byte [es:di+2],al
|
|
||||||
add si, 3
|
|
||||||
|
|
||||||
; ligne 'y'+1; si paire +0x2000, si impaire -0x2000
|
|
||||||
add di, dx ; charge first word other bank (+0x2000 ou -0x2000)
|
|
||||||
mov ax,word [ds:si] ; recupère le 1er word
|
|
||||||
mov word [es:di],ax
|
|
||||||
mov al,byte [ds:si+2] ; charge 3ème byte
|
|
||||||
mov byte [es:di+2],al
|
|
||||||
add si, 3
|
|
||||||
sub di, dx
|
|
||||||
add di, CGA_STRIDE
|
|
||||||
dec bx
|
|
||||||
jnz .row3
|
|
||||||
jmp .done
|
|
||||||
|
|
||||||
.row2: ; restore en 2 bytes/ligne
|
|
||||||
; ligne 'y', peut etre paire ou impaire
|
|
||||||
mov ax,word [ds:si] ; recupère le 1er word
|
|
||||||
mov word [es:di],ax
|
|
||||||
add si, 2
|
|
||||||
|
|
||||||
; ligne 'y'+1; si paire +0x2000, si impaire -0x2000
|
|
||||||
add di, dx ; charge first word other bank (+0x2000 ou -0x2000)
|
|
||||||
mov ax,word [ds:si] ; recupère le 1er word
|
|
||||||
mov word [es:di],ax
|
|
||||||
add si, 2
|
|
||||||
sub di, dx
|
|
||||||
add di, CGA_STRIDE
|
|
||||||
dec bx
|
|
||||||
jnz .row2
|
|
||||||
.done:
|
|
||||||
popa
|
|
||||||
ret
|
|
||||||
|
|
||||||
; ------------------------------------------------------------
|
; ------------------------------------------------------------
|
||||||
; Dessine un pixel, en [ES:DI] accès VRAM direct.
|
; Dessine un pixel, en [ES:DI] accès VRAM direct.
|
||||||
;
|
;
|
||||||
|
|
@ -361,28 +211,28 @@ gfx_cursor_draw:
|
||||||
mov ax, VIDEO_SEG
|
mov ax, VIDEO_SEG
|
||||||
mov es, ax
|
mov es, ax
|
||||||
|
|
||||||
mov cx, [BDA_CURSOR_NEWX]
|
mov ax, word [BDA_CURSOR_PTR]
|
||||||
mov dx, [BDA_CURSOR_NEWY]
|
mov si, ax
|
||||||
|
|
||||||
|
mov cx, word [BDA_CURSOR_NEWX]
|
||||||
|
mov dx, word [BDA_CURSOR_NEWY]
|
||||||
|
|
||||||
; calcule offset et bytes/ligne (2 ou 3)
|
; calcule offset et bytes/ligne (2 ou 3)
|
||||||
call gfx_cursor_calc_align
|
call gfx_cursor_calc_align
|
||||||
mov bl, [BDA_CURSOR_BITOFF] ; 0..7
|
mov bl, byte [BDA_CURSOR_BITOFF]; 0..7
|
||||||
|
|
||||||
; calcule DI de départ (attention: gfx_calc_addr modifie CL)
|
; calcule DI de départ (attention: gfx_calc_addr modifie CL)
|
||||||
push cx
|
push cx
|
||||||
call gfx_calc_addr ; DI ok, AH ignoré
|
call gfx_calc_addr ; DI ok, AH ignoré
|
||||||
pop cx
|
pop cx
|
||||||
|
|
||||||
; dxbank = +0x2000 si DI < 0x2000, sinon dxbank = -0x2000
|
; dxbank = +0x2000 si DI < 0x2000, sinon dxbank = -0x2000
|
||||||
mov bp, 02000h
|
mov bp, 02000h
|
||||||
cmp di, bp
|
cmp di, bp
|
||||||
jl .bank_ok
|
jl .bank_ok
|
||||||
neg bp ; bp = -0x2000
|
neg bp ; bp = -0x2000
|
||||||
.bank_ok:
|
.bank_ok:
|
||||||
|
|
||||||
; on va dessiner 16 lignes: 8 paires (ligne dans bank courant + ligne dans autre bank)
|
; on va dessiner 16 lignes: 8 paires (ligne dans bank courant + ligne dans autre bank)
|
||||||
mov bx, 0 ; row index (0..15)
|
mov bh, 0 ; row index (0..15)
|
||||||
|
|
||||||
mov dh, 8
|
mov dh, 8
|
||||||
.pair:
|
.pair:
|
||||||
; ----- ligne row (bank courant) -----
|
; ----- ligne row (bank courant) -----
|
||||||
|
|
@ -394,7 +244,7 @@ gfx_cursor_draw:
|
||||||
|
|
||||||
; ----- ligne row+1 (autre bank) -----
|
; ----- ligne row+1 (autre bank) -----
|
||||||
add di, bp
|
add di, bp
|
||||||
inc bx
|
inc bh
|
||||||
push di
|
push di
|
||||||
push si
|
push si
|
||||||
call .draw_line
|
call .draw_line
|
||||||
|
|
@ -405,7 +255,7 @@ gfx_cursor_draw:
|
||||||
; avancer de 2 lignes (dans le bank courant): +80 bytes
|
; avancer de 2 lignes (dans le bank courant): +80 bytes
|
||||||
add di, CGA_STRIDE
|
add di, CGA_STRIDE
|
||||||
|
|
||||||
inc bx
|
inc bh
|
||||||
dec dh
|
dec dh
|
||||||
jnz .pair
|
jnz .pair
|
||||||
|
|
||||||
|
|
@ -426,7 +276,8 @@ gfx_cursor_draw:
|
||||||
push di
|
push di
|
||||||
|
|
||||||
; charger masks de la ligne: AND = [SI + row*2], XOR = [SI + 32 + row*2]
|
; charger masks de la ligne: AND = [SI + row*2], XOR = [SI + 32 + row*2]
|
||||||
mov ax, bx
|
xor ax, ax
|
||||||
|
mov al, bh
|
||||||
shl ax, 1 ; row*2
|
shl ax, 1 ; row*2
|
||||||
|
|
||||||
push si
|
push si
|
||||||
|
|
@ -550,3 +401,158 @@ gfx_cursor_draw:
|
||||||
pop cx
|
pop cx
|
||||||
pop ax
|
pop ax
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
; ------------------------------------------------------------
|
||||||
|
; Sauvegarde le background (24x16) sous le curseur
|
||||||
|
;
|
||||||
|
; utilise les variables du BDA pour stocker
|
||||||
|
; ------------------------------------------------------------
|
||||||
|
gfx_cursor_savebg:
|
||||||
|
pusha ; sauvegarde registres
|
||||||
|
|
||||||
|
mov ax, BDA_MOUSE_SEG
|
||||||
|
mov ds, ax
|
||||||
|
|
||||||
|
mov ax, VIDEO_SEG
|
||||||
|
mov es, ax
|
||||||
|
|
||||||
|
cmp byte [BDA_CURSOR_SAVED], 0
|
||||||
|
jne .done ; déjà sauvé
|
||||||
|
|
||||||
|
mov cx, [BDA_MOUSE_X]
|
||||||
|
mov dx, [BDA_MOUSE_Y]
|
||||||
|
|
||||||
|
mov byte [BDA_CURSOR_SAVED], 1 ; flag image saved
|
||||||
|
|
||||||
|
mov word [BDA_CURSOR_NEWX], cx ; sauvegarde la nouvelle position
|
||||||
|
mov word [BDA_CURSOR_NEWY], dx
|
||||||
|
|
||||||
|
call gfx_calc_addr ; ES:DI = byteaddr pour (X,Y)
|
||||||
|
mov dx,0x2000 ; offset pour lignes impaire
|
||||||
|
cmp di,dx
|
||||||
|
jl .no_odd_bank
|
||||||
|
neg dx ; Y est déja une ligne impaire, on retire l'offset
|
||||||
|
.no_odd_bank:
|
||||||
|
|
||||||
|
mov si, BDA_CURSOR_BG ; DS:SI = buffer de sauvegarde
|
||||||
|
mov bx, 8
|
||||||
|
|
||||||
|
and cx,0x0007 ; alignement X
|
||||||
|
jnz .row3
|
||||||
|
|
||||||
|
.row3: ; sauve 3 bytes/ligne
|
||||||
|
mov byte [BDA_CURSOR_BYTES], 3 ; 3 bytes/ligne
|
||||||
|
; ligne 'y', peut etre paire ou impaire
|
||||||
|
mov ax, word [es:di] ; charge first word
|
||||||
|
mov word [ds:si], ax ; sauvegarde
|
||||||
|
mov al, byte [es:di+2] ; charge 3ème byte
|
||||||
|
mov byte [ds:si+2], al
|
||||||
|
add si, 3
|
||||||
|
|
||||||
|
; ligne 'y'+1; si paire +0x2000, si impaire -0x2000
|
||||||
|
add di, dx ; charge first word other bank (+0x2000 ou -0x2000)
|
||||||
|
mov ax, word [es:di]
|
||||||
|
mov word [ds:si], ax
|
||||||
|
mov al, byte [es:di+2]
|
||||||
|
mov byte [ds:si+2], al
|
||||||
|
add si, 3
|
||||||
|
sub di, dx
|
||||||
|
add di, CGA_STRIDE
|
||||||
|
dec bx
|
||||||
|
jnz .row3
|
||||||
|
jmp .done
|
||||||
|
|
||||||
|
.row2: ; sauve 2 bytes/ligne
|
||||||
|
mov byte [BDA_CURSOR_BYTES], 2 ; par défaut
|
||||||
|
; ligne 'y', peut etre paire ou impaire
|
||||||
|
mov ax, word [es:di] ; charge first word
|
||||||
|
mov word [ds:si], ax ; sauvegarde
|
||||||
|
add si, 2
|
||||||
|
|
||||||
|
; ligne 'y'+1; si paire +0x2000, si impaire -0x2000
|
||||||
|
add di, dx ; charge first word other bank (+0x2000 ou -0x2000)
|
||||||
|
mov ax, word [es:di]
|
||||||
|
mov word [ds:si], ax
|
||||||
|
add si, 2
|
||||||
|
sub di, dx
|
||||||
|
add di, CGA_STRIDE
|
||||||
|
dec bx
|
||||||
|
jnz .row3
|
||||||
|
.done:
|
||||||
|
popa
|
||||||
|
ret
|
||||||
|
|
||||||
|
; ------------------------------------------------------------
|
||||||
|
; restore le background (24x16)
|
||||||
|
;
|
||||||
|
; utilise les variables du BDA pour stocker
|
||||||
|
; ------------------------------------------------------------
|
||||||
|
gfx_cursor_restorebg:
|
||||||
|
pusha ; sauvegarde registres
|
||||||
|
|
||||||
|
mov ax, BDA_MOUSE_SEG
|
||||||
|
mov ds, ax
|
||||||
|
|
||||||
|
mov ax, VIDEO_SEG
|
||||||
|
mov es, ax
|
||||||
|
|
||||||
|
cmp byte [BDA_CURSOR_SAVED], 0 ; pas de background sauvé
|
||||||
|
je .done
|
||||||
|
|
||||||
|
mov cx,word [BDA_CURSOR_OLDX] ; restore de la position
|
||||||
|
mov dx,word [BDA_CURSOR_OLDY]
|
||||||
|
mov byte [BDA_CURSOR_SAVED], 0 ; le background a été restauré
|
||||||
|
|
||||||
|
call gfx_calc_addr ; ES:DI = byteaddr pour (X,Y)
|
||||||
|
mov dx,0x2000 ; offset pour lignes impaire
|
||||||
|
cmp di,dx
|
||||||
|
jl .no_odd_bank
|
||||||
|
neg dx ; Y est déja une ligne impaire, on retire l'offset
|
||||||
|
.no_odd_bank:
|
||||||
|
mov si, BDA_CURSOR_BG ; DS:SI = buffer de sauvegarde
|
||||||
|
mov bx, 8
|
||||||
|
|
||||||
|
cmp byte [BDA_CURSOR_BYTES], 2 ; si la sauvegarde est en 2 bytes/ligne
|
||||||
|
je .row2
|
||||||
|
|
||||||
|
.row3: ; restore en 3 bytes/ligne
|
||||||
|
; ligne 'y', peut etre paire ou impaire
|
||||||
|
mov ax,word [ds:si] ; recupère le 1er word
|
||||||
|
mov word [es:di],ax
|
||||||
|
mov al,byte [ds:si+2] ; charge 3ème byte
|
||||||
|
mov byte [es:di+2],al
|
||||||
|
add si, 3
|
||||||
|
|
||||||
|
; ligne 'y'+1; si paire +0x2000, si impaire -0x2000
|
||||||
|
add di, dx ; charge first word other bank (+0x2000 ou -0x2000)
|
||||||
|
mov ax,word [ds:si] ; recupère le 1er word
|
||||||
|
mov word [es:di],ax
|
||||||
|
mov al,byte [ds:si+2] ; charge 3ème byte
|
||||||
|
mov byte [es:di+2],al
|
||||||
|
add si, 3
|
||||||
|
sub di, dx
|
||||||
|
add di, CGA_STRIDE
|
||||||
|
dec bx
|
||||||
|
jnz .row3
|
||||||
|
jmp .done
|
||||||
|
|
||||||
|
.row2: ; restore en 2 bytes/ligne
|
||||||
|
; ligne 'y', peut etre paire ou impaire
|
||||||
|
mov ax,word [ds:si] ; recupère le 1er word
|
||||||
|
mov word [es:di],ax
|
||||||
|
add si, 2
|
||||||
|
|
||||||
|
; ligne 'y'+1; si paire +0x2000, si impaire -0x2000
|
||||||
|
add di, dx ; charge first word other bank (+0x2000 ou -0x2000)
|
||||||
|
mov ax,word [ds:si] ; recupère le 1er word
|
||||||
|
mov word [es:di],ax
|
||||||
|
add si, 2
|
||||||
|
sub di, dx
|
||||||
|
add di, CGA_STRIDE
|
||||||
|
dec bx
|
||||||
|
jnz .row2
|
||||||
|
.done:
|
||||||
|
popa
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -88,18 +88,23 @@ mouse_reset:
|
||||||
mov ds,ax
|
mov ds,ax
|
||||||
|
|
||||||
; effacer les variables du drivers
|
; effacer les variables du drivers
|
||||||
mov [BDA_MOUSE_IDX],0
|
mov byte [BDA_MOUSE_IDX],0
|
||||||
mov dword [BDA_MOUSE_BUFFER],0
|
mov dword [BDA_MOUSE_BUFFER],0
|
||||||
mov byte [DBA_MOUSE_PACKETLEN],3
|
mov byte [DBA_MOUSE_PACKETLEN],3
|
||||||
|
|
||||||
mov byte [BDA_MOUSE_STATUS],0
|
mov byte [BDA_MOUSE_STATUS],0
|
||||||
mov word [BDA_MOUSE_X],0 ; vous pouvez aussi préciser le centre
|
mov word [BDA_MOUSE_X],320 ; vous pouvez aussi préciser le centre
|
||||||
mov word [BDA_MOUSE_Y],0 ; vous pouvez aussi préciser le centre
|
mov word [BDA_MOUSE_Y],100 ; vous pouvez aussi préciser le centre
|
||||||
|
|
||||||
; experiemntal
|
; experiemntal
|
||||||
mov word [BDA_MOUSE_WHEEL],0
|
mov word [BDA_MOUSE_WHEEL],0
|
||||||
ret
|
|
||||||
|
|
||||||
|
mov byte [BDA_CURSOR_VISIBLE], 1
|
||||||
|
mov word [BDA_CURSOR_OLDX], 0
|
||||||
|
mov word [BDA_CURSOR_OLDY], 0
|
||||||
|
|
||||||
|
mov word [BDA_CURSOR_PTR], mouse_arrow
|
||||||
|
ret
|
||||||
|
|
||||||
; ------------------------------------------------------------
|
; ------------------------------------------------------------
|
||||||
; initialise le i8042 keyboard and mouse (PS/2)
|
; initialise le i8042 keyboard and mouse (PS/2)
|
||||||
|
|
@ -157,7 +162,7 @@ mouse_init:
|
||||||
call mouse_sendcmd
|
call mouse_sendcmd
|
||||||
|
|
||||||
; détecter le packet size (3/4 bytes)
|
; détecter le packet size (3/4 bytes)
|
||||||
call mouse_detect_packet_len
|
call mouse_detect_packet_len
|
||||||
|
|
||||||
; installer ISR IRQ12 (INT 74h)
|
; installer ISR IRQ12 (INT 74h)
|
||||||
cli
|
cli
|
||||||
|
|
@ -300,22 +305,22 @@ mouse_sendcmd:
|
||||||
; bit 7 = Y overflow
|
; bit 7 = Y overflow
|
||||||
; ------------------------------------------------------------
|
; ------------------------------------------------------------
|
||||||
mouse_handler:
|
mouse_handler:
|
||||||
PUSH_ABCD
|
; sauvegarder tout les registres
|
||||||
push ds
|
pusha
|
||||||
|
|
||||||
; use BDA segment
|
; use BDA segment
|
||||||
mov ax,BDA_MOUSE_SEG
|
mov ax,BDA_MOUSE_SEG
|
||||||
mov ds,ax
|
mov ds,ax
|
||||||
|
|
||||||
in al, PS2_PORT_BUFFER ; lire octet souris
|
in al, PS2_PORT_BUFFER ; lire octet souris
|
||||||
mov [BDA_MOUSE_BUFFER + BDA_MOUSE_IDX], al
|
mov byte [BDA_MOUSE_BUFFER + BDA_MOUSE_IDX], al
|
||||||
inc [BDA_MOUSE_IDX]
|
inc byte [BDA_MOUSE_IDX]
|
||||||
|
|
||||||
mov al, [DBA_MOUSE_PACKETLEN]
|
mov al, [DBA_MOUSE_PACKETLEN]
|
||||||
cmp [BDA_MOUSE_IDX], al
|
cmp [BDA_MOUSE_IDX], al
|
||||||
jne .done
|
jne .done
|
||||||
|
|
||||||
mov [BDA_MOUSE_IDX], 0
|
mov byte [BDA_MOUSE_IDX], 0
|
||||||
|
|
||||||
; decode buffer manuallement
|
; decode buffer manuallement
|
||||||
mov al, [BDA_MOUSE_BUFFER]
|
mov al, [BDA_MOUSE_BUFFER]
|
||||||
|
|
@ -332,14 +337,42 @@ mouse_handler:
|
||||||
; si packetlen = 4, gérer la molette; experimental
|
; si packetlen = 4, gérer la molette; experimental
|
||||||
mov al, [BDA_MOUSE_BUFFER+3]
|
mov al, [BDA_MOUSE_BUFFER+3]
|
||||||
cbw
|
cbw
|
||||||
sub [BDA_MOUSE_WHEEL], ax
|
add word [BDA_MOUSE_WHEEL], ax
|
||||||
|
|
||||||
|
; debug: afficher les valeurs
|
||||||
|
mov si, BDA_MOUSE_BUFFER
|
||||||
|
mov cx, 4
|
||||||
|
.debug_loop:
|
||||||
|
mov al, [si]
|
||||||
|
call debug_puthex8
|
||||||
|
mov al, ' '
|
||||||
|
call debug_putc
|
||||||
|
inc si
|
||||||
|
loop .debug_loop
|
||||||
|
|
||||||
|
; clamp X
|
||||||
|
cmp word [BDA_MOUSE_X], 0
|
||||||
|
jge .x_ok_low
|
||||||
|
mov word [BDA_MOUSE_X], 0
|
||||||
|
.x_ok_low:
|
||||||
|
cmp word [BDA_MOUSE_X], 639
|
||||||
|
jle .x_ok_high
|
||||||
|
mov word [BDA_MOUSE_X], 639
|
||||||
|
.x_ok_high:
|
||||||
|
|
||||||
|
; clamp Y
|
||||||
|
cmp word [BDA_MOUSE_Y], 0
|
||||||
|
jge .y_ok_low
|
||||||
|
mov word [BDA_MOUSE_Y], 0
|
||||||
|
.y_ok_low:
|
||||||
|
cmp word [BDA_MOUSE_Y], 199
|
||||||
|
jle .y_ok_high
|
||||||
|
mov word [BDA_MOUSE_Y], 199
|
||||||
|
.y_ok_high:
|
||||||
; restaurer l'ancien arrière plan du curseur
|
; restaurer l'ancien arrière plan du curseur
|
||||||
call gfx_cursor_restorebg
|
call gfx_cursor_restorebg
|
||||||
|
|
||||||
; sauvegarder le nouvel arrière plan du curseur
|
; sauvegarder le nouvel arrière plan du curseur
|
||||||
mov cx, [BDA_MOUSE_X]
|
|
||||||
mov dx, [BDA_MOUSE_Y]
|
|
||||||
call gfx_cursor_savebg
|
call gfx_cursor_savebg
|
||||||
|
|
||||||
call gfx_cursor_draw
|
call gfx_cursor_draw
|
||||||
|
|
@ -349,6 +382,6 @@ mouse_handler:
|
||||||
out 0xA0, al ; EOI PIC esclave
|
out 0xA0, al ; EOI PIC esclave
|
||||||
out 0x20, al ; EOI PIC maître
|
out 0x20, al ; EOI PIC maître
|
||||||
|
|
||||||
pop ds
|
; restaurer tous les registres
|
||||||
POP_ABCD
|
popa
|
||||||
iret
|
iret
|
||||||
Loading…
Reference in a new issue