www.pudn.com > OSBDM08.zip > bdm.c


/* 
    Open Source BDM - BDM communication 
 	 /* Prominent Notice-This software was modified from TBDML software - 12/05 
    This program is free software; you can redistribute it and/or modify 
    it under the terms of the GNU General Public License as published by 
    the Free Software Foundation; either version 2 of the License, or 
    (at your option) any later version. 
 
    This program is distributed in the hope that it will be useful, 
    but WITHOUT ANY WARRANTY; without even the implied warranty of 
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
    GNU General Public License for more details. 
 
    You should have received a copy of the GNU General Public License 
    along with this program; if not, write to the Free Software 
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
*/ 
 
#include "MC68HC908JB16.h" 
#include "hidef.h" 
#include "bdm.h" 
#include "commands.h" 
#include "usb.h" 
 
/* i, j & k are used as timing and general purpose variables in the Tx & Rx routines */ 
/* must be placed into the direct segment */ 
static unsigned char i; 
static unsigned char j; 
static unsigned char k; 
 
/* pointers to Rx & Tx routines, tables for selection */ 
unsigned char (*bdm_rx_ptr)(void) = bdm_empty_rx_tx; 
void (*bdm_tx_ptr)(unsigned char) = bdm_empty_rx_tx; 
 
/* when SYNC length expressed in 60MHz ticks is ABOVE OR EQUAL to the value in the table, the correspnding pointer is selected */ 
/* if SYNC is shother than the first entry, the target runs too fast */ 
/* if SYNC is longer or equal to the last entry, the target runs too slow */ 
const unsigned int bdm_tx_sel_tresholds[]= 
  {600,     1129,    1335,    1541,    1747,    1952,    2157,    2465,    2877,    3288, 
   3800,    4418,    5136,    6059,    7189,    8524,    10066,   11814,   13867,   16988}; 
void (* const bdm_tx_sel_ptrs[])(unsigned char)= 
  {bdm_tx1, bdm_tx2, bdm_tx3, bdm_tx4, bdm_tx5, bdm_tx6, bdm_tx7, bdm_tx8, bdm_tx9, bdm_tx10, 
   bdm_tx11,bdm_tx12,bdm_tx13,bdm_tx14,bdm_tx15,bdm_tx16,bdm_tx17,bdm_tx18,bdm_tx19,bdm_empty_rx_tx}; 
const unsigned int bdm_rx_sel_tresholds[]= 
  {600,     1101,    1347,    1592,    1837,    2202,    2694,    3303,    4042,    4897, 
   5998,    7346,    9055,    11257,   13952,   17919}; 
unsigned char (* const bdm_rx_sel_ptrs[])(void)= 
  {bdm_rx1, bdm_rx2, bdm_rx3, bdm_rx4, bdm_rx5, bdm_rx6, bdm_rx7, bdm_rx8, bdm_rx9, bdm_rx10, 
   bdm_rx11,bdm_rx12,bdm_rx13,bdm_rx14,bdm_rx15,bdm_empty_rx_tx}; 
 
/* status of the BDM communication */ 
bdm_status_t bdm_status; 
 
/* private macros */ 
 
#define ACKN_CLR   asm (BCLR T1SC0_CH0F_BITNUM,T1SC0); /* clear timer capture flag, in assembly to make sure the compiler does not mess it up... */ 
 
/* functions */ 
 unsigned char bdm08_stat(void) { 
  unsigned char bdm_sts;                
   /* try the ACKN feature */ 
 BDM08_CMD_READSTATUS(&bdm_sts); 
 if ((bdm_sts&0x40)==0) { 
   
  return(0); 
 } 
 return(1);/* connection established */ 
} 
 unsigned char bdm08_connect(void) { 
  unsigned char bdm_sts;                
  bdm_status.ackn = WAIT;               /* clear the ACKN feature */ 
  bdm_status.reset = NO_RESET_ACTIVITY;               /* clear the reset flag */ 
  /* first wait until both RESET and BDM are high */ 
  T1MOD = RESET_WAIT * BUS_FREQUENCY * 16;             /* this is by 2.4% longer than (RESET_WAIT * BUS_FREQUENCY * 1000)/64, but cannot do that in 16-bit math */ 
  T1SC = T1SC_TRST_MASK | T1SC_PS1_MASK | T1SC_PS2_MASK;  /* reset the timer and start counting @ bus clock divided by 64 */ 
  T1SC_TOF = 0; 
  while(((RESET_IN==0)||(BDM_IN==0))&&(T1SC_TOF==0));  /* wait for reset and bdm to rise or timeout */ 
  if (T1SC_TOF) return(1);                             /* timeout */   
  if (bdm_sync_meas()) { 
    /* trying to measure SYNC was not successful */ 
      return(1);   
  } 
 if (bdm_rx_tx_select()) return(1); /* if at least one of the two methods succeeded, we can select the right Rx and Tx routines */ 
 bdm_ackn_init();    /* try the ACKN feature */ 
 BDM08_CMD_READSTATUS(&bdm_sts); 
 if ((bdm_sts&0x80)==0) BDM08_CMD_WRITECONTROL(0x80|bdm_sts); /* if BDM not enabled yet, enable it so it can be made active */ 
  return(0);          /* connection established */ 
} 
 
  
  
/* connect to HC12 or HCS12 target */ 
/* returns 0 on succes or 1 on failure */ 
unsigned char bdm12_connect(void) { 
  unsigned char bdm_sts;															 
  bdm_status.ackn = WAIT;															/* clear the ACKN feature */ 
  bdm_status.reset = NO_RESET_ACTIVITY;               /* clear the reset flag */ 
  /* first wait until both RESET and BDM are high */ 
  T1MOD = RESET_WAIT * BUS_FREQUENCY * 16;             /* this is by 2.4% longer than (RESET_WAIT * BUS_FREQUENCY * 1000)/64, but cannot do that in 16-bit math */ 
  T1SC = T1SC_TRST_MASK | T1SC_PS1_MASK | T1SC_PS2_MASK;  /* reset the timer and start counting @ bus clock divided by 64 */ 
  T1SC_TOF = 0; 
  while(((RESET_IN==0)||(BDM_IN==0))&&(T1SC_TOF==0));  /* wait for reset and bdm to rise or timeout */ 
  if (T1SC_TOF) return(1);                             /* timeout */   
  if (bdm_sync_meas()) { 
    /* trying to measure SYNC was not successful */ 
      return(1);   
  } 
	if (bdm_rx_tx_select()) return(1); /* if at least one of the two methods succeeded, we can select the right Rx and Tx routines */ 
	bdm_ackn_init();    /* try the ACKN feature */ 
	BDM12_CMD_BDREADB(BDM12_STS_ADDR,&bdm_sts); 
	if ((bdm_sts&0x80)==0) BDM12_CMD_BDWRITEB(BDM12_STS_ADDR,0x80|bdm_sts);	/* if BDM not enabled yet, enable it so it can be made active */ 
  return(0);          /* connection established */ 
} 
 
/* resets the target */ 
/* mode == 0 -> reset to special mode, mode == 1 -> reset to normal mode */ 
/* returns zero on success and non-zero if reset signal stuck to ground */ 
  unsigned char bdm_softreset(unsigned char mode) { 
   
  		  if(mode ==0){ 
  		     
  		    BDM08_CMD_Res(0x1801,0x01); 
						   
         	     BDM_OUT = 0;                                      /* drive BDM low */ 
          asm{ 
            MOV   #01,BDM_DIR2_PORT    /* start driving the BDM */ 
          } 
            T1MOD = RESET_SETTLE * BUS_FREQUENCY;              /* time to wait for signals to settle */ 
            T1SC = T1SC_TRST_MASK;                              /* reset the timer and start counting @ bus clock */ 
            T1SC_TOF = 0; 
           while(T1SC_TOF==0);                                /* wait for timeout */ 
  	 
          T1MOD = RESET_SETTLE * BUS_FREQUENCY;              /* time to wait for signals to settle */ 
          T1SC = T1SC_TRST_MASK;                              /* reset the timer and start counting @ bus clock */ 
          T1SC_TOF = 0; 
            while(T1SC_TOF==0);                                /* wait for timeout */ 
          asm { 
             CLRX   						                              /* point to PTA */ 
             CLRH 
       
               LDA   #BDM_DIR1_MASK + BDM_OUT_MASK + RESET_OUT_MASK   
               STA   ,X                                        /* bring BDM high */ 
            AND   #0xEF 
       
               STA   ,X                                        /* stop driving the BDM */ 
      /* it took 4 cycles from bringing BDM high to stop driving it and that is fast enough up to 16*3/4 = 12 MHz of BDM frequency on JB8 */ 
             } 
              
  /* wait one more settling time before allowing anythig else to happen on the BDM */ 
           T1MOD = RESET_SETTLE * BUS_FREQUENCY;                /* time to wait for signals to settle */ 
            T1SC = T1SC_TRST_MASK;                                /* reset the timer and start counting @ bus clock */ 
          T1SC_TOF = 0; 
          while(T1SC_TOF==0);  
         	 bdm_tx_finish();  
  		  } 
  		   
  		   
  		  if (mode ==1){ 
  		   
  		  	  BDM08_CMD_WRITEB(0x1801,0x01); 
  		   
  		  } 
          
  } 
 
 
/* resets the target */ 
/* mode == 0 -> reset to special mode, mode == 1 -> reset to normal mode */ 
/* returns zero on success and non-zero if reset signal stuck to ground */ 
unsigned char bdm_reset(unsigned char mode) { 
   
  BDM_DIR1 = 0;                                       /* stop driving the BDM */ 
  KBSCR_IMASKK = 1;                                   /* mask KBD interrupts */ 
  T1MOD = RESET_WAIT * BUS_FREQUENCY * 16;             /* this is by 2.4% longer than (RESET_WAIT * BUS_FREQUENCY * 1000)/64, but cannot do that in 16-bit math */ 
  T1SC = T1SC_TRST_MASK | T1SC_PS1_MASK | T1SC_PS2_MASK;  /* reset the timer and start counting @ bus clock divided by 64 */ 
  T1SC_TOF = 0; 
  while((RESET_IN==0)&&(T1SC_TOF==0));                 /* wait for reset to rise or timeout */ 
  if (T1SC_TOF) return(1); 
  if (mode==0) { 
    BDM_OUT = 0;                                      /* drive BDM low */ 
     
    BDM_DIR1 = 1; 
    T1MOD = RESET_SETTLE * BUS_FREQUENCY;              /* time to wait for signals to settle */ 
    T1SC = T1SC_TRST_MASK;                              /* reset the timer and start counting @ bus clock */ 
    T1SC_TOF = 0; 
    while(T1SC_TOF==0);                                /* wait for timeout */ 
  } 
  //Switch To A to B to drive Reset 
  RESET_DR = 1; //Default is B to A for Input 
  RESET_DR_DDR |= RESET_DR_MASK;  // Set as output to Drive the buffer  
   
  RESET_OUT = 0;                                      /* start driving RESET */ 
  RESET_OUT_DDR |= RESET_OUT_MASK; 
  T1MOD = RESET_LENGTH * BUS_FREQUENCY * 16;           /* time of the RESET pulse */ 
  T1SC = T1SC_TRST_MASK | T1SC_PS1_MASK | T1SC_PS2_MASK;  /* reset the timer and start counting @ bus clock divided by 64 */ 
  T1SC_TOF = 0; 
  while(T1SC_TOF==0);                                  /* wait for timeout */ 
  RESET_OUT = 1;																			/* stop driving the RESET */ 
  RESET_OUT_DDR &= ~RESET_OUT_MASK;            /* and make the pin input again so nothing interferes with it */ 
   
  //Switch To B to A 
  RESET_DR = 0; //Default is B to A for Input 
   
  T1MOD = RESET_WAIT * BUS_FREQUENCY * 16;             /* time to wait for reset to rise */ 
  T1SC = T1SC_TRST_MASK | T1SC_PS1_MASK | T1SC_PS2_MASK;  /* reset the timer and start counting @ bus clock divided by 64 */ 
  T1SC_TOF = 0; 
  while((RESET_IN==0)&&(T1SC_TOF==0));                 /* wait for reset to rise or timeout */ 
  if (T1SC_TOF) return(1); 
  if (mode==0) { 
    T1MOD = RESET_SETTLE * BUS_FREQUENCY;              /* time to wait for signals to settle */ 
    T1SC = T1SC_TRST_MASK;                              /* reset the timer and start counting @ bus clock */ 
    T1SC_TOF = 0; 
    while(T1SC_TOF==0);                                /* wait for timeout */ 
    asm { 
      CLRX   						                              /* point to PTA */ 
      CLRH 
       
      LDA   #BDM_DIR1_MASK + BDM_OUT_MASK + RESET_OUT_MASK   
      STA   ,X                                        /* bring BDM high */ 
      AND   #0xEF 
       
      STA   ,X                                        /* stop driving the BDM */ 
      /* it took 4 cycles from bringing BDM high to stop driving it and that is fast enough up to 16*3/4 = 12 MHz of BDM frequency on JB8 */ 
    } 
  } 
  /* wait one more settling time before allowing anythig else to happen on the BDM */ 
  T1MOD = RESET_SETTLE * BUS_FREQUENCY;                /* time to wait for signals to settle */ 
  T1SC = T1SC_TRST_MASK;                                /* reset the timer and start counting @ bus clock */ 
  T1SC_TOF = 0; 
  while(T1SC_TOF==0);                                  /* wait for timeout */ 
  KBSCR_ACKK=1;                                       /* acknowledge KBD interrupt */ 
  KBSCR_IMASKK = 0;                                   /* enable KBD interrupts again */ 
  return(0); 
} 
 
