; ===========================================================================
; MSDOS compatibility 
; ===========================================================================

F5KEY       EQU 3f00h
F6KEY       EQU 4000h
F7KEY       EQU 4100h
F8KEY       EQU 4200h
PSP_USERSP  EQU 2eh
PSP_USERSS  EQU 30h

; These are the interrupts NXDOS uses for itself.
introfs dw int0,  int3, int19, int20, int21, int22, int23, int24, int25
        dw int26, int27,int28, int29, int2a, int2e, int2f, int69, int80
intr    db 0h,3h,19h,20h,21h,22h,23h,24h,25h,26h,27h,28h,29h,2ah,2eh,2fh,69h,80h
intrs   EQU $ - intr

int0_ofs     dw ?
int0_seg     dw ?
int1_ofs     dw ?
int1_seg     dw ?
int3_ofs     dw ?
int3_seg     dw ?
int4_ofs     dw ?
int4_seg     dw ?
int15_ofs    dw ?
int15_seg    dw ?
int19_ofs    dw ?
int19_seg    dw ?
int1E_ofs    dw ?
int1E_seg    dw ?
int2f_ofs    dw ?
int2f_seg    dw ?
int6c_ofs    dw ?
int6c_seg    dw ?
dta          dw 0
returnmode   db ?
returncode   db ?

debugger proc far
     pushregs
     _newline
     call debugregisters
     mov  cx, 128
     call debugdump
     _newline
     call pauseprompt
     popregs
     ret
debugger endp

; ===========================================================================
NXDOS_BUFFERAPI proc far
;demo_buffer:
;  mov  ax, 0bf01h
;  mov  cx, 3
;  int  21h
;  ; mov  cs:[someaddr], es
;  mov  ax, 0bf02h
;  mov  dx, es
;  int  21h
; ===========================================================================
_BF_F1:
      cmp  al, 1
      jne  _BF_F2
           ; CX = Size in paragraphs
           call NewBuffer
      jmp  short _BF_FX
_BF_F2:
      cmp  al, 2
      jne  _BF_FX
           ; DX = Buffer SEG Address
           mov  ES, DX
           call FreeBuffer
      jmp  short _BF_FX
_BF_FX:
      ret
NXDOS_BUFFERAPI endp

int0 proc far
     ; make sure A20 is on
     ; call A20Enable
     ; jmp far Int0Handler, Int0Fixup
     _print cs:ErrMsg0002, 1
     iret
int0 endp

int1 proc far  ; Single step -
     call debugger
     iret
int1 endp

int3 proc far  ; Breakpoint - debugger
     call debugger
     iret
int3 endp


int18 proc far


      iret
int18 endp

int19 proc far

      
      iret
int19 endp

; ===========================================================================
Int20 proc far                             ; Interrupt 20 - Program terminate 
; Input : CS = PSP segment
; Output: never
; This API service or structure is a remnant of bygone days of earlier
; versions of DOS. Later version of DOS continue to support it, but there are
; better ways to get the same result. Right now I just call INT21hAX=4Ch
; inside this.
; ===========================================================================
      ; Should be aligned to next word boundry
      call cs:TerminateProg
      iret
TerminateProg proc far                                    
; CS = segment of program segment prefix of termiating process return none
;      Exits to the parent process; passes control to terminate vector in PSP.
;      Identical to INT 20h Terminate.
;      The CS Segment register must be set to the PSP.
;      Resets vectors for DOS interrupts 22h - 24h (Terminate, Ctrl-Break,
;      Critical Error), to values saved from parent's PSP Flushes file
;      buffers, but files should be closed if their length has changed
;      Easier and cleaner to use DOS fn 4ch (exit)
      push cs  ; cupsp.masterpsp == cupsp abort()
      pop  ax
      cmp  ax, offset psp
      je   abort_terminate
           cli
           push ds
           ; tsr = false
           ; call mfree(CURRENTTASK->PSP:CS)
           mov  bx, cs:errormode
           cmp  bx, 200h
           je   _4cx
                cmp  bx, 100h
                jne  _4cx
                     mov  bl, 0
                     mov  cs:breakflag, bl
           _4cx:
           ; xor  ax, ax  ; return code
           mov ah, cs:exitmethod
           mov al, cs:errorlevel
           clc
           ; call memcheck
           jnc  _4c_MCB_ok
                _panic
           _4c_MCB_ok:
           ; call starttrace
           mov  dx, 0   ; do something useful
           pop  ds
           sti
abort_terminate:
      ret
TerminateProg endp
Int20 endp

Make_TSR proc far
     ; Keep Program (Terminate and Stay Rresident)
     call TerminateProg
     ; memchange(currentpsp, dx<6?6:DX, 0
     or   ax, 300h
     ; tsr = true
     ret
Make_TSR endp

; ===========================================================================
FreeDOS_LFN proc far
; Appliction does findfirst x:\*.*
; This fails, causes int24
; This sets errormode, and calls int24
; application decides not to return to dos,
; but instead pop the stack and return to itself
; (this is legal; see RBIL/INT 24 description
;
;       a) now the alloc()'ed fnode[0] never gets free()'ed
;
;       b) errormode NEVER gets set back to 0 unyil exit()
;
; I have NO idea how real DOS handles this the appended patch cures the
; worst symptoms
; ===========================================================================
;al = 1 allocate LFN node
;al = 2 free LFN node
;al = 3 setup LFN node
;al = 4 create LFN node
;al = 5 read next LFN node
;al = 6 write SFN pointed by lfn inode
;else invalid
        push ax
        mov  cs:criterrcode, ax        ; Maybe
        ; if fnode[0].f_count != 0 || fnode[1].f_count != 0
        ; if (ErrorMode == 0) put_string("near_fnodes not 0"); /* panic ?? */
        ;    fnode[0].f_count = 0;    /* don't panic - THEY ARE unused !! */
        ;    fnode[1].f_count = 0;
        mov  ax, cs:bDumpRegs
        or   ax, ax
        pop  ax
        jz   no_PDLFNDUMP
             call debugregisters
             _newline
no_PDLFNDUMP:
        clc
        ret
FreeDOS_LFN endp

; ===========================================================================
dosfunc proc far
; ===========================================================================
      set_InDOS               ; set InDOS flag
func_00:
      cmp  ah, 00h
      jne  func_01
           ; 00H Terminate
           call terminateprog
      jmp  dosfuncx
; Character I/O and string & keyboard functions                      DOS 1.0+
func_01:
      cmp  ah, 01h
      jne  func_02
           ; 01H Kybd Input
           call char_input
      jmp  dosfuncx
func_02:
      cmp  ah, 02h
      jne  func_05
           ; 02H Display Char
           call char_output
      jmp  dosfuncx
func_03:
      cmp  ah, 03h
      jne  func_04
           call aux_in
      jmp  dosfuncx
