;=========================================================
; Author: Chen Jean-Yuan         NCU-MIS 2A     No.790854
;=========================================================

extrn     display_:near
extrn     ins_line:near
extrn     del_line:near
extrn     put_buff:near
extrn     get_buff:near
extrn     find_ptr:near
extrn     load_act:near
extrn     save_act:near
extrn     write_act:near
extrn     print_act:near
extrn     newing:near
extrn     help_win:near
extrn     chg_drive:near
extrn     p_ptr:word
extrn     q_ptr:word
extrn     r_ptr:word
extrn     free_top:word
extrn     free_ptr:word
extrn     line_buf:byte
extrn     block_top:word
extrn     block_end:word

public    info_win,refresh_,new_act,here_dir,read_line,show_name
public    new_start,new_end,total_l,top_,bottom_,y_table,monitor,cursor_y
public    file_top,file_ptr,file_name,handle_,this_dir
public    psp_start

space     equ      20h
color1    equ      07h
color2    equ      02h
color3    equ      07h
reverse1  equ      70h
reverse2  equ      70h
reverse3  equ      70h
escape    equ      1                    ;-----+
enter_s   equ      28                   ;     |
f10       equ      68                   ;     |
f1        equ      59                   ;     |
f2        equ      60                   ;     |
f3        equ      61                   ;     |
pgup      equ      73                   ;     |
pgdn      equ      81                   ;     |
ctrl_pgup equ      132                  ;     |
ctrl_pgdn equ      118                  ;     |
up        equ      72                   ;     |
left      equ      75                   ;     |
right     equ      77                   ; Scan Code
down      equ      80                   ;     |
inskey    equ      82                   ;     |
delkey    equ      83                   ;     |
homekey   equ      71                   ;     |
endkey    equ      79                   ;     |
d_key     equ      32                   ;     |
o_key     equ      24                   ;     |
m_key     equ      50                   ;     |
b_key     equ      48                   ;     |
k_key     equ      37                   ;     |
h_key     equ      35                   ;     |
p_key     equ      25                   ;     |
n_key     equ      49                   ;     |
y_key     equ      21                   ;-----+

backspace equ      8                    ;-----+
escape_a  equ      27                   ; ASCII Code
enter_a   equ      13                   ;-----+

win_max   equ      4
file_max  equ      6
utl_max   equ      5
block_max equ      7

GET_CHAR  MACRO
          push     ax
          pushf
          mov      ah,0
          int      16h
          mov      char,ah
          popf
          pop      ax
          ENDM

GET_KEY   MACRO
          push     ax
          pushf
          mov      ah,0
          int      16h
          mov      scan_key,ah
          mov      ascii_key,al
          popf
          pop      ax
          ENDM

NEW_      MACRO                         ;AX register save the Segment
          LOCAL    over_z,exist_
          push     es
          push     bx
          cmp      free_top,0
          jne      exist_

          add      new_end,2
          mov      ax,new_end
          jmp      over_z

  exist_: mov      ax,free_top
          mov      es,ax
          mov      bx,es:[0]
          mov      free_top,bx
  over_z: pop      bx
          pop      es
          ENDM

FREE_     MACRO    _ptr
          LOCAL    n_empt,free_z
          push     es
          pushf
          mov      ax,_ptr
          cmp      free_top,0
          jne      n_empt
          mov      free_top,ax
          jmp      free_z

  n_empt: mov      es,free_ptr
          mov      es:[0],ax
  free_z: mov      free_ptr,ax
          mov      es,ax
          mov      word ptr es:[0],0
          popf
          pop      es
          ENDM

GOTOXY    MACRO    x,y
          mov      dh,y
          mov      dl,x
          inc      dh
          dec      dl
          mov      bh,0
          mov      ah,2
          int      10h
          ENDM

CURSOR_1  MACRO
          push     cx
          mov      ch,0bh
          mov      cl,0ch
          mov      ah,1
          int      10h
          pop      cx
          ENDM

CURSOR_0  MACRO
          push     cx
          mov      ch,1ch
          mov      cl,1bh
          mov      ah,1
          int      10h
          pop      cx
          ENDM

data      segment  public
top_      db 0,0,24,'===== Top of File ======'
          db 5 dup(0)
bottom_   db 0,0,24,'==== Bottom of File ===='
          db 5 dup(0)
monitor   dw ?
win_x     dw ?
win_y     dw ?
cursor_x  dw ?
cursor_y  dw ?
total_l   dw ?
psp_start dw ?
new_start dw ?
new_end   dw ?
pos_x     db ?
pos_y     db ?
col_start dw ?
p_lin     dw ?
q_lin     dw ?
r_lin     dw ?
file_top  dw ?
file_ptr  dw ?
file_name db 'NONAME.DOC',3 dup(0)
this_dir  db 80 dup(0)
handle_   dw ?
char      db ?
scan_key  db ?
ascii_key db ?
info_key  db ?
ins_flag  db ?
sub_line  db 256 dup(?)
y_table   dw    0, 160, 320, 480, 640, 800, 960,1120,1280,1440,1600,1760,1920
          dw 2080,2240,2400,2560,2720,2880,3040,3200,3360,3520,3680,3840
win_head  db '    File     Edit     Utility     Block '
          db '           °±² NCU MIS-2A  No.790854 ²±°'
edit_head db 'ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍµ Edi'
          db 'tor ÆÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ'
ins_fun   db                                   'ÍÍÍÍÍÍ'
ins_val   db                                   'Insert'
win_info  db ' F1-Help  F2-Save  F3-Load  F10-Menu    '  ;----+
          db '     º Total '                             ;    |
  str_ttl db              '     '                        ;    |
win_info2 db                   ' ³ Line '                ;  Info
  str_y   db                           '     '           ;    |
win_info3 db                                ' Col '      ;    |
  str_x   db                                     '    '  ;----+
