home *** CD-ROM | disk | FTP | other *** search
- pagesize 86
- v30 equ 0
- test_device equ 0
- cr equ 0dh
- lf equ 0ah
-
- if v30
- ;macros for NEC V20/V30 or Intel 80186/286
- codemacro SHRW parm:ew,count:db ;shift word right by
- db 0c1h ;immediate count
- modrm 5,parm
- db count
- endm
- endif
-
- ;CCPM function EQUs
- mc_max equ 35h
- mc_free equ 39h
-
- codemacro CCPM parm:db ;call CCPM
- db 0b1h ! db parm ;mov cl,parm
- db 0cdh ! db 0e0h ;int 0E0H
- endm
-
- include bufseg.a86 ;buffer definitions
-
- data dseg word public
-
- public textseg
- textseg dw 0ffffh ;segment of current buffer
-
- first_buffer dw 0ffffh ;segment of first buffer
-
- extrn inverse_flag: byte
-
- mcb rb 5 ;memory control block
- mcb_base equ word ptr mcb
- mcb_length equ word ptr mcb+2
- mcb_ext equ byte ptr mcb+4
-
- ;data ends
-
-
- code cseg byte public
- ;all the routines in this segment are entered with ds=data, es=data
- ;*** assume cs:code, ds:data, es:data, ss:data
-
- ;the following externs are in 'memory'
- extrn read_mark: near
- extrn del_to_mark: near
-
- ;the following externs are in 'redisplay'
- extrn redisplay: near
- extrn paint_screen: near
-
- extrn init_entry: near
- extrn uninit_exit: near
-
- extrn abort_fatal: near ;fatal error handler
-
-
- public get_next_buffer
- get_next_buffer:
- push ds
- mov ds,textseg
- ;*** assume ds:bufseg
- mov ax,next_buffer
- pop ds
- ;*** assume ds:data
- ret
-
- public buffer_allocate
- buffer_allocate:
- ;entry:
- ; case cx of
- ; -1..-32768: report the current buffer number.
- ; exit: ax=current buffer number.
- ; 0: create a new buffer.
- ; exit: ax=new buffer number if enough memory, ax=0 otherwise.
- ; 1..32767:
- ; entry: cx=buffer number to select, ax=0 for read/write buffer.
- ; exit: ax=buffer number if it exists, ax=0 otherwise.
- jcxz buffer_allocate_2
- or cx,cx ! jns $+5 ;if cx<0, return buffer number.
- jmp buffer_allocate_7
- ;****** select buffer ******
- push cx
- push ax
- call find_buffer
- jc buffer_allocate_1 ;buffer not found.
-
- push ds
- push dx
- mov ds,dx ;get the current buffer back.
- call select_buffer
- pop dx
- pop ds
-
- pop cx ;pushed as ax =0 if read/write buffer.
- pop ax ;pushed as cx (buffer number).
- ret
-
- buffer_allocate_1:
- add sp,4 ;conserve the stack.
- mov ax,0 ;buffer not found.
- ret
-
- buffer_allocate_2: ;****** create a new buffer ******
- mov mcb_length,1000h ;max. = 64K
- xor ax,ax ! mov mcb_base,ax
- mov mcb_ext,al
- mov dx,offset mcb
- ccpm mc_max ;allocate memory
- or al,al ! jnz buffer_allocate_3;no memory
- mov ax,bufseg_size+0fh
- if v30
- shrw ax,4
- else
- shl ax,1 ! shl ax,1 ! shl ax,1 ! shl ax,1
- endif
- cmp mcb_length,ax
- ja buffer_allocate_4 ;there is enough memory
- mov mcb_ext,0
- mov dx,offset mcb
- ccpm mc_free ;free this small memory block
- buffer_allocate_3:
- xor ax,ax ! ret ;error return
- buffer_allocate_4:
- mov ax,1 ! push es
- mov dx,first_buffer
- cmp dx,0ffffh
- jne buffer_allocate_5
- mov cx,mcb_base
- mov first_buffer,cx
- jmps buffer_allocate_6
- buffer_allocate_5: inc ax
- mov es,dx ! mov dx,es:next_buffer
- cmp dx,0ffffh ! jne buffer_allocate_5
- mov cx,mcb_base
- mov es:next_buffer,cx
- buffer_allocate_6:
- mov cx,mcb_length
- mov es,mcb_base
- mov es:buffer_length,cx
- mov es:next_buffer,0ffffh
- pop es ! push ds ! push ax
- mov ds,mcb_base
- call init_vars?
- call init_marks
- call open_buffer
- pop ax ! pop ds ! ret
-
- buffer_allocate_7: ;****** return current buffer number ******
- mov bx,ss:textseg
- call buffer_number ;return number in ax.
- ret
-
-
- public buffer_insert
- buffer_insert:
- ;enter with al=mark, cx=buffer number.
- ;insert the text between point and mark from the given buffer.
- ;exit with nc if ok, cy if the given buffer doesn't exist, or the specified
- ; text won't fit.
- push textseg
- push ax
- call find_buffer ;find their buffer.
- ;*** assume ds:bufseg
- jc buffer_insert_1 ;not found.
-
- push ds
- push dx
- mov ds,dx ;get the current buffer back.
- call select_buffer
- pop dx
- pop ds
-
- pop ax
-
- push dx
- call read_mark
- pop dx
-
- pop ds ;make ds->our buffer.
- push dx ;save ->their buffer.
- push cx
- call select_buffer
- pop cx
- pop ax ;pushed as dx.
- call insert_string?
- jmps buffer_insert_2
- buffer_insert_1:
- add sp,4 ;get rid of mark, textseg.
- stc
- buffer_insert_2:
- push es ;restore ds.
- pop ds
- ;*** assume ds:data
- ret
-
-
- public buffer_number
- buffer_number:
- ;enter with bx=paragraph of buffer.
- ;exit with ax=number of buffer.
- push ds
- ;*** assume ds:bufseg
- mov dx,ss:first_buffer
- xor ax,ax
- buffer_number_1:
- inc ax
- mov ds,dx
- cmp dx,bx ;is this the one we're looking for.
- mov dx,next_buffer ;in any case, get the next buffer
- jne buffer_number_1
- buffer_number_2:
- pop ds
- ;*** assume ds:data
- ret
-
-
- public succ_buffer
- succ_buffer:
- ;enter with bx=buffer number.
- ;exit with nc, bx=next nonempty buffer, dx=segment of next buffer,
- ; cy if no other buffers or all other buffers are empty.
- push ds
- mov cx,bx
- mov ax,bx
- mov dx,first_buffer
- ;*** assume ds:bufseg
- succ_buffer_2:
- cmp dx,0FFFh ;at the end?
- stc
- je succ_buffer_3 ;yes - don't change the buffer number.
- mov ds,dx
- mov dx,next_buffer
- loop succ_buffer_2
- succ_buffer_0:
- cmp dx,0FFFFh ;are we at the end?
- jne succ_buffer_1
- mov ds,first_buffer ;yes - start from the beginning again.
- mov dx,next_buffer ;skip the first buffer.
- mov ax,1
- succ_buffer_1:
- inc ax ;preincrement.
- cmp ax,bx ;have we wrapped around?
- stc
- je succ_buffer_3 ;yes - exit.
- mov ds,dx ;get the new segment to try.
- mov dx,topbot ;is the next buffer empty?
- sub dx,toptop
- add dx,botbot
- sub dx,bottop
- mov dx,next_buffer
- je succ_buffer_0 ;yes - keep looking.
- mov bx,ax ;return the new buffer number.
- clc
- succ_buffer_3:
- mov dx,ds ;remember the segment.
- ;*** assume ds:data
- pop ds
- ret
-
-
- public find_buffer
- find_buffer:
- ;enter with cx=buffer number.
- ;exit with nc, dx set to that buffer if it exists, cy otherwise.
- mov dx,first_buffer
- ;*** assume ds:bufseg
- find_buffer_1:
- cmp dx,0FFFFh ;at the end?
- je find_buffer_2
- mov ds,dx
- mov dx,next_buffer
- loop find_buffer_1
- mov dx,ds ;get the current buffer back.
- push es
- pop ds
- clc
- ret
- find_buffer_2:
- push es ;restore the data segment.
- pop ds
- ;*** assume ds:data
- stc
- ret
-
-
- ;code ends
-
-
- code cseg byte public
- ;all the code in this segment is entered with ds=bufseg, es=data
- ;*** assume cs:code, ds:bufseg, es:data
-
- ;the following externs are in 'memory'
- extrn init_vars?: near
- extrn insert_string?: near
-
- ;the following externs are in 'marks'
- extrn init_marks: near
-
- ;the following externs are in 'redisp'
- extrn adjust_buffers: near
-
-
- select_buffer:
- ;enter with ds=buffer to select.
- mov ss:textseg,ds ;save the new current buffer.
- mov ax,botbot
- sub ax,toptop
- mov dx,0
- mov cx,100
- div cx
- mov memsize,ax
- ret
-
- close_buffer:
- ;close the buffer in ds.
- mov ax,topbot ;if topbot<>bottop, then it's open.
- cmp ax,bottop
- je close_buffer_1 ;if it's already closed, we're done.
- mov di,topbot
- if 1
- mov ax,ds ;if it's open and it's not the first
- cmp ax,ss:first_buffer ; buffer, close it.
- jne close_buffer_2
- add di,2000 ;leave at most this many free bytes
- cmp di,bottop ; in buffer one.
- jae close_buffer_1 ;but if we can't leave that many, don't bother
- close_buffer_2:
- endif
- mov si,bottop
- mov bottop,di ;save the new bottop.
- mov cx,botbot
- sub cx,si ;same as sub cx,bottop
- add cx,2 ;include the trailing newline.
- push es
- push ds
- pop es
- rep movsb
- pop es
- sub di,2 ;don't include the newline in botbot.
- mov botbot,di
- close_buffer_1:
- ret
-
-
- open_buffer:
- ;select the buffer in ds.
- ;enter with ds=buffer to open.
- mov bx,buffer_length
- mov ax,ds
- mov di,bx
- add bx,ax ;make bx=first unused para.
- mov cl,04 ;change di from paras into bytes
- shl di,cl
- push es
- push ds
- pop es
- mov si,botbot
- std
- mov cx,botbot
- sub cx,bottop
- inc si
- dec di
- movsb ;move the LF
- mov botbot,di
- movsb ;move the CR
- rep movsb
- inc di
- mov bottop,di
- cld
- pop es
- call select_buffer
- ret
-
- buffer_paragraphs:
- ;compute the number of paragraphs used by a buffer.
- ;enter with ds=buffer
- ;exit with cx=number of paragraphs.
- mov cx,botbot
- add cx,0fh+2 ;round up to next paragraph plus two for newline
- rcr cx,1 ;ensure that 65536 bytes becomes
- shr cx,1 ; 1000h paragraphs.
- shr cx,1
- shr cx,1
- ret
-
-
- ;code ends
-
- end
-