Beginner Needs Help in 6809 code, but 6502 is fine too!

Programming the 6502 microprocessor and its relatives in assembly and other languages.
Finn
Posts: 11
Joined: 05 Nov 2012

Beginner Needs Help in 6809 code, but 6502 is fine too!

Post by Finn »

I hope it's ok to ask this here because it's 6809 code, but it's pretty similar to 6502 so i hoped it would be ok. (i cant find any 6809 forums!) I am a *complete* beginner but i am trying to write a program for the Vectrex console, hence the 6809

To Start with i wanted to just make a dot move left and right on the screen, but limit it to the borders of the screen. I normally write in a BASIC variant and to do that you would do something like this below. where XMan is the x-position of the object (or man) and Xv is the x-vector added to his x-position each frame

Code: Select all

Repeat

    xMan=XMan+Xv

    If Xv>20 then Xv=20 : Xv=-Xv
    If Xv<-20 then Xv=-20 : Xv=-Xv

Until Escape key pressed

Here is the logic part of my 6809 program (I have taken out the initialisation + the drawing parts which arent relevant)

Code: Select all

loop:
                LDA   XMan		        ;add Xv to Xman
		ADDA	Xv
		
		CMPA	#20			;Check XMan >20
		BLE	chk2
		LDA	#20
		BRA	NegXv
chk2:
		CMPA	#-20			;Check if XMan <20
		BGE	fin
		LDA	#-20
		BRA	NegXv
NegXv:
		NEG	Xv			;two's complement Xv
fin:
		STA	XMan
                 
                BRA     loop			; and repeat forever
(sorry for the weird formatting - it looks ok in the message box, just not here)

This works, but i wanted if know if there is a faster way to do it? with the least number of cycles, because i will want to eventually move a lot of objects round the screen and then i will be checking limits on the y-axis too, so for this reason, it needs to be fast. Thanks very much for any help :) if 6809 is a problem then 6502 code is fine too. I have read (beginner) books on both recently.
teamtempest
Posts: 443
Joined: 08 Nov 2009
Location: Minnesota
Contact:

Re: Beginner Needs Help in 6809 code, but 6502 is fine too!

Post by teamtempest »

Don't know much about the 6809, but some bits of code look unnecessary. The second BRA, for instance. There's no code between it and the target at 'NegVx', so it essentially does nothing but take up time. It can go:

Code: Select all

loop:
                LDA   XMan              ;add Xv to Xman
      ADDA   Xv
      
      CMPA   #20         ;Check XMan >20
      BLE   chk2
      LDA   #20
      BRA   NegXv
chk2:
      CMPA   #-20         ;Check if XMan <20
      BGE   fin
      LDA   #-20
NegXv:
      NEG   Xv         ;two's complement Xv
fin:
      STA   XMan
                 
                BRA     loop         ; and repeat forever
Then there's the whole issue of NEG. Why? I don't understand it in the BASIC code either. Why load a value just to negate it right away? Why not load the negated value in the first place and be done with it?

Code: Select all

loop:
                LDA   XMan              ;add Xv to Xman
      ADDA   Xv
      
      CMPA   #20         ;Check XMan >20
      BLE   chk2
      LDA   #-20
      BRA   fin

chk2:
      CMPA   #-20         ;Check if XMan <20
      BGE   fin
      LDA   #20
fin:
      STA   XMan
                 
                BRA     loop         ; and repeat forever
User avatar
Dr Jefyll
Posts: 3526
Joined: 11 Dec 2009
Location: Ontario, Canada
Contact:

Re: Beginner Needs Help in 6809 code, but 6502 is fine too!

Post by Dr Jefyll »

Quote:
sorry for the weird formatting - it looks ok in the message box, just not here
Welcome, Finn. When composing your post if you hit the Preview button you'll be able to see in advance what the result will look like and make adjustments accordingly. It may take a few iterations but eventually you can get things prettied up! :D

