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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
|
/**
* Operating Systems
* Mod 6
* Averill and Ben
* Writing awesome printer stuff.
*/
#include <dos.h>
#include <stdio.h>
#include "mpx.h";
void interrupt (*vect0f)();
int prt_opened;
int prt_open(int * prt_flag) {
unsigned char imr;
disable();
if (prt_opened == NULL || prt_opened == 0) {
prt_opened = 1;
} else {
return -2;
}
// set up vector interrupt
vect0f = getvect(0x0f);
setvect(0x0f, &prt_int);
// enable printer interrupts on 8259
imr = inportb(IMR);
imr = imr & 0x7f; //0111-1111
outportb(IMR, imr);
// clear init bit (b2), set select bit (b3)
// 0000 1010
outportb(PCR, 0x0a);
// initialize a printer control block
prt.current_op = NO_OP;
prt.event_flag = prt_flag;
prt.count = 0;
enable();
return 0;
}
int prt_write(char far *buffer, int far *length) {
disable();
// check that prt isn't busy
if (prt.current_op != NO_OP) {
return -2;
}
// check that length is valid
if (*length < 1) {
return -3;
}
//save buffer and length in prt dcb
prt.buffer = buffer;
prt.length = length;
prt.current_op = WRITE_OP;
prt.count = 0;
// enable printer interrupts on PCR
// 0001 1010
outportb(PCR, 0x1a);
// strobe printer
// 0001 1011
outportb(PCR, 0x1d);
// print a null
// NOTE: something is not right here because when i print something
// other than a null it still doesn't print
outportb(PDR, 0x00);
// unstrobe printer
// 0001 1010
outportb(PCR, 0x1c);
enable();
return 0;
}
int prt_close() {
unsigned char imr;
disable();
// reset printer
// set init bit (b2) to 1 all else clear
// 0000 0100
outportb(PCR, 0x04);
//disable printer interrupts
imr = inportb(IMR);
imr = imr | 0x80;
outportb(IMR, imr);
// restore ms-dos's printer interrupt vector
setvect(0x0f, vect0f);
enable();
return 0;
}
void interrupt prt_int() {
unsigned char pcr;
int *lst_stk;
disable();
lst_stk = _BP;
// if no more char to write
if (prt.count == *(prt.length)) {
// disable printer interrupts at PCR
// clear b4 on PCR
pcr = inportb(PCR);
pcr = pcr & 0xef; // 1110-1111
outportb(PCR, pcr);
// set event flag
prt.current_op = NO_OP;
*(prt.event_flag) = 1;
// call io-complete
IO_complete(PRT, lst_stk);
// send end of interrupt signal
outportb(0x20, 0x20);
} else {
// strobe printer
// 0001 1101
outportb(PCR, 0x1d);
// write char to PDR
outportb(PDR, prt.buffer[prt.count]);
prt.count++;
// unstrobe printer
// 0001 1100
outportb(PCR, 0x1c);
}
// send EOI
outportb(0x20, 0x20);
enable();
}
|