Vistas de página en total

Mostrando entradas con la etiqueta fseek. Mostrar todas las entradas
Mostrando entradas con la etiqueta fseek. Mostrar todas las entradas

sábado, 7 de septiembre de 2013

WINDIR


   Hoy voy a colocar una función que la hice como parte de la librería window, para presentar, de forma emergente, una ventana para la búsqueda de un fichero.
    La función presenta en pantalla una ventana emergente con los ficheros a buscar, y permite mediante los cursores, desplazarse arriba y abajo por ellos para seleccionar el deseado.
   Esta función es un ejemplo más complejo del uso de todas las funciones que he ido implementando en el blog. Aquí incluyo ya funciones de acceso a fichero. Como se va viendo, el uso de las macros para nombrar de forma diferente las llamadas a las funciones resulta muy cómodo para luego leer el programa.
    Igualmente, en esta función aparece un bucle que he implementado con la macro for



   Con esta función se tiene una forma cómoda de abrir ficheros. Es la implementación de una función equivalente a  OpenFileDialog de windows actual, pero hecha en modo texto y en ensamblador en la época de windows 11.
    Se puede añadir las barras de scroll a la derecha y hacer las implementaciones del ratón, pero para lo que necesitaba me era funcional y rápido tal y como está.
     Devuelve el fichero seleccionado.
     Hice dos versiones, una con memoria dinámica y otra con memoria en disco. Debido a que ahora no funciona la reserva de memoria dinámica por culpa de windows, he colocado la versión de disco.
   Esta versión almacena los ficheros encontrados en un fichero temporal, para poder usarlos durante los scroll. Resultaba más lenta y la abandoné, pero ahora es la única manera de reservar memoria, usando swaping en disco



WINDIR.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 main.mac
include dos.mac
include window.mac
include stdio.mac
include io.mac
include string.mac

.model compact,pascal

.data
buffer db 400 dup (0)
ffblk _dta ?
temporal db "temporal.tmp",0
handle dw 0
indice dw 0
seleccionado db 0
op db 0
nficheros dw 0
limpia db 14 dup (' '),0

.code
public _windir
_windir proc near uses bx cx dx si di,FsCiz,mascara,fichero,color
     mov bx,fichero
     mov [bx],byte ptr 0
    ;clacula las coordenadas de la ventana
    mov cx,FsCiz 
    mov dx,cx
    add dx,0A11h
    getwindow ch,cl,dh,dl,buffer ; salva el area de pantalla
    mov si,mascara
     ;   se da el dato de puntero a traves de si por usarse lea en la macro  
    draw_win ch,cl,dh,dl,[si]  
    setdta ffblk
    new_file temporal,_archivo,handle
    jnc seguir
    exit 1

seguir:
    mov nficheros,0
    findfirst [si],_TODOS
    jc find 
    mov cx,size ffblk
    otro: write handle,cx,ffblk
    inc nficheros
    findnext
    jnc otro
    find:
    close handle

     mov indice,0
    mov seleccionado,0
    open temporal,_R,handle

nuevalista:
     mov ax,FsCiz
     push ax
     call printlista
     opcion:
     getch op
     cmp op,27
     jne no_esc
     jmp escapar
no_esc:
    cmp op,0
    je opcion
    cmp op,13
    je fin
    cmp op,80
    jne sube
    call bajar
    jmp nuevalista
sube:
    cmp op,72
    jne pgup
    call subir
    jmp nuevalista
pgup:
    cmp op,81
    jne gdn
    call pagup
    jmp nuevalista
gdn:
    cmp op,73
    jne nada
    call pagdn
    jmp nuevalista
nada:
     jmp opcion

fin:
     mov al,seleccionado
     cbw
     add ax,indice
     mov dx,ax
     rseek handle,dx,ffblk
     mov cx,size ffblk
     read handle,cx,ffblk
     mov bx,fichero
     cmp nficheros,0
     jz escapar
     strcpy [bx],ffblk._nombre

escapar:
     close handle
     delete temporal
     mov cx,FsCiz
     mov dx,cx
     add dx,0A11h
     putwindow ch,cl,dh,dl,buffer ;repone el area de pantalla
     ret
_windir endp
pagup proc near
    mov ax,indice
    add ax,9
    cmp ax,nficheros
    jae n_pagup
    mov indice,ax
n_pagup:
    ret
pagup endp
pagdn proc near
     mov ax,indice
     sub ax,9
     cmp ax,0
     jg a_pagdn
     mov ax,0
a_pagdn:
     mov indice,ax
     ret
pagdn endp
subir proc near
     cmp seleccionado,0
     je su1
     dec seleccionado
      jmp su3
su1:
      cmp indice,0
      je su3
     dec indice
su3:
     ret
subir endp
bajar proc near
     xor ax,ax
     mov al,seleccionado
     add ax,indice
     inc ax
    cmp ax,nficheros
    jae b3
    cmp seleccionado,8
    jae b1
    inc seleccionado
    jmp b3
b1:
    inc indice
b3:
    ret
bajar endp
printlista proc near uses bx cx dx, FsCiz
      mov bx,FsCiz
     inc bl
     inc bl
     inc bh
     mov cx,9 
     cmp nficheros,cx
     ja toda
     mov cx,nficheros
toda:
     cmp cx,0
     je fin_lista
     mov dx,size ffblk
     rseek handle,indice,ffblk
lista:
     gotoxy bl,bh
     puts limpia
     read handle,dx,ffblk
     cmp ax,0
     je ot_n
     gotoxy bl,bh
     puts ffblk._nombre
