AUDIO
MAIN SYSTEM
VIDEO
CPU
128kb RAM
CPU
64kb RAM
DSP
PPU
64kb VRAM
512b CGRAM
544b OAM
CARTRIDGE
1-4MB ROM
AUDIO
MAIN SYSTEM
VIDEO
CPU
128kb RAM
CPU
64kb RAM
DSP
PPU
64kb VRAM
512b CGRAM
544b OAM
CARTRIDGE
1-4MB ROM
DMA!!
main() { printf("Hello World"); }
public void Render(int width, int height, Sync sync, double time)
{
GL.ClearColor(Color.FromArgb(0, 0, 68));
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
GL.LoadIdentity();
GL.Translate(0.0f, 0.0f, -25.0f);
var color = Color.FromArgb(113, 232, 81);
Helpers.Bar(color, 0.0f, -1.0f, 3.0f, 0.5f);
Helpers.Bar(color, 0.0f, 0.0f, 3.0f, 0.5f);
Helpers.Bar(color, 0.0f, 1.0f, 3.0f, 0.5f);
}
; x = voice data offset (trashes y)
ReadPatternByte:
mov a, VoiceState::CompType + x
bne +
; Uncompressed
call ReadNextByte
ret
; Rle (run length, symbol)
+: mov a, VoiceState::CompParam1 + x
bne +
; Start next run
call ReadNextByte
push a
call ReadNextByte
mov VoiceState::CompParam2 + x, a
pop a
+: ; Read next byte from run
dec a
mov VoiceState::CompParam1 + x, a
mov a, VoiceState::CompParam2 + x
ret
; x = voice data offset (trashes y)
ReadNextByte:
mov a, VoiceState::PatternAddrLow + x
mov CurrentByteAddrLow, a
clrc
adc a, #$01
mov VoiceState::PatternAddrLow + x, a
mov a, VoiceState::PatternAddrHigh + x
mov CurrentByteAddrHigh, a
adc a, #$00
mov VoiceState::PatternAddrHigh + x, a
mov y, #$00
mov a, [CurrentByteAddr] + y
ret
; a = note, x = voice data offset
SetNote:
asl a
mov y, a
mov a, !MusicData.PitchTable + y
mov VoiceState::PitchLow + x, a
inc y
mov a, !MusicData.PitchTable + y
mov VoiceState::PitchHigh + x, a
ret
; a = instrument number
LoadInstrumentDataAddr:
push x
dec a
asl a
mov x, a
mov a, !MusicData.InstrumentTable + x
mov CurrentInstrAddrLow, a
inc x
mov a, !MusicData.InstrumentTable + x
mov CurrentInstrAddrHigh, a
pop x
ret
EffectArpeggio:
pop x
mov y, #$00
mov a, VoiceState::EffectParam2 + x
cmp a, #$01
bne ++++
mov a, VoiceState::EffectParam1 + x
xcn a
mov y, a
++++: cmp a, #$02
bne ++++
mov a, VoiceState::EffectParam1 + x
mov y, a
++++: mov a, y
and a, #$0f
clrc
adc a, VoiceState::Note + x ; TODO: Handle overflows
call SetNote
mov a, VoiceState::EffectParam2 + x
inc a
cmp a, #$03
bcc ++++
mov a, #$00
++++: mov VoiceState::EffectParam2 + x, a
jmp EffectEnd
EffectPitchUp:
pop x
mov a, VoiceState::EffectParam1 + x
xcn a
mov y, a
and a, #$f0
clrc
adc a, VoiceState::PitchLow + x
mov VoiceState::PitchLow + x, a
mov a, y
and a, #$0f
adc a, VoiceState::PitchHigh + x
mov VoiceState::PitchHigh + x, a
jmp EffectEnd
EffectPitchDown:
pop x
mov a, VoiceState::EffectParam1 + x
xcn a
mov y, a
and a, #$f0
mov FxWork1, a
mov a, VoiceState::PitchLow + x
setc
sbc a, FxWork1
mov VoiceState::PitchLow + x, a
mov a, y
and a, #$0f
mov FxWork1, a
mov a, VoiceState::PitchHigh + x
sbc a, FxWork1
mov VoiceState::PitchHigh + x, a
jmp EffectEnd
// Execute macro
:ClearScreen($0400,$20) // Since they are encapsulated in a scope
:ClearScreen($4400,$20) // the two resulting loop labels don’t
// interfere
// Define macro
.macro ClearScreen(screen,clearByte) {
lda #clearByte
ldx #0
Loop: // The loop label can’t be seen from the outside
sta screen,x
sta screen+$100,x
sta screen+$200,x
sta screen+$300,x
inx
bne Loop
}
LoadPaletteData address length data LoadVramData address length data
EndOfFrame
EndOfTransmission
LoadPaletteData 0x00 0x16 [...] LoadVramData 0x2000 0x0800 [...] EndOfFrame