2 TITLE DOS
- PRINT
- RESIDENT
6 ; include Extended Atribute support
10 BREAK <Resident Portion
>
17 Code Segment public para
18 extrn TransRet
:WORD,TransSize
:WORD,NameBuf
:WORD
24 CodeR
Segment public para
26 public SliceCnt
, BusyTick
, MaxTick
, TimeSlice
27 public EndRes
, BlkSiz
, QueueLen
, PChar
28 public ListName
, FileQueue
, EndQueue
, Buffer
29 public EndPtr
, NxtChr
, MoveTrans
37 db " - PRINT utility - "
41 db 01Ah ; fake end of file for 'TYPE'
42 DB (361 - 80h
) + 310 DUP (?
) ; (362 - 80h) is IBM's New
43 ; recommended Stack Size -
44 ; Old recommended Stack Size
46 ISTACK
LABEL WORD ;Stack starts here and grows down the
51 ; Due to flagrant bogosity by file servers, BUSY is *ALWAYS* relevant.
53 BUSY
DB 0 ;Internal ME flag
56 ; WARNING!!! The *&^%(*&^ 286 chip hangs if you access a word that will wrap
57 ; at the segment boundary. Make the initial INDOS point somewhere reasonable.
59 INDOS
DD TimeSlice
;DOS buisy flag
60 NEXTINT
DD ?
;Chain for int
61 NEXT_REBOOT
DD ?
;Chain for ROM bootstrap
63 fFake db 0 ; TRUE => do not diddle I/O ports
64 SOFINT
DB 0 ;Internal ME flag
65 TICKCNT
DB 0 ;Tick counter
66 TICKSUB
DB 0 ;Tick miss counter
67 SLICECNT
DB DefTimeSlice
;Time slice counter, init to same val
70 TIMESLICE
DB DefTimeSlice
;The PRINT scheduling time slice. PRINT
71 ; lets this many "ticks" go by before
72 ; using a time slice to pump out characters.
73 ; Setting this to 3 for instance means PRINT
74 ; Will skip 3 slices, then take the fourth.
75 ; Thus using up 1/4 of the CPU. Setting it
76 ; to one gives PRINT 1/2 of the CPU.
77 ; The above examples assume MAXTICK is
78 ; 1. The actual PRINT CPU percentage is
79 ; (MAXTICK/(1+TIMESLICE))*100
81 MAXTICK
DB DefMaxTick
;The PRINT in timeslice. PRINT will pump
82 ; out characters for this many clock ticks
83 ; and then exit. The selection of a value
84 ; for this is dependent on the timer rate.
86 BUSYTICK
DB DefBusyTick
;If PRINT sits in a wait loop waiting for
87 ; output device to come ready for this
88 ; many ticks, it gives up its time slice.
89 ; Setting it greater than or equal to
90 ; MAXTICK causes it to be ignored.
92 ;User gets TIMESLICE ticks and then PRINT takes MAXTICK ticks unless BUSYTICK
93 ; ticks go by without getting a character out.
95 QueueLen db DefQueueLen
; Actual length of print queue
97 EndQueue dw ?
; pointer to end of print queue
98 QueueTail dw offset CodeR
:FileQueue
; pointer to next free entry
100 buffer dw ?
; pointer to data buffer
102 I24_ERR
DW ?
;Save location for INT 24H error code
103 Ctrlc
DB ?
; saved ^C trapping state
104 SPNEXT
DD ?
;Chain location for INT 28
105 COMNEXT
DD ?
;Chain location for INT 2F
106 SSsave
DW ?
;Stack save area for INT 24
108 HERRINT
DD ?
;Place to save Hard error interrupt
109 LISTDEV
DD ?
;Pointer to Device
110 COLPOS
DB 0 ;Column position for TAB processing
112 CURRCP
DW -1 ; Current file's CP in binary ;AN000;
115 PrinterNum
DW no_lptx
; index for printer
116 no_lptx equ
-1 ; no valid LPTx
117 QueueLock db 0 ; queue lock, 0=unlocked
120 PChar db ?
; path character
121 AmbCan db ?
; = 1 ambigous cancel
122 CanFlg db ?
; = 1 Current was already canceled
123 ACanOcrd db ?
; = 1 a file was found during an
126 ;--- Warnning: this is a FCB!!
131 db 4 dup(?
) ; how big is an unopened fcb???
134 CONTXTFLAG
DB 0 ;0 means his context, NZ means me
136 PABORT
DB 0 ;Abort flag
137 BLKSIZ
DW DefBufferLen
;Size of the PRINT I/O block in bytes
140 COMDISP
LABEL WORD ; Communications dispatch table
142 DW OFFSET CodeR
:INST_REQ
143 DW OFFSET CodeR
:ADDFIL
144 DW OFFSET CodeR
:CANFIL
145 DW OFFSET CodeR
:CanAll
146 DW OFFSET CodeR
:QSTAT
147 DW OFFSET CodeR
:EndStat
148 DW OFFSET CodeR
:QSTATDEV
150 query_list
label word
153 qea
<EAISBINARY
,EASYSTEM
,2,"C">
154 db "P" ; specify name as CP
157 dw 1 ; only one EA of interest
158 ea
<EAISBINARY
,EASYSTEM
,?
,2,2,"C">
160 code_page dw 0 ; CP initialized to 0
162 list_size equ
$ - list
163 ;--------------------------------------
164 ; Resident Message Buffer - Data area
165 ;--------------------------------------
167 ERRMES
DB 13,10,13,10
171 BELMES
DB 13,0CH,7,"$"
175 ;--------------------------------------
176 ; Resident Message Pointer Control Block
177 ;--------------------------------------
179 MESBAS
DW ?
; OFFSET CodeR:ERR0 This list is order sensitive
180 DW ?
; OFFSET CodeR:ERR1 and must not be changed without
181 DW ?
; OFFSET CodeR:ERR2 considering the logic in
182 DW ?
; OFFSET CodeR:ERR3 Load_R_Msg
183 DW ?
; OFFSET CodeR:ERR4
184 DW ?
; OFFSET CodeR:ERR5
185 DW ?
; OFFSET CodeR:ERR6
186 DW ?
; OFFSET CodeR:ERR7
187 DW ?
; OFFSET CodeR:ERR8
188 DW ?
; OFFSET CodeR:ERR9
189 DW ?
; OFFSET CodeR:ERR10
190 DW ?
; OFFSET CodeR:ERR11
191 DW ?
; OFFSET CodeR:ERR12
192 ERRMEST_PTR
DW ?
; OFFSET CodeR:ERRMEST
193 ErrMesT2_PTR
DW ?
; OFFSET CodeR:ErrMesT2
194 CANMES_PTR
DW ?
; OFFSET CodeR:CANMES
195 CanFilNam_PTR
DW ?
; OFFSET CodeR:CanFilNam
196 AllCan_PTR
DW ?
; OFFSET CodeR:AllCan
197 FATMES_PTR
DW ?
; OFFSET CodeR:FATMES
198 BADDRVM_PTR
DW ?
; OFFSET CodeR:BADDRVM
200 ENDRES
DW ?
; filled in at initialization time
206 BREAK <Resident
Code>
208 CodeR
Segment public para
210 Break <Server critical
section routines
>
218 mov ax,8700h
; Can I run?
232 ;---------------------------------------
234 ;---------------------------------------
236 ASSUME
CS:CodeR
,DS:nothing
,ES:nothing
,SS:nothing
238 ;---------------------------------------
240 ; PRINT is stimulated by a hardware
244 ; The Server may also stimulate us
245 ; during timer ticks (if we handled
246 ; the ticks ourselves, it would be
247 ; disasterous). Therefore, we have a
248 ; substitute entry here that simulates
249 ; the timer stuff but does NOT muck
252 ;---------------------------------------
256 jmp SHORT InnerHardInt
258 HDSPINT: ;Hardware interrupt entry point
276 dec [SLICECNT
] ;Count down
282 cmp BUSY
,0 ; interrupting ourself ?
284 ; $if z,and ; if NOT interupting ourselves and ... ;AC000;
287 push ax ; check for nested interrupts
288 mov al,00001011b ; select ISR in 8259
294 in al,20H
; get ISR register
295 and al,0FEH ; mask timer int
298 ; $if z,and ; if there are no other ints to service;AC000;
303 lds si,[INDOS
] ;Check for making DOS calls
305 ;---------------------------------------
307 ; WARNING!!! Due to INT 24 clearing the
308 ; INDOS flag, we must test both INDOS
309 ; and ERRORMODE at once!
311 ; These must be contiguous in MSDATA.
313 ;---------------------------------------
314 cmp WORD PTR [SI-1],0
318 ; $if z ; if no errors ;AC000;
321 inc [BUSY
] ;Exclude furthur interrupts
322 mov [TICKCNT
],0 ;Reset tick counter
323 mov [TICKSUB
],0 ;Reset tick counter
324 sti ;Keep things rolling
327 ; $if z ;if needed ;AC000;
331 mov al,EOI
;Acknowledge interrupt
335 ; $endif ; endif ;AC000;
342 mov [SLICECNT
],al ;Either soft or hard int resets time slice
344 dec Busy
;Done, let others in
362 jmp [NEXTINT
] ; chain to next clock routine
369 ;---------------------------------------
370 ; PRINT is stimulated by a
371 ; spooler idle interrupt
372 ;---------------------------------------
374 SPINT: ; INT 28H entry point
378 ; $if nc ; if no server ;AC000;
383 ; $if z ; if not busy ;AC000;
386 inc [BUSY
] ; exclude hardware interrupt
387 inc [SOFINT
] ; indicate a software int in progress
388 sti ; hardware interrupts ok on INT 28H entry
391 mov [SOFINT
],0 ;Indicate INT done
394 mov [SLICECNT
],al ;Either soft or hard int resets time slice
406 jmp [SPNEXT
] ;Chain to next INT 28
408 ;---------------------------------------
409 ; Since we may be entering at arbitrary
410 ; times, we need to get/set the extended
411 ; error as we may end up blowing it away.
412 ; We do not do this on spooler ints.
413 ;---------------------------------------
415 SaveState DPL
<> ; empty DPL
423 ; $if z ;if not soft int ;AC000;
426 mov ah,GetExtendedError
428 mov SaveState
.DPL_AX
,AX
429 mov SaveState
.DPL_BX
,BX
430 mov SaveState
.DPL_CX
,CX
431 mov SaveState
.DPL_DX
,DX
432 mov SaveState
.DPL_SI
,SI
433 mov SaveState
.DPL_DI
,DI
434 mov SaveState
.DPL_DS
,DS
435 mov SaveState
.DPL_ES
,ES
448 ; $if z ; if soft int ;AC000;
451 mov ax,(ServerCall
SHL 8) + 10
454 mov dx,OFFSET CodeR
:SaveState
466 ASSUME
CS:CodeR
,DS:nothing
,ES:nothing
,SS:nothing
478 je spret
; queue locked, do nothing...
479 push ax ;Need a working register
484 ;---------------------------------------
485 ; Go to internal stack to prevent
486 ; INT 24 overflowing system stack
487 ;---------------------------------------
489 mov sp,OFFSET CodeR
:ISTACK
508 jmp READBUFF
;Buffer empty
528 jae DONEJMPJ
;Buffer has become empty
533 cmp [TICKCNT
],al ;Check our time slice
542 jz DONEJMPJP
;File got cancelled by error
544 jz DOCHAR
;Printer ready
546 jnz DONEJMP
;If soft int give up
549 cmp [TICKSUB
],al ;Check our busy timeout
561 ; $if z ; if CR ;AC000;
571 mov cl,[COLPOS
] ;expand tab to # spaces
575 jcxz TABDONE
;CX contains # spaces to print
585 jz TABDONE
;G We're done - get next char
586 jmp PLOOP
;G Keep processing tab
593 cmp al,8 ;Back space?
599 cmp al,20h
;Non Printing char?
601 ; $if ae ; if not printable
604 inc [COLPOS
] ;Printing char
613 inc [NXTCHR
] ;Next char
614 mov [TICKSUB
],0 ;Got a character out, Reset counter
615 cmp [SOFINT
],0 ;Soft int does one char at a time
632 ASSUME
DS:nothing
,ES:nothing
635 mov ss,[SSsave
] ;Restore Entry Stack
644 ASSUME
DS:nothing
,ES:nothing
,SS:nothing
648 ; $if nz ; if not in context ;AC000;
653 mov ah,SET_CURRENT_PDB
665 ASSUME
DS:nothing
,ES:nothing
,SS:nothing
669 ; $if z ; if context off ;AC000;
673 mov ah,GET_CURRENT_PDB
677 sub bx,10h
; The 2.5 print is an exe program
678 mov ah,SET_CURRENT_PDB
687 ;---------------------------------------
688 ;--- Refill the print buffer ---
689 ;---------------------------------------
692 ASSUME
DS:CodeR
,ES:NOTHING
,SS:NOTHING
694 call Set24
; switch Int24 vector
695 mov [PABORT
],0 ;No abort
702 call Res24
; reset Int 24 vector
705 pop ax ;Flags from read
706 jmp FilClose
;Barf on this file, got INT 24
714 mov bx,[BUFFER
] ;Buffer full
721 ; $if ncxz ; if buffer is not completely full ;AC000;
728 rep stosb ; pad the buffer
730 ; $endif ; endif ;AC000;
737 mov al,0Ch ;Form feed
739 ;---------------------------------------
742 ; note: we came here from an i24
743 ; then PAbort is already = 1
744 ;---------------------------------------
750 call CloseFile
; ;AC000;
752 mov [CURRFIL
],0 ; No file
753 mov [CURRHAND
],-1 ; Invalid handle
755 mov [NXTCHR
],ax ; Buffer empty
757 ;---------------------------------------
758 ;--- Send close on output device
759 ;---------------------------------------
762 ;---------------------------------------
763 ;--- compact the print queue
764 ;---------------------------------------
770 ;---------------------------------------
771 ;--- Check if there are any more
773 ;---------------------------------------
774 mov si,OFFSET CodeR
:FileQueue
775 cmp byte ptr [si],0 ; no more left if name starts with nul
778 mov [PABORT
],0 ;No abort
779 mov dx,si ; DS:DX points to file name
780 call OpenFile
; try opening new file ;AC000;
786 jmp short CompQAgn
; try next file
795 GotNewFile: ; buffer was already marked as empty
800 ;---------------------------------------
801 ;--- Send Open on output device
802 ;---------------------------------------
809 ;---------------------------------------
810 ;--- Print open error ---
812 ;---------------------------------------
816 ASSUME
DS:CodeR
,ES:nothing
818 ;---------------------------------------
819 ; This stuff constitutes a "file" so it
820 ; is bracketed by an open/close
821 ; on the output device.
822 ;---------------------------------------
824 ;---------------------------------------
825 ;--- Send Open on output device
826 ;---------------------------------------
834 mov si,OFFSET CodeR
:ErrMes
836 mov si,ErrMesT2_ptr
; ;AC000;
838 mov si,OFFSET CodeR
:FileQueue
840 mov si,OFFSET CodeR
:BelMes
843 ;---------------------------------------
844 ;--- Send close on output device
845 ;---------------------------------------
852 ;---------------------------------------
853 ;--- Compact File Queue ---
854 ; - modifies: AX,CX,SI,DI,ES
855 ;---------------------------------------
859 ASSUME
DS:CodeR
,ES:nothing
,SS:nothing
866 mov di,OFFSET CodeR
:FileQueue
; ES:DI points to top of queue
867 mov si,(OFFSET CodeR
:FileQueue
+ MaxFileLen
) ; DS:SI points to next entry
869 sub cx,si ; length in bytes of the queue
871 rep movsb ; compact the queue
872 mov ax,[QueueTail
] ; normalize tail pointer as we
873 sub ax,MaxFileLen
; know have a new "next empty slot"
876 mov byte ptr [si],0 ; nul first byte of last entry
881 BREAK <Resident
Code: DSKERR
>
883 ;---------------------------------------
884 ;--- Set Local Int 24 vector ---
886 ;---------------------------------------
890 ASSUME
DS:nothing
,ES:nothing
,SS:nothing
896 mov ah,GET_INTERRUPT_VECTOR
898 mov WORD PTR [HERRINT
+2],es ; Save current vector
899 mov WORD PTR [HERRINT
],bx
900 mov dx,OFFSET CodeR
:DSKERR
902 mov ah,SET_INTERRUPT_VECTOR
; Install our own
903 call do_21
; Spooler must catch its errors
909 ;---------------------------------------
910 ;--- Reset Old Int 24 vector ---
912 ;---------------------------------------
915 ASSUME
DS:nothing
,ES:nothing
,SS:nothing
925 mov ah,SET_INTERRUPT_VECTOR
926 call do_21
;Restore Error INT
932 ;---------------------------------------
933 ;--- INT 24 handler ---
934 ;---------------------------------------
937 ASSUME
DS:nothing
,ES:nothing
,SS:nothing
941 ; $if z ; if not to ignore ;AC000;
958 ASSUME
DS:CodeR
,ES:CodeR
960 mov si,BADDRVM_PTR
; Fix up Drive ID for FATMES ;AC000;
961 add ds:[si],al ; ;AC000;
962 mov si,OFFSET CodeR
:ERRMES
966 ; $if z ; if not fat error ;AC000;
972 ; $if a ; if greater - force it to 12 ;AC000;
982 mov di,WORD PTR [di+MESBAS
] ; Get pointer to error message
984 call LISTMES
; Print error type
985 mov si,ERRMEST_PTR
; ;AC000;
987 mov si,OFFSET CodeR
:FileQueue
; print filename
988 call ListMes2
; print name
989 mov si,OFFSET CodeR
:BelMes
997 mov si,FATMES_PTR
; ;AC000;
1003 inc [PABORT
] ;Indicate abort
1020 BREAK <Resident
Code: SPCOMINT
>
1022 ;---------------------------------------
1023 ;--- Communications interrupt ---
1024 ;---------------------------------------
1028 ASSUME
DS:nothing
,ES:nothing
,SS:nothing
1046 mov al,1 ; Tell PSPRINT to go away (AH = 1)
1076 or word ptr [bp+6],f_Carry
1084 CMP AX,6 ; check function within valid range
1086 mov ax,error_invalid_function
1092 sti ;Turn ints back on
1101 mov [QueueLock
],0 ; unlock the print queue
1102 shl ax,1 ;Turn into word index
1108 ; $if nc ; if no error ;AC000;
1111 ASSUME
DS:CodeR
,ES:nothing
1117 ASSUME
DS:CodeR
,ES:nothing
1119 call PSTAT
; Tweek error counter
1131 dec BUSY
; leaves carry alone!
1141 and word ptr [bp+6],NOT f_Carry
1148 BREAK <Get queue status
>
1150 ;---------------------------------------
1151 ;--- Return pointer to file queue ---
1152 ;---------------------------------------
1156 ASSUME
DS:CodeR
,ES:nothing
1158 mov [QueueLock
],1 ; lock the print queue
1159 call PSTAT
; Tweek error counter
1162 mov [bp+ 2 + 2],cs ; <BP> <RET> <DS>
1164 mov si,OFFSET CodeR
:FileQueue
1165 mov dx,[ErrCnt
] ; return error count
1169 ;---------------------------------------
1170 ;--- Return pointer to device ---
1171 ; --- driver if active ---
1172 ;---------------------------------------
1175 ASSUME
DS:CodeR
,ES:nothing
1177 xor ax,ax ;g assume not busy
1178 mov [QueueLock
],1 ;g lock the print queue
1179 call PSTAT
;g Tweek error counter
1180 cmp byte ptr FileQueue
,0 ;g is there anything in the queue?
1182 jz qstatdev_end
;g no - just exit
1183 mov ax,error_queue_full
;g yes - set error queue full
1184 mov si,word ptr [listdev
+2] ;g get segment of list device
1187 mov [bp+2+2],si ;g <BP><RET><DS> seg of device to DS
1189 mov si,word ptr [listdev
] ;g offset of device to SI
1194 mov [QueueLock
],0 ;g unlock the print queue
1197 BREAK <Resident
Code: EndStat
>
1199 ;---------------------------------------
1200 ;--- Unlock the print queue ---
1201 ;---------------------------------------
1205 ASSUME
DS:CodeR
,ES:nothing
1212 BREAK <Cancel all available files
in the queue
>
1214 ;---------------------------------------
1215 ; Note: Loop until the background is free
1216 ;---------------------------------------
1220 ASSUME
DS:CodeR
,ES:nothing
1222 cmp [CurrFil
],0 ; are we currently printing?
1227 ;---------------------------------------
1228 ;--- Cancel active file
1229 ;---------------------------------------
1231 mov bx,[CurrHand
] ; close the current file
1233 mov [PAbort
],1 ; no Int24's
1234 call CloseFile
; close the file ;AC000;
1236 mov [CurrFil
],0 ; no files to print
1237 mov [CurrHand
],-1 ; invalidate handle
1238 mov ax,[EndPtr
] ; buffer empty
1241 ;---------------------------------------
1242 ;--- Cancel rest of files
1243 ;---------------------------------------
1245 mov si,OFFSET CodeR
:FileQueue
1246 mov [QueueTail
],si ; next free entry is the first
1247 mov byte ptr [si],0 ; nul first byte of firts entry
1248 mov si,AllCan_PTR
; ;AC000;
1249 call ListMes
; print cancelation message
1250 mov si,OFFSET CodeR
:BelMes
1251 call ListMes
; ring!!
1253 ;---------------------------------------
1254 ;--- Send close on output device
1255 ;---------------------------------------
1265 BREAK <Cancel a
file in progress
>
1269 ASSUME
DS:CodeR
,ES:nothing
1274 ret ; carry is clear
1277 ;---------------------------------------
1278 ;--- find which file to cancel
1279 ;---------------------------------------
1282 mov ds,[bp+ 2 + 2] ; <BP> <RET> <DS>
1292 mov [CanFlg
],0 ; reset message flag
1293 mov [ACanOcrd
],0 ; no cancelation has ocured yet
1294 mov bx,OFFSET CodeR
:FileQueue
; ES:BX points to 1st entry in queue
1299 mov di,bx ; ES:DI points to 1st entry in queue
1300 mov si,dx ; DS:SI points to filename to cancel
1305 cmp al,byte ptr es:[di] ; names in queue are all in upper case
1307 jmp AnotherName
; a mismatch, try another name
1311 cmp es:byte ptr es:[di],0 ; was this the terminating nul?
1312 je NameFound
; yes we got our file...
1318 cmp [AmbCan
],1 ; ambigous file name specified?
1319 jne AnName
; if not then no more work to do
1322 cmp byte ptr es:[di],"."
1324 cmp byte ptr es:[di],0 ; if nul then file names match
1325 jne CharMatch
; only if only ?'s are left...
1335 jne AnName
; found something else, no match
1338 FindPeriod: ; ambigous files always have 8 chars
1340 lodsb ; in name so we can not look for the
1341 or al,al ; period twice (smart uh?)
1342 je AnName
; no period found, files do not match
1350 cmp byte ptr es:[bx],0 ; end of queue?
1351 jne AnotherTry
; no, continue...
1352 cmp [ACanOcrd
],1 ; yes, was there a file found?
1357 ASSUME
DS:CodeR
; StartAnFil likes it this way...
1359 jmp StartAnFil
; restart printing
1365 mov ax,error_file_not_found
1369 ;---------------------------------------
1370 ;--- Name found, check if current file
1371 ;---------------------------------------
1379 mov [ACanOcrd
],1 ; remember we found a file
1380 cmp bx,OFFSET CodeR
:FileQueue
; is the file being printed?
1382 ; $if e,and ; if it is and .................. ;AC000;
1387 ; $if e ; if not in cancel mode ........: ;AC000;
1390 ;---------------------------------------
1391 ;--- Cancel current file
1392 ;---------------------------------------
1394 mov [CanFlg
],1 ; remeber we already canceled current
1396 mov bx,[CurrHand
] ; close the current file
1398 mov [PAbort
],1 ; no Int24's
1399 call CloseFile
; close the file ;AC000;
1401 mov [CurrFil
],0 ; no files to print
1402 mov [CurrHand
],-1 ; invalidate handle
1403 mov ax,[EndPtr
] ; buffer empty
1406 ;---------------------------------------
1407 ;--- print cancelation message
1408 ;---------------------------------------
1410 mov si,CanMes_PTR
; ;AC000;
1411 call ListMes
; print cancelation message
1412 mov si,bx ; points to filename
1413 call ListMes2
; print filename
1414 mov si,CanFilNam_PTR
; ;AC000;
1416 mov si,OFFSET CodeR
:BelMes
1417 call ListMes
; ring!!
1419 ;---------------------------------------
1420 ;--- Send close on output device
1421 ;---------------------------------------
1427 mov di,bx ; DI points to entry to cancel
1429 add si,MaxFileLen
; SI points to next entry
1430 cmp si,[QueueTail
] ; is the entry being canceled the last?
1432 ; $if e ; if it is ;AC000;
1435 mov byte ptr [di],0 ; yes, just nul the first byte
1441 mov cx,[EndQueue
] ; CX points to the end of the queue
1442 sub cx,si ; length of the remainning of the queue
1444 rep movsb ; compact the queue
1449 mov ax,[QueueTail
] ; remember new end of queue
1453 mov byte ptr [si],0 ; nul first byte of last entry
1455 cmp byte ptr [bx],0 ; is there another file to consider?
1459 mov ds,[bp+ 2 + 2] ; <BP> <RET> <DS>
1464 jmp AnotherTry
; yes do it again...
1466 ;---------------------------------------
1467 ;--- Start new file...
1468 ;---------------------------------------
1473 cmp [CurrHand
],-1 ; was the canceled name the current?
1474 jne NoneLeft
; no, just quit
1478 mov si,OFFSET CodeR
:FileQueue
; points to new current file
1479 cmp byte ptr[si],0 ; is there one there?
1480 je NoneLeft
; no, we canceled current and are none left
1484 call OpenFile
; try to open the file ;AC000;
1490 call CompQ
; compact file queue
1491 jmp short StartAnFil2
1497 call PrtOpErr
; print open error
1498 call CompQ
; compact file queue
1499 jmp short StartAnFil2
1503 mov [CurrHand
],ax ; save handle
1504 mov [CurrFil
],1 ; signal active (buffer is already empty)
1506 ;---------------------------------------
1507 ;--- Send Open on output device
1508 ;---------------------------------------
1516 ;---------------------------------------
1517 ;--- Ambigous file name check ---
1518 ; entry: ds:dx points to filename
1519 ; preserves ds:dx and es
1520 ;---------------------------------------
1521 ASSUME
DS:nothing
,ES:CodeR
1525 mov [AmbCan
],0 ; assume not ambigous
1535 ; $enddo e ; ;AC000;
1538 dec si ; points to nul
1539 std ; scan backwards
1547 ; $if e ; if a * ;AC000;
1557 ; $if e ; if a ? ;AC000;
1567 ; $enddo e ; ;AC000;
1571 cmp [AmbCan
],1 ; an ambigous cancel?
1573 ; $if e ; if its an ambiguous cancel ;AC000;
1576 ;---------------------------------------
1577 ;--- transform * to ?'s
1578 ;---------------------------------------
1580 inc si ; points to actual name (past path char)
1581 mov di,OFFSET CodeR
:ACBuf
1586 rep stosb ; fill fcb with blanks
1589 mov ax,(Parse_file_descriptor
shl 8) and 0FF00h
1593 ;---------------------------------------
1594 ;--- Copy name to expanded name
1595 ;---------------------------------------
1609 mov si,OFFSET CodeR
:ACName
1618 ; $leave e ; ;AC000;
1623 ; $enddo loop ; ;AC000;
1627 mov si,OFFSET CodeR
:ACExt
1628 cmp byte ptr [si],20h
; extension starts with blank ?
1630 ; $if ne ; if it does not ;AC000;
1643 ; $leave e ; ;AC000;
1648 ; $enddo loop ; ;AC000;
1655 mov byte ptr es:[di],0 ; nul terminate
1670 BREAK <Add a
file to the queue
>
1674 ASSUME
DS:CodeR
,ES:nothing
1676 ;---------------------------------------
1677 ;--- Check that queue is not full
1678 ;---------------------------------------
1680 mov di,[QueueTail
] ; load pointer to next empty entry
1681 cmp di,[EndQueue
] ; queue full?
1682 jb OkToQueue
; no, place in queue...
1683 mov ax,error_queue_full
1687 ;---------------------------------------
1688 ;--- Copy name to empty slot in queue
1689 ;---------------------------------------
1697 mov ds,[bp+ 2 + 2] ; <BP> <RET> <DS>
1703 pop es ; ES:DI points to empty slot
1707 mov si,dx ; DS:SI points to submit packet
1708 cmp byte ptr ds:[si],0
1710 lds si,dword ptr ds:[si+1] ; DS:SI points to filename
1711 mov cx,MaxFileLen
; maximum length of file name
1718 je CopyDone
; yes, done with move...
1725 mov ax,error_name_too_long
; if normal exit from the loop then
1732 mov ax,error_invalid_function
1737 ASSUME
DS:nothing
,ES:nothing
; es:nothing = not true but lets
1739 CopyDone: ; avoid possible problems...
1746 ;---------------------------------------
1747 ;--- advance queue pointer
1748 ;---------------------------------------
1750 mov si,[QueueTail
] ; pointer to slot just used
1751 push si ; save for test open later
1753 mov [QueueTail
],si ; store for next round
1754 mov byte ptr [si],0 ; nul next entry (maybe the EndQueue)
1756 ;---------------------------------------
1757 ;--- Check that file exists
1758 ;---------------------------------------
1762 pop dx ; get pointer to filename
1763 call OpenFile
; ;AC000;
1768 ;;;popff ;; dcl removed for p1020 ;AC000;
1769 popf ;; dcl to fix p1020
1771 ;---------------------------------------
1772 ; See if brain damaged user entered
1774 ;---------------------------------------
1777 cmp BYTE PTR CS:[SI+1],':'
1784 mov ah,Get_default_drive
; get current
1787 mov dl,CS:[SI] ; get drive letter to test
1790 mov ah,Set_Default_Drive
; set it
1792 mov ah,Get_default_drive
; get it back
1794 cmp al,dl ; same? ;; dcl change al,al to al,dl
1795 jnz BadDrive
; no, bad drive
1796 pop dx ; get original back
1797 mov ah,Set_Default_Drive
; set original
1805 pop dx ; get original back
1806 mov ah,Set_Default_Drive
; set original
1809 mov ax,error_invalid_drive
1814 mov si,[QueueTail
] ; take bad name out of queue
1815 sub si,MaxFileLen
; SI points to the slot with bad name
1817 mov byte ptr [si],0 ; nul the first byte
1823 ;---------------------------------------
1824 ;--- Check if print currently busy
1825 ;---------------------------------------
1829 cmp [CURRFIL
],0 ; currently printing?
1831 ; $if nz ; if currently printing ;AC000;
1834 mov bx,ax ; busy, close handle
1836 mov [PAbort
],1 ; no Int24's
1837 call CloseFile
; close the file ;AC000;
1843 ;---------------------------------------
1845 ;---------------------------------------
1847 mov [CURRHAND
],ax ; Valid handle
1849 mov [NXTCHR
],ax ; Buffer empty
1851 ;---------------------------------------
1852 ;--- Send Open on output device
1853 ;---------------------------------------
1863 BREAK <Fake
int 21H
>
1865 ;---------------------------------------
1866 ; perform a system call as myself
1867 ;---------------------------------------
1880 ASSUME
DS:nothing
,ES:nothing
1882 CMP BYTE PTR CS:[INT15FLAG
],0
1884 ; $if nz ; if for PRINT ;AC000;
1889 lds bx,cs:[INT15PTR
]
1898 pushf ; Flags from system call
1899 lds bx,CS:[INT15PTR
]
1920 ASSUME
DS:nothing
,ES:nothing
,SS:nothing
1924 mov ax,Set_CTRL_C_Trapping
SHL 8 + 2
1935 ASSUME
DS:nothing
,ES:nothing
,SS:nothing
1939 mov ax,Set_CTRL_C_Trapping
SHL 8 + 2
1947 BREAK <Priter Support
>
1951 ASSUME
DS:CodeR
,ES:nothing
1962 ASSUME
DS:CodeR
,ES:nothing
1982 cmp [ERRCNT
],ERRCNT2
1983 ja POPRET
;Don't get stuck
1998 ;******************* START OF SPECIFICATIONS ***********************************
2002 ; FUNCTION: Make a SERVER DOS call
2010 ; REGISTERS USED: T.B.D.
2021 ; CHANGE 12/16/87 - Add SERVER DOS call - F. G
2024 ;******************* END OF SPECIFICATIONS *************************************
2025 ;******************** START - PSEUDOCODE ***************************************
2033 ;******************** END - PSEUDOCODE ***************************************
2037 ASSUME
DS:NOTHING
,ES:NOTHING
2039 ; Call the dos via server dos call using a DPL. The currentPDB *must* be
2040 ; properly set before this call!
2041 ; INPUT: Regs set for INT 21
2046 MOV [PRTDPL
.DPL_DS
],DS ; ;AN010;
2050 MOV [PRTDPL
.DPL_BX
],BX ; ;AN010;
2051 MOV BL,AL ; set up DRIVE ID ;AN010;
2052 SUB BL,40h
; convert to number ;AN010;
2053 XOR AL,AL ; remove file ID ;AN010;
2054 MOV [PRTDPL
.DPL_AX
],AX ; ;AN010;
2055 MOV [PRTDPL
.DPL_CX
],CX ; ;AN010;
2056 MOV [PRTDPL
.DPL_DX
],DX ; ;AN010;
2057 MOV [PRTDPL
.DPL_SI
],SI ; ;AN010;
2058 MOV [PRTDPL
.DPL_DI
],DI ; ;AN010;
2059 MOV [PRTDPL
.DPL_ES
],ES ; ;AN010;
2061 MOV [PRTDPL
.DPL_reserved
],AX ; ;AN010;
2062 MOV [PRTDPL
.DPL_UID
],AX ; ;AN010;
2064 SUB AX,10h
; ;AN010;
2065 MOV [PRTDPL
.DPL_PID
],AX ; ;AN010; ; ;AN010;
2066 ; IOCtl call to see if target drive is local
2067 ; x = IOCTL (getdrive, Drive+1) ;AN010;
2068 mov ax,(IOCTL
SHL 8) + 9 ; ;AN010;
2069 INT 21h
; IOCtl + dev_local <4409> ;AN010;
2071 MOV BX,[PRTDPL
.DPL_BX
] ; restore register ;AN010;
2073 ; $if nc,and ; target drive local and ;AN010;
2076 test dx,1200H
; check if (x & 0x1000) ;AN010;
2077 ; (redirected or shared)
2078 ; $if z ; if RC indicates NOT a network drive ;AN010;
2081 MOV DX,OFFSET CODER
:PRTDPL
; ;AN010;
2082 MOV AX,(ServerCall
SHL 8) ; make a SERVER DOS call ;AN010;
2088 MOV DX,[PRTDPL
.DPL_DX
] ; fix up reg ;AN010;
2089 MOV AX,[PRTDPL
.DPL_AX
] ; make a normal DOS call ;AN010;
2090 PUSH [PRTDPL
.DPL_DS
] ; fix up segment reg ;AN010;
2103 ;---------------------------------------
2104 ; Stuff for BIOS interface
2105 ;---------------------------------------
2107 ; $SALUT (4,25,30,41)
2122 DW OFFSET CodeR
:BYTEBUF
2129 ;---------------------------------------
2130 ; Following two routines perform device
2131 ; open and close on output device.
2132 ; NO REGISTERS (including flags) are
2133 ; Revised. No errors generated.
2134 ;---------------------------------------
2140 ASSUME
DS:nothing
,ES:nothing
2142 ;---------------------------------------
2143 ; We are now going to use the printer...
2144 ; We must lock down the printer so that
2145 ; the network does not intersperse output
2147 ; We must also signal the REDIRector for
2148 ; stream open. We must ask DOS to set
2149 ; the Printer Flag to busy
2150 ;---------------------------------------
2162 mov ax,0203h ; redirector lock
2164 mov ax,0201H ; Redirector OPEN
2170 mov ax,(SET_PRINTER_FLAG
SHL 8) + 01
2174 mov bl,DEVOPN
; Device OPEN
2189 test [SI.SDEVATT
],DEVOPCL
2199 mov [IOCALL
],DOPCLHL
2216 ASSUME
DS:nothing
,ES:nothing
2218 ;---------------------------------------
2219 ; At this point, we release the ownership
2220 ; of the printer... and do a redirector
2222 ; Also tell DOS to reset the Printer Flag
2223 ;---------------------------------------
2228 call OP_CL_OP
; Device CLOSE
2237 mov ax,0202h ; redirector CLOSE
2239 mov ax,0204h ; redirector clear
2245 mov ax,(SET_PRINTER_FLAG
SHL 8) +00
2261 mov [IOCALL
],DSTATHL
2263 test [IOSTAT
],IOERROR
2268 or [IOSTAT
],IOBUSY
;If error, show buisy
2273 test [IOSTAT
],IOBUSY
2275 ; $if z ; if ;AC000;
2293 mov [IOCALL
],DRDWRHL
2307 mov bx,OFFSET CodeR
:IOCALL
2312 mov ax,[SI+SDEVSTRAT
]
2313 mov WORD PTR [CALLAD
],ax
2316 mov WORD PTR [CALLAD
],ax
2328 ; $SALUT (4,25,30,41)
2332 INT_13_RETADDR
DW OFFSET CodeR
:INT_13_BACK
2338 ASSUME
DS:nothing
,ES:nothing
,SS:nothing
2341 inc [BUSY
] ;Exclude if dumb program call ROM
2343 push [INT_13_RETADDR
]
2344 push WORD PTR [REAL_INT_13
+2]
2345 push WORD PTR [REAL_INT_13
]
2351 INT_13_BACK PROC
FAR
2357 ret 2 ;Chuck saved flags
2361 ; $SALUT (4,25,30,41)
2364 INT15FLAG
DB 0 ; Init to off
2371 ASSUME
DS:nothing
,ES:nothing
,SS:nothing
2374 jnz REAL_15
; Not my function
2376 ja REAL_15
; I only know 0 and 1
2378 inc [INT15FLAG
] ; Turn ON
2379 mov WORD PTR [INT15PTR
],bx ; Save counter loc
2380 mov WORD PTR [INT15PTR
+2],es
2386 mov [INT15FLAG
],0 ; Turn OFF
2396 ; $SALUT (4,25,30,41)
2398 FLAG17_14
DB 0 ; Flags state of AUX/PRN redir
2407 ASSUME
DS:nothing
,ES:nothing
,SS:nothing
2410 jnz DO_INT_17
;The PRN device is not used
2412 jz DO_INT_17
;Nothing pending, so OK
2414 jnz DO_INT_17
;Not my unit
2416 jnz DO_INT_17
;You are me
2418 mov ah,0A1h ;You are bad, get time out
2424 jmp [REAL_INT_17
] ;Do a 17
2426 ; $SALUT (4,25,30,41)
2435 ASSUME
DS:nothing
,ES:nothing
,SS:nothing
2438 jnz DO_INT_14
;The AUX device is not used
2440 jz DO_INT_14
;Nothing pending, so OK
2442 jnz DO_INT_14
;Not my unit
2444 jnz DO_INT_14
;You are me
2457 mov ah,80h
;Time out
2463 jmp [REAL_INT_14
] ;Do a 14
2467 ASSUME
DS:nothing
,ES:nothing
,SS:nothing
2470 jnz DO_INT_5
;The PRN device is not used
2472 jz DO_INT_5
;Nothing pending, so OK
2474 jnz DO_INT_5
;Only care about unit 0
2476 iret ;Pretend it worked
2480 jmp [REAL_INT_5
] ;Do a 5
2482 ; $SALUT (4,25,30,41)
2488 BREAK <Bootstrap Cleanup
Code>
2492 ASSUME
CS:CodeR
,DS:nothing
,ES:nothing
,SS:nothing
2506 inc [BUSY
] ; Exclude hardware interrupts
2507 inc [SOFINT
] ; Exclude software interrupts
2509 call CanAll
; Purge the Queue
2511 lds dx,CodeR
:COMNEXT
2512 mov ax,(set_interrupt_vector
shl 8) or comint
2513 int 21h
;Set int 2f vector
2515 lds dx,CodeR
:NEXTINT
2516 mov ax,(set_interrupt_vector
shl 8) or intloc
2517 int 21h
;Set hardware interrupt
2519 mov ax,(set_interrupt_vector
shl 8) or 15h
2520 lds dx,CodeR
:Real_Int_15
; Reset the wait on event on ATs
2523 mov ax,(set_interrupt_vector
shl 8) or 17h
2524 lds dx,CodeR
:Real_Int_17
2525 int 21h
;Set printer interrupt
2527 mov ax,(set_interrupt_vector
shl 8) or 5h
2528 lds dx,CodeR
:Real_Int_5
2529 int 21h
;Set print screen interrupt
2531 mov ax,(set_interrupt_vector
shl 8) or 14h
2532 lds dx,CodeR
:Real_Int_14
2533 int 21h
;Set printer interrupt
2535 mov ax,(set_interrupt_vector
shl 8) or 24h
2536 lds dx,CodeR
:HERRINT
2537 int 21h
;Set printer interrupt
2539 mov ax,(set_interrupt_vector
shl 8) or reboot
2540 lds dx,CodeR
:NEXT_REBOOT
2541 int 21h
;Set bootstrap interrupt
2547 ;******************* START OF SPECIFICATIONS ***********************************
2549 ; NAME: OpenFile - PRINT Open a File for printing
2551 ; FUNCTION: This subroutine will mannage all environment changes required
2552 ; for Code Page switching support. This is accomplished as set
2553 ; out in the pseudocode below.
2555 ; INPUT: (DS:DX) = ASCIIZ of file to print
2557 ; OUTPUT: (AX) = handle of file
2558 ; No CPSW - File opened using INT 21 - 3D
2559 ; CPSW active - no CP on print file
2560 ; - Print file opened using INT 21 - 3D
2561 ; - valid CP on print file
2562 ; - PRINTER.SYS locked from CP change
2563 ; - Print file opened using INT 21 - 6C
2564 ; - Print file CP in CURRCP
2565 ; - Printer set to CURRCP
2567 ; NOTE: PRINT - PRINTER.SYS 2F Interface
2569 ; (AX) = AD40h - ADh is the function id
2570 ; - 40h is the sub-function id
2571 ; (BX) = n - change to this code page (binary value)
2572 ; and save current CP or any further
2574 ; -1 - restore saved CP and unlock
2578 ; REGISTERS USED: T.B.D.
2581 ; LINKAGE: Called by FILEOF, CANFIL and ADDFIL
2583 ; EXTERNAL Calls to: My21
2592 ; CHANGE 03/11/87 - First release - F. Gnuechtel
2595 ;******************* END OF SPECIFICATIONS *************************************
2596 ;******************** START - PSEUDOCODE ***************************************
2600 ; set up for INT 21 - 33 to see if CPSW is active
2602 ; if CPSW is active and
2603 ; set up for INT 21 - 6C Extended Open
2604 ; call MY_21 to open file
2609 ; call INT 2F to lock and set PRINTER.SYS to CURRCP
2612 ; set up for INT 21 - 3D Open
2613 ; call MY_21 to open file
2619 ;******************** END - PSEUDOCODE ***************************************
2627 mov bx,dx ; save pointer for later ;AN000;
2628 mov ax,(Set_CTRL_C_Trapping
shl 8) + get_CPSW
; set up for INT 21 - 33 ;AN000;
2629 ; to see if CPSW is active
2630 call My21
; call MY_21 ;AN000;
2631 xchg dx,bx ; recover pointer ;AN000;
2632 cmp bl,CPSW_on
; is CPSW active ? ;AN000; ;AN000;
2634 ; $if e ; if CPSW is active ;AC006;
2637 mov ax,(ExtOpen
shl 8) + 0 ; set for INT 21-6C ;AN000;
2638 xor cx,cx ; Extended Open ;AN000;
2639 mov bx,open_mode
; ;AN000;
2640 mov si,dx ; set DS:SI to name ;AC006;
2641 mov dx,(ignore_cp
shl 8) + (failopen
shl 4) + openit
; open if exists ;AC001;
2644 mov al,ds:[si] ; recover drive - TO_DOS needs it
2645 call TO_DOS
; call TO_DOS to open file (SERVER DOS);AC010;
2647 ; $if nc,and ; if no error and ;AN000;
2651 mov ax,(File_Times
SHL 8) + get_ea_by_handle
; now find out what CP ;AN001;
2652 mov cx,list_size
; ;AN001;
2653 lea si,query_list
; ;AN001;
2654 lea di,list
; ;AN001;
2655 call My21
; to get the CP ;AN001;
2657 ; $if nc,and ; if no error and ;AN000;
2660 mov ax,bx ; move HANDLE back to where its needed ;AN001;
2662 mov bx,[code_page
] ; is there a valid CP ? ;AC006;
2664 cmp bx,0 ; is there a valid CP ? ;AC006;
2666 ; $if g ; if valid CP ie: 0 < CP < -1 ;AN000;
2669 cmp [PrinterNum
],no_lptx
; is there a valid LPTx ? ;AN000; ;AN000;
2671 ; $if ne ; if valid LPTx available ;AN000;
2674 mov cx,ax ; save file handle ;AN008;
2675 mov [CURRCP
],bx ; update CURRCP ;AN000;
2676 mov dx,[PrinterNum
] ; ;AN000;
2677 mov ax,(major_code
shl 8) + minor_code
; semophore PRINTER.SYS ;AN000;
2678 int 2Fh
; call INT 2F to lock and set ;AN000;
2679 ; PRINTER.SYS to CURRCP
2680 mov ax,cx ; restore file handle ;AN008;
2681 ; $endif ; endif ;AN000;
2683 ; $endif ; endif ;AN006;
2686 ; $else ; else ;AN000;
2691 mov al,ds:[si] ; recover drive - TO_DOS needs it
2692 mov ah,(open
) ; set up for INT 21 - 3D Open ;AN000;
2693 mov cx,016h ; set up search attribute for Server ;AN011;
2695 call TO_DOS
; call TO_DOS to open file (SERVER DOS);AC010;
2697 ; $endif ; endif ;AN000;
2700 ret ; return ;AN000;
2705 ;******************* START OF SPECIFICATIONS ***********************************
2707 ; NAME: CloseFile - PRINT Close a File for printing
2709 ; FUNCTION: This subroutine will mannage all environment changes required
2710 ; for Code Page switching support. This is accomplished by:
2714 ; INPUT: (BX) = handle of file to close
2717 ; OUTPUT: File closed
2718 ; CPSW active - PRINTER.SYS unlocked
2719 ; - CHECKCP is reset
2721 ; REGISTERS USED: T.B.D.
2724 ; LINKAGE: Called by FILEOF, CANALL, CANFIL and ADDFIL
2726 ; EXTERNAL Calls to: My21
2735 ; CHANGE 03/11/87 - First release - F. G
2738 ;******************* END OF SPECIFICATIONS *************************************
2739 ;******************** START - PSEUDOCODE ***************************************
2743 ; if CHECKCP != 0 then
2744 ; call INT 2F to unlock PRINTER.SYS
2748 ; call My21 to close file
2754 ;******************** END - PSEUDOCODE ***************************************
2758 cmp [CURRCP
],0 ; is 0 < CHECKCP < -1 ? ;AN000;
2760 ; $if g ; if CHECKCP is valid ;AN000;
2763 push bx ; save file handle ;AN000;
2764 xor bx,bx ; set CP to unlock ;AN000;
2766 mov dx,[PrinterNum
] ; set which LPTx ;AN000;
2767 mov ax,(major_code
shl 8) + minor_code
; semophore to PRINTER.SYS ;AN000;
2768 int 2Fh
; call INT 2F to unlock PRINTER.SYS ;AN000;
2769 mov [CURRCP
],0 ; reset CHECKCP ;AN000;
2770 pop bx ; recover file handle ;AN000;
2772 ; $endif ; endif ;AN000;
2775 mov ax,(close
shl 8) ; set up for INT 21 - close ;AN000;
2776 call My21
; call My21 to close file ;AC010;
2778 ret ; return ;AN000;
2782 BREAK <QUeue
& Buffer Space
>
2784 ; $SALUT (4,25,30,41)
2786 ;---------------------------------------
2788 ; NOTE: FileQueue is the actuall end of
2789 ; the RESIDENT PRINT code. The
2790 ; code that follows this is still
2791 ; initialization code - and is NOT
2794 ; --- File name Queue and data buffer
2797 ;---------------------------------------
2799 FileQueue
Label byte
2801 db 0 ; the file queue starts empty
2805 ;******************* START OF SPECIFICATIONS ***********************************
2811 ; INPUT: LISTNAME has the 8 char device name IN UPPER CASE
2817 ; REGISTERS USED: Only DS preserved
2820 ; LINKAGE: Called by: MoveTrans
2825 ; ERROR CF = 1 - Bad Device name
2828 ; CHANGE 05/20/87 - Header added - F. G
2831 ;******************* END OF SPECIFICATIONS *************************************
2832 ;******************** START - PSEUDOCODE ***************************************
2840 ;******************** END - PSEUDOCODE ***************************************
2842 ;---------------------------------------
2843 ; Reserved names for parallel card
2844 ;---------------------------------------
2845 INT_17_HITLIST
LABEL BYTE
2853 ;---------------------------------------
2854 ; Reserved names for Async adaptor
2855 ;---------------------------------------
2856 INT_14_HITLIST
LABEL BYTE
2862 ;---------------------------------------
2863 ; Default Device Name
2864 ;---------------------------------------
2866 LISTNAME
DB "PRN " ;Device name
2872 ASSUME
CS:CodeR
,DS:CodeR
,ES:nothing
,SS:nothing
2879 lea si,es:[bx.SYSI_DEV
]
2888 mov di,OFFSET CodeR
:LISTNAME
2893 test [si.SDEVATT
],DEVTYP
;
2895 ; $if nz,and ; if type is character ;AN000;
2900 add si,SDEVNAME
; Point at name
2906 ; $if z ; if the end was reached with a match ;AN000;
2909 stc ; signal end ;AN000;
2920 ; $exitif c ; ;AN000;
2923 mov WORD PTR [CALLAD
+2],ds ;Get I/O routines
2924 mov WORD PTR [LISTDEV
+2],ds ;Get I/O routines
2925 mov WORD PTR [LISTDEV
],si
2931 mov PrinterNum
,-1 ; Assume not an INT 17 device
2937 mov bp,OFFSET CodeR
:LISTNAME
2939 mov di,OFFSET CodeR
:INT_17_HITLIST
2947 lds si,[si.SDEVNEXT
] ;
2950 ; $endloop z ; ;AN000;
2957 ; $endsrch ; ;AN000;
2964 BREAK <chk_int17_dev
>
2965 ;******************* START OF SPECIFICATIONS ***********************************
2967 ; NAME: chk_int17_dev
2971 ; INPUT: (DS) = CodeR
2978 ; REGISTERS USED: T.B.D.
2989 ; CHANGE 05/20/87 - Header added - F. G
2992 ;******************* END OF SPECIFICATIONS *************************************
2993 ;******************** START - PSEUDOCODE ***************************************
2995 ; START chk_int17_dev
3001 ;******************** END - PSEUDOCODE ***************************************
3003 chk_int17_dev PROC
NEAR
3011 ; $if ncxz ; ;AC000;
3025 ; $exitif c ; ;AC000;
3028 mov di,OFFSET CodeR
:INT_14_HITLIST
3030 call chk_int14_dev
; ;AC000;
3038 add di,cx ;Bump to next position without affecting flags
3039 mov bl,[di] ;Get device number
3043 ; $endloop z ; ;AC000;
3048 mov PrinterNum
,bx ; Set this as well to the INT 17 device
3052 ; $endsrch ; ;AC000;
3059 BREAK <chk_int14_dev
>
3060 ;******************* START OF SPECIFICATIONS ***********************************
3062 ; NAME: chk_int14_dev
3066 ; INPUT: (DS) = CodeR
3073 ; REGISTERS USED: T.B.D.
3084 ; CHANGE 05/20/87 - Header added - F. G
3087 ;******************* END OF SPECIFICATIONS *************************************
3088 ;******************** START - PSEUDOCODE ***************************************
3090 ; START chk_int14_dev
3096 ;******************** END - PSEUDOCODE ***************************************
3098 chk_int14_dev PROC
NEAR
3107 ; $if ncxz ; ;AC000;
3121 ; $exitif c ; ;AC000;
3132 add di,cx ;Bump to next position without affecting flags
3133 mov bl,[di] ;Get device number
3137 ; $endloop z ; ;AC000;
3144 ; $endsrch ; ;AC000;
3154 ;******************* START OF SPECIFICATIONS ***********************************
3166 ; REGISTERS USED: T.B.D.
3177 ; CHANGE 05/20/87 - Header added - F. G
3180 ;******************* END OF SPECIFICATIONS *************************************
3181 ;******************** START - PSEUDOCODE ***************************************
3189 ;******************** END - PSEUDOCODE ***************************************
3193 ASSUME
CS:CodeR
,DS:CodeR
,ES:nothing
,SS:nothing
3195 mov ax,(CLASS_B
shl 8) + BADMES
; ;AC000;
3196 call GoDispMsg
; ;AC002;
3197 ;*********************************************************************
3198 mov ax,(SET_PRINTER_FLAG
SHL 8) ; Set flag to Idle
3200 ;*********************************************************************
3201 mov ax,(EXIT
SHL 8) OR 0FFH
3207 ;******************* START OF SPECIFICATIONS ***********************************
3211 ; FUNCTION: Move the transient out of the way of the Buffer space
3219 ; REGISTERS USED: T.B.D.
3230 ; CHANGE 05/20/87 - Header added - F. G
3233 ;******************* END OF SPECIFICATIONS *************************************
3234 ;******************** START - PSEUDOCODE ***************************************
3242 ;******************** END - PSEUDOCODE ***************************************
3244 ContTrans dd ?
; transient continuation address after move
3248 ASSUME
CS:CodeR
,DS:CodeR
,ES:CodeR
,SS:nothing
3258 mov dx,OFFSET CodeR
:SPINT
3260 mov ah,GET_INTERRUPT_VECTOR
3261 int 21h
;Get soft vector
3262 mov WORD PTR [SPNEXT
+2],es
3263 mov WORD PTR [SPNEXT
],bx
3265 mov ah,SET_INTERRUPT_VECTOR
3266 int 21h
;Set soft vector
3267 mov dx,OFFSET CodeR
:SPCOMINT
3269 mov ah,GET_INTERRUPT_VECTOR
3270 int 21h
;Get communication vector
3271 mov WORD PTR [COMNEXT
+2],es
3272 mov WORD PTR [COMNEXT
],bx
3274 mov ah,SET_INTERRUPT_VECTOR
;Set communication vector
3277 mov AH,GET_INTERRUPT_VECTOR
3279 mov WORD PTR [REAL_INT_13
+2],es
3280 mov WORD PTR [REAL_INT_13
],bx
3281 mov DX,OFFSET CodeR
:INT_13
3283 mov ah,SET_INTERRUPT_VECTOR
3284 int 21h
;Set diskI/O interrupt
3287 mov ah,GET_INTERRUPT_VECTOR
3289 mov WORD PTR [REAL_INT_15
+2],es
3290 mov WORD PTR [REAL_INT_15
],bx
3291 mov dx,OFFSET CodeR
:INT_15
3293 mov ah,SET_INTERRUPT_VECTOR
3294 int 21h
;Set INT 15 vector
3296 mov ah,GET_INTERRUPT_VECTOR
3298 mov WORD PTR [REAL_INT_17
+2],es
3299 mov WORD PTR [REAL_INT_17
],bx
3300 mov dx,OFFSET CodeR
:INT_17
3302 mov ah,SET_INTERRUPT_VECTOR
3303 int 21h
;Set printer interrupt
3305 mov ah,GET_INTERRUPT_VECTOR
3307 mov WORD PTR [REAL_INT_14
+2],es
3308 mov WORD PTR [REAL_INT_14
],bx
3309 mov dx,OFFSET CodeR
:INT_14
3311 mov ah,SET_INTERRUPT_VECTOR
3312 int 21h
;Set RS232 port interrupt
3314 mov ah,GET_INTERRUPT_VECTOR
3316 mov WORD PTR [REAL_INT_5
+2],es
3317 mov WORD PTR [REAL_INT_5
],bx
3318 mov DX,OFFSET CodeR
:INT_5
3320 mov ah,SET_INTERRUPT_VECTOR
3321 int 21h
;Set print screen interrupt
3322 mov ah,GET_INDOS_FLAG
3327 mov WORD PTR [INDOS
+2],es ;Get indos flag location
3328 mov WORD PTR [INDOS
],bx
3330 mov ah,GET_INTERRUPT_VECTOR
3332 mov WORD PTR [NEXTINT
+2],es
3333 mov WORD PTR [NEXTINT
],bx
3335 mov al,REBOOT
; We also need to chain
3336 mov ah,GET_INTERRUPT_VECTOR
; Into the INT 19 sequence
3337 int 21h
; To properly "unhook"
3338 mov WORD PTR [NEXT_REBOOT
+2],es ; ourselves from the TimerTick
3339 mov WORD PTR [NEXT_REBOOT
],bx ; sequence
3343 je SET_HDSPINT
; No NETWORK, set hardware int
3344 test bx,0000000011000100B
3345 jnz NO_HDSPINT
; DO NOT set HDSPINT if RCV|MSG|SRV
3349 mov dx,OFFSET CodeR
:HDSPINT
3351 mov ah,SET_INTERRUPT_VECTOR
3352 int 21h
;Set hardware interrupt
3354 mov dx,OFFSET CodeR
:ReBtINT
3356 mov ah,SET_INTERRUPT_VECTOR
3357 int 21h
;Set bootstrap interrupt
3361 mov ax,(CLASS_B
shl 8) + GOODMES
; ;AC000;
3362 call GoDispMsg
; ;AC002;
3364 ;---------------------------------------
3366 ; Note: do not use stack, it may
3367 ; get trashed in move!
3368 ;---------------------------------------
3374 mov ax,OFFSET dg
:TransRet
3375 mov WORD PTR [ContTrans
],ax ; store return offset
3377 mov WORD PTR [ContTrans
+2],cx ; return segment
3379 add ax,[endres
] ; get start of moved transient, actually
3380 ; this is 100 bytes more than need be
3381 ; because of lack of pdb, but who cares?
3383 ; NOTE: The following $IF was added for
3384 ; DOS 4.0. For earlier versions,
3385 ; the transient would even be moved
3386 ; IN if required < available
3387 ; - this would now clobber the
3390 cmp ax,cx ; is required size > available size ?
3392 ; $if a ; if it is - move transient out
3395 mov WORD PTR [ContTrans
+2],ax ; return segment
3396 mov es,ax ; new location for dg group
3405 mov cx,OFFSET dg
:TransSize
3406 mov si,cx ; start from the bottom and move up
3409 rep movsb ; move all code, data and stack
3410 cld ; restore to expected setting...
3412 ;---------------------------------------
3413 ;--- normalize transient segment regs
3414 ;---------------------------------------
3417 sub ax,dg
; displacement
3419 add dx,ax ; displace stack segemnt
3425 ASSUME
DS:nothing
,ES:nothing
,SS:nothing
3427 jmp ContTrans
; back to the transient...