-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathOX2.ASM
454 lines (396 loc) · 14 KB
/
OX2.ASM
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
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
TITLE AUX Monochrome Device Driver for OS/2
PAGE 60, 132
COMMENT +
File: OX2.ASM
File type: Microsoft Macro Assembler (MASM) Version 5.1 or higher
Author: JWC (parts by Mike Geary)
Date: June, 1989
Purpose:
This device directs AUX output to the monochrome display under OS/2.
This driver is in the public domain. If you find it useful,
how about returning the favor and putting some of your own
favorite utilities in the public domain, too?
(***with source code!!!***)
+
.286c
.sall
DATA SEGMENT WORD PUBLIC 'DATA'
SUBTTL Device Driver Header
PAGE +
; ***********************************************************************
; * DEVICE HEADER *
; ***********************************************************************
PtrToNextHeader dd 0FFFFFFFFh ; Indicates loadable device driver
DeviceAttribute dw 1000100010000000b
; Bit 15 - Character device
; Bit 11 - Supports Open/Close
; Bits 9-7 - OS/2 device driver
StrategyOffset dw CODE:Strategy ; Offset to the Strategy routine
IDCOffset dw -1 ; unused--must be -1
DeviceName db 'AUX ' ; Name of the device
ReservedBlock2 db 8 dup (0) ; Reserved words
; ***********************************************************************
; * DEVHLP SUPPORT *
; ***********************************************************************
.XLIST
;
; These constants define the DevHlp commands:
;
;DevHlp_SchedClockAddr EQU 0 ; 0h Get system clock routine
;DevHlp_DevDone EQU 1 ; 1h Device I/O Complete
;DevHlp_Yield EQU 2 ; 2h Yield the CPU
;DevHlp_TCYield EQU 3 ; 3h Yield the CPU to time-critical
;DevHlp_Block EQU 4 ; 4h Block thread on event
;DevHlp_Run EQU 5 ; 5h Unblock thread
;DevHlp_SemRequest EQU 6 ; 6h Claim a semaphore
;DevHlp_SemClear EQU 7 ; 7h Release a semaphore
;DevHlp_SemHandle EQU 8 ; 8h Get a semaphore handle
;DevHlp_PushReqPacket EQU 9 ; 9h Add request to list
;DevHlp_PullReqPacket EQU 10 ; Ah Remove request from list
;DevHlp_PullParticular EQU 11 ; Bh Remove a specific request from list
;DevHlp_SortReqPacket EQU 12 ; Ch Insert request in sorted order to list
;DevHlp_AllocReqPacket EQU 13 ; Dh Get a request packet
;DevHlp_FreeReqPacket EQU 14 ; Eh Free request packet
;DevHlp_QueueInit EQU 15 ; Fh Initialize character queue
;DevHlp_QueueFlush EQU 16 ;10h Clear character queue
;DevHlp_QueueWrite EQU 17 ;11h Put a char in the queue
;DevHlp_QueueRead EQU 18 ;12h Get a char from the queue
;DevHlp_Lock EQU 19 ;13h Lock segment
;DevHlp_Unlock EQU 20 ;14h Unlock segment
DevHlp_PhysToVirt EQU 21 ;15h Map physical address to virtual
DevHlp_VirtToPhys EQU 22 ;16h Map virtual-to-physical address
;DevHlp_PhysToUVirt EQU 23 ;17h Map physical-to-user virtual
;DevHlp_AllocPhys EQU 24 ;18h Allocate physical memory
;DevHlp_FreePhys EQU 25 ;19h Free physical memory
;DevHlp_SetROMVector EQU 26 ;1Ah Set software interrupt vector
;DevHlp_SetIRQ EQU 27 ;1Bh Set a hardware interrupt handler
;DevHlp_UnSetIRQ EQU 28 ;1Ch Reset a hardware interrupt handler
;DevHlp_SetTimer EQU 29 ;1Dh Set timer request handler
;DevHlp_ResetTimer EQU 30 ;1Eh Remove a timer handler
;DevHlp_MonitorCreate EQU 31 ;1Fh Create a monitor
;DevHlp_Register EQU 32 ;20h Install a monitor
;DevHlp_DeRegister EQU 33 ;21h Remove a monitor
;DevHlp_MonWrite EQU 34 ;22h Pass data records to monitor
;DevHlp_MonFlush EQU 35 ;23h Remove all data from stream
;DevHlp_GetDOSVar EQU 36 ;24h Return pointer to DOS variable
;DevHlp_SendEvent EQU 37 ;25h Indicate an event
;DevHlp_ROMCritSection EQU 38 ;26h ROM BIOS critical section
;DevHlp_VerifyAccess EQU 39 ;27h Verify access to memory
DevHlp_AllocGDTSelector EQU 45 ;2Dh Allocate GDT selectors
DevHlp_PhysToGDTSelector EQU 46 ;2Eh Map physical to virtual address
;DevHlp_RealToProt EQU 47 ;2Fh Real Mode to Protect Mode
;DevHlp_ProtToReal EQU 48 ;30h Protect Mode to Real Mode
;DevHlp_EOI EQU 49 ;31h Issue an End-Of-Interrupt
DevHlp_UnPhysToVirt EQU 50 ;32h Mark PhysToVirt complete
;DevHlp_TickCount EQU 51 ;33h Modify timer
;DevHlp_GetLIDEntry EQU 52 ;34h Get Logical ID
;DevHlp_FreeLIDEntry EQU 53 ;35h Release Logical ID
;DevHlp_ABIOSCall EQU 54 ;36h Invoke ABIOS function
;DevHlp_ABIOSCommonEntry EQU 55 ;37h Invoke ABIOS Common Entry Point
;
; This macro simplifies calling a DevHlp service by doing a load of the
; function code into DL and calling pfnDevHlp.
;
@DevHlp MACRO name
mov dl, DevHlp_&name
call pfnDevHlp
ENDM
.LIST
SUBTTL Structures/Codes for Request Packets
PAGE +
; ***********************************************************************
; * REQUEST PACKET STRUCTURE *
; ***********************************************************************
PKTMAX EQU 18 ; Maximum size of packet
PacketStruc STRUC
PktLen db ? ; Length in bytes of packet
PktUnit db ? ; Subunit number of block device
PktCmd db ? ; Command code
PktStatus dw ? ; Status word
PktDOSLink dd ? ; Reserved
PktDevLink dd ? ; Device multiple-request link
PktData db PKTMAX dup (?) ; Data pertaining to specific packet
PacketStruc ENDS
; ***********************************************************************
; * CODES FOR STATUS OF REQUEST PACKET *
; ***********************************************************************
; Bit positions in Status field:
StatRecord RECORD StatError:1,StatDevError:1,StatRes:4,StatBusy:1,\
StatDone:1,StatErrCode:8
; Error Codes:
StatWrProtVio EQU 00h ; WRITE PROTECT VIOLATION
StatUnknownCmd EQU 03h ; UNKNOWN COMMAND
StatGenFailure EQU 0Ch ; GENERAL FAILURE
StatCharIOIntd EQU 11h ; CHARACTER I/O INTERRUPTED
StatMonNotSupp EQU 12h ; MONITORS NOT SUPPORTED
; ***********************************************************************
; * POINTER CONSTANTS FOR REQUEST PACKET *
; ***********************************************************************
Packet EQU ES:[BX]
; INIT arguments:
InitpEnd EQU DWORD PTR PktData+1 ; Pointer to freemem after dev
IOpData EQU DWORD PTR PktData+1 ; Transfer address
IOcount EQU WORD PTR PktData+5 ; Count of bytes/sectors
InitArgs EQU DWORD PTR PktData+5 ; Pointer to CONFIG.SYS args
; ***********************************************************************
; * DATA USED BY THE STRATEGY ROUTINE *
; ***********************************************************************
pfnDevHlp dd ? ; Holds address of the DevHlp function entry
fbError db 0 ; Error flag used to signal to the Strategy
; routine a return with error from another
; subroutine.
SCRMINOFF EQU 160*24
SCRMAXOFF EQU 160*25
ptrMonoMem LABEL DWORD
offMonoMem dw SCRMINOFF
selMonoMem dw ?
BS EQU 08h
TAB EQU 09h
LF EQU 0Ah
CR EQU 0Dh
; ***********************************************************************
; * A call table is set up to call a particular subroutine depending on *
; * the command code field within the request packet. *
; * The table of offsets must be stored in the data segment. *
; ***********************************************************************
StrategyFuncTable dw INIT ; 0 INIT
dw BadCommand ; 1 MEDIA CHECK - N/A
dw BadCommand ; 2 BUILD BPB - N/A
dw BadCommand ; 3 reserved
dw BadCommand ; 4 READ (input) - N/A
dw BadCommand ; 5 NONDES READ NO WAIT - N/A
dw BadCommand ; 6 INPUT STATUS - N/A
dw BadCommand ; 7 INPUT FLUSH - N/A
dw WRITE ; 8 WRITE (output)
dw WRITE ; 9 WRITE WITH VERIFY - N/A
dw STATUS ; A OUTPUT STATUS
dw FLUSH ; B OUTPUT FLUSH
dw BadCommand ; C Reserved
dw OPEN ; D DEVICE OPEN
dw CLOSE ; E DEVICE CLOSE
dw BadCommand ; F REMOVABLE MEDIA - N/A
dw BadCommand ; 10 GENERIC IOCtl - N/A
dw BadCommand ; 11 RESET MEDIA - N/A
dw BadCommand ; 12 GET LOGICAL DRIVE MAP - N/A
dw BadCommand ; 13 SET LOGICAL DRIVE MAP - N/A
dw BadCommand ; 14 DEINSTALL - N/A
MaxCommandCode EQU (($-StrategyFuncTable) / 2) - 1
END_OF_DATA EQU $
DATA ENDS
CODE SEGMENT WORD PUBLIC 'CODE'
ASSUME CS:CODE, DS:DATA, ES:NOTHING
; ***********************************************************************
; * STRATEGY ROUTINE *
; * *
; * Far procedure Strategy gets the request packet and based on its *
; * command code branches to the appropriate subroutine. Upon return *
; * from the subroutine, the request is signalled serviced with or *
; * without error. *
; ***********************************************************************
Strategy PROC FAR
push es ; save the pointers to the request packet
push bx
mov al, BYTE PTR Packet.PktCmd
; Command code is moved into al
cmp al, MaxCommandCode
; If index larger than those supported
ja UNSUPPORTED ; Jump to indicate that the command is
; unsupported
cbw ; Byte in al is converted to word
mov di, ax ; It is then moved to di
shl di, 1 ; Converted to an index
mov fbError, 0 ; Zero out the fbError flag prior to the call
call WORD PTR StrategyFuncTable[di]
; Jump to appropriate offset
pop bx ; Restore the pointers to the request packet
pop es
cmp fbError, 0 ; Upon return, check if subroutine returned
; an error
jz ERROR_FREE ; If no error, jump to signal devdone
or Packet.PktStatus, MASK StatError + StatGenFailure
; Set the error condition in the Req Packet
; Set the error to General Failure
ERROR_FREE:
or Packet.PktStatus, MASK StatDone
jmp FIN
UNSUPPORTED:
pop bx ; Retrieve the pushed values of bx and es
pop es
call BadCommand
FIN:
ret
Strategy ENDP
; ***********************************************************************
; * WRITE ROUTINE *
; ***********************************************************************
WRITE PROC NEAR
cld
mov cx, WORD PTR Packet.IOcount ; CX = # bytes to write
mov ax, WORD PTR Packet.IOpData+2 ; hi word of physical address
mov dx, ax
mov bx, WORD PTR Packet.IOpData ; low word of physical address
mov bp, bx ; NOTE: "Packet." is trashed!
les di, ptrMonoMem ; point ES:DI to mono memory
mov dh, 0 ; 0 == DS:SI is virt address
push ds
@DevHlp PhysToVirt
jnc outLoop
mov fbError, 1 ; If failed, signal error writing
jmp write_term ; Jump to write_term
outLoop:
lodsb ; Load a byte to write
cmp al, CR
ja outChar
je outCR
cmp al, LF
je outLF
cmp al, TAB
je outTAB
cmp al, BS
je outBS
outChar:
stosb ; write the char
inc di ; advance over the attribute
cmp di, SCRMAXOFF ; are we at end of line?
jb outDone ; no, done with this char
mov di, SCRMINOFF ; yes, carriage return and ...
outLF:
push es ; save pointers and count
push di
push ds
push si
push cx
mov ax, es
mov ds, ax
xor di, di ; Scroll screen
mov si, 160
mov cx, 24*80
rep movsw
mov ax, 0720h ; Blank bottom line
mov cx, 80
rep stosw
; Remap DS to the user's physical buffer.
; mov ax, dx ; saved hi word of phys. addr
; mov bx, bp ; saved low word of phys. addr
; mov dh, 0 ; use DS:SI
; @DevHlp PhysToVirt
pop cx
pop si
pop ds
pop di
pop es
jmp outDone
outBS:
cmp di, SCRMINOFF
je outDone
sub di, 2
jmp outDone
outTAB:
or di, 0Eh
add di, 2
jmp outDone
outCR:
mov di, SCRMINOFF
outDone:
loop outLoop
write_term:
pop ds ; restore driver's DS register
@DevHlp UnPhysToVirt ; mark completion of PhysToVirt
mov WORD PTR ptrMonoMem, di ; save position on screen
; ------------------------------------------------------------------------
; Set new cursor position.
; ------------------------------------------------------------------------
mov dx, 03B4h
shr di, 1
mov ax, di
mov al, 0Eh
out dx, ax
mov ax, di
xchg ah, al
mov al, 0Fh
out dx, ax
ret
WRITE ENDP
OPEN PROC NEAR
mov dx, 03B4h ; Set standard monochrome cursor.
mov ax, 0B0Ah
out dx, ax
mov ax, 0C0Bh
out dx, ax
ret
OPEN ENDP
CLOSE PROC NEAR
ret
CLOSE ENDP
STATUS PROC NEAR
ret
STATUS ENDP
FLUSH PROC NEAR
ret
FLUSH ENDP
NO_OP PROC NEAR
ret
NO_OP ENDP
BadCommand PROC NEAR
or Packet.PktStatus, MASK StatError + StatUnknownCmd
ret
BadCommand ENDP
SUBTTL Initialization Code
page +
END_OF_CODE EQU $
; ***********************************************************************
; * INIT ROUTINE *
; * *
; * INIT procedure is placed at the end of the code so it can go away *
; * once initialization has been done. *
; ***********************************************************************
INIT PROC NEAR
; ========================================================================
; Save the pointer to the DevHlp routines passed in the request packet.
; ========================================================================
mov ax, WORD PTR Packet.InitpEnd ; Save pointer to DevHlp
mov WORD PTR pfnDevHlp, ax
mov ax, WORD PTR Packet.InitpEnd+2
mov WORD PTR pfnDevHlp+2, ax
; ========================================================================
; Obtain a GDT selector and map it to the monochrome monitor's memory
; at B 0000. The WRITE routine uses this memory area.
; ========================================================================
push es ; save ptr to request packet
push bx
mov ax, ds ; point ES:DI to GDT sel array
mov es, ax
mov di, OFFSET ptrMonoMem+2
mov cx, 1 ; number of selectors
@DevHlp AllocGDTSelector ; allocate the selector
jc init_error
mov ax, 000Bh
mov bx, 0000h
mov cx, 4000
mov si, WORD PTR ptrMonoMem+2
@DevHlp PhysToGDTSelector ; map the selector to memory
jc init_error
; ------------------------------------------------------------------------
; ptrMonoMem now refers to the monochrome adapter's memory.
; ------------------------------------------------------------------------
; ------------------------------------------------------------------------
; Set the ending offsets to unload initialization code and data.
; ------------------------------------------------------------------------
@@: pop bx
pop es
lea ax, END_OF_CODE ; Place end of code segment into
mov WORD PTR Packet.InitpEnd, ax ; request packet
lea ax, END_OF_DATA ; Place end of data segment into
mov WORD PTR Packet.InitpEnd+2, ax ; request packet
jmp init_done
init_error:
pop bx ; restore ptr to request packet
pop es
mov fbError, 1
mov WORD PTR Packet.InitpEnd, 0
mov WORD PTR Packet.InitpEnd+2, 0
init_done:
ret
INIT ENDP
CODE ENDS
END