Hints for making a DIY Calculator user program ============================================== Note: All of the following refers to using TASM (the Telemark Cross Assembler, http://home.comcast.net/~tasm/). The reasons for using TASM rather than the supplied DIY Calculator assembler are that TASM supports macros and include files, and can be run from a command line shell. You can download a shareware version of TASM from the above mentioned internet site. Note that the DIY Calculator assembler uses '#' as a line comment, whereas TASM uses the ';' character. On the physical implementation of the DIY Calculator when powering up there is already a program running, the ROM Monitor. It supplies basic functionality to be able to load, run, and debug user programs on the DIY Calculator hardware. Additional to that it is possible to use some functions, such as console I/O, delay, etc., which are used inside the ROM Monitor from a user program. To be able to do so you have to include the following statement into your assembler program: #include "monitor.inc" The file 'monitor.inc' must be in the same directroy as your assembler source file. For common definitions, such as I/O port addresses and bit masks you may include this line: #include "diy_calc.inc" Following functions are provided in the runtime environment of ROM monitor: --------------------------------------------------------------------------- putchar .. prints one character to the serial terminal the character is expected in the ACC register puts ..... prints a 0-terminated string to the serial terminal the address of the string is expected in the X register returns number of characters in ACC tstc ..... tests whether a character is available from the serial terminal return value in ACC: 0 - no character available getch .... reads one character from the serial terminal (blocking) waits for a character and returns char in ACC getche ... same as getch but additionally echos char back to terminal getchar .. reads and echos one character from the terminal, waits for carriage return to complete input gets ..... reads several characters from the terminal, input is terminated with CR. Replaces the CR with a '\0' character (0-terminated string) expects the address of a buffer for the string in X register atox ..... converts ASCII input to 8bit number, using hexadecimal radix expects address of 0-terminated string in X returns number in ACC atobx .... converts ASCII input to 16bit number, using hexadecimal radix expects address of 0-terminated string in X returns number in X strcpy ... copies a 0-terminated string to a second location 1) push the destination address onto the stack 2) push the source address onto the stack returns the destination address in X strcmp ... compares two 0-terminated strings push address of string 1 onto the stack push address of string 2 onto the stack returns in ACC: 1 - string 1 > string 2 0 - string 2 == string 2 -1 - string 1 < string 2 getarg ... get the next argument of a cmdline, i.e. a pointer to the next word in a white-sapce separated text line puthex ... print an 8bit value to the terminal using HEX radix expects the vaule in ACC puthex16 . print a 16bit valut to the terminal using HEX radix expects the value in X delay .... wait for a number of milliseconds expects the # millisecs in X Note that the delay time is not very accurate with small numbers note that the delay time is matched to 12.5MHz CPU frequency wait .... wait for a number of microseconds expects the # microsecs in X Note that the delay time is not very accurate with small numbers note that the delay time is matched to 12.5MHz CPU frequency How it works: ------------- Inside the monitor.inc file there are function pointers defined for each of the above functions. Additionally macros are defined to use the function pointers instead of direct function calls. During startup of the ROM monitor the function pointers are assigned to the address of the respective function. Example: puthex function - the code for the puthex function starts at label '_PUTHEX' - during startup the word variable 'PUTHEX' is assigned with '_PUTHEX' - the macro 'puthex' maps the function call: JSR [puthex] --> JSR [[PUTHEX]] So you would write in your code JSR [puthex] which looks like a normal function call. Through macro preprocessing of TASM this is changed to JSR [[PUTHEX]] using indirect addressing. The 16bit variable 'PUTHEX' (= the function pointer) contains the address of the code at label '_PUTHEX'. Of course you could write directly JSR [[PUTHEX]] but using the macro capability of TASM makes this more convenient. For details look into the code of the ROM monitor. 15.Dec.2006 Johannes Hausensteiner