win_file  db 15,8,color2
          db 'ÚÄÄÄÄÄÄÄÄÄÄÄÄÄ·'
          db '³ Load     F3 º'
          db '³ Save     F2 º'
          db '³ Write to    º'
          db '³ New         º'
          db '³ OS Shell    º'
          db '³ Exit        º'
          db 'ÔÍÍÍÍÍÍÍÍÍÍÍÍÍ¼'
win_utl   db 20,7,color2
          db 'ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ·'
          db '³ Help          F1 º'
          db '³ Change Drive     º'
          db '³ Time & Date      º'
          db '³ Print File       º'
          db '³ Lock Terminal    º'
          db 'ÔÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ¼'
win_block db 30,9,color2
          db 'ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ·'
          db '³ Set Begin     Shift-Ctrl-B º'
          db '³ Set End       Shift-Ctrl-K º'
          db '³ Copy Block    Shift-Ctrl-O º'
          db '³ Delete Block  Shift-Ctrl-D º'
          db '³ Move Block    Shift-Ctrl-M º'
          db '³ Hide Block    Shift-Ctrl-H º'
          db '³ Print Block   Shift-Ctrl-P º'
          db 'ÔÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ¼'
good_bye  db 'Thanks for Using this Editor !!! $'
data      ends
;---------------------------------------
code      segment  public
          assume   cs:code,ds:data,ss:stack

