fixed putch/writestring

This commit is contained in:
Frater 2026-01-25 21:15:19 +01:00
commit dcf67075e5
10 changed files with 1984 additions and 697 deletions

View file

@ -48,7 +48,6 @@
; information relative à la souris ; information relative à la souris
; ;
%define BDA_DATA_SEG 0x0050 %define BDA_DATA_SEG 0x0050
%define BDA_MOUSE 0x0000
%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
@ -56,30 +55,57 @@
%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_bank_add resw 1 ; + ou - 0x2000 .cur_bank_add resw 1 ; + ou - 0x2000
.cur_drawing resb 1 .cur_drawing resb 1
.cur_visible resb 1 .cur_visible resb 1
.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
.cur_mask resb 1 ; pixels mask (bit per pixel) .cur_mask resb 1 ; pixels mask (bit per pixel)
.cur_bit_ofs resb 1 ; 0..7 bits d'offset (x&7) .cur_bit_ofs resb 1 ; 0..7 bits d'offset (x&7)
.bkg_saved resb 1 ; background saved .bkg_saved resb 1 ; background saved
.bkg_buffer resd 16 ; buffer for saved background alignb 4 ; alignement 4 bytes
.bkg_buffer resd 16 ; buffer for saved background
endstruc endstruc
%define BDA_TIMER (BDA_MOUSE + mouse_size) struc gfx
.cur_x resw 1 ; x,y en pixel
.cur_y resw 1
.cur_offset resw 1 ; offset calculé pour le prochain caractère
.cur_line_ofs resw 1 ; "interligne" +2000h ou -2000h
; .cur_xbyte resb 1 ; x>>3 (0..79)
.cur_shift resb 1 ; x&7 (0..7)
; .cur_parity resb 1
; .cur_color resb 1 ; 0 = texte en noir, autre = texte en blanc
; .cur_trans resb 1 ; 0 = fond transparent, autre = fond inversé .txt_color
.cur_mode resb 1 ;
endstruc
%define BDA_MOUSE 0x0000
%define BDA_GFX (BDA_MOUSE + mouse_size)
;
; memory map
;
; 0x00000-0x003FF : IVT (1kB)
; 0x00400-0x007FF : BDA (1kB) pour les options 'ROMS' carte graphique, etc...
; 0x00800-0x009FF : Varibles custom.
;
; 0x03C00-0x08000 : stack segment
; 0x
; ----------------------------------------------------------------------------------- ; -----------------------------------------------------------------------------------
; PC components I/O ports ; PC components I/O ports

View file

@ -26,13 +26,16 @@ bits 16
; configuration du bios ; configuration du bios
; ;
; --------------------------------------------------------------------------- ; ---------------------------------------------------------------------------
%define DEBUG_PORT 0xe9 ; 0x402 ou 0xe9 %define DEBUG_PORT 0xe9 ; 0x402 ou 0xe9
; initial stack ; initial stack
%define STACK_SEG 0x1000 ; segment de base %define STACK_SEG 0x0800 ; segment de base
section .text section .text
bits 16 bits 16
;%include "./common/chartable.asm"
;%include "./common/cursor.asm"
; definition du BDA ; definition du BDA
%include "./bda.asm" %include "./bda.asm"
@ -44,152 +47,188 @@ bits 16
%include "./drivers/keyboard_ps2.asm" %include "./drivers/keyboard_ps2.asm"
%include "./services/generic.asm" %include "./services/generic.asm"
err_vganok db 'VGA Not Initialized',0 err_vganok db 'VGA Not Initialized',0
;err_end db 'code completed successfully',0 ;err_end db 'code completed successfully',0
cpt_txt db '0123456789A123456789B123456789C123456789D123456789E123456789F123456789',0
helloworld db 'Hello World !',0
reset: reset:
cli cli
cld ; il n'existe aucun 'stack' par défaut
mov ax, STACK_SEG
mov ss, ax
mov sp, 0xFFFE ; haut du segment (64ko de stack), mot-aligné
cld
; il n'existe aucun 'stack' par défaut ; installé une table d'interruption "dummy"
mov ax, STACK_SEG call ivt_setup
mov ss, ax
mov sp, 0xFFFE ; haut du segment (64ko de stack), mot-aligné
; installé une table d'interruption "dummy" call bda_setup
call ivt_setup
call bda_setup ; test IRQ 0
mov ax,cs
mov dx,ax
mov bx,test_isr
mov ax,i8259_MASTER_INT
; test IRQ 0 call ivt_setvector
mov ax,cs
mov dx,ax
mov bx,test_isr
mov ax,i8259_MASTER_INT
call ivt_setvector ; initialisation des PIC 8259A
call pic_init
; initialisation des PIC 8259A ; load Roms
call pic_init call setup_load_rom
; load Roms ; on vérifie que le BIOS VGA a installé une INT 10h
call setup_load_rom call setup_check_vga
; on vérifie que le BIOS VGA a installé une INT 10h ; on initialise le mode texte 80x25 par défaut DEBUG
call setup_check_vga ;mov ax, 0x0003
;int 10h
; on initialise le mode texte 80x25 par défaut DEBUG ; enable IRQ 0
;mov ax, 0x0003 mov ah,IRQ_ENABLED
;int 10h mov al,0
call pic_set_irq_mask
; enable IRQ 0 call kbd_init
mov ah,IRQ_ENABLED sti
mov al,0
call pic_set_irq_mask
call kbd_init ; on active le mode graphique
sti GFX_DRV GFX_INIT
; on active le mode graphique call mouse_reset
call gfx_init ;call mouse_init
call mouse_reset ; GFX_DRV GFX_CRS_UPDATE
; call mouse_init
call gfx_cursor_move GFX_SET_WRTIE_MODE GFX_TXT_BLACK_ON_WHITE
xor cx,cx
mov dx,0
GFX_DRV GFX_GOTOXY
push cs
pop ds
mov si, cpt_txt
GFX_DRV GFX_WRITE
GFX_SET_WRTIE_MODE GFX_TXT_WHITE_TRANSPARENT
mov cx,8
mov dx,8
GFX_DRV GFX_GOTOXY
mov si, helloworld
GFX_DRV GFX_WRITE
mov cx,8
mov dx,24
GFX_SET_WRTIE_MODE 0
.loopshift:
GFX_DRV GFX_GOTOXY
mov si, helloworld
GFX_DRV GFX_WRITE
add dx,8
inc cx
cmp cx,16
jbe .loopshift
endless: endless:
mov ax,BDA_DATA_SEG mov ax,BDA_DATA_SEG
mov ds,ax mov ds,ax
;mov dx,0x300 ;mov dx,0x300
;call scr_gotoxy ;call scr_gotoxy
;mov al, byte [BDA_TIMER] ;mov al, byte [BDA_TIMER]
;call scr_puthex8 ;call scr_puthex8
cmp byte [BDA_TIMER],5 ;cmp byte [BDA_TIMER],5
ja .skip2 ;ja .skip2
mov ax, [BDA_MOUSE + mouse.x] ;mov ax, [BDA_MOUSE + mouse.x]
add ax, 25 ;add ax, 25
cmp ax,640 ;cmp ax,640
jb .moveok ;jb .moveok
; ;
mov ax,0 mov ax,0
.moveok: .moveok:
mov [BDA_MOUSE + mouse.x],ax mov [BDA_MOUSE + mouse.x],ax
; ;
call gfx_cursor_move GFX_DRV GFX_CRS_UPDATE
cmp byte [BDA_MOUSE + mouse.buffer+1], 0 cmp byte [BDA_MOUSE + mouse.buffer+1], 0
jge .skip jge .skip
;mov dx,0x400 ;mov dx,0x400
;call scr_gotoxy ;call scr_gotoxy
;mov al, byte [BDA_MOUSE + mouse.buffer+1] ;mov al, byte [BDA_MOUSE + mouse.buffer+1]
;call scr_puthex8 ;call scr_puthex8
.skip: .skip:
;cmp byte [BDA_MOUSE + mouse.buffer+2], 0 ;cmp byte [BDA_MOUSE + mouse.buffer+2], 0
;jge .skip2 ;jge .skip2
;mov dx,0x404 ;mov dx,0x404
;call scr_gotoxy ;call scr_gotoxy
;mov al, byte [BDA_MOUSE + mouse.buffer+2] ;mov al, byte [BDA_MOUSE + mouse.buffer+2]
;call scr_puthex8 ;call scr_puthex8
.skip2: .skip2:
;mov dx,0 ;mov dx,0
;call scr_gotoxy ;call scr_gotoxy
;mov ax,[BDA_MOUSE] ; adresse début dump ;mov ax,[BDA_MOUSE] ; adresse début dump
;mov si,ax ;mov si,ax
mov cx, 0x20 mov cx, 0x20
.dump: .dump:
; test cx,0x000F ; test cx,0x000F
; jnz .sameline ; jnz .sameline
; inc dh ; inc dh
; xor dl,dl ; xor dl,dl
; call scr_gotoxy ; call scr_gotoxy
;.sameline: ;.sameline:
; mov al,[ds:si] ; mov al,[ds:si]
; inc si ; inc si
; push ds ; push ds
; push si ; push si
; call scr_puthex8 ; call scr_puthex8
; mov al,' ' ; mov al,' '
; call scr_putc ; call scr_putc
; pop si ; pop si
; pop ds ; pop ds
nop nop
loop .dump loop .dump
jmp endless jmp endless
; ----------------------------------------------------------- ; -----------------------------------------------------------
; Keyboard ISR (IRQ -> INT) ; timer ISR (IRQ -> INT)
; ----------------------------------------------------------- ; -----------------------------------------------------------
test_isr: test_isr:
push ax push ax
push fs push fs
mov ax,BDA_DATA_SEG mov ax,BDA_DATA_SEG
mov fs,ax mov fs,ax
inc byte [fs:BDA_TIMER] ; inc byte [fs:BDA_TIMER]
mov al, PIC_EOI ; EOI master mov al, PIC_EOI ; EOI master
out i8259_MASTER_CMD, al out i8259_MASTER_CMD, al
pop fs pop fs
pop ax pop ax
iret iret
; ------------------------------------------------------------------ ; ------------------------------------------------------------------
; Padding jusqu'au reset vector ; Padding jusqu'au reset vector
@ -200,13 +239,15 @@ times 0xFFF0 - ($ - $$) db 0xFF
; RESET VECTOR (exécuté par le CPU) ; RESET VECTOR (exécuté par le CPU)
; ------------------------------------------------------------------ ; ------------------------------------------------------------------
section .resetvect section .resetvect
bits 16 bits 16
global reset_vector global reset_vector
reset_vector: reset_vector:
; code minimal au reset ; code minimal au reset
jmp 0xF000:reset jmp 0xF000:reset
builddate db '06/01/2026'
times 16-($-$$) db 0 ; le stub tient dans 16 octets (ou moins) builddate:
db '06/01/2026'
times 16-($-$$) db 0 ; le stub tient dans 16 octets (ou moins)

