;  -   (     )
;  sleep   (   ?)

STRUCT app
BYTE priority ; (0= )
BYTE flags ; (factive, ftimeslice, fusetimer)
factive=0 ; : SET   , RES    
ftimeslice=1
fusetimer=2
;ftimer=3
;fcritical=4 (   hl)
WORD id ; 
WORD mainpg ;   (  )
WORD curmsg ;    
WORD endmsg ;     
WORD curpg ; 
WORD sp ;   (    ( ) ,   )
WORD next ;    (      )
;[ ,     ]
ENDSTRUCT

STRUCT msg
WORD type ;  (2 )
WORD sender ;  (2 )
WORD par0
WORD par1
WORD par2
WORD par3
WORD par4
WORD par5
ENDSTRUCT
;16  (  256)

WORD Os_curapp ;()=Os_Tapp
WORD Os_nextapp ;()=Os_Tapp
WORD Isr_SP
WORD Os_frames
BYTE Os_critical
WORD Os_targetid
ARRAY Os_msg1,SIZEOF_msg
ARRAY Os_msg2,SIZEOF_msg
Os_TIMERSENDER=55555

MACRO STARTCRITICAL
ld hl,Os_critical
inc (hl) ;     ,  
ENDM

MACRO ENDCRITICAL
ld hl,Os_critical
dec (hl) ;+  
call nz,IsrEndCritical ;  IsrEndCritical  , ..    di
;   ,   
ENDM

;   
MACRO RELEASECONTEXT
ld ix,(Os_curapp)
ld hl,(curpg)
PUTWORD app_curpg,HL
ld hl,0
add hl,sp
PUTWORD app_sp,HL
ld sp,lowmem
ENDM

;   
MACRO GETCONTEXT
GETWORD HL,app_sp
push bc,hl
GETWORD HL,app_curpg
SETPG
pop hl,bc
ld sp,hl
ENDM

MACRO SETFLAG
SET \0,(IX+app_flags)
ENDM

MACRO RESFLAG
RES \0,(IX+app_flags)
ENDM

MACRO TESTFLAG
BIT \0,(IX+app_flags)
ENDM


;  , , ,  (,    )
;   -  fusetimer (   ?)
;      !
;   ftimer
;[:      (  )]
Timer
ld ix,Os_Tapp-SIZEOF_app
ld de,SIZEOF_app
Timer0
add ix,de
ld a,(ix+app_priority)
or a
ret z
TESTFLAG fusetimer
jz Timer0
SETFLAG ftimer
jr Timer0



;  ,  
Sleep
STARTCRITICAL
ld ix,(Os_curapp)
SETFLAG ftimeslice ;  
call Sched ;  (  ..)
;ld ix,(Os_curapp) ;  Sched?
RESFLAG ftimeslice ;  
ENDCRITICAL
;  
ret

IsrEndCritical
; 
;   AF,HL
dec (hl) ;1-1=0
push ...
call Isr
pop ...
; 
ret

Isr
;  ,       
ld (Isr_SP),sp
ld sp,lowmem
;       (    )
;   RS232,  .
;  RS232,    (..     RS232).
; RS232    ,   .
;     RS232,    (    )
;fcritical=0, ..   SENDMSG (  DOMSG)
call Timer
;
ld sp,(Isr_SP)
ei
ret

;   
; ,        IsrEndCritical
CriticalInt
; 
inc a ;=2
ld (Os_critical),a
;pop hl
pop af
ret ; 

OnInt
push af
;push hl
;todo  timer
;ld hl,(Os_frames)
;inc hl
;ld (Os_frames),hl
ld a,(Os_critical)
or a
jnz CriticalInt
push ...
CALL Isr ; ei
;  ,     , ..   
call Sleep
pop ...
;pop hl
pop af
ret

GetMsg
STARTCRITICAL
call Sched
;exx
;todo   Sched   ,      (  )?
ld bc,(Os_msg1+msg_par3)
ld de,(Os_msg1+msg_par4)
ld hl,(Os_msg1+msg_par5)
exx
ld bc,(Os_msg1+msg_par0)
ld de,(Os_msg1+msg_par1)
ld iy,(Os_msg1+msg_par2)
;   hl',de',bc',iy,de,bc
ld hl,(Os_msg1+msg_type) ;   !
ld ix,(Os_msg1+msg_sender) ;
push hl
ENDCRITICAL
pop hl
ret

;    bc,de,iy,bc',de',hl'
MsgGetPars
GETWORD HL,app_mainpg
SETPG
GETWORD HL,app_curmsg
ld de,Os_msg1
ld bc,15
ldir
ld a,(hl)
ld (de),a
inc l
PUTWORD app_curmsg,HL
GETWORD DE,app_endmsg
or a
sbc hl,de
ret nz ;    
RESFLAG factive ;
ret

;    ID=bc
CallTask
STARTCRITICAL
RELEASECONTEXT ; hl,ix
ld ix,(Os_curapp)
SETFLAG ftimeslice ;  ,     STARTCRITICAL  ,              
;  (  ,  )
ld ix,Os_Tapp-SIZEOF_app
ld de,SIZEOF_app
SchedGivenSearch
add ix,de
ld a,(ix+app_priority)
or a
jz SchedSearch ;   -   
GETWORD HL,app_id
;CY=0
sbc hl,bc
jnz SchedGivenSearch
;   Os_nextapp, ..         
jr SchedFound