ot_n:
     inc bh
     loop lista
fin_lista:
     mov bx,FsCiz
     inc bh
     inc bl
     mov dx,bx
     add dx,080fh
     wincolor bh,bl,dh,dl,normal
     add bh,seleccionado
     wincolor bh,bl,bh,dl,inverso
     ret
printlista endp

end

viernes, 30 de agosto de 2013

MANEJO FICHEROS

     Hoy voy a crear las instrucciones para manejo de ficheros.
     Como siempre, primero la cabecera con las macros y las constantes asociadas a su manejo.
  Esta cabecera es muy importante, pues sus funciones son utilizadas, junto con las de SYDIO y WINDOW para todos los programas complejos.
     La funciones  open, close y newfile no se implementan en librerías, pues cuando se usan en un programa no se suelen repetir mucho, por lo que no vale la pena el gasto de código extra para paso de parámetros, frente al tamaño de la macro. Por ello lo mantengo como macro.


IO.MAC 
; 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/>.
; constantes para manejo de unidades
ifndef _unidades
    _unidades equ 1
;unidades
_A equ  0
_B equ 1
_C equ 2
_D equ 3
endif

; constantes para manejo de archivos
ifndef _atributos
   _atributos equ 1
;;atributos de fichero
_O_READ  equ 1
_HIDE    equ 2
_SISTEM  equ 4
_VOL     equ 8
_DIR     equ 16
_ARCHIVO equ 32
_TODOS   equ 00111111B
endif

;posiciones de fseek
_INICIO EQU 0
_FIN    EQU 2
_ULTIMA EQU 3

;; modos de acceso
_R EQU 0
_W EQU 1
_R_W EQU 2

;;Estructuras
_DTA struc
   _RES_DTA DB 21 DUP (?)
   _ATTR    DB ?
   _HORA    DW ?
   _FECHA   DW ?
   _LONG    DD ?
   _NOMBRE  DB 13 DUP (?)
   ENDS

;dispositivos standar
_stdin equ 0
_stdout equ 1
_stderr equ 2
_stdaux equ 3
_stdprn equ 4








;; file direccion cadena ascii fichero
;;handle numero de fichero o codigo de retorno
;;atributo es el tipo de fichero
;;si cf =1 error
;;si cf=0 ax es numero de fichero

newfile macro file,atributo,handle
     mov ah,3ch
     push cx
     push dx
     mov cx,atributo
     lea dx,file
     int 21h
     pop dx
     pop cx
     mov handle,ax
 endm


;abre un fichero. 
; devuelve cf=0 si ok y el handle en la variable handle
;devuelve cf=1 si error y el error en la variable handle
open macro file,atributo,handle

     mov ah,3dh
     mov al,atributo
     push dx
     lea dx,file
     int 21h
     pop  dx
     mov handle,ax
 endm

close macro handle
     mov ah,3eh
     push bx
     mov bx,handle
     int 21h
     pop bx
 endm


;;fichero encontrado esta escrito en la zona DTA
;;      offset descripcion
;;       0      reservado para dos
;;      21      atributo de fichero encontado
;;      22      hora
;;      24      fecha
;;      26      tamaño
;;      30      nombre del fichero y extension
;; devuelve CF=1 si hay error
findfirst macro file,atributo
ifndef _find_first
        extrn _find_first:near
endif
        lea ax,file
        push ax
        mov ax,atributo
        push ax
        call _find_first
  endm


findnext macro
ifndef _find_next
        extrn _find_next:near
endif
        call _find_next
  endm

;; posicion en un fichero el puntero
;; cx marca la parte alta de la direccion
;; para hacerlo mas sencillo nos limitaremos a 65535 bytes por lo que
;; cx=0
;; el metodo es
;;      0    principio fichero
;;      1    desde la posicion actual
;;      2    desde final de fichero
;; devuelve en dx:ax la direccion en que se ha quedado referida al principo del fichero

fseek macro handle,metodo,posicion
ifndef _fseek
        extrn _fseek:near
endif
        mov ax,handle
        push ax        
        mov ax,metodo
        push ax
        mov ax,posicion
        push ax
        call _fseek

 endm

;;obtine direcion de transferencia de disco
;;devuelve en ax un codigo de retorno
;;devuelve en es:bx direccion de DTA
offsetdta macro
      mov ah,2fh
      int 21h
  endm



;READ y WRITE devuelven en ax el número de bytes leidos
;realmente.

read macro handle,n_bytes,buffer
ifndef _read
        extrn _read:near
endif
        mov ax,handle
        push ax
        mov ax,n_bytes
        push AX
        mov ax,offset buffer
        push ax
        call _read

 endm

rseek macro handle,numero,registro

ifndef _rseek
        extrn _rseek:near
endif
        mov ax,handle
        push ax
        mov ax,numero
        push ax
        mov ax,size registro
        push ax
        call _rseek

 endm

setdta macro posicion
      mov ah,1ah
      PUSH DX
      lea dx,posicion
      int 21h
      POP DX
  endm


write macro handle,n_bytes,buffer
ifndef _write
        extrn _write:near
endif
        mov ax,handle
        push ax
        mov ax,n_bytes
        push AX
        lea ax,buffer
        push ax
        call _write

 endm

getpath macro camino,path
ifndef _getpath
      extrn _getpath:near
endif
      lea ax,camino
      push ax
      lea ax,path
      push ax
      call _getpath

endm