main      proc     far
          org      100h

  start:  push     ds
          mov      ax,data
          mov      ds,ax

          pop      ax
          mov      psp_start,ax         ;Save PSP addr. of Segment

          mov      ax,sp
          mov      cl,4
          shr      ax,cl
          mov      cx,ss
          add      ax,cx
          inc      ax
          mov      new_start,ax
          mov      new_end,ax

          int      11h                  ;Initalize Monitor Type
          and      al,00110000b
          cmp      al,00110000b
          mov      monitor,0B000h       ;Mono
          je       over_s
          add      monitor,800h         ;Color
  over_s:
          mov      al,0                 ;Clear Screen
          mov      ch,2
          mov      cl,0
          mov      dh,22
          mov      dl,79
          mov      bh,07
          mov      ah,6
          int      10h
          mov      win_x,1              ;Initialize New Values
          mov      cursor_x,1
          mov      cursor_y,1
          mov      total_l,1
          mov      col_start,1
          mov      pos_x,1
          mov      pos_y,2
          mov      block_top,1
          mov      block_end,1
          mov      free_top,0
          mov      ins_flag,0

          NEW_
          mov      word ptr top_,ax
          mov      ax,seg top_
          add      ax,2
          push     es
          mov      es,word ptr top_
          mov      es:[0],ax
          mov      byte ptr es:[2],0
          mov      word ptr es:[30],0
          pop      es

          call     here_dir
          call     title_win
          call     info_win
          call     show_name
          GOTOXY   pos_x,pos_y
          mov      ax,0
          push     ax
          mov      ax,1
          push     ax
          call     display_

  get_c:  GET_KEY
          xor      ax,ax                ;If Shift-Ctrl Both pressed
          mov      es,ax
          mov      al,es:[417h]
          and      al,00000111b
          cmp      al,4
          jbe      chk_k
          call     s_c_key
          jmp      get_c

  chk_k:  cmp      ascii_key,0
          je       key_0
          cmp      ascii_key,224
          je       key_0
          jmp      comm_
  key_0:  cmp      scan_key,f10         ;F10 pressed
          jne      key_1
          call     windows
          jmp      get_c
  key_1:  cmp      scan_key,up          ;Up-Arrow pressed
          jne      key_2
          cmp      cursor_y,1
          je       no_ch1
          dec      cursor_y
          call     info_win
          cmp      pos_y,1
          je       st_ch1
          dec      pos_y
          GOTOXY   pos_x,pos_y
          jmp      get_c

  st_ch1: call     refresh_
          jmp      get_c

  no_ch1: mov      pos_y,2
          GOTOXY   pos_x,pos_y
          call     refresh_
          jmp      get_c

  key_2:  cmp      scan_key,down        ;Down-Arrow pressed
          jne      key_3
          mov      ax,total_l
          cmp      cursor_y,ax
          je       no_ch2
          inc      cursor_y
          call     info_win
          cmp      pos_y,21
          je       st_ch2
          inc      pos_y
          GOTOXY   pos_x,pos_y
          jmp      get_c

  st_ch2: call     refresh_
          jmp      get_c

  no_ch2: cmp      total_l,20
          jae      mor_20
          jmp      get_c
  mor_20: mov      pos_y,20
          GOTOXY   pos_x,pos_y
          call     refresh_
          jmp      get_c

  key_3:  cmp      scan_key,left        ;Left-Arrow pressed
          jne      key_4
          cmp      cursor_x,1
          je       no_ch3
          dec      cursor_x
          call     info_win
          cmp      pos_x,1
          je       st_ch3
          dec      pos_x
          GOTOXY   pos_x,pos_y
          jmp      st__3

  st_ch3: dec      col_start
  st__3:  call     refresh_

  no_ch3: jmp      get_c

  key_4:  cmp      scan_key,right       ;Right-Arrow pressed
          jne      key_5
          cmp      cursor_x,256
          je       no_ch4
          inc      cursor_x
          call     info_win
          cmp      pos_x,80
          je       st_ch4
          inc      pos_x
          GOTOXY   pos_x,pos_y
          jmp      no_ch4

  st_ch4: inc      col_start
          call     refresh_

  no_ch4: jmp      get_c

  key_5:  cmp      scan_key,delkey      ;Delete Key pressed
          jne      key_6
          mov      ax,cursor_y
          push     ax
          call     find_ptr
          call     put_buff             ;Put Linked-List in Line-Buffer
          mov      ax,cursor_x
          dec      ax
          cmp      line_buf,al
          ja       shf_d1
          mov      ax,cursor_y
          inc      ax
          cmp      ax,total_l
          jae      no_del               ;No Act at Last 2 Line
          call     extra_del
  no_del: jmp      get_c

  shf_d1: xor      cx,cx
          mov      cl,line_buf
          mov      di,offset line_buf
          add      di,ax
          sub      cx,ax
  shf_d2: inc      di
          mov      al,[di+1]
          mov      [di],al
          loop     shf_d2
          dec      line_buf
          call     get_buff
          call     refresh_
          jmp      get_c

  key_6:  cmp      scan_key,homekey     ;Home Key pressed
          jne      key_7
          mov      pos_x,1
          GOTOXY   pos_x,pos_y
          mov      cursor_x,1
          call     info_win
          mov      col_start,1
          call     refresh_
          jmp      get_c

  key_7:  cmp      scan_key,endkey       ;End Key pressed
          jne      key_8
          mov      ax,cursor_y
          push     ax
          call     find_ptr
          call     put_buff
          xor      ax,ax
          mov      al,line_buf
          mov      cursor_x,ax
          inc      cursor_x
          call     info_win
          cmp      line_buf,78
          ja       at_80
          mov      pos_x,al
          inc      pos_x
          GOTOXY   pos_x,pos_y
          mov      col_start,1
          call     refresh_
          jmp      get_c

  at_80:  mov      pos_x,80
          push     ax
          GOTOXY   pos_x,pos_y
          pop      ax
          sub      ax,78
          mov      col_start,ax
          call     refresh_
          jmp      get_c

  key_8:  cmp      scan_key,inskey      ;Insert Key pressed
          jne      key_9
          mov      di,offset ins_fun
          cmp      ins_flag,0
          je       inson
          mov      cx,6
  insoff: mov      byte ptr [di],'Í'
          inc      di
          loop     insoff
          mov      ins_flag,0
          call     title_win
          jmp      get_c

  inson:  mov      si,offset ins_val
          mov      ax,seg ins_fun
          mov      es,ax
          cld
          mov      cx,6
  rep     movsb
          mov      ins_flag,1
          call     title_win
          jmp      get_c

  key_9:  cmp      scan_key,f3          ;F3 Key pressed
          jne      key_10
          call     load_act
          call     refresh_
          call     info_win
          GOTOXY   pos_x,pos_y
          jmp      get_c

  key_10: cmp      scan_key,f2          ;F2 Key pressed
          jne      key_11
          mov      ax,offset this_dir[1]
          push     ax
          call     save_act
          call     refresh_
          jmp      get_c

  key_11: cmp      scan_key,pgup        ;Page Up
          jne      key_12
          mov      ax,cursor_y
          xor      ch,ch
          mov      cl,pos_y
          sub      ax,cx
          cmp      ax,20
          jg       sub_20
          cmp      cursor_y,20
          ja       su__20
          mov      pos_y,2
          mov      cursor_y,1
          GOTOXY   pos_x,pos_y
          jmp      pg_up

  su__20: add      cx,ax
          sub      cx,20
          mov      pos_y,cl
          GOTOXY   pos_x,pos_y
  sub_20: sub      cursor_y,20
  pg_up:  call     refresh_
          call     info_win
          jmp      get_c

  key_12: cmp      scan_key,pgdn        ;Page Down
          jne      key_13

  no_ct2: mov      ax,total_l
          sub      ax,cursor_y
          cmp      ax,20
          ja       add_20
          mov      pos_y,1
          mov      ax,total_l
          mov      cursor_y,ax
          GOTOXY   pos_x,pos_y
          jmp      pg_up

  add_20: add      cursor_y,20
  pg_dn:  call     refresh_
          call     info_win
          jmp      get_c

  key_13: cmp      scan_key,f1          ;F1 Key pressed
          jne      key_14
          call     help_win
          call     refresh_
          jmp      get_c

  key_14: cmp      scan_key,ctrl_pgup   ;Control-Page Up
          jne      key_15
          mov      pos_y,2
          mov      cursor_y,1
          GOTOXY   pos_x,pos_y
          call     refresh_
          call     info_win

  key_15: cmp      scan_key,ctrl_pgdn   ;Control-Page Down
          jne      key_16
          mov      ax,total_l
          mov      cursor_y,ax
          cmp      ax,20
          jb       at_20
          mov      al,20
  at_20:  mov      pos_y,al
          GOTOXY   pos_x,pos_y
          call     refresh_
          call     info_win

  key_16: jmp      get_c

  comm_:  mov      ax,cursor_y
          push     ax
          call     find_ptr
          call     put_buff             ;Key in a Character
          cmp      ascii_key,backspace  ;BackSpace Key pressed
          jne      comm_1

          mov      ax,cursor_x
          cmp      ax,1
          jne      con_
          jmp      get_c

  con_:   dec      ax
          cmp      line_buf,al
          ja       shf_l1
          jb       same_l
          dec      line_buf
          call     get_buff
  same_l: mov      scan_key,left
          jmp      key_3

  shf_l1: xor      cx,cx
          mov      cl,line_buf
          mov      di,offset line_buf
          add      di,ax
          sub      cx,ax
  shf_l2: mov      al,[di+1]
          mov      [di],al
          inc      di
          loop     shf_l2
          dec      line_buf
          call     get_buff
          jmp      same_l

  comm_1: cmp      ascii_key,enter_a    ;Enter Key pressed
          je       _13h
          jmp      comm_2
  _13h:   mov      pos_x,1
          mov      col_start,1
          cmp      ins_flag,1
          je       ins_li

          mov      ax,total_l
          cmp      cursor_y,ax
          je       eq_hom
          mov      cursor_x,1
          inc      cursor_y
          cmp      pos_y,21
          je       sc_up1
          inc      pos_y
  sc_up1: GOTOXY   pos_x,pos_y
          call     info_win
          call     refresh_
          jmp      get_c

  eq_hom: mov      scan_key,homekey
          jmp      key_6

  ins_li: inc      cursor_y
          mov      ax,cursor_x
          dec      ax
          mov      cursor_x,1
          cmp      line_buf,al
          ja       cut_l
          cmp      pos_y,21
          je       sc_up2
          inc      pos_y
  sc_up2: GOTOXY   pos_x,pos_y
          call     ins_line
          call     refresh_
          jmp      get_c

  cut_l:  xor      cx,cx                ;Cut This Line to be 2 Parts
          mov      cl,line_buf
          mov      line_buf,al
          sub      cl,al
          mov      sub_line,cl
          mov      bx,seg sub_line
          mov      es,bx
          mov      di,offset sub_line+1
          mov      si,offset line_buf
          add      si,ax
          inc      si
          cld
  rep     movsb
          NEW_                          ;===== Insert 1 Line =====
          mov      es,r_ptr             ;P_ptr^.next:=NEW_ptr
          mov      es:[0],ax
          mov      es,ax
          mov      ax,p_ptr             ;NEW_ptr^.next:=P_ptr
          mov      es:[0],ax
          mov      byte ptr es:[2],0
          mov      word ptr es:[30],0
          mov      p_ptr,es
          inc      total_l
          call     info_win
          call     get_buff
          mov      es,p_ptr
          mov      ax,es:[0]
          mov      p_ptr,ax
          cmp      pos_y,21
          je       sc_up3
          inc      pos_y
  sc_up3: GOTOXY   pos_x,pos_y
          xor      cx,cx
          mov      cl,sub_line
          inc      cx
          mov      bx,seg line_buf
          mov      es,bx
          mov      di,offset line_buf
          mov      si,offset sub_line
          cld
  rep     movsb
          call     get_buff
          call     refresh_
          jmp      get_c

  comm_2: cmp      ascii_key,escape_a   ;ESC Key pressed
          jne      comm_3
          jmp      get_c

  comm_3: cmp      cursor_x,256         ;Common Key
          jne      ok_
          jmp      get_c

  ok_:    mov      di,offset line_buf
          xor      ax,ax
          mov      al,line_buf
          mov      cx,cursor_x
          dec      cx
          cmp      cl,line_buf
          ja       add_bk

          inc      cx
          cmp      cl,line_buf
          jbe      no_lng
          mov      line_buf,cl
          add      di,cx
          mov      al,ascii_key
          mov      [di],al
          jmp      p_link

  no_lng: add      di,cx
          cmp      ins_flag,0
          je       no_ins

          cmp      line_buf,255
          je       key_in

          xor      ax,ax
          mov      al,line_buf
          neg      cx
          add      cx,ax
          inc      cx
          mov      si,di
          add      si,cx
  shf_r:  mov      al,[si-1]
          mov      [si],al
          dec      si
          loop     shf_r
          inc      line_buf

  no_ins: mov      al,ascii_key
          mov      [di],al
          jmp      p_link

  add_bk: add      di,ax
          sub      cl,line_buf
  put_s:  inc      di
          mov      byte ptr [di],' '
          loop     put_s
          mov      ax,cursor_x
          mov      line_buf,al
          mov      al,ascii_key
          mov      [di+1],al

  p_link: call     get_buff
          inc      cursor_x
          call     info_win
          cmp      pos_x,80
          je       scro_
          inc      pos_x
          GOTOXY   pos_x,pos_y
          jmp      one_ch

  scro_:  inc      col_start
  one_ch: call     refresh_

  key_in: jmp      get_c

