home *** CD-ROM | disk | FTP | other *** search
- ;History:1712,1
- ;Thu Feb 22 15:43:22 1990 output the blanks for a tab specially.
- ;Fri Feb 02 07:20:33 1990 don't forget the "more" symbol if we have trailing whitespace.
- ;Wed Nov 15 23:51:43 1989 use num_screen_cols-1 columns.
- ;Tue Nov 14 22:48:37 1989 add scrollbar code.
- ;Fri Jun 02 00:36:53 1989 gotoxy should position the cursor also.
- ;Sun Mar 26 20:45:02 1989 optimize a little code in store_current_window.
- ;06-26-88 23:53:50 in chrout, CR was changing the line w/o setting TRASHED.
- ;05-17-88 22:39:59 Make CGA scroll if only one line [kdb]
- ;05-17-88 22:09:22 Force redraw for CGA [kdb]
- ;05-17-88 19:39:15 Remove reference to scrwait [kdb]
- ;04-01-88 22:42:23 add tab_size to allow for varying tab sizes.
- ;03-26-88 14:37:44 on 40 column screens, fix horizontal scrolling (40 / 2) % 8 != 0
- ;11-16-87 23:18:13 remove memsize
- ;11-15-87 22:50:18 make w1_windseg, and w2_windseg for buffers.asm's sake.
- ;09-09-87 00:48:00 compute the middle of the screen, rather than assuming column 40.
- ;07-13-87 23:08:49 remove xyputch
- ;07-13-87 22:58:51 move the call to paint_screen into init_screen.
- ;07-07-87 22:37:35 also check for eof in trailing blanks code
- ;07-07-87 22:12:44 check for bottom correctly in redraw_line
- ;07-07-87 22:10:54 in redraw_line, move the check where we need it.
- ;07-06-87 06:52:39 use botbot to check for eof, not LINENEW
- .xlist
-
- HT equ 09h
- LF equ 0ah
- CR equ 0dh
- LINENEW equ CR+LF*256 ;the way a newline is stored in memory.
-
- TRAIL_BLANK equ 4dh
- TRAIL_TAB equ 4eh
- MORE_CHAR equ 52h
- NEWLINE_CHAR equ 54h
- UP_CHAR equ 55h
- DOWN_CHAR equ 56h
- TAB_BLANK equ 57h
-
- bufseg segment byte public
-
- extrn toptop: word
- extrn topbot: word
- extrn bottop: word
- extrn botbot: word
-
- extrn linecount: word
- extrn linesbefore: word
-
- bufseg ends
-
- data segment byte public
-
- if 1
- public w1, w2, this_point, this_row, other_row, topbotpercent
- public botpercent, toppercent, firstlimit, lastlimit, overwrite_row
- public overwrite_col, screen_column, window, inversed, inverse_mark
- public showblanks
- endif
-
- ;pointrow contains the row that the cursor is currently on, relative to the
- ; screen boundaries. Pointrow may be negative if the point is above the screen,
- ; or it may be larger than max_screen_line if the point is below the screen.
-
- wind_struc struc
- windseg dw ?
- pointrow dw ?
- firstline db ?
- lastline db ?
- firstpossible db ?
- lastpossible db ?
- firstcolumn dw ?
- wind_struc ends
-
- w1 wind_struc<>
-
- w2 wind_struc<>
-
- public w1_windseg, w2_windseg
- w1_windseg equ w1.windseg
- w2_windseg equ w2.windseg
-
-
- this_point dw ? ;->point in the current file.
- this_row dw ? ;row of point on screen.
- other_row dw ? ;row of point in other window.
-
- topbotpercent label word
- botpercent db ?
- toppercent db ?
-
- firstlastlimits label word
- firstlimit db ?
- lastlimit db ?
-
-
- public tab_size
- tab_size dw 7 ;mask for tab stops.
-
- public next_redisp_line
- next_redisp_line dw 0
-
- public overwrite_flag
- overwrite_flag db 0 ;=0 if not overwriting.
-
- overwrite_rowcol label word
- overwrite_row db 0
- overwrite_col db 0
-
- ;the following externs are in the computer-dependent file
- extrn max_screen_line: byte
- extrn num_screen_cols: byte
-
- ;the following externs are in 'buffers'
- extrn textseg: word
-
- screen_column dw ?
-
- ;window contains a list of which lines should be moved where, and which
- ; lines need to be redrawn. If an entry is positive, then the line which is
- ; currently at x belongs at window[x]. If an entry is TRASHED, it
- ; should be redrawn.
- ;inversed contains a list of which lines currently show inverse video.
- window db 128 dup(?) ;128 is > max_screen_line
- inversed db 128 dup(?) ;. .
- inverse_flag db 0 ;=0 means no inversing.
- public inverse_seg ;used by buffers.asm to adjust.
- inverse_seg dw 0 ;segment of marked buffer.
- public inversing ;used by ibm.asm or z100.asm to control
- inversing dw 0 ; which lines are inversed.
-
- inverse_mark dw ? ;pointing to the inverse mark.
-
- TRASHED equ -1 ;note that TRASHED must be negative.
-
- showblanks db 0
-
- data ends
-
- b_struc struc
- b db ?
- b_struc ends
-
- w_struc struc
- w dw ?
- w_struc ends
-
- byte_ptr label byte
-
- code segment byte public
- ;all the routines in this segment are entered with ds=data, es=data
- assume cs:code, ds:data, es:data
-
-
- ;the following externs are in the computer-dependent file.
- extrn move_line: near
- extrn clear_to_eol: near
- extrn xychrout: near
- extrn hardware_roll_up: near
- extrn hardware_roll_down: near
- extrn position_cursor: near
- extrn read_ibm_cga: near
-
- ;the following externs are in 'memory'
- extrn compute_cursor$: near
- extrn set_line$: near
-
- ;the following externs are in 'buffers'
- extrn buffer_number: near
- ;enter with bx=paragraph of buffer.
- ;exit with ax=number of buffer.
- extrn buffer_allocate: near
- extrn find_buffer: near
- ;enter with cx=buffer number.
- ;exit with nc, dx set to that buffer if it exists, cy otherwise.
-
- ;the following externs are in 'marks'
- extrn read_mark$: near
- extrn goto_mark$: near
- extrn get_split_mark: near
- extrn get_mark: near
- extrn split_at_point: near
- extrn set_mark_si: near
- extrn set_mark: near
- extrn stack_marks: near
- extrn goto_mark: near
-
-
- public read_current_window
- read_current_window:
- mov ax,1 ;probably window 1.
- cmp w2.windseg,0 ;no window 2 - must be 1.
- je read_current_window_1
- mov bl,w1.firstline
- cmp bl,w2.firstline
- jb read_current_window_1
- inc ax
- read_current_window_1:
- ret
-
-
- public store_current_window
- store_current_window:
- cmp ax,1
- jne store_current_window_1
- mov al,w1.firstline
- cmp al,w2.firstline
- jb store_current_window_2
- jmp short store_current_window_3
- store_current_window_1:
- cmp ax,2
- jne store_current_window_2
- mov al,w1.firstline
- cmp al,w2.firstline
- ja store_current_window_2
- store_current_window_3:
- cmp w2.windseg,0 ;is there a second window?
- je store_current_window_2 ;no - don't swap.
- call swap_other_row
- call swap_windows
- store_current_window_2:
- ret
-
-
- swap_other_row:
- mov ax,w1.windseg ;are we in the other window?
- cmp ax,w2.windseg
- jne swap_other_row_1 ;no - no worries.
- push w1.pointrow ;remember what other_row will be.
-
- mov ax,1
- call stack_marks
- mov ax,'*'*256+'0' ;0 := *
- call set_mark
- mov ax,'.'*256+'*' ;* := .
- call set_mark
- mov al,'0' ;. := 0
- call goto_mark
- mov ax,0
- call stack_marks
-
- pop other_row
- swap_other_row_1:
- ret
-
-
- public read_other_window
- read_other_window:
- mov bx,w2.windseg
- or bx,bx
- je read_other_window_1
- call buffer_number
- ret
- read_other_window_1:
- xor ax,ax
- ret
-
-
- public store_other_window
- store_other_window:
- ;enter with ax=buffer segment to show.
- mov cx,ax ;do they want one window?
- jcxz store_other_window_3 ;yes.
- call find_buffer ;find the buffer.
- jc store_other_window_3 ;can't find it - give them one window.
-
- cmp w2.windseg,0 ;do we have another window to set?
- jne store_other_window_1 ;yes - just set it.
- push dx
- call split_screen
- pop dx
- store_other_window_1:
- cmp dx,w2.windseg ;is it already showing?
- je store_other_window_2 ;yes - they're being silly.
-
- mov w2.windseg,dx ;show the buffer here.
-
- cmp w1.windseg,dx ;is this buffer also in w1?
- jne store_other_window_4 ;no - no worries.
-
- mov ax,w1.pointrow ;the place that the this window is at
- mov other_row,ax ; becomes the other row.
-
- mov ax,'.'*256+'*' ;set the split mark to the point.
- call set_mark
-
- store_other_window_4:
- mov bl,w2.firstline ;trash what's there.
- mov al,w2.lastline
- call trash_some_lines
- store_other_window_2:
- ret
-
- store_other_window_3:
- mov w2.windseg,0
- mov al,max_screen_line ;fill the screen with this window.
- mov w1.lastline,al
- mov w1.firstline,0
- mov si,offset w1
- call set_window_percent
- call paint_screen
- ret
-
-
- split_screen:
- mov al,max_screen_line
- mov w2.lastline,al
- sar al,1
- dec al
- mov w1.lastline,al
- add al,2
- mov w2.firstline,al
- split_recompute:
- mov si,offset w1
- call set_window_percent
-
- mov si,offset w2
- call set_window_percent
-
- call paint_screen
-
- ret
-
-
- public store_firstline
- store_firstline:
- cmp w2.windseg,0 ;do we really have two windows?
- je store_firstline_1 ;no.
- cmp w1.firstline,0 ;are we the top window?
- je store_firstline_1 ;yes - we can't set it.
- cmp al,2 ;less than 2?
- jb store_firstline_1 ;yes - would leave no room for the top.
- mov w1.firstline,al
- sub al,2
- mov w2.lastline,al
-
- call split_recompute
- store_firstline_1:
- ret
-
-
- public store_lastline
- store_lastline:
- cmp w2.windseg,0 ;do we really have two windows?
- je store_lastline_1 ;no.
- cmp w1.firstline,0 ;are we the top window?
- jne store_lastline_1 ;no - we can't set it.
- mov ah,max_screen_line
- sub ah,2
- cmp al,ah ;at the screen size?
- ja store_lastline_1 ;yes - would leave no room for the top.
- mov w1.lastline,al
- add al,2
- mov w2.firstline,al
-
- call split_recompute
- store_lastline_1:
- ret
-
-
- public store_showblanks
- store_showblanks:
- cmp showblanks,al ;are we changing it?
- mov showblanks,al ;store it in any case.
- je store_showblanks_1 ;if we changed it, paint the window.
- call paint_window
- store_showblanks_1:
- ret
-
-
- public read_showblanks
- read_showblanks:
- mov al,showblanks
- ret
-
-
- public read_firstline
- read_firstline:
- mov al,w1.firstline
- ret
-
-
- public read_lastline
- read_lastline:
- mov al,w1.lastline
- ret
-
-
- public read_newrow
- read_newrow:
- mov ax,w1.pointrow
- ret
-
-
- public read_firstcolumn
- read_firstcolumn:
- mov ax,w1.firstcolumn
- ret
-
-
- public store_firstcolumn
- store_firstcolumn:
- and ax,not 7 ;go to the next leftmost tab stop.
- push ax
- mov bl,w1.firstline
- mov al,w1.lastline
- call trash_some_lines
- pop w1.firstcolumn
- ret
-
-
- public read_top_percent
- read_top_percent:
- mov al,toppercent
- ret
-
-
- public read_bot_percent
- read_bot_percent:
- mov al,botpercent
- ret
-
-
- public store_top_percent
- store_top_percent:
- mov toppercent,al
- mov si,offset w1
- call set_window_percent
- ret
-
-
- public store_bot_percent
- store_bot_percent:
- mov botpercent,al
- mov si,offset w1
- call set_window_percent
- ret
-
-
- public read_inverse_mark
- read_inverse_mark:
- mov al,inverse_flag
- ret
-
-
- public store_inverse_mark
- store_inverse_mark:
- mov inverse_flag,al
- mov ax,textseg
- mov inverse_seg,ax
- ret
-
- public init_screen
- init_screen:
- xor al,al
- mov w1.firstline,al
- mov w1.firstpossible,al
- mov al,max_screen_line ;fill the screen with this window.
- mov w1.lastline,al
- mov w1.lastpossible,al
- mov w1.firstcolumn,0
- mov ax,textseg
- mov w1.windseg,ax
- call paint_screen
- ret
-
-
- public gotoxy
- gotoxy:
- cmp dl,max_screen_line ;is max_screen_line ok?
- jbe gotoxy_1 ;yes.
- mov dl,max_screen_line ;no - take min(dl, max_screen_line)
- gotoxy_1:
- cmp dh,num_screen_cols ;are we on the screen?
- jb gotoxy_2
- mov dh,num_screen_cols ;no - take min(dh, num_screen_cols-1)
- dec dh
- gotoxy_2:
- mov overwrite_rowcol,dx
- call position_cursor
- ret
-
-
- public chrout
- chrout:
- ;enter with ax=char to "type" on screen.
- ;preserve si.
- cmp overwrite_flag,0 ;are we already overwriting?
- jne chrout_1 ;yes.
- mov overwrite_flag,1 ;say that we're overwriting
- mov window[0],TRASHED ;trash the first line.
- chrout_1:
- mov dx,overwrite_rowcol ;get the cursor position.
- cmp al,CR ;go to left margin?
- jne chrout_4
- mov bh,0 ;trash the line because we're clearing it.
- mov bl,dl
- mov window[bx],TRASHED
- call clear_to_eol ;yes - clear to end here.
- mov dh,0
- jmp chrout_exit
- chrout_4:
- cmp al,LF ;go down a line?
- jne chrout_5
- inc dl
- cmp dl,max_screen_line ;are we past the last line?
- jbe chrout_exit ;no.
- call paint_screen ;yes - paint the whole thing.
- call hardware_roll_up ;yes - roll the screen up.
- jnc chrout_6
- mov dl,1 ;have to software scroll.
- chrout_7:
- mov al,dl
- dec al
- call move_line
- inc dl
- cmp dl,max_screen_line
- jbe chrout_7
- chrout_6:
- mov dl,max_screen_line ;say on the last line.
- push dx ;clear the entire line.
- mov dh,0
- call clear_to_eol
- pop dx
- jmp short chrout_exit
- chrout_5:
- cmp al,HT
- jne chrout_8
- chrout_9:
- mov ah,0
- mov al,' '
- call chrout_putch
- test dh,byte ptr tab_size
- jnz chrout_9
- jmp short chrout_exit
- chrout_8:
- call chrout_putch
- chrout_exit:
- mov overwrite_rowcol,dx ;remember where we are.
- call position_cursor
- ret
-
-
- chrout_putch:
- mov bh,0 ;trash the line.
- mov bl,dl
- mov window[bx],TRASHED
- call xychrout
- inc dh
- ret
-
-
- public redisplay
- redisplay:
-
- mov ax,textseg ;is the current buffer showing in w1?
- cmp ax,w1.windseg
- je redisplay$_1 ;yes - all ok.
-
- xchg w1.windseg,ax ;no - put it in this window.
- cmp ax,w2.windseg ;was the old w1 showing in w2?
- jne redisplay$_2 ;no - nothing special.
-
- push ds
- mov ds,w2.windseg
- mov al,'*' ;yes - make the split mark the point
- call goto_mark$
- pop ds
-
- redisplay$_2:
-
- mov bl,w1.firstline
- mov al,w1.lastline
- call trash_some_lines
-
- mov ax,w1.windseg ;is this buffer also in w2?
- cmp ax,w2.windseg
- jne redisplay$_1 ;no - no worries.
-
- mov bl,w2.firstline ;yes - trash one line so that
- mov bh,0 ; the point is recomputed. hack, hack.
- mov window[bx],TRASHED
-
- mov ax,w2.pointrow ;the place that the other window is at
- mov other_row,ax ; becomes the other row.
-
- mov ax,'.'*256+'*' ;set the split mark to the point.
- call set_mark
-
- redisplay$_1:
-
- mov overwrite_flag,0 ;no longer overwriting.
- mov dx,0 ;start in the upper left hand corner
- mov overwrite_rowcol,dx ; the next time we overwrite.
- if 0
- mov dx,0*256+24 ;dh=column, dl=row.
- mov si,offset window
- rd_0:
- lodsb
- add al,'A'
- call xychrout
- inc dh
- cmp dh,25
- jb rd_0
- mov si,offset inversed
- rd_1:
- lodsb
- add al,'0'
- call xychrout
- inc dh
- cmp dh,48
- jb rd_1
-
- endif
-
- push ds
- mov ds,w1.windseg
- assume ds:bufseg
-
- mov si,topbot
- mov this_point,si
-
- mov ax,next_redisp_line
-
- call force_point_into_window
- mov ax,w1.pointrow
- mov this_row,ax
-
- call redraw_trashed
- call write_scrollbar
-
- mov ax,this_row
- mov w1.pointrow,ax
-
- pop ds
- assume ds:data
-
- mov dx,screen_column
- sub dx,w1.firstcolumn
- mov dh,dl
- mov dl,byte ptr w1.pointrow
- call position_cursor
-
- cmp w2.windseg,0 ;is there a second window?
- je redisplay_one ;no.
- call swap_windows
- push ds
- mov ax,w1.windseg ;are they the same file?
- cmp ax,w2.windseg
- mov ds,ax ;really w2.
- assume ds:bufseg
- jne redisplay__2
- ;two windows into the same buffer.
- call get_split_mark ;get the split mark.
- cmp si,bottop ;are we at the point?
- jne redisplay__1 ;no.
- mov si,topbot ;yes - always use the top point.
- redisplay__1:
- mov this_point,si
- mov ax,other_row ;get the row in the other window.
- mov this_row,ax
- call redraw_trashed
- call write_scrollbar
- mov ax,this_row
- xchg other_row,ax
- sub ax,other_row ;how much did we adjust it by?
- sub w1.pointrow,ax ;adjust pointrow, too.
-
- jmp short redisplay__3
- redisplay__2:
- ;two windows, two buffers.
- mov si,topbot
- mov this_point,si
- xor ax,ax
- call force_point_into_window
- mov ax,w1.pointrow
- mov this_row,ax
- call redraw_trashed
- call write_scrollbar
- mov ax,this_row
- mov w1.pointrow,ax
- redisplay__3:
- call swap_windows
- pop ds
- assume ds:data
- redisplay_one:
- mov next_redisp_line,0 ;no more desired line
- ret
-
-
- code ends
-
- code segment byte public
- ;all the code in this segment is entered with ds=bufseg, es=data
- assume cs:code, ds:bufseg, es:data
-
-
- write_scrollbar:
- mov ax,this_point
- cmp ax,topbot ;is it in the lower half?
- jbe write_scrollbar_3 ;go if yes.
- sub ax,bottop ;change this_point into a count of
- add ax,topbot ; characters before point.
- write_scrollbar_3:
- sub ax,toptop ;now subtract off the beginning.
- mov dl,w1.lastline
- sub dl,w1.firstline
- xor dh,dh
- mul dx
-
- mov cx,topbot
- sub cx,toptop
- add cx,botbot
- sub cx,bottop
- inc cx
-
- div cx
- add al,w1.firstline
- inc al ;remember, we aren't counting the first line.
- mov bl,al
-
- mov dl,w1.firstline
- mov dh,num_screen_cols
- mov ax,8*256+UP_CHAR
- call xychrout
-
- inc dl
- write_scrollbar_1:
-
- mov ax,0b1h ;50% halftone block
- cmp dl,bl ;did we reach our cursor point yet?
- jne write_scrollbar_2
- mov ax,0dbh ;solid block
- write_scrollbar_2:
- call xychrout
-
- inc dl
- cmp dl,w1.lastline
- jbe write_scrollbar_1
-
- mov ax,8*256+DOWN_CHAR
- call xychrout
- ret
-
-
- set_window_percent:
- ;note that set_window_percent doesn't use ds.
- ;enter with si->window to set.
- mov cl,100
- mov ch,data:[si].lastline
- sub ch,data:[si].firstline
- inc ch
- mov al,toppercent
- mul ch
- div cl
- cmp al,ch
- jb set_window_percent_1
- xor al,al
- set_window_percent_1:
- add al,data:[si].firstline
- mov data:[si].firstpossible,al
- mov al,botpercent
- mul ch
- div cl
- mov ch,data:[si].lastline
- sub ch,al
- jae set_window_percent_2
- mov ch,data:[si].lastline
- set_window_percent_2:
- mov data:[si].lastpossible,ch
- ret
-
-
- roll_window_down_2_j_1:
- jmp roll_window_down_2
- roll_window_down_5_j_1:
- jmp roll_window_down_5
-
- roll_window_down:
- ;roll the window down until pointrow is in the window.
-
- mov al,firstlimit
- cbw
- cmp w1.pointrow,ax ;if pointrow>=firstlimit, we don't
- jge roll_window_down_2_j_1 ; need to roll down.
-
- ;Are there any lines now on the screen that will remain? Go if not.
-
- mov cx,w1.pointrow
- mov bh,0
- mov bl,w1.lastline
- add cx,bx
- mov bl,w1.firstline
- sub cx,bx
- mov bl,firstlimit
- cmp cx,bx
- jl roll_window_down_5_j_1 ;we have to repaint the entire window.
-
- ;Repaint screen if CGA, believe it or not, it is faster
- call read_ibm_cga
- cmp al,0
- je roll_window_down_normal
- mov cx,w1.pointrow
- mov bl,firstlimit
- mov bh,0
- sub cx,bx
- inc cx ;Scroll if only one line
- jnz roll_window_down_5_j_1 ; it looks better
-
- roll_window_down_normal:
-
- mov dx,w1.pointrow
- mov cl,w1.firstline
- mov ch,0
- sub dx,cx
- inc dx
-
- ;now compute the number of times we need to roll.
-
- mov cx,w1.pointrow
- sub cx,bx
- mov w1.pointrow,bx ;bx is firstlimit
- neg cx
-
- if 0
- ;Can we use the hardware scroll? Go if not.
-
- cmp w1.firstline,0
- jne roll_window_down_3
- mov al,max_screen_line
- cmp w1.lastline,al
- jne roll_window_down_3
- endif
-
- ;Use the hardware scroll unless there isn't one.
-
- xchg cx,dx ;get the distance to skip
- call skip_to_line
- mov cx,dx
-
- roll_window_down_4:
- mov ah,w1.firstline
- mov al,w1.lastline
- call hardware_roll_down
- jc roll_window_down_3 ;can't hardware roll.
-
- ;now adjust window[] for the change we just made to the screen.
-
- mov bl,w1.firstline
- mov bh,0
- mov al,window[bx] ;save the current values for later.
- mov ah,inversed[bx]
- push ax
- push si
- call redraw_compare ;remember if we're inversing here.
- mov inversed[bx],al
- call redraw_line
- call remember_redrawn
- pop si
- call prevline
- mov window[bx],bl ;remember that this line is real.
- pop ax ;restore the old values.
- roll_window_down_6:
- cmp al,TRASHED ;is this a trashed line?
- je roll_window_down_7
- inc al ;no - say that the line's moved up.
- cmp al,max_screen_line ;did it roll off the screen?
- jbe roll_window_down_7 ;no.
- mov al,TRASHED ;yes - it's gone.
- roll_window_down_7:
- inc bl
- xchg al,window[bx]
- xchg ah,inversed[bx]
- cmp bl,w1.lastline
- jb roll_window_down_6
- loop roll_window_down_4
- jmp short roll_window_down_2
-
- ;repaint screen.
-
- roll_window_down_5:
- call center_this
- jmp short roll_window_down_2
-
- ;Use software scroll. All we do is roll the window array.
-
- roll_window_down_3:
- mov bl,w1.firstline
- mov bh,0
- mov al,window[bx] ;save the current value for later.
- mov ah,inversed[bx]
- mov window[bx],TRASHED
- roll_window_down_1:
- inc bl
- xchg al,window[bx]
- xchg ah,inversed[bx]
- cmp bl,w1.lastline
- jb roll_window_down_1
- loop roll_window_down_3
- roll_window_down_2:
- ret
-
-
- roll_window_up_2_j_1:
- jmp roll_window_up_2
- roll_window_up_5_j_1:
- jmp roll_window_up_5
-
- roll_window_up:
-
- mov al,lastlimit
- cbw
- cmp w1.pointrow,ax ;if pointrow<=lastlimit, we don't
- jle roll_window_up_2_j_1 ; need to roll up.
-
- ;compute: pointrow-(lastline-firstline) > lastlimit
-
- ;Are there any lines now on the screen that will remain? Go if not.
-
- mov cx,w1.pointrow
- mov bh,0
- mov bl,w1.firstline
- add cx,bx
- mov bl,w1.lastline
- sub cx,bx
- mov bl,lastlimit
- cmp cx,bx
- jg roll_window_up_5_j_1 ;we have to repaint the entire window.
-
- ;Repaint screen if CGA, believe it or not, it is faster
- call read_ibm_cga
- cmp al,0
- je roll_window_up_normal
- mov cx,w1.pointrow
- mov bl,lastlimit
- mov bh,0
- sub cx,bx
- dec cx ;Scroll if only one line
- jnz roll_window_up_5_j_1 ; it looks better
-
- roll_window_up_normal:
-
- mov dx,w1.pointrow
- mov cl,w1.lastline
- mov ch,0
- sub dx,cx
- dec dx
-
- ;now compute the number of times we need to roll.
-
- mov cx,w1.pointrow
- sub cx,bx
- mov w1.pointrow,bx ;bx is lastlimit.
-
- ;Can we use hardware scroll? Go if not.
-
- if 0
- cmp w1.firstline,0
- jne roll_window_up_3
- mov al,max_screen_line
- cmp w1.lastline,al
- jne roll_window_up_3
- endif
-
- ;Use the hardware scroll unless there isn't one.
-
- xchg cx,dx ;get the distance to skip
- call skip_to_line
- mov cx,dx
-
- roll_window_up_4:
- mov ah,w1.firstline
- mov al,w1.lastline
- call hardware_roll_up
- jc roll_window_up_3 ;can't hardware roll.
-
- ;now adjust window[] for the change we just made to the screen.
-
- mov bl,w1.lastline
- mov bh,0
- mov al,window[bx] ;save the current values for later.
- mov ah,inversed[bx]
- push ax
- call redraw_compare ;remember if we're inversing here.
- mov inversed[bx],al
- call redraw_line
- call remember_redrawn
- mov window[bx],bl ;remember that this line is real.
- pop ax ;restore old values.
- roll_window_up_6:
- cmp al,TRASHED ;has this line been trashed?
- je roll_window_up_7
- dec al ;no - say the line's been moved.
- roll_window_up_7:
- dec bl
- xchg al,window[bx]
- xchg ah,inversed[bx]
- cmp bl,w1.firstline
- ja roll_window_up_6
- loop roll_window_up_4
- jmp short roll_window_up_2
-
- ;repaint screen.
-
- roll_window_up_5:
- call center_this
- jmp short roll_window_up_2
-
- ;Use software scroll. All we do is roll the window array.
-
- roll_window_up_3:
- mov bl,w1.lastline
- mov bh,0
- mov al,window[bx] ;save the current value for later.
- mov ah,inversed[bx]
- mov window[bx],TRASHED
- roll_window_up_1:
- dec bl
- xchg al,window[bx]
- xchg ah,inversed[bx]
- cmp bl,w1.firstline
- ja roll_window_up_1
- loop roll_window_up_3
- roll_window_up_2:
- ret
-
-
- ;enter with pointrow=current relative screen line
- ;exit with a line inserted before pointrow.
- public window_insert
- window_insert:
- push si
- mov ax,ds ;is this in window 1?
- cmp ax,w1.windseg
- jne window_insert_1
- mov si,offset w1
- call window_ins
- window_insert_1:
- mov ax,ds ;is this in window 2?
- cmp ax,w2.windseg
- jne window_insert_2
- mov si,offset w2
- call window_ins
- window_insert_2:
- mov ax,ds ;are we showing in both windows?
- cmp ax,w1.windseg
- jne window_insert_3
- cmp ax,w2.windseg
- jne window_insert_3
- call split_at_point ;is the split mark at or after the point?
- jnc window_insert_3 ;no
- inc other_row ;yes - must increment the other row.
- window_insert_3:
- pop si
- ret
-
- ;private subroutine, called by window_insert to insert a line in a window.
- ;enter with si-> a window structure.
- window_ins:
- mov bx,data:[si].pointrow
- mov al,data:[si].firstline
- cbw
- cmp bx,ax ;are we above the screen?
- jl window_ins_3 ;yes - exit.
- mov al,data:[si].lastline
- cmp bx,ax ;are we below the screen?
- jg window_ins_2 ;yes - go down a row.
-
- mov window[bx],TRASHED
- mov al,TRASHED
- jmp short window_ins_4
- window_ins_1:
- xchg al,window[bx]
- xchg ah,inversed[bx]
- window_ins_4:
- inc bl
- cmp bl,data:[si].lastline
- jbe window_ins_1
- window_ins_2:
- inc data:[si].pointrow
- window_ins_3:
- ret
-
-
- ;enter with pointrow=current relative screen line
- ;exit with the line at pointrow deleted.
- public window_delete
- window_delete:
- push si
- mov ax,ds ;is this in window 1?
- cmp ax,w1.windseg
- jne window_delete_1
- mov si,offset w1
- call window_del
- window_delete_1:
- mov ax,ds ;is this in window 2?
- cmp ax,w2.windseg
- jne window_delete_2
- mov si,offset w2
- call window_del
- window_delete_2:
- mov ax,ds ;are we showing in both windows?
- cmp ax,w1.windseg
- jne window_delete_3
- cmp ax,w2.windseg
- jne window_delete_3
- call split_at_point ;is the split mark at or after the point?
- jnc window_delete_3 ;no
- dec other_row ;yes - must decrement the other row.
- window_delete_3:
- pop si
- ret
-
- ;private subroutine, called by window_delete to delete a line from a window.
- ;enter with si-> a window structure.
- window_del:
- mov bx,data:[si].pointrow
- mov al,data:[si].firstline
- cbw
- cmp bx,ax ;are we above the screen?
- jl window_del_4 ;yes.
- mov al,data:[si].lastline
- cbw
- cmp bx,ax ;are we below the screen?
- jg window_del_1 ;yes.
-
- mov window[bx],TRASHED ;kill the line the cursor is on.
- jmp short window_del_5 ;go into while...do loop
- window_del_4:
- inc data:[si].pointrow
- jmp short window_del_1
- window_del_3:
- mov al,window[bx+1]
- mov ah,inversed[bx+1]
- mov window[bx],al
- mov inversed[bx],ah
- window_del_5:
- inc bl
- cmp bl,data:[si].lastline
- jb window_del_3
- mov window[bx],TRASHED ;kill lastline
- window_del_1:
- ret
-
-
- public trash_line
- trash_line:
- ;destroy the line that the point is on if it's also in the window.
- mov ax,ds ;is this in window 1?
- cmp ax,w1.windseg
- jne trash_line_1
- mov si,offset w1
- call trash_line_0
- trash_line_1:
- mov ax,ds ;is this in window 2?
- cmp ax,w2.windseg
- jne trash_line_2
- mov si,offset w2
- call trash_line_0
- trash_line_2:
- ret
-
-
- ;enter with si-> a window structure.
- trash_line_0:
- mov bx,data:[si].pointrow
- mov al,data:[si].firstline
- cbw
- cmp bx,ax
- jl trash_line_3
- mov al,data:[si].lastline
- cbw
- cmp bx,ax
- jg trash_line_3
- mov window[bx],TRASHED
- trash_line_3:
- ret
-
-
- public up_lines
- up_lines:
- mov ax,ds ;is this in window 2?
- cmp ax,w1.windseg
- jne up_lines_1
- sub w1.pointrow,bx
- up_lines_1:
- mov ax,ds ;is this in window 2?
- cmp ax,w2.windseg
- jne up_lines_2
- sub w2.pointrow,bx
- up_lines_2:
- ret
-
-
- public down_lines
- down_lines:
- mov ax,ds ;is this in window 1?
- cmp ax,w1.windseg
- jne down_lines_1
- add w1.pointrow,bx
- down_lines_1:
- mov ax,ds ;is this in window 2?
- cmp ax,w2.windseg
- jne down_lines_2
- add w2.pointrow,bx
- down_lines_2:
- ret
-
-
- public paint_screen
- paint_screen:
- ;note that paint doesn't use ds.
- ;what's on the screen is garbage.
- ;preserve si, dx.
- mov bl,0
- mov al,max_screen_line
- call trash_some_lines
- ret
-
-
- center_window:
- ;note that center doesn't use ds.
- ;preserve dx.
- center_this:
- mov cl,w1.lastline ;compute the middle of the screen.
- sub cl,w1.firstline
- sar cl,1
- add cl,w1.firstline
- mov ch,0
- mov w1.pointrow,cx
- mov bl,w1.firstline
- mov al,w1.lastline
- call trash_some_lines
- ret
-
-
- public paint_window
- paint_window:
- ;preserve dx.
- mov ax,textseg
- cmp ax,w1.windseg
- jne paint_window_1
- mov bl,w1.firstline
- mov al,w1.lastline
- call trash_some_lines
- paint_window_1:
- mov ax,textseg
- cmp ax,w2.windseg
- jne paint_window_2
- mov bl,w2.firstline
- mov al,w2.lastline
- call trash_some_lines
- paint_window_2:
- ret
-
-
- trash_some_lines:
- ;enter with bl=first line to destroy, al=last line.
- ;preserve si, dx.
- mov w1.firstcolumn,0 ;go to the first column.
- mov bh,0
- trash_some_lines_0:
- mov window[bx],TRASHED
- inc bl
- cmp bl,al
- jbe trash_some_lines_0
- mov al,w1.firstpossible ;ensure that we're not above the screen.
- cbw
- cmp w1.pointrow,ax
- jge trash_some_lines_1 ;we're not.
- mov w1.pointrow,ax
- trash_some_lines_1:
- mov al,w1.lastpossible ;ensure that we're not below the screen.
- cbw
- cmp w1.pointrow,ax
- jle trash_some_lines_2 ;we're not.
- mov w1.pointrow,ax
- trash_some_lines_2:
- ret
-
-
- ;swap the two window data structures.
- swap_windows:
- mov si,offset w1
- mov di,offset w2
- mov cx,(size wind_struc)
- swap_windows_0:
- mov al,data:[si]
- xchg al,data:[di]
- mov data:[si],al
- inc si
- inc di
- loop swap_windows_0
- ret
-
-
- force_point_into_window:
- ;enter with al=the desired row, =0 if we don't care.
- comment /**********************************************************************
- * roll the window array until pointrow is on the screen.
- * when we roll the array, the lines we roll in must be repainted.
- * for example, assume: screen is 0..23
- * if pointrow is 5, then we're done.
- * if pointrow is -7, then we must roll down 7 lines.
- * if pointrow is <=-24, then we must roll down 24 lines, which says that the
- * entire screen will be repainted.
- * if pointrow is 27, then we must roll up 3 lines.
- * if pointrow is >=48, then we must roll up 24 lines, which says that the
- * entire screen will be repainted.
- *****************************************************************************/
- mov bl,w1.firstpossible
- mov bh,w1.lastpossible
- or al,al ;do we have a desired row?
- je redisplay_1 ;no.
- dec al
- cmp al,bl ;above firstpossible?
- ja redisplay_0 ;yes - ok.
- mov al,bl ;no - clip to firstpossible.
- redisplay_0:
- cmp al,bh ;below lastpossible?
- jb redisplay_00 ;yes - ok.
- mov al,bh ;no - clip to lastpossible.
- redisplay_00:
- mov bl,al
- mov bh,al
- redisplay_1:
- mov firstlastlimits,bx
- ;now truncate firstlimit if we can't get there.
- mov al,firstlimit
- cbw ;compute the number of display lines
- sub al,w1.firstline ; desired before the cursor line.
- cmp ax,linesbefore ;is it even possible to get there?
- jb redisplay_2 ;yes - just do it.
- mov ax,linesbefore ;no - truncate firstlimit to
- add al,w1.firstline ; the largest possible.
- mov firstlimit,al
- redisplay_2:
-
- ;Now update row,col
-
- call compute_cursor$
- mov screen_column,dx
- sub dx,w1.firstcolumn ;are we to the left of the screen?
- jb redisplay_01 ;yes - must roll the screen right.
- cmp dx,word ptr num_screen_cols ;are we on the screen?
- jb redisplay_02 ;yes - we don't have the roll left.
-
- ;roll the window to the left.
-
- comment /
- Eventually, we'll be smart about all this and really scroll the screen.
- For now, we'll repaint the screen every time we roll.
- jmp short redisplay_02
- /
-
- redisplay_01:
-
- ;roll the window to the right.
-
- comment /
- Eventually, we'll be smart about all this and really scroll the screen.
- For now, we'll repaint the screen every time we roll.
- /
-
- add dx,w1.firstcolumn ;restore the cursor position.
- mov bl,w1.firstline
- mov al,w1.lastline
- call trash_some_lines
- mov ax,word ptr num_screen_cols
- shr ax,1
- sub dx,ax ;put the cursor in middle of screen.
- jae redisplay_03
- mov dx,0 ;column is less than 40.
- redisplay_03:
- and dl,not 7 ;back up to previous tab stop.
- mov w1.firstcolumn,dx ;that is where we start redisplaying.......................
- redisplay_02:
-
- ;now roll the screen up or down, as needed.
-
- call roll_window_down
- call roll_window_up
- ret
-
-
- redraw_trashed:
- ;redraw all changed lines if there are any to redraw.
- redraw_trashed_4:
- mov bl,w1.firstline
- mov bh,0
- mov dh,0 ;initially, we don't need to redraw any.
- redraw_trashed_3:
- mov dl,window[bx] ;get new window contents.
- or dh,dl ;remember if we need to redraw any.
- or dl,dl ;if positive, it's a line to be moved.
- js redraw_trashed_5 ;if negative, skip it.
- cmp dl,bl ;is the line already there?
- je redraw_trashed_5 ;yes - skip it.
- mov di,offset window ;is this row referred to?
- mov cl,max_screen_line
- inc cl
- mov ch,0
- mov al,bl
- repne scasb ;scan for the row.
- je redraw_trashed_5 ;yes - we can't move something here.
- call move_line ;move dl to al.
- mov dh,0 ;get the source line.
- mov di,dx
- mov al,inversed[di] ;transfer the inversed contents.
- mov inversed[bx],al
- mov window[bx],bl ;say that this line is where it is.
- jmp redraw_trashed_4 ;restart search.
- redraw_trashed_5:
- inc bl
- cmp bl,w1.lastline
- jbe redraw_trashed_3
-
- cmp inverse_flag,0 ;if we're inversing, we might need to redraw.
- jne redraw_trashed_1
- or dh,dh ;do we need to redraw any lines?
- jns redraw_trashed_9 ;no.
-
- redraw_trashed_1:
- mov bl,w1.firstline
- mov bh,0
- mov cx,this_row ;get the row that the point is on.
- sub cx,bx
- call skip_to_line ;find the first line on the screen.
- call redraw_anyway ;see if we need to redraw anyway.
- redraw_trashed_7:
- call redraw_compare ;remember if we're inversing here.
- mov inversed[bx],al
- cmp window[bx],0
- jns redraw_trashed_a ;if negative, redraw it.
- call redraw_line
- mov window[bx],bl ;remember that this line is drawn.
- redraw_trashed_a:
- call remember_redrawn
- inc bl
- cmp bl,w1.lastline
- jbe redraw_trashed_7
- redraw_trashed_9:
- mov inversing,0 ;say that we're not inversing.
- ret
-
-
- remember_redrawn:
- ;enter with si->text, bx=screen line.
- ;exit with si->next line.
- call nextline
- shl inversed[bx],1
- shl inversed[bx],1
- call redraw_compare
- or inversed[bx],al
- ret
-
-
- redraw_anyway:
- ;preserve si,bx.
- cmp inverse_flag,0
- je redraw_anyway_1
- push si
- push bx
- redraw_anyway_2:
- call redraw_compare
- push ax
- call nextline ;see if this line contains the mark or point.
- call redraw_compare
- pop cx
- mov ch,cl ;save a copy.
- xor cl,al ;see if the bits changed.
- test cl,1 ;is the point in this line?
- jne redraw_anyway_yes ;yes - must redraw.
- shl ch,1
- shl ch,1
- or al,ch ;make up the compare byte.
- cmp al,inversed[bx] ;have they changed?
- je redraw_anyway_no ;no - don't necessarily redraw.
- redraw_anyway_yes:
- mov window[bx],TRASHED ;say that this line is gone.
- redraw_anyway_no:
- inc bl
- cmp bl,w1.lastline
- jbe redraw_anyway_2
- pop bx
- pop si
- redraw_anyway_1:
- ret
-
-
- redraw_compare:
- ;enter with si->text buffer.
- ;exit with al and 1 = 1 if si<point,
- ; al and 2 = 2 if si<mark.
- cmp si,inverse_mark ;set cy if si is below inverse_mark (mark)
- rcl al,1
- cmp si,bottop ;set cy if si is below bottop (point)
- rcl al,1
- and al,3 ;get rid of other bits.
- ret
-
-
-
- skip_to_line:
- ;enter with cx=number of lines to move forward or backward.
- ;Note: positive values move toward top of file.
- ;return si -> beginning of desired line.
- ;don't destroy dx.
- mov si,this_point ;get the point.
- or cx,cx ;is cx negative?
- js skip_to_line_4 ;yes - we have to move forward.
- cmp [si-2].w,LINENEW ;if we're not at the beginning of
- je skip_to_line_3 ; this line, backup to beginning.
- call prevline
- skip_to_line_3:
- jcxz skip_to_line_2
- skip_to_line_1:
- call prevline
- loopne skip_to_line_1
- jne skip_to_line_2 ;did we hit the beginning?
- inc cx ;yes - restore the count.
- sub this_row,cx ;adjust this row.
- jmp short skip_to_line_2
- skip_to_line_4:
- neg cx ;make cx into a positive count.
- ;cx is at least one.
- skip_to_line_5:
- call nextline
- loopne skip_to_line_5
- skip_to_line_2:
- mov al,inverse_flag ;are we inversing?
- cmp al,0
- je skip_to_line_6 ;no.
- push bx
- push dx
- push si
- call get_mark ;the mark is in inverse_flag
- mov inverse_mark,si ;remember where the inverse mark is.
- pop si
- pop dx
- pop bx
- skip_to_line_6:
- ret
-
-
- redraw_line:
- ;enter with si -> line to be redrawn, bl=row of line.
- ;paint from firstcolumn for num_screen_cols columns.
- ;this routine is intense.
- ;preserve cx, bx
- call redraw_set
- mov di,0 ;start at column zero.
- mov dh,0
- mov dl,bl
- mov bl,-1 ;start without trailing blanks.
- cmp si,botbot ;are we at bottom already?
- je redraw_line_9_j_1 ;yes - clear to eol.
- redraw_line_2:
- call redraw_pointer
- cmp si,botbot ;are we at bottom already?
- je redraw_line_3 ;yes - exit.
- mov ax,[si]
- cmp ax,LINENEW ;done with line?
- je redraw_line_3 ;yes - exit.
- inc si
- cmp dh,num_screen_cols ;at right hand column?
- jae redraw_line_d ;yes - don't print.
- cmp di,w1.firstcolumn ;before first column?
- jb redraw_line_4 ;yes - just compute new column.
- cmp al,' ' ;possible trailing blanks.
- je redraw_line_a
- cmp al,HT
- jne redraw_line_b ;not trailing blanks - forget.
- redraw_line_a:
- cmp bl,-1 ;are we already remembering?
- jne redraw_line_c ;yes - don't remember again.
- mov bl,dh ;found a trailing blank character,
- mov bp,si ; remember where it was.
- jmp short redraw_line_c
- redraw_line_b:
- mov bl,-1 ;printable char - forget trailing blanks.
- redraw_line_c:
- call xy_char_put
- jmp redraw_line_2
- redraw_line_d:
- cmp dh,num_screen_cols ;did we just get there?
- ja redraw_line_2 ;no.
- dec dh
- mov ax,8*256+MORE_CHAR ;yes - print the "more" symbol.
- call xychrout
- mov dh,num_screen_cols ;say that we're in the next column.
- inc dh
- jmp redraw_line_2
- redraw_line_4:
- inc di
- cmp al,HT ;only tabs are special
- jne redraw_line_2
- mov ax,di
- add ax,tab_size ;round up to next tab stop.
- or ax,tab_size ;same as 'and not'.
- xor ax,tab_size
- mov di,ax
- jmp redraw_line_2
- redraw_line_9_j_1:
- jmp redraw_line_9
- redraw_line_3:
- cmp showblanks,0 ;should we show blanks?
- je redraw_line_8
- cmp bl,-1 ;are there any trailing blanks?
- je redraw_line_8 ;no.
- mov dh,bl ;restore the column.
- xchg si,bp ;save the current and restore the old.
- dec si
- call redraw_set
- redraw_line_7:
- call redraw_pointer
- cmp si,botbot ;hit the bottom yet?
- je redraw_line_e ;yes - we're done.
- mov ax,[si] ;get the next char.
- cmp ax,LINENEW
- je redraw_line_e
- cmp dh,num_screen_cols
- jae redraw_line_f
- inc si
- cmp al,' ' ;it can only be a tab or a space.
- je redraw_line_6 ;must be a space.
- redraw_line_5:
- cmp dh,num_screen_cols
- jae redraw_line_f
- mov ax,8*256+TRAIL_TAB ;output a trailing tab char.
- call xychrout
- inc dh
- test dh,byte ptr tab_size ;at a tab stop yet?
- jne redraw_line_5 ;no.
- jmp redraw_line_7
- redraw_line_6: ;output a trailing blank char.
- mov ax,8*256+TRAIL_BLANK
- call xychrout
- inc dh
- jmp redraw_line_7
- redraw_line_f:
- dec dh
- mov ax,8*256+MORE_CHAR ;yes - print the "more" symbol.
- call xychrout
- inc dh
- redraw_line_e:
- mov si,bp ;restore the text pointer.
- redraw_line_8:
- cmp dh,num_screen_cols ;put a newline symbol if there's room.
- jae redraw_line_9
- cmp inversing,0 ;only if we're inversing.
- je redraw_line_9
- mov ax,8*256+NEWLINE_CHAR ;newline symbol.
- call xychrout
- inc dh
- redraw_line_9:
- call clear_to_eol
- mov bh,0 ;restore bx.
- mov bl,dl
- ret
-
-
- redraw_pointer:
- ;adjust si from the top to the bottom if necessary, and adjust inversing.
- cmp si,topbot ;at the point yet?
- jne redraw_pointer_1 ;no.
- mov si,bottop
- cmp inverse_flag,0 ;are we inversing?
- je redraw_pointer_1 ;no.
- mov ax,ds
- cmp ax,inverse_seg ;is this our segment?
- jne redraw_pointer_1 ;no.
- not inversing ;say that we've passed the point.
- redraw_pointer_1:
- cmp si,inverse_mark ;are we at the inverse mark?
- jne redraw_pointer_2 ;yes - maybe inverse.
- cmp inverse_flag,0 ;are we inversing?
- je redraw_pointer_2 ;no.
- mov ax,ds
- cmp ax,inverse_seg ;is this our segment?
- jne redraw_pointer_2 ;no.
- not inversing ;say that we've passed the point.
- redraw_pointer_2:
- ret
-
-
- redraw_set:
- cmp si,topbot ;have we hit the top bottm yet?
- jne redraw_set_3
- mov si,bottop
- redraw_set_3:
- cmp inverse_flag,0 ;if we're not inversing, don't inverse.
- je redraw_set_1
- mov ax,ds
- cmp ax,inverse_seg ;is this our segment?
- jne redraw_set_1 ;no.
- call redraw_compare
- cmp si,inverse_mark ;are we exactly at the mark?
- jne redraw_set_2 ;no - just check parity.
- xor al,2 ;yes - flip the associated bit.
- redraw_set_2:
- mov inversing,0 ;say that we're not inversing.
- or al,al ;look for 00,11 or 10,01
- jpe redraw_set_1 ;go if not within point and mark.
- not inversing ;say that we're inversing.
- redraw_set_1:
- ret
-
-
- xy_char_put:
- ;put a char on the screen. Interpret tabs.
- cmp al,HT
- jne xy_char_put_1
- xy_char_put_2:
- mov ax,8*256+TAB_BLANK ;output a tab blank char.
- call xychrout
- inc dh
- test dh,byte ptr tab_size
- jnz xy_char_put_2
- ret
- xy_char_put_1:
- mov ah,0
- call xychrout
- inc dh
- xy_char_put_4:
- ret
-
-
- public prevline
- prevline:
- ;retreat si to the previous line.
- ;return zr if si->beginning of file (and leave si alone)
- ;return nz otherwise.
-
- ;are we at the beginning of the file already?
- cmp si,toptop
- je prevline_beginning ;yes - exit.
-
- ;where are we in the file?
- cmp si,topbot ;at, before or after the point?
- jbe prevline_before
- prevline_after:
- dec si
- cmp si,bottop ;have we reached the top of the bottom?
- je prevline_at ;yes - drop down to prevline_before.
- cmp [si-2].w,LINENEW ;at the beginning of a new line?
- jne prevline_after ;no - keep looking.
- dec si ;did we just find a non-real newline?
- cmp si,bottop ;if we did, then si is now at bottop
- je prevline_at ; and we need to keep searching.
- inc si ;restore si and exit.
- jmp short prevline_exit
-
- prevline_at:
- mov si,topbot ;start searching at the bottom
- inc si ; of the top.
- prevline_before:
- dec si
- cmp [si-2].w,LINENEW ;at the beginning of a new line?
- jne prevline_before ;no - keep looking.
- prevline_exit:
- or si,si ;return nz
- prevline_beginning:
- ret
-
-
- public nextline
- nextline:
- ;advance si to the next line.
- ;return zr if si->end of file (and leave si alone)
- ;return nz otherwise.
- cmp si,topbot
- jne nextline_1
- mov si,bottop
- nextline_1:
- cmp si,botbot
- je nextline_2
- cmp [si].w,LINENEW
- je nextline_3
- inc si
- jmp nextline
- nextline_3:
- add si,2
- or si,si
- ret
- nextline_2:
- push ax
- xor ax,ax
- pop ax
- ret
-
-
- public compute_one
- compute_one:
- cmp al,HT
- jne compute_one_1
- or dl,byte ptr tab_size ;same as 'and not'
- xor dl,byte ptr tab_size
- add dx,tab_size
- compute_one_1:
- inc dx
- ret
-
-
- code ends
-
- end