I like the 6809, and back in the day built a homebrew with two 6809's running at 1.5 MHz and 64K of memory running at 3 MHz. But on the software side I'm not what you'd call an expert -- and what little I knew I've mostly forgotten! Still, I can venture an observation or two. (And this would apply in 6502, 6809 or even BASIC !)

[Edit:Oops, I see TT has posted while I was typing this...]

Mostly what I notice is that you'd do better to begin by testing the sign of Xv (the x-vector added to position), and then, based on its sign, branching into either of two main forks. So, for example, if Xv is positive then you needn't subsequently execute code to test whether you've encountered the negative limit. Likewise if Xv is negative then the code that executes on that fork needn't waste time testing whether the positive limit has been encountered.

Naturally my suggestion is intended to constructive, not critical. Really you're to be congratulated on taking the plunge into assembly language -- and, despite lack of experience, producing working code!

Feel free to stick around and get acquainted with the gang; there's a LOT of expertise on tap here! You're also welcome to PM or email me if you feel so inclined.

cheers
Jeff
Last edited by Dr Jefyll on Tue Nov 06, 2012 12:56 am, edited 1 time in total.
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html
User avatar
Dr Jefyll
Posts: 3526
Joined: 11 Dec 2009
Location: Ontario, Canada
Contact:

Re: Beginner Needs Help in 6809 code, but 6502 is fine too!

Post by Dr Jefyll »

teamtempest wrote:
Why not load the negated value in the first place and be done with it?
This is also a helpful suggestion. If you have a series of operations that need to occur then it'll be quicker to do them in a register.
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html
Finn
Posts: 11
Joined: 05 Nov 2012

Re: Beginner Needs Help in 6809 code, but 6502 is fine too!

Post by Finn »

Thanks for the tips and replies. i am just reading through them and trying to understand.

I screwed up the BASIC code (there is no hope for me in assembly!)

should be

Code: Select all

Repeat

    xMan=XMan+Xv

    If XMan>20 then XMan=20 : Xv=-Xv
    If XMan<-20 then XMan=-20 : Xv=-Xv

Until Escape key pressed
i suppose i negated Xv there so that it could be any value and maybe change between frames, like a general thing. but yes in this vectrex programme it will probably be a set value so good tip.

@Team Tempest - yes good point on the second BRA, even with my limited knowledge i can see that's a bad idea.
Quote:
TeamTempest wrote:- Then there's the whole issue of NEG. Why? I don't understand it in the BASIC code either. Why load a value just to negate it right away? Why not load the negated value in the first place and be done with it?
I think i confused you with my dodgy BASIC and my comment was wrong in the 2nd program too (Sorry!). It should set XMan to -20 (the left side limit) and then Negate Xv, which is a seperate variable. The NEG instruction negates the value from a memory location in this case not from the accumulator. but yes i understand now about setting Xv directly to a value. thank you.
Quote:
Dr Jefyll wrote :- I like the 6809, and back in the day built a homebrew with two 6809's running at 1.5 MHz and 64K of memory running at 3 MHz. But on the software side I'm not what you'd call an expert -- and what little I knew I've mostly forgotten! Still, I can venture an observation or two. (And this would apply in 6502, 6809 or even BASIC !)
thanks for welcome Dr Jefyll. My initial experiements have lead me to believe that writing bad assembly language will be quite easy but doing it well will be very difficult! i was reading some of your tips in 6502 yesterday and wondering if there were equivalent tips for the 6809 (e.g using a BIT instruction to skip over a byte or 2 bytes n the 6502). Yes i really like the 6809 so far. I did read a book on 6502 first and the 6809 seems to 'fix' a lot of the issues the author of the first book had with the 6502. and it has a multiply instruction too! but sadly no division :/

