]> wirehaze git hosting - MS-DOS.git/blob - v4.0/src/CMD/MODE/RESCODE.ASM

wirehaze git hosting

MZ is back!
[MS-DOS.git] / v4.0 / src / CMD / MODE / RESCODE.ASM
1 PAGE ,132 ;\ f
2
3 TITLE CODE TO BE MADE RESIDENT BY MODE
4
5 .XLIST
6 INCLUDE STRUC.INC
7 .LIST
8 ;.SALL
9
10 ;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ P R O L O G ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» ;AN000;
11 ;º º ;AN000;
12 ;AN000;
13 ; AC000 - P2852: Infinite retry check at beginning of INT 14 handler was using
14 ; wrong bit pattern.
15
16 ; AC001 - P5148: retry_flag was addressing the wrong segment
17
18 ;º º ;AN000;
19 ;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ P R O L O G ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ ;AN000;
20 ;AN000;
21
22 ;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ M A C R O S ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
23 ;º º
24
25 DISPLAY MACRO MSG
26 MOV DX,OFFSET MSG
27 CALL PRINTF
28 ENDM
29
30 GET_INT_VECT MACRO INT_NO ;Input: "INT_NO" - the interrupt to be gotten
31 PUSH AX
32 MOV AL,INT_NO ;
33 MOV AH,35H ;FUNCTION CALL "GET VECTOR"
34 INT 21H ;Output: ES:BX = the address in the vector
35 POP AX
36 ENDM
37
38 SET MACRO REG,VALUE ;SET REG TO VALUE. DON'T SPECIFY AX FOR REG
39
40 PUSH AX
41 MOV AX,VALUE
42 MOV REG,AX
43 POP AX
44
45 ENDM
46
47 SET_INT_VECT MACRO INT_NO ;Input: "INT_NO" - the interrupt to be set
48 PUSH AX ; DS:DX = CS:IP value to set the interrupt to
49 MOV AL,INT_NO ;Output: the vector "INT_NO" contains DS:DX
50 MOV AH,25H ;function call "SET VECTOR"
51 INT 21H
52 POP AX
53 ENDM
54
55 store_vector MACRO dword_holder ;Input: "dword_holder" - where to store it
56 ; ES:BX - the address (vector) to be stored
57 MOV WORD PTR dword_holder,BX ;Output: "dword_holder"=the value passed in ES:BX
58 MOV WORD PTR dword_holder[2],ES
59
60 ENDM
61
62 ;º º
63 ;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ M A C R O S ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
64
65
66 ;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ E Q U A T E S ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
67 ;º º
68
69 ADJUSTMENT EQU (entpt - move_destination) ;# of bytes the resident code is moved
70 adjustment_in_paragraphs EQU (adjustment / 10H) ;# paragraphs the code moved
71 COM_status EQU 03 ;BIOS input for com status request ;AN001;
72 E EQU 1 ;value of "res_com_retry_type" for E retry requested ;AN001;
73 false EQU 0
74 framing_error EQU 0000100000000000B ;bit returned in AX from com status ;AN001;
75 holding_empty EQU 0010000000000000B ;bit returned in AX from com status ;AN001;
76 INT14 EQU 014H
77 INT17 EQU 017H
78 LPT_status EQU 02 ;value of AH for printer status checks ;AN000;
79 not_busy EQU 80H ;just the not busy bit on
80 overrun_error EQU 0000001000000000B ;bit returned in AX from com status ;AN001;
81 parity_error EQU 0000010000000000B ;bit returned in AX from com status ;AN001;
82 P14_model_byte EQU 0F9H ;P14's have a F9 at F000:FFFE
83 R EQU 3 ;value of "res_com_retry_type" for R retry requested ;AN001;
84 shift_empty EQU 0100000000000000B ;bit returned in AX from com status ;AN001;
85 time_out EQU 1000000000000000B ;time out bit returned in AX from com status ;AN001;
86 TO_SCREEN EQU 9 ;REQUEST OUTPUT TO SCREEN
87 TRUE EQU 0FFH
88 USER_ABORT EQU 00H
89
90 ;º º
91 ;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ E Q U A T E S ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
92
93
94 ;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ S T R U C T U R E S ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
95 ;º º
96
97
98 ;º º
99 ;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ S T R U C T U R E S ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
100
101
102 ROM SEGMENT AT 0F000H
103 ORG 0E739H
104 RS232 LABEL FAR
105 ORG 0EFD2H
106 PRINTER_IO LABEL FAR
107 ;NOTE: THE VALUES REPRESENTED BY THIS SEGMENT ARE NOT NECESSARILY
108 ; THE ONES USED BY THE SUBSEQUENT PROCEDURES. THESE HERE MERELY
109 ; SERVE AS SAMPLES. THE ACTUAL VALUES IN THE INSTRUCTIONS:
110 ; JMP RS232
111 ; JMP PRINTER_IO
112 ; WILL BE MOVED INTO THESE INSTRUCTIONS FROM THE VECTOR TABLE USING
113 ; THE THEN CURRENT VALUES OF INT 14H FOR RS232 AND OF INT 17H FOR
114 ; THE PRINTER_IO JUMP TARGETS. THIS IS TO ALLOW FOR SOME USER
115 ; TO HAVE INTERCEPTED THESE VECTORS AND DIRECTED THEIR REQUESTS TO
116 ; HIMSELF INSTEAD OF TO THE ROM.
117
118 ORG 0FFFEH
119 ;model_byte LABEL BYTE
120 ROM ENDS
121
122 VECT SEGMENT AT 0
123 ORG 50H
124 VECT14H LABEL DWORD ;RS232 CALL
125 ORG 5CH
126 VECT17H LABEL DWORD ;PRINTER I/O CALL
127 ORG 471H
128 BREAK_FLAG LABEL BYTE ;BREAK FLAG
129 BREAK_BIT EQU 80H ;ON=BREAK
130 ORG 530H
131 RESSEG LABEL DWORD ;VECTOR OF MODETO, INIT TO ZERO
132 VECT ENDS
133
134
135 ;****************************************************************
136 PRINTF_CODE SEGMENT PUBLIC
137 ASSUME CS:PRINTF_CODE,DS:PRINTF_CODE
138
139
140 ;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ E X T R N S ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
141 ;º º
142
143 EXTRN device_type:BYTE ;see parse.asm
144 EXTRN COMX:ABS ;see parse.asm
145 EXTRN LPTX:ABS ;see parse.asm
146 EXTRN MAIN:NEAR
147 EXTRN MOVED_MSG:WORD ;CR,LF,"Resident portion of MODE loaded",CR,LF,"$"
148 EXTRN busy_status:ABS ;value of lpt1_retry_type[BX] when user wants actual status, see modeprin
149 EXTRN PRINTF:NEAR ;interface to message retriever, see display.asm
150 EXTRN reroute_requested:BYTE ;see parse.asm
151 EXTRN retry_requested:BYTE ;see parse.asm
152
153 ;º º
154 ;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ E X T R N S ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
155
156
157
158 ;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ P U B L I C S ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
159 ;º º
160
161 PUBLIC first_char_in_command_line ;location of the command line parameters
162 PUBLIC FIXUP
163 PUBLIC lpt1_retry_type ;filled in and used to get at other two lpt retry masks in modeprin
164 PUBLIC rescode_length ;REFERENCED IN MAIN PROCEDURE
165 PUBLIC MODETO
166 PUBLIC move_destination ;location of the resident code after it has been moved
167 PUBLIC NEW_PTSFLAG ;RESIDENT THE FLAG WILL BE ACCESSABLE TO
168 PUBLIC NEW_SCRNTABL ;MODESCRN NEEDS TO KNOW WHERE IT WENT
169 PUBLIC OFFPTS ;USED IN MODEECHO TO ADDRESS MODEPTS
170 PUBLIC OFFRETRY
171 PUBLIC ptsflag1 ;make available to display_printer_reroute_status
172 PUBLIC P14_model_byte
173 PUBLIC res_com_retry_type
174 ;PUBLIC res_lpt_retry_type
175 PUBLIC resflag2 ;make available to display_printer_reroute_status
176 PUBLIC RES_MODEFLAG ; RESIDENT THE FLAG WILL BE ACCESSABLE
177 PUBLIC RESSEG ;SCRNTABL NEEDS TO FOLLOW THIS VECTOR TO ADDRESS VIDEO PARMS
178 PUBLIC SCRNTABL
179 PUBLIC submodel_byte ;holder for machine's secondary model byte
180 PUBLIC VECTOR14
181 PUBLIC VECTOR17
182
183 ;º º
184 ;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ P U B L I C S ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
185
186 ORG 2CH
187 environ_seg DW ? ;segment address of the environment, used as the block of memory to free so ;AN000;
188 ;environment is not part of resident code.
189
190 ORG 60H ;first usable byte of PSP. If you change this check the
191 ;calculation of paragraphs in 'main'
192
193 move_destination LABEL WORD ;where the resident will be moved to
194
195 ; THIS STRUCTURE DEFINES THE PROGRAM SEGMENT PREFIX AREA
196 ; POINTED TO BY THE ES REGISTER. THIS MUST BE DEFINED HERE, IT REPLACES THE
197 ; 'ORG 100'
198
199 ORG 80H
200 command_line_length DB ? ;not used, just place holder to allign next field
201 first_char_in_command_line LABEL BYTE ;location of the command line parameters
202 ;command_line DB 7FH DUP(?) ;PARM AREA
203
204 ORG 100H
205 ENTPT: JMP MAIN ;ENTRY POINT, START AT THE MAIN PROCEDURE
206 SUBTTL SERIAL RETRY
207 PAGE
208 ;THIS PROC WILL BE POINTED TO BY INT VECTOR 14H
209
210
211 MODETO PROC NEAR
212
213
214
215
216 PUSH CX
217 MOV CL,DL ;CL=DL=0,1,2 or 3
218 SHL CL,1 ;CL= 0, 2, 4 or 6 for COM 1,2,3 or 4 respectively ;AC000;
219 XOR CH,CH ;CH=0 ready for ANDing in the mask ;AC000;
220 OR CH,00000011B ;CH=00000011, mask for any type of retry, to be shifted into proper position ;AC000;
221 SHL CH,CL ;CH=00000011, 00001100, 00110000 or 11000000 for COM 1,2,3 or 4 respectively
222 AND CH,BYTE PTR CS:res_modeflag ;see if any bit is on for this COM port ;AC001;
223 MOV CS:retry_type,CX ;AC001; save for check after call to old INT 14 ;AN001;
224 POP CX
225 JNZ pushax
226
227
228
229
230
231 VECTOR14 LABEL WORD ;THE NEXT JMP INSTRUCTION HAS 5 BYTES,
232 ; THE LAST 4 ARE THE CONTENTS OF INT 14H,
233 ; WHICH NORMALLY POINTS TO THE ROM RS232
234 ; HANDLER. THE CODE GENERATED HERE BY THE
235 ; ASSEMBLER IS REPLACED BY THE ACTUAL
236 ; CONTENTS OF INT 14H.
237
238 TOROM:
239 JMP RS232 ;NO RETRY, GO DIRECTLY TO ROM ENTRY IRET from there
240 PUSHAX:
241 MOV CS:request,AH ;save request type
242 PUSH AX ;SAVE ENTRY PARAMETERS FOR LATER RETRY
243 PUSH DS ;SAVE REGS
244 PUSH AX ;SAVE REGS
245 SUB AX,AX ;POINT TO
246 MOV DS,AX ; PAGE ZERO
247 AND DS:BREAK_FLAG,0FFH-BREAK_BIT ;RESET BREAK FLAG
248 POP AX ;RESTORE
249 POP DS ; REGS
250 PUSHF ;SAVE FLAGS TO SIMULATE INT INSTRUCTION
251
252 VEC EQU (VECTOR14 +1) ;OFFSET TO IMMEDIATE FIELD OF PREVIOUSLY SET
253 ; FAR JMP INSTRUCTION, FILLED WITH THE
254 ; ORIGINAL CONTENTS OF THE INTERRUPT VECTOR
255 CALL DWORD PTR CS:VEC ;CALL PREVIOUS RS232 HANDLER
256 .IF <CS:request EQ COM_status> THEN ;IF a status request THEN ;AN001;
257 PUSH CX ;need CX for shift count in CL ;AN001;
258 MOV CX,CS:retry_type ;AC001; get back retry type for this port ;AN001;
259 SHR CH,CL ;put back in first two bits for retry type check below ;AN001;
260 .IF <CH EQ E> THEN ;AN001;
261 MOV AX,time_out+framing_error+parity_error+overrun_error ;indicate the port is on fire ;AN001;
262 .ELSEIF <CH EQ R> THEN ;AN001;
263 MOV AX,shift_empty+holding_empty+clear_to_send+data_set_ready ;indicate the port is ready ;AN001;
264 .ENDIF ;otherwise assume B retry and pass actual status ;AN001;
265 POP CX ;restore reg ;AN001;
266 .ELSE ;continue as if a send request ;AN001;
267 PUSH AX ;SAVE REGS
268 PUSH DS ; REGS
269 SUB AX,AX ;POINT TO
270 MOV DS,AX ; PAGE ZERO
271 TEST DS:BREAK_FLAG,BREAK_BIT ;TEST BREAK FLAG
272 POP DS ;RESTORE
273 POP AX ; REGS
274 JZ TESTER ;BRANCH IF NO BREAK
275 OR AH,80H ;SIMULATE TIMEOUT ERROR ON BREAK
276 .ENDIF ;ENDIF status request ;AN001;
277 FLUSH:
278 INC SP ;FLUSH THE
279 INC SP ; STACK
280 IRET ;RETURN
281 ;
282 TESTER:
283 TEST AH,80H ;TEST IF A REAL TIMEOUT
284 JZ FLUSH ;IF NOT, RETURN
285 POP AX ;RETRIEVE ORIGINAL ENTRY PARAMETERS
286 JMP PUSHAX ;DO RETRY
287 ;**********************************************************************
288 RES_MODEFLAG EQU $ ;WHEN THIS CODE IS RESIDENT THE FLAG WILL BE
289 ; ACCESSABLE BY MODECOM AS AN OFFSET FROM ADDRESS
290 ; POINTED TO BY VECT14H AND RESSEG
291 res_com_retry_type equ $
292
293 DB 0 ;AN665;no retry of any type active for any port
294 ;
295 ; bits comx 00=>no retry for any port
296 ; ---- ---- 01=>E for COM1, no retry for 2, 3 and 4
297 ; 0-1 com1 02=>B for COM1, no retry for 2, 3 and 4
298 ; 2-3 com2 03=>R for COM1, no retry for 2, 3 and 4
299 ; 4-5 com3 04=>E for COM2, no retry for 1, 3 and 4
300 ; 6-7 com4 05=>E for COM2, E for COM1, none for 3 and 4
301 ; 06=>E for COM2, B for COM1, none for 3 and 4
302 ; bit 07=>E for COM2, R for COM1, none for 3 and 4
303 ; pair 08=>B for COM2, none for 1, 3 and 4
304 ; value active 09=>B for COM2, E for COM1, none for 3 and 4
305 ; ----- ------ 0A=>B for COM2, B for COM1, none for 3 and 4
306 ; 0 unknown 0B=>B for COM2, R for COM1, none for 3 and 4
307 ; 1 E 0C=>R for COM2, no retry for 1, 3 and 4
308 ; 2 B 0D=>R for COM2, E for COM1, none for 3 and 4
309 ; 3 R 0E=>R for COM2, B for COM1, none for 3 and 4
310 ; 0F=>R for COM2, R for COM1, none for 3 and 4
311 ; 10=>E for COM3, none for 1, 2 and 4
312 ; etc.
313 MODETO ENDP
314 ;**************************************************************
315 SUBTTL DETERMINE PARALLEL TO SERIAL, OR PARALLEL TIMEOUT
316 PAGE
317 ;THIS PROC MAY BE POINTED TO BY INT VECTOR 17H
318 MODEPTS PROC NEAR
319 OFFPTS EQU MODEPTS - MODETO
320 TEST DL,1 ;DETERMINE IF REDIRECTION APPLIES
321 ; NOTE: THIS IMMEDIATE FIELD IS Revised BY MODE
322 ;
323 ;THIS NEXT JUMP INSTRUCTION IS Revised BY MODEECHO TO REFLECT WHICH
324 ;LPTN IS TO BE REDIRECTED TO WHICH COMM.
325 JNZ CK ;THIS JNZ IS Revised BY MODE
326 ;
327 ORG $-2
328 JZ CK ;IT MAY BE CHANGED TO THIS
329 ;
330 ORG $-2
331 JMP SHORT NOREDIRECT ; OR THIS...
332 ;
333 NOREDIRECT:
334 OFFRETRY EQU $ ;disp into resident code of retry flgs
335 ;THIS NEXT SECTION WILL TEST FOR THE OPTIONAL RETRY ON PARALLEL TIMEOUT.
336 TEST DL,1 ;TEST TO SEE IF PARALLEL RETRY IS ACTIVE
337 ;THIS NEXT JUMP INSTRUCTION IS Revised BY MODEPRIN TO REFLECT WHICH
338 ;LPT1n DEFICE IS TO BE RETRIED. IT WILL APPEAR IN SEVERAL FORMS:
339 JNZ PAR_RETRY ;THIS INSTRUCTION MAY BE Revised
340 ;
341 ORG $-2
342 JZ PAR_RETRY
343 ;
344 ORG $-2
345 JMP SHORT ASIS
346 ;
347 VECTOR17 LABEL WORD
348 ASIS: JMP PRINTER_IO ;NO REDIRECTION, GO DIRECTLY TO PREVIOUS INT 17H
349 ;**************************************************************
350 SUBTTL RETRY PARALLEL ON TIMEOUT.
351 PAGE
352 PAR_RETRY:
353 RT:
354 MOV CS:request,AH ;save the function requested for check after return from call to INT 17 ;AN000;
355 PUSH AX ;SAVE ENTRY PARAMETERS FOR LATER USE
356 PUSH DS ;SAVE CALLER'S REGS
357 PUSH AX ;SAVE REGS
358 ;
359 SUB AX,AX ;POINT TO PAGE ZERO
360 MOV DS,AX ; USING THE DATA SEG REG
361 ;
362 AND DS:BREAK_FLAG,0FFH-BREAK_BIT ;RESET BREAK FLAG
363 ;
364 POP AX ;RESTORE CALLER'S REGS
365 POP DS ;RESTORE REGS
366 PUSHF ;SAVE FLAGS TO SIMULATE INT INSTRUCTION
367 PVEC EQU VECTOR17+1 ;OFFSET TO IMMEDIATE FIELD OF PREVIOUSLY SET
368 ; FAR JUMP INSTRUCTION, FILLED WITH THE
369 ; ORIGINAL CONTENTS OF THE INT 17H VECTOR.
370 CALL DWORD PTR CS:PVEC ;CALL PREVIOUS PARALLEL PORT HANDLER
371 CMP CS:request,LPT_status ;AN000;
372 JNE init_or_write ;AN000;
373 TEST AH,not_busy ;see if the printer was busy (not busy bit off) ;AN000;
374 JNZ pflush ;IF busy dork the status byte ;AN000;
375 PUSH BX ;AN000;
376 MOV BX,DX ;BX=zero based printer number ;AN000;
377 CMP BYTE PTR CS:lpt1_retry_type[BX],busy_status ;IF status should be changed THEN ;AN000;
378 JZ dont_modify ;busy setting means user wants actual status ;AN000;
379 MOV AH,BYTE PTR CS:lpt1_retry_type[BX] ;change to status set by prior retry setting request for this LPT ;AN000;
380 dont_modify: ;AN000;
381 POP BX ;AN000;
382 JMP pflush ;return to caller ;AN000;
383 init_or_write: ;AN000;
384 PUSH AX ;SAVE RETURN CODE IN AH
385 PUSH DS ;SAVE DATA SEGMENT REG
386 ;
387 SUB AX,AX ;POINT TO
388 MOV DS,AX ; SEGMENT AT ZERO
389 ;
390 TEST DS:BREAK_FLAG,BREAK_BIT ;TEST BREAK FLAG BIT
391 POP DS ;RESTORE SEG REG
392 POP AX ;RESTORE RETURN CODE TO AH
393 JZ PTEST ;BRANCH IF NO BREAK REQUESTED
394 ;
395 OR AH,USER_ABORT ;SIMULATE TIMEOUT
396 PFLUSH:
397 INC SP ;FLUSH THE
398 INC SP ; STACK
399 IRET ;RETURN TO CALLER
400 ;
401 PTEST:
402 TEST AH,01H ;TEST IF A REAL PARALLEL TIMEOUT
403 JZ PFLUSH ;IF NOT, RETURN
404 POP AX ;RETRIEVE ORIGINAL ENTRY PARAMETERS
405 JMP RT ;DO RETRY
406 ;**************************************************************
407 SUBTTL REDIRECT PARALLEL I/O TO SERIAL
408 PAGE
409 CK:
410 FIXUP EQU CK - NOREDIRECT
411 CMP AH,1 ;CHECK FOR 'INITIALIZE' CODE
412 ; AH=0, PRINT THE CHAR IN AL
413 ; AH=1, INITIALIZE
414 ; AH=2, READ STATUS
415 JNZ PTCHR ;IT IS PRINT CHARACTER OR READ STATUS
416 ; SINCE IT IS 'INITIALIZE'
417 MOV AH,80H ;PASS BACK 'NOT BUSY' RETURN CODE FROM
418 ; AH=1, (INITIALIZE)
419 IRET
420 ;
421 PTCHR:
422 ; IT IS PRINT CHARACTER OR READ STATUS
423 PUSH BX ;SAVE THE
424 PUSH AX ; REGS
425 PUSH DX ;SAVE MORE REGS
426 MOV BX,OFFSET RESFLAG2 ;POINT AT PARALLEL TO SERIAL
427 ; CORRESPONDENCE TABLE IN RESIDENT CODE
428 ADD BX,DX ;INDEX USING PRINTER SELECTION (0,1,OR 2)
429 MOV DL,CS:[BX] ;GET CORRESPONDING SERIAL PORT SELECT
430 CMP AH,0 ;CHECK FOR 'PRINT CHAR' CODE
431 JZ SENDCHAR ; YES, PRINT CHAR
432 ; NO, MUST BE READ STATUS
433 MOV AH,3 ;SET TO INT 14 'READ STAT' ENTRY PT
434 INT 14H ;GO RS232 AND READ STATUS INTO AX
435 ;
436 ; AH HAS LINE STATUS:
437 ; IF TRANSFER HOLDING REG EMPTY, AND
438 ; IF TRANSMIT SHIFT REGISTER READY, THEN SERIAL PORT
439 ; NOT BUSY
440 CLEAR_TO_SEND EQU 10H
441 DATA_SET_READY EQU 20H ;DATA SET READY LINE HIGH
442 AND AL,CLEAR_TO_SEND+DATA_SET_READY ;SEE IF PRINTER HAS A CHANCE
443 ; $IF Z ;DSR and CTS low, so probably off or out of paper
444 JNZ $$IF1
445 MOV AH,29H ;PAR 'BUSY' 'OUT OF PAPER' 'I/O ERROR' 'TIME OUT'
446 ; $ELSE
447 JMP SHORT $$EN1
448 $$IF1:
449 CMP AL,CLEAR_TO_SEND+DATA_SET_READY
450 ; $IF E ;IF clear to send and dsta set ready THEN
451 JNE $$IF3
452 MOV AH,90H ;'NOT BUSY' 'SELECTED'
453 ; $ELSE ;ELSE clear to send high OR data set ready high
454 JMP SHORT $$EN3
455 $$IF3:
456 MOV AH,10H ;SET TO PARALLEL 'BUSY' 'SELECTED'
457 ; $ENDIF
458 $$EN3:
459 ; $ENDIF
460 $$EN1:
461 POP DX ;RESTORE REG
462 JMP SHORT POPPER ;RESTORE REGS AND EXIT
463 ;
464 SENDCHAR:
465 MOV AH,1 ;SET TO INT 14 'SEND CHAR' ENTRY PT
466 INT 14H ;GO RS232 SEND CHAR
467 ;
468 POP DX ;RESTORE REG
469 TEST AH,80H ;TEST IF TIMEOUT RS232 ERROR
470 MOV AH,90H ;SET UP NORMAL RETURN AS IF FROM PRINTER
471 ; THAT IS: PARALLEL 'NOT BUSY' 'SELECTED'
472 JZ POPPER ;IF NO ERROR
473 MOV AH,09H ;RESET AH TO PARALLEL TIMEOUT ERROR CODE
474 ; RET CODE='BUSY', 'I/O ERROR', 'TIMEOUT'
475 ; THE USUAL RETURN FROM A WRITE DATA
476 ; TO A PARALLEL PRINTER THAT IS OFFLINE
477 POPPER:
478 POP BX ;RETRIEVE ORIGINAL AX
479 MOV AL,BL ;RESTORE ORIGINAL AL VALUE LEAVING NEW AH
480 POP BX ;RESTORE BX
481 IRET ;RETURN
482
483 ;**********************************************************************
484 PAGE
485
486 PTSFLAG1 DB 0 ;FLAG FOR MODE COMMAND:
487
488 NEW_PTSFLAG EQU PTSFLAG1 - MODETO ;WHEN THIS CODE IS
489 ; RESIDENT THE FLAG WILL BE ACCESSABLE TO
490 ; MODEECHO AS AN OFFSET FROM ADDRESS
491 ; POINTED TO BY VECT14H AND RESSEG
492 ; 0=NO INTERCEPT
493 ; 1=INTERCEPT LPT1
494 ; 2=INTERCEPT LPT2
495 ; 3=INTERCEPT LPT1 AND LPT2
496 ; 4=INTERCEPT LPT3
497 ; 5=INTERCEPT LPT1 AND LPT3
498 ; 6=INTERCEPT LPT2 AND LPT3
499 ; 7=INTERCEPT LPT1, LPT2, AND LPT3
500 RESFLAG2 EQU $ ;WHERE PTSFLAG2 IS IN THE RESIDENT CODE
501 PTSFLAG2 DB 0 ;FLAG FOR MODE COMMAND:
502 ; LPT1 CORRESPONDENCE VALUE:
503 ; 0=COM1
504 ; 1=COM2
505 ; 2=COM3
506 ; 3=COM4
507 ;RESFLAG2 EQU (PTSFLAG2 - MODETO)+BASE ;WHERE PTSFLAG2
508 ; IS IN THE RESIDENT CODE
509 PTSFLAG3 DB 0 ;FLAG FOR MODE COMMAND:
510 ; LPT2 CORRESPONDENCE VALUE:
511 ; 0=COM1
512 ; 1=COM2
513 ; 2=COM3
514 ; 3=COM4
515 PTSFLAG4 DB 0 ;FLAG FORMODE COMMAND:
516 ; LPT3 CORRESPONDENCE VALUE:
517 ; 0=COM1
518 ; 1=COM2
519 ; 2=COM3
520 ; 3=COM4
521
522
523 lpt1_retry_type DB 0 ;holder of mask for status return byte ;AN000;
524 lpt2_retry_type DB 0 ;can be one of no_retry_flag, error_status, ;AN000;
525 lpt3_retry_type DB 0 ;busy_status or ready_status, see MODEPRIN ;AN000;
526
527 PUBLIC lpt1_retry_type
528
529
530 ;THE FOLLOWING AREA IS USED BY MODESCRN TO STORE THE VIDEO PARMS THAT
531 ;ALLOW FOR THE SHIFTING RIGHT OR LEFT OF THE SCREEN IMAGE.
532 SCRNTABL DB 16 DUP("PARM") ;64 BYTES OF SPACE
533 NEW_SCRNTABL EQU SCRNTABL - MODETO ;OFFSET INTO RESIDENT
534 ; CODE OF THE 64 BYTE SCREEN TABLE
535
536 request DB 0 ;holder for INT 14 or INT 17 request passed in AH
537 retry_type DW 0 ;holder for INT 14 retry type and shift count
538
539 MODEPTS ENDP
540
541 rescode_length equ (($ - entpt) / 16) + 1 ;length of resident code in paragraphs
542
543 MOVELEN EQU $ - entpt ;length of resident code in bytes
544
545
546 ;*******************************************************************************
547
548 SUBTTL LOAD THE RESIDENT PORTION OF MODE
549
550 PAGE
551
552
553 MODELOAD PROC NEAR
554 PUBLIC MODELOAD
555 ; GET THE CONTENTS OF INT VECTOR 14H
556 ; TO SEE IF THE RESIDENT CODE IS
557 ; ALREADY LOADED
558 ; SET UP REGS TO MOVE IT INTO PLACE
559 PUSH DS ;SAVE SEG REG
560 PUSH ES ;SAVE SEG REG
561 PUSH DI
562 PUSH SI ;SAVE FOR CALLING PROCEDURE
563 PUSH DX ;SAVE FOR CALLING PROCEDURE
564 PUSH AX ;SAVE FOR CALLING PROCEDURE
565 PUSH BX
566 MOV AX,0 ;GET THE PARAGRAPH NUMBER OF DESTINATION
567 MOV ES,AX ; TO THE EXTRA SEGMENT BASE
568 LES DI,ES:RESSEG ;GET POINTER TO RETRY CODE
569 ; IF THE CODE IS NOT ALREADY MOVED,
570 .IF <DI EQ 0> THEN NEAR ;AC000;IF nothing at 50:30 THEN code is not loaded
571 ;
572 ; SINCE CODE HAS NOT YET BEEN MOVED,
573 ; PATCH PROPER ADDRESSES INTO IT
574
575 ; .IF <retry_requested EQ true> AND ;AN000;
576 ; .IF <device_type EQ COMX> THEN ;AN000;
577 ;
578 ; XOR AX,AX
579 ; MOV ES,AX ;BACK TO THE VECTOR AT ZERO
580 ; MOV AX,WORD PTR ES:VECT14H ;GET THE VECTOR OF INT 14H
581 ; MOV VECTOR14+1,AX ; INTO CODE TO BE MOVED
582 ;
583 ; MOV AX,WORD PTR ES:VECT14H[2] ;MOVE REST OF VECTOR
584 ; MOV VECTOR14+3,AX
585 ;
586 ; .ENDIF ;AN000;
587 ;
588 ; .IF <device_type EQ LPTX> AND ;AN000;
589 ; .IF <retry_requested EQ true> OR ;AN000;
590 ; .IF <reroute_requested EQ true> THEN ;AN000;
591 ;
592 ; MOV AX,WORD PTR ES:VECT17H ;GET VECTOR OF INT 17H
593 ; MOV VECTOR17+1,AX ; INTO CODE TO BE MOVED
594 ;
595 ; MOV AX,WORD PTR ES:VECT17H[2] ;MOVE REST OF VECTOR
596 ; MOV VECTOR17+3,AX
597 ;
598 ; .ENDIF ;AN000;
599
600
601 PUSH ES ;SAVE POINTER TO VECTOR ZERO
602
603 ;Get and save previous interrupt handlers
604
605 get_int_vect 14H ;get vector of INT 17H, ES:BX=vector
606 MOV VECTOR14+1,BX ;put offset INTO CODE TO BE MOVED
607 MOV VECTOR14+3,ES ;save segment
608
609 get_int_vect 17H ;get vector of INT 17H, ES:BX=vector
610 MOV VECTOR17+1,BX ;put offset INTO CODE TO BE MOVED
611 MOV VECTOR17+3,ES ;save segment
612
613
614 MOV SI,OFFSET entpt ;WILL BE MOVED FROM HERE
615 MOV DI,OFFSET move_destination ;WILL BE MOVED TO HERE
616 MOV CX,MOVELEN ;NUMBER OF BYTES TO BE MOVED
617 PUSH CS ;GET SEGMENT OF PROGRAM HEADER
618 POP ES ; INTO ES, THE DESTINATION SEGMENT
619 CLD ;INCREMENT SI AND DI AFTER EACH BYTE IS MOVED
620 REP MOVSB ;MOVE CX BYTES FROM DS:SI TO ES:DI
621 POP ES
622
623
624 ;Put a pointer to the resident code 50:30 (0:530)
625
626 CLI ;DISABLE UNTIL VECTOR SET
627
628 MOV ES:WORD PTR resseg,OFFSET modeto ;offset of "modeto" in res code pointer
629 MOV AX,CS
630 SUB AX,adjustment_in_paragraphs ;adjust res CS by amount the code moved
631 MOV ES:WORD PTR resseg[2],AX ;store segment of res code in pointer
632
633 STI ;allow some interrupts
634
635 ;Set interrupts 14 and 17 to point to their respective handlers. AX has correct segment.
636
637 MOV DS,AX ;DS=resident code segment
638 MOV DX,OFFSET modeto ;DS:DX=> INT14 handler "modeto"
639 set_int_vect INT14
640
641 MOV DX,OFFSET modepts ;DS:DX=> INT17 handler "modepts"
642 set_int_vect INT17
643
644 MOV ES,CS:environ_seg ;ES=segment of the block to be returned
645 MOV AH,49H ;49 is the Free Allocated Memory function call
646 INT 21H ;free the environment
647
648 MOV BYTE PTR CS:1,27H ;SET EXIT TO REMAIN RESIDENT by dorking opcode in the PSP
649 ;
650 PUSH CS
651 POP DS ;"PRINTF" requires that DS be the segment containing the messages
652
653 DISPLAY MOVED_MSG ;"Resident portion of MODE loaded"
654 MOV BYTE PTR CS:LOADED_YET,1 ;SET FLAG TO INDICATE ABOVE MSG
655 ; HAS BEEN DISPLAYED
656 ; MODESCRN MAY NEED TO REPEAT MESSAGE
657 MOV stay_resident,true
658 .ENDIF ;AC000;END IS CODE ALREADY LOADED? TEST
659
660 POP BX
661 POP AX ;RESTORE FOR CALLING PROCEDURE
662 POP DX ;RESTORE FOR CALLING PROCEDURE
663 POP SI ;RESTORE FOR CALLING PROCEDURE
664 POP DI
665 POP ES ;RESTORE SEG REG
666 POP DS ;RESTORE SEG REG
667 RET
668 MODELOAD ENDP
669
670 ;************************************************************
671 SUBTTL COMMON PARMAMETER LIST AND WORKAREA
672 PAGE
673 ; THE FOLLOWING AREA IS USED TO STORE PARSED PARAMETER LIST, AND WORK STORAGE
674 ; USED BY OTHER MODULES
675
676 ;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ N O N R E S I D E N T D A T A ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
677 ;º º
678
679 CTRL_ST DB 5 DUP(24) ;PRINTER CONFIGURATION CONTROL STRING
680 PARM1 DB 10 DUP(0)
681 PARM2 DB -1 ;-1 INDICATES TO SERVER THAT THIS PARM IS UNCHANGED
682 PARM3 DB 0
683 MODE DB 0
684 FLAG DB 0
685 INDEX DW 00 ;REDIRECTED PRINTER NETWORK REDIRECTION LIST INDEX
686 IS_LOCAL DB TRUE ;INITIALIZE for MODEPRIN
687 LOADED_YET DB false
688 LOCAL_NAME DB 16 DUP(0) ;HOLDING AREA FOR GET ASSIGN LIST ENTRY CALL USE
689 machine_type DB 0FFH ;holder for the machine type
690 NOERROR DB TRUE ;INDICATE NO ERROR MESSAGES HAVE BEEN ISSUED YET
691 NEW_VIDEO_PARMS_OFFSET DW 090H ;OFFSET OF INIT TABLE FOR SCREEN SHIFTING
692 NEW_VIDEO_PARMS_SEGMENT DW 040H ;SEGMENT OF INIT TABLE FOR SCREEN SHIFTING
693 REMOTE_DEV DB 50 DUP(0) ;HOLDING AREA FOR GET ASSIGN LIST ENTRY CALL USE
694 stay_resident DB false ;boolean indicating should stay resident when terminate
695 submodel_byte DB 0FFH ;secondary model byte
696
697
698 ;º º
699 ;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ N O N R E S I D E N T D A T A ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
700
701
702 ;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ P U B L I C S ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
703 ;º º
704
705 PUBLIC PARM1,PARM2,PARM3,MODE,FLAG,CTRL_ST,INDEX,LOCAL_NAME,REMOTE_DEV ;AC000;
706 PUBLIC IS_LOCAL
707 PUBLIC LOADED_YET
708 PUBLIC machine_type ;holder for machine type, found in "main"
709 PUBLIC NOERROR
710 PUBLIC NEW_VIDEO_PARMS_OFFSET
711 PUBLIC NEW_VIDEO_PARMS_SEGMENT
712 PUBLIC stay_resident
713
714 ;º º
715 ;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ P U B L I C S ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
716
717 PRINTF_CODE ENDS
718 END ENTPT
719 \1a