$NOLIST

; This os.frontend.asm


    NAME OsFrontEnd


OS_CGROUP GROUP OS_CODE
OS_DGROUP GROUP OS_DATA

    nullPid EQU 0ffffh

    PUBLIC xOsOpen, xOsClose, xOsAttach, xOsDelete, xOsDetach, xOsRename
    PUBLIC xOsTruncate,  xOsGetArgument, xOsSearchForTitle
    PUBLIC xOsGetSystemID,  xOsSwitchBuffer, xOsReadDescriptor
    PUBLIC xOsDecodeException, xOsFlushAllBuffers
    PUBLIC xGetEntryPoint, xOsCreateProcess, xOsWriteDescriptor, xOsOverlay
    PUBLIC xOsAddDevice, xOsForkProcess
    PUBLIC xOsPutProperty, xOsAddAlias, xOsDeleteAlias
    PUBLIC xOsRemoveDevice, xOsUpdateDeviceList
    PUBLIC PushFlags, PopFlags

    EXTRN OsOpen:FAR, OsClose:FAR, OsAttach:FAR, OsDelete:FAR, OsDetach:FAR
    EXTRN OsRename:FAR, OsTruncate:FAR, OsSearchForTitle:FAR
    EXTRN OsGetArgument:FAR, OsGetSystemID:FAR
    EXTRN OsSwitchBuffer:FAR, OsReadDescriptor:FAR
    EXTRN OsDecodeException:FAR, OsFlushAllBuffers:FAR, GetEntryPoint:FAR
    EXTRN OsCreateProcess:FAR, OsWriteDescriptor:FAR, OsOverlay:FAR
    EXTRN OsAddDevice:FAR, IntForkProcess:FAR
    EXTRN OsPutProperty:FAR
    EXTRN OsAddAlias:FAR, OsDeleteAlias:FAR
    EXTRN OsRemoveDevice: FAR, OsUpdateDeviceList: FAR

    EXTRN EnterSystem:FAR, ExitSystem:FAR
$EJECT

OS_DATA SEGMENT PARA PUBLIC 'DATA'
  EXTRN currentUser: WORD
  EXTRN saveIP:      WORD
  EXTRN saveCS:      WORD
OS_DATA ENDS

OS_CODE SEGMENT PARA PUBLIC 'CODE'
    ASSUME CS:OS_CGROUP, DS:OS_DGROUP

  EXTRN CpWhoAmI: NEAR

jumpTable DD OsOpen
          DD OsClose
          DD OsAttach
          DD OsDelete
          DD OsDetach
          DD OsRename
          DD OsTruncate
          DD OsGetArgument
          DD OsGetSystemID
          DD OsSwitchBuffer
          DD OsReadDescriptor
          DD OsDecodeException
          DD OsFlushAllBuffers
          DD GetEntryPoint
          DD OsCreateProcess
          DD OsWriteDescriptor
          DD OsOverlay
          DD OsAddDevice
          DD IntForkProcess
          DD OsPutProperty
          DD OsAddAlias
          DD OsDeleteAlias
          DD OsRemoveDevice
          DD OsUpdateDeviceList
          DD OsSearchForTitle


$EJECT

xOsOpen LABEL FAR
    MOV  AX, 0
    JMP  SystemCall
xOsClose LABEL FAR
    MOV  AX, 1
    JMP  SystemCall
xOsAttach LABEL FAR
    MOV  AX, 2
    JMP  SystemCall
xOsDelete LABEL FAR
    MOV  AX, 3
    JMP  SystemCall
xOsDetach LABEL FAR
    MOV  AX, 4
    JMP  SystemCall
xOsRename LABEL FAR
    MOV  AX, 5
    JMP  SystemCall
xOsTruncate LABEL FAR
    MOV  AX, 6
    JMP  SystemCall
xOsGetArgument LABEL FAR
    MOV  AX, 7
    JMP  SystemCall
xOsGetSystemID LABEL FAR
    MOV  AX, 8
    JMP  SystemCall
