ZXSpin Assembler

The place for codemasters or beginners to talk about programming any language for the Spectrum.
Post Reply
User avatar
PeterJ
Site Admin
Posts: 6855
Joined: Thu Nov 09, 2017 7:19 pm
Location: Surrey, UK

ZXSpin Assembler

Post by PeterJ »

Evening,

I'm working my way through 'How to Write ZX Spectrum Games' by Jonathan Cauldwell, and I have tried this snippet of code in Spin 0.7S and 0.7Q with the same results. The code assembles fine, then when I try and run with a Randomize USR 24576 it I get a BASIC error 'Integer Out of Range'. It assembles fine with Pasmo, and I can run the .tap file created by Pasmo without problem.

Even though its very old in the tooth now, I like the integrated nature of Spin (and I'm secretly hoping [mention]ZXDunny[/mention] might update it one day) I'm using Windows 10.

Code: Select all

org $6000
	ld a,71
	ld (23693),a
	xor a	
	call 8859

	ld hl,blocks
	ld (23675),hl

	call 3503

	ld hl,21+15*256
	ld (plx),hl
	

	call basexy
	
	call splayr
	ret

basexy	ld a,22
	rst 16
	ld a,(plx)
	rst 16
	ld a,(ply)
	rst 16
	ret

splayr	ld a,69
	ld (23695),a
	ld a,144
	rst 16
	ret

plx defb 0
ply defb 0
blocks defb 16,16,56,56,124,124,254,254
Ralf
Rick Dangerous
Posts: 2279
Joined: Mon Nov 13, 2017 11:59 am
Location: Poland

Re: ZXSpin Assembler

Post by Ralf »

I can't help you with this one but I would have an general advice. Remember that Spin is unfortunately a bit buggy :( It's really a pity as it without bugs it would be really, really great and now it's just good ;)
User avatar
Stefan
Manic Miner
Posts: 795
Joined: Mon Nov 13, 2017 9:51 pm
Location: Belgium
Contact:

Re: ZXSpin Assembler

Post by Stefan »

Compare the contents of memory at 24576 ($6000) with the contents of the Pasmo compiled source?

This post however seems to indicate that the ZX Spin assembler is just broken.
User avatar
R-Tape
Site Admin
Posts: 6353
Joined: Thu Nov 09, 2017 11:46 am

Re: ZXSpin Assembler

Post by R-Tape »

I use 0.666 and have never had any problems, but then I don't use assembly to its full potential.

The problem is this line:

ld hl,21+15*256

It loads HL with 9216 = 0,36 which is an impossible coord.

ld hl,21+(15*256) works.
namco
Manic Miner
Posts: 247
Joined: Mon Dec 04, 2017 8:55 pm

Re: ZXSpin Assembler

Post by namco »

[mention]R-Tape[/mention] Beaten me to it, I was just about to mention that line (but not the solution).

However, comparing this code to mine (from a earlier game):

Code: Select all

ld a,(plx)
rst 16
ld a,(ply)
rst 16
Are the x and y values the wrong way around?
User avatar
PeterJ
Site Admin
Posts: 6855
Joined: Thu Nov 09, 2017 7:19 pm
Location: Surrey, UK

Re: ZXSpin Assembler

Post by PeterJ »

R-Tape wrote: Mon Dec 04, 2017 8:44 pm I use 0.666 and have never had any problems, but then I don't use assembly to its full potential.

The problem is this line:

ld hl,21+15*256

It loads HL with 9216 = 0,36 which is an impossible coord.

ld hl,21+(15*256) works.
Interesting, so Pasmo is doing 15*256 = 3840 + 21 (3,861) which is correct and follows BODMAS (and Sinclair BASIC), whilst Spin is doing (21+15)*256 which is 9,216 as you say Dave.

Replacing that line with LD HL,3,861 works fine in Spin. I suppose its just a matter of getting used to each assemblers oddities.

I did try the Zeus assembler but can't make head nor tale of that.

Thanks everyone

Image
User avatar
R-Tape
Site Admin
Posts: 6353
Joined: Thu Nov 09, 2017 11:46 am

Re: ZXSpin Assembler

Post by R-Tape »

namco wrote: Mon Dec 04, 2017 9:04 pm Are the x and y values the wrong way around?
How do you mean the wrong way round?

This is where I get confused because Jonathan's documentation (and AGD) say X when they mean Y (the vertical axis) and Y when they mean X (the horizontal axis). Both ways work as long as the vertical axis is RSTd first followed the horizontal axis. I think that's why Jonathan uses them that was round, because we say X,Y and the ROM print uses the vertical cord first.

So as long as you mean Y when you say X, and X when you say Y, or whichever way you want X to be, Y can be X or X can be Y.

Do that make sense?

No, where am I? :mrgreen:
User avatar
Ast A. Moore
Rick Dangerous
Posts: 2640
Joined: Mon Nov 13, 2017 3:16 pm

Re: ZXSpin Assembler

Post by Ast A. Moore »

I don’t think it’s the most logical approach in the long run, though. Restart at $10 is just a special case, and I don’t think it’s beneficial for a novice to think of the print coordinates as X and Y. Ideally, you should reserve these to refer to actual pixel coordinates, and stick to thinking “column, row” for anything print-related.

In my simplest (and fastest) printout routines, I don’t even bother with columns and rows—just use the attribute area of the display file directly. (Although, converting back and forth is trivial.)

And yes, each assembler has its own set of quirks. Some are quirkier than others. ;)
Every man should plant a tree, build a house, and write a ZX Spectrum game.