func_04:
      cmp  ah, 04h
      jne  func_05
           Call aux_out
      jmp  dosfuncx
func_05:
      cmp  ah, 05h
      jne  func_06
           ; 05H Prn Output
           call LPT_OUT
      jmp  dosfuncx
func_06:
      cmp  ah, 06h
      jne  func_07
           ; 06H Console I/O
           call dir_conIO
      jmp  dosfuncx
func_07:
      cmp  ah, 07h
      jne  func_08
           ; 07H NoEcho RawInp
           mov  dl, 0ffh
           call dir_conIO
      jmp  dosfuncx
func_08:
      cmp  ah, 08h
      jne  func_09
           ; 08H NoEcho Inp
           mov  dl, 0ffh
           call dir_conIO
      jmp  dosfuncx
func_09:
      cmp  ah, 09h
      jne  func_0a
           ; 09H Display Text  
           ; CON Output string DS:DX
           ; DS:DX address of $ terminated string (ASCII 24H)
           ; returns NONE
           ; string is displayed until 24h character is found.
           ; Backspaces are handled by the 02H Display CHAR Function
           ; The normal procedure for displaying a newline is to embed a
           ; CR/LF (0a/0d) pair into the string.
           ; String contining '$' may be printed via 40H write file (BX=0)
           call mswrite
      jmp  dosfuncx
func_0a:
      cmp  ah, 0ah
      jne  func_0b
           ; 0aH Bufrd Input   
           call buf_input
      jmp  dosfuncx
func_0b:
      cmp  ah, 0bh
      jne  func_0c
           ; 0bH Get InpStatus 
           mov  al, 0ffh
           ; if (StdinBusy()) lr.AL = 0x00;
      jmp  dosfuncx
func_0c:
      cmp  ah, 0ch
      jne  func_0d
           ; 0cH Clear & Input 
           ; Flush Buffer, Read Keyboard    
           ; flush (wipe w/ 00h keyboard buffer STDIN)
           ; if al = 01 goto function 01
           ; if al = 06 goto function 06
           ; if al = 07 goto function 07
           ; if al = 08 goto function 08
           ; if al = 0a goto function 0A
           call char_input
      jmp  dosfuncx
func_0d:
      cmp  ah, 0dh
      jne  func_0e
           ; 0dH Reset Disk
           ; flush ()
           mov  dl, byte ptr cs:diskdrive
           call resetdisk
      jmp  dosfuncx
func_0e:
      cmp  ah, 0eh
      jne  func_0f
           ; 0eH Set Dflt Disk 
           ; Set Default drive
           mov  al, dl   ; lr.AL = DosSelectDrv(lr.DL);
      jmp  dosfuncx
func_0f:
      cmp  ah, 0fh
      jne  func_18
           ; FCB OPEN DS:DX
           ; FcbOpen(FP_DS_DX, O_FCB | O_LEGACY | O_OPEN | O_RDWR);
      jmp  dosfuncx
func_10:
      cmp  ah, 10h   
      jne  func_11
           ; FCB CLOSE DS:DX
           ; FcbClose(FP_DS_DX);
      jmp  dosfuncx
func_11:
      cmp  ah, 11h
      jne  func_12
           ; lr.AL = FcbFindFirstNext(FP_DS_DX, TRUE);
      jmp  dosfuncx
func_12:
      cmp  ah, 12h
      jne  func_13
           ; lr.AL = FcbFindFirstNext(FP_DS_DX, FALSE);
      jmp  dosfuncx
func_13:
      cmp  ah, 13h
      jne  func_14
           ; lr.AL = FcbDelete(FP_DS_DX);
      jmp  dosfuncx
func_14:
      cmp  ah, 14h   
      jne  func_15
           ; FCB Read
           ; lr.AL = FcbReadWrite(FP_DS_DX, 1, XFR_READ);
      jmp  dosfuncx
func_15:
      cmp  ah, 15h   ; FCB Write
      jne  func_16   
           ; lr.AL = FcbReadWrite(FP_DS_DX, 1, XFR_WRITE);
      jmp  dosfuncx
func_16:
      cmp  ah, 16h   ; FCB Open w/ create
      jne  func_17   
           ; lr.AL = FcbOpen(FP_DS_DX, O_FCB | O_LEGACY | O_CREAT | O_TRUNC | O_RDWR);
      jmp  dosfuncx
func_17:
      cmp  ah, 17h   ; FCB Rename
      jne  func_18         
           ; lr.AL = FcbRename(FP_DS_DX);
      jmp  dosfuncx
func_18:                                        ; CP/M compatibility function
      cmp  ah, 18h   
      jne  func_19            ; CPM functions are a remnant of bygone days.

      jmp  dosfuncx
func_19:
      cmp  ah, 19h
      jne  func_1a
           ; 19H Get Dflt Disk 
           ; Get Default Drive
           ; default_drive
      jmp  dosfuncx
func_1a:
      cmp  ah, 1ah
      jne  func_1b
           ; 1aH Set DTA       
           ; mov  dta, dx   ; FP_DS_DS
      jmp  dosfuncx
func_1b:
      cmp  ah, 1bh 
      jne  func_1c 
           ; Get Default Drive Data
           xor  dl, dl
           jmp  _DOS_1c   ; fall through
      jmp  dosfuncx
func_1c:
      cmp  ah, 1ch
      jne  func_1d
_DOS_1c:
           ; Get Drive Data
           ; UBYTE FAR *p = FatGetDrvData(lr.DL, &lr.AL, &lr.CX, &lr.DX);
           ; ds = seg(p)
      jmp  dosfuncx
func_1d:
      cmp  ah, 1dh  
      jne  func_1e      ; CPM

      jmp  dosfuncx
func_1e:                ; CPM
      cmp  ah, 1eh   
      jne  func_1f

      jmp  dosfuncx  
func_1f:
      cmp  ah, 1fh 
      jne  func_20 
           ; Get default DPB
           ; see case 0x32
      jmp  dosfuncx
func_20:
      cmp  ah, 20h      ; CPM
      jne  func_21     

      jmp  dosfuncx  
func_21:
      cmp  ah, 21h   
      jne  func_22   
           ; Random read using FCB: fields not updated
           ; (XFR_RANDOM should not be used here)
           ; lr.AL = FcbRandomIO(FP_DS_DX, XFR_READ);
func_22:
      cmp  ah, 22h   
      jne  func_23
           ; Random write using FCB
           ; lr.AL = FcbRandomIO(FP_DS_DX, XFR_WRITE);
      jmp  dosfuncx
func_23:
      cmp  ah, 23h   
      jne  func_24
           ; Get file size in records using FCB
           ; lr.AL = FcbGetFileSize(FP_DS_DX);
      jmp  dosfuncx
