mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-11-02 06:05:57 +00:00
Added a sprite CX16 example. #581
This commit is contained in:
parent
2d58a799d5
commit
dbaea05623
155
src/main/fragment/cache/fragment-cache-wdc65c02.asm
vendored
155
src/main/fragment/cache/fragment-cache-wdc65c02.asm
vendored
@ -315,3 +315,158 @@ ldx {z1}
|
||||
ldy {c1},x
|
||||
//FRAGMENT vbuxx=pbuc1_derefidx_vbuyy
|
||||
ldx {c1},y
|
||||
//FRAGMENT vwuz1=vwuc1
|
||||
lda #<{c1}
|
||||
sta {z1}
|
||||
lda #>{c1}
|
||||
sta {z1}+1
|
||||
//FRAGMENT vwuz1=_inc_vwuz1
|
||||
inc {z1}
|
||||
bne !+
|
||||
inc {z1}+1
|
||||
!:
|
||||
//FRAGMENT vwuz1_neq_vbuc1_then_la1
|
||||
NO_SYNTHESIS
|
||||
//FRAGMENT vwuz1_neq_vwuc1_then_la1
|
||||
lda {z1}+1
|
||||
cmp #>{c1}
|
||||
bne {la1}
|
||||
lda {z1}
|
||||
cmp #<{c1}
|
||||
bne {la1}
|
||||
//FRAGMENT vwuz1=vbuc1
|
||||
lda #<{c1}
|
||||
sta {z1}
|
||||
lda #>{c1}
|
||||
sta {z1}+1
|
||||
//FRAGMENT vwuz1=_dec_vwuz1
|
||||
lda {z1}
|
||||
bne !+
|
||||
dec {z1}+1
|
||||
!:
|
||||
dec {z1}
|
||||
//FRAGMENT vwuz1=vwuz2_rol_1
|
||||
lda {z2}
|
||||
asl
|
||||
sta {z1}
|
||||
lda {z2}+1
|
||||
rol
|
||||
sta {z1}+1
|
||||
//FRAGMENT pwuz1=pwuc1_plus_vwuz2
|
||||
clc
|
||||
lda {z2}
|
||||
adc #<{c1}
|
||||
sta {z1}
|
||||
lda {z2}+1
|
||||
adc #>{c1}
|
||||
sta {z1}+1
|
||||
//FRAGMENT _deref_pwuc1=_deref_pwuz1
|
||||
ldy #0
|
||||
lda ({z1}),y
|
||||
sta {c1}
|
||||
iny
|
||||
lda ({z1}),y
|
||||
sta {c1}+1
|
||||
//FRAGMENT pvoz1=pvoc1
|
||||
lda #<{c1}
|
||||
sta {z1}
|
||||
lda #>{c1}
|
||||
sta {z1}+1
|
||||
//FRAGMENT vbuz1=_lo_pvoz2
|
||||
lda {z2}
|
||||
sta {z1}
|
||||
//FRAGMENT vbuz1=_hi_pvoz2
|
||||
lda {z2}+1
|
||||
sta {z1}
|
||||
//FRAGMENT vbuz1=vbuc1_bor_vbuz2
|
||||
lda #{c1}
|
||||
ora {z2}
|
||||
sta {z1}
|
||||
//FRAGMENT pbuz1=pbuz2_plus_vwuz3
|
||||
lda {z2}
|
||||
clc
|
||||
adc {z3}
|
||||
sta {z1}
|
||||
lda {z2}+1
|
||||
adc {z3}+1
|
||||
sta {z1}+1
|
||||
//FRAGMENT pbuz1_neq_pbuz2_then_la1
|
||||
lda {z1}+1
|
||||
cmp {z2}+1
|
||||
bne {la1}
|
||||
lda {z1}
|
||||
cmp {z2}
|
||||
bne {la1}
|
||||
//FRAGMENT _deref_pbuc1=_deref_pbuz1
|
||||
ldy #0
|
||||
lda ({z1}),y
|
||||
sta {c1}
|
||||
//FRAGMENT vbuaa=_lo_pvoz1
|
||||
lda {z1}
|
||||
//FRAGMENT vbuxx=_lo_pvoz1
|
||||
ldx {z1}
|
||||
//FRAGMENT vbuaa=_hi_pvoz1
|
||||
lda {z1}+1
|
||||
//FRAGMENT vbuxx=_hi_pvoz1
|
||||
ldx {z1}+1
|
||||
//FRAGMENT vbuaa=vbuc1_bor_vbuz1
|
||||
lda #{c1}
|
||||
ora {z1}
|
||||
//FRAGMENT vbuxx=vbuc1_bor_vbuz1
|
||||
lda #{c1}
|
||||
ora {z1}
|
||||
tax
|
||||
//FRAGMENT vbuyy=vbuc1_bor_vbuz1
|
||||
lda #{c1}
|
||||
ora {z1}
|
||||
tay
|
||||
//FRAGMENT vbuz1=vbuc1_bor_vbuxx
|
||||
txa
|
||||
ora #{c1}
|
||||
sta {z1}
|
||||
//FRAGMENT vbuaa=vbuc1_bor_vbuxx
|
||||
txa
|
||||
ora #{c1}
|
||||
//FRAGMENT vbuxx=vbuc1_bor_vbuxx
|
||||
txa
|
||||
ora #{c1}
|
||||
tax
|
||||
//FRAGMENT vbuyy=vbuc1_bor_vbuxx
|
||||
txa
|
||||
ora #{c1}
|
||||
tay
|
||||
//FRAGMENT vbuz1=vbuc1_bor_vbuyy
|
||||
tya
|
||||
ora #{c1}
|
||||
sta {z1}
|
||||
//FRAGMENT vbuaa=vbuc1_bor_vbuyy
|
||||
tya
|
||||
ora #{c1}
|
||||
//FRAGMENT vbuxx=vbuc1_bor_vbuyy
|
||||
tya
|
||||
ora #{c1}
|
||||
tax
|
||||
//FRAGMENT vbuyy=vbuc1_bor_vbuyy
|
||||
tya
|
||||
ora #{c1}
|
||||
tay
|
||||
//FRAGMENT vbuyy=_lo_pvoz1
|
||||
ldy {z1}
|
||||
//FRAGMENT vbuyy=_hi_pvoz1
|
||||
ldy {z1}+1
|
||||
//FRAGMENT pbuz1=pbuz2_plus_vwuz1
|
||||
lda {z1}
|
||||
clc
|
||||
adc {z2}
|
||||
sta {z1}
|
||||
lda {z1}+1
|
||||
adc {z2}+1
|
||||
sta {z1}+1
|
||||
//FRAGMENT pwuz1=pwuc1_plus_vwuz1
|
||||
clc
|
||||
lda {z1}
|
||||
adc #<{c1}
|
||||
sta {z1}
|
||||
lda {z1}+1
|
||||
adc #>{c1}
|
||||
sta {z1}+1
|
||||
|
@ -81,6 +81,14 @@ char * const VERA_IRQLINE_L = 0x9f28;
|
||||
// Bit 2: Chroma Disable Setting 'Chroma Disable' disables output of chroma in NTSC composite mode and will give a better picture on a monochrome display. (Setting this bit will also disable the chroma output on the S-video output.)
|
||||
// Bit 0-1: Output Mode 0: Video disabled, 1: VGA output, 2: NTSC composite, 3: RGB interlaced, composite sync (via VGA connector)
|
||||
char * const VERA_DC_VIDEO = 0x9f29;
|
||||
char VERA_SPRITES_ENABLE = 0x40;
|
||||
char VERA_LAYER1_ENABLE = 0x20;
|
||||
char VERA_LAYER0_ENABLE = 0x10;
|
||||
char VERA_CROMA_DISABLE = 0x04;
|
||||
char VERA_OUTPUT_DISABLE = 0x00;
|
||||
char VERA_OUTPUT_VGA = 0x01;
|
||||
char VERA_OUTPUT_NTSC = 0x02;
|
||||
char VERA_OUTPUT_RGB = 0x03;
|
||||
// $9F2A DC_HSCALE (DCSEL=0) Active Display H-Scale
|
||||
char * const VERA_DC_HSCALE = 0x9f2a;
|
||||
// $9F2B DC_VSCALE (DCSEL=0) Active Display V-Scale
|
||||
@ -156,3 +164,32 @@ char * const VERA_SPI_DATA = 0x9f3e;
|
||||
// Bit 1: Slow clock
|
||||
// Bit 0: Select
|
||||
char * const VERA_SPI_CTRL = 0x9f3f;
|
||||
|
||||
// Sprite Attributes address in VERA VRAM
|
||||
const unsigned long VERA_SPRITE_ATTR = 0x1fc00;
|
||||
|
||||
// The VERA structure of a sprite (8 bytes)
|
||||
// 128*8 bytes located at $1FC00-$1FFFF
|
||||
struct VERA_SPRITE {
|
||||
// 0-1 ADDRESS Address and mode
|
||||
// - bits 0-11: Address (16:5)
|
||||
// - bits 15: Mode (0:4 bpp 1:8 bpp)
|
||||
unsigned int ADDR;
|
||||
// 2-3 X (9:0)
|
||||
unsigned int X;
|
||||
// 4-5 Y (9:0)
|
||||
unsigned int Y;
|
||||
// 6 CTRL1 Control 1
|
||||
// - bits 4-7 Collision mask
|
||||
// - bits 2-3 Z-depth ( 0:Sprite disabled, 1:Sprite between background and layer 0, 2:Sprite between layer 0 and layer 1, 3:Sprite in front of layer 1 )
|
||||
// - bits 1 V-flip
|
||||
// - bits 0 H-flip
|
||||
char CTRL1;
|
||||
// 7 CTRL2 Control 2
|
||||
// - bits 6-7 Sprite height ( 0:8 pixels, 1:16 pixels, 2:32 pixels, 3:64 pixels )
|
||||
// - bits 4-5 Sprite width ( 0:8 pixels, 1:16 pixels, 2:32 pixels, 3:64 pixels )
|
||||
// - bits 0-3 Palette offset (if 4bpp Color index 1-15 is modified by adding 16 x palette offset)
|
||||
char CTRL2;
|
||||
};
|
||||
// 8BPP sprite mode (add to VERA_SPRITE.ADDR to enable)
|
||||
const unsigned int VERA_SPRITE_8BPP = 0x8000;
|
||||
|
@ -47,6 +47,13 @@ char * const DEFAULT_SCREEN_VBANK = 0;
|
||||
// - data: The data to put into VRAM
|
||||
void vpoke(char vbank, char* vaddr, char data);
|
||||
|
||||
// Read a single byte from VRAM.
|
||||
// Uses VERA DATA0
|
||||
// - bank: Which 64K VRAM bank to put data into (0/1)
|
||||
// - addr: The address in VRAM
|
||||
// - returns: The data to put into VRAM
|
||||
char vpeek(char vbank, char* vaddr);
|
||||
|
||||
// Copy block of memory (from RAM to VRAM)
|
||||
// Copies the values of num bytes from the location pointed to by source directly to the memory block pointed to by destination in VRAM.
|
||||
// - vbank: Which 64K VRAM bank to put data into (0/1)
|
||||
|
@ -20,6 +20,22 @@ void vpoke(char vbank, char* vaddr, char data) {
|
||||
*VERA_DATA0 = data;
|
||||
}
|
||||
|
||||
// Read a single byte from VRAM.
|
||||
// Uses VERA DATA0
|
||||
// - bank: Which 64K VRAM bank to put data into (0/1)
|
||||
// - addr: The address in VRAM
|
||||
// - returns: The data to put into VRAM
|
||||
char vpeek(char vbank, char* vaddr) {
|
||||
// Select DATA0
|
||||
*VERA_CTRL &= ~VERA_ADDRSEL;
|
||||
// Set address
|
||||
*VERA_ADDRX_L = <vaddr;
|
||||
*VERA_ADDRX_M = >vaddr;
|
||||
*VERA_ADDRX_H = VERA_INC_0 | vbank;
|
||||
// Get data
|
||||
return *VERA_DATA0;
|
||||
}
|
||||
|
||||
// Copy block of memory (from RAM to VRAM)
|
||||
// Copies the values of num bytes from the location pointed to by source directly to the memory block pointed to by destination in VRAM.
|
||||
// - vbank: Which 64K VRAM bank to put data into (0/1)
|
||||
@ -34,8 +50,7 @@ void memcpy_to_vram(char vbank, void* vdest, void* src, unsigned int num ) {
|
||||
*VERA_ADDRX_M = >vdest;
|
||||
*VERA_ADDRX_H = VERA_INC_1 | vbank;
|
||||
// Transfer the data
|
||||
char *s = src;
|
||||
char *end = (char*)src+num;
|
||||
for(; s!=end; s++)
|
||||
for(char *s = src; s!=end; s++)
|
||||
*VERA_DATA0 = *s;
|
||||
}
|
||||
|
@ -463,6 +463,11 @@ public class TestPrograms {
|
||||
compileAndCompare("examples/nes/nes-demo.c");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCx16Sprite() throws IOException, URISyntaxException {
|
||||
compileAndCompare("examples/cx16/sprite.c");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCx16Text() throws IOException, URISyntaxException {
|
||||
compileAndCompare("examples/cx16/text.c");
|
||||
|
68
src/test/kc/examples/cx16/sprite.c
Normal file
68
src/test/kc/examples/cx16/sprite.c
Normal file
@ -0,0 +1,68 @@
|
||||
// Example program for the Commander X16
|
||||
// Displays a sprite
|
||||
|
||||
#pragma target(cx16)
|
||||
#include <cx16.h>
|
||||
#include <6502.h>
|
||||
|
||||
// A 64*64 8bpp sprite
|
||||
align(0x100) char SPRITE_PIXELS[64*64] = kickasm(resource "sprite.png") {{
|
||||
.var pic = LoadPicture("sprite.png", List().add($000000, $ffffff))
|
||||
.for (var x=0;x<64; x++)
|
||||
.for (var y=0; y<64; y++)
|
||||
.byte (pic.getPixel(x,y)==0) ? 0 : 1
|
||||
}};
|
||||
|
||||
// Address to use for sprite pixels in VRAM
|
||||
const unsigned long SPRITE_PIXELS_VRAM = 0x08000;
|
||||
|
||||
// Sprite attributes: 8bpp, in front, 64x64, address SPRITE_PIXELS_VRAM
|
||||
struct VERA_SPRITE SPRITE_ATTR = { <(SPRITE_PIXELS_VRAM/32)|VERA_SPRITE_8BPP, 320-32, 240-32, 0x0c, 0xf0 };
|
||||
|
||||
// X sine [0;640-64]
|
||||
align(0x100) unsigned int SINX[241] = kickasm {{
|
||||
.fillword 256, 288+288*sin(i*2*PI/241)
|
||||
}};
|
||||
|
||||
// Y sine [0;480-64]
|
||||
align(0x100) unsigned int SINY[251] = kickasm {{
|
||||
.fillword 256, 208+208*sin(i*2*PI/251)
|
||||
}};
|
||||
|
||||
void main() {
|
||||
// Copy sprite data to VRAM
|
||||
memcpy_to_vram((char)>SPRITE_PIXELS_VRAM, <SPRITE_PIXELS_VRAM, SPRITE_PIXELS, sizeof(SPRITE_PIXELS));
|
||||
// Copy sprite attributes to VRAM
|
||||
memcpy_to_vram((char)>VERA_SPRITE_ATTR, <VERA_SPRITE_ATTR, &SPRITE_ATTR, sizeof(SPRITE_ATTR));
|
||||
// Enable sprites
|
||||
*VERA_CTRL &= ~VERA_DCSEL;
|
||||
*VERA_DC_VIDEO |= VERA_SPRITES_ENABLE;
|
||||
// Enable VSYNC IRQ (also set line bit 8 to 0)
|
||||
SEI();
|
||||
*KERNEL_IRQ = &irq_vsync;
|
||||
*VERA_IEN = VERA_VSYNC;
|
||||
CLI();
|
||||
}
|
||||
|
||||
// X sine index
|
||||
volatile unsigned int sin_idx_x = 119;
|
||||
// Y sine index
|
||||
volatile unsigned int sin_idx_y = 79;
|
||||
|
||||
// VSYNC Interrupt Routine
|
||||
void irq_vsync() {
|
||||
// Move the sprite around
|
||||
if(++sin_idx_x==241) sin_idx_x = 0;
|
||||
if(--sin_idx_y==0xffff) sin_idx_y = 251-1;
|
||||
SPRITE_ATTR.X = SINX[sin_idx_x];
|
||||
SPRITE_ATTR.Y = SINY[sin_idx_y];
|
||||
// Copy sprite positions to VRAM (the 4 relevant bytes in VERA_SPRITE_ATTR)
|
||||
memcpy_to_vram((char)>VERA_SPRITE_ATTR, <VERA_SPRITE_ATTR+2, &SPRITE_ATTR+2, 4);
|
||||
// Reset the VSYNC interrupt
|
||||
*VERA_ISR = VERA_VSYNC;
|
||||
// Exit CX16 KERNAL IRQ
|
||||
asm {
|
||||
// soft exit (keep kernal running)
|
||||
jmp $e034
|
||||
}
|
||||
}
|
BIN
src/test/kc/examples/cx16/sprite.png
Normal file
BIN
src/test/kc/examples/cx16/sprite.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 650 B |
@ -862,6 +862,7 @@ REGISTER UPLIFT SCOPES
|
||||
Uplift Scope [irq_line] 370.33: zp[1]:5 [ irq_line::i2#2 irq_line::i2#1 ] 353.5: zp[1]:6 [ irq_line::i#2 irq_line::i#1 ] 353.5: zp[1]:7 [ irq_line::i1#2 irq_line::i1#1 ] 26.12: zp[1]:3 [ irq_line::b#2 irq_line::b#1 ] 26: zp[1]:2 [ irq_line::l#2 irq_line::l#1 ] 22.4: zp[2]:16 [ irq_line::bar#0 ] 18: zp[1]:4 [ irq_line::idx#2 irq_line::idx#1 irq_line::idx#0 ]
|
||||
Uplift Scope [memset] 336.67: zp[2]:8 [ memset::dst#2 memset::dst#1 ]
|
||||
Uplift Scope [] 0.53: zp[1]:14 [ cnt ] 0.45: zp[1]:10 [ hstart ] 0.35: zp[1]:11 [ hstop ] 0.33: zp[1]:12 [ vstart ] 0.32: zp[1]:13 [ vstop ] 0.28: zp[1]:15 [ sin_idx ]
|
||||
Uplift Scope [VERA_SPRITE]
|
||||
Uplift Scope [MOS6522_VIA]
|
||||
Uplift Scope [main]
|
||||
Uplift Scope [__start]
|
||||
@ -870,6 +871,7 @@ Uplifting [irq_line] best 8197 combination reg byte y [ irq_line::i2#2 irq_line:
|
||||
Limited combination testing to 100 combinations of 1296 possible.
|
||||
Uplifting [memset] best 8197 combination zp[2]:8 [ memset::dst#2 memset::dst#1 ]
|
||||
Uplifting [] best 8197 combination zp[1]:14 [ cnt ] zp[1]:10 [ hstart ] zp[1]:11 [ hstop ] zp[1]:12 [ vstart ] zp[1]:13 [ vstop ] zp[1]:15 [ sin_idx ]
|
||||
Uplifting [VERA_SPRITE] best 8197 combination
|
||||
Uplifting [MOS6522_VIA] best 8197 combination
|
||||
Uplifting [main] best 8197 combination
|
||||
Uplifting [__start] best 8197 combination
|
||||
|
337
src/test/ref/examples/cx16/sprite.asm
Normal file
337
src/test/ref/examples/cx16/sprite.asm
Normal file
@ -0,0 +1,337 @@
|
||||
// Example program for the Commander X16
|
||||
// Displays a sprite
|
||||
.cpu _65c02
|
||||
// Commodore 64 PRG executable file
|
||||
.file [name="sprite.prg", type="prg", segments="Program"]
|
||||
.segmentdef Program [segments="Basic, Code, Data"]
|
||||
.segmentdef Basic [start=$0801]
|
||||
.segmentdef Code [start=$80d]
|
||||
.segmentdef Data [startAfter="Code"]
|
||||
.segment Basic
|
||||
:BasicUpstart(__start)
|
||||
.segment Code
|
||||
|
||||
|
||||
.const VERA_INC_1 = $10
|
||||
.const VERA_DCSEL = 2
|
||||
.const VERA_ADDRSEL = 1
|
||||
.const VERA_VSYNC = 1
|
||||
// Sprite Attributes address in VERA VRAM
|
||||
.const VERA_SPRITE_ATTR = $1fc00
|
||||
// 8BPP sprite mode (add to VERA_SPRITE.ADDR to enable)
|
||||
.const VERA_SPRITE_8BPP = $8000
|
||||
// Address to use for sprite pixels in VRAM
|
||||
.const SPRITE_PIXELS_VRAM = $8000
|
||||
.const SIZEOF_STRUCT_VERA_SPRITE = 8
|
||||
.const OFFSET_STRUCT_VERA_SPRITE_X = 2
|
||||
.const OFFSET_STRUCT_VERA_SPRITE_Y = 4
|
||||
.const VERA_SPRITES_ENABLE = $40
|
||||
.const SIZEOF_BYTE = 1
|
||||
// $9F20 VRAM Address (7:0)
|
||||
.label VERA_ADDRX_L = $9f20
|
||||
// $9F21 VRAM Address (15:8)
|
||||
.label VERA_ADDRX_M = $9f21
|
||||
// $9F22 VRAM Address (7:0)
|
||||
// Bit 4-7: Address Increment The following is the amount incremented per value value:increment
|
||||
// 0:0, 1:1, 2:2, 3:4, 4:8, 5:16, 6:32, 7:64, 8:128, 9:256, 10:512, 11:40, 12:80, 13:160, 14:320, 15:640
|
||||
// Bit 3: DECR Setting the DECR bit, will decrement instead of increment by the value set by the 'Address Increment' field.
|
||||
// Bit 0: VRAM Address (16)
|
||||
.label VERA_ADDRX_H = $9f22
|
||||
// $9F23 DATA0 VRAM Data port 0
|
||||
.label VERA_DATA0 = $9f23
|
||||
// $9F25 CTRL Control
|
||||
// Bit 7: Reset
|
||||
// Bit 1: DCSEL
|
||||
// Bit 2: ADDRSEL
|
||||
.label VERA_CTRL = $9f25
|
||||
// $9F26 IEN Interrupt Enable
|
||||
// Bit 7: IRQ line (8)
|
||||
// Bit 3: AFLOW
|
||||
// Bit 2: SPRCOL
|
||||
// Bit 1: LINE
|
||||
// Bit 0: VSYNC
|
||||
.label VERA_IEN = $9f26
|
||||
// $9F27 ISR Interrupt Status
|
||||
// Interrupts will be generated for the interrupt sources set in the lower 4 bits of IEN. ISR will indicate the interrupts that have occurred.
|
||||
// Writing a 1 to one of the lower 3 bits in ISR will clear that interrupt status. AFLOW can only be cleared by filling the audio FIFO for at least 1/4.
|
||||
// Bit 4-7: Sprite Collisions. This field indicates which groups of sprites have collided.
|
||||
// Bit 3: AFLOW
|
||||
// Bit 2: SPRCOL
|
||||
// Bit 1: LINE
|
||||
// Bit 0: VSYNC
|
||||
.label VERA_ISR = $9f27
|
||||
// $9F29 DC_VIDEO (DCSEL=0)
|
||||
// Bit 7: Current Field Read-only bit which reflects the active interlaced field in composite and RGB modes. (0: even, 1: odd)
|
||||
// Bit 6: Sprites Enable Enable output from the Sprites renderer
|
||||
// Bit 5: Layer1 Enable Enable output from the Layer1 renderer
|
||||
// Bit 4: Layer0 Enable Enable output from the Layer0 renderer
|
||||
// Bit 2: Chroma Disable Setting 'Chroma Disable' disables output of chroma in NTSC composite mode and will give a better picture on a monochrome display. (Setting this bit will also disable the chroma output on the S-video output.)
|
||||
// Bit 0-1: Output Mode 0: Video disabled, 1: VGA output, 2: NTSC composite, 3: RGB interlaced, composite sync (via VGA connector)
|
||||
.label VERA_DC_VIDEO = $9f29
|
||||
// $0314 (RAM) IRQ vector - The vector used when the KERNAL serves IRQ interrupts
|
||||
.label KERNEL_IRQ = $314
|
||||
// X sine index
|
||||
.label sin_idx_x = 8
|
||||
// Y sine index
|
||||
.label sin_idx_y = $a
|
||||
.segment Code
|
||||
__start: {
|
||||
// sin_idx_x = 119
|
||||
lda #<$77
|
||||
sta.z sin_idx_x
|
||||
lda #>$77
|
||||
sta.z sin_idx_x+1
|
||||
// sin_idx_y = 79
|
||||
lda #<$4f
|
||||
sta.z sin_idx_y
|
||||
lda #>$4f
|
||||
sta.z sin_idx_y+1
|
||||
jsr main
|
||||
rts
|
||||
}
|
||||
// VSYNC Interrupt Routine
|
||||
irq_vsync: {
|
||||
.label __5 = $c
|
||||
.label __6 = $e
|
||||
.label __7 = $c
|
||||
.label __8 = $e
|
||||
// if(++sin_idx_x==241)
|
||||
inc.z sin_idx_x
|
||||
bne !+
|
||||
inc.z sin_idx_x+1
|
||||
!:
|
||||
lda.z sin_idx_x+1
|
||||
cmp #>$f1
|
||||
bne __b1
|
||||
lda.z sin_idx_x
|
||||
cmp #<$f1
|
||||
bne __b1
|
||||
// sin_idx_x = 0
|
||||
lda #<0
|
||||
sta.z sin_idx_x
|
||||
sta.z sin_idx_x+1
|
||||
__b1:
|
||||
// if(--sin_idx_y==0xffff)
|
||||
lda.z sin_idx_y
|
||||
bne !+
|
||||
dec.z sin_idx_y+1
|
||||
!:
|
||||
dec.z sin_idx_y
|
||||
lda.z sin_idx_y+1
|
||||
cmp #>$ffff
|
||||
bne __b2
|
||||
lda.z sin_idx_y
|
||||
cmp #<$ffff
|
||||
bne __b2
|
||||
// sin_idx_y = 251-1
|
||||
lda #<$fb-1
|
||||
sta.z sin_idx_y
|
||||
lda #>$fb-1
|
||||
sta.z sin_idx_y+1
|
||||
__b2:
|
||||
// SPRITE_ATTR.X = SINX[sin_idx_x]
|
||||
lda.z sin_idx_x
|
||||
asl
|
||||
sta.z __5
|
||||
lda.z sin_idx_x+1
|
||||
rol
|
||||
sta.z __5+1
|
||||
clc
|
||||
lda.z __7
|
||||
adc #<SINX
|
||||
sta.z __7
|
||||
lda.z __7+1
|
||||
adc #>SINX
|
||||
sta.z __7+1
|
||||
ldy #0
|
||||
lda (__7),y
|
||||
sta SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_X
|
||||
iny
|
||||
lda (__7),y
|
||||
sta SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_X+1
|
||||
// SPRITE_ATTR.Y = SINY[sin_idx_y]
|
||||
lda.z sin_idx_y
|
||||
asl
|
||||
sta.z __6
|
||||
lda.z sin_idx_y+1
|
||||
rol
|
||||
sta.z __6+1
|
||||
clc
|
||||
lda.z __8
|
||||
adc #<SINY
|
||||
sta.z __8
|
||||
lda.z __8+1
|
||||
adc #>SINY
|
||||
sta.z __8+1
|
||||
ldy #0
|
||||
lda (__8),y
|
||||
sta SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_Y
|
||||
iny
|
||||
lda (__8),y
|
||||
sta SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_Y+1
|
||||
// memcpy_to_vram((char)>VERA_SPRITE_ATTR, <VERA_SPRITE_ATTR+2, &SPRITE_ATTR+2, 4)
|
||||
// Copy sprite positions to VRAM (the 4 relevant bytes in VERA_SPRITE_ATTR)
|
||||
lda #<4
|
||||
sta.z memcpy_to_vram.num
|
||||
lda #>4
|
||||
sta.z memcpy_to_vram.num+1
|
||||
lda #<SPRITE_ATTR+2
|
||||
sta.z memcpy_to_vram.src
|
||||
lda #>SPRITE_ATTR+2
|
||||
sta.z memcpy_to_vram.src+1
|
||||
ldx #VERA_SPRITE_ATTR>>$10
|
||||
lda #<VERA_SPRITE_ATTR+2&$ffff
|
||||
sta.z memcpy_to_vram.vdest
|
||||
lda #>VERA_SPRITE_ATTR+2&$ffff
|
||||
sta.z memcpy_to_vram.vdest+1
|
||||
jsr memcpy_to_vram
|
||||
// *VERA_ISR = VERA_VSYNC
|
||||
// Reset the VSYNC interrupt
|
||||
lda #VERA_VSYNC
|
||||
sta VERA_ISR
|
||||
// asm
|
||||
// Exit CX16 KERNAL IRQ
|
||||
jmp $e034
|
||||
// }
|
||||
}
|
||||
main: {
|
||||
// memcpy_to_vram((char)>SPRITE_PIXELS_VRAM, <SPRITE_PIXELS_VRAM, SPRITE_PIXELS, sizeof(SPRITE_PIXELS))
|
||||
// Copy sprite data to VRAM
|
||||
lda #<$40*$40*SIZEOF_BYTE
|
||||
sta.z memcpy_to_vram.num
|
||||
lda #>$40*$40*SIZEOF_BYTE
|
||||
sta.z memcpy_to_vram.num+1
|
||||
lda #<SPRITE_PIXELS
|
||||
sta.z memcpy_to_vram.src
|
||||
lda #>SPRITE_PIXELS
|
||||
sta.z memcpy_to_vram.src+1
|
||||
ldx #0
|
||||
lda #<SPRITE_PIXELS_VRAM&$ffff
|
||||
sta.z memcpy_to_vram.vdest
|
||||
lda #>SPRITE_PIXELS_VRAM&$ffff
|
||||
sta.z memcpy_to_vram.vdest+1
|
||||
jsr memcpy_to_vram
|
||||
// memcpy_to_vram((char)>VERA_SPRITE_ATTR, <VERA_SPRITE_ATTR, &SPRITE_ATTR, sizeof(SPRITE_ATTR))
|
||||
// Copy sprite attributes to VRAM
|
||||
lda #<SIZEOF_STRUCT_VERA_SPRITE
|
||||
sta.z memcpy_to_vram.num
|
||||
lda #>SIZEOF_STRUCT_VERA_SPRITE
|
||||
sta.z memcpy_to_vram.num+1
|
||||
lda #<SPRITE_ATTR
|
||||
sta.z memcpy_to_vram.src
|
||||
lda #>SPRITE_ATTR
|
||||
sta.z memcpy_to_vram.src+1
|
||||
ldx #VERA_SPRITE_ATTR>>$10
|
||||
lda #<VERA_SPRITE_ATTR&$ffff
|
||||
sta.z memcpy_to_vram.vdest
|
||||
lda #>VERA_SPRITE_ATTR&$ffff
|
||||
sta.z memcpy_to_vram.vdest+1
|
||||
jsr memcpy_to_vram
|
||||
// *VERA_CTRL &= ~VERA_DCSEL
|
||||
// Enable sprites
|
||||
lda #VERA_DCSEL^$ff
|
||||
and VERA_CTRL
|
||||
sta VERA_CTRL
|
||||
// *VERA_DC_VIDEO |= VERA_SPRITES_ENABLE
|
||||
lda #VERA_SPRITES_ENABLE
|
||||
ora VERA_DC_VIDEO
|
||||
sta VERA_DC_VIDEO
|
||||
// asm
|
||||
sei
|
||||
// *KERNEL_IRQ = &irq_vsync
|
||||
lda #<irq_vsync
|
||||
sta KERNEL_IRQ
|
||||
lda #>irq_vsync
|
||||
sta KERNEL_IRQ+1
|
||||
// *VERA_IEN = VERA_VSYNC
|
||||
lda #VERA_VSYNC
|
||||
sta VERA_IEN
|
||||
// asm
|
||||
cli
|
||||
// }
|
||||
rts
|
||||
}
|
||||
// Copy block of memory (from RAM to VRAM)
|
||||
// Copies the values of num bytes from the location pointed to by source directly to the memory block pointed to by destination in VRAM.
|
||||
// - vbank: Which 64K VRAM bank to put data into (0/1)
|
||||
// - vdest: The destination address in VRAM
|
||||
// - src: The source address in RAM
|
||||
// - num: The number of bytes to copy
|
||||
// memcpy_to_vram(byte register(X) vbank, void* zp(2) vdest, void* zp(4) src, word zp(6) num)
|
||||
memcpy_to_vram: {
|
||||
.label end = 6
|
||||
.label s = 4
|
||||
.label vdest = 2
|
||||
.label src = 4
|
||||
.label num = 6
|
||||
// *VERA_CTRL &= ~VERA_ADDRSEL
|
||||
// Select DATA0
|
||||
lda #VERA_ADDRSEL^$ff
|
||||
and VERA_CTRL
|
||||
sta VERA_CTRL
|
||||
// <vdest
|
||||
lda.z vdest
|
||||
// *VERA_ADDRX_L = <vdest
|
||||
// Set address
|
||||
sta VERA_ADDRX_L
|
||||
// >vdest
|
||||
lda.z vdest+1
|
||||
// *VERA_ADDRX_M = >vdest
|
||||
sta VERA_ADDRX_M
|
||||
// VERA_INC_1 | vbank
|
||||
txa
|
||||
ora #VERA_INC_1
|
||||
// *VERA_ADDRX_H = VERA_INC_1 | vbank
|
||||
sta VERA_ADDRX_H
|
||||
// end = (char*)src+num
|
||||
lda.z end
|
||||
clc
|
||||
adc.z src
|
||||
sta.z end
|
||||
lda.z end+1
|
||||
adc.z src+1
|
||||
sta.z end+1
|
||||
__b1:
|
||||
// for(char *s = src; s!=end; s++)
|
||||
lda.z s+1
|
||||
cmp.z end+1
|
||||
bne __b2
|
||||
lda.z s
|
||||
cmp.z end
|
||||
bne __b2
|
||||
// }
|
||||
rts
|
||||
__b2:
|
||||
// *VERA_DATA0 = *s
|
||||
ldy #0
|
||||
lda (s),y
|
||||
sta VERA_DATA0
|
||||
// for(char *s = src; s!=end; s++)
|
||||
inc.z s
|
||||
bne !+
|
||||
inc.z s+1
|
||||
!:
|
||||
jmp __b1
|
||||
}
|
||||
.segment Data
|
||||
// A 64*64 8bpp sprite
|
||||
.align $100
|
||||
SPRITE_PIXELS:
|
||||
.var pic = LoadPicture("sprite.png", List().add($000000, $ffffff))
|
||||
.for (var x=0;x<64; x++)
|
||||
.for (var y=0; y<64; y++)
|
||||
.byte (pic.getPixel(x,y)==0) ? 0 : 1
|
||||
|
||||
// X sine [0;640-64]
|
||||
.align $100
|
||||
SINX:
|
||||
.fillword 256, 288+288*sin(i*2*PI/241)
|
||||
|
||||
// Y sine [0;480-64]
|
||||
.align $100
|
||||
SINY:
|
||||
.fillword 256, 208+208*sin(i*2*PI/251)
|
||||
|
||||
// Sprite attributes: 8bpp, in front, 64x64, address SPRITE_PIXELS_VRAM
|
||||
SPRITE_ATTR: .word (SPRITE_PIXELS_VRAM/$20&$ffff)|VERA_SPRITE_8BPP, $140-$20, $f0-$20
|
||||
.byte $c, $f0
|
103
src/test/ref/examples/cx16/sprite.cfg
Normal file
103
src/test/ref/examples/cx16/sprite.cfg
Normal file
@ -0,0 +1,103 @@
|
||||
|
||||
void __start()
|
||||
__start: scope:[__start] from
|
||||
[0] phi()
|
||||
to:__start::__init1
|
||||
__start::__init1: scope:[__start] from __start
|
||||
[1] sin_idx_x = $77
|
||||
[2] sin_idx_y = $4f
|
||||
to:__start::@1
|
||||
__start::@1: scope:[__start] from __start::__init1
|
||||
[3] phi()
|
||||
[4] call main
|
||||
to:__start::@return
|
||||
__start::@return: scope:[__start] from __start::@1
|
||||
[5] return
|
||||
to:@return
|
||||
|
||||
void irq_vsync()
|
||||
irq_vsync: scope:[irq_vsync] from
|
||||
[6] sin_idx_x = ++ sin_idx_x
|
||||
[7] if(sin_idx_x!=$f1) goto irq_vsync::@1
|
||||
to:irq_vsync::@3
|
||||
irq_vsync::@3: scope:[irq_vsync] from irq_vsync
|
||||
[8] sin_idx_x = 0
|
||||
to:irq_vsync::@1
|
||||
irq_vsync::@1: scope:[irq_vsync] from irq_vsync irq_vsync::@3
|
||||
[9] sin_idx_y = -- sin_idx_y
|
||||
[10] if(sin_idx_y!=$ffff) goto irq_vsync::@2
|
||||
to:irq_vsync::@4
|
||||
irq_vsync::@4: scope:[irq_vsync] from irq_vsync::@1
|
||||
[11] sin_idx_y = $fb-1
|
||||
to:irq_vsync::@2
|
||||
irq_vsync::@2: scope:[irq_vsync] from irq_vsync::@1 irq_vsync::@4
|
||||
[12] irq_vsync::$5 = sin_idx_x << 1
|
||||
[13] irq_vsync::$7 = SINX + irq_vsync::$5
|
||||
[14] *((word*)&SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_X) = *irq_vsync::$7
|
||||
[15] irq_vsync::$6 = sin_idx_y << 1
|
||||
[16] irq_vsync::$8 = SINY + irq_vsync::$6
|
||||
[17] *((word*)&SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_Y) = *irq_vsync::$8
|
||||
[18] call memcpy_to_vram
|
||||
to:irq_vsync::@5
|
||||
irq_vsync::@5: scope:[irq_vsync] from irq_vsync::@2
|
||||
[19] *VERA_ISR = VERA_VSYNC
|
||||
asm { jmp$e034 }
|
||||
to:irq_vsync::@return
|
||||
irq_vsync::@return: scope:[irq_vsync] from irq_vsync::@5
|
||||
[21] return
|
||||
to:@return
|
||||
|
||||
void main()
|
||||
main: scope:[main] from __start::@1
|
||||
[22] phi()
|
||||
[23] call memcpy_to_vram
|
||||
to:main::@2
|
||||
main::@2: scope:[main] from main
|
||||
[24] phi()
|
||||
[25] call memcpy_to_vram
|
||||
to:main::@3
|
||||
main::@3: scope:[main] from main::@2
|
||||
[26] *VERA_CTRL = *VERA_CTRL & ~VERA_DCSEL
|
||||
[27] *VERA_DC_VIDEO = *VERA_DC_VIDEO | VERA_SPRITES_ENABLE
|
||||
to:main::SEI1
|
||||
main::SEI1: scope:[main] from main::@3
|
||||
asm { sei }
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main::SEI1
|
||||
[29] *KERNEL_IRQ = &irq_vsync
|
||||
[30] *VERA_IEN = VERA_VSYNC
|
||||
to:main::CLI1
|
||||
main::CLI1: scope:[main] from main::@1
|
||||
asm { cli }
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::CLI1
|
||||
[32] return
|
||||
to:@return
|
||||
|
||||
void memcpy_to_vram(byte memcpy_to_vram::vbank , void* memcpy_to_vram::vdest , void* memcpy_to_vram::src , word memcpy_to_vram::num)
|
||||
memcpy_to_vram: scope:[memcpy_to_vram] from irq_vsync::@2 main main::@2
|
||||
[33] memcpy_to_vram::num#3 = phi( irq_vsync::@2/4, main/(word)$40*$40*SIZEOF_BYTE, main::@2/SIZEOF_STRUCT_VERA_SPRITE )
|
||||
[33] memcpy_to_vram::src#3 = phi( irq_vsync::@2/(void*)&SPRITE_ATTR+2, main/(void*)SPRITE_PIXELS, main::@2/(void*)&SPRITE_ATTR )
|
||||
[33] memcpy_to_vram::vbank#3 = phi( irq_vsync::@2/(byte)>VERA_SPRITE_ATTR, main/0, main::@2/(byte)>VERA_SPRITE_ATTR )
|
||||
[33] memcpy_to_vram::vdest#3 = phi( irq_vsync::@2/(void*)<VERA_SPRITE_ATTR+2, main/(void*)<SPRITE_PIXELS_VRAM, main::@2/(void*)<VERA_SPRITE_ATTR )
|
||||
[34] *VERA_CTRL = *VERA_CTRL & ~VERA_ADDRSEL
|
||||
[35] memcpy_to_vram::$0 = < memcpy_to_vram::vdest#3
|
||||
[36] *VERA_ADDRX_L = memcpy_to_vram::$0
|
||||
[37] memcpy_to_vram::$1 = > memcpy_to_vram::vdest#3
|
||||
[38] *VERA_ADDRX_M = memcpy_to_vram::$1
|
||||
[39] memcpy_to_vram::$2 = VERA_INC_1 | memcpy_to_vram::vbank#3
|
||||
[40] *VERA_ADDRX_H = memcpy_to_vram::$2
|
||||
[41] memcpy_to_vram::end#0 = (byte*)memcpy_to_vram::src#3 + memcpy_to_vram::num#3
|
||||
[42] memcpy_to_vram::s#4 = (byte*)memcpy_to_vram::src#3
|
||||
to:memcpy_to_vram::@1
|
||||
memcpy_to_vram::@1: scope:[memcpy_to_vram] from memcpy_to_vram memcpy_to_vram::@2
|
||||
[43] memcpy_to_vram::s#2 = phi( memcpy_to_vram/memcpy_to_vram::s#4, memcpy_to_vram::@2/memcpy_to_vram::s#1 )
|
||||
[44] if(memcpy_to_vram::s#2!=memcpy_to_vram::end#0) goto memcpy_to_vram::@2
|
||||
to:memcpy_to_vram::@return
|
||||
memcpy_to_vram::@return: scope:[memcpy_to_vram] from memcpy_to_vram::@1
|
||||
[45] return
|
||||
to:@return
|
||||
memcpy_to_vram::@2: scope:[memcpy_to_vram] from memcpy_to_vram::@1
|
||||
[46] *VERA_DATA0 = *memcpy_to_vram::s#2
|
||||
[47] memcpy_to_vram::s#1 = ++ memcpy_to_vram::s#2
|
||||
to:memcpy_to_vram::@1
|
1632
src/test/ref/examples/cx16/sprite.log
Normal file
1632
src/test/ref/examples/cx16/sprite.log
Normal file
File diff suppressed because it is too large
Load Diff
71
src/test/ref/examples/cx16/sprite.sym
Normal file
71
src/test/ref/examples/cx16/sprite.sym
Normal file
@ -0,0 +1,71 @@
|
||||
const nomodify void()** KERNEL_IRQ = (void()**) 788
|
||||
const byte OFFSET_STRUCT_VERA_SPRITE_X = 2
|
||||
const byte OFFSET_STRUCT_VERA_SPRITE_Y = 4
|
||||
const word* SINX[$f1] = kickasm {{ .fillword 256, 288+288*sin(i*2*PI/241)
|
||||
}}
|
||||
const word* SINY[$fb] = kickasm {{ .fillword 256, 208+208*sin(i*2*PI/251)
|
||||
}}
|
||||
const byte SIZEOF_BYTE = 1
|
||||
const byte SIZEOF_STRUCT_VERA_SPRITE = 8
|
||||
struct VERA_SPRITE SPRITE_ATTR loadstore mem[8] = { ADDR: <SPRITE_PIXELS_VRAM/$20|VERA_SPRITE_8BPP, X: $140-$20, Y: (word)$f0-$20, CTRL1: $c, CTRL2: $f0 }
|
||||
const byte* SPRITE_PIXELS[$40*$40] = kickasm {{ .var pic = LoadPicture("sprite.png", List().add($000000, $ffffff))
|
||||
.for (var x=0;x<64; x++)
|
||||
.for (var y=0; y<64; y++)
|
||||
.byte (pic.getPixel(x,y)==0) ? 0 : 1
|
||||
}}
|
||||
const nomodify dword SPRITE_PIXELS_VRAM = $8000
|
||||
const nomodify byte VERA_ADDRSEL = 1
|
||||
const nomodify byte* VERA_ADDRX_H = (byte*) 40738
|
||||
const nomodify byte* VERA_ADDRX_L = (byte*) 40736
|
||||
const nomodify byte* VERA_ADDRX_M = (byte*) 40737
|
||||
const nomodify byte* VERA_CTRL = (byte*) 40741
|
||||
const nomodify byte* VERA_DATA0 = (byte*) 40739
|
||||
const nomodify byte VERA_DCSEL = 2
|
||||
const nomodify byte* VERA_DC_VIDEO = (byte*) 40745
|
||||
const nomodify byte* VERA_IEN = (byte*) 40742
|
||||
const nomodify byte VERA_INC_1 = $10
|
||||
const nomodify byte* VERA_ISR = (byte*) 40743
|
||||
const byte VERA_SPRITES_ENABLE = $40
|
||||
const nomodify word VERA_SPRITE_8BPP = $8000
|
||||
const nomodify dword VERA_SPRITE_ATTR = $1fc00
|
||||
const nomodify byte VERA_VSYNC = 1
|
||||
void __start()
|
||||
void irq_vsync()
|
||||
word~ irq_vsync::$5 zp[2]:12 4.0
|
||||
word~ irq_vsync::$6 zp[2]:14 4.0
|
||||
word*~ irq_vsync::$7 zp[2]:12 4.0
|
||||
word*~ irq_vsync::$8 zp[2]:14 4.0
|
||||
void main()
|
||||
void memcpy_to_vram(byte memcpy_to_vram::vbank , void* memcpy_to_vram::vdest , void* memcpy_to_vram::src , word memcpy_to_vram::num)
|
||||
byte~ memcpy_to_vram::$0 reg byte a 202.0
|
||||
byte~ memcpy_to_vram::$1 reg byte a 202.0
|
||||
byte~ memcpy_to_vram::$2 reg byte a 202.0
|
||||
byte* memcpy_to_vram::end
|
||||
byte* memcpy_to_vram::end#0 end zp[2]:6 183.66666666666669
|
||||
word memcpy_to_vram::num
|
||||
word memcpy_to_vram::num#3 num zp[2]:6 12.625
|
||||
byte* memcpy_to_vram::s
|
||||
byte* memcpy_to_vram::s#1 s zp[2]:4 2002.0
|
||||
byte* memcpy_to_vram::s#2 s zp[2]:4 1368.3333333333335
|
||||
byte* memcpy_to_vram::s#4 s zp[2]:4 202.0
|
||||
void* memcpy_to_vram::src
|
||||
void* memcpy_to_vram::src#3 src zp[2]:4
|
||||
byte memcpy_to_vram::vbank
|
||||
byte memcpy_to_vram::vbank#3 reg byte x 16.833333333333332
|
||||
void* memcpy_to_vram::vdest
|
||||
void* memcpy_to_vram::vdest#3 vdest zp[2]:2 50.5
|
||||
volatile word sin_idx_x loadstore zp[2]:8 1.9999999999999998
|
||||
volatile word sin_idx_y loadstore zp[2]:10 1.3333333333333335
|
||||
|
||||
zp[2]:2 [ memcpy_to_vram::vdest#3 ]
|
||||
reg byte x [ memcpy_to_vram::vbank#3 ]
|
||||
zp[2]:4 [ memcpy_to_vram::src#3 memcpy_to_vram::s#2 memcpy_to_vram::s#4 memcpy_to_vram::s#1 ]
|
||||
zp[2]:6 [ memcpy_to_vram::num#3 memcpy_to_vram::end#0 ]
|
||||
zp[2]:8 [ sin_idx_x ]
|
||||
zp[2]:10 [ sin_idx_y ]
|
||||
zp[2]:12 [ irq_vsync::$5 irq_vsync::$7 ]
|
||||
zp[2]:14 [ irq_vsync::$6 irq_vsync::$8 ]
|
||||
reg byte a [ memcpy_to_vram::$0 ]
|
||||
reg byte a [ memcpy_to_vram::$1 ]
|
||||
reg byte a [ memcpy_to_vram::$2 ]
|
||||
mem[8] [ SPRITE_ATTR ]
|
@ -93,7 +93,6 @@ memcpy_to_vram: {
|
||||
.label vdest = DEFAULT_SCREEN+$100
|
||||
.label src = main.MSG2
|
||||
.label end = src+num
|
||||
// Transfer the data
|
||||
.label s = 4
|
||||
// *VERA_CTRL &= ~VERA_ADDRSEL
|
||||
// Select DATA0
|
||||
@ -115,7 +114,7 @@ memcpy_to_vram: {
|
||||
lda #>src
|
||||
sta.z s+1
|
||||
__b1:
|
||||
// for(; s!=end; s++)
|
||||
// for(char *s = src; s!=end; s++)
|
||||
lda.z s+1
|
||||
cmp #>end
|
||||
bne __b2
|
||||
@ -129,7 +128,7 @@ memcpy_to_vram: {
|
||||
ldy #0
|
||||
lda (s),y
|
||||
sta VERA_DATA0
|
||||
// for(; s!=end; s++)
|
||||
// for(char *s = src; s!=end; s++)
|
||||
inc.z s
|
||||
bne !+
|
||||
inc.z s+1
|
||||
|
@ -1,3 +1,4 @@
|
||||
Inlined call call __init
|
||||
|
||||
CONTROL FLOW GRAPH SSA
|
||||
|
||||
@ -32,10 +33,10 @@ memcpy_to_vram: scope:[memcpy_to_vram] from main::@3
|
||||
*VERA_ADDRX_M = memcpy_to_vram::$1
|
||||
memcpy_to_vram::$2 = VERA_INC_1 | memcpy_to_vram::vbank#1
|
||||
*VERA_ADDRX_H = memcpy_to_vram::$2
|
||||
memcpy_to_vram::s#0 = ((byte*)) memcpy_to_vram::src#1
|
||||
memcpy_to_vram::$5 = (byte*)memcpy_to_vram::src#1
|
||||
memcpy_to_vram::$3 = memcpy_to_vram::$5 + memcpy_to_vram::num#1
|
||||
memcpy_to_vram::end#0 = memcpy_to_vram::$3
|
||||
memcpy_to_vram::s#0 = ((byte*)) memcpy_to_vram::src#1
|
||||
to:memcpy_to_vram::@1
|
||||
memcpy_to_vram::@1: scope:[memcpy_to_vram] from memcpy_to_vram memcpy_to_vram::@2
|
||||
memcpy_to_vram::end#1 = phi( memcpy_to_vram/memcpy_to_vram::end#0, memcpy_to_vram::@2/memcpy_to_vram::end#2 )
|
||||
@ -54,7 +55,7 @@ memcpy_to_vram::@return: scope:[memcpy_to_vram] from memcpy_to_vram::@1
|
||||
to:@return
|
||||
|
||||
void main()
|
||||
main: scope:[main] from __start
|
||||
main: scope:[main] from __start::@1
|
||||
main::vaddr#0 = DEFAULT_SCREEN
|
||||
main::i#0 = 0
|
||||
to:main::@1
|
||||
@ -103,11 +104,15 @@ main::@return: scope:[main] from main::@6
|
||||
|
||||
void __start()
|
||||
__start: scope:[__start] from
|
||||
call main
|
||||
to:__start::__init1
|
||||
__start::__init1: scope:[__start] from __start
|
||||
to:__start::@1
|
||||
__start::@1: scope:[__start] from __start
|
||||
__start::@1: scope:[__start] from __start::__init1
|
||||
call main
|
||||
to:__start::@2
|
||||
__start::@2: scope:[__start] from __start::@1
|
||||
to:__start::@return
|
||||
__start::@return: scope:[__start] from __start::@1
|
||||
__start::@return: scope:[__start] from __start::@2
|
||||
return
|
||||
to:@return
|
||||
|
||||
@ -249,8 +254,8 @@ Constant memcpy_to_vram::vbank#0 = 0
|
||||
Constant memcpy_to_vram::vdest#0 = (void*)DEFAULT_SCREEN+$100
|
||||
Constant memcpy_to_vram::src#0 = (void*)main::MSG2
|
||||
Successful SSA optimization Pass2ConstantIdentification
|
||||
Constant memcpy_to_vram::s#0 = (byte*)memcpy_to_vram::src#0
|
||||
Constant memcpy_to_vram::$5 = (byte*)memcpy_to_vram::src#0
|
||||
Constant memcpy_to_vram::s#0 = (byte*)memcpy_to_vram::src#0
|
||||
Successful SSA optimization Pass2ConstantIdentification
|
||||
Simplifying expression containing zero vpoke::vbank#2 in [6] vpoke::$2 = VERA_INC_0 | vpoke::vbank#2
|
||||
Simplifying expression containing zero VERA_INC_1 in [16] memcpy_to_vram::$2 = VERA_INC_1 | memcpy_to_vram::vbank#0
|
||||
@ -260,7 +265,9 @@ Eliminating unused constant memcpy_to_vram::vbank#0
|
||||
Successful SSA optimization PassNEliminateUnusedVars
|
||||
Removing unused procedure __start
|
||||
Removing unused procedure block __start
|
||||
Removing unused procedure block __start::__init1
|
||||
Removing unused procedure block __start::@1
|
||||
Removing unused procedure block __start::@2
|
||||
Removing unused procedure block __start::@return
|
||||
Successful SSA optimization PassNEliminateEmptyStart
|
||||
Resolving string sizeof() sizeof main::MSG2
|
||||
@ -488,12 +495,14 @@ REGISTER UPLIFT SCOPES
|
||||
Uplift Scope [vpoke] 202: zp[1]:12 [ vpoke::$0 ] 202: zp[1]:13 [ vpoke::$1 ] 89: zp[2]:7 [ vpoke::vaddr#2 vpoke::vaddr#0 vpoke::vaddr#1 ] 38: zp[1]:9 [ vpoke::data#2 vpoke::data#0 ]
|
||||
Uplift Scope [memcpy_to_vram] 336.67: zp[2]:5 [ memcpy_to_vram::s#2 memcpy_to_vram::s#1 ]
|
||||
Uplift Scope [main] 26.89: zp[1]:2 [ main::i#2 main::i#1 ] 17.6: zp[2]:3 [ main::vaddr#3 main::vaddr#2 ] 11: zp[2]:10 [ main::vaddr#1 ]
|
||||
Uplift Scope [VERA_SPRITE]
|
||||
Uplift Scope [MOS6522_VIA]
|
||||
Uplift Scope []
|
||||
|
||||
Uplifting [vpoke] best 1750 combination reg byte a [ vpoke::$0 ] reg byte a [ vpoke::$1 ] zp[2]:7 [ vpoke::vaddr#2 vpoke::vaddr#0 vpoke::vaddr#1 ] reg byte x [ vpoke::data#2 vpoke::data#0 ]
|
||||
Uplifting [memcpy_to_vram] best 1750 combination zp[2]:5 [ memcpy_to_vram::s#2 memcpy_to_vram::s#1 ]
|
||||
Uplifting [main] best 1630 combination reg byte y [ main::i#2 main::i#1 ] zp[2]:3 [ main::vaddr#3 main::vaddr#2 ] zp[2]:10 [ main::vaddr#1 ]
|
||||
Uplifting [VERA_SPRITE] best 1630 combination
|
||||
Uplifting [MOS6522_VIA] best 1630 combination
|
||||
Uplifting [] best 1630 combination
|
||||
Coalescing zero page register [ zp[2]:3 [ main::vaddr#3 main::vaddr#2 ] ] with [ zp[2]:10 [ main::vaddr#1 ] ] - score: 2
|
||||
@ -638,7 +647,6 @@ memcpy_to_vram: {
|
||||
.label vdest = DEFAULT_SCREEN+$100
|
||||
.label src = main.MSG2
|
||||
.label end = src+num
|
||||
// Transfer the data
|
||||
.label s = 4
|
||||
// [14] *VERA_CTRL = *VERA_CTRL & ~VERA_ADDRSEL -- _deref_pbuc1=_deref_pbuc1_band_vbuc2
|
||||
// Select DATA0
|
||||
@ -942,7 +950,6 @@ memcpy_to_vram: {
|
||||
.label vdest = DEFAULT_SCREEN+$100
|
||||
.label src = main.MSG2
|
||||
.label end = src+num
|
||||
// Transfer the data
|
||||
.label s = 4
|
||||
// *VERA_CTRL &= ~VERA_ADDRSEL
|
||||
// [14] *VERA_CTRL = *VERA_CTRL & ~VERA_ADDRSEL -- _deref_pbuc1=_deref_pbuc1_band_vbuc2
|
||||
@ -971,7 +978,7 @@ memcpy_to_vram: {
|
||||
sta.z s+1
|
||||
// memcpy_to_vram::@1
|
||||
__b1:
|
||||
// for(; s!=end; s++)
|
||||
// for(char *s = src; s!=end; s++)
|
||||
// [19] if(memcpy_to_vram::s#2!=memcpy_to_vram::end#0) goto memcpy_to_vram::@2 -- pbuz1_neq_pbuc1_then_la1
|
||||
lda.z s+1
|
||||
cmp #>end
|
||||
@ -990,7 +997,7 @@ memcpy_to_vram: {
|
||||
ldy #0
|
||||
lda (s),y
|
||||
sta VERA_DATA0
|
||||
// for(; s!=end; s++)
|
||||
// for(char *s = src; s!=end; s++)
|
||||
// [22] memcpy_to_vram::s#1 = ++ memcpy_to_vram::s#2 -- pbuz1=_inc_pbuz1
|
||||
inc.z s
|
||||
bne !+
|
||||
|
Loading…
Reference in New Issue
Block a user