$LIST

; This Os.xWindows.ASM


    NAME xWindows


RAM_CGROUP GROUP RAM_CODE
OS_DGROUP GROUP OS_DATA

    nullPid      EQU      0ffffh
    NULLWORD     EQU      0FFFFh
    signalNormal EQU      1

    PUBLIC xWinTestPixel, xWinClipRectangle, xWinClipLine, xWinDrawLine
    PUBLIC xWinEraseLine, xWinInvertLine, xWinResetClip, xWinSetClip
    PUBLIC xWinInitDefaultWindow, xWinEraseRectangle, xWinInvertRectangle
    PUBLIC xWinEraseWindow, xWinFrameWindow, xWinDrawPixel, xWinErasePixel
    PUBLIC xWinCopyRectangle, xWinScrollRectangle, xWinScrollWindow
    PUBLIC xWinDrawChar, xWinDrawChars, xWinInvertChar, xWinEraseChar
    PUBLIC xWinGetWindowExtent, xWinInvertPixel, xWinSetWindow
    PUBLIC xWinSetAlternateWindow, xWinCopyRemoteRectangle

    PUBLIC EnterWindows, LeaveWindows


    EXTRN WinTestPixel:FAR, WinClipRectangle:FAR, WinClipLine:FAR
    EXTRN WinDrawLine:FAR
    EXTRN WinEraseLine:FAR, WinInvertLine:FAR, WinResetClip:FAR, WinSetClip:FAR
    EXTRN WinInitDefaultWindow:FAR, WinEraseRectangle:FAR
    EXTRN WinInvertRectangle:FAR
    EXTRN WinEraseWindow:FAR, IntWinFrameWindow:FAR, WinDrawPixel:FAR
    EXTRN WinErasePixel:FAR
    EXTRN WinCopyRectangle:FAR, WinScrollRectangle:FAR, WinScrollWindow:FAR
    EXTRN WinDrawChar:FAR, WinDrawChars:FAR, WinInvertChar:FAR, WinEraseChar:FAR
    EXTRN WinGetWindowExtent:FAR, WinInvertPixel:FAR, WinSetWindow:FAR
    EXTRN WinSetAlternateWindow: FAR, WinCopyRemoteRectangle: FAR

    EXTRN CpWait:NEAR, CpSignal:NEAR
$EJECT

OS_DATA SEGMENT PARA PUBLIC 'DATA'
  EXTRN windowSema: WORD

  windowSaveIP DW 1 DUP (?)
  windowSaveCS DW 1 DUP (?)
OS_DATA ENDS

RAM_CODE SEGMENT PARA PUBLIC 'CODE'
    ASSUME CS:RAM_CGROUP, DS:OS_DGROUP

  EXTRN CpWhoAmI: NEAR

jumpTable DD WinTestPixel
          DD WinClipLine
          DD WinClipRectangle
          DD WinDrawLine
          DD WinEraseLine
          DD WinInvertLine
          DD WinSetClip
          DD WinResetClip
          DD WinSetWindow
          DD WinInitDefaultWindow
          DD WinEraseRectangle
          DD WinInvertRectangle
          DD WinEraseWindow
          DD IntWinFrameWindow
          DD WinDrawPixel
          DD WinErasePixel
          DD WinCopyRectangle
          DD WinScrollRectangle
          DD WinScrollWindow
          DD WinDrawChar
          DD WinDrawChars
          DD WinInvertChar
          DD WinEraseChar
          DD WinGetWindowExtent
          DD WinInvertPixel
          DD WinSetAlternateWindow
          DD WinCopyRemoteRectangle


$EJECT

;  EnterWindows: PROCEDURE
;
; Enter the Window through windowSema
;
EnterWindows PROC FAR
    PUSH DS            ; save old DS reg
    PUSH AX            ; space for error
    MOV  BX, SP
    MOV  AX, OS_DGROUP
    MOV  DS, AX
    PUSH DS:windowSema     ; window sema
    MOV  AX, NULLWORD 
    PUSH AX                ; time = NULLWORD
    PUSH SS                ; pError
    PUSH BX
    CALL CpWait            ; wait on windowSema
    POP  AX            ; old error
    POP  DS            ; old DS register
    RET
; Now we have entered
EnterWindows ENDP

;  LeaveWindows: PROCEDURE
;
; Leave the Window through windowSema

