


data segment 
    Pgsize  dw  ?
    buf_size    db   80
    s_buf       db  ?
    buf   db    200 dup(?)
    names  db    20 dup(?)
    cur     dw   ?
    handle  dw  ?
    buf_tmp db  24*80 dup(?)
    cur_tmp dw ?
    name_tmp  db  "t0m1p",0
    handle_tmp  dw ?
    mark    db  ?
    mess_getname  db  0dh,0ah,"    Please input filename: $"
    mess_err1     db  0ah,0dh,"    Illegal filename ! $"
    mess_err2     db  0ah,0dh,"    File not found !$"
    mess_err3     db  0ah,0dh,"    File read error !$"
    mess_psize    db  0ah,0dh,"    Page Size : $"
    mess_dele     db  0dh,0ah,"    The last page is deleted !"
    crlf          db  0ah,0dh,"$"
    mess_star     db  0ah,0dh,"********************************************"
		  db  0ah,0dh,"$"
data ends

code segment
    assume ds:data, cs:code
    main proc far
start:
    push  ds
    sub   ax,ax
    push  ax
    mov   ax,data
    mov   ds,ax

    mov   mark,0
    mov   PgSize,12
    mov   cur,200       ;  File  data  buffer  is  empty
    call  getline       ;  Get file name
    call  openf  ; open the file and creat temporary file, 
                 ; (ax)=0 means no such file
    or    ax,ax
    jnz   display
    mov   dx,offset mess_err2
    mov   ah,09h
    int   21h
    jmp   file_end
display:
    mov cx,PgSize
    mov cur_tmp,0
show_page:
    call read_block   ; read a line from handle to buf
    or   ax,ax
    jnz  next2
    mov  dx,offset mess_err3
    mov  ah,09h
    int  21h		; error in read.
    jmp  file_end
next2:
    call show_and_reserve   ; display a line in buf ,
			    ; and put the line in buf_tmp.
			    ; (bx) returned = 0
                            ; means that the file reach its end.
    or   bx,bx
    jz   file_end	; (bx)=0 : at the end of file.

    or   cx,cx
    jnz  show_page	

; (cx)=0 : end of a page, print a line of stars.

    mov  dx,offset mess_star
    mov  ah,09h
    int  21h
 
; the current page has been on screen,
; and followed by a line of stars.
 
wait_space:
    mov  ah,1
    int  21h
    cmp  al," "
    jnz  psize
    call write_buf_tmp	
; command=space , then reserve the page in temp file.
    jmp  display
psize:
    cmp al,"p"
    jnz delete
    call write_buf_tmp

; the last page is reserved.

    call change_psize
    jmp  stick
delete:
    cmp  al,"d"
    jnz  wait_space

; command is DELETE ,the last page 
; not reserved in temp file.
    mov  mark,1
    mov  dx,offset mess_dele
    mov   ah,09h
    int   21h
stick:
    mov   ah,1
    int   21h
    cmp   al," "
    jnz   stick
    jmp   display
file_end:
    call write_buf_tmp 	; reserve the last page in 
			; temp file.
    cmp  mark,0
    jz   ok
    call write_tmp_back	; write the temp file back
			; to user's file.
ok:
    ret
main endp
;***************************************

;***************************************
change_psize proc near
    push ax
    push bx
    push cx
    push dx
    mov  dx,offset mess_psize
    mov  ah,09h
    int  21h
    mov  ah,01
    int  21h
  
    cmp  al,0dh
    jz   illeg
    sub  al,"0"
    mov  cl,al
getp:
    mov  ah,1
    int  21h
    cmp  al,0dh
    jz   pgot
    sub  al,"0"
    mov  dl,al
    mov  al,cl
    mov  cl,dl     ;  exchange  al  and  cl.

    mov  bl,10
    mul  bl
    add  cl,al
    jmp  getp
pgot:
    mov  dl,0ah
    mov  ah,2
    int  21h	  ; output  0ah to complete the RETURN.
    cmp  cx,0
    jle  illeg
    cmp  cx,24
    jg   illeg
    mov  PgSize,cx
illeg:
    mov  dl,0ah
    mov  ah,09h
    int  21h	   ; output 0ah to complete the RETURN.
    pop  dx
    pop  cx
    pop  bx
    pop  ax
    ret
