locals @@
.model tiny, C
.code
.startup
mov ax, 0012h ;графический режим 12h, vga 640х480х16
int 10h
mov dx, 03CEh ;индексный порт графического контроллера
mov ax, 0F01h ;регистр 01h: разрешение установки/сброса
out dx, ax
mov ax, 0a000h
mov es, ax ; es - сегмент видео
MainLoop:
call Draw,offset msk ;адрес маски
call DELAY ;задержка
mov ah,1 ;проверка на нажатие клавиши
int 16h
jz @@1
cmp al,' ' ; пробел - пауза, можно рассмотреть рисунок
jne @@1
mov ah, 0 ;извлекаем код клавиши из буфера
int 16h
xor ax,ax ; ждем нажатия клавиши
int 16h
cmp ah, 1 ; по Esc выходим
je Exit
@@1:
call Draw,offset black ;стираем
add row,5 ;шаг движения
call Proverka ;проверка на последнюю строку
mov ah,1 ;проверка на нажатие клавиши
int 16h
jz MainLoop
mov ah, 0 ;извлекаем код клавиши из буфера
int 16h
cmp ax,4b00h ; влево
jne @@2
dec [column]
jmp MainLoop
@@2: cmp ax,4d00h ; вправо
jne @@3
inc [column]
jmp MainLoop
@@3: cmp ah, 1 ;по Esc выходим
jne MainLoop
Exit:
mov ax, 0003h ;восстановим текстовый режим
int 10h
mov ax, 4c00h
int 21h
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.286
Draw proc maska: word
; вычислить номер байта в видеопамяти
mov ax, [row] ;AX = строка
mov bx, 80
mul bx ;AХ = АХ * 80 = строка * байт_в_строке
mov di, ax ;сохранить адрес начала строки в di
mov ax, [column]
mov cl, al
shr ax, 3 ;AX = номер байта в строке
add di, ax ;DI = номер байта в видеопамяти
and cl, 7 ;вычислить номер бита в байте, остаток от
; деления на 8 – номер бита в байте
mov ch, 80h
shr ch, cl ;нужный бит установлен в 1
mov dx, 03CEh ;индексный порт графического контроллера
mov si,[maska]
mov bl,[si] ; число строк
inc si
mov cl,[si] ; число столбцов
inc si
@@next_row:
push di ; сохраняем смещение начала маски в видеобуфере
push cx ; маска пикселя и число столбцов
@@next_pixel:
mov ah, [si] ;цвет
mov al, 0 ;al = регистр установки/сброса
out dx, ax ;ah = цвет
mov al, 8 ; al = битовая маска
mov ah, ch ;записать в битовую маску нули всюду, кроме
out dx, ax ;бита, соответствующего выводимому пикселю
xchg es:[di],ah ;заполнить регистры-защелки и вывести на экран пиксель
inc si ; к следующему байту маски
ror ch,1 ; маска для следующего пикселя
jnc @@2
inc di ; к следующему байту видеобуфера
@@2:
dec cl
jnz @@next_pixel
pop cx ; восстанавливаем маску
pop di
add di,80 ; к следующей строке
dec bl
jnz @@next_row
ret
Draw endp
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
time equ 30 ;число интервалов по 10мс
DELAY:
; pusha ;сохраним все регистры
mov ah,2dh ;сбросим время
xor cx,cx
xor dx,dx
int 21h
dl2:
mov ah,2ch ; читаем время, GET SYSTEM TIME
int 21h ; Return: CH = hour, CL = minute, DH = second, DL = 1/100 seconds
;считаем сотни мс
mov al,100
mul dh ;секунды умножаем на 100 - ax = количество интервалов по 10мс
xor dh,dh ;dx - число сотых
xchg ax,dx ;поменяем местами
mov cl,10
div cl ;ax = количество интервалов по 10мс из сотых
add ax,dx ;складываем с количеством из секунд
cmp ax,time ;сравним с ожидаемым интервалом
jl dl2 ;ждем, если меньше
; popa ;восстановим все регистры
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Proverka proc
cmp row,470 ;доходим почти до края экрана, обнуляем строку. Если сравнить с 479, то
;верхний следующий пунктир выведется не с 320 колонки, а больше.
jb @@1
mov row,0
@@1: cmp [column],630
jb @@2
mov [column],1
@@2: cmp [column],0
ja @@3
mov [column],629
@@3: ret
Proverka endp
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.data
column dw 320
row dw 0
Msk db 10, 7 ; размер маски в точках: строк, столбцов
db 8,8,8,8,8,8,8
db 8,1,1,14,1,1,8
db 8,1,1,14,1,1,8
db 8,1,1,14,1,1,8
db 8,1,1,14,1,1,8
db 8,1,1,14,1,1,8
db 8,14,14,14,14,14,8
db 8,1,14,14,14,1,8
db 8,1,1,14,1,1,8
db 8,8,8,8,8,8,8
black db 10, 7 ; размер маски в точках: строк, столбцов
db 0,0,0,0,0,0,0
db 0,0,0,0,0,0,0
db 0,0,0,0,0,0,0
db 0,0,0,0,0,0,0
db 0,0,0,0,0,0,0
db 0,0,0,0,0,0,0
db 0,0,0,0,0,0,0
db 0,0,0,0,0,0,0
db 0,0,0,0,0,0,0
db 0,0,0,0,0,0,0
END
ror ch,1 ; маска для следующего пикселя
jnc @@2
inc di ; к следующему байту видеобуфера
@@2:
ror ch,1 ; маска для следующего пикселя
adc di,0 ; если был перенос, то к следующему байту видеобуфера
; вывод нескольких масок (прямоугольных шаблонов) в видеорежиме 12h
locals @@
.model tiny, pascal
N_MASK = 7 ; количество выводимых шаблонов
T_MASK STRUC ; положение маски и шаг смещения
x dw ?
y dw ?
dy dw ?
T_MASK ENDS
.code
.startup
mov ax, 0012h ;графический режим 12h, vga 640х480х16
int 10h
mov dx, 03CEh ;индексный порт графического контроллера
mov ax, 0F01h ;регистр 01h: разрешение установки/сброса
out dx, ax
mov ax, 0a000h
mov es, ax ; es - сегмент видео
MainLoop:
mov ax,offset msk
call drawAll ; рисуем все маски
call DELAY ; задержка
mov ah,1 ; проверка на нажатие клавиши
int 16h
jz @@1
cmp al,' ' ; пробел - пауза, можно рассмотреть рисунок
jne @@1
mov ah, 0 ; извлекаем код клавиши из буфера
int 16h
xor ax,ax ; ждем нажатия клавиши
int 16h
cmp ah, 1 ; по Esc выходим
je Exit
@@1:
mov ax,offset black
call drawAll ; стираем маски
call drop ; сдвигаем маски вниз
call Proverka ; проверка на последнюю строку/столбец
mov ah,1 ;проверка на нажатие клавиши
int 16h
jz MainLoop
mov ah, 0 ;извлекаем код клавиши из буфера
int 16h
cmp ax,4b00h ; влево
jne @@2
mov ax,-1
call shift
jmp MainLoop
@@2: cmp ax,4d00h ; вправо
jne @@3
mov ax,1
call shift
jmp MainLoop
@@3: cmp ah, 1 ;по Esc выходим
jne MainLoop
Exit:
mov ax, 0003h ;восстановим текстовый режим
int 10h
mov ax, 4c00h
int 21h
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; рисуем все маски
; AX = адрес маски
drawAll proc
mov cx,N_MASK
mov si,offset pos
@@draw:
push ax cx si
call Draw, [si].x, [si].y, ax ; x, y, адрес маски
pop si cx ax
add si,SIZE T_MASK
loop @@draw
ret
drawAll endp
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; сдвиг масок влево-вправо
shift proc
mov cx,N_MASK
mov si,offset pos
@@next:
add [si].x,ax
add si,SIZE T_MASK ; к следующей маске
loop @@next
ret
shift endp
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; сдвигаем маски вниз
drop proc
mov cx,N_MASK
mov si,offset pos
@@next:
mov ax,[si].dy ; шаг движения
add [si].y,ax ; новая позиция по вертикали
add si,SIZE T_MASK ; к следующей маске
loop @@next
ret
drop endp
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.286
Draw proc _x: word, _y: word, maska: word
; вычислить номер байта в видеопамяти
mov ax, [_y] ;AX = строка
mov bx, 80
mul bx ;AХ = АХ * 80 = строка * байт_в_строке
mov di, ax ;сохранить адрес начала строки в di
mov ax, [_x]
mov cl, al
shr ax, 3 ;AX = номер байта в строке
add di, ax ;DI = номер байта в видеопамяти
and cl, 7 ;вычислить номер бита в байте, остаток от
; деления на 8 – номер бита в байте
mov ch, 80h
shr ch, cl ;нужный бит установлен в 1
mov dx, 03CEh ;индексный порт графического контроллера
mov si,[maska]
mov bl,[si] ; число строк
inc si
mov cl,[si] ; число столбцов
inc si
@@next_row:
push di ; сохраняем смещение начала маски в видеобуфере
push cx ; маска пикселя и число столбцов
@@next_pixel:
mov ah, [si] ;цвет
mov al, 0 ;al = регистр установки/сброса
out dx, ax ;ah = цвет
mov al, 8 ; al = битовая маска
mov ah, ch ;записать в битовую маску нули всюду, кроме
out dx, ax ;бита, соответствующего выводимому пикселю
xchg es:[di],ah ;заполнить регистры-защелки и вывести на экран пиксель
inc si ; к следующему байту маски
ror ch,1 ; маска для следующего пикселя
adc di,0 ; если был перенос, то к следующему байту видеобуфера
dec cl
jnz @@next_pixel
pop cx ; восстанавливаем маску
pop di
add di,80 ; к следующей строке
dec bl
jnz @@next_row
ret
Draw endp
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
time equ 30 ;число интервалов по 10мс
DELAY:
; pusha ;сохраним все регистры
mov ah,2dh ;сбросим время
xor cx,cx
xor dx,dx
int 21h
dl2:
mov ah,2ch ; читаем время, GET SYSTEM TIME
int 21h ; Return: CH = hour, CL = minute, DH = second, DL = 1/100 seconds
;считаем сотни мс
mov al,100
mul dh ;секунды умножаем на 100 - ax = количество интервалов по 10мс
xor dh,dh ;dx - число сотых
xchg ax,dx ;поменяем местами
mov cl,10
div cl ;ax = количество интервалов по 10мс из сотых
add ax,dx ;складываем с количеством из секунд
cmp ax,time ;сравним с ожидаемым интервалом
jl dl2 ;ждем, если меньше
; popa ;восстановим все регистры
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Proverka proc
mov cx,N_MASK
mov si,offset pos
xor ax,ax
@@next:
cmp [si].y,470 ; доходим почти до края экрана, обнуляем строку. Если сравнить с 479, то
; верхний следующий пунктир выведется не с 320 колонки, а больше.
jb @@1
mov [si].y,ax
@@1: cmp [si].x,630
jb @@2
mov [si].x,1
@@2: cmp [si],ax
ja @@3
mov [si].x,629
@@3:
add si,SIZE T_MASK ; к следующей маске
loop @@next
ret
Proverka endp
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.data
pos T_MASK < 20, 110, 5>
T_MASK <100, 5, 3>
T_MASK <155, 300, 8>
T_MASK <270, 127, 4>
T_MASK <333, 72, 2>
T_MASK <450, 215, 7>
T_MASK <517, 20, 6>
Msk db 10, 7 ; размер маски в точках: строк, столбцов
db 8,8,8,8,8,8,8
db 8,1,1,14,1,1,8
db 8,1,1,14,1,1,8
db 8,1,1,14,1,1,8
db 8,1,1,14,1,1,8
db 8,1,1,14,1,1,8
db 8,14,14,14,14,14,8
db 8,1,14,14,14,1,8
db 8,1,1,14,1,1,8
db 8,8,8,8,8,8,8
black db 10, 7 ; размер маски в точках: строк, столбцов
db 0,0,0,0,0,0,0
db 0,0,0,0,0,0,0
db 0,0,0,0,0,0,0
db 0,0,0,0,0,0,0
db 0,0,0,0,0,0,0
db 0,0,0,0,0,0,0
db 0,0,0,0,0,0,0
db 0,0,0,0,0,0,0
db 0,0,0,0,0,0,0
db 0,0,0,0,0,0,0
END
jc lbl
jnc @@1 ; обратное условие
jmp near lbl
@@1:
Если Вы уже зарегистрированы на Портале - войдите в систему, если Вы еще не регистрировались - пройдите простую процедуру регистрации.