LeaveWindows PROC FAR
    PUSH DS            ; save old DS reg
    PUSH AX            ; space for error
    MOV  BX, SP
    MOV  AX, OS_DGROUP
    MOV  DS, AX
    PUSH DS:windowSema     ; window sema
    MOV  AX, signalNormal
    PUSH AX                ; mode
    XOR  AX, AX
    PUSH AX                ; note = 0
    PUSH SS                ; pError
    PUSH BX
    CALL CpSignal          ; signal windowSema
    POP  AX                ; old error
    POP  DS                ; old DS register
    RET
LeaveWindows ENDP
$EJECT
xWinTestPixel LABEL FAR
    MOV  AX, 0
    JMP  WindowCall
xWinClipLine LABEL FAR
    MOV  AX, 1
    JMP  WindowCall
xWinClipRectangle LABEL FAR
    MOV  AX, 2
    JMP  WindowCall
xWinDrawLine LABEL FAR
    MOV  AX, 3 
    JMP  WindowCall
xWinEraseLine LABEL FAR
    MOV  AX, 4
    JMP  WindowCall
xWinInvertLine LABEL FAR
    MOV  AX, 5
    JMP  WindowCall
xWinSetClip LABEL FAR
    MOV  AX, 6
    JMP  WindowCall
xWinResetClip LABEL FAR
    MOV  AX, 7
    JMP  WindowCall
xWinSetWindow LABEL FAR
    MOV  AX, 8
    JMP  WindowCall
xWinInitDefaultWindow LABEL FAR
    MOV  AX, 9
    JMP  WindowCall
xWinEraseRectangle LABEL FAR
    MOV  AX, 10
    JMP  WindowCall
xWinInvertRectangle LABEL FAR
    MOV  AX, 11
    JMP  WindowCall
xWinEraseWindow LABEL FAR
    MOV  AX, 12
    JMP  WindowCall
xWinFrameWindow LABEL FAR
    MOV  AX, 13
    JMP  WindowCall
xWinDrawPixel LABEL FAR
    MOV  AX, 14
    JMP  WindowCall
xWinErasePixel LABEL FAR
    MOV  AX, 15
    JMP  WindowCall
xWinCopyRectangle LABEL FAR
    MOV  AX, 16
    JMP  WindowCall
xWinScrollRectangle LABEL FAR
    MOV  AX, 17
    JMP  WindowCall
xWinScrollWindow LABEL FAR
    MOV  AX, 18
    JMP  WindowCall
xWinDrawChar LABEL FAR
    MOV  AX, 19
    JMP  WindowCall
xWinDrawChars LABEL FAR
    MOV  AX, 20
    JMP  WindowCall
xWinInvertChar LABEL FAR
    MOV  AX, 21
    JMP  WindowCall
xWinEraseChar LABEL FAR
    MOV  AX, 22
    JMP  WindowCall
xWinGetWindowExtent LABEL FAR
    MOV  AX, 23
    JMP  WindowCall
xWinInvertPixel LABEL FAR
    MOV  AX, 24
    JMP  SHORT WindowCall
xWinSetAlternateWindow LABEL FAR
    MOV  AX, 25
    JMP  SHORT WindowCall
xWinCopyRemoteRectangle LABEL FAR
    MOV  AX, 26
;    JMP  SHORT WindowCall
$EJECT

WindowCall LABEL NEAR

    PUSH AX            ;save jump table index

; Enter the Window through windowSema
    CALL EnterWindows

    POP  BX            ;restore jump table index

    SHL  BX, 1
    SHL  BX, 1
    MOV  AX, RAM_Code
    MOV  ES, AX

; first set up the DS register

    MOV  CX, DS
    MOV  AX, Os_DGROUP
    MOV  DS, AX

    POP  DS:windowSaveIP
    POP  DS:windowSaveCS
    MOV  DS, CX

    CALL DWORD PTR ES:JumpTable[BX]

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

    PUSH DS:windowSaveCS
    PUSH DS:windowSaveIP
    MOV  AX, DI      ;restore it
    MOV  DS, SI      ;restore it
    
    PUSH AX            ;save any returned parameters
    PUSH BX
    PUSH CX
    PUSH DX
    PUSH ES

; Leave the Window through windowSema
    CALL LeaveWindows


EndItAll:
    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

RAM_CODE ENDS

    END
