-
Notifications
You must be signed in to change notification settings - Fork 5
code and doc updates #14
Comments
As for documentation, I think the most important things to do are:
About replacing the
Yes. Do you think that there also should be logic to check for the unpermissible situation that both are defined? What about checking for trying to define a CMOS variant with no decimal mode?
That's fine
This is what the real hardware does, at least from what I understand. There is a comment in |
As you're on documentation, I wanted to ask you your opinion on the README. I don't really know what I would suggest, but wanted to see if you see where it falls short? I don't really know much about technical writing. |
Looks like the code changes you're OK with, so I'll do those. The 'void*' pointer - is actually what I would rather do, I just didn't know if you knew about that method, and didn't want to over step with any changes. documentation - I wouldn't say I'm an expert in this area, but I'd like to make it better. And the link you provided (to the changelog project) seams good, if not maybe more than we need. So I'll see what I come up with. |
CHANGELOG.md - do you want that to include a dump of the git log history for fake6502.c? That would give some coverage of the history, and as the project goes forward, better entries can be added. |
I think it would be better for the log history to be higher level. Probably should be much coarser than the commit history, which is easy to find anyway. For example:
this kind of high-level view is better for a changelog than a dump of git's commits, much easier to read and understand |
Yes, agreed - for going forward. I just would include the git log history, to cover the previous edits that this new file/method does not cover. |
I'll see what the pull request is like before I comment further |
ooops accidentally closed it |
A lot of 'lines' changed, as the context accessing changed. But otherwise, no real code/functionality changes. |
Don't merge it in yet, I might have a small update. |
Ideas for the 3rd update:
So it is better 'example' code.
Are you concerned about there being any name clashes with other peoples code, either in their host source, or with another library that they may be using? I tend to prefix all my 'global scope' names with something unique. Like a TLA (three letter abbreviation), eg. JDW_readvalue(). So any names that might be of common usage, have less of a chance of clashing with code from/in other modules. By possible example - in my project, I am looking to also include a Z80 emulator. The one I'm looking at has a global #define A to be some code. That has a very high chance of causing a problem with other source code. Fake6502 also used to have a global 'a', but since you put the 'registers' into a struct, that has help a lot with this type of problem. So - would you be interested in some small prefix (eg. f6_, f6502_) or postfix (eg. _6502) for all the global names? setzero(), setsign() - might be a common name in projects of this nature (CPU based).
a) I prefer to define them in a header file, rather that via the makefile. This would require a couple of changes in fake6502.h, to #include a couple of outside/host provided files. I have tried this and it works well, and gives another (I think small) benefit to the source code/file structure. b) I could adapt the code so that they could be run-time selectable. Again, that may make fake6502 more useful as a library, so the host can choose different CPU configs at run-time. And keep the option of compiling as a single/set CPU type.
'call' - runs the code at address, and returns the Acc. Then restore the CPU back to it's state before the 'run'. 'exec_*' - runs the emulator up to that many clock ticks or instructions. So let me know which ones you'd like to do/see/try - we can do them one at a time, if you like, to see how it works. ps. one more fn(): opcode_replace() that allows the host code to replace an opcode with it's own fn. I do use this for adding in some 'special' options in my project, kind of like being able to simulate some special hardware mod's, like different IO on/at a given address. |
Nifty idea; maybe the unimplemented opcodes should be rigged to call
Yeah I like all your suggestions here. Please can you do one pull request for each one, including your PS. |
Regarding your second bullet point, names like |
I'd be happy with that - just as long as we keep it consistent over everything - defines and macros too? |
Exactly so. Thanks for making this codebase a better one 👍 |
Do you have any thoughts on upper/lower case for fn/macro/define names? eg: function names: all_lowercase() Any guide/preference? |
You've got function names and #defines correct: all_lowercase() and ALLCAPS. I think that macro names should stay looking like functions, for example, |
Agreed. And that was going to be another tweak to the code/api - that the read/write memory functions, could also be implemented as macros by the host code. |
I've done an update to my repo - but didn't do a pull request yet. Can you check the changes in my repo? Then, some more changes before the pull request:
Is that OK so far, and then the 2 additional changes? And I'll need to update the version/Changelog too. |
That's perfect @john-walsh, thanks One point about the opcodes, I am not decided but wanted to throw an idea out. Because (we can assume), we don't need to let client code call |
Let me look at that. |
I'll leave the 'static' opcodes for the next update. Just thinking on 'naming conventions' - which do you prefer:
or:
I prefer the second (object / action). It's a bit more RP (reverse polish notation), but it makes searching for all the 'actions' on an 'object', easier (fake6502_carry_*). |
I think you're right; the second option is better |
I've updated my repo - have a check and let me know. I'd do a pull at this point, if all is OK. |
Yep that looks fine, can you do a pull request |
Next ideas:
Would you rather not have that - I can move them?
we could do this as a compile time option. then declare the opcode fns via a macro, that would be either 'static' or not, depending on the compile time option. so:
would become something like:
or just:
|
|
1 it's more for multi-line style comments (/* */) - they should never be mixed in/on a code line. So it's just a style thing really.
|
|
For the fns (point 3), I'd also like to move the opening brace onto a new line. Is that OK? |
Fine by me 🙂 |
Have a check over these updates. Turned out there was a name conflict, with test.c, when not 'static' - so I had to prefix the fn name's in test.c. |
Huh? you've got a PR for me? |
No PR - I'll update in my repo, then when it's good, do the PR. |
Are you on about commit f7da666? that looks fine to me |
The next updates I think will be the last. But it's going to require something new - so I have a question for you. Do you have any ideas on how to do this: As a source code level library, fake6502 has to both, provide 'stuff' to the host project (I'm thinking of option defines that can be selected), and have the host project provide 'stuff' for it (like the memory accessing fn/macro's). With only a single header file, this creates a chicken/egg situation. ie. both the library and the host project, need to know things from the other, and provide input to/for the other. Have you seen this before, do you have any suggestions? |
I'm not sure how; the library and the host will be compiled separately and then linked together. The |
Yes, as the code stands, it's OK. But as any defines/options get more complex, it would get more involved (like I'm suggesting). I have this in my project (of which fake6502 will be a part) - more complex options at compile time. And one more personal preference - I'd rather have everything needed to compile the source code, in the source code. I'm not keen on the use of '-D' in the makefile. But, that's my preference. I'll try to show you an example. |
so that will require the library (fake6502) including some file that is provided by the host, because the macros need to be known at compile time. What name could we use for that file? I would say it needs to be based on the library name, eg: fake6502.??? |
What is the motive for this? I'm finding it hard to picture a use for it. |
You thought of it - and I agree, it could be an option. But I'm trying to be a bit more theoretical - how do 2 sources, both give a take bits to/from each other? What would that source file structure look like? |
If you know graph theory, the dependency relation between the software components is an acyclic directed graph, roughly meaning the dependency relationship goes only one way.
is trickier to do because, as you've noted, it introduces a circular dependency. The directed graph would no longer be acyclic. So far as I've seen, that's not a kind of relationship we see between (well engineered) software projects |
Yes, I agree with what your saying. I think I'm trying to go beyond the 'norm'. For a 'standard' library that can be integrated at the object level (by the linker), then you are correct. I'm aiming for a source code (compile time) level integration, and that could require info passing both ways - between library and host code. So maybe I'm trying to do too much. Just on the idea of the host providing the compile time 'defines' in a source file (rather than via the makefile -D), I have seen other libraries (one of the z80 ones I looked at, I think?) including a 'glue.h' header file, that the host code is responsible for providing. That gives the host source, so involvement/control over the compilation of the library source. Is that idea OK for you? And what file name would you go for? I like 'libname.opt' - meaning the setting of any options for the library code. Could also be 'libname.inc', 'libname.hh' (host header), ...? So the options available would be documented in/by the library, and provide an example _library.opt file, but it is up to the host to provide the library.opt file - and a new/update of the library would not overwrite the host config/opt file. |
Can you show me the kind of thing you've seen? It sounds like a pain in the rear for not much benefit. But it's of course possible you've seen something I haven't. |
They use 'z80user.h' - and the user can provide macros, so it is interfacing at the compile time level. And 'z80config.h' - for the user to select config options. See the comment at the top of z80emu.h And note the order of inclusion. 'z80config.h' - included first, to set any options. 'z80user.h' - after the z80 library header file, and before the C code, so it has access to defines/types, and can provide macros for the library C fn's. Other than the naming of the files, that is exactly the same solution that I came to for what I am trying to do with fake6502 - in terms of giving the host code more options. NB. it also reminds me of a large project I worked on a long time ago - we had an 'options.h' file, that was used as a central dumping ground for all '#define options' across all source code files. |
I don't think we should do it We need to stay simple and orderly. "Central dumping ground" reeks of Considered Harmful, doesn't it? You're going to have very tight implicit coupling between the software components. And testing just became nearly impossible to do well, especially integration testing.
More options how exactly? Memory access as a preprocessor directive? Again it seems like the wrong solution. Better define it as a function and let the compiler inline it where it sees fit. I'll ask again, am I missing something? |
'options.h' - I wasn't suggesting using that. This just reminded me of that way. By using the 2 include files like z80emu does, it just gives the host a lot more options - you never know what a host may want to do, so I err on the side of giving them all the options I can. fake6502 is very simple, and that may be overkill. So we don't need to go all the way, but I would like to be able to define my 'host project' options in a header file, and there is no way to do that at present. I'd like to add: _fake6502.opt which the host renames to' fake6502.opt', and can put their compile options in there. |
Feel free, but I don't think it'll make its way into omarandlorraine/fake6502 |
OK, I'll leave that for my last update. |
For the next set of changes/updates, here is what I'd like to propose:
documentation
Let me know what you'd like to see, in which (maybe new) files?
Do we want a new file for 'history', or should that be in README.md?
If you'd like to suggest a new file layout, I'll go with that, or I can try to develop it.
FYI: I found that:
git log fake6502.c > fake6502_c.log
produces the complete commit history, so we can use that to automate or get a 'history' file started.
code
structs
That would allow the save/restore of each state, separately (useful fro something I have in mind). It's not essential, but would make for better code later on.
re-instate the 'instructions' counter, again, useful for another change later on.
uint8_t mem[65536] - replace by a pointer: uint8_t *mem
I can see the use for putting the memory space in the context, but it should be by reference (pointer), rather than by allocation.
As a library, it should not be allocating such memory - it is for the host process to do that (IMHO).
And this change would allow 2 hosted CPU's to share the same memory space - if that's what a user wanted.
For my use case, I already have the 64K allocated, so by having the array in the contact, it is forcing another allocation of memory, which is not going to be used.
source code
for the option defines (NMOS6502 and CMOS6502), add a logic check, to ensure that one of them has been defined, else give an error.
move the defines/macros into the header file, so they can be accessed by the host project.
This is something I need to do in my project, as I'm adding some functionality (specific to my project) in my code space, so I need access to them.
I would have thought that it starts at 0xff.
The text was updated successfully, but these errors were encountered: