Paul3
Гость
|
|
« : 02-09-2004 08:28 » |
|
Уважаемые Господа! Требуется Ваша помощь. Я работаю с QB45. Разрисовываю экран в 118h режиме. Очень интересное занятие, скажу я Вам. Однако, встретился с проблемой, которая заключается в том, что ассемблерные подпрограммы, которые вызывает Basic программа, работают очень не стабильно (их несколько, и выполняют они разные функции: рисуют всякий разный фон, разноцветные квадраты, прямоугольники, линии и пр.). Нестабильность проявляется в том, что одна и та же картинка, например, в режиме 112h рисуется, а в режиме 118h – нет. Она начинает рисоваться, доходит до определенного места в программе, и зависает. Причем, иногда, очень глухо зависает. Иногда только тяжелая перезагрузка помогает. Кроме того, и в режиме 112h не все благополучно. Более того. Если в той же программе на Basic добавить или убрать один или несколько операторов, то зависание случается уже в другом месте, или подпрограмма не реагирует на передаваемые ей параметры и начинает рисовать, допустим, прямоугольник, совсем не в требуемом месте экрана, а где её хочется.
Вот фрагменты программ:
BASIC-программа ‘ ASM-подпрограмма рисования одного пикселя DECLARE SUB aPSET (X1%, Y1%, Size%, Red%, Green%, Blue%) . . . Size%= MODEINFO.BytesPerScanLine ‘ 1024 . . . call aPSET (Colon%, Row%, Size%, 128, 128, 128) . . . END
Компилируется с помощью BC.EXE, которая входит в пакет QB45 X:\Quickb.4_5\bc.exe %1,%1,%1 После создания библиотеки ASM-модулей, линкуется с помощью: X:\Quickb.4_5\link /NOI %1,%1,%1,bcom45+qb+mylib.lib
А вот одна из ASM подпрограмм: ; MASM 5.1 ; Name aPSET - рисование одного пикселя ; ; Params: ; X - Координата Х ; Y - Координата Y ; ScanLine - Размер линии сканирования в байтах; uRed - Красная компонента цвета ; uGreen - Зелёная компонента цвета ; uBlue - Синяя компонента цвета ; ; Return - нет ;
.MODEL medium,BASIC
include ASMParam.inc include Macros.inc
.DATA
BytesPerPixel dw 4 ; Количество байт на пиксель WinOffSet dw 0 ; Текущее значение смещения WinPos dw 0 ; Текущее значение положения окна А ScanWidth dw 0 ; Размер линии сканирования
; Параметры, передаваемые через стек uBlue EQU WORD PTR [bp+6] uGreen EQU WORD PTR [bp+8] uRed EQU WORD PTR [bp+10] ScanLine EQU WORD PTR [bp+12] Y EQU WORD PTR [bp+14] X EQU WORD PTR [bp+16]
.CODE
PUBLIC APSET APSET PROC FAR
push bp ; Сохранить предыдущее значение ВР mov bp, sp ; Установить ВР для этой процедуры
;sub sp, 256 ;mov ax, @data ;mov ds, ax
; Установить стартовый номер окна А sub ax,ax mov ax, SEG_VGA ; 0A000h – находится в ASMParam.inc mov es,ax
xor ax, ax xor bx, bx xor dx, dx
; Расчёт смещения = Y * BytesPerScanLine + X * BytesPerPixel mov bx, ScanLine ; Считать значение BytesPerScanLine mov ax, [bx] ; mov ScanWidth,ax mov bx, Y ; Считать значение Y mov ax, [bx] ; ax = Y mul ScanWidth ; dx:[ax] = Y * BytesPerScanLine
push dx ; Запомнить dх, показывающий ; не скорректированную позицию окна А mov bx, ax ; Запомнить ax (остаток) в bx push bx
xor ax, ax ; Обнулить ax mov bx, X ; Считать значение Х mov ax, [bx] mov cl, 2 shl ax, cl ; ax = X * BytesPerPixel
and ax, 07FFFh ; Обнулить старший разряд pop bx add ax, bx ; Сложить старое и новое значение ax ; и получить смещение
pop dx jnc SHORT SWITCHWIN ; Если при сложении ax и bx не было ; переполнения (нет переноса), ; то переход по метке SWITCHWIN ; В этом случае в DX - точное значение окна А ; В противном случае (есть единица переноса) ; номер окна = номер окна + 1 inc dx ; dx = dx + 1 SWITCHWIN: mov WinPos, dx
mov WinOffSet, ax @SetWindow WinPos ; Установить новое окно. ; Макрос находится в Macros.inc ; Номер окна хранится в dx ; Текст макроса "Установить новую позицию окна" ;@SetWindow MACRO WinPos ; xor ax,ax ; mov ax,SWITCH_WIN ; SWITCH_WIN в ASMParam.inc ; SWITCH_WIN DW 4F05H ; mov bx,0000h ; mov dx,WinPos ; int 10h ; ENDM
; Нарисовать пиксель xor bx,bx mov di,WinOffSet ; Установить смещение в окне ; Достать значения компонент цвета ; и занести их по установленному смещению mov bx, uBlue mov ax, [bx] mov es:[di],al mov bx, uGreen mov ax, [bx] mov es:[di+1],al mov bx, uRed mov ax, [bx] mov es:[di+2],al
mov sp, bp ; Восстановить SP, выбросив из ; стека все переменные pop bp ; Восстановить ВР BASIC-программы
ret 12 ; Вернуться, удалив 6 параметров из стека
APSET ENDP END APSET
;/////////////////////////////////////////////////////////////////////////
Эта подпрограмма (и другие ASM - подпрограммы) помещается в библиотеку mylib.lib c помощью следующего ВАТ-файла: CLS d:\masm51\masm /Dmodel=MEDIUM /Dlang=BASIC %1,%1,%1,%1 IF NOT ERRORLEVEL 1 d:\masm51\lib mylib.lib-%1, mylib.lst, mylib.lib IF NOT ERRORLEVEL 1 d:\masm51\lib mylib.lib+%1, mylib.lst, mylib.lib
Подскажите пожалуйста. Что не так? Где нет стыковки? Что нужно исправить, чтобы ASM подпрограммы заработали четко.
Заранее благодарю.
|