📄 os_cpu_a.asm
字号:
; SI
; BP
; SP
; BX
; DX
; CX
; AX
; OFFSET of task code address
; SEGMENT of task code address
; Flags to load in PSW (High memory)
;
; 3) The stack frame of the task to resume looks as follows:
;
; OSTCBHighRdy->OSTCBStkPtr --> DS (Low memory)
; ES
; DI
; SI
; BP
; SP
; BX
; DX
; CX
; AX
; OFFSET of task code address
; SEGMENT of task code address
; Flags to load in PSW (High memory)
;*********************************************************************************************************
funcstack .set 3
;必须检查OSIntExit()被编译器汇编的
;程序,计算其使用的堆栈个数,因为
;OSIntCtxSw()并没有用到堆栈,所以不必
;理睬。OSIntExit用到的堆栈为
;1 返回地址
;2 AR0
;3 临时变量
;每次编译后都应检查OSIntExit的汇编程序
;的头部是不是如下
;_OSIntExit:
; POPD *+
; SAR AR0,*+
; SAR AR1,*
; LARK AR0,1
; LAR AR0,*0+
;并且还要检查后面到CALL _OSIntCtxSw前
;的程序是否改变了SP(AR1)
;在CPU本身的堆栈顶是OSIntCtxSw的返回地址,
;因为不需要返回,所以丢弃,当然也可以用
;popd *指令将其丢弃,本程序未如此。
_OSIntCtxSw:; PROC FAR
;; ; Ignore calls to OSIntExit and OSIntCtxSw
;; ADD SP,8 ; (Uncomment if OS_CRITICAL_METHOD is 1, see OS_CPU.H)
; ADD SP,10 ; (Uncomment if OS_CRITICAL_METHOD is 2, see OS_CPU.H)
;;
; MOV AX, SEG _OSTCBCur ; Reload DS in case it was altered
; MOV DS, AX ;
;;
; LES BX, DWORD PTR DS:_OSTCBCur ; OSTCBCur->OSTCBStkPtr = SS:SP
; MOV ES:[BX+2], SS ;
; MOV ES:[BX+0], SP ;
;;
; CALL FAR PTR _OSTaskSwHook ; Call user defined task switch hook
;;
; MOV AX, WORD PTR DS:_OSTCBHighRdy+2 ; OSTCBCur = OSTCBHighRdy
; MOV DX, WORD PTR DS:_OSTCBHighRdy ;
; MOV WORD PTR DS:_OSTCBCur+2, AX ;
; MOV WORD PTR DS:_OSTCBCur, DX ;
;;
; MOV AL, BYTE PTR DS:_OSPrioHighRdy ; OSPrioCur = OSPrioHighRdy
; MOV BYTE PTR DS:_OSPrioCur, AL
;;
; LES BX, DWORD PTR DS:_OSTCBHighRdy ; SS:SP = OSTCBHighRdy->OSTCBStkPtr
; MOV SS, ES:[BX+2] ;
; MOV SP, ES:[BX] ;
;;
; POP DS ; Load new task's context
; POP ES ;
; POPA ;
;;
; IRET ; Return to new task
;;
sbrk funcstack
ldpk _OSTCBCur
lar ar3,_OSTCBCur
mar *,ar3
sar ar1,*,ar1
call _OSTaskSwHook
ldpk _OSTCBHighRdy
lar ar1,_OSTCBHighRdy
;ldpk _OSTCBCur
sar ar1,_OSTCBCur
lacl _OSPrioHighRdy
sacl _OSPrioCur
lar ar1,*
b I$$REST,ar1
;_OSIntCtxSw ENDP
;
; PAGE ; /*$PAGE*/
;*********************************************************************************************************
; HANDLE TICK ISR
;
; Description: This function is called 199.99 times per second or, 11 times faster than the normal DOS
; tick rate of 18.20648 Hz. Thus every 11th time, the normal DOS tick handler is called.
; This is called chaining. 10 times out of 11, however, the interrupt controller on the PC
; must be cleared to allow for the next interrupt.
;
; Arguments : none
;
; Returns : none
;
; Note(s) : The following C-like pseudo-code describe the operation being performed in the code below.
;
; Save all registers on the current task's stack;
; OSIntNesting++;
; OSTickDOSCtr--;
; if (OSTickDOSCtr == 0) {
; INT 81H; Chain into DOS every 54.925 mS
; (Interrupt will be cleared by DOS)
; } else {
; Send EOI to PIC; Clear tick interrupt by sending an End-Of-Interrupt to the 8259
; PIC (Priority Interrupt Controller)
; }
; OSTimeTick(); Notify uC/OS-II that a tick has occured
; OSIntExit(); Notify uC/OS-II about end of ISR
; Restore all registers that were save on the current task's stack;
; Return from Interrupt;
;*********************************************************************************************************
;
.ref _timesforlight
.ref _timesfortx
.ref _pivr
.ref _gptcona
.ref _evaifrb
.ref _evaifra
_OSTickISR:; PROC FAR
;;
; PUSHA ; Save interrupted task's context
; PUSH ES
; PUSH DS
;;
; MOV AX, SEG _OSTickDOSCtr ; Reload DS
; MOV DS, AX
;;
; INC BYTE PTR _OSIntNesting ; Notify uC/OS-II of ISR
;;
; DEC BYTE PTR DS:_OSTickDOSCtr
; CMP BYTE PTR DS:_OSTickDOSCtr, 0
; JNE SHORT _OSTickISR1 ; Every 11 ticks (~199.99 Hz), chain into DOS
;;
; MOV BYTE PTR DS:_OSTickDOSCtr, 11
; INT 081H ; Chain into DOS's tick ISR
; JMP SHORT _OSTickISR2
;
;_OSTickISR1:
; MOV AL, 20H ; Move EOI code into AL.
; MOV DX, 20H ; Address of 8259 PIC in DX.
; OUT DX, AL ; Send EOI to PIC if not processing DOS timer.
;;
;_OSTickISR2:
; CALL FAR PTR _OSTimeTick ; Process system tick
;;
; CALL FAR PTR _OSIntExit ; Notify uC/OS-II of end of ISR
;;
; POP DS ; Restore interrupted task's context
; POP ES
; POPA
;;
; IRET ; Return to interrupted task
;;
call I$$SAVE
ldp #_pivr;/128
lacc _pivr
ldp #_gptcona;/128
lacc #80h
sacl _evaifra
ldpk _OSIntNesting
lacc _OSIntNesting
addk 1
sacl _OSIntNesting
;the next program can be cut if no other function
;need to be execute
; .if TICKISRFOROTHERFUNC
; lacc _OSTickDOSCtr
; subk 1
; bnz _OSTickISR1
; call _OSTickISRForOther
; lacl #_TickTimesForOther
;_OSTickISR1:
; sacl _OSTickDOSCtr
; .endif
;user code
ldpk _timesfortx
lacl _timesfortx
addk 1
sacl _timesfortx
ldpk _timesforlight
lacl _timesforlight
addk 1
sacl _timesforlight
;user code
;
call _OSTimeTick
call _OSIntExit
b I$$REST
;_OSTickISR ENDP
;
.end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -