I use a program I wrote that drops in frequently used functions. I am separating this into numbered sections.
Eric has put some facility in A86 to do the same but I have never used it. You may want to try it.
tl macro
db 13,"A86: " ;CR
db #1 ;Get title line
#em
main: jmp buffer ;Begin in Overwrite area
start1: tl "Adulterate Characters"
| 1 |
;Sun 07-21-2002 Updated better from keyboard. ;New version typed in Mon 12-10-2001 Old ADULT.8 lost ;BP holds Translate Table starting address | 2 |
CR equ 0d
LF equ 0a
command equ 080 ;parameter location
db cr,lf,lf
db ' | 3 |
testx equ 0 ;1=read from X, 0=filter
quit: ret
;Make a do nothing TT
first: stosb ;Creating Trans Table
inc al
loop first
mov dx,di ;[DX]=input/output
;Set up to process parameters
mov si,080
lodsb ;AL=length
mov cx,ax ;CX=bytes in parameter
jcxz quit
t1: lodsb
cmp al,' ' ;Skip spaces
loope t1
inc cx ;bypassing extra loop
shr cx,1 ;account for words
;Modify TT as specified by the user
| 4 |
db 03c ;CMP AL, kill next byte
| 5 |
t1: lodsb
mov bl,al ;Use first for index into TT
lodsb ;Get replacement Character
mov [bx+0111],al ;Store in TT
plant equ w($-2) ;to fix above offset to BX
loop t1
;Now we can do the work
t2: xor bx,bx ;BX=0 to read StdIn
| 6 |
;Read File [bx]=handle into buffer at [dx]
mov cx,dx ;[DX]=Input area
not cx ;CX=Rest of the segment
mov ah,03f ;DOS file read function
int 021
mov cx,ax ;CX=number of bytes input
jcxz quit
mov si,dx ;SI=Input
mov di,dx ;DI=Output
mov bx,bp ;[BX]=Tran Table
t1: lodsb ;Get input
xlat ;translate it
stosb ;put it back
loop t1 ;Repeat for all input
mov bx,1 ;1=Handle for StdOut
| 7 |
;Write buffer to [bx] handle from [dx] to [di]
mov cx,di ;write main stuff
sub cx,dx ;(dx)=start of buffer
jz >l1
mov ah,040 ;Write to file/device
int 021 ;call DOS
cmp ax,cx ;write error?
jne we
l1:
| 8 |
jmp t2 | 9 |
m1: db cr,lf,'Write error, disk full?',0
we: mov si,m1 ;? disk full
;Must fall into ED
;Error Display
ed: mov al,7 ;bell code
call edo+1
mov ax,04c01 ;set errorlevel to 1
int 21h ;exit to DOS
;procedure to do error output of a string
edo: lodsb ;get initial cahracter
xor bx,bx ;clear color stuff
l1: mov ah,14 ;ROM-BIOS TTY service
int 010
lodsb
or al,al ;? done
jne l1
ret
| 10 |
;Begin Overlay area, and first executed code
#if testx
even 0100 ;for easy debug
buffer: cld ;start clean
#else
;performe a sum check, hang if fails
even
buffer: cld ;start clean
mov cx,(zend-main+2) shr 1
mov si,0100 ;start of .COM file
xor bx,bx ;clear total
l1: lodsw
add bx,ax
loop l1
or bx,bx
jnz buffer ;loop to hang
#endif
;Move Stack to higher Segment
pop dx ;Bump SP & get zero
mov ax,cs ;get Code Segment
add ah,010 ;bump to next 64K
mov ss,ax ;Move Stack Segment
push dx ;Zero on top
| 11 |
mov dx,buffer ;DX=Overlay location
mov [plant],dx ;point mov inst to TT
mov cx,0100 ;CX=length of TT
mov di,dx ;Use DI to build
mov bp,dx
;BX is left at zero by the sum check
xor ax,ax
jmp first ;go do it.
| 12 |
even
zend: dw 0 ;Sum check word
| 13 |
I do with four of my "boiler plate" drop ins: They are to create:
main: jmp buffer
For reasons not obvious, with A86 I had to create a macro "TL" and
then use it latter to put the CR (decimal value 13) and the program
Title out. This is at the label: "start1:"
Generally in my programs you can use the DOS type command to display some help text. What is displayed is in the db lines. You will notice this starts with a CR Not followed by an LF. This is to cover up the two or three bytes of the jmp instruction.
A copyright note, the Assembly Date, and how to contact me are also put in by these routines. This "text" is terminated with a Ctrl-Z which will terminate the type command. A convention inherited from CPM, which ran on Intel 8080 based computers,
testx is used later in conditional logic.
Debugging is easier when the input is from a file I use the name X. After it works I change the value of "testx" to make it read from Standard In.
First: is where control goes after some one-time initialization which is done in the buffer. The more of the program that gets over written, the larger the buffer is!
A "do nothing" translate table just translates everything into itself. This gets modified by parameters from the command line.
The parameters are picked up from location 080 and the program stops if the parameter length is zero. First it has to skip any leading spaces.
Life gets tricky here! The first non-space character is in AL so I
don't want to execute the lodsb instruction, so I could have
jumped around it, but 5 is a useful trick for which there is not an
assembly pneumonic. On the first time through it kills the following one
byte instruction.
Another trick: The mov bl instruction gets modified in the initialization code. Some consider instruction modification pornographic. I like it, because it is faster! But some day caching or pipelining may cause it to fail.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
11 is at the end of the program where the buffer starts. I put the one time initialization code in the buffer area.
It is here where "testx" is checked to determine if the program has
been corrupted. Another of my programs:fsum (For Fix SUMcheck) is
used from a .BAT file to make the entire program sum to zero. You do not
have "fsum" so you must kill this code for the present. This
could be done by replacing the jnz buffer that occurs right
before the "endif" with
I feel that virtually every computer that will run my programs has a lot of memory, so as standard procedure I move the stack to a second segment. In the good old DOS days I never used to do this
This is the startup code specific to this program.
Boiler Plate to make space for "fsum" to make the entire program sum to zero.
That's it folks.
To make it easier you can click here to get a clean copy of "adult.8" but it will come as "adult.txt" and you must then rename it before you assemble it. But unless you have and use: fsum.com you should remove everything in section 11 before moving the stack except: buffer: cld. You could also keep the even to make buffer: be word aligned.This has been short and quick. I hope I have encouraged you to try Assembly Language programming. Please contact me if you think this has been useful and would like more "samples".