Jump to content
  • 0
JohnGill

assembly variables / two byte memory addressing

Question

Hi all,

I'm working away furiously at writing a routine in assembly that will scroll text within a window on screen for my hexes adventure game, loading text from a memory bank and adding it at the bottom line by line. This is really stretching my assembly skills but I'm enjoying the challenge. I've got my head round using both vera's data0 and data1 to read and write the screen to shuffle up the whole window a line at a time, but I've come across a blip that I can't get my head round, and I'm wondering if someone can please point me in the right direction:

I'm copying a string of characters from somewhere in the ram bank space ($A000 upwards), which is referenced by two ZP vars that I've assigned to variables thus:

startHi=$14
startLo=$15

I've written the maths routines to calculate the start position of the required string, which sets startHi to say, $A1, and startLo to say, $34. The maths routines I've tested and know are working, they give the correct values in startHi and startLo for the base position of the text within the ram bank.

My problem seems to be actually copying those bytes to the screen. I'm feeling exceptionally clever for working out how to use the y register in indirect indexed addressing mode to step through the memory thus:

loop:
    lda  (startHi),y
    ..... do stuff

But it ain't working (yet 😉 ).

If I've understood things correctly, this is supposed to look at the byte at memory address startHi ($14 for me) *and*  the byte at memory address startHi+1 ($15, startLo) and use that as a two-byte base address, and then add on the value of y. Is that right?

When I run the routine, it just writes a ton of "@" to the screen. I've set the break point at the start of the loop with the debugger monitor thing (very useful), and it steps through y from $00 > $FF fine, and sure enough, its just loading zeros into the accumulator at the lda (startHi), y line every time. I can see the ZP vars in the debugger, and $14 and $15 are indeed pointing to $A1 and $34 (or whatever), but I don't understand the debugger well enough to work out if I can look at the actual $A134 while I'm stepping through the assembly. 

When I print chr$(peek($A134... $A135... $A136 etc)) from basic, then it shows that the characters are indeed present in the ram bank page (see below). So why does my assembly just find zeros?

Any tips very gratefully received!!!

thanks

 

Bitmap in Untitled-1.png

Share this post


Link to post
Share on other sites

Recommended Posts

  • 0
6 hours ago, JohnGill said:

It seems to be the correct text; but, all the lower case characters have turned into graphics, and the upper case characters have been reversed out.
And now, the BASIC bit that prints the first line of the message doesn't print anything at all!

Coding in Assembly, for me, just feels like one step forward, two steps back, every time!

Yep.  But in this case, it's three steps back.  😉

There are two encodings: PetSCII and screen codes.  We print PetSCII to the screen.  But, we poke screen codes into screen RAM.  Therefore, you must change the text lines that you copy into VERA's VRAM.  Change the quotation marks into apostrophes.

    text    'In a wild and rough scrubland.'

  • Thanks 1

Share this post


Link to post
Share on other sites
  • 0

The 6502 is little endian. This means that when using a 16 bit number (like an address) it expects the 'low' byte to come before the 'high' byte in memory. So you need to swap some bytes round. For your example, you should have startLo = $14, startHi = $15, then lda (startLo),x.

Hope that helps.

  • Thanks 1

Share this post


Link to post
Share on other sites
  • 0
6 minutes ago, togster510 said:

The 6502 is little endian. This means that when using a 16 bit number (like an address) it expects the 'low' byte to come before the 'high' byte in memory. So you need to swap some bytes round. For your example, you should have startLo = $14, startHi = $15, then lda (startLo),x.

Hope that helps.

ah! that makes perfect sense. yep, thought it might be some noobish error like that. Many thanks, I'll switch them up and see what happens... (!!!)

Share this post


Link to post
Share on other sites
  • 0

curiouser and curiouser.... I've switched startLo and startHi around into proper little endian order, and now I get this (see attachment).

It seems to be the correct text, but all the lower case characters have turned into graphics and the upper case characters have been reversed out.

And now the BASIC bit that prints the first line of the message doesn't print anything at all!

coding in assembly for me just feels like one step forward two steps back every time!

Bitmap in Untitled-1.png

Share this post


Link to post
Share on other sites
  • 0

Also, typing ‘m A134’ in the debugger will show the memory values in the lower section.


Sent from my iPhone using Tapatalk

  • Thanks 1

Share this post


Link to post
Share on other sites
  • 0
Posted (edited)
2 hours ago, togster510 said:

Could you post what it is supposed to say?


Sent from my iPhone using Tapatalk

it's supposed to say :
 


 

the spaces are all in the correct places, and the capital letters are all there (I, T and F), just reversed out. I've replaced some of the upper-case characters to make the hex-construction graphics, and the resource blobs as well. I'm going to re-organise my character set map but the untampered-with- lower case characters should still display correctly shouldn't they? I'm still a bit of a noob at petscii and how the character sets are handled so it could just be that I'm being a bit dim.

*edit - don't know what happened to the text I copied and pasted above - it should have said "In a wild and rough scrubland. Thick grasses and heathers make the going slow, and gorse bushes pick at your clothes. From unseen heights, the cries of distant birds catch on the wind from time to time.%"

