home *** CD-ROM | disk | FTP | other *** search
- ; Int Numbers
- DOS Equ 21H
- Kbrd Equ 16H
- ;
- ; Dos Func Numbers
- ReadNoEcho Equ 0800H
- ClearReadNoEcho Equ 0C08H
- SelectDisk Equ 0E00H
- CurrDisk Equ 1900H
- SetDTA Equ 1A00H
- SetCtrlVect Equ 2523H
- GetDate Equ 2A00H
- GetTime Equ 2C00H
- DosVersion Equ 3000H
- GetCtrlState Equ 3300H
- SetCtrlState Equ 3301H
- DiskFree Equ 3600H
- CreateFile Equ 3C00H
- OpenForRead Equ 3D00H
- OpenForWrite Equ 3D01H
- Close Equ 3E00H
- Read Equ 3F00H
- Write Equ 40H
- Delete Equ 4100H
- SetFileAtBeg Equ 4200H
- GetFileLoc Equ 4201H
- GetFileLen Equ 4202H
- IoctlGet Equ 4400H
- IoctlSet Equ 4401H
- ForceDup Equ 4600H
- AllocMemory Equ 48H
- FreeMemory Equ 49H
- SetBlock Equ 4AH
- FindFirst Equ 4E00H
- FindNext Equ 4F00H
- ;
- CtrlStateOn Equ 01H
- Hidden Equ 02H
- System Equ 04H
- ;
- ExitProg Equ 4CH
- ;
- ; Std Handles
- StdInput Equ 00H
- StdOutput Equ 01H
- StdError Equ 02H
- ;
- ; Chars
- Space Equ 20H
- Slash Equ '/'
- CtrlZ Equ 1AH
- LF Equ 0AH
- CR Equ 0DH
- CRLF Equ 0A0DH
- Escp Equ 1BH
- PageUp Equ 49H
- PageDown Equ 51H
- ;
- KeyReverse Equ 0001H
- KeyZero Equ 0002H
- KeyASCII Equ 0004H
- KeyPascal Equ 0008H
- KeyInteger Equ 0010H
- KeyUnsigned Equ 0020H
- KeyMicro Equ 0040H
- KeyTurbo Equ 0080H
- KeyFloat Equ 0100H
- ;
- KeyDecimal Equ 0200H
- KeyNumDisp Equ 0400H
- ;
- Question Equ '?'
- LengthParm Equ ':'
- ASCIIParm Equ 'A'
- NoBreakParm Equ 'B'
- ZeroParm Equ 'C'
- DupParm Equ 'D'
- ErrorParm Equ 'E'
- FixedParm Equ 'F'
- FloatParm Equ 'F'
- IntegerParm Equ 'I'
- MicroParm Equ 'M'
- NullParm Equ 'N'
- PascalParm Equ 'P'
- QuietParm Equ 'Q'
- ReverseParm Equ 'R'
- TempParm Equ 'T'
- TurboParm Equ 'T'
- UnsignedParm Equ 'U'
- CtrlZParm Equ 'Z'
- ;
- DecimalParm Equ 'D'
- NumDispParm Equ 'N'
- ;
- StartColumn Equ 1111H
- RelColumn Equ 1111H
- KeyLength Equ 1111H
- ;
- GotBinStrErr Equ 01H
- GotDiffBinErr Equ 02H
- GotNumbNotFErr Equ 04H
- GotOtherErr Equ 80H
- ;
- BegSegm Struc
- Beg DW ?
- Segm DW ?
- BegSegm Ends
- ;
- CdeSeg Segment Para Public 'Code'
- Assume CS:CdeSeg,DS:CdeSeg,ES:CdeSeg,SS:CdeSeg
- ;
- Org 80H
- ParmsLen DB ? ;Set up ref to cmd parms.
- Parms DB 127 Dup(?)
- ;
- Org 100H ;Set start addr for COM module.
- MainStart: Jmp MainRoutine
- ;
- Version5 DB 0
- DefaultSortKey DB 0
- GotQuiet DB 0
- IpDevice DB ?
- DosStart_Hou DB ? ;Start time Hour
- DosStart_Min DB ? ; Min
- DosStart_Sec DB ? ; Sec
- DosStart_Hun DB ? ; Hundredths
- DosEnds_Hou DB ? ;End time Hour
- DosEnds_Min DB ? ; Min
- DosEnds_Sec DB ? ; Sec
- DosEnds_Hun DB ? ; Hundredths
-
-
- TimeMsg DB 'Processing Took '
- TimeMsgHou DB '00'
- DB ':'
- TimeMsgMin DB '00'
- DB ':'
- TimeMsgSec DB '00'
- DB '.'
- TimeMsgHun DB '00'
- DB CR,LF
- TimeMsgLen EQU $ - TimeMsg
- ;
- ; Syntax Errors
- ;
- SlashNullMsg DB '001: Slash (/) must be followed by a parameter.$'
- BadSwitchMsg DB '002: Illegal parameter: $'
- SecondTFMsg DB '003: Only one /X switch is allowed.$'
- PAndCNgMsg DB '004: /P and /C are incompatible.$'
- BadRcdLenMsg DB '005: Record len must be between 1 and 32,750 in: $'
- PNotFNGMsg DB '006: Pascal string key only allowed in fixed len '
- DB 'record: $'
- PMustBeFMsg DB '007: /P only allowed for fixed length records.$'
- NumbNotFNGMsg DB '008: Binary number key (F,I,M,T or U) '
- DB 'only allowed in fixed len record: $'
- FixNotAllowMsg DB '009: /X switch not allowed for fixed length records.$'
- ;BadStartParmMsg DB '015: Syntax for /S parameter is /S[-]nnn not: $'
- ;BigStartParmMsg DB '016: ASCII code in /S parameter must not exceed 255: $'
- BadDriveMsg DB '010: One and only one temp drive letter may be entered: $'
- NotExistMsg DB '011: Non-existent drive: $'
- NgDriveMsg DB '012: Invalid character for the drive: $'
- BadStartMsg DB '013: Start column must be between 1 and 32,750: $'
- BigStartMsg DB '014: Start column must not exceed record len: $'
- SecondStartMsg DB '015: Only one start column allowed: $'
- BadKeyMsg DB '016: Error in sort key: $'
- BadKeyLenMsg DB '017: Key len must be between 1 and 32,750: $'
- BigKeyLenMsg DB '018: Key len is too big to fit in record: $'
- SecondKeyLenMsg DB '019: Only one key length allowed: $'
- NGFloatLenMsg DB '020: Length for 80x87 floating point number'
- DB ' must be 4, 8 or 10: $'
- NGMicroLenMsg DB '021: Length for GWBASIC/BASICA floating '
- DB 'point number must be 4 or 8: $'
- NGTurboLenMsg DB '022: Length for Turbo Pascal floating point'
- DB ' number must be 6: $'
- PascalLenNGMsg DB '023: Length for Pascal strings must be between 2 and 256:'
- DB ' $'
- PascalDefNGMsg DB '024: Length for Pascal strings must be between 2 and 256.$'
- PascalZeroNGMsg DB '025: "P" and "C" attributes are incompatible: $'
- SwitchKeyNGMsg DB '026: C attribute conflicts with /P: $'
- BinaryStringMsg DB '027: Sort key cannot be both a binary number and a string: $'
- DiffBinaryMsg DB '028: Only one binary key type allowed in a sort key: $'
- SecondIpMsg DB '029: Only one list of input files and a single output'
- DB ' file may be given.',13,10
- DB ' Found additional file spec: $'
- OutputPlusMsg DB '030: Multiple files not allowed in output spec: $'
- MisplacedMsg DB '031: Misplaced plus sign in input file list: $'
- FileAndRedirMsg DB '032: Input is redirected to the standard input, '
- DB 'so output must go to',13,10
- DB ' the standard output. The following file spec '
- DB 'is illegal: $'
- DeviceMsg DB '033: You must specify an input file.$'
- NoErrorSpecMsg DB '034: No name specified for error file: $'
- ;
- VersionMsg DB '037: RPSORT requires MS DOS version 2.00 or later.$'
- ;
- ; Memory Problems
- ;
- NoMemoryMsg DB '040: Not enough memory. RPSORT requires 30,000 bytes.$'
- TwoRcdMsg DB '041: Not enough memory to hold at least two '
- DB 'records/lines at a time.$'
- ;
- ; File Doesn't Meet RPSORT Requirements
- ;
- LinGTMaxMsg DB '043: Line exceeds max length of 32750 bytes.$'
- PascTooLongMsg DB '044: Found Pascal string whose length byte '
- DB 'exceeds specified key length.$'
- ;
- ; Input/Output Problems
- ;
- NoDataMsg DB '046: No data in input file(s) so nothing to do.$'
- NoFileMsg DB '047: Input file not found: '
- NoFileEnd Label Byte
- ReadErrorMsg DB '048: Error reading input file.$'
- FullOutMsg DB '049: No room on disk to write sorted output file.$'
- FullTempMsg DB '050: No room on disk to write temp file.$'
- NoTempDirMsg DB '051: Unable to create temp file.$'
- NoOpDirMsg DB '052: Unable to create output file.$'
- FullErrDirMsg DB '053: Unable to create error file: $'
- FullErrMsg DB 13,10,' ERROR 054: Ran out of space on disk attempting '
- DB 'to write error file.',13,10
- DB ' Redirecting error messages to the screen.',13,10
- FullErrEnd Label Byte
- ;
- ; Unexpected Errors
- ;
- AllocMsg DB '059: Error allocating memory. $'
- DiskErrorMsg DB '060: Unknown error accessing disk.$'
- ;
- SuccessMsg DB 13,10,'Sort successfully completed.',13,10
- SuccessEnd Label Byte
- SyntaxMsg DB 13,10,'Enter the RPSORT command with no parameters to get '
- DB 'a description of the syntax.',13,10
- SyntaxFin Label Byte
- ShortRcdMsg DB 13,10,'Found short record at end of input file. Will'
- DB ' delete it from output file.',13,10
- ShortRcdEnd Label Byte
- MissCRLFMsg DB 13,10,'Added carriage return and line feed which '
- DB 'was missing for last line in file.',13,10
- MissCRLFEnd Label Byte
- ;
- QuitMsg DB 13,10,'Do you wish to quit RPSORT? Press "Esc" to quit, any'
- DB ' other key to continue.',13,10
- QuitEnd Label Byte
- ContinueMsg DB 'Continuing...',13,10
- ContinueEnd Label Byte
- ;
- Even
- XlatTable DB 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
- DB 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31
- DB ' !"#$%&',39,'()*+,-./0123456789:;<=>?'
- DB '@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_'
- DB '`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~',127
- ForeignChars DB 'CUEAAAACEEEIIIAAEAAOOOUUYOU$$$$$AIOUNN'
- DB 166,167,'?',169,170,171,172,'!',34,34
- DB 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191
- DB 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207
- DB 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223
- DB 224,'S',226,227,228,229,230,231,232,233,234,235,236,237,238,239
- DB 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255
- ;
- IndicatorBits DB KeyAscii,255,KeyZero,255,255,81H,255,255
- DB KeyInteger,255,255,255,KeyMicro,255,255,KeyPascal,255
- DB KeyReverse,255,KeyTurbo,KeyUnsigned,255,255,255,255,255
- ;
- MainRoutine Proc Near
- Mov AX,GetTime ;Get Start Time
- Int Dos
- Mov DosStart_Hou,CH
- Mov DosStart_Min,CL
- Mov DosStart_Sec,DH
- Mov DosStart_Hun,DL
- Sti
- Call DoCopyRight
- Mov AX,DosVersion
- Int DOS
- Cmp AL,2
- Jae Main2
- Mov DX,Offset VersionMsg
- Jmp DisplayExit
- Main2: Cmp AL,5
- Jb Main3
- Mov Version5,0FFH
- Mov CommandSize,0A00H
- Mov LeaveCmdSize,2E00H
- Main3: Mov AX,SetDTA
- Mov DX,Offset DiskXferArea
- Int DOS
- Mov AX,CurrDisk
- Int DOS
- Add AL,41H
- Mov DefaultDisk,AL
- Mov SI,Offset CompRtnEnd - 1 ;End of code to move.
- Mov DI,SP
- Sub DI,512 ;End addr for dest of move.
- ;Leaves 512 bytes for stack.
- Cmp DI,SI ;Jump if stk alloc overlays code
- Ja ChkStdIP
- Jmp NoMemory ;and mem is thus too small.
- ChkStdIP: Mov AX,IoctlGet
- Mov BX,StdInput ;Handle for std ip.
- Int DOS ;Ck if ip is a device.
- Mov IpDevice,DL ;If no sign, it is a file
- Mov CX,Offset CompRtnEnd - Offset CompRoutine
- Std
- Rep Movsb
- Inc DI
- Mov ModelCodeLoc,DI
- Sub DI,Offset CompRoutine
- Mov CompMove,DI
- DoGetParms: Call GetParms ;Parse switches and sort keys.
- Cmp CodePointer,Offset CompRoutine
- Jnz ChkIfError ;Chk if sort keys were given.
- Cmp GotSortKey,0
- Jnz ChkIfError
- Mov DefaultSortKey,0FFH
- Call CreateKey ;If no keys given, create std key.
- Call ChkKeyInRcd
- ChkIfError: Cmp GotError,0
- Jz MoveStack
- Mov DX,Offset SyntaxMsg
- Mov CX,Offset SyntaxFin - Offset SyntaxMsg
- Call WriteStdError2
- Jmp ErrorExit
- MoveStack: Mov DI,CodePointer
- Add DI,512 ;Allow 512 byte stack after key code.
- And DI,0FFFEH
- Mov SP,DI ;Prev code assures this is avail.
- Call SetupCtrlBrk
- Call SetupMemory
- Cmp InputFileCt,0 ;If zero then no filespecs.
- Jnz NextSpec2
- CallLoadStd: Call LoadStd ;Use std ip.
- Jmp Short DoSetPtrs
- NextSpec: Mov AL,InputFileCt
- Or AL,WildCard
- Jz DoSetPtrs
- NextSpec2: Call LoadSpec
- Jnc NextSpec ;Go back if mem avail.
- DoSetPtrs: Cmp GotData,0
- Jnz DoSetPtrs2
- Mov DX,Offset NoDataMsg
- Jmp DisplayExit
- DoSetPtrs2: Mov Byte Ptr FromMain,0FFH
- Call SetupPointers ;Create array of ptrs to lines.
- Call SortData ;Qsort of ptrs based on keys in lines
- Cmp FinalOutput,0
- Jz NotFinal
- Cmp GotOutput,0
- Jz DoWriteData
- Call OpenOutput
- Jmp Short DoWriteData
- NotFinal: Cmp WriteHandle,StdOutput
- Ja DoWriteData
- Call SetupTempFiles
- DoWriteData: Call WriteData ;Use ptrs to write lines in seq.
- Cmp MoreData,0
- Jz CheckMerge
- Mov Byte Ptr NeedMerge,0FFH
- Call ReSetupMemory
- Cmp HaveSpecs,0
- Jz CallLoadStd
- Jmp NextSpec2
- CheckMerge: Cmp NeedMerge,0
- Jz GoBackOk
- Call MergeData ;Mod WriteData code and do merge.
- GoBackOk: Cmp GotQuiet,0
- Jnz SetRetZero
- Mov DX,Offset SuccessMsg
- Mov CX,Offset SuccessEnd - Offset SuccessMsg
- Call WriteStdError2
- SetRetZero: Xor AX,AX ;Ret code is 0.
- GoBack: Push AX
- Cmp ErrorHandle,StdError
- Jz GoBack2
- Mov BX,ErrorHandle
- Mov AX,Close ;Close error file.
- Int Dos
- Goback2: Mov AX,SetCtrlState
- Mov DL,CtrlState
- Int Dos
- Call ComputeTime
- Pop AX
- Mov AH,ExitProg
- Int DOS
- MainRoutine Endp
- ;
- ComputeTime Proc Near ;Display Elapsed time
- Mov AX,GetTime ;Get End Time
- Int Dos
- Mov DosEnds_Hou,CH
- Mov DosEnds_Min,CL
- Mov DosEnds_Sec,DH
- Mov DosEnds_Hun,DL
- Mov AL,DL
- Mov AH,100
- Mov Di,offset TimeMsgHun
- Sub AL,DosStart_Hun
- Call Conv_Byte
-
- Mov AL,DosEnds_Sec
- Mov AH,60
- Mov Di,offset TimeMsgSec
- Sbb AL,DosStart_Sec
- Call Conv_Byte
-
- Mov AL,DosEnds_Min
- Mov AH,60
- Mov Di,offset TimeMsgMin
- Sbb AL,DosStart_Min
- Call Conv_Byte
-
- Mov AL,DosEnds_Hou
- Mov AH,24
- Mov Di,offset TimeMsgHou
- Sbb AL,DosStart_Hou
- Call Conv_Byte
- Mov DX,Offset TimeMsg
- Mov CX,TimeMsgLen
- Call WriteStdError2
- Ret
-
- ComputeTime Endp
-
- Conv_Byte proc near ;convert binary byte to hex ASCII.
- ;call with AL = binary value
- ; DI = addr to store string
- ;returns AX, DI, CX modified.
-
- pushf
- cmp Ah,Al
- Ja Conv_Byte2
- Xor Cl,Cl ;If > max, convert it to max-based
- Sub Cl,Al ; 256 - number -> max - number
- Sub Ah,Cl
- Mov Al,Ah
- Conv_Byte2: Xor ah,ah ;clear upper byte
- mov cl,10 ;Divide binary data by 10
- div cl ;to force to decimal
- call Ascii ;the quotient becomes the first
- stosb ;ASCII character.
- mov al,ah
- call Ascii ;the remainder becomes the second
- stosb ;ASCII character.
- popf
- ret
- Conv_Byte endp
-
- Ascii proc near ;convert value 0-0fFH in AL
- add al,'0' ;into a "hex ASCII" character.
- cmp al,'9'
- jle Ascii2 ;jump if in range 0-9,
- add al,'A'-'9'-1 ;offset it to range A-F
- Ascii2: ret ;return ASCII char in AL.
- Ascii endp
-
- DoCopyRight Proc Near
- Mov SI,Offset Parms ;Ofs of cmd line parms.
- Xor CX,CX
- Mov CL,ParmsLen ;Len of cmd line parms.
- Mov ParmBegInit,SI
- Mov ParmCharsInit,CX
- Mov BX,Offset XlatTable
- FindSlashQ: Jcxz DispCopyRight
- Dec CX
- Lodsb
- Cmp AL,Space
- Jz FindSlashQ
- Cmp AL,Slash
- Jnz DispCopyRight
- Jcxz DispCopyRight
- Dec CX
- Lodsb
- Xlat
- Cmp AL,QuietParm
- Jnz DispCopyRight
- Mov GotQuiet,0FFH
- Mov ParmBegInit,SI
- Mov ParmCharsInit,CX
- Ret
- DispCopyRight: Mov DX,Offset CopyRightMsg
- Mov CX,Offset CopyRightEnd - Offset CopyRightMsg
- Call WriteStdError2
- Ret
- DoCopyRight Endp
- ;
- SetupCtrlBrk Proc Near
- Mov AX,GetCtrlState
- Int DOS
- Mov CtrlState,DL
- Mov AX,SetCtrlState
- Mov DL,CtrlStateOn
- Int DOS
- Mov AX,SetCtrlVect
- Mov DX,Offset CtrlBrkHandler
- Int DOS
- Cmp GotOutput,0
- Jz SetupCtrlRet
- Mov AX,OpenForWrite
- Mov DX,Offset NulASCIIZ
- Int DOS
- Mov BX,AX
- Mov CX,StdOutput
- Mov AX,ForceDup
- Int DOS
- SetupCtrlRet: Ret
- SetupCtrlBrk Endp
- ;
- CtrlBrkHandler Proc Far
- Push AX
- Push BX
- Push CX
- Push DX
- Push SI
- Push DI
- Push BP
- Push DS
- Push ES
- Push CS
- Pop DS
- Cmp NoBreak,0
- Jnz DontBreak
- Test IpDevice,80H
- Jz DoExit
- Cmp GotOutput,0
- Jz DoExit
- AskYN: Mov DX,Offset QuitMsg
- Mov CX,Offset QuitEnd - Offset QuitMsg
- Call WriteStdError2
- StdIPIsDevice: Mov AX,ClearReadNoEcho
- Int DOS
- ChkEscp: Cmp AL,Escp
- Jz DoExit
- Mov DX,Offset ContinueMsg
- Mov CX,Offset ContinueEnd - Offset ContinueMsg
- Call WriteStdError2
- DontBreak: Cmp GotOutput,0
- Jnz DontBreak2
- Mov AX,GetFileLoc
- Xor CX,CX
- Mov DX,CX
- Mov BX,StdOutput
- Int DOS
- Jc DontBreak2
- Mov CX,DX
- Mov DX,AX
- Sub DX,4
- Sbb CX,0
- Jc DontBreak2
- Mov AX,SetFileAtBeg
- Mov BX,StdOutput
- Int DOS
- DontBreak2: Clc
- Jmp Short CtrlBrkRet
- DoExit: Call FinalDeletes
- Stc
- CtrlBrkRet: Pop ES
- Pop DS
- Pop BP
- Pop DI
- Pop SI
- Pop DX
- Pop CX
- Pop BX
- Pop AX
- Ret
- CtrlBrkHandler Endp
- ;
- Even
- ;
- DataArea Equ $
- ;
- Data BegSegm 64 Dup(<>) ;Pts to first byte of ip data.
- DataEnd DW 64 Dup(?) ;Pts after end of ip data.
- ;
- BlockOfs DD 64 Dup(?) ;Offset in block on disk to read from next.
- BlockPos DD 64 Dup(?) ;Offset in file on disk of block.
- BlockLen DD 64 Dup(?) ;Length of block on disk.
- ;
- Pointer BegSegm 16 Dup(<>)
- PointerEnd DW 16 Dup(?) ;Pts to byte after end of ptrs.
- ;
- TopIndex DW 64 Dup(?)
- ;
- WriteBuff BegSegm <>
- MemoryBegSeg DW ? ;Beg of avail mem.
- MemoryEndSeg DW ? ;End of avail mem.
- BelowLow DW ? ;3/4 of avail memory para below
- BelowHi DW ? ;the location of transient COMMAND.COM.
- BegSeg DW ?
- BegOfs DW ?
- NextSeg DW ? ;Next avail seg addr.
- NextOfs DW ?
- LastSeg DW ?
- PtrSeg DW ?
- PtrOfs DW ?
- FileSizeLo DW ?
- FileSizeHi DW ?
- MemParaAvail DW ?
- MaxSegCount DW ?
- MaxSegSize DW ?
- Handle DW ?
- UseHandle DW ?
- ExtraEnd DD ?
- MaxSegs DW ?
- BegBlock DW ? ;Block that goes into first mem seg this time.
- EndBlock DW ? ;Block that goes into last mem seg this time.
- BlockSeg DW ? ;Segment for table of block locations.
- NewBlockCt DW ? ;BlockCt to be used in next phase of merge.
- NewBlockSeg DW ? ;Segment for new table of block locations.
- NewBlockBeg DW ? ;First entry in new table of block locations.
- NewBlockEnd DW ? ;Next entry in new table of block locations.
- RemainderSegs DW ?
- ExtraHandle DW ?
- IpNamePtr DW ?
- ;
- TempName1 DB 15 Dup(?)
- TempName2 DB 15 Dup(?)
- TempName3 DB 15 Dup(?)
- ;
- DiskXferArea DB 21 Dup(?)
- IpAttr DB ?
- IpTime DW ?
- IpData DW ?
- IpSize DD ?
- IpNameExt DB 13 Dup(?)
- IpASCIIZ DB 128 Dup(?)
- ;
- Org DataArea
- ;
- CopyRightMsg DB 13,10,'RPSORT v1.02 Dec. 15, 1992,'
- DB ' Copyright 1991 by Bob Pirko,'
- DB ' All rights reserved',13,10
- CopyRightEnd Label Byte
- ;
- Syntax DB 13,10,'Usage: RPSORT [/Q] [/Eerrfile] [/]? [in' ;01
- DB 'putfile[+inputfile]] [outputfile] [/A]'
- DB 13,10,' [/B] [/C] [/D] [/Fnnnn] [/N] ' ;02
- DB '[/P] [/R] [/Td] [/Z] [sort key defin...]',13,10
- DB 13,10,'Sort key defin syntax: /+ [col] [:len]' ;04
- DB ' [A] [C] [F] [I] [M] [P] [R] [T] [U]'
- DB 13,10,'---------------------------------------' ;05
- DB '----------------------------------------'
- SyntaxEnd Label Byte
- ;
- LastLine DB 13,10,' (Press PageUp or'
- LastLine2 DB ' PageDown'
- LastLine3 DB ' to see other syntax screens or Esc to exit)'
- LastLineEnd Label Byte
- ;
- Syntax1Screen DB 13,10,'RPSORT greatly improves upon the featur' ;06
- DB 'es and the performance of the sort'
- DB 13,10,'utility distributed with Microsoft DOS.' ;07
- DB ' First, RPSORT does everything that'
- DB 13,10,'the DOS SORT does. Virtually any comma' ;08
- DB 'nd that works with the DOS SORT will'
- DB 13,10,'work with RPSORT and produce the same r' ;09
- DB 'esult.',13,10
- DB 13,10,'But RPSORT does much more. It can sort' ;11
- DB ' very large files and supports multiple'
- DB 13,10,'sort keys. It is extremely fast. I kn' ;12
- DB 'ow of no sort utility that outspeeds it.',13,10
- DB 13,10,'RPSORT sorts text files. These consist' ;14
- DB ' of lines each ended by CRLF (i.e. a'
- DB 13,10,'carriage return and a line feed). It a' ;15
- DB 'lso sorts files of fixed length records'
- DB 13,10,'such as those produced by many BASIC, P' ;16
- DB 'ascal and C language programs.',13,10
- DB 13,10,'RPSORT supports numerous sort key types' ;18
- DB ' including regular text keys, C language'
- DB 13,10,'strings, Turbo Pascal strings, signed a' ;19
- DB 'nd unsigned binary integers of any'
- DB 13,10,'length and several types of binary floa' ;20
- DB 'ting point numbers.',13,10
- DB 13,10,'RPSORT can delete null lines (consistin' ;22
- DB 'g only of CRLF). It can also delete'
- DB 13,10,'records/lines whose sort keys duplicate' ;23
- DB ' those in a previous record/line.',13,10
- DB 13,10,' (Press ' ;25
- Syntax1End Label Byte
- ;
- Syntax2Screen DB 13,10,'Parameters may be entered in any order ' ;06
- DB 'except as noted below.',13,10
- DB 13,10,'RPSORT may be run as a filter using red' ;08
- DB 'irection.',13,10
- DB 13,10,' For example: RPSORT <ipfile >opfile';10
- DB 13,10,' or: DIR | RPSORT | MORE',13,10 ;11
- DB 13,10,'Input and output may be specified direc' ;13
- DB 'tly. Input is one or more filespecs'
- DB 13,10,'separated by plus signs. Output must b' ;14
- DB 'e a single file. Input filespec(s) must'
- DB 13,10,'precede output filespec. Filespecs may' ;15
- DB ' include a path. Wildcard characters'
- DB 13,10,'are allowed. Input files are sorted to' ;16
- DB 'gether into the single output file.',13,10
- DB 13,10,' For example: RPSORT ipfile*.txt+c' ;18
- DB ':\mydir\ip??file.txt opfile',13,10
- DB 13,10,'By default, RPSORT assumes the input is' ;20
- DB ' a text file and that the entire line is'
- DB 13,10,'the sort key. The sort is case insensi' ;21
- DB 'tive (lower equals upper case) and just'
- DB 13,10,'like the DOS SORT it equates foreign le' ;22
- DB 'tters, punctuation, and currency symbols'
- DB 13,10,'to their English equivalents. The foll' ;23
- DB 'owing screens describe other options.',13,10
- Syntax2End Label Byte
- ;
- Syntax3Screen DB 13,10,'/Q if it is the first parameter suppres' ;06
- DB 'ses copyright and success messages.'
- DB 13,10,'/Eerrfile directs error messages to a f' ;07
- DB 'ile. Should precede all but /Q.'
- DB 13,10,'/? or ? produces these syntax screens. ' ;08
- DB ' RPSORT with no parameters also does.'
- DB 13,10,'/A does an ASCII sort. This is case se' ;09
- DB 'nsitive (lower not equal upper case).'
- DB 13,10,'/B tells RPSORT to ignore any control b' ;10
- DB 'reak entered from the keyboard.'
- DB 13,10,'/C says that text keys are terminated b' ;11
- DB 'y a binary zero (C language strings).'
- DB 13,10,'/D deletes any record whose sortkeys du' ;12
- DB 'plicate those in a previous record.'
- DB 13,10,'/Fnnnn says that the input consists of ' ;13
- DB 'fixed length records of nnnn bytes.'
- DB 13,10,'/N deletes any null lines (those consis' ;14
- DB 'ting only of a CRLF sequence).'
- DB 13,10,'/P uses the first byte of text keys as ' ;15
- DB 'the key length (Turbo Pascal strings).'
- DB 13,10,'/R specifies a reverse (descending orde' ;16
- DB 'r) sort.'
- DB 13,10,'/Td designates drive to be used for tem' ;17
- DB 'p files instead of default drive.'
- DB 13,10,'/Z says to ignore any Ctrl-Z in a text ' ;18
- DB 'file and use the entire file. Normally'
- DB 13,10,' RPSORT (just like MS-DOS) treats Ctr' ;19
- DB 'l-Z as the end of a text file.',13,10
- DB 13,10,'/R applies to all sort key definitions ' ;21
- DB 'while /A, /C and /P apply to all text'
- DB 13,10,"sort keys. Sort key definitions can't " ;22
- DB 'over-ride them. To sort some keys one'
- DB 13,10,'way and some another way, use the sort ' ;23
- DB 'key attributes on the next screen.',13,10
- Syntax3End Label Byte
- ;
- Syntax4Screen DB 13,10,'A sort key definition has the above for' ;06
- DB 'm with no spaces between the attributes.',13,10
- DB 13,10,' col is starting column of this key. ' ;08
- DB ' Col 1 is the first col in the record.'
- DB 13,10,' len is the length of this key.' ;09
- DB 13,10,' A does an ASCII (case sensitive) s' ;10
- DB 'ort for the key.'
- DB 13,10,' C treats a binary zero as the end ' ;11
- DB 'of the key (i.e. a C type string).'
- DB 13,10,' Len should equal max C string le' ;12
- DB 'ngth (e.g. if "char mystr[8]", len = 8).'
- DB 13,10,' F sorts this key as 80x87 binary f' ;13
- DB 'loating point number. Len is 4, 8 or 10.'
- DB 13,10,' I sorts this key as a signed binar' ;14
- DB 'y integer. This may be any length.'
- DB 13,10,' M sorts this key as a binary float' ;15
- DB 'ing point number defined by BASICA,'
- DB 13,10,' GWBASIC or older versions of Mic' ;16
- DB 'rosoft QuickBASIC. Len is 4 or 8.'
- DB 13,10,' P uses the first byte of this key ' ;17
- DB 'as the key length (a Pascal string).'
- DB 13,10,' Len must equal max Pascal string' ;18
- DB ' length + 1 (e.g. if string[8] len = 9).'
- DB 13,10,' R does a reverse (descending) sort' ;19
- DB ' for this key.'
- DB 13,10,' T sorts this key as a Turbo Pascal' ;20
- DB ' number of type "real". Len must be 6.'
- DB 13,10,' U sorts this key as an unsigned bi' ;21
- DB 'nary integer. This may be any length.',13,10
- DB 13,10,'Attributes F, I, M, P, T and U are only' ;23
- DB ' allowed for fixed length records.',13,10
- Syntax4End Label Byte
- ;
- Syntax5Screen DB 13,10,'1. RPSORT as a filter. Input is a text' ;06
- DB ' file. Sort key is the entire line.',13,10
- DB 13,10,' RPSORT <DATAINP.DAT >SORT.DAT' ;08
- DB 13,10
- DB 13,10,'2. Combine two files. Do an ASCII (cas' ;10
- DB 'e sensitive) sort. Write the output to'
- DB 13,10,' SORT.DAT. Put temp files on the C d' ;11
- DB 'rive. Key is 5 bytes at column 4.',13,10
- DB 13,10,' RPSORT DATA1.DAT+C:\MYDIR\DATA2' ;13
- DB '.DAT SORT.DAT /TC /A /+4:5',13,10
- DB 13,10,'3. Sort a file of 90 byte records. The' ;15
- DB ' first key is a Turbo Pascal real number'
- DB 13,10,' at column 15. The second key is a T' ;16
- DB 'urbo Pascal string of type string[11].',13,10
- DB 13,10,' RPSORT PASFILE.DAT SORTFILE.DA' ;18
- DB 'T /F90 /+15:6T /+1:12P',13,10
- DB 13,10,'4. Sort a file of 70 byte records. Bot' ;20
- DB 'h keys are C type strings. The first'
- DB 13,10,' key is ASCII (case sensitive) the se' ;21
- DB 'cond is case insensitive by default.',13,10
- DB 13,10,' RPSORT CFILE.DAT SORT.DAT /F70' ;23
- DB ' /C /+5:10A /+23:7',13,10
- DB 13,10,' (Press PageUp' ;25
- Syntax5End Label Byte
- ;
- Syntax1List DW Syntax,SyntaxEnd-Syntax
- DW Syntax1Screen,Syntax1End-Syntax1Screen
- DW LastLine2,LastLineEnd-LastLine2
- Syntax2List DW Syntax,SyntaxEnd-Syntax
- DW Syntax2Screen,Syntax2End-Syntax2Screen
- DW LastLine,LastLineEnd-LastLine
- Syntax3List DW Syntax,SyntaxEnd-Syntax
- DW Syntax3Screen,Syntax3End-Syntax3Screen
- DW LastLine,LastLineEnd-LastLine
- Syntax4List DW Syntax,SyntaxEnd-Syntax
- DW Syntax4Screen,Syntax4End-Syntax4Screen
- DW LastLine,LastLineEnd-LastLine
- Syntax5List DW Syntax,SyntaxEnd-Syntax
- DW Syntax5Screen,Syntax5End-Syntax5Screen
- DW LastLine3,LastLineEnd-LastLine3
- SyntaxLastList Label Word
- SyntaxPtrs DW Syntax1List,Syntax2List,Syntax3List,Syntax4List
- DW Syntax5List,SyntaxLastList
- SyntaxScrNo DW 0
- ;
- Even
- ;
- ParmBeg DW ?
- ParmChars DW ?
- ParmBegInit DW ?
- ParmCharsInit DW ?
- CodePointer DW CompRoutine
- ModelCodeLoc DW ?
- CompMove DW ?
- FixedLen DW 0
- LongestLen DW 0
- MaxAllowLen DW 32750
- KeyTypInit DW 0
- KeyTyp DW 0
- StartCol DW 0
- RelCol DW 0
- KeyLen DW 0
- PrevEndCol DW 0
- LenBuckSize DW 2
- WriteHandle DW StdOutput
- OutputHandle DW StdOutput
- ReadHandle DW StdInput
- ErrorHandle DW StdError
- TempHandle1 DW 0
- TempHandle2 DW 0
- TempHandle3 DW 0
- ExtraNumb DW 0
- HowManySegs DW 0
- ThisTimeSegs DW 0
- LineEnd DW CRLF
- NewLine DW CRLF
- DataMax DW 65520
- DataPara DW 0FFFH
- SegCount DW 0 ;SegCount = (seg ct) * 2.
- SegNumb DW 0 ;Segment info ptr.
- MaxPara DW 23FEH ;This is 144K. Allows loading full 64K of data.
- MinPara DW 0C00H ;Require 48K (or 1/3 total mem) to load data.
- MinBuff DW 0400H ;Reserve 16K (or 1/9 total mem) for write buff.
- MergeBuff DW 0800H ;Reserve 32K for writebuff during merge.
- MergeSeg DW 0400H ;Let minimum merge segment be 16K.
- BlockCt DW 0 ;Count of entries in table of block locations.
- BlockBeg DW 0008H ;First entry in table of block locations.
- BlockEnd DW 0008H ;Next entry in table of block locations.
- PointerMax DW 65520 ;Max val for ptr end.
- WriteBuffEnd DW 65535 ;Max space for write buff.
- PrevAddr Label DWord
- PrevOfs DW 0FFFFH
- PrevSeg DW 0
- PrevBuffOfs DW 0FFFFH
- InputAddr DW ?
- InputEnd DW ?
- ErrorAddr DW ?
- OutputAddr DW ?
- OutputEnd DW ?
- StackHigh DW ?
- All1Start DW ?
- SecondStart DW ?
- Fix1Start DW ?
- Line1Start DW ?
- CompFinish DW ?
- OrigStart DW ?
- FixPlus2 DW ?
- ParmOfs DW ? ;Pts to next byte of cmd line parms.
- ParmBytes DW ? ;Ct of remain cmd line bytes.
- RetFromErrSP DW ?
- ReservedForPtrs DW 0
- CommandSize DW 0600H
- LeaveCmdSize DW 2A00H
- ;
- ERRORWord DB ' ERROR '
- DidErrorWord DB 0
- Quote DB '"'
- TwelveSpaces DB 13,10,12 Dup(' ')
- GotParms DB 0
- GotSortKey DB 0
- GotInput DB 0
- GotOutput DB 0
- FromMain DB 0
- MoreData DB 0
- NeedMerge DB 0
- FinalOutput DB 0FFH
- OpenedOutput DB 0
- HaveSpecs DB 0
- EndData DB 0
- InputFileCt DB 0
- WildCard DB 0
- TotalFileCt DB 1
- DefaultDisk DB 0
- TempDisk DB 0
- UseRcdLen DB 0
- GotCtrlZ DB 0
- PrtCtrlZ DB 1AH
- SkipSetupTop DB 0
- IgnoreCtrlZ DB 0
- FirstExtra DB 0FFH
- FirstMerge DB 0FFH
- UseExtra DB 0
- LastIsExtra DB 0
- MustSetPtrs DB 0
- ElimDup DB 0
- ElimNull DB 0
- NoBreak DB 0
- ParmPass DB 0
- GotData DB 0
- GotStringParm DB ?
- GotBinaryParm DB ?
- GotCParm DB ?
- GotPParm DB ?
- GotEParm DB ?
- CtrlState DB ?
- GotError DB 0
- KeyCount DB 0
- GotKeyErr DB 0
- ErrorCode DB 0
- PtrsAgain DB 0
- NulASCIIZ DB 'NUL',0
- ;
- GetParmsFin Proc Near
- Cmp ParmPass,2
- Jb GetParms
- Cmp GotParms,0
- Jnz GetParmsRet
- Mov AX,IoctlGet
- Mov BX,StdInput ;Handle for std ip.
- Int DOS ;Ck if ip is a device.
- Or DL,DL ;If no sign, it is a file
- Jns GetParmsRet ;else it is a device.
- Jmp HelpScreen
- GetParmsRet: Ret
- ;
- GetParmsFin Endp
- ;
- DoDisplayError: Call DisplayError
- Jmp Short RestorePtr
- DoDispErrParm: Call DispErrorParm
- RestorePtr: Mov SP,RetFromErrSP
- Mov CX,ParmChars
- Mov SI,ParmBeg
- Dec CX
- Inc SI
- SkipParm: Jcxz NextParmChar
- Lodsb
- Dec CX
- Cmp AL,Space
- Jz NextParmChar
- Cmp AL,Slash
- Jnz SkipParm
- Dec SI
- Inc CX
- Jmp Short NextParmChar
- ;
- GetParms Proc Near
- Cld
- Mov RetFromErrSP,SP
- Inc ParmPass
- Mov SI,ParmBegInit ;Ofs of cmd line parms.
- Mov CX,ParmCharsInit ;Len of cmd line parms.
- Mov BX,Offset XlatTable
- NextParmChar: Jcxz GetParmsFin ;No more parms if CX = 0.
- Mov ParmBeg,SI
- Mov ParmChars,CX
- Lodsb
- Dec CX
- Cmp AL,Space
- Jz NextParmChar
- Cmp AL,Question
- Jnz IsItSlash
- Jmp HelpScreen
- IsItSlash: Cmp AL,Slash
- Jz GotSlash
- Cmp ParmPass,1
- Jz DoFileName
- Jmp SkipParm
- DoFileName: Mov GotParms,0FFH
- Call SaveFileAddr
- Jmp NextParmChar
- GotSlash: Jcxz ErrSlashNull ;/ must be followed by something.
- Dec CX
- Lodsb ;Load char following /.
- Cmp AL,Question
- Jnz GotParm
- Jmp HelpScreen
- ErrSlashNull: Mov DX,Offset SlashNullMsg
- Jmp DoDisplayError
- GotParm: Mov GotParms,0FFH
- Cmp AL,Space
- Jz ErrSlashNull
- Cmp AL,Slash
- Jnz IsItSortKey
- Inc CX
- Dec SI
- Jmp ErrSlashNull
- IsItSortKey: Cmp AL,'+' ;Is it sort key spec.
- Jz DoSortKey ;If "+" then must be sort key.
- Cmp AL,'0' ;If number then
- Jb MustBeSwitch ;must be
- Cmp AL,':' ;sortkey.
- Ja MustBeSwitch
- Inc CX
- Dec SI
- DoSortKey: Cmp ParmPass,2
- Jz DoGetSortKey
- Jmp SkipParm
- DoGetSortKey: Call GetSortKey
- Jmp NextParmChar
- MustBeSwitch: Cmp ParmPass,1
- Jz DoSwitch
- Jmp SkipParm
- DoSwitch: Xlat ;Lower case to upper case.
- Mov DX,AX
- Call GetIndicBit ;Chk for valid parm.
- Js IsItFixed ;Jump if not.
- Cmp AX,KeyPascal
- Ja IsItFixed ;Jump if not valid global parm.
- Or KeyTypInit,AX ;Set global switch bit.
- Jmp Short CheckExtraChar
- ErrBadRcdLen: Mov FixedLen,32750
- Mov DX,Offset BadRcdLenMsg
- Jmp DoDispErrParm
- IsItFixed: Mov AX,DX
- Cmp AL,FixedParm
- Jnz ChkIfIgnCtrlZ
- Cmp FixedLen,0
- Jz TestFixedLen
- Mov AX,3446H ;Error 004: second /F.
- Jmp Short Second
- TestFixedLen: Jcxz ErrBadRcdLen
- Dec CX
- Lodsb
- Call GetNumb
- Cmp DX,32750
- Ja ErrBadRcdLen
- Or DX,DX
- Jz ErrBadRcdLen
- Mov FixedLen,DX
- Call AnyExtraChar
- Mov LongestLen,DX
- Inc DX
- Inc DX
- Mov FixPlus2,DX
- Mov LenBuckSize,0
- Jmp NextParmChar
- ChkIfIgnCtrlZ: Cmp AL,CtrlZParm
- Jnz ChkIfElimDup
- Mov IgnoreCtrlZ,0FFH
- CheckExtraChar: Call AnyExtraChar
- Jmp NextParmChar
- ChkIfElimDup: Cmp AL,DupParm
- Jnz ChkIfNoBreak
- Mov ElimDup,0FFH
- Jmp CheckExtraChar
- ChkIfNoBreak: Cmp AL,NoBreakParm
- Jnz ChkIfElimNull
- Mov NoBreak,0FFH
- Jmp CheckExtraChar
- ChkIfElimNull: Cmp AL,NullParm
- Jnz ChkIfErrFile
- Mov ElimNull,0FFH
- Jmp CheckExtraChar
- ChkIfErrFile: Cmp AL,ErrorParm
- Jnz ChkIfTemp
- Call CheckErrorFile
- Jmp NextParmChar
- ChkIfTemp: Call IsItTemp
- Jnz BadSwitch
- Jmp CheckExtraChar
- BadSwitch: Mov DX,Offset BadSwitchMsg
- Jmp DoDispErrParm
- Second: Mov SecondTFMsg+15,AL
- Mov SecondTFMsg+2,AH
- Mov DX,Offset SecondTFMsg
- Jmp DoDisplayError
- GetParms Endp
- ;
- AnyExtraChar Proc Near
- Jcxz AnyExtraRet
- Cmp Byte Ptr [SI],Slash
- Jz AnyExtraRet
- Cmp Byte Ptr [SI],Space
- Jz AnyExtraRet
- ExtraChar: Jmp BadSwitch
- AnyExtraRet: Ret
- AnyExtraChar Endp
- ;
- CheckErrorFile Proc Near
- Cmp GotEParm,0
- Jz CheckErrFile2
- Mov AX,3745H ;Error 007: second /E.
- Jmp Second
- CheckErrFile2: Mov GotEParm,0FFH
- Jcxz NoErrorSpec
- Mov ErrorAddr,SI ;Offset of error file name
- Dec CX
- Lodsb
- Cmp AL,Space
- Jz NoErrorSpec
- Cmp AL,Slash
- Jz NoErrorSpec
- NewError: Jcxz GotErrorName
- Lodsb
- Dec CX
- Cmp AL,Space
- Jz DecErrorPtr
- Cmp AL,Slash
- Jnz NewError
- DecErrorPtr: Dec SI
- Inc CX
- GotErrorName: Mov AL,0
- Xchg AL,[SI]
- Push AX
- Push SI
- Push CX
- Mov AX,CreateFile
- Mov DX,ErrorAddr
- Xor CX,CX
- Int DOS
- Jc FullErrDir
- Mov ErrorHandle,AX
- Pop CX
- Pop SI
- Pop AX
- Xchg AL,[SI]
- Ret
- NoErrorSpec: Mov DX,Offset NoErrorSpecMsg
- Jmp DoDispErrParm
- FullErrDir: Pop CX
- Pop SI
- Pop AX
- Xchg AL,[SI]
- Mov DX,Offset FullErrDirMsg
- Jmp DoDispErrParm
- CheckErrorFile Endp
- ;
- HelpScreen Proc Near
- Mov SyntaxScrNo,0
- Mov DI,Offset Syntax1List
- Mov SI,Offset Syntax2List
- Call PrintScreen2
- HelpScreen1: Mov AX,ClearReadNoEcho
- Int DOS
- HelpScreen2: Or AL,AL
- Jz GetExtended
- Cmp AL,Escp
- Jz NoMoreScreens
- ReadAnother: Mov AX,ReadNoEcho
- Int DOS
- Jmp HelpScreen2
- GetExtended: Mov AX,ReadNoEcho
- Int DOS
- Cmp AL,PageUp
- Jz DoPageUp
- Cmp AL,PageDown
- Jnz ReadAnother
- DoPageDown: Mov DI,SyntaxScrNo
- Cmp DI,4
- Je ReadAnother
- Inc SyntaxScrNo
- Jmp Short DispScreen
- DoPageUp: Mov DI,SyntaxScrNo
- Cmp DI,0
- Je ReadAnother
- Dec SyntaxScrNo
- DispScreen: Call PrintScreen
- Jmp HelpScreen1
- NoMoreScreens: Xor AL,AL
- Jmp GoBack
- HelpScreen Endp
- ;
- PrintScreen Proc Near
- Mov DI,SyntaxScrNo
- Shl DI,1
- Add DI,Offset SyntaxPtrs
- Lea SI,[DI+2]
- Mov DI,[DI]
- Mov SI,[SI]
- PrintScreen2: Mov DX,[DI]
- Mov CX,[DI+2]
- Call WriteStdError2
- Add DI,4
- Cmp DI,SI
- Jb PrintScreen2
- Ret
- PrintScreen Endp
- ;
- IsItTemp Proc Near
- Cmp AL,TempParm
- Jnz IsItTempRet
- Cmp TempDisk,0
- Jz IsItTemp2
- Mov AX,3654H ;Error 006: second /T.
- Jmp Second
- IsItTemp2: Mov AX,SelectDisk
- Mov DL,DefaultDisk
- Sub DL,41H
- Int DOS
- Add AL,40H
- Mov DL,AL ;Max drive letter.
- Xor DH,DH ;Count of drives
- NextTempDrive: Jcxz CheckTempCt
- Lodsb
- Dec CX
- Xlat
- Cmp AL,Space
- Je CheckTempCt
- Cmp AL,Slash
- Jz CheckTempCT
- Cmp AL,'A'
- Jb BadDriveLett
- Cmp AL,'Z'
- Ja BadDriveLett
- Cmp AL,DL
- Ja NotExistDrive
- Inc DH
- Mov TempDisk,AL
- Jmp NextTempDrive
- CheckTempCT: Dec DH
- Js BadDriveLett2
- Jnz BadDriveLett2
- Jcxz IsItTempOK
- Inc CX
- Dec SI
- IsItTempOK: Xor DX,DX
- IsItTempRet: Ret
- BadDriveLett: Mov DX,Offset NgDriveMsg
- Jmp DoDispErrParm
- BadDriveLett2: Mov DX,Offset BadDriveMsg
- Jmp DoDispErrParm
- NotExistDrive: Mov DX,Offset NotExistMsg
- Jmp DoDispErrParm
- IsItTemp Endp
- ;
- GetIndicBit Proc Near
- Cmp AL,'A'
- Jb MakeFFFF
- Cmp AL,'Z'
- Ja MakeFFFF
- Push BX
- Mov BX,Offset IndicatorBits - 'A'
- Xlat ;Get indicator bit.
- Pop BX
- Cmp AL,255
- Jz MakeFFFF
- Mov AH,0
- Cmp AL,81H
- Jb WhatKind
- Sub AL,80H
- Xchg AL,AH
- WhatKind: Cmp AX,KeyReverse
- Jz GetIndicRet
- Cmp AX,KeyPascal
- Ja IsItNumbIndic
- Mov GotStringParm,0FFH
- Jnz GetIndicRet
- Jmp Short GetIndicRet
- IsItNumbIndic: Cmp AX,KeyFloat
- Jmp Short GetIndicRet
- MakeFFFF: Mov AX,65535
- GetIndicRet: Or AX,AX
- Ret
- GetIndicBit Endp
- ;
- GetSortKey Proc Near
- Mov GotSortKey,0FFH
- Call CreateKey ;Setup default sort key rcd.
- Mov GotStringParm,0
- Mov GotBinaryParm,0
- Mov GotCParm,0
- Mov GotPParm,0
- Mov GotKeyErr,0
- NextKeyParm: Jcxz JmpChkKeyIn ;Jmp if no more parms.
- Dec CX
- Lodsb ;Get next sort key byte.
- Xlat ;Conv low case to up case.
- Cmp AL,Space ;If space this sort key is done,
- Jnz IsNextSlash
- JmpChkKeyIn: Jmp ChkKeyIn ;go get the next one.
- IsNextSlash: Cmp AL,Slash ;If / this sort key is done,
- Jz JmpChkKeyIn ;go get the next one.
- Mov DX,AX
- Call GetIndicBit ;Chk for valid parm.
- Jns CmpKeyRev
- Jmp CheckKeyLen ;Jump if not.
- CmpKeyRev: Cmp AX,KeyReverse
- Je JmpSaveIndic
- Cmp AX,KeyPascal
- Jbe CmpGotBin
- Jmp CheckNumbStr
- CmpGotBin: Cmp GotBinaryParm,0
- Jz CmpKeyZero
- Test GotKeyErr,GotBinStrErr
- Jnz CmpKeyZero
- Or GotKeyErr,GotBinStrErr
- Mov DX,Offset BinaryStringMsg
- Call DispErrorParm
- CmpKeyZero: Cmp AX,KeyZero
- Jnz PascalCmp
- Mov GotCParm,0FFH
- Cmp GotPParm,0
- Jnz PascalZeroNg
- Test KeyTypInit,KeyPascal
- Jnz DoPSwitchCKey
- Jmp SaveIndic
- DoPSwitchCKey: Mov SwitchKeyNGMsg+2,'5'
- Mov SwitchKeyNGMsg+5,'C'
- Mov SwitchKeyNGMsg+33,'P'
- Mov DX,Offset SwitchKeyNGMsg
- Call DispErrorParm
- JmpSaveIndic: Jmp SaveIndic
- PascalZeroNG: Mov DX,Offset PascalZeroNGMsg
- Call DispErrorParm
- Jmp SaveIndic
- PascalCmp: Cmp AX,KeyPascal
- Ja CheckNumbStr
- Je SetGotPParm
- Jmp SaveIndic
- SetGotPParm: Mov GotPParm,0FFH
- Cmp GotCParm,0
- Jnz PascalZeroNg
- Test KeyTypInit,KeyZero
- Jz CheckPasFix
- Mov SwitchKeyNGMsg+2,'6'
- Mov SwitchKeyNGMsg+5,'P'
- Mov SwitchKeyNGMsg+33,'C'
- Mov DX,Offset SwitchKeyNGMsg
- Call DispErrorParm
- CheckPasFix: Cmp FixedLen,0
- Jnz SaveIndic
- Mov DX,Offset PNotFNGMsg
- Call DispErrorParm
- Jmp Short SaveIndic
- CheckNumbStr: Cmp GotStringParm,0
- Jz CheckNumbFix
- Test GotKeyErr,GotBinStrErr
- Jnz SaveIndic
- Or GotKeyErr,GotBinStrErr
- Mov DX,Offset BinaryStringMsg
- Call DispErrorParm
- Jmp Short SaveIndic
- CheckNumbFix: Cmp FixedLen,0
- Jnz CheckPrevNumb
- Test GotKeyErr,GotNumbNotFErr
- Jnz CheckPrevNumb
- Or GotKeyErr,GotNumbNotFErr
- Mov DX,Offset NumbNotFNGMsg
- Call DispErrorParm
- CheckPrevNumb: Cmp GotBinaryParm,0
- Mov GotBinaryParm,0FFH
- Jz SaveIndic
- Mov DX,KeyTyp
- And DX,KeyInteger+KeyUnSigned+KeyMicro+KeyTurbo+KeyFloat
- Test DX,AX
- Jnz SaveIndic ;If same type of binary then ok.
- Test GotKeyErr,GotDiffBinErr
- Jnz SaveIndic
- Or GotKeyErr,GotDiffBinErr
- Mov DX,Offset DiffBinaryMsg
- Call DispErrorParm
- SaveIndic: Or KeyTyp,AX ;Set the switch bit.
- Jmp NextKeyParm ;Get next byte in sort key.
- CheckKeyLen: Mov AX,DX
- Cmp AL,LengthParm ;Chk if parm is key len.
- Jz GetKeyLen ;If so jmp.
- Cmp AL,'0'
- Jb BadSortKey
- Cmp AL,'9'
- Ja BadSortKey
- Call GetNumb ;Else must be start col.
- Cmp DX,32750
- Ja BadStartCol
- Or DX,DX
- Jz BadStartCol
- Cmp StartCol,0
- Jnz SecondStartCol ;Jmp if already got StartCol.
- Mov StartCol,DX ;Store start col.
- Jmp NextKeyParm
- GetKeyLen: Jcxz BadKeyLen ;Len must have at least one digit.
- Dec CX
- Lodsb ;Load 1st digit of len.
- Call GetNumb ;Returns numeric val in DX.
- Cmp DX,32750
- Ja BadKeyLen
- Or DX,DX
- Jz BadKeyLen
- Cmp KeyLen,0
- Jnz SecondKeyLen ;Jmp if already got KeyLen.
- Mov KeyLen,DX ;Store key len.
- Jmp NextKeyParm ;Get nxt byte of sort key.
- ChkKeyIn: Push AX
- Call ChkKeyInRcd
- Pop AX
- Jcxz GetSortKeyRet
- Cmp AL,Space
- Jz GetSortKeyRet
- Inc CX
- Dec SI
- GetSortKeyRet: Ret
- BadStartCol: Mov DX,Offset BadStartMsg
- Call DispErrorParm
- Jmp NextKeyParm
- BadSortKey: Test GotKeyErr,0FFH
- Jz DoBadSortKey
- Jmp NextKeyParm
- DoBadSortKey: Mov DX,Offset BadKeyMsg
- Call DispErrorParm
- Jmp NextKeyParm
- SecondStartCol: Mov DX,Offset SecondStartMsg
- Call DispErrorParm
- Jmp NextKeyParm
- BadKeyLen: Mov DX,Offset BadKeyLenMsg
- Call DispErrorParm
- Jmp NextKeyParm
- SecondKeyLen: Mov DX,Offset SecondKeyLenMsg
- Call DispErrorParm
- Jmp NextKeyParm
- GetSortKey Endp
- ;
- ;
- JmpNoMem1: Jmp NoMemory
- ;
- CreateKey Proc Near
- Push CX
- Push SI
- Cld
- Add KeyCount,1
- Mov AX,StartCol
- Test KeyTyp,KeyInteger+KeyUnsigned+KeyFloat+KeyMicro+KeyTurbo
- Jz NotBinNumb
- Sub AX,KeyLen
- Dec AX
- Jmp Short SavePrevEnd
- NotBinNumb: Add AX,Keylen
- SavePrevEnd: Mov PrevEndCol,AX
- Mov StartCol,0
- Mov RelCol,0
- Mov KeyLen,0
- Mov DI,CodePointer ;DI = addr of next key rout.
- Mov AX,KeyTypInit
- Test AX,KeyPascal
- Jz SetKeyTyp
- Cmp KeyCount,1
- Jnz SetKeyTyp
- Cmp FixedLen,0
- Jnz CheckPAndC
- Mov DX,Offset PMustBeFMsg
- Call DisplayError
- CheckPAndC: Test AX,KeyZero
- Jz SetKeyTyp
- Mov DX,Offset PAndCNGMsg
- Call DisplayError
- SetKeyTyp: Mov KeyTyp,AX
- Cmp GotError,0
- Jz SetKeyTyp2
- Jmp Short CreateKeyRet
- SetKeyTyp2: Mov SecondStart,0
- Cmp DI,Offset CompRoutine
- Jz All1
- Mov DI,OrigStart
- Mov SI,CompMove
- Add SI,Offset SecondBeg
- Mov CX,Offset SecondEnd - Offset SecondBeg
- Mov SecondStart,DI
- Rep Movsb
- All1: Mov SI,CompMove
- Add SI,Offset All1Beg
- Mov CX,Offset All1End - Offset All1Beg
- Mov All1Start,DI
- Rep Movsb
- Mov CodePointer,DI
- Cmp DI,ModelCodeLoc
- Jb CreateKeyRet
- NoMemory9: Jmp NoMemory
- CreateKeyRet: Pop SI
- Pop CX
- Ret
- CreateKey Endp
- ;
- FileAndRedir: Mov DX,Offset FileAndRedirMsg
- Jmp DoDispErrParm
- ;
- SaveFileAddr Proc Near
- Test IpDevice,80H
- Jz FileAndRedir ;Jump if input redirected.
- Dec SI
- Inc CX
- Cmp GotInput,0
- Jnz OutputFile
- Mov GotInput,0FFH
- Mov HaveSpecs,0FFH
- Mov InputAddr,SI
- NewInput: Jcxz MisplacedPlus ;Jump if plus at end.
- Lodsb
- Dec CX
- Cmp AL,'+'
- Jz MisplacedPlus ;Jump if plus at beginning.
- Inc InputFileCt
- NextNameChar: Jcxz SaveInputEnd2
- Lodsb
- Dec CX
- Cmp AL,Space
- Jz SaveInputEnd
- Cmp AL,Slash
- Jz SaveInputEnd
- Cmp AL,'+'
- Jnz NextNameChar
- Jmp Short NewInput
- SaveInputEnd: Dec SI
- Inc CX
- SaveInputEnd2: Mov InputEnd,SI
- Mov AL,InputFileCt
- Mov TotalFileCt,AL
- Ret
- ;
- OutputFile: Cmp GotOutput,0
- Jnz SecondIpOp
- Mov GotOutput,0FFH
- Mov OutputAddr,SI
- NextOpChar: Jcxz SaveOutputEnd2
- Lodsb
- Dec CX
- Cmp AL,Space
- Jz SaveOutputEnd2
- Cmp AL,Slash
- Jz SaveOutputEnd
- Cmp AL,'+'
- Jnz NextOpChar
- Jmp Short OutputPlus
- SaveOutputEnd: Dec SI
- Inc CX
- SaveOutputEnd2: Mov OutputEnd,SI
- Ret
- ;
- SecondIpOp: Mov DX,Offset SecondIpMsg
- Jmp DoDispErrParm
- OutputPlus: Mov DX,Offset OutputPlusMsg
- Jmp DoDispErrParm
- MisplacedPlus: Mov DX,Offset MisplacedMsg
- Jmp DoDispErrParm
- ;
- SaveFileAddr Endp
- ;
- AllocError: Mov DX,Offset AllocMsg
- Jmp DisplayExit
- ;
- SetupMemory Proc Near
- Mov BX,SP ;Add 31 to SP val assures that BX pts
- Add BX,31 ;beyond stack and allows round para up.
- Mov CL,4
- Shr BX,CL ;Convert to para.
- Mov AH,SetBlock
- Int DOS ;Dealloc mem above stack.
- Jc AllocError
- Mov AH,AllocMemory
- Mov BX,0FFFFH ;Ask how much mem avail.
- Int DOS ;Ret BX = avail para.
- Cmp Ax,8 ;Code 8 means not enough mem, so OK.
- Jnz AllocError ;Else is fatal.
- Mov AH,AllocMemory ;Now alloc all avail mem.
- Int DOS
- Jc AllocError
- Cmp BX,0200H ;Insist on 512 para (8192 bytes).
- Jae SetupMem2
- NoMemory: Mov DX,Offset NoMemoryMsg
- Jmp DisplayExit
- SetupMem2: Mov MemParaAvail,BX
- Mov MemoryBegSeg,AX
- Mov NextSeg,AX
- Mov NextOfs,0
- Mov Data.Segm,AX
- Mov Data.Beg,0
- Add BX,AX ;Seg addr of end of avail space.
- Mov MemoryEndSeg,BX ;End of avail mem.
- Dec BX ;Allow one para for block table.
- Mov LastSeg,BX ;End of mem avail for data.
- Mov BlockSeg,BX
- Mov DS,BX
- Mov DS:Word Ptr[000CH],0
- Mov DS:Word Ptr[000EH],0
- Push CS
- Pop DS
- Mov CX,FixedLen
- Jcxz Short MakeOfs2 ;Jmp if not fixed len.
- Cmp CX,2
- Jae FixedLenGE2
- Mov DataMax,32752
- Mov DataPara,07FFH
- Mov AX,32752
- Jmp Short FixedMaxPara
- FixedLenGE2: Mov AX,65520
- Xor DX,DX
- Div CX ;AX is max number of rcds in 65520 bytes.
- Mov BX,65520
- Sub BX,DX ;Get ofs after last byte of last rcd.
- Mov DataMax,BX ;Save in DataMax.
- Add BX,15
- Mov CL,4
- Shr BX,CL
- Mov DataPara,BX ;Save # of para to contain rcds.
- FixedMaxPara: Mul FixPlus2 ;DX:AX = space for DataMax + pointers.
- Add AX,15
- Adc DX,0
- Shr DX,1 ;1st shift involves DX because might exceed 64K.
- Rcr AX,1
- Mov CL,3
- Shr AX,CL ;AX = para for DataMax + ptrs.
- Add AX,0400H ;Add 16K for write buff.
- Mov MaxPara,AX
- Jmp Short ChkMinPara
- MakeOfs2: Mov NextOfs,2
- Mov DS,NextSeg
- Mov AX,CS:LineEnd
- Mov DS:Word Ptr[0],AX
- Push CS
- Pop DS
- ChkMinPara: Mov AX,MemParaAvail
- Mov BX,AX
- Cmp AX,4800H ;Do we have at least 288K avail.
- Jae CalcMaxAllow ;If so, MergeBuff=32K, MergeSeg=16K.
- Xor DX,DX
- Push AX
- Mov CX,9 ;Else MergeBuff = ninth of avail mem.
- Div CX
- Mov MergeBuff,AX
- Shr AX,1
- Cmp AX,0100H
- Jae SvMergeSeg
- Mov AX,0100H ;At least 4K for MergeSeg.
- SvMergeSeg: Mov MergeSeg,AX ;MergeSeg = one half of MergeBuff.
- Pop AX
- Cmp AX,2400H ;Do we have at least 144K avail.
- Jae CalcMaxAllow ;If so, MinPara = 48K, MinBuff = 16K.
- Xor DX,DX
- Mov CX,3 ;Else MinPara = third of avail memory.
- Div CX
- Mov MinPara,AX
- Xor DX,DX
- Div CX ;And MinBuff = 1/9 avail memory.
- Mov MinBuff,AX
- CalcMaxAllow: Sub BX,MinBuff ;MemParaAvail - MinBuff.
- Shr BX,1 ;One half of avail memory.
- Dec BX
- Dec BX ;Allow for two one para ptr segs.
- Cmp BX,07FFH ;If GE 32752 bytes then OK.
- Jae SetupMemRet
- Mov CL,4
- Shl BX,CL
- Mov MaxAllowLen,BX
- Cmp BX,FixedLen
- Jb CantHoldTwo
- SetupMemRet: Mov AX,MemParaAvail
- Sub AX,CommandSize
- Jc SetupMemRet2
- Mov CX,12
- Mul CX
- Cmp FixedLen,0
- Jz StoreBelow
- Mov BX,AX ;BX = BelowLow.
- Mov AX,DX ;AX = BelowHi.
- Xor DX,DX ;DX:AX = BelowHi.
- Mov CX,FixPlus2
- Div CX ;AX = Hi part of BelowHi / FixPlus2.
- Xchg AX,BX ;BX = Hi BelowHi/FixPlus2. DX:AX = Rem:BelowLow.
- Div CX ;BX:AX = Below / FixPlus2.
- Mov CX,FixedLen
- Xchg BX,AX ;BX = Quotient low. AX = Quotient high.
- Mul CX ;AX = FixedLen * Quotient high.
- Xchg BX,AX ;BX = FixedLen*QuotHi. AX = QuotLow.
- Mul CX ;DX:AX = QuotLow * FixedLen.
- Add DX,BX ;DX:AX = (Below / FixPlus2) * FixedLen.
- StoreBelow: Mov BelowLow,AX
- Mov BelowHi,DX
- SetupMemRet2: Ret
- CantHoldTwo: Cmp CS:MaxAllowLen,32750
- Jb DoTwoRcdMsg
- Mov DX,Offset LinGTMaxMsg
- Jmp DisplayExit
- DoTwoRcdMsg: Mov DX,Offset TwoRcdMsg
- Jmp DisplayExit
- SetupMemory Endp
- ;
- ReSetupMemory Proc Near
- Cmp FixedLen,0
- Jz ResetLines
- Mov AX,MemoryBegSeg
- Mov NextSeg,AX
- Mov NextOfs,0
- Mov SegCount,0
- Ret
- ResetLines: Mov DI,SegCount
- Shl DI,1
- Mov AX,NextSeg
- Mov BX,Data.Segm[DI]
- Sub AX,BX ;Full para in last part line.
- Mov CL,4
- Shl AX,CL ;Bytes equiv to para in part line.
- Mov DS,BX
- Mov SI,CS:Data.Beg[DI] ;DS:SI pts to part line.
- Sub AX,SI ;Subt ofs of part line.
- Add AX,CS:NextOfs ;Add bytes after last para.
- Mov BX,AX ;Hold len of last part line.
- Mov DX,AX
- And AL,0F0H
- Sub DX,AX ;Bytes after full para.
- Mov CS:NextOfs,DX ;NextOfs after move.
- Shr AX,CL ;Number of para.
- Add AX,CS:Data.Segm[0] ;Compute NextSeg after move.
- Mov CS:NextSeg,AX
- Mov CX,BX ;Recover len of last part line.
- Xor DI,DI
- Mov ES,CS:Data.Segm[0] ;ES:DI points to dest for move.
- Cld
- Shr CX,1
- Jnc MovePartWords
- Movsb
- MovePartWords: Rep Movsw
- Mov CS:SegCount,0
- Mov AX,CS:LineEnd
- Mov ES:Word Ptr[0],AX
- Push CS
- Push CS
- Pop DS
- Pop ES
- Ret
- ;
- ReSetupMemory Endp
- ;
- LoadStd Proc Near
- Cmp MoreData,0
- Jnz DoLoadStd
- Test IpDevice,80H
- Jnz DeviceErr ;If sign bit is on StdIp is a device.
- Mov Handle,StdInput ;Save std ip handle.
- DoLoadStd: Call LoadFile ;Load the file.
- Ret
- DeviceErr: Mov DX,Offset DeviceMsg
- Jmp DisplayExit
- LoadStd Endp
- ;
- LoadSpec Proc Near
- Cmp MoreData,0
- Jnz DoLoadSpec
- Cmp WildCard,0
- Jz LoadSpec2
- Mov AX,FindNext
- Int DOS
- Jc LoadSpec2
- Call MoveToASCIIZ ;DX=ASCIIZ offset, DI points after zero.
- Jmp Short OpenSpec
- LoadSpec2: Mov WildCard,0
- Cmp InputFileCt,0
- Jnz LoadSpec3
- Clc
- Ret
- LoadSpec3: Dec InputFileCt
- Mov DI,InputAddr
- Mov DX,DI ;DX pts to ASCIIZ string.
- Mov CX,InputEnd
- Sub CX,DI
- Cld
- Mov AL,'+' ;Look for term plus
- Repne Scasb ;after filespec.
- Jz StoreZero ;Jmp if found term plus.
- Inc DI ;Hit end of parms. Inc DI for following move.
- StoreZero: Mov Byte Ptr[DI-1],0 ;Put 0 at end of ASCIIZ string.
- Mov InputAddr,DI ;Save ptr to next
- Call AnyWildCard
- Jnc OpenSpec ;Jump if no wildcards.
- Mov WildCard,0FFH
- Mov AX,FindFirst
- Mov CX,Hidden+System
- Int DOS
- Jc FileOpenNG
- Call MoveToASCIIZ ;DX=ASCIIZ offset, DI points after zero.
- OpenSpec: Mov AX,OpenForRead ;Open the file for read.
- Int DOS
- Jc FileOpenNG ;Jmp if open was no good.
- Mov Handle,AX ;Save handle.
- DoLoadSpec: Call LoadFile ;Load the file.
- Jc LoadSpecRet
- Mov BX,Handle
- Mov AX,Close ;Close the file.
- Int Dos
- Clc
- LoadSpecRet: Ret
- FileOpenNg: Push DX ;Save addr of ASCIIZ string.
- Call WriteNewLine
- Call WriteERROR
- Mov DX,Offset NoFileMsg
- Mov CL,Offset NoFileEnd - Offset NoFileMsg
- Call WriteStdError
- Pop DX ;Recover ASCIIZ addr.
- Mov CX,DI ;Pts to end of ASCIIZ.
- Sub CX,DX
- Dec CX ;Len of ASCIIZ.
- Call WriteStdError
- Call WriteNewLine
- Mov CS:ErrorCode,47
- Jmp ErrorExit
- LoadSpec Endp
- ;
- AnyWildCard Proc Near
- ; Scan from [DI-2] to [DX] and if find "?" or "*" in file name or ext (i.e.
- ; if find one of these before find "\" or ":":
- ; . Move drive and path to IpASCIIZ area.
- ; . Save offset of next byte in IpASCIIZ area at IpNamePtr.
- ; . Preserve DX and DI.
- ; . Return with carry set.
- ; Otherwise:
- ; . Preserve DX and DI.
- ; . Return with carry clear.
- Mov CX,DI
- Sub CX,DX
- Dec CX
- Lea SI,[DI-2]
- Std
- FindWild: Lodsb
- Cmp AL,'?'
- Jz FoundWild
- Cmp AL,'*'
- Jz FoundWild
- Cmp AL,'\'
- Jz NotFoundWild
- Cmp AL,':'
- Jz NotFoundWild
- Loop FindWild
- NotFoundWild: Clc
- Cld
- Ret
- FoundWild: Dec CX
- Jz OnlyFileName
- ScanSlashColon: Lodsb
- Cmp AL,'\'
- Jz GotPath
- Cmp AL,':'
- Jz GotPath
- Loop ScanSlashColon
- OnlyFileName: Mov AX,Offset IpASCIIZ
- Mov IpNamePtr,AX
- Cld
- Stc
- Ret
- GotPath: Cld
- Mov SI,DX
- Push DI
- Mov DI,Offset IpASCIIZ
- Rep Movsb
- Mov IpNamePtr,DI
- Pop DI
- Stc
- Ret
- AnyWildCard Endp
- ;
- MoveToASCIIZ Proc Near
- ; Copy file name at IpNameExt to [IPNamePtr].
- ; Load IpNamePtr into DX.
- ; Load DI with adress of byte after binary zero.
- Cld
- Mov SI,Offset IpNameExt
- Mov DI,IpNamePtr
- Mov CX,13
- Mov DX,Offset IpASCIIZ
- NextASCIIZ: Lodsb
- Stosb
- Cmp AL,0
- Loopne NextASCIIZ
- Ret
- MoveToASCIIZ Endp
- ;
- MemIsFull Proc Near
- Push CS
- Pop DS ;Restore ptr to code seg.
- Mov MoreData,0FFH
- Cmp WriteHandle,1
- Ja MemIsFull2
- Mov WriteHandle,0
- MemIsFull2: Mov FileSizeHi,BP
- Mov FileSizeLo,DI
- Mov GotData,1
- Mov FinalOutput,0
- Stc
- Ret
- MemIsFull Endp
- ;
- LoadFile Proc Near
- Mov BX,Handle
- Cmp CS:MoreData,0
- Jz NewFile
- Mov CS:MoreData,0
- Mov BP,CS:FileSizeHi
- Mov DI,CS:FileSizeLo
- Jmp LoadFile2
- NewFile: Mov AX,GetFileLen
- Xor CX,CX
- Mov DX,CX
- Int DOS ;DX:AX = len of file
- Push AX
- Push DX
- Mov AX,SetFileAtBeg
- Xor CX,CX
- Mov DX,CX
- Int DOS
- Pop BP
- Pop DI ;BP:DI = File len.
- Cmp TotalFileCt,1
- Jnz NewFile2
- Cmp WildCard,0
- Jnz NewFile2
- Mov AX,LeaveCmdSize
- Cmp MemParaAvail,AX
- Jb NewFile2
- Mov AX,DI
- Mov DX,BP
- Sub AX,BelowLow
- Sbb DX,BelowHi
- Jnc NewFile2
- Mov AX,CommandSize
- Sub MemoryEndSeg,AX
- Sub LastSeg,AX
- Sub BlockSeg,AX
- Sub MemParaAvail,AX
- Push DS
- Mov DS,BlockSeg
- Mov DS:Word Ptr[000CH],0
- Mov DS:Word Ptr[000EH],0
- Pop DS
- NewFile2: Mov CX,FixedLen
- Jcxz LoadFile1
- Mov AX,BP ;High part of file len.
- Xor DX,DX
- Div CX
- Mov AX,DI ;Low part of file len.
- Div CX ;DX = remainder of div by FixedLen.
- Sub DI,DX ;Subtract remainder from file len to
- Sbb BP,0 ;get multiple of FixedLen.
- Or DX,DX
- Jz LoadFile1
- Push BP
- Push DI
- Mov DX,Offset ShortRcdMsg
- Mov CX,Offset ShortRcdEnd - Offset ShortRcdMsg
- Call WriteStdError2
- Pop DI
- Pop BP
- LoadFile1: Mov DX,BP
- Or DX,DI
- Jnz LoadFile2
- Jmp LoadRet
- LoadFile2: Mov DS,CS:NextSeg
- Mov DX,CS:NextOfs ;DS:DX = load addr.
- Mov AX,DS
- Mov BX,CS:LastSeg
- Sub BX,AX
- Sub BX,CS:ReservedForPtrs ;Avail para.
- Cmp BX,CS:MaxPara
- Jbe LoadFile2A
- Mov CX,CS:DataMax
- Jmp Short LoadFile5
- LoadFile2A: Cmp BX,CS:MinPara
- Jb JmpMemIsFull
- Sub BX,CS:MinBuff
- Cmp CS:FixedLen,0
- Jnz LoadFile3
- Mov CL,3 ;Use half of space for data and half for ptrs.
- Shl BX,CL
- Mov CX,BX
- Jmp Short LoadFile4
- LoadFile3: Dec BX
- Mov AX,BX
- Mov CX,16
- Push DX
- Mul CX
- Div CS:FixPlus2
- Mul CS:FixedLen
- Pop DX
- Mov CX,AX ;CX = avail bytes in seg.
- Cmp CX,CS:FixedLen
- Jae LoadFile5
- JmpMemIsFull: Jmp MemIsFull
- LoadFile4: Sub CX,DX ;CX = avail bytes in seg.
- LoadFile5: Sub DI,CX
- Sbb BP,0
- Jnc BiggerThanSeg ;Jmp if rest of file bigger then seg.
- Add CX,DI ;else use len of rest of file.
- Xor DI,DI
- Mov BP,DI ;Remain len of file is 0.
- Mov CS:MustSetPtrs,0
- Jmp Short DoRead
- BiggerThanSeg: Mov CS:MustSetPtrs,0FFH
- DoRead: Mov BX,CS:Handle
- Mov AX,Read ;Read up to avail bytes in seg.
- Int DOS
- Jc JmpReadErr ;Jmp if read no good.
- Cmp AX,CX ;Do bytes read = bytes req.
- Jnz JmpReadErr ;Jmp if they don't.
- Mov BX,AX ;Hold # of bytes read.
- Cmp CS:FixedLen,0
- Jnz AdjustOfs
- ;
- Push DS
- Pop ES
- Cld
- ScanCtrlZ: Push DI
- Mov DI,DX
- Add DI,BX
- Sub DI,CX ;Start ofs for Ctrl-Z scan.
- Mov AL,CtrlZ
- Repne Scasb
- Mov SI,DI
- Pop DI
- Jnz AdjustOfs
- Dec BX
- Mov CS:GotCtrlZ,0FFH
- Cmp CS:IgnoreCtrlZ,0
- Jz AdjustBytes
- Jcxz AdjustOfs
- Call DeleteCtrlZ
- Jmp ScanCtrlZ
- AdjustBytes: Sub BX,CX ;Number bytes of data.
- ;
- Jnz AdjustBytes2
- Jmp LoadRet
- AdjustBytes2: Add CS:NextOfs,BX
- Mov CS:EndData,0
- Mov AX,BX
- Shr AX,1
- Shr AX,1
- Shr AX,1
- Shr AX,1
- Add CS:ReservedForPtrs,AX
- Jmp Short LoadFin
- JmpReadErr: Jmp ReadError
- AdjustOfs: Add CS:NextOfs,BX
- Mov CS:EndData,0
- Cmp CS:FixedLen,0
- Jnz FixReserved
- Mov AX,BX
- Shr AX,1
- Shr AX,1
- Shr AX,1
- Shr AX,1
- Add CS:ReservedForPtrs,AX
- Jmp Short AdjustOfs2
- FixReserved: Push DX
- Mov AX,BX
- Xor DX,DX
- Div CS:FixedLen
- Shr AX,1
- Shr AX,1
- Shr AX,1
- Add CS:ReservedForPtrs,AX
- Pop DX
- AdjustOfs2: Mov AX,BP
- Or AX,DI
- Jz LoadFin
- Push BP
- Push DI
- Mov CS:FromMain,0
- Call SetupPointers
- Pop DI
- Pop BP
- Jmp LoadFile2
- LoadFin: Mov CS:GotData,1
- Cmp CS:Fixedlen,0
- Jnz LoadRet
- Add BX,DX ;Pt after last byte.
- Mov AX,Word Ptr[BX-2]
- Cmp AX,CS:LineEnd
- Jz AdjNextOfs
- Xchg AH,AL
- Cmp AX,CS:LineEnd
- Jz AdjNextOfs
- Inc BX
- Cmp AL,CS:Byte Ptr LineEnd + 1
- Jz LoadFin3
- LoadFin2: Cmp AL,CS:Byte Ptr LineEnd
- Jz LoadFin3
- Inc BX
- LoadFin3: Mov AX,CS:LineEnd
- Mov Word Ptr[BX-2],AX
- Push BX
- Push DS
- Push CS
- Pop DS
- Mov DX,Offset MissCRLFMsg
- Mov CX,Offset MissCRLFEnd - Offset MissCRLFMsg
- Call WriteStdError2
- Pop DS
- Pop BX
- AdjNextOfs: Mov CS:NextOfs,BX
- LoadRet: Call SetupPointers
- Push CS
- Push CS
- Pop DS
- Pop ES
- Clc
- Ret
- ReadError: Mov DX,Offset ReadErrorMsg
- Jmp DisplayExit
- LoadFile Endp
- ;
- DeleteCtrlZ Proc Near
- Push DI
- Push CX
- Lea DI,[SI-1]
- Shr CX,1
- Jnc DeleteCtrlZ2
- Movsb
- DeleteCtrlZ2: Rep Movsw
- Pop CX
- Pop DI
- Ret
- DeleteCtrlZ Endp
- ;
- SetupPointers Proc Near
- ;
- Cld
- Mov SI,CS:SegCount
- Shl SI,1
- Mov AX,CS:NextOfs
- Mov DX,AX
- And AL,0F0H
- Sub DX,AX ;Ofs for load.
- Mov CS:NextOfs,DX
- Mov BP,DX ;Hold NextOfs
- Mov CL,4
- Shr AX,CL
- Add AX,CS:NextSeg
- Mov CS:NextSeg,AX
- Cmp CS:PtrsAgain,0
- Jz SetupPtrs1
- Mov CS:PtrsAgain,0
- Mov CS:EndData,0
- Jmp Short SetupPtrs2
- SetupPtrs1: Cmp CS:EndData,0
- Jz SetupPtrs2
- Mov CS:EndData,0
- Ret
- SetupPtrs2: Mov DI,AX ;Hold NextSeg
- Sub AX,CS:Data.Segm[SI]
- Mov CX,16
- Mul CX ;DX:AX = ofs of NextSeg from DataSeg[SI].
- Add AX,BP
- Adc DX,0 ;Ofs of Next loc from DataSeg[SI].
- Sub AX,CS:LenBuckSize ;If lines, pt to 1st len buck.
- Sbb DX,0
- Jz SetupPtrs3
- Cmp CS:FromMain,0
- Jnz SetPtrsAgain
- Cmp DX,1
- Jbe UseDataMax
- SetPtrsAgain: Mov CS:PtrsAgain,0FFH
- Jmp Short UseDataMax ;Jmp if more than 65535.
- SetupPtrs3: Cmp AX,CS:Data.Beg[SI]
- Ja ChkDataMax
- Ret ;Return if no data.
- ChkDataMax: Cmp AX,CS:DataMax
- Jae UseDataMax
- Cmp CS:FromMain,0
- Jnz SaveDataEnd
- Cmp CS:MustSetPtrs,0
- Jnz SaveDataEnd
- Ret ;Return if LT DataMax and not final time.
- UseDataMax: Mov AX,CS:DataMax
- SaveDataEnd: Push AX ;Save end of data ptr in seg.
- Mov BX,CS:LastSeg
- Inc DI ;NextSeg plus 1.
- Mov CX,BX
- Sub BX,DI ;Avail para.
- Cmp BX,0FFFH
- Jbe GetPtrSegBeg
- Mov BX,0FFFH
- GetPtrSegBeg: Sub CX,BX
- Mov DS,CX
- Mov CS:Pointer.Segm[SI],CX
- Mov CL,3
- Shl BX,CL
- Mov DX,BX ;Max ptr ct.
- Shl BX,1
- Dec BX
- Dec BX
- Mov CS:Pointer.Beg[SI],BX
- Les DI,CS:Data[SI]
- Pop CX
- Add CX,CS:LenBuckSize
- Sub CX,DI ;Number of data bytes.
- Mov SI,BX ;ES:DI=Data,DS:SI=Ptr,DX=PtrCt,CX=DataBytes.
- Cmp CS:FixedLen,0
- Jz LinePtrs
- Jmp NextFix
- ;
- LinePtrs: Mov BX,CX
- Shr BX,1
- Shr BX,1
- Shr BX,1
- Shr BX,1
- Sub CS:ReservedForPtrs,BX
- Jnc NextLine
- Mov CS:ReservedForPtrs,0
- NextLine: Mov BX,DI ;Pt to len field.
- Dec CX
- Inc DI
- Dec CX
- Inc DI ;Pt to line.
- Mov BP,CX ;Hold remain len of data.
- Jcxz FinishSegLine ;Jmp if no more data.
- Mov AX,CS:LineEnd
- ScanForCR: Dec CX
- Scasb
- Jcxz EndOfData2
- Jnz ScanForCR2
- Cmp ES:Byte Ptr[DI],AH ;If next char is not LF
- Jz PointToCr
- ScanForCR2: Repne Scasb ;Find CR.
- Jcxz EndOfData ;Jmp if no CR or CR in last byte.
- Cmp ES:Byte Ptr[DI-2],AH
- Jnz ScanForCR3
- Dec DI
- Inc CX
- Jmp Short PointToCR
- ScanForCR3: Cmp ES:Byte Ptr[DI],AH ;If next char is not LF then
- Jnz ScanForCR2 ;cont the search.
- PointToCR: Inc CX
- Dec DI ;Pt back to CR.
- SaveLineLen: Sub BP,CX ;BP = len of line
- Jnz SaveLineLen2
- Cmp CS:ElimNull,0
- Jnz NextLine
- SaveLineLen2: Mov ES:[BX],BP ;Store line len in prev CRLF buck.
- Add BP,2
- Cmp BP,CS:LongestLen
- Jbe IncLineCt
- Cmp BP,CS:MaxAllowLen
- Ja LineLongJmp
- Mov CS:LongestLen,BP
- IncLineCt: Sub BP,2
- Dec DX
- Mov [SI],BX ;Store addr of line in ptr buck.
- Dec SI
- Dec SI
- Jmp NextLine
- EndOfData: Jnz EndOfData2
- Cmp ES:Byte Ptr[DI-2],AH
- Jnz EndOfData2
- Dec DI
- Inc CX
- Jmp PointToCR
- LineLongJmp: Jmp CantHoldTwo
- EndOfData2: Sub DI,BP ;Ptr to 1st byte in line.
- Add BP,2
- Cmp BP,CS:MaxAllowLen
- Ja LineLongJmp
- Mov CS:EndData,0FFH
- Sub BP,2
- FinishSegLine: Dec DI
- Dec DI
- Mov AX,SI
- FinishPtrs: Mov BX,CS
- Mov DS,BX
- Mov ES,BX
- Mov SI,SegCount
- Mov BX,SI
- Cmp AX,Pointer.Beg[BX+SI]
- Jz FinPtrsRet
- Mov DataEnd[SI],DI
- Inc AX
- Inc AX
- Mov PointerEnd[SI],AX
- And AL,0F0H
- Sub PointerEnd[SI],AX
- Sub Pointer.Beg[SI+BX],AX
- Mov CL,4
- Shr AX,CL
- Add AX,Pointer.Segm[SI+BX]
- Mov Pointer.Segm[SI+BX],AX
- Mov LastSeg,AX
- Inc SI
- Inc SI
- Mov SegCount,SI
- Mov BX,SI
- Mov AX,DI
- And AL,0F0H
- Sub DI,AX
- Mov Data.Beg[SI+BX],DI
- Mov CL,4
- Shr AX,CL
- Add AX,Data.Segm[SI+BX-4]
- Mov Data.Segm[SI+BX],AX
- Jmp SetupPointers
- FinPtrsRet: Ret
- ;
- NextFix: Mov AX,CX ;AX = Size of data seg.
- Xor DX,DX
- Div CS:FixedLen ;AX = # of Rcds
- Mov CX,AX
- Shr AX,1
- Shr AX,1
- Shr AX,1
- Sub CS:ReservedForPtrs,AX
- Jnc NextFix2
- Mov CS:ReservedForPtrs,0
- NextFix2: Mov AX,DI
- Mov BX,DS
- Mov ES,BX
- Mov DI,SI
- Mov BP,CS:FixedLen
- Std
- StoreFixedPtr: Stosw
- Add AX,BP
- Loop StoreFixedPtr
- Cld
- Xchg AX,DI
- Jmp FinishPtrs
- ;
- SetupPointers Endp
- ;
- FourDigits Proc Near
- Mov BP,10
- Inc AH
- Inc AL
- Mul AH
- Mov CX,4
- NextDig: Xor DX,DX
- Div BP
- Or DL,30H
- Mov DS:Byte Ptr[SI],DL
- Inc SI
- Loop NextDig
- Ret
- FourDigits Endp
- ;
- SetupTempFiles Proc Near
- Cmp CS:TempDisk,0
- Jnz SetTempFiles2
- Mov AL,CS:DefaultDisk
- Mov CS:TempDisk,AL
- SetTempFiles2: Mov DL,CS:TempDisk
- Mov DH,':'
- Mov Word Ptr TempName1,DX
- Mov Word Ptr TempName2,DX
- Mov Word Ptr TempName3,DX
- Mov SI,Offset TempName1+2
- Mov DI,0
- Call CreateTempFile
- Mov WriteHandle,AX
- Mov TempHandle1,AX
- Mov SI,Offset TempName2+2
- Mov DI,1
- Call CreateTempFile
- Mov ReadHandle,AX
- Mov TempHandle2,AX
- Mov SI,Offset TempName3+2
- Mov DI,2
- Call CreateTempFile
- Mov TempHandle3,AX
- Mov ExtraHandle,AX
- Ret
- SetupTempFiles Endp
- ;
- CreateTempFile Proc Near
- Push SI
- Mov AX,GetTime
- Int DOS
- Mov AX,DX
- Add DI,CX
- Call FourDigits
- Mov AX,DI
- Call FourDigits
- Mov DI,SI
- Mov AX,422EH
- Stosw
- Mov AX,4250H
- Stosw
- Xor AL,AL
- Stosb
- Pop DX
- Dec DX
- Dec DX
- Xor CX,CX
- Mov AX,CreateFile
- Int DOS
- Jc FullTempDir
- Ret
- FullTempDir: Mov DX,Offset NoTempDirMsg
- Jmp DisplayExit
- CreateTempFile Endp
- ;
- OpenOutput Proc Near
- Mov DI,CS:OutputEnd
- Mov CS:Byte Ptr[DI],0
- Mov DX,CS:OutputAddr
- Push CS
- Pop DS
- Xor CX,CX
- Mov AX,CreateFile
- Int DOS
- Jc FullOpDir
- Mov CS:OpenedOutput,0FFH
- Mov CS:WriteHandle,AX
- Mov CS:OutputHandle,AX
- Ret
- FullOpDir: Mov DX,Offset NoOpDirMsg
- Jmp DisplayExit
- OpenOutput Endp
- ;
- WriteSetup Proc Near
- Cld
- Mov CX,CS:SegCount
- Mov SI,CX
- Dec SI
- Dec SI
- Mov CS:SegNumb,SI
- Cmp CS:SkipSetupTop,0
- Jz DoSetup
- Jmp WriteSetupRet
- DoSetUp: Mov CS:WriteBuffEnd,65535
- Shr CX,1
- Xor AX,AX
- Mov DI,Offset TopIndex
- SetupTop: Stosw
- Inc AX
- Inc AX
- Loop SetupTop
- Mov AX,CS:NextSeg
- Inc AX
- Mov CS:WriteBuff.Segm,AX
- Mov CS:WriteBuff.Beg,0
- Mov DX,CS:LastSeg
- Sub DX,AX
- Cmp DX,1000H
- Jae SortTopRcds
- Mov CL,4
- Shl DX,CL
- SaveLength: Mov CS:WriteBuffEnd,DX
- SortTopRcds: Xor SI,SI ;Init J.
- Push SI
- TopNextJ: Pop SI ;Get prev J.
- Cmp SI,CS:SegNumb
- Je WriteSetupRet
- Inc SI
- Inc SI ;Next J.
- Push SI
- Mov BP,SI ;Init prev I.
- Cmp CS:UseRcdLen,0
- Jz UsePointerJ
- Mov SI,CS:TopIndex[SI] ;Contents of Jth TopIndex buck.
- Push SI ;Will insert this in proper buck.
- Shl SI,1
- Lds SI,CS:Data[SI] ;DS:SI pts low rcd in data seg.
- Jmp Short TopNextI
- UsePointerJ: Mov BX,CS:TopIndex[SI] ;Contents of Jth TopIndex buck.
- Push BX ;Will insert this in proper buck.
- Shl BX,1
- Lds SI,CS:Pointer[BX]
- Mov SI,Word Ptr[SI] ;Ofs of low rcd in data seg.
- Mov DS,CS:Data.Segm[BX] ;DS:SI pts low rcd in data seg.
- TopNextI: Dec BP
- Dec BP ;Next I.
- Js TopInsert
- Mov DI,BP
- Cmp CS:UseRcdLen,0
- Jz UsePointerI
- Mov DI,CS:TopIndex[DI] ;Contents of Jth TopIndex buck.
- Push DI ;Will insert this in proper buck.
- Shl DI,1
- Les DI,CS:Data[DI] ;ES:DI pts low rcd in data seg.
- Jmp Short TopCompare
- UsePointerI: Mov BX,CS:TopIndex[DI] ;Contents of Jth TopIndex buck.
- Push BX ;Will insert this in proper buck.
- Shl BX,1
- Les DI,CS:Pointer[BX]
- Mov DI,ES:Word Ptr[DI] ;Ofs of low rcd in data seg.
- Mov ES,CS:Data.Segm[BX] ;ES:DI pts low rcd in data seg.
- TopCompare: Push SI
- Call CompRoutine
- Jnc TopAddFour
- TopNotInsert: Pop SI ;Restore ofs of Jth line.
- Pop DI ;Get contents of Ith buck.
- Mov CS:TopIndex[BP+2],DI ;Store in I+1th buck.
- Jmp TopNextI ;Recompute I.
- TopAddFour: Add SP,4 ;Discard Jth rcd ofs and Ith index.
- TopInsert: Pop SI ;Get contents of Jth buck.
- Mov CS:TopIndex[BP+2],SI ;Store in I+1th buck.
- Jmp TopNextJ
- WriteSetupRet: Ret
- ;
- WriteSetup Endp
- ;
- WriteData Proc Near
- Mov SI,CS:OrigStart
- Mov CS:Word Ptr[SI+4],0DB8CH
- Mov CS:Byte Ptr[SI+6],08CH
- Call WriteSetup
- Mov CS:PrevOfs,0FFFFH
- Jmp Short WriteLowRcd
- NextLowJ: Inc CX
- Inc CX ;CH = 0, CL SegNumb + 2.
- Mov BX,CX
- Shr BX,1
- And BL,0FEH ;First trial TopIndex.
- Mov BP,CS:TopIndex ;Contents of Jth TopIndex buck.
- Push BP ;Will insert this in proper buck.
- Shl BP,1
- Lds SI,CS:Pointer[BP]
- Mov SI,Word Ptr[SI] ;Ofs of low rcd in data seg.
- Mov DS,CS:Data.Segm[BP] ;DS:SI pts low rcd in data seg.
- NextLowI: Mov BP,CS:TopIndex[BX] ;Contents of Jth TopIndex buck.
- Shl BP,1
- Les DI,CS:Pointer[BP]
- Mov DI,ES:Word Ptr[DI] ;Ofs of low rcd in data seg.
- Mov ES,CS:Data.Segm[BP] ;ES:DI pts low rcd in data seg.
- Push CX
- Mov BP,BX
- Mov DX,SI
- Call CompRoutine
- Mov SI,DX
- Mov BX,BP
- Pop CX
- Jnc GoUp
- GoDown: Mov CL,BL
- Add BL,CH
- Shr BL,1
- And BL,0FEH
- Cmp BL,CH
- Ja NextLowI
- Jmp Short FoundPos
- GoUp: Mov CH,BL
- Add BL,CL
- Shr BL,1
- And BL,0FEH
- Cmp BL,CH
- Ja NextLowI
- FoundPos: Mov CX,BX
- Shr CX,1
- Mov DI,Offset TopIndex
- Lea SI,[DI+2]
- Mov AX,CS
- Mov ES,AX
- Mov DS,AX
- Rep Movsw
- Pop BP
- Mov [DI],BP
- WriteLowRcd: Mov BX,CS:TopIndex ;Index in 0th buck.
- Shl BX,1
- Lds SI,CS:Pointer[BX]
- Mov SI,Word Ptr[SI] ;Ofs of low rcd in data seg.
- Mov DS,CS:Data.Segm[BX] ;Data seg for low rcd.
- Call DoWriteLow
- Jc WriteLowRcd
- SetNextSearch: Mov AX,CS
- Mov DS,AX
- Mov ES,AX
- Mov BX,TopIndex ;Contents of 1st top index buck.
- Mov DI,BX
- Mov CX,Pointer.Beg[BX+DI]
- Jcxz SetNext3
- Dec CX
- Dec CX
- Cmp CX,PointerEnd[BX]
- Jb SetNext3
- Mov Pointer.Beg[BX+DI],CX
- Jmp Short SetJEqSegNumb
- SetNext3: Sub SegNumb,2
- Js WriteFin
- Mov CX,SegNumb
- Shr CX,1 ;Ct of TopIndex bucks.
- Inc CX
- Mov DI,Offset TopIndex ;Pt to 1st TopIndex buck.
- Lea SI,[DI+2] ;Pt to 2nd TopIndex buck.
- Rep Movsw
- Jmp WriteLowRcd
- SetJEqSegNumb: Mov CX,SegNumb ;Pt to last TopIndex buck.
- Jcxz WriteLowRcd
- Jmp NextLowJ
- WriteFin: Call WriteBuffer
- Mov BX,CS:WriteHandle
- Cmp CS:FinalOutput,0
- Jz NotFinalOp
- Cmp CS:GotCtrlZ,0
- Jz CloseOutput
- Mov AX,CS
- Mov DS,AX
- Mov DX,Offset PrtCtrlZ
- Mov CX,1
- Mov AH,Write
- Int DOS
- CloseOutput: Mov BX,WriteHandle
- Cmp BX,StdOutput
- Jz WriteRet
- Mov AX,Close
- Int DOS
- Jmp Short WriteRet
- NotFinalOp: Mov AX,GetFileLoc
- Xor CX,CX
- Mov DX,CX
- Int DOS
- Jc DiskError61
- Mov SI,CS:BlockEnd
- Mov DS,CS:BlockSeg
- Mov Word Ptr[SI],AX
- Mov Word Ptr[SI+2],DX
- Inc CS:BlockCt
- Sub SI,4
- Jnc StoreBlockEnd
- Dec CS:BlockSeg
- Add CS:BlockBeg,10H
- Add SI,10H
- StoreBlockEnd: Mov CS:BlockEnd,SI
- Mov AX,CS:BlockSeg
- Mov CS:LastSeg,AX
- WriteRet: Mov AX,CS
- Mov DS,AX
- Mov ES,AX
- Mov SI,OrigStart
- Mov CS:Word Ptr[SI+4],0FE39H
- Mov CS:Byte Ptr[SI+6],0C3H
- Ret
- ;
- WriteBuffer: Mov DS,CS:WriteBuff.Segm
- Mov CX,CS:WriteBuff.Beg ;Len to write.
- Jcxz WriteBufferRet
- Xor DX,DX
- WriteBuffer2: Mov CS:PrevBuffOfs,0FFFFH
- Mov BX,CS:WriteHandle ;Write to std op.
- Mov AH,Write
- Int DOS
- Jc DiskError62 ;Err msg if write NG.
- Cmp AX,CX
- Jnz FullDisk ;Err if not write req bytes.
- Mov CS:WriteBuff.Beg,0
- WriteBufferRet: Ret
- ;
- DiskError61: Mov AX,3136H
- Jmp Short DiskError
- DiskError62: Mov AX,3236H
- DiskError: Mov DX,Offset DiskErrorMsg
- Mov CS:Word Ptr DiskErrorMsg+1,AX
- Jmp DisplayExit
- ;
- FullDisk: Cmp BX,StdOutput
- Jz FullOut
- Cmp CS:FinalOutput,0
- Jnz FullOut
- FullTemp: Mov DX,Offset FullTempMsg
- Jmp DisplayExit
- FullOut: Mov DX,Offset FullOutMsg
- Jmp DisplayExit
- ;
- WriteData Endp
- ;
- DoWriteLow Proc Near
- Cmp CS:ElimDup,0
- Jz MoveLine2
- Les DI,CS:PrevAddr
- Mov CS:PrevOfs,SI
- Mov CS:PrevSeg,DS
- Cmp DI,0FFFFH
- Jnz DoCheckDup
- Mov DI,CS:PrevBuffOfs
- Cmp DI,0FFFFH
- Jz MoveLine2
- Mov ES,CS:WriteBuff.Segm
- Cmp CS:FinalOutput,0
- Jz DoCheckDup
- Cmp CS:FixedLen,0
- Jnz DoCheckDup
- Mov CX,CS:WriteBuff.Beg
- Sub CX,DI ;Length of last line in write buffer.
- Dec CX
- Dec CX ;Length excluding CRLF.
- Dec DI
- Dec DI ;Point to where length field should be.
- Xchg CX,ES:[DI] ;Xchg length for current contents.
- Push CX
- Push DI
- Mov DX,SI
- Call CompRoutine
- Sahf
- Mov SI,DX
- Pop DI
- Pop CX
- Mov ES:[DI],CX ;Restore contents of bucket.
- Jnz MoveLine2
- Clc
- Ret
- DoCheckDup: Mov DX,SI
- Call CompRoutine
- Sahf
- Mov SI,DX
- Jnz MoveLine2
- Clc
- Ret
- MoveLine2: Mov AX,CS:FixedLen
- Or AX,AX
- Jnz MoveLine4
- MoveLine3: Lodsw ;AX = line len.
- Inc AX
- Inc AX ;Len of line + CRLF.
- MoveLine4: Mov CX,CS:WriteBuffEnd
- Les DI,CS:WriteBuff
- Sub CX,DI ;Remain space in buffer.
- Sub CX,AX
- Xchg CX,AX ;CX = Line len.
- Jae RoomForLine ;Jmp if enough space in buff.
- Or DI,DI ;Chk if data in buff.
- Jz WriteInPlace ;Jmp if nothing in buff.
- Call WriteBuffer ;OK if something in buff.
- Mov CS:PrevOfs,0FFFFH ;Don't compare line to itself.
- Stc
- Ret
- RoomForLine: Mov CS:PrevBuffOfs,DI
- Add CS:WriteBuff.Beg,CX
- Cmp CS:FinalOutput,0
- Jnz RoomForLine1
- Sub SI,CS:LenBuckSize
- Jmp Short RoomForLine1B
- RoomForLine1: Cmp CS:FixedLen,0
- Jz RoomForLine2
- RoomForLine1B: Shr CX,1
- Jnc MoveWords1
- Movsb
- MoveWords1: Rep Movsw
- Clc
- Ret
- RoomForLine2: Shr CX,1
- Dec CX
- Jnc MoveWords2
- Movsb
- MoveWords2: Rep Movsw
- Mov AX,CS:LineEnd
- Stosw ;Move CRLF to buff.
- Clc
- Ret
- WriteInPlace: Cmp CS:FinalOutput,0
- Jnz DoWrtInPlace1
- Sub SI,CS:LenBuckSize
- Mov DX,SI
- Call WriteBuffer2
- Clc
- Ret
- DoWrtInPlace1: Mov DX,SI
- Cmp CS:FixedLen,0
- Jz DoWrtInPlace2
- Call WriteBuffer2
- Clc
- Ret
- DoWrtInPlace2: Add SI,CX
- Mov AX,CS:LineEnd
- Xchg Word Ptr[SI-2],AX
- Push AX
- Call WriteBuffer2
- Pop AX
- Mov Word Ptr[SI-2],AX
- Clc
- Ret
- DoWriteLow Endp
- ;
- WriteDataM Proc Near
- Call WriteSetup
- Cmp CS:SkipSetupTop,0
- Jz WriteLowRcdM
- Jmp SetJEqSegNumbM
- NextLowJM: Inc CX
- Inc CX ;CH = 0, CL SegNumb + 2.
- Mov BX,CX
- Shr BX,1
- And BL,0FEH ;First trial TopIndex.
- Mov SI,CS:TopIndex ;Contents of Jth TopIndex buck.
- Push SI ;Will insert this in proper buck.
- Shl SI,1
- Lds SI,CS:Data[SI] ;DS:SI pts low rcd in data seg.
- NextLowIM: Mov DI,CS:TopIndex[BX] ;Contents of Jth TopIndex buck.
- Shl DI,1
- Les DI,CS:Data[DI] ;ES:DI pts low rcd in data seg.
- Push CX
- Mov BP,BX
- Mov DX,SI
- Call CompRoutine
- Mov SI,DX
- Mov BX,BP
- Pop CX
- Jnc GoUpM
- GoDownM: Mov CL,BL
- Add BL,CH
- Shr BL,1
- And BL,0FEH
- Cmp BL,CH
- Ja NextLowIM
- Jmp Short FoundPosM
- GoUpM: Mov CH,BL
- Add BL,CL
- Shr BL,1
- And BL,0FEH
- Cmp BL,CH
- Ja NextLowIM
- FoundPosM: Mov CX,BX
- Shr CX,1
- Mov DI,Offset TopIndex
- Lea SI,[DI+2]
- Mov AX,CS
- Mov ES,AX
- Mov DS,AX
- Rep Movsw
- Pop BP
- Mov [DI],BP
- WriteLowRcdM: Mov SI,CS:TopIndex ;Index in 0th buck.
- Shl SI,1
- Lds SI,CS:Data[SI] ;DS:SI pts low rcd in data seg.
- Call DoWriteLow
- Jc WriteLowRcdM
- SetNextSearchM: Mov AX,CS
- Mov DS,AX
- Mov ES,AX
- Mov BX,TopIndex ;Contents of 1st top index buck.
- Mov DI,BX
- Mov SI,Data.Beg[BX+DI]
- Mov CX,FixedLen
- Jcxz SetNext2BM
- Add SI,CX ;Offset of next line in segment.
- Mov Data.Beg[BX+DI],SI
- Cmp SI,DataEnd[BX]
- Jae WriteFinM
- Jmp Short SetJEqSegNumbM
- SetNext2BM: Mov DS,Data.Segm[BX+DI]
- Lodsw
- Add SI,AX ;Offset of next line in segment.
- Mov CS:Data.Beg[BX+DI],SI
- Cmp SI,CS:DataEnd[BX]
- Jae WriteFinM
- Lodsw
- Add SI,AX
- Jc WriteFinM
- Cmp SI,CS:DataEnd[BX]
- Ja WriteFinM
- Mov CX,CS
- Mov DS,CX
- SetJEqSegNumbM: Mov CX,CS:SegNumb ;Pt to last TopIndex buck.
- Jcxz WriteLowRcdM
- Jmp NextLowJM
- WriteFinM: Ret
- ;
- WriteDataM Endp
- ;
- MergeData Proc Near
- ;
- Mov SI,CS:OrigStart
- Mov CS:Word Ptr[SI+4],0DB8CH
- Mov CS:Byte Ptr[SI+6],08CH
- Mov CS:UseRcdLen,0FFH
- ;
- ;Repeat {Until BlockCt = 1}
- ;
- ; Initialize NewBlockBeg, NewBlockEnd and NewBlockSeg
- MergeData1: Mov AX,CS:BlockSeg
- Mov CS:LastSeg,AX
- Mov CS:NewBlockBeg,0008H
- Mov CS:NewBlockEnd,0008H
- Mov AX,CS:MemoryEndSeg
- Dec AX
- Mov CS:NewBlockSeg,AX
- Mov AX,CS:LastSeg
- Sub AX,CS:MemoryBegSeg
- Sub AX,CS:MergeBuff
- Mov BX,CS:LongestLen
- Add BX,15
- Mov CL,4
- Shr BX,CL
- Mov CX,CS:MergeSeg ;Minimum for segment.
- Cmp CX,BX
- Jae CompMaxSegCt
- Mov CX,BX
- CompMaxSegCt: Xor DX,DX
- Div CX
- Cmp AX,2
- Jae StoreMaxSegCt
- Or AX,AX
- Jz CompMaxSegCt2
- Mov AX,CX
- CompMaxSegCt2: Add AX,DX ;Recover avail mem paragraphs.
- Shr AX,1 ;Half of avail mem paragraphs.
- Cmp AX,BX
- Jbe TwoRcdNG ;Jmp if not room for two records.
- Mov AX,2 ;Else set two segments.
- Jmp Short StoreMaxSegCt
- TwoRcdNG: Jmp DoTwoRcdMsg ;Error if not room for two data seg.
- StoreMaxSegCt: Mov CS:MaxSegCount,AX
- ;
- ; HowManySegs = the minimum of:
- ; a. 64
- ; b. BlockCt
- ; c. MaxSegCount
- ;
- Mov BP,CS:BlockCT
- Cmp BP,AX
- Jbe MergeData2
- Xchg BP,AX
- MergeData2: Cmp BP,64
- Jbe MergeData3
- Mov BP,64
- MergeData3: Mov CS:HowManySegs,BP
- ;
- ; Swap WriteHandle with ReadHandle.
- Mov BX,CS:WriteHandle
- Xchg BX,CS:ReadHandle
- Mov CS:WriteHandle,BX
- ;
- ; Truncate WriteHandle file.
- Cmp CS:FirstMerge,0
- Jnz MergeData3B
- Call TruncFile
- ;
- ; NewBlockCt = (BlockCt) / HowManySegs.
- ; Since HowManySegs LE BlockCt, NewBlockCt GE 1.
- MergeData3B: Mov CS:FirstMerge,0
- Mov CS:UseExtra,0
- Mov CS:LastIsExtra,0
- Mov AX,CS:BlockCt
- Xor DX,DX
- Div CS:HowManySegs
- Mov CS:NewBlockCt,AX
- Mov CS:RemainderSegs,DX
- ;
- ; If RemainderSegs <> 0 and NewBlockCT = 1 then:
- ; a. ThisTimeSegs = RemainderSegs + 1.
- ; b. BegBlock = BlockCt - RemainderSegs - 1.
- ; c. Swap WriteHandle with ExtraHandle.
- ; d. Truncate ExtraHandle file.
- ; e. Call CalcMaxSegSize.
- ; f. Call MergeOneBlock.
- ; g. Call WriteBuffer.
- ; h. Set UseExtra = 0FFH.
- ; i. Swap WriteHandle with ExtraHandle.
- ; j. Store length of extra file in ExtraEnd.
- ; k. Reduce length of write file by ExtraEnd.
- ; l. RemainderSegs = 0.
- Or DX,DX
- Jnz MergeData5H1
- JmpMergeData5I: Jmp MergeData5I ;Jump if RemainderSegs = 0.
- MergeData5H1: Cmp AX,1
- Jnz JmpMergeData5I ;Jump if NewBlockCt <> 1.
- Inc DX
- Mov CS:ThisTimeSegs,DX ;Will merge RemainderSegs + 1.
- Mov AX,CS:BlockCT
- Sub AX,DX
- Mov CS:BegBlock,AX
- Mov BX,CS:WriteHandle
- Xchg BX,CS:ExtraHandle
- Mov CS:WriteHandle,BX
- Cmp CS:FirstExtra,0
- Jnz MergeData5H
- Call TruncFile
- MergeData5H: Mov CS:FirstExtra,0
- Call CalcMaxSegSize
- Call MergeOneBlock
- Call WriteBuffer
- Mov CS:UseExtra,0FFH
- ;
- Mov AX,GetFileLen
- Mov BX,CS:WriteHandle
- Xor CX,CX
- Mov DX,CX
- Int DOS
- Jnc SaveExtraEnd
- DoError73: Mov AX,3337H
- Jmp DiskError
- SaveExtraEnd: Mov CS:Word Ptr ExtraEnd,AX
- Mov CS:Word Ptr ExtraEnd+2,DX
- ;
- Mov BX,CS:WriteHandle
- Xchg BX,CS:ExtraHandle
- Mov CS:WriteHandle,BX
- ;
- Mov SI,CS:BegBlock
- Dec SI
- Call GetFileLocn
- Mov BX,CS:ReadHandle ;CX:DX = New read file size.
- Call TruncFile2
- Mov CS:RemainderSegs,0
- ;
- ; Get MaxSegSize for the merge down to NewBlockCt.
- MergeData5I: Mov AX,CS:HowManySegs
- Mov CS:ThisTimeSegs,AX
- Call CalcMaxSegSize
- ;
- ; If NewBlockCt <> 1 go and merge the blocks
- ; else close and delete WriteHandle
- ; set WriteHandle = output file.
- Cmp CS:NewBlockCt,1
- Jnz MergeData5L
- Mov CS:FinalOutput,0FFH
- ; Close and delete the WriteHandle file.
- Mov BX,CS:WriteHandle
- Mov DX,Offset TempName1
- Cmp BX,CS:TempHandle1
- Jz MergeData5C2
- Mov DX,Offset TempName2
- Mov CS:TempHandle2,0
- Jmp Short MergeData5D
- MergeData5C2: Mov CS:TempHandle1,0
- MergeData5D: Mov AX,CS
- Mov DS,AX
- Call CloseDelete
- ; WriteHandle = output file handle.
- Cmp CS:GotOutput,0
- Jz UseStdOp
- Call OpenOutput
- Jmp Short MergeData5L
- UseStdOp: Mov CS:WriteHandle,StdOutput
- ;
- ; If RemainderSegs <> 0 then NewBlockCt = NewBlockCt + 1
- ; else RemainderSegs = HowManySegs.
- MergeData5L: Cmp CS:RemainderSegs,0
- Jz MergeData5J
- Inc CS:NewBlockCt
- Jmp Short MergeData6
- MergeData5J: Mov CX,CS:HowManySegs
- Mov CS:RemainderSegs,CX
- ;
- ; For N = NewBlockCt - 1 To 0 Step -1
- MergeData6: Mov CX,CS:NewBlockCT
- Dec CX
- MergeData7: Push CX
- ;
- ; If N = 0 and UseExtra = 0FFH then LastIsExtra = 0FFH.
- ; If N = 0 ThisTimeSegs = RemainderSegs
- Or CX,CX
- Jnz MergeData8
- Mov AX,CS:RemainderSegs
- Cmp AX,CS:ThisTimeSegs
- Jz MergeData7B
- Mov CS:ThisTimeSegs,AX
- Push CX
- Call CalcMaxSegSize
- Pop CX
- MergeData7B: Cmp CS:UseExtra,0
- Jz MergeData8
- Mov CS:LastIsExtra,0FFH
- ;
- ; BegBlock = (NewBlockCt - N - 1) * HowManySegs
- MergeData8: Mov AX,CS:NewBlockCt
- Dec AX
- Sub AX,CX
- Mul CS:HowManySegs
- Mov CS:BegBlock,AX
- Add AX,CS:ThisTimeSegs
- Dec AX
- Mov CS:EndBlock,AX
- ;
- Call MergeOneBlock
- ;
- ; We come here when we when have finished one of the new blocks. Just as was
- ; done by WriteData we must save the ending position of the new block in the
- ; block table (reusing one of the buckets used for one of the old blocks)
- ; and must store the new blockend blockbeg and blockseg values. Since the
- ; old values are still needed, we store them in NewBlockEnd, NewBlockBeg and
- ; NewBlockSeg.
- MergeData17: Call WriteBuffer
- Cmp CS:FinalOutput,0
- Jnz MergeData19
- ;
- Mov AX,GetFileLen
- Mov BX,CS:WriteHandle
- Xor CX,CX
- Mov DX,CX
- Int DOS
- Jnc SaveWriteEnd
- DoError74: Mov AX,3437H
- Jmp DiskError
- SaveWriteEnd: Mov SI,CS:NewBlockEnd
- Mov DS,CS:NewBlockSeg
- Mov Word Ptr[SI],AX
- Mov Word Ptr[SI+2],DX
- Sub SI,4
- Jnc MergeData18
- Dec CS:NewBlockSeg
- Add CS:NewBlockBeg,10H
- Add SI,10H
- MergeData18: Mov CS:NewBlockEnd,SI
- ;
- ; Next N
- MergeData19: Pop CX
- Dec CX
- Js MergeData19B
- Jmp MergeData7
- ;
- ; BlockCt = NewBlockCt: BlockEnd = NewBlockEnd
- ; BlockBeg = NewBlockBeg: BlockSeg = NewBlockSeg
- MergeData19B: Mov AX,CS:NewBlockEnd
- Mov CS:BlockEnd,AX
- Mov AX,CS:NewBlockBeg
- Mov CS:BlockBeg,AX
- Mov AX,CS:NewBlockSeg
- Mov CS:BlockSeg,AX
- Mov AX,CS:NewBlockCt
- Mov CS:BlockCt,AX
- ;
- ;Until BlockCt = 1
- Cmp AX,1
- Jz MergeData19C
- Jmp MergeData1
- ;
- ;Write CtrlZ if input file had one.
- MergeData19C: Mov AX,CS
- Mov DS,AX
- Cmp GotCtrlZ,0
- Jz MergeData19C2
- Mov DX,Offset PrtCtrlZ
- Mov CX,1
- Mov BX,WriteHandle
- Mov AH,Write
- Int DOS
- ;Close the output file if it is not the standard output.
- MergeData19C2: Mov BX,WriteHandle
- Cmp BX,StdOutput
- Jz MergeData19D
- Mov AX,Close
- Int DOS
- ;Close and delete the ReadHandle and ExtraHandle files.
- MergeData19D: Cmp NeedMerge,0
- Jz MergeDataRet
- Mov BX,ReadHandle
- Mov DX,Offset TempName1
- Cmp BX,TempHandle1
- Jz MergeData19E
- Mov DX,Offset TempName2
- Mov TempHandle2,0
- Jmp Short MergeData20
- MergeData19E: Mov TempHandle1,0
- MergeData20: Call CloseDelete
- Mov BX,ExtraHandle
- Mov ExtraHandle,0
- Mov DX,Offset TempName3
- Call CloseDelete
- MergeDataRet: Ret
- ;
- MergeData Endp
- ;
- TruncFile Proc Near
- Xor CX,CX
- Mov DX,CX
- TruncFile2: Mov AX,SetFileAtBeg
- Int DOS
- Jc TruncNg63
- Mov AH,Write
- Xor CX,CX
- Int DOS
- Jc TruncNG64
- Or AX,AX
- Jnz TruncNg65
- Ret
- TruncNg63: Mov AX,3336H
- Jmp DiskError
- TruncNg64: Mov AX,3436H
- Jmp DiskError
- TruncNg65: Mov AX,3536H
- Jmp DiskError
- TruncFile Endp
- ;
- GetFileLocn Proc Near
- Mov DS,CS:BlockSeg
- Mov BX,CS:BlockBeg
- Shl SI,1
- Shl SI,1
- Sub BX,SI
- Mov DX,[BX]
- Mov CX,[BX+2] ;CX:DX = Loc in file.
- Ret
- GetFileLocn Endp
- ;
- CalcMaxSegSize Proc Near
- ;
- ; MaxSegSize = Minimum of:
- ; a. (Avail Mem - MinBuff) / ThisTimeSegs
- ; b. 64K (1000H paragraphs).
- ;
- Mov AX,CS:LastSeg
- Sub AX,CS:MemoryBegSeg
- Sub AX,CS:MergeBuff
- Xor DX,DX
- Div CS:ThisTimeSegs
- Mov BX,CS:DataPara
- Cmp AX,BX
- Jb MergeData4
- Mov AX,CS:DataMax
- Jmp Short MergeData5
- MergeData4: Mov CL,4
- Shl AX,CL
- Mov CX,CS:FixedLen
- Jcxz MergeData5
- Xor DX,DX
- Div CX
- Mul CX
- MergeData5: Mov CS:MaxSegSize,AX
- Ret
- CalcMaxSegSize Endp
- ;
- MergeOneBlock Proc Near
- ; SegCount = HowManySegs
- Mov AX,CS:ThisTimeSegs
- Shl AX,1
- Mov CS:SegCount,AX
- ;
- ; NextSeg = MemoryBegSeg
- Mov AX,CS:MemoryBegSeg
- Mov CS:NextSeg,AX
- ;
- ; If LastIsExtra = 0FFH
- ; then MaxSegs = ThisTimeSegs - 2
- ; else MaxSegs = ThisTimeSegs - 1.
- Mov AX,CS:ThisTimeSegs
- Dec AX
- Cmp CS:LastIsExtra,0
- Jz StoreMaxSegs
- Dec AX
- StoreMaxSegs: Mov CS:MaxSegs,AX
- ;
- ; For M = 0 To MaxSegs
- Xor CX,CX
- Mov CS:SkipSetupTop,0
- ;
- ; If BlockLen(BegBlock + M) >= MaxSegSize Then
- ; SegLen(M) = MaxSegSize
- ; Else
- ; SegLen(M) = BlockLen(BegBlock + M)
- ; EndIf
- MergeData9: Push CX
- Mov DS,CS:BlockSeg
- Mov BX,CS:BlockBeg
- Mov DI,CX
- Shl DI,1
- Shl DI,1 ;4 * M
- Mov AX,CS:BegBlock
- Shl AX,1
- Shl AX,1 ;4 * BegBlock
- Sub BX,AX
- Sub BX,DI ;Point to table entry for BegBlock + M.
- Mov AX,[BX]
- Mov DX,[BX+2] ;Location of end of block.
- Mov SI,[BX+4]
- Mov BP,[BX+6] ;Location of beg of block.
- Call ReadOneBlock
- ;
- ; BlockOfs(M) = SegLen(M)
- MergeData11B: Pop DI ;Recover M.
- Mov AX,DI ;Hold M.
- Shl DI,1
- Shl DI,1 ;Point to BlockOfs bucket.
- Mov CS:Word Ptr BlockOfs[DI],CX
- Mov CS:Word Ptr BlockOfs[DI+2],0
- ;
- ; Next M
- Mov CX,AX
- Inc CX
- Cmp CX,CS:MaxSegs
- Jbe MergeData9
- ;
- MergeData11C: Cmp CS:LastIsExtra,0
- Jz DoMergeWrite1
- Mov DI,CX
- Push DI
- Shl DI,1
- Mov CS:ExtraNumb,DI
- Shl DI,1 ;4 * M
- Mov AX,CS:Word Ptr ExtraEnd
- Mov DX,CS:Word Ptr ExtraEnd+2 ;Location of end of block.
- Xor SI,SI
- Mov BP,SI ;Location of beg of block.
- Mov BX,CS:ReadHandle
- Xchg BX,CS:ExtraHandle
- Mov CS:ReadHandle,BX
- Call ReadOneBlock
- Mov BX,CS:ReadHandle
- Xchg BX,CS:ExtraHandle
- Mov CS:ReadHandle,BX
- ;
- ; BlockOfs(M) = SegLen(M)
- Pop DI ;Recover M.
- Shl DI,1
- Shl DI,1 ;Point to BlockOfs bucket.
- Mov CS:Word Ptr BlockOfs[DI],CX
- Mov CS:Word Ptr BlockOfs[DI+2],0
- ;
- DoMergeWrite1: Mov CS:PrevOfs,0FFFFH
- DoMergeWrite: Call WriteDataM
- Mov CS:SkipSetupTop,0FFH
- ;
- ; Empty = TopIndex(1)
- Mov BX,CS:TopIndex
- ;
- ; Check for partial line, if any, and move to beginning of segment.
- Mov CX,CS:DataEnd[BX]
- Shl BX,1
- Mov SI,CS:Data.Beg[BX]
- Sub CX,SI
- Je MergeData12 ;Jump if no partial line.
- Xor DI,DI
- Mov AX,CS:Data.Segm[BX]
- Mov DS,AX
- Mov ES,AX
- Shr CX,1
- Jnc PartWords
- Movsb
- PartWords: Rep Movsw
- Mov CS:Data.Beg[BX],DI
- Jmp Short MergeData12B
- ;
- ; If BlockLen(Empty) <= BlockOfs(Empty) Then
- ; SegCount = SegCount - 1
- ; If SegCount > 0 Then
- ; Goto DoMergeWrite
- ; Else
- ; Goto FinishNewBlock
- ; EndIf
- ; EndIf
- MergeData12: Mov CS:Data.Beg[BX],0
- MergeData12B: Mov AX,CS:Word Ptr BlockLen[BX]
- Mov DX,CS:Word Ptr BlockLen[BX+2]
- Sub AX,CS:Word Ptr BlockOfs[BX]
- Sbb DX,CS:Word Ptr BlockOfs[BX+2]
- Jb MergeData13
- Mov CX,DX
- Or CX,AX
- Jnz MergeData14
- MergeData13: Cmp CS:Data.Beg[BX],0
- Jnz MergeData14
- Cmp CS:LastIsExtra,0
- Jz MergeData13B
- Shr BX,1
- Cmp BX,CS:ExtraNumb
- Jnz MergeData13B
- Mov CS:LastIsExtra,0
- MergeData13B: Sub CS:SegCount,2
- Jz JmpMergeOneRet
- Mov AX,CS
- Mov DS,AX
- Mov ES,AX
- Mov BX,TopIndex
- Mov CX,SegCount
- Shr CX,1
- Mov DI,Offset TopIndex
- Lea SI,[DI+2]
- Rep Movsw
- Mov [DI],BX
- Jmp DoMergeWrite
- JmpMergeOneRet: Jmp MergeOneRet
- ;
- ; If BlockLen(Empty) - BlockOfs(Empty) >= MaxSegSize Then
- ; SegLen(Empty) = SegMax
- ; Else
- ; SegLen(Empty) = BlockLen(BegBlock + Empty) - BlockOfs(BegBlock + Empty);
- ; EndIf
- MergeData14: Add AX,CS:Data.Beg[BX]
- Adc DX,0
- Or DX,DX
- Jnz MergeData15
- Cmp AX,CS:MaxSegSize
- Jbe MergeData16
- MergeData15: Mov AX,CS:MaxSegSize
- ;
- ; Read SegLen(Empty) bytes from Block(BegBlock + Empty) into Seg(Empty)
- ; BlockOfs(Empty) = BlockOfs(Empty) + SegLen(Empty)
- ; Goto DoMergeWrite
- MergeData16: Shr BX,1
- Mov CS:DataEnd[BX],AX
- Push AX
- Mov AX,CS:ReadHandle
- Mov CS:UseHandle,AX
- Cmp CS:LastIsExtra,0
- Jz MergeData16B
- Cmp BX,CS:ExtraNumb
- Jnz MergeData16B
- Mov AX,CS:ExtraHandle
- Mov CS:UseHandle,AX
- MergeData16B: Mov AX,SetFileAtBeg
- Shl BX,1
- Mov DX,CS:Word Ptr BlockPos[BX]
- Mov CX,CS:Word Ptr BlockPos[BX+2]
- Add DX,CS:Word Ptr BlockOfs[BX]
- Adc CX,CS:Word Ptr BlockOfs[BX+2]
- Push BX
- Mov BX,CS:UseHandle
- Int DOS
- Jc GoNgWrite66
- Pop BX
- Pop CX
- Mov DX,CS:Data.Beg[BX]
- Mov CS:Data.Beg[BX],0
- Sub CX,DX
- Add CS:Word Ptr BlockOfs[BX],CX
- Adc CS:Word Ptr BlockOfs[BX+2],0
- Mov DS,CS:Data.Segm[BX]
- Mov BX,CS:UseHandle
- Mov AX,Read
- Int DOS
- Jc GoNGWrite67
- Cmp AX,CX
- Jne GoNGWrite68
- Jmp DoMergeWrite1
- MergeOneRet: Ret
- GoNGWrite66: Mov AX,3636H
- Jmp DiskError
- GoNGWrite67: Mov AX,3736H
- Jmp DiskError
- GoNGWrite68: Mov AX,3836H
- Jmp DiskError
- MergeOneBlock Endp
- ;
- ReadOneBlock Proc Near
- Sub AX,SI
- Sbb DX,BP ;Length of block.
- Mov CS:Word Ptr BlockLen[DI],AX
- Mov CS:Word Ptr BlockLen[DI+2],DX
- Mov CS:Word Ptr BlockPos[DI],SI
- Mov CS:Word Ptr BlockPos[DI+2],BP
- Jnz MergeData10
- Cmp AX,CS:MaxSegSize
- Jb MergeData11
- MergeData10: Mov AX,CS:MaxSegSize
- MergeData11: Shr DI,1
- Mov CS:DataEnd[DI],AX
- Mov DX,CS:NextSeg
- Shl DI,1
- Mov CS:Data.Segm[DI],DX
- Mov CS:Data.Beg[DI],0
- Mov DI,AX
- Add DI,15
- Mov CL,4
- Shr DI,CL
- Add CS:NextSeg,DI
- ;
- ; Read SegLen(M) bytes from loc zero in Block(BegBlock + M) into Seg(M)
- Push DX
- Push AX
- Mov AX,SetFileAtBeg
- Mov DX,SI
- Mov CX,BP
- Mov BX,CS:ReadHandle
- Int DOS
- Jc JmpNGWrite69
- Pop CX
- Pop DS
- Mov BX,CS:ReadHandle
- Mov AX,Read
- Xor DX,DX
- Int DOS
- Jc JmpNGWrite70
- Cmp AX,CX
- Je ReadOneBlkRet
- JmpNGWrite69: Mov AX,3936H
- Jmp DiskError
- JmpNGWrite70: Mov AX,3037H
- Jmp DiskError
- ReadOneBlkRet: Ret
- ReadOneBlock Endp
- ;
- FindMsgEnd Proc Near
- Push CS
- Push CS
- Pop DS
- Pop ES
- Cld
- Push DX
- Cmp GotError,0
- Jnz DoWriteERROR
- Mov SI,DX
- Inc SI
- Lodsw
- And AX,0F0FH
- Xchg AH,AL ;AH = hi digit, AL = lo digit of code.
- Aad
- Mov ErrorCode,AL
- Call WriteNewLine
- DoWriteERROR: Call WriteERROR
- Pop DX
- Or GotKeyErr,GotOtherErr
- Mov GotError,0FFH
- Mov DI,DX ;Address of message
- Mov CX,256
- Mov AL,'$'
- Repne Scasb
- Dec DI ;Point back to '$'.
- Mov CX,DI
- Sub CX,DX
- Call WriteStdError
- Ret
- FindMsgEnd Endp
- ;
- DispErrorParm Proc Near
- Push DS
- Push ES
- Push CX
- Push SI
- Push BX
- Push AX
- Call FindMsgEnd
- Push CX ;Save length of message.
- Mov DX,ParmBeg
- Mov SI,DX
- Mov CX,ParmChars ;Remaining parm characters.
- Lodsb
- Dec CX
- Jcxz EndOfParm
- NextErrorChar: Lodsb
- Cmp AL,Slash
- Jz EndOfParm
- Cmp AL,Space
- Jz EndOfParm
- Loop NextErrorChar
- Jmp Short EndOfParm2
- EndOfParm: Dec SI
- EndOfParm2: Mov CX,SI
- Sub CX,DX
- Pop AX ;Retreive length of message.
- Add AX,8 ;Length of " ERROR " plus quote.
- Cmp AX,80
- Jbe EndOfParm3
- Sub AX,80
- EndOfParm3: Add AX,CX ;Add length of parm.
- Cmp AX,79
- Jb EndOfParm4
- Push CX
- Push DX
- Mov DX,Offset TwelveSpaces
- Mov CX,14
- Call WriteStdError
- Pop DX
- Pop CX
- EndOfParm4: Push CX
- Push DX
- Mov DX,Offset Quote
- Mov CX,1
- Call WriteStdError
- Pop DX
- Pop CX
- Call WriteStdError
- Mov DX,Offset Quote
- Mov CX,1
- Call WriteStdError
- Jmp Short DispError2
- DispErrorParm Endp
- ;
- DisplayError Proc Near
- Push DS
- Push ES
- Push CX
- Push SI
- Push BX
- Push AX
- Call FindMsgEnd
- DispError2: Call WriteNewLine
- Mov CS:DidErrorWord,0
- Pop AX
- Pop BX
- Pop SI
- Pop CX
- Pop ES
- Pop DS
- Ret
- DisplayError Endp
- ;
- DisplayExit Proc Near
- Call DisplayError
- ErrorExit: Call FinalDeletes
- Mov AL,CS:ErrorCode
- Jmp GoBack
- DisplayExit Endp
- ;
- FinalDeletes Proc Near
- Push CS
- Pop DS
- Mov BX,TempHandle1
- Mov TempHandle1,0
- Mov DX,Offset TempName1
- Call CloseDelete
- Mov BX,TempHandle2
- Mov TempHandle2,0
- Mov DX,Offset TempName2
- Call CloseDelete
- Mov BX,TempHandle3
- Mov TempHandle3,0
- Mov DX,Offset TempName3
- Call CloseDelete
- Cmp OpenedOutput,0
- Jz FinalDeleteRet
- Mov BX,OutputHandle
- Cmp BX,StdOutput
- Jbe FinalDeleteRet
- Mov DX,OutputAddr
- Call CloseDelete
- FinalDeleteRet: Ret
- FinalDeletes Endp
- ;
- CloseDelete Proc Near
- Or BX,BX
- Jz CloseDeleteRet
- Mov AX,Close
- Int DOS
- Jc DoError71
- Mov AX,Delete
- Int DOS
- Jc DoError72
- CloseDeleteRet: Ret
- DoError71: Mov AX,3137H
- Jmp DiskError
- DoError72: Mov AX,3237H
- Jmp DiskError
- CloseDelete Endp
- ;
- WriteERROR: Mov CS:DidErrorWord,0FFH
- Mov DX,Offset ERRORWord
- Mov CX,7
- Jmp Short WriteStdError2
- ;
- WriteNewLine: Mov DX,Offset NewLine
- Mov CX,2
- ;
- WriteStdError Proc Near
- Mov CH,0
- WriteStdError2: Mov BX,ErrorHandle ;Write to StdError or error file.
- Mov AH,Write
- Int DOS
- Jc WrtStdNG
- Cmp AX,CX
- Jz WrtStdErrRet
- WrtStdNG: Cmp ErrorHandle,StdError
- Jz WrtStdErrRet
- Mov AX,Close
- Int DOS
- Mov ErrorHandle,StdError
- Mov BX,StdError
- Push DX
- Push CX
- Mov DX,Offset FullErrMsg
- Mov CX,Offset FullErrEnd - Offset FullErrMsg
- Mov AH,Write
- Int DOS
- Cmp CS:DidErrorWord,0
- Jz WrtStdNG2
- Call WriteERROR
- Mov CS:DidErrorWord,0
- WrtStdNG2: Pop CX
- Pop DX
- Jmp WriteStdError2
- WrtStdErrRet: Ret
- WriteStdError Endp
- ;
- GetNumb Proc Near
- Cld
- Xor DX,DX ;Start with result = 0.
- Mov DI,10
- NextDigit: Cmp AL,30H ;Digit must
- Jb FinNumb1 ;be between
- Cmp AL,39H ;0 and 9.
- Ja FinNumb1
- And AX,0FH ;Strip high nibl.
- Push AX
- Xchg AX,DX ;AX now = prev result.
- Mul DI ;Mult by 10.
- Pop DX ;Recover new digit.
- Jo Make65535 ;NG if GT 65535.
- Add DX,AX ;DX = result so far.
- Jc Make65535 ;NG if GT 65535.
- Jcxz FinNumbRet
- Dec CX
- Lodsb
- Jmp NextDigit
- FinNumb1: Dec SI
- Inc CX
- FinNumbRet: Ret
- Make65535: Mov DX,65535
- AnyMoreNumb: Jcxz FinNumbRet
- Dec CX
- Lodsb
- Cmp AL,30H
- Jb FinNumb1
- Cmp AL,39H
- Ja FinNumb1
- Jmp AnyMoreNumb
- GetNumb Endp
- PascTooLong: Mov DX,Offset PascTooLongMsg
- Jmp DisplayExit
- ;
- AtHighEnd: Xchg BP,SI
- Xchg DX,BX
- Mov CX,BP
- Sub CX,DX
- Jmp Short CheckPartSize
- ;
- SortEnd Proc Near
- Mov AX,CS
- Mov DS,AX
- Mov ES,AX
- Ret
- SortEnd Endp
- ;
- SortData Proc Near
- Cld
- Mov StackHigh,SP
- Mov AX,SegCount
- Mov SegNumb,AX
- SortNextSeg: Sub CS:SegNumb,2
- Js SortEnd
- Mov AH,30H
- Int DOS
- Mov SI,CS:SegNumb
- Mov BX,SI
- Mov DS,CS:Data.Segm[SI+BX]
- Mov CS:BegSeg,DS
- Mov ES,CS:Pointer.Segm[SI+BX]
- Mov CS:PtrSeg,ES
- Mov DX,CS:PointerEnd[SI] ;Ofs of last (Jth) ptr buck.
- Mov BP,CS:Pointer.Beg[SI+BX] ;Ofs of first (Ith) ptr buck.
- Mov CX,BP
- Sub CX,DX
- Jmp Short CheckPartSize
- NewPartition: Pop SI ;Lo end of curr part.
- Pop BX ;Hi end of curr part.
- Xchg BX,DX
- Dec BP ;BP is lo for upper part.
- Dec BP ;DX is hi for upper part.
- Inc BX ;BX is hi for low part.
- Inc BX ;SI is lo for low part.
- Mov CX,BP
- Sub CX,DX ;Size of upper part.
- Cmp CX,-2
- Jz AtHighEnd
- Mov AX,SI
- Sub AX,BX ;Size of low part.
- Jc CheckPartSize
- Cmp AX,CX
- Jae Save1Part ;Jmp if low part GE upper.
- Xchg BX,DX
- Xchg SI,BP
- Xchg AX,CX
- Save1Part: Push BX
- Push SI
- CheckPartSize: Shr CX,1
- Jnz GetIOffset
- FinishPart: Cmp SP,CS:StackHigh
- Jb FinishPart2
- Jmp SortNextSeg ;If no more parts we are done.
- FinishPart2: Pop BP ;Lo ofs in part.
- Pop DX ;Hi ofs in part.
- Mov CX,BP
- Sub CX,DX
- Jmp CheckPartSize
- GetIOffset: Push DX ;Hi ofs for new part.
- Push BP ;Lo ofs for new part.
- Mov DI,BP
- Add DI,DX ;(Hi ofs + Lo ofs).
- Rcr DI,1 ;(Hi ofs + Lo ofs) / 2.
- Jpe ClearBit0
- Mov SI,BP
- Sub SI,DX
- Shr SI,1
- Shr SI,1
- Jpe SubDiff
- AddDiff: Add DI,SI ;Add (Hi - Lo) / 4.
- Jmp Short ClearBit0
- SubDiff: Shr SI,1
- Sub DI,SI ;Sub (Hi - Lo) / 8.
- ClearBit0: And DI,0FFFEH ;Make sure its on a word boundary.
- Mov SI,ES:[BP] ;Former first rcd.
- Xchg SI,ES:[DI] ;Swap ofs of rcd I
- Mov ES:[BP],SI ;with ofs of former first rcd.
- ;
- GetJOfSDown: Mov DI,DX ;Ofs of Jth ptr.
- Mov DI,ES:[DI] ;Ofs of Jth rcd.
- Push SI
- Mov ES,CS:BegSeg
- Call CompRoutine
- Mov ES,CS:PtrSeg
- Pop SI ;Recover ofs of Ith rcd.
- Ja ReverseDown ;Jump if Ith rcd goes after Jth.
- NextJDown: Inc DX ;Ofs of next Jth ptr buck.
- Inc DX
- Cmp DX,BP ;If J = I we have found correct
- Jnz GetJOfsDown ;pos for the Ith ptr.
- SaveIOfsDown: Mov ES:[BP],SI
- Jmp NewPartition ;Setup new part.
- ReverseDown: Mov DI,DX ;Ofs of Jth ptr.
- Mov DI,ES:[DI] ;Ofs of Jth rcd.
- Mov ES:[BP],DI ;Store in Ith ptr buck.
- Xchg DX,BP ;I and J ptrs are swapped.
- Jmp Short NextJUp ;Now must move upwards in search.
- ;
- GetJOfSUp: Mov DI,DX ;Ofs of Jth ptr.
- Mov DI,ES:[DI] ;Ofs of Jth rcd.
- Push SI
- Mov ES,CS:BegSeg
- Call CompRoutine
- Mov ES,CS:PtrSeg
- Pop SI ;Recover ofs of Ith rcd.
- Jb ReverseUp ;Jmp if Ith rcd goes before Jth.
- NextJUp: Dec DX ;Ofs of next Jth ptr buck.
- Dec DX
- Cmp DX,BP ;If J = I we have found correct
- Jne GetJOfsUp ;pos for the Ith ptr.
- SaveIOfsUp: Mov ES:[BP],SI
- Jmp NewPartition ;Setup new part.
- ReverseUP: Mov DI,DX ;Ofs of Jth ptr.
- Mov DI,ES:[DI] ;Ofs of Jth rcd.
- Mov ES:[BP],DI ;Store in Ith ptr buck.
- Xchg DX,BP ;I and J ptrs are swapped.
- Jmp NextJDown ;Now move down in search.
- ;
- SortData Endp
- ;
- TempRealExp DW 0
- TempRealShft1 DW 0
- TempRealShft2 DW 0
- TempReal1 DB 8 Dup(0)
- TempReal2 DB 8 Dup(0)
- ;
- TempUnNormal Proc Near
- ;
- Call CalcExponent ;Returns BX=shft ct, AX=new exp.
- Mov CS:TempRealExp,AX
- Mov CS:TempRealShft1,BX
- Push SI
- Mov SI,DI
- Push DS
- Push ES
- Pop DS
- Call CalcExponent
- Pop DS
- Pop SI
- Mov CS:TempRealShft2,BX
- Cmp CS:TempRealExp,AX ;If the two exponents are unequal
- Jne TempUnNormal2b ;then return proper carry flag.
- Or AX,AX ;If new exps equal and both zero
- Jnz TempUnNormal3 ;then return with z flag set.
- TempUnNormal2b: Mov CX,10
- Ret ;Return if new exponents not equal.
- ;
- TempUnNormal3: Push DS
- Push SI
- Push ES
- Push DI
- Mov BX,CS:TempRealShft1
- Mov DI,Offset TempReal1+7
- Call MoveTempReal
- Pop SI
- Pop DS
- Push DS
- Push SI
- Mov BX,CS:TempRealShft2
- Mov DI,Offset TempReal2+7
- Call MoveTempReal
- Mov AX,CS
- Mov ES,AX
- Mov DS,AX
- Mov SI,Offset TempReal1+7
- Mov DI,Offset TempReal2+7
- Mov CX,8
- Rep Cmpsb
- Pop DI
- Pop ES
- Pop SI
- Pop DS
- Mov CX,10
- Ret
- TempUnNormal Endp
- ;
- CalcExponent Proc Near
- Push SI
- Sub SI,3 ;Point to high word of mantissa.
- Mov CX,4
- Xor BX,BX
- NextWord: Lodsw
- Or AX,AX
- Js GotShift
- Jnz GetShift2
- Add BL,16
- Loop NextWord
- Jmp Short GotShift
- GetShift1: Inc BX
- GetShift2: Shl AX,1
- Jnc GetShift1
- GotShift: Pop SI
- Cmp BX,64
- Jnz GotShift2
- Xor AX,AX ;If pseudo zero make new exp = 0.
- Ret
- GotShift2: Mov AX,[SI-1]
- And AX,07FFFH
- Jnz GotShift3 ;If exp is zero this must be a
- Inc AX ;denormal so we increment it to one.
- GotShift3: Sub AX,BX ;New exp = old exp - shift count.
- Add AX,64 ;Make sure new exp is GE 0.
- Ret
- CalcExponent Endp
- ;
- MoveTempReal Proc Near
- Mov AX,CS
- Mov ES,AX
- Mov AX,BX
- Mov CL,3
- Shr AX,CL ;Number of leading zero bytes in mantissa.
- Mov BH,AL ;Number of trailing zero bytes in new mantissa.
- Sub SI,2 ;Skip exponent.
- Sub SI,AX ;Points to first non-zero byte.
- And BL,07H ;Number of lead zero bits in 1st non-zero byte.
- Mov CL,BL
- Mov BL,8
- Sub BL,BH ;Number of non-zero bytes.
- ;
- Push DX
- Jz TrailingZeros
- Lodsb
- Mov DH,AL
- Dec BL
- Jz LastTempByte
- ;
- NextTempByte: Lodsb
- Mov DL,AL
- Shl DX,CL
- Mov AL,DH
- Stosb
- Mov DH,DL
- Shr DH,CL
- Dec BL
- Jnz NextTempByte
- ;
- LastTempByte: Shl DH,CL
- Mov AL,DH
- Stosb
- TrailingZeros: Mov CL,BH
- Xor AL,AL
- Rep Stosb
- Pop DX
- Ret
- MoveTempReal Endp
- ;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- CompRoutine Proc Near
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;
- CompRtnBeg:
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;Use for second and later sort keys.
- ;
- SecondBeg: Sub CX,RelColumn
- Add SI,CX
- Add DI,CX
- SecondEnd:
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;Use in all cases.
- ;
- All1Beg: Mov CX,StartColumn ;Start col of key.
- All1End:
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;If fixed length add the following code.
- ;
- Fix1Beg: Add SI,CX ;Pt to key in Jth rcd.
- Add DI,CX ;Pt to key in Ith rcd.
- Mov CX,KeyLength ;Len of key.
- Fix1End:
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;If Pascal add the following code.
- ;
- Pascal1Beg: Xor AX,AX
- Mov BX,AX
- Lodsb ;Len of string in Jth line.
- Mov BL,ES:[DI] ;Len of string in Ith line.
- Inc DI
- Dec CX
- Xchg BX,CX ;BX = maxstrlen, CX = Ith strlen.
- Cmp AX,CX
- Jae GotShortLen
- Xchg CX,AX ;CX = lesser string length.
- GotShortLen: Lahf ;Save flags from compare.
- Cmp AL,BL ;Greater str len versus key len.
- Jbe GetPascRest
- JmpPascTooLong: Mov AX,Offset PascTooLong
- Jmp AX
- GetPascRest: Sub BX,CX ;Rest of key len.
- Sahf ;Set flags based on len compare in case one len
- Pascal1End: ;is zero. This prevents spurious flags.
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;If lines add the following code.
- ;
- Line1Beg: Lodsw
- Add SI,CX ;Pt to key in Jth rcd.
- Mov BX,ES:[DI] ;Len of Ith line.
- Inc DI
- Inc DI
- Add DI,CX ;Pt to key in Ith rcd.
- Xchg CX,AX ;Len of Jth line.
- Cmp CX,BX
- Jae GotShort
- Xchg BX,CX ;BX = lesser length.
- GotShort: Lahf
- Cmp CX,StartColumn
- MovKeyLen: Mov CX,KeyLength ;Len of key.
- Ja ShortLen
- BothShort: Mov BX,StartColumn
- Add CX,BX
- Sub SI,BX
- Sub DI,BX
- ;
- ;As code for each key is created, this target is set to FinishBeg + 2.
- ;If this is last key then the OrigSeq code will be at this loc.
- ;If not last key then code for next key will start at this addr.
- ;
- JmpOrigSeq: Jmp Short DoCompare ;If both too short then = compare.
- ShortLen: Sub BX,StartColumn ;Remain short line len.
- Ja DoCompare
- Sahf ;One line too short so get flags based on len.
- ;
- ;Change following to Cmc followed by Ret if /R specified.
- ;
- OnlyOneShort: Ret
- Nop
- ;
- DoCompare: Cmp BX,CX ;Remain short line len vs. key len.
- Jae LineEq
- Xchg CX,BX ;Len if only partial key in short line.
- Sub BX,CX
- Jmp Short Line1End
- LineEq: Mov AH,40H ;Neither short so make =.
- Xor BX,BX
- Line1End:
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;If collating and not zero add the following.
- ;
- CollNZ1Beg: Repe Cmpsb ;ASCII collating sort.
- CollNZ1End:
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;If collating and zero and lines add the following.
- ;
- LineCollZ1Beg: Push DX
- Jmp Short LineCollZ1Mid2
- LineCollZ1Mid1: Or AL,DL
- Jz LineCollZ1Mid3
- LineCollZ1Mid2: Lodsb
- Mov DL,ES:[DI]
- Inc DI
- Cmp AL,DL
- Loope LineCollZ1Mid1
- Jne LineCollZ1Mid4
- Or AL,DL
- Jz LineCollZ1Mid3
- Xor DX,DX ;Restore zero flag.
- Jmp Short LineCollZ1Mid4
- LineCollZ1Mid3: Mov AH,40H
- LineCollZ1Mid4: Pop DX
- LineCollZ1End:
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;If collating and zero and fixed add the following.
- ;
- FixCollZ1Beg: Lodsb
- Mov AH,ES:[DI]
- Inc DI
- Dec CX
- Cmp AL,AH
- Jnz FixCollZ1End
- Jcxz FixCollZ1End
- Or AL,AH
- Jnz FixCollZ1Beg
- FixCollZ1End:
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;If case insensitive and either Pascal or lines but not zero add the following.
- ;
- LinePasNZ1Beg: Push AX
- Push BX
- LinePasNZ1End:
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;If case insensitive and not zero add the following.
- ;
- CaseNZ1Beg: Jcxz CaseNZ1End ;For Pascal strings, CX could be zero.
- Mov BX,Offset XlatTable
- CaseNZNextChar: Lodsb ;Next byte of Jth line.
- Xlat CS:XlatTable ;Xlat byte from Jth line.
- Xchg AH,AL
- Mov AL,ES:[DI]
- Inc DI
- Xlat CS:XlatTable ;Xlat byte from Ith line.
- Cmp AH,AL ;J line byte vs. I line byte.
- Loope CaseNZNextChar
- CaseNZ1End:
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;If case insensitive and either Pascal or lines but not zero add the following.
- ;
- LinePasNZ2Beg: Pop BX
- Pop AX
- LinePasNZ2End:
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;If case insensitive and zero and lines add the following.
- ;
- LineCaseZ1Beg: Push DX
- Push BX
- Mov BX,Offset XlatTable
- Jmp Short LineCaseZ1Mid2
- LineCaseZ1Mid1: Or AL,DL
- Jz LineCaseZ1Mid3
- LineCaseZ1Mid2: Lodsb
- Xlat CS:XlatTable ;Xlat byte from Jth line.
- Xchg DL,AL
- Mov AL,ES:[DI]
- Inc DI
- Xlat CS:XlatTable ;Xlat byte from Ith line.
- Cmp DL,AL
- Loope LineCaseZ1Mid1
- Jne LineCaseZ1Mid4
- Or AL,DL
- Jz LineCaseZ1Mid3
- Xor DX,DX ;Restore zero flag.
- Jmp Short LineCaseZ1Mid4
- LineCaseZ1Mid3: Mov AH,40H
- LineCaseZ1Mid4: Pop BX
- Pop DX
- LineCaseZ1End:
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;If case insensitive and zero and fixed add the following.
- ;
- FixCaseZ1Beg: Push BX
- Mov BX,Offset XlatTable
- FixCaseZ1Mid1: Lodsb
- Xlat CS:XlatTable ;Xlat byte from Jth line.
- Xchg AH,AL
- Mov AL,ES:[DI]
- Inc DI
- Dec CX
- Xlat CS:XlatTable ;Xlat byte from Ith line.
- Cmp AH,AL
- Jnz FixCaseZ1Mid2
- Jcxz FixCaseZ1Mid2
- Or AL,AH
- Jnz FixCaseZ1Mid1
- FixCaseZ1Mid2: Pop BX
- FixCaseZ1End:
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;If signed binary integer add the following.
- ;
- Integer1Beg: Std
- Lodsb
- Mov AH,ES:[DI]
- Dec DI
- Dec CX
- Add AL,80H
- Add AH,80H
- Cmp AL,AH
- Jnz Integer1Mid
- Repe Cmpsb
- Integer1Mid: Cld
- Not CX
- Integer1End:
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;If unsigned binary integer add the following.
- ;
- Unsigned1Beg: Std
- Repe Cmpsb
- Cld
- Not CX
- Unsigned1End:
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;If IEEE temp real float add the following.
- ;
- TempReal1Beg: Std
- Or CX,CX ;Clear zero and carry flags.
- Mov AL,[SI]
- Mov AH,ES:[DI]
- Rcl AH,1 ;I use Rcl because it will never set
- Jc SecondNegE ;the Z flag.
- Rcl AL,1 ;I use Rcl because it will never set
- Jc TempReal1Mid ;the Z flag.
- BothPosE: Test Byte Ptr[SI-2],80H
- Jz DoPosUnNormal
- Test Byte Ptr ES:[DI-2],80H
- Jz DoPosUnNormal
- Repe Cmpsb
- Jmp Short TempReal1Mid
- DoPosUnNormal: Mov AX,Offset TempUnNormal
- Call AX
- Jmp Short TempReal1Mid
- DoNegUnNormal: Mov AX,Offset TempUnNormal
- Call AX
- Jmp Short TestNegEqual
- SecondNegE: Rcl AL,1 ;I use Rcl because it will never set
- Jnc TempReal1Mid ;the Z flag.
- BothNegE: Test Byte Ptr[SI-2],80H
- Jz DoNegUnNormal
- Test Byte Ptr ES:[DI-2],80H
- Jz DoNegUnNormal
- Repe Cmpsb
- TestNegEqual: Je TempReal1Mid
- Cmc
- TempReal1Mid: Cld
- Not CX
- TempReal1End:
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;If IEEE float add the following.
- ;
- ;Note that a negative zero will sort low relative to a positive zero. I
- ;have decided to make this a feature since the code to make negative and
- ;positive zeros compare equal would be inefficient.
- ;
- Float1Beg: Std
- Or CX,CX ;Clear zero and carry flags.
- Mov AL,[SI]
- Mov AH,ES:[DI]
- Rcl AH,1 ;I use Rcl because it will never set
- Jc SecondNeg ;the Z flag.
- Rcl AL,1 ;I use Rcl because it will never set
- Jc Float1Mid ;the Z flag.
- BothPos: Repe Cmpsb
- Jmp Short Float1Mid
- SecondNeg: Rcl AL,1 ;I use Rcl because it will never set
- Jnc Float1Mid ;the Z flag.
- BothNeg: Repe Cmpsb
- Je Float1Mid
- Cmc
- Float1Mid: Cld
- Not CX
- Float1End:
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;If original Microsoft binary float add the following.
- ;
- ;Note that in this case negative and positive zeros will sort equal because.
- ;I don't check for sign if both exponents are zero because interpreted BASIC
- ;often leaves garbage in the mantissa in such cases.
- ;
- Micro1Beg: Std
- Mov AX,[SI-1] ;AH = exponent, AL contains sign.
- Mov BX,ES:[DI-1] ;BH = exponent, BL contains sign.
- Or BH,AH
- Jz Micro1Mid ;If both exponents are zero don't
- ;compare the mantissas. Note that because we only continue
- ;if the Z flag is reset, we don't have to worry that we will
- ;have a spurious equal condition if signs are different.
- Rcl BL,1 ;I use Rcl because it will never set
- Jc SecondNegM ;the Z flag.
- Rcl AL,1 ;I use Rcl because it will never set
- Jc Micro1Mid ;the Z flag.
- BothPosM: Repe Cmpsb
- Jmp Short Micro1Mid
- SecondNegM: Rcl AL,1 ;I use Rcl because it will never set
- Jnc Micro1Mid ;the Z flag.
- BothNegM: Repe Cmpsb
- Je Micro1Mid
- Cmc
- Micro1Mid: Cld
- Not CX
- Micro1End:
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;If original Turbo Pascal binary float add the following.
- ;
- Turbo1Beg: Std
- Mov AL,[SI-5]
- Mov AH,ES:[DI-5]
- Or AL,AH ;If both exps zero don't compare
- Jz Turbo1Mid ;mantissas. Otherwise clear Z flag.
- Mov AL,[SI]
- Mov AH,ES:[DI]
- Rcl AH,1 ;I use Rcl because it will never set
- Jc SecondNegT ;set the Z flag.
- Rcl AL,1 ;I use Rcl because it will never set
- Jc Turbo1Mid ;the Z flag.
- BothPosT: Mov AL,[SI-5]
- Mov AH,ES:[DI-5]
- Cmp AL,AH
- Jnz Turbo1Mid
- Repe Cmpsb
- Jmp Short Turbo1Mid
- SecondNegT: Rcl AL,1 ;I use Rcl because it will never set
- Jnc Turbo1Mid ;the Z flag.
- BothNegT: Mov AL,[SI-5]
- Mov AH,ES:[DI-5]
- Cmp AL,AH
- Jnz ReverseCarry
- Repe Cmpsb
- Je Turbo1Mid
- ReverseCarry: Cmc
- Turbo1Mid: Cld
- Not CX
- Turbo1End:
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;In all cases add the following.
- ;
- ;If /R specified then Ret Nop becomes Cmc Ret.
- ;
- All2Beg: Jz All2End
- Mov AH,0 ;This is required by the ElimDup routine.
- Ret
- Nop
- All2End:
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;If lines or Pascal add the following.
- ;
- ;If /R specified then Ret Nop becomes Cmc Ret.
- ;
- LinePascal3Beg: Sahf
- Jz SameLen
- Mov AH,0 ;This is required by the ElimDup routine.
- Ret
- Nop
- SameLen: Add CX,BX
- ;
- LinePascal3End:
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;Add the following for all cases.
- ;
- ;This code added after each key is processed but is overlain by next key.
- ;
- OrigBeg:
- OrigSeq: Mov AH,40H ;This is required by the ElimDup routine.
- Inc SI ;These Incs are required because a numeric Cmp
- Inc DI ;might reduce to 0FFFFH for 1st item in seg.
- Cmp SI,DI ;If keys are EQ, we maintain the
- Ret ;orig seq for ident keys.
- DB 0C1H
- Cmp BX,CX
- Ret
- OrigEnd:
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;
- CompRtnEnd:
- ;
- CompRoutine Endp
- ;
-
- ChkKeyInRcd Proc Near
- Push CX
- Push SI
- Cmp FixedLen,0
- Jz CompStartCol
- Cmp KeyCount,1
- Jnz CompStartCol
- CmpElimNull: Cmp ElimNull,0
- Jz CompStartCol
- NullFix: Mov FixNotAllowMsg+2,'4'
- Mov FixNotAllowMsg+6,'N'
- Mov DX,Offset FixNotAllowMsg
- Call DisplayError
- CompStartCol: Cmp StartCol,0
- Jz ChkKeyInRcd2
- Dec StartCol ;Dec StartCol if not 0.
- ChkKeyInRcd2: Mov DX,FixedLen
- Or DX,DX
- Jnz ChkKeyInRcd3 ;Jmp if fixed len.
- Mov DX,32750
- ChkKeyInRcd3: Sub DX,StartCol ;DX = FixedLen or 32750 less StartCol.
- Lahf
- Cmp KeyLen,0
- Jnz ChkKeyInRcd4
- Test KeyTyp,KeyTurbo
- Jz ChkKeyInRcd3b
- Mov KeyLen,6
- Jmp Short ChkKeyInRcd4
- ChkKeyInRcd3B: Mov KeyLen,DX
- ChkKeyInRcd4: Sahf
- Ja SubKeyLen
- Mov DX,Offset BigStartMsg
- Call DispErrorParm
- Jmp Short ChkKeyInRcd5
- SubKeyLen: Sub DX,KeyLen
- Jae ChkKeyInRcd5 ;Rcd len must be >= KeyLen.
- Cmp FixedLen,0
- Jnz BigKeyLen
- Add KeyLen,DX ;If lines and big key len let keylen equal
- ;32750 - StartCol.
- Jmp Short ChkKeyInRcd5
- BigKeyLen: Mov DX,Offset BigKeyLenMsg
- Call DispErrorParm
- ChkKeyInRcd5: Test KeyTyp,KeyInteger+KeyUnsigned+KeyFloat+KeyMicro+KeyTurbo
- Jz CheckPascal
- Mov AX,Keylen
- Add AX,StartCol
- Dec AX
- Mov StartCol,AX
- And KeyTyp,0FFFFH XOR KeyASCII+KeyZero+KeyPascal
- Test KeyTyp,KeyMicro+KeyTurbo+KeyFloat
- Jz JmpCalcRelCol
- Test KeyTyp,KeyTurbo
- Jz Test4Or8
- Cmp KeyLen,6
- Jz CalcRelCol
- Mov DX,Offset NGTurboLenMsg
- Call DispErrorParm
- JmpCalcRelCol: Jmp Short CalcRelCol
- NGFloatLen: Mov DX,Offset NGFloatLenMsg
- Call DispErrorParm
- Jmp Short CalcRelCol
- NGMicroLen: Mov DX,Offset NGMicroLenMsg
- Call DispErrorParm
- Jmp Short CalcRelCol
- ;
- Test4Or8: Cmp KeyLen,4
- Jz CalcRelCol
- Cmp KeyLen,8
- Jz CalcRelCol
- Test KeyTyp,KeyMicro
- Jnz NGMicroLen
- Cmp KeyLen,10
- Jnz NGFloatLen
- Jmp Short CalcRelCol
- CheckPascal: Test KeyTyp,KeyPascal
- Jz CalcRelCol
- Cmp DefaultSortKey,0
- Jz ChkPascalLen
- Cmp FixedLen,0
- Jz CalcRelCol
- Cmp KeyLen,2
- Jb PascalLenNgDef
- Cmp KeyLen,256
- Jbe CalcRelCol
- PascalLenNGDef: Mov DX,Offset PascalDefNGMsg
- Call DisplayError
- Jmp Short CalcRelCol
- ChkPascalLen: Cmp KeyLen,2
- Jb PascalLenNG
- Cmp KeyLen,256
- Jbe CalcRelCol
- PascalLenNG: Mov DX,Offset PascalLenNGMsg
- Call DispErrorParm
- CalcRelCol: Mov DX,PrevEndCol
- Cmp FixedLen,0
- Jnz StoreRelCol
- Inc DX
- Inc DX
- StoreRelCol: Mov RelCol,DX
- Cmp GotError,0
- Jz StoreRelCol2
- Jmp ChkKeyRet
- StoreRelCol2: Mov DI,CodePointer
- Mov SI,CompMove
- Cmp Fixedlen,0
- Jz Line1
- Mov Fix1Start,DI
- Mov Line1Start,0
- Add SI,Offset Fix1Beg
- Test KeyTyp,KeyPascal
- Jnz DoPascal
- Mov CX,Offset Fix1End - Offset Fix1Beg
- Jmp Short MoveKeyLen
- DoPascal: Mov CX,Offset Pascal1End - Offset Fix1Beg
- Jmp Short MoveKeyLen
- Line1: Add SI,Offset Line1Beg
- Mov CX,Offset Line1End - Offset Line1Beg
- Mov Fix1Start,0
- Mov Line1Start,DI
- MoveKeyLen: Rep Movsb
- Test KeyTyp,KeyInteger+KeyUnsigned+KeyFloat+KeyMicro+KeyTurbo
- Jnz DoBinaryNumb
- Test KeyTyp,KeyASCII
- Jz JmpCaseInsen
- Test KeyTyp,KeyZero
- Jnz ASCIIZero
- Mov SI,Offset CollNZ1Beg
- Mov CX,Offset CollNZ1End - Offset CollNZ1Beg
- Jmp Short MoveASCIICode
- JmpCaseInsen: Jmp Short CaseInsen
- DoBinaryNumb: Test KeyTyp,KeyInteger
- Jz TestUnsigned
- Mov SI,Offset Integer1Beg
- Mov CX,Offset Integer1End - Offset Integer1Beg
- Jmp Short MoveBinNumb
- TestUnsigned: Test KeyTyp,KeyUnsigned
- Jz TestFloat
- Mov SI,Offset Unsigned1Beg
- Mov CX,Offset Unsigned1End - Offset Unsigned1Beg
- Jmp Short MoveBinNumb
- TestFloat: Test KeyTyp,KeyFloat
- Jz TestMicro
- Cmp KeyLen,10
- Jz DoTempReal
- Mov SI,Offset Float1Beg
- Mov CX,Offset Float1End - Offset Float1Beg
- Jmp Short MoveBinNumb
- DoTempReal: Mov SI,Offset TempReal1Beg
- Mov CX,Offset TempReal1End - Offset TempReal1Beg
- Jmp Short MoveBinNumb
- TestMicro: Test KeyTyp,KeyMicro
- Jz DoTurbo
- Mov SI,Offset Micro1Beg
- Mov CX,Offset Micro1End - Offset Micro1Beg
- Jmp Short MoveBinNumb
- DoTurbo: Mov SI,Offset Turbo1Beg
- Mov CX,Offset Turbo1End - Offset Turbo1Beg
- MoveBinNumb: Add SI,CompMove
- Rep Movsb
- Jmp Short All2
- ASCIIZero: Cmp FixedLen,0
- Jz LineASCIIZero
- Mov SI,Offset FixCollZ1Beg
- Mov CX,Offset FixCollZ1End - Offset FixCollZ1Beg
- Jmp Short MoveASCIICode
- LineASCIIZero: Mov SI,Offset LineCollZ1Beg
- Mov CX,Offset LineCollZ1End - Offset LineCollZ1Beg
- MoveASCIICode: Add SI,CompMove
- Rep Movsb
- Jmp Short All2
- CaseInsen: Test KeyTyp,KeyZero
- Jnz CaseZero
- Cmp FixedLen,0
- Jz LinesPascal1
- Test KeyTyp,KeyPascal
- Jz Case1
- LinesPascal1: Mov SI,Offset LinePasNZ1Beg
- Mov CX,Offset LinePasNZ2End - Offset LinePasNZ1Beg
- Jmp Short MoveCaseCode
- Case1: Mov SI,Offset CaseNZ1Beg
- Mov CX,Offset CaseNZ1End - Offset CaseNZ1Beg
- Jmp Short MoveCaseCode
- CaseZero: Cmp FixedLen,0
- Jz CaseZeroLines
- Mov SI,Offset FixCaseZ1Beg
- Mov CX,Offset FixCaseZ1End - Offset FixCaseZ1Beg
- Jmp Short MoveCaseCode
- CaseZeroLines: Mov SI,Offset LineCaseZ1Beg
- Mov CX,Offset LineCaseZ1End - Offset LineCaseZ1beg
- MoveCaseCode: Add SI,CompMove
- Rep Movsb
- All2: Mov SI,CompMove
- Add SI,Offset All2Beg
- Mov CX,Offset All2End - Offset All2Beg
- Rep Movsb
- Cmp FixedLen,0
- Jz LinesPascal3
- Test KeyTyp,KeyPascal
- Jz CheckMemory
- LinesPascal3: Mov SI,CompMove
- Add SI,Offset LinePascal3Beg
- Mov CX,Offset LinePascal3End - Offset LinePascal3Beg
- Rep Movsb
- CheckMemory: Mov CompFinish,DI
- Mov CodePointer,DI
- Cmp DI,ModelCodeLoc
- Jb Chk2nd
- Jmp NoMemory
- Chk2nd: Cmp SecondStart,0 ;Jump if not SecondStart.
- Jz DoAll1
- Mov AX,RelCol
- Mov DI,SecondStart
- Mov [DI+2],AX ;Store imm val for RelColumn.
- DoAll1: Mov DI,All1Start
- Mov AX,StartCol
- Mov [DI+1],AX
- Cmp Fix1Start,0
- Jz MustBeLines
- Mov DI,Fix1Start
- Mov AX,KeyLen
- Mov [DI+5],AX
- Test KeyTyp,KeyReverse
- Jz MovOrigCode
- Test KeyTyp,KeyPascal
- Jnz RevLinesPascal
- Mov DI,CompFinish
- Mov [DI-2],0C3F5H
- Jmp Short MovOrigCode
- MustBeLines: Mov DI,Line1Start
- Mov AX,StartCol
- Mov [DI + Offset GotShort - Offset Line1Beg + 3],AX
- Mov [DI + Offset ShortLen - Offset Line1Beg + 2],AX
- Mov [DI+Offset BothShort-Offset Line1Beg+1],AX
- Mov AX,KeyLen
- Mov [DI+Offset MovKeyLen-Offset Line1Beg+1],AX
- Mov AX,CompFinish
- Sub AX,DI
- Sub AX,Offset JmpOrigSeq - Offset Line1Beg + 2
- Mov [DI + Offset JmpOrigSeq - Offset Line1Beg + 1],AL
- Test KeyTyp,KeyReverse
- Jz MovOrigCode
- Mov [DI + Offset OnlyOneShort - Offset Line1Beg],0C3F5H
- RevLinesPascal: Mov DI,CompFinish
- Mov [DI - 4],0C3F5H
- Mov [DI - 11],0C3F5H
- MovOrigCode: Mov DI,CodePointer
- Mov OrigStart,DI
- Mov SI,Offset OrigBeg
- Mov CX,Offset OrigEnd - Offset OrigBeg
- Add SI,CompMove
- Rep Movsb
- Mov CodePointer,DI
- Cmp DI,ModelCodeLoc
- Jb ChkKeyRet
- Jmp JmpNoMem1
- ChkKeyRet: Pop SI
- Pop CX
- Ret
- ChkKeyInRcd Endp
-
- ;
- CdeSeg Ends
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
- End MainStart
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;If numeric and fixed add the following code.
- ;
- ;NumFix1Beg: Add SI,CX ;Point to Jth key.
- ; Add DI,CX ;Point to Ith key.
- ; Mov CX,KeyLength
- ; Push CX
- ;NumFix1End:
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;If numeric and lines add the following code.
- ;
- ;NumLine1Beg: Lodsw ;Length of Jth line.
- ; Add SI,CX ;Point to Jth key.
- ; Mov BX,ES:[DI] ;Length of Ith line.
- ; Inc DI
- ; Inc DI
- ; Add DI,CX ;Point to Ith key.
- ;
- ; Sub AX,CX ;Remaining len of Jth line.
- ; Ja NumLine1A
- ; Xor AX,AX
- ;NumLine1A: Sub BX,CX ;Remaining len of Ith line.
- ; Ja NumLine1B
- ; Xor BX,BX
- ;NumLine1B: Mov CX,KeyLength
- ; Cmp AX,CX
- ; Jbe NumLine1C
- ; Mov AX,CX ;Lesser of remain Jth len and keylen.
- ;NumLine1C: Cmp BX,CX
- ; Jbe NumLine1D
- ; Mov BX,CX ;Lesser of remain Ith len and keylen.
- ;NumLine1D: Mov CX,AX
- ; Push BX
- ;NumLine1End:
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;If numeric add the following. Must preserve SI, DI, DS, ES return CX = 0
- ;let RelCol be zero.
- ;
- ;Numeric1Beg: Push ES
- ; Push DI
- ; Mov AX,CS
- ; Mov ES,AX
- ; Mov DI,Offset JNumber
- ; Call ConvertNumb
- ; Pop SI
- ; Pop DS
- ; Pop CX
- ; Call ConvertNumb
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-