dos_compilers/Mark Williams MWC v4/SAMPLE/INTDIS.M
2024-07-01 16:08:53 -07:00

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