Using a "word" data type

Basic and Machine Language

Moderator: Moderators

User avatar
bkumanchik
Vic 20 Newbie
Posts: 13
Joined: Thu Mar 03, 2022 8:03 pm
Location: Los Angeles
Occupation: Art Director

Using a "word" data type

Post by bkumanchik »

why does this work:

Code: Select all

	ldx #1          ; code for "A"
	stx 7680        ; place at first screen location

but this does not:

Code: Select all

	ldx #1          ; code for "A"	
	stx char_p      ; place at first screen location 
	
char_p
        word 7680	; invader starting position
It should be the same thing, right?

Thanks for any help,

Brian
Last edited by Mike on Wed Mar 23, 2022 2:19 am, edited 2 times in total.
Reason: topic title shortened from 'Using a "word" data type in CBM Prog Studio' as issue does not actually concern CBM Prog Studio
READY_
User avatar
chysn
Vic 20 Scientist
Posts: 1205
Joined: Tue Oct 22, 2019 12:36 pm
Website: http://www.beigemaze.com
Location: Michigan, USA
Occupation: Software Dev Manager

Re: Using a "word" data type

Post by chysn »

I don't know anything about CBM Prog Studio, but I'm pretty sure that I see why the second one doesn't work.

It doesn't matter what's stored at char_p in the least, because your X is stored to whatever address the label is defined as. You can confirm this by disassembling the code. For example, if that code started at $2000, it would look like this:

Code: Select all

., 2000 LDX #$01
., 2002 STX $2004       ; The address of char_p, NOT the contents of memory at char_p!
., 2004 BRK             ; $00 from low byte of word at char_p
., 2005 ASL something,X ; $1E from high byte of word, and whatever's after it
., 2008 etc...
Instead of using char_p as a label to the address of a word, define char_p as a value in the assembler.

Update: I just looked this up, and its definition syntax is like that of other assemblers. You'd want to do

Code: Select all

char_p = 7680
ldx #1
stx char_p
Last edited by chysn on Tue Mar 22, 2022 2:51 pm, edited 1 time in total.
VIC-20 Projects: wAx Assembler, TRBo: Turtle RescueBot, Helix Colony, Sub Med, Trolley Problem, Dungeon of Dance, ZEPTOPOLIS, MIDI KERNAL, The Archivist, Ed for Prophet-5

WIP: MIDIcast BASIC extension

he/him/his
User avatar
Mike
Herr VC
Posts: 4841
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: Using a "word" data type

Post by Mike »

The answer depends on what you actually wanted to achieve:

If what you wanted is to equate the symbol char_p with the value 7680, so the STX assembles to exactly the same opcode and address mode, then CBM Prog Studio should offer an EQU directive or the like to equate symbol and value. The exact syntax for this probably hides in one of the tutorials. Edit: chysn has answered this above.

If you actually wanted to store the X register at the address pointed to by the word stored at char_p (i.e. that word directly behind the LDX/STX instructions), that would need the "made-up" instruction "STX (char_p)". It is made up because this instruction (store X with absolute indirect) does not exist at all on the 6502! STA (zp),Y would do what you wanted, but it requires the value to be in A, the pointer to be in zero page at addresses zp (low byte) and zp+1 (high byte), and Y=0 as offset (Y is added to the 16 bit pointer after it is fetched from zero page to get the effective address).
User avatar
chysn
Vic 20 Scientist
Posts: 1205
Joined: Tue Oct 22, 2019 12:36 pm
Website: http://www.beigemaze.com
Location: Michigan, USA
Occupation: Software Dev Manager

Re: Using a "word" data type

Post by chysn »

Mike's point about zeropage indirect addressing is important here, because you're writing things to the screen. You probably plan on moving these things around. If so, you're likely to abandon your original code in favor of using a couple zeropage locations to store a pointer to the location to which you're writing. Such a thing might look like this:

Code: Select all

ptr = $fd    ; The location of the thing (2 bytes)
lda #$00     ; Initialize the low byte of the pointer
sta ptr      ; ,,
lda #$1e     ; Initialize the high byte of the pointer; also consider lda $0288, which adjusts for memory expansion
sta ptr+1    ; ,,
lda #1       ; The character code for A
ldy #0       ; Index (the value added to the address in the next line)
sta (ptr),y  ; Basically, the pointed-at location + Y
It's more code, but you get to manipulate the $fd/$fe pointer to change the position of something. If you use absolute addressing here, you lack flexibility, and you'll get frustrated when it comes to putting things where you want.
User avatar
Mike
Herr VC
Posts: 4841
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: Using a "word" data type

Post by Mike »

