;*******************************************************************************
;* Include   : COROUTINE.INC
;* Programmer: Tony Papadimitriou <tonyp@acm.org>
;* Purpose   : Example macro for simple coroutine switching
;* Language  : Freescale HC08/9S08 Assembly Language (aspisys.com/ASM8 v9.65+)
;* Status    : FREEWARE Copyright (c) 2015 by Tony Papadimitriou <tonyp@acm.org>
;* Original  : http://www.aspisys.com/code/hc08/coroutine.html
;* Note(s)   : Use: #Uses    coroutine.inc
;*******************************************************************************

#ifmain ;-----------------------------------------------------------------------
                    #ListOff
                    #Uses     mcu.inc
                    #ListOn
#endif ;------------------------------------------------------------------------

;*******************************************************************************
; Macro to start a coroutine (done first), or switch between two (done next)

CoCall              macro     [CoroutineAddress]
          #ifparm ~@~
                    mreq      1:CoroutineAddress
                    !jsr      ~#1~
                    mexit
          #endif
                    #push
                    ais       #-2
                    pshhx
                    ldhx      5,asp               ;;caller PC ...
                    sthx      3,asp               ;;... into placeholder
                    ldhx      #Return$$$          ;;return address ...
                    sthx      5,asp               ;;... into caller PC
                    pulhx
                    RTS                           ;;switch to coroutine
                    #pull
Return$$$
                    endm

;*******************************************************************************
                    #Exit
;*******************************************************************************

Start               proc
                    @rsp
                    clra                          ;(keeps simulator happy)

                    @cocall   CoroutineA

Done@@              @cop
                    bra       Done@@

;*******************************************************************************

CoroutineA          proc
                    @cocall   CoroutineB
                    nop
                    @cocall
                    nop
                    @cocall
                    nop
                    rts

;*******************************************************************************

CoroutineB          proc
                    @cocall
                    nop
                    @cocall
                    nop
                    @cocall   CoroutineC
                    nop
                    @cocall
                    nop
                    @cocall
                    nop
                    @cocall
                    nop
                    rts

;*******************************************************************************

CoroutineC          proc
                    @cocall
                    nop
                    @cocall
                    nop
                    rts

;*******************************************************************************
                    @vector   Vreset,Start
;*******************************************************************************