$NOLIST
  NAME PascalCalls

RAM_CGROUP GROUP RAM_CODE

PUBLIC SetPascalCallsInterrupt

EXTRN PQ_310 : FAR
EXTRN PQ_320 : FAR
EXTRN PQ_546 : FAR
EXTRN PQ_566 : FAR
EXTRN PQ_571 : FAR
EXTRN PQ_575 : FAR
EXTRN PQ_577 : FAR
EXTRN PQ_578 : FAR
EXTRN PQ_580 : FAR
EXTRN PQ_585 : FAR
EXTRN PQ_595 : FAR
EXTRN TQ_001 : FAR
EXTRN TQ_100 : FAR
EXTRN TQ_110 : FAR
EXTRN TQ_125 : FAR
EXTRN TQ_150 : FAR
EXTRN TQ_999 : FAR
EXTRN MQERACS : FAR
EXTRN MQERASN : FAR
EXTRN MQERATN : FAR
EXTRN MQERCI2 : FAR
EXTRN MQERCOS : FAR
EXTRN MQEREXP : FAR
EXTRN MQERINT : FAR
EXTRN MQERLGE : FAR
EXTRN MQERNI2 : FAR
EXTRN MQERNIN : FAR
EXTRN MQERSIN : FAR
EXTRN MQERTAN : FAR
EXTRN INITFP : FAR
EXTRN PatchHole : FAR
EXTRN LQ_DWORD_MUL: FAR
EXTRN LQ_DWORD_DIV: FAR
$EJECT

$LIST
RAM_CODE SEGMENT PARA PUBLIC 'CODE'
  ASSUME CS:RAM_CGROUP

