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
correct?
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?
inc RTCSEC
lda RTCSEC
cmp #$1E ; 30 seconds
beq incRTCMIN
What to put here???
incRTCMIN: clr RTCSEC
inc RTCMIN
lda RTCMIN
cmp #$78 ; 120 mins make an hour (since 30 secs make a min)
beq incRTCHR
bra incRTCMIN
Hello Derrick,
The assembly code for an "incrementing" solution might be as follows:
ORG Z_RAMStart
...
RTCSEC: DS.B 1
RTCMIN: DS.B 1
RTCHR: DS.B 1
ORG ROMStart
...
; Increment RTC registers
RTC_INCR: INC RTCSEC
LDA RTCSEC
CMP #30
BLO RI1
CLR RTCSEC
INC RTCMIN
LDA RTCMIN
CMP #120
BLO RI1
CLR RTCMIN
INC RTCHR
RI1: RTS
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.
Regards,
Mac
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
init_clock:
mov #INIT_RTCSEC, RTCSEC ; initialize RTCSEC
mov #INIT_RTCMIN, RTCMIN ; initialize RTCMIN
rts ; return
ISR_clock:
;
; 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
ISR_clock_exit:
rti ; exit
I hope that this helps.
Best Regards,
Derrick
Derrick,
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.
Best Regards,
Derrick
(I apologize for the late response - I had a busy holiday season :smileyhappy:)