From c8858526a6796be2508f299ead51a3b45ee36a45 Mon Sep 17 00:00:00 2001 From: Frater <13979047+saintfrater@users.noreply.github.com> Date: Wed, 21 Jan 2026 22:22:14 +0100 Subject: [PATCH] going to 32bits --- src/bda.asm | 7 +- src/boot.asm | 4 +- src/drivers/gfx_cgam.asm | 629 ++++++++++++++++++++++++++++++-------- src/drivers/mouse_ps2.asm | 2 +- 4 files changed, 505 insertions(+), 137 deletions(-) diff --git a/src/bda.asm b/src/bda.asm index 9a06108..d7f7a37 100644 --- a/src/bda.asm +++ b/src/bda.asm @@ -50,6 +50,11 @@ %define BDA_DATA_SEG 0x0050 %define BDA_MOUSE 0x0000 +%define BKG_DWORDS_PER_LINE 1 ; 1 dword stocké par ligne +%define BKG_LINES 16 +%define BKG_TOTAL_DWORDS (BKG_LINES * BKG_DWORDS_PER_LINE) ; 16 +%define BKG_TOTAL_BYTES (BKG_TOTAL_DWORDS * 4) ; 64 + struc mouse .buffer resb 4 ; i8042 input buffer .idx resb 1 ; index in the buffer @@ -71,7 +76,7 @@ struc mouse .cur_mask resb 1 ; pixels mask (bit per pixel) .cur_bit_ofs resb 1 ; 0..7 bits d'offset (x&7) .bkg_saved resb 1 ; background saved - .bkg_buffer resb 16*3 ; buffer for saved background + .bkg_buffer resd 16 ; buffer for saved background endstruc %define BDA_TIMER (BDA_MOUSE + mouse_size) diff --git a/src/boot.asm b/src/boot.asm index 4fa94b0..d4771c4 100644 --- a/src/boot.asm +++ b/src/boot.asm @@ -96,7 +96,7 @@ reset: ; call mouse_reset call mouse_init - call gfx_cursor_move + ; call gfx_cursor_move endless: mov ax,BDA_DATA_SEG @@ -120,7 +120,7 @@ endless: .moveok: mov [BDA_MOUSE + mouse.x],ax ; - call gfx_cursor_move + ; call gfx_cursor_move cmp byte [BDA_MOUSE + mouse.buffer+1], 0 jge .skip diff --git a/src/drivers/gfx_cgam.asm b/src/drivers/gfx_cgam.asm index 0a6ef1f..e635b89 100644 --- a/src/drivers/gfx_cgam.asm +++ b/src/drivers/gfx_cgam.asm @@ -200,13 +200,14 @@ gfx_getpixel: gfx_background: mov ax,VIDEO_SEG mov es,ax - xor di,di - mov ax,0xaaaa - mov cx,0x1000 - rep stosw - mov ax,0x5555 - mov cx,0x1000 ; 640/8/2 - rep stosw + mov di,0x0000 + mov eax,0xaaaaaaaa + mov cx,0x800 + rep stosd + mov di,0x2000 + mov eax,0x55555555 + mov cx,0x800 ; 640/8/4 + rep stosd ret ; ------------------------------------------------------------ @@ -277,12 +278,315 @@ gfx_cursor_move: popa ret +; ============================================================ +; gfx_draw_cursor (CPU>=386, bits 16) - PAS de clamp +; x:0..639, y:0..199 +; clipping droite/bas: +; width = min(16, 640-x) +; height = min(16, 200-y) +; bytes_to_touch = ((off + width + 7) >> 3) ; 1..3 +; +; Requiert: +; gfx_calc_addr (CX=x, DX=y) => DI (bank incluse) +; sprite en GS:SI (AND[16w] puis XOR[16w] à +32) +; +; ============================================================ +gfx_cursor_draw: + push ds + push es + push gs + pusha + + mov ax, BDA_DATA_SEG + mov ds, ax + + ; GS:SI sprite + mov ax, [BDA_MOUSE + mouse.cur_seg] + mov gs, ax + mov si, [BDA_MOUSE + mouse.cur_ofs] + + ; ES VRAM + mov ax, VIDEO_SEG + mov es, ax + + ; x,y + mov cx, [BDA_MOUSE + mouse.x] + mov dx, [BDA_MOUSE + mouse.y] + + ; off = x&7 -> BL + mov bl, cl + and bl, 7 + + ; width = min(16, 640-x) -> AL + mov ax, 640 + sub ax, cx + cmp ax, 16 + jbe .w_ok + mov ax, 16 +.w_ok: + ; AL = width + test al, al + jz .done + + ; height = min(16, 200-y) -> DL + mov bp, 200 + sub bp, dx + cmp bp, 16 + jbe .h_ok + mov bp, 16 +.h_ok: + mov ax, bp + mov dl, al ; DL = height + test dl, dl + jz .done + + ; bytes_to_touch = ((off + width + 7) >> 3) -> BH + mov ah, bl + add ah, al + add ah, 7 + shr ah, 3 + mov bh, ah ; BH=1..3 + + ; clip_mask16 = 0xFFFF << (16-width) -> BP + mov bp, 0FFFFh + mov cl, 16 + sub cl, al + shl bp, cl ; BP = clipmask + + ; DI pour (x,y) + call gfx_calc_addr + + ; bank_add = +0x2000 si DI<0x2000 sinon -0x2000 -> BX + mov bx, 02000h + cmp di, bx + jl .bank_ok + neg bx +.bank_ok: + + ; AL = row (0..15) + xor ax, ax ; AL=0, AH=0 + ; AH = toggle bank flag: + ; 0 => prochaine ligne: DI += BX + ; 1 => prochaine ligne: DI -= BX, DI += 80 + xor ah, ah + +.line_loop: + push ax ; préserver row(AL) + toggle(AH) (draw_line_masked détruit AX) + + ; charge AND'/XOR' clippés pour row=AL -> CX/DX + call .load_andxor_clipped + + ; dessine la ligne: ES:DI, BL=off, BH=bytes, CX=AND', DX=XOR' + call draw_line_masked + + pop ax ; restore row/toggle + + ; next line + inc al + dec dl + jz .done + + ; alternance banks et stride CGA + test ah, ah + jnz .to_base + + ; vers autre bank + add di, bx + mov ah, 1 + jmp .line_loop + +.to_base: + sub di, bx + add di, CGA_STRIDE + xor ah, ah + jmp .line_loop + +.done: + popa + pop gs + pop es + pop ds + ret + + +; ------------------------------------------------------------ +; .load_andxor_clipped +; Entrées: +; AL = row (0..15) +; GS:SI = base sprite +; BP = clipmask16 +; Sorties: +; CX = AND' , DX = XOR' +; Détruit: +; AX, DI (DI restauré) +; ------------------------------------------------------------ +.load_andxor_clipped: + push di + xor ah, ah + shl ax, 1 ; AX = row*2 + + mov di, si + add di, ax + mov cx, [gs:di] ; AND + add di, 32 + mov dx, [gs:di] ; XOR + + ; AND' = AND | (~clipmask) + ; XOR' = XOR & clipmask + mov ax, bp + not ax + or cx, ax + and dx, bp + + pop di + ret + + +; ============================================================ +; draw_line_masked (NASM bits16, CPU 386+ ok, pas de bpl/sil) +; +; Entrées: +; ES:DI = adresse b0 +; BL = off (0..7) +; BH = bytes_to_touch (1..3) +; CX = AND' +; DX = XOR' +; +; Détruit: AX,BP,SI,CL,DL,DH,AH +; (ok car caller recharge CX/DX à chaque ligne) +; ============================================================ +draw_line_masked: + push si + push bp + + ; w0 = (b0<<8)|b1 dans SI + mov al, [es:di] + mov ah, [es:di+1] + xchg al, ah + mov si, ax + + ; seg in AX + mov ax, si + test bl, bl + jz .seg_ready + + cmp bh, 3 + jne .seg_no_b2 + + ; BP = w1 = (b1<<8)|b2 + mov al, [es:di+1] + mov ah, [es:di+2] + xchg al, ah + mov bp, ax + + mov ax, si ; AX=w0 + mov cl, bl + shl ax, cl + mov cl, 8 + sub cl, bl + shr bp, cl + or ax, bp + jmp .seg_ready + +.seg_no_b2: + mov cl, bl + shl ax, cl + +.seg_ready: + ; newseg in BP + and ax, cx + xor ax, dx + mov bp, ax + + test bl, bl + jz .write_aligned + + ; -------- b0 partiel -------- + ; val0 = newseg >> (8+off) dans AL + mov ax, bp + mov cl, bl + add cl, 8 + shr ax, cl ; AL=val0 + + ; mask0 = (1<<(8-off))-1 dans AH + mov cl, 8 + sub cl, bl + mov ah, 1 + shl ah, cl + dec ah + + ; b0 = (b0 & ~mask0) | (val0 & mask0) + mov dl, [es:di] + mov dh, ah + not dh + and dl, dh + not dh + and al, dh + or dl, al + mov [es:di], dl + + cmp bh, 1 + je .ret + + ; -------- b1 complet -------- + mov ax, bp + mov cl, bl + shr ax, cl ; AL=b1 + mov [es:di+1], al + + cmp bh, 2 + je .ret + + ; -------- b2 partiel -------- + mov ax, bp ; AL=newseg low + + ; lowmask = (1<>(8-off)) --- + mov cl, bl + shl ax, cl + mov cl, 8 + sub cl, bl + shr bp, cl + or ax, bp ; AX = seg - ; seg = (w0<>(8-off)) - ; off = BL, rshift = (8-BL) - push bx ; sauvegarde row/off - mov cl, bl - shl ax, cl ; AX = w0<>(8-off) + ; --- write unaligned --- + ; b0 + mov bp, ax + mov cl, bl + add cl, 8 + shr bp, cl ; BP = val0 + mov dl, 1 + mov cl, 8 + sub cl, bl + shl dl, cl + dec dl ; mask0 + mov dh, [es:di] + not dl + and dh, dl + not dl + or dh, bl + mov [es:di], dh - or ax, dx ; AX = seg (16 bits alignés) - pop bx + ; b1 + mov cl, bl + shr ax, cl + mov [es:di+1], al - jmp .apply_masks + ; b2 + mov ax, bp + mov cl, bl + ; and al, (1<> (8+off) - ; (8+off) = 8 + BL - mov dx, ax - mov cl, bl - add cl, 8 - shr dx, cl ; DL = val0 (0..(2^(8-off)-1)) - - ; mask0 = (1<> off) & 0xFF - mov dx, ax - mov cl, bl - shr dx, cl - inc di - mov [es:di], dl - dec di - - ; b2 high off bits = (newseg & ((1<