routines DD PatchHole ;MQERAIN
         DD PatchHole ;MQERANT
         DD PatchHole ;MQERAT2
         DD PatchHole ;MQERCSH
         DD PatchHole ;MQERDIM
         DD PatchHole ;MQERLGD
         DD PatchHole ;MQERMAX
         DD PatchHole ;MQERMIN
         DD PatchHole ;MQERMOD
         DD PatchHole ;MQERRMD
         DD PatchHole ;MQERRNT
         DD PatchHole ;MQERSGN
         DD PatchHole ;MQERSNH
         DD PatchHole ;MQERTNH
         DD PatchHole ;MQERY2X
         DD PatchHole ;MQERYI4
         DD PatchHole ;NORMAL
         DD PQ_546
         DD PQ_566
         DD PQ_571
         DD PQ_575
         DD PQ_577
         DD PQ_578
         DD PQ_580
         DD PQ_585
         DD PQ_595
         DD PatchHole ;PQ_ADD_PTR
         DD PatchHole ;PQ_ALL_ZEROS
         DD PatchHole ;PQ_BUILD_EMPTY_STACK_AT
         DD PatchHole ;PQ_COPYP
         DD PatchHole ;PQ_COPY_DOWN_STK
         DD PatchHole ;PQ_COPY_STK
         DD PatchHole ;SIEVE
         DD PatchHole ;PQ_FILLP
         DD PatchHole ;PQ_FILLS
         DD PatchHole ;PQ_FILL_BOOLEAN_PACK
         DD PatchHole ;PQ_FILL_HEADER_INFO
         DD PatchHole ;PQ_FIXDOWN2_STACK_FOR_OLD_SET
         DD PatchHole ;PQ_FIXDOWN2_STACK_FOR_SIZE
         DD PatchHole ;PQ_FIXUP2_STACK_FOR_NEW_SET
         DD PatchHole ;PQ_FIXUP2_STACK_FOR_SIZE
         DD PatchHole ;PQ_FIXUP_BASE_AND_SIZE
         DD PatchHole ;PQ_GEN_COPY_SET
         DD PatchHole ;PQ_GET_STACK_SET_INFO
         DD PatchHole ;PQ_INC_PTR
         DD PatchHole ;PQ_MAKE_SS_PTR
         DD PatchHole ;PQ_NEW_SET_NTH_BIT_ON
         DD PatchHole ;PQ_NORMALIZE_OFFSET
         DD PatchHole ;PQ_NUMBER_OF_WORDS
         DD PatchHole ;PQ_SETS_OVERLAP
         DD PatchHole ;PQ_SET_ERROR
         DD PatchHole ;TQFETCH_AND_STORE
         DD PatchHole ;TQINSTRUCTION_RETRY
         DD PatchHole ;TQNORMALIZE
         DD PatchHole ;TQPOP_THE_TOP
         DD PatchHole ;TQRESTORE_PTRS
         DD PatchHole ;TQSAVE_PTRS
         DD PatchHole ;TQUNPOP_THE_TOP
         DD PatchHole ;TQ_320
         DD PatchHole ;TQ_322
         DD PatchHole ;TQ_324
         DD PatchHole ;TQ_326
         DD PatchHole ;PQCALL_DEVICEDRIVER
         DD PatchHole ;PQINTERNALWRITEBUFFER
         DD PatchHole ;PQI_ALLOCATE
         DD PatchHole ;PQI_FREE
         DD PatchHole ;PQUTSCLOSEDOWN
         DD PatchHole ;PQUTSSTARTUP
         DD PQ_310
         DD PQ_320
         DD PatchHole ;PQ_ADD_BLOCK
         DD PatchHole ;PQ_ADD_NEW_PAGE
         DD PatchHole ;PQ_ALLOCATE_BLOCK
         DD PatchHole ;PQ_ERROR_CHECK
         DD PatchHole ;PQ_FIND_BLOCK
         DD PatchHole ;PQ_FREE_BLOCK
         DD PatchHole ;MQ_1
         DD PatchHole ;PQ_FREE_PAGE
         DD PatchHole ;PQ_GET_LOCAL_TOKEN
         DD PatchHole ;PQ_INIT_FREE_LIST
         DD PatchHole ;PQ_IOSC
         DD PatchHole ;PQ_REMOVE_BLOCK
         DD PatchHole ;TQALLOCATE
         DD PatchHole ;TQESTART
         DD PatchHole ;TQEXIT
         DD PatchHole ;TQFREE
         DD PatchHole ;TQGETERH
         DD PatchHole ;TQINITIALIZE
         DD PatchHole ;TQINITIO
         DD PatchHole ;TQINITMM
         DD PatchHole ;TQPARSECL
         DD PatchHole ;TQSETERH
         DD PatchHole ;TQWHERESTRAP87
         DD TQ_001
         DD TQ_100
         DD PatchHole ;TQ_102
         DD TQ_110
         DD PatchHole ;TQ_120
         DD PatchHole ;TQ_121
         DD TQ_125
         DD TQ_150
         DD PatchHole ;TQ_152
         DD PatchHole ;TQ_160
         DD PatchHole ;TQ_170
         DD PatchHole ;TQ_171
         DD PatchHole ;TQ_180
         DD PatchHole ;TQ_181
         DD PatchHole ;TQ_190
         DD PatchHole ;TQ_191
         DD PatchHole ;TQ_200
         DD PatchHole ;TQ_210
         DD PatchHole ;TQ_312
         DD PatchHole ;TQ_313
         DD TQ_999
         DD PatchHole ;TQ_COPYRIGHT
         DD PatchHole ;TQ_FLPERH
         DD PatchHole ;TQ_HEXOUT
         DD PatchHole ;TQ_IN_8087_ERH
         DD PatchHole ;TQ_LRSERH
         DD PatchHole ;TQ_MSGOUT
         DD PatchHole ;TQ_PUSHSTR
         DD PatchHole ;TQ_STATUS_CHECK
         DD PatchHole ;TQ_SYSERH
         DD PatchHole ;TQ_TRAP87
         DD PatchHole ;UQ_100
         DD MQERACS
         DD MQERASN
         DD MQERATN
         DD MQERCI2
         DD MQERCOS
         DD MQEREXP
         DD PatchHole ;MQERIA2
         DD PatchHole ;MQERIA4
         DD PatchHole ;MQERIC2
         DD PatchHole ;MQERIC4
         DD PatchHole ;MQERIE2
         DD PatchHole ;MQERIE4
         DD MQERINT
         DD PatchHole ;MQERIRT
         DD MQERLGE
         DD MQERNI2
         DD MQERNIN
         DD PatchHole ;MQERRI2
         DD PatchHole ;MQ_I
         DD MQERSIN
         DD MQERTAN
         DD PatchHole ;MQ_2XM1
         DD PatchHole ;MQ_63U
         DD PatchHole ;MQ_63U1
         DD PatchHole ;MQ_63UPI2
         DD PatchHole ;MQ_AT2
         DD PatchHole ;MQ_COS
         DD PatchHole ;MQ_CP2N63
         DD PatchHole ;MQ_DECIDE
         DD PatchHole ;MQ_EXIT
         DD PatchHole ;MQ_EXM1
         DD PatchHole ;MQ_IRCHK
         DD PatchHole ;MQ_LOG
         DD PatchHole ;MQ_LOG10
         DD PatchHole ;MQ_LOGDN
         DD PatchHole ;MQ_MQRPI
         DD PatchHole ;MQ_NAN
         DD PatchHole ;MQ_NQ
         DD PatchHole ;MQ_OF
         DD PatchHole ;MQ_P0
         DD PatchHole ;MQ_PI2
         DD PatchHole ;MQ_PII
         DD PatchHole ;MQ_Q
         DD PatchHole ;MQ_RAD
         DD PatchHole ;MQ_RERR
         DD PatchHole ;MQ_SIN
         DD PatchHole ;MQ_U0
         DD PatchHole ;MQ_YL2X
         DD PatchHole ;MQ_CONST
         DD PatchHole ;TQLOCAL
         DD PatchHole ;PQ_HIGH_BITS_ON
         DD PatchHole ;PQ_LOW_BITS_ON
         DD PatchHole ;TQDEFAULTPL
         DD InitFP    ;INIT87 - should be the same
         DD INITFP
         DD PatchHole ;TQDECODE87
         DD PatchHole ;TQENCODE87
         DD PatchHole ;TQNANFILTER
         DD PatchHole ;TQNORM87
         DD PatchHole ;Filter
         DD PatchHole ;Encode
         DD PatchHole ;Decode
         DD LQ_DWORD_MUL
         DD LQ_DWORD_DIV
