|
|
1.1 root 1: page ,132
2: TITLE nmsghdr - near message handler and finder
3: ;***
4: ;nmsghdr.asm - near message handler and finder
5: ;
6: ; Copyright (c) 1986-1987, Microsoft Corporation. All rights reserved.
7: ;
8: ;Purpose:
9: ; Near message handler and finder.
10: ;
11: ;*******************************************************************************
12:
13:
14: ?DF= 1 ; this is special for c startup
15: include version.inc
16: ?PLM= 1 ; pascal calling conventions
17: .xlist
18: ifdef _QC ;[2] Move these includes out of version.inc
19: include \sl\qc\src\include\kernel.inc ;[2]
20: include \sl\qc\src\include\kmac.inc ;[2]
21: endif ;_QC ;[2]
22:
23: include cmacros.inc
24: include msdos.inc
25: .list
26:
27: createSeg _TEXT, code, word, public, CODE, <>
28:
29: createSeg _DATA, data, word, public, DATA, DGROUP
30:
31: createSeg HDR, nhdr, byte, public, MSG, DGROUP
32: createSeg MSG, nmsg, byte, public, MSG, DGROUP
33: createSeg PAD, npad, byte, common, MSG, DGROUP
34: createSeg EPAD, nepad, byte, common, MSG, DGROUP
35:
36: defGrp DGROUP ; define DGROUP
37:
38: codeOFFSET equ offset _TEXT:
39: dataOFFSET equ offset DGROUP:
40:
41:
42: sBegin nhdr
43: assumes ds,data
44:
45: db '<<NMSG>>'
46: stnmsg label byte
47:
48: sEnd
49:
50: sBegin npad
51: assumes ds,data
52:
53: dw -1 ; message padding marker
54:
55: sEnd
56:
57: sBegin nepad
58: assumes ds,data
59:
60: db -1
61:
62: sEnd
63:
64: ifdef _QC
65: sBegin data
66: externW __psp ; psp:0 (paragraph #)
67: sEnd data
68: endif ;_QC
69:
70:
71: sBegin code
72: assumes cs,code
73: assumes ds,data
74:
75: page
76: ;***
77: ;__NMSG_TEXT(messagenumber) - find message for given message number
78: ;
79: ;Purpose:
80: ; This routine returns a near pointer to the message associated with
81: ; messagenumber. If the message does not exist, then a 0 is returned.
82: ;
83: ifdef IBMC20
84: ; This routine reestablishes DS = ES = SS (DGROUP)
85: else
86: ; This routine assumes DS = DGROUP
87: endif ; IBMC20
88: ;
89: ;Entry:
90: ; ==PASCAL CALLING CONVENTIONS==
91: ; messagenumber = WORD message number of desired message
92: ;
93: ;Exit:
94: ; AX = pointer to message text or 0 if no message exists.
95: ;
96: ;Uses:
97: ;
98: ;Exceptions:
99: ;
100: ;*******************************************************************************
101:
102: cProc __NMSG_TEXT,<PUBLIC>,<si,di> ; pascal calling
103:
104: parmW msgt
105:
106: cBegin
107: ifdef _QC ;[X]
108: push ds ; assume that ds = DGROUP
109: pop es ; es = ds = DGROUP
110: mov dx,msgt ; dx = message number
111: mov si,dataOFFSET stnmsg ; start of messages in core
112: call tloop ; search for message
113: or ax,ax ; found one?
114: jnz done ; yes - exit
115:
116: ;
117: ; try finding message in user library
118: ;
119: push ds ; save DGROUP
120: mov ds,[__psp] ;
121: lds si,dword ptr ds:[PSP_UL_TERM_OFF] ; [X]
122: mov cx,ds ; is there a user lib?
123: or cx,si ;
124: jz nmsg2 ; no - skip to .exe
125:
126: lds si,ds:[si+28h] ;
127: push ds
128: pop es
129: call tloop ; search for message
130: or ax,ax ; found one?
131: jnz nmsg3 ; yes - clean it up correctly
132:
133: ;
134: ; try finding message in program-list.exe
135: ;
136: nmsg2:
137: pop ds ; restore DGROUP
138: push ds ; save DGROUP
139: mov ds,[__psp] ;
140: lds si,dword ptr ds:[PSP_EXE_TRM_OFF] ; [X]
141: mov cx,ds ; is there a user lib?
142: or cx,si ;
143: jz fail ; no - fail
144:
145: lds si,ds:[si+28h] ;
146: push ds
147: pop es
148: call tloop ; search for message
149: or ax,ax ; found one?
150: jz fail ; no - fail
151:
152: nmsg3:
153: pop ds ;
154: push ax ;
155: mov ax,es ;
156: mov dx,ds ;
157: sub ax,dx ;
158: mov cl,4 ;
159: shl ax,cl ;
160: pop bx ;
161: add ax,bx ;
162: push ds ;
163: pop es ;
164: jmp done ;
165:
166: fail:
167: pop ds ;
168: done:
169:
170:
171: else ;_QC ;[X]
172: ifdef IBMC20
173: mov ax,DGROUP
174: mov ds,ax ; ds = DGROUP (force it always)
175: endif ; IBMC20
176: push ds
177: pop es
178: mov dx,msgt ; dx = message number
179: mov si,dataOFFSET stnmsg ; start of near messages
180:
181: tloop:
182: lodsw ; ax = current message number
183: cmp ax,dx
184: je found ; found it - return address
185: inc ax
186: xchg ax,si
187: jz found ; at end and not found - return 0
188: xchg di,ax
189: xor ax,ax
190: mov cx,-1
191: repne scasb ; skip until 00
192: mov si,di
193: jmp tloop ; try next entry
194:
195: found:
196: xchg ax,si
197: endif ;_QC ;[X]
198: cEnd
199:
200: ifdef _QC
201: tloop:
202: lodsw ; ax = current message number
203: cmp ax,dx
204: je found ; found it - return address
205: inc ax
206: xchg ax,si
207: jz found ; at end and not found - return 0
208: xchg di,ax
209: xor ax,ax
210: mov cx,-1
211: repne scasb ; skip until 00
212: mov si,di
213: jmp tloop ; try next entry
214: found:
215: xchg ax,si
216: ret
217: endif ;_QC
218:
219: page
220: ;***
221: ;__NMSGWRITE(messagenumber) - writes message on stderr
222: ;
223: ;Purpose:
224: ; This routine writes the message associated with messagenumber
225: ; to stderr.
226: ;
227: ;Entry:
228: ; ==PASCAL CALLING CONVENTIONS==
229: ; messagenumber = WORD number of desired message
230: ;
231: ;Exit:
232: ;
233: ;Uses:
234: ;
235: ;Exceptions:
236: ;
237: ;*******************************************************************************
238:
239: cProc __NMSG_WRITE,<PUBLIC>,<di> ; pascal calling
240:
241: parmW msgw
242:
243: cBegin
244: push msgw
245: call __NMSG_TEXT ; find near text pointer
246: or ax,ax
247: jz nowrite ; don't write anything if not there
248:
249: xchg dx,ax ; ds:dx = string address
250: mov di,dx
251: xor ax,ax
252: mov cx,-1
253: repne scasb ; es = ds from __NMSG_TEXT
254: not cx
255: dec cx ; cx = string length
256: mov bx,2
257: ifdef _QC ;[1]
258: int 0f3h ;[1] Force Screen for QC
259: endif ;_QC
260: callos write
261:
262: nowrite:
263: cEnd
264:
265: sEnd
266:
267: end
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.