📄 os_cpu_a.a51
字号:
$NOMOD51
;
; The uC/OS II port for Dallas 80C390 on Keil C51 V7
;
; Ported date: Dec 2, 2003
; By: Stuart Wright (swright@jiskoot.com)
; Target platform: Keil C51 V7.07 and above
; Based on port for 8051 by John X. Liu, China, (johnxliu@163.com)
NAME OS_CPU_A_ASM
; ?C_XBP is the simulated external stack pointer in large mode, but its origianal
; declare makes it can not be used in c files, so redeclare it in this module
; insteading of the old one
PUBLIC ?C_XBP, C_XBP ;
EXTRN CODE(_?C_OSCtxSw)
EXTRN DATA (?C_IBP)
PUBLIC LoadCtx, STACK_START, _?OSCtxSw, _?KCOSCtxSw
#include "reg52.h"
; Declare the external stack pointer by ourself, so that we can use it freely.
; you know, in the name of '?C_XBP' it can not be used in c modules but in the
; name of 'C_XBP' it can do.
DT?C_XBP SEGMENT DATA
RSEG DT?C_XBP
?C_XBP: ; These two labels point to the same address
C_XBP: ;
DS 2
; Declare a label 'Stack' in the hardware stack segment so that we know where it begins.
?STACK SEGMENT IDATA
RSEG ?STACK
STACK_START:
DS 1
LoadXBP MACRO
;MOV DPX,#0
MOV DPH, C_XBP
MOV DPL, C_XBP+1
ENDM
SaveXBP MACRO
PUSH IE
CLR EA
MOV C_XBP, DPH
MOV C_XBP+1, DPL
POP IE
ENDM
LoadREG MACRO REG
MOVX A, @DPTR
MOV REG, A
ENDM
SaveREG MACRO REG
MOV A, REG
MOVX @DPTR, A
ENDM
; The PUSHA now emulates the pushing sequence what Keil C does.
PUSHR MACRO
; IRP REG, <ACC, B, DPX, DPH, DPL, DPX1, DPH1, DPL1, DPS, PSW, 0, 1, 2, 3, 4, 5, 6, 7> ;Code for two DPTR's
;IRP REG, <ACC, B, DPX, DPH, DPL, PSW, 0, 1, 2, 3, 4, 5, 6, 7> ;Code for one DPTR ; Code for one DPTR
IRP REG, <ACC, B, DPH, DPL, PSW, 0, 1, 2, 3, 4, 5, 6, 7> ;Code for one DPTR ; Code for one DPTR
PUSH REG
ENDM
ENDM
POPR MACRO
; IRP REG, <7, 6, 5, 4, 3, 2, 1, 0, PSW, DPS, DPL1, DPH1, DPX1, DPL, DPH, DPX, B, ACC> ;Code for two DPTR's
;IRP REG, <7, 6, 5, 4, 3, 2, 1, 0, PSW, DPL, DPH, DPX, B, ACC> ;Code for one DPTR ; Code for one DPTR
IRP REG, <7, 6, 5, 4, 3, 2, 1, 0, PSW, DPL, DPH, B, ACC> ;Code for one DPTR ; Code for one DPTR
POP REG
ENDM
ENDM
; Load context from the external stack pointed by C_XBP
PUBLIC LoadCtx
PR?LoadCtx SEGMENT CODE
RSEG PR?LoadCtx
LoadCtx:
; C_IBP=*C_XBP++;
LoadXBP
LoadREG ?C_IBP
INC DPTR
; I_BP=C_IBP;
MOV R0,A
; while(I_BP)
// MOV A,I_BP
JZ LC_1
; {
; *I_BP++=*C_XBP++;
LC_0:
LoadREG @R0
INC DPTR
INC R0
MOV A,R0
JNZ LC_0
LC_1:
; SP=*C_XBP++;
LoadREG SP
INC DPTR
; I_BP=SP;
MOV R0,A
XRL A,#LOW(STACK_START-2)
JZ LC_3
LC_2:
; while(I_BP!=STACK_BOTTOM)
; MOV A,I_BP
;CJNE R0,#LOW(STACK_START-1),LC_3
; {
; *I_BP--=*C_XBP++;
LoadREG @R0
INC DPTR
DEC R0
; }
CJNE R0,#LOW(STACK_START-2),LC_2
; }
LC_3:
;CJNE R0, #LOW (_?STACK_START-1), LC_1 ;
SaveXBP ; after the hardware stack has been popped,
; the external stack pointer should be adjusted
RestoreCtx:
WANTFASTER EQU 1
$IF WANTFASTER
POP PSW ; A little bit dangerous but it works. C is PSW.7 and EA is IE.7
MOV EA, C ; They are at the same bit location of a byte.
$ELSE
POP ACC ; Safe way to do the same thing.
RLC A ;
MOV EA, C ;
$ENDIF
; Now that the context has been loaded into hardware
POPR ; stack, what we need do is just popping them upto registers.
;
RET ; Now everything is ready, a RET will bring the task to run.
; Task level context switch entry point, which is intended to be called by task gracefully.
_?OSCtxSw:
PUSHR ; Save current context first into hardware stack
PUSH IE
_?KCOSCtxSw: ; Now begin pushing hardware stack to external one
LoadXBP
; C_XBP=(unsigned int)C_XBP-((SP-STACK_BOTTOM)-(unsigned char)C_IBP+1+1);
MOV A,SP
CLR C
SUBB A,#LOW(STACK_START-2)
CLR C
SUBB A,?C_IBP
INC ACC ;for SP
INC ACC ;for C_IBP
XCH A,DPL
CLR C
SUBB A,DPL
XCH A,DPL
CLR A
XCH A,DPH
SUBB A,DPH
XCH A,DPH
SaveXBP
; *(C_XBP++)=(unsigned char)C_IBP;
SaveREG ?C_IBP
INC DPTR
; while(C_IBP)
MOV R0,?C_IBP
MOV A,R0
JZ C_S1
C_S0:
; {
; *(C_XBP++)=*(C_IBP++);pop(C_IBP) //由于从相反方向填入堆栈,所以写入方式相反
SaveREG @R0
INC R0
INC DPTR
MOV A,R0
JZ C_S1
SJMP C_S0
; }
; *(C_XBP++)=SP;
C_S1:
SaveREG SP
INC DPTR
MOV R0,A
CS_2:
; while(SP!=STACK_BOTTOM)
XRL A,#LOW(STACK_START-2)
JZ CS_4
; {
; *(C_XBP++)=*(unsigned char idata *)(SP--);
CS_3:
SaveREG @R0
INC DPTR
DEC R0
; }
CJNE R0,#LOW(STACK_START-2),CS_3
; }
CS_4:
LJMP _?C_OSCtxSw ;
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -