The main structure of this program is:
In order to save time on coding, I wrote 3 procedures to do the most often tesks in this program:
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