summaryrefslogtreecommitdiff
path: root/libc/msdos/intr.c
blob: 22de04239da24e6df6a96701f985691c72a9eaa7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82

struct REGPACK
{
   unsigned r_ax, r_bx, r_cx, r_dx;
   unsigned r_bp, r_si, r_di, r_ds, r_es, r_flags;
};

/* DANGER DANGER -- Self modifying code! */

#asm
.text
save_sp:
  dw	0
#endasm

intr(intr, regs)
int intr;
struct REGPACK * regs;
{
#asm
  mov	bx,sp
  push	bp
  push	si
  push	di
  push	es
  push	ds

  mov	ax,[bx+2]
  seg	cs
  mov	[intr_inst+1],al
  seg	cs
  mov	[save_sp],sp

  mov	bx,[bx+4]

  mov	ah,[bx+18]	! Flags low byte
  sahf 

  mov	ax,[bx]
  push	[bx+2]
  mov	cx,[bx+4]
  mov	dx,[bx+6]
  mov	bp,[bx+8]
  mov	si,[bx+10]
  mov	di,[bx+12]
  mov	es,[bx+16]
  mov	ds,[bx+14]
  pop	bx

intr_inst:
  int	$FF		! Must be a real int .. consider protected mode.

  seg	cs		! Could be SS as DS==SS
  mov	sp,[save_sp]
  seg	cs
  mov	[save_sp],ds
  pop	ds
  push	[save_sp]

  push	bx
  mov	bx,sp
  mov	bx,[bx+12]

  mov	[bx],ax
  pop	[bx+2]
  mov	[bx+4],cx
  mov	[bx+6],dx 
  mov	[bx+8],bp
  mov	[bx+10],si
  mov	[bx+12],di
  pop	[bx+14]
  mov	[bx+16],es
  pushf
  pop	[bx+18]

  pop	es
  pop	di
  pop	si
  pop	bp
  
#endasm
}