Squares
Squares
Squares is a little program I wrote, as an exercise, because I wanted to write a program that writes direct to the video memory. As you can see, it has no practical use, it only draw some squares on the screen.
squares.asm
;---------------------------------------------------------------
%TITLE "squares.asm"
;---------------------------------------------------------------
IDEAL
MODEL small
STACK 256
;---------------------------------------------------------------
DATASEG
;---------------------------------------------------------------
excode DB 0h
char DB 'X'
attr DB 07h
v DW 4
vbase DW 0B800h
rect DB 0,0,79,24
DB 6,2,73,22
DB 13,4,65,20
DB 19,6,59,18
DB 26,8,52,16
DB 32,10,46,14
DB 38,11,40,13
;---------------------------------------------------------------
UDATASEG
;---------------------------------------------------------------
vmode DB ?
rbase DW ?
vbuffer DW 2000 DUP(?)
;---------------------------------------------------------------
CODESEG
;---------------------------------------------------------------
Start:
mov ax, @data ; Initialize DS to address
mov ds, ax ; of segment
mov es, ax ; Make es=ds
;----> get videomode
mov ah, 0Fh ; DOS function: get videomode
int 10h
mov [vmode], al ; save
@@L10:
cld
xor bx, bx
mov dx, 1
mov [attr], dl
@@L20:
push dx
push bx
mov dx, offset rect
add dx, bx
mov [rbase], dx
mov ah, 00h
int 1ah
push dx
call write_vbuffer
mov si, offset vbuffer
mov es, [vbase]
xor di, di
mov cx, 2000
rep movsw
pop bx
@@L25:
mov ah, 00h
int 1ah
sub dx, bx
cmp dx, 10 ; <-- 20 = ~ 1 sec.
jb @@L25
mov ah, 0Bh
int 21h ;result in al
or al, al
jnz @@L80
pop bx
pop dx
add [attr], dl
add bx, [v]
cmp bx, 0
jz @@L30
cmp bx, 24
jne @@L20
@@L30:
neg [v]
xor dh, dh
neg dx
jmp @@L20
@@L80:
;----> wait for keypresss before exit
mov ah, 08h ; DOS function: keyb input w/o echo
int 21h
;----> set videmode back to original
mov ah, 00h ; DOS function: set videomode
mov al, [vmode] ;
int 10h ;
Exit:
mov ah, 04Ch ; DOS function: Exit program
mov al, [excode] ; Return exit code value
int 21h ; Call DOS. Terminate program
;---------------------------------------------------------------
;
; WRITE_VBUFFER
;
; expect:
;
; return:
;
;---------------------------------------------------------------
PROC write_vbuffer
; clear mem area
mov ax, ds
mov es, ax
mov di, offset vbuffer
mov ax, 0
mov cx, 2000
rep stosw
mov di, offset vbuffer
xor cx, cx
mov bx, [rbase]
mov cl, [byte bx+1] ;starty
cmp cl, 0
je @@ll10
@@ll5:
;add 80 words = one line
add di, 160
loop @@ll5
@@ll10:
; from start to first pos
mov cl, [byte bx] ;startx
shl cx, 1
add di, cx
; di is now in pos for first char
xor ch, ch
mov cl, [byte bx+2] ;endx
sub cl, [byte bx] ;startx
; num of chars on line in cl
mov al, [char]
mov ah, [attr]
rep stosw
;from last char to end of line
xor dh, dh
mov dl, 80
sub dl, [byte bx+2] ;endx
shl dl, 1
add di, dx
; num of lines to write
mov cl, [byte bx+3] ;endy
sub cl, [byte bx+1] ;starty
cmp cl, 1
je @@ll99
cmp cl, 2
je @@ll80
sub cl, 2
@@ll20:
; from start to first pos
mov dl, [byte bx] ;startx
shl dl, 1
add di, dx
stosw
;left char done now
xor dx, dx
mov dl, [byte bx+2] ;endx
sub dl, [byte bx] ;startx
sub dl, 2
shl dx, 1
add di, dx
stosw
;right char done now
mov dl, 80
sub dl, [byte bx+2] ;endx
shl dl, 1
add di, dx
loop @@ll20
;ready for last line
@@ll80:
mov cl, [byte bx] ;startx
shl cx, 1
add di, cx
xor ch, ch
mov cl, [byte bx+2] ;endx
sub cl, [byte bx] ;startx
rep stosw
@@ll99:
ret
ENDP write_vbuffer
;---------------------------------------------------------------
END Start ; End of program / entry point