Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation since 11/08/21 in all areas

  1. Hi everyone while waiting for the X16 to get real, I started to design my own computer case. I want it to resemble the keyboard or wedge-shape cases of the 80ies era. I owned a TI-994A and a Atari ST back then and I wanted to have something similar where I can put the X16 board in. As I just started with 3D printing I fired up Blender and started designing. After many, many hours of sketching, klicking, dragging and swearing I started printing the whole thing. Then I integrated a xtrify ten-keyless keyboard (which I want to lower a bit) and integrated a MISTER, Raspberry Pi (and a KVM Switch). This now gives me the full retro vibe - until the X16 will arrive... So this is how it looks now, what do you think? The frame around the keyboard is still missing, but I'll do that as soon as I have lowered the keyboard.
    8 points
  2. One of the annoying things about using SD card mode is that LOAD fails when loading into banked RAM. As many know, when using the emulator without an SD image, it performs a hyperload directly into memory w/o emulating the actual file transfer. It does this by skipping the kernal routine entirely. When using SD card images, the Kernal runs as normal. Using hyperload, you can issue a command to BASIC like this: LOAD "MYFILE",8,3,$A000 This loads MYFILE into bank 3 of Hi Ram, and it is automatically continued into banks 4,5,6... as necessary. This operation fails when using Kernal (SD card attached). The same works/fails conditions apply when calling SETNAM,SETLFS,LOAD from within programs. I got really really tired of this, so I decided to fix it in the Kernal. As I'm not a code god, I'd like to see if anyone experiences any instabilities or crashes with it before I do a pull request to include the fix on the main repo. The ROM image is attached below. Use it with emulator R39 or Box16. It will not work in R38. I tested the performance with my additional code and the impact is negligible. I haven't checked what the return values look like after a LOAD into Hi RAM. The Kernal's output message gives the memory address where the load finished, and the final bank remains active, so I presume the return values in X/Y are similar. There's not much space available in the ROM so I'm trying to keep from adding too much to it. Let me know if you experience any crashes with it that don't happen using the current repo version of R39. Thanks. EDIT: Dec 05, 21:17 UTC (3:17pm Central time): Updated the attached ROM to fix a bug reported by @desertfish EDIT2: UPDATE - I've re-done the patch with a much smaller code size, saving over 60 bytes vs. my previous patch. The new one is MUCH easier code to read and follow, and it's only slightly slower. For a 96KB file I'm testing with, the previous patch took 60 jiffies (frames) to load, while the new routine took 63 jiffies. This speed penalty only happens on loads into banked memory, so I call that a win. I have updated the file here again. If you downloaded the previous ones, then I recommend that you re-download this one, as it's the one I'm using for the pull request into the Kernal repo. rom-r39-fixedload.bin
    7 points
  3. One thought just went through my head while thinking about my music playback routine - there's no kind of checking being done when you say "start here and go." What happens if you're off by one byte? Meh, it'll just crash. Don't do that. "It'll just crash" - there's something fun about that, and in this theater of operation, it's totally justified. You have neither the CPU time nor the memory resources to waste on paltry things like range checks and sanity checks on values passed in to / out from subroutines. "Git gud" Plus, all that meticulous guarding against every conceivable thing that could go wrong is just tedious anyway. It's nice that you don't have to harden every routine of every module of code against bad actors on the Internet or anything like that. Just "start here and start copying until you reach a sentinel value." (no sentinel value found - interrupt table overwritten - oh well, time to launch the debugger and see why the screen turns to garbage and the sound sticks on a digital shriek that makes your hair stand on end)
    7 points
  4. Iain Bennie has painstakingly recreated the Commodore 64 User's Guide and Programmer's Reference Guide in a form that can be printed. He does not print them himself, but provides the material and instructions on how to have your very own copy printed on demand. I haven't done it yet, but the prices aren't bad at all for the apparently quality. About $30 for the PRG, and under $20 for the UG. If interested, they can be found at: https://pickledlight.blogspot.com/p/commodore-64-guides.html
    5 points
  5. Not going to ruin anything for anyone, but I went and seen it, and if you're a fan of the series like I am, it's a must! My wife, daughter, and I went to check it out, being a Monday night we pretty much had the theater to ourselves. I really enjoyed the film, there is a lot of "fan service", and it was really well done. The way they did things was really respectful to the original films and it was well worth the $65 it cost, once you add in popcorn and soda. haha I seen the original two films in theaters when they released, no way I was going to miss this one, especially since it's one of my all time favorite film franchises. Also, if you go, there are two post credit scenes, one near the start of the credits, and one at the end. So don't run out of the theater, you wont want to miss them. Have you seen it? Plan on seeing it in theaters? What did you think?
    4 points
  6. Version 1.0.0

    15 downloads

    This is a console application for Windows that will convert png images to a format that the video controller (VERA) of the Commander X16 can read. Both indexed images (which contain a palette) and full-color images are supported. The original file can contain an image or a number of tiles or sprites with max 256 colors. For conversion of images, the width of the image must be 320 or 640 pixels. Height has no restrictrions. For conversion to tiles or sprites, the width and height of each tile/sprite must be specified. COLORS Bits per pixel (BPP) in the generated file will depend on how many colors the conversion results in. The number of colors might be reduced because the color depth of VERA is limited to 12 bits. In other words several 32-bit colors in the original image might be converted to the same 12-bit color. Semitransparent colors (0 < alpha < 255) will be treated as solid colors. For conversions of images with 16 colors or less, up to 13 colors will be displayed in the console window. Due to limitations of the console itself this is the maximum number that can be displayed correctly. TRANSPARENCY The first color of the palette might be transparent when rendered by VERA. This is for example the case when a sprite is rendered in front of a layer. Therefore it can be absolutely crucial which color in the original image that will receive index 0 in the generated palette. The selection is made in the following way: 1. If the original image is indexed (has a palette), the color with index 0 in the original will also receive index 0 in the converted image. 2. If the user has explicitly stated which color should be the first, this color will receive index 0. 3. If nothing above applies, the color of the top left pixel will receive index 0. OUTPUT At least two files will be generated: a binary file with image data and the palette in binary format or in the format of assembly source code or BASIC. As an extra bonus a BASIC program that displays the image/tiles/sprites can be generated. INSTALLATION The application is for Windows and depends on .NET 6.0. No installation is needed, there is just one executable file. SYNTAX X16PngConverter [-help] [FILENAME] {-image|-tiles|-sprites} [-height] [-width] [-palette] [-transparent] [-demo]. OPTIONS (No arguments) : Displays this text. -help/-h : Same as above if it is the first argument. FILENAME : If the name of the file is the only argument, the original image will be analyzed to see if conversion is possible and in that case which options that are possible. -image|-tiles|-sprites : Set conversion mode (mandatory). When image mode is used the original image must be either 320 or 640 pixels wide. -height/-h : Set height of tiles or sprites (not used when converting to a bitmap image). Valid values for tile mode are 8 and 16, for sprites 8, 16, 32 and 64. -width/-w : Set width of tiles or sprites, (not used when converting to a bitmap image). Valid values are the same as for height. -palette/-p : Set file format for the destination file that contains the palette. Valid values are: bin - a binary file asm - text file containing assembly source code) bas - text file containing BASIC DATA statements). If this option is omitted, all three files will be created. -transparent/-t : Set which color that will have index 0 in the generated palette. The value must be a 32-bit hexadecimal value in the following format: $aarrggbb where a = alpha, r = red, g = green and b = blue. -demo/-d : Generate a demo program in BASIC. This can be loaded to the emulator by using the -bas option. For example: x16emu -bas mysprites_demo.txt. To run it immediately add the option -run. Using this option will cause a binary palette file to be created. EXAMPLES X16PngConverter : Display help text. X16PngConverter image.png : Analyse image and see if it is possible to convert. X16PngConverter image.png -image : Convert to a bitmap image (width must be 320 or 640 pixels). X16PngConverter image.png -tiles -h 16 -w 16 : Convert to tiles with a widht and height of 16 pixels. X16PngConverter image.png -image -p asm : Convert to sprites and output palette only as a file with assembly source code. X16PngConverter image.png -image -t $ff88aacc : Convert image with the specified (potentially transparent) color as the first in the generated palette. X16PngConverter image.png -image -demo : Convert image and generate a BASIC demo program named image_demo.txt.
    4 points
  7. And today is perhaps the most American holiday: Black Friday. Try not to murder anyone while Christmas shopping! And if you work in retail in the US: stay strong!
    4 points
  8. I've now implemented the time resolution support in both the library's player and the ZSM generation script. As a test, I generated Sonic The Hedgehog, Green Hill Zone at the VGM-native 44100 just to see how much more CPU-expensive that is. It's pretty steep, roughly 20% of the visible raster time. My simple player produces a "raster bar" at the top-right corner of the screen. This is how much raster time is taken up as a minimum when it calls step_music 735 times per frame: For comparison, when the same tune is re-sampled to 60Hz and only called once per frame, the minimum is actually zero pixels of the raster bar shown... typically one or two raster lines are used except when YM voices re-patch for instrument changes. Obviously, this "step it 735 times" per frame method is still not as accurate (or CPU-intensive) as it would be to generate IRQs at 44.1KHz, but it demonstrates that the format handles it well. Also, now that the playback rate support is there, the player can now speed up or slow down the playback in real time.
    4 points
  9. I do admit, and as those on here who know me, I use my modern hardware to do a lot of retro things. Though, I do my fair share of purely modern things as well. I am sometimes flabbergasted at the complexity of modern games, seeing why it takes an entire studio, hundreds of people, truck loads of money, and months (if not years), to put out a single "AAA" title. On the flip side I also really marvel at small indie studios who put out amazing games with both modern and retro themes, with little to no resources at their disposal. For me that's one of the main reasons I like our modern hardware, there is so much computing power available that you can push the envelope of whats possible and create ultra realistic games, create a smash hit retro game that strikes that nostalgic nerve with players, and emulate most all of the platforms and operating systems of the past, all from your desk. That being said I am sitting here muddling through Arduino code working on making myself a portable FM radio, just becasue. Letting Steam update a long list of games, watching (more like listening) Adrian's Digital Basement work on a IBM PC 5160 motherboard, looking for some specific ROM's, and taking a bit of a break to mess around on the forums here. Multitasking! This is how I enjoy my days off work. You got to love modern technology.
    4 points
  10. I just did a comparison between my algorithm (bespoke), @BruceMcF's General algorithm, and one that @Scott Robison proposed on Discord (Galaxybrain): Galaxybrain took my algorithm and enhanced it by using clever byte-order manipulation to cut down the number of shifts required to perform the computation. For computing 31,217/60 into 16.8 fixed point format: (answer = 48 08 02) galaxybrain: 46 08 02 , 230 cycles, 159 bytes bespoke: 46 08 02 , 531 cycles, 122 bytes general: 48 08 02 , 3813 cycles, 70 bytes As you can see, bespoke is pretty much what I said - a bit of a balance between speed and size (I could've gotten about 30-60 less cycles, but would've been at least as large as Galaxybrain. My computation X = X>>6 + X>>10 + X>>14 + X>>18 + X>>22 is slightly off from the answer I computed by hand. Not sure why, as it's the same algorithm, and it didn't have this slight error in my main library. (I assembled all these into a testbed project). Galaxybrain gets the same error though, so not sure what's going on... Anyway, that's the results. As BruceMcF states - the general purpose answer is clearly the winner in size optimization (no shock there). As this calculation is only done once when a song is loaded, that may not be the biggest sacrifice in performance to make. It could probably be optimized a little for my application by skipping the first 5 loops and pre-shifting everything. For reference, right after starting a song, it's usually going to load quite a few YM bytes (assuming it's got FM tracks) which is slow, about 150 cycles per write (due to having to wait on the YM to be ready for each successive write). So the first two algos pretty much equate to just a few YM writes' worth of time. Well, that's the tale of the tape, folks. This has been a fun exercise.
    4 points
  11. Well, for comment 486 (woot), I'd like to say that SFX did do a lot of the image processing for Star Fox, but definitely not all of it, and not the game engine either. It was essentially a VooDoo3 card for SNES. The SNES still did a lot on the game engine side, and did the horizon graphics and pop-up portrait sprites and whatnot. So yeah, SFX definitely pushed the SNES well beyond anything it could dream of doing alone, it wasn't running the entire game. That's what my comment about doom on NES cart was about. I played Quake in xterm using a VGA to ASCII art plugin once.....
    4 points
  12. Version 1.0.0

    26 downloads

    Fractal Mania (fracman) is a Mandelbrot and Julia Set generator/explorer, written in 6502 assembly language. It uses 320x240x256 color mode, supports mouse and keyboard input and if an sdcard image is attached, will cache each plotted image to disk, so that the user may go back and forth, among the generated images. These images are currently only available for that session, but a future version will allow reloading of previous session images. Iteration support is from 16 to 256 and the slightly modified color pallette may be shifted by 16 places per each use of the command key. Help screens are available at program start and by using the 'H' command key. To speed image generation up to a snail's pace , fracman draws every other column, the other columns can be drawn if desired. Thanks to those in the CX16 community that post/have posted code, demos, videos, tutorials, etc., without which, this program would not exist!
    4 points
  13. So glad I included the disclaimer that maybe there were stubs in BASIC.
    4 points
  14. Version 1.0.0

    10 downloads

    Writing BASIC programs longer than 10 rows on the X16 is a tedious experience. The text editor is very limited, much is about struggling with row numbers. This is an extremely simple compiler (sort of at least) for Windows that lets you write your BASIC programs in your favourite text editor with labels. The compiler outputs a new text file with the extension ".bas". It adds row numbers and fills in the right row number after the commands "GOTO", "GOSUB" and "THEN". No installation is needed, just copy the only file to the directory of your choice. Usage: x16LabelCompiler <filename> [first row number] [step between row numbers] Labels must end with a colon (":"). Labels must not be reserved keywords in BASIC. Labels are preserved in the generated code by inserting "REM" before them. Empty rows are removed. All letters are converted to uppercase. A sample program called "guess_the_number.txt" is included. To compile the program: x16LabelCompiler guess_the_number.txt To start the emulator, load the generated file and run it immediately: x16emu -bas guess_the_number.bas -run
    4 points
  15. Wow. Someone is channeling his inner Richard, over here. Maybe relax a bit. Read a book. Watch a movie. The Commander will be here when it gets here...
    4 points
  16. My name is Pedro Crespo and I am from Portugal... I like computers/video games. Also, I am interested in content creation.
    3 points
  17. some sort of "workaround" to load headerless files can be this: OPEN file CHRIN 2 bytes to the first 2 load locations in memory CLOSE file LOAD file in memory location+2 I built this into prog8 as load_raw() and it works like a charm, just requires a fair bit of extra code (hidden away in a library)
    3 points
  18. Version 7.4.1 has been released https://github.com/irmen/prog8/releases/tag/v7.4.1 Documentation as always here https://prog8.readthedocs.io Even more improvements in generated code efficiency, resulting in smaller code that runs faster. improved code generation. optimizer is now smarter about accesses to memory mapped IO that shouldn't be optimized away performance improvements in the compiler itself, updated to Kotlin 1.6 fixed some illegal instructions in the conv module on c64 target other bugfixes documentation improvements
    3 points
  19. I think David crowdfunded another project (one of the PlanetX ?) and didn't rate the experience highly
    3 points
  20. I'm in the US, and many other people are, so Happy Thanksgiving to all of you. Canadians, please accept this as a Happy Belated Thanksgiving. Other countries can take this as Happy Thursday if there isn't a belated or early Thanksgiving in their timeline.
    3 points
  21. I can go out and buy one easily from Amazon, and I almost did just that last week. Not that big of a deal to get one. However, I got to thinking about Christmas 1985 when I got a C128, 1571 drive, 1902 monitor, and some dot matrix printer... and how I wanted to relive that long ago Christmas this year by unwrapping The C64 Maxi with much elation. In order to get that Commodore in 1985 I had to plot, plan, connive, scheme (basically lie to my parents about how it would help with school work)... all the usual stuff that some of us did to convince our parents it would be a good investment. Well, last week I began to annoy the living crap out of my wife about how much The C64 Maxi would be a good thing to add to our media room... Hoping to unwrap one December 25th 2021 and relive Christmas 1985... we'll see. So far it's been fun going through all the motions to drop hints.
    3 points
  22. Hello all! Newcomer here. I used to love Basic programming on the C64, but that was over 30 years ago. I have unfinished business (old programs to port/finish), and new games to create and would love to make them for the x16, but I have really beginner questions (starting over again). Maybe it will help other newbs as well. 1) I know I could start by typing directly into the emulator, but can someone talk me through a better process? I've seen mention of using text editors (like notepad++), but what's the workflow to get from there into the x16 emulator? Copy paste? 2) IIRC, in c-64, each line was limited to 80 cols (chars)? Same here? 3) Anything else real basic about this Basic? I guess that's it for now. If it means anything I'll be starting with some text adventures, so no gfx yet.
    3 points
  23. The documentation for the X16 indicates that BASIC programs for the C64 are 100% compatible, so long as PEEK and POKE commands aren't used. So you could start there, using some existing programs to get comfortable with it. Here is how to use the run command from Notepad++ on the file you are working on (in Windows). Download and install Notepad++ Download the X16 emulator x16emu_win-r38.zip file Open Windows Explorer, go to C:\Program Files(x86), right click > New > Folder, and name it x16emu In Explorer go to your Downloads folder, double click on x16emu_win-r38.zip to open so you can see the files CLT+A to select all the files, then CTL+C to copy them (no indication of success on this), then go back to C:\Program Files(x86)\x16emu and CTL+P to paste the files Open Notepad++, create a new program (type in all caps!) and save the file to your Documents folder Press F5 to open the Run dialog and paste the following into it run the currently active file "C:\Program Files (x86)\x16emu\x16emu.exe" -run -bas "$(FULL_CURRENT_PATH)" Press the Save... button to open the save command dialog box Type Commander X16 Emulator in the Name box Check the ALT box Select X from the drop down that says None by default Press OK to return to the Run dialog box Press the Run button From now on you can run your program by simply pressing ALT+X in Notepad++. I attached a screenshot of the settings used to make Notepad++ look similar to the X16's BASIC interpreter. The settings are in Settings > Style Configurator... One important thing to note is that Notepad++ can't handle special character commands in strings for use with the PRINT statement, such as changing the color of the font, etc. Lower case letters will print their associated "shifted" PETSCII characters, but I don't think the Commodore key based characters can be done in Notepad++ (or any other ASCII/ISO based text editor). Perhaps someone else could tell us!
    3 points
  24. I like Pi2IEC. Since this would basically be the Pi version of the SD2IEC, but with some added benefits.
    3 points
  25. Well, since last night was "algorithm drag racing" I didn't actually implement my HZ conversion in the player, but tonight I did, and it works like a champ. I haven't made a "setspeed" function yet, but using Box16 to poke new speed values directly into RAM, it works like a champ. Once I make a function, I guess I should make a speed change feature in my Sonic demo where you can press up/dn arrow keys, and Sonic will speed up and so will the music. That'd be kind of cool.
    3 points
  26. or Pi-C-IO if you want to sing it
    3 points
  27. So my current thought process is to write assembly or low-level C routines on a Pi Pico or Arduino device, then connect that to software on a Pi or PC via USB. It would cost a few more $$, since you'd need the microcontroller, but then you get the best of both worlds: low level communication via the IEC or User port, and the advanced features a real OS can bring you: TCP/IP transfer, second screen, file storage, and even access to serial devices via the Pi's UART or USB serial devices. In fact, some people are even using the Teensy (an Arduino like board) to run on the C64's expansion port, communicating directly with the system at 2Mhz. So building an IEC/USB bridge and then connecting to a server on a Linux or Windows box should be very possible.
    3 points
  28. Yes, we'll go with that. I'm exceptional. Just please don't qualify it. I have private messages from one party telling me in what ways I'm exceptional, but I really think there were some language issues involved as well.
    3 points
  29. About 7 years ago, a friend of mine started building his own giant collection of arcade machines focused on vector graphics games and pinball. I was into retro gaming/computing a bit at that point, but getting to spend so much time with those machines really gave me the bug bad. I didn't have the money or space to get into arcade machines. I've been a programmer for 20 years and I knew there were still at least a few people out there doing programming for old consoles, so I decided to pickup a 2600, my first childhood console, to learn how it worked and how to program for it. Every 2600 tutorial starts out with a brief history of the 6502, that's where I learned just how big a part of my childhood entertainment that little processor was. It was in basically every console I loved and a bunch of the arcade/pinball machines I liked. Then I learned just how big of a community there still was around, not just retro computing, but even specifically 6502 based machines. Knowing that what I learn for programming the 2600 could be somewhat transferable to so many different machines was really appealing. I learned a ton over the next few years but, eventually, my interest in building anything fun or useful myself waned quite a bit. Now I appreciate what others have built so much more and I love playing the homebrew games. IMO, the retro communities are the best ones to be a part of on the internet these days, and they are what have really kept my interest so high for this long.
    3 points
  30. Version 1.0.0

    150 downloads

    Crazy Lander is another (mostly) BASIC game for Commander X16. We will introduce some new technologies not used before in our projects. It is a variation of Lander type games where we have to guide and land the space capsule to dedicated platforms using thrusters and navigating through natural and man-made obstacles. To make the game more challenging we have to be mindful of the fuel used and land gently. Few highlights: Running in bitmap mode It is a game of precision so we have to assure pixel perfect collision control Animated obstacles unique to each level Music and sound effects Project Specs Emulator Version R.38 Low resolution bitmap mode 320 x 240 in 16 colors on Layer 0 Use the menu system to choose difficulty, turn music on and off, display instructions, quit and of course start the game Animated sprites for displaying capsule as well as thruster exhaust and explosion animation Tile layer 1 is used for HUD and for messages and menus Assembly subroutine for pixel perfect collision detection 4 distinct levels with flexibility to add more Scoring is based on the landing platform multiplier times the remaining fuel Keyboard/Joystick controls Left Arrow / Joystick Left fire left thruster pushing lander right Right Arrow / Joystick Right fire right thruster pushing lander left Space / Fire button main thruster pushing lander up Music in the background using Music Library for BASIC programs Sound effects using direct programming PSG from BASIC using VPOKE 256 color splash screen
    3 points
  31. Making libraries in CA65 is quite straightforward, but your code needs to be configured properly for use in "multi-file" projects. TL;DR: I've posted a reply below with a simple set of example code and build instructions if you want to "just do it" without any further explanations. The basics: Creating a library is essentially just packaging up .o files into a library file. Therefore, your library routines should be written so that they would work as independent source files in any other multi-source-file project. For this howto, let's suppose you want to create a library routine "helloworld" which just uses CHROUT to print "hello world." First, let's consider how you would use this routine if it were written in a stand-alone source file. First, you would create a file "hello.asm" which defines the routine and imports/exports the necessary symbols to perform its task and be reachable from the rest of the project. (more on symbol export/import later). With your routine in its own file, you build your project by listing all source files on the command line: cl65 -t cx16 -o MYPROG.PRG myprog.asm hello.asm Assuming that these assembly files know how to properly import and export the required symbols, this command will build MYPROG.PRG which can now be run. Ostensibly, somewhere in main.asm, there is a call to "helloworld" which prints that string to the screen. This command works pretty much the same for C projects: cl65 -t cx16 -o MYPROG.PRG main.c hello.c Of course, you can mix and match - main.c can use assembly code from assembly sources, e.g: (all-in-one method) cl65 -t cx16 -o MYPROG.PRG myprog.c hello.asm Keep in mind that cl65 is sort of a front-end batch processor command that performs several sub-steps in order to assemble and link your program. Step-by-step building: The reason you can easily mix C and assembly is that behind the scenes, cl65 first compiles/assembles each source file into an object file (.o) An object file is as close as the compiler or assembler can get to the final binary machine code of your program. The one thing that's missing during this step is the final resolution of symbols into the actual memory addresses based on where the program is set up to be loaded in memory. If "helloworld" is built at the beginning of your program, it will be in a different location in memory than it would if it were appended to the end of your program. Thus, it's not known just yet exactly what address to use for any JSR / JMP statements calling your code. Thus the symbol "helloworld:" remains unresolved. The final step of resolving these symbols is done by the linker (ld65). It puts all of the pieces of object code together into the final program. Since the linker is what decides the final locations where everything is actually going to go, it has enough information to turn these remaining unresolved symbols into their final actual memory addresses. It does this, combines all of the object code together, and writes out the .PRG file which can now be loaded into memory and run on the X16. Before, we performed all of these steps at once. However, you can tell cl65 to skip the linking phase on your project and do only the compiling/assembling. You do this by adding the -c command-line switch. This will cause cl65 to stop short of calling the linker to create a complete executable program. Instead, it will simply create the object files from your sources. cl65 -t cx16 -c myprog.c cl65 -t cx16 -c hello.asm Running these two commands produces the files main.o and hello.o - note that you need to run them as separate commands - once for each source file. You can then finish your build just as if these files were the source files: (precompiled method) cl65 -t cx16 -o MYPROG.PRG myprog.o hello.o You could even pre-assemble the helloworld module, but compile directly from source on the main .c file: (hybrid method) cl65 -t cx16 -c hello.asm cl65 -t cx16 -o MYPROG.PRG myprog.c hello.o All of these methods will produce the same executable program MYPROG.PRG - the second and third methods just take multiple steps. These "granular" methods are useful in larger projects. If you compile your sources into object code, then you don't need to recompile everything whenever you only make changes to one source file. Suppose hello.asm did not change, but you made changes to myprog.c - you would recompile myprog.c as above in the (precompiled method), or using the hybrid method, but you would not need to reassemble hello.o as it has not changed. Make is designed to work with this mode of project building. Make will go through and determine which .o files are older than their source files, and only recompile those components. If your project had more auxilliary functions such as "goodbyeworld" and "waitforkey" in their own source files, you would pre-compile them and then add their filenames to the final build command: cl65 -t cx16 -o MYPROG.PRG myprog.c hello.o goodbye.o waitkey.o Now we get to libraries: A library file is simply an archive of .o files all packed together into a single file. Instead of having a bunch of .o files laying around in a directory, you simply have one library file, e.g. "mytools.lib" which includes routines like helloworld: from hello.asm, etc. So this means that to create it, all you need to do is first compile or assemble your sources into object files, and then add the object files to your library archive using the archive tool ar65. ar65 a mytools.lib hello.o goodbye.o waitkey.o Note that these must be object files, not the uncompiled sources. Now, you no longer need to specify all of your individual source files: cl65 -t cx16 -o MYPROG.PRG myprog.c hello.o goodbye.o waitkey.o Instead, you can just reference the library file: cl65 -t cx16 -o MYPROG.PRG myprog.c mytools.lib ld65 will go through the library archive when it needs to resolve symbols such as the names of your functions and variables defined in the archive. What about the symbols? ld65 is able to find the symbols in the archive and use them for any code that needs them. However, the archive only contains the symbols that the sources told the compiler to export. Export means to make this symbol available from outside of this particular source file. If you do not export "helloworld" then that symbol can't be called from myprog.prg. C vs Assembly symbols: The cc65/ca65 suite uses the convention that any symbols in C will be presented to assembly with an underscore _ prepended to them. Thus a variable "foo" in C would be seen as the symbol "_foo" in assembly. Likewise, any symbols with leading underscores in assembly will be presented in C with the leading underscore removed. Thus, your helloworld function could also have another symbol: "_helloworld" which points to the same code. Doing this, you may now call "helloworld()" from C just as you would from assembly. In myprog.c, you would declare it as follows: "extern void helloworld();" That's all you need to do to access a simple function like helloworld: that was actually written in assembly. Had helloworld been written in C, then you could still access it from assembly projects: .import "_helloworld" ... jsr _helloworld If you would like to be able to refer to the same function as helloworld: in assembly and as helloworld() in C, you can simply create a second symbol using the := syntax in your assembly module, and export both symbols: .export "_helloworld" .export "helloworld" _helloworld := helloworld .proc helloworld: near ;code .endproc Variables: Lastly, I should point out that importing and exporting variables works in exactly the same way. Just remember that "variables" and "types" don't exist in assembly, at least not in the sense that they do in C. In assembly, everything is just a reference to an address. So if you reserve some space and give it a symbol name in assembly, and export that symbol, this is enough to pass it between C and assembly. (the _ rules still apply, obviously) .export "foo" .export "_foo" .segment "BSS" foo: .res 2 ; reserve 2 bytes of memory for a 16-bit value, foo _foo := foo ; alias it as _foo for importing into C projects In case you're wondering, BSS segment is for uninitialized variables. I.e.: no values are emitted into the binary created by the build process. It is expected that programs will write values into this memory during run time. Basically, it just reserves memory space without adding size to the actual code. Other segments where you might put data: RODATA : for constants such as strings, lookup tables, etc. .segment "RODATA" message: .asciiz "hello world" DATA : for initialized variables: .segment "DATA" bar: .word $1000 Any concept of type is defined in C, as assembly just doesn't care. In C, you would define foo: "extern uint16_t foo;" or if it's a pointer of some sort, it could be "extern char* foo;" etc. Nutshell: Create the sources for your library just as any other components of a project Compile/assemble them as object files cl65 -t cx16 -s hello.asm Combine the objects into a single archive ar65 a mytools.lib hello.o Create an include file for easy access to the required symbols (optional but recommended) .import "helloworld" (assembly .inc style) extern void helloworld(); (C .h style - be sure to export _helloworld if the source is assembly) Conclusion: These are just the basics, obviously. If you need to pass parameters between C and assembly, you should consult the cc65 documentation for more details on how that's done. While this howto is written as a mixed assembly / C example, there is no reason that your libraries need to be written in assembly. You could have some complicated routines, such as trig.c which creates SIN() COS() and TAN() functions, written entirely in C. Just build trig.c into trig.o and add trig.o to your archive, and it will work. The main thing to remember is to keep the underscores in mind if you're mixing assembly. If pure C, don't worry about it. I hope the community finds this helpful. Cheers!
    3 points
  32. Yes, that is also possible however it requires that you set the carry flag before calling it to get it to return the actual coordinates. Something like this one-liner should work Address 780-783 are the CPU registers and flags just as the Commodore 64, see https://www.c64-wiki.com/wiki/SYS $FFF0 is the kernal PLOT routine, see https://cx16.dk/c64-kernal-routines/plot.html You do not have to switch ROM as the BASIC ROM does indeed have stubs to forward calls to the Kernal ROM just as @Scott Robison mentioned. Above line will of course use more CPU cycles than a simple peek of a memory address, but you should be fairly certain that the addresses do not change.
    3 points
  33. Crazy Lander links have been added to original post.
    3 points
  34. I got my WASD CX16 keyboard today and am more than satisfied. I just wanted it to support the project, but I think this will be my everyday keyboard! Very good quality and looks great too!
    3 points
  35. 20 downloads

    A simple 8-bar loop song bringing you dance floor vibes. To reduce jitter and audio dropouts, run the demo locally. It uses all 16 PSG voices and a couple of FM voices. Would you like to code some graphics to be accommodated by this song? Send me a PM
    3 points
  36. @Scott Robison After watching the 8BG's latest video on PETSCII Robots makes me really want the 128 version now! Again, excellent work sir! Love the features, look, and dual display option. Honestly, I want the X16, Amiga 500, and C128 versions now. Just in case the random browser missed the video:
    3 points
  37. Quite. It's not the second group who are buying the coffee cups that say "It's a Hardware Problem" and "It's a Software Problem" ... it's the Software and Hardware subgroups (respectively) of the first group. And, to be clear, it IS a hardware problem. The software's working JUST as it was intended to.
    3 points
  38. Just watching some youtube and thought it could be good to share some links to videos we find interesting. "Game Development in Eight Bits" by Kevin Zurawel
    3 points
  39. Very nice. My only currently working project (https://www.commanderx16.com/forum/index.php?/files/file/182-petaxian/) still compiles and run fine though there is no reason to rebuild and upload yet. I have made the Git project public (https://github.com/cyborgar/Petaxian) in case anyone want to look at a bit larger Prog8 code example compared to the mostly smaller examples coming with the compiler. I have organized code in multiple files/modules. Though there is no code protection this does require explicit references when crossing modules and that helps a lot with visibility. I have (slowly) started on another clone game (this one is going to copy liberally from Llamasoft's Gridrunner) but I've just gotten started. I'm going to focus on getting it to work on C64 before I'll probably port it to CX16.
    3 points
  40. You could find this topic debated hotly in that closed thread. Here were the reasons to not do crowdfunding as I recall: 1. The primary issue right now appears to be logistics, not money. Taking people's money wouldn't speed that up. Nor will increasing the the visibility of it through advertising. 2. Crowdfunding creates an obligation (at the very least, in David's view) to reach specific targets, and right now there is too much uncertainty to make any promises about the final product. The case they designed not free to the public. You are free to design your own, of course, and 3D print that for personal use.
    2 points
  41. I've actually downloaded the x16 emulator to try to learn BASIC.
    2 points
  42. Version 1.0.0

    14 downloads

    Akalabeth: World of Doom (1979) by Richard Garriott, AppleSoft basic ported to the Commander X16 by Justin Baldock. When starting I recommend you buy some food. This game is very unforgiving. This game was a little tricky to port, it leaves about 124 bytes free of Basic memory. I've added some colour to a few of the enemies. https://github.com/JustinBaldock/X16-Akalabeth Keyboard commands in play. N = Move North / Foward W = Move West / Turn Left E = Move East / Turn Right S = Move South / Turn Around X = Statistics A = NA / Attack - = Pass / Pass P = Toggle Pause D = Climb Ladder / Enter Town/ Enter Castle / Climb Down Q = Quit AKALABETH.PRG akalabeth.bas
    2 points
  43. A (preferably single cycle) DMA transfer into or out of Vera would be the closest you could come, as expanding the SPRAM module built into the FPGA is not going to happen.
    2 points
  44. In some ways this reminds me of what geoLaser did. The C64 had just enough power to compose the PostScript code to be sent to the printer, and then the printer itself was responsible for turning that into a 300dpi raster on the printed page. In these days of GDI printers that don't have that kind of computing horsepower because it's expected that the PC will take care of that, then offloading the rasterizing to a Raspberry Pi seems perfectly reasonable. Technically, a page of US letter paper, edge to edge, at 300dpi, is 'only' 1051875 bytes in monochrome, which would easily fit in the available memory of a 2MB X16. But the dual hardships of USB and multiple incompatible manufacturer-specific GDI printer control protocols mean that it just isn't feasible to do it from the X16 itself.
    2 points
  45. Some consider you exceptional, but I don't know what noun they'd pair with that adjective. I guess making that comment makes me a retro grammar geek.
    2 points
  46. I had a look at a bit of your code on github. I think you might be trying to make the X16 do a little too much of the work going from the abstract ADSR envelope to the volume of a channel at any given moment. Just how granular does your ADSR envelope need to be? Is 1/60th of a second enough, or does it need to be modulating the volume on a shorter time scale than that? Because if your interrupt routine is relying on the VSYNC interrupt, that's all you've got for resolution. And just how long would the total envelope last? surely not more than four seconds, right? The point I'm getting at is maybe look at getting some C++ program to generate a table of values for an ADSR envelope, some volume between 0 and 63 for each 1/60 of a second of the envelope. Then you only need to increment a pointer into a lookup table at the VSYNC interrupt to find the volume for that channel. Multiple channels could be using the same ADSR lookup tables at different points, each having their own indices incremented every interrupt; perhaps mark the last byte of the sound with an FF or 00 in the lookup table. An envelope that lasts half a second would just be a 30+1 byte string of data. A 256 byte table would be an envelope over 4 seconds long. So, for each channel you'd have two bytes for the starting point of the table, another offset byte incremented every VSYNC, and that's it. You'd just define those envelopes externally and turn them into some sort of ADSR.DAT file. Actually, you could have separate tables for Attack, Decay, and Release, and just a regular counter for Sustain. Then the envelope is just pointers to Attack, Decay, a counter for Sustain, and a pointer for Release. The code is a little more involved than just a single ADSR table, but it could give a bit more flexibility in the sounds.
    2 points
  47. I'm in neither category, and you're right, I'm probably a niche in the niche. I'm a software developer who doesn't really want to understand all of the internals if I can avoid it; I just want a simple toolchain that lets me write games that aren't three orders of magnitude worse than most things written for the target platform (I'm fine with being two orders of magnitude worse though). With some minimal software*, the Commodore 64 gave me that toolchain. * The ubiquitous Sprite Editor, Butterfield's Supermon, and Martin Kees' SuperBASIC 64 (which made it trivially easy to use sprites and the SID), helped me write a dozen half-finished BASIC games in the 1980s.
    2 points
  48. Lots of C64 programming insights (some of which are applicable to the X16) but from a different 'angle' to most Dev type channels... https://www.youtube.com/channel/UCdHiji77FlppuNK6xemrsVA/videos
    2 points
  49. @CX16UserSteveC: What kliepatsch says above is definitely the issue. Whenever you're using the "host FS", in the emulation, this is equivalent to having no media inserted into the SD slot. When using host FS, the emulator intercepts calls to LOAD and SAVE and "hyperloads" the data to/from memory. The Kernal is skipped entirely, and the program counter is adjusted to point at whatever address it would after Kernal finishes the LOAD or SAVE routine. So to your program, it's LIKE the Kernal ran, but it actually did not. However: The emulator ONLY hooks load and save. It does NOT hook all other calls that read/write logical channels. Any such calls still execute in the Kernal. Thus, when using the host FS, the Kernal will see device 8 as having no media inserted, and throw an error. That's why your attempts all fail. Because there's no disk in the drive, so to speak. LOAD and SAVE work even when there's no disk in the system because the emulator "miracles" the data directly into (V)RAM when it sees a call to LOAD or SAVE about to happen. There's still no disk. The Kernal just gets skipped so that no error happens. When using SD image: When you DO mount an SD image, the emulator does not perform the hyperload behavior. In this case, calls to LOAD and SAVE are processed by the Kernal as normal along with the other calls for individual byte I/O. Now that there is media inserted into device 8, everything should work properly, including fopen() type actions. You'll find that LOAD and SAVE operations are much slower when using SD images. Hyperloads take "zero" CPU time and the data just appears in memory. Regular loads have to actually retrieve the data by bit banging the SPI connection between VERA and the SD reader. I believe the emulator's transfer speeds to/from SD are an accurate reflection of the real system's loading and saving performance - or at least that's what's been said here in other threads. Further complicating matters: I think there are bugs in the LOAD/SAVE routines in the r38 Kernal as well if the memory address is HIRAM. I think it fails to properly switch banks when loading into HIRAM. I could be wrong in remembering this, as it's been 6 months since I ran afoul of this "SD vs HostFS" quirk. Assuming I'm remembering correctly, it means that if you DO use an SD image, LOAD and SAVE via the Kernal to/from Banked RAM will fail, but bytewise IO should be fine. This whole situation had me really frustrated because I was still getting my sea legs in C and file IO. I thought I was doing something wrong, and it turned out that nope - my program was fine - it was just a nuance of the emulator's behavior. Personally, I think the emulator's behavior should be updated to only do these hyperloads if LOAD and SAVE are being called from interactive-mode BASIC, and that host FS should be treated exactly the same as an SD image. The hyperload feature was obviously intended to be a convenience so you don't have to wait for your program to load.
    2 points
×
×
  • Create New...

Important Information

Please review our Terms of Use