This is from 6809 The Design Philosophy by Terry Ritter and Joel Boney at Motorola Inc.
Quote:
Point 7:
You have a MULtiply, but no DIVide.
Answer 7:
True enough. Multiply operations are required in high level language subscript array calculations,
but how often do you really need divide? Do you really want to pay for something
you will rarely use and can do easily with a program. Additionally, the unsigned multiply is easily
capable of extension into multiple precision arithmetic. (Try that with a singed multiply!) Divide
does not decompose as nicely. This combined with the absence of similar instructions in the machine
(divide needs 24 bits of parameters, both in and out) was enough to leave it out.
I still wouldnt have minded a divide, but he appears to make a good point.
Quote:
Dr Jefyll wrote :- Mostly what I notice is that you'd do better to begin by testing the sign of Xv (the x-vector added to position), and then, based on its sign, branching into either of two main forks. So, for example, if Xv is positive then you needn't subsequently execute code to test whether you've encountered the negative limit. Likewise if Xv is negative then the code that executes on that fork needn't waste time testing whether the positive limit has been encountered.
yes i like that too, i am going to try and write a revised version taking all of these points onboard. thanks for all the help
User avatar
GARTHWILSON
Forum Moderator
Posts: 8773
Joined: 30 Aug 2002
Location: Southern California
Contact:

Re: Beginner Needs Help in 6809 code, but 6502 is fine too!

Post by GARTHWILSON »

Quote:
Yes i really like the 6809 so far. I did read a book on 6502 first and the 6809 seems to 'fix' a lot of the issues the author of the first book had with the 6502. and it has a multiply instruction too! but sadly no division :/
Note that the 65c02 has more instructions and addressing modes than the original 6502 (NMOS version). The CMOS is not just more power-thrifty, but corrects all the bugs of the NMOS one and adds more features, including in current-production ones some new inputs and outputs, including the bus-enable input, the vector-pull output, and the memory-lock output. The 65816 is the 16-bit extension with 24-bit address bus. It is much more powerful, even if you don't address more than 64K of memory space. I find it much easier also to program for situations that are constantly dealing with 16-bit numbers.

As far as the multiply instruction, how about a whole set of hyper-fast 16-bit math tables? See http://wilsonminesco.com/16bitMathTables/index.html. You can look up trig, log, and other functions in ROM even hundreds of times as fast as actually calculating them, and they will be accurate to all 16 bits every time. For division, one of the tables is a table of inverses, so you can multiply by the inverse (and use tables for the multiply to speed that up too). The inverse table gives 32-bit outputs so you have at least 16 bits' accuracy throughout the entire range of inputs.
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
User avatar
Dr Jefyll
Posts: 3526
Joined: 11 Dec 2009
Location: Ontario, Canada
Contact:

Re: Beginner Needs Help in 6809 code, but 6502 is fine too!

Post by Dr Jefyll »

Hello again, Finn. I didn't know what a Vectrex was, so I just checked it out. I'm envious! What a delightful toy to code for! http://en.wikipedia.org/wiki/Vectrex

I guess that also answers a lot of questions about "why 6809" vs. "why 6502" or even "why 65816." Right now 6809 makes sense for you because that's what you've got! (But you may be interested to read about the 6309, a Hitachi chip that manages to out-6809 the 6809. It includes the Divide instruction... among many other astonishing features, some undocumented.) But 6809 and 6309 are both pretty much just historical curiosities at this point.
Finn wrote:
[...] writing bad assembly language will be quite easy but doing it well will be very difficult! i was reading some of your tips in 6502 yesterday and wondering if there were equivalent tips for the 6809 (e.g using a BIT instruction to skip over a byte or 2 bytes n the 6502)
The trick of using BIT # (or CMP #) to skip over a byte or so is directly transferable to 6809. But I hope that's not your idea of good assembly language programming! Granted; it demands skill and can uniquely solve a problem, but there are far more important things for a novice to learn.
I wrote:
you'd do better to begin by testing the sign of Xv (the x-vector added to position), and then, based on its sign, branching into either of two main forks. So, for example, if Xv is positive then you needn't subsequently execute code to test whether you've encountered the negative limit. Likewise if Xv is negative then the code that executes on that fork needn't waste time testing whether the positive limit has been encountered.
I recoded your program example to incorporate this (below). It's untested, and you should check what I've done, but I think this has the same functionality you were looking for. There's a slight advantage because only one out-of-range check occurs per iteration (not two, as with your original). Hope this helps,

