	title "rtx register support"
	page ,132

	;''''''''''''''''''''''''''''''''''''''''''''''''''''''';
	;  Interrupt/ Register Support for RTX                  ;
	;- - - - - - - - - - - - - - - - - - - - - - - - - - - -;
	;                                                       ;
	;  (C) Copyright, 1991.  Mike Podanoffsky               ;
	;      All Rights Reserved.                             ;
	;                                                       ;
	;  Technical questions: 508/ 454-1620.                  ;
	;.......................................................;

	include stddefs.asm

rtx_text	segment  word public 'CODE'
rtx_text	ends

reg_supp segment para public 'CODE'
	assume cs:reg_supp, ds:reg_supp, es:reg_supp, ss:reg_supp

        public insideDos                        ;switch used when in Dos
        public ischeduler                       ;iret scheduler call
        public scheduler                        ;far call scheduler call
        public setClockInterrupt                ;tells clock ISR when to int
        public keyboardEventFct                 ;keyboard event function

        public condenableInts                   ;allow ints on cond
        public enableInts                       ;enable interrupts
        public disableInts                      ;disable interrupts
        public enableSched                      ;enable scheduler
        public disableSched                     ;disable scheduler

        public save_initregs                    ;used to init a task's stack
        public init_IntTraps                    ;initial state interrupt traps
        public restore_IntTraps                 ;restore interrupt traps

        extrn  terminateTask_id:far
	extrn  scheduleTask:far
        extrn  saveCurrentTask_Stack:far
        extrn  returntask_StackFrame:far
        extrn  waitKbdEvent:far
        extrn  setKbdEvent:far
        extrn  getPriority:far
        extrn  setPriority:far
        extrn  countDown_Timers:far
	extrn  showcounts:far

	extrn  comAck:far
	extrn  com_ISR_odd:far
	extrn  com_ISR_even:far
	;extrn  comPutChar1:far


        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  Flags/ Storage Definitions                           ;
        ;.......................................................;

insideDos:              dw 0
schedulerPending:       dw 0
Rtx_DataSegment:        dw 0


_originalDosTrap:       dd 0
_originalTickInt:       dd 0
_originalKbdSvcTrap:    dd 0
_originalKbdHdwTrap:    dd 0
_originalScrnTrap:      dd 0
_originalCOM1Int:       dd 0
_originalCOM2Int:       dd 0

total_ints:             dw 0
_ClockArmValue:         dd 0


        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  Macro Definitions.                                   ;
        ;.......................................................;

_Int    macro loc

        inc word ptr cs:[insideDos]

        pushf
        call dword ptr cs:[loc]                 ;keep rentrancy problems down.
        call enableSched

        endm


        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  save_initregs                                        ;
        ;- - - - - - - - - - - - - - - - - - - - - - - - - - - -;
        ;                                                       ;
        ;  Initializes stack for task so that it appears sus-   ;
        ;  pended to the scheduler.                             ;
        ;                                                       ;
        ;  void far * pascal save_initregs                      ;
        ;       ( void far * stack,                             ;
        ;         void far * start_addr,                        ;
        ;         void far * argument,                          ;
        ;         int task_id );                                ;
        ;                                                       ;
        ;.......................................................;

    entry save_initregs                         ;emulates Pascal conventions
                                                ; <must have them in rev stack order>
        iarg __task_id                          ; int task_id
	darg __argument                         ; void far * argument,
	darg __start_addr                       ; void far *start_addr, 
	darg __stack                            ; void far * stack,

;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;  order of items stored to task's stack
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
_task_id        equ     40
_argument       equ     36                      ;void far *
_taskExit       equ     32                      ;task exit address

_start_addr     equ     28                      ;start address
_pushf          equ     26                      ;push flag emulation
_push_ax        equ     24                      ;ax
_push_bx        equ     22                      ;bx
_push_cx        equ     20                      ;cx
_push_dx        equ     18                      ;dx
_push_si        equ     16                      ;si
_push_di        equ     14                      ;di
_push_bp        equ     12                      ;bp

