diff options
Diffstat (limited to 'v4.0/src/CMD/SORT/SORT.ASM')
| -rw-r--r-- | v4.0/src/CMD/SORT/SORT.ASM | 1000 |
1 files changed, 1000 insertions, 0 deletions
diff --git a/v4.0/src/CMD/SORT/SORT.ASM b/v4.0/src/CMD/SORT/SORT.ASM new file mode 100644 index 0000000..0a60eb8 --- /dev/null +++ b/v4.0/src/CMD/SORT/SORT.ASM | |||
| @@ -0,0 +1,1000 @@ | |||
| 1 | TITLE SORT FILTER FOR DOS | ||
| 2 | PAGE ,132 ; | ||
| 3 | ;********************************************************** | ||
| 4 | ;* | ||
| 5 | ;* UTILITY NAME: sort | ||
| 6 | ;* | ||
| 7 | ;* SOURCE FILE NAME: sort.asm | ||
| 8 | ;* | ||
| 9 | ;* UTILITY FUNCTION: | ||
| 10 | ;* | ||
| 11 | ;* External non-resident utility, written in Assembler. | ||
| 12 | ;* Reads from the standard input device until end-of-file, | ||
| 13 | ;* sorts the data (up to 64k) and writes the results to | ||
| 14 | ;* the standard output device. Input and output can be | ||
| 15 | ;* redirected. | ||
| 16 | ;* | ||
| 17 | ;* INPUT (Command line) | ||
| 18 | ;* | ||
| 19 | ;* SORT [/R] [/+ n] | ||
| 20 | ;* | ||
| 21 | ;* /R - Sort in reverse order | ||
| 22 | ;* /+n - Start sorting in column "n" , default 1 | ||
| 23 | ;* | ||
| 24 | ;* OUTPUT: | ||
| 25 | ;* Sorted data will be written to the standard output device. | ||
| 26 | ;* | ||
| 27 | ;* ERROR CONDITIONS: | ||
| 28 | ;* Incorrect DOS version | ||
| 29 | ;* Insufficient disk space on target | ||
| 30 | ;* Insufficient memory to allocate SORT buffer | ||
| 31 | ;* Invalid parameter | ||
| 32 | ;* | ||
| 33 | ;* INTERNAL REFERENCES: | ||
| 34 | ;* Main | ||
| 35 | ;* | ||
| 36 | ;* SOURCE HISTORY: | ||
| 37 | ;* Modification History: | ||
| 38 | ;* 3-18-83 MZ (Microsoft) | ||
| 39 | ;* Fix CR-LF at end of buffer | ||
| 40 | ;* Fix small file sorting | ||
| 41 | ;* Fix CR-LF line termination bug | ||
| 42 | ;* Comment the Damn source | ||
| 43 | ;* | ||
| 44 | ;* 6-23-86 RW (IBM) | ||
| 45 | ;* Add DOS 3.30 support for multiple languages | ||
| 46 | ;* Inclusion of common DOS VERSION check equate | ||
| 47 | ;* | ||
| 48 | ;* ;AN000; Code added in DOS 4.0 | ||
| 49 | ;* 5-19-87 RW (IBM) (DOS 4.0) | ||
| 50 | ;* Addition of IBM Parser Service Routines | ||
| 51 | ;* Addition of DOS Message Retriever Service Routines | ||
| 52 | ;* Add code page file tag support | ||
| 53 | ;* | ||
| 54 | ;* ;AN001; Code added in DOS 4.0 | ||
| 55 | ;* ;AN002; DCR 191 | ||
| 56 | ;* 9-18-87 BL (IBM) (DOS 4.0) | ||
| 57 | ;* Added Extended Attribute support for code page checking | ||
| 58 | ;* and file type checking. | ||
| 59 | ;* ;AN003; PTM 1805 | ||
| 60 | ;* 10-19-87 BL (IBM) (DOS 4.0) | ||
| 61 | ;* | ||
| 62 | ;* ;AN004; PTM | ||
| 63 | ;* 01-29-87 BL (IBM) (DOS 4.0) | ||
| 64 | ;* Ran tool INSPECT on .lst file for optimizations | ||
| 65 | ;********************************************************** | ||
| 66 | |||
| 67 | PAGE ; | ||
| 68 | ;------------------------- | ||
| 69 | ;--- Macro definitions | ||
| 70 | ;------------------------- | ||
| 71 | BREAK MACRO subtitle | ||
| 72 | SUBTTL subtitle | ||
| 73 | PAGE | ||
| 74 | ENDM | ||
| 75 | |||
| 76 | |||
| 77 | |||
| 78 | sys MACRO name ;system call macro | ||
| 79 | MOV AH,name | ||
| 80 | INT 21h | ||
| 81 | ENDM | ||
| 82 | |||
| 83 | |||
| 84 | |||
| 85 | save MACRO reglist ;push those registers | ||
| 86 | IRP reg,<reglist> | ||
| 87 | PUSH reg | ||
| 88 | ENDM | ||
| 89 | ENDM | ||
| 90 | |||
| 91 | |||
| 92 | |||
| 93 | restore MACRO reglist ;pop those registers | ||
| 94 | IRP reg,<reglist> | ||
| 95 | POP reg | ||
| 96 | ENDM | ||
| 97 | ENDM | ||
| 98 | |||
| 99 | |||
| 100 | PAGE ; | ||
| 101 | ;------------------------------- | ||
| 102 | ;--- Equates | ||
| 103 | ;------------------------------- | ||
| 104 | FALSE EQU 0 | ||
| 105 | TRUE EQU NOT FALSE | ||
| 106 | MAXREC EQU 256 ;MAXIMUM NUL RECORD SIZE | ||
| 107 | |||
| 108 | SPACE EQU 0 ;Offset zero in the allocated block | ||
| 109 | BUFFER EQU MAXREC ;Offset MAXREC in the allocated block | ||
| 110 | |||
| 111 | RETCODE_NOERROR equ 0 ;AN000; DOS return code (errorlevel) | ||
| 112 | RETCODE_ERROR equ 1 ;AN000; DOS return code (errorlevel) | ||
| 113 | |||
| 114 | NO_CODEPAGE equ 0 ;AN000; Tag for files with no codepage | ||
| 115 | |||
| 116 | GetCPSW equ 3303h ;AN000; Int 021h function calls | ||
| 117 | GetExtAttr equ 5702h ;AN000; | ||
| 118 | SetExtAttr equ 5704h ;AN000; | ||
| 119 | ;----------------------- | ||
| 120 | ;-- Parser equates | ||
| 121 | ;----------------------- | ||
| 122 | EOL EQU -1 ;AN000; Indicator for End-Of-Line | ||
| 123 | NOERROR EQU 0 ;AN000; Return Indicator for No Errors | ||
| 124 | |||
| 125 | FarSW equ 0 ;AN000; | ||
| 126 | DateSW equ 0 ;AN000; | ||
| 127 | TimeSW equ 0 ;AN000; | ||
| 128 | FileSW equ 0 ;AN000; | ||
| 129 | CAPSW equ 0 ;AN000; | ||
| 130 | CmpxSW equ 0 ;AN000; | ||
| 131 | NumSW equ 1 ;AN000; | ||
| 132 | KeySW equ 0 ;AN000; | ||
| 133 | SwSW equ 1 ;AN000; | ||
| 134 | Val1SW equ 1 ;AN000; | ||
| 135 | Val2SW equ 0 ;AN000; | ||
| 136 | Val3SW equ 0 ;AN000; | ||
| 137 | DrvSW equ 0 ;AN000; | ||
| 138 | QusSW equ 0 ;AN000; | ||
| 139 | |||
| 140 | ;----------------------- | ||
| 141 | ;-- Message equates | ||
| 142 | ;----------------------- | ||
| 143 | STDIN equ 0 | ||
| 144 | STDOUT equ 1 | ||
| 145 | STDERR equ 2 | ||
| 146 | |||
| 147 | Msg_NoMem equ 2 ;AC003; | ||
| 148 | Msg_NoDisk equ 4 ;AC003; | ||
| 149 | Msg_sort equ 5 ;AN003; | ||
| 150 | Msg_switch equ 3 ;AN003; | ||
| 151 | |||
| 152 | ;------------------------------ | ||
| 153 | ; EXTENDED ATTRIBUTE Equates | ||
| 154 | ;------------------------------ | ||
| 155 | EAISBINARY equ 02h ;AN001; ea_type | ||
| 156 | EASYSTEM equ 8000h ;AN001; ea_flags | ||
| 157 | |||
| 158 | PAGE ; | ||
| 159 | ;---------------------; | ||
| 160 | .xlist ; | ||
| 161 | .xcref ; | ||
| 162 | INCLUDE syscall.inc ; | ||
| 163 | INCLUDE sysmsg.inc ; ;AN000; Include message equates and MACROS | ||
| 164 | .cref ; | ||
| 165 | .list ; | ||
| 166 | ;---------------------; | ||
| 167 | |||
| 168 | MSG_UTILNAME <SORT> ;AN000; | ||
| 169 | |||
| 170 | SUBTTL Segments used in load order | ||
| 171 | |||
| 172 | |||
| 173 | CODE SEGMENT | ||
| 174 | CODE ENDS | ||
| 175 | |||
| 176 | CONST SEGMENT PUBLIC BYTE | ||
| 177 | CONST ENDS | ||
| 178 | |||
| 179 | |||
| 180 | ;----------------------- | ||
| 181 | ;--- Stack Segment | ||
| 182 | ;----------------------- | ||
| 183 | CSTACK SEGMENT STACK | ||
| 184 | db 128 DUP (0) ;initial stack to be clear | ||
| 185 | |||
| 186 | CSTACK ENDS | ||
| 187 | |||
| 188 | |||
| 189 | |||
| 190 | ;------------------------------- | ||
| 191 | ;--- Group | ||
| 192 | ;------------------------------- | ||
| 193 | DG GROUP CODE,CONST,CSTACK | ||
| 194 | |||
| 195 | |||
| 196 | ;------------------------------- | ||
| 197 | ;--- Code Segment | ||
| 198 | ;------------------------------- | ||
| 199 | CODE SEGMENT | ||
| 200 | ASSUME CS:DG,DS:DG,ES:NOTHING,SS:CSTACK | ||
| 201 | |||
| 202 | ;------------------------------- | ||
| 203 | ;--- Data Definition | ||
| 204 | ;------------------------------- | ||
| 205 | COLUMN dw 0 ;COLUMN TO USE FOR KEY + 1 | ||
| 206 | cp_reset db FALSE ;AN000;Flag indicating if Code Page was reset on target file | ||
| 207 | |||
| 208 | ;------------------------------------------DOS 3.30 - Russ Whitehead | ||
| 209 | CTRY_INFO db ? | ||
| 210 | CTRY_TABLE_OFF dw ? | ||
| 211 | CTRY_TABLE_SEG dw ? | ||
| 212 | ;------------------------------------------ | ||
| 213 | |||
| 214 | MSG_SERVICES <MSGDATA> ;AN000; | ||
| 215 | ASSUME ds:nothing | ||
| 216 | |||
| 217 | ;---------------------------------------- | ||
| 218 | ;- STRUCTURE TO QUERY EXTENDED ATTRIBUTES | ||
| 219 | ;---------------------------------------- | ||
| 220 | querylist struc ;AN001; ;query general list | ||
| 221 | qea_num dw 1 ;AN001; | ||
| 222 | qea_type db EAISBINARY ;AN001; | ||
| 223 | qea_flags dw EASYSTEM ;AN001; | ||
| 224 | qea_namelen db ? ;AN001; | ||
| 225 | qea_name db " " ;AN001; | ||
| 226 | querylist ends ;AN001; | ||
| 227 | |||
| 228 | cp_qlist querylist <1,EAISBINARY,EASYSTEM,2,"CP"> ;AN001; ;query code page attr. | ||
| 229 | |||
| 230 | cp_list label word ;AN001; ;code page attr. get/set list | ||
| 231 | dw 1 ;AN001; ; # of list entries | ||
| 232 | db EAISBINARY ;AN001; ; ea type | ||
| 233 | dw EASYSTEM ;AN001; ; ea flags | ||
| 234 | db ? ;AN001; ; ea return code | ||
| 235 | db 2 ;AN001; ; ea name length | ||
| 236 | dw 2 ;AN001; ; ea value length | ||
| 237 | db "CP" ;AN001; ; ea name | ||
| 238 | cp dw ? ;AN001; ; ea value (code page) | ||
| 239 | cp_len equ ($ - cp_list) ;AN001; | ||
| 240 | |||
| 241 | ;-------Save area for Code Pages | ||
| 242 | src_cp dw ? ;AN000; Save area for current code page | ||
| 243 | tgt_cp dw ? ;AN000; Save area for current code page | ||
| 244 | endlist label word ;AN000; | ||
| 245 | |||
| 246 | PAGE ; | ||
| 247 | ;****************************************************************************** | ||
| 248 | ;* PARSER DATA STRUCTURES FOLLOW | ||
| 249 | ;****************************************************************************** | ||
| 250 | |||
| 251 | ;------------------------------ | ||
| 252 | ;- STRUCTURE TO DEFINE ADDITIONAL COMMAND LINE DELIMITERS | ||
| 253 | ;------------------------------ | ||
| 254 | parms label word ;AN000; | ||
| 255 | dw parmsx ;AN000; POINTER TO PARMS STRUCTURE | ||
| 256 | db 1 ;AN000; DELIMITER LIST FOLLOWS | ||
| 257 | db 1 ;AN000; NUMBER OF ADDITIONAL DELIMITERS | ||
| 258 | db ";" ;AN000; ADDITIONAL DELIMITER | ||
| 259 | |||
| 260 | ;------------------------------ | ||
| 261 | ;- STRUCTURE TO DEFINE SORT SYNTAX REQUIREMENTS | ||
| 262 | ;------------------------------ | ||
| 263 | parmsx label word ;AN000; | ||
| 264 | db 0,0 ;AN000; THERE ARE NO POSITIONAL PARAMETERS | ||
| 265 | db 2 ;AN000; THERE ARE 2 SWITCHES (/R AND /+n) | ||
| 266 | dw sw1 ;AN000; POINTER TO FIRST SWITCH DEFINITION AREA | ||
| 267 | dw sw2 ;AN000; POINTER TO SECOND SWITCH DEFINITION AREA | ||
| 268 | dw 0 ;AN000; THERE ARE NO KEYWORDS IN SORT SYNTAX | ||
| 269 | |||
| 270 | ;------------------------------ | ||
| 271 | ;- STRUCTURE TO DEFINE THE /R SWITCH | ||
| 272 | ;------------------------------ | ||
| 273 | sw1 label word ;AN000; | ||
| 274 | dw 0 ;AN000; NO MATCH FLAGS | ||
| 275 | dw 0 ;AN000; NO FUNCTION FLAGS | ||
| 276 | dw switchbuff ;AN000; PLACE RESULT IN switchbufF | ||
| 277 | dw novals ;AN000; NO VALUE LIST | ||
| 278 | db 1 ;AN000; ONLY ONE SWITCH IN FOLLOWING LIST | ||
| 279 | rev_sw db "/R",0 ;AN000; /R INDICATES REVERSE SORT | ||
| 280 | |||
| 281 | ;------------------------------ | ||
| 282 | ;- STRUCTURE TO DEFINE THE /+n SWITCH | ||
| 283 | ;------------------------------ | ||
| 284 | NUMERIC equ 08000h ;AN000; Control flag for numeric value | ||
| 285 | NO_COLON equ 0020h ;AN000; | ||
| 286 | |||
| 287 | sw2 label word ;AN000; | ||
| 288 | dw NUMERIC ;AN000; MATCH_FLAGS | ||
| 289 | dw NO_COLON ;AN000; NO FUNCTION FLAGS | ||
| 290 | dw switchbuff ;AN000; PLACE RESULT IN switchbufF | ||
| 291 | dw valuelist ;AN000; NEED VALUE LIST FOR n | ||
| 292 | db 1 ;AN000; ONLY 1 SWITCH ON FOLLOWING LIST | ||
| 293 | col_sw db "/+",0 ;AN000; /+n INDICATES BEGIN SORT IN COLUMN n | ||
| 294 | |||
| 295 | ;------------------------------ | ||
| 296 | ;- VALUE LIST DEFINITION FOR NO VALUES | ||
| 297 | ;------------------------------ | ||
| 298 | novals label word ;AN000; | ||
| 299 | DB 0 ;AN000; VALUE LIST | ||
| 300 | |||
| 301 | ;------------------------------ | ||
| 302 | ;- VALUE LIST DEFINITION FOR /+n | ||
| 303 | ;------------------------------ | ||
| 304 | valuelist label word ;AN000; | ||
| 305 | db 1 ;AN000; ONE VALUE ALLOWED | ||
| 306 | db 1 ;AN000; ONLY ONE RANGE | ||
| 307 | db 1 ;AN000; IDENTIFY THE RANGE | ||
| 308 | dd 1,65535 ;AN000; USER CAN SPECIFY /+1 THROUGH /+65535 | ||
| 309 | |||
| 310 | ;------------------------------ | ||
| 311 | ;- RETURN BUFFER FOR SWITCH INFORMATION | ||
| 312 | ;------------------------------ | ||
| 313 | switchbuff label word ;AN000; | ||
| 314 | sb_type db ? ;AN000; TYPE RETURNED | ||
| 315 | sb_item_tag db ? ;AN000; SPACE FOR ITEM TAG | ||
| 316 | sb_synonym dw ? ;AN000; ES:sb_synonym points to synonym | ||
| 317 | |||
| 318 | sb_value dw ? ;AN000; SPACE FOR VALUE | ||
| 319 | sb_value_extra dw ? ;AN000; UNUSED SPACE FOR VALUE | ||
| 320 | |||
| 321 | PAGE ; | ||
| 322 | ;************************************************************** | ||
| 323 | ;* | ||
| 324 | ;* SUBROUTINE NAME: main | ||
| 325 | ;* | ||
| 326 | ;* SUBROUTINE FUNCTION: | ||
| 327 | ;* Mainline routine, performs SYSLODMSG, calls routines to | ||
| 328 | ;* parse command line, performs the SORT and writes the | ||
| 329 | ;* results. | ||
| 330 | ;* | ||
| 331 | ;* INPUT: | ||
| 332 | ;* Command Line. | ||
| 333 | ;* | ||
| 334 | ;* File to be sorted will be read from Standard Input | ||
| 335 | ;* device handle 0. | ||
| 336 | ;* | ||
| 337 | ;* OUTPUT: | ||
| 338 | ;* Sorted data will be written to the Standard Output | ||
| 339 | ;* device handle 1. | ||
| 340 | ;* | ||
| 341 | ;* NORMAL EXIT: | ||
| 342 | ;* SORT will normally exit when data was successfully read | ||
| 343 | ;* in up to 64k or EOF, sorted, and displayed to the | ||
| 344 | ;* standard output device. | ||
| 345 | ;* | ||
| 346 | ;* ERROR EXIT: | ||
| 347 | ;* If any of the following errors, SORT will display the | ||
| 348 | ;* corresponding error message and terminate. | ||
| 349 | ;* | ||
| 350 | ;* Insufficient disk space on target device | ||
| 351 | ;* Incorrect DOS version | ||
| 352 | ;* Insufficient memory to sort | ||
| 353 | ;* | ||
| 354 | ;************************************************************ | ||
| 355 | |||
| 356 | ;------------------------- | ||
| 357 | ; Preload messages | ||
| 358 | ;------------------------- | ||
| 359 | MSG_SERVICES <SORT.ctl,SORT.cla,SORT.cl1,SORT.cl2> ;AN000; | ||
| 360 | MSG_SERVICES <DISPLAYmsg,LOADmsg,CHARmsg,NOCHECKSTDIN> ;AN002; Make retriever services available | ||
| 361 | |||
| 362 | mov ax,cs ;AN003; ;load ES to the right area, | ||
| 363 | mov es,ax ;AN003; | ||
| 364 | mov ds,ax ;AN003; | ||
| 365 | SORT: | ||
| 366 | call sysloadmsg ;AN000; Preload messages, Check DOS Version. | ||
| 367 | ;If Inc DOS Ver or error loading messages, | ||
| 368 | ;SYSLOADMSG will show msg and terminate for us | ||
| 369 | jnc parser ;AN000; If no error, parse command line | ||
| 370 | call sysdispmsg ;AN000; There was error. Let SYSDISPMSG Display | ||
| 371 | cmp bx,-1 ;AN000; Is this DOS 1.0 or 1.1 ? | ||
| 372 | je OLD_ABORT ;AN000; Yes, terminate old way | ||
| 373 | |||
| 374 | mov ah,Exit ;AN000; No, terminate new way | ||
| 375 | mov al,0 ;AN000; Errorlevel 0 (Compatible!) | ||
| 376 | int 021h ;AN000; Bye bye! | ||
| 377 | |||
| 378 | OLD_ABORT: ;AN000; CS should point to PSP | ||
| 379 | mov ah,Abort ;AN000; Terminate program (AH=0) | ||
| 380 | int 021h ;AN000; Bye bye! | ||
| 381 | ;----------------------------------- | ||
| 382 | ;- DOS version is ok. Parse cmd line | ||
| 383 | ;----------------------------------- | ||
| 384 | PARSER: ;AN000; message and terminate | ||
| 385 | call parse ;AN000; Parse command line | ||
| 386 | |||
| 387 | ;----------------------------------- | ||
| 388 | ; set up column for proper sort offset | ||
| 389 | ;----------------------------------- | ||
| 390 | |||
| 391 | ADD COLUMN,2 | ||
| 392 | CMP COLUMN,2 | ||
| 393 | JZ GOT_COL | ||
| 394 | DEC COLUMN | ||
| 395 | |||
| 396 | ;------------------------------------ | ||
| 397 | ; Get sorting area, no more than 64K | ||
| 398 | ;------------------------------------ | ||
| 399 | GOT_COL: | ||
| 400 | MOV BX,1000H ;64K worth of paragraphs | ||
| 401 | GET_MEM: | ||
| 402 | mov bp,bx ;AN003; save buffer length | ||
| 403 | sys ALLOC ;allocate them from somewhere | ||
| 404 | JNC GOT_MEM ;if error, BX has amount free, try to get it | ||
| 405 | OR BX,BX ;but, is BX = 0? | ||
| 406 | JNZ GET_MEM ;nope, try to allocate it | ||
| 407 | JMP short SIZERR ;AN004; ;complain | ||
| 408 | |||
| 409 | GOT_MEM: | ||
| 410 | ;------------------------------------RussW:--Following add in DOS 3.3 for Nat Lang Support | ||
| 411 | push ax ;Save AX | ||
| 412 | push ds ;Save DS | ||
| 413 | push es ;Save ES | ||
| 414 | mov al,6 ;Function for Get collating sequence | ||
| 415 | mov bx,-1 ;Get active code page | ||
| 416 | mov dx,-1 ;Get info from active country | ||
| 417 | mov cx,5 ;Number of bytes to be returned | ||
| 418 | push cs ;Place code segment | ||
| 419 | pop es ;in ES | ||
| 420 | mov di,offset ctry_info ;Return area for 5 byte requested information | ||
| 421 | sys GetExtCntry ;Get extended country information | ||
| 422 | ;Ok, now copy the table in DOS to our segment | ||
| 423 | lds si,dword ptr cs:ctry_table_off | ||
| 424 | mov di,seg dg | ||
| 425 | mov es,di | ||
| 426 | mov di,offset dg:table | ||
| 427 | mov cx,word ptr [si] | ||
| 428 | add si,2 | ||
| 429 | mov ax,256 | ||
| 430 | sub ax,cx | ||
| 431 | add di,ax | ||
| 432 | cld | ||
| 433 | rep movsb | ||
| 434 | ;Done copying, so restore regs and cont | ||
| 435 | pop es ;Restore ES | ||
| 436 | pop ds ;Restore DS | ||
| 437 | pop ax ;Restore AX | ||
| 438 | ;------------------------------------RussW:--End 3.3 addition | ||
| 439 | MOV DS,AX ;Point DS to buffer | ||
| 440 | MOV ES,AX ;and point ES to buffer | ||
| 441 | MOV CL,4 ;2^4 bytes per paragraph | ||
| 442 | MOV BX,BP ;AN003; restore buffer length | ||
| 443 | SHL BX,CL ;Find out how many bytes we have | ||
| 444 | MOV BP,BX ;AN003; save buffer length in bytes | ||
| 445 | |||
| 446 | ;--------------------------- | ||
| 447 | ; Clear out temporary record area | ||
| 448 | ;--------------------------- | ||
| 449 | MOV CX,MAXREC/2 ;Size of temporary buffer (words) | ||
| 450 | MOV AX,' ' ;Character to fill with | ||
| 451 | XOR DI,DI ;AN004; ;Beginning of temp buffer | ||
| 452 | REP STOSW ;Blam. | ||
| 453 | ;----------------------------------- | ||
| 454 | ; Make sure source and target code pages are the same | ||
| 455 | ;----------------------------------- | ||
| 456 | call match_codepages ;AN000; Make sure codepages are the same | ||
| 457 | ;--------------------------- | ||
| 458 | ; read in file from standard input | ||
| 459 | ;--------------------------- | ||
| 460 | MOV DX,BUFFER + 2 ;DX = place to begin reading | ||
| 461 | MOV CX,BP ;AN003; ;CX is the max number to read | ||
| 462 | SUB CX,MAXREC + 2 ;remember offset of temp buffer | ||
| 463 | SORTL: | ||
| 464 | XOR BX,BX ;Standard input | ||
| 465 | sys READ ;Read it in | ||
| 466 | ADD DX,AX ;Bump pointer by count read | ||
| 467 | SUB CX,AX ;subtract from remaining the count read | ||
| 468 | JZ SIZERR ;if buffer is full then error | ||
| 469 | OR AX,AX ;no chars read -> end of file | ||
| 470 | JNZ SORTL ;there were chars read. go read again | ||
| 471 | JMP SHORT SIZOK ;trim last ^Z terminated record | ||
| 472 | SIZERR: | ||
| 473 | mov ax,msg_NoMem ;AN000; not enough memory error | ||
| 474 | mov dh,-1 ;AN003; class: utility error | ||
| 475 | call error_exit ;AN000; and write it out | ||
| 476 | |||
| 477 | ;--------------------------- | ||
| 478 | ; Look for a ^Z. Terminate buffer at 1st ^Z. | ||
| 479 | ;--------------------------- | ||
| 480 | SIZOK: | ||
| 481 | MOV BX,DX ;save end pointer | ||
| 482 | MOV CX,DX ;get pointer to end of text | ||
| 483 | SUB CX,BUFFER+2 ;dif in pointers is count | ||
| 484 | MOV AL,1AH ;char is ^Z | ||
| 485 | MOV DI,BUFFER+2 ;point to beginning of text | ||
| 486 | REPNZ SCASB ;find one | ||
| 487 | JNZ NoBack ;nope, try to find CRLF | ||
| 488 | DEC BX ;pretend that we didn't see ^Z | ||
| 489 | NoBack: | ||
| 490 | SUB BX,CX ;sub from endpointer the number left | ||
| 491 | SUB BX,2 ;Hope for a CR LF at end | ||
| 492 | CMP WORD PTR [BX],0A0Dh ;Was there one there? | ||
| 493 | JZ GOTEND ;yep, here is the end | ||
| 494 | ADD BX,2 ;nope, bump back to SCASB spot | ||
| 495 | CMP BYTE PTR [BX],AL ;Was there ^Z there? | ||
| 496 | JZ GOTEND ;yep, chop it | ||
| 497 | INC BX ;Nope, skip last char | ||
| 498 | GOTEND: | ||
| 499 | MOV BP,BX ;BP = filesize-2(CRLF)+temp buffer+2 | ||
| 500 | MOV WORD PTR DS:[BP],0 ;0 at end of the file | ||
| 501 | |||
| 502 | ;--------------------------- | ||
| 503 | ; We now turn the entire buffer into a linked list of chains by | ||
| 504 | ; replacing CRLFs with the length of the following line (with 2 for CRLF) | ||
| 505 | ;--------------------------- | ||
| 506 | MOV BX,BUFFER ;pointer to line head (length) | ||
| 507 | MOV DI,BUFFER+2 ;pointer to line text | ||
| 508 | REPLACE_LOOP: | ||
| 509 | MOV AL,13 ;char to look for is CR | ||
| 510 | MOV CX,BP ;count = end pointer | ||
| 511 | SUB CX,DI ;chop off start point to get length | ||
| 512 | INC CX ;add 1??? | ||
| 513 | REPLACE_SCAN: | ||
| 514 | REPNZ SCASB ;look for CR | ||
| 515 | JNZ REPLACE_SKIP ;count exhausted | ||
| 516 | CMP BYTE PTR [DI],10 ;LF there? | ||
| 517 | JNZ REPLACE_SCAN ;nope, continue scanning | ||
| 518 | REPLACE_SKIP: | ||
| 519 | MOV AX,DI ;AX to point after CR | ||
| 520 | DEC AX ;AX to point to CR | ||
| 521 | save <AX> ;save pointer | ||
| 522 | SUB AX,BX ;AX is length of line found | ||
| 523 | MOV [BX],AX ;stuff it in previous link | ||
| 524 | restore <BX> ;get pointer to next | ||
| 525 | INC DI ;skip LF??? | ||
| 526 | JCXZ END_REPLACE_LOOP ;no more to scan -> go sort | ||
| 527 | JMP REPLACE_LOOP ;look for next | ||
| 528 | |||
| 529 | END_REPLACE_LOOP: | ||
| 530 | MOV WORD PTR [BX],0 ;terminate file with nul | ||
| 531 | LEA BP,[BX+2] ;remember the null line at end | ||
| 532 | MOV DI,BUFFER ;DI is start of unsorted section | ||
| 533 | |||
| 534 | ;--------------------------- | ||
| 535 | ; begin sort. Outer loop steps over all unsorted lines | ||
| 536 | ;--------------------------- | ||
| 537 | OUTER_SORT_LOOP: | ||
| 538 | MOV BX,DI ;BX is start of unsorted section | ||
| 539 | MOV SI,BX ;SI is scanning place link | ||
| 540 | CMP WORD PTR [BX],0 ;are we at the end of the buffer? | ||
| 541 | JNZ INNER_SORT_LOOP ;No, do inner process | ||
| 542 | JMP END_OUTER_SORT_LOOP ;yes, go dump out | ||
| 543 | |||
| 544 | ;--------------------------- | ||
| 545 | ; BX points to best guy found so far. We scan through the sorted section | ||
| 546 | ; to find an appropriate insertion point | ||
| 547 | ;--------------------------- | ||
| 548 | INNER_SORT_LOOP: | ||
| 549 | ADD SI,[SI] ;link to next fellow | ||
| 550 | MOV AX,[SI] ;get length of comparison guy | ||
| 551 | OR AX,AX ;test for end of buffer | ||
| 552 | JZ END_INNER_SORT_LOOP ;if zero then figure out insertion | ||
| 553 | save <SI,DI> ;save SI,DI | ||
| 554 | MOV DI,BX ;DI = pointer to tester link | ||
| 555 | SUB AX,COLUMN ;adjust length for column | ||
| 556 | JA AXOK ;more chars in tester than column? | ||
| 557 | XOR SI,SI ;AN004; ;point SI to blank area | ||
| 558 | MOV AX,MAXREC ;make AX be max length | ||
| 559 | AXOK: | ||
| 560 | MOV DX,[DI] ;get length of best guy | ||
| 561 | SUB DX,COLUMN ;adjust length for column | ||
| 562 | JA DXOK ;there are more chars after column | ||
| 563 | XOR DI,DI ;AN004; ;point air to a space | ||
| 564 | MOV DX,MAXREC ;really big record | ||
| 565 | DXOK: | ||
| 566 | MOV CX,AX ;AX is shortest record | ||
| 567 | CMP AX,DX ;perhaps DX is shorter | ||
| 568 | JB SMALL ;nope, leace CX alone | ||
| 569 | MOV CX,DX ;DX is shorter, put length in CX | ||
| 570 | SMALL: | ||
| 571 | ADD DI,COLUMN ;offset into record | ||
| 572 | ADD SI,COLUMN ;offset into other record | ||
| 573 | push bx | ||
| 574 | push ax | ||
| 575 | mov bx,offset dg:table | ||
| 576 | tloop: lodsb | ||
| 577 | xlat byte ptr cs:[bx] | ||
| 578 | mov ah,al | ||
| 579 | mov al,es:[di] | ||
| 580 | inc di | ||
| 581 | xlat byte ptr cs:[bx] | ||
| 582 | cmp ah,al | ||
| 583 | loopz tloop | ||
| 584 | pop ax | ||
| 585 | pop bx | ||
| 586 | restore <DI,SI> ;get head pointers back | ||
| 587 | JNZ TESTED_NOT_EQUAL ;didn't exhaust counter, conditions set | ||
| 588 | CMP AX,DX ;check string lengths | ||
| 589 | TESTED_NOT_EQUAL: | ||
| 590 | |||
| 591 | ;--------------------------- | ||
| 592 | ; NOTE! jae is patched to a jbe if file is to be sorted in reverse! | ||
| 593 | ;--------------------------- | ||
| 594 | CODE_PATCH label byte | ||
| 595 | JAE INNER_SORT_LOOP ;if this one wasn't better then go again | ||
| 596 | MOV BX,SI ;it was better, save header | ||
| 597 | JMP INNER_SORT_LOOP ;and scan again | ||
| 598 | |||
| 599 | END_INNER_SORT_LOOP: | ||
| 600 | MOV SI,BX ;SI is now the best person | ||
| 601 | CMP SI,DI ;check best for current | ||
| 602 | JZ END_INSERT ;best equals current, all done | ||
| 603 | |||
| 604 | ;--------------------------- | ||
| 605 | ; SI points to best line found so far | ||
| 606 | ; DI points to a place to insert this line | ||
| 607 | ; DI is guaranteed to be < SI | ||
| 608 | ; make room for line at destination | ||
| 609 | ;--------------------------- | ||
| 610 | MOV DX,[SI] ;get length of line | ||
| 611 | save <SI,DI> ;save positions of people | ||
| 612 | STD ;go right to left | ||
| 613 | MOV CX,BP ;get end of file pointer | ||
| 614 | SUB CX,DI ;get length from destination to end | ||
| 615 | MOV SI,BP ;start from end | ||
| 616 | DEC SI ;SI points to end of file | ||
| 617 | MOV DI,SI ;destination is end of file | ||
| 618 | ADD DI,DX ;DI points to new end of file | ||
| 619 | REP MOVSB ;blam. Move every one up | ||
| 620 | CLD ;back left to right | ||
| 621 | restore <DI,SI> ;get old source and destination | ||
| 622 | ;--------------------------- | ||
| 623 | ; MOVE NEW LINE INTO PLACE | ||
| 624 | ;--------------------------- | ||
| 625 | save <DI> ;save destination | ||
| 626 | ADD SI,DX ;adjust for previous movement | ||
| 627 | save <SI> ;save this value | ||
| 628 | MOV CX,DX ;get number to move | ||
| 629 | REP MOVSB ;blam. move the new line in | ||
| 630 | restore <SI,DI> ;get back destination and new source | ||
| 631 | ;--------------------------- | ||
| 632 | ; DELETE LINE FROM OLD PLACE | ||
| 633 | ;--------------------------- | ||
| 634 | save <DI> ;save destination | ||
| 635 | MOV CX,BP ;pointer to end | ||
| 636 | ADD CX,DX ;remember bump | ||
| 637 | SUB CX,SI ;get count of bytes to move | ||
| 638 | INC CX ;turn it into a word | ||
| 639 | SHR CX,1 ;or a count of words | ||
| 640 | MOV DI,SI ;new destination of move | ||
| 641 | ADD SI,DX ;offset of block | ||
| 642 | REP MOVSW ;blam, squeeze out the space | ||
| 643 | restore <DI> ;get back original destination | ||
| 644 | MOV WORD PTR DS:[BP-2],0 ;remake the end of file mark | ||
| 645 | |||
| 646 | END_INSERT: | ||
| 647 | ADD DI,[DI] ;link to next guy | ||
| 648 | JMP OUTER_SORT_LOOP ;and continue | ||
| 649 | ;------------------------------ | ||
| 650 | ; PUT BACK IN THE CR-LF | ||
| 651 | ;------------------------------ | ||
| 652 | END_OUTER_SORT_LOOP: | ||
| 653 | MOV DI,BUFFER ;start at beginning (where else) | ||
| 654 | MOV CX,[DI] ;count of butes | ||
| 655 | |||
| 656 | INSERT_LOOP: | ||
| 657 | ADD DI,CX ;point to next length | ||
| 658 | MOV CX,[DI] ;get length | ||
| 659 | MOV WORD PTR [DI],0A0DH ;replace length with CRLF | ||
| 660 | AND CX,CX ;AN004; ;check for end of file | ||
| 661 | JNZ INSERT_LOOP ;nope, try again | ||
| 662 | |||
| 663 | WRITE_FILE: | ||
| 664 | MOV DX,BUFFER+2 ;get starting point | ||
| 665 | MOV CX,BP ;pointer to end of buffer | ||
| 666 | SUB CX,DX ;dif in pointers is number of bytes | ||
| 667 | MOV BX,1 ;to standard output | ||
| 668 | sys WRITE ;write 'em out | ||
| 669 | JC BADWRT ;some bizarre error -> flag it | ||
| 670 | CMP AX,CX ;did we write what was expected? | ||
| 671 | JZ WRTOK ;yes, say bye bye | ||
| 672 | BADWRT: | ||
| 673 | |||
| 674 | ;;;;; mov ax,msg_NoDisk ;AN000; Strange write error | ||
| 675 | ;;;;; mov dh,-1 ;AN003; class: extended error | ||
| 676 | ;;;;; call error_exit ;AN000; Bye bye | ||
| 677 | mov al,RETCODE_ERROR ;AN000; return an error code (errorlevel) | ||
| 678 | sys EXIT ;AN000; | ||
| 679 | WRTOK: | ||
| 680 | MOV AL,RETCODE_NOERROR ;AN000; Errorlevel 0 (No error!) | ||
| 681 | sys EXIT ;bye! | ||
| 682 | |||
| 683 | PAGE ; | ||
| 684 | ;************************************************************ | ||
| 685 | ;* | ||
| 686 | ;* SUBROUTINE NAME: display_msg | ||
| 687 | ;* | ||
| 688 | ;* SUBROUTINE FUNCTION: | ||
| 689 | ;* Display the requested message to the specified handle | ||
| 690 | ;* | ||
| 691 | ;* INPUT: | ||
| 692 | ;* 1) AX = Number of the message to be displayed. | ||
| 693 | ;* 2) BX = Handle to be written to. | ||
| 694 | ;* | ||
| 695 | ;* OUTPUT: | ||
| 696 | ;* The message corresponding to the requested msg number will | ||
| 697 | ;* be written to the requested handle. There is no substitution | ||
| 698 | ;* text in SORT. | ||
| 699 | ;* | ||
| 700 | ;* NORMAL EXIT: | ||
| 701 | ;* Message will be successfully written to requested handle. | ||
| 702 | ;* | ||
| 703 | ;* ERROR EXIT: | ||
| 704 | ;* None. Note that theoretically an error can be returned from | ||
| 705 | ;* SYSDISPMSG, but there is nothing that the application can do. | ||
| 706 | ;* | ||
| 707 | ;* INTERNAL REFERENCES: | ||
| 708 | ;* System Display Message service routines | ||
| 709 | ;* | ||
| 710 | ;* EXTERNAL REFERENCES: | ||
| 711 | ;* None | ||
| 712 | ;* | ||
| 713 | ;************************************************************ | ||
| 714 | |||
| 715 | display_msg proc near ;AN000; | ||
| 716 | push ds ;AN000; save DS value | ||
| 717 | push cs ;AN000; get DS addressability | ||
| 718 | pop ds ;AN000; | ||
| 719 | |||
| 720 | xor cx,cx ;AN004; ;AN000; No substitution text | ||
| 721 | ;; mov dh,-1 ;AN003; Message class | ||
| 722 | ; 1=DOS Extended error | ||
| 723 | ; 2=DOS Parse error | ||
| 724 | ; -1=Utility message | ||
| 725 | mov dl,0 ;AN000; DOS INT 21H function number to use for input | ||
| 726 | ; 00H=No input, 01H=Keyboard input, | ||
| 727 | ; 07H=Direct Console Input Without Echo, | ||
| 728 | ; 08H=Console Input Without Echo, 0AH=Buffered Keyboard Input | ||
| 729 | call SYSDISPMSG ;AN000; | ||
| 730 | |||
| 731 | pop ds ;AN000; restore DS | ||
| 732 | ret ;AN000; | ||
| 733 | display_msg ENDP ;AN000; | ||
| 734 | |||
| 735 | PAGE ; | ||
| 736 | ;************************************************************ | ||
| 737 | ;* | ||
| 738 | ;* SUBROUTINE NAME: parse | ||
| 739 | ;* | ||
| 740 | ;* SUBROUTINE FUNCTION: | ||
| 741 | ;* Call the DOS PARSE Service Routines to process the command | ||
| 742 | ;* line. Search for valid switches (/R and /+n) and take | ||
| 743 | ;* appropriate action for each. Display error message and | ||
| 744 | ;* terminate on error. | ||
| 745 | ;* | ||
| 746 | ;* INPUT: None | ||
| 747 | ;* | ||
| 748 | ;* OUTPUT: None | ||
| 749 | ;* | ||
| 750 | ;* NORMAL EXIT: | ||
| 751 | ;* | ||
| 752 | ;* If /R specified, then patches code to perform reverse sort | ||
| 753 | ;* by changing JAE to a JB. | ||
| 754 | ;* | ||
| 755 | ;* If /+n entered, COLUMN will be set to "n," otherwise COLUMN | ||
| 756 | ;* will be set to 1. | ||
| 757 | ;* | ||
| 758 | ;* ERROR EXIT: | ||
| 759 | ;* | ||
| 760 | ;* If user enters any parameter or switch other than /R or /+n, | ||
| 761 | ;* or an invalid value for "n", then this routine will display | ||
| 762 | ;* the "Invalid Parameter" error message and terminate with | ||
| 763 | ;* errorlevel 1. | ||
| 764 | ;* | ||
| 765 | ;* EXTERNAL REFERENCES: | ||
| 766 | ;* System parse service routines | ||
| 767 | ;* INT21 - GET PSP Function Call 062h | ||
| 768 | ;* | ||
| 769 | ;************************************************************ | ||
| 770 | |||
| 771 | parse proc near ;AN000; | ||
| 772 | |||
| 773 | sys GetCurrentPSP ;AN000; Get PSP address, returned in BX | ||
| 774 | |||
| 775 | mov ds,bx ;AN000; Put PSP Seg in DS | ||
| 776 | mov si,081h ;AN000; Offset of command line in PSP | ||
| 777 | cmp byte ptr ds:080h,0 ;AN000; Check length of command line | ||
| 778 | je end_parse ;AN000; If 0 len, the we are done parsing | ||
| 779 | xor cx,cx ;AN000; Number of parms processed so far = 0 | ||
| 780 | push cs ;AN000; Put CS | ||
| 781 | pop es ;AN000; in ES | ||
| 782 | ;--------------------------------- | ||
| 783 | ;- Loop for each operand at DS:SI (Initially PSP + 081h) | ||
| 784 | ;--------------------------------- | ||
| 785 | parse_loop: ;AN000; | ||
| 786 | mov di,offset parms ;AN000; Address of parse control block | ||
| 787 | xor dx,dx ;AN000; Reserved | ||
| 788 | call sysparse ;AN000; Parse parm at DS:SI | ||
| 789 | cmp ax,EOL ;AN000; Q: Are we at end of command line? | ||
| 790 | je end_parse ;AN000; YES: We are done | ||
| 791 | and ax,ax ;AN004; ;AN000; NO: Q: Any errors? | ||
| 792 | jne parse_error ;AN000; YES: Display msg and terminate | ||
| 793 | mov bx,sb_synonym ;AN000; Get offset of switch entered | ||
| 794 | ;---------------------------------- | ||
| 795 | ;- If user said /R, then patch code | ||
| 796 | ;---------------------------------- | ||
| 797 | cmp bx,offset rev_sw ;AN000; If user specified /R | ||
| 798 | jne check_column ;AN000; | ||
| 799 | mov cs:code_patch,072h ;AN000; Sleazy patch to make reverse order sort | ||
| 800 | jmp parse_loop ;AN000; Look for another parm | ||
| 801 | |||
| 802 | ;--------------------------------------------- | ||
| 803 | ;- If user said /+n, then save COLUMN index | ||
| 804 | ;--------------------------------------------- | ||
| 805 | check_column: ;AN000; | ||
| 806 | cmp bx,offset col_sw ;AN000; Q: Did user specified /+n ? | ||
| 807 | jne switch_error ;AC003; No: Unrecognized parm | ||
| 808 | mov ax,sb_value ;AN000; Yes: Get number entered by user | ||
| 809 | mov column,ax ;AN000; Set up column to begin sort | ||
| 810 | jmp parse_loop ;AN000; Check for next parm | ||
| 811 | |||
| 812 | ;------------------------------------------------------------ | ||
| 813 | ;- If any other parameter specified, display message and die | ||
| 814 | ;------------------------------------------------------------ | ||
| 815 | switch_error: ;AN003; | ||
| 816 | mov ax,Msg_switch ;AN003; | ||
| 817 | parse_error: ;AN000; | ||
| 818 | mov dh,2 ;AN003; class: parse error | ||
| 819 | call error_exit ;AN000; Terminate utility | ||
| 820 | |||
| 821 | end_parse: ;AN000; | ||
| 822 | ret ;AN000; | ||
| 823 | parse endp ;AN000; | ||
| 824 | |||
| 825 | PAGE ; | ||
| 826 | ;************************************************************ | ||
| 827 | ;* | ||
| 828 | ;* SUBROUTINE NAME: error_exit | ||
| 829 | ;* | ||
| 830 | ;* SUBROUTINE FUNCTION: | ||
| 831 | ;* Displays the message number in AX to the standard | ||
| 832 | ;* error device, then terminates with errorlevel 1. | ||
| 833 | ;* | ||
| 834 | ;* INPUT: AX = Message number | ||
| 835 | ;* | ||
| 836 | ;* INTERNAL REFERENCES: | ||
| 837 | ;* display_msg | ||
| 838 | ;* | ||
| 839 | ;* EXTERNAL REFERENCES: | ||
| 840 | ;* INT 021h - Terminate Function 043h | ||
| 841 | ;* | ||
| 842 | ;************************************************************ | ||
| 843 | error_exit proc near ;AN000; | ||
| 844 | call prt_sort ;AN003; | ||
| 845 | mov bx,STDERR ;AN000; output to standard error | ||
| 846 | xor cx,cx ;AN004; ;AN003; | ||
| 847 | call display_msg ;AN000; and write it out | ||
| 848 | mov al,RETCODE_ERROR ;AN000; return an error code (errorlevel) | ||
| 849 | sys EXIT ;AN000; | ||
| 850 | ret ;AN000; Meaningless RET | ||
| 851 | error_exit endp ;AN000; | ||
| 852 | |||
| 853 | |||
| 854 | ;************************************************************ | ||
| 855 | ;* | ||
| 856 | ;* SUBROUTINE NAME: match_codepages | ||
| 857 | ;* | ||
| 858 | ;* SUBROUTINE FUNCTION: | ||
| 859 | ;* Check to see if Code Page Support is active. If so, | ||
| 860 | ;* check code page of input and output handles. If the | ||
| 861 | ;* source file has a code page file tag AND the target | ||
| 862 | ;* handles code page is different, then set code page | ||
| 863 | ;* of the target to that of the source. | ||
| 864 | ;* | ||
| 865 | ;* INTERNAL REFERENCES: | ||
| 866 | ;* none | ||
| 867 | ;* | ||
| 868 | ;* EXTERNAL REFERENCES: | ||
| 869 | ;* INT 021h - Check CPSW | ||
| 870 | ;* INT 021h - Get Extended Attributes by Handle | ||
| 871 | ;* INT 021h - Set Extended Attributes by Handle | ||
| 872 | ;* | ||
| 873 | ;************************************************************ | ||
| 874 | |||
| 875 | match_codepages proc near ;AN000; | ||
| 876 | |||
| 877 | ;----------------------------------- | ||
| 878 | ; Check status of Code page support | ||
| 879 | ;----------------------------------- | ||
| 880 | push es ;AN000; Save ES register | ||
| 881 | push ds ;AN001; Save DS register | ||
| 882 | ; | ||
| 883 | mov ax,cs ;AN001; ES, DS -> CS | ||
| 884 | mov ds,ax ;AN001; | ||
| 885 | mov es,ax ;AN001; | ||
| 886 | ; | ||
| 887 | mov ax,GetCPSW ;AN000; Get CPSW state, assume support is OFF | ||
| 888 | int 021h ;AN000; DL: 0=NotSupported,1=Supported | ||
| 889 | cmp dl,1 ;AN000; CPSW supported if DL=1 | ||
| 890 | jne done_cpsw ;AN000; If not supported, we're done | ||
| 891 | ;----------------------------------- | ||
| 892 | ; Get Code Pages of STDIN and STDOUT | ||
| 893 | ;----------------------------------- | ||
| 894 | mov ax,GetExtAttr ;AN000; Get Extended Attributes by Handle | ||
| 895 | mov bx,STDOUT ;AN000; For Standard output device | ||
| 896 | mov di,offset cp_list ;AC001; Return buffer address | ||
| 897 | mov si,offset cp_qlist ;AN001; Query the code page attribute | ||
| 898 | mov cx,cp_len ;AN001; return buffer length | ||
| 899 | int 021h ;AN000; | ||
| 900 | jc done_cpsw ;AN000; Error condition, let system handle | ||
| 901 | mov ax,cp ;AN000; Save target code page | ||
| 902 | mov tgt_cp,ax ;AN000; for later reference | ||
| 903 | |||
| 904 | mov ax,GetExtAttr ;AN000; Get Extended Attributes by Handle | ||
| 905 | xor bx,bx ;AN004; ;AN000; bx = STDIN (0) For Standard input device | ||
| 906 | mov di,offset cp_list ;AC001; Return buffer address | ||
| 907 | mov si,offset cp_qlist ;AN001; Query the code page attribute | ||
| 908 | mov cx,cp_len ;AN001; return buffer length | ||
| 909 | int 021h ;AN000; | ||
| 910 | jc done_cpsw ;AN000; Error condition, let system handle | ||
| 911 | mov ax,cp ;AN000; Save source code page | ||
| 912 | mov src_cp,ax ;AN000; for later reference | ||
| 913 | |||
| 914 | mov ax,src_cp ;AN000; Get source codepage | ||
| 915 | and ax,ax ;AN004; ;AN000; IF no codepage | ||
| 916 | je done_cpsw ;AN000; THEN no action required; | ||
| 917 | cmp ax,tgt_cp ;AN000; IF src_cp = tgt_cp | ||
| 918 | je done_cpsw ;AN000; THEN no action required; | ||
| 919 | ;------------------------------------- | ||
| 920 | ;- Set CP of target to that of source | ||
| 921 | ;------------------------------------- | ||
| 922 | mov cp_reset,TRUE ;AN000; Set flag indicating change | ||
| 923 | mov ax,SetExtAttr ;AN000; Set Extended Attributes by Handle | ||
| 924 | mov bx,STDOUT ;AN000; For Standard output device | ||
| 925 | mov di,offset cp_list ;AC001; Input buffer address | ||
| 926 | int 021h ;AN000; | ||
| 927 | |||
| 928 | done_cpsw: ;AN000; | ||
| 929 | pop ds ;AN001; Restore DS register | ||
| 930 | pop es ;AN000; Restore ES register | ||
| 931 | ret ;AN000; | ||
| 932 | match_codepages endp ;AN000; | ||
| 933 | |||
| 934 | PAGE ; | ||
| 935 | ;************************************************************ | ||
| 936 | ;* | ||
| 937 | ;* SUBROUTINE NAME: prt_sort | ||
| 938 | ;* | ||
| 939 | ;* SUBROUTINE FUNCTION: | ||
| 940 | ;* Preceeds all error messages with "SORT: ". | ||
| 941 | ;* | ||
| 942 | ;* INTERNAL REFERENCES: | ||
| 943 | ;* none | ||
| 944 | ;* EXTERNAL REFERENCES: | ||
| 945 | ;* none | ||
| 946 | ;************************************************************ | ||
| 947 | prt_sort proc near ;AN003; | ||
| 948 | push ax ;AN003; | ||
| 949 | push dx ;AN003; | ||
| 950 | ; | ||
| 951 | mov dh,-1 ;AN003; | ||
| 952 | mov ax,Msg_sort ;AN003; | ||
| 953 | xor cx,cx ;AN004; ;AN003; | ||
| 954 | mov bx,STDERR ;AN003; | ||
| 955 | call display_msg ;AN003; | ||
| 956 | ; | ||
| 957 | pop dx ;AN003; | ||
| 958 | pop ax ;AN003; | ||
| 959 | ; | ||
| 960 | ret ;AN003; | ||
| 961 | prt_sort endp ;AN003; | ||
| 962 | |||
| 963 | |||
| 964 | PAGE ; | ||
| 965 | ;-------------------- | ||
| 966 | .xlist | ||
| 967 | .xcref | ||
| 968 | INCLUDE parse.asm | ||
| 969 | include msgdcl.inc | ||
| 970 | .cref | ||
| 971 | .list | ||
| 972 | ;-------------------- | ||
| 973 | |||
| 974 | CODE ENDS | ||
| 975 | |||
| 976 | |||
| 977 | |||
| 978 | |||
| 979 | |||
| 980 | |||
| 981 | |||
| 982 | CONST SEGMENT PUBLIC BYTE | ||
| 983 | |||
| 984 | extrn table:byte | ||
| 985 | |||
| 986 | CONST ENDS | ||
| 987 | |||
| 988 | |||
| 989 | |||
| 990 | |||
| 991 | SUBTTL Initialized Data | ||
| 992 | ;------------------------------- | ||
| 993 | ;--- Stack Segment | ||
| 994 | ;------------------------------- | ||
| 995 | CSTACK SEGMENT STACK | ||
| 996 | db (362 - 80h) + 96 dup (0) ;(362 - 80h) == New - Old IBM | ||
| 997 | ;interrupt reqs. == size of growth | ||
| 998 | CSTACK ENDS | ||
| 999 | |||
| 1000 | END SORT | ||