-; part of virtual processor, emulator for FIFTH.\r
-\r
-system_init:\r
- mov ax,7202h\r
- push ax\r
- popf\r
- pushf\r
- pop bx\r
- cmp ax,bx\r
- je processor_ok\r
- mov dx, badcpu\r
- mov ah,9\r
- int 21h\r
- mov ah,4Ch\r
- int 21h\r
- badcpu db 'required 80386 or better',24h\r
-processor_ok:\r
- smsw ax\r
- test al,1\r
- jz mode_ok\r
- mov dx, badmode\r
- mov ah,9\r
- int 21h\r
- mov ah,4Ch\r
- int 21h\r
- badmode db 'error: CPU in protected mode',24h\r
-mode_ok:\r
- mov ax,4300h ; check for XMS\r
- int 2Fh\r
- cmp al,80h ; XMS present?\r
- je xms_ok\r
- mov dx, badxms\r
- mov ah,9\r
- int 21h\r
- jmp system_exit\r
- badxms db 'error: HIMEM.SYS not loaded',24h\r
-xms_ok:\r
- mov ax,350Dh\r
- int 21h\r
- mov word [irq_5],bx\r
- mov word [irq_5+2],es\r
- push cs\r
- pop es\r
- mov ax,250Dh\r
- mov dx,int_13\r
- int 21h\r
-\r
- push es\r
- mov ax,4310h ; get XMS driver address\r
- int 2Fh\r
- mov word [xms_call],bx ; store XMS driver address\r
- mov word [xms_call+2],es\r
- pop es\r
- mov ah,3 ; enable A20\r
- call far dword [xms_call]\r
- mov ah,8 ; get free extended memory size\r
- xor bl,bl\r
- call far dword [xms_call]\r
- or bl,bl\r
- mov dx,ax\r
- movzx eax,ax\r
- shl eax,10\r
- mov ah,9 ; allocate largest memory block\r
- call far dword [xms_call]\r
- mov [xms_handle],dx\r
- mov ah,0Ch ; lock extended memory block\r
- call far dword [xms_call]\r
- shl edx,16\r
- mov dx,bx\r
- mov [xms_addr],edx ; store memory block address\r
- ret\r
-\r
-\r
-system_exit:\r
- cmp [xms_handle],0\r
- je sys_exit\r
- mov ah, 0dh ; unlock extended memory block\r
- mov dx, [xms_handle]\r
- call far dword [xms_call]\r
- mov ah, 0ah ; free extended memory block\r
- call far dword [xms_call]\r
-sys_exit:\r
- mov ax, 250dh\r
- mov dx, word [irq_5]\r
- mov ds, word [irq_5+2]\r
- int 21h\r
- pop ax\r
- mov ah, 4ch\r
- int 21h\r
-\r
-int_13: push eax\r
- mov al, 00001011b ; OCW3 - read IRQ in-service register\r
- out 20h, al\r
- in al, 20h\r
- test al, 00100000b ; is IRQ 5 in service?\r
- jz exception\r
- pop eax\r
- jmp dword 0:0\r
- label irq_5 dword at $-4\r
-exception:\r
- push ds es fs gs\r
- cli ; disable interrupts\r
- xor eax, eax ; calculate linear address of GDT\r
- mov ax, cs\r
- shl eax, 4\r
- add eax, GDT\r
- mov dword [cs:GDTR+2],eax\r
- lgdt pword [cs:GDTR] ; load GDT register\r
- mov eax, cr0 ; switch to protected mode\r
- or al, 1\r
- mov cr0, eax\r
- jmp pm_start\r
- pm_start:\r
- mov ax, 1 shl 3 ; load 32-bit data descriptor\r
- mov ds, ax ; to all data segment registers\r
- mov es, ax\r
- mov fs, ax\r
- mov gs, ax\r
- mov eax, cr0 ; switch back to real mode\r
- and al, not 1\r
- mov cr0, eax\r
- jmp pm_end\r
- pm_end:\r
- sti ; enable interrupts\r
- pop gs fs es ds\r
- pop eax\r
- iret\r
-\r
-GDTR dw 2*8-1 ; limit of GDT\r
- dd ? ; linear address of GDT\r
-\r
-GDT rw 4 ; null descriptor\r
- dw 0FFFFh, 0, 9200h, 8Fh ; 32-bit data descriptor\r
-\r
-xms_call dd 0 ; XMS driver pointer\r
-xms_handle dw 0 ; handle of XMS memory block\r
-xms_addr dd 0 ; address to XMS block\r
+; System initialization and management routines
+
+; system_init
+;
+; Initializes the system by:
+; - Checking for 80386 or better CPU
+; - Checking for protected mode
+; - Checking for XMS (Extended Memory Specification) support
+; - Allocating and locking extended memory
+; - Setting up A20 gate
+;
+; Notes:
+; - Uses DOS interrupts for XMS operations.
+; - Allocates the largest possible block of extended memory.
+
+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
+;
+; Cleans up system resources before exiting:
+; - Unlocks and frees extended memory
+; - Restores original interrupt handler for INT 13h
+; - Exits to DOS
+
+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
+;
+; Interrupt handler for INT 13h (disk services)
+; Used for switching to protected mode and back.
+
+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