.MODEL small,pascal TITLE Resolver Source Control Aid PAGE 60,124 .286 Comment * Assembler Version Of OS/2 Revisor Hack Code. 00:09:55 18-Mar-1990 Frank V. Castellucci RR1 265 Overlook Way Purdys, NY 10578 ( 914 ) 277-4312 * Comment * 01:13:38 21-Mar-1990 Changes include fix to retrieve file size of alternate input as opposed to key input. This way the project name identifier will not be the input to the file data offset indicator. * Comment * 21:49:55 26-Mar-1990 Completed port to assembler. Additional capabilities include the DUMP and LIST switch. Have changed the construct of the TOKEN structure to include an alternate name and alternate flag. Although new this should still work with any older versions because the structure size did not change, just reduced the filename size and used the remainder to store an alternate name. * ;****************************************************************** ; Common Structures And Equates ;****************************************************************** ; General Usage MY_MESSGS EQU 0009h ; Number Of Text Messages INFO_MESSGS EQU 0003h ; Number Of Description Text Lines LISTINFO EQU 0001h ; Switch 'LIST' flag LISTALTI EQU 0100h ; Switch 'LIST ALTERNATE' flag LISTDATA EQU LISTINFO OR LISTALTI DUMPINFO EQU 0002h ; Switch 'DUMP' flag BADSWITCH EQU -1 ; Switch Unknown flag LISTCALL EQU 0000h ; Routine Flags DUMPCALL EQU 0001h ; For File Routines FILE_BEGIN EQU 0000h ; For Changing File pointers FILE_CURRENT EQU 0001h ; From current or unknown FILE_END EQU 0002h ; positions ; Directory handle types HDIR_SYSTEM EQU 0001h ; System File Find Handle HDIR_CREATE EQU -1 ; Flag to create your own ; Dosopen/DosQFHandState file attributes FILE_NORMAL EQU 0000h ; Flags for opening files as read FILE_READONLY EQU 0001h FILE_HIDDEN EQU 0002h FILE_SYSTEM EQU 0004h FILE_DIRECTORY EQU 0010h FILE_ARCHIVED EQU 0020h ; DosOpen() open flags FILE_OPEN EQU 0001h ; How to open the files FILE_TRUNCATE EQU 0002h FILE_CREATE EQU 0010h ; DosOpen() actions FILE_EXISTED EQU 0001h ; Return Actions By OS/2 FILE_CREATED EQU 0002h FILE_TRUNCATED EQU 0003h ; DosOpen/DosSetFHandState flags OPEN_ACCESS_READONLY EQU 0000h ; Access and sharing flags OPEN_ACCESS_WRITEONLY EQU 0001h OPEN_ACCESS_READWRITE EQU 0002h OPEN_SHARE_DENYREADWRITE EQU 0010h OPEN_SHARE_DENYWRITE EQU 0020h OPEN_SHARE_DENYREAD EQU 0030h OPEN_SHARE_DENYNONE EQU 0040h OPEN_FLAGS_NOINHERIT EQU 0080h OPEN_FLAGS_FAIL_ON_ERROR EQU 2000h OPEN_FLAGS_WRITE_THROUGH EQU 4000h OPEN_FLAGS_DASD EQU 8000h ; Flag Equate For Extracting Date and Time Values From Word Variable DDAY EQU 0000000000011111b DMON EQU 0000000111100000b DYRS EQU 1111111000000000b MONSHFT EQU 5 YRSHFT EQU MONSHFT + 4 TSEC EQU 0000000000011111b TMIN EQU 0000011111100000b THRS EQU 1111100000000000b MINSHFT EQU 5 HRSHFT EQU MINSHFT + 6 ; File time and date types for DosFindFirst FTIME struc ftime_fs dw ? FTIME ends FDATE struc fdate_fs dw ? FDATE ends ; Directory structure for DosFindFirst FILEFINDBUF struc findbuf_fdateCreation dw (size FDATE)/2 dup (?) findbuf_ftimeCreation dw (size FTIME)/2 dup (?) findbuf_fdateLastAccess dw (size FDATE)/2 dup (?) findbuf_ftimeLastAccess dw (size FTIME)/2 dup (?) findbuf_fdateLastWrite dw (size FDATE)/2 dup (?) findbuf_ftimeLastWrite dw (size FTIME)/2 dup (?) findbuf_cbFile dd ? findbuf_cbFileAlloc dd ? findbuf_attrFile dw ? findbuf_cchName db ? indbuf_achName db 13 dup (?) FILEFINDBUF ends REVTOKEN struc FileName db 32 DUP(?) AltFlag dw ? AltName db 94 DUP(?) DStamp dw (size FDATE)/2 dup (?) TStamp dw (size FTIME)/2 dup (?) Sig dd ? ByteDesc dd ? REVTOKEN ends SCREENREC struc KeyName db 'Key Name or Alternate Key Name ' db 5 DUP(20h) ; Used For Alternate Key As Well DateStmp db 'DateStmp' ; Date Stamp db 5 DUP(20h) ; Filler Space TimeStmp db 'TimeStmp' ; Time Stamp db 5 DUP(20h) ; Filler FSizeB db 'Size ' ; Size Of File db 5 DUP(20h) ; Filler Space SigNat db 4 DUP(20h) ; My Signature CrLf db 0dh,0ah ; EOL SCREENREC ends SCRNLINE EQU SIZE SCREENREC SCRNDATA EQU SIZE SCREENREC.CrLf - SCRNLINE ;****************************************************************** ; Macro For Easy Reading ;****************************************************************** ; @ArgvArgc prepares a call to the ArgvArgc function @ArgvArgc MACRO argS1,argO1,argO2 push argS1 push argO1 push argO2 call ArgvArgc ENDM ; @FStrMove prepares a call to the FStrMove function @FStrMove MACRO argS1,argO1,argS2,argO2 push argS1 push argO1 push argS2 push argO2 call FStrMove ENDM ; @VioWrtTTY prepares a call to the VioWrtTTY function @VioWrtTTY MACRO argS1,argO1,argLen,hvio push argS1 push argO1 push argLen push hvio call VioWrtTTY ENDM ; This macro clears the video buffer with blanks CLRBUFF MACRO argL1 push bx push cx mov bx,offset argL1 mov cx,SCRNDATA @@: mov BYTE PTR [bx],20h inc bx loop @B pop cx pop bx ENDM ; This multiplies Factor by Multiplier and puts result in Results ; also saves contents of the BX register CALCARRAYOFF MACRO Results,Factor,Multiplier push bx mov bx,offset Factor imul Results,[bx],size Multiplier pop bx ENDM ; This macro tests the character to see if it is in upper case, if not ; it converts it, if so it jumps to the closest local forward label UPPERCASE MACRO accumb cmp accumb,60h jl @F sub accumb,20h ENDM ; Extraction Macros For Screen Display XDAY MACRO argIn and argIn,DDAY ENDM XMON MACRO argIn and argIn,DMON shr argIn,MONSHFT ENDM XYRS MACRO argIn and argIn,DYRS shr argIn,YRSHFT add argIn,80 ENDM XSEC MACRO argIn and argIn,TSEC shl argIn,1 ENDM XMIN MACRO argIn and argIn,TMIN shr argIn,MINSHFT ENDM XHRS MACRO argIn and argIn,THRS shr argIn,HRSHFT ENDM ;****************************************************************** ; Simplified MASM Segments ; STACK is 4k ; DATA holds initialized and uninitialized variables ; CONST holds strings as they wont change through the app ;****************************************************************** .STACK 4096 .CONST Err0 db 'Invalid Parms: Usage = REVISOR Keyfile.ext Cat.rev Inp.ext',0dh,0ah Erl0 EQU $-Err0 Err1 db ' or KeyFile.ext , Inp.ext',0dh,0ah Erl1 EQU $-Err1 Err2 db ' or KeyFile.ext Cat.rev',0dh,0ah Erl2 EQU $-Err2 Err3 db ' or KeyFile.ext ',0dh,0ah Erl3 EQU $-Err3 Err4 db 'Invalid KeyFile Name',0dh,0ah Erl4 EQU $-Err4 Err5 db 'No Input File Found For Revision Storage',0dh,0ah Erl5 EQU $-Err5 Err6 db 'Switch Usage: REVISOR Keyfile.ext -L List Cat Key Info',0dh,0ah Erl6 EQU $-Err6 Err7 db ' or -D Cat.rev List All Keys Info',0dh,0ah Erl7 EQU $-Err7 Err8 db 'Catalog File Existense Error!',0dh,0ah Erl8 EQU $-Err8 .DATA CommandArgC dw ? ; Command Line Argument Count CommandArgv dw 16 DUP(?) ; OffSet To Command Line CommandSel dw ? ; Selector To Above Segment hdir dw ? hfCatalog dw ? ; File Handles hfAltInput dw ? Newlocation dd ? fFind FILEFINDBUF 3 DUP(<>) ; FileFindFirst Structure Array Header REVTOKEN <> ; Token Structure For Scans MainLine SCREENREC <> ; Screen Record Line SeprLine SCREENREC <"--------------------------------",,\ "--------",,"--------",,"-----",,,> AltLine SCREENREC <> ; Alternate Record Line DataBuff db 8192 DUP(?) ; Data Transfer Local Buffer InfoCount dw 0 ; File Find Counter InfoFlag dw 0 SwitchFlag dw 2 DUP(0) SwitchPos dw 0 ; Stringlength Arrays cbError dw Erl0,Erl1,Erl2,Erl3,Erl4,Erl5,Erl6,Erl7,Erl8 ; Array Of String Pointers pszErrs dw Err0,Err1,Err2,Err3,Err4,Err5,Err6,Err7,Err8 Token REVTOKEN <,0,,,,434a5646h,> ; Token Structure For General ; revisor.lst .CODE ; External Interfaces to OS/2 functions EXTRN VioWrtTTY:FAR,DosFindFirst:FAR,DosFindClose:FAR EXTRN DosChgFilePtr:FAR, DosOpen:FAR, DosRead:FAR, DosWrite:FAR EXTRN DosClose:FAR, DosExit:FAR Revisor PROC FAR mov CommandSel,ax ; Save Selector And Offset mov dx,offset CommandArgv ; Address Table Of Commands @ArgvArgc ax,bx,dx ; Parse Command Line NormalScanDone: mov dx,CommandArgC cmp dx,0000h ; Test Argument Counter jnz @F ; If we have any arguments mov cx,4 xor bx,bx jmp ErrorOut1 ; Otherwise Display And Exit ; @@: mov es,CommandSel ; Load Extra Segment mov cx,dx ; Get Parameter Count mov dx,0001 ; Now Our Index For Switch Work xor bx,bx ; Get Pointer Setup cmp cx,2 ; Switch Concern 1 and 2 position jng Nscn0 ; dec cx ; Only Test First 2 ; Nscn0: ; Normal Switch Text shl bx,1 ; Into Command Line mov di,CommandArgv[bx] call SpecialSwitch ; Test If Switch or ax,ax ; Compare Results jz @F ; No Switch mov SwitchPos,dx ; Save Argument Index mov SwitchFlag[bx],ax ; Save Value @@: inc dx ; Next Arg Flag Identifier inc bx ; Next ArgV loop Nscn0 ; Loop Normal Switch ; cmp SwitchPos,0 ; If No Switches jz DoGetCat ; Get Catalog Information cmp SwitchPos,2 ; Or if List Switch jnz @F ; Or forget it as we have alternative ; DoGetCat: or InfoFlag,1 ; First Check To See If Cat Exists push es ; And Also Convert Name In Process push CommandArgv[0] ; Check For First File call RevGetFileData ; Check Base Existense ; push es ; And Also Convert Name In Process push CommandArgv[0] call CheckCatalog or InfoFlag,ax ; Results Determine Alternate Usage ; @@: cmp SwitchPos,0 ; Check if normal ops again jz NoSwitchRoutine ; If So then continue verification jmp HaveSwitch ; Have A Switch NoSwitchRoutine: ; Otherwise Stuff Revision In Catalog cmp CommandArgC,0002h ; Do We Have Reason To Test Else? jl NoAltCat ; Nope Straight Talk mov di,CommandArgv[0002] ; Marked for default catalog usage cmp BYTE PTR es:[di],',' jz TestAltInpt ; Default Cat check Alternate Input xor InfoFlag,0002h ; Flip Flag Defualt Cat Off cmp InfoCount,1 ; Reuse FindFileStructure jle @F dec InfoCount ; Reuse FileFindStructure From Default @@: or InfoFlag,0004h ; Flag Alternate Used push es push di call RevGetFileData ; Check Alt Existense or ax,ax jz TestAltInpt or InfoFlag,0020h ; If Alt Not Exist then Create TestAltInpt: cmp CommandArgC,3 ; Alternate Input Source? jl NoAltCat ; If not then skip routine mov di,CommandArgv[0004] ; Alt Name Pointer Offset push es push di call RevGetFileData ; Check Alt Existense or ax,ax ; From Return Code jz @F ; If Exists mov cx,1 ; Flag Dependant File Error mov bx,5 shl bx,1 jmp ErrorOut1 @@: or InfoFlag,0008h ; Flag Alternate Input File mov Token.AltFlag,1 mov bx, offset Token.AltName @FStrMove es,di,ds,bx ; Make Call ; NoAltCat: mov bx,offset fFind ; Get Target File Size In Bytes cmp CommandArgC,3 ; See if we need alt input size jl @F ; If Not Take Key Data dec InfoCount ; Adjust for Zero Offset to counter CALCARRAYOFF ax,InfoCount, inc InfoCount ; Reset for possible reuse add bx,ax ; Add Offset To Alt Input Information @@: ; Provide information in token mov di,offset Token mov ax,WORD PTR [bx].findbuf_cbFile mov cx,WORD PTR [bx].findbuf_cbFile+2 mov WORD PTR [di].ByteDesc,ax mov WORD PTR [di].ByteDesc+2,cx mov ax,[bx].findbuf_fdateLastWrite mov cx,[bx].findbuf_ftimeLastWrite mov [di].DStamp,ax mov [di].TStamp,cx call AddChangeInfo jmp NormalOut HaveSwitch: mov bx,SwitchPos ; Where is switch dec bx shl bx,1 ; Offset Zero Into Results Array mov ax,SwitchFlag[bx] ; Load For Other Testing test ax,BADSWITCH ; Bad Switch jnz @F ; Good Switch BadSyntax: mov cx,2 ; Display Bad Switch Error mov bx,6 ; This Line shl bx,1 ; Word Offset jmp short ErrorOut1 ; Bad Switch Passed @@: mov bx,ax and bx,LISTDATA ; Test For Explicit List Command jnz @F jmp short tDump @@: mov cx,ax cmp CommandArgC,2 ; Better Be At In First Position jl BadSyntax ; If Not Then Flag Error cmp CommandArgC,3 ; Test For Alternate Rev Library jl @F xor InfoFlag,0002h dec InfoCount mov bx,4 ; OffSet To Third Argument mov bx,CommandArgv[bx] ; Get Alt Rev Arg push es ; Push Zero Terminated String push bx call RevGetFileData ; Check File Is Alive or ax,ax ; If Good Continue jz @F jmp short BadSyntax ; Else Error Correct @@: push cx call RevListKeyInfo ; Make Usefull Call jmp short SwitchDone ; Exit Application tDump: cmp ax,DUMPINFO ; Test For Implied Dump jz @F jmp BadSyntax ; Error Or New Switch Jump Goes Here @@: cmp CommandArgC,2 ; If DUMP ok then check parm count jz tDump1 ; For Cat Name exclusive jmp BadSyntax ; If No Catalog Specified ; Later hacks can use wild cards for ; all .REV extension listings tDump1: mov cx,ax mov bx,2 ; OffSet To Second Argument Cat Name mov bx,CommandArgv[bx] ; Get Alt Rev Arg push es ; Push Zero Terminated String push bx call RevGetFileData ; Check File Is Alive or ax,ax ; If Good Continue jz @F jmp BadSyntax ; Else Error Correct @@: push cx call RevDumpKeyInfo SwitchDone: jmp short NormalOut ErrorOut1: ; No Command Line Information @@: push ds ; Push Pointer To String push offset pszErrs[bx] push cbError[bx] ; Push String Length push 0000h ; Handle To Vio always 0 call VioWrtTTY add bx,2 ; Next Group loop @B mov ax,1 ; Return Code To OS/2 CMD = 1 NormalOut: ; Single Exit Point For Entire App push 1 ; End Entire Process push ax ; And Return Code call DosExit Revisor ENDP AddChangeInfo PROC NEAR USES ES DI SI mov dx,1 test InfoFlag,0002h ; Test If Default Cat Used jz UseAlt test InfoFlag,0010h ; Test If We Must Create It jz @F or dx,0002h ; If So Then Flag = 3 @@: mov ax,ds ; Get Local Default Name mov es,ax mov di,offset Token ; And FileName = Key Pointer jmp short OpenCat ; Open The Catalog UseAlt: test InfoFlag,0020h ; Test If Creation on Alt Required jz @F or dx,0002h ; Flag Creation Of File @@: mov es,CommandSel mov di,CommandArgv[0002] ; Pointer To Command Line Arg OpenCat: push dx ; Push Flag push es push di ; Pointer To File Name push ds push offset hfCatalog call DoOpenFile ; Call Routine or ax,ax ; Open Error? jnz BadOpen mov es,CommandSel ; Point To Command Line mov di,CommandArgv[0000] ; First Argument Assumption mov bx,offset Token KeyMove: mov al,BYTE PTR es:[di] ; Move File Name Into Token cmp al,00h jz @F mov BYTE PTR [bx],al inc bx inc di jmp short KeyMove @@: mov BYTE PTR [bx],al mov di,CommandArgv[0000] ; Find Alt or Current Input mov dx,0005h push dx push es cmp CommandArgC,3 jl @F mov di,CommandArgv[0004] @@: push di push ds push offset hfAltInput call DoOpenFile ; Open File For Input or ax,ax jnz BadOpen push hfCatalog push hfAltInput call MoveRevision ; Move The Data Into Repository xor ax,ax BadOpen: ret AddChangeInfo ENDP MoveRevision PROC USES SI DI,hfileD:WORD, hfileS:WORD push hfileD push ds push offset Token push size REVTOKEN call DoWriteData MoveData: push hfileS ; Push Source File Handle push ds mov bx,offset DataBuff ; Pointer To Data Buffer push bx push 8192 ; Size Of Buffer To Fill call DoReadData ; Read The Data or ax,ax ; Any Data Left jz Done ; Nope, all done with transfer push hfileD ; Push Repository Handle push ds mov bx,offset DataBuff ; Pointer To Data Buffer push bx push ax ; Data Size Returned From Read call DoWriteData ; Commit Data to disk jmp short MoveData ; Loop Up to Top Done: ret MoveRevision ENDP CheckCatalog PROC NEAR USES ES DI SI,pszArg:FAR PTR les di,pszArg ; Load Key Pointer Ucase: ; Make Upper Case cmp BYTE PTR es:[di],00h jz EOL UPPERCASE @@: inc di jmp short Ucase EOL: les di,pszArg ; Reload Pointer mov bx,offset Token ; Address Structure xor si,si @@: mov al,BYTE PTR es:[di] ; Transfer Base Key Or FileName cmp al,'.' jz @F mov BYTE PTR [bx][si],al inc di inc si jmp short @B @@: mov BYTE PTR [bx][si],al ; Append Default Catalog Extension inc si mov BYTE PTR [bx][si],'R' inc si mov BYTE PTR [bx][si],'E' inc si mov BYTE PTR [bx][si],'V' inc si mov BYTE PTR [bx][si],00h push ds ; Check For Catalog Exist push bx call RevGetFileData or ax,ax ; Create Neccessary jz Done dec InfoCount or InfoFlag,0010h mov ax,0002h Done: or ax,0002h Done1: ret CheckCatalog ENDP RevDumpKeyInfo PROC NEAR USES DS SI DI, SpecFlag:WORD push 0005h ; We Open The Catalog push CommandSel push CommandArgv[0002] ; With The Name On Command Line push ds push offset hfCatalog call DoOpenFile ; Open File or ax,ax ; If all is well then call list routine jnz DumpError push hfCatalog ; Handle To Cat push SpecFlag ; Type Call call RevPostInfo ; Here is where we show what we got push hfCatalog ; On return we close catalog handle call DosClose xor ax,ax ; Return Success Code DumpError: ret RevDumpKeyInfo ENDP RevListKeyInfo PROC NEAR SpecFlag:WORD push 0005h ; We Open The Catalog cmp CommandArgC,3 jnz @F push CommandSel push CommandArgv[0004] ; Get Alt Rev Arg jmp short OpenCat1 @@: push ds push offset Token ; Or Get Default Based On Key Name OpenCat1: push ds lea ax,hfCatalog push ax call DoOpenFile ; Open File or ax,ax ; If all is well then call list routine jnz ListError push hfCatalog ; Handle To Cat push SpecFlag ; Type Call call RevPostInfo ; Here is where we show what we got push hfCatalog ; On return we close catalog handle call DosClose xor ax,ax ; Return Success Code ListError: ret RevListKeyInfo ENDP RevPostInfo PROC NEAR \ USES ES DI SI, hcatFile:WORD,KeyScan:WORD mov bx,offset AltLine ; Point To Data Line CLRBUFF AltLine ; Clear Buffer For Screen @VioWrtTTY ds,bx,SCRNLINE,0 ; Call The Big Guy For Blank Line mov bx,offset MainLine ; Point To Data Line @VioWrtTTY ds,bx,SCRNLINE,0 ; Call The Big Guy For Topic Headers mov bx,offset SeprLine ; And a dashed seperator line @VioWrtTTY ds,bx,SCRNLINE,0 ; Call The Big Guy For Dashed Line Top0: push hcatFile ; Push Handle To Catalog and push ds ; Use the Header Structure as a push offset Header ; Buffer To return the header info push size REVTOKEN ; To test for keyname matches call DoReadData or ax,ax ; Test for EOF jnz @F ; Have Data jmp short RevOut ; All Done @@: test KeyScan,2 jnz ShowInfo ; If KeyScan 1 then this is dump info mov bx,offset Header.FileName ; Compare Value Here With Keyname push bx ; Entered At Command Line call RevC_and_D or ax,ax ; 0 if match or n for no match jz short ShowInfo ; Also n=character after no match cmp [bx].AltFlag,0000h ; If No Alternate Found jz @F ; Skip Routine lea bx,[bx].AltName ; Otherwise Load AltName For Comp push bx call RevC_and_D ; Compare And Display or ax,ax ; 0 if match or n for no match jnz @F ShowInfo: push ds push offset Header push KeyScan call RevDisplayKey ; Display Routine @@: push hcatFile ; Reset File Pointer To After Data mov ax,WORD PTR Header.ByteDesc+2 push ax ; In this variable which is the size mov ax,WORD PTR Header.ByteDesc push ax ; Of the data when entered into the push FILE_CURRENT ; catalog. Also if compression is ever push ds ; implimented this will represent the push offset Newlocation ; Size of the compressed data. call DosChgFilePtr ; Change file position and read more jmp Top0 RevOut: ret RevPostInfo ENDP RevDisplayKey PROC NEAR \ USES ES DI SI, pTok:FAR PTR, KeyFlag:WORD mov bx,offset MainLine ; Point To Data Line CLRBUFF MainLine ; Clear Buffer For Screen @VioWrtTTY ds,bx,SCRNLINE,0 ; Call The Big Guy For Blank Line les di,pTok ; Point To Data Structure @FStrMove es,di,ds,bx ; Get Key Name xor dx,dx RevD0: mov dx,bx mov si,bx @@: cmp BYTE PTR [si],00h ; Strip Zero Terminate jz @F inc si jmp short @B @@: mov BYTE PTR [si],20h ; Replace With Blank cmp es:[di].AltFlag,0000h ; Check For Key Value jz @F ; If Not Show Data jmp ShowLine ; Otherwise Just Show Key @@: mov ax,es:[di].DStamp ; Get Date lea bx,[bx].DateStmp ; Address Screen Date Pointer mov cx,ax ; Copy Original XMON ax ; Extract Month of Year push ax push 2 push bx call ConvertWrdToAscii ; Change to ASCII add bx,ax ; Add Difference From Starting mov BYTE PTR [bx],'/' ; Put In Seperator inc bx ; Point To Next Location mov ax,cx ; Copy Original XDAY ax ; Extract Day Of Month push ax push 2 push bx call ConvertWrdToAscii ; Change to ASCII add bx,ax mov BYTE PTR [bx],'/' inc bx XYRS cx ; Extract Year From Original push cx push 2 push bx call ConvertWrdToAscii mov bx,dx ; Restore Structure Pointer mov ax,es:[di].TStamp ; Get Time Stamp From Element lea bx,[bx].TimeStmp ; Address Screen Time Pointer mov cx,ax ; Copy Original XHRS ax ; Extract Hour File Changed push ax push 2 push bx call ConvertWrdToAscii ; Change to ASCII add bx,ax mov BYTE PTR [bx],':' ; Delimit inc bx ; Next Location mov ax,cx ; Restore Original XMIN ax ; Extract Minute Of Hour push ax push 2 push bx call ConvertWrdToAscii ; Change to ASCII add bx,ax mov BYTE PTR [bx],':' ; Delimit inc bx XSEC cx ; Pull TwoSecs Variable push cx push 2 push bx call ConvertWrdToAscii ; Change to ASCII mov bx,dx ; Restore Structure Pointer mov ax,WORD PTR es:[di].ByteDesc lea dx,[bx].FSizeB ; Get File Size Word push ax push 5 push dx call ConvertWrdToAscii ; Change To ASCII ShowLine: @VioWrtTTY ds,bx,SCRNLINE,0 ; Call The Big Guy cmp es:[di].AltFlag,0000h jz RevDone mov es:[di].AltFlag,0000h CLRBUFF AltLine ; Clear Buffer For Screen mov bx,offset AltLine push di lea di,es:[di].AltName @FStrMove es,di,ds,bx ; Get Key Name pop di jmp RevD0 RevDone: ret RevDisplayKey ENDP ConvertWrdToAscii PROC NEAR \ USES SI CX BX DX, Value:WORD,Cnt:WORD,Area:WORD mov cx,Cnt ; Load The Conversion Factor mov si,Area ; And Destination Buffer add si,cx ; Start At End Of Buffer dec si ; Pointer Zero Offset mov ax,Value ; Get The Data Value mov bx,000ah ; Set Up Divisor @@: xor dx,dx ; Clear Remainder Register div bx ; 16 Bit Divide add dx,30h ; Convert Remainder To ASCII mov BYTE PTR [si],dl ; Store In Data Buffer dec si ; Point to next location loop @B ; All Numbers mov ax,Cnt ; Return Offset ret ConvertWrdToAscii ENDP RevC_and_D PROC NEAR \ USES ES DI SI BX,pFileName:WORD mov bx,offset CommandArgv ; Get String Length mov cx,[bx+2] ; By Taking Second Args Address sub cx,[bx] ; And Subtracting First For Difference mov es,CommandSel ; Address Source mov ax,[bx] mov di,ax mov si,pFileName ; And Destination Assuming DS is local cld repe cmpsb ; Compare The Strings mov ax,cx ; Which BURNS the C version ret RevC_and_D ENDP DoWriteData PROC NEAR USES ES DI SI,hfile:WORD, pBuf:FAR PTR,SzBuf:WORD LOCAL cbByR:WORD mov ax,hfile ; Handle to file mov cx,SzBuf ; Size Of Data Buffer les di,pBuf ; Pointer To Buffer push ax ; Push Handle push es ; Pointer To Buffer push di push cx ; Byte Count To Write From Buffer push ss lea ax,cbByR ; Push Local Pointer To Count push ax ; Of bytes actually written call DosWrite ret DoWriteData ENDP DoReadData PROC NEAR \ USES ES DI SI, hfile:WORD, pBuf:FAR PTR,SzBuf:WORD LOCAL cbByR:WORD les di,pBuf ; Pointer To File Buffer lea si,cbByR ; Push Bytes Read As Returned by OS/2 push hfile ; File Handle is pushed push es ; And Buffer Pointer push di push SzBuf ; How many bytes to read push ss push si call DosRead ; Call The Big Guy mov ax,cbByR ret DoReadData ENDP DoOpenFile PROC NEAR \ USES ES DI SI,OpFlag:WORD,pFileName:FAR PTR,pFileHand:FAR PTR LOCAL Action:WORD,ulFileSize:DWORD les di,pFileName ; Load And Push File Name Pointer push es push di les di,pFileHand ; Load And Push File Handle Pointer push es push di push ss ; Push Pointer To Results Word lea ax,Action push ax push 0 ; Push Long Zero Length File Size push 0 mov ax,FILE_NORMAL ; Assume Normal File cmp OpFlag,5 jnz @F mov ax,FILE_READONLY ; Or Only Read From File @@: push ax mov ax,FILE_OPEN ; Assume Normal Open cmp OpFlag,3 jnz @F mov ax,FILE_CREATE ; Or Else Create New File @@: push ax mov ax,OPEN_ACCESS_READWRITE ; Assume We Want To Read Or Write cmp OpFlag,5 jnz @F mov ax,OPEN_ACCESS_READONLY ; Or Else We Want To Read Only @@: or ax,OPEN_SHARE_DENYWRITE ; Combine With Other Process Flag push ax push 0 ; OS/2 Reserved Long Value push 0 ; Must Be 0 call DosOpen ; Call The Big Guy or ax,ax ; Test Results jnz Done ; Exit If Error cmp OpFlag,1 ; Test Position For Writing jnz Done ; So We can Add A New Revision les di,pFileHand mov ax,WORD PTR es:[di] ; Get And Push File Handle push ax push 0 push 0 push FILE_END ; Position At End Of File push ds push offset Newlocation call DosChgFilePtr ; Call The Big Guy xor ax,ax ; Resume File Open Done: ret DoOpenFile ENDP SpecialSwitch PROC NEAR USES BX mov bl,BYTE PTR es:[di] ; Test For Switch Flags as defined cmp bl,'/' ; Here jz @F cmp bl,'-' ; or here jz @F xor ax,ax ; Assume NO FLAG AT ALL jmp short Done @@: inc di ; Convert To Uppercase to reduce mov bl,BYTE PTR es:[di] ; number of tests needed UPPERCASE bl @@: cmp bl,'D' ; Test For Dump Info Flag jnz @F mov ax,DUMPINFO jmp short Done @@: mov ax,LISTINFO ; Assume List Flag cmp bl,'L' jnz BadS ; BadSwitch Or Next New Switch inc di ; Switch good check for options mov bl,BYTE PTR es:[di] ; such as alternate key listing cmp bl,00h ; If no flag then end of line jz Done UPPERCASE bl @@: cmp bl,'A' ; Test For Alternate List jnz Done or ax,LISTALTI ; Set Flag For Alternate Listing jmp short Done BadS: mov ax,BADSWITCH ; Otherwise add more test or return Done: ; Bad Flag Info ret SpecialSwitch endp RevGetFileData PROC NEAR USES ES DI,pszFile:FAR PTR LOCAL usSrchCount:WORD mov usSrchCount,1 ; Single File Search mov hdir,HDIR_CREATE ; New Directory Search Handle les di,pszFile ; Pointer To String push es ; Push Pointer To String push di push ds ; Push Far Pointer To push offset hdir ; Directory Search Handle push FILE_NORMAL ; Push Attribute Search Condition CALCARRAYOFF ax,InfoCount, mov bx,ax ; Get Results lea ax,fFind[bx] ; Get Address To File Buffer push ds ; Push Far Pointer push ax ; To Current FileFindBuffer push size FILEFINDBUF ; Push Buffer Size lea ax,usSrchCount push ss ; Push Far Pointer push ax ; To Search Results push 0 ; 0L Reserved by OS/2 push 0 call DosFindFirst ; Call OS/2 mov usSrchCount,ax ; Save Results or ax,ax jnz @F ; If Bad Then So Is Handle push hdir ; Push Returned Handle call DosFindClose ; Call OS/2 @@: inc InfoCount ; For Further Array Processing mov ax,usSrchCount ; Return Results From Search ret RevGetFileData ENDP ArgvArgc PROC NEAR USES ES DI,pArgStr:FAR PTR BYTE,pArgTab:WORD les di,pArgStr ; Load Command Line mov bx,pArgTab mov CommandArgC,0 ScanCommand: ; Scan Command Line From Call cmp BYTE PTR es:[di],20h ; Parse The File Name Info jle @F ; Found A String Or End Of File inc di ; Next Character jmp short ScanCommand ; Next Test @@: cmp WORD PTR es:[di],0000 ; Test End Of Command Line jz ScanDone ; End Of Command Line cmp BYTE PTR es:[di+1],20h ; Test End Of Command Line jnz RemoveBlanks inc di RemoveBlanks: ; First Remove Blanks cmp BYTE PTR es:[di],20h jnz @F mov BYTE PTR es:[di],00h ; Fill With Zero Terminates inc di jmp short RemoveBlanks @@: cmp BYTE PTR es:[di],00h ; Make Sure We Are On Letter jg @F inc di @@: mov ax,di ; Store In Pointer Table mov [bx],ax ; The Entire Execution inc CommandArgC ; Up The Argc Value add bx,2 ; Get Next Pointer Offset inc di ; Next Character jmp short ScanCommand ; Continue Search ScanDone: ret ArgvArgc ENDP FStrMove PROC NEAR USES ES DI DS DX SI,pSrc:FAR PTR, pDest:FAR PTR mov cx,0ffffh ; Load Infinite Loop les di,pSrc ; Point To Source Zero Terminated String mov dx,di ; Copy Start Value xor ax,ax ; Search for Zero repne scasb ; Rep While String NE 0 sub di,dx ; Get String Length mov cx,di ; Save In Next counter mov dx,di ; Save For Upper Case Conversion les di,pDest ; ES DI points to destination lds si,pSrc ; DS SI points to Source rep movsb ; Move Bytes lds si,pDest ; Reload For Near Pointer Access mov cx,dx ; Get count again of string Fs1: UPPERCASE ; Convert To Upper Case @@: inc si loop Fs1 ret ; Exit With String Intact FStrMove ENDP END Revisor