Thursday, December 17, 2009

MCXCALLS.S

;*****************************************************************************
;                      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