;*****************************************************************************
; INTERFACE WhiteSmith to MCX-16
; ------------------------------
; Platform : Motorola 68HC16 running MCX16 Multitasking Executive
; Compiler : Whitesmith C
;
; (c) M. Lutfi Shahab (13389011)
; Instrumentation and Control Labs.
; Department of Engineering Physics
; Institut Teknologi Bandung (ITB)
;
; Created : 13 Apr 1995
; Updated : 5 May 1995
;
;Interface Spec.
;---------------
; In WSC:
; - The default memory model is the COMPACT model, in which all of
; the code and data must share the same 64K area.
; - Type SHORT INT are stored as two bytes, MSB first
; - Type LONG INTEGER are stored as four bytes, in descending order of
; significance.
; - Type FLOAT are represented in specific format adapted to the M68HC16
; processor, is a 4 bytes of data; the first two bytes contain a signed
; mantissa coding real values in the interval [-1.0,1.0]. The other 2
; bytes contain signed exponent. If the first word is zero, the entire
; number will be understood 0.0. The value of the number is the fraction
; multiplied by 2 raised to the exponent. The mantissa is then compatible
; with the internal DSP processor format.
; - Type DOUBLE are represented as for the proposed IEEE-754 floating point
; standard; 8 bytes stored in descending order of byte significance:
; * MSB bit is one of four negative numbers, and zero otherwise.
; * next 8 bits are the characteristic, biased such that the binary
; exponent of the number is the characteristic minus 1002.
; * the remaining bits are the fraction, starting with the weighted bit.
; - Arguments are moved onto the stack from right to left. The first
; argument is stored in the D register if its size is less than or equal
; to the size of an int, or in the register pair E, D if it is a long
; or float, and in the function doesn't return a struct or a double.
; - By default, character data is sign extended to short, and floats are
; extended to doubles.
; - The function is called via jsr _func or jbsr _func.
; - The arguments to the function are popped off the stack.
; - A data space address is move onto stack if a struct or double return
; area is required.
; - The return value is in D register (if length less than 2 bytes), or
; is in the registers E,D (the D register holds the low order bits).
; The addresses of double and struct data are added on stack at call time.
; - Each C function maintains its own stack frame, using IX as frame pointer.
; - You must save an restore the K register if want to call an assembly
; language routine that modifies the EK, XK, YK, or ZK registers.
; - BSR does these microcode sequences:
; 1. put PC to stack
; 2. SP = SP-2
; 3. put CCR to stack
; 4. SP = SP-2
; so SP (now) = SP (before bsr) + 4
;
; - XK, YK, ZK and SK can be modified by using the transfer index register
; to stack pointer and transfer stack pointer to index register instructions.
; When SP is transfered to (TSX, TSY, and TSZ) or from (TXS, TSY, TSZ) an
; index register, the corresponding address extension fields is also
; transfered. Before the extension field is transfered, it is incremented
; or decremented if bank overflow occured as a result of the instruction.
;
; NOTE
; > Be aware of invoking these routines. Make sure you have
; set extension register (K) to a proper value, otherwise the system
; will crash.
;*****************************************************************************/
.PROCESSOR M68HC16
.TITLE "Thesis Project : WSC -> MCX calling translation"
.INCLUDE "mcx16.mac"
.psect _text
.even
.LIST + .MACRO
;* below are calling codes to MCX-16 *
;-----------------------------------
; __mcx_nop
;
; cycles=14
; code = 4 bytes
;----------------------------------
.PUBLIC __mcx_nop
__mcx_nop:
MCX_CALL MCX_NOP_
rts
;------------------------------------------------------
;* Force a semaphore to PENDing state*
; Narrative:
; WSC:
; void _mcx_pend(int sema)
; sema passed to D (ACCB = lo(sema), ACCA = hi(sema))
;
; MCX:
; parameters:
; ACCA = code for _mcx_pend = 3
; ACCB = semaphore number
; return:
; none
;
; cycles = 14
; code = 6 bytes
;------------------------------------------------------
.even
.PUBLIC __mcx_pend
__mcx_pend:
MCX_CALL MCX_PEND_
rts
;--------------------------------------------------
; * Signal the occurence of an event.
; Narrative:
; WSC:
; void _mcx_signal(int sema)
; ACCD = sema
;
; MCX:
; parameters:
; ACCA = code for mcx_signal = 1
; ACCB = semaphore number
; return:
; none
;
; cycles = 14
; code = 6 bytes
;--------------------------------------------------
.even
.PUBLIC __mcx_signal
__mcx_signal:
MCX_CALL MCX_SIGNAL_ ;* Signal semaphore *
rts
;------------------------------------------------------
; * Make a task wait for the occurence of a specified
; event
; Narrative:
; WSC:
; int _mcx_wait(int sema)
; on call, sema in D register
;
; MCX:
; parameters:
; ACCA = code for _mcx_wait = 2
; ACCB = semaphore number
; return:
; ACCA, 0 = success, 1 = fail
;
; cycles = 16
; code = 8 bytes
;------------------------------------------------------
.even
.PUBLIC __mcx_wait
__mcx_wait:
MCX_CALL MCX_WAIT_ ;* Wait on event *
clrb
rts
;------------------------------------------------------
;* Signal completion of message processing*
; Narrative:
; WSC:
; void _mcx_msg_done(void *msg)
; msg passed to D
;
; MCX:
; parameters:
; ACCA = code for _mcx_msg_done = 18
; IX = message address
; return:
; none
;
; cycles = 28
; code = 12 bytes
;------------------------------------------------------
.even
.PUBLIC __mcx_msg_done
__mcx_msg_done:
pshm x ; save stack frame
xgdx ; IX = msg
MCX_CALL MCX_MSG_DONE_
pulm x ; restore old IX (stack frame)
rts
;------------------------------------------------------
;* Fetch message from a mailbox
; Narrative:
; WSC:
; void *_mcx_receive(int mbx)
; mbx passed to D
; return:
; D = address of the received message
;
; MCX:
; parameters:
; ACCA = code for _mcx_receive = 16
; ACCB = mailbox number
; return:
; IX = address of received message
;
; cycles = 28
; code = 12 bytes
;------------------------------------------------------
.even
.PUBLIC __mcx_receive
__mcx_receive:
pshm x ; save stack frame
MCX_CALL MCX_RECEIVE_
xgdx ; D contain address of msg
pulm x ; restore stack frame
rts
;------------------------------------------------------
;* Fetch message from a mailbox with wait directive
;
; Narrative:
; WSC:
; void *_mcx_receive_w(int mbx)
; mbx passed to D
; return:
; ACCD = address of the received message
;
; MCX:
; parameters:
; ACCA = code for _mcx_receive_w = 17
; ACCB = mailbox number
; return:
; IX = address of the received message
;
; cycles = 28
; code = 12 bytes
;------------------------------------------------------
.even
.PUBLIC __mcx_receive_w
__mcx_receive_w:
pshm x ; save stack frame
MCX_CALL MCX_RECEIVE_W_
xgdx ; D = address of received msg
pulm x ; restore stack frame
rts
;-------------------------------------------------------
;* send message MSG into target MAILBOX
; with SEMA semaphore
; Narrative:
; WSC:
; void _mcx_send_mbx(int mbx, void *msg, int sema)
; mbx in D
; msg in [SP+6]
; sema in [SP+8]
;
; MCX:
; parameters:
; ACCA = code for _mcx_send_mbx = 14
; ACCB = message semaphore number (sema)
; ACCE = mailbox number to receive message (mbx)
; IX = message address
; return:
; none
;
; cycles = 14
; code = 18 bytes
;-------------------------------------------------------
.even
.PUBLIC __mcx_send_mbx
__mcx_send_mbx:
pshm x ; save old stack frame because IX used by MCX
tsz ; Z = SP + 2
xgde ; E = mbx
ldd 8,z ; D = sema
ldx 6,z ; IX = msg
mcx_call MCX_SENDMBX_
; accb = sema, acca = 14
pulm x
rts
;-------------------------------------------------------
;* send message MSG into target MAILBOX
; with SEMA semaphore and wait directive
; Narrative:
; WSC:
; void _mcx_send_mbx_w(int mbx, void *msg, int sema)
; mbx in D
; msg in [SP+6]
; sema in [SP+8]
;
; MCX:
; parameters:
; ACCA = code for _mcx_send_mbx_w = 15
; ACCB = message semaphore number
; ACCE = mailbox number to receive message
; IX = message address
; return:
; none
;
; cycles =
; code = 18 bytes
;-------------------------------------------------------
.even
.PUBLIC __mcx_send_mbx_w
__mcx_send_mbx_w:
pshm x ; save old stack frame because IX used by MCX
tsz ; Z = SP + 2
xgde ; E = mbx
ldd 8,z ; D = sema
ldx 6,z ; IX = msg
MCX_CALL MCX_SENDMBX_W_
; accb = sema, acca = 15
pulm x
rts
;-------------------------------------------------------
;* Get the oldest entry from a FIFO queue
; Narrative:
; int _mcx_dequeue(int queue, void *ptr)
; queue in D
; ptr in [SP+6]
; return: ACCD
;
; parameters to mcx:
; ACCA = code for mcx_dequeue = 12
; ACCB = queue number
; IX = destination address of entry
; return:
; ACCA = 0, if queue was empty
; 1, if entry dequeued successfully other
;
; cycles =
; code = 16 bytes
;-------------------------------------------------------
.even
.PUBLIC __mcx_dequeue
__mcx_dequeue:
pshm x
tsz ;
ldx 6,z ; IX = ptr
; ACCD hold queue number, so we just set ACCA
MCX_CALL MCX_DEQUEUE_
pulm x
clrb
rts
;-------------------------------------------------------
;* Get the oldest entry from a FIFO queue. If queue
; empty, wait until queue not empty
; Narrative:
; int _mcx_dequeue_w(int queue, void *ptr)
; queue in ACCD
; ptr in [SP+6]
;
; parameters to mcx:
; ACCA = code for mcx_dequeue_w = 13
; ACCB = queue number
; IX = destination address of entry
; return:
; ACCA = 0, if queue was empty
; = 1, if dequeue was successful
;
; cyles =
; code = 16 bytes
;-------------------------------------------------------
.even
.PUBLIC __mcx_dequeue_w
__mcx_dequeue_w:
pshm x
tsz
ldx 6,z ; IX = ptr
; ACCD hold queue number, so we just set ACCA
MCX_CALL MCX_DEQUEUE_W_
pulm x
clrb ; ACCD = return value of mcx_dequeue_w
rts
;-------------------------------------------------------
;* Put an entry to a FIFO queue.
;
; Narrative:
; int _mcx_enqueue(int queue, void *ptr)
; queue in D
; ptr in [SP+6]
; return: ACCD
;
; parameters to mcx:
; ACCA = code for mcx_dequeue_w = 10
; ACCB = queue number
; IX = destination address of entry
; return:
; ACCA = 0, if queue was empty
; = 1, if dequeue was successful
;
; cycles =
; code = 16 bytes
;-------------------------------------------------------
.even
.PUBLIC __mcx_enqueue
__mcx_enqueue:
pshm x
tsz ; Z = SP + 2
ldx 6,z ; IX = ptr
; ACCD hold queue number, so we just set ACCA
MCX_CALL MCX_ENQUEUE_
pulm x
clrb
rts
;-------------------------------------------------------
;* Put an entry to a FIFO queue and wait if empty.
; Narrative:
; int _mcx_enqueue_w(int queue, void *ptr)
; queue in ACCD
; ptr in [SP+6]
; return: ACCD
;
; parameters to mcx:
; ACCA = code for mcx_dequeue_w = 11
; ACCB = queue number
; IX = source address of entry
; return:
; ACCA = 0, if queue successful
; = 1, if empty
;
; cycles =
; code = 16 bytes
;-------------------------------------------------------
.even
.PUBLIC __mcx_enqueue_w
__mcx_enqueue_w:
pshm x
tsz ; Z = SP + 2
ldx 6,z ; IX = ptr
; ACCD hold queue number, so we just set ACCA
MCX_CALL MCX_ENQUEUE_W_
pulm x
clrb
rts
;-------------------------------------------------------
;* Change the priority of a task *
; Narrative:
; void _mcx_change_pri(int task, priority)
; ACCD = task number
; [SP+6] = priority
;
; parameters:
; ACCA = code for _mcx_execute = 9
; ACCB = task number
; ACCE = task priority
;
; return:
; none
;
; cycles =
; code = 12 bytes
;-------------------------------------------------------
.even
.PUBLIC __mcx_change_pri
__mcx_change_pri:
tsz ; Z = SP + 2
lde 6,z ; E = priority
; ACCD hold task address, so we just set ACCA
MCX_CALL MCX_CHANGE_PRI_
rts
;-------------------------------------------------------
;* Excecute a task *
; Narrative:
; void _mcx_execute(int tsk_num, priority, (void *)(task)(),
; void *stack_ptr, void *reg_init_ptr)
; tsk_num = ACCD
; reg_init_ptr = [SP +12]
; stack_ptr = [SP +10]
; task address = [SP + 8]
; priority = [SP + 6]
;
; parameters:
; ACCA = code for _mcx_execute = 4
; ACCB = task number
; ACCE = task priority
; IX = starting address of task
; IY = base address of task's stack
; IZ = address of register initialization packet
; (IZ=0 means no packet)
; return:
; none
;
; cycles =
; code = 22 bytes
;-------------------------------------------------------
.even
.PUBLIC __mcx_execute
__mcx_execute:
pshm x
tsz ; Z = SP + 2
; ACCD = task number
lde 6,z ; ACCE = task priority
ldx 8,z ; IX = task
ldy 10,z ; IY = stack
ldz 12,z ; IZ = reg_init_pkt
MCX_CALL MCX_EXECUTE_
;* Execute a task *
pulm x
rts
;-------------------------------------------------------
;* Clears the suspend state of task
;
; Narrative:
; WSC:
; void _mcx_resume(int task_num)
; ACCD = task_num
;
; MCX:
; parameters:
; ACCA = code for _mcx_resume = 7
; ACCB = task number
;
; return:
; none
;
; cycles =
; code = 6 bytes
;-------------------------------------------------------
.even
.PUBLIC __mcx_resume
__mcx_resume:
; ACCB = task number
MCX_CALL MCX_RESUME_
rts
;-------------------------------------------------------
;* Blocks the specified task with a SUSPEND condition
; Narrative:
; WSC:
; void _mcx_suspend(int task_num)
; ACCD = task_num
;
; MCX:
; parameters:
; ACCA = code for _mcx_suspend = 6
; ACCB = task number (0= SELF)
; return:
; none
;
; cycles =
; code = 6 bytes
;-------------------------------------------------------
.even
.PUBLIC __mcx_suspend
__mcx_suspend:
; ACCB = task number
MCX_CALL MCX_SUSPEND_
rts
;-------------------------------------------------------
;* Terminate a task's operation
;
; Narrative:
; WSC:
; void _mcx_terminate(int task_num)
; ACCD = task_num
;
; MCX:
; parameters:
; ACCA = code for _mcx_resume = 5
; ACCB = task number
;
; return:
; none
;
; cycles =
; code = 6 bytes
;-------------------------------------------------------
.even
.PUBLIC __mcx_terminate
__mcx_terminate:
; ACCB = task number
MCX_CALL MCX_TERMINATE_
rts
;-------------------------------------------------------
;* Blocks specified task with a DELAYED state for the
; period
; Narrative:
; WSC:
; void _mcx_delay(int task_num, int tick)
; ACCD = task_num
; [SP+6] = tick
;
; MCX:
; parameters:
; ACCA = code for _mcx_delay = 8
; ACCB = task number (0= SELF)
; ACCE = number of clock ticks to delay
; return:
; none
;
; cycles =
; code = 16 bytes
;-------------------------------------------------------
.even
.PUBLIC __mcx_delay
__mcx_delay:
; ACCB = task number
tsz
lde 6,z ; ACCE = tick
MCX_CALL MCX_DELAY_
rts
;-------------------------------------------------------
;* Stop a timer whose handle is specified by ptr
; Narrative:
; WSC:
; void _mcx_kill_timer(void *tick_handler)
; ACCD = tick_handler
;
; MCX:
; parameters:
; ACCA = code for _mcx_kill_timer = 20
; ACCE = Handle of timer to be killed
; return:
; none
;
; cycles =
; code = 10 bytes
;-------------------------------------------------------
.even
.PUBLIC __mcx_kill_timer
__mcx_kill_timer:
tsz
xgde ; ACCE = tick handler
MCX_CALL MCX_KILL_TIMER_
rts
;-------------------------------------------------------
;* Stop a active timer and reset its duration to a new
; value
; Narrative:
; WSC:
; void _mcx_reset_t(void *hndr, int tick)
; ACCD = hndlr
; [SP+6] = tick
;
; MCX:
; parameters:
; ACCA = code for _mcx_delay = 21
; ACCE = Handle of timer to be reset
; IX = duration of timer's initial period
; return:
; none
;
; cycles =
; code = 16 bytes
;-------------------------------------------------------
.even
.PUBLIC __mcx_reset_t
__mcx_reset_t:
; ACCB = task number
pshm x
tsz
xgde ; ACCE = tick handler
ldx 6,z ; tick
MCX_CALL MCX_RESET_T_
pulm x
rts
;-------------------------------------------------------
;* Stop a active timer and reset its duration to a new
; value
; Narrative:
; WSC:
; void *_mcx_timer(int init_t, int recyle_t, int sema)
; ACCD = init_t
; [SP+6] = recyle_t
; [SP+8] = sema
; return: ACCD
;
; MCX:
; parameters:
; ACCA = code for _mcx_timer = 19
; ACCB = semaphore number
; ACCE = Duration of initial period
; IX = duration of recycle time
; return:
; ADDE = handle of timer if it was established
; = 0, if there were no timer blocks available
; in the pool of free timers.
;
; cycles =
; code = 20 bytes
;-------------------------------------------------------
.even
.PUBLIC __mcx_timer
__mcx_timer:
pshm x
tsz ; z = SP
xgde ; ACCE = init_t
ldd 8,z ; ACCD = sema = [SP+8]
ldx 6,z ; IX = recycle_t = [SP+6]
MCX_CALL MCX_TIMER_
pulm x
ted ; ACCD = handle of timer
rts
.END
No comments:
Post a Comment