;from okadboot.nasm, for experimentation ;chances are things will be broken if any of these locations are ;hardcoded in the kernel or Forth code %define BOOTOFFSET 0x7c00 ;%define GRAPHICS_MODE 0x4118 ;from cmcf code %define GRAPHICS_MODE 0x4144 ;for QEMU ;%define GRAPHICS_MODE 0x4123 ;for widescreen emachines E625 ;DI is used globally as a pointer to BOOTOFFSET, e.g. 0x7c00 org 0 [bits 16] start: jmp short start0 clstore: dw 0 sectors_to_load: dw 312 ;number of 512-byte sectors in okadwork.cf, 159744 / 512 dhstore: dw 0 dxstore: dw 0 cxstore: dw 0 cxsave: ;saved but never used? dw 0 wordbuffer: dw 0 ;outword uses this for temporary storage and bit-manipulations screenloc: dw 0 ;outword uses this to store next available screen memory offset hextable: db '0123456789ABCDEF' ;the following used by relocate BIOS call movebuffer: times 16 db 0 source: dw 0xffff, 0xf000, 0x9300, 0x0000 destination: dw 0xffff, 0x0000, 0x9320, 0x0000 times 16 db 0 relocate: pushaw push es mov cx,0x200 mov si,di add si,byte movebuffer xor ax,ax mov es,ax mov ah,0x87 int 0x15 xor ax,ax add word [di+((destination - $$) & 0xff) + 2],0x200 adc [di+((destination - $$) & 0xff) + 4],al pop es popaw mov bx,0xfe00 ret start0: jmp start1 outword: ;show 16-bit hex value on screen push es push ax push cx push si mov ax,0xb800 mov es,ax mov cx,0x4 .loop: xor ax,ax mov al,[di+((wordbuffer - $$) & 0xff) + 1] shr ax,4 mov si,ax add si,di mov al,[si+((hextable - $$) & 0xff)] mov si,[di+((screenloc - $$) & 0xff)] mov [es:si],al add word [di+((screenloc - $$) & 0xff)],byte +0x2 and word [di+((screenloc - $$) & 0xff)],0x7ff shl word [di+((wordbuffer - $$) & 0xff)],4 loop .loop add word [di+((screenloc - $$) & 0xff)],byte +0x2 pop si pop cx pop ax pop es ret start1: sub di,di mov ds,di mov es,di mov di,0x7c00 sti mov [di+((wordbuffer - $$) & 0xff)],dx call outword or [di+((dxstore - $$) & 0xff)],dl mov dl,[di+((dxstore - $$) & 0xff)] mov ah,0x8 push di int 0x13 pop di mov [di+((wordbuffer - $$) & 0xff)],dx call outword inc dh mov [di+((dhstore - $$) & 0xff)], dh mov [di+((wordbuffer - $$) & 0xff)],dx call outword mov [di+((wordbuffer - $$) & 0xff)],cx call outword mov [di+((cxsave - $$) & 0xff)],cx and cl,0x3f ;low 6 bits mov [di+((clstore - $$) & 0xff)],cl mov [di+((wordbuffer - $$) & 0xff)],cx call outword mov bx,0xfe00 mov cx,[di+((cxstore - $$) & 0xff)] mov dx,[di+((dxstore - $$) & 0xff)] mov si,[di+((sectors_to_load - $$) & 0xff)] mov ax,0xf00 mov es,ax sti branch0x112: cmp cl,[di+((clstore - $$) & 0xff)] jnz branch0x126 inc dh cmp dh,[di+((dhstore - $$) & 0xff)] jnz branch0x123 xor dh,dh add ch,0x1 branch0x123: and cl,0xc0 branch0x126: inc cx add bx,0x200 mov ax,0x201 int 0x13 mov [di+((wordbuffer - $$) & 0xff)],ax dec ax jz branch0x139 call outword branch0x139: call relocate dec si jnz branch0x112 ;setup serial port xor ax,ax mov es,ax mov dx,0x3fb mov al,0x83 out dx,al mov al,0x3 sub dl,0x3 out dx,al xor ax,ax inc dx out dx,al mov al,0x3 add dl,0x2 out dx,al xor ax,ax sub dl,0x2 out dx,al mov al,0x3 add dl,0x3 out dx,al mov ax,0x4f02 mov bx, GRAPHICS_MODE int 0x10 cli xor eax,eax mov ebx,eax mov bx,cs mov ds,bx mov es,ax mov edi,eax mov esi,eax mov ds,ax lgdt [gdt + BOOTOFFSET] mov al,0x1 mov cr0,eax jmp word code32p:begin_pmode + BOOTOFFSET [bits 32] begin_pmode: jmp short branch0x1ca branch0x1b6: push eax push edx mov edx,[esp+0x8] mov al,[edx] mov edx,0x3f8 out dx,al pop edx pop eax inc dword [esp] ret branch0x1ca: mov al,0x10 mov ds,ax mov es,ax mov ss,ax mov esp, 0x0a0000 xor ecx,ecx mov al,0xd1 out 0x64,al .wait: in al,0x64 and al,0x2 jnz .wait mov al,0x4b out 0x60,al mov esi,0x9f400 call dword branch0x1b6 inc ecx mov edi,0x200200 jmp edi align 4, db 0 gdt: dw gdt_end - gdt0 - 1 ;GDT limit dd gdt0 + BOOTOFFSET ;pointer to start of table align 8, db 0 gdt0: dw 0, 0, 0, 0 ;start of table must be a null entry code32p equ $ - gdt0 dw 0xffff, 0, 0x9a00, 0xcf ;32-bit protected-mode code data32p equ $ - gdt0 dw 0xffff, 0, 0x9200, 0xcf ;32-bit protected-mode data gdt_end: times 510 - ($ - $$) db 0 db 0x55, 0xaa