mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-11-29 18:49:42 +00:00
Working on MEGA65 platform target. #507
This commit is contained in:
parent
4fe1c9b48e
commit
2cec5191e1
95
src/main/kc/include/mega65.h
Normal file
95
src/main/kc/include/mega65.h
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
// MEGA65 Registers and Constants
|
||||||
|
#ifndef __MEGA65__
|
||||||
|
#error "Target platform must be MEGA64"
|
||||||
|
#endif
|
||||||
|
#include <mos6526.h>
|
||||||
|
#include <mos6569.h>
|
||||||
|
#include <mos6581.h>
|
||||||
|
|
||||||
|
// I/O Personality selection
|
||||||
|
volatile char * const IO_KEY = 0xd02f;
|
||||||
|
// C65 Banking Register
|
||||||
|
volatile char * const IO_BANK = 0xd030;
|
||||||
|
// Map 2nd KB of colour RAM $DC00-$DFFF (hiding CIA's)
|
||||||
|
const char CRAM2K = 0b00000001;
|
||||||
|
|
||||||
|
// Processor port data direction register
|
||||||
|
char* const PROCPORT_DDR = 0x00;
|
||||||
|
// Mask for PROCESSOR_PORT_DDR which allows only memory configuration to be written
|
||||||
|
const char PROCPORT_DDR_MEMORY_MASK = 0b00000111;
|
||||||
|
// Processor Port Register controlling RAM/ROM configuration and the datasette
|
||||||
|
char* const PROCPORT = 0x01;
|
||||||
|
// RAM in all three areas 0xA000, 0xD000, 0xE000
|
||||||
|
const char PROCPORT_RAM_ALL = 0b00000000;
|
||||||
|
// RAM in 0xA000, 0xE000 I/O in 0xD000
|
||||||
|
const char PROCPORT_RAM_IO = 0b00000101;
|
||||||
|
// RAM in 0xA000, 0xE000 CHAR ROM in 0xD000
|
||||||
|
const char PROCPORT_RAM_CHARROM = 0b00000001;
|
||||||
|
// RAM in 0xA000, I/O in 0xD000, KERNEL in 0xE000
|
||||||
|
const char PROCPORT_KERNEL_IO = 0b00000110;
|
||||||
|
// BASIC in 0xA000, I/O in 0xD000, KERNEL in 0xE000
|
||||||
|
const char PROCPORT_BASIC_KERNEL_IO = 0b00000111;
|
||||||
|
|
||||||
|
// The address of the CHARGEN character set
|
||||||
|
char* const CHARGEN = 0xd000;
|
||||||
|
// The SID MOS 6581/8580
|
||||||
|
struct MOS6581_SID * const SID = 0xd400;
|
||||||
|
// The VIC-II MOS 6567/6569
|
||||||
|
struct MOS6569_VICII* const VICII = 0xd000;
|
||||||
|
// Color Ram
|
||||||
|
char * const COLORRAM = 0xd800;
|
||||||
|
|
||||||
|
// Default address of screen character matrix
|
||||||
|
char * const DEFAULT_SCREEN = 0x0800;
|
||||||
|
|
||||||
|
// The CIA#1: keyboard matrix, joystick #1/#2
|
||||||
|
struct MOS6526_CIA * const CIA1 = 0xdc00;
|
||||||
|
// The CIA#2: Serial bus, RS-232, VIC memory bank
|
||||||
|
struct MOS6526_CIA * const CIA2 = 0xdd00;
|
||||||
|
// CIA#1 Interrupt for reading in ASM
|
||||||
|
char * const CIA1_INTERRUPT = 0xdc0d;
|
||||||
|
// CIA#2 timer A&B as one single 32-bit value
|
||||||
|
unsigned long* const CIA2_TIMER_AB = 0xdd04;
|
||||||
|
// CIA#2 Interrupt for reading in ASM
|
||||||
|
char * const CIA2_INTERRUPT = 0xdd0d;
|
||||||
|
|
||||||
|
// The vector used when the KERNAL serves IRQ interrupts
|
||||||
|
void()** const KERNEL_IRQ = 0x0314;
|
||||||
|
// The vector used when the KERNAL serves NMI interrupts
|
||||||
|
void()** const KERNEL_NMI = 0x0318;
|
||||||
|
// The vector used when the HARDWARE serves IRQ interrupts
|
||||||
|
void()** const HARDWARE_IRQ = 0xfffe;
|
||||||
|
|
||||||
|
// The colors of the C64
|
||||||
|
const char BLACK = 0x0;
|
||||||
|
const char WHITE = 0x1;
|
||||||
|
const char RED = 0x2;
|
||||||
|
const char CYAN = 0x3;
|
||||||
|
const char PURPLE = 0x4;
|
||||||
|
const char GREEN = 0x5;
|
||||||
|
const char BLUE = 0x6;
|
||||||
|
const char YELLOW = 0x7;
|
||||||
|
const char ORANGE = 0x8;
|
||||||
|
const char BROWN = 0x9;
|
||||||
|
const char PINK = 0xa;
|
||||||
|
const char DARK_GREY= 0xb;
|
||||||
|
const char GREY = 0xc;
|
||||||
|
const char LIGHT_GREEN = 0xd;
|
||||||
|
const char LIGHT_BLUE = 0xe;
|
||||||
|
const char LIGHT_GREY = 0xf;
|
||||||
|
|
||||||
|
// Get the value to store into D018 to display a specific screen and charset/bitmap
|
||||||
|
// Optimized for ASM from (char)((((unsigned int)screen&0x3fff)/0x40)|(((unsigned int)charset&0x3fff)/0x400));
|
||||||
|
char toD018(char* screen, char* gfx);
|
||||||
|
|
||||||
|
// Get the value to store into DD00 (CIA 2 port A) to choose a specific VIC bank
|
||||||
|
// Optimized for ASM from %00000011 ^ (char)((unsigned int)gfx/0x4000)
|
||||||
|
char toDd00(char* gfx);
|
||||||
|
|
||||||
|
// Get the sprite pointer for a sprite.
|
||||||
|
// The sprite pointer is the index of the sprite within the graphics bank and equal to the sprite (char)(sprite_addr/64)
|
||||||
|
// The sprite pointers are stored SCREEN+0x3f8+sprite_id to set the pointer of each sprite
|
||||||
|
char toSpritePtr(char* sprite);
|
||||||
|
|
||||||
|
// Select a specific VIC graphics bank by setting the CIA 2 port A (0xdd00) as needed
|
||||||
|
void vicSelectGfxBank(char* gfx);
|
51
src/main/kc/lib/conio-mega65.c
Normal file
51
src/main/kc/lib/conio-mega65.c
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
// MEGA65 conio.h implementation
|
||||||
|
#include <conio.h>
|
||||||
|
#include <mega65.h>
|
||||||
|
|
||||||
|
// The screen width
|
||||||
|
#define CONIO_WIDTH 80
|
||||||
|
// The screen height
|
||||||
|
#define CONIO_HEIGHT 25
|
||||||
|
// The text screen address
|
||||||
|
char * const CONIO_SCREEN_TEXT = DEFAULT_SCREEN;
|
||||||
|
// The color screen address
|
||||||
|
char * const CONIO_SCREEN_COLORS = COLORRAM;
|
||||||
|
// The default text color
|
||||||
|
const char CONIO_TEXTCOLOR_DEFAULT = LIGHT_BLUE;
|
||||||
|
|
||||||
|
// Use the shared CMB flat memory implementation
|
||||||
|
#include "conio-cbm-shared.c"
|
||||||
|
|
||||||
|
// Return true if there's a key waiting, return false if not
|
||||||
|
unsigned char kbhit (void) {
|
||||||
|
// CIA#1 Port A: keyboard matrix columns and joystick #2
|
||||||
|
char* const CIA1_PORT_A = 0xdc00;
|
||||||
|
// CIA#1 Port B: keyboard matrix rows and joystick #1.
|
||||||
|
char* const CIA1_PORT_B = 0xdc01;
|
||||||
|
// Map CIA I/O
|
||||||
|
*IO_BANK &= ~CRAM2K;
|
||||||
|
// Read keyboard
|
||||||
|
*CIA1_PORT_A = 0;
|
||||||
|
unsigned char hit = ~*CIA1_PORT_B;
|
||||||
|
// Map 2K Color RAM
|
||||||
|
*IO_BANK |= CRAM2K;
|
||||||
|
return hit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the color for the background. The old color setting is returned.
|
||||||
|
unsigned char bgcolor(unsigned char color) {
|
||||||
|
// The background color register address
|
||||||
|
char * const CONIO_BGCOLOR = 0xd021;
|
||||||
|
char old = *CONIO_BGCOLOR;
|
||||||
|
*CONIO_BGCOLOR = color;
|
||||||
|
return old;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the color for the border. The old color setting is returned.
|
||||||
|
unsigned char bordercolor(unsigned char color) {
|
||||||
|
// The border color register address
|
||||||
|
char * const CONIO_BORDERCOLOR = 0xd020;
|
||||||
|
char old = *CONIO_BORDERCOLOR;
|
||||||
|
*CONIO_BORDERCOLOR = color;
|
||||||
|
return old;
|
||||||
|
}
|
@ -11,6 +11,8 @@
|
|||||||
#include "conio-plus4.c"
|
#include "conio-plus4.c"
|
||||||
#elif defined(__VIC20__)
|
#elif defined(__VIC20__)
|
||||||
#include "conio-vic20.c"
|
#include "conio-vic20.c"
|
||||||
|
#elif defined(__MEGA65__)
|
||||||
|
#include "conio-mega65.c"
|
||||||
#elif defined(__NES__)
|
#elif defined(__NES__)
|
||||||
#include "conio-nes.c"
|
#include "conio-nes.c"
|
||||||
#else
|
#else
|
||||||
|
27
src/main/kc/lib/mega65.c
Normal file
27
src/main/kc/lib/mega65.c
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
// Commodore 64 Registers and Constants
|
||||||
|
#include <mega65.h>
|
||||||
|
|
||||||
|
// Get the value to store into D018 to display a specific screen and charset/bitmap
|
||||||
|
// Optimized for ASM from (char)((((unsigned int)screen&$3fff)/$40)|(((unsigned int)charset&$3fff)/$400));
|
||||||
|
inline char toD018(char* screen, char* gfx) {
|
||||||
|
return (>((((unsigned int)screen&$3fff)*4)))|(((>((unsigned int)gfx))/4)&$f);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the value to store into DD00 (CIA 2 port A) to choose a specific VIC bank
|
||||||
|
// Optimized for ASM from %00000011 ^ (char)((unsigned int)gfx/$4000)
|
||||||
|
inline char toDd00(char* gfx) {
|
||||||
|
return %00000011 ^ (>((unsigned int)gfx))/$40;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the sprite pointer for a sprite.
|
||||||
|
// The sprite pointer is the index of the sprite within the graphics bank and equal to the sprite (char)(sprite_addr/64)
|
||||||
|
// The sprite pointers are stored SCREEN+$3f8+sprite_id to set the pointer of each sprite
|
||||||
|
inline char toSpritePtr(char* sprite) {
|
||||||
|
return (char)(((unsigned int)sprite)/$40);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Select a specific VIC graphics bank by setting the CIA 2 port A ($dd00) as needed
|
||||||
|
inline void vicSelectGfxBank(char* gfx) {
|
||||||
|
CIA2->PORT_A_DDR = %00000011;
|
||||||
|
CIA2->PORT_A = toDd00(gfx);
|
||||||
|
}
|
@ -192,6 +192,11 @@ public class TestPrograms {
|
|||||||
compileAndCompare("examples/nes-demo/nes-demo.c");
|
compileAndCompare("examples/nes-demo/nes-demo.c");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMega65Addressing32bit() throws IOException, URISyntaxException {
|
||||||
|
compileAndCompare("examples/mega65/32bit-addressing-mega65.c");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMega65Hello() throws IOException, URISyntaxException {
|
public void testMega65Hello() throws IOException, URISyntaxException {
|
||||||
compileAndCompare("examples/mega65/hello-mega65.c");
|
compileAndCompare("examples/mega65/hello-mega65.c");
|
||||||
|
31
src/test/kc/examples/mega65/32bit-addressing-mega65.c
Normal file
31
src/test/kc/examples/mega65/32bit-addressing-mega65.c
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
// 32-bit addressing using the new addressing mode
|
||||||
|
#pragma target(mega65)
|
||||||
|
|
||||||
|
// Absolute 32-bit address to use for storing/loading data
|
||||||
|
volatile __zp unsigned long ADDR32;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
// Modify Color Ram using 32-bit addressing
|
||||||
|
ADDR32 = 0xff80000;
|
||||||
|
asm {
|
||||||
|
ldz #0
|
||||||
|
!:
|
||||||
|
tza
|
||||||
|
sta ((ADDR32)),z
|
||||||
|
inz
|
||||||
|
cpz #80
|
||||||
|
bne !-
|
||||||
|
}
|
||||||
|
|
||||||
|
// Modify Screen using 32-bit addressing
|
||||||
|
ADDR32 = 0x00000800;
|
||||||
|
asm {
|
||||||
|
lda #'*'
|
||||||
|
ldz #79
|
||||||
|
!:
|
||||||
|
sta ((ADDR32)),z
|
||||||
|
dez
|
||||||
|
bpl !-
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,5 +1,4 @@
|
|||||||
// Hello World for MEGA 65
|
// Hello World for MEGA 65 - putting chars directly to the screen
|
||||||
|
|
||||||
#pragma target(mega65)
|
#pragma target(mega65)
|
||||||
|
|
||||||
char * SCREEN = 0x0800;
|
char * SCREEN = 0x0800;
|
||||||
|
66
src/test/ref/examples/mega65/32bit-addressing-mega65.asm
Normal file
66
src/test/ref/examples/mega65/32bit-addressing-mega65.asm
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
// 32-bit addressing using the new addressing mode
|
||||||
|
.cpu _45gs02
|
||||||
|
.file [name="32bit-addressing-mega65.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(__start) // NNNN
|
||||||
|
.byte $00, $00, $00 //
|
||||||
|
// Absolute 32-bit address to use for storing/loading data
|
||||||
|
.label ADDR32 = 2
|
||||||
|
.segment Code
|
||||||
|
__start: {
|
||||||
|
// ADDR32
|
||||||
|
lda #<0
|
||||||
|
sta.z ADDR32
|
||||||
|
sta.z ADDR32+1
|
||||||
|
lda #<0>>$10
|
||||||
|
sta.z ADDR32+2
|
||||||
|
lda #>0>>$10
|
||||||
|
sta.z ADDR32+3
|
||||||
|
jsr main
|
||||||
|
rts
|
||||||
|
}
|
||||||
|
main: {
|
||||||
|
// ADDR32 = 0xff80000
|
||||||
|
// Modify Color Ram using 32-bit addressing
|
||||||
|
lda #<$ff80000
|
||||||
|
sta.z ADDR32
|
||||||
|
lda #>$ff80000
|
||||||
|
sta.z ADDR32+1
|
||||||
|
lda #<$ff80000>>$10
|
||||||
|
sta.z ADDR32+2
|
||||||
|
lda #>$ff80000>>$10
|
||||||
|
sta.z ADDR32+3
|
||||||
|
// asm
|
||||||
|
ldz #0
|
||||||
|
!:
|
||||||
|
tza
|
||||||
|
sta.z ((ADDR32)),z
|
||||||
|
inz
|
||||||
|
cpz #$50
|
||||||
|
bne !-
|
||||||
|
// ADDR32 = 0x00000800
|
||||||
|
// Modify Screen using 32-bit addressing
|
||||||
|
lda #<$800
|
||||||
|
sta.z ADDR32
|
||||||
|
lda #>$800
|
||||||
|
sta.z ADDR32+1
|
||||||
|
lda #<$800>>$10
|
||||||
|
sta.z ADDR32+2
|
||||||
|
lda #>$800>>$10
|
||||||
|
sta.z ADDR32+3
|
||||||
|
// asm
|
||||||
|
lda #'*'
|
||||||
|
ldz #$4f
|
||||||
|
!:
|
||||||
|
sta.z ((ADDR32)),z
|
||||||
|
dez
|
||||||
|
bpl !-
|
||||||
|
// }
|
||||||
|
rts
|
||||||
|
}
|
26
src/test/ref/examples/mega65/32bit-addressing-mega65.cfg
Normal file
26
src/test/ref/examples/mega65/32bit-addressing-mega65.cfg
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
|
||||||
|
(void()) __start()
|
||||||
|
__start: scope:[__start] from
|
||||||
|
[0] phi()
|
||||||
|
to:__start::__init1
|
||||||
|
__start::__init1: scope:[__start] from __start
|
||||||
|
[1] (volatile dword) ADDR32 ← (dword) 0
|
||||||
|
to:__start::@1
|
||||||
|
__start::@1: scope:[__start] from __start::__init1
|
||||||
|
[2] phi()
|
||||||
|
[3] call main
|
||||||
|
to:__start::@return
|
||||||
|
__start::@return: scope:[__start] from __start::@1
|
||||||
|
[4] return
|
||||||
|
to:@return
|
||||||
|
|
||||||
|
(void()) main()
|
||||||
|
main: scope:[main] from __start::@1
|
||||||
|
[5] (volatile dword) ADDR32 ← (dword) $ff80000
|
||||||
|
asm { ldz#0 !: tza sta((ADDR32)),z inz cpz#80 bne!- }
|
||||||
|
[7] (volatile dword) ADDR32 ← (word) $800
|
||||||
|
asm { lda#'*' ldz#79 !: sta((ADDR32)),z dez bpl!- }
|
||||||
|
to:main::@return
|
||||||
|
main::@return: scope:[main] from main
|
||||||
|
[9] return
|
||||||
|
to:@return
|
421
src/test/ref/examples/mega65/32bit-addressing-mega65.log
Normal file
421
src/test/ref/examples/mega65/32bit-addressing-mega65.log
Normal file
@ -0,0 +1,421 @@
|
|||||||
|
Inlined call call __init
|
||||||
|
|
||||||
|
CONTROL FLOW GRAPH SSA
|
||||||
|
|
||||||
|
(void()) main()
|
||||||
|
main: scope:[main] from __start::@1
|
||||||
|
(volatile dword) ADDR32 ← (number) $ff80000
|
||||||
|
asm { ldz#0 !: tza sta((ADDR32)),z inz cpz#80 bne!- }
|
||||||
|
(volatile dword) ADDR32 ← (number) $800
|
||||||
|
asm { lda#'*' ldz#79 !: sta((ADDR32)),z dez bpl!- }
|
||||||
|
to:main::@return
|
||||||
|
main::@return: scope:[main] from main
|
||||||
|
return
|
||||||
|
to:@return
|
||||||
|
|
||||||
|
(void()) __start()
|
||||||
|
__start: scope:[__start] from
|
||||||
|
to:__start::__init1
|
||||||
|
__start::__init1: scope:[__start] from __start
|
||||||
|
(volatile dword) ADDR32 ← (dword) 0
|
||||||
|
to:__start::@1
|
||||||
|
__start::@1: scope:[__start] from __start::__init1
|
||||||
|
call main
|
||||||
|
to:__start::@2
|
||||||
|
__start::@2: scope:[__start] from __start::@1
|
||||||
|
to:__start::@return
|
||||||
|
__start::@return: scope:[__start] from __start::@2
|
||||||
|
return
|
||||||
|
to:@return
|
||||||
|
|
||||||
|
SYMBOL TABLE SSA
|
||||||
|
(volatile dword) ADDR32 loadstore
|
||||||
|
(void()) __start()
|
||||||
|
(label) __start::@1
|
||||||
|
(label) __start::@2
|
||||||
|
(label) __start::@return
|
||||||
|
(label) __start::__init1
|
||||||
|
(void()) main()
|
||||||
|
(label) main::@return
|
||||||
|
|
||||||
|
Adding number conversion cast (unumber) $ff80000 in (volatile dword) ADDR32 ← (number) $ff80000
|
||||||
|
Adding number conversion cast (unumber) $800 in (volatile dword) ADDR32 ← (number) $800
|
||||||
|
Successful SSA optimization PassNAddNumberTypeConversions
|
||||||
|
Inlining cast (volatile dword) ADDR32 ← (unumber)(number) $ff80000
|
||||||
|
Inlining cast (volatile dword) ADDR32 ← (unumber)(number) $800
|
||||||
|
Successful SSA optimization Pass2InlineCast
|
||||||
|
Simplifying constant integer cast $ff80000
|
||||||
|
Simplifying constant integer cast $800
|
||||||
|
Successful SSA optimization PassNCastSimplification
|
||||||
|
Finalized unsigned number type (dword) $ff80000
|
||||||
|
Finalized unsigned number type (word) $800
|
||||||
|
Successful SSA optimization PassNFinalizeNumberTypeConversions
|
||||||
|
Adding NOP phi() at start of __start
|
||||||
|
Adding NOP phi() at start of __start::@1
|
||||||
|
Adding NOP phi() at start of __start::@2
|
||||||
|
CALL GRAPH
|
||||||
|
Calls in [__start] to main:3
|
||||||
|
|
||||||
|
Created 0 initial phi equivalence classes
|
||||||
|
Coalesced down to 0 phi equivalence classes
|
||||||
|
Culled Empty Block (label) __start::@2
|
||||||
|
Adding NOP phi() at start of __start
|
||||||
|
Adding NOP phi() at start of __start::@1
|
||||||
|
|
||||||
|
FINAL CONTROL FLOW GRAPH
|
||||||
|
|
||||||
|
(void()) __start()
|
||||||
|
__start: scope:[__start] from
|
||||||
|
[0] phi()
|
||||||
|
to:__start::__init1
|
||||||
|
__start::__init1: scope:[__start] from __start
|
||||||
|
[1] (volatile dword) ADDR32 ← (dword) 0
|
||||||
|
to:__start::@1
|
||||||
|
__start::@1: scope:[__start] from __start::__init1
|
||||||
|
[2] phi()
|
||||||
|
[3] call main
|
||||||
|
to:__start::@return
|
||||||
|
__start::@return: scope:[__start] from __start::@1
|
||||||
|
[4] return
|
||||||
|
to:@return
|
||||||
|
|
||||||
|
(void()) main()
|
||||||
|
main: scope:[main] from __start::@1
|
||||||
|
[5] (volatile dword) ADDR32 ← (dword) $ff80000
|
||||||
|
asm { ldz#0 !: tza sta((ADDR32)),z inz cpz#80 bne!- }
|
||||||
|
[7] (volatile dword) ADDR32 ← (word) $800
|
||||||
|
asm { lda#'*' ldz#79 !: sta((ADDR32)),z dez bpl!- }
|
||||||
|
to:main::@return
|
||||||
|
main::@return: scope:[main] from main
|
||||||
|
[9] return
|
||||||
|
to:@return
|
||||||
|
|
||||||
|
|
||||||
|
VARIABLE REGISTER WEIGHTS
|
||||||
|
(volatile dword) ADDR32 loadstore 12.0
|
||||||
|
(void()) __start()
|
||||||
|
(void()) main()
|
||||||
|
|
||||||
|
Initial phi equivalence classes
|
||||||
|
Added variable ADDR32 to live range equivalence class [ ADDR32 ]
|
||||||
|
Complete equivalence classes
|
||||||
|
[ ADDR32 ]
|
||||||
|
Allocated zp[4]:2 [ ADDR32 ]
|
||||||
|
|
||||||
|
INITIAL ASM
|
||||||
|
Target platform is mega65 / MEGA45GS02
|
||||||
|
// File Comments
|
||||||
|
// 32-bit addressing using the new addressing mode
|
||||||
|
// Upstart
|
||||||
|
.cpu _45gs02
|
||||||
|
.file [name="32bit-addressing-mega65.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(__start) // NNNN
|
||||||
|
.byte $00, $00, $00 //
|
||||||
|
// Global Constants & labels
|
||||||
|
// Absolute 32-bit address to use for storing/loading data
|
||||||
|
.label ADDR32 = 2
|
||||||
|
.segment Code
|
||||||
|
// __start
|
||||||
|
__start: {
|
||||||
|
jmp __init1
|
||||||
|
// __start::__init1
|
||||||
|
__init1:
|
||||||
|
// [1] (volatile dword) ADDR32 ← (dword) 0 -- vduz1=vduc1
|
||||||
|
lda #<0
|
||||||
|
sta.z ADDR32
|
||||||
|
lda #>0
|
||||||
|
sta.z ADDR32+1
|
||||||
|
lda #<0>>$10
|
||||||
|
sta.z ADDR32+2
|
||||||
|
lda #>0>>$10
|
||||||
|
sta.z ADDR32+3
|
||||||
|
// [2] phi from __start::__init1 to __start::@1 [phi:__start::__init1->__start::@1]
|
||||||
|
__b1_from___init1:
|
||||||
|
jmp __b1
|
||||||
|
// __start::@1
|
||||||
|
__b1:
|
||||||
|
// [3] call main
|
||||||
|
jsr main
|
||||||
|
jmp __breturn
|
||||||
|
// __start::@return
|
||||||
|
__breturn:
|
||||||
|
// [4] return
|
||||||
|
rts
|
||||||
|
}
|
||||||
|
// main
|
||||||
|
main: {
|
||||||
|
// [5] (volatile dword) ADDR32 ← (dword) $ff80000 -- vduz1=vduc1
|
||||||
|
// Modify Color Ram using 32-bit addressing
|
||||||
|
lda #<$ff80000
|
||||||
|
sta.z ADDR32
|
||||||
|
lda #>$ff80000
|
||||||
|
sta.z ADDR32+1
|
||||||
|
lda #<$ff80000>>$10
|
||||||
|
sta.z ADDR32+2
|
||||||
|
lda #>$ff80000>>$10
|
||||||
|
sta.z ADDR32+3
|
||||||
|
// asm { ldz#0 !: tza sta((ADDR32)),z inz cpz#80 bne!- }
|
||||||
|
ldz #0
|
||||||
|
!:
|
||||||
|
tza
|
||||||
|
sta.z ((ADDR32)),z
|
||||||
|
inz
|
||||||
|
cpz #$50
|
||||||
|
bne !-
|
||||||
|
// [7] (volatile dword) ADDR32 ← (word) $800 -- vduz1=vduc1
|
||||||
|
// Modify Screen using 32-bit addressing
|
||||||
|
lda #<$800
|
||||||
|
sta.z ADDR32
|
||||||
|
lda #>$800
|
||||||
|
sta.z ADDR32+1
|
||||||
|
lda #<$800>>$10
|
||||||
|
sta.z ADDR32+2
|
||||||
|
lda #>$800>>$10
|
||||||
|
sta.z ADDR32+3
|
||||||
|
// asm { lda#'*' ldz#79 !: sta((ADDR32)),z dez bpl!- }
|
||||||
|
lda #'*'
|
||||||
|
ldz #$4f
|
||||||
|
!:
|
||||||
|
sta.z ((ADDR32)),z
|
||||||
|
dez
|
||||||
|
bpl !-
|
||||||
|
jmp __breturn
|
||||||
|
// main::@return
|
||||||
|
__breturn:
|
||||||
|
// [9] return
|
||||||
|
rts
|
||||||
|
}
|
||||||
|
// File Data
|
||||||
|
|
||||||
|
REGISTER UPLIFT POTENTIAL REGISTERS
|
||||||
|
Statement [1] (volatile dword) ADDR32 ← (dword) 0 [ ] ( [ ] { } ) always clobbers reg byte a
|
||||||
|
Statement [5] (volatile dword) ADDR32 ← (dword) $ff80000 [ ADDR32 ] ( main:3 [ ADDR32 ] { } ) always clobbers reg byte a
|
||||||
|
Statement asm { ldz#0 !: tza sta((ADDR32)),z inz cpz#80 bne!- } always clobbers reg byte a reg byte z
|
||||||
|
Statement [7] (volatile dword) ADDR32 ← (word) $800 [ ADDR32 ] ( main:3 [ ADDR32 ] { } ) always clobbers reg byte a
|
||||||
|
Statement asm { lda#'*' ldz#79 !: sta((ADDR32)),z dez bpl!- } always clobbers reg byte a reg byte z
|
||||||
|
Potential registers zp[4]:2 [ ADDR32 ] : zp[4]:2 ,
|
||||||
|
|
||||||
|
REGISTER UPLIFT SCOPES
|
||||||
|
Uplift Scope [] 12: zp[4]:2 [ ADDR32 ]
|
||||||
|
Uplift Scope [main]
|
||||||
|
Uplift Scope [__start]
|
||||||
|
|
||||||
|
Uplifting [] best 148 combination zp[4]:2 [ ADDR32 ]
|
||||||
|
Uplifting [main] best 148 combination
|
||||||
|
Uplifting [__start] best 148 combination
|
||||||
|
|
||||||
|
ASSEMBLER BEFORE OPTIMIZATION
|
||||||
|
// File Comments
|
||||||
|
// 32-bit addressing using the new addressing mode
|
||||||
|
// Upstart
|
||||||
|
.cpu _45gs02
|
||||||
|
.file [name="32bit-addressing-mega65.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(__start) // NNNN
|
||||||
|
.byte $00, $00, $00 //
|
||||||
|
// Global Constants & labels
|
||||||
|
// Absolute 32-bit address to use for storing/loading data
|
||||||
|
.label ADDR32 = 2
|
||||||
|
.segment Code
|
||||||
|
// __start
|
||||||
|
__start: {
|
||||||
|
jmp __init1
|
||||||
|
// __start::__init1
|
||||||
|
__init1:
|
||||||
|
// [1] (volatile dword) ADDR32 ← (dword) 0 -- vduz1=vduc1
|
||||||
|
lda #<0
|
||||||
|
sta.z ADDR32
|
||||||
|
lda #>0
|
||||||
|
sta.z ADDR32+1
|
||||||
|
lda #<0>>$10
|
||||||
|
sta.z ADDR32+2
|
||||||
|
lda #>0>>$10
|
||||||
|
sta.z ADDR32+3
|
||||||
|
// [2] phi from __start::__init1 to __start::@1 [phi:__start::__init1->__start::@1]
|
||||||
|
__b1_from___init1:
|
||||||
|
jmp __b1
|
||||||
|
// __start::@1
|
||||||
|
__b1:
|
||||||
|
// [3] call main
|
||||||
|
jsr main
|
||||||
|
jmp __breturn
|
||||||
|
// __start::@return
|
||||||
|
__breturn:
|
||||||
|
// [4] return
|
||||||
|
rts
|
||||||
|
}
|
||||||
|
// main
|
||||||
|
main: {
|
||||||
|
// [5] (volatile dword) ADDR32 ← (dword) $ff80000 -- vduz1=vduc1
|
||||||
|
// Modify Color Ram using 32-bit addressing
|
||||||
|
lda #<$ff80000
|
||||||
|
sta.z ADDR32
|
||||||
|
lda #>$ff80000
|
||||||
|
sta.z ADDR32+1
|
||||||
|
lda #<$ff80000>>$10
|
||||||
|
sta.z ADDR32+2
|
||||||
|
lda #>$ff80000>>$10
|
||||||
|
sta.z ADDR32+3
|
||||||
|
// asm { ldz#0 !: tza sta((ADDR32)),z inz cpz#80 bne!- }
|
||||||
|
ldz #0
|
||||||
|
!:
|
||||||
|
tza
|
||||||
|
sta.z ((ADDR32)),z
|
||||||
|
inz
|
||||||
|
cpz #$50
|
||||||
|
bne !-
|
||||||
|
// [7] (volatile dword) ADDR32 ← (word) $800 -- vduz1=vduc1
|
||||||
|
// Modify Screen using 32-bit addressing
|
||||||
|
lda #<$800
|
||||||
|
sta.z ADDR32
|
||||||
|
lda #>$800
|
||||||
|
sta.z ADDR32+1
|
||||||
|
lda #<$800>>$10
|
||||||
|
sta.z ADDR32+2
|
||||||
|
lda #>$800>>$10
|
||||||
|
sta.z ADDR32+3
|
||||||
|
// asm { lda#'*' ldz#79 !: sta((ADDR32)),z dez bpl!- }
|
||||||
|
lda #'*'
|
||||||
|
ldz #$4f
|
||||||
|
!:
|
||||||
|
sta.z ((ADDR32)),z
|
||||||
|
dez
|
||||||
|
bpl !-
|
||||||
|
jmp __breturn
|
||||||
|
// main::@return
|
||||||
|
__breturn:
|
||||||
|
// [9] return
|
||||||
|
rts
|
||||||
|
}
|
||||||
|
// File Data
|
||||||
|
|
||||||
|
ASSEMBLER OPTIMIZATIONS
|
||||||
|
Removing instruction jmp __init1
|
||||||
|
Removing instruction jmp __b1
|
||||||
|
Removing instruction jmp __breturn
|
||||||
|
Removing instruction jmp __breturn
|
||||||
|
Succesful ASM optimization Pass5NextJumpElimination
|
||||||
|
Removing instruction lda #>0
|
||||||
|
Succesful ASM optimization Pass5UnnecesaryLoadElimination
|
||||||
|
Removing instruction __b1_from___init1:
|
||||||
|
Succesful ASM optimization Pass5RedundantLabelElimination
|
||||||
|
Removing instruction __init1:
|
||||||
|
Removing instruction __b1:
|
||||||
|
Removing instruction __breturn:
|
||||||
|
Removing instruction __breturn:
|
||||||
|
Succesful ASM optimization Pass5UnusedLabelElimination
|
||||||
|
|
||||||
|
FINAL SYMBOL TABLE
|
||||||
|
(volatile dword) ADDR32 loadstore zp[4]:2 12.0
|
||||||
|
(void()) __start()
|
||||||
|
(label) __start::@1
|
||||||
|
(label) __start::@return
|
||||||
|
(label) __start::__init1
|
||||||
|
(void()) main()
|
||||||
|
(label) main::@return
|
||||||
|
|
||||||
|
zp[4]:2 [ ADDR32 ]
|
||||||
|
|
||||||
|
|
||||||
|
FINAL ASSEMBLER
|
||||||
|
Score: 107
|
||||||
|
|
||||||
|
// File Comments
|
||||||
|
// 32-bit addressing using the new addressing mode
|
||||||
|
// Upstart
|
||||||
|
.cpu _45gs02
|
||||||
|
.file [name="32bit-addressing-mega65.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(__start) // NNNN
|
||||||
|
.byte $00, $00, $00 //
|
||||||
|
// Global Constants & labels
|
||||||
|
// Absolute 32-bit address to use for storing/loading data
|
||||||
|
.label ADDR32 = 2
|
||||||
|
.segment Code
|
||||||
|
// __start
|
||||||
|
__start: {
|
||||||
|
// __start::__init1
|
||||||
|
// ADDR32
|
||||||
|
// [1] (volatile dword) ADDR32 ← (dword) 0 -- vduz1=vduc1
|
||||||
|
lda #<0
|
||||||
|
sta.z ADDR32
|
||||||
|
sta.z ADDR32+1
|
||||||
|
lda #<0>>$10
|
||||||
|
sta.z ADDR32+2
|
||||||
|
lda #>0>>$10
|
||||||
|
sta.z ADDR32+3
|
||||||
|
// [2] phi from __start::__init1 to __start::@1 [phi:__start::__init1->__start::@1]
|
||||||
|
// __start::@1
|
||||||
|
// [3] call main
|
||||||
|
jsr main
|
||||||
|
// __start::@return
|
||||||
|
// [4] return
|
||||||
|
rts
|
||||||
|
}
|
||||||
|
// main
|
||||||
|
main: {
|
||||||
|
// ADDR32 = 0xff80000
|
||||||
|
// [5] (volatile dword) ADDR32 ← (dword) $ff80000 -- vduz1=vduc1
|
||||||
|
// Modify Color Ram using 32-bit addressing
|
||||||
|
lda #<$ff80000
|
||||||
|
sta.z ADDR32
|
||||||
|
lda #>$ff80000
|
||||||
|
sta.z ADDR32+1
|
||||||
|
lda #<$ff80000>>$10
|
||||||
|
sta.z ADDR32+2
|
||||||
|
lda #>$ff80000>>$10
|
||||||
|
sta.z ADDR32+3
|
||||||
|
// asm
|
||||||
|
// asm { ldz#0 !: tza sta((ADDR32)),z inz cpz#80 bne!- }
|
||||||
|
ldz #0
|
||||||
|
!:
|
||||||
|
tza
|
||||||
|
sta.z ((ADDR32)),z
|
||||||
|
inz
|
||||||
|
cpz #$50
|
||||||
|
bne !-
|
||||||
|
// ADDR32 = 0x00000800
|
||||||
|
// [7] (volatile dword) ADDR32 ← (word) $800 -- vduz1=vduc1
|
||||||
|
// Modify Screen using 32-bit addressing
|
||||||
|
lda #<$800
|
||||||
|
sta.z ADDR32
|
||||||
|
lda #>$800
|
||||||
|
sta.z ADDR32+1
|
||||||
|
lda #<$800>>$10
|
||||||
|
sta.z ADDR32+2
|
||||||
|
lda #>$800>>$10
|
||||||
|
sta.z ADDR32+3
|
||||||
|
// asm
|
||||||
|
// asm { lda#'*' ldz#79 !: sta((ADDR32)),z dez bpl!- }
|
||||||
|
lda #'*'
|
||||||
|
ldz #$4f
|
||||||
|
!:
|
||||||
|
sta.z ((ADDR32)),z
|
||||||
|
dez
|
||||||
|
bpl !-
|
||||||
|
// main::@return
|
||||||
|
// }
|
||||||
|
// [9] return
|
||||||
|
rts
|
||||||
|
}
|
||||||
|
// File Data
|
||||||
|
|
9
src/test/ref/examples/mega65/32bit-addressing-mega65.sym
Normal file
9
src/test/ref/examples/mega65/32bit-addressing-mega65.sym
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
(volatile dword) ADDR32 loadstore zp[4]:2 12.0
|
||||||
|
(void()) __start()
|
||||||
|
(label) __start::@1
|
||||||
|
(label) __start::@return
|
||||||
|
(label) __start::__init1
|
||||||
|
(void()) main()
|
||||||
|
(label) main::@return
|
||||||
|
|
||||||
|
zp[4]:2 [ ADDR32 ]
|
@ -1,4 +1,4 @@
|
|||||||
// Hello World for MEGA 65
|
// Hello World for MEGA 65 - putting chars directly to the screen
|
||||||
.cpu _45gs02
|
.cpu _45gs02
|
||||||
.file [name="hello-mega65.prg", type="prg", segments="Program"]
|
.file [name="hello-mega65.prg", type="prg", segments="Program"]
|
||||||
.segmentdef Program [segments="Basic, Code, Data"]
|
.segmentdef Program [segments="Basic, Code, Data"]
|
||||||
|
@ -122,7 +122,7 @@ Allocated zp[1]:2 [ main::i#2 main::i#1 ]
|
|||||||
INITIAL ASM
|
INITIAL ASM
|
||||||
Target platform is mega65 / MEGA45GS02
|
Target platform is mega65 / MEGA45GS02
|
||||||
// File Comments
|
// File Comments
|
||||||
// Hello World for MEGA 65
|
// Hello World for MEGA 65 - putting chars directly to the screen
|
||||||
// Upstart
|
// Upstart
|
||||||
.cpu _45gs02
|
.cpu _45gs02
|
||||||
.file [name="hello-mega65.prg", type="prg", segments="Program"]
|
.file [name="hello-mega65.prg", type="prg", segments="Program"]
|
||||||
@ -201,7 +201,7 @@ Uplifting [] best 391 combination
|
|||||||
|
|
||||||
ASSEMBLER BEFORE OPTIMIZATION
|
ASSEMBLER BEFORE OPTIMIZATION
|
||||||
// File Comments
|
// File Comments
|
||||||
// Hello World for MEGA 65
|
// Hello World for MEGA 65 - putting chars directly to the screen
|
||||||
// Upstart
|
// Upstart
|
||||||
.cpu _45gs02
|
.cpu _45gs02
|
||||||
.file [name="hello-mega65.prg", type="prg", segments="Program"]
|
.file [name="hello-mega65.prg", type="prg", segments="Program"]
|
||||||
@ -284,7 +284,7 @@ FINAL ASSEMBLER
|
|||||||
Score: 331
|
Score: 331
|
||||||
|
|
||||||
// File Comments
|
// File Comments
|
||||||
// Hello World for MEGA 65
|
// Hello World for MEGA 65 - putting chars directly to the screen
|
||||||
// Upstart
|
// Upstart
|
||||||
.cpu _45gs02
|
.cpu _45gs02
|
||||||
.file [name="hello-mega65.prg", type="prg", segments="Program"]
|
.file [name="hello-mega65.prg", type="prg", segments="Program"]
|
||||||
|
Loading…
Reference in New Issue
Block a user