mirror of
https://gitlab.com/camelot/kickc.git
synced 2025-01-17 00:30:07 +00:00
Added Atari 2600 Sprite test.
This commit is contained in:
parent
c9965b2cc7
commit
d714c6ab4c
@ -1,6 +1,19 @@
|
||||
// Atari Television Interface Adaptor (TIA)
|
||||
// https://en.wikipedia.org/wiki/Television_Interface_Adaptor
|
||||
// http://www.qotile.net/minidig/docs/stella.pdf
|
||||
// Based on https://github.com/munsie/dasm/blob/master/machines/atari2600/vcs.h
|
||||
|
||||
// The number of CPU cycles per scanline
|
||||
const char CYCLES_PER_SCANLINE = 76;
|
||||
|
||||
// The TIA WSYNC register (for access from inline ASM)
|
||||
char* const TIA_WSYNC = 0x02;
|
||||
// The TIA RESP0 register (for access from inline ASM)
|
||||
char* const TIA_RESP0 = 0x10;
|
||||
// The TIA RESP1 register (for access from inline ASM)
|
||||
char* const TIA_RESP1 = 0x11;
|
||||
// The TIA HMP0 register (for access from inline ASM)
|
||||
char* const TIA_HMP0 = 0x20;
|
||||
|
||||
struct ATARI_TIA_WRITE {
|
||||
// $00 0000 00x0 Vertical Sync Set-Clear
|
||||
@ -61,9 +74,9 @@ struct ATARI_TIA_WRITE {
|
||||
char GRP0;
|
||||
// $1C xxxx xxxx Graphics Register Player 1
|
||||
char GRP1;
|
||||
// $1D 0000 00x0 Graphics Enable Missle 0
|
||||
// $1D 0000 00x0 Graphics Enable Missile 0
|
||||
char ENAM0;
|
||||
// $1E 0000 00x0 Graphics Enable Missle 1
|
||||
// $1E 0000 00x0 Graphics Enable Missile 1
|
||||
char ENAM1;
|
||||
// $1F 0000 00x0 Graphics Enable Ball
|
||||
char ENABL;
|
||||
@ -71,9 +84,9 @@ struct ATARI_TIA_WRITE {
|
||||
char HMP0;
|
||||
// $21 xxxx 0000 Horizontal Motion Player 1
|
||||
char HMP1;
|
||||
// $22 xxxx 0000 Horizontal Motion Missle 0
|
||||
// $22 xxxx 0000 Horizontal Motion Missile 0
|
||||
char HMM0;
|
||||
// $23 xxxx 0000 Horizontal Motion Missle 1
|
||||
// $23 xxxx 0000 Horizontal Motion Missile 1
|
||||
char HMM1;
|
||||
// $24 xxxx 0000 Horizontal Motion Ball
|
||||
char HMBL;
|
||||
@ -83,9 +96,9 @@ struct ATARI_TIA_WRITE {
|
||||
char VDELP1;
|
||||
// $27 0000 000x Vertical Delay Ball
|
||||
char VDELBL;
|
||||
// $28 0000 00x0 Reset Missle 0 to Player 0
|
||||
// $28 0000 00x0 Reset Missile 0 to Player 0
|
||||
char RESMP0;
|
||||
// $29 0000 00x0 Reset Missle 1 to Player 1
|
||||
// $29 0000 00x0 Reset Missile 1 to Player 1
|
||||
char RESMP1;
|
||||
// $2A ---- ---- Apply Horizontal Motion
|
||||
char HMOVE;
|
||||
@ -126,3 +139,4 @@ struct ATARI_TIA_READ {
|
||||
// $0D x000 0000 Read Input (Trigger) 1
|
||||
char INPT5;
|
||||
};
|
||||
|
||||
|
@ -12,3 +12,4 @@ struct ATARI_TIA_READ * const TIA_READ = 0x00;
|
||||
|
||||
// Atari RIOT registers
|
||||
struct MOS6532_RIOT * const RIOT = 0x280;
|
||||
|
||||
|
@ -44,6 +44,11 @@ public class TestPrograms {
|
||||
public TestPrograms() {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAtari2600Sprites() throws IOException, URISyntaxException {
|
||||
compileAndCompare("examples/atari2600/atari2600-sprites.c");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAtari2600Demo() throws IOException, URISyntaxException {
|
||||
compileAndCompare("examples/atari2600/atari2600-demo.c");
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Demonstration Atari 2600 VCS Program
|
||||
// Minimal Atari 2600 VCS Program
|
||||
// Source: https://atariage.com/forums/blogs/entry/11109-step-1-generate-a-stable-display/
|
||||
#pragma target(atari2600)
|
||||
#include <atari2600.h>
|
||||
@ -7,49 +7,66 @@
|
||||
#pragma data_seg(Vars)
|
||||
char __mem idx=0;
|
||||
|
||||
// Data
|
||||
// Data
|
||||
#pragma data_seg(Data)
|
||||
const char align(0x100) SINTABLE[0x100] = kickasm {{
|
||||
const char SINTABLE[0x100] = kickasm {{
|
||||
.fill $100, round(127.5+127.5*sin(2*PI*i/256))
|
||||
}};
|
||||
|
||||
void main() {
|
||||
|
||||
TIA->PF0 = 0b10100000;
|
||||
TIA->PF1 = 0b01010101;
|
||||
TIA->PF2 = 0b10101010;
|
||||
TIA->COLUPF = 0x55;
|
||||
|
||||
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.
|
||||
TIA->VSYNC = 2; // Accumulator D1=1, turns on Vertical Sync signal
|
||||
TIA->VSYNC = 2; // D1=1, turns on Vertical Sync signal
|
||||
RIOT->TIM64T = (41*76)/64; // Set timer to wait 41 lines
|
||||
TIA->WSYNC = 0; // Wait for Sync - halts CPU until end of 1st scanline of VSYNC
|
||||
TIA->WSYNC = 0; // wait until end of 2nd scanline of VSYNC
|
||||
TIA->WSYNC = 0; // wait until end of 3rd scanline of VSYNC
|
||||
TIA->VSYNC = 0; // Accumulator D1=0, turns off Vertical Sync signal
|
||||
TIA->VSYNC = 0; // 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++) {
|
||||
TIA->WSYNC = 0; // Wait for SYNC (halts CPU until end of scanline)
|
||||
}
|
||||
// Since we have a timer running this may take variable time
|
||||
|
||||
|
||||
// Wait for the timer to run out
|
||||
while(RIOT->INTIM) TIA->WSYNC = 0;
|
||||
|
||||
// Screen - display logic
|
||||
// Update the registers in TIA (the video chip) in order to generate what the player sees.
|
||||
// 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.
|
||||
TIA->VBLANK = 0; // D1=1, turns off Vertical Blank signal (image output on)
|
||||
char c = SINTABLE[idx++];
|
||||
for(char i=0;i<192;i++) {
|
||||
TIA->WSYNC = 0; // Wait for SYNC (halts CPU until end of scanline)
|
||||
TIA->COLUBK = c++; // Set background color
|
||||
TIA->COLUBK = c; // Set background color
|
||||
TIA->PF0 = c;
|
||||
TIA->PF1 = c;
|
||||
TIA->PF2 = c;
|
||||
TIA->HMOVE = c;
|
||||
c++;
|
||||
}
|
||||
|
||||
// Overscan - game logic
|
||||
// Since we don't have any yet, just delay
|
||||
// Start OverScan
|
||||
TIA->WSYNC = 0; // Wait for SYNC (halts CPU until end of scanline)
|
||||
TIA->VBLANK = 2; // // D1=1 turns image output off
|
||||
TIA->COLUBK = 0;
|
||||
for(char i=0;i<30;i++) {
|
||||
TIA->WSYNC = 0; // Wait for SYNC (halts CPU until end of scanline)
|
||||
}
|
||||
TIA->VBLANK = 2; // D1=1 turns image output off
|
||||
TIA->COLUBK = 0; // Set background color to black
|
||||
RIOT->TIM64T = (27*76)/64; // Set timer to wait 27 lines
|
||||
|
||||
// Vertical Blank - game logic
|
||||
// Since we have a timer running this may take variable time
|
||||
|
||||
// Wait for the timer to run out
|
||||
while(RIOT->INTIM) TIA->WSYNC = 0;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
157
src/test/kc/examples/atari2600/atari2600-sprites.c
Normal file
157
src/test/kc/examples/atari2600/atari2600-sprites.c
Normal file
@ -0,0 +1,157 @@
|
||||
// Minimal Atari 2600 VCS Program using Sprites
|
||||
// Source: https://atariage.com/forums/blogs/entry/11109-step-1-generate-a-stable-display/
|
||||
#pragma target(atari2600)
|
||||
#include <atari2600.h>
|
||||
#pragma var_model(mem)
|
||||
|
||||
// Data
|
||||
#pragma data_seg(Data)
|
||||
const char SINTABLE_160[0x100] = kickasm {{
|
||||
.fill $100, 5+round(74.5+74.5*sin(2*PI*i/256))
|
||||
}};
|
||||
|
||||
char SPRITE_C[] = {
|
||||
0,
|
||||
0b00011000,
|
||||
0b00011000,
|
||||
0b00011000,
|
||||
0b00011000,
|
||||
0b00111100,
|
||||
0b00111100,
|
||||
0b00111100,
|
||||
0b00111100,
|
||||
0b01100110,
|
||||
0b01100110,
|
||||
0b01100110,
|
||||
0b01100110,
|
||||
0b11000000,
|
||||
0b11000000,
|
||||
0b11000000,
|
||||
0b11000000,
|
||||
0b11000000,
|
||||
0b11000000,
|
||||
0b11000000,
|
||||
0b11000000,
|
||||
0b01100110,
|
||||
0b01100110,
|
||||
0b01100110,
|
||||
0b01100110,
|
||||
0b00111100,
|
||||
0b00111100,
|
||||
0b00111100,
|
||||
0b00111100,
|
||||
0b00011000,
|
||||
0b00011000,
|
||||
0b00011000,
|
||||
0b00011000,
|
||||
0
|
||||
};
|
||||
|
||||
|
||||
// Variables
|
||||
#pragma data_seg(Vars)
|
||||
// Counts frames
|
||||
char idx;
|
||||
char idx2 = 57;
|
||||
// Player 0 X position
|
||||
__ma char p0_xpos;
|
||||
// Player 0 Y position
|
||||
char p0_ypos;
|
||||
|
||||
void main() {
|
||||
|
||||
asm { cld }
|
||||
// Player 0
|
||||
// - Color
|
||||
TIA->COLUP0 = 0xf0;
|
||||
// - Graphics
|
||||
TIA->GRP0 = 0xaf;
|
||||
|
||||
// Player 1
|
||||
// - Color
|
||||
//TIA->COLUP1 = 0xf0;
|
||||
// - Graphics
|
||||
//TIA->GRP1 = 0xf5;
|
||||
|
||||
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.
|
||||
TIA->VSYNC = 2; // D1=1, turns on Vertical Sync signal
|
||||
RIOT->TIM64T = (41*CYCLES_PER_SCANLINE)/64; // Set timer to wait 41 lines
|
||||
TIA->WSYNC = 0; // Wait for Sync - halts CPU until end of 1st scanline of VSYNC
|
||||
TIA->WSYNC = 0; // wait until end of 2nd scanline of VSYNC
|
||||
TIA->WSYNC = 0; // wait until end of 3rd scanline of VSYNC
|
||||
TIA->VSYNC = 0; // D1=0, turns off Vertical Sync signal
|
||||
|
||||
// Vertical Blank - game logic
|
||||
// Since we have a timer running this may take variable time
|
||||
|
||||
// Vertical Sprite Position Player 0 - inline ASM to achieve cycle exact code
|
||||
asm {
|
||||
lda p0_xpos
|
||||
sta TIA_WSYNC
|
||||
sec
|
||||
!: sbc #$f
|
||||
bcs !-
|
||||
eor #7
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
sta TIA_HMP0
|
||||
sta TIA_RESP0
|
||||
}
|
||||
p0_xpos = SINTABLE_160[idx++];
|
||||
p0_ypos = SINTABLE_160[idx2++];
|
||||
|
||||
// Execute horisontal movement
|
||||
|
||||
TIA->WSYNC = 0;
|
||||
TIA->HMOVE = 0;
|
||||
|
||||
// Wait for the timer to run out
|
||||
while(RIOT->INTIM) TIA->WSYNC = 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.
|
||||
TIA->VBLANK = 0; // D1=1, turns off Vertical Blank signal (image output on)
|
||||
TIA->COLUBK = 0x0; // Set background color to black
|
||||
|
||||
// index into p0 (0 when not active)
|
||||
char p0_idx = 0;
|
||||
|
||||
for(char i=1;i<192;i++) {
|
||||
// Wait for SYNC (halts CPU until end of scanline)
|
||||
TIA->WSYNC = 0;
|
||||
TIA->COLUBK = i;
|
||||
if(p0_idx) {
|
||||
// Player 0 is active - show it
|
||||
char gfx = SPRITE_C[p0_idx];
|
||||
TIA->GRP0 = gfx;
|
||||
if(gfx==0)
|
||||
p0_idx = 0;
|
||||
else
|
||||
p0_idx++;
|
||||
} else if(p0_ypos==i)
|
||||
// Player 0 becomes active
|
||||
p0_idx = 1;
|
||||
}
|
||||
|
||||
// Start OverScan
|
||||
TIA->WSYNC = 0; // Wait for SYNC (halts CPU until end of scanline)
|
||||
TIA->VBLANK = 2; // D1=1 turns image output off
|
||||
TIA->COLUBK = 0; // Set background color to black
|
||||
RIOT->TIM64T = (27*CYCLES_PER_SCANLINE)/64; // Set timer to wait 27 lines
|
||||
|
||||
// Vertical Blank - game logic
|
||||
// Since we have a timer running this may take variable time
|
||||
|
||||
// Wait for the timer to run out
|
||||
while(RIOT->INTIM) TIA->WSYNC = 0;
|
||||
|
||||
}
|
||||
}
|
@ -13,5 +13,5 @@ void main() {
|
||||
eor value
|
||||
sta SCREEN
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Demonstration Atari 2600 VCS Program
|
||||
// Minimal Atari 2600 VCS Program
|
||||
// Source: https://atariage.com/forums/blogs/entry/11109-step-1-generate-a-stable-display/
|
||||
// Atari 2600 VCS 2K ROM
|
||||
.file [name="atari2600-demo.a26", type="bin", segments="Code, Data, Vectors"]
|
||||
@ -12,13 +12,34 @@
|
||||
.word main // IRQ
|
||||
.segment Code
|
||||
|
||||
.const OFFSET_STRUCT_ATARI_TIA_WRITE_PF0 = $d
|
||||
.const OFFSET_STRUCT_ATARI_TIA_WRITE_PF1 = $e
|
||||
.const OFFSET_STRUCT_ATARI_TIA_WRITE_PF2 = $f
|
||||
.const OFFSET_STRUCT_ATARI_TIA_WRITE_COLUPF = 8
|
||||
.const OFFSET_STRUCT_MOS6532_RIOT_TIM64T = $16
|
||||
.const OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC = 2
|
||||
.const OFFSET_STRUCT_MOS6532_RIOT_INTIM = 4
|
||||
.const OFFSET_STRUCT_ATARI_TIA_WRITE_VBLANK = 1
|
||||
.const OFFSET_STRUCT_ATARI_TIA_WRITE_COLUBK = 9
|
||||
.const OFFSET_STRUCT_ATARI_TIA_WRITE_HMOVE = $2a
|
||||
// Atari TIA write registers
|
||||
.label TIA = 0
|
||||
// Atari RIOT registers
|
||||
.label RIOT = $280
|
||||
.segment Code
|
||||
main: {
|
||||
// TIA->PF0 = 0b10100000
|
||||
lda #$a0
|
||||
sta TIA+OFFSET_STRUCT_ATARI_TIA_WRITE_PF0
|
||||
// TIA->PF1 = 0b01010101
|
||||
lda #$55
|
||||
sta TIA+OFFSET_STRUCT_ATARI_TIA_WRITE_PF1
|
||||
// TIA->PF2 = 0b10101010
|
||||
lda #$aa
|
||||
sta TIA+OFFSET_STRUCT_ATARI_TIA_WRITE_PF2
|
||||
// TIA->COLUPF = 0x55
|
||||
lda #$55
|
||||
sta TIA+OFFSET_STRUCT_ATARI_TIA_WRITE_COLUPF
|
||||
lda #0
|
||||
sta idx
|
||||
__b2:
|
||||
@ -29,8 +50,12 @@ main: {
|
||||
// The Sync Signal must be on for 3 scanlines.
|
||||
lda #2
|
||||
sta TIA
|
||||
// RIOT->TIM64T = (41*76)/64
|
||||
// D1=1, turns on Vertical Sync signal
|
||||
lda #$29*$4c/$40
|
||||
sta RIOT+OFFSET_STRUCT_MOS6532_RIOT_TIM64T
|
||||
// TIA->WSYNC = 0
|
||||
// Accumulator D1=1, turns on Vertical Sync signal
|
||||
// Set timer to wait 41 lines
|
||||
lda #0
|
||||
sta TIA+OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC
|
||||
// Wait for Sync - halts CPU until end of 1st scanline of VSYNC
|
||||
@ -40,18 +65,16 @@ main: {
|
||||
// TIA->VSYNC = 0
|
||||
// wait until end of 3rd scanline of VSYNC
|
||||
sta TIA
|
||||
tax
|
||||
// Vertical Blank - game logic
|
||||
// Since we don't have any yet, just delay
|
||||
// Wait for the timer to run out
|
||||
__b3:
|
||||
// for(char i=0;i<37;i++)
|
||||
cpx #$25
|
||||
bcc __b4
|
||||
// while(RIOT->INTIM)
|
||||
lda #0
|
||||
cmp RIOT+OFFSET_STRUCT_MOS6532_RIOT_INTIM
|
||||
bne __b4
|
||||
// TIA->VBLANK = 0
|
||||
// Screen - display logic
|
||||
// Update the registers in TIA (the video chip) in order to generate what the player sees.
|
||||
// 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 TIA+OFFSET_STRUCT_ATARI_TIA_WRITE_VBLANK
|
||||
// c = SINTABLE[idx++]
|
||||
// D1=1, turns off Vertical Blank signal (image output on)
|
||||
@ -64,8 +87,7 @@ main: {
|
||||
cpy #$c0
|
||||
bcc __b7
|
||||
// TIA->WSYNC = 0
|
||||
// Overscan - game logic
|
||||
// Since we don't have any yet, just delay
|
||||
// Start OverScan
|
||||
lda #0
|
||||
sta TIA+OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC
|
||||
// TIA->VBLANK = 2
|
||||
@ -73,30 +95,41 @@ main: {
|
||||
lda #2
|
||||
sta TIA+OFFSET_STRUCT_ATARI_TIA_WRITE_VBLANK
|
||||
// TIA->COLUBK = 0
|
||||
// // D1=1 turns image output off
|
||||
// D1=1 turns image output off
|
||||
lda #0
|
||||
sta TIA+OFFSET_STRUCT_ATARI_TIA_WRITE_COLUBK
|
||||
tax
|
||||
// RIOT->TIM64T = (27*76)/64
|
||||
// Set background color to black
|
||||
lda #$1b*$4c/$40
|
||||
sta RIOT+OFFSET_STRUCT_MOS6532_RIOT_TIM64T
|
||||
// Wait for the timer to run out
|
||||
__b9:
|
||||
// for(char i=0;i<30;i++)
|
||||
cpx #$1e
|
||||
bcc __b10
|
||||
// while(RIOT->INTIM)
|
||||
lda #0
|
||||
cmp RIOT+OFFSET_STRUCT_MOS6532_RIOT_INTIM
|
||||
bne __b10
|
||||
jmp __b2
|
||||
__b10:
|
||||
// TIA->WSYNC = 0
|
||||
lda #0
|
||||
sta TIA+OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC
|
||||
// for(char i=0;i<30;i++)
|
||||
inx
|
||||
jmp __b9
|
||||
__b7:
|
||||
// TIA->WSYNC = 0
|
||||
lda #0
|
||||
sta TIA+OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC
|
||||
// TIA->COLUBK = c++
|
||||
// TIA->COLUBK = c
|
||||
// Wait for SYNC (halts CPU until end of scanline)
|
||||
stx TIA+OFFSET_STRUCT_ATARI_TIA_WRITE_COLUBK
|
||||
// TIA->COLUBK = c++;
|
||||
// TIA->PF0 = c
|
||||
// Set background color
|
||||
stx TIA+OFFSET_STRUCT_ATARI_TIA_WRITE_PF0
|
||||
// TIA->PF1 = c
|
||||
stx TIA+OFFSET_STRUCT_ATARI_TIA_WRITE_PF1
|
||||
// TIA->PF2 = c
|
||||
stx TIA+OFFSET_STRUCT_ATARI_TIA_WRITE_PF2
|
||||
// TIA->HMOVE = c
|
||||
stx TIA+OFFSET_STRUCT_ATARI_TIA_WRITE_HMOVE
|
||||
// c++;
|
||||
inx
|
||||
// for(char i=0;i<192;i++)
|
||||
iny
|
||||
@ -105,12 +138,9 @@ main: {
|
||||
// TIA->WSYNC = 0
|
||||
lda #0
|
||||
sta TIA+OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC
|
||||
// for(char i=0;i<37;i++)
|
||||
inx
|
||||
jmp __b3
|
||||
}
|
||||
.segment Data
|
||||
.align $100
|
||||
SINTABLE:
|
||||
.fill $100, round(127.5+127.5*sin(2*PI*i/256))
|
||||
|
||||
|
@ -10,52 +10,57 @@
|
||||
|
||||
(void()) main()
|
||||
main: scope:[main] from @1
|
||||
[4] phi()
|
||||
[4] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_PF0) ← (byte) $a0
|
||||
[5] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_PF1) ← (byte) $55
|
||||
[6] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_PF2) ← (byte) $aa
|
||||
[7] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_COLUPF) ← (byte) $55
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main main::@9
|
||||
[5] (byte) idx#12 ← phi( main/(byte) 0 main::@9/(byte) idx#1 )
|
||||
[8] (byte) idx#12 ← phi( main/(byte) 0 main::@9/(byte) idx#1 )
|
||||
to:main::@2
|
||||
main::@2: scope:[main] from main::@1
|
||||
[6] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA) ← (byte) 2
|
||||
[7] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0
|
||||
[8] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0
|
||||
[9] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0
|
||||
[10] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA) ← (byte) 0
|
||||
[9] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA) ← (byte) 2
|
||||
[10] *((byte*)(const nomodify struct MOS6532_RIOT*) RIOT+(const byte) OFFSET_STRUCT_MOS6532_RIOT_TIM64T) ← (byte)(number) $29*(number) $4c/(number) $40
|
||||
[11] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0
|
||||
[12] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0
|
||||
[13] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0
|
||||
[14] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA) ← (byte) 0
|
||||
to:main::@3
|
||||
main::@3: scope:[main] from main::@2 main::@4
|
||||
[11] (byte) main::i#2 ← phi( main::@2/(byte) 0 main::@4/(byte) main::i#1 )
|
||||
[12] if((byte) main::i#2<(byte) $25) goto main::@4
|
||||
[15] if((byte) 0!=*((byte*)(const nomodify struct MOS6532_RIOT*) RIOT+(const byte) OFFSET_STRUCT_MOS6532_RIOT_INTIM)) goto main::@4
|
||||
to:main::@5
|
||||
main::@5: scope:[main] from main::@3
|
||||
[13] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_VBLANK) ← (byte) 0
|
||||
[14] (byte) main::c#0 ← *((const to_nomodify byte*) SINTABLE + (byte) idx#12)
|
||||
[15] (byte) idx#1 ← ++ (byte) idx#12
|
||||
[16] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_VBLANK) ← (byte) 0
|
||||
[17] (byte) main::c#0 ← *((const to_nomodify byte*) SINTABLE + (byte) idx#12)
|
||||
[18] (byte) idx#1 ← ++ (byte) idx#12
|
||||
to:main::@6
|
||||
main::@6: scope:[main] from main::@5 main::@7
|
||||
[16] (byte) main::c#2 ← phi( main::@5/(byte) main::c#0 main::@7/(byte) main::c#1 )
|
||||
[16] (byte) main::i1#2 ← phi( main::@5/(byte) 0 main::@7/(byte) main::i1#1 )
|
||||
[17] if((byte) main::i1#2<(byte) $c0) goto main::@7
|
||||
[19] (byte) main::c#2 ← phi( main::@5/(byte) main::c#0 main::@7/(byte) main::c#1 )
|
||||
[19] (byte) main::i#2 ← phi( main::@5/(byte) 0 main::@7/(byte) main::i#1 )
|
||||
[20] if((byte) main::i#2<(byte) $c0) goto main::@7
|
||||
to:main::@8
|
||||
main::@8: scope:[main] from main::@6
|
||||
[18] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0
|
||||
[19] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_VBLANK) ← (byte) 2
|
||||
[20] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_COLUBK) ← (byte) 0
|
||||
[21] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0
|
||||
[22] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_VBLANK) ← (byte) 2
|
||||
[23] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_COLUBK) ← (byte) 0
|
||||
[24] *((byte*)(const nomodify struct MOS6532_RIOT*) RIOT+(const byte) OFFSET_STRUCT_MOS6532_RIOT_TIM64T) ← (byte)(number) $1b*(number) $4c/(number) $40
|
||||
to:main::@9
|
||||
main::@9: scope:[main] from main::@10 main::@8
|
||||
[21] (byte) main::i2#2 ← phi( main::@10/(byte) main::i2#1 main::@8/(byte) 0 )
|
||||
[22] if((byte) main::i2#2<(byte) $1e) goto main::@10
|
||||
[25] if((byte) 0!=*((byte*)(const nomodify struct MOS6532_RIOT*) RIOT+(const byte) OFFSET_STRUCT_MOS6532_RIOT_INTIM)) goto main::@10
|
||||
to:main::@1
|
||||
main::@10: scope:[main] from main::@9
|
||||
[23] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0
|
||||
[24] (byte) main::i2#1 ← ++ (byte) main::i2#2
|
||||
[26] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0
|
||||
to:main::@9
|
||||
main::@7: scope:[main] from main::@6
|
||||
[25] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0
|
||||
[26] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_COLUBK) ← (byte) main::c#2
|
||||
[27] (byte) main::c#1 ← ++ (byte) main::c#2
|
||||
[28] (byte) main::i1#1 ← ++ (byte) main::i1#2
|
||||
[27] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0
|
||||
[28] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_COLUBK) ← (byte) main::c#2
|
||||
[29] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_PF0) ← (byte) main::c#2
|
||||
[30] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_PF1) ← (byte) main::c#2
|
||||
[31] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_PF2) ← (byte) main::c#2
|
||||
[32] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_HMOVE) ← (byte) main::c#2
|
||||
[33] (byte) main::c#1 ← ++ (byte) main::c#2
|
||||
[34] (byte) main::i#1 ← ++ (byte) main::i#2
|
||||
to:main::@6
|
||||
main::@4: scope:[main] from main::@3
|
||||
[29] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0
|
||||
[30] (byte) main::i#1 ← ++ (byte) main::i#2
|
||||
[35] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0
|
||||
to:main::@3
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -71,14 +71,22 @@
|
||||
(byte) MOS6532_RIOT::TIM8T
|
||||
(const byte*) MOS6532_RIOT::UNUSED[(number) $f] = { fill( $f, 0) }
|
||||
(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_COLUBK = (byte) 9
|
||||
(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_COLUPF = (byte) 8
|
||||
(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_HMOVE = (byte) $2a
|
||||
(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_PF0 = (byte) $d
|
||||
(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_PF1 = (byte) $e
|
||||
(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_PF2 = (byte) $f
|
||||
(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_VBLANK = (byte) 1
|
||||
(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC = (byte) 2
|
||||
(const byte) OFFSET_STRUCT_MOS6532_RIOT_INTIM = (byte) 4
|
||||
(const byte) OFFSET_STRUCT_MOS6532_RIOT_TIM64T = (byte) $16
|
||||
(const nomodify struct MOS6532_RIOT*) RIOT = (struct MOS6532_RIOT*) 640
|
||||
(const to_nomodify byte*) SINTABLE[(number) $100] = kickasm {{ .fill $100, round(127.5+127.5*sin(2*PI*i/256))
|
||||
}}
|
||||
(const nomodify struct ATARI_TIA_WRITE*) TIA = (struct ATARI_TIA_WRITE*) 0
|
||||
(byte) idx
|
||||
(byte) idx#1 idx mem[1] 78.71428571428571
|
||||
(byte) idx#12 idx mem[1] 100.25000000000001
|
||||
(byte) idx#1 idx mem[1] 64.82352941176471
|
||||
(byte) idx#12 idx mem[1] 109.36363636363637
|
||||
(void()) main()
|
||||
(label) main::@1
|
||||
(label) main::@10
|
||||
@ -93,19 +101,11 @@
|
||||
(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::c#2 reg byte x 888.5
|
||||
(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
|
||||
(byte) main::i#1 reg byte y 2002.0
|
||||
(byte) main::i#2 reg byte y 333.6666666666667
|
||||
|
||||
mem[1] [ idx#12 idx#1 ]
|
||||
reg byte x [ main::i#2 main::i#1 ]
|
||||
reg byte y [ main::i1#2 main::i1#1 ]
|
||||
reg byte y [ main::i#2 main::i#1 ]
|
||||
reg byte x [ main::c#2 main::c#0 main::c#1 ]
|
||||
reg byte x [ main::i2#2 main::i2#1 ]
|
||||
|
211
src/test/ref/examples/atari2600/atari2600-sprites.asm
Normal file
211
src/test/ref/examples/atari2600/atari2600-sprites.asm
Normal file
@ -0,0 +1,211 @@
|
||||
// Minimal Atari 2600 VCS Program using Sprites
|
||||
// Source: https://atariage.com/forums/blogs/entry/11109-step-1-generate-a-stable-display/
|
||||
// Atari 2600 VCS 2K ROM
|
||||
.file [name="atari2600-sprites.a26", type="bin", segments="Code, Data, Vectors"]
|
||||
.segmentdef Code [start=$f800,min=$f800,max=$fff9]
|
||||
.segmentdef Data [startAfter="Code",max=$fff9]
|
||||
.segmentdef Vectors [start=$fffa,max=$ffff]
|
||||
.segmentdef Vars [start=$80,max=$ff, virtual]
|
||||
.segment Vectors
|
||||
.word main // NMI
|
||||
.word main // RESET
|
||||
.word main // IRQ
|
||||
.segment Code
|
||||
|
||||
// The number of CPU cycles per scanline
|
||||
.const CYCLES_PER_SCANLINE = $4c
|
||||
.const OFFSET_STRUCT_ATARI_TIA_WRITE_COLUP0 = 6
|
||||
.const OFFSET_STRUCT_ATARI_TIA_WRITE_GRP0 = $1b
|
||||
.const OFFSET_STRUCT_MOS6532_RIOT_TIM64T = $16
|
||||
.const OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC = 2
|
||||
.const OFFSET_STRUCT_ATARI_TIA_WRITE_HMOVE = $2a
|
||||
.const OFFSET_STRUCT_MOS6532_RIOT_INTIM = 4
|
||||
.const OFFSET_STRUCT_ATARI_TIA_WRITE_VBLANK = 1
|
||||
.const OFFSET_STRUCT_ATARI_TIA_WRITE_COLUBK = 9
|
||||
// The TIA WSYNC register (for access from inline ASM)
|
||||
.label TIA_WSYNC = 2
|
||||
// The TIA RESP0 register (for access from inline ASM)
|
||||
.label TIA_RESP0 = $10
|
||||
// The TIA HMP0 register (for access from inline ASM)
|
||||
.label TIA_HMP0 = $20
|
||||
// Atari TIA write registers
|
||||
.label TIA = 0
|
||||
// Atari RIOT registers
|
||||
.label RIOT = $280
|
||||
.segment Code
|
||||
main: {
|
||||
// asm
|
||||
cld
|
||||
// TIA->COLUP0 = 0xf0
|
||||
// Player 0
|
||||
// - Color
|
||||
lda #$f0
|
||||
sta TIA+OFFSET_STRUCT_ATARI_TIA_WRITE_COLUP0
|
||||
// TIA->GRP0 = 0xaf
|
||||
// - Graphics
|
||||
lda #$af
|
||||
sta TIA+OFFSET_STRUCT_ATARI_TIA_WRITE_GRP0
|
||||
lda #$39
|
||||
sta idx2
|
||||
lda #0
|
||||
sta idx
|
||||
// Player 1
|
||||
// - Color
|
||||
//TIA->COLUP1 = 0xf0;
|
||||
// - Graphics
|
||||
//TIA->GRP1 = 0xf5;
|
||||
__b2:
|
||||
// TIA->VSYNC = 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 TIA
|
||||
// RIOT->TIM64T = (41*CYCLES_PER_SCANLINE)/64
|
||||
// D1=1, turns on Vertical Sync signal
|
||||
lda #$29*CYCLES_PER_SCANLINE/$40
|
||||
sta RIOT+OFFSET_STRUCT_MOS6532_RIOT_TIM64T
|
||||
// TIA->WSYNC = 0
|
||||
// Set timer to wait 41 lines
|
||||
lda #0
|
||||
sta TIA+OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC
|
||||
// Wait for Sync - halts CPU until end of 1st scanline of VSYNC
|
||||
sta TIA+OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC
|
||||
// wait until end of 2nd scanline of VSYNC
|
||||
sta TIA+OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC
|
||||
// TIA->VSYNC = 0
|
||||
// wait until end of 3rd scanline of VSYNC
|
||||
sta TIA
|
||||
// asm
|
||||
// Vertical Sprite Position Player 0 - inline ASM to achieve cycle exact code
|
||||
lda p0_xpos
|
||||
sta TIA_WSYNC
|
||||
sec
|
||||
!:
|
||||
sbc #$f
|
||||
bcs !-
|
||||
eor #7
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
sta TIA_HMP0
|
||||
sta TIA_RESP0
|
||||
// p0_xpos = SINTABLE_160[idx++]
|
||||
ldy idx
|
||||
lda SINTABLE_160,y
|
||||
sta p0_xpos
|
||||
// p0_xpos = SINTABLE_160[idx++];
|
||||
inc idx
|
||||
// p0_ypos = SINTABLE_160[idx2++]
|
||||
ldy idx2
|
||||
lda SINTABLE_160,y
|
||||
sta p0_ypos
|
||||
// p0_ypos = SINTABLE_160[idx2++];
|
||||
inc idx2
|
||||
// TIA->WSYNC = 0
|
||||
// Execute horisontal movement
|
||||
lda #0
|
||||
sta TIA+OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC
|
||||
// TIA->HMOVE = 0
|
||||
sta TIA+OFFSET_STRUCT_ATARI_TIA_WRITE_HMOVE
|
||||
// Wait for the timer to run out
|
||||
__b3:
|
||||
// while(RIOT->INTIM)
|
||||
lda #0
|
||||
cmp RIOT+OFFSET_STRUCT_MOS6532_RIOT_INTIM
|
||||
bne __b4
|
||||
// TIA->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.
|
||||
sta TIA+OFFSET_STRUCT_ATARI_TIA_WRITE_VBLANK
|
||||
// TIA->COLUBK = 0x0
|
||||
// D1=1, turns off Vertical Blank signal (image output on)
|
||||
sta TIA+OFFSET_STRUCT_ATARI_TIA_WRITE_COLUBK
|
||||
tay
|
||||
ldx #1
|
||||
__b6:
|
||||
// for(char i=1;i<192;i++)
|
||||
cpx #$c0
|
||||
bcc __b7
|
||||
// TIA->WSYNC = 0
|
||||
// Start OverScan
|
||||
lda #0
|
||||
sta TIA+OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC
|
||||
// TIA->VBLANK = 2
|
||||
// Wait for SYNC (halts CPU until end of scanline)
|
||||
lda #2
|
||||
sta TIA+OFFSET_STRUCT_ATARI_TIA_WRITE_VBLANK
|
||||
// TIA->COLUBK = 0
|
||||
// D1=1 turns image output off
|
||||
lda #0
|
||||
sta TIA+OFFSET_STRUCT_ATARI_TIA_WRITE_COLUBK
|
||||
// RIOT->TIM64T = (27*CYCLES_PER_SCANLINE)/64
|
||||
// Set background color to black
|
||||
lda #$1b*CYCLES_PER_SCANLINE/$40
|
||||
sta RIOT+OFFSET_STRUCT_MOS6532_RIOT_TIM64T
|
||||
// Wait for the timer to run out
|
||||
__b13:
|
||||
// while(RIOT->INTIM)
|
||||
lda #0
|
||||
cmp RIOT+OFFSET_STRUCT_MOS6532_RIOT_INTIM
|
||||
bne __b14
|
||||
jmp __b2
|
||||
__b14:
|
||||
// TIA->WSYNC = 0
|
||||
lda #0
|
||||
sta TIA+OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC
|
||||
jmp __b13
|
||||
__b7:
|
||||
// Wait for SYNC (halts CPU until end of scanline)
|
||||
lda #0
|
||||
sta TIA+OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC
|
||||
// TIA->COLUBK = i
|
||||
stx TIA+OFFSET_STRUCT_ATARI_TIA_WRITE_COLUBK
|
||||
// if(p0_idx)
|
||||
cpy #0
|
||||
bne __b9
|
||||
// if(p0_ypos==i)
|
||||
cpx p0_ypos
|
||||
bne __b10
|
||||
ldy #1
|
||||
jmp __b10
|
||||
__b1:
|
||||
ldy #0
|
||||
__b10:
|
||||
// for(char i=1;i<192;i++)
|
||||
inx
|
||||
jmp __b6
|
||||
__b9:
|
||||
// gfx = SPRITE_C[p0_idx]
|
||||
// Player 0 is active - show it
|
||||
lda SPRITE_C,y
|
||||
// TIA->GRP0 = gfx
|
||||
sta TIA+OFFSET_STRUCT_ATARI_TIA_WRITE_GRP0
|
||||
// if(gfx==0)
|
||||
cmp #0
|
||||
beq __b1
|
||||
// p0_idx++;
|
||||
iny
|
||||
jmp __b10
|
||||
__b4:
|
||||
// TIA->WSYNC = 0
|
||||
lda #0
|
||||
sta TIA+OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC
|
||||
jmp __b3
|
||||
}
|
||||
.segment Data
|
||||
SINTABLE_160:
|
||||
.fill $100, 5+round(74.5+74.5*sin(2*PI*i/256))
|
||||
|
||||
SPRITE_C: .byte 0, $18, $18, $18, $18, $3c, $3c, $3c, $3c, $66, $66, $66, $66, $c0, $c0, $c0, $c0, $c0, $c0, $c0, $c0, $66, $66, $66, $66, $3c, $3c, $3c, $3c, $18, $18, $18, $18, 0
|
||||
.segment Vars
|
||||
// Player 0 X position
|
||||
p0_xpos: .byte 0
|
||||
// Counts frames
|
||||
idx: .byte 0
|
||||
// Player 0 Y position
|
||||
p0_ypos: .byte 0
|
||||
idx2: .byte 0
|
85
src/test/ref/examples/atari2600/atari2600-sprites.cfg
Normal file
85
src/test/ref/examples/atari2600/atari2600-sprites.cfg
Normal file
@ -0,0 +1,85 @@
|
||||
@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
|
||||
asm { cld }
|
||||
[5] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_COLUP0) ← (byte) $f0
|
||||
[6] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_GRP0) ← (byte) $af
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main main::@13
|
||||
[7] (byte) idx2#2 ← phi( main/(byte) $39 main::@13/(byte) idx2#1 )
|
||||
[7] (byte) idx#2 ← phi( main/(byte) 0 main::@13/(byte) idx#1 )
|
||||
to:main::@2
|
||||
main::@2: scope:[main] from main::@1
|
||||
[8] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA) ← (byte) 2
|
||||
[9] *((byte*)(const nomodify struct MOS6532_RIOT*) RIOT+(const byte) OFFSET_STRUCT_MOS6532_RIOT_TIM64T) ← (byte) $29*(const nomodify byte) CYCLES_PER_SCANLINE/(byte) $40
|
||||
[10] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0
|
||||
[11] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0
|
||||
[12] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0
|
||||
[13] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA) ← (byte) 0
|
||||
asm { ldap0_xpos staTIA_WSYNC sec !: sbc#$f bcs!- eor#7 asl asl asl asl staTIA_HMP0 staTIA_RESP0 }
|
||||
[15] (byte) p0_xpos ← *((const to_nomodify byte*) SINTABLE_160 + (byte) idx#2)
|
||||
[16] (byte) idx#1 ← ++ (byte) idx#2
|
||||
[17] (byte) p0_ypos#1 ← *((const to_nomodify byte*) SINTABLE_160 + (byte) idx2#2)
|
||||
[18] (byte) idx2#1 ← ++ (byte) idx2#2
|
||||
[19] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0
|
||||
[20] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_HMOVE) ← (byte) 0
|
||||
to:main::@3
|
||||
main::@3: scope:[main] from main::@2 main::@4
|
||||
[21] if((byte) 0!=*((byte*)(const nomodify struct MOS6532_RIOT*) RIOT+(const byte) OFFSET_STRUCT_MOS6532_RIOT_INTIM)) goto main::@4
|
||||
to:main::@5
|
||||
main::@5: scope:[main] from main::@3
|
||||
[22] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_VBLANK) ← (byte) 0
|
||||
[23] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_COLUBK) ← (byte) 0
|
||||
to:main::@6
|
||||
main::@6: scope:[main] from main::@10 main::@5
|
||||
[24] (byte) main::p0_idx#4 ← phi( main::@10/(byte) main::p0_idx#8 main::@5/(byte) 0 )
|
||||
[24] (byte) main::i#2 ← phi( main::@10/(byte) main::i#1 main::@5/(byte) 1 )
|
||||
[25] if((byte) main::i#2<(byte) $c0) goto main::@7
|
||||
to:main::@8
|
||||
main::@8: scope:[main] from main::@6
|
||||
[26] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0
|
||||
[27] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_VBLANK) ← (byte) 2
|
||||
[28] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_COLUBK) ← (byte) 0
|
||||
[29] *((byte*)(const nomodify struct MOS6532_RIOT*) RIOT+(const byte) OFFSET_STRUCT_MOS6532_RIOT_TIM64T) ← (byte) $1b*(const nomodify byte) CYCLES_PER_SCANLINE/(byte) $40
|
||||
to:main::@13
|
||||
main::@13: scope:[main] from main::@14 main::@8
|
||||
[30] if((byte) 0!=*((byte*)(const nomodify struct MOS6532_RIOT*) RIOT+(const byte) OFFSET_STRUCT_MOS6532_RIOT_INTIM)) goto main::@14
|
||||
to:main::@1
|
||||
main::@14: scope:[main] from main::@13
|
||||
[31] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0
|
||||
to:main::@13
|
||||
main::@7: scope:[main] from main::@6
|
||||
[32] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0
|
||||
[33] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_COLUBK) ← (byte) main::i#2
|
||||
[34] if((byte) 0!=(byte) main::p0_idx#4) goto main::@9
|
||||
to:main::@11
|
||||
main::@11: scope:[main] from main::@7
|
||||
[35] if((byte) p0_ypos#1!=(byte) main::i#2) goto main::@15
|
||||
to:main::@10
|
||||
main::@15: scope:[main] from main::@11
|
||||
[36] phi()
|
||||
to:main::@10
|
||||
main::@10: scope:[main] from main::@11 main::@12 main::@15 main::@9
|
||||
[37] (byte) main::p0_idx#8 ← phi( main::@9/(byte) 0 main::@15/(byte) main::p0_idx#4 main::@11/(byte) 1 main::@12/(byte) main::p0_idx#3 )
|
||||
[38] (byte) main::i#1 ← ++ (byte) main::i#2
|
||||
to:main::@6
|
||||
main::@9: scope:[main] from main::@7
|
||||
[39] (byte) main::gfx#0 ← *((const byte*) SPRITE_C + (byte) main::p0_idx#4)
|
||||
[40] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_GRP0) ← (byte) main::gfx#0
|
||||
[41] if((byte) main::gfx#0==(byte) 0) goto main::@10
|
||||
to:main::@12
|
||||
main::@12: scope:[main] from main::@9
|
||||
[42] (byte) main::p0_idx#3 ← ++ (byte) main::p0_idx#4
|
||||
to:main::@10
|
||||
main::@4: scope:[main] from main::@3
|
||||
[43] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0
|
||||
to:main::@3
|
2031
src/test/ref/examples/atari2600/atari2600-sprites.log
Normal file
2031
src/test/ref/examples/atari2600/atari2600-sprites.log
Normal file
File diff suppressed because it is too large
Load Diff
131
src/test/ref/examples/atari2600/atari2600-sprites.sym
Normal file
131
src/test/ref/examples/atari2600/atari2600-sprites.sym
Normal file
@ -0,0 +1,131 @@
|
||||
(label) @1
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(byte) ATARI_TIA_READ::CXBLPF
|
||||
(byte) ATARI_TIA_READ::CXM0FB
|
||||
(byte) ATARI_TIA_READ::CXM0P
|
||||
(byte) ATARI_TIA_READ::CXM1FB
|
||||
(byte) ATARI_TIA_READ::CXM1P
|
||||
(byte) ATARI_TIA_READ::CXP0FB
|
||||
(byte) ATARI_TIA_READ::CXP1FB
|
||||
(byte) ATARI_TIA_READ::CXPPMM
|
||||
(byte) ATARI_TIA_READ::INPT0
|
||||
(byte) ATARI_TIA_READ::INPT1
|
||||
(byte) ATARI_TIA_READ::INPT2
|
||||
(byte) ATARI_TIA_READ::INPT3
|
||||
(byte) ATARI_TIA_READ::INPT4
|
||||
(byte) ATARI_TIA_READ::INPT5
|
||||
(byte) ATARI_TIA_WRITE::AUDC0
|
||||
(byte) ATARI_TIA_WRITE::AUDC1
|
||||
(byte) ATARI_TIA_WRITE::AUDF0
|
||||
(byte) ATARI_TIA_WRITE::AUDF1
|
||||
(byte) ATARI_TIA_WRITE::AUDV0
|
||||
(byte) ATARI_TIA_WRITE::AUDV1
|
||||
(byte) ATARI_TIA_WRITE::COLUBK
|
||||
(byte) ATARI_TIA_WRITE::COLUP0
|
||||
(byte) ATARI_TIA_WRITE::COLUP1
|
||||
(byte) ATARI_TIA_WRITE::COLUPF
|
||||
(byte) ATARI_TIA_WRITE::CTRLPF
|
||||
(byte) ATARI_TIA_WRITE::CXCLR
|
||||
(byte) ATARI_TIA_WRITE::ENABL
|
||||
(byte) ATARI_TIA_WRITE::ENAM0
|
||||
(byte) ATARI_TIA_WRITE::ENAM1
|
||||
(byte) ATARI_TIA_WRITE::GRP0
|
||||
(byte) ATARI_TIA_WRITE::GRP1
|
||||
(byte) ATARI_TIA_WRITE::HMBL
|
||||
(byte) ATARI_TIA_WRITE::HMCLR
|
||||
(byte) ATARI_TIA_WRITE::HMM0
|
||||
(byte) ATARI_TIA_WRITE::HMM1
|
||||
(byte) ATARI_TIA_WRITE::HMOVE
|
||||
(byte) ATARI_TIA_WRITE::HMP0
|
||||
(byte) ATARI_TIA_WRITE::HMP1
|
||||
(byte) ATARI_TIA_WRITE::NUSIZ0
|
||||
(byte) ATARI_TIA_WRITE::NUSIZ1
|
||||
(byte) ATARI_TIA_WRITE::PF0
|
||||
(byte) ATARI_TIA_WRITE::PF1
|
||||
(byte) ATARI_TIA_WRITE::PF2
|
||||
(byte) ATARI_TIA_WRITE::REFP0
|
||||
(byte) ATARI_TIA_WRITE::REFP1
|
||||
(byte) ATARI_TIA_WRITE::RESBL
|
||||
(byte) ATARI_TIA_WRITE::RESM0
|
||||
(byte) ATARI_TIA_WRITE::RESM1
|
||||
(byte) ATARI_TIA_WRITE::RESMP0
|
||||
(byte) ATARI_TIA_WRITE::RESMP1
|
||||
(byte) ATARI_TIA_WRITE::RESP0
|
||||
(byte) ATARI_TIA_WRITE::RESP1
|
||||
(byte) ATARI_TIA_WRITE::RSYNC
|
||||
(byte) ATARI_TIA_WRITE::VBLANK
|
||||
(byte) ATARI_TIA_WRITE::VDELBL
|
||||
(byte) ATARI_TIA_WRITE::VDELP0
|
||||
(byte) ATARI_TIA_WRITE::VDELP1
|
||||
(byte) ATARI_TIA_WRITE::VSYNC
|
||||
(byte) ATARI_TIA_WRITE::WSYNC
|
||||
(const nomodify byte) CYCLES_PER_SCANLINE = (byte) $4c
|
||||
(byte) MOS6532_RIOT::INTIM
|
||||
(byte) MOS6532_RIOT::SWACNT
|
||||
(byte) MOS6532_RIOT::SWBCNT
|
||||
(byte) MOS6532_RIOT::SWCHA
|
||||
(byte) MOS6532_RIOT::SWCHB
|
||||
(byte) MOS6532_RIOT::T1024T
|
||||
(byte) MOS6532_RIOT::TIM1T
|
||||
(byte) MOS6532_RIOT::TIM64T
|
||||
(byte) MOS6532_RIOT::TIM8T
|
||||
(const byte*) MOS6532_RIOT::UNUSED[(number) $f] = { fill( $f, 0) }
|
||||
(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_COLUBK = (byte) 9
|
||||
(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_COLUP0 = (byte) 6
|
||||
(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_GRP0 = (byte) $1b
|
||||
(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_HMOVE = (byte) $2a
|
||||
(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_VBLANK = (byte) 1
|
||||
(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC = (byte) 2
|
||||
(const byte) OFFSET_STRUCT_MOS6532_RIOT_INTIM = (byte) 4
|
||||
(const byte) OFFSET_STRUCT_MOS6532_RIOT_TIM64T = (byte) $16
|
||||
(const nomodify struct MOS6532_RIOT*) RIOT = (struct MOS6532_RIOT*) 640
|
||||
(const to_nomodify byte*) SINTABLE_160[(number) $100] = kickasm {{ .fill $100, 5+round(74.5+74.5*sin(2*PI*i/256))
|
||||
}}
|
||||
(const byte*) SPRITE_C[] = { (byte) 0, (byte) $18, (byte) $18, (byte) $18, (byte) $18, (byte) $3c, (byte) $3c, (byte) $3c, (byte) $3c, (byte) $66, (byte) $66, (byte) $66, (byte) $66, (byte) $c0, (byte) $c0, (byte) $c0, (byte) $c0, (byte) $c0, (byte) $c0, (byte) $c0, (byte) $c0, (byte) $66, (byte) $66, (byte) $66, (byte) $66, (byte) $3c, (byte) $3c, (byte) $3c, (byte) $3c, (byte) $18, (byte) $18, (byte) $18, (byte) $18, (byte) 0 }
|
||||
(const nomodify struct ATARI_TIA_WRITE*) TIA = (struct ATARI_TIA_WRITE*) 0
|
||||
(const nomodify byte*) TIA_HMP0 = (byte*) 32
|
||||
(const nomodify byte*) TIA_RESP0 = (byte*) 16
|
||||
(const nomodify byte*) TIA_WSYNC = (byte*) 2
|
||||
(byte) idx
|
||||
(byte) idx#1 idx mem[1] 39.357142857142854
|
||||
(byte) idx#2 idx mem[1] 133.66666666666669
|
||||
(byte) idx2
|
||||
(byte) idx2#1 idx2 mem[1] 42.38461538461539
|
||||
(byte) idx2#2 idx2 mem[1] 109.36363636363637
|
||||
(void()) main()
|
||||
(label) main::@1
|
||||
(label) main::@10
|
||||
(label) main::@11
|
||||
(label) main::@12
|
||||
(label) main::@13
|
||||
(label) main::@14
|
||||
(label) main::@15
|
||||
(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::gfx
|
||||
(byte) main::gfx#0 reg byte a 1501.5
|
||||
(byte) main::i
|
||||
(byte) main::i#1 reg byte x 2002.0
|
||||
(byte) main::i#2 reg byte x 417.08333333333337
|
||||
(byte) main::p0_idx
|
||||
(byte) main::p0_idx#3 reg byte y 2002.0
|
||||
(byte) main::p0_idx#4 reg byte y 500.5
|
||||
(byte) main::p0_idx#8 reg byte y 1501.5
|
||||
(byte) p0_xpos loadstore mem[1] 2.4634146341463414 = (byte) 0
|
||||
(byte) p0_ypos
|
||||
(byte) p0_ypos#1 p0_ypos mem[1] 52.476190476190474
|
||||
|
||||
mem[1] [ idx#2 idx#1 ]
|
||||
mem[1] [ idx2#2 idx2#1 ]
|
||||
reg byte x [ main::i#2 main::i#1 ]
|
||||
reg byte y [ main::p0_idx#4 main::p0_idx#8 main::p0_idx#3 ]
|
||||
mem[1] [ p0_xpos ]
|
||||
mem[1] [ p0_ypos#1 ]
|
||||
reg byte a [ main::gfx#0 ]
|
Loading…
x
Reference in New Issue
Block a user