Edited by JohnGill

Share this post


Link to post
Share on other sites
  • 0

I'm using the 'text' type in my assembler and compiling the ram bank as a .prg .  It's strange, because when I print chr$(peek($A134)) from basic, the characters come up on screen correctly. I'm obviously doing something dumb with the assembly but I don't know what yet...

Share this post


Link to post
Share on other sites
  • 0
2 hours ago, JohnGill said:

I'm using the 'text' type in my assembler and compiling the ram bank as a .prg .  It's strange, because when I print chr$(peek($A134)) from basic, the characters come up on screen correctly. I'm obviously doing something dumb with the assembly but I don't know what yet...

If the problem seems to be a bug in your assembly code, then seeing the assembly code would help immensely. Do you have a Github account, or similar? Is the code available somewhere for other eyeballs to have a look-see?

Share this post


Link to post
Share on other sites
  • 0
1 minute ago, StephenHorn said:

If the problem seems to be a bug in your assembly code, then seeing the assembly code would help immensely. Do you have a Github account, or similar? Is the code available somewhere for other eyeballs to have a look-see?

Hi Stephen, thanks for the reply.
 I did sign up with github a couple of years ago but couldn't make any sense of how to use it. You seem to be confusing me with an actual programmer 😉😉 .

In the screenshots below, I've shown how I've coded the bank 1 data in my assembler - this compiles to a prg and loads up fine into the emulator. I've also shown the basic program where it calls the 'print' assembly routine (sys $2a90) and then the assembly code section where it writes the ram bank section onto the screen. (startHi should really be called startLo - I got my endians muddled up - as pointed out by togster510 above! I switched them round but didn't change the variable names).

jsr scroll is a subroutine I've written already and tested, that works perfectly 🙂 - just moves all the message window up one line, leaving the bottom line blank for the next line of text to be written up. 

I've also attached a screen shot of it running to show how the assembly displays the message from the bank (yellow section at the bottom of the message window), and then at the top of the window, I've put some basic code in that loads exactly the same bit of memory and writes up the first line perfectly.  The assembly is definitely reading the right bit of memory, the spaces in the top row line up perfectly with the spaces in the basic printed line. It seems to be something to do with how print chr$() interprets the character set but I can't work it out. Any ideas?

bank01.png

basic.png

assembly.png

screenshot.png

Share this post


Link to post
Share on other sites
  • 0

Huh. What happens when you change this:

lda  #$00
sta vera_choose_port    ; choose vera port 0

To this:

lda  #$01
sta vera_choose_port    ; choose vera port 1

?

Share this post


Link to post
Share on other sites
  • 0
4 minutes ago, StephenHorn said:

Huh. What happens when you change this:

lda  #$00
sta vera_choose_port    ; choose vera port 0

To this:

lda  #$01
sta vera_choose_port    ; choose vera port 1

?

if I'm switching to use vera port 1, I'd  also need to change line 120 (sta vera_data0) also to sta vera_data1.  I've set up all the variables at the top of the assembly to the appropriate register values to I don't have to keep remembering them 😄 I can't see how it'll affect it, but I'll try anything at this stage 😉  I'll give it a go...

Share this post


Link to post
Share on other sites
  • 0

pff. exactly the same. ah well.

although here's a weird thing - I quit out of the program, and typed in the line 'In a wild and rough scrubland' with the shift key held down - and I got exactly the same string of characters as the assembly is displaying (apart from the capital I which didn't appear reversed out).

Question is, why is the text displaying correctly when called with print chr$() in basic? Curiouser and curiouser....

screenshot.png

Share this post


Link to post
Share on other sites
  • 0

Shrug. At this point, I'd be spending a lot of time with the built-in debugger, trying to suss out the exact layer settings I'm working with when things go awry. Is it possible that someone has switched out the character sets between the ASM function being called via SYS and the BASIC version of the same?

Share this post


Link to post
Share on other sites
  • 0
2 minutes ago, StephenHorn said:

Shrug. At this point, I'd be spending a lot of time with the built-in debugger, trying to suss out the exact layer settings I'm working with when things go awry. Is it possible that someone has switched out the character sets between the ASM function being called via SYS and the BASIC version of the same?

I've not done that deliberately - I'm the only one writing this so the screw ups are all mine 😉  it is definitely something to do with how the character sets are being handled, so I'm going to dig a little deeper down that tunnel. Perhaps the kernel calls from print do something clever to make the correct characters appear on screen that my hard-coded vera calls ain't doing.

Share this post


Link to post
Share on other sites
  • 0
14 minutes ago, JohnGill said:

I've not done that deliberately - I'm the only one writing this so the screw ups are all mine 😉  it is definitely something to do with how the character sets are being handled, so I'm going to dig a little deeper down that tunnel. Perhaps the kernel calls from print do something clever to make the correct characters appear on screen that my hard-coded vera calls ain't doing.

That I think is the problem. When writing directly to vera you need to use screencodes rather than petscii values. However, PRINT uses petscii. For a discussion of this, see https://retrocomputing.stackexchange.com/questions/7529/why-the-disparity-between-the-screencodes-and-the-character-codes . The assemblers I've tried have all had a mechanism to translate text to screencodesfor you, but I couldn't find documentation for c64 studio (which I believe is what you're using). Maybe search in the help for screencodes and see what you can find.

  • Thanks 1