Author of A Yankee in Iraq, a 50 fps shoot-’em-up—the first game to utilize the floating bus on the +2A/+3,
and zasm Z80 Assembler syntax highlighter.
namco
Manic Miner
Posts: 247
Joined: Mon Dec 04, 2017 8:55 pm

Re: ZXSpin Assembler

Post by namco »

Both ways work as long as the vertical axis is RSTd first followed the horizontal axis. I think that's why Jonathan uses them that was round, because we say X,Y and the ROM print uses the vertical cord first.
That's fine! :)

Oh and it's probably best to use brackets when seeing things like this:
ld hl,21+15*256

That way no assembler gets confused!
User avatar
R-Tape
Site Admin
Posts: 6353
Joined: Thu Nov 09, 2017 11:46 am

Re: ZXSpin Assembler

Post by R-Tape »

Ast A. Moore wrote: Mon Dec 04, 2017 9:28 pm I don’t think it’s the most logical approach in the long run, though. Restart at $10 is just a special case
I've often wondered* how feasible it would be for a complete beginner's guide to asm to not use ROM routines at all. It's easy enough to draw a char, but moving it around becomes tricky as you'd need a yx2cell routine that brings forth the intimidating display file layout far too early. Perhaps it could just be included with a note 'just CALL this routine to do this, don't worry about understanding it yet'. Then you could move onto sprites more fluidly. In fact I would have understood that more than I did the magic RST 16 at the time! (Not saying this applies to you Peter).

*But never done anything about.
User avatar
Ast A. Moore
Rick Dangerous
Posts: 2640
Joined: Mon Nov 13, 2017 3:16 pm

Re: ZXSpin Assembler

Post by Ast A. Moore »

R-Tape wrote: Mon Dec 04, 2017 10:21 pm It's easy enough to draw a char, but moving it around becomes tricky as you'd need a yx2cell routine that brings forth the intimidating display file layout far too early.
Not for calculating character cell addresses. It’s pretty trivial, as your column is just a range of values 0–31, and your row is just n lots of 0–31. The advantage is that your printout routine doesn’t have to deal with screen thirds.

If I remember correctly, my simplest printout routine was only 19 bytes long (using the bitmap address). Making it accept an attribute address instead will only add seven more bytes. (It’s beneficial if you want to add color and wish for the text to automatically move down one line.)

It’s the smoothest (and most practical) introduction to the actual screen layout I can think of. You are essentially doing sprites. Simple, 8x8, character–cell-aligned sprites, but sprites, nevertheless. Much more exciting than the mysterious incantation of “RST $10.”
Every man should plant a tree, build a house, and write a ZX Spectrum game.

Author of A Yankee in Iraq, a 50 fps shoot-’em-up—the first game to utilize the floating bus on the +2A/+3,
and zasm Z80 Assembler syntax highlighter.
Ralf
Rick Dangerous
Posts: 2279
Joined: Mon Nov 13, 2017 11:59 am
Location: Poland

Re: ZXSpin Assembler

Post by Ralf »

The problem is this line:

ld hl,21+15*256

It loads HL with 9216 = 0,36 which is an impossible coord.
Yes, now I remember old post at WOS about it.

Spin doesn't follow standard math order of calculations. You know - multiplication first, addition later.

Instead it goes just from left to right:

21+15=36
36*256=9216

So remember about it and use brackets every time. They seem to work correctly :)
User avatar
R-Tape
Site Admin
Posts: 6353
Joined: Thu Nov 09, 2017 11:46 am

Re: ZXSpin Assembler

Post by R-Tape »

Ast A. Moore wrote: Tue Dec 05, 2017 9:22 am Not for calculating character cell addresses. It’s pretty trivial, as your column is just a range of values 0–31, and your row is just n lots of 0–31. The advantage is that your printout routine doesn’t have to deal with screen thirds.

If I remember correctly, my simplest printout routine was only 19 bytes long (using the bitmap address). Making it accept an attribute address instead will only add seven more bytes. (It’s beneficial if you want to add color and wish for the text to automatically move down one line.)

