📄 ucos51a.asm
字号:
; ===========================================================================
; $Id: ucos51a.asm,v 1.19 1997/07/18 12:34:47 gianpi Exp $
;
; Description:
; uC/OS-51 - Assembler functions for 8051
;
; Author[s]:
; Gianpaolo Macario <gianpi@geocities.com>
;
; Language:
; BSO-Tasking ASM51 v4.0r0
; ===========================================================================
$CASE
$INCLUDE(..\MODEL)
$INCLUDE(..\MONITOR)
NAME UCOS51A
; Make LINK51 complain if memory models are mixed up
EXTRN CODE(%MODEL)
; Warning: the following extern must match
; with ucos51c.h, ucos.h:
;
extrn data(_OSTCBCur)
extrn data(_OSTCBHighRdy)
extrn code(_?OSIntEnter)
extrn code(_?OSIntExit)
?STACK SEGMENT IDATA
RSEG ?STACK
OSStack:
ds 40h
OSStkStart idata OSStack-1 ; TBD: Should use __STKSTART
;;extrn idat(__STKSTART)
OSFRAMESIZE equ 16
; -------------------------------------------------------------------------
; Macros
;
; Save current task context
;
%*DEFINE (SAVE_ALL)
(
push psw
push acc
push b
push dpl
push dph
mov a,r0
push acc
mov a,r1
push acc
mov a,r2
push acc
mov a,r3
push acc
mov a,r4
push acc
mov a,r5
push acc
mov a,r6
push acc
mov a,r7
push acc
push sp
)
; Simulate lcall @revectab[vecnum]
;
%*DEFINE (LCALL_VEC(vecnum)) LOCAL here
(
mov dptr, #revectab + (2 * %vecnum)
movx a, @dptr
xch a, b
inc dptr
movx a, @dptr
mov dph, b
mov dpl, a
mov a, #low %here
push acc
mov a, #high %here
push acc
clr a
jmp @a+dptr
%here:
)
; Restore registers and exit
;
%*DEFINE (REST_ALL)
(
pop acc ; SP: discard it
pop acc ; R7
mov r7, a
pop acc ; R6
mov r6, a
pop acc ; R5
mov r5, a
pop acc ; R4
mov r4, a
pop acc ; R3
mov r3, a
pop acc ; R2
mov r2, a
pop acc ; R1
mov r1, a
pop acc ; R0
mov r0, a
pop dph
pop dpl
pop b ; B
pop acc ; ACC
pop psw ; PSW
)
%*DEFINE (UCOS51_ISR(vecnum, label))
(
public %label
%label:
%SAVE_ALL
lcall _?OSIntEnter
%LCALL_VEC(%vecnum)
lcall _?OSIntExit
ljmp popall3
)
; -------------------------------------------------------------------------
; Start Multitasking
;
; void OSStartHighRdy(void)
UCOS51A_OSSTARTHIGHRDY_PR SEGMENT CODE
RSEG UCOS51A_OSSTARTHIGHRDY_PR
public _?OSStartHighRdy
_?OSStartHighRdy:
mov dph, _OSTCBHighRdy+0 ; Get highest prio. task
mov dpl, _OSTCBHighRdy+1
mov _OSTCBCur+0, dph ; OSTCBCur = OSTCBHighRdy
mov _OSTCBCur+1, dpl
movx a, @dptr ; stk = OSTCBCur->StkPtr
mov r0, a
inc dptr
movx a, @dptr
mov r1, a ; R0,1 = stk
mov dph, r0
mov dpl, r1
movx a, @dptr ; Get User Stack Ptr (*stk)
add a, #OSFRAMESIZE
mov r5, a ; R5 = #bytes to copy
mov r4, a ; R4 = count
mov a, dpl
clr c
subb a, r5
mov r3, a
mov a, dph
subb a, #0
mov r2, a ; R2,R3 = srcptr - 1
mov dph, r2
mov dpl, r3 ; DPTR = srcptr - 1
; Copy R5 bytes from *stk to OSStack
mov a, #OSStkStart ; R1 = destptr - 1
mov R1, a
copystk1:
inc dptr
inc R1
movx a, @dptr
mov @R1, a
djnz R4, copystk1
; Now R1 is the new task SP
mov sp, r1
; Pop all user register from task stack
popall:
%REST_ALL
setb ea ; Enable interrupts again
ret ; PCH,PCL (DBG: was reti!)
; -------------------------------------------------------------------------
; Perform a context switch (from task level)
;
; void OSCtxSw(void)
UCOS51A_OSCTXSW_PR SEGMENT CODE
RSEG UCOS51A_OSCTXSW_PR
public _?OSCtxSw
_?OSCtxSw:
%SAVE_ALL
mov dph, _OSTCBCur+0 ; Save stack ptr in TCB
mov dpl, _OSTCBCur+1
movx a, @dptr ; stk = OSTCBCur->StkPtr
mov r0, a
inc dptr
movx a, @dptr
mov r1, a ; R0,1 = stk (40B2)
mov dph, r0
mov dpl, r1
movx a, @dptr ; ? 3A
add a, #OSFRAMESIZE ; ? 04 + 10 = 14
mov r2, a ; R2 = *stk - #OSSTACK + #OSFRAMESIZE
mov a, r1
clr c
subb a, r2
mov dpl, a
mov a, r0
subb a, #0
mov dph, a ; ? DPTR = 409E
; DPTR now points to the beginning of the user stack-1
mov a, sp
clr c
subb a, #OSStkStart
mov r5, a ; R5 = #bytes to copy
mov r4, a ; R4 = count
; Copy R5 bytes from OSStack to stk
mov a, #OSStkStart
mov R1, a ; R1= #OSStack - 1
savestk2:
inc r1
inc dptr
mov a, @r1
movx @dptr, a
djnz R4, savestk2
;
mov a, r1
clr c
subb a, #OSStkStart
clr c
subb a, #OSFRAMESIZE
;
movx @dptr, a ; Fix SP in user stack
mov r0, dph ; R0,1 = stk
mov r1, dpl
;
mov dph, _OSTCBCur+0 ; OSTCBCur->OSTCBStkPtr = stk
mov dpl, _OSTCBCur+1
mov a, r0
movx @dptr, a
inc dptr
mov a, r1
movx @dptr, a
; Point to HI Prio. Task Rdy
;
ljmp _?OSStartHighRdy
; -------------------------------------------------------------------------
; Perform a context switch (from an ISR)
;
; void OSIntCtxSw(void)
UCOS51A_OSINTCTXSW_PR SEGMENT CODE
RSEG UCOS51A_OSINTCTXSW_PR
public _?OSIntCtxSw
_?OSIntCtxSw:
; Ignore data in stack:
; - call to OSIntExit (2 bytes)
; - call to OSIntCtxSw (2 bytes)
; - locals (0 bytes)
mov a, sp
clr c
subb a, #4
mov sp, a
;
OSStHRr2: ; Modeled after OSStartHighRdy
mov dph, _OSTCBHighRdy+0 ; Get highest prio. task
mov dpl, _OSTCBHighRdy+1
mov _OSTCBCur+0, dph ; OSTCBCur = OSTCBHighRdy
mov _OSTCBCur+1, dpl
movx a, @dptr ; stk = OSTCBCur->StkPtr
mov r0, a
inc dptr
movx a, @dptr
mov r1, a ; R0,1 = stk
mov dph, r0
mov dpl, r1
movx a, @dptr ; Get User Stack Ptr (*stk)
add a, #OSFRAMESIZE
mov r5, a ; R5 = #bytes to copy
mov r4, a ; R4 = count
mov a, dpl
clr c
subb a, r5
mov r3, a
mov a, dph
subb a, #0
mov r2, a ; R2,R3 = srcptr - 1
mov dph, r2
mov dpl, r3 ; DPTR = srcptr - 1
; Copy R5 bytes from *stk to OSStack
mov a, #OSStkStart ; R1 = destptr - 1
mov R1, a
copystk2:
inc dptr
inc R1
movx a, @dptr
mov @R1, a
djnz R4, copystk2
; Now R1 is the new task SP
mov sp, r1
; Pop all user register from task stack
popall3:
%REST_ALL
setb ea ; Enable interrupts again (?)
reti ; PCH,PCL
; -------------------------------------------------------------------------
; Revector Hardware Interrupts
;
%IF( %EQS(%PAULMON,RAM) ) THEN (
INTVECT_LOC EQU 8000h ; PAULMON-RAM
) ELSE (
%IF( %EQS(%PAULMON,ROM)) THEN (
INTVECT_LOC EQU 0000h ; PAULMON-ROM
) ELSE (
INTVECT_LOC EQU 0000h ; Application without monitor
) FI
) FI
CSEG AT INTVECT_LOC+0003h ; IE0
ljmp __CIH00
CSEG AT INTVECT_LOC+000Bh ; TF0
ljmp __CIH01
; CSEG AT INTVECT_LOC+0013h ; IE1
; ljmp __CIH02
; CSEG AT INTVECT_LOC+001Bh ; TF1
; ljmp __CIH03
CSEG AT INTVECT_LOC+0023h ; RI_TI
ljmp __CIH04
; CSEG AT INTVECT_LOC+002Bh ; UNK5
; ljmp __CIH05
; CSEG AT INTVECT_LOC+0033h ; UNK6
; ljmp __CIH06
; CSEG AT INTVECT_LOC+003Bh ; UNK7
; ljmp __CIH07
; -------------------------------------------------------------------------
; Interrupt Service Routines
UCOS51A_ISR_PR SEGMENT CODE
RSEG UCOS51A_ISR_PR
; Interrupt 0 (INT_IE0) Service Routine
%UCOS51_ISR(0, __CIH00)
; Interrupt 1 (INT_TF0) Service Routine
%UCOS51_ISR(1, __CIH01)
; Interrupt 2 (INT_IE1) Service Routine
%UCOS51_ISR(2, __CIH02)
; Interrupt 3 (INT_TF1) Service Routine
%UCOS51_ISR(3, __CIH03)
; Interrupt 4 (INT_RI_TI) Service Routine
%UCOS51_ISR(4, __CIH04)
; Interrupt 5 (INT_UNK5) Service Routine
%UCOS51_ISR(5, __CIH05)
; Interrupt 6 (INT_UNK6) Service Routine
%UCOS51_ISR(6, __CIH06)
; Interrupt 7 (INT_UNK7) Service Routine
%UCOS51_ISR(7, __CIH07)
; -------------------------------------------------------------------------
; Table of vectors in RAM
;
UCOS51A_XD SEGMENT XDATA
RSEG UCOS51A_XD
revectab:
ds 2 ; vector of CIH00
ds 2 ; vector of CIH01
ds 2 ; vector of CIH02
ds 2 ; vector of CIH03
ds 2 ; vector of CIH04
ds 2 ; vector of CIH05
ds 2 ; vector of CIH07
; -------------------------------------------------------------------------
; Return current interrupt vector
;
; C prototype:
; FUNC_PTR getvect(u_int8_t vecnum)
;
UCOS51A_GETVECT_PR SEGMENT CODE
RSEG UCOS51A_GETVECT_PR
public _?getvect
_?getvect:
mov a, r7 ; get vecnum
anl a, #07h ; just make sure
rl a ; multiply by 2
mov dph, #high revectab
mov dpl, #low revectab
add a, dpl
mov dpl, a
mov a, dph
addc a, #0
mov dph, a ; dptr = #revectab + (2 * vecnum)
movx a, @dptr
mov r6, a ; High(result)
inc dptr
movx a, @dptr
mov r7, a ; Low(result)
ret
; -------------------------------------------------------------------------
; Change interrupt vector
;
; C prototype:
; void setvect(u_int8_t vecnum, FUNC_PTR newfunc)
;
UCOS51A_SETVECT_PR SEGMENT CODE
RSEG UCOS51A_SETVECT_PR
public _?setvect
_?setvect:
mov a, r7 ; get vecnum
anl a, #07h ; just make sure
rl a ; multiply by 2
mov dph, #high revectab
mov dpl, #low revectab
add a, dpl
mov dpl, a
mov a, dph
addc a, #0
mov dph, a ; dptr = #revectab + (2 * vecnum)
mov a, r4 ; High(newfunc)
movx @dptr, a
inc dptr
mov a, r5 ; Low(newfunc)
movx @dptr, a
ret
; -------------------------------------------------------------------------
; end of program
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -