Page 1 of 1

Changing Hex in memory to Decimal on screen

Posted: Sat Dec 26, 2020 7:55 pm
by Gee-k
Hi folks. I'm looking at my ASM code again and have came up against my next great challenge. Showing numbers on the screen in decimal even though the numbers stored in memory are in hex.
So I'm making labels like so:

Code: Select all

;days
dayDate: db &0b
monthDate: db &04
yearDate: dw &0c73
which are going to then be printed on screen in decimal.
These numbers are going to be used in calculations and will change as the user presses up and down arrows depending on wither they are at the day, month or year selection.
My question is, how do I change a hex number into something I can then print on screen?
I was going to make some sort of equation that would then break things down and allocate the relevant hex number for the print char to print. I.e. &0b == Decimal 11 which would be broken into 1 and 1. I'd change that to &31 and &31, printing both (with the print char routine) out to give me 11 on screen.

Is this the correct way to go? maybe break it down using binary then compares depending on each nibble of the byte.
It'll get even more confusing when I get to the years.

I feel like this isn't going to be very efficient though.

Re: Changing Hex in memory to Decimal on screen

Posted: Sun Dec 27, 2020 7:18 am
by akuyou
I'm not saying it's the best, but here is the function I use to show decimal values from 0-255 from a single byte.

You mentioned splitting it into nibbles, so I guess you already know about binary coded decimal? (https://www.chibiakumas.com/z80/advanced.php#LessonA1)... That would certainly be what I would do if you need values that can't be stored in one byte.

Code: Select all

ShowDecimal:
DrawText_Decimal:	;Draw a 3 digit decimal number (non-BCD)
	ld hl,&640A
	ld b,a		
	
	cp h
	jr nc,DecThreeDigit
	
	call PrintSpace
	cp l 
	jr nc,SkipDigit100
	call PrintSpace
	jr SkipDigit10
	
DecThreeDigit:

	call DrawTextDecimalSub
SkipDigit100:
	ld h,l
	call DrawTextDecimalSub

SkipDigit10:
	ld a,b
DrawText_CharSprite48:
	add 48
DrawText_CharSpriteProtectBC:
	jp PrintChar; draw char

DrawTextDecimalSub:
	ld a,b
	ld c,0
DrawText_DecimalSubagain:
	cp h
	jr c,DrawText_DecimalLessThan	;Devide by 100
	inc c
	sub h
	jr DrawText_DecimalSubagain
DrawText_DecimalLessThan:
	ld b,a
	ld a,c
	or a		;We're going to do a compare as soon as we return
	jr DrawText_CharSprite48
	

Re: Changing Hex in memory to Decimal on screen

Posted: Sun Dec 27, 2020 4:09 pm
by Gee-k
Thank Keith,
I'm watching your bcd video now. Hopefully i'll understand that and be able to use that to fire numbers on screen.
although i'm not sure if that will cover the printing of each number.
I'll let you know how I get on!
:Cheers:

Re: Changing Hex in memory to Decimal on screen

Posted: Sun Jan 03, 2021 11:01 pm
by Gee-k
Thought i'd post a little on what I've been up to to try solve this without BCD.
Every time I tried to watch the video you have on BCD it turned out to be very late and I couldn't concentrate.

However, after sleeping on my issue I came up with another solution (I thought).
This was to do some >= statements (JP NC) then run another loop.

As we know, to print a character from 0 to 9 (&30 to &39) on the cpc we can call the print char routine with the characters hex code in 'a'.
If I start with &30 (bear with me on why its in bc just now) in 'bc' so that I can print a 0 if the compares show the number is below 10
Load the number from memory into 'a' and do a compare to see if its >= 10
If it is, then we run a routine to decrement 'a' by 10 and increment 'bc' by 1 (so it will now print a one if the print char is called with what is stored in memory via the a register).
This continues till we are < 10.
Then 'bc' is loaded into its memory location, then into 'a'.
Once thats in 'a', we can then run the print char routine.

My issue is that, I get the character to show on screen, it then goes to the next line which is WaitChar (for user input). If I press a key, I seem to get a loop of printing of memory instead of the next line which is to end the program. I'm no where near done with the program so that is why it'd going straight to an end.

Anyway, here is an extract of the code i'm talking about.

Code: Select all

;set constant PrinChar to firmware routine for printing characters. a contains character to be printer (in hex obviously)
PrintChar equ &bb5a
;set constant WaitChar to firmware routine for waiting on a keypress
WaitChar equ &bb06

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Hex to decimal printing routine
;print day number tens
ld a,(dayDate)		;load &0b into a
ld bc,&30			;load character 0 into bc

tensCompare:
cp 10			;compare a with 10
jp nc,decTens		;if >= jump to decTens
ld (dayDate),a		;loads remainder of date back into memoy location to be used at next stage
ld (dayTens),bc	;load contents of bc into 1st byte of dayTens memory location
ld a,(dayTens)		;loads 1st byte of dayTens into a
call PrintChar		;calls print character routine.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
call WaitChar
;End program
End:
ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;			Items to load on request then return
;			Program end before reaching here.
;			only loaded when called
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
decTens:
sub a,10			;subtract 10 from a
inc bc			;incriment bc by 1
call tensCompare

;date variables
dayDate: dw &000b
dayTens: dw &0000
dayOnes: dw &0000
If anyone has any ideas on what is going on it'd be appreciated.

Re: Changing Hex in memory to Decimal on screen

Posted: Tue Jan 05, 2021 9:55 pm
by Gee-k
I found the issue!

wait for it.

there was a missing ret command..

so happy to have found it.
Was just doing a bunch of break points and watching the program counter.

whilst thinking about this issue I thought of a few tweaks I can make to my code to make it quicker too.
every cloud.