func_24:
      cmp  ah, 24h  
      jne  func_25
           ; Set random record field in FCB
           ; FcbSetRandom(FP_DS_DX);
      jmp  dosfuncx
func_25:
      cmp  ah, 25h
      jne  func_26
           ; 25H Set INT Vector 
           ; AL = vec, DS:DX SEG:OFS ptr to routine
           call setvector
      jmp  dosfuncx
func_26:
      cmp  ah, 26h          
      jne  func_27
           ; Dos Create New Psp
           ; 26h - Create new Program Segment Prefix
           call New_PSP                              ; new_psp(lr.DX, r->CS);
      jmp  dosfuncx  
func_27:
      cmp  ah, 27h          
      jne  func_2a
           ; Read random record(s) using FCB
           ; lr.AL = FcbRandomBlockIO(FP_DS_DX, &lr.CX, XFR_READ | XFR_FCB_RANDOM);
      jmp  dosfuncx
func_28:
      cmp  ah, 28h          
      jne  func_29
           ; Write random record(s) using FCB
           ; lr.AL = FcbRandomBlockIO(FP_DS_DX, &lr.CX, XFR_WRITE | XFR_FCB_RANDOM);         
      jmp  dosfunc
func_29:
      cmp  ah, 29h          
      jne  func_2a
           ; lr.SI = FcbParseFname(&lr.AL, MK_FP(lr.DS, lr.SI), FP_ES_DI);
      jmp  dosfunc
func_2a:
      cmp  ah, 2ah
      jne  func_2b
           ; 2aH Get Sys Date   
           Call GET_DOSDATE
      jmp  dosfuncx
func_2b:
      cmp  ah, 2bh
      jne  func_2c
           ; 2bH Set Sys Date
           call SET_DOSDATE
      jmp  dosfuncx
func_2c:
      cmp  ah, 2ch
      jne  func_2d
           ; 2cH Get Sys Time   
           call GET_DOSTIME
      jmp  dosfuncx
func_2d:
      cmp  ah, 2dh
      jne  func_2e
           ; 2dH Set Sys Time   
           call SET_DOSTIME
      jmp  dosfuncx
func_2e:
      cmp  ah, 2eh
      jne  func_2f
           ; 2eH Set Verify     
           mov  al, byte ptr verifyflag
           and  al, 1
           mov  byte ptr verifyflag, al
      jmp  dosfuncx
func_2f:
      cmp  ah, 2fh
      jne  func_30
           ; 2fH Get DTA        
           ; les  bx, dta
           ; lr.ES = FP_SEG(dta);
           ; lr.BX = FP_OFF(dta);
      jmp  dosfuncx
func_30:
      cmp  ah, 30h
      jne  func_31
           ; 30H Get Version    
           call MSDOS_VERSION
      jmp  dosfuncx
func_31:
      cmp  ah, 31h
      jne  func_32
           ; 31H TSR            
           Call MAKE_TSR
      jmp  dosfuncx
