home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1992 June
/
SIMTEL_0692.cdr
/
msdos
/
deskaces
/
conv.arc
/
CONV.ASM
< prev
next >
Wrap
Assembly Source File
|
1989-01-16
|
56KB
|
1,529 lines
page 60,132
;
;*****************************************************************************
; This resident program performs few tasks: *
; 1. Full ascii table splitted into two parts: 0-7Fh and 80H-0FFh. *
; 2. converts numbers between bases . The bases allowed are Binary, Octal, *
; Decimal, Hexadecimal . Data is entered in base Postfix, i.e. B,O,D,H . *
; For example 3F5Dh means it is an Hex number . *
; 3. Scan Code printing. *
; 4. Simple unsigned calculator of +,-,*,/ integer operations. *
; *
; Hot key of this program is defined to be ALT-A. modification is simple - *
; simply change the scan code at offset 103h, just after the jump at 100, to *
; your choice. You may want to change the prolog message as well. *
; Windows positions may be set via the 2 (x,y) pair, immediatelly after *
; the scan code at 103/104h location. First 2 bytes are the ascii table *
; (x,y) pair, follows by the base conversion pair, math window, scan code *
; window, and finally the main selection window pair. *
; Support of AT enhanced keyboard is added (see BiosGetCh below) *
; Redefinition of Hot key can be defined at source level using HotKet def. *
; *
; Elber Gershon 1988 *
;*****************************************************************************
;
title Number Conversions E.G. 1987
;
Null equ 00
Soh equ 01
Bell equ 07
Bs equ 08
Lf equ 10
Cr equ 13
Escape equ 27
Space equ 32
;
Quit equ 00h ;Dos func call - Quit.
DosGetLn equ 0Ah ;Dos func call - Get Line
DosPutLn equ 09h ;Dos func call - Put Line
BiosLocate equ 02h ;Bios func call - Locate Cursor
BiosGetLoc equ 03h ;Bios func call - Get location
BiosPutCh equ 09h ;Bios func call - Put Char (Int 010h)
BiosGetMode equ 0fh ;Bios func call - Get mode/page/width
;
IFDEF IS_AT_TYPE
;The following will work only in AT type machines with enhanced keyboard only:
BiosGetCh equ 010h ;Bios func call - Get Char (Int 016h)
;
ELSE
;And the following if XT type machines with no enhanced keyboard:
BiosGetCh equ 000h ;Bios func call - Get Char (Int 016h)
;
ENDIF
;
HotKey equ 01E00h ;Keyboard scan code for Alt - A
;
NormalAttr equ 007h ;Screen Attribute - normal
InversAttr equ 070h ;Screen Attribute - inverse
;
BiosDs equ 00040h ;Bios Data segment
ScreenMode equ 00049h ;Screen mode offset within Bios DS
CGAAddress equ 0B800h ;ColorGraphic Adaptor Base
MonoAddress equ 0B000h ;Mono Color Base
ScreenSize equ 01000h ;Screen Buffer Size
;
;*****************************************************************************
;* Begining of Code : *
;*****************************************************************************
code segment para public 'code'
assume cs:code,ds:code
;
org 0100h
;
starter: jmp install ;install the resident & parameters
;
ScanCode dw HotKey ;Hot Key scan code
;
WindowLeftA db 03 ;Window left position - Ascii Table
WindowTopA db 03 ;Window Top position
WindowLeftC db 20 ;Window left position - Conversion
WindowTopC db 05 ;Window Top position
WindowLeftM db 35 ;Window left position - Math
WindowTopM db 07 ;Window Top position
WindowLeftS db 40 ;Window left position - Scan Code
WindowTopS db 12 ;Window Top position
WindowLeftN db 25 ;Window left position - Main
WindowTopN db 08 ;Window Top position
;
;*****************************************************************************
;procedure KbdHandler *
;procedure to get control of int 16 and test for Hot key appearance . *
;In case of positive detection - Open the main window and... *
;*****************************************************************************
KbdHandler proc far
sti
or ah,ah ;Read Extended Ascii code ?
jne KbdHnd9 ;/
;
pushf ;Old keyboard rtn returns with IRET
call cs:OldKbdHandler ;/
;
pushf
;
cmp ax,cs:ScanCode ;Code we are searching for ?
jne KbdHnd8 ;/
call DoMain ;Call the resident part
;
KbdHnd8: popf
iret
;
KbdHnd9: jmp cs:OldKbdHandler ;No - continue as before installation
KbdHandler endp
;
;*****************************************************************************
;procedure DoMain *
;procedure to Open main window and ask for required operation to perform: *
;*****************************************************************************
DoMain proc near
push bp ;save all the used registers
push di
push si
push es
push ds
push dx
push cx
push bx
push ax
;
mov bx,cs ;get back DS segment
mov ds,bx ;/
;
test byte ptr [ResActive],0ffh ;Already active ?
je short DoMain0
jmp DoMain99
DoMain0: not byte ptr [ResActive] ;Set Buzy flag On
;
mov byte ptr [WindowKind],'N';Main window is active
call PushOldScreen ;Save Old Screen and cursor position
mov dx,00202h ;Print the different options:
call GotoXY ; |
mov dx, offset HeaderN1 ; |
call WriteLn ; |
mov dx,00302h ; |
call GotoXY ; |
mov dx, offset HeaderN2 ; |
call WriteLn ; |
mov dx,00402h ; |
call GotoXY ; |
mov dx, offset HeaderN3 ; |
call WriteLn ; |
mov dx,00502h ; |
call GotoXY ; |
mov dx, offset HeaderN4 ; |
call WriteLn ; |
mov dx,0070Ch ; |
call GotoXY ; |
mov dx, offset HeaderN9 ; |
call WriteLn ;/
;
DoMain1: mov dx,00713h ;Wait for entry
call GotoXY ; |
call ReadCh ;/
cmp al,'1' ;If it is Ascii Table
jne short DoMain2 ;/
call PopOldScreen ;Restore screen
call DoAscii ;/
jmp short DoMain98
DoMain2: cmp al,'2' ;If it is Conv.
jne short DoMain3 ;/
call PopOldScreen ;Restore screen
call DoConversion ;/
jmp short DoMain98
DoMain3: cmp al,'3' ;If it is Math
jne short DoMain4 ;/
call PopOldScreen ;Restore screen
call DoMath ;/
jmp short DoMain98
DoMain4: cmp al,'4' ;If it is Scan Code
jne short DoMain5 ;/
call PopOldScreen ;Restore screen
call DoScanCode ;/
jmp short DoMain98
DoMain5:
call PopOldScreen ;Restore screen
;
DoMain98:
not byte ptr [ResActive] ;Set Buzy flag Off again
;
DoMain99:
pop ax ;restore all the used registers
pop bx
pop cx
pop dx
pop ds
pop es
pop si
pop di
pop bp
ret
DoMain endp
;
;*****************************************************************************
;procedure DoAscii *
;procedure to Print the full ascii table : *
;*****************************************************************************
DoAscii proc near
push bp ;save all the used registers
push di
push si
push es
push ds
push dx
push cx
push bx
push ax
;
mov byte ptr [WindowKind],'A';Draw Ascii Table window
call PushOldScreen ;Save Old Screen and cursor position
;
DoAsc0: mov dx,00101h ;Start with window X=1 , Y=1
mov al,[CurrentChar] ;Get current character to print
DoAsc1: call GotoXY ;GotoXY new position
call PrintAsc ;Print al in dec. hex. and ascii
inc al ;Advance to next character
inc dh ;advance Y
cmp dh,17 ;Bottom of Table ?
jb short DoAsc1 ;/
mov dh,001 ;return to window top line
add dl,009 ;Skip to next column
cmp dl,1+9*8 ;over the last column (8th) ?
jb short DoAsc1 ;/
;
DoAsc2: call ReadCh ;Wait for entry
cmp al,' ' ;If it is SP then Print second table
jne short DoAsc3 ;/
add byte ptr [CurrentChar],080h ;Swap hi <> lo ascii
jmp short DoAsc0 ;And print other half
;
DoAsc3: cmp al,Escape ;If Escape then exit
jne short DoAsc2
;
DoAsc9: call PopOldScreen ;Restore Old Screen and cursor position
;
pop ax ;restore all the used registers
pop bx
pop cx
pop dx
pop ds
pop es
pop si
pop di
pop bp
ret
DoAscii endp
;
;*****************************************************************************
;procedure DoConversion *
;procedure to handle the base number conversions : *
;*****************************************************************************
DoConversion proc near
push bp ;save all the used registers
push di
push si
push es
push ds
push dx
push cx
push bx
push ax
;
DoConv0: mov byte ptr [WindowKind],'C' ;Draw Conversion window
call PushOldScreen ;Save Old Screen and cursor position
;
mov dx,00101h ;GotoXY 1,1 relative to window
call GotoXY ;/
mov dx,offset HeaderC1 ;Print the header
call WriteLn ;/
mov dx,00102h ;GotoXY 1,2 relative to window
call GotoXY ;/
mov dx,offset HeaderC2 ;Print the header
call WriteLn ;/
DoConv1: mov dx,00401h ;GotoXY 1,4 relative to window
call GotoXY ;/
mov cx,WindowWidthC ;Clear the line
call PrintSpc ;/
;
mov dx,00403h ;GotoXY 3,4 relative to window
call GotoXY ;/
mov dx,offset EnterData ;Ask for entry
call WriteLn ;/
;
mov dx,offset ReadBuf ;Read the user entry
mov ax,17 ; / 17 bytes to read at the most
call ReadLn ;/
or ax,ax ;No data entered ?
je DoConv9 ;/ Exit - close
;
mov bx,ax ;Find the last char - base
add bx,dx ; /
dec bx ; / (Last char on '$' - EOS)
mov al,[bx] ;/
mov byte ptr [bx],'$' ;and put end of string instead
and al,0dfh ;Make sure its upper case
cmp al,'B' ;Base 2 ?
jne short DoConv2 ;/
mov al,02
jmp short DoConv6
;
DoConv2: cmp al,'O' ;Base 8 ?
jne short DoConv3 ;/
mov al,08
jmp short DoConv6
;
DoConv3: cmp al,'T' ;Base 10 ?
jne short DoConv4 ;/
mov al,10
jmp short DoConv6
;
DoConv4: cmp al,'H' ;Base 16 ?
jne DoConv1 ;/
mov al,16
jmp short DoConv6
;
DoConv6: call Str2Int ;Convert it to integer
or bx,bx ;Test if error in conversion
jne Short DoConv1 ;/
;
call PrintNumBases ;Print the integer in various bases
;
jmp DoConv1
;
DoConv9: call PopOldScreen ;Restore Old Screen and cursor position
;
pop ax ;restore all the used registers
pop bx
pop cx
pop dx
pop ds
pop es
pop si
pop di
pop bp
ret
DoConversion endp
;
;*****************************************************************************
;procedure DoMath *
;procedure to handle the simple 4 operators math : *
;*****************************************************************************
DoMath proc near
push bp ;save all the used registers
push di
push si
push es
push ds
push dx
push cx
push bx
push ax
;
mov byte ptr [WindowKind],'M';Draw Math window
call PushOldScreen ;Save Old Screen and cursor position
;
mov dx,00104h ;Print headers:
call GotoXY ; |
mov dx,offset HeaderM1 ; |
call WriteLn ; |
mov dx,00302h ; |
call GotoXY ; |
mov dx,offset HeaderM2 ; |
call WriteLn ; |
mov dx,00402h ; |
call GotoXY ; |
mov dx,offset HeaderM3 ; |
call WriteLn ; |
mov dx,00502h ; |
call GotoXY ; |
mov dx,offset HeaderM4 ; |
call WriteLn ; |
mov dx,00702h ; |
call GotoXY ; |
mov dx,offset HeaderM5 ; |
call WriteLn ;/
;
DoMath1: mov dx,00114h ;Get Current Base
call GotoXY ; |
call ReadCh ; |
and al,0DFh ; | Make sure its upper case
mov BaseMchar,al ; |
cmp al,'B' ; | Set base in numeric form
jne short DoMath11 ; | |
mov bx,01002h ; | |
jmp short DoMath2 ; | |
DoMath11: ; | |
cmp al,'O' ; | |
jne short DoMath12 ; | |
mov bx,00608h ; | |
jmp short DoMath2 ; | |
DoMath12: ; | |
cmp al,'T' ; | |
jne short DoMath13 ; | |
mov bx,0050Ah ; | |
jmp short DoMath2 ; | |
DoMath13: ; | |
cmp al,'H' ; | |
jne short DoMath14 ; | |
mov bx,00410h ; | |
jmp short DoMath2 ; | |
DoMath14: ; |/
cmp al,Escape ; |
jne short DoMath1 ; |
jmp DoMath9 ; |
; ; |
DoMath2: mov BaseMNum,bl ; /
mov BaseMWidth,bh ;/
call WriteCh ;Print it
;
DoMath3: mov dx,00309h ;Clear old (optional) data
call GotoXY ; |
mov cx,16 ; |
call PrintSpc ; |
mov dx,00413h ; |
call GotoXY ; |
mov al,' ' ; |
call WriteCh ; |
mov dx,00509h ; |
call GotoXY ; |
call PrintSpc ; |
mov dx,0070Bh ; |
call GotoXY ; |
call PrintSpc ;/
;
DoMath4: mov dx,00309h ;Clear old (optional) data
call GotoXY ; |
mov cx,16 ; |
call PrintSpc ; |
mov dx,00309h ;Get first operand
call GotoXY ; |
mov dx,offset ReadBuf ; | Read the user entry,
mov ax,16 ; | 16 bytes to read at the most
call ReadLn ; | /
or ax,ax ; | No data entered ?
jne short DoMath41 ; | / Exit - close
jmp DoMath9 ; |
DoMath41: ; |
mov al,BaseMNum ; | Convert the string pointed by DX
call Str2Int ; | / to numeric data
or bx,bx ; | Test if error in conversion
jne Short DoMath4 ; |
mov si,ax ;/ Save it in si
;
DoMath5: mov dx,00413h ;Clear old (optional) data
call GotoXY ; |
mov al,' ' ; |
call WriteCh ; |
mov dx,00413h ;Get operator
call GotoXY ; |
call ReadCh ; |
cmp al,'+' ; |
je short DoMath51 ; |
cmp al,'-' ; |
je short DoMath51 ; |
cmp al,'*' ; |
je short DoMath51 ; |
cmp al,'/' ; |
je short DoMath51 ; |
cmp al,Escape ; |
jne short DoMath5 ; |
jmp DoMath9 ;/
DoMath51:
call WriteCh ;Print it
mov bp,ax ;And save in bp
;
DoMath6: mov dx,00509h ;Clear old (optional) data
call GotoXY ; |
mov cx,16 ; |
call PrintSpc ; |
mov dx,00509h ;Get second operand
call GotoXY ; |
mov dx,offset ReadBuf ; | Read the user entry,
mov ax,16 ; | 16 bytes to read at the most
call ReadLn ; | /
or ax,ax ; | No data entered ?
je DoMath9 ; | / Exit - close
mov al,BaseMNum ; | Convert the string pointed by DX
call Str2Int ; | / to numeric data
or bx,bx ; | Test if error in conversion
jne Short DoMath6 ; |
mov di,ax ;/ Save it in di
;
mov ax,bp ;Find what operation to perform, and
xor bx,bx ; | do it. Result in ax. Range error
cmp al,'+' ; | if bx <> 0
jne short DoMath71 ; |
mov ax,si ; |
add ax,di ; |
jnc short DoMath8 ; |
inc bx ; |
jmp short DoMath8 ; |
; ; |
DoMath71: ; |
cmp al,'-' ; |
jne short DoMath72 ; |
mov ax,si ; |
sub ax,di ; |
jnc short DoMath8 ; |
inc bx ; |
jmp short DoMath8 ; |
; ; |
DoMath72: ; |
cmp al,'*' ; |
jne short DoMath73 ; |
mov ax,si ; |
mul di ; |
mov bx,dx ; | if dx <> 0 - range error
jmp short DoMath8 ; |
; ; |
DoMath73: ; |
mov ax,si ; | Must be division
xor dx,dx ; |
or di,di ; | Test for divide by zero
je short DoMath733 ; | /
div di ; |
jmp short DoMath8 ; |
DoMath733: ; |
inc bx ; |
jmp short DoMath8 ;/
;
DoMath8: mov dx,0070Bh ;Print result
call GotoXY ; |
or bx,bx ; | Range Error ?
jne DoMath82 ; | /
mov bl,BaseMNum ; | No - print the number in AX
mov bh,BaseMWidth ; | |
mov cl,' ' ; | |
cmp bl,010 ; | |
je DoMath81 ; | |
mov cl,'0' ; | |
DoMath81: ; | |
call PrintNum ; |/
jmp short DoMath83
;
DoMath82:
mov dx,offset HeaderMr ;Print "Range Error"
call WriteLn ;/
;
DoMath83:
call ReadCh ;Wait for keystroke
cmp al,Escape
je short DoMath9
jmp DoMath3
;
DoMath9: call PopOldScreen ;Restore Old Screen and cursor position
;
pop ax ;restore all the used registers
pop bx
pop cx
pop dx
pop ds
pop es
pop si
pop di
pop bp
ret
DoMath endp
;
;*****************************************************************************
;procedure DoScanCode *
;procedure to handle scan code printing : *
;*****************************************************************************
DoScanCode proc near
push bp ;save all the used registers
push di
push si
push es
push ds
push dx
push cx
push bx
push ax
;
mov byte ptr [WindowKind],'S';Draw Scan COde window
call PushOldScreen ;Save Old Screen and cursor position
;
mov dx,00103h ;Print headers:
call GotoXY ; |
mov dx,offset HeaderS1 ; |
call WriteLn ; |
mov dx,00301h ; |
call GotoXY ; |
mov dx,offset HeaderS2 ; |
call WriteLn ; |
mov dx,00401h ; |
call GotoXY ; |
mov dx,offset HeaderS3 ; |
call WriteLn ;/
;
DoScan1: mov dx,0010Dh ;Wait for a key
call GotoXY ; |
call ReadCh ; |
push ax ; |
mov cx,2 ; | Clear old one
call PrintSpc ; | /
mov dx,0010Dh ; |
call GotoXY ; |
cmp al,' ' ; | Print it if printable
jae DoScan10 ; | |
mov ah,al ; | |
mov al,'^' ; | |
call WriteCh ; | |
mov al,ah ; | |
add al,'@' ; | |
DoScan10: ; | |
call WriteCh ; |/
pop ax ; |
; ; |
cmp al,Escape ;Quit ?
je short DoScan9 ;/
;
or al,al ;Is it extended ascii code ?
jne DoScan2 ;/
mov dx,0030Ah ;Print "Extended"
call GotoXY ; |
mov dx,offset HeaderS4 ; |
call WriteLn ; |
mov dx,0040Ah ; |
call GotoXY ; |
mov dx,offset HeaderS4 ; |
call WriteLn ;/
mov al,ah
jmp short DoScan3
;
DoScan2: mov dx,0030Ah ;Clear optional old "Extended"
call GotoXY ; |
mov cx,8 ; |
call PrintSpc ; |
mov dx,0040Ah ; |
call GotoXY ; |
mov cx,8 ; |
call PrintSpc ;/
;
DoScan3: mov dx,00306h ;Print in Hex form
call GotoXY ; |
mov bx,00310h ; | 3 places, base 10h
mov cl,'0' ; | The prefix char
xor ah,ah ; |
call PrintNum ;/
mov dx,00406h ;Print in Dec form
call GotoXY ; |
mov bx,0030Ah ; | 3 places, base 10
mov cl,' ' ; | The prefix char
call PrintNum ;/
;
jmp DoScan1 ;Continue to next char
;
DoScan9: call PopOldScreen ;Restore Old Screen and cursor position
;
pop ax ;restore all the used registers
pop bx
pop cx
pop dx
pop ds
pop es
pop si
pop di
pop bp
ret
DoScanCode endp
;
;
;Save Old Screen status , to recover when exit :
PushOldScreen proc near
push ax
push bx
push cx
push dx
push si
push di
push es
push ds
mov ah,BiosGetMode ;Test what Mode in On
int 010h ; /
cmp al,7 ;/ ( Is it mono ? )
je short PushOldScreen1
;
mov word ptr [ScreenBase],CGAAddress ;Set up as CGA
jmp short PushOldScreen2
;
PushOldScreen1:
mov word ptr [ScreenBase],MonoAddress ;Set up as Mono
;
PushOldScreen2:
;
push bx ;Save current active display page
mov ah,BiosGetLoc ;Get Cursor Location
int 010h ; / ( bh hold page from mode test )
mov [OldCursor],dx ;/
pop bx
;
and bh, 003h ;Make page number between 0-3 only
mov bl,bh ;Multiply it by ScreenSize
xor bh,bh ; \
mov ax,ScreenSize ; | Preper source offset
mul bx ; /
mov si,ax ;Get current page offset into si
mov word ptr [ScreenOffCur],ax
inc bx
and bx,00003h ;Make sure its within range (mod 4)
mov ax,ScreenSize ; \
mul bx ; | Preper destination offset
mov di,ax ; / save page offset into di
mov word ptr [ScreenOffSav],ax
;
push ds
cld
mov es,[ScreenBase] ;Save Old Screen buffer -
mov ds,[ScreenBase] ;Save all the 4k for the simplicity
mov cx,ScreenSize / 2 ; | (Move Words)
rep movsw ;/ ds:si --> es:di , cx times
pop ds
;
cmp byte ptr [WindowKind],'C' ;Is it Converstion Screen ?
jne PushOldScreen4 ;/
;
xor dx,dx ;Print our window
call GotoXY ; |
mov byte ptr [CharAttr],InversAttr
mov bx,offset BorderC1 ; |
xchg bx,dx ; |
call WriteLn ; | (border1 - top)
xchg bx,dx ; |
mov cx,WindowHeightC ; |
PushOldScreen3: ; |
inc dh ; | (Y position)
call GotoXY ; |
push dx
mov dx,offset BorderC21 ; |
call WriteLn ; | (border2 - middle)
;
mov dx,offset BorderC22 ; |
mov byte ptr [CharAttr],NormalAttr
call WriteLn ; | (border2 - middle)
;
mov dx,offset BorderC23 ; |
mov byte ptr [CharAttr],InversAttr
call WriteLn ; | (border2 - middle)
;
pop dx ; |
loop PushOldScreen3 ; |
; ; |
inc dh ; | (Y position)
call GotoXY ; |
mov dx,offset BorderC3 ; |
call WriteLn ;/ (border3 - bottom)
mov byte ptr [CharAttr],NormalAttr
jmp PushOldScreen99
;
PushOldScreen4:
cmp byte ptr [WindowKind],'A' ;Is it Ascii Table Screen ?
jne PushOldScreen6 ;/
;
xor dx,dx ;Print our window
call GotoXY ; |
mov bx,offset BorderA1 ; |
mov byte ptr [CharAttr],InversAttr
xchg bx,dx ; |
call WriteLn ; | (border1 - top)
xchg bx,dx ; |
mov cx,WindowHeightA ; |
PushOldScreen5: ; |
inc dh ; | (Y position)
call GotoXY ; |
push dx
mov dx,offset BorderA21 ; |
call WriteLn ; | (border2 - middle)
;
mov dx,offset BorderA22 ; |
mov byte ptr [CharAttr],NormalAttr
call WriteLn ; | (border2 - middle)
;
mov dx,offset BorderA23 ; |
mov byte ptr [CharAttr],InversAttr
call WriteLn ; | (border2 - middle)
;
pop dx ; |
loop PushOldScreen5 ; |
; ; |
inc dh ; | (Y position)
call GotoXY ; |
mov dx,offset BorderA3 ; |
call WriteLn ;/ (border3 - bottom)
mov byte ptr [CharAttr],NormalAttr
jmp PushOldScreen99
;
PushOldScreen6:
cmp byte ptr [WindowKind],'M' ;Is it Math Screen ?
jne PushOldScreen8 ;/
;
xor dx,dx ;Print our window
call GotoXY ; |
mov byte ptr [CharAttr],InversAttr
mov bx,offset BorderM1 ; |
xchg bx,dx ; |
call WriteLn ; | (border1 - top)
xchg bx,dx ; |
mov cx,WindowHeightM ; |
PushOldScreen7: ; |
inc dh ; | (Y position)
call GotoXY ; |
push dx
mov dx,offset BorderM21 ; |
call WriteLn ; | (border2 - middle)
;
mov dx,offset BorderM22 ; |
mov byte ptr [CharAttr],NormalAttr
call WriteLn ; | (border2 - middle)
;
mov dx,offset BorderM23 ; |
mov byte ptr [CharAttr],InversAttr
call WriteLn ; | (border2 - middle)
;
pop dx ; |
loop PushOldScreen7 ; |
; ; |
inc dh ; | (Y position)
call GotoXY ; |
mov dx,offset BorderM3 ; |
call WriteLn ;/ (border3 - bottom)
mov byte ptr [CharAttr],NormalAttr
jmp PushOldScreen99
;
PushOldScreen8:
cmp byte ptr [WindowKind],'S' ;Is it Scan Code Screen ?
jne PushOldScreen10 ;/
;
xor dx,dx ;Print our window
call GotoXY ; |
mov byte ptr [CharAttr],InversAttr
mov bx,offset BorderS1 ; |
xchg bx,dx ; |
call WriteLn ; | (border1 - top)
xchg bx,dx ; |
mov cx,WindowHeightS ; |
PushOldScreen9: ; |
inc dh ; | (Y position)
call GotoXY ; |
push dx
mov dx,offset BorderS21 ; |
call WriteLn ; | (border2 - middle)
;
mov dx,offset BorderS22 ; |
mov byte ptr [CharAttr],NormalAttr
call WriteLn ; | (border2 - middle)
;
mov dx,offset BorderS23 ; |
mov byte ptr [CharAttr],InversAttr
call WriteLn ; | (border2 - middle)
;
pop dx ; |
loop PushOldScreen9 ; |
; ; |
inc dh ; | (Y position)
call GotoXY ; |
mov dx,offset BorderS3 ; |
call WriteLn ;/ (border3 - bottom)
mov byte ptr [CharAttr],NormalAttr
jmp PushOldScreen99
;
PushOldScreen10:
cmp byte ptr [WindowKind],'N' ;Is it Main Screen ?
jne PushOldScreen99 ;/
;
xor dx,dx ;Print our window
call GotoXY ; |
mov byte ptr [CharAttr],InversAttr
mov bx,offset BorderN1 ; |
xchg bx,dx ; |
call WriteLn ; | (border1 - top)
xchg bx,dx ; |
mov cx,WindowHeightN ; |
PushOldScreen11: ; |
inc dh ; | (Y position)
call GotoXY ; |
push dx
mov dx,offset BorderN21 ; |
call WriteLn ; | (border2 - middle)
;
mov dx,offset BorderN22 ; |
mov byte ptr [CharAttr],NormalAttr
call WriteLn ; | (border2 - middle)
;
mov dx,offset BorderN23 ; |
mov byte ptr [CharAttr],InversAttr
call WriteLn ; | (border2 - middle)
;
pop dx ; |
loop PushOldScreen11 ; |
; ; |
inc dh ; | (Y position)
call GotoXY ; |
mov dx,offset BorderN3 ; |
call WriteLn ;/ (border3 - bottom)
mov byte ptr [CharAttr],NormalAttr
jmp PushOldScreen99
;
;
PushOldScreen99:
pop ds
pop es
pop di
pop si
pop dx
pop cx
pop bx
pop ax
ret
PushOldScreen endp
;
;Restore Old Screen status - recover to exit :
PopOldScreen proc near
push ax
push bx
push cx
push dx
push si
push di
push es
push ds
mov ah,BiosGetMode ;Get current page number into bh
int 010h ;/
mov dx,[OldCursor] ;Set to Old Cursor Location
mov ah,BiosLocate
int 010h ;Call Bios
;
push ds
cld
mov si,[ScreenOffSav] ;Restore Old Screen buffer -
mov di,[ScreenOffCur] ;Restore all the 4k for the simplicity
mov es,[ScreenBase] ; |
mov ds,[ScreenBase] ; | (change ds last!)
mov cx,ScreenSize / 2 ; | (Move Words)
rep movsw ;/ ds:si --> es:di , cx times
pop ds
;
pop ds
pop es
pop di
pop si
pop dx
pop cx
pop bx
pop ax
ret
PopOldScreen endp
;
;Print the char in al in decimal, hexadecimal and ascii forms:
PrintAsc proc near
push ax
push bx
push cx
;
xor ah,ah ;Print in Decimal form
mov bl,010 ; | Base - 10
mov bh,003 ; | On 3 places
mov cl,' ' ; | Prefix - space
call PrintNum ;/
;
push ax
mov al,' ' ;Print one Space
call WriteCh ;/
pop ax
;
mov bl,016 ;Print in HexaDecimal form : Base - 16
mov bh,002 ; | On 2 places
mov cl,'0' ; | Prefix - '0'
call PrintNum ;/
;
push ax
mov al,' ' ;Print one Space
call WriteCh ;/
pop ax
;
call WriteCh ;Print it in Ascii form
;
pop cx
pop bx
pop ax
ret
PrintAsc endp
;
;Print cx spaces from current XY on screen
PrintSpc proc near
push ax
push cx
;
mov al,' ' ;Preper Space to print
PrintSpc1:
call WriteCh ;Print it cx times
loop PrintSpc1 ;/
;
pop cx
pop ax
ret
PrintSpc endp
;
;Print the number in variouse base (note the registers are affected) :
PrintNumBases proc near
;
mov bh,16 ;Print base 2 in 16 places
mov dx,00603h ;GotoXY 3,6 relative to window
call GotoXY ;/
mov dx,offset Base2 ;Print the number in base 2
call WriteLn ; |
mov cl,'0' ; | Prefix fill character
mov bl,02 ; |
call PrintNum ;/
;
mov bh,06 ;Print base 8 in 6 places
mov dx,00703h ;GotoXY 3,7 relative to window
call GotoXY ;/
mov dx,offset Base8 ;Print the number in base 8
call WriteLn ; |
mov cx,10 ; | Print 10 leedin spaces
call PrintSpc ; | /
mov cl,'0' ; | Prefix fill character
mov bl,08 ; |
call PrintNum ;/
;
mov bh,16 ;Print base 10 in 16 places
mov dx,00803h ;GotoXY 3,8 relative to window
call GotoXY ;/
mov dx,offset Base10 ;Print the number in base 10
call WriteLn ; |
mov cl,' ' ; | Prefix fill character
mov bl,10 ; |
call PrintNum ;/
;
mov bh,04 ;Print base 16 in 4 places
mov dx,00903h ;GotoXY 3,9 relative to window
call GotoXY ;/
mov dx,offset Base16 ;Print the number in base 16
call WriteLn ; |
mov cx,12 ; | Print 12 leedin spaces
call PrintSpc ; | /
mov cl,'0' ; | Prefix fill character
mov bl,16 ; |
call PrintNum ;/
;
ret
PrintNumBases endp
;
;Print the given integer number AX in base Bl, in Bh places (less then 20).
;The prefix fill character is in cl (i.e. in 00001000 = 8 cl = '0')
;
PrintNum proc near
push ax
push bx
push cx
push dx
push di
push es
;
mov dx,ds ;Trasfer seg. to es
mov es,dx
push cx ;Save fill char in cl
;
std
mov di,offset PrNumEnd-1 ;Current byte to save
mov cl,bl ;Preper the divisor
xor ch,ch ;/
;
or ax,ax ;Is it 0 to be print ?
je PrNum5 ;If so handle seperately
;
PrNum1: xor dx,dx
div cx ;Quontient in ax, remainder in dx
or ax,ax ;No quontient ?
jne short PrNum2
or dx,dx ;No remainder ?
je PrNum3
PrNum2: xchg dx,ax
cmp al,10 ;Covnert it to ascii code
jae PrNum21 ; |
add al,'0'-('A'-10) ; |
PrNum21: add al,'A'-10 ;/
stosb ;Save the remainder
xchg dx,ax
dec bh ;Decrease current number of places
jmp short PrNum1
;
PrNum3: pop ax ;The fill character
test bh,080h ;Places - overflow ?
jne PrNum6 ;/
or bh,bh ;Places fit exactly ?
je PrNum6 ;/
PrNum4: stosb ;Fill with prefix fill char(s)
dec bh ; |
jne PrNum4 ;/
jmp short PrNum6 ;Skip the ax = 0 case
;
;If we get here then ax=0 and a zero in the right format must be printed
PrNum5: mov al,'0'
stosb ;Save one zero
dec bh ;One less place
jmp short PrNum3 ;And handle as usual
;
PrNum6: mov dx,di ;Print it
inc dx ; |
call WriteLn ;/
pop es
pop di
pop dx
pop cx
pop bx
pop ax
ret
;
PrNumBfLn equ 21 ;Buffer length up to 20
PrNumBuf db PrNumBfLn dup(' ') ;Buffer to create the number here
PrNumEnd db '$'
;
PrintNum endp
;
;Transfer a string pointed by DS:DX into an integer. The string is terminated
;by a '$' char . Base of convertion is in al (2..16) . Return result in ax
;If succesfull then bx = 0 , else bx = 1 (error) .
Str2Int proc near
push cx
push dx
push si
;
mov si,dx
mov cl,al ;Save Base in cx
xor ch,ch ;/
xor ax,ax ;Clear current integer value1
;
cld ;Direction up
Str2In1: mov dx,ax ;Save it temporary
lodsb
cmp al,'$' ;End of data ?
je Str2In8 ;/
mov ah,cl ;Give Chr2Dig the base
call Chr2Dig
mov bl,al ;Save new digit in bx
xor bh,bh ;/
mov ax,dx ;Get Old integer back
cmp bl,0ffh ;Wrong digit ?
je Str2In7 ;/
mul cx ;Multiply old value by base
add ax,bx ;and add new data
jmp short Str2In1 ;/
;
Str2In7: mov bx,0001h ;Error
jmp short Str2In9
Str2In8: mov ax,dx ;Get Integer back
mov bx,0000h ;O.K.
Str2In9: pop si
pop dx
pop cx
ret
Str2Int endp
;
;Return 0ffh in al if the char in al is not a digit in range 0 .. base-1, where
;base is in ah. The digit is given in Ascii form and returned in binary (in al)
Chr2Dig proc near
call ToLower ;if in A..F convert to a..f
sub al,'0'
cmp al,10 ;if hex digit
jb chr2Dg1
sub al,('a'-'0')-10
Chr2Dg1: cmp al,ah ;must be less the base
jb Chr2Dg9
mov al,0ffh ;wrong digit
Chr2Dg9: ret
Chr2dig endp
;
;COnvert the char in al into lower case :
ToLower proc near
cmp al,'A' ;if below A
jb ToLow9
cmp al,'Z' ;if above Z
ja ToLow9
add al,'a'-'A'
ToLow9: ret
ToLower endp
;
;Locate the cursor at position X = Dl, Y = Dh (Relative to Top Left of screen)
GotoXY proc near
push ax
push bx
push cx
push dx
mov [CursorX],dl ;Save Current position
mov [CursorY],dh ;/
;
cmp byte ptr [WindowKind],'A' ;Is it ascii table window ?
jne GotoXY1 ;/
mov al,[WindowLeftA] ;Preper to add Top Left of window offset
mov ah,[WindowTopA] ;/
jmp short GotoXY9
;
GotoXY1: cmp byte ptr [WindowKind],'C' ;Is it conversion window ?
jne GotoXY2 ;/
mov al,[WindowLeftC] ;Preper to add Top Left of window offset
mov ah,[WindowTopC] ;/
jmp short GotoXY9
;
GotoXY2: cmp byte ptr [WindowKind],'M' ;Is it math window ?
jne GotoXY3 ;/
mov al,[WindowLeftM] ;Preper to add Top Left of window offset
mov ah,[WindowTopM] ;/
jmp short GotoXY9
;
GotoXY3: cmp byte ptr [WindowKind],'S' ;Is it conversion window ?
jne GotoXY4 ;/
mov al,[WindowLeftS] ;Preper to add Top Left of window offset
mov ah,[WindowTopS] ;/
jmp short GotoXY9
;
GotoXY4: cmp byte ptr [WindowKind],'N' ;Is it Main window ?
jne GotoXY5 ;/
mov al,[WindowLeftN] ;Preper to add Top Left of window offset
mov ah,[WindowTopN] ;/
jmp short GotoXY9
GotoXY5:
;
GotoXY9: add dx,ax ;Top Left of window position
mov bh,0 ;Screen number 0
mov ah,BiosLocate
int 010h ;Call Bios
pop dx
pop cx
pop bx
pop ax
ret
GotoXY endp
;
;Read one character into al (Result) , ah (ScanCode).
ReadCh proc near
push bx
push cx
push dx
mov ah,BiosGetCh
int 016h ;Call Bios
pop dx
pop cx
pop bx
ret
ReadCh endp
;
;Write one character from al, at current cursor location, and advance to next :
WriteCh proc near
push ax
push bx
push cx
push dx
mov ah,BiosPutCh
mov bl,[CharAttr] ;SetAttribute
mov bh,000h ;Page 0
mov cx,001h ;Number of Chars
int 010h ;Call Bios
;
inc byte ptr [CursorX] ;Advance to next char
mov dl,[CursorX] ;by updating Current position
mov dh,[CursorY] ; /
call GotoXY ;/
;
pop dx
pop cx
pop bx
pop ax
ret
WriteCh endp
;
;Read one line terminated by CR into the buffer DS:DX :
;In ax the maximum number of chars to read.
;On return ax contains actual number read. '$' sign is entered after the last char
ReadLn proc near
push bx
push cx
push dx
push di
push si
push es
mov bx,ds ;Copy ds to es
mov es,bx ;/
mov cx,ax ;Maximum to read
mov di,dx ;transfer pointer of buffer
mov si,dx ;/
mov dl,[CursorX] ;GotoXY the right position
mov dh,[CursorY] ; /
call GotoXY ;/
xor dx,dx ;number of chars actually read
cld
;
ReadLn1: call ReadCh ;Get One char
cmp al,' ' ;Printable ?
jb short ReadLn2
call WriteCh ;Print it
ReadLn2: cmp al,Cr ;Is it Cr ?
je short ReadLn9
cmp al,Escape ;Is it Escape ?
jne short ReadLn3
mov byte ptr [si],'$' ;If Escape pressed - exit with empty
xor ax,ax ;line
jmp short ReadLn91
;
ReadLn3: cmp al,Bs ;Is it Back Space ?
jne short ReadLn4
or dx,dx ;Buffer not empty ?
je short ReadLn1
dec di ;eliminate one char
dec dx ; /
inc cx ;/
push dx
dec byte ptr [CursorX] ;Return to last char
mov dl,[CursorX] ;by updating Current position
mov dh,[CursorY] ; /
call GotoXY ;/
mov al,' '
call WriteCh ;Erase the char
dec byte ptr [CursorX] ;And return to last char again
mov dl,[CursorX] ;by updating Current position
mov dh,[CursorY] ; /
call GotoXY ;/
pop dx
jmp short ReadLn1
;
ReadLn4: stosb
inc dx
ReadLn8: loop ReadLn1
;
ReadLn9: mov al,'$'
stosb
mov ax,dx ;back into dx
ReadLn91:
pop es
pop si
pop di
pop dx
pop cx
pop bx
ret
ReadLn endp
;
;Write one line terminated by a '$' from the buffer DS:DX :
WriteLn proc near
push ax
push bx
push cx
push dx
xchg bx,dx
WriteLn1:
mov al,[bx]
cmp al,'$'
je WriteLn9
call WriteCh
inc bx
jmp WriteLn1
;
WriteLn9:
pop dx
pop cx
pop bx
pop ax
ret
WriteLn endp
;
OldCursor dw 00000h ;Save old Cursor Position
WindowKind db 000h ;Kind of window : A)scii , C)onversion
CursorX db 00 ;Cursor Position X
CursorY db 00 ;Cursor Position Y
ResActive db 00h ;Prevent from reentrance flag
CharAttr db NormalAttr ;Current attribute to write to screen
ScreenBase dw 0B000h ;Screen Base Address
ScreenOffCur dw 00000h ;Screen Offset - current page
ScreenOffSav dw 00000h ;Screen Offset - saved page
OldKbdHandler dd 00000h ;Save here old keyboard int16h
ReadBuf db 17 dup (' ') ;Save here the user entered data
;
;Base Conversion Window Parameters and Constants :
;
BorderC1 db '╔════════════════════════════════╗$' ;Ascii 201,205,187
BorderC21 db '║$' ;Ascii 186
BorderC22 db ' $'
BorderC23 db '║$' ;Ascii 186
BorderC3 db '╚══════════Esc to exit═══════════╝$' ;Ascii 200,205,188
WindowWidthC equ ($ - BorderC3) - 3 ;The Clear width inside
WindowHeightC equ 10 ;Realy number of BorderC2? printing
InstallStamp equ $
HeaderC1 db ' Base Numeric Conversion$'
HeaderC2 db 'Enter number follow by B,O,T,H$'
EnterData db 'Number : $'
Base2 db 'Base 2 : $'
Base8 db 'Base 8 : $'
Base10 db 'Base 10 : $'
Base16 db 'Base 16 : $'
InstallStampLen equ $ - InstallStamp
;
;Ascii Table Window Parameters and Constants :
;
CurrentChar db 00 ;The char to start the Ascii table
BorderA1 db '╔═D══H══C╤═D══H══C╤═D══H══C╤═D══H══C╤═D══H══C╤═D══H══C╤═D══H══C╤═D══H══C╗$'
BorderA21 db '║$'
BorderA22 db ' │ │ │ │ │ │ │ $'
BorderA23 db '║$'
BorderA3 db '╚════════╧════Space to Toggle Ascii Low / High , Esc to Exit═══╧════════╝$'
WindowWidthA equ ($ - BorderA3) - 3 ;The Clear width inside
WindowHeightA equ 16 ;Realy number of BorderA2? printing
;
;Math Calculation Window Parameters and Constants :
;
BorderM1 db '╔═════Unsigned Calculus══════╗$' ;Ascii 201,205,187
BorderM21 db '║$' ;Ascii 186
BorderM22 db ' $'
BorderM23 db '║$' ;Ascii 186
BorderM3 db '╚════════Esc to exit═════════╝$' ;Ascii 200,205,188
WindowWidthM equ ($ - BorderM3) - 3 ;The Clear width inside
WindowHeightM equ 7 ;Realy number of BorderM2? printing
BaseMchar db 'H' ;Default - base 16
BaseMNum db 16 ; /
BaseMWidth db 4 ;/
HeaderM1 db 'Base (B,O,T,H):$'
HeaderM2 db 'Num1 :$'
HeaderM3 db 'Oper (+,-,*,/) :$'
HeaderM4 db 'Num2 :$'
HeaderM5 db 'Result :$'
HeaderMr db 'Range Error$'
;
;Scan Code Window Parameters and Constants :
;
BorderS1 db '╔══Press Any Key══╗$' ;Ascii 201,205,187
BorderS21 db '║$' ;Ascii 186
BorderS22 db ' $'
BorderS23 db '║$' ;Ascii 186
BorderS3 db '╚═══Esc to exit═══╝$' ;Ascii 200,205,188
WindowWidthS equ ($ - BorderS3) - 3 ;The Clear width inside
WindowHeightS equ 4 ;Realy number of BorderM2? printing
HeaderS1 db 'Scan Code:$'
HeaderS2 db 'Hex:$'
HeaderS3 db 'Dec:$'
HeaderS4 db 'Extended$'
;
;
;Main Window Parameters and Constants :
;
BorderN1 db '╔═════════════════════╗$' ;Ascii 201,205,187
BorderN21 db '║$' ;Ascii 186
BorderN22 db ' $'
BorderN23 db '║$' ;Ascii 186
BorderN3 db '╚═════════════════════╝$' ;Ascii 200,205,188
WindowWidthN equ ($ - BorderN3) - 3 ;The Clear width inside
WindowHeightN equ 8 ;Realy number of BorderN2? printing
HeaderN1 db '1. Ascii Table$'
HeaderN2 db '2. Base Conversion$'
HeaderN3 db '3. Math Operations$'
HeaderN4 db '4. Scan Code$'
HeaderN9 db 'Select:$'
;
EndOfResident Equ $ ;End of resident part
;
;*****************************************************************************
;
ExistsMsg db 'Conv was already installed, ignored',cr,lf,'$'
InstMsg db 'Conv is installed: Alt - A to activate, '
db 'Elber Gershon 88 Ver 1.1',cr,lf,'$'
;
;*****************************************************************************
;procedure install *
;procedure to install all the system parameters and quit . *
;*****************************************************************************
Install:
;
;Test if we already installed this once - search all segments below our CS
;for the existance of the data code "InstallStamp":
;I dont know was is the beginning value of segment to search which will be
;safe for all dos versions, so we start just above the vector interrupt...
;
mov bx,040h ;End of Vector Interrupt as start seg.
mov ax,cs ;Save current segment in ax
Install1:
inc bx ;Go to next segment
cmp ax,bx ;if Equal - we didnt find it!
jbe Install2 ;/
mov es,bx
mov si,offset InstallStamp
mov di,si
mov cx,InstallStampLen
repe cmpsb ;Search in current segment
jne Install1
;
mov dx,offset ExistsMsg ;Print its already installed
mov ah,DosPutLn ; /
int 021h ;/
;
mov ax,04c01h ;And exit with return code of 1
int 021h ;/
;
Install2:
cli ;Disable interrupts
;
;Save old Keyboard interrupt routine & install ours (Hot key detection) :
mov al,016h ;get old int 16 address
mov ah,035h ; /
int 021h ;/
mov word ptr cs:OldKbdHandler,bx ;save it !
mov word ptr cs:OldKbdHandler[2],es ;/
;
mov al,016h ;Istall procedure - KbdHandler
mov dx,offset KbdHandler ; |
mov ah,025h ; |
int 021h ;/
;
sti ;int enable
;
Install9:
mov dx,offset InstMsg ;Print it when install
mov ah,DosPutLn ; /
int 021h ;/
;
;Set the length of resident part (in paragraphs) to leave, and quit:
mov dx,(offset EndOfResident - offset code + 15) shr 4
mov ax,03100h ;Return with ret code 0
int 021h ;Terminate & stay resident
;
code ends
;
end starter