.MODEL    SMALL


;-----------------------------------------------------------------------;
; Caracteres gr ficos para el borde del sector                          ;
;-----------------------------------------------------------------------;
VERTICAL_BAR   EQU     0BAh
HORIZONTAL_BAR EQU     0CDh
UPPER_LEFT     EQU     0C9h
UPPER_RIGHT    EQU     0BBh
LOWER_LEFT     EQU     0C8h
LOWER_RIGHT    EQU     0BCh
TOP_T_BAR      EQU     0CBh
BOTTOM_T_BAR   EQU     0CAh
TOP_TICK       EQU     0D1h
BOTTOM_TICK    EQU     0CFh


.DATA

TOP_LINE_PATTERN       LABEL  BYTE
     DB   ' ',7
     DB   UPPER_LEFT, 1
     DB   HORIZONTAL_BAR,12
     DB   TOP_TICK,1
     DB   HORIZONTAL_BAR,11
     DB   TOP_TICK,1
     DB   HORIZONTAL_BAR,11
     DB   TOP_TICK,1
     DB   HORIZONTAL_BAR,12
     DB   TOP_T_BAR,1
     DB   HORIZONTAL_BAR,18
     DB   UPPER_RIGHT,1
     DB   0
BOTTOM_LINE_PATTERN    LABEL  BYTE
     DB   ' ',7
     DB   LOWER_LEFT, 1
     DB   HORIZONTAL_BAR,12
     DB   BOTTOM_TICK,1
     DB   HORIZONTAL_BAR,11
     DB   BOTTOM_TICK,1
     DB   HORIZONTAL_BAR,11
     DB   BOTTOM_TICK,1
     DB   HORIZONTAL_BAR,12
     DB   BOTTOM_T_BAR,1
     DB   HORIZONTAL_BAR,18
     DB   LOWER_RIGHT,1
     DB   0

.DATA?

     PUBLIC    SECTOR
SECTOR    DB   8192 DUP (?)

.CODE

     PUBLIC    INIT_SEC_DISP
     EXTRN     WRITE_PATTERN:PROC, SEND_CRLF:PROC
;-----------------------------------------------------------------------;
; Este procedimiento inicializa la pantalla del medio sector            ;
;                                                                       ;
; Usa:         WRITE_PATTERN, SEND_CRLF, DISP_HALF_SECTOR               ;
;              WRITE_TOP_HEX_NUMBERS                                    ;
; Lee:    TOP_LINE_PATTERN, BOTTOM_LINE_PATTERN                         ;
;-----------------------------------------------------------------------;
INIT_SEC_DISP  PROC
     PUSH DX
     CALL WRITE_TOP_HEX_NUMBERS
     LEA  DX,TOP_LINE_PATTERN
     CALL WRITE_PATTERN
     CALL SEND_CRLF
     XOR  DX,DX               ;Comienza al principio del sector
     CALL DISP_HALF_SECTOR
     LEA  DX,BOTTOM_LINE_PATTERN
     CALL WRITE_PATTERN
     POP  DX
     RET
INIT_SEC_DISP  ENDP

     EXTRN     WRITE_CHAR_N_TIMES:PROC, WRITE_HEX:PROC, WRITE_CHAR:PROC
     EXTRN     WRITE_HEX_DIGIT:PROC, SEND_CRLF:PROC
;-----------------------------------------------------------------------;
; Este procedimiento escribe los n£meros ¡ndice (0 a F) en la parte     ;
; superior de la pantalla del medio sector.                             ;
;                                                                       ;
; Usa:    WRITE_CHAR_N_TIMES, WRITE_HEX, WRITE_CHAR                     ;
;         WRITE_HEX_DIGIT, SEND_CRLF                                    ;
;-----------------------------------------------------------------------;
WRITE_TOP_HEX_NUMBERS  PROC
     PUSH CX
     PUSH DX
     MOV  DL,' '              ;Escribe 9 espacios para el lado izquierdo
     MOV  CX,9
     CALL WRITE_CHAR_N_TIMES
     XOR  DH,DH               ;Comienza por 0
HEX_NUMBER_LOOP:
     MOV  DL,DH
     CALL WRITE_HEX
     MOV  DL,' '
     CALL WRITE_CHAR
     INC  DH
     CMP  DH,10h              ;¨Ha terminado?
     JB   HEX_NUMBER_LOOP

     MOV  DL,' '              ;Escribe n£meros hex encima de la ventana ASCII
     MOV  CX,2
     CALL WRITE_CHAR_N_TIMES
     XOR  DL,DL
