1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-09-08 17:54:40 +00:00

Added NMI sample example.

This commit is contained in:
jespergravgaard 2019-08-07 21:35:40 +02:00
parent 7a49ded40c
commit db3e77d8fd
8 changed files with 1334 additions and 0 deletions

View File

@ -179,10 +179,16 @@ const byte CIA_TIMER_CONTROL_B_TOD_ALARM_SET = 0b10000000;
// The vector used when the KERNAL serves IRQ interrupts
const void()** KERNEL_IRQ = $0314;
// The vector used when the KERNAL serves NMI interrupts
const void()** KERNEL_NMI = $0318;
// The vector used when the HARDWARE serves IRQ interrupts
const void()** HARDWARE_IRQ = $fffe;
// The SID volume
const byte* SID_VOLUME = $d418;
// The colors of the C64
const byte BLACK = $0;
const byte WHITE = $1;

View File

@ -36,6 +36,11 @@ public class TestPrograms {
public TestPrograms() {
}
@Test
public void testNmiSamples() throws IOException, URISyntaxException {
compileAndCompare("examples/nmisamples/nmisamples");
}
@Test
public void testEncodingLiteralChar() throws IOException, URISyntaxException {
compileAndCompare("encoding-literal-char");

Binary file not shown.

View File

@ -0,0 +1,53 @@
// NMI Sample Player using the SID volume register
// Code by Scan of Desire (Richard-William Loerakker)
// Sample from ART OF NOISE: MOMENTS IN LOVE
import "c64"
const unsigned int SAMPLE_SIZE = 0x6100;
char[SAMPLE_SIZE] SAMPLE = kickasm(resource "moments_sample.bin") {{ .import binary "moments_sample.bin" }};
volatile char* sample = SAMPLE;
void main() {
// Boosting 8580 Digis
// See https://gist.github.com/munshkr/30f35e39905e63876ff7 (line 909)
asm {
lda #$ff
sta $d406
sta $d40d
sta $d414
lda #$49
sta $d404
sta $d40b
sta $d412
}
asm { sei }
*CIA2_INTERRUPT = CIA_INTERRUPT_CLEAR;
*KERNEL_NMI = &nmi;
*CIA2_TIMER_A = 0x88; // speed
*CIA2_INTERRUPT = 0x81;
*CIA2_TIMER_A_CONTROL = 0x01;
asm { cli }
}
interrupt(hardware_all) void nmi() {
(*BORDERCOL)++;
asm { lda CIA2_INTERRUPT }
*SID_VOLUME = *sample & $0f;
*KERNEL_NMI = &nmi2;
(*BORDERCOL)--;
}
interrupt(hardware_all) void nmi2() {
(*BORDERCOL)++;
asm { lda CIA2_INTERRUPT }
*SID_VOLUME = *sample >> 4;
sample++;
if (>sample == >(SAMPLE+$6100)) {
sample = SAMPLE;
}
*KERNEL_NMI = &nmi;
(*BORDERCOL)--;
}

View File

@ -0,0 +1,121 @@
// NMI Sample Player using the SID volume register
// Code by Scan of Desire (Richard-William Loerakker)
// Sample from ART OF NOISE: MOMENTS IN LOVE
.pc = $801 "Basic"
:BasicUpstart(bbegin)
.pc = $80d "Program"
.label BORDERCOL = $d020
// CIA #2 Timer A Value (16-bit)
.label CIA2_TIMER_A = $dd04
// CIA #2 Interrupt Status & Control Register
.label CIA2_INTERRUPT = $dd0d
// CIA #2 Timer A Control Register
.label CIA2_TIMER_A_CONTROL = $dd0e
// Value that disables all CIA interrupts when stored to the CIA Interrupt registers
.const CIA_INTERRUPT_CLEAR = $7f
// The vector used when the KERNAL serves NMI interrupts
.label KERNEL_NMI = $318
// The SID volume
.label SID_VOLUME = $d418
.const SAMPLE_SIZE = $6100
.label sample = 2
bbegin:
lda #<SAMPLE
sta.z sample
lda #>SAMPLE
sta.z sample+1
jsr main
rts
main: {
// Boosting 8580 Digis
// See https://gist.github.com/munshkr/30f35e39905e63876ff7 (line 909)
lda #$ff
sta $d406
sta $d40d
sta $d414
lda #$49
sta $d404
sta $d40b
sta $d412
sei
lda #CIA_INTERRUPT_CLEAR
sta CIA2_INTERRUPT
lda #<nmi
sta KERNEL_NMI
lda #>nmi
sta KERNEL_NMI+1
lda #0
sta CIA2_TIMER_A+1
lda #<$88
sta CIA2_TIMER_A
// speed
lda #$81
sta CIA2_INTERRUPT
lda #1
sta CIA2_TIMER_A_CONTROL
cli
rts
}
nmi2: {
sta rega+1
stx regx+1
sty regy+1
inc BORDERCOL
lda CIA2_INTERRUPT
ldy #0
lda (sample),y
lsr
lsr
lsr
lsr
sta SID_VOLUME
inc.z sample
bne !+
inc.z sample+1
!:
lda.z sample+1
cmp #>SAMPLE+$6100
bne b1
lda #<SAMPLE
sta.z sample
lda #>SAMPLE
sta.z sample+1
b1:
lda #<nmi
sta KERNEL_NMI
lda #>nmi
sta KERNEL_NMI+1
dec BORDERCOL
rega:
lda #00
regx:
ldx #00
regy:
ldy #00
rti
}
nmi: {
sta rega+1
stx regx+1
sty regy+1
inc BORDERCOL
lda CIA2_INTERRUPT
lda #$f
ldy #0
and (sample),y
sta SID_VOLUME
lda #<nmi2
sta KERNEL_NMI
lda #>nmi2
sta KERNEL_NMI+1
dec BORDERCOL
rega:
lda #00
regx:
ldx #00
regy:
ldy #00
rti
}
SAMPLE:
.import binary "moments_sample.bin"

View File

@ -0,0 +1,56 @@
@begin: scope:[] from
[0] phi()
to:@1
@1: scope:[] from @begin
[1] (byte*) sample#0 ← (const byte[SAMPLE_SIZE#0]) SAMPLE#0
to:@2
@2: scope:[] from @1
[2] phi()
[3] call main
to:@end
@end: scope:[] from @2
[4] phi()
main: scope:[main] from @2
asm { lda#$ff sta$d406 sta$d40d sta$d414 lda#$49 sta$d404 sta$d40b sta$d412 }
asm { sei }
[7] *((const byte*) CIA2_INTERRUPT#0) ← (const byte) CIA_INTERRUPT_CLEAR#0
[8] *((const void()**) KERNEL_NMI#0) ← &interrupt(HARDWARE_ALL)(void()) nmi()
[9] *((const word*) CIA2_TIMER_A#0) ← (byte) $88
[10] *((const byte*) CIA2_INTERRUPT#0) ← (byte) $81
[11] *((const byte*) CIA2_TIMER_A_CONTROL#0) ← (byte) 1
asm { cli }
to:main::@return
main::@return: scope:[main] from main
[13] return
to:@return
nmi2: scope:[nmi2] from
[14] *((const byte*) BORDERCOL#0) ← ++ *((const byte*) BORDERCOL#0)
asm { ldaCIA2_INTERRUPT }
[16] (byte~) nmi2::$0 ← *((byte*) sample#0) >> (byte) 4
[17] *((const byte*) SID_VOLUME#0) ← (byte~) nmi2::$0
[18] (byte*) sample#1 ← ++ (byte*) sample#0
[19] (byte~) nmi2::$1 ← > (byte*) sample#1
[20] if((byte~) nmi2::$1!=>(const byte[SAMPLE_SIZE#0]) SAMPLE#0+(word) $6100) goto nmi2::@1
to:nmi2::@2
nmi2::@2: scope:[nmi2] from nmi2
[21] (byte*) sample#2 ← (const byte[SAMPLE_SIZE#0]) SAMPLE#0
to:nmi2::@1
nmi2::@1: scope:[nmi2] from nmi2 nmi2::@2
[22] (byte*) sample#3 ← phi( nmi2/(byte*) sample#1 nmi2::@2/(byte*) sample#2 )
[23] *((const void()**) KERNEL_NMI#0) ← &interrupt(HARDWARE_ALL)(void()) nmi()
[24] *((const byte*) BORDERCOL#0) ← -- *((const byte*) BORDERCOL#0)
to:nmi2::@return
nmi2::@return: scope:[nmi2] from nmi2::@1
[25] return
to:@return
nmi: scope:[nmi] from
[26] *((const byte*) BORDERCOL#0) ← ++ *((const byte*) BORDERCOL#0)
asm { ldaCIA2_INTERRUPT }
[28] (byte~) nmi::$0 ← *((byte*) sample#0) & (byte) $f
[29] *((const byte*) SID_VOLUME#0) ← (byte~) nmi::$0
[30] *((const void()**) KERNEL_NMI#0) ← &interrupt(HARDWARE_ALL)(void()) nmi2()
[31] *((const byte*) BORDERCOL#0) ← -- *((const byte*) BORDERCOL#0)
to:nmi::@return
nmi::@return: scope:[nmi] from nmi
[32] return
to:@return

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,43 @@
(label) @1
(label) @2
(label) @begin
(label) @end
(byte*) BORDERCOL
(const byte*) BORDERCOL#0 BORDERCOL = (byte*) 53280
(byte*) CIA2_INTERRUPT
(const byte*) CIA2_INTERRUPT#0 CIA2_INTERRUPT = (byte*) 56589
(word*) CIA2_TIMER_A
(const word*) CIA2_TIMER_A#0 CIA2_TIMER_A = (word*) 56580
(byte*) CIA2_TIMER_A_CONTROL
(const byte*) CIA2_TIMER_A_CONTROL#0 CIA2_TIMER_A_CONTROL = (byte*) 56590
(byte) CIA_INTERRUPT_CLEAR
(const byte) CIA_INTERRUPT_CLEAR#0 CIA_INTERRUPT_CLEAR = (byte) $7f
(void()**) KERNEL_NMI
(const void()**) KERNEL_NMI#0 KERNEL_NMI = (void()**) 792
(byte[SAMPLE_SIZE#0]) SAMPLE
(const byte[SAMPLE_SIZE#0]) SAMPLE#0 SAMPLE = kickasm {{ .import binary "moments_sample.bin" }}
(word) SAMPLE_SIZE
(const word) SAMPLE_SIZE#0 SAMPLE_SIZE = (word) $6100
(byte*) SID_VOLUME
(const byte*) SID_VOLUME#0 SID_VOLUME = (byte*) 54296
(void()) main()
(label) main::@return
interrupt(HARDWARE_ALL)(void()) nmi()
(byte~) nmi::$0 reg byte a 4.0
(label) nmi::@return
interrupt(HARDWARE_ALL)(void()) nmi2()
(byte~) nmi2::$0 reg byte a 4.0
(byte~) nmi2::$1 reg byte a 4.0
(label) nmi2::@1
(label) nmi2::@2
(label) nmi2::@return
(byte*) sample
(byte*) sample#0 sample zp ZP_WORD:2 1.3333333333333333
(byte*) sample#1 sample zp ZP_WORD:2 2.0
(byte*) sample#2 sample zp ZP_WORD:2 4.0
(byte*) sample#3 sample zp ZP_WORD:2 40.0
zp ZP_WORD:2 [ sample#0 sample#3 sample#1 sample#2 ]
reg byte a [ nmi2::$0 ]
reg byte a [ nmi2::$1 ]
reg byte a [ nmi::$0 ]