Document and clarify system management routines in `system.inc`: added detailed comme...
authorSvjatoslav Agejenko <svjatoslav@svjatoslav.eu>
Mon, 16 Feb 2026 23:30:21 +0000 (01:30 +0200)
committerSvjatoslav Agejenko <svjatoslav@svjatoslav.eu>
Mon, 16 Feb 2026 23:30:21 +0000 (01:30 +0200)
emulator/system.inc

index d8c3dc2..2028a0e 100644 (file)
-; 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