1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-10-14 18:24:10 +00:00

Added new MEGA65 DMA methods and tests. Added a missing fragment.

This commit is contained in:
jespergravgaard 2020-12-03 01:37:58 +01:00
parent 5a99c43efb
commit 340db44a84
31 changed files with 7826 additions and 1746 deletions

View File

@ -1,4 +1,4 @@
//KICKC FRAGMENT CACHE 10dedb3bb9 10dedb58e1
//KICKC FRAGMENT CACHE 106673312a 1066734e54
//FRAGMENT vbuz1=vbuc1
lda #{c1}
sta {z1}

View File

@ -1,4 +1,4 @@
//KICKC FRAGMENT CACHE 10dedb3bb9 10dedb58e1
//KICKC FRAGMENT CACHE 106673312a 1066734e54
//FRAGMENT _deref_pbuc1=vbuc2
lda #{c2}
sta {c1}
@ -1389,37 +1389,70 @@ asw {z1}
asw {z1}
asw {z1}
asw {z1}
//FRAGMENT _deref_pbuc1=_inc__deref_pbuc1
inc {c1}
//FRAGMENT vwuz1=vbuc1
lda #<{c1}
sta {z1}
lda #>{c1}
sta {z1}+1
//FRAGMENT _deref_pbuc1_eq_vbuz1_then_la1
lda {c1}
cmp {z1}
beq {la1}
//FRAGMENT _deref_pbuc1=_dec__deref_pbuc1
dec {c1}
//FRAGMENT pbuc1_derefidx_vbuz1=_inc_pbuc1_derefidx_vbuz1
ldx {z1}
inc {c1},x
//FRAGMENT vwuz1=vwuc1
lda #<{c1}
sta {z1}
lda #>{c1}
sta {z1}+1
//FRAGMENT vbuz1=_lo_vwuz2
//FRAGMENT pwuz1=pbuc1
lda #<{c1}
sta {z1}
lda #>{c1}
sta {z1}+1
//FRAGMENT pbuz1=pbuz1_plus_vwuc1
clc
lda {z1}
adc #<{c1}
sta {z1}
lda {z1}+1
adc #>{c1}
sta {z1}+1
//FRAGMENT pbuz1_derefidx_vbuz2=pbuz3_derefidx_vbuz2
ldy {z2}
lda ({z3}),y
sta ({z1}),y
//FRAGMENT pwuz1=pwuz1_plus_vbuc1
lda #{c1}
clc
adc {z1}
sta {z1}
bcc !+
inc {z1}+1
!:
//FRAGMENT vbuz1=vbuz2_rol_1
lda {z2}
asl
sta {z1}
//FRAGMENT vbuz1=_hi_vwuz2
lda {z2}+1
sta {z1}
//FRAGMENT vbuz1=vbuz2_bor_vbuz3
lda {z2}
ora {z3}
//FRAGMENT pwuz1_derefidx_vbuz2=vwuz3
ldy {z2}
lda {z3}
sta ({z1}),y
iny
lda {z3}+1
sta ({z1}),y
//FRAGMENT vwuz1=vwuz1_plus_vbuc1
lda #{c1}
clc
adc {z1}
sta {z1}
bcc !+
inc {z1}+1
!:
//FRAGMENT _deref_pwuc1=vwuz1
lda {z1}
sta {c1}
lda {z1}+1
sta {c1}+1
//FRAGMENT _deref_qbuc1=_ptr_vbuz1
lda {z1}
sta {c1}
lda #0
sta {c1}+1
//FRAGMENT _deref_qbuc1=pbuz1
lda {z1}
sta {c1}
lda {z1}+1
sta {c1}+1
//FRAGMENT _deref_pwuc1=vwuc2
lda #<{c2}
sta {c1}
@ -1430,112 +1463,162 @@ lda #<{c2}
sta {c1}
lda #>{c2}
sta {c1}+1
//FRAGMENT _deref_pbuc1_eq_vbuaa_then_la1
cmp {c1}
beq {la1}
//FRAGMENT pbuc1_derefidx_vbuaa=_inc_pbuc1_derefidx_vbuaa
tax
inc {c1},x
//FRAGMENT pbuc1_derefidx_vbuxx=_inc_pbuc1_derefidx_vbuxx
inc {c1},x
//FRAGMENT vbuaa=_lo_vwuz1
//FRAGMENT pbuz1_derefidx_vbuaa=pbuz2_derefidx_vbuaa
tay
lda ({z2}),y
sta ({z1}),y
//FRAGMENT pbuz1_derefidx_vbuxx=pbuz2_derefidx_vbuxx
txa
tay
lda ({z2}),y
sta ({z1}),y
//FRAGMENT pbuz1_derefidx_vbuyy=pbuz2_derefidx_vbuyy
lda ({z2}),y
sta ({z1}),y
//FRAGMENT pbuz1_derefidx_vbuzz=pbuz2_derefidx_vbuzz
tza
tay
lda ({z2}),y
sta ({z1}),y
//FRAGMENT vwuz1=_word_vbuaa
sta {z1}
lda #0
sta {z1}+1
//FRAGMENT vbuz1=vbuaa_rol_1
asl
sta {z1}
//FRAGMENT vbuz1=vbuxx_rol_1
txa
asl
sta {z1}
//FRAGMENT vbuz1=vbuyy_rol_1
tya
asl
sta {z1}
//FRAGMENT vbuz1=vbuzz_rol_1
tza
asl
sta {z1}
//FRAGMENT vbuaa=vbuz1_rol_1
lda {z1}
//FRAGMENT vbuxx=_lo_vwuz1
ldx {z1}
//FRAGMENT vbuaa=_hi_vwuz1
lda {z1}+1
//FRAGMENT vbuxx=_hi_vwuz1
ldx {z1}+1
//FRAGMENT vbuz1=vbuxx_bor_vbuz2
asl
//FRAGMENT vbuaa=vbuaa_rol_1
asl
//FRAGMENT vbuaa=vbuxx_rol_1
txa
ora {z2}
sta {z1}
//FRAGMENT vbuz1=vbuyy_bor_vbuz2
asl
//FRAGMENT vbuaa=vbuyy_rol_1
tya
ora {z2}
sta {z1}
//FRAGMENT vbuz1=vbuzz_bor_vbuz2
asl
//FRAGMENT vbuaa=vbuzz_rol_1
tza
ora {z2}
sta {z1}
//FRAGMENT vbuz1=vbuz2_bor_vbuaa
ora {z2}
sta {z1}
//FRAGMENT vbuz1=vbuxx_bor_vbuaa
stx $ff
ora $ff
sta {z1}
//FRAGMENT vbuz1=vbuyy_bor_vbuaa
sty $ff
ora $ff
sta {z1}
//FRAGMENT vbuz1=vbuzz_bor_vbuaa
tay
tza
sty $ff
ora $ff
sta {z1}
//FRAGMENT vbuz1=vbuz2_bor_vbuxx
asl
//FRAGMENT vbuxx=vbuz1_rol_1
lda {z1}
asl
tax
//FRAGMENT vbuxx=vbuaa_rol_1
asl
tax
//FRAGMENT vbuxx=vbuxx_rol_1
txa
ora {z2}
sta {z1}
//FRAGMENT vbuz1=vbuxx_bor_vbuxx
stx {z1}
//FRAGMENT vbuyy=_lo_vwuz1
ldy {z1}
//FRAGMENT vbuzz=_lo_vwuz1
ldz {z1}
//FRAGMENT vbuyy=_hi_vwuz1
ldy {z1}+1
//FRAGMENT vbuzz=_hi_vwuz1
ldz {z1}+1
//FRAGMENT vbuz1=vbuz2_bor_vbuyy
asl
tax
//FRAGMENT vbuxx=vbuyy_rol_1
tya
ora {z2}
sta {z1}
//FRAGMENT pbuc1_derefidx_vbuyy=_inc_pbuc1_derefidx_vbuyy
lda {c1},y
inc
sta {c1},y
//FRAGMENT pbuc1_derefidx_vbuzz=_inc_pbuc1_derefidx_vbuzz
asl
tax
//FRAGMENT vbuxx=vbuzz_rol_1
tza
asl
tax
inc {c1},x
//FRAGMENT _deref_pbuc1_eq_vbuxx_then_la1
cpx {c1}
beq {la1}
//FRAGMENT _deref_pbuc1_eq_vbuyy_then_la1
cpy {c1}
beq {la1}
//FRAGMENT _deref_pbuc1_eq_vbuzz_then_la1
cpz {c1}
beq {la1}
//FRAGMENT vbuaa=vbuz1_bor_vbuaa
ora {z1}
//FRAGMENT vbuxx=vbuz1_bor_vbuaa
ora {z1}
tax
//FRAGMENT vbuyy=vbuz1_bor_vbuaa
ora {z1}
//FRAGMENT vbuyy=vbuz1_rol_1
lda {z1}
asl
tay
//FRAGMENT vbuzz=vbuz1_bor_vbuaa
ora {z1}
//FRAGMENT vbuyy=vbuaa_rol_1
asl
tay
//FRAGMENT vbuyy=vbuxx_rol_1
txa
asl
tay
//FRAGMENT vbuyy=vbuyy_rol_1
tya
asl
tay
//FRAGMENT vbuyy=vbuzz_rol_1
tza
asl
tay
//FRAGMENT vbuzz=vbuz1_rol_1
lda {z1}
asl
taz
//FRAGMENT vbuz1=vbuz2_bor_vbuzz
//FRAGMENT vbuzz=vbuaa_rol_1
asl
taz
//FRAGMENT vbuzz=vbuxx_rol_1
txa
asl
taz
//FRAGMENT vbuzz=vbuyy_rol_1
tya
asl
taz
//FRAGMENT vbuzz=vbuzz_rol_1
tza
ora {z2}
sta {z1}
//FRAGMENT vbuaa=vbuxx_bor_vbuaa
stx $ff
ora $ff
//FRAGMENT vbuaa=vbuyy_bor_vbuaa
sty $ff
ora $ff
//FRAGMENT vbuaa=vbuzz_bor_vbuaa
asl
taz
//FRAGMENT pwuz1_derefidx_vbuaa=vwuz2
tay
lda {z2}
sta ({z1}),y
iny
lda {z2}+1
sta ({z1}),y
//FRAGMENT pwuz1_derefidx_vbuxx=vwuz2
txa
tay
lda {z2}
sta ({z1}),y
iny
lda {z2}+1
sta ({z1}),y
//FRAGMENT pwuz1_derefidx_vbuyy=vwuz2
lda {z2}
sta ({z1}),y
iny
lda {z2}+1
sta ({z1}),y
//FRAGMENT pwuz1_derefidx_vbuzz=vwuz2
tza
sty $ff
ora $ff
tay
lda {z2}
sta ({z1}),y
iny
lda {z2}+1
sta ({z1}),y
//FRAGMENT _deref_qbuc1=_ptr_vbuxx
txa
sta {c1}
lda #0
sta {c1}+1
//FRAGMENT _deref_qbuc1=_ptr_vbuyy
tya
sta {c1}
lda #0
sta {c1}+1
//FRAGMENT _deref_qbuc1=_ptr_vbuzz
tza
sta {c1}
lda #0
sta {c1}+1
//FRAGMENT vwuz1=vbuc1
lda #<{c1}
sta {z1}
lda #>{c1}
sta {z1}+1
//FRAGMENT vduz1=vduc1
lda #<{c1}
sta {z1}
@ -1589,6 +1672,16 @@ lda {z2}
sta {z1}
lda {z2}+1
sta {z1}+1
//FRAGMENT vbuz1=_lo_vwuz2
lda {z2}
sta {z1}
//FRAGMENT vbuz1=_hi_vwuz2
lda {z2}+1
sta {z1}
//FRAGMENT vbuz1=vbuz2_bor_vbuz3
lda {z2}
ora {z3}
sta {z1}
//FRAGMENT vduz1=vduz2_ror_4
lda {z2}+3
lsr
@ -2175,6 +2268,49 @@ dey
bne !-
!e:
taz
//FRAGMENT vbuaa=_lo_vwuz1
lda {z1}
//FRAGMENT vbuxx=_lo_vwuz1
ldx {z1}
//FRAGMENT vbuaa=_hi_vwuz1
lda {z1}+1
//FRAGMENT vbuxx=_hi_vwuz1
ldx {z1}+1
//FRAGMENT vbuz1=vbuxx_bor_vbuz2
txa
ora {z2}
sta {z1}
//FRAGMENT vbuz1=vbuyy_bor_vbuz2
tya
ora {z2}
sta {z1}
//FRAGMENT vbuz1=vbuzz_bor_vbuz2
tza
ora {z2}
sta {z1}
//FRAGMENT vbuz1=vbuz2_bor_vbuaa
ora {z2}
sta {z1}
//FRAGMENT vbuz1=vbuxx_bor_vbuaa
stx $ff
ora $ff
sta {z1}
//FRAGMENT vbuz1=vbuyy_bor_vbuaa
sty $ff
ora $ff
sta {z1}
//FRAGMENT vbuz1=vbuzz_bor_vbuaa
tay
tza
sty $ff
ora $ff
sta {z1}
//FRAGMENT vbuz1=vbuz2_bor_vbuxx
txa
ora {z2}
sta {z1}
//FRAGMENT vbuz1=vbuxx_bor_vbuxx
stx {z1}
//FRAGMENT vbuaa=_hi__word_vduz1
lda {z1}+1
//FRAGMENT vbuxx=_hi__word_vduz1
@ -2239,6 +2375,20 @@ tay
tza
ora {z1}
taz
//FRAGMENT vbuaa=vbuz1_bor_vbuaa
ora {z1}
//FRAGMENT vbuxx=vbuz1_bor_vbuaa
ora {z1}
tax
//FRAGMENT vbuyy=vbuz1_bor_vbuaa
ora {z1}
tay
//FRAGMENT vbuzz=vbuz1_bor_vbuaa
ora {z1}
taz
//FRAGMENT vbuaa=vbuxx_bor_vbuaa
stx $ff
ora $ff
//FRAGMENT vbuxx=vbuxx_bor_vbuaa
stx $ff
ora $ff
@ -2251,6 +2401,9 @@ tay
stx $ff
ora $ff
taz
//FRAGMENT vbuaa=vbuyy_bor_vbuaa
sty $ff
ora $ff
//FRAGMENT vbuxx=vbuyy_bor_vbuaa
sty $ff
ora $ff
@ -2263,6 +2416,11 @@ tay
sty $ff
ora $ff
taz
//FRAGMENT vbuaa=vbuzz_bor_vbuaa
tay
tza
sty $ff
ora $ff
//FRAGMENT vbuxx=vbuzz_bor_vbuaa
tax
tza
@ -2296,6 +2454,18 @@ tay
txa
ora {z1}
taz
//FRAGMENT vbuyy=_lo_vwuz1
ldy {z1}
//FRAGMENT vbuzz=_lo_vwuz1
ldz {z1}
//FRAGMENT vbuyy=_hi_vwuz1
ldy {z1}+1
//FRAGMENT vbuzz=_hi_vwuz1
ldz {z1}+1
//FRAGMENT vbuz1=vbuz2_bor_vbuyy
tya
ora {z2}
sta {z1}
//FRAGMENT vbuyy=_hi__word_vduz1
ldy {z1}+1
//FRAGMENT vbuzz=_hi__word_vduz1
@ -2322,6 +2492,10 @@ tza
tax
tya
sta {c1},x
//FRAGMENT vbuz1=vbuz2_bor_vbuzz
tza
ora {z2}
sta {z1}
//FRAGMENT vbuyy=vbuaa
tay
//FRAGMENT vbuzz=vbuaa

View File

@ -1,4 +1,4 @@
//KICKC FRAGMENT CACHE 10dedb3bb9 10dedb58e1
//KICKC FRAGMENT CACHE 106673312a 1066734e54
//FRAGMENT vbuz1=vbuc1
lda #{c1}
sta {z1}

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
//KICKC FRAGMENT CACHE 10dedb3bb9 10dedb58e1
//KICKC FRAGMENT CACHE 106673312a 1066734e54
//FRAGMENT vbuz1=_deref_pbuc1
lda {c1}
sta {z1}

View File

@ -0,0 +1,3 @@
sta {c1}
lda #0
sta {c1}+1

View File

