summaryrefslogtreecommitdiff
path: root/v4.0/src/CMD/MODE/RESCODE.ASM
diff options
context:
space:
mode:
authorGravatar Mark Zbikowski2024-04-25 21:24:10 +0100
committerGravatar Microsoft Open Source2024-04-25 22:32:27 +0000
commit2d04cacc5322951f187bb17e017c12920ac8ebe2 (patch)
tree80ee017efa878dfd5344b44249e6a241f2a7f6e2 /v4.0/src/CMD/MODE/RESCODE.ASM
parentMerge pull request #430 from jpbaltazar/typoptbr (diff)
downloadms-dos-main.tar.gz
ms-dos-main.tar.xz
ms-dos-main.zip
MZ is back!HEADmain
Diffstat (limited to 'v4.0/src/CMD/MODE/RESCODE.ASM')
-rw-r--r--v4.0/src/CMD/MODE/RESCODE.ASM719
1 files changed, 719 insertions, 0 deletions
diff --git a/v4.0/src/CMD/MODE/RESCODE.ASM b/v4.0/src/CMD/MODE/RESCODE.ASM
new file mode 100644
index 0000000..ff55772
--- /dev/null
+++ b/v4.0/src/CMD/MODE/RESCODE.ASM
@@ -0,0 +1,719 @@
1 PAGE ,132 ;
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
25DISPLAY MACRO MSG
26 MOV DX,OFFSET MSG
27 CALL PRINTF
28 ENDM
29
30GET_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
38SET 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
45ENDM
46
47SET_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
55store_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
60ENDM
61
62;Ί Ί
63;ΘΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝ M A C R O S ΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΌ
64
65
66;ΙΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝ E Q U A T E S ΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝ»
67;Ί Ί
68
69ADJUSTMENT EQU (entpt - move_destination) ;# of bytes the resident code is moved
70adjustment_in_paragraphs EQU (adjustment / 10H) ;# paragraphs the code moved
71COM_status EQU 03 ;BIOS input for com status request ;AN001;
72E EQU 1 ;value of "res_com_retry_type" for E retry requested ;AN001;
73false EQU 0
74framing_error EQU 0000100000000000B ;bit returned in AX from com status ;AN001;
75holding_empty EQU 0010000000000000B ;bit returned in AX from com status ;AN001;
76INT14 EQU 014H
77INT17 EQU 017H
78LPT_status EQU 02 ;value of AH for printer status checks ;AN000;
79not_busy EQU 80H ;just the not busy bit on
80overrun_error EQU 0000001000000000B ;bit returned in AX from com status ;AN001;
81parity_error EQU 0000010000000000B ;bit returned in AX from com status ;AN001;
82P14_model_byte EQU 0F9H ;P14's have a F9 at F000:FFFE
83R EQU 3 ;value of "res_com_retry_type" for R retry requested ;AN001;
84shift_empty EQU 0100000000000000B ;bit returned in AX from com status ;AN001;
85time_out EQU 1000000000000000B ;time out bit returned in AX from com status ;AN001;
86TO_SCREEN EQU 9 ;REQUEST OUTPUT TO SCREEN
87TRUE EQU 0FFH
88USER_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
102ROM SEGMENT AT 0F000H
103 ORG 0E739H
104RS232 LABEL FAR
105 ORG 0EFD2H
106PRINTER_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
120ROM ENDS
121
122VECT SEGMENT AT 0
123 ORG 50H
124VECT14H LABEL DWORD ;RS232 CALL
125 ORG 5CH
126VECT17H LABEL DWORD ;PRINTER I/O CALL
127 ORG 471H
128BREAK_FLAG LABEL BYTE ;BREAK FLAG
129BREAK_BIT EQU 80H ;ON=BREAK
130 ORG 530H
131RESSEG LABEL DWORD ;VECTOR OF MODETO, INIT TO ZERO
132VECT ENDS
133
134
135;****************************************************************
136PRINTF_CODE SEGMENT PUBLIC
137 ASSUME CS:PRINTF_CODE,DS:PRINTF_CODE
138
139
140;ΙΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝ E X T R N S ΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝ»
141;Ί Ί
142
143EXTRN device_type:BYTE ;see parse.asm
144EXTRN COMX:ABS ;see parse.asm
145EXTRN LPTX:ABS ;see parse.asm
146EXTRN MAIN:NEAR
147EXTRN MOVED_MSG:WORD ;CR,LF,"Resident portion of MODE loaded",CR,LF,"$"
148EXTRN busy_status:ABS ;value of lpt1_retry_type[BX] when user wants actual status, see modeprin
149EXTRN PRINTF:NEAR ;interface to message retriever, see display.asm
150EXTRN reroute_requested:BYTE ;see parse.asm
151EXTRN 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
161PUBLIC first_char_in_command_line ;location of the command line parameters
162PUBLIC FIXUP
163PUBLIC lpt1_retry_type ;filled in and used to get at other two lpt retry masks in modeprin
164PUBLIC rescode_length ;REFERENCED IN MAIN PROCEDURE
165PUBLIC MODETO
166PUBLIC move_destination ;location of the resident code after it has been moved
167PUBLIC NEW_PTSFLAG ;RESIDENT THE FLAG WILL BE ACCESSABLE TO
168PUBLIC NEW_SCRNTABL ;MODESCRN NEEDS TO KNOW WHERE IT WENT
169PUBLIC OFFPTS ;USED IN MODEECHO TO ADDRESS MODEPTS
170PUBLIC OFFRETRY
171PUBLIC ptsflag1 ;make available to display_printer_reroute_status
172PUBLIC P14_model_byte
173PUBLIC res_com_retry_type
174;PUBLIC res_lpt_retry_type
175PUBLIC resflag2 ;make available to display_printer_reroute_status
176PUBLIC RES_MODEFLAG ; RESIDENT THE FLAG WILL BE ACCESSABLE
177PUBLIC RESSEG ;SCRNTABL NEEDS TO FOLLOW THIS VECTOR TO ADDRESS VIDEO PARMS
178PUBLIC SCRNTABL
179PUBLIC submodel_byte ;holder for machine's secondary model byte
180PUBLIC VECTOR14
181PUBLIC VECTOR17
182
183;Ί Ί
184;ΘΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝ P U B L I C S ΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΌ
185
186 ORG 2CH
187environ_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
193move_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
200command_line_length DB ? ;not used, just place holder to allign next field
201first_char_in_command_line LABEL BYTE ;location of the command line parameters
202;command_line DB 7FH DUP(?) ;PARM AREA
203
204 ORG 100H
205ENTPT: 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
211MODETO PROC NEAR
212
213
214
215
216PUSH CX
217MOV CL,DL ;CL=DL=0,1,2 or 3
218SHL CL,1 ;CL= 0, 2, 4 or 6 for COM 1,2,3 or 4 respectively ;AC000;
219XOR CH,CH ;CH=0 ready for ANDing in the mask ;AC000;
220OR CH,00000011B ;CH=00000011, mask for any type of retry, to be shifted into proper position ;AC000;
221SHL CH,CL ;CH=00000011, 00001100, 00110000 or 11000000 for COM 1,2,3 or 4 respectively
222AND CH,BYTE PTR CS:res_modeflag ;see if any bit is on for this COM port ;AC001;
223MOV CS:retry_type,CX ;AC001; save for check after call to old INT 14 ;AN001;
224POP CX
225JNZ pushax
226
227
228
229
230
231VECTOR14 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
238TOROM:
239 JMP RS232 ;NO RETRY, GO DIRECTLY TO ROM ENTRY IRET from there
240PUSHAX:
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
252VEC 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;
277FLUSH:
278 INC SP ;FLUSH THE
279 INC SP ; STACK
280 IRET ;RETURN
281;
282TESTER:
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;**********************************************************************
288RES_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
291res_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.
313MODETO ENDP
314;**************************************************************
315 SUBTTL DETERMINE PARALLEL TO SERIAL, OR PARALLEL TIMEOUT
316 PAGE
317;THIS PROC MAY BE POINTED TO BY INT VECTOR 17H
318MODEPTS PROC NEAR
319OFFPTS 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;
333NOREDIRECT:
334OFFRETRY 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;
347VECTOR17 LABEL WORD
348ASIS: JMP PRINTER_IO ;NO REDIRECTION, GO DIRECTLY TO PREVIOUS INT 17H
349;**************************************************************
350 SUBTTL RETRY PARALLEL ON TIMEOUT.
351 PAGE
352PAR_RETRY:
353RT:
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
367PVEC 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;
383init_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
396PFLUSH:
397 INC SP ;FLUSH THE
398 INC SP ; STACK
399 IRET ;RETURN TO CALLER
400;
401PTEST:
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
409CK:
410FIXUP 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;
421PTCHR:
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
440CLEAR_TO_SEND EQU 10H
441DATA_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;
464SENDCHAR:
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
477POPPER:
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;**********************************************************************
484PAGE
485
486PTSFLAG1 DB 0 ;FLAG FOR MODE COMMAND:
487
488NEW_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
500RESFLAG2 EQU $ ;WHERE PTSFLAG2 IS IN THE RESIDENT CODE
501PTSFLAG2 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
509PTSFLAG3 DB 0 ;FLAG FOR MODE COMMAND:
510; LPT2 CORRESPONDENCE VALUE:
511; 0=COM1
512; 1=COM2
513; 2=COM3
514; 3=COM4
515PTSFLAG4 DB 0 ;FLAG FORMODE COMMAND:
516; LPT3 CORRESPONDENCE VALUE:
517; 0=COM1
518; 1=COM2
519; 2=COM3
520; 3=COM4
521
522
523lpt1_retry_type DB 0 ;holder of mask for status return byte ;AN000;
524lpt2_retry_type DB 0 ;can be one of no_retry_flag, error_status, ;AN000;
525lpt3_retry_type DB 0 ;busy_status or ready_status, see MODEPRIN ;AN000;
526
527PUBLIC 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.
532SCRNTABL DB 16 DUP("PARM") ;64 BYTES OF SPACE
533NEW_SCRNTABL EQU SCRNTABL - MODETO ;OFFSET INTO RESIDENT
534; CODE OF THE 64 BYTE SCREEN TABLE
535
536request DB 0 ;holder for INT 14 or INT 17 request passed in AH
537retry_type DW 0 ;holder for INT 14 retry type and shift count
538
539MODEPTS ENDP
540
541rescode_length equ (($ - entpt) / 16) + 1 ;length of resident code in paragraphs
542
543MOVELEN 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
553MODELOAD 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
668MODELOAD 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
679CTRL_ST DB 5 DUP(24) ;PRINTER CONFIGURATION CONTROL STRING
680PARM1 DB 10 DUP(0)
681PARM2 DB -1 ;-1 INDICATES TO SERVER THAT THIS PARM IS UNCHANGED
682PARM3 DB 0
683MODE DB 0
684FLAG DB 0
685INDEX DW 00 ;REDIRECTED PRINTER NETWORK REDIRECTION LIST INDEX
686IS_LOCAL DB TRUE ;INITIALIZE for MODEPRIN
687LOADED_YET DB false
688LOCAL_NAME DB 16 DUP(0) ;HOLDING AREA FOR GET ASSIGN LIST ENTRY CALL USE
689machine_type DB 0FFH ;holder for the machine type
690NOERROR DB TRUE ;INDICATE NO ERROR MESSAGES HAVE BEEN ISSUED YET
691NEW_VIDEO_PARMS_OFFSET DW 090H ;OFFSET OF INIT TABLE FOR SCREEN SHIFTING
692NEW_VIDEO_PARMS_SEGMENT DW 040H ;SEGMENT OF INIT TABLE FOR SCREEN SHIFTING
693REMOTE_DEV DB 50 DUP(0) ;HOLDING AREA FOR GET ASSIGN LIST ENTRY CALL USE
694stay_resident DB false ;boolean indicating should stay resident when terminate
695submodel_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
705PUBLIC PARM1,PARM2,PARM3,MODE,FLAG,CTRL_ST,INDEX,LOCAL_NAME,REMOTE_DEV ;AC000;
706PUBLIC IS_LOCAL
707PUBLIC LOADED_YET
708PUBLIC machine_type ;holder for machine type, found in "main"
709PUBLIC NOERROR
710PUBLIC NEW_VIDEO_PARMS_OFFSET
711PUBLIC NEW_VIDEO_PARMS_SEGMENT
712PUBLIC stay_resident
713
714;Ί Ί
715;ΘΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝ P U B L I C S ΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΌ
716
717PRINTF_CODE ENDS
718 END ENTPT
719 \ No newline at end of file