w_shaman
Гость
|
|
« : 27-03-2007 08:32 » |
|
Привет, из книжки Владимира Кулакова "программирование на аппаратном уровне"выдрал это листинг (5.5 по-моему) , и не могу его скомпилировать (в tasm 5.0) в инклюдах все нормально, ошибки вроде тоже поисправлял, пишет: "Unexpected end of file encountered" Пробовал сегменты по-разному определять, в общем не знаю что делать, мож у кого было что-нибудь подобное ? листинг привожу ниже.
IDEAL p386 LOCALS
MODEL MEDIUM ;========================================
;========================================
; Подключить файл мнемонических обозначений ; кодов управляющих клавиш и цветовых кодов include "list1_03.inc" ; Подключить файл макросов include "list1_04.inc"
; Подключить процедуры вывода данных на экран include "list1_02.inc" ; Подключить процедуры очистки выходного буфера ; контроллера клавиатуры и ожидания поступления ; данных от мыши include "list5_03.inc"
segment sseg para stack 'STACK' DB 400h DUP (?)
ends
ScreenLength equ 80 ScreenWidth equ 25
;=========================================
;========================================== DATASEG
; Область сохранения старого вектора прерывания мыши OldPS2MouseInterruptOffset DW ? OldPS2MouseInterruptSegment DW ? ; Номер принимаемого от мыши байта MouseByteNumber DB 0 : Трехбайтовая структура данных, передаваемая мышью FirstByte DB 0 SecondByte DB 0 ThirdByte DB 0 ; Текущее состояние кнопок ButtonsStatus DB 0 ; Текущие координаты курсора мыши XCoordinate DW 0 YCoordinate DW 0 ; Предыдущая позиция курсора мыши OldXCoordinate DW 0 OldYCoordinate DW 0 ; Старое значение фона символа OldCharBackground DB 0Fh ; Текстовые сообщения Txt1 DB LIGHTGREEN,0,28."TecT для мыши PS/2-типа",0 DB WHITE,12,14,"Отображение курсора " DB "мыши инверсией атрибута символа",0 DB YELLOW,24,21 DB "Для выхода нажмите левую клавишу мыши",0 Err1 DB И,22,"Ошибка обмена данными с мышью PS/2!",0
ends ;=====================================================================
CODESEG start: ASSUME CS:CODE,DS:DATA ;***************************** ;* Основной модуль программы * ;***************************** PROC PS2MouseStart ASSUME CS:CODE,DS:DATA mov DS,AX mov [CS:MainDataSeg],AX ;Установить текстовый режим и очистить экран mov АХ,3 int 10h ;Скрыть текстовый курсор - убрать за нижнюю границу экрана mov [ScreenString],25 mov [ScreenColumn],0 call SetCursorPosition ;вывести текстовые сообщения на экран MShowColorText 3,Txt1
;ЗАПРЕТИТЬ ГЕНЕРАЦИЮ ПРЕРЫВАНИЯ IRQ12 ; Прочитать внутренний регистр команд i8042 call Wait8042BufferEmpty mov AL,020h out 64h,AL in AL,60h ; Сохранить содержимое регистра команд в АН mov AH,AL ; Записать внутренний регистр команд i8042 call Wait8042BufferEmpty mov AL,060h out 64h,AL ; Запретить сигнал прерывания от мыши mov AL,AH and AL,11111101b out 60h,AL
;РАЗРЕШИТЬ ПЕРЕДАЧУ ДАННЫХ ОТ МЫШИ call Wait8042BufferEmpty mov AL,0D4h ;послать мыши байт данных out 64h,AL call Wait8042BufferEmpty mov AL,0F4h ;разрешить передачу данных out 60h,AL ;Получить код подтверждения приема команды call WaitMouseData jz @@DataInputError ;данные не поступили in AL,60h ; Получено подтверждение приема команды? cmp AL,0FAh jnz @@DataInputError ;нет подтверждения
; РАЗРЕШИТЬ ГЕНЕРАЦИЮ ПРЕРЫВАНИЯ IRQ12 ; Прочитать внутренний регистр команд 18042 call Wait8042BufferEmpty mov AL,020h out 64h,AL in AL,60h ; Записать внутренний регистр команд 18042 mov AH,AL call Wait8042BufferEmpty mov AL,060h out 64h,AL ; Разрешить сигнал прерывания от мыши mov AL,AH or AL,10b out 60h,AL ; УСТАНОВИТЬ НОВЫЙ ОБРАБОТЧИК ПРЕРЫВАНИЯ ; Обнулить позицию курсора мыши mov [XCoordinate],0 mov [YCoordinate],0 mov [OldXCoordinate],0 mov [OldYCoordinate],0 ; Отобразить курсор мыши первый раз call ShowNewMouseCursorPosition ; Установить новый обработчик прерывания call SetPS2MouseInterrupt ; Цикл, пока не нажата левая кнопка @@Next: test [ButtonsStatus], 1b jz @@Next jmp short @@End
; ЗАВЕРШЕНИЕ РАБОТЫ ПРОГРАММЫ : Восстановить прежний обработчик прерывания @@End: call RestoreOldPS2MouseInterrupt ; Переустановить текстовый режим и очистить экран mov АХ, 3 int 10h ; Выход в DOS mov AH,4Ch int 21h ; Обработка ошибок @@DataInputError: MFatalError Err1 ENDP PS2MouseStart
;================================================ ;************************************** ;* ОБРАБОТЧИК ПРЕРЫВАНИЯ ОТ МЫШИ PS/2 * ;**************************************
proc PS2MouseInterrupt far sti ;разрешить маскируемые прерывания pusha push DS mov AX,[CS:MainDataSeg] mov DS,AX call Wait8042BufferEmpty ;очистка буфера in AL,60h ;получить скан-код
;Выбирать порядковый номер принимаемого байта cmp [MouseByteNumber],0 je @@SaveFirstByte cmp [MouseByteNumber], 1 je @@SaveSecondByte cmp [MouseByteNumber], 2 je @@SaveThirdByte jmp @@Error
; Записать первый байт посылки @@SaveFirstByte: test AL,1000b ;первый байт посылки? jz @@Error ;сбой синхронизации mov [FirstByte],AL inc [MouseByteNumber] jmp @@EndMouseInterrupt
; Записать второй байт посылки @@SaveSecondByte: mov [SecondByte],AL inc [MouseByteNumber] jmp @@EndMouseInterrupt
; Записать третий байт посылки @@SaveThirdByte: mov [ThirdByte],AL mov [MouseByteNumber], 0 ; (пакет данных от мыши принят полностью)
; Записать новое значение байта состояния кнопок mov AL,[FirstByte] and AL,0111b mov [ButtonsStatus],AL ; Вычислить новую Х-координату курсора ; Занести в АХ перемещение по X mov АН,0 ;дублируем знак во все разряды АН mov AL,[FirstByte] test AL,10000b jz @@M0 mov AH,0FFh ; Занести в AL младший байт mov AL,[SecondByte] ; Вычислить новое значение координаты ; курсора по X
add AX,[XCoordinate] cmp AX, 0 jge @@M1 mov ax,0 jmp short @@М2
@@М1 :
cmp AX , ScreenLength jl @@M2 mov AX, ScreenLength-1 mov [XCoordinate],AX
;Вычисляем новую Y-координату курсора ; Занести в АХ перемещение по Y mov АН,0 ;дублируем знак во все разряды АН mov AL,[FirstByte] test AL,100000b jz @@M3 mov AH,0FFh ; Занести в AL младший байт @@M3: mov AL,[ThirdByte] ; Вычислить новое значение координаты курсора ; по Y (Y- координата мыши PS/2 направлена ; противоположно экранной) neg AX add AX,[YCoordinate] cmp AX, 0 jge @@M4 mov AX, 0
jmp short @@М5 @@M4: cmp AX,ScreenWidth jl @@M5 mov ax,ScreenWidth-1 @@M5: mov [YCoordinate],ax ; Показать курсор в новой позиции call ShowNewMouseCursorPosition jmp short @@EndMouseInterrupt ; Обнаружен сбой в порядке передачи информации от мыши @@Error: mov [MouseByteNumber] , 0 ; Нормальное завершение прерывания @@EndMouseInterrupt: cli ; разрешение прерываний с меньшими приоритетами mov AL,20h out 0A0h,AL ; команда EOI в 18059-2 out 20h,AL ;команда EOI в 18059-1 pop DS
popa iret endp PS2MouseInterrupt
;====================================================== ;******************************************* ;* УСТАНОВИТЬ НОВЫЙ ВЕКТОР ПРЕРЫВАНИЯ МЫШИ * ;******************************************* PROC SetPS2MouseInterrupt NEAR pusha push ES mov AX , 0 mov ES,AX ; Запомнить прежний вектор обработчика ; прерывания мыши mov AX,[ES:74h*4] mov [OldPS2MouseInterruptOffset] ,AX mov AX,[ES:74h*4+2] mov [OldPS2MouseInterruptSegment] ,AX ; Установка нового вектора прерывания cli ;запретить прерывания mov AX, offset PS2MouseInterrupt mov [ES:74h*4],AX mov AX,CS mov [ES:74h*4+2],AX sti ; разрешить прерывания ; Размаскировать прерывание IRQ12 in AL,0Alh and AL,11101111b
jmp short $+2 ; задержка jmp short $+2 ; задержка out 0A1h,AL pop ES popa ret ENDP SetPS2MouseInterrupt
;================================================== ;**************************************** ;*Восстановить старый вектор прерывания * ;****************************************
PROC RestoreOldPS2MouseInterrupt NEAR pusha push ES mov AX , 0 mov ES,AX ;Восстановить прежний вектор обработчика прерывания cli mov АХ , [OldPS2MouseInterruptOffset] mov [ES:74h*4],AX mov AX, [OldPS2MouseInterruptSegment] mov [ES:74h*4+2],AX
sti pop ES рора ret
ENDP RestoreddPS2MouseInterrupt
;=================================================== ;************************************************ ;* ОТОБРАЖЕНИЕ КУРСОРА МЫШИ ПУТЕМ ИНВЕРСИИ * ;* АТРИБУТА СИМВОЛА В ПОЗИЦИИ КУРСОРА * ;************************************************
PROC ShowNewMouseCursorPosition NEAR pusha push ES ; Настроить ES на текстовый буфер mov AX,0B800h mov ES,AX ; Вычислить адрес предыдущей позиции курсора мыши mov AX,[OldYCoordinate] mov DX,160 mul DX add AX,[OldXCoordinate] add AX,[OldXCoordinate] inc AX ; Занести смещение в индексный регистр mov DI,AX ; Восстановить исходный атрибут символа mov AL,[OldCharBackground] mov [ES:DI],AL ; Вычислить адрес новой позиции курсора мыши mov AX,[YCoordinate] mov DX,160 mul DX add AX,[XCoordinate] add AX,[XCoordinate] inc AX ; Занести смещение в индексный регистр mov DI,AX ; Сохранить значение атрибута символа mov AL,[ES:DI] mov [OldCharBackground],AL ; Инвертировать атрибут символа (кроме ; старшего разряда) хоr [byte ptr ES:DI],1111111b ; Запомнить координаты курсора mov AX,[XCoordinate] mov [OldXCoordinate],AX mov AX,[YCoordinate] mov [OldYCoordinate],AX
pop ES popa ENDP ShowNewMouseCursorPosition ;======================================
;start:
call PS2MouseStart call PS2MouseInterrupt call SetPS2MouseInterrupt call RestoreOldPS2MouseInterrupt call ShowNewMouseCursorPosition
mov ax,4c00h int 21h
ends end start
|