;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ ;Program: String Library ;Programmer: Anti Resonance ;Date: ??.??.???? ; ;A collection of string functions ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ;Revision History: ; ; 1.0 ??.??.???? ;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ .MODEL MEDIUM .386 LOCALS CODEMAIN SEGMENT PUBLIC "CODE" PAGE USE16 CODEMAIN ENDS DATAMAIN SEGMENT PUBLIC "DATA" PAGE USE16 DATAMAIN ENDS INCLUDE String.Inc INCLUDE Video.Inc ;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ DATAMAIN SEGMENT ;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ ;Equates ;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ ;Variables HexTable DB "0123456789ABCDEF" HexVal DB 0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0,0,10,11,12,13,14,15 DecBuf DB 30h,30h DB 14 DUP(0) DATAMAIN ENDS ;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ CODEMAIN SEGMENT ASSUME CS:CODEMAIN,DS:DATAMAIN ;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ ;Procedures ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ;Convert String to Uppercase ; ;Desc: ; Changes all alphas to uppercase characters ;In: ; SI-> ASCIIZ String ;Out: ; nothing ;Destroys: ; SI ALIGN 16 Str2Up PROC @@Next: Cmp Byte Ptr [SI],'a' JB Short @@Up Cmp Byte Ptr [SI],'z' JA Short @@Up And Byte Ptr [SI],Not 32 @@Up: Inc SI Test Byte Ptr [SI],-1 JNZ Short @@Next Ret Str2Up ENDP ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ;Print Number in Hexidecimal ; ;Desc: ; Prints a number on the screen in hexidecimal ;In: ; EDX/DX/DL = Number to convert ; ES:DI -> Location on screen ;Out: ; DI = Character after number ;Destroys: ; AL,(E)BX=0 ALIGN 16 D2Hex PROC Mov EBX,EDX ShR EBX,28 Cmp BL,0Ah JB Short @@No0 Mov Byte Ptr ES:[DI],'0' Add DI,2 @@No0: D2Hex ENDP D2HexA PROC Push CX XOr EBX,EBX Mov CL,8 @@Print: ShLD EBX,EDX,4 RoL EDX,4 Mov AL,HexTable[BX] Mov ES:[DI],AL Mov BL,0 Add DI,2 Dec CL JNZ Short @@Print Pop CX Ret D2HexA ENDP ALIGN 16 W2Hex PROC Mov BX,DX ShR BX,12 Cmp BL,0Ah JB Short @@No0 Mov Byte Ptr ES:[DI],'0' Add DI,2 @@No0: W2Hex ENDP W2HexA PROC Push CX XOr BX,BX Mov CL,4 @@Print: ShLD BX,DX,4 RoL DX,4 Mov AL,HexTable[BX] Mov ES:[DI],AL Mov BL,0 Add DI,2 Dec CL JNZ Short @@Print Pop CX Ret W2HexA ENDP ALIGN 16 B2Hex PROC Mov BL,DL ShR BL,4 Cmp BL,0Ah JB Short @@No0 Mov Byte Ptr ES:[DI],'0' Add DI,2 @@No0: B2Hex ENDP B2HexA PROC XOr BX,BX Mov BL,DL ShR BL,4 Mov AL,HexTable[BX] Mov ES:[DI],AL Add DI,2 Mov BL,DL And BL,0Fh Mov AL,HexTable[BX] Mov ES:[DI],AL Add DI,2 Mov BL,0 Ret B2HexA ENDP ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ;Print Number in Decimal ; ;Desc: ; Prints a number on the screen in decimal ; ; Name Number Bit Signed ; ÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄ ÄÄÄ ÄÄÄÄÄÄ ; L2Dec Long int 32 yes ; D2Dec Double 32 no ; I2Dec Integer 16 yes ; W2Dec Word 16 no ; S2Dec Short int 8 yes ; B2Dec Byte 8 no ; ;In: ; ES:DI -> Location on screen ; EAX/AX/AL = Number to convert ;Out: ; DI-> Character after number ;Destroys: ; 32-bit: ; EAX,EBX,EDX=0 ; 16-bit: ; AX,BX,DX=0 ; 8-bit: ; AX ALIGN 16 L2Dec PROC Test EAX,EAX ;Is number negative? JNS Short @@Plus ; No, Jump to no minus Neg EAX ;Make number positive Mov Byte Ptr ES:[DI],'-' ;Print a - Add DI,2 @@Plus: L2Dec ENDP D2Dec PROC Push CX Push DI Mov DI,Offset[DecBuf+2] ;Output to buffer XOr EDX,EDX ;Erase EDX Mov EBX,10 ;Base 10 Mov CX,300Ah @@Proc: ;Process number Div EBX ;Get next digit Mov [DI],DL ;Place in buffer Inc DI Mov DL,0 Dec CL JNZ Short @@Proc Jmp @PrintDec ;Jump to W2Dec D2Dec ENDP ALIGN 16 I2Dec PROC Test AX,AX JNS Short @@Plus Neg AX Mov Byte Ptr ES:[DI],'-' Add DI,2 @@Plus: I2Dec ENDP W2Dec PROC Push CX Push DI Mov DI,Offset[DecBuf+2] XOr DX,DX Mov BX,10 Mov CX,300Ah @@Proc: Div BX Mov [DI],DL Inc DI Mov DL,0 Dec CL JNZ Short @@Proc @PrintDec: Mov BX,DI ;BX-> first number Pop DI @@PrePrint: Dec BX ;Move to next digit Or AL,[BX] ;Is digit zero? JZ Short @@PrePrint ; Yes, Keep scanning Or AL,CH ;Convert to ASCII Mov AH,0 @@Print: Mov ES:[DI],AL ;Print character Dec BX ;Move to next digit Add DI,2 Mov AL,[BX] ;Get digit XOr AL,CH ;Convert to ASCII, is it an ASCII numeral? JNZ Short @@Print ; Yes, Print character Pop CX Ret W2Dec ENDP ALIGN 16 S2Dec PROC Test AL,AL JNS Short @@Plus Neg AL Mov Byte Ptr ES:[DI],'-' Add DI,2 @@Plus: S2Dec ENDP B2Dec PROC AAM 100 Test AH,AH JZ Short @@Not100 Or AH,30h Mov ES:[DI],AH Add DI,2 AAM Jmp Short @@Print10 @@Not100: AAM Test AH,AH JZ Short @@Not10 @@Print10: Or AH,30h Mov ES:[DI],AH Add DI,2 @@Not10: Or AL,30h Mov ES:[DI],AL Add DI,2 Ret B2Dec ENDP ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ;Read String Input from Keyboard ; ;Desc: ; Reads characters from the keyboard and stores them in a string or edits an existing string. ;In: ; Len = Maximum length of string ; SI -> ASCIIZ string (If reading a new string, the first character must be a 0) ; ES:DI-> Location of first character on screen ;Out: ; CX = Length ; If a string reaches the maximum length, a null is not added to the end ;Destroys: ; AX,BX,DX,SI,DI ALIGN 16 ReadStr PROC ARG Len:Word LOCAL Over:Byte ;Write current string to screen --------- Mov CX,Len Mov DX,Len @@Print: Mov AL,[SI] Or AL,AL JZ @@Null Mov ES:[DI],AL Inc SI Add DI,2 Dec DX JNZ Short @@Print @@Null: Sub CX,DX Mov BX,CX Mov AH,12h Int 16h Test AL,80h SetZ Over Call CurType,Word Ptr Over @@Repeat: Mov DX,DI ShR DX,1 Call CurPos,DX ;Update cursor position @@Wait: Hlt Mov AH,11h Int 16h JZ Short @@Wait Mov AH,10h ;Get keypress Int 16h Cmp AH,0 ;Is keypress an extended ASCII character? JE @@Char Cmp AL,0E0h ;Is keypress an extended key? JE @@Enh Cmp AL,0 ;Is keypress an enhanced key? JE @@Enh Cmp AL,8 ;Is keypress a backspace? JE @@Back Cmp AL,13 ;Is keypress enter? JE @@Done Cmp AL,9 ;Is keypress tab? JE @@Repeat Cmp AL,27 ;Is keypress escape? JE @@Done @@Char: Cmp BX,Len ;Is the cursor at the max end of the string? JE @@Repeat ; Yes, Can't add a character Cmp BX,CX ;Is the cursor at the end of the string? JE @@EndStr ; Yes, Str len will inc regardless of insert mode Test Over,1 ;Is insert mode enabled? JNZ @@Over ; No, It's in overwrite XOr DX,DX Cmp CX,Len ;Is the string at it's max length? SetE DL Sub CX,DX Mov DX,CX Sub DX,BX JZ @@EndStr Add SI,DX Add DI,DX Add DI,DX Push AX @@Insert: Dec SI Mov AL,[SI] Mov [1+SI],AL Mov ES:[DI],AL Sub DI,2 Dec DX JNZ Short @@Insert Pop AX @@EndStr: Inc CX @@Over: Mov [SI],AL ;Store character in string Mov ES:[DI],AL ;Print character on screen Inc SI ;Move to next character Add DI,2 Inc BX Jmp @@Repeat @@Enh: Cmp AH,47h JE @@Home Cmp AH,4Fh JE @@End Cmp AH,4Bh JE @@Left Cmp AH,4Dh JE @@Right Cmp AH,53h JE @@Del Cmp AH,52h JNE @@Repeat XOr Over,1 Call CurType,Word Ptr Over Jmp @@Repeat @@Del: Cmp BX,CX JE @@Repeat Push SI DI Jmp @@Remove @@Right: Cmp BX,CX JE @@Repeat Add DI,2 Inc SI Inc BX Jmp @@Repeat @@Left: Or BX,BX JZ @@Repeat Sub DI,2 Dec SI Dec BX Jmp @@Repeat @@Home: Sub DI,BX Sub DI,BX Sub SI,BX XOr BX,BX Jmp @@Repeat @@End: Mov DX,CX Sub DX,BX Add DI,DX Add DI,DX Add SI,DX Mov BX,CX Jmp @@Repeat @@Back: Or BX,BX JZ @@Repeat Mov DX,BX Dec BX Sub DI,2 Dec SI Push SI DI Cmp DX,CX JE @@DoneDel @@Remove: Mov DX,CX Sub DX,BX Dec DX JZ @@DoneDel @@Delete: Mov AL,[SI+1] Mov [SI],AL Mov ES:[DI],AL Inc SI Add DI,2 Dec DX JNZ Short @@Delete @@DoneDel: Mov Byte Ptr [SI],0 Mov Byte Ptr ES:[DI],0 Pop DI SI Dec CX Jmp @@Repeat @@Done: Cmp CX,Len JE @@NoNull Mov DX,CX Sub DX,BX Add SI,DX Mov Byte Ptr [SI],0 @@NoNull: Ret ReadStr ENDP ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ;Read Integer Input from Keyboard ALIGN 16 ReadInt PROC USES CX,EDX,EBX,DI,DS ARG Len:Word LOCAL Over:Byte Push EAX Call SetRPlane,0 Or ECX,ECX SetS CL ShL CL,1 Mov Over,CL Mov CX,DI Call L2Dec Sub CX,DI Neg CX ShR CX,1 Mov BX,CX Mov AX,0B800h Mov DS,AX Mov AH,12h Int 16h Test AL,80h SetZ AL Or Over,AL Call CurType,Word Ptr Over @@Repeat: Mov DX,DI ShR DX,1 Call CurPos,DX ;Update cursor position Mov AH,10h ;Get keypress Int 16h Cmp AH,0 ;Is keypress an extended ASCII character? JE @@Char Cmp AL,0E0h ;Is keypress an extended key? JE @@Enh Cmp AL,0 ;Is keypress an enhanced key? JE @@Enh Cmp AL,8 ;Is keypress a backspace? JE @@Back Cmp AL,13 ;Is keypress enter? JE @@Done Cmp AL,9 ;Is keypress tab? JE @@Repeat Cmp AL,27 ;Is keypress escape? JE @@NaN @@Char: Cmp BX,Len ;Is the cursor at the max end of the string? JE @@Repeat ; Yes, Can't add a character Cmp AL,'0' ;Is character less than 0? JB @@Repeat ; Yes, No good Cmp AL,'9' ;Is character a number? JBE Short @@NumChar ; Yes, Move on Test Over,2 ;Can the number be negative? JZ @@Repeat ; No, Go back Test BX,BX ;Are we in the first position? JNZ @@Repeat ; No, Go back Cmp AL,'-' ;Is the character a minus sign? JNE @@Repeat ; No, Go back @@NumChar: Cmp BX,CX ;Is the cursor at the end of the string? JE @@EndStr ; Yes, Str len will inc regardless of insert mode Test Over,1 ;Is insert mode enabled? JNZ @@Over ; No, It's in overwrite XOr DX,DX Cmp CX,Len ;Is the string at it's max length? SetE DL Sub CX,DX Mov DX,CX Sub DX,BX JZ @@EndStr Add DI,DX Add DI,DX Push AX @@Insert: Sub DI,2 Mov AL,[DI] Mov [2+DI],AL Dec DX JNZ Short @@Insert Pop AX @@EndStr: Inc CX @@Over: Mov [DI],AL ;Print character on screen Add DI,2 Inc BX Jmp @@Repeat @@Enh: Cmp AH,47h JE @@Home Cmp AH,4Fh JE @@End Cmp AH,4Bh JE @@Left Cmp AH,4Dh JE @@Right Cmp AH,53h JE @@Del Cmp AH,52h JNE @@Repeat XOr Over,1 Call CurType,Word Ptr Over Jmp @@Repeat @@Del: Cmp BX,CX JE @@Repeat Push DI Jmp @@Remove @@Right: Cmp BX,CX JE @@Repeat Add DI,2 Inc BX Jmp @@Repeat @@Left: Or BX,BX JZ @@Repeat Sub DI,2 Dec BX Jmp @@Repeat @@Home: Sub DI,BX Sub DI,BX XOr BX,BX Jmp @@Repeat @@End: Mov DX,CX Sub DX,BX Add DI,DX Add DI,DX Mov BX,CX Jmp @@Repeat @@Back: Or BX,BX JZ @@Repeat Mov DX,BX Dec BX Sub DI,2 Push DI Cmp DX,CX JE @@DoneDel @@Remove: Mov DX,CX Sub DX,BX Dec DX JZ @@DoneDel @@Delete: Mov AL,[DI+2] Mov [DI],AL Add DI,2 Dec DX JNZ Short @@Delete @@DoneDel: Mov Byte Ptr [DI],0 Pop DI Dec CX Jmp @@Repeat @@Done: XOr EAX,EAX Sub DI,BX Sub DI,BX XOr EDX,EDX Cmp Byte Ptr [DI],'-' SetE DL Sub CX,DX JZ @@NaN Mov Over,DL Add DI,DX Add DI,DX Mov EBX,10 @@Str2Num: IMul EAX,EBX Mov DL,[DI] Sub DL,30h Add DI,2 Add EAX,EDX Dec CL JNZ Short @@Str2Num Test Byte Ptr Over,1 JZ @@Quit Neg EAX @@Quit: Pop EDX ClC Ret @@NaN: Pop EAX StC Ret ReadInt ENDP ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ;Read Hexidecimal Input from Keyboard ; ;Desc: ; Reads an absolute hex value ;In: ; Len = Length of number (in digits) ; ES:DI-> Location of first character on screen ;Out: ; EAX = Number ; CF = User abort ;Destroys: ; Nothing ALIGN 16 ReadHex PROC USES DX,BX,DI,DS ARG Len:Word Mov AX,0B800h Mov DS,AX Call CurSt,1 Call CurType,0 XOr BX,BX @@Repeat: Mov DX,DI ShR DX,1 Call CurPos,DX ;Update cursor position Mov AH,10h ;Get keypress Int 16h Cmp AH,0 ;Is keypress an extended ASCII character? JE @@Char Cmp AL,0E0h ;Is keypress an extended key? JE @@Enh Cmp AL,0 ;Is keypress an enhanced key? JE @@Enh Cmp AL,13 ;Is keypress enter? JE @@Done Cmp AL,27 ;Is keypress escape? JE @@Abort @@Char: Cmp BX,Len ;Is the cursor at the max end of the string? JAE @@Repeat ; Yes, Can't add a character Cmp AL,32 JE @@Right Cmp AL,8 JE @@Left Cmp AL,'0' ;Is character less than 0? JB @@Repeat ; Yes, No good Cmp AL,'9' ;Is character a number? JBE Short @@NumChar ; Yes, Move on And AL,Not 32 Cmp AL,'A' JB @@Repeat Cmp AL,'F' JA @@Repeat @@NumChar: Mov [DI],AL ;Print character on screen Add DI,2 Inc BX Jmp @@Repeat @@Enh: Cmp AH,47h JE @@Home Cmp AH,4Fh JE @@End Cmp AH,4Bh JE @@Left Cmp AH,4Dh JE @@Right Jmp @@Repeat @@Right: Cmp BX,Len JE @@Repeat Add DI,2 Inc BX Jmp @@Repeat @@Left: Test BX,BX JZ @@Repeat Sub DI,2 Dec BX Jmp @@Repeat @@Home: Sub DI,BX Sub DI,BX XOr BX,BX Jmp @@Repeat @@End: Mov DX,Len Sub DX,BX Add DI,DX Add DI,DX Mov BX,Len Jmp @@Repeat @@Done: Mov AX,DATAMAIN Mov DS,AX Sub DI,BX Sub DI,BX XOr EDX,EDX Mov BX,Offset[HexVal] Mov AH,Byte Ptr Len @@Hex2Num: Mov AL,ES:[DI] Add DI,2 Sub AL,30h XLAT ShL EDX,4 Or DL,AL Dec AH JNZ Short @@Hex2Num Mov EAX,EDX Call CurSt,0 ClC Ret @@Abort: Call CurSt,0 StC Ret ReadHex ENDP CODEMAIN ENDS END