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
|
||||
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
|
||||
cd src
|
||||
echo compiling
|
||||
"C:\Program Files\NASM\nasm.exe" -f elf32 -g -F dwarf boot.asm -o ..\build\bios.o
|
||||
echo LD
|
||||
ld -m elf_i386 -T link.ld -o build\bios.elf build\bios.o
|
||||
echo ObjectCopy
|
||||
objcopy -O binary build\bios.elf build\bios.bin
|
||||
cd ..
|
||||
echo compiling ELF file
|
||||
%NASM% -f elf32 -g -F dwarf boot.asm -o ..\build\bios-elf.o
|
||||
echo compiling ROM file
|
||||
%NASM% -f bin boot.asm -o ..\build\bios.bin
|
||||
echo Linking
|
||||
%LD% -m elf_i386 -T link.ld -o ..\build\bios.elf ..\build\bios-elf.o
|
||||
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*) }
|
||||
}
|
||||
26
readme.md
26
readme.md
|
|
@ -1,4 +1,4 @@
|
|||
# Custom BIOS / ROM Project
|
||||
# Custom BIOS / ROM Project
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -51,13 +51,13 @@ The project is intentionally educational, experimental, and minimalist.
|
|||
|
||||
To build and run this project, the following tools and components are required:
|
||||
|
||||
- **NASM (Netwide Assembler)**
|
||||
- **NASM (Netwide Assembler)**
|
||||
Used to assemble x86 real-mode assembly source files into a raw binary ROM image.
|
||||
|
||||
- **QEMU**
|
||||
- **QEMU**
|
||||
Used as the primary PC emulator for testing and debugging the custom BIOS.
|
||||
|
||||
- **QEMU VGA BIOS**
|
||||
- **QEMU VGA BIOS**
|
||||
The standard QEMU VGA BIOS (`vgabios.bin`) is required to initialize the VGA hardware, allowing the custom BIOS to rely on a known and stable VGA implementation while focusing on its own core logic.
|
||||
|
||||
---
|
||||
|
|
@ -88,17 +88,17 @@ Linux
|
|||
`/usr/share/qemu/vgabios.bin`
|
||||
|
||||
You can use an video bios from the 86box's project:
|
||||
|
||||
|
||||
https://github.com/86Box/roms
|
||||
|
||||
Copy it to: `rom/vgabios.bin`
|
||||
Copy it to: `roms/vgabios.bin`
|
||||
|
||||
Then run QEMU with:
|
||||
|
||||
```bash
|
||||
qemu-system-x86_64 \
|
||||
qemu-system-i386 \
|
||||
-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 \
|
||||
-chardev stdio,id=myconsole \
|
||||
-k be \
|
||||
|
|
@ -206,18 +206,18 @@ Windows
|
|||
Linux
|
||||
`/usr/share/qemu/vgabios.bin`
|
||||
|
||||
Vous pouvez aussi utiliser un bios video du projet de 86box
|
||||
Vous pouvez aussi utiliser un bios video du projet de 86box
|
||||
|
||||
https://github.com/86Box/roms
|
||||
|
||||
À copier vers : `rom/vgabios.bin`
|
||||
À copier vers : `roms/vgabios.bin`
|
||||
|
||||
Puis lancer QEMU avec la commande suivante :
|
||||
|
||||
```bash
|
||||
qemu-system-x86_64 \
|
||||
qemu-system-i386 \
|
||||
-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 \
|
||||
-chardev stdio,id=myconsole \
|
||||
-k be \
|
||||
|
|
@ -244,7 +244,7 @@ Ce projet est avant tout un **laboratoire d’apprentissage et d’exploration**
|
|||
|
||||
### Status
|
||||
|
||||
🚧 **Work in progress**
|
||||
🚧 **Work in progress**
|
||||
Designed for experimentation, learning, and documentation.
|
||||
|
||||
---
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@
|
|||
%define BDA_VIDEO_OFS_PAGE 0x004E
|
||||
|
||||
|
||||
; 40:50 8 words Cursor position of pages 1-8, high order byte=row low order byte=column;
|
||||
; 40:50 8 words Cursor position of pages 1-8, high order byte=row low order byte=column;
|
||||
; changing this data isn't reflected immediately on the display
|
||||
; 40:60 byte Cursor ending (bottom) scan line (don't modify)
|
||||
; 40:61 byte Cursor starting (top) scan line (don't modify)
|
||||
|
|
@ -63,10 +63,11 @@
|
|||
|
||||
%define BDA_CURSOR_VISIBLE 0x000E ; byte (0/1)
|
||||
%define BDA_CURSOR_OLDX 0x000F ; word
|
||||
%define BDA_CURSOR_OLDY 0x0011 ; word
|
||||
%define BDA_CURSOR_OLDY 0x0011 ; word
|
||||
%define BDA_CURSOR_NEWX 0x0013 ; word
|
||||
%define BDA_CURSOR_NEWY 0x0015 ; word
|
||||
%define BDA_CURSOR_NEWY 0x0015 ; word
|
||||
%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_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
|
||||
org 0
|
||||
|
||||
bits 16
|
||||
; ---------------------------------------------------------------------------
|
||||
;
|
||||
; configuration du bios
|
||||
|
|
@ -40,7 +38,8 @@ org 0
|
|||
%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
|
||||
|
||||
; definition du BDA
|
||||
|
|
@ -84,24 +83,26 @@ reset:
|
|||
; on active le mode graphique
|
||||
call gfx_init
|
||||
|
||||
; test a line
|
||||
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_reset
|
||||
call mouse_init
|
||||
|
||||
mov ax,cs
|
||||
mov ds,ax
|
||||
|
||||
mov si, err_end
|
||||
call debug_puts
|
||||
; test a line
|
||||
; 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
|
||||
jmp endless
|
||||
|
|
@ -114,8 +115,14 @@ times 0xFFF0 - ($ - $$) db 0xFF
|
|||
; ------------------------------------------------------------------
|
||||
; RESET VECTOR (exécuté par le CPU)
|
||||
; ------------------------------------------------------------------
|
||||
reset_vector:
|
||||
jmp far 0xF000:reset
|
||||
; filling
|
||||
builddate db '06/01/2026',0
|
||||
section .resetvect
|
||||
bits 16
|
||||
global reset_vector
|
||||
|
||||
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:
|
||||
.next:
|
||||
push dx
|
||||
mov dx, DEBUG_PORT
|
||||
lodsb ; AL = *SI++
|
||||
test al, al
|
||||
jz .done
|
||||
|
||||
mov dx, DEBUG_PORT
|
||||
|
||||
out dx, al
|
||||
jmp .next
|
||||
.done:
|
||||
pop dx
|
||||
ret
|
||||
|
||||
|
||||
debug_putc:
|
||||
.next:
|
||||
push dx
|
||||
mov dx, DEBUG_PORT
|
||||
out dx, al
|
||||
ret
|
||||
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
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ gfx_init:
|
|||
mov al, GFX_MODE
|
||||
int 0x10
|
||||
|
||||
mov [BDA_CURSOR_SAVED],0 ; flag image saved
|
||||
mov byte [BDA_CURSOR_SAVED],0 ; flag image saved
|
||||
|
||||
; dessine un background "check-board"
|
||||
call gfx_background
|
||||
|
|
@ -159,7 +159,7 @@ gfx_background:
|
|||
gfx_cursor_calc_align:
|
||||
mov al, cl
|
||||
and al, 7 ; offset = x&7
|
||||
mov [BDA_CURSOR_BITOFF], al
|
||||
mov byte [BDA_CURSOR_BITOFF], al
|
||||
cmp al, 0
|
||||
jne .unaligned
|
||||
mov byte [BDA_CURSOR_BYTES], 2
|
||||
|
|
@ -168,156 +168,6 @@ gfx_cursor_calc_align:
|
|||
mov byte [BDA_CURSOR_BYTES], 3
|
||||
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.
|
||||
;
|
||||
|
|
@ -361,28 +211,28 @@ gfx_cursor_draw:
|
|||
mov ax, VIDEO_SEG
|
||||
mov es, ax
|
||||
|
||||
mov cx, [BDA_CURSOR_NEWX]
|
||||
mov dx, [BDA_CURSOR_NEWY]
|
||||
mov ax, word [BDA_CURSOR_PTR]
|
||||
mov si, ax
|
||||
|
||||
mov cx, word [BDA_CURSOR_NEWX]
|
||||
mov dx, word [BDA_CURSOR_NEWY]
|
||||
|
||||
; calcule offset et bytes/ligne (2 ou 3)
|
||||
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)
|
||||
push cx
|
||||
call gfx_calc_addr ; DI ok, AH ignoré
|
||||
pop cx
|
||||
|
||||
; dxbank = +0x2000 si DI < 0x2000, sinon dxbank = -0x2000
|
||||
mov bp, 02000h
|
||||
cmp di, bp
|
||||
jl .bank_ok
|
||||
neg bp ; bp = -0x2000
|
||||
.bank_ok:
|
||||
|
||||
; 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
|
||||
.pair:
|
||||
; ----- ligne row (bank courant) -----
|
||||
|
|
@ -394,7 +244,7 @@ gfx_cursor_draw:
|
|||
|
||||
; ----- ligne row+1 (autre bank) -----
|
||||
add di, bp
|
||||
inc bx
|
||||
inc bh
|
||||
push di
|
||||
push si
|
||||
call .draw_line
|
||||
|
|
@ -405,7 +255,7 @@ gfx_cursor_draw:
|
|||
; avancer de 2 lignes (dans le bank courant): +80 bytes
|
||||
add di, CGA_STRIDE
|
||||
|
||||
inc bx
|
||||
inc bh
|
||||
dec dh
|
||||
jnz .pair
|
||||
|
||||
|
|
@ -426,7 +276,8 @@ gfx_cursor_draw:
|
|||
push di
|
||||
|
||||
; 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
|
||||
|
||||
push si
|
||||
|
|
@ -550,3 +401,158 @@ gfx_cursor_draw:
|
|||
pop cx
|
||||
pop ax
|
||||
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
|
||||
|
||||
; effacer les variables du drivers
|
||||
mov [BDA_MOUSE_IDX],0
|
||||
mov byte [BDA_MOUSE_IDX],0
|
||||
mov dword [BDA_MOUSE_BUFFER],0
|
||||
mov byte [DBA_MOUSE_PACKETLEN],3
|
||||
|
||||
mov byte [BDA_MOUSE_STATUS],0
|
||||
mov word [BDA_MOUSE_X],0 ; vous pouvez aussi préciser le centre
|
||||
mov word [BDA_MOUSE_Y],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],100 ; vous pouvez aussi préciser le centre
|
||||
|
||||
; experiemntal
|
||||
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)
|
||||
|
|
@ -157,7 +162,7 @@ mouse_init:
|
|||
call mouse_sendcmd
|
||||
|
||||
; détecter le packet size (3/4 bytes)
|
||||
call mouse_detect_packet_len
|
||||
call mouse_detect_packet_len
|
||||
|
||||
; installer ISR IRQ12 (INT 74h)
|
||||
cli
|
||||
|
|
@ -300,22 +305,22 @@ mouse_sendcmd:
|
|||
; bit 7 = Y overflow
|
||||
; ------------------------------------------------------------
|
||||
mouse_handler:
|
||||
PUSH_ABCD
|
||||
push ds
|
||||
; sauvegarder tout les registres
|
||||
pusha
|
||||
|
||||
; use BDA segment
|
||||
mov ax,BDA_MOUSE_SEG
|
||||
mov ds,ax
|
||||
|
||||
in al, PS2_PORT_BUFFER ; lire octet souris
|
||||
mov [BDA_MOUSE_BUFFER + BDA_MOUSE_IDX], al
|
||||
inc [BDA_MOUSE_IDX]
|
||||
mov byte [BDA_MOUSE_BUFFER + BDA_MOUSE_IDX], al
|
||||
inc byte [BDA_MOUSE_IDX]
|
||||
|
||||
mov al, [DBA_MOUSE_PACKETLEN]
|
||||
cmp [BDA_MOUSE_IDX], al
|
||||
jne .done
|
||||
|
||||
mov [BDA_MOUSE_IDX], 0
|
||||
mov byte [BDA_MOUSE_IDX], 0
|
||||
|
||||
; decode buffer manuallement
|
||||
mov al, [BDA_MOUSE_BUFFER]
|
||||
|
|
@ -332,14 +337,42 @@ mouse_handler:
|
|||
; si packetlen = 4, gérer la molette; experimental
|
||||
mov al, [BDA_MOUSE_BUFFER+3]
|
||||
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
|
||||
call gfx_cursor_restorebg
|
||||
|
||||
; 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_draw
|
||||
|
|
@ -349,6 +382,6 @@ mouse_handler:
|
|||
out 0xA0, al ; EOI PIC esclave
|
||||
out 0x20, al ; EOI PIC maître
|
||||
|
||||
pop ds
|
||||
POP_ABCD
|
||||
; restaurer tous les registres
|
||||
popa
|
||||
iret
|
||||
Loading…
Reference in a new issue