Jump to content


  • Posts

  • Joined

  • Last visited

  • Days Won


Snickers11001001 last won the day on January 7

Snickers11001001 had the most liked content!

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

Snickers11001001's Achievements


Newbie (1/14)

Very Popular Rare Week One Done One Month Later

Recent Badges




Community Answers

  1. Wow, that's actually quite mature already. Is there a 'howto' to try it out on the X16 emulator? Is it a custom rom or something?
  2. Love, love love these projects. If I can posit any advice from the cheap seats (i.e., from someone like me who absolutely has no ability to make such a thing, but who is a user of BASIC and enjoys it), it would be this: There are things that BASIC needs but not everything from 'gen 3' basics like visual basic need to be included or are feasible. Remember at bottom this platform is still an 8 bit machine with no prefetch, no branch prediction, no modern pipelining, no cache memory, almost no maths, and a 16 bit address space. Its running at 8mhz, maybe, unless they (a) can't get it to work at that speed, in which case it will be a 4mhz machine, or (b) if they release the faster X8 FPGA version (that won't have the banked memory, ZP space, or space in the pages below $0800 that the X16 has) which probably won't be able to fit all your features anyway. Just take a look at the discussion near the end of the "BASIC 2 vs BASIC 7" thread and the impact of just a few more instructions in the byte fetching/parsing core between the C64 and the later Plus/4 and C128 in terms of the negative impact on performance for the later machines with better BASICs. If you're having to bank-switch, for example, surely it takes a hit. Tokenizing a lot of stuff inline (e.g., constants, jumps, variable memory locations) is a great idea, but I suggest a simple escape code structure using byte codes. Parser finds, say petscii code for '@' not inside quotes and it knows the next two bytes are a small-int in 16 bit signed format; it finds petscii code for [english pound] (which looks a bit like a mutant F), it knows the next 5 bytes are the exponent and mantisa for a float; it finds token for 'goto' or 'gosub' it knows the next two bytes are the actual 6 bit address for the destination of the jump in the code, instead of the petscii numeric representation of a line number; it finds petscii code for "%" it knows the next two bytes are the 16 bit address to the value followed by the name of an int style variable in memory. (At execution it just needs to fetch the value, during LIST operation it grabs the variable name at that address+2 until it hits the terminator). Yeah, OK, the modern way to do many of these things would be with a hash table, but I caution you to consider the performance impact on an 8 bit machine. If you use the idea of inlining 16 bit addresses for jump locations to speed up execution, of course, then there are other issues. With line numbers, your "LIST" routine needs only follow the 16 bit address and then grab the line number at that address and put it on the screen during a 'LIST"; but with LABLES, you will need to set up a data structure (probably a linked list) that can be consulted by the interpreter during code LIST operations to regurgitate the labels or line numbers when the user lists the code and that metadata has to get saved with the program. That's actually a better place to use banked memory... the performance cost of swapping banks is not as important when listing the code. I don't think its feasible to tokenize at runtime, it needs to be as you enter things.
  3. Check out the links provided they really do help. RND takes one of three parameters. RND(1) [or any positive parameter, generally] generates a random number between 0 and 1 based on the next 'seed' -- an internal number that is behind the maths of this pseudo-random number generator) -- and updates the seed. RND(0) does the same thing but uses a byte of the internal clock as the seed. RND with a negative number [i.e., RND(-2.39997)] uses the supplied parameter as, in essence, the seed. Which means calling it with the same neg. number gives the same random number between 0 and 1. So A=RND(1) is the basic function. But to get what you want, you have to do something with that random decimal value it spits out, which again is generated as a number greater than 0 and less than 1. If you want an integer (no decimal fraction) number from 0 to 9 then reason it out: You need to us the INT() function too. And you take that decimal number between 0 and 1 and multiply it by the highest number you want + 1 (assuming you want the entire range of 0 to the highest number) R=INT(RND(1)*10) will cause the variable 'R' to have a random number from 0 to 9. (Think about it, even if the RND() function itself returns .99999999 multiplying it by 10 gets you 9.999999 and then taking the INT() function of that returns a 9. About the INT() function. Its not 'rounding' in the sense you might be used to, i.e., in the event the fractional component is greater than .5 it does not 'round up' Instead, INT() is a 'floor' style rounding, which means the output is always LESS than the input. With a positive number, say INT(9.9999), it returns the next integer that is LESS than the value supplied, which is to say it disregards the decimal fraction, i.e., it returns 9 in this example. But with a negative number, say INT(-10.999), it ALSO returns the next integer that is LESS than the value supplied, i.e., -11 here. All of that is why INT (RND(1)*10) gives you a value between 0 and 9 So, if you want it to return two random single digit numbers, let's say you want to put them in variables to use later you need two calls of this function. 10 N1=INT(RND(1)*10) 20 N2=INT(RND(1)*10) 30 PRINT N1, N2 EDIT: Just read more carefully and saw your thing about wanting either a 1 or 2... that means you multiply by the DIFFERENCE between the lowest number and highest number you want +1. To have a lower boundary you just add it as the base to your calculations, i.e, N1 = 1+INT(RND(1)*2) N2 = 1+INT(RND(1)*2) To test these, try this FOR/NEXT loop from the command line: FOR L=1 TO 10: PRINT 1+INT(RND(1)*2):NEXT After it prints its sequence of 1s and 2s, scroll your cursor up and hit enter on the same command again and watch the sequence change. Viola. Pseudo randoms of either 1 or 2. EDIT: Geez, I was pretty sloppy in answering this... so I went in and fixed some typos and added clarity. Substance is the same, it just reads better.
  4. I'm glad you're still working on this. I don't care what happens with the X8/X16 thing/release. I will play this game on the emulator you specify if that's all that's available. Looks cool and its still really neat to watch someone move a project along like this in sorta real time.
  5. Strider... good one. I remember watching some play-throughs of the NES version on youtube some time ago, and laughing at what the 'changes in battle' effect did to their video compression. Artifacts galore! LOL.
  6. As long as it fits in 256 bytes! Now you're triggering the dark underbelly of nostalgia, LOL! I remember a buddy gnashing his teeth for days trying to fit a sprite animator thing he was making/adapting into the tape buffer on his C64. I think he wound up throwing away the custom character set for his game and using the C64 ram at $C000 since it was 4K of space.
  7. I don't think there would 'be' any other 8K. As I understand it (and I should emphasize that as Bruce mentioned, its all unofficially as a result of surmises and speculations given we don't have formal docs of X8 functionality), there's no "ram under rom" under the BASIC and KERNAL on X8, so I don't see how there'd be an alternative 'page 1' of RAM at $A000 to $BFFF. There's only 128K of RAM for the entire FPGA, 64K of it is VERA vid mem and the other 64K is mapped to the 65c02 address space. If the stuff at $A000 to $BFFF is 'kernal buffers and cbdos' stuff then that is what exists at that location. There's no where else that could hold 8K of what the X16 maps in as 'bank 1' ram for that range. Its really only a headache for those who utilize BASIC and want to use helpers / wedges etc. I would presume if you don't need kernal or basic, you can use their address space as ram (and absent kernal's need for $A000 to $BFFF you could use that too) ... but I must be clear that's just a presumption on my part. The X8 FPGA could be set up so its logic simply does not permit writes to those ranges. I have no idea how to read verilog and the sources are 6 months old anyhow. And don't forget that even though VERA is reduced to 64K video ram on the X8, if you're not using all of it for display, some of it can be a convenient place to park 'pure data' -- sounds, gfx, music data, etc., especially with what should be fairly easy access through that 256 byte window. In the end, I'll buy the X8 if its all that comes out, but I'm personally cheering for and wanting to hold out for the X16 as it was spec'd -- whether in through-hole or FPGA only -- for many reasons.
  8. Sheesh. So on the X8, we would lose the ability to put ML code BASIC helpers/wedges at $0400 to $04FF, $0500 to $05ff, and part of page at $700. Additionally, since there's no longer banked ram, the 8K at $A000 to $BFFF that on the X16 is 'page 0' of the banked ram and reserved 'for KERNAL/CBDOS variables and buffers" is the only RAM in that range. So, uh, if you want to include a machine code routine as a BASIC helper (such as sound effects like the simplest sound library, or a little routine to handle collision detection, or your own interrupt handler for music, or a wedge to implement some currently unavailable bitmap stuff from BASIC (e.g., circle, flood fill)), etc., where do we put it? Sounds like it has to go in the 39K of actual BASIC memory now. Anyone know the 'pokes' for the X16/X8 in terms of the pointer to move down the top of BASIC memory like addresses $37 and $38 on the C64?!
  9. I've been going through Matt's videos. I am _not_ an assembly guru or even passably good at it, so forgive me if I'm all wet. But there's 2 data ports on the VERA (well, at least X16 VERA, the X8 is a whole different ball of wax apparently). You have to set things up to point to the VERA address and port you want and the stride. The VERA memory range includes (a) the video memory; (b) the PSG registers; and (c) the sprite registers. (also palette). Three different activities in the structure of a game code and only two ports into that space, which require set-up to read/write. That's all I meant and is the sort of contention I had in mind when I wrote that. It seemed to me that if you've got a routine using VERA data ports 0 and 1 to move some video data in preparation for a scroll or context change, or to work the VERA sprite registers; then if an interrupt for music fires, the music routine must include code to save the what data port was selected, the VERA address the data port had been pointing at as well as the stride value, and then restore all this before exiting back to regular execution. Otherwise when the program flow gets back to what was happening before the audio code, the data port/stride stuff will have wrong values. Seems to me you'd have to store/restore: $9F20, $9F21, $9F22, and $9F25 at least. Looks like those cover the L,M,H portions of the VERA address, the inc/dec stuff, and the port select bit. So to store that's 4 LDA absolutes at 4 cycles each, plus 4 STAs at 4 cycles each (3 each if you have 4 ZP addresses you can set aside to be temp storage for these or I guess you could push them on the stack if you're sure it will have room), and the same when your music handler is ready to exit, the reverse to put everything back. Reading through this now, I realize I'm stuck in the 'long ago' and thinking at C64 cpu speeds and the old 'cycles per refresh' thing, but those cycles are probably of negligible impact with the 8mhz clock on the X16. Still, until I heard the extra timing considerations on the YM chip in this thread, I had thought it might be easier to just have a music routine that needn't concern itself with saving/restoring VERA state info and just play the dang music. Obviously very naïve thinking, as it turns out. I meant no offense at all at what you're doing, and I thought I made it clear that I love this demo. I hope my ramblings weren't taken as any sort of criticism. Cheers.
  10. Do you have any links to the source of those addresses/pages on the X8? Is the memory at page $0600 affected? What 'part' of page $0700 is also spoken for?
  11. This is awesome! Great work. How well do you think this can mesh with using vera moving sprites, moving/scrollling tiles, and updating lots of vid data? I think that's been my concern about using VERA for music and not just sound effects: Contention and resource traffic jams especially for doing a game. The nice thing about the YM chip it has seemed to me in theory was the possibility of having some nice interrupt driven music that did not need to use a bunch of cycles each interrupt storing and restoring all the VERA registers and state information. I'll be following this with interest!
  12. Absolutely disgusting. Short version, its tulip mania (on purpose) designed to puff up a bubble...
  13. I'm working through Matt's videos, and the format would be hard to follow -- stop, pause, 'oh what did that say' - or 'dang it, I didn't catch that part of the code on the screen, gotta rewind' -- except that he also did some color coding which he incorporated into his scripts, and then includes links to the code etc in the description. That's pretty helpful. I think with any sort of code, you've got to have a written form that folks can look at and refer to beyond just video, especially if they want to go back and look later while they're trying something out. BTW, don't use the 'convert/optimize" thread I did as any sort of a template. I was pretty good at BASIC back in the day but then had a career in a completely non computer field before retiring . This year I picked up BASIC again for the first time and the optimization thread was literally me writing that up AS I was going through the process of trying to figure out how to implement optimization ideas I had spotted. (I revisited it again recently as my game project had to go on hiatus until the 'change in product direction' kerfuffle sorts itself out). But that entire exercise would have been better and more concise if I had planned and outlined it more from the start, and then applied the 20% rule (i.e., 'cut 20% from your first draft no matter what' to force brevity and focus) before putting everything up. As it was, I had some notes on things to try and a sort of order, and just typed right into the forum 'new post' window until I covered what I wanted before making a few screen shots and that was it. No editorial processes at all and it probably shows. Looking forward to your series.
  14. EDITED: Well, I tried both the Plus/4 and C128 emulators and, on both, the following worked fine: 10: A$="" 20 A=ASC(A$) 30 PRINT A So, just a matter of tracing the assembly code for ASC() and seeing where the difference is. ('just' hahaha)
  • Create New...

Important Information

Please review our Terms of Use