main      endp

refresh_  proc     near
          mov      ax,cursor_y
          xor      bx,bx
          mov      bl,pos_y
          sub      ax,bx
          inc      ax
          push     ax
          mov      ax,col_start
          push     ax
          call     display_
refresh_  endp

title_win proc     near                 ;Display Title
          push     es
          push     ax
          push     cx
          pushf

          mov      es,monitor
          cld
          mov      si,offset win_head
          mov      di,0
          mov      al,color1
          mov      cx,80
  loop_w: movsb
          stosb
          loop     loop_w

          mov      si,offset edit_head
          mov      di,y_table+2
          mov      al,color1
          mov      cx,80
  loop_e: movsb
          stosb
          loop     loop_e
          mov      di,y_table[2]
          mov      cx,6
          add      di,75
  b__ed:  mov      byte ptr es:[di],0fh
          add      di,2
          loop     b__ed

          popf
          pop      cx
          pop      ax
          pop      es
          ret
title_win endp

info_win  proc     near
          push     ax
          push     cx
          push     di
          push     si
          push     es

          call     itoa_3
          mov      ax,offset str_y
          push     ax
          push     cursor_y
          call     itoa_5
          mov      ax,offset str_ttl
          push     ax
          push     total_l
          call     itoa_5

          cld
          mov      es,monitor
          mov      di,y_table[46]
          mov      cx,80
          mov      si,offset win_info
          mov      al,reverse2
  loop_i: movsb
          stosb
          loop     loop_i

          pop      es
          pop      si
          pop      di
          pop      cx
          pop      ax
          ret
info_win  endp

windows   proc     near                 ;********************
          push     ax                   ;* Windows Function *
          push     cx                   ;********************
          CURSOR_0

          mov      char,0
  sel_:   call     title_win            ;Refresh Screen
          call     refresh_

          mov      win_y,1
          cmp      char,f10
          je       exit_w

          cmp      win_x,1              ;File Window
          jne      srn1
          call     file_win
          jmp      sel_
  srn1:   cmp      win_x,2              ;Edit Window
          jne      srn2
          call     edit_win
          jmp      sel_
  srn2:   cmp      win_x,3              ;Utility Window
          jne      srn3
          call     utl_win
          jmp      sel_
  srn3:   call     block_win            ;Block Window
          jmp      sel_

  exit_w: GOTOXY   pos_x,pos_y
          CURSOR_1
          pop      cx
          pop      ax
          ret
