209 lines
4.0 KiB
Plaintext
209 lines
4.0 KiB
Plaintext
/
|
|
/ Lets C Version 4.0.C.
|
|
/ Copyright (c) 1982-1987 by Mark Williams Company, Chicago.
|
|
/ All rights reserved. May not be copied or disclosed without permission.
|
|
/
|
|
|
|
/*
|
|
* intdis.m
|
|
* Assembly language interrupt dispatcher.
|
|
* Works in either LARGE or SMALL model.
|
|
* See also: int.c, example.c.
|
|
*/
|
|
|
|
#if LARGE
|
|
#define LARGECODE 1
|
|
#define LARGEDATA 1
|
|
#endif
|
|
|
|
/*
|
|
* The following byte size parameters are used to determine the
|
|
* actual offsets for the members of the structure INTINFO, which
|
|
* is defined in int.c, independent of the data model LARGE or SMALL.
|
|
*/
|
|
#define INTSIZE 2
|
|
|
|
#if LARGEDATA
|
|
#define PTRSIZE 4
|
|
#else
|
|
#define PTRSIZE 2
|
|
#endif
|
|
|
|
/*
|
|
* The following are used to get the correct 8086 mnemonics, independent
|
|
* of the execution model LARGE or SMALL.
|
|
*/
|
|
#if LARGECODE
|
|
#define Gicall xicall
|
|
#define Gret xret
|
|
#else
|
|
#define Gicall icall
|
|
#define Gret ret
|
|
#endif
|
|
|
|
|
|
.shri
|
|
|
|
.globl intdis1_ / Interrupt entry points
|
|
.globl intdis2_
|
|
.globl intdis3_
|
|
.globl intdis4_
|
|
.globl intdis5_
|
|
.globl intdis6_
|
|
.globl intdis7_
|
|
.globl intdis8_
|
|
.globl intdis9_
|
|
.globl intdis10_
|
|
.globl intdis11_
|
|
.globl intdis12_
|
|
.globl intdis13_
|
|
.globl intdis14_
|
|
.globl intdis15_
|
|
.globl intdis16_
|
|
|
|
iisize = 5*PTRSIZE + 4*INTSIZE / sizeof(struct INTINFO)
|
|
i_cfunc = 0 / Member offsets in intinfo
|
|
i_stacksize = PTRSIZE
|
|
i_oldoff = 2*PTRSIZE + 2*INTSIZE
|
|
i_stack = 2*PTRSIZE + 4*INTSIZE
|
|
i_curstack = 3*PTRSIZE + 4*INTSIZE
|
|
i_endstack = 4*PTRSIZE + 4*INTSIZE
|
|
|
|
.globl intinfo_ / External references
|
|
.globl isover_
|
|
|
|
.globl cli_ / External definitions
|
|
.globl sti_
|
|
|
|
cli_:
|
|
cli
|
|
Gret
|
|
sti_:
|
|
sti
|
|
Gret
|
|
|
|
intdis1_: / Entry points
|
|
push bx
|
|
mov bx, $0 * iisize
|
|
jmp dispatch
|
|
intdis2_:
|
|
push bx
|
|
mov bx, $1 * iisize
|
|
jmp dispatch
|
|
intdis3_:
|
|
push bx
|
|
mov bx, $2 * iisize
|
|
jmp dispatch
|
|
intdis4_:
|
|
push bx
|
|
mov bx, $3 * iisize
|
|
jmp dispatch
|
|
intdis5_:
|
|
push bx
|
|
mov bx, $4 * iisize
|
|
jmp dispatch
|
|
intdis6_:
|
|
push bx
|
|
mov bx, $5 * iisize
|
|
jmp dispatch
|
|
intdis7_:
|
|
push bx
|
|
mov bx, $6 * iisize
|
|
jmp dispatch
|
|
intdis8_:
|
|
push bx
|
|
mov bx, $7 * iisize
|
|
jmp dispatch
|
|
intdis9_:
|
|
push bx
|
|
mov bx, $8 * iisize
|
|
jmp dispatch
|
|
intdis10_:
|
|
push bx
|
|
mov bx, $9 * iisize
|
|
jmp dispatch
|
|
intdis11_:
|
|
push bx
|
|
mov bx, $10 * iisize
|
|
jmp dispatch
|
|
intdis12_:
|
|
push bx
|
|
mov bx, $11 * iisize
|
|
jmp dispatch
|
|
intdis13_:
|
|
push bx
|
|
mov bx, $12 * iisize
|
|
jmp dispatch
|
|
intdis14_:
|
|
push bx
|
|
mov bx, $13 * iisize
|
|
jmp dispatch
|
|
intdis15_:
|
|
push bx
|
|
mov bx, $14 * iisize
|
|
jmp dispatch
|
|
intdis16_:
|
|
push bx
|
|
mov bx, $15 * iisize
|
|
dispatch:
|
|
push ax / Save machine state
|
|
push cx
|
|
push dx
|
|
push ds
|
|
push es
|
|
mov cx, ss
|
|
mov dx, sp
|
|
mov ax, $@intinfo_ / Segment of intinfo[]
|
|
mov ds, ax / for data references
|
|
mov es, ax
|
|
|
|
/*
|
|
* The following is used to load the SS and SP registers to the
|
|
* correct value for the interrupt processing routine. With
|
|
* LARGEDATA model, we must get SS from the intinfo[]; otherwise,
|
|
* simply set it the same as DS and ES.
|
|
*/
|
|
#if LARGEDATA
|
|
mov ss, intinfo_+INTSIZE+i_curstack(bx)
|
|
#else
|
|
mov ss, ax
|
|
#endif
|
|
mov sp, intinfo_+i_curstack(bx)
|
|
|
|
mov ax, sp
|
|
cmp ax, intinfo_+i_stack(bx) / Nesting overflow check
|
|
je overflow
|
|
sub ax, intinfo_+i_stacksize(bx) / Make room on stack
|
|
mov intinfo_+i_curstack(bx), ax
|
|
push dx
|
|
push cx
|
|
push bx
|
|
Gicall intinfo_+i_cfunc(bx) / Call C routine
|
|
pop bx / Pop intinfo offset
|
|
pop cx / Pop old ss, sp
|
|
pop dx
|
|
test ax, ax / Call old interrupt?
|
|
jz done / No
|
|
pushf / Simulate int to old function
|
|
mov ax, $@intinfo_ / Segment of intinfo[]
|
|
mov ds, ax / for data reference
|
|
xicall intinfo_+i_oldoff(bx) / Indirect intersegment call
|
|
done:
|
|
mov ax, $@intinfo_ / Segment of intinfo[]
|
|
mov ds, ax / for data reference
|
|
mov intinfo_+i_curstack(bx), sp / Deallocate stack
|
|
mov ss, cx / Restore machine state
|
|
mov sp, dx
|
|
pop es
|
|
pop ds
|
|
pop dx
|
|
pop cx
|
|
pop ax
|
|
pop bx
|
|
iret
|
|
overflow:
|
|
mov sp, intinfo_+i_endstack(bx)
|
|
call isover_ / Nesting overflow
|
|
death:
|
|
jmp death
|