102
src/common/chartable-1.asm Normal file
View file

@ -0,0 +1,102 @@
; ============================================================================
; Font 8x8 (printable ASCII 0x20..0x7E) -> 95 glyphs * 8 = 760 bytes
; - bit7 = gauche, bit0 = droite
; - 1 byte = 1 scanline (haut -> bas)
; ============================================================================
font8x8:
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ; 0x20 ' '
db 0x18,0x18,0x18,0x18,0x18,0x00,0x18,0x00 ; 0x21 '!'
db 0x66,0x66,0x24,0x00,0x00,0x00,0x00,0x00 ; 0x22 '"'
db 0x24,0x24,0x7E,0x24,0x7E,0x24,0x24,0x00 ; 0x23 '#'
db 0x18,0x3E,0x60,0x3C,0x06,0x7C,0x18,0x00 ; 0x24 '$'
db 0x62,0x66,0x0C,0x18,0x30,0x66,0x46,0x00 ; 0x25 '%'
db 0x38,0x6C,0x38,0x76,0xDC,0xCC,0x76,0x00 ; 0x26 '&'
db 0x18,0x18,0x30,0x00,0x00,0x00,0x00,0x00 ; 0x27 '''
db 0x0C,0x18,0x30,0x30,0x30,0x18,0x0C,0x00 ; 0x28 '('
db 0x30,0x18,0x0C,0x0C,0x0C,0x18,0x30,0x00 ; 0x29 ')'
db 0x00,0x66,0x3C,0xFF,0x3C,0x66,0x00,0x00 ; 0x2A '*'
db 0x00,0x18,0x18,0x7E,0x18,0x18,0x00,0x00 ; 0x2B '+'
db 0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x30 ; 0x2C ','
db 0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x00 ; 0x2D '-'
db 0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00 ; 0x2E '.'
db 0x06,0x0C,0x18,0x30,0x60,0xC0,0x80,0x00 ; 0x2F '/'
db 0x3C,0x66,0x6E,0x76,0x66,0x66,0x3C,0x00 ; 0x30 '0'
db 0x18,0x38,0x18,0x18,0x18,0x18,0x3C,0x00 ; 0x31 '1'
db 0x3C,0x66,0x06,0x0C,0x18,0x30,0x7E,0x00 ; 0x32 '2'
db 0x3C,0x66,0x06,0x1C,0x06,0x66,0x3C,0x00 ; 0x33 '3'
db 0x0C,0x1C,0x3C,0x6C,0x7E,0x0C,0x0C,0x00 ; 0x34 '4'
db 0x7E,0x60,0x7C,0x06,0x06,0x66,0x3C,0x00 ; 0x35 '5'
db 0x1C,0x30,0x60,0x7C,0x66,0x66,0x3C,0x00 ; 0x36 '6'
db 0x7E,0x66,0x06,0x0C,0x18,0x18,0x18,0x00 ; 0x37 '7'
db 0x3C,0x66,0x66,0x3C,0x66,0x66,0x3C,0x00 ; 0x38 '8'
db 0x3C,0x66,0x66,0x3E,0x06,0x0C,0x38,0x00 ; 0x39 '9'
db 0x00,0x18,0x18,0x00,0x00,0x18,0x18,0x00 ; 0x3A ':'
db 0x00,0x18,0x18,0x00,0x00,0x18,0x18,0x30 ; 0x3B ';'
db 0x0E,0x1C,0x38,0x70,0x38,0x1C,0x0E,0x00 ; 0x3C '<'
db 0x00,0x00,0x7E,0x00,0x7E,0x00,0x00,0x00 ; 0x3D '='
db 0x70,0x38,0x1C,0x0E,0x1C,0x38,0x70,0x00 ; 0x3E '>'
db 0x3C,0x66,0x06,0x0C,0x18,0x00,0x18,0x00 ; 0x3F '?'
db 0x3C,0x66,0x6E,0x6A,0x6E,0x60,0x3C,0x00 ; 0x40 '@'
db 0x18,0x3C,0x66,0x66,0x7E,0x66,0x66,0x00 ; 0x41 'A'
db 0x7C,0x66,0x66,0x7C,0x66,0x66,0x7C,0x00 ; 0x42 'B'
db 0x3C,0x66,0x60,0x60,0x60,0x66,0x3C,0x00 ; 0x43 'C'
db 0x78,0x6C,0x66,0x66,0x66,0x6C,0x78,0x00 ; 0x44 'D'
db 0x7E,0x60,0x60,0x7C,0x60,0x60,0x7E,0x00 ; 0x45 'E'
db 0x7E,0x60,0x60,0x7C,0x60,0x60,0x60,0x00 ; 0x46 'F'
db 0x3C,0x66,0x60,0x6E,0x66,0x66,0x3C,0x00 ; 0x47 'G'
db 0x66,0x66,0x66,0x7E,0x66,0x66,0x66,0x00 ; 0x48 'H'
db 0x3C,0x18,0x18,0x18,0x18,0x18,0x3C,0x00 ; 0x49 'I'
db 0x1E,0x0C,0x0C,0x0C,0x0C,0x6C,0x38,0x00 ; 0x4A 'J'
db 0x66,0x6C,0x78,0x70,0x78,0x6C,0x66,0x00 ; 0x4B 'K'
db 0x60,0x60,0x60,0x60,0x60,0x60,0x7E,0x00 ; 0x4C 'L'
db 0x63,0x77,0x7F,0x6B,0x63,0x63,0x63,0x00 ; 0x4D 'M'
db 0x66,0x76,0x7E,0x7E,0x6E,0x66,0x66,0x00 ; 0x4E 'N'
db 0x3C,0x66,0x66,0x66,0x66,0x66,0x3C,0x00 ; 0x4F 'O'
db 0x7C,0x66,0x66,0x7C,0x60,0x60,0x60,0x00 ; 0x50 'P'
db 0x3C,0x66,0x66,0x66,0x6E,0x3C,0x0E,0x00 ; 0x51 'Q'
db 0x7C,0x66,0x66,0x7C,0x78,0x6C,0x66,0x00 ; 0x52 'R'
db 0x3C,0x66,0x60,0x3C,0x06,0x66,0x3C,0x00 ; 0x53 'S'
db 0x7E,0x18,0x18,0x18,0x18,0x18,0x18,0x00 ; 0x54 'T'
db 0x66,0x66,0x66,0x66,0x66,0x66,0x3C,0x00 ; 0x55 'U'
db 0x66,0x66,0x66,0x66,0x66,0x3C,0x18,0x00 ; 0x56 'V'
db 0x63,0x63,0x63,0x6B,0x7F,0x77,0x63,0x00 ; 0x57 'W'
db 0x66,0x66,0x3C,0x18,0x3C,0x66,0x66,0x00 ; 0x58 'X'
db 0x66,0x66,0x66,0x3C,0x18,0x18,0x18,0x00 ; 0x59 'Y'
db 0x7E,0x06,0x0C,0x18,0x30,0x60,0x7E,0x00 ; 0x5A 'Z'
db 0x3C,0x30,0x30,0x30,0x30,0x30,0x3C,0x00 ; 0X5B '['
db 0xC0,0x60,0x30,0x18,0x0C,0x06,0x02,0x00 ; 0x5C '\'
db 0x3C,0x0C,0x0C,0x0C,0x0C,0x0C,0x3C,0x00 ; 0x5D ']'
db 0x10,0x38,0x6C,0xC6,0x00,0x00,0x00,0x00 ; 0x5E '^'
db 0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00 ; 0x5F '_'
db 0x30,0x18,0x0C,0x00,0x00,0x00,0x00,0x00 ; 0x60 '`'
db 0x00,0x00,0x3C,0x06,0x3E,0x66,0x3E,0x00 ; 0x61 'a'
db 0x60,0x60,0x7C,0x66,0x66,0x66,0x7C,0x00 ; 0x62 'b'
db 0x00,0x00,0x3C,0x66,0x60,0x66,0x3C,0x00 ; 0x63 'c'
db 0x06,0x06,0x3E,0x66,0x66,0x66,0x3E,0x00 ; 0x64 'd'
db 0x00,0x00,0x3C,0x66,0x7E,0x60,0x3C,0x00 ; 0x65 'e'
db 0x1C,0x30,0x30,0x7C,0x30,0x30,0x30,0x00 ; 0x66 'f'
db 0x00,0x00,0x3E,0x66,0x66,0x3E,0x06,0x3C ; 0x67 'g'
db 0x60,0x60,0x7C,0x66,0x66,0x66,0x66,0x00 ; 0x68 'h'
db 0x18,0x00,0x38,0x18,0x18,0x18,0x3C,0x00 ; 0x69 'i'
db 0x0C,0x00,0x0C,0x0C,0x0C,0x6C,0x6C,0x38 ; 0x6A 'j'
db 0x60,0x60,0x66,0x6C,0x78,0x6C,0x66,0x00 ; 0x6B 'k'
db 0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00 ; 0x6C 'l'
db 0x00,0x00,0x6C,0x7E,0x7E,0x6B,0x63,0x00 ; 0x6D 'm'
db 0x00,0x00,0x7C,0x66,0x66,0x66,0x66,0x00 ; 0x6E 'n'
db 0x00,0x00,0x3C,0x66,0x66,0x66,0x3C,0x00 ; 0x6F 'o'
db 0x00,0x00,0x7C,0x66,0x66,0x7C,0x60,0x60 ; 0x70 'p'
db 0x00,0x00,0x3E,0x66,0x66,0x3E,0x06,0x06 ; 0x71 'q'
db 0x00,0x00,0x6C,0x76,0x60,0x60,0x60,0x00 ; 0x72 'r'
db 0x00,0x00,0x3E,0x60,0x3C,0x06,0x7C,0x00 ; 0x73 's'
db 0x30,0x30,0x7C,0x30,0x30,0x30,0x1C,0x00 ; 0x74 't'
db 0x00,0x00,0x66,0x66,0x66,0x66,0x3E,0x00 ; 0x75 'u'
db 0x00,0x00,0x66,0x66,0x66,0x3C,0x18,0x00 ; 0x76 'v'
db 0x00,0x00,0x63,0x63,0x6B,0x7F,0x36,0x00 ; 0x77 'w'
db 0x00,0x00,0x66,0x3C,0x18,0x3C,0x66,0x00 ; 0x78 'x'
db 0x00,0x00,0x66,0x66,0x66,0x3E,0x06,0x3C ; 0x79 'y'
db 0x00,0x00,0x7E,0x0C,0x18,0x30,0x7E,0x00 ; 0x7A 'z'
db 0x0E,0x18,0x18,0x70,0x18,0x18,0x0E,0x00 ; 0x7B '{'
db 0x18,0x18,0x18,0x00,0x18,0x18,0x18,0x00 ; 0x7C '|'
db 0x70,0x18,0x18,0x0E,0x18,0x18,0x70,0x00 ; 0x7D '}'
db 0x76,0xDC,0x00,0x00,0x00,0x00,0x00,0x00 ; 0x7E '~'

862
src/common/chartable.asm Normal file
View file

@ -0,0 +1,862 @@
; ============================================================================
; Font 8x8 (printable ASCII 0x20..0x7E) -> 95 glyphs * 8 = 760 bytes
; - bit7 = gauche, bit0 = droite
; - 1 byte = 1 scanline (haut -> bas)
; ============================================================================
font8x8:
; 0x20 ' '
db 00000000b
db 00000000b
db 00000000b
db 00000000b
db 00000000b
db 00000000b
db 00000000b
db 00000000b
; 0x21 '!'
db 00011000b
db 00011000b
db 00011000b
db 00011000b
db 00011000b
db 00000000b
db 00011000b
db 00000000b
; 0x22 '"'
db 01100110b
db 01100110b
db 00100100b
db 00000000b
db 00000000b
db 00000000b
db 00000000b
db 00000000b
; 0x23 '#'
db 00100100b
db 00100100b
db 01111110b
db 00100100b
db 01111110b
db 00100100b
db 00100100b
db 00000000b
; 0x24 '$'
db 00011000b
db 00111110b
db 01100000b
db 00111100b
db 00000110b
db 01111100b
db 00011000b
db 00000000b
; 0x25 '%'
db 01100010b
db 01100110b
db 00001100b
db 00011000b
db 00110000b
db 01100110b
db 01000110b
db 00000000b
; 0x26 '&'
db 00111000b
db 01101100b
db 00111000b
db 01110110b
db 11011100b
db 11001100b
db 01110110b
db 00000000b
; 0x27 '''
db 00011000b
db 00011000b
db 00110000b
db 00000000b
db 00000000b
db 00000000b
db 00000000b
db 00000000b
; 0x28 '('
db 00001100b
db 00011000b
db 00110000b
db 00110000b
db 00110000b
db 00011000b
db 00001100b
db 00000000b
; 0x29 ')'
db 00110000b
db 00011000b
db 00001100b
db 00001100b
db 00001100b
db 00011000b
db 00110000b
db 00000000b
; 0x2A '*'
db 00000000b
db 01100110b
db 00111100b
db 11111111b
db 00111100b
db 01100110b
db 00000000b
db 00000000b
; 0x2B '+'
db 00000000b
db 00011000b
db 00011000b
db 01111110b
db 00011000b
db 00011000b
db 00000000b
db 00000000b
; 0x2C ','
db 00000000b
db 00000000b
db 00000000b
db 00000000b
db 00000000b
db 00011000b
db 00011000b
db 00110000b
; 0x2D '-'
db 00000000b
db 00000000b
db 00000000b
db 01111110b
db 00000000b
db 00000000b
db 00000000b
db 00000000b
; 0x2E '.'
db 00000000b
db 00000000b
db 00000000b
db 00000000b
db 00000000b
db 00011000b
db 00011000b
db 00000000b
; 0x2F '/'
db 00000110b
db 00001100b
db 00011000b
db 00110000b
db 01100000b
db 11000000b
db 10000000b
db 00000000b
; 0x30 '0'
db 00111100b
db 01100110b
db 01101110b
db 01110110b
db 01100110b
db 01100110b
db 00111100b
db 00000000b
; 0x31 '1'
db 00011000b
db 00111000b
db 00011000b
db 00011000b
db 00011000b
db 00011000b
db 00111100b
db 00000000b
; 0x32 '2'
db 00111100b
db 01100110b
db 00000110b
db 00001100b
db 00011000b
db 00110000b
db 01111110b
db 00000000b
; 0x33 '3'
db 00111100b
db 01100110b
db 00000110b
db 00011100b
db 00000110b
db 01100110b
db 00111100b
db 00000000b
; 0x34 '4'
db 00001100b
db 00011100b
db 00111100b
db 01101100b
db 01111110b
db 00001100b
db 00001100b
db 00000000b
; 0x35 '5'
db 01111110b
db 01100000b
db 01111100b
db 00000110b
db 00000110b
db 01100110b
db 00111100b
db 00000000b
; 0x36 '6'
db 00011100b
db 00110000b
db 01100000b
db 01111100b
db 01100110b
db 01100110b
db 00111100b
db 00000000b
; 0x37 '7'
db 01111110b
db 01100110b
db 00000110b
db 00001100b
db 00011000b
db 00011000b
db 00011000b
db 00000000b
; 0x38 '8'
db 00111100b
db 01100110b
db 01100110b
db 00111100b
db 01100110b
db 01100110b
db 00111100b
db 00000000b
; 0x39 '9'
db 00111100b
db 01100110b
db 01100110b
db 00111110b
db 00000110b
db 00001100b
db 00111000b
db 00000000b
; 0x3A ':'
db 00000000b
db 00011000b
db 00011000b
db 00000000b
db 00000000b
db 00011000b
db 00011000b
db 00000000b
; 0x3B ';'
db 00000000b
db 00011000b
db 00011000b
db 00000000b
db 00000000b
db 00011000b
db 00011000b
db 00110000b
; 0x3C '<'
db 00001110b
db 00011100b
db 00111000b
db 01110000b
db 00111000b
db 00011100b
db 00001110b
db 00000000b
; 0x3D '='
db 00000000b
db 00000000b
db 01111110b
db 00000000b
db 01111110b
db 00000000b
db 00000000b
db 00000000b
; 0x3E '>'
db 01110000b
db 00111000b
db 00011100b
db 00001110b
db 00011100b
db 00111000b
db 01110000b
db 00000000b
; 0x3F '?'
db 00111100b
db 01100110b
db 00000110b
db 00001100b
db 00011000b
db 00000000b
db 00011000b
db 00000000b
; 0x40 '@'
db 00111100b
db 01100110b
db 01101110b
db 01101010b
db 01101110b
db 01100000b
db 00111100b
db 00000000b
; 0x41 'A'
db 00011000b
db 00111100b
db 01100110b
db 01100110b
db 01111110b
db 01100110b
db 01100110b
db 00000000b
; 0x42 'B'
db 01111100b
db 01100110b
db 01100110b
db 01111100b
db 01100110b
db 01100110b
db 01111100b
db 00000000b
; 0x43 'C'
db 00111100b
db 01100110b
db 01100000b
db 01100000b
db 01100000b
db 01100110b
db 00111100b
db 00000000b
; 0x44 'D'
db 01111000b
db 01101100b
db 01100110b
db 01100110b
db 01100110b
db 01101100b
db 01111000b
db 00000000b
; 0x45 'E'
db 01111110b
db 01100000b
db 01100000b
db 01111100b
db 01100000b
db 01100000b
db 01111110b
db 00000000b
; 0x46 'F'
db 01111110b
db 01100000b
db 01100000b
db 01111100b
db 01100000b
db 01100000b
db 01100000b
db 00000000b
; 0x47 'G'
db 00111100b
db 01100110b
db 01100000b
db 01101110b
db 01100110b
db 01100110b
db 00111100b
db 00000000b
; 0x48 'H'
db 01100110b
db 01100110b
db 01100110b
db 01111110b
db 01100110b
db 01100110b
db 01100110b
db 00000000b
; 0x49 'I'
db 00111100b
db 00011000b
db 00011000b
db 00011000b
db 00011000b
db 00011000b
db 00111100b
db 00000000b
; 0x4A 'J'
db 00011110b
db 00001100b
db 00001100b
db 00001100b
db 00001100b
db 01101100b
db 00111000b
db 00000000b
; 0x4B 'K'
db 01100110b
db 01101100b
db 01111000b
db 01110000b
db 01111000b
db 01101100b
db 01100110b
db 00000000b
; 0x4C 'L'
db 01100000b
db 01100000b
db 01100000b
db 01100000b
db 01100000b
db 01100000b
db 01111110b
db 00000000b
; 0x4D 'M'
db 01100011b
db 01110111b
db 01111111b
db 01101011b
db 01100011b
db 01100011b
db 01100011b
db 00000000b
; 0x4E 'N'
db 01100110b
db 01110110b
db 01111110b
db 01111110b
db 01101110b
db 01100110b
db 01100110b
db 00000000b
; 0x4F 'O'
db 00111100b
db 01100110b
db 01100110b
db 01100110b
db 01100110b
db 01100110b
db 00111100b
db 00000000b
; 0x50 'P'
db 01111100b
db 01100110b
db 01100110b
db 01111100b
db 01100000b
db 01100000b
db 01100000b
db 00000000b
; 0x51 'Q'
db 00111100b
db 01100110b
db 01100110b
db 01100110b
db 01101110b
db 00111100b
db 00001110b
db 00000000b
; 0x52 'R'
db 01111100b
db 01100110b
db 01100110b
db 01111100b
db 01111000b
db 01101100b
db 01100110b
db 00000000b
; 0x53 'S'
db 00111100b
db 01100110b
db 01100000b
db 00111100b
db 00000110b
db 01100110b
db 00111100b
db 00000000b
; 0x54 'T'
db 01111110b
db 00011000b
db 00011000b
db 00011000b
db 00011000b
db 00011000b
db 00011000b
db 00000000b
; 0x55 'U'
db 01100110b
db 01100110b
db 01100110b
db 01100110b
db 01100110b
db 01100110b
db 00111100b
db 00000000b
; 0x56 'V'
db 01100110b
db 01100110b
db 01100110b
db 01100110b
db 01100110b
db 00111100b
db 00011000b
db 00000000b
; 0x57 'W'
db 01100011b
db 01100011b
db 01100011b
db 01101011b
db 01111111b
db 01110111b
db 01100011b
db 00000000b
; 0x58 'X'
db 01100110b
db 01100110b
db 00111100b
db 00011000b
db 00111100b
db 01100110b
db 01100110b
db 00000000b
; 0x59 'Y'
db 01100110b
db 01100110b
db 01100110b
db 00111100b
db 00011000b
db 00011000b
db 00011000b
db 00000000b
; 0x5A 'Z'
db 01111110b
db 00000110b
db 00001100b
db 00011000b
db 00110000b
db 01100000b
db 01111110b
db 00000000b
; 0x5B '['
db 00111100b
db 00110000b
db 00110000b
db 00110000b
db 00110000b
db 00110000b
db 00111100b
db 00000000b
; 0x5C '\'
db 11000000b
db 01100000b
db 00110000b
db 00011000b
db 00001100b
db 00000110b
db 00000010b
db 00000000b
; 0x5D ']'
db 00111100b
db 00001100b
db 00001100b
db 00001100b
db 00001100b
db 00001100b
db 00111100b
db 00000000b
; 0x5E '^'
db 00010000b
db 00111000b
db 01101100b
db 11000110b
db 00000000b
db 00000000b
db 00000000b
db 00000000b
; 0x5F '_'
db 00000000b
db 00000000b
db 00000000b
db 00000000b
db 00000000b
db 00000000b
db 11111111b
db 00000000b
; 0x60 '`'
db 00110000b
db 00011000b
db 00001100b
db 00000000b
db 00000000b
db 00000000b
db 00000000b
db 00000000b
; 0x61 'a'
db 00000000b
db 00000000b
db 00111100b
db 00000110b
db 00111110b
db 01100110b
db 00111110b
db 00000000b
; 0x62 'b'
db 01100000b
db 01100000b
db 01111100b
db 01100110b
db 01100110b
db 01100110b
db 01111100b
db 00000000b
; 0x63 'c'
db 00000000b
db 00000000b
db 00111100b
db 01100110b
db 01100000b
db 01100110b
db 00111100b
db 00000000b
; 0x64 'd'
db 00000110b
db 00000110b
db 00111110b
db 01100110b
db 01100110b
db 01100110b
db 00111110b
db 00000000b
; 0x65 'e'
db 00000000b
db 00000000b
db 00111100b
db 01100110b
db 01111110b
db 01100000b
db 00111100b
db 00000000b
; 0x66 'f'
db 00011100b
db 00110000b
db 00110000b
db 01111100b
db 00110000b
db 00110000b
db 00110000b
db 00000000b
; 0x67 'g'
db 00000000b
db 00000000b
db 00111110b
db 01100110b
db 01100110b
db 00111110b
db 00000110b
db 00111100b
; 0x68 'h'
db 01100000b
db 01100000b
db 01111100b
db 01100110b
db 01100110b
db 01100110b
db 01100110b
db 00000000b
; 0x69 'i'
db 00011000b
db 00000000b
db 00111000b
db 00011000b
db 00011000b
db 00011000b
db 00111100b
db 00000000b
; 0x6A 'j'
db 00001100b
db 00000000b
db 00001100b
db 00001100b
db 00001100b
db 01101100b
db 01101100b
db 00111000b
; 0x6B 'k'
db 01100000b
db 01100000b
db 01100110b
db 01101100b
db 01111000b
db 01101100b
db 01100110b
db 00000000b
; 0x6C 'l'
db 00111000b
db 00011000b
db 00011000b
db 00011000b
db 00011000b
db 00011000b
db 00111100b
db 00000000b
; 0x6D 'm'
db 00000000b
db 00000000b
db 01101100b
db 01111110b
db 01111110b
db 01101011b
db 01100011b
db 00000000b
; 0x6E 'n'
db 00000000b
db 00000000b
db 01111100b
db 01100110b
db 01100110b
db 01100110b
db 01100110b
db 00000000b
; 0x6F 'o'
db 00000000b
db 00000000b
db 00111100b
db 01100110b
db 01100110b
db 01100110b
db 00111100b
db 00000000b
; 0x70 'p'
db 00000000b
db 00000000b
db 01111100b
db 01100110b
db 01100110b
db 01111100b
db 01100000b
db 01100000b
; 0x71 'q'
db 00000000b
db 00000000b
db 00111110b
db 01100110b
db 01100110b
db 00111110b
db 00000110b
db 00000110b
; 0x72 'r'
db 00000000b
db 00000000b
db 01101100b
db 01110110b
db 01100000b
db 01100000b
db 01100000b
db 00000000b
; 0x73 's'
db 00000000b
db 00000000b
db 00111110b
db 01100000b
db 00111100b
db 00000110b
db 01111100b
db 00000000b
; 0x74 't'
db 00110000b
db 00110000b
db 01111100b
db 00110000b
db 00110000b
db 00110000b
db 00011100b
db 00000000b
; 0x75 'u'
db 00000000b
db 00000000b
db 01100110b
db 01100110b
db 01100110b
db 01100110b
db 00111110b
db 00000000b
; 0x76 'v'
db 00000000b
db 00000000b
db 01100110b
db 01100110b
db 01100110b
db 00111100b
db 00011000b
db 00000000b
; 0x77 'w'
db 00000000b
db 00000000b
db 01100011b
db 01100011b
db 01101011b
db 01111111b
db 00110110b
db 00000000b
; 0x78 'x'
db 00000000b
db 00000000b
db 01100110b
db 00111100b
db 00011000b
db 00111100b
db 01100110b
db 00000000b
; 0x79 'y'
db 00000000b
db 00000000b
db 01100110b
db 01100110b
db 01100110b
db 00111110b
db 00000110b
db 00111100b
; 0x7A 'z'
db 00000000b
db 00000000b
db 01111110b
db 00001100b
db 00011000b
db 00110000b
db 01111110b
db 00000000b
; 0x7B '{'
db 00001110b
db 00011000b
db 00011000b
db 01110000b
db 00011000b
db 00011000b
db 00001110b
db 00000000b
; 0x7C '|'
db 00011000b
db 00011000b
db 00011000b
db 00000000b
db 00011000b
db 00011000b
db 00011000b
db 00000000b
; 0x7D '}'
db 01110000b
db 00011000b
db 00011000b
db 00001110b
db 00011000b
db 00011000b
db 01110000b
db 00000000b
; 0x7E '~'
db 01110110b
db 11011100b
db 00000000b
db 00000000b
db 00000000b
db 00000000b
db 00000000b
db 00000000b

