.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, CLEAR_TO_END_OF_LINE: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              ;
;         CLEAR_TO_END_OF_LINE                                          ;
; 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
     CALL CLEAR_TO_END_OF_LINE     ;Borra el resto del n£mero de sector
     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 el 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 decimales 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 un '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
     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