/* interrupt function servicing the KBD interrupt from RESET_IN assertion */ 
void interrupt bdm_reset_sense(void) { 
  KBSCR_ACKK=1;                    /* acknowledge the interrupt */ 
  bdm_status.reset=RESET_DETECTED; /* record the fact that reset was asserted */   
} 
 
/* measures the SYNC length and writes the result into bdm_status structure */ 
/* returns 0 on succes and non-zero on timeout */ 
unsigned char bdm_sync_meas(void) { 
  unsigned int time; 
  bdm_status.speed = NO_INFO; /* indicate that we do not have a clue about target speed at the moment... */ 
  T1MOD = BDM_SYNC_REQ * BUS_FREQUENCY;  /* load T1MOD with the longest SYNC REQUEST possible */ 
  BDM_DIR1 = 0;         /* stop driving the BDM */ 
  T1SC = T1SC_TRST_MASK;  /* restart the timer */ 
  T1SC_TOF = 0;          /* clear TOF */ 
  while((T1SC_TOF==0)&&(BDM_IN==0)); /* wait for the BDM to come high or timeout */ 
  if (T1SC_TOF) return(1);           /* timeout ! */ 
  BDM_OUT = 0; 
  BDM_DIR1 = 1;         /* bring BDM low */ 
  T1SC = T1SC_TRST_MASK;  /* restart the timer */ 
  T1SC_TOF = 0;          /* clear TOF */ 
  while(T1SC_TOF==0);    /* wait for timeout */ 
  T1SC_TOF = 0;          /* clear the TOF flag */ 
  T1SC0 = T1SC0_ELS0B_MASK; /* capture falling edges */ 
  T1SC0_CH0F=0;          /* clear capture flag */ 
  //this is not fast enough, the target will start driving 16 BDM cycles after the pin comes high 
  //BDM_OUT_PORT = BDM_OUT_MASK;  /* bring BDM high */ 
  //BDM_DIR1_PORT = BDM_OUT_MASK | BDM_DIR1_MASK; /* stop driving it */ 
  asm { 
    CLRX   						  /* point to PTA */ 
    CLRH 
     
    LDA   #BDM_DIR1_MASK + BDM_OUT_MASK + RESET_OUT_MASK   
    STA   ,X            /* bring BDM high */ 
    AND   #0xEF 
    STA   ,X            /* stop driving the BDM */ 
    /* it took 4 cycles from bringing BDM high to stop driving it and that is fast enough up to 16*3/4 = 12 MHz of BDM frequency on JB8 */ 
  } 
  while ((T1SC0_CH0F==0)&&(T1SC_TOF==0));     /* wait for capture or timeout */   
  time=T1CH0;                                /* capture start of the SYNC */ 
  T1SC0 = T1SC0_ELS0A_MASK;                   /* capture rising edge, clear capture flag */ 
  /* it takes 32 cycles to reenable capture (worst case) which is good enough up to 128*3/32 = 12 MHz again on JB8 */  
  while ((T1SC0_CH0F==0)&&(T1SC_TOF==0));     /* wait for capture or timeout */   
  time=T1CH0-time;                           /* calculate length of the SYNC */ 
  if (T1SC_TOF) return(2);                   /* timeout ! */ 
  #if (BUS_FREQUENCY==3) 
    bdm_status.sync_length=(time<<2)+(time<<4);   /* multiply by 20 to get the time in 60MHz ticks */ 
  #elif (BUS_FREQUENCY==6) 
    bdm_status.sync_length=(time<<1)+(time<<3);   /* multiply by 10 to get the time in 60MHz ticks */ 
  #else 
    bdm_status.sync_length=time*(60/BUS_FREQUENCY); /* if not 3 or 6 then do it the stupid way... */ 
  #endif 
  bdm_status.speed = SYNC_SUPPORTED; /* SYNC feature is supported by the target */ 
  return(0); 
} 
 
/* waits 64 BDM cycles of the target MCU */ 
void bdm_wait64(void) { 
  asm { 
    LDA  bdm_status.wait64_cnt  /* number of loop iterations to wait */ 
  loop:   
    DBNZA loop                  /* 3 cycles per iteration */ 
  } 
} 
 
/* waits 150 BDM cycles of the target MCU */ 
void bdm_wait150(void) { 
  asm { 
    LDA  bdm_status.wait150_cnt  /* number of loop iterations to wait */ 
  loop:   
    DBNZA loop                  /* 3 cycles per iteration */ 
  } 
} 
 
/* enables ACKN and prepares the timer for easy ACKN timeout use */ 
void bdm_ackn_init(void) { 
  T1MOD = ACKN_TIMEOUT * BUS_FREQUENCY;  /* the timer will set the TOF flag as soon as the timeout time is reached */ 
  T1SC = T1SC_TRST_MASK;    /* start the timer, prescaler = 1 */ 
  T1SC0 = T1SC0_ELS0A_MASK;	/* capture rising edges */ 
  bdm_status.ackn = ACKN; /* switch ACKN on */ 
  BDM_CMD_ACK_ENABLE();   /* send the enable command to the target */ 
} 
 
/* waits for ACKN pulse from the target */ 
void bdm_ackn(void) { 
  T1SC = T1SC_TRST_MASK;                      /* clear the TOF flag if set and restart the timer */ 
  T1SC_TOF = 0;                              /* clear TOF */ 
  while ((T1SC0_CH0F==0)&&(T1SC_TOF==0));     /* wait for capture or timeout */   
  T1SC0 = T1SC0_ELS0A_MASK;                   /* capture rising edge, clear capture flag */ 
  if (T1SC_TOF) { 
    /* timeout */ 
    bdm_status.ackn = WAIT;                 /* switch the ackn feature off */ 
  } 
} 
 
/* selects Rx and Tx routine to be used according to SYNC length in bdm_status structure */ 
/* returns 0 on success and 1 when no appropriate function can be found */ 
unsigned char bdm_rx_tx_select(void) { 
  signed char i; 
  bdm_rx_ptr = bdm_empty_rx_tx;                         /* clear the pointers */ 
  bdm_tx_ptr = bdm_empty_rx_tx; 
  for (i=(sizeof(bdm_tx_sel_tresholds)/2)-1;i>=0;i--) { /* search through the table */ 
    if ((bdm_status.sync_length*2)>=bdm_tx_sel_tresholds[i]) { 
      bdm_tx_ptr = bdm_tx_sel_ptrs[i];                  /* is SYNC is >=, select this routine */ 
      break;                                            /* and finish the search */ 
    } 
  } 
  if (bdm_tx_ptr==bdm_empty_rx_tx) return(1);           /* check if valid routine has been found */ 
  for (i=(sizeof(bdm_rx_sel_tresholds)/2)-1;i>=0;i--) { /* do the same for Rx as well */ 
    if ((bdm_status.sync_length*2)>=bdm_rx_sel_tresholds[i]) { 
      bdm_rx_ptr = bdm_rx_sel_ptrs[i]; 
      break; 
    } 
  } 
  if (bdm_rx_ptr==bdm_empty_rx_tx) return(1); 
  /* there is plenty of overhead: JSR, LDA and RTS of the WAIT, RTS from the previous routine, JSR to the next routine: at least 21 cycles */ 
  /* cannot subtract more than the smallest possible result -1 as the number must be > 0 */ 
  bdm_status.wait64_cnt = (bdm_status.sync_length*2)/(3*(60/BUS_FREQUENCY)*128/64)-6;  
  bdm_status.wait150_cnt =(bdm_status.sync_length*2)/(3*(60/BUS_FREQUENCY)*128/150)-7;  
  return(0); 
} 
 
/* when no function appropriate for the target speed can be found the following routine is selected */ 
/* this is just to make things safe and to make sure there is a place to jump to in such a case */ 
unsigned char bdm_empty_rx_tx(void) { 
  command_buffer[0]=CMD_FAILED; /* if BDM command is executed with this routine set as either Tx or Rx it has failed... */ 
  return(0); 
} 
 
/* initialises I/O pins and internal variables of the module */ 
void bdm_init() { 
  bdm_status.ackn = WAIT;				  /* select default behaviour & values */ 
  bdm_status.target_type = HC12;  
  bdm_status.reset = NO_RESET_ACTIVITY; 
  bdm_status.speed = NO_INFO; 
  POCR_PAP=1;                     /* enable pullups on RESET_OUT, RESET_IN and BDM_DRIVE */ 
  RESET_IN_DDR &= ~RESET_IN_MASK; /* RESET_IN is input */ 
  RESET_OUT = 1;                  /* RESET_OUT inactive */ 
  RESET_OUT_DDR &= ~RESET_OUT_MASK;/* RESET_OUT is input for the moment, only turn it out when needed as Rx routines interfere with RESET_OUT */   
   
  RESET_DR = 0; //Default is B to A for Input 
  RESET_DR_DDR |= RESET_DR_MASK;  // Set as output to Drive the buffer 
  
  BDM_IN_DDR &= ~BDM_IN_MASK;     /* BDM_IN is input */ 
  BDM_OUT = 1;                    /* idle state of BDM line is high */ 
  BDM_OUT_DDR |= BDM_OUT_MASK;    /* BDM_OUT is output */      
  BDM_DIR2 = 1;                   /* prepare to drive the BDM once DIR2 is turned to output */ 
  BDM_DIR2_DDR &= ~BDM_DIR2_MASK; /* turn BDM_DIR2 to input */ 
  BDM_DIR1 = 0;                   /* do not drive the BDM */ 
  BDM_DIR1_DDR |= BDM_DIR1_MASK;  /* turn BDM_DIR1 to output */   
  /* now give the BDM interface enough time to soft reset in case it was doing something before */ 
  T1MOD = SOFT_RESET * BUS_FREQUENCY;  /* load T1MOD with the longest SOFT RESET time possible */ 
  T1SC = T1SC_TRST_MASK;                /* restart the timer */ 
  T1SC_TOF = 0;                        /* clear TOF */ 
  while(T1SC_TOF==0);                  /* wait for timeout */ 
  KBIER = RESET_IN_MASK;          /* enable RESET_IN as keyboard pin */ 
  KBSCR = KBSCR_ACKK_MASK;        /* acknowledge any pending interrupt and enable KBD to cause IRQ (once enabled) */ 
} 
 
/* prepares transmit of BDM data */ 
/* assumes that BDM_OUT is 1 */ 
/* interrupts need to be disabled for the duration of all BDM commands */ 
/* it is up to the caller to see to this */ 
void bdm_tx_prepare(void) { 
  BDM_OUT_PORT = BDM_OUT_MASK | RESET_OUT_MASK; /* make sure BDM will be driven high once the driver is enabled */ 
  BDM_OUT_DDR = BDM_OUT_MASK;     /* turn DIR1 & RESET_OUT to input (now the only output in PTA register is BDM_OUT) */   
  BDM_DIR2_DDR |= BDM_DIR2_MASK;   /* bring DIR low (start driving the BDM) */ 
} 
 
/* finishes transmit of BDM data */ 
void bdm_tx_finish(void) { 
  BDM_OUT_PORT =  BDM_OUT_MASK | RESET_OUT_MASK;  /* do not drive RESET nor BDM once DIR1 is output again */ 
  BDM_DIR2_DDR &= ~BDM_DIR2_MASK;                                              /* stop driving DIR2 low */ 
  BDM_DIR1_DDR = BDM_DIR1_MASK | BDM_OUT_MASK;                   /* enable DIR1 again, leave RESET_OUT as input */   
} 
 
