diff options
| author | 2024-04-25 21:24:10 +0100 | |
|---|---|---|
| committer | 2024-04-25 22:32:27 +0000 | |
| commit | 2d04cacc5322951f187bb17e017c12920ac8ebe2 (patch) | |
| tree | 80ee017efa878dfd5344b44249e6a241f2a7f6e2 /v4.0/src/CMD/COMMAND/TPRINTF.ASM | |
| parent | Merge pull request #430 from jpbaltazar/typoptbr (diff) | |
| download | ms-dos-main.tar.gz ms-dos-main.tar.xz ms-dos-main.zip | |
Diffstat (limited to 'v4.0/src/CMD/COMMAND/TPRINTF.ASM')
| -rw-r--r-- | v4.0/src/CMD/COMMAND/TPRINTF.ASM | 365 |
1 files changed, 365 insertions, 0 deletions
diff --git a/v4.0/src/CMD/COMMAND/TPRINTF.ASM b/v4.0/src/CMD/COMMAND/TPRINTF.ASM new file mode 100644 index 0000000..c502f83 --- /dev/null +++ b/v4.0/src/CMD/COMMAND/TPRINTF.ASM | |||
| @@ -0,0 +1,365 @@ | |||
| 1 | page 80,132 | ||
| 2 | ; SCCSID = @(#)tprintf.asm 4.3 85/07/02 | ||
| 3 | ; SCCSID = @(#)tprintf.asm 4.3 85/07/02 | ||
| 4 | TITLE COMMAND Transient Printf routine | ||
| 5 | |||
| 6 | ;**************************************************************** | ||
| 7 | ;* | ||
| 8 | ;* ROUTINE: STD_PRINTF/STD_EPRINTF | ||
| 9 | ;* | ||
| 10 | ;* FUNCTION: Set up to print out a message using SYSDISPMSG. | ||
| 11 | ;* Set up substitutions if utility message. Make | ||
| 12 | ;* sure any changes to message variables in TDATA | ||
| 13 | ;* are reset to avoid reloading the transient. | ||
| 14 | ;* | ||
| 15 | ;* INPUT: Msg_Disp_Class - set to message class | ||
| 16 | ;* Msg_Cont_Flag - set to control flags | ||
| 17 | ;* DS points to transient segment | ||
| 18 | ;* | ||
| 19 | ;* if utility message: | ||
| 20 | ;* DX points to a block with message number | ||
| 21 | ;* (word), number of substitutions (byte), | ||
| 22 | ;* followed by substitution list if there | ||
| 23 | ;* are substitutions. If substitutions | ||
| 24 | ;* are not in transient segment they must | ||
| 25 | ;* be set. | ||
| 26 | ;* else | ||
| 27 | ;* AX set to message number | ||
| 28 | ;* | ||
| 29 | ;* OUTPUT: none | ||
| 30 | ;* | ||
| 31 | ;**************************************************************** | ||
| 32 | |||
| 33 | .xlist | ||
| 34 | .xcref | ||
| 35 | INCLUDE comsw.asm ;AC000; | ||
| 36 | INCLUDE DOSSYM.INC | ||
| 37 | INCLUDE comseg.asm | ||
| 38 | INCLUDE comequ.asm ;AN000; | ||
| 39 | INCLUDE SYSMSG.INC ;AN000; | ||
| 40 | .list | ||
| 41 | .cref | ||
| 42 | |||
| 43 | datares segment public | ||
| 44 | extrn pipeflag:byte | ||
| 45 | datares ends | ||
| 46 | |||
| 47 | TRANDATA SEGMENT PUBLIC BYTE ;AC000; | ||
| 48 | EXTRN extend_buf_off:word ;AN000; | ||
| 49 | EXTRN Extend_Buf_ptr:word ;AN000; | ||
| 50 | EXTRN Extend_Buf_seg:word ;AN000; | ||
| 51 | EXTRN Msg_Cont_Flag:byte ;AN000; | ||
| 52 | EXTRN Msg_disp_Class:byte ;AN000; | ||
| 53 | EXTRN pipeemes_ptr:word | ||
| 54 | TRANDATA ENDS | ||
| 55 | |||
| 56 | TRANSPACE SEGMENT PUBLIC BYTE ;AC000; | ||
| 57 | EXTRN msg_flag:byte ;AN022; | ||
| 58 | EXTRN print_err_flag:word ;AN000; | ||
| 59 | EXTRN RESSEG:WORD | ||
| 60 | EXTRN String_ptr_2:word ;AC000; | ||
| 61 | EXTRN Subst_buffer:byte ;AN061; | ||
| 62 | ;AD061; EXTRN String_ptr_2_sb:word ;AN000; | ||
| 63 | |||
| 64 | ; include data area for message services | ||
| 65 | |||
| 66 | MSG_UTILNAME <COMMAND> ;AN000; define utility name | ||
| 67 | |||
| 68 | MSG_SERVICES <MSGDATA> ;AN000; | ||
| 69 | |||
| 70 | PRINTF_HANDLE DW ? ;AC000; | ||
| 71 | |||
| 72 | TRANSPACE ENDS ;AC000; | ||
| 73 | |||
| 74 | TRANCODE SEGMENT PUBLIC BYTE ;AC000; | ||
| 75 | |||
| 76 | EXTRN cerror:near | ||
| 77 | EXTRN crlf2:near | ||
| 78 | EXTRN tcommand:near ;AN026; | ||
| 79 | |||
| 80 | ASSUME CS:TRANGROUP,DS:TRANGROUP,ES:NOTHING,SS:NOTHING ;AC000; | ||
| 81 | |||
| 82 | PUBLIC SETSTDINOFF ;AN026; | ||
| 83 | PUBLIC SETSTDINON ;AN026; | ||
| 84 | PUBLIC SETSTDOUTOFF ;AN026; | ||
| 85 | PUBLIC SETSTDOUTON ;AN026; | ||
| 86 | PUBLIC TSYSGETMSG ;AN000; | ||
| 87 | PUBLIC TSYSLOADMSG ;AN000; | ||
| 88 | |||
| 89 | PUBLIC Printf_Init | ||
| 90 | printf_init proc far | ||
| 91 | call std_printf | ||
| 92 | ret | ||
| 93 | printf_init endp | ||
| 94 | |||
| 95 | Public Printf_Crlf | ||
| 96 | PRINTF_CRLF: | ||
| 97 | CALL STD_PRINTF | ||
| 98 | CALL CRLF2 | ||
| 99 | RET | ||
| 100 | |||
| 101 | PUBLIC Std_EPrintf | ||
| 102 | STD_EPRINTF: | ||
| 103 | mov Printf_Handle,2 ;AC000;Print to STDERR | ||
| 104 | jmp short NEW_PRINTF ;AC000; | ||
| 105 | PUBLIC Std_Printf | ||
| 106 | STD_PRINTF: | ||
| 107 | mov Printf_Handle,1 ;AC000;Print to STDOUT | ||
| 108 | |||
| 109 | NEW_PRINTF: | ||
| 110 | push ax ;AN000;save registers | ||
| 111 | push bx ;AN000; | ||
| 112 | push cx ;AN000; | ||
| 113 | push es ;AN000;get local ES | ||
| 114 | push ds ;AN000; | ||
| 115 | pop es ;AN000; | ||
| 116 | push di ;AN000; | ||
| 117 | push si ;AN000; | ||
| 118 | push dx ;AN000; | ||
| 119 | assume es:trangroup ;AN000; | ||
| 120 | ;AD061; mov string_ptr_2_sb,0 ;AN000;initialize | ||
| 121 | mov print_err_flag,0 ;AN000; | ||
| 122 | |||
| 123 | UTILITY_SETUP: | ||
| 124 | mov si,dx ;AN000;Get offset of message number | ||
| 125 | lodsw ;AN000;load message number | ||
| 126 | push ax ;AN000;save it | ||
| 127 | lodsb ;AN000;get number of substitutions | ||
| 128 | mov cl,al ;AN000;set up CX as # of subst | ||
| 129 | xor ch,ch ;AN000; SI now points to subst list | ||
| 130 | pop ax ;AN000;get message number back | ||
| 131 | cmp cx,0 ;AN000;Any substitutions? | ||
| 132 | jz READY_TO_PRINT ;AN000;No - continue | ||
| 133 | |||
| 134 | ;AD061; add dx,Ptr_Seg_Pos ;AN000;Point to position of first segment | ||
| 135 | ;AD061; push cx ;AN000;save substitution count | ||
| 136 | |||
| 137 | ;AD061;SET_SUBST: | ||
| 138 | ;AD061; mov bx,dx ;AN000;get dx into base register | ||
| 139 | ;AD061; cmp word ptr [bx],0 ;AN000;has segment been set? | ||
| 140 | ;AD061; jnz SUBST_SEG_SET ;AN000;if not 0, don't replace it | ||
| 141 | ;AD061; test word ptr [bx+3],date_type ;AN000;if date or time - don't set segment | ||
| 142 | ;AD061; jnz subst_seg_set ;AN000;yes - skip it | ||
| 143 | ;AD061; mov word ptr [bx],cs ;AN000;put segment of subst parm in list | ||
| 144 | |||
| 145 | ;AD061;SUBST_SEG_SET: | ||
| 146 | ;AD061; add dx,Parm_Block_Size ;AN000;point to position of next segment | ||
| 147 | ;AD061; loop SET_SUBST ;AN000;keep replacing until complete | ||
| 148 | ;AD061; pop cx ;AN000; | ||
| 149 | |||
| 150 | ;AD061;NO_REPLACEMENT: | ||
| 151 | ;AD061; mov bx,parm_off_pos [si] ;AN000;get subst offset | ||
| 152 | ;AD061; cmp bx,offset trangroup:string_ptr_2 ;AN000;this is used for double indirection | ||
| 153 | ;AD061; jnz ready_to_print ;AN000;we already have address | ||
| 154 | ;AD061; mov dx,string_ptr_2 ;AN000;get address in string_ptr_2 | ||
| 155 | ;AD061; mov parm_off_pos [si],dx ;AN000;put proper address in table | ||
| 156 | ;AD061; mov string_ptr_2_sb,si ;AN000;save block changed | ||
| 157 | |||
| 158 | mov di,offset trangroup:subst_buffer;AN061; Get address of message subst buffer | ||
| 159 | push di ;AN061; save it | ||
| 160 | push cx ;AN061; save number of subst | ||
| 161 | |||
| 162 | MOVE_SUBST: | ||
| 163 | push cx ;AN061;save number of subst | ||
| 164 | mov bx,si ;AN061;save start of sublist | ||
| 165 | mov cx,parm_block_size ;AN061;get size of sublist | ||
| 166 | rep movsb ;AN061;move sublist | ||
| 167 | test byte ptr [bx.$M_S_FLAG],date_type ;AN061;are we doing date/time? | ||
| 168 | jz move_subst_cont ;AN061;no - no need to reset | ||
| 169 | mov word ptr [bx.$M_S_VALUE],0 ;AN061;reset original date or time to 0 | ||
| 170 | mov word ptr [bx.$M_S_VALUE+2],0 ;AN061; | ||
| 171 | |||
| 172 | MOVE_SUBST_CONT: ;AN061; | ||
| 173 | pop cx ;AN061;get number of subst back | ||
| 174 | loop move_subst ;AN061;move cx sublists | ||
| 175 | |||
| 176 | pop cx ;AN061;get number of subst | ||
| 177 | push ax ;AN061;save message number | ||
| 178 | cmp Msg_Disp_Class,Util_Msg_Class ;AN061;Is this a utility message | ||
| 179 | jz CHECK_FIX ;AN061;YES - go see if substitutions | ||
| 180 | mov msg_flag,ext_msg_class ;AN061;set message flag | ||
| 181 | mov di,offset trangroup:extend_buf_ptr ;AN061; Get address of extended message block | ||
| 182 | xor ax,ax ;AN061;clear ax register | ||
| 183 | stosw ;AN061;clear out message number | ||
| 184 | stosb ;AN061;clear out subst count | ||
| 185 | |||
| 186 | CHECK_FIX: ;AN061; | ||
| 187 | pop ax ;AN061;get message number back | ||
| 188 | pop di ;AN061;get start of sublists | ||
| 189 | mov si,di ;AN061;get into SI for msgserv | ||
| 190 | mov bx,si ;AN061;get into BX for addressing | ||
| 191 | push cx ;AN061;save number of subst | ||
| 192 | |||
| 193 | SET_SUBST: ;AN061;store the segment of the subst | ||
| 194 | cmp word ptr [bx.$M_S_VALUE+2],0 ;AN061;was it set already? | ||
| 195 | jnz subst_seg_set ;AN061;if not 0, don't replace it | ||
| 196 | test byte ptr [bx.$M_S_FLAG],date_type ;AN061;don't replace if date or time | ||
| 197 | jnz subst_seg_set ;AN061;yes - skip it | ||
| 198 | mov word ptr [bx.$M_S_VALUE+2],cs ;AN061;set segment value | ||
| 199 | |||
| 200 | SUBST_SEG_SET: ;AN061; | ||
| 201 | add bx,parm_block_size ;AN061;go to next sublist | ||
| 202 | loop set_subst ;AN061;loop CX times | ||
| 203 | pop cx ;AN061;get number of subst back | ||
| 204 | |||
| 205 | mov bx,si ;AN061;get start of sublist to BX | ||
| 206 | cmp word ptr [bx.$M_S_VALUE],offset trangroup:string_ptr_2 ;AN061;are we using double indirection? | ||
| 207 | jnz ready_to_print ;AN061;no - we already have address | ||
| 208 | mov dx,string_ptr_2 ;AN061;get address in string_ptr_2 | ||
| 209 | mov word ptr [bx.$M_S_VALUE],dx ;AN061;put it into the subst block | ||
| 210 | |||
| 211 | READY_TO_PRINT: | ||
| 212 | mov bx,Printf_Handle ;AN000;get print handle | ||
| 213 | mov dl,Msg_Cont_Flag ;AN000;set up control flag | ||
| 214 | mov dh,Msg_Disp_Class ;AN000;set up display class | ||
| 215 | mov Msg_Cont_Flag,No_Cont_Flag ;AN061;reset flags to avoid | ||
| 216 | mov Msg_Disp_Class,Util_Msg_Class ;AN061; transient reload | ||
| 217 | |||
| 218 | ;AD061; push bx ;AN026; save registers | ||
| 219 | ;AD061; push cx ;AN026; | ||
| 220 | ;AD061; push dx ;AN026; | ||
| 221 | ;AD061; push si ;AN026; | ||
| 222 | ;AD061; push di ;AN026; | ||
| 223 | push ds ;AN026; | ||
| 224 | push es ;AN026; | ||
| 225 | |||
| 226 | |||
| 227 | call SYSDISPMSG ;AN000;call Rod | ||
| 228 | |||
| 229 | pop es ;AN026; restore registers | ||
| 230 | pop ds ;AN026; | ||
| 231 | ;AD061; pop di ;AN026; | ||
| 232 | ;AD061; pop si ;AN026; | ||
| 233 | ;AD061; pop dx ;AN026; | ||
| 234 | ;AD061; pop cx ;AN026; | ||
| 235 | ;AD061; pop bx ;AN026; | ||
| 236 | |||
| 237 | jnc Print_success ;AN000; everything went okay | ||
| 238 | mov print_err_flag,ax ;AN000; | ||
| 239 | |||
| 240 | print_success: | ||
| 241 | ;AD061; cmp Msg_Disp_Class,Util_Msg_Class ;AN000;Is this a utility message | ||
| 242 | ;AD061; jz CHECK_FIX ;AN000;YES - go see if substitutions | ||
| 243 | ;AD061; mov msg_flag,ext_msg_class ;AN022;set message flag | ||
| 244 | ;AD061; mov di,offset trangroup:extend_buf_ptr ;AN000; Get address of extended message block | ||
| 245 | ;AD061; xor ax,ax ;AN000;clear ax register | ||
| 246 | ;AD061; stosw ;AN000;clear out message number | ||
| 247 | ;AD061; stosb ;AN000;clear out subst count | ||
| 248 | |||
| 249 | ;AD061; CHECK_FIX: | ||
| 250 | ;AD061; pop dx ;AN000;restore dx | ||
| 251 | ;AD061; cmp cx,0 ;AN000;Any substitutions? | ||
| 252 | ;AD061; jz NO_FIXUP ;AN000;No - leave | ||
| 253 | |||
| 254 | ;AD061; mov si,dx ;AN000;Reset changes so transient won't reload | ||
| 255 | ;AD061; add si,Ptr_Seg_Pos ;AN000;Point to position of first segment | ||
| 256 | |||
| 257 | ;AD061;FIX_SUBST: | ||
| 258 | ;AD061; mov word ptr [si],0 ;AN000;reset segment to 0 | ||
| 259 | ;AD061; add si,Parm_Block_Size ;AN000;point to position of next segment | ||
| 260 | ;AD061; loop FIX_SUBST ;AN000;keep replacing until complete | ||
| 261 | ;AD061; cmp string_ptr_2_sb,no_subst ;AN000;was double indirection used? | ||
| 262 | ;AD061; jz no_fixup ;AN000;no - we're finished | ||
| 263 | ;AD061; mov si,string_ptr_2_sb ;AN000;get offset changed | ||
| 264 | ;AD061; mov parm_off_pos [si],offset trangroup:string_ptr_2 ;AN000; set address back to string_ptr_2 | ||
| 265 | |||
| 266 | ;AD061;NO_FIXUP: | ||
| 267 | ;AD061; mov Msg_Cont_Flag,No_Cont_Flag ;AN000;reset flags to avoid | ||
| 268 | ;AD061; mov Msg_Disp_Class,Util_Msg_Class ;AN000; transient reload | ||
| 269 | pop dx ;AN061;restore dx | ||
| 270 | pop si ;AN000;restore registers | ||
| 271 | pop di ;AN000; | ||
| 272 | pop es ;AN000;restore registers | ||
| 273 | pop cx ;AN000; | ||
| 274 | pop bx ;AN000; | ||
| 275 | pop ax ;AN000; | ||
| 276 | cmp print_err_flag,0 ;AN000; if an error occurred - handle it | ||
| 277 | jnz print_err ;AN000; | ||
| 278 | |||
| 279 | ret ;AC000; | ||
| 280 | |||
| 281 | print_err: | ||
| 282 | push cs | ||
| 283 | pop es | ||
| 284 | cmp Printf_Handle,2 ;AN026;Print to STDERR? | ||
| 285 | jnz not_stderr ;AN026;no - continue | ||
| 286 | jmp tcommand ;AN026;Yes - hopless - just exit | ||
| 287 | |||
| 288 | not_stderr: | ||
| 289 | mov ax,print_err_flag ;AN026;get extended error number back | ||
| 290 | mov es,[resseg] ; No, set up for error, load the | ||
| 291 | assume es:resgroup ; right error msg, and jmp to cerror. | ||
| 292 | test PipeFlag,-1 | ||
| 293 | jz go_to_error | ||
| 294 | invoke PipeOff | ||
| 295 | mov dx,offset trangroup:pipeemes_ptr | ||
| 296 | jmp print_err_exit ;AC000; | ||
| 297 | |||
| 298 | go_to_error: | ||
| 299 | mov msg_disp_class,ext_msg_class ;AN000; set up extended error msg class | ||
| 300 | mov dx,offset TranGroup:Extend_Buf_ptr ;AC000; get extended message pointer | ||
| 301 | mov Extend_Buf_ptr,ax ;AN000; get message number in control block | ||
| 302 | |||
| 303 | PRINT_ERR_EXIT: ;AC000; | ||
| 304 | push cs | ||
| 305 | pop es | ||
| 306 | JMP CERROR | ||
| 307 | |||
| 308 | ;**************************************************************** | ||
| 309 | ;* | ||
| 310 | ;* ROUTINE: TSYSLOADMSG | ||
| 311 | ;* | ||
| 312 | ;* FUNCTION: Interface to call SYSLOADMSG to avoid duplicate | ||
| 313 | ;* names since these routines are also used in the | ||
| 314 | ;* resident. | ||
| 315 | ;* | ||
| 316 | ;* INPUT: Inputs to SYSLOADMSG | ||
| 317 | ;* | ||
| 318 | ;* OUTPUT: Outputs from SYSLOADMSG | ||
| 319 | ;* | ||
| 320 | ;**************************************************************** | ||
| 321 | |||
| 322 | |||
| 323 | TSYSLOADMSG PROC NEAR ;AN000; | ||
| 324 | |||
| 325 | push bx ;AN000; | ||
| 326 | call sysloadmsg ;AN000; call routine | ||
| 327 | pop bx ;AN000; | ||
| 328 | ret ;AN000; exit | ||
| 329 | |||
| 330 | TSYSLOADMSG ENDP ;AN000; | ||
| 331 | |||
| 332 | ;**************************************************************** | ||
| 333 | ;* | ||
| 334 | ;* ROUTINE: TSYSGETMSG | ||
| 335 | ;* | ||
| 336 | ;* FUNCTION: Interface to call SYSGETMSG to avoid duplicate | ||
| 337 | ;* names since these routines are also used in the | ||
| 338 | ;* resident. | ||
| 339 | ;* | ||
| 340 | ;* INPUT: Inputs to SYSGETMSG | ||
| 341 | ;* | ||
| 342 | ;* OUTPUT: Outputs from SYSGETMSG | ||
| 343 | ;* | ||
| 344 | ;**************************************************************** | ||
| 345 | |||
| 346 | |||
| 347 | TSYSGETMSG PROC NEAR ;AN000; | ||
| 348 | |||
| 349 | push cx ;AN000; | ||
| 350 | call sysgetmsg ;AN000; call routine | ||
| 351 | pop cx ;AN000; | ||
| 352 | ret ;AN000; exit | ||
| 353 | |||
| 354 | TSYSGETMSG ENDP ;AN000; | ||
| 355 | |||
| 356 | MSG_SERVICES <COMT,NOVERCHECKmsg,NEARmsg,LOADmsg,NOCHECKSTDIN,NOCHECKSTDOUT,GETmsg> ;AC026; The message services | ||
| 357 | MSG_SERVICES <COMT,NEARmsg,SETSTDIO,DISPLAYmsg,CHARmsg,NUMmsg,TIMEmsg,DATEmsg> ;AC026; The message services | ||
| 358 | |||
| 359 | PRINTF_LAST LABEL WORD | ||
| 360 | |||
| 361 | include msgdcl.inc | ||
| 362 | |||
| 363 | |||
| 364 | TRANCODE ENDS | ||
| 365 | END | ||