Topic: Apple II
Apple II 1-Bit
You are not logged in. Please login or register.
Apple II 1-Bit
From our forum member krüe: http://krue.net/stitch/
Seriously, I think the Apple II has one of the worst 1-bit setups. Not being able to "set" the 1-bit state directly is a major hassle.
... hmm, one day when I have too much free time I might learn 65xx asm
Radio-86RK should be even worse. It controls the speaker with DI and EI commands, and has DMA bursts constantly running in background to refresh screen and memory (so tape routines only works while display is disabled).
I guess Apple II's inability to set speaker state directly renders Phaser-like engines undoable, but on the other hand Apple II coders often use PWM techniques to get like ~8 'volume' levels, in Fuzz Click fashion.
6502 assembly is actually super easy, the trick is to switch the thinking patterns after x86/8080/Z80, i.e. from register-oriented to memory-oriented programming.
Radio-86RK does indeed sound scary.
Another thing that used to give me a good headache are those devices that output a fixed (preferably high-pitched) frequency (Channel F, or the Sharp Pocket thingies, for example). Thankfully, Zilog's squeeker algo is great at overriding those. Might be also a good candidate for Radio-86RK, since it doesn't seem to require exact timing.
I actually did write a sound routine for the VIC20 once. Couldn't find anything on how to create a 16-bit pointer, so I wrote some really ugly self-modifying code... then later, I looked it up and realized that I'd written it exactly like it's supposed to be done. I have to admit that kind of shaped my experience with MOS products Aside from VIC20, one machine I really want to tackle though is the Atari VCS, so I guess I'll have to wrap my head around 6502 (or 6507, in this case) at some point.
The only 'proper' way to make 16-bit pointer on 6502 is just LDA/STA (ZP),y. Self-modifying code is another option, but that's only for systems with enough RAM for code.
Thought it may be actually useful to sketch out a simple 6502 sound routine. This is Music Box like, two 8-bit channels, interleaving, written in the dumbest way. Tested on NES:
;all referenced vars are 8-bit, located in zero page lda #0 sta <CH1_CNT sta <CH2_CNT sta <CH1_OUT sta <CH2_OUT lda #55 sta <CH1_DIV lda #150 sta <CH2_DIV sound_loop: dec <CH1_CNT ;5 decrement channel 1 counter bne no_inc_1 ;2/3 if no overflow, skip through steady timing code lda <CH1_DIV ;2 load new counter value sta <CH1_CNT ;2 store to the counter inc <CH1_OUT ;5 invert channel output polarity jmp skip_1 ;3 continue no_inc_1: nop ;2 timing nop ;2 nop ;2 nop ;2 jmp skip_1 ;3 skip_1: lda <CH1_OUT ;2 kind of sbc a,a on carry ror a ;2 lda <CH1_OUT ;2 sbc <CH1_OUT ;2 here we get 0 or 255 depending from the original least significant bit, slow, but universal sta DMC_RAW ;4 dump it directly to DAC, other systems may need an AND here dec <CH2_CNT ;5 the same for second channel bne no_inc_2 ;2/3 lda <CH2_DIV ;2 sta <CH2_CNT ;2 inc <CH2_OUT ;5 jmp skip_2 ;3 no_inc_2: nop ;2 timing nop ;2 nop ;2 nop ;2 jmp skip_2 ;3 skip_2: lda <CH2_OUT ;2 kind of sbc a,a on carry ror a ;2 lda <CH2_OUT ;2 sbc <CH2_OUT ;2 sta DMC_RAW ;4 jmp sound_loop ;3=67t
Don't forget about the nasty 6502 quirk, if any branch (except BVS) is crossing 256-byte page, it adds an extra cycle. So it is better to align starting address and keep eye on it. Not that 1 extra cycle will matter a lot, but if there is complex branch logic, it will make difference.