It’s the smoothest (and most practical) introduction to the actual screen layout I can think of. You are essentially doing sprites. Simple, 8x8, character–cell-aligned sprites, but sprites, nevertheless. Much more exciting than the mysterious incantation of “RST $10.”
This sounds a good way in, but I would still say that for the complete beginner trying to get your head around moving within the DF at all is a bit much - so I would include the bit interpretations and screen2attr as things to 'call but don't worry about yet'.
User avatar
R-Tape
Site Admin
Posts: 6353
Joined: Thu Nov 09, 2017 11:46 am

Re: ZXSpin Assembler

Post by R-Tape »

Ast A. Moore wrote: Tue Dec 05, 2017 9:22 am Much more exciting than the mysterious incantation of “RST $10.”
When I started learning asm I used to think RST 16 was superfast instruction as it was hardwired. Little did I realise that in practise they're the same - RST 16 and CALL 16 both can only manage 42 chars per frame.
User avatar
Ast A. Moore
Rick Dangerous
Posts: 2640
Joined: Mon Nov 13, 2017 3:16 pm

Re: ZXSpin Assembler

Post by Ast A. Moore »

R-Tape wrote: Tue Dec 05, 2017 10:54 am I would still say that for the complete beginner trying to get your head around moving within the DF at all is a bit much - so I would include the bit interpretations and screen2attr as things to 'call but don't worry about yet'.
Indeed. Might work for some, with the caveat of inadvertently encouraging the “it’s just the way it is, don’t think too much about it” behavior, though.
R-Tape wrote: Tue Dec 05, 2017 11:05 am When I started learning asm I used to think RST 16 was superfast instruction as it was hardwired. Little did I realise that in practise they're the same - RST 16 and CALL 16 both can only manage 42 chars per frame.
Heh. Yet CALL is three times larger and six T states slower. :D

On a more serious note, I think it’s important to teach beginners that there’s a fundamental difference between universal (read: library-based) and custom approaches to programming for underpowered micros. The former is instrumental for saving space, while the latter is crucial for gaining speed. The RST $10 routine is an excellent case in point. It does too many things—which makes it universal—but at a huge speed expense. A perfect “gateway drug” to writing small and fast custom routines.

Thirty-two characters (with color) in about one-fifth of a frame (the black border represents execution time):
Image
Every man should plant a tree, build a house, and write a ZX Spectrum game.

Author of A Yankee in Iraq, a 50 fps shoot-’em-up—the first game to utilize the floating bus on the +2A/+3,
and zasm Z80 Assembler syntax highlighter.
User avatar
Morkin
Bugaboo
Posts: 3251
Joined: Mon Nov 13, 2017 8:50 am
Location: Bristol, UK

Re: ZXSpin Assembler

Post by Morkin »

I've tended to use Spin 0.666 and its assembler, as it seems a bit more stable than 0.7. Only thing is that the beeper in 0.666 didn't seem to work when it's in 48k mode, but I always found it great apart from that.

I found Jonathan's guide really useful, but I didn't attempt to follow along with creating his game as I didn't really want to play Centipede.. ;)

I used Tapey-boy's method of "borrowing" a routine that converted an XY screen co-ordinate into the correct point on the screen without worrying how it worked, and then printed the sprite on screen. It was then just a series of steps:

(1) work out how print a sprite to the screen
(2) work out how to read the keyboard
(3) create extra graphic sprites for the character in "half character steps" (for 4 pixel rather than 8 pixel moves)

The result was this:

Image

The first time I successfully tried to do (2) I burst out laughing'; the sprite basically just 'teleported' from the middle of the screen to the edge. Having got so used to BASIC back in the day, I'd forgotten that machine code was so quick it was faster than the naked eye.. I had to put a pause in between frames after that.. :lol:

...So ultimately it's proof positive that it's possible for a complete novice to learn without using the RST 16 routine.


[Edit: oh, you can probably see why I recruited Rorthron to do the graphics for Catacombs of Balachor.. :lol: ]
My Speccy site: thirdharmoniser.com
User avatar
PeterJ
Site Admin
Posts: 6855
Joined: Thu Nov 09, 2017 7:19 pm
Location: Surrey, UK

Re: ZXSpin Assembler

Post by PeterJ »

Hi [mention]Morkin[/mention] ,

Thanks for this. Any chance of sharing the code for this example?
User avatar
Morkin
Bugaboo
Posts: 3251
Joined: Mon Nov 13, 2017 8:50 am
Location: Bristol, UK

Re: ZXSpin Assembler

Post by Morkin »

Would be happy to but I'd have to dig it out from a mass of files and I'm not even sure if I still have it... Will have a look, but no promises..! :|

