Assembly Language Help
Assembly Language Help
I'm building my first ever assembly language game (It's only taken my 30 years to start getting my head around assembler (Thanks to the Johnathan Cauldwell book and Cracking the Code by John Wilson). [mention]R-Tape[/mention] has also been very helpful answering all my daft questions!
Anyway, the game is based on the Benny Bunny games which appeared in Sinclair Programs.
My character moves left and right, but what I'm trying to get my head around is how to code the re-drawing of the ladder when you walk past it. I know the purists will hate this, but I'm just using very simple RST16 Character printing.
The code (please don't laugh at it!) is here.
https://pastebin.com/efLPgXP7
I have only started working on the move left code check for now, and you will see it draws a replacement ladder, but in the wrong place.
Thanks
Anyway, the game is based on the Benny Bunny games which appeared in Sinclair Programs.
My character moves left and right, but what I'm trying to get my head around is how to code the re-drawing of the ladder when you walk past it. I know the purists will hate this, but I'm just using very simple RST16 Character printing.
The code (please don't laugh at it!) is here.
https://pastebin.com/efLPgXP7
I have only started working on the move left code check for now, and you will see it draws a replacement ladder, but in the wrong place.
Thanks
- Ast A. Moore
- Rick Dangerous
- Posts: 2641
- Joined: Mon Nov 13, 2017 3:16 pm
Re: Assembly Language Help
My guess is that’s exactly why it’s redrawn at the wrong coordinates. Look into the RST 16 routine. You’ll see that it increments the horizontal coordinate, and the next character (unless explicitly instructed to do otherwise) will be printed one cell to the right of the current one. You print the bunny, then check if he bumps into a ladder, then print the ladder without actually telling it where to print it. So it prints it to the right of the bunny.
Recalculate the coordinates for redrawing the ladder based on the bunny’s coordinates and you’re good.
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.
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.
Re: Assembly Language Help
Thank you [mention]Ast A. Moore[/mention]. I went for a slightly different option, but your thoughts helped me on the road. Thanks
Maybe I can get my title in WH Smiths for Christmas
Maybe I can get my title in WH Smiths for Christmas
- Ast A. Moore
- Rick Dangerous
- Posts: 2641
- Joined: Mon Nov 13, 2017 3:16 pm
Re: Assembly Language Help
Yay! That is one wicked fast bunny.
By the way, you might want to rethink your keyboard polling routine. It’s nice that you try to save a few bytes by pushing and popping the A register. The biggest drawback is that you’ll be cornering yourself if you want to let the user redefine the keys.
This isn’t criticism—your code works perfectly well; just a friendly warning of the pitfalls that might lie ahead.
By the way, you might want to rethink your keyboard polling routine. It’s nice that you try to save a few bytes by pushing and popping the A register. The biggest drawback is that you’ll be cornering yourself if you want to let the user redefine the keys.
This isn’t criticism—your code works perfectly well; just a friendly warning of the pitfalls that might lie ahead.
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.
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.
Re: Assembly Language Help
Thank you, that is a good point. I will bear that in mind.
Next task is to allow him to climb the ladders and stop him from jumping off mid-climb.
Next task is to allow him to climb the ladders and stop him from jumping off mid-climb.
Re: Assembly Language Help
Great to see you first game coming!
But is this only this animated screenshot or does this bunny flicker like hell?
Are you using some synchronisation with the screen refresh?
But is this only this animated screenshot or does this bunny flicker like hell?
Are you using some synchronisation with the screen refresh?
Re: Assembly Language Help
Hi [mention]Ralf[/mention], it's does constantly redraw but I think the flicker is worse in the GIF.
Re: Assembly Language Help
I would suggest that you define some constants instead of adding comments like these:
Since it will be a lot cleaner to read and write, something like:
Also define constants instead of using magic numbers, since it will help you out a lot, the next time you read your code.
Here is a simple example:
That 22, is a magic number.
Define a constant for it instead, so that you know what it means in the future.
`plx` or `ply` are clear on what they are, since they are named, by 22 could be anything.
I also strongly suggest that you start thinking on some level data structures early on, since printing a string (string3), is probably not the best or most efficient way to do it.
Code: Select all
call 8859 ;set border colour
Code: Select all
call set_border_colour
Here is a simple example:
Code: Select all
;Character Printing Routines
basexy ld a,22
rst 16
ld a,(plx)
rst 16
ld a,(ply)
rst 16
ret
Define a constant for it instead, so that you know what it means in the future.
`plx` or `ply` are clear on what they are, since they are named, by 22 could be anything.
I also strongly suggest that you start thinking on some level data structures early on, since printing a string (string3), is probably not the best or most efficient way to do it.
- Ast A. Moore
- Rick Dangerous
- Posts: 2641
- Joined: Mon Nov 13, 2017 3:16 pm
Re: Assembly Language Help
Different strokes. I was never a big fan of this approach. To me, this always took away from the straightforwardness of assembly. Defining tons of constants is a high-level programming language approach. In addition, in my opinion it actually reduces readability, especially with ROM calls. With actual addresses, you can always tell at a glance whether you’re calling a subroutine in ROM or RAM. With constants, it all pretty much turns into a wall of text.
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.
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.
Re: Assembly Language Help
This a kind of a double edge sword.Ast A. Moore wrote: ↑Mon Apr 30, 2018 11:28 amDifferent strokes. I was never a big fan of this approach. To me, this always took away from the straightforwardness of assembly. Defining tons of constants is a high-level programming language approach. In addition, in my opinion it actually reduces readability, especially with ROM calls. With actual addresses, you can always tell at a glance whether you’re calling a subroutine in ROM or RAM. With constants, it all pretty much turns into a wall of text.
If you got used to recognize a set of specific addresses, than that probably works as a name or reference for you, but it will probably not work with others.
For example, a lot of the systems variables are named in the ZX manual, hence in practice we should use their names, since that is common knowledge, but that doesn't prevent individual A or B, to actually know their address values by heart. But that will not be the general case for sure.
Another example, is opcode by values. Back in the day and after a lot of practice, most coders would know the opcode byte values by heart, but that doesn't make it easier to read then see a listing with opcodes instead of byte values.
Our brains are wired to recognize patterns, and it's very good at it, but we can always make it easier for ourselves, by using what is easier to recognize and/or memorize.
TIP: if you need that ROM/RAM distinction, you can always include that in your constants, somehow: ROM_*/RAM_*, or R_*/*, or whatever you find more suitable.
- Ast A. Moore
- Rick Dangerous
- Posts: 2641
- Joined: Mon Nov 13, 2017 3:16 pm
Re: Assembly Language Help
It’s extremely easy to see at a glance whether an address is in ROM or RAM—any Spectrum developer knows that RAM starts at address $4000 (16384), so anything below that is a ROM call. Comments will help with the rest. The same applies to system variables.RMartins wrote: ↑Mon Apr 30, 2018 1:48 pm If you got used to recognize a set of specific addresses, than that probably works as a name or reference for you, but it will probably not work with others.
For example, a lot of the systems variables are named in the ZX manual, hence in practice we should use their names, since that is common knowledge, but that doesn't prevent individual A or B, to actually know their address values by heart. But that will not be the general case for sure.
I’ll reiterate: applying high-level programming language practices to assembly—particularly in the context of the Spectrum (what with it being a relatively simple machine)—will only muddy the waters and create confusion. The fewer levels of abstraction exist between the hardware and the software the better.
As for the opcode analogy, I think that’s strawmanning. Assembly already has a one-to-one correspondence between a mnemonic and its opcode, so there’s no practical need in memorizing the latter. In the rare cases of self-modifying code, when you need to inject a different opcode somewhere in your code, a quick glance at the Z80 instruction set is all that’s needed.
I agree about pattern recognition, but there’s also readability and efficiency. You can just as easily recognize the few ROM addresses that are practical to use in programming. Moreover, a fixed address will instantly tell you that you’re making a ROM call or addressing a system variable; whereas a label will signal to you that it’s a reference to a RAM address, which can move from location to location as you work on your code. When both are represented by a label—confusion will inevitably set in.
Either approach will work, of course. Any assembler will happily replace labels with constants or memory addresses. Readability is a different matter, however.
In any case, for the most part, this whole argument becomes moot at some point, as people tend to use ROM calls more and more sparingly once their programming skills have improved and they have come up with their own, more efficient routines.
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.
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.
Re: Assembly Language Help
If you're going to be showing your code to other people and asking them to help you fix it then it needs to be very clear what's going on.
Whether that's through commenting everything or using labels doesn't really matter, so long as it's clear. But using opcodes and 'magic numbers' without a comment makes the code very hard to read.
Using labels for things like system variable addresses and ROM routines is hardly a 'higher level language' concept though. It's been done for years. Having an include file with lables defined for all the system variables and the ROM functions (as listed in The Complete Spectrum ROM Disassembly) is/was a fairly common practice.
Whether that's through commenting everything or using labels doesn't really matter, so long as it's clear. But using opcodes and 'magic numbers' without a comment makes the code very hard to read.
Using labels for things like system variable addresses and ROM routines is hardly a 'higher level language' concept though. It's been done for years. Having an include file with lables defined for all the system variables and the ROM functions (as listed in The Complete Spectrum ROM Disassembly) is/was a fairly common practice.
Re: Assembly Language Help
Different strokes. I was never a big fan of this approach.
It's a matter of your personal programming style. Eveybody may have his own.This a kind of a double edge sword.
Unfortunately in the past I have seen many really intellingent people going into not so intelligent fights about the style In case of Z80 assembly it was either using decimal/hexadecimal or like here about labels, constants, comments.
Personally I use decimal notation in my programs and several times I was told that it's very wrong. But it just works for me. My answer was always the same - do it your way and let others to do it their way.
As for "magic numbers" my personal approach is something balanced. I never write code like LD (30000),A. Always use labels for such case.
But LD HL,16384 is much clearer for me than LD HL,Screen (what the hell is screen?)
- Ast A. Moore
- Rick Dangerous
- Posts: 2641
- Joined: Mon Nov 13, 2017 3:16 pm
Re: Assembly Language Help
Well, duh. Most uncommented assembly listings are difficult to read. (If I don’t comment my own code profusely, I tend to forget what I was thinking writing it in less than a week.) Knowing some “magic numbers” helps, though.
Well, The Complete Spectrum ROM Disassembly aside (although it too suffers from readability issues, but it’s a special case), I think we need to make a clear distinction then between readability in general and readability as perceived by the author. I posit they are not the same. I personally find browsing through a gazillion include files maddening.Joefish wrote: ↑Mon Apr 30, 2018 2:57 pmUsing labels for things like system variable addresses and ROM routines is hardly a 'higher level language' concept though. It's been done for years. Having an include file with lables defined for all the system variables and the ROM functions (as listed in The Complete Spectrum ROM Disassembly) is/was a fairly common practice.
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.
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.
- Ast A. Moore
- Rick Dangerous
- Posts: 2641
- Joined: Mon Nov 13, 2017 3:16 pm
Re: Assembly Language Help
I use a mixture of all three: mostly decimals for arithmetic and known addresses (i.e. system variables), hexadecimals nice “round” numbers (when suitable) and some well-known locations (i.e. $4000, $5b00, etc.), and binary for when bits are important (i.e. attributes, port masks, etc.)
Occasionally, I even use arithmetic expressions (for fractional coordinates, for example):
Code: Select all
ld hl,15+256*58 ;L=15 (fraction), H=58 (integer)
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.
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.
Re: Assembly Language Help
Hehe, I do that too Things like LD HL,50*256+1Occasionally, I even use arithmetic expressions (for fractional coordinates, for example):
This way I can remain in decimal notation and still see high and low byte.
Re: Assembly Language Help
The point of using named labels is so that the name itself is clear; you shouldn't have to refer to the include file that defines it to understand what it does.
Re: Assembly Language Help
Yes, indeed. If ld hl, Screen doesn't quite do it for you, call the constant ScreenPixelsStart or something! Although extensive commenting is invaluable, there's a certain amount of self-documentation available that can really help.
Robin Verhagen-Guest
SevenFFF / Threetwosevensixseven / colonel32
NXtel • NXTP • ESP Update • ESP Reset • CSpect Plugins
SevenFFF / Threetwosevensixseven / colonel32
NXtel • NXTP • ESP Update • ESP Reset • CSpect Plugins
Re: Assembly Language Help
Thanks for all the comments. Coding style is indeed down to personal preference and I think where it's the equivalent of variables like plx and ply it makes sense to me, but where it's a ROM routine I think a remark is fine. I am trying to use useful names for labels though.
Re: Assembly Language Help
Well, except when it isn't. Like on the +2A/+3.Ast A. Moore wrote: ↑Mon Apr 30, 2018 2:31 pm It’s extremely easy to see at a glance whether an address is in ROM or RAM—any Spectrum developer knows that RAM starts at address $4000 (16384), so anything below that is a ROM call. Comments will help with the rest. The same applies to system variables.
Ironically, that's the biggest reason to use labels over comments. Because you're going to use labels when you use your own code (so gain consistency) and will also find it easier to swap out a ROM routine for a custom version when it's only a matter of removing the ROM label from your include rather than searching through the source looking for (hopefully) commented calls.Ast A. Moore wrote: ↑Mon Apr 30, 2018 2:31 pm In any case, for the most part, this whole argument becomes moot at some point, as people tend to use ROM calls more and more sparingly once their programming skills have improved and they have come up with their own, more efficient routines.
- Ast A. Moore
- Rick Dangerous
- Posts: 2641
- Joined: Mon Nov 13, 2017 3:16 pm
Re: Assembly Language Help
Yeah . . . no. When someone’s at a level of proficiency he needs to use the special addressing mode on a +2A/+3, the last thing he’ll be looking for is a piece of advice on whether to use numeric addresses or name labels. We’re talking beginner stuff here.AndyC wrote: ↑Mon Apr 30, 2018 6:11 pmWell, except when it isn't. Like on the +2A/+3.Ast A. Moore wrote: ↑Mon Apr 30, 2018 2:31 pm It’s extremely easy to see at a glance whether an address is in ROM or RAM—any Spectrum developer knows that RAM starts at address $4000 (16384), so anything below that is a ROM call. Comments will help with the rest. The same applies to system variables.
Theoretically, maybe. In practice, though, if you’re replacing ROM routines with your own, you’re likely to use different parameters, so your whole setup prior to the call will need rewriting.AndyC wrote: ↑Mon Apr 30, 2018 6:11 pmIronically, that's the biggest reason to use labels over comments. Because you're going to use labels when you use your own code (so gain consistency) and will also find it easier to swap out a ROM routine for a custom version when it's only a matter of removing the ROM label from your include rather than searching through the source looking for (hopefully) commented calls.Ast A. Moore wrote: ↑Mon Apr 30, 2018 2:31 pm In any case, for the most part, this whole argument becomes moot at some point, as people tend to use ROM calls more and more sparingly once their programming skills have improved and they have come up with their own, more efficient routines.
Even with ROM calls, you don’t always jump to the beginning of a routine; oftentimes, it’s more efficient to jump somewhere in the middle, and the point of entry might change depending on context. It’s easier and more straighforward to use a numeric address and a comment.
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.
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.
- Einar Saukas
- Bugaboo
- Posts: 3146
- Joined: Wed Nov 15, 2017 2:48 pm
Re: Assembly Language Help
Octals are great for attributes!
- Ast A. Moore
- Rick Dangerous
- Posts: 2641
- Joined: Mon Nov 13, 2017 3:16 pm
Re: Assembly Language Help
True. I just see the entire attribute byte as binary for some reason. Probably out of habit. But, yeah, ignoring Bits 6 and 7, it lends itself to octal numbers very well.
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.
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.
Re: Assembly Language Help
I like to write attributes as binary with spaces, like %01 001 010.
Robin Verhagen-Guest
SevenFFF / Threetwosevensixseven / colonel32
NXtel • NXTP • ESP Update • ESP Reset • CSpect Plugins
SevenFFF / Threetwosevensixseven / colonel32
NXtel • NXTP • ESP Update • ESP Reset • CSpect Plugins
Re: Assembly Language Help
Cool..! Look forward to seeing the final game - looks like it could be a fun arcadey one..
My Speccy site: thirdharmoniser.com