;--- CONSTANTS -----------------------------------------------; ;--- DATA ----------------------------------------------------; SEGMENT .bss winbuf: RESW 4096 SEGMENT .data winbufptr: dw winbuf ;--- CODE ----------------------------------------------------; SEGMENT .text ;;--------------------------------------------; ;; Given a row and a column, determine offset. ;; al: row (0-based) -> GARBAGE ;; ah: column (0-based) -> GARBAGE ;; cx: * -> GARBAGE ;; dx: * -> GARBAGE ;; di: * -> offset CalcScreenOffset:mov cl, ah xor ch, ch xor ah, ah xor dx, dx mul word [bytesperline] shl cx, 1 add ax, cx mov di, ax ret ;;--------------------------------------------; ;; Save a row of the screen to a buffer. ;; di: ptr to start of screen row -> INCREMENTED ;; cl: length of row -> 0 ;; ax: * -> GARBAGE ;; si: * -> GARBAGE SaveScreenRow: mov si, [winbufptr] .Loop: mov ax, [es:di] mov [ds:si], ax inc di inc di inc si inc si dec cl jnz .Loop mov [winbufptr], si ret ;;--------------------------------------------; ;; Save a portion of the screen to a buffer. ;; al: row (0-based) of upper-left corner -> ;; ah: column (0-based) of upper-left corner -> ;; bl: height of portion to save -> 0 ;; bh: width of portion to save -> ;; cx: * -> GARBAGE ;; di: * -> GARBAGE SaveScreen: push ax push bx call CalcScreenOffset .Loop: mov cl, bh push di call SaveScreenRow pop di add di, [bytesperline] dec bl jnz .Loop mov di, [winbufptr] pop bx pop ax mov [ds:di], ax inc di inc di mov [ds:di], bx inc di inc di mov [winbufptr], di ret ;;--------------------------------------------; ;; Restore a row of the screen from the buffer. ;; di: ptr to start of screen row -> INCREMENTED ;; cl: length of row -> 0 ;; ch: * -> GARBAGE ;; ax: * -> GARBAGE ;; si: * -> GARBAGE RestoreScreenRow:xor ch, ch mov si, [winbufptr] mov ax, cx shl ax, 1 sub si, ax mov [winbufptr], si .Loop: mov ax, [ds:si] mov [es:di], ax inc di inc di inc si inc si dec cl jnz .Loop ret ;;--------------------------------------------; ;; Restore a portion of the screen from buffer. ;; *: * -> GARBAGE RestoreScreen: mov di, [winbufptr] dec di dec di mov bx, [ds:di] ; bl = height, bh = width dec di dec di mov ax, [ds:di] ; al = row, ah = column mov [winbufptr], di add al, bl ; work from bot to top! dec al call CalcScreenOffset ; di = offset .Loop: mov cl, bh push di call RestoreScreenRow pop di sub di, [bytesperline] dec bl jnz .Loop ret PopUpTest: mov ax, 200ah mov bx, 0a05h call SaveScreen mov bh, 0 mov cx, 0a20h ; (10,32)- mov dx, 0e29h ; (14,41) mov ax, 0600h ; BIOS clear rectangle int 10h ; draw a border here! call GetKey call RestoreScreen ret ;--- END -----------------------------------------------------;