windows   endp

file_win  proc     near                 ;+------+
          push     ax                   ;| File |
          push     bx                   ;+------+
          push     cx
          push     es
          push     si
          push     di

          mov      es,monitor
          mov      cx,6                 ;[File] be reversed
          mov      di,7
          mov      al,reverse1
  f_6:    mov      es:[di],al
          add      di,2
          loop     f_6

          cld
  draw_f: mov      si,offset win_file+3 ;Draw File Window
          xor      cx,cx
          mov      cl,win_file+1
          xor      bx,bx
  loopf2: mov      di,y_table[bx+2]
          add      bx,2
          add      di,4
          push     cx
          pushf
          xor      cx,cx
          mov      al,win_file+2
          mov      cl,win_file
  loopf1: movsb
          stosb
          loop     loopf1

          popf
          pop      cx
          loop     loopf2

          mov      bx,win_y             ;Mark Selection
          shl      bx,1
          mov      di,y_table[bx+2]
          add      di,7
          xor      cx,cx
          mov      cl,win_file
          sub      cl,2
          mov      al,reverse3
  rev_f:  mov      es:[di],al
          add      di,2
          loop     rev_f

  get_f:  GET_CHAR
          call     l_or_r               ;If Left or Right
          cmp      al,0
          je       n_r_l
          jmp      end_f
  n_r_l:  mov      ax,file_max
          push     ax                   ;If Up or Down
          call     u_or_d
          cmp      al,0
          je       key_f
          jmp      draw_f
  key_f:  cmp      char,f10
          jne      n_f10
          jmp      end_f
  n_f10:  cmp      char,escape
          jne      nextf1
          mov      char,f10
          jmp      end_f
  nextf1: cmp      char,enter_s
          je       chk_y
          jmp      get_f

  chk_y:  cmp      win_y,1              ;LOAD
          jne      chk_y2
          call     load_act
          call     refresh_
          call     info_win
          GOTOXY   pos_x,pos_y
          mov      char,f10
          jmp      end_f

  chk_y2: cmp      win_y,2              ;SAVE
          jne      chk_y3
          mov      ax,offset this_dir[1]
          push     ax
          call     save_act
          call     refresh_
          mov      char,f10
          jmp      end_f

  chk_y3: cmp      win_y,3              ;Write to
          jne      chk_y4
          CURSOR_1
          call     write_act
          CURSOR_0
          jmp      end_f

  chk_y4: cmp      win_y,4              ;New
          jne      chk_y5
          call     new_act
          jmp      end_f

  chk_y5: cmp      win_y,5
          jne      chk_y6
;          call     os_shell
          mov      char,f10
          jmp      end_f

  chk_y6: CURSOR_1                      ;Exit to DOS
          mov      al,0
          xor      cx,cx
          mov      dx,184fh
          mov      bh,07
          mov      ah,6
          int      10h
          mov      dx,offset good_bye
          mov      ah,09h
          int      21h
          mov      ah,4ch
          int      21h

  end_f:  pop      di
          pop      si
          pop      es
          pop      cx
          pop      bx
          pop      ax
          ret
file_win  endp

new_act   proc     near
          call     newing
          mov      total_l,1
          mov      cursor_x,1
          mov      cursor_y,1
          mov      pos_x,1
          mov      pos_y,2
          GOTOXY   pos_x,pos_y
          mov      col_start,1
          mov      block_top,1
          mov      block_end,1
          call     info_win
          mov      char,f10
          ret
new_act   endp

edit_win  proc     near                 ;+------+
          push     di                   ;| Edit |
          push     es                   ;+------+
          push     ax
          push     cx
          pushf

          mov      es,monitor
          mov      cx,6                 ;[Edit] be reversed
          mov      di,25
          mov      al,reverse1
  e_6:    mov      es:[di],al
          add      di,2
          loop     e_6

  get_e:  GET_CHAR
          call     l_or_r
          cmp      al,0
          jne      end_e
          cmp      char,f10
          je       end_e
          cmp      char,enter_s
          jne      get_e
          mov      char,f10

  end_e:  popf
          pop      cx
          pop      ax
          pop      es
          pop      di
          ret
edit_win  endp

utl_win   proc     near                 ;+---------+
          push     ax                   ;| Utility |
          push     bx                   ;+---------+
          push     cx
          push     es
          push     si
          push     di

          cld
          mov      es,monitor
          mov      cx,9                 ;[Utility] be reversed
          mov      di,43
          mov      al,reverse1
  u_9:    mov      es:[di],al
          add      di,2
          loop     u_9

  draw_u: mov      si,offset win_utl+3 ;Draw File Window
          xor      cx,cx
          mov      cl,win_utl+1
          xor      bx,bx
  loopu2: mov      di,y_table[bx+2]
          add      bx,2
          add      di,40
          push     cx
          pushf
          xor      cx,cx
          mov      al,win_utl+2
          mov      cl,win_utl
  loopu1: movsb
          stosb
          loop     loopu1

          popf
          pop      cx
          loop     loopu2

          mov      bx,win_y             ;Mark Selection
          shl      bx,1
          mov      di,y_table[bx+2]
          add      di,43
          xor      cx,cx
          mov      cl,win_utl
          sub      cl,2
          mov      al,reverse3
  rev_u:  mov      es:[di],al
          add      di,2
          loop     rev_u

  get_u:  GET_CHAR
          call     l_or_r
          cmp      al,0
          je       _y_
          jmp      end_u
  _y_:    mov      ax,utl_max
          push     ax                   ;If Up or Down
          call     u_or_d
          cmp      al,0
          je       key_u
          jmp      draw_u

  key_u:  cmp      char,f10             ;F10
          je       end_u
          jne      u_f10
          jmp      end_u
  u_f10:  cmp      char,escape          ;ESC
          jne      nextu1
          mov      char,f10
          jmp      end_u

  nextu1: cmp      char,enter_s
          je       chk_yu
          jmp      get_u

  chk_yu: cmp      win_y,1              ;HELP
          jne      chk_u2
          call     help_win
          jmp      end_u

  chk_u2: cmp      win_y,2              ;Change Drive
          jne      chk_u3
          CURSOR_1
          call     chg_drive
          mov      char,f10
          jmp      end_u

  CHK_u3: cmp      win_y,3
          jne      chk_u4
          mov      char,f10
          jmp      end_u

  chk_u4: cmp      win_y,4              ;Print
          jne      chk_u5
          mov      ax,1
          push     ax
          mov      ax,total_l
          push     ax
          call     print_act
          mov      char,f10
          jmp      end_u

  chk_u5:                               ;Lock Terminal
          mov      char,f10
          jmp      end_u

  end_u:  pop      di
          pop      si
          pop      es
          pop      cx
          pop      bx
          pop      ax
          ret
