| |
Stablizer
Registered: Jan 2016 Posts: 19 |
Coding on a PC for the 64?
I've seen various editors out there, currently starting to use the C64Studio for this, but it seems like getting charsets, graphics, music, etc, is a bit problematic when going at it this way, isn't it?
Would love to get some pointers to reading material on the subject (have done some searches already, but haven't come up with anything notable really).
Thanks!
-Stab |
|
| |
TheRyk
Registered: Mar 2009 Posts: 2244 |
Can't really imagine, why including gfx/music data should be harder on C64studio than in other environments. You create those data with gfx editors or SID trackers and then include them as binaries, *shrug*
But there's a bunch beside the Studio, e.g. I started with Relaunch ages ago and then turned to Notepad++. Both offer syntax highlighting and determining various compilers/emulators.
Guess, it's a matter of taste in the end, same is true for question which crossassembler to use. I've always used ACME, but KickAss is also still popular.
Can't really tell you what to read, just try out and decide what works best for you. |
| |
Endurion
Registered: Mar 2007 Posts: 73 |
Can you imagine a better way than it currently is in C64 Studio? I'm always looking for ways to improve it.
Maybe the !media pseudo op is what you're looking for? The "old" method would be to manually export from charset/sprite/whatever to a binary file and include that.
With !media you can include the data from the charset/sprite project directly. |
| |
Bitbreaker
Registered: Oct 2002 Posts: 508 |
Charset, gfx and music are handled as binary please. A few exceptions can be made if it is simple stuff like a few single chars or sprites, then one could also think of defining them within the source code via:
* = $2800
mycharset
!byte %01110000
!byte %01001000
!byte %01110000
...
One can then easily include the binaries like:
* = $1000
!bin "mymusic.prg",,2
* = $2000
!bin "mykoala.kla"
,,2 is used, to strip of the load address from the binary
Also, acme + vi + syntax highlighting + make or GTFO :-D |
| |
Burglar
Registered: Dec 2004 Posts: 1101 |
http://codebase64.org/doku.php?id=base:crossdev |
| |
chatGPZ
Registered: Dec 2001 Posts: 11386 |
Quote:Charset, gfx and music are handled as binary please.
this |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
kickass can import quite transparantly without having to fuck with binary bullshit. (saying this as a 64tass guy) |
| |
TheRyk
Registered: Mar 2009 Posts: 2244 |
using that "binary bullshit" is part of coding 65xx assembler imho as it forces you to learn about memory mapping which you sooner or later want/need anyway, e.g. when you need to split a prefigured gfx file format such as .kla into bitmap/colram/screen data or wanna cut off unneeded charset data |
| |
Stablizer
Registered: Jan 2016 Posts: 19 |
I agree with Ryk, I'd rather have the memory management be explicit. |
| |
Stablizer
Registered: Jan 2016 Posts: 19 |
Endurion - is there a manual or help files for C64Studio? Something that shows the opcodes, .byte statements, example stuff? I get lots of compile errors that seem more tool based than source based, which is probably common for folks just starting to use the tool.
It would be great to have the opcodes clearly spelled out in a doc or something. I am sure there's already one out there, but I haven't really gone looking yet. |
| |
Stablizer
Registered: Jan 2016 Posts: 19 |
Actually I found the following, which was helpful in telling me that my .BYTE and .TEXT statements needed to be !BYTE and !TEXT. Now things are working better.
http://www.programmermind.com/C64Studio.html |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
Quote: using that "binary bullshit" is part of coding 65xx assembler imho as it forces you to learn about memory mapping which you sooner or later want/need anyway, e.g. when you need to split a prefigured gfx file format such as .kla into bitmap/colram/screen data or wanna cut off unneeded charset data
this has nothing to do with memory mapping, its how much you fuck to get the data you want
kickass will do that .kla split for you in 1 line. with other assemblers you have to fuck with some other tool to get the damned thing sliced up.
kickass will import for you koala from pc formats, or sprites, or music from a .sid. |
| |
Endurion
Registered: Mar 2007 Posts: 73 |
There is a help available (default F1). Pressing F1 while on an opcode shows info on it.
At the bottom of the help start page is a link to AAY, a very neat compendium of the C64s Kernal and VIC/SID registers.
Also note, when you're using a solution you can set the assembler type to a different one (DASM, PDS syntax) in the properties (right-click in Solution Explorer) |
| |
Bitbreaker
Registered: Oct 2002 Posts: 508 |
Quote: this has nothing to do with memory mapping, its how much you fuck to get the data you want
kickass will do that .kla split for you in 1 line. with other assemblers you have to fuck with some other tool to get the damned thing sliced up.
kickass will import for you koala from pc formats, or sprites, or music from a .sid.
Wrong.
* = koala_bitmap
!bin "pic.kla",$1f40,2
* = koala_screen
!bin "pic.kla",$3e8,$1f42
Looks pretty clear to me. No manual splitting needed. |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
indeed, anyhow I seriously think about using kickass even if just for prechewing gfx data. it can solve about any task, not just this split thing. |
| |
Axis/Oxyron Account closed
Registered: Apr 2007 Posts: 91 |
I always tend to use the most simple and slim solution. In my case Notepad++, DreamAss, Subversion and some self-made scripts for Notepad++ to build and execute via hotkey. Thats not as luxurious as some duper-duper studio whatever solution. But, when I run into trouble, theres always a 5 minute way to fix it. And thats worth alot, because you always run into trouble someday. Most likely the day of your deadline. |
| |
Monte Carlos
Registered: Jun 2004 Posts: 359 |
I'm currently using Codeblocks http://www.codeblocks.org/.
If interested, i could send you the hilighters and output parsing configuration. |
| |
chatGPZ
Registered: Dec 2001 Posts: 11386 |
Quote:it can solve about any task
if only |
| |
Perplex
Registered: Feb 2009 Posts: 255 |
I prefer many small tools that do one thing each and do it well, and that can be combined in a limitless number of ways that even the authors themselves never thought about. |
| |
chatGPZ
Registered: Dec 2001 Posts: 11386 |
indeed |
| |
Stablizer
Registered: Jan 2016 Posts: 19 |
agreed |
| |
T.M.R Account closed
Registered: Dec 2001 Posts: 749 |
Quoting PerplexI prefer many small tools that do one thing each and do it well, and that can be combined in a limitless number of ways that even the authors themselves never thought about.
What he said. |
| |
Fungus
Registered: Sep 2002 Posts: 686 |
Same with dedicated small tools that do things right rather than some integrated IDE that does everything but nothing well.
NP++, tass64 w/syntax highlighting, batch scripts, and other small tools like exo and CC1541 for me. |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
fungus is my cross-ass bro! |
| |
Count Zero
Registered: Jan 2003 Posts: 1932 |
Quote: http://codebase64.org/doku.php?id=base:crossdev
batchfiles?
Burglar provided this excellent article http://codebase64.org/doku.php?id=base:cross_development_using_.. and is just too modest to stick your nose right at it :)
PS: I am using sublime 3 and whatever assembler is required. Mostly Dreamass and ACME - very rarely kickass. |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
I dont understand that make tut.
# our implicit build rule
%.prg: %.s
java -jar /usr/share/java/KickAss.jar $< -o $@
# default build target
all: intro.prg
so how does make know that intro.prg should be fed into the implicit rule? how does it even know its an implicit rule ? |
| |
T.M.R Account closed
Registered: Dec 2001 Posts: 749 |
Using ACME with Crimson Editor here, the latter can call the former directly from it's user-configured tools menu or with control/1 so i don't need batch scripts for the majority of jobs. |
| |
soci
Registered: Sep 2003 Posts: 480 |
No idea what's this fuss about using graphics, and music in productions.
At minimum you need to be familiar with the "data" you're trying to "import". Unless you're favouring black boxes instead of learning something.
Common formats are well documented all over the Internet, so there's no need to disassemble utility programs to gain knowledge of save formats, or display code.
Most common assemblers can split out parts of binaries just fine. Figure out once, then copy it forever. This also applies for display code and other reusable stuff.
Converters were around for a while too. And seriously, would I want to write a special case one-off converter scripted in assembler while I have access to general purpose languages with tons of libraries?
Well, probably some operating systems are rather unfriendly in this regard in their default install, but that's usually easy to fix. Still wondering why one would want an emulator launching capability in an assembler for example ;)
IDEs. Well, it probably makes sense for huge projects for cross referencing and refactoring reasons, like stuff written in java for example.
For 6502 code? A fast text editor with syntax highlighting, auto indent and quick searching is usually enough. I tried to love cross referencing but mostly I don't have the need for that. Possibly I need a bigger mess in my sources like reusing the same random 2 character label in different scopes all over the place ;)
This thread goes into the weapons of choice direction. So for me:
* Vim. With a rather complex syntax highlighting for expression syntax checking. Also with custom on-the-fly source reformatting ala C64 tass/tasm. And it's nice for comparing changes, merging, folding, auto completion, quick jumping around, split editing etc, etc.
* C/Python for any sort of non-trivial conversion or generation.
* vbindiff for hex-editing, c1541 for image files. VICE. cat, dd, bash, whatever.
* Make for incremental building, svn for version control. Exomizer/pucrunch for compression (space/speed).
* Did mostly one filers for the last 10 years, but for the few older trackmos I used home grown loader/disk layouter.
* Coded tons of (unreleased) converters over the years. Also several disassemblers, picture rippers, optimizers, etc. View64 for quick checking of the result.
* Surprisingly I eat my own dog-food, so I use 64tass. By now it does most of the things I've only wished for years before.
* I use IDEDOS and PClink for quick testing on the real thing. Which is either a C64C or a C128DCR.
Where's all the stuff then? Unfortunately not all of it is tightly scene related, therefore not here. |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
"would I want to write a special case one-off converter scripted in assembler" -> " Figure out once, then copy it forever." applies here too, I guees, and no need to install yet another compiler ide, and its all compact in the source. |
| |
soci
Registered: Sep 2003 Posts: 480 |
Conversion in the same file as the asm source, uh. It converts stuff every time, even if just tweaking the code.
Almost as bad as having pictures/music/font embedded in source as byte lines...
Wondering which assembler will get base64 or uudecoding first to optimize this use case ;) |
| |
soci
Registered: Sep 2003 Posts: 480 |
"yet another compiler ide".
Right. If you mean stuff like VS, then it grew so much over the years that it might be more space efficient to install a complete operating system with a compiler and editor instead ;) |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
doesnt need to be in the same source, its your implication :) I think it might be better than writing your own converter for yet another special demo gfx format. fex I still dont have a tool for command line sprite conversion, anyone know one good ? :)
but wait even if its in the same source, there's not much difference (except if convert takes a long time) compared to binary include... source changes, source gets compiled right ? |
| |
soci
Registered: Sep 2003 Posts: 480 |
"its all compact in the [asm] source", at least that's how I understood.
There's not much difference if you have a fast machine, the conversion is simple or you're patient. But there was a reason why I optimized the start-up time of VICE many years ago. (e.g. lazy calculation of SID filter parameters)
Those sprite and bitmap conversions I hand craft usually. It's always different because of the arrangement, so I didn't bother to write a general tool for that.
For hires sprites there's a silly trick to create a 24x21 1bit binary pbm image which becames a 63 byte sprite by applying "tail -n +4" on it.
By the way I forgot to recommend "netpbm" for those who like the limitless combination possibilities of small utilities.
It's a collection of command line image conversion and manipulation tools. Using them in the right combination can split out and convert those 1 bit sprite sized pbm images from a bigger image file. With the right parameters, some piping, shell scripting and a bit of creativity of course ;)
The binary pnm format is also very easy to parse in conversion utilities. |
| |
soci
Registered: Sep 2003 Posts: 480 |
Quote: I dont understand that make tut.
# our implicit build rule
%.prg: %.s
java -jar /usr/share/java/KickAss.jar $< -o $@
# default build target
all: intro.prg
so how does make know that intro.prg should be fed into the implicit rule? how does it even know its an implicit rule ?
The name is matching the %.prg pattern, and the rule is translated to:
intro.prg: intro.s
It's easier to write and understand explicit rules. |
| |
chatGPZ
Registered: Dec 2001 Posts: 11386 |
moving the silly inline conversion shit done in kickass to external tools speeded up build times for artphosis by at least a factor of 10.... huge difference. getting rid of kickass and using something non java again boosted the speed by atleast a factor of 5 for crowdpleaser. (and this isnt on a slow pc at all)
as for custom used-once demo-specific formats... i'll just knock up a small c program. because speed. because make. and because chances are its not so custom afterall :)
and at the end of the day, its what axis said - thats also why i dont like kickass or anything else closed source when it comes to tools. |
| |
chatGPZ
Registered: Dec 2001 Posts: 11386 |
Quote:It's easier to write and understand explicit rules.
also more useful for C64 stuff, IMHO. YMMV :) |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
"its all compact in the [asm] source",
point there. |
| |
Bitbreaker
Registered: Oct 2002 Posts: 508 |
Quote: "its all compact in the [asm] source",
point there.
resulting in zero portability ;_; |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
zero portabiity of what? in the first hand nothing is unportable, just the invested effort changes. |
| |
iAN CooG
Registered: May 2002 Posts: 3193 |
ok please make a port of half life to c64, source is out there. Urgent. |
| |
Snabel
Registered: Aug 2015 Posts: 24 |
Quote: ok please make a port of half life to c64, source is out there. Urgent.
...will definitely need REU :) |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
Quote: ok please make a port of half life to c64, source is out there. Urgent.
doom is already out there, have you ever tought it will be ? |
| |
4mat
Registered: May 2010 Posts: 66 |
I use Notepad++, couple of batch files and Dasm. (the version Ian did with extensions) Apart from Cuneiform for chars I usually write my own conversion tools in Blitz Basic, it's super quick to make visual tools with. XVI32 is good if you need to prune exported files to a particular size (eg : cart image blocks) as it has it's own scripting language built in. |
| |
chatGPZ
Registered: Dec 2001 Posts: 11386 |
Quote:doom is already out there
if only |
| |
TheRyk
Registered: Mar 2009 Posts: 2244 |
doom is near \o/ |
| |
Moloch
Registered: Jan 2002 Posts: 2928 |
23-27% |
| |
iAN CooG
Registered: May 2002 Posts: 3193 |
full of lda and sta usage |
| |
Fungus
Registered: Sep 2002 Posts: 686 |
that degenerated quickly
tass64 is open source, it's a console app and it's written in C. How is it not portable? It doesn't compile on your "insert system here" ? Fork it.
If what groepaz says is true, then I would never use kickass if it took more than 1 second to compile anything on a modern machine. Sacrificing speed for portability is nonsense imo. |
| |
Karmic
Registered: Apr 2015 Posts: 66 |
+1 Fungus |
| |
Bob
Registered: Nov 2002 Posts: 71 |
We in Censor uses CRT's home brewed assembler c6510
it is a C coded assembler built for fast turnaround & speed,
using notepad++ and we have for windows bat files or linux /mac also shell scripts..
platform independent ish Win,Linux,Mac
it has support for most of the stuff that we need.
lua, sq we can get for example print out to the console screen when source is being compiled, a good use if you print memory location (I use it allot) where a function start and end, in that way I have complete overview of every chunk or binaries or the code etc.. (lua scripts)
zp address space etc...
generate tables via lua or sq ... mostly used for sinus, but all sort of generation of unrolled code ...
It have worked flawlessly since day one ;)
and there is a first line support if there would be any issues. ;)
the only known quirk is there is no relative jump as *-3
everything req a label name. but you can have sub label names etc..
example
mainLabel:
.subLabel:
etc..
I think CRT was planning to release the c6510, bcoz its really good and easy to use... |
| |
Smasher
Registered: Feb 2003 Posts: 520 |
/me wants!
:) |
| |
mankeli
Registered: Oct 2010 Posts: 146 |
Bob:
So c6510 is an assembler with LUA as the macro language? That's cool. Can you post a syntax example?
I have made a custom assembler as well. All existing assemblers seem have their own custom, awful, half-assed macro languages.
So my assembler uses C++ as it's macro language, because it's actually a library+macro collection that implements a 6502 assembler. Works fine for me(tm), but it's annoying to set up because it requires a modern C++11 compiler, and the API is not completely stable yet. The syntax is also quite "unorthodox". Code example: https://github.com/mankeli/hashembler/blob/master/examples/side..
Although Hashembler works OK, and was used to create the Aerial Core demo for example, it would be nice to be able to use a product that's a bit less hacky and has more traditional syntax. :-) |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
you could translate normal syntax to hashembler format for easyer editing in an inbetween step |
| |
Slammer
Registered: Feb 2004 Posts: 416 |
Bob: Sounds interesting. I look forward to see what you guys have made. I understand the choise of a functional language. The absence of side effects eases the task of implementing the assembler and make things so much easier seen from an implementers point of view.
Mankeli: Thanks for sharing. Always good to see a diffrent appproach on things. |
| |
Fungus
Registered: Sep 2002 Posts: 686 |
Sounds neat Bob. Do want. |
| |
Martin Piper
Registered: Nov 2007 Posts: 722 |
I tend to use a modified version of ACME with remote debugging via VICE monitor and full source code stepping. I also use BDD for reproducible test cases.
All available on my github. |
| |
Bob
Registered: Nov 2002 Posts: 71 |
sorry been offline ;) ish... yes I will try to sample some stuff. |
| |
ChristopherJam
Registered: Aug 2004 Posts: 1409 |
FWIW I'm still using pulling binaries into c64 executables using the cbmcombine utility that came with pucrunch, even though I've switched to nucrunch for my compression needs.
Still assembling with xa, (though I'm tinkering with moving to KickAss), and doing most of my format conversions/dataprep in Python+numpy, though I've recently switched from C to Rust for anything that needs extra speed.
Speaking of, Rust's pretty awesome for getting c-like speed with high level lists and hashmaps, and all without any risk of memory corruption or leaks. Definitely worth checking out. |
| |
ChristopherJam
Registered: Aug 2004 Posts: 1409 |
Oh, and of course gvim for text editing, VICE and an rr-net/retroreplay equipt c64 for testing, and Mac OS X to host the whole shebang on my Retina 13" laptop. |
| |
Peacemaker
Registered: Sep 2004 Posts: 275 |
kickass and notepad++, greets to groepaz =) |
| |
algorithm
Registered: May 2002 Posts: 705 |
acme and notepad. External tools written separately (which usually end up in full blown projects) |
| |
Radiant
Registered: Sep 2004 Posts: 639 |
ca65, make, Vim.
Any conversion or code generation stuff I need to do, I write as separate programs in Python. Its terseness and lack of boilerplate keeps you focused on solving the problem at hand, and it also saves you from the destructive practice of mixing programming languages/domains. |
| |
Frantic
Registered: Mar 2003 Posts: 1648 |
acme (custom), make, TextMate |
| |
Compyx
Registered: Jan 2005 Posts: 631 |
I agree with the Unix approach of small tools that do one thing, but do it well. For me this boils down to:
Whatever assembler gets the job done, usually dreamass, or my own. Assemblers written in languages that need an interpreter or a full-blown VM are out, too slow.
Vim with some custom scripts for editing code.
Python scripts for conversion and code/data generation.
On the graphics side, I write my own tools which run on the C64, since I usually have some arcane requirements for the graphics I'm going to use.
Make to glue everything together.
And Doxygen or Sphinx for documentation, so that when looking at my code a year or so later, I can see what the bloody hell I was doing, and why.
All this is sufficiently portable, should I have to work with someone running Windows. |
| |
Conjuror
Registered: Aug 2004 Posts: 168 |
Kick Assembler, Eclipse with wudsn plugin, exomizer, cc1541, unix utils (win32 ports), DOS batch files, custom JAVA commandline tools for script generation and my KickAssembler demo framework |
| |
Slammer
Registered: Feb 2004 Posts: 416 |
Hi Guys, If you where to make a quick simple intro featuring your groupname flying around in sprites with a sinus movement. How would you generate the sinus and include it in your code in your favorite setup? Could you post some examples in code. |
| |
chatGPZ
Registered: Dec 2001 Posts: 11386 |
$ deltasin pimmel.bin
.include "pimmel.bin" |
| |
Slammer
Registered: Feb 2004 Posts: 416 |
Where is the code for generating the sinus? Does the $ mean running from command prompt or from inside the assembler? What determines the amplitude of the sinus? |
| |
T.M.R Account closed
Registered: Dec 2001 Posts: 749 |
Quoting SlammerHi Guys, If you where to make a quick simple intro featuring your groupname flying around in sprites with a sinus movement. How would you generate the sinus and include it in your code in your favorite setup? Could you post some examples in code.
i just use my own tool CoSinus, it generates cuve data as lines of !byte statements (or other formats since i work with multiple assemblers) that i can cut and paste to the source code. i've been meaning to release it, but there's a few features i need to add before that... |
| |
chatGPZ
Registered: Dec 2001 Posts: 11386 |
Quote:Where is the code for generating the sinus?
in the tool i wrote 15 years ago
Quote:Does the $ mean running from command prompt or from inside the assembler?
commandline, obviously. (you said "quick and dirty", so its not using a makefile)
Quote:What determines the amplitude of the sinus?
its $100 bytes and from 0-$ff - by default (again, quick and dirty. -l <len> -b <bias> -r <range> is of course no problem either if needed. or output .byte statements or C arrays.) |
| |
Slammer
Registered: Feb 2004 Posts: 416 |
Groepaz: Actually, I think it would have been smart if you could run it from inside the assembler with parameters so you quick and easy could adjust the size. At the same time you could read the amplitude just by looking at your sourcecode.
Other solutions? (I look forward to see lua solution you guys have come up with Bob) |
| |
chatGPZ
Registered: Dec 2001 Posts: 11386 |
but for quick and dirty intro 0-$ff sinus in one page is all i'd ever need =) |
| |
Mr. SID
Registered: Jan 2003 Posts: 424 |
k2asm all the way! :) |
| |
Burglar
Registered: Dec 2004 Posts: 1101 |
I used to code on c64 for pc, you losers! :) |
| |
chatGPZ
Registered: Dec 2001 Posts: 11386 |
enno wins |
| |
Hein
Registered: Apr 2004 Posts: 954 |
Since nobody is posting usefull code examples for creating sinusses: Sinus Creator V3.0.
Other tools used: Basic. |
| |
soci
Registered: Sep 2003 Posts: 480 |
Sinus, 256 bytes 0-255 range, symmetric.
.byte 128.5 + 127 * sin(range(256) * rad(360.0/256))
A rather unconventional approach, but works ;) |
| |
Slammer
Registered: Feb 2004 Posts: 416 |
Soci: Look good! Dont you need some kind of counter. How does it work?
EDIT: Ahh .. it must be the range |
| |
soci
Registered: Sep 2003 Posts: 480 |
Universal functions, lists, broadcasting. This should give a hint.
ps.: If this gets copied I'll kick asses ;) |
| |
Slammer
Registered: Feb 2004 Posts: 416 |
Soci: The KickAssembler solution is actually quite close to this and i think it was already there when it was first released in 2006 so no copying there :-) .fill 256, 127.5 + 127.5*sin(toRadians(i*360/256)) Nb. Ofcause you can also import stuff if thats the way you want to do it. |
| |
soci
Registered: Sep 2003 Posts: 480 |
Yes, it looks similar but it's very different.
On the other hand your version is easier to understand for those unfamiliar with the concepts. And at the end that's what matters. |
| |
Slammer
Registered: Feb 2004 Posts: 416 |
I imagine that you find the range directive and then duplicate the line and insert 0,1,2,3,4... as replacement for the range? (Seems clear to me) |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
nice inline sinus stuff guys. any way to use different numbers than 0-256 ? :)
the subtle difference in syntax doesnt matter, its not why some1 would choose one assembler over the other imho. |
| |
soci
Registered: Sep 2003 Posts: 480 |
The macro replacement model gives the correct answer for that example. But I didn't stop there.
Oswald:
A slightly modified version for 100 items in 0-999 range, nicely separated into two tables (low/high bytes).
tmp = 500.5 + 499 * sin(range(100) * rad(360.0/100))
low .byte <tmp
high .byte >tmp
|
| |
ChristopherJam
Registered: Aug 2004 Posts: 1409 |
Loving soci's solution for the sine table.
As for me,
from cjplib3 import dumpNumarrayToa65, np
with open("sinus.inc","w") as fo:
dumpNumarrayToa65(fo, "sinus", (128.5+127*np.sin(np.arange(256)*np.pi/128)).astype(np.int))
All but the last line I'd probably already have in place if there were already other tables or data to include. Fair chance 'i' would already equal range(256), too. |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
soci, you make me excited, now can you generate code aswell with that? an example? :) |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
tmp = range (999)
sta tmp+screen
would work ? |
| |
Slammer
Registered: Feb 2004 Posts: 416 |
I think i would just do it twice. Something like:low: .fill 100, <500.5+499*sin(toRadians(i*360/100))
high: .fill 100, >500.5+499*sin(toRadians(i*360/100)) But you could also define a list or function first if you only want to write you expression once:
.function mySinus(i) { .return 500.5+499*sin(toRadians(i*360/100)) }
low: .fill 100, <mySinus(i)
high: .fill 100, >mySinus(i)
Oswald: My current guess is that soci defines a list with his range command and that all his operations/ functions work on lists. So the range list times the rad(360.0/100) gives another list where all the elements are multiplied by the result of the rad calculation. Etc. |
| |
soci
Registered: Sep 2003 Posts: 480 |
Oswald:
Yes it does work, but I go for an example where you don't need to scroll the forum too much after I paste it in ;)
.1000 a2 00 ldx #$00 ldx #0
.1002 9d 00 04 sta $0400,x lp sta $400+range(4)*256,x
.1005 9d 00 05 sta $0500,x
.1008 9d 00 06 sta $0600,x
.100b 9d 00 07 sta $0700,x
.100e e8 inx inx
.100f d0 f1 bne $1002 bne lp
A bit less pretty example:
.1000 a5 fb lda $fb lda $fb
.1002 0a asl a asl [a,] x 4
.1003 0a asl a
.1004 0a asl a
.1005 0a asl a
.1006 85 fb sta $fb sta $fb
|
| |
soci
Registered: Sep 2003 Posts: 480 |
Slammer: Right. That's what happens.
Range generates a range of integers that's the data source.
Universal functions (like the built-in sin() here) can operate on (nested) arrays. And operators too.
Broadcasting happens when the sizes don't match, then things get repeated as necessary (a simple number is an "array" too).
And at the end the ".byte" directive flattens the arrays (if necessary) for storing.
Using this I can throw out most of my verbose for loops.
There are still some corner cases I need to work on, but all my practical use cases are covered.
Better don't think about how much effort it took to implement this using plain C ;) |
| |
chatGPZ
Registered: Dec 2001 Posts: 11386 |
is that "how to save 3 lines and make the code unreadable 101" now? :=) |
| |
soci
Registered: Sep 2003 Posts: 480 |
Groepaz: It's a shame, but it's not at the level of perl yet in this regard ;) |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
groppie, it could be useful for tables and testing out speedcodes imho. very compact and understandable.
tend to like soci's more because I've never really worked with modern languages (nor programmed for a living, I'm an amateur) so the c64 basic and tasm like simple notation is for me. |
| |
chatGPZ
Registered: Dec 2001 Posts: 11386 |
dunno really, i find regular traditional FOR loops much more readable than this fancy notation :) |
| |
Slammer
Registered: Feb 2004 Posts: 416 |
Oswald: Just to demystify the .fill directive its really not that complicated. Its a directive that output bytes and it takes two arguments: a size, which tells the number of bytes to output, and an expression which is evalutated for each byte to output. Before each evaluation the variable 'i' is set to the byte number. So: .fill 5,0 // Gives .byte 0,0,0,0,0
.fill 3,i // Gives .byte 0,1,2
.fill 5,10-2*i // Gives .byte 10,8,6,4,2 |
| |
Bitbreaker
Registered: Oct 2002 Posts: 508 |
Nice to see you playing with little toys, sinus waves and simple code snippets, but how will you do complex code generation that spits out for e.g. the optimal solution depending on the input? Think for e.g. of fading out a koala in independent 40 columns?
What's next? Will you also implement your packers into your .asm source or still use external tools for that?
I really don't get this mixture of tool code and .asm source in one file. What's so complex about having a makesinus.c/.py/.pl/whatever? Some years ago, a few lines of basic were enough to poke your desired sinus into ram, which was then saved out to disk with the monitor. Nowadays you do, as if this is rocket science :-D
P.S. Yes, with having the stuff separated, the generation does not need to happen on every build, but only if there's changes. And this makes pretty much of a difference on demo projects of a certain size. (comaland builds in ~8s on my i7 her after a make clean, but in rebuilds in zero time if just some changes are made) |
| |
Peacemaker
Registered: Sep 2004 Posts: 275 |
Slammer: any chance to get a tool that does .prg to kickass-source? i lost some of my sources -.- just have kickass generated .prg (final prg with code, gfx, char, data etc) left. |
| |
The Gothicman Account closed
Registered: Aug 2011 Posts: 40 |
Quote: Where is the code for generating the sinus? Does the $ mean running from command prompt or from inside the assembler? What determines the amplitude of the sinus?
Quoting Groepaz:
pimmel.bin
You made my day!!! :) |
| |
The Gothicman Account closed
Registered: Aug 2011 Posts: 40 |
@Peacemaker:
Ask Willi/DUKE/TLC.
He has a .prg to Kickass-Disassembler. |
| |
Peacemaker
Registered: Sep 2004 Posts: 275 |
Quote: @Peacemaker:
Ask Willi/DUKE/TLC.
He has a .prg to Kickass-Disassembler.
where can i reach him? |
| |
soci
Registered: Sep 2003 Posts: 480 |
Quoting BitbreakerWhat's next? Will you also implement your packers into your .asm source or still use external tools for that?
Obviously such functions in assemblers are meant to be used for simple stuff not warranting the creation of an external generator. I was fed up with creating them for trivial offset tables, and copy/pasted bytes take a long time to tweak later if I need to modify them by hand. Especially if I've already forgot how they were made ;)
"Optimal" speed code solutions (more complicated than just unrolling) comes from external tools which split out an asm source (with labels), which gets included and assembled. This later either stays as it is or I turn it to some much shorter binary data which is converted into executable at runtime by an "expander" code.
Packing and picture conversions inline? Nice as a personal challenge and good luck with that ;)
Better use the proper tools for the job. It's not always the assembler, and not always an external tool either. |
| |
The Gothicman Account closed
Registered: Aug 2011 Posts: 40 |
Quote: Quoting BitbreakerWhat's next? Will you also implement your packers into your .asm source or still use external tools for that?
Obviously such functions in assemblers are meant to be used for simple stuff not warranting the creation of an external generator. I was fed up with creating them for trivial offset tables, and copy/pasted bytes take a long time to tweak later if I need to modify them by hand. Especially if I've already forgot how they were made ;)
"Optimal" speed code solutions (more complicated than just unrolling) comes from external tools which split out an asm source (with labels), which gets included and assembled. This later either stays as it is or I turn it to some much shorter binary data which is converted into executable at runtime by an "expander" code.
Packing and picture conversions inline? Nice as a personal challenge and good luck with that ;)
Better use the proper tools for the job. It's not always the assembler, and not always an external tool either.
Check your FB-account, Rene. |
| |
Slammer
Registered: Feb 2004 Posts: 416 |
Quote: Nice to see you playing with little toys, sinus waves and simple code snippets, but how will you do complex code generation that spits out for e.g. the optimal solution depending on the input? Think for e.g. of fading out a koala in independent 40 columns?
What's next? Will you also implement your packers into your .asm source or still use external tools for that?
I really don't get this mixture of tool code and .asm source in one file. What's so complex about having a makesinus.c/.py/.pl/whatever? Some years ago, a few lines of basic were enough to poke your desired sinus into ram, which was then saved out to disk with the monitor. Nowadays you do, as if this is rocket science :-D
P.S. Yes, with having the stuff separated, the generation does not need to happen on every build, but only if there's changes. And this makes pretty much of a difference on demo projects of a certain size. (comaland builds in ~8s on my i7 her after a make clean, but in rebuilds in zero time if just some changes are made)
For simple tasks scripting is very convenient. Things like importing and converting sprites or charsets, importing sidfile from hvsc or just rearranging stuff to the crazy graphics format you are using.
Lets have an example. You can convert a standard 2x2 charset from a gif-file to the standard format with four series of corner chars by this: .pc = $2000
.var charsetPic = LoadPicture("2x2char.gif", List().add($000000, $ffffff))
.fill $200, charsetPic.getSinglecolorByte( 2*[i>>3], i&7)
.fill $200, charsetPic.getSinglecolorByte( 2*[i>>3], 8+[i&7])
.fill $200, charsetPic.getSinglecolorByte(1+2*[i>>3], i&7)
.fill $200, charsetPic.getSinglecolorByte(1+2*[i>>3], 8+[i&7]) Now for a complex task I would use java or C# (But C, C++ etc. would be just as fitting). For example I did a routine to precalculate some halfcut hidden vector coordinates in Java and at the same time got the visualization library from Java to verify they where correct. Its just a matter of picking the tool that is right for the job.
Now if you misjudge the task and it turns out to be heavier than expected, you can always dump the result to a file and import it as a binary.
By the way. I don't see anything against using techniques like this together with a make or ant file. And its only an option, you don't have to use them if you use KickAssembler. You can perfectly well start out with the traditional: *=$1000, .byte, .text etc. and then later pick the features that suits you like scripting, pseudocommands, macros and scoping if you feel like it. |
| |
chatGPZ
Registered: Dec 2001 Posts: 11386 |
Quote:importing sidfile from hvsc
seriously, if you cant write
.incbin "gurken.sid",,$7c
then please go stand in the corner :) |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
I cant, since I dont know the header length, but I can find it out for myself tho :)
its a pointless argument anyway, tastes differ, everyone does it as he likes it. |
| |
mankeli
Registered: Oct 2010 Posts: 146 |
Quote:Nice to see you playing with little toys, sinus waves and simple code snippets, but how will you do complex code generation that spits out for e.g. the optimal solution depending on the input? Think for e.g. of fading out a koala in independent 40 columns?
What's next? Will you also implement your packers into your .asm source or still use external tools for that?
I really don't get this mixture of tool code and .asm source in one file. What's so complex about having a makesinus.c/.py/.pl/whatever? Some years ago, a few lines of basic were enough to poke your desired sinus into ram, which was then saved out to disk with the monitor. Nowadays you do, as if this is rocket science :-D
Actually it would be nice if an assembler could directly output an exomized .prg :-D
Also, it's not complicated to write separate data generators, it's just more convenient (for me) this way. I need a sinus, so i'll just write a for-loop directly to the source file to generate it. If I need to load a picture, i can just load a .png, run hires conversion right there and then just output bytes. If I want to fade out a koala in independent 40 columns, i can just generate my tables (and code) there as well. :)
But in the end, it's just one more tool in the toolbox. Like some people prefer to program in monitor, some like assemblers. And think about early 6502 coders who wrote machine code directly, I bet that some of them never wanted to move beyond that. |
| |
Slammer
Registered: Feb 2004 Posts: 416 |
People should do it the way they are most comfortable with and that fit them best. In the end its the result that counts. I hope this has given some positive examples of scripting to balance Groepaz' rather negative view where everything is 'stupid', 'silly' and 'improper'. Also, it have been cool to see the different approaches! |
| |
chatGPZ
Registered: Dec 2001 Posts: 11386 |
bitbreaker, perplex, tmr, axis, fungus, 4mat, algo, radiance...
i think you will find that actually most ppl prefer to work with those seperated tools, and that most ppl are actually able to use incbin for including their data. and for good reasons :) |
| |
Hoogo
Registered: Jun 2002 Posts: 105 |
Quoting Slammer...Also, it have been cool to see the different approaches! Yes, really interesting to see how new concepts and elements from Basic or Java are put into an Assembler.
What about esoteric elements? Maybe someone could put an Assembler in an Assembler, so we can assemble while we assemble? |
| |
Pantaloon
Registered: Aug 2003 Posts: 124 |
while you all have been writing in this forum ive almost completed my revision demo :) |
| |
Frantic
Registered: Mar 2003 Posts: 1648 |
...in Kick Assembler.. ?
:) |
| |
Brataccas
Registered: Jan 2015 Posts: 16 |
Here's something interesting that showed up recently at http://www.pagetable.com/?p=848
Quote:There are many MOS 6502 cross-assemblers available. Here’s a new one. Or actually a very old one. “Macross”, a very powerful 6502 macro assembler, which was used to create Habitat, Maniac Mansion and Zak McKracken, was developed between 1984 and 1987 at Lucasfilm Ltd. and is now Open Source (MIT license): https://github.com/Museum-of-Art-and-Digital-Entertainment/macr..
|
| |
chatGPZ
Registered: Dec 2001 Posts: 11386 |
"an assembler for people who hate assembly language"
hihi
(what kind of tool is needed to transform .itr into something more readable?) |
| |
ruk
Registered: Jan 2012 Posts: 43 |
Quoting Pantaloonwhile you all have been writing in this forum ive almost completed my revision demo :)
+1 |
| |
JackAsser
Registered: Jun 2002 Posts: 2014 |
Quote: "an assembler for people who hate assembly language"
hihi
(what kind of tool is needed to transform .itr into something more readable?)
Haha, nice find!
macross compiled fine, albeit with tons of warnings, on OSX El Capitan! :)
Interesting with manual implementation of malloc.c bundled in, using sbrk() which nowadays are emulated in OSX, not the actual memory allocation call used by the OS. |
| |
Shadow Account closed
Registered: Apr 2002 Posts: 355 |
For me Kick Assembler is often the fastest way to getting things done, having everything in one place and just recompiling is just so much more convenient for lazy people!
Doing advanced loops with conditionals etc. that spits out unrolled speedcode is ace! |
| |
ChristopherJam
Registered: Aug 2004 Posts: 1409 |
Well, I'm just a single "make run" command away from the next test regardless of whether I'm editing macros in a KickAss source file or editing a Python script that generates unrolled loops for inclusion in an .a65
It just that if I'm writing in Python I'm using a widely supported modernish language with access to some really useful libraries for image access and array manipulation, result caching, signal processing etc etc etc. For me, *that's* the fast, convenient and lazy route :) |
| |
Bitbreaker
Registered: Oct 2002 Posts: 508 |
Exactly. Even if one writes the tool part in brainfuck it is okay, as long as it is separated from the .asm stuff. That way also only that stuff is recompiled that has changed, no need to regenerate hires from png and so on on every compile (and common gfx tools writes out .prg/.kla anyway, so no need for that :-D, for optimized mixed charset, there's a small code snippet for conversion). So here export/conversion happens once, and beforehand.
And as already stated before, it is easy to port the .asm code to any other assembler that usually only differ a little regarding the syntax or label format. As soon as you include severe scripting in your .asm file, it is pretty much impossible to port that. Also, for me readability decreases a lot when asm and scripting is mixed wildly together. This also goes forcode for the censor-assembler c6510, but maybe it is just Bob's messy coding style, haha :-D How much did i curse about a lacking *+x :-)
So yes, as long as you play all alone, you can do whatever you want, but if you build a team and want to support many plattforms and stuff, you also have to think of your groupmates and the one who has to slap the shit together to a working .d64. I guess that is the procedure also groepaz has went through and what made him more critical on all that, just like me. |
| |
Pantaloon
Registered: Aug 2003 Posts: 124 |
Frantic, yeah :) im one of the lazy ones :) |
| |
ChristopherJam
Registered: Aug 2004 Posts: 1409 |
@Bitbreaker - all that said, I suspect readability would suffer a tad if some of the tools were written in brainfuck, too ;) |
| |
enthusi
Registered: May 2004 Posts: 677 |
not when tue external bftool just does what it supposed to do. Mostly data preprocessing. |
| |
ChristopherJam
Registered: Aug 2004 Posts: 1409 |
Wait, you're actually using bf? In any case, I was speaking of readability of the tool source, which as you say is not an issue if the functionality is reasonably stable. |
| |
mankeli
Registered: Oct 2010 Posts: 146 |
Thanks to this thread, I have also learned to put my hires conversions into the makefile! My octacore i7 had such a hard time convert all those 64000 pixels on every compile! |
| |
chatGPZ
Registered: Dec 2001 Posts: 11386 |
Quote:So yes, as long as you play all alone, you can do whatever you want, but if you build a team and want to support many plattforms and stuff, you also have to think of your groupmates and the one who has to slap the shit together to a working .d64. I guess that is the procedure also groepaz has went through and what made him more critical on all that, just like me.
that, with sugar on top. |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
"As soon as you include severe scripting in your .asm file, it is pretty much impossible to port that"
you face the same problem if you write your data prechewing/speedcode gen in whatever modern language.
"I guess that is the procedure also groepaz has went through and what made him more critical on all that, just like me."
you two are not alone having done that. about all demos are made this way since a decade. in my eyes its still trying to tell other people how to do their own stuff. its matter of taste and practice, and experience. |
| |
Martin Piper
Registered: Nov 2007 Posts: 722 |
If the external tools are all cross-platform and use languages with interpreter/compiler availability then they can be quite portable. |
| |
chatGPZ
Registered: Dec 2001 Posts: 11386 |
indeed, porting the tools over is no problem and works out of the box unless you are using something *very* esoteric to make them.
and no, this scripting-inside-assembler madness has only become common among some people recently. |
| |
Slammer
Registered: Feb 2004 Posts: 416 |
Some of us started with this 'scripting madness' around 1991-1992 and got quite ok results with it. |
| |
chatGPZ
Registered: Dec 2001 Posts: 11386 |
yeah and some of us like their ass whipped with a spoon. your point being? |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
Quote: Some of us started with this 'scripting madness' around 1991-1992 and got quite ok results with it.
hard to believe, around 91 I was using profi ass / help plus :) altho you could have used mixed code even in those I guess ? basic / asm lol :) I remember having done a raster color editor in basic ;) |
| |
Slammer
Registered: Feb 2004 Posts: 416 |
Quote: hard to believe, around 91 I was using profi ass / help plus :) altho you could have used mixed code even in those I guess ? basic / asm lol :) I remember having done a raster color editor in basic ;)
I used Einsteins Amiga<->C64 cross assebler. It had some really nice features, including switching the monitor to the c64 after assembling. |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
jesus christ, even soiled legacy (2001) was fully done on a c128d. I was living in the stone ages :) it never occured me my 1200 could be useful to this. I was too hardcore anyway to do it that way. I did most of plastic kiss linking in 2004 on pc but only with savestates in emulator :) and my parts for desert dream (2007) were STILL done in emulator + tasm. omg :D |
| |
ChristopherJam
Registered: Aug 2004 Posts: 1409 |
Must admit, around 91-92 (actually, for my entire first decade, so mid 80s to mid 90s) all my 6502 asm coding was in FASSEM, which was an assembler someone had implemented as a BASIC extension, so I'm really in no position to complain about bloated assemblers. (oh god, having flash backs to FOR loops wrapped around asm fragments now..)
I remember being pretty disappointed to hear that some of my favourite games had been cross assembled; at the time I considered that to be cheating! |
| |
chatGPZ
Registered: Dec 2001 Posts: 11386 |
hehe
i remember when i started with c64 stuff again in '95 i started with using some obscure crossassembler (written by "the uncle" of the dreams i believe).... and then graham told me at mekka that everyone who is doing that is a lamer, because reusing "libraries". *grins* |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
for loops was a luxury, I remember typing out span filler speedcode in tasm, then running out of lines, but surviving with keeping blank lines low :) edit: here Noxious Visions its the last effect. :P |
| |
chatGPZ
Registered: Dec 2001 Posts: 11386 |
tass-macro can do loops fine though :o) |
| |
JackAsser
Registered: Jun 2002 Posts: 2014 |
I used to use the macros in the assembler for various code generation but not any more. It's a nice feature to get things running, but when you want to conserve disk space and decrease loading times you seriously wanna let the 6502 generate all that code for you. A simple template system for generating code native on the c64 and replacing variables while emitting code chunks into memory is dead simple to write anyway. |
| |
Mr. SID
Registered: Jan 2003 Posts: 424 |
On the topic of cross assemblers, the one used by the guys at Lucasfilm games has been released now:
http://www.pagetable.com/?p=848 |
| |
oziphantom
Registered: Oct 2014 Posts: 490 |
64Tass + Relaunced + BDD6502 + Char Pad + Sprite Pad + custom editors and tools as needed in c#
Would love a Static Analyser for the 6502 though. |
| |
chatGPZ
Registered: Dec 2001 Posts: 11386 |
MrSID: look at post #112 =) |
| |
Mr. SID
Registered: Jan 2003 Posts: 424 |
Pfff, I don't have the time to read everything... |
| |
Axis/Oxyron Account closed
Registered: Apr 2007 Posts: 91 |
@Oswald: If you want to know the meaning of stone-age. My parts in "Natural Wonders" were done with "Final Cartridge III"-monitor in VICE.
And then Graham started to change the rule-set for the trackmo system every week (Zeropage and memory layout). 3 month of relocating stuff in a monitor is a good cure. ;o) |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
wow :) havent seen a monitor / ar or similar cart until like 95. so i was in soft fastload stone age aswell for a long time. but that also prevented me from picking up the habit of monitor coding. ripped music with resetting the machine with a fork. |
| |
Frantic
Registered: Mar 2003 Posts: 1648 |
Back in the days, even before the stone age, I used to code trackmos without keyboard, using only my ass. Those were the days!
ZzzzZZzz... |
| |
chatGPZ
Registered: Dec 2001 Posts: 11386 |
i still make graphics that way! |
| |
Stone
Registered: Oct 2006 Posts: 172 |
You were lucky. We didn't even have an ass. We used to run a rusty paper clip across the cassette port again and again until the correct bytes were loaded into memory. And we still found the time to get drunk. |
| |
ChristopherJam
Registered: Aug 2004 Posts: 1409 |
Haha @Axis, I was going to reply to @Oswald that if he wasn't hand coding in FC:III's monitor and doing all his graphics on graph paper then he was cheating. I knew a guy who wrote an entire platform game in his cart monitor back in the day.
But yes, as JackAsser has pointed out, a code generator at runtime will generally beat a cruncher for size, unless it's something decidedly nontrivial to generate. |
| |
chatGPZ
Registered: Dec 2001 Posts: 11386 |
crossbow laughs at you while drawing FLI logos in SMON :=P |
| |
JackAsser
Registered: Jun 2002 Posts: 2014 |
Quote: Haha @Axis, I was going to reply to @Oswald that if he wasn't hand coding in FC:III's monitor and doing all his graphics on graph paper then he was cheating. I knew a guy who wrote an entire platform game in his cart monitor back in the day.
But yes, as JackAsser has pointed out, a code generator at runtime will generally beat a cruncher for size, unless it's something decidedly nontrivial to generate.
And speed. It's faster to instance some code templates in runtime than depack the same amount of code. |
| |
Burglar
Registered: Dec 2004 Posts: 1101 |
Quoting JackAsserAnd speed. It's faster to instance some code templates in runtime than depack the same amount of code.
And size and loading time! |
| |
Burglar
Registered: Dec 2004 Posts: 1101 |
with the current code I'm working on, using a codegen made the exomized result 25 blocks shorter (from 35 to 10).
also, codegenerators themselves tend to pack pretty great too. |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
well, I actually drew sprites and even charset on paper, but that was when I didnt know yet asm, neither had idea the existence of editors, nor it occured to me there could be one. well I was a kid who didnt see anything yet. :) |
| |
ChristopherJam
Registered: Aug 2004 Posts: 1409 |
An extract from Reutastic's source:
def exrv(x):
if x==12*8:
return [0xdd02,0x3c+1]
if x<12*8:
return[0xd018,0x80+16*(x%8)]
else:
return[0xd018,0xf0-16*(x%8)]
def exr(x):
return exrv(x)[0]
def exv(x):
return exrv(x)[1]
with open('data.inc','a') as defs:
defs.write('exr__1=$%02x\n'%exr(-1))
defs.write('exr000=$%02x\n'%exr(0))
defs.write('exr001=$%02x\n'%exr(1))
defs.write('exr200=$%02x\n'%exr(200))
defs.write('exv__1=$%02x\n'%exv(-1))
defs.write('exv000=$%02x\n'%exv(0))
defs.write('exv001=$%02x\n'%exv(1))
defs.write('exv200=$%02x\n'%exv(200))
defs.write('d00d2=$%02x\n'%(vic[0x0d]+21))
defs.write('paletteEntriesPerRow=$%02x\n'%(paletteEntriesPerRow,))
with open('copper.inc','w') as copper:
for line in range(1,201): # first d011 write fetches second raster
i=line-1
ph=(line-1-1)%21
y=(0x39+line-1)&0xff
if line==200:
copper.write("\tlda#$7f:sta $d011\n")
copper.write("\tldy#$%02x:sty REU_ADDRE+1 ; FINAL\n" %y )
copper.write("\tstx REU_CMD\n")
elif ph>13 or line>190:
if line>1:
copper.write("\t%s:lda#$%02x:sta $%04x ; line %3d\n"% ( ["nop","clc"][line%2],exv(line),exr(line),line))
copper.write("\tldy#$%02x:sty REU_ADDRE+1\n" %y )
copper.write("\tstx REU_CMD:lda#$%02x:sta $d011\n\n\n"%( 32+(line+0)%8+[16,24][line>190]))
elif ph%2==0:
copper.write("\tlda#$%02x:sta $%04x:lda#$%02x ; line %3d\n" %(exv(line),exr(line),exv(line+1),line))
copper.write("\tldy#$%02x:sty REU_ADDRE+1\n" %y )
copper.write("\tstx REU_CMD:inc $d011\n\n" )
else:
copper.write("\tsty$d00%x:sta $%04x ; line %3d\n" %(ph,exr(line),line) )
copper.write("\tldy#$%02x:sty REU_ADDRE+1\n" %y )
copper.write("\tstx REU_CMD:lda#$%02x:sta $d011\n\n\n"%( 32+(line+0)%8+0x10))
14 lines out of every 21 bar the last ten, I'm splitting sprite y updates across pairs of lines, and there are different rule for d018 updates for the two banks.
Probably could have written a generator in 6502, but Python was just easier, and besides it's only 15 blocks so ¯\_(ツ)_/¯ |
| |
JackAsser
Registered: Jun 2002 Posts: 2014 |
Lame! Code generator used in the hidden lines vector of the 1991-demo by Booze. Each object has custom code to calculate the rotation of every vertex and normals, not data driven. So, to pack that code I created a byte code that is execute to control the flow of the code generator:
Byte code parser:
.include "zp.inc"
.export generateCodeFromByteCode
.proc generateCodeFromByteCode
stx z2+0
sta z2+1
lda #<RotateCode
sta z1+0
lda #>RotateCode
sta z1+1
nextCode:
ldy #0
lax (z2),y
bmi done
iny
stx tmp
lda template_handler_lo,x
sta sm1+1
lda template_handler_hi,x
sta sm1+2
clc
lda (z2),y
iny
sm1: jsr $1234
tya
clc
adc z2+0
sta z2+0
bcc :+
inc z2+1
:
ldy tmp
jsr emitTemplate
jmp nextCode
Template instancer:
.proc emitTemplate
lda templates_size,y
tax
dex
lda templates_lo,y
sta z3+0
lda templates_hi,y
sta z3+1
ldy #0
:
lda (z3),y
sta (z1),y
iny
dex
bpl :-
tya
clc
adc z1+0
sta z1+0
bcc :+
inc z1+1
:
rts
.endproc
The handler for template 18 (for self moding the template before instancing):
.proc templateHandler18
sta template18+2
adc #8
sta template18+6
lda (z2),y
iny
sta template18+4
lda (z2),y
iny
sta template18+8
lda (z2),y
iny
sta template18+12
rts
.endproc
Template18:
template18: sec
lda $00
sbc #$00
lda $00
sbc #$00
bpl :+
inc visibleNormals
:
template18_end:
Byte code for one of the objects:
bytecode:
.byte $02,$2d,$04,$5d,$0e,$87,$09,$02,$3d,$04,$6d,$0e,$97,$0b,$02,$4d,$04,$7d,$0e,$a7, $0d,$10,$00,$00,$2d,$04,$5d,$0
.byte $04,$6d,$0e,$97,$0b,$00,$4d,$04,$7d,$0e,$a7,$0d,$10,$01,$09,$5d,$0e,$87,$09,$09, $6d,$0e,$97,$0b,$09,$7d,$0e,$a
.byte $27,$08,$5b,$0e,$87,$09,$02,$37,$08,$6b,$0e,$97,$0b,$02,$47,$08,$7b,$0e,$a7,$0d, $10,$03,$00,$2a,$04,$5b,$0e,$8
.byte $6b,$0e,$97,$0b,$00,$4a,$04,$7b,$0e,$a7,$0d,$10,$04,$02,$2a,$04,$5b,$0e,$87,$09, $02,$3a,$04,$6b,$0e,$97,$0b,$0
.byte $a7,$0d,$10,$05,$02,$27,$08,$57,$0e,$87,$09,$02,$37,$08,$67,$0e,$97,$0b,$02,$47, $08,$77,$0e,$a7,$0d,$10,$06,$0
.byte $87,$09,$02,$38,$08,$69,$0e,$97,$0b,$02,$48,$08,$79,$0e,$a7,$0d,$10,$07,$02,$2d, $04,$5d,$0c,$87,$09,$02,$3d,$0
.byte $02,$4d,$04,$7d,$0c,$a7,$0d,$10,$08,$00,$2d,$04,$5d,$0c,$87,$09,$00,$3d,$04,$6d, $0c,$97,$0b,$00,$4d,$04,$7d,$0
.byte $09,$5d,$0c,$87,$09,$09,$6d,$0c,$97,$0b,$09,$7d,$0c,$a7,$0d,$10,$0a,$02,$27,$08, $5b,$0c,$87,$09,$02,$37,$08,$6
.byte $47,$08,$7b,$0c,$a7,$0d,$10,$0b,$00,$2a,$04,$5b,$0c,$87,$09,$00,$3a,$04,$6b,$0c, $97,$0b,$00,$4a,$04,$7b,$0c,$a
.byte $2a,$04,$5b,$0c,$87,$09,$02,$3a,$04,$6b,$0c,$97,$0b,$02,$4a,$04,$7b,$0c,$a7,$0d, $10,$0d,$02,$27,$08,$57,$0c,$8
.byte $67,$0c,$97,$0b,$02,$47,$08,$77,$0c,$a7,$0d,$10,$0e,$02,$28,$08,$59,$0c,$87,$09, $02,$38,$08,$69,$0c,$97,$0b,$0
.byte $a7,$0d,$10,$0f,$00,$2b,$04,$5d,$0e,$87,$09,$00,$3b,$04,$6d,$0e,$97,$0b,$00,$4b, $04,$7d,$0e,$a7,$0d,$10,$10,$0
.byte $87,$09,$00,$3b,$04,$6d,$0c,$97,$0b,$00,$4b,$04,$7d,$0c,$a7,$0d,$10,$11,$21,$a7, $04,$00,$d0,$20,$a7,$fc,$ff,$d
.byte $de,$ff,$d2,$11,$48,$16,$77,$0e,$00,$d3,$11,$48,$18,$77,$04,$00,$d4,$13,$48,$18, $77,$de,$ff,$d5,$1a,$77,$de,$f
.byte $77,$f2,$ff,$d7,$1c,$77,$e8,$ff,$d8,$13,$48,$18,$79,$22,$00,$d9,$11,$48,$18,$77, $de,$ff,$da,$13,$48,$16,$77,$0
|
| |
chatGPZ
Registered: Dec 2001 Posts: 11386 |
jackasser wins :) |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
yup he does, I'm also for realtime speedcode generators. once you have a good basis down, its about as easy to tweak them than higher level generators. |
| |
ChristopherJam
Registered: Aug 2004 Posts: 1409 |
Thirded. JackAsser's code is definitely makes for a better final result, I'm just lazy. |
| |
HCL
Registered: Feb 2003 Posts: 728 |
Damn :). I also use code generators for the last 15 years or so, but i never took it one step further like Jackasser :P. I feel lame. |
| |
Frantic
Registered: Mar 2003 Posts: 1648 |
@HCL: Would you have admitted to feeling lame if the two of you were not in the same group? ;) |
| |
HCL
Registered: Feb 2003 Posts: 728 |
@Frantic: Probably not. Don't fuck'n push me with philosofical off-topic questions ;). |
| |
JackAsser
Registered: Jun 2002 Posts: 2014 |
Quote: jackasser wins :)
It's not about winning, it's about not getting kicked out of Booze. I always use the macro assembler or code generators written in C or Java when developing for speed and ease to tweak. However, delivering a part for linking like that would kill the loading times and HCL would kick me out with my head first, down some random stair. That could very well happen anyway, since I havn't delivered a single part the last year or so. :/ |
| |
Frantic
Registered: Mar 2003 Posts: 1648 |
@HCL: :D |
| |
Slammer
Registered: Feb 2004 Posts: 416 |
Good examples, I use both methods. First the 'script-method' since (for me) its faster and I usually change my mind of how things are supposed to be done a couple of times during development and when everything is ok, the codegen-method.
When i start making a part, I setup a section for generated stuff (*=$8000 "Generated"). Then use .fill and .for-loop etc. for generating the code. When everything is ok, i declare the section virtual (*=$8000 "Generated" virtual), so it won't generate any byte output, and then make codegenerators for the stuff in the generated section.
(A little bonus of this is that the assembler calculates the memory layout so that there are no unused spaces between the generated stuff since the same, now virtual, labels are used.) |
| |
Stone
Registered: Oct 2006 Posts: 172 |
@JackAsser: Very cool! Do you have some higher level abstraction to generate the template handlers, or are they hand coded? |
| |
chatGPZ
Registered: Dec 2001 Posts: 11386 |
Quote:I always use the macro assembler or code generators written in C or Java when developing for speed and ease to tweak. However, delivering a part for linking like that would kill the loading times and HCL would kick me out with my head first, down some random stair.
did you read that peacemaker? =) |
| |
JackAsser
Registered: Jun 2002 Posts: 2014 |
Quote: @JackAsser: Very cool! Do you have some higher level abstraction to generate the template handlers, or are they hand coded?
Nah, each template is hand-written, usually extracted by locating common instances of previously generated code. The handler follows automatically and simply just passes parameters from the byte code stream into the template to be instanced. |
| |
mankeli
Registered: Oct 2010 Posts: 146 |
I'm pretty sure that these fancy "byte code streams" and "template systems" didn't exist in the 80's, and therefore shouldn't be used when coding for the C64! |
| |
JackAsser
Registered: Jun 2002 Posts: 2014 |
Quote: I'm pretty sure that these fancy "byte code streams" and "template systems" didn't exist in the 80's, and therefore shouldn't be used when coding for the C64!
How exactly do you think ScummVM work with Maniac Mansion, or Z-machine with Zork for that matter? Now, their byte code certainly didn't generate code, but did other useful stuff. |
| |
ChristopherJam
Registered: Aug 2004 Posts: 1409 |
@Slammer, good point about scripting first, then switching to code gen if required/worthwhile. Nice trick about keeping the old version around for lable generation!
FWIW the example I gave above crunches down to a mere 1017 bytes, and the decompression time is way shorter than the alpha compositing precalculation that it follows.
And yes, as @JackAsser mentioned, step one is often hand coding individual fragments before spitting out longer loops, either offline or on. |
| |
Fungus
Registered: Sep 2002 Posts: 686 |
was offline for a week because moving house...
screw sines, they are always jerky looking, parabola is better. :D
routine credits to GHD/Shape
partab = somemempage
ldy #$3f
stx $fb
stx $fc
stx $fd
make inc $fb
lda $fb
asl a
asl a
adc $fc
sta $fc
lda $fd
adc #$00
sta $fd
sta partab+$80,y
sta partab+$c0,x
eor #$3f
sta partab,y
sta partab+$40,x
inx
dey
bpl make
I haven't got any of my speedcode generator sources anymore... dug around but couldn't find them.
Best thread on CSDB, lets keep this going. :D |
| |
Fungus
Registered: Sep 2002 Posts: 686 |
mankeli: Also several disk protections used VM's, also several games used byte code and vm's. Like Lucas's games and Infocom's games. |
| |
Martin Piper
Registered: Nov 2007 Posts: 722 |
One of my music players used byte code driven code gen. |
| |
Fungus
Registered: Sep 2002 Posts: 686 |
failed playstation games don't count
*starts drama* |
| |
soci
Registered: Sep 2003 Posts: 480 |
BASIC is implemented as a byte code interpreter too.
Anyone tried xml and xslt for code templating yet? ;) |
| |
JackAsser
Registered: Jun 2002 Posts: 2014 |
Quote: BASIC is implemented as a byte code interpreter too.
Anyone tried xml and xslt for code templating yet? ;)
Brrrrr... :) |
| |
ChristopherJam
Registered: Aug 2004 Posts: 1409 |
Quote: BASIC is implemented as a byte code interpreter too.
Anyone tried xml and xslt for code templating yet? ;)
No, but I've tried .json for music composingÂ… |
| |
chatGPZ
Registered: Dec 2001 Posts: 11386 |
Quote:Anyone tried xml and xslt for code templating yet? ;)
eine woche fernsehverbot für soci! |
| |
JackAsser
Registered: Jun 2002 Posts: 2014 |
Quote: Quote:Anyone tried xml and xslt for code templating yet? ;)
eine woche fernsehverbot für soci!
Agree! |
| |
Mixer
Registered: Apr 2008 Posts: 452 |
Interesting thread this! Many new tricks. |
| |
Frantic
Registered: Mar 2003 Posts: 1648 |
@Mixer: Wasn't one of your music players also a bit like running a few virtual machines in parallel... or did I just dream that up? |
| |
ChristopherJam
Registered: Aug 2004 Posts: 1409 |
Numpy really does make life easier.
bmpbytes=bmppixels.reshape((25,8,40,4)).swapaxes(1,2).reshape((-1,4))@[64, 16,4,1] |
| |
Radiant
Registered: Sep 2004 Posts: 639 |
Run time generators are of course neat; I've used them (the bobs in Faux Visage) but most of the time I've been able to get away with generating the code offline.
I don't get the "I'm lazy so I use KickAssembler" crowd. I'm lazy. What could be more lazy than using the most efficient tools for the task, instead of trying to build an entire house using nothing but a hammer? (Even if it's a MegaHammer 3000 with inline scripting.) |
| |
Radiant
Registered: Sep 2004 Posts: 639 |
Anyway, something I'm often coding Python generators for is the kind of analyzed optimal code generation Bitbreaker was describing (Koala fader). A similar example is the classic static tunnel effect (with scrolling texture); it's a pretty easy task to write a Python snippet that keeps track of all the locations on the screen where a specific texel will end up so the render code will end up looking something like:
lda texel
sta screen + $0009
sta screen + $000a
sta screen + $1234
lda texel + 1
sta screen + $000b
[...]
Doing the same with a run-time generator I would consider non-trivial. |
| |
Fungus
Registered: Sep 2002 Posts: 686 |
If the code follows any kind of pattern than can be done in a short algo, it's usually pretty feasable to do? Saves disk space too and is faster than decompression usually. |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
radiant's example.. I'd do it realtime anyway because of disk space and loading time. estimate max possible nr of occurence of the same texel then build lists while scanning UV map once, then generate code. 2 pass, not rocket science.
scanning:
ldx uvmap
lda listselectlo,x
sta 40
lda listselecthi,x
sta 41
inc listcount,x
ldy listcount
txa
sta (40),y
inc uvmapself+1
bne +
inc uvmapfelf+2
;exit check
the whole shouldnt take more than 1-2 secs, depending on resolution. |
| |
chatGPZ
Registered: Dec 2001 Posts: 11386 |
generating the tunnel thing in 6502 is certainly doable.... but slowish :) |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
Quote: generating the tunnel thing in 6502 is certainly doable.... but slowish :)
nah.
http://codebase64.org/doku.php?id=base:8bit_atan2_8-bit_angle
http://codebase64.org/doku.php?id=base:fast_sqrt |
| |
chatGPZ
Registered: Dec 2001 Posts: 11386 |
still slowish, its quicker to just load it (perhaps even more so with todays loaders). and if you do it like reflex did you get a nice fade effect for free by just loading one effect over the other while it runs :) (not that you should do any of this 4x4 shit anymore, the 90s are over =P) |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
interesting, I always thought they just copy the tunnel over the torus. |
| |
Maxlide
Registered: Apr 2003 Posts: 31 |
|