commit bf4bcbd4f87288b90e92a095bcdea27fc6d3c89f Author: jdg Date: Fri Sep 3 17:40:06 2021 +0200 First commit 06/07/1996 diff --git a/CDS/EJE1.COM b/CDS/EJE1.COM new file mode 100644 index 0000000..c71382d Binary files /dev/null and b/CDS/EJE1.COM differ diff --git a/CDS/EJEMPLO1.ASM b/CDS/EJEMPLO1.ASM new file mode 100644 index 0000000..6421b91 --- /dev/null +++ b/CDS/EJEMPLO1.ASM @@ -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 diff --git a/CDS/EJEMPLO1.EXE b/CDS/EJEMPLO1.EXE new file mode 100644 index 0000000..3acfe1f Binary files /dev/null and b/CDS/EJEMPLO1.EXE differ diff --git a/CDS/EJEMPLO1.MAP b/CDS/EJEMPLO1.MAP new file mode 100644 index 0000000..e200667 --- /dev/null +++ b/CDS/EJEMPLO1.MAP @@ -0,0 +1,8 @@ + + Start Stop Length Name Class + + 00000H 00139H 0013AH SEGMENTO CODE + +Program entry point at 0000:0100 +Warning: No stack + diff --git a/CDS/EJEMPLO2.ASM b/CDS/EJEMPLO2.ASM new file mode 100644 index 0000000..e2c670e --- /dev/null +++ b/CDS/EJEMPLO2.ASM @@ -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 + \ No newline at end of file diff --git a/CDS/EJEMPLO2.COM b/CDS/EJEMPLO2.COM new file mode 100644 index 0000000..3c53c21 Binary files /dev/null and b/CDS/EJEMPLO2.COM differ diff --git a/CDS/EJEMPLO3.ASM b/CDS/EJEMPLO3.ASM new file mode 100644 index 0000000..3ab7fec --- /dev/null +++ b/CDS/EJEMPLO3.ASM @@ -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 + \ No newline at end of file diff --git a/CDS/EJEMPLO3.COM b/CDS/EJEMPLO3.COM new file mode 100644 index 0000000..16c82eb Binary files /dev/null and b/CDS/EJEMPLO3.COM differ diff --git a/CDS/EJEMPLO4.ASM b/CDS/EJEMPLO4.ASM new file mode 100644 index 0000000..383cbd7 --- /dev/null +++ b/CDS/EJEMPLO4.ASM @@ -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 + \ No newline at end of file diff --git a/CDS/EJEMPLO4.COM b/CDS/EJEMPLO4.COM new file mode 100644 index 0000000..6f63dcf Binary files /dev/null and b/CDS/EJEMPLO4.COM differ diff --git a/E/ASM.DOC b/E/ASM.DOC new file mode 100644 index 0000000..11fea96 --- /dev/null +++ b/E/ASM.DOC @@ -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 + + 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- + + \ No newline at end of file diff --git a/E/ASM.EXE b/E/ASM.EXE new file mode 100644 index 0000000..1a9ef32 Binary files /dev/null and b/E/ASM.EXE differ diff --git a/E/M.EXE b/E/M.EXE new file mode 100644 index 0000000..2bfb7dc Binary files /dev/null and b/E/M.EXE differ diff --git a/E/M.MAP b/E/M.MAP new file mode 100644 index 0000000..e9a04a0 --- /dev/null +++ b/E/M.MAP @@ -0,0 +1,8 @@ + + Start Stop Length Name Class + + 00000H 0001EH 0001FH PRIMERO CODE + +Program entry point at 0000:0000 +Warning: No stack + diff --git a/LETC.CPP b/LETC.CPP new file mode 100644 index 0000000..3449599 --- /dev/null +++ b/LETC.CPP @@ -0,0 +1,195 @@ +#include + +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 +} + + +} \ No newline at end of file diff --git a/LETRERO.ASM b/LETRERO.ASM new file mode 100644 index 0000000..de0c68d --- /dev/null +++ b/LETRERO.ASM @@ -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 + diff --git a/LETRERO.JD b/LETRERO.JD new file mode 100644 index 0000000..c80e7d7 --- /dev/null +++ b/LETRERO.JD @@ -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 diff --git a/M.ASM b/M.ASM new file mode 100644 index 0000000..ce2dd3e --- /dev/null +++ b/M.ASM @@ -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 diff --git a/M.EXE b/M.EXE new file mode 100644 index 0000000..2bfb7dc Binary files /dev/null and b/M.EXE differ diff --git a/NONAME00.EXE b/NONAME00.EXE new file mode 100644 index 0000000..a5da1b4 Binary files /dev/null and b/NONAME00.EXE differ diff --git a/NONAME00.TFA b/NONAME00.TFA new file mode 100644 index 0000000..dbfcd90 Binary files /dev/null and b/NONAME00.TFA differ diff --git a/V/BROWSE.ASM b/V/BROWSE.ASM new file mode 100644 index 0000000..229ff5b --- /dev/null +++ b/V/BROWSE.ASM @@ -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 + diff --git a/V/BROWSE.COM b/V/BROWSE.COM new file mode 100644 index 0000000..ba832cf Binary files /dev/null and b/V/BROWSE.COM differ