;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; ;; BOOTCODE.INC ;; ;; ;; ;; 16 bit bootcode for MenuetOS ;; ;; ;; ;; Copyright 2002 Ville Turjanmaa ;; ;; ;; ;; See file COPYING for details ;; ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;========================================================================== ; ; 16 BIT FUNCTIONS ; ;========================================================================== print: push si mov si,leftpr-0x10000 call printplain pop si printplain: pusha mov dx,0x1000 mov es,dx cmp byte [es:display_atboot-0x10000],2 je printplain_exit mov ds,dx cld lodsb prpl1: mov ah,0xe xor bh,bh int 0x10 lodsb cmp al,0 jne prpl1 printplain_exit: popa ret setbase1000: push ax mov ax,0x1000 mov es,ax mov ds,ax pop ax ret getkey: push ecx push edx add ebx,0x0101 xor eax,eax gk1: in al,0x60 mov cl,al gk0: in al,0x60 cmp al,cl je gk0 cmp ax,11 jg gk0 gk0_1: mov cl,al ; add al,47 ; mov [ds:keyinbs-0x10000],al ; mov si,keyinbs-0x10000 ; call printplain gk12: in al,0x60 cmp al,cl je gk12 cmp ax,240 jne gk13 mov al,cl jmp gk14 gk13: add cl,128 cmp al,cl jne gk1 sub al,128 gk14: movzx edx,bl cmp eax,edx jb gk1 movzx edx,bh cmp eax,edx jg gk1 test ebx,0x010000 jnz gk3 mov cx,0x1000 mov dx,cx add eax,47 mov cx,ax cmp cx,58 jb gk_nozero sub cx,10 gk_nozero: mov [ds:keyin-0x10000],cl mov si,keyin-0x10000 call printplain gk3: sub eax,48 pop edx pop ecx ret ;========================================================================= ; ; 16 BIT CODE ; ;========================================================================= start_of_code: ; RESET 16 BIT SELECTORS/REGISTERS/STACK mov ax,0x1000 mov es,ax mov ds,ax mov ax,0x3000 mov ss,ax mov sp,0xec00 xor ax,ax xor bx,bx xor cx,cx xor dx,dx xor si,si xor di,di xor bp,bp ; DRAW FRAMES call setbase1000 cmp byte [es:display_atboot-0x10000],2 je no_mode_atboot mov ax,0x0003 mov bx,0x0000 mov dx,0x0000 int 0x10 no_mode_atboot: ; Load & set russian VGA font (RU.INC) mov bp,RU_FNT1-10000h ; RU_FNT1 - First part mov bx,1000h ; 768 bytes mov cx,30h ; 48 symbols mov dx,80h ; 128 - position of first symbol mov ax,1100h push cs pop es int 10h mov bp,RU_FNT2-10000h ; RU_FNT2 -Second part mov bx,1000h ; 512 bytes mov cx,20h ; 32 symbols mov dx,0E0h ; 224 - position of first symbol mov ax,1100h push cs pop es int 10h ; End set VGA russian font call setbase1000 mov ax,0xb800 mov es,ax mov di,0 mov si,d80x25-0x10000 mov cx,80*25 mov ah,1*16+15 dfl1: cld lodsb stosw loop dfl1 call setbase1000 ; SAY HI TO USER mov si,linef2-0x10000 call printplain mov si,version-0x10000 call print ; TEST FOR 386+ pushf pop ax mov dx,ax xor ax,0x4000 push ax popf pushf pop ax and ax,0x4000 and dx,0x4000 cmp ax,dx jnz cpugood mov si,not386-0x10000 call print jmp $ cpugood: ; RESET 32 BIT SELECTORS/REGISTERS/SELECTORS mov ax,0x1000 mov es,ax mov ds,ax mov ax,0x3000 mov ss,ax mov esp,0xec00 xor eax,eax xor ebx,ebx xor ecx,ecx xor edx,edx xor esi,esi xor edi,edi xor ebp,ebp ; FLUSH 8042 KEYBOARD CONTROLLER ;// mike.dld [ ; mov al,0xED ; out 0x60,al ; or cx,-1 ; @@: ; in al,0x64 ; test al,2 ; jz @f ; loop @b ; @@: ; mov al,0 ; out 0x60,al ; or cx,-1 ; @@: ; in al,0x64 ; test al,2 ; jz @f ; loop @b ; @@: ;// mike.dld ] ; mov ecx,10000 ; fl1: ; in al,0x64 ; loop fl1 ; test al,1 ; jz fl2 ; in al,0x60 ; jmp fl1 ; fl2: ;**************************************************************** ; The function is modified Mario79 ;***************************************************************** ; wait_kbd: ; variant 1 ; mov cx,2500h ;задержка порядка 10 мсек ; test_kbd: ; in al,64h ;читаем состояние клавиатуры ; test al,2 ;проверка бита готовности ; loopnz test_kbd mov al,0xf6 ; Сброс клавиатуры, разрешить сканирование out 0x60,al mov cx,0 wait_loop: ; variant 2 ; reading state of port of 8042 controller in al,64h and al,00000010b ; ready flag ; wait until 8042 controller is ready loopnz wait_loop ; DISPLAY VESA INFORMATION mov ax,0x0 mov es,ax mov ax,0x4f00 mov di,0xa000 int 0x10 cmp ax,0x004f je vesaok2 mov dx,0x1000 mov es,dx mov si,novesa-0x10000 call print mov ax,16 jmp novesafound vesaok2: mov ax,[es:di+4] mov dx,ax add ax,'0'*256+'0' push word 0x1000 pop es mov [es:vervesa+vervesa_off-0x10000], ah mov [es:vervesa+vervesa_off+2-0x10000], al ; ivan 24/11/2004 begin ;push ax ; ivan 24/11/2004 end mov si,vervesa-0x10000 call print novesafound: call setbase1000 ; ivan 24/11/2004 begin ;pop bx ; ivan 24/11/2004 end ; ASK GRAPHICS MODE movzx eax,byte [es:preboot_graph-0x10000] cmp eax,0 jne pre_graph mov si,gr_mode-0x10000 call printplain gml0: mov ebx,0x0A01 call getkey pre_graph: cmp eax,1 jl sgml1 cmp eax,8 jg sgml1 mov si,ax sub si,1 shl si,4 add si,gr_table-0x10000 mov bx,[es:si+0] mov cx,[es:si+4] mov dx,[es:si+8] jmp gml10 sgml1: cmp al,9 jnz gml00 mov bx,0x13 mov cx,640 mov dx,480 push word 0x0 pop es mov [es:0x9000],byte 32 mov dword [es:0x9018],0x800000 push word 0x1000 pop es jmp gml10 gml00: cmp al,0xa jnz gml02 mov bx,0x12 mov cx,640 mov dx,480 push word 0x0 pop es mov [es:0x9000],byte 32 mov dword [es:0x9018],0x800000 push word 0x1000 pop es jmp gml10 gml02: jmp gml0 gr_table: dd 0x112+0100000000000000b , 640 , 480 , 0 dd 0x115+0100000000000000b , 800 , 600 , 0 dd 0x118+0100000000000000b , 1024 , 768 , 0 dd 0x11B+0100000000000000b , 1280 , 1024 , 0 dd 0x112 , 640 , 480 , 0 dd 0x115 , 800 , 600 , 0 dd 0x118 , 1024 , 768 , 0 dd 0x11B , 1280 ,1024 , 0 gml10: push word 0x0000 pop es mov [es:0x9008],bx mov [es:0x900A],cx mov [es:0x900C],dx push word 0x1000 pop es mov ax,32 cmp bx,0x13 je nov cmp bx,0x12 je nov ; USE DEFAULTS OR PROBE ; bx - mode : cx - x size : dx - y size ;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! movzx ax,[es:preboot_gprobe-0x10000] test ax,ax jne pre_probe ;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! test bx,0100000000000000b jz noprobe mov si,probetext-0x10000 call printplain push bx mov ebx,0x0201 call getkey pop bx pre_probe: cmp ax,1 je noprobe push cx dx mov bx,0x100 newprobe: inc bx cmp bx,0x17f jne probemore mov si,prnotfnd-0x10000 call printplain jmp $ probemore: mov ax,0x4f01 mov cx,bx and cx,0xfff push word 0x0000 pop es mov di,0xa000 int 0x10 mov eax,[es:di] ; lfb ? test eax,10000000b jz newprobe mov eax,[es:di+0x12] ; x size ? cmp ax,word [esp+2] jne newprobe mov eax,[es:di+0x14] ; y size ? cmp ax,dx jne newprobe movzx eax,byte [es:di+0x19] cmp eax,32 ;24 jb newprobe push word 0x0000 ; save probed mode pop es add bx,0100000000000000b mov [es:0x9008],bx push word 0x1000 pop es push bx mov si,prid-0x10000 call printplain pop bx dx cx noprobe: ; FIND VESA 2.0 LFB & BPP mov ax,0x4f01 mov cx,bx and cx,0xfff push word 0x0000 pop es mov di,0xa000 int 0x10 ; LFB mov ecx,[es:di+0x28] mov [es:0x9018],ecx ; BPP movzx ax,byte [es:di+0x19] mov [es:0x9000],ax ; ---- vbe voodoo BytesPerScanLine equ 0x10 push ax mov ax, [es:di+BytesPerScanLine] mov [es:0x9001],ax pop ax ; ----- nov: cmp ax,24 jnz nbpp24 mov si,bt24-0x10000 jmp bppl nbpp24: cmp ax,32 jnz nbpp32 mov si,bt32-0x10000 jmp bppl nbpp32: mov si,btns-0x10000 call print jmp $ bppl: call printplain ; FIND VESA 1.2 PM BANK SWITCH ADDRESS mov ax,0x4f0A mov bx,0x0 int 0x10 xor eax,eax xor ebx,ebx mov ax,es shl eax,4 mov bx,di add eax,ebx xor ebx,ebx mov bx,[es:di] add eax,ebx push word 0x0 pop es mov [es:0x9014],eax push word 0x1000 pop es ; GRAPHICS ACCELERATION mov al, [es:preboot_mtrr-0x10000] test al,al jne pre_mtrr mov si,gr_acc-0x10000 call printplain mov ebx,0x0201 call getkey pre_mtrr: push word 0x0000 pop es mov [es:0x901C],al push word 0x1000 pop es mov si,linef-0x10000 call printplain ; VRR_M USE mov al,[es:preboot_vrrm-0x10000] test al,al jne pre_vrrm mov si,vrrmprint-0x10000 call print mov ebx,0x0301 call getkey pre_vrrm: push word 0x0000 pop es mov [es:0x9030],al push word 0x1000 pop es mov si,linef2-0x10000 call printplain ; MEMORY MODEL ; movzx eax,byte [es:preboot_memory-0x10000] ; cmp eax,0 ; jne pre_mem ;;;;;;;;;;;;;;;;;;;;;;;;; ; mario79 - memory size ; ;;;;;;;;;;;;;;;;;;;;;;;;; ; mov ax,0E801h ;;; xor bx,bx ; thanks to Alexei for bugfix [18.07.2004] ; xor cx, cx ; xor dx, dx ; int 0x15 ; movzx ebx, dx ;bx ; movzx eax, cx ;ax ; shl ebx,6 ; перевод в килобайты (x64) ; add eax,ebx ; add eax, 1000h ;440h ; cmp eax,40000h ; 256? ; jge mem_256_z ; cmp eax,20000h ; 128? ; jge mem_128_z ; cmp eax,10000h ; 64? ; jge mem_64_z ; cmp eax,8000h ; 32? ; jge mem_32_z ; jmp mem_16_z ; ;mem_256_z: mov si,memokz256-0x10000 ; call printplain ; mov eax,5 ; jmp pre_mem ;mem_128_z: mov si,memokz128-0x10000 ; call printplain ; mov eax,4 ; jmp pre_mem ;mem_64_z: mov si,memokz64-0x10000 ; call printplain ; mov eax,3 ; jmp pre_mem ;mem_32_z: mov si,memokz32-0x10000 ; call printplain ; mov eax,2 ; jmp pre_mem ;mem_16_z: mov si,memokz16-0x10000 ; call printplain ; mov eax,1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; pre_mem: ; push word 0x0000 ; pop es ; mov [es:0x9030],al ; push word 0x1000 ; pop es ; mov si,linef-0x10000 ; call printplain ; DIRECT WRITE TO LFB, PAGING DISABLED ; movzx eax,byte [es:preboot_lfb-0x10000] ; mov eax,1 ; paging disabled ; cmp eax,0 ; jne pre_lfb ; mov si,gr_direct-0x10000 ; call printplain ; mov ebx,0x0201 ; call getkey ; pre_lfb: ; push word 0x0000 ; pop es ; mov [es:0x901E],al ; mov ax,0x1000 ; mov es,ax ; mov si,linef-0x10000 ; call printplain push 0 pop es mov [es:0x901E],byte 1 push 0x1000 pop es ; BOOT DEVICE movzx eax,byte [es:preboot_device-0x10000] cmp eax,0 jne pre_device mov si,bdev-0x10000 call printplain mov ebx,0x0301 call getkey pre_device: dec al mov [es:boot_dev-0x10000],al mov si,linef-0x10000 call printplain ; READ DISKETTE TO MEMORY cmp [boot_dev-0x10000],0 jne no_sys_on_floppy mov si,diskload-0x10000 call print mov ax,0x0000 ; reset drive mov dx,0x0000 int 0x13 mov cx,0x0001 ; startcyl,startsector mov dx,0x0000 ; starthead,drive push word 80*2 ; read no of sect reads: pusha xor si,si newread: push word 0x0 pop es mov bx,0xa000 ; es:bx -> data area mov ax,0x0200+18 ; read, no of sectors to read int 0x13 cmp ah,0 jz goodread add si,1 cmp si,10 jnz newread mov si,badsect-0x10000 call printplain jmp $ goodread: ; move -> 1mb mov si,movedesc-0x10000 push word 0x1000 pop es mov cx,256*18 mov ah,0x87 int 0x15 cmp ah,0 ; was the move successfull ? je goodmove mov dx,0x3f2 ; floppy motor off mov al,0 out dx,al mov si,memmovefailed-0x10000 call print jmp $ goodmove: mov eax,[es:movedesc-0x10000+0x18+2] add eax,512*18 mov [es:movedesc-0x10000+0x18+2],eax popa inc dh cmp dh,2 jnz bb2 mov dh,0 inc ch pusha ; print prosentage push word 0x1000 pop es xor eax,eax ; 5 mov al,ch shr eax,2 and eax,1 mov ebx,5 mul bx add al,48 mov [es:pros+1-0x10000],al xor eax,eax ; 10 mov al,ch shr eax,3 add al,48 mov [es:pros-0x10000],al mov si,pros-0x10000 call printplain popa bb2: pop ax dec ax push ax cmp ax,0 jnz rs jmp readdone rs: jmp reads movedesc: db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 db 0xff,0xff,0x0,0xa0,0x00,0x93,0x0,0x0 db 0xff,0xff,0x0,0x00,0x10,0x93,0x0,0x0 db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 readdone: pop ax mov dx,0x3f2 ; floppy motor off mov al,0 out dx,al mov si,backspace-0x10000 call printplain call printplain mov si,okt-0x10000 call printplain no_sys_on_floppy: mov ax,0x0000 ; reset drive mov dx,0x0000 int 0x13 mov dx,0x3f2 ; floppy motor off mov al,0 out dx,al ; PAGE TABLE push word 0x0000 pop es mov ecx,[es:0x9018] push ecx map_mem equ 64 ; amount of memory to map mov bx,0x6000 mov es,bx ; [es:di] = 6000:0 xor edi,edi mov ecx,256*map_mem ; Map (mapmem) M mov eax,7 cld pt2: cmp ecx,256*(map_mem-8) ; 8 M map to LFB jnz pt3 pop eax add eax,7 pt3: cmp ecx,256*(map_mem-12) ; 12 M back to linear = physical jnz pt4 mov eax,12*0x100000 + 7 pt4: stosd add eax,4096 loop pt2 mov bx,0x7100 mov es,bx xor edi,edi mov eax,8*0x100000+7 mov ecx,256*4 pt5: stosd add eax,0x1000 loop pt5 ; 4 KB PAGE DIRECTORY mov bx , 0x7F00 mov es , bx ; [es:di] = 7000:0 xor edi, edi mov ecx, 64 / 4 mov eax, 0x60007 ; for 0 M cld pd4k: stosd add eax, 0x1000 loop pd4k mov dword [es:0x800],0x71007 ;map region 0x80000000-0x803FFFFF to 0x800000-0xCFFFFF xor esi,esi mov edi,second_base_address shr 20 mov ecx,64/4 mov bx,0x7F00 mov ds,bx rep movsd mov bx,0x1000 mov ds,bx mov eax, 0x7F000 +8+16 ; Page directory and enable caches mov cr3, eax ; SET GRAPHICS mov dx,0x0000 mov es,dx mov bx,[es:0x9008] mov ax,bx ; vga & 320x200 cmp ax,0x13 je setgr cmp ax,0x12 je setgr mov ax,0x4f02 ; Vesa setgr: int 0x10 cmp ah,0 jz gmok mov si,fatalsel-0x10000 call print jmp $ gmok: mov dx,0x1000 mov es,dx ; set mode 0x12 graphics registers: cmp bx,0x12 jne gmok2 mov al,0x05 mov dx,0x03ce out dx,al ; select GDC mode register mov al,0x02 mov dx,0x03cf out dx,al ; set write mode 2 mov al,0x02 mov dx,0x03c4 out dx,al ; select VGA sequencer map mask register mov al,0x0f mov dx,0x03c5 out dx,al ; set mask for all planes 0-3 mov al,0x08 mov dx,0x03ce out dx,al ; select GDC bit mask register ; for writes to 0x03cf gmok2: mov dx,0x1000 mov es,dx