Writing contents of a memory address to screen

JMP $FCE2
User avatar
yaztromo
Member
Member
Posts: 292
Joined: Fri Apr 11, 2014 8:42 pm
Location: South Yorkshire, UK
Contact:

Writing contents of a memory address to screen

Post by yaztromo »

How would I write the value stored in a memory location to screen as a decimal?

For example say I have the value #96 stored at $d001

I would like the output on screen to be "150".

Is there a simple way to do this?


satpro

Re: Writing contents of a memory address to screen

Post by satpro »

Hi yaztromo,

Try the attached routine. It's from Compute's Machine Language Routines for the Commodore 64/128. I have used this routine many different times in many different ways, including something I modified for 16-bit Winc64.

It is explained very well, is short, and you can modify it very easily if you wish. Any questions about how to go about using the routine -- just ask.

Bert
User avatar
buzbard
Member
Member
Posts: 24
Joined: Sun Apr 13, 2014 9:06 pm
Location: Washington State
Contact:

Re: Writing contents of a memory address to screen

Post by buzbard »

There's also a handy routine built into the BASIC ROM at $BDCD, it's part of the LIST command that prints the line number, just load the Accumulator with the high byte and the .X register with the low byte then jsr to the routine.

Code: Select all

LDA #$00
LDX #$96
JSR $BDCD
For the VIC20 use $DDCD.
Ray...
It's Ok if you don't agree with me, I can't force you to be right.
satpro

Re: Writing contents of a memory address to screen

Post by satpro »

$BDCD is a good way to print numbers, too. The difference is it prints two-byte values.
User avatar
yaztromo
Member
Member
Posts: 292
Joined: Fri Apr 11, 2014 8:42 pm
Location: South Yorkshire, UK
Contact:

Re: Writing contents of a memory address to screen

Post by yaztromo »

Thanks both of you for some great help.

For the time being I have got it working the simple way with BDCD and then resetting the cursor position with e566.

However the need will come to swap out the BASIC ROM eventually so I will convert to the more hands on method then. I suspect it is also a faster routine.
satpro

Re: Writing contents of a memory address to screen

Post by satpro »

Hey yaz... happy you took the time to work it out.

You know the subtraction method is the faster way to do it -- by a mile. Also less complicated if you add it to your permanent collection of go-to routines.
User avatar
yaztromo
Member
Member
Posts: 292
Joined: Fri Apr 11, 2014 8:42 pm
Location: South Yorkshire, UK
Contact:

Re: Writing contents of a memory address to screen

Post by yaztromo »

Satpro,

Sorry to pick at your brains like this, I'll not make a habit of it ;)

I'm having some trouble fathoming how to make a BVC work after I've done my JSR $BDCD. I thought that I could save my CPU status to the stack, call the routine, then restore the CPU status and do my BVC as normal. However it doesn't work! I thought maybe the routine messes with the stack so I save my CPU status now to a memory location "statusregister" at $c0004 and then restore it. However this does not work either.

If I comment out the JSR $BDCD then everything works as it should. I'm missing something important obviously.

Here's a code snippet, apologies in advance for terrible code. At the moment this is all steep learning curve for me!

Code: Select all

lda #sprite0speed ; get the sprite speed and add it to the precision buffer
	adc sprite0yPrecision
	sta sprite0yPrecision
	php ; store cpu status to memory
	pla
	sta statusregister
	lda #$00
	ldx sprite0yPrecision ; Display number on screen using basic routine
        jsr $bdcd
	jsr $e566 ; Move cursor back to home position
	lda statusregister
	pha
	plp ; restore status register
	bvc loop ; skip on if didn't overflow
User avatar
buzbard
Member
Member
Posts: 24
Joined: Sun Apr 13, 2014 9:06 pm
Location: Washington State
Contact:

Re: Writing contents of a memory address to screen

Post by buzbard »

The Overflow flag (V) is being set by the ADC opcode in the second line.

It has to do with "Twos Compliment" addition. A byte can be in the range of 0 to 255 but to represent negative numbers the processor uses 0 to 127 then values after that will have the high bit set (128) which represents the negative sign.

For example: when you have a value of 255 and you add 1, the value goes to 0 and the carry flag (C) will be set, to let you know you exceeded the maximum value of the byte.
Any time you add a number that brings the value to 128 or higher the Overflow flag will be set to let you know it's a negative number.