func_32:
      cmp  ah, 32h
      jne  func_33
           ; 32H Get DPB        
           ; DL is NOT changed by MS 6.22
           ; INT21/32 is documented to reread the DPB
           ; int drv = (lr.DL == 0 || lr.AH == 0x1f) ? default_drive : lr.DL - 1;
           ; struct dpb FAR *dpb = get_dpb(drv);
           ; if (dpb == NULL)  {
           ;  CritErrCode = -DE_INVLDDRV;
           ;  AL = 0xFF;
           ;  hazard: no error checking!
           ; flush_buffers(dpb->dpb_unit);
           ; dpb->dpb_flags = M_CHANGED;     /* force flush and reread of drive BPB/DPB */
           ;   #ifdef WITHFAT32
           ;   if (media_check(dpb) < 0 || ISFAT32(dpb))
           ;   #else
           ;   if (media_check(dpb) < 0)
           ;   #endif
           ;   lr.AL = 0xff;
           ; CritErrCode = -DE_INVLDDRV;
           ;   lr.DS = FP_SEG(dpb);
           ; lr.BX = FP_OFF(dpb);
           ; lr.AL = 0;
      jmp  dosfuncx
func_33:
      cmp  ah, 33h
      jne  func_34
           ; 3300H Get BreakLvl 
           ; 3301H Set BreakLvl 
           ; 3305H Get Boot Drv
           call MSDOS_DOSVARS
      jmp  dosfuncx
func_34:
      cmp  ah, 34h
      jne  func_35
           ; 34H Get InDOS      
           call GET_INDOS_FLAG   ;  Get InDOS flag
      jmp  dosfuncx
func_35:
      cmp  ah, 35h
      jne  func_36
           ; 35H Get INT Vector 
           ; Get Interrupt Vector
           call getvector
      jmp  dosfuncx
func_36:
      cmp  ah, 36h
      jne  func_37
           ; 36H Disk Size/Free 
           ; Dos Get Disk Free Space 
           ; lr.AX = DosGetFree(lr.DL, &lr.BX, &lr.CX, &lr.DX);
      jmp  dosfuncx
func_37:
      cmp  ah, 37h   
      jne  func_38
           ; Undocumented Get/Set Switchar
           cmp  al, 1
           jb   _dos_37g
           mov  switchchar, dl
           jmp  _dos_37x
_dos_37g:  mov  dl, switchchar
_dos_37x:  mov  al, 0
      jmp  dosfuncx
func_38:
      cmp  ah, 38h   
      jne  func_39
           ; Get/Set Country Info
           call Country_Info
      jmp  dosfuncx
func_39:
      cmp  ah, 39h
      jne  func_3a
           ; 39H MkDir          
           ;    add directory name to fat/root directory entries

      jmp  dosfuncx
func_3a:
      cmp  ah, 3ah
      jne  func_3b
           ; 3aH RmDir          
           ;    Delete directory name in fat/root directory entries
      jmp  dosfuncx
func_3b:
      cmp  ah, 3bh
      jne  func_3c
           ; 3bH ChDir                            
           ;    CD into directory name in fat/root directory entries
      jmp  dosfuncx
func_3c:
      cmp  ah, 3ch
      jne  func_3d
           ; 3CH Create File   
           ;    Add filename to fat/root directory entries
           IFDEF (FILESYS)
           call FOPEN
           ENDIF
      jmp  dosfuncx
func_3d:
      cmp  ah, 3dh
      jne  func_3e
           ; 3dH Open File     
           IFDEF (FILESYS)
           call FOPEN
           ENDIF
           ;    Return handle on AX
      jmp  dosfuncx
func_3e:
      cmp  ah, 3eh
      jne  func_3f
           ; 3eH Close File    
           ;    Close and flush file handle to disk update fat
           IFDEF (FILESYS)
           CALL FCLOSE
           ENDIF
      jmp  dosfuncx
func_3f:
      cmp  ah, 3fh
      jne  func_40
           ; 3fH Read File
           IFDEF (FILESYS)
              CALL FS_READ
           ENDIF
      jmp  dosfuncx
func_40:
      cmp  ah, 40h
      jne  func_41
           ; 40H Write File    
           IFDEF (FILESYS)
           CALL FWRITE
           ENDIF
      jmp  dosfuncx
func_41:
      cmp  ah, 41h
      jne  func_42
           ; 41H Delete File   

      jmp  dosfuncx
func_42:
      cmp  ah, 42h
      jne  func_43
           ; 42H Move File Ptr 
           ; Move file ptr (seek)
           IFDEF (FILESYS)
           CALL FS_SEEK
           ENDIF
      jmp  dosfuncx
func_43:
      cmp  ah, 43h
      jne  func_44
           ; 43H File Attrib 
           ; File Attributes

      jmp  dosfuncx
func_44:
      cmp  ah, 44h
      jne  func_45
           ; 44H IOCTL         
           ;  rc = DosDevIOctl(&lr);
           ;  can set critical error code!
           ; if (rc < SUCCESS) {
           ;   lr.AX = -rc;
           ;   if (rc != DE_DEVICE && rc != DE_ACCESS)
           ;   CritErrCode = lr.AX;
           ;   goto error_carry;
      jmp  dosfuncx
func_45:
      cmp  ah, 45h
      jne  func_46
           ; 45H Dup Handle    

      jmp  dosfuncx
func_46:
      cmp  ah, 46h
      jne  func_47
           ; 46H Redir Handle  

      jmp  dosfuncx
func_47:
      cmp  ah, 47h
      jne  func_48
           ; 47H Get Dflt Dir  
           mov  ax, 100h        ; from interrupt list
      jmp  dosfuncx
func_48:
      cmp  ah, 48h
      jne  func_49
           ; 48H Mem Alloc     
           IF (MSDOS)
              mov  cx, bx
              call AllocMemBlock ; getmem(size:longint) : pointer
              jc   alloc48_not
                   push es
                   pop  ax
                   inc  ax   ; dosmemalloc returns seg of MCB rather than data
                   mov  bx, cx
              alloc48_not:
           ELSE
              mov  cx, bx
              call smm_alloc
              jc   alloc48nx_not
                   ; AX:DX = SEG:OFS
              alloc48nx_not:
           ENDIF
      jmp  dosfuncx
func_49:
      cmp  ah, 49h
      jne  func_4a
           ; 49H Mem Free
           IF (MSDOS)
              call Free_Block ; memFree(ES - 1 < SUCCESS
              jc   dealloc49_not
                   xor   ax, ax
              dealloc49_not:
           ELSE
              call smm_free
              jc   dealloc49nx_not
                   xor   ax, ax
              dealloc49nx_not:
           ENDIF
      jmp  dosfuncx
func_4a:
      cmp  ah, 4ah
      jne  func_4b
           ; 4aH Mem Resize
           IF (MSDOS)
              call Modify_Block
              jc   modmem4a_not
                   xor  ax, ax
                   jmp  dosfuncx
              modmem4a_not:
                   mov  bx, word ptr cs:[MaxMemory]
           ELSE
              stc
              mov  bx, word ptr cs:[memused]
              ; call DOS_MEM_RESIZE
           ENDIF
      jmp  dosfuncx
func_4b:
      cmp  ah, 4bh
      jne  func_4c
           ; 4bH Exec          
           ; Exec - Load and Execute Program
           ; rc = DosExec(lr.AL, MK_FP(lr.ES, lr.BX), FP_DS_DX);
           mov  di, dx
           ;  call loadprogram
           jc   _dcs_4b_error
           clc
_dcs_4c:   jmp _dcs_4b_ret
_dcs_4b_error:
           stc
           mov  ax, 1
_dcs_4b_ret:
      jmp  dosfuncx
func_4c:
      cmp  ah, 4ch
      jne  func_4d
           ; 4cH Terminate
           ; Terminate - End Program
           call TerminateProg
      jmp  dosfuncx
func_4d:
      cmp  ah, 4dh
      jne  func_4e
           ; 4dH Get Exit Code 
           call GET_EXIT_CODE
      jmp  dosfuncx
func_4e:
      cmp  ah, 4eh
      jne  func_4f
           ; 4eH Find File/GetInfo
           ; Find File/Get Info - Dos Find First
           ; dta for this call is set on entry.  This needs to be changed
           ; for new versions.
           ; rc = DosFindFirst(lr.CX, FP_DS_DX);
      jmp  dosfuncx
func_4f:
      cmp  ah, 4fh
      jne  func_50
           ; Find Next File - Dos Find Next
           ; dta for this call is set on entry.  This needs to be changed
           ; for new versions.
           ; rc = DosFindNext();
      jmp  dosfuncx
func_50:
      cmp  ah, 50h
      jne  func_51
           ; 50H Set Cur PSP
           ; Set PSP = BX
           ; mov  currentpsp, bx

      jmp  dosfuncx
func_51:
      cmp  ah, 51h
      jne  func_52
           ; 51H Get Cur PSP
           ; Get BX = PSP !! UNDOCUMENTED !! 
           ; mov  bx, currentpsp

      jmp  dosfuncx
func_52:
      cmp  ah, 52h
      jne  func_53
           ; 52H List Of Lists
           ; *** UNDOCUMENTED - Get List of Lists
           call GET_IN_VARS
      jmp  dosfuncx
func_53:
      cmp  ah, 53h
      jne  func_54
           ; DOS 2+ internal - TRANSLATE BIOS
           ; PARAMETER BLOCK TO DRIVE PARAM BLOCK
           ; bpb_to_dpb((bpb FAR *) MK_FP(lr.DS, lr.SI), (struct dpb FAR *)MK_FP(lr.ES, r->BP)
           ; IFDEF (WITHFAT32)
           ;  cmp  cx, 4558h
           ;  jne  dcs53x
           ;  cmp  dx, 4152h
           ;  jne  dcs53x
           ; ENDIF
      jmp  dosfuncx
func_54:
      cmp  ah, 54h
      jne  func_55
           ; 54H Get Verify
           ; Get Verify Flag setting
           mov  al, byte ptr cs:verifyflag
      jmp  dosfuncx
func_55:
      cmp  ah, 55h
      jne  func_56
           ; * UNDOCUMENTED - Create New Psp/set p_size
           Call Duplicate_PSP ; child_psp(lr.DX, cu_psp, lr.SI);
           mov  word ptr cs:[_CurrentPSP], dx  ; cu_psp = lr.DX
      jmp  dosfuncx
func_56:
      cmp  ah, 56h
      jne  func_57
           ; 56H Rename/Move File
           ; DOS Rename/Move File
           ; DS:DS = ASCIIZ
           ; ES:DI = ASCIIZ PathName\Filespec
           ; Rename(file1,file2)
      jmp  dosfuncx
func_57:
      cmp  ah, 57h
      jne  func_58
           ; 57H Time/Date File
           ; Get/Set Time/Date on File
           ; AL = 1 {
           ; Set Ftime
           ; BX = handle
           ; DX = FileDate
           ; CX = FileTime
           ; } else {
           ; Get Ftime
           ; BX = handle
           ; DX = FileDate
           ; CX = FileTime
           ; }
      jmp  dosfuncx
func_58:
      cmp  ah, 58h
      jne  func_59
           ; 58H MemAlloc Strategy
           IF (MSDOS)
              call AllocStrat
           ELSE
              call Memalloc_Strat
           ENDIF
      jmp  dosfuncx
func_59:
      cmp  ah, 59h
      jne  func_5a
           ; 59H Get Err Info
           ; Get Extended Error Info - 3.0+
           ; Input: BX = 0000h need for 3.x and 4.x
           call GET_DOS_EXTERR
      jmp  dosfuncx
func_5a:
      cmp  ah, 5ah
      jne  func_5b
           ; 5aH Create Uniq File
           ; Create Temporary File
           ; MkTmp(DS:DX, CX)
      jmp  dosfuncx
func_5b:
      cmp  ah, 5bh
      jne  func_5c
           ; 5bH Create New File
           ; DosOpen(FP_DS_DX, O_LEGACY | O_RDWR | O_CREAT, lr.CX);
      jmp  dosfuncx
func_5c:
      cmp  ah, 5ch
      jne  func_5d
           ; 5cH Lock File
           ; Lock/unlock file access - SHARE.EXE
           ; rc = DosLockUnlock(lr.BX, ((unsigned long)lr.CX << 16) | lr.DX,
           ;      ((unsigned long)lr.SI << 16) | lr.DI, lr.AL != 0);
           ; if (rc != SUCCESS) goto error_exit;
      jmp  dosfuncx
func_5d:
      cmp  ah, 5dh
      jne  func_5e
           ; UNDOCUMENTED - SHARE SERVER and SDA 
           ;  AL = 0   ; remote server call
           ;       memcopy lr, DS:DX, sizeof(lc)
           ;       goto dispatch
           ;  AL = 6  
           ;       lds  si, internal_data
           ;       mov  cx, swap_indos - internal_data
           ;       mov  dx, swap_always - internal_data
           ;       clc
           ;  AL = 7  
           ;  AL = 8  
           ;  AL = 9   ; remote print directory
           ;       remote_printredir(lr.DX, Int21AX);
           ;       clc
           ;  AL = 0ah ; set extended error
           ;       memcpy(&er, FP_DS_DX, sizeof(er));
           ;       CritErrCode        = er.AX;
           ;       CritErrDev         = MK_FP(er.ES, er.DI);
           ;       CritErrLocus       = er.CH;
           ;       CritErrClass       = er.BH;
           ;       CritErrAction      = er.BL;
           ;       clc
           ; default : CritErrCode = SUCCESS;
      jmp  dosfuncx
func_5e:
      cmp  ah, 5eh
      jne  func_5f
           ; 5eH Network Misc
           call NET_MISC
      jmp  dosfuncx
func_5f:
      cmp  ah, 5fh
      jne  func_60
           ; 5fH Network Redirect
           ; These functions are avialable when the IBM PC Local Area network
           ; Program or other NETBIOS-compatible system is loaded.
           ; 5f02 = get assigned-list entry
           ; 5f03 = make network connection
           ; 5f04 = delete network connection
           ; if (inrange(UBYTE, lr.AL, 7, 8))
           ; if (lr.DL < lastdrive)
           ;  struct cds FAR *cdsp = CDSp + lr.DL;
           ;   if (FP_OFF(cdsp->cdsDpb))     /* letter of physical drive?    */
           ;      cdsp->cdsFlags &= ~CDSPHYSDRV;
           ;      if (lr.AL == 7)  cdsp->cdsFlags |= CDSPHYSDRV;
           ;rc = DE_INVLDDRV;
           ;= -(int)network_redirector_mx(REM_DOREDIRECT, &lr, (void *)Int21AX);
           ; The remote function manipulates *r directly !, so we should
           ; not copy lr to r here
           ; if !success setcarry
           ; criterrorcode = rc
      jmp  dosfuncx
func_60:
      cmp  ah, 60h   
      jne  func_61
           ; TRUENAME
           ; DosTruename(MK_FP(lr.DS, lr.SI), adjust_far(FP_ES_DI));
      jmp  dosfuncx
func_61:
      cmp  ah, 61h      
      jne  func_62               
           ; UNDOCUMENTED: no-op
           ; DOS-C: tsc support
           ; if al = 1 bTraceNext = true
           ; if al = 2 bDumpRegs = false
           mov  al, 0
      jmp  dosfuncx       
func_62:
      cmp  ah, 62h         
      jne  func_63
           ; UNDOCUMENTED: return current psp
           mov  bx, currentpsp
      jmp  dosfuncx
func_63:
      cmp  ah, 63h    
      jne  func_64
           ; UNDOCUMENTED: Double byte and korean tables
           ; DS:SI = DBCS
           mov  al, 0
           ; fails for PQDI and WATCOM utilities: use the above again
      jmp  dosfuncx
func_64:
      cmp  ah, 64h
      jne  func_65
           ; see above (invalid)
      jmp  dosfuncx
func_65:
      cmp  ah, 65h
      jne  func_66
           ; 65H National Lang Fns
           call EXT_COUNTRY_INF
      jmp  dosfuncx
func_66:
      cmp  ah, 66h
      jne  func_67
           ; Code Page functions
           ; al = 1 get codepage BX, DX
           ; al = 2 set codepage BX, DX
      jmp  dosfuncx
func_67:
      cmp  ah, 67h
      jne  func_68
           ; 67H Set Handle Cnt
           ; Set Max file handle count
           mov  _Files, BX
      jmp  dosfuncx
func_68:
      cmp  ah, 68h
      jne  func_69
           ; Flush file buffer -- COMMIT FILE. see 6a

      jmp  dosfuncx
func_69:
      cmp  ah, 69h
      jne  func_6a
           call DOS_SERIAL
      jmp  dosfuncx
func_6a:
      cmp  ah, 6ah     
      jne  func_6b
           ; DOSCommit BX - ; see case 0x68

      jmp  dosfuncx
func_6b:
      cmp  ah, 6bh     
      jne  func_6c
           ; dummy func: return AL=0
           mov  al, 0
      jmp  dosfuncx
func_6c:
      cmp  ah, 6ch
      jne  func_6d
           ; 6cH Open/Create File
           ; Extended Open-Creat, not fully functional. (bits 4,5,6 of BH)
           ; high nibble must be <= 1, low nibble must be <= 2
           ; if ((lr.DL & 0xef) > 0x2) goto error_invalid;
           ; lrc = DosOpen(MK_FP(lr.DS, lr.SI), (lr.BX & 0x70ff) | ((lr.DL & 3) << 8) |
           ;               ((lr.DL & 0x10) << 6), lr.CL);
           ; if (lrc >= SUCCESS) /* action */ lr.CX = (UWORD)(lrc >> 16);
      jmp  dosfuncx
func_6d:
      cmp  ah, 6dh      
      jne  func_6f      
           ; case 0x6d and above not implemented see default; return AL=0
           xor  ax, ax
      jmp  dosfuncx
func_6f:
      cmp  ah, 6fh      
      jne  func_70      

      jmp  dosfuncx
func_70:
      cmp  ah, 70h
      jne  func_71

      jmp  dosfuncx
func_71:
      cmp  ah, 71h
      jne  func_72
           xor  ax, ax           ; LFN - fail with "function not supported"
      jmp  dosfuncx
func_72:
      cmp  ah, 72h
      jne  func_73
           ; what ever!
      jmp  dosfuncx 
func_73:
      cmp  ah, 73h
      jne  func_74
           ; int21_fat32(&lr);
      jmp  dosfuncx 
func_74:
      cmp  ah, 74h
      jne  func_92      
           call cs:FreeDOS_LFN      ; FreeDOS LFN helper API functions
      jmp  dosfuncx
func_92:
      cmp  ah, 092h
      jne  func_e3
           nop
      jmp  dosfuncx
func_e3:
      cmp  ah, 0e3h
      jne  func_e8
           call DoubleDOS_F_e3
      jmp  dosfuncx
func_e8:   
      cmp  ah, 0e8h
      jne  func_ee
           call DoubleDOS_F_e8
      jmp  dosfuncx
func_ee:   
      cmp  ah, 0eeh
      jne  func_ce
           ; DoubleDOS
           call DoubleDOS_F_ee
      jmp  dosfuncx
func_ce:
      cmp  ah, 0ceh
      jne  func_cf
           ; Novell NetWare, Alloy NTNX - Clear File (FCB)
           nop
      jmp  dosfuncx
func_cf:
      cmp  ah, 0cfh
      jne  func_be
           nop
  
      jmp  dosfuncx
func_be:
      cmp  ah, 0BFh
      jne  func_bf    
           nop  
      jmp  dosfuncx
func_bf:
      cmp  ah, 0BFh
      jne  func_f3    
           call NXDOS_BUFFERAPI
      jmp  dosfuncx
func_f3:
      cmp  ah, 0f3h
      jne  func_fc
           call DoubleDOS_F_f3
      jmp  dosfuncx
func_fc:
      cmp  ah, 0fch  
      jne  func_fd
           ; set FreeDOS returned version for int 21.30 from BX
           mov  word ptr cs:setver, bx
      jmp  dosfuncx
func_fd:
      cmp  ah, 0fdh     
      jne  func_fe
           ; Toggle DOS-C rdwrblock trace dump
           xor  dx, dx
           mov  dl, cs:DebugFlags
           and  dl, DosRWTrace
           mov  cs:DebugFlags, dl
      jmp  dosfuncx
func_fe:
      cmp  ah, 0feh     
      jne  func_unknown
           ; Toggle DOS-C syscall trace dump
           xor  dx, dx
           mov  dl, cs:DebugFlags
           and  dl, bDumpregs
           and  dl, Syscalltrace
           mov  cs:DebugFlags, dl
           ;
      jmp  dosfuncx
func_unknown:
      ; Unsupported INT21 Call, Set AL=FF as error, NOT carry
      mov  al, 0ffh
      clc
dosfuncx:
      ret
dosfunc endp

; ===========================================================================
Int21 proc far                  ; Interrupt 21 - MSDOS Service Dispatcher API
; Portal to most DOS functions
; Set AH ot AX to service function number and prepare any registers then call
; this function or issue INT21H (if hooked).
; INT 25,26,28,29,  2f,15,31,33,67 are not called from interuppt 21h
; Input : AL = Function code
; ===========================================================================
      call dosfunc
      iret
Int21 endp

; ===========================================================================
int22 proc far                                            ; Terminate address
; Interrupt 22 - Program terminate
; ===========================================================================
      call cs:exitprog
      iret
exitprog proc far
      call cs:TerminateProg
      ret
exitprog endp
int22 endp

; ===========================================================================
int23 proc far                                           
; Interrupt 23 - Ctl-Break exit address
; ===========================================================================
      Call cs:CtrlBreak
Int1Trap:
Int3Trap:
Int4Trap:
      iret
CtrlBreak proc far
      ; if BREAK != TRUE then ignore user else exit application
      mov  al, cs:breakflag
      or   al, al
      jz   no_progbreak
           _echo '^'
           _echo 'C'
           _newline
           call cs:con_flush
           call cs:TerminateProg
no_progbreak:
      ret
CtrlBreak endp
int23 endp

; ===========================================================================
int24 proc far                                           
; Interrupt 24 - Critical error handler address
; ===========================================================================
      call cs:CriticalError
      iret
CriticalError proc far
      _print ErrMsg0001, 1
      ret
CriticalError endp
int24 endp

; ===========================================================================
int25 proc far                                           
; Interrupt 25 - Absolute DiskRead 
; ===========================================================================
      call cs:abs_diskread
      iret
abs_diskread proc far
      push ds
      pop  es
      call readsectors
      ret
abs_diskread endp
int25 endp

; ===========================================================================
int26 proc far                                           
; Interrupt 26 - Absolute DiskWrite
; ===========================================================================
      call cs:abs_diskwrite
      iret
abs_diskwrite proc far
      call writedisk
      ret
abs_diskwrite endp
int26 endp

; ===========================================================================
int27 proc far                                           
; Interrupt 27 - Terminate and stay resident
; ===========================================================================
      call Make_TSR
      iret
int27 endp

; ===========================================================================
int28 proc far                                           
; Interrupt 28 - DOS IDLE: Timeslice - CRON scheduler
; ===========================================================================
      call cs:idle
      iret
idle  proc far     ; twiddle thumbs
      push ds
      mov  ds, cs:NXDOSSEG
      cmp  byte ptr cs:InDOS, 1
      jne  we_are_indos
           push ax
           push es
           ; push word ptr cs:machineid
           ; push word ptr cs:user_r
           ; push word ptr cs:user_r+2
           ; mov  es, word ptr cs:[_cu_psp]
           ; push word ptr es:[PSP_USERSS]
           ; push word ptr es:[PSP_USERSP]
           ; int  28h
           ; mov  es, word ptr cs:[_cu_psp]
           ; pop  word ptr es:[PSP_USERSP]
           ; pop  word ptr es:[PSP_USERSS]
           ; pop  word ptr cs:user_r+2
           ; pop  word ptr cs:user_r
           ; pop  word ptr cs:machineid
           pop  es
           pop  ax
we_are_indos:
      pop  ds
      ret
idle  endp
idlespin proc far
     push cx
     jcxz endidle
idle1:
     push cx
     xor  cx, cx
idle2:
     loop idle2
     pop  cx
     loop idle1
endidle:
     pop  cx
     ret
idlespin endp
int28 endp

; ===========================================================================
int2a proc far                                           
; Interrupt 2A - DOS Network and NETBIOS interface
; ===========================================================================
msn_chk_80:
      cmp  ah, 80h
      jne  msn_chk_81
           ; Begin DOS Critical Section
           ; AL = indentifier (00-0F)
           ;  1 = KERNEL, SHARE.EXE, Network Data Structure Integrity
           ;  2 = KERNEL, Device Driver exclusivity
           ;  3 = ?
           ;  4 = ?
           ;  5 = IFSFUNC dos 4.0+
           ;  6 = IFSFUNC
           ;  7 = ?
           ;  8 = ASSIGN.COM
           mov  cs:criticalId, al
           mov  ah, 1
           mov  cs:CriticalFlag, ah
      jmp  int2a_critexit
msn_chk_81:
      cmp  ah, 81h
      jne  msn_chk_82
           ; End DOS Critical Section
           mov  cs:criticalId, al
           mov  ah, 0
           mov  cs:CriticalFlag, ah
      jmp  int2a_critexit
msn_chk_82:
      cmp  ah, 82h
      jne  msn_chk_84
           ; End DOS Critical Sections 0 - 7
           xor  ax, ax
           mov  cs:criticalId, al
           mov  cs:CriticalFlag, ah
      jmp  int2a_critexit
msn_chk_84:
      cmp  ah, 84h
      jne  msn_chk_87
           ; Keyboard Busy Loop - INT28
           ; allows other processes to run while waiting for keyboard
           call cs:idle
      jmp  int2a_critexit
msn_chk_87:
      cmp  ah, 87h
      jne  chk_MSNetwork
           ; Critcal Section
           ; AL = 1 = end = 0 = start
           not  al                   ; invert 1s comp
           mov  cs:criticalflag, al
      jmp  int2a_critexit
chk_MSNetwork:
      call cs:MSNetwork
int2a_critexit:
      iret
MSNetwork proc far
      cmp  ah, 0
      jne  msn_chk_1
           ; network installation query
           ; AH = NZ = Installed
           mov  ah, 1
      jmp  msn_exit
msn_chk_1:
      cmp  ah, 1
      jne  msn_chk_2
           ; Execute NETBIOS Request w/ no error retry - Similar to INT 5C
           ; ES:BX = NCB Network Ctrl Block
           ; ret: AL = NETBIOS error code
           ;      AH = NZ = if error

           mov  al, 1
           ; invoke netbios handler

           mov  al, 1
           mov  ah, 1
      jmp  msn_exit
msn_chk_2:
      cmp  ah, 2
      jne  msn_chk_3
           ; Set network printer mode (not listed)


      jmp  msn_exit
msn_chk_3:
      cmp  ah, 3
      jne  msn_chk_4
           ; Check if direct I/O allowed
           ; DS:SI = ASCIIZ disk device name or pathname (including ":")
           ; CF = CY = Disk access not allowed

           stc
      jmp  msn_exit
msn_chk_4:
      cmp  ah, 4
      jne  msn_chk_5
           ; Execute NETBIOS Request
           ; AL = 0 = allow retry = 1 no retry allowed
           ; ES:BX  = pointer to NCB
           ; RET : AX = Z = OK = NZ = error = AL = error code

           ; invoke netbios handler

           mov  ah, 1
           mov  al, 1
      jmp  msn_exit
msn_chk_5:
      cmp  ah, 5
      jne  msn_chk_6
           ; Get network resource information
           mov  ax, 0   ; ?
           mov  bx, 10  ; network names
           mov  cx, 10  ; NCB commands available
           mov  dx, 5   ; available sessions
      jmp  msn_exit
msn_chk_6:
      cmp  ah, 6
      jne  msn_exit
           ; Network print stream control
           ; AL = 1 = concatenation mode (one job)
           ;      2 = truncation mode (seperate job)
           ;      3 = flush printer output then start new job
           ;          similar to pressign Ctrl-Alt-Kp-*
           ; Ret : AX = error code if CF = CY

           stc
           mov  ax, 1
      jmp  msn_exit
msn_exit:
      ret
MSNetwork endp
int2a endp
; ===========================================================================
int2e proc far                                           
; Interrupt 2E - BackDoor - Execute command.com command
; ===========================================================================
      call cs:BackDoor
      iret
BackDoor proc far
      ; DS:SI - Command line (first byte of command is length) CR

      ; execute base level command.com w/ DS:SI command

      ; SS SP destroyed!

      ret
BackDoor endp
int2e endp

; ===========================================================================
int2f proc far                                           
; Interrupt 2F - Multiplex
; ===========================================================================
      call cs:mplex
      iret
mplex proc far

      ret
mplex endp
int2f endp

; ===========================================================================
int42 proc far                                           
; Interrupt 42 - Deep Thought 
; ===========================================================================
      call cs:_h2tg      
      iret
_h2tg proc far
      
      ret
_h2tg endp
int42 endp

; ===========================================================================
int69 proc far                                           
; Interrupt 69 - Toolbox API 
; ===========================================================================
      call cs:tbx_i
      iret
tbx_i proc far
           call cs:toolbox_api
      ret
tbx_i endp
int69 endp

; ===========================================================================
dummyint proc far
; ===========================================================================
         call cs:dummy
         iret
dummy    proc far

         ret
dummy    endp
dummyint endp

; ===========================================================================
rplloader proc far
; ===========================================================================
        xor  ax, ax
        mov  es, ax
        mov  bx, 4*2fh
        les  bx, es:dword ptr [bx]
        lea  di, 3[bx]
        mov  si, offset rpl
        mov  cx, 3
        repe cmpsb
        jne  rplend
        mov  cx, 5
        repe cmpsb
        jne  norpl
        mov  word ptr cs:rpl_seg, es
        mov  word ptr cs:rpl_off, bx
norpl:  mov  ax, 4a06h
        int  2fh
        inc  dx
        IF (MSDOS)
            cmp  dx, cs:MaxMemory
        ELSE
            cmp  dx, cs:memsize
        ENDIF
        jnb  rplend
        dec  dx
        dec  dx
        mov  es, dx    ; ES -> DMD
;        mov  DMD_ID, IDZ ; Last in chain
;        mov  DMD_PSP, 8  ; Owned by DOS
;        lea  di, DMD_NAME
;        mov  si, offset rpl
;        mov  cx, 4
;        rep  movsw
;        inc  dx
;        xchg dx, cs:mem_size
;        sub  dx, cs:mem_size
;        mov  cs:DMD_LEN, dx
rplend:
        ret
rplloader endp

; ===========================================================================
option_key proc far
; ===========================================================================
        xor  ax, ax
        int  1ah  ; save ticks
        mov  cx, dx
okey:
        push cx
        mov  ah, 1
        int  16h
        pop  cx
        jnz  okey_yes                ; stop if key avail
        push cx
        xor  ax, ax
        int  1ah
        pop  cx
        sub  dx, ax  ; elapsed time   > 2 secs
        cmp  dx, 36
        jb   okey
okey_no:
        xor  ax, ax  ; time out ZF no key pressed
        jmp  short okey_x
okey_yes:
        cmp  ax, F5KEY
        je   F5_p 
        cmp  ax, F6KEY
        je   F6_p
        cmp  ax, F8KEY
        je   F8_p
        jmp  okey_no
F1_p:   jmp  FxPRESSED
F2_p:   jmp  FxPRESSED
F3_p:   jmp  FxPRESSED
F4_p:   jmp  FxPRESSED
F5_p:
        xor  ax, ax
        mov  al, cs:DebugFlags
        and  al, AbortStartup
        mov  cs:DebugFlags, al
        jmp  FxPRESSED
F6_p:
        mov  al, 3
        mov  cs:runlevel, al
        jmp  FxPRESSED
F7_p:   jmp  FxPRESSED
F8_p:
        xor  ax, ax
        mov  al, cs:DebugFlags
        and  al, TraceStartup
        mov  cs:DebugFlags, al
        jmp  FxPRESSED
F9_p:   jmp  FxPRESSED
F10_p:  jmp  FxPRESSED
FxPRESSED:
        xor  ax, ax
        int  16h
        test ax, ax
okey_x:
        ret
option_key endp

; ===========================================================================
IINIT proc far                                          ; Initalise Interrupt
; ===========================================================================
	push ax	
	push es

        xor ax, ax
	mov es, ax
        ; save interuppt services int 20, 21-2fh

        call cs:savevectors
        ;

        ; set them to locs at beginning of this file
        ; Grab int0, 1, 3, 4, and 19 vectors

        ; Add the Interrupt procedure location to the IVT
        mov  cx, intrs
        lea  si, intr
        lea  di, introfs
initvectors:
             push si
             push di
             push cx
             push ds
             mov  ax, word ptr cs:[si]
             mov  cx, word ptr cs:[di]
             push cs
             pop  ds
             call setvector
             pop  ds
             pop  cx
             pop  si
             pop  di
             ;
             inc  si
             inc  di
             inc  di
        loop initvectors

	pop es
	pop ax
        ;

             IF (DEBUG)
                   breakpoint
             ENDIF

        ret
;         sub  ax, ax
;         mov  es, ax  ; 0:0 ivector
;         mov  ax, offset cs:FastConsole
;         mov  di, FASTCON_INT*4
;         stosw
;         mov  ax, ds
;         stosw
IINIT endp

; ===========================================================================
SysInit proc far
; ===========================================================================
     cli
     cld
     mov  dl, byte ptr cs:[bootdrive]
     ;
     ; ROM BOOT?
     mov  si, cs
     mov  ds, si
     cmp  dl, 0ffh
     jz   rom_boot
     ; test if debugging
     cmp  si, 1000h
     jb   disk_boot
bdos_boot:
;
; When the BIOS is loaded by the DOSLOAD or LOADER utilities under Concurrent
; for DEBUGGING or in a ROM system then on entry AX contains the current
; location of the BDOS and CX the memory Size.
; BX = current code segment
;
     mov  oscode_seg,dx           ; rom segment of bios
     mov  current_dos,ax          ; current location of the BDOS
IF (MSDOS)
     ; mov  word ptr cs:[MaxMemory], cx
ELSE
     mov  memsize, cx             ; total memory size
ENDIF
     mov  init_drv,bl             ; initial drive
     mov  comspec_drv,bh          ;
     mov  init_buf,3              ; assume default # of buffers
     mov  init_flags,3
     jmp  bios_exit
rom_boot:
     ; BIOS is copied from ROM:
     ; DL = 0FFh
     ; AX = segment address of DRBDOS
     ; BH = COMSPEC drive
     ; BL = INIT_DRV
     ; DI = BIOS ROM SEG 
     mov  oscode_seg, di  
     mov  current_dos, ax          ; current location of the BDOS
     mov  init_drv, bl             ; initial drive C:
     mov  comspec_drv, bh          ; commspec drive C:
     mov  init_flags, 3            ; it is a ROM system, use comspec drive
     jmp  dos_commonboot
disk_boot:
     ; AL = Boot drive 
     mov  oscode_seg, cs
     sub  ax, ax
     mov  current_dos, ax
     xchg ax, dx
     mov  init_runit, al
     test al, al
     jz   floppy_boot
     ;
     ; It is C:
     ;
     mov  al, 2
floppy_boot:
     mov  init_drv, al ; set boot drive
dos_commonboot:
     call cs:IINIT
     call cs:option_key
     jnz  boot_key
     mov  ah, 2
     int  16h
     and  ax, 3             ; Is it the SHIFT key?
     jz   boot_key
     mov  ax, F5KEY
boot_key:
     mov  boot_options, ax       
bios_exit:
     ; Fix ups for ROM executable internal device drivers
     mov  ax, cs  ; ROMMED?
     cmp  ax, oscode_seg
     jne  keep_code          ; no relocation required!

     ; ...

keep_code:
     ; Get System Parameters
     ; call checkcpu
     ; mov  cs:[cputype], al
     call checkndp
     mov  cs:[ndptype], al
     call cpuinfo
     call cpuspeed
     call is_pcibios
     mov  cs:[pcibus], al
     ; call enumerate_pcidevices
     call meminfo

init0:
IF (MSDOS)
     call init_memory
ELSE
     call memsetup
ENDIF
     call sinit

IF (DEBUG)
     _print MakeBufmsg, 1
     xor  ax, ax
     call readkey
     call upcase
     cmp  al, 'Y'
     jne  short NO_Buffers
ENDIF
          mov  ax, cs:init_buf
          call MkBuf
NO_Buffers:
     mov  al, byte ptr cs:[bootdrive]
     cmp  al, 80h
     jb   short init_1
          _print ErrMsg0014, 1

init_1:
     call cs:rplloader
     call devdriver
     _newline

init_2:

     call cs:testblock

IFDEF (FILESYS)
IFS:
     call cs:driverinit
     jnc  short IFS_OK
          _panic
IFS_OK:
ELSE

     stc
ENDIF
     call crash

init_3:

     ; external drivers froom config.sys

     ; then load command.com /autoexec.bat


     ret
SysInit endp