utl_win   endp

block_win proc     near                 ;+-------+
          push     ax                   ;| Block |
          push     bx                   ;+-------+
          push     cx
          push     es
          push     si
          push     di

          cld
          mov      es,monitor
          mov      cx,7                 ;[Block] be reversed
          mov      di,67
          mov      al,reverse1
  b_7:    mov      es:[di],al
          add      di,2
          loop     b_7

  draw_b: mov      si,offset win_block+3 ;Draw File Window
          xor      cx,cx
          mov      cl,win_block+1
          xor      bx,bx
  loopb2: mov      di,y_table[bx+2]
          add      bx,2
          add      di,64
          push     cx
          pushf
          xor      cx,cx
          mov      al,win_block+2
          mov      cl,win_block
  loopb1: movsb
          stosb
          loop     loopb1

          popf
          pop      cx
          loop     loopb2

          mov      bx,win_y             ;Mark Selection
          shl      bx,1
          mov      di,y_table[bx+2]
          add      di,67
          xor      cx,cx
          mov      cl,win_block
          sub      cl,2
          mov      al,reverse3
  rev_b:  mov      es:[di],al
          add      di,2
          loop     rev_b

  get_b:  GET_CHAR
          call     l_or_r
          cmp      al,0
          jne      end_b
          mov      ax,block_max
          push     ax                   ;If Up or Down
          call     u_or_d
          cmp      al,0
          je       key_b
          jmp      draw_b
  key_b:  cmp      char,f10
          je       end_b
          jmp      get_b

  end_b:  pop      di
          pop      si
          pop      es
          pop      cx
          pop      bx
          pop      ax

          ret
block_win endp

l_or_r    proc     near                 ;Right or Left Key <- ->
          mov      al,0                 ;Set a Boolean AL=0
          cmp      char,left
          jne      next1
          cmp      win_x,1
          ja       x_min
          mov      win_x,win_max+1
  x_min:  dec      win_x
          mov      al,1
  next1:  cmp      char,right
          jne      next2
          cmp      win_x,win_max
          jb       x_max
          mov      win_x,0
  x_max:  inc      win_x
          mov      al,1                 ;Right or Left is True
  next2:  ret
l_or_r    endp

u_or_d    proc     near                 ;Up or Down Key
          push     bp
          mov      bp,sp
          push     dx
          mov      dx,[bp+4]
          mov      al,0                 ;Set a Boolean AL=0
          cmp      char,up
          jne      nextv1
          cmp      win_y,1
          ja       y_min
          mov      win_y,dx
          inc      win_y
  y_min:  dec      win_y
          mov      al,1                 ;Up or Down is True
  nextv1: cmp      char,down
          jne      nextv2
          cmp      win_y,dx
          jb       y_max
          mov      win_y,0
  y_max:  inc      win_y
          mov      al,1                 ;Up or Down is True

  nextv2: pop      dx
          pop      bp
          ret      2
u_or_d    endp

itoa_5    proc     near                 ;Stack Put Addr. of Data
          push     bp                   ;Stack Put Value of Data
          mov      bp,sp
          push     ax
          push     bx
          push     cx
          push     dx
          push     si
          push     di
          push     es
          pushf

          std
          mov      ax,ds
          mov      es,ax
          mov      si,[bp+6]
          mov      dl,' '
          mov      [si],dl
          mov      [si+1],dl
          mov      [si+2],dl
          mov      [si+3],dl
          mov      [si+4],dl
          mov      ax,[bp+4]
          mov      bx,10
  loopd5: mov      si,[bp+6]
          add      si,3
          mov      di,si
          inc      di
          mov      dx,0
          div      bx
          add      dl,30h
          mov      cx,4
  rep     movsb
          mov      [si+1],dl
          cmp      ax,0
          jne      loopd5

          popf
          pop      es
          pop      di
          pop      si
          pop      dx
          pop      cx
          pop      bx
          pop      ax
          pop      bp
          ret      4
itoa_5    endp

itoa_3    proc     near
          push     ax
          push     bx
          push     cx
          push     dx
          push     si
          pushf

          mov      si,offset str_x
          mov      str_x,' '
          mov      str_x[1],' '
          mov      str_x[2],' '
          mov      ax,cursor_x
          mov      bx,10
  loopd3: mov      dx,0
          div      bx
          add      dl,30h
          mov      cl,[si+1]
          mov      [si+2],cl
          mov      cl,[si]
          mov      [si+1],cl
          mov      [si],dl
          cmp      ax,0
          jne      loopd3

          popf
          pop      si
          pop      dx
          pop      cx
          pop      bx
          pop      ax
          ret
