Con todo lo que he ido publicando en este blog hasta ahora, ya estamos en disposición de hacer el primer comando del sistema. En este caso voy a exponer el comando Type. Para evitar que choque con el comando interno del sistema vamos a llamarlo MyType.
Este programa imprimirá un fichero sobre pantalla o sobre impresora. Y podremos hacerlo de forma continua o de forma paginada.
Llevará como todos los comandos una ayuda implícita que podrá ser llamada a través de la línea de comandos con '/H', '/h', o '/?'. Cuando se introduzca alguno de estos comandos en la línea aparecerá la siguiente información.
Este comando muestra el fichero especificado"
Por Jose Angel Moneo"
Formato: ver [unidad:][trayecto]fichero(s) [/M] [/P][/H][/?]
/M ....Por páginas
/P .....Sobre impresora
/H o /?.......Ayuda
En este caso el programa es muy sencillo. Solo tiene la rutina principal en la que analizamos y ejecutamos el comando y una subrutina para imprimir el fichero. Por lo tanto lo incluyo de forma íntegra en esta entrada.
Es sencillo, no porque sea fácil hacer esto en ensamblador, sino porque ya dispongo de una librería de funciones y una estructura de programa suficientemente potente, para programar como si lo estuviera haciendo en alto nivel.
La rutina principal lee la línea de comandos y analiza los parámetros pasados, para realizar posteriormente la acción correspondiente.
Si no indicamos fichero en la línea de comandos, este Type, solicitará el fichero por ventana emergente mediante el windir.
En el caso de que se pulse EXC y no se seleccione fichero en el windir, la función saldrá sin hacer nada.
En una impresión paginada (/M) el fichero se irá imprimiendo, deteniendo el proceso al final de la pantalla y escribiendo "------MAS-----", para indicar que el fichero no ha terminado.
Al final de proceso, siempre pedirá un CR antes de salir al sistema.
En este caso, como se ve también he utilizado la macro FOR...NEXT, para realizar los bucles. Existe un SWITCH, en el programa que ha sido implementado de forma directa en ensamblador, ya que es muy simple. En la siguiente entrada creare una macro SWITCH...CASE, para poder ver como simplificar el programa, aunque en este caso es innecesario, ya que está muy claro.
MYTYPE.ASM
; Copyright (C) 2013 José Ángel Moneo Fernández ; This program is free software: you can redistribute it and/or modify ; it under the terms of the GNU General Public License as published by ; the Free Software Foundation, either version 3 of the License, or ; (at your option) any later version. ; This program is distributed in the hope that it will be useful, ; but WITHOUT ANY WARRANTY; without even the implied warranty of ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; GNU General Public License for more details. ; You should have received a copy of the GNU General Public License ; along with this program. If not, see <http://www.gnu.org/licenses/>.
include io.mac
include argum.mac
include stdio.mac
include string.mac
include main.mac
include window.mac
include hi_level.mac
.model compact,pascal
.stack 300
.data
dta _dta ?
mens1 db 10,13,"Par metro incorrecto",10,13,0
help db "Este comando muestra el fichero especificado"
db 10,13,"Por Jose Angel Moneo"
db 10,13,"Formato: ver [unidad:][trayecto]fichero(s)"
db " [/M] [/P][/H[/h] ",10,10,13, " /M ....Por p ginas",10,13
db " /P .....Sobre impresora",10,13,0," /H o /? .....Ayuda",10,13,0
mens2 db "falta nombre de fichero",0
mens3 db "El fichero ",0
mens4 db " no existe.",0
mens6 db " No se puede abrir ",0
mens7 db "------------------ Presentando fichero ",0
mens8 db "------------------",10,13,0
mens9 db "-----------MAS----------",10,13,0
hay db 0
sw db 0
sw1 db 0
i db 0
salida dw 0
todo db "*.*",0
total db 40 dup (0)
camino db 40 dup (0)
buffer db 80 dup (0)
handle dw 0
ends
.code
Type proc far
main
setdta dta
argc dl
inc dl ;inc 1 ya que cl empieza en 1
FOR cl,1,dl
argv cl,si
cmp byte ptr [si],'/'
je switch1
mov hay,1
jmp fin_for1
switch1:
mov ah,[si+1]
cmp ah,'H'
je irah
cmp ah,'h'
je irah
cmp ah,'?'
je irah
cmp ah,'M'
je iram
cmp ah,'m'
je iram
cmp ah,'P'
je irap
cmp ah,'p'
je irap
default:
puts mens1
puts help
exit 1
irah:
puts help
exit 0
iram:
mov sw,1
jmp fin_for1
irap:
mov sw1,1
fin_for1:
NEXT cl
cmp hay,0
jne cpsw
setcursor off
windir 5,20,todo,dta._nombre
cmp dta._nombre,0
je nada
call presenta
exit 0
nada:
exit 1
cpsw:
cmp sw1,1
jne pantalla
mov salida,_stdprn
mov sw,0
jmp alfor2
Pantalla:
mov salida,_stdout
alfor2:
FOR CL,1,DL
argv cl,si
cmp byte ptr [si],'/'
je fin_for2
getpath camino,[si]
findfirst [si],_archivo
jnc presentar
puts mens3
puts [si]
puts mens4
jmp fin_for2
Presentar:
call presenta
in_while:
findnext
jc fin_for2
call presenta
jmp in_while
fin_for2:
NEXT CL
exit 0
type endp
presenta proc near
push cx
strcpy total,camino
strcat total,total,dta._nombre
open total,_r,handle
jnc abierto
puts mens3
puts total
puts mens6
pop cx
ret
abierto:
clrscr
puts mens7
puts total
puts mens8
mov cx,3
in_buc:
read handle,80,buffer
mov bx,ax
cmp bx,0
je salir_buc
mov si,0
resto:
cmp si,bx
je fin_buc
write salida,1,[buffer+si]
cmp byte ptr [buffer+si],10
pushf
inc si
popf
jne resto
inc cx
cmp cx,23
jne resto
cmp sw,1
jne resto
puts mens9
getch al
mov cx,1
fin_buc:
jmp in_buc
salir_buc:
close handle
getch al
pop cx
ret
presenta endp
end type
No hay comentarios:
Publicar un comentario
Si tienes algún comentario, duda o sugerencia, o si quieres aportar algún código creado a partir de las librerías expuestas aquí, por favor, indícamelo.