View file

@ -1,86 +1,43 @@
; ============================================================================= ; On doit répartir sur 2 octets :
; Project : Custom BIOS / ROM ; mask0 = glyph >> shift
; File : boot.asm ; mask1 = glyph << (8-shift)
; Author : frater ;
; Created : 06 jan 2026 ; Utilise AH pour conserver glyph original
; mov ah, al
; 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/>.
;
; =============================================================================
; mask0 dans AL
mov al, ah
shr al, cl
; mask1 dans AH
mov ah, ah
mov dl, 8
sub dl, cl
mov cl, dl
mov dl, ah
shl dl, cl
mov ah, dl
; restaurer shift dans CL (on en a besoin pour les lignes suivantes)
mov cl, [ds:GFX_CUR_SHIFT]
%define GFX_MODE 0x06 ; MCGA HiRes (B/W) ; Si mask0/mask1 nuls, saute ce côté
%define GFX_WIDTH 640 %if GFX_CHAR_COL = 1
%define GFX_HEIGHT 200 test al, al
jz .skip0_set
gfx_init: or [es:di], al
; init graphics mode .skip0_set:
mov ah, 0x00 ; AH=00h set video mode test ah, ah
mov al, GFX_MODE jz .skip1_set
int 0x10 or [es:di+1], ah
.skip1_set:
call gfx_background %else
test al, al
ret jz .skip0_clr
not al
; PutPixel(x=cx, y=dx, color=al) sur page bh and [es:di], al
gfx_putpixel: .skip0_clr:
mov ah, 0Ch test ah, ah
;mov al, 0Fh ; couleur (0..15) jz .skip1_clr
;mov bh, 00h ; page not ah
;mov cx, 100 ; x and [es:di+1], ah
;mov dx, 50 ; y .skip1_clr:
int 10h %endif
ret
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
ret
; gfx_background:
xor dx,dx ; Y
.loop_y:
test dl,1
jnz .pair
mov cx,0 ; X = 0
jmp .loop_x
.pair:
mov cx,1 ; X = 1
.loop_x:
mov ah,0x0c ; putpixel
mov al,0x0f ; blanc
xor bh,bh
int 10h
add cx,2 ; x=x+2
cmp cx,GFX_WIDTH
jb .loop_x
inc dx
cmp dx,GFX_HEIGHT
jb .loop_y
ret

