From 2f562526ffc9b25509239d2ea184c1f52537bf27 Mon Sep 17 00:00:00 2001 From: Frater <13979047+saintfrater@users.noreply.github.com> Date: Thu, 5 Feb 2026 17:58:06 +0100 Subject: [PATCH] move ega to ega banch --- src/drivers/gfx_egam.asm | 1065 -------------------------------------- 1 file changed, 1065 deletions(-) delete mode 100644 src/drivers/gfx_egam.asm diff --git a/src/drivers/gfx_egam.asm b/src/drivers/gfx_egam.asm deleted file mode 100644 index 8994bb9..0000000 --- a/src/drivers/gfx_egam.asm +++ /dev/null @@ -1,1065 +0,0 @@ -; ============================================================================= -; Project : Custom BIOS / ROM -; File : gfx_ega.asm -; Author : frater (Converted to EGA by Assistant) -; -; License : GNU General Public License v3.0 or later (GPL-3.0+) -; ============================================================================= - -; -; graphics drivers pour carte video/mode EGA (640x350x16) -; -%define VIDEO_SEG 0xA000 ; EGA Memory Segment - -%define GFX_MODE 0x10 ; EGA HiRes (640x350 16 colors) -%define GFX_WIDTH 640 -%define GFX_HEIGHT 350 - -%define EGA_STRIDE 80 ; 640 pixels / 8 bits = 80 bytes - -; EGA IO Ports -%define SC_INDEX 0x3C4 ; Sequencer Index -%define SC_DATA 0x3C5 ; Sequencer Data -%define GC_INDEX 0x3CE ; Graphics Controller Index -%define GC_DATA 0x3CF ; Graphics Controller Data - -; EGA Registers Indices -%define GC_SET_RESET 0x00 -%define GC_ENABLE_SR 0x01 -%define GC_COLOR_CMP 0x02 -%define GC_ROTATE 0x03 -%define GC_READ_MAP 0x04 -%define GC_MODE 0x05 -%define GC_MISC 0x06 -%define GC_BIT_MASK 0x08 - -%define SC_MAP_MASK 0x02 - -; -; bit : descr -; 0 : text color : 0=black, 1=white (In EGA, mapped to logic) -; 1 : transparent : 1=apply background attribut -; -%define GFX_TXT_TRANSPARENT_MASK 00000010b - -%macro GFX 1-* - %rep %0 - 1 - %rotate -1 - push %1 - %endrep - %rotate -1 - call word [cs:graph_driver + ((%1)*2)] - add sp, (%0 - 1) * 2 -%endmacro - -; ------------------------------------------------------------ -; TABLE DE SAUT (VECTEURS API) -; ------------------------------------------------------------ -%define INIT 0 -%define PUTPIXEL 1 -%define GETPIXEL 2 -%define GOTOXY 3 -%define TXT_MODE 4 -%define PUTCH 5 -%define WRITE 6 -%define LINE_VERT 7 -%define LINE_HORIZ 8 -%define RECTANGLE 9 -%define RECTANGLE_FILL 10 -%define RECTANGLE_ROUND 11 -%define MOUSE_HIDE 12 -%define MOUSE_SHOW 13 -%define MOUSE_MOVE 14 - -align 2 -graph_driver: - dw ega_init ; 0 - dw ega_putpixel ; 1 - dw ega_getpixel ; 2 - dw ega_set_charpos ; 3 - dw ega_set_writemode ; 4 - dw ega_putc ; 5 - dw ega_write ; 6 - dw ega_line_vertical ; 7 - dw ega_line_horizontal ; 8 - dw ega_draw_rect ; 9 - dw ega_fill_rect ; 10 - dw ega_draw_rounded_frame ; 11 - dw ega_mouse_hide ; 12 - dw ega_mouse_show ; 13 - dw ega_mouse_cursor_move ; 14 - -; ============================================================================= -; SECTION : PATTERNS -; ============================================================================= -align 8 -pattern_8x8: - dq 0x0000000000000000 ; pattern_black - dq 0x2200880022008800 ; pattern_gray_dark - dq 0x2288228822882288 ; pattern_gray_mid - dq 0xAA55AA55AA55AA55 ; pattern_gray_light - dq 0x77DD77DD77DD77DD ; pattern_white_light - dq 0xFFFFFFFFFFFFFFFF ; pattern_white - -; ------------------------------------------------------------ -; initialise le mode graphique (via l'int 10h) -; ------------------------------------------------------------ -ega_init: - mov ax, BDA_DATA_SEG - mov ds, ax - - ; init graphics mode EGA 640x350x16 - mov ax, GFX_MODE - int 0x10 - - ; Configurer les registres EGA par défaut (Write Mode 0, etc.) - mov dx, GC_INDEX - mov ax, 0x0005 ; Index 5 (Mode), Value 0 (Write Mode 0) - out dx, ax - mov ax, 0x0003 ; Index 3 (Rotate/Func), Value 0 (Copy) - out dx, ax - mov ax, 0xFF08 ; Index 8 (Bit Mask), Value 0xFF (All bits) - out dx, ax - - call ega_background - ret - -; ------------------------------------------------------------ -; Calcule DI + AH=mask pour (CX=x, DX=y) en mode EGA 640x350 -; Out: ES=VIDEO_SEG, DI=offset, AH=bitmask -; ------------------------------------------------------------ -ega_calc_addr: - ; Offset = Y * 80 + X / 8 - ; Y * 80 = Y*64 + Y*16 - mov ax, dx - shl ax, 4 ; Y * 16 - mov di, ax - shl ax, 2 ; Y * 64 - add di, ax ; DI = Y * 80 - - mov ax, cx - shr ax, 3 ; X / 8 - add di, ax ; DI = Offset final - - ; Bitmask : bit 7 = pixel de gauche, bit 0 = droite - mov cl, is_cx_low_byte_safe ; Trick to use CL - mov cl, key_x_mask - mov ax, cx - and cl, 7 - xor cl, 7 ; Inversion pour l'endianness EGA - mov ah, 1 - shl ah, cl ; AH = Masque - - ret - - ; Note: NASM local define workaround - %define key_x_mask 7 - -; --------------------------------------------------------------------------- -; ega_set_writemode (mode) -; --------------------------------------------------------------------------- -ega_set_writemode: - push bp - mov bp, sp - %define .mode word [bp+4] - push fs - push ax - mov ax, BDA_DATA_SEG - mov fs,ax - mov ax, .mode - mov byte [fs:BDA_GFX + gfx.cur_mode], al - pop ax - pop fs - leave - ret - -; --------------------------------------------------------------------------- -; ega_set_charpos (x,y) -; --------------------------------------------------------------------------- -%define .x word [bp+4] -%define .y word [bp+6] -ega_set_charpos: - push bp - mov bp, sp - - - pusha - push fs - mov ax,BDA_DATA_SEG - mov fs,ax - - mov cx, .x - mov dx, .y - mov [fs:BDA_GFX + gfx.cur_x], cx - mov [fs:BDA_GFX + gfx.cur_y], dx - - ; Calcul offset - call ega_calc_addr_internal ; Helper local - - mov [fs:BDA_GFX + gfx.cur_offset], di - - ; Shift pour le texte (inutilisé en EGA hardware text, mais utile pour notre routine software) - mov ax, cx - and ax, 7 - mov [fs:BDA_GFX + gfx.cur_shift], al - - pop fs - popa - leave - ret - %undef .x - %undef .y - -; Helper sans AH mask return -ega_calc_addr_internal: - mov ax, dx - shl ax, 4 - mov di, ax - shl ax, 2 - add di, ax - mov ax, cx - shr ax, 3 - add di, ax - ret - -; --------------------------------------------------------------------------- -; get_glyph_offset -; --------------------------------------------------------------------------- -get_glyph_offset: - cmp al, 0x20 - jb .qmark - cmp al, 0x7E - ja .qmark - 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 - -; --------------------------------------------------------------------------- -; ega_putc -; Dessine un caractère 8x8. -; Optimisé pour EGA : Utilise Write Mode 2 ou le masque de bits pour la vitesse. -; Simplification : On dessine byte aligné si possible, sinon pixel par pixel. -; Pour ce portage, on adapte la logique existante pixel-pixel (lente mais sûre) -; ou une version optimisée Write Mode 0. -; --------------------------------------------------------------------------- -ega_putc: - push bp - mov bp, sp - %define .car word [bp+4] - - pusha - push fs - push es - - call ega_mouse_hide - - mov ax, VIDEO_SEG - mov es, ax - mov ax, BDA_DATA_SEG - mov fs, ax - - mov ax, .car - call get_glyph_offset ; CS:SI points to glyph - - mov di, [fs:BDA_GFX + gfx.cur_offset] - mov cx, [fs:BDA_GFX + gfx.cur_x] - and cx, 7 - jnz .unaligned ; Si x n'est pas multiple de 8, c'est complexe - - ; --- Version Alignée (Rapide) --- - ; On configure EGA pour Write Mode 0 - mov dx, GC_INDEX - mov ax, 0x0005 ; Mode 0 - out dx, ax - mov ax, 0x0F01 ; Enable Set/Reset all planes - out dx, ax - - ; Couleur Texte (Blanc = 15 = 0xF) - mov ax, 0x0F00 ; Set/Reset color index (Foreground) - out dx, ax - - ; Boucle sur 8 lignes - mov bx, 8 - .row_loop_a: - mov ah, [cs:si] ; Load font byte - inc si - - ; Masque de bits = Font Byte - mov al, 0x08 ; Index BitMask - out dx, ax ; Out AH=Mask, AL=08 - - ; RMW pour écrire le FG - mov al, [es:di] ; Load latches - mov byte [es:di], 0xFF ; Write (les bits à 0 dans le masque sont protégés) - - ; TODO: Gestion Background (si non transparent) - ; Pour l'instant, transparent "additif" simple - - add di, EGA_STRIDE - dec bx - jnz .row_loop_a - - ; Restore Defaults - mov ax, 0xFF08 ; Bitmask FF - out dx, ax - mov ax, 0x0001 ; Disable Set/Reset - out dx, ax - jmp .done - - .unaligned: - ; Pour le cas non aligné, on utilise putpixel pour simplifier la conversion - ; ou on décale le masque. Pour ce snippet, fallback pixel-pixel simulé. - ; (Omis pour brièveté, le driver EGA standard préfère l'alignement byte) - - .done: - ; Avance curseur - add word [fs:BDA_GFX + gfx.cur_x], 8 - inc word [fs:BDA_GFX + gfx.cur_offset] - - call ega_mouse_show - pop es - pop fs - popa - leave - ret - -; ------------------------------------------------------------ -; ega_write -; ------------------------------------------------------------ -%define .txt_seg word [bp+4] -%define .txt_ofs word [bp+6] -ega_write: - push bp - mov bp, sp - push ax - push ds - mov ax, .txt_seg - mov ds, ax - mov si, .txt_ofs - .loops: - lodsb - cmp al,0 - je .done - push ax - call ega_putc - jmp .loops - .done: - pop ds - pop ax - leave - ret -%undef .txt_seg -%undef .txt_ofs - -; ------------------------------------------------------------ -; ega_putpixel (x,y,color) -; Utilise EGA Write Mode 2 pour modifier un pixel individuel -; ------------------------------------------------------------ -%define .x word [bp+4] -%define .y word [bp+6] -%define .color byte [bp+8] -ega_putpixel: - push bp - mov bp, sp - pusha - push es - - mov ax, VIDEO_SEG - mov es, ax - - call ega_mouse_hide - - mov cx, .x - mov dx, .y - call ega_calc_addr ; Return DI=Offset, AH=BitMask - - ; Setup EGA Hardware - mov dx, GC_INDEX - - ; 1. Set Bit Mask (AH calculé par calc_addr) - mov al, 0x08 - out dx, al - inc dx - mov al, ah - out dx, al - dec dx - - ; 2. Set Write Mode 2 - mov ax, 0x0205 ; Index 5 = Mode, Val = 2 - out dx, ax - - ; 3. Read-Modify-Write - ; Le Read charge les latches (les 4 plans) - mov al, [es:di] ; Dummy read - - ; 4. Write Color - ; En Mode 2, les bits 0-3 de la data CPU deviennent les valeurs pour les plans 0-3 - ; aux positions définies par le BitMask. - mov al, .color - mov [es:di], al - - ; 5. Reset Default (Write Mode 0, BitMask FF) - mov ax, 0x0005 - out dx, ax - mov ax, 0xFF08 - out dx, ax - - call ega_mouse_show - pop es - popa - leave - ret -%undef .x -%undef .y -%undef .color - -; ------------------------------------------------------------ -; ega_getpixel (x,y) -; Out: AL = Color (0-15) -; ------------------------------------------------------------ -%define .x word [bp+4] -%define .y word [bp+6] -ega_getpixel: - push bp - mov bp, sp - - - push di - push es - push dx - push cx - push bx - - mov cx, .x - mov dx, .y - mov ax, VIDEO_SEG - mov es, ax - call ega_calc_addr ; DI=Offset, AH=BitMask - - mov dx, GC_INDEX - - ; On doit lire plan par plan - ; Plan 0 - mov ax, 0x0004 ; Read Map Select = 0 - out dx, ax - mov al, [es:di] - and al, ah ; Apply Bitmask - setnz bl ; BL bit 0 - - ; Plan 1 - mov ax, 0x0104 - out dx, ax - mov al, [es:di] - and al, ah - setnz bh - shl bh, 1 - or bl, bh - - ; Plan 2 - mov ax, 0x0204 - out dx, ax - mov al, [es:di] - and al, ah - setnz bh - shl bh, 2 - or bl, bh - - ; Plan 3 - mov ax, 0x0304 - out dx, ax - mov al, [es:di] - and al, ah - setnz bh - shl bh, 3 - or bl, bh - - mov al, bl ; Result in AL - xor ah, ah - - pop bx - pop cx - pop dx - pop es - pop di - leave - ret -%undef .x -%undef .y - -; ------------------------------------------------------------ -; ega_background -; Remplissage rapide en Write Mode 0 + Map Mask -; ------------------------------------------------------------ -ega_background: - mov ax, VIDEO_SEG - mov es, ax - mov di, 0 - mov cx, 28000 ; 640 * 350 / 8 = 28000 bytes - - ; Couleur de fond (ex: Gris foncé 0x8 ? Ou pattern ?) - ; Pour checkerboard, c'est plus dur en planaire. - ; On va faire un gris simple pour l'exemple. - - mov dx, GC_INDEX - mov ax, 0x0F01 ; Enable Set/Reset all - out dx, ax - mov ax, 0x0100 ; Set Color 1 (Bleu) - out dx, ax - - mov al, 0xFF - rep stosb - - ; Reset - mov ax, 0x0001 - out dx, ax - ret - -; ------------------------------------------------------------ -; ega_line_horizontal -; Optimisé pour écriture par octets -; ------------------------------------------------------------ -%define .x1 word [bp+4] -%define .x2 word [bp+6] -%define .y word [bp+8] -%define .color byte [bp+10] -ega_line_horizontal: - push bp - mov bp, sp - pusha - push es - - mov ax, VIDEO_SEG - mov es, ax - call ega_mouse_hide - - mov ax, .x1 - mov bx, .x2 - cmp ax, bx - jle .sort_done - xchg ax, bx - .sort_done: - - ; Config EGA : Write Mode 0, Set Color - mov dx, GC_INDEX - mov ax, 0x0005 ; Mode 0 - out dx, ax - mov ax, 0x0F01 ; Enable Set/Reset - out dx, ax - mov ah, .color - and ah, 0x0F - mov al, 0x00 ; Index 0 (Set/Reset Color) - out dx, ax - - ; Calcul adresses - mov cx, ax ; save - mov cx, ax ; x1 - mov dx, .y - call ega_calc_addr_internal ; DI = Byte Offset - - ; Masque Gauche - mov cx, .x1 - and cx, 7 - xor cx, 7 ; Inversion endian bit - mov dh, 0xFF - shl dh, cl ; 11110000 (exemple) - - ; Masque Droite - mov cx, .x2 - and cx, 7 - xor cx, 7 - mov dl, 0xFF - inc cx - rol dl, cl ; Masque fin - - ; Indices Bytes - mov si, .x1 - shr si, 3 - mov bx, .x2 - shr bx, 3 - - cmp si, bx - je .single_byte - - ; Gauche - mov ah, dh - mov al, 0x08 ; BitMask Index - out dx, ax - mov al, [es:di] ; Load Latches - mov byte [es:di], 0xFF ; Write - inc di - inc si - - ; Milieu - mov ax, 0xFF08 ; Full Mask - out dx, ax - .mid_loop: - cmp si, bx - je .do_right - mov al, [es:di] - mov byte [es:di], 0xFF - inc di - inc si - jmp .mid_loop - - .do_right: - ; Droite - mov ah, dl - mov al, 0x08 - out dx, ax - mov al, [es:di] - mov byte [es:di], 0xFF - jmp .cleanup - - .single_byte: - and dh, dl ; Combine masks - mov ah, dh - mov al, 0x08 - out dx, ax - mov al, [es:di] - mov byte [es:di], 0xFF - - .cleanup: - ; Reset defaults - mov ax, 0xFF08 - out dx, ax - mov ax, 0x0001 - out dx, ax - - call ega_mouse_show - pop es - popa - leave - ret -%undef .x1 -%undef .x2 -%undef .y -%undef .color - -; ------------------------------------------------------------ -; ega_line_vertical -; ------------------------------------------------------------ -%define .x word [bp+4] -%define .y1 word [bp+6] -%define .y2 word [bp+8] -%define .color byte [bp+10] -ega_line_vertical: - push bp - mov bp, sp - pusha - push es - - mov ax, VIDEO_SEG - mov es, ax - call ega_mouse_hide - - mov bx, .y1 - mov dx, .y2 - cmp bx, dx - jle .y_ok - xchg bx, dx - .y_ok: - - mov cx, dx - sub cx, bx ; Height - inc cx - - ; Calcul adresse start - push cx - mov cx, .x - mov dx, bx - call ega_calc_addr ; DI start, AH mask - pop cx ; Restore Height - - ; Setup EGA - mov dx, GC_INDEX - mov al, 0x08 ; BitMask - out dx, al - inc dx - mov al, ah ; Le masque calculé - out dx, al - dec dx - - mov ax, 0x0205 ; Write Mode 2 - out dx, ax - - mov al, .color - - .v_loop: - mov ah, [es:di] ; Latch - mov [es:di], al ; Write Color - add di, EGA_STRIDE - loop .v_loop - - ; Reset - mov ax, 0x0005 - out dx, ax - mov ax, 0xFF08 - out dx, ax - - call ega_mouse_show - pop es - popa - leave - ret -%undef .x -%undef .y1 -%undef .y2 -%undef .color - -; ------------------------------------------------------------ -; Wrapper fonctions géométriques (inchangées logique high-level) -; ------------------------------------------------------------ -%define .x1 word [bp+4] -%define .y1 word [bp+6] -%define .x2 word [bp+8] -%define .y2 word [bp+10] -%define .color word [bp+12] -ega_draw_rect: - push bp - mov bp, sp - pusha - ; Simplifié: appels GFX internes - GFX LINE_HORIZ, .x1, .x2, .y1, .color - GFX LINE_HORIZ, .x1, .x2, .y2, .color - GFX LINE_VERT, .x1, .y1, .y2, .color - GFX LINE_VERT, .x2, .y1, .y2, .color - popa - leave - ret -%undef .x1 -%undef .y1 -%undef .x2 -%undef .y2 -%undef .color - -; ------------------------------------------------------------ -; ega_fill_rect -; Adapté pour EGA (plus complexe à cause des patterns et plans) -; Pour cette version, on fait un remplissage couleur unie simple -; si pattern_id < 4, sinon blanc. -; ------------------------------------------------------------ -%define .x1 word [bp+4] -%define .y1 word [bp+6] -%define .x2 word [bp+8] -%define .y2 word [bp+10] -%define .pat word [bp+12] -ega_fill_rect: - push bp - mov bp, sp - ; ... Implementation simplifiée utilisant des lignes horizontales - ; car le remplissage pattern 1bpp sur 4 plans EGA est verbeux - pusha - - mov cx, .y1 - mov dx, .y2 - cmp cx, dx - jle .loop - xchg cx, dx - .loop: - push cx - push dx - ; Couleur dérivée du pattern (simplification) - mov ax, .pat - cmp ax, 0 - je .blk - mov ax, 15 ; White - jmp .do_line - .blk: - mov ax, 0 - .do_line: - - GFX LINE_HORIZ, .x1, .x2, cx, ax - - pop dx - pop cx - inc cx - cmp cx, dx - jle .loop - - popa - leave - ret -%undef .x1 -%undef .y1 -%undef .x2 -%undef .y2 -%undef .pat - -; ------------------------------------------------------------ -; ega_draw_rounded_frame (Identique CGA, appels GFX) -; ------------------------------------------------------------ -%define .x1 word [bp+4] -%define .y1 word [bp+6] -%define .x2 word [bp+8] -%define .y2 word [bp+10] -%define .color word [bp+12] -ega_draw_rounded_frame: - push bp - mov bp, sp - pusha - call ega_mouse_hide - - mov ax, .x1 - add ax, 2 - mov bx, .x2 - sub bx, 2 - GFX LINE_HORIZ, ax, bx, .y1, .color - GFX LINE_HORIZ, ax, bx, .y2, .color - - mov cx, .y1 - add cx, 2 - mov dx, .y2 - sub dx, 2 - GFX LINE_VERT, .x1, cx, dx, .color - GFX LINE_VERT, .x2, cx, dx, .color - - ; Coins (PutPixel wrappers) - mov ax, .x1 - inc ax - mov bx, .y1 - inc bx - GFX PUTPIXEL, ax, bx, .color - - mov ax, .x1 - inc ax - mov bx, .y2 - dec bx - GFX PUTPIXEL, ax, bx, .color - - mov ax, .x2 - dec ax - mov bx, .y1 - inc bx - GFX PUTPIXEL, ax, bx, .color - - mov ax, .x2 - dec ax - mov bx, .y2 - dec bx - GFX PUTPIXEL, ax, bx, .color - - call ega_mouse_show - popa - leave - ret -%undef .x1 -%undef .y1 -%undef .x2 -%undef .y2 -%undef .color - -; ============================================================ -; GESTION SOURIS EGA -; ============================================================ -; Le buffer souris doit être plus grand : 16x16 pixels -; = 2 octets de large x 16 haut x 4 plans = 128 bytes. -; ============================================================ - -ega_mouse_hide: - pushf - cli - pushad - push ds - mov ax, BDA_DATA_SEG - mov ds, ax - dec byte [BDA_MOUSE + mouse.cur_counter] - cmp byte [BDA_MOUSE + mouse.cur_counter], -1 - jne .skip - call ega_cursor_restorebg - .skip: - pop ds - popad - popf - ret - -ega_mouse_show: - pushf - cli - pushad - push ds - mov ax, BDA_DATA_SEG - mov ds, ax - inc byte [BDA_MOUSE + mouse.cur_counter] - cmp byte [BDA_MOUSE + mouse.cur_counter], 0 - jne .skip - call ega_cursor_savebg - call ega_cursor_draw - .skip: - pop ds - popad - popf - ret - -ega_mouse_cursor_move: - pushad - push ds - push es - mov ax, BDA_DATA_SEG - mov ds, ax - cmp byte [BDA_MOUSE + mouse.cur_counter], 0 - jl .done - cmp byte [BDA_MOUSE + mouse.cur_drawing], 0 - jne .done - mov byte [BDA_MOUSE + mouse.cur_drawing], 1 - - mov ax, VIDEO_SEG - mov es, ax - - call ega_cursor_restorebg - call ega_cursor_savebg - call ega_cursor_draw - - mov byte [BDA_MOUSE + mouse.cur_drawing], 0 - .done: - pop es - pop ds - popad - ret - -; ------------------------------------------------------------ -; Save Background (4 planes) -; Lit 2 octets par ligne (16px large), sur 16 lignes, sur 4 plans -; Buffer size needed ~ 128 bytes -; ------------------------------------------------------------ -ega_cursor_savebg: - cmp byte [BDA_MOUSE + mouse.bkg_saved], 0 - jne .done - - push es - mov ax, VIDEO_SEG - mov es, ax - - ; Calc Offset - mov cx, [BDA_MOUSE + mouse.x] - mov dx, [BDA_MOUSE + mouse.y] - mov [BDA_MOUSE + mouse.cur_x], cx - mov [BDA_MOUSE + mouse.cur_y], dx - call ega_calc_addr_internal ; DI = Offset - - mov [BDA_MOUSE + mouse.cur_addr_start], di - lea si, [BDA_MOUSE + mouse.bkg_buffer] - - mov dx, GC_INDEX - - ; Boucle sur les 4 plans - mov bl, 0 ; Plan index - .plane_loop: - mov ah, bl - mov al, 0x04 ; Read Map Select - out dx, ax - - push di ; Save screen offset start - mov cx, 16 ; Height - .row_loop: - mov al, [es:di] ; Byte 1 - mov [ds:si], al - inc si - mov al, [es:di+1] ; Byte 2 (Cursor is 16px wide max) - mov [ds:si], al - inc si - add di, EGA_STRIDE - loop .row_loop - pop di ; Restore screen offset - - inc bl - cmp bl, 4 - jl .plane_loop - - mov byte [BDA_MOUSE + mouse.bkg_saved], 1 - .done: - pop es - ret - -; ------------------------------------------------------------ -; Restore Background -; ------------------------------------------------------------ -ega_cursor_restorebg: - cmp byte [BDA_MOUSE + mouse.bkg_saved], 0 - je .done - - push es - mov ax, VIDEO_SEG - mov es, ax - - mov di, [BDA_MOUSE + mouse.cur_addr_start] - lea si, [BDA_MOUSE + mouse.bkg_buffer] - - mov dx, GC_INDEX - mov ax, 0x0005 ; Write Mode 0 - out dx, ax - mov ax, 0xFF08 ; Mask all - out dx, ax - - mov dx, SC_INDEX ; Sequencer pour Map Mask - - mov bl, 1 ; Map Mask bit (Plan 0 = 1) - .plane_loop: - mov al, SC_MAP_MASK - mov ah, bl - out dx, ax ; Select Plane to write - - push di - mov cx, 16 - .row_loop: - lodsb ; Load Byte 1 from buffer - mov [es:di], al - lodsb ; Load Byte 2 - mov [es:di+1], al - add di, EGA_STRIDE - loop .row_loop - pop di - - shl bl, 1 - cmp bl, 16 ; Bit 4 = Fin - jl .plane_loop - - ; Restore Map Mask to All - mov ax, 0x0F02 - out dx, ax - - mov byte [BDA_MOUSE + mouse.bkg_saved], 0 - pop es - .done: - ret - -; ------------------------------------------------------------ -; Draw Cursor (Fleche simple, Write Mode 2 ou Masking) -; Pour simplicité : on dessine un bloc blanc 8x8 via PutPixel -; ou un sprite hardcodé. -; ------------------------------------------------------------ -ega_cursor_draw: - pushad - push es - mov ax, VIDEO_SEG - mov es, ax - - ; Utilisation d'un masque simple pour dessiner une croix - ; X, Y centre - mov cx, [BDA_MOUSE + mouse.x] - mov dx, [BDA_MOUSE + mouse.y] - - ; Dessine une croix rouge (Color 4) de 10x10 - mov bx, 10 - .l1: - ; Horizontal - mov ax, cx - add ax, bx - GFX PUTPIXEL, ax, dx, 4 - ; Vertical - mov ax, dx - add ax, bx - GFX PUTPIXEL, cx, ax, 4 - dec bx - jnz .l1 - - pop es - popad - ret \ No newline at end of file