HC08 ASM freak needs some tips from C geeks!

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

HC08 ASM freak needs some tips from C geeks!

2,663 Views
joerg
Contributor II
Hi there
as i am an oldie in ASM, but i would like to "convert" to C i need some tips.

The problem:
I would like to recycle my modules written in assembly. I tried to define a header file (xx.h) and i also have

modified the xx.asm module. his works fine, but how can i make my modules universal like i am used with asm.

Here the example:

Lets say the module uses a port for setting a bit. The port is named TST_PRT and the bits are defined in the

module. By including the module the TST_PRT is assigned in the main program, so the module is usable by

different programs and/or different MPU's.
The asm module could look like:

;tst.asm
XDEF TAST
XREF.B TST_PRT ;the port
XREF.B TST_z ;a counter

;TST_PRT ;the TAST port, defined in the main program
TST_C0 EQU 0 ;the bit definition for easyer access
TST_C1 EQU 1
TST_C2 EQU 2
TST_C3 EQU 4
;....and so on

TAST: ;the routine
BSET TST_C1,TST_PRT ;set the TST_C1 bit
INC Z_TST
TASTE: ;end of the routine
RTS

So far so good. I have now tried to write a tst.h header file looking like:

/*tst.h*/

#define TST_PRT PTAD

#pragma DATA_SEG __SHORT_SEG MY_ZEROPAGE

byte TST_z; / *the counter in the zero page */


void TAST(void); /*the entry point of the routine */



So and here my question: how do i have to define/redefine TST_PRT so it will be PTAD?
The above header does not work, the TST_PRT is not found by the linker. The rest of the header works this way.

Thanks for some advices

Joerg

Message Edited by CrasyCat on 2007-04-13 10:46 AM

Labels (1)
Tags (1)
0 Kudos
5 Replies

582 Views
Norm
Contributor I
Hi
My suggestion is, if you want to learn C, then start rewriting all of your assembler code in C.
It will be a valuable learning experience!
Norm
0 Kudos

582 Views
joerg
Contributor II
Hi Norm
thanks for the advise.
Knowing C for about 25 years (it was more hating "C") i do not really need to learn it. The point is to have a concept that allows me to reuse my asm code since i have a lot of perfect working modules for the HC(S)08 family (15 years of programming!). The integration has to bee a clean way to do that. So rewriting all my modules does not make too much sense. You could see a example how i did some integration of asm in a C project here:
http://www.systech-gmbh.ch/indexEBS08.html (EBS08C_QD4_51_10)
Even if it is not perfect -> it works!

Saluti Joerg
0 Kudos

582 Views
mjbcswitzerland
Specialist V
Joerg

Here's the method used in the uTasker project - it is a C based project and runs on a number of different processors and boards. The project can be moved between targets and boards by defining two flags (one for the processor and one (optional) for one of a number of boards)

Assume every project has an output which can be set or cleared.
To turn the output on and off the main project code does the following:
SET_TEST_OUTPUT(); // set the test output to '1'
CLEAR_TEST_OUTPUT(); // set the test output to '0'

A project header file (linked in every file) includes a hardware header file which is dependent on the processor and board.

// C file start
#include "config.h" // every file has this and here the processor and board type can be configured
..
SET_TEST_OUTPUT();
CLEAR_TEST_OUTPUT();
..
// C file end


In config.h the user can specify which board and processor is being used (eg. whether running on demo board or real target, where the ports may not necessarily be in the same place) [the processor can alternatively be configured by using a C pre-processor define. ie. configured in the compiler set up and the compiler then supplies the define to all code being compiled]

// start config.h
...
//#define _HW_68302 // commented out
#define _HW_M52233 // this processor is active
//#define _HW_HCS12D256 // commented out

#if defined (_HW_M52233)
#define M52233_DEMO // this board for the target is active
//#define M52233_PRODUCTION // commented out
#include "M52233_app.h" // include the application details for this processor
#endif
...
// end config.h


In the last include file (conditionally included for the particular processor) the details are sorted out.

For example in M52233_app.h the hardware and target dependent code is defined (it can also be in assember...!)

// start of M52233_app.h
...
#if defined (M52233_DEMO)
#define TEST_OUTPUT_BIT 0x02 // use this port output on the demo board
#elif defined (M52233_PRODUCTION)
#define TEST_OUTPUT_BIT 0x40 // use this output on the real target
#endif

SET_TEST_OUTPUT() GPIO_PORT_A |= TEST_OUTPUT_BIT
CLEAR_TEST_OUTPUT() GPIO_PORT_A &= ~TEST_OUTPUT_BIT
...
// end M52233_app.h


All of the detail work is therefore performed in one header file (it requires a header per processor type to be maintained). All configuration detail is in config.h.
It should be evident that if you are testing code on the demo board where the test port is bit 1 of the fictional GPIO_PORT_A, by modifying M52233_PRODUCTION to be defined rather than M52233_DEMO the code for the production board will use bit 6 (of course it could also be on a completely different GPIO).

The register defines are of course also defined in a hardware header for the processor but this is standard to all projects with that particular processor (eg. the hardware header delivered by the manufacturer).

This is what the register define may look like which would be compatible with the code above
#define GPIO_PORT_A *(unsigned char *)(PORT_MODULE_ADD + 0x1f)

As noted above there is also no reason why you can't also use assembler at that level - since most C-compilers allow inline assembler.
eg.
#define SET_TEST_OUTPUT() asm { xxxxxxx }

Last notes
- the defines can also be multiple lines long by using the '\' at the end of a line
eg.
#define INITIALISE_LCD_CONTROL_LINES() IO_BUS_PORT_DDR = 0; \
IO_BUS_PORT_DDR = 0; \
O_CONTROL_PORT_DDR &= ~(O_CONTROL_LINES | O_LCD_BACKLIGHT); \
O_CONTROL_PORT_DAT &= ~(O_CONTROL_LINES | O_LCD_BACKLIGHT); \
O_CONTROL_PORT_DAT |= (O_LCD_BACKLIGHT | O_WRITE_READ); \
O_CONTROL_PORT_DDR |= (O_CONTROL_LINES | O_LCD_BACKLIGHT);

- the defines can also be macros
#define SET_PORT_OUTPUT_VALUE(x) GPIO_PORT_A = x
or
#define SET_PORT_OUTPUT_VALUE(x) GPIO_PORT_A = ~x
(the second inverts the output should the hardware use negative logic so that the main project code always remains the same.

Once you get the hang of using these (or similar) techniques you should find project control of modules quite easy.

Regards

0 Kudos

582 Views
joerg
Contributor II
Thanks Mac and Mark

I will do some "research" to get how define the hardware labels in asm with the header file.

Saluti Joerg
0 Kudos

582 Views
bigmac
Specialist III
Hello Joerg,
 
I wonder if the problem might be that the C preprocessor does not do the label substitution, for the C style #define, within the wholly ASM file.  Perhaps there should be an ASM style include file containing the assignment -
 
TST_PRT:   EQU   PTAD
 
Another solution might be to use inline assembly within a C wrapper.
 
Regards,
Mac
 

Message Edited by bigmac on 2007-02-1901:35 AM

0 Kudos