The BALLPING example in my VICMON primer thread (see second post) shows a more elaborate example use of this address mode. ;)
User avatar
bkumanchik
Vic 20 Newbie
Posts: 13
Joined: Thu Mar 03, 2022 8:03 pm
Location: Los Angeles
Occupation: Art Director

Re: Using a "word" data type

Post by bkumanchik »

Thanks for all of the help, I want char_p (should have been more clear - maybe car_pos for character position) to be the start of screen memory (7680) as a variable and store the character "A" there.

then if I right on the joystick I could

Code: Select all

inc car_pos
ldx #1             ; char "A"
stx car_pos      ; store in new car_pos  (7680 + 1)
The problem I was having before was I was doing this:

Code: Select all

ldx char_pos               
lda #1                  
sta 7680,x
So you can inc char_pos to move right and dec char_pos to move left and add 22 to char_pos to move down and subtract 22 to move up but since I can only store an 8-bit number in char_pos I can't move all over the screen.

I created an elaborate system where I keep track of a separate Y value and when I get halfway down the screen I reset Y and use a different coordinate system but it is very complicated and I know that there must be an simpler way - I feel like if I didn't have the 8-bit restriction and I could plug a 16-bit variable into the base screen position (like you can do in basic) then that would solve my problem.

So that is why I tried to create a word data type named char_pos

Let me know if you'd like to see my full code as it's currently working.

Brian
READY_
User avatar
bkumanchik
Vic 20 Newbie
Posts: 13
Joined: Thu Mar 03, 2022 8:03 pm
Location: Los Angeles
Occupation: Art Director

Re: Using a "word" data type

Post by bkumanchik »

Thanks, I'll check this out

Mike wrote: Tue Mar 22, 2022 4:11 pm The BALLPING example in my VICMON primer thread (see second post) shows a more elaborate example use of this address mode. ;)
READY_
User avatar
Mike
Herr VC
Posts: 4841
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: Using a "word" data type

Post by Mike »

Since the topic did not turn out to be concerned about an issue of CBM Prg Studio (which would have warranted a move to the "Emulation & Cross-Developing" section, BTW), I changed/shortened the title.
bkumanchik wrote:

Code: Select all

inc car_pos
ldx #1 ; char "A"
stx car_pos ; store in new car_pos (7680 + 1)
The intention is clear, but INC car_pos will only increment the byte at car_pos, the carry will not 'miraculously' spill over to car_pos+1.
User avatar
thegg
Vic 20 Amateur
Posts: 69
Joined: Mon Aug 30, 2021 4:49 am
Location: England
Occupation: retired

Re: Using a "word" data type

Post by thegg »

You might find it useful to hold your character position as a screen row and column rather than an offset from an absolute address. You can then load the zero page pointers (as shown by chysn) with the address of the screen row, and offset to the column using the y index. To keep things simple, I use a table of row addresses as words indexed by row *2 rather than multiplying by 22.

Alternatively, if you work in terms of row and column you could make use of the Kernal routines PLOT and CHROUT to print your character.
For example:
Your character is to be displayed at row 10, column 11. The code would be:
clc ;indicate plot position
ldx #11 ;column (0-21)
ldy #10 ;row (0-22)
jsr $FFF0 ;plot - set cursor position
lda #char ;CBM ASCII code for character
jsr $FFD2 ;chrout - print at cursor position
User avatar
chysn
Vic 20 Scientist
Posts: 1205
Joined: Tue Oct 22, 2019 12:36 pm
Website: http://www.beigemaze.com
Location: Michigan, USA
Occupation: Software Dev Manager

Re: Using a "word" data type

Post by chysn »

thegg wrote: Wed Mar 23, 2022 4:14 pm clc
ldx #11 ;column (0-21)
ldy #10 ;row (0-22)
jsr $FFF0 ;plot - set cursor position
I've come to appreciate PLOT for various things that don't need optimum speed. It's wonderful simplicity when the alternative is 16-bit math.

But... keep in mind that X and Y registers are reversed from Cartesian (x,y) coordinates. X is the y coordinate (row) and Y is the x coordinate (column). For some reason. And yes, the Programmer's Reference Guide gets this wrong.
wimoos
Vic 20 Afficionado
Posts: 348
Joined: Tue Apr 14, 2009 8:15 am
Website: http://wimbasic.webs.com
Location: Netherlands
Occupation: farmer

Re: Using a "word" data type

Post by wimoos »

Not much math needed:

Code: Select all

	PHA
	LDA $EDFD,X
	STA $FD
	LDA $D9,X
	AND #$7F
	STA $FE
	PLA
	STA ($FD),Y ; put char
	LDA $FE
	AND #$03
	ORA #$94
	STA $FE
	LDA $0286
	STA ($FD),Y ; put color
	RTS
