Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 01.09.2011, 22:21   #1
AnnyOne
 
Регистрация: 01.09.2011
Сообщений: 5
Восклицание Графика в BIOS

Может знает кто, как средствами BIOS изобразить на экране окружность ? Очень надо. Срочно
AnnyOne вне форума Ответить с цитированием
Старый 02.09.2011, 04:22   #2
Mikl___
Участник клуба
 
Регистрация: 11.01.2010
Сообщений: 1,139
По умолчанию

AnnyOne
Рисование окружности
Построить окружность несложно. У окружности координаты любой точки относительно ее центра вычисляются из соотношения R²=X²+Y², где R радиус окружности. С точки зрения программирования достаточно нарисовать 1/8 часть окружности, а симметрия закончит дело. В языках программирования высокого уровня существует специальная функция CIRCLE, которая строит окружность либо, вычисляя синус, либо, двигаясь например по оси X вычисляет на каждом шаге координату Y по формуле √(R²-X²). В языке ассемблера для вычисления квадратного корня или функции синуса пришлось бы использовать обращение к сопроцессору, а такая программа с точки зрения ассемблера работает непозволительно долго. Подумаем, как нам реализовать более быстрый метод рисования окружностей используя только целочисленную арифметику, ведь на экране можно выводить точку только туда, где находится люминофор, а не между люминофорами, или смещать точку на долю микрона вправо или влево. Пусть центр окружности находится в точке (0, 0) Y=R=100 и X=0 по формуле Y² равен R²−X². По мере движения по оси X мы должны выяснить, когда нам необходимо уменьшить Y. Это нужно сделать если отклонение от Y будет больше 0,5 величины люминофора, т.е. больше должна засвечиваться соседняя точка. Вычисляем квадрат отклонения: (Y−0,5)²=Y²−Y+0,25. Выражение Y²−Y вычисляется в целых числах, а 0,25 игнорируем. Если разность R²−X² больше чем Y²−Y необходимо уменьшить Y на единицу и опять пересчитать ту величину, когда необходимо будет снова изменить Y и так в цикле. Вы выводите N точек, где N вычисляется из значения L=2*π*R. Так как Вам надо нарисовать 1/8 окружности N=L/8=3.14*R/4≈157*R/200.

Последний раз редактировалось Mikl___; 02.09.2011 в 04:25.
Mikl___ вне форума Ответить с цитированием
Старый 02.09.2011, 04:23   #3
Mikl___
Участник клуба
 
Регистрация: 11.01.2010
Сообщений: 1,139
По умолчанию

[продолжение]
Код:
.286
.model tiny
.code
ORG 100h
; константы
RADIUS EQU 99 ;рисуем окружность с радиусом 99
RADIUS2 EQU RADIUS*RADIUS ;квадрат радиуса
DIAMETR EQU RADIUS*2 ;диаметр окружности
N EQU 157*RADIUS/200;количество точек на 1/8 
COLOR EQU 10 ;цвет окружности
start: MOV AH,0Fh  ;узнать номер текущего видеорежима
    INT 10h
    MOV VIDEOR,AL ;запомним текущий видеорежим
    MOV AX,13h;установить видеорежим 320х200х256 
    INT 10h
    PUSH 0A000h;установить регистр ES на сегмент 
    POP ES ; видеопамяти
    XOR BP,BP ;будем увеличивать X и Y
    MOV Y,RADIUS-1 ;координаты X=0 и Y=R
     CALL DRAW_OCT1 ;рисуем восьмушку окружности
    MOV BP,RADIUS-1 ;координата X=2*R
    MOV Y,0 ;координата Y=0
    CALL DRAW_OCT2 ;рисуем восьмушку окружности
    NEG DELTA_X ;увеличиваем Y и уменьшаем X
    MOV Y,RADIUS  
    MOV BP,DIAMETR ;координаты Y=R и X=2*R
    CALL DRAW_OCT1 ;рисуем восьмушку окружности
    MOV BP,RADIUS ;координата X=R
    MOV Y,0 ;координата Y=0
    CALL DRAW_OCT2 ;рисуем восьмушку окружности
    NEG DELTA_Y ;уменьшаем координаты Y и X
    MOV Y,RADIUS ;координата Y=R
    MOV BP,DIAMETR ;координата X=2*R
    CALL DRAW_OCT1 ;рисуем восьмушку окружности
    MOV BP,RADIUS ;координата X=R
    MOV Y,DIAMETR ;координата Y=2*R
    CALL DRAW_OCT2 ;рисуем восьмушку окружности
    NEG DELTA_X ; уменьшаем Y и увеличиваем X
    XOR BP,BP ;координата X=0
    MOV Y,RADIUS ;координата Y=R
    CALL DRAW_OCT1 ;рисуем восьмушку окружности
    MOV BP,RADIUS ;координата X=R
    MOV Y,DIAMETR ;координата Y=2*R
    CALL DRAW_OCT2 ;рисуем восьмушку окружности
    XOR AX,AX  ;ожидание нажатия любой клавиши
    INT 16h
    MOV AX,WORD PTR VIDEOR;восстановление видеорежима
    INT 10h
    RET  ;выход из программы
PROC DELTA_CALC ;рассчитаем ошибку накопления
    MOV BX,AX ;в AX значение координаты X или Y 
    DEC AX ;вычислим (Y+0,5)² ≈ Y²+Y
    MUL AX ;или (X+0,5)² ≈ X²+X
    ADD AX,BX
    MOV DELTA,AX ;и поместим это значение в DELTA
    RET
