.MODEL    SMALL


;-----------------------------------------------------------------------;
; Graphics characters for border of 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?

     EXTRN     SECTOR:BYTE

.CODE

     PUBLIC    INIT_SEC_DISP
     EXTRN     WRITE_PATTERN:PROC, SEND_CRLF:PROC
     EXTRN     GOTO_XY:PROC
;-----------------------------------------------------------------------;
; Este procedimiento inicializa la pantalla del medio sector.           ;
;                                                                       ;
; Usa:    WRITE_PATTERN, SEND_CRLF, DISP_HALF_SECTOR                    ;
;         WRITE_TOP_HEX_NUMBERS, GOTO_XY                                ;
; Lee:    TOP_LINE_PATTERN, BOTTOM_LINE_PATTERN                         ;
;-----------------------------------------------------------------------;
INIT_SEC_DISP  PROC
     PUSH DX
     XOR  DL,DL               ;Mueve el cursor a la posici¢n de comienzo
     MOV  DH,2                ;de la tercera l¡nea
     CALL GOTO_XY
     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


     PUBLIC    WRITE_HEADER
.DATA
     EXTRN     HEADER_LINE_NO:BYTE
     EXTRN     HEADER_PART_1:BYTE
     EXTRN     HEADER_PART_2:BYTE
     EXTRN     DISK_DRIVE_NO:BYTE
     EXTRN     CURRENT_SECTOR_NO:WORD
.CODE
     EXTRN     WRITE_STRING:PROC, WRITE_DECIMAL:PROC
     EXTRN     GOTO_XY:PROC
;-----------------------------------------------------------------------;
; Este procedimiento escribe la cabecera con la unidad de disco y el    ;
; n£mero de sector                                                      ;
;                                                                       ;
; Usa:    GOTO_XY, WRITE_STRING, WRITE_CHAR, WRITE_DECIMAL              ;
; Lee:    HEADER_LINE_NO, HEADER_PART_1, HEADER_PART_2                  ;
;         DISK_DRIVE_NO, CURRENT_SECTOR_NO                              ;
;-----------------------------------------------------------------------;
WRITE_HEADER   PROC
     PUSH DX
     XOR  DL,DL             ;Mueve el cursor al n£mero de l¡nea de la cabecera
     MOV  DH,HEADER_LINE_NO
     CALL GOTO_XY
     LEA  DX,HEADER_PART_1
     CALL WRITE_STRING
     MOV  DL,DISK_DRIVE_NO
     ADD  DL,'A'            ;Escribe la letra de la unidad, A, B...
     CALL WRITE_CHAR
     LEA  DX,HEADER_PART_2
     CALL WRITE_STRING
     MOV  DX,CURRENT_SECTOR_NO
     CALL WRITE_DECIMAL
     POP  DX
     RET
WRITE_HEADER   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 su- ;
; perior 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 en el lado izquierdo
     MOV  CX,9
     CALL WRITE_CHAR_N_TIMES
     XOR  DH,DH               ;Comienza en 0
HEX_NUMBER_LOOP:
     MOV  DL,DH
     CALL WRITE_HEX
     MOV  DL,' '
     CALL WRITE_CHAR
     INC  DH
     CMP  DH,10h              ;¨Terminado ya?
     JB   HEX_NUMBER_LOOP

     MOV  DL,' '              ;Escribe n£meros hexadecimales sobre la
     MOV  CX,2                ;  ventana ASCII
     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
;-----------------------------------------------------------------------;
; Este procedimiento visualiza la mitad de un sector (256 bytes).       ;
;                                                                       ;
; A la entrada:  DS:DX   Desplazamiento dentro del sector, en bytes.    ;
;                        Debe ser m£ltiplo de 16.                       ;
;                                                                       ;
; Usa:         DISP_LINE, SEND_CRLF                                     ;
;-----------------------------------------------------------------------;
DISP_HALF_SECTOR    PROC
     PUSH CX
     PUSH DX
     MOV  CX,16               ;Visualiza 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 visualiza una l¡nea de datos, o 16 bytes, primero  ;
; en hexadecimal y luego en ASCII.                                      ;
;                                                                       ;
; A la entrada:  DS:DX   Desplazamiento sobre el 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 tres espacios despu‚s de la l¡nea
     CALL WRITE_CHAR_N_TIMES
                          ;Escribe el desplazamiento en hexadecimal
     CMP  BX,100h         ;¨Es el primer d¡gito un 1?
     JB   WRITE_ONE       ;No, escribe el espacio que est  en DL
     MOV  DL,'1'          ;S¡, entonces pone '1' en DL para imprimir
WRITE_ONE:
     CALL WRITE_CHAR
     MOV  DL,BL           ;Copia el byte inferior en DL para imprimirlo en hex
     CALL WRITE_HEX
                          ;Separador
     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 este 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
     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