Try adding a CLV after the ADC line then you should be able to just PHP then later PLP without having to save it to RAM.

There's a great article that goes into more detail here: The Overflow Flag
Ray...
It's Ok if you don't agree with me, I can't force you to be right.
satpro

Re: Writing contents of a memory address to screen

Post by satpro »

Hi yaztromo,

Thank you for asking. Go ahead -- pick my brain -- see if there's anything the buzzards ain't 'et yet :D

I want to repeat the code here -- please forgive me, but web-text is horrible for looking at something we've been viewing in mono-text since it was invented...

Is this a partial clip? The reason I ask is because you never want to do addition without first clearing the carry flag -- unless you know the state of the carry flag before the addition. In 65x the instruction is ADC (which means Add With Carry). The value of the carry flag (which can be 0 or 1) is ADDed to the result. Your addition could be off by 1 -- or 256x. The opposite is true for subtraction. I won't bore you with why, but it has everything to do with cost-cutting on the original chip.0

Code: Select all

lda #sprite0speed ; get the sprite speed and add it to the precision buffer
--> Is this a constant -- or a variable? If it is a variable in memory, then remove the "#" (judging by the rest of the code --> it's a variable). The way it is will give you the ADDRESS of sprite0speed, not the value found at that location.

Here is an example:

Code: Select all

NULL = 0
LDA #NULL
Here we are loading .A with a zero. Why? If you just said "LDA NULL" (no "#") it would load A with the value found at address NULL (Address 0). By saying "LDA #NULL" you are loading A with the address of NULL, which we know (NULL = 0) is 0. It's a bitch getting it straight, but this is something you will eventually get familiar with. Maybe I just gave a speech for no reason, but I was not sure what your intent was.

Code: Select all

adc sprite0yPrecision
sta sprite0yPrecision
php
pla
sta statusregister
lda statusregister
pha
plp ; restore status register
bvc loop ; skip on if didn't overflow
This section is interesting. Here's why: When you PHP you are officially saving the status register on the Stack. Everything goes --> carry flag, zero flag, decimal flag, interrupt disable flag, break flag, overflow flag, and negative flag. You are saving the state of the registers, and this is a very powerful instruction, but there is seldom need to do so. It's an instruction we use to save the computer's state, such as when you go to interrupt -- you need to save the registers so that everything is the same as before the interrupt was called. By pulling (PLA) and storing to memory it would appear to be doubling up. Once you PHP, the status register is "saved" on the Stack for as long as you require. I have PHP'd, PLA'd, then immediately PHP'd again -- just to get the status register for a saved carry or zero flag at different parts of a program, but that's not what you are doing here. The point is... if you push "Register P", it's saved -- and available for as long as you need it (just make sure you get it off the Stack later). There is most likely never a need to save it (again) in memory (sta statusregister).

The overflow flag is rarely used, and when it is used, it's mainly by hardware to signal something is ready. An example would be when a byte (all 8 bits) is read from the disk. It is also used in signed arithmetic. Other than that, the overflow flag is almost never used.

Good luck with the programming. This is exactly how you learn -- by doing and asking.
Thanks for asking.

Bert
Prime

Re: Writing contents of a memory address to screen

Post by Prime »

yaztromo
Feel free to write, pm any of us with questions we were all where you are at one point.
Don't ever feel that your questions are inadequate, melon created the forum for others to ask questions and inquire.
Most programmers (stick)together, as Arthur, myslef, bebz, satpro, tmr, melon, and others on the forum all chat, but each one of use will go out of our way to help another be it (novice, intermediate.advanced)we all share ideas.The absolute great thing about having so many programmers is,If I'm unaware how to present a subject to you others will take that task and so on.I'm going to assume based on your posts your a hands on programmer with that I mean (read source and duplicate)which means your a detail programmer.(a good thing)if one of us can't respond to your question we will refer you to another programmer that can.I'm a hands on programmer I despise theory programmers(programming is a universal language)I learn by duplicating, understanding 100% another programmers code structure(and enjoy studying his code).I'll elaborate coders(will explain how to accomplish a task)programmers will show code and explain in detail how to accomplish that task, notice how Satpro went into deep detail to explain the inner workings to you(and is enthusiastic to explain)only a programmer with a great depth of knowledge will go into that depth. Anyway I'm rambling feel free to pick a programmers mind they enjoy helping.
Post Reply Previous topicNext topic

Who is online

Users browsing this forum: No registered users and 8 guests