/* receive 8 bit of data, MSB first */ 
/* expects DIR1 active and DIR2 inactive */ 
/* 6.75 - 9.75 MHz */ 
unsigned char bdm_rx1(void) { 
  #pragma NO_RETURN 
  asm { 
    LDA   #RESET_OUT_MASK	/* contents of A will be driven to PTA in order to switch the driver off */ 
     
    CLRX                    /* prepare HX to point to PTA */   
    CLRH 
    /* bit 7 (MSB) */ 
   bset 7,0 
   com  ,x 
    
   //mov #0x10,0 
    //STX   ,X                /* drive BDM low */ 
    STA   ,X                /* switch BDM to high impedance */ 
    LDX   ,X                /* load X with value on the PTA port (including BDM_IN) */ 
    PSHX                    /* store the value on the stack */ 
    CLRX                    /* clear X again */ 
    /* bit 6 */                 
     bset 7,0 
   com  ,x 
   //mov #0x10,0 
    //STX   ,X                /* drive BDM low */ 
    STA   ,X                /* switch BDM to high impedance */ 
    LDX   ,X                /* load X with value on the PTA port (including BDM_IN) */ 
    PSHX                    /* store the value on the stack */ 
    CLRX                    /* clear X again */ 
    /* bit 5 */                 
     bset 7,0 
   com  ,x//mov #0x10,0 
    //STX   ,X                /* drive BDM low */ 
    STA   ,X                /* switch BDM to high impedance */ 
    LDX   ,X                /* load X with value on the PTA port (including BDM_IN) */ 
    PSHX                    /* store the value on the stack */ 
    CLRX                    /* clear X again */ 
    /* bit 4 */                 
     bset 7,0 
   com  ,x//mov #0x10,0 
    //STX   ,X                /* drive BDM low */ 
    STA   ,X                /* switch BDM to high impedance */ 
    LDX   ,X                /* load X with value on the PTA port (including BDM_IN) */ 
    PSHX                    /* store the value on the stack */ 
    CLRX                    /* clear X again */ 
    /* bit 3 */                 
     bset 7,0 
   com  ,x//mov #0x10,0 
    //STX   ,X                /* drive BDM low */ 
    STA   ,X                /* switch BDM to high impedance */ 
    LDX   ,X                /* load X with value on the PTA port (including BDM_IN) */ 
    PSHX                    /* store the value on the stack */ 
    CLRX                    /* clear X again */ 
    /* bit 2 */                 
     bset 7,0 
   com  ,x 
   //mov #0x10,0 
    //STX   ,X                /* drive BDM low */ 
    STA   ,X                /* switch BDM to high impedance */ 
    LDX   ,X                /* load X with value on the PTA port (including BDM_IN) */ 
    PSHX                    /* store the value on the stack */ 
    CLRX                    /* clear X again */ 
    /* bit 1 */                 
     bset 7,0 
   com  ,x 
   //mov #0x10,0 
    //STX   ,X                /* drive BDM low */ 
    STA   ,X                /* switch BDM to high impedance */ 
    LDX   ,X                /* load X with value on the PTA port (including BDM_IN) */ 
    PSHX                    /* store the value on the stack */ 
    CLRX                    /* clear X again */ 
    /* bit 0 */                 
     bset 7,0 
   com  ,x 
   //mov #0x10,0 
    //STX   ,X                /* drive BDM low */ 
    STA   ,X                /* switch BDM to high impedance */ 
    LDX   ,X                /* load X with value on the PTA port (including BDM_IN) */ 
    /* now get the bit values (last value is in X, previous 7 on stack) */ 
    JMP   rx_stack_decode 
  } 
} 
/* 5.4 - 7.8 MHz */ 
unsigned char bdm_rx2(void) { 
  #pragma NO_RETURN 
  asm { 
    LDA   #RESET_OUT_MASK	/* contents of A will be driven to PTA in order to switch the driver off */ 
    CLRX                    /* prepare HX to point to PTA */   
    CLRH 
    /* bit 7 (MSB) */ 
    mov #0x10,0 
    //STX   ,X                /* drive BDM low */ 
    STA   ,X                /* switch BDM to high impedance */ 
    NOP                     /* wait 1 cycle */ 
    LDX   ,X                /* load X with value on the PTA port (including BDM_IN) */ 
    PSHX                    /* store the value on the stack */ 
    CLRX                    /* clear X again */ 
    /* bit 6 */                 
    mov #0x10,0 
    //STX   ,X                /* drive BDM low */ 
    STA   ,X                /* switch BDM to high impedance */ 
    NOP                     /* wait 1 cycle */ 
    LDX   ,X                /* load X with value on the PTA port (including BDM_IN) */ 
    PSHX                    /* store the value on the stack */ 
    CLRX                    /* clear X again */ 
    /* bit 5 */                 
    mov #0x10,0 
    //STX   ,X                /* drive BDM low */ 
    STA   ,X                /* switch BDM to high impedance */ 
    NOP                     /* wait 1 cycle */ 
    LDX   ,X                /* load X with value on the PTA port (including BDM_IN) */ 
    PSHX                    /* store the value on the stack */ 
    CLRX                    /* clear X again */ 
    /* bit 4 */                 
    mov #0x10,0 
    //STX   ,X                /* drive BDM low */ 
    STA   ,X                /* switch BDM to high impedance */ 
    NOP                     /* wait 1 cycle */ 
    LDX   ,X                /* load X with value on the PTA port (including BDM_IN) */ 
    PSHX                    /* store the value on the stack */ 
    CLRX                    /* clear X again */ 
    /* bit 3 */                 
    mov #0x10,0 
    //STX   ,X                /* drive BDM low */ 
    STA   ,X                /* switch BDM to high impedance */ 
    NOP                     /* wait 1 cycle */ 
    LDX   ,X                /* load X with value on the PTA port (including BDM_IN) */ 
    PSHX                    /* store the value on the stack */ 
    CLRX                    /* clear X again */ 
    /* bit 2 */                 
    mov #0x10,0 
    //STX   ,X                /* drive BDM low */ 
    STA   ,X                /* switch BDM to high impedance */ 
    NOP                     /* wait 1 cycle */ 
    LDX   ,X                /* load X with value on the PTA port (including BDM_IN) */ 
    PSHX                    /* store the value on the stack */ 
    CLRX                    /* clear X again */ 
    /* bit 1 */                 
    mov #0x10,0 
    //STX   ,X                /* drive BDM low */ 
    STA   ,X                /* switch BDM to high impedance */ 
    NOP                     /* wait 1 cycle */ 
    LDX   ,X                /* load X with value on the PTA port (including BDM_IN) */ 
    PSHX                    /* store the value on the stack */ 
    CLRX                    /* clear X again */ 
    /* bit 0 */                 
    mov #0x10,0 
    //STX   ,X                /* drive BDM low */ 
    STA   ,X                /* switch BDM to high impedance */ 
    NOP                     /* wait 1 cycle */ 
    LDX   ,X                /* load X with value on the PTA port (including BDM_IN) */ 
    /* now get the bit values (last value is in X, previous 7 on stack) */ 
    JMP   rx_stack_decode 
  } 
} 
/* 4.5 - 6.5 MHz */ 
unsigned char bdm_rx3(void) { 
  #pragma NO_RETURN 
  asm { 
    LDA   #RESET_OUT_MASK	/* contents of A will be driven to PTA in order to switch the driver off */ 
    CLRX                    /* prepare HX to point to PTA */   
    CLRH 
    /* bit 7 (MSB) */ 
    mov #0x10,0 
    //STX   ,X                /* drive BDM low */ 
    STA   ,X                /* switch BDM to high impedance */ 
    BIT   ,X                /* wait 2 cycles */ 
    LDX   ,X                /* load X with value on the PTA port (including BDM_IN) */ 
    PSHX                    /* store the value on the stack */ 
    CLRX                    /* clear X again */ 
    /* bit 6 */                 
    mov #0x10,0 
    //STX   ,X                /* drive BDM low */ 
    STA   ,X                /* switch BDM to high impedance */ 
    BIT   ,X                /* wait 2 cycles */ 
    LDX   ,X                /* load X with value on the PTA port (including BDM_IN) */ 
    PSHX                    /* store the value on the stack */ 
    CLRX                    /* clear X again */ 
    /* bit 5 */                 
    mov #0x10,0 
    //STX   ,X                /* drive BDM low */ 
    STA   ,X                /* switch BDM to high impedance */ 
    BIT   ,X                /* wait 2 cycles */ 
    LDX   ,X                /* load X with value on the PTA port (including BDM_IN) */ 
    PSHX                    /* store the value on the stack */ 
    CLRX                    /* clear X again */ 
    /* bit 4 */                 
    mov #0x10,0 
    //STX   ,X                /* drive BDM low */ 
    STA   ,X                /* switch BDM to high impedance */ 
    BIT   ,X                /* wait 2 cycles */ 
    LDX   ,X                /* load X with value on the PTA port (including BDM_IN) */ 
    PSHX                    /* store the value on the stack */ 
    CLRX                    /* clear X again */ 
    /* bit 3 */                 
    mov #0x10,0 
    //STX   ,X                /* drive BDM low */ 
    STA   ,X                /* switch BDM to high impedance */ 
    BIT   ,X                /* wait 2 cycles */ 
    LDX   ,X                /* load X with value on the PTA port (including BDM_IN) */ 
    PSHX                    /* store the value on the stack */ 
    CLRX                    /* clear X again */ 
    /* bit 2 */                 
    mov #0x10,0 
    //STX   ,X                /* drive BDM low */ 
    STA   ,X                /* switch BDM to high impedance */ 
    BIT   ,X                /* wait 2 cycles */ 
    LDX   ,X                /* load X with value on the PTA port (including BDM_IN) */ 
    PSHX                    /* store the value on the stack */ 
    CLRX                    /* clear X again */ 
    /* bit 1 */                 
    mov #0x10,0 
    //STX   ,X                /* drive BDM low */ 
    STA   ,X                /* switch BDM to high impedance */ 
    BIT   ,X                /* wait 2 cycles */ 
    LDX   ,X                /* load X with value on the PTA port (including BDM_IN) */ 
    PSHX                    /* store the value on the stack */ 
    CLRX                    /* clear X again */ 
    /* bit 0 */                 
    mov #0x10,0 
    //STX   ,X                /* drive BDM low */ 
    STA   ,X                /* switch BDM to high impedance */ 
    BIT   ,X                /* wait 2 cycles */ 
    LDX   ,X                /* load X with value on the PTA port (including BDM_IN) */ 
    /* now get the bit values (last value is in X, previous 7 on stack) */ 
    JMP   rx_stack_decode 
  } 
} 
/* 3.86 - 5.57 MHz */ 
unsigned char bdm_rx4(void) { 
  #pragma NO_RETURN 
  asm { 
    LDA   #RESET_OUT_MASK	/* contents of A will be driven to PTA in order to switch the driver off */ 
    CLRX                    /* prepare HX to point to PTA */   
    CLRH 
    /* bit 7 (MSB) */ 
    mov #0x10,0 
    //STX   ,X                /* drive BDM low */ 
    STA   ,X                /* switch BDM to high impedance */ 
    BRN   0                 /* wait 3 cycles */ 
    LDX   ,X                /* load X with value on the PTA port (including BDM_IN) */ 
    PSHX                    /* store the value on the stack */ 
    CLRX                    /* clear X again */ 
    NOP                     /* wait 1 cycle */ 
    /* bit 6 */                 
    mov #0x10,0 
    //STX   ,X                /* drive BDM low */ 
    STA   ,X                /* switch BDM to high impedance */ 
    BRN   0                 /* wait 3 cycles */ 
    LDX   ,X                /* load X with value on the PTA port (including BDM_IN) */ 
    PSHX                    /* store the value on the stack */ 
    CLRX                    /* clear X again */ 
    NOP                     /* wait 1 cycle */ 
    /* bit 5 */                 
    mov #0x10,0 
    //STX   ,X                /* drive BDM low */ 
    STA   ,X                /* switch BDM to high impedance */ 
    BRN   0                 /* wait 3 cycles */ 
    LDX   ,X                /* load X with value on the PTA port (including BDM_IN) */ 
    PSHX                    /* store the value on the stack */ 
    CLRX                    /* clear X again */ 
    NOP                     /* wait 1 cycle */ 
    /* bit 4 */                 
    mov #0x10,0 
    //STX   ,X                /* drive BDM low */ 
    STA   ,X                /* switch BDM to high impedance */ 
    BRN   0                 /* wait 3 cycles */ 
    LDX   ,X                /* load X with value on the PTA port (including BDM_IN) */ 
    PSHX                    /* store the value on the stack */ 
    CLRX                    /* clear X again */ 
    NOP                     /* wait 1 cycle */ 
    /* bit 3 */                 
    mov #0x10,0 
    //STX   ,X                /* drive BDM low */ 
    STA   ,X                /* switch BDM to high impedance */ 
    BRN   0                 /* wait 3 cycles */ 
    LDX   ,X                /* load X with value on the PTA port (including BDM_IN) */ 
    PSHX                    /* store the value on the stack */ 
    CLRX                    /* clear X again */ 
    NOP                     /* wait 1 cycle */ 
    /* bit 2 */                 
    mov #0x10,0 
    //STX   ,X                /* drive BDM low */ 
    STA   ,X                /* switch BDM to high impedance */ 
    BRN   0                 /* wait 3 cycles */ 
    LDX   ,X                /* load X with value on the PTA port (including BDM_IN) */ 
    PSHX                    /* store the value on the stack */ 
    CLRX                    /* clear X again */ 
    NOP                     /* wait 1 cycle */ 
    /* bit 1 */                 
    mov #0x10,0 
    //STX   ,X                /* drive BDM low */ 
    STA   ,X                /* switch BDM to high impedance */ 
    BRN   0                 /* wait 3 cycles */ 
    LDX   ,X                /* load X with value on the PTA port (including BDM_IN) */ 
    PSHX                    /* store the value on the stack */ 
    CLRX                    /* clear X again */ 
    NOP                     /* wait 1 cycle */ 
    /* bit 0 */                 
    mov #0x10,0 
    //STX   ,X                /* drive BDM low */ 
    STA   ,X                /* switch BDM to high impedance */ 
    BRN   0                 /* wait 3 cycles */ 
    LDX   ,X                /* load X with value on the PTA port (including BDM_IN) */ 
    /* now get the bit values (last value is in X, previous 7 on stack) */ 
    JMP   rx_stack_decode 
  } 
} 
/* 3.38 - 4.48 MHz */ 
unsigned char bdm_rx5(void) { 
  #pragma NO_RETURN 
  asm { 
    LDA   #RESET_OUT_MASK	/* contents of A will be driven to PTA in order to switch the driver off */ 
    //LDA   #BDM_DIR1_MASK+RESET_OUT_MASK	/* contents of A will be driven to PTA in order to switch the driver off */ 
    CLRX                    /* prepare HX to point to PTA */   
    CLRH 
    /* bit 7 (MSB) */ 
     
    mov #0x10,0 
    //STX   ,X                /* drive BDM low */ 
    //NOP                     /* wait 1 cycle */ 
    STA   ,X                /* switch BDM to high impedance */ 
    BRN   0                 /* wait 3 cycles */ 
    LDX   ,X                /* load X with value on the PTA port (including BDM_IN) */ 
    PSHX                    /* store the value on the stack */ 
    CLRX                    /* clear X again */ 
    BIT   ,X                /* wait 2 cycles */ 
    /* bit 6 */                 
    mov #0x10,0 
    //STX   ,X                /* drive BDM low */ 
    //NOP                     /* wait 1 cycle */ 
    STA   ,X                /* switch BDM to high impedance */ 
    BRN   0                 /* wait 3 cycles */ 
    LDX   ,X                /* load X with value on the PTA port (including BDM_IN) */ 
    PSHX                    /* store the value on the stack */ 
    CLRX                    /* clear X again */ 
    BIT   ,X                /* wait 2 cycles */ 
    /* bit 5 */                 
    mov #0x10,0 
    //STX   ,X                /* drive BDM low */ 
    //NOP                     /* wait 1 cycle */ 
    STA   ,X                /* switch BDM to high impedance */ 
    BRN   0                 /* wait 3 cycles */ 
    LDX   ,X                /* load X with value on the PTA port (including BDM_IN) */ 
    PSHX                    /* store the value on the stack */ 
    CLRX                    /* clear X again */ 
    BIT   ,X                /* wait 2 cycles */ 
    /* bit 4 */                 
    mov #0x10,0 
    //STX   ,X                /* drive BDM low */ 
    //NOP                     /* wait 1 cycle */ 
    STA   ,X                /* switch BDM to high impedance */ 
    BRN   0                 /* wait 3 cycles */ 
    LDX   ,X                /* load X with value on the PTA port (including BDM_IN) */ 
    PSHX                    /* store the value on the stack */ 
    CLRX                    /* clear X again */ 
    BIT   ,X                /* wait 2 cycles */ 
    /* bit 3 */                 
    mov #0x10,0 
    //STX   ,X                /* drive BDM low */ 
    //NOP                     /* wait 1 cycle */ 
    STA   ,X                /* switch BDM to high impedance */ 
    BRN   0                 /* wait 3 cycles */ 
    LDX   ,X                /* load X with value on the PTA port (including BDM_IN) */ 
    PSHX                    /* store the value on the stack */ 
    CLRX                    /* clear X again */ 
    BIT   ,X                /* wait 2 cycles */ 
    /* bit 2 */                 
     mov #0x10,0 
    //STX   ,X                /* drive BDM low */ 
    //NOP                     /* wait 1 cycle */ 
    STA   ,X                /* switch BDM to high impedance */ 
    BRN   0                 /* wait 3 cycles */ 
    LDX   ,X                /* load X with value on the PTA port (including BDM_IN) */ 
    PSHX                    /* store the value on the stack */ 
    CLRX                    /* clear X again */ 
    BIT   ,X                /* wait 2 cycles */ 
    /* bit 1 */                 
    mov #0x10,0 
    //STX   ,X                /* drive BDM low */ 
    //NOP                     /* wait 1 cycle */ 
    STA   ,X                /* switch BDM to high impedance */ 
    BRN   0                 /* wait 3 cycles */ 
    LDX   ,X                /* load X with value on the PTA port (including BDM_IN) */ 
    PSHX                    /* store the value on the stack */ 
    CLRX                    /* clear X again */ 
    BIT   ,X                /* wait 2 cycles */ 
    /* bit 0 */                 
    mov #0x10,0 
    //STX   ,X                /* drive BDM low */ 
    //NOP                     /* wait 1 cycle */ 
    STA   ,X                /* switch BDM to high impedance */ 
    BRN   0                 /* wait 3 cycles */ 
    LDX   ,X                /* load X with value on the PTA port (including BDM_IN) */ 
    /* now get the bit values (last value is in X, previous 7 on stack) */ 
    JMP   rx_stack_decode 
  } 
} 
/* 2.7 - 3.9 MHz */ 
unsigned char bdm_rx6(void) { 
  asm { 
    LDA   #RESET_OUT_MASK	/* contents of A will be driven to PTA in order to switch the driver off */ 
    //LDA   #BDM_DIR1_MASK+RESET_OUT_MASK	/* contents of A will be driven to PTA in order to switch the driver off */ 
    CLRX                    /* prepare HX to point to PTA */   
    CLRH 
    /* bit 7 (MSB) */ 
  mov #0x10,0 
    //STX   ,X                /* drive BDM low */ 
    //NOP                     /* wait 1 cycle */ 
      STA   ,X                /* switch BDM to high impedance */ 
    BRSET 0,DDRA,0          /* wait 5 cycles */ 
    LDX   ,X                /* load X with value on the PTA port (including BDM_IN) */ 
		LSLX                    /* shift BDM_IN into C */ 
		LSLX 
    CLRX                    /* clear X again */ 
    BRN   0                 /* wait 3 cycles */ 
    /* bit 6 */                 
    mov #0x10,0 
    //STX   ,X                /* drive BDM low */ 
    //NOP                     /* wait 1 cycle */ 
    STA   ,X                /* switch BDM to high impedance */ 
    ROL   i                 /* shift C into i (from the bottom) */ 
		NOP                     /* wait 1 more cycle (5 cycles in total together with ROL) */ 
    LDX   ,X                /* load X with value on the PTA port (including BDM_IN) */ 
		LSLX                    /* shift BDM_IN into C */ 
		LSLX 
    CLRX                    /* clear X again */ 
    BRN   0                 /* wait 3 cycles */ 
    /* bit 5 */                 
    mov #0x10,0 
    //STX   ,X                /* drive BDM low */ 
    //NOP                     /* wait 1 cycle */ 
    STA   ,X                /* switch BDM to high impedance */ 
    ROL   i                 /* shift C into i (from the bottom) */ 
		NOP                     /* wait 1 more cycle */ 
    LDX   ,X                /* load X with value on the PTA port (including BDM_IN) */ 
		LSLX                    /* shift BDM_IN into C */ 
		LSLX 
    CLRX                    /* clear X again */ 
    BRN   0                 /* wait 3 cycles */ 
    /* bit 4 */                 
    mov #0x10,0 
    //STX   ,X                /* drive BDM low */ 
    //NOP                     /* wait 1 cycle */ 
    STA   ,X                /* switch BDM to high impedance */ 
    ROL   i                 /* shift C into i (from the bottom) */ 
		NOP                     /* wait 1 more cycle */ 
    LDX   ,X                /* load X with value on the PTA port (including BDM_IN) */ 
		LSLX                    /* shift BDM_IN into C */ 
		LSLX 
    CLRX                    /* clear X again */ 
    BRN   0                 /* wait 3 cycles */ 
    /* bit 3 */                 
    mov #0x10,0 
    //STX   ,X                /* drive BDM low */ 
    //NOP                     /* wait 1 cycle */ 
    STA   ,X                /* switch BDM to high impedance */ 
    ROL   i                 /* shift C into i (from the bottom) */ 
		NOP                     /* wait 1 more cycle */ 
    LDX   ,X                /* load X with value on the PTA port (including BDM_IN) */ 
		LSLX                    /* shift BDM_IN into C */ 
		LSLX 
    CLRX                    /* clear X again */ 
    BRN   0                 /* wait 3 cycles */ 
    /* bit 2 */                 
    mov #0x10,0 
    //STX   ,X                /* drive BDM low */ 
    //NOP                     /* wait 1 cycle */ 
    STA   ,X                /* switch BDM to high impedance */ 
    ROL   i                 /* shift C into i (from the bottom) */ 
		NOP                     /* wait 1 more cycle */ 
    LDX   ,X                /* load X with value on the PTA port (including BDM_IN) */ 
		LSLX                    /* shift BDM_IN into C */ 
		LSLX 
    CLRX                    /* clear X again */ 
    BRN   0                 /* wait 3 cycles */ 
    /* bit 1 */                 
    mov #0x10,0 
    //STX   ,X                /* drive BDM low */ 
    //NOP                     /* wait 1 cycle */ 
    STA   ,X                /* switch BDM to high impedance */ 
    ROL   i                 /* shift C into i (from the bottom) */ 
		NOP                     /* wait 1 more cycle */ 
    LDX   ,X                /* load X with value on the PTA port (including BDM_IN) */ 
		LSLX                    /* shift BDM_IN into C */ 
		LSLX 
    CLRX                    /* clear X again */ 
    BRN   0                 /* wait 3 cycles */ 
    /* bit 0 */                 
    mov #0x10,0 
    //STX   ,X                /* drive BDM low */ 
    //NOP                     /* wait 1 cycle */ 
    STA   ,X                /* switch BDM to high impedance */ 
    ROL   i                 /* shift C into i (from the bottom) */ 
		NOP                     /* wait 1 more cycle */ 
    LDX   ,X                /* load X with value on the PTA port (including BDM_IN) */ 
		LSLX                    /* shift BDM_IN into C */ 
		LSLX 
    ROL   i                 /* shift C into i (from the bottom) */ 
    LDA   i                 /* load the result into A */ 
  } 
} 
/* 2.25 - 3.25 MHz */ 
unsigned char bdm_rx7(void) { 
  asm { 
    LDA   #RESET_OUT_MASK	/* contents of A will be driven to PTA in order to switch the driver off */ 
    MOV   #8,j              /* store number of iterations into j */ 
    CLRH                    /* prepare H */ 
  loop: 
    /* the following construction is a bit awkward cause by the fact that there is time for loop iteration in the middle of the routine, but not at its end... */ 
    /* this is the end of bit processing, it is done 1 extra time before bit 7 (but that does not matter) */ 
    LDX   ,X                /* load X with value on the PTA port (including BDM_IN) */ 
		LSLX                    /* shift BDM_IN into C */ 
		LSLX 
    ROL   i                 /* shift C into i (from the bottom) */ 
    NOP                     /* wait 1 cycle (5 in total with ROL) */ 
    CLRX                    /* clear X for HX to point to PTA */ 
    /* here the bit begins */ 
    mov #0x10,0 
    //STX   ,X                /* drive BDM low */ 
    //NOP                     /* wait 1 cycle */ 
    STA   ,X                /* switch BDM to high impedance */ 
    DEC   j		              /* iterate the loop (this takes 7 cycles) */ 
    BNE   loop 
    /* finish processing of bit 0 (after exit from the loop) */ 
    LDX   ,X                /* load X with value on the PTA port (including BDM_IN) */ 
		LSLX                    /* shift BDM_IN into C */ 
		LSLX 
    ROL   i                 /* shift C into i (from the bottom) */ 
    LDA   i                 /* load the result into A */ 
  } 
} 
/* 1.8 - 2.6 MHz */ 
unsigned char bdm_rx8(void) { 
  asm { 
    LDA   #RESET_OUT_MASK	/* contents of A will be driven to PTA in order to switch the driver off */ 
    //LDA   #BDM_DIR1_MASK+RESET_OUT_MASK	/* contents of A will be driven to PTA in order to switch the driver off */ 
    MOV   #8,j              /* store number of iterations into j */ 
    CLRH                    /* prepare H */ 
  loop: 
    CLRX                    /* clear X to point to PTA, CLRX has been moved to the beginning of the algorithm here to prevent its execution for the last bit */ 
    mov #0x10,0 
     // 
    // 
    STA   ,X                /* switch BDM to high impedance */ 
    ROL   i                 /* shift C into i (from the bottom) */ 
    BRSET 0,DDRA,0          /* wait 5 cycles (9 in total with ROL) */ 
    LDX   ,X                /* load X with value on the PTA port (including BDM_IN) */ 
		LSLX                    /* shift BDM_IN into C */ 
		LSLX 
    DEC   j		              /* iterate the loop (this takes 7 cycles) */ 
    BNE   loop 
    ROL   i                 /* shift C into i (from the bottom) */ 
    LDA   i                 /* load the result into A */ 
  } 
} 
/* 1.5 - 2.166 MHz */ 
unsigned char bdm_rx9(void) { 
  asm { 
    LDA   #RESET_OUT_MASK	/* contents of A will be driven to PTA in order to switch the driver off */ 
    //LDA   #BDM_DIR1_MASK+RESET_OUT_MASK	/* contents of A will be driven to PTA in order to switch the driver off */ 
    MOV   #8,j              /* store number of iterations into j */ 
    CLRH                    /* prepare H */ 
  loop: 
    CLRX                    /* clear X to point to PTA, CLRX has been moved to the beginning of the algorithm here to prevent its execution for the last bit */ 
    mov #0x10,0 
     // 
    STA   ,X                /* switch BDM to high impedance */ 
    ROL   i                 /* shift C into i (from the bottom) */ 
    BIT   ,X                /* wait 8 cycles (12 in total with ROL) */ 
    BIT   ,X                 
    BIT   ,X                 
    BIT   ,X                 
    LDX   ,X                /* load X with value on the PTA port (including BDM_IN) */ 
		BIT   ,X                /* wait 9 cycles, iterate the loop while waiting (7 cycles) */ 
		LSLX                    /* shift BDM_IN into C */ 
		LSLX                    /* LSLX needs to be after the BIT as it chages C */   
    DEC   j		               
    BNE   loop 
    ROL   i                 /* shift C into i (from the bottom) */ 
    LDA   i                 /* load the result into A */ 
  } 
} 
/* 1.227 - 1.772 MHz */ 
unsigned char bdm_rx10(void) { 
  asm { 
    LDA   #RESET_OUT_MASK	/* contents of A will be driven to PTA in order to switch the driver off */ 
    MOV   #8,j              /* store number of iterations into j */ 
    CLRH                    /* prepare H */ 
  loop: 
    CLRX                    /* clear X to point to PTA, CLRX has been moved to the beginning of the algorithm here to prevent its execution for the last bit */ 
    mov #0x10,0 
    //STX   ,X                /* drive BDM low */BRN   0                 /* wait 3 cycles */ 
    STA   ,X                /* switch BDM to high impedance */ 
    BIT   ,X                /* wait 15 cycles */ 
    BIT   ,X                 
    BIT   ,X                 
    BIT   ,X                 
    BIT   ,X                 
    BIT   ,X                 
    BRN   0 
    LDX   ,X                /* load X with value on the PTA port (including BDM_IN) */ 
		LSLX                    /* shift BDM_IN into C */ 
		LSLX 
    ROL   i                 /* shift C into i (from the bottom) */ 
    BIT   ,X                /* wait 13 cycles, iterate the loop while waiting (7 cycles), ROL takes 4 cycles */ 
    DEC   j		               
    BNE   loop 
    LDA   i                 /* load the result into A */ 
  } 
} 
/* 1 - 1.444 MHz */ 
unsigned char bdm_rx11(void) { 
  asm { 
    LDA   #RESET_OUT_MASK	/* contents of A will be driven to PTA in order to switch the driver off */ 
    MOV   #8,j              /* store number of iterations into j */ 
    CLRH                    /* prepare H */ 
  loop: 
    CLRX                    /* clear X to point to PTA, CLRX has been moved to the beginning of the algorithm here to prevent its execution for the last bit */ 
    mov #0x10,0 
    //STX   ,X                /* drive BDM low */ 
    BIT   ,X                /* wait 4 cycles */ 
    BIT   ,X                 
    STA   ,X                /* switch BDM to high impedance */ 
    BIT   ,X                /* wait 19 cycles */ 
    BIT   ,X                 
    BIT   ,X                 
    BIT   ,X                 
    BIT   ,X                 
    BIT   ,X                 
    BIT   ,X                 
    BIT   ,X                 
    BRN   0 
    LDX   ,X                /* load X with value on the PTA port (including BDM_IN) */ 
		LSLX                    /* shift BDM_IN into C */ 
		LSLX 
    ROL   i                 /* shift C into i (from the bottom) */ 
    BIT   ,X                /* wait 16 cycles, iterate the loop while waiting (7 cycles), ROL takes 4 cycles */ 
    BRN   0 
    DEC   j		               
    BNE   loop 
    LDA   i                 /* load the result into A */ 
  } 
} 
/* 0.818 - 1.181 MHz */ 
unsigned char bdm_rx12(void) { 
  asm { 
    LDA   #RESET_OUT_MASK	/* contents of A will be driven to PTA in order to switch the driver off */ 
    MOV   #8,j              /* store number of iterations into j */ 
    CLRH                    /* prepare H */ 
  loop: 
    CLRX                    /* clear X to point to PTA, CLRX has been moved to the beginning of the algorithm here to prevent its execution for the last bit */ 
    mov #0x10,0 
    //STX   ,X                /* drive BDM low */ 
    BIT   ,X                /* wait 6 cycles */ 
    BIT   ,X                 
    BIT   ,X                 
    STA   ,X                /* switch BDM to high impedance */ 
    MOV   #2,k              /* wait 23 cycles (= 4 + 2*9 + 1) */ 
  wait1: 
    BIT   ,X 
    DEC   k 
    BNE   wait1 
    NOP 
    LDX   ,X                /* load X with value on the PTA port (including BDM_IN) */ 
		LSLX                    /* shift BDM_IN into C */ 
		LSLX 
    ROL   i                 /* shift C into i (from the bottom) */ 
    BIT   ,X                /* wait 21 cycles, iterate the loop while waiting (7 cycles), ROL takes 4 cycles */ 
    BIT   ,X 
    BIT   ,X 
    BIT   ,X 
    BIT   ,X 
    DEC   j		               
    BNE   loop 
    LDA   i                 /* load the result into A */ 
  } 
} 
/* 0.658 - 0.951 MHz */ 
unsigned char bdm_rx13(void) { 
  asm { 
    LDA   #RESET_OUT_MASK	/* contents of A will be driven to PTA in order to switch the driver off */ 
    MOV   #8,j              /* store number of iterations into j */ 
    CLRH                    /* prepare H */ 
  loop: 
    CLRX                    /* clear X to point to PTA, CLRX has been moved to the beginning of the algorithm here to prevent its execution for the last bit */ 
    mov #0x10,0 
    //STX   ,X                /* drive BDM low */ 
    BIT   ,X                /* wait 8 cycles */ 
    BIT   ,X                 
    BIT   ,X                 
    BIT   ,X                 
    STA   ,X                /* switch BDM to high impedance */ 
    MOV   #3,k              /* wait 29 cycles (= 4 + 3*8 + 1) */ 
  wait1: 
    NOP 
    DEC   k 
    BNE   wait1 
    NOP 
    LDX   ,X                /* load X with value on the PTA port (including BDM_IN) */ 
		LSLX                    /* shift BDM_IN into C */ 
		LSLX 
    ROL   i                 /* shift C into i (from the bottom) */ 
    BIT   ,X                /* wait 27 cycles, iterate the loop while waiting (7 cycles), ROL takes 4 cycles */ 
    BIT   ,X 
    BIT   ,X 
    BIT   ,X 
    BIT   ,X 
    BIT   ,X 
    BIT   ,X 
    BIT   ,X 
    DEC   j		               
    BNE   loop 
    LDA   i                 /* load the result into A */ 
  } 
} 
/* 0.529 - 0.764 MHz */ 
unsigned char bdm_rx14(void) { 
  asm { 
    LDA   #RESET_OUT_MASK	/* contents of A will be driven to PTA in order to switch the driver off */ 
    MOV   #8,j              /* store number of iterations into j */ 
    CLRH                    /* prepare H */ 
  loop: 
    CLRX                    /* clear X to point to PTA, CLRX has been moved to the beginning of the algorithm here to prevent its execution for the last bit */ 
   mov #0x10,0 
    //STX   ,X                /* drive BDM low */ 
    BIT   ,X                /* wait 10 cycles */ 
    BIT   ,X                 
    BIT   ,X                 
    BIT   ,X                 
    BIT   ,X                 
    STA   ,X                /* switch BDM to high impedance */ 
    MOV   #4,k              /* wait 37 cycles (= 4 + 4*8 + 1) */ 
  wait1: 
    NOP 
    DEC   k 
    BNE   wait1 
    NOP 
    LDX   ,X                /* load X with value on the PTA port (including BDM_IN) */ 
		LSLX                    /* shift BDM_IN into C */ 
		LSLX 
    ROL   i                 /* shift C into i (from the bottom) */ 
    MOV   #2,k              /* wait 35 cycles, iterate the loop while waiting (7 cycles), ROL takes 4 cycles */ 
  wait2:		  							/* 35 = 4 + 2*10 + 4 + 7 */ 
    BRN   0 
    DEC   k 
    BNE   wait2 
    DEC   j		               
    BNE   loop 
    LDA   i                 /* load the result into A */ 
  } 
} 
/* 0.421 - 0.609 MHz */ 
unsigned char bdm_rx15(void) { 
  asm { 
    LDA   #RESET_OUT_MASK	/* contents of A will be driven to PTA in order to switch the driver off */ 
    MOV   #8,j              /* store number of iterations into j */ 
    CLRH                    /* prepare H */ 
  loop: 
    CLRX                    /* clear X to point to PTA, CLRX has been moved to the beginning of the algorithm here to prevent its execution for the last bit */ 
   mov #0x10,0 
    //STX   ,X                /* drive BDM low */ 
    BIT   ,X                /* wait 13 cycles */ 
    BIT   ,X                 
    BIT   ,X                 
    BIT   ,X                 
    BIT   ,X                 
    BRN   0 
    STA   ,X                /* switch BDM to high impedance */ 
    MOV   #6,k              /* wait 46 cycles (= 4 + 6*7) */ /* wait 47 cycles (= 4 + 6*7 + 1) */ 
  wait1: 
    DEC   k 
    BNE   wait1 
/*  NOP  */ 
    LDX   ,X                /* load X with value on the PTA port (including BDM_IN) */ 
		LSLX                    /* shift BDM_IN into C */ 
		LSLX 
    ROL   i                 /* shift C into i (from the bottom) */ 
    MOV   #3,k              /* wait 45 cycles, iterate the loop while waiting (7 cycles), ROL takes 4 cycles */ 
  wait2:		  							/* 45 = 4 + 3*10 + 4 + 7 */ 
    BRN   0 
    DEC   k 
    BNE   wait2 
    DEC   j		               
    BNE   loop 
    LDA   i                 /* load the result into A */ 
  } 
} 
 