View file

@ -23,35 +23,84 @@
; ;
; graphics drivers pour carte video/mode CGA-Mono (640x200x2) ; graphics drivers pour carte video/mode CGA-Mono (640x200x2)
; ;
%define VIDEO_SEG 0xB800 ; ou 0xB000 %define VIDEO_SEG 0xB800 ; ou 0xB000
%define GFX_MODE 0x06 ; MCGA HiRes (B/W) %define GFX_MODE 0x06 ; MCGA HiRes (B/W)
%define GFX_WIDTH 640 %define GFX_WIDTH 640
%define GFX_HEIGHT 200 %define GFX_HEIGHT 200
%define CGA_STRIDE 80 %define CGA_STRIDE 80
%define CGA_ODD_BANK 0x2000 %define CGA_ODD_BANK 0x2000
; décommenter cette constante si vous voulez un mode aligné/non alligné différent
; sinon le code utilisé sera toujours "shifted"
; %define FULL_MODE_ALLIGNED 1
; align putch mode
%define GFX_TXT_WHITE_TRANSPARENT 0
%define GFX_TXT_BLACK_TRANSPARENT 1
%define GFX_TXT_TRANSP_ON_WHITE 2
%define GFX_TXT_WHITE_ON_BLACK 3
%define GFX_TXT_BLACK_ON_WHITE 4
%macro GFX_DRV 1
call word [cs:graph_driver + ((%1)*2)]
%endmacro
; ------------------------------------------------------------ ; ------------------------------------------------------------
; TABLE DE SAUT (VECTEURS API) ; TABLE DE SAUT (VECTEURS API)
; Cette table doit être située au début du driver pour être ; Cette table doit être située au début du driver pour être
; accessible par la GUI à des offsets fixes. ; accessible par la GUI à des offsets fixes.
; ------------------------------------------------------------ ; ------------------------------------------------------------
%define GFX_INIT 0
%define GFX_PUTPIXEL 1
%define GFX_GETPIXEL 2
%define GFX_GOTOXY 3
%define GFX_PUTCH_MODE 4
%define GFX_PUTCH 5
%define GFX_WRITE 6
%define GFX_CRS_UPDATE 7
%define INIT 0 graph_driver:
%define PUTPIXEL 3 dw cga_init
%define GETPIXEL 6 dw cga_putpixel
%define MOUSE_UPDATE 9 dw cga_getpixel
dw cga_set_charpos
gfx_api: dw cga_none
jmp gfx_init ; Offset +0: Initialisation dw cga_putc
jmp gfx_putpixel ; Offset +3: Dessin pixel dw cga_write
jmp gfx_getpixel ; Offset +6: Lecture pixel dw cga_cursor_move
jmp gfx_cursor_move ; Offset +9: mouse update
; jmp gfx_fill_rect ; Remplissage rectangle (Nouveau) ; jmp gfx_fill_rect ; Remplissage rectangle (Nouveau)
; jmp gfx_invert_rect ; Offset +12: Inversion (Nouveau pour Menus) ; jmp gfx_invert_rect ; Offset +12: Inversion (Nouveau pour Menus)
; jmp gfx_draw_hline ; Offset +15: Ligne horizontale rapide (Nouveau) ; jmp gfx_draw_hline ; Offset +15: Ligne horizontale rapide (Nouveau)
%include "./common/cursor.asm"
%include "./common/chartable.asm"
;
;
; convert al -> AX aligned with "cl"
%macro ALING_BYTE 0
mov ah,al
xor al,al
shr ax,cl
xchg ah,al
%endmacro
%macro GFX_SET_WRTIE_MODE 1
push fs
push BDA_DATA_SEG
pop fs
mov [fs:BDA_GFX + gfx.cur_mode], %1
pop fs
pop ax
%endmacro
; ------------------------------------------------------------ ; ------------------------------------------------------------
; COMMENTAIRE SUR LA MÉTHODE D'APPEL ; COMMENTAIRE SUR LA MÉTHODE D'APPEL
; ;
@ -72,51 +121,335 @@ gfx_api:
; ;
; ce mode est entrelacé, un bit/pixel, 8 pixels par octet ; ce mode est entrelacé, un bit/pixel, 8 pixels par octet
; ------------------------------------------------------------ ; ------------------------------------------------------------
gfx_init: cga_init:
; init graphics mode mov ax, BDA_DATA_SEG
mov ah, 0x00 ; AH=00h set video mode mov ds, ax
mov al, GFX_MODE
int 0x10
mov byte [BDA_MOUSE + mouse.bkg_saved],0 ; flag image saved ; init graphics mode
mov ah, 0x00 ; AH=00h set video mode
mov al, GFX_MODE
int 0x10
mov byte [BDA_MOUSE + mouse.bkg_saved],0 ; flag image saved
; dessine un background "check-board" mov byte [BDA_GFX + gfx.cur_mode], 1
call gfx_background ; dessine un background "check-board"
call cga_background
ret
cga_none:
ret
; ---------------------------------------------------------------------------
; gfx_set_charpos
; 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
; ---------------------------------------------------------------------------
cga_set_charpos:
pusha
push fs
mov ax,BDA_DATA_SEG
mov fs,ax
; store x,y en pixel
mov [fs:BDA_GFX + gfx.cur_x], cx
mov [fs:BDA_GFX + gfx.cur_y], dx
mov ax, cx
and ax, 0x07
mov [fs:BDA_GFX + gfx.cur_shift], al
; calcul de l'offset de la position 'x,y':
; si 'y' est paire, DI < 0x2000 & add = 0x2000
; si 'y' est impaire, DI> 0x2000 & add = -0x2000
; DI = (y>>1)*80 + (x>>3) + (y&1)*
mov ax, dx
shr ax, 1
mov bx, ax ; bx = dx>>1
shl bx, 4 ; bx = bx * 16
shl ax, 6 ; ax = ax * 64
add bx, ax
mov ax, cx
shr ax, 3 ; ax = x/8
add bx, ax
mov ax, CGA_ODD_BANK
test dl, 1
jz .even
add bx, ax
neg ax
.even:
mov [fs:BDA_GFX + gfx.cur_line_ofs], ax
mov [fs:BDA_GFX + gfx.cur_offset], bx
pop fs
popa
ret
; ---------------------------------------------------------------------------
; 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_aligned
; In : AL = char (ASCII)
; Uses: DS:GFX_CUR_* (baseDI, shift, etc.)
; Out: avance le curseur d'un caractère (8 pixels) sans recalcul complet
; Notes:
; - Nécessite une font 8x8 accessible en CS (voir get_glyph8x8_cs_si)
; - Transparent: bits 0 du glyph ne touchent pas le fond
; ---------------------------------------------------------------------------
%ifdef FULL_MODE_ALLIGNED
cga_putc_aligned:
; Base offset VRAM pour la scanline Y
mov di, [fs:BDA_GFX + gfx.cur_offset]
mov bx, [fs:BDA_GFX + gfx.cur_line_ofs]
mov dl, [fs:BDA_GFX + gfx.cur_mode]
mov cx,4
.row_loop:
; AL = byte glyph pour cette scanline
mov ax, [cs:si]
add si,2
cmp dl,0
jne .black_transparent
; white with transparent
or [es:di], al
or [es:di+bx], ah
jmp .next
.black_transparent:
cmp dl,1
jne .transparent_white
; black with transparent
not ax
and [es:di], al
and [es:di+bx], ah
jmp .next
.transparent_white:
cmp dl,2
jne .black_white
; transparent on white
not ax
or [es:di], al
or [es:di+bx], ah
jmp .next
.black_white:
cmp dl,3
jne .white_transparent
; white on black
mov [es:di], al
mov [es:di+bx], ah
jmp .next
.white_transparent:
not ax
mov [es:di], al
mov [es:di+bx], ah
.next:
add di,CGA_STRIDE
loop .row_loop
; Avancer curseur d'un caractère (8 pixels)
inc word [fs:BDA_GFX + gfx.cur_offset]
add word [fs:BDA_GFX + gfx.cur_x], 8
ret
%endif
; ---------------------------------------------------------------------------
; cga_putc_unalign
; In : AL = char (ASCII)
; Uses: FS:BDA_GFX + gfx.cur_* (offset, add_ofs, shift, mode)
; Notes:
; - x non aligné (x&7 != 0)
; - écrit sur 2 bytes (di et di+1) dans chaque banque
; ---------------------------------------------------------------------------
cga_putc_unaligned:
; Base offset VRAM pour la scanline Y
mov di, [fs:BDA_GFX + gfx.cur_offset]
mov bx, [fs:BDA_GFX + gfx.cur_line_ofs]
mov ch, [fs:BDA_GFX + gfx.cur_mode]
mov cl, [fs:BDA_GFX + gfx.cur_shift]
mov bp,4
.row_loop:
; ligne "paire" du gylphe
mov al, [cs:si]
inc si
ALING_BYTE
push ax
; ligne "impaire" du gylphe
mov al, [cs:si]
inc si
ALING_BYTE
pop dx
xchg ax, dx
cmp ch,0
jne .black_transparent
; white with transparent
or [es:di], ax
or [es:di+bx], dx
jmp .next
.black_transparent:
; cmp ch,1
; jne .transparent_white
; black with transparent
not ax
not dx
and [es:di], ax
and [es:di+bx], dx
; jmp .next
; .transparent_white:
; cmp ch,2
; jne .black_white
;
; ; transparent on white
; not ax
; or [es:di], ax
; or [es:di+bx], dx
; jmp .next
;
; .black_white:
; cmp ch,3
; jne .white_transparent
;
; ; white on black
; mov [es:di], ax
; mov [es:di+bx], dx
; jmp .next
;
; .white_transparent:
; not ax
; mov [es:di], ax
; mov [es:di+bx], dx
;
.next:
add di,CGA_STRIDE
dec bp
jnz .row_loop
; Avancer curseur d'un caractère (8 pixels)
inc word [fs:BDA_GFX + gfx.cur_offset]
add word [fs:BDA_GFX + gfx.cur_x], 8
ret
cga_putc:
pusha
push fs
push es
mov bx, VIDEO_SEG
mov es, bx
mov bx, BDA_DATA_SEG
mov fs, bx
call get_glyph_offset
%ifdef FULL_MODE_ALLIGNED
cmp byte [fs:BDA_GFX + gfx.cur_shift], 0
jne .unaligned
call cga_putc_aligned
jmp .done
.unaligned:
%endif
call cga_putc_unaligned
.done:
pop es
pop fs
popa
ret
;
; write string from [DS:SI] to screen
;
cga_write:
push ax
.loops:
lodsb
cmp al,0
je .done
call cga_putc
jmp .loops
.done:
pop ax
ret
ret
; ------------------------------------------------------------ ; ------------------------------------------------------------
; Calcule DI + AH=mask pour (CX=x, DX=y) en mode CGA 640x200 ; Calcule DI + AH=mask pour (CX=x, DX=y) en mode CGA 640x200
; ;
; Out: ES=VIDEO_SEG, DI=offset, AH=bitmask (0x80 >> (x&7)) ; Out: ES=VIDEO_SEG, DI=offset, AH=bitmask (0x80 >> (x&7))
; ------------------------------------------------------------ ; ------------------------------------------------------------
gfx_calc_addr: cga_calc_addr:
; calcul de l'offset 'y': ; calcul de l'offset 'y':
; si y est impaire, DI+=0x2000 ; si y est impaire, DI+=0x2000
; DI = (y>>1)*80 + (x>>3) + (y&1)*0x2000 ; DI = (y>>1)*80 + (x>>3) + (y&1)*0x2000
mov ax, dx mov ax, dx
shr ax, 1 ; ax = y/2 shr ax, 1 ; ax = y/2
mov di, ax
mov di, ax shl di, 4 ; (y/2)*16
shl di, 4 ; (y/2)*16 shl ax, 6 ; (y/2)*64
shl ax, 6 ; (y/2)*64 add di, ax ; *80
add di, ax ; *80 mov ax, cx
shr ax, 3
mov ax, cx add di, ax
shr ax, 3 test dl, 1
add di, ax jz .even
add di, CGA_ODD_BANK
test dl, 1
jz .even
add di, CGA_ODD_BANK
.even: .even:
; masque bit = 0x80 >> (x&7) ; masque bit = 0x80 >> (x&7)
push cx push cx
and cl, 7 and cl, 7
mov ah, 080h mov ah, 080h
shr ah, cl shr ah, cl
pop cx pop cx
ret ret
; ------------------------------------------------------------ ; ------------------------------------------------------------
; Dessine un pixel, accès VRAM direct. ; Dessine un pixel, accès VRAM direct.
@ -126,22 +459,22 @@ gfx_calc_addr:
; ES = Target Segment (usually VIDEO_SEG) ; ES = Target Segment (usually VIDEO_SEG)
; BL = color (0=black, !=0=white) ; BL = color (0=black, !=0=white)
; ------------------------------------------------------------ ; ------------------------------------------------------------
gfx_local_putpixel: cga_local_putpixel:
call gfx_calc_addr call cga_calc_addr
; write ; write
cmp bl, 0 cmp bl, 0
je .clear je .clear
.set: .set:
or byte [es:di], ah or byte [es:di], ah
jmp .done jmp .done
.clear: .clear:
not ah not ah
and byte [es:di], ah and byte [es:di], ah
.done: .done:
ret ret
; ------------------------------------------------------------ ; ------------------------------------------------------------
; Dessine un pixel, accès VRAM direct. ; Dessine un pixel, accès VRAM direct.
@ -150,76 +483,76 @@ gfx_local_putpixel:
; DX = y (0..199) ; DX = y (0..199)
; BL = color (0=black, !=0=white) ; BL = color (0=black, !=0=white)
; ------------------------------------------------------------ ; ------------------------------------------------------------
gfx_putpixel: cga_putpixel:
push ax push ax
push di push di
push es push es
mov ax, VIDEO_SEG mov ax, VIDEO_SEG
mov es,ax mov es,ax
call gfx_calc_addr call cga_calc_addr
; write ; write
cmp bl, 0 cmp bl, 0
je .clear je .clear
.set: .set:
or byte [es:di], ah or byte [es:di], ah
jmp .done jmp .done
.clear: .clear:
not ah not ah
and byte [es:di], ah and byte [es:di], ah
.done: .done:
pop es pop es
pop di pop di
pop ax pop ax
ret ret
; ------------------------------------------------------------ ; ------------------------------------------------------------
; Lit un pixel (CX=x, DX=y) ; Lit un pixel (CX=x, DX=y)
; Out: AL=0/1 ; Out: AL=0/1
; ------------------------------------------------------------ ; ------------------------------------------------------------
gfx_getpixel: cga_getpixel:
push di push di
push es push es
call gfx_calc_addr call cga_calc_addr
mov al, [es:di] mov al, [es:di]
and al, ah and al, ah
setnz al setnz al
pop es pop es
pop di pop di
ret ret
; ------------------------------------------------------------ ; ------------------------------------------------------------
; Dessine un background "check-board", accès VRAM direct. ; Dessine un background "check-board", accès VRAM direct.
; ;
; ------------------------------------------------------------ ; ------------------------------------------------------------
gfx_background: cga_background:
mov ax,VIDEO_SEG mov ax,VIDEO_SEG
mov es,ax mov es,ax
mov di,0x0000 mov di,0x0000
mov eax,0xaaaaaaaa mov eax,0xaaaaaaaa
mov cx,0x800 mov cx,0x800
rep stosd rep stosd
mov di,0x2000 mov di,0x2000
mov eax,0x55555555 mov eax,0x55555555
mov cx,0x800 ; 640/8/4 mov cx,0x800 ; 640/8/4
rep stosd rep stosd
ret ret
; ------------------------------------------------------------ ; ------------------------------------------------------------
; Calcule les infos de l'alignement du curseur, basé sur cx=X ; Calcule les infos de l'alignement du curseur, basé sur cx=X
; il est important que DS pointe sur le BDA_MOUSE_SEG ; il est important que DS pointe sur le BDA_MOUSE_SEG
; Out: BDA_CURSOR_BITOFF, BDA_CURSOR_BYTES ; Out: BDA_CURSOR_BITOFF, BDA_CURSOR_BYTES
; ------------------------------------------------------------ ; ------------------------------------------------------------
gfx_cursor_calc_align: cga_cursor_calc_align:
mov al, cl mov al, cl
and al, 7 ; offset = x&7 and al, 7 ; offset = x&7
mov byte [BDA_MOUSE + mouse.cur_bit_ofs], al mov byte [BDA_MOUSE + mouse.cur_bit_ofs], al
ret ret
; ------------------------------------------------------------ ; ------------------------------------------------------------
; Dessine un pixel, en [ES:DI] accès VRAM direct. ; Dessine un pixel, en [ES:DI] accès VRAM direct.
@ -228,62 +561,54 @@ gfx_cursor_calc_align:
; DX = y (0..199) ; DX = y (0..199)
; BL = color (0=black, !=0=white) ; BL = color (0=black, !=0=white)
; ------------------------------------------------------------ ; ------------------------------------------------------------
gfx_putpixel_fast: cga_putpixel_fast:
cmp bl, 0 cmp bl, 0
je .clear je .clear
.set: .set:
or byte [es:di], ah or byte [es:di], ah
jmp .done jmp .done
.clear: .clear:
not ah not ah
and byte [es:di], ah and byte [es:di], ah
.done: .done:
ret ret
; ------------------------------------------------------------ ; ------------------------------------------------------------
; Lit un pixel, en [ES:DI] accès VRAM direct. ; Lit un pixel, en [ES:DI] accès VRAM direct.
; ;
; ------------------------------------------------------------ ; ------------------------------------------------------------
gfx_getpixel_fast: cga_getpixel_fast:
mov al, [es:di] mov al, [es:di]
and al, ah and al, ah
setnz al setnz al
ret ret
gfx_cursor_move: cga_cursor_move:
pusha pusha
push ds push ds
push es push es
; move Data Segment ; move Data Segment
mov ax, BDA_DATA_SEG mov ax, BDA_DATA_SEG
mov ds, ax mov ds, ax
cmp byte [BDA_MOUSE + mouse.cur_drawing],0 cmp byte [BDA_MOUSE + mouse.cur_drawing],0
jne .done jne .done
mov byte [BDA_MOUSE + mouse.cur_drawing],1 mov byte [BDA_MOUSE + mouse.cur_drawing],1
mov ax, VIDEO_SEG mov ax, VIDEO_SEG
mov es, ax mov es, ax
;call gfx_cursor_restorebg ;call cga_cursor_restorebg
;call gfx_cursor_savebg ;call cga_cursor_savebg
call cga_cursor_draw
call gfx_cursor_draw mov byte [BDA_MOUSE + mouse.cur_drawing],0
mov byte [BDA_MOUSE + mouse.cur_drawing],0
.done: .done:
pop es pop es
pop ds pop ds
popa popa
ret ret
bits 16
%define GFX_WIDTH 640
%define GFX_HEIGHT 200
%define CGA_STRIDE 80
%define CGA_ODD_BANK 0x2000
; ============================================================ ; ============================================================
; gfx_cursor_draw_rm16_i386_self ; gfx_cursor_draw_rm16_i386_self
@ -292,7 +617,7 @@ bits 16
; Sortie: rien ; Sortie: rien
; Détruit: registres sauvegardés/restaurés (PUSHA/POPA) ; Détruit: registres sauvegardés/restaurés (PUSHA/POPA)
; ============================================================ ; ============================================================
gfx_cursor_draw_rm16_i386_self: cga_cursor_draw:
push es push es
push gs push gs
pusha pusha
@ -605,7 +930,7 @@ gfx_cursor_draw_rm16_i386_self:
ret ret
; ----------------------------------------------- ; -----------------------------------------------
; gfx_cursor_savebg_32 ; cga_cursor_savebg_32
; Sauve 16 lignes (3 bytes/ligne) sous le curseur. ; Sauve 16 lignes (3 bytes/ligne) sous le curseur.
; Stocke 16 DWORDs: chaque DWORD contient (b0|b1<<8|b2<<16) dans les 24 bits bas. ; Stocke 16 DWORDs: chaque DWORD contient (b0|b1<<8|b2<<16) dans les 24 bits bas.
; ----------------------------------------------- ; -----------------------------------------------
@ -622,7 +947,7 @@ gfx_cursor_savebg:
mov [BDA_MOUSE + mouse.cur_y], dx mov [BDA_MOUSE + mouse.cur_y], dx
; calcule ES:DI pour (x,y) ; calcule ES:DI pour (x,y)
call gfx_calc_addr call cga_calc_addr
; bank_add = +0x2000 si DI<0x2000 sinon -0x2000 ; bank_add = +0x2000 si DI<0x2000 sinon -0x2000
mov bx, 02000h mov bx, 02000h
@ -660,12 +985,12 @@ gfx_cursor_savebg:
ret ret
; ----------------------------------------------- ; -----------------------------------------------
; gfx_cursor_restorebg_32 ; cga_cursor_restorebg_32
; Restaure 16 lignes sauvegardées. ; Restaure 16 lignes sauvegardées.
; Pour ne pas écraser le 4e byte voisin: ; Pour ne pas écraser le 4e byte voisin:
; dst = (dst & 0xFF000000) | (saved & 0x00FFFFFF) ; dst = (dst & 0xFF000000) | (saved & 0x00FFFFFF)
; ----------------------------------------------- ; -----------------------------------------------
gfx_cursor_restorebg: cga_cursor_restorebg:
cmp byte [BDA_MOUSE + mouse.bkg_saved], 0 cmp byte [BDA_MOUSE + mouse.bkg_saved], 0
je .done je .done