_push_ds        equ     10                      ;ds
_push_es        equ     08                      ;es

_push_dta       equ     04                      ;dta
_push_stackf    equ     00                      ;null stack frame pointer(req'd )

FLAGS_VALUE     equ     0246h                   ;ei zr nc


;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;  execution starts here.
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
	saveSegments

        push ds
        pop es                                  ;insure es: = ds:
	getdarg ds,bx,__stack                   ;where we'll emulate this.

        sub bx,128                              ;disk transfer address
        push bx
        push ds                                 ;ds:bx

        sub bx,_task_id+2                       ;total arguments we'll store

;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;  task stack will contain task_id, return address, ...
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
	getarg ax,__task_id                     ;
        mov word ptr _task_id [bx],ax

	getdarg dx,ax,__argument
        mov word ptr _argument+2 [bx],dx
        mov word ptr _argument [bx],ax

        mov word ptr _taskExit+2 [bx], seg taskExit
        mov word ptr _taskExit [bx], offset taskExit

        mov word ptr _pushf [bx], FLAGS_VALUE   ;flags.

	getdarg dx,ax,__start_addr
        mov word ptr _start_addr+2 [bx],dx
        mov word ptr _start_addr [bx],ax

;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;  now save on stack ALL registers
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        xor ax,ax
        mov word ptr _push_ax [bx],ax
        mov word ptr _push_bx [bx],ax
        mov word ptr _push_cx [bx],ax
        mov word ptr _push_dx [bx],ax
        mov word ptr _push_si [bx],ax
        mov word ptr _push_di [bx],ax
        mov word ptr _push_bp [bx],ax

        mov word ptr _push_ds [bx],ss
        mov word ptr _push_es [bx],ss

        pop word ptr _push_dta [bx]             ; seg  (dta)
        pop word ptr _push_dta + 2 [bx]         ; address

        xor ax,ax
        mov word ptr _push_stackf [bx],ax       ; seg  (stack frame)
        mov word ptr _push_stackf+ 2 [bx],ax    ; address

;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;  return adjusted stack address
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        mov dx,ds
        mov ax,bx                               ; dx:ax contain remaining stack.

	restoreSegments
	return pascal

save_initregs     endp

        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  scheduler                                            ;
	;- - - - - - - - - - - - - - - - - - - - - - - - - - - -;
	;                                                       ;
	;  No parameters.                                       ;
	;                                                       ;
	;  Will suspend current task, schedule next task.       ;
	;  See related function: ischedule() for isr calls.     ;
	;                                                       ;
	;.......................................................;

scheduler         proc far

	pushf                                   ;save flags
	cli                                     ;stop interrupts
	cmp word ptr cs:[ insideDos ],0         ;inside DOS ?
	jz scheduler_04                         ;don't schedule -->
	mov word ptr cs:[schedulerPending],-1   ;say we'll stay pending
	jmp scheduler_40                        ;exit -->

scheduler_04:
	inc word ptr cs:[ insideDos ]
	sti                                     ;its safe to interr now

	SaveRegisters

	callDos GetDiskTransferAddr
	push bx
	push es                                 ;save data on stack.

	mov ds, word ptr cs:[Rtx_DataSegment]
	mov es, word ptr cs:[Rtx_DataSegment]

	cli
	call rtx_text:returntask_StackFrame
	push dx                                 ;save current stack frame.
	push ax

	mov dx,ss
	mov ax,sp
	push dx
	push ax
	call rtx_text:saveCurrentTask_Stack
	sti

;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;  round robin task within priority
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

	xor dx,dx
	push dx
	push dx                                 ;NULL pointer means curr task
	call rtx_text:getPriority               ;return priority
	or ax,ax
	jz scheduler_32

	xor dx,dx
	push dx
	push dx                                 ;NULL pointer means curr task
	push ax                                 ;reset priority
	call rtx_text:setPriority

;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;  if return, stack switch
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
scheduler_32:
	call rtx_text:scheduleTask

	mov cx,ax
	or cx,dx                                ;NULL value ?
	jnz scheduler_36temp                    ;don't switch stacks -->
	int 3
	jmp scheduler_38

scheduler_36temp:
	cli                                     ;switch task stacks.
	mov ss,dx
	mov sp,ax

;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;  if return, stack switch
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
scheduler_38:
	call rtx_text:saveCurrentTask_Stack     ;restore stack frame.
	call rtx_text:showcounts

	sti                                     ;ok ints now

	pop ds                                  ;restore dta.
	pop dx
	callDos SetDiskTransferAddr

	RestoreRegisters
	dec word ptr cs:[insideDos]
	mov word ptr cs:[schedulerPending],0

scheduler_40:
	popf                                    ;this will restore ints
	ret

scheduler         endp

	;''''''''''''''''''''''''''''''''''''''''''''''''''''''';
	;  scheduler                                            ;
	;- - - - - - - - - - - - - - - - - - - - - - - - - - - -;
        ;                                                       ;
        ;  No parameters.                                       ;
        ;                                                       ;
        ;  Will suspend current task, schedule next task.       ;
        ;  Performs an iret.  Some ISRs may find this call      ;
        ;  preferable.                                          ;
        ;                                                       ;
        ;.......................................................;

ischeduler        proc far

        call scheduler
        iret
ischeduler         endp

        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  taskExit()                                           ;
        ;- - - - - - - - - - - - - - - - - - - - - - - - - - - -;
        ;                                                       ;
        ;  This process is called whenever a task terminates.   ;
        ;  Calls scheduler to release task.                     ;
        ;                                                       ;
        ;.......................................................;

taskExit        proc far
        mov bp,sp                               ;didn't get here through a call
        mov dx,word ptr [bp]                    ;should be task_id

; switch to temp stack, then ...
        cli
        mov ds, word ptr cs:[Rtx_DataSegment]
        mov ax,seg temp_stack
        mov ss,ax
        mov sp,offset temp_stack

        sti
        push dx                                 ;copy to stack
	call rtx_text:terminateTask_id          ;terminate task

taskExit_08:
        call scheduler
        jmp taskExit_08

taskExit        endp

        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  enableSched                                          ;
        ;- - - - - - - - - - - - - - - - - - - - - - - - - - - -;
        ;                                                       ;
        ;  No Parameters.                                       ;
        ;                                                       ;
        ;  The flag insideDos is used to prevent the scheduler  ;
        ;  from running.  This performs similar to disabling    ;
        ;  interrupts, except only the scheduler is disabled.   ;
        ;                                                       ;
        ;.......................................................;

enableSched     proc far

        pushf
        dec word ptr cs:[ insideDos ]
        jnz enableSched_08              ;still busy -->
        cmp word ptr cs:[schedulerPending],0
        jz enableSched_08               ;not pending -->

        call scheduler

enableSched_08: popf
        ret                              

enableSched     endp

        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  disableSched                                         ;
        ;- - - - - - - - - - - - - - - - - - - - - - - - - - - -;
        ;                                                       ;
        ;  No Parameters.                                       ;
        ;                                                       ;
        ;  The flag insideDos is used to prevent the scheduler  ;
        ;  from running.  This performs similar to disabling    ;
        ;  interrupts, except only the scheduler is disabled.   ;
        ;                                                       ;
        ;.......................................................;

disableSched    proc far

        inc word ptr cs:[ insideDos ]
        ret

disableSched    endp

        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  enableInts()                                         ;
        ;- - - - - - - - - - - - - - - - - - - - - - - - - - - -;
        ;                                                       ;
        ;  Enables interrupts for C programs.                   ;
        ;                                                       ;
        ;.......................................................;

enableInts      proc far

        sti
        ret

enableInts      endp

        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  disableInts()                                        ;
        ;- - - - - - - - - - - - - - - - - - - - - - - - - - - -;
        ;                                                       ;
        ;  Disables interrupts for C programs.                  ;
        ;                                                       ;
        ;.......................................................;

disableInts     proc far

        pushf
        pop ax                                  ;copy flags to ax.
        and ax,_flags_if
        jz disableInts_08                       ;if ints were disabled -->
        mov ax,1                                ;if ints are enabled.

disableInts_08: 
        cli
        ret

disableInts     endp

        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  condenableInts()                                     ;
        ;- - - - - - - - - - - - - - - - - - - - - - - - - - - -;
        ;                                                       ;
        ;  Conditional enables interrupts.  Use disableInts to  ;
        ;  disable interrupts.  This is a convenience function. ;
        ;                                                       ;
        ;.......................................................;

    entry condenableInts                        ;emulates Pascal conventions
                                                ; <must have them in rev stack order>
        iarg  __condition                        ; int previous status

        getarg ax, __condition
        or ax,ax
        jz condenableInts_08
        sti

condenableInts_08:
        return pascal

condenableInts  endp

        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  setClockInterrupt                                    ;
        ;- - - - - - - - - - - - - - - - - - - - - - - - - - - -;
        ;                                                       ;
        ;  call with long argument on stack.                    ;
        ;                                                       ;
        ;  argument will have value of clock when the clock     ;
        ;  isr will call scheduler.                             ;
        ;                                                       ;
        ;  push ax                    ;least signif word        ;
        ;  push dx                    ;most signif word         ;
        ;  call setClockInterrupt                               ;
        ;                                                       ;
        ;.......................................................;

    entry setClockInterrupt                     ;emulates Pascal conventions
	darg __argument                         ; void far * argument,

        getdarg dx,ax,__argument

        mov word ptr cs:[ _ClockArmValue + 2 ], dx
        mov word ptr cs:[ _ClockArmValue ], ax
        return pascal

setClockInterrupt       endp

        ;'int 08'''''''''''''''''''''''''''''''''''''''''''''''';
        ;  TimerTick                                            ;
        ;- - - - - - - - - - - - - - - - - - - - - - - - - - - -;
        ;                                                       ;
        ;  This ISR is called every clock tick (int 08)         ;
        ;  If the current clock value at interrupt equals or    ;
        ;  passes the next required clock value, the scheduler  ;
        ;  is called to determine what action is required next. ;
        ;                                                       ;
        ;.......................................................;

TimerTick       proc far

        push ax
        push bx
        push dx
        push ds

        _Int _originalTickInt                   ;emulate int call
        inc word ptr cs:[ total_ints ]

;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;  see if min timer value expired.
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        mov ax,40h
        mov ds,ax
        mov bx, 6Ch

        mov ax,word ptr [ bx ]
        mov dx,word ptr [ bx + 2 ]

        push cs
        pop ds                                  ; set ds to current.
        sub ax,word ptr [ _ClockArmValue ]
        sbb dx,word ptr [ _ClockArmValue + 2 ]
        jg TimerTick_40

        sti
        xor ax,ax
        mov word ptr [ _ClockArmValue ],ax
        mov word ptr [ _ClockArmValue + 2 ],ax

	SaveRegisters
        mov ds, word ptr cs:[Rtx_DataSegment]
	call rtx_text:countDown_Timers          ;see if timers elapsed
        call scheduler                          ;see if task time slice 
        RestoreRegisters

TimerTick_40:
        pop ds
        pop dx
        pop bx
        pop ax

        iret

TimerTick       endp

        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  restore_IntTraps()                                   ;
        ;- - - - - - - - - - - - - - - - - - - - - - - - - - - -;
        ;                                                       ;
        ;  Restores interrupt traps before exit.                ;
        ;                                                       ;
        ;.......................................................;

restore_IntTraps proc far

        lds dx,dword ptr cs:[_originalDosTrap]
        callDos SetIntVector, 21h               ;restore vector to Int21.

        lds dx,dword ptr cs:[_originalKbdHdwTrap]
        callDos SetIntVector, 09h

        lds dx,dword ptr cs:[_originalScrnTrap]
        callDos SetIntVector, 10h

        lds dx,dword ptr cs:[_originalKbdSvcTrap]
        callDos SetIntVector, 16h

	lds dx,dword ptr cs:[_originalTickInt]
	callDos SetIntVector, 08h

	lds dx,dword ptr cs:[_originalCOM1Int]
	callDos SetIntVector, 0Ch

	lds dx,dword ptr cs:[_originalCOM2Int]
	callDos SetIntVector, 0Bh

	ret
restore_IntTraps endp    

        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  Int21()                                              ;
        ;- - - - - - - - - - - - - - - - - - - - - - - - - - - -;
        ;                                                       ;
        ;  Int 21 traps to here.  We can detect DMA address     ;
        ;  change, terminate process, and whether we are        ;
        ;  entering/exiting DOS.                                ;
        ;                                                       ;
        ;.......................................................;

Int21   proc far

        cmp ah,ExitProgram
        jz Int21_12
        cmp ah,TerminateProcess
        jnz Int21_20

Int21_12:
        push ax                                 ;save return code.

        lds dx,dword ptr cs:[_originalDosTrap]
        callDos SetIntVector, 21h               ;restore vector to Int21.
        call restore_IntTraps
        pop ax

Int21_20:
        _Int _originalDosTrap                   ;emulate int call
        ret 2                                   ;pass through our own status.

Int21   endp

        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  Int16()                                              ;
        ;- - - - - - - - - - - - - - - - - - - - - - - - - - - -;
        ;                                                       ;
        ;  Int 16 is used to read the keyboard.  It needs to    ;
        ;  trap to a waitKbdEvent() function which sets the     ;
        ;  KBD event flag in the current task and exits to the  ;
        ;  scheduler.                                           ;
        ;                                                       ;
        ;.......................................................;

Int16   proc far
        or ah,ah                                ;is it a keyboard wait call ?
        jnz Int16_22                            ;no, go ahead and execute -->

	SaveRegisters
        mov ah,1
        int 16h                                 ;we'll call ourselves
        jnz Int16_20                            ;if key available, no need waiting -->

        mov ds, word ptr cs:[Rtx_DataSegment]
	call rtx_text:waitKbdEvent              ;wait on kbd event.

Int16_20:
        RestoreRegisters

Int16_22:
	_Int _originalKbdSvcTrap
	ret 2                                   ;pass through our own status.
Int16   endp

        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  Int09()                                              ;
        ;- - - - - - - - - - - - - - - - - - - - - - - - - - - -;
        ;                                                       ;
        ;  Int 09 is the keyboard interrupt.  If a key is       ;
        ;  detected and saved by the ROM BIOS it will force     ;
	;  the setKbdEvent. Then exit thru Scheduler.           ;
	;                                                       ;
	;.......................................................;

Int09   proc far

	_Int _originalKbdHdwTrap                ;do normal kbd duties.

	push ax
	push bx
	push ds
	mov ax,40h
	mov ds,ax                               ;look at bios kbd area
	mov bx,1Ah

	cli
	mov ax,word ptr [ bx ]                  ; 1Ah
	cmp ax,word ptr [ bx + 2 ]              ; 1Ch
	sti
	jz Int09_20                             ; if zero, no keys pending ->

	SaveRegisters
	mov ds, word ptr cs:[Rtx_DataSegment]
	call rtx_text:setKbdEvent              ;say keyboard event occourred.
	call scheduler
	RestoreRegisters

Int09_20:
	pop ds
	pop bx
	pop ax

	iret
Int09   endp

	;''''''''''''''''''''''''''''''''''''''''''''''''''''''';
	;  KeyboardEventFct                                     ;
	;- - - - - - - - - - - - - - - - - - - - - - - - - - - -;
	;                                                       ;
	;  Sample of an event fct.  This returns true (non-zero);
	;  when keyboard data is available; false (zero) when no;
	;  keyboard data is available.                          ;
	;                                                       ;
	;.......................................................;

    entry keyboardEventFct                      ;emulates Pascal conventions
						; <must have them in rev stack order>
	darg __argument                         ; void far * argument,
	iarg  __event_id                         ; event event_id

	push bx
	push ds
	mov ax,40h
	mov ds,ax                               ;look at bios kbd area
	mov bx,1Ah

	cli
	mov ax,word ptr [ bx ]                  ; 1Ah
	cmp ax,word ptr [ bx + 2 ]              ; 1Ch
	sti

	mov ax, 0                               ;false if no input available.
	jz keyboardEventFct_08                  ; if zero, no keys pending ->

	mov ax, 1                               ;true if input available.

keyboardEventFct_08:
	pop ds
	pop bx
	return pascal

keyboardEventFct  endp

	;''''''''''''''''''''''''''''''''''''''''''''''''''''''';
	;  Int10()                                              ;
	;- - - - - - - - - - - - - - - - - - - - - - - - - - - -;
	;                                                       ;
	;  This would handle any program to Int 10 calls.  There;
	;  are no screen special considerations unless you need ;
	;  to support different windows per task.               ;
	;                                                       ;
	;.......................................................;

Int10   proc

	_Int _originalScrnTrap

	iret
Int10   endp


	;''''''''''''''''''''''''''''''''''''''''''''''''''''''';
	;  COM port ISRs                                        ;
	;- - - - - - - - - - - - - - - - - - - - - - - - - - - -;
	;                                                       ;
	;  Trap send & receive interrupts for serial lines.     ;
	;                                                       ;
	;.......................................................;

COM1	proc   far

	SaveRegisters
	mov ds, word ptr cs:[Rtx_DataSegment]
	call rtx_text:comAck

	call com_ISR_odd

	;call rtx_text:comPutChar1
	RestoreRegisters
	iret
COM1    endp
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

COM2	proc   far

	SaveRegisters
	mov ds, word ptr cs:[Rtx_DataSegment]
	call rtx_text:comAck

	call com_ISR_even

	;call rtx_text:comPutChar1
	RestoreRegisters
	iret
COM2    endp



	;''''''''''''''''''''''''''''''''''''''''''''''''''''''';
	;  init_IntTraps()                                      ;
	;- - - - - - - - - - - - - - - - - - - - - - - - - - - -;
	;                                                       ;
	;  Init int traps for whole system.  Called by          ;
	;  initTaskSystem().                                    ;
	;                                                       ;
	;.......................................................;

init_IntTraps   proc far

	saveSegments
	mov word ptr cs:[Rtx_DataSegment], ds

	push cs
	pop ds

	setIntTrap      09h, Int09,     _originalKbdHdwTrap
	setIntTrap	0Ch, COM1,	_originalCOM1Int
	setIntTrap	0Bh, COM2,	_originalCOM2Int
	setIntTrap      10h, Int10,     _originalScrnTrap
	setIntTrap      16h, Int16,     _originalKbdSvcTrap
        setIntTrap      08h, TimerTick, _originalTickInt
        setIntTrap      21h, Int21,     _originalDosTrap

        mov word ptr [insideDos],0000
        restoreSegments
        ret
init_IntTraps   endp

reg_supp 	ends

        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  temporary stack                                      ;
        ;.......................................................;

t_stack         segment para 'DATA'
                dw 2000 dup( 0 )
temp_stack      dd 0
t_stack         ends

        end


