So I began working on z80 assembly a while ago, and failed. This time, I'm going to do it right. This is my questions/learning thread (which will be cross-posted to the other sites).

My setup:
Assembler: spasm-ng
Editor: Notepad++
Tutorial: http://media.taricorp.net/83pa28d/lesson/toc.html
Plans: I'm going to write a small game I call "World of Code." It will probably just end up being an RPG movement engine and end up stalling, knowing myself. If it turns into a thing, I'll post about it.
SPASM is certainly a great tool to use, but have you given the Doors CS SDK and Brass a try? Everything is set up for you, and you don't have to worry about getting any directory structure in order. Of course, if you're planning to work with ez80, you'll have to indeed stick with SPASM-ng. I'm not sure why you would cross-post a thread away from the primary z80 ASM programming site in the community, but I suppose that's your prerogative. Wink Anyway, let's have those questions!
While I am a fan of SDKs, I like using small tools when I can, so I don't have to download more than a few MBs of stuff (my computer's internet connection sucks, due to throttling by my dad). As for the cross-posting, it's because I have been trying to advocate cross posting since December, and should practice what I preach, so to speak Wink
Sounds like a plan! Speaking of plans, I like that you have a goal in mind of something that you want to make, but I also hope you'll consider making smaller, easier programs while you learn. I'm sure you've seen as well as I have how new programmers of any language can get frustrated if they try to start with a project that is too large. Smile Also, what emulator + debugger do you plan to use? I don't recommend solely using a real calculator for beginning ASM, since it's so much easier to debug when you can examine memory, single-step programs, and set breakpoints and watchpoints
I knew I was forgetting something!

I'm using Wabbitemu because I can run it in the batch file I have mapped to ctrl + F7 with Notepad++ along with the spasm command.

As for projects, I'm just doing a movement engine for the time being as my first "goal," but all the programs in 28 days and any variants I can think of will serve my purposes nicely.

Now my first question (and this is a convention question): I love macros a lot. Is it considered bad practice to have several different macros at the start of your program for two/three line things that are really common, such as multiplication or division?
Oh, of course! I use macros a lot to do some things, such as printing text and combining high and low bytes, and many other things. I think this makes the code a lot more humanly readable. You may also want to take a look at the Funk Library by Nano too. Smile

EDIT: Oh, and I usually just put them in a separate file rather than at the start, and then just include it. That way I don't have to have excess "stuff" near the top.
Btw, add and i have been going through a simple tilemap/movement engine together as a sort of introduction into the concepts behind game programming. You can see the code in its various states here:
https://github.com/RevolutionSoftware/famwars

The idea is to eventually use that to write a tutorial on game programming concepts for the z80. I've tried to document it well, but that part is still a WIP. Feel free to look through that and ask questions, though you missed out on all the explanations i gave to add over Skype (and me forcing them to write many of the routines. Well, with some guidance). I'd be happy to help you out, too.