If it helps, I used the two routines in chapter one (p6-8) of the Advanced Spectrum Machine Language book:

http://zxinfo.dk/details/2000025

One for the pixels and one for the attributes.

It explains about how the screen works but I couldn't get my head round how the rows/columns etc. worked at the time, despite reading it about 3 times...

Fortunately, you can just use the routines without knowing exactly how they work, you only need to get the general gist of them to start with. (Well, that's what I reckon anyway! :D )

You can LD B (and C) with your X (and Y) screen co-ordinates, CALL the routines and the HL register is pointing at the top pixel line of the square you want to print your graphic at, ready to LD data into.
My Speccy site: thirdharmoniser.com
User avatar
PeterJ
Site Admin
Posts: 6855
Joined: Thu Nov 09, 2017 7:19 pm
Location: Surrey, UK

Re: ZXSpin Assembler

Post by PeterJ »

This is where I get confused because Jonathan's documentation (and AGD) say X when they mean Y (the vertical axis) and Y when they mean X (the horizontal axis). Both ways work as long as the vertical axis is RSTd first followed the horizontal axis. I think that's why Jonathan uses them that was round, because we say X,Y and the ROM print uses the vertical cord first.
I have been letting my brain digest this today, and reading my Spectrum manual again and I agree with you it is odd how the Spectrum BASIC (and ROM routine) works opposite to what you expect.

Normally you would expect X along the bottom and Y up the side:

Image

But the "Print At" and RST routines uses lines then columns which I would have said in Y,X as you say. Then Jonathan refers to them as X,Y. Sorry if I'm rambling! I need to print something out and stick it on the wall!
User avatar
PeterJ
Site Admin
Posts: 6855
Joined: Thu Nov 09, 2017 7:19 pm
Location: Surrey, UK

Re: ZXSpin Assembler

Post by PeterJ »

Bob's 8-Bit Blog tutorials code everything from scratch rather than using ROM routines.

https://bobs8bb.wordpress.com/
User avatar
Ast A. Moore
Rick Dangerous
Posts: 2640
Joined: Mon Nov 13, 2017 3:16 pm

Re: ZXSpin Assembler

Post by Ast A. Moore »

PeterJ wrote: Tue Dec 05, 2017 8:41 pm But the "Print At" and RST routines uses lines then columns which I would have said in Y,X as you say. Then Jonathan refers to them as X,Y.
As I mentioned, it’s not a good idea to think of the print position as having coordinates in the conventional sense. Jonathan’s tutorial is probably reflective of his peculiar paradigm. No need to rack your brain over it. Just remember that it’s “at row R, column C.” Forget the X and Y. Leave them strictly to pixel coordinates.

Another important aspect regarding coordinates on the Spectrum is that the graph in your picture is, well, also misleading. While you could set up an arbitrary origin point in your code (and, in fact, the BASIC PLOT routine does just that), the easiest and most natural way is to pin it to the top left corner. This way, increasing an address in the display file will also naturally increase the coordinates.
Every man should plant a tree, build a house, and write a ZX Spectrum game.

Author of A Yankee in Iraq, a 50 fps shoot-’em-up—the first game to utilize the floating bus on the +2A/+3,
and zasm Z80 Assembler syntax highlighter.
User avatar
PeterJ
Site Admin
Posts: 6855
Joined: Thu Nov 09, 2017 7:19 pm
Location: Surrey, UK

Re: ZXSpin Assembler

Post by PeterJ »

Thanks for that. The graph was just to illustrate the tradition x,y and I appreciate the Spectrum print at coordinates start in the top left. Thanks for all the detail.
User avatar
Seven.FFF
Manic Miner
Posts: 735
Joined: Sat Nov 25, 2017 10:50 pm
Location: USA

Re: ZXSpin Assembler

Post by Seven.FFF »

I never really bothered with any ROM routines. I just checked my commit history, and the first thing I wrote before the initial commit was a table-based level renderer.

It was a little different because Nirvana has a well-optimised character print routine. In that respect it was a little like R-Tape’s “call but don't worry about yet” idea. But having the source accessible actually encouraged me to pore over the code endlessly, until I was able to understand it well enough to write my own specialised adaptations.

I gave some thought to how I wanted to store level data compactly, and being a db programmer in real life it was interesting to Approach it that way. I ended up with some kind of almost relational structure that stored characters and multicolour attributes in their own tables, and composed combinations of those plus coordinates into another table, then added another table referencing a set of those records for each level.

It’s still serving me well now. I even extended it other day in a new project to allow the data to be split up across RAM banks.
Robin Verhagen-Guest
SevenFFF / Threetwosevensixseven / colonel32
NXtel NXTP ESP Update ESP Reset CSpect Plugins
Post Reply