Jeff

Code: Select all

loop:
      LDA   Xv         ;get Xv, the signed value that'll be added to XMan (the object's position)
      BMI   Xv_Neg

Xv_Pos:                 ;Xv is Positive
      ADDA  XMan        ;A= new XMan value= Xv + XMan
      CMPA  #20         ;Is new XMan value > 20? (Over upper limit?)
      BLE   fin         ;Branch if no;
      LDA   #20         ;else replace over-limit value...
      NEG   Xv          ;and make Xv negative for future iterations.
      BRA   fin

Xv_Neg:                 ;Xv is Negative
      ADDA  XMan        ;A= new XMan value= Xv + XMan
      CMPA  #-20        ;Is new XMan value < -20? (Below lower limit?)
      BGE   fin         ;Branch if no;
      LDA   #-20        ;else replace under-limit value...
      NEG   Xv          ;and make Xv positive for future iterations.

fin:
      STA   XMan        ;save updated XMan value       
      BRA   loop        ;and repeat forever
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html
User avatar
BigEd
Posts: 11464
Joined: 11 Dec 2008
Location: England
Contact:

Re: Beginner Needs Help in 6809 code, but 6502 is fine too!

Post by BigEd »

I need to look up that 3-part BYTE article! Thanks, Finn, and a belated welcome!

January 1979
32 A MICROPROCESSOR FOR THE REVOLUTION: The 6809, by Terry Ritter and Joel Boney
February 1979
32 A MICROPROCESSOR FOR THE REVOLUTION: The 6809, by Terry Ritter and Joel Boney
March 1979
46 A MICROPROCESSOR FOR THE REVOLUTION: THE 6800, Part 3, by Terry Ritter and Joel Boney

