mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-11-25 20:32:25 +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"
|
||||
#elif defined(__VIC20__)
|
||||
#include "conio-vic20.c"
|
||||
#elif defined(__MEGA65__)
|
||||
#include "conio-mega65.c"
|
||||
#elif defined(__NES__)
|
||||
#include "conio-nes.c"
|
||||
#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");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMega65Addressing32bit() throws IOException, URISyntaxException {
|
||||
compileAndCompare("examples/mega65/32bit-addressing-mega65.c");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMega65Hello() throws IOException, URISyntaxException {
|
||||
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)
|
||||
|
||||
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
|
||||
.file [name="hello-mega65.prg", type="prg", segments="Program"]
|
||||
.segmentdef Program [segments="Basic, Code, Data"]
|
||||
|
@ -122,7 +122,7 @@ Allocated zp[1]:2 [ main::i#2 main::i#1 ]
|
||||
INITIAL ASM
|
||||
Target platform is mega65 / MEGA45GS02
|
||||
// File Comments
|
||||
// Hello World for MEGA 65
|
||||
// Hello World for MEGA 65 - putting chars directly to the screen
|
||||
// Upstart
|
||||
.cpu _45gs02
|
||||
.file [name="hello-mega65.prg", type="prg", segments="Program"]
|
||||
@ -201,7 +201,7 @@ Uplifting [] best 391 combination
|
||||
|
||||
ASSEMBLER BEFORE OPTIMIZATION
|
||||
// File Comments
|
||||
// Hello World for MEGA 65
|
||||
// Hello World for MEGA 65 - putting chars directly to the screen
|
||||
// Upstart
|
||||
.cpu _45gs02
|
||||
.file [name="hello-mega65.prg", type="prg", segments="Program"]
|
||||
@ -284,7 +284,7 @@ FINAL ASSEMBLER
|
||||
Score: 331
|
||||
|
||||
// File Comments
|
||||
// Hello World for MEGA 65
|
||||
// Hello World for MEGA 65 - putting chars directly to the screen
|
||||
// Upstart
|
||||
.cpu _45gs02
|
||||
.file [name="hello-mega65.prg", type="prg", segments="Program"]
|
||||
|
Loading…
Reference in New Issue
Block a user