COMMON EQU 1

Is_bDumpRegs macro
   xor  ax, ax
   mov  al, cs:DebugFlags
   and  al, bDumpRegs
   cmp  al, 0
   endm

Is_Syscalltrace macro
   xor  ax, ax
   mov  al, cs:DebugFlags
   and  al, Syscalltrace
   cmp  al, 0
   endm

Is_AbortStartup macro
   xor  ax, ax
   mov  al, cs:DebugFlags
   and  al, AbortStartup
   cmp  al, 0
   endm

Is_TraceStartup macro
   xor  ax, ax
   mov  al, cs:DebugFlags
   and  al, TraceStartup
   cmp  al, 0
   endm

callGate:
.386
; void callGate(short gate);
; gobal callGate
;   push ebp
;   mov ebp, esp
;   jmp far ss:[ebp+4]
;   pop ebp
;.286
   ret 

systemerror macro
    pusha
    push cs
    pop  ds
    _print ErrMsg0015, 1
    call debugregisters
    popa
    endm

; ===========================================================================
SetError proc far
; AX = Code
; ===========================================================================
     xor  dx, dx
     stc
     ; mov  ax, errNotEnoughMemory
     ret
SetError endp

; ===========================================================================
memcmp proc far
; ES:SI = SOURCE
; DS:DI = DEST
; CX    = SIZE
; Return: 
; BX    = -1 not equal strings 
; ===========================================================================
      push bx
      mov  bx, -1
mc1:
      mov  ah, byte ptr es:[si]
      mov  al, byte ptr ds:[di]
      cmp  al, ah
      je   short mc_e
           xor  bx, bx
           jmp  short mc_x
mc_e:
      inc  si
      inc  di
      loop mc1
mc_x:
      mov  ax, bx
      pop  bx
      ret
memcmp endp

cmpi  proc far
;Input : ds:si and es:di point to the chars to be compared
;Output: Zero flag set if match
;        Both di and si advanced
        push    ax
	lodsb	  		;get one char
	cmp	al,byte ptr es:[di]
	jz	cmp_match
	xor	al,20h		;get opposite case
	cmp	al,byte ptr es:[di]
cmp_match:
	lea	di,[di+1]		;Increment without changing flags
        pop     ax
	ret
cmpi    endp

; ===========================================================================
meminfo proc far
; ===========================================================================
     mov  ax, 0e801h
     int  15h
     jnc  short bios_extmem
bios_getextmem:
     mov  ah, 88h           ; return extended memory size in KB
     int  15h
     jnc  short bios_extmem
     xor  ax, ax            ; we have no memory
bios_extmem:
     mov  cs:ext_mem_size, ax
     int  12h
     mov  cs:memsize, ax
     mov  cs:freemem, ax
     mov  cl, 6
     shl  ax, cl            ; convert KBs to paragraphs
     mov  cs:paragraphs, ax
     ; call cs:mhimem
     ; jc
     ; mov  al, cs:cputype
     ; cmp  al, 3
     ; jb   short extmem32b_fail
     ; EXT mem detect annoyance.. bios bugs I hear on some
     .386
     ; mov  eax, 0000e820h        ; 32bit CPU only
     ; mov  edx, 534d4150h        ; SMAP
     ; xor  ebx, ebx
     ; mov  ecx, 20
     ; mov  di, offset _buffer
     ; push cs
     ; pop  es
     ; int  15h
     ; jc   short extmem32b_fail
     ; cmp  eax, 534d4150h
     ; jne  short extmem32b_fail
     .286
extmem32b_fail:

     ret
meminfo endp

; ===========================================================================
mhimem proc far
; ===========================================================================
       mov  ax, 4300h   ; Check HIMEM.SYS installed state
       int  2fh
       stc
       cmp  al, 80h
       jne  nomhimem
       ;
       mov  ax, 4310h   ; Get HIMEM.SYS entrypoint es:bx
       int  2fh
       mov  word ptr cs:himemaddr, bx
       mov  word ptr cs:himemaddr+2, es
       clc
nomhimem:
       ret
himemaddr dd 0
mhimem endp