(I bought a second-hand Vectrex in '85, but the CRT died in a matter of weeks. I still have it. I did once hook up the outputs to a scope in X-Y mode!)

Cheers
Ed
(Edit: readily found online from the title you gave. We don't generally post links here to copyright material.)
Finn
Posts: 11
Joined: 05 Nov 2012

Re: Beginner Needs Help in 6809 code, but 6502 is fine too!

Post by Finn »

Quote:
Garth Wilson wrote:- As far as the multiply instruction, how about a whole set of hyper-fast 16-bit math tables?
Thanks Garth. i like the sound of those look up tables. There is a fair amount of space on vectrex carts, so i could probably use something like that. Providing i am actually capable of making a game! Rotation is quite common in vecrex games because all the objects are drawn with lines, so i will probably need a look up table for sin and cosine as well. (unless there is already one in the bios routines)
Quote:
Dr Jefyll wrote :- Hello again, Finn. I didn't know what a Vectrex was, so I just checked it out. I'm envious! What a delightful toy to code for!
yes vectrex is awesome, mine is actually in the process of breaking so i need a new one. It's really something special in real-life because there is really no way to recreate the vector display the same on emulators (I am using an emulator to program because i dont have a flash cart). It has a minimalist beauty

http://www.youtube.com/watch?v=TV-0AumPhhc

The Vectrex is all open source now too. You can also get source code for one of the best homebrew games, seen in teaser video above (Thrust - converted from the commodore 64 version) online. This is what i am using to help me code at the moment. If anyone wants to follow me into vectrex programming feel free.

Thrust (freeware) source code kindly made available by the author Ville Krumlinde:
http://www.emix8.org/static.php?page=Ve ... rustSource

Code: Select all

Dr Jefyll wrote :- The trick of using BIT # (or CMP #) to skip over a byte or so is directly transferable to 6809. But I hope that's not your idea of good assembly language programming! Granted; it demands skill and can uniquely solve a problem, but there are far more important things for a novice to learn. 
haha yes i do like that stuff. Obviously i am not very skilled but i like to learn about the little tricks i could maybe use in future. I suspect i will struggle just to write a game, so maybe i will leave the tricks to later. They do seem part of the fun of learning assembly though. I learnt yesterday i will have 30,000 cycles per frame if i want my game to run at 50fps. which i do otherwise the vector display wont be stable, but that is quite lot of cycles i guess.

Thats intersting about the 6309 too. It has extra registers! i wish they had used that chip in the vectrex now, but maybe it wasnt available in 1982 anyway.

Thanks very much for taking the time to write me the program. yes that is much better than mine. having only one check. I like your commenting too. I might have to re-jig that program now because i noticed the display is off-centre (on my earlier program too) so i now think the vectrex-beam positioning function may work on relative coordinates rather than actual coordinates. The tutorial i was using was a bit confusing in that sense. (in general the Vectrex uses cartesian coordinates with 0,0 at the centre of the screen)


I had an idea for an optimised solution, but i'm not sure if it actually works. But maybe something can be worked with it by someone better than me.

It was if i knew the object would exactly hit the limit-boundaries and if the boundary was a power of 2. so in this case the boundaries of movement are -32 and 32 and Xv can be 1,2,4,8 or 16. (I figured because the two's complement represntation of any number of a power of 2 always ends in the same sequence of binary numbers as the positive version, you can detect it with one check?)

Code: Select all

loop:
		LDA	XMan			;add Xv to Xman
		ADDA	Xv
		
		ANDA	#$1F 			; Check if Xman=32 or Xman=-32
		BNE	cont
		NEG	XV
cont:	
		STA	XMan
		
		BRA	loop
EDIT: I think i have got that AND wrong. what should it be to detect 32 or -32? is this possible?

Thanks very much for welcome BigED,thats a shame about your vectrex. It sounds like you know what you are doing though, i would have no idea how to hook mine up to anything! Maybe you should get a new one and get some of the new homebrew games out now. There is a great Defender clone called Protector, probably one of the best games on the system.
User avatar
BigEd
Posts: 11464
Joined: 11 Dec 2008
Location: England
Contact:

Re: Beginner Needs Help in 6809 code, but 6502 is fine too!

Post by BigEd »

Ah, Thrust! I remember that from the Beeb - an excellent game.

That Defendalike looks really good:
Image

I think I was planning some kind of dual-ported RAM based cartridge so it could be reprogrammed from a Beeb. But that was many many years ago!

Cheers
Ed
Finn
Posts: 11
Joined: 05 Nov 2012

Re: Beginner Needs Help in 6809 code, but 6502 is fine too!

Post by Finn »

Yes it's great, very smooth too. You wouldnt think the Vectrex's screen would work well for Defender since it's quite narrow, but it's a very good game. Vector Pilot is also really good, that only came out last year.
Quote:
BigEd wrote :- I think I was planning some kind of dual-ported RAM based cartridge so it could be reprogrammed from a Beeb. But that was many many years ago!
that would be a great development system. I used to have a BBC(Master Compact), well my parents did. I'm very fond of the beeb. On here I am named after Mike Finn, hero from the best game ever written in 6502, Exile of course.
White Flame
Posts: 704
Joined: 24 Jul 2012

Re: Beginner Needs Help in 6809 code, but 6502 is fine too!

Post by White Flame »

Finn wrote:
EDIT: I think i have got that AND wrong. what should it be to detect 32 or -32? is this possible?
It's true that if AND #$1f is zero, then it's exactly a multiple of 32, including negatives. However, zero is also a multiple of 32.

One of the shortest ways I can think of to do a range test is this:

Code: Select all

; Pseudo arch
add #32
cmp #65
bcs outOfBounds
Offset the value from -32,+32 range to 0,64, and do an unsigned comparison (branch if >= 65). If it were -32,+31, then you'd be able to do bit masking here, but it still comes out to the same number of instructions.
User avatar
Dr Jefyll
Posts: 3526
Joined: 11 Dec 2009
Location: Ontario, Canada
Contact:

Re: Beginner Needs Help in 6809 code, but 6502 is fine too!

Post by Dr Jefyll »

Quote:
This is from 6809 The Design Philosophy by Terry Ritter and Joel Boney at Motorola Inc.
Quite interesting! In addition to the usual hype about a product and its great features, this material also discusses what isn't included -- some tradeoffs and tough decisions that had to be made.
White Flame wrote:
One of the shortest ways I can think of to do a range test is this:
Looks good to me! :D A lookup table might be a hair faster but that's kind of absurd in this case.
Finn wrote:
haha yes i do like that stuff. [...] They do seem part of the fun of learning assembly
I confess to enjoying the arcane tricks myself -- they are fun!
Finn wrote:
I like your commenting too.
Thanks. You will find (if you haven't already) that commenting is more than just a nicety. Very often the mental process of composing appropriate comments will reveal a logical flaw or other significant insight regarding your program.
Finn wrote:
I might have to re-jig that program now because i noticed the display is off-centre (on my earlier program too) so i now think the vectrex-beam positioning function may work on relative coordinates rather than actual coordinates. The tutorial i was using was a bit confusing in that sense. (in general the Vectrex uses cartesian coordinates with 0,0 at the centre of the screen)
There does seem to be some confusion. The Wikipedia article says, "The vector generator is an all analog design using two integrators: X and Y. The computer sets the integration rates using a digital-to-analog converter. [...] Voltage ramps are produced that the monitor uses to steer the electron-beam over the face of the phosphor screen of the cathode ray tube." To me this says the commands from the CPU aren't relative or absolute coordinates for the dot on the CRT, but instead specify signed speeds for the dot -- its rate of motion in the X and Y axes. For example (dealing just with the X axis), a command of 5 might cause moderate motion in one direction, and a command of -20 would cause rapid motion in the opposite direction. Of course there's got to be more to it than that. For one thing there'd have to be some sort of absolute reference (perhaps zeroing the dot to screen center) before all the motions begin. But understanding this integrator (ramp generator) business sounds like a crucial piece of the puzzle.

cheers
Jeff

ps -- what seems to be the problem with your Vectrex (which you describe as "in the process of breaking")?
pps-- I take back what I said about 6809/6309 being merely historical curiosities. I bet they live on in FPGA.
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html
User avatar
Dr Jefyll
Posts: 3526
Joined: 11 Dec 2009
Location: Ontario, Canada
Contact:

Re: Beginner Needs Help in 6809 code, but 6502 is fine too!

Post by Dr Jefyll »

To satisfy my curiosity I did some cursory research, hoping to find a schematic of the Vectrex analog circuitry that generates the X and Y "ramp" waveforms that produce lines on the screen. I gave up without having found a schematic, but a good deal can be gleaned from some of the programmers reference material. For those who share my curiosity, I direct you to "The Cinematronics Vector Generator" on pg 28 of http://www.vectrex.nl/docs/CineRef.pdf Featured on a Vectrex-related web site, the Cinematronics doc is presumably pertinent. [Edit: no, apparently the Cinematronics is somewhat different.]

[For Cinematronics] it seems commands from the CPU are just X-Y coordinates rendered by a DAC. To draw a line, voltages representing the X-Y of the starting point are instantaneously impressed upon an X capacitor and a Y capacitor. Then new coordinates -- the end point of the line -- are presented, but the mode of the analog circuitry is switched so that the voltage change on the capacitors is not instantaneous; instead, X and Y use RC delay to cause the dot to progress much more slowly, leaving a perceptible image on the CRT. (The nonlinearity of the RC approach is minimized by exaggerating the delta-X and delta-Y. Only a fraction of the RC curve gets expressed; the line-draw aborts and is deemed complete upon expiry of a time delay. Clever! )

-- Jeff

Edit: Cinematronics ramp-generation is not directly eqivalent to Vectrex
Last edited by Dr Jefyll on Sun Nov 11, 2012 2:16 pm, edited 1 time in total.
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html
User avatar
BigEd
Posts: 11464
Joined: 11 Dec 2008
Location: England
Contact:

Re: Beginner Needs Help in 6809 code, but 6502 is fine too!

Post by BigEd »

Hi Jeff
there are some diagrams and notes in this service manual:
http://www.vectrex.nl/docs/vecman.pdf
Cheers
Ed
Post Reply