@ -5,10 +5,7 @@ import dk.camelot64.kickc.model.InternalError;
import dk.camelot64.kickc.model.symbols.ProgramScope;
import dk.camelot64.kickc.model.types.SymbolType;
import dk.camelot64.kickc.model.types.SymbolTypePointer;
import dk.camelot64.kickc.model.values.ConstantInteger;
import dk.camelot64.kickc.model.values.ConstantLiteral;
import dk.camelot64.kickc.model.values.ConstantPointer;
import dk.camelot64.kickc.model.values.ConstantString;
import dk.camelot64.kickc.model.values.*;
/** Unary Cast to a pointer ( type* ) */
public class OperatorCastPtr extends OperatorCast {
@ -24,6 +21,8 @@ public class OperatorCastPtr extends OperatorCast {
public ConstantLiteral calculateLiteral(ConstantLiteral value, ProgramScope scope) {
if(value instanceof ConstantInteger) {
return new ConstantPointer(((ConstantInteger) value).getInteger(), pointerType.getElementType());
} else if(value instanceof ConstantChar) {
return new ConstantPointer(((ConstantChar) value).getInteger(), pointerType.getElementType());
} else if(value instanceof ConstantPointer) {
return new ConstantPointer(((ConstantPointer) value).getLocation(), pointerType.getElementType());
} else if(value instanceof ConstantString){

View File

@ -26,4 +26,20 @@ void memcpy_dma4(char dest_bank, void* dest, char src_bank, void* src, unsigned
// - src_bank The 64KB bank for the source (0-15)
// - src The source address (within the MB and bank)
// - num The number of bytes to copy
void memcpy_dma256(char dest_mb, char dest_bank, void* dest, char src_mb, char src_bank, void* src, unsigned int num);
void memcpy_dma256(char dest_mb, char dest_bank, void* dest, char src_mb, char src_bank, void* src, unsigned int num);
// Fill a memory block within the first 64K memory space using MEGA65 DMagic DMA
// Fills the values of num bytes at the destination with a single byte value.
// - dest The destination address (within the MB and bank)
// - fill The char to fill with
// - num The number of bytes to copy
void memset_dma(void* dest, char fill, unsigned int num);
// Set a memory block anywhere in the entire 256MB memory space using MEGA65 DMagic DMA
// Sets the values of num bytes to the memory block pointed to by destination.
// - dest_mb The MB value for the destination (0-255)
// - dest_bank The 64KB bank for the destination (0-15)
// - dest The destination address (within the MB and bank)
// - fill The byte to fill into the memory
// - num The number of bytes to copy
void memset_dma256(char dest_mb, char dest_bank, void* dest, char fill, unsigned int num);

View File

@ -127,3 +127,87 @@ char memcpy_dma_command256[] = {
0, // sub-command
0, 0 // modulo-value
};
// Fill a memory block within the first 64K memory space using MEGA65 DMagic DMA
// Fills the values of num bytes at the destination with a single byte value.
// - dest The destination address (within the MB and bank)
// - fill The char to fill with
// - num The number of bytes to copy
void memset_dma(void* dest, char fill, unsigned int num) {
// Remember current F018 A/B mode
char dmaMode = DMA->EN018B;
// Set up command
memset_dma_command.count = num;
memset_dma_command.src = (char*)fill;
memset_dma_command.dest = dest;
// Set F018B mode
DMA->EN018B = 1;
// Set address of DMA list
DMA->ADDRMB = 0;
DMA->ADDRBANK = 0;
DMA-> ADDRMSB = >&memset_dma_command;
// Trigger the DMA (without option lists)
DMA-> ADDRLSBTRIG = <&memset_dma_command;
// Re-enable F018A mode
DMA->EN018B = dmaMode;
}
// DMA list entry for filling data
struct DMA_LIST_F018B memset_dma_command = {
DMA_COMMAND_FILL, // command
0, // count
0, // source
0, // source bank
0, // destination
0, // destination bank
0, // sub-command
0 // modulo-value
};
// Set a memory block anywhere in the entire 256MB memory space using MEGA65 DMagic DMA
// Sets the values of num bytes to the memory block pointed to by destination.
// - dest_mb The MB value for the destination (0-255)
// - dest_bank The 64KB bank for the destination (0-15)
// - dest The destination address (within the MB and bank)
// - num The number of bytes to copy
void memset_dma256(char dest_mb, char dest_bank, void* dest, char fill, unsigned int num) {
// Remember current F018 A/B mode
char dmaMode = DMA->EN018B;
// Set up command
memset_dma_command256[1] = dest_mb;
struct DMA_LIST_F018B * f018b = (struct DMA_LIST_F018B *)(&memset_dma_command256[4]);
f018b->count = num;
f018b->dest_bank = dest_bank;
f018b->dest = dest;
// Set fill byte
f018b->src = (char*)fill;
// Set F018B mode
DMA->EN018B = 1;
// Set address of DMA list
DMA->ADDRMB = 0;
DMA->ADDRBANK = 0;
DMA-> ADDRMSB = >memset_dma_command256;
// Trigger the DMA (with option lists)
DMA-> ETRIG = <memset_dma_command256;
// Re-enable F018A mode
DMA->EN018B = dmaMode;
}
// DMA list entry with options for setting data in the 256MB memory space
// Contains DMA options options for setting MB followed by DMA_LIST_F018B struct.
char memset_dma_command256[] = {
DMA_OPTION_DEST_MB, 0x00, // Set MB of destination address
DMA_OPTION_FORMAT_F018B, // Use F018B list format
DMA_OPTION_END, // End of options
// struct DMA_LIST_F018B
DMA_COMMAND_FILL, // command
0, 0, // count
0, 0, // source
0, // source bank
0, 0, // destination
0, // destination bank
0, // sub-command
0, 0 // modulo-value
};

View File

@ -385,6 +385,16 @@ public class TestPrograms {
compileAndCompare("examples/mega65/banked-music.c");
}
@Test
public void testMega65DmaTest6() throws IOException, URISyntaxException {
compileAndCompare("examples/mega65/dma-test6.c");
}
@Test
public void testMega65DmaTest5() throws IOException, URISyntaxException {
compileAndCompare("examples/mega65/dma-test5.c");
}
@Test
public void testMega65DmaTest4() throws IOException, URISyntaxException {
compileAndCompare("examples/mega65/dma-test4.c");
@ -435,6 +445,11 @@ public class TestPrograms {
compileAndCompare("examples/mega65/raster65.c");
}
@Test
public void testMega65Dypp65() throws IOException, URISyntaxException {
compileAndCompare("examples/mega65/dypp65.c");
}
@Test
public void testAtariXlConioTest() throws IOException, URISyntaxException {
compileAndCompare("examples/atarixl/conio-test.c");

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

View File

@ -0,0 +1,14 @@
// MEGA65 DMA test using memset
// Appendix J in https://mega.scryptos.com/sharefolder-link/MEGA/MEGA65+filehost/Docs/MEGA65-Book_draft.pdf
#pragma target(mega65)
#include <mega65-dma.h>
#include <6502.h>
void main() {
// Map memory to BANK 0 : 0x00XXXX - giving access to I/O
memoryRemap(0,0,0);
// Fill screen up using DMA
memset_dma(DEFAULT_SCREEN, '*', 80*10);
}

View File

@ -0,0 +1,12 @@
// MEGA65 DMA test using memset
// Appendix J in https://mega.scryptos.com/sharefolder-link/MEGA/MEGA65+filehost/Docs/MEGA65-Book_draft.pdf
#pragma target(mega65)
#include <mega65-dma.h>
#include <6502.h>
void main() {
// Map memory to BANK 0 : 0x00XXXX - giving access to I/O
memoryRemap(0,0,0);
// Fill screen up using 256MB DMA
memset_dma256(0, 0, DEFAULT_SCREEN, '*', 80*10);
}

View File

@ -0,0 +1,104 @@
// DYPP (Different Y Pixel Position) LOGO created using DMA
// Graphics mode is 320x200 full-colour super extended attribute mode text-mode
// Character layout is column-wise giving linear addressing of the graphics (one byte per pixel)
#pragma target(mega65)
#include <mega65.h>
#include <mega65-dma.h>
#include <6502.h>
#include <string.h>
// The screen address (45*25*2=0x08ca bytes)
char * const SCREEN = 0x5000;
// The charset address (45*32*8=0x2d00 bytes)
char * const CHARSET = 0x6000;
// A logo in column-wide linear single-color memory layout
char LOGO[45*25*8] = kickasm(resource "camelot.png") {{
.var pic = LoadPicture("camelot.png", List().add($ffffff, $000000))
.for (var x=0;x<45; x++)
.for (var y=0; y<25*8; y++)
.byte pic.getSinglecolorByte(x,y)
}};
void main() {
// Avoid interrupts
SEI();
// Map memory to BANK 0 : 0x00XXXX - giving access to I/O
memoryRemap(0,0,0);
// Set sideborder width=0, disable raster delay and hot registers
VICIV->SIDBDRWD_LO = 0;
VICIV->SIDBDRWD_HI = 0;
// Disable top/bottom borders
VICIV->TBDRPOS_LO = 0;
VICIV->TBDRPOS_HI = 0;
VICIV->BBDRPOS_LO = 0;
VICIV->BBDRPOS_HI = 2;
// Enable 48MHz fast mode
VICIV->CONTROLB |= 0x40;
VICIV->CONTROLC |= 0x40;
// Enable the VIC 4
VICIV->KEY = 0x47;
VICIV->KEY = 0x53;
// Enable Super Extended Attribute Mode
VICIV->CONTROLC |= 1;
// Mode 40x25 chars - will be 45*25 when utilizing the borders
VICIV->CONTROLB &= 0x7f;
VICIV->CHARSTEP_LO = 90;
VICIV->CHARSTEP_HI = 0;
// Start text in the left border
VICIV->TEXTXPOS_LO = 40;
VICIV->TEXTXPOS_HI = 0;
// Set number of characters to display per row
VICIV->CHRCOUNT = 45;
// Set exact screen address
VICIV->SCRNPTR_LOLO = <SCREEN;
VICIV->SCRNPTR_LOHI = >SCREEN;
VICIV->SCRNPTR_HILO = 0;
VICIV->SCRNPTR_HIHI = 0;
// Set exact charset address
VICIV->CHARPTR_LOLO = <CHARSET;
VICIV->CHARPTR_LOHI = >CHARSET;
VICIV->CHARPTR_HILO = 0;
// Enable Full-Colour Mode
//VICIV->CONTROLC |= 2|4;
// Fill the screen with 0
memset_dma(SCREEN, 0, 45*25*2);
// Fill the colours with WHITE - directly into $ff80000
memset_dma256(0xff,0x08,0x0000, WHITE, 45*25*2);
// Fill the charset with 0x55
memset_dma(CHARSET, 0x55, 45*32*8);
// Extended screen (each char is an integer)
unsigned int *ESCREEN = SCREEN;
// Fill extended screen to achieve column-wise linear addressing
unsigned int *erow = ESCREEN;
for(char r=0; r<25; r++) {
unsigned int c = r;
for(char i=0; i<45; i++) {
erow[i] = c;
c += 32;
}
erow += 45;
}
// Copy the LOGO to the CHARSET
char* logo_dest = CHARSET;
char* logo_src = LOGO;
for(char col=0;col<45;col++) {
for(char y=0;y<25*8;y++) {
logo_dest[y] = logo_src[y];
}
logo_dest += 32*8;
logo_src += 25*8;
}
// Loop forever
for(;;) {
VICIV->BG_COLOR = VICII->RASTER;
}
}

View File

@ -16,6 +16,15 @@ Resolved forward reference memcpy_dma_command256 to memcpy_dma_command256
Resolved forward reference memcpy_dma_command256 to memcpy_dma_command256
Resolved forward reference memcpy_dma_command256 to memcpy_dma_command256
Resolved forward reference memcpy_dma_command256 to memcpy_dma_command256
Resolved forward reference memset_dma_command to memset_dma_command
Resolved forward reference memset_dma_command to memset_dma_command
Resolved forward reference memset_dma_command to memset_dma_command
Resolved forward reference memset_dma_command to memset_dma_command
Resolved forward reference memset_dma_command to memset_dma_command
Resolved forward reference memset_dma_command256 to memset_dma_command256
Resolved forward reference memset_dma_command256 to memset_dma_command256
Resolved forward reference memset_dma_command256 to memset_dma_command256
Resolved forward reference memset_dma_command256 to memset_dma_command256
Resolved forward reference MUSIC_END to MUSIC_END
Resolved forward reference MUSIC to MUSIC
Resolved forward reference upperCodeData to upperCodeData
@ -33,9 +42,12 @@ Setting struct to load/store in variable affected by address-of *DMA.ADDRMSB = >
Setting struct to load/store in variable affected by address-of *DMA.ADDRLSBTRIG = <&memcpy_dma_command
Setting struct to load/store in variable affected by address-of *DMA.ADDRMSB = >&memcpy_dma_command4
Setting struct to load/store in variable affected by address-of *DMA.ADDRLSBTRIG = <&memcpy_dma_command4
Setting struct to load/store in variable affected by address-of *DMA.ADDRMSB = >&memset_dma_command
Setting struct to load/store in variable affected by address-of *DMA.ADDRLSBTRIG = <&memset_dma_command
Inlined call vicSelectGfxBank::$0 = call toDd00 vicSelectGfxBank::gfx
Inlined call call __init
Eliminating unused variable with no statement memcpy_dma_command
Eliminating unused variable with no statement memset_dma_command
CONTROL FLOW GRAPH SSA

View File

@ -15,6 +15,15 @@ Resolved forward reference memcpy_dma_command256 to memcpy_dma_command256
Resolved forward reference memcpy_dma_command256 to memcpy_dma_command256
Resolved forward reference memcpy_dma_command256 to memcpy_dma_command256
Resolved forward reference memcpy_dma_command256 to memcpy_dma_command256
Resolved forward reference memset_dma_command to memset_dma_command
Resolved forward reference memset_dma_command to memset_dma_command
Resolved forward reference memset_dma_command to memset_dma_command
Resolved forward reference memset_dma_command to memset_dma_command
Resolved forward reference memset_dma_command to memset_dma_command
Resolved forward reference memset_dma_command256 to memset_dma_command256
Resolved forward reference memset_dma_command256 to memset_dma_command256
Resolved forward reference memset_dma_command256 to memset_dma_command256
Resolved forward reference memset_dma_command256 to memset_dma_command256
Fixing struct type size struct F018_DMAGIC to 17
Fixing struct type SIZE_OF struct F018_DMAGIC to 17
Fixing struct type SIZE_OF struct F018_DMAGIC to 17
@ -22,8 +31,11 @@ Setting struct to load/store in variable affected by address-of *DMA.ADDRMSB = >
Setting struct to load/store in variable affected by address-of *DMA.ADDRLSBTRIG = <&memcpy_dma_command
Setting struct to load/store in variable affected by address-of *DMA.ADDRMSB = >&memcpy_dma_command4
Setting struct to load/store in variable affected by address-of *DMA.ADDRLSBTRIG = <&memcpy_dma_command4
Setting struct to load/store in variable affected by address-of *DMA.ADDRMSB = >&memset_dma_command
Setting struct to load/store in variable affected by address-of *DMA.ADDRLSBTRIG = <&memset_dma_command
Inlined call vicSelectGfxBank::$0 = call toDd00 vicSelectGfxBank::gfx
Eliminating unused variable with no statement memcpy_dma_command4
Eliminating unused variable with no statement memset_dma_command
CONTROL FLOW GRAPH SSA

View File

@ -15,6 +15,15 @@ Resolved forward reference memcpy_dma_command256 to memcpy_dma_command256
Resolved forward reference memcpy_dma_command256 to memcpy_dma_command256
Resolved forward reference memcpy_dma_command256 to memcpy_dma_command256
Resolved forward reference memcpy_dma_command256 to memcpy_dma_command256
Resolved forward reference memset_dma_command to memset_dma_command
Resolved forward reference memset_dma_command to memset_dma_command
Resolved forward reference memset_dma_command to memset_dma_command
Resolved forward reference memset_dma_command to memset_dma_command
Resolved forward reference memset_dma_command to memset_dma_command
Resolved forward reference memset_dma_command256 to memset_dma_command256
Resolved forward reference memset_dma_command256 to memset_dma_command256
Resolved forward reference memset_dma_command256 to memset_dma_command256
Resolved forward reference memset_dma_command256 to memset_dma_command256
Fixing struct type size struct F018_DMAGIC to 17
Fixing struct type SIZE_OF struct F018_DMAGIC to 17
Fixing struct type SIZE_OF struct F018_DMAGIC to 17
@ -22,8 +31,11 @@ Setting struct to load/store in variable affected by address-of *DMA.ADDRMSB = >
Setting struct to load/store in variable affected by address-of *DMA.ADDRLSBTRIG = <&memcpy_dma_command
Setting struct to load/store in variable affected by address-of *DMA.ADDRMSB = >&memcpy_dma_command4
Setting struct to load/store in variable affected by address-of *DMA.ADDRLSBTRIG = <&memcpy_dma_command4
Setting struct to load/store in variable affected by address-of *DMA.ADDRMSB = >&memset_dma_command
Setting struct to load/store in variable affected by address-of *DMA.ADDRLSBTRIG = <&memset_dma_command
Inlined call vicSelectGfxBank::$0 = call toDd00 vicSelectGfxBank::gfx
Eliminating unused variable with no statement memcpy_dma_command
Eliminating unused variable with no statement memset_dma_command
CONTROL FLOW GRAPH SSA

View File

@ -15,6 +15,15 @@ Resolved forward reference memcpy_dma_command256 to memcpy_dma_command256
Resolved forward reference memcpy_dma_command256 to memcpy_dma_command256
Resolved forward reference memcpy_dma_command256 to memcpy_dma_command256
Resolved forward reference memcpy_dma_command256 to memcpy_dma_command256
Resolved forward reference memset_dma_command to memset_dma_command
Resolved forward reference memset_dma_command to memset_dma_command
Resolved forward reference memset_dma_command to memset_dma_command
Resolved forward reference memset_dma_command to memset_dma_command
Resolved forward reference memset_dma_command to memset_dma_command
Resolved forward reference memset_dma_command256 to memset_dma_command256
Resolved forward reference memset_dma_command256 to memset_dma_command256
Resolved forward reference memset_dma_command256 to memset_dma_command256
Resolved forward reference memset_dma_command256 to memset_dma_command256
Fixing struct type size struct F018_DMAGIC to 17
Fixing struct type SIZE_OF struct F018_DMAGIC to 17
Fixing struct type SIZE_OF struct F018_DMAGIC to 17
@ -22,9 +31,12 @@ Setting struct to load/store in variable affected by address-of *DMA.ADDRMSB = >
Setting struct to load/store in variable affected by address-of *DMA.ADDRLSBTRIG = <&memcpy_dma_command
Setting struct to load/store in variable affected by address-of *DMA.ADDRMSB = >&memcpy_dma_command4
Setting struct to load/store in variable affected by address-of *DMA.ADDRLSBTRIG = <&memcpy_dma_command4
Setting struct to load/store in variable affected by address-of *DMA.ADDRMSB = >&memset_dma_command
Setting struct to load/store in variable affected by address-of *DMA.ADDRLSBTRIG = <&memset_dma_command
Inlined call vicSelectGfxBank::$0 = call toDd00 vicSelectGfxBank::gfx
Eliminating unused variable with no statement memcpy_dma_command
Eliminating unused variable with no statement memcpy_dma_command4
Eliminating unused variable with no statement memset_dma_command
CONTROL FLOW GRAPH SSA

View File

@ -0,0 +1,149 @@
// MEGA65 DMA test using memset
// Appendix J in https://mega.scryptos.com/sharefolder-link/MEGA/MEGA65+filehost/Docs/MEGA65-Book_draft.pdf
// Functions for using the F018 DMA for very fast copying or filling of memory
// MEGA65 Registers and Constants
// The MOS 6526 Complex Interface Adapter (CIA)
// http://archive.6502.org/datasheets/mos_6526_cia_recreated.pdf
.cpu _45gs02
// MEGA65 platform PRG executable starting in MEGA65 mode.
.file [name="dma-test5.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$2001]
.segmentdef Code [start=$2017]
.segmentdef Data [startAfter="Code"]
.segment Basic
.byte $0a, $20, $0a, $00, $fe, $02, $20, $30, $00 // 10 BANK 0
.byte $15, $20, $14, $00, $9e, $20 // 20 SYS
.text toIntString(main) // NNNN
.byte $00, $00, $00 //
// DMA command fill
.const DMA_COMMAND_FILL = 3
.const OFFSET_STRUCT_F018_DMAGIC_EN018B = 3
.const OFFSET_STRUCT_DMA_LIST_F018B_COUNT = 1
.const OFFSET_STRUCT_DMA_LIST_F018B_SRC = 3
.const OFFSET_STRUCT_DMA_LIST_F018B_DEST = 6
.const OFFSET_STRUCT_F018_DMAGIC_ADDRMB = 4
.const OFFSET_STRUCT_F018_DMAGIC_ADDRBANK = 2
.const OFFSET_STRUCT_F018_DMAGIC_ADDRMSB = 1
// DMAgic F018 Controller
.label DMA = $d700
// Default address of screen character matrix
.label DEFAULT_SCREEN = $800
.segment Code
main: {
// memoryRemap(0,0,0)
// Map memory to BANK 0 : 0x00XXXX - giving access to I/O
jsr memoryRemap
// memset_dma(DEFAULT_SCREEN, '*', 80*10)
// Fill screen up using DMA
jsr memset_dma
// }
rts
}
// Remap some of the eight 8K memory blocks in the 64K address space of the 6502 to point somewhere else in the first 1MB memory space of the MEGA65.
// After the remapping the CPU will access the mapped memory whenever it uses instructions that access a remapped block.
// See section 2.3.4 in http://www.zimmers.net/cbmpics/cbm/c65/c65manual.txt for a description of the CPU memory remapper of the C65.
// remapBlocks: Indicates which 8K blocks of the 6502 address space to remap. Each bit represents one 8K block
// - bit 0 Memory block $0000-$1fff. Use constant MEMORYBLOCK_0000.
// - bit 1 Memory block $2000-$3fff. Use constant MEMORYBLOCK_2000.
// - bit 2 Memory block $4000-$5fff. Use constant MEMORYBLOCK_4000.
// - bit 3 Memory block $6000-$7fff. Use constant MEMORYBLOCK_6000.
// - bit 4 Memory block $8000-$9fff. Use constant MEMORYBLOCK_8000.
// - bit 5 Memory block $a000-$bfff. Use constant MEMORYBLOCK_A000.
// - bit 6 Memory block $c000-$dfff. Use constant MEMORYBLOCK_C000.
// - bit 7 Memory block $e000-$ffff. Use constant MEMORYBLOCK_E000.
// lowerPageOffset: Offset that will be added to any remapped blocks in the lower 32K of memory (block 0-3).
// The offset is a page offset (meaning it is multiplied by 0x100). Only the lower 12bits of the passed value is used.
// - If block 0 ($0000-$1fff) is remapped it will point to lowerPageOffset*$100.
// - If block 1 ($2000-$3fff) is remapped it will point to lowerPageOffset*$100 + $2000.
// - If block 2 ($4000-$5fff) is remapped it will point to lowerPageOffset*$100 + $4000.
// - If block 3 ($6000-$7fff) is remapped it will point to lowerPageOffset*$100 + $6000.
// upperPageOffset: Offset that will be added to any remapped blocks in the upper 32K of memory (block 4-7).
// The offset is a page offset (meaning it is multiplied by 0x100). Only the lower 12bits of the passed value is used.
// - If block 4 ($8000-$9fff) is remapped it will point to upperPageOffset*$100 + $8000
// - If block 5 ($a000-$bfff) is remapped it will point to upperPageOffset*$100 + $a000.
// - If block 6 ($c000-$dfff) is remapped it will point to upperPageOffset*$100 + $c000.
// - If block 7 ($e000-$ffff) is remapped it will point to upperPageOffset*$100 + $e000.
memoryRemap: {
.label aVal = $fc
.label xVal = $fd
.label yVal = $fe
.label zVal = $ff
// *aVal = <lowerPageOffset
lda #0
sta aVal
// *xVal = (remapBlocks << 4) | (>lowerPageOffset & 0xf)
sta xVal
// *yVal = <upperPageOffset
sta yVal
// *zVal = (remapBlocks & 0xf0) | (>upperPageOffset & 0xf)
sta zVal
// asm
lda aVal
ldx xVal
ldy yVal
ldz zVal
map
eom
// }
rts
}
// Fill a memory block within the first 64K memory space using MEGA65 DMagic DMA
// Fills the values of num bytes at the destination with a single byte value.
// - dest The destination address (within the MB and bank)
// - fill The char to fill with
// - num The number of bytes to copy
memset_dma: {
.const fill = '*'
.const num = $50*$a
.label dest = DEFAULT_SCREEN
// dmaMode = DMA->EN018B
// Remember current F018 A/B mode
ldx DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B
// memset_dma_command.count = num
// Set up command
lda #<num
sta memset_dma_command+OFFSET_STRUCT_DMA_LIST_F018B_COUNT
lda #>num
sta memset_dma_command+OFFSET_STRUCT_DMA_LIST_F018B_COUNT+1
// memset_dma_command.src = (char*)fill
lda #<fill
sta memset_dma_command+OFFSET_STRUCT_DMA_LIST_F018B_SRC
lda #>fill
sta memset_dma_command+OFFSET_STRUCT_DMA_LIST_F018B_SRC+1
// memset_dma_command.dest = dest
lda #<dest
sta memset_dma_command+OFFSET_STRUCT_DMA_LIST_F018B_DEST
lda #>dest
sta memset_dma_command+OFFSET_STRUCT_DMA_LIST_F018B_DEST+1
// DMA->EN018B = 1
// Set F018B mode
lda #1
sta DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B
// DMA->ADDRMB = 0
// Set address of DMA list
lda #0
sta DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMB
// DMA->ADDRBANK = 0
sta DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRBANK
// DMA-> ADDRMSB = >&memset_dma_command
lda #>memset_dma_command
sta DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMSB
// DMA-> ADDRLSBTRIG = <&memset_dma_command
// Trigger the DMA (without option lists)
lda #<memset_dma_command
sta DMA
// DMA->EN018B = dmaMode
// Re-enable F018A mode
stx DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B
// }
rts
}
.segment Data
// DMA list entry for filling data
memset_dma_command: .byte DMA_COMMAND_FILL
.word 0, 0
.byte 0
.word 0
.byte 0, 0
.word 0

View File

@ -0,0 +1,42 @@
void main()
main: scope:[main] from
[0] phi()
[1] call memoryRemap
to:main::@1
main::@1: scope:[main] from main
[2] phi()
[3] call memset_dma
to:main::@return
main::@return: scope:[main] from main::@1
[4] return
to:@return
void memoryRemap(byte memoryRemap::remapBlocks , word memoryRemap::lowerPageOffset , word memoryRemap::upperPageOffset)
memoryRemap: scope:[memoryRemap] from main
[5] *memoryRemap::aVal = 0
[6] *memoryRemap::xVal = 0
[7] *memoryRemap::yVal = 0
[8] *memoryRemap::zVal = 0
asm { ldaaVal ldxxVal ldyyVal ldzzVal map eom }
to:memoryRemap::@return
memoryRemap::@return: scope:[memoryRemap] from memoryRemap
[10] return
to:@return
void memset_dma(void* memset_dma::dest , byte memset_dma::fill , word memset_dma::num)
memset_dma: scope:[memset_dma] from main::@1
[11] memset_dma::dmaMode#0 = *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B)
[12] *((word*)&memset_dma_command+OFFSET_STRUCT_DMA_LIST_F018B_COUNT) = memset_dma::num#0
[13] *((byte**)&memset_dma_command+OFFSET_STRUCT_DMA_LIST_F018B_SRC) = (byte*)memset_dma::fill#0
[14] *((byte**)&memset_dma_command+OFFSET_STRUCT_DMA_LIST_F018B_DEST) = (byte*)memset_dma::dest#0
[15] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B) = 1
[16] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMB) = 0
[17] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRBANK) = 0
[18] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMSB) = >&memset_dma_command
[19] *((byte*)DMA) = <&memset_dma_command
[20] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B) = memset_dma::dmaMode#0
to:memset_dma::@return
memset_dma::@return: scope:[memset_dma] from memset_dma
[21] return
to:@return

View File

@ -0,0 +1,858 @@
Resolved forward reference memcpy_dma_command to memcpy_dma_command
Resolved forward reference memcpy_dma_command to memcpy_dma_command
Resolved forward reference memcpy_dma_command to memcpy_dma_command
Resolved forward reference memcpy_dma_command to memcpy_dma_command
Resolved forward reference memcpy_dma_command to memcpy_dma_command
Resolved forward reference memcpy_dma_command4 to memcpy_dma_command4
Resolved forward reference memcpy_dma_command4 to memcpy_dma_command4
Resolved forward reference memcpy_dma_command4 to memcpy_dma_command4
Resolved forward reference memcpy_dma_command4 to memcpy_dma_command4
Resolved forward reference memcpy_dma_command4 to memcpy_dma_command4
Resolved forward reference memcpy_dma_command4 to memcpy_dma_command4
Resolved forward reference memcpy_dma_command4 to memcpy_dma_command4
Resolved forward reference memcpy_dma_command256 to memcpy_dma_command256
Resolved forward reference memcpy_dma_command256 to memcpy_dma_command256
Resolved forward reference memcpy_dma_command256 to memcpy_dma_command256
Resolved forward reference memcpy_dma_command256 to memcpy_dma_command256
Resolved forward reference memcpy_dma_command256 to memcpy_dma_command256
Resolved forward reference memset_dma_command to memset_dma_command
Resolved forward reference memset_dma_command to memset_dma_command
Resolved forward reference memset_dma_command to memset_dma_command
Resolved forward reference memset_dma_command to memset_dma_command
Resolved forward reference memset_dma_command to memset_dma_command
Resolved forward reference memset_dma_command256 to memset_dma_command256
Resolved forward reference memset_dma_command256 to memset_dma_command256
Resolved forward reference memset_dma_command256 to memset_dma_command256
Resolved forward reference memset_dma_command256 to memset_dma_command256
Fixing struct type size struct F018_DMAGIC to 17
Fixing struct type SIZE_OF struct F018_DMAGIC to 17
Fixing struct type SIZE_OF struct F018_DMAGIC to 17
Setting struct to load/store in variable affected by address-of *DMA.ADDRMSB = >&memcpy_dma_command
Setting struct to load/store in variable affected by address-of *DMA.ADDRLSBTRIG = <&memcpy_dma_command
Setting struct to load/store in variable affected by address-of *DMA.ADDRMSB = >&memcpy_dma_command4
Setting struct to load/store in variable affected by address-of *DMA.ADDRLSBTRIG = <&memcpy_dma_command4
Setting struct to load/store in variable affected by address-of *DMA.ADDRMSB = >&memset_dma_command
Setting struct to load/store in variable affected by address-of *DMA.ADDRLSBTRIG = <&memset_dma_command
Inlined call vicSelectGfxBank::$0 = call toDd00 vicSelectGfxBank::gfx
Eliminating unused variable with no statement memcpy_dma_command
Eliminating unused variable with no statement memcpy_dma_command4
CONTROL FLOW GRAPH SSA
void memoryRemap(byte memoryRemap::remapBlocks , word memoryRemap::lowerPageOffset , word memoryRemap::upperPageOffset)
memoryRemap: scope:[memoryRemap] from main
memoryRemap::upperPageOffset#1 = phi( main/memoryRemap::upperPageOffset#0 )
memoryRemap::remapBlocks#1 = phi( main/memoryRemap::remapBlocks#0 )
memoryRemap::lowerPageOffset#1 = phi( main/memoryRemap::lowerPageOffset#0 )
memoryRemap::$0 = < memoryRemap::lowerPageOffset#1
*memoryRemap::aVal = memoryRemap::$0
memoryRemap::$1 = memoryRemap::remapBlocks#1 << 4
memoryRemap::$2 = > memoryRemap::lowerPageOffset#1
memoryRemap::$3 = memoryRemap::$2 & $f
memoryRemap::$4 = memoryRemap::$1 | memoryRemap::$3
*memoryRemap::xVal = memoryRemap::$4
memoryRemap::$5 = < memoryRemap::upperPageOffset#1
*memoryRemap::yVal = memoryRemap::$5
memoryRemap::$6 = memoryRemap::remapBlocks#1 & $f0
memoryRemap::$7 = > memoryRemap::upperPageOffset#1
memoryRemap::$8 = memoryRemap::$7 & $f
memoryRemap::$9 = memoryRemap::$6 | memoryRemap::$8
*memoryRemap::zVal = memoryRemap::$9
asm { ldaaVal ldxxVal ldyyVal ldzzVal map eom }
to:memoryRemap::@return
memoryRemap::@return: scope:[memoryRemap] from memoryRemap
return
to:@return
void memset_dma(void* memset_dma::dest , byte memset_dma::fill , word memset_dma::num)
memset_dma: scope:[memset_dma] from main::@1
memset_dma::dest#1 = phi( main::@1/memset_dma::dest#0 )
memset_dma::fill#1 = phi( main::@1/memset_dma::fill#0 )
memset_dma::num#1 = phi( main::@1/memset_dma::num#0 )
memset_dma::dmaMode#0 = *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B)
*((word*)&memset_dma_command+OFFSET_STRUCT_DMA_LIST_F018B_COUNT) = memset_dma::num#1
*((byte**)&memset_dma_command+OFFSET_STRUCT_DMA_LIST_F018B_SRC) = (byte*)memset_dma::fill#1
*((byte**)&memset_dma_command+OFFSET_STRUCT_DMA_LIST_F018B_DEST) = ((byte*)) memset_dma::dest#1
*((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B) = 1
*((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMB) = 0
*((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRBANK) = 0
*((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMSB) = >&memset_dma_command
*((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRLSBTRIG) = <&memset_dma_command
*((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B) = memset_dma::dmaMode#0
to:memset_dma::@return
memset_dma::@return: scope:[memset_dma] from memset_dma
return
to:@return
void main()
main: scope:[main] from __start
memoryRemap::remapBlocks#0 = 0
memoryRemap::lowerPageOffset#0 = 0
memoryRemap::upperPageOffset#0 = 0
call memoryRemap
to:main::@1
main::@1: scope:[main] from main
memset_dma::dest#0 = (void*)DEFAULT_SCREEN
memset_dma::fill#0 = '*'
memset_dma::num#0 = $50*$a
call memset_dma
to:main::@2
main::@2: scope:[main] from main::@1
to:main::@return
main::@return: scope:[main] from main::@2
return
to:@return
void __start()
__start: scope:[__start] from
call main
to:__start::@1
__start::@1: scope:[__start] from __start
to:__start::@return
__start::@return: scope:[__start] from __start::@1
return
to:@return
SYMBOL TABLE SSA
const nomodify byte* DEFAULT_SCREEN = (byte*)$800
const nomodify struct F018_DMAGIC* DMA = (struct F018_DMAGIC*)$d700
const nomodify byte DMA_COMMAND_FILL = 3
const byte OFFSET_STRUCT_DMA_LIST_F018B_COUNT = 1
const byte OFFSET_STRUCT_DMA_LIST_F018B_DEST = 6
const byte OFFSET_STRUCT_DMA_LIST_F018B_SRC = 3
const byte OFFSET_STRUCT_F018_DMAGIC_ADDRBANK = 2
const byte OFFSET_STRUCT_F018_DMAGIC_ADDRLSBTRIG = 0
const byte OFFSET_STRUCT_F018_DMAGIC_ADDRMB = 4
const byte OFFSET_STRUCT_F018_DMAGIC_ADDRMSB = 1
const byte OFFSET_STRUCT_F018_DMAGIC_EN018B = 3
void __start()
void main()
void memoryRemap(byte memoryRemap::remapBlocks , word memoryRemap::lowerPageOffset , word memoryRemap::upperPageOffset)
byte~ memoryRemap::$0
byte~ memoryRemap::$1
byte~ memoryRemap::$2
number~ memoryRemap::$3
number~ memoryRemap::$4
byte~ memoryRemap::$5
number~ memoryRemap::$6
byte~ memoryRemap::$7
number~ memoryRemap::$8
number~ memoryRemap::$9
const byte* memoryRemap::aVal = (byte*)$fc
word memoryRemap::lowerPageOffset
word memoryRemap::lowerPageOffset#0
word memoryRemap::lowerPageOffset#1
byte memoryRemap::remapBlocks
byte memoryRemap::remapBlocks#0
byte memoryRemap::remapBlocks#1
word memoryRemap::upperPageOffset
word memoryRemap::upperPageOffset#0
word memoryRemap::upperPageOffset#1
const byte* memoryRemap::xVal = (byte*)$fd
const byte* memoryRemap::yVal = (byte*)$fe
const byte* memoryRemap::zVal = (byte*)$ff
void memset_dma(void* memset_dma::dest , byte memset_dma::fill , word memset_dma::num)
void* memset_dma::dest
void* memset_dma::dest#0
void* memset_dma::dest#1
byte memset_dma::dmaMode
byte memset_dma::dmaMode#0
byte memset_dma::fill
byte memset_dma::fill#0
byte memset_dma::fill#1
word memset_dma::num
word memset_dma::num#0
word memset_dma::num#1
struct DMA_LIST_F018B memset_dma_command loadstore = { command: DMA_COMMAND_FILL, count: 0, src: (byte*)0, src_bank: 0, dest: (byte*)0, dest_bank: 0, sub_command: 0, modulo: 0 }
Adding number conversion cast (unumber) 4 in memoryRemap::$1 = memoryRemap::remapBlocks#1 << 4
Adding number conversion cast (unumber) $f in memoryRemap::$3 = memoryRemap::$2 & $f
Adding number conversion cast (unumber) memoryRemap::$3 in memoryRemap::$3 = memoryRemap::$2 & (unumber)$f
Adding number conversion cast (unumber) memoryRemap::$4 in memoryRemap::$4 = memoryRemap::$1 | memoryRemap::$3
Adding number conversion cast (unumber) $f0 in memoryRemap::$6 = memoryRemap::remapBlocks#1 & $f0
Adding number conversion cast (unumber) memoryRemap::$6 in memoryRemap::$6 = memoryRemap::remapBlocks#1 & (unumber)$f0
Adding number conversion cast (unumber) $f in memoryRemap::$8 = memoryRemap::$7 & $f
Adding number conversion cast (unumber) memoryRemap::$8 in memoryRemap::$8 = memoryRemap::$7 & (unumber)$f
Adding number conversion cast (unumber) memoryRemap::$9 in memoryRemap::$9 = memoryRemap::$6 | memoryRemap::$8
Adding number conversion cast (unumber) 1 in *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B) = 1
Adding number conversion cast (unumber) 0 in *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMB) = 0
Adding number conversion cast (unumber) 0 in *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRBANK) = 0
Adding number conversion cast (unumber) 0 in memoryRemap::remapBlocks#0 = 0
Adding number conversion cast (unumber) 0 in memoryRemap::lowerPageOffset#0 = 0
Adding number conversion cast (unumber) 0 in memoryRemap::upperPageOffset#0 = 0
Adding number conversion cast (unumber) $50*$a in memset_dma::num#0 = $50*$a
Successful SSA optimization PassNAddNumberTypeConversions
Inlining cast *((byte**)&memset_dma_command+OFFSET_STRUCT_DMA_LIST_F018B_DEST) = (byte*)memset_dma::dest#1
Inlining cast *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B) = (unumber)1
Inlining cast *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMB) = (unumber)0
Inlining cast *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRBANK) = (unumber)0
Inlining cast memoryRemap::remapBlocks#0 = (unumber)0
Inlining cast memoryRemap::lowerPageOffset#0 = (unumber)0
Inlining cast memoryRemap::upperPageOffset#0 = (unumber)0
Inlining cast memset_dma::num#0 = (unumber)$50*$a
Successful SSA optimization Pass2InlineCast
Simplifying constant pointer cast (byte*) 252
Simplifying constant pointer cast (byte*) 253
Simplifying constant pointer cast (byte*) 254
Simplifying constant pointer cast (byte*) 255
Simplifying constant pointer cast (struct F018_DMAGIC*) 55040
Simplifying constant pointer cast (byte*) 2048
Simplifying constant pointer cast (byte*) 0
Simplifying constant pointer cast (byte*) 0
Simplifying constant integer cast 4
Simplifying constant integer cast $f
Simplifying constant integer cast $f0
Simplifying constant integer cast $f
Simplifying constant integer cast 1
Simplifying constant integer cast 0
Simplifying constant integer cast 0
Simplifying constant integer cast 0
Simplifying constant integer cast 0
Simplifying constant integer cast 0
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type 4
Finalized unsigned number type $f
Finalized unsigned number type $f0
Finalized unsigned number type $f
Finalized unsigned number type 1
Finalized unsigned number type 0
Finalized unsigned number type 0
Finalized unsigned number type 0
Finalized unsigned number type 0
Finalized unsigned number type 0
Successful SSA optimization PassNFinalizeNumberTypeConversions
Inferred type updated to byte in memoryRemap::$3 = memoryRemap::$2 & $f
Inferred type updated to byte in memoryRemap::$4 = memoryRemap::$1 | memoryRemap::$3
Inferred type updated to byte in memoryRemap::$6 = memoryRemap::remapBlocks#1 & $f0
Inferred type updated to byte in memoryRemap::$8 = memoryRemap::$7 & $f
Inferred type updated to byte in memoryRemap::$9 = memoryRemap::$6 | memoryRemap::$8
Identical Phi Values memoryRemap::lowerPageOffset#1 memoryRemap::lowerPageOffset#0
Identical Phi Values memoryRemap::remapBlocks#1 memoryRemap::remapBlocks#0
Identical Phi Values memoryRemap::upperPageOffset#1 memoryRemap::upperPageOffset#0
Identical Phi Values memset_dma::num#1 memset_dma::num#0
Identical Phi Values memset_dma::fill#1 memset_dma::fill#0
Identical Phi Values memset_dma::dest#1 memset_dma::dest#0
Successful SSA optimization Pass2IdenticalPhiElimination
Constant right-side identified [35] memset_dma::num#0 = (unumber)$50*$a
Successful SSA optimization Pass2ConstantRValueConsolidation
Constant memoryRemap::remapBlocks#0 = 0
Constant memoryRemap::lowerPageOffset#0 = 0
Constant memoryRemap::upperPageOffset#0 = 0
Constant memset_dma::dest#0 = (void*)DEFAULT_SCREEN
Constant memset_dma::fill#0 = '*'
Constant memset_dma::num#0 = (unumber)$50*$a
Successful SSA optimization Pass2ConstantIdentification
Constant value identified (byte*)memset_dma::fill#0 in [20] *((byte**)&memset_dma_command+OFFSET_STRUCT_DMA_LIST_F018B_SRC) = (byte*)memset_dma::fill#0
Constant value identified (byte*)memset_dma::dest#0 in [21] *((byte**)&memset_dma_command+OFFSET_STRUCT_DMA_LIST_F018B_DEST) = (byte*)memset_dma::dest#0
Successful SSA optimization Pass2ConstantValues
Simplifying expression containing zero (byte*)DMA in [26] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRLSBTRIG) = <&memset_dma_command
Successful SSA optimization PassNSimplifyExpressionWithZero
Eliminating unused constant OFFSET_STRUCT_F018_DMAGIC_ADDRLSBTRIG
Successful SSA optimization PassNEliminateUnusedVars
Removing unused procedure __start
Removing unused procedure block __start
Removing unused procedure block __start::@1
Removing unused procedure block __start::@return
Successful SSA optimization PassNEliminateEmptyStart
Constant right-side identified [0] memoryRemap::$0 = < memoryRemap::lowerPageOffset#0
Constant right-side identified [2] memoryRemap::$1 = memoryRemap::remapBlocks#0 << 4
Constant right-side identified [3] memoryRemap::$2 = > memoryRemap::lowerPageOffset#0
Constant right-side identified [7] memoryRemap::$5 = < memoryRemap::upperPageOffset#0
Constant right-side identified [9] memoryRemap::$6 = memoryRemap::remapBlocks#0 & $f0
Constant right-side identified [10] memoryRemap::$7 = > memoryRemap::upperPageOffset#0
Successful SSA optimization Pass2ConstantRValueConsolidation
Constant memoryRemap::$0 = <memoryRemap::lowerPageOffset#0
Constant memoryRemap::$1 = memoryRemap::remapBlocks#0<<4
Constant memoryRemap::$2 = >memoryRemap::lowerPageOffset#0
Constant memoryRemap::$5 = <memoryRemap::upperPageOffset#0
Constant memoryRemap::$6 = memoryRemap::remapBlocks#0&$f0
Constant memoryRemap::$7 = >memoryRemap::upperPageOffset#0
Successful SSA optimization Pass2ConstantIdentification
Simplifying constant evaluating to zero <memoryRemap::lowerPageOffset#0 in
Simplifying constant evaluating to zero memoryRemap::remapBlocks#0<<4 in
Simplifying constant evaluating to zero >memoryRemap::lowerPageOffset#0 in
Simplifying constant evaluating to zero <memoryRemap::upperPageOffset#0 in
Simplifying constant evaluating to zero memoryRemap::remapBlocks#0&$f0 in
Simplifying constant evaluating to zero >memoryRemap::upperPageOffset#0 in
Successful SSA optimization PassNSimplifyConstantZero
Simplifying expression containing zero memoryRemap::$3 in [5] memoryRemap::$4 = memoryRemap::$1 | memoryRemap::$3
Simplifying expression containing zero memoryRemap::$8 in [12] memoryRemap::$9 = memoryRemap::$6 | memoryRemap::$8
Successful SSA optimization PassNSimplifyExpressionWithZero
Eliminating unused constant memoryRemap::remapBlocks#0
Eliminating unused constant memoryRemap::lowerPageOffset#0
Eliminating unused constant memoryRemap::upperPageOffset#0
Eliminating unused constant memoryRemap::$1
Eliminating unused constant memoryRemap::$6
Successful SSA optimization PassNEliminateUnusedVars
Alias memoryRemap::$4 = memoryRemap::$3
Alias memoryRemap::$9 = memoryRemap::$8
Successful SSA optimization Pass2AliasElimination
Constant right-side identified [1] memoryRemap::$4 = memoryRemap::$2 & $f
Constant right-side identified [4] memoryRemap::$9 = memoryRemap::$7 & $f
Successful SSA optimization Pass2ConstantRValueConsolidation
Constant memoryRemap::$4 = memoryRemap::$2&$f
Constant memoryRemap::$9 = memoryRemap::$7&$f
Successful SSA optimization Pass2ConstantIdentification
Simplifying constant evaluating to zero memoryRemap::$2&$f in
Simplifying constant evaluating to zero memoryRemap::$7&$f in
Successful SSA optimization PassNSimplifyConstantZero
Eliminating unused constant memoryRemap::$2
Eliminating unused constant memoryRemap::$7
Successful SSA optimization PassNEliminateUnusedVars
Constant inlined memoryRemap::$4 = 0
Constant inlined memoryRemap::$5 = 0
Constant inlined memoryRemap::$0 = 0
Constant inlined memoryRemap::$9 = 0
Successful SSA optimization Pass2ConstantInlining
Adding NOP phi() at start of main
Adding NOP phi() at start of main::@1
Adding NOP phi() at start of main::@2
CALL GRAPH
Calls in [main] to memoryRemap:1 memset_dma:3
Created 0 initial phi equivalence classes
Coalesced down to 0 phi equivalence classes
Culled Empty Block label main::@2
Adding NOP phi() at start of main
Adding NOP phi() at start of main::@1
FINAL CONTROL FLOW GRAPH
void main()
main: scope:[main] from
[0] phi()
[1] call memoryRemap
to:main::@1
main::@1: scope:[main] from main
[2] phi()
[3] call memset_dma
to:main::@return
main::@return: scope:[main] from main::@1
[4] return
to:@return
void memoryRemap(byte memoryRemap::remapBlocks , word memoryRemap::lowerPageOffset , word memoryRemap::upperPageOffset)
memoryRemap: scope:[memoryRemap] from main
[5] *memoryRemap::aVal = 0
[6] *memoryRemap::xVal = 0
[7] *memoryRemap::yVal = 0
[8] *memoryRemap::zVal = 0
asm { ldaaVal ldxxVal ldyyVal ldzzVal map eom }
to:memoryRemap::@return
memoryRemap::@return: scope:[memoryRemap] from memoryRemap
[10] return
to:@return
void memset_dma(void* memset_dma::dest , byte memset_dma::fill , word memset_dma::num)
memset_dma: scope:[memset_dma] from main::@1
[11] memset_dma::dmaMode#0 = *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B)
[12] *((word*)&memset_dma_command+OFFSET_STRUCT_DMA_LIST_F018B_COUNT) = memset_dma::num#0
[13] *((byte**)&memset_dma_command+OFFSET_STRUCT_DMA_LIST_F018B_SRC) = (byte*)memset_dma::fill#0
[14] *((byte**)&memset_dma_command+OFFSET_STRUCT_DMA_LIST_F018B_DEST) = (byte*)memset_dma::dest#0
[15] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B) = 1
[16] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMB) = 0
[17] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRBANK) = 0
[18] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMSB) = >&memset_dma_command
[19] *((byte*)DMA) = <&memset_dma_command
[20] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B) = memset_dma::dmaMode#0
to:memset_dma::@return
memset_dma::@return: scope:[memset_dma] from memset_dma
[21] return
to:@return
VARIABLE REGISTER WEIGHTS
void main()
void memoryRemap(byte memoryRemap::remapBlocks , word memoryRemap::lowerPageOffset , word memoryRemap::upperPageOffset)
word memoryRemap::lowerPageOffset
byte memoryRemap::remapBlocks
word memoryRemap::upperPageOffset
void memset_dma(void* memset_dma::dest , byte memset_dma::fill , word memset_dma::num)
void* memset_dma::dest
byte memset_dma::dmaMode
byte memset_dma::dmaMode#0 2.4444444444444446
byte memset_dma::fill
word memset_dma::num
struct DMA_LIST_F018B memset_dma_command loadstore = { command: DMA_COMMAND_FILL, count: 0, src: (byte*) 0, src_bank: 0, dest: (byte*) 0, dest_bank: 0, sub_command: 0, modulo: 0 }
Initial phi equivalence classes
Added variable memset_dma::dmaMode#0 to live range equivalence class [ memset_dma::dmaMode#0 ]
Added variable memset_dma_command to live range equivalence class [ memset_dma_command ]
Complete equivalence classes
[ memset_dma::dmaMode#0 ]
[ memset_dma_command ]
Allocated zp[1]:2 [ memset_dma::dmaMode#0 ]
Allocated mem[12] [ memset_dma_command ]
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [5] *memoryRemap::aVal = 0 [ ] ( memoryRemap:1 [ memset_dma_command ] { } ) always clobbers reg byte a
Statement [6] *memoryRemap::xVal = 0 [ ] ( memoryRemap:1 [ memset_dma_command ] { } ) always clobbers reg byte a
Statement [7] *memoryRemap::yVal = 0 [ ] ( memoryRemap:1 [ memset_dma_command ] { } ) always clobbers reg byte a
Statement [8] *memoryRemap::zVal = 0 [ ] ( memoryRemap:1 [ memset_dma_command ] { } ) always clobbers reg byte a
Statement asm { ldaaVal ldxxVal ldyyVal ldzzVal map eom } always clobbers reg byte a reg byte x reg byte y reg byte z
Statement [12] *((word*)&memset_dma_command+OFFSET_STRUCT_DMA_LIST_F018B_COUNT) = memset_dma::num#0 [ memset_dma::dmaMode#0 memset_dma_command ] ( memset_dma:3 [ memset_dma::dmaMode#0 memset_dma_command ] { } ) always clobbers reg byte a
Removing always clobbered register reg byte a as potential for zp[1]:2 [ memset_dma::dmaMode#0 ]
Statement [13] *((byte**)&memset_dma_command+OFFSET_STRUCT_DMA_LIST_F018B_SRC) = (byte*)memset_dma::fill#0 [ memset_dma::dmaMode#0 memset_dma_command ] ( memset_dma:3 [ memset_dma::dmaMode#0 memset_dma_command ] { } ) always clobbers reg byte a
Statement [14] *((byte**)&memset_dma_command+OFFSET_STRUCT_DMA_LIST_F018B_DEST) = (byte*)memset_dma::dest#0 [ memset_dma::dmaMode#0 memset_dma_command ] ( memset_dma:3 [ memset_dma::dmaMode#0 memset_dma_command ] { } ) always clobbers reg byte a
Statement [15] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B) = 1 [ memset_dma::dmaMode#0 memset_dma_command ] ( memset_dma:3 [ memset_dma::dmaMode#0 memset_dma_command ] { } ) always clobbers reg byte a
Statement [16] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMB) = 0 [ memset_dma::dmaMode#0 memset_dma_command ] ( memset_dma:3 [ memset_dma::dmaMode#0 memset_dma_command ] { } ) always clobbers reg byte a
Statement [17] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRBANK) = 0 [ memset_dma::dmaMode#0 memset_dma_command ] ( memset_dma:3 [ memset_dma::dmaMode#0 memset_dma_command ] { } ) always clobbers reg byte a
Statement [18] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMSB) = >&memset_dma_command [ memset_dma::dmaMode#0 memset_dma_command ] ( memset_dma:3 [ memset_dma::dmaMode#0 memset_dma_command ] { } ) always clobbers reg byte a
Statement [19] *((byte*)DMA) = <&memset_dma_command [ memset_dma::dmaMode#0 ] ( memset_dma:3 [ memset_dma::dmaMode#0 ] { } ) always clobbers reg byte a
Statement [5] *memoryRemap::aVal = 0 [ ] ( memoryRemap:1 [ memset_dma_command ] { } ) always clobbers reg byte a
Statement [6] *memoryRemap::xVal = 0 [ ] ( memoryRemap:1 [ memset_dma_command ] { } ) always clobbers reg byte a
Statement [7] *memoryRemap::yVal = 0 [ ] ( memoryRemap:1 [ memset_dma_command ] { } ) always clobbers reg byte a
Statement [8] *memoryRemap::zVal = 0 [ ] ( memoryRemap:1 [ memset_dma_command ] { } ) always clobbers reg byte a
Statement asm { ldaaVal ldxxVal ldyyVal ldzzVal map eom } always clobbers reg byte a reg byte x reg byte y reg byte z
Statement [12] *((word*)&memset_dma_command+OFFSET_STRUCT_DMA_LIST_F018B_COUNT) = memset_dma::num#0 [ memset_dma::dmaMode#0 memset_dma_command ] ( memset_dma:3 [ memset_dma::dmaMode#0 memset_dma_command ] { } ) always clobbers reg byte a
Statement [13] *((byte**)&memset_dma_command+OFFSET_STRUCT_DMA_LIST_F018B_SRC) = (byte*)memset_dma::fill#0 [ memset_dma::dmaMode#0 memset_dma_command ] ( memset_dma:3 [ memset_dma::dmaMode#0 memset_dma_command ] { } ) always clobbers reg byte a
Statement [14] *((byte**)&memset_dma_command+OFFSET_STRUCT_DMA_LIST_F018B_DEST) = (byte*)memset_dma::dest#0 [ memset_dma::dmaMode#0 memset_dma_command ] ( memset_dma:3 [ memset_dma::dmaMode#0 memset_dma_command ] { } ) always clobbers reg byte a
Statement [15] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B) = 1 [ memset_dma::dmaMode#0 memset_dma_command ] ( memset_dma:3 [ memset_dma::dmaMode#0 memset_dma_command ] { } ) always clobbers reg byte a
Statement [16] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMB) = 0 [ memset_dma::dmaMode#0 memset_dma_command ] ( memset_dma:3 [ memset_dma::dmaMode#0 memset_dma_command ] { } ) always clobbers reg byte a
Statement [17] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRBANK) = 0 [ memset_dma::dmaMode#0 memset_dma_command ] ( memset_dma:3 [ memset_dma::dmaMode#0 memset_dma_command ] { } ) always clobbers reg byte a
Statement [18] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMSB) = >&memset_dma_command [ memset_dma::dmaMode#0 memset_dma_command ] ( memset_dma:3 [ memset_dma::dmaMode#0 memset_dma_command ] { } ) always clobbers reg byte a
Statement [19] *((byte*)DMA) = <&memset_dma_command [ memset_dma::dmaMode#0 ] ( memset_dma:3 [ memset_dma::dmaMode#0 ] { } ) always clobbers reg byte a
Potential registers zp[1]:2 [ memset_dma::dmaMode#0 ] : zp[1]:2 , reg byte x , reg byte y , reg byte z ,
Potential registers mem[12] [ memset_dma_command ] : mem[12] ,
REGISTER UPLIFT SCOPES
Uplift Scope [memset_dma] 2.44: zp[1]:2 [ memset_dma::dmaMode#0 ]
Uplift Scope [MOS6526_CIA]
Uplift Scope [MOS6569_VICII]
Uplift Scope [MOS6581_SID]
Uplift Scope [MOS4569_VICIII]
Uplift Scope [MEGA65_VICIV]
Uplift Scope [memoryRemap]
Uplift Scope [F018_DMAGIC]
Uplift Scope [DMA_LIST_F018A]
Uplift Scope [DMA_LIST_F018B]
Uplift Scope [main]
Uplift Scope [] 0: mem[12] [ memset_dma_command ]
Uplifting [memset_dma] best 159 combination reg byte x [ memset_dma::dmaMode#0 ]
Uplifting [MOS6526_CIA] best 159 combination
Uplifting [MOS6569_VICII] best 159 combination
Uplifting [MOS6581_SID] best 159 combination
Uplifting [MOS4569_VICIII] best 159 combination
Uplifting [MEGA65_VICIV] best 159 combination
Uplifting [memoryRemap] best 159 combination
Uplifting [F018_DMAGIC] best 159 combination
Uplifting [DMA_LIST_F018A] best 159 combination
Uplifting [DMA_LIST_F018B] best 159 combination
Uplifting [main] best 159 combination
Uplifting [] best 159 combination mem[12] [ memset_dma_command ]
ASSEMBLER BEFORE OPTIMIZATION
// File Comments
// MEGA65 DMA test using memset
// Appendix J in https://mega.scryptos.com/sharefolder-link/MEGA/MEGA65+filehost/Docs/MEGA65-Book_draft.pdf
// Functions for using the F018 DMA for very fast copying or filling of memory
// MEGA65 Registers and Constants
// The MOS 6526 Complex Interface Adapter (CIA)
// http://archive.6502.org/datasheets/mos_6526_cia_recreated.pdf
// Upstart
.cpu _45gs02
// MEGA65 platform PRG executable starting in MEGA65 mode.
.file [name="dma-test5.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$2001]
.segmentdef Code [start=$2017]
.segmentdef Data [startAfter="Code"]
.segment Basic
.byte $0a, $20, $0a, $00, $fe, $02, $20, $30, $00 // 10 BANK 0
.byte $15, $20, $14, $00, $9e, $20 // 20 SYS
.text toIntString(main) // NNNN
.byte $00, $00, $00 //
// Global Constants & labels
// DMA command fill
.const DMA_COMMAND_FILL = 3
.const OFFSET_STRUCT_F018_DMAGIC_EN018B = 3
.const OFFSET_STRUCT_DMA_LIST_F018B_COUNT = 1
.const OFFSET_STRUCT_DMA_LIST_F018B_SRC = 3
.const OFFSET_STRUCT_DMA_LIST_F018B_DEST = 6
.const OFFSET_STRUCT_F018_DMAGIC_ADDRMB = 4
.const OFFSET_STRUCT_F018_DMAGIC_ADDRBANK = 2
.const OFFSET_STRUCT_F018_DMAGIC_ADDRMSB = 1
// DMAgic F018 Controller
.label DMA = $d700
// Default address of screen character matrix
.label DEFAULT_SCREEN = $800
.segment Code
// main
main: {
// [1] call memoryRemap
// Map memory to BANK 0 : 0x00XXXX - giving access to I/O
jsr memoryRemap
// [2] phi from main to main::@1 [phi:main->main::@1]
__b1_from_main:
jmp __b1
// main::@1
__b1:
// [3] call memset_dma
// Fill screen up using DMA
jsr memset_dma
jmp __breturn
// main::@return
__breturn:
// [4] return
rts
}
// memoryRemap
// Remap some of the eight 8K memory blocks in the 64K address space of the 6502 to point somewhere else in the first 1MB memory space of the MEGA65.
// After the remapping the CPU will access the mapped memory whenever it uses instructions that access a remapped block.
// See section 2.3.4 in http://www.zimmers.net/cbmpics/cbm/c65/c65manual.txt for a description of the CPU memory remapper of the C65.
// remapBlocks: Indicates which 8K blocks of the 6502 address space to remap. Each bit represents one 8K block
// - bit 0 Memory block $0000-$1fff. Use constant MEMORYBLOCK_0000.
// - bit 1 Memory block $2000-$3fff. Use constant MEMORYBLOCK_2000.
// - bit 2 Memory block $4000-$5fff. Use constant MEMORYBLOCK_4000.
// - bit 3 Memory block $6000-$7fff. Use constant MEMORYBLOCK_6000.
// - bit 4 Memory block $8000-$9fff. Use constant MEMORYBLOCK_8000.
// - bit 5 Memory block $a000-$bfff. Use constant MEMORYBLOCK_A000.
// - bit 6 Memory block $c000-$dfff. Use constant MEMORYBLOCK_C000.
// - bit 7 Memory block $e000-$ffff. Use constant MEMORYBLOCK_E000.
// lowerPageOffset: Offset that will be added to any remapped blocks in the lower 32K of memory (block 0-3).
// The offset is a page offset (meaning it is multiplied by 0x100). Only the lower 12bits of the passed value is used.
// - If block 0 ($0000-$1fff) is remapped it will point to lowerPageOffset*$100.
// - If block 1 ($2000-$3fff) is remapped it will point to lowerPageOffset*$100 + $2000.
// - If block 2 ($4000-$5fff) is remapped it will point to lowerPageOffset*$100 + $4000.
// - If block 3 ($6000-$7fff) is remapped it will point to lowerPageOffset*$100 + $6000.
// upperPageOffset: Offset that will be added to any remapped blocks in the upper 32K of memory (block 4-7).
// The offset is a page offset (meaning it is multiplied by 0x100). Only the lower 12bits of the passed value is used.
// - If block 4 ($8000-$9fff) is remapped it will point to upperPageOffset*$100 + $8000
// - If block 5 ($a000-$bfff) is remapped it will point to upperPageOffset*$100 + $a000.
// - If block 6 ($c000-$dfff) is remapped it will point to upperPageOffset*$100 + $c000.
// - If block 7 ($e000-$ffff) is remapped it will point to upperPageOffset*$100 + $e000.
memoryRemap: {
.label aVal = $fc
.label xVal = $fd
.label yVal = $fe
.label zVal = $ff
// [5] *memoryRemap::aVal = 0 -- _deref_pbuc1=vbuc2
lda #0
sta aVal
// [6] *memoryRemap::xVal = 0 -- _deref_pbuc1=vbuc2
lda #0
sta xVal
// [7] *memoryRemap::yVal = 0 -- _deref_pbuc1=vbuc2
lda #0
sta yVal
// [8] *memoryRemap::zVal = 0 -- _deref_pbuc1=vbuc2
lda #0
sta zVal
// asm { ldaaVal ldxxVal ldyyVal ldzzVal map eom }
lda aVal
ldx xVal
ldy yVal
ldz zVal
map
eom
jmp __breturn
// memoryRemap::@return
__breturn:
// [10] return
rts
}
// memset_dma
// Fill a memory block within the first 64K memory space using MEGA65 DMagic DMA
// Fills the values of num bytes at the destination with a single byte value.
// - dest The destination address (within the MB and bank)
// - fill The char to fill with
// - num The number of bytes to copy
memset_dma: {
.const fill = '*'
.const num = $50*$a
.label dest = DEFAULT_SCREEN
// [11] memset_dma::dmaMode#0 = *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B) -- vbuxx=_deref_pbuc1
// Remember current F018 A/B mode
ldx DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B
// [12] *((word*)&memset_dma_command+OFFSET_STRUCT_DMA_LIST_F018B_COUNT) = memset_dma::num#0 -- _deref_pwuc1=vwuc2
// Set up command
lda #<num
sta memset_dma_command+OFFSET_STRUCT_DMA_LIST_F018B_COUNT
lda #>num
sta memset_dma_command+OFFSET_STRUCT_DMA_LIST_F018B_COUNT+1
// [13] *((byte**)&memset_dma_command+OFFSET_STRUCT_DMA_LIST_F018B_SRC) = (byte*)memset_dma::fill#0 -- _deref_qbuc1=pbuc2
lda #<fill
sta memset_dma_command+OFFSET_STRUCT_DMA_LIST_F018B_SRC
lda #>fill
sta memset_dma_command+OFFSET_STRUCT_DMA_LIST_F018B_SRC+1
// [14] *((byte**)&memset_dma_command+OFFSET_STRUCT_DMA_LIST_F018B_DEST) = (byte*)memset_dma::dest#0 -- _deref_qbuc1=pbuc2
lda #<dest
sta memset_dma_command+OFFSET_STRUCT_DMA_LIST_F018B_DEST
lda #>dest
sta memset_dma_command+OFFSET_STRUCT_DMA_LIST_F018B_DEST+1
// [15] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B) = 1 -- _deref_pbuc1=vbuc2
// Set F018B mode
lda #1
sta DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B
// [16] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMB) = 0 -- _deref_pbuc1=vbuc2
// Set address of DMA list
lda #0
sta DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMB
// [17] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRBANK) = 0 -- _deref_pbuc1=vbuc2
lda #0
sta DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRBANK
// [18] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMSB) = >&memset_dma_command -- _deref_pbuc1=vbuc2
lda #>memset_dma_command
sta DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMSB
// [19] *((byte*)DMA) = <&memset_dma_command -- _deref_pbuc1=vbuc2
// Trigger the DMA (without option lists)
lda #<memset_dma_command
sta DMA
// [20] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B) = memset_dma::dmaMode#0 -- _deref_pbuc1=vbuxx
// Re-enable F018A mode
stx DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B
jmp __breturn
// memset_dma::@return
__breturn:
// [21] return
rts
}
// File Data
.segment Data
// DMA list entry for filling data
memset_dma_command: .byte DMA_COMMAND_FILL
.word 0, 0
.byte 0
.word 0
.byte 0, 0
.word 0
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1
Removing instruction jmp __breturn
Removing instruction jmp __breturn
Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction lda #0
Removing instruction lda #0
Removing instruction lda #0
Removing instruction lda #0
Succesful ASM optimization Pass5UnnecesaryLoadElimination
Removing instruction __b1_from_main:
Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction __b1:
Removing instruction __breturn:
Removing instruction __breturn:
Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE
const nomodify byte* DEFAULT_SCREEN = (byte*) 2048
const nomodify struct F018_DMAGIC* DMA = (struct F018_DMAGIC*) 55040
const nomodify byte DMA_COMMAND_FILL = 3
const byte OFFSET_STRUCT_DMA_LIST_F018B_COUNT = 1
const byte OFFSET_STRUCT_DMA_LIST_F018B_DEST = 6
const byte OFFSET_STRUCT_DMA_LIST_F018B_SRC = 3
const byte OFFSET_STRUCT_F018_DMAGIC_ADDRBANK = 2
const byte OFFSET_STRUCT_F018_DMAGIC_ADDRMB = 4
const byte OFFSET_STRUCT_F018_DMAGIC_ADDRMSB = 1
const byte OFFSET_STRUCT_F018_DMAGIC_EN018B = 3
void main()
void memoryRemap(byte memoryRemap::remapBlocks , word memoryRemap::lowerPageOffset , word memoryRemap::upperPageOffset)
const byte* memoryRemap::aVal = (byte*) 252
word memoryRemap::lowerPageOffset
byte memoryRemap::remapBlocks
word memoryRemap::upperPageOffset
const byte* memoryRemap::xVal = (byte*) 253
const byte* memoryRemap::yVal = (byte*) 254
const byte* memoryRemap::zVal = (byte*) 255
void memset_dma(void* memset_dma::dest , byte memset_dma::fill , word memset_dma::num)
void* memset_dma::dest
const void* memset_dma::dest#0 dest = (void*)DEFAULT_SCREEN
byte memset_dma::dmaMode
byte memset_dma::dmaMode#0 reg byte x 2.4444444444444446
byte memset_dma::fill
const byte memset_dma::fill#0 fill = '*'
word memset_dma::num
const word memset_dma::num#0 num = (word)$50*$a
struct DMA_LIST_F018B memset_dma_command loadstore mem[12] = { command: DMA_COMMAND_FILL, count: 0, src: (byte*) 0, src_bank: 0, dest: (byte*) 0, dest_bank: 0, sub_command: 0, modulo: 0 }
reg byte x [ memset_dma::dmaMode#0 ]
mem[12] [ memset_dma_command ]
FINAL ASSEMBLER
Score: 139
// File Comments
// MEGA65 DMA test using memset
// Appendix J in https://mega.scryptos.com/sharefolder-link/MEGA/MEGA65+filehost/Docs/MEGA65-Book_draft.pdf
// Functions for using the F018 DMA for very fast copying or filling of memory
// MEGA65 Registers and Constants
// The MOS 6526 Complex Interface Adapter (CIA)
// http://archive.6502.org/datasheets/mos_6526_cia_recreated.pdf
// Upstart
.cpu _45gs02
// MEGA65 platform PRG executable starting in MEGA65 mode.
.file [name="dma-test5.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$2001]
.segmentdef Code [start=$2017]
.segmentdef Data [startAfter="Code"]
.segment Basic
.byte $0a, $20, $0a, $00, $fe, $02, $20, $30, $00 // 10 BANK 0
.byte $15, $20, $14, $00, $9e, $20 // 20 SYS
.text toIntString(main) // NNNN
.byte $00, $00, $00 //
// Global Constants & labels
// DMA command fill
.const DMA_COMMAND_FILL = 3
.const OFFSET_STRUCT_F018_DMAGIC_EN018B = 3
.const OFFSET_STRUCT_DMA_LIST_F018B_COUNT = 1
.const OFFSET_STRUCT_DMA_LIST_F018B_SRC = 3
.const OFFSET_STRUCT_DMA_LIST_F018B_DEST = 6
.const OFFSET_STRUCT_F018_DMAGIC_ADDRMB = 4
.const OFFSET_STRUCT_F018_DMAGIC_ADDRBANK = 2
.const OFFSET_STRUCT_F018_DMAGIC_ADDRMSB = 1
// DMAgic F018 Controller
.label DMA = $d700
// Default address of screen character matrix
.label DEFAULT_SCREEN = $800
.segment Code
// main
main: {
// memoryRemap(0,0,0)
// [1] call memoryRemap
// Map memory to BANK 0 : 0x00XXXX - giving access to I/O
jsr memoryRemap
// [2] phi from main to main::@1 [phi:main->main::@1]
// main::@1
// memset_dma(DEFAULT_SCREEN, '*', 80*10)
// [3] call memset_dma
// Fill screen up using DMA
jsr memset_dma
// main::@return
// }
// [4] return
rts
}
// memoryRemap
// Remap some of the eight 8K memory blocks in the 64K address space of the 6502 to point somewhere else in the first 1MB memory space of the MEGA65.
// After the remapping the CPU will access the mapped memory whenever it uses instructions that access a remapped block.
// See section 2.3.4 in http://www.zimmers.net/cbmpics/cbm/c65/c65manual.txt for a description of the CPU memory remapper of the C65.
// remapBlocks: Indicates which 8K blocks of the 6502 address space to remap. Each bit represents one 8K block
// - bit 0 Memory block $0000-$1fff. Use constant MEMORYBLOCK_0000.
// - bit 1 Memory block $2000-$3fff. Use constant MEMORYBLOCK_2000.
// - bit 2 Memory block $4000-$5fff. Use constant MEMORYBLOCK_4000.
// - bit 3 Memory block $6000-$7fff. Use constant MEMORYBLOCK_6000.
// - bit 4 Memory block $8000-$9fff. Use constant MEMORYBLOCK_8000.
// - bit 5 Memory block $a000-$bfff. Use constant MEMORYBLOCK_A000.
// - bit 6 Memory block $c000-$dfff. Use constant MEMORYBLOCK_C000.
// - bit 7 Memory block $e000-$ffff. Use constant MEMORYBLOCK_E000.
// lowerPageOffset: Offset that will be added to any remapped blocks in the lower 32K of memory (block 0-3).
// The offset is a page offset (meaning it is multiplied by 0x100). Only the lower 12bits of the passed value is used.
// - If block 0 ($0000-$1fff) is remapped it will point to lowerPageOffset*$100.
// - If block 1 ($2000-$3fff) is remapped it will point to lowerPageOffset*$100 + $2000.
// - If block 2 ($4000-$5fff) is remapped it will point to lowerPageOffset*$100 + $4000.
// - If block 3 ($6000-$7fff) is remapped it will point to lowerPageOffset*$100 + $6000.
// upperPageOffset: Offset that will be added to any remapped blocks in the upper 32K of memory (block 4-7).
// The offset is a page offset (meaning it is multiplied by 0x100). Only the lower 12bits of the passed value is used.
// - If block 4 ($8000-$9fff) is remapped it will point to upperPageOffset*$100 + $8000
// - If block 5 ($a000-$bfff) is remapped it will point to upperPageOffset*$100 + $a000.
// - If block 6 ($c000-$dfff) is remapped it will point to upperPageOffset*$100 + $c000.
// - If block 7 ($e000-$ffff) is remapped it will point to upperPageOffset*$100 + $e000.
memoryRemap: {
.label aVal = $fc
.label xVal = $fd
.label yVal = $fe
.label zVal = $ff
// *aVal = <lowerPageOffset
// [5] *memoryRemap::aVal = 0 -- _deref_pbuc1=vbuc2
lda #0
sta aVal
// *xVal = (remapBlocks << 4) | (>lowerPageOffset & 0xf)
// [6] *memoryRemap::xVal = 0 -- _deref_pbuc1=vbuc2
sta xVal
// *yVal = <upperPageOffset
// [7] *memoryRemap::yVal = 0 -- _deref_pbuc1=vbuc2
sta yVal
// *zVal = (remapBlocks & 0xf0) | (>upperPageOffset & 0xf)
// [8] *memoryRemap::zVal = 0 -- _deref_pbuc1=vbuc2
sta zVal
// asm
// asm { ldaaVal ldxxVal ldyyVal ldzzVal map eom }
lda aVal
ldx xVal
ldy yVal
ldz zVal
map
eom
// memoryRemap::@return
// }
// [10] return
rts
}
// memset_dma
// Fill a memory block within the first 64K memory space using MEGA65 DMagic DMA
// Fills the values of num bytes at the destination with a single byte value.
// - dest The destination address (within the MB and bank)
// - fill The char to fill with
// - num The number of bytes to copy
memset_dma: {
.const fill = '*'
.const num = $50*$a
.label dest = DEFAULT_SCREEN
// dmaMode = DMA->EN018B
// [11] memset_dma::dmaMode#0 = *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B) -- vbuxx=_deref_pbuc1
// Remember current F018 A/B mode
ldx DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B
// memset_dma_command.count = num
// [12] *((word*)&memset_dma_command+OFFSET_STRUCT_DMA_LIST_F018B_COUNT) = memset_dma::num#0 -- _deref_pwuc1=vwuc2
// Set up command
lda #<num
sta memset_dma_command+OFFSET_STRUCT_DMA_LIST_F018B_COUNT
lda #>num
sta memset_dma_command+OFFSET_STRUCT_DMA_LIST_F018B_COUNT+1
// memset_dma_command.src = (char*)fill
// [13] *((byte**)&memset_dma_command+OFFSET_STRUCT_DMA_LIST_F018B_SRC) = (byte*)memset_dma::fill#0 -- _deref_qbuc1=pbuc2
lda #<fill
sta memset_dma_command+OFFSET_STRUCT_DMA_LIST_F018B_SRC
lda #>fill
sta memset_dma_command+OFFSET_STRUCT_DMA_LIST_F018B_SRC+1
// memset_dma_command.dest = dest
// [14] *((byte**)&memset_dma_command+OFFSET_STRUCT_DMA_LIST_F018B_DEST) = (byte*)memset_dma::dest#0 -- _deref_qbuc1=pbuc2
lda #<dest
sta memset_dma_command+OFFSET_STRUCT_DMA_LIST_F018B_DEST
lda #>dest
sta memset_dma_command+OFFSET_STRUCT_DMA_LIST_F018B_DEST+1
// DMA->EN018B = 1
// [15] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B) = 1 -- _deref_pbuc1=vbuc2
// Set F018B mode
lda #1
sta DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B
// DMA->ADDRMB = 0
// [16] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMB) = 0 -- _deref_pbuc1=vbuc2
// Set address of DMA list
lda #0
sta DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMB
// DMA->ADDRBANK = 0
// [17] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRBANK) = 0 -- _deref_pbuc1=vbuc2
sta DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRBANK
// DMA-> ADDRMSB = >&memset_dma_command
// [18] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMSB) = >&memset_dma_command -- _deref_pbuc1=vbuc2
lda #>memset_dma_command
sta DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMSB
// DMA-> ADDRLSBTRIG = <&memset_dma_command
// [19] *((byte*)DMA) = <&memset_dma_command -- _deref_pbuc1=vbuc2
// Trigger the DMA (without option lists)
lda #<memset_dma_command
sta DMA
// DMA->EN018B = dmaMode
// [20] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B) = memset_dma::dmaMode#0 -- _deref_pbuc1=vbuxx
// Re-enable F018A mode
stx DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B
// memset_dma::@return
// }
// [21] return
rts
}
// File Data
.segment Data
// DMA list entry for filling data
memset_dma_command: .byte DMA_COMMAND_FILL
.word 0, 0
.byte 0
.word 0
.byte 0, 0
.word 0

View File

@ -0,0 +1,32 @@
const nomodify byte* DEFAULT_SCREEN = (byte*) 2048
const nomodify struct F018_DMAGIC* DMA = (struct F018_DMAGIC*) 55040
const nomodify byte DMA_COMMAND_FILL = 3
const byte OFFSET_STRUCT_DMA_LIST_F018B_COUNT = 1
const byte OFFSET_STRUCT_DMA_LIST_F018B_DEST = 6
const byte OFFSET_STRUCT_DMA_LIST_F018B_SRC = 3
const byte OFFSET_STRUCT_F018_DMAGIC_ADDRBANK = 2
const byte OFFSET_STRUCT_F018_DMAGIC_ADDRMB = 4
const byte OFFSET_STRUCT_F018_DMAGIC_ADDRMSB = 1
const byte OFFSET_STRUCT_F018_DMAGIC_EN018B = 3
void main()
void memoryRemap(byte memoryRemap::remapBlocks , word memoryRemap::lowerPageOffset , word memoryRemap::upperPageOffset)
const byte* memoryRemap::aVal = (byte*) 252
word memoryRemap::lowerPageOffset
byte memoryRemap::remapBlocks
word memoryRemap::upperPageOffset
const byte* memoryRemap::xVal = (byte*) 253
const byte* memoryRemap::yVal = (byte*) 254
const byte* memoryRemap::zVal = (byte*) 255
void memset_dma(void* memset_dma::dest , byte memset_dma::fill , word memset_dma::num)
void* memset_dma::dest
const void* memset_dma::dest#0 dest = (void*)DEFAULT_SCREEN
byte memset_dma::dmaMode
byte memset_dma::dmaMode#0 reg byte x 2.4444444444444446
byte memset_dma::fill
const byte memset_dma::fill#0 fill = '*'
word memset_dma::num
const word memset_dma::num#0 num = (word)$50*$a
struct DMA_LIST_F018B memset_dma_command loadstore mem[12] = { command: DMA_COMMAND_FILL, count: 0, src: (byte*) 0, src_bank: 0, dest: (byte*) 0, dest_bank: 0, sub_command: 0, modulo: 0 }
reg byte x [ memset_dma::dmaMode#0 ]
mem[12] [ memset_dma_command ]

View File

@ -0,0 +1,164 @@
// MEGA65 DMA test using memset
// Appendix J in https://mega.scryptos.com/sharefolder-link/MEGA/MEGA65+filehost/Docs/MEGA65-Book_draft.pdf
// Functions for using the F018 DMA for very fast copying or filling of memory
// MEGA65 Registers and Constants
// The MOS 6526 Complex Interface Adapter (CIA)
// http://archive.6502.org/datasheets/mos_6526_cia_recreated.pdf
.cpu _45gs02
// MEGA65 platform PRG executable starting in MEGA65 mode.
.file [name="dma-test6.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$2001]
.segmentdef Code [start=$2017]
.segmentdef Data [startAfter="Code"]
.segment Basic
.byte $0a, $20, $0a, $00, $fe, $02, $20, $30, $00 // 10 BANK 0
.byte $15, $20, $14, $00, $9e, $20 // 20 SYS
.text toIntString(main) // NNNN
.byte $00, $00, $00 //
// DMA command fill
.const DMA_COMMAND_FILL = 3
// $00 = End of options
.const DMA_OPTION_END = 0
// $0B = Use F018B list format
.const DMA_OPTION_FORMAT_F018B = $a
// $81 $xx = Set MB of destination address
.const DMA_OPTION_DEST_MB = $81
.const OFFSET_STRUCT_F018_DMAGIC_EN018B = 3
.const OFFSET_STRUCT_DMA_LIST_F018B_COUNT = 1
.const OFFSET_STRUCT_DMA_LIST_F018B_SRC = 3
.const OFFSET_STRUCT_DMA_LIST_F018B_DEST = 6
.const OFFSET_STRUCT_F018_DMAGIC_ADDRMB = 4
.const OFFSET_STRUCT_F018_DMAGIC_ADDRBANK = 2
.const OFFSET_STRUCT_F018_DMAGIC_ADDRMSB = 1
.const OFFSET_STRUCT_DMA_LIST_F018B_DEST_BANK = 8
.const OFFSET_STRUCT_F018_DMAGIC_ETRIG = 5
// DMAgic F018 Controller
.label DMA = $d700
// Default address of screen character matrix
.label DEFAULT_SCREEN = $800
.segment Code
main: {
// memoryRemap(0,0,0)
// Map memory to BANK 0 : 0x00XXXX - giving access to I/O
jsr memoryRemap
// memset_dma256(0, 0, DEFAULT_SCREEN, '*', 80*10)
// Fill screen up using 256MB DMA
jsr memset_dma256
// }
rts
}
// Remap some of the eight 8K memory blocks in the 64K address space of the 6502 to point somewhere else in the first 1MB memory space of the MEGA65.
// After the remapping the CPU will access the mapped memory whenever it uses instructions that access a remapped block.
// See section 2.3.4 in http://www.zimmers.net/cbmpics/cbm/c65/c65manual.txt for a description of the CPU memory remapper of the C65.
// remapBlocks: Indicates which 8K blocks of the 6502 address space to remap. Each bit represents one 8K block
// - bit 0 Memory block $0000-$1fff. Use constant MEMORYBLOCK_0000.
// - bit 1 Memory block $2000-$3fff. Use constant MEMORYBLOCK_2000.
// - bit 2 Memory block $4000-$5fff. Use constant MEMORYBLOCK_4000.
// - bit 3 Memory block $6000-$7fff. Use constant MEMORYBLOCK_6000.
// - bit 4 Memory block $8000-$9fff. Use constant MEMORYBLOCK_8000.
// - bit 5 Memory block $a000-$bfff. Use constant MEMORYBLOCK_A000.
// - bit 6 Memory block $c000-$dfff. Use constant MEMORYBLOCK_C000.
// - bit 7 Memory block $e000-$ffff. Use constant MEMORYBLOCK_E000.
// lowerPageOffset: Offset that will be added to any remapped blocks in the lower 32K of memory (block 0-3).
// The offset is a page offset (meaning it is multiplied by 0x100). Only the lower 12bits of the passed value is used.
// - If block 0 ($0000-$1fff) is remapped it will point to lowerPageOffset*$100.
// - If block 1 ($2000-$3fff) is remapped it will point to lowerPageOffset*$100 + $2000.
// - If block 2 ($4000-$5fff) is remapped it will point to lowerPageOffset*$100 + $4000.
// - If block 3 ($6000-$7fff) is remapped it will point to lowerPageOffset*$100 + $6000.
// upperPageOffset: Offset that will be added to any remapped blocks in the upper 32K of memory (block 4-7).
// The offset is a page offset (meaning it is multiplied by 0x100). Only the lower 12bits of the passed value is used.
// - If block 4 ($8000-$9fff) is remapped it will point to upperPageOffset*$100 + $8000
// - If block 5 ($a000-$bfff) is remapped it will point to upperPageOffset*$100 + $a000.
// - If block 6 ($c000-$dfff) is remapped it will point to upperPageOffset*$100 + $c000.
// - If block 7 ($e000-$ffff) is remapped it will point to upperPageOffset*$100 + $e000.
memoryRemap: {
.label aVal = $fc
.label xVal = $fd
.label yVal = $fe
.label zVal = $ff
// *aVal = <lowerPageOffset
lda #0
sta aVal
// *xVal = (remapBlocks << 4) | (>lowerPageOffset & 0xf)
sta xVal
// *yVal = <upperPageOffset
sta yVal
// *zVal = (remapBlocks & 0xf0) | (>upperPageOffset & 0xf)
sta zVal
// asm
lda aVal
ldx xVal
ldy yVal
ldz zVal
map
eom
// }
rts
}
// Set a memory block anywhere in the entire 256MB memory space using MEGA65 DMagic DMA
// Sets the values of num bytes to the memory block pointed to by destination.
// - dest_mb The MB value for the destination (0-255)
// - dest_bank The 64KB bank for the destination (0-15)
// - dest The destination address (within the MB and bank)
// - num The number of bytes to copy
memset_dma256: {
.const dest_mb = 0
.const dest_bank = 0
.const fill = '*'
.const num = $50*$a
.label dest = DEFAULT_SCREEN
.label f018b = memset_dma_command256+4
// dmaMode = DMA->EN018B
// Remember current F018 A/B mode
ldx DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B
// memset_dma_command256[1] = dest_mb
// Set up command
lda #dest_mb
sta memset_dma_command256+1
// f018b->count = num
lda #<num
sta f018b+OFFSET_STRUCT_DMA_LIST_F018B_COUNT
lda #>num
sta f018b+OFFSET_STRUCT_DMA_LIST_F018B_COUNT+1
// f018b->dest_bank = dest_bank
lda #dest_bank
sta f018b+OFFSET_STRUCT_DMA_LIST_F018B_DEST_BANK
// f018b->dest = dest
lda #<dest
sta f018b+OFFSET_STRUCT_DMA_LIST_F018B_DEST
lda #>dest
sta f018b+OFFSET_STRUCT_DMA_LIST_F018B_DEST+1
// f018b->src = (char*)fill
// Set fill byte
lda #<fill
sta f018b+OFFSET_STRUCT_DMA_LIST_F018B_SRC
lda #>fill
sta f018b+OFFSET_STRUCT_DMA_LIST_F018B_SRC+1
// DMA->EN018B = 1
// Set F018B mode
lda #1
sta DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B
// DMA->ADDRMB = 0
// Set address of DMA list
lda #0
sta DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMB
// DMA->ADDRBANK = 0
sta DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRBANK
// DMA-> ADDRMSB = >memset_dma_command256
lda #>memset_dma_command256
sta DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMSB
// DMA-> ETRIG = <memset_dma_command256
// Trigger the DMA (with option lists)
lda #<memset_dma_command256
sta DMA+OFFSET_STRUCT_F018_DMAGIC_ETRIG
// DMA->EN018B = dmaMode
// Re-enable F018A mode
stx DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B
// }
rts
}
.segment Data
// DMA list entry with options for setting data in the 256MB memory space
// Contains DMA options options for setting MB followed by DMA_LIST_F018B struct.
memset_dma_command256: .byte DMA_OPTION_DEST_MB, 0, DMA_OPTION_FORMAT_F018B, DMA_OPTION_END, DMA_COMMAND_FILL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0

View File

@ -0,0 +1,44 @@
void main()
main: scope:[main] from
[0] phi()
[1] call memoryRemap
to:main::@1
main::@1: scope:[main] from main
[2] phi()
[3] call memset_dma256
to:main::@return
main::@return: scope:[main] from main::@1
[4] return
to:@return
void memoryRemap(byte memoryRemap::remapBlocks , word memoryRemap::lowerPageOffset , word memoryRemap::upperPageOffset)
memoryRemap: scope:[memoryRemap] from main
[5] *memoryRemap::aVal = 0
[6] *memoryRemap::xVal = 0
[7] *memoryRemap::yVal = 0
[8] *memoryRemap::zVal = 0
asm { ldaaVal ldxxVal ldyyVal ldzzVal map eom }
to:memoryRemap::@return
memoryRemap::@return: scope:[memoryRemap] from memoryRemap
[10] return
to:@return
void memset_dma256(byte memset_dma256::dest_mb , byte memset_dma256::dest_bank , void* memset_dma256::dest , byte memset_dma256::fill , word memset_dma256::num)
memset_dma256: scope:[memset_dma256] from main::@1
[11] memset_dma256::dmaMode#0 = *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B)
[12] *(memset_dma_command256+1) = memset_dma256::dest_mb#0
[13] *((word*)memset_dma256::f018b#0+OFFSET_STRUCT_DMA_LIST_F018B_COUNT) = memset_dma256::num#0
[14] *((byte*)memset_dma256::f018b#0+OFFSET_STRUCT_DMA_LIST_F018B_DEST_BANK) = memset_dma256::dest_bank#0
[15] *((byte**)memset_dma256::f018b#0+OFFSET_STRUCT_DMA_LIST_F018B_DEST) = (byte*)memset_dma256::dest#0
[16] *((byte**)memset_dma256::f018b#0+OFFSET_STRUCT_DMA_LIST_F018B_SRC) = (byte*)memset_dma256::fill#0
[17] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B) = 1
[18] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMB) = 0
[19] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRBANK) = 0
[20] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMSB) = >memset_dma_command256
[21] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ETRIG) = <memset_dma_command256
[22] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B) = memset_dma256::dmaMode#0
to:memset_dma256::@return
memset_dma256::@return: scope:[memset_dma256] from memset_dma256
[23] return
to:@return

View File

@ -0,0 +1,996 @@
Resolved forward reference memcpy_dma_command to memcpy_dma_command
Resolved forward reference memcpy_dma_command to memcpy_dma_command
Resolved forward reference memcpy_dma_command to memcpy_dma_command
Resolved forward reference memcpy_dma_command to memcpy_dma_command
Resolved forward reference memcpy_dma_command to memcpy_dma_command
Resolved forward reference memcpy_dma_command4 to memcpy_dma_command4
Resolved forward reference memcpy_dma_command4 to memcpy_dma_command4
Resolved forward reference memcpy_dma_command4 to memcpy_dma_command4
Resolved forward reference memcpy_dma_command4 to memcpy_dma_command4
Resolved forward reference memcpy_dma_command4 to memcpy_dma_command4
Resolved forward reference memcpy_dma_command4 to memcpy_dma_command4
Resolved forward reference memcpy_dma_command4 to memcpy_dma_command4
Resolved forward reference memcpy_dma_command256 to memcpy_dma_command256
Resolved forward reference memcpy_dma_command256 to memcpy_dma_command256
Resolved forward reference memcpy_dma_command256 to memcpy_dma_command256
Resolved forward reference memcpy_dma_command256 to memcpy_dma_command256
Resolved forward reference memcpy_dma_command256 to memcpy_dma_command256
Resolved forward reference memset_dma_command to memset_dma_command
Resolved forward reference memset_dma_command to memset_dma_command
Resolved forward reference memset_dma_command to memset_dma_command
Resolved forward reference memset_dma_command to memset_dma_command
Resolved forward reference memset_dma_command to memset_dma_command
Resolved forward reference memset_dma_command256 to memset_dma_command256
Resolved forward reference memset_dma_command256 to memset_dma_command256
Resolved forward reference memset_dma_command256 to memset_dma_command256
Resolved forward reference memset_dma_command256 to memset_dma_command256
Fixing struct type size struct F018_DMAGIC to 17
Fixing struct type SIZE_OF struct F018_DMAGIC to 17
Fixing struct type SIZE_OF struct F018_DMAGIC to 17
Setting struct to load/store in variable affected by address-of *DMA.ADDRMSB = >&memcpy_dma_command
Setting struct to load/store in variable affected by address-of *DMA.ADDRLSBTRIG = <&memcpy_dma_command
Setting struct to load/store in variable affected by address-of *DMA.ADDRMSB = >&memcpy_dma_command4
Setting struct to load/store in variable affected by address-of *DMA.ADDRLSBTRIG = <&memcpy_dma_command4
Setting struct to load/store in variable affected by address-of *DMA.ADDRMSB = >&memset_dma_command
Setting struct to load/store in variable affected by address-of *DMA.ADDRLSBTRIG = <&memset_dma_command
Inlined call vicSelectGfxBank::$0 = call toDd00 vicSelectGfxBank::gfx
Eliminating unused variable with no statement memcpy_dma_command
Eliminating unused variable with no statement memcpy_dma_command4
Eliminating unused variable with no statement memset_dma_command
CONTROL FLOW GRAPH SSA
void memoryRemap(byte memoryRemap::remapBlocks , word memoryRemap::lowerPageOffset , word memoryRemap::upperPageOffset)
memoryRemap: scope:[memoryRemap] from main
memoryRemap::upperPageOffset#1 = phi( main/memoryRemap::upperPageOffset#0 )
memoryRemap::remapBlocks#1 = phi( main/memoryRemap::remapBlocks#0 )
memoryRemap::lowerPageOffset#1 = phi( main/memoryRemap::lowerPageOffset#0 )
memoryRemap::$0 = < memoryRemap::lowerPageOffset#1
*memoryRemap::aVal = memoryRemap::$0
memoryRemap::$1 = memoryRemap::remapBlocks#1 << 4
memoryRemap::$2 = > memoryRemap::lowerPageOffset#1
memoryRemap::$3 = memoryRemap::$2 & $f
memoryRemap::$4 = memoryRemap::$1 | memoryRemap::$3
*memoryRemap::xVal = memoryRemap::$4
memoryRemap::$5 = < memoryRemap::upperPageOffset#1
*memoryRemap::yVal = memoryRemap::$5
memoryRemap::$6 = memoryRemap::remapBlocks#1 & $f0
memoryRemap::$7 = > memoryRemap::upperPageOffset#1
memoryRemap::$8 = memoryRemap::$7 & $f
memoryRemap::$9 = memoryRemap::$6 | memoryRemap::$8
*memoryRemap::zVal = memoryRemap::$9
asm { ldaaVal ldxxVal ldyyVal ldzzVal map eom }
to:memoryRemap::@return
memoryRemap::@return: scope:[memoryRemap] from memoryRemap
return
to:@return
void memset_dma256(byte memset_dma256::dest_mb , byte memset_dma256::dest_bank , void* memset_dma256::dest , byte memset_dma256::fill , word memset_dma256::num)
memset_dma256: scope:[memset_dma256] from main::@1
memset_dma256::fill#1 = phi( main::@1/memset_dma256::fill#0 )
memset_dma256::dest#1 = phi( main::@1/memset_dma256::dest#0 )
memset_dma256::dest_bank#1 = phi( main::@1/memset_dma256::dest_bank#0 )
memset_dma256::num#1 = phi( main::@1/memset_dma256::num#0 )
memset_dma256::dest_mb#1 = phi( main::@1/memset_dma256::dest_mb#0 )
memset_dma256::dmaMode#0 = *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B)
memset_dma_command256[1] = memset_dma256::dest_mb#1
memset_dma256::$0 = & memset_dma_command256[4]
memset_dma256::f018b#0 = (struct DMA_LIST_F018B*)memset_dma256::$0
memset_dma256::$7 = (word*)memset_dma256::f018b#0
memset_dma256::$3 = memset_dma256::$7 + OFFSET_STRUCT_DMA_LIST_F018B_COUNT
*memset_dma256::$3 = memset_dma256::num#1
memset_dma256::$8 = (byte*)memset_dma256::f018b#0
memset_dma256::$4 = memset_dma256::$8 + OFFSET_STRUCT_DMA_LIST_F018B_DEST_BANK
*memset_dma256::$4 = memset_dma256::dest_bank#1
memset_dma256::$9 = (byte**)memset_dma256::f018b#0
memset_dma256::$5 = memset_dma256::$9 + OFFSET_STRUCT_DMA_LIST_F018B_DEST
*memset_dma256::$5 = ((byte*)) memset_dma256::dest#1
memset_dma256::$10 = (byte**)memset_dma256::f018b#0
memset_dma256::$6 = memset_dma256::$10 + OFFSET_STRUCT_DMA_LIST_F018B_SRC
*memset_dma256::$6 = (byte*)memset_dma256::fill#1
*((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B) = 1
*((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMB) = 0
*((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRBANK) = 0
memset_dma256::$1 = > memset_dma_command256
*((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMSB) = memset_dma256::$1
memset_dma256::$2 = < memset_dma_command256
*((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ETRIG) = memset_dma256::$2
*((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B) = memset_dma256::dmaMode#0
to:memset_dma256::@return
memset_dma256::@return: scope:[memset_dma256] from memset_dma256
return
to:@return
void main()
main: scope:[main] from __start
memoryRemap::remapBlocks#0 = 0
memoryRemap::lowerPageOffset#0 = 0
memoryRemap::upperPageOffset#0 = 0
call memoryRemap
to:main::@1
main::@1: scope:[main] from main
memset_dma256::dest_mb#0 = 0
memset_dma256::dest_bank#0 = 0
memset_dma256::dest#0 = (void*)DEFAULT_SCREEN
memset_dma256::fill#0 = '*'
memset_dma256::num#0 = $50*$a
call memset_dma256
to:main::@2
main::@2: scope:[main] from main::@1
to:main::@return
main::@return: scope:[main] from main::@2
return
to:@return
void __start()
__start: scope:[__start] from
call main
to:__start::@1
__start::@1: scope:[__start] from __start
to:__start::@return
__start::@return: scope:[__start] from __start::@1
return
to:@return
SYMBOL TABLE SSA
const nomodify byte* DEFAULT_SCREEN = (byte*)$800
const nomodify struct F018_DMAGIC* DMA = (struct F018_DMAGIC*)$d700
const nomodify byte DMA_COMMAND_FILL = 3
const nomodify byte DMA_OPTION_DEST_MB = $81
const nomodify byte DMA_OPTION_END = 0
const nomodify byte DMA_OPTION_FORMAT_F018B = $a
const byte OFFSET_STRUCT_DMA_LIST_F018B_COUNT = 1
const byte OFFSET_STRUCT_DMA_LIST_F018B_DEST = 6
const byte OFFSET_STRUCT_DMA_LIST_F018B_DEST_BANK = 8
const byte OFFSET_STRUCT_DMA_LIST_F018B_SRC = 3
const byte OFFSET_STRUCT_F018_DMAGIC_ADDRBANK = 2
const byte OFFSET_STRUCT_F018_DMAGIC_ADDRMB = 4
const byte OFFSET_STRUCT_F018_DMAGIC_ADDRMSB = 1
const byte OFFSET_STRUCT_F018_DMAGIC_EN018B = 3
const byte OFFSET_STRUCT_F018_DMAGIC_ETRIG = 5
void __start()
void main()
void memoryRemap(byte memoryRemap::remapBlocks , word memoryRemap::lowerPageOffset , word memoryRemap::upperPageOffset)
byte~ memoryRemap::$0
byte~ memoryRemap::$1
byte~ memoryRemap::$2
number~ memoryRemap::$3
number~ memoryRemap::$4
byte~ memoryRemap::$5
number~ memoryRemap::$6
byte~ memoryRemap::$7
number~ memoryRemap::$8
number~ memoryRemap::$9
const byte* memoryRemap::aVal = (byte*)$fc
word memoryRemap::lowerPageOffset
word memoryRemap::lowerPageOffset#0
word memoryRemap::lowerPageOffset#1
byte memoryRemap::remapBlocks
byte memoryRemap::remapBlocks#0
byte memoryRemap::remapBlocks#1
word memoryRemap::upperPageOffset
word memoryRemap::upperPageOffset#0
word memoryRemap::upperPageOffset#1
const byte* memoryRemap::xVal = (byte*)$fd
const byte* memoryRemap::yVal = (byte*)$fe
const byte* memoryRemap::zVal = (byte*)$ff
void memset_dma256(byte memset_dma256::dest_mb , byte memset_dma256::dest_bank , void* memset_dma256::dest , byte memset_dma256::fill , word memset_dma256::num)
byte*~ memset_dma256::$0
byte~ memset_dma256::$1
byte**~ memset_dma256::$10
byte~ memset_dma256::$2
word*~ memset_dma256::$3
byte*~ memset_dma256::$4
byte**~ memset_dma256::$5
byte**~ memset_dma256::$6
word*~ memset_dma256::$7
byte*~ memset_dma256::$8
byte**~ memset_dma256::$9
void* memset_dma256::dest
void* memset_dma256::dest#0
void* memset_dma256::dest#1
byte memset_dma256::dest_bank
byte memset_dma256::dest_bank#0
byte memset_dma256::dest_bank#1
byte memset_dma256::dest_mb
byte memset_dma256::dest_mb#0
byte memset_dma256::dest_mb#1
byte memset_dma256::dmaMode
byte memset_dma256::dmaMode#0
struct DMA_LIST_F018B* memset_dma256::f018b
struct DMA_LIST_F018B* memset_dma256::f018b#0
byte memset_dma256::fill
byte memset_dma256::fill#0
byte memset_dma256::fill#1
word memset_dma256::num
word memset_dma256::num#0
word memset_dma256::num#1
const byte* memset_dma_command256[] = { DMA_OPTION_DEST_MB, 0, DMA_OPTION_FORMAT_F018B, DMA_OPTION_END, DMA_COMMAND_FILL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
Adding number conversion cast (unumber) 4 in memoryRemap::$1 = memoryRemap::remapBlocks#1 << 4
Adding number conversion cast (unumber) $f in memoryRemap::$3 = memoryRemap::$2 & $f
Adding number conversion cast (unumber) memoryRemap::$3 in memoryRemap::$3 = memoryRemap::$2 & (unumber)$f
Adding number conversion cast (unumber) memoryRemap::$4 in memoryRemap::$4 = memoryRemap::$1 | memoryRemap::$3
Adding number conversion cast (unumber) $f0 in memoryRemap::$6 = memoryRemap::remapBlocks#1 & $f0
Adding number conversion cast (unumber) memoryRemap::$6 in memoryRemap::$6 = memoryRemap::remapBlocks#1 & (unumber)$f0
Adding number conversion cast (unumber) $f in memoryRemap::$8 = memoryRemap::$7 & $f
Adding number conversion cast (unumber) memoryRemap::$8 in memoryRemap::$8 = memoryRemap::$7 & (unumber)$f
Adding number conversion cast (unumber) memoryRemap::$9 in memoryRemap::$9 = memoryRemap::$6 | memoryRemap::$8
Adding number conversion cast (unumber) 1 in memset_dma_command256[1] = memset_dma256::dest_mb#1
Adding number conversion cast (unumber) 4 in memset_dma256::$0 = & memset_dma_command256[4]
Adding number conversion cast (unumber) 1 in *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B) = 1
Adding number conversion cast (unumber) 0 in *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMB) = 0
Adding number conversion cast (unumber) 0 in *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRBANK) = 0
Adding number conversion cast (unumber) 0 in memoryRemap::remapBlocks#0 = 0
Adding number conversion cast (unumber) 0 in memoryRemap::lowerPageOffset#0 = 0
Adding number conversion cast (unumber) 0 in memoryRemap::upperPageOffset#0 = 0
Adding number conversion cast (unumber) 0 in memset_dma256::dest_mb#0 = 0
Adding number conversion cast (unumber) 0 in memset_dma256::dest_bank#0 = 0
Adding number conversion cast (unumber) $50*$a in memset_dma256::num#0 = $50*$a
Successful SSA optimization PassNAddNumberTypeConversions
Inlining cast *memset_dma256::$5 = (byte*)memset_dma256::dest#1
Inlining cast *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B) = (unumber)1
Inlining cast *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMB) = (unumber)0
Inlining cast *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRBANK) = (unumber)0
Inlining cast memoryRemap::remapBlocks#0 = (unumber)0
Inlining cast memoryRemap::lowerPageOffset#0 = (unumber)0
Inlining cast memoryRemap::upperPageOffset#0 = (unumber)0
Inlining cast memset_dma256::dest_mb#0 = (unumber)0
Inlining cast memset_dma256::dest_bank#0 = (unumber)0
Inlining cast memset_dma256::num#0 = (unumber)$50*$a
Successful SSA optimization Pass2InlineCast
Simplifying constant pointer cast (byte*) 252
Simplifying constant pointer cast (byte*) 253
Simplifying constant pointer cast (byte*) 254
Simplifying constant pointer cast (byte*) 255
Simplifying constant pointer cast (struct F018_DMAGIC*) 55040
Simplifying constant pointer cast (byte*) 2048
Simplifying constant integer cast 4
Simplifying constant integer cast $f
Simplifying constant integer cast $f0
Simplifying constant integer cast $f
Simplifying constant integer cast 1
Simplifying constant integer cast 4
Simplifying constant integer cast 1
Simplifying constant integer cast 0
Simplifying constant integer cast 0
Simplifying constant integer cast 0
Simplifying constant integer cast 0
Simplifying constant integer cast 0
Simplifying constant integer cast 0
Simplifying constant integer cast 0
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type 4
Finalized unsigned number type $f
Finalized unsigned number type $f0
Finalized unsigned number type $f
Finalized unsigned number type 1
Finalized unsigned number type 4
Finalized unsigned number type 1
Finalized unsigned number type 0
Finalized unsigned number type 0
Finalized unsigned number type 0
Finalized unsigned number type 0
Finalized unsigned number type 0
Finalized unsigned number type 0
Finalized unsigned number type 0
Successful SSA optimization PassNFinalizeNumberTypeConversions
Inferred type updated to byte in memoryRemap::$3 = memoryRemap::$2 & $f
Inferred type updated to byte in memoryRemap::$4 = memoryRemap::$1 | memoryRemap::$3
Inferred type updated to byte in memoryRemap::$6 = memoryRemap::remapBlocks#1 & $f0
Inferred type updated to byte in memoryRemap::$8 = memoryRemap::$7 & $f
Inferred type updated to byte in memoryRemap::$9 = memoryRemap::$6 | memoryRemap::$8
Identical Phi Values memoryRemap::lowerPageOffset#1 memoryRemap::lowerPageOffset#0
Identical Phi Values memoryRemap::remapBlocks#1 memoryRemap::remapBlocks#0
Identical Phi Values memoryRemap::upperPageOffset#1 memoryRemap::upperPageOffset#0
Identical Phi Values memset_dma256::dest_mb#1 memset_dma256::dest_mb#0
Identical Phi Values memset_dma256::num#1 memset_dma256::num#0
Identical Phi Values memset_dma256::dest_bank#1 memset_dma256::dest_bank#0
Identical Phi Values memset_dma256::dest#1 memset_dma256::dest#0
Identical Phi Values memset_dma256::fill#1 memset_dma256::fill#0
Successful SSA optimization Pass2IdenticalPhiElimination
Rewriting array member address-of to pointer addition [20] memset_dma256::$0 = memset_dma_command256 + 4
Successful SSA optimization PassNArrayElementAddressOfRewriting
Constant right-side identified [20] memset_dma256::$0 = memset_dma_command256 + 4
Constant right-side identified [37] memset_dma256::$1 = > memset_dma_command256
Constant right-side identified [39] memset_dma256::$2 = < memset_dma_command256
Constant right-side identified [51] memset_dma256::num#0 = (unumber)$50*$a
Successful SSA optimization Pass2ConstantRValueConsolidation
Constant memset_dma256::$0 = memset_dma_command256+4
Constant memset_dma256::$1 = >memset_dma_command256
Constant memset_dma256::$2 = <memset_dma_command256
Constant memoryRemap::remapBlocks#0 = 0
Constant memoryRemap::lowerPageOffset#0 = 0
Constant memoryRemap::upperPageOffset#0 = 0
Constant memset_dma256::dest_mb#0 = 0
Constant memset_dma256::dest_bank#0 = 0
Constant memset_dma256::dest#0 = (void*)DEFAULT_SCREEN
Constant memset_dma256::fill#0 = '*'
Constant memset_dma256::num#0 = (unumber)$50*$a
Successful SSA optimization Pass2ConstantIdentification
Constant memset_dma256::f018b#0 = (struct DMA_LIST_F018B*)memset_dma256::$0
Successful SSA optimization Pass2ConstantIdentification
Constant memset_dma256::$7 = (word*)memset_dma256::f018b#0
Constant memset_dma256::$8 = (byte*)memset_dma256::f018b#0
Constant memset_dma256::$9 = (byte**)memset_dma256::f018b#0
Constant memset_dma256::$10 = (byte**)memset_dma256::f018b#0
Successful SSA optimization Pass2ConstantIdentification
Constant value identified (byte*)memset_dma256::dest#0 in [30] *memset_dma256::$5 = (byte*)memset_dma256::dest#0
Constant value identified (byte*)memset_dma256::fill#0 in [33] *memset_dma256::$6 = (byte*)memset_dma256::fill#0
Successful SSA optimization Pass2ConstantValues
Converting *(pointer+n) to pointer[n] [24] *memset_dma256::$3 = memset_dma256::num#0 -- memset_dma256::$7[OFFSET_STRUCT_DMA_LIST_F018B_COUNT]
Converting *(pointer+n) to pointer[n] [27] *memset_dma256::$4 = memset_dma256::dest_bank#0 -- memset_dma256::$8[OFFSET_STRUCT_DMA_LIST_F018B_DEST_BANK]
Converting *(pointer+n) to pointer[n] [30] *memset_dma256::$5 = (byte*)memset_dma256::dest#0 -- memset_dma256::$9[OFFSET_STRUCT_DMA_LIST_F018B_DEST]
Converting *(pointer+n) to pointer[n] [33] *memset_dma256::$6 = (byte*)memset_dma256::fill#0 -- memset_dma256::$10[OFFSET_STRUCT_DMA_LIST_F018B_SRC]
Successful SSA optimization Pass2InlineDerefIdx
Eliminating unused variable memset_dma256::$3 and assignment [18] memset_dma256::$3 = memset_dma256::$7 + OFFSET_STRUCT_DMA_LIST_F018B_COUNT
Eliminating unused variable memset_dma256::$4 and assignment [20] memset_dma256::$4 = memset_dma256::$8 + OFFSET_STRUCT_DMA_LIST_F018B_DEST_BANK
Eliminating unused variable memset_dma256::$5 and assignment [22] memset_dma256::$5 = memset_dma256::$9 + OFFSET_STRUCT_DMA_LIST_F018B_DEST
Eliminating unused variable memset_dma256::$6 and assignment [24] memset_dma256::$6 = memset_dma256::$10 + OFFSET_STRUCT_DMA_LIST_F018B_SRC
Successful SSA optimization PassNEliminateUnusedVars
Removing unused procedure __start
Removing unused procedure block __start
Removing unused procedure block __start::@1
Removing unused procedure block __start::@return
Successful SSA optimization PassNEliminateEmptyStart
Constant right-side identified [0] memoryRemap::$0 = < memoryRemap::lowerPageOffset#0
Constant right-side identified [2] memoryRemap::$1 = memoryRemap::remapBlocks#0 << 4
Constant right-side identified [3] memoryRemap::$2 = > memoryRemap::lowerPageOffset#0
Constant right-side identified [7] memoryRemap::$5 = < memoryRemap::upperPageOffset#0
Constant right-side identified [9] memoryRemap::$6 = memoryRemap::remapBlocks#0 & $f0
Constant right-side identified [10] memoryRemap::$7 = > memoryRemap::upperPageOffset#0
Successful SSA optimization Pass2ConstantRValueConsolidation
Constant memoryRemap::$0 = <memoryRemap::lowerPageOffset#0
Constant memoryRemap::$1 = memoryRemap::remapBlocks#0<<4
Constant memoryRemap::$2 = >memoryRemap::lowerPageOffset#0
Constant memoryRemap::$5 = <memoryRemap::upperPageOffset#0
Constant memoryRemap::$6 = memoryRemap::remapBlocks#0&$f0
Constant memoryRemap::$7 = >memoryRemap::upperPageOffset#0
Successful SSA optimization Pass2ConstantIdentification
Simplifying constant evaluating to zero <memoryRemap::lowerPageOffset#0 in
Simplifying constant evaluating to zero memoryRemap::remapBlocks#0<<4 in
Simplifying constant evaluating to zero >memoryRemap::lowerPageOffset#0 in
Simplifying constant evaluating to zero <memoryRemap::upperPageOffset#0 in
Simplifying constant evaluating to zero memoryRemap::remapBlocks#0&$f0 in
Simplifying constant evaluating to zero >memoryRemap::upperPageOffset#0 in
Successful SSA optimization PassNSimplifyConstantZero
Simplifying expression containing zero memoryRemap::$3 in [5] memoryRemap::$4 = memoryRemap::$1 | memoryRemap::$3
Simplifying expression containing zero memoryRemap::$8 in [12] memoryRemap::$9 = memoryRemap::$6 | memoryRemap::$8
Successful SSA optimization PassNSimplifyExpressionWithZero
Eliminating unused constant memoryRemap::remapBlocks#0
Eliminating unused constant memoryRemap::lowerPageOffset#0
Eliminating unused constant memoryRemap::upperPageOffset#0
Eliminating unused constant memoryRemap::$1
Eliminating unused constant memoryRemap::$6
Successful SSA optimization PassNEliminateUnusedVars
Alias memoryRemap::$4 = memoryRemap::$3
Alias memoryRemap::$9 = memoryRemap::$8
Successful SSA optimization Pass2AliasElimination
Constant right-side identified [1] memoryRemap::$4 = memoryRemap::$2 & $f
Constant right-side identified [4] memoryRemap::$9 = memoryRemap::$7 & $f
Successful SSA optimization Pass2ConstantRValueConsolidation
Constant memoryRemap::$4 = memoryRemap::$2&$f
Constant memoryRemap::$9 = memoryRemap::$7&$f
Successful SSA optimization Pass2ConstantIdentification
Simplifying constant evaluating to zero memoryRemap::$2&$f in
Simplifying constant evaluating to zero memoryRemap::$7&$f in
Successful SSA optimization PassNSimplifyConstantZero
Eliminating unused constant memoryRemap::$2
Eliminating unused constant memoryRemap::$7
Successful SSA optimization PassNEliminateUnusedVars
Constant inlined memoryRemap::$0 = 0
Constant inlined memset_dma256::$1 = >memset_dma_command256
Constant inlined memset_dma256::$2 = <memset_dma_command256
Constant inlined memset_dma256::$0 = memset_dma_command256+4
Constant inlined memoryRemap::$4 = 0
Constant inlined memoryRemap::$5 = 0
Constant inlined memset_dma256::$9 = (byte**)memset_dma256::f018b#0
Constant inlined memoryRemap::$9 = 0
Constant inlined memset_dma256::$7 = (word*)memset_dma256::f018b#0
Constant inlined memset_dma256::$8 = (byte*)memset_dma256::f018b#0
Constant inlined memset_dma256::$10 = (byte**)memset_dma256::f018b#0
Successful SSA optimization Pass2ConstantInlining
Consolidated array index constant in *(memset_dma_command256+1)
Consolidated array index constant in *((word*)memset_dma256::f018b#0+OFFSET_STRUCT_DMA_LIST_F018B_COUNT)
Consolidated array index constant in *((byte*)memset_dma256::f018b#0+OFFSET_STRUCT_DMA_LIST_F018B_DEST_BANK)
Consolidated array index constant in *((byte**)memset_dma256::f018b#0+OFFSET_STRUCT_DMA_LIST_F018B_DEST)
Consolidated array index constant in *((byte**)memset_dma256::f018b#0+OFFSET_STRUCT_DMA_LIST_F018B_SRC)
Successful SSA optimization Pass2ConstantAdditionElimination
Adding NOP phi() at start of main
Adding NOP phi() at start of main::@1
Adding NOP phi() at start of main::@2
CALL GRAPH
Calls in [main] to memoryRemap:1 memset_dma256:3
Created 0 initial phi equivalence classes
Coalesced down to 0 phi equivalence classes
Culled Empty Block label main::@2
Adding NOP phi() at start of main
Adding NOP phi() at start of main::@1
FINAL CONTROL FLOW GRAPH
void main()
main: scope:[main] from
[0] phi()
[1] call memoryRemap
to:main::@1
main::@1: scope:[main] from main
[2] phi()
[3] call memset_dma256
to:main::@return
main::@return: scope:[main] from main::@1
[4] return
to:@return
void memoryRemap(byte memoryRemap::remapBlocks , word memoryRemap::lowerPageOffset , word memoryRemap::upperPageOffset)
memoryRemap: scope:[memoryRemap] from main
[5] *memoryRemap::aVal = 0
[6] *memoryRemap::xVal = 0
[7] *memoryRemap::yVal = 0
[8] *memoryRemap::zVal = 0
asm { ldaaVal ldxxVal ldyyVal ldzzVal map eom }
to:memoryRemap::@return
memoryRemap::@return: scope:[memoryRemap] from memoryRemap
[10] return
to:@return
void memset_dma256(byte memset_dma256::dest_mb , byte memset_dma256::dest_bank , void* memset_dma256::dest , byte memset_dma256::fill , word memset_dma256::num)
memset_dma256: scope:[memset_dma256] from main::@1
[11] memset_dma256::dmaMode#0 = *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B)
[12] *(memset_dma_command256+1) = memset_dma256::dest_mb#0
[13] *((word*)memset_dma256::f018b#0+OFFSET_STRUCT_DMA_LIST_F018B_COUNT) = memset_dma256::num#0
[14] *((byte*)memset_dma256::f018b#0+OFFSET_STRUCT_DMA_LIST_F018B_DEST_BANK) = memset_dma256::dest_bank#0
[15] *((byte**)memset_dma256::f018b#0+OFFSET_STRUCT_DMA_LIST_F018B_DEST) = (byte*)memset_dma256::dest#0
[16] *((byte**)memset_dma256::f018b#0+OFFSET_STRUCT_DMA_LIST_F018B_SRC) = (byte*)memset_dma256::fill#0
[17] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B) = 1
[18] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMB) = 0
[19] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRBANK) = 0
[20] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMSB) = >memset_dma_command256
[21] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ETRIG) = <memset_dma_command256
[22] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B) = memset_dma256::dmaMode#0
to:memset_dma256::@return
memset_dma256::@return: scope:[memset_dma256] from memset_dma256
[23] return
to:@return
VARIABLE REGISTER WEIGHTS
void main()
void memoryRemap(byte memoryRemap::remapBlocks , word memoryRemap::lowerPageOffset , word memoryRemap::upperPageOffset)
word memoryRemap::lowerPageOffset
byte memoryRemap::remapBlocks
word memoryRemap::upperPageOffset
void memset_dma256(byte memset_dma256::dest_mb , byte memset_dma256::dest_bank , void* memset_dma256::dest , byte memset_dma256::fill , word memset_dma256::num)
void* memset_dma256::dest
byte memset_dma256::dest_bank
byte memset_dma256::dest_mb
byte memset_dma256::dmaMode
byte memset_dma256::dmaMode#0 2.0
struct DMA_LIST_F018B* memset_dma256::f018b
byte memset_dma256::fill
word memset_dma256::num
Initial phi equivalence classes
Added variable memset_dma256::dmaMode#0 to live range equivalence class [ memset_dma256::dmaMode#0 ]
Complete equivalence classes
[ memset_dma256::dmaMode#0 ]
Allocated zp[1]:2 [ memset_dma256::dmaMode#0 ]
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [5] *memoryRemap::aVal = 0 [ ] ( memoryRemap:1 [ ] { } ) always clobbers reg byte a
Statement [6] *memoryRemap::xVal = 0 [ ] ( memoryRemap:1 [ ] { } ) always clobbers reg byte a
Statement [7] *memoryRemap::yVal = 0 [ ] ( memoryRemap:1 [ ] { } ) always clobbers reg byte a
Statement [8] *memoryRemap::zVal = 0 [ ] ( memoryRemap:1 [ ] { } ) always clobbers reg byte a
Statement asm { ldaaVal ldxxVal ldyyVal ldzzVal map eom } always clobbers reg byte a reg byte x reg byte y reg byte z
Statement [12] *(memset_dma_command256+1) = memset_dma256::dest_mb#0 [ memset_dma256::dmaMode#0 ] ( memset_dma256:3 [ memset_dma256::dmaMode#0 ] { } ) always clobbers reg byte a
Removing always clobbered register reg byte a as potential for zp[1]:2 [ memset_dma256::dmaMode#0 ]
Statement [13] *((word*)memset_dma256::f018b#0+OFFSET_STRUCT_DMA_LIST_F018B_COUNT) = memset_dma256::num#0 [ memset_dma256::dmaMode#0 ] ( memset_dma256:3 [ memset_dma256::dmaMode#0 ] { } ) always clobbers reg byte a
Statement [14] *((byte*)memset_dma256::f018b#0+OFFSET_STRUCT_DMA_LIST_F018B_DEST_BANK) = memset_dma256::dest_bank#0 [ memset_dma256::dmaMode#0 ] ( memset_dma256:3 [ memset_dma256::dmaMode#0 ] { } ) always clobbers reg byte a
Statement [15] *((byte**)memset_dma256::f018b#0+OFFSET_STRUCT_DMA_LIST_F018B_DEST) = (byte*)memset_dma256::dest#0 [ memset_dma256::dmaMode#0 ] ( memset_dma256:3 [ memset_dma256::dmaMode#0 ] { } ) always clobbers reg byte a
Statement [16] *((byte**)memset_dma256::f018b#0+OFFSET_STRUCT_DMA_LIST_F018B_SRC) = (byte*)memset_dma256::fill#0 [ memset_dma256::dmaMode#0 ] ( memset_dma256:3 [ memset_dma256::dmaMode#0 ] { } ) always clobbers reg byte a
Statement [17] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B) = 1 [ memset_dma256::dmaMode#0 ] ( memset_dma256:3 [ memset_dma256::dmaMode#0 ] { } ) always clobbers reg byte a
Statement [18] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMB) = 0 [ memset_dma256::dmaMode#0 ] ( memset_dma256:3 [ memset_dma256::dmaMode#0 ] { } ) always clobbers reg byte a
Statement [19] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRBANK) = 0 [ memset_dma256::dmaMode#0 ] ( memset_dma256:3 [ memset_dma256::dmaMode#0 ] { } ) always clobbers reg byte a
Statement [20] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMSB) = >memset_dma_command256 [ memset_dma256::dmaMode#0 ] ( memset_dma256:3 [ memset_dma256::dmaMode#0 ] { } ) always clobbers reg byte a
Statement [21] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ETRIG) = <memset_dma_command256 [ memset_dma256::dmaMode#0 ] ( memset_dma256:3 [ memset_dma256::dmaMode#0 ] { } ) always clobbers reg byte a
Statement [5] *memoryRemap::aVal = 0 [ ] ( memoryRemap:1 [ ] { } ) always clobbers reg byte a
Statement [6] *memoryRemap::xVal = 0 [ ] ( memoryRemap:1 [ ] { } ) always clobbers reg byte a
Statement [7] *memoryRemap::yVal = 0 [ ] ( memoryRemap:1 [ ] { } ) always clobbers reg byte a
Statement [8] *memoryRemap::zVal = 0 [ ] ( memoryRemap:1 [ ] { } ) always clobbers reg byte a
Statement asm { ldaaVal ldxxVal ldyyVal ldzzVal map eom } always clobbers reg byte a reg byte x reg byte y reg byte z
Statement [12] *(memset_dma_command256+1) = memset_dma256::dest_mb#0 [ memset_dma256::dmaMode#0 ] ( memset_dma256:3 [ memset_dma256::dmaMode#0 ] { } ) always clobbers reg byte a
Statement [13] *((word*)memset_dma256::f018b#0+OFFSET_STRUCT_DMA_LIST_F018B_COUNT) = memset_dma256::num#0 [ memset_dma256::dmaMode#0 ] ( memset_dma256:3 [ memset_dma256::dmaMode#0 ] { } ) always clobbers reg byte a
Statement [14] *((byte*)memset_dma256::f018b#0+OFFSET_STRUCT_DMA_LIST_F018B_DEST_BANK) = memset_dma256::dest_bank#0 [ memset_dma256::dmaMode#0 ] ( memset_dma256:3 [ memset_dma256::dmaMode#0 ] { } ) always clobbers reg byte a
Statement [15] *((byte**)memset_dma256::f018b#0+OFFSET_STRUCT_DMA_LIST_F018B_DEST) = (byte*)memset_dma256::dest#0 [ memset_dma256::dmaMode#0 ] ( memset_dma256:3 [ memset_dma256::dmaMode#0 ] { } ) always clobbers reg byte a
Statement [16] *((byte**)memset_dma256::f018b#0+OFFSET_STRUCT_DMA_LIST_F018B_SRC) = (byte*)memset_dma256::fill#0 [ memset_dma256::dmaMode#0 ] ( memset_dma256:3 [ memset_dma256::dmaMode#0 ] { } ) always clobbers reg byte a
Statement [17] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B) = 1 [ memset_dma256::dmaMode#0 ] ( memset_dma256:3 [ memset_dma256::dmaMode#0 ] { } ) always clobbers reg byte a
Statement [18] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMB) = 0 [ memset_dma256::dmaMode#0 ] ( memset_dma256:3 [ memset_dma256::dmaMode#0 ] { } ) always clobbers reg byte a
Statement [19] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRBANK) = 0 [ memset_dma256::dmaMode#0 ] ( memset_dma256:3 [ memset_dma256::dmaMode#0 ] { } ) always clobbers reg byte a
Statement [20] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMSB) = >memset_dma_command256 [ memset_dma256::dmaMode#0 ] ( memset_dma256:3 [ memset_dma256::dmaMode#0 ] { } ) always clobbers reg byte a
Statement [21] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ETRIG) = <memset_dma_command256 [ memset_dma256::dmaMode#0 ] ( memset_dma256:3 [ memset_dma256::dmaMode#0 ] { } ) always clobbers reg byte a
Potential registers zp[1]:2 [ memset_dma256::dmaMode#0 ] : zp[1]:2 , reg byte x , reg byte y , reg byte z ,
REGISTER UPLIFT SCOPES
Uplift Scope [memset_dma256] 2: zp[1]:2 [ memset_dma256::dmaMode#0 ]
Uplift Scope [MOS6526_CIA]
Uplift Scope [MOS6569_VICII]
Uplift Scope [MOS6581_SID]
Uplift Scope [MOS4569_VICIII]
Uplift Scope [MEGA65_VICIV]
Uplift Scope [memoryRemap]
Uplift Scope [F018_DMAGIC]
Uplift Scope [DMA_LIST_F018A]
Uplift Scope [DMA_LIST_F018B]
Uplift Scope [main]
Uplift Scope []
Uplifting [memset_dma256] best 171 combination reg byte x [ memset_dma256::dmaMode#0 ]
Uplifting [MOS6526_CIA] best 171 combination
Uplifting [MOS6569_VICII] best 171 combination
Uplifting [MOS6581_SID] best 171 combination
Uplifting [MOS4569_VICIII] best 171 combination
Uplifting [MEGA65_VICIV] best 171 combination
Uplifting [memoryRemap] best 171 combination
Uplifting [F018_DMAGIC] best 171 combination
Uplifting [DMA_LIST_F018A] best 171 combination
Uplifting [DMA_LIST_F018B] best 171 combination
Uplifting [main] best 171 combination
Uplifting [] best 171 combination
ASSEMBLER BEFORE OPTIMIZATION
// File Comments
// MEGA65 DMA test using memset
// Appendix J in https://mega.scryptos.com/sharefolder-link/MEGA/MEGA65+filehost/Docs/MEGA65-Book_draft.pdf
// Functions for using the F018 DMA for very fast copying or filling of memory
// MEGA65 Registers and Constants
// The MOS 6526 Complex Interface Adapter (CIA)
// http://archive.6502.org/datasheets/mos_6526_cia_recreated.pdf
// Upstart
.cpu _45gs02
// MEGA65 platform PRG executable starting in MEGA65 mode.
.file [name="dma-test6.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$2001]
.segmentdef Code [start=$2017]
.segmentdef Data [startAfter="Code"]
.segment Basic
.byte $0a, $20, $0a, $00, $fe, $02, $20, $30, $00 // 10 BANK 0
.byte $15, $20, $14, $00, $9e, $20 // 20 SYS
.text toIntString(main) // NNNN
.byte $00, $00, $00 //
// Global Constants & labels
// DMA command fill
.const DMA_COMMAND_FILL = 3
// $00 = End of options
.const DMA_OPTION_END = 0
// $0B = Use F018B list format
.const DMA_OPTION_FORMAT_F018B = $a
// $81 $xx = Set MB of destination address
.const DMA_OPTION_DEST_MB = $81
.const OFFSET_STRUCT_F018_DMAGIC_EN018B = 3
.const OFFSET_STRUCT_DMA_LIST_F018B_COUNT = 1
.const OFFSET_STRUCT_DMA_LIST_F018B_SRC = 3
.const OFFSET_STRUCT_DMA_LIST_F018B_DEST = 6
.const OFFSET_STRUCT_F018_DMAGIC_ADDRMB = 4
.const OFFSET_STRUCT_F018_DMAGIC_ADDRBANK = 2
.const OFFSET_STRUCT_F018_DMAGIC_ADDRMSB = 1
.const OFFSET_STRUCT_DMA_LIST_F018B_DEST_BANK = 8
.const OFFSET_STRUCT_F018_DMAGIC_ETRIG = 5
// DMAgic F018 Controller
.label DMA = $d700
// Default address of screen character matrix
.label DEFAULT_SCREEN = $800
.segment Code
// main
main: {
// [1] call memoryRemap
// Map memory to BANK 0 : 0x00XXXX - giving access to I/O
jsr memoryRemap
// [2] phi from main to main::@1 [phi:main->main::@1]
__b1_from_main:
jmp __b1
// main::@1
__b1:
// [3] call memset_dma256
// Fill screen up using 256MB DMA
jsr memset_dma256
jmp __breturn
// main::@return
__breturn:
// [4] return
rts
}
// memoryRemap
// Remap some of the eight 8K memory blocks in the 64K address space of the 6502 to point somewhere else in the first 1MB memory space of the MEGA65.
// After the remapping the CPU will access the mapped memory whenever it uses instructions that access a remapped block.
// See section 2.3.4 in http://www.zimmers.net/cbmpics/cbm/c65/c65manual.txt for a description of the CPU memory remapper of the C65.
// remapBlocks: Indicates which 8K blocks of the 6502 address space to remap. Each bit represents one 8K block
// - bit 0 Memory block $0000-$1fff. Use constant MEMORYBLOCK_0000.
// - bit 1 Memory block $2000-$3fff. Use constant MEMORYBLOCK_2000.
// - bit 2 Memory block $4000-$5fff. Use constant MEMORYBLOCK_4000.
// - bit 3 Memory block $6000-$7fff. Use constant MEMORYBLOCK_6000.
// - bit 4 Memory block $8000-$9fff. Use constant MEMORYBLOCK_8000.
// - bit 5 Memory block $a000-$bfff. Use constant MEMORYBLOCK_A000.
// - bit 6 Memory block $c000-$dfff. Use constant MEMORYBLOCK_C000.
// - bit 7 Memory block $e000-$ffff. Use constant MEMORYBLOCK_E000.
// lowerPageOffset: Offset that will be added to any remapped blocks in the lower 32K of memory (block 0-3).
// The offset is a page offset (meaning it is multiplied by 0x100). Only the lower 12bits of the passed value is used.
// - If block 0 ($0000-$1fff) is remapped it will point to lowerPageOffset*$100.
// - If block 1 ($2000-$3fff) is remapped it will point to lowerPageOffset*$100 + $2000.
// - If block 2 ($4000-$5fff) is remapped it will point to lowerPageOffset*$100 + $4000.
// - If block 3 ($6000-$7fff) is remapped it will point to lowerPageOffset*$100 + $6000.
// upperPageOffset: Offset that will be added to any remapped blocks in the upper 32K of memory (block 4-7).
// The offset is a page offset (meaning it is multiplied by 0x100). Only the lower 12bits of the passed value is used.
// - If block 4 ($8000-$9fff) is remapped it will point to upperPageOffset*$100 + $8000
// - If block 5 ($a000-$bfff) is remapped it will point to upperPageOffset*$100 + $a000.
// - If block 6 ($c000-$dfff) is remapped it will point to upperPageOffset*$100 + $c000.
// - If block 7 ($e000-$ffff) is remapped it will point to upperPageOffset*$100 + $e000.
memoryRemap: {
.label aVal = $fc
.label xVal = $fd
.label yVal = $fe
.label zVal = $ff
// [5] *memoryRemap::aVal = 0 -- _deref_pbuc1=vbuc2
lda #0
sta aVal
// [6] *memoryRemap::xVal = 0 -- _deref_pbuc1=vbuc2
lda #0
sta xVal
// [7] *memoryRemap::yVal = 0 -- _deref_pbuc1=vbuc2
lda #0
sta yVal
// [8] *memoryRemap::zVal = 0 -- _deref_pbuc1=vbuc2
lda #0
sta zVal
// asm { ldaaVal ldxxVal ldyyVal ldzzVal map eom }
lda aVal
ldx xVal
ldy yVal
ldz zVal
map
eom
jmp __breturn
// memoryRemap::@return
__breturn:
// [10] return
rts
}
// memset_dma256
// Set a memory block anywhere in the entire 256MB memory space using MEGA65 DMagic DMA
// Sets the values of num bytes to the memory block pointed to by destination.
// - dest_mb The MB value for the destination (0-255)
// - dest_bank The 64KB bank for the destination (0-15)
// - dest The destination address (within the MB and bank)
// - num The number of bytes to copy
memset_dma256: {
.const dest_mb = 0
.const dest_bank = 0
.const fill = '*'
.const num = $50*$a
.label dest = DEFAULT_SCREEN
.label f018b = memset_dma_command256+4
// [11] memset_dma256::dmaMode#0 = *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B) -- vbuxx=_deref_pbuc1
// Remember current F018 A/B mode
ldx DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B
// [12] *(memset_dma_command256+1) = memset_dma256::dest_mb#0 -- _deref_pbuc1=vbuc2
// Set up command
lda #dest_mb
sta memset_dma_command256+1
// [13] *((word*)memset_dma256::f018b#0+OFFSET_STRUCT_DMA_LIST_F018B_COUNT) = memset_dma256::num#0 -- _deref_pwuc1=vwuc2
lda #<num
sta f018b+OFFSET_STRUCT_DMA_LIST_F018B_COUNT
lda #>num
sta f018b+OFFSET_STRUCT_DMA_LIST_F018B_COUNT+1
// [14] *((byte*)memset_dma256::f018b#0+OFFSET_STRUCT_DMA_LIST_F018B_DEST_BANK) = memset_dma256::dest_bank#0 -- _deref_pbuc1=vbuc2
lda #dest_bank
sta f018b+OFFSET_STRUCT_DMA_LIST_F018B_DEST_BANK
// [15] *((byte**)memset_dma256::f018b#0+OFFSET_STRUCT_DMA_LIST_F018B_DEST) = (byte*)memset_dma256::dest#0 -- _deref_qbuc1=pbuc2
lda #<dest
sta f018b+OFFSET_STRUCT_DMA_LIST_F018B_DEST
lda #>dest
sta f018b+OFFSET_STRUCT_DMA_LIST_F018B_DEST+1
// [16] *((byte**)memset_dma256::f018b#0+OFFSET_STRUCT_DMA_LIST_F018B_SRC) = (byte*)memset_dma256::fill#0 -- _deref_qbuc1=pbuc2
// Set fill byte
lda #<fill
sta f018b+OFFSET_STRUCT_DMA_LIST_F018B_SRC
lda #>fill
sta f018b+OFFSET_STRUCT_DMA_LIST_F018B_SRC+1
// [17] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B) = 1 -- _deref_pbuc1=vbuc2
// Set F018B mode
lda #1
sta DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B
// [18] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMB) = 0 -- _deref_pbuc1=vbuc2
// Set address of DMA list
lda #0
sta DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMB
// [19] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRBANK) = 0 -- _deref_pbuc1=vbuc2
lda #0
sta DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRBANK
// [20] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMSB) = >memset_dma_command256 -- _deref_pbuc1=vbuc2
lda #>memset_dma_command256
sta DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMSB
// [21] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ETRIG) = <memset_dma_command256 -- _deref_pbuc1=vbuc2
// Trigger the DMA (with option lists)
lda #<memset_dma_command256
sta DMA+OFFSET_STRUCT_F018_DMAGIC_ETRIG
// [22] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B) = memset_dma256::dmaMode#0 -- _deref_pbuc1=vbuxx
// Re-enable F018A mode
stx DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B
jmp __breturn
// memset_dma256::@return
__breturn:
// [23] return
rts
}
// File Data
.segment Data
// DMA list entry with options for setting data in the 256MB memory space
// Contains DMA options options for setting MB followed by DMA_LIST_F018B struct.
memset_dma_command256: .byte DMA_OPTION_DEST_MB, 0, DMA_OPTION_FORMAT_F018B, DMA_OPTION_END, DMA_COMMAND_FILL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1
Removing instruction jmp __breturn
Removing instruction jmp __breturn
Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction lda #0
Removing instruction lda #0
Removing instruction lda #0
Removing instruction lda #0
Succesful ASM optimization Pass5UnnecesaryLoadElimination
Removing instruction __b1_from_main:
Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction __b1:
Removing instruction __breturn:
Removing instruction __breturn:
Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE
const nomodify byte* DEFAULT_SCREEN = (byte*) 2048
const nomodify struct F018_DMAGIC* DMA = (struct F018_DMAGIC*) 55040
const nomodify byte DMA_COMMAND_FILL = 3
const nomodify byte DMA_OPTION_DEST_MB = $81
const nomodify byte DMA_OPTION_END = 0
const nomodify byte DMA_OPTION_FORMAT_F018B = $a
const byte OFFSET_STRUCT_DMA_LIST_F018B_COUNT = 1
const byte OFFSET_STRUCT_DMA_LIST_F018B_DEST = 6
const byte OFFSET_STRUCT_DMA_LIST_F018B_DEST_BANK = 8
const byte OFFSET_STRUCT_DMA_LIST_F018B_SRC = 3
const byte OFFSET_STRUCT_F018_DMAGIC_ADDRBANK = 2
const byte OFFSET_STRUCT_F018_DMAGIC_ADDRMB = 4
const byte OFFSET_STRUCT_F018_DMAGIC_ADDRMSB = 1
const byte OFFSET_STRUCT_F018_DMAGIC_EN018B = 3
const byte OFFSET_STRUCT_F018_DMAGIC_ETRIG = 5
void main()
void memoryRemap(byte memoryRemap::remapBlocks , word memoryRemap::lowerPageOffset , word memoryRemap::upperPageOffset)
const byte* memoryRemap::aVal = (byte*) 252
word memoryRemap::lowerPageOffset
byte memoryRemap::remapBlocks
word memoryRemap::upperPageOffset
const byte* memoryRemap::xVal = (byte*) 253
const byte* memoryRemap::yVal = (byte*) 254
const byte* memoryRemap::zVal = (byte*) 255
void memset_dma256(byte memset_dma256::dest_mb , byte memset_dma256::dest_bank , void* memset_dma256::dest , byte memset_dma256::fill , word memset_dma256::num)
void* memset_dma256::dest
const void* memset_dma256::dest#0 dest = (void*)DEFAULT_SCREEN
byte memset_dma256::dest_bank
const byte memset_dma256::dest_bank#0 dest_bank = 0
byte memset_dma256::dest_mb
const byte memset_dma256::dest_mb#0 dest_mb = 0
byte memset_dma256::dmaMode
byte memset_dma256::dmaMode#0 reg byte x 2.0
struct DMA_LIST_F018B* memset_dma256::f018b
const struct DMA_LIST_F018B* memset_dma256::f018b#0 f018b = (struct DMA_LIST_F018B*)memset_dma_command256+4
byte memset_dma256::fill
const byte memset_dma256::fill#0 fill = '*'
word memset_dma256::num
const word memset_dma256::num#0 num = (word)$50*$a
const byte* memset_dma_command256[] = { DMA_OPTION_DEST_MB, 0, DMA_OPTION_FORMAT_F018B, DMA_OPTION_END, DMA_COMMAND_FILL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
reg byte x [ memset_dma256::dmaMode#0 ]
FINAL ASSEMBLER
Score: 151
// File Comments
// MEGA65 DMA test using memset
// Appendix J in https://mega.scryptos.com/sharefolder-link/MEGA/MEGA65+filehost/Docs/MEGA65-Book_draft.pdf
// Functions for using the F018 DMA for very fast copying or filling of memory
// MEGA65 Registers and Constants
// The MOS 6526 Complex Interface Adapter (CIA)
// http://archive.6502.org/datasheets/mos_6526_cia_recreated.pdf
// Upstart
.cpu _45gs02
// MEGA65 platform PRG executable starting in MEGA65 mode.
.file [name="dma-test6.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$2001]
.segmentdef Code [start=$2017]
.segmentdef Data [startAfter="Code"]
.segment Basic
.byte $0a, $20, $0a, $00, $fe, $02, $20, $30, $00 // 10 BANK 0
.byte $15, $20, $14, $00, $9e, $20 // 20 SYS
.text toIntString(main) // NNNN
.byte $00, $00, $00 //
// Global Constants & labels
// DMA command fill
.const DMA_COMMAND_FILL = 3
// $00 = End of options
.const DMA_OPTION_END = 0
// $0B = Use F018B list format
.const DMA_OPTION_FORMAT_F018B = $a
// $81 $xx = Set MB of destination address
.const DMA_OPTION_DEST_MB = $81
.const OFFSET_STRUCT_F018_DMAGIC_EN018B = 3
.const OFFSET_STRUCT_DMA_LIST_F018B_COUNT = 1
.const OFFSET_STRUCT_DMA_LIST_F018B_SRC = 3
.const OFFSET_STRUCT_DMA_LIST_F018B_DEST = 6
.const OFFSET_STRUCT_F018_DMAGIC_ADDRMB = 4
.const OFFSET_STRUCT_F018_DMAGIC_ADDRBANK = 2
.const OFFSET_STRUCT_F018_DMAGIC_ADDRMSB = 1
.const OFFSET_STRUCT_DMA_LIST_F018B_DEST_BANK = 8
.const OFFSET_STRUCT_F018_DMAGIC_ETRIG = 5
// DMAgic F018 Controller
.label DMA = $d700
// Default address of screen character matrix
.label DEFAULT_SCREEN = $800
.segment Code
// main
main: {
// memoryRemap(0,0,0)
// [1] call memoryRemap
// Map memory to BANK 0 : 0x00XXXX - giving access to I/O
jsr memoryRemap
// [2] phi from main to main::@1 [phi:main->main::@1]
// main::@1
// memset_dma256(0, 0, DEFAULT_SCREEN, '*', 80*10)
// [3] call memset_dma256
// Fill screen up using 256MB DMA
jsr memset_dma256
// main::@return
// }
// [4] return
rts
}
// memoryRemap
// Remap some of the eight 8K memory blocks in the 64K address space of the 6502 to point somewhere else in the first 1MB memory space of the MEGA65.
// After the remapping the CPU will access the mapped memory whenever it uses instructions that access a remapped block.
// See section 2.3.4 in http://www.zimmers.net/cbmpics/cbm/c65/c65manual.txt for a description of the CPU memory remapper of the C65.
// remapBlocks: Indicates which 8K blocks of the 6502 address space to remap. Each bit represents one 8K block
// - bit 0 Memory block $0000-$1fff. Use constant MEMORYBLOCK_0000.
// - bit 1 Memory block $2000-$3fff. Use constant MEMORYBLOCK_2000.
// - bit 2 Memory block $4000-$5fff. Use constant MEMORYBLOCK_4000.
// - bit 3 Memory block $6000-$7fff. Use constant MEMORYBLOCK_6000.
// - bit 4 Memory block $8000-$9fff. Use constant MEMORYBLOCK_8000.
// - bit 5 Memory block $a000-$bfff. Use constant MEMORYBLOCK_A000.
// - bit 6 Memory block $c000-$dfff. Use constant MEMORYBLOCK_C000.
// - bit 7 Memory block $e000-$ffff. Use constant MEMORYBLOCK_E000.
// lowerPageOffset: Offset that will be added to any remapped blocks in the lower 32K of memory (block 0-3).
// The offset is a page offset (meaning it is multiplied by 0x100). Only the lower 12bits of the passed value is used.
// - If block 0 ($0000-$1fff) is remapped it will point to lowerPageOffset*$100.
// - If block 1 ($2000-$3fff) is remapped it will point to lowerPageOffset*$100 + $2000.
// - If block 2 ($4000-$5fff) is remapped it will point to lowerPageOffset*$100 + $4000.
// - If block 3 ($6000-$7fff) is remapped it will point to lowerPageOffset*$100 + $6000.
// upperPageOffset: Offset that will be added to any remapped blocks in the upper 32K of memory (block 4-7).
// The offset is a page offset (meaning it is multiplied by 0x100). Only the lower 12bits of the passed value is used.
// - If block 4 ($8000-$9fff) is remapped it will point to upperPageOffset*$100 + $8000
// - If block 5 ($a000-$bfff) is remapped it will point to upperPageOffset*$100 + $a000.
// - If block 6 ($c000-$dfff) is remapped it will point to upperPageOffset*$100 + $c000.
// - If block 7 ($e000-$ffff) is remapped it will point to upperPageOffset*$100 + $e000.
memoryRemap: {
.label aVal = $fc
.label xVal = $fd
.label yVal = $fe
.label zVal = $ff
// *aVal = <lowerPageOffset
// [5] *memoryRemap::aVal = 0 -- _deref_pbuc1=vbuc2
lda #0
sta aVal
// *xVal = (remapBlocks << 4) | (>lowerPageOffset & 0xf)
// [6] *memoryRemap::xVal = 0 -- _deref_pbuc1=vbuc2
sta xVal
// *yVal = <upperPageOffset
// [7] *memoryRemap::yVal = 0 -- _deref_pbuc1=vbuc2
sta yVal
// *zVal = (remapBlocks & 0xf0) | (>upperPageOffset & 0xf)
// [8] *memoryRemap::zVal = 0 -- _deref_pbuc1=vbuc2
sta zVal
// asm
// asm { ldaaVal ldxxVal ldyyVal ldzzVal map eom }
lda aVal
ldx xVal
ldy yVal
ldz zVal
map
eom
// memoryRemap::@return
// }
// [10] return
rts
}
// memset_dma256
// Set a memory block anywhere in the entire 256MB memory space using MEGA65 DMagic DMA
// Sets the values of num bytes to the memory block pointed to by destination.
// - dest_mb The MB value for the destination (0-255)
// - dest_bank The 64KB bank for the destination (0-15)
// - dest The destination address (within the MB and bank)
// - num The number of bytes to copy
memset_dma256: {
.const dest_mb = 0
.const dest_bank = 0
.const fill = '*'
.const num = $50*$a
.label dest = DEFAULT_SCREEN
.label f018b = memset_dma_command256+4
// dmaMode = DMA->EN018B
// [11] memset_dma256::dmaMode#0 = *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B) -- vbuxx=_deref_pbuc1
// Remember current F018 A/B mode
ldx DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B
// memset_dma_command256[1] = dest_mb
// [12] *(memset_dma_command256+1) = memset_dma256::dest_mb#0 -- _deref_pbuc1=vbuc2
// Set up command
lda #dest_mb
sta memset_dma_command256+1
// f018b->count = num
// [13] *((word*)memset_dma256::f018b#0+OFFSET_STRUCT_DMA_LIST_F018B_COUNT) = memset_dma256::num#0 -- _deref_pwuc1=vwuc2
lda #<num
sta f018b+OFFSET_STRUCT_DMA_LIST_F018B_COUNT
lda #>num
sta f018b+OFFSET_STRUCT_DMA_LIST_F018B_COUNT+1
// f018b->dest_bank = dest_bank
// [14] *((byte*)memset_dma256::f018b#0+OFFSET_STRUCT_DMA_LIST_F018B_DEST_BANK) = memset_dma256::dest_bank#0 -- _deref_pbuc1=vbuc2
lda #dest_bank
sta f018b+OFFSET_STRUCT_DMA_LIST_F018B_DEST_BANK
// f018b->dest = dest
// [15] *((byte**)memset_dma256::f018b#0+OFFSET_STRUCT_DMA_LIST_F018B_DEST) = (byte*)memset_dma256::dest#0 -- _deref_qbuc1=pbuc2
lda #<dest
sta f018b+OFFSET_STRUCT_DMA_LIST_F018B_DEST
lda #>dest
sta f018b+OFFSET_STRUCT_DMA_LIST_F018B_DEST+1
// f018b->src = (char*)fill
// [16] *((byte**)memset_dma256::f018b#0+OFFSET_STRUCT_DMA_LIST_F018B_SRC) = (byte*)memset_dma256::fill#0 -- _deref_qbuc1=pbuc2
// Set fill byte
lda #<fill
sta f018b+OFFSET_STRUCT_DMA_LIST_F018B_SRC
lda #>fill
sta f018b+OFFSET_STRUCT_DMA_LIST_F018B_SRC+1
// DMA->EN018B = 1
// [17] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B) = 1 -- _deref_pbuc1=vbuc2
// Set F018B mode
lda #1
sta DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B
// DMA->ADDRMB = 0
// [18] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMB) = 0 -- _deref_pbuc1=vbuc2
// Set address of DMA list
lda #0
sta DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMB
// DMA->ADDRBANK = 0
// [19] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRBANK) = 0 -- _deref_pbuc1=vbuc2
sta DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRBANK
// DMA-> ADDRMSB = >memset_dma_command256
// [20] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMSB) = >memset_dma_command256 -- _deref_pbuc1=vbuc2
lda #>memset_dma_command256
sta DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMSB
// DMA-> ETRIG = <memset_dma_command256
// [21] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ETRIG) = <memset_dma_command256 -- _deref_pbuc1=vbuc2
// Trigger the DMA (with option lists)
lda #<memset_dma_command256
sta DMA+OFFSET_STRUCT_F018_DMAGIC_ETRIG
// DMA->EN018B = dmaMode
// [22] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B) = memset_dma256::dmaMode#0 -- _deref_pbuc1=vbuxx
// Re-enable F018A mode
stx DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B
// memset_dma256::@return
// }
// [23] return
rts
}
// File Data
.segment Data
// DMA list entry with options for setting data in the 256MB memory space
// Contains DMA options options for setting MB followed by DMA_LIST_F018B struct.
memset_dma_command256: .byte DMA_OPTION_DEST_MB, 0, DMA_OPTION_FORMAT_F018B, DMA_OPTION_END, DMA_COMMAND_FILL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0

View File

@ -0,0 +1,42 @@
const nomodify byte* DEFAULT_SCREEN = (byte*) 2048
const nomodify struct F018_DMAGIC* DMA = (struct F018_DMAGIC*) 55040
const nomodify byte DMA_COMMAND_FILL = 3
const nomodify byte DMA_OPTION_DEST_MB = $81
const nomodify byte DMA_OPTION_END = 0
const nomodify byte DMA_OPTION_FORMAT_F018B = $a
const byte OFFSET_STRUCT_DMA_LIST_F018B_COUNT = 1
const byte OFFSET_STRUCT_DMA_LIST_F018B_DEST = 6
const byte OFFSET_STRUCT_DMA_LIST_F018B_DEST_BANK = 8
const byte OFFSET_STRUCT_DMA_LIST_F018B_SRC = 3
const byte OFFSET_STRUCT_F018_DMAGIC_ADDRBANK = 2
const byte OFFSET_STRUCT_F018_DMAGIC_ADDRMB = 4
const byte OFFSET_STRUCT_F018_DMAGIC_ADDRMSB = 1
const byte OFFSET_STRUCT_F018_DMAGIC_EN018B = 3
const byte OFFSET_STRUCT_F018_DMAGIC_ETRIG = 5
void main()
void memoryRemap(byte memoryRemap::remapBlocks , word memoryRemap::lowerPageOffset , word memoryRemap::upperPageOffset)
const byte* memoryRemap::aVal = (byte*) 252
word memoryRemap::lowerPageOffset
byte memoryRemap::remapBlocks
word memoryRemap::upperPageOffset
const byte* memoryRemap::xVal = (byte*) 253
const byte* memoryRemap::yVal = (byte*) 254
const byte* memoryRemap::zVal = (byte*) 255
void memset_dma256(byte memset_dma256::dest_mb , byte memset_dma256::dest_bank , void* memset_dma256::dest , byte memset_dma256::fill , word memset_dma256::num)
void* memset_dma256::dest
const void* memset_dma256::dest#0 dest = (void*)DEFAULT_SCREEN
byte memset_dma256::dest_bank
const byte memset_dma256::dest_bank#0 dest_bank = 0
byte memset_dma256::dest_mb
const byte memset_dma256::dest_mb#0 dest_mb = 0
byte memset_dma256::dmaMode
byte memset_dma256::dmaMode#0 reg byte x 2.0
struct DMA_LIST_F018B* memset_dma256::f018b
const struct DMA_LIST_F018B* memset_dma256::f018b#0 f018b = (struct DMA_LIST_F018B*)memset_dma_command256+4
byte memset_dma256::fill
const byte memset_dma256::fill#0 fill = '*'
word memset_dma256::num
const word memset_dma256::num#0 num = (word)$50*$a
const byte* memset_dma_command256[] = { DMA_OPTION_DEST_MB, 0, DMA_OPTION_FORMAT_F018B, DMA_OPTION_END, DMA_COMMAND_FILL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
reg byte x [ memset_dma256::dmaMode#0 ]

View File

@ -0,0 +1,468 @@
// DYPP (Different Y Pixel Position) LOGO created using DMA
// Graphics mode is 320x200 full-colour super extended attribute mode text-mode
// Character layout is column-wise giving linear addressing of the graphics (one byte per pixel)
.cpu _45gs02
// MEGA65 platform PRG executable starting in MEGA65 mode.
.file [name="dypp65.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$2001]
.segmentdef Code [start=$2017]
.segmentdef Data [startAfter="Code"]
.segment Basic
.byte $0a, $20, $0a, $00, $fe, $02, $20, $30, $00 // 10 BANK 0
.byte $15, $20, $14, $00, $9e, $20 // 20 SYS
.text toIntString(main) // NNNN
.byte $00, $00, $00 //
// DMA command fill
.const DMA_COMMAND_FILL = 3
// $00 = End of options
.const DMA_OPTION_END = 0
// $0B = Use F018B list format
.const DMA_OPTION_FORMAT_F018B = $a
// $81 $xx = Set MB of destination address
.const DMA_OPTION_DEST_MB = $81
.const WHITE = 1
.const SIZEOF_WORD = 2
.const OFFSET_STRUCT_F018_DMAGIC_EN018B = 3
.const OFFSET_STRUCT_DMA_LIST_F018B_COUNT = 1
.const OFFSET_STRUCT_DMA_LIST_F018B_SRC = 3
.const OFFSET_STRUCT_DMA_LIST_F018B_DEST = 6
.const OFFSET_STRUCT_F018_DMAGIC_ADDRMB = 4
.const OFFSET_STRUCT_F018_DMAGIC_ADDRBANK = 2
.const OFFSET_STRUCT_F018_DMAGIC_ADDRMSB = 1
.const OFFSET_STRUCT_DMA_LIST_F018B_DEST_BANK = 8
.const OFFSET_STRUCT_F018_DMAGIC_ETRIG = 5
.const OFFSET_STRUCT_MEGA65_VICIV_SIDBDRWD_LO = $5c
.const OFFSET_STRUCT_MEGA65_VICIV_SIDBDRWD_HI = $5d
.const OFFSET_STRUCT_MEGA65_VICIV_TBDRPOS_LO = $48
.const OFFSET_STRUCT_MEGA65_VICIV_TBDRPOS_HI = $49
.const OFFSET_STRUCT_MEGA65_VICIV_BBDRPOS_LO = $4a
.const OFFSET_STRUCT_MEGA65_VICIV_BBDRPOS_HI = $4b
.const OFFSET_STRUCT_MEGA65_VICIV_CONTROLB = $31
.const OFFSET_STRUCT_MEGA65_VICIV_CONTROLC = $54
.const OFFSET_STRUCT_MEGA65_VICIV_KEY = $2f
.const OFFSET_STRUCT_MEGA65_VICIV_CHARSTEP_LO = $58
.const OFFSET_STRUCT_MEGA65_VICIV_CHARSTEP_HI = $59
.const OFFSET_STRUCT_MEGA65_VICIV_TEXTXPOS_LO = $4c
.const OFFSET_STRUCT_MEGA65_VICIV_TEXTXPOS_HI = $4d
.const OFFSET_STRUCT_MEGA65_VICIV_CHRCOUNT = $5e
.const OFFSET_STRUCT_MEGA65_VICIV_SCRNPTR_LOLO = $60
.const OFFSET_STRUCT_MEGA65_VICIV_SCRNPTR_LOHI = $61
.const OFFSET_STRUCT_MEGA65_VICIV_SCRNPTR_HILO = $62
.const OFFSET_STRUCT_MEGA65_VICIV_SCRNPTR_HIHI = $63
.const OFFSET_STRUCT_MEGA65_VICIV_CHARPTR_LOLO = $68
.const OFFSET_STRUCT_MEGA65_VICIV_CHARPTR_LOHI = $69
.const OFFSET_STRUCT_MEGA65_VICIV_CHARPTR_HILO = $6a
.const OFFSET_STRUCT_MOS6569_VICII_RASTER = $12
.const OFFSET_STRUCT_MEGA65_VICIV_BG_COLOR = $21
// The VIC-II MOS 6567/6569
.label VICII = $d000
// The VIC IV
.label VICIV = $d000
// DMAgic F018 Controller
.label DMA = $d700
// The screen address (45*25*2=0x08ca bytes)
.label SCREEN = $5000
// The charset address (45*32*8=0x2d00 bytes)
.label CHARSET = $6000
.segment Code
main: {
.label c = 8
// Fill extended screen to achieve column-wise linear addressing
.label erow = 2
// Copy the LOGO to the CHARSET
.label logo_dest = 6
.label logo_src = 4
// asm
sei
// memoryRemap(0,0,0)
// Map memory to BANK 0 : 0x00XXXX - giving access to I/O
jsr memoryRemap
// VICIV->SIDBDRWD_LO = 0
// Set sideborder width=0, disable raster delay and hot registers
lda #0
sta VICIV+OFFSET_STRUCT_MEGA65_VICIV_SIDBDRWD_LO
// VICIV->SIDBDRWD_HI = 0
sta VICIV+OFFSET_STRUCT_MEGA65_VICIV_SIDBDRWD_HI
// VICIV->TBDRPOS_LO = 0
// Disable top/bottom borders
sta VICIV+OFFSET_STRUCT_MEGA65_VICIV_TBDRPOS_LO
// VICIV->TBDRPOS_HI = 0
sta VICIV+OFFSET_STRUCT_MEGA65_VICIV_TBDRPOS_HI
// VICIV->BBDRPOS_LO = 0
sta VICIV+OFFSET_STRUCT_MEGA65_VICIV_BBDRPOS_LO
// VICIV->BBDRPOS_HI = 2
lda #2
sta VICIV+OFFSET_STRUCT_MEGA65_VICIV_BBDRPOS_HI
// VICIV->CONTROLB |= 0x40
// Enable 48MHz fast mode
lda #$40
ora VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLB
sta VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLB
// VICIV->CONTROLC |= 0x40
lda #$40
ora VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLC
sta VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLC
// VICIV->KEY = 0x47
// Enable the VIC 4
lda #$47
sta VICIV+OFFSET_STRUCT_MEGA65_VICIV_KEY
// VICIV->KEY = 0x53
lda #$53
sta VICIV+OFFSET_STRUCT_MEGA65_VICIV_KEY
// VICIV->CONTROLC |= 1
// Enable Super Extended Attribute Mode
lda #1
ora VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLC
sta VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLC
// VICIV->CONTROLB &= 0x7f
// Mode 40x25 chars - will be 45*25 when utilizing the borders
lda #$7f
and VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLB
sta VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLB
// VICIV->CHARSTEP_LO = 90
lda #$5a
sta VICIV+OFFSET_STRUCT_MEGA65_VICIV_CHARSTEP_LO
// VICIV->CHARSTEP_HI = 0
lda #0
sta VICIV+OFFSET_STRUCT_MEGA65_VICIV_CHARSTEP_HI
// VICIV->TEXTXPOS_LO = 40
// Start text in the left border
lda #$28
sta VICIV+OFFSET_STRUCT_MEGA65_VICIV_TEXTXPOS_LO
// VICIV->TEXTXPOS_HI = 0
lda #0
sta VICIV+OFFSET_STRUCT_MEGA65_VICIV_TEXTXPOS_HI
// VICIV->CHRCOUNT = 45
// Set number of characters to display per row
lda #$2d
sta VICIV+OFFSET_STRUCT_MEGA65_VICIV_CHRCOUNT
// VICIV->SCRNPTR_LOLO = <SCREEN
// Set exact screen address
lda #0
sta VICIV+OFFSET_STRUCT_MEGA65_VICIV_SCRNPTR_LOLO
// VICIV->SCRNPTR_LOHI = >SCREEN
lda #>SCREEN
sta VICIV+OFFSET_STRUCT_MEGA65_VICIV_SCRNPTR_LOHI
// VICIV->SCRNPTR_HILO = 0
lda #0
sta VICIV+OFFSET_STRUCT_MEGA65_VICIV_SCRNPTR_HILO
// VICIV->SCRNPTR_HIHI = 0
sta VICIV+OFFSET_STRUCT_MEGA65_VICIV_SCRNPTR_HIHI
// VICIV->CHARPTR_LOLO = <CHARSET
// Set exact charset address
sta VICIV+OFFSET_STRUCT_MEGA65_VICIV_CHARPTR_LOLO
// VICIV->CHARPTR_LOHI = >CHARSET
lda #>CHARSET
sta VICIV+OFFSET_STRUCT_MEGA65_VICIV_CHARPTR_LOHI
// VICIV->CHARPTR_HILO = 0
lda #0
sta VICIV+OFFSET_STRUCT_MEGA65_VICIV_CHARPTR_HILO
// memset_dma(SCREEN, 0, 45*25*2)
// Fill the screen with 0
lda #<SCREEN
sta.z memset_dma.dest
lda #>SCREEN
sta.z memset_dma.dest+1
ldz #0
lda #<$2d*$19*2
sta.z memset_dma.num
lda #>$2d*$19*2
sta.z memset_dma.num+1
jsr memset_dma
// memset_dma256(0xff,0x08,0x0000, WHITE, 45*25*2)
// Fill the colours with WHITE - directly into $ff80000
jsr memset_dma256
// memset_dma(CHARSET, 0x55, 45*32*8)
// Fill the charset with 0x55
lda #<CHARSET
sta.z memset_dma.dest
lda #>CHARSET
sta.z memset_dma.dest+1
ldz #$55
lda #<$2d*$20*8
sta.z memset_dma.num
lda #>$2d*$20*8
sta.z memset_dma.num+1
jsr memset_dma
lda #<SCREEN
sta.z erow
lda #>SCREEN
sta.z erow+1
ldx #0
__b1:
// for(char r=0; r<25; r++)
cpx #$19
bcc __b2
lda #<CHARSET
sta.z logo_dest
lda #>CHARSET
sta.z logo_dest+1
lda #<LOGO
sta.z logo_src
lda #>LOGO
sta.z logo_src+1
ldx #0
__b6:
// for(char col=0;col<45;col++)
cpx #$2d
bcc __b5
__b10:
// VICIV->BG_COLOR = VICII->RASTER
lda VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER
sta VICIV+OFFSET_STRUCT_MEGA65_VICIV_BG_COLOR
jmp __b10
__b5:
ldy #0
__b7:
// for(char y=0;y<25*8;y++)
cpy #$19*8
bcc __b8
// logo_dest += 32*8
clc
lda.z logo_dest
adc #<$20*8
sta.z logo_dest
lda.z logo_dest+1
adc #>$20*8
sta.z logo_dest+1
// logo_src += 25*8
lda #$19*8
clc
adc.z logo_src
sta.z logo_src
bcc !+
inc.z logo_src+1
!:
// for(char col=0;col<45;col++)
inx
jmp __b6
__b8:
// logo_dest[y] = logo_src[y]
lda (logo_src),y
sta (logo_dest),y
// for(char y=0;y<25*8;y++)
iny
jmp __b7
__b2:
// c = r
txa
sta.z c
lda #0
sta.z c+1
ldz #0
__b3:
// for(char i=0; i<45; i++)
cpz #$2d
bcc __b4
// erow += 45
lda #$2d*SIZEOF_WORD
clc
adc.z erow
sta.z erow
bcc !+
inc.z erow+1
!:
// for(char r=0; r<25; r++)
inx
jmp __b1
__b4:
// erow[i] = c
tza
asl
tay
lda.z c
sta (erow),y
iny
lda.z c+1
sta (erow),y
// c += 32
lda #$20
clc
adc.z c
sta.z c
bcc !+
inc.z c+1
!:
// for(char i=0; i<45; i++)
inz
jmp __b3
}
// Remap some of the eight 8K memory blocks in the 64K address space of the 6502 to point somewhere else in the first 1MB memory space of the MEGA65.
// After the remapping the CPU will access the mapped memory whenever it uses instructions that access a remapped block.
// See section 2.3.4 in http://www.zimmers.net/cbmpics/cbm/c65/c65manual.txt for a description of the CPU memory remapper of the C65.
// remapBlocks: Indicates which 8K blocks of the 6502 address space to remap. Each bit represents one 8K block
// - bit 0 Memory block $0000-$1fff. Use constant MEMORYBLOCK_0000.
// - bit 1 Memory block $2000-$3fff. Use constant MEMORYBLOCK_2000.
// - bit 2 Memory block $4000-$5fff. Use constant MEMORYBLOCK_4000.
// - bit 3 Memory block $6000-$7fff. Use constant MEMORYBLOCK_6000.
// - bit 4 Memory block $8000-$9fff. Use constant MEMORYBLOCK_8000.
// - bit 5 Memory block $a000-$bfff. Use constant MEMORYBLOCK_A000.
// - bit 6 Memory block $c000-$dfff. Use constant MEMORYBLOCK_C000.
// - bit 7 Memory block $e000-$ffff. Use constant MEMORYBLOCK_E000.
// lowerPageOffset: Offset that will be added to any remapped blocks in the lower 32K of memory (block 0-3).
// The offset is a page offset (meaning it is multiplied by 0x100). Only the lower 12bits of the passed value is used.
// - If block 0 ($0000-$1fff) is remapped it will point to lowerPageOffset*$100.
// - If block 1 ($2000-$3fff) is remapped it will point to lowerPageOffset*$100 + $2000.
// - If block 2 ($4000-$5fff) is remapped it will point to lowerPageOffset*$100 + $4000.
// - If block 3 ($6000-$7fff) is remapped it will point to lowerPageOffset*$100 + $6000.
// upperPageOffset: Offset that will be added to any remapped blocks in the upper 32K of memory (block 4-7).
// The offset is a page offset (meaning it is multiplied by 0x100). Only the lower 12bits of the passed value is used.
// - If block 4 ($8000-$9fff) is remapped it will point to upperPageOffset*$100 + $8000
// - If block 5 ($a000-$bfff) is remapped it will point to upperPageOffset*$100 + $a000.
// - If block 6 ($c000-$dfff) is remapped it will point to upperPageOffset*$100 + $c000.
// - If block 7 ($e000-$ffff) is remapped it will point to upperPageOffset*$100 + $e000.
memoryRemap: {
.label aVal = $fc
.label xVal = $fd
.label yVal = $fe
.label zVal = $ff
// *aVal = <lowerPageOffset
lda #0
sta aVal
// *xVal = (remapBlocks << 4) | (>lowerPageOffset & 0xf)
sta xVal
// *yVal = <upperPageOffset
sta yVal
// *zVal = (remapBlocks & 0xf0) | (>upperPageOffset & 0xf)
sta zVal
// asm
lda aVal
ldx xVal
ldy yVal
ldz zVal
map
eom
// }
rts
}
// Fill a memory block within the first 64K memory space using MEGA65 DMagic DMA
// Fills the values of num bytes at the destination with a single byte value.
// - dest The destination address (within the MB and bank)
// - fill The char to fill with
// - num The number of bytes to copy
// memset_dma(void* zp($c) dest, byte register(Z) fill, word zp($a) num)
memset_dma: {
.label num = $a
.label dest = $c
// dmaMode = DMA->EN018B
// Remember current F018 A/B mode
ldx DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B
// memset_dma_command.count = num
// Set up command
lda.z num
sta memset_dma_command+OFFSET_STRUCT_DMA_LIST_F018B_COUNT
lda.z num+1
sta memset_dma_command+OFFSET_STRUCT_DMA_LIST_F018B_COUNT+1
// memset_dma_command.src = (char*)fill
tza
sta memset_dma_command+OFFSET_STRUCT_DMA_LIST_F018B_SRC
lda #0
sta memset_dma_command+OFFSET_STRUCT_DMA_LIST_F018B_SRC+1
// memset_dma_command.dest = dest
lda.z dest
sta memset_dma_command+OFFSET_STRUCT_DMA_LIST_F018B_DEST
lda.z dest+1
sta memset_dma_command+OFFSET_STRUCT_DMA_LIST_F018B_DEST+1
// DMA->EN018B = 1
// Set F018B mode
lda #1
sta DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B
// DMA->ADDRMB = 0
// Set address of DMA list
lda #0
sta DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMB
// DMA->ADDRBANK = 0
sta DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRBANK
// DMA-> ADDRMSB = >&memset_dma_command
lda #>memset_dma_command
sta DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMSB
// DMA-> ADDRLSBTRIG = <&memset_dma_command
// Trigger the DMA (without option lists)
lda #<memset_dma_command
sta DMA
// DMA->EN018B = dmaMode
// Re-enable F018A mode
stx DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B
// }
rts
}
// Set a memory block anywhere in the entire 256MB memory space using MEGA65 DMagic DMA
// Sets the values of num bytes to the memory block pointed to by destination.
// - dest_mb The MB value for the destination (0-255)
// - dest_bank The 64KB bank for the destination (0-15)
// - dest The destination address (within the MB and bank)
// - num The number of bytes to copy
memset_dma256: {
.const dest_mb = $ff
.const dest_bank = 8
.const num = $2d*$19*2
.label dest = 0
.label f018b = memset_dma_command256+4
// dmaMode = DMA->EN018B
// Remember current F018 A/B mode
ldx DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B
// memset_dma_command256[1] = dest_mb
// Set up command
lda #dest_mb
sta memset_dma_command256+1
// f018b->count = num
lda #<num
sta f018b+OFFSET_STRUCT_DMA_LIST_F018B_COUNT
lda #>num
sta f018b+OFFSET_STRUCT_DMA_LIST_F018B_COUNT+1
// f018b->dest_bank = dest_bank
lda #dest_bank
sta f018b+OFFSET_STRUCT_DMA_LIST_F018B_DEST_BANK
// f018b->dest = dest
lda #<dest
sta f018b+OFFSET_STRUCT_DMA_LIST_F018B_DEST
lda #>dest
sta f018b+OFFSET_STRUCT_DMA_LIST_F018B_DEST+1
// f018b->src = (char*)fill
// Set fill byte
lda #<WHITE
sta f018b+OFFSET_STRUCT_DMA_LIST_F018B_SRC
lda #>WHITE
sta f018b+OFFSET_STRUCT_DMA_LIST_F018B_SRC+1
// DMA->EN018B = 1
// Set F018B mode
lda #1
sta DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B
// DMA->ADDRMB = 0
// Set address of DMA list
lda #0
sta DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMB
// DMA->ADDRBANK = 0
sta DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRBANK
// DMA-> ADDRMSB = >memset_dma_command256
lda #>memset_dma_command256
sta DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMSB
// DMA-> ETRIG = <memset_dma_command256
// Trigger the DMA (with option lists)
lda #<memset_dma_command256
sta DMA+OFFSET_STRUCT_F018_DMAGIC_ETRIG
// DMA->EN018B = dmaMode
// Re-enable F018A mode
stx DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B
// }
rts
}
.segment Data
// DMA list entry with options for setting data in the 256MB memory space
// Contains DMA options options for setting MB followed by DMA_LIST_F018B struct.
memset_dma_command256: .byte DMA_OPTION_DEST_MB, 0, DMA_OPTION_FORMAT_F018B, DMA_OPTION_END, DMA_COMMAND_FILL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
// A logo in column-wide linear single-color memory layout
LOGO:
.var pic = LoadPicture("camelot.png", List().add($ffffff, $000000))
.for (var x=0;x<45; x++)
.for (var y=0; y<25*8; y++)
.byte pic.getSinglecolorByte(x,y)
// DMA list entry for filling data
memset_dma_command: .byte DMA_COMMAND_FILL
.word 0, 0
.byte 0
.word 0
.byte 0, 0
.word 0

View File

@ -0,0 +1,143 @@
void main()
main: scope:[main] from
[0] phi()
to:main::SEI1
main::SEI1: scope:[main] from main
asm { sei }
to:main::@11
main::@11: scope:[main] from main::SEI1
[2] phi()
[3] call memoryRemap
to:main::@12
main::@12: scope:[main] from main::@11
[4] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_SIDBDRWD_LO) = 0
[5] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_SIDBDRWD_HI) = 0
[6] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_TBDRPOS_LO) = 0
[7] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_TBDRPOS_HI) = 0
[8] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_BBDRPOS_LO) = 0
[9] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_BBDRPOS_HI) = 2
[10] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLB) = *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLB) | $40
[11] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLC) = *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLC) | $40
[12] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_KEY) = $47
[13] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_KEY) = $53
[14] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLC) = *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLC) | 1
[15] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLB) = *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CONTROLB) & $7f
[16] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CHARSTEP_LO) = $5a
[17] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CHARSTEP_HI) = 0
[18] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_TEXTXPOS_LO) = $28
[19] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_TEXTXPOS_HI) = 0
[20] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CHRCOUNT) = $2d
[21] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_SCRNPTR_LOLO) = 0
[22] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_SCRNPTR_LOHI) = >SCREEN
[23] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_SCRNPTR_HILO) = 0
[24] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_SCRNPTR_HIHI) = 0
[25] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CHARPTR_LOLO) = 0
[26] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CHARPTR_LOHI) = >CHARSET
[27] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_CHARPTR_HILO) = 0
[28] call memset_dma
to:main::@13
main::@13: scope:[main] from main::@12
[29] phi()
[30] call memset_dma256
to:main::@14
main::@14: scope:[main] from main::@13
[31] phi()
[32] call memset_dma
to:main::@1
main::@1: scope:[main] from main::@14 main::@5
[33] main::erow#5 = phi( main::@14/SCREEN, main::@5/main::erow#1 )
[33] main::r#2 = phi( main::@14/0, main::@5/main::r#1 )
[34] if(main::r#2<$19) goto main::@2
to:main::@6
main::@6: scope:[main] from main::@1 main::@9
[35] main::logo_dest#5 = phi( main::@9/main::logo_dest#1, main::@1/CHARSET )
[35] main::logo_src#5 = phi( main::@9/main::logo_src#1, main::@1/LOGO )
[35] main::col#2 = phi( main::@9/main::col#1, main::@1/0 )
[36] if(main::col#2<$2d) goto main::@7
to:main::@10
main::@10: scope:[main] from main::@10 main::@6
[37] *((byte*)VICIV+OFFSET_STRUCT_MEGA65_VICIV_BG_COLOR) = *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER)
to:main::@10
main::@7: scope:[main] from main::@6 main::@8
[38] main::y#2 = phi( main::@8/main::y#1, main::@6/0 )
[39] if(main::y#2<(byte)$19*8) goto main::@8
to:main::@9
main::@9: scope:[main] from main::@7
[40] main::logo_dest#1 = main::logo_dest#5 + (word)$20*8
[41] main::logo_src#1 = main::logo_src#5 + (byte)$19*8
[42] main::col#1 = ++ main::col#2
to:main::@6
main::@8: scope:[main] from main::@7
[43] main::logo_dest#5[main::y#2] = main::logo_src#5[main::y#2]
[44] main::y#1 = ++ main::y#2
to:main::@7
main::@2: scope:[main] from main::@1
[45] main::c#0 = (word)main::r#2
to:main::@3
main::@3: scope:[main] from main::@2 main::@4
[46] main::c#2 = phi( main::@2/main::c#0, main::@4/main::c#1 )
[46] main::i#2 = phi( main::@2/0, main::@4/main::i#1 )
[47] if(main::i#2<$2d) goto main::@4
to:main::@5
main::@5: scope:[main] from main::@3
[48] main::erow#1 = main::erow#5 + $2d*SIZEOF_WORD
[49] main::r#1 = ++ main::r#2
to:main::@1
main::@4: scope:[main] from main::@3
[50] main::$10 = main::i#2 << 1
[51] main::erow#5[main::$10] = main::c#2
[52] main::c#1 = main::c#2 + $20
[53] main::i#1 = ++ main::i#2
to:main::@3
void memoryRemap(byte memoryRemap::remapBlocks , word memoryRemap::lowerPageOffset , word memoryRemap::upperPageOffset)
memoryRemap: scope:[memoryRemap] from main::@11
[54] *memoryRemap::aVal = 0
[55] *memoryRemap::xVal = 0
[56] *memoryRemap::yVal = 0
[57] *memoryRemap::zVal = 0
asm { ldaaVal ldxxVal ldyyVal ldzzVal map eom }
to:memoryRemap::@return
memoryRemap::@return: scope:[memoryRemap] from memoryRemap
[59] return
to:@return
void memset_dma(void* memset_dma::dest , byte memset_dma::fill , word memset_dma::num)
memset_dma: scope:[memset_dma] from main::@12 main::@14
[60] memset_dma::dest#2 = phi( main::@12/(void*)SCREEN, main::@14/(void*)CHARSET )
[60] memset_dma::fill#2 = phi( main::@12/0, main::@14/$55 )
[60] memset_dma::num#2 = phi( main::@12/(word)$2d*$19*2, main::@14/(word)$2d*$20*8 )
[61] memset_dma::dmaMode#0 = *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B)
[62] *((word*)&memset_dma_command+OFFSET_STRUCT_DMA_LIST_F018B_COUNT) = memset_dma::num#2
[63] *((byte**)&memset_dma_command+OFFSET_STRUCT_DMA_LIST_F018B_SRC) = (byte*)memset_dma::fill#2
[64] *((byte**)&memset_dma_command+OFFSET_STRUCT_DMA_LIST_F018B_DEST) = (byte*)memset_dma::dest#2
[65] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B) = 1
[66] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMB) = 0
[67] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRBANK) = 0
[68] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMSB) = >&memset_dma_command
[69] *((byte*)DMA) = <&memset_dma_command
[70] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B) = memset_dma::dmaMode#0
to:memset_dma::@return
memset_dma::@return: scope:[memset_dma] from memset_dma
[71] return
to:@return
void memset_dma256(byte memset_dma256::dest_mb , byte memset_dma256::dest_bank , void* memset_dma256::dest , byte memset_dma256::fill , word memset_dma256::num)
memset_dma256: scope:[memset_dma256] from main::@13
[72] memset_dma256::dmaMode#0 = *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B)
[73] *(memset_dma_command256+1) = memset_dma256::dest_mb#0
[74] *((word*)memset_dma256::f018b#0+OFFSET_STRUCT_DMA_LIST_F018B_COUNT) = memset_dma256::num#0
[75] *((byte*)memset_dma256::f018b#0+OFFSET_STRUCT_DMA_LIST_F018B_DEST_BANK) = memset_dma256::dest_bank#0
[76] *((byte**)memset_dma256::f018b#0+OFFSET_STRUCT_DMA_LIST_F018B_DEST) = (byte*)memset_dma256::dest#0
[77] *((byte**)memset_dma256::f018b#0+OFFSET_STRUCT_DMA_LIST_F018B_SRC) = (byte*)WHITE
[78] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B) = 1
[79] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMB) = 0
[80] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRBANK) = 0
[81] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ADDRMSB) = >memset_dma_command256
[82] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_ETRIG) = <memset_dma_command256
[83] *((byte*)DMA+OFFSET_STRUCT_F018_DMAGIC_EN018B) = memset_dma256::dmaMode#0
to:memset_dma256::@return
memset_dma256::@return: scope:[memset_dma256] from memset_dma256
[84] return
to:@return

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,124 @@
const nomodify byte* CHARSET = (byte*) 24576
const nomodify struct F018_DMAGIC* DMA = (struct F018_DMAGIC*) 55040
const nomodify byte DMA_COMMAND_FILL = 3
const nomodify byte DMA_OPTION_DEST_MB = $81
const nomodify byte DMA_OPTION_END = 0
const nomodify byte DMA_OPTION_FORMAT_F018B = $a
const byte* LOGO[$2d*$19*8] = kickasm {{ .var pic = LoadPicture("camelot.png", List().add($ffffff, $000000))
.for (var x=0;x<45; x++)
.for (var y=0; y<25*8; y++)
.byte pic.getSinglecolorByte(x,y)
}}
const byte OFFSET_STRUCT_DMA_LIST_F018B_COUNT = 1
const byte OFFSET_STRUCT_DMA_LIST_F018B_DEST = 6
const byte OFFSET_STRUCT_DMA_LIST_F018B_DEST_BANK = 8
const byte OFFSET_STRUCT_DMA_LIST_F018B_SRC = 3
const byte OFFSET_STRUCT_F018_DMAGIC_ADDRBANK = 2
const byte OFFSET_STRUCT_F018_DMAGIC_ADDRMB = 4
const byte OFFSET_STRUCT_F018_DMAGIC_ADDRMSB = 1
const byte OFFSET_STRUCT_F018_DMAGIC_EN018B = 3
const byte OFFSET_STRUCT_F018_DMAGIC_ETRIG = 5
const byte OFFSET_STRUCT_MEGA65_VICIV_BBDRPOS_HI = $4b
const byte OFFSET_STRUCT_MEGA65_VICIV_BBDRPOS_LO = $4a
const byte OFFSET_STRUCT_MEGA65_VICIV_BG_COLOR = $21
const byte OFFSET_STRUCT_MEGA65_VICIV_CHARPTR_HILO = $6a
const byte OFFSET_STRUCT_MEGA65_VICIV_CHARPTR_LOHI = $69
const byte OFFSET_STRUCT_MEGA65_VICIV_CHARPTR_LOLO = $68
const byte OFFSET_STRUCT_MEGA65_VICIV_CHARSTEP_HI = $59
const byte OFFSET_STRUCT_MEGA65_VICIV_CHARSTEP_LO = $58
const byte OFFSET_STRUCT_MEGA65_VICIV_CHRCOUNT = $5e
const byte OFFSET_STRUCT_MEGA65_VICIV_CONTROLB = $31
const byte OFFSET_STRUCT_MEGA65_VICIV_CONTROLC = $54
const byte OFFSET_STRUCT_MEGA65_VICIV_KEY = $2f
const byte OFFSET_STRUCT_MEGA65_VICIV_SCRNPTR_HIHI = $63
const byte OFFSET_STRUCT_MEGA65_VICIV_SCRNPTR_HILO = $62
const byte OFFSET_STRUCT_MEGA65_VICIV_SCRNPTR_LOHI = $61
const byte OFFSET_STRUCT_MEGA65_VICIV_SCRNPTR_LOLO = $60
const byte OFFSET_STRUCT_MEGA65_VICIV_SIDBDRWD_HI = $5d
const byte OFFSET_STRUCT_MEGA65_VICIV_SIDBDRWD_LO = $5c
const byte OFFSET_STRUCT_MEGA65_VICIV_TBDRPOS_HI = $49
const byte OFFSET_STRUCT_MEGA65_VICIV_TBDRPOS_LO = $48
const byte OFFSET_STRUCT_MEGA65_VICIV_TEXTXPOS_HI = $4d
const byte OFFSET_STRUCT_MEGA65_VICIV_TEXTXPOS_LO = $4c
const byte OFFSET_STRUCT_MOS6569_VICII_RASTER = $12
const nomodify byte* SCREEN = (byte*) 20480
const byte SIZEOF_WORD = 2
const nomodify struct MOS6569_VICII* VICII = (struct MOS6569_VICII*) 53248
const nomodify struct MEGA65_VICIV* VICIV = (struct MEGA65_VICIV*) 53248
const nomodify byte WHITE = 1
void main()
byte~ main::$10 reg byte a 202.0
word main::c
word main::c#0 c zp[2]:8 22.0
word main::c#1 c zp[2]:8 101.0
word main::c#2 c zp[2]:8 78.5
byte main::col
byte main::col#1 reg byte x 22.0
byte main::col#2 reg byte x 4.125
word* main::erow
word* main::erow#1 erow zp[2]:2 11.0
word* main::erow#5 erow zp[2]:2 13.666666666666666
byte main::i
byte main::i#1 reg byte z 202.0
byte main::i#2 reg byte z 80.8
byte* main::logo_dest
byte* main::logo_dest#1 logo_dest zp[2]:6 7.333333333333333
byte* main::logo_dest#5 logo_dest zp[2]:6 20.5
byte* main::logo_src
byte* main::logo_src#1 logo_src zp[2]:4 11.0
byte* main::logo_src#5 logo_src zp[2]:4 17.571428571428573
byte main::r
byte main::r#1 reg byte x 22.0
byte main::r#2 reg byte x 3.3000000000000003
byte main::y
byte main::y#1 reg byte y 202.0
byte main::y#2 reg byte y 168.33333333333331
void memoryRemap(byte memoryRemap::remapBlocks , word memoryRemap::lowerPageOffset , word memoryRemap::upperPageOffset)
const byte* memoryRemap::aVal = (byte*) 252
word memoryRemap::lowerPageOffset
byte memoryRemap::remapBlocks
word memoryRemap::upperPageOffset
const byte* memoryRemap::xVal = (byte*) 253
const byte* memoryRemap::yVal = (byte*) 254
const byte* memoryRemap::zVal = (byte*) 255
void memset_dma(void* memset_dma::dest , byte memset_dma::fill , word memset_dma::num)
void* memset_dma::dest
void* memset_dma::dest#2 dest zp[2]:12
byte memset_dma::dmaMode
byte memset_dma::dmaMode#0 reg byte x 2.4444444444444446
byte memset_dma::fill
byte memset_dma::fill#2 reg byte z
word memset_dma::num
word memset_dma::num#2 num zp[2]:10 5.5
void memset_dma256(byte memset_dma256::dest_mb , byte memset_dma256::dest_bank , void* memset_dma256::dest , byte memset_dma256::fill , word memset_dma256::num)
void* memset_dma256::dest
const void* memset_dma256::dest#0 dest = (void*) 0
byte memset_dma256::dest_bank
const byte memset_dma256::dest_bank#0 dest_bank = 8
byte memset_dma256::dest_mb
const byte memset_dma256::dest_mb#0 dest_mb = $ff
byte memset_dma256::dmaMode
byte memset_dma256::dmaMode#0 reg byte x 2.0
struct DMA_LIST_F018B* memset_dma256::f018b
const struct DMA_LIST_F018B* memset_dma256::f018b#0 f018b = (struct DMA_LIST_F018B*)memset_dma_command256+4
byte memset_dma256::fill
word memset_dma256::num
const word memset_dma256::num#0 num = (word)$2d*$19*2
struct DMA_LIST_F018B memset_dma_command loadstore mem[12] = { command: DMA_COMMAND_FILL, count: 0, src: (byte*) 0, src_bank: 0, dest: (byte*) 0, dest_bank: 0, sub_command: 0, modulo: 0 }
const byte* memset_dma_command256[] = { DMA_OPTION_DEST_MB, 0, DMA_OPTION_FORMAT_F018B, DMA_OPTION_END, DMA_COMMAND_FILL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
reg byte x [ main::r#2 main::r#1 ]
zp[2]:2 [ main::erow#5 main::erow#1 ]
reg byte x [ main::col#2 main::col#1 ]
zp[2]:4 [ main::logo_src#5 main::logo_src#1 ]
zp[2]:6 [ main::logo_dest#5 main::logo_dest#1 ]
reg byte y [ main::y#2 main::y#1 ]
reg byte z [ main::i#2 main::i#1 ]
zp[2]:8 [ main::c#2 main::c#0 main::c#1 ]
zp[2]:10 [ memset_dma::num#2 ]
reg byte z [ memset_dma::fill#2 ]
zp[2]:12 [ memset_dma::dest#2 ]
reg byte a [ main::$10 ]
reg byte x [ memset_dma::dmaMode#0 ]
reg byte x [ memset_dma256::dmaMode#0 ]
mem[12] [ memset_dma_command ]