VICE; selfwritten 65asmgen; tasm; maintainer of WimBasic
User avatar
bkumanchik
Vic 20 Newbie
Posts: 13
Joined: Thu Mar 03, 2022 8:03 pm
Location: Los Angeles
Occupation: Art Director

Re: Using a "word" data type

Post by bkumanchik »

Thanks, I'll try that out

chysn wrote: Wed Mar 23, 2022 7:13 pm
thegg wrote: Wed Mar 23, 2022 4:14 pm clc
ldx #11 ;column (0-21)
ldy #10 ;row (0-22)
jsr $FFF0 ;plot - set cursor position
I've come to appreciate PLOT for various things that don't need optimum speed. It's wonderful simplicity when the alternative is 16-bit math.

But... keep in mind that X and Y registers are reversed from Cartesian (x,y) coordinates. X is the y coordinate (row) and Y is the x coordinate (column). For some reason. And yes, the Programmer's Reference Guide gets this wrong.
READY_
User avatar
bkumanchik
Vic 20 Newbie
Posts: 13
Joined: Thu Mar 03, 2022 8:03 pm
Location: Los Angeles
Occupation: Art Director

Re: Using a "word" data type

Post by bkumanchik »

Isn't that how you declare a constant, not a variable?





chysn wrote: Tue Mar 22, 2022 2:32 pm I don't know anything about CBM Prog Studio, but I'm pretty sure that I see why the second one doesn't work.

It doesn't matter what's stored at char_p in the least, because your X is stored to whatever address the label is defined as. You can confirm this by disassembling the code. For example, if that code started at $2000, it would look like this:

Code: Select all

., 2000 LDX #$01
., 2002 STX $2004       ; The address of char_p, NOT the contents of memory at char_p!
., 2004 BRK             ; $00 from low byte of word at char_p
., 2005 ASL something,X ; $1E from high byte of word, and whatever's after it
., 2008 etc...
Instead of using char_p as a label to the address of a word, define char_p as a value in the assembler.

Update: I just looked this up, and its definition syntax is like that of other assemblers. You'd want to do

Code: Select all

char_p = 7680
ldx #1
stx char_p
READY_
User avatar
bkumanchik
Vic 20 Newbie
Posts: 13
Joined: Thu Mar 03, 2022 8:03 pm
Location: Los Angeles
Occupation: Art Director

Re: Using a "word" data type

Post by bkumanchik »

Thanks!



chysn wrote: Tue Mar 22, 2022 3:25 pm Mike's point about zeropage indirect addressing is important here, because you're writing things to the screen. You probably plan on moving these things around. If so, you're likely to abandon your original code in favor of using a couple zeropage locations to store a pointer to the location to which you're writing. Such a thing might look like this:

Code: Select all

ptr = $fd    ; The location of the thing (2 bytes)
lda #$00     ; Initialize the low byte of the pointer
sta ptr      ; ,,
lda #$1e     ; Initialize the high byte of the pointer; also consider lda $0288, which adjusts for memory expansion
sta ptr+1    ; ,,
lda #1       ; The character code for A
ldy #0       ; Index (the value added to the address in the next line)
sta (ptr),y  ; Basically, the pointed-at location + Y
It's more code, but you get to manipulate the $fd/$fe pointer to change the position of something. If you use absolute addressing here, you lack flexibility, and you'll get frustrated when it comes to putting things where you want.
READY_
User avatar
bkumanchik
Vic 20 Newbie
Posts: 13
Joined: Thu Mar 03, 2022 8:03 pm
Location: Los Angeles
Occupation: Art Director

Re: Using a "word" data type

Post by bkumanchik »

I'll give that a try, thanks


thegg wrote: Wed Mar 23, 2022 4:14 pm You might find it useful to hold your character position as a screen row and column rather than an offset from an absolute address. You can then load the zero page pointers (as shown by chysn) with the address of the screen row, and offset to the column using the y index. To keep things simple, I use a table of row addresses as words indexed by row *2 rather than multiplying by 22.

Alternatively, if you work in terms of row and column you could make use of the Kernal routines PLOT and CHROUT to print your character.
For example:
Your character is to be displayed at row 10, column 11. The code would be:
clc ;indicate plot position
ldx #11 ;column (0-21)
ldy #10 ;row (0-22)
jsr $FFF0 ;plot - set cursor position
lda #char ;CBM ASCII code for character
jsr $FFD2 ;chrout - print at cursor position
READY_
Post Reply