ENDP
;процедура прорисовки 1/8 окружности с вычислением 
PROC DRAW_OCT1 ; координаты X
    MOV AX,Y
    SHL AX,6  ;должно быть DI=Y*320, но для умножения 
    MOV DI,AX  ;на 320 используем сдвиги, AX= Y*64,
    SHL AX,2 ;сохраним AX в DI и умножим Y*64 на 4
    ADD DI,AX ;DI=Y*(256+64)=Y*320.
    MOV AX,BP  
    SUB AX,RADIUS ;BP=X AX=R-X
    CALL DELTA_CALC ;расчет ошибки накопления по X
    MOV CX,N
CIRC1: MOV AX,Y
    SUB AX,RADIUS ;AX=Y-R 
    MUL AX
    NEG AX
    ADD AX,RADIUS2 ;AX=R²-Y²
    CMP DELTA,AX ;сравнить текущий X²=R²-Y² с ошибкой 
    JBE A3 ;накопления, если меньше, увеличиваем или 
    ADD BP,DELTA_X;уменьшаем только Y, иначе 
    MOV AX,BP;увеличиваем или уменьшаем еще и X и 
    SUB AX,RADIUS; вычисляем новую ошибку накопления
    CALL DELTA_CALC
A3: CMP DELTA_Y,1
    JNE A1
    ADD DI,320
    JMP SHORT A2
A1: SUB DI,320
A2: MOV BYTE PTR ES:[DI][BP],COLOR;выводим точку на 
    MOV AX,DELTA_Y; экран
    ADD Y,AX
    LOOP CIRC1  ;повторяем цикл
    RET
ENDP
;процедура прорисовки 1/8 окружности с вычислением 
PROC DRAW_OCT2 ; координаты X
    MOV AX,Y
    SHL AX,6  ;должно быть DI=Y*320, но для умножения 
    MOV DI,AX  ;на 320 используем сдвиги, AX= Y*64,
    SHL AX,2 ;сохраним AX в DI и умножим Y*64 на 4
    ADD DI,AX ;DI=Y*(256+64)=Y*320.
    MOV AX, Y
    SUB AX,RADIUS
    CALL DELTA_CALC
    MOV CX,N
CIRC2: MOV AX,BP
    SUB AX,RADIUS
    MUL AX
    NEG AX
    ADD AX,RADIUS2 ;AX=R²-(X-R)²
    CMP DELTA,AX
    JBE A5
    MOV AX,DELTA_Y
    ADD Y,AX
    MOV AX,Y
    SUB AX,RADIUS
    CALL DELTA_CALC
    CMP DELTA_Y,1
    JNE A4
    ADD DI,320
    JMP SHORT A5
A4: SUB DI,320
A5: ADD BP,DELTA_X
    MOV BYTE PTR ES:[DI][BP],COLOR
    LOOP CIRC2
    RET
ENDP
VIDEOR DB 0,0  ;значение текущего видеорежима
DELTA DW  0 ;ошибка накопления
DELTA_X DW  1 ;смещение по оси X
DELTA_Y DW  1 ;смещение по оси Y
Y  DW  0 ;координата Y
END start
Данная программа выводит на экран окружность, заданного радиуса и цвета, с центром, определенным координатами (R, R). Скорость прорисовки окружности можно увеличить, если не вычислять координату в каждой точке, а вычислять координаты только в начале рисования 1/8 окружности, а далее прибавлять или вычитать 1 к содержимому регистра BP при изменении координаты X и прибавлять или вычитать 320 (длина строки в режиме 13h (320x200x256)) к содержимому регистра DI при изменении координаты Y. Также для увеличения скорости умножение координаты Y на 320 заменено на операции сдвига и сложения. Написано на диалекте MASM/TASM, программа компилируется в COM-файл, используется только 10h прерывание (BIOS).

Последний раз редактировалось Mikl___; 02.09.2011 в 05:40.
Mikl___ вне форума Ответить с цитированием
Старый 03.09.2011, 01:02   #4
AnnyOne
 
Регистрация: 01.09.2011
Сообщений: 5
По умолчанию

О_О
солидный код ) спасибо.
забыла я уточнить, что программу-то нужно писать, например, на си с ассемблерными вставками. это ведь упростит задачу намного ?
AnnyOne вне форума Ответить с цитированием
Старый 03.09.2011, 02:36   #5
Son Of Pain
Участник клуба
 
Регистрация: 23.12.2010
Сообщений: 1,129
По умолчанию

Особо не упростит, если рисование должно быть написано на ассемблере.
Son Of Pain вне форума Ответить с цитированием
Старый 08.09.2011, 14:40   #6
AnnyOne
 
Регистрация: 01.09.2011
Сообщений: 5
По умолчанию

а черт поймет что преподавателям надо конкретно )
в любом случае спасибо, уже разобрались
AnnyOne вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
как к BIOS обращаться. Нужно чтение/запись BIOS. Dethon_ASM_Scarel Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 7 26.10.2011 11:40
bios Pavel1992 Компьютерное железо 5 08.10.2010 13:09
BIOS smileman Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 17 24.05.2009 21:29
BIOS smileman Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 16 16.07.2008 14:54
Bios vitalik007 Общие вопросы Delphi 4 20.08.2007 11:05