; ===========================================================================
mdpmimode proc far
; ===========================================================================
       mov  ax, 1687h
       int  2fh
       cmp  ax, 0
       jne  no_dpmi
            mov  word ptr cs:pfpdpmiFns, di
            mov  word ptr cs:pfpdpmiFns+2, es
       ; --- Alloc mem needed by host
       mov  bx, si
       mov  ah, 48h
       int  21h
       jc   dpmi_err ; bail out
       mov  es, ax
       mov  ax, 0
       call cs:pfpdpmiswth
       jc   cantswitch_dpmi
       mov  ax, 0400h
       int  31h
       jc   dpmi_errhandle
dpmi_okay:
       jmp  short dpmix
cantswitch_dpmi:
       stc
dpmi_errhandle:
       stc
dpmi_err:
       stc
no_dpmi:
       stc
       xor  ax, ax
dpmix:
       ret
mdpmimode endp

; ===========================================================================
mdpmi  proc far
; Input : EAX   = RequestSize
; Output: CF=CY = ERROR
; ===========================================================================
.386p
       push ax
       mov  bx, 0ffffh
       mov  ax, 100h
       int  31h
       mov  cs:dpmilargest, bx
       pop  ax
       cmp  eax, 0
       je   no_dpmireq
       cmp  eax, 1024000
       je   no_dpmireq
            or   eax, 15 ; paragraphs = ((requestsize | 15) >> 4);
            shr  eax, 4
            mov  bx, ax  ; put number of paragraphs into bx
            ; call the dpmi host
            mov     ax, 100h        ; call dpmi host
            int     31h             ;
            mov     cs:rmseg, ax       ; collect results to C variables
            mov     cs:pmsel, dx       ;
            sbb     ax, ax          ; carry code to ax
            ; mov     failed, ax    
no_dpmireq:
.286c
       ret
mdpmi  endp

; ===========================================================================
isbeta proc far
; ===========================================================================
     clc
     xor  ax, ax
     mov  al, _maintenance
     mov  ah, _build
     or   ax, ax
     jz   no_beta
          stc
no_beta:
     ret
isbeta endp

; ===========================================================================
exit    proc far
; Input : AL = ERRORLEVEL
; ===========================================================================
        push cs
        pop  ds
        push cs
        pop  es
IF (MSDOS)
        add  bl, cl
ELSE
        mov  bx, smm_off
        call cs:chimaira
ENDIF
        jnc  no_exit_debug
             call debugregisters
             _newline
no_exit_debug:
        _print ErrMsg0005, 1
        _print ErrMsg0016, 1
exitprompt:
        _print exit_prompt, 1
exitwait:
        kbhit
        or  al, al
        jz  exitwait
            _readkey
            call upcase
            cmp  al, 'S'
            jne  chkexit_r
                 call cs:main                ; k_init
            jmp  exitprompt
chkexit_r:
            cmp  al, 'R'
            jne  exitprompt
                 call reset
                 call reboot
                 nop
exitkernel:

IF (ZSTART)
        call dosexit
ELSEIF
        int  18h
ENDIF
        ret
exit    endp

; ===========================================================================
show_hardware proc far
; ===========================================================================
       xor  ax, ax
       mov  al, cs:cputype
       call putnum
       _echo '8'
       _echo '6'
       mov  al, cs:ndptype
       or   al, al
       jz   _sh_nomath
       _echo 'D'
       jmp  _sh_nomath2
_sh_nomath:
       _echo 'S'
_sh_nomath2:
       _echo 'X'
       _echo ' '
IF (MSDOS)
       mov  ax, word ptr cs:[MaxMemory]
       call putnum
       _echo ' '
ENDIF
       mov  ax, cs:memsize
       call putnum
       _echo 'K'
       _echo 'B'
       _echo ' '
       mov  ax, cs:ext_mem_size
       call putnum
       _echo 'K'
       _echo 'B'
       _echo ' '
IF (DEBUG)
     mov  ax, word ptr cs:[wbaseMemSeg]
     call put_hex
     _echo 'H'
     _echo ' '
ENDIF
       mov  al, cs:pcibus
       or   al, al
       jnz  _sh_pci
       _print ISA, 1
       jmp  _sh_x
_sh_pci:
       _print PCi, 1
       _spaces 1
       mov  ax, cs:PCIVERSION
       _swap
       call wrdec
