Assembly Program 1 B84204021

   
PROC Sh_line This procedure does the work to redraw the changed line. The line is specified in DH register.
PROC Offbuf This procedure calculate the offset address of the buffer. So that I don't have to write the same code in every key manipulate codes. This will also reduce the size of the progeam.
PROC SaveF This procedure is to save the content of the window to a text file.
 

The following is the source code with comments:

INCLUDE \MASM61\INCLUDE\DOS.INC
INCLUDE \MASM61\INCLUDE\BIOS.INC

.MODEL SMALL
.DATA         ;datas
top DB '+--------------------------------+$'
side DB '|                                |$'
empty DB '                                                    $'
pos_x DB 0
pos_y DB 0
win_x DB 10
win_y DB 10
size_x DB 32
size_y DB 10
is_ins DB 0
msg DB 'Enter Filename: $'
newline DB 0Dh,0Ah
buff DB 32,0
fname DB 32 DUP(0)
f_hdl DW ?
buffer DB 320 DUP(20h)

;=============================================================================
.CODE         ;codes
begin: .STARTUP

 ;-----------------------------------------------------
 @SetCsrPos win_x,win_y,0  ;start to show window
 @ShowStr [top]

 mov  cx,10
sides: mov dh,win_y
 add dh,cl
 @SetCsrPos win_x,,0 ;draw the sides of window
 @ShowStr [side]
 loop sides

 mov dh,win_y
 add dh,11
 @SetCsrPos win_x,,0
 @ShowStr [top]  ;draw the bottom
 
 ;-----------------------------------------------------

setcsr: mov dl,pos_x
 add dl,win_x
 inc dl
 mov dh,pos_y
 add dh,win_y
 inc dh

 @SetCsrPos ,,0

 ;get key
 ;-----------------------------------------------------
getkey: mov ah,0
 int 16h  ;get key...

 .IF ( al == 27 ) ;ESC
 je quit  ;exit program
 .ENDIF

 .IF ( al == 0Dh && pos_y < 9 ) ;ENTER
 mov pos_x,0
 inc pos_y
 .ENDIF

 .IF al == 8    ;BACK-SPACE
 ;mov al,pos_y
 ;mov bl,32
 ;mul bl    ;ax=pos_y*32
 ;mov bx,0
 ;add bl,pos_x
 ;add bx,ax    ;bx=pos_y*32+pos_x
 call Offbuf
 .IF pos_x > 0
 add bx,OFFSET buffer
 mov si,bx
 dec pos_x
 mov di,bx
 dec di
 mov cx,31
 sub cl,pos_x
 rep movsb    ;move string
 .ELSEIF pos_y > 0
 dec pos_y
 mov pos_x,31
 sub ax,32
 .ENDIF
 mov bx,ax
 add bx,31
 mov buffer[bx],32  ;put empty space

 mov dh,pos_y   ;show line at pos_y
 call Sh_line

 .ENDIF

 .IF al == 0    ;arrar
 .IF ( ah == 72 && pos_y > 0 ) ;up
 dec pos_y

 .ELSEIF ah == 75    ;left
 .IF pos_x > 0
 dec pos_x
 .ELSEIF pos_y > 0
 dec pos_y
 mov pos_x,31
 .ENDIF

 .ELSEIF ah == 77    ;right
 .IF pos_x < 31
 inc pos_x
 .ELSEIF pos_y < 9
 inc pos_y
 mov pos_x,0
 .ENDIF

 .ELSEIF ( ah == 80 && pos_y < 9) ;down
 inc  pos_y

 .ELSEIF ( ah == 53h && pos_x > 0 ) ;0053DEL
 ;mov al,pos_y
 ;mov bl,32
 ;mul bl    ;ax=pos_y*32
 ;mov bx,0
 ;add bl,pos_x
 ;add bx,ax    ;bx=pos_y*32+pos_x
 call Offbuf
 add bx,OFFSET buffer
 mov di,bx
 inc bx
 mov si,bx
 mov cx,31
 sub cl,pos_x
 rep movsb    ;move string

 mov bx,ax
 add bx,31
 mov buffer[bx],32   ;put empty space

 mov dh,pos_y  ;show line at pos_y
 call Sh_line

 .ELSEIF ah == 52h  ;INS key
 not is_ins
 .IF is_ins==0
 @SetCsrSize 0Dh,0Fh
 .ELSE
 @SetCsrSize 0,0Fh
 .ENDIF

 .ELSEIF ah==3Ch   ;F2
 call SaveF

 .ENDIF    ;end special key

 jmp setcsr

 .ENDIF    ;end al==0

 .IF ( al >=32 && al <= 126 )
 mov dl,al   ;save char at dl
 ;mov al,pos_y
 ;mov bl,32
 ;mul bl   ;ax=pos_y*32
 ;mov bx,ax
 call Offbuf
 .IF is_ins!=0    ;INS mode on
 std
 add ax,31
 mov cx,31
 sub cl,pos_x
 add ax,OFFSET buffer
 mov si,ax
 dec si
 mov di,ax
 rep movsb    ;move string
 cld
 .ENDIF
 ;mov ax,0
 ;add al,pos_x
 ;add bx,ax   ;bx=pos_y*32+pos_x
 mov buffer[bx],dl
 .IF pos_x < 31
 inc pos_x
 .ELSEIF pos_y < 9
 mov dh,pos_y
 call Sh_line
 inc pos_y
 mov pos_x,0
 .ENDIF
 .ENDIF    ;end character key
 
 mov dh,pos_y
 call Sh_line   ;show line at pos_y
 jmp setcsr   ;refresh screen
 

quit: .EXIT

;-----------------------------------------------------------------------------
Sh_line PROC NEAR  ;line # is at dh

 mov al,32
 mul dh   ;ax=dh*32
 mov bp,ax
 add bp,OFFSET buffer ;set the addr. of line

 mov ah,13h
 mov bx,ds
 mov es,bx
 mov al,0
 mov bh,0
 mov bl,3
 add dh,win_y
 inc dh
 mov dl,win_x
 inc dl
 mov cx,32   ;show line at (win_x,dh)
 int 10h
 ret

Sh_line ENDP

Offbuf PROC NEAR
 mov al,pos_y
 mov bl,size_x
 mul bl    ;ax=pos_y*32
 mov bx,0
 add bl,pos_x
 add bx,ax    ;bx=pos_y*32+pos_x
 ret
Offbuf ENDP

SaveF PROC NEAR
 @SetCsrPos 0,23,0
 @ShowStr empty
 @SetCsrPos 0,23,0
 @ShowStr msg
 @GetStr  buff,0
 @MakeFile fname,00100000b
 mov f_hdl,ax

 mov cl,10
 mov di,OFFSET buffer
save: push cx
 @Write di,32,f_hdl
 @Write newline,2,f_hdl
 pop cx
 add di,32
 loop save

 @SetCsrPos 0,23,0
 @ShowStr empty
 @CloseFile f_hdl
 ret
SaveF ENDP
;========================================================================
.STACK
END