I've been fooling around with the Merlin 8 (v2.58) assembler on my Apple IIe and ran into a small snag.
Basically, I would like to load the address of a block of data into a two-byte pair in zero page. The data block might represent ASCII text, or a lookup table or just about anything. In my case, I want to do this as a way of passing the pointer to a subroutine.
I've written a short "Hello World" program that shows an example of what I am trying to do. Please note, this question isn't about the best way to print text or taking advantage of possible convenience features or Macros within Merlin. I just wrote this code as an example of what I am trying to do.
ORG $0900
STRLO EQU $08
STRHI EQU $09
CHROUT EQU $FDED
START LDA PTR ;DATA PTR LSB TO STRLO
STA STRLO
LDA PTR+1 ;DATA PTR MSB TO STRHI
STA STRHI
JSR PRINT ;PRINT
RTS ;ALL DONE
PRINT LDY #$00
:CONT LDA (STRLO),Y
BEQ :DONE
JSR CHROUT
INY
JMP :CONT
:DONE RTS
DATA ASC "HELLO RCSE!",00
PTR DA DATA
If you look at the listing, there is a subroutine labeled PRINT that expects an address to be already loaded into two zero page registers STRLO and STRHI. As it's name implies, PRINT will simply start spitting out characters starting at the address in STRLO/STRHI until a null terminator is encountered. This means the calling thread is responsible for loading the address of the data to be printed into STRLO/STRHI.
This is where things seem overly complicated, which is a sure sign I am missing something simple. Merlin allows a convenient mechanism to define and label my data block (in this example my data is simply a short string) like this:
DATA ASC "HELLO RCSE!",00
What I would like to know is the correct way to load the address of this data into STRLO/STRHI before calling PRINT. My first try was to use the DATA label directly like this:
START LDA DATA
STA STRLO
LDA DATA+1
STA STRHI
but this results in the loading the first two bytes of the data, not the address of the data.
My second attempt to was to try adding the immediate mode prefix # to my LDA instructions, like this:
START LDA #DATA
STA STRLO
LDA #DATA+1
STA STRHI
but that resulted in simply loading 0 (zero) and 1 (one) into STRLO/STRHI.
Ultimately, the only thing I have figured out is that I can get the address by defining a second label to serve as a pointer to the data (as shown in my code). This works, but it seems clunky and makes me feel like I am simply missing the correct syntax to work with the address of DATA directly.
In modern terms, having to define a second label to serve as a pointer to the actual label has a bad smell, not to mention it doubles the number of labels for things like string tables, etc. Can anyone shed some light on this for me?