So far, some stuff we've gotten done:
1. Basic tilemap (not smooth scrolling)
2. Aligned sprite routine for use with the tilemap
3. Scrolling of the map
4. Filled rectangle routine (black border with white fill)
5. Simple menus
6. Scrollable menus (with items that don't all fit on screen)
7. Oh yeah, and the cursor, don't feel like changing all the other numbers so i'll put it here Wink

Things we'll be working on next include building and moving units, so there will be lots of tables and other fun stuff going on, including using ix with an offset to access unit data.
Thanks for that! After I make my own, I'll compare and see how well I did.

So I made a macro for 16 bit subtraction and one for resetting carry (because two lines is annoying Razz)

That said, I was looking at the wikiti multiplication routines, and they work, but I can't work them into a macro. Can I put calls in .inc files, or do I have to put them in my source?
pimathbrainiac wrote:
hat said, I was looking at the wikiti multiplication routines, and they work, but I can't work them into a macro. Can I put calls in .inc files, or do I have to put them in my source?

Oh, I'm sure that that would work just fine too. I'm somewhat surprised that you can't do macros with it though...if it has a jp, you could probably just get by with replacing it with a jr and then jumping the correct number of bytes as well. Smile
Well, there's a djnz to a label at the beginning of the loop. The problem comes from the label Eh, I'll just use them as calls in the main source for now.

another question: Can you have different labels with the same name in different calls, and jr still work right?

example:


Code:
mult_h_e:       ;stores in hl
    ld   l, 0
    ld   d, l
   
    sla   h      ; optimised 1st iteration
    jr   nc, $+3
    ld   l, e
   
    ld b, 7
_loop:
    add   hl, hl         
    jr   nc, $+3
    add   hl, de
   
    djnz   _loop
   
    ret

mult_a_de:      ;stores in ahl
    ld   c, 0
    ld   h, c
    ld   l, h
   
    add   a, a    ; optimised 1st iteration
    jr   nc, $+4
    ld   h,d
    ld   l,e
   
    ld b, 7
_loop:
    add   hl, hl
    rla
    jr   nc, $+4
    add   hl, de
    adc   a, c

    djnz   _loop
   
    ret
pimathbrainiac wrote:
Well, there's a djnz to a label at the beginning of the loop. The problem comes from the label Eh, I'll just use them as calls in the main source for now.

another question: Can you have different labels with the same name in different calls, and jr still work right?

Yes, using a call is definitely preferred in this case. Macros are usually just to set thing up easier. As for your second question, the answer is no. Labels are just memory addresses, and have no relation to being specific to any degree. You would need a different name. Razz Try to get into the mindset that they are not really labels, as this will make things easier when you get to SMC and other topics. Hope this helps! Smile
To add to the topic of labels, some assemblers like Brass have anonymous reusable labels with special syntax.

Code:

DoUselsesThing:
  ld b,3
-:
  djnz {-} ;Go back to the first '-' label above this line
  ret


There are other variations on this included in Brass like '@', '+', and using different amounts of +/- in the label name. It'd be better for you to refer to the Brass documentation than for me to try to explain them all here if you're interested.

I could've sworn that SPASM had something like this too, but I couldn't find any documentation on it. Maybe someone more familiar with it could tell us.
Spasm has that, too. It's an underscore:

Code:
   jr +_
;...some code
_:
To jump backwards, use the - sign:

Code:
_
;...some code
   djnz -_
You can also jump forward or backwards multiple _'s:

Code:
_  nop
_  nop
    djnz -_
   ld b,c
    djnz --_
Also, putting something like a multiplication routine as a macro doesn't make much sense, it'll add unnecessary code every time you multiply. As Mateo said, copy the routine into your program and call it whenever you want to multiply. If you want, you can make a macro to call the multiplication routine.

And labels are only for the assembler, they are really just pointers to addresses in your code. They have no range/scope like a C function might, ie. there is no start and end of the label. So if two parts of your code have the same label, then two different addresses have the same name. The assembler won't know which one you want to use. I think Brass has some stuff to limit labels/declarations within a certain scope, i dunno. I just give everything a unique name.

Your code starts at the top and runs to the bottom, regardless of how many labels you put in between. The only thing that will break that are branch instructions and other clever ways of changing the value of the pc register (eg. pushing an address onto the stack and ret'ing).
pimathbrainiac wrote:

So I made a macro for 16 bit subtraction and one for resetting carry (because two lines is annoying Razz)


A bit late, but I just read this and couldn't resist commenting: You don't need two lines to reset carry. "or a" will do the trick Wink
Yeah, almost everyone uses "or a" to reset the carry. It either means cp 0 or reset the carry (or both). Though it'll affect the sign and Z flags, too. Generally it won't be an issue though.
And I always though, well, if "scf" stands for "set carry flag", then "ccf" must stand for "clear carry flag", right? Took me a long time to figure out that one Wink
Thanks for reminding me to continue this. I've been really... busy... recently. I'll get some more questions in in a bit (hopefully).
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
Page 1 of 1
» All times are UTC - 5 Hours
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Advertisement