itoa_3    endp

extra_del proc     near                 ;Add 2 Lines to be 1 Line
          mov      es,p_ptr
          mov      ax,es:[0]
          mov      q_ptr,ax
          mov      ax,p_ptr
          mov      r_ptr,ax
          cld
          xor      cx,cx
          mov      cl,line_buf
          inc      cx
          mov      ax,seg sub_line
          mov      es,ax
          mov      di,offset sub_line
          mov      si,offset line_buf
  rep     movsb                         ;Sub_line = Line_buf
          mov      cl,line_buf
          inc      cx
          neg      cx
          add      cx,cursor_x
          cmp      cx,0
          je       no_20h
  _fill:  mov      byte ptr [di],' '
          inc      di
          loop     _fill

  no_20h: mov      es,p_ptr             ;Move Next Line UP
          mov      ax,es:[0]
          mov      p_ptr,ax
          call     put_buff
          xor      cx,cx
          mov      cl,line_buf
          cmp      cx,0
          je       del_nx
          mov      ax,offset sub_line+1
          mov      bx,di
          sub      bx,ax
          mov      ax,bx
          add      bx,cx
          cmp      bx,255
          jbe      ad_sub
          neg      ax
          add      ax,255
          mov      cx,ax
  ad_sub: mov      si,offset line_buf+1
          mov      ax,seg sub_line
          mov      es,ax
          cld
  rep     movsb
          mov      bx,offset sub_line+1
          mov      cx,di
          sub      cx,bx
          mov      line_buf,cl
          mov      ax,seg line_buf
          mov      es,ax
          mov      di,offset line_buf+1
          mov      si,offset sub_line+1
          cld
  rep     movsb
          mov      ax,r_ptr
          mov      p_ptr,ax
          call     get_buff

  del_nx: mov      es,q_ptr
          push     es
          mov      ax,es:[0]
          mov      es,r_ptr
          mov      es:[0],ax
          pop      es
          xor      cx,cx
          mov      cl,es:[2]
          FREE_    q_ptr
          cmp      cx,0
          je       extr_z

  dis_2:  mov      ax,es:[30]
          mov      es,ax
          FREE_    ax
          loop     dis_2

  extr_z: dec      total_l
          mov      ax,cursor_y
          cmp      ax,block_top
          jb       bk_1e
          cmp      ax,block_end
          jb       bk_2e
          jmp      bk_ze
  bk_1e:  dec      block_top
  bk_2e:  dec      block_end
  bk_ze:  call     info_win
          call     refresh_
          ret
extra_del endp

s_c_key   proc     near
          cmp      scan_key,n_key       ;[N/n] pressed
          jne      s_c_1
          call     ins_line
          jmp      s_c_z

  s_c_1:  cmp      scan_key,y_key       ;[Y/y] pressed
          jne      s_c_2
          mov      ax,cursor_y
          cmp      ax,block_top
          jb       bk_1d
          cmp      ax,block_end
          jb       bk_2d
          jmp      bk_zd
  bk_1d:  dec      block_top
  bk_2d:  dec      block_end
  bk_zd:  call     del_line
          jmp      s_c_z

  s_c_2:  cmp      scan_key,b_key       ;[B/b] pressed
          jne      s_c_3
          mov      ax,cursor_y
          mov      block_top,ax
          call     refresh_
          jmp      s_c_z

  s_c_3:  cmp      scan_key,k_key       ;[K/k] pressed
          jne      s_c_4
          mov      ax,cursor_y
          mov      block_end,ax
          call     refresh_
          jmp      s_c_z

  s_c_4:  cmp      scan_key,h_key       ;[H/h] pressed
          jne      s_c_5
          mov      ax,block_top
          mov      block_end,ax
          call     refresh_
          jmp      s_c_z

  s_c_5:  cmp      scan_key,m_key      ;[M/m] pressed
          jne      s_c_6
          mov      cx,block_end
          cmp      cx,block_top
          jbe      no_m_
          cmp      cx,cursor_y
          jae      m_1_
          mov      pos_y,2
          GOTOXY   pos_x,pos_y
          call     ptr_move
          sub      cx,block_top
          sub      cursor_y,cx
          mov      ax,cursor_y
          mov      block_top,ax
          add      ax,cx
          mov      block_end,ax
          call     refresh_
          jmp      s_c_z

  m_1_:   mov      ax,block_top
          cmp      ax,cursor_y
          jbe      no_m_
          call     ptr_move
          mov      ax,cursor_y
          sub      cx,block_top
          mov      block_top,ax
          mov      block_end,ax
          add      block_end,cx
          call     refresh_
  no_m_:  jmp      s_c_z

  s_c_6:  cmp      scan_key,o_key      ;[O/o] pressed
          je       _6_ok
          jmp      s_c_7
  _6_ok:  mov      cx,block_end
          cmp      cx,block_top
          jbe      chk_no
          mov      ax,cursor_y
          cmp      ax,block_top
          jb       yes_c_
          cmp      ax,block_end
          jae      yes_c_
  chk_no: jmp      no_c_

  yes_c_: push     ax
          call     find_ptr
          mov      ax,p_ptr
          mov      p_lin,ax
          mov      ax,r_ptr
          mov      es,ax
          mov      bx,block_top
          push     bx
          call     find_ptr
          call     put_buff
          mov      bx,p_ptr
          NEW_
          mov      es:[0],ax
          push     es
          mov      es,ax
          mov      byte ptr es:[2],0
          mov      word ptr es:[30],0
          pop      es
          mov      p_ptr,ax
          call     get_buff
          sub      cx,block_top
          push     cx
          dec      cx
          cmp      cx,0
          je       cpy_z

  r_cpy:  push     es
          mov      es,bx
          mov      bx,es:[0]
          mov      p_ptr,bx
          pop      es
          call     put_buff
          mov      es,es:[0]
          NEW_
          mov      es:[0],ax
          push     es
          mov      es,ax
          mov      byte ptr es:[2],0
          mov      word ptr es:[30],0
          pop      es
          mov      p_ptr,ax
          call     get_buff
          loop     r_cpy

  cpy_z:  pop      cx
          mov      es,p_ptr
          mov      ax,p_lin
          mov      es:[0],ax
          mov      ax,cursor_y
          mov      block_top,ax
          mov      block_end,ax
          add      block_end,cx
          add      total_l,cx
          call     refresh_
          call     info_win
  no_c_:  jmp      s_c_z

  s_c_7:  cmp      scan_key,d_key      ;[D/d] pressed
          jne      s_c_8
          mov      cx,block_end
          cmp      cx,block_top
          jbe      no_d_
          sub      cx,block_top
          mov      pos_y,2
          GOTOXY   pos_x,pos_y
          mov      ax,block_top
          mov      block_end,ax

  d_blk:  mov      cursor_y,ax
          call     del_line
          loop     d_blk

  no_d_:  jmp      s_c_z

  s_c_8:  cmp      scan_key,p_key      ;[P/p] pressed
          jne      s_c_z
          mov      cx,block_top
          cmp      cx,block_end
          jae      s_c_z
          push     cx
          mov      ax,block_end
          sub      ax,cx
          push     ax
          call     print_act
          call     refresh_
  s_c_z:
          ret
