-
Notifications
You must be signed in to change notification settings - Fork 6
/
HASPDRV.INC
202 lines (168 loc) · 6.96 KB
/
HASPDRV.INC
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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
;
; HASP DOS driver, main routine
;
; (c) [email protected] 03/2022
;
; For this device driver to work i.e. in DosBox-X, you have to set
; DOS version number to 5.50 so that HASP thinks that it is running on
; Windows NTVDM
;
title HASP DOS driver
;****************************************************************
;* INSTRUCTING THE ASSEMBLER *
;****************************************************************
cseg segment para public 'code'
hasp proc far
assume cs:cseg, es:cseg, ds:cseg
include haspstr.inc
;****************************************************************
;* MAIN PROCEDURE CODE *
;****************************************************************
begin:
;****************************************************************
;* DEVICE HEADER REQUIRED BY DOS *
;****************************************************************
next_dev dd -1 ;no other drivers following
attribute dw 0C840h ;logical devices,open/close/RM
;IOCTL, character device
strategy dw dev_strategy ;Strategy routine address
interrupt dw dev_interrupt ;Interrupt routine address
dev_name db 'HASPDOSDRV' ;name of our driver
;****************************************************************
;* WORK SPACE FOR OUR DEVICE DRIVER *
;****************************************************************
rh_ofs dw ? ;offset address of the request header
rh_seg dw ? ;segment address of the request header
old_int2Fh_ofs dw ? ;offset address of old INT 2F handler
old_int2Fh_seg dw ? ;segment address of old INT 2F handler
;CMDTAB is the command table that contains the word address
;for each command. The request header will contain the
;command desired. The INTERRUPT routine will jump through an
;address corresponding to the requested command to get to
;the appropriate command processing routine.
CMDTAB label byte ;* = char devices only
dw INITIALIZATION ; initialization
dw REPLY_0 ; media check (block only)
dw REPLY_0 ; build bpb
dw REPLY_0 ; ioctl in
dw INPUT ; input (read)
dw REPLY_0 ;*non destructive input no wait
dw REPLY_0 ;*input status
dw REPLY_0 ;*input flush
dw REPLY_0 ; output (write)
dw REPLY_0 ; output (write) with verify
dw REPLY_0 ;*output status
dw REPLY_0 ;*output flush
dw REPLY_0 ; ioctl output
dw OPEN ; device open
dw CLOSE ; device close
dw REPLY_0 ; removeable media
dw REPLY_0 ; output til busy
dw REPLY_8003 ; command 17
dw REPLY_8003 ; command 18
dw REPLY_0 ; generic IOCTL
dw REPLY_8003 ; command 20
dw REPLY_8003 ; command 21
dw REPLY_8003 ; command 22
dw REPLY_0 ; get device
dw REPLY_0 ; set device
;****************************************************************
;* THE STRATEGY PROCEDURE *
;****************************************************************
dev_strategy: mov cs:rh_ofs,bx ;save the offset address
mov cs:rh_seg,es ;save the segment address
ret ;return to DOS
;****************************************************************
;* THE INTERRUPT PROCEDURE *
;****************************************************************
;device interrupt handler - 2nd call from DOS
dev_interrupt:
push ax ;save machine state on entry
push bx
push cx
push dx
push ds
push es
push di
push si
push bp
push cs
pop ds
les di, dword ptr rh_ofs
;jump to appropriate routine to process command
mov bl,es:[di].rh_cmd ;get request header header command
xor bh, bh
cmp bx, 18h ;index above table limits?
jle make_call
jmp unk_cmd
make_call:
shl bx,1 ;times 2 for index into word table
call word ptr cmdtab[bx]
les di, dword ptr rh_ofs
done: or ax ,0100h ;set done
mov es:[di].rh_status, ax
pop bp ;restore all registers
pop si
pop di
pop es
pop ds
pop dx
pop cx
pop bx
pop ax
ret ;return to DOS
unk_cmd:
mov ax, 8003h ;set error bit and error code
jmp done ;set done and exit
;****************************************************************
;* YOUR LOCAL PROCEDURES *
;****************************************************************
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; Return success
;
REPLY_0 proc near
xor ax, ax ;return 0
ret ;return to caller
REPLY_0 endp ;end of tone
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; Return not implemented
;
REPLY_8003 proc near
mov ax, 8003h
ret ;return to caller
REPLY_8003 endp ;end of tone
;****************************************************************
;* DOS COMMAND PROCESSING *
;****************************************************************
;
; The Interrupt 2F handler for call 5000h
;
int_2f_handler:
cmp ax, 5000h
jz handle_hasp
jmp dword ptr cs:old_int2fh_ofs
handle_hasp:
mov ax, 192h
mov bx, 4553h
mov cx, 4143h
mov dx, 4950h
iret
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; Init routine
;
INITIALIZATION proc near
push es
lea ax,initial ;set Break Addr. at initial
mov es:[di].rh0_brk_ofs,ax ;store offset address
mov es:[di].rh0_brk_seg,cs ;store segment address
mov ax, 352Fh ;get INT 2f interrupt vector
int 21h
mov cs:old_int2Fh_ofs,bx
mov cs:old_int2Fh_seg,es
mov ah, 25h ; install new INT 2f handler
mov dx, offset int_2f_handler
int 21h
call initial ;display message
pop es
ret
INITIALIZATION endp