;******************************************************************************* ;* Module : BRIF.SUB ;* Programmer: Tony Papadimitriou <tonyp@acm.org> ;* Purpose : Example for BRSET equivalent using macro/subroutine combination ;* Language : Motorola/Freescale/NXP HC08/9S08 Assembly Language (aspisys.com/ASM8) ;* Status : FREEWARE Copyright (c) 2021 by Tony Papadimitriou <tonyp@acm.org> ;* Original : http://www.aspisys.com/code/hc08/brif.html ;* Note(s) : Use: #Include brif.sub ;******************************************************************************* #ifmain ;----------------------------------------------------------------------- #ListOff #Uses mcu.inc #ListOn #MapOff #ROM #endif ;------------------------------------------------------------------------ ?_OBJECT_? ;******************************************************************************* ; Purpose: BRSET for use with extended addresses ; Input : Words following BSR/JSR/CALL instruction: ; : Offset 0 = Branch Address ; : Offset 2 = BitPos (15..13) & Variable Address (12..0) ; Output : None BRIFSET macro BitPos,Variable,BranchAddress mreq 1,2,3:BitPos,Variable,BranchAddress #ifz ]~2~ brset ~@~ ;;use normal instruction mexit #endif #if ~1~ > 7 merror BitPos not in range 0..7 #endif #ifparm ~3~ = * mset 3,{*} #endif call ~0~ ;call the emulation routine dw ~2~&$1FFF|{~1~<13} ;BitPos (15..13) & Variable (12..0) dw ~3~ ;Branch address endm ;------------------------------------------------------------------------------- #spauto :ab BRIFSET proc pc@@ equ ::+{:ab-2},2 push PBS@@ equ 0 ;Offsets (from original return PC) into hardcoded parameter block pos@@ next PBS@@,0 ;bit position var@@ next PBS@@,2 ;variable address branch@@ next PBS@@,2 ;branch-to address tpa psha ccr@@ #ais #ifhcs ldhx pc@@,sp ;HX = return PC #else tsx lda pc@@,spx ;HX = return PC ldx pc@@+1,spx tah #endif lda branch@@+1,x ;get branch address parameter psha lda branch@@,x psha branch@@,2 ;stacked branch address lda var@@+1,x ;get variable address psha lda var@@,x and #$1F ;mask off the bit position psha var@@,2 ;stacked pure variable address lda ccr@@,sp and #CCR_C_^NOT ;clear the return CCR[Carry] sta ccr@@,sp lda pos@@,x ;get bit position and #$E0 ;mask off the variable address aix #PBS@@ ;non-branch returns after parms #ifhcs sthx pc@@,sp ;update default return PC #else stx pc@@+1,sp ;update default return PC thx stx pc@@,sp #endif nsa ;bit position into lower nibble lsra ;align to Bit0 (Bits 0..2) inca ;make bit position one-based tax ;X = one-based bit position clra ;start with clear mask sec ;Carry will create mask PosToMask@@ rola dbnzx PosToMask@@ ;at the end of loop, A = mask ;;;;;;;;;;;;;;;;;;; sei ;uncomment for atomic execution #ifhcs ldhx var@@,sp ;HX -> variable to test #else ldx var@@,sp ;HX -> variable to test txh ldx var@@+1,sp #endif and ,x ;do the actual bit test beq Done@@ ;bit is clear, so exit #ifhcs ldhx branch@@,sp ;update return address with sthx pc@@,sp ;branch address parameter tsx #else tsx @mova.s branch@@,spx pc@@,spx ;update return address with branch address parameter #endif lda ccr@@,spx ora #CCR_C_ ;set the return CCR[Carry] sta ccr@@,spx Done@@ ais #:ais ;de-allocate temporaries pula tap pull rtc #sp ;******************************************************************************* #Exit ;******************************************************************************* @EndStats ; For testing under a simulator #HideMacros #MapOn TEST def $55 #XRAM var rmb 1 #ROM Start proc @rsp lda #TEST sta var ;--------------------------------------------------------------------- @brifset 0,var,T1 nop ;used to see if branch is taken ;--------------------------------------------------------------------- T1 @brifset 1,var,T2 nop ;used to see if branch is taken ;--------------------------------------------------------------------- T2 @brifset 2,var,T3 nop ;used to see if branch is taken ;--------------------------------------------------------------------- T3 @brifset 3,var,T4 nop ;used to see if branch is taken ;--------------------------------------------------------------------- T4 @brifset 4,var,T5 nop ;used to see if branch is taken ;--------------------------------------------------------------------- T5 @brifset 5,var,T6 nop ;used to see if branch is taken ;--------------------------------------------------------------------- T6 @brifset 6,var,T7 nop ;used to see if branch is taken ;--------------------------------------------------------------------- T7 @brifset 7,var,Done nop ;used to see if branch is taken ;--------------------------------------------------------------------- Done bra * @vector Vreset,Start