; part of virtual processor, emulator for FIFTH. system_init: mov ax,7202h push ax popf pushf pop bx cmp ax,bx je processor_ok mov dx, badcpu mov ah,9 int 21h mov ah,4Ch int 21h badcpu db 'required 80386 or better',24h processor_ok: smsw ax test al,1 jz mode_ok mov dx, badmode mov ah,9 int 21h mov ah,4Ch int 21h badmode db 'error: CPU in protected mode',24h mode_ok: mov ax,4300h ; check for XMS int 2Fh cmp al,80h ; XMS present? je xms_ok mov dx, badxms mov ah,9 int 21h jmp system_exit badxms db 'error: HIMEM.SYS not loaded',24h xms_ok: mov ax,350Dh int 21h mov word [irq_5],bx mov word [irq_5+2],es push cs pop es mov ax,250Dh mov dx,int_13 int 21h push es mov ax,4310h ; get XMS driver address int 2Fh mov word [xms_call],bx ; store XMS driver address mov word [xms_call+2],es pop es mov ah,3 ; enable A20 call far dword [xms_call] mov ah,8 ; get free extended memory size xor bl,bl call far dword [xms_call] or bl,bl mov dx,ax movzx eax,ax shl eax,10 mov ah,9 ; allocate largest memory block call far dword [xms_call] mov [xms_handle],dx mov ah,0Ch ; lock extended memory block call far dword [xms_call] shl edx,16 mov dx,bx mov [xms_addr],edx ; store memory block address ret system_exit: cmp [xms_handle],0 je sys_exit mov ah, 0dh ; unlock extended memory block mov dx, [xms_handle] call far dword [xms_call] mov ah, 0ah ; free extended memory block call far dword [xms_call] sys_exit: mov ax, 250dh mov dx, word [irq_5] mov ds, word [irq_5+2] int 21h pop ax mov ah, 4ch int 21h int_13: push eax mov al, 00001011b ; OCW3 - read IRQ in-service register out 20h, al in al, 20h test al, 00100000b ; is IRQ 5 in service? jz exception pop eax jmp dword 0:0 label irq_5 dword at $-4 exception: push ds es fs gs cli ; disable interrupts xor eax, eax ; calculate linear address of GDT mov ax, cs shl eax, 4 add eax, GDT mov dword [cs:GDTR+2],eax lgdt pword [cs:GDTR] ; load GDT register mov eax, cr0 ; switch to protected mode or al, 1 mov cr0, eax jmp pm_start pm_start: mov ax, 1 shl 3 ; load 32-bit data descriptor mov ds, ax ; to all data segment registers mov es, ax mov fs, ax mov gs, ax mov eax, cr0 ; switch back to real mode and al, not 1 mov cr0, eax jmp pm_end pm_end: sti ; enable interrupts pop gs fs es ds pop eax iret GDTR dw 2*8-1 ; limit of GDT dd ? ; linear address of GDT GDT rw 4 ; null descriptor dw 0FFFFh, 0, 9200h, 8Fh ; 32-bit data descriptor xms_call dd 0 ; XMS driver pointer xms_handle dw 0 ; handle of XMS memory block xms_addr dd 0 ; address to XMS block