Sched
RELEASECONTEXT ; hl,ix
SchedSearch
;call SchedFind ;  -   ix
;  /     
; -   ,   ,  
;SchedFind
LOCAL
ld ix,Os_Tapp-SIZEOF_app
ld de,(Os_nextapp) ;"  "
ld bc,SIZEOF_app
_next
add ix,bc
ld a,(ix+app_flags)
and factive|ftimeslice|ftimer
jz _next ;   ,  "  ",    - 
ld a,(de) ; /  
cp (ix+app_priority)
jnz _ok
push ix
pop hl
;or a ;CY=0
sbc hl,de
jc _next ;    - 
_ok
GETWORD HL,app_next
ld (Os_nextapp),hl ;"  "
ENDL
;ret
SchedFound
TESTFLAG ftimeslice
jnz SchedOk ; -    
TESTFLAG ftimer
jz SchedGetPars ;  ,     
;nz
RESFLAG ftimer
ld hl,Os_TIMERSENDER
ld (Os_msg1+msg_sender),hl ;,   sender
;jr SchedOk
SchedGetPars
call z,MsgGetPars
SchedOk
ld (Os_curapp),ix
GETCONTEXT ; hl, ix
ret ;


;CY=  
SendMsg
;ix - ID 
;hl -  
;bc,de,iy,bc',de',hl' - 
;      ,          ,   (    )
;     - ,    ,   
push hl
STARTCRITICAL
pop hl
;   !
ld (Os_targetid),ix ;ID 
ld (Os_msg2+msg_type),hl
GETWORD HL,app_id
ld (Os_msg2+msg_sender),hl
ld (Os_msg2+msg_par0),bc
ld (Os_msg2+msg_par1),de
ld (Os_msg2+msg_par2),iy
exx
ld (Os_msg2+msg_par3),bc
ld (Os_msg2+msg_par4),de
ld (Os_msg2+msg_par5),hl
;exx
RELEASECONTEXT ; hl,ix
;  ( ,  )
ld bc,(Os_targetid) ;ID 
ld ix,Os_Tapp-SIZEOF_app
ld de,SIZEOF_app
SendMsgSearch
add ix,de
ld a,(ix+app_priority)
or a
jz SendMsgError ;   -   
GETWORD HL,app_id
;CY=0
sbc hl,bc
jnz SendMsgSearch
;   
GETWORD HL,app_mainpg
SETPG
SendMsgLoop
;   ?
GETWORD HL,app_curmsg
GETWORD DE,app_endmsg
or a
sbc hl,de
jz SendMsgNoRoom
;  {
; 
ld hl,Os_msg2
ld bc,15
ldir
ld a,(hl)
ld (de),a
inc e
PUTWORD app_endmsg,DE
ld ix,(Os_curapp)
GETCONTEXT
ENDCRITICAL
or a ;CY=0
ret ;
SendMsgError
ld ix,(Os_curapp)
GETCONTEXT
ENDCRITICAL
scf ;CY=1
ret ;
;}
SendMsgNoRoom
;de=curmsg=endmsg
;  {
TESTBIT ftimeslice ;  ?
jnz SendMsgTimeSlice
;   {
;  
push de
exd
ld de,Os_msg1
ld bc,15
ldir
ld a,(hl)
ld (de),a
inc l
PUTWORD app_curmsg,HL
;  
pop de
ld hl,Os_msg2
ld bc,15
ldir
ld a,(hl)
ld (de),a
inc e
PUTWORD app_endmsg,DE
;  :
ld (Os_curapp),ix
; "  ",  
GETWORD HL,app_next
ld (Os_nextapp),hl
;exx
ld bc,(Os_msg1+msg_par3)
ld de,(Os_msg1+msg_par4)
ld hl,(Os_msg1+msg_par5)
exx
ld bc,(Os_msg1+msg_par0)
ld de,(Os_msg1+msg_par1)
ld iy,(Os_msg1+msg_par2)
GETCONTEXT ; hl, ix
ld hl,(Os_msg1+msg_type) ;   !
ld ix,(Os_msg1+msg_sender) ;
push hl
ENDCRITICAL
pop hl
ret ;
;}
SendMsgTimeSlice
;  {
;     
;exx
ld bc,(Os_msg2+msg_par3)
ld de,(Os_msg2+msg_par4)
ld hl,(Os_msg2+msg_par5)
exx
ld bc,(Os_msg2+msg_par0)
ld de,(Os_msg2+msg_par1)
ld iy,(Os_msg2+msg_par2)
ld ix,(Os_curapp)
GETCONTEXT ; hl, ix
ld hl,(Os_msg2+msg_type) ;   !
ld ix,(Os_targetid) ;
push hl
ENDCRITICAL
pop hl
; 
;  
;       ,        ,      -   
;,     ,   ,   !!!
;     ?
push af
push hl
push ...
push ix
pop bc ;ID 
call CallTask ;   (  ,    )
;  
pop ...
pop hl
pop af
jp SendMsg ; 
;}
;}

