This first part of the OS-9 level 2 kernel (OS9p1) provides essential system calls that make up the operating system allowing proper task administration, memory management, etc.
Comparing the OS9p1 used for the CMS9639 with standard OS9p1 code it is clear that there are three low-level functions that have changed. All three are involved with moving data between tasks and in the case of the CMS9639 the memory-to-memory DMA facility is used even if there is only one byte to be moved.
Here, we don't consider changes in setting up/checking memory and the Data Address Translator (DAT, key part of the MMU) initialisation since these would be different for any system.
The changes are found in the code for Mover(00)/MoveRegs, PutRegs and STABX/LDABX (using source code labels). Below the difference between standard and CMS9639 is shown for PutRegs, which copies registers between tasks.
Below we compare PutRegs:
CMS9639:
************************************************************ * * Subroutine PutRegs * * Copy User interrupt register stack * * Input: X = Process Descriptor ptr * U = local stack ptr * * Output: none * * Data: none * * Calls: uses DMA to copy register stack * PutRegs ldb P$Task,X get process task andb #^SysTask clra pshs u,x,cc ldx P$SP,X get process stack ptr exg x,u switch source & destination PutReg.A equ * orcc #IntMasks sta >Tsk.Src Task to copy from stx >$FFC0 DMAC source address register stu >$FFC4 DMAC destination address register ldx #R$Size stx >$FFC2 DMAC Source byte count register stx >$FFC6 DMAC Destination byte count register stb >Tsk.Dst Task to copy to ldb #$03 stb >ContrlSW send command nop puls pc,u,x,cc
Standard:
************************************************************ * * Subroutine PutRegs * * Copy User interrupt register stack * * Input: X = Process Descriptor ptr * U = local stack ptr * * Output: none * * Data: none * * Calls: MoveRegs * PutRegs ldb P$Task,x get process task lda D.SysTsk get system stack pshs u,y,x,DP,D,CC save registers ldx P$SP,x get process stack ptr exg x,u switch source & destination PutReg.A equ * ldy #R$Size/2 get double byte count tfr B,DP copy process task orcc #IntMasks set interrupt masks lbra MoveRegs
Mover10 lda 1,s get source task number orcc #IntMasks set interrupt masks MoveRegs sta DAT.Task set source task ldd ,x++ get data double byte exg b,dp switch data & task stb DAT.Task exg b,dp switch back std ,u++ Mover30 lda #SysTask get system task sta DAT.Task set system task lda 0,s get previous masks tfr a,cc reset interrupt masks leay -1,y count double byte bne Mover10 branch if more puls pc,u,y,x,dp,d,cc
The DMA version essentially uploads source and destination information and moves bytes during DMA just after 3 is written to the ControlSwitch (ARM DMA). Task switching is automatic between source and destination.
For the standard case there is changing of task needed for every (double)byte. R$Size is the number of bytes to move.
Apart from the data moving routines there is one further CMS9639 specific change that is at the heart of system calls. System calls use a SWI2 software interrupt followed by a PostByte which indicates what system call is to be performed. Normally software collects the PostByte from user space and increments the program counter to skip the PostByte upon return. The CMS9639 has a dedicated circuit that captures the PostByte and places it in memory location $FFFA0. It also increments the program counter before placing it on the stack.
In the snippet from OS9p1 this process can be found in detail for both cases using conditional assembly:
************************************************************ * * System Service Request Routine * * Process system service requests * * Input: S = value of stack after interrupt * * Output: none * * Data: D.SysDis, D.SysPrc * * Calls: Dispatch, SysRet * SysSvc leau 0,s get registers ptr ifeq CPUType-CMS9639 ldb Postbyte get service code lda R$CC,u get caller's interrupt masks tfr a,cc restore interrupt masks else lda R$CC,u get caller's interrupt masks tfr a,cc restore interrupt masks ldx R$PC,u get program counter ldb ,x+ get service code stx R$PC,u update program counter endc ldy D.SysDis get system dispatch table ptr bsr Dispatch dispatch to service routine lbra SysRet
roelof4
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.