-
Content Count
1,048 -
Joined
-
Last visited
-
Days Won
1
Content Type
Profiles
Member Map
Forums
Blogs
Gallery
Calendar
Store
Everything posted by andym00
-
I mentioned earlier in a post about wanting to change the timer position using SKCTL, but unfortunately Atari800WinPlus doesn't do the timers properly so I can't test out the SKCTL thing for moving Pokey, and Altirra doesn't support the Pot apparently.. I just wanted to shift it so that I could position it ideally, so that once interrupt entry had completed that the Pot value had only just incremented, giving me as much time as possible on the desired scanline, whilst having all the irq entry and gubbins handled on the previous line.. The timer interrupts seem to happen at a different position to the Pot incrementing.. In Altirra I see the (default?) Pokey timer 15Khz position was just off the right of the visible screen (if I remember right).. The Pot values seems to increment right at the very start of the visible scanline, that's if Atari800Win isn't lying to me, which it probably is
-
I remember the 64 sprite one in particular.. Anyway, without wanting to lay my entire plan out on the floor, I've done the numbers for what I want to do, and it works out, the plan is ~32, whether or not I hit that we shall see Either way, it's my little expedition into Atari land, slightly deluded or not
-
But the overhead of initialising a timer based system of interrupts is less than the DLI based setup, plus the DLI still has to do the same work to respond to the fact it might have taken longer than expected to complete the sprite reloads.. At least with the timer irq you can check that, and alter things dynamically rather than having a predetermined DLI set.. Plus this means you can leave the DLIs free for whatever screen stuff you want, and the timer irqs will handle that easily with minimal glitching of players.. But you only check the Pot value in a timer interrupt, so it's just lda #next_raster_interrupt cmp Pot7 bcc straight_into_next_irq beq straight_into_next_irq sec sbc Pot7 sbc #1 sta AUDF4 sta STIMER I know there's a flaw in that logic, that the pot might count up in between the reads, but for now I'm just getting this working.. Turning that above code into something bullet-proof and faster will come later.. And yes, you've probably had kittens see that I'm hitting STIMER round about 32 times a frame I've yet to listen to the results it has on Pokey music and sound, but I'm fairly confident it's going to be quite comical Without that though it's a guessing game since you have to rely stuff the new timer value you need for the next interval in the previous interrupt, which means things get wonky because you have no idea how long your processing just took, well you do, but there's no way to correct it immediately.. I tried first of all just running completely with calculated timer deltas for the frame, but it can't recover fast enough if something knocks it out of kilter, like a DLI taking an ungodly amount of time, or (god forbid) code in the DLI doing WSYNCs during the frame.. So I figured I'd live with whatever horrendous side-effects hammering STIMER will have in Pokey sound, for now
-
I was thinking bitmap mode, with compiled sprites, and having a background thread (using ~10% of the cpu) to compile sprites on demand, well, actually in advance of where they're needed.. Typically a game isn't going to have so many active sprite frames in use at once.. NRVs sprite stuff is very nice, and he does shift more than 12.. ~24 of the Marios if I recall right, but granted that was at half vertical res. though.. And it was also running in NTSC as well if I remember so I imagine there's some slack in there from a PAL point of view.. But given he's already shifting more data than I plan, in less time than I intend, I don't see why it's not possible.. To me the numbers sitting in my note-pad work out I didn't mean Timers as in Timers that generate interrupts, but literally just a timer.. I'm just using it to keep track of the current screen raster line (with one line resolution as opposed to VCOUNTs 2 line resolution), so I can adjust my timer interrupts relative to it, and know if I've fallen behind schedule, and should start short circuiting interrupts and jumping into the next one rather faff around setting the timers for the next interval.. Just so the thing can respond dynamically to DLIs and other crud happening on the screen. The results are better then using VCOUNT, plus I can start the count from 0 zero whenever I like, which means I can calibrate everything to *MY* idea of y positioning.. Edit: Weird, just dug up NRVs sprite demo on YouTube.. I could have sworn there were more sprites than that ? Bugger.. Maybe I've got it confused with another one of his sprite samples he did with that engine.. Either way, numbers work for me
-
I don't know, Atariksi mentioned it in the 'thread from hell' when him and I were squabbling about timers.. Then it popped back into my head the other day when I was getting frustrated with VCOUNT and it's half resolution.. A quick chat with Atariksi about it, and there's nothing to it.. Just hit POTGO, and then it starts counting up once per scanline.. If there's no paddle connected they finish at 228.. So you just start them with an IRQ at the top of your displayed screen, and then you have a scanline accurate raster line register (that is directly related to the current visible screen scanline or offset by however much you want) whenever you want it in POT7 I used POT7, since I hope no-one will ever run my stuff on a 400/800 and have a paddle connected.. Though I guess you'd use whichever number you liked best between 4-7
-
Don't bring this nonsense in here as well, please.. I'm just very curious to explore the possibilities of the various modes they have here, with lots of sprites in the process.. Without wishing to sound like I'm swapping sides, they have a big advantage over the 64 and that's not being limited to 21 pixel high sprites which are a fecking bugger at times, and sometime the damn things are too wide as well Would have preferred 16x16 sprites (plus a bit to flag the 9th bit for the sprite pointer) and maybe 12 sprites, or at the very least a register to write to allow termination of a sprite and the shutdown of its DMA when it's 6bit internal address counter matches.. But it's not going to happen, and you can easily see why they chose 24x21.. Anyway, I don't want 10 pixel wide players Mr.SmartyPants I just want to see what you can do with this machine, that's all
-
Some rough figures.. I'll assume 16 pixel high players for simplicity.. For each line of player image copied, you're looking at 9 cycles for a typical copy, so if your sprites are 16 lines high then ~144 cycles for each one, plus a little overhead.. You also have to add 4 cycles per player scanline to be erased, but that's fairly straight forward.. So ~208 cycles per 16pixel high player (that's copy and erase).. So very roughly 2 and a bit scanlines of raster time per sprite is what I think.. You could speed the copy up enourmously on mission critical sprites at the expense of some memory, but I'd leave that until absolutely necessary.. So in 100 lines off screen, you can probably manage to copy over 50 16 pixel high players, but since it's a multiplexer and you've got the sprites sorted, you don't have to be limited by the VBL time.. You can just carry on copying whilst the frame is drawing and hope you stay ahead of the raster.. So god know how many you could really manage.. More sprites = more sorting time = more IRQ chain prep time = more raster time.. But I think you could easily manage ~100, *IF* you can find the screen real estate to do something useful with that many given the limits per line without giving the multiplexer a coronary in the process Personally I've got a few idea, and whilst I was initially gagging to throw 100 odd sprites on screen, I've changed my mind a bit now, and want to try to go for 32+ soft-sprites plus 32+ player overlays (and the wacky PRIOR stuff) for them.. I've got a few ideas for things you might say As for trying to reduce memory copies by trying to keep the data in one player for as long as possible, good luck I've been working on a multiplexer but haven't actually implemented the image copying yet because it's been so much fun doing raster interrupts using the Timers And besides the copying stuff is a fairly known quantity and will probably remain out until quite late.. But it works, and quite nicely, thanks to Atariksi's idea of using the Pots as a timer[1].. So thanks Atariksi, I owe you a beer one day for that [1] Except Altirra has no Pot emulation whatsoever The Pots just go straight to 228 once you hit POTGO, which is a bummer since it's the only one with cycle accurate emulation of the Timers.. And then Atari800Win Plus, the Pots work, but has only scanline emulation of Timers, so I can't try out Pokey SKCTL initialisation shifting thing to move my irqs around along the scanline..
-
The wacky TQA syntax always takes me 5 times as long to decipher as normal assembler Though the above example is quite tame in comparison to some of the stuff I've seen you post
-
I'd love to see something like this.. How about something like Codebase64 ? Something that people can contribute to and improve upon fairly easily.. At the moment with my adventure into Atari land I feel like I'm reinventing the wheel and searching for information can be really tedious at times, and I'm loathe to spark up a thread here everytime I've got a question
-
Stone the crows... Whoever let that ship should be damned for all eternity.. How on earth does a game ship with sprites like that ??? edit: And for the potential comedians I meant the Atari sprites
-
It's not realistically going to happen on the 64.. The 11Khz just sits badly against the badlines that occur.. And there's nothing you can do about that unless you want to get really messy You can abort the badlines, which means in text mode that you'll have the same character line and colour ram repeated down the screen, which isn't so useful since you run of out character sets very quickly.. In bitmap mode, it's a bit different, you can abort the DMA on each bad line, and the graphics fetches still take place, just no new colour fetches, so you end up with a 320x200 or 160x200 with no badlines, just in interrupts every 8 lines to abort the DMA.. You can have more colours, since you can allow a one off fetch of colour data, which is then held for every line of the screen, so in bitmap mode, you could have a vertical scrolling game with nice colour graduations going our horizontally, and still no bad lines.. This really isn't used very often and it's a royal bugger to setup Practically, 7.8Khz is your limit.. The 64s CPU is just to slow to go to 15.6Khz using IRQs and having the screen on, *AND* having zero cycle jitter on the interrupt.. We have only 23 spare cycles on a bad line, which just doesn't cut it.. and the interrupt overhead is too much for a 1Mhz processor.. 7 cycles to enter, 6 cycles to preserve a register, then 9 to ACK + RTI from the interrupt (assuming your using the jmp $DD0C[1].. That's not including the jitter from the previous instruction, so add another possible 7 onto that, and we've got a minimum of 29 cycles, and that's before we've done anything.. There's just no practical way to deliver 15.6Khz audio on the 64, we just don't have the cycles for it.. And if you want to go for 8bit playback you can stick an extra 24 cycles onto each sample outputted, 30cycles if you go for 12bit playback, though the crappy 4bit volume stuff is of course only 4 cycles.. One option to do it though, is to have the sample playback in 8 line kernel chunks[3], but then you burn too much CPU time, and then you'll have to do whatever computation you need in the IRQs to make up for raping the CPU like that.. And the interrupt code on the last line to get the sample out, and to bail from the irq is critical to how much time you get left with because there's a big angry bad-line coming for your arse just cycles away.. But then you could squeeze 15.6Khz out of it, but (if I remember rightly the last time I tried this) I ended up with 12 (maybe 11) spare cycles per 8 lines of display, which isn't particularly useful to do anything with.. Lol, 468 cycles per frame left, enough to run a very minimal music driver for the task in question but fecking useless for anything else.. I know I've just handed a nice arsenal of ammunition to the hostiles, but that's life, and we all know we've got a crappy CPU on the 64, that's what actually makes life fun in some ways.. Already in the short few days that I've been playing on the A8, I'm feeling like I've got more CPU power than I know what to do with[4] So there you go.. 11Khz (which to be fair doesn't sit nicely on the A8 either), just shouldn't be done, unless you switch the screen off.. There's far to much jitter you'll be fighting against.. 3.9Khz, 7.8Khz, 15.6Khz are your best options... And doing the bad line aborts[2], with samples playing (at non-scanline ratios) I don't think has even been done before, so maybe you'll be the first Another option is to disable screen DMA completely, and put the VIC into a state whereby it will only display sprites[5], then there's no badlines, and what you want is doable, but again the sprite DMA will cause jitter with you 11Khz desire, but with 15.6Khz it's very doable, especially if you fill the screen with sprites since it'll provide you with the interrupt stabilisation source you need through the 19cycle sprite dma block.. [1] You place the RTI instruction into the serial shift register on the CIA, then jump to it to exit the interrupt, and due to 6502 behaviour it will hit the ack register after the RTI instruction which saves 1 cycle [2] Though thinking about it now, I've a vague memory of a way to do this in a one off fashion without using stacks of IRQs, hmmmm, should go check, though maybe it's my addled memory letting me down.. I'm sure one of the demo gods will correct me on this [3] The added benefit of this is that you use the end of the previous bad-line dma to stabilise your interrupt perfectly, since you set the timer to occur during the badline period, the cpu will be perfectly aligned and the interrupt start the cycle dma finishes, which saves a few cycles on stabilising your interrupt.. This can also be down with using the sprite dma period as well.. [4] And I've started to keep a diary of my real-world observations of programming the A8 versus C64, the pros & cons of both, from a programmers point of view, which I'll put somewhere sometime [5] Only one interrupt per frame with a lot of leeway in terms of scanlines so it can be disturbed by audio interrupts with no problems, but it *HAS* to be done each frame once you've started the process otherwise VIC will vanish up it's own arse and shutdown totally until you reset the machine..
-
There's a long way to go: http://mybroadband.co.za/vb/showthread.php?t=18194 303165 Posts.. 20211 Pages.. It all depends if Emkay can hold out for another 295122 posts
-
Raiden 4 actually looks quite tame and fairly conventional I think of the Danmaku genre as being slightly different than your conventional schmup.. The good shooters like GigaWing, DangunFeveron, DoDonPachi, Gunwange are kind of more like puzzle games, working out the right path through the bullets whilst trying to keep your chain going (if the games has a chain that is) and maximising your score.. For example in DDP it's not just about annihiliating everything that arrives, but timing it just right so your chain stays alive, which means holding back on your destruction of the enemy sometimes.. They're about achieving perfection through the scoring mechanism, which adds another element to the gameplay that's (to quote Dangun) "Maximum Fever!" They are also pretty forgiving at heart what with the size of the collision detection with the player, more often than not just the single pixel at the centre of the players ship.. Now this is a proper shooter
-
Bingo! I didn't realise I had to reset after mounting a Disk Image.. I've only been loading XEXs onto it so far which start straight up.. Oops And it makes sense since I was wondering how it would handle a disk swap for Joyride.. Not enough coffee and cigarettes yet this morning Erm, as for a test app, only have a test harness of the stuff I'm working on that isn't exactly a full on unit test of the instruction But I can put one together for you..
-
Don't get me wrong I wasn't criticising you for doing it like that, from reading your blog and your motivations and reasoning for the entire project it makes perfect sense how you're going ahead with it.. And I completely understand your pain with implementing the illegals properly But once again, thank you so much for Altirra, it an absolute godsend in comparison to Atari800Win
-
Think of a buch of Ataris, connected via the Joystick interface... Ditto for the C64 With each 64 having 4 1541s attached
-
Reading the blog for Altirra it seems a lot of stuff uses illegal opcodes.. It appears (to me anyway) that he's only implementing stuff as and when he finds something that doesn't work, which seems to be the process with the illegals at least, and that it'll get added when something doesn't work with it, which is a fair enough approach.. But no worries, I'm quite happy changing Altirra locally here and adding the opcode(s) myself, once I figure out what not to break in the process edit: I get nothing from Altirra opening Joyide.. Open Image->Joyride - Disk 1.atr and then it just sits there with nothing happening Ah but it works in Atari800Win AH! Did it really have to have the Joyride music in it!
-
I meant add in my previous post about SBX.. So, okay, I mean to add or subtract an immediate value from X.. I mean in the exact thing that brought this up, there's code that looks like this, where I'm computing the delta values for all the Timer4 interrupts down the screen, and pre-calculating how many to reload on each line, rather than use VCOUNT directly.. It was a test to see which will actually perform better, one block of solid code doing the preparations (and possible timer fixing live down the screen), or doing it all live in the interrupts.. Anyway.. At the end of this routine, I need carry to be clear, and also to add 4 to X, and branch back possibly.. Can you see a quicker way than using sbx ? And bear in mind the carry will be set from the previous sbc.. lda .y_base+4,x sbc .y_base+0,x sbc #1 sta .d_base+0,x lda #3 sta .g_base,x lda #-4 sbx #-4 bmi .loop rts I only set A to -4 because that's me It could be #$ff or any value, as long as it doesn't clear any set bits in X, and very often you find you have just the right value in A a lot of the time.. Of course you can set A to other values, so in the above example I could set a to $f which'd then be (X&15) - 4 which is useful as well at times.. I'm sure you can see the possiblities Anyway, job done, and since it ignores the carry flag in its operation (but sets it correctly) it's nice and quick, and open other avenues to how you might structure code.. There's other cases as well, but it's handy when you want to and a value and then add or subtract from it.. More often than not you find a use for it that you didn't expect.. A good real world example would be this from a speech synthesiser I was playing with that synthesised 5 waveforms for the speech synthesis.. It was just a test because I was curious what sine waves used for speech synths would sound like, and like the idea of having them morph into tones.. Anyway.. ; Osc #0 lda #$ff ; 2 .phs0 ldx #0 ; 2 .f0_0 sbx #$ff ; 2 .v0_0 ldy sine_00,x ; 4 sty .s00+1 ; 4 .f0_1 sbx #$ff ; 2 .v0_1 ldy sine_00,x ; 4 sty .s01+1 ; 4 .f0_2 sbx #$ff ; 2 .v0_2 ldy sine_00,x ; 4 sty .s02+1 ; 4 .f0_3 sbx #$ff ; 2 .v0_3 ldy sine_00,x ; 4 sty .s03+1 ; 4 stx .phs0+1 ; 4 (48) Yes the tuning was slightly wonky, but it did the job, and with an average of 12 cycles per sample per oscillator I couldn't see any faster way of doing it.. SAX is a bugger, there's few times it's that useful, but if you want to write stuff to memory, and'ed with a constant which you'll have in either A or X it's a time saver..
-
No, they designed it so C64 could make pretty graphical interpretations of your simulation data, whilst the 1541(s) did all the simulation work You're comparing the A8 against the worlds first truly scaleable parallel processing machine.. Just add another 1541 to gain another 6502 processor!! Visionary!! Just think, RoF using 4 1541s
-
I wouldn't say softsynth in the strictest sense (to avoid the weight of this thread coming crashing down on me), but there's lots of things which are dependent upon the exact cycles they're changed.. Things like using the test bit to restart waveforms, used in things like hard restarts so that the waveform as at known point when the Envelope Generator starts to run to avoid clicks, or even to add the clicks if you desire.. Plus the waveform sample playback techniques, and also all the additional waveforms available through setting multiple bits of the waveform select.. All of the 'mixed' waveforms are available on 6581 but some are very very quiet in comparison to the 8580, and it's something that's being used a lot nowadays and gives SID a very large range of timbres, more so than you might think.. But all of the existing techniques that have been used on SID to make sound do work in ResidFP.. Even the latest waveform sample playback stuff works in there now, so anything that will play on a 64 will play in ResidFP correctly.. There are many cool things you can do with SID, one of the coolest (imho) is running FM on the voices, then SID just changes its character like you wouldn't believe.. I've been working on a player that provides just this, providing 3 audio rate modulators with a usual Yamaha Carrier Modulator setup with modulation envelopes, depths, scaling etc and the various usual Yamaha modulator waveforms but that's on hold for the time being due to other projects.. Anyway, enough sales pitch.. But a majority of the effort goes into emulating SID at a very high rate, essentially 1Mhz, and then downsampling the result to get an accurate version of what you would hear on a real SID, and a lot of that time is spent processing the filters which they've tried to accurately model on various SID chips.. If you look in the player you can see the various filter models you have available, all of which are slightly different, but then again that's what it's like on the real SID.. You've got different options in ResidFP of how the downsampling takes places, but even the cheapest one is still a bit of a CPU hog..
-
Hmmm, if that's the case I'll add some CPU detection to anything serious I'd write for the Atari, and support 6502C, 65C02 and 65816..
-
I just use them as matter of course on the 64.. SBX is a little gem.. How else can you add immediate values to X nice and quickly ? DCP is incredibly useful.. SAX as well.. Other than that, the others I hardly use.. In this particular case using SBX gave me above a 4 cycles advantage over not using it in a a loop that took ~52 cycles and had to be run 32 times.. It's an advantage I figure Anyway, that's the least of my worries considering the vast differences I get running on Atari800Win and Altirra and playing with the Timers edit: And of course LAX which is an absolute diamond of an instruction..
-
Ah, okay, I'd missed the blog part there.. I'll add it myself, it seems simple enough to add a kStateAdd (that does the add without borrow) which is what it seems to need to implement that instruction, or at least implement that stage of the instruction..
-
It would appear that opcode $CB is missing any kind of implementation in cpu6502ill.cpp AXS (SBX) [sAX] ~~~~~~~~~~~~~~~ AND X register with accumulator and store result in X regis- ter, then subtract byte from X register (without borrow). Status flags: N,Z,C Addressing |Mnemonics |Opc|Sz | n ------------|-----------|---|---|--- Immediate |AXS #arg |$CB| 2 | 2
-
I'm getting my hands dirty with the A8s for the first time, and I've just run into the fact that I'm getting Illegal instruction errors from Altirra running my code, when I use illegal opcodes.. CPU: Illegal instruction hit: 23AD (10559:249,108) PC=23AC A=FD X=E0 Y=00 S=F8 P=B5 (N I C) 23AC: CB bad The opcode in question is SBX (also called AXS and SAX as well depending upon which side of the fence you hail), which is listed as being present on the 6502C on this this webpage.. The CPU model in Altirra is set to 6502C, and the 'Enable Illegal Instructions' box is ticked.. Is there something I've missed in the configuration maybe ? Or possibly that I've missed something really obvious here ? Just for reference, and to ensure it's not the assembler ballsing it up, I took exactly the same file, assembled it for a C64 and ran it no problems, so my monies on me missing something glaringly obvious, or Altirra is having a bad day.. And the code runs fine if I replace the illegals with regular but slower work arounds.. edit: Aha, it works fine in Atari800Win Plus..