HEX_DIGIT_LOOP:
     CALL WRITE_HEX_DIGIT
     INC  DL
     CMP  DL,10h
     JB   HEX_DIGIT_LOOP
     CALL SEND_CRLF
     POP  DX
     POP  CX
     RET
WRITE_TOP_HEX_NUMBERS  ENDP

     PUBLIC    DISP_HALF_SECTOR
     EXTRN     SEND_CRLF:PROC

;-----------------------------------------------------------------------;
; This procedure displays half a sector (256 bytes)                     ;
;                                                                       ;
; On entry:    DS:DX   Offset into sector, in bytes -- should be        ;
;              multiple of 16.                                          ;
;                                                                       ;
; Uses:        DISP_LINE, SEND_CRLF                                     ;
;-----------------------------------------------------------------------;
DISP_HALF_SECTOR       PROC
     PUSH CX
     PUSH DX
     MOV  CX,16               ;Muestra 16 l¡neas
HALF_SECTOR:
     CALL DISP_LINE
     CALL SEND_CRLF
     ADD  DX,16
     LOOP HALF_SECTOR
     POP  DX
     POP  CX
     RET
DISP_HALF_SECTOR       ENDP


     PUBLIC    DISP_LINE
     EXTRN     WRITE_HEX:PROC
     EXTRN     WRITE_CHAR:PROC
     EXTRN     WRITE_CHAR_N_TIMES:PROC
;-----------------------------------------------------------------------;
; Este procedimiento muestra una l¡nea de datos, o 16 bytes, primero en ;
; hex y despu‚s en ASCII.                                               ;
;                                                                       ;
; A la entrada:        DS:DX  Desplazamiento dentro del sector, en bytes;
;                                                                       ;
; Usa:    WRITE_CHAR, WRITE_HEX, WRITE_CHAR_N_TIMES                     ;
; Lee:    SECTOR                                                        ;
;-----------------------------------------------------------------------;
DISP_LINE PROC
     PUSH BX
     PUSH CX
     PUSH DX
     MOV  BX,DX          ;El desplazamiento es m s £til en BX
     MOV  DL,' '
     MOV  CX,3           ;Escribe 3 espacio delante de la l¡nea
     CALL WRITE_CHAR_N_TIMES
                         ;Escribe el desplazamiento en  hex
     CMP  BX,100h        ;¨Es el primer d¡gito un 1?
     JB   WRITE_ONE      ;No, escribe el espacio que ya esta en DL
     MOV  DL,'1'         ;S¡ entonces pone un '1' en DL para imprimirlo
WRITE_ONE:
     CALL WRITE_CHAR
     MOV  DL,BL          ;Copia el byte inferior en DL para imprimirlo en hex
     CALL WRITE_HEX
                         ;Separador de escritura
     MOV  DL,' '
     CALL WRITE_CHAR
     MOV  DL,VERTICAL_BAR     ;Dibuja el lado izquierdo del recuadro
     CALL WRITE_CHAR
     MOV  DL,' '
     CALL WRITE_CHAR
                          ;Ahora escribe 16 bytes
     MOV  CX,16           ;Vuelca 16 bytes
     PUSH BX              ;Salva el desplazamiento para ASCII_LOOP
HEX_LOOP:
     MOV  DL,SECTOR[BX]   ;Lee 1 byte
     CALL WRITE_HEX       ;Vuelca el byte en hexadecimal
     MOV  DL,' '          ;Escribe un espacio entre los n£meros
     CALL WRITE_CHAR
     INC  BX
     LOOP HEX_LOOP

     MOV  DL,VERTICAL_BAR ;Separador de escritura
     CALL WRITE_CHAR
     MOV  DL,' '          ;A¤ade otro espacio delante de los caracteres
     CALL WRITE_CHAR

     MOV  CX,16
     POP  BX              ;Vuelve a poner el desplazamiento en SECTOR
ASCII_LOOP:
     MOV  DL,SECTOR[BX]
     CALL WRITE_CHAR
     INC  BX
     LOOP ASCII_LOOP

     MOV  DL,' '          ;Dibuja el lado derecho del recuadro
     CALL WRITE_CHAR
     MOV  DL,VERTICAL_BAR
     CALL WRITE_CHAR

     POP  DX
     POP  CX
     POP  BX
     RET
DISP_LINE ENDP


     END
