diff --git a/src/bda.asm b/src/bda.asm index d7f7a37..8da813d 100644 --- a/src/bda.asm +++ b/src/bda.asm @@ -48,7 +48,6 @@ ; information relative à la souris ; %define BDA_DATA_SEG 0x0050 -%define BDA_MOUSE 0x0000 %define BKG_DWORDS_PER_LINE 1 ; 1 dword stocké par ligne %define BKG_LINES 16 @@ -56,30 +55,57 @@ %define BKG_TOTAL_BYTES (BKG_TOTAL_DWORDS * 4) ; 64 struc mouse - .buffer resb 4 ; i8042 input buffer - .idx resb 1 ; index in the buffer - .packetlen resb 1 ; max buffer len (3 ou 4) + .buffer resb 4 ; i8042 input buffer + .idx resb 1 ; index in the buffer + .packetlen resb 1 ; max buffer len (3 ou 4) - .status resb 1 ; mouse status (button etc) - .wheel resb 1 ; if a packet size is 4; experimental - .x resw 1 ; - .y resw 1 + .status resb 1 ; mouse status (button etc) + .wheel resb 1 ; if a packet size is 4; experimental + .x resw 1 ; + .y resw 1 ; cursor management - .cur_x resw 1 ; preservation des x,y du background - .cur_y resw 1 - .cur_addr_start resw 1 ; adresse de départ de la sauvegarde - .cur_bank_add resw 1 ; + ou - 0x2000 - .cur_drawing resb 1 - .cur_visible resb 1 - .cur_seg resw 1 ; segment / offset of the pointer - .cur_ofs resw 1 - .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 resd 16 ; buffer for saved background + .cur_x resw 1 ; preservation des x,y du background + .cur_y resw 1 + .cur_addr_start resw 1 ; adresse de départ de la sauvegarde + .cur_bank_add resw 1 ; + ou - 0x2000 + .cur_drawing resb 1 + .cur_visible resb 1 + .cur_seg resw 1 ; segment / offset of the pointer + .cur_ofs resw 1 + .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 + alignb 4 ; alignement 4 bytes + .bkg_buffer resd 16 ; buffer for saved background 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 diff --git a/src/boot.asm b/src/boot.asm index 72b6358..7d0edc3 100644 --- a/src/boot.asm +++ b/src/boot.asm @@ -26,13 +26,16 @@ bits 16 ; configuration du bios ; ; --------------------------------------------------------------------------- -%define DEBUG_PORT 0xe9 ; 0x402 ou 0xe9 +%define DEBUG_PORT 0xe9 ; 0x402 ou 0xe9 ; initial stack -%define STACK_SEG 0x1000 ; segment de base +%define STACK_SEG 0x0800 ; segment de base section .text -bits 16 +bits 16 + +;%include "./common/chartable.asm" +;%include "./common/cursor.asm" ; definition du BDA %include "./bda.asm" @@ -44,152 +47,188 @@ bits 16 %include "./drivers/keyboard_ps2.asm" %include "./services/generic.asm" -err_vganok db 'VGA Not Initialized',0 -;err_end db 'code completed successfully',0 +err_vganok db 'VGA Not Initialized',0 +;err_end db 'code completed successfully',0 + +cpt_txt db '0123456789A123456789B123456789C123456789D123456789E123456789F123456789',0 +helloworld db 'Hello World !',0 reset: - cli - cld + cli + ; 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 - mov ax, STACK_SEG - mov ss, ax - mov sp, 0xFFFE ; haut du segment (64ko de stack), mot-aligné + ; installé une table d'interruption "dummy" + call ivt_setup - ; installé une table d'interruption "dummy" - call ivt_setup + call bda_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 - mov ax,cs - mov dx,ax - mov bx,test_isr - mov ax,i8259_MASTER_INT + call ivt_setvector - call ivt_setvector + ; initialisation des PIC 8259A + call pic_init - ; initialisation des PIC 8259A - call pic_init + ; load Roms + call setup_load_rom - ; load Roms - call setup_load_rom + ; on vérifie que le BIOS VGA a installé une INT 10h + call setup_check_vga - ; on vérifie que le BIOS VGA a installé une INT 10h - call setup_check_vga + ; on initialise le mode texte 80x25 par défaut DEBUG + ;mov ax, 0x0003 + ;int 10h - ; on initialise le mode texte 80x25 par défaut DEBUG - ;mov ax, 0x0003 - ;int 10h + ; enable IRQ 0 + mov ah,IRQ_ENABLED + mov al,0 + call pic_set_irq_mask - ; enable IRQ 0 - mov ah,IRQ_ENABLED - mov al,0 - call pic_set_irq_mask + call kbd_init + sti - call kbd_init - sti + ; on active le mode graphique + GFX_DRV GFX_INIT - ; on active le mode graphique - call gfx_init + call mouse_reset + ;call mouse_init - call mouse_reset - ; call mouse_init +; GFX_DRV GFX_CRS_UPDATE - 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: - mov ax,BDA_DATA_SEG - mov ds,ax + mov ax,BDA_DATA_SEG + mov ds,ax - ;mov dx,0x300 - ;call scr_gotoxy + ;mov dx,0x300 + ;call scr_gotoxy - ;mov al, byte [BDA_TIMER] - ;call scr_puthex8 + ;mov al, byte [BDA_TIMER] + ;call scr_puthex8 - cmp byte [BDA_TIMER],5 - ja .skip2 + ;cmp byte [BDA_TIMER],5 + ;ja .skip2 - mov ax, [BDA_MOUSE + mouse.x] - add ax, 25 - cmp ax,640 - jb .moveok + ;mov ax, [BDA_MOUSE + mouse.x] + ;add ax, 25 + ;cmp ax,640 + ;jb .moveok ; - mov ax,0 + mov ax,0 .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 - jge .skip + cmp byte [BDA_MOUSE + mouse.buffer+1], 0 + jge .skip - ;mov dx,0x400 - ;call scr_gotoxy + ;mov dx,0x400 + ;call scr_gotoxy - ;mov al, byte [BDA_MOUSE + mouse.buffer+1] - ;call scr_puthex8 + ;mov al, byte [BDA_MOUSE + mouse.buffer+1] + ;call scr_puthex8 .skip: - ;cmp byte [BDA_MOUSE + mouse.buffer+2], 0 - ;jge .skip2 + ;cmp byte [BDA_MOUSE + mouse.buffer+2], 0 + ;jge .skip2 - ;mov dx,0x404 - ;call scr_gotoxy + ;mov dx,0x404 + ;call scr_gotoxy - ;mov al, byte [BDA_MOUSE + mouse.buffer+2] - ;call scr_puthex8 + ;mov al, byte [BDA_MOUSE + mouse.buffer+2] + ;call scr_puthex8 .skip2: - ;mov dx,0 - ;call scr_gotoxy + ;mov dx,0 + ;call scr_gotoxy - ;mov ax,[BDA_MOUSE] ; adresse début dump - ;mov si,ax - mov cx, 0x20 + ;mov ax,[BDA_MOUSE] ; adresse début dump + ;mov si,ax + mov cx, 0x20 .dump: -; test cx,0x000F -; jnz .sameline -; inc dh -; xor dl,dl -; call scr_gotoxy +; test cx,0x000F +; jnz .sameline +; inc dh +; xor dl,dl +; call scr_gotoxy ;.sameline: -; mov al,[ds:si] -; inc si +; mov al,[ds:si] +; inc si -; push ds -; push si +; push ds +; push si -; call scr_puthex8 -; mov al,' ' -; call scr_putc +; call scr_puthex8 +; mov al,' ' +; call scr_putc -; pop si -; pop ds +; pop si +; pop ds - nop + nop - loop .dump + loop .dump - jmp endless + jmp endless ; ----------------------------------------------------------- -; Keyboard ISR (IRQ -> INT) +; timer ISR (IRQ -> INT) ; ----------------------------------------------------------- test_isr: - push ax + push ax - push fs - mov ax,BDA_DATA_SEG - mov fs,ax - inc byte [fs:BDA_TIMER] + push fs + mov ax,BDA_DATA_SEG + mov fs,ax +; inc byte [fs:BDA_TIMER] - mov al, PIC_EOI ; EOI master - out i8259_MASTER_CMD, al - pop fs + mov al, PIC_EOI ; EOI master + out i8259_MASTER_CMD, al + pop fs - pop ax - iret + pop ax + iret ; ------------------------------------------------------------------ ; Padding jusqu'au reset vector @@ -200,13 +239,15 @@ times 0xFFF0 - ($ - $$) db 0xFF ; RESET VECTOR (exécuté par le CPU) ; ------------------------------------------------------------------ section .resetvect -bits 16 +bits 16 global reset_vector reset_vector: - ; code minimal au reset - jmp 0xF000:reset -builddate db '06/01/2026' - times 16-($-$$) db 0 ; le stub tient dans 16 octets (ou moins) + ; code minimal au reset + jmp 0xF000:reset + +builddate: + db '06/01/2026' + times 16-($-$$) db 0 ; le stub tient dans 16 octets (ou moins) diff --git a/src/common/chartable-1.asm b/src/common/chartable-1.asm new file mode 100644 index 0000000..a3639a1 --- /dev/null +++ b/src/common/chartable-1.asm @@ -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 '~' + diff --git a/src/common/chartable.asm b/src/common/chartable.asm new file mode 100644 index 0000000..882af0a --- /dev/null +++ b/src/common/chartable.asm @@ -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 + diff --git a/src/services/cursor.asm b/src/common/cursor.asm similarity index 100% rename from src/services/cursor.asm rename to src/common/cursor.asm diff --git a/src/drivers/gfx.asm b/src/drivers/gfx.asm index 8f12e4c..b2419fc 100644 --- a/src/drivers/gfx.asm +++ b/src/drivers/gfx.asm @@ -1,86 +1,43 @@ -; ============================================================================= -; Project : Custom BIOS / ROM -; File : boot.asm -; Author : frater -; Created : 06 jan 2026 -; -; 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 . -; -; ============================================================================= +; On doit répartir sur 2 octets : + ; mask0 = glyph >> shift + ; mask1 = glyph << (8-shift) + ; + ; Utilise AH pour conserver glyph original + mov ah, al + ; 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) -%define GFX_WIDTH 640 -%define GFX_HEIGHT 200 - -gfx_init: - ; init graphics mode - mov ah, 0x00 ; AH=00h set video mode - mov al, GFX_MODE - int 0x10 - - call gfx_background - - ret - -; PutPixel(x=cx, y=dx, color=al) sur page bh -gfx_putpixel: - mov ah, 0Ch - ;mov al, 0Fh ; couleur (0..15) - ;mov bh, 00h ; page - ;mov cx, 100 ; x - ;mov dx, 50 ; y - int 10h - 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 \ No newline at end of file + ; Si mask0/mask1 nuls, saute ce côté +%if GFX_CHAR_COL = 1 + test al, al + jz .skip0_set + or [es:di], al +.skip0_set: + test ah, ah + jz .skip1_set + or [es:di+1], ah +.skip1_set: +%else + test al, al + jz .skip0_clr + not al + and [es:di], al +.skip0_clr: + test ah, ah + jz .skip1_clr + not ah + and [es:di+1], ah +.skip1_clr: +%endif \ No newline at end of file diff --git a/src/drivers/gfx_cgam.asm b/src/drivers/gfx_cgam.asm index 4de8c8a..1062da7 100644 --- a/src/drivers/gfx_cgam.asm +++ b/src/drivers/gfx_cgam.asm @@ -23,35 +23,84 @@ ; ; 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_WIDTH 640 +%define GFX_MODE 0x06 ; MCGA HiRes (B/W) +%define GFX_WIDTH 640 %define GFX_HEIGHT 200 -%define CGA_STRIDE 80 -%define CGA_ODD_BANK 0x2000 +%define CGA_STRIDE 80 +%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) ; Cette table doit être située au début du driver pour être ; 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 -%define PUTPIXEL 3 -%define GETPIXEL 6 -%define MOUSE_UPDATE 9 - -gfx_api: - jmp gfx_init ; Offset +0: Initialisation - jmp gfx_putpixel ; Offset +3: Dessin pixel - jmp gfx_getpixel ; Offset +6: Lecture pixel - jmp gfx_cursor_move ; Offset +9: mouse update +graph_driver: + dw cga_init + dw cga_putpixel + dw cga_getpixel + dw cga_set_charpos + dw cga_none + dw cga_putc + dw cga_write + dw cga_cursor_move ; jmp gfx_fill_rect ; Remplissage rectangle (Nouveau) ; jmp gfx_invert_rect ; Offset +12: Inversion (Nouveau pour Menus) ; 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 ; @@ -72,51 +121,335 @@ gfx_api: ; ; ce mode est entrelacé, un bit/pixel, 8 pixels par octet ; ------------------------------------------------------------ -gfx_init: - ; init graphics mode - mov ah, 0x00 ; AH=00h set video mode - mov al, GFX_MODE - int 0x10 +cga_init: + mov ax, BDA_DATA_SEG + mov ds, ax - 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" - call gfx_background + mov byte [BDA_GFX + gfx.cur_mode], 1 + ; 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 ; ; Out: ES=VIDEO_SEG, DI=offset, AH=bitmask (0x80 >> (x&7)) ; ------------------------------------------------------------ -gfx_calc_addr: - ; calcul de l'offset 'y': - ; si y est impaire, DI+=0x2000 - ; DI = (y>>1)*80 + (x>>3) + (y&1)*0x2000 - mov ax, dx - shr ax, 1 ; ax = y/2 - - mov di, ax - shl di, 4 ; (y/2)*16 - shl ax, 6 ; (y/2)*64 - add di, ax ; *80 - - mov ax, cx - shr ax, 3 - add di, ax - - test dl, 1 - jz .even - add di, CGA_ODD_BANK +cga_calc_addr: + ; calcul de l'offset 'y': + ; si y est impaire, DI+=0x2000 + ; DI = (y>>1)*80 + (x>>3) + (y&1)*0x2000 + mov ax, dx + shr ax, 1 ; ax = y/2 + mov di, ax + shl di, 4 ; (y/2)*16 + shl ax, 6 ; (y/2)*64 + add di, ax ; *80 + mov ax, cx + shr ax, 3 + add di, ax + test dl, 1 + jz .even + add di, CGA_ODD_BANK .even: - ; masque bit = 0x80 >> (x&7) - push cx - and cl, 7 - mov ah, 080h - shr ah, cl - pop cx - ret + ; masque bit = 0x80 >> (x&7) + push cx + and cl, 7 + mov ah, 080h + shr ah, cl + pop cx + ret ; ------------------------------------------------------------ ; Dessine un pixel, accès VRAM direct. @@ -126,22 +459,22 @@ gfx_calc_addr: ; ES = Target Segment (usually VIDEO_SEG) ; BL = color (0=black, !=0=white) ; ------------------------------------------------------------ -gfx_local_putpixel: - call gfx_calc_addr +cga_local_putpixel: + call cga_calc_addr - ; write - cmp bl, 0 - je .clear + ; write + cmp bl, 0 + je .clear .set: - or byte [es:di], ah - jmp .done + or byte [es:di], ah + jmp .done .clear: - not ah - and byte [es:di], ah + not ah + and byte [es:di], ah .done: - ret + ret ; ------------------------------------------------------------ ; Dessine un pixel, accès VRAM direct. @@ -150,76 +483,76 @@ gfx_local_putpixel: ; DX = y (0..199) ; BL = color (0=black, !=0=white) ; ------------------------------------------------------------ -gfx_putpixel: - push ax - push di - push es +cga_putpixel: + push ax + push di + push es - mov ax, VIDEO_SEG - mov es,ax - call gfx_calc_addr + mov ax, VIDEO_SEG + mov es,ax + call cga_calc_addr - ; write - cmp bl, 0 - je .clear + ; write + cmp bl, 0 + je .clear .set: - or byte [es:di], ah - jmp .done + or byte [es:di], ah + jmp .done .clear: - not ah - and byte [es:di], ah + not ah + and byte [es:di], ah .done: - pop es - pop di - pop ax - ret + pop es + pop di + pop ax + ret ; ------------------------------------------------------------ ; Lit un pixel (CX=x, DX=y) ; Out: AL=0/1 ; ------------------------------------------------------------ -gfx_getpixel: - push di - push es +cga_getpixel: + push di + push es - call gfx_calc_addr - mov al, [es:di] - and al, ah - setnz al + call cga_calc_addr + mov al, [es:di] + and al, ah + setnz al - pop es - pop di - ret + pop es + pop di + ret ; ------------------------------------------------------------ ; Dessine un background "check-board", accès VRAM direct. ; ; ------------------------------------------------------------ -gfx_background: - mov ax,VIDEO_SEG - mov es,ax - 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 +cga_background: + mov ax,VIDEO_SEG + mov es,ax + 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 ; ------------------------------------------------------------ ; Calcule les infos de l'alignement du curseur, basé sur cx=X ; il est important que DS pointe sur le BDA_MOUSE_SEG ; Out: BDA_CURSOR_BITOFF, BDA_CURSOR_BYTES ; ------------------------------------------------------------ -gfx_cursor_calc_align: - mov al, cl - and al, 7 ; offset = x&7 - mov byte [BDA_MOUSE + mouse.cur_bit_ofs], al - ret +cga_cursor_calc_align: + mov al, cl + and al, 7 ; offset = x&7 + mov byte [BDA_MOUSE + mouse.cur_bit_ofs], al + ret ; ------------------------------------------------------------ ; Dessine un pixel, en [ES:DI] accès VRAM direct. @@ -228,62 +561,54 @@ gfx_cursor_calc_align: ; DX = y (0..199) ; BL = color (0=black, !=0=white) ; ------------------------------------------------------------ -gfx_putpixel_fast: - cmp bl, 0 - je .clear +cga_putpixel_fast: + cmp bl, 0 + je .clear .set: - or byte [es:di], ah - jmp .done + or byte [es:di], ah + jmp .done .clear: - not ah - and byte [es:di], ah + not ah + and byte [es:di], ah .done: - ret + ret ; ------------------------------------------------------------ ; Lit un pixel, en [ES:DI] accès VRAM direct. ; ; ------------------------------------------------------------ -gfx_getpixel_fast: - mov al, [es:di] - and al, ah - setnz al - ret +cga_getpixel_fast: + mov al, [es:di] + and al, ah + setnz al + ret -gfx_cursor_move: - pusha - push ds - push es +cga_cursor_move: + pusha + push ds + push es - ; move Data Segment - mov ax, BDA_DATA_SEG - mov ds, ax + ; move Data Segment + mov ax, BDA_DATA_SEG + mov ds, ax - cmp byte [BDA_MOUSE + mouse.cur_drawing],0 - jne .done - mov byte [BDA_MOUSE + mouse.cur_drawing],1 + 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 + mov ax, VIDEO_SEG + mov es, ax - ;call gfx_cursor_restorebg + ;call cga_cursor_restorebg - ;call gfx_cursor_savebg - - call gfx_cursor_draw - mov byte [BDA_MOUSE + mouse.cur_drawing],0 + ;call cga_cursor_savebg + call cga_cursor_draw + mov byte [BDA_MOUSE + mouse.cur_drawing],0 .done: - pop es - pop ds - popa - ret - -bits 16 - -%define GFX_WIDTH 640 -%define GFX_HEIGHT 200 -%define CGA_STRIDE 80 -%define CGA_ODD_BANK 0x2000 + pop es + pop ds + popa + ret ; ============================================================ ; gfx_cursor_draw_rm16_i386_self @@ -292,7 +617,7 @@ bits 16 ; Sortie: rien ; Détruit: registres sauvegardés/restaurés (PUSHA/POPA) ; ============================================================ -gfx_cursor_draw_rm16_i386_self: +cga_cursor_draw: push es push gs pusha @@ -605,7 +930,7 @@ gfx_cursor_draw_rm16_i386_self: ret ; ----------------------------------------------- -; gfx_cursor_savebg_32 +; cga_cursor_savebg_32 ; 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. ; ----------------------------------------------- @@ -622,7 +947,7 @@ gfx_cursor_savebg: mov [BDA_MOUSE + mouse.cur_y], dx ; calcule ES:DI pour (x,y) - call gfx_calc_addr + call cga_calc_addr ; bank_add = +0x2000 si DI<0x2000 sinon -0x2000 mov bx, 02000h @@ -660,12 +985,12 @@ gfx_cursor_savebg: ret ; ----------------------------------------------- -; gfx_cursor_restorebg_32 +; cga_cursor_restorebg_32 ; Restaure 16 lignes sauvegardées. ; Pour ne pas écraser le 4e byte voisin: ; dst = (dst & 0xFF000000) | (saved & 0x00FFFFFF) ; ----------------------------------------------- -gfx_cursor_restorebg: +cga_cursor_restorebg: cmp byte [BDA_MOUSE + mouse.bkg_saved], 0 je .done diff --git a/src/drivers/memory.asm b/src/drivers/memory.asm index 0400811..188051f 100644 --- a/src/drivers/memory.asm +++ b/src/drivers/memory.asm @@ -8,13 +8,13 @@ %define MEM_DUMP_RESET 8 %define MEM_DUMP_NEXT 10 -mem_api: - dw mem_init - dw mem_detect - dw mem_alloc - dw mem_free - dw mem_dump_reset - dw mem_dump_next +memory_api: + dw mem_init + dw mem_detect + dw mem_alloc + dw mem_free + dw mem_dump_reset + dw mem_dump_next ; ======================= ; Contexte en RAM (DS = CTX_SEG) @@ -33,6 +33,79 @@ dump_cursor dw 0 %define MIN_BLK 12 ; aligné (>= HDR+FTR) %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 ; AX=conv_kb, DX=ebda_seg, CF=0 diff --git a/src/drivers/mouse_ps2.asm b/src/drivers/mouse_ps2.asm index 83c683d..480a1cb 100644 --- a/src/drivers/mouse_ps2.asm +++ b/src/drivers/mouse_ps2.asm @@ -34,41 +34,35 @@ %define I8042_CMD_EN_AUX 0xA8 %define I8042_CMD_RD_CBYTE 0x20 %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_WRITE_AUX 0xD4 -%include "./services/cursor.asm" - ; ------------------------------------------------------------ ; remise a zero des valeurs internes du "drivers" ; ; ------------------------------------------------------------ mouse_reset: - mov ax, BDA_DATA_SEG - mov fs,ax + mov ax, BDA_DATA_SEG + mov fs,ax - ; effacer les variables du drivers - mov byte [fs:BDA_MOUSE + mouse.idx],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.status],0 - 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 - - ; experiemntal - mov word [fs:BDA_MOUSE + mouse.wheel],0 - - mov byte [fs:BDA_MOUSE + mouse.cur_visible], 1 - 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_drawing], 0 - - mov ax, cs - mov word [fs:BDA_MOUSE + mouse.cur_seg], ax - mov word [fs:BDA_MOUSE + mouse.cur_ofs], mouse_arrow - ret + ; effacer les variables du drivers + mov byte [fs:BDA_MOUSE + mouse.idx],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.status],0 + 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 + ; experiemntal + mov word [fs:BDA_MOUSE + mouse.wheel],0 + mov byte [fs:BDA_MOUSE + mouse.cur_visible], 1 + 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_drawing], 0 + 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) @@ -76,90 +70,71 @@ mouse_reset: ; on envoit les commandes RESET/DEFAULT/STREAM ; ------------------------------------------------------------ mouse_init: - push ds - push ax + push ds + 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 mouse_reset + 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 - 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 - - 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 + ; --- 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 ; ------------------------------------------------------------ ; detect la taille du "payload" de la souris. ; @@ -167,42 +142,42 @@ mouse_init: ; ; ------------------------------------------------------------ mouse_detect_packet_len: - mov ax, BDA_DATA_SEG - mov fs,ax + mov ax, BDA_DATA_SEG + mov fs,ax - mov byte [fs:BDA_MOUSE + mouse.packetlen], 3 + mov byte [fs:BDA_MOUSE + mouse.packetlen], 3 - ; SET_RATE + 200 - mov bl, MOUSE_SET_RATE - call mouse_sendcmd - mov bl, 200 - call mouse_sendcmd + ; SET_RATE + 200 + mov bl, MOUSE_SET_RATE + call mouse_sendcmd + mov bl, 200 + call mouse_sendcmd - ; SET_RATE + 100 - mov bl, MOUSE_SET_RATE - call mouse_sendcmd - mov bl, 100 - call mouse_sendcmd + ; SET_RATE + 100 + mov bl, MOUSE_SET_RATE + call mouse_sendcmd + mov bl, 100 + call mouse_sendcmd - ; SET_RATE + 80 - mov bl, MOUSE_SET_RATE - call mouse_sendcmd - mov bl, 80 - call mouse_sendcmd + ; SET_RATE + 80 + mov bl, MOUSE_SET_RATE + call mouse_sendcmd + mov bl, 80 + call mouse_sendcmd - ; Get ID - mov bl, MOUSE_GET_ID - call mouse_sendcmd - call ps2_read ; AL = ID + ; Get ID + mov bl, MOUSE_GET_ID + call mouse_sendcmd + call ps2_read ; AL = ID - cmp al, 03h - je .is4 - cmp al, 04h - je .is4 - ret + cmp al, 03h + je .is4 + cmp al, 04h + je .is4 + ret .is4: - mov byte [fs:BDA_MOUSE + mouse.packetlen], 4 - ret + mov byte [fs:BDA_MOUSE + mouse.packetlen], 4 + ret ; ------------------------------------------------------------ ; fonction de gestion du i8042 @@ -211,41 +186,41 @@ mouse_detect_packet_len: ; attendre que le 8042 soit pret a recevoir de l'information ps2_wait_ready_write: - push cx - mov cx, 1000 + push cx + mov cx, 1000 .wait: - in al, i8042_PS2_CTRL - test al, 02h ; IBF - jz .ok - loop .wait + in al, i8042_PS2_CTRL + test al, 02h ; IBF + jz .ok + loop .wait .ok: - pop cx - ret + pop cx + ret ; attendre que le 8042 soit pret a lire de l'information ps2_wait_ready_read: .wait: - in al, i8042_PS2_CTRL - test al, 01h ; OBF - jz .wait - ret + in al, i8042_PS2_CTRL + test al, 01h ; OBF + jz .wait + ret ; lire de l'information depuis le 8042 ps2_read: - call ps2_wait_ready_read - in al, i8042_PS2_DATA - ret + call ps2_wait_ready_read + in al, i8042_PS2_DATA + ret ; vide le buffer interne du 8042 (information(s) ignorée(s)) ps2_flush_output: .flush: - in al, i8042_PS2_CTRL - test al, 01h - jz .done - in al, i8042_PS2_DATA - jmp .flush + in al, i8042_PS2_CTRL + test al, 01h + jz .done + in al, i8042_PS2_DATA + jmp .flush .done: - ret + ret ; ------------------------------------------------------------ ; envoye une commande souris et attends le ACK @@ -255,23 +230,23 @@ ps2_flush_output: ; renvoi CF=0 si ACK, CF=1 sinon ; ------------------------------------------------------------ mouse_sendcmd: - call ps2_wait_ready_write + call ps2_wait_ready_write - mov al, I8042_CMD_WRITE_AUX - out i8042_PS2_CTRL, al + mov al, I8042_CMD_WRITE_AUX + out i8042_PS2_CTRL, al - call ps2_wait_ready_write - mov al, bl - out i8042_PS2_DATA, al + call ps2_wait_ready_write + mov al, bl + out i8042_PS2_DATA, al - call ps2_read ; AL = réponse - cmp al, MOUSE_ACK - jne .bad - clc - ret + call ps2_read ; AL = réponse + cmp al, MOUSE_ACK + jne .bad + clc + ret .bad: - stc - ret + stc + ret ; ------------------------------------------------------------ ; interrupt handler @@ -292,82 +267,81 @@ mouse_sendcmd: ; bit 7 = Y overflow ; ------------------------------------------------------------ isr_mouse_handler: - ; sauvegarder tout les registres - pusha - push ds + ; sauvegarder tout les registres + pusha + push ds - ; use BDA segment - mov ax,BDA_DATA_SEG - mov ds,ax + ; use BDA segment + mov ax,BDA_DATA_SEG + mov ds,ax - ; lire un octet depuis le contrôleur et le stocker dans le buffer - in al, i8042_PS2_DATA ; lire octet souris + ; lire un octet depuis le contrôleur et le stocker dans le buffer + in al, i8042_PS2_DATA ; lire octet souris - movzx bx, byte [BDA_MOUSE + mouse.idx] - mov byte [BDA_MOUSE + mouse.buffer + bx], al - inc byte [BDA_MOUSE + mouse.idx] + movzx bx, byte [BDA_MOUSE + mouse.idx] + mov byte [BDA_MOUSE + mouse.buffer + bx], al + inc byte [BDA_MOUSE + mouse.idx] - ; vérifier si le packet est complet - mov al, [BDA_MOUSE + mouse.packetlen] - cmp byte [BDA_MOUSE + mouse.idx], al - jb .done + ; vérifier si le packet est complet + mov al, [BDA_MOUSE + mouse.packetlen] + cmp byte [BDA_MOUSE + mouse.idx], al + jb .done - ; packet complet, on decode les données - mov byte [BDA_MOUSE + mouse.idx], 0 - mov bl, [BDA_MOUSE + mouse.buffer] ; status - mov [BDA_MOUSE + mouse.status], bl + ; packet complet, on decode les données + mov byte [BDA_MOUSE + mouse.idx], 0 + mov bl, [BDA_MOUSE + mouse.buffer] ; status + mov [BDA_MOUSE + mouse.status], bl - xor ax,ax - mov al, byte [BDA_MOUSE + mouse.buffer+1] ; delta X - test bl,00010000b ; signe X - jz .x_pos - or al, 0xF0 + xor ax,ax + mov al, byte [BDA_MOUSE + mouse.buffer+1] ; delta X + test bl,00010000b ; signe X + jz .x_pos + or al, 0xF0 .x_pos: - cbw - add [BDA_MOUSE + mouse.x], ax + cbw + add [BDA_MOUSE + mouse.x], ax - - xor ax,ax - mov al, byte [BDA_MOUSE + mouse.buffer+2] ; delta Y - test bl,00100000b ; signe Y - jz .y_pos - or al, 0xF0 + xor ax,ax + mov al, byte [BDA_MOUSE + mouse.buffer+2] ; delta Y + test bl,00100000b ; signe Y + jz .y_pos + or al, 0xF0 .y_pos: - cbw - sub [BDA_MOUSE + mouse.y], ax + cbw + sub [BDA_MOUSE + mouse.y], ax - ; si packetlen = 4, gérer la molette; experimental - movsx ax, byte [BDA_MOUSE + mouse.buffer+3] ; delta Wheel - cbw - add word [BDA_MOUSE + mouse.wheel], ax + ; si packetlen = 4, gérer la molette; experimental + movsx ax, byte [BDA_MOUSE + mouse.buffer+3] ; delta Wheel + cbw + add word [BDA_MOUSE + mouse.wheel], ax - ; clamp X - cmp word [BDA_MOUSE + mouse.x], 0 - jge .x_ok_low - mov word [BDA_MOUSE + mouse.x], 0 + ; clamp X + cmp word [BDA_MOUSE + mouse.x], 0 + jge .x_ok_low + mov word [BDA_MOUSE + mouse.x], 0 .x_ok_low: - cmp word [BDA_MOUSE + mouse.x], 639 - jle .x_ok_high - mov word [BDA_MOUSE + mouse.x], 639 + cmp word [BDA_MOUSE + mouse.x], 639 + jle .x_ok_high + mov word [BDA_MOUSE + mouse.x], 639 .x_ok_high: - ; clamp Y - cmp word [BDA_MOUSE + mouse.y], 0 - jge .y_ok_low - mov word [BDA_MOUSE + mouse.y], 0 + ; clamp Y + cmp word [BDA_MOUSE + mouse.y], 0 + jge .y_ok_low + mov word [BDA_MOUSE + mouse.y], 0 .y_ok_low: - cmp word [BDA_MOUSE + mouse.y], 199 - jle .y_ok_high - mov word [BDA_MOUSE + mouse.y], 199 + cmp word [BDA_MOUSE + mouse.y], 199 + jle .y_ok_high + mov word [BDA_MOUSE + mouse.y], 199 .y_ok_high: - ; call gfx_cursor_move + ; call gfx_cursor_move .done: - mov al, 0x20 - out i8259_SLAVE_CMD, al ; EOI PIC esclave - out i8259_MASTER_CMD, al ; EOI PIC maître + mov al, 0x20 + out i8259_SLAVE_CMD, al ; EOI PIC esclave + out i8259_MASTER_CMD, al ; EOI PIC maître - ; restaurer tous les registres - pop ds - popa - iret \ No newline at end of file + ; restaurer tous les registres + pop ds + popa + iret \ No newline at end of file diff --git a/src/services/generic.asm b/src/services/generic.asm index 9fbbd67..837b92d 100644 --- a/src/services/generic.asm +++ b/src/services/generic.asm @@ -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 @@ -147,7 +75,6 @@ setup_check_vga: .init_ok: ret - ; --------------------------------------------------------------------------- ; IVT install (8088, mode réel) - remplit les 256 vecteurs avec un handler IRET ; ---------------------------------------------------------------------------