First commit 06/07/1996
This commit is contained in:
commit
bf4bcbd4f8
BIN
CDS/EJE1.COM
Normal file
BIN
CDS/EJE1.COM
Normal file
Binary file not shown.
43
CDS/EJEMPLO1.ASM
Normal file
43
CDS/EJEMPLO1.ASM
Normal file
@ -0,0 +1,43 @@
|
||||
segmento SEGMENT para PUBLIC 'CODE'
|
||||
ASSUME DS:segmento, CS:segmento
|
||||
ORG 100h
|
||||
principal PROC NEAR
|
||||
|
||||
call Borra
|
||||
|
||||
mov ah, 02h
|
||||
mov dh, 11
|
||||
mov dl, 30
|
||||
mov bh, 00h
|
||||
int 10h
|
||||
|
||||
mov ah, 09h
|
||||
mov dx, OFFSET MensajeSaludo
|
||||
int 21h
|
||||
|
||||
mov ah, 00h
|
||||
int 16h
|
||||
|
||||
call Borra
|
||||
|
||||
mov ah, 4ch
|
||||
int 21h
|
||||
|
||||
principal ENDP
|
||||
|
||||
Borra PROC NEAR
|
||||
|
||||
mov ax, 0600h
|
||||
mov bh, 07h
|
||||
mov cx, 0000h
|
||||
mov dx, 184fh
|
||||
int 10h
|
||||
|
||||
ret
|
||||
|
||||
Borra ENDP
|
||||
|
||||
MensajeSaludo DB 'Hola Mundo!$'
|
||||
|
||||
segmento ENDS
|
||||
END principal
|
BIN
CDS/EJEMPLO1.EXE
Normal file
BIN
CDS/EJEMPLO1.EXE
Normal file
Binary file not shown.
8
CDS/EJEMPLO1.MAP
Normal file
8
CDS/EJEMPLO1.MAP
Normal file
@ -0,0 +1,8 @@
|
||||
|
||||
Start Stop Length Name Class
|
||||
|
||||
00000H 00139H 0013AH SEGMENTO CODE
|
||||
|
||||
Program entry point at 0000:0100
|
||||
Warning: No stack
|
||||
|
55
CDS/EJEMPLO2.ASM
Normal file
55
CDS/EJEMPLO2.ASM
Normal file
@ -0,0 +1,55 @@
|
||||
segmento SEGMENT
|
||||
ASSUME DS:segmento
|
||||
ORG 100h
|
||||
principal PROC NEAR
|
||||
|
||||
call Borra
|
||||
|
||||
mov ah, 02h
|
||||
mov dh, 11
|
||||
mov dl, 30
|
||||
mov bh, 00h
|
||||
int 10h
|
||||
|
||||
mov ah, 09h
|
||||
mov dx, OFFSET MensajeSaludo
|
||||
int 21h
|
||||
|
||||
mov ah, 00h
|
||||
int 16h
|
||||
|
||||
call Borra
|
||||
|
||||
mov ah, 4ch
|
||||
int 21h
|
||||
|
||||
principal ENDP
|
||||
|
||||
Borra PROC NEAR
|
||||
|
||||
push ax ; Se almacenan en la pila los registros que va a utilizar
|
||||
push bx ; la subrutina. El valor de SP disminuye en 4 * 2 = 8
|
||||
push cx ; unidades
|
||||
push dx
|
||||
|
||||
mov ax, 0600h ; Se borra la pantalla
|
||||
mov bh, 07h
|
||||
mov cx, 0000h
|
||||
mov dx, 184fh
|
||||
int 10h
|
||||
|
||||
pop dx ; Se recuperan los valores de los registros, de forma que
|
||||
pop cx ; al volver el control de la ejecuci¢n al m¢dulo principal
|
||||
pop bx ; ‚stos almacenen los valores que pose¡an antes de la
|
||||
pop ax ; llamada al procedimiento. SP se incrementa en 4 * 2 = 8
|
||||
; unidades
|
||||
|
||||
ret
|
||||
|
||||
Borra ENDP
|
||||
|
||||
MensajeSaludo DB 'Hola Mundo!$'
|
||||
|
||||
segmento ENDS
|
||||
END principal
|
||||
|
BIN
CDS/EJEMPLO2.COM
Normal file
BIN
CDS/EJEMPLO2.COM
Normal file
Binary file not shown.
110
CDS/EJEMPLO3.ASM
Normal file
110
CDS/EJEMPLO3.ASM
Normal file
@ -0,0 +1,110 @@
|
||||
segmento SEGMENT
|
||||
ASSUME DS:segmento
|
||||
ORG 100h
|
||||
principal PROC NEAR
|
||||
|
||||
mov ax, OFFSET Cadena1
|
||||
push ax
|
||||
mov al, 1eh
|
||||
push ax
|
||||
|
||||
call VerCadena
|
||||
|
||||
mov ah, 00h ; Se acepta una tecla
|
||||
int 16h
|
||||
|
||||
mov ax, OFFSET Cadena2
|
||||
push ax
|
||||
mov al, 21h
|
||||
push ax
|
||||
|
||||
call VerCadena
|
||||
|
||||
mov ah, 00h ; Se acepta una tecla
|
||||
int 16h
|
||||
|
||||
mov ax, OFFSET Cadena3
|
||||
push ax
|
||||
mov al, 34h
|
||||
push ax
|
||||
|
||||
call VerCadena
|
||||
|
||||
mov ah, 00h ; Se acepta una tecla
|
||||
int 16h
|
||||
|
||||
mov ax, OFFSET Cadena4
|
||||
push ax
|
||||
mov al, 42h
|
||||
push ax
|
||||
|
||||
call VerCadena
|
||||
|
||||
mov ah, 00h ; Se acepta una tecla
|
||||
int 16h
|
||||
|
||||
mov ax, OFFSET Fin
|
||||
push ax
|
||||
mov al, 07h
|
||||
push ax
|
||||
|
||||
call VerCadena
|
||||
|
||||
mov ah, 00h ; Se acepta una tecla
|
||||
int 16h
|
||||
|
||||
mov ah, 4ch
|
||||
int 21h
|
||||
|
||||
principal ENDP
|
||||
|
||||
VerCadena PROC NEAR
|
||||
|
||||
push bp
|
||||
mov bp, sp
|
||||
|
||||
push bx ; Se almacenan en la pila los registros que va a utilizar
|
||||
push cx ; la subrutina. El valor de SP disminuye en 3 * 2 = 6
|
||||
push dx ; unidades
|
||||
; Por otro lado, cuando se sabe que el registro AX es el
|
||||
; empleado para pasar los par metros, no es necesario
|
||||
; salvarlo
|
||||
|
||||
|
||||
mov ax, 0600h ; Se borra la pantalla empleando el atributo
|
||||
mov bh, [bp+4] ; pasado como par metro mediante el registro AL,
|
||||
mov cx, 0000h ; almacenado ahora en la pila y recuperado con
|
||||
mov dx, 184fh ; la instrucci¢n MOV BH, [BP+4]
|
||||
int 10h
|
||||
|
||||
mov ah, 02h ; Se posiciona el cursor en (25,11)
|
||||
mov bh, 00h
|
||||
mov dh, 11
|
||||
mov dl, 25
|
||||
int 10h
|
||||
|
||||
mov ah, 09h
|
||||
mov dx, [bp+6] ; El desplazamiento de la cadena que se va a visualizar
|
||||
int 21h ; se mueve a DX
|
||||
|
||||
pop dx ; Se recuperan los valores de los registros, de forma que
|
||||
pop cx ; al volver el control de la ejecuci¢n al m¢dulo principal
|
||||
pop bx ; ‚stos almacenen los valores que pose¡an antes de la
|
||||
; llamada al procedimiento. SP se incrementa en 3 * 2 = 6
|
||||
; unidades
|
||||
|
||||
pop bp ; Se restaura BP
|
||||
|
||||
ret 4
|
||||
|
||||
VerCadena ENDP
|
||||
|
||||
Cadena1 DB 'Primera cadena que se visualiza$'
|
||||
Cadena2 DB 'Segunda cadena que se visualiza$'
|
||||
Cadena3 DB 'Tercera cadena que se visualiza$'
|
||||
Cadena4 DB 'Cuarta cadena que se visualiza$'
|
||||
Fin DB 'Fin del programa ejemplo$'
|
||||
|
||||
segmento ENDS
|
||||
END principal
|
||||
|
BIN
CDS/EJEMPLO3.COM
Normal file
BIN
CDS/EJEMPLO3.COM
Normal file
Binary file not shown.
61
CDS/EJEMPLO4.ASM
Normal file
61
CDS/EJEMPLO4.ASM
Normal file
@ -0,0 +1,61 @@
|
||||
segmento SEGMENT
|
||||
ASSUME DS:segmento
|
||||
ORG 100h
|
||||
principal PROC NEAR
|
||||
|
||||
mov ax, Numero
|
||||
push ax
|
||||
mov ax, OFFSET Producto
|
||||
push ax
|
||||
|
||||
call Multiplica
|
||||
|
||||
mov ah, 4ch
|
||||
int 21h
|
||||
|
||||
principal ENDP
|
||||
|
||||
Multiplica PROC NEAR
|
||||
|
||||
push bp ; se salva BP
|
||||
mov bp, sp ; se hace que BP apunte a la zona de par metros
|
||||
sub sp, 2 ; se crea espacio para una variable local de 2 bytes
|
||||
push si ; se salva SI
|
||||
|
||||
mov si, [bp+4] ; se mueve a SI el desplazamiento del campo resultado
|
||||
mov ax, [bp+6] ; se mueve a AX el n£mero que va a ser multiplicado por 9,5
|
||||
|
||||
shr ax, 1 ; se divide el n£mero entre 2
|
||||
mov [bp-2], ax ; se guarda el resultado en la variable local
|
||||
|
||||
mov ax, [bp+6] ; se mueve a AX de nuevo el n£mero que va a ser multiplicado por 9,5
|
||||
|
||||
shl ax, 1 ; se multiplica AX por 8 por el m‚todo de los desplazamientos
|
||||
shl ax, 1
|
||||
shl ax, 1
|
||||
|
||||
add ax, [bp+6] ; se suma el resultado de la multiplicaci¢n con el
|
||||
; n£mero para obtener el producto de ‚ste por 9
|
||||
|
||||
add ax, [bp-2] ; se suma la mitad del n£mero original al resultado de
|
||||
; multiplicar por 9
|
||||
|
||||
mov [si], ax ; se mueve al campo resultado
|
||||
|
||||
pop si ; se recupera el valor inicial de SI
|
||||
|
||||
mov sp, bp ; se elimina la variable local
|
||||
|
||||
pop bp ; se recupera el valor inicial de BP
|
||||
|
||||
ret 4 ; finaliza el proceso restaurando la pila
|
||||
|
||||
Multiplica ENDP
|
||||
|
||||
|
||||
Numero WORD 1000h
|
||||
Producto WORD ?
|
||||
|
||||
segmento ENDS
|
||||
END principal
|
||||
|
BIN
CDS/EJEMPLO4.COM
Normal file
BIN
CDS/EJEMPLO4.COM
Normal file
Binary file not shown.
395
E/ASM.DOC
Normal file
395
E/ASM.DOC
Normal file
@ -0,0 +1,395 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
THE ARROWSOFT ASSEMBLER
|
||||
|
||||
Public Domain Version 1.00D
|
||||
|
||||
|
||||
User's Guide
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
The Arrowsoft Assembler Program and Manual are both
|
||||
Copyright (C) 1986 by Arrowsoft Systems, Inc.
|
||||
554 West Sixth Avenue
|
||||
Larkview, MO 66069
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Arrowsoft Assembler v1.00 User's Guide
|
||||
|
||||
|
||||
INTRODUCTION
|
||||
|
||||
Thank you for trying out the public domain version of our
|
||||
Arrowsoft Assembler. We feel that the best way to alert you, the
|
||||
programmer, to our fine line of professional products is to let
|
||||
you use one. Once you have experienced the high quality and ease
|
||||
of use of this free product, we hope that you will contact us
|
||||
regarding our other software (our address is on the cover of this
|
||||
manual).
|
||||
|
||||
You will no doubt notice that this manual is not exhaustive; in
|
||||
fact, it includes the least amount of information we felt we
|
||||
could include without robbing the program of its usefulness.
|
||||
There are two reasons for the brevity of this manual: First, we
|
||||
have targeted professional software developers with our products,
|
||||
and we suspect that an experienced professional will have no
|
||||
trouble figuring out how to use the Arrowsoft Assembler with the
|
||||
information given; second, the program is, after all, free and we
|
||||
feel that the quality of this assembler will more that compensate
|
||||
you for the time you spend learning to use it.
|
||||
|
||||
Please note that this is NOT a supported product. If you contact
|
||||
us, we will be happy to discuss our line of software but we will
|
||||
NOT answer questions about the Arrowsoft Assembler.
|
||||
|
||||
Again, we thank you for giving our product a try.
|
||||
|
||||
(NOTE: 'Microsoft' and 'Microsoft Macro Assembler' are trademarks
|
||||
of Microsoft Corporation. 'Arrowsoft', 'Arrowsoft Professional
|
||||
Assembler' and 'Super Link' are trademarks of Arrowsoft Systems,
|
||||
Inc.)
|
||||
|
||||
|
||||
|
||||
OVERVIEW
|
||||
|
||||
The Arrowsoft Assembler takes as its input 8086, 8088, 80186 and
|
||||
80286 assembly language source files and produces relocatable
|
||||
object modules which may be linked and run under the MS-DOS and
|
||||
PC-DOS operating systems. The syntax of the input files is a
|
||||
superset of that accepted by the Microsoft Macro Assembler
|
||||
(versions 3.0 and later). In fact, most programs written for the
|
||||
Microsoft product should assemble without modification with the
|
||||
Arrowsoft Assembler.
|
||||
|
||||
The remaining sections of this manual will cover, in this order,
|
||||
assembler command line options, input language specifications,
|
||||
linking and execution of assembled object modules, and assembler
|
||||
error messages.
|
||||
|
||||
|
||||
|
||||
INVOKING THE ARROWSOFT ASSEMBLER
|
||||
|
||||
You may run the Arrowsoft Assembler interactively or directly
|
||||
from the DOS command line. To invoke the assembler
|
||||
interactively, simply type
|
||||
|
||||
|
||||
|
||||
-1-
|
||||
|
||||
|
||||
Arrowsoft Assembler v1.00 User's Guide
|
||||
|
||||
|
||||
asm
|
||||
|
||||
at the DOS prompt and follow the ensuing instructions. To run
|
||||
the assembler non-interactively, use the following syntax:
|
||||
|
||||
asm source [,object] [,list] [,xref] [options] [;]
|
||||
|
||||
where 'source' is a filespec for the source file (default
|
||||
extension .ASM), 'object' is a filespec for the object file
|
||||
(default extension .OBJ), 'list' is a filespec for the listing
|
||||
file (default extension .LST) and 'xref' is a filespec for the
|
||||
cross-reference file (default extension .CRF). Note that all
|
||||
filespecs may consist of a drive letter, a pathname, a filename
|
||||
and an extension. If the object file is not specified, the
|
||||
assembler will use the source filename with the .OBJ extension.
|
||||
If the list and cross-reference files are not specified, the
|
||||
assembler will not produce them. Finally, the semicolon (;) will
|
||||
force the assembler to assume default values for any unspecified
|
||||
parameters.
|
||||
|
||||
|
||||
|
||||
OPTION CODES
|
||||
|
||||
The options list consists of a sequence of option codes. These
|
||||
option codes consist of a slash (/) or dash (-) followed by one
|
||||
or more letters, case being insignificant. Most of these options
|
||||
are compatible with Microsoft conventions.
|
||||
|
||||
/A Write segments in alphabetical order
|
||||
/Bnumber Set buffer size
|
||||
/Dsymbol Define assembler symbol
|
||||
/E Generate 8087/80287 emulator code
|
||||
/Ipath Set 'include' search path
|
||||
/ML Case sensitive internal labels
|
||||
/MX Case sensitive external and public labels
|
||||
/MU Convert labels to uppercase
|
||||
/R Generate 8087/80287 floating point code
|
||||
/S Write segments in source code order
|
||||
/X Include false conditionals in listing
|
||||
/Z Display error lines on screen
|
||||
|
||||
|
||||
Many of these command line options are self explanatory; for
|
||||
whose which aren't, see the descriptions below:
|
||||
|
||||
|
||||
/B Set Buffer Size
|
||||
|
||||
Sets the size of the buffer used to hold the source file during
|
||||
assembly. The 'number' is the number of 1K pages reserved for
|
||||
use as a buffer. You may set the buffer size to any value
|
||||
between 1K and 63K; default buffer size is 32K. Note that a
|
||||
larger buffer can speed assembly of large files considerably.
|
||||
|
||||
|
||||
/E Generate 8087/80287 Emulator Code
|
||||
|
||||
|
||||
|
||||
-2-
|
||||
|
||||
|
||||
Arrowsoft Assembler v1.00 User's Guide
|
||||
|
||||
|
||||
If you are writing programs for use with the 8087/80287 numeric
|
||||
processor on a machine which does not have the processor, and you
|
||||
have an 8087/80287 emulator library available, the /E option
|
||||
directs the assembler to generate code for the emulator.
|
||||
|
||||
|
||||
/I Set 'include' file search paths
|
||||
|
||||
You may direct the assembler to search up to 5 directories for
|
||||
'include' files by including a '/Ipath' command for EACH of
|
||||
them. For example, to set the search paths '\bin\lib' and
|
||||
'\asm\lib', include the following in your options list:
|
||||
/I\bin\lib/I\asm\lib.
|
||||
|
||||
|
||||
/R
|
||||
|
||||
This option directs the assembler to generate floating point code
|
||||
for the 8087/80287 numeric processor. Note that programs
|
||||
assembled with the '/R' option will run ONLY on machines which
|
||||
have an 8087/80287 installed.
|
||||
|
||||
|
||||
|
||||
ARROWSOFT ASSEMBLY LANGUAGE
|
||||
|
||||
As we mentioned earlier, the Arrowsoft Assembly Language is a
|
||||
superset of the well-known Microsoft Macro Assembler Language. We
|
||||
modeled our system after Microsoft's for two reasons: First, the
|
||||
language has a flexible and moderately powerful macro facility;
|
||||
second, and for this public domain project most important, there
|
||||
is a plethora of third-party books which explain how to program
|
||||
using the Microsoft product. We recommend that you purchase one
|
||||
of these guides if you are not familiar with 8086 assembly
|
||||
language. If you would like to take advantage of the many
|
||||
extensions to the Microsoft Language we have implemented in the
|
||||
Arrowsoft Assembler, you must do one of two things: Try to figure
|
||||
them out for yourself (using experimentation, disassembly or
|
||||
anything else you can think of); or you can contact us about
|
||||
purchasing the Arrowsoft Professional Assembler, which includes
|
||||
the complete documentation. Again, please DO NOT CALL us about
|
||||
the Arrowsoft Assembler; we will not answer any questions or
|
||||
provide clues as to how to access the assembler's advanced
|
||||
features.
|
||||
|
||||
|
||||
|
||||
LINKING AND EXECUTING ARROWSOFT OBJECT MODULES
|
||||
|
||||
The Arrowsoft Assembler produces relocatable object modules which
|
||||
are compatible with the Microsoft 8086 Object Linker (versions
|
||||
3.0 and later). This means that programs assembled by the
|
||||
Arrowsoft Assembler may be linked with other Microsoft
|
||||
Linker-compatible programs generated by other assemblers and
|
||||
compilers. If you need more information on how to use the
|
||||
Microsoft 8086 Object Linker, see your DOS or Microsoft language
|
||||
manual.
|
||||
|
||||
|
||||
|
||||
-3-
|
||||
|
||||
|
||||
Arrowsoft Assembler v1.00 User's Guide
|
||||
|
||||
|
||||
By the way, we would like you to know about Arrowsofts Super Link
|
||||
8086/8086 Object Link Utility. Super Link is a full-service
|
||||
overlaying linker which is fully compatible with the Microsoft
|
||||
8086 Object Linker, yet much faster and far more versatile.
|
||||
Contact us at the address on the cover of this manual for more
|
||||
information.
|
||||
|
||||
|
||||
|
||||
ASSEMBLER ERROR MESSAGES
|
||||
|
||||
An Arrowsoft Assembler error report consists of three parts: A
|
||||
source file line number, an error number and a terse error
|
||||
description. In most cases, the error messages, in spite of
|
||||
their brevity, are self explanatory. However, for those few
|
||||
messages which require addtional elaboration, we offer the
|
||||
following explanations:
|
||||
|
||||
|
||||
2 Internal error
|
||||
|
||||
This message will appear only if an error occurred within the
|
||||
assembler itself. If you see this message, please send an
|
||||
assembly listing of the source file and any other relevant
|
||||
information (DOS version, assembler version, etc.) to the address
|
||||
on the cover of this manual.
|
||||
|
||||
|
||||
68 Can't reach with segment reg
|
||||
|
||||
You have not issued the appropriate ASSUME directive.
|
||||
|
||||
|
||||
99 Line too long expanding <symbol>
|
||||
|
||||
Expanding an EQU-defined symbol would result in a line too long
|
||||
for the assembler to handle. Check for inadvertent recursion in
|
||||
the symbol.
|
||||
|
||||
|
||||
Out of Memory
|
||||
|
||||
Either the source file exceeds the 64K limit of the assembler or
|
||||
the symbol table exceeds its allocation. If this condition
|
||||
occurs, try assembling without creating list or cross-reference
|
||||
files. If this doesn't work, try dividing your source code into
|
||||
several smaller source files and assembling them separately. The
|
||||
resulting code may then be linked with a link utility. (Again,
|
||||
we can't resist pointing out that the Arrowsoft Professional
|
||||
Assembler uses ALL available memory for the assembly process; in
|
||||
fact, it will assemble a file of arbitrary size, regardless of
|
||||
memory limitations.)
|
||||
|
||||
|
||||
Internal Error
|
||||
|
||||
See the explanation for error number 2 above.
|
||||
|
||||
|
||||
|
||||
-4-
|
||||
|
||||
|
||||
Arrowsoft Assembler v1.00 User's Guide
|
||||
|
||||
|
||||
|
||||
|
||||
THE ARROWSOFT PROFESSIONAL ASSEMBLER
|
||||
|
||||
Our real reason for giving you this program free of charge is to
|
||||
encourage you to purchase our commercial product, the Arrowsoft
|
||||
Professional Assembler. The program you have now differs from the
|
||||
full program in only three respects: (1) It includes no
|
||||
documentation for those language features which extend the
|
||||
Microsoft Macro Assembly Language (although they are implemented
|
||||
by the public domain version); (2) the maximum input file size is
|
||||
limited to 64K bytes; and (3) it is not supported via our 24 hour
|
||||
toll-free help line (in fact, it is not supported at all by us).
|
||||
With these 3 exceptions, the program you now have is identical to
|
||||
the Professional Assembler.
|
||||
|
||||
If you decide you'd like to purchase the Arrowsoft Professional
|
||||
Assembler, send a postcard requesting our catalog to the address
|
||||
on the cover of this manual. Our catalog will show you our
|
||||
entire line of professional software development products and
|
||||
will convince you that our quality and prices are as competitive
|
||||
as you will find anywhere.
|
||||
|
||||
|
||||
|
||||
CONCLUDING REMARKS AND CREDITS
|
||||
|
||||
Again, we would like to thank you for trying our product. We
|
||||
hope that the remarks we've made concerning our programming
|
||||
products (Arrowsoft Professional Assembler and Super Link 8086
|
||||
Object Linker) have piqued your curiosity enough that you'll
|
||||
write to us for more information. Further, we hope that actually
|
||||
using one of our products has convinced you of our dedication to
|
||||
quality and performance. Finally, we hope to welcome you to our
|
||||
growing family of satisfied customers.
|
||||
|
||||
Even if you don't buy anything from us, you can do us a favor.
|
||||
We want you to distribute this product to all of your friends by
|
||||
any means possible. You may post it to bulletin boards, offer it
|
||||
through your computer club or just copy it and pass it around.
|
||||
We only ask that (1) you charge nothing for the software beyond
|
||||
reasonable copying and disk costs and (2) that you distribute the
|
||||
two files (ASM.EXE and ASM.DOC) together and without
|
||||
modification.
|
||||
|
||||
The Arrowsoft Assembler was written by Kaplan 'Kap' Morovitz and
|
||||
tested by the programming staff at Arrowsoft. Since 'Kap' writes
|
||||
only in assembly language and C, this manual was written by Stan
|
||||
Goldwyn-Benton.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
-5-
|
||||
|
||||
|
8
E/M.MAP
Normal file
8
E/M.MAP
Normal file
@ -0,0 +1,8 @@
|
||||
|
||||
Start Stop Length Name Class
|
||||
|
||||
00000H 0001EH 0001FH PRIMERO CODE
|
||||
|
||||
Program entry point at 0000:0000
|
||||
Warning: No stack
|
||||
|
195
LETC.CPP
Normal file
195
LETC.CPP
Normal file
@ -0,0 +1,195 @@
|
||||
#include <conio.h>
|
||||
|
||||
void Letrero(int AX_register );
|
||||
char mi_estruct[] = "Esto solo es una prueba, de mi primer programa en Assembly JD $ 000018000000000000";
|
||||
|
||||
long dir_fuentes;
|
||||
|
||||
|
||||
void main( void )
|
||||
{
|
||||
|
||||
|
||||
Letrero( 1 );
|
||||
|
||||
while( !kbhit() )
|
||||
Letrero( 0 );
|
||||
|
||||
}
|
||||
|
||||
|
||||
void Letrero(int AX_register )
|
||||
{
|
||||
|
||||
asm{
|
||||
|
||||
push DS
|
||||
mov AX, SEG mi_estruct
|
||||
mov DS, AX
|
||||
mov SI, OFFSET mi_estruct
|
||||
|
||||
mov AX, AX_register
|
||||
|
||||
|
||||
//; Funci¢n para generar un letrero digital 100 % ASM
|
||||
//;
|
||||
//; Entradas:
|
||||
//; SI ptr a las estructura de datos 256 bytes
|
||||
//;
|
||||
//; 237 cadena a mostrar en el letrero: el final es $
|
||||
//; 2 posici¢n X
|
||||
//; 2 posici¢n Y
|
||||
//; 1 (1nibble Escala X | 2nibble Escala Y )
|
||||
//; 1 n£mero de d¡gitos a mostrar en pantalla
|
||||
//; 1 color de fondo
|
||||
//; 1 color principal
|
||||
//; -----------------------------------------------
|
||||
//; 1 posici¢n dentro de la cadena
|
||||
//; 1 posici¢n en el byte
|
||||
//; 8 FUTURA AMPLIACIàN
|
||||
//;
|
||||
//; AX si 1, inicializa nuestra informacion
|
||||
//;
|
||||
|
||||
//; letrero_digital PROC near //;--------------------------------------------
|
||||
|
||||
cmp AX, 1 //; si no hay que inicializar nada,
|
||||
jne generar_digitos //; empezamos a generar los d¡gitos
|
||||
|
||||
mov AX, 1130h //; obtenemos la direccion del juego
|
||||
mov BH, 03h //; de caracteres 8x8 de la ROM ( 0 - 127 )
|
||||
int 10h //; Funci¢n de video 10h
|
||||
|
||||
mov [dir_fuentes], ES //; guardamos el segmento en dir_fuentes
|
||||
mov [dir_fuentes+2], BP //; guardamos el offset en dir_fuentes
|
||||
|
||||
mov [SI + F6h], 0 //; posicion dentro de la cadena <-- 0
|
||||
mov [SI + F7h], 0 //; posicion dentro del byte <------ 0
|
||||
|
||||
generar_digitos:
|
||||
|
||||
mov BH, [ SI + F3h ] //; n§ de digitos a mostar
|
||||
|
||||
push [ SI + F6h ] //; guardo el contenido original de la pos.
|
||||
|
||||
mov BP, [ SI + F6h ] //; posicion dentro de la cadena
|
||||
add BP, SI //; posicion del digito a procesar
|
||||
|
||||
mov AL, [BP] //; digito a procesar
|
||||
|
||||
|
||||
|
||||
nuevo_digito:
|
||||
|
||||
mov AH, 0
|
||||
mov CL, 3 //; multiplico por 8 AX para tener la
|
||||
shl AX, CL //; posicion dentro de la ROM
|
||||
|
||||
add AX, dir_fuentes+2 //; cargo AX con la direccion de la letra
|
||||
|
||||
mov CH, 0 //; recorre las 8 filas ( 0 - 7 )
|
||||
|
||||
siguiente_fila:
|
||||
|
||||
//; **************************
|
||||
mov DH, 0
|
||||
mov DL, CH
|
||||
add AX, DX
|
||||
//; add AX, CH //; direccion por fila de la letra a recorrer
|
||||
//; **************************
|
||||
mov BL, dir_fuentes:[AX]//; colocamos en BL la fila del digito a tratar
|
||||
|
||||
mov CL, 8 //; recorre los 8 puntos horizontales
|
||||
|
||||
sigue_horizontal:
|
||||
|
||||
//; ************************** muestro en (x,y) un punto o un espacio
|
||||
push AX push BX push CX
|
||||
|
||||
mov DH, [SI+238] //; coordenada x inicial
|
||||
mov DL, [SI+240] //; coordenada y inicial
|
||||
|
||||
add DL, CH //; coordenada y final
|
||||
|
||||
mov AL, [SI+F3] //; n§ de digitos a mostar
|
||||
sub AL, BH //; ndm - digitos que quedan = digitos mostrados
|
||||
|
||||
mov CL, 3 //;
|
||||
shl AL, CL //; multiplico por 8 los digitos mostrados
|
||||
|
||||
add DH, AL //; coordenada y final
|
||||
|
||||
mov AH, 02h
|
||||
mov BH, 1h
|
||||
int 10h
|
||||
|
||||
pop CX pop BX pop AX
|
||||
//; ************************** muestro en (x,y) un punto o un espacio
|
||||
//; ************************** muestro en (x,y) un punto o un espacio
|
||||
push AX push BX push CX
|
||||
|
||||
shl BL, 1 //; dezplaza 1 bit a la izquierda
|
||||
|
||||
jc punto_letrero_on
|
||||
|
||||
mov AL, 32d
|
||||
|
||||
jmp fin_punto
|
||||
|
||||
punto_letrero_on:
|
||||
|
||||
mov AL, 43d
|
||||
|
||||
fin_punto:
|
||||
|
||||
mov AH, 0Ah
|
||||
mov BH, 1h
|
||||
mov CX, 1h
|
||||
int 10h
|
||||
|
||||
pop CX pop BX pop AX
|
||||
//; ************************** muestro en (x,y) un punto o un espacio
|
||||
|
||||
dec CL //;
|
||||
jnz sigue_horizontal //; continua hasta los 8 bit's
|
||||
|
||||
inc CH //;
|
||||
cmp CH, 8 //;
|
||||
jne siguiente_fila //; procesa las 8 filas
|
||||
|
||||
inc [ SI + F6h ] //; inc el puntero de posicion
|
||||
|
||||
mov BP, [ SI + F6h ] //; posicion dentro de la cadena
|
||||
add BP, SI //; posicion del digito a procesar
|
||||
|
||||
mov AL, [BP] //; digito a procesar
|
||||
|
||||
inc [SI + F6h] //; inc la posicion dentro de la frase
|
||||
cmp AL, '$' //; si no fin de frase continuo normalmente
|
||||
jne es_fin_frase //;
|
||||
mov [SI + F6h], 0 //; si no, posicion de frase == 0
|
||||
|
||||
es_fin_frase:
|
||||
|
||||
dec BH //; solo visualiza los digitos que manda el
|
||||
jnz nuevo_digito //; usuario.
|
||||
|
||||
pop [ SI + F6h ] //; restauro el contenido original de la pos.
|
||||
|
||||
inc [ SI + F6h ] //; actualizo la rotacion para la proxima vez
|
||||
cmp AL, '$' //;
|
||||
je frase_rotada //;
|
||||
mov [ SI + F6h ], 0 //;
|
||||
|
||||
frase_rotada:
|
||||
|
||||
RET //; regreso de la llamada
|
||||
|
||||
//; letrero_digital endp
|
||||
|
||||
|
||||
POP DS
|
||||
}
|
||||
|
||||
|
||||
}
|
204
LETRERO.ASM
Normal file
204
LETRERO.ASM
Normal file
@ -0,0 +1,204 @@
|
||||
Codigo segment
|
||||
|
||||
assume cs:Codigo, ds:Datos, ss:Pila
|
||||
|
||||
|
||||
display_frase PROC near ;--------------------------------------------
|
||||
|
||||
mov AX, 1
|
||||
mov SI, OFFSET mi_estruct
|
||||
CALL letrero_digital
|
||||
|
||||
mov CX, FFFFh
|
||||
|
||||
continua_un_rato:
|
||||
|
||||
push CX
|
||||
mov AX, 0
|
||||
CALL letrero_digital
|
||||
pop CX
|
||||
|
||||
loop continua_un_rato
|
||||
|
||||
mov ax,4c00h ;no exit back to DOS
|
||||
int 21h ;DOS interrupt
|
||||
|
||||
display_frase endp ;--------------------------------------------
|
||||
|
||||
|
||||
|
||||
; Funci¢n para generar un letrero digital 100 % ASM
|
||||
;
|
||||
; Entradas:
|
||||
; SI ptr a las estructura de datos 256 bytes
|
||||
;
|
||||
; 237 cadena a mostrar en el letrero: el final es $
|
||||
; 2 posici¢n X
|
||||
; 2 posici¢n Y
|
||||
; 1 (1nibble Escala X | 2nibble Escala Y )
|
||||
; 1 n£mero de d¡gitos a mostrar en pantalla
|
||||
; 1 color de fondo
|
||||
; 1 color principal
|
||||
; -----------------------------------------------
|
||||
; 1 posici¢n dentro de la cadena
|
||||
; 1 posici¢n en el byte
|
||||
; 8 FUTURA AMPLIACIàN
|
||||
;
|
||||
; AX si 1, inicializa nuestra informacion
|
||||
;
|
||||
|
||||
letrero_digital PROC near ;--------------------------------------------
|
||||
|
||||
cmp AX, 1 ; si no hay que inicializar nada,
|
||||
jne generar_digitos ; empezamos a generar los d¡gitos
|
||||
|
||||
mov AX, 1130h ; obtenemos la direccion del juego
|
||||
mov BH, 03h ; de caracteres 8x8 de la ROM ( 0 - 127 )
|
||||
int 10h ; Funci¢n de video 10h
|
||||
|
||||
mov dir_fuentes, ES ; guardamos el segmento en dir_fuentes
|
||||
mov dir_fuentes+2, BP ; guardamos el offset en dir_fuentes
|
||||
|
||||
mov [SI + F6h], 0 ; posicion dentro de la cadena <-- 0
|
||||
mov [SI + F7h], 0 ; posicion dentro del byte <------ 0
|
||||
|
||||
generar_digitos:
|
||||
|
||||
mov BH, [ SI + F3h ] ; n§ de digitos a mostar
|
||||
|
||||
push [ SI + F6h ] ; guardo el contenido original de la pos.
|
||||
|
||||
mov BP, [ SI + F6h ] ; posicion dentro de la cadena
|
||||
add BP, SI ; posicion del digito a procesar
|
||||
|
||||
mov AL, [BP] ; digito a procesar
|
||||
|
||||
|
||||
|
||||
nuevo_digito:
|
||||
|
||||
mov AH, 0
|
||||
mov CL, 3 ; multiplico por 8 AX para tener la
|
||||
shl AX, CL ; posicion dentro de la ROM
|
||||
|
||||
add AX, dir_fuentes+2 ; cargo AX con la direccion de la letra
|
||||
|
||||
mov CH, 0 ; recorre las 8 filas ( 0 - 7 )
|
||||
|
||||
siguiente_fila:
|
||||
|
||||
; **************************
|
||||
mov DH, 0
|
||||
mov DL, CH
|
||||
add AX, DX
|
||||
; add AX, CH ; direccion por fila de la letra a recorrer
|
||||
; **************************
|
||||
mov BL, dir_fuentes:[AX]; colocamos en BL la fila del digito a tratar
|
||||
|
||||
mov CL, 8 ; recorre los 8 puntos horizontales
|
||||
|
||||
sigue_horizontal:
|
||||
|
||||
; ************************** muestro en (x,y) un punto o un espacio
|
||||
push AX push BX push CX
|
||||
|
||||
mov DH, [SI+238] ; coordenada x inicial
|
||||
mov DL, [SI+240] ; coordenada y inicial
|
||||
|
||||
add DL, CH ; coordenada y final
|
||||
|
||||
mov AL, [SI+F3] ; n§ de digitos a mostar
|
||||
sub AL, BH ; ndm - digitos que quedan = digitos mostrados
|
||||
|
||||
mov CL, 3 ;
|
||||
shl AL, CL ; multiplico por 8 los digitos mostrados
|
||||
|
||||
add DH, AL ; coordenada y final
|
||||
|
||||
mov AH, 02h
|
||||
mov BH, 1h
|
||||
int 10h
|
||||
|
||||
pop CX pop BX pop AX
|
||||
; ************************** muestro en (x,y) un punto o un espacio
|
||||
; ************************** muestro en (x,y) un punto o un espacio
|
||||
push AX push BX push CX
|
||||
|
||||
shl BL, 1 ; dezplaza 1 bit a la izquierda
|
||||
|
||||
jc punto_letrero_on
|
||||
|
||||
mov AL, 32d
|
||||
|
||||
jmp fin_punto
|
||||
|
||||
punto_letrero_on:
|
||||
|
||||
mov AL, 43d
|
||||
|
||||
fin_punto:
|
||||
|
||||
mov AH, 0Ah
|
||||
mov BH, 1h
|
||||
mov CX, 1h
|
||||
int 10h
|
||||
|
||||
pop CX pop BX pop AX
|
||||
; ************************** muestro en (x,y) un punto o un espacio
|
||||
|
||||
dec CL ;
|
||||
jnz sigue_horizontal ; continua hasta los 8 bit's
|
||||
|
||||
inc CH ;
|
||||
cmp CH, 8 ;
|
||||
jne siguiente_fila ; procesa las 8 filas
|
||||
|
||||
inc [ SI + F6h ] ; inc el puntero de posicion
|
||||
|
||||
mov BP, [ SI + F6h ] ; posicion dentro de la cadena
|
||||
add BP, SI ; posicion del digito a procesar
|
||||
|
||||
mov AL, [BP] ; digito a procesar
|
||||
|
||||
inc [SI + F6h] ; inc la posicion dentro de la frase
|
||||
cmp AL, '$' ; si no fin de frase continuo normalmente
|
||||
jne es_fin_frase ;
|
||||
mov [SI + F6h], 0 ; si no, posicion de frase == 0
|
||||
|
||||
es_fin_frase:
|
||||
|
||||
dec BH ; solo visualiza los digitos que manda el
|
||||
jnz nuevo_digito ; usuario.
|
||||
|
||||
pop [ SI + F6h ] ; restauro el contenido original de la pos.
|
||||
|
||||
inc [ SI + F6h ] ; actualizo la rotacion para la proxima vez
|
||||
cmp AL, '$' ;
|
||||
je frase_rotada ;
|
||||
mov [ SI + F6h ], 0 ;
|
||||
|
||||
frase_rotada:
|
||||
|
||||
RET ; regreso de la llamada
|
||||
|
||||
letrero_digital endp
|
||||
|
||||
Codigo ends
|
||||
|
||||
Datos segment para public 'data'
|
||||
|
||||
dir_fuentes qb FFFF0000h
|
||||
|
||||
mi_estruct db 'Esto solo es una prueba, de mi primer programa en Assembly JD $ 000018000000000000'
|
||||
|
||||
Datos ends
|
||||
|
||||
|
||||
Pila segment stack 'stack'
|
||||
|
||||
db 1000 dup (0)
|
||||
|
||||
Pila ends
|
||||
|
||||
end
|
||||
|
200
LETRERO.JD
Normal file
200
LETRERO.JD
Normal file
@ -0,0 +1,200 @@
|
||||
NAME JD
|
||||
PAGE 60, 130
|
||||
TITLE 'MI PRIMER PROGRAMA EN ASM -->JD'
|
||||
|
||||
|
||||
UNICO SEGMENT PARA PUBLIC 'CODE'
|
||||
|
||||
ORG 0100H
|
||||
|
||||
ASSUME CS:UNICO, DS:UNICO, ES:UNICO, SS:UNICO
|
||||
|
||||
|
||||
|
||||
mi_estruct db "Esto solo es una prueba, de mi primer programa en Assembly JD $ 000018000000000000"
|
||||
|
||||
|
||||
diplay_frase PROC near
|
||||
|
||||
mov AX, 1
|
||||
mov SI, OFFSET mi_estruct
|
||||
CALL letrero_digital
|
||||
|
||||
mov CX, FFFFh
|
||||
|
||||
continua_un_rato:
|
||||
|
||||
push CX
|
||||
|
||||
mov AX, 0
|
||||
CALL letrero_digital
|
||||
|
||||
pop CX
|
||||
|
||||
loop continua_un_rato
|
||||
|
||||
mov AX, 04c00h
|
||||
int 21h
|
||||
|
||||
display_frase endp
|
||||
|
||||
|
||||
; Funci¢n para generar un letrero digital 100 % ASM
|
||||
;
|
||||
; Entradas:
|
||||
; SI ptr a las estructura de datos 256 bytes
|
||||
;
|
||||
; 237 cadena a mostrar en el letrero: el final es $
|
||||
; 2 posici¢n X
|
||||
; 2 posici¢n Y
|
||||
; 1 (1nibble Escala X | 2nibble Escala Y )
|
||||
; 1 n£mero de d¡gitos a mostrar en pantalla
|
||||
; 1 color de fondo
|
||||
; 1 color principal
|
||||
; -----------------------------------------------
|
||||
; 1 posici¢n dentro de la cadena
|
||||
; 1 posici¢n en el byte
|
||||
; 8 FUTURA AMPLIACIàN
|
||||
;
|
||||
; AX si 1, inicializa nuestra informacion
|
||||
;
|
||||
|
||||
dir_fuentes db 4 DUP (0)
|
||||
|
||||
|
||||
letrero_digital PROC near
|
||||
|
||||
|
||||
cmp AX, 1 ; si no hay que inicializar nada,
|
||||
jne generar_digitos ; empezamos a generar los d¡gitos
|
||||
|
||||
mov AX, 1130h ; obtenemos la direccion del juego
|
||||
mov BH, 03h ; de caracteres 8x8 de la ROM ( 0 - 127 )
|
||||
int 10h ; Funci¢n de video 10h
|
||||
|
||||
mov dir_fuentes, ES ; guardamos el segmento en dir_fuentes
|
||||
mov dir_fuentes+2, BP ; guardamos el offset en dir_fuentes
|
||||
|
||||
mov [SI + F6h], 0 ; posicion dentro de la cadena <-- 0
|
||||
mov [SI + F7h], 0 ; posicion dentro del byte <------ 0
|
||||
|
||||
generar_digitos:
|
||||
|
||||
|
||||
mov BH, [ SI + F3h ] ; n§ de digitos a mostar
|
||||
|
||||
push [ SI + F6h ] ; guardo el contenido original de la pos.
|
||||
|
||||
mov AX, [ SI + F6h ] ; posicion dentro de la cadena
|
||||
add AX, SI ; posicion del digito a procesar
|
||||
mov AL, [AX] ; digito a procesar
|
||||
|
||||
nuevo_digito:
|
||||
|
||||
mov AH, 0
|
||||
mov CL, 3 ; multiplico por 8 AX para tener la
|
||||
shl AX, CL ; posicion dentro de la ROM
|
||||
|
||||
add AX, dir_fuentes+2 ; cargo AX con la direccion de la letra
|
||||
|
||||
mov CH, 0 ; recorre las 8 filas ( 0 - 7 )
|
||||
|
||||
siguiente_fila:
|
||||
|
||||
add AX, CH ; direccion por fila de la letra a recorrer
|
||||
mov BL, dir_fuentes:[AX]; colocamos en BL la fila del digito a tratar
|
||||
|
||||
mov CL, 8 ; recorre los 8 puntos horizontales
|
||||
|
||||
sigue_horizontal:
|
||||
|
||||
; ************************** muestro en (x,y) un punto o un espacio
|
||||
push AX push BX push CX
|
||||
|
||||
mov DH, [SI+238] ; coordenada x inicial
|
||||
mov DL, [SI+240] ; coordenada y inicial
|
||||
|
||||
add DL, CH ; coordenada y final
|
||||
|
||||
mov AL, [SI+F3] ; n§ de digitos a mostar
|
||||
sub AL, BH ; ndm - digitos que quedan = digitos mostrados
|
||||
|
||||
mov CL, 3 ;
|
||||
shl AL, CL ; multiplico por 8 los digitos mostrados
|
||||
|
||||
add DH, AL ; coordenada y final
|
||||
|
||||
mov AH, 02h
|
||||
mov BH, 1h
|
||||
int 10h
|
||||
|
||||
pop CX pop BX pop AX
|
||||
; ************************** muestro en (x,y) un punto o un espacio
|
||||
; ************************** muestro en (x,y) un punto o un espacio
|
||||
push AX push BX push CX
|
||||
|
||||
shl BL, 1 ; dezplaza 1 bit a la izquierda
|
||||
|
||||
jc punto_letrero_on
|
||||
|
||||
mov AL, 32d
|
||||
|
||||
jmp fin_punto
|
||||
|
||||
punto_letrero_on:
|
||||
|
||||
mov AL, 43d
|
||||
|
||||
fin_punto:
|
||||
|
||||
mov AH, 0Ah
|
||||
mov BH, 1h
|
||||
mov CX, 1h
|
||||
int 10h
|
||||
|
||||
pop CX pop BX pop AX
|
||||
; ************************** muestro en (x,y) un punto o un espacio
|
||||
|
||||
dec CL ;
|
||||
jnz sigue_horizontal ; continua hasta los 8 bit's
|
||||
|
||||
inc CH ;
|
||||
cmp CH, 8 ;
|
||||
jne siguiente_fila ; procesa las 8 filas
|
||||
|
||||
inc [ SI + F6h ] ; inc el puntero de posicion
|
||||
|
||||
mov AX, [ SI + F6h ] ; posicion dentro de la cadena
|
||||
add AX, SI ; posicion del digito a procesar
|
||||
mov AL, [AX] ; digito a procesar
|
||||
|
||||
|
||||
inc [SI + F6h] ; inc la posicion dentro de la frase
|
||||
cmp AL, '$' ; si no fin de frase continuo normalmente
|
||||
jne es_fin_frase ;
|
||||
mov [SI + F6h], 0 ; si no, posicion de frase == 0
|
||||
|
||||
es_fin_frase:
|
||||
|
||||
dec BH ; solo visualiza los digitos que manda el
|
||||
jnz nuevo_digito ; usuario.
|
||||
|
||||
pop [ SI + F6h ] ; restauro el contenido original de la pos.
|
||||
|
||||
inc [ SI + F6h ] ; actualizo la rotacion para la proxima vez
|
||||
cmp AL, '$' ;
|
||||
je frase_rotada ;
|
||||
mov [ SI + F6h ], 0 ;
|
||||
|
||||
frase_rotada:
|
||||
|
||||
RET ; regreso de la llamada
|
||||
|
||||
letrero_digital endp
|
||||
|
||||
|
||||
|
||||
|
||||
UNICO ends
|
||||
|
||||
end
|
21
M.ASM
Normal file
21
M.ASM
Normal file
@ -0,0 +1,21 @@
|
||||
primero segment para public 'CODE'
|
||||
|
||||
|
||||
assume cs:primero, ds:primero, ss:primero
|
||||
|
||||
inicial proc near
|
||||
|
||||
mov DX, offset ds:cadenatexto
|
||||
mov AH, 09h
|
||||
int 21h
|
||||
|
||||
mov ax, 04c00h
|
||||
int 21h
|
||||
|
||||
inicial endp
|
||||
|
||||
|
||||
cadenatexto db "Esto es una prueba$"
|
||||
|
||||
primero ends
|
||||
end
|
BIN
NONAME00.EXE
Normal file
BIN
NONAME00.EXE
Normal file
Binary file not shown.
BIN
NONAME00.TFA
Normal file
BIN
NONAME00.TFA
Normal file
Binary file not shown.
454
V/BROWSE.ASM
Normal file
454
V/BROWSE.ASM
Normal file
@ -0,0 +1,454 @@
|
||||
; BROWSE.ASM -- Full Screen File Pager
|
||||
; ====================================
|
||||
|
||||
CSEG Segment para public 'code'
|
||||
Assume CS:CSEG, DS:CSEG, ES:CSEG, SS:CSEG
|
||||
Org 0080h
|
||||
Parameter Label Byte
|
||||
Org 0100h
|
||||
Entry: Jmp Begin
|
||||
|
||||
; All Data
|
||||
; --------
|
||||
|
||||
db 'ATTR='
|
||||
Attribute db 0 ; Current screen attribute
|
||||
db 'SHIFT='
|
||||
ShiftHoriz db 8 ; Horizontal shift screen default
|
||||
DosVersionFail db 'Requires DOS 2.0 or above$'
|
||||
NoSpaceFail db 'Not enough memory$'
|
||||
FileFail db 'File Not Found$'
|
||||
ScreenFail db 'Unsupported video mode$'
|
||||
Delimiters db 9,' ,;=/' ; Delimiters in parameter
|
||||
FileHandle dw ? ; Use for saving file handle
|
||||
WSMode db 0FFh ; AND value for non-WordStar mode
|
||||
LineLength db ? ; Length of line (from BIOS)
|
||||
NumberLines db 25,0 ; Number of lines (check EGA BIOS)
|
||||
ScreenSize dw ? ; Size of screen in bytes
|
||||
CheckRetrace db 1 ; Flag zero if EGA or MONO used
|
||||
Addr6845 dw ? ; Could use for retrace check
|
||||
ScreenAddr Label DWord ; Address of screen
|
||||
ScreenOff dw 0 ; Higher for non-page 0
|
||||
ScreenSeg dw 0B800h ; Set to B000h for Mono Mode 7
|
||||
ScreenStart dw ? ; Points within buffer
|
||||
EndOfFile dw ? ; Points within buffer
|
||||
FileOffset dw -1, -1 ; Address within file of buffer data
|
||||
HorizOffset dw 0 ; Horizontal offset for display
|
||||
RightMargin dw 0 ; Right margin for offset display
|
||||
Dispatch dw Home, Up, PgUp, Dummy, Left
|
||||
dw Dummy, Right, Dummy, Ending, Down, PgDn
|
||||
|
||||
; Check DOS Version for 2.0 or above
|
||||
; ----------------------------------
|
||||
|
||||
Begin: Cld ; All string directions forward
|
||||
Mov AH,30h
|
||||
Int 21h ; Get DOS Version Number
|
||||
Cmp AL,2 ; Check for 2.0 or later
|
||||
Jae DOSVerOK
|
||||
Mov DX,Offset DOSVersionFail
|
||||
ErrorExit: Mov AH,9 ; Write error message
|
||||
Int 21h
|
||||
Int 20h
|
||||
|
||||
; Parse Command Line to get File Name and WordStar flag
|
||||
; -----------------------------------------------------
|
||||
|
||||
DOSVerOK: Mov SI,1 + Offset Parameter ; Points to parameter
|
||||
NameSearch: Lodsb ; Get byte
|
||||
Cmp AL,13 ; Check if carriage return
|
||||
Jz NoFileFound ; If so, no file name
|
||||
Mov DI,Offset Delimiters ; String of delimiters
|
||||
Mov CX,5 ; Number of delimiters (no /)
|
||||
Repne Scasb ; See if a match
|
||||
Je NameSearch ; If a delimiter, keep looking
|
||||
Mov DX,SI ; Otherwise found file name
|
||||
Dec DX ; Points to beginning of it
|
||||
EndSearch: Lodsb ; Get next byte
|
||||
Cmp AL,13 ; See if carriage return
|
||||
Je GotFileEnd ; If so, we're all done
|
||||
Mov DI,Offset Delimiters ; String of delimiters
|
||||
Mov CX,6 ; Number (including /)
|
||||
Repne Scasb ; See if a match
|
||||
Jne EndSearch ; If not, still in file name
|
||||
Mov Byte Ptr [SI - 1],0 ; If so, mark end of file name
|
||||
Jcxz GotFlag ; If slash, check for W
|
||||
Jmp EndSearch ; Or continue flag search
|
||||
GotFlag: Lodsb ; Get byte after / flag
|
||||
Or AL,20h ; Uncapitalize
|
||||
Cmp AL,'w' ; See if w for WordStar mode
|
||||
Jnz GotFileEnd ; If not, just ignore it
|
||||
Mov [WSMode],7Fh ; AND value for WordStar
|
||||
|
||||
; Open the File
|
||||
; -------------
|
||||
|
||||
GotFileEnd: Mov Byte Ptr [SI - 1],0 ; Mark end of file name
|
||||
; DX still points to name
|
||||
Mov AX,3D00h ; Open file for reading
|
||||
Int 21h ; by calling DOS
|
||||
Jnc GotTheFile ; If no error, continue
|
||||
NoFileFound: Mov DX,Offset FileFail ; Otherwise print a message
|
||||
Jmp ErrorExit
|
||||
GotTheFile: Mov [FileHandle],AX ; Save the file handle
|
||||
|
||||
; Get Screen Mode Information from BIOS Data Area
|
||||
; -----------------------------------------------
|
||||
|
||||
Push ES ; Save register
|
||||
Sub AX,AX
|
||||
Mov ES,AX ; Set ES to 0 (BIOS Data)
|
||||
Mov AL,ES:[0449h] ; Current Video Mode
|
||||
Cmp AL,3 ; Check if Color Alpha
|
||||
Jbe DisplayOK ; Continue if so
|
||||
Cmp AL,7 ; Check if monochrome display
|
||||
Je Monochrome ; If so, branch
|
||||
Mov DX,Offset ScreenFail ; We can't handle graphics
|
||||
Jmp ErrorExit ; So print an error message
|
||||
Monochrome: Mov [ScreenSeg],0B000h ; Use Monochrome Segment
|
||||
Mov [CheckRetrace],0 ; Don't have to check retrace
|
||||
DisplayOK: Mov AL,ES:[044Ah] ; Number of Columns
|
||||
Mov [LineLength],AL ; Save it
|
||||
Mov AX,ES:[044Eh] ; Offset into screen buffer
|
||||
Mov [ScreenOff],AX ; Save it
|
||||
Mov AX,ES:[0463h] ; Address of 6845 Regsiter
|
||||
Mov [Addr6845],AX ; Save it
|
||||
Push ES
|
||||
Sub DL,DL ; Set Rows to zero first
|
||||
Sub BH,BH
|
||||
Mov AX,1130h ; EGA BIOS: Get Information
|
||||
Int 10h
|
||||
Pop ES
|
||||
Or DL,DL ; Check if DL is still zero
|
||||
Jz NoEGA ; If so, skip rest of stuff
|
||||
Inc DL
|
||||
Mov [NumberLines],DL ; Save Number of Lines
|
||||
Test Byte Ptr ES:[0487h],4 ; Check if must check retrace
|
||||
Jnz NoEGA
|
||||
Mov [CheckRetrace],0 ; EGA says we don't have to
|
||||
NoEGA: Mov BH,ES:[0462h] ; Get Current Page (use later)
|
||||
Pop ES
|
||||
Mov AL,[LineLength] ; Length of each line
|
||||
Mul [NumberLines] ; Total chars on screen
|
||||
Add AX,AX ; Double for attributes
|
||||
Mov [ScreenSize],AX ; And Save it
|
||||
|
||||
; See if enough memory is left
|
||||
; ----------------------------
|
||||
|
||||
Add AX,Offset ScreenHold ; Add ScreenSize to code end
|
||||
Add AX,256 ; Add a little stack room
|
||||
Cmp AX,SP ; Check against stack pointer
|
||||
Jbe GotEnufMemory ; Continue if OK
|
||||
Mov DX,Offset NoSpaceFail ; Otherwise end program
|
||||
Jmp ErrorExit ; with error messae
|
||||
|
||||
; Get Current Screen Attribute
|
||||
; ----------------------------
|
||||
|
||||
GotEnufMemory: Cmp [Attribute],0 ; Check if attribute pre-set
|
||||
Jnz GotAttribute ; If so, move on
|
||||
Mov DL,' ' ; Write out a byte
|
||||
Mov AH,2 ; using DOS
|
||||
Int 21h
|
||||
Mov AL,8 ; Now backspace
|
||||
Mov AH,14 ; using BIOS call
|
||||
Int 10h
|
||||
Mov AH,8 ; Read character & attribute
|
||||
Int 10h ; using BIOS call (BH = pg)
|
||||
Mov [Attribute],AH ; And save attribute
|
||||
|
||||
; Save Current Screen
|
||||
; -------------------
|
||||
|
||||
GotAttribute: Mov DX,Offset Terminate ; Set Ctrl-Break exit
|
||||
Mov AX,2523h ; to terminate that way
|
||||
Int 21h
|
||||
Mov DI,Offset ScreenHold ; Destination of screen
|
||||
Mov CX,[ScreenSize] ; Size of screen
|
||||
Push DS ; Save Source Segment
|
||||
Lds SI,[ScreenAddr] ; Get screen address
|
||||
Rep Movsb ; Move in the bytes
|
||||
Pop DS ; Restore Source Segment
|
||||
|
||||
; Get Keyboard Key and Decide on Action
|
||||
; -------------------------------------
|
||||
|
||||
Call Home ; Read file in
|
||||
Mov [ScreenStart],SI ; Set buffer address
|
||||
KeyLoop: Call UpDateScreen ; Write file to screen
|
||||
GetKey: Mov AH,8 ; Get key
|
||||
Int 21h ; by calling DOS
|
||||
Cmp AL,27 ; Check if ESC
|
||||
Je Terminate ; If so, terminate
|
||||
Cmp AL,0 ; Check if extended
|
||||
Jnz GetKey ; If not, try again
|
||||
Mov AH,8 ; Get extended code
|
||||
Int 21h ; by calling DOS
|
||||
Sub AL,71 ; Subtract Home key value
|
||||
Jb GetKey ; If below that, not valid
|
||||
Cmp AL,(81 - 71) ; Check if above PgDn
|
||||
Ja GetKey ; If so, ignore it
|
||||
Sub AH,AH ; Zero out top byte
|
||||
Add AX,AX ; Double for word access
|
||||
Mov BX,AX ; Offset in dispatch table
|
||||
Mov SI,[ScreenStart] ; Set current buffer pointer
|
||||
Call [Dispatch + BX] ; Do the call
|
||||
Mov [ScreenStart],SI ; Set new buffer pointer
|
||||
Jmp KeyLoop ; And update the screen
|
||||
|
||||
; Terminate -- Restore screen and close file
|
||||
; ------------------------------------------
|
||||
|
||||
Terminate: Mov SI,Offset ScreenHold ; Address of Saved Screen
|
||||
Les DI,[ScreenAddr] ; Address of Display
|
||||
Mov CX,[ScreenSize] ; Number of characters
|
||||
Rep Movsb ; Move them back
|
||||
Mov BX,[FileHandle] ; Get File Handle
|
||||
Mov AH,3Eh ; Close File
|
||||
Int 21h
|
||||
Int 20h ; Terminate
|
||||
|
||||
; Cursor Key Routines -- Home Key
|
||||
; -------------------------------
|
||||
|
||||
Home: Sub BX,BX ; For zeroing out values
|
||||
Mov AX,[FileOffset] ; Check if read in file
|
||||
Or AX,[FileOffset + 2]
|
||||
Mov [FileOffset],BX ; Zero out file address
|
||||
Mov [FileOffset + 2],BX
|
||||
Mov [HorizOffset],BX ; Zero out horizontal offset
|
||||
Mov SI,Offset Buffer ; Reset buffer pointer
|
||||
Jz Dummy ; Skip file read if in already
|
||||
Mov DX,Offset Buffer ; Area to read file in
|
||||
Mov CX,32768 ; Number of bytes to read
|
||||
Call FileRead ; Read in file
|
||||
Dummy: Ret
|
||||
|
||||
; Up and PgUp Keys
|
||||
; ----------------
|
||||
|
||||
Up: Call GetPrevChar ; Get previous char in buffer
|
||||
Jc UpDone ; If none available, finish
|
||||
UpLoop: Call GetPrevChar ; Get previous char again
|
||||
Jc UpDone ; if none, we're done
|
||||
Cmp AL,10 ; Check if line feed
|
||||
Jnz UpLoop ; If not, try again
|
||||
Call GetNextChar ; Get char after line feed
|
||||
UpDone: Ret
|
||||
|
||||
PgUp: Mov CX,Word Ptr [NumberLines] ; Number of lines
|
||||
PgUpLoop: Call Up ; Do UP that many times
|
||||
Loop PgUpLoop
|
||||
Ret
|
||||
|
||||
; Left and Right Keys
|
||||
; -------------------
|
||||
|
||||
Left: Mov [HorizOffset],0 ; Reset Horizontal Offset
|
||||
Ret
|
||||
|
||||
Right: Mov AL,[ShiftHoriz] ; Get places to shift
|
||||
Sub AH,AH
|
||||
Add [HorizOffset],AX ; Move that many right
|
||||
Ret
|
||||
|
||||
; End, Down, and PgDn Keys
|
||||
; ------------------------
|
||||
|
||||
Ending: Mov BX,SI ; Save buffer pointer
|
||||
Call PgDn ; Go page down
|
||||
Cmp BX,SI ; Check if we did so
|
||||
Jnz Ending ; If so, do it again
|
||||
Ret
|
||||
|
||||
Down: Call GetNextChar ; Get next character
|
||||
Jc NoMoreDown ; If no more, we're done
|
||||
DownLoop: Call GetNextChar ; Get one again
|
||||
Jc UpLoop ; If no more, find prev LF
|
||||
Cmp AL,10 ; See if line feed
|
||||
Jnz DownLoop ; If not, continue
|
||||
NoMoreDown: Ret
|
||||
|
||||
PgDn: Mov CX,Word Ptr [NumberLines] ; Number of lines
|
||||
PgDnLoop: Call Down ; Do DOWN that many times
|
||||
Loop PgDnLoop
|
||||
Ret
|
||||
|
||||
; Update Screen
|
||||
; -------------
|
||||
|
||||
UpdateScreen: Push ES
|
||||
Mov SI,[ScreenStart] ; Address of data in buffer
|
||||
Les DI,[ScreenAddr] ; Address of display
|
||||
Mov CX,ScreenSize ; Number of bytes in screen
|
||||
Shr CX,1 ; Half for number of chars
|
||||
Mov AL,' ' ; Will blank screen
|
||||
Mov AH,[Attribute] ; With screen attribute
|
||||
Rep Stosw ; Blank it
|
||||
Mov AL,[LineLength] ; Length of display line
|
||||
Sub AH,AH
|
||||
Add AX,[HorizOffset] ; Add Horizontal Offset
|
||||
Mov [RightMargin],AX ; That's right display margin
|
||||
Sub DL,DL ; Line Number
|
||||
LineLoop: Sub BX,BX ; Column Number
|
||||
Mov AL,[LineLength] ; Use Line Length
|
||||
Mul DL ; and Line Number
|
||||
Add AX,AX ; to recalculate
|
||||
Mov DI,AX ; display destination
|
||||
Add DI,[ScreenOff] ; Add beginning address
|
||||
CharLoop: Call GetNextChar ; Get next character
|
||||
Jc EndOfScreen ; If no more, we're done
|
||||
And AL,[WSMode] ; Will be 7Fh for WordStar
|
||||
Cmp AL,13 ; Check for carriage return
|
||||
Je CharLoop ; Do nothing if so
|
||||
Cmp AL,10 ; Check for line feed
|
||||
Je LineFeed ; Do routine if so
|
||||
Cmp AL,9 ; Check for tab
|
||||
Je Tab ; Do routine if so
|
||||
Mov CX,1 ; Just 1 char to display
|
||||
PrintChar: Cmp BX,[HorizOffset] ; See if we can print it
|
||||
Jb NoPrint
|
||||
Cmp BX,[RightMargin] ; See if within margin
|
||||
Jae NoPrint
|
||||
Mov AH,[Attribute] ; Attribute for display
|
||||
Cmp [CheckRetrace],0 ; See if must stop snow
|
||||
Jz WriteIt ; If not, skip retrace wait
|
||||
Push BX
|
||||
Push DX
|
||||
Mov BX,AX ; Save character and attribute
|
||||
Mov DX,[Addr6845] ; Set up I/O address
|
||||
Add DX,6
|
||||
RetraceWait1: In AL,DX ; Check until
|
||||
Shr AL,1 ; vertical retrace
|
||||
Jc RetraceWait1 ; ends
|
||||
Cli ; Clear interrupts
|
||||
RetraceWait2: In AL,DX ; Check until
|
||||
Shr AL,1 ; vertical retrace
|
||||
Jnc RetraceWait2 ; begins
|
||||
Mov AX,BX ; Get back character & attr
|
||||
Stosw ; Write to display
|
||||
Sti ; Enable interrupts again
|
||||
Pop DX
|
||||
Pop BX
|
||||
Jmp Short NoPrint ; Skip around "no snow" write
|
||||
WriteIt: Stosw ; Write without retrace wait
|
||||
NoPrint: Inc BX ; Bump up line counter
|
||||
Loop PrintChar ; Do it CX times
|
||||
Jmp CharLoop ; Then go back to top
|
||||
Tab: Mov AX,BX ; Current column number
|
||||
And AX,07h ; Take lower three bits
|
||||
Mov CX,8
|
||||
Sub CX,AX ; Subtract from 8
|
||||
Mov AL,' ' ; Will print CX blanks
|
||||
Jmp PrintChar
|
||||
LineFeed: Inc DL ; Next line
|
||||
Cmp DL,[NumberLines] ; See if down at bottom
|
||||
Jb LineLoop ; If not, continue
|
||||
EndOfScreen: Pop ES ; All done -- leave
|
||||
Ret
|
||||
|
||||
; Get Next Character from buffer
|
||||
; ------------------------------
|
||||
; (Input is SI pointing to buffer, Returns AL, CY if no more)
|
||||
|
||||
GetNextChar: Cmp SI,[EndOfFile] ; See if at end of file
|
||||
Jae NoMoreNext ; If so, no more chars
|
||||
Cmp SI,Offset BufferEnd ; See if at end of buffer
|
||||
Jb CanGetNext ; If not, just get character
|
||||
Push CX ; Otherwise save registers
|
||||
Push DX
|
||||
Push DI
|
||||
Push ES
|
||||
Push DS ; Set ES to DS
|
||||
Pop ES ; (could be different)
|
||||
Mov SI,Offset BufferMid ; Move 2nd buffer half
|
||||
Mov DI,Offset Buffer ; to 1st buffer half
|
||||
Mov CX,16384
|
||||
Sub [ScreenStart],CX ; New buffer pointer
|
||||
Rep Movsb ; Move them
|
||||
Mov SI,DI ; SI also buffer pointer
|
||||
Add [FileOffset],32768 ; Adjust file addr to read
|
||||
Adc [FileOffset + 2],0
|
||||
Mov DX,Offset BufferMid ; Place to read file
|
||||
Mov CX,16384 ; Number of bytes
|
||||
Call FileRead ; Read the file
|
||||
Sub [FileOffset],16384 ; Now adjust so reflects
|
||||
Sbb [FileOffset + 2],0 ; 1st half of buffer
|
||||
Pop ES ; Get back registers
|
||||
Pop DI
|
||||
Pop DX
|
||||
Pop CX
|
||||
Jmp GetNextChar ; And try again to get char
|
||||
CanGetNext: Lodsb ; Get the character
|
||||
NoMoreNext: Cmc ; So CY set if no more
|
||||
Ret
|
||||
|
||||
; Get Previous Character from buffer
|
||||
; ----------------------------------
|
||||
|
||||
GetPrevChar: Cmp SI,Offset Buffer ; See if at top of buffer
|
||||
Ja CanGetPrev ; If not, just get character
|
||||
Mov AX,[FileOffset] ; See if at top of file
|
||||
Or AX,[FileOffset + 2]
|
||||
Jz AtTopAlready ; If so, can't get anymore
|
||||
Push CX ; Save some registers
|
||||
Push DX
|
||||
Mov SI,Offset Buffer ; Move 1st half of buffer
|
||||
Mov DI,Offset BufferMid ; to 2nd half of buffer
|
||||
Mov CX,16384
|
||||
Add [ScreenStart],CX ; New buffer pointer
|
||||
Rep Movsb ; Do the move
|
||||
Sub [FileOffset],16384 ; Adjust file addr for read
|
||||
Sbb [FileOffset + 2],0
|
||||
Mov DX,Offset Buffer ; Area to read file into
|
||||
Mov CX,16384 ; Number of bytes
|
||||
Call FileRead ; Read the file
|
||||
Pop DX ; Get back registers
|
||||
Pop CX
|
||||
Jmp Short CanGetPrev ; Now get character
|
||||
AtTopAlready: Stc ; CY flag set for no more
|
||||
Ret
|
||||
CanGetPrev: Dec SI ; Move pointer back
|
||||
Mov AL,[SI] ; Get the character
|
||||
Clc ; CY flag reset for success
|
||||
Ret
|
||||
|
||||
; Read CX bytes from the file into DX buffer
|
||||
; ------------------------------------------
|
||||
|
||||
FileRead: Push AX ; Save some registers
|
||||
Push BX
|
||||
Push CX
|
||||
Push DX
|
||||
Mov [EndOfFile],-1 ; Initialize this
|
||||
Mov DX,[FileOffset] ; Get file address to read
|
||||
Mov CX,[FileOffset + 2]
|
||||
Mov BX,[FileHandle] ; Get file Handle
|
||||
Sub AL,AL ; Do LSEEK from beginning
|
||||
Mov AH,42h ; LSEEK call
|
||||
Int 21h
|
||||
Pop DX ; Get back destination
|
||||
Pop CX ; Get back count
|
||||
Mov AH,3Fh ; Read file function call
|
||||
Int 21h
|
||||
Jnc NoReadError ; If no error, continue
|
||||
Sub AX,AX ; Otherwise read zero bytes
|
||||
NoReadError: Cmp AX,CX ; See if 32K has been read
|
||||
Je GotItAll ; If so, we're home free
|
||||
Add AX,DX ; Otherwise add to buffer addr
|
||||
Mov [EndOfFile],AX ; And save as end of file
|
||||
GotItAll: Pop BX
|
||||
Pop AX
|
||||
Ret
|
||||
|
||||
; File Buffer and Screen Hold Areas
|
||||
; ---------------------------------
|
||||
|
||||
Buffer Label Byte ; Area for file reads
|
||||
BufferMid equ Buffer + 16384 ; Halfway through it
|
||||
BufferEnd equ BufferMid + 16384 ; At end of it
|
||||
ScreenHold equ BufferEnd ; Area for holding screen
|
||||
CSEG EndS ; End of segment
|
||||
End Entry ; Denotes entry point
|
||||
|
BIN
V/BROWSE.COM
Normal file
BIN
V/BROWSE.COM
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user