home *** CD-ROM | disk | FTP | other *** search
- ;Copyright 1987, John J. Newlin
-
- PUBLIC setxy,upcase,cga_retrace,fillstr,screenwrite,init_screen,savebox
- PUBLIC restbox,shiftl,shiftr,hi,lo,move,chdir,findfirst,findnext,cls
- PUBLIC strng,video_mode,set_mem,getdir,msdos,set_dta,scroll,keycode
- PUBLIC exec,hide_cursor,rest_cursor,save_cursor,longstr,addlong
-
- toolcode segment word PUBLIC 'code'
- assume cs:toolcode
-
- ;;;;;;;;;;;;;;
- ;changes lower case char to upper case
- ;function upcase(ch : char) : char
- upcase proc near
- push bp
- mov bp,sp ;save BP
- mov ax,[bp+4] ;get the char
- cmp al,97 ;is it 'a' or above?
- jb u_exit ;no, do nothing
- cmp al,122 ;is it 'z' or below?
- ja u_exit ;no, do nothing
- sub al,32 ;change to upper case
- u_exit: mov [bp+6],ax ;return as function result
- pop bp
- ret 2
- upcase endp
-
- ;;;;;;;;;;;;;;;
- ;uses undocumented interrupt 2E to execute a program
- ;procedure exec(var name : string);
- exec proc near
- push bp ;save bp
- mov bp,sp ;bp points to the stack
- push ax ;save
- push bx ; all
- push cx ; other
- push dx ; regs
- push di
- push si
- jmp past ;jump over storage area
- mls_ds dw 0 ;stores our DS reg
- mls_es dw 0 ;stores our ES reg
- mls_ss dw 0 ;stores our SS reg
- mls_sp dw 0 ;stores our SP reg
- mls_bp dw 0 ;stores our BP reg
- past:
- mov cs:mls_ss,ss ;save SS reg
- mov cs:mls_sp,sp ;save SP reg
- mov cs:mls_es,es ;save ES reg
- mov cs:mls_ds,ds ;save DS reg
- mov cs:mls_bp,bp ;save BP reg
- push ds
- pop es ;set ES = DS
- mov si,[bp+4] ;si points to command string
- int 2Eh ;call DOS to execute
- mov ax,cs:mls_ss ;retrieve SS reg
- mov ss,ax ;reset it
- mov sp,cs:mls_sp ;retrieve SP reg
- mov ax,cs:mls_ds ;retrieve DS reg
- mov ds,ax ;reset it
- mov ax,cs:mls_es ;retrieve ES reg
- mov es,ax ;reset it
- mov bp,cs:mls_bp ;retrieve BP reg
- pop si ;restore
- pop di ; all
- pop dx ; other
- pop cx ; regs
- pop bx
- pop ax
- pop bp
- ret 2
- exec endp
-
- ;;;;;;;;;;;;
- ;returns keyboard status byte, ascii code, and scan code
- ;function keycode(var status,ascii,scan : integer) : boolean;
- keycode proc near
- push bp
- mov bp,sp ;BP points to stack
- push bx ;Marshal says save BX
- push si ;and also SI
- mov ah,1 ;Int 16h to check buffer
- int 16h ;call BIOS
- mov word ptr [bp+10],0 ;function returns a false
- jz _no_key ;no key avail, so depart
- mov ah,0 ;key is avail, so get it
- int 16h ;call BIOS
- push ax ;save result
- mov ah,2 ;to get status byte
- int 16h ;call BIOS
- mov bx,[bp+8] ;get address of status
- mov ah,0 ;zero the MSB
- mov [bx],ax ;set status
- pop ax ;restore AX
- mov bx,[bp+6] ;get address of ascii
- mov si,[bp+4] ;get address of scan
- xor dx,dx ;zero DX
- mov dl,ah ;put scan value in DX
- mov [si],dx ;move it into scan
- mov dl,al ;move ascii code into DL
- mov [bx],dx ;and into ascii
- mov word ptr[bp+10],1 ;function returns true
- _no_key: pop si
- pop bx
- pop bp
- ret 6
- keycode endp
-
- ;;;;;;;;;;;;;;;
- ;scrolls the specified area of the screen up/down number of lines
- ;normalize to screen dimensions of (1,1) to (25,80)
- ;procedure scroll(ulx,uly,lrx,lry,lines,attr,dir : integer); external;
- scroll proc near
- push bp
- mov bp,sp ;BP points to stack
- push bx ;must preserve BX
- mov bh,byte ptr 6[bp] ;get desired attribute
- mov ch,byte ptr 14[bp] ;upper left y coord
- dec ch ;normalize
- mov cl,byte ptr 16[bp] ;upper left x coord
- dec cl ;normalize
- mov dh,byte ptr 10[bp] ;lower right y coord
- dec dh ;normalize
- mov dl,byte ptr 12[bp] ;lower right x coord
- dec dl ;normalize
- mov al,byte ptr 08[bp] ;no. of lines to scroll
- cmp byte ptr 4[bp],0 ;scroll up?
- je scroll_up ;yes
- mov ah,7 ;no, scroll down
- jmp short scroll_it ;do it
- scroll_up: mov ah,6 ;scroll up
- scroll_it: int 10h ;call BIOS
- pop bx
- pop bp
- ret 14
- scroll endp
-
- ;;;;;;;;;;;;;
- ;set the Disk Transfer Area to desired structure
- ;procedure set_dta(var buffer : buff_type);
- set_dta proc near
- push bp
- mov bp,sp ;BP points to stack
- mov dx,[bp+4] ;get address of buffer
- mov ah,1Ah ;function to set DTA
- int 21h ;DOS will do it
- pop bp
- ret 2
- set_dta endp
-
- ;;;;;;;;;;;;;;
- ;call DOS interrupt 21h with registers set as desired
- ;procedure msdos(var regs : regtype)
- msdos proc near
- push bp
- mov bp,sp ;BP points to stack
- push ax ;save
- push bx ; all
- push cx ; regs
- push dx ;
- push di ;
- push si ;
- push ds ;
- push es ;
- jmp short pst ;leap over code seg data
- saveit dw 0
- pst:
- mov bx,[bp+4] ;BX points to regs structure
- mov ax,[bx+0] ;set AX
- mov cx,[bx+4] ;set CX
- mov dx,[bx+6] ;set DX
- mov di,[bx+8] ;set DI
- mov si,[bx+10] ;set SI
- mov cs:saveit,ds ;save our DS reg
- push [bx+14] ;push ES value in structure
- pop es ;pop it into ES
- push [bx+2] ;push BX value in structure
- push [bx+12] ;push DS value in structure
- pop ds ;set DS
- pop bx ;set BX
- push bp ;save our BP during call
- int 21h ;call DOS
- pop bp ;restore our BP
- push ds ;save returned DS
- push bx ;save returned BX
- mov bx,cs:saveit ;get our DS reg
- mov ds,bx ;set our DS
- mov bx,[bp+4] ;get pointer to structure
- pop [bx+2] ;set structure BX
- pop [bx+12] ;set structure DS
- mov [bx+0],ax ;set structure AX
- mov [bx+4],cx ;set structure CX
- mov [bx+6],dx ;set structure DX
- mov [bx+8],di ;set structure DI
- mov [bx+10],si ;set structure SI
- push es ;push returned ES
- pop [bx+14] ;pop it into structure ES
- pushf ;push returned flags
- pop [bx+16] ;pop into structure flags
- pop es ;restore
- pop ds ; all
- pop si ; regs
- pop di ;
- pop dx ;
- pop cx ;
- pop bx ;
- pop ax ;
- pop bp ;
- ret 2
- msdos endp
-
- ;;;;;;;;;;;;;
- ;returns active drive and directory in string
- ;drive code 0 = A, 1 = B, etc.
- ;procedure getdir(var dirname : string);
- getdir proc near
- push bp
- mov bp,sp ;BP points to stack
- push si ;must preserve SI
- mov si,[bp+4] ;SI points to dirname
- mov ah,19h ;set up to get drive desig
- int 21h ;call DOS
- add al,65 ;make it a char
- mov byte ptr[si],al ;put in string
- inc si ;point to next char
- mov al,58 ;58 = ':'
- mov byte ptr[si],al ;put in string
- inc si ;point to next char
- mov byte ptr[si],'\' ;put in backslash
- inc si ;point to next char
- mov ah,47h ;set up to get default dir
- int 21h ;call DOS
- pop si
- pop bp
- ret 2
- getdir endp
-
- ;;;;;;;;;;;;;;
- ;set program memory to only what is required by code, data, and stack
- ;function set_mem : integer;
- set_mem proc near
- push bp ;save BP
- mov bp,sp ;BP points to stack
- push es ;save ES
- push bx ;save BX
- mov ax,ds ;AX = DS
- mov bx,cs ;BX = CS
- sub ax,bx ;ds-cs = data seg paragraphs
- inc ax ;round up one
- mov bx,ax ;store in BX
- mov ax,bp ;AX = stack pointer
- mov cl,4 ;for shifting
- shr ax,cl ;convert to paragraphs
- add ax,bx ;add BX
- add ax,32 ;bump by 32 paragraph overhead
- mov bx,ax ;store in BX
- mov cx,ax ;save in CX
- mov ax,cs ;AX = code segment
- sub ax,16 ;AX set to mem control block seg
- mov es,ax ;ES = mem control block seg
- mov ah,4Ah ;DOS mod alloc mem function
- int 21h ;DOS will do it
- jnc no_mem_err ;error will set carry flag
- mov cx,-1 ;if error return -1
- no_mem_err: mov [bp+4],cx ;function result
- pop bx ;restore BX
- pop es ;restore ES
- pop bp ;restore BP
- ret
- set_mem endp
-
- ;;;;;;;;;;;;;;;
- ;converts an integer into a Pascal string
- ;procedure strng(num : integer; var numstr : string)
- strng proc near
- push bp
- mov bp,sp ;BP points to stack
- push bx ;preserve BX
- push di ;preserve DI
- push es ;preserve ES
- push ds ;preserve DS
- mov ax,ds ;get DS
- mov es,ax ;make ES = DS
- mov di,[bp+4] ;DI points to string
- mov dx,[bp+6] ;AX = integer to convert
- xor bx,bx ;zero BX
- new_char: mov ax,dx
- xor dx,dx ;zero DX
- mov cx,10 ;for decimal conversion
- div cx ;AX gets result
- xchg ax,dx ;swap AX and DX
- add al,30h ;convert to ascii
- push ax ;save AX
- inc bx ;bump count
- cmp dx,0 ;are we done?
- jnz new_char ;no, get another digit
- str_loop:
- pop ax ;restore AX
- stosb ;put in string
- dec bx ;dec count
- cmp bx,0 ;are we done?
- jne str_loop ;no, do again
- mov al,0 ;AL = 0
- stosb ;end of string byte
- pop ds ;restore
- pop es ; regs
- pop di ;
- pop bx ;
- pop bp ;
- ret 4
- strng endp
-
- ;;;;;;;;;;;
- ;clears the entire screen using the specified attribute
- ;procedure cls(attr : integer);
- cls proc near
- push bp
- mov bp,sp ;BP points to stack
- push bx ;preserve BX
- mov ah,7 ;code to scroll
- mov al,0 ;AL = 0 so all will be blanked
- mov bh,byte ptr[bp+4] ;attribute for scroll
- mov cx,0 ;CL = 0, CH = 0
- mov dx,184Fh ;DL = 79, DH = 24
- int 10h ;call BIOS
- pop bx ;restore BX
- pop bp
- ret 2
- cls endp
-
- ;;;;;;;;;;;;;;;;;
- ;returns current video mode
- ;function vide_mode : integer
- video_mode proc near
- push bp
- mov bp,sp ;BP points to stack
- mov ah,0Fh ;set up to get mode
- int 10h ;call BIOS
- mov ah,0 ;clear upper half
- mov 4[bp],ax ;return function result
- pop bp
- ret
- video_mode endp
-
-
- ;;;;;;;;;;;;;;;;;;
- ;if file is found, returns a 0 - returns non-zero otherwise
- ;function findfirst(var pathname : string; attr : integer) : integer
- findfirst proc near
- push bp
- mov bp,sp ;BP points to stack
- mov dx,[bp+6] ;DX points to ASCIIZ string
- mov cx,[bp+4] ;CX = file attribute
- mov ah,4Eh ;set up to find first
- int 21h ;call DOS
- jc ff_err ;carry flag set if not found
- mov ax,0 ;was found, so AX = 0
- ff_err: mov [bp+8],ax ;return function result
- pop bp
- ret 4
- findfirst endp
-
- ;;;;;;;;;;;;;;;;;;
- ;returns 0 if next find is successful, non-zero if not
- ;function findnext : integer
- findnext proc near
- push bp
- mov bp,sp ;BP points to stack
- mov ah,4Fh ;set up for find next
- int 21h ;call DOS
- jc fn_err ;carry flag set if not found
- mov ax,0 ;was found, so AX = 0
- fn_err: mov [bp+4],ax ;return function result
- pop bp
- ret
- findnext endp
-
- ;;;;;;;;;;;;;;;;;;;;;;;
- ;changes to specified drive/directory
- ;returns 0 if successful, non-zero if not
- ;function chdir(var dirname : string) : integer;
- chdir proc near
- push bp
- mov bp,sp ;BP points to stack
- push si ;must preserve SI
- mov si,[bp+4] ;SI points to dirname
- cmp byte ptr [si+1],':' ;is drive spec present
- jne no_drive ;if not, skip drive stuff
- mov dl,[si] ;yes, get drive letter
- cmp dl,65 ;is it below 'A'
- jb no_drive ;yes, skip
- cmp dl,90 ;is it above 'Z'
- ja lo_case_desig ;yes, check lower case
- sub dl,65 ;convert letter to byte
- jmp drv_ok ;continue
- lo_case_desig: cmp dl,97 ;is it below 'a'
- jb no_drive ;yes, skip
- cmp dl,122 ;is it above 'z'
- ja no_drive ;yes, skip
- sub dl,97 ;convert letter to byte
- drv_ok: mov ah,0Eh ;change drive
- int 21h ;call DOS
- cmp byte ptr [si+2],0 ;are we done?
- je are_done ;yes
- no_drive: mov dx,si ;dx points to directory
- mov ah,3Bh ;set up to change
- int 21h ;call DOS
- jc ch_err ;if err don't zero AX
- are_done: mov ax,0 ;AX = 0
- ch_err: mov [bp+6],ax ;return function result
- pop si ;restore SI
- pop bp
- ret 2
- chdir endp
-
- ;;;;;;;;;;;;;;;
- ;returns most significant byte of num
- ;function hi(num : integer) : integer;
- hi proc near
- push bp
- mov bp,sp ;BP points to stack
- mov ax,[bp+4] ;AX = num
- xchg ah,al ;swap
- mov ah,0 ;clear upper half
- mov [bp+6],ax ;return function result
- pop bp
- ret 2
- hi endp
-
- ;;;;;;;;;;;;;;;;;
- ;returns least significant byte of num
- ;functio lo(num : integer) : integer;
- lo proc near
- push bp
- mov bp,sp ;BP points to stack
- mov ax,[bp+4] ;AX = num
- mov ah,0 ;clear upper half
- mov [bp+6],ax ;return function result
- pop bp
- ret 2
- lo endp
-
- ;;;;;;;;;;;;;;;;;
- ;shifts target to the left by quantity bits
- ;function shiftl(target,bits : integer) : integer;
- shiftl proc near
- push bp
- mov bp,sp ;BP points to stack
- mov cl,byte ptr [bp+4] ;CL = bits
- mov ax,[bp+6] ;AX = target
- shl ax,cl ;shift left
- mov [bp+8],ax ;return function result
- pop bp
- ret 4
- shiftl endp
-
- ;;;;;;;;;;;;;;;;;
- ;shifts target to the right by quantity bits
- ;function shiftr(target,bits : integer) : integer;
- shiftr proc near
- push bp
- mov bp,sp ;BP points to stack
- mov cl,byte ptr [bp+4] ;CL = bits
- mov ax,[bp+6] ;AX = target
- shr ax,cl ;shift right
- mov [bp+8],ax ;return function result
- pop bp
- ret 4
- shiftr endp
-
- ;;;;;;;;;;;;;;;;;;
- ;initializes video ram address and video type variables
- ;procedure init_screen;
- init_screen proc near
- push bp
- jmp short past_data
- vid_addr dw 0B000h
- mono_box db 1
- past_data: push ds ;save DS
- push bx ;save BX
- mov ah,0Fh ;set up to get mode
- int 10h ;call BIOS
- cmp al,7 ;is it mono?
- je mc ;yes
- mov ax,0B800h ;no, set up for CGA
- mov cl,0 ;for mono_box
- jmp short continue ;and continue
- mc: mov ax,0B000h ;set up for mono
- mov cl,1 ;for mono_box
- continue: mov cs:vid_addr,ax ;save video address
- mov cs:mono_box,cl ;save the flag
- pop bx ;restore BX
- pop ds ;restore DS
- pop bp
- ret
- init_screen endp
-
- ;;;;;;;;;;;;;;;;;;;
- ;waits for horiz and vertical retrace before writing to video ram
- cga_retrace proc near
- retrace: in al,dx ;get status
- test al,8 ;check retrace
- jnz horiz ;ok - chech horiz
- rcr al,1 ;check retrace
- jc retrace ;check again
- horiz: in al,dx ;get status
- rcr al,1 ;check retrace
- jnc horiz ;test again
- store_it: ret
- cga_retrace endp
-
-
- ;;;;;;;;;;;;;;;;;;
- ;saves the video area defined by row,col, width and depth to buff
- ;procedure savebox(col,row,width,depth,buff);
- savebox proc near
- push bp
- mov bp,sp ;BP points to stack
- push ds ;save
- push es ; important
- push bx ; regs
- push di ; on
- push si ; stack
- push ss
- pop es ;ES = SS
- jmp short mc2 ;jump over data and proc
-
- s_width dw 0
- s_offset dw 0
- mc2: mov ax,cs:vid_addr ;get video address
- continue2: mov ds,ax ;put in DS
- mov di,[bp+4] ;DI points to buffer
- mov ax,[bp+10] ;AX = row
- dec ax ;normalize
- mov bx,160 ;160 bytes per row
- mul bx ;times number of rows
- mov si,ax ;SI points to video start
- mov bx,[bp+12] ;BX = col
- dec bx ;normalize
- shl bx,1 ;times 2
- mov dx,[bp+8] ;DX = width
- shl dx,1 ;times 2
- mov cs:s_width,dx ;save width
- mov cs:s_offset,160 ;save offset
- sub cs:s_offset,dx ;subtract width
- add si,bx ;add to SI
- mov cx,[bp+6] ;CX = depth
- cmp cs:vid_addr,0B000h ;mono screen?
- mov ax,8[bp] ;AX = width
- je mono9 ;yes, go to mono routine
- again9: push cx ;save CX = depth
- mov cx,[bp+8] ;CX = width
- mov dx,03DAh ;CGA port
- loop9: cli ;halt interrupts
- call cga_retrace ;wait for CGA retrace
- store9: movsw ;store the char and attribute
- sti ;restore interrupts
- loop loop9 ;do again
- pop cx ;restore CX = depth
- add si,cs:s_offset ;add the offset
- loop again9 ;and continue
- jmp y_done ;until done
- mono9: push cx ;save CX = depth
- mov cx,ax ;CX = AX = width
- rep movsw ;do it
- add si,cs:s_offset ;add the offset
- pop cx ;restore CX = depth
- loop mono9 ;do again
- y_done: pop si ;restore
- pop di ; regs
- pop bx ; from
- pop es ; the
- pop ds ; stack
- pop bp
- ret 10
- savebox endp
-
- ;;;;;;;;;;;;;;;;;;;;
- ;restores buffer to video area defined by col, row, width, and depth
- ;procedure restbox(col,row,width,depth,buff : integer)
- restbox proc near
- push bp
- mov bp,sp ;BP points to stack
- push ds ;save
- push es ; important
- push bx ; regs
- push di ; on
- push si ; stack
- mov ax,cs:vid_addr ;AX = video address
- mov es,ax ;ES = video address
- mov si,[bp+4] ;SI points to buff
- mov ax,[bp+10] ;AX = row
- dec ax ;normalize
- mov bx,160 ;160 bytes per row
- mul bx ;times number of rows
- mov di,ax ;DI points to area
- mov bx,[bp+12] ;BX = col
- dec bx ;normalize
- shl bx,1 ;times 2
- mov dx,[bp+8] ;DX = width
- shl dx,1 ;times 2
- mov cs:s_width,dx ;store width
- mov cs:s_offset,160 ;store offset
- sub cs:s_offset,dx ;DX = offset
- add di,bx ;DI points to area
- mov cx,[bp+6] ;CX = depth
- cmp cs:mono_box,1 ;mono screen?
- mov ax,[bp+8] ;AX = video segment
- je mono6 ;go to mono routine
- again6: push cx ;save CX = depth
- mov cx,[bp+8] ;CX = width
- mov dx,03DAh ;CGA port address
- loop6: cli ;turn off interrupts
- call cga_retrace ;wait for retrace
- store6: movsw ;store char and attribute
- sti ;interrupts enabled
- loop loop6 ;do again
- pop cx ;CX = depth
- add di,cs:s_offset ;add offset to DI
- loop again6 ;and do another row
- jmp x_done ;done with CGA
- mono6: push cx ;save CX = depth
- mov cx,ax ;CX = width
- rep movsw ;move all at once
- add di,cs:s_offset ;add offset to DI
- pop cx ;CX = depth
- loop mono6 ;do another row
- x_done: pop si ;restore
- pop di ; regs
- pop bx ; from
- pop es ; the
- pop ds ; stack
- pop bp
- ret 10
- restbox endp
-
- ;;;;;;;;;;;;;;;;;;;;;;;
- ;writes a string directly to video ram
- ; procedure screenwrite(col,row,attr:integer; var str : string);
- screenwrite proc near
- push bp
- mov bp,sp ;BP points to stack
- push es ;save
- push bx ; regs
- push di ; on
- push si ; stack
- mov ax,[bp+8] ;AX = row
- dec ax ;normalize
- mov bx,160 ;160 bytes per row
- mul bx ;AX = AX * 160
- mov di,ax ;DI points to video area
- mov bx,[bp+10] ;BX = col
- dec bx ;normalize
- shl bx,1 ;adjust for attr byte
- add di,bx ;DI = DI + col
- mov si,[bp+4] ;SI points to string
- mov ah,[bp+6] ;AH = attribute
- mov dx,cs:vid_addr ;DX = video segment
- cmp byte ptr cs:mono_box,1 ;mono screen?
- mov es,dx ;ES = video segment
- je sw_mono ;yes, go to mono routine
- mov dx,03dah ;CGA port address
- sw_getnext: lodsb ;AL = char
- cmp al,0 ;end of string?
- je sw_exit ;yes, exit
- mov cx,ax ;no, save AX in CX
- cli ;disable interrupts
- call cga_retrace ;wait for retrace
- sw_store: mov ax,cx ;restore AX
- stosw ;store word in video ram
- sti ;enable interrupts
- jmp sw_getnext ;get next character
- sw_mono: lodsb ;AL = next char
- cmp al,0 ;end of string?
- je sw_exit ;yes, exit
- stosw ;no, store in video ram
- jmp sw_mono ;get next character
- sw_exit: pop si ;restore
- pop di ; regs
- pop bx ; from
- pop es ; stack
- pop bp
- ret 8
- screenwrite endp
-
-
- ;;;;;;;;;;;;;;;;;;;;;
- ;moves bytes from v1addr to v2addr
- ;procedure move(v1addr,v2addr,bytes : integer);
- move proc near
- push bp
- mov bp,sp ;BP points to stack
- push es ;save
- push di ; regs
- push si ; on stack
- mov ax,ds ;AX = DS
- mov es,ax ;ES = AX = DS
- mov si,[bp+8] ;SI points to v1addr
- mov di,[bp+6] ;DI points to v2addr
- mov cx,[bp+4] ;CX number of bytes to move
- rep movsb ;mass move
- pop si ;restore
- pop di ; regs
- pop es ; from stack
- pop bp
- ret 6
- move endp
-
- ;;;;;;;;;;;;;;;;;;;;;
- ;positions cursor to col, row values
- ;procedure setxy(col,row : integer)
- setxy proc near
- push bp
- mov bp,sp ;BP points to stack
- push bx ;preserve BX
- mov bh,0 ;page is 0
- mov ah,2 ;for BIOS call to move cursor
- mov dh,[bp+4] ;DH = row
- dec dh ;normalize
- mov dl,[bp+6] ;DL = col
- dec dl ;normalize
- int 10h ;BIOS will move it
- pop bx ;restore BX
- pop bp
- ret 4
- setxy endp
-
- ;;;;;;;;;;;;;;;;;;;;;
- ;fills designated string with specified character
- ;procedure fillstr(var target : string; num,ch : integer);
- fillstr proc near
- push bp
- mov bp,sp ;BP points to stack
- push es ;save ES
- mov ax,ds ;AX = DS
- mov es,ax ;ES = AX = DS
- mov di,8[bp] ;DI points to target string
- mov cx,6[bp] ;CX = num
- cmp cx,80 ;longer than 80 char?
- jg poof ;yes, depart
- mov al,byte ptr 4[bp] ;AL = ch
- cld ;for forward move
- rep stosb ;store ch in string
- mov al,0 ;AL = 0
- stosb ;for end of string byte
- poof: pop es ;restore ES
- pop bp
- ret 6
- fillstr endp
-
- ;;;;;;;;;;;;;;;;;;;;;
- ;adds two long integers - return result in total
- ;procedure addlong(var total,n1,n2 : longint)
- addlong proc near
- push bp
- mov bp,sp
- push bx ;save
- push di ; regs
- push si ; on stack
- mov si,[bp+6] ;SI points to n1 low word
- mov di,[bp+4] ;DI points to n2 low word
- mov bx,[bp+8] ;BX points to total low word
- mov cx,2 ;CX = 2
- clc ;clear carry
- add_em: mov ax,[si] ;AX = n1
- inc si ;bump SI
- inc si ;SI now points to n1 hi word
- adc ax,[di] ;add n1 to n2
- inc di ;bump di
- inc di ;DI now points to n2 hi word
- mov [bx],ax ;store in total lo word
- inc bx ;bump bx
- inc bx ;BX now points total hi word
- loop add_em ;do again for hi word
- pop si ;restore
- pop di ; regs
- pop bx ; from stack
- pop bp
- ret 6
- addlong endp
-
-
- ;;;;;;;;;;;;;;;;;;;;
- ;converts a long integer into a string;
- ;procedure longstr( var long : longint; var str : longstr)
- longstr proc near
- push bp
- mov bp,sp ;BP points to stack
- push ds ;save
- push es ; regs
- push bx ; on
- push si ; the
- push di ; stack
- jmp over_dat ;skip over data
- temp_buff db 5 dup(0)
- lstr db 12 dup(0)
- over_dat: cld ;set direction to forward
- mov ax,ds ;AX = DS
- push ax ;save AX, we need DS later
- mov bx,[bp+6] ;BX points to long low word
- mov dx,[bx+2] ;DX points to long hi word
- mov bx,[bx] ;BX = long low word
- mov ax,cs ;AX = CS
- mov ds,ax ;DS = AX = CS
- mov es,ax ;ES = AX = CS
- lea di,temp_buff ;DI points to buffer
- mov cx,5 ;CX = 5 (for 10 digits)
- mov al,0 ;AL = 0
- clear: stosb ;store a 0
- loop clear ;fill buffer with zeros
- mov cx,32 ;
- test dx,8000h ;is low word negative?
- jz no_neg ;no, skip code
- not dx ;DX = -DX
- not bx ;BX = -BX
- add bx,1 ;BX = BX + 1
- adc dx,0 ;adjust for carry
- no_neg: std ;set direction to back
- l_loop: push cx ;save counter
- mov cx,5 ;five bytes=10 digits
- lea si,temp_buff ;SI points to buffer
- add si,4 ;SI points to buffer end
- mov di,si ;DI = SI
- shl bx,1 ;grab a bit
- rcl dx,1 ;and then rotate
- adjust: lodsb ;load AL with byte
- adc al,al ;add carry
- daa ;decimal adjust
- stosb ;store in temp_buff
- loop adjust ;keep going
- pop cx ;restore counter
- loop l_loop ;and do again
- cld ;set flag to forward
- lea di,lstr ;DI points to lstr
- xor dx,dx ;DX = 0
- lea si,temp_buff ;SI points to buffer
- mov cx,10 ;CX = 10 characters
- xor bx,bx ;BX = 0
- x_str: test cx,1 ;high or low?
- jnz y_str ;low
- lodsb ;AL = char
- mov ah,al ;AH = AL
- push cx ;save CX
- mov cl,4 ;CL = 4
- shr al,cl ;shift AL right 4
- pop cx ;restore CX
- jmp z_str ;do a character
- y_str: mov al,ah ;low part
- and al,0Fh ;and it
- z_str: test al,0Fh ;is it zero?
- jnz w_str ;no
- or bx,bx ;a leading zero
- jz l_next ;no
- w_str: inc bx ;BX has length
- or al,'0' ;AL = ASCII char
- stosb ;store in string
- l_next: loop x_str ;continue
- add bx,dx ;add 0
- jnz l_done ;are we done?
- inc bx ;bump length
- mov al,'0' ;make 0
- stosb ;store it
- l_done: cld ;back to forward
- mov byte ptr [di],0 ;end of string byte
- pop ax ;restore AX
- mov es,ax ;ES = DS
- lea si,lstr ;SI points to lstr
- mov di,[bp+4] ;DI points to str
- mov cx,12 ;we'll move all
- rep movsb ;move them
- pop di ;restore
- pop si ; regs
- pop bx ; from
- pop es ; the
- pop ds ; stack
- pop bp
- ret 4
- longstr endp
-
-
- ;;;;;;;;;;;;;;;
- ;hides the cursor
- hide_cursor proc near
- mov ah,1 ;cursor size function
- mov ch,20h ;set it to 20h
- int 10h ;BIOS does it
- ret
- hide_cursor endp
-
- ;;;;;;;;;;;;;;;
- ;saves the DOS cursor for later restoration
- save_cursor proc near
- jmp get_it ;jump past data
- save_curs dw 0
- get_it: mov ah,3 ;get cursor size function
- mov bh,0 ;page is 0
- int 10h ;BIOS does it
- mov cs:save_curs,cx ;CX has size - save it
- ret
- save_cursor endp
-
- ;;;;;;;;;;;;;;;
- ;restores the saved DOS cursor
- rest_cursor proc near
- mov cx,cs:save_curs ;retrieve cursor size
- mov ah,1 ;set cursor size function
- int 10h ;BIOS does it
- ret
- rest_cursor endp
-
-
- toolcode ends
- end
-