xOsSwitchBuffer LABEL FAR
    MOV  AX, 9
    JMP  SystemCall
xOsReadDescriptor LABEL FAR
    MOV  AX, 10
    JMP  SystemCall
xOsDecodeException LABEL FAR
    MOV  AX, 11
    JMP  SystemCall
xOsFlushAllBuffers LABEL FAR
    MOV  AX, 12
    JMP  SystemCall
xGetEntryPoint LABEL FAR
    MOV  AX, 13
    JMP  SystemCall
xOsCreateProcess LABEL FAR
    MOV  AX, 14
    JMP  SystemCall
xOsWriteDescriptor LABEL FAR
    MOV  AX, 15
    JMP  SystemCall
xOsOverlay LABEL FAR
    MOV  AX, 16
    JMP  SystemCall
xOsAddDevice LABEL FAR
    MOV  AX, 17
    JMP  SystemCall
xOsForkProcess LABEL FAR
    MOV  AX, 18
    JMP  SystemCall
xOsPutProperty LABEL FAR
    MOV  AX, 19
    JMP  SystemCall
xOsAddAlias LABEL FAR
    MOV  AX, 20
    JMP  SystemCall
xOsDeleteAlias LABEL FAR
    MOV  AX, 21
    JMP  SystemCall
xOsRemoveDevice LABEL FAR
    MOV  AX, 22
    JMP  SystemCall
xOsUpdateDeviceList LABEL FAR
    MOV  AX, 23
    JMP  SystemCall
xOsSearchForTitle LABEL FAR
    MOV  AX, 24
    JMP  SystemCall
$EJECT
$LIST
SystemCall LABEL NEAR

    SHL  AX, 1
    SHL  AX, 1
    PUSH AX            ;save jump table index

    CALL CpWhoAmI
    MOV  CX, DS
    XCHG AX, BX
    MOV  AX, OS_DGROUP
    MOV  DS, AX
    XCHG BX, AX

    CMP  AX, DS:currentUser  ; am I the current pid?
    JNE  EnterTheSystem
    MOV  DS, CX
    POP  BX
 
;    MOV  AX, OS_CODE
;    MOV  ES, AX

    JMP  DWORD PTR CS:JumpTable[BX]

EnterTheSystem:
    MOV  DS, CX
    CALL EnterSystem
    CALL CpWhoAmI
    POP  BX            ;restore jump table index

;    MOV  CX, OS_CODE
;    MOV  ES, CX

; first set up the DS register

    MOV  CX, DS
    XCHG DX, AX
    MOV  AX, Os_DGROUP
    MOV  DS, AX
    XCHG AX, DX

    POP  DS:saveIP
    POP  DS:saveCS
    MOV  DS:currentUser, AX
    MOV  DS, CX

    CALL DWORD PTR CS:JumpTable[BX]

    MOV  SI, DS      ;save DS reg
    MOV  DI, AX      ;save AX reg
    MOV  AX, OS_DGROUP
    MOV  DS, AX

    PUSH DS:saveCS
    PUSH DS:saveIP
    MOV  DS:currentUser, nullPid
    MOV  AX, DI      ;restore it
    MOV  DS, SI      ;restore it
    
    PUSH AX            ;save any returned parameters
    PUSH BX
    PUSH CX
    PUSH DX
    PUSH ES

    CALL ExitSystem

    POP  ES            ;restore any returned parameters
    POP  DX
    POP  CX
    POP  BX
    POP  AX

LongRet PROC FAR
    RET                ;long return to long caller
LongRet ENDP

; PushFlags: PROCEDURE CLEAN

; This routine will push the flags onto the stack.

PushFlags PROC NEAR
  POP  DI
  PUSHF
  JMP DI
PushFlags ENDP

; PopFlags: PROCEDURE CLEAN

; This routine will push the flags onto the stack.

PopFlags PROC NEAR
  POP  DI
  POPF
  JMP DI
PopFlags ENDP

OS_CODE ENDS

    END
