This page is a mirror of Tepples' nesdev forum mirror (URL TBD).
Last updated on Oct-18-2019 Download

NES Development Tool Project - Would This Be Useful?

NES Development Tool Project - Would This Be Useful?
by on (#163405)
I've started my journey through the K&R2, into the wonderful world of C. My main interest with the language, at this time, is making tools for my game. I had an idea for a first project that I feel would be a great aid in coding, and wondered if others felt similarly, or if there is already available a tool for this purpose. This is my overview for the project:

6502 Assembly Formula Tester – My First C Programming Project
by darryl.revok

The goal of this project is to create a tool to aid in the writing of software programs utilizing the 6502 machine language.

In designing routines, I often spend a lot of time on paper with various examples of data, in order to test formulas. This is time-consuming and prone to errors on edge cases, because it only tests a small number of possibilities. I would like to design a piece of software which will take a series of instructions for 6502 assembly, and perform calculations in the same manner, returning all results with a variety of options. In order to support the type of instructions that would require testing in an actual workflow, the software will need to support all 6502 instructions. It must also allow for an arbitrary number of arguments.

The software should include support for testing various conditions and alerting the user upon errors. Given a piece of code wherein a programmer may want to test 256 input values for an arbitrary number of arguments, with various states of flags, against all other conditions, it would not be practical to read through the output to search for outlying results. In this case, a user should be able to create a test which would flag any inappropriate values. Tests such as {vScrollLo >= 240} would show if the equation produced a value which exceeded the vertical bounds of the screen. It should be possible to test {sameValue[carrySet] != sameValue[carryClear]} to ensure that the carry has been properly considered.

If the user desires to test the output of a function with only one argument, all 256 options could be displayed on the screen easily for more thorough assessment. Two arguments may be reasonable to view in an output file, but any more than that would most likely have little practical use for human examination.

At times, a formula may have a limited number of possible argument values. In an instance where the number input will only range from 0-15, or only multiples of 16, testing all 256 variations for that argument would improperly display error flags. The program needs to be able to specify a series of values for any arguments it will test. It should also be able to specify whether the carry status is clear, set, or unknown when entering the routine.

As my first project, this application will initially be a command-line tool. However, I feel the design of the program would be best suited in a GUI environment, where it could sit side-by-side with a code editor and allow for rapidly pasting code, setting conditions, and debugging routines. If the program gains much use, I would like to consider an extended project of making a simple cross-platform GUI environment for the tool.

The program will be developed as a free-software project for use by anyone for essentially any purpose. I feel that it will be a great tool in helping 6502 programmers write better code, debug faster, and ease the transition into binary math for new programmers. It will also make edge case errors much less likely when any possible data can be tested.
Re: NES Development Tool Project - Would This Be Useful?
by on (#163416)
You should maybe ask yourself, will working on tools for game development speed up that process, or merely distract you from the actually working on your game?

Other than being a Debbie Downer, I have nothing useful to add to this discussion.

Now, get back to work, and I want to see three ideas for level designs on my desk by 5 o'clock, or you're fired buddy. ;)
Re: NES Development Tool Project - Would This Be Useful?
by on (#163417)
This'll basically require writing a 6502 emulator, wouldn't it?

If it's going to be operating on 6502 code that you've already written, seems easier to me to just
assemble it and test it on your favourite NES emulator of choice.
Re: NES Development Tool Project - Would This Be Useful?
by on (#163432)
dougeff wrote:
You should maybe ask yourself, will working on tools for game development speed up that process, or merely distract you from the actually working on your game?


This would pay off the first time I use it. Does nobody else do anything like this:

Image

It might be easy to do some calculations in your head, but doesn't it get cumbersome when you have a complex formula with a lot of steps, and the math doesn't work the same as it does on a calculator?

adam_smasher wrote:
This'll basically require writing a 6502 emulator, wouldn't it?


It wouldn't require writing an NES emulator, so anything involved the graphics or audio hardware need not be included. It would require a function for each calculation that can be performed. It probably wouldn't need a few functions, like RTS or JSR. It wouldn't really need to test the length of a branch command. The idea isn't to test whole routines, just the output of certain arguments, against all possible input conditions.

Quote:
seems easier to me to just
assemble it and test it on your favourite NES emulator of choice.

Running the routine inside of a game isn't going to necessarily test every option, and won't necessarily cause a visible error if a value is returned out of bounds. If you want to improve a routine and want to rapidly test your new routine against your old one, or if you want to test it against a formula which is much easier to write with floating point math, this seems a much more efficient option.

Does anyone else ever deal with edge cases which may hide themselves in the program and not create problems until another set of conditions comes into play?
Re: NES Development Tool Project - Would This Be Useful?
by on (#163453)
I wrote a long thing, then wasn't sure I understood the goals.

So... once I wrote a test program to test if the famous reverse subtract set the carry the same as subtracting the two variables normally. I used 6502 Macro Assembler.

With one way I've interpreted your post, you're offering me a thing where I can do something like...
Code:
if(
  carry:(
    lda #XX,sec,sbc #YY
  )
    !=
  carry:(
    lda #YY,eor #$FF,sec,adc #XX
  )
){
    return false;
}

It will run through all possible values for XX and YY and tell me if the carry was ever different between those two things. The above is the only thing that comes to mind that I've done that I could have used something like that for. And it only would have saved the time of writing the loops that change the values myself. It'd have taken (significantly) more time to construct your program than write the tests I could have used it for. I'd venture to say just writing something that interprets the text given to it would take longer than even writing an individual test in C.

So with this interpretation, I'm sure some would find it helpful but it's not a huge time saver overall. Still, it's not a bad programming project just to learn. Writing a text parser is good practice.

Or, rather than something that runs through things for you, you're talking about making something that just lets you write quick tests yourself. In which case that exists in 6502 macro assembler.

Here's the test mentioned above:
Code:
temp1 = $00
temp2 = $01
result = $02
sign = $03
   
   .org $8000
   
   LDA #$00
   STA temp1
   STA temp2
loop:
   LDA temp1
   SEC
   SBC temp2
   STA result
   
   ROR
   AND #@10000000;Macro assembler uses #@ instead of #%.
   STA sign
   
   LDA temp2
   
   EOR #$FF
   SEC
   ADC temp1
   
   PHA
   
   ROR
   AND #@10000000
   CMP sign
   BNE fail
   
   pla
   CMP result
   BNE fail
   
   
   
   INC temp1
   BNE loop
   INC temp2
   BNE loop
success:
   jmp success
   
   
fail
   jmp fail

I typed it, I pressed F7 (Assemble), F6(Debugger), F5(Run), ctrl+break and it showed the arrow on the jmp result.

Actually, I think you could totally write a test suite in straight 6502 to do this sort of thing. Like... to compare two functions, the program would jsr to one, store its state, then jsr to the other, and compare to the state of the first. I don't think it'd save time, but it might be fun to write.
Quote:
Does anyone else ever deal with edge cases which may hide themselves in the program and not create problems until another set of conditions comes into play?

Well sure. That's programming. The thing about this is... what if you have edge cases in this program meant to detect edge cases that don't cause problems until a certain set of conditions comes into play?
Re: NES Development Tool Project - Would This Be Useful?
by on (#163458)
Honestly, I think this is too much trouble for so little benefit, and your time would be better spent on making an actual game rather than obsessing over making every little piece of 6502 assembly perfect. Bugs are an inherent part of software development, and there's no such thing as a bug-free game. If your game ends up glitching under an uncommon edge case that wasn't detected during beta testing, congratulations, your game is exactly like 100% of the best games ever made. Luckily someone will make an interesting video about exploiting these bugs and give your game some extra publicity.

Like Kasumi, when I want to test an algorithm, I use the 6502 simulator. If it's something simple, I manually test a few hand-picked set of inputs and call it a day. If there are bugs I'm sure they'll manifest themselves sooner or later when the code is implemented into the game. If it's something more complicated, I log the results and compare them to results generated by a high-level language program. I did this recently for a signed multiplication algorithm (which worked but I ended up not using), but it's really rare for me to get to this point.
Re: NES Development Tool Project - Would This Be Useful?
by on (#163464)
This sounds like a project to create a 6502 simulator specialized toward test-driven development. I made one of those long ago to test a math library.
Re: NES Development Tool Project - Would This Be Useful?
by on (#163467)
Cc65 also ships with a simple 6502 simulator (sim65) that could be used for testing purposes. It can be set as a target for linking and it supports basic I/O operations (open, close, read, write). That includes being able to read/write from/to stdin/stdout and of course files. You can access the functions from assembly or C (they're just magic addresses in the simulator). From C you can even use stuff like printf() so it should be fairly simple to use it to make a test harness.
Re: NES Development Tool Project - Would This Be Useful?
by on (#163479)
My approach to edge cases, bugs, regressions and such is to just use source control, and track as many fine-grained changes as possible. When something breaks, git bisect can help me find which lines of code caused the bug in just a few minutes. I didn't actually track the # of bugs that came up during my first project, but my current one is up to 401 (found and fixed bugs). That's pretty much dwarfed by every professional piece of software I've ever worked on (which usually have bugs in the thousands).

I agree with much of the sentiment above, it is nearly impossible to anticipate every edge case. The reason is that as the amount of state you're managing in a program increases, the number of combinations of every piece of data becomes exponentially huge. Even the best test case suite can't find all possible bugs. I've sometimes thought about what it would take to create unit tests for an NES game, but I can't be bothered...source control has been more than enough help in this case. Make me wonder how developers in the 80's and 90's managed their source code....

In terms of prototyping algorithms and such, I use a combination of pseudo code and that old 6502 simulator for windows when I need it.

I do think writing tools for oneself can help speed up the development of a game, though, once they are written! I usually stick to immediately practical things like level editors, for that. Those usually have such custom needs that it makes sense to write them yourself, though I'm sure some folks have successfully re-purposed a generic level editor for NES dev.
Re: NES Development Tool Project - Would This Be Useful?
by on (#163491)
Another thing I do is design a lot of algorithms using only pen and paper. I'm actually more productive that way than when I'm in front of the computer, because there aren't any distractions. Sometimes I feel like I could code an entire game that way! Anyway, when I do that, I often make optimizations, rewriting the code a few times, and debug the code in my head. Most of the time, code I write like that works on the first try, unlike code I write directly on the PC.
Re: NES Development Tool Project - Would This Be Useful?
by on (#163538)
Thank you for all of the thoughtful opinions!

Kasumi wrote:
Still, it's not a bad programming project just to learn. Writing a text parser is good practice.

I maybe should have iterated that the main reason I had this idea was thinking of an easy project I could do as I go through the book, which would be something relevant to me and the project at hand. I feel that would help me commit things to memory and serve as inspiration to learn faster. A level editor is really my main goal with C at this time, but I felt that was too big of a project to begin with. As I was working through the book and working with things like getchar and functions, I tried to think of something I could do which would be basic and useful.

I guess to really sit down and think about it, it would be easier to program a test directly into 6502. I guess maybe there's not much purpose to this other than for learning. But it would be nice if I could make something that will be useful for my game development while learning.

I'm trying to consider how it might affect the writing process. The idea was first, basically a very small 6502 simulator to calculate the math used by the system.

So, this is how I've been doing things. If I need to solve a problem and I'm not sure how, maybe I'll consider it with conventional math first on paper, or maybe I'll break it up into 6502 steps in my head, it depends on the situation. In either case, this part of the process wouldn't change. You'd need to have an idea of how to write 6502 ASM to solve your problem. But the next step is where the idea would come into play.

tokumaru wrote:
If it's something simple, I manually test a few hand-picked set of inputs and call it a day.

This is what I've been doing, and generally you can know where your edge cases are going to be. I usually test a high limit and a low limit, and then a middle number. That's usually enough. Now, I'd been doing this by hand on paper, and that's a lot of what was in the picture I posted. (that's just for one routine though. I've got a stack I've kept in case there's something useful on one of them) I first thought, "I could use this C to write a program which would calculate the result like a 6502 without me having to manually going through and write it all out". Writing it out was probably good practice for understanding the binary math though.

It sounds from what you guys are saying though, that there are already options available for this. The only 6502 simulator of which I was previously aware was this one: http://skilldrick.github.io/easy6502/. It would work if your result ended up in one of the registers but I don't know how it functions with values in memory.
thefox wrote:
Cc65 also ships with a simple 6502 simulator (sim65) that could be used for testing purposes.

I haven't transitioned my game to CA65 yet but I've managed to successfully compile CC65 (in mac OS, even) which is a big step for me. Anything that needed compiling previously was outside of my skill level. I've found a doc for the command line version, and as for the idea of a cross-platform GUI, I found this: http://www.wsxyz.net/sim65/. So it seems that the bulk of what the project would contribute already exists.

I don't know about you guys, but I get a backlog of programs I want to try and transitions I want to make to my workflow. CC65 and Git are the two things on that backlog that I've started on. When I'm in the middle of making progress to my game, I don't like to stop and do a low level relearning until I hit a slow point. Luckily I've got someone willing to mentor me in C now and I'm wanting to take advantage of that.

So, the project would be a learning project, but if it goes into things that are, a) outside of the path of learning C fundamentals, and b) not producing tangible gain for my game development, then it is ultimately a time-sucker.

GradualGames wrote:
When something breaks, git bisect can help me find which lines of code caused the bug in just a few minutes.

I definitely want to learn more about this soon. So far I've made a commit of my project, and in doing so, realized how messy the project files have become. Right now I'm planning to learn some C, then structure my program for CA65, then learn Git. Hopefully this is a solid plan of action for making progress.

tokumaru wrote:
Honestly, I think this is too much trouble for so little benefit, and your time would be better spent on making an actual game rather than obsessing over making every little piece of 6502 assembly perfect.

That's an easy trap to fall in, but I don't want it to be about that. It kind of happened as a side-effect that the idea would work really well for revisions, but the thought was to cut down on writing time. I'm sure this varies for everybody, especially with experience, but it often takes me a long time to figure out how to do something at all, let alone efficiently. That part usually takes a lot longer than revision actually, because I usually come back and do revision later after I've got more experience and have seen more of the picture. I, also, will often think about code when I'm away from the computer, when I'm in the shower, driving on a country road, performing licensed surgery (just kidding on the last one, I'm not licensed) Honestly if I get really stuck on something a lot of times the best move I can do is go to bed and in the morning the answer is really obvious.

But the thought was to have something that could help with the initial writing. The 6502 simulator does a lot of that. I think in most instances though, somebody could write out the answer more easily in C code. From thefox's suggestions, I could do this and then test against ASM code with sim65 and cc65. After I did this once, I could save it as a template and drop in new ASM and write a new test equation. The savings versus having a standalone application are pretty insignificant. Seems like it would probably take me away from right path. I did write out a couple opcodes as functions in C before I even had this idea, as practice while I was doing the first chapter. I suppose that was enough.

I will though, try some of the suggestions about using a 6502 simulator, and maybe even trying it against C code in the future, when it seems applicable. That beats going through the code line by line in my head and on paper, shifting bits and tracking carries. I think there's part of the initial writing that only works that way, really, or you have nothing to test. I'm talking about the point at which you say, "I think I've got it and I'm not sure" or you want to know "how far off am I?". So far I've answered the first one by running my game and encountering the situation I'm coding, and answered the second one by watching a value in memory in Nintendulator DX.

Kasumi wrote:
Well sure. That's programming. The thing about this is... what if you have edge cases in this program meant to detect edge cases that don't cause problems until a certain set of conditions comes into play?

That's so meta. I suppose I'll have to write a program to test C code against all variables of the universe. :)