Share this post


Link to post
Share on other sites
  • 0

Thank you very much! Yes that sounds very probable. Something concrete for me to work on. 👍🏼

Share this post


Link to post
Share on other sites
  • 0
2 minutes ago, Greg King said:

Yep.  But in this case, it's three steps back.  😉

There are two encodings: PetSCII and screen codes.  We print PetSCII to the screen.  But, we poke screen codes into screen RAM.  Therefore, you must change the text lines that you copy into VERA's VRAM.  Change the quotation marks into apostrophes.

    text    'In a wild and rough scrubland.'

What kind of magic syntax nonsense is that? 🤔 Is this something specific to CBM prg studio, that it'll translate from ASCII to the appropriate screen codes? Or is/was this a standard convention for C64-type software?

Share this post


Link to post
Share on other sites
  • 0
45 minutes ago, StephenHorn said:

What kind of magic syntax nonsense is that? 🤔 Is this something specific to CBM prg studio, that it'll translate from ASCII to the appropriate screen codes? Or is/was this a standard convention for C64-type software?

It's specific to CBM prg Studio.  There was no standard convention for handling screen codes.

  • Like 2

Share this post


Link to post
Share on other sites
  • 0
10 hours ago, StephenHorn said:

What kind of magic syntax nonsense is that? 🤔 Is this something specific to CBM prg studio, that it'll translate from ASCII to the appropriate screen codes? Or is/was this a standard convention for C64-type software?

 

11 hours ago, Greg King said:

Yep.  But in this case, it's three steps back.  😉

There are two encodings: PetSCII and screen codes.  We print PetSCII to the screen.  But, we poke screen codes into screen RAM.  Therefore, you must change the text lines that you copy into VERA's VRAM.  Change the quotation marks into apostrophes.

    text    'In a wild and rough scrubland.'

So I switched the " to ' and recompiled  bank1.prg, and sure enough, the text bytes are encoded completely differently, so CBM PRG Studio is doing something clever. But not clever enough it would seem - now when I run it, it does a screen clear, and I'm getting different gobbledigook so the new values are still not correct. I'm going to go back to quotation marks around the text rather than apostrophes, I know then that CBM PRG Studio outputs PETSCII values into the bytes for upper and lower case characters. All I need to do then is, before writing each character to the screen, send it to a conversion routine that checks the PETSCII value held in the byte, and converts it to a screencode. I found a table here : https://sta.c64.org/cbm64pettoscr.html so it seems straightforward enough.

On a very steep learning curve here, but it feels good to be getting to the bottom of this ASCII/PETSCII/screencode weirdness!  Thanks Stephen and Greg. I'll report back!

screenshot.png

Share this post


Link to post
Share on other sites
  • 0
So I switched the " to ' and recompiled  bank1.prg, and sure enough, the text bytes are encoded completely differently, so CBM PRG Studio is doing something clever. But not clever enough it would seem - now when I run it, it does a screen clear, and I'm getting different gobbledigook so the new values are still not correct. I'm going to go back to quotation marks around the text rather than apostrophes, I know then that CBM PRG Studio outputs PETSCII values into the bytes for upper and lower case characters. All I need to do then is, before writing each character to the screen, send it to a conversion routine that checks the PETSCII value held in the byte, and converts it to a screencode. I found a table here : https://sta.c64.org/cbm64pettoscr.html so it seems straightforward enough.

On a very steep learning curve here, but it feels good to be getting to the bottom of this ASCII/PETSCII/screencode weirdness!  Thanks Stephen and Greg. I'll report back!

screenshot.png.16e41a651eb0822d59d57ed0d5fd2be6.png

In that routine, you could also consider handling return characters, which don’t have a screen code but would allow you to have longer bits of text.


Sent from my iPhone using Tapatalk
  • Like 1

Share this post


Link to post
Share on other sites
  • 0
Posted (edited)
8 hours ago, JohnGill said:

So, I switched the " to ', and recompiled  bank1.prg; and sure enough, the text bytes are encoded completely differently; so, CBM PRG Studio is doing something clever. But, not clever enough it would seem -- now when I run it, it does a screen clear, and I'm getting different gobbledigook; so, the new values are still not correct.

I'd say that CBM prg Studio is being too clever (I don't like IDEs that put code into our programs, behind our backs)!  The help file says,

Quote

If the assembler detects lower case characters in a text string, it will assume the characters are from set 2. That behaviour can be changed in the configuration.

Will you try an experiment?

  1. Click Tools, then OPTIONS...
  2. In the left column, click Assembler.
  3. Uncheck the line, in the middle column, that says, Detect character set for 'text' directive
  4. Click OK.

Then, try apostrophes on your first message.

Also, in that same Options dialog, there is a drop-down list box in the right column, entitled "Character set". I don't know what affect it has; but, you could try changing it, to see what happens.

Edited by Greg King

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...

Important Information

Please review our Terms of Use