Embedded KOS (AMD/HT version)

git-svn-id: svn://kolibrios.org@1505 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
Artem Jerdev (art_zh) 2010-06-25 16:47:51 +00:00
parent 2ccee1b676
commit 9022bde80a
1793 changed files with 1006250 additions and 0 deletions

View File

@ -0,0 +1,546 @@
;**********************************************************
; Непосредственная работа с устройством СD (ATAPI)
;**********************************************************
; Автор исходного текста Кулаков Владимир Геннадьевич.
; Адаптация и доработка Mario79
; Процедура для полного считывания всех
; данных из сектора компакт-диска
; Автор текста программы Кулаков Владимир Геннадьевич.
; Максимальное количество повторений операции чтения
MaxRetr equ 3
; Предельное время ожидания готовности к приему команды
; (в тиках)
BSYWaitTime equ 1000 ;2
;*************************************************
;* ПОЛНОЕ ЧТЕНИЕ СЕКТОРА КОМПАКТ-ДИСКА *
;* Считываются данные пользователя, информация *
;* субканала и контрольная информация *
;* Входные параметры передаются через глобальные *
;* перменные: *
;* ChannelNumber - номер канала; *
;* DiskNumber - номер диска на канале; *
;* CDSectorAddress - адрес считываемого сектора. *
;* Данные считывается в массив CDDataBuf. *
;*************************************************
ReadCD:
pusha
; Задать размер сектора
mov [CDBlockSize],2048 ;2352
; Очистить буфер пакетной команды
call clear_packet_buffer
; Сформировать пакетную команду для считывания
; сектора данных
; Задать код команды Read CD
mov [PacketCommand],byte 0x28 ;0xBE
; Задать адрес сектора
mov AX,word [CDSectorAddress+2]
xchg AL,AH
mov word [PacketCommand+2],AX
mov AX,word [CDSectorAddress]
xchg AL,AH
mov word [PacketCommand+4],AX
; mov eax,[CDSectorAddress]
; mov [PacketCommand+2],eax
; Задать количество считываемых секторов
mov [PacketCommand+8],byte 1
; Задать считывание данных в полном объеме
; mov [PacketCommand+9],byte 0xF8
; Подать команду
call SendPacketDatCommand
; call test_mario79
popa
ret
;********************************************
;* ЧТЕНИЕ СЕКТОРА С ПОВТОРАМИ *
;* Многократное повторение чтения при сбоях *
;********************************************
ReadCDWRetr:
pusha
; Цикл, пока команда не выполнена успешно или не
; исчерпано количество попыток
mov ECX,MaxRetr
@@NextRetr:
; Подать команду
call ReadCD
cmp [DevErrorCode],0
je @@End_4
; Задержка на 2,5 секунды
mov EAX,[timer_ticks]
add EAX,250 ;50
@@Wait:
call change_task
cmp EAX,[timer_ticks]
ja @@Wait
loop @@NextRetr
; call test_mario79
; Сообщение об ошибке
; mov SI,offset ErrS
; call FatalError
@@End_4:
popa
ret
; Универсальные процедуры, обеспечивающие выполнение
; пакетных команд в режиме PIO
;
; Автор текста программы Кулаков Владимир Геннадьевич.
; Максимально допустимое время ожидания реакции
; устройства на пакетную команду (в тиках)
MaxCDWaitTime equ 1000 ;200 ;10 секунд
; Область памяти для формирования пакетной команды
PacketCommand: rb 12 ;DB 12 DUP (?)
; Область памяти для приема данных от дисковода
;CDDataBuf DB 4096 DUP (0)
; Размер принимаемого блока данных в байтах
CDBlockSize DW ?
; Адрес считываемого сектора данных
CDSectorAddress: DD ?
; Время начала очередной операции с диском
TickCounter_1 DD 0
; Время начала ожидания готовности устройства
WURStartTime DD 0
; указатель буфера для считывания
CDDataBuf_pointer dd 0
;****************************************************
;* ПОСЛАТЬ УСТРОЙСТВУ ATAPI ПАКЕТНУЮ КОМАНДУ, *
;* ПРЕДУСМАТРИВАЮЩУЮ ПЕРЕДАЧУ ОДНОГО СЕКТОРА ДАННЫХ *
;* РАЗМЕРОМ 2048 БАЙТ ОТ УСТРОЙСТВА К ХОСТУ *
;* Входные параметры передаются через глобальные *
;* перменные: *
;* ChannelNumber - номер канала; *
;* DiskNumber - номер диска на канале; *
;* PacketCommand - 12-байтный командный пакет; *
;* CDBlockSize - размер принимаемого блока данных. *
;****************************************************
SendPacketDatCommand:
pushad
; Задать режим CHS
mov [ATAAddressMode],0
; Послать ATA-команду передачи пакетной команды
mov [ATAFeatures],0
mov [ATASectorCount],0
mov [ATASectorNumber],0
; Загрузить размер передаваемого блока
mov AX,[CDBlockSize]
mov [ATACylinder],AX
mov [ATAHead],0
mov [ATACommand],0A0h
call SendCommandToHDD_1
; call test_mario79
cmp [DevErrorCode],0 ;проверить код ошибки
jne @@End_8 ;закончить, сохранив код ошибки
; Ожидание готовности дисковода к приему
; пакетной команды
mov DX,[ATABasePortAddr]
add DX,7 ;порт 1х7h
@@WaitDevice0:
call change_task
; Проверить время выполнения команды
mov EAX,[timer_ticks]
sub EAX,[TickCounter_1]
cmp EAX,BSYWaitTime
ja @@Err1_1 ;ошибка тайм-аута
; Проверить готовность
in AL,DX
test AL,80h ;состояние сигнала BSY
jnz @@WaitDevice0
test AL,1 ;состояние сигнала ERR
jnz @@Err6
test AL,08h ;состояние сигнала DRQ
jz @@WaitDevice0
; Послать пакетную команду
cli
mov DX,[ATABasePortAddr]
mov AX,[PacketCommand]
out DX,AX
mov AX,[PacketCommand+2]
out DX,AX
mov AX,[PacketCommand+4]
out DX,AX
mov AX,[PacketCommand+6]
out DX,AX
mov AX,[PacketCommand+8]
out DX,AX
mov AX,[PacketCommand+10]
out DX,AX
sti
; Ожидание готовности данных
mov DX,[ATABasePortAddr]
add DX,7 ;порт 1х7h
@@WaitDevice1:
call change_task
; Проверить время выполнения команды
mov EAX,[timer_ticks]
sub EAX,[TickCounter_1]
cmp EAX,MaxCDWaitTime
ja @@Err1_1 ;ошибка тайм-аута
; Проверить готовность
in AL,DX
test AL,80h ;состояние сигнала BSY
jnz @@WaitDevice1
test AL,1 ;состояние сигнала ERR
jnz @@Err6_temp
test AL,08h ;состояние сигнала DRQ
jz @@WaitDevice1
cli
; Принять блок данных от контроллера
mov EDI,[CDDataBuf_pointer] ;0x7000 ;CDDataBuf
; Загрузить адрес регистра данных контроллера
mov DX,[ATABasePortAddr] ;порт 1x0h
; Загрузить в счетчик размер блока в байтах
mov CX,[CDBlockSize]
; Вычислить размер блока в 16-разрядных словах
shr CX,1 ;разделить размер блока на 2
; Принять блок данных
cld
rep insw
sti
; Успешное завершение приема данных
jmp @@End_8
; Записать код ошибки
@@Err1_1:
mov [DevErrorCode],1
jmp @@End_8
@@Err6_temp:
mov [DevErrorCode],7
jmp @@End_8
@@Err6:
mov [DevErrorCode],6
@@End_8:
popad
ret
;***********************************************
;* ПОСЛАТЬ УСТРОЙСТВУ ATAPI ПАКЕТНУЮ КОМАНДУ, *
;* НЕ ПРЕДУСМАТРИВАЮЩУЮ ПЕРЕДАЧИ ДАННЫХ *
;* Входные параметры передаются через *
;* глобальные перменные: *
;* ChannelNumber - номер канала; *
;* DiskNumber - номер диска на канале; *
;* PacketCommand - 12-байтный командный пакет. *
;***********************************************
SendPacketNoDatCommand:
pushad
; Задать режим CHS
mov [ATAAddressMode],0
; Послать ATA-команду передачи пакетной команды
mov [ATAFeatures],0
mov [ATASectorCount],0
mov [ATASectorNumber],0
mov [ATACylinder],0
mov [ATAHead],0
mov [ATACommand],0A0h
call SendCommandToHDD_1
cmp [DevErrorCode],0 ;проверить код ошибки
jne @@End_9 ;закончить, сохранив код ошибки
; Ожидание готовности дисковода к приему
; пакетной команды
mov DX,[ATABasePortAddr]
add DX,7 ;порт 1х7h
@@WaitDevice0_1:
call change_task
; Проверить время ожидания
mov EAX,[timer_ticks]
sub EAX,[TickCounter_1]
cmp EAX,BSYWaitTime
ja @@Err1_3 ;ошибка тайм-аута
; Проверить готовность
in AL,DX
test AL,80h ;состояние сигнала BSY
jnz @@WaitDevice0_1
test AL,1 ;состояние сигнала ERR
jnz @@Err6_1
test AL,08h ;состояние сигнала DRQ
jz @@WaitDevice0_1
; Послать пакетную команду
; cli
mov DX,[ATABasePortAddr]
mov AX,word [PacketCommand]
out DX,AX
mov AX,word [PacketCommand+2]
out DX,AX
mov AX,word [PacketCommand+4]
out DX,AX
mov AX,word [PacketCommand+6]
out DX,AX
mov AX,word [PacketCommand+8]
out DX,AX
mov AX,word [PacketCommand+10]
out DX,AX
; sti
; Ожидание подтверждения приема команды
mov DX,[ATABasePortAddr]
add DX,7 ;порт 1х7h
@@WaitDevice1_1:
call change_task
; Проверить время выполнения команды
mov EAX,[timer_ticks]
sub EAX,[TickCounter_1]
cmp EAX,MaxCDWaitTime
ja @@Err1_3 ;ошибка тайм-аута
; Ожидать освобождения устройства
in AL,DX
test AL,80h ;состояние сигнала BSY
jnz @@WaitDevice1_1
test AL,1 ;состояние сигнала ERR
jnz @@Err6_1
test AL,40h ;состояние сигнала DRDY
jz @@WaitDevice1_1
jmp @@End_9
; Записать код ошибки
@@Err1_3:
mov [DevErrorCode],1
jmp @@End_9
@@Err6_1:
mov [DevErrorCode],6
@@End_9:
popad
ret
;****************************************************
;* ПОСЛАТЬ КОМАНДУ ЗАДАННОМУ ДИСКУ *
;* Входные параметры передаются через глобальные *
;* переменные: *
;* ChannelNumber - номер канала (1 или 2); *
;* DiskNumber - номер диска (0 или 1); *
;* ATAFeatures - "особенности"; *
;* ATASectorCount - количество секторов; *
;* ATASectorNumber - номер начального сектора; *
;* ATACylinder - номер начального цилиндра; *
;* ATAHead - номер начальной головки; *
;* ATAAddressMode - режим адресации (0-CHS, 1-LBA); *
;* ATACommand - код команды. *
;* После успешного выполнения функции: *
;* в ATABasePortAddr - базовый адрес HDD; *
;* в DevErrorCode - ноль. *
;* При возникновении ошибки в DevErrorCode будет *
;* возвращен код ошибки. *
;****************************************************
SendCommandToHDD_1:
pushad
; Проверить значение кода режима
cmp [ATAAddressMode],1
ja @@Err2_4
; Проверить корректность номера канала
mov BX,[ChannelNumber]
cmp BX,1
jb @@Err3_4
cmp BX,2
ja @@Err3_4
; Установить базовый адрес
dec BX
shl BX,1
movzx ebx,bx
mov AX,[ebx+StandardATABases]
mov [ATABasePortAddr],AX
; Ожидание готовности HDD к приему команды
; Выбрать нужный диск
mov DX,[ATABasePortAddr]
add DX,6 ;адрес регистра головок
mov AL,[DiskNumber]
cmp AL,1 ;проверить номера диска
ja @@Err4_4
shl AL,4
or AL,10100000b
out DX,AL
; Ожидать, пока диск не будет готов
inc DX
; mov ecx,0xfff
mov eax,[timer_ticks]
mov [TickCounter_1],eax
@@WaitHDReady_2:
call change_task
; Проверить время ожидания
; dec ecx
; cmp ecx,0
; je @@Err1
mov eax,[timer_ticks]
sub eax,[TickCounter_1]
cmp eax,BSYWaitTime ;300 ;ожидать 3 сек.
ja @@Err1_4 ;ошибка тайм-аута
; Прочитать регистр состояния
in AL,DX
; Проверить состояние сигнала BSY
test AL,80h
jnz @@WaitHDReady_2
; Проверить состояние сигнала DRQ
test AL,08h
jnz @@WaitHDReady_2
; Загрузить команду в регистры контроллера
cli
mov DX,[ATABasePortAddr]
inc DX ;регистр "особенностей"
mov AL,[ATAFeatures]
out DX,AL
inc DX ;счетчик секторов
mov AL,[ATASectorCount]
out DX,AL
inc DX ;регистр номера сектора
mov AL,[ATASectorNumber]
out DX,AL
inc DX ;номер цилиндра (младший байт)
mov AX,[ATACylinder]
out DX,AL
inc DX ;номер цилиндра (старший байт)
mov AL,AH
out DX,AL
inc DX ;номер головки/номер диска
mov AL,[DiskNumber]
shl AL,4
cmp [ATAHead],0Fh ;проверить номер головки
ja @@Err5_4
or AL,[ATAHead]
or AL,10100000b
mov AH,[ATAAddressMode]
shl AH,6
or AL,AH
out DX,AL
; Послать команду
mov AL,[ATACommand]
inc DX ;регистр команд
out DX,AL
sti
; Сбросить признак ошибки
mov [DevErrorCode],0
jmp @@End_10
; Записать код ошибки
@@Err1_4:
mov [DevErrorCode],1
jmp @@End_10
@@Err2_4:
mov [DevErrorCode],2
jmp @@End_10
@@Err3_4:
mov [DevErrorCode],3
jmp @@End_10
@@Err4_4:
mov [DevErrorCode],4
jmp @@End_10
@@Err5_4:
mov [DevErrorCode],5
; Завершение работы программы
@@End_10:
sti
popad
ret
;*************************************************
;* ОЖИДАНИЕ ГОТОВНОСТИ УСТРОЙСТВА К РАБОТЕ *
;* Входные параметры передаются через глобальные *
;* перменные: *
;* ChannelNumber - номер канала; *
;* DiskNumber - номер диска на канале. *
;*************************************************
WaitUnitReady:
pusha
; Запомнить время начала операции
mov EAX,[timer_ticks]
mov [WURStartTime],EAX
; Очистить буфер пакетной команды
call clear_packet_buffer
; Сформировать команду TEST UNIT READY
mov [PacketCommand],word 00h
; ЦИКЛ ОЖИДАНИЯ ГОТОВНОСТИ УСТРОЙСТВА
@@SendCommand:
; Подать команду проверки готовности
call SendPacketNoDatCommand
call change_task
; Проверить код ошибки
cmp [DevErrorCode],0
je @@End_11
; Проверить время ожидания готовности
mov EAX,[timer_ticks]
sub EAX,[WURStartTime]
cmp EAX,MaxCDWaitTime
jb @@SendCommand
; Ошибка тайм-аута
mov [DevErrorCode],1
@@End_11:
popa
ret
;*************************************************
;* ЗАГРУЗИТЬ НОСИТЕЛЬ В ДИСКОВОД *
;* Входные параметры передаются через глобальные *
;* перменные: *
;* ChannelNumber - номер канала; *
;* DiskNumber - номер диска на канале. *
;*************************************************
LoadMedium:
pusha
; Очистить буфер пакетной команды
call clear_packet_buffer
; Сформировать команду START/STOP UNIT
; Задать код команды
mov [PacketCommand],word 1Bh
; Задать операцию загрузки носителя
mov [PacketCommand+4],word 00000011b
; Подать команду
call SendPacketNoDatCommand
popa
ret
;*************************************************
;* ИЗВЛЕЧЬ НОСИТЕЛЬ ИЗ ДИСКОВОДА *
;* Входные параметры передаются через глобальные *
;* перменные: *
;* ChannelNumber - номер канала; *
;* DiskNumber - номер диска на канале. *
;*************************************************
UnloadMedium:
pusha
; Очистить буфер пакетной команды
call clear_packet_buffer
; Сформировать команду START/STOP UNIT
; Задать код команды
mov [PacketCommand],word 1Bh
; Задать операцию извлечения носителя
mov [PacketCommand+4],word 00000010b
; Подать команду
call SendPacketNoDatCommand
popa
ret
;*************************************************
;* ОПРЕДЕЛИТЬ ОБЩЕЕ КОЛИЧЕСТВО СЕКТОРОВ НА ДИСКЕ *
;* Входные параметры передаются через глобальные *
;* переменные: *
;* ChannelNumber - номер канала; *
;* DiskNumber - номер диска на канале. *
;*************************************************
ReadCapacity:
pusha
; Очистить буфер пакетной команды
call clear_packet_buffer
; Задать размер буфера в байтах
mov [CDBlockSize],8
; Сформировать команду READ CAPACITY
mov [PacketCommand],word 25h
; Подать команду
call SendPacketDatCommand
popa
ret
clear_packet_buffer:
; Очистить буфер пакетной команды
mov [PacketCommand],dword 0
mov [PacketCommand+4],dword 0
mov [PacketCommand+8],dword 0
ret

View File

@ -0,0 +1,261 @@
sys_cd_audio:
cmp word [cdbase],word 0
jnz @f
mov eax,1
ret
@@:
; eax=1 cdplay at ebx 0x00FFSSMM
; eax=2 get tracklist size of ecx to [ebx]
; eax=3 stop/pause playing
cmp eax,1
jnz nocdp
call sys_cdplay
ret
nocdp:
cmp eax,2
jnz nocdtl
mov edi,[TASK_BASE]
add edi,TASKDATA.mem_start
add ebx,[edi]
call sys_cdtracklist
ret
nocdtl:
cmp eax,3
jnz nocdpause
call sys_cdpause
ret
nocdpause:
mov eax,0xffffff01
ret
sys_cd_atapi_command:
pushad
mov dx,word [cdbase]
add dx,6
mov ax,word [cdid]
out dx,al
mov esi,10
call delay_ms
mov dx,word [cdbase]
add dx,7
in al,dx
and al,0x80
cmp al,0
jnz res
jmp cdl6
res:
mov dx,word [cdbase]
add dx,7
mov al,0x8
out dx,al
mov dx,word [cdbase]
add dx,0x206
mov al,0xe
out dx,al
mov esi,1
call delay_ms
mov dx,word [cdbase]
add dx,0x206
mov al,0x8
out dx,al
mov esi,30
call delay_ms
xor cx,cx
cdl5:
inc cx
cmp cx,10
jz cdl6
mov dx,word [cdbase]
add dx,7
in al,dx
and al,0x88
cmp al,0x00
jz cdl5
mov esi,100
call delay_ms
jmp cdl5
cdl6:
mov dx,word [cdbase]
add dx,4
mov al,0
out dx,al
mov dx,word [cdbase]
add dx,5
mov al,0
out dx,al
mov dx,word [cdbase]
add dx,7
mov al,0xec
out dx,al
mov esi,5
call delay_ms
mov dx,word [cdbase]
add dx,1
mov al,0
out dx,al
add dx,1
mov al,0
out dx,al
add dx,1
mov al,0
out dx,al
add dx,1
mov al,0
out dx,al
add dx,1
mov al,128
out dx,al
add dx,2
mov al,0xa0
out dx,al
xor cx,cx
mov dx,word [cdbase]
add dx,7
cdl1:
inc cx
cmp cx,100
jz cdl2
in al,dx
and ax,0x88
cmp al,0x8
jz cdl2
mov esi,2
call delay_ms
jmp cdl1
cdl2:
popad
ret
sys_cdplay:
mov ax,5
push ax
push ebx
cdplay:
call sys_cd_atapi_command
cli
mov dx,word [cdbase]
mov ax,0x0047
out dx,ax
mov al,1
mov ah,[esp+0] ; min xx
out dx,ax
mov ax,[esp+1] ; fr sec
out dx,ax
mov ax,256+99
out dx,ax
mov ax,0x0001
out dx,ax
mov ax,0x0000
out dx,ax
mov esi,10
call delay_ms
sti
add dx,7
in al,dx
test al,1
jz cdplayok
mov ax,[esp+4]
dec ax
mov [esp+4],ax
cmp ax,0
jz cdplayfail
jmp cdplay
cdplayfail:
cdplayok:
pop ebx
pop ax
xor eax, eax
ret
sys_cdtracklist:
push ebx
tcdplay:
call sys_cd_atapi_command
mov dx,word [cdbase]
mov ax,0x43+2*256
out dx,ax
mov ax,0x0
out dx,ax
mov ax,0x0
out dx,ax
mov ax,0x0
out dx,ax
mov ax,200
out dx,ax
mov ax,0x0
out dx,ax
in al,dx
mov cx,1000
mov dx,word [cdbase]
add dx,7
cld
cdtrnwewait:
mov esi,10
call delay_ms
in al,dx
and al,128
cmp al,0
jz cdtrl1
loop cdtrnwewait
cdtrl1:
; read the result
mov ecx,[esp+0]
mov dx,word [cdbase]
cdtrread:
add dx,7
in al,dx
and al,8
cmp al,8
jnz cdtrdone
sub dx,7
in ax,dx
mov [ecx],ax
add ecx,2
jmp cdtrread
cdtrdone:
pop ecx
xor eax, eax
ret
sys_cdpause:
call sys_cd_atapi_command
mov dx,word [cdbase]
mov ax,0x004B
out dx,ax
mov ax,0
out dx,ax
mov ax,0
out dx,ax
mov ax,0
out dx,ax
mov ax,0
out dx,ax
mov ax,0
out dx,ax
mov esi,10
call delay_ms
add dx,7
in al,dx
xor eax, eax
ret

View File

@ -0,0 +1,73 @@
iglobal
;function pointers.
fdc_irq_func dd fdc_null
endg
uglobal
dmasize db 0x0
dmamode db 0x0
endg
fdc_init: ;start with clean tracks.
mov edi,0xD201
mov al,0
mov ecx,160
rep stosb
ret
fdc_filesave: ;ebx: cluster to be saved.
pusha ;returns immediately. does not trigger a write.
mov eax,ebx
add eax,31
mov bl,18
div bl
mov ah,0
add eax,0xD201
mov [eax],byte 1 ;This track is now dirty.
popa
ret
fdc_irq:
call [fdc_irq_func]
fdc_null:
ret
save_image:
call reserve_flp
call restorefatchain
pusha
call check_label
cmp [FDC_Status],0
jne unnecessary_save_image
mov [FDD_Track],0 ; Öèëèíäð
mov [FDD_Head],0 ; Ñòîðîíà
mov [FDD_Sector],1 ; Ñåêòîð
mov esi,RAMDISK
call SeekTrack
save_image_1:
push esi
call take_data_from_application_1
pop esi
add esi,512
call WriteSectWithRetr
; call WriteSector
cmp [FDC_Status],0
jne unnecessary_save_image
inc [FDD_Sector]
cmp [FDD_Sector],19
jne save_image_1
mov [FDD_Sector],1
inc [FDD_Head]
cmp [FDD_Head],2
jne save_image_1
mov [FDD_Head],0
inc [FDD_Track]
call SeekTrack
cmp [FDD_Track],80
jne save_image_1
unnecessary_save_image:
mov [fdc_irq_func],fdc_null
popa
mov [flp_status],0
ret

View File

@ -0,0 +1,615 @@
;**********************************************************
; Непосредственная работа с контроллером гибкого диска
;**********************************************************
; Автор исходного текста Кулаков Владимир Геннадьевич.
; Адаптация и доработка Mario79
give_back_application_data: ; переслать приложению
mov edi,[TASK_BASE]
mov edi,[edi+TASKDATA.mem_start]
add edi,ecx
give_back_application_data_1:
mov esi,FDD_BUFF ;FDD_DataBuffer ;0x40000
xor ecx,ecx
mov cx,128
cld
rep movsd
ret
take_data_from_application: ; взять из приложени
mov esi,[TASK_BASE]
mov esi,[esi+TASKDATA.mem_start]
add esi,ecx
take_data_from_application_1:
mov edi,FDD_BUFF ;FDD_DataBuffer ;0x40000
xor ecx,ecx
mov cx,128
cld
rep movsd
ret
; Коды завершения операции с контроллером (FDC_Status)
FDC_Normal equ 0 ;нормальное завершение
FDC_TimeOut equ 1 ;ошибка тайм-аута
FDC_DiskNotFound equ 2 ;в дисководе нет диска
FDC_TrackNotFound equ 3 ;дорожка не найдена
FDC_SectorNotFound equ 4 ;сектор не найден
; Максимальные значения координат сектора (заданные
; значения соответствуют параметрам стандартного
; трехдюймового гибкого диска объемом 1,44 Мб)
MAX_Track equ 79
MAX_Head equ 1
MAX_Sector equ 18
uglobal
; Счетчик тиков таймера
TickCounter dd ?
; Код завершения операции с контроллером НГМД
FDC_Status DB ?
; Флаг прерывания от НГМД
FDD_IntFlag DB ?
; Момент начала последней операции с НГМД
FDD_Time DD ?
; Номер дисковода
FDD_Type db 0
; Координаты сектора
FDD_Track DB ?
FDD_Head DB ?
FDD_Sector DB ?
; Блок результата операции
FDC_ST0 DB ?
FDC_ST1 DB ?
FDC_ST2 DB ?
FDC_C DB ?
FDC_H DB ?
FDC_R DB ?
FDC_N DB ?
; Счетчик повторения операции чтени
ReadRepCounter DB ?
; Счетчик повторения операции рекалибровки
RecalRepCounter DB ?
endg
; Область памяти для хранения прочитанного сектора
;FDD_DataBuffer: times 512 db 0 ;DB 512 DUP (?)
fdd_motor_status db 0
timer_fdd_motor dd 0
;*************************************
;* ИНИЦИАЛИЗАЦИЯ РЕЖИМА ПДП ДЛЯ НГМД *
;*************************************
Init_FDC_DMA:
pushad
mov al,0
out 0x0c,al ; reset the flip-flop to a known state.
mov al,6 ; mask channel 2 so we can reprogram it.
out 0x0a,al
mov al,[dmamode] ; 0x46 -> Read from floppy - 0x4A Write to floppy
out 0x0b,al
mov al,0
out 0x0c,al ; reset the flip-flop to a known state.
mov eax,0xD000
out 0x04,al ; set the channel 2 starting address to 0
shr eax,8
out 0x04,al
shr eax,8
out 0x81,al
mov al,0
out 0x0c, al ; reset flip-flop
mov al, 0xff ;set count (actual size -1)
out 0x5, al
mov al,0x1 ;[dmasize] ;(0x1ff = 511 / 0x23ff =9215)
out 0x5,al
mov al,2
out 0xa,al
popad
ret
;***********************************
;* ЗАПИСАТЬ БАЙТ В ПОРТ ДАННЫХ FDC *
;* Параметры: *
;* AL - выводимый байт. *
;***********************************
FDCDataOutput:
; pusha
push eax ecx edx
mov AH,AL ;запомнить байт в AH
; Сбросить переменную состояния контроллера
mov [FDC_Status],FDC_Normal
; Проверить готовность контроллера к приему данных
mov DX,3F4h ;(порт состояния FDC)
mov ecx, 0x10000 ;установить счетчик тайм-аута
@@TestRS:
in AL,DX ;прочитать регистр RS
and AL,0C0h ;выделить разряды 6 и 7
cmp AL,80h ;проверить разряды 6 и 7
je @@OutByteToFDC
loop @@TestRS
; Ошибка тайм-аута
mov [FDC_Status],FDC_TimeOut
jmp @@End_5
; Вывести байт в порт данных
@@OutByteToFDC:
inc DX
mov AL,AH
out DX,AL
@@End_5:
; popa
pop edx ecx eax
ret
;******************************************
;* ПРОЧИТАТЬ БАЙТ ИЗ ПОРТА ДАННЫХ FDC *
;* Процедура не имеет входных параметров. *
;* Выходные данные: *
;* AL - считанный байт. *
;******************************************
FDCDataInput:
push ECX
push DX
; Сбросить переменную состояния контроллера
mov [FDC_Status],FDC_Normal
; Проверить готовность контроллера к передаче данных
mov DX,3F4h ;(порт состояния FDC)
xor CX,CX ;установить счетчик тайм-аута
@@TestRS_1:
in AL,DX ;прочитать регистр RS
and AL,0C0h ;выдлить разряды 6 и 7
cmp AL,0C0h ;проверить разряды 6 и 7
je @@GetByteFromFDC
loop @@TestRS_1
; Ошибка тайм-аута
mov [FDC_Status],FDC_TimeOut
jmp @@End_6
; Ввести байт из порта данных
@@GetByteFromFDC:
inc DX
in AL,DX
@@End_6: pop DX
pop ECX
ret
;*********************************************
;* ОБРАБОТЧИК ПРЕРЫВАНИЯ ОТ КОНТРОЛЛЕРА НГМД *
;*********************************************
FDCInterrupt:
; Установить флаг прерывани
mov [FDD_IntFlag],1
ret
;******************************************
;* УСТАНОВИТЬ НОВЫЙ ОБРАБОТЧИК ПРЕРЫВАНИЙ *
;* НГМД *
;******************************************
SetUserInterrupts:
mov [fdc_irq_func],FDCInterrupt
ret
;*******************************************
;* ОЖИДАНИЕ ПРЕРЫВАНИЯ ОТ КОНТРОЛЛЕРА НГМД *
;*******************************************
WaitFDCInterrupt:
pusha
; Сбросить байт состояния операции
mov [FDC_Status],FDC_Normal
; Сбросить флаг прерывани
mov [FDD_IntFlag],0
; Обнулить счетчик тиков
mov eax,[timer_ticks]
mov [TickCounter],eax
; Ожидать установки флага прерывания НГМД
@@TestRS_2:
cmp [FDD_IntFlag],0
jnz @@End_7 ;прерывание произошло
call change_task
mov eax,[timer_ticks]
sub eax,[TickCounter]
cmp eax,50 ;25 ;5 ;ожидать 5 тиков
jb @@TestRS_2
; jl @@TestRS_2
; Ошибка тайм-аута
mov [FDC_Status],FDC_TimeOut
; mov [flp_status],0
@@End_7: popa
ret
;*********************************
;* ВКЛЮЧИТЬ МОТОР ДИСКОВОДА "A:" *
;*********************************
FDDMotorON:
pusha
; cmp [fdd_motor_status],1
; je fdd_motor_on
mov al,[flp_number]
cmp [fdd_motor_status],al
je fdd_motor_on
; Произвести сброс контроллера НГМД
mov DX,3F2h ;порт управления двигателями
mov AL,0
out DX,AL
; Выбрать и включить мотор дисковода
cmp [flp_number],1
jne FDDMotorON_B
; call FDDMotorOFF_B
mov AL,1Ch ; Floppy A
jmp FDDMotorON_1
FDDMotorON_B:
; call FDDMotorOFF_A
mov AL,2Dh ; Floppy B
FDDMotorON_1:
out DX,AL
; Обнулить счетчик тиков
mov eax,[timer_ticks]
mov [TickCounter],eax
; Ожидать 0,5 с
@@dT:
call change_task
mov eax,[timer_ticks]
sub eax,[TickCounter]
cmp eax,50 ;10
jb @@dT
cmp [flp_number],1
jne fdd_motor_on_B
mov [fdd_motor_status],1
jmp fdd_motor_on
fdd_motor_on_B:
mov [fdd_motor_status],2
fdd_motor_on:
call save_timer_fdd_motor
popa
ret
;*****************************************
;* СОХРАНЕНИЕ УКАЗАТЕЛЯ ВРЕМЕНИ *
;*****************************************
save_timer_fdd_motor:
mov eax,[timer_ticks]
mov [timer_fdd_motor],eax
ret
;*****************************************
;* ПРОВЕРКА ЗАДЕРЖКИ ВЫКЛЮЧЕНИЯ МОТОРА *
;*****************************************
check_fdd_motor_status:
cmp [fdd_motor_status],0
je end_check_fdd_motor_status_1
mov eax,[timer_ticks]
sub eax,[timer_fdd_motor]
cmp eax,500
jb end_check_fdd_motor_status
call FDDMotorOFF
mov [fdd_motor_status],0
end_check_fdd_motor_status_1:
mov [flp_status],0
end_check_fdd_motor_status:
ret
;**********************************
;* ВЫКЛЮЧИТЬ МОТОР ДИСКОВОДА *
;**********************************
FDDMotorOFF:
push AX
push DX
cmp [flp_number],1
jne FDDMotorOFF_1
call FDDMotorOFF_A
jmp FDDMotorOFF_2
FDDMotorOFF_1:
call FDDMotorOFF_B
FDDMotorOFF_2:
pop DX
pop AX
; сброс флагов кеширования в связи с устареванием информации
mov [root_read],0
mov [flp_fat],0
ret
FDDMotorOFF_A:
mov DX,3F2h ;порт управления двигателями
mov AL,0Ch ; Floppy A
out DX,AL
ret
FDDMotorOFF_B:
mov DX,3F2h ;порт управления двигателями
mov AL,5h ; Floppy B
out DX,AL
ret
;*******************************
;* РЕКАЛИБРОВКА ДИСКОВОДА "A:" *
;*******************************
RecalibrateFDD:
pusha
call save_timer_fdd_motor
; Подать команду "Рекалибровка"
mov AL,07h
call FDCDataOutput
mov AL,00h
call FDCDataOutput
; Ожидать завершения операции
call WaitFDCInterrupt
; cmp [FDC_Status],0
; je no_fdc_status_error
; mov [flp_status],0
;no_fdc_status_error:
call save_timer_fdd_motor
popa
ret
;*****************************************************
;* ПОИСК ДОРОЖКИ *
;* Параметры передаются через глобальные переменные: *
;* FDD_Track - номер дорожки (0-79); *
;* FDD_Head - номер головки (0-1). *
;* Результат операции заносится в FDC_Status. *
;*****************************************************
SeekTrack:
pusha
call save_timer_fdd_motor
; Подать команду "Поиск"
mov AL,0Fh
call FDCDataOutput
; Передать байт номера головки/накопител
mov AL,[FDD_Head]
shl AL,2
call FDCDataOutput
; Передать байт номера дорожки
mov AL,[FDD_Track]
call FDCDataOutput
; Ожидать завершения операции
call WaitFDCInterrupt
cmp [FDC_Status],FDC_Normal
jne @@Exit
; Сохранить результат поиска
mov AL,08h
call FDCDataOutput
call FDCDataInput
mov [FDC_ST0],AL
call FDCDataInput
mov [FDC_C],AL
; Проверить результат поиска
; Поиск завершен?
test [FDC_ST0],100000b
je @@Err
; Заданный трек найден?
mov AL,[FDC_C]
cmp AL,[FDD_Track]
jne @@Err
; Номер головки совпадает с заданным?
mov AL,[FDC_ST0]
and AL,100b
shr AL,2
cmp AL,[FDD_Head]
jne @@Err
; Операция завершена успешно
mov [FDC_Status],FDC_Normal
jmp @@Exit
@@Err: ; Трек не найден
mov [FDC_Status],FDC_TrackNotFound
; mov [flp_status],0
@@Exit:
call save_timer_fdd_motor
popa
ret
;*******************************************************
;* ЧТЕНИЕ СЕКТОРА ДАННЫХ *
;* Параметры передаются через глобальные переменные: *
;* FDD_Track - номер дорожки (0-79); *
;* FDD_Head - номер головки (0-1); *
;* FDD_Sector - номер сектора (1-18). *
;* Результат операции заносится в FDC_Status. *
;* В случае успешного выполнения операции чтения *
;* содержимое сектора будет занесено в FDD_DataBuffer. *
;*******************************************************
ReadSector:
pushad
call save_timer_fdd_motor
; Установить скорость передачи 500 Кбайт/с
mov AX,0
mov DX,03F7h
out DX,AL
; Инициализировать канал прямого доступа к памяти
mov [dmamode],0x46
call Init_FDC_DMA
; Подать команду "Чтение данных"
mov AL,0E6h ;чтение в мультитрековом режиме
call FDCDataOutput
mov AL,[FDD_Head]
shl AL,2
call FDCDataOutput
mov AL,[FDD_Track]
call FDCDataOutput
mov AL,[FDD_Head]
call FDCDataOutput
mov AL,[FDD_Sector]
call FDCDataOutput
mov AL,2 ;код размера сектора (512 байт)
call FDCDataOutput
mov AL,18 ;+1; 3Fh ;число секторов на дорожке
call FDCDataOutput
mov AL,1Bh ;значение GPL
call FDCDataOutput
mov AL,0FFh ;значение DTL
call FDCDataOutput
; Ожидаем прерывание по завершении операции
call WaitFDCInterrupt
cmp [FDC_Status],FDC_Normal
jne @@Exit_1
; Считываем статус завершения операции
call GetStatusInfo
test [FDC_ST0],11011000b
jnz @@Err_1
mov [FDC_Status],FDC_Normal
jmp @@Exit_1
@@Err_1: mov [FDC_Status],FDC_SectorNotFound
; mov [flp_status],0
@@Exit_1:
call save_timer_fdd_motor
popad
ret
;*******************************************************
;* ЧТЕНИЕ СЕКТОРА (С ПОВТОРЕНИЕМ ОПЕРАЦИИ ПРИ СБОЕ) *
;* Параметры передаются через глобальные переменные: *
;* FDD_Track - номер дорожки (0-79); *
;* FDD_Head - номер головки (0-1); *
;* FDD_Sector - номер сектора (1-18). *
;* Результат операции заносится в FDC_Status. *
;* В случае успешного выполнения операции чтения *
;* содержимое сектора будет занесено в FDD_DataBuffer. *
;*******************************************************
ReadSectWithRetr:
pusha
; Обнулить счетчик повторения операции рекалибровки
mov [RecalRepCounter],0
@@TryAgain:
; Обнулить счетчик повторения операции чтени
mov [ReadRepCounter],0
@@ReadSector_1:
call ReadSector
cmp [FDC_Status],0
je @@Exit_2
cmp [FDC_Status],1
je @@Err_3
; Троекратное повторение чтени
inc [ReadRepCounter]
cmp [ReadRepCounter],3
jb @@ReadSector_1
; Троекратное повторение рекалибровки
call RecalibrateFDD
call SeekTrack
inc [RecalRepCounter]
cmp [RecalRepCounter],3
jb @@TryAgain
; mov [flp_status],0
@@Exit_2:
popa
ret
@@Err_3:
mov [flp_status],0
popa
ret
;*******************************************************
;* ЗАПИСЬ СЕКТОРА ДАННЫХ *
;* Параметры передаются через глобальные переменные: *
;* FDD_Track - номер дорожки (0-79); *
;* FDD_Head - номер головки (0-1); *
;* FDD_Sector - номер сектора (1-18). *
;* Результат операции заносится в FDC_Status. *
;* В случае успешного выполнения операции записи *
;* содержимое FDD_DataBuffer будет занесено в сектор. *
;*******************************************************
WriteSector:
pushad
call save_timer_fdd_motor
; Установить скорость передачи 500 Кбайт/с
mov AX,0
mov DX,03F7h
out DX,AL
; Инициализировать канал прямого доступа к памяти
mov [dmamode],0x4A
call Init_FDC_DMA
; Подать команду "Запись данных"
mov AL,0xC5 ;0x45 ;запись в мультитрековом режиме
call FDCDataOutput
mov AL,[FDD_Head]
shl AL,2
call FDCDataOutput
mov AL,[FDD_Track]
call FDCDataOutput
mov AL,[FDD_Head]
call FDCDataOutput
mov AL,[FDD_Sector]
call FDCDataOutput
mov AL,2 ;код размера сектора (512 байт)
call FDCDataOutput
mov AL,18; 3Fh ;число секторов на дорожке
call FDCDataOutput
mov AL,1Bh ;значение GPL
call FDCDataOutput
mov AL,0FFh ;значение DTL
call FDCDataOutput
; Ожидаем прерывание по завершении операции
call WaitFDCInterrupt
cmp [FDC_Status],FDC_Normal
jne @@Exit_3
; Считываем статус завершения операции
call GetStatusInfo
test [FDC_ST0],11000000b ;11011000b
jnz @@Err_2
mov [FDC_Status],FDC_Normal
jmp @@Exit_3
@@Err_2: mov [FDC_Status],FDC_SectorNotFound
@@Exit_3:
call save_timer_fdd_motor
popad
ret
;*******************************************************
;* ЗАПИСЬ СЕКТОРА (С ПОВТОРЕНИЕМ ОПЕРАЦИИ ПРИ СБОЕ) *
;* Параметры передаются через глобальные переменные: *
;* FDD_Track - номер дорожки (0-79); *
;* FDD_Head - номер головки (0-1); *
;* FDD_Sector - номер сектора (1-18). *
;* Результат операции заносится в FDC_Status. *
;* В случае успешного выполнения операции записи *
;* содержимое FDD_DataBuffer будет занесено в сектор. *
;*******************************************************
WriteSectWithRetr:
pusha
; Обнулить счетчик повторения операции рекалибровки
mov [RecalRepCounter],0
@@TryAgain_1:
; Обнулить счетчик повторения операции чтени
mov [ReadRepCounter],0
@@WriteSector_1:
call WriteSector
cmp [FDC_Status],0
je @@Exit_4
cmp [FDC_Status],1
je @@Err_4
; Троекратное повторение чтени
inc [ReadRepCounter]
cmp [ReadRepCounter],3
jb @@WriteSector_1
; Троекратное повторение рекалибровки
call RecalibrateFDD
call SeekTrack
inc [RecalRepCounter]
cmp [RecalRepCounter],3
jb @@TryAgain_1
@@Exit_4:
popa
ret
@@Err_4:
mov [flp_status],0
popa
ret
;*********************************************
;* ПОЛУЧИТЬ ИНФОРМАЦИЮ О РЕЗУЛЬТАТЕ ОПЕРАЦИИ *
;*********************************************
GetStatusInfo:
push AX
call FDCDataInput
mov [FDC_ST0],AL
call FDCDataInput
mov [FDC_ST1],AL
call FDCDataInput
mov [FDC_ST2],AL
call FDCDataInput
mov [FDC_C],AL
call FDCDataInput
mov [FDC_H],AL
call FDCDataInput
mov [FDC_R],AL
call FDCDataInput
mov [FDC_N],AL
pop AX
ret

View File

@ -0,0 +1,863 @@
; Low-level driver for HDD access
; DMA support by Mario79
;**************************************************************************
;
; 0x600008 - first entry in cache list
;
; +0 - lba sector
; +4 - state of cache sector
; 0 = empty
; 1 = used for read ( same as in hd )
; 2 = used for write ( differs from hd )
;
; +65536 - cache entries
;
;**************************************************************************
align 4
hd_read:
;-----------------------------------------------------------
; input : eax = block to read
; ebx = destination
;-----------------------------------------------------------
and [hd_error], 0
push ecx esi edi ; scan cache
mov ecx,cache_max ; entries in cache
mov esi,0x600000+8
mov edi,1
hdreadcache:
cmp dword [esi+4],0 ; empty
je nohdcache
cmp [esi],eax ; correct sector
je yeshdcache
nohdcache:
add esi,8
inc edi
dec ecx
jnz hdreadcache
call find_empty_slot ; ret in edi
cmp [hd_error],0
jne return_01
cmp [dma_hdd], 1
jnz .nodma
call hd_read_dma
jmp @f
.nodma:
call hd_read_pio
@@:
lea esi,[edi*8+0x600000]
mov [esi],eax ; sector number
mov dword [esi+4],1 ; hd read - mark as same as in hd
yeshdcache:
mov esi,edi
shl esi,9
add esi,0x600000+65536
mov edi,ebx
mov ecx,512/4
cld
rep movsd ; move data
return_01:
pop edi esi ecx
ret
align 4
hd_read_pio:
push eax edx
call wait_for_hd_idle
cmp [hd_error],0
jne hd_read_error
cli
xor eax,eax
mov edx,[hdbase]
inc edx
out dx,al ; ATAFeatures ॣ¨áâà "®á®¡¥­­®á⥩"
inc edx
inc eax
out dx,al ; ATASectorCount áçñâ稪 ᥪâ®à®¢
inc edx
mov eax,[esp+4]
out dx,al ; ATASectorNumber ॣ¨áâà ­®¬¥à  ᥪâ®à 
shr eax,8
inc edx
out dx,al ; ATACylinder ­®¬¥à 樫¨­¤à  (¬« ¤è¨© ¡ ©â)
shr eax,8
inc edx
out dx,al ; ­®¬¥à 樫¨­¤à  (áâ à訩 ¡ ©â)
shr eax,8
inc edx
and al,1+2+4+8
add al,byte [hdid]
add al,128+64+32
out dx,al ; ­®¬¥à £®«®¢ª¨/­®¬¥à ¤¨áª 
inc edx
mov al,20h
out dx,al ; ATACommand ॣ¨áâà ª®¬ ­¤
sti
call wait_for_sector_buffer
cmp [hd_error],0
jne hd_read_error
cli
push edi
shl edi,9
add edi,0x600000+65536
mov ecx,256
mov edx,[hdbase]
cld
rep insw
pop edi
sti
pop edx eax
ret
disable_ide_int:
; mov edx,[hdbase]
; add edx,0x206
; mov al,2
; out dx,al
cli
ret
enable_ide_int:
; mov edx,[hdbase]
; add edx,0x206
; mov al,0
; out dx,al
sti
ret
align 4
hd_write:
;-----------------------------------------------------------
; input : eax = block
; ebx = pointer to memory
;-----------------------------------------------------------
push ecx esi edi
; check if the cache already has the sector and overwrite it
mov ecx,cache_max
mov esi,0x600000+8
mov edi,1
hdwritecache:
cmp dword [esi+4],0 ; if cache slot is empty
je not_in_cache_write
cmp [esi],eax ; if the slot has the sector
je yes_in_cache_write
not_in_cache_write:
add esi,8
inc edi
dec ecx
jnz hdwritecache
; sector not found in cache
; write the block to a new location
call find_empty_slot ; ret in edi
cmp [hd_error],0
jne hd_write_access_denied
lea esi,[edi*8+0x600000]
mov [esi],eax ; sector number
yes_in_cache_write:
mov dword [esi+4],2 ; write - differs from hd
shl edi,9
add edi,0x600000+65536
mov esi,ebx
mov ecx,512/4
cld
rep movsd ; move data
hd_write_access_denied:
pop edi esi ecx
ret
write_cache:
;-----------------------------------------------------------
; write all changed sectors to disk
;-----------------------------------------------------------
push eax ecx edx esi edi
; write difference ( 2 ) from cache to hd
mov ecx,cache_max
mov esi,0x600000+8
mov edi,1
write_cache_more:
cmp dword [esi+4],2 ; if cache slot is not different
jne .write_chain
mov dword [esi+4],1 ; same as in hd
mov eax,[esi] ; eax = sector to write
cmp eax,[PARTITION_START]
jb danger
cmp eax,[PARTITION_END]
ja danger
cmp [allow_dma_write], 1
jnz .nodma
cmp [dma_hdd], 1
jnz .nodma
; Ž¡ê¥¤¨­ï¥¬ § ¯¨áì 楯®çª¨ ¯®á«¥¤®¢ â¥«ì­ëå ᥪâ®à®¢ ¢ ®¤­® ®¡à é¥­¨¥ ª ¤¨áªã
cmp ecx, 1
jz .nonext
cmp dword [esi+8+4], 2
jnz .nonext
push eax
inc eax
cmp eax, [esi+8]
pop eax
jnz .nonext
cmp [cache_chain_started], 1
jz @f
mov [cache_chain_started], 1
mov [cache_chain_size], 0
mov [cache_chain_pos], edi
mov [cache_chain_ptr], esi
@@:
inc [cache_chain_size]
cmp [cache_chain_size], 64
jnz .continue
jmp .write_chain
.nonext:
call flush_cache_chain
mov [cache_chain_size], 1
mov [cache_chain_ptr], esi
call write_cache_sector
jmp .continue
.nodma:
call cache_write_pio
.write_chain:
call flush_cache_chain
.continue:
danger:
add esi,8
inc edi
dec ecx
jnz write_cache_more
call flush_cache_chain
return_02:
pop edi esi edx ecx eax
ret
flush_cache_chain:
cmp [cache_chain_started], 0
jz @f
call write_cache_chain
mov [cache_chain_started], 0
@@:
ret
align 4
cache_write_pio:
call disable_ide_int
call wait_for_hd_idle
cmp [hd_error],0
jne hd_write_error
; cli
xor eax,eax
mov edx,[hdbase]
inc edx
out dx,al
inc edx
inc eax
out dx,al
inc edx
mov eax,[esi] ; eax = sector to write
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,byte [hdid]
add al,128+64+32
out dx,al
inc edx
mov al,30h
out dx,al
; sti
call wait_for_sector_buffer
cmp [hd_error],0
jne hd_write_error
push ecx esi
; cli
mov esi,edi
shl esi,9
add esi,0x600000+65536 ; esi = from memory position
mov ecx,256
mov edx,[hdbase]
cld
rep outsw
; sti
call enable_ide_int
pop esi ecx
ret
align 4
find_empty_slot:
;-----------------------------------------------------------
; find empty or read slot, flush cache if next 10% is used by write
; output : edi = cache slot
;-----------------------------------------------------------
; push ecx esi
search_again:
mov ecx,cache_max*10/100
mov edi,[cache_search_start]
search_for_empty:
inc edi
cmp edi,cache_max
jbe inside_cache
mov edi,1
inside_cache:
cmp dword [edi*8+0x600000+4],2 ; get cache slot info
jb found_slot ; it's empty or read
dec ecx
jnz search_for_empty
call write_cache ; no empty slots found, write all
cmp [hd_error],0
jne found_slot_access_denied
jmp search_again ; and start again
found_slot:
mov [cache_search_start],edi
found_slot_access_denied:
ret
align 4
clear_hd_cache:
push eax ecx edi
mov edi,0x600000
mov ecx,16384
xor eax,eax
cld
rep stosd ; clear hd cache with 0
mov [cache_search_start],eax
mov [fat_in_cache],-1
mov [fat_change],0
pop edi ecx eax
ret
save_hd_wait_timeout:
push eax
mov eax,[timer_ticks];[0xfdf0]
add eax,300 ; 3 sec timeout
mov [hd_wait_timeout],eax
pop eax
ret
align 4
check_hd_wait_timeout:
push eax
mov eax,[hd_wait_timeout]
cmp [timer_ticks], eax ;[0xfdf0],eax
jg hd_timeout_error
pop eax
mov [hd_error],0
ret
;iglobal
; hd_timeout_str db 'K : FS - HD timeout',0
; hd_read_str db 'K : FS - HD read error',0
; hd_write_str db 'K : FS - HD write error',0
; hd_lba_str db 'K : FS - HD LBA error',0
;endg
hd_timeout_error:
; call clear_hd_cache
; call clear_application_table_status
; mov esi,hd_timeout_str
; call sys_msg_board_str
DEBUGF 1,"K : FS - HD timeout\n"
; jmp $
mov [hd_error],1
pop eax
ret
hd_read_error:
; call clear_hd_cache
; call clear_application_table_status
; mov esi,hd_read_str
; call sys_msg_board_str
DEBUGF 1,"K : FS - HD read error\n"
pop edx eax
ret
hd_write_error:
; call clear_hd_cache
; call clear_application_table_status
; mov esi,hd_write_str
; call sys_msg_board_str
DEBUGF 1,"K : FS - HD write error\n"
ret
hd_write_error_dma:
; call clear_hd_cache
; call clear_application_table_status
; mov esi, hd_write_str
; call sys_msg_board_str
DEBUGF 1,"K : FS - HD read error\n"
pop esi
ret
hd_lba_error:
; call clear_hd_cache
; call clear_application_table_status
; mov esi,hd_lba_str
; call sys_msg_board_str
DEBUGF 1,"K : FS - HD LBA error\n"
jmp LBA_read_ret
align 4
wait_for_hd_idle:
push eax edx
call save_hd_wait_timeout
mov edx,[hdbase]
add edx,0x7
wfhil1:
call check_hd_wait_timeout
cmp [hd_error],0
jne @f
in al,dx
test al,128
jnz wfhil1
@@:
pop edx eax
ret
align 4
wait_for_sector_buffer:
push eax edx
mov edx,[hdbase]
add edx,0x7
call save_hd_wait_timeout
hdwait_sbuf: ; wait for sector buffer to be ready
call check_hd_wait_timeout
cmp [hd_error],0
jne @f
in al,dx
test al,8
jz hdwait_sbuf
mov [hd_error],0
cmp [hd_setup],1 ; do not mark error for setup request
je buf_wait_ok
test al,1 ; previous command ended up with an error
jz buf_wait_ok
@@:
mov [hd_error],1
buf_wait_ok:
pop edx eax
ret
; \begin{Mario79}
align 4
wait_for_sector_dma_ide0:
push eax
push edx
call save_hd_wait_timeout
.wait:
call change_task
cmp [irq14_func], hdd_irq14
jnz .done
call check_hd_wait_timeout
cmp [hd_error], 0
jz .wait
mov [irq14_func], hdd_irq_null
mov dx, [IDEContrRegsBaseAddr]
mov al, 0
out dx, al
.done:
pop edx
pop eax
ret
align 4
wait_for_sector_dma_ide1:
push eax
push edx
call save_hd_wait_timeout
.wait:
call change_task
cmp [irq15_func], hdd_irq15
jnz .done
call check_hd_wait_timeout
cmp [hd_error], 0
jz .wait
mov [irq15_func], hdd_irq_null
mov dx, [IDEContrRegsBaseAddr]
add dx, 8
mov al, 0
out dx, al
.done:
pop edx
pop eax
ret
iglobal
align 4
; note that IDE descriptor table must be 4-byte aligned and do not cross 4K boundary
IDE_descriptor_table:
dd 284000h
dw 2000h
dw 8000h
dma_cur_sector dd not 40h
irq14_func dd hdd_irq_null
irq15_func dd hdd_irq_null
endg
uglobal
; all uglobals are zeroed at boot
dma_process dd 0
dma_slot_ptr dd 0
cache_chain_pos dd 0
cache_chain_ptr dd 0
cache_chain_size db 0
cache_chain_started db 0
dma_task_switched db 0
dma_hdd db 0
allow_dma_write db 0
endg
align 4
hdd_irq14:
pushfd
cli
pushad
mov [irq14_func], hdd_irq_null
mov dx, [IDEContrRegsBaseAddr]
mov al, 0
out dx, al
call update_counters
mov ebx, [dma_process]
cmp [0x3000], ebx
jz .noswitch
mov [dma_task_switched], 1
mov edi, [dma_slot_ptr]
mov eax, [0x3000]
mov [dma_process], eax
mov eax, [0x3010]
mov [dma_slot_ptr], eax
mov [0x3000], ebx
mov [0x3010], edi
mov byte [0xFFFF], 1
call do_change_task
.noswitch:
popad
popfd
align 4
hdd_irq_null:
ret
align 4
hdd_irq15:
pushfd
cli
pushad
mov [irq15_func], hdd_irq_null
mov dx, [IDEContrRegsBaseAddr]
add dx, 8
mov al, 0
out dx, al
call update_counters
mov ebx, [dma_process]
cmp [0x3000], ebx
jz .noswitch
mov [dma_task_switched], 1
mov edi, [dma_slot_ptr]
mov eax, [0x3000]
mov [dma_process], eax
mov eax, [0x3010]
mov [dma_slot_ptr], eax
mov [0x3000], ebx
mov [0x3010], edi
mov byte [0xFFFF], 1
call do_change_task
.noswitch:
popad
popfd
ret
align 4
hd_read_dma:
push eax
push edx
mov edx, [dma_cur_sector]
cmp eax, edx
jb .notread
add edx, 15
cmp [esp+4], edx
ja .notread
mov eax, [esp+4]
sub eax, [dma_cur_sector]
shl eax, 9
add eax, 0x284000
push ecx esi edi
mov esi, eax
shl edi, 9
add edi, 0x610000
mov ecx, 512/4
cld
rep movsd
pop edi esi ecx
pop edx
pop eax
ret
.notread:
mov eax, IDE_descriptor_table
mov dword [eax], 0x284000
mov word [eax+4], 0x2000
mov dx, [IDEContrRegsBaseAddr]
cmp [hdbase], 0x1F0
jz @f
add edx, 8
@@:
push edx
add edx, 4
out dx, eax
pop edx
mov al, 0
out dx, al
add edx, 2
mov al, 6
out dx, al
call wait_for_hd_idle
cmp [hd_error], 0
jnz hd_read_error
call disable_ide_int
xor eax, eax
mov edx, [hdbase]
inc edx
out dx, al
inc edx
mov eax, 10h
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, 0xF
add al, byte [hdid]
add al, 11100000b
out dx, al
inc edx
mov al, 0xC8
out dx, al
mov dx, [IDEContrRegsBaseAddr]
cmp [hdbase], 0x1F0
jz @f
add dx, 8
@@:
mov al, 9
out dx, al
mov eax, [0x3000]
mov [dma_process], eax
mov eax, [0x3010]
mov [dma_slot_ptr], eax
cmp [hdbase], 0x1F0
jnz .ide1
mov [irq14_func], hdd_irq14
jmp @f
.ide1:
mov [irq15_func], hdd_irq15
@@:
call enable_ide_int
cmp [hdbase], 0x1F0
jnz .wait_ide1
call wait_for_sector_dma_ide0
jmp @f
.wait_ide1:
call wait_for_sector_dma_ide1
@@:
cmp [hd_error], 0
jnz hd_read_error
pop edx
pop eax
mov [dma_cur_sector], eax
jmp hd_read_dma
align 4
write_cache_chain:
push esi
mov eax, IDE_descriptor_table
mov edx, [cache_chain_pos]
shl edx, 9
add edx, 0x610000
mov [eax], edx
movzx edx, [cache_chain_size]
shl edx, 9
mov [eax+4], dx
jmp do_write_dma
write_cache_sector:
push esi
mov eax, IDE_descriptor_table
mov edx, edi
shl edx, 9
add edx, 0x610000
mov [eax], edx
mov word [eax+4], 0x200
do_write_dma:
mov dx, [IDEContrRegsBaseAddr]
cmp [hdbase], 0x1F0
jz @f
add edx, 8
@@:
push edx
add edx, 4
out dx, eax
pop edx
mov al, 0
out dx, al
add edx, 2
mov al, 6
out dx, al
call wait_for_hd_idle
cmp [hd_error], 0
jnz hd_write_error_dma
call disable_ide_int
xor eax, eax
mov edx, [hdbase]
inc edx
out dx, al
inc edx
mov al, [cache_chain_size]
out dx, al
inc edx
mov esi, [cache_chain_ptr]
mov eax, [esi]
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, 0xF
add al, byte [hdid]
add al, 11100000b
out dx, al
inc edx
mov al, 0xCA
out dx, al
mov dx, [IDEContrRegsBaseAddr]
cmp [hdbase], 0x1F0
jz @f
add dx, 8
@@:
mov al, 1
out dx, al
mov eax, [0x3000]
mov [dma_process], eax
mov eax, [0x3010]
mov [dma_slot_ptr], eax
cmp [hdbase], 0x1F0
jnz .ide1
mov [irq14_func], hdd_irq14
jmp @f
.ide1:
mov [irq15_func], hdd_irq15
@@:
call enable_ide_int
mov [dma_cur_sector], not 0x40
cmp [hdbase], 0x1F0
jnz .wait_ide1
call wait_for_sector_dma_ide0
jmp @f
.wait_ide1:
call wait_for_sector_dma_ide1
@@:
cmp [hd_error], 0
jnz hd_write_error_dma
pop esi
ret
uglobal
IDEContrRegsBaseAddr dw ?
endg
; \end{Mario79}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,22 @@
iglobal
saverd_fileinfo:
dd 2 ; subfunction: write
dd 0 ; (reserved)
dd 0 ; (reserved)
dd 1440*1024 ; size 1440 Kb
dd 0x100000 - std_application_base_address ; base address
db 0
.name:
dd ?
endg
sysfn_saveramdisk: ; 18.6 = SAVE FLOPPY IMAGE (HD version only)
call restorefatchain
mov eax, saverd_fileinfo - std_application_base_address
mov [saverd_fileinfo.name], ebx
pushad
push eax
call file_system_lfn
pop eax
popad
mov [esp+36], eax
ret

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,134 @@
;======================================================================
;
; BOOT DATA
;
;======================================================================
macro line_full_top {
db 201
times 78 db 205
db 187
}
macro line_full_bottom {
db 200
times 78 db 205
db 188
}
macro line_half {
db 186,' '
times 76 db 0xc4
db ' ',186
}
macro line_space {
db 186
times 78 db 32
db 186
}
d80x25_top:
line_full_top
verstr2:
; line_space
; version string
db 186,32
repeat 78
load a byte from version+%-1
if a = 13
break
end if
db a
end repeat
repeat 78 - ($-verstr2)
db ' '
end repeat
db 32,186
verstr:
line_half
space_msg: line_space
d80x25_top_num = 3
d80x25_bottom:
db 186,' KolibriOS 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 "VESA version: "
.ver db "?.? ("
.mem db "??? Mbytes)",13,10,0
gr_mode db "Select mode: ",13,10,0
s_bpp db 13,10,186," Bits per pixel: "
.bpp dw "??"
db 13,10,0
vrrmprint db "Apply VRR? (picture frequency greater than 60Hz"
db " only for transfers:",13,10
db 186," 1024*768->800*600 and 800*600->640*480) [1-yes,2-no]:",0
ask_dma db "Use DMA for HDD writing? [1-yes/2-no]: ",0
bdev db "Load ramdisk from [1-floppy; 2-C:\kolibri.img (FAT32);"
db "3-use preloaded ram-image from kernel restart]: ",0
not386 db "Fatal - CPU 386+ required.",0
fatalsel db 13,10,"Fatal - Graphics mode not supported by hardware.",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
modevesa20 db " with LFB",0
modevesa12 db ", VESA 1.2 Bnk",0
mode9 db "320x200, EGA/CGA 256 colors",0
mode10 db "640x480, VGA 16 colors",0
dma_msg db " [b] Use DMA for HDD writing:",0
on_msg db " on",13,10,0
off_msg db " off",13,10,0
vrrm_msg db " [c] Use VRR:",0
preboot_device_msg db " [d] Floppy image: ",0
preboot_device_msgs dw 0,pdm1-0x10000,pdm2-0x10000,pdm3-0x10000
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
loading_msg db "Loading KolibriOS...",0
save_quest db "Remember current settings? [y/n]: ",0
loader_block_error db "Bootloader data invalid, I cannot continue. Stopped.",0
_oem db 'oem: ',0
db 5
s_ven_intel db 'Intel'
db 2
s_ven_s3 db 'S3'
;db 5
;s_ven_bochs db 'Bochs'
;db 8
;s_ven_vmware db 'V M ware'
s_mode db " ????-????-?? (?) ",0
s_mode1 db " 0640-0480-04 (a) 0320-0200-08 (b) ",13,10,0
;_tl db 'ÚÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄ¿',13,10,\
; '³ resolution ³ 4 ³ 8 ³ 15 ³ 16 ³ 24 ³ 32 ³',13,10,\
; 'ÃÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄ´',13,10,0
;_rs db '³ ????x???? ³ - ³ - ³ - ³ - ³ - ³ - ³',13,10,0
;_bt db 'ÀÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÙ',13,10,0
_tl db 186,' ÚÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄ¿',13,10,\
186,' ³ 4 ³ 8 ³ 15 ³ 16 ³ 24 ³ 32 ³',13,10,\
186,' ÚÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÅÄ¿',13,10,0
_rs db 186,' ³ ????x???? ³ ? ³ ? ³ ? ³ ? ³ ? ³ ? ³Û³',13,10,0
_bt db 186,' ÀÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÁÄÙ',13,10,0
_sel1 db 0x1A,0
_sel2 db 0x1B,0

View File

@ -0,0 +1,133 @@
;======================================================================
;
; BOOT DATA
;
;======================================================================
macro line_full_top {
db 201
times 78 db 205
db 187
}
macro line_full_bottom {
db 200
times 78 db 205
db 188
}
macro line_half {
db 186,' '
times 76 db 0xc4
db ' ',186
}
macro line_space {
db 186
times 78 db 32
db 186
}
d80x25_top:
line_full_top
space_msg: line_space
verstr:
; line_space
; version string
db 186,32
repeat 78
load a byte from version+%-1
if a = 13
break
end if
db a
end repeat
repeat 78 - ($-verstr)
db ' '
end repeat
db 32,186
line_half
d80x25_top_num = 4
d80x25_bottom:
db 186,' KolibriOS 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
novesa db "Ekraan: EGA/CGA",13,10,0
vervesa db "Vesa versioon: Vesa x.x",13,10,0
vervesa_off=20
msg_apm db " APM x.x ", 0
gr_mode db 186," Vesa 2.0+ 16 M LFB: [1] 640x480, [2] 800x600, "
db "[3] 1024x768, [4] 1280x1024",13,10
db 186," Vesa 1.2 16 M Bnk: [5] 640x480, [6] 800x600, "
db "[7] 1024x768, [8] 1280x1024",13,10
db 186," EGA/CGA 256 värvi: [9] 320x200, "
db "VGA 16 värvi: [0] 640x480",13,10
db 186," Vali reziim: ",0
bt24 db "Bitti pikseli kohta: 24",13,10,0
bt32 db "Bitti pikseli kohta: 32",13,10,0
vrrmprint db "Kinnita VRR? (ekraani sagedus suurem kui 60Hz"
db " ainult:",13,10
db 186," 1024*768->800*600 ja 800*600->640*480) [1-jah,2-ei]:",0
;askmouse db " Hiir:"
; db " [1] PS/2 (USB), [2] Com1, [3] Com2."
; db " Vali port [1-3]: ",0
;no_com1 db 13,10,186, " No COM1 mouse",0
;no_com2 db 13,10,186, " No COM2 mouse",0
ask_dma db "Use DMA for HDD writing? [1-jah/2-ei]: ",0
;gr_direct db 186," Use direct LFB writing? "
; db "[1-yes/2-no] ? ",0
;mem_model db 13,10,186," Motherboard memory [1-16 Mb / 2-32 Mb / "
; db "3-64Mb / 4-128 Mb / 5-256 Mb] ? ",0
;bootlog db 13,10,186," After bootlog display [1-continue/2-pause] ? ",0
bdev db "Paigalda mäluketas [1-diskett; 2-C:\kolibri.img (FAT32);"
db 13,10,186," "
db "3-kasuta eellaaditud mäluketast kerneli restardist]: ",0
probetext db 13,10,13,10,186," Kasuta standartset graafika reziimi? [1-jah, "
db "2-leia biosist (Vesa 3.0)]: ",0
;memokz256 db 13,10,186," RAM 256 Mb",0
;memokz128 db 13,10,186," RAM 128 Mb",0
;memokz64 db 13,10,186," RAM 64 Mb",0
;memokz32 db 13,10,186," RAM 32 Mb",0
;memokz16 db 13,10,186," RAM 16 Mb",0
prnotfnd db "Fataalne - Videoreziimi ei leitud.",0
;modena db "Fataalne - VBE 0x112+ on vajalik.",0
not386 db "Fataalne - CPU 386+ on vajalik.",0
btns db "Fataalne - Ei suuda värvisügavust määratleda.",0
fatalsel db "Fataalne - Graafilist reziimi riistvara ei toeta.",0
badsect db 13,10,186," Fataalne - Vigane sektor. Asenda diskett.",0
memmovefailed db 13,10,186," Fataalne - Int 0x15 liigutamine ebaõnnestus.",0
okt db " ... OK"
linef db 13,10,0
diskload db "Loen disketti: 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 "Vajuta [abcd] seadete muutmiseks, vajuta [Enter] laadimise jätkamiseks",13,10,0
time_msg db " või oota "
time_str db " 5 sekundit"
db " automaatseks jätkamiseks",13,10,0
current_cfg_msg db "Praegused seaded:",13,10,0
curvideo_msg db " [a] Videoreziim: ",0
mode1 db "640x480",0
mode2 db "800x600",0
mode3 db "1024x768",0
mode4 db "1280x1024",0
modes_msg dw mode4-0x10000,mode1-0x10000,mode2-0x10000,mode3-0x10000
modevesa20 db " koos LFB",0
modevesa12 db ", VESA 1.2 Bnk",0
mode9 db "320x200, EGA/CGA 256 värvi",0
mode10 db "640x480, VGA 16 värvi",0
probeno_msg db " (standard reziim)",0
probeok_msg db " (kontrolli ebastandardseid reziime)",0
dma_msg db " [b] Use DMA for HDD writing:",0
on_msg db " sees",13,10,0
off_msg db " väljas",13,10,0
vrrm_msg db " [c] Kasuta VRR:",0
preboot_device_msg db " [d] Disketi kujutis: ",0
preboot_device_msgs dw 0,pdm1-0x10000,pdm2-0x10000,pdm3-0x10000
pdm1 db "reaalne diskett",13,10,0
pdm2 db "C:\kolibri.img (FAT32)",13,10,0
pdm3 db "kasuta juba laaditud kujutist",13,10,0
loading_msg db "Laadin KolibriOS...",0
save_quest db "Jäta meelde praegused seaded? [y/n]: ",0
loader_block_error db "Alglaaduri andmed vigased, ei saa jätkata. Peatatud.",0

View File

@ -0,0 +1,138 @@
;======================================================================
;
; BOOT DATA
;
;======================================================================
macro line_full_top {
db 201
times 78 db 205
db 187
}
macro line_full_bottom {
db 200
times 78 db 205
db 188
}
macro line_half {
db 186,' '
times 76 db 0xc4
db ' ',186
}
macro line_space {
db 186
times 78 db 32
db 186
}
d80x25_top:
line_full_top
space_msg: line_space
verstr:
; line_space
; version string
db 186,32
repeat 78
load a byte from version+%-1
if a = 13
break
end if
db a
end repeat
repeat 78 - ($-verstr)
db ' '
end repeat
db 32,186
line_half
d80x25_top_num = 4
d80x25_bottom:
; db 186,' KolibriOS based on MenuetOS and comes with ABSOLUTELY '
; db 'NO WARRANTY ',186
; db 186,' See file COPYING for details '
; db ' ',186
db 186,' KolibriOS basiert auf MenuetOS und wird ohne jegliche '
db ' Garantie vertrieben ',186
db 186,' Details stehen in der Datei COPYING '
db ' ',186
line_full_bottom
d80x25_bottom_num = 3
novesa db "Anzeige: EGA/CGA ",13,10,0
vervesa db "Vesa-Version: Vesa ",13,10,0
vervesa_off=22
msg_apm db " APM x.x ", 0
gr_mode db 186," Vesa 2.0+ 16 M LFB: [1] 640x480, [2] 800x600, "
db "[3] 1024x768, [4] 1280x1024",13,10
db 186," Vesa 1.2 16 M Bnk: [5] 640x480, [6] 800x600, "
db "[7] 1024x768, [8] 1280x1024",13,10
db 186," EGA/CGA 256 Farben: [9] 320x200, "
db "VGA 16 Farben: [0] 640x480",13,10
db 186," Waehle Modus: ",0
bt24 db "Bits Per Pixel: 24",13,10,0
bt32 db "Bits Per Pixel: 32",13,10,0
vrrmprint db "VRR verwenden? (Monitorfrequenz groesser als 60Hz"
db " only for transfers:",13,10
db 186," 1024*768->800*600 und 800*600->640*480) [1-ja,2-nein]:",0
;askmouse db " Maus angeschlossen an:"
; db " [1] PS/2 (USB), [2] Com1, [3] Com2."
; db " Waehle Port [1-3]: ",0
;no_com1 db 13,10,186, " Keine COM1 Maus",0
;no_com2 db 13,10,186, " Keine COM2 Maus",0
ask_dma db "Nutze DMA zum HDD Aufschreiben? [1-ja/2-nein]: ",0
;gr_direct db 186," Benutze direct LFB? "
; db "[1-ja/2-nein] ? ",0
;mem_model db 13,10,186," Hauptspeicher [1-16 Mb / 2-32 Mb / "
; db "3-64Mb / 4-128 Mb / 5-256 Mb] ? ",0
;bootlog db 13,10,186," After bootlog display [1-continue/2-pause] ? ",0
bdev db "Lade die Ramdisk von [1-Diskette; 2-C:\kolibri.img (FAT32);"
db 13,10,186," "
db "3-benutze ein bereits geladenes Kernel image]: ",0
probetext db 13,10,13,10,186," Nutze Standardgrafikmodi? [1-ja, "
db "2-BIOS Test (Vesa 3.0)]: ",0
;memokz256 db 13,10,186," RAM 256 Mb",0
;memokz128 db 13,10,186," RAM 128 Mb",0
;memokz64 db 13,10,186," RAM 64 Mb",0
;memokz32 db 13,10,186," RAM 32 Mb",0
;memokz16 db 13,10,186," RAM 16 Mb",0
prnotfnd db "Fatal - Videomodus nicht gefunden.",0
;modena db "Fatal - VBE 0x112+ required.",0
not386 db "Fatal - CPU 386+ benoetigt.",0
btns db "Fatal - konnte Farbtiefe nicht erkennen.",0
fatalsel db "Fatal - Grafikmodus nicht unterstuetzt.",0
badsect db 13,10,186," Fatal - Sektorfehler, Andere Diskette neutzen.",0
memmovefailed db 13,10,186," Fatal - Int 0x15 Fehler.",0
okt db " ... OK"
linef db 13,10,0
diskload db "Lade 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 "Druecke [abcd], um die Einstellungen zu aendern , druecke [Enter] zum starten",13,10,0
time_msg db " oder warte "
time_str db " 5 Sekunden"
db " bis zum automatischen Start",13,10,0
current_cfg_msg db "Aktuelle Einstellungen:",13,10,0
curvideo_msg db " [a] Videomodus: ",0
mode1 db "640x480",0
mode2 db "800x600",0
mode3 db "1024x768",0
mode4 db "1280x1024",0
modes_msg dw mode4-0x10000,mode1-0x10000,mode2-0x10000,mode3-0x10000
modevesa20 db " mit LFB",0
modevesa12 db ", VESA 1.2 Bnk",0
mode9 db "320x200, EGA/CGA 256 colors",0
mode10 db "640x480, VGA 16 colors",0
probeno_msg db " (Standard Modus)",0
probeok_msg db " (teste nicht-standard Modi)",0
dma_msg db " [b] Nutze DMA zum HDD Aufschreiben:",0
on_msg db " an",13,10,0
off_msg db " aus",13,10,0
vrrm_msg db " [c] Nutze VRR:",0
preboot_device_msg db " [d] Diskettenimage: ",0
preboot_device_msgs dw 0,pdm1-0x10000,pdm2-0x10000,pdm3-0x10000
pdm1 db "Echte Diskette",13,10,0
pdm2 db "C:\kolibri.img (FAT32)",13,10,0
pdm3 db "Nutze bereits geladenes Image",13,10,0
loading_msg db "Lade KolibriOS...",0
save_quest db "Aktuelle Einstellungen speichern? [y/n]: ",0
loader_block_error db "Bootloader Daten ungueltig, Kann nicht fortfahren. Angehalten.",0

View File

@ -0,0 +1,146 @@
;======================================================================
;
; BOOT DATA
;
;======================================================================
macro line_full_top {
db 201
times 78 db 205
db 187
}
macro line_full_bottom {
db 200
times 78 db 205
db 188
}
macro line_half {
db 186,' '
times 76 db 0xc4
db ' ',186
}
macro line_space {
db 186
times 78 db 32
db 186
}
d80x25_top:
line_full_top
verstr2:
; line_space
; version string
db 186,32
repeat 78
load a byte from version+%-1
if a = 13
break
end if
db a
end repeat
repeat 78 - ($-verstr2)
db ' '
end repeat
db 32,186
verstr:
line_half
space_msg: line_space
d80x25_top_num = 3
d80x25_bottom:
db 186,' Kolibri OS ®á­®¢ ­  ­  Menuet OS ¨ ­¥ ¯à¥¤®áâ ¢«ï¥â '
db '­¨ª ª¨å £ àa­â¨©. ',186
db 186,' <20>®¤à®¡­¥¥ ᬮâà¨â¥ ä ©« GNU.TXT '
db ' ',186
line_full_bottom
d80x25_bottom_num = 3
msg_apm db " APM x.x ",0
novesa db "‚¨¤¥®ª àâ : EGA/CGA",13,10,0
s_vesa db "‚¥àá¨ï VESA: "
.ver db "?.? ("
.mem db "??? Œ¡)",13,10,0
gr_mode db "‚ë¡¥à¨â¥ ¢¨¤¥®à¥¦¨¬: ",13,10,0
s_bpp db 13,10,186," ƒ«ã¡¨­  梥â : "
.bpp dw "??"
db 13,10,0
vrrmprint db "ˆá¯®«ì§®¢ âì VRR? (ç áâ®â  ª ¤à®¢ ¢ëè¥ 60 ƒæ"
db " ⮫쪮 ¤«ï ¯¥à¥å®¤®¢:",13,10
db 186," 1024*768>800*600 ¨ 800*600>640*480) [1-¤ , 2-­¥â]: ",0
ask_dma db "ˆá¯®«ì§®¢ âì DMA ¤«ï § ¯¨á¨ ­  HDD? [1-¤ /2-­¥â]: ",0
bdev db "‡ £à㧨âì ®¡à § ¨§ [1-¤¨áª¥â ; 2-C:\kolibri.img (FAT32);"
db 13,10,186," "
db "3-¨á¯®«ì§®¢ âì 㦥 § £à㦥­­ë© ®¡à §]: ",0
probetext db 13,10,13,10,186," ‘â ­¤ àâ­ë© ¢¨¤¥®à¥¦¨¬? [1-¤ , "
db "2-¯à®¢¥à¨âì ¤à㣨¥ (Vesa 3.0)]: ",0
prnotfnd db "Žè¨¡ª  - ‚¨¤¥®à¥¦¨¬ ­¥ ­ ©¤¥­.",0
;modena db "Žè¨¡ª  - ’ॡã¥âáï ¯®¤¤¥à¦ª  VBE 0x112+.",0
not386 db "Žè¨¡ª  - ’ॡã¥âáï ¯à®æ¥áá®à 386+.",0
btns db "Žè¨¡ª  - <20>¥ ¬®£ã ®¯à¥¤¥«¨âì £«ã¡¨­ã 梥â .",0
fatalsel db "Žè¨¡ª  - ‚ë¡à ­­ë© ¢¨¤¥®à¥¦¨¬ ­¥ ¯®¤¤¥à¦¨¢ ¥âáï.",0
badsect db 13,10,186," Žè¨¡ª  - „¨áª¥â  ¯®¢à¥¦¤¥­ . <20>®¯à®¡ã©â¥ ¤àã£ãî.",0
memmovefailed db 13,10,186," Žè¨¡ª  - Int 0x15 move failed.",0
okt db " ... OK"
linef db 13,10,0
diskload db "‡ £à㧪  ¤¨áª¥âë: 00 %",8,8,8,8,0
pros db "00"
backspace2 db 8,8,0
boot_dev db 0
start_msg db "<EFBFBD> ¦¬¨â¥ [abcd] ¤«ï ¨§¬¥­¥­¨ï ­ áâ஥ª, [Enter] ¤«ï ¯à®¤®«¦¥­¨ï § £à㧪¨",13,10,0
time_msg db " ¨«¨ ¯®¤®¦¤¨â¥ "
time_str db " 5 ᥪ㭤 "
db " ¤®  ¢â®¬ â¨ç¥áª®£® ¯à®¤®«¦¥­¨ï",13,10,0
current_cfg_msg db "’¥ªã騥 ­ áâனª¨:",13,10,0
curvideo_msg db " [a] ‚¨¤¥®à¥¦¨¬: ",0
mode1 db "640x480",0
mode2 db "800x600",0
mode3 db "1024x768",0
mode4 db "1280x1024",0
modes_msg dw mode4-0x10000,mode1-0x10000,mode2-0x10000,mode3-0x10000
modevesa20 db " á LFB",0
modevesa12 db ", VESA 1.2 Bnk",0
mode9 db "320x200, EGA/CGA 256 梥⮢",0
mode10 db "640x480, VGA 16 梥⮢",0
probeno_msg db " (áâ ­¤ àâ­ë© ¢¨¤¥®à¥¦¨¬)",0
probeok_msg db " (¯à®¢¥à¨âì ­¥áâ ­¤ àâ­ë¥ ०¨¬ë)",0
dma_msg db " [b] ˆá¯®«ì§®¢ ­¨¥ DMA ¤«ï § ¯¨á¨ ­  HDD:",0
on_msg db " ¢ª«",13,10,0
off_msg db " ¢ëª«",13,10,0
vrrm_msg db " [c] ˆá¯®«ì§®¢ ­¨¥ VRR:",0
preboot_device_msg db " [d] Ž¡à § ¤¨áª¥âë: ",0
preboot_device_msgs dw 0,pdm1-0x10000,pdm2-0x10000,pdm3-0x10000
pdm1 db "­ áâ®ïé ï ¤¨áª¥â ",13,10,0
pdm2 db "C:\kolibri.img (FAT32)",13,10,0
pdm3 db "¨á¯®«ì§®¢ âì 㦥 § £à㦥­­ë© ®¡à §",13,10,0
loading_msg db "ˆ¤ñâ § £à㧪  KolibriOS...",0
save_quest db "‡ ¯®¬­¨âì ⥪ã騥 ­ áâனª¨? [y/n]: ",0
loader_block_error db "Žè¨¡ª  ¢ ¤ ­­ëå ­ ç «ì­®£® § £àã§ç¨ª , ¯à®¤®«¦¥­¨¥ ­¥¢®§¬®¦­®.",0
_oem db 'oem: ',0
db 5
s_ven_intel db 'Intel'
db 2
s_ven_s3 db 'S3'
;db 5
;s_ven_bochs db 'Bochs'
;db 8
;s_ven_vmware db 'V M ware'
s_mode db " ????-????-?? (?) ",0
s_mode1 db " 0640-0480-04 (a) 0320-0200-08 (b) ",13,10,0
;_tl db 'ÚÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄ¿',13,10,\
; '³ à §à¥è¥­¨¥ ³ 4 ³ 8 ³ 15 ³ 16 ³ 24 ³ 32 ³',13,10,\
; 'ÃÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄ´',13,10,0
;_rs db '³ ????x???? ³ - ³ - ³ - ³ - ³ - ³ - ³',13,10,0
;_bt db 'ÀÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÙ',13,10,0
_tl db 186,' ÚÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄ¿',13,10,\
186,' ³ 4 ³ 8 ³ 15 ³ 16 ³ 24 ³ 32 ³',13,10,\
186,' ÚÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÅÄ¿',13,10,0
_rs db 186,' ³ ????x???? ³ ? ³ ? ³ ? ³ ? ³ ? ³ ? ³Û³',13,10,0
_bt db 186,' ÀÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÁÄÙ',13,10,0
_sel1 db 0x1A,0
_sel2 db 0x1B,0

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,44 @@
substr:
push si di cx
movzx cx,byte[ds:si-1]
@@: mov al,[ds:si]
cmp al,[es:di]
jne @f
inc si
inc di
dec cx
jnz @b
; cld
; repe cmps byte[ds:si],[es:di]
@@: pop cx di si
ret
int2str:
dec bl
jz @f
xor edx,edx
div ecx
push edx
call int2str
pop eax
@@: cmp al,10
sbb al,$69
das
mov [ds:di],al
inc di
ret
int2strnz:
cmp eax,ecx
jb @f
xor edx,edx
div ecx
push edx
call int2strnz
pop eax
@@: cmp al,10
sbb al,$69
das
mov [ds:di],al
inc di
ret

View File

@ -0,0 +1,6 @@
; Full ASCII code font
; only õ and ä added
; Kaitz
ET_FNT:
fontfile file "ETFONT.FNT"

View File

@ -0,0 +1,23 @@
display_modechg db 0 ; display mode change for text, yes/no (0 or 2)
;
; !! Important note !!
;
; Must be set to 2, to avoid two screenmode
; changes within a very short period of time.
display_atboot db 0 ; show boot screen messages ( 2-no )
preboot_graph db 0 ; graph mode
preboot_gprobe db 0 ; probe vesa3 videomodes (1-no, 2-yes)
preboot_vrrm db 0 ; use VRR_M (1-yes, 2- no)
preboot_dma_write db 0 ; use DMA for writing to HDD (1-yes, 2-no)
preboot_device db 0 ; boot device
; (1-floppy 2-harddisk 3-kernel restart)
;!!!! 0 - autodetect !!!!
preboot_blogesc db 1 ; start immediately after bootlog
if $>10200h
ERROR: prebooting parameters must fit in first sector!!!
end if
hdsysimage db 'KOLIBRI IMG' ; load from
image_save db 'KOLIBRI IMG' ; save to

View File

@ -0,0 +1,94 @@
; READ RAMDISK IMAGE FROM HD
cmp [boot_dev],1
jne no_sys_on_hd
test [0x40001],byte 0x40
jz position_2
mov [hdbase],0x1f0
mov [hdid],0x0
mov [hdpos],1
mov [fat32part],0
position_1_1:
inc [fat32part]
call search_and_read_image
cmp [image_retrieved],1
je yes_sys_on_hd
movzx eax,byte [0x40002]
cmp [fat32part],eax
jle position_1_1
position_2:
test [0x40001],byte 0x10
jz position_3
mov [hdbase],0x1f0
mov [hdid],0x10
mov [hdpos],2
mov [fat32part],0
position_2_1:
inc [fat32part]
call search_and_read_image
cmp [image_retrieved],1
je yes_sys_on_hd
movzx eax,byte [0x40003]
cmp eax,[fat32part]
jle position_2_1
position_3:
test [0x40001],byte 0x4
jz position_4
mov [hdbase],0x170
mov [hdid],0x0
mov [hdpos],3
mov [fat32part],0
position_3_1:
inc [fat32part]
call search_and_read_image
cmp [image_retrieved],1
je yes_sys_on_hd
movzx eax,byte [0x40004]
cmp eax,[fat32part]
jle position_3_1
position_4:
test [0x40001],byte 0x1
jz no_sys_on_hd
mov [hdbase],0x170
mov [hdid],0x10
mov [hdpos],4
mov [fat32part],0
position_4_1:
inc [fat32part]
call search_and_read_image
cmp [image_retrieved],1
je yes_sys_on_hd
movzx eax,byte [0x40005]
cmp eax,[fat32part]
jle position_4_1
jmp yes_sys_on_hd
search_and_read_image:
call set_FAT32_variables
mov edx, bootpath
call read_image
test eax, eax
jz image_present
mov edx, bootpath2
call read_image
test eax, eax
jz image_present
ret
image_present:
mov [image_retrieved],1
ret
read_image:
mov eax, hdsysimage
mov ebx, 1474560/512
mov ecx, RAMDISK
mov esi, 0
mov edi, 12
call file_read
ret
image_retrieved db 0
counter_of_partitions db 0
no_sys_on_hd:
yes_sys_on_hd:

View File

@ -0,0 +1,92 @@
; Generated by RUFNT.EXE
; By BadBugsKiller (C)
; Modifyed by BadBugsKiller 12.01.2004 17:45
; Øðèôò óìåíüøåí â ðàçìåðå è òåïåðü ñîñòîèò èç 2-óõ ÷àñòåé,
; ñîäåðæàùèõ òîëüêî ñèìâîëû ðóññêîãî àëôàâèòà.
; ñèìâîëû â êîäèðîâêå ASCII (ÄÎÑ'îâñêàÿ), êîäîâàÿ ñòàíèöà 866.
RU_FNT1:
db 0x00, 0x00, 0x1E, 0x36, 0x66, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xFE, 0x62, 0x60, 0x60, 0x7C, 0x66, 0x66, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x7C, 0x66, 0x66, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xFE, 0x66, 0x62, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x1E, 0x36, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0xFF, 0xC3, 0x81, 0x00, 0x00
db 0x00, 0x00, 0xFE, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xFE, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xDB, 0xDB, 0x5A, 0x5A, 0x7E, 0x7E, 0x5A, 0xDB, 0xDB, 0xDB, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x06, 0x3C, 0x06, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xCE, 0xDE, 0xF6, 0xE6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
db 0x6C, 0x38, 0xC6, 0xC6, 0xC6, 0xCE, 0xDE, 0xF6, 0xE6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xE6, 0x66, 0x6C, 0x6C, 0x78, 0x78, 0x6C, 0x6C, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x1F, 0x36, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0xCF, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xC6, 0xEE, 0xFE, 0xFE, 0xD6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC0, 0xC0, 0xC0, 0xC0, 0xC2, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xFF, 0xDB, 0x99, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x7E, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0x7E, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xC6, 0xC6, 0x6C, 0x7C, 0x38, 0x38, 0x7C, 0x6C, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xFF, 0x03, 0x03, 0x00, 0x00
db 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xFE, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xFF, 0x03, 0x03, 0x00, 0x00
db 0x00, 0x00, 0xF8, 0xF0, 0xB0, 0x30, 0x3E, 0x33, 0x33, 0x33, 0x33, 0x7E, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xC3, 0xC3, 0xC3, 0xC3, 0xF3, 0xDB, 0xDB, 0xDB, 0xDB, 0xF3, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xF0, 0x60, 0x60, 0x60, 0x7C, 0x66, 0x66, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x26, 0x3E, 0x26, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xCE, 0xDB, 0xDB, 0xDB, 0xFB, 0xDB, 0xDB, 0xDB, 0xDB, 0xCE, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x3F, 0x66, 0x66, 0x66, 0x3E, 0x3E, 0x66, 0x66, 0x66, 0xE7, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x02, 0x06, 0x7C, 0xC0, 0xC0, 0xFC, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x66, 0x66, 0x7C, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x62, 0x62, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x36, 0x66, 0x66, 0x66, 0x66, 0xFF, 0xC3, 0xC3, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xFE, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xD6, 0xD6, 0x54, 0x7C, 0x54, 0xD6, 0xD6, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x3C, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xCE, 0xD6, 0xE6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x6C, 0x38, 0xC6, 0xC6, 0xCE, 0xD6, 0xE6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xE6, 0x6C, 0x78, 0x78, 0x6C, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x36, 0x66, 0x66, 0x66, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xEE, 0xFE, 0xFE, 0xD6, 0xD6, 0xC6, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
RU_FNT2:
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x60, 0x60, 0xF0, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC0, 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x5A, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0xC6, 0x7C, 0x00
db 0x00, 0x00, 0x00, 0x3C, 0x18, 0x7E, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0x7E, 0x18, 0x18, 0x3C, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0x6C, 0x38, 0x38, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xFF, 0x03, 0x03, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xFE, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xFE, 0x03, 0x03, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xB0, 0xB0, 0x3E, 0x33, 0x33, 0x7E, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xF6, 0xDE, 0xDE, 0xF6, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x60, 0x60, 0x7C, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x3E, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xCE, 0xDB, 0xDB, 0xFB, 0xDB, 0xDB, 0xCE, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xC6, 0xC6, 0x7E, 0x36, 0x66, 0xE7, 0x00, 0x00, 0x00, 0x00
db 0x6C, 0x00, 0xFE, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xFE, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x6C, 0x00, 0x7C, 0xC6, 0xC6, 0xFC, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x7C, 0xC6, 0xC0, 0xC8, 0xF8, 0xC8, 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC0, 0xF8, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
db 0x66, 0x00, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x6C, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00
db 0x6C, 0x38, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x6C, 0x38, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0xC6, 0x7C, 0x00
db 0x00, 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0xEC, 0x6C, 0x3C, 0x1C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xCF, 0xCD, 0xEF, 0xEC, 0xFF, 0xDC, 0xDC, 0xCC, 0xCC, 0xCC, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0xC6, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0xC6, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00

View File

@ -0,0 +1,534 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Shutdown for Menuet
;;
;; Distributed under General Public License
;; See file COPYING for details.
;; Copyright 2003 Ville Turjanmaa
;;
system_shutdown: ; shut down the system
call stop_all_services
push 3 ; stop playing cd
pop eax
call sys_cd_audio
cld
mov al,[0x2f0000+0x9030]
cmp al,1
jl no_shutdown_parameter
cmp al,4
jle yes_shutdown_param
no_shutdown_parameter:
; movzx ecx,word [0x2f0000+0x900A]
; movzx esi,word [0x2f0000+0x900C]
; imul ecx,esi ;[0xfe04]
;; mov ecx,0x500000/4 ;3fff00/4 ; darken screen
; push ecx
; mov esi,[0xfe80]
; cmp esi,32*0x100000
; jbe no_darken_screen
; mov edi,16*0x100000
; push esi edi
; sdnewpix:
; lodsd
; shr eax,1
; and eax,0x7f7f7f7f
; stosd
; loop sdnewpix
; pop ecx
; pop esi edi
; rep movsd
; no_darken_screen:
; read shutdown code:
; 1) display shutdown "window"
mov eax,[0xfe00]
shr eax,1
lea esi,[eax+220] ; x end
sub eax,220 ; x start
mov ebx,[ScreenHeight]
shr ebx,1
mov [shutdownpos],ebx
lea ebp,[ebx+105] ; y end
sub ebx,120 ; y start
xor edi,edi
inc edi ; force putpixel & dtext
mov ecx,0x0000ff
; vertical loop begin
sdnewpix1:
push eax ; save x start
; horizontal loop begin
sdnewpix2:
call [putpixel]
inc eax
cmp eax,esi
jnz sdnewpix2
; horizontal loop end
dec ecx ; color
pop eax ; restore x start
inc ebx ; advance y pos
cmp ebx,ebp
jnz sdnewpix1
; vertical loop end
; 2) display text strings
; a) version
mov eax,[0xfe00]
shr eax,1
shl eax,16
mov ax,word [shutdownpos]
push eax
sub eax,(220-27)*10000h + 105
mov ebx,0xffff00
mov ecx,version
push 34
pop edx
call dtext
; b) variants
add eax,105+33
push 6
pop esi
; mov ebx,0xffffff
mov bl,0xFF
mov ecx,shutdowntext
mov dl,40
newsdt:
call dtext
add eax,10
add ecx,edx
dec esi
jnz newsdt
; 3) load & display rose.txt
mov eax,rosef ; load rose.txt
xor ebx,ebx
push 2
pop ecx
mov edx,0x90000
push edx
push 12
pop esi
push edi ; may be destroyed
call fileread
pop edi
pop ecx
inc ecx ; do not display stars from rose.txt
pop eax
add eax,20*10000h - 110
mov ebx,0x00ff00
push 27
pop edx
nrl:
call dtext
; sub ebx,0x050000
ror ebx, 16
sub bl, 0x05
ror ebx, 16
add eax,8
add ecx,31
cmp cx,word 0x0001+25*31
jnz nrl
call checkVga_N13
yes_shutdown_param:
cli
mov eax,kernel ; load kernel.mnt to 0x8000:0
push 12
pop esi
xor ebx,ebx
or ecx,-1
mov edx,0x80000
call fileread
mov esi,restart_kernel_4000+0x10000 ; move kernel re-starter to 0x4000:0
mov edi,0x40000
mov ecx,1000
rep movsb
mov eax,0x2F0000 ; restore 0x0 - 0xffff
xor ebx,ebx
mov ecx,0x10000
call memmove
call restorefatchain
mov al, 0xFF
out 0x21, al
out 0xA1, al
mov word [0x467+0],pr_mode_exit-0x10000
mov word [0x467+2],0x1000
mov al,0x0F
out 0x70,al
mov al,0x05
out 0x71,al
mov al,0xFE
out 0x64,al
hlt
use16
pr_mode_exit:
org $-0x10000
; setup stack
mov ax, 3000h
mov ss, ax
mov esp, 0EC00h
; setup ds
push cs
pop ds
lidt [old_ints_h-0x10000]
;remap IRQs
mov al,0x11
out 0x20,al
call rdelay
out 0xA0,al
call rdelay
mov al,0x08
out 0x21,al
call rdelay
mov al,0x70
out 0xA1,al
call rdelay
mov al,0x04
out 0x21,al
call rdelay
mov al,0x02
out 0xA1,al
call rdelay
mov al,0x01
out 0x21,al
call rdelay
out 0xA1,al
call rdelay
mov al,0xB8
out 0x21,al
call rdelay
mov al,0xBD
out 0xA1,al
sti
temp_3456:
xor ax,ax
mov es,ax
mov al,byte [es:0x9030]
cmp al,1
jl nbw
cmp al,4
jle nbw32
nbw:
in al,0x60
call pause_key
cmp al,6
jae nbw
mov bl,al
nbw2:
in al,0x60
call pause_key
cmp al,bl
je nbw2
cmp al,240 ;ax,240
jne nbw31
mov al,bl
dec ax
jmp nbw32
nbw31:
add bl,128
cmp al,bl
jne nbw
sub al,129
nbw32:
dec ax ; 1 = write floppy
js nbw
jnz no_floppy_write
call floppy_write
jmp temp_3456 ;nbw
no_floppy_write:
dec ax ; 2 = power off
jnz no_apm_off
call APM_PowerOff
jmp $
no_apm_off:
dec ax ; 3 = reboot
jnz restart_kernel ; 4 = restart kernel
push 0x40
pop ds
mov word[0x0072],0x1234
jmp 0xF000:0xFFF0
pause_key:
mov cx,100
pause_key_1:
loop pause_key_1
ret
rdelay:
ret
iglobal
kernel db 'KERNEL MNT'
; shutdown_parameter db 0
endg
restart_kernel:
mov ax,0x0003 ; set text mode for screen
int 0x10
jmp 0x4000:0000
restart_kernel_4000:
cli
; mov di,0x1000 ; load kernel image from 0x8000:0 -> 0x1000:0
;
; new_kernel_block_move:
;
; mov ebx,0
;
; new_kernel_byte_move:
;
; mov ax,di
; add ax,0x7000
; mov es,ax
; mov dl,[es:bx]
; mov es,di
; mov [es:bx],dl
;
; inc ebx
; cmp ebx,65536
; jbe new_kernel_byte_move
;
; add di,0x1000
; cmp di,0x2000
; jbe new_kernel_block_move
push ds
pop es
mov cx, 0x8000
push cx
mov ds, cx
xor si, si
xor di, di
rep movsw
push 0x9000
pop ds
push 0x2000
pop es
pop cx
rep movsw
wbinvd ; write and invalidate cache
; mov ax,0x1000
; mov es,ax
; mov ax,0x3000
; mov ss,ax
; mov sp,0xec00
; restore timer
mov al, 00110100b
out 43h, al
jcxz $+2
mov al, 0xFF
out 40h, al
jcxz $+2
out 40h, al
jcxz $+2
sti
; (hint by Black_mirror)
; We must read data from keyboard port,
; because there may be situation when previous keyboard interrupt is lost
; (due to return to real mode and IRQ reprogramming)
; and next interrupt will not be generated (as keyboard waits for handling)
in al, 0x60
; bootloader interface
push 0x1000
pop ds
mov si, kernel_restart_bootblock-0x10000
mov ax, 'KL'
jmp 0x1000:0000
APM_PowerOff:
mov ax, 5304h
xor bx, bx
int 15h
;!!!!!!!!!!!!!!!!!!!!!!!!
mov ax,0x5300
xor bx,bx
int 0x15
push ax
mov ax,0x5301
xor bx,bx
int 0x15
mov ax,0x5308
mov bx,1
mov cx,bx
int 0x15
mov ax,0x530E
xor bx,bx
pop cx
int 0x15
mov ax,0x530D
mov bx,1
mov cx,bx
int 0x15
mov ax,0x530F
mov bx,1
mov cx,bx
int 0x15
mov ax,0x5307
mov bx,1
mov cx,3
int 0x15
;!!!!!!!!!!!!!!!!!!!!!!!!
fwwritedone:
ret
org $+0x10000
flm db 0
org $-0x10000
floppy_write: ; write diskette image to physical floppy
cmp [flm-0x10000],byte 1
je fwwritedone
mov [flm-0x10000],byte 1
xor ax, ax ; reset drive
xor dx, dx
int 0x13
mov cx,0x0001 ; startcyl,startsector
; mov dx,0x0000 ; starthead,drive
xor dx, dx
mov ax, 80*2 ; read no of sect
fwwrites:
push ax
; move 1mb+ -> 0:a000
pusha
mov si,fwmovedesc -0x10000
mov cx,256*18
mov ah,0x87
push ds
pop es
int 0x15
add dword [fwmovedesc-0x10000+0x12], 512*18
popa
xor si,si
mov es,si
fwnewwrite:
mov bx,0xa000 ; es:bx -> data area
mov ax,0x0300+18 ; read, no of sectors to read
int 0x13
test ah, ah
jz fwgoodwrite
inc si
cmp si,10
jnz fwnewwrite
; can't access diskette - return
pop ax
ret
fwgoodwrite:
inc dh
cmp dh,2
jnz fwbb2
mov dh,0
inc ch
fwbb2:
pop ax
dec ax
jnz fwwrites
ret
org $+0x10000
fwmovedesc:
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
db 0xff,0xff,0x0,0x00,0x10,0x93,0x0,0x0
db 0xff,0xff,0x0,0xa0,0x00,0x93,0x0,0x0
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
org $-0x10000
use32
org $+0x10000
uglobal
shutdownpos dd 0x0
endg
iglobal
if lang eq en
shutdowntext:
db "IT'S SAFE TO POWER OFF COMPUTER OR "
db ' '
db '1) SAVE RAMDISK TO FLOPPY '
db '2) APM - POWEROFF '
db '3) REBOOT '
db '4) RESTART KERNEL '
else if lang eq ru
shutdowntext:
db "<EFBFBD>¥§®¯ á­®¥ ¢ëª«î祭¨¥ ª®¬¯ìîâ¥à  ¨«¨ "
db ' '
db '1) ‘®åà ­¨âì à ¬¤¨áª ­  ¤¨áª¥âã '
db '2) APM - ¢ëª«î祭¨¥ ¯¨â ­¨ï '
db '3) <20>¥à¥§ £à㧪  á¨á⥬ë '
db '4) <20>¥áâ àâ ï¤à  ¨§ Ž‡“ '
else
shutdowntext:
db "SIE KOENNEN DEN COMPUTER NUN AUSSCHALTEN"
db ' '
db '1) RAMDISK AUF DISK SPEICHERN '
db '2) APM - AUSSCHALTEN '
db '3) NEUSTARTEN '
db '4) KERNEL NEU STARTEN '
end if
rosef:
db 'ROSE TXT'
endg

View File

@ -0,0 +1,114 @@
@echo off
set languages=en ru ge et
set drivers=sound sis infinity ati2d
set targets=all kernel drivers skins clean
call :Check_Target %1
for %%a in (all kernel) do if %%a==%target% call :Check_Lang %2
call :Target_%target%
if ERRORLEVEL 0 goto Exit_OK
echo Probably at runing has been created error
echo For help send a report...
pause
goto :eof
:Check_Lang
set res=%1
:Check_Lang_loop
for %%a in (%languages%) do if %%a==%res% set lang=%res%
if defined lang goto :eof
echo Language "%res%" is not founded
echo Enter valide languege
echo [%languages%]
set /P res=">
goto Check_Lang_loop
goto :eof
:Check_Target
set res=%1
:Check_Target_loop
for %%a in (%targets%) do if %%a==%res% set target=%res%
if defined target goto :eof
echo Target "%res%" is not valide
echo Enter valide target
echo [%targets%]
set /P res=">
goto Check_Target_loop
goto :eof
:Target_kernel
echo building kernel with language %lang% ...
if not exist bin mkdir bin
echo lang fix %lang% > lang.inc
fasm -m 65536 kernel.asm bin\kernel.mnt
if not %errorlevel%==0 goto :Error_FasmFailed
erase lang.inc
goto :eof
:Target_all
echo building all ...
call :Target_kernel
call :Target_drivers
call :Target_skins
goto :eof
:Target_drivers
echo building drivers ...
if not exist bin\drivers mkdir bin\drivers
cd drivers
for %%a in (%drivers%) do (
fasm -m 65536 %%a.asm ..\bin\drivers\%%a.obj
if not %errorlevel%==0 goto :Error_FasmFailed
)
cd ..
goto :eof
:Target_skins
echo building skins ...
if not exist bin\skins mkdir bin\skins
cd skin
fasm -m 65536 default.asm ..\bin\skins\default.skn
if not %errorlevel%==0 goto :Error_FasmFailed
cd ..
goto :eof
:Target_clean
echo cleaning ...
del /Q bin\drivers\*.*
del /Q bin\skins\*.*
del /Q bin\*.*
rmdir bin\drivers
rmdir bin\skins
rmdir bin
goto :Exit_OK
:Error_FasmFailed
echo error: fasm execution failed
erase lang.inc
pause
exit 1
:Exit_OK
echo all operations has been done
pause
exit 0

View File

@ -0,0 +1,46 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; PCI16.INC ;;
;; ;;
;; 16 bit PCI driver code ;;
;; ;;
;; Version 0.2 December 21st, 2002 ;;
;; ;;
;; Author: Victor Prodan, victorprodan@yahoo.com ;;
;; ;;
;; See file COPYING for details ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
init_pci_16:
pushad
xor ax,ax
mov es,ax
mov byte [es:0x9020],1 ;default mechanism:1
mov ax,0xb101
int 0x1a
or ah,ah
jnz pci16skip
mov [es:0x9021],cl ;last PCI bus in system
mov [es:0x9022],bx
mov [es:0x9024],edi
; we have a PCI BIOS, so check which configuration mechanism(s)
; it supports
; AL = PCI hardware characteristics (bit0 => mechanism1, bit1 => mechanism2)
test al,1
jnz pci16skip
test al,2
jz pci16skip
mov byte [es:0x9020],2 ; if (al&3)==2 => mechanism 2
pci16skip:
mov ax,0x1000
mov es,ax
popad

View File

@ -0,0 +1,358 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; PCI32.INC ;;
;; ;;
;; 32 bit PCI driver code ;;
;; ;;
;; Version 0.2 December 21st, 2002 ;;
;; ;;
;; Author: Victor Prodan, victorprodan@yahoo.com ;;
;; Credits: ;;
;; Ralf Brown ;;
;; Mike Hibbett, mikeh@oceanfree.net ;;
;; ;;
;; See file COPYING for details ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;***************************************************************************
; Function
; pci_api:
;
; Description
; entry point for system PCI calls
;***************************************************************************
align 4
pci_api:
cmp [pci_access_enabled],1
jne no_pci_access_for_applications
or al,al
jnz pci_fn_1
; PCI function 0: get pci version (AH.AL)
movzx eax,word [0x2F0000+0x9022]
ret
pci_fn_1:
cmp al,1
jnz pci_fn_2
; PCI function 1: get last bus in AL
mov al,[0x2F0000+0x9021]
ret
pci_fn_2:
cmp al,2
jne pci_fn_3
; PCI function 2: get pci access mechanism
mov al,[0x2F0000+0x9020]
ret
pci_fn_3:
cmp al,4
jz pci_read_reg ;byte
cmp al,5
jz pci_read_reg ;word
cmp al,6
jz pci_read_reg ;dword
cmp al,8
jz pci_write_reg ;byte
cmp al,9
jz pci_write_reg ;word
cmp al,10
jz pci_write_reg ;dword
no_pci_access_for_applications:
mov eax,-1
ret
;***************************************************************************
; Function
; pci_make_config_cmd
;
; Description
; creates a command dword for use with the PCI bus
; bus # in ah
; device+func in bh (dddddfff)
; register in bl
;
; command dword returned in eax ( 10000000 bbbbbbbb dddddfff rrrrrr00 )
;***************************************************************************
align 4
pci_make_config_cmd:
shl eax,8 ; move bus to bits 16-23
mov ax,bx ; combine all
and eax,0xffffff
or eax,0x80000000
ret
;***************************************************************************
; Function
; pci_read_reg:
;
; Description
; read a register from the PCI config space into EAX/AX/AL
; IN: ah=bus,device+func=bh,register address=bl
; number of bytes to read (1,2,4) coded into AL, bits 0-1
;***************************************************************************
align 4
pci_read_reg:
cmp byte [0x2F0000+0x9020],2 ;what mechanism will we use?
je pci_read_reg_2
; mechanism 1
push esi ; save register size into ESI
mov esi,eax
and esi,3
call pci_make_config_cmd
mov ebx,eax
; get current state
mov dx,0xcf8
in eax, dx
push eax
; set up addressing to config data
mov eax,ebx
and al,0xfc ; make address dword-aligned
out dx,eax
; get requested DWORD of config data
mov dl,0xfc
and bl,3
or dl,bl ; add to port address first 2 bits of register address
or esi,esi
jz pci_read_byte1
cmp esi,1
jz pci_read_word1
cmp esi,2
jz pci_read_dword1
jmp pci_fin_read1
pci_read_byte1:
in al,dx
jmp pci_fin_read1
pci_read_word1:
in ax,dx
jmp pci_fin_read1
pci_read_dword1:
in eax,dx
jmp pci_fin_read1
pci_fin_read1:
; restore configuration control
xchg eax,[esp]
mov dx,0xcf8
out dx,eax
pop eax
pop esi
ret
pci_read_reg_2:
test bh,128 ;mech#2 only supports 16 devices per bus
jnz pci_read_reg_err
push esi ; save register size into ESI
mov esi,eax
and esi,3
push eax
;store current state of config space
mov dx,0xcf8
in al,dx
mov ah,al
mov dl,0xfa
in al,dx
xchg eax,[esp]
; out 0xcfa,bus
mov al,ah
out dx,al
; out 0xcf8,0x80
mov dl,0xf8
mov al,0x80
out dx,al
; compute addr
shr bh,3 ; func is ignored in mechanism 2
or bh,0xc0
mov dx,bx
or esi,esi
jz pci_read_byte2
cmp esi,1
jz pci_read_word2
cmp esi,2
jz pci_read_dword2
jmp pci_fin_read2
pci_read_byte2:
in al,dx
jmp pci_fin_read2
pci_read_word2:
in ax,dx
jmp pci_fin_read2
pci_read_dword2:
in eax,dx
; jmp pci_fin_read2
pci_fin_read2:
; restore configuration space
xchg eax,[esp]
mov dx,0xcfa
out dx,al
mov dl,0xf8
mov al,ah
out dx,al
pop eax
pop esi
ret
pci_read_reg_err:
xor eax,eax
dec eax
ret
;***************************************************************************
; Function
; pci_write_reg:
;
; Description
; write a register from ECX/CX/CL into the PCI config space
; IN: ah=bus,device+func=bh,register address (dword aligned)=bl,
; value to write in ecx
; number of bytes to write (1,2,4) coded into AL, bits 0-1
;***************************************************************************
align 4
pci_write_reg:
cmp byte [0x2F0000+0x9020],2 ;what mechanism will we use?
je pci_write_reg_2
; mechanism 1
push esi ; save register size into ESI
mov esi,eax
and esi,3
call pci_make_config_cmd
mov ebx,eax
; get current state into ecx
mov dx,0xcf8
in eax, dx
push eax
; set up addressing to config data
mov eax,ebx
and al,0xfc ; make address dword-aligned
out dx,eax
; write DWORD of config data
mov dl,0xfc
and bl,3
or dl,bl
mov eax,ecx
or esi,esi
jz pci_write_byte1
cmp esi,1
jz pci_write_word1
cmp esi,2
jz pci_write_dword1
jmp pci_fin_write1
pci_write_byte1:
out dx,al
jmp pci_fin_write1
pci_write_word1:
out dx,ax
jmp pci_fin_write1
pci_write_dword1:
out dx,eax
jmp pci_fin_write1
pci_fin_write1:
; restore configuration control
pop eax
mov dl,0xf8
out dx,eax
xor eax,eax
pop esi
ret
pci_write_reg_2:
test bh,128 ;mech#2 only supports 16 devices per bus
jnz pci_write_reg_err
push esi ; save register size into ESI
mov esi,eax
and esi,3
push eax
;store current state of config space
mov dx,0xcf8
in al,dx
mov ah,al
mov dl,0xfa
in al,dx
xchg eax,[esp]
; out 0xcfa,bus
mov al,ah
out dx,al
; out 0xcf8,0x80
mov dl,0xf8
mov al,0x80
out dx,al
; compute addr
shr bh,3 ; func is ignored in mechanism 2
or bh,0xc0
mov dx,bx
; write register
mov eax,ecx
or esi,esi
jz pci_write_byte2
cmp esi,1
jz pci_write_word2
cmp esi,2
jz pci_write_dword2
jmp pci_fin_write2
pci_write_byte2:
out dx,al
jmp pci_fin_write2
pci_write_word2:
out dx,ax
jmp pci_fin_write2
pci_write_dword2:
out dx,eax
jmp pci_fin_write2
pci_fin_write2:
; restore configuration space
pop eax
mov dx,0xcfa
out dx,al
mov dl,0xf8
mov al,ah
out dx,al
xor eax,eax
pop esi
ret
pci_write_reg_err:
xor eax,eax
dec eax
ret

View File

@ -0,0 +1,571 @@
drw0 equ 10010010b ; data read/write dpl0
drw3 equ 11110010b ; data read/write dpl3
cpl0 equ 10011010b ; code read dpl0
cpl3 equ 11111010b ; code read dpl3
D32 equ 01000000b ; 32bit segment
G32 equ 10000000b ; page gran
;;;;;;;;;;;;cpu_caps flags;;;;;;;;;;;;;;;;
CPU_386 equ 3
CPU_486 equ 4
CPU_PENTIUM equ 5
CPU_P6 equ 6
CPU_PENTIUM4 equ 0x0F
CAPS_FPU equ 00 ;on-chip x87 floating point unit
CAPS_VME equ 01 ;virtual-mode enhancements
CAPS_DE equ 02 ;debugging extensions
CAPS_PSE equ 03 ;page-size extensions
CAPS_TSC equ 04 ;time stamp counter
CAPS_MSR equ 05 ;model-specific registers
CAPS_PAE equ 06 ;physical-address extensions
CAPS_MCE equ 07 ;machine check exception
CAPS_CX8 equ 08 ;CMPXCHG8B instruction
CAPS_APIC equ 09 ;on-chip advanced programmable
; interrupt controller
; 10 ;unused
CAPS_SEP equ 11 ;SYSENTER and SYSEXIT instructions
CAPS_MTRR equ 12 ;memory-type range registers
CAPS_PGE equ 13 ;page global extension
CAPS_MCA equ 14 ;machine check architecture
CAPS_CMOV equ 15 ;conditional move instructions
CAPS_PAT equ 16 ;page attribute table
CAPS_PSE36 equ 17 ;page-size extensions
CAPS_PSN equ 18 ;processor serial number
CAPS_CLFLUSH equ 19 ;CLFUSH instruction
CAPS_DS equ 21 ;debug store
CAPS_ACPI equ 22 ;thermal monitor and software
;controlled clock supported
CAPS_MMX equ 23 ;MMX instructions
CAPS_FXSR equ 24 ;FXSAVE and FXRSTOR instructions
CAPS_SSE equ 25 ;SSE instructions
CAPS_SSE2 equ 26 ;SSE2 instructions
CAPS_SS equ 27 ;self-snoop
CAPS_HTT equ 28 ;hyper-threading technology
CAPS_TM equ 29 ;thermal monitor supported
CAPS_IA64 equ 30 ;IA64 capabilities
CAPS_PBE equ 31 ;pending break enable
;ecx
CAPS_SSE3 equ 32 ;SSE3 instructions
; 33
; 34
CAPS_MONITOR equ 35 ;MONITOR/MWAIT instructions
CAPS_DS_CPL equ 36 ;
CAPS_VMX equ 37 ;virtual mode extensions
; 38 ;
CAPS_EST equ 39 ;enhansed speed step
CAPS_TM2 equ 40 ;thermal monitor2 supported
; 41
CAPS_CID equ 42 ;
; 43
; 44
CAPS_CX16 equ 45 ;CMPXCHG16B instruction
CAPS_xTPR equ 46 ;
;
;reserved
;
;ext edx /ecx
CAPS_SYSCAL equ 64 ;
CAPS_XD equ 65 ;execution disable
CAPS_FFXSR equ 66 ;
CAPS_RDTSCP equ 67 ;
CAPS_X64 equ 68 ;
CAPS_3DNOW equ 69 ;
CAPS_3DNOWEXT equ 70 ;
CAPS_LAHF equ 71 ;
CAPS_CMP_LEG equ 72 ;
CAPS_SVM equ 73 ;secure virual machine
CAPS_ALTMOVCR8 equ 74 ;
; CPU MSR names
MSR_SYSENTER_CS equ 0x174
MSR_SYSENTER_ESP equ 0x175
MSR_SYSENTER_EIP equ 0x176
MSR_AMD_EFER equ 0xC0000080 ; Extended Feature Enable Register
MSR_AMD_STAR equ 0xC0000081 ; SYSCALL/SYSRET Target Address Register
CR0_PE equ 0x00000001 ;protected mode
CR0_MP equ 0x00000002 ;monitor fpu
CR0_EM equ 0x00000004 ;fpu emulation
CR0_TS equ 0x00000008 ;task switch
CR0_ET equ 0x00000010 ;extension type hardcoded to 1
CR0_NE equ 0x00000020 ;numeric error
CR0_WP equ 0x00010000 ;write protect
CR0_AM equ 0x00040000 ;alignment check
CR0_NW equ 0x20000000 ;not write-through
CR0_CD equ 0x40000000 ;cache disable
CR0_PG equ 0x80000000 ;paging
CR4_VME equ 0x0001
CR4_PVI equ 0x0002
CR4_TSD equ 0x0004
CR4_DE equ 0x0008
CR4_PSE equ 0x0010
CR4_PAE equ 0x0020
CR4_MCE equ 0x0040
CR4_PGE equ 0x0080
CR4_PCE equ 0x0100
CR4_OSFXSR equ 0x0200
CR4_OSXMMEXPT equ 0x0400
SSE_IE equ 0x0001
SSE_DE equ 0x0002
SSE_ZE equ 0x0004
SSE_OE equ 0x0008
SSE_UE equ 0x0010
SSE_PE equ 0x0020
SSE_DAZ equ 0x0040
SSE_IM equ 0x0080
SSE_DM equ 0x0100
SSE_ZM equ 0x0200
SSE_OM equ 0x0400
SSE_UM equ 0x0800
SSE_PM equ 0x1000
SSE_FZ equ 0x8000
SSE_INIT equ (SSE_IM+SSE_DM+SSE_ZM+SSE_OM+SSE_UM+SSE_PM)
OS_BASE equ 0
window_data equ (OS_BASE+0x0000000)
CURRENT_TASK equ (OS_BASE+0x0003000)
TASK_COUNT equ (OS_BASE+0x0003004)
TASK_BASE equ (OS_BASE+0x0003010)
TASK_DATA equ (OS_BASE+0x0003020)
TASK_EVENT equ (OS_BASE+0x0003020)
;mouseunder equ (OS_BASE+0x0006900)
FLOPPY_BUFF equ (OS_BASE+0x0008000)
ACTIVE_PROC_STACK equ (OS_BASE+0x000A400) ;unused
idts equ (OS_BASE+0x000B100)
WIN_STACK equ (OS_BASE+0x000C000)
WIN_POS equ (OS_BASE+0x000C400)
FDD_BUFF equ (OS_BASE+0x000D000)
;unused ? only one reference
ENABLE_TASKSWITCH equ (OS_BASE+0x000E000)
PUTPIXEL equ (OS_BASE+0x000E020)
GETPIXEL equ (OS_BASE+0x000E024)
;unused ? only one reference
BANK_SWITCH equ (OS_BASE+0x000E030)
VESA_VER_MAJOR equ (OS_BASE+0x000E034)
GFX_CARD_VENDOR equ (OS_BASE+0x000E035)
;unused ? store mousepointer
MOUSE_PICTURE equ (OS_BASE+0x000F200)
MOUSE_VISIBLE equ (OS_BASE+0x000F204)
WIN_TEMP_XY equ (OS_BASE+0x000F300)
KEY_COUNT equ (OS_BASE+0x000F400)
KEY_BUFF equ (OS_BASE+0x000F401)
BTN_COUNT equ (OS_BASE+0x000F500)
BTN_BUFF equ (OS_BASE+0x000F501)
CPU_FREQ equ (OS_BASE+0x000F600)
;unused ? no active references
MOUSE_PORT equ (OS_BASE+0x000F604)
;unused
PS2_CHUNK equ (OS_BASE+0x000FB00)
MOUSE_X equ (OS_BASE+0x000FB0A)
MOUSE_Y equ (OS_BASE+0x000FB0C)
MOUSE_COLOR_MEM equ (OS_BASE+0x000FB10)
COLOR_TEMP equ (OS_BASE+0x000FB30)
BTN_DOWN equ (OS_BASE+0x000FB40)
MOUSE_DOWN equ (OS_BASE+0x000FB44)
X_UNDER equ (OS_BASE+0x000FB4A)
Y_UNDER equ (OS_BASE+0x000FB4C)
ScreenBPP equ (OS_BASE+0x000FBF1)
;unused ? only one reference
MOUSE_BUFF_COUNT equ (OS_BASE+0x000FCFF)
LFBAddress equ (OS_BASE+0x000FE80)
MEM_AMOUNT equ (OS_BASE+0x000FE8C)
;LFBSize equ (OS_BASE+0x02f9050)
ScreenWidth equ (OS_BASE+0x000FE00)
ScreenHeight equ (OS_BASE+0x000FE04)
BytesPerScanLine equ (OS_BASE+0x000FE08)
SCR_MODE equ (OS_BASE+0x000FE0C)
BTN_ADDR equ (OS_BASE+0x000FE88)
SYS_SHUTDOWN equ (OS_BASE+0x000FF00)
TASK_ACTIVATE equ (OS_BASE+0x000FF01)
REDRAW_BACKGROUND equ (OS_BASE+0x000FFF0)
BANK_RW equ (OS_BASE+0x000FFF2)
MOUSE_BACKGROUND equ (OS_BASE+0x000FFF4)
DONT_DRAW_MOUSE equ (OS_BASE+0x000FFF5)
DONT_SWITCH equ (OS_BASE+0x000FFFF)
TMP_STACK_TOP equ 0x003EC00
FONT_II equ (OS_BASE+0x003EC00)
FONT_I equ (OS_BASE+0x003F600)
DRIVE_DATA equ (OS_BASE+0x0040000)
SLOT_BASE equ (OS_BASE+0x0080000)
;unused
TMP_BUFF equ (OS_BASE+0x0090000)
VGABasePtr equ (OS_BASE+0x00A0000)
RAMDISK equ (OS_BASE+0x0100000)
RAMDISK_FAT equ (OS_BASE+0x0280000)
FLOPPY_FAT equ (OS_BASE+0x0282000)
; unused?
SB16_Status equ (OS_BASE+0x02B0000)
BUTTON_INFO equ (OS_BASE+0x02C0000)
RESERVED_PORTS equ (OS_BASE+0x02D0000)
IRQ_SAVE equ (OS_BASE+0x02E0000)
SYS_VAR equ (OS_BASE+0x02f0000)
IMG_BACKGROUND equ (OS_BASE+0x0300000)
WinMapAddress equ (OS_BASE+0x0460000)
display_data equ (OS_BASE+0x0460000)
;unused ?
HD_CACHE equ (OS_BASE+0x0600000)
stack_data_start equ (OS_BASE+0x0700000)
eth_data_start equ (OS_BASE+0x0700000)
stack_data equ (OS_BASE+0x0704000)
stack_data_end equ (OS_BASE+0x071ffff)
VMODE_BASE equ (OS_BASE+0x0760000)
resendQ equ (OS_BASE+0x0770000)
skin_data equ (OS_BASE+0x0778000)
tss_data equ (OS_BASE+0x780000)
draw_data equ (OS_BASE+0x988000)
HEAP_BASE equ (OS_BASE+0x98B000)
LFB_BASE equ 0x7DC00000
page_tabs equ 0x7FC00000
master_tab equ 0x7FDFF000
app_page_tabs equ 0x7FE00000
sys_pgdir equ OS_BASE+0x00050000
sys_master_tab equ OS_BASE+0x00051000
sys_pgmap equ OS_BASE+0x00052000
new_app_base equ 0x80000000
twdw equ (CURRENT_TASK-window_data)
std_application_base_address equ new_app_base
RING0_STACK_SIZE equ 0x2000 - 512 ;512 áàéò äëÿ êîíòåêñòà FPU
;PAGES_USED equ 4
PG_UNMAP equ 0x000
PG_MAP equ 0x001
PG_WRITE equ 0x002
PG_SW equ 0x003
PG_USER equ 0x005
PG_UW equ 0x007
PG_NOCACHE equ 0x018
PG_LARGE equ 0x080
PG_GLOBAL equ 0x100
;;;;;;;;;;;boot time variables
;BOOT_BPP equ 0x9000 ;byte bits per pixel
BOOT_SCANLINE equ 0x9001 ;word scanline length
BOOT_VESA_MODE equ 0x9008 ;word vesa video mode
;;BOOT_X_RES equ 0x900A ;word X res
;;BOOT_Y_RES equ 0x900C ;word Y res
;;BOOT_MOUSE_PORT equ 0x9010 ;byte mouse port - not used
BOOT_BANK_SW equ 0x9014 ;dword Vesa 1.2 pm bank switch
BOOT_LFB equ 0x9018 ;dword Vesa 2.0 LFB address
BOOT_MTRR equ 0x901C ;byte 0 or 1 : enable MTRR graphics acceleration
BOOT_LOG equ 0x901D ;byte not used anymore (0 or 1 : enable system log display)
BOOT_DIRECT_LFB equ 0x901E ;byte 0 or 1 : enable direct lfb write, paging disabled
BOOT_PCI_DATA equ 0x9020 ;8bytes pci data
BOOT_VRR equ 0x9030 ;byte VRR start enabled 1, 2-no
BOOT_IDE_BASE_ADDR equ 0x9031 ;word IDEContrRegsBaseAddr
BOOT_MEM_AMOUNT equ 0x9034 ;dword memory amount
TMP_FILE_NAME equ 0
TMP_CMD_LINE equ 1024
TMP_ICON_OFFS equ 1280
EVENT_REDRAW equ 0x00000001
EVENT_KEY equ 0x00000002
EVENT_BUTTON equ 0x00000004
EVENT_BACKGROUND equ 0x00000010
EVENT_MOUSE equ 0x00000020
EVENT_IPC equ 0x00000040
EVENT_NETWORK equ 0x00000080
EVENT_DEBUG equ 0x00000100
EVENT_EXTENDED equ 0x00000200
EV_INTR equ 1
struc SYS_VARS
{ .bpp dd ?
.scanline dd ?
.vesa_mode dd ?
.x_res dd ?
.y_res dd ?
.cpu_caps dd ?
dd ?
dd ?
dd ?
}
struc APPOBJ ;common object header
{
.magic dd ? ;
.destroy dd ? ;internal destructor
.fd dd ? ;next object in list
.bk dd ? ;prev object in list
.pid dd ? ;owner id
};
virtual at 0
APPOBJ APPOBJ
end virtual
APP_OBJ_OFFSET equ 48
APP_EV_OFFSET equ 40
struc CURSOR
{;common object header
.magic dd ? ;'CURS'
.destroy dd ? ;internal destructor
.fd dd ? ;next object in list
.bk dd ? ;prev object in list
.pid dd ? ;owner id
;cursor data
.base dd ? ;allocated memory
.hot_x dd ? ;hotspot coords
.hot_y dd ?
}
virtual at 0
CURSOR CURSOR
end virtual
CURSOR_SIZE equ 32
struc EVENT
{
.magic dd ? ;'EVNT'
.destroy dd ? ;internal destructor
.fd dd ? ;next object in list
.bk dd ? ;prev object in list
.pid dd ? ;owner id
.id dd ? ;event uid
.state dd ? ;internal flags
.code dd ?
rd 5
}
EVENT_SIZE equ 52
virtual at 0
EVENT EVENT
end virtual
struc HEAP_DATA
{
.mutex rd 1
.refcount rd 1
.heap_base rd 1
.heap_top rd 1
.app_mem rd 1
}
HEAP_DATA_SIZE equ 20
virtual at 0
HEAP_DATA HEAP_DATA
end virtual
struc BOOT_DATA
{ .bpp dd ?
.scanline dd ?
.vesa_mode dd ?
.x_res dd ?
.y_res dd ?
.mouse_port dd ?
.bank_switch dd ?
.lfb dd ?
.vesa_mem dd ?
.log dd ?
.direct_lfb dd ?
.pci_data dd ?
; dd ?
.vrr dd ?
.ide_base dd ?
.mem_amount dd ?
.pages_count dd ?
.pagemap_size dd ?
.kernel_max dd ?
.kernel_pages dd ?
.kernel_tables dd ?
.cpu_vendor dd ?
dd ?
dd ?
.cpu_sign dd ?
.cpu_info dd ?
.cpu_caps dd ?
dd ?
dd ?
}
virtual at 0
BOOT_DATA BOOT_DATA
end virtual
struc MEM_STATE
{ .mutex rd 1
.smallmap rd 1
.treemap rd 1
.topsize rd 1
.top rd 1
.smallbins rd 4*32
.treebins rd 32
}
struc PG_DATA
{ .mem_amount dd ?
.vesa_mem dd ?
.pages_count dd ?
.pages_free dd ?
.pages_faults dd ?
.pagemap_size dd ?
.kernel_max dd ?
.kernel_pages dd ?
.kernel_tables dd ?
.sys_page_dir dd ?
.pg_mutex dd ?
}
;struc LIB
;{ .lib_name rb 16
; .lib_base dd ?
; .lib_start dd ?
; .export dd ?
; .import dd ?
;}
struc SRV
{ .srv_name rb 16 ;ASCIIZ string
.magic dd ? ;+0x10 ;'SRV '
.size dd ? ;+0x14 ;size of structure SRV
.fd dd ? ;+0x18 ;next SRV descriptor
.bk dd ? ;+0x1C ;prev SRV descriptor
.base dd ? ;+0x20 ;service base address
.entry dd ? ;+0x24 ;service START function
.srv_proc dd ? ;+0x28 ;main service handler
}
SRV_FD_OFFSET equ 0x18
SRV_SIZE equ 44
struc COFF_HEADER
{ .machine dw ?
.nSections dw ?
.DataTime dd ?
.pSymTable dd ?
.nSymbols dd ?
.optHeader dw ?
.flags dw ?
};
struc COFF_SECTION
{ .Name rb 8
.VirtualSize dd ?
.VirtualAddress dd ?
.SizeOfRawData dd ?
.PtrRawData dd ?
.PtrReloc dd ?
.PtrLinenumbers dd ?
.NumReloc dw ?
.NumLinenum dw ?
.Characteristics dd ?
}
COFF_SECTION_SIZE equ 40
struc COFF_RELOC
{ .VirtualAddress dd ?
.SymIndex dd ?
.Type dw ?
}
struc COFF_SYM
{ .Name rb 8
.Value dd ?
.SectionNumber dw ?
.Type dw ?
.StorageClass db ?
.NumAuxSymbols db ?
}
CSYM_SIZE equ 18
struc IOCTL
{ .handle dd ?
.io_code dd ?
.input dd ?
.inp_size dd ?
.output dd ?
.out_size dd ?
}
virtual at 0
IOCTL IOCTL
end virtual
;virtual at 0
; LIB LIB
;end virtual
virtual at 0
SRV SRV
end virtual
virtual at 0
CFH COFF_HEADER
end virtual
virtual at 0
CFS COFF_SECTION
end virtual
virtual at 0
CRELOC COFF_RELOC
end virtual
virtual at 0
CSYM COFF_SYM
end virtual

View File

@ -0,0 +1,499 @@
; diamond, 2006
sys_debug_services:
cmp eax, 9
ja @f
jmp dword [sys_debug_services_table+eax*4]
@@: ret
sys_debug_services_table:
dd debug_set_event_data
dd debug_getcontext
dd debug_setcontext
dd debug_detach
dd debug_suspend
dd debug_resume
dd debug_read_process_memory
dd debug_write_process_memory
dd debug_terminate
dd debug_set_drx
debug_set_event_data:
; in: ebx = pointer
; destroys eax
mov eax, [CURRENT_TASK]
shl eax, 8
mov [eax+SLOT_BASE+APPDATA.dbg_event_mem], ebx
ret
get_debuggee_slot:
; in: ebx=PID
; out: CF=1 if error
; CF=0 and eax=slot*0x20 if ok
; out: interrupts disabled
cli
mov eax, ebx
call pid_to_slot
test eax, eax
jz .ret_bad
shl eax, 5
push ebx
mov ebx, [CURRENT_TASK]
cmp [SLOT_BASE+eax*8+APPDATA.debugger_slot], ebx
pop ebx
jnz .ret_bad
; clc ; automatically
ret
.ret_bad:
stc
ret
debug_detach:
; in: ebx=pid
; destroys eax,ebx
call get_debuggee_slot
jc .ret
and dword [eax*8+SLOT_BASE+APPDATA.debugger_slot], 0
call do_resume
.ret:
sti
ret
debug_terminate:
; in: ebx=pid
call get_debuggee_slot
jc debug_detach.ret
mov ebx, eax
shr ebx, 5
push 2
pop eax
jmp sys_system
debug_suspend:
; in: ebx=pid
; destroys eax,ebx
call get_debuggee_slot
jc .ret
mov bl, [CURRENT_TASK+eax+TASKDATA.state] ; process state
test bl, bl
jz .1
cmp bl, 5
jnz .ret
mov bl, 2
.2: mov [CURRENT_TASK+eax+TASKDATA.state], bl
.ret:
sti
ret
.1:
inc ebx
jmp .2
do_resume:
mov bl, [CURRENT_TASK+eax+TASKDATA.state]
cmp bl, 1
jz .1
cmp bl, 2
jnz .ret
mov bl, 5
.2: mov [CURRENT_TASK+eax+TASKDATA.state], bl
.ret: ret
.1: dec ebx
jmp .2
debug_resume:
; in: ebx=pid
; destroys eax,ebx
call get_debuggee_slot
jc .ret
call do_resume
.ret: sti
ret
debug_getcontext:
; in:
; ebx=pid
; ecx=sizeof(CONTEXT)
; edx->CONTEXT
; destroys eax,ecx,edx,esi,edi
cmp ecx, 28h
jnz .ret
add edx, std_application_base_address
push ebx
mov ebx, edx
call check_region
pop ebx
dec eax
jnz .ret
call get_debuggee_slot
jc .ret
imul eax, tss_step/32
add eax, tss_data
mov edi, edx
cmp [eax+TSS._cs], app_code
jnz .ring0
lea esi, [eax+TSS._eip]
shr ecx, 2
rep movsd
jmp .ret
.ring0:
; note that following code assumes that all interrupt/exception handlers
; saves ring-3 context by push ds es, pushad in this order
mov esi, [eax+TSS._esp0]
; top of ring0 stack: ring3 stack ptr (ss+esp), iret data (cs+eip+eflags), ds, es, pushad
sub esi, 8+12+8+20h
lodsd
mov [edi+24h], eax
lodsd
mov [edi+20h], eax
lodsd
mov [edi+1Ch], eax
lodsd
lodsd
mov [edi+14h], eax
lodsd
mov [edi+10h], eax
lodsd
mov [edi+0Ch], eax
lodsd
mov [edi+8], eax
add esi, 8
lodsd
mov [edi], eax
lodsd
lodsd
mov [edi+4], eax
lodsd
mov [edi+18h], eax
.ret:
sti
ret
debug_setcontext:
; in:
; ebx=pid
; ecx=sizeof(CONTEXT)
; edx->CONTEXT
; destroys eax,ecx,edx,esi,edi
cmp ecx, 28h
jnz .ret
add edx, std_application_base_address
push ebx
mov ebx, edx
call check_region
pop ebx
dec eax
jnz .ret
call get_debuggee_slot
jc .stiret
imul eax, tss_step/32
add eax, tss_data
mov esi, edx
cmp [eax+TSS._cs], app_code
jnz .ring0
lea edi, [eax+TSS._eip]
shr ecx, 2
rep movsd
jmp .stiret
.ring0:
mov edi, [eax+TSS._esp0]
sub edi, 8+12+8+20h
mov eax, [esi+24h]
stosd
mov eax, [esi+20h]
stosd
mov eax, [esi+1Ch]
stosd
scasd
mov eax, [esi+14h]
stosd
mov eax, [esi+10h]
stosd
mov eax, [esi+0Ch]
stosd
mov eax, [esi+8]
stosd
add edi, 8
mov eax, [esi]
stosd
scasd
mov eax, [esi+4]
stosd
mov eax, [esi+18h]
stosd
.stiret:
sti
.ret:
ret
debug_set_drx:
call get_debuggee_slot
jc .errret
mov ebp, eax
lea eax, [eax*8+SLOT_BASE+APPDATA.dbg_regs]
; [eax]=dr0, [eax+4]=dr1, [eax+8]=dr2, [eax+C]=dr3
; [eax+10]=dr7
add edx, std_application_base_address
jc .errret
cmp cl, 3
ja .errret
mov ebx, dr7
shr ebx, cl
shr ebx, cl
test ebx, 2 ; bit 1+2*index = G0..G3, global break enable
jnz .errret2
test ch, ch
jns .new
; clear breakpoint
movzx ecx, cl
add ecx, ecx
and dword [eax+ecx*2], 0 ; clear DR<i>
btr dword [eax+10h], ecx ; clear L<i> bit
test byte [eax+10h], 55h
jnz .okret
imul eax, ebp, tss_step/32
and byte [eax + tss_data + TSS._trap], not 1
.okret:
and dword [esp+36], 0
sti
ret
.errret:
sti
mov dword [esp+36], 1
ret
.errret2:
sti
mov dword [esp+36], 2
ret
.new:
; add new breakpoint
; cl=index; ch=flags; edx=address
test ch, 0xF0
jnz .errret
mov bl, ch
and bl, 3
cmp bl, 2
jz .errret
mov bl, ch
shr bl, 2
cmp bl, 2
jz .errret
test dl, bl
jnz .errret
or byte [eax+10h+1], 3 ; set GE and LE flags
movzx ebx, ch
movzx ecx, cl
add ecx, ecx
bts dword [eax+10h], ecx ; set L<i> flag
add ecx, ecx
mov [eax+ecx], edx ; set DR<i>
shl ebx, cl
mov edx, 0xF
shl edx, cl
not edx
and [eax+10h+2], dx
or [eax+10h+2], bx ; set R/W and LEN fields
imul eax, ebp, tss_step/32
or byte [eax + tss_data + TSS._trap], 1
jmp .okret
debug_read_process_memory:
; in:
; ebx=pid
; ecx=length
; esi->buffer in debugger
; edx=address in debuggee
; out: [esp+36]=sizeof(read)
; destroys all
add esi, std_application_base_address
push ebx
mov ebx, esi
call check_region
pop ebx
dec eax
jnz .err
call get_debuggee_slot
jc .err
shr eax, 5
mov ebx, esi
call read_process_memory
sti
mov dword [esp+36], eax
ret
.err:
or dword [esp+36], -1
ret
debug_write_process_memory:
; in:
; ebx=pid
; ecx=length
; esi->buffer in debugger
; edx=address in debuggee
; out: [esp+36]=sizeof(write)
; destroys all
add esi, std_application_base_address
push ebx
mov ebx, esi
call check_region
pop ebx
dec eax
jnz debug_read_process_memory.err
call get_debuggee_slot
jc debug_read_process_memory.err
shr eax, 5
mov ebx, esi
call write_process_memory
sti
mov [esp+36], eax
ret
debugger_notify:
; in: eax=debugger slot
; ecx=size of debug message
; [esp+4]..[esp+4+ecx]=message
; interrupts must be disabled!
; destroys all general registers
; interrupts remain disabled
xchg ebp, eax
mov edi, [timer_ticks]
add edi, 500 ; 5 sec timeout
.1:
mov eax, ebp
shl eax, 8
mov edx, [SLOT_BASE+eax+APPDATA.dbg_event_mem]
test edx, edx
jz .ret
; read buffer header
push ecx
push eax
push eax
mov eax, ebp
mov ebx, esp
mov ecx, 8
call read_process_memory
cmp eax, ecx
jz @f
add esp, 12
jmp .ret
@@:
cmp dword [ebx], 0
jg @f
.2:
pop ecx
pop ecx
pop ecx
cmp dword [CURRENT_TASK], 1
jnz .notos
cmp [timer_ticks], edi
jae .ret
.notos:
sti
call change_task
cli
jmp .1
@@:
mov ecx, [ebx+8]
add ecx, [ebx+4]
cmp ecx, [ebx]
ja .2
; advance buffer position
push ecx
mov ecx, 4
sub ebx, ecx
mov eax, ebp
add edx, ecx
call write_process_memory
pop eax
; write message
mov eax, ebp
add edx, ecx
add edx, [ebx+8]
add ebx, 20
pop ecx
pop ecx
pop ecx
call write_process_memory
; new debug event
mov eax, ebp
shl eax, 8
or byte [SLOT_BASE+eax+APPDATA.event_mask+1], 1 ; set flag 100h
.ret:
ret
debug_exc:
; int 1 = #DB
save_ring3_context
cld
mov ax, os_data
mov ds, ax
mov es, ax
mov eax, dr6
test ax, ax
jns @f
; this is exception from task switch
; set DRx registers for task and continue
mov eax, [CURRENT_TASK]
shl eax, 8
add eax, SLOT_BASE+APPDATA.dbg_regs
mov ecx, [eax+0]
mov dr0, ecx
mov ecx, [eax+4]
mov dr1, ecx
mov ecx, [eax+8]
mov dr2, ecx
mov ecx, [eax+0Ch]
mov dr3, ecx
xor ecx, ecx
mov dr6, ecx
mov ecx, [eax+10h]
mov dr7, ecx
restore_ring3_context
iretd
@@:
push eax
xor eax, eax
mov dr6, eax
; test if debugging
cli
mov eax, [CURRENT_TASK]
shl eax, 8
mov eax, [SLOT_BASE+eax+APPDATA.debugger_slot]
test eax, eax
jnz .debug
sti
; not debuggee => say error and terminate
add esp, 28h+4
mov [error_interrupt], 1
call show_error_parameters
mov edx, [TASK_BASE]
mov byte [edx+TASKDATA.state], 4
jmp change_task
.debug:
; we are debugged process, notify debugger and suspend ourself
; eax=debugger PID
pop edx
mov ebx, dr7
mov cl, not 1
.l1:
test bl, 1
jnz @f
and dl, cl
@@:
shr ebx, 2
add cl, cl
inc ecx
cmp cl, not 10h
jnz .l1
push edx ; DR6 image
mov ecx, [TASK_BASE]
push dword [ecx+TASKDATA.pid] ; PID
push 12
pop ecx
push 3 ; 3 = debug exception
call debugger_notify
pop ecx
pop ecx
pop ecx
mov edx, [TASK_BASE]
mov byte [edx+TASKDATA.state], 1 ; suspended
call change_task
restore_ring3_context
iretd

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,110 @@
iglobal
szKernel db 'KERNEL', 0
szVersion db 'version',0
szRegService db 'RegService',0
szGetService db 'GetService',0
szServiceHandler db 'ServiceHandler',0
szAttachIntHandler db 'AttachIntHandler',0
szFpuSave db 'FpuSave',0
szFpuRestore db 'FpuRestore',0
szPciApi db 'PciApi', 0
szPciRead32 db 'PciRead32', 0
szPciRead8 db 'PciRead8', 0
szPciWrite8 db 'PciWrite8',0
szAllocPage db 'AllocPage',0
szAllocPages db 'AllocPages',0
szFreePage db 'FreePage',0
szGetPgAddr db 'GetPgAddr',0
szMapPage db 'MapPage',0
szMapSpace db 'MapSpace',0
szCommitPages db 'CommitPages',0
szReleasePages db 'ReleasePages',0
szAllocKernelSpace db 'AllocKernelSpace',0
szFreeKernelSpace db 'FreeKernelSpace',0
szKernelAlloc db 'KernelAlloc',0
szKernelFree db 'KernelFree',0
szUserAlloc db 'UserAlloc',0
szUserFree db 'UserFree',0
szKmalloc db 'Kmalloc',0
szKfree db 'Kfree',0
szCreateObject db 'CreateObject',0
szDestroyObject db 'DestroyObject',0
szCreateEvent db 'CreateEvent',0
szRaiseEvent db 'RaiseEvent',0
szWaitEvent db 'WaitEvent',0
szDestroyEvent db 'DestroyEvent',0
szClearEvent db 'ClearEvent',0
szLoadCursor db 'LoadCursor',0
szSetHwCursor db 'SetHwCursor',0
szHwCursorRestore db 'HwCursorRestore', 0
szHwCursorCreate db 'HwCursorCreate', 0
szSysMsgBoardStr db 'SysMsgBoardStr', 0
szGetCurrentTask db 'GetCurrentTask',0
szLFBAddress db 'LFBAddress',0
szLoadFile db 'LoadFile',0
szSendEvent db 'SendEvent',0
align 16
kernel_export:
dd szRegService , reg_service
dd szGetService , get_service
dd szServiceHandler , srv_handler
dd szAttachIntHandler, attach_int_handler
dd szFpuSave , fpu_save
dd szFpuRestore , fpu_restore
dd szPciApi , pci_api
dd szPciRead32 , pci_read32
dd szPciRead8 , pci_read8
dd szPciWrite8 , pci_write8
dd szAllocPage , alloc_page
dd szAllocPages , alloc_pages
dd szFreePage , free_page
dd szMapPage , map_page
dd szMapSpace , map_space
dd szGetPgAddr , get_pg_addr
dd szCommitPages , commit_pages ;not implemented
dd szReleasePages , release_pages
dd szAllocKernelSpace, alloc_kernel_space
dd szFreeKernelSpace , free_kernel_space
dd szKernelAlloc , kernel_alloc
dd szKernelFree , kernel_free
dd szUserAlloc , user_alloc
dd szUserFree , user_free
dd szKmalloc , malloc
dd szKfree , free
dd szCreateObject , create_kernel_object
dd szDestroyObject , destroy_kernel_object
dd szCreateEvent , create_event
dd szRaiseEvent , raise_event
dd szWaitEvent , wait_event
dd szDestroyEvent , destroy_event
dd szClearEvent , clear_event
dd szLoadCursor , load_cursor
dd szSetHwCursor , set_hw_cursor
dd szHwCursorRestore , hw_restore
dd szHwCursorCreate , create_cursor
dd szSysMsgBoardStr , sys_msg_board_str
dd szGetCurrentTask , get_curr_task
dd szLoadFile , load_file
dd szSendEvent , send_event
exp_lfb:
dd szLFBAddress , 0
dd 0
endg

View File

@ -0,0 +1,270 @@
init_fpu:
clts
fninit
bt [cpu_caps], CAPS_SSE
jnc .no_SSE
mov ebx, cr4
mov ecx, cr0
or ebx, CR4_OSFXSR+CR4_OSXMMEXPT
mov cr4, ebx
and ecx, not (CR0_MP+CR0_EM)
or ecx, CR0_NE
mov cr0, ecx
mov dword [esp-4], SSE_INIT
ldmxcsr [esp-4]
xorps xmm0, xmm0
xorps xmm1, xmm1
xorps xmm2, xmm2
xorps xmm3, xmm3
xorps xmm4, xmm4
xorps xmm5, xmm5
xorps xmm6, xmm6
xorps xmm7, xmm7
fxsave [fpu_data] ;[eax]
ret
.no_SSE:
mov ecx, cr0
and ecx, not CR0_EM
or ecx, CR0_MP+CR0_NE
mov cr0, ecx
fnsave [fpu_data]
ret
; param
; eax= 512 bytes memory area
align 4
fpu_save:
push ecx
push esi
push edi
pushfd
cli
clts
mov edi, eax
mov ecx, [fpu_owner]
mov eax, [CURRENT_TASK]
cmp ecx, eax
jne .save
.copy:
shl eax, 8
mov esi, [eax+SLOT_BASE+APPDATA.fpu_state]
mov ecx, 512/4
cld
rep movsd
fninit
popfd
pop edi
pop esi
pop ecx
ret
.save:
mov [fpu_owner], eax
shl ecx, 8
mov ecx, [ecx+SLOT_BASE+APPDATA.fpu_state]
bt [cpu_caps], CAPS_SSE
jnc .no_SSE
fxsave [ecx]
jmp .copy
.no_SSE:
fnsave [ecx]
jmp .copy
align 4
fpu_restore:
push ecx
push esi
mov esi, eax
pushfd
cli
mov ecx, [fpu_owner]
mov eax, [CURRENT_TASK]
cmp ecx, eax
jne .copy
clts
bt [cpu_caps], CAPS_SSE
jnc .no_SSE
fxrstor [esi]
popfd
pop esi
pop ecx
ret
.no_SSE:
fnclex ;fix possible problems
frstor [esi]
popfd
pop esi
pop ecx
ret
.copy:
shl eax, 8
mov edi, [eax+SLOT_BASE+APPDATA.fpu_state]
mov ecx, 512/4
cld
rep movsd
popfd
pop esi
pop ecx
ret
align 4
e7: ;#NM exception handler
save_ring3_context
clts
mov ax, os_data
mov ds, ax
mov es, ax
mov ebx, [fpu_owner]
cmp ebx, [CURRENT_TASK]
je .exit
shl ebx, 8
mov eax, [ebx+SLOT_BASE+APPDATA.fpu_state]
bt [cpu_caps], CAPS_SSE
jnc .no_SSE
fxsave [eax]
mov ebx, [CURRENT_TASK]
mov [fpu_owner], ebx
shl ebx, 8
mov eax, [ebx+SLOT_BASE+APPDATA.fpu_state]
fxrstor [eax]
.exit:
restore_ring3_context
iret
.no_SSE:
fnsave [eax]
mov ebx, [CURRENT_TASK]
mov [fpu_owner], ebx
shl ebx, 8
mov eax, [ebx+SLOT_BASE+APPDATA.fpu_state]
frstor [eax]
restore_ring3_context
iret
iglobal
fpu_owner dd 1
endg
reg_eip equ ebp+4
reg_cs equ ebp+8
reg_eflags equ ebp+12
reg_esp equ ebp+16
reg_ss equ ebp+20
align 4
except_16: ;fpu native exceptions handler
push ebp
mov ebp, esp
push eax
push ebx
push ecx
push edx
mov ebx, [ss:CURRENT_TASK]
shl ebx, 8
mov eax, [ss:ebx+SLOT_BASE+APPDATA.fpu_handler]
test eax, eax
jz .default
mov ecx, [reg_eip]
mov edx, [reg_esp]
sub edx, 4
mov [ss:edx+new_app_base], ecx
mov [reg_esp], edx
mov dword [reg_eip], eax
pop edx
pop ecx
pop ebx
pop eax
leave
iretd
.default:
pop edx
pop ecx
pop ebx
pop eax
leave
save_ring3_context ;debugger support
mov bl, 16
jmp exc_c
align 4
except_19: ;sse exceptions handler
push ebp
mov ebp, esp
push eax
push ebx
push ecx
push edx
mov ebx, [ss:CURRENT_TASK]
shl ebx, 8
mov eax, [ss:ebx+SLOT_BASE+APPDATA.sse_handler]
test eax, eax
jz .default
mov ecx, [reg_eip]
mov edx, [reg_esp]
sub edx, 4
mov [ss:edx+new_app_base], ecx
mov [reg_esp], edx
mov dword [reg_eip], eax
pop edx
pop ecx
pop ebx
pop eax
leave
iretd
.default:
pop edx
pop ecx
pop ebx
pop eax
leave
save_ring3_context ;debugger support
mov bl, 19
jmp exc_c
restore reg_eip
restore reg_cs
restore reg_eflags
restore reg_esp
restore reg_ss

View File

@ -0,0 +1,841 @@
struc MEM_BLOCK
{ .next_block dd ?
.prev_block dd ? ;+4
.list_fd dd ? ;+8
.list_bk dd ? ;+12
.base dd ? ;+16
.size dd ? ;+20
.flags dd ? ;+24
.handle dd ? ;+28
}
MEM_LIST_OFFSET equ 8
FREE_BLOCK equ 4
USED_BLOCK equ 8
virtual at 0
MEM_BLOCK MEM_BLOCK
end virtual
MEM_BLOCK_SIZE equ 8*4
block_next equ MEM_BLOCK.next_block
block_prev equ MEM_BLOCK.prev_block
list_fd equ MEM_BLOCK.list_fd
list_bk equ MEM_BLOCK.list_bk
block_base equ MEM_BLOCK.base
block_size equ MEM_BLOCK.size
block_flags equ MEM_BLOCK.flags
macro calc_index op
{ shr op, 12
dec op
cmp op, 63
jna @f
mov op, 63
@@:
}
macro remove_from_list op
{ mov edx, [op+list_fd]
mov ecx, [op+list_bk]
test edx, edx
jz @f
mov [edx+list_bk], ecx
@@:
test ecx, ecx
jz @f
mov [ecx+list_fd], edx
@@:
mov [op+list_fd],0
mov [op+list_bk],0
}
macro remove_from_free op
{
remove_from_list op
mov eax, [op+block_size]
calc_index eax
cmp [mem_block_list+eax*4], op
jne @f
mov [mem_block_list+eax*4], edx
@@:
cmp [mem_block_list+eax*4], 0
jne @f
btr [mem_block_mask], eax
@@:
}
macro remove_from_used op
{
mov edx, [op+list_fd]
mov ecx, [op+list_bk]
mov [edx+list_bk], ecx
mov [ecx+list_fd], edx
mov [op+list_fd], 0
mov [op+list_bk], 0
}
align 4
proc init_kernel_heap
mov ecx, 64/4
mov edi, mem_block_list
xor eax, eax
cld
rep stosd
mov ecx, 512/4
mov edi, mem_block_map
not eax
rep stosd
mov [mem_block_start], mem_block_map
mov [mem_block_end], mem_block_map+512
mov [mem_block_arr], HEAP_BASE
mov eax, mem_used.fd-MEM_LIST_OFFSET
mov [mem_used.fd], eax
mov [mem_used.bk], eax
stdcall alloc_pages, dword 32
mov ecx, 32
mov edx, eax
mov edi, HEAP_BASE
.l1:
stdcall map_page,edi,edx,PG_SW
add edi, 0x1000
add edx, 0x1000
dec ecx
jnz .l1
mov edi, HEAP_BASE
mov ebx, HEAP_BASE+MEM_BLOCK_SIZE
xor eax, eax
mov [edi+block_next], ebx
mov [edi+block_prev], eax
mov [edi+list_fd], eax
mov [edi+list_bk], eax
mov [edi+block_base], HEAP_BASE
mov [edi+block_size], 4096*MEM_BLOCK_SIZE
mov [edi+block_flags], USED_BLOCK
mov [ebx+block_next], eax
mov [ebx+block_prev], eax
mov [ebx+list_fd], eax
mov [ebx+list_bk], eax
mov [ebx+block_base], HEAP_BASE+4096*MEM_BLOCK_SIZE
mov ecx, [MEM_AMOUNT]
sub ecx, HEAP_BASE + 4096*MEM_BLOCK_SIZE
mov [heap_size], ecx
mov [heap_free], ecx
mov [ebx+block_size], ecx
mov [ebx+block_flags], FREE_BLOCK
mov [mem_block_mask], eax
mov [mem_block_mask+4],0x80000000
mov [mem_block_list+63*4], ebx
mov byte [mem_block_map], 0xFC
and [heap_mutex], 0
mov [heap_blocks], 4095
mov [free_blocks], 4095
ret
endp
; param
; eax= required size
;
; retval
; edi= memory block descriptor
; ebx= descriptor index
align 4
get_block:
mov ecx, eax
shr ecx, 12
dec ecx
cmp ecx, 63
jle .get_index
mov ecx, 63
.get_index:
lea esi, [mem_block_mask]
xor ebx, ebx
or edx, -1
cmp ecx, 32
jb .bit_test
sub ecx, 32
add ebx, 32
add esi, 4
.bit_test:
shl edx, cl
and edx, [esi]
.find:
bsf edi, edx
jz .high_mask
add ebx, edi
mov edi, [mem_block_list+ebx*4]
.check_size:
cmp eax, [edi+block_size]
ja .next
ret
.high_mask:
add esi, 4
cmp esi, mem_block_mask+8
jae .err
add ebx, 32
mov edx, [esi]
jmp .find
.next:
mov edi, [edi+list_fd]
test edi, edi
jnz .check_size
.err:
xor edi, edi
ret
align 4
proc alloc_mem_block
mov ebx, [mem_block_start]
mov ecx, [mem_block_end]
.l1:
bsf eax,[ebx];
jnz found
add ebx,4
cmp ebx, ecx
jb .l1
xor eax,eax
ret
found:
btr [ebx], eax
mov [mem_block_start],ebx
sub ebx, mem_block_map
lea eax,[eax+ebx*8]
shl eax, 5
add eax, [mem_block_arr]
dec [free_blocks]
ret
endp
proc free_mem_block
mov dword [eax], 0
mov dword [eax+4], 0
mov dword [eax+8], 0
mov dword [eax+12], 0
mov dword [eax+16], 0
; mov dword [eax+20], 0
mov dword [eax+24], 0
mov dword [eax+28], 0
sub eax, [mem_block_arr]
shr eax, 5
mov ebx, mem_block_map
bts [ebx], eax
inc [free_blocks]
shr eax, 3
and eax, not 3
add eax, ebx
cmp [mem_block_start], eax
ja @f
ret
@@:
mov [mem_block_start], eax
ret
.err:
xor eax, eax
ret
endp
align 4
proc alloc_kernel_space stdcall, size:dword
local block_ind:DWORD
mov eax, [size]
add eax, 4095
and eax, not 4095
mov [size], eax
mov ebx, heap_mutex
call wait_mutex ;ebx
cmp eax, [heap_free]
ja .error
call get_block ; eax
test edi, edi
jz .error
cmp [edi+block_flags], FREE_BLOCK
jne .error
mov [block_ind], ebx ;index of allocated block
mov eax, [edi+block_size]
cmp eax, [size]
je .m_eq_size
call alloc_mem_block
and eax, eax
jz .error
mov esi, eax ;esi - splitted block
mov [esi+block_next], edi
mov eax, [edi+block_prev]
mov [esi+block_prev], eax
mov [edi+block_prev], esi
mov [esi+list_fd], 0
mov [esi+list_bk], 0
and eax, eax
jz @f
mov [eax+block_next], esi
@@:
mov ebx, [edi+block_base]
mov [esi+block_base], ebx
mov edx, [size]
mov [esi+block_size], edx
add [edi+block_base], edx
sub [edi+block_size], edx
mov eax, [edi+block_size]
shr eax, 12
sub eax, 1
cmp eax, 63
jna @f
mov eax, 63
@@:
cmp eax, [block_ind]
je .m_eq_ind
remove_from_list edi
mov ecx, [block_ind]
mov [mem_block_list+ecx*4], edx
test edx, edx
jnz @f
btr [mem_block_mask], ecx
@@:
mov edx, [mem_block_list+eax*4]
mov [edi+list_fd], edx
test edx, edx
jz @f
mov [edx+list_bk], edi
@@:
mov [mem_block_list+eax*4], edi
bts [mem_block_mask], eax
.m_eq_ind:
mov ecx, mem_used.fd-MEM_LIST_OFFSET
mov edx, [ecx+list_fd]
mov [esi+list_fd], edx
mov [esi+list_bk], ecx
mov [ecx+list_fd], esi
mov [edx+list_bk], esi
mov [esi+block_flags], USED_BLOCK
mov eax, [esi+block_base]
mov ebx, [size]
sub [heap_free], ebx
and [heap_mutex], 0
ret
.m_eq_size:
remove_from_list edi
mov [mem_block_list+ebx*4], edx
and edx, edx
jnz @f
btr [mem_block_mask], ebx
@@:
mov ecx, mem_used.fd-MEM_LIST_OFFSET
mov edx, [ecx+list_fd]
mov [edi+list_fd], edx
mov [edi+list_bk], ecx
mov [ecx+list_fd], edi
mov [edx+list_bk], edi
mov [edi+block_flags], USED_BLOCK
mov eax, [edi+block_base]
mov ebx, [size]
sub [heap_free], ebx
and [heap_mutex], 0
ret
.error:
xor eax, eax
mov [heap_mutex], eax
ret
endp
align 4
proc free_kernel_space stdcall uses ebx ecx edx esi edi, base:dword
mov ebx, heap_mutex
call wait_mutex ;ebx
mov eax, [base]
mov esi, [mem_used.fd]
@@:
cmp esi, mem_used.fd-MEM_LIST_OFFSET
je .fail
cmp [esi+block_base], eax
je .found
mov esi, [esi+list_fd]
jmp @b
.found:
cmp [esi+block_flags], USED_BLOCK
jne .fail
mov eax, [esi+block_size]
add [heap_free], eax
mov edi, [esi+block_next]
test edi, edi
jz .prev
cmp [edi+block_flags], FREE_BLOCK
jne .prev
remove_from_free edi
mov edx, [edi+block_next]
mov [esi+block_next], edx
test edx, edx
jz @f
mov [edx+block_prev], esi
@@:
mov ecx, [edi+block_size]
add [esi+block_size], ecx
mov eax, edi
call free_mem_block
.prev:
mov edi, [esi+block_prev]
test edi, edi
jz .insert
cmp [edi+block_flags], FREE_BLOCK
jne .insert
remove_from_used esi
mov edx, [esi+block_next]
mov [edi+block_next], edx
test edx, edx
jz @f
mov [edx+block_prev], edi
@@:
mov eax, esi
call free_mem_block
mov ecx, [edi+block_size]
mov eax, [esi+block_size]
add eax, ecx
mov [edi+block_size], eax
calc_index eax
calc_index ecx
cmp eax, ecx
je .m_eq
push ecx
remove_from_list edi
pop ecx
cmp [mem_block_list+ecx*4], edi
jne @f
mov [mem_block_list+ecx*4], edx
@@:
cmp [mem_block_list+ecx*4], 0
jne @f
btr [mem_block_mask], ecx
@@:
mov esi, [mem_block_list+eax*4]
mov [mem_block_list+eax*4], edi
mov [edi+list_fd], esi
test esi, esi
jz @f
mov [esi+list_bk], edi
@@:
bts [mem_block_mask], eax
.m_eq:
xor eax, eax
mov [heap_mutex], eax
dec eax
ret
.insert:
remove_from_used esi
mov eax, [esi+block_size]
calc_index eax
mov edi, [mem_block_list+eax*4]
mov [mem_block_list+eax*4], esi
mov [esi+list_fd], edi
test edi, edi
jz @f
mov [edi+list_bk], esi
@@:
bts [mem_block_mask], eax
mov [esi+block_flags],FREE_BLOCK
xor eax, eax
mov [heap_mutex], eax
dec eax
ret
.fail:
xor eax, eax
mov [heap_mutex], eax
ret
endp
align 4
proc kernel_alloc stdcall, size:dword
locals
lin_addr dd ?
pages_count dd ?
endl
mov eax, [size]
add eax, 4095
and eax, not 4095;
mov [size], eax
and eax, eax
jz .err
mov ebx, eax
shr ebx, 12
mov [pages_count], ebx
stdcall alloc_kernel_space, eax
test eax, eax
jz .err
mov [lin_addr], eax
mov ecx, [pages_count]
mov edx, eax
mov ebx, ecx
shr ecx, 3
jz .next
and ebx, not 7
push ebx
stdcall alloc_pages, ebx
pop ecx ; yes ecx!!!
and eax, eax
jz .err
mov edi, eax
mov edx, [lin_addr]
@@:
stdcall map_page,edx,edi,dword PG_SW
add edx, 0x1000
add edi, 0x1000
dec ecx
jnz @B
.next:
mov ecx, [pages_count]
and ecx, 7
jz .end
@@:
push ecx
call alloc_page
pop ecx
test eax, eax
jz .err
stdcall map_page,edx,eax,dword PG_SW
add edx, 0x1000
dec ecx
jnz @B
.end:
mov eax, [lin_addr]
ret
.err:
xor eax, eax
ret
endp
align 4
proc kernel_free stdcall, base:dword
push ebx esi
mov ebx, heap_mutex
call wait_mutex ;ebx
mov eax, [base]
mov esi, [mem_used.fd]
@@:
cmp esi, mem_used.fd-MEM_LIST_OFFSET
je .fail
cmp [esi+block_base], eax
je .found
mov esi, [esi+list_fd]
jmp @b
.found:
cmp [esi+block_flags], USED_BLOCK
jne .fail
and [heap_mutex], 0
push ecx
mov ecx, [esi+block_size];
shr ecx, 12
call release_pages ;eax, ecx
pop ecx
stdcall free_kernel_space, [base]
pop esi ebx
ret
.fail:
and [heap_mutex], 0
pop esi ebx
ret
endp
restore block_next
restore block_prev
restore block_list
restore block_base
restore block_size
restore block_flags
;;;;;;;;;;;;;; USER ;;;;;;;;;;;;;;;;;
HEAP_TOP equ 0x5FC00000
align 4
proc init_heap
mov ebx,[CURRENT_TASK]
shl ebx,8
mov eax, [SLOT_BASE+APPDATA.heap_top+ebx]
test eax, eax
jz @F
sub eax,[SLOT_BASE+APPDATA.heap_base+ebx]
sub eax, 4096
ret
@@:
mov esi, [SLOT_BASE+APPDATA.mem_size+ebx]
add esi, 4095
and esi, not 4095
mov [SLOT_BASE+APPDATA.mem_size+ebx], esi
mov eax, HEAP_TOP
mov [SLOT_BASE+APPDATA.heap_base+ebx], esi
mov [SLOT_BASE+APPDATA.heap_top+ebx], eax
sub eax, esi
add esi, new_app_base
shr esi, 10
mov ecx, eax
sub eax, 4096
or ecx, FREE_BLOCK
mov [page_tabs+esi], ecx
ret
.exit:
xor eax, eax
ret
endp
align 4
proc user_alloc stdcall, alloc_size:dword
mov ecx, [alloc_size]
add ecx, (4095+4096)
and ecx, not 4095
mov ebx, [CURRENT_TASK]
shl ebx, 8
mov esi, dword [ebx+SLOT_BASE+APPDATA.heap_base]; heap_base
mov edi, dword [ebx+SLOT_BASE+APPDATA.heap_top]; heap_top
add esi, new_app_base
add edi, new_app_base
l_0:
cmp esi, edi
jae m_exit
mov ebx, esi
shr ebx, 12
mov eax, [page_tabs+ebx*4]
test eax, FREE_BLOCK
jz test_used
and eax, 0xFFFFF000
cmp eax, ecx ;alloc_size
jb m_next
jz @f
mov edx, esi
add edx, ecx
sub eax, ecx;
or eax, FREE_BLOCK
shr edx, 12
mov [page_tabs+edx*4], eax
@@:
or ecx, USED_BLOCK
mov [page_tabs+ebx*4], ecx
shr ecx, 12
dec ecx
inc ebx
@@:
mov dword [page_tabs+ebx*4], 2
inc ebx
dec ecx
jnz @B
mov edx, [CURRENT_TASK]
shl edx, 8
mov ebx, [alloc_size]
add ebx, 0xFFF
and ebx, not 0xFFF
add ebx, [SLOT_BASE+APPDATA.mem_size+edx]
call update_mem_size
mov eax, esi
add eax, 4096
sub eax, new_app_base
ret
m_next:
add esi, eax
jmp l_0
test_used:
test eax, USED_BLOCK
jz m_exit
and eax, 0xFFFFF000
add esi, eax
jmp l_0
m_exit:
xor eax, eax
ret
endp
align 4
proc user_free stdcall, base:dword
mov esi, [base]
test esi, esi
jz .exit
xor ebx, ebx
sub esi, 4096
shr esi, 12
mov eax, [page_tabs+esi*4]
test eax, USED_BLOCK
jz .not_used
and eax, not 4095
mov ecx, eax
or eax, FREE_BLOCK
mov [page_tabs+esi*4], eax
inc esi
sub ecx, 4096
shr ecx, 12
mov ebx, ecx
.release:
xor eax, eax
xchg eax, [page_tabs+esi*4]
test eax, 1
jz @F
call free_page
@@:
inc esi
dec ecx
jnz .release
.not_used:
mov edx, [CURRENT_TASK]
shl edx, 8
mov esi, dword [edx+SLOT_BASE+APPDATA.heap_base]; heap_base
mov edi, dword [edx+SLOT_BASE+APPDATA.heap_top]; heap_top
sub ebx, [edx+SLOT_BASE+APPDATA.mem_size]
neg ebx
call update_mem_size
add esi, new_app_base
add edi, new_app_base
shr esi, 12
shr edi, 12
@@:
mov eax, [page_tabs+esi*4]
test eax, USED_BLOCK
jz .test_free
shr eax, 12
add esi, eax
jmp @B
.test_free:
test eax, FREE_BLOCK
jz .err
mov edx, eax
shr edx, 12
add edx, esi
cmp edx, edi
jae .exit
mov ebx, [page_tabs+edx*4]
test ebx, USED_BLOCK
jz .next_free
shr ebx, 12
add edx, ebx
mov esi, edx
jmp @B
.next_free:
test ebx, FREE_BLOCK
jz .err
and dword [page_tabs+edx*4], 0
add eax, ebx
and eax, not 4095
or eax, FREE_BLOCK
mov [page_tabs+esi*4], eax
jmp @B
.exit:
xor eax, eax
inc eax
ret
.err:
xor eax, eax
ret
endp
if 0
align 4
proc alloc_dll
pushf
cli
bsf eax, [dll_map]
jnz .find
popf
xor eax, eax
ret
.find:
btr [dll_map], eax
popf
shl eax, 5
add eax, dll_tab
ret
endp
align 4
proc alloc_service
pushf
cli
bsf eax, [srv_map]
jnz .find
popf
xor eax, eax
ret
.find:
btr [srv_map], eax
popf
shl eax,0x02
lea eax,[srv_tab+eax+eax*8] ;srv_tab+eax*36
ret
endp
end if

View File

@ -0,0 +1,993 @@
; Small heap based on malloc/free/realloc written by Doug Lea
; Version 2.8.3 Thu Sep 22 11:16:15 2005 Doug Lea (dl at gee)
; Source ftp://gee.cs.oswego.edu/pub/misc/malloc.c
; License http://creativecommons.org/licenses/publicdomain.
; eax= size
; temp
; esi= nb
; ebx= idx
;
malloc:
push esi
; nb = ((size+7)&~7)+8;
mov esi, eax ;size
add esi, 7
and esi, -8
add esi, 8
mov ebx, mst.mutex
call wait_mutex ;ebx
cmp esi, 256
jae .large
mov ecx, esi
shr ecx, 3
or eax, -1
shl eax, cl
and eax, [mst.smallmap]
jz .small
push ebp
push edi
bsf eax, eax
mov ebx, eax
; psize= idx<<3;
; B = &ms.smallbins[idx];
; p = B->fd;
; F = p->fd;
; rsize= psize-nb;
lea ebp, [eax*8] ;ebp= psize
shl eax, 4
lea edi, [mst.smallbins+eax] ;edi= B
mov edx, [edi+8] ;edx= p
mov eax, [edx+8] ;eax= F
mov ecx, ebp
sub ecx, esi ;ecx= rsize
; if (B == F)
cmp edi, eax
jne @F
btr [mst.smallmap], ebx
@@:
; B->fd = F;
; F->bk = B;
; if(rsize<16)
cmp ecx, 16
mov [edi+8], eax
mov [eax+12], edi
jae .split
; p->head = psize|PINUSE_BIT|CINUSE_BIT;
; (p + psize)->head |= PINUSE_BIT;
lea eax, [edx+8]
or dword [edx+ebp+4], 1
or ebp, 3
mov [edx+4], ebp
pop edi
pop ebp
.done:
pop esi
mov [mst.mutex], 0
ret
.split:
lea ebx, [edx+8] ;ebx=mem
; r = chunk_plus_offset(p, nb);
; p->head = nb|PINUSE_BIT|CINUSE_BIT;
; r->head = rsize|PINUSE_BIT;
lea eax, [edx+esi] ;eax= r
or esi, 3
mov [edx+4], esi
mov edx, ecx
or edx, 1
mov [eax+4], edx
; (r + rsize)->prev_foot = rsize;
mov [eax+ecx], ecx
; I = rsize>>3;
shr ecx, 3
; ms.smallmap |= 1<< I;
bts [mst.smallmap], ecx
; B = &ms.smallbins[I];
shl ecx, 4
pop edi
pop ebp
add ecx, mst.smallbins ;ecx= B
mov edx, [ecx+8] ; F = B->fd;
mov [ecx+8], eax ; B->fd = r;
mov [edx+12], eax ; F->bk = r;
mov [eax+8], edx ; r->fd = F;
mov [eax+12], ecx ; r->bk = B;
mov eax, ebx
pop esi
ret
.small:
; if (ms.treemap != 0 && (mem = malloc_small(nb)) != 0)
cmp [mst.treemap], 0
je .from_top
mov eax, esi
call malloc_small
test eax, eax
jz .from_top
pop esi
and [mst.mutex], 0
ret
.large:
; if (ms.treemap != 0 && (mem = malloc_large(nb)) != 0)
cmp [mst.treemap], 0
je .from_top
call malloc_large ;esi= nb
test eax, eax
jne .done
.from_top:
; if (nb < ms.topsize)
mov eax, [mst.topsize]
cmp esi, eax
jae .fail
; rsize = ms.topsize -= nb;
; p = ms.top;
mov ecx, [mst.top]
sub eax, esi
mov [mst.topsize], eax
; r = ms.top = chunk_plus_offset(p, nb);
; r->head = rsize | PINUSE_BIT;
; p->head = nb |PINUSE_BIT|CINUSE_BIT;
lea edx, [ecx+esi]
or eax, 1
mov [mst.top], edx
or esi, 3
mov [edx+4], eax
mov [ecx+4], esi
lea eax, [ecx+8]
pop esi
and [mst.mutex], 0
ret
.fail:
xor eax, eax
pop esi
and [mst.mutex], 0
ret
; param
; eax= mem
align 4
free:
push edi
mov edi, eax
add edi, -8
; if(p->head & CINUSE_BIT)
test byte [edi+4], 2
je .fail
mov ebx, mst.mutex
call wait_mutex ;ebx
; psize = p->head & (~3);
mov eax, [edi+4]
push esi
mov esi, eax
and esi, -4
; next = chunk_plus_offset(p, psize);
; if(!(p->head & PINUSE_BIT))
test al, 1
lea ebx, [esi+edi]
jne .next
; prevsize = p->prev_foot;
; prev=p - prevsize;
; psize += prevsize;
; p = prev;
mov ecx, [edi] ;ecx= prevsize
add esi, ecx ;esi= psize
sub edi, ecx ;edi= p
; if (prevsize < 256)
cmp ecx, 256
jae .unlink_large
mov eax, [edi+8] ;F = p->fd;
mov edx, [edi+12] ;B = p->bk;
; if (F == B)
; ms.smallmap &= ~(1<< I);
shr ecx, 3
cmp eax, edx
jne @F
and [mst.smallmap], ecx
@@:
mov [eax+12], edx ;F->bk = B;
mov [edx+8], eax ;B->fd = F
jmp .next
.unlink_large:
mov edx, edi
call unlink_large_chunk
.next:
; if(next->head & PINUSE_BIT)
mov eax, [ebx+4]
test al, 1
jz .fail2
; if (! (next->head & CINUSE_BIT))
test al, 2
jnz .fix_next
; if (next == ms.top)
cmp ebx, [mst.top]
jne @F
; tsize = ms.topsize += psize;
mov eax, [mst.topsize]
add eax, esi
mov [mst.topsize], eax
; ms.top = p;
; p->head = tsize | PINUSE_BIT;
or eax, 1
mov [mst.top], edi
mov [edi+4], eax
.fail2:
and [mst.mutex], 0
pop esi
.fail:
pop edi
ret
@@:
; nsize = next->head & ~INUSE_BITS;
and eax, -4
add esi, eax ;psize += nsize;
; if (nsize < 256)
cmp eax, 256
jae .unl_large
mov edx, [ebx+8] ;F = next->fd
mov ebx, [ebx+12] ;B = next->bk
; if (F == B)
cmp edx, ebx
jne @F
mov ecx, eax
shr ecx, 3
btr [mst.smallmap], ecx
@@:
mov [edx+12], ebx ;F->bk = B
; p->head = psize|PINUSE_BIT;
mov ecx, esi
mov [ebx+8], edx
or ecx, 1
mov [edi+4], ecx
; (p+psize)->prev_foot = psize;
mov [esi+edi], esi
; insert_chunk(p,psize);
mov eax, esi
pop esi
mov ecx, edi
pop edi
jmp insert_chunk
.unl_large:
; unlink_large_chunk((tchunkptr)next);
mov edx, ebx
call unlink_large_chunk
; p->head = psize|PINUSE_BIT;
mov ecx, esi
or ecx, 1
mov [edi+4], ecx
; (p+psize)->prev_foot = psize;
mov [esi+edi], esi
; insert_chunk(p,psize);
mov eax, esi
pop esi
mov ecx, edi
pop edi
jmp insert_chunk
.fix_next:
; (p+psize)->prev_foot = psize;
; next->head &= ~PINUSE_BIT;
; p->head = psize|PINUSE_BIT;
and eax, -2
mov edx, esi
mov [ebx+4], eax
or edx, 1
mov [edi+4], edx
; (p+psize)->prev_foot = psize;
mov [esi+edi], esi
; insert_chunk(p,psize);
mov eax, esi
pop esi
mov ecx, edi
pop edi
jmp insert_chunk
; param
; ecx = chunk
; eax = size
align 4
insert_chunk:
cmp eax, 256
push esi
mov esi, ecx
jae .large
; I = S>>3;
; ms.smallmap |= 1<< I;
shr eax, 3
bts [mst.smallmap], eax
; B = &ms.smallbins[I];
shl eax, 4
add eax, mst.smallbins
mov edx, [eax+8] ;F = B->fd
mov [eax+8], esi ;B->fd = P
mov [edx+12], esi ;F->bk = P
mov [esi+8], edx ;P->fd = F
mov [esi+12], eax ;P->bk = B
pop esi
and [mst.mutex], 0
ret
.large:
mov ebx, eax
call insert_large_chunk
pop esi
and [mst.mutex], 0
ret
align 4
; param
; esi= chunk
; ebx= size
align 4
insert_large_chunk:
; I = compute_tree_index(S);
mov edx, ebx
shr edx, 8
bsr eax, edx
lea ecx, [eax+7]
mov edx, ebx
shr edx, cl
and edx, 1
lea ecx, [edx+eax*2]
; X->index = I;
mov dword [esi+28], ecx
; X->child[0] = X->child[1] = 0;
and dword [esi+20], 0
and dword [esi+16], 0
; H = &ms.treebins[I];
mov eax, ecx
lea edx, [mst.treebins+eax*4]
; if (!(ms.treemap & 1<<I))
bt [mst.treemap], ecx
jc .tree
; ms.treemap |= 1<<I;
bts [mst.treemap], ecx
; *H = X;
mov dword [edx], esi
jmp .done
.tree:
; T = *H;
mov edx, [edx]
; K = S << leftshift_for_tree_index(I);
mov eax, ecx
shr eax, 1
sub ecx, 31
mov edi, 37
sub edi, eax
neg ecx
sbb ecx, ecx
and ecx, edi
mov eax, ebx
shl eax, cl ;eax= K
jmp .loop
.not_eq_size:
; C = &(T->child[(K >> 31) & 1]);
mov ecx, eax
shr ecx, 31
lea ecx, [edx+ecx*4+16]
; K <<= 1;
; if (*C != 0)
mov edi, [ecx]
add eax, eax
test edi, edi
jz .insert_child
; T = *C;
mov edx, edi
.loop:
; for (;;)
; if ((T->head & ~INUSE_BITS) != S)
mov ecx, [edx+4]
and ecx, not 3
cmp ecx, ebx
jne .not_eq_size
; F = T->fd;
mov eax, [edx+8]
; T->fd = F->bk = X;
mov [eax+12], esi
mov [edx+8], esi
; X->fd = F;
; X->bk = T;
; X->parent = 0;
and dword [esi+24], 0
mov [esi+8], eax
mov [esi+12], edx
ret
.insert_child:
; *C = X;
mov [ecx], esi
.done:
; X->parent = T;
mov [esi+24], edx
; X->fd = X->bk = X;
mov [esi+12], esi
mov [esi+8], esi
ret
; param
; edx= chunk
align 4
unlink_large_chunk:
mov eax, [edx+12]
cmp eax, edx
push edi
mov edi, [edx+24]
je @F
mov ecx, [edx+8] ;F = X->fd
mov [ecx+12], eax ;F->bk = R;
mov [eax+8], ecx ;R->fd = F
jmp .parent
@@:
mov eax, [edx+20]
test eax, eax
push esi
lea esi, [edx+20]
jne .loop
mov eax, [edx+16]
test eax, eax
lea esi, [edx+16]
je .l2
.loop:
cmp dword [eax+20], 0
lea ecx, [eax+20]
jne @F
cmp dword [eax+16], 0
lea ecx, [eax+16]
je .l1
@@:
mov eax, [ecx]
mov esi, ecx
jmp .loop
.l1:
mov dword [esi], 0
.l2:
pop esi
.parent:
test edi, edi
je .done
mov ecx, [edx+28]
cmp edx, [mst.treebins+ecx*4]
lea ecx, [mst.treebins+ecx*4]
jne .l3
test eax, eax
mov [ecx], eax
jne .l5
mov ecx, [edx+28]
btr [mst.treemap], ecx
pop edi
ret
.l3:
cmp [edi+16], edx
jne @F
mov [edi+16], eax
jmp .l4
@@:
mov [edi+20], eax
.l4:
test eax, eax
je .done
.l5:
mov [eax+24], edi
mov ecx, [edx+16]
test ecx, ecx
je .l6
mov [eax+16], ecx
mov [ecx+24], eax
.l6:
mov edx, [edx+20]
test edx, edx
je .done
mov [eax+20], edx
mov [edx+24], eax
.done:
pop edi
ret
; param
; esi= nb
align 4
malloc_small:
push ebp
mov ebp, esi
push edi
bsf eax,[mst.treemap]
mov ecx, [mst.treebins+eax*4]
; rsize = (t->head & ~INUSE_BITS) - nb;
mov edi, [ecx+4]
and edi, -4
sub edi, esi
.loop:
mov ebx, ecx
.loop_1:
; while ((t = leftmost_child(t)) != 0)
mov eax, [ecx+16]
test eax, eax
jz @F
mov ecx, eax
jmp .l1
@@:
mov ecx, [ecx+20]
.l1:
test ecx, ecx
jz .unlink
; trem = (t->head & ~INUSE_BITS) - nb;
mov eax, [ecx+4]
and eax, -4
sub eax, ebp
; if (trem < rsize)
cmp eax, edi
jae .loop_1
; rsize = trem;
mov edi, eax
jmp .loop
.unlink:
; r = chunk_plus_offset((mchunkptr)v, nb);
; unlink_large_chunk(v);
mov edx, ebx
lea esi, [ebx+ebp]
call unlink_large_chunk
; if (rsize < 16)
cmp edi, 16
jae .split
; v->head = (rsize + nb)|PINUSE_BIT|CINUSE_BIT;
lea ecx, [edi+ebp]
; (v+rsize + nb)->head |= PINUSE_BIT;
add edi, ebx
lea eax, [edi+ebp+4]
pop edi
or ecx, 3
mov [ebx+4], ecx
or dword [eax], 1
pop ebp
lea eax, [ebx+8]
ret
.split:
; v->head = nb|PINUSE_BIT|CINUSE_BIT;
; r->head = rsize|PINUSE_BIT;
; (r+rsize)->prev_foot = rsize;
or ebp, 3
mov edx, edi
or edx, 1
cmp edi, 256
mov [ebx+4], ebp
mov [esi+4], edx
mov [esi+edi], edi
jae .large
shr edi, 3
bts [mst.smallmap], edi
mov eax, edi
shl eax, 4
add eax, mst.smallbins
mov edx, [eax+8]
mov [eax+8], esi
mov [edx+12], esi
pop edi
mov [esi+12], eax
mov [esi+8], edx
pop ebp
lea eax, [ebx+8]
ret
.large:
lea eax, [ebx+8]
push eax
mov ebx, edi
call insert_large_chunk
pop eax
pop edi
pop ebp
ret
; param
; esi= nb
align 4
malloc_large:
.idx equ esp+4
.rst equ esp
push ebp
push edi
sub esp, 8
; v = 0;
; rsize = -nb;
mov edi, esi
mov ebx, esi
xor ebp, ebp
neg edi
; idx = compute_tree_index(nb);
mov edx, esi
shr edx, 8
bsr eax, edx
lea ecx, [eax+7]
shr esi, cl
and esi, 1
lea ecx, [esi+eax*2]
mov [.idx], ecx
; if ((t = ms.treebins[idx]) != 0)
mov eax, [mst.treebins+ecx*4]
test eax, eax
jz .l3
; sizebits = nb << leftshift_for_tree_index(idx);
cmp ecx, 31
jne @F
xor ecx, ecx
jmp .l1
@@:
mov edx, ecx
shr edx, 1
mov ecx, 37
sub ecx, edx
.l1:
mov edx, ebx
shl edx, cl
; rst = 0;
mov [.rst], ebp
.loop:
; trem = (t->head & ~INUSE_BITS) - nb;
mov ecx, [eax+4]
and ecx, -4
sub ecx, ebx
; if (trem < rsize)
cmp ecx, edi
jae @F
; v = t;
; if ((rsize = trem) == 0)
test ecx, ecx
mov ebp, eax
mov edi, ecx
je .l2
@@:
; rt = t->child[1];
mov ecx, [eax+20]
; t = t->child[(sizebits >> 31) & 1];
mov esi, edx
shr esi, 31
; if (rt != 0 && rt != t)
test ecx, ecx
mov eax, [eax+esi*4+16]
jz @F
cmp ecx, eax
jz @F
; rst = rt;
mov [.rst], ecx
@@:
; if (t == 0)
test eax, eax
jz @F
; sizebits <<= 1;
add edx, edx
jmp .loop
@@:
; t = rst;
mov eax, [.rst]
.l2:
; if (t == 0 && v == 0)
test eax, eax
jne .l4
test ebp, ebp
jne .l7
mov ecx, [.idx]
.l3:
; leftbits = (-1<<idx) & ms.treemap;
; if (leftbits != 0)
or edx, -1
shl edx, cl
and edx, [mst.treemap]
jz @F
bsf eax, edx
; t = ms.treebins[i];
mov eax, [mst.treebins+eax*4]
@@:
; while (t != 0)
test eax, eax
jz .l5
.l4:
; trem = (t->head & ~INUSE_BITS) - nb;
mov ecx, [eax+4]
and ecx, -4
sub ecx, ebx
; if (trem < rsize)
cmp ecx, edi
jae @F
; rsize = trem;
mov edi, ecx
; v = t;
mov ebp, eax
@@:
; t = leftmost_child(t);
mov ecx, [eax+16]
test ecx, ecx
je @F
mov eax, ecx
jmp .l6
@@:
mov eax, [eax+20]
.l6:
; while (t != 0)
test eax, eax
jne .l4
.l5:
; if (v != 0)
test ebp, ebp
jz .done
.l7:
; r = chunk_plus_offset((mchunkptr)v, nb);
; unlink_large_chunk(v);
mov edx, ebp
lea esi, [ebx+ebp]
call unlink_large_chunk
; if (rsize < 16)
cmp edi, 16
jae .large
; v->head = (rsize + nb)|PINUSE_BIT|CINUSE_BIT;
lea ecx, [edi+ebx]
; (v+rsize + nb)->head |= PINUSE_BIT;
add edi, ebp
lea eax, [edi+ebx+4]
or ecx, 3
mov [ebp+4], ecx
or dword [eax], 1
lea eax, [ebp+8]
add esp, 8
pop edi
pop ebp
ret
.large:
; v->head = nb|PINUSE_BIT|CINUSE_BIT;
; r->head = rsize|PINUSE_BIT;
mov edx, edi
or ebx, 3
mov [ebp+4], ebx
or edx, 1
mov [esi+4], edx
; (r+rsize)->prev_foot = rsize;
; insert_large_chunk((tchunkptr)r, rsize);
mov [esi+edi], edi
mov eax, edi
mov ecx, esi
call insert_chunk
lea eax, [ebp+8]
add esp, 8
pop edi
pop ebp
ret
.done:
add esp, 8
pop edi
pop ebp
xor eax, eax
ret
align 4
init_malloc:
stdcall kernel_alloc, 0x20000
mov [mst.top], eax
mov [mst.topsize], 128*1024
mov dword [eax+4], (128*1024) or 1
mov eax, mst.smallbins
@@:
mov [eax+8], eax
mov [eax+12], eax
add eax, 16
cmp eax, mst.smallbins+512
jl @B
ret

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,204 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; IRQ0 HANDLER (TIMER INTERRUPT) ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
align 32
irq0:
save_ring3_context
mov ax, os_data
mov ds, ax
mov es, ax
inc dword [timer_ticks]
mov eax, [timer_ticks]
call playNote ; <<<--- Speaker driver
cmp eax,[next_usage_update]
jb .nocounter
add eax,100
mov [next_usage_update],eax
call updatecputimes
.nocounter:
cmp [DONT_SWITCH], byte 1
jne .change_task
mov al,0x20 ; send End Of Interrupt signal
mov dx,0x20
out dx,al
mov [DONT_SWITCH], byte 0
restore_ring3_context
iret
.change_task:
call update_counters
call find_next_task
mov ecx, eax
mov al,0x20 ; send End Of Interrupt signal
mov dx,0x20
out dx,al
test ecx, ecx ; if there is only one running process
jnz .return
call do_change_task
.return:
restore_ring3_context
iret
align 4
change_task:
pushfd
cli
pushad
call update_counters
; \begin{Mario79}
cmp [dma_task_switched], 1
jne .find_next_task
mov [dma_task_switched], 0
mov ebx, [dma_process]
cmp [CURRENT_TASK], ebx
je .return
mov edi, [dma_slot_ptr]
mov [CURRENT_TASK], ebx
mov [TASK_BASE], edi
jmp @f
.find_next_task:
; \end{Mario79}
call find_next_task
test eax, eax ; the same task -> skip switch
jnz .return
@@:
mov [DONT_SWITCH],byte 1
call do_change_task
.return:
popad
popfd
ret
uglobal
align 4
far_jump:
.offs dd ?
.sel dw ?
context_counter dd ? ;noname & halyavin
next_usage_update dd ?
timer_ticks dd ?
prev_slot dd ?
event_sched dd ?
endg
update_counters:
mov edi, [TASK_BASE]
mov ebx, [edi+TASKDATA.counter_add] ; time stamp counter add
call _rdtsc
sub eax, ebx
add eax, [edi+TASKDATA.counter_sum] ; counter sum
mov [edi+TASKDATA.counter_sum], eax
ret
; Find next task to execute
; result: ebx = number of the selected task
; eax = 1 if the task is the same
; edi = address of the data for the task in ebx
; [0x3000] = ebx and [0x3010] = edi
; corrupts other regs
find_next_task:
mov ebx, [CURRENT_TASK]
mov edi, [TASK_BASE]
mov [prev_slot], ebx
.waiting_for_termination:
.waiting_for_reuse:
.waiting_for_event:
.suspended:
cmp ebx, [TASK_COUNT]
jb @f
mov edi, CURRENT_TASK
xor ebx, ebx
@@:
add edi,0x20
inc ebx
mov al, byte [edi+TASKDATA.state]
test al, al
jz .found
cmp al, 1
jz .suspended
cmp al, 2
jz .suspended
cmp al, 3
je .waiting_for_termination
cmp al, 4
je .waiting_for_termination
cmp al, 9
je .waiting_for_reuse
mov [CURRENT_TASK],ebx
mov [TASK_BASE],edi
cmp al, 5
jne .noevents
call get_event_for_app
test eax, eax
jz .waiting_for_event
mov [event_sched], eax
mov [edi+TASKDATA.state], byte 0
.noevents:
.found:
mov [CURRENT_TASK],ebx
mov [TASK_BASE],edi
call _rdtsc
mov [edi+TASKDATA.counter_add],eax
xor eax, eax
cmp ebx, [prev_slot]
sete al
ret
; in: ebx = TSS selector index
do_change_task:
shl ebx, 3
xor eax, eax
add ebx, tss0
mov [far_jump.sel], bx ; selector
mov [far_jump.offs], eax ; offset
jmp pword [far_jump]
inc [context_counter] ;noname & halyavin
ret
align 4
updatecputimes:
mov eax,[idleuse]
mov [idleusesec],eax
mov [idleuse],dword 0
mov ecx, [TASK_COUNT]
mov edi, TASK_DATA
.newupdate:
mov ebx,[edi+TASKDATA.counter_sum]
mov [edi+TASKDATA.cpu_usage],ebx
mov [edi+TASKDATA.counter_sum],dword 0
add edi,0x20
dec ecx
jnz .newupdate
ret

View File

@ -0,0 +1,111 @@
if ~defined sync_inc
sync_inc_fix:
sync_inc fix sync_inc_fix
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;Synhronization for MenuetOS. ;;
;;Author: Halyavin Andrey, halyavin@land.ru ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;simplest mutex.
macro SimpleMutex name
{
; iglobal
name dd 0
name#.type = 1
; endg
}
macro WaitSimpleMutex name
{
local start_wait,ok
start_wait=$
cli
cmp [name],dword 0
jz ok
sti
call change_task
jmp start_wait
ok=$
push eax
mov eax,dword [TASK_BASE+second_base_address]
mov eax,[eax+TASKDATA.pid]
mov [name],eax
pop eax
sti
}
macro ReleaseSimpleMutex name
{
mov [name],dword 0
}
macro TryWaitSimpleMutex name ;result in eax and in flags
{
local ok,try_end
cmp [name],dword 0
jz ok
xor eax,eax
jmp try_end
ok=$
xor eax,eax
inc eax
try_end=$
}
macro SimpleCriticalSection name
{
; iglobal
name dd 0
dd 0
name#.type=2
; endg
}
macro WaitSimpleCriticalSection name
{
local start_wait,first_wait,inc_counter,end_wait
push eax
mov eax,[TASK_BASE+second_base_address]
mov eax,[eax+TASKDATA.pid]
start_wait=$
cli
cmp [name],dword 0
jz first_wait
cmp [name],eax
jz inc_counter
sti
call change_task
jmp start_wait
first_wait=$
mov [name],eax
mov [name+4],dword 1
jmp end_wait
inc_counter=$
inc dword [name+4]
end_wait=$
sti
pop eax
}
macro ReleaseSimpleCriticalSection name
{
local release_end
dec dword [name+4]
jnz release_end
mov [name],dword 0
release_end=$
}
macro TryWaitSimpleCriticalSection name ;result in eax and in flags
{
local ok,try_end
mov eax,[CURRENT_TASK+second_base_address]
mov eax,[eax+TASKDATA.pid]
cmp [name],eax
jz ok
cmp [name],0
jz ok
xor eax,eax
jmp try_end
ok=$
xor eax,eax
inc eax
try_end=$
}
_cli equ call MEM_HeapLock
_sti equ call MEM_HeapUnLock
end if

View File

@ -0,0 +1,848 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; MenuetOS process management, protected ring3 ;;
;; ;;
;; Distributed under GPL. See file COPYING for details. ;;
;; Copyright 2003 Ville Turjanmaa ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
idtreg:
dw 8*0x41-1
dd idts+8
build_process_gdt_tss_pointer:
mov ecx,tss_data
mov edi,0
setgdtl2:
mov [edi+gdts+ tss0 +0], word tss_step
mov [edi+gdts+ tss0 +2], cx
mov eax,ecx
shr eax,16
mov [edi+gdts+ tss0 +4], al
mov [edi+gdts+ tss0 +7], ah
mov [edi+gdts+ tss0 +5], word 01010000b *256 +11101001b
add ecx,tss_step
add edi,8
cmp edi,8*(max_processes+5)
jbe setgdtl2
ret
build_interrupt_table:
mov edi, idts+8
mov esi, sys_int
mov ecx, 0x40
@@:
mov eax, [esi]
mov [edi], ax ; lower part of offset
mov [edi+2], word os_code ; segment selector
shr eax, 16
mov [edi+4], word 10001110b shl 8 ; interrupt descriptor
mov [edi+6], ax
add esi, 4
add edi, 8
dec ecx
jnz @b
;mov edi,8*0x40+idts+8
mov [edi + 0], word (i40 and ((1 shl 16)-1))
mov [edi + 2], word os_code
mov [edi + 4], word 11101110b*256
mov [edi + 6], word (i40 shr 16)
ret
iglobal
sys_int:
dd e0,debug_exc,e2,e3
dd e4,e5,e6,e7
dd e8,e9,e10,e11
dd e12,e13,page_fault_handler,e15
dd except_16, e17,e18, except_19
times 12 dd unknown_interrupt
dd irq0 , irq_serv.irq_1, p_irq2 , p_irq3 ;irq_serv.irq_3
dd p_irq4 ,irq_serv.irq_5,p_irq6,irq_serv.irq_7
dd irq_serv.irq_8, irq_serv.irq_9, irq_serv.irq_10
dd irq_serv.irq_11,p_irq12,irqD ,p_irq14,p_irq15
times 16 dd unknown_interrupt
dd i40
endg
macro save_ring3_context
{
push ds es
pushad
}
macro restore_ring3_context
{
popad
pop es ds
}
; simply return control to interrupted process
unknown_interrupt:
iret
macro exc_wo_code [num]
{
forward
e#num :
save_ring3_context
mov bl, num
jmp exc_c
}
macro exc_w_code [num]
{
forward
e#num :
add esp, 4
save_ring3_context
mov bl, num
jmp exc_c
}
exc_wo_code 0, 1, 2, 3, 4, 5, 6, 9, 15, 18
exc_w_code 8, 10, 11, 12, 13, 14, 17
exc_c:
mov ax, os_data
mov ds, ax
mov es, ax
; test if debugging
cli
mov eax, [CURRENT_TASK]
shl eax, 8
mov eax, [SLOT_BASE+eax+APPDATA.debugger_slot]
test eax, eax
jnz .debug
sti
; not debuggee => say error and terminate
add esp, 28h
movzx eax, bl
mov [error_interrupt], eax
call show_error_parameters
mov edx, [TASK_BASE]
mov [edx + TASKDATA.state], byte 4
jmp change_task
.debug:
; we are debugged process, notify debugger and suspend ourself
; eax=debugger PID
cld
movzx ecx, bl
push ecx
mov ecx, [TASK_BASE]
push dword [ecx+TASKDATA.pid] ; PID of current process
push 12
pop ecx
push 1 ; 1=exception
call debugger_notify
pop ecx
pop ecx
pop ecx
mov edx, [TASK_BASE]
mov byte [edx+TASKDATA.state], 1 ; suspended
call change_task
restore_ring3_context
iretd
writehex:
pusha
mov edi, [write_error_to]
mov esi, 8
@@:
mov ecx, eax
and ecx, 0xf
mov cl,[ecx+hexletters]
mov [edi],cl
dec edi
shr eax,4
dec esi
jnz @b
popa
ret
iglobal
hexletters db '0123456789ABCDEF'
error_interrupt dd -1
process_error db 'K : Process - forced terminate INT: 00000000',13,10,0
process_pid db 'K : Process - forced terminate PID: 00000000',13,10,0
process_eip db 'K : Process - forced terminate EIP: 00000000',13,10,0
system_error db 'K : Kernel error',13,10,0
endg
uglobal
write_error_to dd 0x0
endg
show_error_parameters:
mov [write_error_to],process_pid+43
mov eax,[CURRENT_TASK]
shl eax, 5
mov eax,[CURRENT_TASK+TASKDATA.pid+eax]
call writehex
mov [write_error_to],process_error+43
mov eax,[error_interrupt]
call writehex
cmp dword [esp+4+4], os_code ; CS
jnz @f
mov esi,system_error
call sys_msg_board_str
@@:
mov eax, [esp+4] ; EIP
mov [write_error_to],process_eip+43
call writehex
mov esi,process_error
call sys_msg_board_str
mov esi,process_pid
call sys_msg_board_str
mov esi,process_eip
call sys_msg_board_str
ret
; irq1 -> hid/keyboard.inc
macro irqh [num]
{
forward
p_irq#num :
save_ring3_context
mov edi, num
jmp irq_c
}
irqh 2,5,7,8,9,10,11
irq_c:
mov ax, os_data
mov ds, ax
mov es, ax
call irqhandler
restore_ring3_context
iret
p_irq6:
save_ring3_context
mov ax, os_data
mov ds, ax
mov es, ax
call fdc_irq
call ready_for_next_irq
restore_ring3_context
iret
p_irq3:
save_ring3_context
mov ax, os_data
mov ds, ax
mov es, ax
cmp [com2_mouse_detected],0
je old_irq3_handler
call check_mouse_data_com2
jmp p_irq3_1
old_irq3_handler:
mov edi,3
call irqhandler
p_irq3_1:
restore_ring3_context
iret
p_irq4:
save_ring3_context
mov ax, os_data
mov ds, ax
mov es, ax
cmp [com1_mouse_detected],0
je old_irq4_handler
call check_mouse_data_com1
jmp p_irq4_1
old_irq4_handler:
mov edi,4
call irqhandler
p_irq4_1:
restore_ring3_context
iret
p_irq12:
save_ring3_context
mov ax, os_data
mov ds, ax
mov es, ax
call check_mouse_data_ps2
restore_ring3_context
iret
p_irq14:
save_ring3_context
mov ax, os_data
mov ds, ax
mov es, ax
call [irq14_func]
call ready_for_next_irq_1
restore_ring3_context
iret
p_irq15:
save_ring3_context
mov ax, os_data
mov ds, ax
mov es, ax
call [irq15_func]
call ready_for_next_irq_1
restore_ring3_context
iret
ready_for_next_irq:
mov [check_idle_semaphore],5
mov al, 0x20
out 0x20, al
ret
ready_for_next_irq_1:
mov [check_idle_semaphore],5
mov al, 0x20
out 0xa0,al
out 0x20, al
ret
irqD:
save_ring3_context
mov ax, os_data
mov ds, ax
mov es, ax
mov dx,0xf0
mov al,0
out dx,al
mov dx,0xa0
mov al,0x20
out dx,al
mov dx,0x20
out dx,al
restore_ring3_context
iret
irqhandler:
push edi
mov esi,edi ; 1
shl esi,6 ; 1
add esi,irq00read ; 1
shl edi,12 ; 1
add edi,IRQ_SAVE
mov ecx,16
mov [check_idle_semaphore],5
irqnewread:
dec ecx
js irqover
mov dx,[esi] ; 2+
cmp dx,0 ; 1
jz irqover
cmp [esi+3],byte 1 ; 2 ; byte read
jne noirqbyte ; 4-11
in al,dx
mov edx,[edi]
cmp edx,4000
je irqfull
mov ebx,edi
add ebx,0x10
add ebx,edx
mov [ebx],al
inc edx
mov [edi],edx
add esi,4
jmp irqnewread
noirqbyte:
cmp [esi+3],byte 2 ; word read
jne noirqword
in ax,dx
mov edx,[edi]
cmp edx,4000
je irqfull
mov ebx,edi
add ebx,0x10
add ebx,edx
mov [ebx],ax
add edx,2
mov [edi],edx
add esi,4
jmp irqnewread
noirqword:
irqfull:
irqover:
mov al,0x20 ; ready for next irq
out 0x20,al
pop ebx
cmp ebx,7
jbe noa0
out 0xa0,al
noa0:
ret
set_application_table_status:
push eax
mov eax,[CURRENT_TASK]
shl eax, 5
add eax,CURRENT_TASK+TASKDATA.pid
mov eax,[eax]
mov [application_table_status],eax
pop eax
ret
clear_application_table_status:
push eax
mov eax,[CURRENT_TASK]
shl eax, 5
add eax,CURRENT_TASK+TASKDATA.pid
mov eax,[eax]
cmp eax,[application_table_status]
jne apptsl1
mov [application_table_status],0
apptsl1:
pop eax
ret
sys_resize_app_memory:
; eax = 1 - resize
; ebx = new amount of memory
cmp eax,1
jne .no_application_mem_resize
stdcall new_mem_resize, ebx
mov [esp+36], eax
ret
.no_application_mem_resize:
ret
sys_threads:
; eax=1 create thread
;
; ebx=thread start
; ecx=thread stack value
;
; on return : eax = pid
jmp new_sys_threads
iglobal
process_terminating db 'K : Process - terminating',13,10,0
process_terminated db 'K : Process - done',13,10,0
msg_obj_destroy db 'K : destroy app object',13,10,0
endg
; param
; esi= slot
terminate: ; terminate application
.slot equ esp ;locals
push esi ;save .slot
shl esi, 8
cmp [SLOT_BASE+esi+APPDATA.dir_table], 0
jne @F
add esp, 4
ret
@@:
mov esi,process_terminating
call sys_msg_board_str
@@:
cli
cmp [application_table_status],0
je term9
sti
call change_task
jmp @b
term9:
call set_application_table_status
mov esi, [.slot]
shl esi,8
add esi, SLOT_BASE+APP_OBJ_OFFSET
@@:
mov eax, [esi+APPOBJ.fd]
test eax, eax
jz @F
cmp eax, esi
je @F
push esi
call [eax+APPOBJ.destroy]
mov esi, msg_obj_destroy
call sys_msg_board_str
pop esi
jmp @B
@@:
mov eax, [.slot]
shl eax, 8
mov eax,[SLOT_BASE+eax+APPDATA.dir_table]
stdcall destroy_app_space, eax
mov esi, [.slot]
cmp [fpu_owner],esi ; if user fpu last -> fpu user = 1
jne @F
mov [fpu_owner],1
mov eax, [256+SLOT_BASE+APPDATA.fpu_state]
clts
bt [cpu_caps], CAPS_SSE
jnc .no_SSE
fxrstor [eax]
jmp @F
.no_SSE:
fnclex
frstor [eax]
@@:
mov [KEY_COUNT],byte 0 ; empty keyboard buffer
mov [BTN_COUNT],byte 0 ; empty button buffer
; remove defined hotkeys
mov eax, hotkey_list
.loop:
cmp [eax+8], esi
jnz .cont
mov ecx, [eax]
jecxz @f
push dword [eax+12]
pop dword [ecx+12]
@@:
mov ecx, [eax+12]
push dword [eax]
pop dword [ecx]
xor ecx, ecx
mov [eax], ecx
mov [eax+4], ecx
mov [eax+8], ecx
mov [eax+12], ecx
.cont:
add eax, 16
cmp eax, hotkey_list+256*16
jb .loop
; remove hotkeys in buffer
mov eax, hotkey_buffer
.loop2:
cmp [eax], esi
jnz .cont2
and dword [eax+4], 0
and dword [eax], 0
.cont2:
add eax, 8
cmp eax, hotkey_buffer+120*8
jb .loop2
mov ecx,esi ; remove buttons
bnewba2:
mov edi,[BTN_ADDR]
mov eax,edi
cld
movzx ebx,word [edi]
inc bx
bnewba:
dec bx
jz bnmba
add eax,0x10
cmp cx,[eax]
jnz bnewba
pusha
mov ecx,ebx
inc ecx
shl ecx,4
mov ebx,eax
add eax,0x10
call memmove
dec dword [edi]
popa
jmp bnewba2
bnmba:
pusha ; save window coordinates for window restoring
cld
shl esi,5
add esi,window_data
mov eax,[esi+WDATA.box.left]
mov [dlx],eax
add eax,[esi+WDATA.box.width]
mov [dlxe],eax
mov eax,[esi+WDATA.box.top]
mov [dly],eax
add eax,[esi+WDATA.box.height]
mov [dlye],eax
xor eax, eax
mov [esi+WDATA.box.left],eax
mov [esi+WDATA.box.width],eax
mov [esi+WDATA.box.top],eax
mov [esi+WDATA.box.height],eax
mov [esi+WDATA.cl_workarea],eax
mov [esi+WDATA.cl_titlebar],eax
mov [esi+WDATA.cl_frames],eax
mov dword [esi+WDATA.reserved],eax ; clear all flags: wstate, redraw, wdrawn
lea edi, [esi-window_data+draw_data]
mov ecx,32/4
rep stosd
popa
; debuggee test
pushad
mov edi, esi
shl edi, 5
mov eax, [SLOT_BASE+edi*8+APPDATA.debugger_slot]
test eax, eax
jz .nodebug
push 8
pop ecx
push dword [CURRENT_TASK+edi+TASKDATA.pid] ; PID
push 2
call debugger_notify
pop ecx
pop ecx
.nodebug:
popad
mov ebx, [.slot]
shl ebx, 8
mov ebx,[SLOT_BASE+ebx+APPDATA.pl0_stack]
stdcall kernel_free, ebx
mov edi, [.slot]
shl edi,8
add edi,SLOT_BASE
mov eax, 0x20202020
stosd
stosd
stosd
mov ecx,244/4
xor eax, eax
rep stosd
; activate window
movzx eax, word [WIN_STACK + esi*2]
cmp eax, [TASK_COUNT]
jne .dont_activate
pushad
.check_next_window:
dec eax
cmp eax, 1
jbe .nothing_to_activate
lea esi, [WIN_POS+eax*2]
movzx edi, word [esi] ; edi = process
shl edi, 5
cmp [CURRENT_TASK + edi + TASKDATA.state], byte 9 ; skip dead slots
je .check_next_window
add edi, window_data
; \begin{diamond}[19.09.2006]
; skip minimized windows
test [edi + WDATA.fl_wstate], WSTATE_MINIMIZED
jnz .check_next_window
; \end{diamond}
call waredraw
.nothing_to_activate:
popad
.dont_activate:
push esi ; remove hd1 & cd & flp reservation
shl esi, 5
mov esi, [esi+CURRENT_TASK+TASKDATA.pid]
cmp [hd1_status], esi
jnz @f
call free_hd_channel
mov [hd1_status], 0
@@:
cmp [cd_status], esi
jnz @f
call free_cd_channel
mov [cd_status], 0
@@:
cmp [flp_status], esi
jnz @f
mov [flp_status], 0
@@:
pop esi
pusha ; remove all irq reservations
mov eax,esi
shl eax, 5
mov eax,[eax+CURRENT_TASK+TASKDATA.pid]
mov edi,irq_owner
mov ecx,16
newirqfree:
scasd
jne nofreeirq
mov [edi-4],dword 0
nofreeirq:
loop newirqfree
popa
pusha ; remove all port reservations
mov edx,esi
shl edx, 5
add edx,CURRENT_TASK
mov edx,[edx+TASKDATA.pid]
rmpr0:
mov esi,[RESERVED_PORTS]
cmp esi,0
je rmpr9
rmpr3:
mov edi,esi
shl edi,4
add edi,RESERVED_PORTS
cmp edx,[edi]
je rmpr4
dec esi
jnz rmpr3
jmp rmpr9
rmpr4:
mov ecx,256
sub ecx,esi
shl ecx,4
mov esi,edi
add esi,16
cld
rep movsb
dec dword [RESERVED_PORTS]
jmp rmpr0
rmpr9:
popa
mov edi,esi ; do not run this process slot
shl edi, 5
mov [edi+CURRENT_TASK + TASKDATA.state],byte 9
; debugger test - terminate all debuggees
mov eax, 2
mov ecx, SLOT_BASE+2*0x100+APPDATA.debugger_slot
.xd0:
cmp eax, [TASK_COUNT]
ja .xd1
cmp dword [ecx], esi
jnz @f
and dword [ecx], 0
pushad
xchg eax, ebx
mov eax, 2
call sys_system
popad
@@:
inc eax
add ecx, 0x100
jmp .xd0
.xd1:
; call systest
sti ; .. and life goes on
mov eax, [dlx]
mov ebx, [dly]
mov ecx, [dlxe]
mov edx, [dlye]
call [calculatescreen]
xor eax, eax
xor esi, esi
call redrawscreen
mov [MOUSE_BACKGROUND],byte 0 ; no mouse background
mov [DONT_DRAW_MOUSE],byte 0 ; draw mouse
mov [application_table_status],0
mov esi,process_terminated
call sys_msg_board_str
add esp, 4
ret
restore .slot
iglobal
boot_sched_1 db 'Building gdt tss pointer',0
boot_sched_2 db 'Building IDT table',0
endg
build_scheduler:
mov esi,boot_sched_1
call boot_log
call build_process_gdt_tss_pointer
mov esi,boot_sched_2
call boot_log
call build_interrupt_table
ret

View File

@ -0,0 +1,217 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; SYSTEM CALL ENTRY ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
align 32
i40:
push ds es
pushad
cld
mov ax,word os_data
mov ds,ax
mov es,ax
; load all registers in crossed order
mov eax, ebx
mov ebx, ecx
mov ecx, edx
mov edx, esi
mov esi, edi
mov edi, [esp+28]
; enable interupts - a task switch or an IRQ _CAN_ interrupt i40 handler
sti
push eax
and edi,0xff
call dword [servetable+edi*4]
pop eax
; cli
popad
pop es ds
iretd
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; SYSENTER ENTRY ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
uglobal
times 100 db ?
sysenter_stack:
endg
align 32
SYSENTER_VAR equ 0
sysenter_entry:
; Íàñòðàèâàåì ñòåê
cli
push eax
mov eax, [ss:CURRENT_TASK]
shl eax, 8
mov eax, [ss:SLOT_BASE + eax + APPDATA.pl0_stack]
lea esp, [ss:eax + RING0_STACK_SIZE] ; configure ESP
mov eax, [ss:sysenter_stack - 4] ; eax - original eax, from app
sti
;------------------
push ds es
pushad
cld
mov ax, word os_data
mov ds, ax
mov es, ax
mov eax, ebx
mov ebx, ecx
mov ecx, edx
mov edx, esi
mov esi, edi
mov edi, [esp + 28]
push eax
and edi, 0xff
call dword [servetable + edi * 4]
pop eax
popad
pop es ds
;------------------
mov edx, [SYSENTER_VAR] ; eip
mov ecx, [SYSENTER_VAR + 4] ; esp
sysexit
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; SYSCALL ENTRY ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
align 32
syscall_entry:
cli
xchg ecx, [esp]
mov [SYSENTER_VAR + 4], esp
mov [ss:sysenter_stack - 4], eax
mov eax, [ss:CURRENT_TASK]
shl eax, 8
mov eax, [ss:SLOT_BASE + eax + APPDATA.pl0_stack]
lea esp, [ss:eax + RING0_STACK_SIZE] ; configure ESP
mov eax, [ss:sysenter_stack - 4] ; eax - original eax, from app
sti
;------------------
push ds es
pushad
cld
mov ax, word os_data
mov ds, ax
mov es, ax
mov eax, ebx
mov ebx, ecx
mov ecx, edx
mov edx, esi
mov esi, edi
mov edi, [esp + 28]
push eax
and edi, 0xff
call dword [servetable + edi * 4]
pop eax
popad
pop es ds
;------------------
mov esp, [SYSENTER_VAR + 4]
xchg ecx, [esp]
sysret
iglobal
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; SYSTEM FUNCTIONS TABLE ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
align 4
servetable:
dd sys_drawwindow ; 0-DrawWindow
dd syscall_setpixel ; 1-SetPixel
dd sys_getkey ; 2-GetKey
dd sys_clock ; 3-GetTime
dd syscall_writetext ; 4-WriteText
dd delay_hs ; 5-DelayHs
dd syscall_openramdiskfile ; 6-OpenRamdiskFile
dd syscall_putimage ; 7-PutImage
dd sys_button ; 8-DefineButton
dd sys_cpuusage ; 9-GetProcessInfo
dd sys_waitforevent ; 10-WaitForEvent
dd sys_getevent ; 11-CheckForEvent
dd sys_redrawstat ; 12-BeginDraw and EndDraw
dd syscall_drawrect ; 13-DrawRect
dd syscall_getscreensize ; 14-GetScreenSize
dd sys_background ; 15-bgr
dd sys_cachetodiskette ; 16-FlushFloppyCache
dd sys_getbutton ; 17-GetButton
dd sys_system ; 18-System Services
dd paleholder;undefined_syscall ; 19-reserved
dd sys_midi ; 20-ResetMidi and OutputMidi
dd sys_setup ; 21-SetMidiBase,SetKeymap,SetShiftKeymap,.
dd sys_settime ; 22-setting date,time,clock and alarm-clock
dd sys_wait_event_timeout ; 23-TimeOutWaitForEvent
dd syscall_cdaudio ; 24-PlayCdTrack,StopCd and GetCdPlaylist
dd sys_sb16 ; 25-SetSb16
dd sys_getsetup ; 26-GetMidiBase,GetKeymap,GetShiftKeymap,.
dd undefined_syscall ; 27-reserved
dd sys_sb16II ; 28-SetSb16
dd sys_date ; 29-GetDate
dd undefined_syscall ; 30-reserved
dd undefined_syscall ; 31-reserved
dd syscall_delramdiskfile ; 32-DelRamdiskFile
dd syscall_writeramdiskfile; 33-WriteRamdiskFile
dd undefined_syscall ; 34-reserved
dd syscall_getpixel ; 35-GetPixel
dd syscall_readstring ; 36-ReadString (not yet ready)
dd readmousepos ; 37-GetMousePosition_ScreenRelative,.
dd syscall_drawline ; 38-DrawLine
dd sys_getbackground ; 39-GetBackgroundSize,ReadBgrData,.
dd set_app_param ; 40-WantEvents
dd syscall_getirqowner ; 41-GetIrqOwner
dd get_irq_data ; 42-ReadIrqData
dd sys_outport ; 43-SendDeviceData
dd sys_programirq ; 44-ProgramIrqs
dd reserve_free_irq ; 45-ReserveIrq and FreeIrq
dd syscall_reserveportarea ; 46-ReservePortArea and FreePortArea
dd display_number ; 47-WriteNum
dd display_settings ; 48-SetRedrawType and SetButtonType
dd sys_apm ; 49-Advanced Power Management (APM)
dd random_shaped_window ; 50-Window shape & scale
dd syscall_threads ; 51-Threads
dd stack_driver_stat ; 52-Stack driver status
dd socket ; 53-Socket interface
dd user_events ; 54-User events
dd sound_interface ; 55-Sound interface
dd undefined_syscall ; 56-reserved
dd undefined_syscall ; 57-reserved
dd file_system ; 58-Common file system interface
dd undefined_syscall ; 59-reserved
dd sys_IPC ; 60-Inter Process Communication
dd sys_gs ; 61-Direct graphics access
dd sys_pci ; 62-PCI functions
dd sys_msg_board ; 63-System message board
dd sys_resize_app_memory ; 64-Resize application memory usage
dd syscall_putimage_palette; 65-PutImagePalette
dd sys_process_def ; 66-Process definitions - keyboard
dd sys_window_move ; 67-Window move or resize
dd new_services ; 68-Some internal services
dd sys_debug_services ; 69-Debug
dd file_system_lfn ; 70-Common file system interface, version 2
dd syscall_windowsettings ; 71-Window settings
times 255 - ( ($-servetable) /4 ) dd undefined_syscall
dd sys_end ; -1-end application
endg

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,135 @@
;**************************************************
;* ПОИСК МЫШИ ПО ПОСЛЕДОВАТЕЛЬНЫМ ПОРТАМ *
;* Процедура подготавливает глобальные переменные *
;* COMPortNum и COMPortBaseAddr для подпрограммы *
;* установки обработчика прерывания *
;**************************************************
; Автор исходного текста Кулаков Владимир Геннадьевич.
; Адаптация и доработка Mario79
Detect_COM_Mouse:
pusha
call MSMouseSearch
cmp AL,'M'
jne @f
mov [com1_mouse_detected],1
pusha
mov eax,4
shl eax,2
mov [irq_owner+eax],byte 1
inc dword [0x2d0000]
mov edi,[0x2d0000]
shl edi,4
mov [0x2d0000+edi+0],dword 1
mov [0x2d0000+edi+4],dword 0x3f0
mov [0x2d0000+edi+8],dword 0x3ff
popa
mov esi,boot_setmouse_type+22
call boot_log
@@:
sub [COMPortBaseAddr],100h
call MSMouseSearch
cmp AL,'M'
jne @f
mov [com2_mouse_detected],1
pusha
mov eax,3
shl eax,2
mov [irq_owner+eax],byte 1
inc dword [0x2d0000]
mov edi,[0x2d0000]
shl edi,4
mov [0x2d0000+edi+0],dword 1
mov [0x2d0000+edi+4],dword 0x2f0
mov [0x2d0000+edi+8],dword 0x2ff
popa
mov esi,boot_setmouse_type+44
call boot_log
@@:
popa
jmp end_detecting_mouse
MSMouseSearch:
; ПОИСК МЫШИ ЧЕРЕЗ COM-ПОРТЫ
MouseSearch:
; Устанавливаем скорость
; приема/передачи 1200 бод
mov DX,[COMPortBaseAddr]
add DX,3
in AL,DX
or AL,80h ;установить бит DLAB
out DX,AL
mov DX,[COMPortBaseAddr]
mov AL,60h ;1200 бод
out DX,AL
inc DX
mov AL,0
out DX,AL
; Установить длину слова 7 бит, 1 стоповый бит,
; четность не контролировать
mov DX,[COMPortBaseAddr]
add DX,3
mov AL,00000010b
out DX,AL
; Запретить все прерывания
mov DX,[COMPortBaseAddr]
inc DX
mov AL,0
out DX,AL
; Проверить, что устройство подключено и является
; мышью типа MSMouse
; Отключить питание мыши и прерывания
mov DX,[COMPortBaseAddr]
add DX,4 ;регистр управления модемом
mov AL,0 ;сбросить DTR, RTS и OUT2
out DX,AL
; Ожидать 5 "тиков" (0,2 с)
mov ecx,0xffff
dT_1:
dec ecx
cmp ecx,0
jne dT_1
mov ecx,0xffff
; Включить питание мыши
mov AL,11b ;установить DTR и RTS
out DX,AL
; Очистить регистр данных
mov DX,[COMPortBaseAddr]
in AL,DX
; Цикл опроса порта
WaitData:
; Ожидать еще 10 "тиков"
dec ecx
cmp ecx,0
je NoMouse
; Проверить наличие идентификационного байта
mov DX,[COMPortBaseAddr]
add DX,5
in AL,DX
test AL,1 ;Данные готовы?
jz WaitData
; Ввести данные
mov DX,[COMPortBaseAddr]
in AL,DX
NoMouse:
ret
iglobal
COMPortBaseAddr dw 3F8h
;COMPortNum dw 0
endg
iglobal
boot_setmouse_type db 'Detected - PS2 mouse',0
db 'Detected - COM1 mouse',0
db 'Detected - COM2 mouse',0
endg
end_detecting_mouse:

View File

@ -0,0 +1,20 @@
;***************************************************
; предварительная очистка области таблицы
; поиск и занесение в таблицу приводов FDD
; автор Mario79
;***************************************************
xor eax,eax
mov edi,0x40000
mov ecx,16384
cld
rep stosd
mov al,0x10
out 0x70,al
mov cx,0xff
wait_cmos:
dec cx
cmp cx,0
jne wait_cmos
in al,0x71
mov [0x40000],al

View File

@ -0,0 +1,374 @@
;******************************************************
; поиск приводов HDD и CD
; автор исходного текста Кулаков Владимир Геннадьевич.
; адаптация и доработка Mario79
;******************************************************
;****************************************************
;* ПОИСК HDD и CD *
;****************************************************
FindHDD:
mov [ChannelNumber],1
mov [DiskNumber],0
call FindHDD_3
; mov ax,[Sector512+176]
; mov [0x40006],ax
; mov ax,[Sector512+126]
; mov [0x40008],ax
; mov ax,[Sector512+128]
; mov [0x40008],ax
mov [DiskNumber],1
call FindHDD_3
; mov al,[Sector512+176]
; mov [0x40007],al
inc [ChannelNumber]
mov [DiskNumber],0
call FindHDD_3
; mov al,[Sector512+176]
; mov [0x40008],al
mov [DiskNumber],1
call FindHDD_1
; mov al,[Sector512+176]
; mov [0x40009],al
jmp EndFindHDD
FindHDD_1:
call ReadHDD_ID
cmp [DevErrorCode],0
jne FindHDD_2
cmp [Sector512+6],word 16
ja FindHDD_2
cmp [Sector512+12],word 255
ja FindHDD_2
inc byte [0x40001]
jmp FindHDD_2_2
FindHDD_2:
call DeviceReset
cmp [DevErrorCode],0
jne FindHDD_2_2
call ReadCD_ID
cmp [DevErrorCode],0
jne FindHDD_2_2
inc byte [0x40001]
inc byte [0x40001]
FindHDD_2_2:
ret
FindHDD_3:
call FindHDD_1
shl byte [0x40001],2
ret
; Адрес считываемого сектора в режиме LBA
SectorAddress DD ?
;*************************************************
;* ЧТЕНИЕ ИДЕНТИФИКАТОРА ЖЕСТКОГО ДИСКА *
;* Входные параметры передаются через глобальные *
;* переменные: *
;* ChannelNumber - номер канала (1 или 2); *
;* DiskNumber - номер диска на канале (0 или 1). *
;* Идентификационный блок данных считывается *
;* в массив Sector512. *
;*************************************************
ReadHDD_ID:
; Задать режим CHS
mov [ATAAddressMode],0
; Послать команду идентификации устройства
mov [ATAFeatures],0
mov [ATAHead],0
mov [ATACommand],0ECh
call SendCommandToHDD
cmp [DevErrorCode],0 ;проверить код ошибки
jne @@End ;закончить, сохранив код ошибки
mov DX,[ATABasePortAddr]
add DX,7 ;адрес регистра состояния
mov ecx,0xffff
@@WaitCompleet:
; Проверить время выполнения команды
dec ecx
cmp ecx,0
je @@Error1 ;ошибка тайм-аута
; Проверить готовность
in AL,DX
test AL,80h ;состояние сигнала BSY
jnz @@WaitCompleet
test AL,1 ;состояние сигнала ERR
jnz @@Error6
test AL,08h ;состояние сигнала DRQ
jz @@WaitCompleet
; Принять блок данных от контроллера
; mov AX,DS
; mov ES,AX
mov EDI,Sector512 ;offset Sector512
mov DX,[ATABasePortAddr] ;регистр данных
mov CX,256 ;число считываемых слов
rep insw ;принять блок данных
jmp @@End
; Записать код ошибки
@@Error1:
mov [DevErrorCode],1
jmp @@End
@@Error6:
mov [DevErrorCode],6
@@End: ret
; Стандартные базовые адреса каналов 1 и 2
StandardATABases DW 1F0h, 170h
; Номер канала
ChannelNumber DW ?
; Номер диска
DiskNumber DB ?
; Базовый адрес группы портов контроллера ATA
ATABasePortAddr DW ?
; Параметры ATA-команды
ATAFeatures DB ? ;особенности
ATASectorCount DB ? ;количество обрабатываемых секторов
ATASectorNumber DB ? ;номер начального сектора
ATACylinder DW ? ;номер начального цилиндра
ATAHead DB ? ;номер начальной головки
ATAAddressMode DB ? ;режим адресации (0 - CHS, 1 - LBA)
ATACommand DB ? ;код команды, подлежащей выполнению
; Код ошибки (0 - нет ошибок, 1 - превышен допустимый
; интервал ожидания, 2 - неверный код режима адресации,
; 3 - неверный номер канала, 4 - неверный номер диска,
; 5 - неверный номер головки, 6 - ошибка при выполнении
; команды)
DevErrorCode DB ?
;****************************************************
;* ПОСЛАТЬ КОМАНДУ ЗАДАННОМУ ДИСКУ *
;* Входные параметры передаются через глобальные *
;* переменные: *
;* ChannelNumber - номер канала (1 или 2); *
;* DiskNumber - номер диска (0 или 1); *
;* ATAFeatures - "особенности"; *
;* ATASectorCount - количество секторов; *
;* ATASectorNumber - номер начального сектора; *
;* ATACylinder - номер начального цилиндра; *
;* ATAHead - номер начальной головки; *
;* ATAAddressMode - режим адресации (0-CHS, 1-LBA); *
;* ATACommand - код команды. *
;* После успешного выполнения функции: *
;* в ATABasePortAddr - базовый адрес HDD; *
;* в DevErrorCode - ноль. *
;* При возникновении ошибки в DevErrorCode будет *
;* возвращен код ошибки. *
;****************************************************
SendCommandToHDD:
; Проверить значение кода режима
cmp [ATAAddressMode],1
ja @@Err2
; Проверить корректность номера канала
mov BX,[ChannelNumber]
cmp BX,1
jb @@Err3
cmp BX,2
ja @@Err3
; Установить базовый адрес
dec BX
shl BX,1
movzx ebx,bx
mov AX,[ebx+StandardATABases]
mov [ATABasePortAddr],AX
; Ожидание готовности HDD к приему команды
; Выбрать нужный диск
mov DX,[ATABasePortAddr]
add DX,6 ;адрес регистра головок
mov AL,[DiskNumber]
cmp AL,1 ;проверить номера диска
ja @@Err4
shl AL,4
or AL,10100000b
out DX,AL
; Ожидать, пока диск не будет готов
inc DX
mov ecx,0xfff
; mov eax,[timer_ticks]
; mov [TickCounter_1],eax
@@WaitHDReady:
; Проверить время ожидания
dec ecx
cmp ecx,0
je @@Err1
; mov eax,[timer_ticks]
; sub eax,[TickCounter_1]
; cmp eax,300 ;ожидать 300 тиков
; ja @@Err1 ;ошибка тайм-аута
; Прочитать регистр состояния
in AL,DX
; Проверить состояние сигнала BSY
test AL,80h
jnz @@WaitHDReady
; Проверить состояние сигнала DRQ
test AL,08h
jnz @@WaitHDReady
; Загрузить команду в регистры контроллера
cli
mov DX,[ATABasePortAddr]
inc DX ;регистр "особенностей"
mov AL,[ATAFeatures]
out DX,AL
inc DX ;счетчик секторов
mov AL,[ATASectorCount]
out DX,AL
inc DX ;регистр номера сектора
mov AL,[ATASectorNumber]
out DX,AL
inc DX ;номер цилиндра (младший байт)
mov AX,[ATACylinder]
out DX,AL
inc DX ;номер цилиндра (старший байт)
mov AL,AH
out DX,AL
inc DX ;номер головки/номер диска
mov AL,[DiskNumber]
shl AL,4
cmp [ATAHead],0Fh ;проверить номер головки
ja @@Err5
or AL,[ATAHead]
or AL,10100000b
mov AH,[ATAAddressMode]
shl AH,6
or AL,AH
out DX,AL
; Послать команду
mov AL,[ATACommand]
inc DX ;регистр команд
out DX,AL
sti
; Сбросить признак ошибки
mov [DevErrorCode],0
jmp @@End_2
; Записать код ошибки
@@Err1: mov [DevErrorCode],1
jmp @@End_2
@@Err2: mov [DevErrorCode],2
jmp @@End_2
@@Err3: mov [DevErrorCode],3
jmp @@End_2
@@Err4: mov [DevErrorCode],4
jmp @@End_2
@@Err5: mov [DevErrorCode],5
; Завершение работы программы
@@End_2:
ret
;*************************************************
;* ЧТЕНИЕ ИДЕНТИФИКАТОРА УСТРОЙСТВА ATAPI *
;* Входные параметры передаются через глобальные *
;* перменные: *
;* ChannelNumber - номер канала; *
;* DiskNumber - номер диска на канале. *
;* Идентификационный блок данных считывается *
;* в массив Sector512. *
;*************************************************
ReadCD_ID:
; Задать режим CHS
mov [ATAAddressMode],0
; Послать команду идентификации устройства
mov [ATAFeatures],0
mov [ATASectorCount],0
mov [ATASectorNumber],0
mov [ATACylinder],0
mov [ATAHead],0
mov [ATACommand],0A1h
call SendCommandToHDD
cmp [DevErrorCode],0 ;проверить код ошибки
jne @@End_1 ;закончить, сохранив код ошибки
; Ожидать готовность данных HDD
mov DX,[ATABasePortAddr]
add DX,7 ;порт 1х7h
mov ecx,0xffff
@@WaitCompleet_1:
; Проверить время
dec ecx
cmp ecx,0
je @@Error1_1 ;ошибка тайм-аута
; Проверить готовность
in AL,DX
test AL,80h ;состояние сигнала BSY
jnz @@WaitCompleet_1
test AL,1 ;состояние сигнала ERR
jnz @@Error6_1
test AL,08h ;состояние сигнала DRQ
jz @@WaitCompleet_1
; Принять блок данных от контроллера
; mov AX,DS
; mov ES,AX
mov EDI,Sector512 ;offset Sector512
mov DX,[ATABasePortAddr] ;порт 1x0h
mov CX,256 ;число считываемых слов
rep insw
jmp @@End_1
; Записать код ошибки
@@Error1_1:
mov [DevErrorCode],1
jmp @@End_1
@@Error6_1:
mov [DevErrorCode],6
@@End_1:
ret
;*************************************************
;* СБРОС УСТРОЙСТВА *
;* Входные параметры передаются через глобальные *
;* переменные: *
;* ChannelNumber - номер канала (1 или 2); *
;* DiskNumber - номер диска (0 или 1). *
;*************************************************
DeviceReset:
; Проверить корректность номера канала
mov BX,[ChannelNumber]
cmp BX,1
jb @@Err3_2
cmp BX,2
ja @@Err3_2
; Установить базовый адрес
dec BX
shl BX,1
movzx ebx,bx
mov DX,[ebx+StandardATABases]
mov [ATABasePortAddr],DX
; Выбрать нужный диск
add DX,6 ;адрес регистра головок
mov AL,[DiskNumber]
cmp AL,1 ;проверить номера диска
ja @@Err4_2
shl AL,4
or AL,10100000b
out DX,AL
; Послать команду "Сброс"
mov AL,08h
inc DX ;регистр команд
out DX,AL
mov ecx,0xffff
@@WaitHDReady_1:
; Проверить время ожидания
dec ecx
cmp ecx,0
je @@Err1_2 ;ошибка тайм-аута
; Прочитать регистр состояния
in AL,DX
; Проверить состояние сигнала BSY
test AL,80h
jnz @@WaitHDReady_1
; Сбросить признак ошибки
mov [DevErrorCode],0
jmp @@End_3
; Обработка ошибок
@@Err1_2: mov [DevErrorCode],1
jmp @@End_3
@@Err3_2: mov [DevErrorCode],3
jmp @@End_3
@@Err4_2: mov [DevErrorCode],4
; Записать код ошибки
@@End_3:
ret
EndFindHDD:

View File

@ -0,0 +1,4 @@
include 'dev_fd.inc'
include 'dev_hdcd.inc'
include 'sear_par.inc'

View File

@ -0,0 +1,69 @@
MouseSearch_PS2:
pusha
mov bl, 0xAD
call kb_cmd
mov bl,0xa8 ; enable mouse cmd
call kb_cmd
cmp ah,1
je @@DataInputError
mov bl,0xd4 ; for mouse
call kb_cmd
cmp ah,1
je @@DataInputError
mov al,0xeb ;
call kb_write
cmp ah,1
je @@DataInputError
call kb_read ; Acknowledge
call kb_read
mov [ps2_mouse_detected],0
test al,18h
jz @f
mov [ps2_mouse_detected],1
@@:
call kb_read ;
call kb_read ;
mov bl,0x20 ; get command byte
call kb_cmd
cmp ah,1
je @@DataInputError
call kb_read
cmp ah,1
je @@DataInputError
or al,3 ; enable interrupt
mov bl,0x60 ; write command
push eax
call kb_cmd
pop eax
call kb_write
cmp ah,1
je @@DataInputError
mov bl,0xd4 ; for mouse
call kb_cmd
cmp ah,1
je @@DataInputError
mov al,0xf4 ; enable mouse device
call kb_write
cmp ah,1
je @@DataInputError
call kb_read ; read status return
cmp ah,1
je @@DataInputError
cmp AL,0FAh
jnz @@DataInputError ;íåò ïîäòâåðæäåíèÿ
@@DataInputError:
cmp [ps2_mouse_detected],0
je @f
mov esi,boot_setmouse_type
call boot_log
@@:
mov bl, 0xAE
call kb_cmd
popa

View File

@ -0,0 +1,118 @@
;****************************************************
; ïîèñê ëîãè÷åñêèõ äèñêîâ íà îáíàðóæåííûõ HDD
; è çàíåñåíèå äàííûõ â îáëàñòü òàáëèöû
; àâòîð Mario79
;****************************************************
mov [transfer_adress],0x4000a
search_partitions_ide0:
test [0x40001],byte 0x40
jz search_partitions_ide1
mov [hdbase],0x1f0
mov [hdid],0x0
mov [hdpos],1
mov [fat32part],1
search_partitions_ide0_1:
call set_FAT32_variables
cmp [problem_partition],0
jne search_partitions_ide1
inc byte [0x40002]
call partition_data_transfer
add [transfer_adress],100
inc [fat32part]
jmp search_partitions_ide0_1
search_partitions_ide1:
test [0x40001],byte 0x10
jz search_partitions_ide2
mov [hdbase],0x1f0
mov [hdid],0x10
mov [hdpos],2
mov [fat32part],1
search_partitions_ide1_1:
call set_FAT32_variables
cmp [problem_partition],0
jne search_partitions_ide2
inc byte [0x40003]
call partition_data_transfer
add [transfer_adress],100
inc [fat32part]
jmp search_partitions_ide1_1
search_partitions_ide2:
test [0x40001],byte 0x4
jz search_partitions_ide3
mov [hdbase],0x170
mov [hdid],0x0
mov [hdpos],3
mov [fat32part],1
search_partitions_ide2_1:
call set_FAT32_variables
cmp [problem_partition],0
jne search_partitions_ide3
inc byte [0x40004]
call partition_data_transfer
add [transfer_adress],100
inc [fat32part]
jmp search_partitions_ide2_1
search_partitions_ide3:
test [0x40001],byte 0x1
jz end_search_partitions_ide
mov [hdbase],0x170
mov [hdid],0x10
mov [hdpos],4
mov [fat32part],1
search_partitions_ide3_1:
call set_FAT32_variables
cmp [problem_partition],0
jne end_search_partitions_ide
inc byte [0x40005]
call partition_data_transfer
add [transfer_adress],100
inc [fat32part]
jmp search_partitions_ide3_1
partition_data_transfer:
mov edi,[transfer_adress]
mov esi,PARTITION_START
xor ecx,ecx
mov cx,69 ;100
rep movsb
ret
transfer_adress dd 0
partition_data_transfer_1:
cli
push edi
mov edi,PARTITION_START
mov esi,[transfer_adress]
xor ecx,ecx
mov cx,69 ;100
rep movsb
pop edi
sti
ret
end_search_partitions_ide:
;PARTITION_START dd 0x3f
;PARTITION_END dd 0
;SECTORS_PER_FAT dd 0x1f3a
;NUMBER_OF_FATS dd 0x2
;SECTORS_PER_CLUSTER dd 0x8
;BYTES_PER_SECTOR dd 0x200 ; Note: if BPS <> 512 need lots of changes
;ROOT_CLUSTER dd 2 ; first rootdir cluster
;FAT_START dd 0 ; start of fat table
;ROOT_START dd 0 ; start of rootdir (only fat16)
;ROOT_SECTORS dd 0 ; count of rootdir sectors (only fat16)
;DATA_START dd 0 ; start of data area (=first cluster 2)
;LAST_CLUSTER dd 0 ; last availabe cluster
;ADR_FSINFO dd 0 ; used only by fat32
;
;fatRESERVED dd 0x0FFFFFF6
;fatBAD dd 0x0FFFFFF7
;fatEND dd 0x0FFFFFF8
;fatMASK dd 0x0FFFFFFF
;
;fat_type db 0 ; 0=none, 16=fat16, 32=fat32

View File

@ -0,0 +1,518 @@
--------p-155300-----------------------------
INT 15 - Advanced Power Management v1.0+ - INSTALLATION CHECK
AX = 5300h
BX = device ID of system BIOS (0000h)
Return: CF clear if successful
AH = major version (BCD)
AL = minor version (BCD)
BX = 504Dh ("PM")
CX = flags (see #00472)
CF set on error
AH = error code (06h,09h,86h) (see #00473)
BUG: early versions of the Award Modular BIOS with built-in APM support
reportedly do not set BX on return
Bitfields for APM flags:
Bit(s) Description (Table 00472)
0 16-bit protected mode interface supported
1 32-bit protected mode interface supported
2 CPU idle call reduces processor speed
3 BIOS power management disabled
4 BIOS power management disengaged (APM v1.1)
5-7 reserved
(Table 00473)
Values for APM error code:
01h power management functionality disabled
02h interface connection already in effect
03h interface not connected
04h real-mode interface not connected
05h 16-bit protected-mode interface already connected
06h 16-bit protected-mode interface not supported
07h 32-bit protected-mode interface already connected
08h 32-bit protected-mode interface not supported
09h unrecognized device ID
0Ah invalid parameter value in CX
0Bh (APM v1.1) interface not engaged
0Ch (APM v1.2) function not supported
0Dh (APM v1.2) Resume Timer disabled
0Eh-1Fh reserved for other interface and general errors
20h-3Fh reserved for CPU errors
40h-5Fh reserved for device errors
60h can't enter requested state
61h-7Fh reserved for other system errors
80h no power management events pending
81h-85h reserved for other power management event errors
86h APM not present
87h-9Fh reserved for other power management event errors
A0h-FEh reserved
FFh undefined
--------p-155301-----------------------------
INT 15 - Advanced Power Management v1.0+ - CONNECT REAL-MODE INTERFACE
AX = 5301h
BX = device ID of system BIOS (0000h)
Return: CF clear if successful
CF set on error
AH = error code (02h,05h,07h,09h) (see #00473)
Note: on connection, an APM v1.1 or v1.2 BIOS switches to APM v1.0
compatibility mode until it is informed that the user supports a
newer version of APM (see AX=530Eh)
SeeAlso: AX=5302h,AX=5303h,AX=5304h
--------p-155302-----------------------------
INT 15 R - Advanced Power Management v1.0+ - CONNECT 16-BIT PROTMODE INTERFACE
AX = 5302h
BX = device ID of system BIOS (0000h)
Return: CF clear if successful
AX = real-mode segment base address of protected-mode 16-bit code
segment
BX = offset of entry point
CX = real-mode segment base address of protected-mode 16-bit data
segment
---APM v1.1---
SI = APM BIOS code segment length
DI = APM BIOS data segment length
CF set on error
AH = error code (02h,05h,06h,07h,09h) (see #00473)
Notes: the caller must initialize two consecutive descriptors with the
returned segment base addresses; these descriptors must be valid
whenever the protected-mode interface is called, and will have
their limits arbitrarily set to 64K.
the protected mode interface is invoked by making a far call with the
same register values as for INT 15; it must be invoked while CPL=0,
the code segment descriptor must have a DPL of 0, the stack must be
in a 16-bit segment and have enough room for BIOS use and possible
interrupts, and the current I/O permission bit map must allow access
to the I/O ports used for power management.
functions 00h-03h are not available from protected mode
on connection, an APM v1.1 or v1.2 BIOS switches to APM v1.0
compatibility mode until it is informed that the user supports a
newer version of APM (see AX=530Eh)
SeeAlso: AX=5301h,AX=5303h,AX=5304h
--------p-155303-----------------------------
INT 15 - Advanced Power Management v1.0+ - CONNECT 32-BIT PROTMODE INTERFACE
AX = 5303h
BX = device ID of system BIOS (0000h)
Return: CF clear if successful
AX = real-mode segment base address of protected-mode 32-bit code
segment
EBX = offset of entry point
CX = real-mode segment base address of protected-mode 16-bit code
segment
DX = real-mode segment base address of protected-mode 16-bit data
segment
---APM v1.1---
SI = APM BIOS code segment length
DI = APM BIOS data segment length
CF set on error
AH = error code (02h,05h,07h,08h,09h) (see #00473)
Notes: the caller must initialize three consecutive descriptors with the
returned segment base addresses for 32-bit code, 16-bit code, and
16-bit data, respectively; these descriptors must be valid whenever
the protected-mode interface is called, and will have their limits
arbitrarily set to 64K.
the protected mode interface is invoked by making a far call to the
32-bit code segment with the same register values as for INT 15; it
must be invoked while CPL=0, the code segment descriptor must have a
DPL of 0, the stack must be in a 32-bit segment and have enough room
for BIOS use and possible interrupts, and the current I/O permission
bit map must allow access to the I/O ports used for power management.
functions 00h-03h are not available from protected mode
on connection, an APM v1.1 or v1.2 BIOS switches to APM v1.0
compatibility mode until it is informed that the user supports a
newer version of APM (see AX=530Eh)
SeeAlso: AX=5301h,AX=5302h,AX=5304h
--------p-155304-----------------------------
INT 15 - Advanced Power Management v1.0+ - DISCONNECT INTERFACE
AX = 5304h
BX = device ID of system BIOS (0000h)
Return: CF clear if successful
CF set on error
AH = error code (03h,09h) (see #00473)
SeeAlso: AX=5301h,AX=5302h,AX=5303h
--------p-155305-----------------------------
INT 15 - Advanced Power Management v1.0+ - CPU IDLE
AX = 5305h
Return: CF clear if successful (after system leaves idle state)
CF set on error
AH = error code (03h,0Bh) (see #00473)
Notes: call when the system is idle and should be suspended until the next
system event or interrupt
should not be called from within a hardware interrupt handler to avoid
reentrance problems
if an interrupt causes the system to resume normal processing, the
interrupt may or may not have been handled when the BIOS returns
from this call; thus, the caller should allow interrupts on return
interrupt handlers may not retain control if the BIOS allows
interrupts while in idle mode even if they are able to determine
that they were called from idle mode
the caller should issue this call continuously in a loop until it needs
to perform some processing of its own
SeeAlso: AX=1000h,AX=5306h,INT 2F/AX=1680h
--------p-155306-----------------------------
INT 15 - Advanced Power Management v1.0+ - CPU BUSY
AX = 5306h
Return: CF clear if successful
CF set on error
AH = error code (03h,0Bh) (see #00473)
Notes: called to ensure that the system runs at full speed even on systems
where the BIOS is unable to recognize increased activity (especially
if interrupts are hooked by other programs and not chained to the
BIOS)
this call may be made even when the system is already running at full
speed, but it will create unnecessary overhead
should not be called from within a hardware interrupt handler to avoid
reentrance problems
SeeAlso: AX=5305h
--------p-155307-----------------------------
INT 15 - Advanced Power Management v1.0+ - SET POWER STATE
AX = 5307h
BX = device ID (see #00474)
CX = system state ID (see #00475)
Return: CF clear if successful
CF set on error
AH = error code (01h,03h,09h,0Ah,0Bh,60h) (see #00473)
Note: should not be called from within a hardware interrupt handler to avoid
reentrance problems
SeeAlso: AX=530Ch
(Table 00474)
Values for APM device IDs:
0000h system BIOS
0001h all devices for which the system BIOS manages power
01xxh display (01FFh for all attached display devices)
02xxh secondary storage (02FFh for all attached secondary storage devices)
03xxh parallel ports (03FFh for all attached parallel ports)
04xxh serial ports (04FFh for all attached serial ports)
---APM v1.1+ ---
05xxh network adapters (05FFh for all attached network adapters)
06xxh PCMCIA sockets (06FFh for all)
0700h-7FFFh reserved
80xxh system battery devices (APM v1.2)
8100h-DFFFh reserved
Exxxh OEM-defined power device IDs
F000h-FFFFh reserved
(Table 00475)
Values for system state ID:
0000h ready (not supported for device ID 0001h)
0001h stand-by
0002h suspend
0003h off (not supported for device ID 0001h in APM v1.0)
---APM v1.1---
0004h last request processing notification (only for device ID 0001h)
0005h last request rejected (only for device ID 0001h)
0006h-001Fh reserved system states
0020h-003Fh OEM-defined system states
0040h-007Fh OEM-defined device states
0080h-FFFFh reserved device states
--------p-155307CX0001-----------------------
INT 15 - Advanced Power Management v1.0+ - SYSTEM STAND-BY
AX = 5307h
CX = 0001h
BX = 0001h (device ID for all power-managed devices)
Return: CF clear
Notes: puts the entire system into stand-by mode; normally called in response
to a System Stand-by Request notification after any necessary
processing, but may also be invoked at the caller's discretion
should not be called from within a hardware interrupt handler to avoid
reentrance problems
the stand-by state is typically exited on an interrupt
SeeAlso: AX=4280h,AX=5307h/CX=0002h"SUSPEND",AX=5307h/CX=0003h,AX=530Bh
--------p-155307CX0002-----------------------
INT 15 - Advanced Power Management v1.0+ - SUSPEND SYSTEM
AX = 5307h
CX = 0002h
BX = 0001h (device ID for all power-managed devices)
Return: after system is resumed
CF clear
Notes: puts the entire system into a low-power suspended state; normally
called in response to a Suspend System Request notification after
any necessary processing, but may also be invoked at the caller's
discretion
should not be called from within a hardware interrupt handler to avoid
reentrance problems
the caller may need to update its date and time values because the
system could have been suspended for a long period of time
SeeAlso: AX=5307h/CX=0001h"STAND-BY",AX=530Bh
--------p-155307CX0003-----------------------
INT 15 - Advanced Power Management v1.2 - TURN OFF SYSTEM
AX = 5307h
CX = 0003h
BX = 0001h (device ID for all power-managed devices)
Return: after system is resumed
CF clear
Notes: if supported by the system's power supply, turns off the system power
SeeAlso: AX=5307h/CX=0001h"STAND-BY",AX=530Bh
--------p-155308-----------------------------
INT 15 - Advanced Power Management v1.0+ - ENABLE/DISABLE POWER MANAGEMENT
AX = 5308h
BX = device ID for all devices power-managed by APM
0001h (APM v1.1+)
FFFFh (APM v1.0)
CX = new state
0000h disabled
0001h enabled
Return: CF clear if successful
CF set on error
AH = error code (01h,03h,09h,0Ah,0Bh) (see #00473)
Notes: when power management is disabled, the system BIOS will not
automatically power down devices, enter stand-by or suspended mode,
or perform any power-saving actions in response to AX=5305h calls
should not be called from within a hardware interrupt handler to avoid
reentrance problems
the APM BIOS should never be both disabled and disengaged at the same
time
SeeAlso: AX=5309h,AX=530Dh,AX=530Fh
--------p-155309-----------------------------
INT 15 - Advanced Power Management v1.0+ - RESTORE POWER-ON DEFAULTS
AX = 5309h
BX = device ID for all devices power-managed by APM
0001h (APM v1.1)
FFFFh (APM v1.0)
Return: CF clear if successful
CF set on error
AH = error code (03h,09h,0Bh) (see #00473)
Note: should not be called from within a hardware interrupt handler to avoid
reentrance problems
SeeAlso: AX=5308h
--------p-15530A-----------------------------
INT 15 - Advanced Power Management v1.0+ - GET POWER STATUS
AX = 530Ah
BX = device ID
0001h all devices power-managed by APM
80xxh specific battery unit number XXh (01h-FFh) (APM v1.2)
Return: CF clear if successful
BH = AC line status
00h off-line
01h on-line
02h on backup power (APM v1.1)
FFh unknown
other reserved
BL = battery status (see #00476)
CH = battery flag (APM v1.1+) (see #00477)
CL = remaining battery life, percentage
00h-64h (0-100) percentage of full charge
FFh unknown
DX = remaining battery life, time (APM v1.1) (see #00478)
---if specific battery unit specified---
SI = number of battery units currently installed
CF set on error
AH = error code (09h,0Ah) (see #00473)
Notes: should not be called from within a hardware interrupt handler to avoid
reentrance problems
supported in real mode (INT 15) and both 16-bit and 32-bit protected
mode
(Table 00476)
Values for APM v1.0+ battery status:
00h high
01h low
02h critical
03h charging
FFh unknown
other reserved
SeeAlso: #00477,#00478
Bitfields for APM v1.1+ battery flag:
Bit(s) Description (Table 00477)
0 high
1 low
2 critical
3 charging
4 selected battery not present (APM v1.2)
5-6 reserved (0)
7 no system battery
Note: all bits set (FFh) if unknown
SeeAlso: #00476,#00478
Bitfields for APM v1.1+ remaining battery life:
Bit(s) Description (Table 00478)
15 time units: 0=seconds, 1=minutes
14-0 battery life in minutes or seconds
Note: all bits set (FFFFh) if unknown
SeeAlso: #00476,#00477
--------p-15530B-----------------------------
INT 15 - Advanced Power Management v1.0+ - GET POWER MANAGEMENT EVENT
AX = 530Bh
Return: CF clear if successful
BX = event code (see #00479)
CX = event information (APM v1.2) if BX=0003h or BX=0004h
bit 0: PCMCIA socket was powered down in suspend state
CF set on error
AH = error code (03h,0Bh,80h) (see #00473)
Notes: although power management events are often asynchronous, notification
will not be made until polled via this call to permit software to
only receive event notification when it is prepared to process
power management events; since these events are not very time-
critical, it should be sufficient to poll once or twice per second
the critical resume notification is made after the system resumes
from an emergency suspension; normally, the system BIOS only notifies
its partner that it wishes to suspend and relies on the partner to
actually request the suspension, but no notification is made on an
emergency suspension
should not be called from within a hardware interrupt handler to avoid
reentrance problems
SeeAlso: AX=5307h,AX=5307h/CX=0001h"STAND-BY",AX=5307h/CX=0002h"SUSPEND"
(Table 00479)
Values for APM event code:
0001h system stand-by request
0002h system suspend request
0003h normal resume system notification
0004h critical resume system notification
0005h battery low notification
---APM v1.1---
0006h power status change notification
0007h update time notification
0008h critical system suspend notification
0009h user system standby request notification
000Ah user system suspend request notification
000Bh system standby resume notification
---APM v1.2---
000Ch capabilities change notification (see AX=5310h)
------
000Dh-00FFh reserved system events
01xxh reserved device events
02xxh OEM-defined APM events
0300h-FFFFh reserved
--------p-15530C-----------------------------
INT 15 - Advanced Power Management v1.1+ - GET POWER STATE
AX = 530Ch
BX = device ID (see #00474)
Return: CF clear if successful
CX = system state ID (see #00475)
CF set on error
AH = error code (01h,09h) (see #00473)
SeeAlso: AX=5307h
--------p-15530D-----------------------------
INT 15 - Advanced Power Management v1.1+ - EN/DISABLE DEVICE POWER MANAGEMENT
AX = 530Dh
BX = device ID (see #00474)
CX = function
0000h disable power management
0001h enable power management
Return: CF clear if successful
CF set on error
AH = error code (01h,03h,09h,0Ah,0Bh) (see #00473)
Desc: specify whether automatic power management should be active for a
given device
SeeAlso: AX=5308h,AX=530Fh
--------p-15530E-----------------------------
INT 15 - Advanced Power Management v1.1+ - DRIVER VERSION
AX = 530Eh
BX = device ID of system BIOS (0000h)
CH = APM driver major version (BCD)
CL = APM driver minor version (BCD) (02h for APM v1.2)
Return: CF clear if successful
AH = APM connection major version (BCD)
AL = APM connection minor version (BCD)
CF set on error
AH = error code (03h,09h,0Bh) (see #00473)
SeeAlso: AX=5300h,AX=5303h
--------p-15530F-----------------------------
INT 15 - Advanced Power Management v1.1+ - ENGAGE/DISENGAGE POWER MANAGEMENT
AX = 530Fh
BX = device ID (see #00474)
CX = function
0000h disengage power management
0001h engage power management
Return: CF clear if successful
CF set on error
AH = error code (01h,09h) (see #00473)
Notes: unlike AX=5308h, this call does not affect the functioning of the APM
BIOS
when cooperative power management is disengaged, the APM BIOS performs
automatic power management of the system or device
SeeAlso: AX=5308h,AX=530Dh
--------p-155310-----------------------------
INT 15 - Advanced Power Management v1.2 - GET CAPABILITIES
AX = 5310h
BX = device ID (see #00474)
0000h (APM BIOS)
other reserved
Return: CF clear if successful
BL = number of battery units supported (00h if no system batteries)
CX = capabilities flags (see #00480)
CF set on error
AH = error code (01h,09h,86h) (see #00473)
Notes: this function is supported via the INT 15, 16-bit protected mode, and
32-bit protected mode interfaces; it does not require that a
connection be established prior to use
this function will return the capabilities currently in effect, not
any new settings which have been made but do not take effect until
a system restart
SeeAlso: AX=5300h,AX=530Fh,AX=5311h,AX=5312h,AX=5313h
Bitfields for APM v1.2 capabilities flags:
Bit(s) Description (Table 00480)
15-8 reserved
7 PCMCIA Ring Indicator will wake up system from suspend mode
6 PCMCIA Ring Indicator will wake up system from standby mode
5 Resume on Ring Indicator will wake up system from suspend mode
4 Resume on Ring Indicator will wake up system from standby mode
3 resume timer will wake up system from suspend mode
2 resume timer will wake up system from standby mode
1 can enter global suspend state
0 can enter global standby state
--------p-155311-----------------------------
INT 15 - Advanced Power Management v1.2 - GET/SET/DISABLE RESUME TIMER
AX = 5311h
BX = device ID (see #00474)
0000h (APM BIOS)
other reserved
CL = function
00h disable Resume Timer
01h get Resume Timer
02h set Resume Timer
CH = resume time, seconds (BCD)
DL = resume time, minutes (BCD)
DH = resume time, hours (BCD)
SI = resume date (BCD), high byte = month, low byte = day
DI = resume date, year (BCD)
Return: CF clear if successful
---if getting timer---
CH = resume time, seconds (BCD)
DL = resume time, minutes (BCD)
DH = resume time, hours (BCD)
SI = resume date (BCD), high byte = month, low byte = day
DI = resume date, year (BCD)
CF set on error
AH = error code (03h,09h,0Ah,0Bh,0Ch,0Dh,86h) (see #00473)
Notes: this function is supported via the INT 15, 16-bit protected mode, and
32-bit protected mode interfaces
SeeAlso: AX=5300h,AX=5310h,AX=5312h,AX=5313h
--------p-155312-----------------------------
INT 15 - Advanced Power Management v1.2 - ENABLE/DISABLE RESUME ON RING
AX = 5312h
BX = device ID (see #00474)
0000h (APM BIOS)
other reserved
CL = function
00h disable Resume on Ring Indicator
01h enable Resume on Ring Indicator
02h get Resume on Ring Indicator status
Return: CF clear if successful
CX = resume status (0000h disabled, 0001h enabled)
CF set on error
AH = error code (03h,09h,0Ah,0Bh,0Ch,86h) (see #00473)
Notes: this function is supported via the INT 15, 16-bit protected mode, and
32-bit protected mode interfaces
SeeAlso: AX=5300h,AX=5310h,AX=5311h,AX=5313h
--------p-155313-----------------------------
INT 15 - Advanced Power Management v1.2 - ENABLE/DISABLE TIMER-BASED REQUESTS
AX = 5313h
BX = device ID (see #00474)
0000h (APM BIOS)
other reserved
CL = function
00h disable timer-based requests
01h enable timer-based requests
02h get timer-based requests status
Return: CF clear if successful
CX = timer-based requests status (0000h disabled, 0001h enabled)
CF set on error
AH = error code (03h,09h,0Ah,0Bh,86h) (see #00473)
Notes: this function is supported via the INT 15, 16-bit protected mode, and
32-bit protected mode interfaces
some BIOSes set AH on return even when successful
SeeAlso: AX=5300h,AX=5310h,AX=5311h,AX=5312h

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,220 @@
align 4
proc detect_codec
locals
codec_id dd ?
endl
stdcall codec_read, dword 0x7C
shl eax, 16
mov [codec_id], eax
stdcall codec_read, dword 0x7E
or eax, [codec_id]
mov [codec.chip_id], eax
and eax, 0xFFFFFF00
mov edi, codecs
@@:
mov ebx, [edi]
test ebx, ebx
jz .unknown
cmp eax, ebx
jne .next
mov eax, [edi+4]
mov [codec.ac_vendor_ids], eax
stdcall detect_chip, [edi+8]
ret
.next:
add edi, 12
jmp @B
.unknown:
mov [codec.ac_vendor_ids], ac_unknown
mov [codec.chip_ids], chip_unknown
ret
endp
align 4
proc detect_chip stdcall, chip_tab:dword
mov eax, [codec.chip_id]
and eax, 0xFF
mov edi, [chip_tab]
@@:
mov ebx, [edi]
test ebx, ebx
jz .unknown
cmp eax,ebx
jne .next
mov eax, [edi+4]
mov [codec.chip_ids], eax
ret
.next:
add edi, 8
jmp @b
.unknown:
mov [codec.chip_ids], chip_unknown
ret
endp
align 4
proc setup_codec
xor eax, eax
stdcall codec_write, dword CODEC_AUX_VOL
mov eax, 0x0B0B
stdcall codec_write, dword CODEC_MASTER_VOL_REG
mov ax, 0x08
stdcall codec_write, dword 0x0C
mov ax, 0x0808
stdcall codec_write, dword CODEC_PCM_OUT_REG
mov ax, 0x0808
stdcall codec_write, dword 0x10
mov ax, 0x0808
stdcall codec_write, dword 0x12
mov ax, 0x0808
stdcall codec_write, dword 0x16
stdcall codec_read, dword CODEC_EXT_AUDIO_CTRL_REG
and eax, 0FFFFh - BIT1 ; clear DRA (BIT1)
or eax, BIT0 ; set VRA (BIT0)
stdcall codec_write, dword CODEC_EXT_AUDIO_CTRL_REG
stdcall set_sample_rate, dword 48000
.init_error:
xor eax, eax ; exit with error
ret
endp
; param
; eax= volume -10000 - 0 for both channels
align 4
set_master_vol:
cmp eax, 0
jl @F
xor eax, eax
jmp .set
@@:
cmp eax, -9450
jg .set
mov eax, -9450 ;clamp into 6 bits
.set:
cdq
mov ebx, -150
idiv ebx
mov ah, al
stdcall codec_write, dword CODEC_MASTER_VOL_REG
xor eax, eax
ret
align 4
proc get_master_vol stdcall, pvol:dword
stdcall codec_read, dword CODEC_MASTER_VOL_REG
and eax, 0x3F
imul eax, -150
mov ebx, [pvol]
mov [ebx], eax
xor eax, eax
ret
endp
align 4
proc set_sample_rate stdcall, rate:dword
mov eax, [rate]
stdcall codec_write, dword CODEC_PCM_FRONT_DACRATE_REG
ret
endp
align 16
ac_unknown db 'unknown manufacturer',13,10,0
ac_Realtek db 'Realtek Semiconductor',13,10,0
ac_Analog db 'Analog Devices',13,10,0
ac_CMedia db 'C-Media Electronics',13,10,0
chip_unknown db 'unknown chip', 13,10,0
CHIP_ANALOG equ 0x41445300
CHIP_REALTEK equ 0x414C4700
CHIP_CMEDIA equ 0x434D4900
align 16
codecs dd CHIP_ANALOG, ac_Analog, chips_Analog
dd CHIP_CMEDIA, ac_CMedia, chips_CMedia
dd CHIP_REALTEK,ac_Realtek, chips_Realtek
dd 0
align 16
chips_Analog dd 0x03, chip_AD1819
dd 0x40, chip_AD1881
dd 0x48, chip_AD1881A
dd 0x60, chip_AD1884
dd 0x61, chip_AD1886
dd 0x62, chip_AD1887
dd 0x63, chip_AD1886A
dd 0x70, chip_AD1980
dd 0x75, chip_AD1985
dd 0
chips_Realtek dd 0x20, chip_ALC650
dd 0x21, chip_ALC650D
dd 0x22, chip_ALC650E
dd 0x23, chip_ALC650F
dd 0x60, chip_ALC655
dd 0x80, chip_ALC658
dd 0x81, chip_ALC658D
dd 0x90, chip_ALC850
dd 0
chips_CMedia dd 0x41, chip_CM9738
dd 0x61, chip_CM9739
dd 0x69, chip_CM9780
dd 0x78, chip_CM9761
dd 0x82, chip_CM9761
dd 0x83, chip_CM9761
dd 0
align 16
;Analog Devices
chip_AD1819 db 'AD1819 ',0dh,0ah,00h
chip_AD1881 db 'AD1881 ',0dh,0ah,00h
chip_AD1881A db 'AD1881A',0dh,0ah,00h
chip_AD1884 db 'AD1885 ',0dh,0ah,00h
chip_AD1885 db 'AD1885 ',0dh,0ah,00h
chip_AD1886 db 'AD1886 ',0dh,0ah,00h
chip_AD1886A db 'AD1886A',0dh,0ah,00h
chip_AD1887 db 'AD1887 ',0dh,0ah,00h
chip_AD1980 db 'AD1980 ',0dh,0ah,00h
chip_AD1985 db 'AD1985 ',0dh,0ah,00h
;Realtek
chip_ALC650 db 'ALC650 ',0dh,0ah,00h
chip_ALC650D db 'ALC650D',0dh,0ah,00h
chip_ALC650E db 'ALC650E',0dh,0ah,00h
chip_ALC650F db 'ALC650F',0dh,0ah,00h
chip_ALC655 db 'ALC655 ',0dh,0ah,00h
chip_ALC658 db 'ALC658 ',0dh,0ah,00h
chip_ALC658D db 'ALC658D',0dh,0ah,00h
chip_ALC850 db 'ALC850 ',0dh,0ah,00h
;CMedia
chip_CM9738 db 'CMI9738', 0dh,0ah,0
chip_CM9739 db 'CMI9739', 0dh,0ah,0
chip_CM9780 db 'CMI9780', 0dh,0ah,0
chip_CM9761 db 'CMI9761', 0dh,0ah,0

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,136 @@
; all exported kernel functions and data
if used RegService
extrn RegService
end if
if used GetService
extrn GetService
end if
if used ServiceHandler
extrn ServiceHandler
end if
if used AttachIntHandler
extrn AttachIntHandler
end if
if used FpuSave
extrn FpuSave
end if
if used FpuRestore
extrn FpuRestore
end if
if used PciApi
extrn PciApi
end if
if used PciRead32
extrn PciRead32
end if
if used PciRead8
extrn PciRead8
end if
if used PciWrite8
extrn PciWrite8
end if
if used AllocPage
extrn AllocPage
end if
if used AllocPages
extrn AllocPages
end if
if used FreePage
extrn FreePage
end if
if used MapPage
extrn MapPage
end if
if used MapSpace
extrn MapSpace
end if
if used GetPgAddr
extrn GetPgAddr
end if
if used CommitPages
extrn CommitPages
end if
if used ReleasePages
extrn ReleasePages
end if
if used AllocKernelSpace
extrn AllocKernelSpace
end if
if used FreeKernelSpace
extrn FreeKernelSpace
end if
if used KernelAlloc
extrn KernelAlloc
end if
if used KernelFree
extrn KernelFree
end if
if used UserAlloc
extrn UserAlloc
end if
if used UserFree
extrn UserFree
end if
if used Kmalloc
extrn Kmalloc
end if
if used Kfree
extrn Kfree
end if
if used CreateObject
extrn CreateObject
end if
if used DestroyObject
extrn DestroyObject
end if
if used CreateEvent
extrn CreateEvent
end if
if used RaiseEvent
extrn RaiseEvent
end if
if used WaitEvent
extrn WaitEvent
end if
if used DestroyEvent
extrn DestroyEvent
end if
if used ClearEvent
extrn ClearEvent
end if
if used LoadCursor
extrn LoadCursor
end if
if used SetHwCursor
extrn SetHwCursor
end if
if used HwCursorRestore
extrn HwCursorRestore
end if
if used HwCursorCreate
extrn HwCursorCreate
end if
if used SysMsgBoardStr
extrn SysMsgBoardStr
end if
if used GetCurrentTask
extrn GetCurrentTask
end if
if used LoadFile
extrn LoadFile
end if
if used SendEvent
extrn SendEvent
end if
if used LFBAddress
extrn LFBAddress
end if

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,169 @@
;
; This file is part of the Infinity sound driver.
; (C) copyright Serge 2006-2007
; email: infinity_sound@mail.ru
;
; This program is free software; you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation; either version 2 of the License, or
; (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
SOUND_VERSION equ 0x01000100
PLAY_SYNC equ 0x80000000
PCM_ALL equ 0
PCM_OUT equ 0x08000000
PCM_RING equ 0x10000000
PCM_STATIC equ 0x20000000
PCM_FLOAT equ 0x40000000 ;reserved
PCM_FILTER equ 0x80000000 ;reserved
PCM_2_16_48 equ 1
PCM_1_16_48 equ 2
PCM_2_16_44 equ 3
PCM_1_16_44 equ 4
PCM_2_16_32 equ 5
PCM_1_16_32 equ 6
PCM_2_16_24 equ 7
PCM_1_16_24 equ 8
PCM_2_16_22 equ 9
PCM_1_16_22 equ 10
PCM_2_16_16 equ 11
PCM_1_16_16 equ 12
PCM_2_16_12 equ 13
PCM_1_16_12 equ 14
PCM_2_16_11 equ 15
PCM_1_16_11 equ 16
PCM_2_16_8 equ 17
PCM_1_16_8 equ 18
PCM_2_8_48 equ 19
PCM_1_8_48 equ 20
PCM_2_8_44 equ 21
PCM_1_8_44 equ 22
PCM_2_8_32 equ 23
PCM_1_8_32 equ 24
PCM_2_8_24 equ 25
PCM_1_8_24 equ 26
PCM_2_8_22 equ 27
PCM_1_8_22 equ 28
PCM_2_8_16 equ 29
PCM_1_8_16 equ 30
PCM_2_8_12 equ 31
PCM_1_8_12 equ 32
PCM_2_8_11 equ 33
PCM_1_8_11 equ 34
PCM_2_8_8 equ 35
PCM_1_8_8 equ 36
SRV_GETVERSION equ 0
SND_CREATE_BUFF equ 1
SND_DESTROY_BUFF equ 2
SND_SETFORMAT equ 3
SND_GETFORMAT equ 4
SND_RESET equ 5
SND_SETPOS equ 6
SND_GETPOS equ 7
SND_SETBUFF equ 8
SND_OUT equ 9
SND_PLAY equ 10
SND_STOP equ 11
SND_SETVOLUME equ 12
SND_GETVOLUME equ 13
SND_SETPAN equ 14
SND_GETPAN equ 15
SND_GETBUFFSIZE equ 16
struc STREAM
{
.magic dd ? ;'WAVE'
.destroy dd ? ;internal destructor
.fd dd ? ;next object in list
.bk dd ? ;prev object in list
.pid dd ? ;owner id
.size dd ?
.str_fd dd ?
.str_bk dd ?
.device dd ?
.format dd ?
.flags dd ?
.out_base dd ?
.out_wp dd ?
.out_rp dd ?
.out_count dd ?
.out_top dd ?
.r_size dd ?
.r_dt dd ?
.r_silence dd ?
.resample dd ?
.l_vol dd ?
.r_vol dd ?
.l_amp dw ?
.r_amp dw ?
.pan dd ?
.in_base dd ?
.in_size dd ?
.in_wp dd ?
.in_rp dd ?
.in_count dd ?
.in_free dd ?
.in_top dd ?
.notify_event dd ?
.notify_id dd ?
}
STREAM_SIZE equ 34*4
FD_OFFSET equ 24
virtual at 0
STREAM STREAM
end virtual
struc WAVE_HEADER
{ .riff_id dd ?
.riff_size dd ?
.riff_format dd ?
.fmt_id dd ?
.fmt_size dd ?
.format_tag dw ?
.channels dw ?
.freq dd ?
.bytes_sec dd ?
.block_align dw ?
.bits_sample dw ?
.data_id dd ?
.data_size dd ?
}

View File

@ -0,0 +1,241 @@
; params
; edi= output
; eax= input stream 1
; ebx= input stream 2
if used mmx_mix_2
align 4
mmx_mix_2:
movq mm0, [eax]
movq mm1, [eax+8]
movq mm2, [eax+16]
movq mm3, [eax+24]
movq mm4, [eax+32]
movq mm5, [eax+40]
movq mm6, [eax+48]
movq mm7, [eax+56]
paddsw mm0, [ebx]
movq [edi], mm0
paddsw mm1,[ebx+8]
movq [edi+8], mm1
paddsw mm2, [ebx+16]
movq [edi+16], mm2
paddsw mm3, [ebx+24]
movq [edi+24], mm3
paddsw mm4, [ebx+32]
movq [edi+32], mm4
paddsw mm5, [ebx+40]
movq [edi+40], mm5
paddsw mm6, [ebx+48]
movq [edi+48], mm6
paddsw mm7, [ebx+56]
movq [edi+56], mm7
movq mm0, [eax+64]
movq mm1, [eax+72]
movq mm2, [eax+80]
movq mm3, [eax+88]
movq mm4, [eax+96]
movq mm5, [eax+104]
movq mm6, [eax+112]
movq mm7, [eax+120]
paddsw mm0, [ebx+64]
movq [edi+64], mm0
paddsw mm1, [ebx+72]
movq [edi+72], mm1
paddsw mm2, [ebx+80]
movq [edi+80], mm2
paddsw mm3, [ebx+88]
movq [edi+88], mm3
paddsw mm4, [ebx+96]
movq [edi+96], mm4
paddsw mm5, [ecx+104]
movq [edx+104], mm5
paddsw mm6, [ebx+112]
movq [edi+112], mm6
paddsw mm7, [ebx+120]
movq [edi+120], mm7
ret
align 4
mmx_mix_3:
movq mm0, [eax]
movq mm1, [eax+8]
movq mm2, [eax+16]
movq mm3, [eax+24]
movq mm4, [eax+32]
movq mm5, [eax+40]
movq mm6, [eax+48]
movq mm7, [eax+56]
paddsw mm0, [ebx]
paddsw mm1, [ebx+8]
paddsw mm2, [ebx+16]
paddsw mm3, [ebx+24]
paddsw mm4, [ebx+32]
paddsw mm5, [ebx+40]
paddsw mm6, [ebx+48]
paddsw mm7, [ebx+56]
paddsw mm0, [ecx]
movq [edi], mm0
paddsw mm1,[ecx+8]
movq [edi+8], mm1
paddsw mm2, [ecx+16]
movq [edi+16], mm2
paddsw mm3, [ecx+24]
movq [edi+24], mm3
paddsw mm4, [ecx+32]
movq [edi+32], mm4
paddsw mm5, [ecx+40]
movq [edi+40], mm5
paddsw mm6, [ecx+48]
movq [edi+48], mm6
paddsw mm7, [ecx+56]
movq [edi+56], mm7
movq mm0, [eax+64]
movq mm1, [eax+72]
movq mm2, [eax+80]
movq mm3, [eax+88]
movq mm4, [eax+96]
movq mm5, [eax+104]
movq mm6, [eax+112]
movq mm7, [eax+120]
paddsw mm0, [ebx+64]
paddsw mm1, [ebx+72]
paddsw mm2, [ebx+80]
paddsw mm3, [ebx+88]
paddsw mm4, [ebx+96]
paddsw mm5, [ebx+104]
paddsw mm6, [ebx+112]
paddsw mm7, [ebx+120]
paddsw mm0, [ecx+64]
movq [edi+64], mm0
paddsw mm1, [ecx+72]
movq [edi+72], mm1
paddsw mm2, [ecx+80]
movq [edi+80], mm2
paddsw mm3, [ecx+88]
movq [edi+88], mm3
paddsw mm4, [ecx+96]
movq [edi+96], mm4
paddsw mm5, [ecx+104]
movq [edi+104], mm5
paddsw mm6, [ecx+112]
movq [edi+112], mm6
paddsw mm7, [ecx+120]
movq [edi+120], mm7
ret
align 4
mmx_mix_4:
movq mm0, [eax]
movq mm2, [eax+8]
movq mm4, [eax+16]
movq mm6, [eax+24]
movq mm1, [ebx]
movq mm3, [ebx+8]
movq mm5, [ebx+16]
movq mm7, [ebx+24]
paddsw mm0, [ecx]
paddsw mm2, [ecx+8]
paddsw mm4, [ecx+16]
paddsw mm6, [ecx+24]
paddsw mm1, [edx]
paddsw mm3, [edx+8]
paddsw mm5, [edx+16]
paddsw mm7, [edx+24]
paddsw mm0, mm1
movq [edi], mm0
paddsw mm2, mm3
movq [edi+8], mm2
paddsw mm4, mm5
movq [edi+16], mm4
paddsw mm5, mm6
movq [edi+24], mm6
movq mm0, [eax+32]
movq mm2, [eax+40]
movq mm4, [eax+48]
movq mm6, [eax+56]
movq mm1, [ebx+32]
movq mm3, [ebx+40]
movq mm5, [ebx+48]
movq mm7, [ebx+56]
paddsw mm0, [ecx+32]
paddsw mm2, [ecx+40]
paddsw mm4, [ecx+48]
paddsw mm6, [ecx+56]
paddsw mm1, [edx+32]
paddsw mm3, [edx+40]
paddsw mm5, [edx+48]
paddsw mm7, [edx+56]
paddsw mm0, mm1
movq [edi+32], mm0
paddsw mm2, mm2
movq [edi+40], mm2
paddsw mm4, mm5
movq [edi+48], mm4
paddsw mm6, mm7
movq [edi+56], mm6
movq mm0, [eax+64]
movq mm2, [eax+72]
movq mm4, [eax+80]
movq mm6, [eax+88]
movq mm1, [ebx+64]
movq mm3, [ebx+72]
movq mm5, [ebx+80]
movq mm7, [ebx+88]
paddsw mm0, [ecx+64]
paddsw mm2, [ecx+72]
paddsw mm4, [ecx+80]
paddsw mm6, [ecx+88]
paddsw mm1, [edx+64]
paddsw mm3, [edx+72]
paddsw mm5, [edx+80]
paddsw mm7, [edx+88]
paddsw mm0, mm1
movq [edi+64], mm0
paddsw mm2, mm3
movq [edi+72], mm2
paddsw mm4, mm5
movq [edi+80], mm4
paddsw mm6, mm5
movq [edi+88], mm7
movq mm0, [eax+96]
movq mm2, [eax+104]
movq mm4, [eax+112]
movq mm6, [eax+120]
movq mm1, [ebx+96]
movq mm3, [ebx+104]
movq mm5, [ebx+112]
movq mm7, [ebx+120]
paddsw mm0, [ecx+96]
paddsw mm2, [ecx+104]
paddsw mm4, [ecx+112]
paddsw mm6, [ecx+120]
paddsw mm1, [edx+96]
paddsw mm3, [edx+104]
paddsw mm5, [edx+112]
paddsw mm7, [edx+120]
paddsw mm0, mm1
movq [eax+96], mm0
paddsw mm2, mm3
movq [edi+104], mm2
paddsw mm4, mm5
movq [edi+112], mm4
paddsw mm6, mm7
movq [edi+120], mm6
ret
end if

View File

@ -0,0 +1,139 @@
if used mmx128_mix_2
align 4
mmx128_mix_2:
prefetcht1 [eax+128]
prefetcht1 [ebx+128]
movaps xmm0, [eax]
movaps xmm1, [eax+16]
movaps xmm2, [eax+32]
movaps xmm3, [eax+48]
movaps xmm4, [eax+64]
movaps xmm5, [eax+80]
movaps xmm6, [eax+96]
movaps xmm7, [eax+112]
paddsw xmm0, [ebx]
movaps [edi], xmm0
paddsw xmm1,[ebx+16]
movaps [edi+16], xmm1
paddsw xmm2, [ebx+32]
movaps [edi+32], xmm2
paddsw xmm3, [ebx+48]
movaps [edi+48], xmm3
paddsw xmm4, [ebx+64]
movaps [edi+64], xmm4
paddsw xmm5, [ebx+80]
movaps [edi+80], xmm5
paddsw xmm6, [ebx+96]
movaps [edi+96], xmm6
paddsw xmm7, [ebx+112]
movaps [edi+112], xmm7
ret
align 4
mmx128_mix_3:
prefetcht1 [eax+128]
prefetcht1 [ebx+128]
prefetcht1 [ecx+128]
movaps xmm0, [eax]
movaps xmm1, [eax+16]
movaps xmm2, [eax+32]
movaps xmm3, [eax+48]
movaps xmm4, [eax+64]
movaps xmm5, [eax+80]
movaps xmm6, [eax+96]
movaps xmm7, [eax+112]
paddsw xmm0, [ebx]
paddsw xmm1, [ebx+16]
paddsw xmm2, [ebx+32]
paddsw xmm3, [ebx+48]
paddsw xmm4, [ebx+64]
paddsw xmm5, [ebx+80]
paddsw xmm6, [ebx+96]
paddsw xmm7, [ebx+112]
paddsw xmm0, [ecx]
movaps [edi], xmm0
paddsw xmm1, [ecx+16]
movaps [edi+16], xmm1
paddsw xmm2, [ecx+32]
movaps [edi+32], xmm2
paddsw xmm3, [ecx+48]
movaps [edi+48], xmm3
paddsw xmm4, [ecx+64]
movaps [edi+64], xmm4
paddsw xmm5, [ecx+80]
movaps [edi+80], xmm5
paddsw xmm6, [ecx+96]
movaps [edi+96], xmm6
paddsw xmm7, [ecx+112]
movaps [edi+112], xmm7
ret
align 4
mmx128_mix_4:
prefetcht1 [eax+128]
prefetcht1 [ebx+128]
prefetcht1 [ecx+128]
prefetcht1 [edx+128]
movaps xmm0, [eax]
movaps xmm2, [eax+16]
movaps xmm4, [eax+32]
movaps xmm6, [eax+48]
movaps xmm1, [ebx]
movaps xmm3, [ebx+16]
movaps xmm5, [ebx+32]
movaps xmm7, [ebx+48]
paddsw xmm0, [ecx]
paddsw xmm2, [ecx+16]
paddsw xmm4, [ecx+32]
paddsw xmm6, [ecx+48]
paddsw xmm1, [edx]
paddsw xmm3, [edx+16]
paddsw xmm5, [edx+32]
paddsw xmm7, [edx+48]
paddsw xmm0, xmm1
movaps [edi], xmm0
paddsw xmm2, xmm3
movaps [edi+16], xmm2
paddsw xmm4, xmm5
movaps [edi+32], xmm4
paddsw xmm6, xmm7
movaps [edi+48], xmm6
movaps xmm0, [eax+64]
movaps xmm2, [eax+80]
movaps xmm4, [eax+96]
movaps xmm6, [eax+112]
movaps xmm1, [ebx+64]
movaps xmm3, [ebx+80]
movaps xmm5, [ebx+96]
movaps xmm7, [ebx+112]
paddsw xmm0, [ecx+64]
paddsw xmm2, [ecx+80]
paddsw xmm4, [ecx+96]
paddsw xmm6, [ecx+112]
paddsw xmm1, [edx+64]
paddsw xmm3, [edx+80]
paddsw xmm5, [edx+96]
paddsw xmm7, [edx+112]
paddsw xmm0, xmm1
movaps [edi+64], xmm0
paddsw xmm2, xmm3
movaps [edi+80], xmm2
paddsw xmm4, xmm5
movaps [edi+96], xmm4
paddsw xmm6, xmm7
movaps [edi+112], xmm6
ret
end if

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,268 @@
; Macroinstructions for defining and calling procedures
macro stdcall proc,[arg] ; directly call STDCALL procedure
{ common
if ~ arg eq
reverse
pushd arg
common
end if
call proc }
macro invoke proc,[arg] ; indirectly call STDCALL procedure
{ common
if ~ arg eq
reverse
pushd arg
common
end if
call [proc] }
macro ccall proc,[arg] ; directly call CDECL procedure
{ common
size@ccall = 0
if ~ arg eq
reverse
pushd arg
size@ccall = size@ccall+4
common
end if
call proc
if size@ccall
add esp,size@ccall
end if }
macro cinvoke proc,[arg] ; indirectly call CDECL procedure
{ common
size@ccall = 0
if ~ arg eq
reverse
pushd arg
size@ccall = size@ccall+4
common
end if
call [proc]
if size@ccall
add esp,size@ccall
end if }
macro proc [args] ; define procedure
{ common
match name params, args>
\{ define@proc name,<params \} }
prologue@proc equ prologuedef
macro prologuedef procname,flag,parmbytes,localbytes,reglist
{ if parmbytes | localbytes
push ebp
mov ebp,esp
if localbytes
sub esp,localbytes
end if
end if
irps reg, reglist \{ push reg \} }
epilogue@proc equ epiloguedef
macro epiloguedef procname,flag,parmbytes,localbytes,reglist
{ irps reg, reglist \{ reverse pop reg \}
if parmbytes | localbytes
leave
end if
if (flag and 10000b) | (parmbytes=0)
retn
else
retn parmbytes
end if }
macro define@proc name,statement
{ local params,flag,regs,parmbytes,localbytes,current
if used name
name:
match =stdcall args, statement \{ params equ args
flag = 11b \}
match =stdcall, statement \{ params equ
flag = 11b \}
match =c args, statement \{ params equ args
flag = 10001b \}
match =c, statement \{ params equ
flag = 10001b \}
match =params, params \{ params equ statement
flag = 0 \}
virtual at ebp+8
match =uses reglist=,args, params \{ regs equ reglist
params equ args \}
match =regs =uses reglist, regs params \{ regs equ reglist
params equ \}
match =regs, regs \{ regs equ \}
match =,args, params \{ defargs@proc args \}
match =args@proc args, args@proc params \{ defargs@proc args \}
parmbytes = $ - (ebp+8)
end virtual
name # % = parmbytes/4
all@vars equ
current = 0
match prologue:reglist, prologue@proc:<regs> \{ prologue name,flag,parmbytes,localbytes,reglist \}
macro locals
\{ virtual at ebp-localbytes+current
macro label . \\{ deflocal@proc .,:, \\}
struc db [val] \\{ \common deflocal@proc .,db,val \\}
struc dw [val] \\{ \common deflocal@proc .,dw,val \\}
struc dp [val] \\{ \common deflocal@proc .,dp,val \\}
struc dd [val] \\{ \common deflocal@proc .,dd,val \\}
struc dt [val] \\{ \common deflocal@proc .,dt,val \\}
struc dq [val] \\{ \common deflocal@proc .,dq,val \\}
struc rb cnt \\{ deflocal@proc .,rb cnt, \\}
struc rw cnt \\{ deflocal@proc .,rw cnt, \\}
struc rp cnt \\{ deflocal@proc .,rp cnt, \\}
struc rd cnt \\{ deflocal@proc .,rd cnt, \\}
struc rt cnt \\{ deflocal@proc .,rt cnt, \\}
struc rq cnt \\{ deflocal@proc .,rq cnt, \\} \}
macro endl
\{ purge label
restruc db,dw,dp,dd,dt,dq
restruc rb,rw,rp,rd,rt,rq
restruc byte,word,dword,pword,tword,qword
current = $-(ebp-localbytes)
end virtual \}
macro ret operand
\{ match any, operand \\{ retn operand \\}
match , operand \\{ match epilogue:reglist, epilogue@proc:<regs>
\\\{ epilogue name,flag,parmbytes,localbytes,reglist \\\} \\} \}
macro finish@proc \{ localbytes = (((current-1) shr 2)+1) shl 2
end if \} }
macro defargs@proc [arg]
{ common
if ~ arg eq
forward
local ..arg,current@arg
match argname:type, arg
\{ current@arg equ argname
label ..arg type
argname equ ..arg
if dqword eq type
dd ?,?,?,?
else if tbyte eq type
dd ?,?,?
else if qword eq type | pword eq type
dd ?,?
else
dd ?
end if \}
match =current@arg,current@arg
\{ current@arg equ arg
arg equ ..arg
..arg dd ? \}
common
args@proc equ current@arg
forward
restore current@arg
common
end if }
macro deflocal@proc name,def,[val]
{ common
match vars, all@vars \{ all@vars equ all@vars, \}
all@vars equ all@vars name
forward
local ..var,..tmp
..var def val
match =?, val \{ ..tmp equ \}
match any =dup (=?), val \{ ..tmp equ \}
match tmp : value, ..tmp : val
\{ tmp: end virtual
initlocal@proc ..var,def value
virtual at tmp\}
common
match first rest, ..var, \{ name equ first \} }
macro initlocal@proc name,def
{ virtual at name
def
size@initlocal = $ - name
end virtual
position@initlocal = 0
while size@initlocal > position@initlocal
virtual at name
def
if size@initlocal - position@initlocal < 2
current@initlocal = 1
load byte@initlocal byte from name+position@initlocal
else if size@initlocal - position@initlocal < 4
current@initlocal = 2
load word@initlocal word from name+position@initlocal
else
current@initlocal = 4
load dword@initlocal dword from name+position@initlocal
end if
end virtual
if current@initlocal = 1
mov byte [name+position@initlocal],byte@initlocal
else if current@initlocal = 2
mov word [name+position@initlocal],word@initlocal
else
mov dword [name+position@initlocal],dword@initlocal
end if
position@initlocal = position@initlocal + current@initlocal
end while }
macro endp
{ purge ret,locals,endl
finish@proc
purge finish@proc
restore regs@proc
match all,args@proc \{ restore all \}
restore args@proc
match all,all@vars \{ restore all \} }
macro local [var]
{ common
locals
forward done@local equ
match varname[count]:vartype, var
\{ match =BYTE, vartype \\{ varname rb count
restore done@local \\}
match =WORD, vartype \\{ varname rw count
restore done@local \\}
match =DWORD, vartype \\{ varname rd count
restore done@local \\}
match =PWORD, vartype \\{ varname rp count
restore done@local \\}
match =QWORD, vartype \\{ varname rq count
restore done@local \\}
match =TBYTE, vartype \\{ varname rt count
restore done@local \\}
match =DQWORD, vartype \\{ label varname dqword
rq count+count
restore done@local \\}
match , done@local \\{ virtual
varname vartype
end virtual
rb count*sizeof.\#vartype
restore done@local \\} \}
match :varname:vartype, done@local:var
\{ match =BYTE, vartype \\{ varname db ?
restore done@local \\}
match =WORD, vartype \\{ varname dw ?
restore done@local \\}
match =DWORD, vartype \\{ varname dd ?
restore done@local \\}
match =PWORD, vartype \\{ varname dp ?
restore done@local \\}
match =QWORD, vartype \\{ varname dq ?
restore done@local \\}
match =TBYTE, vartype \\{ varname dt ?
restore done@local \\}
match =DQWORD, vartype \\{ label varname dqword
dq ?,?
restore done@local \\}
match , done@local \\{ varname vartype
restore done@local \\} \}
match ,done@local
\{ var
restore done@local \}
common
endl }

View File

@ -0,0 +1,157 @@
;driver sceletone
format MS COFF
include 'proc32.inc'
include 'imports.inc'
OS_BASE equ 0;
new_app_base equ 0x60400000
PROC_BASE equ OS_BASE+0x0080000
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
DEBUG equ 1
DRV_ENTRY equ 1
DRV_EXIT equ -1
STRIDE equ 4 ;size of row in devices table
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 edi, [ioctl]
; mov eax, [edi+io_code]
xor eax, eax
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
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:
xor eax, eax
inc eax
ret
.err:
xor eax, eax
ret
endp
;DEVICE_ID equ ; pci device id
;VENDOR_ID equ ; device vendor id
;all initialized data place here
align 4
devices dd (DEVICE_ID shl 16)+VENDOR_ID
dd 0 ;terminator
version dd 0x00030003
my_service db 'MY_SERVICE',0 ;max 16 chars include zero
msgInit db 'detect hardware...',13,10,0
msgPCI db 'PCI accsess not supported',13,10,0
msgFail db 'device not found',13,10,0
section '.data' data readable writable align 16
;all uninitialized data place here

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,422 @@
;
; 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
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:
add esp,4*8+4
mov edx,..str
sub esp,4*8+4
else
mov edx,_str
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
add 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
sub esp,4*8+4
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
else if _hex in <ax,bx,cx,dx,si,di,bp,sp>
if ~_hex eq ax
movzx eax,_hex
end if
shl eax,16
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
shl eax,24
if (_num eq)
mov edx,2
end if
end if
else if _hex eqtype 0
mov eax,_hex
else
add esp,4*8+4
mov eax,dword _hex
sub esp,4*8+4
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 ebx,al
mov eax,1
call sys_msg_board
popad
ret
debug_endf
debug_func fdo_debug_outstr
debug_beginf
mov eax,1
.l1: dec esi
js .l2
movzx ebx,byte[edx]
or bl,bl
jz .l2
call sys_msg_board
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
@@: push 10
pop ecx
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
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,835 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; 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 ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
iglobal
dir0: db 'HARDDISK '
db 'RAMDISK '
db 'FLOPPYDISK '
db 0
dir1: db 'FIRST '
db 'SECOND '
db 'THIRD '
db 'FOURTH '
db 0
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 = 1 ; write file /RamDisk/First 33 /HardDisk/First 56
; 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 'h'
je fs_info_h
cmp [eax+21],byte 'H'
je fs_info_h
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
jmp fs_info1
fs_info_h: ;if harddisk
call get_hd_info
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:
cmp dword [esp+20],1 ; WRITE
jne fs_noramdisk_write
mov eax,[esp+4] ; fname
add eax,2*12+1
mov ebx,[esp+8] ; buffer
mov ecx,[esp+12] ; count to write
mov edx,0 ; create new
call filesave
; eax=0 ok - eax=1 not enough free space
jmp file_system_return
fs_noramdisk_write:
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:
cmp dword [esp+20],1 ; WRITE
jne fs_noflpdisk_write
mov eax,[esp+4] ; fname
add eax,2*12+1
mov ebx,[esp+8] ; buffer
mov ecx,[esp+12] ; count to write
mov edx,0 ; create new
call floppy_filesave
; eax=0 ok - eax=1 not enough free space
jmp file_system_return
fs_noflpdisk_write:
fs_noflpdisk:
;*****************************************************************
mov eax,[edi+1]
cmp eax,'HD0 '
je fs_yesharddisk_IDE0
cmp eax,'HD1 '
je fs_yesharddisk_IDE1
cmp eax,'HD2 '
je fs_yesharddisk_IDE2
cmp eax,'HD3 '
je fs_yesharddisk_IDE3
jmp old_path_harddisk
fs_yesharddisk_IDE0:
call reserve_hd1
mov [hdbase],0x1f0
mov [hdid],0x0
mov [hdpos],1
jmp fs_yesharddisk_partition
fs_yesharddisk_IDE1:
call reserve_hd1
mov [hdbase],0x1f0
mov [hdid],0x10
mov [hdpos],2
jmp fs_yesharddisk_partition
fs_yesharddisk_IDE2:
call reserve_hd1
mov [hdbase],0x170
mov [hdid],0x0
mov [hdpos],3
jmp fs_yesharddisk_partition
fs_yesharddisk_IDE3:
call reserve_hd1
mov [hdbase],0x170
mov [hdid],0x10
mov [hdpos],4
fs_yesharddisk_partition:
call reserve_hd_channel
; call choice_necessity_partition
; jmp fs_yesharddisk_all
jmp fs_for_new_semantic
choice_necessity_partition:
mov eax,[edi+1+12]
call StringToNumber
mov [fat32part],eax
choice_necessity_partition_1:
mov ecx,[hdpos]
xor eax,eax
mov [0xfe10], eax ; entries in hd cache
mov edx,0x40002
search_partition_array:
mov bl,[edx]
movzx ebx,bl
add eax,ebx
inc edx
loop search_partition_array
sub eax,ebx
add eax,[fat32part]
dec eax
xor edx,edx
imul eax,100
add eax,0x4000a
mov [transfer_adress],eax
call partition_data_transfer_1
ret
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:
cmp byte [edi+1+11],0 ; directory read
je fs_give_dir1
call reserve_hd1
fs_for_new_semantic:
call choice_necessity_partition
fs_yesharddisk_all:
mov eax,1
mov ebx, [esp+24+24]
cmp [hdpos],0 ; is hd base set?
jz hd_err_return
cmp [fat32part],0 ; is partition set?
jnz @f
hd_err_return:
call free_hd_channel
and [hd1_status], 0
jmp file_system_return
@@:
cmp dword [esp+20],0 ; READ
jne fs_noharddisk_read
mov eax,[esp+0] ; /fname
lea edi,[eax+12]
mov byte [eax],0 ; path to asciiz
inc eax ; filename start
mov ebx,[esp+12] ; count to read
mov ecx,[esp+8] ; buffer
mov edx,[esp+4]
add edx,12*2 ; dir start
sub edi,edx ; path length
mov esi,[esp+16] ; blocks to read
call file_read
mov edi,[esp+0]
mov byte [edi],'/'
call free_hd_channel
and [hd1_status], 0
jmp file_system_return
fs_noharddisk_read:
cmp dword [esp+20],1 ; WRITE
jne fs_noharddisk_write
mov eax,[esp+0] ; /fname
mov byte [eax],0 ; path to asciiz
inc eax ; filename start
mov ebx,[esp+12] ; count to write
mov ecx,[esp+8] ; buffer
mov edx,[esp+4]
add edx,12*2 ; path start
call file_write
mov edi,[esp+0]
mov byte [edi],'/'
; eax=0 ok - eax=1 not enough free space
call free_hd_channel
and [hd1_status], 0
jmp file_system_return
fs_noharddisk_write:
call free_hd_channel
and [hd1_status], 0
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:
call reserve_hd1
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
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 err
mov bx,cx
shl cx,1
jc err
shl cx,1
jc err
add cx,bx
jc err
cbw
add cx,ax
jc err
i3:
inc edi
jmp i1
i_exit:
mov ax,cx
clc
i4:
movzx eax,ax
pop edi
pop dx
pop cx
pop bx
ret
err:
stc
jmp i4
partition_string: dd 0
db 32

View File

@ -0,0 +1,678 @@
; System function 70 - files with long names (LFN)
; diamond, 2006
iglobal
; in this table names must be in lowercase
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,'hd0'
dd fs_OnHd0
dd fs_NextHd0
db 3,'hd1'
dd fs_OnHd1
dd fs_NextHd1
db 3,'hd2'
dd fs_OnHd2
dd fs_NextHd2
db 3,'hd3'
dd fs_OnHd3
dd fs_NextHd3
;**********************************************
db 3,'cd0'
dd fs_OnCd0
dd fs_NextCd
db 3,'cd1'
dd fs_OnCd1
dd fs_NextCd
db 3,'cd2'
dd fs_OnCd2
dd fs_NextCd
db 3,'cd3'
dd fs_OnCd3
dd fs_NextCd
;***********************************************
db 0
virtual_root_query:
dd fs_HasRamdisk
db 'rd',0
dd fs_HasFloppy
db 'fd',0
dd fs_HasHd0
db 'hd0',0
dd fs_HasHd1
db 'hd1',0
dd fs_HasHd2
db 'hd2',0
dd fs_HasHd3
db 'hd3',0
;**********************************************
dd fs_HasCd0
db 'cd0',0
dd fs_HasCd1
db 'cd1',0
dd fs_HasCd2
db 'cd2',0
dd fs_HasCd3
db 'cd3',0
;**********************************************
dd 0
endg
file_system_lfn:
; in: eax->fileinfo block
; operation codes:
; 0 : read file
; 1 : read folder
; 2 : create/rewrite file
; 3 : write/append to file
; 4 : set end of file
; 5 : get file/directory attributes structure
; 6 : set file/directory attributes structure
; 7 : start application
; 8 : delete file
; 9 : create directory
add eax, std_application_base_address
; parse file name
xchg ebx, eax
lea esi, [ebx+20]
mov ebp, esi ; for 'start app' function full path must be known
lodsb
test al, al
jnz @f
mov esi, [esi]
add esi, std_application_base_address
mov ebp, esi
lodsb
@@:
cmp dword [ebx], 7
jne @F
mov edx, [ebx+4]
mov ebx, [ebx+8]
test ebx, ebx
jz .l1
add ebx, new_app_base
.l1:
call fs_execute ; ebp, ebx, edx
mov [esp+36], eax
ret
@@:
cmp al, '/'
jz @f
.notfound:
mov dword [esp+36], 5 ; file not found
ret
@@:
cmp byte [esi], 0
jz .rootdir
mov edi, rootdirs-8
xor ecx, ecx
push esi
.scan1:
pop esi
add edi, ecx
scasd
scasd
mov cl, byte [edi]
jecxz .notfound
inc edi
push esi
@@:
lodsb
or al, 20h
scasb
loopz @b
jnz .scan1
lodsb
cmp al, '/'
jz .found1
test al, al
jnz .scan1
pop eax
; directory /xxx
.maindir:
cmp dword [ebx], 1
jnz .access_denied
xor eax, eax
mov ebp, [ebx+12]
mov edx, [ebx+16]
add edx, std_application_base_address
push dword [ebx+4] ; first block
mov ebx, [ebx+8] ; flags
mov esi, [edi+4]
; ebx=flags, [esp]=first block, ebp=number of blocks, edx=return area, esi='Next' handler
mov edi, edx
mov ecx, 32/4
rep stosd
mov byte [edx], 1 ; version
.maindir_loop:
call esi
jc .maindir_done
inc dword [edx+8]
dec dword [esp]
jns .maindir_loop
dec ebp
js .maindir_loop
inc dword [edx+4]
mov dword [edi], 0x10 ; attributes: folder
mov dword [edi+4], 1 ; name type: UNICODE
push eax
xor eax, eax
add edi, 8
mov ecx, 40/4-2
rep stosd
pop eax
push eax edx
; convert number in eax to decimal UNICODE string
push edi
push -'0'
mov cl, 10
@@:
xor edx, edx
div ecx
push edx
test eax, eax
jnz @b
@@:
pop eax
add al, '0'
stosb
test bl, 1 ; UNICODE name?
jz .ansi2
mov byte [edi], 0
inc edi
.ansi2:
test al, al
jnz @b
mov byte [edi-1], 0
pop edi
; UNICODE name length is 520 bytes, ANSI - 264
add edi, 520
test bl, 1
jnz @f
sub edi, 520-264
@@:
pop edx eax
jmp .maindir_loop
.maindir_done:
pop eax
mov ebx, [edx+4]
xor eax, eax
dec ebp
js @f
mov al, ERROR_END_OF_FILE
@@:
mov [esp+36], eax
mov [esp+24], ebx
ret
; directory /
.rootdir:
cmp dword [ebx], 1 ; read folder?
jz .readroot
.access_denied:
mov dword [esp+36], 10 ; access denied
ret
.readroot:
; virtual root folder - special handler
mov esi, virtual_root_query
mov ebp, [ebx+12]
mov edx, [ebx+16]
add edx, std_application_base_address
push dword [ebx+4] ; first block
mov ebx, [ebx+8] ; flags
xor eax, eax
; eax=0, [esp]=first block, ebx=flags, ebp=number of blocks, edx=return area
mov edi, edx
mov ecx, 32/4
rep stosd
mov byte [edx], 1 ; version
.readroot_loop:
cmp dword [esi], eax
jz .readroot_done
call dword [esi]
add esi, 4
test eax, eax
jnz @f
.readroot_next:
or ecx, -1
xchg esi, edi
repnz scasb
xchg esi, edi
jmp .readroot_loop
@@:
xor eax, eax
inc dword [edx+8]
dec dword [esp]
jns .readroot_next
dec ebp
js .readroot_next
inc dword [edx+4]
mov dword [edi], 0x10 ; attributes: folder
mov dword [edi+4], 1 ; name type: UNICODE
add edi, 8
mov ecx, 40/4-2
rep stosd
push edi
@@:
lodsb
stosb
test bl, 1
jz .ansi
mov byte [edi], 0
inc edi
.ansi:
test eax, eax
jnz @b
pop edi
add edi, 520
test bl, 1
jnz .readroot_loop
sub edi, 520-264
jmp .readroot_loop
.readroot_done:
pop eax
mov ebx, [edx+4]
xor eax, eax
dec ebp
js @f
mov al, ERROR_END_OF_FILE
@@:
mov [esp+36], eax
mov [esp+24], ebx
ret
.found1:
pop eax
cmp byte [esi], 0
jz .maindir
; read partition number
xor ecx, ecx
xor eax, eax
@@:
lodsb
cmp al, '/'
jz .done1
test al, al
jz .done1
sub al, '0'
cmp al, 9
ja .notfound
imul ecx, 10
add ecx, eax
jmp @b
.done1:
test ecx, ecx
jz .notfound
test al, al
jnz @f
dec esi
@@:
; now [edi] contains handler address, ecx - partition number,
; esi points to ASCIIZ string - rest of name
jmp dword [edi]
; handlers for devices
; in: ecx = 0 => query virtual directory /xxx
; in: ecx = partition number
; esi -> relative (for device) name
; ebx -> fileinfo
; out: [esp+36]=image of eax, [esp+24]=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 [esp+36], eax
mov [esp+24], ebx
ret
.not_impl:
mov dword [esp+36], 2 ; not implemented
ret
fs_NotImplemented:
mov eax, 2
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 ;fs_RamdiskExecute
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 [esp+36], eax
mov [esp+24], 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 ;fs_FloppyExecute
dd fs_FloppyDelete
dd fs_FloppyCreateFolder
fs_NumFloppyServices = ($ - fs_FloppyServices)/4
fs_OnHd0:
call reserve_hd1
mov [hdbase], 0x1F0
mov [hdid], 0
push 1
jmp fs_OnHd
fs_OnHd1:
call reserve_hd1
mov [hdbase], 0x1F0
mov [hdid], 0x10
push 2
jmp fs_OnHd
fs_OnHd2:
call reserve_hd1
mov [hdbase], 0x170
mov [hdid], 0
push 3
jmp fs_OnHd
fs_OnHd3:
call reserve_hd1
mov [hdbase], 0x170
mov [hdid], 0x10
push 4
fs_OnHd:
call reserve_hd_channel
pop eax
mov [hdpos], eax
cmp ecx, 0x100
jae .nf
cmp cl, [0x40001+eax]
jbe @f
.nf:
call free_hd_channel
and [hd1_status], 0
mov dword [esp+36], 5 ; not found
ret
@@:
mov [fat32part], ecx
push ebx esi
call choice_necessity_partition_1
pop esi ebx
mov ecx, [ebx+12]
mov edx, [ebx+16]
add edx, std_application_base_address
mov eax, [ebx]
cmp eax, fs_NumHdServices
jae .not_impl
add ebx, 4
call dword [fs_HdServices + eax*4]
call free_hd_channel
and [hd1_status], 0
mov [esp+36], eax
mov [esp+24], ebx
ret
.not_impl:
call free_hd_channel
and [hd1_status], 0
mov dword [esp+36], 2 ; not implemented
ret
fs_HdServices:
dd fs_HdRead
dd fs_HdReadFolder
dd fs_HdRewrite
dd fs_HdWrite
dd fs_HdSetFileEnd
dd fs_HdGetFileInfo
dd fs_HdSetFileInfo
dd 0 ;fs_HdExecute
dd fs_HdDelete
dd fs_HdCreateFolder
fs_NumHdServices = ($ - fs_HdServices)/4
;*******************************************************
fs_OnCd0:
call reserve_cd
mov [ChannelNumber],1
mov [DiskNumber],0
push 6
jmp fs_OnCd
fs_OnCd1:
call reserve_cd
mov [ChannelNumber],1
mov [DiskNumber],1
push 4
jmp fs_OnCd
fs_OnCd2:
call reserve_cd
mov [ChannelNumber],2
mov [DiskNumber],0
push 2
jmp fs_OnCd
fs_OnCd3:
call reserve_cd
mov [ChannelNumber],2
mov [DiskNumber],1
push 0
fs_OnCd:
call reserve_cd_channel
pop eax
mov [hdpos], eax
cmp ecx, 0x100
jae .nf
push ecx ebx
mov cl,al
mov bl,[0x40001]
shr bl,cl
test bl,2
pop ebx ecx
jnz @f
.nf:
call free_cd_channel
and [cd_status], 0
mov dword [esp+36], 5 ; not found
ret
@@:
mov ecx, [ebx+12]
mov edx, [ebx+16]
add edx, std_application_base_address
mov eax, [ebx]
cmp eax,fs_NumCdServices
jae .not_impl
add ebx, 4
call dword [fs_CdServices + eax*4]
call free_cd_channel
and [cd_status], 0
mov [esp+36], eax
mov [esp+24], ebx
ret
.not_impl:
call free_cd_channel
and [cd_status], 0
mov dword [esp+36], 2 ; not implemented
ret
fs_CdServices:
dd fs_CdRead
dd fs_CdReadFolder
dd fs_NotImplemented
dd fs_NotImplemented
dd fs_NotImplemented
dd fs_CdGetFileInfo
dd fs_NotImplemented
dd fs_CdExecute
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_HasHd0:
mov al, [DRIVE_DATA+1]
and al, 11000000b
cmp al, 01000000b
setz al
ret
fs_HasHd1:
mov al, [DRIVE_DATA+1]
and al, 00110000b
cmp al, 00010000b
setz al
ret
fs_HasHd2:
mov al, [DRIVE_DATA+1]
and al, 00001100b
cmp al, 00000100b
setz al
ret
fs_HasHd3:
mov al, [DRIVE_DATA+1]
and al, 00000011b
cmp al, 00000001b
setz al
ret
;*******************************************************
fs_HasCd0:
mov al, [DRIVE_DATA+1]
and al, 11000000b
cmp al, 10000000b
setz al
ret
fs_HasCd1:
mov al, [DRIVE_DATA+1]
and al, 00110000b
cmp al, 00100000b
setz al
ret
fs_HasCd2:
mov al, [DRIVE_DATA+1]
and al, 00001100b
cmp al, 00001000b
setz al
ret
fs_HasCd3:
mov al, [DRIVE_DATA+1]
and al, 00000011b
cmp al, 00000010b
setz al
ret
;*******************************************************
; fs_NextXXX functions:
; in: eax = partition number, from which start to scan
; out: CF=1 => no more partitions
; 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
; on hdx, we have partitions from 1 to [0x40002+x]
fs_NextHd0:
push 0
jmp fs_NextHd
fs_NextHd1:
push 1
jmp fs_NextHd
fs_NextHd2:
push 2
jmp fs_NextHd
fs_NextHd3:
push 3
fs_NextHd:
pop ecx
movzx ecx, byte [DRIVE_DATA+2+ecx]
cmp eax, ecx
jae fs_NextFloppy.no2
inc eax
clc
ret
;*******************************************************
fs_NextCd:
; we always have /cdX/1
test eax, eax
stc
jnz @f
mov al, 1
clc
@@:
ret
;*******************************************************

View File

@ -0,0 +1,826 @@
uglobal
cd_current_pointer_of_input dd 0
cd_current_pointer_of_input_2 dd 0
cd_mem_location dd 0
cd_counter_block dd 0
IDE_Channel_1 db 0
IDE_Channel_2 db 0
endg
CDDataBuf equ 0x7000
reserve_cd:
cli
cmp [cd_status],0
je reserve_ok2
sti
call change_task
jmp reserve_cd
reserve_ok2:
push eax
mov eax,[CURRENT_TASK]
shl eax,5
mov eax,[eax+CURRENT_TASK+TASKDATA.pid]
mov [cd_status],eax
pop eax
sti
ret
reserve_cd_channel:
cmp [ChannelNumber],1
jne .IDE_Channel_2
.IDE_Channel_1:
cli
cmp [IDE_Channel_1],0
je .reserve_ok_1
sti
call change_task
jmp .IDE_Channel_1
.IDE_Channel_2:
cli
cmp [IDE_Channel_2],0
je .reserve_ok_2
sti
call change_task
jmp .IDE_Channel_1
.reserve_ok_1:
mov [IDE_Channel_1],1
ret
.reserve_ok_2:
mov [IDE_Channel_2],1
ret
free_cd_channel:
cmp [ChannelNumber],1
jne .IDE_Channel_2
.IDE_Channel_1:
mov [IDE_Channel_1],0
ret
.IDE_Channel_2:
mov [IDE_Channel_2],0
ret
uglobal
cd_status dd 0
endg
;----------------------------------------------------------------
;
; fs_CdRead - LFN variant for reading CD disk
;
; esi points to filename /dir1/dir2/.../dirn/file,0
; ebx pointer to 64-bit number = first wanted byte, 0+
; may be ebx=0 - start from first byte
; ecx number of bytes to read, 0+
; edx mem location to return data
;
; ret ebx = bytes read or 0xffffffff file not found
; eax = 0 ok read or other = errormsg
;
;--------------------------------------------------------------
fs_CdRead:
push edi
cmp byte [esi], 0
jnz @f
.noaccess:
pop edi
.noaccess_2:
or ebx, -1
mov eax, ERROR_ACCESS_DENIED
ret
.noaccess_3:
pop eax edx ecx edi
jmp .noaccess_2
@@:
call cd_find_lfn
jnc .found
pop edi
cmp [DevErrorCode],0
jne .noaccess_2
or ebx, -1
mov eax, ERROR_FILE_NOT_FOUND
ret
.found:
mov edi,[cd_current_pointer_of_input]
test byte [edi+25],10b ; do not allow read directories
jnz .noaccess
test ebx, ebx
jz .l1
cmp dword [ebx+4], 0
jz @f
xor ebx, ebx
.reteof:
mov eax, 6 ; end of file
pop edi
ret
@@:
mov ebx, [ebx]
.l1:
push ecx edx
push 0
mov eax, [edi+10] ; ðåàëüíûé ðàçìåð ôàéëîâîé ñåêöèè
sub eax, ebx
jb .eof
cmp eax, ecx
jae @f
mov ecx, eax
mov byte [esp], 6
@@:
mov eax,[edi+2]
mov [CDSectorAddress],eax
; now eax=cluster, ebx=position, ecx=count, edx=buffer for data
.new_sector:
test ecx, ecx
jz .done
sub ebx, 2048
jae .next
add ebx, 2048
jnz .incomplete_sector
cmp ecx, 2048
jb .incomplete_sector
; we may read and memmove complete sector
mov [CDDataBuf_pointer],edx
call ReadCDWRetr ; ÷èòàåì ñåêòîð ôàéëà
cmp [DevErrorCode],0
jne .noaccess_3
add edx, 2048
sub ecx, 2048
.next:
inc dword [CDSectorAddress]
jmp .new_sector
.incomplete_sector:
; we must read and memmove incomplete sector
mov [CDDataBuf_pointer],CDDataBuf
call ReadCDWRetr ; ÷èòàåì ñåêòîð ôàéëà
cmp [DevErrorCode],0
jne .noaccess_3
push ecx
add ecx, ebx
cmp ecx, 2048
jbe @f
mov ecx, 2048
@@:
sub ecx, ebx
push edi esi ecx
mov edi,edx
lea esi, [CDDataBuf + ebx]
cld
rep movsb
pop ecx esi edi
add edx, ecx
sub [esp], ecx
pop ecx
xor ebx, ebx
jmp .next
.done:
mov ebx, edx
pop eax edx ecx edi
sub ebx, edx
ret
.eof:
mov ebx, edx
pop eax edx ecx
sub ebx, edx
jmp .reteof
;----------------------------------------------------------------
;
; fs_CdReadFolder - LFN variant for reading CD disk folder
;
; esi points to filename /dir1/dir2/.../dirn/file,0
; ebx pointer to structure 32-bit number = first wanted block, 0+
; & flags (bitfields)
; flags: bit 0: 0=ANSI names, 1=UNICODE names
; ecx number of blocks to read, 0+
; edx mem location to return data
;
; ret ebx = blocks read or 0xffffffff folder not found
; eax = 0 ok read or other = errormsg
;
;--------------------------------------------------------------
fs_CdReadFolder:
push edi
call cd_find_lfn
jnc .found
pop edi
cmp [DevErrorCode], 0
jne .noaccess_1
or ebx, -1
mov eax, ERROR_FILE_NOT_FOUND
ret
.found:
mov edi, [cd_current_pointer_of_input]
test byte [edi+25], 10b ; do not allow read directories
jnz .found_dir
pop edi
.noaccess_1:
or ebx, -1
mov eax, ERROR_ACCESS_DENIED
ret
.found_dir:
mov eax, [edi+2] ; eax=cluster
mov [CDSectorAddress], eax
mov eax, [edi+10] ; ðàçìåð äèðåêòðîðèè
.doit:
; init header
push eax ecx
mov edi, edx
mov ecx, 32/4
xor eax, eax
rep stosd
pop ecx eax
mov byte [edx], 1 ; version
mov [cd_mem_location], edx
add [cd_mem_location], 32
; íà÷èíàåì ïåðåáðîñêó ÁÄÂÊ â ÓÑÂÊ
;.mainloop:
mov [cd_counter_block], dword 0
dec dword [CDSectorAddress]
push ecx
.read_to_buffer:
inc dword [CDSectorAddress]
mov [CDDataBuf_pointer], CDDataBuf
call ReadCDWRetr ; ÷èòàåì ñåêòîð äèðåêòîðèè
cmp [DevErrorCode], 0
jne .noaccess_1
call .get_names_from_buffer
sub eax,2048
; äèðåêòîðèÿ çàêîí÷èëàñü?
ja .read_to_buffer
mov edi, [cd_counter_block]
mov [edx+8], edi
mov edi, [ebx]
sub [edx+4], edi
xor eax, eax
dec ecx
js @f
mov al, ERROR_END_OF_FILE
@@:
pop ecx edi
mov ebx, [edx+4]
ret
.get_names_from_buffer:
mov [cd_current_pointer_of_input_2],CDDataBuf
push eax esi edi edx
.get_names_from_buffer_1:
call cd_get_name
jc .end_buffer
inc dword [cd_counter_block]
mov eax,[cd_counter_block]
cmp [ebx],eax
jae .get_names_from_buffer_1
test ecx, ecx
jz .get_names_from_buffer_1
mov edi,[cd_counter_block]
mov [edx+4],edi
dec ecx
mov esi,ebp
mov edi,[cd_mem_location]
add edi,40
test dword [ebx+4], 1 ; 0=ANSI, 1=UNICODE
jnz .unicode
; jmp .unicode
.ansi:
cmp [cd_counter_block],2
jbe .ansi_parent_directory
cld
lodsw
xchg ah,al
call uni2ansi_char
cld
stosb
; ïðîâåðêà êîíöà ôàéëà
mov ax,[esi]
cmp ax,word 3B00h ; ñåïàðàòîð êîíöà ôàéëà ';'
je .cd_get_parameters_of_file_1
; ïðîâåðêà äëÿ ôàéëîâ íå çàêàí÷èâàþùèõñÿ ñåïàðàòîðîì
movzx eax,byte [ebp-33]
add eax,ebp
sub eax,34
cmp esi,eax
je .cd_get_parameters_of_file_1
; ïðîâåðêà êîíöà ïàïêè
movzx eax,byte [ebp-1]
add eax,ebp
cmp esi,eax
jb .ansi
.cd_get_parameters_of_file_1:
mov [edi],byte 0
call cd_get_parameters_of_file
add [cd_mem_location],304
jmp .get_names_from_buffer_1
.ansi_parent_directory:
cmp [cd_counter_block],2
je @f
mov [edi],byte '.'
inc edi
jmp .cd_get_parameters_of_file_1
@@:
mov [edi],word '..'
add edi,2
jmp .cd_get_parameters_of_file_1
.unicode:
cmp [cd_counter_block],2
jbe .unicode_parent_directory
cld
movsw
; ïðîâåðêà êîíöà ôàéëà
mov ax,[esi]
cmp ax,word 3B00h ; ñåïàðàòîð êîíöà ôàéëà ';'
je .cd_get_parameters_of_file_2
; ïðîâåðêà äëÿ ôàéëîâ íå çàêàí÷èâàþùèõñÿ ñåïàðàòîðîì
movzx eax,byte [ebp-33]
add eax,ebp
sub eax,34
cmp esi,eax
je .cd_get_parameters_of_file_2
; ïðîâåðêà êîíöà ïàïêè
movzx eax,byte [ebp-1]
add eax,ebp
cmp esi,eax
jb .unicode
.cd_get_parameters_of_file_2:
mov [edi],word 0
call cd_get_parameters_of_file
add [cd_mem_location],560
jmp .get_names_from_buffer_1
.unicode_parent_directory:
cmp [cd_counter_block],2
je @f
mov [edi],word 2E00h ; '.'
add edi,2
jmp .cd_get_parameters_of_file_2
@@:
mov [edi],dword 2E002E00h ; '..'
add edi,4
jmp .cd_get_parameters_of_file_2
.end_buffer:
pop edx edi esi eax
ret
cd_get_parameters_of_file:
mov edi,[cd_mem_location]
cd_get_parameters_of_file_1:
; ïîëó÷àåì àòðèáóòû ôàéëà
xor eax,eax
; ôàéë íå àðõèâèðîâàëñ
inc al
shl eax,1
; ýòî êàòàëîã?
test [ebp-8],byte 2
jz .file
inc al
.file:
; ìåòêà òîìà íå êàê â FAT, â ýòîì âèäå îòñóòñâóåò
; ôàéë íå ÿâëÿåòñÿ ñèñòåìíûì
shl eax,3
; ôàéë ÿâëÿåòñÿ ñêðûòûì? (àòðèáóò ñóùåñòâîâàíèå)
test [ebp-8],byte 1
jz .hidden
inc al
.hidden:
shl eax,1
; ôàéë âñåãäà òîëüêî äëÿ ÷òåíèÿ, òàê êàê ýòî CD
inc al
mov [edi],eax
; ïîëó÷àåì âðåìÿ äëÿ ôàéëà
;÷àñ
movzx eax,byte [ebp-12]
shl eax,8
;ìèíóòà
mov al,[ebp-11]
shl eax,8
;ñåêóíäà
mov al,[ebp-10]
;âðåìÿ ñîçäàíèÿ ôàéëà
mov [edi+8],eax
;âðåìÿ ïîñëåäíåãî äîñòóïà
mov [edi+16],eax
;âðåìÿ ïîñëåäíåé çàïèñè
mov [edi+24],eax
; ïîëó÷àåì äàòó äëÿ ôàéëà
;ãîä
movzx eax,byte [ebp-15]
add eax,1900
shl eax,8
;ìåñÿö
mov al,[ebp-14]
shl eax,8
;äåíü
mov al,[ebp-13]
;äàòà ñîçäàíèÿ ôàéëà
mov [edi+12],eax
;âðåìÿ ïîñëåäíåãî äîñòóïà
mov [edi+20],eax
;âðåìÿ ïîñëåäíåé çàïèñè
mov [edi+28],eax
; ïîëó÷àåì òèï äàííûõ èìåíè
xor eax,eax
test dword [ebx+4], 1 ; 0=ANSI, 1=UNICODE
jnz .unicode_1
mov [edi+4],eax
jmp @f
.unicode_1:
inc eax
mov [edi+4],eax
@@:
; ïîëó÷àåì ðàçìåð ôàéëà â áàéòàõ
xor eax,eax
mov [edi+32+4],eax
mov eax,[ebp-23]
mov [edi+32],eax
ret
;----------------------------------------------------------------
;
; fs_CdGetFileInfo - LFN variant for CD
; get file/directory attributes structure
;
;----------------------------------------------------------------
fs_CdGetFileInfo:
cmp byte [esi], 0
jnz @f
mov eax, 2
ret
@@:
push edi ebp
call cd_find_lfn
pushfd
cmp [DevErrorCode], 0
jz @f
popfd
pop ebp edi
mov eax, 11
ret
@@:
popfd
jnc @f
pop ebp edi
mov eax, ERROR_FILE_NOT_FOUND
ret
@@:
mov edi, edx
call cd_get_parameters_of_file_1
and dword [edi+4], 0
pop ebp edi
xor eax, eax
ret
;----------------------------------------------------------------
;
; fs_CdExecute - LFN variant for executing from CD
;
; esi points to hd filename (e.g. 'dir1/name')
; ebp points to full filename (e.g. '/hd0/1/dir1/name')
; dword [ebx] = flags
; dword [ebx+4] = cmdline
;
; ret ebx,edx destroyed
; eax > 0 - PID, < 0 - error
;
;--------------------------------------------------------------
fs_CdExecute:
mov edx, [ebx]
mov ebx, [ebx+4]
test ebx, ebx
jz @f
add ebx, std_application_base_address
@@:
;----------------------------------------------------------------
;
; fs_CdExecute.flags - second entry
;
; esi points to floppy filename (kernel address)
; ebp points to full filename
; edx flags
; ebx cmdline (kernel address)
;
; ret eax > 0 - PID, < 0 - error
;
;--------------------------------------------------------------
.flags:
cmp byte [esi], 0
jnz @f
; cannot execute root!
mov eax, -ERROR_ACCESS_DENIED
ret
@@:
push edi
call cd_find_lfn
jnc .found
pop edi
mov eax, -ERROR_FILE_NOT_FOUND
cmp [DevErrorCode], 0
jz @f
mov al, -11
@@:
ret
.found:
mov edi,[cd_current_pointer_of_input]
mov eax,[edi+2]
push 0
push eax
push dword [edi+10] ; size
push .DoRead
call fs_execute
add esp, 16
pop edi
ret
.DoRead:
; read next block
; in: eax->parameters, edi->buffer
; out: eax = error code
pushad
cmp dword [eax], 0 ; file size
jz .eof
cmp [eax+8],dword 0
jne @f
mov ecx,[eax+4]
inc dword [eax+4]
mov [CDSectorAddress],ecx
mov [CDDataBuf_pointer],CDDataBuf ;edi
call ReadCDWRetr
cmp [DevErrorCode], 0
jnz .err
@@:
push esi edi ecx
mov esi,512
imul esi,[eax+8]
add esi,CDDataBuf
mov ecx,512/4
cld
rep movsd
pop ecx edi esi
mov eax, [esp+28]
mov ecx, [eax]
sub ecx, 512
jae @f
lea edi, [edi+ecx+512]
neg ecx
push eax
xor eax, eax
rep stosb
pop eax
@@:
mov [eax], ecx
mov edx, [eax+8]
inc edx
cmp edx, 4 ; 2048/512=4
jb @f
xor edx, edx
@@:
mov [eax+8], edx
popad
xor eax, eax
ret
.eof:
popad
mov eax, 6
ret
.err:
popad
mov eax, 11
ret
cd_find_lfn:
; in: esi->name
; out: CF=1 - file not found
; else CF=0 and [cd_current_pointer_of_input] direntry
push eax esi
; 16 ñåêòîð íà÷àëî íàáîðà äåñêðèïòîðîâ òîìîâ
mov [CDSectorAddress],dword 15
.start:
inc dword [CDSectorAddress]
mov [CDDataBuf_pointer],CDDataBuf
call ReadCDWRetr
cmp [DevErrorCode],0
jne .access_denied
; ïðîâåðêà íà âøèâîñòü
cmp [CDDataBuf+1],dword 'CD00'
jne .access_denied
cmp [CDDataBuf+5],byte '1'
jne .access_denied
; ñåêòîð ÿâëÿåòñÿ òåðìèíàòîðîì íàáîð äåñêðèïòîðîâ òîìîâ?
cmp [CDDataBuf],byte 0xff
je .access_denied
; ñåêòîð ÿâëÿåòñÿ äîïîëíèòåëüíûì è óëó÷øåííûì äåñêðèïòîðîì òîìà?
cmp [CDDataBuf],byte 0x2
jne .start
; ñåêòîð ÿâëÿåòñÿ äîïîëíèòåëüíûì äåñêðèïòîðîì òîìà?
cmp [CDDataBuf+6],byte 0x1
jne .start
; ïàðàìåòðû root äèðåêòðîðèè
mov eax,[CDDataBuf+0x9c+2] ; íà÷àëî root äèðåêòðîðèè
mov [CDSectorAddress],eax
mov eax,[CDDataBuf+0x9c+10] ; ðàçìåð root äèðåêòðîðèè
cmp byte [esi], 0
jnz @f
mov [cd_current_pointer_of_input],CDDataBuf+0x9c
jmp .done
@@:
; íà÷èíàåì ïîèñê
.mainloop:
dec dword [CDSectorAddress]
.read_to_buffer:
inc dword [CDSectorAddress]
mov [CDDataBuf_pointer],CDDataBuf
call ReadCDWRetr ; ÷èòàåì ñåêòîð äèðåêòîðèè
cmp [DevErrorCode],0
jne .access_denied
call cd_find_name_in_buffer
jnc .found
sub eax,2048
; äèðåêòîðèÿ çàêîí÷èëàñü?
cmp eax,0
ja .read_to_buffer
; íåò èñêîìîãî ýëåìåíòà öåïî÷êè
.access_denied:
pop esi eax
stc
ret
; èñêîìûé ýëåìåíò öåïî÷êè íàéäåí
.found:
; êîíåö ïóòè ôàéëà
cmp byte [esi-1], 0
jz .done
mov eax,[cd_current_pointer_of_input]
push dword [eax+2]
pop dword [CDSectorAddress] ; íà÷àëî äèðåêòîðèè
mov eax,[eax+2+8] ; ðàçìåð äèðåêòîðèè
jmp .mainloop
; óêàçàòåëü ôàéëà íàéäåí
.done:
pop esi eax
clc
ret
cd_find_name_in_buffer:
mov [cd_current_pointer_of_input_2],CDDataBuf
.start:
call cd_get_name
jc .not_found
call cd_compare_name
jc .start
.found:
clc
ret
.not_found:
stc
ret
cd_get_name:
push eax
mov ebp,[cd_current_pointer_of_input_2]
mov [cd_current_pointer_of_input],ebp
mov eax,[ebp]
cmp eax,0 ; âõîäû çàêîí÷èëèñü?
je .next_sector
cmp ebp,CDDataBuf+2048 ; áóôåð çàêîí÷èëñÿ?
jae .next_sector
movzx eax, byte [ebp]
add [cd_current_pointer_of_input_2],eax ; ñëåäóþùèé âõîä êàòàëîãà
add ebp,33 ; óêàçàòåëü óñòàíîâëåí íà íà÷àëî èìåíè
pop eax
clc
ret
.next_sector:
pop eax
stc
ret
cd_compare_name:
; compares ASCIIZ-names, case-insensitive (cp866 encoding)
; in: esi->name, ebp->name
; out: if names match: ZF=1 and esi->next component of name
; else: ZF=0, esi is not changed
; destroys eax
push esi eax edi
mov edi,ebp
.loop:
cld
lodsb
push ax
call char_todown
call ansi2uni_char
xchg ah,al
cld
scasw
pop ax
je .coincides
call char_toupper
call ansi2uni_char
xchg ah,al
cld
sub edi,2
scasw
jne .name_not_coincide
.coincides:
cmp [esi],byte '/' ; ðàçäåëèòåëü ïóòè, êîíåö èìåíè òåêóùåãî ýëåìåíòà
je .done
cmp [esi],byte 0 ; ðàçäåëèòåëü ïóòè, êîíåö èìåíè òåêóùåãî ýëåìåíòà
je .done
jmp .loop
.name_not_coincide:
pop edi eax esi
stc
ret
.done:
; ïðîâåðêà êîíöà ôàéëà
cmp [edi],word 3B00h ; ñåïàðàòîð êîíöà ôàéëà ';'
je .done_1
; ïðîâåðêà äëÿ ôàéëîâ íå çàêàí÷èâàþùèõñÿ ñåïàðàòîðîì
movzx eax,byte [ebp-33]
add eax,ebp
sub eax,34
cmp edi,eax
je .done_1
; ïðîâåðêà êîíöà ïàïêè
movzx eax,byte [ebp-1]
add eax,ebp
cmp edi,eax
jne .name_not_coincide
.done_1:
pop edi eax
add esp,4
inc esi
clc
ret
char_todown:
; convert character to uppercase, using cp866 encoding
; in: al=symbol
; out: al=converted symbol
cmp al, 'A'
jb .ret
cmp al, 'Z'
jbe .az
cmp al, '€'
jb .ret
cmp al, '<27>'
jb .rus1
cmp al, 'Ÿ'
ja .ret
; 0x90-0x9F -> 0xE0-0xEF
add al, 'à'-'<27>'
.ret:
ret
.rus1:
; 0x80-0x8F -> 0xA0-0xAF
.az:
add al, 0x20
ret
uni2ansi_char:
; convert UNICODE character in al to ANSI character in ax, using cp866 encoding
; in: ax=UNICODE character
; out: al=converted ANSI character
cmp ax, 0x80
jb .ascii
cmp ax, 0x401
jz .yo1
cmp ax, 0x451
jz .yo2
cmp ax, 0x410
jb .unk
cmp ax, 0x440
jb .rus1
cmp ax, 0x450
jb .rus2
.unk:
mov al, '_'
jmp .doit
.yo1:
mov al, 'ð'
jmp .doit
.yo2:
mov al, 'ñ'
jmp .doit
.rus1:
; 0x410-0x43F -> 0x80-0xAF
add al, 0x70
jmp .doit
.rus2:
; 0x440-0x44F -> 0xE0-0xEF
add al, 0xA0
.ascii:
.doit:
ret

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,444 @@
;*************************************************************
;* 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 ; 0=none, 1=NTFS, 16=FAT16, 32=FAT32
align 4
fs_dependent_data_start:
; FATxx data
SECTORS_PER_FAT dd 0x1f3a
NUMBER_OF_FATS dd 0x2
SECTORS_PER_CLUSTER dd 0x8
BYTES_PER_SECTOR dd 0x200 ; Note: if BPS <> 512 need lots of changes
ROOT_CLUSTER dd 2 ; first rootdir cluster
FAT_START dd 0 ; start of fat table
ROOT_START dd 0 ; start of rootdir (only fat16)
ROOT_SECTORS dd 0 ; count of rootdir sectors (only fat16)
DATA_START dd 0 ; start of data area (=first cluster 2)
LAST_CLUSTER dd 0 ; last availabe cluster
ADR_FSINFO dd 0 ; used only by fat32
fatRESERVED dd 0x0FFFFFF6
fatBAD dd 0x0FFFFFF7
fatEND dd 0x0FFFFFF8
fatMASK dd 0x0FFFFFFF
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
;***************************************************************************
; 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
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 ; PARTITION2 ; PARTITION3 ; PARTITION4
;==========================================================
; fat16/32 +-- fat16/32 +-- fat16/32 +-- fat16/32 +--
; extended --+ extended --+ extended --+ extended --+
; 0 0 0 0
; 0 0 0 0
; Notes:
; - extended partition need to be in second entry on table
; - it will skip over removed partitions
set_FAT32_variables:
mov [problem_partition],0
call reserve_hd1
call reserve_hd_channel
cmp dword [hdpos],0
je problem_hd
pushad
xor ecx,ecx ; partition count
mov edx,-1 ; flag for partition
xor eax,eax ; read MBR
xor ebp,ebp ; extended partition start
new_partition:
test ebp,ebp ; is there extended partition?
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
cmp dword [ebx+0x1be+0xc],0 ; skip over empty partition
jz next_partition
push eax
mov al,[ebx+0x1be+4] ; get primary partition type
call scan_partition_types
pop eax
jnz next_primary_partition ; no. skip over
inc ecx
cmp ecx,[fat32part] ; is it wanted partition?
jnz next_primary_partition ; no
mov edx, eax ; start sector
add edx, [ebx+0x1be+8] ; add relative start
push edx
add edx, [ebx+0x1be+12] ; 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 dl, [ebx+0x1be+4]
mov [fs_type], dl ; save for FS recognizer (separate FAT vs NTFS)
pop edx
next_primary_partition:
push eax
mov al,[ebx+0x1be+4+16] ; get primary partition type
call scan_partition_types
pop eax
jnz next_primary_partition_1 ; no. skip over
inc ecx
cmp ecx,[fat32part] ; is it wanted partition?
jnz next_primary_partition_1 ; no
mov edx, eax
add edx, [ebx+0x1be+8+16]
push edx
add edx, [ebx+0x1be+12+16]
dec edx
mov [PARTITION_END], edx
mov dl, [ebx+0x1be+4+16]
mov [fs_type], dl
pop edx
next_primary_partition_1:
push eax
mov al,[ebx+0x1be+4+16+16] ; get primary partition type
call scan_partition_types
pop eax
jnz next_primary_partition_2 ; no. skip over
inc ecx
cmp ecx,[fat32part] ; is it wanted partition?
jnz next_primary_partition_2 ; no
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 dl, [ebx+0x1be+4+16+16]
mov [fs_type], dl
pop edx
next_primary_partition_2:
push eax
mov al,[ebx+0x1be+4+16+16+16] ; get primary partition type
call scan_partition_types
pop eax
jnz next_partition ; no. skip over
inc ecx
cmp ecx,[fat32part] ; is it wanted partition?
jnz next_partition ; no
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 dl, [ebx+0x1be+4+16+16+16]
mov [fs_type], dl
pop edx
next_partition:
push eax
mov al,[ebx+0x1be+4] ; get extended partition type
call scan_extended_types
pop eax
jnz next_partition_1
mov eax,[ebx+0x1be+8] ; add relative start
test eax,eax ; is there extended partition?
jnz new_partition ; yes. read it
next_partition_1:
push eax
mov al,[ebx+0x1be+4+16] ; get extended partition type
call scan_extended_types
pop eax
jnz next_partition_2
mov eax,[ebx+0x1be+8+16] ; add relative start
test eax,eax ; is there extended partition?
jnz new_partition ; yes. read it
next_partition_2:
push eax
mov al,[ebx+0x1be+4+16+16] ; get extended partition type
call scan_extended_types
pop eax
jnz next_partition_3
mov eax,[ebx+0x1be+8+16+16] ; add relative start
test eax,eax ; is there extended partition?
jnz new_partition ; yes. read it
next_partition_3:
push eax
mov al,[ebx+0x1be+4+16+16+16] ; get extended partition type
call scan_extended_types
pop eax
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_partition ; 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
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:
popad
problem_hd:
mov [fs_type],0
call free_hd_channel
mov [hd1_status],0 ; free
mov [problem_partition],1
ret
hd_and_partition_ok:
mov eax,edx
mov [PARTITION_START],eax
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 ; ­¥ áã¤ì¡ ...
boot_read_ok:
; mov [hd_setup], 0
; if we are running on NTFS, check bootsector
cmp [fs_type], 7
jz ntfs_setup
cmp word [ebx+0x1fe],0xaa55 ; is it valid boot sector?
jnz problem_fat_dec_count
movzx eax,word [ebx+0xe] ; sectors reserved
add eax,[PARTITION_START]
mov [FAT_START],eax ; fat_start = partition_start + reserved
movzx eax,byte [ebx+0xd] ; sectors per cluster
mov [SECTORS_PER_CLUSTER],eax
movzx ecx,word [ebx+0xb] ; bytes per sector
mov [BYTES_PER_SECTOR],ecx
movzx eax,word [ebx+0x11] ; count of rootdir entries (=0 fat32)
mov edx,32
mul edx
dec ecx
add eax,ecx ; round up if not equal count
inc ecx ; bytes per sector
div ecx
mov [ROOT_SECTORS],eax ; count of rootdir sectors
movzx eax,word [ebx+0x16] ; sectors per fat <65536
test eax,eax
jnz fat16_fatsize
mov eax,[ebx+0x24] ; sectors per fat
fat16_fatsize:
mov [SECTORS_PER_FAT],eax
movzx eax,byte [ebx+0x10] ; number of fats
test eax,eax ; if 0 it's not fat partition
jz problem_fat_dec_count
mov [NUMBER_OF_FATS],eax
imul eax,[SECTORS_PER_FAT]
add eax,[FAT_START]
mov [ROOT_START],eax ; rootdir = fat_start + fat_size * fat_count
add eax,[ROOT_SECTORS] ; rootdir sectors should be 0 on fat32
mov [DATA_START],eax ; data area = rootdir + rootdir_size
movzx eax,word [ebx+0x13] ; total sector count <65536
test eax,eax
jnz fat16_total
mov eax,[ebx+0x20] ; total sector count
fat16_total:
add eax,[PARTITION_START]
dec eax
mov [PARTITION_END],eax
inc eax
sub eax,[DATA_START] ; eax = count of data sectors
xor edx,edx
div dword [SECTORS_PER_CLUSTER]
inc eax
mov [LAST_CLUSTER],eax
dec eax ; cluster count
; limits by Microsoft Hardware White Paper v1.03
cmp eax,4085 ; 0xff5
jb problem_fat_dec_count ; fat12 not supported
cmp eax,65525 ; 0xfff5
jb fat16_partition
fat32_partition:
mov eax,[ebx+0x2c] ; rootdir cluster
mov [ROOT_CLUSTER],eax
movzx eax,word [ebx+0x30] ; fs info sector
add eax,[PARTITION_START]
mov [ADR_FSINFO],eax
popad
mov [fatRESERVED],0x0FFFFFF6
mov [fatBAD],0x0FFFFFF7
mov [fatEND],0x0FFFFFF8
mov [fatMASK],0x0FFFFFFF
mov [fs_type],32 ; Fat32
call free_hd_channel
mov [hd1_status],0 ; free
ret
fat16_partition:
xor eax,eax
mov [ROOT_CLUSTER],eax
popad
mov [fatRESERVED],0x0000FFF6
mov [fatBAD],0x0000FFF7
mov [fatEND],0x0000FFF8
mov [fatMASK],0x0000FFFF
mov [fs_type],16 ; Fat16
call free_hd_channel
mov [hd1_status],0 ; free
ret

View File

@ -0,0 +1,649 @@
max_buttons=4095
dececx:
push edx
push ecx
mov edx,2
.loop:
cmp byte [esp+edx],0x20
jae @f
mov [esp+edx],byte 0x20
@@:
sub [esp+edx],byte 0x20
dec edx
jns .loop
pop ecx
pop edx
ret
incecx:
push edx
push ecx
mov edx,2
.loop:
cmp byte [esp+edx],0xdf
jbe @f
mov [esp+edx],byte 0xdf
@@:
add [esp+edx],byte 0x20
dec edx
jns .loop
pop ecx
pop edx
ret
incecx2:
push edx
push ecx
mov edx,2
.loop:
cmp byte [esp+edx],0xeb
jbe @f
mov [esp+edx],byte 0xeb
@@:
add [esp+edx],byte 0x14
dec edx
jns .loop
pop ecx
pop edx
ret
drawbuttonframes:
push esi
push edi
push eax
push ebx
push ecx
push edx
shr eax,16
shr ebx,16
mov edx,[TASK_BASE]
add eax,[edx-twdw + WDATA.box.left]
add ebx,[edx-twdw + WDATA.box.top]
mov cx,ax
mov dx,bx
shl eax,16
shl ebx,16
mov ax,cx
mov bx,dx
add ax,word [esp+12]
mov esi,ebx
mov edi,0
mov ecx,[esp+0]
call incecx
call [draw_line]
movzx edx,word [esp+8]
add ebx,edx
shl edx,16
add ebx,edx
mov ecx,[esp+0]
call dececx
call [draw_line]
mov ebx,esi
push edx
mov edx,eax
shr edx,16
mov ax,dx
mov edx,ebx
shr edx,16
mov bx,dx
mov dx,[esp+8+4]
add bx,dx
pop edx
mov edi,0
mov ecx,[esp+0]
call incecx
call [draw_line]
mov esi,edx
mov dx,[esp+12]
add ax,dx
shl edx,16
add eax,edx
add ebx,1*65536
mov edx,esi
mov ecx,[esp+0]
call dececx
call [draw_line]
pop edx
pop ecx
pop ebx
pop eax
pop edi
pop esi
ret
button_dececx:
cmp [buttontype],dword 1
jne .finish
; je bdece
; ret
; bdece:
push eax
mov eax,0x01
cmp edi,20
jg @f
mov eax,0x02
@@:
test ecx,0xff
jz @f
sub ecx,eax
@@:
shl eax,8
test ecx,0xff00
jz @f
sub ecx,eax
@@:
shl eax,8
test ecx,0xff0000
jz @f
sub ecx,eax
@@:
pop eax
.finish:
ret
sys_button:
push edi
mov edi,[CURRENT_TASK]
shl edi,8
rol eax,16
add ax,word[edi+SLOT_BASE+APPDATA.wnd_clientbox.left]
rol eax,16
rol ebx,16
add bx,word[edi+SLOT_BASE+APPDATA.wnd_clientbox.top]
rol ebx,16
pop edi
.forced:
test ecx,0x80000000
jnz remove_button
push esi
push edi
push eax ; <x,xs>
push ebx ; <y,ys>
push ecx ; <id>
push edx
or ax,ax
jle noaddbutt
or bx,bx
jle noaddbutt
test ecx,0x40000000
jnz button_no_draw
pushad ; button body
push ebx
sar eax,16
sar ebx,16
mov edx,[TASK_BASE]
mov esi,[edx-twdw + WDATA.box.left]
mov edi,[edx-twdw + WDATA.box.top]
add eax,esi
add ebx,edi
mov cx,ax
mov dx,bx
shl eax,16
shl ebx,16
mov ax,cx
mov bx,dx
add ax,[4+32+esp+12]
mov ecx,[4+32+esp+0]
cmp [buttontype],dword 0
je @f
call incecx2
@@:
movzx edi,word [esp]
pop edx
and edx, 0xFFFF
.newline:
call button_dececx
push edi
xor edi, edi
call [draw_line]
pop edi
inc bx
rol ebx,16
inc bx
dec edx
jnz .newline
popad
call drawbuttonframes
button_no_draw:
and ecx,0xffff
mov edi,[BTN_ADDR]
movzx eax,word [edi]
cmp eax,max_buttons
jge noaddbutt
inc eax
mov [edi],ax
shl eax,4
add eax,edi
mov bx,[CURRENT_TASK]
mov [eax],bx
add eax,2 ; save button id number
mov ebx,[esp+4]
mov [eax],bx ; bits 0-15
shr ebx,16
mov [eax-2+0xc],bx; bits 16-31
add eax,2 ; x start
mov bx,[esp+12+2]
mov [eax],bx
add eax,2 ; x size
mov bx,[esp+12+0]
mov [eax],bx
add eax,2 ; y start
mov bx,[esp+8+2]
mov [eax],bx
add eax,2 ; y size
mov bx,[esp+8+0]
mov [eax],bx
noaddbutt:
pop edx
pop ecx
pop ebx
pop eax
pop edi
pop esi
ret
remove_button:
and ecx,0x7fffffff
rnewba2:
mov edi,[BTN_ADDR]
mov eax,edi
movzx ebx,word [edi]
inc bx
rnewba:
dec bx
jz rnmba
add eax,0x10
mov dx,[CURRENT_TASK]
cmp dx,[eax]
jnz rnewba
cmp cx,[eax+2]
jnz rnewba
pushad
mov ecx,ebx
inc ecx
shl ecx,4
mov ebx,eax
add eax,0x10
call memmove
dec dword [edi]
popad
jmp rnewba2
rnmba:
ret
find_pressed_button_frames:
pushad
movzx ebx,word [eax+0]
shl ebx,5
add ebx,window_data
mov ecx, [ebx+ WDATA.box.left] ; window x start
movsx edx,word [eax+4] ; button x start
add ecx,edx
push ecx
movzx edx,word[eax+6] ; button x size
add ecx,edx
mov esi,ecx
inc esi
mov ecx, [ebx+WDATA.box.top] ; window y start
movsx edx,word[eax+8] ; button y start
add ecx,edx
mov ebx,ecx
movzx edx,word[eax+10] ; button y size
add edx,ecx
inc edx
pop eax
; eax x beginning
; ebx y beginning
; esi x end
; edx y end
; ecx color
mov [pressed_button_eax],eax
mov [pressed_button_ebx],ebx
mov [pressed_button_ecx],ecx
mov [pressed_button_edx],edx
mov [pressed_button_esi],esi
popad
ret
uglobal
pressed_button_eax dd 0
pressed_button_ebx dd 0
pressed_button_ecx dd 0
pressed_button_edx dd 0
pressed_button_esi dd 0
endg
; negative button image
negativebutton:
; If requested, do not display button
; boarder on press.
test ebx,0x20000000
jz draw_negative_button
ret
draw_negative_button:
pushad
mov eax,[pressed_button_eax]
mov ebx,[pressed_button_ebx]
mov ecx,[pressed_button_ecx]
mov edx,[pressed_button_edx]
mov esi,[pressed_button_esi]
mov ecx,0x01000000
dec edx
push edx
inc edx
dec esi
push esi
inc esi
push eax
push ebx
push ecx
push edx
push edi
call [disable_mouse]
bdbnewline:
mov edi,1 ; force
cmp eax,[esp+16]
jz bneg
cmp eax,[esp+20]
jz bneg
cmp ebx,[esp+12]
jz bneg
cmp ebx,[esp+24]
jnz nbneg
; jz bneg
; jmp nbneg
bneg:
;;;call [disable_mouse]
call [putpixel]
nbneg:
inc eax
cmp eax,esi
jnz bdbnewline
mov eax,[esp+16]
inc ebx
cmp ebx,edx
jnz bdbnewline
add esp,28
popad
ret
; check buttons
; 0000 word process number
; 0002 word button id number : bits 0-15
; 0004 word x start
; 0006 word x size
; 0008 word y start
; 000A word y size
; 000C word button id number : bits 16-31
;
; button table in 0x10 increments
;
; first at 0x10
checkbuttons:
cmp [BTN_DOWN],byte 0 ; mouse buttons pressed
jnz @f
ret
@@:
pushad
xor esi, esi
mov edi, [BTN_ADDR]
movzx edx, word [edi]
test edx, edx
jne @f
popad
ret
@@:
push esi
inc edx
push edx
buttonnewcheck:
pop edx
pop esi
inc esi
cmp edx,esi
jge bch
popad ; no button pressed
ret
bch:
push esi
push edx
mov eax,esi
shl eax,4
add eax,edi
;......................start 1/2 : modified by vhanla .............................
mov [buttonid],eax
;......................end 1/2 : modified by vhanla .............................
; check that button is at top of windowing stack
movzx ebx,word [eax]
movzx ecx,word [WIN_STACK + ebx * 2]
cmp ecx,[TASK_COUNT]
jne buttonnewcheck
; check that button start is inside window x/y end
movzx ebx,word [eax+0]
shl ebx,5
test [ebx+window_data+WDATA.fl_wstate],WSTATE_MINIMIZED
jnz buttonnewcheck
; add ebx,window_data
; mov ecx,[window_data+ebx+8] ; window end X
movsx edx,word [eax+4] ; button start X
cmp edx, [window_data+ebx+WDATA.box.width] ;ecx
jge buttonnewcheck
; mov ecx,[window_data+ebx+12] ; window end Y
movsx edx, word [eax+8] ; button start Y
cmp edx, [window_data+ebx+WDATA.box.height] ;ecx
jge buttonnewcheck
; check coordinates
; mouse x >= button x ?
movzx ebx,word [eax+0]
shl ebx,5
add ebx,window_data
mov ecx, [ebx+WDATA.box.left] ; window x start
movsx edx,word [eax+4] ; button x start
add edx,ecx
movzx ecx,word[0xfb0a]
cmp ecx,edx
jl buttonnewcheck
movzx ebx,word [eax+6] ; button x size
add edx,ebx
cmp ecx,edx
jg buttonnewcheck
; mouse y >= button y ?
movzx ebx,word [eax+0]
shl ebx,5
add ebx,window_data
mov ecx, [ebx+WDATA.box.top] ; window y start
movsx edx,word [eax+8] ; button y start
add edx,ecx
movzx ecx,word[0xfb0c]
cmp ecx,edx
jl buttonnewcheck
movzx ebx,word [eax+10] ; button y size
add edx,ebx
cmp ecx,edx
jg buttonnewcheck
; mouse on button
pop edx
pop esi
mov bx,[eax+0xc] ; button id : bits 16-31
shl ebx,16
mov bx,[eax+2] ; button id : bits 00-16
push ebx
mov [MOUSE_DOWN],byte 1 ; no mouse down checks
call find_pressed_button_frames
call negativebutton
pushad
cbwaitmouseup:
call checkidle
call [draw_pointer]
pushad
call stack_handler
popad
cmp [BTN_DOWN],byte 0 ; mouse buttons pressed ?
jnz cbwaitmouseup
popad
call negativebutton
mov [MOUSE_BACKGROUND],byte 0 ; no mouse background
mov [DONT_DRAW_MOUSE],byte 0 ; draw mouse
;..................................... start 2/2 : modified by vhanla .............................
; check coordinates
jmp afterbuttonid
buttonid dd 0x0 ;here a will backup the eax value
afterbuttonid:
pusha
; mouse x >= button x ?
movzx ebx,word [eax+0]
shl ebx,5
add ebx,window_data
mov ecx, [ebx+WDATA.box.left] ; window x start
movsx edx,word [eax+4] ; button x start
add edx,ecx
movzx ecx,word[0xfb0a]
cmp edx,ecx
jg no_on_button ;if we release the pointer out of the button area
movzx ebx,word [eax+6] ; button x size
add edx,ebx
cmp ecx,edx
jg no_on_button
; mouse y >= button y ?
movzx ebx,word [eax+0]
shl ebx,5
add ebx,window_data
mov ecx, [ebx+WDATA.box.top] ; window y start
movsx edx,word [eax+8] ; button y start
add edx,ecx
movzx ecx,word[0xfb0c]
cmp edx,ecx
jg no_on_button
movzx ebx,word [eax+10] ; button y size
add edx,ebx
cmp ecx,edx
jg no_on_button
popa
mov [BTN_COUNT],byte 1 ; no of buttons in buffer
pop ebx
mov [BTN_BUFF],ebx ; lets put the button id in buffer
push ebx
pusha
jmp yes_on_button
no_on_button:
mov [BTN_COUNT],byte 0 ; no of buttons in buffer
yes_on_button:
mov [MOUSE_DOWN],byte 0 ; mouse down -> do not draw
popa
pop ebx
popa
ret
;..................................... end 2/2 : modified by vhanla ................................

View File

@ -0,0 +1,685 @@
align 4
init_events:
stdcall kernel_alloc, 512*EVENT_SIZE
mov [events], eax
xor eax, eax
mov [event_uid], eax
not eax
mov edi, event_map
mov [event_start], edi
mov ecx, 64/4
cld
rep stosd
mov [event_end], edi
ret
align 4
proc alloc_event
pushfd
cli
mov ebx, [event_start]
mov ecx, [event_end]
.l1:
bsf eax,[ebx]
jnz .found
add ebx,4
cmp ebx, ecx
jb .l1
popfd
xor eax,eax
ret
.found:
btr [ebx], eax
mov [event_start],ebx
inc [event_uid]
sub ebx, event_map
lea eax,[eax+ebx*8]
lea ebx, [eax+eax*4]
shl eax,5
lea eax,[eax+ebx*4] ;eax*=52 (EVENT_SIZE)
add eax, [events]
mov ebx, [event_uid]
popfd
ret
endp
align 4
free_event:
sub eax, [events]
mov ecx, EVENT_SIZE
mov ebx, event_map
cdq
div ecx
pushfd
cli
bts [ebx], eax
shr eax, 3
and eax, not 3
add eax, ebx
cmp [event_start], eax
ja @f
popfd
ret
@@:
mov [event_start], eax
popfd
ret
EVENT_WATCHED equ 0x10000000
EVENT_SIGNALED equ 0x20000000
MANUAL_RESET equ 0x40000000
MANUAL_DESTROY equ 0x80000000
; param
; eax= event data
; ebx= flags
;
; retval
; eax= event
; edx= id
create_event:
.flags equ esp+4
.data equ esp
push ebx
push eax
call alloc_event
test eax, eax
jz .fail
mov [eax+APPOBJ.magic], 'EVNT'
mov [eax+APPOBJ.destroy], destroy_event.internal
mov [eax+EVENT.id], ebx
mov ebx, [CURRENT_TASK]
shl ebx, 5
mov ebx, [CURRENT_TASK+ebx+4]
mov [eax+APPOBJ.pid], ebx
mov edx, [.flags]
mov [eax+EVENT.state], edx
mov esi, [.data]
test esi, esi
jz @F
lea edi, [eax+EVENT.code]
mov ecx, 6
cld
rep movsd
@@:
mov ecx, [CURRENT_TASK]
shl ecx,8
add ecx, SLOT_BASE+APP_OBJ_OFFSET
pushfd
cli
mov edx, [ecx+APPOBJ.fd]
mov [eax+APPOBJ.fd], edx
mov [eax+APPOBJ.bk], ecx
mov [ecx+APPOBJ.fd], eax
mov [edx+APPOBJ.bk], eax
popfd
mov edx, [eax+EVENT.id]
.fail:
add esp, 8
ret
restore .flags
restore .data
; param
; eax= event
; ebx= id
destroy_event:
cmp [eax+APPOBJ.magic], 'EVNT'
jne .fail
cmp [eax+EVENT.id], ebx
jne .fail
.internal:
mov ebx, [eax+APPOBJ.fd]
mov ecx, [eax+APPOBJ.bk]
mov [ebx+APPOBJ.bk], ecx
mov [ecx+APPOBJ.fd], ebx
.force:
xor edx, edx ;clear common header
mov [eax], edx
mov [eax+4], edx
mov [eax+8], edx
mov [eax+12], edx
mov [eax+16], edx
call free_event ;release object memory
.fail:
ret
align 4
proc send_event stdcall pid:dword, event:dword
locals
slot dd ?
endl
mov eax, [pid]
call pid_to_slot
test eax, eax
jz .fail
shl eax, 8
cmp [SLOT_BASE+eax+APPDATA.ev_count], 32
ja .fail
mov [slot], eax
call alloc_event
test eax, eax
jz .fail
lea edi, [eax+EVENT.code]
mov ecx, 6
mov esi, [event]
cld
rep movsd
mov ecx, [slot]
add ecx, SLOT_BASE+APP_EV_OFFSET
mov [eax+APPOBJ.magic], 'EVNT'
mov [eax+APPOBJ.destroy], destroy_event
mov ebx, [pid]
mov [eax+APPOBJ.pid], ebx
mov [eax+EVENT.state], EVENT_SIGNALED
pushfd
cli ;insert event into
mov edx, [ecx+APPOBJ.fd] ;events list
mov [eax+APPOBJ.fd], edx ;and set events flag
mov [eax+APPOBJ.bk], ecx
mov [ecx+APPOBJ.fd], eax
mov [edx+APPOBJ.bk], eax
inc [ecx+APPDATA.ev_count-APP_EV_OFFSET]
or [ecx+APPDATA.event_mask-APP_EV_OFFSET], EVENT_EXTENDED
popfd
.fail:
ret
endp
; timeout ignored
align 4
proc get_event_ex stdcall, p_ev:dword, timeout:dword
.wait:
mov edx,[CURRENT_TASK]
shl edx,8
; cmp [SLOT_BASE+edx+APPDATA.ev_count], 0
; je .switch
add edx, SLOT_BASE+APP_EV_OFFSET
mov eax, [edx+APPOBJ.fd]
cmp eax, edx
je .switch
lea esi, [eax+EVENT.code]
mov edi, [p_ev] ;copy event data
mov ecx, 6
cld
rep movsd
and dword [edi-24], 0xFF00FFFF ;clear priority field
;
test [eax+EVENT.state], MANUAL_RESET
jnz .done
pushfd
cli ;remove event from events
mov ebx, [eax+APPOBJ.fd] ;list (reset event)
mov ecx, [eax+APPOBJ.bk] ;and clear events flag
mov [ebx+APPOBJ.bk], ecx ;if no active events
mov [ecx+APPOBJ.fd], ebx
and [eax+EVENT.state], not (EVENT_SIGNALED+EVENT_WATCHED)
dec [edx+APPDATA.ev_count-APP_EV_OFFSET]
jnz @F
and [edx+APPDATA.event_mask-APP_EV_OFFSET], not EVENT_EXTENDED
@@:
popfd
test [eax+EVENT.state], MANUAL_DESTROY
jz .destroy
add edx, (APP_OBJ_OFFSET-APP_EV_OFFSET)
pushfd
cli
mov ebx, [edx+APPOBJ.fd] ;insert event into
mov [eax+APPOBJ.fd], ebx ;objects list
mov [eax+APPOBJ.bk], edx
mov [edx+APPOBJ.fd], eax
mov [ebx+APPOBJ.bk], eax
popfd
.done:
ret
.destroy:
call destroy_event.force
ret
.switch:
mov eax, [TASK_BASE]
mov [eax+TASKDATA.state], byte 5
call change_task
jmp .wait
endp
; param
; eax= event
; ebx= id
align 4
wait_event:
.event equ esp
push eax
.wait:
cmp [eax+APPOBJ.magic], 'EVNT'
jne .done
cmp [eax+EVENT.id], ebx
jne .done
test [eax+EVENT.state], EVENT_SIGNALED
jz .switch
test [eax+EVENT.state], MANUAL_RESET
jnz .done
mov edx,[CURRENT_TASK]
shl edx,8
add edx, SLOT_BASE
pushfd
cli ;remove event from events
mov ebx, [eax+APPOBJ.fd] ;list (reset event)
mov ecx, [eax+APPOBJ.bk] ;and clear events flag
mov [ebx+APPOBJ.bk], ecx ;if no active events
mov [ecx+APPOBJ.fd], ebx
dec [edx+APPDATA.ev_count]
jnz @F
and [edx+APPDATA.event_mask], not EVENT_EXTENDED
@@:
and [eax+EVENT.state], not (EVENT_SIGNALED+EVENT_WATCHED)
popfd
test [eax+EVENT.state], MANUAL_DESTROY
jz .destroy
add edx, APP_OBJ_OFFSET
pushfd
cli
mov ecx, [edx+APPOBJ.fd] ;insert event into
mov [eax+APPOBJ.fd], ecx ;objects list
mov [eax+APPOBJ.bk], edx
mov [edx+APPOBJ.fd], eax
mov [ecx+APPOBJ.bk], eax
popfd
.done:
add esp, 4
ret
.destroy:
call destroy_event.force
add esp, 4
ret
.switch:
or [eax+EVENT.state], EVENT_WATCHED
mov eax, [TASK_BASE]
mov [eax+TASKDATA.state], byte 5
call change_task
mov eax, [.event]
jmp .wait
restore .event
; param
; eax= event
; ebx= id
; ecx= flags
; edx= event data
raise_event:
.event equ esp
push eax
cmp [eax+APPOBJ.magic], 'EVNT'
jne .fail
cmp [eax+EVENT.id], ebx
jne .fail
mov eax, [eax+APPOBJ.pid]
call pid_to_slot
test eax, eax
jz .fail
mov esi, edx
test esi, esi
mov edx, [.event]
jz @F
push ecx
lea edi, [edx+EVENT.code]
mov ecx, 6
cld
rep movsd
pop ecx
@@:
test [edx+EVENT.state], EVENT_SIGNALED
jnz .done
test ecx, EVENT_WATCHED
jz @F
test [edx+EVENT.state], EVENT_WATCHED
jz .done
@@:
shl eax, 8
add eax, SLOT_BASE+APP_EV_OFFSET
pushfd
cli
mov ebx, [edx+APPOBJ.fd]
mov ecx, [edx+APPOBJ.bk]
mov [ebx+APPOBJ.bk], ecx
mov [ecx+APPOBJ.fd], ebx
mov ecx, [eax+APPOBJ.fd]
mov [edx+APPOBJ.fd], ecx
mov [edx+APPOBJ.bk], eax
mov [eax+APPOBJ.fd], edx
mov [ecx+APPOBJ.bk], edx
or [edx+EVENT.state], EVENT_SIGNALED
inc [eax+APPDATA.ev_count-APP_EV_OFFSET]
or [eax+APPDATA.event_mask-APP_EV_OFFSET], EVENT_EXTENDED
popfd
.fail:
.done:
add esp, 4
ret
restore .event
; param
; eax= event
; ebx= id
align 4
clear_event:
.event equ esp
push eax
cmp [eax+APPOBJ.magic], 'EVNT'
jne .fail
cmp [eax+EVENT.id], ebx
jne .fail
mov eax, [eax+APPOBJ.pid]
call pid_to_slot
test eax, eax
jz .fail
shl eax, 8
add eax, SLOT_BASE+APP_EV_OFFSET
mov edx, [.event]
pushfd
cli ;remove event from events
mov ebx, [edx+APPOBJ.fd] ;list (reset event)
mov ecx, [edx+APPOBJ.bk] ;and clear events flag
mov [ebx+APPOBJ.bk], ecx ;if no active events
mov [ecx+APPOBJ.fd], ebx
and [edx+EVENT.state], not (EVENT_SIGNALED+EVENT_WATCHED)
dec [eax+APPDATA.ev_count-APP_EV_OFFSET]
jnz @F
and [eax+APPDATA.event_mask-APP_EV_OFFSET], not EVENT_EXTENDED
@@:
add eax, (APP_OBJ_OFFSET-APP_EV_OFFSET)
mov ecx, [eax+APPOBJ.fd] ;insert event into
mov [edx+APPOBJ.fd], ecx ;objects list
mov [edx+APPOBJ.bk], eax
mov [eax+APPOBJ.fd], edx
mov [ecx+APPOBJ.bk], edx
popfd
.fail:
.done:
add esp, 4
ret
restore .event
sys_getevent:
call get_event_for_app
mov [esp+36],eax
ret
align 4
sys_wait_event_timeout:
mov ebx,[timer_ticks]
add ebx,eax
cmp ebx,[timer_ticks]
jna .swfet2
.swfet1:
call get_event_for_app
test eax,eax
jne .eventoccur_time
call change_task
cmp ebx,[timer_ticks]
jg .swfet1
.swfet2:
xor eax,eax
.eventoccur_time:
mov [esp+36],eax
ret
align 4
sys_waitforevent:
call get_event_for_app
test eax,eax
jne eventoccur
newwait:
mov eax, [TASK_BASE]
mov [eax+TASKDATA.state], byte 5
call change_task
mov eax, [event_sched]
eventoccur:
mov [esp+36],eax
ret
get_event_for_app:
pushad
mov edi,[TASK_BASE] ; WINDOW REDRAW
test [edi+TASKDATA.event_mask],dword 1
jz no_eventoccur1
;mov edi,[TASK_BASE]
cmp [edi-twdw+WDATA.fl_redraw],byte 0
je no_eventoccur1
popad
mov eax,1
ret
no_eventoccur1:
;mov edi,[TASK_BASE] ; KEY IN BUFFER
test [edi+TASKDATA.event_mask],dword 2
jz no_eventoccur2
mov ecx, [CURRENT_TASK]
movzx edx,word [WIN_STACK+ecx*2]
mov eax, [TASK_COUNT]
cmp eax,edx
jne no_eventoccur2x
cmp [KEY_COUNT],byte 0
je no_eventoccur2x
eventoccur2:
popad
mov eax,2
ret
no_eventoccur2x:
mov eax, hotkey_buffer
@@:
cmp [eax], ecx
jz eventoccur2
add eax, 8
cmp eax, hotkey_buffer+120*8
jb @b
no_eventoccur2:
;mov edi,[TASK_BASE] ; BUTTON IN BUFFER
test [edi+TASKDATA.event_mask],dword 4
jz no_eventoccur3
cmp [BTN_COUNT],byte 0
je no_eventoccur3
mov ecx, [CURRENT_TASK]
movzx edx, word [WIN_STACK+ecx*2]
mov eax, [TASK_COUNT]
cmp eax,edx
jnz no_eventoccur3
popad
mov eax,[BTN_BUFF]
cmp eax,65535
je no_event_1
mov eax,3
ret
no_event_1:
mov [window_minimize],1
mov [BTN_COUNT],byte 0
xor eax, eax
ret
no_eventoccur3:
;mov edi,[TASK_BASE] ; mouse event
test [edi+TASKDATA.event_mask],dword 00100000b
jz no_mouse_event
mov eax,[CURRENT_TASK]
shl eax,8
test [eax+SLOT_BASE+APPDATA.event_mask],dword 00100000b
jz no_mouse_event
and [eax+SLOT_BASE+APPDATA.event_mask],dword 0xffffffff-00100000b
popad
mov eax,6
ret
no_mouse_event:
;mov edi,[TASK_BASE] ; DESKTOP BACKGROUND REDRAW
test [edi+TASKDATA.event_mask],dword 16
jz no_eventoccur5
cmp [REDRAW_BACKGROUND],byte 2
jnz no_eventoccur5
popad
mov eax,5
ret
no_eventoccur5:
;mov edi,[TASK_BASE] ; IPC
test [edi+TASKDATA.event_mask],dword 01000000b
jz no_ipc
mov eax,[CURRENT_TASK]
shl eax,8
test [eax+SLOT_BASE+APPDATA.event_mask],dword 01000000b
jz no_ipc
and [eax+SLOT_BASE+APPDATA.event_mask],dword 0xffffffff-01000000b
popad
mov eax,7
ret
no_ipc:
;mov edi,[TASK_BASE] ; STACK
test [edi+TASKDATA.event_mask],dword 10000000b
jz no_stack_event
mov eax,[CURRENT_TASK]
shl eax,8
test [eax+SLOT_BASE+APPDATA.event_mask],dword 10000000b
jz no_stack_event
and [eax+SLOT_BASE+APPDATA.event_mask],dword 0xffffffff-10000000b
popad
mov eax,8
ret
no_stack_event:
test byte [edi+TASKDATA.event_mask+1], 1 ; DEBUG
jz .test_IRQ
mov eax, [CURRENT_TASK]
shl eax, 8
test byte [eax+SLOT_BASE+APPDATA.event_mask+1], byte 1
jz .test_IRQ
and byte [eax+SLOT_BASE+APPDATA.event_mask+1], not 1
popad
mov eax, 9
ret
;.test_ext:
; mov eax, [CURRENT_TASK]
; shl eax, 8
; test dword [eax+SLOT_BASE+APPDATA.event_mask], EVENT_EXTENDED
; jz .test_IRQ
; popad
; mov eax, 10
; ret
.test_IRQ:
cmp dword [edi+TASKDATA.event_mask], 0xFFFF
jbe no_events
mov esi,IRQ_SAVE ; IRQ'S AND DATA
mov ebx,0x00010000
xor ecx, ecx
irq_event_test:
mov edi,[TASK_BASE]
test [edi+TASKDATA.event_mask],ebx
jz no_irq_event
mov edi,ecx
shl edi,2
add edi,irq_owner
mov edx,[edi]
mov eax,[TASK_BASE]
mov eax,[eax+TASKDATA.pid]
cmp edx,eax
jne no_irq_event
cmp [esi],dword 0
jz no_irq_event
mov eax,ecx
add eax,16
mov [esp+28],eax
popad
ret
no_irq_event:
add esi,0x1000
shl ebx,1
inc ecx
cmp ecx,16
jb irq_event_test
no_events:
popad
xor eax, eax
ret

View File

@ -0,0 +1,107 @@
align 4
dtext: ; Text String Output (rw by Johnny_B[john@kolibrios.org])
; eax x & y
; ebx style ( 0xX0000000 ) & color ( 0x00RRGGBB )
; X = ABnnb:
; nn = font
; A = 0 <=> output edx characters; otherwise output ASCIIZ string
; B = 1 <=> fill background with color esi
; ecx start of text
; edi 1 force
pushad
call [disable_mouse]
mov ebp, ecx ; ebp=pointer to text
mov ecx, ebx ; ecx=color
movsx ebx, ax ; ebx=y
sar eax, 16 ; eax=x
cmp edx, 255
jb .loop
mov edx, 255
.loop:
test ecx, ecx
js .test_asciiz
dec edx
js .end
jmp @f
.test_asciiz:
cmp byte [ebp], 0
jz .end
@@:
push edx
movzx edx, byte [ebp]
inc ebp
test ecx, 0x10000000
jnz .font2
pushad
mov esi, 9
lea ebp, [FONT_I+8*edx+edx]
.symloop1:
mov dl, byte [ebp]
or dl, 1 shl 6
.pixloop1:
shr dl, 1
jz .pixloop1end
jnc .nopix
call [putpixel]
jmp .pixloop1cont
.nopix:
test ecx, 0x40000000
jz .pixloop1cont
push ecx
mov ecx, [esp+4+4]
call [putpixel]
pop ecx
.pixloop1cont:
inc eax
jmp .pixloop1
.pixloop1end:
sub eax, 6
inc ebx
inc ebp
dec esi
jnz .symloop1
popad
add eax, 6
pop edx
jmp .loop
.font2:
pushad
add edx, edx
lea ebp, [FONT_II+4*edx+edx+1]
push 9
movzx esi, byte [ebp-1]
.symloop2:
mov dl, byte [ebp]
push esi
.pixloop2:
shr dl, 1
jnc .nopix2
call [putpixel]
jmp .pixloop2cont
.nopix2:
test ecx, 0x40000000
jz .pixloop2cont
push ecx
mov ecx, [esp+12+4]
call [putpixel]
pop ecx
.pixloop2cont:
inc eax
dec esi
jnz .pixloop2
pop esi
sub eax, esi
inc ebx
inc ebp
dec dword [esp]
jnz .symloop2
pop eax
add dword [esp+28], esi
popad
pop edx
jmp .loop
.end:
popad
ret

View File

@ -0,0 +1,11 @@
uglobal
mouseunder:
times 32*32*3+1 db ?
mousecomb = $ - mouseunder
times 32*32*3+1 db ?
endg
uglobal
mousepointer:
times 4608 db 0 ; 32*32*4+62 = 4286
endg

View File

@ -0,0 +1,446 @@
include "skindata.inc"
;skin_data = 0x00778000
load_skin_file:
; eax = filename
; edx = destination
mov ebx,1
or ecx,-1
mov esi,12
call fileread
ret
struct SKIN_HEADER
.ident dd ?
.version dd ?
.params dd ?
.buttons dd ?
.bitmaps dd ?
ends
struct SKIN_PARAMS
.skin_height dd ?
.margin.right dw ?
.margin.left dw ?
.margin.bottom dw ?
.margin.top dw ?
.colors.inner dd ?
.colors.outer dd ?
.colors.frame dd ?
.colors_1.inner dd ?
.colors_1.outer dd ?
.colors_1.frame dd ?
.dtp.size dd ?
.dtp.data db 40 dup (?)
ends
struct SKIN_BUTTONS
.type dd ?
.pos:
.left dw ?
.top dw ?
.size:
.width dw ?
.height dw ?
ends
struct SKIN_BITMAPS
.kind dw ?
.type dw ?
.data dd ?
ends
load_skin:
pushad
mov [_skinh],22
mov eax,_skin_file
mov edx,skin_data
mov [edx+SKIN_HEADER.ident],'????'
call load_skin_file
cmp eax,ERROR_SUCCESS
je @f
cmp eax,ERROR_END_OF_FILE
jne .exit
@@: call parse_skin_data
.exit:
popad
ret
parse_skin_data:
mov ebp,skin_data
cmp [ebp+SKIN_HEADER.ident],'SKIN'
jne .exit
mov edi,skin_udata
mov ecx,(skin_udata.end-skin_udata)/4
xor eax,eax
cld
rep stosd
mov ebx,[ebp+SKIN_HEADER.params]
add ebx,skin_data
mov eax,[ebx+SKIN_PARAMS.skin_height]
mov [_skinh],eax
mov eax,[ebx+SKIN_PARAMS.colors.inner]
mov [skin_active.colors.inner],eax
mov eax,[ebx+SKIN_PARAMS.colors.outer]
mov [skin_active.colors.outer],eax
mov eax,[ebx+SKIN_PARAMS.colors.frame]
mov [skin_active.colors.frame],eax
mov eax,[ebx+SKIN_PARAMS.colors_1.inner]
mov [skin_inactive.colors.inner],eax
mov eax,[ebx+SKIN_PARAMS.colors_1.outer]
mov [skin_inactive.colors.outer],eax
mov eax,[ebx+SKIN_PARAMS.colors_1.frame]
mov [skin_inactive.colors.frame],eax
lea esi,[ebx+SKIN_PARAMS.dtp.data]
mov edi,common_colours
mov ecx,[ebx+SKIN_PARAMS.dtp.size]
and ecx,127
rep movsb
mov eax,dword[ebx+SKIN_PARAMS.margin.right]
mov dword[_skinmargins+0],eax
mov eax,dword[ebx+SKIN_PARAMS.margin.bottom]
mov dword[_skinmargins+4],eax
mov ebx,[ebp+SKIN_HEADER.bitmaps]
add ebx,skin_data
.lp1: cmp dword[ebx],0
je .end_bitmaps
movzx eax,[ebx+SKIN_BITMAPS.kind]
movzx ecx,[ebx+SKIN_BITMAPS.type]
dec eax
jnz .not_left
xor eax,eax
mov edx,skin_active.left.data
or ecx,ecx
jnz @f
mov edx,skin_inactive.left.data
@@: jmp .next_bitmap
.not_left:
dec eax
jnz .not_oper
mov esi,[ebx+SKIN_BITMAPS.data]
add esi,skin_data
mov eax,[esi+0]
neg eax
mov edx,skin_active.oper.data
or ecx,ecx
jnz @f
mov edx,skin_inactive.oper.data
@@: jmp .next_bitmap
.not_oper:
dec eax
jnz .not_base
mov eax,[skin_active.left.width]
mov edx,skin_active.base.data
or ecx,ecx
jnz @f
mov eax,[skin_inactive.left.width]
mov edx,skin_inactive.base.data
@@: jmp .next_bitmap
.not_base:
add ebx,8
jmp .lp1
.next_bitmap:
mov ecx,[ebx+SKIN_BITMAPS.data]
add ecx,skin_data
mov [edx+4],eax
mov eax,[ecx+0]
mov [edx+8],eax
add ecx,8
mov [edx+0],ecx
add ebx,8
jmp .lp1
.end_bitmaps:
mov ebx,[ebp+SKIN_HEADER.buttons]
add ebx,skin_data
.lp2: cmp dword[ebx],0
je .end_buttons
mov eax,[ebx+SKIN_BUTTONS.type]
dec eax
jnz .not_close
mov edx,skin_btn_close
jmp .next_button
.not_close:
dec eax
jnz .not_minimize
mov edx,skin_btn_minimize
jmp .next_button
.not_minimize:
add ebx,12
jmp .lp2
.next_button:
movsx eax,[ebx+SKIN_BUTTONS.left]
mov [edx+SKIN_BUTTON.left],eax
movsx eax,[ebx+SKIN_BUTTONS.top]
mov [edx+SKIN_BUTTON.top],eax
movsx eax,[ebx+SKIN_BUTTONS.width]
mov [edx+SKIN_BUTTON.width],eax
movsx eax,[ebx+SKIN_BUTTONS.height]
mov [edx+SKIN_BUTTON.height],eax
add ebx,12
jmp .lp2
.end_buttons:
.exit:
ret
sys_putimage_with_check:
or ebx,ebx
jz @f
call [putimage]
@@: ret
drawwindow_IV_caption:
mov ebp,skin_active
or al,al
jnz @f
mov ebp,skin_inactive
@@:
mov esi,[esp+4]
mov eax,[esi+WDATA.box.width] ; window width
mov edx,[ebp+SKIN_DATA.left.left]
shl edx,16
mov ecx,[ebp+SKIN_DATA.left.width]
shl ecx,16
add ecx,[_skinh]
mov ebx, [ebp+SKIN_DATA.left.data]
call sys_putimage_with_check
mov esi,[esp+4]
mov eax,[esi+WDATA.box.width]
sub eax,[ebp+SKIN_DATA.left.width]
sub eax,[ebp+SKIN_DATA.oper.width]
cmp eax,[ebp+SKIN_DATA.base.left]
jng .non_base
xor edx,edx
mov ecx,[ebp+SKIN_DATA.base.width]
jecxz .non_base
div ecx
inc eax
mov ebx,[ebp+SKIN_DATA.base.data]
mov ecx,[ebp+SKIN_DATA.base.width]
shl ecx,16
add ecx,[_skinh]
mov edx,[ebp+SKIN_DATA.base.left]
sub edx,[ebp+SKIN_DATA.base.width]
shl edx,16
.baseskinloop:
shr edx,16
add edx,[ebp+SKIN_DATA.base.width]
shl edx,16
push eax ebx ecx edx
call sys_putimage_with_check
pop edx ecx ebx eax
dec eax
jnz .baseskinloop
.non_base:
mov esi,[esp+4]
mov edx,[esi+WDATA.box.width]
sub edx,[ebp+SKIN_DATA.oper.width]
inc edx
shl edx,16
mov ebx,[ebp+SKIN_DATA.oper.data]
mov ecx,[ebp+SKIN_DATA.oper.width]
shl ecx,16
add ecx,[_skinh]
call sys_putimage_with_check
ret
;//mike.dld, 2006-08-02 ]
drawwindow_IV:
;param1 - aw_yes
pusha
push edx
mov edi,edx
mov ebp,skin_active
cmp byte [esp+32+4+4],0
jne @f
mov ebp,skin_inactive
@@:
mov eax,[edi+WDATA.box.left]
shl eax,16
mov ax,word [edi+WDATA.box.left]
add ax,word [edi+WDATA.box.width]
mov ebx,[edi+WDATA.box.top]
shl ebx,16
mov bx,word [edi+WDATA.box.top]
add bx,word [edi+WDATA.box.height]
; mov esi,[edi+24]
; shr esi,1
; and esi,0x007f7f7f
mov esi,[ebp+SKIN_DATA.colors.outer]
or [edi+WDATA.fl_wdrawn], 4
call draw_rectangle
mov ecx,3
_dw3l:
add eax,1*65536-1
add ebx,1*65536-1
test ax,ax
js no_skin_add_button
test bx,bx
js no_skin_add_button
mov esi,[ebp+SKIN_DATA.colors.frame] ;[edi+24]
call draw_rectangle
dec ecx
jnz _dw3l
mov esi,[ebp+SKIN_DATA.colors.inner]
add eax,1*65536-1
add ebx,1*65536-1
test ax,ax
js no_skin_add_button
test bx,bx
js no_skin_add_button
call draw_rectangle
cmp dword[skin_data],'SKIN'
je @f
xor eax,eax
xor ebx,ebx
mov esi,[esp]
mov ecx,[esi+WDATA.box.width]
inc ecx
mov edx,[_skinh]
mov edi,[common_colours+4] ; standard grab color
call [drawbar]
jmp draw_clientbar
@@:
mov al,[esp+32+4+4]
call drawwindow_IV_caption
draw_clientbar:
mov esi,[esp]
mov edx,[esi+WDATA.box.top] ; WORK AREA
add edx,21+5
mov ebx,[esi+WDATA.box.top]
add ebx,[esi+WDATA.box.height]
cmp edx,ebx
jg _noinside2
mov eax,5
mov ebx,[_skinh]
mov ecx,[esi+WDATA.box.width]
mov edx,[esi+WDATA.box.height]
sub ecx,4
sub edx,4
mov edi,[esi+WDATA.cl_workarea]
test edi,0x40000000
jnz _noinside2
call [drawbar]
_noinside2:
cmp dword[skin_data],'SKIN'
jne no_skin_add_button
;* close button
mov edi,[BTN_ADDR]
movzx eax,word [edi]
cmp eax,1000
jge no_skin_add_button
inc eax
mov [edi],ax
shl eax,4
add eax,edi
mov bx,[CURRENT_TASK]
mov [eax],bx
add eax,2 ; save button id number
mov bx,1
mov [eax],bx
add eax,2 ; x start
xor ebx,ebx
cmp [skin_btn_close.left],0
jge _bCx_at_right
mov ebx,[esp]
mov ebx,[ebx+WDATA.box.width]
inc ebx
_bCx_at_right:
add ebx,[skin_btn_close.left]
mov [eax],bx
add eax,2 ; x size
mov ebx,[skin_btn_close.width]
dec ebx
mov [eax],bx
add eax,2 ; y start
mov ebx,[skin_btn_close.top]
mov [eax],bx
add eax,2 ; y size
mov ebx,[skin_btn_close.height]
dec ebx
mov [eax],bx
;* minimize button
mov edi,[BTN_ADDR]
movzx eax,word [edi]
cmp eax,1000
jge no_skin_add_button
inc eax
mov [edi],ax
shl eax,4
add eax,edi
mov bx,[CURRENT_TASK]
mov [eax],bx
add eax,2 ; save button id number
mov bx,65535 ;999
mov [eax],bx
add eax,2 ; x start
xor ebx,ebx
cmp [skin_btn_minimize.left],0
jge _bMx_at_right
mov ebx,[esp]
mov ebx,[ebx+WDATA.box.width]
inc ebx
_bMx_at_right:
add ebx,[skin_btn_minimize.left]
mov [eax],bx
add eax,2 ; x size
mov ebx,[skin_btn_minimize.width]
dec ebx
mov [eax],bx
add eax,2 ; y start
mov ebx,[skin_btn_minimize.top]
mov [eax],bx
add eax,2 ; y size
mov ebx,[skin_btn_minimize.height]
dec ebx
mov [eax],bx
no_skin_add_button:
pop edi
and [edi+WDATA.fl_wdrawn], not 4
test [edi+WDATA.fl_wdrawn], 2
jz @f
call drawwindowframes
@@:
popa
ret 4

View File

@ -0,0 +1,56 @@
;
; WINDOW SKIN DATA
;
iglobal
_skin_file_default db 'DEFAULT SKN',0
endg
struct SKIN_DATA
.colors.inner dd ?
.colors.outer dd ?
.colors.frame dd ?
.left.data dd ?
.left.left dd ?
.left.width dd ?
.oper.data dd ?
.oper.left dd ?
.oper.width dd ?
.base.data dd ?
.base.left dd ?
.base.width dd ?
ends
struct SKIN_BUTTON
.left dd ?
.top dd ?
.width dd ?
.height dd ?
ends
uglobal
align 4
skin_udata:
_skinh dd ?
_skinmargins: ; rw 4
.right dw ?
.left dw ?
.bottom dw ?
.top dw ?
skin_btn_close SKIN_BUTTON
skin_btn_minimize SKIN_BUTTON
skin_active SKIN_DATA
skin_inactive SKIN_DATA
_skin_file rb 256
align 4
skin_udata.end:
endg

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,294 @@
;// mike.dld [
VKEY_LSHIFT = 0000000000000001b
VKEY_RSHIFT = 0000000000000010b
VKEY_LCONTROL = 0000000000000100b
VKEY_RCONTROL = 0000000000001000b
VKEY_LALT = 0000000000010000b
VKEY_RALT = 0000000000100000b
VKEY_CAPSLOCK = 0000000001000000b
VKEY_NUMLOCK = 0000000010000000b
VKEY_SCRLOCK = 0000000100000000b
VKEY_SHIFT = 0000000000000011b
VKEY_CONTROL = 0000000000001100b
VKEY_ALT = 0000000000110000b
uglobal
align 4
kb_state dd 0
ext_code db 0
keyboard_mode db 0
keyboard_data db 0
altmouseb db 0
ctrl_alt_del db 0
kb_lights db 0
align 4
hotkey_scancodes rd 256 ; we have 256 scancodes
hotkey_list rd 256*4 ; max 256 defined hotkeys
hotkey_buffer rd 120*2 ; buffer for 120 hotkeys
endg
iglobal
hotkey_tests dd hotkey_test0
dd hotkey_test1
dd hotkey_test2
dd hotkey_test3
dd hotkey_test4
hotkey_tests_num = 5
endg
hotkey_test0:
test al, al
setz al
ret
hotkey_test1:
test al, al
setnp al
ret
hotkey_test2:
cmp al, 3
setz al
ret
hotkey_test3:
cmp al, 1
setz al
ret
hotkey_test4:
cmp al, 2
setz al
ret
hotkey_do_test:
push eax
mov edx, [kb_state]
shr edx, cl
add cl, cl
mov eax, [eax+4]
shr eax, cl
and eax, 15
cmp al, hotkey_tests_num
jae .fail
xchg eax, edx
and al, 3
call [hotkey_tests + edx*4]
cmp al, 1
pop eax
ret
.fail:
stc
pop eax
ret
align 4
irq1:
; save_ring3_context
; mov ax, os_data
; mov ds, ax
; mov es, ax
movzx eax,word[TASK_COUNT] ; top window process
movzx eax,word[WIN_POS+eax*2]
shl eax,8
mov al,[SLOT_BASE+eax+APPDATA.keyboard_mode]
mov [keyboard_mode],al
in al,0x60
mov [keyboard_data],al
; ch = scancode
; cl = ext_code
; bh = 0 - normal key
; bh = 1 - modifier (Shift/Ctrl/Alt)
; bh = 2 - extended code
mov ch,al
cmp al,0xE0
je @f
cmp al,0xE1
jne .normal_code
@@:
mov bh, 2
mov [ext_code], al
jmp .writekey
.normal_code:
mov cl, 0
xchg cl, [ext_code]
and al,0x7F
mov bh, 1
@@: cmp al,0x2A
jne @f
cmp cl,0xE0
je .writekey
mov eax,VKEY_LSHIFT
jmp .modifier
@@: cmp al,0x36
jne @f
cmp cl,0xE0
je .writekey
mov eax,VKEY_RSHIFT
jmp .modifier
@@: cmp al,0x38
jne @f
mov eax, VKEY_LALT
test cl, cl
jz .modifier
mov al, VKEY_RALT
jmp .modifier
@@: cmp al,0x1D
jne @f
mov eax, VKEY_LCONTROL
test cl, cl
jz .modifier
mov al, VKEY_RCONTROL
cmp cl, 0xE0
jz .modifier
mov [ext_code], cl
jmp .writekey
@@: cmp al,0x3A
jne @f
mov bl,4
mov eax,VKEY_CAPSLOCK
jmp .no_key.xor
@@: cmp al,0x45
jne @f
test cl, cl
jnz .writekey
mov bl,2
mov eax,VKEY_NUMLOCK
jmp .no_key.xor
@@: cmp al,0x46
jne @f
mov bl,1
mov eax,VKEY_SCRLOCK
jmp .no_key.xor
@@:
test ch,ch
js .writekey
movzx eax,ch ; plain key
mov bl,[keymap+eax]
mov edx,[kb_state]
test dl,VKEY_CONTROL ; ctrl alt del
jz .noctrlaltdel
test dl,VKEY_ALT
jz .noctrlaltdel
cmp ch,53h
jne .noctrlaltdel
mov [ctrl_alt_del],1
.noctrlaltdel:
test dl,VKEY_CONTROL ; ctrl on ?
jz @f
sub bl,0x60
@@: test dl,VKEY_SHIFT ; shift on ?
jz @f
mov bl,[keymap_shift+eax]
@@: test dl,VKEY_ALT ; alt on ?
jz @f
mov bl,[keymap_alt+eax]
@@:
mov bh, 0
jmp .writekey
.modifier:
test ch, ch
js .modifier.up
or [kb_state], eax
jmp .writekey
.modifier.up:
not eax
and [kb_state], eax
jmp .writekey
.no_key.xor:
mov bh, 0
test ch, ch
js .writekey
xor [kb_state], eax
xor [kb_lights], bl
call set_lights
.writekey:
; test for system hotkeys
movzx eax, ch
cmp bh, 1
ja .nohotkey
jb @f
xor eax, eax
@@:
mov eax, [hotkey_scancodes + eax*4]
.hotkey_loop:
test eax, eax
jz .nohotkey
mov cl, 0
call hotkey_do_test
jc .hotkey_cont
mov cl, 2
call hotkey_do_test
jc .hotkey_cont
mov cl, 4
call hotkey_do_test
jnc .hotkey_found
.hotkey_cont:
mov eax, [eax]
jmp .hotkey_loop
.hotkey_found:
mov eax, [eax+8]
; put key in buffer for process in slot eax
mov edi, hotkey_buffer
@@:
cmp dword [edi], 0
jz .found_free
add edi, 8
cmp edi, hotkey_buffer+120*8
jb @b
; no free space - replace first entry
mov edi, hotkey_buffer
.found_free:
mov [edi], eax
movzx eax, ch
cmp bh, 1
jnz @f
xor eax, eax
@@:
mov [edi+4], ax
mov eax, [kb_state]
mov [edi+6], ax
jmp .exit.irq1
.nohotkey:
cmp [keyboard_mode],0 ; return from keymap
jne .scancode
test bh, bh
jnz .exit.irq1
test bl, bl
jz .exit.irq1
jmp .dowrite
.scancode:
mov bl, ch
.dowrite:
movzx eax,byte[KEY_COUNT]
cmp al,120
jae .exit.irq1
inc eax
mov [KEY_COUNT],al
mov [KEY_COUNT+eax],bl
.exit.irq1:
mov [check_idle_semaphore],5
; mov al,0x20 ; ready for next irq
; out 0x20,al
; restore_ring3_context
; iret
ret
set_lights:
mov al,0xED
call kb_write
mov al,[kb_lights]
call kb_write
ret
;// mike.dld ]

View File

@ -0,0 +1,130 @@
; Номер принимаемого от мыши байта
MouseByteNumber DB 0
; Трехбайтовая структура данных, передаваемая мышью
FirstByte DB 0
SecondByte DB 0
ThirdByte DB 0
timer_ticks_com dd 0
;***************************************
;* НОВЫЙ ОБРАБОТЧИК ПРЕРЫВАНИЯ ОТ МЫШИ *
;***************************************
check_mouse_data_com1:
; cmp [com1_mouse_detected],0
; je @@EndMouseInterrupt
; Проверить наличие данных
mov DX,3F8h ;[COMPortBaseAddr]
add DX,5 ;xFDh
in AL,DX
test AL,1 ;Данные готовы?
jz @@Error
; Ввести данные
mov DX,3F8h ;[COMPortBaseAddr] ;xF8h
in AL,DX
; Сбросить старший незначащий бит
and AL,01111111b
; Определить порядковый номер принимаемого байта
cmp [MouseByteNumber],0
je @@FirstByte
cmp [MouseByteNumber],1
je @@SecondByte
cmp [MouseByteNumber],2
je @@ThirdByte
jmp @@Error
; Сохранить первый байт данных
@@FirstByte:
test AL,1000000b ;Первый байт посылки?
jz @@Error
mov [FirstByte],AL
inc [MouseByteNumber] ;увеличить счетчик
jmp @@EndMouseInterrupt
; Сохранить второй байт данных
@@SecondByte:
test AL,1000000b
jnz @@Error
mov [SecondByte],AL
inc [MouseByteNumber] ;увеличить счетчик
jmp @@EndMouseInterrupt
; Сохранить третий байт данных
@@ThirdByte:
test AL,1000000b
jnz @@Error
mov [ThirdByte],AL ;увеличить счетчик
mov [MouseByteNumber],0
; (Пакет данных от мыши принят полностью).
; Записать новое значение состояния кнопок мыши
mov al,[FirstByte] ;[0xfb01]
mov ah,al
shr al,3
and al,2
shr ah,5
and ah,1
add al,ah
mov [BTN_DOWN],al
mov [mouse_active],1
; Прибавить перемещение по X к координате X
mov AL,[FirstByte]
shl AL,6
or AL,[SecondByte]
cbw
call mouse_acceleration_com1
add AX,[MOUSE_X] ;[XCoordinate]
; Курсор не должен выходить за левую или
; правую границу экрана
js @@X1
cmp AX,[ScreenWidth] ;ScreenLength
jb @@X2
; Установить координату X по правой границе
mov AX,[ScreenWidth] ;ScreenLength-1
dec ax
jmp @@X2
@@X1:
; Установить координату X по левой границе
xor AX,AX
@@X2:
mov [MOUSE_X],AX ;[XCoordinate]
; Прибавить перемещение по Y к координате Y
mov AL,[FirstByte]
and AL,00001100b
shl AL,4
or AL,[ThirdByte]
cbw
call mouse_acceleration_com1
add AX,[MOUSE_Y] ;[YCoordinate]
; Курсор не должен выходить за верхнюю или
; нижнюю границу экрана
js @@Y1
cmp AX,[ScreenHeight] ;ScreenHeigth
jb @@Y2
; Установить координату X по нижней границе
mov AX,[ScreenHeight] ;ScreenHeigth-1
dec ax
jmp @@Y2
@@Y1:
; Установить координату X по верхней границе
xor AX,AX
@@Y2:
mov [MOUSE_Y],AX ;[YCoordinate]
mov eax,[timer_ticks]
mov [timer_ticks_com],eax
jmp @@EndMouseInterrupt
@@Error:
; Произошел сбой в порядке передачи информации от
; мыши, обнулить счетчик байтов пакета данных
mov [MouseByteNumber],0
@@EndMouseInterrupt:
call ready_for_next_irq
ret
mouse_acceleration_com1:
push eax
mov eax,[timer_ticks]
sub eax,[timer_ticks_com]
cmp eax,[mouse_delay]
pop eax
ja @f
imul ax,[mouse_speed_factor]
@@:
ret

View File

@ -0,0 +1,130 @@
; Номер принимаемого от мыши байта
MouseByteNumber_1 DB 0
; Трехбайтовая структура данных, передаваемая мышью
FirstByte_1 DB 0
SecondByte_1 DB 0
ThirdByte_1 DB 0
timer_ticks_com_1 dd 0
;***************************************
;* НОВЫЙ ОБРАБОТЧИК ПРЕРЫВАНИЯ ОТ МЫШИ *
;***************************************
check_mouse_data_com2:
; cmp [com2_mouse_detected],0
; je @@EndMouseInterrupt_1
; Проверить наличие данных
mov DX,2F8h ;[COMPortBaseAddr]
add DX,5 ;xFDh
in AL,DX
test AL,1 ;Данные готовы?
jz @@Error_1
; Ввести данные
mov DX,2F8h ;[COMPortBaseAddr] ;xF8h
in AL,DX
; Сбросить старший незначащий бит
and AL,01111111b
; Определить порядковый номер принимаемого байта
cmp [MouseByteNumber_1],0
je @@FirstByte_1
cmp [MouseByteNumber_1],1
je @@SecondByte_1
cmp [MouseByteNumber_1],2
je @@ThirdByte_1
jmp @@Error_1
; Сохранить первый байт данных
@@FirstByte_1:
test AL,1000000b ;Первый байт посылки?
jz @@Error_1
mov [FirstByte_1],AL
inc [MouseByteNumber_1] ;увеличить счетчик
jmp @@EndMouseInterrupt_1
; Сохранить второй байт данных
@@SecondByte_1:
test AL,1000000b
jnz @@Error_1
mov [SecondByte_1],AL
inc [MouseByteNumber_1] ;увеличить счетчик
jmp @@EndMouseInterrupt_1
; Сохранить третий байт данных
@@ThirdByte_1:
test AL,1000000b
jnz @@Error_1
mov [ThirdByte_1],AL ;увеличить счетчик
mov [MouseByteNumber_1],0
; (Пакет данных от мыши принят полностью).
; Записать новое значение состояния кнопок мыши
mov al,[FirstByte_1] ;[0xfb01]
mov ah,al
shr al,3
and al,2
shr ah,5
and ah,1
add al,ah
mov [BTN_DOWN],al
mov [mouse_active],1
; Прибавить перемещение по X к координате X
mov AL,[FirstByte_1]
shl AL,6
or AL,[SecondByte_1]
cbw
call mouse_acceleration_com2
add AX,[MOUSE_X] ;[XCoordinate]
; Курсор не должен выходить за левую или
; правую границу экрана
js @@X1_1
cmp AX,[ScreenWidth] ;ScreenLength
jb @@X2_1
; Установить координату X по правой границе
mov AX,[ScreenWidth] ;ScreenLength-1
dec ax
jmp @@X2_1
@@X1_1:
; Установить координату X по левой границе
xor AX,AX
@@X2_1:
mov [MOUSE_X],AX ;[XCoordinate]
; Прибавить перемещение по Y к координате Y
mov AL,[FirstByte_1]
and AL,00001100b
shl AL,4
or AL,[ThirdByte_1]
cbw
call mouse_acceleration_com2
add AX,[MOUSE_Y] ;[YCoordinate]
; Курсор не должен выходить за верхнюю или
; нижнюю границу экрана
js @@Y1_1
cmp AX,[ScreenHeight] ;ScreenHeigth
jb @@Y2_1
; Установить координату X по нижней границе
mov AX,[ScreenHeight] ;ScreenHeigth-1
dec ax
jmp @@Y2_1
@@Y1_1:
; Установить координату X по верхней границе
xor AX,AX
@@Y2_1:
mov [MOUSE_Y],AX ;[YCoordinate]
mov eax,[timer_ticks]
mov [timer_ticks_com_1],eax
jmp @@EndMouseInterrupt_1
@@Error_1:
; Произошел сбой в порядке передачи информации от
; мыши, обнулить счетчик байтов пакета данных
mov [MouseByteNumber_1],0
@@EndMouseInterrupt_1:
call ready_for_next_irq
ret
mouse_acceleration_com2:
push eax
mov eax,[timer_ticks]
sub eax,[timer_ticks_com_1]
cmp eax,[mouse_delay]
pop eax
ja @f
imul ax,[mouse_speed_factor]
@@:
ret

View File

@ -0,0 +1,170 @@
; Номер принимаемого от мыши байта
MouseByteNumber_2 DB 0
; Трехбайтовая структура данных, передаваемая мышью
FirstByte_2 DB 0
SecondByte_2 DB 0
ThirdByte_2 DB 0
timer_ticks_ps2 dd 0
;**************************************
;* ОБРАБОТЧИК ПРЕРЫВАНИЯ ОТ МЫШИ PS/2 *
;**************************************
check_mouse_data_ps2:
cmp [ps2_mouse_detected],0
je @@EndMouseInterrupt_2
call Wait8042BufferEmpty ;очистка буфера
in AL,0x60 ;получить скэн-код
; Выбирать порядковый номер принимаемого байта
cmp [MouseByteNumber_2],0
je @@SaveFirstByte
cmp [MouseByteNumber_2],1
je @@SaveSecondByte
cmp [MouseByteNumber_2],2
je @@SaveThirdByte
jmp @@Error_2
; Записать первый байт посылки
@@SaveFirstByte:
test AL,1000b ;первый байт посылки?
jz @@Error_2 ;сбой синхронизации
mov [FirstByte_2],AL
inc [MouseByteNumber_2]
jmp @@EndMouseInterrupt_2
; Записать второй байт посылки
@@SaveSecondByte:
mov [SecondByte_2],AL
inc [MouseByteNumber_2]
jmp @@EndMouseInterrupt_2
; Записать третий байт посылки
@@SaveThirdByte:
mov [ThirdByte_2],AL
mov [MouseByteNumber_2],0
; (пакет данных от мыши принят полностью)
; Записать новое значение байта состояния кнопок
mov al,[FirstByte_2] ;[0xfb01]
and eax,3
mov [BTN_DOWN],al
mov [mouse_active],1
; Вычислить новую X-координату курсора
; Занести в AX перемещение по X
mov AH,0 ;дублируем знак во все разряды AH
mov AL,[FirstByte_2]
test AL,10000b
jz @@M0
mov AH,0FFh
; Занести в AL младший байт
@@M0:
mov AL,[SecondByte_2]
call mouse_acceleration_ps2
; Вычислить новое значение координаты
; курсора по X
add AX,[MOUSE_X] ;[XCoordinate]
cmp AX,0
jge @@M1
mov AX,0
jmp @@M2
@@M1:
cmp AX,[ScreenWidth] ;ScreenLength
jl @@M2
mov AX,[ScreenWidth] ;ScreenLength-1
dec ax
@@M2:
mov [MOUSE_X],AX ;[XCoordinate]
; Вычисляем новую Y-координату курсора
; Занести в AX перемещение по Y
mov AH,0 ;дублируем знак во все разряды AH
mov AL,[FirstByte_2]
test AL,100000b
jz @@M3
mov AH,0FFh
; Занести в AL младший байт
@@M3:
mov AL,[ThirdByte_2]
call mouse_acceleration_ps2
; Вычислить новое значение координаты курсора
; по Y (Y-координата мыши PS/2 направлена
; противоположно экранной)
neg AX
add AX,[MOUSE_Y] ;[YCoordinate]
cmp AX,0
jge @@M4
mov AX,0
jmp @@M5
@@M4:
cmp AX,[ScreenHeight] ;ScreenHeigth
jl @@M5
mov AX,[ScreenHeight] ;ScreenHeigth-1
dec ax
@@M5:
mov [MOUSE_Y],AX ;[YCoordinate]
; Показать курсор в новой позиции
mov eax,[timer_ticks]
mov [timer_ticks_ps2],eax
jmp @@EndMouseInterrupt_2
; Обнаружен сбой в порядке передачи информации от мыши
@@Error_2:
mov [MouseByteNumber_2],0
; Нормальное завершение прерывани
@@EndMouseInterrupt_2:
call ready_for_next_irq_1
ret
mouse_acceleration_ps2:
push eax
mov eax,[timer_ticks]
sub eax,[timer_ticks_ps2]
cmp eax,[mouse_delay]
pop eax
ja @f
imul ax,[mouse_speed_factor]
@@:
ret
;***********************************************
;* ОЖИДАНИЕ ОЧИСТКИ ВХОДНОГО БУФЕРА I8042 *
;* При выходе из процедуры: *
;* флаг ZF установлен - нормальное завершение, *
;* флаг ZF сброшен - ошибка тайм-аута. *
;***********************************************
Wait8042BufferEmpty:
; push CX
; mov CX,0FFFFh ;задать число циклов ожидани
;@@kb:
; in AL,64h ;получить статус
; test AL,10b ;буфер i8042 свободен?
; loopnz @@kb ;если нет, то цикл
; pop CX
push ecx
xor ecx,ecx
@@:
in al,64h
test al,00000010b
loopnz @b
pop ecx
;Если при выходе из подпрограммы сброшен
;флаг ZF - ошибка
ret ;возврат в подпрограмму
;***************************************
;* ОЖИДАНИЕ ПОСТУПЛЕНИЯ ДАННЫХ ОТ МЫШИ *
;***************************************
WaitMouseData:
; push CX
; mov CX,0FFFFh ;задать число циклов ожидани
;@@mouse:
; in AL,64h ;опросить регистр статуса
; test AL,100000b ;данные поступили?
; loopz @@mouse ;если нет, то цикл
; pop CX
push ecx
mov ECX,0FFFFh
@@:
in al,64h
test al,100000b
loopz @b
pop ecx
;Если при выходе из подпрограммы установлен
;флаг ZF - ошибка
ret

View File

@ -0,0 +1,377 @@
; check mouse
;
;
; FB00 -> FB0F mouse memory 00 chunk count - FB0A-B x - FB0C-D y
; FB10 -> FB17 mouse color mem
; FB21 x move
; FB22 y move
; FB30 color temp
; FB28 high bits temp
; FB4A -> FB4D FB4A-B x-under - FB4C-D y-under
; FC00 -> FCFE com1/ps2 buffer
; FCFF com1/ps2 buffer count starting from FC00
uglobal
mousecount dd 0x0
mousedata dd 0x0
endg
mouse_delay dd 10
mouse_speed_factor dw 3
include 'm_ps2.inc'
include 'm_com1.inc'
include 'm_com2.inc'
;test_mario79:
; push esi
; push eax
; mov [write_error_to],process_test_m79+43
; movzx eax,al ;[DevErrorCode]
; call writehex
; mov esi,process_test_m79
; call sys_msg_board_str
; pop eax
; pop esi
; ret
;process_test_m79 db 'K : Process - test Mario79 error 00000000',13,10,0
__sys_draw_mouse_under:
; return old picture
cmp [set_hw_cursor], 0
jz @F
pushad
movzx eax,word [X_UNDER]
movzx ebx,word [Y_UNDER]
stdcall [hw_restore], eax, ebx
popad
ret
@@:
pushad
xor ecx,ecx
xor edx,edx
align 4
mres:
movzx eax,word [X_UNDER]
movzx ebx,word [Y_UNDER]
add eax,ecx
add ebx,edx
push ecx
push edx
push eax
push ebx
mov eax,edx
shl eax,6
shl ecx,2
add eax,ecx
add eax,mouseunder
mov ecx,[eax]
pop ebx
pop eax
mov edi, 1 ;force
call [putpixel]
pop edx
pop ecx
inc ecx
cmp ecx, 16
jnz mres
xor ecx, ecx
inc edx
cmp edx, 24
jnz mres
popad
ret
save_draw_mouse:
cmp [set_hw_cursor], 0
jz @F
pushad
mov [X_UNDER],ax
mov [Y_UNDER],bx
movzx eax,word [MOUSE_Y]
movzx ebx,word [MOUSE_X]
push eax
push ebx
mov ecx, [ScreenWidth]
inc ecx
mul ecx
movzx edx, byte [display_data+ebx+eax]
shl edx, 8
mov ecx, [edx+SLOT_BASE+APPDATA.cursor]
cmp [ecx+CURSOR.magic], 'CURS'
jne .fail
; cmp [ecx+CURSOR.size], CURSOR_SIZE
; jne .fail
push ecx
call [set_hw_cursor]
popad
ret
.fail:
mov ecx, [def_cursor]
mov [edx+SLOT_BASE+APPDATA.cursor], ecx
push ecx
call [set_hw_cursor]
popad
ret
@@:
pushad
; save & draw
mov [X_UNDER],ax
mov [Y_UNDER],bx
push eax
push ebx
mov ecx,0
mov edx,0
align 4
drm:
push eax
push ebx
push ecx
push edx
; helloworld
push ecx
add eax,ecx ; save picture under mouse
add ebx,edx
push ecx
call getpixel
mov [COLOR_TEMP],ecx
pop ecx
mov eax,edx
shl eax,6
shl ecx,2
add eax,ecx
add eax,mouseunder
mov ebx,[COLOR_TEMP]
mov [eax],ebx
pop ecx
mov edi,edx ; y cycle
shl edi,4 ; *16 bytes per row
add edi,ecx ; x cycle
mov esi, edi
add edi, esi
add edi, esi ; *3
add edi,[MOUSE_PICTURE] ; we have our str address
mov esi, edi
add esi, 16*24*3
push ecx
mov ecx, [COLOR_TEMP]
call combine_colors
mov [MOUSE_COLOR_MEM], ecx
pop ecx
pop edx
pop ecx
pop ebx
pop eax
add eax,ecx ; we have x coord+cycle
add ebx,edx ; and y coord+cycle
push ecx
mov ecx, [MOUSE_COLOR_MEM]
mov edi, 1
call [putpixel]
pop ecx
mov ebx,[esp+0] ; pure y coord again
mov eax,[esp+4] ; and x
inc ecx ; +1 cycle
cmp ecx,16 ; if more than 16
jnz drm
xor ecx, ecx
inc edx
cmp edx,24
jnz drm
add esp,8
popad
ret
combine_colors:
; in
; ecx - color ( 00 RR GG BB )
; edi - ref to new color byte
; esi - ref to alpha byte
;
; out
; ecx - new color ( roughly (ecx*[esi]>>8)+([edi]*[esi]>>8) )
push eax
push ebx
push edx
push ecx
xor ecx, ecx
; byte 2
mov eax, 0xff
sub al, [esi+0]
mov ebx, [esp]
shr ebx, 16
and ebx, 0xff
mul ebx
shr eax, 8
add ecx, eax
xor eax, eax
xor ebx, ebx
mov al, [edi+0]
mov bl, [esi+0]
mul ebx
shr eax, 8
add ecx, eax
shl ecx, 8
; byte 1
mov eax, 0xff
sub al, [esi+1]
mov ebx, [esp]
shr ebx, 8
and ebx, 0xff
mul ebx
shr eax, 8
add ecx, eax
xor eax, eax
xor ebx, ebx
mov al, [edi+1]
mov bl, [esi+1]
mul ebx
shr eax, 8
add ecx, eax
shl ecx, 8
; byte 2
mov eax, 0xff
sub al, [esi+2]
mov ebx, [esp]
and ebx, 0xff
mul ebx
shr eax, 8
add ecx, eax
xor eax, eax
xor ebx, ebx
mov al, [edi+2]
mov bl, [esi+2]
mul ebx
shr eax, 8
add ecx, eax
pop eax
pop edx
pop ebx
pop eax
ret
__sys_disable_mouse:
cmp dword [MOUSE_VISIBLE],dword 0
je @f
ret
@@:
pushad
cmp [CURRENT_TASK],dword 1
je disable_m
mov edx,[CURRENT_TASK]
shl edx,5
add edx,window_data
movzx eax, word [MOUSE_X]
movzx ebx, word [MOUSE_Y]
mov ecx,[ScreenWidth]
inc ecx
imul ecx,ebx
add ecx,eax
add ecx, display_data
mov eax, [CURRENT_TASK]
movzx ebx, byte [ecx]
cmp eax,ebx
je yes_mouse_disable
movzx ebx, byte [ecx+16]
cmp eax,ebx
je yes_mouse_disable
mov ebx,[ScreenWidth]
inc ebx
imul ebx,10
add ecx,ebx
movzx ebx, byte [ecx]
cmp eax,ebx
je yes_mouse_disable
movzx ebx, byte [ecx+16]
cmp eax,ebx
je yes_mouse_disable
jmp no_mouse_disable
yes_mouse_disable:
mov edx,[CURRENT_TASK]
shl edx,5
add edx,window_data
movzx eax, word [MOUSE_X]
movzx ebx, word [MOUSE_Y]
mov ecx,[edx+0] ; mouse inside the area ?
add eax,14
cmp eax,ecx
jb no_mouse_disable
sub eax,14
add ecx,[edx+8]
cmp eax,ecx
jg no_mouse_disable
mov ecx,[edx+4]
add ebx,20
cmp ebx,ecx
jb no_mouse_disable
sub ebx,20
add ecx,[edx+12]
cmp ebx,ecx
jg no_mouse_disable
disable_m:
cmp dword [MOUSE_VISIBLE],dword 0
jne no_mouse_disable
cli
call [draw_mouse_under]
sti
mov [MOUSE_VISIBLE],dword 1
no_mouse_disable:
popad
ret
__sys_draw_pointer:
cmp [mouse_pause],0
je @f
ret
@@:
push eax
mov eax,[timer_ticks]
sub eax,[MouseTickCounter]
cmp eax,1
ja @f
pop eax
ret
@@:
mov eax,[timer_ticks]
mov [MouseTickCounter],eax
pop eax
pushad
cmp dword [MOUSE_VISIBLE],dword 0 ; mouse visible ?
je chms00
mov [MOUSE_VISIBLE], dword 0
movzx ebx,word [MOUSE_Y]
movzx eax,word [MOUSE_X]
cli
call save_draw_mouse
sti
nodmu2:
popad
ret
chms00:
movzx ecx,word [X_UNDER]
movzx edx,word [Y_UNDER]
movzx ebx,word [MOUSE_Y]
movzx eax,word [MOUSE_X]
cmp eax,ecx
jne redrawmouse
cmp ebx,edx
jne redrawmouse
jmp nodmp
redrawmouse:
cli
call [draw_mouse_under]
call save_draw_mouse
sti
nodmp:
popad
ret

View File

@ -0,0 +1,191 @@
;setting date,time,clock and alarm-clock
;add sys_settime at servetable as for ex. 22 fcn:
; 22 - SETTING DATE TIME, CLOCK AND ALARM-CLOCK
; ebx =0 - set time ecx - 00SSMMHH
; ebx =1 - set date ecx=00DDMMYY
; ebx =2 - set day of week ecx- 1-7
; ebx =3 - set alarm-clock ecx - 00SSMMHH
; out: 0 -Ok 1 -wrong format 2 -battery low
sys_settime:
mov ecx,eax
cli
mov al,0x0d
out 0x70,al
in al,0x71
bt ax,7
jnc bat_low
cmp ecx,2 ;day of week
jne nosetweek
test ebx,ebx ;test day of week
je wrongtime
cmp ebx,7
ja wrongtime
mov dx,0x70
call startstopclk
dec edx
mov al,6
out dx,al
inc edx
mov al,bl
out dx,al
jmp endsettime
nosetweek: ;set date
cmp ecx,1
jne nosetdate
cmp bl,0x99 ;test year
ja wrongtime
shl ebx,4
cmp bl,0x90
ja wrongtime
cmp bh,0x99 ;test month
ja wrongtime
shr ebx,4
test bh,bh
je wrongtime
cmp bh,0x12
ja wrongtime
shl ebx,8
bswap ebx ;ebx=00YYMMDD
test bl,bl ;test day
je wrongtime
shl ebx,4
cmp bl,0x90
ja wrongtime
shr ebx,4
cmp bh,2 ;February
jne testday
cmp bl,0x29
ja wrongtime
jmp setdate
testday:
cmp bh,8
jb testday1 ;Aug-Dec
bt bx,8
jnc days31
jmp days30
testday1:
bt bx,8 ;Jan-Jul ex.Feb
jnc days30
days31:
cmp bl,0x31
ja wrongtime
jmp setdate
days30:
cmp bl,0x30
ja wrongtime
setdate:
mov dx,0x70
call startstopclk
dec edx
mov al,7 ;set days
out dx,al
inc edx
mov al,bl
out dx,al
dec edx
mov al,8 ;set months
out dx,al
inc edx
mov al,bh
out dx,al
dec edx
mov al,9 ;set years
out dx,al
inc edx
shr ebx,8
mov al,bh
out dx,al
jmp endsettime
nosetdate: ;set time or alarm-clock
cmp ecx,3
ja wrongtime
cmp bl,0x23
ja wrongtime
cmp bh,0x59
ja wrongtime
shl ebx,4
cmp bl,0x90
ja wrongtime
cmp bh,0x92
ja wrongtime
shl ebx,4
bswap ebx ;00HHMMSS
cmp bl,0x59
ja wrongtime
shl ebx,4
cmp bl,0x90
ja wrongtime
shr ebx,4
mov dx,0x70
call startstopclk
dec edx
cmp ecx,3
je setalarm
xor eax,eax ;al=0-set seconds
out dx,al
inc edx
mov al,bl
out dx,al
dec edx
mov al,2 ;set minutes
out dx,al
inc edx
mov al,bh
out dx,al
dec edx
mov al,4 ;set hours
out dx,al
inc edx
shr ebx,8
mov al,bh
out dx,al
jmp endsettime
setalarm:
mov al,1 ;set seconds for al.
out dx,al
inc edx
mov al,bl
out dx,al
dec edx
mov al,3 ;set minutes for al.
out dx,al
inc edx
mov al,bh
out dx,al
dec edx
mov al,5 ;set hours for al.
out dx,al
inc edx
shr ebx,8
mov al,bh
out dx,al
dec edx
mov al,0x0b ;enable irq's
out dx,al
inc dx
in al,dx
bts ax,5 ;set bit 5
out dx,al
endsettime:
dec edx
call startstopclk
sti
mov [esp+36],dword 0
ret
bat_low:
sti
mov [esp+36],dword 2
ret
wrongtime:
sti
mov [esp+36],dword 1
ret
startstopclk:
mov al,0x0b
out dx,al
inc dx
in al,dx
btc ax,7
out dx,al
ret

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,40 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; KERNEL16.INC ;;
;; ;;
;; Included 16 bit kernel files for MenuetOS ;;
;; ;;
;; This file is kept separate as it will be easier to ;;
;; maintain and compile with an automated SETUP program ;;
;; in the future. ;;
;; ;;
;; Copyright Ville Turjanmaa, see file COPYING for details. ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;% +include
;!!!
if lang eq en
include "boot/booteng.inc" ; english system boot messages
else if lang eq ru
include "boot/bootru.inc" ; russian system boot messages
else if lang eq et
include "boot/bootet.inc" ; estonian system boot messages
else
include "boot/bootge.inc" ; german system boot messages
;!!!
end if
if lang eq et
include "boot/et.inc" ; Estonian font
else
include "boot/ru.inc" ; Russian font
end if
org $-0x10000
include "boot/bootcode.inc" ; 16 bit system boot code
include "bus/pci/pci16.inc"
;% -include

View File

@ -0,0 +1,303 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; KERNEL32.INC ;;
;; ;;
;; Included 32 bit kernel files for MenuetOS ;;
;; ;;
;; This file is kept separate as it will be easier to ;;
;; maintain and compile with an automated SETUP program ;;
;; in the future. ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; structure definition helper
macro struct name, [arg]
{
common
name@struct equ name
struc name arg {
}
macro struct_helper name
{
match xname,name
\{
virtual at 0
xname xname
sizeof.#xname = $ - xname
name equ sizeof.#xname
end virtual
\}
}
ends fix } struct_helper name@struct
;// mike.dld, 2006-29-01 [
; macros definition
macro diff16 title,l1,l2
{
local s,d
s = l2-l1
display title,': 0x'
repeat 8
d = 48 + s shr ((8-%) shl 2) and $0F
if d > 57
d = d + 65-57-1
end if
display d
end repeat
display 13,10
}
; \begin{diamond}[29.09.2006]
; may be useful for kernel debugging
; example 1:
; dbgstr 'Hello, World!'
; example 2:
; dbgstr 'Hello, World!', save_flags
macro dbgstr string*, f
{
local a
iglobal_nested
a db 'K : ',string,13,10,0
endg_nested
if ~ f eq
pushfd
end if
push esi
mov esi, a
call sys_msg_board_str
pop esi
if ~ f eq
popfd
end if
}
; \end{diamond}[29.09.2006]
;struc db [a] { common . db a
; if ~used .
; display 'not used db: ',`.,13,10
; end if }
;struc dw [a] { common . dw a
; if ~used .
; display 'not used dw: ',`.,13,10
; end if }
;struc dd [a] { common . dd a
; if ~used .
; display 'not used dd: ',`.,13,10
; end if }
;struc dp [a] { common . dp a
; if ~used .
; display 'not used dp: ',`.,13,10
; end if }
;struc dq [a] { common . dq a
; if ~used .
; display 'not used dq: ',`.,13,10
; end if }
;struc dt [a] { common . dt a
; if ~used .
; display 'not used dt: ',`.,13,10
; end if }
struc RECT {
.left dd ?
.top dd ?
.right dd ?
.bottom dd ?
}
virtual at 0
RECT RECT
end virtual
struc BOX {
.left dd ?
.top dd ?
.width dd ?
.height dd ?
}
virtual at 0
BOX BOX
end virtual
; constants definition
WSTATE_NORMAL = 00000000b
WSTATE_MAXIMIZED = 00000001b
WSTATE_MINIMIZED = 00000010b
WSTATE_ROLLEDUP = 00000100b
WSTATE_REDRAW = 00000001b
WSTATE_WNDDRAWN = 00000010b
WSTYLE_HASCAPTION = 00010000b
WSTYLE_CLIENTRELATIVE = 00100000b
struc TASKDATA
{
.event_mask dd ?
.pid dd ?
dw ?
.state db ?
db ?
dw ?
.wnd_number db ?
db ?
.mem_start dd ?
.counter_sum dd ?
.counter_add dd ?
.cpu_usage dd ?
}
virtual at 0
TASKDATA TASKDATA
end virtual
; structures definition
struc WDATA {
.box BOX
.cl_workarea dd ?
.cl_titlebar dd ?
.cl_frames dd ?
.reserved db ?
.fl_wstate db ?
.fl_wdrawn db ?
.fl_redraw db ?
}
virtual at 0
WDATA WDATA
end virtual
label WDATA.fl_wstyle byte at 0x13
struc APPDATA
{
.app_name db 11 dup(?)
db 5 dup(?)
.fpu_state dd ? ;+16
.ev_count dd ? ;+20
.fpu_handler dd ? ;+24
.sse_handler dd ? ;+28
.pl0_stack dd ? ;unused ;+32
.heap_base dd ? ;+36
.heap_top dd ? ;+40
.cursor dd ? ;+44
.fd_ev dd ? ;+48
.bk_ev dd ? ;+52
.fd_obj dd ? ;+56
.bk_obj dd ? ;+60
db 64 dup(?) ;+64
.wnd_shape dd ? ;+128
.wnd_shape_scale dd ? ;+132
dd ? ;+136
.mem_size dd ? ;+140
.saved_box BOX
.ipc_start dd ?
.ipc_size dd ?
.event_mask dd ?
.debugger_slot dd ?
dd ?
.keyboard_mode db ?
db 3 dup(?)
.dir_table dd ?
.dbg_event_mem dd ?
.dbg_regs:
.dbg_regs.dr0 dd ?
.dbg_regs.dr1 dd ?
.dbg_regs.dr2 dd ?
.dbg_regs.dr3 dd ?
.dbg_regs.dr7 dd ?
.wnd_caption dd ?
.wnd_clientbox BOX
}
virtual at 0
APPDATA APPDATA
end virtual
;// mike.dld, 2006-29-01 ]
; Core functions
include "core/sync.inc" ; macros for synhronization objects
include "core/sys32.inc" ; process management
include "core/sched.inc" ; process scheduling
include "core/syscall.inc" ; system call
include "core/fpu.inc" ; all fpu/sse support
include "core/memory.inc"
include "core/heap.inc" ; kernel and app heap
include "core/malloc.inc" ; small kernel heap
include "core/taskman.inc"
include "core/dll.inc"
include "core/exports.inc"
; GUI stuff
include "gui/window.inc"
include "gui/event.inc"
include "gui/font.inc"
include "gui/button.inc"
; shutdown
include "boot/shutdown.inc" ; shutdown or restart
; file system
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 "fs/fs_lfn.inc" ; syscall, version 2
include "fs/iso9660.inc" ; read for iso9660 filesystem CD
; sound
include "sound/sb16.inc" ; playback for Sound Blaster 16
include "sound/playnote.inc" ; player Note for Speaker PC
; display
include "video/vesa12.inc" ; Vesa 1.2 functions
include "video/vesa20.inc" ; Vesa 2.0 functions
include "video/vga.inc" ; VGA 16 color functions
include "video/cursors.inc" ; cursors functions
; Network Interface & TCPIP Stack
include "network/stack.inc"
; Mouse pointer
include "gui/mouse.inc"
; Window skinning
include "gui/skincode.inc"
; Pci functions
include "bus/pci/pci32.inc"
; Floppy drive controller
include "blkdev/fdc.inc"
include "blkdev/flp_drv.inc"
; HD drive controller
include "blkdev/hd_drv.inc"
; CD drive controller
include "blkdev/cdrom.inc"
include "blkdev/cd_drv.inc"
; Character devices
include "hid/keyboard.inc"
include "hid/mousedrv.inc"
; setting date,time,clock and alarm-clock
include "hid/set_dtc.inc"
;% -include

View File

@ -0,0 +1,59 @@
;------------------------------------------------------------------
; use "iglobal" for inserting initialized global data definitions.
;------------------------------------------------------------------
macro iglobal {
IGlobals equ IGlobals,
macro __IGlobalBlock { }
macro iglobal_nested {
IGlobals equ IGlobals,
macro __IGlobalBlock \{ }
;-------------------------------------------------------------
; use 'uglobal' for inserting uninitialized global definitions.
; even when you define some data values, these variables
; will be stored as uninitialized data.
;-------------------------------------------------------------
macro uglobal {
UGlobals equ UGlobals,
macro __UGlobalBlock { }
macro uglobal_nested {
UGlobals equ UGlobals,
macro __UGlobalBlock \{ }
endg fix } ; Use endg for ending iglobal and uglobal blocks.
endg_nested fix \}
macro IncludeIGlobals{
macro IGlobals dummy,[n] \{ __IGlobalBlock
purge __IGlobalBlock \}
match I, IGlobals \{ I \} }
macro IncludeUGlobals{
macro UGlobals dummy,[n] \{
\common
\local begin, size
begin = $
virtual at $
\forward
__UGlobalBlock
purge __UGlobalBlock
\common
size = $ - begin
end virtual
rb size
\}
match U, UGlobals \{ U \} }
macro IncludeAllGlobals {
IncludeIGlobals
IncludeUGlobals
}
iglobal
endg
uglobal
endg

View File

@ -0,0 +1,16 @@
FASM=fasm
KSRC=kernel.asm
KOUT=kernel.mnt
en: kernel.asm
rm -f lang.inc
echo lang fix en > lang.inc
$(FASM) $(KSRC) $(KOUT)
ru: kernel.asm
rm -f lang.inc
echo lang fix ru > lang.inc
$(FASM) $(KSRC) $(KOUT)
clean:
rm -f $(KOUT)
rm -f lang.inc

View File

@ -0,0 +1,224 @@
;
; MEMORY MAP
;
; Boot:
;
; 0:9000 byte bits per pixel
; 0:9001 word scanline length
; 0:9008 word vesa video mode
; 0:900A word X res
; 0:900C word Y res
; 0:9010 byte mouse port - not used
; 0:9014 dword Vesa 1.2 pm bank switch
; 0:9018 dword Vesa 2.0 LFB address
; 0:901C byte 0 or 1 : enable MTRR graphics acceleration
; 0:901D byte not used anymore (0 or 1 : enable system log display)
; 0:901E byte 0 or 1 : enable direct lfb write, paging disabled
; 0:901F byte DMA write : 1=yes, 2=no
; 0:9020 8bytes pci data
; 0:9030 byte VRR start enabled 1, 2-no
; 0:9031 word IDEContrRegsBaseAddr
; 0x9040 - dword - entry point of APM BIOS
; 0x9044 - word - version (BCD)
; 0x9046 - word - flags
;
; Runtime:
;
; 0000 -> 1FFF window_data - 256 entries
;
; 0000 dword x start
; 0004 dword y start
; 0008 dword x size
; 000C dword y size
; 0010 dword color of work area
; 0014 dword color of grab bar
; 0018 dword color of frames
; 001C dword window flags, +30 = window drawn, +31 redraw flag
;
; 2000 -> 2FFF free
;
; 3000 -> 4FFF task list - 256 entries
;
; 00 dword process count
; 04 dword no of processes
; 10 dword base of running process at 0x3000+
;
; 20 dword application event mask
; 24 dword PID - process identification number
; 2a byte slot state: 0=running, 1,2=suspended
; 3=zombie, 4=terminate,
; 5=waiting for event, 9 = not used
; 2e byte window number on screen
; 30 dword exact position in memory
; 34 dword counter sum
; 38 dword time stamp counter add
; 3c dword cpu usage in cpu timer tics
;
;
; 5000 -> 68FF free
; 6900 -> 6EFF saved picture under mouse pointer
;
; 6F00 -> 6FFF free
;
; 7000 -> 7FFF used CD driver
;
; 8000 -> A3FF used FLOPPY driver
;
; A400 -> B0FF free
; B100 -> B2FF IDT
; B300 -> BFFF free
; C000 -> C3FF window stack C000 no of windows - all in words
; C402 -> C7FF window position in stack
; D000 -> D1FF FDC controller
; D200 -> D3FF FDC controller for Fat12
; D400 -> DFFF free
; E000 byte multitasking started
; E020 dword putpixel address
; E024 dword getpixel address
; E030 dword Vesa 1.2 pm bank switch address
; F200 dword mousepicture -pointer
; F204 dword mouse appearance counter
; F300 dword x & y temp for windowmove
; F400 byte no of keys in buffer
; F401 byte 'buffer'
; F402 -> F4FF reserved for keys
; F500 byte no of buttons in buffer
; F501 dword 'buffer'
; F502 -> F5FF reserved for buttons
; F600 dword tsc / second
; F604 byte mouse port: 1 ps2, 2 com1, 3 com2
; FB00 -> FB0F mouse memory 00 chunk count - FB0A-B x - FB0C-D y
; FB10 -> FB17 mouse color mem
; FB21 x move
; FB22 y move
; FB28 high bits temp
; FB30 color temp
; FB40 byte buttons down
; FB44 byte 0 mouse down -> do not draw
; FB4A -> FB4D FB4A-B x-under - FB4C-D y-under
; FBF1 byte bits per pixel
; FC00 -> FCFE com1/ps2 buffer
; FCFF com1/ps2 buffer count starting from FC00
; FE00 dword screen x size
; FE04 dword screen y size
; FE08 dword screen y multiplier
; FE0C dword screen mode
; FE80 dword address of LFB in physical
; FE84 dword address of applications memory start in physical
; FE88 dword address of button list
; FE8C dword memory to use
; FF00 byte 1 = system shutdown request
; FF01 dword free
; FFF0 byte 1 = redraw background request from app
; FFF1 byte 1 = diskette int occur
; FFF2 write and read bank in screen
; FFF4 byte 0 if first mouse draw & do not return picture under
; FFF5 byte 1 do not draw pointer
; FFFF byte do not change task for 1/100 sec.
;
; 10000 -> 3DBFF kernel, 32-bit run-time code (up to 183 Kb)
; 3DC00 -> 3EBFF stack at boot time (4Kb)
; 3EC00 -> 3F5FF basic text font II
; 3F600 -> 3FFFF basic text font I
; 40000 -> 4FFFF data of retrieved disks and partitions (Mario79)
; 50000 -> 50FFF main page directory
; 50200 -> 5FFFF pages bitmap
; 60000 -> 7FFFF free (128 Kb)
; 80000 -> 8FFFF additional app info, in 256 byte steps - 256 entries
;
; 00 11db name of app running
; 10 108db floating point unit save area
; 7f byte 0= no fpu saved , 1= fpu saved to 0x10 -> restore
; 80 dword address of random shaped window area
; 84 byte shape area scale
; 88 dword free
; 8C dword application memory size
; 90 dword window X position save
; 94 dword window Y position save
; 98 dword window X size save
; 9C dword window Y size save
; A0 dword IPC memory start
; A4 dword IPC memory size
; A8 dword event bits: mouse, stack,..
; AC dword 0 or debugger slot
; B0 dword free
; B4 byte keyboard mode: 0 = keymap, 1 = scancodes
; B8 dword physical address of directory table
; BC dword address of debug event memory
; C0 5 dd thread debug registers: DR0,DR1,DR2,DR3,DR7
;
; 90000 -> 9FFFF tmp
; A0000 -> AFFFF screen access area
; B0000 -> FFFFF bios rest in peace -area
; 100000 -> 27FFFF diskette image
; 280000 -> 281FFF ramdisk fat
; 282000 -> 283FFF floppy fat
;
; 284000 -> 29FFFF free (112 Kb)
;
; 2A0000 -> 2B00ff wav device data
; 2C0000 -> 2C3fff button info
;
; 0000 word number of buttons
; first button entry at 0x10
; +0000 word process number
; +0002 word button id number : bits 00-15
; +0004 word x start
; +0006 word x size
; +0008 word y start
; +000A word y size
; +000C word button id number : bits 16-31
;
; 2C4000 -> 2CFFFF free (48Kb)
;
; 2D0000 -> 2DFFFF reserved port area
;
; 0000 dword no of port areas reserved
; 0010 dword process id
; dword start port
; dword end port
; dword 0
;
; 2E0000 -> 2EFFFF irq data area
; 2F0000 -> 2FFFFF low memory save
;
; 300000 -> 45FFFF background image, max 1,375 M
;
; 460000 -> 5FFFFF display info
;
; 600000 -> 6FFFFF hd cache
;
; 700000 -> 71ffff tcp memory (128 kb)
; 720000 -> 75ffff free (256 kb)
;
; 760000 -> 76ffff !vrr driver
; 770000 -> 777fff tcp memory ( 32 kb)
;
; 780000 -> 987FFF TSS and IO map for (8192*8)=65536 ports
; (128+8192)*256 = 2129920 = 0x208000
;
; 988000 -> 98AFFF draw_data - 256 entries
;
; 00 dword draw limit - x start
; 04 dword draw limit - y start
; 08 dword draw limit - x end
; 0C dword draw limit - y end
;
;
; 0x0098B000 -> kernel heap
;
; 0x01FFFFFF heap min limit
; 0x7DBFFFFF heap max limit
; 0x7DC00000 -> 0x7FBFFFFF LFB 32Mb
; 0x7DC00000 -> 0x7E3FFFFF application available LFB 8Mb
; 0x7E400000 -> 0x7FBFFFFF kernel LFB part 24 Mb
; 0x7FC00000 -> 0x7FFFFFFF page tables 4Mb
; 0x80000000 -> 0xFFFFFFFF application 2Gb

View File

@ -0,0 +1,546 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; ARP.INC
;;
;; Address Resolution Protocol
;;
;; Last revision: 10.11.2006
;;
;; This file contains the following:
;; arp_table_manager - Manages an ARPTable
;; arp_request - Sends an ARP request on the ethernet
;; arp_handler - Called when an ARP packet is received
;;
;; Changes history:
;; 22.09.2003 - [Mike Hibbett] : mikeh@oceanfree.net
;; 11.11.2006 - [Johnny_B] and [smb]
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ARP_NO_ENTRY equ 0
ARP_VALID_MAPPING equ 1
ARP_AWAITING_RESPONSE equ 2
ARP_RESPONSE_TIMEOUT equ 3
struc ARP_ENTRY ;=14 bytes
{ .IP dd ? ;+00
.MAC dp ? ;+04
.Status dw ? ;+10
.TTL dw ? ;+12 : ( in seconds )
}
virtual at 0
ARP_ENTRY ARP_ENTRY
end virtual
; The TTL field is decremented every second, and is deleted when it
; reaches 0. It is refreshed every time a packet is received
; If the TTL field is 0xFFFF it is a static entry and is never deleted
; The status field can be the following values:
; 0x0000 entry not used
; 0x0001 entry holds a valid mapping
; 0x0002 entry contains an IP address, awaiting ARP response
; 0x0003 No response received to ARP request.
; The last status value is provided to allow the network layer to delete
; a packet that is queued awaiting an ARP response
; The follow is the ARP Table.
; This table must be manually updated and the kernel recompilied if
; changes are made to it.
; Empty entries are filled with zeros
ARP_ENTRY_SIZE equ 14 ; Number of bytes per entry
ARP_TABLE_SIZE equ 20 ; Size of table
ARP_TABLE_ENTRIES equ 0 ; Number of static entries in the table
;TO ADD A STATIC ENTRY, DONT FORGET, PUT "ARPTable" from "uglobal" to "iglobal"!!!
;AND ALSO - IP and MAC have net byte-order, BUT STATUS AND TTL HAVE A MIRROR BYTE-ORDER!!!
uglobal
ARPTable:
;example, static entry -> db 11,22,33,44, 0x11,0x22,0x33,0x44,0x55,0x66, 0x01,0x00, 0xFF,0xFF
times ( ARP_TABLE_SIZE - ARP_TABLE_ENTRIES ) * ARP_ENTRY_SIZE db 0
endg
iglobal
NumARP: dd ARP_TABLE_ENTRIES
ARPTable_ptr dd ARPTable ;pointer to ARPTable
endg
ARP_REQ_OPCODE equ 0x0100 ;request
ARP_REP_OPCODE equ 0x0200 ;reply
struc ARP_PACKET
{ .HardwareType dw ? ;+00
.ProtocolType dw ? ;+02
.HardwareSize db ? ;+04
.ProtocolSize db ? ;+05
.Opcode dw ? ;+06
.SenderMAC dp ? ;+08
.SenderIP dd ? ;+14
.TargetMAC dp ? ;+18
.TargetIP dd ? ;+24
}
virtual at 0
ARP_PACKET ARP_PACKET
end virtual
;***************************************************************************
; Function
; arp_table_manager [by Johnny_B]
;
; Description
; Does a most required operations with ARP-table
; IN:
; Operation: see Opcode's constants below
; Index: Index of entry in the ARP-table
; Extra: Extra parameter for some Opcodes
; OUT:
; EAX = Returned value depends on opcodes, more detailed see below
;
;***************************************************************************
;Opcode's constants
ARP_TABLE_ADD equ 1
ARP_TABLE_DEL equ 2
ARP_TABLE_GET equ 3
ARP_TABLE_GET_ENTRIES_NUMBER equ 4
ARP_TABLE_IP_TO_MAC equ 5
ARP_TABLE_TIMER equ 6
;Index's constants
EXTRA_IS_ARP_PACKET_PTR equ 0 ;if Extra contain pointer to ARP_PACKET
EXTRA_IS_ARP_ENTRY_PTR equ -1 ;if Extra contain pointer to ARP_ENTRY
align 4
proc arp_table_manager stdcall uses ebx esi edi ecx edx,\
Opcode:DWORD,Index:DWORD,Extra:DWORD
mov ebx, dword[ARPTable_ptr] ;ARPTable base
mov ecx, dword[NumARP] ;ARP-entries counter
mov eax, dword[Opcode]
cmp eax, ARP_TABLE_TIMER
je .timer
cmp eax, ARP_TABLE_ADD
je .add
cmp eax, ARP_TABLE_DEL
je .del
cmp eax, ARP_TABLE_GET
je .get
cmp eax, ARP_TABLE_IP_TO_MAC
je .ip_to_mac
cmp eax, ARP_TABLE_GET_ENTRIES_NUMBER
je .get_entries_number
jmp .exit ;if unknown opcode
;;BEGIN TIMER
;;Description: it must be callback every second. It is responsible for removing expired routes.
;;IN: Operation: ARP_TABLE_TIMER
;; Index: must be zero
;; Extra: must be zero
;;OUT:
;; EAX=not defined
;;
.timer:
test ecx, ecx
jz .exit ;if NumARP=0 nothing to do
sub ecx, ARP_TABLE_ENTRIES ;ecx=dynamic entries number
jz .exit ;if NumARP=number of static entries then exit
add ebx, ARP_TABLE_ENTRIES*ARP_ENTRY_SIZE ;ebx=dynamic entries base
.timer_loop:
movsx esi, word [ebx + ARP_ENTRY.TTL]
cmp esi, 0xFFFFFFFF
je .timer_loop_end ;if TTL==0xFFFF then it's static entry
test esi, esi
jnz .timer_loop_end_with_dec ;if TTL!=0
; Ok, TTL is 0
;if Status==AWAITING_RESPONSE and TTL==0
;then we have to change it to ARP_RESPONSE_TIMEOUT
cmp word [ebx + ARP_ENTRY.Status], ARP_AWAITING_RESPONSE
jne @f
mov word [ebx + ARP_ENTRY.Status], ARP_RESPONSE_TIMEOUT
mov word [ebx + ARP_ENTRY.TTL], word 0x000A ;10 sec
jmp .timer_loop_end
@@:
;if TTL==0 and Status==VALID_MAPPING, we have to delete it
;if TTL==0 and Status==RESPONSE_TIMEOUT, delete too
mov esi, dword[NumARP]
sub esi, ecx ;esi=index of entry, will be deleted
stdcall arp_table_manager,ARP_TABLE_DEL,esi,0 ;opcode,index,extra
jmp .timer_loop_end
.timer_loop_end_with_dec:
dec word [ebx + ARP_ENTRY.TTL] ;decrease TTL
.timer_loop_end:
add ebx, ARP_ENTRY_SIZE
loop .timer_loop
jmp .exit
;;END TIMER
;;BEGIN ADD
;;Description: it adds an entry in the table. If ARP-table already
;; contains same IP, it will be updated.
;;IN: Operation: ARP_TABLE_ADD
;; Index: specifies what contains Extra-parameter
;; Extra: if Index==EXTRA_IS_ARP_PACKET_PTR,
;; then Extra contains pointer to ARP_PACKET,
;; otherwise Extra contains pointer to ARP_ENTRY
;;OUT:
;; EAX=index of entry, that has been added
;;
.add:
sub esp, ARP_ENTRY_SIZE ;Allocate ARP_ENTRY_SIZE byte in stack
mov esi, [Extra] ;pointer
mov edi, [Index] ;opcode
cmp edi, EXTRA_IS_ARP_PACKET_PTR
je .arp_packet_to_entry ;if Extra contain ptr to ARP_PACKET and we have to form arp-entry
;else it contain ptr to arp-entry
cld
; esi already has been loaded
mov edi, esp ;ebx + eax=ARPTable_base + ARP-entry_base(where we will add)
mov ecx,ARP_ENTRY_SIZE/2 ;ARP_ENTRY_SIZE must be even number!!!
rep movsw ;copy
jmp .search
.arp_packet_to_entry:
mov edx, dword[esi + ARP_PACKET.SenderIP] ;esi=base of ARP_PACKET
mov [esp + ARP_ENTRY.IP], edx
cld
lea esi, [esi + ARP_PACKET.SenderMAC]
lea edi, [esp + ARP_ENTRY.MAC]
movsd
movsw
mov word[esp + ARP_ENTRY.Status], ARP_VALID_MAPPING ; specify the type - a valid entry
mov word[esp + ARP_ENTRY.TTL], 0x0E10 ; = 1 hour
.search:
mov edx, dword[esp + ARP_ENTRY.IP] ;edx=IP-address, which we'll search
mov ecx, dword[NumARP] ;ecx=ARP-entries counter
jecxz .add_to_end ;if ARP-entries number == 0
imul eax, ecx, ARP_ENTRY_SIZE ;eax=current table size(in bytes)
@@:
sub eax, ARP_ENTRY_SIZE
cmp dword[ebx + eax + ARP_ENTRY.IP], edx
loopnz @b
jz .replace ; found, replace existing entry, ptr to it is in eax
.add_to_end:
;else add to end
or eax,-1 ;set eax=0xFFFFFFFF if adding is impossible
mov ecx, dword[NumARP]
cmp ecx, ARP_TABLE_SIZE
je .add_exit ;if arp-entries number is equal to arp-table maxsize
imul eax, dword[NumARP], ARP_ENTRY_SIZE ;eax=ptr to end of ARPTable
inc dword [NumARP] ;increase ARP-entries counter
.replace:
cld
mov esi, esp ;esp=base of ARP-entry, that will be added
lea edi, [ebx + eax] ;ebx + eax=ARPTable_base + ARP-entry_base(where we will add)
mov ecx,ARP_ENTRY_SIZE/2 ;ARP_ENTRY_SIZE must be even number!!!
rep movsw
mov ecx, ARP_ENTRY_SIZE
xor edx, edx ;"div" takes operand from EDX:EAX
div ecx ;eax=index of entry, which has been added
.add_exit:
add esp, ARP_ENTRY_SIZE ;free stack
jmp .exit
;;END ADD
;;BEGIN DEL
;;Description: it deletes an entry in the table.
;;IN: Operation: ARP_TABLE_DEL
;; Index: index of entry, that should be deleted
;; Extra: must be zero
;;OUT:
;; EAX=not defined
;;
.del:
mov esi, [Index]
imul esi, ARP_ENTRY_SIZE
mov ecx, (ARP_TABLE_SIZE - 1) * ARP_ENTRY_SIZE
sub ecx, esi
lea edi, [ebx + esi] ;edi=ptr to entry that should be deleted
lea esi, [edi + ARP_ENTRY_SIZE] ;esi=ptr to next entry
shr ecx,1 ;ecx/2 => ARP_ENTRY_SIZE MUST BE EVEN NUMBER!
cld
rep movsw
dec dword[NumARP] ;decrease arp-entries counter
jmp .exit
;;END DEL
;;BEGIN GET
;;Description: it reads an entry of table into buffer.
;;IN: Operation: ARP_TABLE_GET
;; Index: index of entry, that should be read
;; Extra: pointer to buffer for reading(size must be equal to ARP_ENTRY_SIZE)
;;OUT:
;; EAX=not defined
;;
.get:
mov esi, [Index]
imul esi, ARP_ENTRY_SIZE ;esi=ptr to required ARP_ENTRY
mov edi, [Extra] ;edi=buffer for reading
mov ecx, ARP_ENTRY_SIZE/2 ; must be even number!!!
cld
rep movsw
jmp .exit
;;END GET
;;BEGIN IP_TO_MAC
;;Description: it gets an IP from Index, scans each entry in the table and writes
;; MAC, that relates to specified IP, into buffer specified in Extra.
;; And if it cannot find an IP-address in the table, it does an ARP-request of that.
;;IN: Operation: ARP_TABLE_IP_TO_MAC
;; Index: IP that should be transformed into MAC
;; Extra: pointer to buffer where will be written the MAC-address.
;;OUT:
;; EAX=ARP table entry status code.
;; If EAX==ARP_NO_ENTRY, IP isn't found in the table and we have sent the request.
;; If EAX==ARP_AWAITING_RESPONSE, we wait the response from remote system.
;; If EAX==ARP_RESPONSE_TIMEOUT, remote system not responds too long.
;; If EAX==ARP_VALID_MAPPING, all is ok, we've got a true MAC.
;;
;; If MAC will equal to a zero, in the buffer. It means, that IP-address was not yet
;; resolved, or that doesn't exist. I recommend you, to do at most 3-5 calls of this
;; function with 1sec delay. sure, only if it not return a valid MAC after a first call.
;;
.ip_to_mac:
xor eax, eax
mov edi, dword[Extra]
cld
stosd
stosw
cmp dword[NumARP], 0
je .ip_to_mac_send_request ;if ARP-table not contain an entries, we have to request IP.
;EAX will be containing a zero, it's equal to ARP_NO_ENTRY
; first, check destination IP to see if it is on 'this' network.
; The test is:
; if ( destIP & subnet_mask == stack_ip & subnet_mask )
; destination is local
; else
; destination is remote, so pass to gateway
mov eax, [Index] ;eax=required IP
mov esi, eax
and esi, [subnet_mask]
mov ecx, [stack_ip]
and ecx, [subnet_mask]
cmp esi, ecx
je @f ;if we and target IP are located in the same network
mov eax, [gateway_ip]
@@:
mov ecx, dword[NumARP]
imul esi, ecx, ARP_ENTRY_SIZE ;esi=current ARP-table size
@@:
sub esi, ARP_ENTRY_SIZE
cmp [ebx + esi], eax ; ebx=ARPTable base
loopnz @b ; Return back if non match
jnz .ip_to_mac_send_request ; and request IP->MAC if none found in the table
; Return the entry status in eax
movzx eax, word[ebx + esi + ARP_ENTRY.Status]
; esi holds index
cld
lea esi, [ebx + esi + ARP_ENTRY.MAC]
mov edi, [Extra] ;edi=ptr to buffer for write MAC
movsd
movsw
jmp .exit
.ip_to_mac_send_request:
stdcall arp_request,[Index],stack_ip,node_addr ;TargetIP,SenderIP_ptr,SenderMAC_ptr
mov eax, ARP_NO_ENTRY
jmp .exit
;;END IP_TO_MAC
;;BEGIN GET_ENTRIES_NUMBER
;;Description: returns an ARP-entries number in the ARPTable
;;IN: Operation: ARP_TABLE_GET_ENTRIES_NUMBER
;; Index: must be zero
;; Extra: must be zero
;;OUT:
;; EAX=ARP-entries number in the ARPTable
.get_entries_number:
mov eax, dword[NumARP]
jmp .exit
;;END GET_ENTRIES_NUMBER
.exit:
ret
endp
;***************************************************************************
; Function
; arp_handler
;
; Description
; Called when an ARP packet is received on the ethernet
; Header + Data is in Ether_buffer[]
; It looks to see if the packet is a request to resolve this Hosts
; IP address. If it is, send the ARP reply packet.
; This Hosts IP address is in dword [stack_ip] ( in network format )
; This Hosts MAC address is in node_addr[6]
; All registers may be destroyed
;
;***************************************************************************
arp_handler:
; Is this a REQUEST?
; Is this a request for My Host IP
; Yes - So construct a response message.
; Send this message to the ethernet card for transmission
stdcall arp_table_manager,ARP_TABLE_ADD,EXTRA_IS_ARP_PACKET_PTR,ETH_FRAME.Data + ARP_PACKET
inc dword[arp_rx_count] ;increase ARP-packets counter
cmp word[ETH_FRAME.Data + ARP_PACKET.Opcode], ARP_REQ_OPCODE ; Is this a request packet?
jne .exit ; No - so exit
mov eax, [stack_ip]
cmp eax, dword[ETH_FRAME.Data + ARP_PACKET.TargetIP] ; Is it looking for my IP address?
jne .exit ; No - so quit now
; OK, it is a request for my MAC address. Build the frame and send it
; We can reuse the packet.
mov word[ETH_FRAME.Data + ARP_PACKET.Opcode], ARP_REP_OPCODE
cld
mov esi, ETH_FRAME.Data + ARP_PACKET.SenderMAC
mov edi, ETH_FRAME.Data + ARP_PACKET.TargetMAC
movsd
movsw
mov esi, ETH_FRAME.Data + ARP_PACKET.SenderIP
mov edi, ETH_FRAME.Data + ARP_PACKET.TargetIP
movsd
mov esi, node_addr
mov edi, ETH_FRAME.Data + ARP_PACKET.SenderMAC
movsd
movsw
mov esi, stack_ip
mov edi, ETH_FRAME.Data + ARP_PACKET.SenderIP
movsd
; Now, send it!
mov edi, ETH_FRAME.Data + ARP_PACKET.TargetMAC ;ptr to destination MAC address
mov bx, ETHER_ARP ;type of protocol
mov ecx, 28 ;data size
mov esi, ETH_FRAME.Data + ARP_PACKET ;ptr to data
call dword [drvr_transmit] ;transmit packet
.exit:
ret
;***************************************************************************
; Function
; arp_request [by Johnny_B]
;
; Description
; Sends an ARP request on the ethernet
; IN:
; TargetIP : requested IP address
; SenderIP_ptr : POINTER to sender's IP address(our system's address)
; SenderMAC_ptr : POINTER to sender's MAC address(our system's address)
; OUT:
; EAX=0 (if all is ok), otherwise EAX is not defined
;
; EBX,ESI,EDI will be saved
;
;***************************************************************************
proc arp_request stdcall uses ebx esi edi,\
TargetIP:DWORD, SenderIP_ptr:DWORD, SenderMAC_ptr:DWORD
inc dword[arp_tx_count] ; increase counter
sub esp, 28 ; allocate memory for ARP_PACKET
mov word[esp + ARP_PACKET.HardwareType],0x0100 ;Ethernet
mov word[esp + ARP_PACKET.ProtocolType],0x0008 ;IP
mov byte[esp + ARP_PACKET.HardwareSize],0x06 ;MAC-addr length
mov byte[esp + ARP_PACKET.ProtocolSize],0x04 ;IP-addr length
mov word[esp + ARP_PACKET.Opcode],0x0100 ;Request
cld
mov esi,[SenderMAC_ptr]
lea edi,[esp + ARP_PACKET.SenderMAC] ;Our MAC-addr
movsd
movsw
mov esi,[SenderIP_ptr]
lea edi,[esp + ARP_PACKET.SenderIP] ;Our IP-addr
movsd
xor eax, eax
lea edi, [esp + ARP_PACKET.TargetMAC] ;Required MAC-addr(zeroed)
stosd
stosw
mov esi, dword[TargetIP]
mov dword[esp + ARP_PACKET.TargetIP],esi ;Required IP-addr(we get it as function parameter)
; Now, send it!
mov edi, broadcast_add ; Pointer to 48 bit destination address
mov bx, ETHER_ARP ; Type of packet
mov ecx, 28 ; size of packet
lea esi, [esp + ARP_PACKET]; pointer to packet data
call dword [drvr_transmit] ; Call the drivers transmit function
add esp, 28 ; free memory, allocated before for ARP_PACKET
; Add an entry in the ARP table, awaiting response
sub esp, ARP_ENTRY_SIZE ;allocate memory for ARP-entry
mov esi, dword[TargetIP]
mov dword[esp + ARP_ENTRY.IP],esi
lea edi, [esp + ARP_ENTRY.MAC]
xor eax, eax
stosd
stosw
mov word[esp + ARP_ENTRY.Status], ARP_AWAITING_RESPONSE
mov word[esp + ARP_ENTRY.TTL], 0x000A ; 10 seconds
stdcall arp_table_manager,ARP_TABLE_ADD,EXTRA_IS_ARP_ENTRY_PTR,esp
add esp, ARP_ENTRY_SIZE ; free memory
.exit:
ret
endp

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,739 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; I8255X.INC ;;
;; ;;
;; Ethernet driver for Menuet OS ;;
;; ;;
;; Version 0.3 11 August 2003 ;;
;; ;;
;; This driver is based on the eepro100 driver from ;;
;; the etherboot 5.0.6 project. The copyright statement is ;;
;; ;;
;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;;
;; ;;
;; remaining parts Copyright 2002 Mike Hibbett, ;;
;; mikeh@oceanfree.net ;;
;; ;;
;; See file COPYING for details ;;
;; ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;********************************************************************
; Interface
; I8255x_reset
; I8255x_probe
; I8255x_poll
; I8255x_transmit
;
; These functions are referenced in ethernet.inc
;
;********************************************************************
rxfd_status equ eth_data_start
rxfd_command equ eth_data_start + 2
rxfd_link equ eth_data_start + 4
rxfd_rx_buf_addr equ eth_data_start + 8
rxfd_count equ eth_data_start + 12
rxfd_size equ eth_data_start + 14
rxfd_packet equ eth_data_start + 16
uglobal
eeprom_data: times 16 dd 0
align 4
lstats:
tx_good_frames: dd 0
tx_coll16_errs: dd 0
tx_late_colls: dd 0
tx_underruns: dd 0
tx_lost_carrier: dd 0
tx_deferred: dd 0
tx_one_colls: dd 0
tx_multi_colls: dd 0
tx_total_colls: dd 0
rx_good_frames: dd 0
rx_crc_errs: dd 0
rx_align_errs: dd 0
rx_resource_errs: dd 0
rx_overrun_errs: dd 0
rx_colls_errs: dd 0
rx_runt_errs: dd 0
done_marker: dd 0
align 4
confcmd:
confcmd_status: dw 0
confcmd_command: dw 0
confcmd_link: dd 0
endg
iglobal
confcmd_data: db 22, 0x08, 0, 0, 0, 0x80, 0x32, 0x03, 1
db 0, 0x2e, 0, 0x60, 0, 0xf2, 0x48, 0, 0x40, 0xf2
db 0x80, 0x3f, 0x05
endg
uglobal
align 4
txfd:
txfd_status: dw 0
txfd_command: dw 0
txfd_link: dd 0
txfd_tx_desc_addr: dd 0
txfd_count: dd 0
txfd_tx_buf_addr0: dd 0
txfd_tx_buf_size0: dd 0
txfd_tx_buf_addr1: dd 0
txfd_tx_buf_size1: dd 0
align 4
hdr:
hdr_dst_addr: times 6 db 0
hdr_src_addr: times 6 db 0
hdr_type: dw 0
endg
;***************************************************************************
; Function
; wait_for_cmd_done
;
; Description
; waits for the hardware to complete a command
; port address in edx
;
; al destroyed
;***************************************************************************
wait_for_cmd_done:
in al, dx
cmp al, 0
jne wait_for_cmd_done
ret
;***************************************************************************
; Function
; mdio_read
;
; Description
; This probably reads a register in the "physical media interface chip"
; Phy_id in ebx
; location in ecx
;
; Data returned in eax
;
;***************************************************************************
mdio_read:
mov edx, [io_addr]
add edx, 16 ; SCBCtrlMDI
mov eax, 0x08000000
shl ecx, 16
or eax, ecx
shl ebx, 21
or eax, ebx
out dx, eax
mrlp:
call delay_us
in eax, dx
mov ecx, eax
and ecx, 0x10000000
jz mrlp
and eax, 0xffff
ret
;***************************************************************************
; Function
; mdio_write
;
; Description
; This probably writes a register in the "physical media interface chip"
; Phy_id in ebx
; location in ecx
; data in edx
; Data returned in eax
;
;***************************************************************************
mdio_write:
mov eax, 0x04000000
shl ecx, 16
or eax, ecx
shl ebx, 21
or eax, ebx
or eax, edx
mov edx, [io_addr]
add edx, 16 ; SCBCtrlMDI
out dx, eax
mwlp:
call delay_us
in eax, dx
mov ecx, eax
and ecx, 0x10000000
jz mwlp
and eax, 0xffff
ret
;/***********************************************************************/
;/* I82557 related defines */
;/***********************************************************************/
; Serial EEPROM section.
; A "bit" grungy, but we work our way through bit-by-bit :->.
; EEPROM_Ctrl bits.
EE_SHIFT_CLK equ 0x01 ; EEPROM shift clock.
EE_CS equ 0x02 ; EEPROM chip select.
EE_DATA_WRITE equ 0x04 ; EEPROM chip data in.
EE_DATA_READ equ 0x08 ; EEPROM chip data out.
EE_WRITE_0 equ 0x4802
EE_WRITE_1 equ 0x4806
EE_ENB equ 0x4802
; The EEPROM commands include the alway-set leading bit.
EE_READ_CMD equ 6
; The SCB accepts the following controls for the Tx and Rx units:
CU_START equ 0x0010
CU_RESUME equ 0x0020
CU_STATSADDR equ 0x0040
CU_SHOWSTATS equ 0x0050 ; Dump statistics counters.
CU_CMD_BASE equ 0x0060 ; Base address to add to add CU commands.
CU_DUMPSTATS equ 0x0070 ; Dump then reset stats counters.
RX_START equ 0x0001
RX_RESUME equ 0x0002
RX_ABORT equ 0x0004
RX_ADDR_LOAD equ 0x0006
RX_RESUMENR equ 0x0007
INT_MASK equ 0x0100
DRVR_INT equ 0x0200 ; Driver generated interrupt.
;***************************************************************************
; Function
; do_eeprom_cmd
;
; Description
; writes a cmd to the ethernet cards eeprom, by bit bashing
; cmd in ebx
; cmd length in ecx
; return in eax
;***************************************************************************
do_eeprom_cmd:
mov edx, [io_addr] ; We only require the value in dx
add dx, 14 ; the value SCBeeprom
mov ax, EE_ENB
out dx, ax
call delay_us
mov ax, 0x4803 ; EE_ENB | EE_SHIFT_CLK
out dx, ax
call delay_us
; dx holds ee_addr
; ecx holds count
; eax holds cmd
xor edi, edi ; this will be the receive data
dec_001:
mov esi, 1
dec ecx
shl esi, cl
inc ecx
and esi, ebx
mov eax, EE_WRITE_0 ; I am assuming this doesnt affect the flags..
cmp esi,0
jz dec_002
mov eax, EE_WRITE_1
dec_002:
out dx, ax
call delay_us
or ax, EE_SHIFT_CLK
out dx, ax
call delay_us
shl edi,1
in ax, dx
and ax, EE_DATA_READ
cmp ax,0
jz dec_003
inc edi
dec_003:
loop dec_001
mov ax, EE_ENB
out dx, ax
call delay_us
mov ax, 0x4800
out dx, ax
call delay_us
mov eax, edi
ret
;***************************************************************************
; Function
; I8255x_reset
; Description
; Place the chip (ie, the ethernet card) into a virgin state
; No inputs
; All registers destroyed
;
;***************************************************************************
I8255x_reset:
ret
;***************************************************************************
; Function
; I8255x_probe
; Description
; Searches for an ethernet card, enables it and clears the rx buffer
; If a card was found, it enables the ethernet -> TCPIP link
;
;***************************************************************************
I8255x_probe:
mov eax, [io_addr]
mov ebx, [pci_bus]
mov ecx, [pci_dev]
mov edx, 0x04 ; PCI_COMMAND
call pcibios_read_config_word
or ax, 0x05
mov ebx, [pci_bus]
mov ecx, [pci_dev]
mov edx, 0x04 ; PCI_COMMAND
call pcibios_write_config_word
mov ebx, 0x6000000
mov ecx, 27
call do_eeprom_cmd
and eax, 0xffe0000
cmp eax, 0xffe0000
je bige
mov ebx, 0x1800000
mov ecx, 0x40
jmp doread
bige:
mov ebx, 0x6000000
mov ecx, 0x100
doread:
; do-eeprom-cmd will destroy all registers
; we have eesize in ecx
; read_cmd in ebx
; Ignore full eeprom - just load the mac address
mov ecx, 0
drlp:
push ecx ; save count
push ebx
mov eax, ecx
shl eax, 16
or ebx, eax
mov ecx, 27
call do_eeprom_cmd
pop ebx
pop ecx
mov edx, ecx
shl edx, 2
mov esi, eeprom_data
add esi, edx
mov [esi], eax
inc ecx
cmp ecx, 16
jne drlp
; OK, we have the MAC address.
; Now reset the card
mov edx, [io_addr]
add dx, 8 ; SCBPort
xor eax, eax ; The reset cmd == 0
out dx, eax
mov esi, 10
call delay_ms ; Give the card time to warm up.
mov eax, lstats
mov edx, [io_addr]
add edx, 4 ; SCBPointer
out dx, eax
mov eax, 0x0140 ; INT_MASK | CU_STATSADDR
mov edx, [io_addr]
add edx, 2 ; SCBCmd
out dx, ax
call wait_for_cmd_done
mov eax, 0
mov edx, [io_addr]
add edx, 4 ; SCBPointer
out dx, eax
mov eax, 0x0106 ; INT_MASK | RX_ADDR_LOAD
mov edx, [io_addr]
add edx, 2 ; SCBCmd
out dx, ax
call wait_for_cmd_done
; build rxrd structure
mov ax, 0x0001
mov [rxfd_status], ax
mov ax, 0x0000
mov [rxfd_command], ax
mov eax, rxfd_status
mov [rxfd_link], eax
mov eax, Ether_buffer
mov [rxfd_rx_buf_addr], eax
mov ax, 0
mov [rxfd_count], ax
mov ax, 1528
mov [rxfd_size], ax
mov edx, [io_addr]
add edx, 4 ; SCBPointer
mov eax, rxfd_status
out dx, eax
mov edx, [io_addr]
add edx, 2 ; SCBCmd
mov ax, 0x0101 ; INT_MASK | RX_START
out dx, ax
call wait_for_cmd_done
; start the reciver
mov ax, 0
mov [rxfd_status], ax
mov ax, 0xc000
mov [rxfd_command], ax
mov edx, [io_addr]
add edx, 4 ; SCBPointer
mov eax, rxfd_status
out dx, eax
mov edx, [io_addr]
add edx, 2 ; SCBCmd
mov ax, 0x0101 ; INT_MASK | RX_START
out dx, ax
; Init TX Stuff
mov edx, [io_addr]
add edx, 4 ; SCBPointer
mov eax, 0
out dx, eax
mov edx, [io_addr]
add edx, 2 ; SCBCmd
mov ax, 0x0160 ; INT_MASK | CU_CMD_BASE
out dx, ax
call wait_for_cmd_done
; Set TX Base address
; First, set up confcmd values
mov ax, 2
mov [confcmd_command], ax
mov eax, txfd
mov [confcmd_link], eax
mov ax, 1
mov [txfd_command], ax ; CmdIASetup
mov ax, 0
mov [txfd_status], ax
mov eax, confcmd
mov [txfd_link], eax
; ETH_ALEN is 6 bytes
mov esi, eeprom_data
mov edi, node_addr
mov ecx, 3
drp000:
mov eax, [esi]
mov [edi], al
shr eax, 8
inc edi
mov [edi], al
inc edi
add esi, 4
loop drp000
; Hard code your MAC address into node_addr at this point,
; If you cannot read the MAC address from the eeprom in the previous step.
; You also have to write the mac address into txfd_tx_desc_addr, rather
; than taking data from eeprom_data
mov esi, eeprom_data
mov edi, txfd_tx_desc_addr
mov ecx, 3
drp001:
mov eax, [esi]
mov [edi], al
shr eax, 8
inc edi
mov [edi], al
inc edi
add esi, 4
loop drp001
mov esi, eeprom_data + (6 * 4)
mov eax, [esi]
shr eax, 8
and eax, 0x3f
cmp eax, 4 ; DP83840
je drp002
cmp eax, 10 ; DP83840A
je drp002
jmp drp003
drp002:
mov ebx, [esi]
and ebx, 0x1f
push ebx
mov ecx, 23
call mdio_read
pop ebx
or eax, 0x0422
mov ecx, 23
mov edx, eax
call mdio_write
drp003:
mov ax, 0x4002 ; Cmdsuspend | CmdConfigure
mov [confcmd_command], ax
mov ax, 0
mov [confcmd_status], ax
mov eax, txfd
mov [confcmd_link], eax
mov ebx, confcmd_data
mov al, 0x88 ; fifo of 8 each
mov [ebx + 1], al
mov al, 0
mov [ebx + 4], al
mov al, 0x80
mov [ebx + 5], al
mov al, 0x48
mov [ebx + 15], al
mov al, 0x80
mov [ebx + 19], al
mov al, 0x05
mov [ebx + 21], al
mov eax, txfd
mov edx, [io_addr]
add edx, 4 ; SCBPointer
out dx, eax
mov eax, 0x0110 ; INT_MASK | CU_START
mov edx, [io_addr]
add edx, 2 ; SCBCmd
out dx, ax
call wait_for_cmd_done
jmp skip
; wait for thing to start
drp004:
mov ax, [txfd_status]
cmp ax, 0
je drp004
skip:
; Indicate that we have successfully reset the card
mov eax, [pci_data]
mov [eth_status], eax
I8255x_exit:
ret
;***************************************************************************
; Function
; I8255x_poll
;
; Description
; Polls the ethernet card for a received packet
; Received data, if any, ends up in Ether_buffer
;
;***************************************************************************
I8255x_poll:
mov ax, 0 ; assume no data
mov [eth_rx_data_len], ax
mov ax, [rxfd_status]
cmp ax, 0
je i8p_exit
mov ax, 0
mov [rxfd_status], ax
mov ax, 0xc000
mov [rxfd_command], ax
mov edx, [io_addr]
add edx, 4 ; SCBPointer
mov eax, rxfd_status
out dx, eax
mov edx, [io_addr]
add edx, 2 ; SCBCmd
mov ax, 0x0101 ; INT_MASK | RX_START
out dx, ax
call wait_for_cmd_done
mov esi, rxfd_packet
mov edi, Ether_buffer
mov ecx, 1518
cld
rep movsb
mov ax, [rxfd_count]
and ax, 0x3fff
mov [eth_rx_data_len], ax
i8p_exit:
ret
;***************************************************************************
; Function
; I8255x_transmit
;
; Description
; Transmits a packet of data via the ethernet card
; Pointer to 48 bit destination address in edi
; Type of packet in bx
; size of packet in ecx
; pointer to packet data in esi
;
;***************************************************************************
I8255x_transmit:
mov [hdr_type], bx
mov eax, [edi]
mov [hdr_dst_addr], eax
mov ax, [edi+4]
mov [hdr_dst_addr+4], ax
mov eax, [node_addr]
mov [hdr_src_addr], eax
mov ax, [node_addr+4]
mov [hdr_src_addr+4], ax
mov edx, [io_addr]
in ax, dx
and ax, 0xfc00
out dx, ax
xor ax, ax
mov [txfd_status], ax
mov ax, 0x400C ; Cmdsuspend | CmdTx | CmdTxFlex
mov [txfd_command], ax
mov eax, txfd
mov [txfd_link], eax
mov eax, 0x02208000
mov [txfd_count], eax
mov eax, txfd_tx_buf_addr0
mov [txfd_tx_desc_addr], eax
mov eax, hdr
mov [txfd_tx_buf_addr0], eax
mov eax, 14 ; sizeof hdr
mov [txfd_tx_buf_size0], eax
; Copy the buffer address and size in
mov eax, esi
mov [txfd_tx_buf_addr1], eax
mov eax, ecx
mov [txfd_tx_buf_size1], eax
mov eax, txfd
mov edx, [io_addr]
add edx, 4 ; SCBPointer
out dx, eax
mov ax, 0x0110 ; INT_MASK | CU_START
mov edx, [io_addr]
add edx, 2 ; SCBCmd
out dx, ax
call wait_for_cmd_done
mov edx, [io_addr]
in ax, dx
I8t_001:
mov ax, [txfd_status]
cmp ax, 0
je I8t_001
mov edx, [io_addr]
in ax, dx
ret

View File

@ -0,0 +1,814 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; PCNET32.INC ;;
;; ;;
;; Ethernet driver for Menuet OS ;;
;; ;;
;; Version 1.0 31 July 2004 ;;
;; ;;
;; This driver is based on the PCNet32 driver from ;;
;; the etherboot 5.0.6 project. The copyright statement is ;;
;; ;;
;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;;
;; ;;
;; remaining parts Copyright 2004 Jarek Pelczar, ;;
;; jpelczar@interia.pl ;;
;; ;;
;; See file COPYING for details ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;macro PutStr X
;{
; local .__xyz1
; local .__xyz2
; push esi
; mov esi,.__xyz1
; call sys_msg_board_str
; push eax
; mov eax,1
; call delay_hs
; pop eax
; jmp .__xyz2
;.__xyz1:
; db X
; db 13,10,0
;.__xyz2:
; pop esi
;}
PCNET32_PORT_AUI equ 0x00
PCNET32_PORT_10BT equ 0x01
PCNET32_PORT_GPSI equ 0x02
PCNET32_PORT_MII equ 0x03
PCNET32_PORT_PORTSEL equ 0x03
PCNET32_PORT_ASEL equ 0x04
PCNET32_PORT_100 equ 0x40
PCNET32_PORT_FD equ 0x80
PCNET32_DMA_MASK equ 0xffffffff
PCNET32_LOG_TX_BUFFERS equ 1
PCNET32_LOG_RX_BUFFERS equ 2
PCNET32_TX_RING_SIZE equ (1 shl PCNET32_LOG_TX_BUFFERS)
PCNET32_TX_RING_MOD_MASK equ (PCNET32_TX_RING_SIZE-1)
PCNET32_TX_RING_LEN_BITS equ 0
PCNET32_RX_RING_SIZE equ (1 shl PCNET32_LOG_RX_BUFFERS)
PCNET32_RX_RING_MOD_MASK equ (PCNET32_RX_RING_SIZE-1)
PCNET32_RX_RING_LEN_BITS equ (PCNET32_LOG_RX_BUFFERS shl 4)
PCNET32_PKT_BUF_SZ equ 1544
PCNET32_PKT_BUF_SZ_NEG equ 0xf9f8
pcnet32_txb equ (eth_data_start)
pcnet32_rxb equ ((pcnet32_txb+(PCNET32_PKT_BUF_SZ*PCNET32_TX_RING_SIZE)+0xf) and 0xfffffff0)
pcnet32_tx_ring equ ((pcnet32_rxb+(PCNET32_PKT_BUF_SZ*PCNET32_RX_RING_SIZE)+0xf) and 0xfffffff0)
pcnet32_rx_ring equ ((pcnet32_tx_ring+(16*PCNET32_TX_RING_SIZE)+0xf) and 0xfffffff0)
virtual at ((pcnet32_rx_ring+(16*PCNET32_RX_RING_SIZE)+0xf) and 0xfffffff0)
pcnet32_private:
.mode dw ?
.tlen_rlen dw ?
.phys_addr db ?,?,?,?,?,?
.reserved dw ?
.filter dd ?,?
.rx_ring dd ?
.tx_ring dd ?
.cur_rx dd ?
.cur_tx dd ?
.dirty_rx dd ?
.dirty_tx dd ?
.tx_full db ?
.options dd ?
.full_duplex db ?
.chip_version dd ?
.mii db ?
.ltint db ?
.dxsuflo db ?
.fset db ?
.fdx db ?
end virtual
virtual at 0
pcnet32_rx_head:
.base dd ?
.buf_length dw ?
.status dw ?
.msg_length dd ?
.reserved dd ?
end virtual
virtual at 0
pcnet32_tx_head:
.base dd ?
.length dw ?
.status dw ?
.misc dd ?
.reserved dd ?
end virtual
uglobal
pcnet32_access:
.read_csr dd ?
.write_csr dd ?
.read_bcr dd ?
.write_bcr dd ?
.read_rap dd ?
.write_rap dd ?
.reset dd ?
endg
iglobal
pcnet32_options_mapping:
dd PCNET32_PORT_ASEL ; 0 Auto-select
dd PCNET32_PORT_AUI ; 1 BNC/AUI
dd PCNET32_PORT_AUI ; 2 AUI/BNC
dd PCNET32_PORT_ASEL ; 3 not supported
dd PCNET32_PORT_10BT or PCNET32_PORT_FD ; 4 10baseT-FD
dd PCNET32_PORT_ASEL ; 5 not supported
dd PCNET32_PORT_ASEL ; 6 not supported
dd PCNET32_PORT_ASEL ; 7 not supported
dd PCNET32_PORT_ASEL ; 8 not supported
dd PCNET32_PORT_MII ; 9 MII 10baseT
dd PCNET32_PORT_MII or PCNET32_PORT_FD ; 10 MII 10baseT-FD
dd PCNET32_PORT_MII ; 11 MII (autosel)
dd PCNET32_PORT_10BT ; 12 10BaseT
dd PCNET32_PORT_MII or PCNET32_PORT_100 ; 13 MII 100BaseTx
dd PCNET32_PORT_MII or PCNET32_PORT_100 or PCNET32_PORT_FD ; 14 MII 100BaseTx-FD
dd PCNET32_PORT_ASEL ; 15 not supported
endg
PCNET32_WIO_RDP equ 0x10
PCNET32_WIO_RAP equ 0x12
PCNET32_WIO_RESET equ 0x14
PCNET32_WIO_BDP equ 0x16
PCNET32_DWIO_RDP equ 0x10
PCNET32_DWIO_RAP equ 0x14
PCNET32_DWIO_RESET equ 0x18
PCNET32_DWIO_BDP equ 0x1C
PCNET32_TOTAL_SIZE equ 0x20
; ebx - index
; return:
; eax - data
pcnet32_wio_read_csr:
push edx
lea edx,[ebp+PCNET32_WIO_RAP]
mov ax,bx
out dx,ax
lea edx,[ebp+PCNET32_WIO_RDP]
in ax,dx
and eax,0xffff
pop edx
ret
; eax - data
; ebx - index
pcnet32_wio_write_csr:
push edx
lea edx,[ebp+PCNET32_WIO_RAP]
xchg eax,ebx
out dx,ax
xchg eax,ebx
lea edx,[ebp+PCNET32_WIO_RDP]
out dx,ax
pop edx
ret
; ebx - index
; return:
; eax - data
pcnet32_wio_read_bcr:
push edx
lea edx,[ebp+PCNET32_WIO_RAP]
mov ax,bx
out dx,ax
lea edx,[ebp+PCNET32_WIO_BDP]
in ax,dx
and eax,0xffff
pop edx
ret
; eax - data
; ebx - index
pcnet32_wio_write_bcr:
push edx
lea edx,[ebp+PCNET32_WIO_RAP]
xchg eax,ebx
out dx,ax
xchg eax,ebx
lea edx,[ebp+PCNET32_WIO_BDP]
out dx,ax
pop edx
ret
pcnet32_wio_read_rap:
push edx
lea edx,[ebp+PCNET32_WIO_RAP]
in ax,dx
and eax,0xffff
pop edx
ret
; eax - val
pcnet32_wio_write_rap:
push edx
lea edx,[ebp+PCNET32_WIO_RAP]
out dx,ax
pop edx
ret
pcnet32_wio_reset:
push edx
push eax
lea edx,[ebp+PCNET32_WIO_RESET]
in ax,dx
pop eax
pop edx
ret
pcnet32_wio_check:
push edx
mov ax,88
lea edx,[ebp+PCNET32_WIO_RAP]
out dx,ax
nop
nop
in ax,dx
cmp ax,88
sete al
pop edx
ret
iglobal
pcnet32_wio:
dd pcnet32_wio_read_csr
dd pcnet32_wio_write_csr
dd pcnet32_wio_read_bcr
dd pcnet32_wio_write_bcr
dd pcnet32_wio_read_rap
dd pcnet32_wio_write_rap
dd pcnet32_wio_reset
endg
; ebx - index
; return:
; eax - data
pcnet32_dwio_read_csr:
push edx
lea edx,[ebp+PCNET32_DWIO_RAP]
mov ebx,eax
out dx,eax
lea edx,[ebp+PCNET32_DWIO_RDP]
in eax,dx
and eax,0xffff
pop edx
ret
; ebx - index
; eax - data
pcnet32_dwio_write_csr:
push edx
lea edx,[ebp+PCNET32_DWIO_RAP]
xchg eax,ebx
out dx,eax
lea edx,[ebp+PCNET32_DWIO_RDP]
xchg eax,ebx
out dx,eax
pop edx
ret
; ebx - index
; return:
; eax - data
pcnet32_dwio_read_bcr:
push edx
lea edx,[ebp+PCNET32_DWIO_RAP]
mov ebx,eax
out dx,eax
lea edx,[ebp+PCNET32_DWIO_BDP]
in eax,dx
and eax,0xffff
pop edx
ret
; ebx - index
; eax - data
pcnet32_dwio_write_bcr:
push edx
lea edx,[ebp+PCNET32_DWIO_RAP]
xchg eax,ebx
out dx,eax
lea edx,[ebp+PCNET32_DWIO_BDP]
xchg eax,ebx
out dx,eax
pop edx
ret
pcnet32_dwio_read_rap:
push edx
lea edx,[ebp+PCNET32_DWIO_RAP]
in eax,dx
and eax,0xffff
pop edx
ret
; eax - val
pcnet32_dwio_write_rap:
push edx
lea edx,[ebp+PCNET32_DWIO_RAP]
out dx,eax
pop edx
ret
pcnet32_dwio_reset:
push edx
push eax
lea edx,[ebp+PCNET32_DWIO_RESET]
in eax,dx
pop eax
pop edx
ret
pcnet32_dwio_check:
push edx
lea edx,[PCNET32_DWIO_RAP]
mov eax,88
out dx,eax
nop
nop
in eax,dx
and eax,0xffff
cmp eax,88
sete al
pop edx
ret
iglobal
pcnet32_dwio:
dd pcnet32_dwio_read_csr
dd pcnet32_dwio_write_csr
dd pcnet32_dwio_read_bcr
dd pcnet32_dwio_write_bcr
dd pcnet32_dwio_read_rap
dd pcnet32_dwio_write_rap
dd pcnet32_dwio_reset
endg
pcnet32_init_ring:
mov [pcnet32_private.tx_full],0
mov [pcnet32_private.cur_rx],0
mov [pcnet32_private.cur_tx],0
mov [pcnet32_private.dirty_rx],0
mov [pcnet32_private.dirty_tx],0
mov edi,pcnet32_rx_ring
mov ecx,PCNET32_RX_RING_SIZE
mov ebx,pcnet32_rxb
.rx_init:
mov [edi+pcnet32_rx_head.base],ebx
mov [edi+pcnet32_rx_head.buf_length],word PCNET32_PKT_BUF_SZ_NEG
mov [edi+pcnet32_rx_head.status],word 0x8000
add ebx,PCNET32_PKT_BUF_SZ
; inc ebx
add edi,16
loop .rx_init
mov edi,pcnet32_tx_ring
mov ecx,PCNET32_TX_RING_SIZE
.tx_init:
mov [edi+pcnet32_tx_head.base],dword 0
mov [edi+pcnet32_tx_head.status],word 0
add edi,16
loop .tx_init
mov [pcnet32_private.tlen_rlen],(PCNET32_TX_RING_LEN_BITS or PCNET32_RX_RING_LEN_BITS)
mov esi,node_addr
mov edi,pcnet32_private.phys_addr
cld
movsd
movsw
mov dword [pcnet32_private.rx_ring],pcnet32_rx_ring
mov dword [pcnet32_private.tx_ring],pcnet32_tx_ring
ret
pcnet32_reset:
; Reset PCNET32
mov ebp,[io_addr]
call dword [pcnet32_access.reset]
; set 32bit mode
mov ebx,20
mov eax,2
call dword [pcnet32_access.write_bcr]
; set/reset autoselect bit
mov ebx,2
call dword [pcnet32_access.read_bcr]
and eax,not 2
test [pcnet32_private.options],PCNET32_PORT_ASEL
jz .L1
or eax,2
.L1:
call dword [pcnet32_access.write_bcr]
; Handle full duplex setting
cmp byte [pcnet32_private.full_duplex],0
je .L2
mov ebx,9
call dword [pcnet32_access.read_bcr]
and eax,not 3
test [pcnet32_private.options],PCNET32_PORT_FD
jz .L3
or eax,1
cmp [pcnet32_private.options],PCNET32_PORT_FD or PCNET32_PORT_AUI
jne .L4
or eax,2
jmp .L4
.L3:
test [pcnet32_private.options],PCNET32_PORT_ASEL
jz .L4
cmp [pcnet32_private.chip_version],0x2627
jne .L4
or eax,3
.L4:
mov ebx,9
call dword [pcnet32_access.write_bcr]
.L2:
; set/reset GPSI bit
mov ebx,124
call dword [pcnet32_access.read_csr]
mov ecx,[pcnet32_private.options]
and ecx,PCNET32_PORT_PORTSEL
cmp ecx,PCNET32_PORT_GPSI
jne .L5
or eax,0x10
.L5:
call dword [pcnet32_access.write_csr]
cmp [pcnet32_private.mii],0
je .L6
test [pcnet32_private.options],PCNET32_PORT_ASEL
jnz .L6
mov ebx,32
call dword [pcnet32_access.read_bcr]
and eax,not 0x38
test [pcnet32_private.options],PCNET32_PORT_FD
jz .L7
or eax,0x10
.L7:
test [pcnet32_private.options],PCNET32_PORT_100
jz .L8
or eax,0x08
.L8:
call dword [pcnet32_access.write_bcr]
jmp .L9
.L6:
test [pcnet32_private.options],PCNET32_PORT_ASEL
jz .L9
mov ebx,32
; PutStr "ASEL, enable auto-negotiation"
call dword [pcnet32_access.read_bcr]
and eax,not 0x98
or eax,0x20
call dword [pcnet32_access.write_bcr]
.L9:
cmp [pcnet32_private.ltint],0
je .L10
mov ebx,5
call dword [pcnet32_access.read_csr]
or eax,(1 shl 14)
call dword [pcnet32_access.write_csr]
.L10:
mov eax,[pcnet32_private.options]
and eax,PCNET32_PORT_PORTSEL
shl eax,7
mov [pcnet32_private.mode],ax
mov [pcnet32_private.filter],dword 0xffffffff
mov [pcnet32_private.filter+4],dword 0xffffffff
call pcnet32_init_ring
mov ebx,1
mov eax,pcnet32_private
and eax,0xffff
call dword [pcnet32_access.write_csr]
mov eax,pcnet32_private
mov ebx,2
shr eax,16
call dword [pcnet32_access.write_csr]
mov ebx,4
mov eax,0x0915
call dword [pcnet32_access.write_csr]
mov ebx,0
mov eax,1
call dword [pcnet32_access.write_csr]
mov ecx,100
.L11:
xor ebx,ebx
call dword [pcnet32_access.read_csr]
test ax,0x100
jnz .L12
loop .L11
.L12:
; PutStr "hardware reset"
xor ebx,ebx
mov eax,0x0002
call dword [pcnet32_access.write_csr]
xor ebx,ebx
call dword [pcnet32_access.read_csr]
; PutStr "PCNET reset complete"
ret
pcnet32_adjust_pci_device:
;*******Get current setting************************
mov al, 2 ;read a word
mov bh, [pci_dev]
mov ah, [pci_bus]
mov bl, 0x04 ;from command Register
call pci_read_reg
;******see if its already set as bus master********
mov bx, ax
and bx,5
cmp bx,5
je pcnet32_adjust_pci_device_Latency
;******Make card a bus master*******
mov cx, ax ;value to write
mov bh, [pci_dev]
mov al, 2 ;write a word
or cx,5
mov ah, [pci_bus]
mov bl, 0x04 ;to command register
call pci_write_reg
;******Check latency setting***********
pcnet32_adjust_pci_device_Latency:
;*******Get current latency setting************************
; mov al, 1 ;read a byte
; mov bh, [pci_dev]
; mov ah, [pci_bus]
; mov bl, 0x0D ;from Lantency Timer Register
; call pci_read_reg
;******see if its aat least 64 clocks********
; cmp ax,64
; jge pcnet32_adjust_pci_device_Done
;******Set latency to 32 clocks*******
; mov cx, 64 ;value to write
; mov bh, [pci_dev]
; mov al, 1 ;write a byte
; mov ah, [pci_bus]
; mov bl, 0x0D ;to Lantency Timer Register
; call pci_write_reg
;******Check latency setting***********
pcnet32_adjust_pci_device_Done:
ret
pcnet32_probe:
mov ebp,[io_addr]
call pcnet32_wio_reset
xor ebx,ebx
call pcnet32_wio_read_csr
cmp eax,4
jne .try_dwio
call pcnet32_wio_check
and al,al
jz .try_dwio
; PutStr "Using WIO"
mov esi,pcnet32_wio
jmp .L1
.try_dwio:
call pcnet32_dwio_reset
xor ebx,ebx
call pcnet32_dwio_read_csr
cmp eax,4
jne .no_dev
call pcnet32_dwio_check
and al,al
jz .no_dev
; PutStr "Using DWIO"
mov esi,pcnet32_dwio
jmp .L1
.no_dev:
; PutStr "PCNET32 not found"
ret
.L1:
mov edi,pcnet32_access
mov ecx,7
cld
rep movsd
mov ebx,88
call dword [pcnet32_access.read_csr]
mov ecx,eax
mov ebx,89
call dword [pcnet32_access.read_csr]
shl eax,16
or eax,ecx
mov ecx,eax
and ecx,0xfff
cmp ecx,3
jne .no_dev
shr eax,12
and eax,0xffff
mov [pcnet32_private.chip_version],eax
; PutStr "PCNET32 chip version OK"
mov [pcnet32_private.fdx],0
mov [pcnet32_private.mii],0
mov [pcnet32_private.fset],0
mov [pcnet32_private.dxsuflo],0
mov [pcnet32_private.ltint],0
mov eax,[pcnet32_private.chip_version]
cmp eax,0x2420
je .L2
cmp eax,0x2430
je .L3
cmp eax,0x2621
je .L4
cmp eax,0x2623
je .L5
cmp eax,0x2624
je .L6
cmp eax,0x2625
je .L7
cmp eax,0x2626
je .L8
cmp eax,0x2627
je .L9
; PutStr "Invalid chip rev"
jmp .no_dev
.L2:
; PutStr "PCnet/PCI 79C970"
jmp .L10
.L3:
; PutStr "PCnet/PCI 79C970"
jmp .L10
.L4:
; PutStr "PCnet/PCI II 79C970A"
mov [pcnet32_private.fdx],1
jmp .L10
.L5:
; PutStr "PCnet/FAST 79C971"
mov [pcnet32_private.fdx],1
mov [pcnet32_private.mii],1
mov [pcnet32_private.fset],1
mov [pcnet32_private.ltint],1
jmp .L10
.L6:
; PutStr "PCnet/FAST+ 79C972"
mov [pcnet32_private.fdx],1
mov [pcnet32_private.mii],1
mov [pcnet32_private.fset],1
jmp .L10
.L7:
; PutStr "PCnet/FAST III 79C973"
mov [pcnet32_private.fdx],1
mov [pcnet32_private.mii],1
jmp .L10
.L8:
; PutStr "PCnet/Home 79C978"
mov [pcnet32_private.fdx],1
mov ebx,49
call dword [pcnet32_access.read_bcr]
call dword [pcnet32_access.write_bcr]
jmp .L10
.L9:
; PutStr "PCnet/FAST III 79C975"
mov [pcnet32_private.fdx],1
mov [pcnet32_private.mii],1
.L10:
cmp [pcnet32_private.fset],1
jne .L11
mov ebx,18
call dword [pcnet32_access.read_bcr]
or eax,0x800
call dword [pcnet32_access.write_bcr]
mov ebx,80
call dword [pcnet32_access.read_csr]
and eax,0xc00
or eax,0xc00
call dword [pcnet32_access.write_csr]
mov [pcnet32_private.dxsuflo],1
mov [pcnet32_private.ltint],1
.L11:
; read MAC
mov edi,node_addr
mov edx,ebp
mov ecx,6
.Lmac:
in al,dx
stosb
inc edx
loop .Lmac
; PutStr "MAC read"
call pcnet32_adjust_pci_device
; PutStr "PCI done"
mov eax,PCNET32_PORT_ASEL
mov [pcnet32_private.options],eax
mov [pcnet32_private.mode],word 0x0003
mov [pcnet32_private.tlen_rlen],word (PCNET32_TX_RING_LEN_BITS or PCNET32_RX_RING_LEN_BITS)
mov esi,node_addr
mov edi,pcnet32_private.phys_addr
cld
movsd
movsw
mov [pcnet32_private.filter],dword 0
mov [pcnet32_private.filter+4],dword 0
mov dword [pcnet32_private.rx_ring],pcnet32_rx_ring
mov dword [pcnet32_private.tx_ring],pcnet32_tx_ring
; PutStr "Switching to 32"
mov ebx,20
mov eax,2
call dword [pcnet32_access.write_bcr]
mov ebx,1
mov eax,(pcnet32_private and 0xffff)
call dword [pcnet32_access.write_csr]
mov ebx,2
mov eax,(pcnet32_private shr 16) and 0xffff
call dword [pcnet32_access.write_csr]
mov ebx,0
mov eax,1
call dword [pcnet32_access.write_csr]
mov esi,1
call delay_ms
call pcnet32_reset
mov eax, [pci_data]
mov [eth_status], eax
ret
pcnet32_poll:
xor eax,eax
mov [eth_rx_data_len],ax
mov eax,[pcnet32_private.cur_rx]
and eax,PCNET32_RX_RING_MOD_MASK
mov ebx,eax
imul esi,eax,PCNET32_PKT_BUF_SZ
add esi,pcnet32_rxb
shl ebx,4
add ebx,pcnet32_rx_ring
mov cx,[ebx+pcnet32_rx_head.status]
test cx,0x8000
jnz .L1
cmp ch,3
jne .L1
; PutStr "PCNETRX"
mov ecx,[ebx+pcnet32_rx_head.msg_length]
and ecx,0xfff
sub ecx,4
mov [eth_rx_data_len],cx
push ecx
shr ecx,2
mov edi,Ether_buffer
cld
rep movsd
pop ecx
and ecx,3
rep movsb
mov [ebx+pcnet32_rx_head.buf_length],word PCNET32_PKT_BUF_SZ_NEG
or [ebx+pcnet32_rx_head.status],word 0x8000
inc [pcnet32_private.cur_rx]
.L1:
ret
; Pointer to 48 bit destination address in edi
; Type of packet in bx
; size of packet in ecx
; pointer to packet data in esi
pcnet32_xmit:
push edi
push esi
push ebx
push ecx
; PutStr "PCNETTX"
mov esi,edi
mov edi,[pcnet32_private.cur_tx]
imul edi,PCNET32_PKT_BUF_SZ
add edi,pcnet32_txb ; edi=ptxb
mov eax,edi
cld ; copy MAC
movsd
movsw
mov esi,node_addr
cld
movsd
movsw
mov [edi],bx
add edi,2
mov esi,[esp+8]
mov ecx,[esp]
push ecx
shr ecx,2
cld
rep movsd
pop ecx
and ecx,3
rep movsb
; mov ecx,[esp]
; add ecx,14 ; ETH_HLEN
; xor eax,eax
; pad to min length (60=ETH_ZLEN)
; cmp ecx,60
; jae .L1
; sub ecx,60
; cld
; rep stosb
;.L1:
mov edi,pcnet32_tx_ring+0 ; entry=0
mov ecx,[esp]
add ecx,14
cmp cx,60
jae .L1
mov cx,60
.L1:
neg cx
mov [edi+pcnet32_tx_head.length],cx
mov [edi+pcnet32_tx_head.misc],dword 0
mov [edi+pcnet32_tx_head.base],eax
mov [edi+pcnet32_tx_head.status],word 0x8300
; trigger an immediate send poll
mov ebx,0
mov eax,0x0008 ; 0x0048
mov ebp,[io_addr]
call dword [pcnet32_access.write_csr]
mov dword [pcnet32_private.cur_tx],0
; wait for TX to complete
mov ecx,[timer_ticks];[0xfdf0]
add ecx,100
.L2:
mov ax,[edi+pcnet32_tx_head.status]
test ax,0x8000
jz .L3
cmp ecx,[timer_ticks];[0xfdf0]
jb .L4
mov esi,10
call delay_ms
jnz .L2
.L4:
; PutStr "PCNET: Send timeout"
.L3:
mov dword [edi+pcnet32_tx_head.base],0
pop ecx
pop ebx
pop esi
pop edi
ret

View File

@ -0,0 +1,955 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; RTL8029.INC ;;
;; ;;
;; Ethernet driver for Menuet OS ;;
;; ;;
;; Version 0.2 31 July 2002 ;;
;; ;;
;; This driver is based on the ns8390 driver from ;;
;; the etherboot 5.0.6 project. The copyright statement is ;;
;; ;;
;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;;
;; ;;
;; remaining parts Copyright 2002 Mike Hibbett, ;;
;; mikeh@oceanfree.net ;;
;; ;;
;; See file COPYING for details ;;
;; ;;
;; While this implementation handles only PCI bus RTL8029 ;;
;; hardware, it can be easily adapted to other NE2000 clone ;;
;; products. I just dont have any to try! ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;********************************************************************
; Interface
; rtl8029_reset
; rtl8029_probe
; rtl8029_poll
; rtl8029_transmit
;
;********************************************************************
;**************************************************************************
; 8390 Register Definitions
;**************************************************************************
D8390_P0_COMMAND equ 0x00
D8390_P0_PSTART equ 0x01
D8390_P0_PSTOP equ 0x02
D8390_P0_BOUND equ 0x03
D8390_P0_TSR equ 0x04
D8390_P0_TPSR equ 0x04
D8390_P0_TBCR0 equ 0x05
D8390_P0_TBCR1 equ 0x06
D8390_P0_ISR equ 0x07
D8390_P0_RSAR0 equ 0x08
D8390_P0_RSAR1 equ 0x09
D8390_P0_RBCR0 equ 0x0A
D8390_P0_RBCR1 equ 0x0B
D8390_P0_RSR equ 0x0C
D8390_P0_RCR equ 0x0C
D8390_P0_TCR equ 0x0D
D8390_P0_DCR equ 0x0E
D8390_P0_IMR equ 0x0F
D8390_P1_COMMAND equ 0x00
D8390_P1_PAR0 equ 0x01
D8390_P1_PAR1 equ 0x02
D8390_P1_PAR2 equ 0x03
D8390_P1_PAR3 equ 0x04
D8390_P1_PAR4 equ 0x05
D8390_P1_PAR5 equ 0x06
D8390_P1_CURR equ 0x07
D8390_P1_MAR0 equ 0x08
D8390_COMMAND_PS0 equ 0x0 ; Page 0 select
D8390_COMMAND_PS1 equ 0x40 ; Page 1 select
D8390_COMMAND_PS2 equ 0x80 ; Page 2 select
D8390_COMMAND_RD2 equ 0x20 ; Remote DMA control
D8390_COMMAND_RD1 equ 0x10
D8390_COMMAND_RD0 equ 0x08
D8390_COMMAND_TXP equ 0x04 ; transmit packet
D8390_COMMAND_STA equ 0x02 ; start
D8390_COMMAND_STP equ 0x01 ; stop
D8390_COMMAND_RD2_STA equ 0x22
D8390_COMMAND_RD2_STP equ 0x21
D8390_COMMAND_RD1_STA equ 0x12
D8390_COMMAND_RD0_STA equ 0x0A
D8390_COMMAND_PS0_RD2_STP equ 0x21
D8390_COMMAND_PS1_RD2_STP equ 0x61
D8390_COMMAND_PS0_RD2_STA equ 0x22
D8390_COMMAND_PS0_TXP_RD2_STA equ 0x26
D8390_RCR_MON equ 0x20 ; monitor mode
D8390_DCR_FT1 equ 0x40
D8390_DCR_LS equ 0x08 ; Loopback select
D8390_DCR_WTS equ 0x01 ; Word transfer select
D8390_DCR_FT1_LS equ 0x48
D8390_DCR_WTS_FT1_LS equ 0x49
D8390_ISR_PRX equ 0x01 ; successful recv
D8390_ISR_PTX equ 0x02 ; successful xmit
D8390_ISR_RXE equ 0x04 ; receive error
D8390_ISR_TXE equ 0x08 ; transmit error
D8390_ISR_OVW equ 0x10 ; Overflow
D8390_ISR_CNT equ 0x20 ; Counter overflow
D8390_ISR_RDC equ 0x40 ; Remote DMA complete
D8390_ISR_RST equ 0x80 ; reset
D8390_RSTAT_PRX equ 0x01 ; successful recv
D8390_RSTAT_CRC equ 0x02 ; CRC error
D8390_RSTAT_FAE equ 0x04 ; Frame alignment error
D8390_RSTAT_OVER equ 0x08 ; FIFO overrun
D8390_TXBUF_SIZE equ 6
D8390_RXBUF_END equ 32
D8390_PAGE_SIZE equ 256
ETH_ALEN equ 6
ETH_HLEN equ 14
ETH_ZLEN equ 60
ETH_FRAME_LEN equ 1514
FLAG_PIO equ 0x01
FLAG_16BIT equ 0x02
ASIC_PIO equ 0
VENDOR_NONE equ 0
VENDOR_WD equ 1
VENDOR_NOVELL equ 2
VENDOR_3COM equ 3
NE_ASIC_OFFSET equ 0x10
NE_RESET equ 0x0F ; Used to reset card
NE_DATA equ 0x00 ; Used to read/write NIC mem
MEM_8192 equ 32
MEM_16384 equ 64
MEM_32768 equ 128
ISA_MAX_ADDR equ 0x400
uglobal
eth_flags: db 0
eth_vendor: db 0
eth_nic_base: dw 0
eth_asic_base: dw 0
eth_memsize: db 0
eth_rx_start: db 0
eth_tx_start: db 0
eth_bmem: dd 0
eth_rmem: dd 0
romdata: db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
endg
iglobal
test_data: db 'NE*000 memory',0
test_buffer: db ' ',0
endg
uglobal
eth_type: dw 0
pkthdr: db 0,0,0,0 ; status, next, (short) len
pktoff: dw 0
eth_rx_data_ptr: dd 0
eth_tmp_len: dw 0
endg
;***************************************************************************
; Function
; eth_pio_read
;
; Description
; Read a frame from the ethernet card via Programmed I/O
; src in ebx
; cnt in ecx
; dst in edi
;***************************************************************************
eth_pio_read:
mov al, [eth_flags]
and al, FLAG_16BIT
cmp al, 0
je epr_001
inc ecx
and ecx, 0xFFFFFFFE
epr_001:
mov al, D8390_COMMAND_RD2_STA
mov dx, [eth_nic_base]
add dx, D8390_P0_COMMAND
out dx, al
mov al, cl
mov dx, [eth_nic_base]
add dx, D8390_P0_RBCR0
out dx, al
mov al, ch
mov dx, [eth_nic_base]
add dx, D8390_P0_RBCR1
out dx, al
mov al, bl
mov dx, [eth_nic_base]
add dx, D8390_P0_RSAR0
out dx, al
mov al, bh
mov dx, [eth_nic_base]
add dx, D8390_P0_RSAR1
out dx, al
mov al, D8390_COMMAND_RD0_STA
mov dx, [eth_nic_base]
add dx, D8390_P0_COMMAND
out dx, al
mov dx, [eth_asic_base]
add dx, ASIC_PIO
mov al, [eth_flags]
and al, FLAG_16BIT
cmp al, 0
je epr_003
shr ecx, 1
epr_002:
; 2 bytes at a time
in ax, dx
mov [edi], ax
add edi, 2
loop epr_002
ret
epr_003:
; 1 byte at a time
in al, dx
mov [edi], al
inc edi
loop epr_003
ret
;***************************************************************************
; Function
; eth_pio_write
;
; Description
; writes a frame to the ethernet card via Programmed I/O
; dst in ebx
; cnt in ecx
; src in esi
;***************************************************************************
eth_pio_write:
mov al, [eth_flags]
and al, FLAG_16BIT
cmp al, 0
je epw_001
inc ecx
and ecx, 0xFFFFFFFE
epw_001:
mov al, D8390_COMMAND_RD2_STA
mov dx, [eth_nic_base]
add dx, D8390_P0_COMMAND
out dx, al
mov al, D8390_ISR_RDC
mov dx, [eth_nic_base]
add dx, D8390_P0_ISR
out dx, al
mov al, cl
mov dx, [eth_nic_base]
add dx, D8390_P0_RBCR0
out dx, al
mov al, ch
mov dx, [eth_nic_base]
add dx, D8390_P0_RBCR1
out dx, al
mov al, bl
mov dx, [eth_nic_base]
add dx, D8390_P0_RSAR0
out dx, al
mov al, bh
mov dx, [eth_nic_base]
add dx, D8390_P0_RSAR1
out dx, al
mov al, D8390_COMMAND_RD1_STA
mov dx, [eth_nic_base]
add dx, D8390_P0_COMMAND
out dx, al
mov dx, [eth_asic_base]
add dx, ASIC_PIO
mov al, [eth_flags]
and al, FLAG_16BIT
cmp al, 0
je epw_003
shr ecx, 1
epw_002:
; 2 bytes at a time
mov ax, [esi]
add esi, 2
out dx, ax
loop epw_002
jmp epw_004
epw_003:
; 1 byte at a time
mov al, [esi]
inc esi
out dx, al
loop epw_003
epw_004:
mov dx, [eth_nic_base]
add dx, D8390_P0_ISR
epw_005:
in al, dx
and al, D8390_ISR_RDC
cmp al, D8390_ISR_RDC
jne epw_005
ret
;***************************************************************************
; Function
; rtl8029_reset
; Description
; Place the chip (ie, the ethernet card) into a virgin state
; No inputs
; All registers destroyed
;
;***************************************************************************
rtl8029_reset:
mov bx, [eth_nic_base]
mov dx, bx
add dx, D8390_P0_COMMAND
mov al, D8390_COMMAND_PS0_RD2_STP
out dx, al
mov dx, bx
add dx, D8390_P0_DCR
mov al, [eth_flags]
and al, FLAG_16BIT
cmp al, FLAG_16BIT
jne nsr_001
mov al, 0x49
jmp nsr_002
nsr_001:
mov al, 0x48
nsr_002:
out dx, al
xor al, al
mov dx, bx
add dx, D8390_P0_RBCR0
out dx, al
mov dx, bx
add dx, D8390_P0_RBCR1
out dx, al
mov dx, bx
add dx, D8390_P0_RCR
mov al, 0x20
out dx, al
mov dx, bx
add dx, D8390_P0_TCR
mov al, 2
out dx, al
mov dx, bx
add dx, D8390_P0_TPSR
mov al, [eth_tx_start]
out dx, al
mov dx, bx
add dx, D8390_P0_PSTART
mov al, [eth_rx_start]
out dx, al
mov dx, bx
add dx, D8390_P0_PSTOP
mov al, [eth_memsize]
out dx, al
mov dx, bx
add dx, D8390_P0_BOUND
mov al, [eth_memsize]
dec al
out dx, al
mov dx, bx
add dx, D8390_P0_ISR
mov al, 0xff
out dx, al
mov dx, bx
add dx, D8390_P0_IMR
xor al, al
out dx, al
mov dx, bx
add dx, D8390_P0_COMMAND
mov al, D8390_COMMAND_PS1_RD2_STP
out dx, al
mov dx, bx
add dx, D8390_P1_PAR0
mov esi, node_addr
mov ecx, ETH_ALEN
nsr_003:
mov al, [esi]
out dx, al
inc esi
inc dx
loop nsr_003
mov dx, bx
add dx, D8390_P1_MAR0
mov ecx, ETH_ALEN
mov al, 0xff
nsr_004:
out dx, al
inc dx
loop nsr_004
mov dx, bx
add dx, D8390_P1_CURR
mov al, [eth_rx_start]
out dx, al
mov dx, bx
add dx, D8390_P0_COMMAND
mov al, D8390_COMMAND_PS0_RD2_STA
out dx, al
mov dx, bx
add dx, D8390_P0_ISR
mov al, 0xff
out dx, al
mov dx, bx
add dx, D8390_P0_TCR
mov al, 0
out dx, al
mov dx, bx
add dx, D8390_P0_RCR
mov al, 4
out dx, al
ret
;***************************************************************************
; Function
; rtl8029_probe
; Description
; Searches for an ethernet card, enables it and clears the rx buffer
; If a card was found, it enables the ethernet -> TCPIP link
;
;***************************************************************************
rtl8029_probe:
mov eax, [io_addr]
mov [eth_nic_base], ax ; The IO address space is 16 bit only
mov al, VENDOR_NONE
mov [eth_vendor], al
mov al, [eth_vendor]
cmp al, VENDOR_NONE
jne ep_check_have_vendor
xor eax, eax
mov [eth_bmem], eax
mov al, FLAG_PIO
mov [eth_flags], al
mov ax, [eth_nic_base]
add ax, NE_ASIC_OFFSET
mov [eth_asic_base], ax
mov al, MEM_16384
mov [eth_memsize], al
mov al, 32
mov [eth_tx_start], al
add al, D8390_TXBUF_SIZE
mov [eth_rx_start], al
mov dx, [eth_asic_base]
add dx, NE_RESET
in al, dx
out dx, al
in al, 0x84
mov bx, [eth_nic_base]
mov dx, bx
add dx, D8390_P0_COMMAND
mov al, D8390_COMMAND_RD2_STP
out dx, al
mov dx, bx
add dx, D8390_P0_RCR
mov al, D8390_RCR_MON
out dx, al
mov dx, bx
add dx, D8390_P0_DCR
mov al, D8390_DCR_FT1_LS
out dx, al
mov dx, bx
add dx, D8390_P0_PSTART
mov al, MEM_8192
out dx, al
mov dx, bx
add dx, D8390_P0_PSTOP
mov al, MEM_16384
out dx, al
mov esi, test_data
mov ebx, 8192
mov ecx, 14
call eth_pio_write
mov ebx, 8192
mov ecx, 14
mov edi, test_buffer
call eth_pio_read
mov esi, test_buffer
mov edi, test_data
mov ecx, 13
cld
rep cmpsb
je ep_set_vendor
mov al, [eth_flags]
or al, FLAG_16BIT
mov [eth_flags], al
mov al, MEM_32768
mov [eth_memsize], al
mov al, 64
mov [eth_tx_start], al
add al, D8390_TXBUF_SIZE
mov [eth_rx_start], al
mov bx, [eth_nic_base]
mov dx, bx
add dx, D8390_P0_DCR
mov al, D8390_DCR_WTS_FT1_LS
out dx, al
mov dx, bx
add dx, D8390_P0_PSTART
mov al, MEM_16384
out dx, al
mov dx, bx
add dx, D8390_P0_PSTOP
mov al, MEM_32768
out dx, al
mov esi, test_data
mov ebx, 16384
mov ecx, 14
call eth_pio_write
mov ebx, 16384
mov ecx, 14
mov edi, test_buffer
call eth_pio_read
mov esi, test_buffer
mov edi, test_data
mov ecx, 13
cld
rep cmpsb
ep_set_vendor:
; this bit is odd - probably left over from my hacking
mov ax, [eth_nic_base]
cmp ax, 0
je rtl8029_exit
cmp ax, ISA_MAX_ADDR
jbe ep_001
mov al, [eth_flags]
or al, FLAG_16BIT
mov [eth_flags], al
ep_001:
mov al, VENDOR_NOVELL
mov [eth_vendor], al
mov ebx, 0
mov ecx, 16
mov edi, romdata
call eth_pio_read
mov ecx, ETH_ALEN
mov esi, romdata
mov edi, node_addr
mov bl, [eth_flags]
and bl, FLAG_16BIT
ep_002:
mov al, [esi]
mov [edi], al
inc edi
inc esi
cmp bl, FLAG_16BIT
jne ep_003
inc esi
ep_003:
loop ep_002
ep_check_have_vendor:
mov al, [eth_vendor]
cmp al, VENDOR_NONE
je rtl8029_exit
cmp al, VENDOR_3COM
je ep_reset_card
mov eax, [eth_bmem]
mov [eth_rmem], eax
ep_reset_card:
; Reset the card
call rtl8029_reset
; Indicate that we have successfully reset the card
mov eax, [pci_data]
mov [eth_status], eax
rtl8029_exit:
ret
;***************************************************************************
; Function
; rtl8029_poll
;
; Description
; Polls the ethernet card for a received packet
; Received data, if any, ends up in Ether_buffer
;
;***************************************************************************
rtl8029_poll:
mov eax, Ether_buffer
mov [eth_rx_data_ptr], eax
mov bx, [eth_nic_base]
mov dx, bx
add dx, D8390_P0_RSR
in al, dx
and al, D8390_RSTAT_PRX
cmp al, D8390_RSTAT_PRX
jne nsp_exit
mov dx, bx
add dx, D8390_P0_BOUND
in al, dx
inc al
cmp al, [eth_memsize]
jb nsp_001
mov al, [eth_rx_start]
nsp_001:
mov ch, al
mov dx, bx
add dx, D8390_P0_COMMAND
mov al, D8390_COMMAND_PS1
out dx, al
mov dx, bx
add dx, D8390_P1_CURR
in al, dx ; get current page
mov cl, al
mov dx, bx
add dx, D8390_P0_COMMAND
mov al, D8390_COMMAND_PS0
out dx, al
cmp cl, [eth_memsize]
jb nsp_002
mov cl, [eth_rx_start]
nsp_002:
cmp cl, ch
je nsp_exit
xor ax, ax
mov ah, ch
mov [pktoff], ax
mov al, [eth_flags]
and al, FLAG_PIO
cmp al, FLAG_PIO
jne nsp_003
movzx ebx, word [pktoff]
mov edi, pkthdr
mov ecx, 4
call eth_pio_read
jmp nsp_004
nsp_003:
mov edi, [eth_rmem]
movzx eax, word [pktoff]
add edi, eax
mov eax, [edi]
mov [pkthdr], eax
nsp_004:
mov ax, [pktoff]
add ax, 4
mov [pktoff], ax
mov ax, [pkthdr + 2]
sub ax, 4
mov [eth_tmp_len], ax
cmp ax, ETH_ZLEN
jb nsp_exit
cmp ax, ETH_FRAME_LEN
ja nsp_exit
mov al, [pkthdr]
and al, D8390_RSTAT_PRX
cmp al, D8390_RSTAT_PRX
jne nsp_exit
; Right, we can now get the data
mov ax, [eth_tmp_len]
mov [eth_rx_data_len], ax
xor ebx, ebx
mov bh, [eth_memsize]
sub bx, [pktoff]
cmp [eth_tmp_len], bx
jbe nsp_005
mov al, [eth_flags]
and al, FLAG_PIO
cmp al, FLAG_PIO
jne nsp_006
push ebx
mov ecx, ebx
xor ebx, ebx
mov bx, [pktoff]
mov edi, [eth_rx_data_ptr]
call eth_pio_read
pop ebx
jmp nsp_007
nsp_006:
; Not implemented, as we are using PIO mode on this card
nsp_007:
xor ax, ax
mov ah, [eth_rx_start]
mov [pktoff], ax
mov eax, [eth_rx_data_ptr]
add eax, ebx
mov [eth_rx_data_ptr], eax
mov ax, [eth_tmp_len]
sub ax, bx
mov [eth_tmp_len], ax
nsp_005:
mov al, [eth_flags]
and al, FLAG_PIO
cmp al, FLAG_PIO
jne nsp_008
xor ebx, ebx
mov bx, [pktoff]
xor ecx, ecx
mov cx, [eth_tmp_len]
mov edi, [eth_rx_data_ptr]
call eth_pio_read
jmp nsp_009
nsp_008:
; Not implemented, as we are using PIO mode on this card
nsp_009:
mov al, [pkthdr+1]
cmp al, [eth_rx_start]
jne nsp_010
mov al, [eth_memsize]
nsp_010:
mov dx, [eth_nic_base]
add dx, D8390_P0_BOUND
dec al
out dx, al
nsp_exit:
ret
;***************************************************************************
; Function
; rtl8029_transmit
;
; Description
; Transmits a packet of data via the ethernet card
; Pointer to 48 bit destination address in edi
; Type of packet in bx
; size of packet in ecx
; pointer to packet data in esi
;
;***************************************************************************
rtl8029_transmit:
mov [eth_type], bx
pusha
mov esi, edi
xor bx, bx
mov bh, [eth_tx_start]
mov ecx, ETH_ALEN
call eth_pio_write
mov esi, node_addr
xor bx, bx
mov bh, [eth_tx_start]
add bx, ETH_ALEN
mov ecx, ETH_ALEN
call eth_pio_write
mov esi, eth_type
xor bx, bx
mov bh, [eth_tx_start]
add bx, ETH_ALEN
add bx, ETH_ALEN
mov ecx, 2
call eth_pio_write
popa
xor bx, bx
mov bh, [eth_tx_start]
add bx, ETH_HLEN
push ecx
call eth_pio_write
pop ecx
add ecx, ETH_HLEN
cmp ecx, ETH_ZLEN
jae nst_001
mov ecx, ETH_ZLEN
nst_001:
push ecx
mov bx, [eth_nic_base]
mov dx, bx
add dx, D8390_P0_COMMAND
mov al, D8390_COMMAND_PS0_RD2_STA
out dx, al
mov dx, bx
add dx, D8390_P0_TPSR
mov al, [eth_tx_start]
out dx, al
pop ecx
mov dx, bx
add dx, D8390_P0_TBCR0
mov al, cl
out dx, al
mov dx, bx
add dx, D8390_P0_TBCR1
mov al, ch
out dx, al
mov dx, bx
add dx, D8390_P0_COMMAND
mov al, D8390_COMMAND_PS0_TXP_RD2_STA
out dx, al
ret

View File

@ -0,0 +1,612 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; RTL8139.INC ;;
;; ;;
;; Ethernet driver for Menuet OS ;;
;; ;;
;; Version 0.2 11 August 2003 ;;
;; ;;
;; Driver for chips of RealTek 8139 family ;;
;; References: ;;
;; www.realtek.com.hw - data sheets ;;
;; rtl8139.c - linux driver ;;
;; 8139too.c - linux driver ;;
;; ethernet driver template by Mike Hibbett ;;
;; ;;
;; The copyright statement is ;;
;; ;;
;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;;
;; ;;
;; Copyright 2003 Endre Kozma, ;;
;; endre.kozma@axelero.hu ;;
;; ;;
;; See file COPYING for details ;;
;; ;;
;; 10.01.2007 Bugfix for l8139_transmit from Paolo Franchetti ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ETH_ALEN equ 6
ETH_HLEN equ (2 * ETH_ALEN + 2)
ETH_ZLEN equ 60 ; 60 + 4bytes auto payload for
; mininmum 64bytes frame length
PCI_REG_COMMAND equ 0x04 ; command register
PCI_BIT_PIO equ 0 ; bit0: io space control
PCI_BIT_MMIO equ 1 ; bit1: memory space control
PCI_BIT_MASTER equ 2 ; bit2: device acts as a PCI master
RTL8139_REG_MAR0 equ 0x08 ; multicast filter register 0
RTL8139_REG_MAR4 equ 0x0c ; multicast filter register 4
RTL8139_REG_TSD0 equ 0x10 ; transmit status of descriptor
RTL8139_REG_TSAD0 equ 0x20 ; transmit start address of descriptor
RTL8139_REG_RBSTART equ 0x30 ; RxBuffer start address
RTL8139_REG_COMMAND equ 0x37 ; command register
RTL8139_REG_CAPR equ 0x38 ; current address of packet read
RTL8139_REG_IMR equ 0x3c ; interrupt mask register
RTL8139_REG_ISR equ 0x3e ; interrupt status register
RTL8139_REG_TXCONFIG equ 0x40 ; transmit configuration register
RTL8139_REG_TXCONFIG_0 equ 0x40 ; transmit configuration register 0
RTL8139_REG_TXCONFIG_1 equ 0x41 ; transmit configuration register 1
RTL8139_REG_TXCONFIG_2 equ 0x42 ; transmit configuration register 2
RTL8139_REG_TXCONFIG_3 equ 0x43 ; transmit configuration register 3
RTL8139_REG_RXCONFIG equ 0x44 ; receive configuration register 0
RTL8139_REG_RXCONFIG_0 equ 0x44 ; receive configuration register 0
RTL8139_REG_RXCONFIG_1 equ 0x45 ; receive configuration register 1
RTL8139_REG_RXCONFIG_2 equ 0x46 ; receive configuration register 2
RTL8139_REG_RXCONFIG_3 equ 0x47 ; receive configuration register 3
RTL8139_REG_MPC equ 0x4c ; missed packet counter
RTL8139_REG_9346CR equ 0x50 ; serial eeprom 93C46 command register
RTL8139_REG_CONFIG1 equ 0x52 ; configuration register 1
RTL8139_REG_CONFIG4 equ 0x5a ; configuration register 4
RTL8139_REG_HLTCLK equ 0x5b ; undocumented halt clock register
RTL8139_REG_BMCR equ 0x62 ; basic mode control register
RTL8139_REG_ANAR equ 0x66 ; auto negotiation advertisement register
; 5.1 packet header
RTL8139_BIT_RUNT equ 4 ; total packet length < 64 bytes
RTL8139_BIT_LONG equ 3 ; total packet length > 4k
RTL8139_BIT_CRC equ 2 ; crc error occured
RTL8139_BIT_FAE equ 1 ; frame alignment error occured
RTL8139_BIT_ROK equ 0 ; received packet is ok
; 5.4 command register
RTL8139_BIT_RST equ 4 ; reset bit
RTL8139_BIT_RE equ 3 ; receiver enabled
RTL8139_BIT_TE equ 2 ; transmitter enabled
RTL8139_BIT_BUFE equ 0 ; rx buffer is empty, no packet stored
; 5.6 interrupt status register
RTL8139_BIT_ISR_TOK equ 2 ; transmit ok
RTL8139_BIT_ISR_RER equ 1 ; receive error interrupt
RTL8139_BIT_ISR_ROK equ 0 ; receive ok
; 5.7 transmit configyration register
RTL8139_BIT_TX_MXDMA equ 8 ; Max DMA burst size per Tx DMA burst
RTL8139_BIT_TXRR equ 4 ; Tx Retry count 16+(TXRR*16)
; 5.8 receive configuration register
RTL8139_BIT_RXFTH equ 13 ; Rx fifo threshold
RTL8139_BIT_RBLEN equ 11 ; Ring buffer length indicator
RTL8139_BIT_RX_MXDMA equ 8 ; Max DMA burst size per Rx DMA burst
RTL8139_BIT_NOWRAP equ 7 ; transfered data wrapping
RTL8139_BIT_9356SEL equ 6 ; eeprom selector 9346/9356
RTL8139_BIT_AER equ 5 ; accept error packets
RTL8139_BIT_AR equ 4 ; accept runt packets
RTL8139_BIT_AB equ 3 ; accept broadcast packets
RTL8139_BIT_AM equ 2 ; accept multicast packets
RTL8139_BIT_APM equ 1 ; accept physical match packets
RTL8139_BIT_AAP equ 0 ; accept all packets
; 5.9 93C46/93C56 command register
RTL8139_BIT_93C46_EEM1 equ 7 ; RTL8139 eeprom operating mode1
RTL8139_BIT_93C46_EEM0 equ 6 ; RTL8139 eeprom operating mode0
RTL8139_BIT_93C46_EECS equ 3 ; chip select
RTL8139_BIT_93C46_EESK equ 2 ; serial data clock
RTL8139_BIT_93C46_EEDI equ 1 ; serial data input
RTL8139_BIT_93C46_EEDO equ 0 ; serial data output
; 5.11 configuration register 1
RTL8139_BIT_LWACT equ 4 ; see RTL8139_REG_CONFIG1
RTL8139_BIT_SLEEP equ 1 ; sleep bit at older chips
RTL8139_BIT_PWRDWN equ 0 ; power down bit at older chips
RTL8139_BIT_PMEn equ 0 ; power management enabled
; 5.14 configuration register 4
RTL8139_BIT_LWPTN equ 2 ; see RTL8139_REG_CONFIG4
; 6.2 transmit status register
RTL8139_BIT_ERTXTH equ 16 ; early TX threshold
RTL8139_BIT_TOK equ 15 ; transmit ok
RTL8139_BIT_OWN equ 13 ; tx DMA operation is completed
; 6.18 basic mode control register
RTL8139_BIT_ANE equ 12 ; auto negotiation enable
; 6.20 auto negotiation advertisement register
RTL8139_BIT_TXFD equ 8 ; 100base-T full duplex
RTL8139_BIT_TX equ 7 ; 100base-T
RTL8139_BIT_10FD equ 6 ; 10base-T full duplex
RTL8139_BIT_10 equ 5 ; 10base-T
RTL8139_BIT_SELECTOR equ 0 ; binary encoded selector CSMA/CD=00001
; RX/TX buffer size
RTL8139_RBLEN equ 0 ; 0==8K 1==16k 2==32k 3==64k
RTL8139_RX_BUFFER_SIZE equ (8192 shl RTL8139_RBLEN)
MAX_ETH_FRAME_SIZE equ 1516 ; exactly 1514 wthout CRC
RTL8139_NUM_TX_DESC equ 4
RTL8139_TX_BUFFER_SIZE equ (MAX_ETH_FRAME_SIZE * RTL8139_NUM_TX_DESC)
RTL8139_TXRR equ 8 ; total retries = 16+(TXRR*16)
RTL8139_TX_MXDMA equ 6 ; 0==16 1==32 2==64 3==128
; 4==256 5==512 6==1024 7==2048
RTL8139_ERTXTH equ 8 ; in unit of 32 bytes e.g:(8*32)=256
RTL8139_RX_MXDMA equ 7 ; 0==16 1==32 2==64 3==128
; 4==256 5==512 6==1024 7==unlimited
RTL8139_RXFTH equ 7 ; 0==16 1==32 2==64 3==128
; 4==256 5==512 6==1024 7==no threshold
RTL8139_RX_CONFIG equ ((RTL8139_RBLEN shl RTL8139_BIT_RBLEN) \
or (RTL8139_RX_MXDMA shl RTL8139_BIT_RX_MXDMA) \
or (1 shl RTL8139_BIT_NOWRAP) \
or (RTL8139_RXFTH shl RTL8139_BIT_RXFTH) \
or (1 shl RTL8139_BIT_AB) or (1 shl RTL8139_BIT_APM) \
or (1 shl RTL8139_BIT_AER) or (1 shl RTL8139_BIT_AR) \
or (1 shl RTL8139_BIT_AM))
RTL8139_TX_TIMEOUT equ 30 ; 300 milliseconds timeout
EE_93C46_REG_ETH_ID equ 7 ; MAC offset
EE_93C46_READ_CMD equ (6 shl 6) ; 110b + 6bit address
EE_93C56_READ_CMD equ (6 shl 8) ; 110b + 8bit address
EE_93C46_CMD_LENGTH equ 9 ; start bit + cmd + 6bit address
EE_93C56_CMD_LENGTH equ 11 ; start bit + cmd + 8bit ddress
VER_RTL8139 equ 1100000b
VER_RTL8139A equ 1110000b
; VER_RTL8139AG equ 1110100b
VER_RTL8139B equ 1111000b
VER_RTL8130 equ VER_RTL8139B
VER_RTL8139C equ 1110100b
VER_RTL8100 equ 1111010b
VER_RTL8100B equ 1110101b
VER_RTL8139D equ VER_RTL8100B
VER_RTL8139CP equ 1110110b
VER_RTL8101 equ 1110111b
IDX_RTL8139 equ 0
IDX_RTL8139A equ 1
IDX_RTL8139B equ 2
IDX_RTL8139C equ 3
IDX_RTL8100 equ 4
IDX_RTL8139D equ 5
IDX_RTL8139D equ 6
IDX_RTL8101 equ 7
; These two must be 4 byte aligned ( which they are )
rtl8139_rx_buff equ eth_data_start
rtl8139_tx_buff equ rtl8139_rx_buff + (RTL8139_RX_BUFFER_SIZE + MAX_ETH_FRAME_SIZE)
uglobal
align 4
rtl8139_rx_buff_offset: dd 0
curr_tx_desc dd 0
endg
iglobal
hw_ver_array: db VER_RTL8139, VER_RTL8139A, VER_RTL8139B, VER_RTL8139C
db VER_RTL8100, VER_RTL8139D, VER_RTL8139CP, VER_RTL8101
HW_VER_ARRAY_SIZE = $-hw_ver_array
endg
uglobal
hw_ver_id: db 0
endg
;***************************************************************************
; Function
; rtl8139_probe
; Description
; Searches for an ethernet card, enables it and clears the rx buffer
; If a card was found, it enables the ethernet -> TCPIP link
; Destroyed registers
; eax, ebx, ecx, edx
;
;***************************************************************************
rtl8139_probe:
; enable the device
mov al, 2
mov ah, [pci_bus]
mov bh, [pci_dev]
mov bl, PCI_REG_COMMAND
call pci_read_reg
mov cx, ax
or cl, (1 shl PCI_BIT_MASTER) or (1 shl PCI_BIT_PIO)
and cl, not (1 shl PCI_BIT_MMIO)
mov al, 2
mov ah, [pci_bus]
mov bh, [pci_dev]
mov bl, PCI_REG_COMMAND
call pci_write_reg
; get chip version
mov edx, [io_addr]
add edx, RTL8139_REG_TXCONFIG_2
in ax, dx
shr ah, 2
shr ax, 6
and al, 01111111b
mov ecx, HW_VER_ARRAY_SIZE-1
.chip_ver_loop:
cmp al, [hw_ver_array+ecx]
je .chip_ver_found
dec ecx
jns .chip_ver_loop
xor cl, cl ; default RTL8139
.chip_ver_found:
mov [hw_ver_id], cl
; wake up the chip
mov edx, [io_addr]
add edx, RTL8139_REG_HLTCLK
mov al, 'R' ; run the clock
out dx, al
; unlock config and BMCR registers
add edx, RTL8139_REG_9346CR - RTL8139_REG_HLTCLK
mov al, (1 shl RTL8139_BIT_93C46_EEM1) or (1 shl RTL8139_BIT_93C46_EEM0)
out dx, al
; enable power management
add edx, RTL8139_REG_CONFIG1 - RTL8139_REG_9346CR
in al, dx
cmp byte [hw_ver_id], IDX_RTL8139B
jl .old_chip
; set LWAKE pin to active high (default value).
; it is for Wake-On-LAN functionality of some motherboards.
; this signal is used to inform the motherboard to execute a wake-up process.
; only at newer chips.
or al, (1 shl RTL8139_BIT_PMEn)
and al, not (1 shl RTL8139_BIT_LWACT)
out dx, al
add edx, RTL8139_REG_CONFIG4 - RTL8139_REG_CONFIG1
in al, dx
and al, not (1 shl RTL8139_BIT_LWPTN)
out dx, al
jmp .finish_wake_up
.old_chip:
; wake up older chips
and al, not ((1 shl RTL8139_BIT_SLEEP) or (1 shl RTL8139_BIT_PWRDWN))
out dx, al
.finish_wake_up:
; lock config and BMCR registers
xor al, al
mov edx, [io_addr]
add edx, RTL8139_REG_9346CR
out dx, al
;***************************************************************************
; Function
; rt8139_reset
; Description
; Place the chip (ie, the ethernet card) into a virgin state
; Destroyed registers
; eax, ebx, ecx, edx
;
;***************************************************************************
rtl8139_reset:
mov edx, [io_addr]
add edx, RTL8139_REG_COMMAND
mov al, 1 shl RTL8139_BIT_RST
out dx, al
mov cx, 1000 ; wait no longer for the reset
.wait_for_reset:
in al, dx
test al, 1 shl RTL8139_BIT_RST
jz .reset_completed ; RST remains 1 during reset
dec cx
jns .wait_for_reset
.reset_completed:
; get MAC (hardware address)
mov ecx, 2
.mac_read_loop:
lea eax, [EE_93C46_REG_ETH_ID+ecx]
push ecx
call rtl8139_read_eeprom
pop ecx
mov [node_addr+ecx*2], ax
dec ecx
jns .mac_read_loop
; unlock config and BMCR registers
mov edx, [io_addr]
add edx, RTL8139_REG_9346CR
mov al, (1 shl RTL8139_BIT_93C46_EEM1) or (1 shl RTL8139_BIT_93C46_EEM0)
out dx, al
; initialize multicast registers (no filtering)
mov eax, 0xffffffff
add edx, RTL8139_REG_MAR0 - RTL8139_REG_9346CR
out dx, eax
add edx, RTL8139_REG_MAR4 - RTL8139_REG_MAR0
out dx, eax
; enable Rx/Tx
mov al, (1 shl RTL8139_BIT_RE) or (1 shl RTL8139_BIT_TE)
add edx, RTL8139_REG_COMMAND - RTL8139_REG_MAR4
out dx, al
; 32k Rxbuffer, unlimited dma burst, no wrapping, no rx threshold
; accept broadcast packets, accept physical match packets
mov ax, RTL8139_RX_CONFIG
add edx, RTL8139_REG_RXCONFIG - RTL8139_REG_COMMAND
out dx, ax
; 1024 bytes DMA burst, total retries = 16 + 8 * 16 = 144
mov ax, (RTL8139_TX_MXDMA shl RTL8139_BIT_TX_MXDMA) \
or (RTL8139_TXRR shl RTL8139_BIT_TXRR)
add edx, RTL8139_REG_TXCONFIG - RTL8139_REG_RXCONFIG
out dx, ax
; enable auto negotiation
add edx, RTL8139_REG_BMCR - RTL8139_REG_TXCONFIG
in ax, dx
or ax, (1 shl RTL8139_BIT_ANE)
out dx, ax
; set auto negotiation advertisement
add edx, RTL8139_REG_ANAR - RTL8139_REG_BMCR
in ax, dx
or ax, (1 shl RTL8139_BIT_SELECTOR) or (1 shl RTL8139_BIT_10) \
or (1 shl RTL8139_BIT_10FD) or (1 shl RTL8139_BIT_TX) \
or (1 shl RTL8139_BIT_TXFD)
out dx, ax
; lock config and BMCR registers
xor eax, eax
add edx, RTL8139_REG_9346CR - RTL8139_REG_ANAR
out dx, al
; init RX/TX pointers
mov [rtl8139_rx_buff_offset], eax
mov [curr_tx_desc], eax
; clear missing packet counter
add edx, RTL8139_REG_MPC - RTL8139_REG_9346CR
out dx, eax
; disable all interrupts
add edx, RTL8139_REG_IMR - RTL8139_REG_MPC
out dx, ax
; set RxBuffer address, init RX buffer offset, init TX ring
mov eax, rtl8139_rx_buff
add edx, RTL8139_REG_RBSTART - RTL8139_REG_IMR
out dx, eax
; Indicate that we have successfully reset the card
mov eax, [pci_data]
mov [eth_status], eax
ret
;***************************************************************************
; Function
; rtl8139_read_eeprom
; Description
; reads eeprom type 93c46 and 93c56
; Parameters
; al - word to be read (6bit in case of 93c46 and 8bit otherwise)
; Return value
; ax - word read in
; Destroyed register(s)
; eax, cx, ebx, edx
;
;***************************************************************************
rtl8139_read_eeprom:
movzx ebx, al
mov edx, [io_addr]
add edx, RTL8139_REG_RXCONFIG
in al, dx
test al, (1 shl RTL8139_BIT_9356SEL)
jz .type_93c46
; and bl, 01111111b ; don't care first bit
or bx, EE_93C56_READ_CMD ; it contains start bit
mov cx, EE_93C56_CMD_LENGTH-1 ; cmd_loop counter
jmp .read_eeprom
.type_93c46:
and bl, 00111111b
or bx, EE_93C46_READ_CMD ; it contains start bit
mov cx, EE_93C46_CMD_LENGTH-1 ; cmd_loop counter
.read_eeprom:
add edx, RTL8139_REG_9346CR - RTL8139_REG_RXCONFIG_0
; mov al, (1 shl RTL8139_BIT_93C46_EEM1)
; out dx, al
mov al, (1 shl RTL8139_BIT_93C46_EEM1) \
or (1 shl RTL8139_BIT_93C46_EECS) ; wake up the eeprom
out dx, al
.cmd_loop:
mov al, (1 shl RTL8139_BIT_93C46_EEM1) or (1 shl RTL8139_BIT_93C46_EECS)
bt bx, cx
jnc .zero_bit
or al, (1 shl RTL8139_BIT_93C46_EEDI)
.zero_bit:
out dx, al
; push eax
; in eax, dx ; eeprom delay
; pop eax
or al, (1 shl RTL8139_BIT_93C46_EESK)
out dx, al
; in eax, dx ; eeprom delay
dec cx
jns .cmd_loop
; in eax, dx ; eeprom delay
mov al, (1 shl RTL8139_BIT_93C46_EEM1) or (1 shl RTL8139_BIT_93C46_EECS)
out dx, al
mov cl, 0xf
.read_loop:
shl ebx, 1
mov al, (1 shl RTL8139_BIT_93C46_EEM1) \
or (1 shl RTL8139_BIT_93C46_EECS) \
or (1 shl RTL8139_BIT_93C46_EESK)
out dx, al
; in eax, dx ; eeprom delay
in al, dx
and al, (1 shl RTL8139_BIT_93C46_EEDO)
jz .dont_set
inc ebx
.dont_set:
mov al, (1 shl RTL8139_BIT_93C46_EEM1) \
or (1 shl RTL8139_BIT_93C46_EECS)
out dx, al
; in eax, dx ; eeprom delay
dec cl
jns .read_loop
xor al, al
out dx, al
mov ax, bx
ret
;***************************************************************************
; Function
; rtl8139_transmit
; Description
; Transmits a packet of data via the ethernet card
; Pointer to 48 bit destination address in edi
; Type of packet in bx
; Size of packet in ecx
; Pointer to packet data in esi
; Destroyed registers
; eax, edx, esi, edi
; ToDo
; for waiting of timeout the rtl8139 internal timer
; should be used
;
;***************************************************************************
rtl8139_transmit:
cmp ecx, MAX_ETH_FRAME_SIZE
jg .finish ; packet is too long
push ecx
; check descriptor
mov ecx, [curr_tx_desc]
mov edx, [io_addr]
lea edx, [edx+ecx*4+RTL8139_REG_TSD0]
push edx ebx
in ax, dx
test ax, 0x1fff ; or no size given
jz .send_packet
and ax, (1 shl RTL8139_BIT_TOK) or (1 shl RTL8139_BIT_OWN)
cmp ax, (1 shl RTL8139_BIT_TOK) or (1 shl RTL8139_BIT_OWN)
jz .send_packet
; wait for timeout
mov ebx, RTL8139_TX_TIMEOUT
mov eax, 0x5 ; delay x/100 secs
int 0x40
in ax, dx
and ax, (1 shl RTL8139_BIT_TOK) or (1 shl RTL8139_BIT_OWN)
cmp ax, (1 shl RTL8139_BIT_TOK) or (1 shl RTL8139_BIT_OWN)
jz .send_packet
; chip hung, reset it
call rtl8139_reset
; reset the card
.send_packet:
; calculate tx_buffer address
pop ebx
push esi
mov eax, MAX_ETH_FRAME_SIZE
mul dword [curr_tx_desc]
mov esi, edi
lea edi, [rtl8139_tx_buff+eax]
mov eax, edi
cld
; copy destination address
movsd
movsw
; copy source address
mov esi, node_addr
movsd
movsw
; copy packet type
mov [edi], bx
add edi, 2
; copy the packet data
pop esi edx ecx
push ecx
shr ecx, 2
rep movsd
pop ecx
push ecx
and ecx, 3
rep movsb
; set address
add edx, RTL8139_REG_TSAD0 - RTL8139_REG_TSD0
out dx, eax
; set size and early threshold
pop eax ; pick up the size
add eax, ETH_HLEN
cmp eax, ETH_ZLEN
jnc .no_pad
mov eax, ETH_ZLEN
.no_pad:
or eax, (RTL8139_ERTXTH shl RTL8139_BIT_ERTXTH)
add edx, RTL8139_REG_TSD0 - RTL8139_REG_TSAD0
out dx, eax
; get next descriptor 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, ...
inc dword [curr_tx_desc]
and dword [curr_tx_desc], 3
.finish:
ret
;***************************************************************************
; Function
; rtl8139_poll
;
; Description
; Polls the ethernet card for a received packet
; Received data, if any, ends up in Ether_buffer
; Destroyed register(s)
; eax, edx, ecx
;
;***************************************************************************
rtl8139_poll:
mov word [eth_rx_data_len], 0
mov edx, [io_addr]
add edx, RTL8139_REG_COMMAND
in al, dx
test al, (1 shl RTL8139_BIT_BUFE)
jnz .finish
; new packet received copy it from rx_buffer into Ether_buffer
mov eax, rtl8139_rx_buff
add eax, [rtl8139_rx_buff_offset]
; check if packet is ok
test byte [eax], (1 shl RTL8139_BIT_ROK)
jz .reset_rx
; packet is ok copy it into the Ether_buffer
movzx ecx, word [eax+2] ; packet length
sub ecx, 4 ; don't copy CRC
mov word [eth_rx_data_len], cx
push ecx
shr ecx, 2 ; first copy dword-wise
lea esi, [eax+4] ; don't copy the packet header
mov edi, Ether_buffer
cld
rep movsd ; copy the dwords
pop ecx
and ecx, 3
rep movsb ; copy the rest bytes
; update rtl8139_rx_buff_offset
movzx eax, word [eax+2] ; packet length
add eax, [rtl8139_rx_buff_offset]
add eax, 4+3 ; packet header is 4 bytes long + dword alignment
and eax, not 3 ; dword alignment
cmp eax, RTL8139_RX_BUFFER_SIZE
jl .no_wrap
sub eax, RTL8139_RX_BUFFER_SIZE
.no_wrap:
mov [rtl8139_rx_buff_offset], eax
; update CAPR register
sub eax, 0x10 ; value 0x10 is a constant for CAPR
add edx, RTL8139_REG_CAPR - RTL8139_REG_COMMAND
out dx, ax
.finish:
; clear active interrupt sources
mov edx, [io_addr]
add edx, RTL8139_REG_ISR
in ax, dx
out dx, ax
ret
.reset_rx:
in al, dx ; read command register
push eax
and al, not (1 shl RTL8139_BIT_RE)
out dx, al
pop eax
out dx, al
add edx, RTL8139_REG_RXCONFIG - RTL8139_REG_COMMAND
mov ax, RTL8139_RX_CONFIG
out dx, ax
ret
rtl8139_cable:
pusha
mov edx, [io_addr]
add edx, 0x58
in al,dx
test al,1 SHL 2
jnz .notconnected
popa
xor al,al
inc al
ret
.notconnected:
popa
xor al,al
ret

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,453 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; ETHERNET.INC ;;
;; ;;
;; Ethernet network layer for Menuet OS ;;
;; ;;
;; Version 0.4 22 September 2003 ;;
;; ;;
;; This file contains the following: ;;
;; PCI bus scanning for valid devices ;;
;; Table of supported ethernet drivers ;;
;; Code to identify and activate a supported driver ;;
;; ARP handler ;;
;; Driver interface to the IP layer ;;
;; Gateway support ;;
;; ;;
;; Individual driver files are included here ;;
;; ;;
;; The PCI bus scanning code was ported from the etherboot ;;
;; 5.0.6 project. The copyright statement for that code is ;;
;; ;;
;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;;
;; ;;
;; remaining parts Copyright 2002 Mike Hibbett ;;
;; mikeh@oceanfree.net ;;
;; ;;
;; See file COPYING for details ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;********************************************************************
; Interface
; ethernet_driver called by stack_handler in stack.inc
; eth_probe called by app_stack_handler in stack.inc
;
;********************************************************************
ETHER_IP equ 0x0008 ; Reversed from 0800 for intel
ETHER_ARP equ 0x0608 ; Reversed from 0806 for intel
ETHER_RARP equ 0x3580
struc ETH_FRAME
{ .DstMAC dp ? ;destination MAC-address [6 bytes]
.SrcMAC dp ? ;source MAC-address [6 bytes]
.Type dw ? ;type of the upper-layer protocol [2 bytes]
.Data db ? ;data [46-1500 bytes]
}
virtual at Ether_buffer
ETH_FRAME ETH_FRAME
end virtual
; Some useful information on data structures
; Ethernet Packet - ARP Request example
;
; 0 1 2 3
; 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
;
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; | Dest H/W Address |
; | ( 14 byte header ) |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; | | Source H/W Address |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; | Protocol - ARP 08 06 |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; | H/W Type 00 01 | Protocol Type 08 00 |
; | ( ARP Request packet ) |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; | HLen 0x06 | PLen 0x04 | OpCode 00 01 |
; | ( 0001 for request, 0002 for reply ) |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; | Source Hardware Address ( MAC Address ) |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; | | Source IP Address |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; | | Destination Hardware Address |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; | Destination IP Address |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; Include individual drivers source files at this point.
; If you create a new driver, include it below.
include "drivers/rtl8029.inc"
include "drivers/i8255x.inc"
include "drivers/rtl8139.inc"
include "drivers/3c59x.inc"
include "drivers/sis900.inc"
include "drivers/pcnet32.inc"
;include "drivers/mtd80x.inc"
include "drivers/rtl8169.inc"
; PCICards
; ========
; PCI vendor and hardware types for hardware supported by the above drivers
; If you add a driver, ensure you update this datastructure, otherwise the
; card will not be probed.
; Each driver is defined by 4 double words. These are
; PCIVendorDevice probeFunction ResetFunction PollFunction transmitFunction
; The last entry must be kept at all zeros, to indicate the end of the list
; As a PCI driver may support more than one hardware implementation, there may
; be several lines which refer to the same functions.
; The first driver found on the PCI bus will be the one used.
PCICARDS_ENTRY_SIZE equ 24 ; Size of each PCICARDS entry
iglobal
PCICards:
dd 0x12098086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit, 0
dd 0x10298086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit, 0
dd 0x12298086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit, 0
dd 0x10308086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit, 0
dd 0x24498086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit, 0
dd 0x802910ec, rtl8029_probe, rtl8029_reset, rtl8029_poll, rtl8029_transmit, 0
dd 0x12111113, rtl8029_probe, rtl8029_reset, rtl8029_poll, rtl8029_transmit, 0
dd 0x813910ec, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable
dd 0x813810ec, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable
dd 0x12111113, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable
dd 0x13601500, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable
dd 0x13604033, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable
dd 0x13001186, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable
dd 0x13401186, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable
dd 0xab0613d1, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable
dd 0xa1171259, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable
dd 0xa11e1259, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable
dd 0xab0614ea, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable
dd 0xab0714ea, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable
dd 0x123411db, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable
dd 0x91301432, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable
dd 0x101202ac, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable
dd 0x0106018a, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable
dd 0x1211126c, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable
dd 0x81391743, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable
dd 0x8139021b, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable
dd 0x816810ec, rtl8169_probe, rtl8169_reset, rtl8169_poll, rtl8169_transmit, 0
dd 0x816910ec, rtl8169_probe, rtl8169_reset, rtl8169_poll, rtl8169_transmit, 0
dd 0x011616ec, rtl8169_probe, rtl8169_reset, rtl8169_poll, rtl8169_transmit, 0
dd 0x43001186, rtl8169_probe, rtl8169_reset, rtl8169_poll, rtl8169_transmit, 0
dd 0x590010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x592010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x597010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x595010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x595110b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x595210b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x900010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x900110b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x900410b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x900510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x900610b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x900A10b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x905010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x905110b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x905510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x905810b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x905A10b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x920010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x980010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x980510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x764610b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x505510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x605510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x605610b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x5b5710b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x505710b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x515710b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x525710b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x656010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x656210b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x656410b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x450010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x09001039, SIS900_probe, SIS900_reset, SIS900_poll, SIS900_transmit, 0
dd 0x20001022, pcnet32_probe, pcnet32_reset, pcnet32_poll, pcnet32_xmit, 0
dd 0x26251022, pcnet32_probe, pcnet32_reset, pcnet32_poll, pcnet32_xmit, 0
dd 0x20011022, pcnet32_probe, pcnet32_reset, pcnet32_poll, pcnet32_xmit, 0
;dd 0x08031516, mtd80x_probe, mtd80x_reset, mtd80x_poll, mtd80x_transmit, mtd80x_cable
; following cards are untested
dd 0x70161039, SIS900_probe, SIS900_reset, SIS900_poll, SIS900_transmit, 0
;dd 0x08001516, mtd80x_probe, mtd80x_reset, mtd80x_poll, mtd80x_transmit, mtd80x_cable
;dd 0x08911516, mtd80x_probe, mtd80x_reset, mtd80x_poll, mtd80x_transmit, mtd80x_cable
rb PCICARDS_ENTRY_SIZE ; end of list marker, do not remove
endg
uglobal
;Net-stack's interface's settings
node_addr: db 0,0,0,0,0,0
gateway_ip: dd 0
dns_ip: dd 0
eth_rx_data_len: dw 0
eth_status: dd 0
io_addr: dd 0
hdrtype: db 0
vendor_device: dd 0
pci_data: dd 0
pci_dev: dd 0
pci_bus: dd 0
; These will hold pointers to the selected driver functions
drvr_probe: dd 0
drvr_reset: dd 0
drvr_poll: dd 0
drvr_transmit: dd 0
drvr_cable: dd 0
endg
iglobal
broadcast_add: db 0xff,0xff,0xff,0xff,0xff,0xff
subnet_mask: dd 0x00ffffff ; 255.255.255.0
endg
include "arp.inc" ;arp-protocol functions
include "pci.inc" ;PCI bus access functions
;***************************************************************************
; Function
; eth_tx
;
; Description
; Looks at the NET1OUT_QUEUE for data to send.
; Stores that destination IP in a location used by the tx routine
; Looks up the MAC address in the ARP table; stores that where
; the tx routine can get it
; Get the length of the data. Store that where the tx routine wants it
; Call tx
; Places buffer on empty queue when the tx routine finished
;
;***************************************************************************
proc eth_tx stdcall uses ebx esi edi
local MACAddress dp ? ;allocate 6 bytes in the stack
; Look for a buffer to tx
mov eax, NET1OUT_QUEUE
call dequeue
cmp ax, NO_BUFFER
je .exit ; Exit if no buffer available
push eax ;save buffer number
; convert buffer pointer eax to the absolute address
imul eax, IPBUFFSIZE
add eax, IPbuffs
; Extract the destination IP
; find the destination IP in the ARP table, get MAC
; store this MAC in 'MACAddress'
mov ebx, eax ; Save buffer address
mov edx, [ebx + 16] ; get destination address
; If the destination address is 255.255.255.255,
; set the MACAddress to all ones ( broadcast )
cld
mov esi, broadcast_add
lea edi, [MACAddress]
movsd
movsw
cmp edx, 0xffffffff
je .send ; If it is broadcast, just send
lea eax, [MACAddress] ;cause this is local variable
stdcall arp_table_manager, ARP_TABLE_IP_TO_MAC, edx, eax ;opcode,IP,MAC_ptr - Get the MAC address.
cmp eax, ARP_VALID_MAPPING
je .send
; No valid entry. Has the request been sent, but timed out?
cmp eax, ARP_RESPONSE_TIMEOUT
je .freebuf
.wait_response: ;we wait arp-response
; Re-queue the packet, and exit
pop ebx
mov eax, NET1OUT_QUEUE
call queue ; Get the buffer back
jmp .exit
.send: ;if ARP_VALID_MAPPING then send the packet
lea edi, [MACAddress] ; Pointer to 48 bit destination address
movzx ecx, word[ebx+2] ; Size of IP packet to send
xchg ch, cl ; because mirror byte-order
mov esi, ebx ; Pointer to packet data
mov bx, ETHER_IP ; Type of packet
call dword [drvr_transmit] ; Call the drivers transmit function
; OK, we have sent a packet, so increment the count
inc dword [ip_tx_count]
; And finally, return the buffer to the free queue
.freebuf:
pop eax
call freeBuff
.exit:
ret
endp
;***************************************************************************
; Function
; ether_IP_handler
;
; Description
; Called when an IP ethernet packet is received on the ethernet
; Header + Data is in Ether_buffer[]
; We just need to get a buffer from the 'free' queue, and
; store the packet in it, then insert the packet number into the
; IPRX queue.
; If no queue entry is available, the packet is silently discarded
; All registers may be destroyed
;
;***************************************************************************
ether_IP_handler:
mov eax, EMPTY_QUEUE
call dequeue
cmp ax, NO_BUFFER
je eiph00x
; convert buffer pointer eax to the absolute address
push eax
mov ecx, IPBUFFSIZE
mul ecx
add eax, IPbuffs
mov edi, eax
; get a pointer to the start of the DATA
mov esi, ETH_FRAME.Data
; Now store it all away
mov ecx, IPBUFFSIZE / 4 ; Copy all of the available
; data across - worse case
cld
rep movsd
; And finally, place the buffer in the IPRX queue
pop ebx
mov eax, IPIN_QUEUE
call queue
eiph00x:
ret
;***************************************************************************
; Function
; eth_probe
; Description
; Searches for an ethernet card. If found, the card is enabled and
; the ethernet -> IP link established
;
; This function scans the PCI bus looking for a supported device.
; ISA bus is currently not supported.
;
; eax is 0 if no hardware found
;***************************************************************************
eth_probe:
; Find a card on the PCI bus, and get it's address
call scan_bus ; Find the ethernet cards PIC address
xor eax, eax
cmp [io_addr], eax
je ep_00x ; Return 0 in eax if no cards found
call dword [drvr_probe] ; Call the drivers probe function
mov eax, [io_addr] ; return a non zero value
ep_00x:
ret
;***************************************************************************
; Function
; ethernet_driver
;
; Description
; The ethernet RX and TX handler
; This is a kernel function, called by stack_handler
;
;***************************************************************************
ethernet_driver:
; Do nothing if the driver is inactive
cmp [ethernet_active], byte 0
je eth_exit
call eth_rx
call eth_tx
eth_exit:
ret
;***************************************************************************
; Function
; eth_rx
;
; Description
; Polls the ethernet card for received data. Extracts if present
; Depending on the Protocol within the packet:
; ARP : Pass to ARP_handler. This may result in an ARP reply
; being tx'ed
; IP : Store in an IP buffer
;
;***************************************************************************
eth_rx:
xor ax, ax
mov [eth_rx_data_len], ax
call dword [drvr_poll] ; Call the drivers poll function
mov ax, [eth_rx_data_len]
cmp ax, 0
je .exit
; Check the protocol. Call appropriate handler
mov ax, [ETH_FRAME.Type] ; The address of the protocol word
cmp ax, ETHER_IP
je .is_ip ; It's IP
cmp ax, ETHER_ARP
je .is_arp ; It is ARP
jmp .exit ; If not IP or ARP, ignore
.is_ip:
DEBUGF 1,"K : eth_rx - IP packet\n"
inc dword [ip_rx_count]
call ether_IP_handler
jmp .exit
.is_arp:
DEBUGF 1,"K : eth_rx - ARP packet\n"
; At this point, the packet is still in the Ether_buffer
call arp_handler
.exit:
ret

View File

@ -0,0 +1,341 @@
;***************************************************************************
;
; PCI CODE FOLLOWS
;
; the following functions provide access to the PCI interface.
; These functions are used by scan_bus, and also some ethernet drivers
;
;***************************************************************************
; PCI Bus defines
PCI_HEADER_TYPE equ 0x0e ;8 bit
PCI_BASE_ADDRESS_0 equ 0x10 ;32 bit
PCI_BASE_ADDRESS_5 equ 0x24 ;32 bits
PCI_BASE_ADDRESS_SPACE_IO equ 0x01
PCI_VENDOR_ID equ 0x00 ;16 bit
PCI_BASE_ADDRESS_IO_MASK equ 0xFFFFFFFC
;***************************************************************************
; Function
; config_cmd
;
; Description
; creates a command dword for use with the PCI bus
; bus # in ebx
; devfn in ecx
; where in edx
;
; command dword returned in eax
; Only eax destroyed
;***************************************************************************
config_cmd:
push ecx
mov eax, ebx
shl eax, 16
or eax, 0x80000000
shl ecx, 8
or eax, ecx
pop ecx
or eax, edx
and eax, 0xFFFFFFFC
ret
;***************************************************************************
; Function
; pcibios_read_config_byte
;
; Description
; reads a byte from the PCI config space
; bus # in ebx
; devfn in ecx
; where in edx ( ls 16 bits significant )
;
; byte returned in al ( rest of eax zero )
; Only eax/edx destroyed
;***************************************************************************
pcibios_read_config_byte:
call config_cmd
push dx
mov dx, 0xCF8
out dx, eax
pop dx
xor eax, eax
and dx, 0x03
add dx, 0xCFC
; and dx, 0xFFC
in al, dx
ret
;***************************************************************************
; Function
; pcibios_read_config_word
;
; Description
; reads a word from the PCI config space
; bus # in ebx
; devfn in ecx
; where in edx ( ls 16 bits significant )
;
; word returned in ax ( rest of eax zero )
; Only eax/edx destroyed
;***************************************************************************
pcibios_read_config_word:
call config_cmd
push dx
mov dx, 0xCF8
out dx, eax
pop dx
xor eax, eax
and dx, 0x02
add dx, 0xCFC
; and dx, 0xFFC
in ax, dx
ret
;***************************************************************************
; Function
; pcibios_read_config_dword
;
; Description
; reads a dword from the PCI config space
; bus # in ebx
; devfn in ecx
; where in edx ( ls 16 bits significant )
;
; dword returned in eax
; Only eax/edx destroyed
;***************************************************************************
pcibios_read_config_dword:
push edx
call config_cmd
push dx
mov dx, 0xCF8
out dx, eax
pop dx
xor eax, eax
mov dx, 0xCFC
in eax, dx
pop edx
ret
;***************************************************************************
; Function
; pcibios_write_config_byte
;
; Description
; write a byte in al to the PCI config space
; bus # in ebx
; devfn in ecx
; where in edx ( ls 16 bits significant )
;
; Only eax/edx destroyed
;***************************************************************************
pcibios_write_config_byte:
push ax
call config_cmd
push dx
mov dx, 0xCF8
out dx, eax
pop dx
pop ax
and dx, 0x03
add dx, 0xCFC
out dx, al
ret
;***************************************************************************
; Function
; pcibios_write_config_word
;
; Description
; write a word in ax to the PCI config space
; bus # in ebx
; devfn in ecx
; where in edx ( ls 16 bits significant )
;
; Only eax/edx destroyed
;***************************************************************************
pcibios_write_config_word:
push ax
call config_cmd
push dx
mov dx, 0xCF8
out dx, eax
pop dx
pop ax
and dx, 0x02
add dx, 0xCFC
out dx, ax
ret
;***************************************************************************
; Function
; delay_us
;
; Description
; delays for 30 to 60 us
;
; I would prefer this routine to be able to delay for
; a selectable number of microseconds, but this works for now.
;
; If you know a better way to do 2us delay, pleae tell me!
;***************************************************************************
delay_us:
push eax
push ecx
mov ecx,2
in al,0x61
and al,0x10
mov ah,al
cld
dcnt1:
in al,0x61
and al,0x10
cmp al,ah
jz dcnt1
mov ah,al
loop dcnt1
pop ecx
pop eax
ret
;***************************************************************************
; Function
; scan_bus
;
; Description
; Scans the PCI bus for a supported device
; If a supported device is found, the drvr_ variables are initialised
; to that drivers functions ( as defined in the PCICards table)
;
; io_addr holds card I/O space. 32 bit, but only LS 16 bits valid
; pci_data holds the PCI vendor + device code
; pci_dev holds PCI bus dev #
; pci_bus holds PCI bus #
;
; io_addr will be zero if no card found
;
;***************************************************************************
scan_bus:
xor eax, eax
mov [hdrtype], al
mov [pci_data], eax
xor ebx, ebx ; ebx = bus# 0 .. 255
sb_bus_loop:
xor ecx, ecx ; ecx = devfn# 0 .. 254 ( not 255? )
sb_devf_loop:
mov eax, ecx
and eax, 0x07
cmp eax, 0
jne sb_001
mov edx, PCI_HEADER_TYPE
call pcibios_read_config_byte
mov [hdrtype], al
jmp sb_002
sb_001:
mov al, [hdrtype]
and al, 0x80
cmp al, 0x80
jne sb_inc_devf
sb_002:
mov edx, PCI_VENDOR_ID
call pcibios_read_config_dword
mov [vendor_device], eax
cmp eax, 0xffffffff
je sb_empty
cmp eax, 0
jne sb_check_vendor
sb_empty:
mov [hdrtype], byte 0
jmp sb_inc_devf
sb_check_vendor:
; iterate though PCICards until end or match found
mov esi, PCICards
sb_check:
cmp [esi], dword 0
je sb_inc_devf ; Quit if at last entry
cmp eax, [esi]
je sb_got_card
add esi, PCICARDS_ENTRY_SIZE
jmp sb_check
sb_got_card:
; indicate that we have found the card
mov [pci_data], eax
mov [pci_dev], ecx
mov [pci_bus], ebx
; Define the driver functions
push eax
mov eax, [esi+4]
mov [drvr_probe], eax
mov eax, [esi+8]
mov [drvr_reset], eax
mov eax, [esi+12]
mov [drvr_poll], eax
mov eax, [esi+16]
mov [drvr_transmit], eax
mov eax, [esi+20]
mov [drvr_cable], eax
pop eax
mov edx, PCI_BASE_ADDRESS_0
sb_reg_check:
call pcibios_read_config_dword
mov [io_addr], eax
and eax, PCI_BASE_ADDRESS_IO_MASK
cmp eax, 0
je sb_inc_reg
mov eax, [io_addr]
and eax, PCI_BASE_ADDRESS_SPACE_IO
cmp eax, 0
je sb_inc_reg
mov eax, [io_addr]
and eax, PCI_BASE_ADDRESS_IO_MASK
mov [io_addr], eax
sb_exit1:
ret
sb_inc_reg:
add edx, 4
cmp edx, PCI_BASE_ADDRESS_5
jbe sb_reg_check
sb_inc_devf:
inc ecx
cmp ecx, 255
jb sb_devf_loop
inc ebx
cmp ebx, 256
jb sb_bus_loop
; We get here if we didn't find our card
; set io_addr to 0 as an indication
xor eax, eax
mov [io_addr], eax
sb_exit2:
ret

View File

@ -0,0 +1,188 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; ICMP.INC
;;
;; Internet Control Message Protocol ( RFC 792 )
;;
;; Last revision: 11.11.2006
;;
;; This file contains the following:
;; icmp_rx - processes ICMP-packets received by the IP layer
;;
;; Changes history:
;; 22.09.2003 - [Mike Hibbett] : mikeh@oceanfree.net
;; 11.11.2006 - [Johnny_B] and [smb]
;;
;; Current status:
;; This implemetation of ICMP proto supports message of ECHO type.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
struc ICMP_PACKET
{ .Type db ? ;+00
.Code db ? ;+01
.Checksum dw ? ;+02
.Identifier dw ? ;+04
.SequenceNumber dw ? ;+06
.Data db ? ;+08
}
virtual at 0
ICMP_PACKET ICMP_PACKET
end virtual
; Example:
; ECHO message format
;
;
; 0 1 2 3
; 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; | Type | Code | Checksum |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; | Identifier | Sequence Number |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; | Data ...
; +-+-+-+-+-
;
;
; ICMP types & codes, RFC 792 and FreeBSD's ICMP sources
;
ICMP_ECHOREPLY equ 0 ; echo reply message
ICMP_UNREACH equ 3
ICMP_UNREACH_NET equ 0 ; bad net
ICMP_UNREACH_HOST equ 1 ; bad host
ICMP_UNREACH_PROTOCOL equ 2 ; bad protocol
ICMP_UNREACH_PORT equ 3 ; bad port
ICMP_UNREACH_NEEDFRAG equ 4 ; IP_DF caused drop
ICMP_UNREACH_SRCFAIL equ 5 ; src route failed
ICMP_UNREACH_NET_UNKNOWN equ 6 ; unknown net
ICMP_UNREACH_HOST_UNKNOWN equ 7 ; unknown host
ICMP_UNREACH_ISOLATED equ 8 ; src host isolated
ICMP_UNREACH_NET_PROHIB equ 9 ; prohibited access
ICMP_UNREACH_HOST_PROHIB equ 10 ; ditto
ICMP_UNREACH_TOSNET equ 11 ; bad tos for net
ICMP_UNREACH_TOSHOST equ 12 ; bad tos for host
ICMP_UNREACH_FILTER_PROHIB equ 13 ; admin prohib
ICMP_UNREACH_HOST_PRECEDENCE equ 14 ; host prec vio.
ICMP_UNREACH_PRECEDENCE_CUTOFF equ 15 ; prec cutoff
ICMP_SOURCEQUENCH equ 4 ; packet lost, slow down
ICMP_REDIRECT equ 5 ; shorter route, codes:
ICMP_REDIRECT_NET equ 0 ; for network
ICMP_REDIRECT_HOST equ 1 ; for host
ICMP_REDIRECT_TOSNET equ 2 ; for tos and net
ICMP_REDIRECT_TOSHOST equ 3 ; for tos and host
ICMP_ALTHOSTADDR equ 6 ; alternate host address
ICMP_ECHO equ 8 ; echo service
ICMP_ROUTERADVERT equ 9 ; router advertisement
ICMP_ROUTERADVERT_NORMAL equ 0 ; normal advertisement
ICMP_ROUTERADVERT_NOROUTE_COMMON equ 16 ; selective routing
ICMP_ROUTERSOLICIT equ 10 ; router solicitation
ICMP_TIMXCEED equ 11 ; time exceeded, code:
ICMP_TIMXCEED_INTRANS equ 0 ; ttl==0 in transit
ICMP_TIMXCEED_REASS equ 1 ; ttl==0 in reass
ICMP_PARAMPROB equ 12 ; ip header bad
ICMP_PARAMPROB_ERRATPTR equ 0 ; error at param ptr
ICMP_PARAMPROB_OPTABSENT equ 1 ; req. opt. absent
ICMP_PARAMPROB_LENGTH equ 2 ; bad length
ICMP_TSTAMP equ 13 ; timestamp request
ICMP_TSTAMPREPLY equ 14 ; timestamp reply
ICMP_IREQ equ 15 ; information request
ICMP_IREQREPLY equ 16 ; information reply
ICMP_MASKREQ equ 17 ; address mask request
ICMP_MASKREPLY equ 18 ; address mask reply
ICMP_TRACEROUTE equ 30 ; traceroute
ICMP_DATACONVERR equ 31 ; data conversion error
ICMP_MOBILE_REDIRECT equ 32 ; mobile host redirect
ICMP_IPV6_WHEREAREYOU equ 33 ; IPv6 where-are-you
ICMP_IPV6_IAMHERE equ 34 ; IPv6 i-am-here
ICMP_MOBILE_REGREQUEST equ 35 ; mobile registration req
ICMP_MOBILE_REGREPLY equ 36 ; mobile registreation reply
ICMP_SKIP equ 39 ; SKIP
ICMP_PHOTURIS equ 40 ; Photuris
ICMP_PHOTURIS_UNKNOWN_INDEX equ 1 ; unknown sec index
ICMP_PHOTURIS_AUTH_FAILED equ 2 ; auth failed
ICMP_PHOTURIS_DECRYPT_FAILED equ 3 ; decrypt failed
;***************************************************************************
; Function
; icmp_rx [by Johnny_B]
;
; Description
; ICMP protocol handler
; This is a kernel function, called by ip_rx
;
; IN:
; buffer_number - # of IP-buffer. This buffer must be reused or marked as empty afterwards
; IPPacketBase - IP_PACKET base address
; IPHeaderLength - Header length of IP_PACKET
;
; OUT:
; EAX=not defined
;
; All used registers will be saved
;
;***************************************************************************
proc icmp_rx stdcall uses ebx esi edi,\
buffer_number:DWORD,IPPacketBase:DWORD,IPHeaderLength:DWORD
mov esi,[IPPacketBase] ;esi=IP_PACKET base address
mov edi, esi
add edi,[IPHeaderLength] ;edi=ICMP_PACKET base address
cmp byte[edi + ICMP_PACKET.Type], ICMP_ECHO ; Is this an echo request? discard if not
jz .icmp_echo
mov eax, [buffer_number]
call freeBuff
jmp .exit
.icmp_echo:
; swap the source and destination addresses
mov ecx, [esi + IP_PACKET.DestinationAddress]
mov ebx, [esi + IP_PACKET.SourceAddress]
mov [esi + IP_PACKET.DestinationAddress], ebx
mov [esi + IP_PACKET.SourceAddress], ecx
; recalculate the IP header checksum
mov eax,[IPHeaderLength]
stdcall checksum_jb,esi,eax ;buf_ptr,buf_size
mov byte[esi + IP_PACKET.HeaderChecksum], ah
mov byte[esi + IP_PACKET.HeaderChecksum + 1], al ; ?? correct byte order?
mov byte[edi + ICMP_PACKET.Type], ICMP_ECHOREPLY ; change the request to a response
mov word[edi + ICMP_PACKET.Checksum], 0 ; clear ICMP checksum prior to re-calc
; Calculate the length of the ICMP data ( IP payload)
xor eax, eax
mov ah, byte[esi + IP_PACKET.TotalLength]
mov al, byte[esi + IP_PACKET.TotalLength + 1]
sub ax, word[IPHeaderLength] ;ax=ICMP-packet length
stdcall checksum_jb,edi,eax ;buf_ptr,buf_size
mov byte[edi + ICMP_PACKET.Checksum], ah
mov byte[edi + ICMP_PACKET.Checksum + 1], al
; Queue packet for transmission
mov ebx, [buffer_number]
mov eax, NET1OUT_QUEUE
call queue
.exit:
ret
endp

View File

@ -0,0 +1,197 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; IP.INC ;;
;; ;;
;; IP Processes for Menuet OS TCP/IP stack ;;
;; ;;
;; Version 0.3 29 August 2002 ;;
;; ;;
;; Copyright 2002 Mike Hibbett, mikeh@oceanfree.net ;;
;; ;;
;; See file COPYING for details ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; IP underlying protocols numbers
PROTOCOL_ICMP equ 1
PROTOCOL_TCP equ 6
PROTOCOL_UDP equ 17
struc IP_PACKET
{ .VersionAndIHL db ? ;+00 - Version[0-3 bits] and IHL(header length)[4-7 bits]
.TypeOfService db ? ;+01
.TotalLength dw ? ;+02
.Identification dw ? ;+04
.FlagsAndFragmentOffset dw ? ;+06 - Flags[0-2] and FragmentOffset[3-15]
.TimeToLive db ? ;+08
.Protocol db ? ;+09
.HeaderChecksum dw ? ;+10
.SourceAddress dd ? ;+12
.DestinationAddress dd ? ;+16
.DataOrOptional dd ? ;+20
}
virtual at 0
IP_PACKET IP_PACKET
end virtual
;*******************************************************************
; Interface
;
; ip_rx processes all packets received by the network layer
; It calls the appropriate protocol handler
;
;
;
;*******************************************************************
;
; IP Packet after reception - Normal IP packet format
;
; 0 1 2 3
; 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
;
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
;0 |Version| IHL |Type of Service| Total Length |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
;4 | Identification |Flags| Fragment Offset |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
;8 | Time to Live | Protocol | Header Checksum |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
;12 | Source Address |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
;16 | Destination Address |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
;20 | Data |
; +-+-+-.......... -+
;
;
; [smb] attention! according to RFC 791 IP packet may have 'options' sections,
; so we can't simply think, that data have offset 20. We must calculate offset from
; IHL field
;
macro GET_IHL reg, header_addr
{
movzx reg, byte [header_addr]
; we need 4-7 bits, so....
and reg, 0x0000000F
; IHL keeps number of octets, so we need to << 2 'reg'
shl reg, 2
}
;***************************************************************************
; Function
; ip_rx
;
; Description
; This is a kernel function, called by stack_handler
; Processes all IP-packets received by the network layer
; It calls the appropriate protocol handler
;
;***************************************************************************
proc ip_rx stdcall
local buffer_number dd ?
; Look for a buffer to tx
mov eax, IPIN_QUEUE
call dequeue
cmp ax, NO_BUFFER
je .exit ; Exit if no buffer available
mov [buffer_number], eax ;save buffer number
; convert buffer pointer eax to the absolute address
imul eax, IPBUFFSIZE
add eax, IPbuffs
mov ebx, eax ; ebx=pointer to IP_PACKET
; Validate the IP checksum
mov dx, word[ebx + IP_PACKET.HeaderChecksum]
xchg dh,dl ; Get the checksum in intel format
mov [ebx + IP_PACKET.HeaderChecksum], word 0 ; clear checksum field - need to when
; recalculating checksum
; this needs two data pointers and two size #.
; 2nd pointer can be of length 0
GET_IHL ecx, ebx + IP_PACKET.VersionAndIHL ;get packet length in ecx
stdcall checksum_jb, ebx, ecx ;buf_ptr, buf_size
cmp dx, ax
mov edx, ebx ; EDX (IP-BUFFER POINTER) WILL BE USED FOR *_rx HANDLERS BELOW!!!
jnz .dump ;if CHECKSUM isn't valid then dump packet
; Validate the IP address, if it isn't broadcast
mov eax, [stack_ip]
cmp dword[ebx + IP_PACKET.DestinationAddress], eax
je @f
; If the IP address is 255.255.255.255, accept it
; - it is a broadcast packet, which we need for dhcp
cmp dword[ebx + IP_PACKET.DestinationAddress], 0xffffffff
jne .dump
@@:
mov al, [ebx + IP_PACKET.VersionAndIHL]
and al, 0x0f ;get IHL(header length)
cmp al, 0x05 ;if IHL!= 5*4(20 bytes)
jnz .dump ;then dump it
cmp byte[ebx + IP_PACKET.TimeToLive], byte 0
je .dump ;if TTL==0 then dump it
mov ax, word[ebx + IP_PACKET.FlagsAndFragmentOffset]
and ax, 0xFFBF ;get flags
cmp ax, 0 ;if some flags was set then we dump this packet
jnz .dump ;the flags should be used for fragmented packets
; Check the protocol, and call the appropriate handler
; Each handler will re-use or free the queue buffer as appropriate
mov al, [ebx + IP_PACKET.Protocol]
cmp al , PROTOCOL_TCP
jne .not_tcp
DEBUGF 1,"K : ip_rx - TCP packet\n"
mov eax, dword[buffer_number]
call tcp_rx
jmp .exit
.not_tcp:
cmp al, PROTOCOL_UDP
jne .not_udp
DEBUGF 1,"K : ip_rx - UDP packet\n"
mov eax, dword[buffer_number]
call udp_rx
jmp .exit
.not_udp:
cmp al , PROTOCOL_ICMP
jne .dump ;protocol ain't supported
DEBUGF 1,"K : ip_rx - ICMP packet\n"
;GET_IHL ecx, ebx + IP_PACKET.VersionAndIHL ;get packet length in ecx
mov eax, dword[buffer_number]
stdcall icmp_rx,eax,ebx,ecx ;buffer_number,IPPacketBase,IPHeaderLength
jmp .exit
.dump:
; No protocol handler available, so
; silently dump the packet, freeing up the queue buffer
inc dword [dumped_rx_count]
mov eax, dword[buffer_number]
call freeBuff
.exit:
ret
endp

View File

@ -0,0 +1,214 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; QUEUE.INC ;;
;; ;;
;; Buffer queue management for Menuet OS TCP/IP Stack ;;
;; ;;
;; Version 0.3 29 August 2002 ;;
;; ;;
;; Copyright 2002 Mike Hibbett, mikeh@oceanfree.net ;;
;; ;;
;; See file COPYING for details ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;*******************************************************************
; Interface
;
; queueInit Configures the queues to empty
; dequeue Removes a buffer pointer from a queue
; queue Inserts a buffer pointer into a queue
; freeBuff Adds the buffer pointer to the list of free buffers
; queueSize Returns the number of entries in a queue
;
; The various defines for queue names can be found in stack.inc
;
;*******************************************************************
;***************************************************************************
; Function
; freeBuff
;
; Description
; Adds a buffer number to the beginning of the free list.
; buffer number in eax ( ms word zeroed )
; all other registers preserved
; This always works, so no error returned
;***************************************************************************
freeBuff:
push ebx
push ecx
mov ebx, EMPTY_QUEUE
shl ebx, 1
add ebx, queues
cli ; Ensure that another process does not interfer
movzx ecx, word [ebx]
mov [ebx], ax
shl eax, 1
add eax, queueList
mov [eax], cx
sti
pop ecx
pop ebx
ret
;***************************************************************************
; Function
; queueSize
;
; Description
; Counts the number of entries in a queue
; queue number in ebx ( ms word zeroed )
; Queue size returned in eax
; This always works, so no error returned
;***************************************************************************
queueSize:
xor eax, eax
shl ebx, 1
add ebx, queues
movzx ecx, word [ebx]
cmp cx, NO_BUFFER
je qs_exit
qs_001:
inc eax
shl ecx, 1
add ecx, queueList
movzx ecx, word [ecx]
cmp cx, NO_BUFFER
je qs_exit
jmp qs_001
qs_exit:
ret
;***************************************************************************
; Function
; queue
;
; Description
; Adds a buffer number to the *end* of a queue
; This is quite quick because these queues will be short
; queue number in eax ( ms word zeroed )
; buffer number in ebx ( ms word zeroed )
; all other registers preserved
; This always works, so no error returned
;***************************************************************************
queue:
push ebx
shl ebx, 1
add ebx, queueList ; eax now holds address of queue entry
mov [ebx], word NO_BUFFER ; This buffer will be the last
cli
shl eax, 1
add eax, queues ; eax now holds address of queue
movzx ebx, word [eax]
cmp bx, NO_BUFFER
jne qu_001
pop ebx
; The list is empty, so add this to the head
mov [eax], bx
jmp qu_exit
qu_001:
; Find the last entry
shl ebx, 1
add ebx, queueList
mov eax, ebx
movzx ebx, word [ebx]
cmp bx, NO_BUFFER
jne qu_001
mov ebx, eax
pop eax
mov [ebx], ax
qu_exit:
sti
ret
;***************************************************************************
; Function
; dequeue
;
; Description
; removes a buffer number from the head of a queue
; This is fast, as it unlinks the first entry in the list
; queue number in eax ( ms word zeroed )
; buffer number returned in eax ( ms word zeroed )
; all other registers preserved
;
;***************************************************************************
dequeue:
push ebx
shl eax, 1
add eax, queues ; eax now holds address of queue
mov ebx, eax
cli
movzx eax, word [eax]
cmp ax, NO_BUFFER
je dq_exit
push eax
shl eax, 1
add eax, queueList ; eax now holds address of queue entry
mov ax, [eax]
mov [ebx], ax
pop eax
dq_exit:
sti
pop ebx
ret
;***************************************************************************
; Function
; queueInit
;
; Description
; Initialises the queues to empty, and creates the free queue
; list.
;
;***************************************************************************
queueInit:
mov esi, queues
mov ecx, NUMQUEUES
mov ax, NO_BUFFER
qi001:
mov [esi], ax
inc esi
inc esi
loop qi001
mov esi, queues + ( 2 * EMPTY_QUEUE )
; Initialise empty queue list
xor ax, ax
mov [esi], ax
mov ecx, NUMQUEUEENTRIES - 1
mov esi, queueList
qi002:
inc ax
mov [esi], ax
inc esi
inc esi
loop qi002
mov ax, NO_BUFFER
mov [esi], ax
ret

View File

@ -0,0 +1,926 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; SOCKET.INC
;;
;; Sockets constants, structures and functions
;;
;; Last revision: 11.11.2006
;;
;; This file contains the following:
;; is_localport_unused
;; get_free_socket
;; socket_open
;; socket_open_tcp
;; socket_close
;; socket_close_tcp
;; socket_poll
;; socket_status
;; socket_read
;; socket_write
;; socket_write_tcp
;;
;;
;; Changes history:
;; 22.09.2003 - [Mike Hibbett] : mikeh@oceanfree.net
;; 11.11.2006 - [Johnny_B] and [smb]
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Socket Descriptor + Buffer
;
; 0 1 2 3
; 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
;
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; 0| Status ( of this buffer ) |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; 4| Application Process ID |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; 8| Local IP Address |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; 12| Local IP Port | Unused ( set to 0 ) |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; 16| Remote IP Address |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; 20| Remote IP Port | Unused ( set to 0 ) |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; 24| Rx Data Count INTEL format|
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; 28| TCB STATE INTEL format|
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; 32| TCB Timer (seconds) INTEL format|
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; 36| ISS (Inital Sequence # used by this connection ) INET format|
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; 40| IRS ( Inital Receive Sequence # ) INET format|
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; 44| SND.UNA Seq # of unack'ed sent packets INET format|
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; 48| SND.NXT Next send seq # to use INET format|
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; 52| SND.WND Send window INET format|
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; 56| RCV.NXT Next expected receive sequence # INET format|
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; 60| RCV.WND Receive window INET format|
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; 64| SEG.LEN Segment length INTEL format|
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; 68| SEG.WND Segment window INTEL format|
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; 72| Retransmit queue # NOW WINDOW SIZE TIMER INTEL format|
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; 76| RX offset from
; 76| RX Data |
; +-+-+-.......... -+
; so, define struct
struc SOCKET
{ .Status dd ? ;+00 - Status ( of this buffer )
.PID dd ? ;+04 - Application Process ID
.LocalIP dd ? ;+08 - Local IP Address
.LocalPort dw ? ;+12 - Local Port
.UnusedL dw ? ;+14 - may be removed in future
.RemoteIP dd ? ;+16 - Remote IP Address
.RemotePort dw ? ;+20 - Remote Port
.UnusedR dw ? ;+22 - may be removed in future
.rxDataCount dd ? ;+24 - Rx Data Count
.TCBState dd ? ;+28 - TCB STATE
.TCBTimer dd ? ;+32 - TCB Timer (seconds)
.ISS dd ? ;+36 - Initial Send Sequence
.IRS dd ? ;+40 - Initial Receive Sequence
.SND_UNA dd ? ;+44 - Sequence number of unack'ed sent packets
.SND_NXT dd ? ;+48 - Next send sequence number to use
.SND_WND dd ? ;+52 - Send window
.RCV_NXT dd ? ;+56 - Next receive sequence number to use
.RCV_WND dd ? ;+60 - Receive window
.SEG_LEN dd ? ;+64 - Segment length
.SEG_WND dd ? ;+68 - Segment window
.wndsizeTimer dd ? ;+72 - Retransmit queue # NOW WINDOW SIZE TIMER
.rxData dd ? ;+76 - receive data buffer here
}
virtual at 0
SOCKET SOCKET
end virtual
; simple macro calcing real memory address of SOCKET struct by socket's
macro Index2RealAddr reg
{
shl reg, 12
add reg, sockets
}
;Constants
; current socket statuses
SOCK_EMPTY equ 0 ; socket not in use
SOCK_OPEN equ 1 ; open issued, but no data sent
; TCP opening modes
SOCKET_PASSIVE equ 0
SOCKET_ACTIVE equ 1
;***************************************************************************
; Function
; is_localport_unused
;
; Description
; scans through all the active sockets , looking to see if the
; port number specified in bx is in use as a localport number.
; This is useful when you want a to generate a unique local port
; number.
; On return, eax = 1 for free, 0 for in use
;
;***************************************************************************
is_localport_unused:
mov al, bh
mov ah, bl
mov bx, ax
mov edx, SOCKETBUFFSIZE * NUM_SOCKETS
mov ecx, NUM_SOCKETS
mov eax, 0 ; Assume the return value is 'in use'
ilu1:
sub edx, SOCKETBUFFSIZE
cmp [edx + sockets + SOCKET.LocalPort], bx
loopnz ilu1 ; Return back if the socket is occupied
jz ilu_exit
inc eax ; return port not in use
ilu_exit:
ret
;***************************************************************************
; Function
; get_free_socket
;
; Description
;
;***************************************************************************
get_free_socket:
push ecx
mov eax, SOCKETBUFFSIZE * NUM_SOCKETS
mov ecx, NUM_SOCKETS
gfs1:
sub eax, SOCKETBUFFSIZE
cmp [eax + sockets + SOCKET.Status], dword SOCK_EMPTY
loopnz gfs1 ; Return back if the socket is occupied
mov eax, ecx
pop ecx
jz gfs_exit
mov eax, 0xFFFFFFFF
gfs_exit:
ret
;***************************************************************************
; Function
; socket_open
;
; Description
; find a free socket
; local port in ebx
; remote port in ecx
; remote ip in edx
; return socket # in eax, -1 if none available
;
;***************************************************************************
socket_open:
call get_free_socket
cmp eax, 0xFFFFFFFF
jz so_exit
; ax holds the socket number that is free. Get real address
push eax
Index2RealAddr eax
mov [eax + SOCKET.Status], dword SOCK_OPEN
xchg bh, bl
mov [eax + SOCKET.LocalPort], bx
xchg ch, cl
mov [eax + SOCKET.RemotePort], cx
mov ebx, [stack_ip]
mov [eax + SOCKET.LocalIP], ebx
mov [eax + SOCKET.RemoteIP], edx
mov [eax + SOCKET.rxDataCount], dword 0 ; recieved data count
mov esi, [TASK_BASE]
mov ebx, [esi+TASKDATA.pid]
mov [eax + SOCKET.PID], ebx ; save the process ID
pop eax ; Get the socket number back, so we can return it
so_exit:
ret
;***************************************************************************
; Function
; socket_open_tcp
;
; Description
; Opens a TCP socket in PASSIVE or ACTIVE mode
; find a free socket
; local port in ebx ( intel format )
; remote port in ecx ( intel format )
; remote ip in edx ( in Internet byte order )
; Socket open mode in esi ( SOCKET_PASSIVE or SOCKET_ACTIVE )
; return socket # in eax, -1 if none available
;
;***************************************************************************
socket_open_tcp:
call get_free_socket
cmp eax, 0xFFFFFFFF
jz so_exit
; ax holds the socket number that is free. Get real address
push eax
Index2RealAddr eax
mov [sktAddr], eax
mov [eax], dword SOCK_OPEN
; TODO - check this works!
mov [eax + SOCKET.wndsizeTimer], dword 0 ; Reset the window timer.
xchg bh, bl
mov [eax + SOCKET.LocalPort], bx
; mov [eax + 12], byte bh ; Local port ( LS 16 bits )
; mov [eax + 13], byte bl ; Local port ( LS 16 bits )
xchg ch, cl
mov [eax + SOCKET.RemotePort], cx
; mov [eax + 20], ch ; Remote Port ( LS 16 bits )
; mov [eax + 21], cl ; Remote Port ( LS 16 bits )
mov ebx, [stack_ip]
mov [eax + SOCKET.LocalIP], ebx
mov [eax + SOCKET.RemoteIP], edx
mov [eax + SOCKET.rxDataCount], dword 0
; Now fill in TCB state
mov ebx, TCB_LISTEN
cmp esi, SOCKET_PASSIVE
jz sot_001
mov ebx, TCB_SYN_SENT
sot_001:
mov [eax + SOCKET.TCBState], ebx ; Indicate the state of the TCB
mov esi, [TASK_BASE]
mov ecx, [esi+TASKDATA.pid]
mov [eax + SOCKET.PID], ecx ; save the process ID
cmp ebx, TCB_LISTEN
je sot_done
; Now, if we are in active mode, then we have to send a SYN to the specified remote port
mov eax, EMPTY_QUEUE
call dequeue
cmp ax, NO_BUFFER
je sot_done
push eax
mov bl, 0x02 ; SYN
mov ecx, 0
call buildTCPPacket
mov eax, NET1OUT_QUEUE
mov edx, [stack_ip]
mov ecx, [sktAddr ]
mov ecx, [ecx + 16]
cmp edx, ecx
jne sot_notlocal
mov eax, IPIN_QUEUE
sot_notlocal:
; Send it.
pop ebx
call queue
mov esi, [sktAddr]
; increment SND.NXT in socket
add esi, 48
call inc_inet_esi
sot_done:
pop eax ; Get the socket number back, so we can return it
sot_exit:
ret
;***************************************************************************
; Function
; socket_close
;
; Description
; socket # in ebx
; returns 0 for ok, -1 for socket not open (fail)
;
;***************************************************************************
socket_close:
Index2RealAddr ebx
mov eax, 0xFFFFFFFF ; assume this operation will fail..
cmp [ebx + SOCKET.Status], dword SOCK_EMPTY
jz sc_exit
; Clear the socket varaibles
xor eax, eax
mov edi, ebx
mov ecx, SOCKETHEADERSIZE
cld
rep stosb
sc_exit:
ret
;***************************************************************************
; Function
; socket_close_tcp
;
; Description
; socket # in ebx
; returns 0 for ok, -1 for socket not open (fail)
;
;***************************************************************************
socket_close_tcp:
; first, remove any resend entries
pusha
mov esi, resendQ
mov ecx, 0
sct001:
cmp ecx, NUMRESENDENTRIES
je sct003 ; None left
cmp [esi], bl
je sct002 ; found one
inc ecx
add esi, 4
jmp sct001
sct002:
mov [esi], byte 0xFF
jmp sct001
sct003:
popa
Index2RealAddr ebx
mov [sktAddr], ebx
mov eax, 0xFFFFFFFF ; assume this operation will fail..
cmp [ebx + SOCKET.Status], dword SOCK_EMPTY
jz sct_exit
; Now construct the response, and queue for sending by IP
mov eax, EMPTY_QUEUE
call dequeue
cmp ax, NO_BUFFER
je stl_exit
push eax
mov bl, 0x11 ; FIN + ACK
mov ecx, 0
mov esi, 0
call buildTCPPacket
mov ebx, [sktAddr]
; increament SND.NXT in socket
mov esi, 48
add esi, ebx
call inc_inet_esi
; Get the socket state
mov eax, [ebx + SOCKET.TCBState]
cmp eax, TCB_LISTEN
je destroyTCB
cmp eax, TCB_SYN_SENT
je destroyTCB
cmp eax, TCB_SYN_RECEIVED
je sct_finwait1
cmp eax, TCB_ESTABLISHED
je sct_finwait1
; assume CLOSE WAIT
; Send a fin, then enter last-ack state
mov eax, TCB_LAST_ACK
mov [ebx + SOCKET.TCBState], eax
xor eax, eax
jmp sct_send
sct_finwait1:
; Send a fin, then enter finwait2 state
mov eax, TCB_FIN_WAIT_1
mov [ebx + SOCKET.TCBState], eax
xor eax, eax
sct_send:
mov eax, NET1OUT_QUEUE
mov edx, [stack_ip]
mov ecx, [sktAddr ]
mov ecx, [ecx + 16]
cmp edx, ecx
jne sct_notlocal
mov eax, IPIN_QUEUE
sct_notlocal:
; Send it.
pop ebx
call queue
jmp sct_exit
destroyTCB:
pop eax
; Clear the socket varaibles
xor eax, eax
mov edi, ebx
mov ecx, SOCKETHEADERSIZE
cld
rep stosb
sct_exit:
ret
;***************************************************************************
; Function
; socket_poll
;
; Description
; socket # in ebx
; returns count in eax.
;
;***************************************************************************
socket_poll:
Index2RealAddr ebx
mov eax, [ebx + SOCKET.rxDataCount]
ret
;***************************************************************************
; Function
; socket_status
;
; Description
; socket # in ebx
; returns TCB state in eax.
;
;***************************************************************************
socket_status:
Index2RealAddr ebx
mov eax, [ebx + SOCKET.TCBState]
ret
;***************************************************************************
; Function
; socket_read
;
; Description
; socket # in ebx
; returns # of bytes remaining in eax, data in bl
;
;***************************************************************************
socket_read:
Index2RealAddr ebx
mov eax, [ebx + SOCKET.rxDataCount] ; get count of bytes
mov ecx, 1
test eax, eax
jz sr2
dec eax
mov esi, ebx ; esi is address of socket
mov [ebx + SOCKET.rxDataCount], eax ; store new count
;movzx ebx, byte [ebx + SOCKET.rxData] ; get the byte
movzx ebx, byte [ebx + SOCKETHEADERSIZE] ; get the byte
add esi, SOCKETHEADERSIZE
mov edi, esi
inc esi
mov ecx, (SOCKETBUFFSIZE - SOCKETHEADERSIZE) / 4
cld
rep movsd
xor ecx, ecx
sr1:
jmp sor_exit
sr2:
xor bl, bl
sor_exit:
ret
;***************************************************************************
; Function
; socket_read_packet
;
; Description
; socket # in ebx
; datapointer # in ecx
; buffer size in edx
; returns # of bytes copied in eax
;
;***************************************************************************
socket_read_packet:
Index2RealAddr ebx ; get real socket address
mov eax, [ebx + SOCKET.rxDataCount] ; get count of bytes
test eax, eax ; if count of bytes is zero..
jz .exit ; exit function (eax will be zero)
test edx, edx ; if buffer size is zero, copy all data
jz .copyallbytes
cmp edx, eax ; if buffer size is larger then the bytes of data, copy all data
jge .copyallbytes
sub eax, edx ; store new count (data bytes in buffer - bytes we're about to copy)
mov [ebx + SOCKET.rxDataCount], eax ;
push eax
mov eax, edx ; number of bytes we want to copy must be in eax
call .startcopy ; copy to the application
mov esi, ebx ; now we're going to copy the remaining bytes to the beginning
add esi, SOCKETHEADERSIZE ; we dont need to copy the header
mov edi, esi ; edi is where we're going to copy to
add esi, edx ; esi is from where we copy
pop ecx ; count of bytes we have left
push ecx ; push it again so we can re-use it later
shr ecx, 2 ; divide eax by 4
cld
rep movsd ; copy all full dwords
pop ecx
and ecx, 3
rep movsb ; copy remaining bytes
ret ; at last, exit
.copyallbytes:
xor esi, esi
mov [ebx + SOCKET.rxDataCount], esi ; store new count (zero)
.startcopy:
mov edi, ecx ;
add edi, std_application_base_address ; get data pointer to buffer in application
mov esi, ebx ;
add esi, SOCKETHEADERSIZE ; we dont need to copy the header
mov ecx, eax ; eax is count of bytes
push ecx
shr ecx, 2 ; divide eax by 4
cld ; copy all full dwords
rep movsd ;
pop ecx
and ecx, 3
rep movsb ; copy the rest bytes
.exit:
ret ; exit, or go back to shift remaining bytes if any
;***************************************************************************
; Function
; socket_write
;
; Description
; socket in ebx
; # of bytes to write in ecx
; pointer to data in edx
; returns 0 in eax ok, -1 == failed ( invalid socket, or
; could not queue IP packet )
;
;***************************************************************************
socket_write:
Index2RealAddr ebx
mov eax, 0xFFFFFFFF
; If the socket is invalid, return with an error code
cmp [ebx], dword SOCK_EMPTY
je sw_exit
mov eax, EMPTY_QUEUE
call dequeue
cmp ax, NO_BUFFER
je sw_exit
; Save the queue entry number
push eax
; save the pointers to the data buffer & size
push edx
push ecx
; convert buffer pointer eax to the absolute address
mov ecx, IPBUFFSIZE
mul ecx
add eax, IPbuffs
mov edx, eax
; So, ebx holds the socket ptr, edx holds the IPbuffer ptr
; Fill in the IP header ( some data is in the socket descriptor)
mov eax, [ebx + 8]
mov [edx + 12], eax ; source IP
mov eax, [ebx + 16]
mov [edx + 16], eax ; Destination IP
mov al, 0x45
mov [edx], al ; Version, IHL
xor al, al
mov [edx + 1], al ; Type of service
pop eax ; Get the UDP data length
push eax
add eax, 20 + 8 ; add IP header and UDP header lengths
mov [edx + 2], ah
mov [edx + 3], al
xor al, al
mov [edx + 4], al
mov [edx + 5], al
mov al, 0x40
mov [edx + 6], al
xor al, al
mov [edx + 7], al
mov al, 0x20
mov [edx + 8], al
mov al, 17
mov [edx + 9], al
; Checksum left unfilled
xor ax, ax
mov [edx + 10], ax
; Fill in the UDP header ( some data is in the socket descriptor)
mov ax, [ebx + 12]
mov [edx + 20], ax
mov ax, [ebx + 20]
mov [edx + 20 + 2], ax
pop eax
push eax
add eax, 8
mov [edx + 20 + 4], ah
mov [edx + 20 + 5], al
; Checksum left unfilled
xor ax, ax
mov [edx + 20 + 6], ax
pop ecx ; count of bytes to send
mov ebx, ecx ; need the length later
pop eax ; get callers ptr to data to send
; Get the address of the callers data
mov edi, [TASK_BASE]
add edi, TASKDATA.mem_start
add eax, [edi]
mov esi, eax
mov edi, edx
add edi, 28
cld
rep movsb ; copy the data across
; we have edx as IPbuffer ptr.
; Fill in the UDP checksum
; First, fill in pseudoheader
mov eax, [edx + 12]
mov [pseudoHeader], eax
mov eax, [edx + 16]
mov [pseudoHeader+4], eax
mov ax, 0x1100 ; 0 + protocol
mov [pseudoHeader+8], ax
add ebx, 8
mov eax, ebx
mov [pseudoHeader+10], ah
mov [pseudoHeader+11], al
mov eax, pseudoHeader
mov [checkAdd1], eax
mov [checkSize1], word 12
mov eax, edx
add eax, 20
mov [checkAdd2], eax
mov eax, ebx
mov [checkSize2], ax ; was eax!! mjh 8/7/02
call checksum
; store it in the UDP checksum ( in the correct order! )
mov ax, [checkResult]
; If the UDP checksum computes to 0, we must make it 0xffff
; (0 is reserved for 'not used')
cmp ax, 0
jne sw_001
mov ax, 0xffff
sw_001:
mov [edx + 20 + 6], ah
mov [edx + 20 + 7], al
; Fill in the IP header checksum
GET_IHL ecx,edx ; get IP-Header length
stdcall checksum_jb,edx,ecx ; buf_ptr, buf_size
mov [edx + 10], ah
mov [edx + 11], al
; Check destination IP address.
; If it is the local host IP, route it back to IP_RX
pop ebx
mov eax, NET1OUT_QUEUE
mov ecx, [ edx + 16]
mov edx, [stack_ip]
cmp edx, ecx
jne sw_notlocal
mov eax, IPIN_QUEUE
sw_notlocal:
; Send it.
call queue
xor eax, eax
sw_exit:
ret
;***************************************************************************
; Function
; socket_write_tcp
;
; Description
; socket in ebx
; # of bytes to write in ecx
; pointer to data in edx
; returns 0 in eax ok, -1 == failed ( invalid socket, or
; could not queue IP packet )
;
;***************************************************************************
socket_write_tcp:
Index2RealAddr ebx
mov [sktAddr], ebx
mov eax, 0xFFFFFFFF
; If the socket is invalid, return with an error code
cmp [ebx], dword SOCK_EMPTY
je swt_exit
; If the sockets window timer is nonzero, do not queue packet
; TODO - done
cmp [ebx + SOCKET.wndsizeTimer], dword 0
jne swt_exit
mov eax, EMPTY_QUEUE
call dequeue
cmp ax, NO_BUFFER
je swt_exit
push eax
mov bl, 0x10 ; ACK
; Get the address of the callers data
mov edi, [TASK_BASE]
add edi, TASKDATA.mem_start
add edx, [edi]
mov esi, edx
pop eax
push eax
push ecx
call buildTCPPacket
pop ecx
; Check destination IP address.
; If it is the local host IP, route it back to IP_RX
pop ebx
push ecx
mov eax, NET1OUT_QUEUE
mov edx, [stack_ip]
mov ecx, [sktAddr ]
mov ecx, [ecx + 16]
cmp edx, ecx
jne swt_notlocal
mov eax, IPIN_QUEUE
swt_notlocal:
pop ecx
push ebx ; save ipbuffer number
call queue
mov esi, [sktAddr]
; increament SND.NXT in socket
; Amount to increment by is in ecx
add esi, 48
call add_inet_esi
pop ebx
; Copy the IP buffer to a resend queue
; If there isn't one, dont worry about it for now
mov esi, resendQ
mov ecx, 0
swt003:
cmp ecx, NUMRESENDENTRIES
je swt001 ; None found
cmp [esi], byte 0xFF
je swt002 ; found one
inc ecx
add esi, 4
jmp swt003
swt002:
push ebx
; OK, we have a buffer descriptor ptr in esi.
; resend entry # in ecx
; Populate it
; socket #
; retries count
; retry time
; fill IP buffer associated with this descriptor
mov eax, [sktAddr]
sub eax, sockets
shr eax, 12 ; get skt #
mov [esi], al
mov [esi + 1], byte TCP_RETRIES
mov [esi + 2], word TCP_TIMEOUT
inc ecx
; Now get buffer location, and copy buffer across. argh! more copying,,
mov edi, resendBuffer - IPBUFFSIZE
swt002a:
add edi, IPBUFFSIZE
loop swt002a
; we have dest buffer location in edi
pop eax
; convert source buffer pointer eax to the absolute address
mov ecx, IPBUFFSIZE
mul ecx
add eax, IPbuffs
mov esi, eax
; do copy
mov ecx, IPBUFFSIZE
cld
rep movsb
swt001:
xor eax, eax
swt_exit:
ret

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More