mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-11-26 12:49:21 +00:00
Added Atari 2600 target platform and a minimal sample program. It is functional, but still needs some work.
This commit is contained in:
parent
9693ea125a
commit
26718942e9
@ -32,7 +32,7 @@ import java.util.stream.Collectors;
|
||||
descriptionHeading = "%nDescription:%n%n",
|
||||
parameterListHeading = "%nParameters:%n",
|
||||
optionListHeading = "%nOptions:%n",
|
||||
version = "KickC 0.8.1 BETA"
|
||||
version = "KickC 0.8.2 BETA"
|
||||
)
|
||||
public class KickC implements Callable<Integer> {
|
||||
|
||||
|
10
src/main/kc/target/atari2600.ld
Normal file
10
src/main/kc/target/atari2600.ld
Normal file
@ -0,0 +1,10 @@
|
||||
// Atari 2600 VCS 4K ROM
|
||||
.file [name="%O.prg", type="bin", segments="Code, Vectors"]
|
||||
.segmentdef Code [start=$f800,min=$f800,max=$fff9]
|
||||
.segmentdef Data [start=$80,max=$ff, virtual]
|
||||
.segmentdef Vectors [start=$fffa,max=$ffff]
|
||||
.segment Vectors
|
||||
.word %E // NMI
|
||||
.word %E // RESET
|
||||
.word %E // IRQ
|
||||
.segment Code
|
8
src/main/kc/target/atari2600.tgt
Normal file
8
src/main/kc/target/atari2600.tgt
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"link": "atari2600.ld",
|
||||
"cpu": "MOS6502X",
|
||||
"emulator": "stella",
|
||||
"defines": {
|
||||
"__ATARI2600__": 1
|
||||
}
|
||||
}
|
@ -44,12 +44,16 @@ public class TestPrograms {
|
||||
public TestPrograms() {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAtari2600Min() throws IOException, URISyntaxException {
|
||||
compileAndCompare("atari2600-min.c");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testVic20Raster() throws IOException, URISyntaxException {
|
||||
compileAndCompare("vic20-raster.c");
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testVic20Simple() throws IOException, URISyntaxException {
|
||||
compileAndCompare("vic20-simple.c");
|
||||
|
51
src/test/kc/atari2600-min.c
Normal file
51
src/test/kc/atari2600-min.c
Normal file
@ -0,0 +1,51 @@
|
||||
// Minimal Atari 2600 VCS Program
|
||||
#pragma target(atari2600)
|
||||
|
||||
char * const VSYNC = 0x00;
|
||||
char * const VBLANK = 0x01;
|
||||
char * const WSYNC = 0x02;
|
||||
char * const BACKGROUND_COLOR = 0x09;
|
||||
|
||||
char __mem col=0;
|
||||
|
||||
void main() {
|
||||
while(1) {
|
||||
|
||||
// Vertical Sync
|
||||
// here we generate the signal that tells the TV to move the beam to the top of
|
||||
// the screen so we can start the next frame of video.
|
||||
// The Sync Signal must be on for 3 scanlines.
|
||||
*WSYNC = 2; // Wait for SYNC (halts CPU until end of scanline)
|
||||
*VSYNC = 2; // Accumulator D1=1, turns on Vertical Sync signal
|
||||
*WSYNC = 2; // Wait for Sync - halts CPU until end of 1st scanline of VSYNC
|
||||
*WSYNC = 2; // wait until end of 2nd scanline of VSYNC
|
||||
*WSYNC = 0; // wait until end of 3rd scanline of VSYNC
|
||||
*VSYNC = 0; // Accumulator D1=0, turns off Vertical Sync signal
|
||||
|
||||
// Vertical Blank - game logic
|
||||
// Since we don't have any yet, just delay
|
||||
for(char i=0;i<37;i++) {
|
||||
*WSYNC = 0; // Wait for SYNC (halts CPU until end of scanline)
|
||||
}
|
||||
|
||||
// Screen - display logic
|
||||
// Update the registers in TIA (the video chip) in order to generate what the player sees.
|
||||
// For now we're just going to output 192 colored scanlines lines so we have something to see.
|
||||
*VBLANK = 0; // D1=1, turns off Vertical Blank signal (image output on)
|
||||
char c = col++;
|
||||
for(char i=0;i<192;i++) {
|
||||
*WSYNC = 0; // Wait for SYNC (halts CPU until end of scanline)
|
||||
*BACKGROUND_COLOR = c++; // Set background color
|
||||
}
|
||||
|
||||
// Overscan - game logic
|
||||
// Since we don't have any yet, just delay
|
||||
*WSYNC = 0; // Wait for SYNC (halts CPU until end of scanline)
|
||||
*VBLANK = 2; // // D1=1 turns image output off
|
||||
*BACKGROUND_COLOR = 0;
|
||||
for(char i=0;i<07;i++) {
|
||||
*WSYNC = 0; // Wait for SYNC (halts CPU until end of scanline)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
113
src/test/ref/atari2600-min.asm
Normal file
113
src/test/ref/atari2600-min.asm
Normal file
@ -0,0 +1,113 @@
|
||||
// Minimal Atari 2600 VCS Program
|
||||
// Atari 2600 VCS 4K ROM
|
||||
.file [name="atari2600-min.prg", type="bin", segments="Code, Vectors"]
|
||||
.segmentdef Code [start=$f800,min=$f800,max=$fff9]
|
||||
.segmentdef Data [start=$80,max=$ff, virtual]
|
||||
.segmentdef Vectors [start=$fffa,max=$ffff]
|
||||
.segment Vectors
|
||||
.word main // NMI
|
||||
.word main // RESET
|
||||
.word main // IRQ
|
||||
.segment Code
|
||||
|
||||
.label VSYNC = 0
|
||||
.label VBLANK = 1
|
||||
.label WSYNC = 2
|
||||
.label BACKGROUND_COLOR = 9
|
||||
.segment Code
|
||||
main: {
|
||||
lda #0
|
||||
sta col
|
||||
__b2:
|
||||
// *WSYNC = 2
|
||||
// Vertical Sync
|
||||
// here we generate the signal that tells the TV to move the beam to the top of
|
||||
// the screen so we can start the next frame of video.
|
||||
// The Sync Signal must be on for 3 scanlines.
|
||||
lda #2
|
||||
sta WSYNC
|
||||
// *VSYNC = 2
|
||||
// Wait for SYNC (halts CPU until end of scanline)
|
||||
sta VSYNC
|
||||
// *WSYNC = 2
|
||||
// Accumulator D1=1, turns on Vertical Sync signal
|
||||
sta WSYNC
|
||||
// Wait for Sync - halts CPU until end of 1st scanline of VSYNC
|
||||
sta WSYNC
|
||||
// *WSYNC = 0
|
||||
// wait until end of 2nd scanline of VSYNC
|
||||
lda #0
|
||||
sta WSYNC
|
||||
// *VSYNC = 0
|
||||
// wait until end of 3rd scanline of VSYNC
|
||||
sta VSYNC
|
||||
tax
|
||||
// Vertical Blank - game logic
|
||||
// Since we don't have any yet, just delay
|
||||
__b3:
|
||||
// for(char i=0;i<37;i++)
|
||||
cpx #$25
|
||||
bcc __b4
|
||||
// *VBLANK = 0
|
||||
// Screen - display logic
|
||||
// Update the registers in TIA (the video chip) in order to generate what the player sees.
|
||||
// For now we're just going to output 192 colored scanlines lines so we have something to see.
|
||||
lda #0
|
||||
sta VBLANK
|
||||
// c = col++
|
||||
// D1=1, turns off Vertical Blank signal (image output on)
|
||||
ldx col
|
||||
inc col
|
||||
tay
|
||||
__b6:
|
||||
// for(char i=0;i<192;i++)
|
||||
cpy #$c0
|
||||
bcc __b7
|
||||
// *WSYNC = 0
|
||||
// Overscan - game logic
|
||||
// Since we don't have any yet, just delay
|
||||
lda #0
|
||||
sta WSYNC
|
||||
// *VBLANK = 2
|
||||
// Wait for SYNC (halts CPU until end of scanline)
|
||||
lda #2
|
||||
sta VBLANK
|
||||
// *BACKGROUND_COLOR = 0
|
||||
// // D1=1 turns image output off
|
||||
lda #0
|
||||
sta BACKGROUND_COLOR
|
||||
tax
|
||||
__b9:
|
||||
// for(char i=0;i<07;i++)
|
||||
cpx #7
|
||||
bcc __b10
|
||||
jmp __b2
|
||||
__b10:
|
||||
// *WSYNC = 0
|
||||
lda #0
|
||||
sta WSYNC
|
||||
// for(char i=0;i<07;i++)
|
||||
inx
|
||||
jmp __b9
|
||||
__b7:
|
||||
// *WSYNC = 0
|
||||
lda #0
|
||||
sta WSYNC
|
||||
// *BACKGROUND_COLOR = c++
|
||||
// Wait for SYNC (halts CPU until end of scanline)
|
||||
stx BACKGROUND_COLOR
|
||||
// *BACKGROUND_COLOR = c++;
|
||||
inx
|
||||
// for(char i=0;i<192;i++)
|
||||
iny
|
||||
jmp __b6
|
||||
__b4:
|
||||
// *WSYNC = 0
|
||||
lda #0
|
||||
sta WSYNC
|
||||
// for(char i=0;i<37;i++)
|
||||
inx
|
||||
jmp __b3
|
||||
}
|
||||
.segment Data
|
||||
col: .byte 0
|
62
src/test/ref/atari2600-min.cfg
Normal file
62
src/test/ref/atari2600-min.cfg
Normal file
@ -0,0 +1,62 @@
|
||||
@begin: scope:[] from
|
||||
[0] phi()
|
||||
to:@1
|
||||
@1: scope:[] from @begin
|
||||
[1] phi()
|
||||
[2] call main
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
[3] phi()
|
||||
|
||||
(void()) main()
|
||||
main: scope:[main] from @1
|
||||
[4] phi()
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main main::@9
|
||||
[5] (byte) col#12 ← phi( main/(byte) 0 main::@9/(byte) col#1 )
|
||||
to:main::@2
|
||||
main::@2: scope:[main] from main::@1
|
||||
[6] *((const nomodify byte*) WSYNC) ← (byte) 2
|
||||
[7] *((const nomodify byte*) VSYNC) ← (byte) 2
|
||||
[8] *((const nomodify byte*) WSYNC) ← (byte) 2
|
||||
[9] *((const nomodify byte*) WSYNC) ← (byte) 2
|
||||
[10] *((const nomodify byte*) WSYNC) ← (byte) 0
|
||||
[11] *((const nomodify byte*) VSYNC) ← (byte) 0
|
||||
to:main::@3
|
||||
main::@3: scope:[main] from main::@2 main::@4
|
||||
[12] (byte) main::i#2 ← phi( main::@2/(byte) 0 main::@4/(byte) main::i#1 )
|
||||
[13] if((byte) main::i#2<(byte) $25) goto main::@4
|
||||
to:main::@5
|
||||
main::@5: scope:[main] from main::@3
|
||||
[14] *((const nomodify byte*) VBLANK) ← (byte) 0
|
||||
[15] (byte) main::c#0 ← (byte) col#12
|
||||
[16] (byte) col#1 ← ++ (byte) col#12
|
||||
to:main::@6
|
||||
main::@6: scope:[main] from main::@5 main::@7
|
||||
[17] (byte) main::c#2 ← phi( main::@5/(byte) main::c#0 main::@7/(byte) main::c#1 )
|
||||
[17] (byte) main::i1#2 ← phi( main::@5/(byte) 0 main::@7/(byte) main::i1#1 )
|
||||
[18] if((byte) main::i1#2<(byte) $c0) goto main::@7
|
||||
to:main::@8
|
||||
main::@8: scope:[main] from main::@6
|
||||
[19] *((const nomodify byte*) WSYNC) ← (byte) 0
|
||||
[20] *((const nomodify byte*) VBLANK) ← (byte) 2
|
||||
[21] *((const nomodify byte*) BACKGROUND_COLOR) ← (byte) 0
|
||||
to:main::@9
|
||||
main::@9: scope:[main] from main::@10 main::@8
|
||||
[22] (byte) main::i2#2 ← phi( main::@10/(byte) main::i2#1 main::@8/(byte) 0 )
|
||||
[23] if((byte) main::i2#2<(byte) 7) goto main::@10
|
||||
to:main::@1
|
||||
main::@10: scope:[main] from main::@9
|
||||
[24] *((const nomodify byte*) WSYNC) ← (byte) 0
|
||||
[25] (byte) main::i2#1 ← ++ (byte) main::i2#2
|
||||
to:main::@9
|
||||
main::@7: scope:[main] from main::@6
|
||||
[26] *((const nomodify byte*) WSYNC) ← (byte) 0
|
||||
[27] *((const nomodify byte*) BACKGROUND_COLOR) ← (byte) main::c#2
|
||||
[28] (byte) main::c#1 ← ++ (byte) main::c#2
|
||||
[29] (byte) main::i1#1 ← ++ (byte) main::i1#2
|
||||
to:main::@6
|
||||
main::@4: scope:[main] from main::@3
|
||||
[30] *((const nomodify byte*) WSYNC) ← (byte) 0
|
||||
[31] (byte) main::i#1 ← ++ (byte) main::i#2
|
||||
to:main::@3
|
1095
src/test/ref/atari2600-min.log
Normal file
1095
src/test/ref/atari2600-min.log
Normal file
File diff suppressed because it is too large
Load Diff
40
src/test/ref/atari2600-min.sym
Normal file
40
src/test/ref/atari2600-min.sym
Normal file
@ -0,0 +1,40 @@
|
||||
(label) @1
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(const nomodify byte*) BACKGROUND_COLOR = (byte*) 9
|
||||
(const nomodify byte*) VBLANK = (byte*) 1
|
||||
(const nomodify byte*) VSYNC = (byte*) 0
|
||||
(const nomodify byte*) WSYNC = (byte*) 2
|
||||
(byte) col
|
||||
(byte) col#1 col mem[1] 78.71428571428571
|
||||
(byte) col#12 col mem[1] 92.53846153846155
|
||||
(void()) main()
|
||||
(label) main::@1
|
||||
(label) main::@10
|
||||
(label) main::@2
|
||||
(label) main::@3
|
||||
(label) main::@4
|
||||
(label) main::@5
|
||||
(label) main::@6
|
||||
(label) main::@7
|
||||
(label) main::@8
|
||||
(label) main::@9
|
||||
(byte) main::c
|
||||
(byte) main::c#0 reg byte x 101.0
|
||||
(byte) main::c#1 reg byte x 1001.0
|
||||
(byte) main::c#2 reg byte x 776.0
|
||||
(byte) main::i
|
||||
(byte) main::i#1 reg byte x 2002.0
|
||||
(byte) main::i#2 reg byte x 1001.0
|
||||
(byte) main::i1
|
||||
(byte) main::i1#1 reg byte y 2002.0
|
||||
(byte) main::i1#2 reg byte y 600.5999999999999
|
||||
(byte) main::i2
|
||||
(byte) main::i2#1 reg byte x 2002.0
|
||||
(byte) main::i2#2 reg byte x 1001.0
|
||||
|
||||
mem[1] [ col#12 col#1 ]
|
||||
reg byte x [ main::i#2 main::i#1 ]
|
||||
reg byte y [ main::i1#2 main::i1#1 ]
|
||||
reg byte x [ main::c#2 main::c#0 main::c#1 ]
|
||||
reg byte x [ main::i2#2 main::i2#1 ]
|
Loading…
Reference in New Issue
Block a user