forked from KolibriOS/kolibrios
kolibri-acpi:update
git-svn-id: svn://kolibrios.org@4287 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
8a90112e87
commit
edbca7f724
@ -1213,7 +1213,39 @@ fs_dyndisk_next_nomedia:
|
|||||||
; ecx = partition number, esi+ebp = ASCIIZ name
|
; ecx = partition number, esi+ebp = ASCIIZ name
|
||||||
fs_dyndisk:
|
fs_dyndisk:
|
||||||
dec ecx ; convert to zero-based partition index
|
dec ecx ; convert to zero-based partition index
|
||||||
pop edx edx edx eax ; edx = pointer to DISK, eax = NULL or edx
|
pop edx edx edx ; edx = pointer to DISK, dword [esp] = NULL or edx
|
||||||
|
; If the driver does not support insert notifications and we are the only fs
|
||||||
|
; operation with this disk, ask the driver whether the media
|
||||||
|
; was inserted/removed/changed. Otherwise, assume that media status is valid.
|
||||||
|
test byte [edx+DISK.DriverFlags], DISK_NO_INSERT_NOTIFICATION
|
||||||
|
jz .media_accurate
|
||||||
|
push ecx esi
|
||||||
|
mov esi, edx
|
||||||
|
cmp dword [esp+8], 0
|
||||||
|
jz .test_no_media
|
||||||
|
cmp [esi+DISK.MediaRefCount], 2
|
||||||
|
jnz .media_accurate_pop
|
||||||
|
lea edx, [esi+DISK.MediaInfo]
|
||||||
|
and [edx+DISKMEDIAINFO.Flags], 0
|
||||||
|
mov al, DISKFUNC.querymedia
|
||||||
|
stdcall disk_call_driver, edx
|
||||||
|
test eax, eax
|
||||||
|
jz .media_accurate_pop
|
||||||
|
stdcall disk_media_dereference ; drop our reference so that disk_media_changed could close the media
|
||||||
|
stdcall disk_media_changed, esi, 0
|
||||||
|
and dword [esp+8], 0 ; no media
|
||||||
|
.test_no_media:
|
||||||
|
stdcall disk_media_changed, esi, 1 ; issue fake notification
|
||||||
|
; if querymedia() inside disk_media_changed returns error, the notification is ignored
|
||||||
|
cmp [esi+DISK.MediaInserted], 0
|
||||||
|
jz .media_accurate_pop
|
||||||
|
lock inc [esi+DISK.MediaRefCount]
|
||||||
|
mov dword [esp+8], esi
|
||||||
|
.media_accurate_pop:
|
||||||
|
mov edx, esi
|
||||||
|
pop esi ecx
|
||||||
|
.media_accurate:
|
||||||
|
pop eax
|
||||||
test eax, eax
|
test eax, eax
|
||||||
jz .nomedia
|
jz .nomedia
|
||||||
.main:
|
.main:
|
||||||
@ -1252,30 +1284,6 @@ fs_dyndisk:
|
|||||||
.nomedia:
|
.nomedia:
|
||||||
test ecx, ecx
|
test ecx, ecx
|
||||||
jnz .notfound
|
jnz .notfound
|
||||||
test byte [edx+DISK.DriverFlags], DISK_NO_INSERT_NOTIFICATION
|
|
||||||
jz .deverror
|
|
||||||
; if the driver does not support insert notifications and we are the only fs
|
|
||||||
; operation with this disk, issue the fake insert notification; if media is
|
|
||||||
; still not inserted, 'disk_media_changed' will detect this and do nothing
|
|
||||||
lea ecx, [edx+DISK.MediaLock]
|
|
||||||
call mutex_lock
|
|
||||||
cmp [edx+DISK.MediaRefCount], 1
|
|
||||||
jnz .noluck
|
|
||||||
call mutex_unlock
|
|
||||||
push edx
|
|
||||||
stdcall disk_media_changed, edx, 1
|
|
||||||
pop edx
|
|
||||||
lea ecx, [edx+DISK.MediaLock]
|
|
||||||
call mutex_lock
|
|
||||||
cmp [edx+DISK.MediaInserted], 0
|
|
||||||
jz .noluck
|
|
||||||
lock inc [edx+DISK.MediaRefCount]
|
|
||||||
call mutex_unlock
|
|
||||||
xor ecx, ecx
|
|
||||||
jmp .main
|
|
||||||
.noluck:
|
|
||||||
call mutex_unlock
|
|
||||||
.deverror:
|
|
||||||
mov dword [esp+32], ERROR_DEVICE
|
mov dword [esp+32], ERROR_DEVICE
|
||||||
mov esi, edx
|
mov esi, edx
|
||||||
call disk_dereference
|
call disk_dereference
|
||||||
|
@ -21,40 +21,48 @@ fdc_init: ;start with clean tracks.
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
save_image:
|
save_image:
|
||||||
call reserve_flp
|
cmp [ramdisk_actual_size], FLOPPY_CAPACITY
|
||||||
call restorefatchain
|
jnz .fail
|
||||||
pusha
|
pusha
|
||||||
call check_label
|
mov ecx, floppy_mutex
|
||||||
|
call mutex_lock
|
||||||
|
mov [flp_number], bl
|
||||||
|
call floppy_read_bootsector
|
||||||
cmp [FDC_Status], 0
|
cmp [FDC_Status], 0
|
||||||
jne unnecessary_save_image
|
jne .unnecessary_save_image
|
||||||
mov [FDD_Track], 0; Цилиндр
|
mov [FDD_Track], 0; Цилиндр
|
||||||
mov [FDD_Head], 0; Сторона
|
mov [FDD_Head], 0; Сторона
|
||||||
mov [FDD_Sector], 1; Сектор
|
mov [FDD_Sector], 1; Сектор
|
||||||
mov esi, RAMDISK
|
mov esi, RAMDISK
|
||||||
call SeekTrack
|
call SeekTrack
|
||||||
save_image_1:
|
.save_image_1:
|
||||||
push esi
|
|
||||||
call take_data_from_application_1
|
call take_data_from_application_1
|
||||||
pop esi
|
|
||||||
add esi, 512
|
|
||||||
call WriteSectWithRetr
|
call WriteSectWithRetr
|
||||||
; call WriteSector
|
; call WriteSector
|
||||||
cmp [FDC_Status], 0
|
cmp [FDC_Status], 0
|
||||||
jne unnecessary_save_image
|
jne .unnecessary_save_image
|
||||||
inc [FDD_Sector]
|
inc [FDD_Sector]
|
||||||
cmp [FDD_Sector], 19
|
cmp [FDD_Sector], 19
|
||||||
jne save_image_1
|
jne .save_image_1
|
||||||
mov [FDD_Sector], 1
|
mov [FDD_Sector], 1
|
||||||
inc [FDD_Head]
|
inc [FDD_Head]
|
||||||
cmp [FDD_Head], 2
|
cmp [FDD_Head], 2
|
||||||
jne save_image_1
|
jne .save_image_1
|
||||||
mov [FDD_Head], 0
|
mov [FDD_Head], 0
|
||||||
inc [FDD_Track]
|
inc [FDD_Track]
|
||||||
call SeekTrack
|
call SeekTrack
|
||||||
cmp [FDD_Track], 80
|
cmp [FDD_Track], 80
|
||||||
jne save_image_1
|
jne .save_image_1
|
||||||
unnecessary_save_image:
|
.unnecessary_save_image:
|
||||||
|
cmp [FDC_Status], 0
|
||||||
|
pushf
|
||||||
|
mov ecx, floppy_mutex
|
||||||
|
call mutex_unlock
|
||||||
|
popf
|
||||||
popa
|
popa
|
||||||
mov [flp_status], 0
|
jnz .fail
|
||||||
|
xor eax, eax
|
||||||
|
ret
|
||||||
|
.fail:
|
||||||
|
movi eax, 1
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; ;;
|
;; ;;
|
||||||
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;;
|
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
|
||||||
;; Distributed under terms of the GNU General Public License ;;
|
;; Distributed under terms of the GNU General Public License ;;
|
||||||
;; ;;
|
;; ;;
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
@ -20,8 +20,7 @@ $Revision$
|
|||||||
; add edi,ecx
|
; add edi,ecx
|
||||||
give_back_application_data_1:
|
give_back_application_data_1:
|
||||||
mov esi, FDD_BUFF;FDD_DataBuffer ;0x40000
|
mov esi, FDD_BUFF;FDD_DataBuffer ;0x40000
|
||||||
xor ecx, ecx
|
mov ecx, 128
|
||||||
mov cx, 128
|
|
||||||
cld
|
cld
|
||||||
rep movsd
|
rep movsd
|
||||||
ret
|
ret
|
||||||
@ -32,8 +31,7 @@ give_back_application_data_1:
|
|||||||
; add esi,ecx
|
; add esi,ecx
|
||||||
take_data_from_application_1:
|
take_data_from_application_1:
|
||||||
mov edi, FDD_BUFF;FDD_DataBuffer ;0x40000
|
mov edi, FDD_BUFF;FDD_DataBuffer ;0x40000
|
||||||
xor ecx, ecx
|
mov ecx, 128
|
||||||
mov cx, 128
|
|
||||||
cld
|
cld
|
||||||
rep movsd
|
rep movsd
|
||||||
ret
|
ret
|
||||||
@ -122,6 +120,7 @@ Init_FDC_DMA:
|
|||||||
;* AL - выводимый байт. *
|
;* AL - выводимый байт. *
|
||||||
;***********************************
|
;***********************************
|
||||||
FDCDataOutput:
|
FDCDataOutput:
|
||||||
|
; DEBUGF 1,'K : FDCDataOutput(%x)',al
|
||||||
; pusha
|
; pusha
|
||||||
push eax ecx edx
|
push eax ecx edx
|
||||||
mov AH, AL ;запомнить байт в AH
|
mov AH, AL ;запомнить байт в AH
|
||||||
@ -137,6 +136,7 @@ FDCDataOutput:
|
|||||||
je @@OutByteToFDC
|
je @@OutByteToFDC
|
||||||
loop @@TestRS
|
loop @@TestRS
|
||||||
; Ошибка тайм-аута
|
; Ошибка тайм-аута
|
||||||
|
; DEBUGF 1,' timeout\n'
|
||||||
mov [FDC_Status], FDC_TimeOut
|
mov [FDC_Status], FDC_TimeOut
|
||||||
jmp @@End_5
|
jmp @@End_5
|
||||||
; Вывести байт в порт данных
|
; Вывести байт в порт данных
|
||||||
@ -144,6 +144,7 @@ FDCDataOutput:
|
|||||||
inc DX
|
inc DX
|
||||||
mov AL, AH
|
mov AL, AH
|
||||||
out DX, AL
|
out DX, AL
|
||||||
|
; DEBUGF 1,' ok\n'
|
||||||
@@End_5:
|
@@End_5:
|
||||||
; popa
|
; popa
|
||||||
pop edx ecx eax
|
pop edx ecx eax
|
||||||
@ -170,12 +171,14 @@ FDCDataInput:
|
|||||||
je @@GetByteFromFDC
|
je @@GetByteFromFDC
|
||||||
loop @@TestRS_1
|
loop @@TestRS_1
|
||||||
; Ошибка тайм-аута
|
; Ошибка тайм-аута
|
||||||
|
; DEBUGF 1,'K : FDCDataInput: timeout\n'
|
||||||
mov [FDC_Status], FDC_TimeOut
|
mov [FDC_Status], FDC_TimeOut
|
||||||
jmp @@End_6
|
jmp @@End_6
|
||||||
; Ввести байт из порта данных
|
; Ввести байт из порта данных
|
||||||
@@GetByteFromFDC:
|
@@GetByteFromFDC:
|
||||||
inc DX
|
inc DX
|
||||||
in AL, DX
|
in AL, DX
|
||||||
|
; DEBUGF 1,'K : FDCDataInput: %x\n',al
|
||||||
@@End_6:
|
@@End_6:
|
||||||
pop DX
|
pop DX
|
||||||
pop ECX
|
pop ECX
|
||||||
@ -185,6 +188,7 @@ FDCDataInput:
|
|||||||
;* ОБРАБОТЧИК ПРЕРЫВАНИЯ ОТ КОНТРОЛЛЕРА НГМД *
|
;* ОБРАБОТЧИК ПРЕРЫВАНИЯ ОТ КОНТРОЛЛЕРА НГМД *
|
||||||
;*********************************************
|
;*********************************************
|
||||||
FDCInterrupt:
|
FDCInterrupt:
|
||||||
|
; dbgstr 'FDCInterrupt'
|
||||||
; Установить флаг прерывания
|
; Установить флаг прерывания
|
||||||
mov [FDD_IntFlag], 1
|
mov [FDD_IntFlag], 1
|
||||||
mov al, 1
|
mov al, 1
|
||||||
@ -207,12 +211,12 @@ WaitFDCInterrupt:
|
|||||||
jnz @@End_7 ;прерывание произошло
|
jnz @@End_7 ;прерывание произошло
|
||||||
mov eax, [timer_ticks]
|
mov eax, [timer_ticks]
|
||||||
sub eax, [TickCounter]
|
sub eax, [TickCounter]
|
||||||
cmp eax, 50 ;25 ;5 ;ожидать 5 тиков
|
cmp eax, 200;50 ;25 ;5 ;ожидать 5 тиков
|
||||||
jb @@TestRS_2
|
jb @@TestRS_2
|
||||||
; jl @@TestRS_2
|
; jl @@TestRS_2
|
||||||
; Ошибка тайм-аута
|
; Ошибка тайм-аута
|
||||||
|
; dbgstr 'WaitFDCInterrupt: timeout'
|
||||||
mov [FDC_Status], FDC_TimeOut
|
mov [FDC_Status], FDC_TimeOut
|
||||||
; mov [flp_status],0
|
|
||||||
@@End_7:
|
@@End_7:
|
||||||
popa
|
popa
|
||||||
ret
|
ret
|
||||||
@ -221,6 +225,7 @@ WaitFDCInterrupt:
|
|||||||
;* ВКЛЮЧИТЬ МОТОР ДИСКОВОДА "A:" *
|
;* ВКЛЮЧИТЬ МОТОР ДИСКОВОДА "A:" *
|
||||||
;*********************************
|
;*********************************
|
||||||
FDDMotorON:
|
FDDMotorON:
|
||||||
|
; dbgstr 'FDDMotorON'
|
||||||
pusha
|
pusha
|
||||||
; cmp [fdd_motor_status],1
|
; cmp [fdd_motor_status],1
|
||||||
; je fdd_motor_on
|
; je fdd_motor_on
|
||||||
@ -252,6 +257,20 @@ FDDMotorON_1:
|
|||||||
sub eax, [TickCounter]
|
sub eax, [TickCounter]
|
||||||
cmp eax, 50 ;10
|
cmp eax, 50 ;10
|
||||||
jb @@dT
|
jb @@dT
|
||||||
|
; Read results of RESET command
|
||||||
|
push 4
|
||||||
|
; DEBUGF 1,'K : floppy reset results:'
|
||||||
|
@@:
|
||||||
|
mov al, 8
|
||||||
|
call FDCDataOutput
|
||||||
|
call FDCDataInput
|
||||||
|
; DEBUGF 1,' %x',al
|
||||||
|
call FDCDataInput
|
||||||
|
; DEBUGF 1,' %x',al
|
||||||
|
dec dword [esp]
|
||||||
|
jnz @b
|
||||||
|
; DEBUGF 1,'\n'
|
||||||
|
pop eax
|
||||||
cmp [flp_number], 1
|
cmp [flp_number], 1
|
||||||
jne fdd_motor_on_B
|
jne fdd_motor_on_B
|
||||||
mov [fdd_motor_status], 1
|
mov [fdd_motor_status], 1
|
||||||
@ -275,8 +294,6 @@ save_timer_fdd_motor:
|
|||||||
;* ПРОВЕРКА ЗАДЕРЖКИ ВЫКЛЮЧЕНИЯ МОТОРА *
|
;* ПРОВЕРКА ЗАДЕРЖКИ ВЫКЛЮЧЕНИЯ МОТОРА *
|
||||||
;*****************************************
|
;*****************************************
|
||||||
proc check_fdd_motor_status_has_work?
|
proc check_fdd_motor_status_has_work?
|
||||||
cmp [flp_status], 0
|
|
||||||
jnz .yes
|
|
||||||
cmp [fdd_motor_status], 0
|
cmp [fdd_motor_status], 0
|
||||||
jz .no
|
jz .no
|
||||||
mov eax, [timer_ticks]
|
mov eax, [timer_ticks]
|
||||||
@ -303,7 +320,6 @@ check_fdd_motor_status:
|
|||||||
call FDDMotorOFF
|
call FDDMotorOFF
|
||||||
mov [fdd_motor_status], 0
|
mov [fdd_motor_status], 0
|
||||||
end_check_fdd_motor_status_1:
|
end_check_fdd_motor_status_1:
|
||||||
mov [flp_status], 0
|
|
||||||
end_check_fdd_motor_status:
|
end_check_fdd_motor_status:
|
||||||
ret
|
ret
|
||||||
|
|
||||||
@ -311,6 +327,7 @@ end_check_fdd_motor_status:
|
|||||||
;* ВЫКЛЮЧИТЬ МОТОР ДИСКОВОДА *
|
;* ВЫКЛЮЧИТЬ МОТОР ДИСКОВОДА *
|
||||||
;**********************************
|
;**********************************
|
||||||
FDDMotorOFF:
|
FDDMotorOFF:
|
||||||
|
; dbgstr 'FDDMotorOFF'
|
||||||
push AX
|
push AX
|
||||||
push DX
|
push DX
|
||||||
cmp [flp_number], 1
|
cmp [flp_number], 1
|
||||||
@ -323,8 +340,8 @@ FDDMotorOFF_2:
|
|||||||
pop DX
|
pop DX
|
||||||
pop AX
|
pop AX
|
||||||
; сброс флагов кеширования в связи с устареванием информации
|
; сброс флагов кеширования в связи с устареванием информации
|
||||||
mov [root_read], 0
|
or [floppy_media_flags+0], FLOPPY_MEDIA_NEED_RESCAN
|
||||||
mov [flp_fat], 0
|
or [floppy_media_flags+1], FLOPPY_MEDIA_NEED_RESCAN
|
||||||
ret
|
ret
|
||||||
|
|
||||||
FDDMotorOFF_A:
|
FDDMotorOFF_A:
|
||||||
@ -343,8 +360,11 @@ FDDMotorOFF_B:
|
|||||||
;* РЕКАЛИБРОВКА ДИСКОВОДА "A:" *
|
;* РЕКАЛИБРОВКА ДИСКОВОДА "A:" *
|
||||||
;*******************************
|
;*******************************
|
||||||
RecalibrateFDD:
|
RecalibrateFDD:
|
||||||
|
; dbgstr 'RecalibrateFDD'
|
||||||
pusha
|
pusha
|
||||||
call save_timer_fdd_motor
|
call save_timer_fdd_motor
|
||||||
|
; Сбросить флаг прерывания
|
||||||
|
mov [FDD_IntFlag], 0
|
||||||
; Подать команду "Рекалибровка"
|
; Подать команду "Рекалибровка"
|
||||||
mov AL, 07h
|
mov AL, 07h
|
||||||
call FDCDataOutput
|
call FDCDataOutput
|
||||||
@ -352,10 +372,18 @@ RecalibrateFDD:
|
|||||||
call FDCDataOutput
|
call FDCDataOutput
|
||||||
; Ожидать завершения операции
|
; Ожидать завершения операции
|
||||||
call WaitFDCInterrupt
|
call WaitFDCInterrupt
|
||||||
; cmp [FDC_Status],0
|
cmp [FDC_Status], 0
|
||||||
; je no_fdc_status_error
|
jne .fail
|
||||||
; mov [flp_status],0
|
; Read results of RECALIBRATE command
|
||||||
;no_fdc_status_error:
|
; DEBUGF 1,'K : floppy recalibrate results:'
|
||||||
|
mov al, 8
|
||||||
|
call FDCDataOutput
|
||||||
|
call FDCDataInput
|
||||||
|
; DEBUGF 1,' %x',al
|
||||||
|
call FDCDataInput
|
||||||
|
; DEBUGF 1,' %x',al
|
||||||
|
; DEBUGF 1,'\n'
|
||||||
|
.fail:
|
||||||
call save_timer_fdd_motor
|
call save_timer_fdd_motor
|
||||||
popa
|
popa
|
||||||
ret
|
ret
|
||||||
@ -368,6 +396,7 @@ RecalibrateFDD:
|
|||||||
;* Результат операции заносится в FDC_Status. *
|
;* Результат операции заносится в FDC_Status. *
|
||||||
;*****************************************************
|
;*****************************************************
|
||||||
SeekTrack:
|
SeekTrack:
|
||||||
|
; dbgstr 'SeekTrack'
|
||||||
pusha
|
pusha
|
||||||
call save_timer_fdd_motor
|
call save_timer_fdd_motor
|
||||||
; Сбросить флаг прерывания
|
; Сбросить флаг прерывания
|
||||||
@ -402,17 +431,20 @@ SeekTrack:
|
|||||||
cmp AL, [FDD_Track]
|
cmp AL, [FDD_Track]
|
||||||
jne @@Err
|
jne @@Err
|
||||||
; Номер головки совпадает с заданным?
|
; Номер головки совпадает с заданным?
|
||||||
mov AL, [FDC_ST0]
|
; The H bit (Head Address) in ST0 will always return a "0" (c) 82077AA datasheet,
|
||||||
and AL, 100b
|
; description of SEEK command. So we can not verify the proper head.
|
||||||
shr AL, 2
|
; mov AL, [FDC_ST0]
|
||||||
cmp AL, [FDD_Head]
|
; and AL, 100b
|
||||||
jne @@Err
|
; shr AL, 2
|
||||||
|
; cmp AL, [FDD_Head]
|
||||||
|
; jne @@Err
|
||||||
; Операция завершена успешно
|
; Операция завершена успешно
|
||||||
|
; dbgstr 'SeekTrack: FDC_Normal'
|
||||||
mov [FDC_Status], FDC_Normal
|
mov [FDC_Status], FDC_Normal
|
||||||
jmp @@Exit
|
jmp @@Exit
|
||||||
@@Err: ; Трек не найден
|
@@Err: ; Трек не найден
|
||||||
|
; dbgstr 'SeekTrack: FDC_TrackNotFound'
|
||||||
mov [FDC_Status], FDC_TrackNotFound
|
mov [FDC_Status], FDC_TrackNotFound
|
||||||
; mov [flp_status],0
|
|
||||||
@@Exit:
|
@@Exit:
|
||||||
call save_timer_fdd_motor
|
call save_timer_fdd_motor
|
||||||
popa
|
popa
|
||||||
@ -429,6 +461,7 @@ SeekTrack:
|
|||||||
;* содержимое сектора будет занесено в FDD_DataBuffer. *
|
;* содержимое сектора будет занесено в FDD_DataBuffer. *
|
||||||
;*******************************************************
|
;*******************************************************
|
||||||
ReadSector:
|
ReadSector:
|
||||||
|
; dbgstr 'ReadSector'
|
||||||
pushad
|
pushad
|
||||||
call save_timer_fdd_motor
|
call save_timer_fdd_motor
|
||||||
; Сбросить флаг прерывания
|
; Сбросить флаг прерывания
|
||||||
@ -468,11 +501,12 @@ ReadSector:
|
|||||||
call GetStatusInfo
|
call GetStatusInfo
|
||||||
test [FDC_ST0], 11011000b
|
test [FDC_ST0], 11011000b
|
||||||
jnz @@Err_1
|
jnz @@Err_1
|
||||||
|
; dbgstr 'ReadSector: FDC_Normal'
|
||||||
mov [FDC_Status], FDC_Normal
|
mov [FDC_Status], FDC_Normal
|
||||||
jmp @@Exit_1
|
jmp @@Exit_1
|
||||||
@@Err_1:
|
@@Err_1:
|
||||||
|
; dbgstr 'ReadSector: FDC_SectorNotFound'
|
||||||
mov [FDC_Status], FDC_SectorNotFound
|
mov [FDC_Status], FDC_SectorNotFound
|
||||||
; mov [flp_status],0
|
|
||||||
@@Exit_1:
|
@@Exit_1:
|
||||||
call save_timer_fdd_motor
|
call save_timer_fdd_motor
|
||||||
popad
|
popad
|
||||||
@ -511,12 +545,10 @@ ReadSectWithRetr:
|
|||||||
inc [RecalRepCounter]
|
inc [RecalRepCounter]
|
||||||
cmp [RecalRepCounter], 3
|
cmp [RecalRepCounter], 3
|
||||||
jb @@TryAgain
|
jb @@TryAgain
|
||||||
; mov [flp_status],0
|
|
||||||
@@Exit_2:
|
@@Exit_2:
|
||||||
popa
|
popa
|
||||||
ret
|
ret
|
||||||
@@Err_3:
|
@@Err_3:
|
||||||
mov [flp_status], 0
|
|
||||||
popa
|
popa
|
||||||
ret
|
ret
|
||||||
|
|
||||||
@ -531,6 +563,7 @@ ReadSectWithRetr:
|
|||||||
;* содержимое FDD_DataBuffer будет занесено в сектор. *
|
;* содержимое FDD_DataBuffer будет занесено в сектор. *
|
||||||
;*******************************************************
|
;*******************************************************
|
||||||
WriteSector:
|
WriteSector:
|
||||||
|
; dbgstr 'WriteSector'
|
||||||
pushad
|
pushad
|
||||||
call save_timer_fdd_motor
|
call save_timer_fdd_motor
|
||||||
; Сбросить флаг прерывания
|
; Сбросить флаг прерывания
|
||||||
@ -616,7 +649,6 @@ WriteSectWithRetr:
|
|||||||
popa
|
popa
|
||||||
ret
|
ret
|
||||||
@@Err_4:
|
@@Err_4:
|
||||||
mov [flp_status], 0
|
|
||||||
popa
|
popa
|
||||||
ret
|
ret
|
||||||
|
|
||||||
@ -642,3 +674,276 @@ GetStatusInfo:
|
|||||||
pop AX
|
pop AX
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
; Interface for disk subsystem.
|
||||||
|
; Assume fixed capacity for 1.44M.
|
||||||
|
FLOPPY_CAPACITY = 2880 ; in sectors
|
||||||
|
|
||||||
|
iglobal
|
||||||
|
align 4
|
||||||
|
floppy_functions:
|
||||||
|
dd .size
|
||||||
|
dd 0 ; no close() function
|
||||||
|
dd 0 ; no closemedia() function
|
||||||
|
dd floppy_querymedia
|
||||||
|
dd floppy_read
|
||||||
|
dd floppy_write
|
||||||
|
dd 0 ; no flush() function
|
||||||
|
dd 0 ; no adjust_cache_size() function
|
||||||
|
.size = $ - floppy_functions
|
||||||
|
endg
|
||||||
|
|
||||||
|
uglobal
|
||||||
|
floppy_media_flags rb 2
|
||||||
|
n_sector dd 0 ; temporary save for sector value
|
||||||
|
flp_number db 0 ; 1- Floppy A, 2-Floppy B
|
||||||
|
old_track db 0 ; old value track
|
||||||
|
flp_label rb 15*2 ; Label and ID of inserted floppy disk
|
||||||
|
align 4
|
||||||
|
; Hardware does not allow to work with two floppies in parallel,
|
||||||
|
; so there is one mutex guarding access to any floppy.
|
||||||
|
floppy_mutex MUTEX
|
||||||
|
endg
|
||||||
|
; Meaning of bits in floppy_media_flags
|
||||||
|
FLOPPY_MEDIA_PRESENT = 1 ; media was present when last asked
|
||||||
|
FLOPPY_MEDIA_NEED_RESCAN = 2 ; media was possibly changed, need to rescan
|
||||||
|
FLOPPY_MEDIA_LABEL_CHANGED = 4 ; temporary state
|
||||||
|
|
||||||
|
iglobal
|
||||||
|
floppy1_name db 'fd',0
|
||||||
|
floppy2_name db 'fd2',0
|
||||||
|
endg
|
||||||
|
|
||||||
|
; This function is called in boot process.
|
||||||
|
; It creates filesystems /fd and/or /fd2, if the system has one/two floppy drives.
|
||||||
|
proc floppy_init
|
||||||
|
mov ecx, floppy_mutex
|
||||||
|
call mutex_init
|
||||||
|
; First floppy is present if [DRIVE_DATA] and 0xF0 is nonzero.
|
||||||
|
test byte [DRIVE_DATA], 0xF0
|
||||||
|
jz .no1
|
||||||
|
stdcall disk_add, floppy_functions, floppy1_name, 1, DISK_NO_INSERT_NOTIFICATION
|
||||||
|
.no1:
|
||||||
|
; Second floppy is present if [DRIVE_DATA] and 0x0F is nonzero.
|
||||||
|
test byte [DRIVE_DATA], 0x0F
|
||||||
|
jz .no2
|
||||||
|
stdcall disk_add, floppy_functions, floppy2_name, 2, DISK_NO_INSERT_NOTIFICATION
|
||||||
|
.no2:
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
; Returns information about disk media.
|
||||||
|
; Floppy drives do not support insert notifications,
|
||||||
|
; DISK_NO_INSERT_NOTIFICATION is set,
|
||||||
|
; the disk subsystem calls this function before each filesystem operation.
|
||||||
|
; If the media has changed, return error for the first call as signal
|
||||||
|
; to finalize work with old media and the true geometry for the second call.
|
||||||
|
; Assume that media is (possibly) changed anytime when motor is off.
|
||||||
|
proc floppy_querymedia
|
||||||
|
virtual at esp+4
|
||||||
|
.userdata dd ?
|
||||||
|
.info dd ?
|
||||||
|
end virtual
|
||||||
|
; 1. Acquire the global lock.
|
||||||
|
mov ecx, floppy_mutex
|
||||||
|
call mutex_lock
|
||||||
|
mov edx, [.userdata] ; 1 for /fd, 2 for /fd2
|
||||||
|
; 2. If the media was reported and has been changed, forget it and report an error.
|
||||||
|
mov al, [floppy_media_flags+edx-1]
|
||||||
|
and al, FLOPPY_MEDIA_PRESENT + FLOPPY_MEDIA_NEED_RESCAN
|
||||||
|
cmp al, FLOPPY_MEDIA_PRESENT + FLOPPY_MEDIA_NEED_RESCAN
|
||||||
|
jnz .not_reported
|
||||||
|
.no_media:
|
||||||
|
mov [floppy_media_flags+edx-1], 0
|
||||||
|
.return_no_media:
|
||||||
|
mov ecx, floppy_mutex
|
||||||
|
call mutex_unlock
|
||||||
|
mov eax, DISK_STATUS_NO_MEDIA
|
||||||
|
retn 8
|
||||||
|
.not_reported:
|
||||||
|
; 3. If we are in the temporary state LABEL_CHANGED, this is the second call
|
||||||
|
; after intermediate DISK_STATUS_NO_MEDIA due to media change;
|
||||||
|
; clear the flag and return the current geometry without rereading the bootsector.
|
||||||
|
cmp [floppy_media_flags+edx-1], FLOPPY_MEDIA_LABEL_CHANGED
|
||||||
|
jz .report_geometry
|
||||||
|
; 4. Try to read the bootsector.
|
||||||
|
mov [flp_number], dl
|
||||||
|
mov [FDC_Status], 0
|
||||||
|
call floppy_read_bootsector
|
||||||
|
; 5. If reading bootsector failed, assume that media is not present.
|
||||||
|
mov edx, [.userdata]
|
||||||
|
cmp [FDC_Status], 0
|
||||||
|
jnz .no_media
|
||||||
|
; 6. Check whether the previous status is "present". If not, go to 10.
|
||||||
|
push esi edi
|
||||||
|
imul edi, edx, 15
|
||||||
|
add edi, flp_label-15
|
||||||
|
mov esi, FDD_BUFF+39
|
||||||
|
mov ecx, 15
|
||||||
|
test [floppy_media_flags+edx-1], FLOPPY_MEDIA_PRESENT
|
||||||
|
jz .set_label
|
||||||
|
; 7. Compare the old label with the current one.
|
||||||
|
rep cmpsb
|
||||||
|
; 8. If the label has not changed, go to 11.
|
||||||
|
jz .ok
|
||||||
|
; 9. If the label has changed, store it, enter temporary state LABEL_CHANGED
|
||||||
|
; and report DISK_STATUS_NO_MEDIA.
|
||||||
|
; dbgstr 'floppy label changed'
|
||||||
|
add esi, ecx
|
||||||
|
add edi, ecx
|
||||||
|
mov ecx, 15
|
||||||
|
sub esi, ecx
|
||||||
|
sub edi, ecx
|
||||||
|
rep movsb
|
||||||
|
mov [floppy_media_flags+edx-1], FLOPPY_MEDIA_LABEL_CHANGED
|
||||||
|
pop edi esi
|
||||||
|
jmp .return_no_media
|
||||||
|
.set_label:
|
||||||
|
; 10. The previous state was "not present". Copy the label.
|
||||||
|
rep movsb
|
||||||
|
.ok:
|
||||||
|
pop edi esi
|
||||||
|
.report_geometry:
|
||||||
|
; 11. Fill DISKMEDIAINFO structure.
|
||||||
|
mov ecx, [.info]
|
||||||
|
and [ecx+DISKMEDIAINFO.Flags], 0
|
||||||
|
mov [ecx+DISKMEDIAINFO.SectorSize], 512
|
||||||
|
mov dword [ecx+DISKMEDIAINFO.Capacity], FLOPPY_CAPACITY
|
||||||
|
and dword [ecx+DISKMEDIAINFO.Capacity+4], 0
|
||||||
|
; 12. Update state: media is present, data are actual.
|
||||||
|
mov [floppy_media_flags+edx-1], FLOPPY_MEDIA_PRESENT
|
||||||
|
; 13. Release the global lock and return successful status.
|
||||||
|
mov ecx, floppy_mutex
|
||||||
|
call mutex_unlock
|
||||||
|
xor eax, eax
|
||||||
|
retn 8
|
||||||
|
endp
|
||||||
|
|
||||||
|
proc floppy_read_bootsector
|
||||||
|
pushad
|
||||||
|
mov [FDD_Track], 0; Цилиндр
|
||||||
|
mov [FDD_Head], 0; Сторона
|
||||||
|
mov [FDD_Sector], 1; Сектор
|
||||||
|
call FDDMotorON
|
||||||
|
call RecalibrateFDD
|
||||||
|
cmp [FDC_Status], 0
|
||||||
|
jne .nothing
|
||||||
|
call SeekTrack
|
||||||
|
cmp [FDC_Status], 0
|
||||||
|
jne .nothing
|
||||||
|
call ReadSectWithRetr
|
||||||
|
.nothing:
|
||||||
|
popad
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
read_chs_sector:
|
||||||
|
call calculate_chs
|
||||||
|
call ReadSectWithRetr
|
||||||
|
ret
|
||||||
|
|
||||||
|
save_chs_sector:
|
||||||
|
call calculate_chs
|
||||||
|
call WriteSectWithRetr
|
||||||
|
ret
|
||||||
|
|
||||||
|
calculate_chs:
|
||||||
|
mov bl, [FDD_Track]
|
||||||
|
mov [old_track], bl
|
||||||
|
mov ebx, 18
|
||||||
|
xor edx, edx
|
||||||
|
div ebx
|
||||||
|
inc edx
|
||||||
|
mov [FDD_Sector], dl
|
||||||
|
mov edx, eax
|
||||||
|
shr eax, 1
|
||||||
|
and edx, 1
|
||||||
|
mov [FDD_Track], al
|
||||||
|
mov [FDD_Head], dl
|
||||||
|
mov dl, [old_track]
|
||||||
|
cmp dl, [FDD_Track]
|
||||||
|
je no_seek_track_1
|
||||||
|
call SeekTrack
|
||||||
|
no_seek_track_1:
|
||||||
|
ret
|
||||||
|
|
||||||
|
; Writes one or more sectors to the device.
|
||||||
|
proc floppy_write
|
||||||
|
mov dl, 1
|
||||||
|
jmp floppy_read_write
|
||||||
|
endp
|
||||||
|
|
||||||
|
; Reads one or more sectors from the device.
|
||||||
|
proc floppy_read
|
||||||
|
mov dl, 0
|
||||||
|
endp
|
||||||
|
|
||||||
|
; Common part of floppy_read and floppy_write.
|
||||||
|
proc floppy_read_write userdata:dword, buffer:dword, start_sector:qword, numsectors_ptr:dword
|
||||||
|
virtual at ebp-8
|
||||||
|
.sectors_todo dd ?
|
||||||
|
.operation db ?
|
||||||
|
end virtual
|
||||||
|
push edx ; save operation code to [.operation]
|
||||||
|
; 1. Get number of sectors to read/write
|
||||||
|
; and zero number of sectors that were actually read/written.
|
||||||
|
mov eax, [numsectors_ptr]
|
||||||
|
push dword [eax] ; initialize [.sectors_todo]
|
||||||
|
and dword [eax], 0
|
||||||
|
push ebx esi edi ; save used registers to be stdcall
|
||||||
|
; 2. Acquire the global lock.
|
||||||
|
mov ecx, floppy_mutex
|
||||||
|
call mutex_lock
|
||||||
|
; 3. Set floppy number for this operation.
|
||||||
|
mov edx, [userdata]
|
||||||
|
mov [flp_number], dl
|
||||||
|
; 4. Read/write sector-by-sector.
|
||||||
|
.operation_loop:
|
||||||
|
; 4a. Check that the sector is inside the media.
|
||||||
|
cmp dword [start_sector+4], 0
|
||||||
|
jnz .end_of_media
|
||||||
|
mov eax, dword [start_sector]
|
||||||
|
cmp eax, FLOPPY_CAPACITY
|
||||||
|
jae .end_of_media
|
||||||
|
; 4b. For read operation, call read_chs_sector and then move data from FDD_BUFF to [buffer].
|
||||||
|
; For write operation, move data from [buffer] to FDD_BUFF and then call save_chs_sector.
|
||||||
|
cmp [.operation], 0
|
||||||
|
jz .read
|
||||||
|
mov esi, [buffer]
|
||||||
|
mov edi, FDD_BUFF
|
||||||
|
mov ecx, 512/4
|
||||||
|
rep movsd
|
||||||
|
mov [buffer], esi
|
||||||
|
call save_chs_sector
|
||||||
|
jmp @f
|
||||||
|
.read:
|
||||||
|
call read_chs_sector
|
||||||
|
mov esi, FDD_BUFF
|
||||||
|
mov edi, [buffer]
|
||||||
|
mov ecx, 512/4
|
||||||
|
rep movsd
|
||||||
|
mov [buffer], edi
|
||||||
|
@@:
|
||||||
|
; 4c. If there was an error, propagate it to the caller.
|
||||||
|
cmp [FDC_Status], 0
|
||||||
|
jnz .fail
|
||||||
|
; 4d. Otherwise, increment number of sectors processed and continue the loop.
|
||||||
|
mov eax, [numsectors_ptr]
|
||||||
|
inc dword [eax]
|
||||||
|
inc dword [start_sector]
|
||||||
|
dec [.sectors_todo]
|
||||||
|
jnz .operation_loop
|
||||||
|
; 5. Release the global lock and return with the correct status.
|
||||||
|
push 0
|
||||||
|
.return:
|
||||||
|
mov ecx, floppy_mutex
|
||||||
|
call mutex_unlock
|
||||||
|
pop eax
|
||||||
|
pop edi esi ebx ; restore used registers to be stdcall
|
||||||
|
ret ; this translates to leave/retn N and purges local variables
|
||||||
|
.fail:
|
||||||
|
push -1
|
||||||
|
jmp .return
|
||||||
|
.end_of_media:
|
||||||
|
push DISK_STATUS_END_OF_MEDIA
|
||||||
|
jmp .return
|
||||||
|
endp
|
||||||
|
@ -47,6 +47,10 @@ hd0_data HD_DATA ?, 0, 1
|
|||||||
hd1_data HD_DATA ?, 0x10, 2
|
hd1_data HD_DATA ?, 0x10, 2
|
||||||
hd2_data HD_DATA ?, 0, 3
|
hd2_data HD_DATA ?, 0, 3
|
||||||
hd3_data HD_DATA ?, 0x10, 4
|
hd3_data HD_DATA ?, 0x10, 4
|
||||||
|
|
||||||
|
hd_address_table:
|
||||||
|
dd 0x1f0, 0x00, 0x1f0, 0x10
|
||||||
|
dd 0x170, 0x00, 0x170, 0x10
|
||||||
endg
|
endg
|
||||||
|
|
||||||
uglobal
|
uglobal
|
||||||
@ -645,14 +649,6 @@ hd_write_error:
|
|||||||
end if
|
end if
|
||||||
ret
|
ret
|
||||||
;-----------------------------------------------------------------------------
|
;-----------------------------------------------------------------------------
|
||||||
hd_lba_error:
|
|
||||||
if lang eq sp
|
|
||||||
DEBUGF 1,"K : FS - HD error en LBA\n"
|
|
||||||
else
|
|
||||||
DEBUGF 1,"K : FS - HD LBA error\n"
|
|
||||||
end if
|
|
||||||
jmp LBA_read_ret
|
|
||||||
;-----------------------------------------------------------------------------
|
|
||||||
align 4
|
align 4
|
||||||
wait_for_hd_idle:
|
wait_for_hd_idle:
|
||||||
push eax edx
|
push eax edx
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -13,16 +13,19 @@ saverd_fileinfo:
|
|||||||
dd 2 ; subfunction: write
|
dd 2 ; subfunction: write
|
||||||
dd 0 ; (reserved)
|
dd 0 ; (reserved)
|
||||||
dd 0 ; (reserved)
|
dd 0 ; (reserved)
|
||||||
dd 1440*1024 ; size 1440 Kb
|
.size:
|
||||||
|
dd 0
|
||||||
dd RAMDISK
|
dd RAMDISK
|
||||||
db 0
|
db 0
|
||||||
.name:
|
.name:
|
||||||
dd ?
|
dd ?
|
||||||
endg
|
endg
|
||||||
sysfn_saveramdisk: ; 18.6 = SAVE FLOPPY IMAGE (HD version only)
|
sysfn_saveramdisk: ; 18.6 = SAVE FLOPPY IMAGE (HD version only)
|
||||||
call restorefatchain
|
|
||||||
mov ebx, saverd_fileinfo
|
mov ebx, saverd_fileinfo
|
||||||
mov [saverd_fileinfo.name], ecx
|
mov [ebx+21], ecx
|
||||||
|
mov eax, [ramdisk_actual_size]
|
||||||
|
shl eax, 9
|
||||||
|
mov [ebx+12], eax
|
||||||
pushad
|
pushad
|
||||||
call file_system_lfn_protected ;in ebx
|
call file_system_lfn_protected ;in ebx
|
||||||
popad
|
popad
|
||||||
|
@ -1,302 +0,0 @@
|
|||||||
; FAT12 boot sector for Kolibri OS
|
|
||||||
;
|
|
||||||
; Copyright (C) Alex Nogueira Teixeira
|
|
||||||
; Copyright (C) Diamond
|
|
||||||
; Copyright (C) Dmitry Kartashov aka shurf
|
|
||||||
;
|
|
||||||
; Distributed under GPL, see file COPYING for details
|
|
||||||
;
|
|
||||||
; Version 1.0
|
|
||||||
|
|
||||||
lf equ 0ah
|
|
||||||
cr equ 0dh
|
|
||||||
|
|
||||||
pos_read_tmp equ 0700h ;position for temporary read
|
|
||||||
boot_program equ 07c00h ;position for boot code
|
|
||||||
seg_read_kernel equ 01000h ;segment to kernel read
|
|
||||||
|
|
||||||
jmp start_program
|
|
||||||
nop
|
|
||||||
|
|
||||||
; Boot Sector and BPB Structure
|
|
||||||
BS_OEMName db 'KOLIBRI ' ; db 8
|
|
||||||
BPB_BytsPerSec dw 512 ; bytes per sector
|
|
||||||
BPB_SecPerClus db 1 ; sectors per cluster
|
|
||||||
BPB_RsvdSecCnt dw 1 ; number of reserver sectors
|
|
||||||
BPB_NumFATs db 2 ; count of FAT data structures
|
|
||||||
BPB_RootEntCnt dw 224 ; count of 32-byte dir. entries (224*32 = 14 sectors)
|
|
||||||
BPB_TotSec16 dw 2880 ; count of sectors on the volume (2880 for 1.44 mbytes disk)
|
|
||||||
BPB_Media db 0f0h ; f0 - used for removable media
|
|
||||||
BPB_FATSz16 dw 9 ; count of sectors by one copy of FAT
|
|
||||||
BPB_SecPerTrk dw 18 ; sectors per track
|
|
||||||
BPB_NumHeads dw 2 ; number of heads
|
|
||||||
BPB_HiddSec dd 0 ; count of hidden sectors
|
|
||||||
BPB_TotSec32 dd 0 ; count of sectors on the volume (if > 65535)
|
|
||||||
BS_DrvNum db 0 ; int 13h drive number
|
|
||||||
BS_Reserved db 0 ; reserved
|
|
||||||
BS_BootSig db 29h ; Extended boot signature
|
|
||||||
BS_VolID dd 0 ; Volume serial number
|
|
||||||
BS_VolLab db 'KOLIBRI ' ; Volume label (db 11)
|
|
||||||
BS_FilSysType db 'FAT12 ' ; file system type (db 8)
|
|
||||||
|
|
||||||
start_program:
|
|
||||||
|
|
||||||
xor ax,ax
|
|
||||||
mov ss,ax
|
|
||||||
mov sp,boot_program
|
|
||||||
push ss
|
|
||||||
pop ds
|
|
||||||
|
|
||||||
; print loading string
|
|
||||||
mov si,loading+boot_program
|
|
||||||
loop_loading:
|
|
||||||
lodsb
|
|
||||||
or al,al
|
|
||||||
jz read_root_directory
|
|
||||||
mov ah,0eh
|
|
||||||
mov bx,7
|
|
||||||
int 10h
|
|
||||||
jmp loop_loading
|
|
||||||
|
|
||||||
read_root_directory:
|
|
||||||
push ss
|
|
||||||
pop es
|
|
||||||
|
|
||||||
; calculate some disk parameters
|
|
||||||
; - beginning sector of RootDir
|
|
||||||
mov ax,word [BPB_FATSz16+boot_program]
|
|
||||||
xor cx,cx
|
|
||||||
mov cl,byte [BPB_NumFATs+boot_program]
|
|
||||||
mul cx
|
|
||||||
add ax,word [BPB_RsvdSecCnt+boot_program]
|
|
||||||
mov word [FirstRootDirSecNum+boot_program],ax ; 19
|
|
||||||
mov si,ax
|
|
||||||
|
|
||||||
; - count of sectors in RootDir
|
|
||||||
mov bx,word [BPB_BytsPerSec+boot_program]
|
|
||||||
mov cl,5 ; divide ax by 32
|
|
||||||
shr bx,cl ; bx = directory entries per sector
|
|
||||||
mov ax,word [BPB_RootEntCnt+boot_program]
|
|
||||||
xor dx,dx
|
|
||||||
div bx
|
|
||||||
mov word [RootDirSecs+boot_program],ax ; 14
|
|
||||||
|
|
||||||
; - data start
|
|
||||||
add si,ax ; add beginning sector of RootDir and count sectors in RootDir
|
|
||||||
mov word [data_start+boot_program],si ; 33
|
|
||||||
; reading root directory
|
|
||||||
; al=count root dir sectrors !!!! TODO: al, max 255 sectors !!!!
|
|
||||||
mov ah,2 ; read
|
|
||||||
push ax
|
|
||||||
|
|
||||||
mov ax,word [FirstRootDirSecNum+boot_program]
|
|
||||||
call conv_abs_to_THS ; convert abs sector (AX) to BIOS T:H:S (track:head:sector)
|
|
||||||
pop ax
|
|
||||||
mov bx,pos_read_tmp ; es:bx read buffer
|
|
||||||
call read_sector
|
|
||||||
|
|
||||||
mov si,bx ; read buffer address: es:si
|
|
||||||
mov ax,[RootDirSecs+boot_program]
|
|
||||||
mul word [BPB_BytsPerSec+boot_program]
|
|
||||||
add ax,si ; AX = end of root dir. in buffer pos_read_tmp
|
|
||||||
|
|
||||||
; find kernel file in root directory
|
|
||||||
loop_find_dir_entry:
|
|
||||||
push si
|
|
||||||
mov cx,11
|
|
||||||
mov di,kernel_name+boot_program
|
|
||||||
rep cmpsb ; compare es:si and es:di, cx bytes long
|
|
||||||
pop si
|
|
||||||
je found_kernel_file
|
|
||||||
add si,32 ; next dir. entry
|
|
||||||
cmp si,ax ; end of directory
|
|
||||||
jb loop_find_dir_entry
|
|
||||||
|
|
||||||
file_error_message:
|
|
||||||
mov si,error_message+boot_program
|
|
||||||
|
|
||||||
loop_error_message:
|
|
||||||
lodsb
|
|
||||||
or al,al
|
|
||||||
jz freeze_pc
|
|
||||||
mov ah,0eh
|
|
||||||
mov bx,7
|
|
||||||
int 10h
|
|
||||||
jmp loop_error_message
|
|
||||||
|
|
||||||
freeze_pc:
|
|
||||||
jmp $ ; endless loop
|
|
||||||
|
|
||||||
; === KERNEL FOUND. LOADING... ===
|
|
||||||
|
|
||||||
found_kernel_file:
|
|
||||||
mov bp,[si+01ah] ; first cluster of kernel file
|
|
||||||
; <diamond>
|
|
||||||
mov [cluster1st+boot_program],bp ; starting cluster of kernel file
|
|
||||||
; <\diamond>
|
|
||||||
|
|
||||||
; reading first FAT table
|
|
||||||
mov ax,word [BPB_RsvdSecCnt+boot_program] ; begin first FAT abs sector number
|
|
||||||
call conv_abs_to_THS ; convert abs sector (AX) to BIOS T:H:S (track:head:sector)
|
|
||||||
mov bx,pos_read_tmp ; es:bx read position
|
|
||||||
mov ah,2 ; ah=2 (read)
|
|
||||||
mov al, byte [BPB_FATSz16+boot_program] ; FAT size in sectors (TODO: max 255 sectors)
|
|
||||||
call read_sector
|
|
||||||
jc file_error_message ; read error
|
|
||||||
|
|
||||||
mov ax,seg_read_kernel
|
|
||||||
mov es,ax
|
|
||||||
xor bx,bx ; es:bx = 1000h:0000h
|
|
||||||
|
|
||||||
|
|
||||||
; reading kernel file
|
|
||||||
loop_obtains_kernel_data:
|
|
||||||
; read one cluster of file
|
|
||||||
call obtain_cluster
|
|
||||||
jc file_error_message ; read error
|
|
||||||
|
|
||||||
; add one cluster length to segment:offset
|
|
||||||
push bx
|
|
||||||
mov bx,es
|
|
||||||
mov ax,word [BPB_BytsPerSec+boot_program] ;\
|
|
||||||
movsx cx,byte [BPB_SecPerClus+boot_program] ; | !!! TODO: !!!
|
|
||||||
mul cx ; | out this from loop !!!
|
|
||||||
shr ax,4 ;/
|
|
||||||
add bx,ax
|
|
||||||
mov es,bx
|
|
||||||
pop bx
|
|
||||||
|
|
||||||
mov di,bp
|
|
||||||
shr di,1
|
|
||||||
pushf
|
|
||||||
add di,bp ; di = bp * 1.5
|
|
||||||
add di,pos_read_tmp
|
|
||||||
mov ax,[di] ; read next entry from FAT-chain
|
|
||||||
popf
|
|
||||||
jc move_4_right
|
|
||||||
and ax,0fffh
|
|
||||||
jmp verify_end_sector
|
|
||||||
move_4_right:
|
|
||||||
mov cl,4
|
|
||||||
shr ax,cl
|
|
||||||
verify_end_sector:
|
|
||||||
cmp ax,0ff8h ; last cluster
|
|
||||||
jae execute_kernel
|
|
||||||
mov bp,ax
|
|
||||||
jmp loop_obtains_kernel_data
|
|
||||||
|
|
||||||
execute_kernel:
|
|
||||||
; <diamond>
|
|
||||||
mov ax,'KL'
|
|
||||||
push 0
|
|
||||||
pop ds
|
|
||||||
mov si,loader_block+boot_program
|
|
||||||
; </diamond>
|
|
||||||
push word seg_read_kernel
|
|
||||||
push word 0
|
|
||||||
retf ; jmp far 1000:0000
|
|
||||||
|
|
||||||
|
|
||||||
;------------------------------------------
|
|
||||||
; loading cluster from file to es:bx
|
|
||||||
obtain_cluster:
|
|
||||||
; bp - cluster number to read
|
|
||||||
; carry = 0 -> read OK
|
|
||||||
; carry = 1 -> read ERROR
|
|
||||||
|
|
||||||
; print one dot
|
|
||||||
push bx
|
|
||||||
mov ax,0e2eh ; ah=0eh (teletype), al='.'
|
|
||||||
xor bh,bh
|
|
||||||
int 10h
|
|
||||||
pop bx
|
|
||||||
|
|
||||||
writesec:
|
|
||||||
; convert cluster number to sector number
|
|
||||||
mov ax,bp ; data cluster to read
|
|
||||||
sub ax,2
|
|
||||||
xor dx,dx
|
|
||||||
mov dl,byte [BPB_SecPerClus+boot_program]
|
|
||||||
mul dx
|
|
||||||
add ax,word [data_start+boot_program]
|
|
||||||
|
|
||||||
call conv_abs_to_THS ; convert abs sector (AX) to BIOS T:H:S (track:head:sector)
|
|
||||||
patchhere:
|
|
||||||
mov ah,2 ; ah=2 (read)
|
|
||||||
mov al,byte [BPB_SecPerClus+boot_program] ; al=(one cluster)
|
|
||||||
call read_sector
|
|
||||||
retn
|
|
||||||
;------------------------------------------
|
|
||||||
|
|
||||||
;------------------------------------------
|
|
||||||
; read sector from disk
|
|
||||||
read_sector:
|
|
||||||
push bp
|
|
||||||
mov bp,20 ; try 20 times
|
|
||||||
newread:
|
|
||||||
dec bp
|
|
||||||
jz file_error_message
|
|
||||||
push ax bx cx dx
|
|
||||||
int 13h
|
|
||||||
pop dx cx bx ax
|
|
||||||
jc newread
|
|
||||||
pop bp
|
|
||||||
retn
|
|
||||||
;------------------------------------------
|
|
||||||
; convert abs. sector number (AX) to BIOS T:H:S
|
|
||||||
; sector number = (abs.sector%BPB_SecPerTrk)+1
|
|
||||||
; pre.track number = (abs.sector/BPB_SecPerTrk)
|
|
||||||
; head number = pre.track number%BPB_NumHeads
|
|
||||||
; track number = pre.track number/BPB_NumHeads
|
|
||||||
; Return: cl - sector number
|
|
||||||
; ch - track number
|
|
||||||
; dl - drive number (0 = a:)
|
|
||||||
; dh - head number
|
|
||||||
conv_abs_to_THS:
|
|
||||||
push bx
|
|
||||||
mov bx,word [BPB_SecPerTrk+boot_program]
|
|
||||||
xor dx,dx
|
|
||||||
div bx
|
|
||||||
inc dx
|
|
||||||
mov cl, dl ; cl = sector number
|
|
||||||
mov bx,word [BPB_NumHeads+boot_program]
|
|
||||||
xor dx,dx
|
|
||||||
div bx
|
|
||||||
; !!!!!!! ax = track number, dx = head number
|
|
||||||
mov ch,al ; ch=track number
|
|
||||||
xchg dh,dl ; dh=head number
|
|
||||||
mov dl,0 ; dl=0 (drive 0 (a:))
|
|
||||||
pop bx
|
|
||||||
retn
|
|
||||||
;------------------------------------------
|
|
||||||
|
|
||||||
loading db cr,lf,'Starting system ',00h
|
|
||||||
error_message db 13,10
|
|
||||||
kernel_name db 'KERNEL MNT ?',cr,lf,00h
|
|
||||||
FirstRootDirSecNum dw ?
|
|
||||||
RootDirSecs dw ?
|
|
||||||
data_start dw ?
|
|
||||||
|
|
||||||
; <diamond>
|
|
||||||
write1st:
|
|
||||||
push cs
|
|
||||||
pop ds
|
|
||||||
mov byte [patchhere+1+boot_program], 3 ; change ah=2 to ah=3
|
|
||||||
mov bp,[cluster1st+boot_program]
|
|
||||||
push 1000h
|
|
||||||
pop es
|
|
||||||
xor bx,bx
|
|
||||||
call writesec
|
|
||||||
mov byte [patchhere+1+boot_program], 2 ; change back ah=3 to ah=2
|
|
||||||
retf
|
|
||||||
cluster1st dw ?
|
|
||||||
loader_block:
|
|
||||||
db 1
|
|
||||||
dw 0
|
|
||||||
dw write1st+boot_program
|
|
||||||
dw 0
|
|
||||||
; <\diamond>
|
|
||||||
|
|
||||||
times 0x1fe-$ db 00h
|
|
||||||
|
|
||||||
db 55h,0aah ;boot signature
|
|
@ -1,101 +0,0 @@
|
|||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;; ;;
|
|
||||||
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;;
|
|
||||||
;; Distributed under terms of the GNU General Public License ;;
|
|
||||||
;; ;;
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
|
|
||||||
;======================================================================
|
|
||||||
;
|
|
||||||
; BOOT DATA
|
|
||||||
;
|
|
||||||
;======================================================================
|
|
||||||
|
|
||||||
$Revision$
|
|
||||||
|
|
||||||
|
|
||||||
d80x25_bottom:
|
|
||||||
db 186,' KolibriOS is based on MenuetOS and comes with ABSOLUTELY '
|
|
||||||
db 'NO WARRANTY ',186
|
|
||||||
db 186,' See file COPYING for details '
|
|
||||||
db ' ',186
|
|
||||||
line_full_bottom
|
|
||||||
d80x25_bottom_num = 3
|
|
||||||
|
|
||||||
msg_apm db " APM x.x ", 0
|
|
||||||
novesa db "Display: EGA/CGA",13,10,0
|
|
||||||
s_vesa db "Version of VESA: "
|
|
||||||
.ver db "?.?",13,10,0
|
|
||||||
|
|
||||||
gr_mode db "Select a videomode: ",13,10,0
|
|
||||||
|
|
||||||
ask_bd db "Add disks visible by BIOS emulated in V86-mode? [1-yes, 2-no]: ",0
|
|
||||||
|
|
||||||
if defined extended_primary_loader
|
|
||||||
bdev db "Load ramdisk from [1-floppy; 2-kolibri.img]: ",0
|
|
||||||
else
|
|
||||||
bdev db "Load ramdisk from [1-floppy; 2-C:\kolibri.img (FAT32);"
|
|
||||||
db 13,10,186," "
|
|
||||||
db "3-use preloaded ram-image from kernel restart;"
|
|
||||||
db 13,10,186," "
|
|
||||||
db "4-create blank image]: ",0
|
|
||||||
end if
|
|
||||||
|
|
||||||
prnotfnd db "Fatal - Videomode not found.",0
|
|
||||||
|
|
||||||
not386 db "Fatal - CPU 386+ required.",0
|
|
||||||
fatalsel db "Fatal - Graphics mode not supported by hardware.",0
|
|
||||||
pres_key db "Press any key to choose a new videomode.",0
|
|
||||||
badsect db 13,10,186," Fatal - Bad sector. Replace floppy.",0
|
|
||||||
memmovefailed db 13,10,186," Fatal - Int 0x15 move failed.",0
|
|
||||||
okt db " ... OK"
|
|
||||||
linef db 13,10,0
|
|
||||||
diskload db "Loading diskette: 00 %",8,8,8,8,0
|
|
||||||
pros db "00"
|
|
||||||
backspace2 db 8,8,0
|
|
||||||
boot_dev db 0 ; 0=floppy, 1=hd
|
|
||||||
start_msg db "Press [abcd] to change settings, press [Enter] to continue booting",13,10,0
|
|
||||||
time_msg db " or wait "
|
|
||||||
time_str db " 5 seconds"
|
|
||||||
db " before automatical continuation",13,10,0
|
|
||||||
current_cfg_msg db "Current settings:",13,10,0
|
|
||||||
curvideo_msg db " [a] Videomode: ",0
|
|
||||||
|
|
||||||
mode0 db "320x200, EGA/CGA 256 colors",13,10,0
|
|
||||||
mode9 db "640x480, VGA 16 colors",13,10,0
|
|
||||||
|
|
||||||
usebd_msg db " [b] Add disks visible by BIOS:",0
|
|
||||||
on_msg db " on",13,10,0
|
|
||||||
off_msg db " off",13,10,0
|
|
||||||
|
|
||||||
preboot_device_msg db " [c] Floppy image: ",0
|
|
||||||
|
|
||||||
if defined extended_primary_loader
|
|
||||||
preboot_device_msgs dw 0,pdm1,pdm2,0
|
|
||||||
pdm1 db "real floppy",13,10,0
|
|
||||||
pdm2 db "C:\kolibri.img (FAT32)",13,10,0
|
|
||||||
else
|
|
||||||
preboot_device_msgs dw 0,pdm1,pdm2,pdm3
|
|
||||||
pdm1 db "real floppy",13,10,0
|
|
||||||
pdm2 db "C:\kolibri.img (FAT32)",13,10,0
|
|
||||||
pdm3 db "use already loaded image",13,10,0
|
|
||||||
pdm4 db "create blank image",13,10,0
|
|
||||||
end if
|
|
||||||
|
|
||||||
loading_msg db "Loading KolibriOS...",0
|
|
||||||
|
|
||||||
if ~ defined extended_primary_loader
|
|
||||||
save_quest db "Remember current settings? [y/n]: ",0
|
|
||||||
loader_block_error db "Bootloader data invalid, I cannot continue. Stopped.",0
|
|
||||||
end if
|
|
||||||
|
|
||||||
_st db 186,' ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄ¿',13,10,0
|
|
||||||
_r1 db 186,' ³ 320x200 EGA/CGA 256 colors ³ ³',13,10,0
|
|
||||||
_r2 db 186,' ³ 640x480 VGA 16 colors ³ ³',13,10,0
|
|
||||||
_rs db 186,' ³ ????x????@?? SVGA VESA ³ ³',13,10,0
|
|
||||||
_bt db 186,' ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÙ',13,10,0
|
|
||||||
|
|
||||||
remark1 db "Default values were selected to match most of configurations, but not all.",0
|
|
||||||
remark2 db "If the system does not boot, try to disable the item [b].",0
|
|
||||||
remarks dw remark1, remark2
|
|
||||||
num_remarks = 2
|
|
@ -659,10 +659,6 @@ terminate: ; terminate application
|
|||||||
jnz @f
|
jnz @f
|
||||||
call free_cd_channel
|
call free_cd_channel
|
||||||
and [cd_status], 0
|
and [cd_status], 0
|
||||||
@@:
|
|
||||||
cmp [flp_status], esi
|
|
||||||
jnz @f
|
|
||||||
and [flp_status], 0
|
|
||||||
@@:
|
@@:
|
||||||
pop esi
|
pop esi
|
||||||
cmp [bgrlockpid], esi
|
cmp [bgrlockpid], esi
|
||||||
|
@ -7,20 +7,6 @@
|
|||||||
|
|
||||||
$Revision$
|
$Revision$
|
||||||
|
|
||||||
; Old style system call converter
|
|
||||||
align 16
|
|
||||||
cross_order:
|
|
||||||
; load all registers in crossed order
|
|
||||||
mov eax, ebx
|
|
||||||
mov ebx, ecx
|
|
||||||
mov ecx, edx
|
|
||||||
mov edx, esi
|
|
||||||
mov esi, edi
|
|
||||||
movzx edi, byte[esp+28 + 4]
|
|
||||||
sub edi, 53
|
|
||||||
call dword [servetable+edi*4]
|
|
||||||
ret
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; ;;
|
;; ;;
|
||||||
;; SYSENTER ENTRY ;;
|
;; SYSENTER ENTRY ;;
|
||||||
@ -109,24 +95,6 @@ iglobal
|
|||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; SYSTEM FUNCTIONS TABLE ;;
|
;; SYSTEM FUNCTIONS TABLE ;;
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
align 4
|
|
||||||
servetable:
|
|
||||||
dd 0
|
|
||||||
dd 0
|
|
||||||
dd 0
|
|
||||||
dd 0
|
|
||||||
dd 0
|
|
||||||
dd file_system ; 58-Common file system interface
|
|
||||||
dd 0
|
|
||||||
dd 0
|
|
||||||
dd 0
|
|
||||||
dd 0
|
|
||||||
dd 0
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;; NEW SYSTEM FUNCTIONS TABLE ;;
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
align 4
|
align 4
|
||||||
servetable2:
|
servetable2:
|
||||||
|
|
||||||
@ -136,7 +104,7 @@ iglobal
|
|||||||
dd sys_clock ; 3-GetTime
|
dd sys_clock ; 3-GetTime
|
||||||
dd syscall_writetext ; 4-WriteText
|
dd syscall_writetext ; 4-WriteText
|
||||||
dd delay_hs_unprotected ; 5-DelayHs
|
dd delay_hs_unprotected ; 5-DelayHs
|
||||||
dd syscall_openramdiskfile ; 6-OpenRamdiskFile
|
dd undefined_syscall ; 6-deprecated OpenRamdiskFile
|
||||||
dd syscall_putimage ; 7-PutImage
|
dd syscall_putimage ; 7-PutImage
|
||||||
dd syscall_button ; 8-DefineButton
|
dd syscall_button ; 8-DefineButton
|
||||||
dd sys_cpuusage ; 9-GetProcessInfo
|
dd sys_cpuusage ; 9-GetProcessInfo
|
||||||
@ -188,7 +156,7 @@ iglobal
|
|||||||
dd sound_interface ; 55-Sound interface
|
dd sound_interface ; 55-Sound interface
|
||||||
dd undefined_syscall ; 56-reserved
|
dd undefined_syscall ; 56-reserved
|
||||||
dd sys_pcibios ; 57-PCI BIOS32
|
dd sys_pcibios ; 57-PCI BIOS32
|
||||||
dd cross_order ; 58-Common file system interface
|
dd undefined_syscall ; 58-deprecated Common file system interface
|
||||||
dd undefined_syscall ; 59-reserved
|
dd undefined_syscall ; 59-reserved
|
||||||
dd sys_IPC ; 60-Inter Process Communication
|
dd sys_IPC ; 60-Inter Process Communication
|
||||||
dd sys_gs ; 61-Direct graphics access
|
dd sys_gs ; 61-Direct graphics access
|
||||||
|
@ -51,7 +51,7 @@ keymap_alt:
|
|||||||
if lang eq ru
|
if lang eq ru
|
||||||
boot_initirq cp866 'Инициализация IRQ',0
|
boot_initirq cp866 'Инициализация IRQ',0
|
||||||
boot_picinit cp866 'Инициализация PIC',0
|
boot_picinit cp866 'Инициализация PIC',0
|
||||||
boot_v86machine cp866 'Инициализация системы V86 машины',0
|
boot_v86machine cp866 'Инициализация системной V86 машины',0
|
||||||
boot_inittimer cp866 'Инициализация системного таймера (IRQ0)',0
|
boot_inittimer cp866 'Инициализация системного таймера (IRQ0)',0
|
||||||
boot_initapic cp866 'Попытка инициализации APIC',0
|
boot_initapic cp866 'Попытка инициализации APIC',0
|
||||||
boot_enableirq cp866 'Включить прерывания 2, 13',0
|
boot_enableirq cp866 'Включить прерывания 2, 13',0
|
||||||
@ -69,6 +69,7 @@ if lang eq ru
|
|||||||
boot_cpuid cp866 'Чтение CPUIDs',0
|
boot_cpuid cp866 'Чтение CPUIDs',0
|
||||||
; boot_devices cp866 'Поиск устройств',0
|
; boot_devices cp866 'Поиск устройств',0
|
||||||
boot_timer cp866 'Установка таймера',0
|
boot_timer cp866 'Установка таймера',0
|
||||||
|
boot_initramdisk cp866 'Инициализация рамдиска',0
|
||||||
boot_irqs cp866 'Переопределение IRQ',0
|
boot_irqs cp866 'Переопределение IRQ',0
|
||||||
boot_setmouse cp866 'Установка мыши',0
|
boot_setmouse cp866 'Установка мыши',0
|
||||||
boot_windefs cp866 'Установка настроек окон по умолчанию',0
|
boot_windefs cp866 'Установка настроек окон по умолчанию',0
|
||||||
@ -98,6 +99,7 @@ else
|
|||||||
boot_picinit db 'Initialize PIC',0
|
boot_picinit db 'Initialize PIC',0
|
||||||
boot_v86machine db 'Initialize system V86 machine',0
|
boot_v86machine db 'Initialize system V86 machine',0
|
||||||
boot_inittimer db 'Initialize system timer (IRQ0)',0
|
boot_inittimer db 'Initialize system timer (IRQ0)',0
|
||||||
|
boot_initramdisk db 'Initialize ramdisk',0
|
||||||
boot_initapic db 'Try to initialize APIC',0
|
boot_initapic db 'Try to initialize APIC',0
|
||||||
boot_enableirq db 'Enable interrupts 2, 13',0
|
boot_enableirq db 'Enable interrupts 2, 13',0
|
||||||
boot_disabling_ide db 'Disable interrupts in IDE controller',0
|
boot_disabling_ide db 'Disable interrupts in IDE controller',0
|
||||||
@ -172,7 +174,13 @@ end if
|
|||||||
|
|
||||||
vmode db '/sys/drivers/VMODE.MDR',0
|
vmode db '/sys/drivers/VMODE.MDR',0
|
||||||
;vrr_m db 'VRR_M',0
|
;vrr_m db 'VRR_M',0
|
||||||
kernel_file db 'KERNEL MNT'
|
kernel_file_load:
|
||||||
|
; load kernel.mnt to 0x7000:0
|
||||||
|
dd 0 ; subfunction
|
||||||
|
dq 0 ; offset in file
|
||||||
|
dd 0x30000 ; number of bytes to read
|
||||||
|
dd OS_BASE + 0x70000 ; buffer for data
|
||||||
|
db '/RD/1/KERNEL.MNT',0
|
||||||
|
|
||||||
dev_data_path db '/RD/1/DRIVERS/DEVICES.DAT',0
|
dev_data_path db '/RD/1/DRIVERS/DEVICES.DAT',0
|
||||||
|
|
||||||
@ -570,8 +578,7 @@ end if
|
|||||||
org (OS_BASE+0x0100000)
|
org (OS_BASE+0x0100000)
|
||||||
|
|
||||||
RAMDISK: rb 2880*512
|
RAMDISK: rb 2880*512
|
||||||
RAMDISK_FAT: rb 2856*2
|
rb 2856*4 ; not used
|
||||||
FLOPPY_FAT: rb 2856*2
|
|
||||||
|
|
||||||
_CLEAN_ZONE:
|
_CLEAN_ZONE:
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
boot_picinit latin1 'Algväärtustan PIC',0
|
boot_picinit latin1 'Algväärtustan PIC',0
|
||||||
boot_v86machine latin1 'Algväärtustan süsteemi V86 masinat',0
|
boot_v86machine latin1 'Algväärtustan süsteemi V86 masinat',0
|
||||||
boot_inittimer latin1 'Algväärtustan süsteemi taimerit (IRQ0)',0
|
boot_inittimer latin1 'Algväärtustan süsteemi taimerit (IRQ0)',0
|
||||||
|
boot_initramdisk latin1 'Initialize ramdisk',0
|
||||||
boot_initapic latin1 'Proovin Algväärtustada APIC',0
|
boot_initapic latin1 'Proovin Algväärtustada APIC',0
|
||||||
boot_enableirq latin1 'Luban katkestused 2, 13',0
|
boot_enableirq latin1 'Luban katkestused 2, 13',0
|
||||||
boot_disabling_ide latin1 'Keelan IDE kontrolleri katkestused',0
|
boot_disabling_ide latin1 'Keelan IDE kontrolleri katkestused',0
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
boot_picinit: cp850 'Inicializar PIC',0
|
boot_picinit: cp850 'Inicializar PIC',0
|
||||||
boot_v86machine: cp850 'Inicializar sistema V86',0
|
boot_v86machine: cp850 'Inicializar sistema V86',0
|
||||||
boot_inittimer: cp850 'Inicializar reloj del sistema (IRQ0)',0
|
boot_inittimer: cp850 'Inicializar reloj del sistema (IRQ0)',0
|
||||||
|
boot_initramdisk cp850 'Initialize ramdisk',0
|
||||||
boot_initapic: cp850 'Prueba inicializar APIC',0
|
boot_initapic: cp850 'Prueba inicializar APIC',0
|
||||||
boot_enableirq: cp850 'Habilitar interrupciones 2, 13',0
|
boot_enableirq: cp850 'Habilitar interrupciones 2, 13',0
|
||||||
boot_disabling_ide:cp850 'Habiliar interrupciones en controladores IDE',0
|
boot_disabling_ide:cp850 'Habiliar interrupciones en controladores IDE',0
|
||||||
|
@ -33,5 +33,6 @@ wait_cmos:
|
|||||||
|
|
||||||
stdcall attach_int_handler, 6, FDCInterrupt, 0
|
stdcall attach_int_handler, 6, FDCInterrupt, 0
|
||||||
DEBUGF 1, "K : Set IDE IRQ6 return code %x\n", eax
|
DEBUGF 1, "K : Set IDE IRQ6 return code %x\n", eax
|
||||||
|
call floppy_init
|
||||||
@@:
|
@@:
|
||||||
|
|
||||||
|
@ -36,14 +36,20 @@ Vortex86SoClist: ; List of Vortex86 CPUs known today. Add
|
|||||||
Vortex86SoCnum = ($ - Vortex86SoClist) / 4 ; Calculate the total number of known Vortex86 CPUs (if id=Vortex86SoCnum+1 --> unknown SoC)
|
Vortex86SoCnum = ($ - Vortex86SoClist) / 4 ; Calculate the total number of known Vortex86 CPUs (if id=Vortex86SoCnum+1 --> unknown SoC)
|
||||||
endg
|
endg
|
||||||
|
|
||||||
|
; When in debug mode, perform SoC detection regardless of the actual CPU vendor (even for vendors other than DMP)
|
||||||
|
; When in normal (not debug) mode, check the CPU vendor first, and perform SoC detection only if vendor is 'Vortex86 SoC'
|
||||||
|
if ~ VORTEX86DEBUG
|
||||||
|
cmp [cpu_vendor], 'Vort'
|
||||||
|
jnz .Vortex86end ; If the CPU vendor is not 'Vortex86 SoC', skip the SoC detection
|
||||||
|
end if
|
||||||
|
|
||||||
mov dx, 0xcf8 ; CF8h = Vortex86 PCI Configuration Address port
|
mov dx, 0xcf8 ; CF8h = Vortex86 PCI Configuration Address port
|
||||||
mov eax, 0x80000090 ; 0x80000090 = Starting PCI address to read from (32-bit register - accessed as DWORD)
|
mov eax, 0x80000090 ; 0x80000090 = Starting PCI address to read from (32-bit register - accessed as DWORD)
|
||||||
out dx, eax ; Send request to PCI address port to retrieve data from this address
|
out dx, eax ; Send request to PCI address port to retrieve data from this address
|
||||||
mov dx, 0xcfc ; CFCh = Vortex86 PCI Configuration Data port
|
mov dx, 0xcfc ; CFCh = Vortex86 PCI Configuration Data port
|
||||||
in eax, dx ; Read data (SoC type) from PCI data port
|
in eax, dx ; Read data (SoC type) from PCI data port
|
||||||
|
|
||||||
if VORTEX86DEBUG
|
if VORTEX86DEBUG ; When in debug mode, pretend that we received port output equal to "VORTEX86DEBUGVALUE"
|
||||||
; // Used for debug purposes: testing in emulator and in non-Vortex86 CPU computers
|
|
||||||
mov eax, VORTEX86DEBUGVALUE
|
mov eax, VORTEX86DEBUGVALUE
|
||||||
end if
|
end if
|
||||||
|
|
||||||
@ -55,10 +61,9 @@ end if
|
|||||||
cmp ax, 4d44h ; Check whether it's Vortex86 family (all Vortex86 SoC have ID in form of "0xNN504d44")
|
cmp ax, 4d44h ; Check whether it's Vortex86 family (all Vortex86 SoC have ID in form of "0xNN504d44")
|
||||||
jnz .notVortex86
|
jnz .notVortex86
|
||||||
shr eax, 16 ; Discard lower word in EAX which is always 4d44h in Vortex86 family
|
shr eax, 16 ; Discard lower word in EAX which is always 4d44h in Vortex86 family
|
||||||
cmp al, 50h ; The 3rd byte is always 50h in Vortex86 SoC
|
cmp al, 50h ; The 3rd byte is always 50h in Vortex86 SoC (if this is the case, we need just the highest byte)
|
||||||
jnz .notVortex86
|
jnz .notVortex86
|
||||||
shr ax, 8 ; Discard 3rd byte in EAX, the highest byte determines the SoC type
|
mov bl, ah ; Copy SoC type to BL since EAX (that includes AH) is used implicitly in "LODSD" command below
|
||||||
mov bl, al ; Copy SoC type to BL since EAX (that contains AL) is used implicitly in "LODSD" command below
|
|
||||||
mov esi, Vortex86SoClist ; ESI points to the start of Vortex86SoClist (used implicitly in "LODSD" command below)
|
mov esi, Vortex86SoClist ; ESI points to the start of Vortex86SoClist (used implicitly in "LODSD" command below)
|
||||||
xor ecx, ecx ; Zero ECX (it is used as counter)
|
xor ecx, ecx ; Zero ECX (it is used as counter)
|
||||||
cld ; Clears the DF flag in the EFLAGS register (DF=0 --> String operations increment ESI)
|
cld ; Clears the DF flag in the EFLAGS register (DF=0 --> String operations increment ESI)
|
||||||
@ -83,7 +88,7 @@ end if
|
|||||||
|
|
||||||
.unknownVortex86:
|
.unknownVortex86:
|
||||||
mov [Vortex86CPUid], cl ; Save the CPUid (Vortex86SoCnum+1=Unknown Vortex86)
|
mov [Vortex86CPUid], cl ; Save the CPUid (Vortex86SoCnum+1=Unknown Vortex86)
|
||||||
DEBUGF 1, "unknown Vortex86 CPU (has id=%d, last known is %d)\n", [Vortex86CPUid]:1, Vortex86SoCnum
|
DEBUGF 1, "unknown Vortex86 CPU (id=%d, last known is %d)\n", [Vortex86CPUid]:1, Vortex86SoCnum
|
||||||
jmp .Vortex86end
|
jmp .Vortex86end
|
||||||
|
|
||||||
.notVortex86: ; In case this register is used by other CPUs for other purpose, it's interesting what it contains
|
.notVortex86: ; In case this register is used by other CPUs for other purpose, it's interesting what it contains
|
||||||
|
310
kernel/branches/Kolibri-acpi/drivers/agp.asm
Normal file
310
kernel/branches/Kolibri-acpi/drivers/agp.asm
Normal file
@ -0,0 +1,310 @@
|
|||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;; ;;
|
||||||
|
;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;;
|
||||||
|
;; Distributed under terms of the GNU General Public License ;;
|
||||||
|
;; ;;
|
||||||
|
;; simple AGP driver for KolibriOS ;;
|
||||||
|
;; ;;
|
||||||
|
;; Written by hidnplayr@kolibrios.org ;;
|
||||||
|
;; ;;
|
||||||
|
;; GNU GENERAL PUBLIC LICENSE ;;
|
||||||
|
;; Version 2, June 1991 ;;
|
||||||
|
;; ;;
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
|
||||||
|
format MS COFF
|
||||||
|
|
||||||
|
DEBUG equ 1
|
||||||
|
FAST_WRITE equ 0 ; may cause problems with some motherboards
|
||||||
|
|
||||||
|
include 'proc32.inc'
|
||||||
|
include 'imports.inc'
|
||||||
|
|
||||||
|
struc IOCTL
|
||||||
|
{ .handle dd ?
|
||||||
|
.io_code dd ?
|
||||||
|
.input dd ?
|
||||||
|
.inp_size dd ?
|
||||||
|
.output dd ?
|
||||||
|
.out_size dd ?
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual at 0
|
||||||
|
IOCTL IOCTL
|
||||||
|
end virtual
|
||||||
|
|
||||||
|
public START
|
||||||
|
public service_proc
|
||||||
|
public version
|
||||||
|
|
||||||
|
DRV_ENTRY equ 1
|
||||||
|
DRV_EXIT equ -1
|
||||||
|
|
||||||
|
SRV_GETVERSION equ 0
|
||||||
|
SRV_DETECT equ 1
|
||||||
|
|
||||||
|
API_VERSION equ 1
|
||||||
|
|
||||||
|
section '.flat' code readable align 16
|
||||||
|
|
||||||
|
proc START stdcall, state:dword
|
||||||
|
|
||||||
|
cmp [state], 1
|
||||||
|
jne .exit
|
||||||
|
.entry:
|
||||||
|
|
||||||
|
if DEBUG
|
||||||
|
mov esi, msgInit
|
||||||
|
call SysMsgBoardStr
|
||||||
|
end if
|
||||||
|
|
||||||
|
stdcall RegService, my_service, service_proc
|
||||||
|
ret
|
||||||
|
.fail:
|
||||||
|
.exit:
|
||||||
|
xor eax, eax
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
handle equ IOCTL.handle
|
||||||
|
io_code equ IOCTL.io_code
|
||||||
|
input equ IOCTL.input
|
||||||
|
inp_size equ IOCTL.inp_size
|
||||||
|
output equ IOCTL.output
|
||||||
|
out_size equ IOCTL.out_size
|
||||||
|
|
||||||
|
align 4
|
||||||
|
proc service_proc stdcall, ioctl:dword
|
||||||
|
|
||||||
|
mov ebx, [ioctl]
|
||||||
|
mov eax, [ebx+io_code]
|
||||||
|
cmp eax, SRV_GETVERSION
|
||||||
|
jne @F
|
||||||
|
|
||||||
|
mov eax, [ebx+output]
|
||||||
|
cmp [ebx+out_size], 4
|
||||||
|
jne .fail
|
||||||
|
mov [eax], dword API_VERSION
|
||||||
|
xor eax, eax
|
||||||
|
ret
|
||||||
|
@@:
|
||||||
|
mov ebx, [ioctl]
|
||||||
|
mov eax, [ebx+io_code]
|
||||||
|
cmp eax, SRV_DETECT
|
||||||
|
jne @F
|
||||||
|
call detect
|
||||||
|
@@:
|
||||||
|
.fail:
|
||||||
|
or eax, -1
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
restore handle
|
||||||
|
restore io_code
|
||||||
|
restore input
|
||||||
|
restore inp_size
|
||||||
|
restore output
|
||||||
|
restore out_size
|
||||||
|
|
||||||
|
align 4
|
||||||
|
proc detect
|
||||||
|
locals
|
||||||
|
last_bus dd ?
|
||||||
|
endl
|
||||||
|
|
||||||
|
mov esi, msgSearch
|
||||||
|
call SysMsgBoardStr
|
||||||
|
|
||||||
|
xor eax, eax
|
||||||
|
mov [bus], eax
|
||||||
|
inc eax
|
||||||
|
call PciApi ; get last bus
|
||||||
|
cmp eax, -1
|
||||||
|
je .error
|
||||||
|
mov [last_bus], eax
|
||||||
|
|
||||||
|
.next_bus:
|
||||||
|
and [devfn], 0
|
||||||
|
.next_dev:
|
||||||
|
stdcall PciRead16, [bus], [devfn], dword 0x0a ; read class/subclass
|
||||||
|
|
||||||
|
cmp ax, 0x0300 ; display controller - vga compatable controller
|
||||||
|
je .found
|
||||||
|
|
||||||
|
cmp ax, 0x0302 ; display controller - 3d controller
|
||||||
|
je .found
|
||||||
|
|
||||||
|
cmp ax, 0x0380 ; display controller - other display controller
|
||||||
|
je .found
|
||||||
|
|
||||||
|
.next:
|
||||||
|
inc [devfn]
|
||||||
|
cmp [devfn], 256
|
||||||
|
jb .next_dev
|
||||||
|
mov eax, [bus]
|
||||||
|
inc eax
|
||||||
|
mov [bus], eax
|
||||||
|
cmp eax, [last_bus]
|
||||||
|
jna .next_bus
|
||||||
|
|
||||||
|
.error:
|
||||||
|
mov esi, msgFail
|
||||||
|
call SysMsgBoardStr
|
||||||
|
|
||||||
|
xor eax, eax
|
||||||
|
inc eax
|
||||||
|
ret
|
||||||
|
|
||||||
|
.found:
|
||||||
|
stdcall PciRead8, [bus], [devfn], dword 0x06 ; read prog IF
|
||||||
|
test al, 1 shl 4 ; got capabilities list?
|
||||||
|
jnz .got_capabilities_list
|
||||||
|
|
||||||
|
; TODO: Do it the old way: detect device and check with a list of known capabilities
|
||||||
|
; stupid pre PCI 2.2 board....
|
||||||
|
|
||||||
|
jmp .next
|
||||||
|
|
||||||
|
.got_capabilities_list:
|
||||||
|
stdcall PciRead8, [bus], [devfn], dword 0x34 ; read capabilities offset
|
||||||
|
and eax, 11111100b ; always dword aligned
|
||||||
|
mov edi, eax
|
||||||
|
|
||||||
|
.read_capability:
|
||||||
|
stdcall PciRead32, [bus], [devfn], edi ; read capability
|
||||||
|
cmp al, 0x02 ; AGP
|
||||||
|
je .got_agp
|
||||||
|
movzx edi, ah ; pointer to next capability
|
||||||
|
test edi, edi
|
||||||
|
jnz .read_capability
|
||||||
|
jmp .next
|
||||||
|
|
||||||
|
.got_agp:
|
||||||
|
shr eax, 16
|
||||||
|
mov [revision], al ; high nibble = major revision
|
||||||
|
; low nibble = minor revision
|
||||||
|
add edi, 4
|
||||||
|
and al, 0xf0
|
||||||
|
cmp al, 0x30
|
||||||
|
je .agp_3
|
||||||
|
|
||||||
|
.agp_2:
|
||||||
|
mov esi, msgAGP2
|
||||||
|
call SysMsgBoardStr
|
||||||
|
|
||||||
|
stdcall PciRead32, [bus], [devfn], edi ; read AGP status
|
||||||
|
.agp_2_:
|
||||||
|
test al, 100b
|
||||||
|
jnz .100b
|
||||||
|
|
||||||
|
test al, 10b
|
||||||
|
jnz .010b
|
||||||
|
|
||||||
|
test al, 1b
|
||||||
|
jz .error
|
||||||
|
|
||||||
|
.001b:
|
||||||
|
mov [cmd], 001b
|
||||||
|
mov esi, msg1
|
||||||
|
call SysMsgBoardStr
|
||||||
|
jmp .agp_go
|
||||||
|
|
||||||
|
.010b:
|
||||||
|
mov [cmd], 010b
|
||||||
|
mov esi, msg2
|
||||||
|
call SysMsgBoardStr
|
||||||
|
jmp .agp_go
|
||||||
|
|
||||||
|
.100b:
|
||||||
|
mov [cmd], 100b
|
||||||
|
mov esi, msg4
|
||||||
|
call SysMsgBoardStr
|
||||||
|
jmp .agp_go
|
||||||
|
|
||||||
|
.agp_2m:
|
||||||
|
mov esi, msgAGP2m
|
||||||
|
call SysMsgBoardStr
|
||||||
|
jmp .agp_2_
|
||||||
|
|
||||||
|
.agp_3:
|
||||||
|
mov esi, msgAGP3
|
||||||
|
call SysMsgBoardStr
|
||||||
|
|
||||||
|
stdcall PciRead32, [bus], [devfn], edi ; read AGP status
|
||||||
|
test al, 1 shl 3
|
||||||
|
jz .agp_2m
|
||||||
|
|
||||||
|
test eax, 10b
|
||||||
|
jnz .8x
|
||||||
|
mov [cmd], 01b
|
||||||
|
mov esi, msg4
|
||||||
|
call SysMsgBoardStr
|
||||||
|
jmp .agp_go
|
||||||
|
|
||||||
|
.8x:
|
||||||
|
mov [cmd], 10b
|
||||||
|
mov esi, msg8
|
||||||
|
call SysMsgBoardStr
|
||||||
|
|
||||||
|
.agp_go:
|
||||||
|
|
||||||
|
if FAST_WRITE
|
||||||
|
test ax, 1 shl 4
|
||||||
|
jz @f
|
||||||
|
or [cmd], 1 shl 4
|
||||||
|
mov esi, msgfast
|
||||||
|
call SysMsgBoardStr
|
||||||
|
@@:
|
||||||
|
end if
|
||||||
|
|
||||||
|
test ax, 1 shl 9 ; Side band addressing
|
||||||
|
jz @f
|
||||||
|
or [cmd], 1 shl 9
|
||||||
|
mov esi, msgside
|
||||||
|
call SysMsgBoardStr
|
||||||
|
@@:
|
||||||
|
|
||||||
|
add edi, 4
|
||||||
|
mov eax, [cmd]
|
||||||
|
or eax, 1 shl 8 ; enable AGP
|
||||||
|
stdcall PciWrite32, [bus], [devfn], edi, eax ; write AGP cmd
|
||||||
|
|
||||||
|
mov esi, msgOK
|
||||||
|
call SysMsgBoardStr
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
endp
|
||||||
|
|
||||||
|
|
||||||
|
; initialized data
|
||||||
|
|
||||||
|
align 4
|
||||||
|
version dd (5 shl 16) or (API_VERSION and 0xFFFF)
|
||||||
|
|
||||||
|
my_service db 'AGP', 0 ; max 16 chars include zero
|
||||||
|
|
||||||
|
msgInit db 'AGP driver loaded.', 13, 10, 0
|
||||||
|
msgSearch db 'Searching for AGP card...', 13, 10, 0
|
||||||
|
msgFail db 'device not found', 13, 10, 0
|
||||||
|
msgOK db 'AGP device enabled', 13, 10, 0
|
||||||
|
msgAGP2 db 'AGP2 device found', 13, 10, 0
|
||||||
|
msgAGP3 db 'AGP3 device found', 13, 10, 0
|
||||||
|
msgAGP2m db 'Running in AGP2 mode', 13, 10, 0
|
||||||
|
msg8 db '8x speed', 13, 10, 0
|
||||||
|
msg4 db '4x speed', 13, 10, 0
|
||||||
|
msg2 db '2x speed', 13, 10, 0
|
||||||
|
msg1 db '1x speed', 13, 10, 0
|
||||||
|
msgfast db 'Fast Write', 13, 10, 0
|
||||||
|
msgside db 'Side band addressing', 13, 10, 0
|
||||||
|
|
||||||
|
section '.data' data readable writable align 16
|
||||||
|
|
||||||
|
; uninitialized data
|
||||||
|
|
||||||
|
revision db ?
|
||||||
|
cmd dd ?
|
||||||
|
bus dd ?
|
||||||
|
devfn dd ?
|
||||||
|
|
350
kernel/branches/Kolibri-acpi/drivers/apm.asm
Normal file
350
kernel/branches/Kolibri-acpi/drivers/apm.asm
Normal file
@ -0,0 +1,350 @@
|
|||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;; ;;
|
||||||
|
;; Copyright (C) KolibriOS team 2009-2011. All rights reserved. ;;
|
||||||
|
;; Distributed under terms of the GNU General Public License ;;
|
||||||
|
;; ;;
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
; 11.09.2009 staper@inbox.ru
|
||||||
|
; see kernel\docs\apm.txt
|
||||||
|
|
||||||
|
use32
|
||||||
|
|
||||||
|
org 0x0
|
||||||
|
|
||||||
|
db 'MENUET01'
|
||||||
|
dd 0x1
|
||||||
|
dd START
|
||||||
|
dd I_END
|
||||||
|
dd (I_END+100) and not 3
|
||||||
|
dd (I_END+100) and not 3
|
||||||
|
dd 0x0,0x0
|
||||||
|
|
||||||
|
include 'macros.inc'
|
||||||
|
|
||||||
|
START:
|
||||||
|
mcall 40,0x7
|
||||||
|
|
||||||
|
mcall 49,0x0001,0x0001,0x5308 ;CX = FFFFh APM v1.0
|
||||||
|
; mcall 49,0x0001,0x0001,0x530d
|
||||||
|
; mcall 49,0x0001,0x0001,0x530f
|
||||||
|
|
||||||
|
; mcall 49,0x0000,,0x5310 ;bl - number of batteries
|
||||||
|
redraw:
|
||||||
|
mcall 49,0x0000,,0x530c
|
||||||
|
dec cl
|
||||||
|
jz still
|
||||||
|
mcall 49,0x0001,0x0001,0x5308
|
||||||
|
mcall 49,0x01ff,,0x530c
|
||||||
|
test cl, cl
|
||||||
|
jz @f
|
||||||
|
mcall 49,0x0000,0x0001,0x530d
|
||||||
|
mcall 49,0x0000,0x0000,0x5307
|
||||||
|
mcall 49,0x0000,0x0001,0x5308
|
||||||
|
@@:
|
||||||
|
mcall 12,1
|
||||||
|
mcall 0,100*65536+235,100*65536+90,0x34ffffff,0x000000,title
|
||||||
|
mcall 49,0x0000,,0x5300
|
||||||
|
jnc @f
|
||||||
|
mcall 4,10*65536+3,0x80000000,text.4
|
||||||
|
bts [flags], 1
|
||||||
|
jmp .end
|
||||||
|
@@:
|
||||||
|
cmp al, 0
|
||||||
|
jne @f
|
||||||
|
mov edx, text.1
|
||||||
|
jmp .0
|
||||||
|
@@:
|
||||||
|
cmp al, 1
|
||||||
|
jne @f
|
||||||
|
mov edx, text.2
|
||||||
|
jmp .0
|
||||||
|
@@:
|
||||||
|
mov edx, text.3
|
||||||
|
.0:
|
||||||
|
push edx
|
||||||
|
mcall 4,169*65536+3,0x80dddddd,text.0
|
||||||
|
pop edx
|
||||||
|
add ebx, 47*65536
|
||||||
|
mcall
|
||||||
|
mcall 49,0x0001,,0x530a
|
||||||
|
jc .error
|
||||||
|
push si dx cx bx ;time of battery life, b. flag, b. status, AC line status
|
||||||
|
|
||||||
|
;AC line status
|
||||||
|
cmp bh, 0
|
||||||
|
jne @f
|
||||||
|
mov edx, text.01
|
||||||
|
jmp .1
|
||||||
|
@@:
|
||||||
|
cmp bh, 1
|
||||||
|
jne @f
|
||||||
|
mov edx, text.02
|
||||||
|
jmp .1
|
||||||
|
@@:
|
||||||
|
cmp bh, 2
|
||||||
|
jne @f
|
||||||
|
mov edx, text.03
|
||||||
|
jmp .1
|
||||||
|
@@:
|
||||||
|
mov edx, text.04
|
||||||
|
.1:
|
||||||
|
push edx
|
||||||
|
mcall 4,10*65536+10,0x80000000,text.00
|
||||||
|
pop edx
|
||||||
|
mcall ,100*65536+10,;0x80000000
|
||||||
|
|
||||||
|
;battery status
|
||||||
|
pop bx
|
||||||
|
cmp bl, 0
|
||||||
|
jne @f
|
||||||
|
mov edx, text.11
|
||||||
|
jmp .2
|
||||||
|
@@:
|
||||||
|
cmp bl, 1
|
||||||
|
jne @f
|
||||||
|
mov edx, text.12
|
||||||
|
jmp .2
|
||||||
|
@@:
|
||||||
|
cmp bl, 2
|
||||||
|
jne @f
|
||||||
|
mov edx, text.13
|
||||||
|
jmp .2
|
||||||
|
@@:
|
||||||
|
cmp bl, 3
|
||||||
|
jne @f
|
||||||
|
mov edx, text.14
|
||||||
|
jmp .2
|
||||||
|
@@:
|
||||||
|
mov edx, text.04
|
||||||
|
.2:
|
||||||
|
push edx
|
||||||
|
mcall 4,10*65536+20,0x80000000,text.10
|
||||||
|
pop edx
|
||||||
|
mcall ,100*65536+20,
|
||||||
|
|
||||||
|
;battery life, percentage and minutes/seconds
|
||||||
|
mcall ,10*65536+30,,text.20
|
||||||
|
pop cx
|
||||||
|
cmp cl, 0xff
|
||||||
|
jne @f
|
||||||
|
mcall ,100*65536+30,0x80000000,text.04
|
||||||
|
pop eax
|
||||||
|
jmp .end
|
||||||
|
@@:
|
||||||
|
shl ecx, 24
|
||||||
|
shr ecx, 24
|
||||||
|
mcall 47,0x80030000,,100*65536+30,0x347636
|
||||||
|
.3:
|
||||||
|
mcall 4,115*65536+30,0x80000000,text.15
|
||||||
|
mov dx, [esp]
|
||||||
|
shl edx, 17
|
||||||
|
shr edx, 17
|
||||||
|
mov ecx, edx
|
||||||
|
mcall 47,0x80030000,,140*65536+30
|
||||||
|
pop cx
|
||||||
|
mov edx, text.21
|
||||||
|
bt cx, 15
|
||||||
|
jc @f
|
||||||
|
mov edx, text.22
|
||||||
|
@@:
|
||||||
|
mcall 4,160*65536+30,0x80000000
|
||||||
|
pop si
|
||||||
|
.error:
|
||||||
|
.end:
|
||||||
|
;buttons
|
||||||
|
mcall 8,148*65536+16,45*65536+15,3,0x00677ab0
|
||||||
|
mcall ,166*65536+16,,4,
|
||||||
|
mcall ,184*65536+16,,5,
|
||||||
|
mcall ,202*65536+16,,6,
|
||||||
|
bt [flags], 1
|
||||||
|
jc @f
|
||||||
|
mcall ,65*65536+45,,2,
|
||||||
|
@@:
|
||||||
|
mcall 4,10*65536+50,0x80564242,text.30
|
||||||
|
mcall 12,2
|
||||||
|
|
||||||
|
still:
|
||||||
|
; mcall 10
|
||||||
|
mcall 23,12000
|
||||||
|
test eax, eax
|
||||||
|
jz redraw
|
||||||
|
|
||||||
|
dec al
|
||||||
|
jz redraw
|
||||||
|
dec al
|
||||||
|
jz key
|
||||||
|
dec al
|
||||||
|
jz button
|
||||||
|
jmp still
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
key:
|
||||||
|
mcall 2
|
||||||
|
jmp still
|
||||||
|
|
||||||
|
button:
|
||||||
|
mcall 17
|
||||||
|
cmp ah, 1
|
||||||
|
jne @f
|
||||||
|
mcall -1
|
||||||
|
|
||||||
|
@@:
|
||||||
|
cmp ah, 2
|
||||||
|
jne @f
|
||||||
|
mcall 5,50
|
||||||
|
mcall 49,0x0001,0x0001,0x5307
|
||||||
|
jmp redraw
|
||||||
|
|
||||||
|
@@:
|
||||||
|
cmp ah, 4
|
||||||
|
jg @f
|
||||||
|
mov edx, 0x01f7 ;primary chan.
|
||||||
|
call reserv_ports
|
||||||
|
jc redraw
|
||||||
|
sub bh, 3
|
||||||
|
.1:
|
||||||
|
call set_drive
|
||||||
|
btc [flags], 2
|
||||||
|
jnc .2
|
||||||
|
call device_reset
|
||||||
|
jmp .3
|
||||||
|
.2:
|
||||||
|
call standby_hdd
|
||||||
|
.3:
|
||||||
|
call free_ports
|
||||||
|
jmp redraw
|
||||||
|
|
||||||
|
@@:
|
||||||
|
cmp ah, 6
|
||||||
|
jg redraw
|
||||||
|
mov edx, 0x0177 ;secondary chan.
|
||||||
|
call reserv_ports
|
||||||
|
jc redraw
|
||||||
|
sub bh, 5
|
||||||
|
jmp .1
|
||||||
|
|
||||||
|
set_drive:
|
||||||
|
dec dx
|
||||||
|
in al, dx
|
||||||
|
test bh, bh
|
||||||
|
jnz @f
|
||||||
|
btr ax, 4
|
||||||
|
.1:
|
||||||
|
out dx, al
|
||||||
|
inc dx
|
||||||
|
ret
|
||||||
|
@@:
|
||||||
|
bts ax, 4
|
||||||
|
jmp .1
|
||||||
|
|
||||||
|
|
||||||
|
standby_hdd:
|
||||||
|
; 94h E0h nondata standby immediate
|
||||||
|
; 95h E1h nondata idle immediate
|
||||||
|
; 96h E2h nondata standby
|
||||||
|
; 97h E3h nondata idle
|
||||||
|
; 98h E5h nondata check power mode
|
||||||
|
; 99h E6h nondata set sleep mode
|
||||||
|
xor ecx, ecx
|
||||||
|
@@:
|
||||||
|
in al, dx
|
||||||
|
dec cx
|
||||||
|
jz @f
|
||||||
|
bt ax, 6
|
||||||
|
jnc @b
|
||||||
|
mov al, 0x96
|
||||||
|
out dx, al
|
||||||
|
mov al, 0xe2
|
||||||
|
out dx, al
|
||||||
|
@@:
|
||||||
|
ret
|
||||||
|
|
||||||
|
reserv_ports:
|
||||||
|
mov ecx, edx
|
||||||
|
dec ecx
|
||||||
|
push ax
|
||||||
|
mcall 46,0
|
||||||
|
test al, al
|
||||||
|
jnz @f
|
||||||
|
pop bx
|
||||||
|
clc
|
||||||
|
ret
|
||||||
|
@@:
|
||||||
|
pop bx
|
||||||
|
stc
|
||||||
|
ret
|
||||||
|
|
||||||
|
device_reset:
|
||||||
|
xor ecx, ecx
|
||||||
|
@@:
|
||||||
|
in al, dx
|
||||||
|
dec cx
|
||||||
|
jz @f
|
||||||
|
bt ax, 6
|
||||||
|
jnc @b
|
||||||
|
mov al, 0x10
|
||||||
|
out dx, al
|
||||||
|
@@:
|
||||||
|
ret
|
||||||
|
|
||||||
|
free_ports:
|
||||||
|
mov ecx, edx
|
||||||
|
dec ecx
|
||||||
|
mcall 46,1
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
; ДАННЫЕ ПРОГРАММЫ
|
||||||
|
title db '',0
|
||||||
|
flags dw 0
|
||||||
|
|
||||||
|
text:
|
||||||
|
.0:
|
||||||
|
db 'APM v.1.',0
|
||||||
|
.1:
|
||||||
|
db '0',0
|
||||||
|
.2:
|
||||||
|
db '1',0
|
||||||
|
.3:
|
||||||
|
db '2',0
|
||||||
|
.4:
|
||||||
|
db 'APM not supported',0
|
||||||
|
|
||||||
|
.00:
|
||||||
|
db 'power status:',0
|
||||||
|
.01:
|
||||||
|
db 'off-line',0
|
||||||
|
.02:
|
||||||
|
db 'on-line',0
|
||||||
|
.03:
|
||||||
|
db 'on backup power',0
|
||||||
|
.04:
|
||||||
|
db 'unknown',0
|
||||||
|
|
||||||
|
.10:
|
||||||
|
db 'battery flag:',0
|
||||||
|
.11:
|
||||||
|
db 'high',0
|
||||||
|
.12:
|
||||||
|
db 'low',0
|
||||||
|
.13:
|
||||||
|
db 'critical',0
|
||||||
|
.14:
|
||||||
|
db 'charging',0
|
||||||
|
.15:
|
||||||
|
db ' % ,',0
|
||||||
|
|
||||||
|
.20:
|
||||||
|
db 'battery life:',0
|
||||||
|
.21:
|
||||||
|
db 'min',0
|
||||||
|
.22:
|
||||||
|
db 'sec',0
|
||||||
|
|
||||||
|
.30:
|
||||||
|
db 'STAND-BY: SYSTEM HDD: 0 1 2 3',0
|
||||||
|
|
||||||
|
I_END:
|
453
kernel/branches/Kolibri-acpi/drivers/fdo.inc
Normal file
453
kernel/branches/Kolibri-acpi/drivers/fdo.inc
Normal file
@ -0,0 +1,453 @@
|
|||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;; ;;
|
||||||
|
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
|
||||||
|
;; Distributed under terms of the GNU General Public License ;;
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
_esp equ esp
|
||||||
|
|
||||||
|
;
|
||||||
|
; Formatted Debug Output (FDO)
|
||||||
|
; Copyright (c) 2005-2006, mike.dld
|
||||||
|
; Created: 2005-01-29, Changed: 2006-11-10
|
||||||
|
;
|
||||||
|
; For questions and bug reports, mail to mike.dld@gmail.com
|
||||||
|
;
|
||||||
|
; Available format specifiers are: %s, %d, %u, %x (with partial width support)
|
||||||
|
;
|
||||||
|
|
||||||
|
; to be defined:
|
||||||
|
; __DEBUG__ equ 1
|
||||||
|
; __DEBUG_LEVEL__ equ 5
|
||||||
|
|
||||||
|
; MOV Immediate.
|
||||||
|
; Useful for things like movi eax,10:
|
||||||
|
; shorter than regular mov, but slightly slower,
|
||||||
|
; do not use it in performance-critical places.
|
||||||
|
macro movi dst, imm
|
||||||
|
{
|
||||||
|
if imm >= -0x80 & imm <= 0x7F
|
||||||
|
push imm
|
||||||
|
pop dst
|
||||||
|
else
|
||||||
|
mov dst, imm
|
||||||
|
end if
|
||||||
|
}
|
||||||
|
|
||||||
|
macro debug_func name {
|
||||||
|
if used name
|
||||||
|
name@of@func equ name
|
||||||
|
}
|
||||||
|
|
||||||
|
macro debug_beginf {
|
||||||
|
align 4
|
||||||
|
name@of@func:
|
||||||
|
}
|
||||||
|
|
||||||
|
debug_endf fix end if
|
||||||
|
|
||||||
|
macro DEBUGS _sign,[_str] {
|
||||||
|
common
|
||||||
|
local tp
|
||||||
|
tp equ 0
|
||||||
|
match _arg:_num,_str \{
|
||||||
|
DEBUGS_N _sign,_num,_arg
|
||||||
|
tp equ 1
|
||||||
|
\}
|
||||||
|
match =0 _arg,tp _str \{
|
||||||
|
DEBUGS_N _sign,,_arg
|
||||||
|
\}
|
||||||
|
}
|
||||||
|
|
||||||
|
macro DEBUGS_N _sign,_num,[_str] {
|
||||||
|
common
|
||||||
|
pushf
|
||||||
|
pushad
|
||||||
|
local ..str,..label,is_str
|
||||||
|
is_str = 0
|
||||||
|
forward
|
||||||
|
if _str eqtype ''
|
||||||
|
is_str = 1
|
||||||
|
end if
|
||||||
|
common
|
||||||
|
if is_str = 1
|
||||||
|
jmp ..label
|
||||||
|
..str db _str,0
|
||||||
|
..label:
|
||||||
|
mov edx, ..str
|
||||||
|
else
|
||||||
|
esp equ esp+4*8+4
|
||||||
|
mov edx, _str
|
||||||
|
esp equ _esp
|
||||||
|
end if
|
||||||
|
if ~_num eq
|
||||||
|
if _num eqtype eax
|
||||||
|
if _num in <eax,ebx,ecx,edx,edi,ebp,esp>
|
||||||
|
mov esi, _num
|
||||||
|
else if ~_num eq esi
|
||||||
|
movzx esi, _num
|
||||||
|
end if
|
||||||
|
else if _num eqtype 0
|
||||||
|
mov esi, _num
|
||||||
|
else
|
||||||
|
local tp
|
||||||
|
tp equ 0
|
||||||
|
match [_arg],_num \{
|
||||||
|
mov esi, dword[_arg]
|
||||||
|
tp equ 1
|
||||||
|
\}
|
||||||
|
match =0 =dword[_arg],tp _num \{
|
||||||
|
mov esi, dword[_arg]
|
||||||
|
tp equ 1
|
||||||
|
\}
|
||||||
|
match =0 =word[_arg],tp _num \{
|
||||||
|
movzx esi, word[_arg]
|
||||||
|
tp equ 1
|
||||||
|
\}
|
||||||
|
match =0 =byte[_arg],tp _num \{
|
||||||
|
movzx esi, byte[_arg]
|
||||||
|
tp equ 1
|
||||||
|
\}
|
||||||
|
match =0,tp \{
|
||||||
|
'Error: specified string width is incorrect'
|
||||||
|
\}
|
||||||
|
end if
|
||||||
|
else
|
||||||
|
mov esi, 0x7FFFFFFF
|
||||||
|
end if
|
||||||
|
call fdo_debug_outstr
|
||||||
|
popad
|
||||||
|
popf
|
||||||
|
}
|
||||||
|
|
||||||
|
macro DEBUGD _sign,_dec {
|
||||||
|
local tp
|
||||||
|
tp equ 0
|
||||||
|
match _arg:_num,_dec \{
|
||||||
|
DEBUGD_N _sign,_num,_arg
|
||||||
|
tp equ 1
|
||||||
|
\}
|
||||||
|
match =0 _arg,tp _dec \{
|
||||||
|
DEBUGD_N _sign,,_arg
|
||||||
|
\}
|
||||||
|
}
|
||||||
|
|
||||||
|
macro DEBUGD_N _sign,_num,_dec {
|
||||||
|
pushf
|
||||||
|
pushad
|
||||||
|
if (~_num eq)
|
||||||
|
if (_dec eqtype eax | _dec eqtype 0)
|
||||||
|
'Error: precision allowed only for in-memory variables'
|
||||||
|
end if
|
||||||
|
if (~_num in <1,2,4>)
|
||||||
|
if _sign
|
||||||
|
'Error: 1, 2 and 4 are only allowed for precision in %d'
|
||||||
|
else
|
||||||
|
'Error: 1, 2 and 4 are only allowed for precision in %u'
|
||||||
|
end if
|
||||||
|
end if
|
||||||
|
end if
|
||||||
|
if _dec eqtype eax
|
||||||
|
if _dec in <ebx,ecx,edx,esi,edi,ebp,esp>
|
||||||
|
mov eax, _dec
|
||||||
|
else if ~_dec eq eax
|
||||||
|
if _sign = 1
|
||||||
|
movsx eax, _dec
|
||||||
|
else
|
||||||
|
movzx eax, _dec
|
||||||
|
end if
|
||||||
|
end if
|
||||||
|
else if _dec eqtype 0
|
||||||
|
mov eax, _dec
|
||||||
|
else
|
||||||
|
esp equ esp+4*8+4
|
||||||
|
if _num eq
|
||||||
|
mov eax, dword _dec
|
||||||
|
else if _num = 1
|
||||||
|
if _sign = 1
|
||||||
|
movsx eax, byte _dec
|
||||||
|
else
|
||||||
|
movzx eax, byte _dec
|
||||||
|
end if
|
||||||
|
else if _num = 2
|
||||||
|
if _sign = 1
|
||||||
|
movsx eax, word _dec
|
||||||
|
else
|
||||||
|
movzx eax, word _dec
|
||||||
|
end if
|
||||||
|
else
|
||||||
|
mov eax, dword _dec
|
||||||
|
end if
|
||||||
|
esp equ _esp
|
||||||
|
end if
|
||||||
|
mov cl, _sign
|
||||||
|
call fdo_debug_outdec
|
||||||
|
popad
|
||||||
|
popf
|
||||||
|
}
|
||||||
|
|
||||||
|
macro DEBUGH _sign,_hex {
|
||||||
|
local tp
|
||||||
|
tp equ 0
|
||||||
|
match _arg:_num,_hex \{
|
||||||
|
DEBUGH_N _sign,_num,_arg
|
||||||
|
tp equ 1
|
||||||
|
\}
|
||||||
|
match =0 _arg,tp _hex \{
|
||||||
|
DEBUGH_N _sign,,_arg
|
||||||
|
\}
|
||||||
|
}
|
||||||
|
|
||||||
|
macro DEBUGH_N _sign,_num,_hex {
|
||||||
|
pushf
|
||||||
|
pushad
|
||||||
|
if (~_num eq) & (~_num in <1,2,3,4,5,6,7,8>)
|
||||||
|
'Error: 1..8 are only allowed for precision in %x'
|
||||||
|
end if
|
||||||
|
if _hex eqtype eax
|
||||||
|
if _hex in <eax,ebx,ecx,edx,esi,edi,ebp,esp>
|
||||||
|
if ~_hex eq eax
|
||||||
|
mov eax, _hex
|
||||||
|
end if
|
||||||
|
mov edx, 8
|
||||||
|
else if _hex in <ax,bx,cx,dx,si,di,bp,sp>
|
||||||
|
if ~_hex eq ax
|
||||||
|
movzx eax, _hex
|
||||||
|
end if
|
||||||
|
if (_num eq)
|
||||||
|
mov edx, 4
|
||||||
|
end if
|
||||||
|
else if _hex in <al,ah,bl,bh,cl,ch,dl,dh>
|
||||||
|
if ~_hex eq al
|
||||||
|
movzx eax, _hex
|
||||||
|
end if
|
||||||
|
if (_num eq)
|
||||||
|
mov edx, 2
|
||||||
|
end if
|
||||||
|
end if
|
||||||
|
else if _hex eqtype 0
|
||||||
|
mov eax, _hex
|
||||||
|
else
|
||||||
|
esp equ esp+4*8+4
|
||||||
|
mov eax, dword _hex
|
||||||
|
esp equ _esp
|
||||||
|
end if
|
||||||
|
if ~_num eq
|
||||||
|
mov edx, _num
|
||||||
|
else
|
||||||
|
if ~_hex eqtype eax
|
||||||
|
mov edx, 8
|
||||||
|
end if
|
||||||
|
end if
|
||||||
|
call fdo_debug_outhex
|
||||||
|
popad
|
||||||
|
popf
|
||||||
|
}
|
||||||
|
|
||||||
|
;-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
debug_func fdo_debug_outchar
|
||||||
|
debug_beginf
|
||||||
|
pushad
|
||||||
|
movzx ecx, al
|
||||||
|
mov ebx, 1
|
||||||
|
; mov ecx,sys_msg_board
|
||||||
|
; call ecx ; sys_msg_board
|
||||||
|
stdcall SysMsgBoard
|
||||||
|
popad
|
||||||
|
ret
|
||||||
|
debug_endf
|
||||||
|
|
||||||
|
debug_func fdo_debug_outstr
|
||||||
|
debug_beginf
|
||||||
|
mov ebx, 1
|
||||||
|
.l1:
|
||||||
|
dec esi
|
||||||
|
js .l2
|
||||||
|
movzx ecx, byte[edx]
|
||||||
|
or cl, cl
|
||||||
|
jz .l2
|
||||||
|
; mov ecx,sys_msg_board
|
||||||
|
; call ecx ; sys_msg_board
|
||||||
|
stdcall SysMsgBoard
|
||||||
|
inc edx
|
||||||
|
jmp .l1
|
||||||
|
.l2:
|
||||||
|
ret
|
||||||
|
debug_endf
|
||||||
|
|
||||||
|
debug_func fdo_debug_outdec
|
||||||
|
debug_beginf
|
||||||
|
or cl, cl
|
||||||
|
jz @f
|
||||||
|
or eax, eax
|
||||||
|
jns @f
|
||||||
|
neg eax
|
||||||
|
push eax
|
||||||
|
mov al, '-'
|
||||||
|
call fdo_debug_outchar
|
||||||
|
pop eax
|
||||||
|
@@:
|
||||||
|
movi ecx, 10
|
||||||
|
push -'0'
|
||||||
|
.l1:
|
||||||
|
xor edx, edx
|
||||||
|
div ecx
|
||||||
|
push edx
|
||||||
|
test eax, eax
|
||||||
|
jnz .l1
|
||||||
|
.l2:
|
||||||
|
pop eax
|
||||||
|
add al, '0'
|
||||||
|
jz .l3
|
||||||
|
call fdo_debug_outchar
|
||||||
|
jmp .l2
|
||||||
|
.l3:
|
||||||
|
ret
|
||||||
|
debug_endf
|
||||||
|
|
||||||
|
debug_func fdo_debug_outhex
|
||||||
|
__fdo_hexdigits db '0123456789ABCDEF'
|
||||||
|
debug_beginf
|
||||||
|
mov cl, dl
|
||||||
|
neg cl
|
||||||
|
add cl, 8
|
||||||
|
shl cl, 2
|
||||||
|
rol eax, cl
|
||||||
|
.l1:
|
||||||
|
rol eax, 4
|
||||||
|
push eax
|
||||||
|
and eax, 0x0000000F
|
||||||
|
mov al, [__fdo_hexdigits+eax]
|
||||||
|
call fdo_debug_outchar
|
||||||
|
pop eax
|
||||||
|
dec edx
|
||||||
|
jnz .l1
|
||||||
|
ret
|
||||||
|
debug_endf
|
||||||
|
|
||||||
|
;-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
macro DEBUGF _level,_format,[_arg] {
|
||||||
|
common
|
||||||
|
if __DEBUG__ = 1 & _level >= __DEBUG_LEVEL__
|
||||||
|
local ..f1,f2,a1,a2,c1,c2,c3,..lbl
|
||||||
|
_debug_str_ equ __debug_str_ # a1
|
||||||
|
a1 = 0
|
||||||
|
c2 = 0
|
||||||
|
c3 = 0
|
||||||
|
f2 = 0
|
||||||
|
repeat ..lbl-..f1
|
||||||
|
virtual at 0
|
||||||
|
db _format,0,0
|
||||||
|
load c1 word from %-1
|
||||||
|
end virtual
|
||||||
|
if c1 = '%s'
|
||||||
|
virtual at 0
|
||||||
|
db _format,0,0
|
||||||
|
store word 0 at %-1
|
||||||
|
load c1 from f2-c2
|
||||||
|
end virtual
|
||||||
|
if c1 <> 0
|
||||||
|
DEBUGS 0,_debug_str_+f2-c2
|
||||||
|
end if
|
||||||
|
c2 = c2 + 1
|
||||||
|
f2 = %+1
|
||||||
|
DEBUGF_HELPER S,a1,0,_arg
|
||||||
|
else if c1 = '%x'
|
||||||
|
virtual at 0
|
||||||
|
db _format,0,0
|
||||||
|
store word 0 at %-1
|
||||||
|
load c1 from f2-c2
|
||||||
|
end virtual
|
||||||
|
if c1 <> 0
|
||||||
|
DEBUGS 0,_debug_str_+f2-c2
|
||||||
|
end if
|
||||||
|
c2 = c2 + 1
|
||||||
|
f2 = %+1
|
||||||
|
DEBUGF_HELPER H,a1,0,_arg
|
||||||
|
else if c1 = '%d' | c1 = '%u'
|
||||||
|
local c4
|
||||||
|
if c1 = '%d'
|
||||||
|
c4 = 1
|
||||||
|
else
|
||||||
|
c4 = 0
|
||||||
|
end if
|
||||||
|
virtual at 0
|
||||||
|
db _format,0,0
|
||||||
|
store word 0 at %-1
|
||||||
|
load c1 from f2-c2
|
||||||
|
end virtual
|
||||||
|
if c1 <> 0
|
||||||
|
DEBUGS 0,_debug_str_+f2-c2
|
||||||
|
end if
|
||||||
|
c2 = c2 + 1
|
||||||
|
f2 = %+1
|
||||||
|
DEBUGF_HELPER D,a1,c4,_arg
|
||||||
|
else if c1 = '\n'
|
||||||
|
c3 = c3 + 1
|
||||||
|
end if
|
||||||
|
end repeat
|
||||||
|
virtual at 0
|
||||||
|
db _format,0,0
|
||||||
|
load c1 from f2-c2
|
||||||
|
end virtual
|
||||||
|
if (c1<>0)&(f2<>..lbl-..f1-1)
|
||||||
|
DEBUGS 0,_debug_str_+f2-c2
|
||||||
|
end if
|
||||||
|
virtual at 0
|
||||||
|
..f1 db _format,0
|
||||||
|
..lbl:
|
||||||
|
__debug_strings equ __debug_strings,_debug_str_,<_format>,..lbl-..f1-1-c2-c3
|
||||||
|
end virtual
|
||||||
|
end if
|
||||||
|
}
|
||||||
|
|
||||||
|
macro __include_debug_strings dummy,[_id,_fmt,_len] {
|
||||||
|
common
|
||||||
|
local c1,a1,a2
|
||||||
|
forward
|
||||||
|
if defined _len & ~_len eq
|
||||||
|
_id:
|
||||||
|
a1 = 0
|
||||||
|
a2 = 0
|
||||||
|
repeat _len
|
||||||
|
virtual at 0
|
||||||
|
db _fmt,0,0
|
||||||
|
load c1 word from %+a2-1
|
||||||
|
end virtual
|
||||||
|
if (c1='%s')|(c1='%x')|(c1='%d')|(c1='%u')
|
||||||
|
db 0
|
||||||
|
a2 = a2 + 1
|
||||||
|
else if (c1='\n')
|
||||||
|
dw $0A0D
|
||||||
|
a1 = a1 + 1
|
||||||
|
a2 = a2 + 1
|
||||||
|
else
|
||||||
|
db c1 and 0x0FF
|
||||||
|
end if
|
||||||
|
end repeat
|
||||||
|
db 0
|
||||||
|
end if
|
||||||
|
}
|
||||||
|
|
||||||
|
macro DEBUGF_HELPER _letter,_num,_sign,[_arg] {
|
||||||
|
common
|
||||||
|
local num
|
||||||
|
num = 0
|
||||||
|
forward
|
||||||
|
if num = _num
|
||||||
|
DEBUG#_letter _sign,_arg
|
||||||
|
end if
|
||||||
|
num = num+1
|
||||||
|
common
|
||||||
|
_num = _num+1
|
||||||
|
}
|
||||||
|
|
||||||
|
macro include_debug_strings {
|
||||||
|
if __DEBUG__ = 1
|
||||||
|
match dbg_str,__debug_strings \{
|
||||||
|
__include_debug_strings dbg_str
|
||||||
|
\}
|
||||||
|
end if
|
||||||
|
}
|
@ -1,121 +0,0 @@
|
|||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;; ;;
|
|
||||||
;; Copyright (C) KolibriOS team 2007-2011. All rights reserved. ;;
|
|
||||||
;; Distributed under terms of the GNU General Public License ;;
|
|
||||||
;; ;;
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
|
|
||||||
struc URB
|
|
||||||
{
|
|
||||||
.fd dd ?
|
|
||||||
.bk dd ?
|
|
||||||
.dev dd ? ; pointer to associated device
|
|
||||||
.pipe dd ? ; pipe information
|
|
||||||
.status dd ? ; non-ISO status
|
|
||||||
.transfer_flags dd ? ; URB_SHORT_NOT_OK | ...
|
|
||||||
.transfer_buffer dd ? ; associated data buffer
|
|
||||||
.transfer_dma dd ? ; dma addr for transfer_buffer
|
|
||||||
.transfer_buffer_length dd ? ; data buffer length
|
|
||||||
.actual_length dd ? ; actual transfer length
|
|
||||||
.setup_packet dd ? ; setup packet (control only)
|
|
||||||
.setup_dma dd ? ; dma addr for setup_packet
|
|
||||||
.start_frame dd ? ; start frame (ISO)
|
|
||||||
.number_of_packets dd ? ; number of ISO packets
|
|
||||||
.interval dd ? ; transfer interval
|
|
||||||
|
|
||||||
.error_count dd ? ; number of ISO errors
|
|
||||||
.context dd ? ; context for completion
|
|
||||||
.complete dd ? ; (in) completion routine
|
|
||||||
.iso_frame_desc:
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual at 0
|
|
||||||
URB URB
|
|
||||||
end virtual
|
|
||||||
|
|
||||||
|
|
||||||
struc REQ ;usb request
|
|
||||||
{
|
|
||||||
.request_type db ?
|
|
||||||
.request db ?
|
|
||||||
.value dw ?
|
|
||||||
.index dw ?
|
|
||||||
.length dw ?
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual at 0
|
|
||||||
REQ REQ
|
|
||||||
end virtual
|
|
||||||
|
|
||||||
align 4
|
|
||||||
proc usb_control_msg stdcall, dev:dword, pipe:dword, request:dword,\
|
|
||||||
requesttype:dword, value:dword, index:dword,\
|
|
||||||
data:dword, size:dword, timeout:dword
|
|
||||||
|
|
||||||
locals
|
|
||||||
req REQ
|
|
||||||
endl
|
|
||||||
|
|
||||||
lea eax, [req]
|
|
||||||
mov ecx, [request]
|
|
||||||
mov ebx, [requesttupe]
|
|
||||||
mov edx, [value]
|
|
||||||
mov esi, [index]
|
|
||||||
mov edi, [size]
|
|
||||||
|
|
||||||
mov [eax+REQ.request_type], bl
|
|
||||||
mov [eax+REQ.request], cl
|
|
||||||
mov [eax+REQ.value], dx
|
|
||||||
mov [eax+REQ.index], si
|
|
||||||
mov [eax+REQ.length], di
|
|
||||||
|
|
||||||
stdcall usb_internal_control_msg, [dev], [pipe], \
|
|
||||||
eax, [data], [size], [timeout]
|
|
||||||
|
|
||||||
ret
|
|
||||||
endp
|
|
||||||
|
|
||||||
|
|
||||||
; returns status (negative) or length (positive)
|
|
||||||
static int usb_internal_control_msg(struct usb_device *usb_dev,
|
|
||||||
unsigned int pipe,
|
|
||||||
struct usb_ctrlrequest *cmd,
|
|
||||||
void *data, int len, int timeout)
|
|
||||||
{
|
|
||||||
struct urb *urb;
|
|
||||||
int retv;
|
|
||||||
int length;
|
|
||||||
|
|
||||||
urb = usb_alloc_urb(0, GFP_NOIO);
|
|
||||||
if (!urb)
|
|
||||||
return -ENOMEM;
|
|
||||||
usb_fill_control_urb(urb, usb_dev, pipe, (unsigned char *)cmd, data,
|
|
||||||
len, usb_api_blocking_completion, NULL);
|
|
||||||
|
|
||||||
retv = usb_start_wait_urb(urb, timeout, &length);
|
|
||||||
if (retv < 0)
|
|
||||||
return retv;
|
|
||||||
else
|
|
||||||
return length;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
;void usb_fill_control_urb (struct urb *urb,
|
|
||||||
; struct usb_device *dev,
|
|
||||||
; unsigned int pipe,
|
|
||||||
; unsigned char *setup_packet,
|
|
||||||
; void *transfer_buffer,
|
|
||||||
; int buffer_length,
|
|
||||||
; usb_complete_t complete_fn,
|
|
||||||
; void *context)
|
|
||||||
;{
|
|
||||||
;
|
|
||||||
; urb->dev = dev;
|
|
||||||
; urb->pipe = pipe;
|
|
||||||
; urb->setup_packet = setup_packet;
|
|
||||||
; urb->transfer_buffer = transfer_buffer;
|
|
||||||
; urb->transfer_buffer_length = buffer_length;
|
|
||||||
; urb->complete = complete_fn;
|
|
||||||
; urb->context = context;
|
|
||||||
;}
|
|
||||||
;
|
|
@ -1,435 +0,0 @@
|
|||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;; ;;
|
|
||||||
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;;
|
|
||||||
;; Distributed under terms of the GNU General Public License ;;
|
|
||||||
;; ;;
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
|
|
||||||
;driver sceletone
|
|
||||||
|
|
||||||
format MS COFF
|
|
||||||
|
|
||||||
API_VERSION equ 0 ;debug
|
|
||||||
|
|
||||||
include '../proc32.inc'
|
|
||||||
include '../imports.inc'
|
|
||||||
include 'urb.inc'
|
|
||||||
|
|
||||||
struc UHCI
|
|
||||||
{
|
|
||||||
.bus dd ?
|
|
||||||
.devfn dd ?
|
|
||||||
.io_base dd ?
|
|
||||||
.mm_base dd ?
|
|
||||||
.irq dd ?
|
|
||||||
.flags dd ?
|
|
||||||
.reset dd ?
|
|
||||||
.start dd ?
|
|
||||||
.stop dd ?
|
|
||||||
|
|
||||||
.port_c_suspend dd ?
|
|
||||||
.resuming_ports dd ?
|
|
||||||
.rh_state dd ?
|
|
||||||
.rh_numports dd ?
|
|
||||||
.is_stopped dd ?
|
|
||||||
.dead dd ?
|
|
||||||
|
|
||||||
.sizeof:
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual at 0
|
|
||||||
UHCI UHCI
|
|
||||||
end virtual
|
|
||||||
|
|
||||||
struc IOCTL
|
|
||||||
{ .handle dd ?
|
|
||||||
.io_code dd ?
|
|
||||||
.input dd ?
|
|
||||||
.inp_size dd ?
|
|
||||||
.output dd ?
|
|
||||||
.out_size dd ?
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual at 0
|
|
||||||
IOCTL IOCTL
|
|
||||||
end virtual
|
|
||||||
|
|
||||||
struc TD ;transfer descriptor
|
|
||||||
{
|
|
||||||
.link dd ?
|
|
||||||
.status dd ?
|
|
||||||
.token dd ?
|
|
||||||
.buffer dd ?
|
|
||||||
|
|
||||||
.addr dd ?
|
|
||||||
.frame dd ?
|
|
||||||
.fd dd ?
|
|
||||||
.bk dd ?
|
|
||||||
.sizeof:
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual at 0
|
|
||||||
TD TD
|
|
||||||
end virtual
|
|
||||||
|
|
||||||
public START
|
|
||||||
public service_proc
|
|
||||||
public version
|
|
||||||
|
|
||||||
DEBUG equ 1
|
|
||||||
|
|
||||||
DRV_ENTRY equ 1
|
|
||||||
DRV_EXIT equ -1
|
|
||||||
STRIDE equ 4 ;size of row in devices table
|
|
||||||
|
|
||||||
SRV_GETVERSION equ 0
|
|
||||||
|
|
||||||
section '.flat' code readable align 16
|
|
||||||
|
|
||||||
proc START stdcall, state:dword
|
|
||||||
|
|
||||||
cmp [state], 1
|
|
||||||
jne .exit
|
|
||||||
.entry:
|
|
||||||
|
|
||||||
if DEBUG
|
|
||||||
mov esi, msgInit
|
|
||||||
call SysMsgBoardStr
|
|
||||||
end if
|
|
||||||
|
|
||||||
call init
|
|
||||||
|
|
||||||
stdcall RegService, my_service, service_proc
|
|
||||||
ret
|
|
||||||
.fail:
|
|
||||||
.exit:
|
|
||||||
xor eax, eax
|
|
||||||
ret
|
|
||||||
endp
|
|
||||||
|
|
||||||
handle equ IOCTL.handle
|
|
||||||
io_code equ IOCTL.io_code
|
|
||||||
input equ IOCTL.input
|
|
||||||
inp_size equ IOCTL.inp_size
|
|
||||||
output equ IOCTL.output
|
|
||||||
out_size equ IOCTL.out_size
|
|
||||||
|
|
||||||
align 4
|
|
||||||
proc service_proc stdcall, ioctl:dword
|
|
||||||
|
|
||||||
mov ebx, [ioctl]
|
|
||||||
mov eax, [ebx+io_code]
|
|
||||||
cmp eax, SRV_GETVERSION
|
|
||||||
jne @F
|
|
||||||
|
|
||||||
mov eax, [ebx+output]
|
|
||||||
cmp [ebx+out_size], 4
|
|
||||||
jne .fail
|
|
||||||
mov [eax], dword API_VERSION
|
|
||||||
xor eax, eax
|
|
||||||
ret
|
|
||||||
@@:
|
|
||||||
.fail:
|
|
||||||
or eax, -1
|
|
||||||
ret
|
|
||||||
endp
|
|
||||||
|
|
||||||
restore handle
|
|
||||||
restore io_code
|
|
||||||
restore input
|
|
||||||
restore inp_size
|
|
||||||
restore output
|
|
||||||
restore out_size
|
|
||||||
|
|
||||||
align 4
|
|
||||||
proc detect
|
|
||||||
locals
|
|
||||||
last_bus dd ?
|
|
||||||
bus dd ?
|
|
||||||
devfn dd ?
|
|
||||||
endl
|
|
||||||
|
|
||||||
xor eax, eax
|
|
||||||
mov [bus], eax
|
|
||||||
inc eax
|
|
||||||
call PciApi
|
|
||||||
cmp eax, -1
|
|
||||||
je .err
|
|
||||||
|
|
||||||
mov [last_bus], eax
|
|
||||||
|
|
||||||
.next_bus:
|
|
||||||
and [devfn], 0
|
|
||||||
.next_dev:
|
|
||||||
stdcall PciRead32, [bus], [devfn], dword 0
|
|
||||||
test eax, eax
|
|
||||||
jz .next
|
|
||||||
cmp eax, -1
|
|
||||||
je .next
|
|
||||||
|
|
||||||
mov edi, devices
|
|
||||||
@@:
|
|
||||||
mov ebx, [edi]
|
|
||||||
test ebx, ebx
|
|
||||||
jz .next
|
|
||||||
|
|
||||||
cmp eax, ebx
|
|
||||||
je .found
|
|
||||||
|
|
||||||
add edi, STRIDE
|
|
||||||
jmp @B
|
|
||||||
.next:
|
|
||||||
inc [devfn]
|
|
||||||
cmp [devfn], 256
|
|
||||||
jb .next_dev
|
|
||||||
mov eax, [bus]
|
|
||||||
inc eax
|
|
||||||
mov [bus], eax
|
|
||||||
cmp eax, [last_bus]
|
|
||||||
jna .next_bus
|
|
||||||
xor eax, eax
|
|
||||||
ret
|
|
||||||
.found:
|
|
||||||
mov eax, UHCI.sizeof
|
|
||||||
call Kmalloc
|
|
||||||
test eax, eax
|
|
||||||
jz .mem_fail
|
|
||||||
|
|
||||||
mov ebx, [bus]
|
|
||||||
mov [eax+UHCI.bus], ebx
|
|
||||||
|
|
||||||
mov ecx, [devfn]
|
|
||||||
mov [eax+UHCI.devfn], ecx
|
|
||||||
ret
|
|
||||||
.mem_fail:
|
|
||||||
if DEBUG
|
|
||||||
mov esi, msgMemFail
|
|
||||||
call SysMsgBoardStr
|
|
||||||
end if
|
|
||||||
.err:
|
|
||||||
xor eax, eax
|
|
||||||
ret
|
|
||||||
endp
|
|
||||||
|
|
||||||
PCI_BASE equ 0x20
|
|
||||||
USB_LEGKEY equ 0xC0
|
|
||||||
|
|
||||||
align 4
|
|
||||||
proc init
|
|
||||||
locals
|
|
||||||
uhci dd ?
|
|
||||||
endl
|
|
||||||
|
|
||||||
call detect
|
|
||||||
test eax, eax
|
|
||||||
jz .fail
|
|
||||||
|
|
||||||
mov [uhci], eax
|
|
||||||
|
|
||||||
stdcall PciRead32, [eax+UHCI.bus], [eax+UHCI.devfn], PCI_BASE
|
|
||||||
and eax, 0xFFC0
|
|
||||||
mov esi, [uhci]
|
|
||||||
mov [esi+UHCI.io_base], eax
|
|
||||||
|
|
||||||
stdcall uhci_reset, esi
|
|
||||||
|
|
||||||
stdcall finish_reset, [uhci]
|
|
||||||
|
|
||||||
.fail:
|
|
||||||
if DEBUG
|
|
||||||
mov esi, msgDevNotFound
|
|
||||||
call SysMsgBoardStr
|
|
||||||
end if
|
|
||||||
ret
|
|
||||||
endp
|
|
||||||
|
|
||||||
UHCI_USBINTR equ 4 ; interrupt register
|
|
||||||
|
|
||||||
UHCI_USBLEGSUP_RWC equ 0x8f00 ; the R/WC bits
|
|
||||||
UHCI_USBLEGSUP_RO equ 0x5040 ; R/O and reserved bits
|
|
||||||
|
|
||||||
UHCI_USBCMD_RUN equ 0x0001 ; RUN/STOP bit
|
|
||||||
UHCI_USBCMD_HCRESET equ 0x0002 ; Host Controller reset
|
|
||||||
UHCI_USBCMD_EGSM equ 0x0008 ; Global Suspend Mode
|
|
||||||
UHCI_USBCMD_CONFIGURE equ 0x0040 ; Config Flag
|
|
||||||
UHCI_USBINTR_RESUME equ 0x0002 ; Resume interrupt enable
|
|
||||||
|
|
||||||
PORTSC0 equ 0x10
|
|
||||||
PORTSC1 equ 0x12
|
|
||||||
|
|
||||||
|
|
||||||
UHCI_RH_RESET equ 0
|
|
||||||
UHCI_RH_SUSPENDED equ 1
|
|
||||||
UHCI_RH_AUTO_STOPPED equ 2
|
|
||||||
UHCI_RH_RESUMING equ 3
|
|
||||||
|
|
||||||
; In this state the HC changes from running to halted
|
|
||||||
; so it can legally appear either way.
|
|
||||||
UHCI_RH_SUSPENDING equ 4
|
|
||||||
|
|
||||||
; In the following states it's an error if the HC is halted.
|
|
||||||
; These two must come last.
|
|
||||||
UHCI_RH_RUNNING equ 5 ; The normal state
|
|
||||||
UHCI_RH_RUNNING_NODEVS equ 6 ; Running with no devices
|
|
||||||
|
|
||||||
UHCI_IS_STOPPED equ 9999
|
|
||||||
|
|
||||||
align 4
|
|
||||||
proc uhci_reset stdcall, uhci:dword
|
|
||||||
mov esi, [uhci]
|
|
||||||
stdcall PciRead16, [esi+UHCI.bus], [esi+UHCI.devfn], USB_LEGKEY
|
|
||||||
test eax, not (UHCI_USBLEGSUP_RO or UHCI_USBLEGSUP_RWC)
|
|
||||||
jnz .reset
|
|
||||||
|
|
||||||
mov edx, [esi+UHCI.io_base]
|
|
||||||
in ax, dx
|
|
||||||
test ax, UHCI_USBCMD_RUN
|
|
||||||
jnz .reset
|
|
||||||
|
|
||||||
test ax, UHCI_USBCMD_CONFIGURE
|
|
||||||
jz .reset
|
|
||||||
|
|
||||||
test ax, UHCI_USBCMD_EGSM
|
|
||||||
jz .reset
|
|
||||||
|
|
||||||
add edx, UHCI_USBINTR
|
|
||||||
in ax, dx
|
|
||||||
test ax, not UHCI_USBINTR_RESUME
|
|
||||||
jnz .reset
|
|
||||||
ret
|
|
||||||
.reset:
|
|
||||||
stdcall PciWrite16, [esi+UHCI.bus], [esi+UHCI.devfn], USB_LEGKEY, UHCI_USBLEGSUP_RWC
|
|
||||||
|
|
||||||
mov edx, [esi+UHCI.io_base]
|
|
||||||
mov ax, UHCI_USBCMD_HCRESET
|
|
||||||
out dx, ax
|
|
||||||
|
|
||||||
xor eax, eax
|
|
||||||
out dx, ax
|
|
||||||
add edx, UHCI_USBINTR
|
|
||||||
out dx, ax
|
|
||||||
ret
|
|
||||||
endp
|
|
||||||
|
|
||||||
proc finish_reset stdcall, uhci:dword
|
|
||||||
|
|
||||||
mov esi, [uhci]
|
|
||||||
mov edx, [esi+UHCI.io_base]
|
|
||||||
add edx, PORTSC0
|
|
||||||
xor eax, eax
|
|
||||||
out dx, ax
|
|
||||||
add edx, (PORTSC1-PORTSC0)
|
|
||||||
out dx, ax
|
|
||||||
|
|
||||||
mov [esi+UHCI.port_c_suspend], eax
|
|
||||||
mov [esi+UHCI.resuming_ports], eax
|
|
||||||
mov [esi+UHCI.rh_state], UHCI_RH_RESET
|
|
||||||
mov [esi+UHCI.rh_numports], 2
|
|
||||||
|
|
||||||
mov [esi+UHCI.is_stopped], UHCI_IS_STOPPED
|
|
||||||
; mov [ uhci_to_hcd(uhci)->state = HC_STATE_HALT;
|
|
||||||
; uhci_to_hcd(uhci)->poll_rh = 0;
|
|
||||||
|
|
||||||
mov [esi+UHCI.dead], eax ; Full reset resurrects the controller
|
|
||||||
|
|
||||||
ret
|
|
||||||
endp
|
|
||||||
|
|
||||||
proc insert_td stdcall, td:dword, frame:dword
|
|
||||||
|
|
||||||
mov edi, [td]
|
|
||||||
mov eax, [frame]
|
|
||||||
and eax, -1024
|
|
||||||
mov [edi+TD.frame], eax
|
|
||||||
|
|
||||||
mov ebx, [framelist]
|
|
||||||
mov edx, [dma_framelist]
|
|
||||||
shl eax, 5
|
|
||||||
|
|
||||||
mov ecx, [eax+ebx]
|
|
||||||
test ecx, ecx
|
|
||||||
jz .empty
|
|
||||||
|
|
||||||
mov ecx, [ecx+TD.bk] ;last TD
|
|
||||||
|
|
||||||
mov edx, [ecx+TD.fd]
|
|
||||||
mov [edi+TD.fd], edx
|
|
||||||
mov [edi+TD.bk], ecx
|
|
||||||
mov [ecx+TD.fd], edi
|
|
||||||
mov [edx+TD.bk], edi
|
|
||||||
|
|
||||||
mov eax, [ecx+TD.link]
|
|
||||||
mov [edi+TD.link], eax
|
|
||||||
mov ebx, [edi+TD.addr]
|
|
||||||
mov [ecx+TD.link], ebx
|
|
||||||
ret
|
|
||||||
.empty:
|
|
||||||
mov ecx, [eax+edx]
|
|
||||||
mov [edi+TD.link], ecx
|
|
||||||
mov [ebx+eax], edi
|
|
||||||
mov ecx, [edi+TD.addr]
|
|
||||||
mov [eax+edx], ecx
|
|
||||||
ret
|
|
||||||
endp
|
|
||||||
|
|
||||||
|
|
||||||
align 4
|
|
||||||
proc usb_get_descriptor stdcall, dev:dword, type:dword, index:dword,\
|
|
||||||
buf:dword, size:dword
|
|
||||||
|
|
||||||
locals
|
|
||||||
count dd ?
|
|
||||||
endl
|
|
||||||
|
|
||||||
mov esi, [buf]
|
|
||||||
mov ecx, [size]
|
|
||||||
xor eax, eax
|
|
||||||
cld
|
|
||||||
rep stosb
|
|
||||||
|
|
||||||
mov [count], 3
|
|
||||||
@@:
|
|
||||||
mov eax, [type]
|
|
||||||
shl eax, 8
|
|
||||||
add eax, [index]
|
|
||||||
stdcall usb_control_msg, [dev], pipe, USB_REQ_GET_DESCRIPTOR, \
|
|
||||||
USB_DIR_IN, eax,0,[buf], [size],\
|
|
||||||
USB_CTRL_GET_TIMEOUT
|
|
||||||
test eax, eax
|
|
||||||
jz .next
|
|
||||||
cmp eax, -1
|
|
||||||
je .next
|
|
||||||
jmp. ok
|
|
||||||
.next:
|
|
||||||
dec [count]
|
|
||||||
jnz @B
|
|
||||||
mov eax, -1
|
|
||||||
.ok:
|
|
||||||
ret
|
|
||||||
endp
|
|
||||||
|
|
||||||
DEVICE_ID equ 0x24D2 ; pci device id
|
|
||||||
VENDOR_ID equ 0x8086 ; device vendor id
|
|
||||||
QEMU_USB equ 0x7020
|
|
||||||
|
|
||||||
;all initialized data place here
|
|
||||||
|
|
||||||
align 4
|
|
||||||
devices dd (DEVICE_ID shl 16)+VENDOR_ID
|
|
||||||
dd (QEMU_USB shl 16)+VENDOR_ID
|
|
||||||
dd 0 ;terminator
|
|
||||||
|
|
||||||
version dd (5 shl 16) or (API_VERSION and 0xFFFF)
|
|
||||||
|
|
||||||
my_service db 'UHCI',0 ;max 16 chars include zero
|
|
||||||
|
|
||||||
msgInit db 'detect hardware...',13,10,0
|
|
||||||
msgPCI db 'PCI accsess not supported',13,10,0
|
|
||||||
msgDevNotFound db 'device not found',13,10,0
|
|
||||||
msgMemFail db 'Kmalloc failed', 10,10,0
|
|
||||||
;msgFail db 'device not found',13,10,0
|
|
||||||
|
|
||||||
section '.data' data readable writable align 16
|
|
||||||
|
|
||||||
;all uninitialized data place here
|
|
||||||
|
|
@ -1,693 +0,0 @@
|
|||||||
; standard driver stuff
|
|
||||||
format MS COFF
|
|
||||||
|
|
||||||
DEBUG = 1
|
|
||||||
|
|
||||||
; this is for DEBUGF macro from 'fdo.inc'
|
|
||||||
__DEBUG__ = 1
|
|
||||||
__DEBUG_LEVEL__ = 1
|
|
||||||
|
|
||||||
include 'proc32.inc'
|
|
||||||
include 'imports.inc'
|
|
||||||
include 'fdo.inc'
|
|
||||||
|
|
||||||
public START
|
|
||||||
public version
|
|
||||||
|
|
||||||
; USB constants
|
|
||||||
DEVICE_DESCR_TYPE = 1
|
|
||||||
CONFIG_DESCR_TYPE = 2
|
|
||||||
STRING_DESCR_TYPE = 3
|
|
||||||
INTERFACE_DESCR_TYPE = 4
|
|
||||||
ENDPOINT_DESCR_TYPE = 5
|
|
||||||
DEVICE_QUALIFIER_DESCR_TYPE = 6
|
|
||||||
|
|
||||||
CONTROL_PIPE = 0
|
|
||||||
ISOCHRONOUS_PIPE = 1
|
|
||||||
BULK_PIPE = 2
|
|
||||||
INTERRUPT_PIPE = 3
|
|
||||||
|
|
||||||
; USB structures
|
|
||||||
virtual at 0
|
|
||||||
config_descr:
|
|
||||||
.bLength db ?
|
|
||||||
.bDescriptorType db ?
|
|
||||||
.wTotalLength dw ?
|
|
||||||
.bNumInterfaces db ?
|
|
||||||
.bConfigurationValue db ?
|
|
||||||
.iConfiguration db ?
|
|
||||||
.bmAttributes db ?
|
|
||||||
.bMaxPower db ?
|
|
||||||
.sizeof:
|
|
||||||
end virtual
|
|
||||||
|
|
||||||
virtual at 0
|
|
||||||
interface_descr:
|
|
||||||
.bLength db ?
|
|
||||||
.bDescriptorType db ?
|
|
||||||
.bInterfaceNumber db ?
|
|
||||||
.bAlternateSetting db ?
|
|
||||||
.bNumEndpoints db ?
|
|
||||||
.bInterfaceClass db ?
|
|
||||||
.bInterfaceSubClass db ?
|
|
||||||
.bInterfaceProtocol db ?
|
|
||||||
.iInterface db ?
|
|
||||||
.sizeof:
|
|
||||||
end virtual
|
|
||||||
|
|
||||||
virtual at 0
|
|
||||||
endpoint_descr:
|
|
||||||
.bLength db ?
|
|
||||||
.bDescriptorType db ?
|
|
||||||
.bEndpointAddress db ?
|
|
||||||
.bmAttributes db ?
|
|
||||||
.wMaxPacketSize dw ?
|
|
||||||
.bInterval db ?
|
|
||||||
.sizeof:
|
|
||||||
end virtual
|
|
||||||
|
|
||||||
; Driver data for all devices
|
|
||||||
virtual at 0
|
|
||||||
device_data:
|
|
||||||
.type dd ? ; 1 = keyboard, 2 = mouse
|
|
||||||
.intpipe dd ? ; interrupt pipe handle
|
|
||||||
.packetsize dd ?
|
|
||||||
.packet rb 8 ; packet with data from device
|
|
||||||
.control rb 8 ; control packet to device
|
|
||||||
.sizeof:
|
|
||||||
end virtual
|
|
||||||
|
|
||||||
; Driver data for mouse
|
|
||||||
virtual at device_data.sizeof
|
|
||||||
mouse_data:
|
|
||||||
; no additional data
|
|
||||||
.sizeof:
|
|
||||||
end virtual
|
|
||||||
|
|
||||||
; Driver data for keyboard
|
|
||||||
virtual at device_data.sizeof
|
|
||||||
keyboard_data:
|
|
||||||
.handle dd ? ; keyboard handle from RegKeyboard
|
|
||||||
.configpipe dd ? ; config pipe handle
|
|
||||||
.prevpacket rb 8 ; previous packet with data from device
|
|
||||||
.timer dd ? ; auto-repeat timer handle
|
|
||||||
.repeatkey db ? ; auto-repeat key code
|
|
||||||
.ledstate db ? ; state of LEDs
|
|
||||||
align 4
|
|
||||||
.sizeof:
|
|
||||||
end virtual
|
|
||||||
|
|
||||||
section '.flat' code readable align 16
|
|
||||||
; The start procedure.
|
|
||||||
START:
|
|
||||||
; 1. Test whether the procedure is called with the argument DRV_ENTRY.
|
|
||||||
; If not, return 0.
|
|
||||||
xor eax, eax ; initialize return value
|
|
||||||
cmp dword [esp+4], 1 ; compare the argument
|
|
||||||
jnz .nothing
|
|
||||||
; 2. Register self as a USB driver.
|
|
||||||
; The name is my_driver = 'usbhid'; IOCTL interface is not supported;
|
|
||||||
; usb_functions is an offset of a structure with callback functions.
|
|
||||||
stdcall RegUSBDriver, my_driver, eax, usb_functions
|
|
||||||
; 3. Return the returned value of RegUSBDriver.
|
|
||||||
.nothing:
|
|
||||||
ret 4
|
|
||||||
|
|
||||||
; This procedure is called when new HID device is detected.
|
|
||||||
; It initializes the device.
|
|
||||||
AddDevice:
|
|
||||||
; Arguments are addressed through esp. In this point of the function,
|
|
||||||
; [esp+4] = a handle of the config pipe, [esp+8] points to config_descr
|
|
||||||
; structure, [esp+12] points to interface_descr structure.
|
|
||||||
; 1. Check device type. Currently only mice and keyboards with
|
|
||||||
; boot protocol are supported.
|
|
||||||
; 1a. Get the subclass and the protocol. Since bInterfaceSubClass and
|
|
||||||
; bInterfaceProtocol are subsequent in interface_descr, just one
|
|
||||||
; memory reference is used for both.
|
|
||||||
mov edx, [esp+12]
|
|
||||||
push ebx ; save used register to be stdcall
|
|
||||||
mov cx, word [edx+interface_descr.bInterfaceSubClass]
|
|
||||||
; 1b. For boot protocol, subclass must be 1 and protocol must be either 1 for
|
|
||||||
; a keyboard or 2 for a mouse. Check.
|
|
||||||
cmp cx, 0x0101
|
|
||||||
jz .keyboard
|
|
||||||
cmp cx, 0x0201
|
|
||||||
jz .mouse
|
|
||||||
; 1c. If the device is neither a keyboard nor a mouse, print a message and
|
|
||||||
; go to 6c.
|
|
||||||
DEBUGF 1,'K : unknown HID device\n'
|
|
||||||
jmp .nothing
|
|
||||||
; 1d. If the device is a keyboard or a mouse, print a message and continue
|
|
||||||
; configuring.
|
|
||||||
.keyboard:
|
|
||||||
DEBUGF 1,'K : USB keyboard detected\n'
|
|
||||||
push keyboard_data.sizeof
|
|
||||||
jmp .common
|
|
||||||
.mouse:
|
|
||||||
DEBUGF 1,'K : USB mouse detected\n'
|
|
||||||
push mouse_data.sizeof
|
|
||||||
.common:
|
|
||||||
; 2. Allocate memory for device data.
|
|
||||||
pop eax ; get size of device data
|
|
||||||
; 2a. Call the kernel, saving and restoring register edx.
|
|
||||||
push edx
|
|
||||||
call Kmalloc
|
|
||||||
pop edx
|
|
||||||
; 2b. Check result. If failed, say a message and go to 6c.
|
|
||||||
test eax, eax
|
|
||||||
jnz @f
|
|
||||||
DEBUGF 1,'K : no memory\n'
|
|
||||||
jmp .nothing
|
|
||||||
@@:
|
|
||||||
xchg eax, ebx
|
|
||||||
; HID devices use one IN interrupt endpoint for polling the device
|
|
||||||
; and an optional OUT interrupt endpoint. We do not use the later,
|
|
||||||
; but must locate the first. Look for the IN interrupt endpoint.
|
|
||||||
; 3. Get the upper bound of all descriptors' data.
|
|
||||||
mov eax, [esp+8+4] ; configuration descriptor
|
|
||||||
movzx ecx, [eax+config_descr.wTotalLength]
|
|
||||||
add eax, ecx
|
|
||||||
; 4. Loop over all descriptors until
|
|
||||||
; either end-of-data reached - this is fail
|
|
||||||
; or interface descriptor found - this is fail, all further data
|
|
||||||
; correspond to that interface
|
|
||||||
; or endpoint descriptor found.
|
|
||||||
; 4a. Loop start: eax points to the interface descriptor.
|
|
||||||
.lookep:
|
|
||||||
; 4b. Get next descriptor.
|
|
||||||
movzx ecx, byte [edx] ; the first byte of all descriptors is length
|
|
||||||
add edx, ecx
|
|
||||||
; 4c. Check that at least two bytes are readable. The opposite is an error.
|
|
||||||
inc edx
|
|
||||||
cmp edx, eax
|
|
||||||
jae .errorep
|
|
||||||
dec edx
|
|
||||||
; 4d. Check that this descriptor is not interface descriptor. The opposite is
|
|
||||||
; an error.
|
|
||||||
cmp byte [edx+endpoint_descr.bDescriptorType], INTERFACE_DESCR_TYPE
|
|
||||||
jz .errorep
|
|
||||||
; 4e. Test whether this descriptor is an endpoint descriptor. If not, continue
|
|
||||||
; the loop.
|
|
||||||
cmp byte [edx+endpoint_descr.bDescriptorType], ENDPOINT_DESCR_TYPE
|
|
||||||
jnz .lookep
|
|
||||||
; 5. Check that the descriptor contains all required data and all data are
|
|
||||||
; readable. If so, proceed to 7.
|
|
||||||
cmp byte [edx+endpoint_descr.bLength], endpoint_descr.sizeof
|
|
||||||
jb .errorep
|
|
||||||
sub eax, endpoint_descr.sizeof
|
|
||||||
cmp edx, eax
|
|
||||||
jbe @f
|
|
||||||
; 6. An error occured during processing endpoint descriptor.
|
|
||||||
.errorep:
|
|
||||||
; 6a. Print a message.
|
|
||||||
DEBUGF 1,'K : error: invalid endpoint descriptor\n'
|
|
||||||
; 6b. Free memory allocated for device data.
|
|
||||||
.free:
|
|
||||||
xchg eax, ebx
|
|
||||||
call Kfree
|
|
||||||
.nothing:
|
|
||||||
; 6c. Return an error.
|
|
||||||
xor eax, eax
|
|
||||||
pop ebx
|
|
||||||
ret 12
|
|
||||||
@@:
|
|
||||||
; 7. Check that the endpoint is IN interrupt endpoint. If not, go to 6.
|
|
||||||
test [edx+endpoint_descr.bEndpointAddress], 80h
|
|
||||||
jz .errorep
|
|
||||||
mov cl, [edx+endpoint_descr.bmAttributes]
|
|
||||||
and cl, 3
|
|
||||||
cmp cl, INTERRUPT_PIPE
|
|
||||||
jnz .errorep
|
|
||||||
; 8. Open pipe for the endpoint.
|
|
||||||
; 8a. Load parameters from the descriptor.
|
|
||||||
movzx ecx, [edx+endpoint_descr.bEndpointAddress]
|
|
||||||
movzx eax, [edx+endpoint_descr.bInterval]
|
|
||||||
movzx edx, [edx+endpoint_descr.wMaxPacketSize]
|
|
||||||
; 8b. Call the kernel, saving and restoring edx.
|
|
||||||
push edx
|
|
||||||
stdcall USBOpenPipe, [esp+4+24], ecx, edx, INTERRUPT_PIPE, eax
|
|
||||||
pop edx
|
|
||||||
; 8c. Check result. If failed, go to 6b.
|
|
||||||
test eax, eax
|
|
||||||
jz .free
|
|
||||||
; We use 12 bytes for device type, interrupt pipe and interrupt packet size,
|
|
||||||
; 8 bytes for a packet and 8 bytes for previous packet, used by a keyboard.
|
|
||||||
; 9. Initialize device data.
|
|
||||||
mov [ebx+device_data.intpipe], eax
|
|
||||||
movi ecx, 8
|
|
||||||
cmp edx, ecx
|
|
||||||
jb @f
|
|
||||||
mov edx, ecx
|
|
||||||
@@:
|
|
||||||
xor eax, eax
|
|
||||||
mov [ebx+device_data.packetsize], edx
|
|
||||||
mov dword [ebx+device_data.packet], eax
|
|
||||||
mov dword [ebx+device_data.packet+4], eax
|
|
||||||
mov edx, [esp+12+4] ; interface descriptor
|
|
||||||
movzx ecx, [edx+interface_descr.bInterfaceProtocol]
|
|
||||||
mov [ebx+device_data.type], ecx
|
|
||||||
cmp ecx, 1
|
|
||||||
jnz @f
|
|
||||||
mov [ebx+keyboard_data.handle], eax
|
|
||||||
mov [ebx+keyboard_data.timer], eax
|
|
||||||
mov [ebx+keyboard_data.repeatkey], al
|
|
||||||
mov dword [ebx+keyboard_data.prevpacket], eax
|
|
||||||
mov dword [ebx+keyboard_data.prevpacket+4], eax
|
|
||||||
mov eax, [esp+4+4]
|
|
||||||
mov [ebx+keyboard_data.configpipe], eax
|
|
||||||
@@:
|
|
||||||
; 10. Send the control packet SET_PROTOCOL(Boot Protocol) to the interface.
|
|
||||||
lea eax, [ebx+device_data.control]
|
|
||||||
mov dword [eax], 21h + (0Bh shl 8) + (0 shl 16) ; class request to interface + SET_PROTOCOL + Boot protocol
|
|
||||||
and dword [eax+4], 0
|
|
||||||
mov dl, [edx+interface_descr.bInterfaceNumber]
|
|
||||||
mov [eax+4], dl
|
|
||||||
; Callback function is mouse_configured for mice and keyboard_configured1 for keyboards.
|
|
||||||
mov edx, keyboard_configured1
|
|
||||||
cmp ecx, 1
|
|
||||||
jz @f
|
|
||||||
mov edx, mouse_configured
|
|
||||||
@@:
|
|
||||||
stdcall USBControlTransferAsync, [esp+4+28], eax, 0, 0, edx, ebx, 0
|
|
||||||
; 11. Return with pointer to device data as returned value.
|
|
||||||
xchg eax, ebx
|
|
||||||
pop ebx
|
|
||||||
ret 12
|
|
||||||
|
|
||||||
; This function is called when SET_PROTOCOL command for keyboard is done,
|
|
||||||
; either successful or unsuccessful.
|
|
||||||
keyboard_configured1:
|
|
||||||
xor edx, edx
|
|
||||||
; 1. Check the status of the transfer.
|
|
||||||
; If the transfer was failed, go to the common error handler.
|
|
||||||
cmp dword [esp+8], edx ; status is zero?
|
|
||||||
jnz keyboard_data_ready.error
|
|
||||||
; 2. Send the control packet SET_IDLE(infinity). HID auto-repeat is not useful.
|
|
||||||
mov eax, [esp+20]
|
|
||||||
push edx ; flags for USBControlTransferAsync
|
|
||||||
push eax ; userdata for USBControlTransferAsync
|
|
||||||
add eax, device_data.control
|
|
||||||
mov dword [eax], 21h + (0Ah shl 8) + (0 shl 24) ; class request to interface + SET_IDLE + no autorepeat
|
|
||||||
stdcall USBControlTransferAsync, dword [eax+keyboard_data.configpipe-device_data.control], \
|
|
||||||
eax, edx, edx, keyboard_configured2; , <userdata>, <flags>
|
|
||||||
; 3. Return.
|
|
||||||
ret 20
|
|
||||||
|
|
||||||
; This function is called when SET_IDLE command for keyboard is done,
|
|
||||||
; either successful or unsuccessful.
|
|
||||||
keyboard_configured2:
|
|
||||||
; Check the status of the transfer and go to the corresponding label
|
|
||||||
; in the main handler.
|
|
||||||
cmp dword [esp+8], 0
|
|
||||||
jnz keyboard_data_ready.error
|
|
||||||
mov edx, [esp+20]
|
|
||||||
push edx
|
|
||||||
stdcall RegKeyboard, usbkbd_functions, edx
|
|
||||||
pop edx
|
|
||||||
mov [edx+keyboard_data.handle], eax
|
|
||||||
jmp keyboard_data_ready.next
|
|
||||||
|
|
||||||
; This function is called when another interrupt packet arrives,
|
|
||||||
; processed either successfully or unsuccessfully.
|
|
||||||
; It should parse the packet and initiate another transfer with
|
|
||||||
; the same callback function.
|
|
||||||
keyboard_data_ready:
|
|
||||||
; 1. Check the status of the transfer.
|
|
||||||
mov eax, [esp+8]
|
|
||||||
test eax, eax
|
|
||||||
jnz .error
|
|
||||||
; Parse the packet, comparing with the previous packet.
|
|
||||||
; For boot protocol, USB keyboard packet consists of the first byte
|
|
||||||
; with status keys that are currently pressed. The second byte should
|
|
||||||
; be ignored, and other 5 bytes denote keys that are currently pressed.
|
|
||||||
push esi ebx ; save used registers to be stdcall
|
|
||||||
; 2. Process control keys.
|
|
||||||
; 2a. Initialize before loop for control keys. edx = mask for control bits
|
|
||||||
; that were changed.
|
|
||||||
mov ebx, [esp+20+8]
|
|
||||||
movzx edx, byte [ebx+device_data.packet] ; get state of control keys
|
|
||||||
xor dl, byte [ebx+keyboard_data.prevpacket] ; compare with previous state
|
|
||||||
; 2b. If state of control keys has not changed, advance to 3.
|
|
||||||
jz .nocontrol
|
|
||||||
; 2c. Otherwise, loop over control keys; esi = bit number.
|
|
||||||
xor esi, esi
|
|
||||||
.controlloop:
|
|
||||||
; 2d. Skip bits that have not changed.
|
|
||||||
bt edx, esi
|
|
||||||
jnc .controlnext
|
|
||||||
push edx ; save register which is possibly modified by API
|
|
||||||
; The state of the current control key has changed.
|
|
||||||
; 2e. For extended control keys, send the prefix 0xE0.
|
|
||||||
mov al, [control_keys+esi]
|
|
||||||
test al, al
|
|
||||||
jns @f
|
|
||||||
push eax
|
|
||||||
mov ecx, 0xE0
|
|
||||||
call SetKeyboardData
|
|
||||||
pop eax
|
|
||||||
and al, 0x7F
|
|
||||||
@@:
|
|
||||||
; 2f. If the current state of the control key is "pressed", send normal
|
|
||||||
; scancode. Otherwise, the key is released, so set the high bit in scancode.
|
|
||||||
movzx ecx, al
|
|
||||||
bt dword [ebx+device_data.packet], esi
|
|
||||||
jc @f
|
|
||||||
or cl, 0x80
|
|
||||||
@@:
|
|
||||||
call SetKeyboardData
|
|
||||||
pop edx ; restore register which was possibly modified by API
|
|
||||||
.controlnext:
|
|
||||||
; 2g. We have 8 control keys.
|
|
||||||
inc esi
|
|
||||||
cmp esi, 8
|
|
||||||
jb .controlloop
|
|
||||||
.nocontrol:
|
|
||||||
; 3. Initialize before loop for normal keys. esi = index.
|
|
||||||
movi esi, 2
|
|
||||||
.normalloop:
|
|
||||||
; 4. Process one key which was pressed in the previous packet.
|
|
||||||
; 4a. Get the next pressed key from the previous packet.
|
|
||||||
movzx eax, byte [ebx+esi+keyboard_data.prevpacket]
|
|
||||||
; 4b. Ignore special codes.
|
|
||||||
cmp al, 3
|
|
||||||
jbe .normalnext1
|
|
||||||
; 4c. Ignore keys that are still pressed in the current packet.
|
|
||||||
lea ecx, [ebx+device_data.packet]
|
|
||||||
call haskey
|
|
||||||
jz .normalnext1
|
|
||||||
; 4d. Say warning about keys with strange codes.
|
|
||||||
cmp eax, normal_keys_number
|
|
||||||
jae .badkey1
|
|
||||||
movzx ecx, [normal_keys+eax]
|
|
||||||
jecxz .badkey1
|
|
||||||
; 4e. For extended keys, send the prefix 0xE0.
|
|
||||||
push ecx ; save keycode
|
|
||||||
test cl, cl
|
|
||||||
jns @f
|
|
||||||
push ecx
|
|
||||||
mov ecx, 0xE0
|
|
||||||
call SetKeyboardData
|
|
||||||
pop ecx
|
|
||||||
@@:
|
|
||||||
; 4f. Send the release event.
|
|
||||||
or cl, 0x80
|
|
||||||
call SetKeyboardData
|
|
||||||
; 4g. If this key is autorepeating, stop the timer.
|
|
||||||
pop ecx ; restore keycode
|
|
||||||
cmp cl, [ebx+keyboard_data.repeatkey]
|
|
||||||
jnz .normalnext1
|
|
||||||
mov eax, [ebx+keyboard_data.timer]
|
|
||||||
test eax, eax
|
|
||||||
jz .normalnext1
|
|
||||||
stdcall CancelTimerHS, eax
|
|
||||||
and [ebx+keyboard_data.timer], 0
|
|
||||||
jmp .normalnext1
|
|
||||||
.badkey1:
|
|
||||||
DEBUGF 1,'K : unknown keycode: %x\n',al
|
|
||||||
.normalnext1:
|
|
||||||
; 5. Process one key which is pressed in the current packet.
|
|
||||||
; 5a. Get the next pressed key from the current packet.
|
|
||||||
movzx eax, byte [ebx+esi+device_data.packet]
|
|
||||||
; 5b. Ignore special codes.
|
|
||||||
cmp al, 3
|
|
||||||
jbe .normalnext2
|
|
||||||
; 5c. Ignore keys that were already pressed in the previous packet.
|
|
||||||
lea ecx, [ebx+keyboard_data.prevpacket]
|
|
||||||
call haskey
|
|
||||||
jz .normalnext2
|
|
||||||
; 5d. Say warning about keys with strange codes.
|
|
||||||
cmp eax, normal_keys_number
|
|
||||||
jae .badkey2
|
|
||||||
movzx ecx, [normal_keys+eax]
|
|
||||||
jecxz .badkey2
|
|
||||||
; 5e. For extended keys, send the prefix 0xE0.
|
|
||||||
push ecx ; save keycode
|
|
||||||
test cl, cl
|
|
||||||
jns @f
|
|
||||||
push ecx
|
|
||||||
mov ecx, 0xE0
|
|
||||||
call SetKeyboardData
|
|
||||||
pop ecx
|
|
||||||
@@:
|
|
||||||
; 5f. Send the press event.
|
|
||||||
and cl, not 0x80
|
|
||||||
call SetKeyboardData
|
|
||||||
; 5g. Stop the current auto-repeat timer, if present.
|
|
||||||
mov eax, [ebx+keyboard_data.timer]
|
|
||||||
test eax, eax
|
|
||||||
jz @f
|
|
||||||
stdcall CancelTimerHS, eax
|
|
||||||
@@:
|
|
||||||
; 5h. Start the auto-repeat timer.
|
|
||||||
pop ecx ; restore keycode
|
|
||||||
mov [ebx+keyboard_data.repeatkey], cl
|
|
||||||
stdcall TimerHS, 25, 5, autorepeat_timer, ebx
|
|
||||||
mov [ebx+keyboard_data.timer], eax
|
|
||||||
jmp .normalnext2
|
|
||||||
.badkey2:
|
|
||||||
DEBUGF 1,'K : unknown keycode: %x\n',al
|
|
||||||
.normalnext2:
|
|
||||||
; 6. Advance to next key.
|
|
||||||
inc esi
|
|
||||||
cmp esi, 8
|
|
||||||
jb .normalloop
|
|
||||||
; 7. Save the packet data for future reference.
|
|
||||||
mov eax, dword [ebx+device_data.packet]
|
|
||||||
mov dword [ebx+keyboard_data.prevpacket], eax
|
|
||||||
mov eax, dword [ebx+device_data.packet+4]
|
|
||||||
mov dword [ebx+keyboard_data.prevpacket+4], eax
|
|
||||||
pop ebx esi ; restore registers to be stdcall
|
|
||||||
.next:
|
|
||||||
; 8. Initiate transfer on the interrupt pipe.
|
|
||||||
mov eax, [esp+20]
|
|
||||||
push 1 ; flags for USBNormalTransferAsync
|
|
||||||
push eax ; userdata for USBNormalTransferAsync
|
|
||||||
add eax, device_data.packet
|
|
||||||
stdcall USBNormalTransferAsync, dword [eax+device_data.intpipe-device_data.packet], \
|
|
||||||
eax, dword [eax+device_data.packetsize-device_data.packet], \
|
|
||||||
keyboard_data_ready;, <userdata>, <flags>
|
|
||||||
; 9. Return.
|
|
||||||
.nothing:
|
|
||||||
ret 20
|
|
||||||
.error:
|
|
||||||
; An error has occured.
|
|
||||||
; 10. If an error is caused by the disconnect, do nothing, it is handled
|
|
||||||
; in DeviceDisconnected. Otherwise, say a message.
|
|
||||||
cmp eax, 16
|
|
||||||
jz @f
|
|
||||||
push esi
|
|
||||||
mov esi, errormsgkbd
|
|
||||||
call SysMsgBoardStr
|
|
||||||
pop esi
|
|
||||||
@@:
|
|
||||||
ret 20
|
|
||||||
|
|
||||||
; Auxiliary procedure for keyboard_data_ready.
|
|
||||||
haskey:
|
|
||||||
movi edx, 2
|
|
||||||
@@:
|
|
||||||
cmp byte [ecx+edx], al
|
|
||||||
jz @f
|
|
||||||
inc edx
|
|
||||||
cmp edx, 7
|
|
||||||
jbe @b
|
|
||||||
@@:
|
|
||||||
ret
|
|
||||||
|
|
||||||
; Timer function for auto-repeat.
|
|
||||||
autorepeat_timer:
|
|
||||||
mov eax, [esp+4]
|
|
||||||
movzx ecx, [eax+keyboard_data.repeatkey]
|
|
||||||
test cl, cl
|
|
||||||
jns @f
|
|
||||||
push ecx
|
|
||||||
mov ecx, 0xE0
|
|
||||||
call SetKeyboardData
|
|
||||||
pop ecx
|
|
||||||
and cl, not 0x80
|
|
||||||
@@:
|
|
||||||
call SetKeyboardData
|
|
||||||
ret 4
|
|
||||||
|
|
||||||
; This function is called to update LED state on the keyboard.
|
|
||||||
SetKeyboardLights:
|
|
||||||
mov eax, [esp+4]
|
|
||||||
add eax, device_data.control
|
|
||||||
mov dword [eax], 21h + (9 shl 8) + (2 shl 24)
|
|
||||||
; class request to interface + SET_REPORT + Output zero report
|
|
||||||
mov byte [eax+6], 1
|
|
||||||
mov edx, [esp+8]
|
|
||||||
shr dl, 1
|
|
||||||
jnc @f
|
|
||||||
or dl, 4
|
|
||||||
@@:
|
|
||||||
lea ecx, [eax+keyboard_data.ledstate-device_data.control]
|
|
||||||
mov [ecx], dl
|
|
||||||
stdcall USBControlTransferAsync, dword [eax+keyboard_data.configpipe-device_data.control], \
|
|
||||||
eax, ecx, 1, keyboard_data_ready.nothing, 0, 0
|
|
||||||
ret 8
|
|
||||||
|
|
||||||
; This function is called when it is safe to free keyboard data.
|
|
||||||
CloseKeyboard:
|
|
||||||
mov eax, [esp+4]
|
|
||||||
push ebx
|
|
||||||
call Kfree
|
|
||||||
pop ebx
|
|
||||||
ret 4
|
|
||||||
|
|
||||||
; This function is called when SET_PROTOCOL command for mouse is done,
|
|
||||||
; either successful or unsuccessful.
|
|
||||||
mouse_configured:
|
|
||||||
; Check the status of the transfer and go to the corresponding label
|
|
||||||
; in the main handler.
|
|
||||||
cmp dword [esp+8], 0
|
|
||||||
jnz mouse_data_ready.error
|
|
||||||
mov eax, [esp+20]
|
|
||||||
add eax, device_data.packet
|
|
||||||
jmp mouse_data_ready.next
|
|
||||||
|
|
||||||
; This function is called when another interrupt packet arrives,
|
|
||||||
; processed either successfully or unsuccessfully.
|
|
||||||
; It should parse the packet and initiate another transfer with
|
|
||||||
; the same callback function.
|
|
||||||
mouse_data_ready:
|
|
||||||
; 1. Check the status of the transfer.
|
|
||||||
mov eax, [esp+8]
|
|
||||||
test eax, eax
|
|
||||||
jnz .error
|
|
||||||
mov edx, [esp+16]
|
|
||||||
; 2. Parse the packet.
|
|
||||||
; For boot protocol, USB mouse packet consists of at least 3 bytes.
|
|
||||||
; The first byte is state of mouse buttons, the next two bytes are
|
|
||||||
; x and y movements.
|
|
||||||
; Normal mice do not distinguish between boot protocol and report protocol;
|
|
||||||
; in this case, scroll data are also present. Advanced mice, however,
|
|
||||||
; support two different protocols, boot protocol is used for compatibility
|
|
||||||
; and does not contain extended buttons or scroll data.
|
|
||||||
mov eax, [esp+12] ; buffer
|
|
||||||
push eax
|
|
||||||
xor ecx, ecx
|
|
||||||
cmp edx, 4
|
|
||||||
jbe @f
|
|
||||||
movsx ecx, byte [eax+4]
|
|
||||||
@@:
|
|
||||||
push ecx
|
|
||||||
xor ecx, ecx
|
|
||||||
cmp edx, 3
|
|
||||||
jbe @f
|
|
||||||
movsx ecx, byte [eax+3]
|
|
||||||
neg ecx
|
|
||||||
@@:
|
|
||||||
push ecx
|
|
||||||
xor ecx, ecx
|
|
||||||
cmp edx, 2
|
|
||||||
jbe @f
|
|
||||||
movsx ecx, byte [eax+2]
|
|
||||||
neg ecx
|
|
||||||
@@:
|
|
||||||
push ecx
|
|
||||||
movsx ecx, byte [eax+1]
|
|
||||||
push ecx
|
|
||||||
movzx ecx, byte [eax]
|
|
||||||
push ecx
|
|
||||||
call SetMouseData
|
|
||||||
pop eax
|
|
||||||
.next:
|
|
||||||
; 3. Initiate transfer on the interrupt pipe.
|
|
||||||
stdcall USBNormalTransferAsync, dword [eax+device_data.intpipe-device_data.packet], \
|
|
||||||
eax, dword [eax+device_data.packetsize-device_data.packet], mouse_data_ready, eax, 1
|
|
||||||
; 4. Return.
|
|
||||||
ret 20
|
|
||||||
.error:
|
|
||||||
; An error has occured.
|
|
||||||
; 5. If an error is caused by the disconnect, do nothing, it is handled
|
|
||||||
; in DeviceDisconnected. Otherwise, say a message.
|
|
||||||
cmp eax, 16
|
|
||||||
jz @f
|
|
||||||
push esi
|
|
||||||
mov esi, errormsgmouse
|
|
||||||
call SysMsgBoardStr
|
|
||||||
pop esi
|
|
||||||
@@:
|
|
||||||
ret 20
|
|
||||||
|
|
||||||
; This function is called when the device is disconnected.
|
|
||||||
DeviceDisconnected:
|
|
||||||
push ebx ; save used register to be stdcall
|
|
||||||
; 1. Say a message. Use different messages for keyboards and mice.
|
|
||||||
mov ebx, [esp+4+4]
|
|
||||||
push esi
|
|
||||||
mov esi, disconnectmsgk
|
|
||||||
cmp byte [ebx+device_data.type], 1
|
|
||||||
jz @f
|
|
||||||
mov esi, disconnectmsgm
|
|
||||||
@@:
|
|
||||||
stdcall SysMsgBoardStr
|
|
||||||
pop esi
|
|
||||||
; 2. If device is keyboard, then we must unregister it as a keyboard and
|
|
||||||
; possibly stop the auto-repeat timer.
|
|
||||||
cmp byte [ebx+device_data.type], 1
|
|
||||||
jnz .nokbd
|
|
||||||
mov eax, [ebx+keyboard_data.timer]
|
|
||||||
test eax, eax
|
|
||||||
jz @f
|
|
||||||
stdcall CancelTimerHS, eax
|
|
||||||
@@:
|
|
||||||
mov ecx, [ebx+keyboard_data.handle]
|
|
||||||
jecxz .nokbd
|
|
||||||
stdcall DelKeyboard, ecx
|
|
||||||
; If keyboard is registered, then we should free data in CloseKeyboard, not here.
|
|
||||||
jmp .nothing
|
|
||||||
.nokbd:
|
|
||||||
; 3. Free the device data.
|
|
||||||
xchg eax, ebx
|
|
||||||
call Kfree
|
|
||||||
; 4. Return.
|
|
||||||
.nothing:
|
|
||||||
pop ebx ; restore used register to be stdcall
|
|
||||||
ret 4 ; purge one dword argument to be stdcall
|
|
||||||
|
|
||||||
; strings
|
|
||||||
my_driver db 'usbhid',0
|
|
||||||
errormsgmouse db 'K : USB transfer error, disabling mouse',10,0
|
|
||||||
errormsgkbd db 'K : USB transfer error, disabling keyboard',10,0
|
|
||||||
disconnectmsgm db 'K : USB mouse disconnected',10,0
|
|
||||||
disconnectmsgk db 'K : USB keyboard disconnected',10,0
|
|
||||||
|
|
||||||
; data for keyboard: correspondence between HID usage keys and PS/2 scancodes.
|
|
||||||
EX = 80h
|
|
||||||
label control_keys byte
|
|
||||||
db 1Dh, 2Ah, 38h, 5Bh+EX, 1Dh+EX, 36h, 38h+EX, 5Ch+EX
|
|
||||||
label normal_keys byte
|
|
||||||
db 00h, 00h, 00h, 00h, 1Eh, 30h, 2Eh, 20h, 12h, 21h, 22h, 23h, 17h, 24h, 25h, 26h ; 0x
|
|
||||||
db 32h, 31h, 18h, 19h, 10h, 13h, 1Fh, 14h, 16h, 2Fh, 11h, 2Dh, 15h, 2Ch, 02h, 03h ; 1x
|
|
||||||
db 04h, 05h, 06h, 07h, 08h, 09h, 0Ah, 0Bh, 1Ch, 01h, 0Eh, 0Fh, 39h, 0Ch, 0Dh, 1Ah ; 2x
|
|
||||||
db 1Bh, 2Bh, 2Bh, 27h, 28h, 29h, 33h, 34h, 35h, 3Ah, 3Bh, 3Ch, 3Dh, 3Eh, 3Fh, 40h ; 3x
|
|
||||||
db 41h, 42h, 43h, 44h, 57h, 58h,37h+EX,46h,0,52h+EX,47h+EX,49h+EX,53h+EX,4Fh+EX,51h+EX,4Dh+EX ; 4x
|
|
||||||
db 4Bh+EX,50h+EX,48h+EX,45h,35h+EX,37h,4Ah,4Eh,1Ch+EX,4Fh,50h,51h,4Bh,4Ch,4Dh,47h ; 5x
|
|
||||||
db 48h, 49h, 52h, 53h, 56h,5Dh+EX,5Eh+EX,59h,64h,65h,66h, 67h, 68h, 69h, 6Ah, 6Bh ; 6x
|
|
||||||
db 6Ch, 6Dh, 6Eh, 76h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h ; 7x
|
|
||||||
db 00h, 00h, 00h, 00h, 00h, 7Eh, 00h, 73h, 70h, 7Dh, 79h, 7Bh, 5Ch, 00h, 00h, 00h ; 8x
|
|
||||||
db 0F2h,0F1h,78h, 77h, 76h
|
|
||||||
normal_keys_number = $ - normal_keys
|
|
||||||
|
|
||||||
; Exported variable: kernel API version.
|
|
||||||
align 4
|
|
||||||
version dd 50005h
|
|
||||||
; Structure with callback functions.
|
|
||||||
usb_functions:
|
|
||||||
dd 12
|
|
||||||
dd AddDevice
|
|
||||||
dd DeviceDisconnected
|
|
||||||
|
|
||||||
; Structure with callback functions for keyboards.
|
|
||||||
usbkbd_functions:
|
|
||||||
dd 12
|
|
||||||
dd CloseKeyboard
|
|
||||||
dd SetKeyboardLights
|
|
||||||
|
|
||||||
; for DEBUGF macro
|
|
||||||
include_debug_strings
|
|
||||||
|
|
||||||
; for uninitialized data
|
|
||||||
section '.data' data readable writable align 16
|
|
475
kernel/branches/Kolibri-acpi/drivers/usbhid/keyboard.inc
Normal file
475
kernel/branches/Kolibri-acpi/drivers/usbhid/keyboard.inc
Normal file
@ -0,0 +1,475 @@
|
|||||||
|
; HID keyboard driver, part of USBHID driver.
|
||||||
|
|
||||||
|
; Global constants.
|
||||||
|
; They are assembled in a macro to separate code and data;
|
||||||
|
; the code is located at the point of "include 'keyboard.inc'",
|
||||||
|
; the data are collected when workers_globals is instantiated.
|
||||||
|
macro workers_globals
|
||||||
|
{
|
||||||
|
; include global constants from previous workers
|
||||||
|
workers_globals
|
||||||
|
align 4
|
||||||
|
; Callbacks for HID layer.
|
||||||
|
keyboard_driver:
|
||||||
|
dd keyboard_driver_add_device
|
||||||
|
dd keyboard_driver_disconnect
|
||||||
|
dd keyboard_driver_begin_packet
|
||||||
|
dd keyboard_driver_array_overflow?
|
||||||
|
dd keyboard_driver_input_field
|
||||||
|
dd keyboard_driver_end_packet
|
||||||
|
; Callbacks for keyboard layer.
|
||||||
|
kbd_functions:
|
||||||
|
dd 12
|
||||||
|
dd CloseKeyboard
|
||||||
|
dd SetKeyboardLights
|
||||||
|
; Kernel keyboard layer takes input in form of PS/2 scancodes.
|
||||||
|
; data for keyboard: correspondence between HID usage keys and PS/2 scancodes.
|
||||||
|
EX = 80h ; if set, precede the scancode with special scancode 0xE0
|
||||||
|
label control_keys byte
|
||||||
|
; Usages 700E0h ... 700E7h: LCtrl, LShift, LAlt, LWin, RCtrl, RShift, RAlt, RWin
|
||||||
|
db 1Dh, 2Ah, 38h, 5Bh+EX, 1Dh+EX, 36h, 38h+EX, 5Ch+EX
|
||||||
|
; Usages 70004h ... 70004h + normal_keys_number - 1
|
||||||
|
label normal_keys byte
|
||||||
|
db 1Eh, 30h, 2Eh, 20h, 12h, 21h, 22h, 23h, 17h, 24h, 25h, 26h, 32h, 31h, 18h, 19h
|
||||||
|
db 10h, 13h, 1Fh, 14h, 16h, 2Fh, 11h, 2Dh, 15h, 2Ch, 02h, 03h, 04h, 05h, 06h, 07h
|
||||||
|
db 08h, 09h, 0Ah, 0Bh, 1Ch, 01h, 0Eh, 0Fh, 39h, 0Ch, 0Dh, 1Ah, 1Bh, 2Bh, 0, 27h
|
||||||
|
db 28h, 29h, 33h, 34h, 35h, 3Ah, 3Bh, 3Ch, 3Dh, 3Eh, 3Fh, 40h, 41h, 42h, 43h, 44h
|
||||||
|
db 57h, 58h,37h+EX,46h,0,52h+EX,47h+EX,49h+EX,53h+EX,4Fh+EX,51h+EX,4Dh+EX,4Bh+EX,50h+EX,48h+EX,45h
|
||||||
|
db 35h+EX,37h,4Ah,4Eh,1Ch+EX,4Fh,50h, 51h, 4Bh, 4Ch, 4Dh, 47h, 48h, 49h, 52h, 53h
|
||||||
|
db 0,5Dh+EX,5Eh+EX
|
||||||
|
normal_keys_number = $ - normal_keys
|
||||||
|
}
|
||||||
|
|
||||||
|
; Data that are specific for one keyboard device.
|
||||||
|
struct keyboard_device_data
|
||||||
|
handle dd ? ; keyboard handle from RegKeyboard
|
||||||
|
timer dd ? ; auto-repeat timer handle
|
||||||
|
repeatkey db ? ; auto-repeat key code
|
||||||
|
rb 3 ; padding
|
||||||
|
usbdev dd ? ; pointer to device_data of USB and HID layers
|
||||||
|
modifiers dd ? ; state of LCtrl ... RWin
|
||||||
|
led_report dd ? ; output report for LEDs state
|
||||||
|
numlock_bit dd ? ; position of NumLock bit in LED output report
|
||||||
|
capslock_bit dd ?
|
||||||
|
scrolllock_bit dd ? ; guess what
|
||||||
|
ends
|
||||||
|
|
||||||
|
; This procedure is called when HID layer detects a new keyboard.
|
||||||
|
; in: ebx -> usb_device_data, edi -> collection
|
||||||
|
; out: eax = device-specific data or NULL on error
|
||||||
|
proc keyboard_driver_add_device
|
||||||
|
; 1. Allocate memory for keyboard_device_data. If failed, return NULL.
|
||||||
|
movi eax, sizeof.keyboard_device_data
|
||||||
|
call Kmalloc
|
||||||
|
test eax, eax
|
||||||
|
jz .nothing
|
||||||
|
; 2. Initialize keyboard_device_data: store pointer to USB layer data,
|
||||||
|
; zero some fields, initialize bit positions to -1.
|
||||||
|
mov [eax+keyboard_device_data.usbdev], ebx
|
||||||
|
xor ecx, ecx
|
||||||
|
mov [eax+keyboard_device_data.timer], ecx
|
||||||
|
mov [eax+keyboard_device_data.repeatkey], cl
|
||||||
|
mov [eax+keyboard_device_data.modifiers], ecx
|
||||||
|
mov [eax+keyboard_device_data.led_report], ecx
|
||||||
|
dec ecx
|
||||||
|
mov [eax+keyboard_device_data.numlock_bit], ecx
|
||||||
|
mov [eax+keyboard_device_data.capslock_bit], ecx
|
||||||
|
mov [eax+keyboard_device_data.scrolllock_bit], ecx
|
||||||
|
; 3. Look for LED report and bits corresponding to indicators.
|
||||||
|
; For now, assume that all LEDs are set by the same report.
|
||||||
|
; 3a. Save registers.
|
||||||
|
push ebx esi
|
||||||
|
; 3b. Prepare for loop over output reports: get the first output report.
|
||||||
|
; If there are no output records, skip step 3;
|
||||||
|
; default values of led_report and *_bit were set in step 2.
|
||||||
|
mov edx, [edi+collection.output.first_report]
|
||||||
|
test edx, edx
|
||||||
|
jz .led_report_set
|
||||||
|
.scan_led_report:
|
||||||
|
; Process one output report.
|
||||||
|
; 3c. Prepare for loop over field groups in the current report:
|
||||||
|
; get the first field group.
|
||||||
|
mov ecx, [edx+report.first_field]
|
||||||
|
.scan_led_field:
|
||||||
|
; Process one field group.
|
||||||
|
; 3d. If there are no more field groups, exit the loop over field groups.
|
||||||
|
test ecx, ecx
|
||||||
|
jz .next_led_report
|
||||||
|
; For now, assume that all LEDs are plain variable fields, not arrays.
|
||||||
|
; 3e. Ignore array field groups.
|
||||||
|
test byte [ecx+report_field_group.flags], HID_FIELD_VARIABLE
|
||||||
|
jz .next_led_field
|
||||||
|
; 3f. Loop over all fields in the current group.
|
||||||
|
push [ecx+report_field_group.count]
|
||||||
|
; esi = pointer to usage of the current field
|
||||||
|
lea esi, [ecx+report_field_group.common_sizeof]
|
||||||
|
; ebx = bit position of the current field
|
||||||
|
mov ebx, [ecx+report_field_group.offset]
|
||||||
|
; if report is numbered, add extra byte in the start of report
|
||||||
|
cmp [edx+report.id], 0
|
||||||
|
jz .scan_led_usage
|
||||||
|
add ebx, 8
|
||||||
|
.scan_led_usage:
|
||||||
|
; for USAGE_LED_*LOCK, store the current bit position in the corresponding field
|
||||||
|
; and store the current report as the LED report
|
||||||
|
cmp dword [esi], USAGE_LED_NUMLOCK
|
||||||
|
jz .numlock
|
||||||
|
cmp dword [esi], USAGE_LED_CAPSLOCK
|
||||||
|
jz .capslock
|
||||||
|
cmp dword [esi], USAGE_LED_SCROLLLOCK
|
||||||
|
jnz .next_field
|
||||||
|
.scrolllock:
|
||||||
|
mov [eax+keyboard_device_data.scrolllock_bit], ebx
|
||||||
|
jmp @f
|
||||||
|
.capslock:
|
||||||
|
mov [eax+keyboard_device_data.capslock_bit], ebx
|
||||||
|
jmp @f
|
||||||
|
.numlock:
|
||||||
|
mov [eax+keyboard_device_data.numlock_bit], ebx
|
||||||
|
@@:
|
||||||
|
mov [eax+keyboard_device_data.led_report], edx
|
||||||
|
.next_field:
|
||||||
|
add esi, 4
|
||||||
|
add ebx, [ecx+report_field_group.size]
|
||||||
|
dec dword [esp]
|
||||||
|
jnz .scan_led_usage
|
||||||
|
pop ebx
|
||||||
|
.next_led_field:
|
||||||
|
; 3g. Continue loop over field groups: get next field group.
|
||||||
|
mov ecx, [ecx+report_field_group.next]
|
||||||
|
jmp .scan_led_field
|
||||||
|
.next_led_report:
|
||||||
|
; 3h. If the LED report has been set, break from the loop over reports.
|
||||||
|
; Otherwise, get the next report and continue if the current report is not
|
||||||
|
; the last for this collection.
|
||||||
|
cmp [eax+keyboard_device_data.led_report], 0
|
||||||
|
jnz .led_report_set
|
||||||
|
cmp edx, [edi+collection.output.last_report]
|
||||||
|
mov edx, [edx+report.next]
|
||||||
|
jnz .scan_led_report
|
||||||
|
.led_report_set:
|
||||||
|
; 3i. Restore registers.
|
||||||
|
pop esi ebx
|
||||||
|
; 4. Register keyboard in the kernel.
|
||||||
|
; store pointer to keyboard_device_data in the stack
|
||||||
|
push eax
|
||||||
|
; call kernel API
|
||||||
|
stdcall RegKeyboard, kbd_functions, eax
|
||||||
|
; restore pointer to keyboard_device_data from the stack,
|
||||||
|
; putting keyboard handle from API to the stack
|
||||||
|
xchg eax, [esp]
|
||||||
|
; put keyboard handle from API from the stack to keyboard_device_data field
|
||||||
|
pop [eax+keyboard_device_data.handle]
|
||||||
|
; If failed, free keyboard_device_data and return NULL.
|
||||||
|
cmp [eax+keyboard_device_data.handle], 0
|
||||||
|
jz .fail_free
|
||||||
|
; 5. Return pointer to keyboard_device_data.
|
||||||
|
.nothing:
|
||||||
|
ret
|
||||||
|
.fail_free:
|
||||||
|
call Kfree
|
||||||
|
xor eax, eax
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
; This procedure is called when HID layer detects disconnect of a previously
|
||||||
|
; connected keyboard.
|
||||||
|
; in: edi -> keyboard_device_data (pointer returned from keyboard_driver_add_device)
|
||||||
|
proc keyboard_driver_disconnect
|
||||||
|
; 1. If an autorepeat timer is active, stop it.
|
||||||
|
cmp [edi+keyboard_device_data.timer], 0
|
||||||
|
jz @f
|
||||||
|
stdcall CancelTimerHS, [edi+keyboard_device_data.timer]
|
||||||
|
@@:
|
||||||
|
; 2. Unregister keyboard in the kernel.
|
||||||
|
stdcall DelKeyboard, [edi+keyboard_device_data.handle]
|
||||||
|
; We should free data in CloseKeyboard, not here.
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
; This procedure is called when HID layer starts processing a new input packet
|
||||||
|
; from a keyboard.
|
||||||
|
; in: edi -> keyboard_device_data (pointer returned from keyboard_driver_add_device)
|
||||||
|
proc keyboard_driver_begin_packet
|
||||||
|
; Nothing to do.
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
; This procedure is called when HID layer processes every non-empty array field group.
|
||||||
|
; in: edi -> keyboard_device_data (pointer returned from keyboard_driver_add_device)
|
||||||
|
; in: ecx = fields count (always nonzero), edx = pointer to fields values
|
||||||
|
; in: esi -> report_field_group
|
||||||
|
; out: CF set => group is ok, CF cleared => group should be ignored
|
||||||
|
proc keyboard_driver_array_overflow?
|
||||||
|
; The keyboard signals array overflow by filling the entire array with
|
||||||
|
; USAGE_KBD_ROLLOVER codes.
|
||||||
|
mov eax, [edx] ; eax = first field in the array
|
||||||
|
sub eax, USAGE_KBD_ROLLOVER ; eax = 0 if overflow, nonzero otherwise
|
||||||
|
neg eax ; CF cleared if eax was zero, CF set if eax was nonzero
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
; This procedure is called from HID layer for every field.
|
||||||
|
; in: edi -> keyboard_device_data (pointer returned from keyboard_driver_add_device)
|
||||||
|
; in: ecx = field usage, edx = value, esi -> report_field_group
|
||||||
|
proc keyboard_driver_input_field
|
||||||
|
if HID_DUMP_UNCLAIMED
|
||||||
|
.unclaimed = default_driver_input_field
|
||||||
|
end if
|
||||||
|
; 1. Process normal keys:
|
||||||
|
; from USAGE_KBD_FIRST_KEY to USAGE_KBD_FIRST_KEY + normal_keys_number - 1,
|
||||||
|
; excluding zeroes in [normal_keys].
|
||||||
|
; 1a. Test whether usage is in the range.
|
||||||
|
lea eax, [ecx-USAGE_KBD_FIRST_KEY]
|
||||||
|
cmp eax, normal_keys_number
|
||||||
|
jae .not_normal_key
|
||||||
|
; 1b. If the corresponding entry in [normal_keys] is zero,
|
||||||
|
; pass this field to the default handler - if HID_DUMP_UNCLAIMED is enabled,
|
||||||
|
; default handler is default_driver_input_field, otherwise just ignore the field.
|
||||||
|
cmp [normal_keys + eax], 0
|
||||||
|
jz .unclaimed
|
||||||
|
; 1c. Get the scancode.
|
||||||
|
movzx ecx, [normal_keys + eax]
|
||||||
|
; 1d. Further actions are slightly different for key press and key release.
|
||||||
|
; Decide what to do.
|
||||||
|
test edx, edx
|
||||||
|
jz .normal_key_released
|
||||||
|
.normal_key_pressed:
|
||||||
|
; The key is pressed.
|
||||||
|
; 1e. Store the last pressed key for autorepeat.
|
||||||
|
mov [edi+keyboard_device_data.repeatkey], cl
|
||||||
|
; 1f. Copy bit 7 to CF and send scancode with bit 7 cleared.
|
||||||
|
btr ecx, 7
|
||||||
|
call .send_key
|
||||||
|
; 1g. Stop the previous autorepeat timer, if any.
|
||||||
|
mov eax, [edi+keyboard_device_data.timer]
|
||||||
|
test eax, eax
|
||||||
|
jz @f
|
||||||
|
stdcall CancelTimerHS, eax
|
||||||
|
@@:
|
||||||
|
; 1h. Start the new autorepeat timer with 250 ms initial delay
|
||||||
|
; and 50 ms subsequent delays.
|
||||||
|
stdcall TimerHS, 25, 5, autorepeat_timer, edi
|
||||||
|
mov [edi+keyboard_device_data.timer], eax
|
||||||
|
if ~HID_DUMP_UNCLAIMED
|
||||||
|
.unclaimed:
|
||||||
|
end if
|
||||||
|
ret
|
||||||
|
.normal_key_released:
|
||||||
|
; The key is released.
|
||||||
|
; 1i. Stop the autorepeat timer if it is autorepeating the released key.
|
||||||
|
cmp [edi+keyboard_device_data.repeatkey], cl
|
||||||
|
jnz .no_stop_timer
|
||||||
|
push ecx
|
||||||
|
mov [edi+keyboard_device_data.repeatkey], 0
|
||||||
|
mov eax, [edi+keyboard_device_data.timer]
|
||||||
|
test eax, eax
|
||||||
|
jz @f
|
||||||
|
stdcall CancelTimerHS, eax
|
||||||
|
mov [edi+keyboard_device_data.timer], 0
|
||||||
|
@@:
|
||||||
|
pop ecx
|
||||||
|
.no_stop_timer:
|
||||||
|
; 1j. Copy bit 7 to CF and send scancode with bit 7 set.
|
||||||
|
bts ecx, 7
|
||||||
|
call .send_key
|
||||||
|
ret
|
||||||
|
.not_normal_key:
|
||||||
|
; 2. USAGE_KBD_NOEVENT is simply a filler for free array fields,
|
||||||
|
; ignore it.
|
||||||
|
cmp ecx, USAGE_KBD_NOEVENT
|
||||||
|
jz .nothing
|
||||||
|
; 3. Process modifiers: 8 keys starting at USAGE_KBD_LCTRL.
|
||||||
|
; 3a. Test whether usage is in range.
|
||||||
|
; If not, we don't know what this field means, so pass it to the default handler.
|
||||||
|
lea eax, [ecx-USAGE_KBD_LCTRL]
|
||||||
|
cmp eax, 8
|
||||||
|
jae .unclaimed
|
||||||
|
; 3b. Further actions are slightly different for modifier press
|
||||||
|
; and modifier release. Decide what to do.
|
||||||
|
test edx, edx
|
||||||
|
jz .modifier_not_pressed
|
||||||
|
.modifier_pressed:
|
||||||
|
; The modifier is pressed.
|
||||||
|
; 3c. Set the corresponding status bit.
|
||||||
|
; If it was not set, send the corresponding scancode to the kernel
|
||||||
|
; with bit 7 cleared.
|
||||||
|
bts [edi+keyboard_device_data.modifiers], eax
|
||||||
|
jc @f
|
||||||
|
movzx ecx, [control_keys+eax]
|
||||||
|
btr ecx, 7
|
||||||
|
call .send_key
|
||||||
|
@@:
|
||||||
|
.nothing:
|
||||||
|
ret
|
||||||
|
.modifier_not_pressed:
|
||||||
|
; The modifier is not pressed.
|
||||||
|
; 3d. Clear the correspodning status bit.
|
||||||
|
; If it was set, send the corresponding scancode to the kernel
|
||||||
|
; with bit 7 set.
|
||||||
|
btr [edi+keyboard_device_data.modifiers], eax
|
||||||
|
jnc @f
|
||||||
|
movzx ecx, [control_keys+eax]
|
||||||
|
bts ecx, 7
|
||||||
|
call .send_key
|
||||||
|
@@:
|
||||||
|
ret
|
||||||
|
|
||||||
|
; Helper procedure. Sends scancode from cl to the kernel.
|
||||||
|
; If CF is set, precede it with special code 0xE0.
|
||||||
|
.send_key:
|
||||||
|
jnc @f
|
||||||
|
push ecx
|
||||||
|
mov ecx, 0xE0
|
||||||
|
call SetKeyboardData
|
||||||
|
pop ecx
|
||||||
|
@@:
|
||||||
|
call SetKeyboardData
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
; This procedure is called when HID layer ends processing a new input packet
|
||||||
|
; from a keyboard.
|
||||||
|
; in: edi -> keyboard_device_data (pointer returned from keyboard_driver_add_device)
|
||||||
|
proc keyboard_driver_end_packet
|
||||||
|
; Nothing to do.
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
; Timer callback for SetTimerHS.
|
||||||
|
proc autorepeat_timer
|
||||||
|
virtual at esp
|
||||||
|
dd ? ; return address
|
||||||
|
.data dd ?
|
||||||
|
end virtual
|
||||||
|
; Just resend the last pressed key.
|
||||||
|
mov eax, [.data]
|
||||||
|
movzx ecx, [eax+keyboard_device_data.repeatkey]
|
||||||
|
; Copy bit 7 to CF and send scancode with bit 7 cleared.
|
||||||
|
btr ecx, 7
|
||||||
|
call keyboard_driver_input_field.send_key
|
||||||
|
ret 4
|
||||||
|
endp
|
||||||
|
|
||||||
|
; This function is called from the keyboard layer
|
||||||
|
; when it is safe to free keyboard data.
|
||||||
|
proc CloseKeyboard
|
||||||
|
virtual at esp
|
||||||
|
dd ? ; return address
|
||||||
|
.device_data dd ?
|
||||||
|
end virtual
|
||||||
|
mov eax, [.device_data]
|
||||||
|
call Kfree
|
||||||
|
ret 4
|
||||||
|
endp
|
||||||
|
|
||||||
|
; This function is called from the keyboard layer
|
||||||
|
; to update LED state on the keyboard.
|
||||||
|
proc SetKeyboardLights stdcall uses ebx esi edi, device_data, led_state
|
||||||
|
locals
|
||||||
|
size dd ?
|
||||||
|
endl
|
||||||
|
; 1. Get the pointer to the LED report.
|
||||||
|
; If there is no LED report, exit from the function.
|
||||||
|
mov ebx, [device_data]
|
||||||
|
mov esi, [ebx+keyboard_device_data.led_report]
|
||||||
|
test esi, esi
|
||||||
|
jz .nothing
|
||||||
|
; 2. Get report size in bytes.
|
||||||
|
; report.size is size in bits without possible report ID;
|
||||||
|
; if an ID is assigned, the size is one byte greater.
|
||||||
|
mov eax, [esi+report.size]
|
||||||
|
add eax, 7
|
||||||
|
shr eax, 3
|
||||||
|
cmp [esi+report.id], 0
|
||||||
|
jz @f
|
||||||
|
inc eax
|
||||||
|
@@:
|
||||||
|
mov [size], eax
|
||||||
|
; 3. Allocate memory for report + 8 bytes for setup packet.
|
||||||
|
; Dword-align size for subsequent rep stosd and bts.
|
||||||
|
; If failed, exit from the function.
|
||||||
|
add eax, 8 + 3
|
||||||
|
and eax, not 3
|
||||||
|
push eax
|
||||||
|
call Kmalloc
|
||||||
|
pop ecx
|
||||||
|
test eax, eax
|
||||||
|
jz .nothing
|
||||||
|
; 4. Zero-initialize output report.
|
||||||
|
push eax
|
||||||
|
mov edi, eax
|
||||||
|
shr ecx, 2
|
||||||
|
xor eax, eax
|
||||||
|
rep stosd
|
||||||
|
pop edi
|
||||||
|
add edi, 8
|
||||||
|
; 5. Store report ID, if assigned. If not assigned, that would just write zero
|
||||||
|
; over zeroes.
|
||||||
|
mov edx, [esi+report.id]
|
||||||
|
mov [edi], edx
|
||||||
|
; 6. Set report bits corresponding to active indicators.
|
||||||
|
mov eax, [led_state]
|
||||||
|
test al, 1 ; PS/2 Scroll Lock
|
||||||
|
jz @f
|
||||||
|
mov ecx, [ebx+keyboard_device_data.scrolllock_bit]
|
||||||
|
test ecx, ecx
|
||||||
|
js @f
|
||||||
|
bts [edi], ecx
|
||||||
|
@@:
|
||||||
|
test al, 2 ; PS/2 Num Lock
|
||||||
|
jz @f
|
||||||
|
mov ecx, [ebx+keyboard_device_data.numlock_bit]
|
||||||
|
test ecx, ecx
|
||||||
|
js @f
|
||||||
|
bts [edi], ecx
|
||||||
|
@@:
|
||||||
|
test al, 4 ; PS/2 Caps Lock
|
||||||
|
jz @f
|
||||||
|
mov ecx, [ebx+keyboard_device_data.capslock_bit]
|
||||||
|
test ecx, ecx
|
||||||
|
js @f
|
||||||
|
bts [edi], ecx
|
||||||
|
@@:
|
||||||
|
; 7. Fill setup packet.
|
||||||
|
shl edx, 16 ; move Report ID to byte 2
|
||||||
|
or edx, 21h + \ ; Class-specific request to Interface
|
||||||
|
(9 shl 8) + \ ; SET_REPORT
|
||||||
|
(2 shl 24) ; Report Type = Output
|
||||||
|
lea eax, [edi-8]
|
||||||
|
mov ebx, [ebx+keyboard_device_data.usbdev]
|
||||||
|
mov dword [eax], edx
|
||||||
|
mov edx, [size]
|
||||||
|
shl edx, 16 ; move Size to last word
|
||||||
|
or edx, [ebx+usb_device_data.interface_number]
|
||||||
|
mov [eax+4], edx
|
||||||
|
; 8. Submit output control request.
|
||||||
|
stdcall USBControlTransferAsync, [ebx+usb_device_data.configpipe], \
|
||||||
|
eax, edi, [size], after_set_keyboard_lights, ebx, 0
|
||||||
|
; If failed, free the buffer now.
|
||||||
|
; If succeeded, the callback will free the buffer.
|
||||||
|
test eax, eax
|
||||||
|
jnz .nothing
|
||||||
|
lea eax, [edi-8]
|
||||||
|
call Kfree
|
||||||
|
.nothing:
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
; This procedure is called from the USB subsystem when the request initiated by
|
||||||
|
; SetKeyboardLights is completed, either successfully or unsuccessfully.
|
||||||
|
proc after_set_keyboard_lights
|
||||||
|
virtual at esp
|
||||||
|
dd ? ; return address
|
||||||
|
.pipe dd ?
|
||||||
|
.status dd ?
|
||||||
|
.buffer dd ?
|
||||||
|
.length dd ?
|
||||||
|
.calldata dd ?
|
||||||
|
end virtual
|
||||||
|
; Ignore status, just free the buffer allocated by SetKeyboardLights.
|
||||||
|
mov eax, [.buffer]
|
||||||
|
sub eax, 8
|
||||||
|
call Kfree
|
||||||
|
ret 20
|
||||||
|
endp
|
155
kernel/branches/Kolibri-acpi/drivers/usbhid/mouse.inc
Normal file
155
kernel/branches/Kolibri-acpi/drivers/usbhid/mouse.inc
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
; HID mouse driver, part of USBHID driver.
|
||||||
|
|
||||||
|
; Global constants.
|
||||||
|
; They are assembled in a macro to separate code and data;
|
||||||
|
; the code is located at the point of "include 'mouse.inc'",
|
||||||
|
; the data are collected when workers_globals is instantiated.
|
||||||
|
macro workers_globals
|
||||||
|
{
|
||||||
|
; include global constants from previous workers
|
||||||
|
workers_globals
|
||||||
|
align 4
|
||||||
|
; Callbacks for HID layer.
|
||||||
|
mouse_driver:
|
||||||
|
dd mouse_driver_add_device
|
||||||
|
dd mouse_driver_disconnect
|
||||||
|
dd mouse_driver_begin_packet
|
||||||
|
dd mouse_driver_array_overflow?
|
||||||
|
dd mouse_driver_input_field
|
||||||
|
dd mouse_driver_end_packet
|
||||||
|
}
|
||||||
|
|
||||||
|
; Data that are specific for one mouse device.
|
||||||
|
struct mouse_device_data
|
||||||
|
buttons dd ? ; buttons that are currently pressed
|
||||||
|
dx dd ? ; current x moving
|
||||||
|
dy dd ? ; current y moving
|
||||||
|
wheel dd ? ; current wheel moving
|
||||||
|
hwheel dd ?
|
||||||
|
ends
|
||||||
|
|
||||||
|
; This procedure is called when HID layer detects a new mouse.
|
||||||
|
; in: ebx -> device_data from USB layer, edi -> collection
|
||||||
|
; out: eax = device-specific data or NULL on error
|
||||||
|
proc mouse_driver_add_device
|
||||||
|
; Just allocate memory; no initialization needed.
|
||||||
|
movi eax, sizeof.mouse_device_data
|
||||||
|
call Kmalloc
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
; This procedure is called when HID layer detects disconnect of a previously
|
||||||
|
; connected mouse.
|
||||||
|
; in: edi -> mouse_device_data (pointer returned from mouse_driver_add_device)
|
||||||
|
proc mouse_driver_disconnect
|
||||||
|
; Free the allocated memory.
|
||||||
|
mov eax, edi
|
||||||
|
call Kfree
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
; This procedure is called when HID layer starts processing a new input packet
|
||||||
|
; from a mouse.
|
||||||
|
; in: edi -> mouse_device_data (pointer returned from mouse_driver_add_device)
|
||||||
|
proc mouse_driver_begin_packet
|
||||||
|
; Zero all variables describing the current state.
|
||||||
|
mov [edi+mouse_device_data.buttons], 0
|
||||||
|
mov [edi+mouse_device_data.dx], 0
|
||||||
|
mov [edi+mouse_device_data.dy], 0
|
||||||
|
mov [edi+mouse_device_data.wheel], 0
|
||||||
|
mov [edi+mouse_device_data.hwheel], 0
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
; This procedure is called when HID layer processes every non-empty array field group.
|
||||||
|
; in: edi -> mouse_device_data (pointer returned from mouse_driver_add_device)
|
||||||
|
; in: ecx = fields count (always nonzero), edx = pointer to fields values
|
||||||
|
; in: esi -> report_field_group
|
||||||
|
; out: CF set => array is ok, CF cleared => array should be ignored
|
||||||
|
proc mouse_driver_array_overflow?
|
||||||
|
; no array fields, no overflows
|
||||||
|
stc
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
; This procedure is called from HID layer for every field.
|
||||||
|
; in: edi -> mouse_device_data (pointer returned from mouse_driver_add_device)
|
||||||
|
; in: ecx = field usage, edx = value, esi -> report_field_group
|
||||||
|
proc mouse_driver_input_field
|
||||||
|
; 1. Determine the handler. We process x/y moving, wheel and up to 32 buttons.
|
||||||
|
; Pass other fields to the default handler - default_driver_input_field if
|
||||||
|
; HID_DUMP_UNCLAIMED is enabled, just ignore otherwise.
|
||||||
|
cmp ecx, USAGE_GD_X
|
||||||
|
jz .x
|
||||||
|
cmp ecx, USAGE_GD_Y
|
||||||
|
jz .y
|
||||||
|
cmp ecx, USAGE_GD_WHEEL
|
||||||
|
jz .wheel
|
||||||
|
cmp ecx, 0xC0238
|
||||||
|
jz .hwheel
|
||||||
|
sub ecx, USAGE_BUTTON_PAGE + 1
|
||||||
|
jb .unclaimed
|
||||||
|
cmp ecx, 32
|
||||||
|
jae .unclaimed
|
||||||
|
; 2. This is a button.
|
||||||
|
; If a button is pressed, set the corresponding bit in the state.
|
||||||
|
; If a button is not pressed, do nothing.
|
||||||
|
test edx, edx
|
||||||
|
jz @f
|
||||||
|
bts [edi+mouse_device_data.buttons], ecx
|
||||||
|
@@:
|
||||||
|
if ~HID_DUMP_UNCLAIMED
|
||||||
|
.unclaimed:
|
||||||
|
end if
|
||||||
|
ret
|
||||||
|
if HID_DUMP_UNCLAIMED
|
||||||
|
.unclaimed:
|
||||||
|
add ecx, USAGE_BUTTON_PAGE + 1
|
||||||
|
jmp default_driver_input_field
|
||||||
|
end if
|
||||||
|
.x:
|
||||||
|
; 3. This is x moving. For relative fields, store the value in the state.
|
||||||
|
; Pass absolute field to the default handler.
|
||||||
|
test byte [esi+report_field_group.flags], HID_FIELD_RELATIVE
|
||||||
|
jz .unclaimed
|
||||||
|
mov [edi+mouse_device_data.dx], edx
|
||||||
|
ret
|
||||||
|
.y:
|
||||||
|
; 4. This is y moving. For relative fields, store the value in the state,
|
||||||
|
; changing the sign: HID uses "mathematics" scheme with Y axis increasing from
|
||||||
|
; bottom to top, the kernel expects "programming" PS/2-style with Y axis
|
||||||
|
; increasing from top to bottom.
|
||||||
|
; Pass absolute fields to the default handler.
|
||||||
|
test byte [esi+report_field_group.flags], HID_FIELD_RELATIVE
|
||||||
|
jz .unclaimed
|
||||||
|
neg edx
|
||||||
|
mov [edi+mouse_device_data.dy], edx
|
||||||
|
ret
|
||||||
|
.wheel:
|
||||||
|
; 5. This is wheel event. For relative fields, store the value in the state,
|
||||||
|
; changing the sign. Pass absolute fields to the default handler.
|
||||||
|
test byte [esi+report_field_group.flags], HID_FIELD_RELATIVE
|
||||||
|
jz .unclaimed
|
||||||
|
neg edx
|
||||||
|
mov [edi+mouse_device_data.wheel], edx
|
||||||
|
ret
|
||||||
|
.hwheel:
|
||||||
|
test byte [esi+report_field_group.flags], HID_FIELD_RELATIVE
|
||||||
|
jz .unclaimed
|
||||||
|
mov [edi+mouse_device_data.hwheel], edx
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
; This procedure is called when HID layer ends processing a new input packet
|
||||||
|
; from a mouse.
|
||||||
|
; in: edi -> mouse_device_data (pointer returned from mouse_driver_add_device)
|
||||||
|
proc mouse_driver_end_packet
|
||||||
|
; Call the kernel, passing collected state.
|
||||||
|
stdcall SetMouseData, \
|
||||||
|
[edi+mouse_device_data.buttons], \
|
||||||
|
[edi+mouse_device_data.dx], \
|
||||||
|
[edi+mouse_device_data.dy], \
|
||||||
|
[edi+mouse_device_data.wheel], \
|
||||||
|
[edi+mouse_device_data.hwheel]
|
||||||
|
ret
|
||||||
|
endp
|
1442
kernel/branches/Kolibri-acpi/drivers/usbhid/report.inc
Normal file
1442
kernel/branches/Kolibri-acpi/drivers/usbhid/report.inc
Normal file
File diff suppressed because it is too large
Load Diff
60
kernel/branches/Kolibri-acpi/drivers/usbhid/sort.inc
Normal file
60
kernel/branches/Kolibri-acpi/drivers/usbhid/sort.inc
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
; Sort array of unsigned dwords in non-decreasing order.
|
||||||
|
; ecx = array size, edx = array pointer.
|
||||||
|
; Destroys eax, ecx, esi, edi.
|
||||||
|
sort:
|
||||||
|
test ecx, ecx
|
||||||
|
jz .done
|
||||||
|
mov eax, ecx
|
||||||
|
@@:
|
||||||
|
push eax
|
||||||
|
call .restore
|
||||||
|
pop eax
|
||||||
|
dec eax
|
||||||
|
jnz @b
|
||||||
|
@@:
|
||||||
|
cmp ecx, 1
|
||||||
|
jz .done
|
||||||
|
mov esi, 1
|
||||||
|
mov edi, ecx
|
||||||
|
call .exchange
|
||||||
|
dec ecx
|
||||||
|
mov eax, 1
|
||||||
|
call .restore
|
||||||
|
jmp @b
|
||||||
|
.done:
|
||||||
|
ret
|
||||||
|
|
||||||
|
.exchange:
|
||||||
|
push eax ecx
|
||||||
|
mov eax, [edx+esi*4-4]
|
||||||
|
mov ecx, [edx+edi*4-4]
|
||||||
|
mov [edx+esi*4-4], ecx
|
||||||
|
mov [edx+edi*4-4], eax
|
||||||
|
pop ecx eax
|
||||||
|
ret
|
||||||
|
|
||||||
|
.restore:
|
||||||
|
lea esi, [eax+eax]
|
||||||
|
cmp esi, ecx
|
||||||
|
ja .doner
|
||||||
|
mov edi, [edx+eax*4-4]
|
||||||
|
cmp [edx+esi*4-4], edi
|
||||||
|
ja .need_xchg
|
||||||
|
cmp esi, ecx
|
||||||
|
jae .doner
|
||||||
|
mov edi, [edx+eax*4-4]
|
||||||
|
cmp [edx+esi*4], edi
|
||||||
|
jbe .doner
|
||||||
|
.need_xchg:
|
||||||
|
cmp esi, ecx
|
||||||
|
jz .do_xchg
|
||||||
|
mov edi, [edx+esi*4-4]
|
||||||
|
cmp [edx+esi*4], edi
|
||||||
|
sbb esi, -1
|
||||||
|
.do_xchg:
|
||||||
|
mov edi, eax
|
||||||
|
call .exchange
|
||||||
|
mov eax, esi
|
||||||
|
jmp .restore
|
||||||
|
.doner:
|
||||||
|
ret
|
60
kernel/branches/Kolibri-acpi/drivers/usbhid/unclaimed.inc
Normal file
60
kernel/branches/Kolibri-acpi/drivers/usbhid/unclaimed.inc
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
; HID default driver, part of USBHID driver.
|
||||||
|
; Present only if compile-time setting HID_DUMP_UNCLAIMED is on.
|
||||||
|
; Active for those devices when we do not have a specialized driver.
|
||||||
|
; Just dumps everything to the debug board.
|
||||||
|
|
||||||
|
if HID_DUMP_UNCLAIMED
|
||||||
|
; Global constants.
|
||||||
|
; They are assembled in a macro to separate code and data;
|
||||||
|
; the code is located at the point of "include 'unclaimed.inc'",
|
||||||
|
; the data are collected when workers_globals is instantiated.
|
||||||
|
macro workers_globals
|
||||||
|
{
|
||||||
|
; include global constants from previous workers
|
||||||
|
workers_globals
|
||||||
|
align 4
|
||||||
|
; Callbacks for HID layer.
|
||||||
|
default_driver:
|
||||||
|
dd default_driver_add_device
|
||||||
|
dd default_driver_disconnect
|
||||||
|
dd default_driver_begin_packet
|
||||||
|
dd default_driver_array_overflow?
|
||||||
|
dd default_driver_input_field
|
||||||
|
dd default_driver_end_packet
|
||||||
|
}
|
||||||
|
; This procedure is called when HID layer detects a new driverless device.
|
||||||
|
; in: ebx -> usb_device_data, edi -> collection
|
||||||
|
; out: eax = device-specific data or NULL on error
|
||||||
|
default_driver_add_device:
|
||||||
|
; just return something nonzero, no matter what
|
||||||
|
xor eax, eax
|
||||||
|
inc eax
|
||||||
|
ret
|
||||||
|
; This procedure is called when HID layer processes every non-empty array field group.
|
||||||
|
; in: edi -> keyboard_device_data (pointer returned from keyboard_driver_add_device)
|
||||||
|
; in: ecx = fields count (always nonzero), edx = pointer to fields values
|
||||||
|
; in: esi -> report_field_group
|
||||||
|
; out: CF set => group is ok, CF cleared => group should be ignored
|
||||||
|
default_driver_array_overflow?:
|
||||||
|
; parse everything
|
||||||
|
stc
|
||||||
|
ret
|
||||||
|
; This procedure is called from HID layer for every field.
|
||||||
|
; in: ecx = field usage, edx = value, esi -> report_field_group
|
||||||
|
default_driver_input_field:
|
||||||
|
; Do not dump zero values in Variable fields,
|
||||||
|
; they are present even if the corresponding control is inactive.
|
||||||
|
test edx, edx
|
||||||
|
jnz @f
|
||||||
|
test byte [esi+report_field_group.flags], HID_FIELD_VARIABLE
|
||||||
|
jnz .nodump
|
||||||
|
@@:
|
||||||
|
DEBUGF 1,'K : unclaimed HID input: usage=%x, value=%x\n',ecx,edx
|
||||||
|
.nodump:
|
||||||
|
; pass through
|
||||||
|
; Three nothing-to-do procedures.
|
||||||
|
default_driver_disconnect:
|
||||||
|
default_driver_begin_packet:
|
||||||
|
default_driver_end_packet:
|
||||||
|
ret
|
||||||
|
end if
|
553
kernel/branches/Kolibri-acpi/drivers/usbhid/usbhid.asm
Normal file
553
kernel/branches/Kolibri-acpi/drivers/usbhid/usbhid.asm
Normal file
@ -0,0 +1,553 @@
|
|||||||
|
; standard driver stuff
|
||||||
|
format MS COFF
|
||||||
|
|
||||||
|
DEBUG = 1
|
||||||
|
|
||||||
|
; this is for DEBUGF macro from 'fdo.inc'
|
||||||
|
__DEBUG__ = 1
|
||||||
|
__DEBUG_LEVEL__ = 1
|
||||||
|
|
||||||
|
include '../proc32.inc'
|
||||||
|
include '../imports.inc'
|
||||||
|
include '../fdo.inc'
|
||||||
|
include '../../struct.inc'
|
||||||
|
|
||||||
|
public START
|
||||||
|
public version
|
||||||
|
|
||||||
|
; Compile-time settings.
|
||||||
|
; If set, the code will dump all descriptors as they are read to the debug board.
|
||||||
|
USB_DUMP_DESCRIPTORS = 1
|
||||||
|
; If set, the code will dump any unclaimed input to the debug board.
|
||||||
|
HID_DUMP_UNCLAIMED = 1
|
||||||
|
|
||||||
|
; USB constants
|
||||||
|
DEVICE_DESCR_TYPE = 1
|
||||||
|
CONFIG_DESCR_TYPE = 2
|
||||||
|
STRING_DESCR_TYPE = 3
|
||||||
|
INTERFACE_DESCR_TYPE = 4
|
||||||
|
ENDPOINT_DESCR_TYPE = 5
|
||||||
|
DEVICE_QUALIFIER_DESCR_TYPE = 6
|
||||||
|
|
||||||
|
CONTROL_PIPE = 0
|
||||||
|
ISOCHRONOUS_PIPE = 1
|
||||||
|
BULK_PIPE = 2
|
||||||
|
INTERRUPT_PIPE = 3
|
||||||
|
|
||||||
|
; USB HID constants
|
||||||
|
HID_DESCR_TYPE = 21h
|
||||||
|
REPORT_DESCR_TYPE = 22h
|
||||||
|
PHYSICAL_DESCR_TYPE = 23h
|
||||||
|
|
||||||
|
; USB structures
|
||||||
|
struct config_descr
|
||||||
|
bLength db ?
|
||||||
|
bDescriptorType db ?
|
||||||
|
wTotalLength dw ?
|
||||||
|
bNumInterfaces db ?
|
||||||
|
bConfigurationValue db ?
|
||||||
|
iConfiguration db ?
|
||||||
|
bmAttributes db ?
|
||||||
|
bMaxPower db ?
|
||||||
|
ends
|
||||||
|
|
||||||
|
struct interface_descr
|
||||||
|
bLength db ?
|
||||||
|
bDescriptorType db ?
|
||||||
|
bInterfaceNumber db ?
|
||||||
|
bAlternateSetting db ?
|
||||||
|
bNumEndpoints db ?
|
||||||
|
bInterfaceClass db ?
|
||||||
|
bInterfaceSubClass db ?
|
||||||
|
bInterfaceProtocol db ?
|
||||||
|
iInterface db ?
|
||||||
|
ends
|
||||||
|
|
||||||
|
struct endpoint_descr
|
||||||
|
bLength db ?
|
||||||
|
bDescriptorType db ?
|
||||||
|
bEndpointAddress db ?
|
||||||
|
bmAttributes db ?
|
||||||
|
wMaxPacketSize dw ?
|
||||||
|
bInterval db ?
|
||||||
|
ends
|
||||||
|
|
||||||
|
; USB HID structures
|
||||||
|
struct hid_descr
|
||||||
|
bLength db ?
|
||||||
|
bDescriptorType db ?
|
||||||
|
bcdHID dw ?
|
||||||
|
bCountryCode db ?
|
||||||
|
bNumDescriptors db ?
|
||||||
|
base_sizeof rb 0
|
||||||
|
; now two fields are repeated .bNumDescriptors times:
|
||||||
|
subDescriptorType db ?
|
||||||
|
subDescriptorLength dw ?
|
||||||
|
ends
|
||||||
|
|
||||||
|
; Include macro for parsing report descriptors/data.
|
||||||
|
macro workers_globals
|
||||||
|
{}
|
||||||
|
include 'report.inc'
|
||||||
|
|
||||||
|
; Driver data for all devices
|
||||||
|
struct usb_device_data
|
||||||
|
hid hid_data ; data of HID layer
|
||||||
|
epdescr dd ? ; endpoint descriptor
|
||||||
|
hiddescr dd ? ; HID descriptor
|
||||||
|
interface_number dd ? ; copy of interface_descr.bInterfaceNumber
|
||||||
|
configpipe dd ? ; config pipe handle
|
||||||
|
intpipe dd ? ; interrupt pipe handle
|
||||||
|
input_transfer_size dd ? ; input transfer size
|
||||||
|
input_buffer dd ? ; buffer for input transfers
|
||||||
|
control rb 8 ; control packet to device
|
||||||
|
ends
|
||||||
|
|
||||||
|
section '.flat' code readable align 16
|
||||||
|
; The start procedure.
|
||||||
|
proc START
|
||||||
|
virtual at esp
|
||||||
|
dd ? ; return address
|
||||||
|
.reason dd ?
|
||||||
|
end virtual
|
||||||
|
; 1. Test whether the procedure is called with the argument DRV_ENTRY.
|
||||||
|
; If not, return 0.
|
||||||
|
xor eax, eax ; initialize return value
|
||||||
|
cmp [.reason], 1 ; compare the argument
|
||||||
|
jnz .nothing
|
||||||
|
; 2. Register self as a USB driver.
|
||||||
|
; The name is my_driver = 'usbhid'; IOCTL interface is not supported;
|
||||||
|
; usb_functions is an offset of a structure with callback functions.
|
||||||
|
stdcall RegUSBDriver, my_driver, eax, usb_functions
|
||||||
|
; 3. Return the returned value of RegUSBDriver.
|
||||||
|
.nothing:
|
||||||
|
ret 4
|
||||||
|
endp
|
||||||
|
|
||||||
|
; This procedure is called when new HID device is detected.
|
||||||
|
; It initializes the device.
|
||||||
|
proc AddDevice
|
||||||
|
push ebx esi edi ; save used registers to be stdcall
|
||||||
|
virtual at esp
|
||||||
|
rd 3 ; saved registers
|
||||||
|
dd ? ; return address
|
||||||
|
.config_pipe dd ?
|
||||||
|
.config_descr dd ?
|
||||||
|
.interface dd ?
|
||||||
|
end virtual
|
||||||
|
DEBUGF 1,'K : USB HID device detected\n'
|
||||||
|
; 1. Allocate memory for device data.
|
||||||
|
movi eax, sizeof.usb_device_data
|
||||||
|
call Kmalloc
|
||||||
|
test eax, eax
|
||||||
|
jnz @f
|
||||||
|
mov esi, nomemory_msg
|
||||||
|
call SysMsgBoardStr
|
||||||
|
jmp .return0
|
||||||
|
@@:
|
||||||
|
; zero-initialize it
|
||||||
|
mov edi, eax
|
||||||
|
xchg eax, ebx
|
||||||
|
xor eax, eax
|
||||||
|
movi ecx, sizeof.usb_device_data / 4
|
||||||
|
rep stosd
|
||||||
|
mov edx, [.interface]
|
||||||
|
; HID devices use one IN interrupt endpoint for polling the device
|
||||||
|
; and an optional OUT interrupt endpoint. We do not use the later,
|
||||||
|
; but must locate the first. Look for the IN interrupt endpoint.
|
||||||
|
; Also, look for the HID descriptor; according to HID spec, it must be
|
||||||
|
; located before endpoint descriptors.
|
||||||
|
; 2. Get the upper bound of all descriptors' data.
|
||||||
|
mov eax, [.config_descr]
|
||||||
|
movzx ecx, [eax+config_descr.wTotalLength]
|
||||||
|
add eax, ecx
|
||||||
|
; 3. Loop over all descriptors until
|
||||||
|
; either end-of-data reached - this is fail
|
||||||
|
; or interface descriptor found - this is fail, all further data
|
||||||
|
; correspond to that interface
|
||||||
|
; or endpoint descriptor for IN endpoint is found
|
||||||
|
; (HID descriptor must be located before the endpoint descriptor).
|
||||||
|
; 3a. Loop start: edx points to the interface descriptor.
|
||||||
|
.lookep:
|
||||||
|
; 3b. Get next descriptor.
|
||||||
|
movzx ecx, byte [edx] ; the first byte of all descriptors is length
|
||||||
|
test ecx, ecx
|
||||||
|
jz .cfgerror
|
||||||
|
add edx, ecx
|
||||||
|
; 3c. Check that at least two bytes are readable. The opposite is an error.
|
||||||
|
inc edx
|
||||||
|
cmp edx, eax
|
||||||
|
jae .cfgerror
|
||||||
|
dec edx
|
||||||
|
; 3d. Check that this descriptor is not interface descriptor. The opposite is
|
||||||
|
; an error.
|
||||||
|
cmp [edx+endpoint_descr.bDescriptorType], INTERFACE_DESCR_TYPE
|
||||||
|
jz .cfgerror
|
||||||
|
; 3e. For HID descriptor, proceed to 4.
|
||||||
|
; For endpoint descriptor, go to 5.
|
||||||
|
; For other descriptors, continue the loop.
|
||||||
|
; Note: bDescriptorType is in the same place in all descriptors.
|
||||||
|
cmp [edx+endpoint_descr.bDescriptorType], ENDPOINT_DESCR_TYPE
|
||||||
|
jz .foundep
|
||||||
|
cmp [edx+endpoint_descr.bDescriptorType], HID_DESCR_TYPE
|
||||||
|
jnz .lookep
|
||||||
|
; 4a. Check that the descriptor contains all required data and all data are
|
||||||
|
; readable. The opposite is an error.
|
||||||
|
movzx ecx, [edx+hid_descr.bLength]
|
||||||
|
cmp ecx, hid_descr.base_sizeof + 3
|
||||||
|
jb .cfgerror
|
||||||
|
add ecx, edx
|
||||||
|
cmp ecx, eax
|
||||||
|
ja .cfgerror
|
||||||
|
; 4b. Store the pointer in usb_device_data structure for further references.
|
||||||
|
mov [ebx+usb_device_data.hiddescr], edx
|
||||||
|
; 4c. Continue the loop.
|
||||||
|
jmp .lookep
|
||||||
|
.foundep:
|
||||||
|
; 5a. Check that the descriptor contains all required data and all data are
|
||||||
|
; readable. The opposite is an error.
|
||||||
|
cmp byte [edx+endpoint_descr.bLength], sizeof.endpoint_descr
|
||||||
|
jb .cfgerror
|
||||||
|
lea ecx, [edx+sizeof.endpoint_descr]
|
||||||
|
cmp ecx, eax
|
||||||
|
jbe @f
|
||||||
|
; 6. An error occured during processing endpoint descriptor.
|
||||||
|
.cfgerror:
|
||||||
|
; 6a. Print a message.
|
||||||
|
mov esi, invalid_config_descr_msg
|
||||||
|
call SysMsgBoardStr
|
||||||
|
; 6b. Free memory allocated for device data.
|
||||||
|
.free:
|
||||||
|
xchg eax, ebx
|
||||||
|
call Kfree
|
||||||
|
.return0:
|
||||||
|
; 6c. Return an error.
|
||||||
|
xor eax, eax
|
||||||
|
.nothing:
|
||||||
|
pop edi esi ebx ; restore used registers to be stdcall
|
||||||
|
ret 12
|
||||||
|
@@:
|
||||||
|
; 5b. If this is not IN interrupt endpoint, ignore it and continue the loop.
|
||||||
|
test [edx+endpoint_descr.bEndpointAddress], 80h
|
||||||
|
jz .lookep
|
||||||
|
mov cl, [edx+endpoint_descr.bmAttributes]
|
||||||
|
and cl, 3
|
||||||
|
cmp cl, INTERRUPT_PIPE
|
||||||
|
jnz .lookep
|
||||||
|
; 5c. Store the pointer in usb_device_data structure for futher references.
|
||||||
|
mov [ebx+usb_device_data.epdescr], edx
|
||||||
|
; 5d. Check that HID descriptor was found. If not, go to 6.
|
||||||
|
cmp [ebx+usb_device_data.hiddescr], 0
|
||||||
|
jz .cfgerror
|
||||||
|
.descriptors_found:
|
||||||
|
; 6. Configuration descriptor seems to be ok.
|
||||||
|
; Send SET_IDLE command disabling auto-repeat feature (it is quite useless)
|
||||||
|
; and continue configuring in SET_IDLE callback.
|
||||||
|
lea edx, [ebx+usb_device_data.control]
|
||||||
|
mov eax, [.interface]
|
||||||
|
mov dword [edx], 21h + \ ; Class-specific request to Interface
|
||||||
|
(0Ah shl 8) + \ ; SET_IDLE
|
||||||
|
(0 shl 16) + \ ; apply to all input reports
|
||||||
|
(0 shl 24) ; disable auto-repeat
|
||||||
|
movzx eax, [eax+interface_descr.bInterfaceNumber]
|
||||||
|
mov [ebx+usb_device_data.interface_number], eax
|
||||||
|
mov [edx+4], eax ; set interface number, zero length
|
||||||
|
mov eax, [.config_pipe]
|
||||||
|
mov [ebx+usb_device_data.configpipe], eax
|
||||||
|
xor ecx, ecx
|
||||||
|
stdcall USBControlTransferAsync, eax, edx, ecx, ecx, idle_set, ebx, ecx
|
||||||
|
; 7. Return pointer to usb_device_data.
|
||||||
|
xchg eax, ebx
|
||||||
|
jmp .nothing
|
||||||
|
endp
|
||||||
|
|
||||||
|
; This procedure is called by USB stack when SET_IDLE request initiated by
|
||||||
|
; AddDevice is completed, either successfully or unsuccessfully.
|
||||||
|
proc idle_set
|
||||||
|
push ebx esi ; save used registers to be stdcall
|
||||||
|
virtual at esp
|
||||||
|
rd 2 ; saved registers
|
||||||
|
dd ? ; return address
|
||||||
|
.pipe dd ?
|
||||||
|
.status dd ?
|
||||||
|
.buffer dd ?
|
||||||
|
.length dd ?
|
||||||
|
.calldata dd ?
|
||||||
|
end virtual
|
||||||
|
; Ignore status. Support for SET_IDLE is optional, so the device is free to
|
||||||
|
; STALL the request; config pipe should remain functional without explicit cleanup.
|
||||||
|
mov ebx, [.calldata]
|
||||||
|
; 1. HID descriptor contains length of Report descriptor. Parse it.
|
||||||
|
mov esi, [ebx+usb_device_data.hiddescr]
|
||||||
|
movzx ecx, [esi+hid_descr.bNumDescriptors]
|
||||||
|
lea eax, [hid_descr.base_sizeof+ecx*3]
|
||||||
|
cmp eax, 100h
|
||||||
|
jae .cfgerror
|
||||||
|
cmp al, [esi+hid_descr.bLength]
|
||||||
|
jb .cfgerror
|
||||||
|
.look_report:
|
||||||
|
dec ecx
|
||||||
|
js .cfgerror
|
||||||
|
cmp [esi+hid_descr.subDescriptorType], REPORT_DESCR_TYPE
|
||||||
|
jz .found_report
|
||||||
|
add esi, 3
|
||||||
|
jmp .look_report
|
||||||
|
.cfgerror:
|
||||||
|
mov esi, invalid_config_descr_msg
|
||||||
|
.abort_with_msg:
|
||||||
|
call SysMsgBoardStr
|
||||||
|
jmp .nothing
|
||||||
|
.found_report:
|
||||||
|
; 2. Send request for the Report descriptor.
|
||||||
|
; 2a. Allocate memory.
|
||||||
|
movzx eax, [esi+hid_descr.subDescriptorLength]
|
||||||
|
test eax, eax
|
||||||
|
jz .cfgerror
|
||||||
|
push eax
|
||||||
|
call Kmalloc
|
||||||
|
pop ecx
|
||||||
|
; If failed, say a message and stop initialization.
|
||||||
|
mov esi, nomemory_msg
|
||||||
|
test eax, eax
|
||||||
|
jz .abort_with_msg
|
||||||
|
; 2b. Submit the request.
|
||||||
|
xchg eax, esi
|
||||||
|
lea edx, [ebx+usb_device_data.control]
|
||||||
|
mov eax, [ebx+usb_device_data.interface_number]
|
||||||
|
mov dword [edx], 81h + \ ; Standard request to Interface
|
||||||
|
(6 shl 8) + \ ; GET_DESCRIPTOR
|
||||||
|
(0 shl 16) + \ ; descriptor index: there is only one report descriptor
|
||||||
|
(REPORT_DESCR_TYPE shl 24); descriptor type
|
||||||
|
mov [edx+4], ax ; Interface number
|
||||||
|
mov [edx+6], cx ; descriptor length
|
||||||
|
stdcall USBControlTransferAsync, [ebx+usb_device_data.configpipe], \
|
||||||
|
edx, esi, ecx, got_report, ebx, 0
|
||||||
|
; 2c. If failed, free the buffer and stop initialization.
|
||||||
|
test eax, eax
|
||||||
|
jnz .nothing
|
||||||
|
xchg eax, esi
|
||||||
|
call Kfree
|
||||||
|
.nothing:
|
||||||
|
pop esi ebx ; restore used registers to be stdcall
|
||||||
|
ret 20
|
||||||
|
endp
|
||||||
|
|
||||||
|
; This procedure is called by USB stack when the report descriptor queried
|
||||||
|
; by idle_set is completed, either successfully or unsuccessfully.
|
||||||
|
proc got_report stdcall uses ebx esi edi, pipe, status, buffer, length, calldata
|
||||||
|
locals
|
||||||
|
parse_descr_locals
|
||||||
|
if ~HID_DUMP_UNCLAIMED
|
||||||
|
has_driver db ?
|
||||||
|
rb 3
|
||||||
|
end if
|
||||||
|
endl
|
||||||
|
; 1. Check the status; if the request has failed, say something to the debug board
|
||||||
|
; and stop initialization.
|
||||||
|
cmp [status], 0
|
||||||
|
jnz .generic_fail
|
||||||
|
; 2. Subtract size of setup packet from the total length;
|
||||||
|
; the rest is length of the descriptor, and it must be nonzero.
|
||||||
|
sub [length], 8
|
||||||
|
ja .has_something
|
||||||
|
.generic_fail:
|
||||||
|
push esi
|
||||||
|
mov esi, reportfail
|
||||||
|
call SysMsgBoardStr
|
||||||
|
pop esi
|
||||||
|
jmp .exit
|
||||||
|
.has_something:
|
||||||
|
; 3. Process descriptor.
|
||||||
|
; 3a. Dump it to the debug board, if enabled in compile-time setting.
|
||||||
|
if USB_DUMP_DESCRIPTORS
|
||||||
|
mov eax, [buffer]
|
||||||
|
mov ecx, [length]
|
||||||
|
DEBUGF 1,'K : report descriptor:'
|
||||||
|
@@:
|
||||||
|
DEBUGF 1,' %x',[eax]:2
|
||||||
|
inc eax
|
||||||
|
dec ecx
|
||||||
|
jnz @b
|
||||||
|
DEBUGF 1,'\n'
|
||||||
|
end if
|
||||||
|
; 3b. Call the HID layer.
|
||||||
|
parse_descr
|
||||||
|
cmp [report_ok], 0
|
||||||
|
jz got_report.exit
|
||||||
|
mov ebx, [calldata]
|
||||||
|
postprocess_descr
|
||||||
|
; 4. Stop initialization if no driver is assigned.
|
||||||
|
if ~HID_DUMP_UNCLAIMED
|
||||||
|
cmp [has_driver], 0
|
||||||
|
jz got_report.exit
|
||||||
|
end if
|
||||||
|
; 5. Open interrupt IN pipe. If failed, stop initialization.
|
||||||
|
mov edx, [ebx+usb_device_data.epdescr]
|
||||||
|
movzx ecx, [edx+endpoint_descr.bEndpointAddress]
|
||||||
|
movzx eax, [edx+endpoint_descr.bInterval]
|
||||||
|
movzx edx, [edx+endpoint_descr.wMaxPacketSize]
|
||||||
|
stdcall USBOpenPipe, [ebx+usb_device_data.configpipe], ecx, edx, INTERRUPT_PIPE, eax
|
||||||
|
test eax, eax
|
||||||
|
jz got_report.exit
|
||||||
|
mov [ebx+usb_device_data.intpipe], eax
|
||||||
|
; 6. Initialize buffer for input packet.
|
||||||
|
; 6a. Find the length of input packet.
|
||||||
|
; This is the maximal length of all input reports.
|
||||||
|
mov edx, [ebx+usb_device_data.hid.input.first_report]
|
||||||
|
xor eax, eax
|
||||||
|
.find_input_size:
|
||||||
|
test edx, edx
|
||||||
|
jz .found_input_size
|
||||||
|
cmp eax, [edx+report.size]
|
||||||
|
jae @f
|
||||||
|
mov eax, [edx+report.size]
|
||||||
|
@@:
|
||||||
|
mov edx, [edx+report.next]
|
||||||
|
jmp .find_input_size
|
||||||
|
.found_input_size:
|
||||||
|
; report.size is in bits, transform it to bytes
|
||||||
|
add eax, 7
|
||||||
|
shr eax, 3
|
||||||
|
; if reports are numbered, the first byte is report ID, include it
|
||||||
|
cmp [ebx+usb_device_data.hid.input.numbered], 0
|
||||||
|
jz @f
|
||||||
|
inc eax
|
||||||
|
@@:
|
||||||
|
mov [ebx+usb_device_data.input_transfer_size], eax
|
||||||
|
; 6b. Allocate memory for input packet: dword-align and add additional dword
|
||||||
|
; for extract_field_value.
|
||||||
|
add eax, 4+3
|
||||||
|
and eax, not 3
|
||||||
|
call Kmalloc
|
||||||
|
test eax, eax
|
||||||
|
jnz @f
|
||||||
|
mov esi, nomemory_msg
|
||||||
|
call SysMsgBoardStr
|
||||||
|
jmp got_report.exit
|
||||||
|
@@:
|
||||||
|
mov [ebx+usb_device_data.input_buffer], eax
|
||||||
|
; 7. Submit a request for input packet and wait for input.
|
||||||
|
call ask_for_input
|
||||||
|
got_report.exit:
|
||||||
|
mov eax, [buffer]
|
||||||
|
call Kfree
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
; Helper procedure for got_report and got_input.
|
||||||
|
; Submits a request for the next input packet.
|
||||||
|
proc ask_for_input
|
||||||
|
; just call USBNormalTransferAsync with correct parameters,
|
||||||
|
; allow short packets
|
||||||
|
stdcall USBNormalTransferAsync, \
|
||||||
|
[ebx+usb_device_data.intpipe], \
|
||||||
|
[ebx+usb_device_data.input_buffer], \
|
||||||
|
[ebx+usb_device_data.input_transfer_size], \
|
||||||
|
got_input, ebx, \
|
||||||
|
1
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
; This procedure is called by USB stack when a HID device responds with input
|
||||||
|
; data packet.
|
||||||
|
proc got_input stdcall uses ebx esi edi, pipe, status, buffer, length, calldata
|
||||||
|
locals
|
||||||
|
parse_input_locals
|
||||||
|
endl
|
||||||
|
; 1. Validate parameters: fail on error, ignore zero-length transfers.
|
||||||
|
mov ebx, [calldata]
|
||||||
|
cmp [status], 0
|
||||||
|
jnz .fail
|
||||||
|
cmp [length], 0
|
||||||
|
jz .done
|
||||||
|
; 2. Get pointer to report in esi.
|
||||||
|
; 2a. If there are no report IDs, use hid.input.data.
|
||||||
|
mov eax, [buffer]
|
||||||
|
mov esi, [ebx+usb_device_data.hid.input.data]
|
||||||
|
cmp [ebx+usb_device_data.hid.input.numbered], 0
|
||||||
|
jz .report_found
|
||||||
|
; 2b. Otherwise, the first byte of report is report ID;
|
||||||
|
; locate the report by its ID, advance buffer+length to one byte.
|
||||||
|
movzx eax, byte [eax]
|
||||||
|
mov esi, [esi+eax*4]
|
||||||
|
inc [buffer]
|
||||||
|
dec [length]
|
||||||
|
.report_found:
|
||||||
|
; 3. Validate: ignore transfers with unregistered report IDs
|
||||||
|
; and transfers which are too short for the corresponding report.
|
||||||
|
test esi, esi
|
||||||
|
jz .done
|
||||||
|
mov eax, [esi+report.size]
|
||||||
|
add eax, 7
|
||||||
|
shr eax, 3
|
||||||
|
cmp eax, [length]
|
||||||
|
ja .done
|
||||||
|
; 4. Pass everything to HID layer.
|
||||||
|
parse_input
|
||||||
|
.done:
|
||||||
|
; 5. Query the next input.
|
||||||
|
mov ebx, [calldata]
|
||||||
|
call ask_for_input
|
||||||
|
.nothing:
|
||||||
|
ret
|
||||||
|
.fail:
|
||||||
|
mov esi, transfer_error_msg
|
||||||
|
call SysMsgBoardStr
|
||||||
|
jmp .nothing
|
||||||
|
endp
|
||||||
|
|
||||||
|
; This function is called by the USB subsystem when a device is disconnected.
|
||||||
|
proc DeviceDisconnected
|
||||||
|
push ebx esi edi ; save used registers to be stdcall
|
||||||
|
virtual at esp
|
||||||
|
rd 3 ; saved registers
|
||||||
|
dd ? ; return address
|
||||||
|
.device_data dd ?
|
||||||
|
end virtual
|
||||||
|
; 1. Say a message.
|
||||||
|
mov ebx, [.device_data]
|
||||||
|
mov esi, disconnectmsg
|
||||||
|
stdcall SysMsgBoardStr
|
||||||
|
; 2. Ask HID layer to release all HID-related resources.
|
||||||
|
hid_cleanup
|
||||||
|
; 3. Free the device data.
|
||||||
|
xchg eax, ebx
|
||||||
|
call Kfree
|
||||||
|
; 4. Return.
|
||||||
|
.nothing:
|
||||||
|
pop edi esi ebx ; restore used registers to be stdcall
|
||||||
|
ret 4 ; purge one dword argument to be stdcall
|
||||||
|
endp
|
||||||
|
|
||||||
|
include 'sort.inc'
|
||||||
|
include 'unclaimed.inc'
|
||||||
|
include 'mouse.inc'
|
||||||
|
include 'keyboard.inc'
|
||||||
|
|
||||||
|
; strings
|
||||||
|
my_driver db 'usbhid',0
|
||||||
|
nomemory_msg db 'K : no memory',13,10,0
|
||||||
|
invalid_config_descr_msg db 'K : invalid config descriptor',13,10,0
|
||||||
|
reportfail db 'K : failed to read report descriptor',13,10,0
|
||||||
|
transfer_error_msg db 'K : USB transfer error, disabling HID device',13,10,0
|
||||||
|
disconnectmsg db 'K : USB HID device disconnected',13,10,0
|
||||||
|
invalid_report_msg db 'K : report descriptor is invalid',13,10,0
|
||||||
|
delimiter_note db 'K : note: alternate usage ignored',13,10,0
|
||||||
|
|
||||||
|
; Exported variable: kernel API version.
|
||||||
|
align 4
|
||||||
|
version dd 50005h
|
||||||
|
; Structure with callback functions.
|
||||||
|
usb_functions:
|
||||||
|
dd 12
|
||||||
|
dd AddDevice
|
||||||
|
dd DeviceDisconnected
|
||||||
|
|
||||||
|
; for DEBUGF macro
|
||||||
|
include_debug_strings
|
||||||
|
|
||||||
|
; Workers data
|
||||||
|
workers_globals
|
||||||
|
|
||||||
|
; for uninitialized data
|
||||||
|
;section '.data' data readable writable align 16
|
438
kernel/branches/Kolibri-acpi/drivers/vidrdc.asm
Normal file
438
kernel/branches/Kolibri-acpi/drivers/vidrdc.asm
Normal file
@ -0,0 +1,438 @@
|
|||||||
|
; Stub of videodriver for RDC Semiconductor Co. M2010/M2012 videocards (controller names: R3306/R3308).
|
||||||
|
; It is used in SoC produced by DMP Electronics Inc.:
|
||||||
|
; Vortex86MX (contains RDC M2010 graphics card, appears in eBox-3300MX)
|
||||||
|
; Vortex86MX+ (contains RDC M2012 graphics card, appears in eBox-3310MX)
|
||||||
|
; Link to manufacturers websites -
|
||||||
|
; RDC Semiconductor Co.: http://www.rdc.com.tw
|
||||||
|
; DM&P Electronics Inc.: http://www.dmp.com.tw and http://www.compactpc.com.tw
|
||||||
|
; Code stolen from vidintel.asm driver (c) by CleverMouse and adapted for RDC.
|
||||||
|
|
||||||
|
; When the start procedure gets control,
|
||||||
|
; it tries to detect preferred resolution,
|
||||||
|
; sets the detected resolution assuming 32-bpp VESA mode and exits
|
||||||
|
; (without registering a service).
|
||||||
|
; Detection can be overloaded with compile-time settings
|
||||||
|
; use_predefined_mode/predefined_width/predefined_height.
|
||||||
|
|
||||||
|
; set predefined resolution here
|
||||||
|
use_predefined_mode = 0;1
|
||||||
|
predefined_width = 0;1366
|
||||||
|
predefined_height = 0;768
|
||||||
|
|
||||||
|
; standard driver stuff
|
||||||
|
format MS COFF
|
||||||
|
|
||||||
|
DEBUG = 1
|
||||||
|
|
||||||
|
include 'proc32.inc'
|
||||||
|
include 'imports.inc'
|
||||||
|
|
||||||
|
public START
|
||||||
|
public version
|
||||||
|
|
||||||
|
section '.flat' code readable align 16
|
||||||
|
; the start procedure (see the description above)
|
||||||
|
START:
|
||||||
|
; 1. Detect device. Abort if not found.
|
||||||
|
push esi
|
||||||
|
call DetectDevice
|
||||||
|
test esi, esi
|
||||||
|
jz .return0
|
||||||
|
|
||||||
|
;{START}yogev_ezra: temporary exit after detection
|
||||||
|
pusha
|
||||||
|
mov esi, exitmsg
|
||||||
|
call SysMsgBoardStr
|
||||||
|
popa
|
||||||
|
jmp .return0
|
||||||
|
;{END}yogev_ezra: temporary exit after detection
|
||||||
|
|
||||||
|
; 2. Detect optimal mode unless the mode is given explicitly. Abort if failed.
|
||||||
|
if use_predefined_mode = 0
|
||||||
|
call DetectMode
|
||||||
|
end if
|
||||||
|
cmp [width], 0
|
||||||
|
jz .return0_cleanup
|
||||||
|
; 3. Set the detected mode.
|
||||||
|
call SetMode
|
||||||
|
; 4. Cleanup and return.
|
||||||
|
.return0_cleanup:
|
||||||
|
stdcall FreeKernelSpace, esi
|
||||||
|
.return0:
|
||||||
|
pop esi
|
||||||
|
xor eax, eax
|
||||||
|
ret 4
|
||||||
|
|
||||||
|
; check that there is RDC videocard
|
||||||
|
; if so, map MMIO registers and set internal variables
|
||||||
|
; esi points to MMIO block; NULL means no device
|
||||||
|
DetectDevice:
|
||||||
|
; 1. Sanity check: check that we are dealing with RDC videocard.
|
||||||
|
; Integrated video device for RDC is always at PCI:0:13:0 (bus:dev:fn=0:0d:0)
|
||||||
|
xor esi, esi ; initialize return value to NULL
|
||||||
|
; 1a. Get PCI VendorID and DeviceID.
|
||||||
|
push esi ; in: reg=0 (register) -> register 00 means return DeviceID (bits 16-31) + VendorID (bits 0-15)
|
||||||
|
push 68h ; in: devfn=13:0 | device:5bit (0Dh = 1101) + func:3bit (0 = 000) -> total:1byte (1101000b = 68h)
|
||||||
|
push esi ; in: bus=0
|
||||||
|
call PciRead32
|
||||||
|
; 1b. loword(eax) = ax = VendorID, hiword(eax) = DeviceID.
|
||||||
|
; Test whether we have RDC Semiconductor Co. chipset.
|
||||||
|
cmp ax, 17F3h ;VendorID 0x17F3, 'RDC Semiconductor Co.'
|
||||||
|
jnz .return
|
||||||
|
; 1c. Say hi including DeviceID.
|
||||||
|
shr eax, 10h ; now, ax = HIWORD(eax) = PCI DeviceID
|
||||||
|
push edi
|
||||||
|
pusha
|
||||||
|
mov edi, pciid_text ; edi='0000'
|
||||||
|
call WriteWord
|
||||||
|
mov esi, hellomsg
|
||||||
|
call SysMsgBoardStr
|
||||||
|
popa
|
||||||
|
; 1d. Test whether we know this DeviceID.
|
||||||
|
; If this is the case, remember the position of the device in line of RDC cards;
|
||||||
|
; this knowledge will be useful later.
|
||||||
|
; Tested on devices with id: 17F3:2010, 17F3:2012.
|
||||||
|
mov ecx, pciids_num
|
||||||
|
mov edi, pciids
|
||||||
|
repnz scasw
|
||||||
|
pop edi
|
||||||
|
jnz .return_unknown_pciid
|
||||||
|
sub ecx, pciids_num - 1
|
||||||
|
neg ecx
|
||||||
|
mov [deviceType], ecx
|
||||||
|
; 1e. Continue saying hi with positive intonation.
|
||||||
|
pusha
|
||||||
|
mov esi, knownmsg
|
||||||
|
call SysMsgBoardStr
|
||||||
|
popa
|
||||||
|
; 2. Prepare MMIO region to control the card.
|
||||||
|
; 2a. Read MMIO physical address from PCI config space.
|
||||||
|
; According to RDC M2010/M2012 registers manual, their memory-mapped I/O space is located at Base address #1
|
||||||
|
push 14h ; in: reg=14h (register) -> register 14h means Base address #1 (BAR1) in PCI configuration space
|
||||||
|
push 68h ; in: devfn=13:0 | device:5bit (0Dh = 1101) + func:3bit (0 = 000) -> total:1byte (1101000b = 68h)
|
||||||
|
push esi ; in: bus=0
|
||||||
|
call PciRead32
|
||||||
|
; 2b. Mask out PCI region type, lower 4 bits.
|
||||||
|
and al, not 0xF
|
||||||
|
; 2c. Create virtual mapping of the physical memory.
|
||||||
|
push 1Bh
|
||||||
|
push 100000h
|
||||||
|
push eax
|
||||||
|
call MapIoMem
|
||||||
|
; 3. Return.
|
||||||
|
xchg esi, eax
|
||||||
|
.return:
|
||||||
|
ret
|
||||||
|
; 1f. If we do not know DeviceID, continue saying hi with negative intonation.
|
||||||
|
.return_unknown_pciid:
|
||||||
|
pusha
|
||||||
|
mov esi, unknownmsg
|
||||||
|
call SysMsgBoardStr
|
||||||
|
popa
|
||||||
|
ret
|
||||||
|
|
||||||
|
; Convert word in ax to hexadecimal text in edi, advance edi.
|
||||||
|
WriteWord:
|
||||||
|
; 1. Convert high byte.
|
||||||
|
push eax
|
||||||
|
mov al, ah
|
||||||
|
call WriteByte
|
||||||
|
pop eax
|
||||||
|
; 2. Convert low byte.
|
||||||
|
; Fall through to WriteByte; ret from WriteByte is ret from WriteWord too.
|
||||||
|
|
||||||
|
; Convert byte in al to hexadecimal text in edi, advance edi.
|
||||||
|
WriteByte:
|
||||||
|
; 1. Convert high nibble.
|
||||||
|
push eax
|
||||||
|
shr al, 4
|
||||||
|
call WriteNibble
|
||||||
|
pop eax
|
||||||
|
; 2. Convert low nibble.
|
||||||
|
and al, 0xF
|
||||||
|
; Fall through to WriteNibble; ret from WriteNibble is ret from WriteByte too.
|
||||||
|
|
||||||
|
; Convert nibble in al to hexadecimal text in edi, advance edi.
|
||||||
|
WriteNibble:
|
||||||
|
; Obvious, isn't it?
|
||||||
|
cmp al, 10
|
||||||
|
sbb al, 69h
|
||||||
|
das
|
||||||
|
stosb ; This instruction uses EDI implicitly
|
||||||
|
ret
|
||||||
|
|
||||||
|
if use_predefined_mode = 0
|
||||||
|
; detect resolution of the flat panel
|
||||||
|
DetectMode:
|
||||||
|
push esi edi
|
||||||
|
; 1. Get the location of block of GMBUS* registers.
|
||||||
|
; Starting with Ironlake, GMBUS* registers were moved.
|
||||||
|
add esi, 5100h
|
||||||
|
cmp [deviceType], pciids_num ;ironlake_start
|
||||||
|
jb @f
|
||||||
|
add esi, 0xC0000
|
||||||
|
@@:
|
||||||
|
; 2. Initialize GMBUS engine.
|
||||||
|
mov edi, edid
|
||||||
|
mov ecx, 0x10000
|
||||||
|
@@:
|
||||||
|
test byte [esi+8+1], 80h
|
||||||
|
loopnz @b
|
||||||
|
jnz .fail
|
||||||
|
mov dword [esi], 3
|
||||||
|
test byte [esi+8+1], 4
|
||||||
|
jz .noreset
|
||||||
|
call ResetGMBus
|
||||||
|
jnz .fail
|
||||||
|
.noreset:
|
||||||
|
; 3. Send read command.
|
||||||
|
and dword [esi+20h], 0
|
||||||
|
mov dword [esi+4], 4E8000A1h
|
||||||
|
; 4. Wait for data, writing to the buffer as data arrive.
|
||||||
|
.getdata:
|
||||||
|
mov ecx, 0x10000
|
||||||
|
@@:
|
||||||
|
test byte [esi+8+1], 8
|
||||||
|
loopz @b
|
||||||
|
test byte [esi+8+1], 4
|
||||||
|
jz .dataok
|
||||||
|
call ResetGMBus
|
||||||
|
jmp .fail
|
||||||
|
.dataok:
|
||||||
|
mov eax, [esi+0Ch]
|
||||||
|
stosd
|
||||||
|
cmp edi, edid+80h
|
||||||
|
jb .getdata
|
||||||
|
; 5. Wait for bus idle.
|
||||||
|
mov ecx, 0x10000
|
||||||
|
@@:
|
||||||
|
test byte [esi+8+1], 2
|
||||||
|
loopnz @b
|
||||||
|
; 6. We got EDID; dump it if DEBUG.
|
||||||
|
if DEBUG
|
||||||
|
pusha
|
||||||
|
xor ecx, ecx
|
||||||
|
mov esi, edid
|
||||||
|
mov edi, edid_text
|
||||||
|
.dumploop:
|
||||||
|
lodsb
|
||||||
|
call WriteByte
|
||||||
|
mov al, ' '
|
||||||
|
stosb
|
||||||
|
inc cl
|
||||||
|
test cl, 15
|
||||||
|
jnz @f
|
||||||
|
mov byte [edi-1], 13
|
||||||
|
mov al, 10
|
||||||
|
stosb
|
||||||
|
@@:
|
||||||
|
test cl, cl
|
||||||
|
jns .dumploop
|
||||||
|
mov esi, edidmsg
|
||||||
|
call SysMsgBoardStr
|
||||||
|
popa
|
||||||
|
end if
|
||||||
|
; 7. Test whether EDID is good.
|
||||||
|
; 7a. Signature: 00 FF FF FF FF FF FF 00.
|
||||||
|
mov esi, edid
|
||||||
|
cmp dword [esi], 0xFFFFFF00
|
||||||
|
jnz .fail
|
||||||
|
cmp dword [esi+4], 0x00FFFFFF
|
||||||
|
jnz .fail
|
||||||
|
; 7b. Checksum must be zero.
|
||||||
|
xor edx, edx
|
||||||
|
mov ecx, 80h
|
||||||
|
@@:
|
||||||
|
lodsb
|
||||||
|
add dl, al
|
||||||
|
loop @b
|
||||||
|
jnz .fail
|
||||||
|
; 8. Get width and height from EDID.
|
||||||
|
xor eax, eax
|
||||||
|
mov ah, [esi-80h+3Ah]
|
||||||
|
shr ah, 4
|
||||||
|
mov al, [esi-80h+38h]
|
||||||
|
mov [width], eax
|
||||||
|
mov ah, [esi-80h+3Dh]
|
||||||
|
shr ah, 4
|
||||||
|
mov al, [esi-80h+3Bh]
|
||||||
|
mov [height], eax
|
||||||
|
; 9. Return.
|
||||||
|
.fail:
|
||||||
|
pop edi esi
|
||||||
|
ret
|
||||||
|
|
||||||
|
; reset bus, clear all errors
|
||||||
|
ResetGMBus:
|
||||||
|
; look into the PRM
|
||||||
|
mov dword [esi+4], 80000000h
|
||||||
|
mov dword [esi+4], 0
|
||||||
|
mov ecx, 0x10000
|
||||||
|
@@:
|
||||||
|
test byte [esi+8+1], 2
|
||||||
|
loopnz @b
|
||||||
|
ret
|
||||||
|
end if
|
||||||
|
|
||||||
|
; set resolution [width]*[height]
|
||||||
|
SetMode:
|
||||||
|
; 1. Program the registers of videocard.
|
||||||
|
; look into the PRM
|
||||||
|
cli
|
||||||
|
; or byte [esi+7000Ah], 0Ch ; PIPEACONF: disable Display+Cursor Planes
|
||||||
|
; or byte [esi+7100Ah], 0Ch ; PIPEBCONF: disable Display+Cursor Planes
|
||||||
|
xor eax, eax
|
||||||
|
xor edx, edx
|
||||||
|
cmp [deviceType], pciids_num ;i965_start
|
||||||
|
jb @f
|
||||||
|
mov dl, 9Ch - 84h
|
||||||
|
@@:
|
||||||
|
; or byte [esi+71403h], 80h ; VGACNTRL: VGA Display Disable
|
||||||
|
and byte [esi+70080h], not 27h ; CURACNTR: disable cursor A
|
||||||
|
mov dword [esi+70084h], eax ; CURABASE: force write to CURA* regs
|
||||||
|
and byte [esi+700C0h], not 27h ; CURBCNTR: disable cursor B
|
||||||
|
mov dword [esi+700C4h], eax ; CURBBASE: force write to CURB* regs
|
||||||
|
and byte [esi+70183h], not 80h ; DSPACNTR: disable Primary A Plane
|
||||||
|
mov dword [esi+edx+70184h], eax ; DSPALINOFF/DSPASURF: force write to DSPA* regs
|
||||||
|
and byte [esi+71183h], not 80h ; DSPBCNTR: disable Primary B Plane
|
||||||
|
mov dword [esi+edx+71184h], eax ; DSPBLINOFF/DSPBSURF: force write to DSPB* regs
|
||||||
|
if 1
|
||||||
|
cmp [deviceType], pciids_num ;ironlake_start
|
||||||
|
jae .disable_pipes
|
||||||
|
mov edx, 10000h
|
||||||
|
or byte [esi+70024h], 2 ; PIPEASTAT: clear VBLANK status
|
||||||
|
or byte [esi+71024h], 2 ; PIPEBSTAT: clear VBLANK status
|
||||||
|
.wait_vblank_preironlake1:
|
||||||
|
mov ecx, 1000h
|
||||||
|
loop $
|
||||||
|
test byte [esi+7000Bh], 80h ; PIPEACONF: pipe A active?
|
||||||
|
jz @f
|
||||||
|
test byte [esi+70024h], 2 ; PIPEASTAT: got VBLANK?
|
||||||
|
jz .wait_vblank_preironlake2
|
||||||
|
@@:
|
||||||
|
test byte [esi+7100Bh], 80h ; PIPEBCONF: pipe B active?
|
||||||
|
jz .disable_pipes
|
||||||
|
test byte [esi+71024h], 2 ; PIPEBSTAT: got VBLANK?
|
||||||
|
jnz .disable_pipes
|
||||||
|
.wait_vblank_preironlake2:
|
||||||
|
dec edx
|
||||||
|
jnz .wait_vblank_preironlake1
|
||||||
|
jmp .not_disabled
|
||||||
|
.disable_pipes:
|
||||||
|
end if
|
||||||
|
and byte [esi+7000Bh], not 80h ; PIPEACONF: disable pipe
|
||||||
|
and byte [esi+7100Bh], not 80h ; PIPEBCONF: disable pipe
|
||||||
|
cmp [deviceType], pciids_num ;gen4_start
|
||||||
|
jb .wait_watching_scanline
|
||||||
|
; g45 and later: use special flag from PIPE*CONF
|
||||||
|
mov edx, 10000h
|
||||||
|
@@:
|
||||||
|
mov ecx, 1000h
|
||||||
|
loop $
|
||||||
|
test byte [esi+7000Bh], 40h ; PIPEACONF: wait until pipe disabled
|
||||||
|
jz @f
|
||||||
|
dec edx
|
||||||
|
jnz @b
|
||||||
|
jmp .not_disabled
|
||||||
|
@@:
|
||||||
|
test byte [esi+7100Bh], 40h ; PIPEBCONF: wait until pipe disabled
|
||||||
|
jz .disabled
|
||||||
|
mov ecx, 1000h
|
||||||
|
loop $
|
||||||
|
dec edx
|
||||||
|
jnz @b
|
||||||
|
jmp .not_disabled
|
||||||
|
; pineview and before: wait while scanline still changes
|
||||||
|
.wait_watching_scanline:
|
||||||
|
mov edx, 1000h
|
||||||
|
.dis1:
|
||||||
|
push dword [esi+71000h]
|
||||||
|
push dword [esi+70000h]
|
||||||
|
mov ecx, 10000h
|
||||||
|
loop $
|
||||||
|
pop eax
|
||||||
|
xor eax, [esi+70000h]
|
||||||
|
and eax, 1FFFh
|
||||||
|
pop eax
|
||||||
|
jnz .notdis1
|
||||||
|
xor eax, [esi+71000h]
|
||||||
|
and eax, 1FFFh
|
||||||
|
jz .disabled
|
||||||
|
.notdis1:
|
||||||
|
dec edx
|
||||||
|
jnz .dis1
|
||||||
|
.not_disabled:
|
||||||
|
sti
|
||||||
|
jmp .return
|
||||||
|
.disabled:
|
||||||
|
lea eax, [esi+61183h]
|
||||||
|
cmp [deviceType], pciids_num ;ironlake_start
|
||||||
|
jb @f
|
||||||
|
add eax, 0xE0000 - 0x60000
|
||||||
|
@@:
|
||||||
|
lea edx, [esi+60000h]
|
||||||
|
test byte [eax], 40h
|
||||||
|
jz @f
|
||||||
|
add edx, 1000h
|
||||||
|
@@:
|
||||||
|
mov eax, [width]
|
||||||
|
dec eax
|
||||||
|
shl eax, 16
|
||||||
|
mov ax, word [height]
|
||||||
|
dec eax
|
||||||
|
mov dword [edx+1Ch], eax ; PIPEASRC: set source image size
|
||||||
|
ror eax, 16
|
||||||
|
mov dword [edx+10190h], eax ; for old cards
|
||||||
|
mov ecx, [width]
|
||||||
|
add ecx, 15
|
||||||
|
and ecx, not 15
|
||||||
|
shl ecx, 2
|
||||||
|
mov dword [edx+10188h], ecx ; DSPASTRIDE: set scanline length
|
||||||
|
mov dword [edx+10184h], 0 ; DSPALINOFF: force write to DSPA* registers
|
||||||
|
and byte [esi+61233h], not 80h ; PFIT_CONTROL: disable panel fitting
|
||||||
|
or byte [edx+1000Bh], 80h ; PIPEACONF: enable pipe
|
||||||
|
; and byte [edx+1000Ah], not 0Ch ; PIPEACONF: enable Display+Cursor Planes
|
||||||
|
or byte [edx+10183h], 80h ; DSPACNTR: enable Display Plane A
|
||||||
|
sti
|
||||||
|
; 2. Notify the kernel that resolution has changed.
|
||||||
|
call GetDisplay
|
||||||
|
mov edx, [width]
|
||||||
|
mov dword [eax+8], edx
|
||||||
|
mov edx, [height]
|
||||||
|
mov dword [eax+0Ch], edx
|
||||||
|
mov [eax+18h], ecx
|
||||||
|
mov eax, [width]
|
||||||
|
dec eax
|
||||||
|
dec edx
|
||||||
|
call SetScreen
|
||||||
|
.return:
|
||||||
|
ret
|
||||||
|
|
||||||
|
align 4
|
||||||
|
hellomsg db 'RDC videocard detected, PciId=17F3:' ;VendorID 0x17F3, 'RDC Semiconductor Co.'
|
||||||
|
pciid_text db '0000'
|
||||||
|
db ', which is ', 0
|
||||||
|
knownmsg db 'known',13,10,0
|
||||||
|
unknownmsg db 'unknown',13,10,0
|
||||||
|
exitmsg db 'Card detected successfully, exiting driver...',13,10,0
|
||||||
|
|
||||||
|
if DEBUG
|
||||||
|
edidmsg db 'EDID successfully read:',13,10
|
||||||
|
edid_text rb 8*(16*3+1)
|
||||||
|
db 0
|
||||||
|
end if
|
||||||
|
|
||||||
|
version:
|
||||||
|
dd 0x50005
|
||||||
|
|
||||||
|
width dd predefined_width
|
||||||
|
height dd predefined_height
|
||||||
|
|
||||||
|
pciids:
|
||||||
|
dw 0x2010 ; M2010 - appears in eBox-3300MX (Vortex86MX SoC)
|
||||||
|
dw 0x2012 ; M2012 - appears in eBox-3310MX (Vortex86MX+ SoC)
|
||||||
|
pciids_num = ($ - pciids) / 2
|
||||||
|
|
||||||
|
align 4
|
||||||
|
deviceType dd ?
|
||||||
|
edid rb 0x80
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,12 +0,0 @@
|
|||||||
dir0:
|
|
||||||
db 'KÕVAKETAS '
|
|
||||||
db 'MÄLUKETAS '
|
|
||||||
db 'FLOPPIKETAS'
|
|
||||||
db 0
|
|
||||||
|
|
||||||
dir1:
|
|
||||||
db 'ESIMENE '
|
|
||||||
db 'TEINE '
|
|
||||||
db 'KOLAMS '
|
|
||||||
db 'NELJAS '
|
|
||||||
db 0
|
|
@ -1,13 +0,0 @@
|
|||||||
dir0:
|
|
||||||
db 'DISCO DURO '
|
|
||||||
db 'UNIDAD RAM '
|
|
||||||
db 'DISQUETE '
|
|
||||||
db 0
|
|
||||||
|
|
||||||
dir1:
|
|
||||||
db 'PRIMERO '
|
|
||||||
db 'SEGUNDO '
|
|
||||||
db 'TERCERO '
|
|
||||||
db 'CUARTO '
|
|
||||||
db 0
|
|
||||||
|
|
@ -1,682 +0,0 @@
|
|||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;; ;;
|
|
||||||
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;;
|
|
||||||
;; Distributed under terms of the GNU General Public License ;;
|
|
||||||
;; ;;
|
|
||||||
;; ;;
|
|
||||||
;; System service for filesystem call ;;
|
|
||||||
;; (C) 2004 Ville Turjanmaa, License: GPL ;;
|
|
||||||
;; 29.04.2006 Elimination of hangup after the ;;
|
|
||||||
;; expiration hd_wait_timeout (for LBA) - Mario79 ;;
|
|
||||||
;; 15.01.2005 get file size/attr/date, ;;
|
|
||||||
;; file_append (only for hd) - ATV ;;
|
|
||||||
;; 23.11.2004 test if hd/partition is set - ATV ;;
|
|
||||||
;; 18.11.2004 get_disk_info and more error codes - ATV ;;
|
|
||||||
;; 08.11.2004 expand_pathz and rename (only for hd) - ATV ;;
|
|
||||||
;; 20.10.2004 Makedir/Removedir (only for hd) - ATV ;;
|
|
||||||
;; ;;
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
|
|
||||||
$Revision$
|
|
||||||
|
|
||||||
|
|
||||||
iglobal
|
|
||||||
|
|
||||||
if lang eq sp
|
|
||||||
include 'fs/fs-sp.inc'
|
|
||||||
else if lang eq et
|
|
||||||
include 'fs/fs-et.inc'
|
|
||||||
else
|
|
||||||
dir0:
|
|
||||||
db 'HARDDISK '
|
|
||||||
db 'RAMDISK '
|
|
||||||
db 'FLOPPYDISK '
|
|
||||||
db 0
|
|
||||||
|
|
||||||
dir1:
|
|
||||||
db 'FIRST '
|
|
||||||
db 'SECOND '
|
|
||||||
db 'THIRD '
|
|
||||||
db 'FOURTH '
|
|
||||||
db 0
|
|
||||||
end if
|
|
||||||
|
|
||||||
not_select_IDE db 0
|
|
||||||
|
|
||||||
hd_address_table:
|
|
||||||
dd 0x1f0,0x00,0x1f0,0x10
|
|
||||||
dd 0x170,0x00,0x170,0x10
|
|
||||||
endg
|
|
||||||
|
|
||||||
file_system:
|
|
||||||
|
|
||||||
; IN:
|
|
||||||
;
|
|
||||||
; eax = 0 ; read file /RamDisk/First 6
|
|
||||||
; eax = 8 ; lba read
|
|
||||||
; eax = 15 ; get_disk_info
|
|
||||||
;
|
|
||||||
; OUT:
|
|
||||||
;
|
|
||||||
; eax = 0 : read ok
|
|
||||||
; eax = 1 : no hd base and/or partition defined
|
|
||||||
; eax = 2 : function is unsupported for this FS
|
|
||||||
; eax = 3 : unknown FS
|
|
||||||
; eax = 4 : partition not defined at hd
|
|
||||||
; eax = 5 : file not found
|
|
||||||
; eax = 6 : end of file
|
|
||||||
; eax = 7 : memory pointer not in application area
|
|
||||||
; eax = 8 : disk full
|
|
||||||
; eax = 9 : fat table corrupted
|
|
||||||
; eax = 10 : access denied
|
|
||||||
; eax = 11 : disk error
|
|
||||||
;
|
|
||||||
; ebx = size
|
|
||||||
|
|
||||||
; \begin{diamond}[18.03.2006]
|
|
||||||
; for subfunction 16 (start application) error codes must be negative
|
|
||||||
; because positive values are valid PIDs
|
|
||||||
; so possible return values are:
|
|
||||||
; eax > 0 : process created, eax=PID
|
|
||||||
|
|
||||||
; -0x10 <= eax < 0 : -eax is filesystem error code:
|
|
||||||
; eax = -1 = 0xFFFFFFFF : no hd base and/or partition defined
|
|
||||||
; eax = -3 = 0xFFFFFFFD : unknown FS
|
|
||||||
; eax = -5 = 0xFFFFFFFB : file not found
|
|
||||||
; eax = -6 = 0xFFFFFFFA : unexpected end of file (probably not executable file)
|
|
||||||
; eax = -9 = 0xFFFFFFF7 : fat table corrupted
|
|
||||||
; eax = -10 = 0xFFFFFFF6 : access denied
|
|
||||||
|
|
||||||
; -0x20 <= eax < -0x10: eax is process creation error code:
|
|
||||||
; eax = -0x20 = 0xFFFFFFE0 : too many processes
|
|
||||||
; eax = -0x1F = 0xFFFFFFE1 : not Menuet/Kolibri executable
|
|
||||||
; eax = -0x1E = 0xFFFFFFE2 : no memory
|
|
||||||
|
|
||||||
; ebx is not changed
|
|
||||||
|
|
||||||
; \end{diamond}[18.03.2006]
|
|
||||||
|
|
||||||
; Extract parameters
|
|
||||||
; add eax, std_application_base_address ; abs start of info block
|
|
||||||
|
|
||||||
cmp dword [eax+0], 15; GET_DISK_INFO
|
|
||||||
je fs_info
|
|
||||||
|
|
||||||
cmp dword [CURRENT_TASK], 1; no memory checks for kernel requests
|
|
||||||
jz no_checks_for_kernel
|
|
||||||
mov edx, eax
|
|
||||||
cmp dword [eax+0], 1
|
|
||||||
jnz .usual_check
|
|
||||||
mov ebx, [eax+12]
|
|
||||||
; add ebx,std_application_base_address
|
|
||||||
mov ecx, [eax+8]
|
|
||||||
call check_region
|
|
||||||
test eax, eax
|
|
||||||
jnz area_in_app_mem
|
|
||||||
|
|
||||||
.error_output:
|
|
||||||
mov esi, buffer_failed
|
|
||||||
call sys_msg_board_str
|
|
||||||
; mov eax,7
|
|
||||||
mov dword [esp+36], 7
|
|
||||||
ret
|
|
||||||
iglobal
|
|
||||||
buffer_failed db 'K : Buffer check failed',13,10,0
|
|
||||||
endg
|
|
||||||
.usual_check:
|
|
||||||
cmp dword [eax+0], 0
|
|
||||||
mov ecx, 512
|
|
||||||
jnz .small_size
|
|
||||||
mov ecx, [eax+8]
|
|
||||||
shl ecx, 9
|
|
||||||
.small_size:
|
|
||||||
mov ebx, [eax+12]
|
|
||||||
; add ebx,std_application_base_address
|
|
||||||
call check_region
|
|
||||||
test eax, eax
|
|
||||||
jz .error_output
|
|
||||||
area_in_app_mem:
|
|
||||||
mov eax, edx
|
|
||||||
no_checks_for_kernel:
|
|
||||||
|
|
||||||
fs_read:
|
|
||||||
|
|
||||||
mov ebx, [eax+20] ; program wants root directory ?
|
|
||||||
test bl, bl
|
|
||||||
je fs_getroot
|
|
||||||
test bh, bh
|
|
||||||
jne fs_noroot
|
|
||||||
fs_getroot:
|
|
||||||
; \begin{diamond}[18.03.2006]
|
|
||||||
; root - only read is allowed
|
|
||||||
; other operations return "access denied", eax=10
|
|
||||||
; (execute operation returns eax=-10)
|
|
||||||
cmp dword [eax], 0
|
|
||||||
jz .read_root
|
|
||||||
mov dword [esp+36], 10
|
|
||||||
ret
|
|
||||||
.read_root:
|
|
||||||
; \end{diamond}[18.03.2006]
|
|
||||||
mov esi, dir0
|
|
||||||
mov edi, [eax+12]
|
|
||||||
; add edi,std_application_base_address
|
|
||||||
mov ecx, 11
|
|
||||||
push ecx
|
|
||||||
; cld ; already is
|
|
||||||
rep movsb
|
|
||||||
mov al, 0x10
|
|
||||||
stosb
|
|
||||||
add edi, 32-11-1
|
|
||||||
pop ecx
|
|
||||||
rep movsb
|
|
||||||
stosb
|
|
||||||
and dword [esp+36], 0; ok read
|
|
||||||
mov dword [esp+24], 32*2; size of root
|
|
||||||
ret
|
|
||||||
|
|
||||||
fs_info: ;start of code - Mihasik
|
|
||||||
push eax
|
|
||||||
cmp [eax+21], byte 'r'
|
|
||||||
je fs_info_r
|
|
||||||
cmp [eax+21], byte 'R'
|
|
||||||
je fs_info_r
|
|
||||||
mov eax, 3 ;if unknown disk
|
|
||||||
xor ebx, ebx
|
|
||||||
xor ecx, ecx
|
|
||||||
xor edx, edx
|
|
||||||
jmp fs_info1
|
|
||||||
fs_info_r:
|
|
||||||
call ramdisk_free_space;if ramdisk
|
|
||||||
mov ecx, edi ;free space in ecx
|
|
||||||
shr ecx, 9 ;free clusters
|
|
||||||
mov ebx, 2847 ;total clusters
|
|
||||||
mov edx, 512 ;cluster size
|
|
||||||
xor eax, eax ;always 0
|
|
||||||
fs_info1:
|
|
||||||
pop edi
|
|
||||||
mov [esp+36], eax
|
|
||||||
mov [esp+24], ebx ; total clusters on disk
|
|
||||||
mov [esp+32], ecx ; free clusters on disk
|
|
||||||
mov [edi], edx ; cluster size in bytes
|
|
||||||
ret ;end of code - Mihasik
|
|
||||||
|
|
||||||
fs_noroot:
|
|
||||||
|
|
||||||
push dword [eax+0] ; read/write/delete/.../makedir/rename/lba/run
|
|
||||||
push dword [eax+4] ; 512 block number to read
|
|
||||||
push dword [eax+8] ; bytes to write/append or 512 blocks to read
|
|
||||||
mov ebx, [eax+12]
|
|
||||||
; add ebx,std_application_base_address
|
|
||||||
push ebx ; abs start of return/save area
|
|
||||||
|
|
||||||
lea esi, [eax+20] ; abs start of dir + filename
|
|
||||||
mov edi, [eax+16]
|
|
||||||
; add edi,std_application_base_address ; abs start of work area
|
|
||||||
|
|
||||||
call expand_pathz
|
|
||||||
|
|
||||||
push edi ; dir start
|
|
||||||
push ebx ; name of file start
|
|
||||||
|
|
||||||
mov eax, [edi+1]
|
|
||||||
cmp eax, 'RD '
|
|
||||||
je fs_yesramdisk
|
|
||||||
cmp eax, 'RAMD'
|
|
||||||
jne fs_noramdisk
|
|
||||||
|
|
||||||
fs_yesramdisk:
|
|
||||||
|
|
||||||
cmp byte [edi+1+11], 0
|
|
||||||
je fs_give_dir1
|
|
||||||
|
|
||||||
mov eax, [edi+1+12]
|
|
||||||
cmp eax, '1 '
|
|
||||||
je fs_yesramdisk_first
|
|
||||||
cmp eax, 'FIRS'
|
|
||||||
jne fs_noramdisk
|
|
||||||
|
|
||||||
fs_yesramdisk_first:
|
|
||||||
|
|
||||||
cmp dword [esp+20], 8; LBA read ramdisk
|
|
||||||
jne fs_no_LBA_read_ramdisk
|
|
||||||
|
|
||||||
mov eax, [esp+16] ; LBA block to read
|
|
||||||
mov ecx, [esp+8] ; abs pointer to return area
|
|
||||||
|
|
||||||
call LBA_read_ramdisk
|
|
||||||
jmp file_system_return
|
|
||||||
|
|
||||||
|
|
||||||
fs_no_LBA_read_ramdisk:
|
|
||||||
|
|
||||||
cmp dword [esp+20], 0; READ
|
|
||||||
jne fs_noramdisk_read
|
|
||||||
|
|
||||||
mov eax, [esp+4] ; fname
|
|
||||||
add eax, 2*12+1
|
|
||||||
mov ebx, [esp+16] ; block start
|
|
||||||
inc ebx
|
|
||||||
mov ecx, [esp+12] ; block count
|
|
||||||
mov edx, [esp+8] ; return
|
|
||||||
mov esi, [esp+0]
|
|
||||||
sub esi, eax
|
|
||||||
add esi, 12+1 ; file name length
|
|
||||||
call fileread
|
|
||||||
|
|
||||||
jmp file_system_return
|
|
||||||
|
|
||||||
|
|
||||||
fs_noramdisk_read:
|
|
||||||
fs_noramdisk:
|
|
||||||
|
|
||||||
;********************************************************************
|
|
||||||
mov eax, [edi+1]
|
|
||||||
cmp eax, 'FD '
|
|
||||||
je fs_yesflpdisk
|
|
||||||
cmp eax, 'FLOP'
|
|
||||||
jne fs_noflpdisk
|
|
||||||
|
|
||||||
fs_yesflpdisk:
|
|
||||||
call reserve_flp
|
|
||||||
|
|
||||||
cmp byte [edi+1+11], 0
|
|
||||||
je fs_give_dir1
|
|
||||||
|
|
||||||
mov eax, [edi+1+12]
|
|
||||||
cmp eax, '1 '
|
|
||||||
je fs_yesflpdisk_first
|
|
||||||
cmp eax, 'FIRS'
|
|
||||||
je fs_yesflpdisk_first
|
|
||||||
cmp eax, '2 '
|
|
||||||
je fs_yesflpdisk_second
|
|
||||||
cmp eax, 'SECO'
|
|
||||||
jne fs_noflpdisk
|
|
||||||
jmp fs_yesflpdisk_second
|
|
||||||
|
|
||||||
fs_yesflpdisk_first:
|
|
||||||
mov [flp_number], 1
|
|
||||||
jmp fs_yesflpdisk_start
|
|
||||||
fs_yesflpdisk_second:
|
|
||||||
mov [flp_number], 2
|
|
||||||
fs_yesflpdisk_start:
|
|
||||||
cmp dword [esp+20], 0; READ
|
|
||||||
jne fs_noflpdisk_read
|
|
||||||
|
|
||||||
mov eax, [esp+4] ; fname
|
|
||||||
add eax, 2*12+1
|
|
||||||
mov ebx, [esp+16] ; block start
|
|
||||||
inc ebx
|
|
||||||
mov ecx, [esp+12] ; block count
|
|
||||||
mov edx, [esp+8] ; return
|
|
||||||
mov esi, [esp+0]
|
|
||||||
sub esi, eax
|
|
||||||
add esi, 12+1 ; file name length
|
|
||||||
call floppy_fileread
|
|
||||||
|
|
||||||
jmp file_system_return
|
|
||||||
|
|
||||||
|
|
||||||
fs_noflpdisk_read:
|
|
||||||
fs_noflpdisk:
|
|
||||||
;*****************************************************************
|
|
||||||
|
|
||||||
old_path_harddisk:
|
|
||||||
mov eax, [edi+1]
|
|
||||||
cmp eax, 'HD '
|
|
||||||
je fs_yesharddisk
|
|
||||||
cmp eax, 'HARD'
|
|
||||||
jne fs_noharddisk
|
|
||||||
|
|
||||||
fs_yesharddisk:
|
|
||||||
cmp dword [esp+20], 8; LBA read
|
|
||||||
jne fs_no_LBA_read
|
|
||||||
mov eax, [esp+16] ; LBA block to read
|
|
||||||
lea ebx, [edi+1+12] ; pointer to FIRST/SECOND/THIRD/FOURTH
|
|
||||||
mov ecx, [esp+8] ; abs pointer to return area
|
|
||||||
call LBA_read
|
|
||||||
jmp file_system_return
|
|
||||||
|
|
||||||
fs_no_LBA_read:
|
|
||||||
|
|
||||||
hd_err_return:
|
|
||||||
|
|
||||||
fs_noharddisk:
|
|
||||||
; \begin{diamond}[18.03.2006]
|
|
||||||
mov eax, 5 ; file not found
|
|
||||||
; а может быть, возвращать другой код ошибки?
|
|
||||||
mov ebx, [esp+24+24]; do not change ebx in application
|
|
||||||
; \end{diamond}[18.03.2006]
|
|
||||||
|
|
||||||
file_system_return:
|
|
||||||
|
|
||||||
add esp, 24
|
|
||||||
|
|
||||||
mov [esp+36], eax
|
|
||||||
mov [esp+24], ebx
|
|
||||||
ret
|
|
||||||
|
|
||||||
|
|
||||||
fs_give_dir1:
|
|
||||||
|
|
||||||
; \begin{diamond}[18.03.2006]
|
|
||||||
; /RD,/FD,/HD - only read is allowed
|
|
||||||
; other operations return "access denied", eax=10
|
|
||||||
; (execute operation returns eax=-10)
|
|
||||||
cmp dword [esp+20], 0
|
|
||||||
jz .read
|
|
||||||
add esp, 20
|
|
||||||
pop ecx
|
|
||||||
mov dword [esp+36], 10
|
|
||||||
ret
|
|
||||||
.read:
|
|
||||||
; \end{diamond}[18.03.2006]
|
|
||||||
mov al, 0x10
|
|
||||||
mov ebx, 1
|
|
||||||
mov edi, [esp+8]
|
|
||||||
mov esi, dir1
|
|
||||||
fs_d1_new:
|
|
||||||
mov ecx, 11
|
|
||||||
; cld
|
|
||||||
rep movsb
|
|
||||||
stosb
|
|
||||||
add edi, 32-11-1
|
|
||||||
dec ebx
|
|
||||||
jne fs_d1_new
|
|
||||||
|
|
||||||
add esp, 24
|
|
||||||
|
|
||||||
and dword [esp+36], 0; ok read
|
|
||||||
mov dword [esp+24], 32*1; dir/data size
|
|
||||||
ret
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
LBA_read_ramdisk:
|
|
||||||
|
|
||||||
cmp [lba_read_enabled], 1
|
|
||||||
je lbarrl1
|
|
||||||
|
|
||||||
xor ebx, ebx
|
|
||||||
mov eax, 2
|
|
||||||
ret
|
|
||||||
|
|
||||||
lbarrl1:
|
|
||||||
|
|
||||||
cmp eax, 18*2*80
|
|
||||||
jb lbarrl2
|
|
||||||
xor ebx, ebx
|
|
||||||
mov eax, 3
|
|
||||||
ret
|
|
||||||
|
|
||||||
lbarrl2:
|
|
||||||
|
|
||||||
pushad
|
|
||||||
|
|
||||||
call restorefatchain
|
|
||||||
|
|
||||||
mov edi, ecx
|
|
||||||
mov esi, eax
|
|
||||||
|
|
||||||
shl esi, 9
|
|
||||||
add esi, RAMDISK
|
|
||||||
mov ecx, 512/4
|
|
||||||
; cld
|
|
||||||
rep movsd
|
|
||||||
|
|
||||||
popad
|
|
||||||
|
|
||||||
xor ebx, ebx
|
|
||||||
xor eax, eax
|
|
||||||
ret
|
|
||||||
|
|
||||||
LBA_read:
|
|
||||||
|
|
||||||
; IN:
|
|
||||||
;
|
|
||||||
; eax = LBA block to read
|
|
||||||
; ebx = pointer to FIRST/SECOND/THIRD/FOURTH
|
|
||||||
; ecx = abs pointer to return area
|
|
||||||
|
|
||||||
cmp [lba_read_enabled], 1
|
|
||||||
je lbarl1
|
|
||||||
mov eax, 2
|
|
||||||
ret
|
|
||||||
|
|
||||||
lbarl1:
|
|
||||||
|
|
||||||
pushad
|
|
||||||
mov ecx, ide_mutex
|
|
||||||
call mutex_lock
|
|
||||||
popad
|
|
||||||
|
|
||||||
push eax
|
|
||||||
push ecx
|
|
||||||
|
|
||||||
mov edi, hd_address_table
|
|
||||||
mov esi, dir1
|
|
||||||
mov eax, [ebx]
|
|
||||||
mov edx, '1 '
|
|
||||||
mov ecx, 4
|
|
||||||
blar0:
|
|
||||||
cmp eax, [esi]
|
|
||||||
je blar2
|
|
||||||
cmp eax, edx
|
|
||||||
je blar2
|
|
||||||
inc edx
|
|
||||||
add edi, 8
|
|
||||||
add esi, 11
|
|
||||||
dec ecx
|
|
||||||
jnz blar0
|
|
||||||
|
|
||||||
mov eax, 1
|
|
||||||
mov ebx, 1
|
|
||||||
jmp LBA_read_ret
|
|
||||||
|
|
||||||
blar2:
|
|
||||||
mov eax, [edi+0]
|
|
||||||
mov ebx, [edi+4]
|
|
||||||
|
|
||||||
mov [hdbase], eax
|
|
||||||
mov [hdid], ebx
|
|
||||||
|
|
||||||
call wait_for_hd_idle
|
|
||||||
cmp [hd_error], 0
|
|
||||||
jne hd_lba_error
|
|
||||||
|
|
||||||
; eax = hd port
|
|
||||||
; ebx = set for primary (0x00) or slave (0x10)
|
|
||||||
|
|
||||||
cli
|
|
||||||
|
|
||||||
mov edx, eax
|
|
||||||
inc edx
|
|
||||||
xor eax, eax
|
|
||||||
out dx, al
|
|
||||||
inc edx
|
|
||||||
inc eax
|
|
||||||
out dx, al
|
|
||||||
inc edx
|
|
||||||
mov eax, [esp+4]
|
|
||||||
out dx, al
|
|
||||||
shr eax, 8
|
|
||||||
inc edx
|
|
||||||
out dx, al
|
|
||||||
shr eax, 8
|
|
||||||
inc edx
|
|
||||||
out dx, al
|
|
||||||
shr eax, 8
|
|
||||||
inc edx
|
|
||||||
and al, 1+2+4+8
|
|
||||||
add al, bl
|
|
||||||
add al, 128+64+32
|
|
||||||
out dx, al
|
|
||||||
|
|
||||||
inc edx
|
|
||||||
mov al, 20h
|
|
||||||
out dx, al
|
|
||||||
|
|
||||||
sti
|
|
||||||
|
|
||||||
call wait_for_sector_buffer
|
|
||||||
cmp [hd_error], 0
|
|
||||||
jne hd_lba_error
|
|
||||||
|
|
||||||
cli
|
|
||||||
|
|
||||||
mov edi, [esp+0]
|
|
||||||
mov ecx, 256
|
|
||||||
sub edx, 7
|
|
||||||
cld
|
|
||||||
rep insw
|
|
||||||
|
|
||||||
sti
|
|
||||||
|
|
||||||
xor eax, eax
|
|
||||||
xor ebx, ebx
|
|
||||||
|
|
||||||
LBA_read_ret:
|
|
||||||
mov [hd_error], 0
|
|
||||||
mov [hd1_status], 0
|
|
||||||
add esp, 2*4
|
|
||||||
pushad
|
|
||||||
mov ecx, ide_mutex
|
|
||||||
call mutex_unlock
|
|
||||||
popad
|
|
||||||
|
|
||||||
ret
|
|
||||||
|
|
||||||
|
|
||||||
expand_pathz:
|
|
||||||
; IN:
|
|
||||||
; esi = asciiz path & file
|
|
||||||
; edi = buffer for path & file name
|
|
||||||
; OUT:
|
|
||||||
; edi = directory & file : / 11 + / 11 + / 11 - zero terminated
|
|
||||||
; ebx = /file name - zero terminated
|
|
||||||
; esi = pointer after source
|
|
||||||
|
|
||||||
push eax
|
|
||||||
push ecx
|
|
||||||
push edi;[esp+0]
|
|
||||||
|
|
||||||
pathz_start:
|
|
||||||
mov byte [edi], '/'
|
|
||||||
inc edi
|
|
||||||
mov al, 32
|
|
||||||
mov ecx, 11
|
|
||||||
cld
|
|
||||||
rep stosb ; clear filename area
|
|
||||||
sub edi, 11
|
|
||||||
mov ebx, edi ; start of dir/file name
|
|
||||||
|
|
||||||
pathz_new_char:
|
|
||||||
mov al, [esi]
|
|
||||||
inc esi
|
|
||||||
cmp al, 0
|
|
||||||
je pathz_end
|
|
||||||
|
|
||||||
cmp al, '/'
|
|
||||||
jne pathz_not_path
|
|
||||||
cmp edi, ebx ; skip first '/'
|
|
||||||
jz pathz_new_char
|
|
||||||
lea edi, [ebx+11] ; start of next directory
|
|
||||||
jmp pathz_start
|
|
||||||
|
|
||||||
pathz_not_path:
|
|
||||||
cmp al, '.'
|
|
||||||
jne pathz_not_ext
|
|
||||||
lea edi, [ebx+8] ; start of extension
|
|
||||||
jmp pathz_new_char
|
|
||||||
|
|
||||||
pathz_not_ext:
|
|
||||||
cmp al, 'a'
|
|
||||||
jb pathz_not_low
|
|
||||||
cmp al, 'z'
|
|
||||||
ja pathz_not_low
|
|
||||||
sub al, 0x20 ; char to uppercase
|
|
||||||
|
|
||||||
pathz_not_low:
|
|
||||||
mov [edi], al
|
|
||||||
inc edi
|
|
||||||
mov eax, [esp+0] ; start_of_dest_path
|
|
||||||
add eax, 512 ; keep maximum path under 512 bytes
|
|
||||||
cmp edi, eax
|
|
||||||
jb pathz_new_char
|
|
||||||
|
|
||||||
pathz_end:
|
|
||||||
cmp ebx, edi ; if path end with '/'
|
|
||||||
jnz pathz_put_zero ; go back 1 level
|
|
||||||
sub ebx, 12
|
|
||||||
|
|
||||||
pathz_put_zero:
|
|
||||||
mov byte [ebx+11], 0
|
|
||||||
dec ebx ; include '/' char into file name
|
|
||||||
pop edi
|
|
||||||
pop ecx
|
|
||||||
pop eax
|
|
||||||
ret
|
|
||||||
|
|
||||||
;*******************************************
|
|
||||||
;* string to number
|
|
||||||
;* input eax - 4 byte string
|
|
||||||
;* output eax - number
|
|
||||||
;*******************************************
|
|
||||||
StringToNumber:
|
|
||||||
; ПЕРЕВОД СТРОКОВОГО ЧИСЛА В ЧИСЛОВОЙ ВИД
|
|
||||||
; Вход:
|
|
||||||
; EDI - адрес строки с числом. Конец числа отмечен кодом 0Dh
|
|
||||||
; Выход:
|
|
||||||
; CF - индикатор ошибок:
|
|
||||||
; 0 - ошибок нет;
|
|
||||||
; 1 - ошибка
|
|
||||||
; Если CF=0, то AX - число.
|
|
||||||
|
|
||||||
push bx
|
|
||||||
push cx
|
|
||||||
push dx
|
|
||||||
push edi
|
|
||||||
mov [partition_string], eax
|
|
||||||
mov edi, partition_string
|
|
||||||
xor cx, cx
|
|
||||||
i1:
|
|
||||||
mov al, [edi]
|
|
||||||
cmp al, 32;13
|
|
||||||
je i_exit
|
|
||||||
; cmp al,'0'
|
|
||||||
; jb err
|
|
||||||
; cmp al,'9'
|
|
||||||
; ja err
|
|
||||||
sub al, 48
|
|
||||||
shl cx, 1
|
|
||||||
jc error
|
|
||||||
mov bx, cx
|
|
||||||
shl cx, 1
|
|
||||||
jc error
|
|
||||||
shl cx, 1
|
|
||||||
jc error
|
|
||||||
add cx, bx
|
|
||||||
jc error
|
|
||||||
cbw
|
|
||||||
add cx, ax
|
|
||||||
jc error
|
|
||||||
i3:
|
|
||||||
inc edi
|
|
||||||
jmp i1
|
|
||||||
i_exit:
|
|
||||||
mov ax, cx
|
|
||||||
clc
|
|
||||||
i4:
|
|
||||||
movzx eax, ax
|
|
||||||
pop edi
|
|
||||||
pop dx
|
|
||||||
pop cx
|
|
||||||
pop bx
|
|
||||||
ret
|
|
||||||
|
|
||||||
error:
|
|
||||||
stc
|
|
||||||
jmp i4
|
|
||||||
|
|
||||||
partition_string:
|
|
||||||
dd 0
|
|
||||||
db 32
|
|
@ -30,18 +30,6 @@ image_of_ebx EQU esp+20
|
|||||||
iglobal
|
iglobal
|
||||||
; in this table names must be in lowercase
|
; in this table names must be in lowercase
|
||||||
rootdirs:
|
rootdirs:
|
||||||
db 2,'rd'
|
|
||||||
dd fs_OnRamdisk
|
|
||||||
dd fs_NextRamdisk
|
|
||||||
db 7,'ramdisk'
|
|
||||||
dd fs_OnRamdisk
|
|
||||||
dd fs_NextRamdisk
|
|
||||||
db 2,'fd'
|
|
||||||
dd fs_OnFloppy
|
|
||||||
dd fs_NextFloppy
|
|
||||||
db 10,'floppydisk'
|
|
||||||
dd fs_OnFloppy
|
|
||||||
dd fs_NextFloppy
|
|
||||||
;**********************************************
|
;**********************************************
|
||||||
db 3,'cd0'
|
db 3,'cd0'
|
||||||
dd fs_OnCd0
|
dd fs_OnCd0
|
||||||
@ -60,10 +48,6 @@ rootdirs:
|
|||||||
|
|
||||||
|
|
||||||
virtual_root_query:
|
virtual_root_query:
|
||||||
dd fs_HasRamdisk
|
|
||||||
db 'rd',0
|
|
||||||
dd fs_HasFloppy
|
|
||||||
db 'fd',0
|
|
||||||
;**********************************************
|
;**********************************************
|
||||||
dd fs_HasCd0
|
dd fs_HasCd0
|
||||||
db 'cd0',0
|
db 'cd0',0
|
||||||
@ -75,12 +59,6 @@ virtual_root_query:
|
|||||||
db 'cd3',0
|
db 'cd3',0
|
||||||
;**********************************************
|
;**********************************************
|
||||||
dd 0
|
dd 0
|
||||||
|
|
||||||
fs_additional_handlers:
|
|
||||||
dd dyndisk_handler, dyndisk_enum_root
|
|
||||||
; add new handlers here
|
|
||||||
dd 0
|
|
||||||
|
|
||||||
endg
|
endg
|
||||||
|
|
||||||
file_system_lfn_protected:
|
file_system_lfn_protected:
|
||||||
@ -257,7 +235,6 @@ file_system_lfn:
|
|||||||
|
|
||||||
.readroot:
|
.readroot:
|
||||||
; virtual root folder - special handler
|
; virtual root folder - special handler
|
||||||
mov esi, virtual_root_query
|
|
||||||
mov ebp, [ebx+12]
|
mov ebp, [ebx+12]
|
||||||
mov edx, [ebx+16]
|
mov edx, [ebx+16]
|
||||||
; add edx, std_application_base_address
|
; add edx, std_application_base_address
|
||||||
@ -269,9 +246,51 @@ file_system_lfn:
|
|||||||
mov ecx, 32/4
|
mov ecx, 32/4
|
||||||
rep stosd
|
rep stosd
|
||||||
mov byte [edx], 1 ; version
|
mov byte [edx], 1 ; version
|
||||||
|
sub esp, 16
|
||||||
|
.readroot_ah_loop2:
|
||||||
|
push edi
|
||||||
|
lea edi, [esp+4]
|
||||||
|
call dyndisk_enum_root
|
||||||
|
pop edi
|
||||||
|
test eax, eax
|
||||||
|
jz .readroot_done_dynamic
|
||||||
|
inc dword [edx+8]
|
||||||
|
dec dword [esp+16]
|
||||||
|
jns .readroot_ah_loop2
|
||||||
|
dec ebp
|
||||||
|
js .readroot_ah_loop2
|
||||||
|
push eax
|
||||||
|
xor eax, eax
|
||||||
|
inc dword [edx+4]
|
||||||
|
mov dword [edi], 0x10 ; attributes: folder
|
||||||
|
mov dword [edi+4], ebx
|
||||||
|
add edi, 8
|
||||||
|
mov ecx, 40/4-2
|
||||||
|
rep stosd
|
||||||
|
push esi edi
|
||||||
|
lea esi, [esp+12]
|
||||||
|
@@:
|
||||||
|
lodsb
|
||||||
|
stosb
|
||||||
|
test bl, 1
|
||||||
|
jz .ansi3
|
||||||
|
mov byte [edi], 0
|
||||||
|
inc edi
|
||||||
|
.ansi3:
|
||||||
|
test al, al
|
||||||
|
jnz @b
|
||||||
|
pop edi esi eax
|
||||||
|
add edi, 520
|
||||||
|
test bl, 1
|
||||||
|
jnz .readroot_ah_loop2
|
||||||
|
sub edi, 520-264
|
||||||
|
jmp .readroot_ah_loop2
|
||||||
|
.readroot_done_dynamic:
|
||||||
|
add esp, 16
|
||||||
|
mov esi, virtual_root_query
|
||||||
.readroot_loop:
|
.readroot_loop:
|
||||||
cmp dword [esi], eax
|
cmp dword [esi], eax
|
||||||
jz .readroot_done_static
|
jz .readroot_done
|
||||||
call dword [esi]
|
call dword [esi]
|
||||||
add esi, 4
|
add esi, 4
|
||||||
test eax, eax
|
test eax, eax
|
||||||
@ -312,54 +331,7 @@ file_system_lfn:
|
|||||||
jnz .readroot_loop
|
jnz .readroot_loop
|
||||||
sub edi, 520-264
|
sub edi, 520-264
|
||||||
jmp .readroot_loop
|
jmp .readroot_loop
|
||||||
.readroot_done_static:
|
|
||||||
mov esi, fs_additional_handlers-8
|
|
||||||
sub esp, 16
|
|
||||||
.readroot_ah_loop:
|
|
||||||
add esi, 8
|
|
||||||
cmp dword [esi], 0
|
|
||||||
jz .readroot_done
|
|
||||||
xor eax, eax
|
|
||||||
.readroot_ah_loop2:
|
|
||||||
push edi
|
|
||||||
lea edi, [esp+4]
|
|
||||||
call dword [esi+4]
|
|
||||||
pop edi
|
|
||||||
test eax, eax
|
|
||||||
jz .readroot_ah_loop
|
|
||||||
inc dword [edx+8]
|
|
||||||
dec dword [esp+16]
|
|
||||||
jns .readroot_ah_loop2
|
|
||||||
dec ebp
|
|
||||||
js .readroot_ah_loop2
|
|
||||||
push eax
|
|
||||||
xor eax, eax
|
|
||||||
inc dword [edx+4]
|
|
||||||
mov dword [edi], 0x10 ; attributes: folder
|
|
||||||
mov dword [edi+4], ebx
|
|
||||||
add edi, 8
|
|
||||||
mov ecx, 40/4-2
|
|
||||||
rep stosd
|
|
||||||
push esi edi
|
|
||||||
lea esi, [esp+12]
|
|
||||||
@@:
|
|
||||||
lodsb
|
|
||||||
stosb
|
|
||||||
test bl, 1
|
|
||||||
jz .ansi3
|
|
||||||
mov byte [edi], 0
|
|
||||||
inc edi
|
|
||||||
.ansi3:
|
|
||||||
test al, al
|
|
||||||
jnz @b
|
|
||||||
pop edi esi eax
|
|
||||||
add edi, 520
|
|
||||||
test bl, 1
|
|
||||||
jnz .readroot_ah_loop2
|
|
||||||
sub edi, 520-264
|
|
||||||
jmp .readroot_ah_loop2
|
|
||||||
.readroot_done:
|
.readroot_done:
|
||||||
add esp, 16
|
|
||||||
pop eax
|
pop eax
|
||||||
mov ebx, [edx+4]
|
mov ebx, [edx+4]
|
||||||
xor eax, eax
|
xor eax, eax
|
||||||
@ -371,14 +343,7 @@ file_system_lfn:
|
|||||||
mov [image_of_ebx], ebx
|
mov [image_of_ebx], ebx
|
||||||
ret
|
ret
|
||||||
.notfound_try:
|
.notfound_try:
|
||||||
mov edi, fs_additional_handlers
|
call dyndisk_handler
|
||||||
@@:
|
|
||||||
cmp dword [edi], 0
|
|
||||||
jz .notfound
|
|
||||||
call dword [edi]
|
|
||||||
scasd
|
|
||||||
scasd
|
|
||||||
jmp @b
|
|
||||||
.notfound:
|
.notfound:
|
||||||
mov dword [image_of_eax], ERROR_FILE_NOT_FOUND
|
mov dword [image_of_eax], ERROR_FILE_NOT_FOUND
|
||||||
and dword [image_of_ebx], 0
|
and dword [image_of_ebx], 0
|
||||||
@ -436,72 +401,10 @@ file_system_lfn:
|
|||||||
; ebp = 0 or pointer to rest of name from folder addressed by esi
|
; ebp = 0 or pointer to rest of name from folder addressed by esi
|
||||||
; out: [image_of_eax]=image of eax, [image_of_ebx]=image of ebx
|
; out: [image_of_eax]=image of eax, [image_of_ebx]=image of ebx
|
||||||
|
|
||||||
fs_OnRamdisk:
|
|
||||||
cmp ecx, 1
|
|
||||||
jnz file_system_lfn.notfound
|
|
||||||
mov eax, [ebx]
|
|
||||||
cmp eax, fs_NumRamdiskServices
|
|
||||||
jae .not_impl
|
|
||||||
mov ecx, [ebx+12]
|
|
||||||
mov edx, [ebx+16]
|
|
||||||
; add edx, std_application_base_address
|
|
||||||
add ebx, 4
|
|
||||||
call dword [fs_RamdiskServices + eax*4]
|
|
||||||
mov [image_of_eax], eax
|
|
||||||
mov [image_of_ebx], ebx
|
|
||||||
ret
|
|
||||||
.not_impl:
|
|
||||||
mov dword [image_of_eax], 2 ; not implemented
|
|
||||||
ret
|
|
||||||
|
|
||||||
fs_NotImplemented:
|
fs_NotImplemented:
|
||||||
mov eax, 2
|
mov eax, 2
|
||||||
ret
|
ret
|
||||||
|
|
||||||
fs_RamdiskServices:
|
|
||||||
dd fs_RamdiskRead
|
|
||||||
dd fs_RamdiskReadFolder
|
|
||||||
dd fs_RamdiskRewrite
|
|
||||||
dd fs_RamdiskWrite
|
|
||||||
dd fs_RamdiskSetFileEnd
|
|
||||||
dd fs_RamdiskGetFileInfo
|
|
||||||
dd fs_RamdiskSetFileInfo
|
|
||||||
dd 0
|
|
||||||
dd fs_RamdiskDelete
|
|
||||||
dd fs_RamdiskCreateFolder
|
|
||||||
fs_NumRamdiskServices = ($ - fs_RamdiskServices)/4
|
|
||||||
|
|
||||||
fs_OnFloppy:
|
|
||||||
cmp ecx, 2
|
|
||||||
ja file_system_lfn.notfound
|
|
||||||
mov eax, [ebx]
|
|
||||||
cmp eax, fs_NumFloppyServices
|
|
||||||
jae fs_OnRamdisk.not_impl
|
|
||||||
call reserve_flp
|
|
||||||
mov [flp_number], cl
|
|
||||||
mov ecx, [ebx+12]
|
|
||||||
mov edx, [ebx+16]
|
|
||||||
; add edx, std_application_base_address
|
|
||||||
add ebx, 4
|
|
||||||
call dword [fs_FloppyServices + eax*4]
|
|
||||||
and [flp_status], 0
|
|
||||||
mov [image_of_eax], eax
|
|
||||||
mov [image_of_ebx], ebx
|
|
||||||
ret
|
|
||||||
|
|
||||||
fs_FloppyServices:
|
|
||||||
dd fs_FloppyRead
|
|
||||||
dd fs_FloppyReadFolder
|
|
||||||
dd fs_FloppyRewrite
|
|
||||||
dd fs_FloppyWrite
|
|
||||||
dd fs_FloppySetFileEnd
|
|
||||||
dd fs_FloppyGetFileInfo
|
|
||||||
dd fs_FloppySetFileInfo
|
|
||||||
dd 0
|
|
||||||
dd fs_FloppyDelete
|
|
||||||
dd fs_FloppyCreateFolder
|
|
||||||
fs_NumFloppyServices = ($ - fs_FloppyServices)/4
|
|
||||||
|
|
||||||
;*******************************************************
|
;*******************************************************
|
||||||
fs_OnCd0:
|
fs_OnCd0:
|
||||||
call reserve_cd
|
call reserve_cd
|
||||||
@ -583,16 +486,6 @@ fs_CdServices:
|
|||||||
dd fs_NotImplemented
|
dd fs_NotImplemented
|
||||||
fs_NumCdServices = ($ - fs_CdServices)/4
|
fs_NumCdServices = ($ - fs_CdServices)/4
|
||||||
|
|
||||||
;*******************************************************
|
|
||||||
|
|
||||||
fs_HasRamdisk:
|
|
||||||
mov al, 1 ; we always have ramdisk
|
|
||||||
ret
|
|
||||||
fs_HasFloppy:
|
|
||||||
cmp byte [DRIVE_DATA], 0
|
|
||||||
setnz al
|
|
||||||
ret
|
|
||||||
|
|
||||||
;*******************************************************
|
;*******************************************************
|
||||||
fs_HasCd0:
|
fs_HasCd0:
|
||||||
test byte [DRIVE_DATA+1], 10000000b
|
test byte [DRIVE_DATA+1], 10000000b
|
||||||
@ -617,36 +510,6 @@ fs_HasCd3:
|
|||||||
; out: CF=1 => no more partitions
|
; out: CF=1 => no more partitions
|
||||||
; CF=0 => eax=next partition number
|
; CF=0 => eax=next partition number
|
||||||
|
|
||||||
fs_NextRamdisk:
|
|
||||||
; we always have /rd/1
|
|
||||||
test eax, eax
|
|
||||||
stc
|
|
||||||
jnz @f
|
|
||||||
mov al, 1
|
|
||||||
clc
|
|
||||||
@@:
|
|
||||||
ret
|
|
||||||
|
|
||||||
fs_NextFloppy:
|
|
||||||
; we have /fd/1 iff (([DRIVE_DATA] and 0xF0) != 0) and /fd/2 iff (([DRIVE_DATA] and 0x0F) != 0)
|
|
||||||
test byte [DRIVE_DATA], 0xF0
|
|
||||||
jz .no1
|
|
||||||
test eax, eax
|
|
||||||
jnz .no1
|
|
||||||
inc eax
|
|
||||||
ret ; CF cleared
|
|
||||||
.no1:
|
|
||||||
test byte [DRIVE_DATA], 0x0F
|
|
||||||
jz .no2
|
|
||||||
cmp al, 2
|
|
||||||
jae .no2
|
|
||||||
mov al, 2
|
|
||||||
clc
|
|
||||||
ret
|
|
||||||
.no2:
|
|
||||||
stc
|
|
||||||
ret
|
|
||||||
|
|
||||||
;*******************************************************
|
;*******************************************************
|
||||||
fs_NextCd:
|
fs_NextCd:
|
||||||
; we always have /cdX/1
|
; we always have /cdX/1
|
||||||
|
@ -1,436 +0,0 @@
|
|||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;; ;;
|
|
||||||
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;;
|
|
||||||
;; Distributed under terms of the GNU General Public License ;;
|
|
||||||
;; ;;
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
|
|
||||||
$Revision$
|
|
||||||
|
|
||||||
|
|
||||||
;*************************************************************
|
|
||||||
;* 13.02.2010 Find all partition and check supported FS
|
|
||||||
;* 12.07.2007 Check all 4 entry of MBR and EMBR
|
|
||||||
;* 29.04.2006 Elimination of hangup after the
|
|
||||||
;* expiration hd_wait_timeout - Mario79
|
|
||||||
;* 28.01.2006 find all Fat16/32 partition in all input point
|
|
||||||
;* to MBR - Mario79
|
|
||||||
;*************************************************************
|
|
||||||
|
|
||||||
uglobal
|
|
||||||
align 4
|
|
||||||
|
|
||||||
;******************************************************
|
|
||||||
; Please do not change this place - variables in text
|
|
||||||
; Mario79
|
|
||||||
; START place
|
|
||||||
;******************************************************
|
|
||||||
PARTITION_START dd 0x3f
|
|
||||||
PARTITION_END dd 0
|
|
||||||
fs_type db 0 ; 1=NTFS, 2=EXT2/3, 16=FAT16, 32=FAT32
|
|
||||||
align 4
|
|
||||||
|
|
||||||
fs_dependent_data_start:
|
|
||||||
; FATxx data
|
|
||||||
|
|
||||||
.partition dd ?
|
|
||||||
rb 80
|
|
||||||
|
|
||||||
fs_dependent_data_end:
|
|
||||||
file_system_data_size = $ - PARTITION_START
|
|
||||||
if file_system_data_size > 96
|
|
||||||
ERROR:
|
|
||||||
sizeof(file system data) too big!
|
|
||||||
end if
|
|
||||||
|
|
||||||
virtual at fs_dependent_data_start
|
|
||||||
; NTFS data
|
|
||||||
ntfs_data:
|
|
||||||
.sectors_per_cluster dd ?
|
|
||||||
.mft_cluster dd ?
|
|
||||||
.mftmirr_cluster dd ?
|
|
||||||
.frs_size dd ? ; FRS size in bytes
|
|
||||||
.iab_size dd ? ; IndexAllocationBuffer size in bytes
|
|
||||||
.frs_buffer dd ?
|
|
||||||
.iab_buffer dd ?
|
|
||||||
.mft_retrieval dd ?
|
|
||||||
.mft_retrieval_size dd ?
|
|
||||||
.mft_retrieval_alloc dd ?
|
|
||||||
.mft_retrieval_end dd ?
|
|
||||||
.cur_index_size dd ?
|
|
||||||
.cur_index_buf dd ?
|
|
||||||
if $ > fs_dependent_data_end
|
|
||||||
ERROR:
|
|
||||||
increase sizeof(fs_dependent_data)!
|
|
||||||
end if
|
|
||||||
end virtual
|
|
||||||
|
|
||||||
virtual at fs_dependent_data_start
|
|
||||||
; EXT2 data
|
|
||||||
ext2_data:
|
|
||||||
.log_block_size dd ?
|
|
||||||
.block_size dd ?
|
|
||||||
.count_block_in_block dd ?
|
|
||||||
.blocks_per_group dd ?
|
|
||||||
.global_desc_table dd ?
|
|
||||||
.root_inode dd ? ; pointer to root inode in memory
|
|
||||||
.inode_size dd ?
|
|
||||||
.count_pointer_in_block dd ? ; block_size / 4
|
|
||||||
.count_pointer_in_block_square dd ? ; (block_size / 4)**2
|
|
||||||
.ext2_save_block dd ? ;RUS: блок на глобальную 1 процедуру ;ENG: block for 1 global procedure
|
|
||||||
.ext2_temp_block dd ? ;RUS: блок для мелких процедур ;ENG: block for small procedures
|
|
||||||
.ext2_save_inode dd ? ;RUS: inode на глобальную процедуру ;ENG: inode for global procedure
|
|
||||||
.ext2_temp_inode dd ? ;RUS: inode для мелких процедур ;ENG: inode for small procedures
|
|
||||||
.sb dd ? ; superblock
|
|
||||||
.groups_count dd ?
|
|
||||||
if $ > fs_dependent_data_end
|
|
||||||
ERROR:
|
|
||||||
increase sizeof(fs_dependent_data)!
|
|
||||||
end if
|
|
||||||
end virtual
|
|
||||||
|
|
||||||
;***************************************************************************
|
|
||||||
; End place
|
|
||||||
; Mario79
|
|
||||||
;***************************************************************************
|
|
||||||
endg
|
|
||||||
iglobal
|
|
||||||
|
|
||||||
partition_types: ; list of fat16/32 partitions
|
|
||||||
db 0x04 ; DOS: fat16 <32M
|
|
||||||
db 0x06 ; DOS: fat16 >32M
|
|
||||||
db 0x0b ; WIN95: fat32
|
|
||||||
db 0x0c ; WIN95: fat32, LBA-mapped
|
|
||||||
db 0x0e ; WIN95: fat16, LBA-mapped
|
|
||||||
db 0x14 ; Hidden DOS: fat16 <32M
|
|
||||||
db 0x16 ; Hidden DOS: fat16 >32M
|
|
||||||
db 0x1b ; Hidden WIN95: fat32
|
|
||||||
db 0x1c ; Hidden WIN95: fat32, LBA-mapped
|
|
||||||
db 0x1e ; Hidden WIN95: fat16, LBA-mapped
|
|
||||||
db 0xc4 ; DRDOS/secured: fat16 <32M
|
|
||||||
db 0xc6 ; DRDOS/secured: fat16 >32M
|
|
||||||
db 0xcb ; DRDOS/secured: fat32
|
|
||||||
db 0xcc ; DRDOS/secured: fat32, LBA-mapped
|
|
||||||
db 0xce ; DRDOS/secured: fat16, LBA-mapped
|
|
||||||
db 0xd4 ; Old Multiuser DOS secured: fat16 <32M
|
|
||||||
db 0xd6 ; Old Multiuser DOS secured: fat16 >32M
|
|
||||||
db 0x07 ; NTFS
|
|
||||||
db 0x27 ; NTFS, hidden
|
|
||||||
db 0x83 ; Linux native file system (ext2fs)
|
|
||||||
partition_types_end:
|
|
||||||
|
|
||||||
|
|
||||||
extended_types: ; list of extended partitions
|
|
||||||
db 0x05 ; DOS: extended partition
|
|
||||||
db 0x0f ; WIN95: extended partition, LBA-mapped
|
|
||||||
db 0xc5 ; DRDOS/secured: extended partition
|
|
||||||
db 0xd5 ; Old Multiuser DOS secured: extended partition
|
|
||||||
extended_types_end:
|
|
||||||
|
|
||||||
endg
|
|
||||||
|
|
||||||
; Partition chain used:
|
|
||||||
; MBR <---------------------
|
|
||||||
; | |
|
|
||||||
; |-> PARTITION1 |
|
|
||||||
; |-> EXTENDED PARTITION - ;not need be second partition
|
|
||||||
; |-> PARTITION3
|
|
||||||
; |-> PARTITION4
|
|
||||||
|
|
||||||
set_PARTITION_variables:
|
|
||||||
set_FAT32_variables: ;deprecated
|
|
||||||
and [problem_partition], 0
|
|
||||||
call reserve_hd1
|
|
||||||
call reserve_hd_channel
|
|
||||||
|
|
||||||
pushad
|
|
||||||
|
|
||||||
cmp dword [hdpos], 0
|
|
||||||
je problem_hd
|
|
||||||
|
|
||||||
xor ecx, ecx ; partition count
|
|
||||||
;or edx,-1 ; flag for partition
|
|
||||||
xor eax, eax ; address MBR
|
|
||||||
xor ebp, ebp ; extended partition start
|
|
||||||
|
|
||||||
new_mbr:
|
|
||||||
test ebp, ebp ; is there extended partition? (MBR or EMBR)
|
|
||||||
jnz extended_already_set; yes
|
|
||||||
xchg ebp, eax ; no. set it now
|
|
||||||
|
|
||||||
extended_already_set:
|
|
||||||
add eax, ebp ; mbr=mbr+0, ext_part=ext_start+relat_start
|
|
||||||
mov ebx, buffer
|
|
||||||
call hd_read
|
|
||||||
cmp [hd_error], 0
|
|
||||||
jne problem_hd
|
|
||||||
|
|
||||||
cmp word [ebx+0x1fe], 0xaa55; is it valid boot sector?
|
|
||||||
jnz end_partition_chain
|
|
||||||
push eax ; push only one time
|
|
||||||
cmp dword [ebx+0x1be+0xc], 0; skip over empty partition
|
|
||||||
jnz test_primary_partition_0
|
|
||||||
cmp dword [ebx+0x1be+0xc+16], 0
|
|
||||||
jnz test_primary_partition_1
|
|
||||||
cmp dword [ebx+0x1be+0xc+16+16], 0
|
|
||||||
jnz test_primary_partition_2
|
|
||||||
cmp dword [ebx+0x1be+0xc+16+16+16], 0
|
|
||||||
jnz test_primary_partition_3
|
|
||||||
pop eax
|
|
||||||
jmp end_partition_chain
|
|
||||||
|
|
||||||
test_primary_partition_0:
|
|
||||||
mov al, [ebx+0x1be+4]; get primary partition type
|
|
||||||
call scan_partition_types
|
|
||||||
jnz test_primary_partition_1; no. skip over
|
|
||||||
|
|
||||||
inc ecx
|
|
||||||
cmp ecx, [known_part]; is it wanted partition?
|
|
||||||
jnz test_primary_partition_1; no
|
|
||||||
|
|
||||||
pop eax
|
|
||||||
;mov edx, eax ; start sector
|
|
||||||
add eax, [ebx+0x1be+8] ; add relative start
|
|
||||||
;mov [PARTITON_START],edx
|
|
||||||
;push edx
|
|
||||||
mov edx, [ebx+0x1be+12] ; length
|
|
||||||
;add edx, eax ; add length
|
|
||||||
;dec edx ; PARTITION_END is inclusive
|
|
||||||
;mov [PARTITION_END], edx ; note that this can be changed
|
|
||||||
; when file system data will be available
|
|
||||||
mov cl, [ebx+0x1be+4] ; fs_type
|
|
||||||
;mov [fs_type], dl ; save for FS recognizer (separate FAT vs NTFS)
|
|
||||||
;pop edx
|
|
||||||
jmp hd_and_partition_ok
|
|
||||||
|
|
||||||
test_primary_partition_1:
|
|
||||||
mov al, [ebx+0x1be+4+16]; get primary partition type
|
|
||||||
call scan_partition_types
|
|
||||||
jnz test_primary_partition_2 ; no. skip over
|
|
||||||
|
|
||||||
inc ecx
|
|
||||||
cmp ecx, [known_part]; is it wanted partition?
|
|
||||||
jnz test_primary_partition_2 ; no
|
|
||||||
|
|
||||||
pop eax
|
|
||||||
add eax, [ebx+0x1be+8+16]
|
|
||||||
mov edx, [ebx+0x1be+12+16]
|
|
||||||
mov cl, [ebx+0x1be+4+16]
|
|
||||||
jmp hd_and_partition_ok
|
|
||||||
|
|
||||||
;mov edx, eax
|
|
||||||
;add edx, [ebx+0x1be+8+16]
|
|
||||||
;push edx
|
|
||||||
;add edx, [ebx+0x1be+12+16]
|
|
||||||
;dec edx
|
|
||||||
;mov [PARTITION_END], edx
|
|
||||||
;mov al, [ebx+0x1be+4+16]
|
|
||||||
;mov [fs_type], dl
|
|
||||||
;pop edx
|
|
||||||
|
|
||||||
test_primary_partition_2:
|
|
||||||
mov al, [ebx+0x1be+4+16+16]; get primary partition type
|
|
||||||
call scan_partition_types
|
|
||||||
jnz test_primary_partition_3 ; no. skip over
|
|
||||||
|
|
||||||
inc ecx
|
|
||||||
cmp ecx, [known_part]; is it wanted partition?
|
|
||||||
jnz test_primary_partition_3 ; no
|
|
||||||
|
|
||||||
pop eax
|
|
||||||
add eax, [ebx+0x1be+8+16+16]
|
|
||||||
mov edx, [ebx+0x1be+12+16+16]
|
|
||||||
mov cl, [ebx+0x1be+4+16+16]
|
|
||||||
jmp hd_and_partition_ok
|
|
||||||
;mov edx, eax
|
|
||||||
;add edx, [ebx+0x1be+8+16+16]
|
|
||||||
;push edx
|
|
||||||
;add edx, [ebx+0x1be+12+16+16]
|
|
||||||
;dec edx
|
|
||||||
;mov [PARTITION_END], edx
|
|
||||||
;mov al, [ebx+0x1be+4+16+16]
|
|
||||||
;mov [fs_type], dl
|
|
||||||
;pop edx
|
|
||||||
|
|
||||||
test_primary_partition_3:
|
|
||||||
mov al, [ebx+0x1be+4+16+16+16]; get primary partition type
|
|
||||||
call scan_partition_types
|
|
||||||
jnz test_ext_partition_0 ; no. skip over
|
|
||||||
|
|
||||||
inc ecx
|
|
||||||
cmp ecx, [known_part]; is it wanted partition?
|
|
||||||
jnz test_ext_partition_0; no
|
|
||||||
|
|
||||||
pop eax
|
|
||||||
add eax, [ebx+0x1be+8+16+16+16]
|
|
||||||
mov edx, [ebx+0x1be+12+16+16+16]
|
|
||||||
mov cl, [ebx+0x1be+4+16+16+16]
|
|
||||||
jmp hd_and_partition_ok
|
|
||||||
|
|
||||||
;mov edx, eax
|
|
||||||
;add edx, [ebx+0x1be+8+16+16+16]
|
|
||||||
;push edx
|
|
||||||
;add edx, [ebx+0x1be+12+16+16+16]
|
|
||||||
;dec edx
|
|
||||||
;mov [PARTITION_END], edx
|
|
||||||
;mov al, [ebx+0x1be+4+16+16+16]
|
|
||||||
;mov [fs_type], dl
|
|
||||||
;pop edx
|
|
||||||
|
|
||||||
test_ext_partition_0:
|
|
||||||
pop eax ; просто выкидываем из стека
|
|
||||||
mov al, [ebx+0x1be+4]; get extended partition type
|
|
||||||
call scan_extended_types
|
|
||||||
jnz test_ext_partition_1
|
|
||||||
|
|
||||||
mov eax, [ebx+0x1be+8]; add relative start
|
|
||||||
test eax, eax ; is there extended partition?
|
|
||||||
jnz new_mbr ; yes. read it
|
|
||||||
|
|
||||||
test_ext_partition_1:
|
|
||||||
mov al, [ebx+0x1be+4+16]; get extended partition type
|
|
||||||
call scan_extended_types
|
|
||||||
jnz test_ext_partition_2
|
|
||||||
|
|
||||||
mov eax, [ebx+0x1be+8+16]; add relative start
|
|
||||||
test eax, eax ; is there extended partition?
|
|
||||||
jnz new_mbr ; yes. read it
|
|
||||||
|
|
||||||
test_ext_partition_2:
|
|
||||||
mov al, [ebx+0x1be+4+16+16]; get extended partition type
|
|
||||||
call scan_extended_types
|
|
||||||
jnz test_ext_partition_3
|
|
||||||
|
|
||||||
mov eax, [ebx+0x1be+8+16+16]; add relative start
|
|
||||||
test eax, eax ; is there extended partition?
|
|
||||||
jnz new_mbr ; yes. read it
|
|
||||||
|
|
||||||
test_ext_partition_3:
|
|
||||||
mov al, [ebx+0x1be+4+16+16+16]; get extended partition type
|
|
||||||
call scan_extended_types
|
|
||||||
jnz end_partition_chain; no. end chain
|
|
||||||
|
|
||||||
mov eax, [ebx+0x1be+8+16+16+16]; get start of extended partition
|
|
||||||
test eax, eax ; is there extended partition?
|
|
||||||
jnz new_mbr ; yes. read it
|
|
||||||
|
|
||||||
end_partition_chain:
|
|
||||||
;mov [partition_count],ecx
|
|
||||||
|
|
||||||
;cmp edx,-1 ; found wanted partition?
|
|
||||||
;jnz hd_and_partition_ok ; yes. install it
|
|
||||||
;jmp problem_partition_or_fat
|
|
||||||
problem_hd:
|
|
||||||
or [problem_partition], 2
|
|
||||||
jmp return_from_part_set
|
|
||||||
|
|
||||||
|
|
||||||
scan_partition_types:
|
|
||||||
push ecx
|
|
||||||
mov edi, partition_types
|
|
||||||
mov ecx, partition_types_end-partition_types
|
|
||||||
cld
|
|
||||||
repne scasb ; is partition type ok?
|
|
||||||
pop ecx
|
|
||||||
ret
|
|
||||||
|
|
||||||
scan_extended_types:
|
|
||||||
push ecx
|
|
||||||
mov edi, extended_types
|
|
||||||
mov ecx, extended_types_end-extended_types
|
|
||||||
cld
|
|
||||||
repne scasb ; is it extended partition?
|
|
||||||
pop ecx
|
|
||||||
ret
|
|
||||||
|
|
||||||
problem_fat_dec_count: ; bootsector is missing or another problem
|
|
||||||
; dec [partition_count] ; remove it from partition_count
|
|
||||||
|
|
||||||
problem_partition_or_fat:
|
|
||||||
or [problem_partition], 1
|
|
||||||
|
|
||||||
return_from_part_set:
|
|
||||||
popad
|
|
||||||
;mov [fs_type],0
|
|
||||||
call free_hd_channel
|
|
||||||
mov [hd1_status], 0 ; free
|
|
||||||
ret
|
|
||||||
|
|
||||||
hd_and_partition_ok:
|
|
||||||
|
|
||||||
;eax = PARTITION_START edx=PARTITION_LENGTH cl=fs_type
|
|
||||||
mov [fs_type], cl
|
|
||||||
;mov eax,edx
|
|
||||||
mov [PARTITION_START], eax
|
|
||||||
add edx, eax
|
|
||||||
dec edx
|
|
||||||
mov [PARTITION_END], edx
|
|
||||||
|
|
||||||
; mov edx, [PARTITION_END]
|
|
||||||
; sub edx, eax
|
|
||||||
; inc edx ; edx = length of partition зачем оно нам??
|
|
||||||
|
|
||||||
; mov [hd_setup],1
|
|
||||||
mov ebx, buffer
|
|
||||||
call hd_read ; read boot sector of partition
|
|
||||||
cmp [hd_error], 0
|
|
||||||
jz boot_read_ok
|
|
||||||
cmp [fs_type], 7
|
|
||||||
jnz problem_fat_dec_count
|
|
||||||
; NTFS duplicates bootsector:
|
|
||||||
; NT4/2k/XP+ saves bootsector copy in the end of disk
|
|
||||||
; NT 3.51 saves bootsector copy in the middle of disk
|
|
||||||
and [hd_error], 0
|
|
||||||
mov eax, [PARTITION_END]
|
|
||||||
call hd_read
|
|
||||||
cmp [hd_error], 0
|
|
||||||
jnz @f
|
|
||||||
call ntfs_test_bootsec
|
|
||||||
jnc boot_read_ok
|
|
||||||
@@:
|
|
||||||
and [hd_error], 0
|
|
||||||
mov eax, edx
|
|
||||||
shr eax, 1
|
|
||||||
add eax, [PARTITION_START]
|
|
||||||
call hd_read
|
|
||||||
cmp [hd_error], 0
|
|
||||||
jnz problem_fat_dec_count ; no chance...
|
|
||||||
boot_read_ok:
|
|
||||||
|
|
||||||
; if we are running on NTFS, check bootsector
|
|
||||||
|
|
||||||
call ntfs_test_bootsec ; test ntfs
|
|
||||||
jnc ntfs_setup
|
|
||||||
|
|
||||||
call ext2_test_superblock ; test ext2fs
|
|
||||||
jnc ext2_setup
|
|
||||||
|
|
||||||
mov eax, [PARTITION_START] ;ext2 test changes [buffer]
|
|
||||||
call hd_read
|
|
||||||
cmp [hd_error], 0
|
|
||||||
jnz problem_fat_dec_count
|
|
||||||
|
|
||||||
push 0
|
|
||||||
mov eax, [PARTITION_END]
|
|
||||||
sub eax, [PARTITION_START]
|
|
||||||
inc eax
|
|
||||||
push eax
|
|
||||||
push 0
|
|
||||||
push [PARTITION_START]
|
|
||||||
push ebp
|
|
||||||
push ebp
|
|
||||||
mov ebp, esp
|
|
||||||
mov esi, 'old' ; special value: there is no DISK structure
|
|
||||||
push 1 ; bootsector read successfully
|
|
||||||
call fat_create_partition
|
|
||||||
add esp, 4*7
|
|
||||||
test eax, eax
|
|
||||||
jz problem_fat_dec_count
|
|
||||||
mov [fs_dependent_data_start.partition], eax
|
|
||||||
mov al, [eax+FAT.fs_type]
|
|
||||||
mov [fs_type], al
|
|
||||||
|
|
||||||
popad
|
|
||||||
call free_hd_channel
|
|
||||||
mov [hd1_status], 0 ; free
|
|
||||||
ret
|
|
BIN
kernel/branches/Kolibri-acpi/gui/char2_et.mt
Normal file
BIN
kernel/branches/Kolibri-acpi/gui/char2_et.mt
Normal file
Binary file not shown.
BIN
kernel/branches/Kolibri-acpi/gui/char_et.mt
Normal file
BIN
kernel/branches/Kolibri-acpi/gui/char_et.mt
Normal file
Binary file not shown.
@ -2036,9 +2036,9 @@ window._.window_activate: ;////////////////////////////////////////////////////
|
|||||||
|
|
||||||
; if type of current active window is 3 or 4, it must be redrawn
|
; if type of current active window is 3 or 4, it must be redrawn
|
||||||
mov ebx, [TASK_COUNT]
|
mov ebx, [TASK_COUNT]
|
||||||
|
|
||||||
; DEBUGF 1, "K : TASK_COUNT (0x%x)\n", ebx
|
; DEBUGF 1, "K : TASK_COUNT (0x%x)\n", ebx
|
||||||
|
|
||||||
movzx ebx, word[WIN_POS + ebx * 2]
|
movzx ebx, word[WIN_POS + ebx * 2]
|
||||||
shl ebx, 5
|
shl ebx, 5
|
||||||
add eax, window_data
|
add eax, window_data
|
||||||
@ -2068,13 +2068,13 @@ align 4
|
|||||||
cmp eax, [TASK_COUNT]
|
cmp eax, [TASK_COUNT]
|
||||||
jae .move_self_up
|
jae .move_self_up
|
||||||
inc eax
|
inc eax
|
||||||
|
|
||||||
; push ebx
|
; push ebx
|
||||||
; xor ebx,ebx
|
; xor ebx,ebx
|
||||||
; mov bx,[WIN_STACK + eax * 2]
|
; mov bx,[WIN_STACK + eax * 2]
|
||||||
; DEBUGF 1, "K : DEC WIN_STACK (0x%x)\n",ebx
|
; DEBUGF 1, "K : DEC WIN_STACK (0x%x)\n",ebx
|
||||||
; pop ebx
|
; pop ebx
|
||||||
|
|
||||||
cmp [WIN_STACK + eax * 2], bx
|
cmp [WIN_STACK + eax * 2], bx
|
||||||
jbe .next_stack_window
|
jbe .next_stack_window
|
||||||
dec word[WIN_STACK + eax * 2]
|
dec word[WIN_STACK + eax * 2]
|
||||||
@ -2162,7 +2162,7 @@ align 4
|
|||||||
mov word[MOUSE_SCROLL_V], 0
|
mov word[MOUSE_SCROLL_V], 0
|
||||||
pop ebx eax
|
pop ebx eax
|
||||||
ret
|
ret
|
||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
align 4
|
align 4
|
||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
window._.check_window_draw: ;//////////////////////////////////////////////////
|
window._.check_window_draw: ;//////////////////////////////////////////////////
|
||||||
|
@ -759,9 +759,10 @@ no_mode_0x12:
|
|||||||
; Initialize system timer (IRQ0)
|
; Initialize system timer (IRQ0)
|
||||||
call PIT_init
|
call PIT_init
|
||||||
|
|
||||||
; CALCULATE FAT CHAIN FOR RAMDISK
|
; Register ramdisk file system
|
||||||
|
mov esi, boot_initramdisk
|
||||||
call calculatefatchain
|
call boot_log
|
||||||
|
call ramdisk_init
|
||||||
|
|
||||||
mov esi, boot_initapic
|
mov esi, boot_initapic
|
||||||
call boot_log
|
call boot_log
|
||||||
@ -1333,8 +1334,8 @@ proc osloop_has_work?
|
|||||||
jnz .yes
|
jnz .yes
|
||||||
call stack_handler_has_work?
|
call stack_handler_has_work?
|
||||||
jnz .yes
|
jnz .yes
|
||||||
; call check_fdd_motor_status_has_work?
|
call check_fdd_motor_status_has_work?
|
||||||
; jnz .yes
|
jnz .yes
|
||||||
call check_ATAPI_device_event_has_work?
|
call check_ATAPI_device_event_has_work?
|
||||||
jnz .yes
|
jnz .yes
|
||||||
call check_lights_state_has_work?
|
call check_lights_state_has_work?
|
||||||
@ -2673,29 +2674,14 @@ endg
|
|||||||
align 4
|
align 4
|
||||||
sys_cachetodiskette:
|
sys_cachetodiskette:
|
||||||
cmp ebx, 1
|
cmp ebx, 1
|
||||||
jne .no_floppy_a_save
|
jb .no_floppy_save
|
||||||
mov [flp_number], 1
|
|
||||||
jmp .save_image_on_floppy
|
|
||||||
;--------------------------------------
|
|
||||||
align 4
|
|
||||||
.no_floppy_a_save:
|
|
||||||
cmp ebx, 2
|
cmp ebx, 2
|
||||||
jne .no_floppy_b_save
|
ja .no_floppy_save
|
||||||
mov [flp_number], 2
|
|
||||||
;--------------------------------------
|
|
||||||
align 4
|
|
||||||
.save_image_on_floppy:
|
|
||||||
call save_image
|
call save_image
|
||||||
mov [esp + 32], dword 0
|
mov [esp + 32], eax
|
||||||
cmp [FDC_Status], 0
|
ret
|
||||||
je .yes_floppy_save
|
.no_floppy_save:
|
||||||
;--------------------------------------
|
|
||||||
align 4
|
|
||||||
.no_floppy_b_save:
|
|
||||||
mov [esp + 32], dword 1
|
mov [esp + 32], dword 1
|
||||||
;--------------------------------------
|
|
||||||
align 4
|
|
||||||
.yes_floppy_save:
|
|
||||||
ret
|
ret
|
||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
uglobal
|
uglobal
|
||||||
@ -3268,7 +3254,7 @@ sys_cpuusage:
|
|||||||
|
|
||||||
; Keyboard mode (+75)
|
; Keyboard mode (+75)
|
||||||
mov al, byte [ecx*8 + SLOT_BASE + APPDATA.keyboard_mode]
|
mov al, byte [ecx*8 + SLOT_BASE + APPDATA.keyboard_mode]
|
||||||
stosb
|
stosb
|
||||||
|
|
||||||
pop esi
|
pop esi
|
||||||
pop edi
|
pop edi
|
||||||
@ -5266,19 +5252,6 @@ align 4
|
|||||||
|
|
||||||
align 4
|
align 4
|
||||||
|
|
||||||
syscall_openramdiskfile: ; OpenRamdiskFile
|
|
||||||
|
|
||||||
mov eax, ebx
|
|
||||||
mov ebx, ecx
|
|
||||||
mov ecx, edx
|
|
||||||
mov edx, esi
|
|
||||||
mov esi, 12
|
|
||||||
call fileread
|
|
||||||
mov [esp+32], eax
|
|
||||||
ret
|
|
||||||
|
|
||||||
align 4
|
|
||||||
|
|
||||||
syscall_drawrect: ; DrawRect
|
syscall_drawrect: ; DrawRect
|
||||||
|
|
||||||
mov edi, edx ; color + gradient
|
mov edi, edx ; color + gradient
|
||||||
@ -5638,13 +5611,7 @@ set_screen:
|
|||||||
; eax - new Screen_Max_X
|
; eax - new Screen_Max_X
|
||||||
; ecx - new BytesPerScanLine
|
; ecx - new BytesPerScanLine
|
||||||
; edx - new Screen_Max_Y
|
; edx - new Screen_Max_Y
|
||||||
cmp eax, [Screen_Max_X]
|
|
||||||
jne .set
|
|
||||||
|
|
||||||
cmp edx, [Screen_Max_Y]
|
|
||||||
jne .set
|
|
||||||
ret
|
|
||||||
.set:
|
|
||||||
pushfd
|
pushfd
|
||||||
cli
|
cli
|
||||||
|
|
||||||
@ -5783,12 +5750,11 @@ yes_shutdown_param:
|
|||||||
cli
|
cli
|
||||||
|
|
||||||
if ~ defined extended_primary_loader
|
if ~ defined extended_primary_loader
|
||||||
mov eax, kernel_file ; load kernel.mnt to 0x7000:0
|
; load kernel.mnt to 0x7000:0
|
||||||
movi esi, 12
|
mov ebx, kernel_file_load
|
||||||
xor ebx, ebx
|
pushad
|
||||||
or ecx, -1
|
call file_system_lfn
|
||||||
mov edx, OS_BASE+0x70000
|
popad
|
||||||
call fileread
|
|
||||||
|
|
||||||
mov esi, restart_kernel_4000+OS_BASE+0x10000 ; move kernel re-starter to 0x4000:0
|
mov esi, restart_kernel_4000+OS_BASE+0x10000 ; move kernel re-starter to 0x4000:0
|
||||||
mov edi, OS_BASE+0x40000
|
mov edi, OS_BASE+0x40000
|
||||||
@ -5802,8 +5768,6 @@ end if
|
|||||||
; cld
|
; cld
|
||||||
; rep movsd
|
; rep movsd
|
||||||
|
|
||||||
call restorefatchain
|
|
||||||
|
|
||||||
call IRQ_mask_all
|
call IRQ_mask_all
|
||||||
|
|
||||||
if 0
|
if 0
|
||||||
|
@ -185,11 +185,9 @@ include "gui/button.inc"
|
|||||||
|
|
||||||
include "blkdev/disk.inc" ; support for plug-n-play disks
|
include "blkdev/disk.inc" ; support for plug-n-play disks
|
||||||
include "blkdev/disk_cache.inc" ; caching for plug-n-play disks
|
include "blkdev/disk_cache.inc" ; caching for plug-n-play disks
|
||||||
include "fs/fs.inc" ; syscall
|
|
||||||
include "fs/fat32.inc" ; read / write for fat32 filesystem
|
|
||||||
include "fs/ntfs.inc" ; read / write for ntfs filesystem
|
|
||||||
include "fs/fat12.inc" ; read / write for fat12 filesystem
|
|
||||||
include "blkdev/rd.inc" ; ramdisk read /write
|
include "blkdev/rd.inc" ; ramdisk read /write
|
||||||
|
include "fs/fat.inc" ; read / write for fat filesystem
|
||||||
|
include "fs/ntfs.inc" ; read / write for ntfs filesystem
|
||||||
include "fs/fs_lfn.inc" ; syscall, version 2
|
include "fs/fs_lfn.inc" ; syscall, version 2
|
||||||
include "fs/iso9660.inc" ; read for iso9660 filesystem CD
|
include "fs/iso9660.inc" ; read for iso9660 filesystem CD
|
||||||
include "fs/ext2/ext2.asm" ; read / write for ext2 filesystem
|
include "fs/ext2/ext2.asm" ; read / write for ext2 filesystem
|
||||||
|
@ -198,8 +198,7 @@
|
|||||||
; 0x800A0000 -> AFFFF screen access area
|
; 0x800A0000 -> AFFFF screen access area
|
||||||
; 0x800B0000 -> FFFFF bios rest in peace -area (320k) ?
|
; 0x800B0000 -> FFFFF bios rest in peace -area (320k) ?
|
||||||
; 0x80100000 -> 27FFFF diskette image (1m5)
|
; 0x80100000 -> 27FFFF diskette image (1m5)
|
||||||
; 0x80280000 -> 281FFF ramdisk fat (8k)
|
; 0x80280000 -> 283FFF free (16k)
|
||||||
; 0x80282000 -> 283FFF floppy fat (8k)
|
|
||||||
;
|
;
|
||||||
; 0x80284000 -> 28BFFF HDD DMA AREA (32k)
|
; 0x80284000 -> 28BFFF HDD DMA AREA (32k)
|
||||||
; 0x8028C000 -> 297FFF free (48k)
|
; 0x8028C000 -> 297FFF free (48k)
|
||||||
|
52
kernel/branches/Kolibri-acpi/readme-ext-loader.txt
Normal file
52
kernel/branches/Kolibri-acpi/readme-ext-loader.txt
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
При компиляции ядра можно задать - например, в lang.inc, - дополнительный
|
||||||
|
параметр extended_primary_loader=1; он переключает ядро на альтернативный
|
||||||
|
способ загрузки. Загрузка несовместима
|
||||||
|
с основой версией ядра; требуется специальный первичный загрузчик, существующие
|
||||||
|
собраны в папке bootloader/extended_primary_loader.
|
||||||
|
Есть варианты загрузки с FAT12/FAT16/FAT32/ISO,
|
||||||
|
есть вариант загрузчика, встраивающегося в загрузку Windows. Встраивание
|
||||||
|
в GRUB аналогично описанному для основного способа загрузки -
|
||||||
|
последним загрузчиком в цепочке
|
||||||
|
при этом оказывается тот, который установлен в образе дискеты FAT12.
|
||||||
|
|
||||||
|
При загрузке поддерживается опрос параметров из файла config.ini,
|
||||||
|
но не поддерживается сохранение выбранных параметров. Файл config.ini
|
||||||
|
ищется рядом с первичным загрузчиком, как и ядро kernel.mnt; в случае
|
||||||
|
загрузчика с дискеты эти файлы располагаются на самой дискете,
|
||||||
|
в случае других загрузчиков - рядом с первичным загрузчиком вне образа.
|
||||||
|
|
||||||
|
Если config.ini не найден, используются умолчальные значения. Если
|
||||||
|
config.ini найден, то он разбивается на строчки, строчки должны иметь
|
||||||
|
вид <параметр>=<значение>, перед параметром и вокруг знака равенства
|
||||||
|
могут быть пробелы, всё, что идёт в строке после значения, игнорируется.
|
||||||
|
Параметры чувствительны к регистру символов.
|
||||||
|
Строки, не имеющие такого вида, а также строки, в которых параметр неизвестен,
|
||||||
|
а также строки, в которых значение недопустимо, игнорируются.
|
||||||
|
|
||||||
|
Все числа должны быть целыми неотрицательными, записанными в десятичной
|
||||||
|
системе счисления. Булевские значения кодируются следующим образом:
|
||||||
|
0=off=no соответствует выключенному параметру, 1=on=yes - включённому.
|
||||||
|
|
||||||
|
Известные параметры:
|
||||||
|
|
||||||
|
timeout=<число секунд> задаёт время ожидания в экране выбора параметров.
|
||||||
|
Если таймаут больше 9, используется значение 9. Значение по умолчанию 5.
|
||||||
|
|
||||||
|
resolution=<ширина>*<высота> или <ширина>x<высота> задаёт желаемое
|
||||||
|
разрешение графического режима. Если такого графического режима,
|
||||||
|
устраивающего систему, не найдено, параметр игнорируется. По умолчанию
|
||||||
|
пробуются последовательно разрешения 1024*768, 800*600, 640*480.
|
||||||
|
|
||||||
|
vbemode=<номер видеорежима VBE> задаёт желаемый графический режим.
|
||||||
|
Если такой режим не существует или не устраивает систему, параметр
|
||||||
|
игнорируется. Параметр более приоритетен, чем resolution. Умолчального
|
||||||
|
значения нет.
|
||||||
|
|
||||||
|
vrr=<включить VRR> - булевский параметр. Умолчальное значение 0.
|
||||||
|
|
||||||
|
biosdisks=<включить доступ к дискам через BIOS> - булевский параметр.
|
||||||
|
Умолчальное значение 1.
|
||||||
|
|
||||||
|
imgfrom=<источник рамдиска>. 1 - грузить дискету, 2 - грузить файл
|
||||||
|
kolibri.img, находящийся рядом с первичным загрузчиком. Умолчальное
|
||||||
|
значение 1 при загрузке с дискеты и 2 в противном случае.
|
Binary file not shown.
Before Width: | Height: | Size: 584 B |
Binary file not shown.
Before Width: | Height: | Size: 584 B |
@ -1,38 +0,0 @@
|
|||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;; ;;
|
|
||||||
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;;
|
|
||||||
;; Distributed under terms of the GNU General Public License ;;
|
|
||||||
;; ;;
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
|
|
||||||
include 'me_skin.inc'
|
|
||||||
|
|
||||||
SKIN_PARAMS \
|
|
||||||
height = bmp_base.height,\ ; skin height
|
|
||||||
margins = [5:1:43:1],\ ; margins [left:top:right:bottom]
|
|
||||||
colors active = [binner=0x00081d:\ ; border inner color
|
|
||||||
bouter=0x00081d:\ ; border outer color
|
|
||||||
bframe=0x0054e7],\ ; border frame color
|
|
||||||
colors inactive = [binner=0x00081d:\ ; border inner color
|
|
||||||
bouter=0x00081d:\ ; border outer color
|
|
||||||
bframe=0x1a8acc],\ ; border frame color
|
|
||||||
dtp = 'myblue.dtp' ; dtp colors
|
|
||||||
|
|
||||||
SKIN_BUTTONS \
|
|
||||||
close = [-21:3][16:16],\ ; buttons coordinates
|
|
||||||
minimize = [-39:3][16:16] ; [left:top][width:height]
|
|
||||||
|
|
||||||
SKIN_BITMAPS \
|
|
||||||
left active = bmp_left,\ ; skin bitmaps pointers
|
|
||||||
left inactive = bmp_left1,\
|
|
||||||
oper active = bmp_oper,\
|
|
||||||
oper inactive = bmp_oper1,\
|
|
||||||
base active = bmp_base,\
|
|
||||||
base inactive = bmp_base1
|
|
||||||
|
|
||||||
BITMAP bmp_left ,'left.bmp' ; skin bitmaps
|
|
||||||
BITMAP bmp_oper ,'oper.bmp'
|
|
||||||
BITMAP bmp_base ,'base.bmp'
|
|
||||||
BITMAP bmp_left1,'left_1.bmp'
|
|
||||||
BITMAP bmp_oper1,'oper_1.bmp'
|
|
||||||
BITMAP bmp_base1,'base_1.bmp'
|
|
Binary file not shown.
Before Width: | Height: | Size: 670 B |
Binary file not shown.
Before Width: | Height: | Size: 670 B |
@ -1,242 +0,0 @@
|
|||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;; ;;
|
|
||||||
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;;
|
|
||||||
;; Distributed under terms of the GNU General Public License ;;
|
|
||||||
;; ;;
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
|
|
||||||
;============================================================================
|
|
||||||
; This file should be used to generate skins of new standard
|
|
||||||
;============================================================================
|
|
||||||
; skin file structure:
|
|
||||||
;----------------------------------------------------------------------------
|
|
||||||
; header:
|
|
||||||
; dd 'SKIN'
|
|
||||||
; dd = version (1 for now)
|
|
||||||
; dd @ params
|
|
||||||
; dd @ buttons
|
|
||||||
; dd @ bitmaps
|
|
||||||
; ...
|
|
||||||
;----------------------------------------------------------------------------
|
|
||||||
; NOTE: order of sections listed below is insignificant
|
|
||||||
; since they're identified by pointer in above header
|
|
||||||
;----------------------------------------------------------------------------
|
|
||||||
; ...
|
|
||||||
; params:
|
|
||||||
; dd = skin height
|
|
||||||
; dw = right margin
|
|
||||||
; dw = left margin
|
|
||||||
; dw = bottom margin
|
|
||||||
; dw = top margin
|
|
||||||
; dd = inner line color
|
|
||||||
; dd = outer line color
|
|
||||||
; dd = frame color
|
|
||||||
; dd = dtp file size
|
|
||||||
; ?? = dtp file itself
|
|
||||||
; ...
|
|
||||||
;----------------------------------------------------------------------------
|
|
||||||
; ...
|
|
||||||
; buttons:
|
|
||||||
; dd = button type (1 = close, 2 = minimize)
|
|
||||||
; dw = left button coord (could be negative)
|
|
||||||
; dw = top button coord (could be negative)
|
|
||||||
; dw = button width
|
|
||||||
; dw = button height
|
|
||||||
; ... etc for all buttons
|
|
||||||
; dd = 0 (end of buttons list)
|
|
||||||
; ...
|
|
||||||
;----------------------------------------------------------------------------
|
|
||||||
; ...
|
|
||||||
; bitmaps:
|
|
||||||
; dw = bitmap kind (1 = left, 2 = oper, 3 = base)
|
|
||||||
; dw = bitmap type (1 = active, 0 = inactive)
|
|
||||||
; dd @ bitmap
|
|
||||||
; ... etc for all bitmaps
|
|
||||||
; dd 0 (end of bitmaps list)
|
|
||||||
; ...
|
|
||||||
;----------------------------------------------------------------------------
|
|
||||||
; ...
|
|
||||||
; bitmap:
|
|
||||||
; dd = bitmap width
|
|
||||||
; dd = bitmap height
|
|
||||||
; ?? = raw bitmap data
|
|
||||||
; ... etc for all bitmaps
|
|
||||||
; ...
|
|
||||||
;============================================================================
|
|
||||||
|
|
||||||
dd 'SKIN',1,__params__,__buttons__,__bitmaps__
|
|
||||||
|
|
||||||
struc BITMAPFILEHEADER {
|
|
||||||
.bfType dw ? ; WORD
|
|
||||||
.bfSize dd ? ; DWORD
|
|
||||||
.bfReserved1 dw ? ; WORD
|
|
||||||
.bfReserved2 dw ? ; WORD
|
|
||||||
.bfOffBits dd ? ; DWORD
|
|
||||||
}
|
|
||||||
|
|
||||||
struc BITMAPINFOHEADER {
|
|
||||||
.biSize dd ? ; DWORD
|
|
||||||
.biWidth dd ? ; LONG
|
|
||||||
.biHeight dd ? ; LONG
|
|
||||||
.biPlanes dw ? ; WORD
|
|
||||||
.biBitCount dw ? ; WORD
|
|
||||||
.biCompression dd ? ; DWORD
|
|
||||||
.biSizeImage dd ? ; DWORD
|
|
||||||
.biXPelsPerMeter dd ? ; LONG
|
|
||||||
.biYPelsPerMeter dd ? ; LONG
|
|
||||||
.biClrUsed dd ? ; DWORD
|
|
||||||
.biClrImportant dd ? ; DWORD
|
|
||||||
}
|
|
||||||
|
|
||||||
struc _bmp {
|
|
||||||
.h BITMAPFILEHEADER
|
|
||||||
.i BITMAPINFOHEADER
|
|
||||||
}
|
|
||||||
virtual at 0
|
|
||||||
_bmp _bmp
|
|
||||||
end virtual
|
|
||||||
|
|
||||||
macro BITMAP _name*,_fname*
|
|
||||||
{
|
|
||||||
local w,h,a,r,g,b
|
|
||||||
virtual at 0
|
|
||||||
file _fname
|
|
||||||
load w dword from _bmp.i.biWidth
|
|
||||||
load h dword from _bmp.i.biHeight
|
|
||||||
end virtual
|
|
||||||
align 4
|
|
||||||
label _name
|
|
||||||
.width = w
|
|
||||||
.height = h
|
|
||||||
dd w,h
|
|
||||||
a=54+(w*3+(w mod 4))*(h-1)
|
|
||||||
size = $
|
|
||||||
repeat h
|
|
||||||
repeat w
|
|
||||||
virtual at 0
|
|
||||||
file _fname
|
|
||||||
load r from a+0
|
|
||||||
load g from a+1
|
|
||||||
load b from a+2
|
|
||||||
end virtual
|
|
||||||
db r,g,b
|
|
||||||
a=a+3
|
|
||||||
end repeat
|
|
||||||
a=a-w*3*2-(w mod 4)
|
|
||||||
end repeat
|
|
||||||
}
|
|
||||||
|
|
||||||
macro define_colors name,[col,val]
|
|
||||||
{
|
|
||||||
common
|
|
||||||
local a,b,c
|
|
||||||
forward
|
|
||||||
match =binner,col \{ a = val \}
|
|
||||||
match =bouter,col \{ b = val \}
|
|
||||||
match =bframe,col \{ c = val \}
|
|
||||||
common
|
|
||||||
name equ a,b,c
|
|
||||||
}
|
|
||||||
|
|
||||||
macro SKIN_PARAMS [a]
|
|
||||||
{
|
|
||||||
common
|
|
||||||
local _height,_margins,_colors,_colors_1,_dtp,_dtp_sz
|
|
||||||
__params__:
|
|
||||||
forward
|
|
||||||
match qq == ww,a
|
|
||||||
\{
|
|
||||||
match =height,qq \\{ _height = ww \\}
|
|
||||||
match =margins,qq \\{
|
|
||||||
match [q1:q2:q3:q4],ww
|
|
||||||
\\\{
|
|
||||||
_margins equ q3,q1,q4,q2
|
|
||||||
\\\}
|
|
||||||
\\}
|
|
||||||
match =colors =active,qq
|
|
||||||
\\{
|
|
||||||
match [q10==q11:q20==q21:q30==q31],ww
|
|
||||||
\\\{
|
|
||||||
define_colors _colors,q10,q11,q20,q21,q30,q31
|
|
||||||
\\\}
|
|
||||||
\\}
|
|
||||||
match =colors =inactive,qq
|
|
||||||
\\{
|
|
||||||
match [q10==q11:q20==q21:q30==q31],ww
|
|
||||||
\\\{
|
|
||||||
define_colors _colors_1,q10,q11,q20,q21,q30,q31
|
|
||||||
\\\}
|
|
||||||
\\}
|
|
||||||
match =dtp,qq \\{ _dtp equ ww \\}
|
|
||||||
\}
|
|
||||||
common
|
|
||||||
dd _height
|
|
||||||
dw _margins
|
|
||||||
dd _colors,_colors_1
|
|
||||||
virtual at 0
|
|
||||||
file _dtp
|
|
||||||
_dtp_sz = $
|
|
||||||
end virtual
|
|
||||||
dd _dtp_sz
|
|
||||||
file _dtp
|
|
||||||
}
|
|
||||||
|
|
||||||
macro SKIN_BUTTONS [a]
|
|
||||||
{
|
|
||||||
common
|
|
||||||
local btn
|
|
||||||
__buttons__:
|
|
||||||
forward
|
|
||||||
match qq == ww,a
|
|
||||||
\{
|
|
||||||
btn = 0
|
|
||||||
match =close,qq \\{ btn = 1 \\}
|
|
||||||
match =minimize,qq \\{ btn = 2 \\}
|
|
||||||
match [q1:q2][q3:q4],ww
|
|
||||||
\\{
|
|
||||||
if btn <> 0
|
|
||||||
dd btn
|
|
||||||
dw q1,q2,q3,q4
|
|
||||||
end if
|
|
||||||
\\}
|
|
||||||
\}
|
|
||||||
common
|
|
||||||
dd 0
|
|
||||||
}
|
|
||||||
|
|
||||||
macro SKIN_BITMAPS [a]
|
|
||||||
{
|
|
||||||
common
|
|
||||||
local bmp
|
|
||||||
__bitmaps__:
|
|
||||||
forward
|
|
||||||
match qq == ww,a
|
|
||||||
\{
|
|
||||||
bmp=-1
|
|
||||||
match qqq =active,qq \\{ bmp = 1 \\}
|
|
||||||
match qqq =inactive,qq \\{ bmp = 0 \\}
|
|
||||||
match =left qqq,qq
|
|
||||||
\\{
|
|
||||||
if bmp >= 0
|
|
||||||
dw 1,bmp
|
|
||||||
dd ww
|
|
||||||
end if
|
|
||||||
\\}
|
|
||||||
match =oper qqq,qq
|
|
||||||
\\{
|
|
||||||
if bmp >= 0
|
|
||||||
dw 2,bmp
|
|
||||||
dd ww
|
|
||||||
end if
|
|
||||||
\\}
|
|
||||||
match =base qqq,qq
|
|
||||||
\\{
|
|
||||||
if bmp >= 0
|
|
||||||
dw 3,bmp
|
|
||||||
dd ww
|
|
||||||
end if
|
|
||||||
\\}
|
|
||||||
\}
|
|
||||||
common
|
|
||||||
dd 0
|
|
||||||
}
|
|
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 2.6 KiB |
Binary file not shown.
Before Width: | Height: | Size: 2.6 KiB |
Loading…
Reference in New Issue
Block a user