View file

@ -8,13 +8,13 @@
%define MEM_DUMP_RESET 8 %define MEM_DUMP_RESET 8
%define MEM_DUMP_NEXT 10 %define MEM_DUMP_NEXT 10
mem_api: memory_api:
dw mem_init dw mem_init
dw mem_detect dw mem_detect
dw mem_alloc dw mem_alloc
dw mem_free dw mem_free
dw mem_dump_reset dw mem_dump_reset
dw mem_dump_next dw mem_dump_next
; ======================= ; =======================
; Contexte en RAM (DS = CTX_SEG) ; Contexte en RAM (DS = CTX_SEG)
@ -33,6 +33,79 @@ dump_cursor dw 0
%define MIN_BLK 12 ; aligné (>= HDR+FTR) %define MIN_BLK 12 ; aligné (>= HDR+FTR)
%define FLAG_USED 1 %define FLAG_USED 1
%define MEM_SEG_DEB 0x0800 ; 0x0800:0000 = 0x8000 (32KB) évite IVT/BDA + stack 7C00
%define MEM_SEG_END 0xA000 ; 0xA000:0000 = 0xA0000 (début zone vidéo)
%define MEM_SEG_STEP 0x0040 ; 1KB = 0x400 bytes = 0x40 paragraphs
; ---------------------------------------------------------------------------
; Détection RAM conventionnelle
; Teste la RAM de MEM_SEG_DEB -> MEM_SEG_END (0xA000, 640KB), par pas de 1KB.
; Méthode: sauvegarde 1 mot, écrit 2 patterns, relit, restaure.
;
; Résultats:
; AX = taille détectée en Ko (KB) à partir de 0 jusqu’au “top conventionnel”
; DX = top_segment (segment du premier Ko NON valide) (optionnel)
;
; Précautions:
; - Ne testez PAS une zone où se trouve votre pile / variables.
; - Si votre pile est à 0000:7C00 (phys 0x7C00), commencez au moins à 0x0800.
; - Ne testez pas au-delà de MEM_SEG_END (0xA000: début VGA/vidéo).
; ---------------------------------------------------------------------------
memory_setup:
xor ax, ax ; AX = compteur KB trouvés
mov dx, MEM_SEG_DEB ; DX = segment courant testé
mov cx, MEM_SEG_END ; CX = segment fin (exclu)
xor di, di ; tester au début du bloc 1KB: ES:0000
.loop_seg:
cmp dx, cx
jae .done
mov es, dx
; sauvegarder le mot existant
mov bx, [es:di]
; pattern 1
mov word [es:di], 0x55AA
cmp word [es:di], 0x55AA
jne .fail_restore
; pattern 2 (inverse)
mov word [es:di], 0xAA55
cmp word [es:di], 0xAA55
jne .fail_restore
; restaurer
mov [es:di], bx
; OK: avancer d’1KB
inc ax ; +1KB valide
add dx, MEM_SEG_STEP
jmp .loop_seg
.fail_restore:
; restaurer avant de sortir
mov [es:di], bx
.done:
; AX contient le nb de KB valides *à partir de MEM_SEG_DEB*.
; Si vous voulez une taille “depuis 0KB”, ajoutez MEM_SEG_DEB*16/1024 = MEM_SEG_DEB/64.
;
; base_kb = MEM_SEG_DEB / 0x0040 (car 1KB = 0x40 segments)
mov bx, MEM_SEG_DEB
shr bx, 6 ; /64 = /0x40 => KB de base
add ax, bx ; AX = taille conventionnelle totale en KB (approx. 0..640)
; DX = segment du premier bloc NON valide (top)
; DX est déjà positionné (segment courant)
; stocker l'information dans le BDA
mov bx, BDA_SEGMENT
mov ds, bx
mov [BDA_INFO_MEM_SIZE], ax
mov [BDA_INFO_MEM_SEG], dx
ret
; ----------------------- ; -----------------------
; mem_detect ; mem_detect
; AX=conv_kb, DX=ebda_seg, CF=0 ; AX=conv_kb, DX=ebda_seg, CF=0

