Modify multitasking and dynamic thread registration example (11.2) such that • It displays a rotating bar on top left corner of the screen (as in Example 11.1). • Also, if we press “S (both small and caps)”, it will generate new process which will display rotating bars on screen in next column from the previous one. • And if “Q (both small and caps)” is pressed from keyboard it will restore every thing to normal as it was before the multitasking kernel was there. You can generate maximum up to 20 processes. After 20 processes no new process will be created if “S (both small and caps)” will be pressed from keyboard
Solution:
[org 0x0100]
jmp start
; Original Registers:
;ax, bx, cx, dx, si, di, bp, sp, ip, cs, ds, ss, es, flags
; 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26
; PCB layout:
;ax, bx, cx, dx, si, di, bp, sp, ip, cs, ds, ss, es, flags, next, dummy
; 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26 , 28 , 30
originalstate: times 14 dw 0
oldtimer: dd 0
pcb: times 20*16 dw 0 ; space for 20 PCBs
stack: times 20*256 dw 0 ; space for 20 512 byte stacks
nextpcb: dw 1 ; index of next free pcb
current: dw 0 ; index of current pcb
column_no: dw 0 ; column for next thread
chars: db '/-\|' ; shapes to form a bar
mytask:
push bp ;save registers value
mov bp, sp
push ds
push es
push di
push ax
push bx
mov ax, 0xb800
mov es, ax ; point es to video base
push cs
pop ds ; point ds to current segment
mov di, [bp+4] ; load ax with column number
shl di, 1 ; turn into byte count
and bx, 0 ; initialize bx
mov ah, 0x07 ; normal attribute
rotation:
mov al, [chars+bx] ; read current shape
mov [es:di], ax ; print at specified place
inc bx ; update for next shape
and bx, 3 ; take modulus with 4
jmp rotation ; repeat infinitely
pop di ; restore register values
pop bx
pop ax
pop es
pop ds
pop bp
ret
initpcb:
push bp ; save registers
mov bp, sp
push ax
push bx
push cx
push si
mov bx, [nextpcb] ; read next available pcb index
cmp bx, 20 ; are all PCBs used
je exit ; yes, exit
mov cl, 5
shl bx, cl ; multiply by 32 for pcb start
mov ax, [bp+8] ; read segment parameter
mov [pcb+bx+18], ax ; save in pcb space for cs
mov ax, [bp+6] ; read offset parameter
mov [pcb+bx+16], ax ; save in pcb space for ip
mov [pcb+bx+22], ds ; set stack to our segment
mov si, [nextpcb] ; read this pcb index
mov cl, 9
shl si, cl ; multiply by 512
add si, 256*2+stack ; end of stack for this thread
mov ax, [bp+4] ; read parameter for subroutine
sub si, 2 ; decrement thread stack pointer
mov [si], ax ; pushing param on thread stack
sub si, 2 ; space for return address
mov [pcb+bx+14], si ; save si in pcb space for sp
mov word [pcb+bx+26], 0x0200 ; initialize thread flags
mov ax, [pcb+28] ; read next of 0th thread in ax
mov [pcb+bx+28], ax ; set as next of new thread
mov ax, [nextpcb] ; read new thread index
mov [pcb+28], ax ; set as next of 0th thread
inc word [nextpcb] ; this pcb is now used
exit:
pop si ; restore all registers
pop cx
pop bx
pop ax
pop bp
ret 6 ;discard 3 parameters from stack
timer:
push ds
push bx
push cs
pop ds ; initialize ds to data segment
mov bx, [current] ; read index of current in bx
shl bx, 5 ; multiply by 32 for pcb start
mov [pcb+bx+0], ax ; save ax in current pcb
mov [pcb+bx+4], cx ; save cx in current pcb
mov [pcb+bx+6], dx ; save dx in current pcb
mov [pcb+bx+8], si ; save si in current pcb
mov [pcb+bx+10], di ; save di in current pcb
mov [pcb+bx+12], bp ; save bp in current pcb
mov [pcb+bx+24], es ; save es in current pcb
pop ax ; read original bx from stack
mov [pcb+bx+2], ax ; save bx in current pcb
pop ax ; read original ds from stack
mov [pcb+bx+20], ax ; save ds in current pcb
pop ax ; read original ip from stack
mov [pcb+bx+16], ax ; save ip in current pcb
pop ax ; read original cs from stack
mov [pcb+bx+18], ax ; save cs in current pcb
pop ax ; read original flags from stack
mov [pcb+bx+26], ax ; save cs in current pcb
mov [pcb+bx+22], ss ; save ss in current pcb
mov [pcb+bx+14], sp ; save sp in current pcb
mov bx, [pcb+bx+28] ; read next pcb of this pcb
mov [current], bx ; update current to new pcb
mov cl, 5
shl bx, cl ; multiply by 32 for pcb start
mov cx, [pcb+bx+4] ; read cx of new process
mov dx, [pcb+bx+6] ; read dx of new process
mov si, [pcb+bx+8] ; read si of new process
mov di, [pcb+bx+10] ; read di of new process
mov bp, [pcb+bx+12] ; read bp of new process
mov es, [pcb+bx+24] ; read es of new process
mov ss, [pcb+bx+22] ; read ss of new process
mov sp, [pcb+bx+14] ; read sp of new process
push word [pcb+bx+26] ; push flags of new process
push word [pcb+bx+18] ; push cs of new process
push word [pcb+bx+16] ; push ip of new process
push word [pcb+bx+20] ; push ds of new process
mov al, 0x20
out 0x20, al ; send EOI to PIC
mov ax, [pcb+bx+0] ; read ax of new process
mov bx, [pcb+bx+2] ; read bx of new process
pop ds ; read ds of new process
iret ; return to new process
start:
mov [originalstate], ax ; save original state
mov [originalstate +2], bx
mov [originalstate +4], cx
mov [originalstate +6], dx
mov [originalstate +8], si
mov [originalstate +10], di
mov [originalstate +12], bp
mov [originalstate +14], sp
mov [originalstate +20], ds
mov [originalstate +22], ss
mov [originalstate +24], es
pushf ; push flags on stack
pop word [originalstate +26] ; save flags register in memory
xor ax, ax ; initialize ax with zero
mov es, ax ; point es to IVT base
mov bx, [es:8*4] ; load offset of timer ISR
mov word [oldtimer], bx ; save original ISR offset
mov bx, [es:8*4+2] ; load segment of timer ISR
mov [oldtimer +2], bx ; save original ISR segment
cli ; disable all interrupts
mov word [es:8*4], timer ; hooking timer interrupt
mov [es:8*4+2], cs
sti ; enable interrupts
nextkey:
xor ah, ah ; service 0 - get keystroke
int 0x16 ; bios keyboard services
cmp al, ‘s’ ; compeare if s is pressed
je newtask ; if s is pressed go to newtask
cmp al, ‘S’ ; compeare if S is pressed
je newtask ; if S is pressed go to newtask
cmp al, ‘q’ ; compeare if q is pressed
je quit ; if q is pressed go to quit
cmp al, ‘Q’ ; compeare if Q is pressed
je quit ; if Q is pressed go to quit
jmp nextkey ; otherwise wait for next key
newtask:
push cs ; use current code segment
mov ax, mytask
push ax ; use mytask as offset
push word [column_no] ; Pushing [column_no] as thread parameter
call initpcb ; register the thread
inc word [column_no] ; increment column_no by 1
jmp nextkey ; wait for next keypress
quit:
xor ax, ax
mov es, ax ; point es to IVT base
cli ; disable interrupts
mov ax, word [oldtimer] ; load timer offset in ax
mov [es:8*4], ax ; Point IVT to original timer ISR
mov ax, word [oldtimer+2] ; load timer segment in ax
mov [es:8*4+2], ax ; Point IVT to original timer ISR
sti ; enable interrupts
mov ax, [originalstate] ; restore original state
mov bx, [originalstate +2]
mov cx, [originalstate +4]
mov dx, [originalstate +6]
mov si, [originalstate +8]
mov di, [originalstate +10]
mov bp, [originalstate +12]
mov sp, [originalstate +14]
mov ds, [originalstate +20]
mov ss, [originalstate +22]
mov es, [originalstate +24]
push word [originalstate +26]
popf ; restore flag register
mov ah, 0x4c ; DOS service to terminate program
int 0x21
1 comments:
AOA
Good Program but error this program, check it.
Post a Comment