org 100h
jmp start
STACKSIZE dw 256
timer: dd 0
active1: db 1
active2: db 1
vidmem_start equ 0x0b800
default_color equ 7 ;default_color
scrw equ 80*25 ;25=lines 80=chars per line
eom equ 0
stat1 dw 0
stat2 dw 0
stasys dw 0
temp dw ?
oldIntOff: dw 0 ; old timer interrupt offset
oldIntSeg: dw 0
stacksys: rb STACKSIZE
stacksysend:
stacktask1: rb STACKSIZE
stack1end:
stacktask2: rb STACKSIZE
stack2end:
start: mov sp,stack2end
pushf
push cs
push task2
pusha
mov ax,sp
mov [stat2],ax
mov sp,stack1end
pushf
push cs
push task1
pusha
mov [stat1],sp
mov sp,stacksysend
push word [stat2]
mov bp,sp
mov [stasys],sp
mov sp,[stat1]
mov ax,0
mov gs,ax
mov ax,[gs:0x1c*4]
mov [oldIntOff],ax
mov ax,[gs:0x1c*4+2]
mov [oldIntSeg],ax
; Critical Section Start: Hook the new ISR for 0x1c
cli
mov ax,cs
mov [gs:0x1c*4+2],ax
mov ax,timer_isr
mov [gs:0x1c*4],ax
; Critical Section End: ISR is hooked
sti
main:
task1:
mov bx,vidmem_start
mov ax,0
mov ds,bx
mov di,0
mov ah,6
mov al,2
a1:
mov [ds:di],ax
inc di
mov cx,0FFh
loop $
cmp di,4000
jnz a1
mov [active1],byte 0
task1end: jmp task1end
task2: mov bx,vidmem_start
mov ax,0
mov ds,bx
mov di,3998
mov ah,6
mov al,3
a2:
mov [ds:di],ax
dec di
mov cx,0fFh
loop $
CMP di,4000
jnz a2
mov [active2],byte 0
task2end: jmp task2end
timer_isr: cmp [active1],byte 0
jnz sch
cmp [active2],byte 0
jnz sch
jmp end1
sch: push ax
mov ax,cs
mov ds,ax
inc dword [timer]
mov al,0x20
out 0x20, al
pop ax
; the task switch takes place here
pusha
mov [temp],sp
mov sp,[stasys]
push word [temp]
mov [stasys],sp
mov sp,[bp]
sub bp,2
popa
;pushf
;call FAR [oldIntOff]
iret
end1 : cli
mov ax,[oldIntOff]
mov [gs:0x1c*4],ax
mov ax,[oldIntSeg]
mov [gs:0x1c*4+2],ax
sti
int 0x21 ;
|