View file

@ -34,41 +34,35 @@
%define I8042_CMD_EN_AUX 0xA8 %define I8042_CMD_EN_AUX 0xA8
%define I8042_CMD_RD_CBYTE 0x20 %define I8042_CMD_RD_CBYTE 0x20
%define I8042_CMD_WR_CBYTE 0x60 %define I8042_CMD_WR_CBYTE 0x60
%define I8042_CMD_DIS_KBD 0xAD %define I8042_CMD_DIS_KBD 0xAD
%define I8042_CMD_DIS_MOUSE 0xA7 %define I8042_CMD_DIS_MOUSE 0xA7
%define I8042_CMD_WRITE_AUX 0xD4 %define I8042_CMD_WRITE_AUX 0xD4
%include "./services/cursor.asm"
; ------------------------------------------------------------ ; ------------------------------------------------------------
; remise a zero des valeurs internes du "drivers" ; remise a zero des valeurs internes du "drivers"
; ;
; ------------------------------------------------------------ ; ------------------------------------------------------------
mouse_reset: mouse_reset:
mov ax, BDA_DATA_SEG mov ax, BDA_DATA_SEG
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:BDA_MOUSE + mouse.idx],0
mov dword [fs:BDA_MOUSE + mouse.buffer],0 mov dword [fs:BDA_MOUSE + mouse.buffer],0
mov byte [fs:BDA_MOUSE + mouse.packetlen],3 ; 3 bytes par défaut mov byte [fs:BDA_MOUSE + mouse.packetlen],3 ; 3 bytes par défaut
mov byte [fs:BDA_MOUSE + mouse.status],0
mov byte [fs:BDA_MOUSE + mouse.status],0 mov word [fs:BDA_MOUSE + mouse.x],320 ; vous pouvez aussi préciser le centre
mov word [fs:BDA_MOUSE + mouse.x],320 ; vous pouvez aussi préciser le centre mov word [fs:BDA_MOUSE + mouse.y],100 ; vous pouvez aussi préciser le centre
mov word [fs:BDA_MOUSE + mouse.y],100 ; vous pouvez aussi préciser le centre ; experiemntal
mov word [fs:BDA_MOUSE + mouse.wheel],0
; experiemntal mov byte [fs:BDA_MOUSE + mouse.cur_visible], 1
mov word [fs:BDA_MOUSE + mouse.wheel],0 mov word [fs:BDA_MOUSE + mouse.cur_x], 0
mov word [fs:BDA_MOUSE + mouse.cur_y], 0
mov byte [fs:BDA_MOUSE + mouse.cur_visible], 1 mov byte [fs:BDA_MOUSE + mouse.cur_drawing], 0
mov word [fs:BDA_MOUSE + mouse.cur_x], 0 mov ax, cs
mov word [fs:BDA_MOUSE + mouse.cur_y], 0 mov word [fs:BDA_MOUSE + mouse.cur_seg], ax
mov byte [fs:BDA_MOUSE + mouse.cur_drawing], 0 mov word [fs:BDA_MOUSE + mouse.cur_ofs], mouse_arrow
ret
mov ax, cs
mov word [fs:BDA_MOUSE + mouse.cur_seg], ax
mov word [fs:BDA_MOUSE + mouse.cur_ofs], mouse_arrow
ret
; ------------------------------------------------------------ ; ------------------------------------------------------------
; initialise le i8042 keyboard and mouse (PS/2) ; initialise le i8042 keyboard and mouse (PS/2)
@ -76,90 +70,71 @@ mouse_reset:
; on envoit les commandes RESET/DEFAULT/STREAM ; on envoit les commandes RESET/DEFAULT/STREAM
; ------------------------------------------------------------ ; ------------------------------------------------------------
mouse_init: mouse_init:
push ds push ds
push ax push ax
; reset des valeurs internes
call mouse_reset
cli
call ps2_wait_ready_write
mov al, I8042_CMD_DIS_KBD ; Disable Keyboard
out i8042_PS2_CTRL, al
call ps2_wait_ready_write
mov al, I8042_CMD_DIS_MOUSE ; Disable Mouse
out i8042_PS2_CTRL, al
; Vider tout ce qui traîne
call ps2_flush_output
; Activer le port souris (AUX)
call ps2_wait_ready_write
mov al, I8042_CMD_EN_AUX
out i8042_PS2_CTRL, al
; Lire command byte
call ps2_wait_ready_write
mov al, I8042_CMD_RD_CBYTE
out i8042_PS2_CTRL, al
; reset des valeurs internes call ps2_read ; AL = command byte
call mouse_reset ; Activer IRQ12 (bit 1)
or al, 02h
mov ah, al
; Réécrire command byte (commande 0x60 envoyée à 0x64)
call ps2_wait_ready_write
mov al, I8042_CMD_WR_CBYTE
out i8042_PS2_CTRL, al
call ps2_wait_ready_write
mov al, ah
out i8042_PS2_DATA, al
call ps2_flush_output
; --- Reset
; réponse attendue : 0xAA, [ID]
mov bl, MOUSE_CMD_RESET
call mouse_sendcmd
call ps2_read ; 0xAA attendu (self-test OK)
call ps2_read ; ID (souvent 0x00)
; --- Default
mov bl, MOUSE_CMD_DEFAULT
call mouse_sendcmd
cli ; --- streaming
mov bl, MOUSE_EN_STREAM
call ps2_wait_ready_write call mouse_sendcmd
mov al, I8042_CMD_DIS_KBD ; Disable Keyboard
out i8042_PS2_CTRL, al
call ps2_wait_ready_write
mov al, I8042_CMD_DIS_MOUSE ; Disable Mouse
out i8042_PS2_CTRL, al
; Vider tout ce qui traîne
call ps2_flush_output
; Activer le port souris (AUX)
call ps2_wait_ready_write
mov al, I8042_CMD_EN_AUX
out i8042_PS2_CTRL, al
; Lire command byte
call ps2_wait_ready_write
mov al, I8042_CMD_RD_CBYTE
out i8042_PS2_CTRL, al
call ps2_read ; AL = command byte
; Activer IRQ12 (bit 1)
or al, 02h
mov ah, al
; Réécrire command byte (commande 0x60 envoyée à 0x64)
call ps2_wait_ready_write
mov al, I8042_CMD_WR_CBYTE
out i8042_PS2_CTRL, al
call ps2_wait_ready_write
mov al, ah
out i8042_PS2_DATA, al
call ps2_flush_output
; --- Reset
; réponse attendue : 0xAA, [ID]
mov bl, MOUSE_CMD_RESET
call mouse_sendcmd
call ps2_read ; 0xAA attendu (self-test OK)
call ps2_read ; ID (souvent 0x00)
; --- Default
mov bl, MOUSE_CMD_DEFAULT
call mouse_sendcmd
; --- streaming
mov bl, MOUSE_EN_STREAM
call mouse_sendcmd
; détecter le packet size (3/4 bytes)
call mouse_detect_packet_len
; installer ISR IRQ12 (INT 74h)
mov ax,cs
mov dx,ax
mov bx, isr_mouse_handler
mov ax, i8259_SLAVE_INT ; base offset IRQ8
add ax,4 ; IRQ 12
call ivt_setvector
; enable IRQ 1
mov ah,IRQ_ENABLED
mov al, 12
call pic_set_irq_mask
sti
pop ax
pop ds
ret
; détecter le packet size (3/4 bytes)
call mouse_detect_packet_len
; installer ISR IRQ12 (INT 74h)
mov ax,cs
mov dx,ax
mov bx, isr_mouse_handler
mov ax, i8259_SLAVE_INT ; base offset IRQ8
add ax,4 ; IRQ 12
call ivt_setvector
; enable IRQ 1
mov ah,IRQ_ENABLED
mov al, 12
call pic_set_irq_mask
sti
pop ax
pop ds
ret
; ------------------------------------------------------------ ; ------------------------------------------------------------
; detect la taille du "payload" de la souris. ; detect la taille du "payload" de la souris.
; ;
@ -167,42 +142,42 @@ mouse_init:
; ;
; ------------------------------------------------------------ ; ------------------------------------------------------------
mouse_detect_packet_len: mouse_detect_packet_len:
mov ax, BDA_DATA_SEG mov ax, BDA_DATA_SEG
mov fs,ax mov fs,ax
mov byte [fs:BDA_MOUSE + mouse.packetlen], 3 mov byte [fs:BDA_MOUSE + mouse.packetlen], 3
; SET_RATE + 200 ; SET_RATE + 200
mov bl, MOUSE_SET_RATE mov bl, MOUSE_SET_RATE
call mouse_sendcmd call mouse_sendcmd
mov bl, 200 mov bl, 200
call mouse_sendcmd call mouse_sendcmd
; SET_RATE + 100 ; SET_RATE + 100
mov bl, MOUSE_SET_RATE mov bl, MOUSE_SET_RATE
call mouse_sendcmd call mouse_sendcmd
mov bl, 100 mov bl, 100
call mouse_sendcmd call mouse_sendcmd
; SET_RATE + 80 ; SET_RATE + 80
mov bl, MOUSE_SET_RATE mov bl, MOUSE_SET_RATE
call mouse_sendcmd call mouse_sendcmd
mov bl, 80 mov bl, 80
call mouse_sendcmd call mouse_sendcmd
; Get ID ; Get ID
mov bl, MOUSE_GET_ID mov bl, MOUSE_GET_ID
call mouse_sendcmd call mouse_sendcmd
call ps2_read ; AL = ID call ps2_read ; AL = ID
cmp al, 03h cmp al, 03h
je .is4 je .is4
cmp al, 04h cmp al, 04h
je .is4 je .is4
ret ret
.is4: .is4:
mov byte [fs:BDA_MOUSE + mouse.packetlen], 4 mov byte [fs:BDA_MOUSE + mouse.packetlen], 4
ret ret
; ------------------------------------------------------------ ; ------------------------------------------------------------
; fonction de gestion du i8042 ; fonction de gestion du i8042
@ -211,41 +186,41 @@ mouse_detect_packet_len:
; attendre que le 8042 soit pret a recevoir de l'information ; attendre que le 8042 soit pret a recevoir de l'information
ps2_wait_ready_write: ps2_wait_ready_write:
push cx push cx
mov cx, 1000 mov cx, 1000
.wait: .wait:
in al, i8042_PS2_CTRL in al, i8042_PS2_CTRL
test al, 02h ; IBF test al, 02h ; IBF
jz .ok jz .ok
loop .wait loop .wait
.ok: .ok:
pop cx pop cx
ret ret
; attendre que le 8042 soit pret a lire de l'information ; attendre que le 8042 soit pret a lire de l'information
ps2_wait_ready_read: ps2_wait_ready_read:
.wait: .wait:
in al, i8042_PS2_CTRL in al, i8042_PS2_CTRL
test al, 01h ; OBF test al, 01h ; OBF
jz .wait jz .wait
ret ret
; lire de l'information depuis le 8042 ; lire de l'information depuis le 8042
ps2_read: ps2_read:
call ps2_wait_ready_read call ps2_wait_ready_read
in al, i8042_PS2_DATA in al, i8042_PS2_DATA
ret ret
; vide le buffer interne du 8042 (information(s) ignorée(s)) ; vide le buffer interne du 8042 (information(s) ignorée(s))
ps2_flush_output: ps2_flush_output:
.flush: .flush:
in al, i8042_PS2_CTRL in al, i8042_PS2_CTRL
test al, 01h test al, 01h
jz .done jz .done
in al, i8042_PS2_DATA in al, i8042_PS2_DATA
jmp .flush jmp .flush
.done: .done:
ret ret
; ------------------------------------------------------------ ; ------------------------------------------------------------
; envoye une commande souris et attends le ACK ; envoye une commande souris et attends le ACK
@ -255,23 +230,23 @@ ps2_flush_output:
; renvoi CF=0 si ACK, CF=1 sinon ; renvoi CF=0 si ACK, CF=1 sinon
; ------------------------------------------------------------ ; ------------------------------------------------------------
mouse_sendcmd: mouse_sendcmd:
call ps2_wait_ready_write call ps2_wait_ready_write
mov al, I8042_CMD_WRITE_AUX mov al, I8042_CMD_WRITE_AUX
out i8042_PS2_CTRL, al out i8042_PS2_CTRL, al
call ps2_wait_ready_write call ps2_wait_ready_write
mov al, bl mov al, bl
out i8042_PS2_DATA, al out i8042_PS2_DATA, al
call ps2_read ; AL = réponse call ps2_read ; AL = réponse
cmp al, MOUSE_ACK cmp al, MOUSE_ACK
jne .bad jne .bad
clc clc
ret ret
.bad: .bad:
stc stc
ret ret
; ------------------------------------------------------------ ; ------------------------------------------------------------
; interrupt handler ; interrupt handler
@ -292,82 +267,81 @@ mouse_sendcmd:
; bit 7 = Y overflow ; bit 7 = Y overflow
; ------------------------------------------------------------ ; ------------------------------------------------------------
isr_mouse_handler: isr_mouse_handler:
; sauvegarder tout les registres ; sauvegarder tout les registres
pusha pusha
push ds push ds
; use BDA segment ; use BDA segment
mov ax,BDA_DATA_SEG mov ax,BDA_DATA_SEG
mov ds,ax mov ds,ax
; 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 [BDA_MOUSE + mouse.idx]
mov byte [BDA_MOUSE + mouse.buffer + bx], al mov byte [BDA_MOUSE + mouse.buffer + bx], al
inc byte [BDA_MOUSE + mouse.idx] inc byte [BDA_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, [BDA_MOUSE + mouse.packetlen]
cmp byte [BDA_MOUSE + mouse.idx], al cmp byte [BDA_MOUSE + mouse.idx], al
jb .done jb .done
; packet complet, on decode les données ; packet complet, on decode les données
mov byte [BDA_MOUSE + mouse.idx], 0 mov byte [BDA_MOUSE + mouse.idx], 0
mov bl, [BDA_MOUSE + mouse.buffer] ; status mov bl, [BDA_MOUSE + mouse.buffer] ; status
mov [BDA_MOUSE + mouse.status], bl mov [BDA_MOUSE + mouse.status], bl
xor ax,ax xor ax,ax
mov al, byte [BDA_MOUSE + mouse.buffer+1] ; delta X mov al, byte [BDA_MOUSE + mouse.buffer+1] ; delta X
test bl,00010000b ; signe X test bl,00010000b ; signe X
jz .x_pos jz .x_pos
or al, 0xF0 or al, 0xF0
.x_pos: .x_pos:
cbw cbw
add [BDA_MOUSE + mouse.x], ax add [BDA_MOUSE + mouse.x], ax
xor ax,ax
xor ax,ax mov al, byte [BDA_MOUSE + mouse.buffer+2] ; delta Y
mov al, byte [BDA_MOUSE + mouse.buffer+2] ; delta Y test bl,00100000b ; signe Y
test bl,00100000b ; signe Y jz .y_pos
jz .y_pos or al, 0xF0
or al, 0xF0
.y_pos: .y_pos:
cbw cbw
sub [BDA_MOUSE + mouse.y], ax sub [BDA_MOUSE + mouse.y], ax
; si packetlen = 4, gérer la molette; experimental ; si packetlen = 4, gérer la molette; experimental
movsx ax, byte [BDA_MOUSE + mouse.buffer+3] ; delta Wheel movsx ax, byte [BDA_MOUSE + mouse.buffer+3] ; delta Wheel
cbw cbw
add word [BDA_MOUSE + mouse.wheel], ax add word [BDA_MOUSE + mouse.wheel], ax
; clamp X ; clamp X
cmp word [BDA_MOUSE + mouse.x], 0 cmp word [BDA_MOUSE + mouse.x], 0
jge .x_ok_low jge .x_ok_low
mov word [BDA_MOUSE + mouse.x], 0 mov word [BDA_MOUSE + mouse.x], 0
.x_ok_low: .x_ok_low:
cmp word [BDA_MOUSE + mouse.x], 639 cmp word [BDA_MOUSE + mouse.x], 639
jle .x_ok_high jle .x_ok_high
mov word [BDA_MOUSE + mouse.x], 639 mov word [BDA_MOUSE + mouse.x], 639
.x_ok_high: .x_ok_high:
; clamp Y ; clamp Y
cmp word [BDA_MOUSE + mouse.y], 0 cmp word [BDA_MOUSE + mouse.y], 0
jge .y_ok_low jge .y_ok_low
mov word [BDA_MOUSE + mouse.y], 0 mov word [BDA_MOUSE + mouse.y], 0
.y_ok_low: .y_ok_low:
cmp word [BDA_MOUSE + mouse.y], 199 cmp word [BDA_MOUSE + mouse.y], 199
jle .y_ok_high jle .y_ok_high
mov word [BDA_MOUSE + mouse.y], 199 mov word [BDA_MOUSE + mouse.y], 199
.y_ok_high: .y_ok_high:
; call gfx_cursor_move ; call gfx_cursor_move
.done: .done:
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 popa
iret iret

View file

@ -20,78 +20,6 @@
; ;
; ============================================================================= ; =============================================================================
%define MEM_SEG_DEB 0x0800 ; 0x0800:0000 = 0x8000 (32KB) évite IVT/BDA + stack 7C00
%define MEM_SEG_END 0xA000 ; 0xA000:0000 = 0xA0000 (début zone vidéo)
%define MEM_SEG_STEP 0x0040 ; 1KB = 0x400 bytes = 0x40 paragraphs
; ---------------------------------------------------------------------------
; Détection RAM conventionnelle
; Teste la RAM de MEM_SEG_DEB -> MEM_SEG_END (0xA000, 640KB), par pas de 1KB.
; Méthode: sauvegarde 1 mot, écrit 2 patterns, relit, restaure.
;
; Résultats:
; AX = taille détectée en Ko (KB) à partir de 0 jusqu’au “top conventionnel”
; DX = top_segment (segment du premier Ko NON valide) (optionnel)
;
; Précautions:
; - Ne testez PAS une zone où se trouve votre pile / variables.
; - Si votre pile est à 0000:7C00 (phys 0x7C00), commencez au moins à 0x0800.
; - Ne testez pas au-delà de MEM_SEG_END (0xA000: début VGA/vidéo).
; ---------------------------------------------------------------------------
ram_setup:
xor ax, ax ; AX = compteur KB trouvés
mov dx, MEM_SEG_DEB ; DX = segment courant testé
mov cx, MEM_SEG_END ; CX = segment fin (exclu)
xor di, di ; tester au début du bloc 1KB: ES:0000
.loop_seg:
cmp dx, cx
jae .done
mov es, dx
; sauvegarder le mot existant
mov bx, [es:di]
; pattern 1
mov word [es:di], 0x55AA
cmp word [es:di], 0x55AA
jne .fail_restore
; pattern 2 (inverse)
mov word [es:di], 0xAA55
cmp word [es:di], 0xAA55
jne .fail_restore
; restaurer
mov [es:di], bx
; OK: avancer d’1KB
inc ax ; +1KB valide
add dx, MEM_SEG_STEP
jmp .loop_seg
.fail_restore:
; restaurer avant de sortir
mov [es:di], bx
.done:
; AX contient le nb de KB valides *à partir de MEM_SEG_DEB*.
; Si vous voulez une taille “depuis 0KB”, ajoutez MEM_SEG_DEB*16/1024 = MEM_SEG_DEB/64.
;
; base_kb = MEM_SEG_DEB / 0x0040 (car 1KB = 0x40 segments)
mov bx, MEM_SEG_DEB
shr bx, 6 ; /64 = /0x40 => KB de base
add ax, bx ; AX = taille conventionnelle totale en KB (approx. 0..640)
; DX = segment du premier bloc NON valide (top)
; DX est déjà positionné (segment courant)
; stocker l'information dans le BDA
mov bx, BDA_SEGMENT
mov ds, bx
mov [BDA_INFO_MEM_SIZE], ax
mov [BDA_INFO_MEM_SEG], dx
ret
; --------------------------------------------------------------------------- ; ---------------------------------------------------------------------------
; Détection les ROM supplementaires ; Détection les ROM supplementaires
@ -147,7 +75,6 @@ setup_check_vga:
.init_ok: .init_ok:
ret ret
; --------------------------------------------------------------------------- ; ---------------------------------------------------------------------------
; IVT install (8088, mode réel) - remplit les 256 vecteurs avec un handler IRET ; IVT install (8088, mode réel) - remplit les 256 vecteurs avec un handler IRET
; --------------------------------------------------------------------------- ; ---------------------------------------------------------------------------