$EJECT
params STRUC
  regAX      DW ?
  regES      DW ?
  regBX      DW ?
  regBP      DW ?
  routineIP  DW ?
  routineCS  DW ?     ; also return IP on entry
  returnIP   DW ?     ; also return CS on entry
  returnCS   DW ?     ; also return FL on entry
params ENDS
params1 STRUC
  seeAbove   DW 5 DUP (?)
  entryIP    DW ?     
  entryCS    DW ?     
  entryFl    DW ?     
params1 ENDS
loc  EQU SS:[BP]

IntrEntry LABEL FAR
  JMP  SHORT InterruptEntry

IndrEntry:
  JMP  SHORT IndirectEntry

; jump table access
jumpTable:
  DW   routines
  DW   0
parms:
  DW   0000Fh
  DW   0FFFFh
routineCount:
  DB   188

InterruptEntry:
  PUSH AX          ; room for return
  PUSH BP          ; save the registers
  PUSH BX
  PUSH ES
  PUSH AX
  MOV  BP, SP

  MOV  AX, loc.entryFL  ; Flags
  PUSH AX
  POPF                  ; set the flags

  MOV  AX, loc.entryCS  ; CS
  MOV  BX, loc.entryIP  ; IP
  MOV  ES, AX

  MOV  AX, ES:[BX] ; get call #
  XOR  AH, AH
  INC  BX          ; skip call #

  MOV  loc.returnCS, ES  ; restore CS
  MOV  loc.returnIP, BX  ; restore IP

IndirectEntry:
  PUSH DI          ; save DI reg
  MOV  BX, AX      ; table index
  SHL  BX, 1
  SHL  BX, 1       ; bx = bx * 4
  CMP  AL, BYTE PTR routineCount
  JA   CallPatchHole

  LES  DI, DWORD PTR jumpTable
  MOV  AX, ES
  OR   AX, AX
  JNZ  SHORT GetThePointer
  MOV  AX, CS
  MOV  ES, AX    ; seg is current segment

GetThePointer:
  MOV  AX, WORD PTR ES:[DI+BX+2]  ;CS
  MOV  loc.routineCS, AX  ;restore it
  CMP  AX, SEG PatchHole
  JNE  SetOffset
  MOV  AX, WORD PTR ES:[DI+BX]    ;IP
  MOV  loc.routineIP, AX   ;restore it
  CMP  AX, OFFSET PatchHole
  JNE  AllDone

CallPatchHole:
  SHR  BX, 1
  SHR  BX, 1
  PUSH BX
  CALL PatchHole

SetOffset:
  MOV  AX, WORD PTR ES:[DI+BX]    ;IP
  MOV  loc.routineIP, AX   ;restore it

AllDone:
  POP  DI
  POP  AX           ; restore the regs
  POP  ES
  POP  BX
  POP  BP

LongReturn PROC FAR
  RET
LongReturn ENDP
$EJECT

SetPascalCallsInterrupt PROC FAR
  PUSH DS
  PUSH BP

  XOR  AX, AX
  MOV  ES, AX

  CLI

  MOV  AX, 4 * 114
  MOV  BX, AX

  MOV  AX, SEG IntrEntry
  MOV  ES:[BX+2], AX

  MOV  AX, OFFSET IntrEntry
  MOV  ES:[BX+0], AX

  STI

  POP  BP
  POP  DS
  RET
SetPascalCallsInterrupt ENDP

RAM_CODE ENDS

  END
