.model small .386 .stack 100h .data NumChoices equ 4 Maxlen equ 15 normalcolor equ 31 hilite equ 95 ; ; ; TitleMsg db 'CIS 35 Moving Bar Menu Program$' Choices db 'Add A Customer ' db 'Change Customer' db 'Delete Customer' db 'Exit ' x1 db 0 ;left x coord y1 db 0 ;top y coord row db 0 ;current row oldchoice db 1 menuchoice db 1 menuchar db ' ' menustring db maxlen dup (' ') .code mov ax, @data mov ds, ax mov es, ax start: call Init call MainLoop call Ending done: mov ah, 4ch int 21h Init proc near mov al, 0 call SetCursor ;turn cursor off mov ah, 6 mov al, 25 mov bh, 7 mov ch, 0 mov cl, 0 mov dh, 24 mov dl, 79 int 10h ;clear screen lea si, TitleMsg mov dh, 1 call Center call DisplayMenu ret Init endp Center proc near push si mov cx, 0 CNextChar: mov al, [si] cmp al, '$' jz CEndStr inc cx inc si jmp CNextChar CEndStr: pop si mov ax, 80 sub al, cl ;al := (80-CL)/2 shr al, 1 mov dl, al call SetCursorPos ;set cursor pos mov dx, si mov ah, 9 int 21h ;print it ret Center endp DisplayMenu proc near mov ax, 76 sub al, maxlen add al, 4 ;x1 := [80-(maxlen+4)]/2 shr al, 1 mov x1, al mov al, 23 sub al, numchoices shr al, 1 ;y1 := [25-(numchoices+2)]/2 mov y1, al mov row, al mov dl, x1 mov dh, y1 call SetCursorPos ;gotoxy (dl, dh) mov dl, 218 mov ah, 2 int 21h ;write upper left menu corner mov cl, maxlen mov ch, 0 mov dl, 196 DMNextTopChar: int 21h ;write top part of menu loop DMNextTopChar mov dl, 191 ;write upper right menu corner inc row mov dh, row int 21h mov cx, numchoices lea bp, choices mov dl, x1 Call SetCursorPos DMNextChoice: push cx mov dl, 179 ;write first '³' int 21h ; mov dl, 32 ; int 21h mov dl, x1 inc dl mov ah, 13h mov al, 1 mov bh, 0 mov bl, normalcolor mov cl, maxlen int 10h add bp, maxlen mov ah, 2 ; mov dl, 32 ; int 21h mov dl, 179 int 21h inc row mov dh, row mov dl, x1 call SetCursorPos pop cx loop DMNextChoice mov dl, 192 int 21h mov cx, maxlen mov dl, 196 DMNextBottomChar: int 21h loop DMNextBottomChar mov dl, 217 int 21h ret DisplayMenu endp MainLoop proc near MainRefresh: call HiliteChoice Maingetnewkey: mov al, menuchoice mov oldchoice, al mov ah, 0 ;get keypress int 16h cmp ah, 72 jz up cmp ah, 80 jz down cmp al, 13 jz enterkey cmp al, 27 jz esckey jmp MainGetNewKey up: cmp Menuchoice, 1 jz WrapUp dec Menuchoice jmp MainRefresh WrapUp: mov al, Numchoices mov menuchoice, al jmp MainRefresh Down: mov al, Numchoices cmp al, Menuchoice jz WrapDown inc Menuchoice jmp MainRefresh WrapDown: mov menuchoice, 1 jmp MainRefresh Enterkey: jmp MainDone Esckey: MainDone: ret MainLoop endp Ending proc near mov al, 1 call SetCursor ;turn cursor on lea si, choices mov al, maxlen mov ah, menuchoice sub ah, 1 mul ah add si, ax mov cx, maxlen cld lea di, menustring rep movsb mov al, menustring mov menuchar, al ret Ending endp Hilitechoice Proc near mov al, y1 add al, oldchoice mov ah, 160 mul ah mov cl, x1 mov ch, 0 add ax, cx add ax, cx add ax, 3 mov di, ax mov cx, maxlen push ds mov ax, 0b800h mov ds, ax deHiliteNextChar: mov byte ptr [di], normalcolor add di, 2 loop deHiliteNextChar pop ds mov al, y1 add al, menuchoice mov ah, 160 mul ah mov cl, x1 mov ch, 0 add ax, cx add ax, cx add ax, 3 mov di, ax mov cx, maxlen push ds mov ax, 0b800h mov ds, ax HiliteNextChar: mov byte ptr [di], hilite add di, 2 loop HiliteNextChar pop ds ret HiliteChoice endp SetCursorPos proc near ;sets cursor coordinates at (dl, dh) pusha cmp dh, 0ffh jnz SCPSameLine mov ah, 3 mov bh, 0 mov al, dl int 10h mov dl, al SCPSameLine: mov ah, 2 mov bh, 0 int 10h popa ret SetCursorPos endp SetCursor proc near cmp al, 1 jz SetCursorOn SetCursorOff: mov ah, 3 int 10h or ch, 20h mov ah, 1 int 10h jmp setcursordone SetCursorOn: mov ah, 3 int 10h and ch, 1fh mov ah, 1 int 10h SetCursorDone: ret SetCursor endp end