Mission Goal
The mission goal is inspired by a similar example code written by
John S. Fine. The mission goal is to have 26 individual tasks running at the same time. Each task will advance its individual letter on the screen. The speed that each letter moves with is different from task to task.
Elements
This is a list of elements which are required by the test. Each element has a short description of what it does.
Global Descriptor Table
The Global Descriptor Table (GDT) contain generally segment and system descriptors. There are three code segments in this test and one data segment. The following is a list of the descriptors in the GDT:
Global Descriptor Table
Desc # |
Location |
Type |
Description |
0000h | 0000 | Null | Required null descriptor |
0001h | 30000h | Data | Global Descriptor Table |
0002h | 38000h | Data | Interrupt Descriptor Table |
0003h | 40000h | Code | ISR Dispatcher code |
0004h | 41000h | Code | Multitask ISR code |
0005h | 42000h | Code | Dump State code |
0006h | 43000h | Code | Task code |
0007h | 50000h | System | Task State Segment for task A |
... | ... | ... | ... |
0021h | 6A000h | System | Task State Segment for task Z |
0022h | B8000h | Data | Screen Location |
Interrupt Descriptor Table
The only reason the Interrupt Descriptor Table (IDT) is used in this is because we need to have the
Multitask ISR routine called each time the
PIT send an interrupt signal. We don't have any handlers for CPU exceptions so these will just dump system state information on the screen, and if any of the other interrupts are called, except the Multitask ISR (IDT[50h]), the system state will also be dumped.
Interrupt Descriptor Table
INT Vector # | Desc # | Description | Group |
00h - 1Fh |
0005h |
Just dump state information if called. |
CPU Exceptions |
20h - 3Fh |
0005h |
Just dump state information if called. |
OS Reserved |
40h |
0004h |
Systemtimer - Execute 'Multitask ISR' |
IRQ Service Routines |
41h - FFh |
0005h |
Just dump state information if called. |
OS Reserved |
ISR Dispatcher
The ISR Dispatcher is especially usefull when multiple
have been installed on the same IRQ. But for testing purposes it is used in this test. The code will call each ISR which has been installed for the interrupt number. This is what the code will do:
; Each interrupt points to a different offset for each IDT entry. At this
; this offset there will be the following three commands.
push eax
push
jmp ISR_Dispatcher
; This is the actual ISR Dispatcher.
ISR_Dispatcher:
pusha ;Save registers
push ds
push ss ;Set up ds (note ss is always valid)
pop ds
mov al, EOI ;Tell 8259 that interrupt is done
out M_PIC, al
inc dword [diag_events] ;Diagnostic
mov esi, [pri_heap] ;Get current task
mov eax, [esi+EVT_defer] ;Get its defer value
add [esi+EVT_time], eax ;Advance its time value
call sift_heap ;Update priority heap
dispatch_task:
mov esi, [pri_heap] ;Get next task
mov al, [esi+EVT_quantum] ;Program 8254 for next quantum
out TMR_CNT0, al
mov al, [esi+EVT_quantum+1]
out TMR_CNT0, al
lea eax, [esi+EVT_tss] ;Get its tss address
shr eax, 8 ;Just the interesting bits
mov [tss_dsc+3], ax ;Change tss descriptor in gdt
;;; mov byte [tss_dsc+5], (D_TSS+D_PRESENT)>>8 ;Pretend it isn't busy
jmp tss_sel:0 ;Switch tasks
;Switching tasks saves context in the old tss. When some other task switches
;back to us, it will continue from after the above JMP.
pop ds ;Restore registers
popa
iret ;Exit interrupt
pop eax
pop eax
iret
Multitask ISR
This is an
ISR which is installed, to handle switches between different processes. In this test it is started when ever a IRQ is received from the
PIT This specific ISR uses a round-robin algorithm to dispatch the next task.
Task Code
This is the code which actually advances the letter on screen. The same code segment is used by all 26 tasks, only the x/y position and the letter is different. These values are in the AL and DX registers.
segment TaskCode use32
UpdateLetter:
mov ds:[ebx], 0
add ebx, 2
mov ds:[ebx], al
cmp ebx, 80*25*2
jnz .Continue
xor ebx, ebx
.Continue:
hlt
jmp UpdateLetter
Task State Segments
All fields, except AL, DX, CS and EIP, are the same in each of the 26 task state segments (TSS).