

.MODEL    SMALL
 
 
;-----------------------------------------------------------------------;
; Caracteres gr ficos del 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?
 
     EXTRN     SECTOR:BYTE
 
.CODE
 
     PUBLIC    INIT_SEC_DISP
     EXTRN     WRITE_PATTERN:PROC, SEND_CRLF:PROC
     EXTRN     GOTO_XY:PROC, WRITE_PHANTOM:PROC
.DATA
     EXTRN     LINES_BEFORE_SECTOR:BYTE
     EXTRN     SECTOR_OFFSET:WORD
.CODE
;-----------------------------------------------------------------------;
; Este procedimiento inicializa la pantalla de la mitad del sector.     ;
;                                                                       ;
; Usa:    WRITE_PATTERN, SEND_CRLF, DISP_HALF_SECTOR                    ;
;         WRITE_TOP_HEX_NUMBERS, GOTO_XY, WRITE_PHANTOM                 ;
; Lee:    TOP_LINE_PATTERN, BOTTOM_LINE_PATTERN                         ;
;         LINES_BEFORE_SECTOR                                           ;
; Escribe: SECTOR_OFFSET                                                ;
;-----------------------------------------------------------------------;
INIT_SEC_DISP  PROC
     PUSH DX
     XOR  DL,DL                    ;Pone el cursor en posici¢n
     MOV  DH,LINES_BEFORE_SECTOR
     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
     MOV  SECTOR_OFFSET,DX    ;Pone a 0 el desplazamiento del sector
     CALL DISP_HALF_SECTOR
     LEA  DX,BOTTOM_LINE_PATTERN
     CALL WRITE_PATTERN
     CALL WRITE_PHANTOM       ;Visualiza el cursor fantasma
     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 de la mitad del 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 sacarlo
                              ; en hexadecimal
     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,' '              ;
     CALL WRITE_CHAR          ;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
 
 
     PUBLIC    WRITE_PROMPT_LINE
     EXTRN     CLEAR_TO_END_OF_LINE:PROC, WRITE_STRING:PROC
     EXTRN     GOTO_XY:PROC
.DATA
     EXTRN     PROMPT_LINE_NO:BYTE
.CODE
;-----------------------------------------------------------------------;
; Este procedimiento escribe la l¡nea de mensajes en la pantalla y      ;
; borra hasta el final de la l¡nea.                                     ;
;                                                                       ;
; A la entrada:  DS:DX Direcci¢n del mensaje de la l¡nea de mensajes.   ;
;                                                                       ;
; Usa:         WRITE_STRING, CLEAR_TO_END_OF_LINE, GOTO_XY              ;
; Lee:         PROMPT_LINE_NO                                           ;
;-----------------------------------------------------------------------;
WRITE_PROMPT_LINE      PROC
     PUSH DX
     XOR  DL,DL               ;Escribe la l¡nea de mensajes y
     MOV  DH,PROMPT_LINE_NO   ; mueve all¡ el cursor
     CALL GOTO_XY
     POP  DX
     CALL WRITE_STRING
     CALL CLEAR_TO_END_OF_LINE
     RET
WRITE_PROMPT_LINE      ENDP
 
     END

