Metropoli BBS
VIEWER: display.asm MODE: TEXT (ASCII)
; DISPLAY for E32 - Copyright (C) 1994 Douglas Herr
;  all rights reserved

; 11/17/1994: fixed bug causing exception when end of file is at
; right edge of screen and selector limit = file size
; also increased speed of clear_to_edge code

; DISPLAY_CURRENT: display current line
; DISPLAY_SCREEN:  display entire screen

include	model.inc

public	display_current
public	display_screen, display_bottom
public	display_hex
extrn	dwordtohex:near
extrn	tprint:near, tputchr:near, tprintce:near
extrn	find_start:near
extrn	find_next:near
extrn	topline:near

space	equ	20h
CR	equ	0Dh
LF	equ	0Ah
TAB	equ	09h

include	dataseg.inc

three	db '   ',0
extrn	cursor:dword

extrn	top_of_screen:dword
extrn	rows:byte
extrn	dirty_bits:byte
extrn	mark_mode:byte
extrn	mark_start:dword
extrn	mark_end:dword
extrn	cur_posn:word
extrn	normal:byte
extrn	inverse:byte
extrn	filesiz:dword
extrn	columns:byte
extrn	first_row:byte
extrn	left_margin:word
extrn	nul:byte, display_mode:byte

margin_count	dw 0

display	dd offset display_ascii
	dd offset display_hex

@curseg	ends

include	codeseg.inc

;
;  This displays the file buffer on the screen
;
display_screen	proc	near
	call	topline
	movzx	esi,display_mode
	jmp	display[esi]

display_ascii:
	mov	esi,top_of_screen
	mov	dh,first_row
	jmp	short next_row
display_bottom:
	call	find_start
	mov	dx,cur_posn
next_row:
	push	edx
	call	display_line
	pop	edx
	inc	dh
	cmp	dh,rows
	jbe	next_row
	and	dirty_bits,11111110b
	ret
display_screen	endp

;
; This subroutine displays a single line on the screen.  DH holds the
; row number, ESI has the offset into the file buffer.  Tabs are expanded.
; Adjustment is made for side shift.
;
display_current	proc	near
	call	find_start
	mov	dx,cur_posn
display_line:
	xor	edi,edi		; default:mark off
	xor	ecx,ecx
	cmp	mark_mode,0
	je	short d1
	mov	edi,mark_start	; 4-byte mark start
	mov	ecx,mark_end	; 4-byte mark_end

d1:	xor	dl,dl		; start at column zero
	mov	margin_count,0
	push	fs
	pop	es
next_char:
	cmp	esi,filesiz	; at end of file?
	jae	short line_done
	mov	al,es:[esi]
	inc	esi

	cmp	al,CR		; is it CR?
	je	short found_CR
	cmp	al,TAB		; is this a TAB character?
	je	short expand_tab
	call	put_char	; put character on screen
tab_done:
	cmp	dl,columns	; at right edge of screen?
	jb	next_char
	cmp	esi,filesiz	; end of file?
	jae	short line_done
	cmp	byte ptr es:[esi],CR
	je	short not_beyond
	dec	dl
	mov	al,4
	mov	ah,inverse
	call	tputchr
not_beyond:
	jmp	find_next	; find start of next line
found_CR:
	cmp	esi,filesiz
	jae	short line_done
	mov	al,es:[esi]
	inc	esi
	cmp	al,LF
	je	short line_done
	dec	esi
line_done:
	and	dirty_bits,(not 4)
	jmp	short clear_to_edge	; erase the rest of the line
expand_TAB:
	mov	al,' '
	call	put_char
	mov	ax,margin_count
	add	al,dl
	test	al,00000111b	; even multiple of eight?
	jnz	expand_TAB
	jmp	tab_done

display_current	endp

clear_to_edge:
	push	esi			; save file pointer
	mov	al,' '
	mov	ah,normal		; AH = color, AL = character
	cmp	dl,columns		; don't go past edge of screen
	jae	short clear_done
	lea	esi,nul			; point to NUL byte
	call	tprintce		;  just clears to edge of screen
clear_done:
	pop	esi			; restore file pointer
	ret


;
;  This displays a single character on the screen.  If the
;  character is marked, it is displayed in reverse video.
;  Characters outside the current margin are not displayed.
;  Characters left of the margin are skipped.
;

put_char:
	mov	bx,margin_count
	cmp	bx,left_margin	; within left margin?
	jae	short in_window	; yup; show character
	inc	bx
	mov	margin_count,bx
	ret
in_window:
	mov	ah,normal
	cmp	esi,edi		; before start of marked area?
	jbe	short not_marked
	cmp	esi,ecx		; after end of marked area?
	ja	short not_marked
	mov	ah,inverse
not_marked:
	call	tputchr		; update screen
	inc	dl		; next column
	ret


;
; display file in hex mode
;
blankspace	equ	[ebp-10]

display_hex	proc	near
	push	es
	enter	10,0
	mov	edi,top_of_screen
	push	fs
	pop	es
	xor	edx,edx
	mov	dh,first_row

;
; start row with near address
;
row:
	cmp	edi,filesiz
	jae	row4
	lea	esi,blankspace
	mov	eax,edi
	call	dwordtohex
	mov	word ptr 8[esi],':'
	mov	ah,normal
	call	tprint
	add	dl,9
	mov	al,' '
	call	tputchr
	inc	dl
	mov	ecx,16

;
; print 16 hex bytes
;
	push	edi			; save address of start of row
row1:
	cmp	edi,filesiz
	jae	short row2

	lea	esi,blankspace
	push	ecx
	movzx	eax,byte ptr es:[edi]
	call	dwordtohex
	mov	byte ptr 8[esi],0
	add	esi,6
	mov	ah,normal
	cmp	mark_mode,0
	je	short row1a
	cmp	edi,mark_start
	jb	short row1a
	cmp	edi,mark_end
	ja	short row1a
	mov	ah,inverse
row1a:
	cmp	edi,cursor
	jne	short row1b
	xor	ah,08h
row1b:
	call	tprint
	add	dl,2
	mov	ah,normal
	mov	al,' '
	call	tputchr

	pop	ecx
	inc	dl
	inc	edi
	loop	row1

row2:
	inc	ecx
	lea	esi,three
	mov	ah,normal
row3:
	push	ecx
	call	tprint
	add	dl,cl
	pop	ecx
	loop	row3

	pop	esi			; address of start of row

;
; print ASCII characters at right side of screen
;
	mov	ecx,16
ascii:
	cmp	esi,filesiz
	jae	short row4
	mov	al,es:[esi]
	mov	ah,normal
	cmp	mark_mode,0
	je	short ascii0
	cmp	esi,mark_start
	jb	short ascii0
	cmp	esi,mark_end
	ja	short ascii0
	mov	ah,inverse
ascii0:
	cmp	esi,cursor
	jne	short ascii1
	xor	ah,08h
ascii1:
	call	tputchr
	inc	esi
	inc	dl
	loop	ascii

row4:
	lea	esi,nul
	mov	ah,normal
	call	tprintce

; finished with row; set up for next row
	inc	dh
	xor	dl,dl
	cmp	dh,rows
	jbe	row

	leave
	pop	es
	ret

display_hex	endp

@curseg	ends
	end
[ RETURN TO DIRECTORY ]