Display Value to Screen

Page 1/2
| 2

By Chilly Willy

Rookie (30)

Chilly Willy's picture

07-12-2020, 15:57

Hey guys...New to the site.
I am an intermediate level Z80 programmer for the Colecovision and MSX 1
However, I still need to learn a lot.

If I may be so bold to ask anyone with the know how.

I looked everywhere with several places pushing BCD and other avenues to no success.

I would like to take a simple variable say (BUB)

LD A, 130
LD (BUB), A

Then be able to display whatever number is in (BUB) as a 3 digit value
So if 134 is inside (BUB) the screen will display 134

Or even be able to use DE, HL or whatever instead of using A

as in LD HL, (BUB) so I can use values over 256

The display routines I think I can figure out but it seems separating the hundreds from the tens from the ones is a bit beyond my capabilities.

Believe me I looked all over the net including this site but maybe I am just wording my search wrong.

Every game has a score
A lot of games have count down timers or room numbers.

Logic of moving sprites around or displaying screens I am in but something as simple as displaying a set of digits more than 10 is becoming a pain in the toot.

Any help would be great because I am stalled.

Thanks for reading and I will monitor frequently.

Login or register to post comments

By Metalion

Paragon (1319)

Metalion's picture

07-12-2020, 16:12

Usually, you just store the number in BCD.
Let's say you want to store the number 9999, you would store it using two bytes : 99h, 99h.

And then, when you need to display it, you just isolate the nibbles of the bytes.

ld	a,(score)
and	11110000b
rrca
rrca
rrca
rrca
add	48
call	CHPUT (or any other outputing routine)
ld	a,(score)
and	00001111b
add	48
call	CHPUT
...
(repeat for every score number)

By Chilly Willy

Rookie (30)

Chilly Willy's picture

07-12-2020, 16:17

I am seriously trying to follow.

If (BUB) is being updated by the program say randomly you are saying I can use this routine to extract whatever number is in (BUB).

So
LD A, (BUB)

How am I going to separate the 100's from the TENS then the TENS from ONES

By DamnedAngel

Master (210)

DamnedAngel's picture

07-12-2020, 16:53

Chilly Willy wrote:

How am I going to separate the 100's from the TENS then the TENS from ONES

Metalion is explaining that if you use BCD (1 digit per byte) or Packed BCD (better, 1 digit per nibble) they are already separated (in the sense that they are independent from each other). Ever group of 8 bits (BCD) or 4 bits (Packer BCD) stores a digit. Then you just add 48 and you have the ascii code for the digit.

Find more info here: https://www.chibiakumas.com/z80/advanced.php

[]'s

By Chilly Willy

Rookie (30)

Chilly Willy's picture

07-12-2020, 17:02

So what you are saying is that any number in memory is stored in BCD format and I have to extract it.

Maybe I am just confused.

Can somebody just post a tested routine that you can pass a value such as 194 to A and it will display 194 on the screen on the MSX 1.

Like I mentioned I am learning still.
I am certainly not trying to give you guy grief.

By Metalion

Paragon (1319)

Metalion's picture

07-12-2020, 17:09

(duplicate message)

By Metalion

Paragon (1319)

Metalion's picture

07-12-2020, 17:12

BCD (Binary Coded Decima) is a different way to store a decimal number in a byte, which is more practical to display it afterwards. Instead of storing 99 as a decimal value (which would be 63h in hexadecimal), you store 99h (9 in the upper nibble, 9 in the lower nibble).

The beauty of it is that the Z80 provides a way to deal with BCD in a native way. You can do whatever operation on the number (well, almost), and then use the operation DAA (Decimal Accumulator Adjust) which will correct the result so it is still BCD.

For example, if you have the value 9 in (BUB), this operation will result in 10h being stored in (BUB), which is the correct BCD representation of the result (9+1=10), instead of 0Ah (which is the uncorrected result).

ld  a,(BUB)
inc a
daa
ld  (BUB),a
Chilly Willy wrote:

Can somebody just post a tested routine that you can pass a value such as 194 to A and it will display 194 on the screen on the MSX 1.

It would be useless to post such a routine because it's not the correct way to do this. If you have 194 to store in RAM for a score for example, you have to use two bytes because 194 in BCD is 0194h, which uses 2 bytes.

Once the number are stored in BCD format, then you can use the routine I have posted earlier.

By Chilly Willy

Rookie (30)

Chilly Willy's picture

07-12-2020, 17:18

Metalion wrote:

BCD (Binary Coded Decima) is a different way to store a decimal number in a byte, which is more practical to display it afterwards. Instead of storing 99 as a decimal value (which would be 63h in hexadecimal), you store 99h (9 in the upper nibble, 9 in the lower nibble).

The beauty of it is that the Z80 provides a way to deal with BCD in a native way. You can do whatever operation on the number (well, almost), and then use the operation DAA (Decimal Accumulator Adjust) which will correct the result so it is still BCD.

For example, if you have the value 9 in (BUB), this operation will result in 10h being stored in (BUB), which is the correct BCD representation of the result (9+1=10), instead of 0Ah (which is the uncorrected result).

ld  a,(BUB)
inc a
daa
ld  (BUB),a

I guess I am confused because I taking a value calculated by the game, timer or whatever which is placed n (BUB)
I LD A, with (BUB) then send A through a process so I can get
100
30
4

If that number was 134

I can then CP 1 then print 1 using a pattern for 1

LD HL,VRAM_NAME+759
CALL SETWRT
CP 00
CALL Z, PRINT_ZERO
CP 01
CALL Z, PRINT_ONE
CP 02
CALL Z, PRINT_TWO
CP 03
CALL Z, PRINT_THREE
CP 04
CALL Z, PRINT_FOUR
CP 05
CALL Z, PRINT_FIVE
CP 06
CALL Z, PRINT_SIX
CP 07
CALL Z, PRINT_SEVEN
CP 08
CALL Z, PRINT_EIGHT
CP 09
CALL Z, PRINT_NINE

What I am reading from the responses is that I should save the number in BCD format so I can retrieve it then convert it back from BCD.

By Metalion

Paragon (1319)

Metalion's picture

07-12-2020, 17:21

Yes, but as I have explained, this is not the correct way to store a value in RAM if you want to display it afterwards. If you want to have an easy routine like the one I posted, then you have to store the value in BCD format.

Which means that you have to go back to the part of your program that calculates the value and modify it so that it is corrected for BCD format.

For example, if you have a simple score routine that add 10 points to the score for each enemy shot, you do :

ld  a,(BUB)
add 10
daa
ld  (BUB),a

And then when you need to display the value, then you can use

display_score:
ld   hl,BUB
call display_BCD
ret

display_BCD:
ld	a,(hl)
and	11110000b
rrca
rrca
rrca
rrca
add	48
call	CHPUT (or any other outputing routine)
ld	a,(hl)
and	00001111b
add	48
call	CHPUT
ret

By Chilly Willy

Rookie (30)

Chilly Willy's picture

07-12-2020, 17:23

I am going to input these numbers and get back with you in 5

By Grauw

Ascended (9589)

Grauw's picture

07-12-2020, 19:19

Alternatively you can use a division by ten routine, which outputs the modulo (remainder) as well. You divide the number by ten until you reach zero, or if you know the maximum number of digits you can simply divide that many times. After each division you print the modulo on screen starting at the rightmost digit. Add the ASCII code of "0" to convert a digit to an ASCII character.

The advantage of BCD is that it’s much faster. The downside of BCD is that you need to amend your score keeping for BCD with the DAA instruction and such.

Page 1/2
| 2