s_c_key   endp

ptr_move  proc     near
          mov      ax,block_top
          push     ax
          call     find_ptr
          mov      es,r_ptr             ;ES
          mov      ax,p_ptr             ;P_lin
          mov      p_lin,ax
          mov      ax,block_end
          push     ax
          call     find_ptr
          mov      bx,r_ptr             ;BX
          mov      ax,p_ptr             ;Q_lin
          mov      q_lin,ax
          mov      ax,cursor_y
          push     ax
          call     find_ptr             ;R_ptr
                                        ;P_ptr
          mov      ax,q_lin
          mov      es:[0],ax
          mov      es,bx
          mov      ax,p_ptr
          mov      es:[0],ax
          mov      es,r_ptr
          mov      ax,p_lin
          mov      es:[0],ax
          ret
ptr_move  endp

show_name proc     near
          push     es
          push     si
          push     di
          mov      es,monitor
          mov      di,y_table[48]
          mov      si,offset this_dir[1]
          mov      al,0eh
          mov      cl,this_dir
          xor      ch,ch
  lll:    movsb
          stosb
          loop     lll

          mov      cl,this_dir
          neg      cx
          add      cx,80
  clr_el: mov      byte ptr es:[di],' '
          mov      byte ptr es:[di+1],0eh
          add      di,2
          loop     clr_el

          pop      di
          pop      si
          pop      es
          ret
show_name endp

here_dir  proc     near
          mov      ah,19h                 ;GET Current Drive
          int      21h
          add      al,65
          mov      this_dir[1],al
          mov      this_dir[2],':'
          mov      this_dir[3],'\'
          mov      si,offset this_dir[4] ;GET Current Directory
          mov      dl,0
          mov      ah,47h
          int      21h
          mov      al,0
          mov      cx,64
          mov      di,offset this_dir[1]
  cpr_0:  cmp      byte ptr [di],0
          je       __dir
          inc      al
          inc      di
          loop     cpr_0

  __dir:  cmp      al,3
          jne      slash_
          dec      al
          dec      di
  slash_: add      al,13
          mov      this_dir,al
          mov      byte ptr [di],'\'
          inc      di
          mov      cx,13
          mov      ax,seg this_dir
          mov      es,ax
          mov      si,offset file_name
  rep     movsb
          call     show_name
          ret
here_dir  endp

read_line proc     near                 ;Stack Put [Offset of Line]
          push     bp                   ;DL put X-axis
          mov      bp,sp                ;DH put Y-axis
          push     ax
          push     bx
          push     si
          push     di
          push     es
          xor      bx,0
          dec      dh
          sub      dl,2
          mov      bl,dh
          shl      bx,1
          mov      es,monitor
          mov      si,y_table[bx]
          mov      bl,dl
          shl      bl,1
          inc      dl
          add      si,bx
          mov      cl,0
          mov      di,[bp+4]
          mov      bl,[di]
          add      dl,bl

  re_in:  mov      ah,2
          int      10h

          xor      ch,ch
          mov      cl,bl
          cmp      cx,0
          je       no_c
  _one_c: add      si,2
          inc      di
          mov      al,[di]
          mov      es:[si],al
          loop     _one_c
   no_c:  mov      byte ptr es:[si+2],' '
          mov      byte ptr [di+1],0
          sub      di,bx
          mov      byte ptr [di],bl
          sub      si,bx
          sub      si,bx

          GET_KEY
          cmp      ascii_key,0
          je       re_in
          cmp      ascii_key,backspace
          jne      rk1
          cmp      bl,0
          je       re_in
          dec      bx
          dec      dl
          jmp      re_in

  rk1:    cmp      ascii_key,enter_a
          jne      rk2
          mov      cl,1
          jmp      out_rk

  rk2:    cmp      ascii_key,escape_a
          jne      rk3
          mov      cl,0
          jmp      out_rk

  rk3:    cmp      bl,28
          je       re_in
          inc      dl
          inc      bx
          mov      al,ascii_key
          mov      [di+bx],al
          jmp      re_in

  out_rk: pop      es
          pop      di
          pop      si
          pop      bx
          pop      ax
          pop      bp
          ret      2
read_line endp

code      ends
;--------------------------------------
stack     segment  stack
          db       2048 dup(?)
stack     ends
          end      start