/* decodes values recorded by RX functions */ 
/* expects LSB data in X and remaining 7 bytes on stack */ 
/* it is expected that caller will JUMP into this routine */ 
void rx_stack_decode(void) { 
  asm { 
    MOV   #8,i 
  decode:   
    ROLX                    /* get the interesting bit into C (it is bit 6) */ 
    ROLX 
    RORA                    /* and rotate it into A from the top */ 
    PULX                    /* get the next value from stack */ 
    DEC   i 
    BNE   decode 
    PSHX                    /* that was one pop too many, so push the value back */ 
  }				 
} 
 
/* transmit 8 bits of data, MSB first */ 
/* expects DIR2 active and DIR1 inactive (call bdm_tx_prepare) */  
/* target frequency 6.6 - 8.4 MHz (this is BDM frequency (=crystal/2)) */ 
void bdm_tx1(unsigned char data) { 
  asm { 
    CLRX					/* HX points to PTA */ 
    CLRH 
    MOV   #0x01,BDM_DIR2_PORT    /* start driving the BDM */ 
    /* bit 7 (MSB) */ 
    SEC           /* set C */ 
    CLR   ,X      /* bring BDM low */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    RORA          /* set MSB of A */ 
    STA   ,X      /* bring BDM high */ 
    ROLA          /* advance to next bit */ 
    ROLA           
    /* bit 6 */ 
    SEC           /* set C */ 
    CLR   ,X      /* bring BDM low */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    RORA          /* set MSB of A */ 
    STA   ,X      /* bring BDM high */ 
    ROLA          /* advance to next bit */ 
    ROLA           
    /* bit 5 */ 
    SEC           /* set C */ 
    CLR   ,X      /* bring BDM low */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    RORA          /* set MSB of A */ 
    STA   ,X      /* bring BDM high */ 
    ROLA          /* advance to next bit */ 
    ROLA           
    /* bit 4 */ 
    SEC           /* set C */ 
    CLR   ,X      /* bring BDM low */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    RORA          /* set MSB of A */ 
    STA   ,X      /* bring BDM high */ 
    ROLA          /* advance to next bit */ 
    ROLA           
    /* bit 3 */ 
    SEC           /* set C */ 
    CLR   ,X      /* bring BDM low */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    RORA          /* set MSB of A */ 
    STA   ,X      /* bring BDM high */ 
    ROLA          /* advance to next bit */ 
    ROLA           
    /* bit 2 */ 
    SEC           /* set C */ 
    CLR   ,X      /* bring BDM low */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    RORA          /* set MSB of A */ 
    STA   ,X      /* bring BDM high */ 
    ROLA          /* advance to next bit */ 
    ROLA           
    /* bit 1 */ 
    SEC           /* set C */ 
    CLR   ,X      /* bring BDM low */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    RORA          /* set MSB of A */ 
    STA   ,X      /* bring BDM high */ 
    ROLA          /* advance to next bit */ 
    ROLA           
    /* bit 0 */ 
    SEC           /* set C */ 
    CLR   ,X      /* bring BDM low */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    RORA          /* set MSB of A */ 
    STA   ,X      /* bring BDM high */ 
    MOV   #0,BDM_DIR2_PORT              /* stop driving the BDM */ 
  } 
  ACKN_CLR;    /* clear ACKN flag */ 
  /* it takes 8 cycles from end of the last bit till enable of the ACKN capture */ 
  /* that is short enough for BDM freq of: (32+16)*3/8 = 18 MHz */ 
  /* 32+16 comes from minimum delay between command and ACKN (32 BDM cycles) and 16 cycles of the ACKN pulse (capturing its rising edge) */ 
} 
/* target frequency 5.5 - 7 MHz (this is BDM frequency (=crystal/2)) */ 
void bdm_tx2(unsigned char data) { 
  asm { 
    CLRX					/* HX points to PTA */ 
    CLRH 
    MOV   #01,BDM_DIR2_PORT    /* start driving the BDM */ 
    /* bit 7 (MSB) */ 
    CLR   ,X      /* bring BDM low */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    ORA   #BDM_OUT_MASK /* set MSB of A */ 
    STA   ,X      /* bring BDM high */ 
    LSLA          /* advance to next bit */ 
    /* bit 6 */ 
    CLR   ,X      /* bring BDM low */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    ORA   #BDM_OUT_MASK /* set MSB of A */ 
    STA   ,X      /* bring BDM high */ 
    LSLA          /* advance to next bit */ 
    /* bit 5 */ 
    CLR   ,X      /* bring BDM low */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    ORA   #BDM_OUT_MASK /* set MSB of A */ 
    STA   ,X      /* bring BDM high */ 
    LSLA          /* advance to next bit */ 
    /* bit 4 */ 
    CLR   ,X      /* bring BDM low */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    ORA   #BDM_OUT_MASK /* set MSB of A */ 
    STA   ,X      /* bring BDM high */ 
    LSLA          /* advance to next bit */ 
    /* bit 3 */ 
    CLR   ,X      /* bring BDM low */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    ORA   #BDM_OUT_MASK /* set MSB of A */ 
    STA   ,X      /* bring BDM high */ 
    LSLA          /* advance to next bit */ 
    /* bit 2 */ 
    CLR   ,X      /* bring BDM low */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    ORA   #BDM_OUT_MASK /* set MSB of A */ 
    STA   ,X      /* bring BDM high */ 
    LSLA          /* advance to next bit */ 
    /* bit 1 */ 
    CLR   ,X      /* bring BDM low */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    ORA   #BDM_OUT_MASK /* set MSB of A */ 
    STA   ,X      /* bring BDM high */ 
    LSLA          /* advance to next bit */ 
    /* bit 0 */ 
    CLR   ,X      /* bring BDM low */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    ORA   #BDM_OUT_MASK /* set MSB of A */ 
    STA   ,X      /* bring BDM high */ 
    MOV   #0,BDM_DIR2_PORT              /* stop driving the BDM */ 
  } 
  ACKN_CLR;    /* clear ACKN flag */ 
} 
/* target frequency 4.714 - 6 MHz (this is BDM frequency (=crystal/2)) */ 
void bdm_tx3(unsigned char data) { 
  asm { 
    CLRX					/* HX points to PTA */ 
    CLRH 
    MOV   #01,BDM_DIR2_PORT    /* start driving the BDM */ 
    /* bit 7 (MSB) */ 
    CLR   ,X      /* bring BDM low */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    ORA   #BDM_OUT_MASK /* set MSB of A */ 
    NOP           /* wait 1 cycle */ 
    STA   ,X      /* bring BDM high */ 
    LSLA          /* advance to next bit */ 
    NOP           /* wait 1 cycle */ 
    /* bit 6 */ 
    CLR   ,X      /* bring BDM low */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    ORA   #BDM_OUT_MASK /* set MSB of A */ 
    NOP           /* wait 1 cycle */ 
    STA   ,X      /* bring BDM high */ 
    LSLA          /* advance to next bit */ 
    NOP           /* wait 1 cycle */ 
    /* bit 5 */ 
    CLR   ,X      /* bring BDM low */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    ORA   #BDM_OUT_MASK /* set MSB of A */ 
    NOP           /* wait 1 cycle */ 
    STA   ,X      /* bring BDM high */ 
    LSLA          /* advance to next bit */ 
    NOP           /* wait 1 cycle */ 
    /* bit 4 */ 
    CLR   ,X      /* bring BDM low */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    ORA   #BDM_OUT_MASK /* set MSB of A */ 
    NOP           /* wait 1 cycle */ 
    STA   ,X      /* bring BDM high */ 
    LSLA          /* advance to next bit */ 
    NOP           /* wait 1 cycle */ 
    /* bit 3 */ 
    CLR   ,X      /* bring BDM low */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    ORA   #BDM_OUT_MASK /* set MSB of A */ 
    NOP           /* wait 1 cycle */ 
    STA   ,X      /* bring BDM high */ 
    LSLA          /* advance to next bit */ 
    NOP           /* wait 1 cycle */ 
    /* bit 2 */ 
    CLR   ,X      /* bring BDM low */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    ORA   #BDM_OUT_MASK /* set MSB of A */ 
    NOP           /* wait 1 cycle */ 
    STA   ,X      /* bring BDM high */ 
    LSLA          /* advance to next bit */ 
    NOP           /* wait 1 cycle */ 
    /* bit 1 */ 
    CLR   ,X      /* bring BDM low */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    ORA   #BDM_OUT_MASK /* set MSB of A */ 
    NOP           /* wait 1 cycle */ 
    STA   ,X      /* bring BDM high */ 
    LSLA          /* advance to next bit */ 
    NOP           /* wait 1 cycle */ 
    /* bit 0 */ 
    CLR   ,X      /* bring BDM low */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    ORA   #BDM_OUT_MASK /* set MSB of A */ 
    NOP           /* wait 1 cycle */ 
    STA   ,X      /* bring BDM high */ 
    MOV   #0,BDM_DIR2_PORT              /* stop driving the BDM */ 
  } 
  ACKN_CLR;    /* clear ACKN flag */ 
} 
/* target frequency 4.125 - 5.25 MHz (this is BDM frequency (=crystal/2)) */ 
void bdm_tx4(unsigned char data) { 
  asm { 
    CLRX					/* HX points to PTA */ 
    CLRH 
    MOV   #01,BDM_DIR2_PORT    /* start driving the BDM */ 
    /* bit 7 (MSB) */ 
    CLR   ,X      /* bring BDM low */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    ORA   #BDM_OUT_MASK /* set MSB of A */ 
    BIT   ,X      /* wait 2 cycles */ 
    STA   ,X      /* bring BDM high */ 
    LSLA          /* advance to next bit */ 
    NOP           /* wait 1 cycle */ 
    /* bit 6 */ 
    CLR   ,X      /* bring BDM low */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    ORA   #BDM_OUT_MASK /* set MSB of A */ 
    BIT   ,X      /* wait 2 cycles */ 
    STA   ,X      /* bring BDM high */ 
    LSLA          /* advance to next bit */ 
    NOP           /* wait 1 cycle */ 
    /* bit 5 */ 
    CLR   ,X      /* bring BDM low */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    ORA   #BDM_OUT_MASK /* set MSB of A */ 
    BIT   ,X      /* wait 2 cycles */ 
    STA   ,X      /* bring BDM high */ 
    LSLA          /* advance to next bit */ 
    NOP           /* wait 1 cycle */ 
    /* bit 4 */ 
    CLR   ,X      /* bring BDM low */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    ORA   #BDM_OUT_MASK /* set MSB of A */ 
    BIT   ,X      /* wait 2 cycles */ 
    STA   ,X      /* bring BDM high */ 
    LSLA          /* advance to next bit */ 
    NOP           /* wait 1 cycle */ 
    /* bit 3 */ 
    CLR   ,X      /* bring BDM low */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    ORA   #BDM_OUT_MASK /* set MSB of A */ 
    BIT   ,X      /* wait 2 cycles */ 
    STA   ,X      /* bring BDM high */ 
    LSLA          /* advance to next bit */ 
    NOP           /* wait 1 cycle */ 
    /* bit 2 */ 
    CLR   ,X      /* bring BDM low */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    ORA   #BDM_OUT_MASK /* set MSB of A */ 
    BIT   ,X      /* wait 2 cycles */ 
    STA   ,X      /* bring BDM high */ 
    LSLA          /* advance to next bit */ 
    NOP           /* wait 1 cycle */ 
    /* bit 1 */ 
    CLR   ,X      /* bring BDM low */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    ORA   #BDM_OUT_MASK /* set MSB of A */ 
    BIT   ,X      /* wait 2 cycles */ 
    STA   ,X      /* bring BDM high */ 
    LSLA          /* advance to next bit */ 
    NOP           /* wait 1 cycle */ 
    /* bit 0 */ 
    CLR   ,X      /* bring BDM low */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    ORA   #BDM_OUT_MASK /* set MSB of A */ 
    BIT   ,X      /* wait 2 cycles */ 
    STA   ,X      /* bring BDM high */ 
    MOV   #0,BDM_DIR2_PORT              /* stop driving the BDM */ 
  } 
  ACKN_CLR;    /* clear ACKN flag */ 
} 
/* target frequency 3.667 - 4.667 MHz (this is BDM frequency (=crystal/2)) */ 
void bdm_tx5(unsigned char data) { 
  asm { 
    CLRX					/* HX points to PTA */ 
    CLRH 
    MOV   #01,BDM_DIR2_PORT    /* start driving the BDM */ 
    /* bit 7 (MSB) */ 
    CLR   ,X      /* bring BDM low */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    ORA   #BDM_OUT_MASK /* set MSB of A */ 
    BRN   0       /* wait 3 cycles */ 
    STA   ,X      /* bring BDM high */ 
    LSLA          /* advance to next bit */ 
    BIT   ,X      /* wait 2 cycles */ 
    /* bit 6 */ 
    CLR   ,X      /* bring BDM low */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    ORA   #BDM_OUT_MASK /* set MSB of A */ 
    BRN   0       /* wait 3 cycles */ 
    STA   ,X      /* bring BDM high */ 
    LSLA          /* advance to next bit */ 
    BIT   ,X      /* wait 2 cycles */ 
    /* bit 5 */ 
    CLR   ,X      /* bring BDM low */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    ORA   #BDM_OUT_MASK /* set MSB of A */ 
    BRN   0       /* wait 3 cycles */ 
    STA   ,X      /* bring BDM high */ 
    LSLA          /* advance to next bit */ 
    BIT   ,X      /* wait 2 cycles */ 
    /* bit 4 */ 
    CLR   ,X      /* bring BDM low */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    ORA   #BDM_OUT_MASK /* set MSB of A */ 
    BRN   0       /* wait 3 cycles */ 
    STA   ,X      /* bring BDM high */ 
    LSLA          /* advance to next bit */ 
    BIT   ,X      /* wait 2 cycles */ 
    /* bit 3 */ 
    CLR   ,X      /* bring BDM low */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    ORA   #BDM_OUT_MASK /* set MSB of A */ 
    BRN   0       /* wait 3 cycles */ 
    STA   ,X      /* bring BDM high */ 
    LSLA          /* advance to next bit */ 
    BIT   ,X      /* wait 2 cycles */ 
    /* bit 2 */ 
    CLR   ,X      /* bring BDM low */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    ORA   #BDM_OUT_MASK /* set MSB of A */ 
    BRN   0       /* wait 3 cycles */ 
    STA   ,X      /* bring BDM high */ 
    LSLA          /* advance to next bit */ 
    BIT   ,X      /* wait 2 cycles */ 
    /* bit 1 */ 
    CLR   ,X      /* bring BDM low */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    ORA   #BDM_OUT_MASK /* set MSB of A */ 
    BRN   0       /* wait 3 cycles */ 
    STA   ,X      /* bring BDM high */ 
    LSLA          /* advance to next bit */ 
    BIT   ,X      /* wait 2 cycles */ 
    /* bit 0 */ 
    CLR   ,X      /* bring BDM low */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    ORA   #BDM_OUT_MASK /* set MSB of A */ 
    BRN   0       /* wait 3 cycles */ 
    STA   ,X      /* bring BDM high */ 
    MOV   #0,BDM_DIR2_PORT              /* stop driving the BDM */ 
  } 
  ACKN_CLR;    /* clear ACKN flag */ 
} 
/* target frequency 3.3 - 4.2 MHz (this is BDM frequency (=crystal/2)) */ 
void bdm_tx6(unsigned char data) { 
  asm { 
    CLRX					/* HX points to PTA */ 
    CLRH 
    MOV   #01,BDM_DIR2_PORT    /* start driving the BDM */ 
    /* bit 7 (MSB) */ 
    CLR   ,X      /* bring BDM low */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    ORA   #BDM_OUT_MASK /* set MSB of A */ 
    BIT   ,X      /* wait 4 cycles */ 
    BIT   ,X  
    STA   ,X      /* bring BDM high */ 
    LSLA          /* advance to next bit */ 
    BIT   ,X      /* wait 2 cycles */ 
    /* bit 6 */ 
    CLR   ,X      /* bring BDM low */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    ORA   #BDM_OUT_MASK /* set MSB of A */ 
    BIT   ,X      /* wait 4 cycles */ 
    BIT   ,X  
    STA   ,X      /* bring BDM high */ 
    LSLA          /* advance to next bit */ 
    BIT   ,X      /* wait 2 cycles */ 
    /* bit 5 */ 
    CLR   ,X      /* bring BDM low */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    ORA   #BDM_OUT_MASK /* set MSB of A */ 
    BIT   ,X      /* wait 4 cycles */ 
    BIT   ,X  
    STA   ,X      /* bring BDM high */ 
    LSLA          /* advance to next bit */ 
    BIT   ,X      /* wait 2 cycles */ 
    /* bit 4 */ 
    CLR   ,X      /* bring BDM low */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    ORA   #BDM_OUT_MASK /* set MSB of A */ 
    BIT   ,X      /* wait 4 cycles */ 
    BIT   ,X  
    STA   ,X      /* bring BDM high */ 
    LSLA          /* advance to next bit */ 
    BIT   ,X      /* wait 2 cycles */ 
    /* bit 3 */ 
    CLR   ,X      /* bring BDM low */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    ORA   #BDM_OUT_MASK /* set MSB of A */ 
    BIT   ,X      /* wait 4 cycles */ 
    BIT   ,X  
    STA   ,X      /* bring BDM high */ 
    LSLA          /* advance to next bit */ 
    BIT   ,X      /* wait 2 cycles */ 
    /* bit 2 */ 
    CLR   ,X      /* bring BDM low */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    ORA   #BDM_OUT_MASK /* set MSB of A */ 
    BIT   ,X      /* wait 4 cycles */ 
    BIT   ,X  
    STA   ,X      /* bring BDM high */ 
    LSLA          /* advance to next bit */ 
    BIT   ,X      /* wait 2 cycles */ 
    /* bit 1 */ 
    CLR   ,X      /* bring BDM low */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    ORA   #BDM_OUT_MASK /* set MSB of A */ 
    BIT   ,X      /* wait 4 cycles */ 
    BIT   ,X  
    STA   ,X      /* bring BDM high */ 
    LSLA          /* advance to next bit */ 
    BIT   ,X      /* wait 2 cycles */ 
    /* bit 0 */ 
    CLR   ,X      /* bring BDM low */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    ORA   #BDM_OUT_MASK /* set MSB of A */ 
    BIT   ,X      /* wait 4 cycles */ 
    BIT   ,X  
    STA   ,X      /* bring BDM high */ 
    MOV   #0,BDM_DIR2_PORT              /* stop driving the BDM */ 
  } 
  ACKN_CLR;    /* clear ACKN flag */ 
} 
/* target frequency 3 - 3.818 MHz (this is BDM frequency (=crystal/2)) */ 
void bdm_tx7(unsigned char data) { 
  asm { 
    CLRX					/* HX points to PTA */ 
    CLRH 
    MOV   #01,BDM_DIR2_PORT    /* start driving the BDM */ 
    /* bit 7 (MSB) */ 
    CLR   ,X      /* bring BDM low */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    ORA   #BDM_OUT_MASK /* set MSB of A */ 
    BIT   ,X      /* wait 5 cycles */ 
    BRN   0 
    STA   ,X      /* bring BDM high */ 
    LSLA          /* advance to next bit */ 
    BIT   ,X      /* wait 2 cycles */ 
    /* bit 6 */ 
    CLR   ,X      /* bring BDM low */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    ORA   #BDM_OUT_MASK /* set MSB of A */ 
    BIT   ,X      /* wait 5 cycles */ 
    BRN   0 
    STA   ,X      /* bring BDM high */ 
    LSLA          /* advance to next bit */ 
    BIT   ,X      /* wait 2 cycles */ 
    /* bit 5 */ 
    CLR   ,X      /* bring BDM low */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    ORA   #BDM_OUT_MASK /* set MSB of A */ 
    BIT   ,X      /* wait 5 cycles */ 
    BRN   0 
    STA   ,X      /* bring BDM high */ 
    LSLA          /* advance to next bit */ 
    BIT   ,X      /* wait 2 cycles */ 
    /* bit 4 */ 
    CLR   ,X      /* bring BDM low */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    ORA   #BDM_OUT_MASK /* set MSB of A */ 
    BIT   ,X      /* wait 5 cycles */ 
    BRN   0 
    STA   ,X      /* bring BDM high */ 
    LSLA          /* advance to next bit */ 
    BIT   ,X      /* wait 2 cycles */ 
    /* bit 3 */ 
    CLR   ,X      /* bring BDM low */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    ORA   #BDM_OUT_MASK /* set MSB of A */ 
    BIT   ,X      /* wait 5 cycles */ 
    BRN   0 
    STA   ,X      /* bring BDM high */ 
    LSLA          /* advance to next bit */ 
    BIT   ,X      /* wait 2 cycles */ 
    /* bit 2 */ 
    CLR   ,X      /* bring BDM low */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    ORA   #BDM_OUT_MASK /* set MSB of A */ 
    BIT   ,X      /* wait 5 cycles */ 
    BRN   0 
    STA   ,X      /* bring BDM high */ 
    LSLA          /* advance to next bit */ 
    BIT   ,X      /* wait 2 cycles */ 
    /* bit 1 */ 
    CLR   ,X      /* bring BDM low */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    ORA   #BDM_OUT_MASK /* set MSB of A */ 
    BIT   ,X      /* wait 5 cycles */ 
    BRN   0 
    STA   ,X      /* bring BDM high */ 
    LSLA          /* advance to next bit */ 
    BIT   ,X      /* wait 2 cycles */ 
    /* bit 0 */ 
    CLR   ,X      /* bring BDM low */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    ORA   #BDM_OUT_MASK /* set MSB of A */ 
    BIT   ,X      /* wait 5 cycles */ 
    BRN   0 
    STA   ,X      /* bring BDM high */ 
    MOV   #0,BDM_DIR2_PORT              /* stop driving the BDM */ 
  } 
  ACKN_CLR;    /* clear ACKN flag */ 
} 
/* target frequency 2.538 - 3.231 MHz (this is BDM frequency (=crystal/2)) */ 
void bdm_tx8(unsigned char data) { 
  asm { 
    CLRX					/* HX points to PTA */ 
    CLRH 
    MOV   #01,BDM_DIR2_PORT    /* start driving the BDM */ 
    /* bit 7 (MSB) */ 
    CLR   ,X      /* bring BDM low */ 
    NOP           /* wait 1 cycle */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    ORA   #BDM_OUT_MASK /* set MSB of A */ 
    BRN   0       /* wait 6 cycles */ 
    BRN   0 
    STA   ,X      /* bring BDM high */ 
    LSLA          /* advance to next bit */ 
    BRN   0       /* wait 3 cycles */ 
    /* bit 6 */ 
    CLR   ,X      /* bring BDM low */ 
    NOP           /* wait 1 cycle */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    ORA   #BDM_OUT_MASK /* set MSB of A */ 
    BRN   0       /* wait 6 cycles */ 
    BRN   0 
    STA   ,X      /* bring BDM high */ 
    LSLA          /* advance to next bit */ 
    BRN   0       /* wait 3 cycles */ 
    /* bit 5 */ 
    CLR   ,X      /* bring BDM low */ 
    NOP           /* wait 1 cycle */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    ORA   #BDM_OUT_MASK /* set MSB of A */ 
    BRN   0       /* wait 6 cycles */ 
    BRN   0 
    STA   ,X      /* bring BDM high */ 
    LSLA          /* advance to next bit */ 
    BRN   0       /* wait 3 cycles */ 
    /* bit 4 */ 
    CLR   ,X      /* bring BDM low */ 
    NOP           /* wait 1 cycle */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    ORA   #BDM_OUT_MASK /* set MSB of A */ 
    BRN   0       /* wait 6 cycles */ 
    BRN   0 
    STA   ,X      /* bring BDM high */ 
    LSLA          /* advance to next bit */ 
    BRN   0       /* wait 3 cycles */ 
    /* bit 3 */ 
    CLR   ,X      /* bring BDM low */ 
    NOP           /* wait 1 cycle */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    ORA   #BDM_OUT_MASK /* set MSB of A */ 
    BRN   0       /* wait 6 cycles */ 
    BRN   0 
    STA   ,X      /* bring BDM high */ 
    LSLA          /* advance to next bit */ 
    BRN   0       /* wait 3 cycles */ 
    /* bit 2 */ 
    CLR   ,X      /* bring BDM low */ 
    NOP           /* wait 1 cycle */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    ORA   #BDM_OUT_MASK /* set MSB of A */ 
    BRN   0       /* wait 6 cycles */ 
    BRN   0 
    STA   ,X      /* bring BDM high */ 
    LSLA          /* advance to next bit */ 
    BRN   0       /* wait 3 cycles */ 
    /* bit 1 */ 
    CLR   ,X      /* bring BDM low */ 
    NOP           /* wait 1 cycle */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    ORA   #BDM_OUT_MASK /* set MSB of A */ 
    BRN   0       /* wait 6 cycles */ 
    BRN   0 
    STA   ,X      /* bring BDM high */ 
    LSLA          /* advance to next bit */ 
    BRN   0       /* wait 3 cycles */ 
    /* bit 0 */ 
    CLR   ,X      /* bring BDM low */ 
    NOP           /* wait 1 cycle */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    ORA   #BDM_OUT_MASK /* set MSB of A */ 
    BRN   0       /* wait 6 cycles */ 
    BRN   0 
    STA   ,X      /* bring BDM high */ 
    MOV   #0,BDM_DIR2_PORT              /* stop driving the BDM */ 
  } 
  ACKN_CLR;    /* clear ACKN flag */ 
} 
/* target frequency 2.2 - 2.8 MHz (this is BDM frequency (=crystal/2)) */ 
void bdm_tx9(unsigned char data) { 
  asm { 
    CLRX					/* HX points to PTA */ 
    CLRH 
    MOV   #8,i    /* store number of iterations to go through */ 
    SEC           /* set C */ 
    RORA          /* pre-rotate A, A now has '1' in MSB, so the extra assignement in first loop iteration does not matter */ 
    MOV   #01,BDM_DIR2_PORT /* start driving the BDM */ 
  loop: 
    /* this is the end of the algorithm */ 
    /* the halves are back to front because there is more time in the middle to iterate the loop */ 
    STA   ,X      /* bring BDM high */ 
    ROLA          /* advance to next bit */ 
    BIT   ,X      /* wait 4 cycles */ 
    BIT   ,X  
    /* this is beginning of the algorithm */ 
    CLR   ,X      /* bring BDM low */ 
    NOP           /* wait 1 cycle */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    ORA   #BDM_OUT_MASK /* set MSB of A */ 
    NOP           /* wait 8 cycles, iterate the loop while waiting */ 
		DEC   i 
    BNE   loop 
    /* finish the last bit */ 
    STA   ,X      /* bring BDM high */ 
    MOV   #0,BDM_DIR2_PORT /* stop driving the BDM */ 
  } 
  ACKN_CLR;    /* clear ACKN flag */ 
} 
/* target frequency 1.941 - 2.471 MHz (this is BDM frequency (=crystal/2)) */ 
void bdm_tx10(unsigned char data) { 
  asm { 
    CLRX					/* HX points to PTA */ 
    CLRH 
    MOV   #8,i    /* store number of iterations to go through */ 
    SEC           /* set C */ 
    RORA          /* pre-rotate A, A now has '1' in MSB, so the extra assignement in first loop iteration does not matter */ 
    MOV   #01,BDM_DIR2_PORT /* start driving the BDM */ 
  loop: 
    /* this is the end of the algorithm */ 
    /* the halves are back to front because there is more time in the middle to iterate the loop */ 
    STA   ,X      /* bring BDM high */ 
    ROLA          /* advance to next bit */ 
    BRSET 0,DDRA,0 /* wait 5 cycles */ 
    /* this is beginning of the algorithm */ 
    CLR   ,X      /* bring BDM low */ 
    BIT   ,X      /* wait 2 cycles */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    ORA   #BDM_OUT_MASK /* set MSB of A */ 
    BIT   ,X      /* wait 9 cycles, iterate the loop while waiting */ 
		DEC   i 
    BNE   loop 
    /* finish the last bit */ 
    STA   ,X      /* bring BDM high */ 
    MOV   #0,BDM_DIR2_PORT /* stop driving the BDM */ 
  } 
  ACKN_CLR;    /* clear ACKN flag */ 
} 
/* target frequency 1.65 - 2.1 MHz (this is BDM frequency (=crystal/2)) */ 
void bdm_tx11(unsigned char data) { 
  asm { 
    CLRX					/* HX points to PTA */ 
    CLRH 
    MOV   #8,i    /* store number of iterations to go through */ 
    MOV   #01,BDM_DIR2_PORT /* start driving the BDM */ 
  loop: 
    /* this is beginning of the algorithm */ 
    CLR   ,X      /* bring BDM low */ 
    BIT   ,X      /* wait 2 cycles */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    ORA   #BDM_OUT_MASK /* set MSB of A */ 
    BIT   ,X       /* wait 12 cycles */ 
    BIT   ,X  
    BIT   ,X  
    BIT   ,X  
    BIT   ,X  
    BIT   ,X  
    STA   ,X      /* bring BDM high */ 
    LSLA          /* advance to next bit */ 
		DEC   i       /* wait 7 cycles, iterate the loop while waiting */ 
    BNE   loop 
    MOV   #0,BDM_DIR2_PORT /* stop driving the BDM */ 
  } 
  ACKN_CLR;    /* clear ACKN flag */ 
} 
/* target frequency 1.435 - 1.826 MHz (this is BDM frequency (=crystal/2)) */ 
void bdm_tx12(unsigned char data) { 
  asm { 
    CLRX					/* HX points to PTA */ 
    CLRH 
    MOV   #8,i    /* store number of iterations to go through */ 
    MOV   #01,BDM_DIR2_PORT /* start driving the BDM */ 
  loop: 
    /* this is beginning of the algorithm */ 
    CLR   ,X      /* bring BDM low */ 
    BRN   0       /* wait 3 cycles */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    ORA   #BDM_OUT_MASK /* set MSB of A */ 
    BIT   ,X      /* wait 14 cycles */ 
    BIT   ,X  
    BIT   ,X  
    BIT   ,X  
    BIT   ,X  
    BIT   ,X  
    BIT   ,X  
    STA   ,X      /* bring BDM high */ 
    LSLA          /* advance to next bit */ 
		NOP           /* wait 8 cycles, iterate the loop while waiting */ 
		DEC   i        
    BNE   loop 
    MOV   #0,BDM_DIR2_PORT /* stop driving the BDM */ 
  } 
  ACKN_CLR;    /* clear ACKN flag */ 
} 
/* target frequency 1.222 - 1.556 MHz (this is BDM frequency (=crystal/2)) */ 
void bdm_tx13(unsigned char data) { 
  asm { 
    CLRX					/* HX points to PTA */ 
    CLRH 
    MOV   #8,i    /* store number of iterations to go through */ 
    MOV   #01,BDM_DIR2_PORT /* start driving the BDM */ 
  loop: 
    /* this is beginning of the algorithm */ 
    CLR   ,X      /* bring BDM low */ 
    BRN   0       /* wait 3 cycles */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    ORA   #BDM_OUT_MASK /* set MSB of A */ 
    BIT   ,X      /* wait 18 cycles */ 
    BIT   ,X  
    BIT   ,X  
    BIT   ,X  
    BIT   ,X  
    BIT   ,X  
    BIT   ,X  
    BIT   ,X  
    BIT   ,X  
    STA   ,X      /* bring BDM high */ 
    LSLA          /* advance to next bit */ 
		BRN   0       /* wait 10 cycles, iterate the loop while waiting */ 
		DEC   i        
    BNE   loop 
    MOV   #0,BDM_DIR2_PORT /* stop driving the BDM */ 
  } 
  ACKN_CLR;    /* clear ACKN flag */ 
} 
/* target frequency 1.031 - 1.313 MHz (this is BDM frequency (=crystal/2)) */ 
void bdm_tx14(unsigned char data) { 
  asm { 
    CLRX					/* HX points to PTA */ 
    CLRH 
    MOV   #8,i    /* store number of iterations to go through */ 
    MOV   #01,BDM_DIR2_PORT /* start driving the BDM */ 
  loop: 
    /* this is beginning of the algorithm */ 
    CLR   ,X      /* bring BDM low */ 
    BIT   ,X      /* wait 4 cycles */ 
    BIT   ,X  
    STA   ,X      /* assign value from MSB of A to BDM */ 
    ORA   #BDM_OUT_MASK /* set MSB of A */ 
    BIT   ,X      /* wait 22 cycles */ 
    BIT   ,X  
    BIT   ,X  
    BIT   ,X  
    BIT   ,X  
    BIT   ,X  
    BIT   ,X  
    BIT   ,X  
    BIT   ,X  
    BIT   ,X  
    BIT   ,X  
    STA   ,X      /* bring BDM high */ 
    LSLA          /* advance to next bit */ 
    BRSET 0,DDRA,0 /* wait 12 cycles, iterate the loop while waiting */ 
		DEC   i        
    BNE   loop 
    MOV   #0,BDM_DIR2_PORT /* stop driving the BDM */ 
  } 
  ACKN_CLR;    /* clear ACKN flag */ 
} 
/* target frequency 0.868 - 1.105 MHz (this is BDM frequency (=crystal/2)) */ 
void bdm_tx15(unsigned char data) { 
  asm { 
    CLRX					/* HX points to PTA */ 
    CLRH 
    MOV   #8,i    /* store number of iterations to go through */ 
    MOV   #01,BDM_DIR2_PORT /* start driving the BDM */ 
  loop: 
    /* this is beginning of the algorithm */ 
    CLR   ,X      /* bring BDM low */ 
    BRSET 0,DDRA,0 /* wait 5 cycles */ 
    STA   ,X      /* assign value from MSB of A to BDM */ 
    ORA   #BDM_OUT_MASK /* set MSB of A */ 
    MOV   #3,j     /* wait 27 cycles = 4 + 3*7 + 2 */ 
  wait1: 
    DEC   j 
    BNE   wait1 
    BIT   ,X  
    STA   ,X      /* bring BDM high */ 
    LSLA          /* advance to next bit */ 
    BIT   ,X      /* wait 12 cycles, iterate the loop while waiting */ 
    BIT   ,X  
    BIT   ,X  
    BIT   ,X  
    DEC   i        
    BNE   loop 
    MOV   #0,BDM_DIR2_PORT /* stop driving the BDM */ 
  } 
  ACKN_CLR;    /* clear ACKN flag */ 
} 
/* target frequency 0.733 - 0.933 MHz (this is BDM frequency (=crystal/2)) */ 
void bdm_tx16(unsigned char data) { 
  asm { 
    CLRX					/* HX points to PTA */ 
    CLRH 
    MOV   #8,i    /* store number of iterations to go through */ 
    MOV   #01,BDM_DIR2_PORT /* start driving the BDM */ 
  loop: 
    /* this is beginning of the algorithm */ 
    CLR   ,X      /* bring BDM low */ 
    BRN   0       /* wait 7 cycles */ 
    BIT   ,X  
    BIT   ,X  
    STA   ,X      /* assign value from MSB of A to BDM */ 
    ORA   #BDM_OUT_MASK /* set MSB of A */ 
    MOV   #4,j     /* wait 32 cycles = 4 + 4*7 */ 
  wait1: 
    DEC   j 
    BNE   wait1 
    STA   ,X      /* bring BDM high */ 
    LSLA          /* advance to next bit */ 
    BIT   ,X      /* wait 18 cycles, iterate the loop while waiting */ 
    BIT   ,X  
    BIT   ,X  
    BIT   ,X  
    BRN   0 
    DEC   i        
    BNE   loop 
    MOV   #0,BDM_DIR2_PORT /* stop driving the BDM */ 
  } 
  ACKN_CLR;    /* clear ACKN flag */ 
} 
/* target frequency 0.623 - 0.792 MHz (this is BDM frequency (=crystal/2)) */ 
void bdm_tx17(unsigned char data) { 
  asm { 
    CLRX					/* HX points to PTA */ 
    CLRH 
    MOV   #8,i    /* store number of iterations to go through */ 
    MOV   #01,BDM_DIR2_PORT /* start driving the BDM */ 
  loop: 
    /* this is beginning of the algorithm */ 
    CLR   ,X      /* bring BDM low */ 
    BIT   ,X      /* wait 8 cycles */ 
    BIT   ,X  
    BIT   ,X  
    BIT   ,X  
    STA   ,X      /* assign value from MSB of A to BDM */ 
    ORA   #BDM_OUT_MASK /* set MSB of A */ 
    MOV   #5,j     /* wait 39 cycles = 4 + 5*7 */ 
  wait1: 
    DEC   j 
    BNE   wait1 
    STA   ,X      /* bring BDM high */ 
    LSLA          /* advance to next bit */ 
    BIT   ,X      /* wait 22 cycles, iterate the loop while waiting */ 
    BIT   ,X  
    BIT   ,X  
    BIT   ,X  
    BIT   ,X  
    BIT   ,X  
    BRN   0 
    DEC   i        
    BNE   loop 
    MOV   #0,BDM_DIR2_PORT /* stop driving the BDM */ 
  } 
  ACKN_CLR;    /* clear ACKN flag */ 
} 
/* target frequency 0.532 - 0.677 MHz (this is BDM frequency (=crystal/2)) */ 
void bdm_tx18(unsigned char data) { 
  asm { 
    CLRX					/* HX points to PTA */ 
    CLRH 
    MOV   #8,i    /* store number of iterations to go through */ 
    MOV   #01,BDM_DIR2_PORT /* start driving the BDM */ 
  loop: 
    /* this is beginning of the algorithm */ 
    CLR   ,X      /* bring BDM low */ 
    BIT   ,X      /* wait 10 cycles */ 
    BIT   ,X  
    BIT   ,X  
    BIT   ,X  
    BIT   ,X  
    STA   ,X      /* assign value from MSB of A to BDM */ 
    ORA   #BDM_OUT_MASK /* set MSB of A */ 
    MOV   #6,j     /* wait 46 cycles = 4 + 6*7 */ 
  wait1: 
    DEC   j 
    BNE   wait1 
    STA   ,X      /* bring BDM high */ 
    LSLA          /* advance to next bit */ 
    BIT   ,X      /* wait 26 cycles, iterate the loop while waiting */ 
    BIT   ,X  
    BIT   ,X  
    BIT   ,X  
    BIT   ,X  
    BIT   ,X  
    BIT   ,X  
    BIT   ,X  
    BRN   0 
    DEC   i        
    BNE   loop 
    MOV   #0,BDM_DIR2_PORT /* stop driving the BDM */ 
  } 
  ACKN_CLR;    /* clear ACKN flag */ 
} 
/* target frequency 0.452 - 0.575 MHz (this is BDM frequency (=crystal/2)) */ 
void bdm_tx19(unsigned char data) { 
  asm { 
    CLRX					/* HX points to PTA */ 
    CLRH 
    MOV   #8,i    /* store number of iterations to go through */ 
    MOV   #01,BDM_DIR2_PORT /* start driving the BDM */ 
  loop: 
    /* this is beginning of the algorithm */ 
    CLR   ,X      /* bring BDM low */ 
    BIT   ,X      /* wait 12 cycles */ 
    BIT   ,X  
    BIT   ,X  
    BIT   ,X  
    BIT   ,X  
    BIT   ,X  
    STA   ,X      /* assign value from MSB of A to BDM */ 
    ORA   #BDM_OUT_MASK /* set MSB of A */ 
    MOV   #7,j    /* wait 55 cycles = 4 + 7*7 + 2 */ 
  wait1: 
    DEC   j 
    BNE   wait1 
    BIT   ,X  
    STA   ,X      /* bring BDM high */ 
    LSLA          /* advance to next bit */ 
    MOV   #2,j    /* wait 31 cycles = 4 + 2*7 + 6 + 7, iterate the loop while waiting */ 
  wait2: 
    DEC   j 
    BNE   wait2 
    BIT   ,X  
    BIT   ,X  
    BIT   ,X  
    DEC   i        
    BNE   loop 
    MOV   #0,BDM_DIR2_PORT /* stop driving the BDM */ 
  } 
  ACKN_CLR;    /* clear ACKN flag */ 
}