; =============================================================================
;
; Litos - Start kernel, protected mode
;
; =============================================================================
%ifdef DEBUG
;%define DEBUG_TIME ; uncomment this to display date+time
%define DEBUG_INS ; uncomment this to display instruct.
; (it can be combined with DEBUG_CPU)
;%define DEBUG_TASK ; uncomment this to test tasks
;%define DEBUG_ALARM ; uncomment this to test alarm
;%define DEBUG_RBTREE ; uncomment this to test Red-black tree
;%define DEBUG_DRVLIST ; display list of drivers
;%define DEBUG_ASCII ; display test
;%define DEBUG_ASCII2 ; display test
;%define DEBUG_ANSI ; display ansi test
%endif
CODE_SECTION 32
; -----------------------------------------------------------------------------
; Start kernel (jump here from INIT\INIT_32.ASM)
; -----------------------------------------------------------------------------
; ------------- Initialize memory page map
StartKernel: call PageMapInit ; initialize memory page map
; ------------- Initialize system memory allocator
call SysMemInit ; initialize system memory allocator
; ------------- Initialize alarm list
call AlarmListInit ; initialize alarm list
; ------------- Initialize TSS list
call InitTSS ; initialize TSS list
; ------------- Initialize swap area tables
call SwapCacheInit ; initialize swap area tables
; ------------- Initialize scheduler
call SchedInit ; initialize scheduler
; ------------- Initialize idle task for this CPU
xor edx,edx ; EDX <- 0, index of this CPU
call IdleInit ; initialize idle task
call ProcRootLink ; link task to root process
lea esp,[ebx+TASK_Stack] ; initialize stack address
mov [ebx+TASK_ESP],esp ; stack
ltr [ebx+TASK_TR] ; load task register
lldt [ebx+TASK_LDT] ; load LST selector
; ------------- Initialize traps
call TrapInit ; initialize traps
; ------------- Initialize IRQ
call IRQInit ; initialize IRQ
; ------------- Initialize system timer
call TimerInit ; initialize system timer
; ------------- Initialize console interfaces
call ConInit ; initialize console interfaces
; ------------- Initialize CPU
; call CPUInit
; ------------- Read time from CMOS real-time clock (synchronize aprox. 2 sec)
call GetCMOSTime ; get CMOS time
xchg eax,ebx ; EBX <- store CMOS time LOW
mov ecx,30000 ; time-out aprox. 2 seconds
SynchroTime: call GetCMOSTime ; get next CMOS time
cmp eax,ebx ; time changed?
jne SynchroTime2 ; wait for 1-second edge
loop SynchroTime ; next read
SynchroTime2: add eax,[CMOSTimeOff] ; add CMOS time offset LOW
add edx,[CMOSTimeOff+4] ; add CMOD time offset HIGH
call SetCurrentTime ; set current time
; ------------- Recalculate performance coefficients
call PerfCoefRecalc ; recalculate performance coefficients
; ------------- Reinitialize alarm list start time
call AlarmReInit ; reinitialize alarm list start time
; ------------- Initialize character mapping
call CharTabInit ; initialize character mapping
; ------------- Initialize standard system drivers and resources
call DrvStdInit ; initialize system drivers
; ------------- Initialize display driver
call VGAInit ; initialite display driver
; ------------- Initialize keyboard driver
call KeybInit ; initialize keyboard driver
; ------------- Initialize VT102 terminal emulator
call VTInit ; initialize VT102 terminal emulator
; ------------- Check EISA bus
; mov esi,0fffd9h ; ESI <- bus identification
; cmp dword [esi],"EISA" ; is EISA bus?
; jne StartKernel2 ; it is not EISA
; cmp byte [esi+4],0 ; ASCIIT terminator
; jne StartKernel2 ; it is not EISA
; inc byte [IsEISA] ; set EISA flag
; ------------- Check PCI/ISA bus
;StartKernel2: cmp dword [esi],"PCI/" ; is PCI/ISA bus?
; jne StartKernel3 ; it is not EISA
; cmp dword [esi+4],"ISA" ; is PCI/ISA bus?
; jne StartKernel3 ; it is not EISA
; inc byte [IsPCIISA] ; set PCI/ISA flag
; ------------- Debug display instruction statistics
%ifdef DEBUG_INS
call DebDispIns ; dispaly instructions
%endif
; ------------- Debug test red-black tree
%ifdef DEBUG_RBTREE
call TestRBTree ; test red-black tree
%endif
; ------------- Enable interrupts
sti
%ifdef DEBUG_ANSI
mov edi,SYSTEM_ADDR+0b8000h
mov al,0dbh
mov ah,0
mov ecx,16
ABCD: stosw
stosw
inc ah
loop ABCD
mov eax,kkkktxt
mov ecx,kkkktxt2-kkkktxt
call ConMWriteAct
jmp kkkktxt2
kkkktxt:
db CSI,'40m',CSI,'H',LF,CSI,'16C',CSI,'0;32m---',CSI,'19C'
db CSI,'37mÙÞ',CSI,'5C',CSI,'1;30m--',CSI,'0;33m---'
db CSI,'1;30m-----------------',CSI,'0;33m---'
db CSI,'1;30m------',CSI,'0m--',CSI,'31m--',CSI,'7C'
db CSI,'1;37m--- ',CSI,'0;32m--------- '
db CSI,'1;37m---',CSI,'10C',CSI,'0m--',CSI,'8C',CSI,'33m-'
db CSI,'19C-',CSI,'8C',CSI,'37m-',CSI,'31m--',CSI,'6C'
db CSI,'1;37m-----',CSI,'0;32m-------------'
db CSI,'1;37m-----',CSI,'8C',CSI,'0mÙÞ- ',CSI,'33m---------'
db '----------------------- ',CSI,'31m--'
db CSI,'7C',CSI,'1;37m----',CSI,'0;32m-------------'
db CSI,'1;37m----',CSI,'9C',CSI,'0mÙÞ- ',CSI,'33m- '
db CSI,'1;34mT T T T - T -¬ T -¦¬ ¬-¦¬ '
db CSI,'0;33m- ',CSI,'31m--',CSI,'11C',CSI,'32m-------------'
db CSI,'13C',CSI,'37mÙÞ- ',CSI,'33m- ',CSI,'1;34mL'
db '¬-- - +¦+¬ - -L¬- - ¦¬ L¦¦¬ ',CSI,'0;33m- '
db CSI,'31m--',CSI,'10C',CSI,'37m-',CSI,'1;33m---',CSI,'34m'
db 'o',CSI,'33m-----',CSI,'34mo',CSI,'33m---'
db CSI,'0m-',CSI,'12CÙÞ- ',CSI,'33m- '
db CSI,'1;34mL- + + + + + L- L¦¦- L¦¦- '
db CSI,'0;33m- ',CSI,'31m--',CSI,'9C',CSI,'37m--'
db CSI,'1;33m-----',CSI,'41m- -',CSI,'40m-----'
db CSI,'0m---',CSI,'10C-Þ-Þ ',CSI,'33m-',CSI,'9C'
db CSI,'1;34mT¦¦¬-¦¦¬-¬ T',CSI,'9C',CSI,'0;33m- '
db CSI,'31m--',CSI,'8C',CSI,'37m---'
db CSI,'1;33m-',CSI,'47m ---',CSI,'0;41m- -',CSI,'1;33;47m--- '
db CSI,'40m-',CSI,'0m---',CSI,'7C',CSI,'1;33m--'
db CSI,'30;47m-----',CSI,'40m- ',CSI,'0;33m-',CSI,'9C'
db CSI,'1;34m- -+¦ -L¬-',CSI,'9C',CSI,'0;33m-'
db ' ',CSI,'31m--',CSI,'7C',CSI,'37m--',CSI,'47m '
db CSI,'1;33;40m--',CSI,'47m---',CSI,'41m---',CSI,'47m---'
db CSI,'40m',CSI,'40m--',CSI,'0m--Þ- '
db CSI,'1m---- ',CSI,'33m------Þ ',CSI,'0;33m-',CSI,'9C'
db CSI,'1;34m+¦¦-L¦¦-+ L-',CSI,'9C'
db CSI,'0;33m- ',CSI,'31m--',CSI,'7C',CSI,'37mÙ'
db CSI,'32;47m- - ',CSI,'1;33m-',CSI,'40m--',CSI,'41mÞ'
db CSI,'40m',CSI,'0;5;30;41m---'
db CSI,'0;1;33;41mÙ',CSI,'40m--',CSI,'47m- ',CSI,'0m--'
db CSI,'1m-------',CSI,'33m--------Þ '
db CSI,'0;33m-------------------------------- '
db CSI,'31m-- ',CSI,'32m-----',CSI,'37m-'
db CSI,'32m--',CSI,'47m-',CSI,'37;40m-',CSI,'32;47m-'
db CSI,'37;40m--',CSI,'5;31;47m--- ',CSI,'0m-'
db CSI,'32;47m-',CSI,'37;40m-',CSI,'32;47m-',CSI,'40m-'
db CSI,'37m-',CSI,'32;47m-',CSI,'1;37;40m------',CSI,'33m-- '
db '-',CSI,'47m---',CSI,'40m-',CSI,'6C',CSI,'30m-'
db CSI,'36m---¬-¬',CSI,'30m¬',CSI,'36m-¬-¬-¬ ¬-¬-¬¬-',CSI,'9C'
db CSI,'0;31m-- ',CSI,'32m----------'
db CSI,'37;42m-- ',CSI,'32;40m-',CSI,'37m--',CSI,'42m -'
db CSI,'40m-',CSI,'42mÞ ',CSI,'40m',CSI,'32;47m-'
db CSI,'37;40m-',CSI,'42mÞ',CSI,'32;40m--',CSI,'1;37m-----'
db CSI,'15C',CSI,'30m-',CSI,'36mL+--++'
db CSI,'30m-',CSI,'36m+++¬ -¦-----L+',CSI,'9C',CSI,'0;31m--'
db CSI,'32mÙ-- --- --Þ----',CSI,'42m ',CSI,'40m'
db CSI,'40m-',CSI,'42m ',CSI,'40m-------'
db CSI,'1;37m---Þ',CSI,'16C',CSI,'30mL ',CSI,'36mLL-L-'
db CSI,'30m-',CSI,'36mL-L- L +L¦L¦ L',CSI,'9C'
db CSI,'0;31m--',CSI,'32m-- --- --Ù---------------'
db CSI,'1;37;42m-',CSI,'40m',CSI,'42m '
db CSI,'40m-',CSI,'48C',CSI,'0;31m--',CSI,'32m-- --- --Ù--'
db CSI,'33;42m------',CSI,'32;40m--------Þ'
db CSI,'49C',CSI,'31m--',CSI,'32m-- --- --',CSI,'1;37m---'
db CSI,'0;33m-',CSI,'1;37;43m----',CSI,'40m'
db CSI,'43m',CSI,'0;33m-',CSI,'1;37m---------',CSI,'49C'
db CSI,'0;31m--',CSI,'32mÙ--- - ---Þ'
db CSI,'1;37;42m---',CSI,'0;33m-',CSI,'1;37;43m----'
db CSI,'0;33m-',CSI,'1;37;42m---------',CSI,'49C',CSI,'40m'
db CSI,'42m',CSI,'0;31m-- ',CSI,'32m---- ----Ù'
db CSI,'42m ',CSI,'43m------',CSI,'42m ',CSI,'40m'
db CSI,'42m',CSI,'49C',CSI,'31;40m-- '
db CSI,'32m--------------- -',CSI,'43m-',CSI,'40m---------'
db CSI,'49C',CSI,'31m-- ',CSI,'32m--- '
db CSI,'1;37m---------ÞÙ---------',CSI,'50C',CSI,'0;31m--'
db CSI,'7C',CSI,'1;37m---------- ----------'
db CSI,'49C',CSI,'0;31m--',CSI,'6C'
db CSI,'33m----------- -----------',CSI,'48C'
db CSI,'31m--',CSI,'5C',CSI,'33m-----------Þ Ù-----------'
db CSI,'12C',CSI,'1;37mANSº By: ',CSI,'0;31mOp'
db CSI,'1mus ',CSI,'33mOut',CSI,'32mla',CSI,'34mnd ',CSI,'35m<'
db CSI,'31mA',CSI,'35m.',CSI,'33mA',CSI,'35m.'
db CSI,'34mA',CSI,'35m>',CSI,'6C',CSI,'0;31m--',CSI,'0m'
kkkktxt2:
%endif
%ifdef DEBUG_ASCII2
mov ebx,EGADrvDDPB
mov ecx,0
mov edx,1
call DispSetCursor
mov ecx,8
mov edx,14
; call DispSetCurSize
mov al,0
; call DispSetVisible
mov al,1
; call DispSetVisible
mov edx,EGA8Pal
call DispSetPalEGA
; call DispClear
mov ecx,DispCharTab
mov edx,CP437ToUniTab
mov edx,CP1250ToUniTab
mov esi,DispCharTabLat
mov edi,F14
call DispLoadSet
mov cl,0
mov dl,1
call DispSetFont
mov edx,DispKA3
mov esi,DispKT3
mov ebp,8
call DispKKKK
%endif
%ifdef DEBUG_ASCII
mov ebx,EGADrvDDPB ; EBX <- driver parameter block
xor ecx,ecx
xor edx,edx
call TXTSetCur
mov al,13h
call TXTSetColor
mov ecx,100
mov edx,100
mov al," "
call TXTFillUp
mov al,17h
call TXTSetColor
xor ecx,ecx
xor edx,edx
call TXTSetCur
mov edx,BootMessage+2
mov ecx,BootMessage2-BootMessage-5
call TXTWriteStr
xor ecx,ecx
xor edx,edx
mov dl,2
call TXTSetCur
mov al,13h
call TXTSetColor
mov edx,DispTestText
mov ecx,DispTestText2-DispTestText
call TXTWriteStr
mov edx,F08X16
call EGASetFont
mov edx,EGA8Pal ;EGAStdPal
call EGASetPal
mov esi,6
mov edi,4
xor ebp,ebp
call DispASCII
mov esi,41
mov edi,4
mov ebp,256
call DispASCII
mov al,17h
call TXTSetColor
xor ecx,ecx
xor edx,edx
mov dl,23
call TXTSetCur
mov ebx,VTEBuff ; EBX <- VT102 first terminal
mov [ebx+VTE_PosX],ecx
mov [ebx+VTE_PosY],edx
%endif
;PageFaultTest: mov [0fffffff0h],esi ; test Page Fault
; ------------- Initialize keyboard
call KeybSetSetup ; setup keyboard
; ------------- Generate initialization task
call TaskClone ; clone idle task
or eax,eax ; is it cloned task?
jz InitTask ; jump to initialization task
; ------------- Debug alarm test (it shifts characters in 1st line)
%ifdef DEBUG_ALARM
xor ecx,ecx ; ECX <- 0 (character position)
mov eax,1 ; EAX <- 1 (interval)
AlarmTest1: mov edx,AlarmTestFunc ; EDX <- alarm test function
call AlarmCreate ; create alarm structure (-> EBX)
inc ecx ; increase character position
inc eax ; EAX <- increase interval
cmp ecx,60 ; position 0 to 59?
jb AlarmTest2 ; it is position 0 to 59
mov edx,ecx ; EDX <- position
sub edx,59 ; EDX <- 1, 2, ...
mov eax,300 ; EAX <- 300
mul edx ; EAX <- 300ms to 6 s
AlarmTest2: push ecx ; push ECX (character position)
push eax ; push EAX (interval)
mov ecx,eax ; ECX <- alarm repeat interval
call AlarmSetInt ; set alarm interval
call AlarmStart ; start alarm
pop eax ; pop EAX (interval)
pop ecx ; pop ECX (character position)
cmp ecx,80 ; all characters?
jb AlarmTest1 ; create next alarm
%endif
; ------------- Debug clone tasks
%ifdef DEBUG_TASK
mov esi,7
xor eax,eax
mov ax,[VideoSegm]
shl eax,4
add eax,SYSTEM_ADDR
add eax,80*2*18
xchg eax,edi
mov bh,7bh
DebCloneTask2: call TaskClone
or eax,eax
jz DebTask
sub edi,2*80*2
sub bh,10h
dec esi
jnz DebCloneTask2
%endif
; ---- Idle loop
Idle:
%ifdef DEBUG_TASK
mov ah,bh
mov al,"I"
stosw
mov al,"d"
stosw
mov al,"l"
stosw
mov al,"e"
stosw
mov al," "
stosw
mov al,":"
stosw
add edi,2*2
%endif
IdleLoop:
%ifdef DEBUG_TIME
call DebDispTime ; debug display date and time
%endif
;%ifdef DEBUG_ASCII
call ConReadAct
jc KKKK2
call ConWriteAct
KKKK2:
;%endif
%ifdef DEBUG_TASK
inc byte [edi]
%endif
jmp IdleLoop
; ------------- Initialization task (idle task cannot sleep)
InitTask:
; ------------- Initialize floppy disk driver
call FDInit ; initialize floppy disk driver
; ------------- Display list of drivers
%ifdef DEBUG_DRVLIST
call DrvLstDisp ; display list of drivers
%endif
InitTaskSleep: mov eax,20
call Sleep
inc byte [800B8000h + 25*80*2-2]
jmp short InitTaskSleep
; ------------- Debug test task
%ifdef DEBUG_TASK
DebTask: mov ah,bh
mov al,"T"
stosw
mov al,"a"
stosw
mov al,"s"
stosw
mov al,"k"
stosw
mov al,bh
shr al,4
add al,"0"
stosw
mov al,":"
stosw
add edi,2*2
DebTask2: mov edx,2
mov eax,50
call RandIntDWord
call Sleep
mov edx,1*TIME_1MS
mov eax,20*TIME_1MS
call RandIntDWord
xchg eax,ebx
call GetSysTimeLOW
add ebx,eax
DebTask3: inc byte [edi]
call GetSysTimeLOW
cmp eax,ebx
jl DebTask3
jmp DebTask2
%endif
%ifdef DEBUG_ASCII2
; display ASCII tables: table addresses EDX, titles ESI, number of tables EBP
DispKKKK: mov ch,3
DispKKKK30: mov cl,5
DispKKKK31: push ecx
push edx
push esi
mov edx,[edx]
mov al,80
mul ch
mov ch,0
add ax,cx
movzx edi,ax
shl edi,1
add edi,[ebx+DDPB_Addr]
mov ecx,16
KKKK32: lodsb
mov ah,7
stosw
loop KKKK32
add edi,160-2*16
mov esi,edx
mov ecx,80h
KKKK3: xor eax,eax
lodsw
mov edx,"?"
call DispMapChar
or ah,16h
stosw
inc ecx
test cl,0fh
jnz KKKK3
add edi,160-2*16
test cl,cl
jnz KKKK3
pop esi
pop edx
pop ecx
dec ebp
jz KKKK4
add esi,16
add edx,4
add cl,18
cmp cl,70
jb DispKKKK31
add ch,10
cmp ch,20
jb DispKKKK30
KKKK4: ret
DispKT1: db ' ASCII '
db ' DEC VT100 GRAPH'
db ' IBM 437 USA '
db ' IBM 737 Greek '
db ' IBM 775 Baltic '
db ' IBM 850 Latin 1'
db ' IBM 852 Latin 2'
db ' IBM 857 Turkish'
DispKT2: db ' ASCII '
db ' IBM 858 Latin 1'
db ' IBM 860 Portug.'
db ' IBM 861 Iceland'
db 'IBM 863 FrCanada'
db ' IBM 865 Nordic '
db ' IBM 869 Greek '
db ' IBM 895 Kamenic'
DispKT3: db ' ASCII '
db ' IBM 437 USA '
db ' Win 1250 CE '
db 'Win 1252 Latin 1'
db ' Win 1253 Greek '
db 'Win 1254 Turkish'
db ' Win 1257 Baltic'
db 'Win 1258 Vietnam'
DispKT4: db ' ASCII '
db 'ISO 8859-1 Lat 1'
db 'ISO 8859-2 Lat 2'
db 'ISO 8859-3 Lat 3'
db 'ISO 8859-4 Balt '
db 'ISO 8859-7 Greek'
db 'ISO 8859-9 Turk '
db 'ISO 8859-15 Lat9'
DispKT5: db ' ASCII '
db ' IBM 720 Arabic '
db 'Win 1256 Arabic '
db 'ISO 8859-6 Arab '
DispKT6: db ' ASCII '
db 'IBM 855 Cyrillic'
db 'IBM 866 Russian '
db 'Win1251 Cyrillic'
db 'ISO 8859-5 Cyril'
DispKT7: db ' ASCII '
db ' IBM 862 Hebrew '
db 'Win 1255 Hebrew '
db 'ISO 8859-8 Hebr '
DispKT8: db ' Font 00h..7fh '
db ' Font 80h..ffh '
db 'Font 100h..17fh '
db 'Font 180h..1ffh '
DispKA1: dd DispCharTab
dd CP1ToUniTab
dd CP437ToUniTab
dd CP737ToUniTab
dd CP775ToUniTab
dd CP850ToUniTab
dd CP852ToUniTab
dd CP857ToUniTab
DispKA2: dd DispCharTab
dd CP858ToUniTab
dd CP860ToUniTab
dd CP861ToUniTab
dd CP863ToUniTab
dd CP865ToUniTab
dd CP869ToUniTab
dd CP895ToUniTab
DispKA3: dd DispCharTab
dd CP437ToUniTab
dd CP1250ToUniTab
dd CP1252ToUniTab
dd CP1253ToUniTab
dd CP1254ToUniTab
dd CP1257ToUniTab
dd CP1258ToUniTab
DispKA4: dd DispCharTab
dd CP28591ToUniTab
dd CP28592ToUniTab
dd CP28593ToUniTab
dd CP28594ToUniTab
dd CP28597ToUniTab
dd CP28599ToUniTab
dd CP28605ToUniTab
DispKA5: dd DispCharTab
dd CP720ToUniTab
dd CP1256ToUniTab
dd CP28596ToUniTab
DispKA6: dd DispCharTab
dd CP855ToUniTab
dd CP866ToUniTab
dd CP1251ToUniTab
dd CP28595ToUniTab
DispKA7: dd DispCharTab
dd CP862ToUniTab
dd CP1255ToUniTab
dd CP28598ToUniTab
DispKA8: dd DispCharTab
dd CP437ToUniTab
dd DispCharTabLat
dd DispCharTabLat+2*128
%endif
; -----------------------------------------------------------------------------
; Test - display ASCII table
; -----------------------------------------------------------------------------
; INPUT: EBX = driver parameter block
; ESI = position
; EDI = row
; EBP = first character (0 or 256)
; -----------------------------------------------------------------------------
%ifdef DEBUG_ASCII
DispASCII: push eax
push ecx
push edx
push ebp
mov ecx,esi
mov edx,edi
call TXTSetCur
mov al,0e0h
or ebp,ebp
jz DispASCII1
mov al,0e8h
DispASCII1: xor ebp,ebp
push eax
call TXTSetColor
mov al,201
call TXTWriteChr
mov al,205
mov ecx,31
mov edx,1
call TXTFillUp
lea ecx,[esi+8]
mov edx,edi
call TXTSetCur
mov al,7
DispASCII12: call TXTSetColor
push eax
shr al,4
add al,"0"
cmp al,"9"
jbe DispASCII14
add al,7
DispASCII14: call TXTWriteChr
pop eax
and al,0f0h
add al,10h
jnc DispASCII12
pop eax
call TXTSetColor
lea ecx,[esi+32]
mov edx,edi
call TXTSetCur
mov al,187
call TXTWriteChr
DispASCII2: mov ecx,esi
mov edx,ebp
shr edx,4
lea edx,[edi+1+edx]
call TXTSetCur
mov al,186
call TXTWriteChr
DispASCII4: mov eax,ebp
call TXTWriteChr
inc ebp
test ebp,0fh
jz DispASCII6
mov al," "
call TXTWriteChr
jmp short DispASCII4
DispASCII6: mov al,186
call TXTWriteChr
test ebp,0ffh
jnz DispASCII2
mov ecx,esi
mov edx,edi
add edx,17
call TXTSetCur
mov al,200
call TXTWriteChr
push edx
mov al,205
mov ecx,31
mov edx,1
call TXTFillUp
pop edx
push edx
mov al,DCHOUT_GETCOLOR
call TXTInfo
push eax
lea ecx,[esi+8]
call TXTSetCur
mov al,70h
DispASCII62: call TXTSetColor
push eax
and al,0fh
add al,"0"
cmp al,"9"
jbe DispASCII64
add al,7
DispASCII64: call TXTWriteChr
pop eax
and al,0fh
add al,1
cmp al,0fh
jbe DispASCII62
pop eax
call TXTSetColor
pop edx
lea ecx,[esi+32]
call TXTSetCur
mov al,188
call TXTWriteChr
pop ebp
pop edx
pop ecx
pop eax
ret
%endif
; -----------------------------------------------------------------------------
; Debug display date and time
; -----------------------------------------------------------------------------
%ifdef DEBUG_TIME
DebDispTime: mov byte [VideoPos],0
; ------------- Get current date and time
call GetCurrentTime
mov ebx,DebSysTime
call JulianToSystem
; ------------- Display date
movzx eax,byte [ebx+SYSTIME_Month]
call DebOutNum
mov al,"/"
call DebOutChar
movzx eax,byte [ebx+SYSTIME_Day]
call DebOutNum
mov al,"/"
call DebOutChar
movsx eax,word [ebx+SYSTIME_Year]
call DebOutNumSig
call DebOutSpc
; ------------- Display time
movzx eax,byte [ebx+SYSTIME_Hour]
call DebOutNum
mov al,':'
call DebOutChar
movzx eax,byte [ebx+SYSTIME_Min]
call DebOutNum
mov al,':'
call DebOutChar
movzx eax,byte [ebx+SYSTIME_Sec]
call DebOutNum
mov al,'.'
call DebOutChar
mov eax,[ebx+SYSTIME_100NSec]
call DebOutNum
call DebOutSpc
call DebOutSpc
call DebOutSpc
call DebOutSpc
ret
%endif
; -----------------------------------------------------------------------------
; Debug display instruction statistics
; -----------------------------------------------------------------------------
%ifdef DEBUG_INS
; ------------- Measure instructions
DebDispIns: mov byte [VideoRow],3
mov byte [VideoPos],0
; ------------- Display simulated text (for screenshot)
;%define DISPINS
%ifdef DISPINS
call DebOutClear
mov esi,DebInsTxt
DebDispInsX2: lodsb
cmp al,0
je DebDispInsX6
cmp al,13
je DebDispInsX3
cmp al,10
jne DebDispInsX4
cmp byte [VideoPos],40
mov byte [VideoPos],40
jb DebDispInsX2
DebDispInsX3: call DebNewLine
jmp short DebDispInsX2
DebDispInsX4: call DebOutChar
jmp short DebDispInsX2
DebDispInsX6: ret
%endif
BIGREP EQU 500
LOWREP EQU 100
; ------------- Short delay to quiet down (0.2 second)
TSC_OK ; is time-stamp counter supported?
jnz TSCOK2 ; time-stamp counter is supported
sti
TSCOK2: mov eax,200000
call UDelay
; ------------- Start time
call PerfGetUS ; get current time
mov [DebStartTime],eax ; push start time
; ------------- Prepare base delay
cli
call DebDispStart ; start measure
call DebDispStop ; stop measure
TSC_OK ; is time-stamp counter supported?
jnz TSCOK3 ; time-stamp counter is supported
sti
TSCOK3: mov [DebPerf],eax ; correction
; ------------- Prepare delay 2x"mov reg32,N" (BIGREP)
cli
call DebDispStart ; start measure
%rep BIGREP
mov eax,1234567
mov edx,234
%endrep
call DebDispStop ; stop measure
TSC_OK ; is time-stamp counter supported?
jnz TSCOK4 ; time-stamp counter is supported
sti
TSCOK4: mov [DebPerf2],eax ; correction
; ------------- Prepare delay "add reg32,N" (LOWREP)
cli
call DebDispStart ; start measure
%rep LOWREP
add ecx,128
%endrep
call DebDispStop ; stop measure
TSC_OK ; is time-stamp counter supported?
jnz TSCOK5 ; time-stamp counter is supported
sti
TSCOK5: mov [DebPerf4],eax ; correction
; ------------- Macro - start measure (%1 = text)
%macro DEBPERF1 1
jmp short %%L2 ; skip text
%%L1: db %1,0 ; text to display
%%L2 mov esi,%%L1
call DebOutText ; display text
mov al,":"
call DebOutChar
call DebOutSpc
cli
call DebDispStart ; start measure
%endmacro
; ------------- Macro - end measure (%1=loops, %2=input/%3=output correction)
%macro DEBPERF2 3
call DebDispStop ; stop measure
TSC_OK ; is time-stamp counter supported?
jnz %%TSCOK6 ; time-stamp counter is supported
sti
%%TSCOK6: mov [%3],eax ; save output correction
sub eax,[%2] ; do input correction
%if %1 > 1
xor edx,edx
mov ebx,%1
div ebx
%endif
call DebOutNum ; display time
%if %1 > 1
cmp eax,100
jae %%L3
mov al,"."
call DebOutChar
xor eax,eax
xchg eax,edx
mov ebx,%1/10
div ebx
call DebOutNum
%%L3:
%endif
call DebOutSpc
%ifdef DEBUG_INS_CLOCK
mov al,"c"
call DebOutChar
mov al,"l"
call DebOutChar
mov al,"k"
%else
mov al,"n"
call DebOutChar
mov al,"s"
%endif
call DebOutChar
cmp byte [VideoPos],40
mov byte [VideoPos],40
jb %%L4
call DebNewLine
%%L4:
%endmacro
; ------------- Macto - unsupported text (%1 = text)
%macro DEBPERFERR 1
jmp short %%L2 ; skip text
%%L1: db %1,0 ; text to display
%%L2 mov esi,%%L1
call DebOutText ; display text
mov al,":"
call DebOutChar
call DebOutSpc
mov al,"-"
call DebOutChar
cmp byte [VideoPos],40
mov byte [VideoPos],40
jb %%L3
call DebNewLine
%%L3:
%endmacro
DEBPERF1 'mov reg8,N'
%rep BIGREP
mov al,123
%endrep
DEBPERF2 BIGREP,DebPerf,DebPerf0
DEBPERF1 'mov reg16,N'
%rep BIGREP
mov ax,1234
%endrep
DEBPERF2 BIGREP,DebPerf,DebPerf0
DEBPERF1 'mov reg32,N'
%rep BIGREP
mov eax,12345
%endrep
DEBPERF2 BIGREP,DebPerf,DebPerf1
DEBPERF1 'mov reg32,reg32'
%rep BIGREP
mov eax,ebx
%endrep
DEBPERF2 BIGREP,DebPerf,DebPerf0
DEBPERF1 'inc reg32'
%rep BIGREP
inc ecx
%endrep
DEBPERF2 BIGREP,DebPerf,DebPerf3
DEBPERF1 'dec reg32'
%rep BIGREP
dec ecx
%endrep
DEBPERF2 BIGREP,DebPerf,DebPerf0
xor ecx,ecx
DEBPERF1 'mov reg32,[addr+offset]'
%rep BIGREP
mov eax,[DebMove1+ecx*4]
inc ecx
%endrep
DEBPERF2 BIGREP,DebPerf3,DebPerf0
xor ecx,ecx
DEBPERF1 'mov [addr+offset],reg32'
%rep BIGREP
mov [DebMove2+ecx*4],ecx
inc ecx
%endrep
DEBPERF2 BIGREP,DebPerf3,DebPerf0
xor ecx,ecx
DEBPERF1 'mov reg32,[addr+offset+1]'
%rep BIGREP
mov eax,[DebMove3+ecx*8+1]
inc ecx
%endrep
DEBPERF2 BIGREP,DebPerf3,DebPerf0
xor ecx,ecx
DEBPERF1 'mov [addr+offset+1],reg32'
%rep BIGREP
mov [DebMove4+ecx*8+1],ecx
inc ecx
%endrep
DEBPERF2 BIGREP,DebPerf3,DebPerf0
DEBPERF1 'xchg reg32,reg32'
%rep BIGREP
xchg eax,ebx
%endrep
DEBPERF2 BIGREP,DebPerf,DebPerf0
mov ecx,123456
DEBPERF1 'add reg32,reg32'
%rep BIGREP
add eax,ecx
%endrep
DEBPERF2 BIGREP,DebPerf,DebPerf0
mov ecx,456789
DEBPERF1 'mul reg32'
%rep BIGREP
mov eax,1234567
mul ecx
%endrep
DEBPERF2 BIGREP,DebPerf1,DebPerf0
mov ecx,45899
DEBPERF1 'div reg32'
%rep BIGREP
mov eax,1234567
mov edx,234
div ecx
%endrep
DEBPERF2 BIGREP,DebPerf2,DebPerf0
DEBPERF1 'push reg32'
mov [DebPushESP],esp
mov esp,TestPush1
%rep BIGREP
push eax
%endrep
mov esp,[DebPushESP]
DEBPERF2 BIGREP,DebPerf,DebPerf0
DEBPERF1 'pop reg32'
mov [DebPushESP],esp
mov esp,TestPush2+BIGREP*4
%rep BIGREP
pop eax
%endrep
mov esp,[DebPushESP]
DEBPERF2 BIGREP,DebPerf,DebPerf0
DEBPERF1 'pusha'
mov [DebPushESP],esp
mov esp,TestPushA1
%rep (BIGREP/8)
pusha
%endrep
mov esp,[DebPushESP]
DEBPERF2 (BIGREP/8),DebPerf,DebPerf0
DEBPERF1 'popa'
mov [DebPushESP],esp
mov esp,TestPushA2+(BIGREP/8)*8*4
%rep (BIGREP/8)
popa
%endrep
mov esp,[DebPushESP]
DEBPERF2 (BIGREP/8),DebPerf,DebPerf0
DEBPERF1 'jmp short'
%rep BIGREP
jmp short $+2
%endrep
DEBPERF2 BIGREP,DebPerf,DebPerf0
DEBPERF1 'jmp near'
%rep BIGREP
jmp near $+5
%endrep
DEBPERF2 BIGREP,DebPerf,DebPerf0
DEBPERF1 'jc short (jump)'
stc
%rep BIGREP
jc short $+2
%endrep
DEBPERF2 BIGREP,DebPerf,DebPerf0
DEBPERF1 'jc short (not jump)'
clc
%rep BIGREP
jc short $+2
%endrep
DEBPERF2 BIGREP,DebPerf,DebPerf0
mov ecx,123456
DEBPERF1 'loop'
%rep BIGREP
loop $+2
%endrep
DEBPERF2 BIGREP,DebPerf,DebPerf0
DEBPERF1 'nop'
%rep BIGREP
nop
%endrep
DEBPERF2 BIGREP,DebPerf,DebPerf0
DEBPERF1 'call addr'
%rep BIGREP
call $+5
%endrep
DEBPERF2 BIGREP,DebPerf,DebPerf0
%rep BIGREP
pop eax
%endrep
%assign RETADDR 0
%rep BIGREP
push dword (DebRet-RETADDR)
%assign RETADDR RETADDR + 1
%endrep
DEBPERF1 'ret'
%rep BIGREP
ret
%endrep
DebRet:
DEBPERF2 BIGREP,DebPerf,DebPerf0
call PerfGetUS ; get current time
sub [DebStartTime],eax ; start time I/O correction
DEBPERF1 'out N,al'
%rep LOWREP
out 80h,al
%endrep
DEBPERF2 LOWREP,DebPerf,DebPerf0
DEBPERF1 'in al,N'
%rep LOWREP
in al,80h
%endrep
DEBPERF2 LOWREP,DebPerf,DebPerf0
mov dx,80h
DEBPERF1 'out dx,al'
%rep LOWREP
out dx,al
%endrep
DEBPERF2 LOWREP,DebPerf,DebPerf0
mov dx,80h
DEBPERF1 'in al,dx'
%rep LOWREP
in al,dx
%endrep
DEBPERF2 LOWREP,DebPerf,DebPerf0
call PerfGetUS ; get current time
add [DebStartTime],eax ; start time I/O correction
TSC_OK ; is time-stamp counter supported?
jnz DebTS2 ; time-stamp counter is supported
DEBPERFERR 'rdtsc'
%rep BIGREP
mov eax,12345 ; time correction
%endrep
jmp near DebTS4
DebTS2: DEBPERF1 'rdtsc'
%rep BIGREP
rdtsc
%endrep
DEBPERF2 BIGREP,DebPerf,DebPerf0
DebTS4: FPU_OK ; FPU present or emulated?
jz DebTS5 ; FPU not present nor emulated
mov ecx,DebFpu1
DEBPERF1 'fnsave'
%rep LOWREP
fnsave [ecx]
add ecx,128
%endrep
DEBPERF2 LOWREP,DebPerf4,DebPerf0
mov ecx,DebFpu2
DEBPERF1 'fsave'
%rep LOWREP
fsave [ecx]
add ecx,128
%endrep
DEBPERF2 LOWREP,DebPerf4,DebPerf0
mov ecx,DebFpu3
DEBPERF1 'frstor'
%rep LOWREP
frstor [ecx]
add ecx,128
%endrep
DEBPERF2 LOWREP,DebPerf4,DebPerf0
jmp DebTS6
DebTS5:
DEBPERFERR 'fnsave'
DEBPERFERR 'fsave'
DEBPERFERR 'frstor'
DEBPERFERR 'fxsave'
DEBPERFERR 'fxrstor'
mov eax,[DebPerf1]
sub eax,[DebPerf0]
jnc DebTS52
xor eax,eax
DebTS52: shr eax,5
sub [DebStartTime],eax ; time difference
jmp DebNoFX2
DebTS6: test dword [CPUInfo+CPU_Features],B24
jz near DebNoFX
mov ecx,DebFpu4
DEBPERF1 'fxsave'
%rep LOWREP
fxsave [ecx]
add ecx,512
%endrep
DEBPERF2 LOWREP,DebPerf4,DebPerf0
mov ecx,DebFpu5
DEBPERF1 'fxrstor'
%rep LOWREP
fxrstor [ecx]
add ecx,512
%endrep
DEBPERF2 LOWREP,DebPerf4,DebPerf0
jmp DebNoFX2
DebNoFX:
DEBPERFERR 'fxsave'
DEBPERFERR 'fxrstor'
mov ecx,DebFpu4
%rep LOWREP
fsave [ecx] ; time correction
add ecx,128
%endrep
mov ecx,DebFpu5
%rep LOWREP
frstor [ecx] ; time correction
add ecx,128
%endrep
DebNoFX2: DEBPERF1 'memfill stosd (4KB)'
mov edi,TestBuff1
mov ecx,4096/4
rep stosd
DEBPERF2 1,DebPerf,DebPerf0
DEBPERF1 'memcopy movsd (4KB)'
mov esi,TestBuff3
mov edi,TestBuff4
mov ecx,4096/4
rep movsd
DEBPERF2 1,DebPerf,DebPerf0
test byte [CPUInfo+CPU_Flags],B1 ; MMX
jnz DebMMX2 ; MMX OK
DEBPERFERR 'memfill MMX0 (4KB)'
DEBPERFERR 'memcopy MMX0 (4KB)'
DEBPERFERR 'memfill MMX0..7 (4KB)'
DEBPERFERR 'memcopy MMX0..7 (4KB)'
mov edi,TestBuff2
mov ecx,4096/4
rep stosd ; time correction
mov esi,TestBuff5
mov edi,TestBuff6
mov ecx,4096/4
rep movsd ; time correction
mov edi,TestBuff7
mov ecx,4096/4
rep stosd ; time correction
mov esi,TestBuff8
mov edi,TestBuff9
mov ecx,4096/4
rep movsd ; time correction
jmp near DebMMX5
DebMMX2: DEBPERF1 'memfill MMX0 (4KB)'
mov edi,TestBuff2
mov ecx,4096/128
DebStoreMMX:
%assign MMXINX 0
%rep 16
movq [edi+MMXINX*8],mm0
%assign MMXINX MMXINX+1
%endrep
add edi,128
loop DebStoreMMX
DEBPERF2 1,DebPerf,DebPerf0
DEBPERF1 'memcopy MMX0 (4KB)'
mov esi,TestBuff5
mov edi,TestBuff6
mov ecx,4096/128
DebMoveMMX:
%assign MMXINX 0
%rep 16
movq mm0,[esi+MMXINX*8]
movq [edi+MMXINX*8],mm0
%assign MMXINX MMXINX+1
%endrep
add edi,128
add esi,128
dec ecx
jnz DebMoveMMX
DEBPERF2 1,DebPerf,DebPerf0
DEBPERF1 'memfill MMX0..7 (4KB)'
mov edi,TestBuff7
mov ecx,4096/128
DebStoreMMX2:
%assign MMXINX 0
%rep 2
movq [edi+MMXINX*8],mm0
movq [edi+(MMXINX+1)*8],mm1
movq [edi+(MMXINX+2)*8],mm2
movq [edi+(MMXINX+3)*8],mm3
movq [edi+(MMXINX+4)*8],mm4
movq [edi+(MMXINX+5)*8],mm5
movq [edi+(MMXINX+6)*8],mm6
movq [edi+(MMXINX+7)*8],mm7
%assign MMXINX MMXINX+8
%endrep
add edi,128
loop DebStoreMMX2
DEBPERF2 1,DebPerf,DebPerf0
DEBPERF1 'memcopy MMX0..7 (4KB)'
mov esi,TestBuff8
mov edi,TestBuff9
mov ecx,4096/128
DebMoveMMX2:
%assign MMXINX 0
%rep 2
movq mm0,[esi+MMXINX*8]
movq mm1,[esi+(MMXINX+1)*8]
movq mm2,[esi+(MMXINX+2)*8]
movq mm3,[esi+(MMXINX+3)*8]
movq mm4,[esi+(MMXINX+4)*8]
movq mm5,[esi+(MMXINX+5)*8]
movq mm6,[esi+(MMXINX+6)*8]
movq mm7,[esi+(MMXINX+7)*8]
movq [edi+MMXINX*8],mm0
movq [edi+(MMXINX+1)*8],mm1
movq [edi+(MMXINX+2)*8],mm2
movq [edi+(MMXINX+3)*8],mm3
movq [edi+(MMXINX+4)*8],mm4
movq [edi+(MMXINX+5)*8],mm5
movq [edi+(MMXINX+6)*8],mm6
movq [edi+(MMXINX+7)*8],mm7
%assign MMXINX MMXINX+8
%endrep
add edi,128
add esi,128
dec ecx
jnz DebMoveMMX2
DEBPERF2 1,DebPerf,DebPerf0
; ------------- Total time
DebMMX5: mov byte [VideoPos],(80-(DebTimeLenTxt2-DebTimeLenTxt+5))/2
mov esi,DebTimeLenTxt
call DebOutText
call PerfGetUS ; get current time
sub eax,[DebStartTime] ; time difference
call DebOutNum ; display time
ret
; ------------- Start measure
DebDispStart: TSC_OK ; is time-stamp counter supported?
jz near SpkTimerStart ; time-stamp not supported
call PerfGetNS ; get current time in nanoseconds
mov [DebPushEAX],eax ; push start time
ret
; ------------- Stop measure
DebDispStop: TSC_OK ; is time-stamp counter supported?
jz near SpkTimerGet ; time-stamp not supported
call PerfGetNS ; get new current time in nanoseconds
sub eax,[DebPushEAX] ; time difference
ret
%endif
%ifdef DEBUG_ALARM
AlarmTestFunc: inc byte [800B8000h+ecx*2] ; alarm test - shift character
ret
%endif
; -----------------------------------------------------------------------------
; Data
; -----------------------------------------------------------------------------
DATA_SECTION
;IsEISA: db 0 ; 1=is EISA bus, 0=no
;IsPCIISA: db 0 ; 1=is PCI/ISA bus, 0=no
; ------------- Debug time structure
%ifdef DEBUG_TIME
DebSysTime: times SYSTIME_size db 0
%endif
; ------------- Current display device parameter block
;CurDDPB: times DDPB_size db 0
%ifdef DEBUG_INS
; ------------- Simulated debug text (for screenshot)
%ifdef DISPINS
DebInsTxt: db 'CPU type: Pentium 3, Vendor: AMD, '
db 'Family: 6, Model: 10, '
db 'Freq.: 1658556 kHz',13
db 'Features: MMX SSE 3DNow! 3DNow!ext MMX+(AMD) '
db 'FPU TSC',13,13
db 'mov reg8,N: 3.4 ns',10
db 'mov reg16,N: 6.2 ns',10
db 'mov reg32,N: 7.9 ns',10
db 'mov reg32,reg32: 2.9 ns',10
db 'inc reg32: 1.5 ns',10
db 'dec reg32: 1.6 ns',10
db 'mov reg32,[addr+offset]: 15.5 ns',10
db 'mov [addr+offset],reg32: 15.0 ns',10
db 'mov reg32,[addr+offset+1]: 17.2 ns',10
db 'mov [addr+offset+1],reg32: 19.7 ns',10
db 'xchg reg32,reg32: 1.3 ns',10
db 'add reg32,reg32: 3.5 ns',10
db 'mul reg32: 3.5 ns',10
db 'div reg32: 14.2 ns',10
db 'push reg32: 1.6 ns',10
db 'pop reg32: 8.0 ns',10
db 'pusha: 61.2 ns',10
db 'popa: 50.2 ns',10
db 'jmp short: 8.1 ns',10
db 'jmp near: 12.6 ns',10
db 'jc short (jump): 7.3 ns',10
db 'jc short (not jump): 3.6 ns',10
db 'loop: 9.2 ns',10
db 'nop: 1.3 ns',10
db 'call addr: 14.8 ns',10
db 'ret: 13.3 ns',10
db 'out N,al: 1447 ns',10
db 'in al,N: 1445 ns',10
db 'out dx,al: 1445 ns',10
db 'in al,dx: 1444 ns',10
db 'rdtsc: 6.5 ns',10
db 'fnsave: 249 ns',10
db 'fsave: 273 ns',10
db 'frstor: 285 ns',10
db 'fxsave: 345 ns',10
db 'fxrstor: 451 ns',10
db 'memfill stosd (4KB): 7922 ns',10
db 'memcopy movsd (4KB): 13869 ns',10
db 'memfill MMX0 (4KB): 6196 ns',10
db 'memcopy MMX0 (4KB): 12140 ns',10
db 'memfill MMX0..7 (4KB): 5986 ns',10
db 'memcopy MMX0..7 (4KB): 12053 ns',10
db ' ',
db 'Total time (without IN/OUT) [us]: 474'
db 0
%endif ; DISPINS
%ifdef DEBUG_INS_CLOCK
DebTimeLenTxt: db 'Total time (without IN/OUT) [clock]: ',0
%else
DebTimeLenTxt: db 'Total time (without IN/OUT) [us]: ',0
%endif
DebTimeLenTxt2:
%endif
; -----------------------------------------------------------------------------
; Uninitialized data
; -----------------------------------------------------------------------------
BSS_SECTION
; ------------- Debug instruction buffers
%ifdef DEBUG_INS
align 4, resb 1
DebStartTime: resd 1 ; start time
DebPushEAX: resd 1 ; push register EAX (with time)
DebPushESP: resd 1 ; push register ESP
DebPerf: resd 1 ; basic correction
DebPerf0: resd 1 ; unused output correction
DebPerf1: resd 1 ; correction "mov reg32,N" (BIGREP)
DebPerf2: resd 1 ; correction 2x"mov reg32,N" (BIGREP)
DebPerf3: resd 1 ; correction "inc reg32" (BIGREP)
DebPerf4: resd 1 ; correction "add reg32,reg32" (LOWREP)
align 4, resb 1
DebMove1: resb BIGREP*4 ; mov reg32,[addr]
align 4, resb 1
DebMove2: resb BIGREP*4 ; mov [addr],reg32
align 4, resb 1
DebMove3: resb BIGREP*4*2 ; mov reg32,[addr+1]
align 4, resb 1
DebMove4: resb BIGREP*4*2 ; mov [addr+1],reg32
align 4, resb 1
TestPush1: resb 4*BIGREP
align 4, resb 1
TestPush2: resb 4*BIGREP
align 4, resb 1
TestPushA1: resb 8*4*(BIGREP/8)
align 4, resb 1
TestPushA2: resb 8*4*(BIGREP/8)
align 32, resb 1
DebFpu1: resb 128*LOWREP ; fnsave
align 4, resb 1
DebFpu2: resb 128*LOWREP ; fsave
align 4, resb 1
DebFpu3: resb 128*LOWREP ; frstor
align 4, resb 1
DebFpu4: resb 512*LOWREP ; fxsave
align 4, resb 1
DebFpu5: resb 512*LOWREP ; fxrstor
align 4, resb 1
TestBuff1: resb 4096
align 4, resb 1
TestBuff2: resb 4096
align 4, resb 1
TestBuff3: resb 4096
align 4, resb 1
TestBuff4: resb 4096
align 4, resb 1
TestBuff5: resb 4096
align 4, resb 1
TestBuff6: resb 4096
align 4, resb 1
TestBuff7: resb 4096
align 4, resb 1
TestBuff8: resb 4096
align 4, resb 1
TestBuff9: resb 4096
%endif
|