_sh_x:
       _echo ' '
IF (AUDIO)
       call cs:audio_info
ENDIF
IF (NETWORK)
       call cs:net_info
ENDIF
IF (GRAPHICS)
       call cs:gfx_showinfo
ENDIF
       ret
show_hardware endp

cpuspeed proc far
        ;
        ; Determine CPU speed for delay loops - Pheonix 386 BIOS
        ; This function reads system timer channel 0 twice, then does
        ; calculations on the returned values to determine the delay loop
        ; counter needed by the BIOS for beeps and floppy timeouts
        mov  ah, 0bch
        int  15h
        jnc  No_DellPhoenix1
        ; Phoenix BIOS 1.10 10a will set 0040:00B0h to delay loop count
        ; Dell 4xxDE BIOS A11 stores as a word value at 0040:00ECh
        push es
        mov  ax, 0040h
        mov  es, ax
        mov  bx, 00b0h
        mov  al, byte ptr es:[bx]
        mov  delayloop, al
        mov  bx, 00ech
        mov  ax, word ptr es:[bx]
        mov  delaywloop, ax
        pop  es
No_DellPhoenix1:
        ret
cpuspeed endp

cpuinfo proc far
        mov  ah, 0C0h
        int  15h              
        jc   CMBD
        cmp  ah, 0
        jne  CMBD
        mov  al, byte ptr es:[bx+2]
        mov  byte ptr pcmodel, al
        mov  al, byte ptr es:[bx+3]
        mov  byte ptr pcsubmodel, al
        jmp  short sinit0   
CMBD:
        mov  si, 0FFFFh
        mov  es, si
        mov  si, 000eh
        mov  al, byte ptr es:[si]
        mov  byte ptr pcmodel, al
sinit0:
        ret
cpuinfo endp

; ===========================================================================
about proc far
; ===========================================================================
      _print logo, 1
      _print copyr, 1
      mov  ax, _version
      call wrdec
      _echo ' '
      mov  ax, _dosversion
      call wrdec
      _echo '.'
      mov  ax, _revision
      call cs:putnum
      _echo '.'
      mov  ax, _maintenance
      call cs:putnum
      _echo '.'
      mov  ax, _build
      call cs:putnum
      _echo ' '
      mov  ax, cs:setver
      call wrdec
      _echo ' '
      _print timestamp, 1
      _newline
      _newline
      _print LICENSE, 1
      _newline
IF (DEBUG)
      call isbeta
      jnc  not_beta
           _print betamsg, 1
not_beta:
ENDIF
      call cs:show_hardware
      ret
about endp

In_V86Mode proc far
; Detect V86 mode
.386P
        smsw ax ; store machine status word (.386P !!)
        and  ax,1                    ;
        jz   short notv86mode        ;
        stc
notv86mode:
        clc
.286P
        ret
In_V86Mode endp

; ===========================================================================
hardware proc far                                          ; //hmm.. thoughts
; ===========================================================================
;   detect=hardwr();
;   if (detect) {
;         // true 
;         pnp_configure(detect);
          call show_hardware       ;         show_hardwaredetails();
;      } else {
;         listed=lspci();         // cardctl  pnpdump
;         if (listed) {
;                  // listed, install problem. try to tweak IO/IRQ settings?                    
;            } else {
;                  // if card is present but not listed then hardware problem
;            }
;      }
       ret
hardware endp

cpu_hotplug_begin proc far
       mov  ax, cpu_hotplug_lock
       ; call mutex_lock
       mov  ax, cpuhcurrent
       mov  cpu_hotplug_active_writer, ax
cpuhpw:
            mov  ax, cpu_hotplug_lock
            ; call mutex_unlock
            mov  ax, cpu_hotplug_readers_done
            ; call wait_for_completion
            mov  ax, cpu_hotplug_lock
            ; call mutex_lock
       mov  ax, cpu_hotplug_refcount
       or   ax, ax
       jnz  short cpuhpw
       ret
cpuhcurrent               dw ?
cpu_hotplug_lock          dw ?
cpu_hotplug_active_writer dw ?
cpu_hotplug_readers_done  dw ?
cpu_hotplug_refcount      dw ?
cpu_hotplug_begin endp