change_psize endp
;**************************************

;***************************************
openf proc near
    push bx
    push cx
    push dx
    mov  dx,offset names
    mov  al,2
    mov  ah,3dh
    int 21h
    mov  handle,ax
    mov  ax,0
    jc   quit
    mov  dx,offset name_tmp
    mov  cx,0
    mov  ah,3ch
    int  21h
    mov  handle_tmp,ax
    jc   quit
    mov  ax,1
quit:
    pop  dx
    pop  cx
    pop  bx
    ret
openf  endp
;***************************************

;***************************************
getline  proc near
    push ax
    push bx
    push cx
    push dx
    mov   dx,offset mess_getname
    mov   ah,09h
    int   21h
    mov   dx,offset buf_size
    mov   ah,0ah
    int   21h
    mov   dx, offset crlf
    mov   ah,09h
    int   21h
    mov   bl,s_buf
    mov   bh,0
    mov   names[bx],0 ; insert 0 to form the asciiz string.
name_move:
    dec   bx
    mov   al,buf[bx]
    mov   names[bx],al ; move the line got into name string
    jnz   name_move
    pop dx
    pop cx
    pop bx
    pop ax
    ret
getline  endp
;**************************************

;**************************************
read_block proc near
   push   bx
   push   cx
   push   dx
   mov    ax,1
   cmp    cur,200
   jnz    back  
   mov    cx,200
   mov    bx,handle
   mov    dx, offset buf
   mov    ah, 3fh
   int    21h
   mov    cur,0
   mov    ax,1
   jnc    back
   mov    cur,200
   mov    ax,0
back:
   pop    dx
   pop    cx
   pop    bx
   ret
read_block endp
;**************************************

;**************************************
show_and_reserve proc near
    push  ax
    push  dx
    mov   bx,cur
    mov   bp,cur_tmp
loop1:
    cmp   bx,200
    jl    lp
    jmp   exit
lp:
    mov   dl,buf[bx]
    mov   ds:buf_tmp[bp],dl	; (dl) need shown, reserve
				; it in buf_tem.
    inc   bx
    inc   cur
    inc   bp
    inc   cur_tmp

    cmp   dl,1ah      ;  search the file end
    jz    exit_eof
    mov   ah,02
    int   21h		; show the (dl).

    cmp   dl, 0ah
    jz    exit_ln	; if meets RETURN, exit.
    jmp   loop1		; else show another char.

exit_eof:
    mov   bx,0
exit_ln:
    dec   cx
exit:
    pop   dx
    pop   ax
    ret
show_and_reserve endp
;**************************************

;**************************************
write_buf_tmp proc near
    push  ax
    push  bx
    push  cx
    push  dx
    mov   dx,offset buf_tmp
    mov   cx,cur_tmp
    mov   bx,handle_tmp
    mov   ah,40h
    int   21h
    pop   dx
    pop   cx
    pop   bx
    pop   ax
    ret
write_buf_tmp endp
;**************************************

;**************************************
write_tmp_back  proc near
    push   ax
    push   bx
    push   cx
    push   dx
    mov    bx,handle_tmp
    mov    ah,3eh
    int    21h           ; close the temporary file.
    mov    bx,handle
    mov    ah,3eh
    int    21h           ; close the file giving.
    mov    dx,offset name_tmp
    mov    al,0
    mov    ah,3dh
    int    21h 		; open the temporary file for reading.
    mov    handle_tmp,ax
    mov    dx,offset names
    mov    al,1
    mov    ah,3dh
    int    21h          ; reopen the file giving for writing.
    mov    handle,ax
    mov    si,1
wrt_back:
    mov    bx,handle_tmp
    mov    ah,3fh
    mov    cx,200
    mov    dx,offset buf
    int    21h		; read a page bytes from temporary file to buf.
    jc     wrt_end
    mov    si,ax
    mov    bx,handle
    mov    ah,40h
    mov    cx,200
    mov    dx,offset buf
    int    21h		; write a page bytes from buf to the file giving.
    or     si,si
    jnz    wrt_back
    mov    ah,3eh
    mov    bx,handle
    int    21h		; close the file giving.
wrt_end:
    pop    dx
    pop    cx
    pop    bx
    pop    ax
    ret
write_tmp_back endp
;************************************
code ends
end start


    