I am doing assembly after a long time. Need some guidance -
To load HX register from RAM,
I do LDHX ram. This should load (ram) to X and (ram+1) to H
I am trying to write code for a clock. I increment "RTCSEC" . When the value is 30d, that's equal to 30seconds.
At every 30secs, I increment RTCMIN. When RTCMIN is 120, I increment RTCHR. If the RTCMIN is not equal to 120, the code branches to incRTCMIN.
Is this correct?
cmp #$1E ; 30 seconds
What to put here???
incRTCMIN: clr RTCSEC
cmp #$78 ; 120 mins make an hour (since 30 secs make a min)
The assembly code for an "incrementing" solution might be as follows:
RTCSEC: DS.B 1
RTCMIN: DS.B 1
RTCHR: DS.B 1
; Increment RTC registers
RTC_INCR: INC RTCSEC
Decimal (rather than hexadecimal) constants may be used within the code, where these make more sense. If you are using a timer interrupt, the above subroutine could be called from within the associated ISR.
It's the other way around:
ldhx RAM ; H = (RAM) and X = (RAM + 1)
As for your code stub, I'm going to guess that this will be run as part of an interrupt service routine (ISR) that gets executed once a second(?). Make sure that you clear the source of the interrupt before you exit the ISR. I'm not sure why you're only counting to 30 seconds, but I'm guessing that you don't need to display these values. If that's the case, decrementing variables can be more efficient. If I assume that this is correct, and that your variables are located in direct page, I suggest considering something like this:
INIT_RTCSEC: equ $1E ; initial value for RTCSEC = 30
INIT_RTCMIN: equ $78 ; initial value for RTCMIN = 120
mov #INIT_RTCSEC, RTCSEC ; initialize RTCSEC
mov #INIT_RTCMIN, RTCMIN ; initialize RTCMIN
rts ; return
; clear the source of the interrupt
dbnz RTCSEC, ISR_clock_exit ; decrement RTCSEC and exit if it's not zero
mov #$1E, RTCSEC ; else, reload RTCSEC with 30
dbnz RTCMIN, ISR_clock_exit ; decrement RTCMIN and exit if not zero
mov #$78, RTCMIN ; else, reload RTCMIN with 120
inc RTCHR ; advance RTCHR
rti ; exit
I hope that this helps.
In the HX register, H is the MSByte and X is the LSbyte?
The HCS08 is big endian? unlike the 8085 which is little endian.
One more question -
How do I move a value to RAM ?
Mov #$02, RAM_location
Yes, H is the MSB and X is the LSB of the 16-bit Index Register.
The endian is the opposite of the 8085. This makes it a little easier to see 16- and 32-bit values in a memory dump (but everyone has their own preferences).
Using the MOV instruction requires that either the source address and/or the destination address be in the Direct Page (i.e., 0x0000 to 0x00FF inclusive). This is why it works when accessing (most) peripheral registers. So your value in RAM needs to be located in the Direct Page for your example to work.
(I apologize for the late response - I had a busy holiday season :smileyhappy:)