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

Added a VIC 20 target. Added CONIO support for VIC 20.

This commit is contained in:
jespergravgaard 2020-05-16 16:28:24 +02:00
parent 97f49cb93c
commit 557212c847
23 changed files with 1075 additions and 216 deletions

View File

@ -2,7 +2,7 @@
// Implements similar functions as conio.h from CC65 for compatibility
// See https://github.com/cc65/cc65/blob/master/include/conio.h
//
// Currently only the C64 and PLUS4 platform is supported
// Currently C64/PLUS4/VIC20 platforms are supported
// clears the screen and moves the cursor to the upper left-hand corner of the screen.

View File

@ -0,0 +1,39 @@
// MOS 6522 Versatile Interface Adapter (VIA)
// Used in VIC 20 and 1541
// https://en.wikipedia.org/wiki/MOS_Technology_6522
// http://archive.6502.org/datasheets/mos_6522_preliminary_nov_1977.pdf
struct MOS6522_VIA {
// Port B
char PORT_B;
// Port A
char PORT_A;
// Port B data direction register.
char PORT_B_DDR;
// Port A data direction register.
char PORT_A_DDR;
// Timer 1 low byte
char TIMER1_LOW;
// Timer 1 high byte
char TIMER1_HIGH;
// Timer 1 latch low byte
char TIMER1_LATCH_LOW;
// Timer 1 latch high byte
char TIMER1_LATCH_HIGH;
// Timer 2 low byte
char TIMER2_LOW;
// Timer 2 high byte
char TIMER2_HIGH;
// Shift Register
char SHIFT;
// Auxiliary Control Register
char AUX_CONTROL;
// Peripheral Control Register
char PERIPHERAL_CONTROL;
// Interrupt Flag Register
char INTERRUPT_FLAG;
// Interrupt Enable Register
char INTERRUPT_ENABLE;
// Port A Output (no handshake)
char PORT_A_OUTPUT;
};

View File

@ -0,0 +1,64 @@
// MOS 6560/6561 VIDEO INTERFACE CHIP
// Used in VIC 20
// http://archive.6502.org/datasheets/mos_6560_6561_vic.pdf
struct MOS6561_VIC {
// Screen Origin X-coordinate
// bits 0-6: horizontal centering
// bit 7: sets interlace scan
char ORIGIN_X;
// Screen Origin Y-coordinate
// bit 0-7: vertical centering
char ORIGIN_Y;
// Number of Screen Columns
// bits 0-6: Number of columns
// bit 7: Upper bit of video matrix address (also controls address of COLOR RAM)
char MATRIX_COLUMNS;
// Number of Screen Rows
// bits 1-6: set ol rows
// bit 7: sets or 16 chars
char MATRIX_ROWS;
// The Raster Line
// bits 0-7: Current TV raster beam line
char RASTER;
// Character and Screen Address
// bits 0-3: start of character memory (default 0)
// ROM: 0000: 0x8000, 0001: 0x8400, 0010: 0x8800, 0011: 0x8c00
// RAM: 1000: 0x0000, 1001: unavail, 1010: unavail, 1011: unavail
// RAM: 1100: 0x1000, 1101: 0x1400, 1110: 0x1800, 1111: 0x1c00
// bits 4-7: is rest of video matrix address (default F)
char MEMORY;
// Lightpen X position
// bits 0-7: horizontal position of light pen
char LIGHTPEN_X;
// Lightpen Y position
// bits 0-7: vertical position of light pen
char LIGHTPEN_Y;
// Paddle X position
// bit 0-7: Digitized value of paddle X
char PADDLE_X;
// Paddle Y position
// bit 0-7: Digitized value oi paddle Y
char PADDLE_Y;
// Sound Voice 1 (low) frequency
// Frequency for oscillator 1 (low) (on: 128-255)
char CH1_FREQ;
// Sound Voice 2 (medium) frequency
// Frequency for oscillator 1 (medium) (on: 128-255)
char CH2_FREQ;
// Sound Voice 3 (high) frequency
// Frequency for oscillator 1 (high) (on: 128-255)
char CH3_FREQ;
// Sound Voice 4 (noise) frequency
// Frequency of noise source
char CH4_FREQ;
// Sound Volume and auxiliary color information
// bit 0-3: sets volume of all sound
// bits 4-7: are auxiliary color information
char VOLUME_COLOR;
// Screen and border color register
// bits 4-7: background color
// bit 3: inverted or normal mode
// bits 0-2: border color
char BORDER_BACKGROUND_COLOR;
};

View File

@ -0,0 +1,42 @@
// Commodore VIC 20 registers and memory layout
// http://sleepingelephant.com/denial/wiki/index.php?title=Memory_Map
// http://www.zimmers.net/anonftp/pub/cbm/vic20/manuals/VIC-20_Programmers_Reference_Guide_1st_Edition_6th_Printing.pdf
#include <mos6561.h>
#include <mos6522.h>
// Default address of screen color matrix
char * const DEFAULT_COLORRAM = 0x9600;
// Address of screen color matrix if bit 7 of $9002 is 1
char * const ALTERNATIVE_COLORRAM = 0x9400;
// Default address of screen character matrix
char * const DEFAULT_SCREEN = 0x1e00;
// The address of the CHARGEN character set
char * const CHARGEN = 0x8000;
// The MOS 6560/6561 VIC Video Interface Chip
struct MOS6561_VIC * const VIC = 0x9000;
// The VIA#1: User port, RS-232, Joystick, Lightpen, Cassette
struct MOS6522_VIA * const VIA1 = 0x9110;
// The VIA#2: Keyboard, Joystick, Cassette
struct MOS6522_VIA * const VIA2 = 0x9120;
// The colors of the VIC 20
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 LIGHT_ORANGE = 0x9;
const char PINK = 0xa;
const char LIGHT_CYAN= 0xb;
const char LIGHT_PURPLE = 0xc;
const char LIGHT_GREEN = 0xd;
const char LIGHT_BLUE = 0xe;
const char LIGHT_YELLOW = 0xf;

View File

@ -2,7 +2,7 @@
// Implements similar functions as conio.h from CC65 for compatibility
// See https://github.com/cc65/cc65/blob/master/include/conio.h
//
// Currently only the C64/PLUS4 platforms are supported
// Currently C64/PLUS4/VIC20 platforms are supported
#include <conio.h>
#include <string.h>
@ -18,21 +18,35 @@
char * const CONIO_SCREEN_TEXT = 0x0400;
// The color screen address
char * const CONIO_SCREEN_COLORS = 0xd800;
// The background color register address
char * const CONIO_BGCOLOR = 0xd021;
// The border color register address
char * const CONIO_BORDERCOLOR = 0xd020;
// The default text color
const char CONIO_TEXTCOLOR_DEFAULT = 0xe;
// 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 CONIO_CIA1_PORT_A = 0xdc00;
char* const CIA1_PORT_A = 0xdc00;
// CIA#1 Port B: keyboard matrix rows and joystick #1.
char* const CONIO_CIA1_PORT_B = 0xdc01;
*CONIO_CIA1_PORT_A = 0;
return ~*CONIO_CIA1_PORT_B;
char* const CIA1_PORT_B = 0xdc01;
*CIA1_PORT_A = 0;
return ~*CIA1_PORT_B;
}
// 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;
}
#elif defined(__PLUS4__)
@ -50,10 +64,6 @@
char * const CONIO_SCREEN_TEXT = DEFAULT_SCREEN;
// The color screen address
char * const CONIO_SCREEN_COLORS = DEFAULT_COLORRAM;
// The background color register address
char * const CONIO_BGCOLOR = &TED->BG_COLOR;
// The border color register address
char * const CONIO_BORDERCOLOR = &TED->BORDER_COLOR;
// The default text color
const char CONIO_TEXTCOLOR_DEFAULT = 0;
@ -69,6 +79,60 @@
return ~TED->KEYBOARD_INPUT;
}
// Set the color for the background. The old color setting is returned.
unsigned char bgcolor(unsigned char color) {
char old = TED->BG_COLOR;
TED->BG_COLOR = color;
return old;
}
// Set the color for the border. The old color setting is returned.
unsigned char bordercolor(unsigned char color) {
char old = TED->BORDER_COLOR;
TED->BORDER_COLOR = color;
return old;
}
#elif defined(__VIC20__)
#include <vic20.h>
// The screen width
#define CONIO_WIDTH 22
// The screen height
#define CONIO_HEIGHT 23
// The screen bytes
#define CONIO_BYTES CONIO_HEIGHT*CONIO_WIDTH
// The text screen address
char * const CONIO_SCREEN_TEXT = DEFAULT_SCREEN;
// The color screen address
char * const CONIO_SCREEN_COLORS = DEFAULT_COLORRAM;
// The default text color
const char CONIO_TEXTCOLOR_DEFAULT = BLUE;
// Return true if there's a key waiting, return false if not
unsigned char kbhit (void) {
// Read all keyboard matrix rows
VIA2->PORT_B = 0x00;
// Read the keyboard input
return ~VIA2->PORT_A;
}
// Set the color for the background. The old color setting is returned.
unsigned char bgcolor(unsigned char color) {
char old = VIC->BORDER_BACKGROUND_COLOR;
VIC->BORDER_BACKGROUND_COLOR = old&0x0f|(color<<4);
return old>>4;
}
// Set the color for the border. The old color setting is returned.
unsigned char bordercolor(unsigned char color) {
char old = VIC->BORDER_BACKGROUND_COLOR;
VIC->BORDER_BACKGROUND_COLOR = old&0xf8|color;
return old&0x07;
}
#else
// #error "Target platform does not support conio.h"
#endif
@ -240,20 +304,6 @@ unsigned char textcolor(unsigned char color) {
return old;
}
// Set the color for the background. The old color setting is returned.
unsigned char bgcolor(unsigned char color) {
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) {
char old = *CONIO_BORDERCOLOR;
*CONIO_BORDERCOLOR = color;
return old;
}
// If onoff is 1, a cursor is displayed when waiting for keyboard input.
// If onoff is 0, the cursor is hidden when waiting for keyboard input.
// The function returns the old cursor setting.

View File

@ -0,0 +1,9 @@
.file [name="%O.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$1001]
.segmentdef Code [start=$100e]
.segmentdef Data [startAfter="Code"]
.segment Basic
:BasicUpstart(%E)
.segment Code

View File

@ -0,0 +1,8 @@
{
"link": "vic20.ld",
"cpu": "MOS6502X",
"emulator": "xvic",
"defines": {
"__VIC20__": 1
}
}

View File

@ -0,0 +1,3 @@
.pc = $1001 "Basic"
:BasicUpstart(%E)
.pc = %P "Program"

View File

@ -0,0 +1,8 @@
{
"link": "vic20basic.ld",
"cpu": "MOS6502X",
"emulator": "xvic",
"defines": {
"__VIC20__": 1
}
}

View File

@ -44,6 +44,11 @@ public class TestPrograms {
public TestPrograms() {
}
@Test
public void testVic20Simple() throws IOException, URISyntaxException {
compileAndCompare("vic20-simple.c");
}
@Test
public void testPlus4KeyboardTest() throws IOException, URISyntaxException {
compileAndCompare("plus4-keyboard-test.c");

View File

@ -0,0 +1,12 @@
// Trivial VIC 20 program
#pragma target(vic20)
#include <vic20.h>
char MESSAGE[] = "hello world!";
void main() {
for(char i=0; MESSAGE[i]; i++) {
DEFAULT_SCREEN[i] = MESSAGE[i];
DEFAULT_COLORRAM[i] = RED;
}
}

View File

@ -882,14 +882,14 @@ irq_bottom_2: {
// Return true if there's a key waiting, return false if not
kbhit: {
// CIA#1 Port A: keyboard matrix columns and joystick #2
.label CONIO_CIA1_PORT_A = $dc00
.label CIA1_PORT_A = $dc00
// CIA#1 Port B: keyboard matrix rows and joystick #1.
.label CONIO_CIA1_PORT_B = $dc01
// *CONIO_CIA1_PORT_A = 0
.label CIA1_PORT_B = $dc01
// *CIA1_PORT_A = 0
lda #0
sta CONIO_CIA1_PORT_A
// ~*CONIO_CIA1_PORT_B
lda CONIO_CIA1_PORT_B
sta CIA1_PORT_A
// ~*CIA1_PORT_B
lda CIA1_PORT_B
eor #$ff
// }
rts

View File

@ -448,8 +448,8 @@ irq_bottom_2::@1: scope:[irq_bottom_2] from irq_bottom_2::@4
(byte()) kbhit()
kbhit: scope:[kbhit] from irq_bottom_2
[219] *((const nomodify byte*) kbhit::CONIO_CIA1_PORT_A) ← (byte) 0
[220] (byte) kbhit::return#0 ← ~ *((const nomodify byte*) kbhit::CONIO_CIA1_PORT_B)
[219] *((const nomodify byte*) kbhit::CIA1_PORT_A) ← (byte) 0
[220] (byte) kbhit::return#0 ← ~ *((const nomodify byte*) kbhit::CIA1_PORT_B)
to:kbhit::@return
kbhit::@return: scope:[kbhit] from kbhit
[221] return

View File

@ -88,11 +88,11 @@ clock_start: scope:[clock_start] from main::@8
clock_start::@return: scope:[clock_start] from clock_start
return
to:@return
$$
(byte()) kbhit()
kbhit: scope:[kbhit] from irq_bottom_2
*((const nomodify byte*) kbhit::CONIO_CIA1_PORT_A) ← (number) 0
(byte~) kbhit::$0 ← ~ *((const nomodify byte*) kbhit::CONIO_CIA1_PORT_B)
*((const nomodify byte*) kbhit::CIA1_PORT_A) ← (number) 0
(byte~) kbhit::$0 ← ~ *((const nomodify byte*) kbhit::CIA1_PORT_B)
(byte) kbhit::return#0 ← (byte~) kbhit::$0
to:kbhit::@return
kbhit::@return: scope:[kbhit] from kbhit
@ -1321,8 +1321,8 @@ interrupt(KERNEL_KEYBOARD)(void()) irq_bottom_2()
(byte()) kbhit()
(byte~) kbhit::$0
(label) kbhit::@return
(const nomodify byte*) kbhit::CONIO_CIA1_PORT_A = (byte*)(number) $dc00
(const nomodify byte*) kbhit::CONIO_CIA1_PORT_B = (byte*)(number) $dc01
(const nomodify byte*) kbhit::CIA1_PORT_A = (byte*)(number) $dc00
(const nomodify byte*) kbhit::CIA1_PORT_B = (byte*)(number) $dc01
(byte) kbhit::return
(byte) kbhit::return#0
(byte) kbhit::return#1
@ -2073,7 +2073,7 @@ Adding number conversion cast (unumber) 0 in (bool~) memset::$0 ← (word) memse
Adding number conversion cast (unumber) $ffffffff in (number~) clock::$0 ← (number) $ffffffff - *((const nomodify dword*) CIA2_TIMER_AB)
Adding number conversion cast (unumber) clock::$0 in (number~) clock::$0 ← (unumber)(number) $ffffffff - *((const nomodify dword*) CIA2_TIMER_AB)
Adding number conversion cast (unumber) $ffffffff in *((const nomodify dword*) CIA2_TIMER_AB) ← (number) $ffffffff
Adding number conversion cast (unumber) 0 in *((const nomodify byte*) kbhit::CONIO_CIA1_PORT_A) ← (number) 0
Adding number conversion cast (unumber) 0 in *((const nomodify byte*) kbhit::CIA1_PORT_A) ← (number) 0
Adding number conversion cast (unumber) $3fff in (number~) toD0181_$0 ← (word~) toD0181_$7 & (number) $3fff
Adding number conversion cast (unumber) toD0181_$0 in (number~) toD0181_$0 ← (word~) toD0181_$7 & (unumber)(number) $3fff
Adding number conversion cast (unumber) 4 in (number~) toD0181_$1 ← (unumber~) toD0181_$0 * (number) 4
@ -2205,7 +2205,7 @@ Adding number conversion cast (unumber) 1 in (byte) sgn_u8::return#3 ← (number
Successful SSA optimization PassNAddNumberTypeConversions
Inlining cast (byte*) memset::dst#0 ← (byte*)(void*) memset::str#5
Inlining cast *((const nomodify dword*) CIA2_TIMER_AB) ← (unumber)(number) $ffffffff
Inlining cast *((const nomodify byte*) kbhit::CONIO_CIA1_PORT_A) ← (unumber)(number) 0
Inlining cast *((const nomodify byte*) kbhit::CIA1_PORT_A) ← (unumber)(number) 0
Inlining cast (word) memset::num#0 ← (unumber)(number) $28*(number) $19
Inlining cast (byte) memset::c#1 ← (unumber)(number) 0
Inlining cast (word) memset::num#1 ← (unumber)(number) $28*(number) $19
@ -3608,8 +3608,8 @@ irq_bottom_2::@1: scope:[irq_bottom_2] from irq_bottom_2::@4
(byte()) kbhit()
kbhit: scope:[kbhit] from irq_bottom_2
[219] *((const nomodify byte*) kbhit::CONIO_CIA1_PORT_A) ← (byte) 0
[220] (byte) kbhit::return#0 ← ~ *((const nomodify byte*) kbhit::CONIO_CIA1_PORT_B)
[219] *((const nomodify byte*) kbhit::CIA1_PORT_A) ← (byte) 0
[220] (byte) kbhit::return#0 ← ~ *((const nomodify byte*) kbhit::CIA1_PORT_B)
to:kbhit::@return
kbhit::@return: scope:[kbhit] from kbhit
[221] return
@ -5638,16 +5638,16 @@ irq_bottom_2: {
// Return true if there's a key waiting, return false if not
kbhit: {
// CIA#1 Port A: keyboard matrix columns and joystick #2
.label CONIO_CIA1_PORT_A = $dc00
.label CIA1_PORT_A = $dc00
// CIA#1 Port B: keyboard matrix rows and joystick #1.
.label CONIO_CIA1_PORT_B = $dc01
.label CIA1_PORT_B = $dc01
.label return = $5d
.label return_1 = $5b
// [219] *((const nomodify byte*) kbhit::CONIO_CIA1_PORT_A) ← (byte) 0 -- _deref_pbuc1=vbuc2
// [219] *((const nomodify byte*) kbhit::CIA1_PORT_A) ← (byte) 0 -- _deref_pbuc1=vbuc2
lda #0
sta CONIO_CIA1_PORT_A
// [220] (byte) kbhit::return#0 ← ~ *((const nomodify byte*) kbhit::CONIO_CIA1_PORT_B) -- vbuz1=_bnot__deref_pbuc1
lda CONIO_CIA1_PORT_B
sta CIA1_PORT_A
// [220] (byte) kbhit::return#0 ← ~ *((const nomodify byte*) kbhit::CIA1_PORT_B) -- vbuz1=_bnot__deref_pbuc1
lda CIA1_PORT_B
eor #$ff
sta.z return
jmp __breturn
@ -5853,8 +5853,8 @@ Statement [214] *((byte*)(const nomodify struct MOS6569_VICII*) VICII+(const byt
Statement [215] *((byte*)(const nomodify struct MOS6569_VICII*) VICII+(const byte) OFFSET_STRUCT_MOS6569_VICII_RASTER) ← (const nomodify byte) BORDER_YPOS_BOTTOM-(byte) 8 [ ] ( [ ] { } ) always clobbers reg byte a
Statement [216] *((const nomodify void()**) KERNEL_IRQ) ← &interrupt(KERNEL_MIN)(void()) irq_bottom_1() [ ] ( [ ] { } ) always clobbers reg byte a
Statement [218] *((byte*)(const nomodify struct MOS6569_VICII*) VICII+(const byte) OFFSET_STRUCT_MOS6569_VICII_MEMORY) ← (volatile byte) canvas_show_memory [ ] ( [ ] { } ) always clobbers reg byte a
Statement [219] *((const nomodify byte*) kbhit::CONIO_CIA1_PORT_A) ← (byte) 0 [ ] ( kbhit:207 [ canvas_show_memory ] { { kbhit::return#0 = kbhit::return#2 } } ) always clobbers reg byte a
Statement [220] (byte) kbhit::return#0 ← ~ *((const nomodify byte*) kbhit::CONIO_CIA1_PORT_B) [ kbhit::return#0 ] ( kbhit:207 [ canvas_show_memory kbhit::return#0 ] { { kbhit::return#0 = kbhit::return#2 } } ) always clobbers reg byte a
Statement [219] *((const nomodify byte*) kbhit::CIA1_PORT_A) ← (byte) 0 [ ] ( kbhit:207 [ canvas_show_memory ] { { kbhit::return#0 = kbhit::return#2 } } ) always clobbers reg byte a
Statement [220] (byte) kbhit::return#0 ← ~ *((const nomodify byte*) kbhit::CIA1_PORT_B) [ kbhit::return#0 ] ( kbhit:207 [ canvas_show_memory kbhit::return#0 ] { { kbhit::return#0 = kbhit::return#2 } } ) always clobbers reg byte a
Statement [222] *((byte*)(const nomodify struct MOS6569_VICII*) VICII+(const byte) OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) ← (const nomodify byte) DARK_GREY [ ] ( [ ] { } ) always clobbers reg byte a
Statement [224] *((byte*)(const nomodify struct MOS6569_VICII*) VICII+(const byte) OFFSET_STRUCT_MOS6569_VICII_MEMORY) ← (const byte) irq_bottom_1::toD0181_return#0 [ ] ( [ ] { } ) always clobbers reg byte a
Statement [225] *((byte*)(const nomodify struct MOS6569_VICII*) VICII+(const byte) OFFSET_STRUCT_MOS6569_VICII_IRQ_STATUS) ← (const nomodify byte) IRQ_RASTER [ ] ( [ ] { } ) always clobbers reg byte a
@ -5955,8 +5955,8 @@ Statement [214] *((byte*)(const nomodify struct MOS6569_VICII*) VICII+(const byt
Statement [215] *((byte*)(const nomodify struct MOS6569_VICII*) VICII+(const byte) OFFSET_STRUCT_MOS6569_VICII_RASTER) ← (const nomodify byte) BORDER_YPOS_BOTTOM-(byte) 8 [ ] ( [ ] { } ) always clobbers reg byte a
Statement [216] *((const nomodify void()**) KERNEL_IRQ) ← &interrupt(KERNEL_MIN)(void()) irq_bottom_1() [ ] ( [ ] { } ) always clobbers reg byte a
Statement [218] *((byte*)(const nomodify struct MOS6569_VICII*) VICII+(const byte) OFFSET_STRUCT_MOS6569_VICII_MEMORY) ← (volatile byte) canvas_show_memory [ ] ( [ ] { } ) always clobbers reg byte a
Statement [219] *((const nomodify byte*) kbhit::CONIO_CIA1_PORT_A) ← (byte) 0 [ ] ( kbhit:207 [ canvas_show_memory ] { { kbhit::return#0 = kbhit::return#2 } } ) always clobbers reg byte a
Statement [220] (byte) kbhit::return#0 ← ~ *((const nomodify byte*) kbhit::CONIO_CIA1_PORT_B) [ kbhit::return#0 ] ( kbhit:207 [ canvas_show_memory kbhit::return#0 ] { { kbhit::return#0 = kbhit::return#2 } } ) always clobbers reg byte a
Statement [219] *((const nomodify byte*) kbhit::CIA1_PORT_A) ← (byte) 0 [ ] ( kbhit:207 [ canvas_show_memory ] { { kbhit::return#0 = kbhit::return#2 } } ) always clobbers reg byte a
Statement [220] (byte) kbhit::return#0 ← ~ *((const nomodify byte*) kbhit::CIA1_PORT_B) [ kbhit::return#0 ] ( kbhit:207 [ canvas_show_memory kbhit::return#0 ] { { kbhit::return#0 = kbhit::return#2 } } ) always clobbers reg byte a
Statement [222] *((byte*)(const nomodify struct MOS6569_VICII*) VICII+(const byte) OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) ← (const nomodify byte) DARK_GREY [ ] ( [ ] { } ) always clobbers reg byte a
Statement [224] *((byte*)(const nomodify struct MOS6569_VICII*) VICII+(const byte) OFFSET_STRUCT_MOS6569_VICII_MEMORY) ← (const byte) irq_bottom_1::toD0181_return#0 [ ] ( [ ] { } ) always clobbers reg byte a
Statement [225] *((byte*)(const nomodify struct MOS6569_VICII*) VICII+(const byte) OFFSET_STRUCT_MOS6569_VICII_IRQ_STATUS) ← (const nomodify byte) IRQ_RASTER [ ] ( [ ] { } ) always clobbers reg byte a
@ -7524,14 +7524,14 @@ irq_bottom_2: {
// Return true if there's a key waiting, return false if not
kbhit: {
// CIA#1 Port A: keyboard matrix columns and joystick #2
.label CONIO_CIA1_PORT_A = $dc00
.label CIA1_PORT_A = $dc00
// CIA#1 Port B: keyboard matrix rows and joystick #1.
.label CONIO_CIA1_PORT_B = $dc01
// [219] *((const nomodify byte*) kbhit::CONIO_CIA1_PORT_A) ← (byte) 0 -- _deref_pbuc1=vbuc2
.label CIA1_PORT_B = $dc01
// [219] *((const nomodify byte*) kbhit::CIA1_PORT_A) ← (byte) 0 -- _deref_pbuc1=vbuc2
lda #0
sta CONIO_CIA1_PORT_A
// [220] (byte) kbhit::return#0 ← ~ *((const nomodify byte*) kbhit::CONIO_CIA1_PORT_B) -- vbuaa=_bnot__deref_pbuc1
lda CONIO_CIA1_PORT_B
sta CIA1_PORT_A
// [220] (byte) kbhit::return#0 ← ~ *((const nomodify byte*) kbhit::CIA1_PORT_B) -- vbuaa=_bnot__deref_pbuc1
lda CIA1_PORT_B
eor #$ff
jmp __breturn
// kbhit::@return
@ -8017,8 +8017,8 @@ interrupt(KERNEL_KEYBOARD)(void()) irq_bottom_2()
(byte*) irq_bottom_2::toD0181_screen
(byte()) kbhit()
(label) kbhit::@return
(const nomodify byte*) kbhit::CONIO_CIA1_PORT_A = (byte*) 56320
(const nomodify byte*) kbhit::CONIO_CIA1_PORT_B = (byte*) 56321
(const nomodify byte*) kbhit::CIA1_PORT_A = (byte*) 56320
(const nomodify byte*) kbhit::CIA1_PORT_B = (byte*) 56321
(byte) kbhit::return
(byte) kbhit::return#0 reg byte a 4.333333333333333
(byte) kbhit::return#2 reg byte a 4.0
@ -9648,16 +9648,16 @@ irq_bottom_2: {
// Return true if there's a key waiting, return false if not
kbhit: {
// CIA#1 Port A: keyboard matrix columns and joystick #2
.label CONIO_CIA1_PORT_A = $dc00
.label CIA1_PORT_A = $dc00
// CIA#1 Port B: keyboard matrix rows and joystick #1.
.label CONIO_CIA1_PORT_B = $dc01
// *CONIO_CIA1_PORT_A = 0
// [219] *((const nomodify byte*) kbhit::CONIO_CIA1_PORT_A) ← (byte) 0 -- _deref_pbuc1=vbuc2
.label CIA1_PORT_B = $dc01
// *CIA1_PORT_A = 0
// [219] *((const nomodify byte*) kbhit::CIA1_PORT_A) ← (byte) 0 -- _deref_pbuc1=vbuc2
lda #0
sta CONIO_CIA1_PORT_A
// ~*CONIO_CIA1_PORT_B
// [220] (byte) kbhit::return#0 ← ~ *((const nomodify byte*) kbhit::CONIO_CIA1_PORT_B) -- vbuaa=_bnot__deref_pbuc1
lda CONIO_CIA1_PORT_B
sta CIA1_PORT_A
// ~*CIA1_PORT_B
// [220] (byte) kbhit::return#0 ← ~ *((const nomodify byte*) kbhit::CIA1_PORT_B) -- vbuaa=_bnot__deref_pbuc1
lda CIA1_PORT_B
eor #$ff
// kbhit::@return
// }

View File

@ -192,8 +192,8 @@ interrupt(KERNEL_KEYBOARD)(void()) irq_bottom_2()
(byte*) irq_bottom_2::toD0181_screen
(byte()) kbhit()
(label) kbhit::@return
(const nomodify byte*) kbhit::CONIO_CIA1_PORT_A = (byte*) 56320
(const nomodify byte*) kbhit::CONIO_CIA1_PORT_B = (byte*) 56321
(const nomodify byte*) kbhit::CIA1_PORT_A = (byte*) 56320
(const nomodify byte*) kbhit::CIA1_PORT_B = (byte*) 56321
(byte) kbhit::return
(byte) kbhit::return#0 reg byte a 4.333333333333333
(byte) kbhit::return#2 reg byte a 4.0

View File

@ -31,10 +31,6 @@
.label CONIO_SCREEN_TEXT = $400
// The color screen address
.label CONIO_SCREEN_COLORS = $d800
// The background color register address
.label CONIO_BGCOLOR = $d021
// The border color register address
.label CONIO_BORDERCOLOR = $d020
.label VIC_MEMORY = $d018
.label conio_cursor_x = 9
.label conio_cursor_y = $a
@ -172,14 +168,14 @@ clrscr: {
// Return true if there's a key waiting, return false if not
kbhit: {
// CIA#1 Port A: keyboard matrix columns and joystick #2
.label CONIO_CIA1_PORT_A = $dc00
.label CIA1_PORT_A = $dc00
// CIA#1 Port B: keyboard matrix rows and joystick #1.
.label CONIO_CIA1_PORT_B = $dc01
// *CONIO_CIA1_PORT_A = 0
.label CIA1_PORT_B = $dc01
// *CIA1_PORT_A = 0
lda #0
sta CONIO_CIA1_PORT_A
// ~*CONIO_CIA1_PORT_B
lda CONIO_CIA1_PORT_B
sta CIA1_PORT_A
// ~*CIA1_PORT_B
lda CIA1_PORT_B
eor #$ff
// }
rts
@ -839,6 +835,8 @@ cursor: {
}
// Set the color for the background. The old color setting is returned.
bgcolor: {
// The background color register address
.label CONIO_BGCOLOR = $d021
// *CONIO_BGCOLOR = color
lda #COLOR_BLACK
sta CONIO_BGCOLOR
@ -847,6 +845,8 @@ bgcolor: {
}
// Set the color for the border. The old color setting is returned.
bordercolor: {
// The border color register address
.label CONIO_BORDERCOLOR = $d020
// *CONIO_BORDERCOLOR = color
lda #COLOR_BLACK
sta CONIO_BORDERCOLOR

View File

@ -82,8 +82,8 @@ clrscr::@4: scope:[clrscr] from clrscr::@3
(byte()) kbhit()
kbhit: scope:[kbhit] from main::@1
[40] *((const nomodify byte*) kbhit::CONIO_CIA1_PORT_A) ← (byte) 0
[41] (byte) kbhit::return#0 ← ~ *((const nomodify byte*) kbhit::CONIO_CIA1_PORT_B)
[40] *((const nomodify byte*) kbhit::CIA1_PORT_A) ← (byte) 0
[41] (byte) kbhit::return#0 ← ~ *((const nomodify byte*) kbhit::CIA1_PORT_B)
to:kbhit::@return
kbhit::@return: scope:[kbhit] from kbhit
[42] return
@ -491,7 +491,7 @@ cursor::@return: scope:[cursor] from cursor
(byte()) bgcolor((byte) bgcolor::color)
bgcolor: scope:[bgcolor] from MakeNiceScreen::@5
[230] *((const nomodify byte*) CONIO_BGCOLOR) ← (const nomodify byte) COLOR_BLACK
[230] *((const nomodify byte*) bgcolor::CONIO_BGCOLOR) ← (const nomodify byte) COLOR_BLACK
to:bgcolor::@return
bgcolor::@return: scope:[bgcolor] from bgcolor
[231] return
@ -499,7 +499,7 @@ bgcolor::@return: scope:[bgcolor] from bgcolor
(byte()) bordercolor((byte) bordercolor::color)
bordercolor: scope:[bordercolor] from MakeNiceScreen::@4
[232] *((const nomodify byte*) CONIO_BORDERCOLOR) ← (const nomodify byte) COLOR_BLACK
[232] *((const nomodify byte*) bordercolor::CONIO_BORDERCOLOR) ← (const nomodify byte) COLOR_BLACK
to:bordercolor::@return
bordercolor::@return: scope:[bordercolor] from bordercolor
[233] return

File diff suppressed because one or more lines are too long

View File

@ -15,8 +15,6 @@
(const nomodify byte) CH_VLINE = (byte) $5d
(const nomodify byte) COLOR_BLACK = (byte) 0
(const nomodify byte) COLOR_GRAY3 = (byte) $f
(const nomodify byte*) CONIO_BGCOLOR = (byte*) 53281
(const nomodify byte*) CONIO_BORDERCOLOR = (byte*) 53280
(const nomodify byte*) CONIO_SCREEN_COLORS = (byte*) 55296
(const nomodify byte*) CONIO_SCREEN_TEXT = (byte*) 1024
(const nomodify byte) CONIO_TEXTCOLOR_DEFAULT = (byte) $e
@ -64,11 +62,13 @@
(volatile byte) YSize loadstore zp[1]:18 20.0
(byte()) bgcolor((byte) bgcolor::color)
(label) bgcolor::@return
(const nomodify byte*) bgcolor::CONIO_BGCOLOR = (byte*) 53281
(byte) bgcolor::color
(byte) bgcolor::old
(byte) bgcolor::return
(byte()) bordercolor((byte) bordercolor::color)
(label) bordercolor::@return
(const nomodify byte*) bordercolor::CONIO_BORDERCOLOR = (byte*) 53280
(byte) bordercolor::color
(byte) bordercolor::old
(byte) bordercolor::return
@ -222,8 +222,8 @@
(byte) gotoxy::y#7 reg byte a 3.3333333333666668E10
(byte()) kbhit()
(label) kbhit::@return
(const nomodify byte*) kbhit::CONIO_CIA1_PORT_A = (byte*) 56320
(const nomodify byte*) kbhit::CONIO_CIA1_PORT_B = (byte*) 56321
(const nomodify byte*) kbhit::CIA1_PORT_A = (byte*) 56320
(const nomodify byte*) kbhit::CIA1_PORT_B = (byte*) 56321
(byte) kbhit::return
(byte) kbhit::return#0 reg byte a 367.33333333333337
(byte) kbhit::return#2 reg byte a 202.0

View File

@ -0,0 +1,40 @@
// Trivial VIC 20 program
.file [name="vic20-simple.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$1001]
.segmentdef Code [start=$100e]
.segmentdef Data [startAfter="Code"]
.segment Basic
:BasicUpstart(main)
.segment Code
.const RED = 2
// Default address of screen color matrix
.label DEFAULT_COLORRAM = $9600
// Default address of screen character matrix
.label DEFAULT_SCREEN = $1e00
.segment Code
main: {
ldx #0
__b1:
// for(char i=0; MESSAGE[i]; i++)
lda MESSAGE,x
cmp #0
bne __b2
// }
rts
__b2:
// DEFAULT_SCREEN[i] = MESSAGE[i]
lda MESSAGE,x
sta DEFAULT_SCREEN,x
// DEFAULT_COLORRAM[i] = RED
lda #RED
sta DEFAULT_COLORRAM,x
// for(char i=0; MESSAGE[i]; i++)
inx
jmp __b1
}
.segment Data
MESSAGE: .text "hello world!"
.byte 0

View File

@ -0,0 +1,26 @@
@begin: scope:[] from
[0] phi()
to:@1
@1: scope:[] from @begin
[1] phi()
[2] call main
to:@end
@end: scope:[] from @1
[3] phi()
(void()) main()
main: scope:[main] from @1
[4] phi()
to:main::@1
main::@1: scope:[main] from main main::@2
[5] (byte) main::i#2 ← phi( main/(byte) 0 main::@2/(byte) main::i#1 )
[6] if((byte) 0!=*((const byte*) MESSAGE + (byte) main::i#2)) goto main::@2
to:main::@return
main::@return: scope:[main] from main::@1
[7] return
to:@return
main::@2: scope:[main] from main::@1
[8] *((const nomodify byte*) DEFAULT_SCREEN + (byte) main::i#2) ← *((const byte*) MESSAGE + (byte) main::i#2)
[9] *((const nomodify byte*) DEFAULT_COLORRAM + (byte) main::i#2) ← (const nomodify byte) RED
[10] (byte) main::i#1 ← ++ (byte) main::i#2
to:main::@1

View File

@ -0,0 +1,505 @@
CONTROL FLOW GRAPH SSA
@begin: scope:[] from
to:@1
(void()) main()
main: scope:[main] from @1
(byte) main::i#0 ← (byte) 0
to:main::@1
main::@1: scope:[main] from main main::@2
(byte) main::i#2 ← phi( main/(byte) main::i#0 main::@2/(byte) main::i#1 )
(bool~) main::$0 ← (number) 0 != *((const byte*) MESSAGE + (byte) main::i#2)
if((bool~) main::$0) goto main::@2
to:main::@return
main::@2: scope:[main] from main::@1
(byte) main::i#3 ← phi( main::@1/(byte) main::i#2 )
*((const nomodify byte*) DEFAULT_SCREEN + (byte) main::i#3) ← *((const byte*) MESSAGE + (byte) main::i#3)
*((const nomodify byte*) DEFAULT_COLORRAM + (byte) main::i#3) ← (const nomodify byte) RED
(byte) main::i#1 ← ++ (byte) main::i#3
to:main::@1
main::@return: scope:[main] from main::@1
return
to:@return
@1: scope:[] from @begin
call main
to:@2
@2: scope:[] from @1
to:@end
@end: scope:[] from @2
SYMBOL TABLE SSA
(label) @1
(label) @2
(label) @begin
(label) @end
(const nomodify byte*) DEFAULT_COLORRAM = (byte*)(number) $9600
(const nomodify byte*) DEFAULT_SCREEN = (byte*)(number) $1e00
(const byte*) MESSAGE[] = (byte*) "hello world!"
(byte) MOS6522_VIA::AUX_CONTROL
(byte) MOS6522_VIA::INTERRUPT_ENABLE
(byte) MOS6522_VIA::INTERRUPT_FLAG
(byte) MOS6522_VIA::PERIPHERAL_CONTROL
(byte) MOS6522_VIA::PORT_A
(byte) MOS6522_VIA::PORT_A_DDR
(byte) MOS6522_VIA::PORT_A_OUTPUT
(byte) MOS6522_VIA::PORT_B
(byte) MOS6522_VIA::PORT_B_DDR
(byte) MOS6522_VIA::SHIFT
(byte) MOS6522_VIA::TIMER1_HIGH
(byte) MOS6522_VIA::TIMER1_LATCH_HIGH
(byte) MOS6522_VIA::TIMER1_LATCH_LOW
(byte) MOS6522_VIA::TIMER1_LOW
(byte) MOS6522_VIA::TIMER2_HIGH
(byte) MOS6522_VIA::TIMER2_LOW
(byte) MOS6561_VIC::BORDER_BACKGROUND_COLOR
(byte) MOS6561_VIC::CH1_FREQ
(byte) MOS6561_VIC::CH2_FREQ
(byte) MOS6561_VIC::CH3_FREQ
(byte) MOS6561_VIC::CH4_FREQ
(byte) MOS6561_VIC::LIGHTPEN_X
(byte) MOS6561_VIC::LIGHTPEN_Y
(byte) MOS6561_VIC::MATRIX_COLUMNS
(byte) MOS6561_VIC::MATRIX_ROWS
(byte) MOS6561_VIC::MEMORY
(byte) MOS6561_VIC::ORIGIN_X
(byte) MOS6561_VIC::ORIGIN_Y
(byte) MOS6561_VIC::PADDLE_X
(byte) MOS6561_VIC::PADDLE_Y
(byte) MOS6561_VIC::RASTER
(byte) MOS6561_VIC::VOLUME_COLOR
(const nomodify byte) RED = (byte) 2
(void()) main()
(bool~) main::$0
(label) main::@1
(label) main::@2
(label) main::@return
(byte) main::i
(byte) main::i#0
(byte) main::i#1
(byte) main::i#2
(byte) main::i#3
Adding number conversion cast (unumber) 0 in (bool~) main::$0 ← (number) 0 != *((const byte*) MESSAGE + (byte) main::i#2)
Successful SSA optimization PassNAddNumberTypeConversions
Simplifying constant pointer cast (byte*) 38400
Simplifying constant pointer cast (byte*) 7680
Simplifying constant integer cast 0
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (byte) 0
Successful SSA optimization PassNFinalizeNumberTypeConversions
Alias main::i#2 = main::i#3
Successful SSA optimization Pass2AliasElimination
Simple Condition (bool~) main::$0 [3] if((byte) 0!=*((const byte*) MESSAGE + (byte) main::i#2)) goto main::@2
Successful SSA optimization Pass2ConditionalJumpSimplification
Constant (const byte) main::i#0 = 0
Successful SSA optimization Pass2ConstantIdentification
Inlining constant with var siblings (const byte) main::i#0
Constant inlined main::i#0 = (byte) 0
Successful SSA optimization Pass2ConstantInlining
Adding NOP phi() at start of @begin
Adding NOP phi() at start of @1
Adding NOP phi() at start of @2
Adding NOP phi() at start of @end
Adding NOP phi() at start of main
CALL GRAPH
Calls in [] to main:2
Created 1 initial phi equivalence classes
Coalesced [12] main::i#4 ← main::i#1
Coalesced down to 1 phi equivalence classes
Culled Empty Block (label) @2
Adding NOP phi() at start of @begin
Adding NOP phi() at start of @1
Adding NOP phi() at start of @end
Adding NOP phi() at start of main
FINAL CONTROL FLOW GRAPH
@begin: scope:[] from
[0] phi()
to:@1
@1: scope:[] from @begin
[1] phi()
[2] call main
to:@end
@end: scope:[] from @1
[3] phi()
(void()) main()
main: scope:[main] from @1
[4] phi()
to:main::@1
main::@1: scope:[main] from main main::@2
[5] (byte) main::i#2 ← phi( main/(byte) 0 main::@2/(byte) main::i#1 )
[6] if((byte) 0!=*((const byte*) MESSAGE + (byte) main::i#2)) goto main::@2
to:main::@return
main::@return: scope:[main] from main::@1
[7] return
to:@return
main::@2: scope:[main] from main::@1
[8] *((const nomodify byte*) DEFAULT_SCREEN + (byte) main::i#2) ← *((const byte*) MESSAGE + (byte) main::i#2)
[9] *((const nomodify byte*) DEFAULT_COLORRAM + (byte) main::i#2) ← (const nomodify byte) RED
[10] (byte) main::i#1 ← ++ (byte) main::i#2
to:main::@1
VARIABLE REGISTER WEIGHTS
(byte) MOS6522_VIA::AUX_CONTROL
(byte) MOS6522_VIA::INTERRUPT_ENABLE
(byte) MOS6522_VIA::INTERRUPT_FLAG
(byte) MOS6522_VIA::PERIPHERAL_CONTROL
(byte) MOS6522_VIA::PORT_A
(byte) MOS6522_VIA::PORT_A_DDR
(byte) MOS6522_VIA::PORT_A_OUTPUT
(byte) MOS6522_VIA::PORT_B
(byte) MOS6522_VIA::PORT_B_DDR
(byte) MOS6522_VIA::SHIFT
(byte) MOS6522_VIA::TIMER1_HIGH
(byte) MOS6522_VIA::TIMER1_LATCH_HIGH
(byte) MOS6522_VIA::TIMER1_LATCH_LOW
(byte) MOS6522_VIA::TIMER1_LOW
(byte) MOS6522_VIA::TIMER2_HIGH
(byte) MOS6522_VIA::TIMER2_LOW
(byte) MOS6561_VIC::BORDER_BACKGROUND_COLOR
(byte) MOS6561_VIC::CH1_FREQ
(byte) MOS6561_VIC::CH2_FREQ
(byte) MOS6561_VIC::CH3_FREQ
(byte) MOS6561_VIC::CH4_FREQ
(byte) MOS6561_VIC::LIGHTPEN_X
(byte) MOS6561_VIC::LIGHTPEN_Y
(byte) MOS6561_VIC::MATRIX_COLUMNS
(byte) MOS6561_VIC::MATRIX_ROWS
(byte) MOS6561_VIC::MEMORY
(byte) MOS6561_VIC::ORIGIN_X
(byte) MOS6561_VIC::ORIGIN_Y
(byte) MOS6561_VIC::PADDLE_X
(byte) MOS6561_VIC::PADDLE_Y
(byte) MOS6561_VIC::RASTER
(byte) MOS6561_VIC::VOLUME_COLOR
(void()) main()
(byte) main::i
(byte) main::i#1 202.0
(byte) main::i#2 151.5
Initial phi equivalence classes
[ main::i#2 main::i#1 ]
Complete equivalence classes
[ main::i#2 main::i#1 ]
Allocated zp[1]:2 [ main::i#2 main::i#1 ]
INITIAL ASM
Target platform is vic20 / MOS6502X
// File Comments
// Trivial VIC 20 program
// Upstart
.file [name="vic20-simple.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$1001]
.segmentdef Code [start=$100e]
.segmentdef Data [startAfter="Code"]
.segment Basic
:BasicUpstart(main)
.segment Code
// Global Constants & labels
.const RED = 2
// Default address of screen color matrix
.label DEFAULT_COLORRAM = $9600
// Default address of screen character matrix
.label DEFAULT_SCREEN = $1e00
// @begin
__bbegin:
// [1] phi from @begin to @1 [phi:@begin->@1]
__b1_from___bbegin:
jmp __b1
// @1
__b1:
// [2] call main
// [4] phi from @1 to main [phi:@1->main]
main_from___b1:
jsr main
// [3] phi from @1 to @end [phi:@1->@end]
__bend_from___b1:
jmp __bend
// @end
__bend:
.segment Code
// main
main: {
.label i = 2
// [5] phi from main to main::@1 [phi:main->main::@1]
__b1_from_main:
// [5] phi (byte) main::i#2 = (byte) 0 [phi:main->main::@1#0] -- vbuz1=vbuc1
lda #0
sta.z i
jmp __b1
// main::@1
__b1:
// [6] if((byte) 0!=*((const byte*) MESSAGE + (byte) main::i#2)) goto main::@2 -- vbuc1_neq_pbuc2_derefidx_vbuz1_then_la1
lda #0
ldy.z i
cmp MESSAGE,y
bne __b2
jmp __breturn
// main::@return
__breturn:
// [7] return
rts
// main::@2
__b2:
// [8] *((const nomodify byte*) DEFAULT_SCREEN + (byte) main::i#2) ← *((const byte*) MESSAGE + (byte) main::i#2) -- pbuc1_derefidx_vbuz1=pbuc2_derefidx_vbuz1
ldy.z i
lda MESSAGE,y
sta DEFAULT_SCREEN,y
// [9] *((const nomodify byte*) DEFAULT_COLORRAM + (byte) main::i#2) ← (const nomodify byte) RED -- pbuc1_derefidx_vbuz1=vbuc2
lda #RED
ldy.z i
sta DEFAULT_COLORRAM,y
// [10] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuz1=_inc_vbuz1
inc.z i
// [5] phi from main::@2 to main::@1 [phi:main::@2->main::@1]
__b1_from___b2:
// [5] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@2->main::@1#0] -- register_copy
jmp __b1
}
// File Data
.segment Data
MESSAGE: .text "hello world!"
.byte 0
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [6] if((byte) 0!=*((const byte*) MESSAGE + (byte) main::i#2)) goto main::@2 [ main::i#2 ] ( main:2 [ main::i#2 ] { } ) always clobbers reg byte a
Removing always clobbered register reg byte a as potential for zp[1]:2 [ main::i#2 main::i#1 ]
Statement [8] *((const nomodify byte*) DEFAULT_SCREEN + (byte) main::i#2) ← *((const byte*) MESSAGE + (byte) main::i#2) [ main::i#2 ] ( main:2 [ main::i#2 ] { } ) always clobbers reg byte a
Statement [9] *((const nomodify byte*) DEFAULT_COLORRAM + (byte) main::i#2) ← (const nomodify byte) RED [ main::i#2 ] ( main:2 [ main::i#2 ] { } ) always clobbers reg byte a
Statement [6] if((byte) 0!=*((const byte*) MESSAGE + (byte) main::i#2)) goto main::@2 [ main::i#2 ] ( main:2 [ main::i#2 ] { } ) always clobbers reg byte a
Statement [8] *((const nomodify byte*) DEFAULT_SCREEN + (byte) main::i#2) ← *((const byte*) MESSAGE + (byte) main::i#2) [ main::i#2 ] ( main:2 [ main::i#2 ] { } ) always clobbers reg byte a
Statement [9] *((const nomodify byte*) DEFAULT_COLORRAM + (byte) main::i#2) ← (const nomodify byte) RED [ main::i#2 ] ( main:2 [ main::i#2 ] { } ) always clobbers reg byte a
Potential registers zp[1]:2 [ main::i#2 main::i#1 ] : zp[1]:2 , reg byte x , reg byte y ,
REGISTER UPLIFT SCOPES
Uplift Scope [main] 353.5: zp[1]:2 [ main::i#2 main::i#1 ]
Uplift Scope [MOS6561_VIC]
Uplift Scope [MOS6522_VIA]
Uplift Scope []
Uplifting [main] best 403 combination reg byte x [ main::i#2 main::i#1 ]
Uplifting [MOS6561_VIC] best 403 combination
Uplifting [MOS6522_VIA] best 403 combination
Uplifting [] best 403 combination
ASSEMBLER BEFORE OPTIMIZATION
// File Comments
// Trivial VIC 20 program
// Upstart
.file [name="vic20-simple.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$1001]
.segmentdef Code [start=$100e]
.segmentdef Data [startAfter="Code"]
.segment Basic
:BasicUpstart(main)
.segment Code
// Global Constants & labels
.const RED = 2
// Default address of screen color matrix
.label DEFAULT_COLORRAM = $9600
// Default address of screen character matrix
.label DEFAULT_SCREEN = $1e00
// @begin
__bbegin:
// [1] phi from @begin to @1 [phi:@begin->@1]
__b1_from___bbegin:
jmp __b1
// @1
__b1:
// [2] call main
// [4] phi from @1 to main [phi:@1->main]
main_from___b1:
jsr main
// [3] phi from @1 to @end [phi:@1->@end]
__bend_from___b1:
jmp __bend
// @end
__bend:
.segment Code
// main
main: {
// [5] phi from main to main::@1 [phi:main->main::@1]
__b1_from_main:
// [5] phi (byte) main::i#2 = (byte) 0 [phi:main->main::@1#0] -- vbuxx=vbuc1
ldx #0
jmp __b1
// main::@1
__b1:
// [6] if((byte) 0!=*((const byte*) MESSAGE + (byte) main::i#2)) goto main::@2 -- vbuc1_neq_pbuc2_derefidx_vbuxx_then_la1
lda MESSAGE,x
cmp #0
bne __b2
jmp __breturn
// main::@return
__breturn:
// [7] return
rts
// main::@2
__b2:
// [8] *((const nomodify byte*) DEFAULT_SCREEN + (byte) main::i#2) ← *((const byte*) MESSAGE + (byte) main::i#2) -- pbuc1_derefidx_vbuxx=pbuc2_derefidx_vbuxx
lda MESSAGE,x
sta DEFAULT_SCREEN,x
// [9] *((const nomodify byte*) DEFAULT_COLORRAM + (byte) main::i#2) ← (const nomodify byte) RED -- pbuc1_derefidx_vbuxx=vbuc2
lda #RED
sta DEFAULT_COLORRAM,x
// [10] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuxx=_inc_vbuxx
inx
// [5] phi from main::@2 to main::@1 [phi:main::@2->main::@1]
__b1_from___b2:
// [5] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@2->main::@1#0] -- register_copy
jmp __b1
}
// File Data
.segment Data
MESSAGE: .text "hello world!"
.byte 0
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1
Removing instruction jmp __bend
Removing instruction jmp __b1
Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction __b1_from___bbegin:
Removing instruction __b1:
Removing instruction main_from___b1:
Removing instruction __bend_from___b1:
Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction __bbegin:
Removing instruction __bend:
Removing instruction __b1_from_main:
Removing instruction __breturn:
Removing instruction __b1_from___b2:
Succesful ASM optimization Pass5UnusedLabelElimination
Removing instruction jsr main
Succesful ASM optimization Pass5SkipBegin
FINAL SYMBOL TABLE
(label) @1
(label) @begin
(label) @end
(const nomodify byte*) DEFAULT_COLORRAM = (byte*) 38400
(const nomodify byte*) DEFAULT_SCREEN = (byte*) 7680
(const byte*) MESSAGE[] = (byte*) "hello world!"
(byte) MOS6522_VIA::AUX_CONTROL
(byte) MOS6522_VIA::INTERRUPT_ENABLE
(byte) MOS6522_VIA::INTERRUPT_FLAG
(byte) MOS6522_VIA::PERIPHERAL_CONTROL
(byte) MOS6522_VIA::PORT_A
(byte) MOS6522_VIA::PORT_A_DDR
(byte) MOS6522_VIA::PORT_A_OUTPUT
(byte) MOS6522_VIA::PORT_B
(byte) MOS6522_VIA::PORT_B_DDR
(byte) MOS6522_VIA::SHIFT
(byte) MOS6522_VIA::TIMER1_HIGH
(byte) MOS6522_VIA::TIMER1_LATCH_HIGH
(byte) MOS6522_VIA::TIMER1_LATCH_LOW
(byte) MOS6522_VIA::TIMER1_LOW
(byte) MOS6522_VIA::TIMER2_HIGH
(byte) MOS6522_VIA::TIMER2_LOW
(byte) MOS6561_VIC::BORDER_BACKGROUND_COLOR
(byte) MOS6561_VIC::CH1_FREQ
(byte) MOS6561_VIC::CH2_FREQ
(byte) MOS6561_VIC::CH3_FREQ
(byte) MOS6561_VIC::CH4_FREQ
(byte) MOS6561_VIC::LIGHTPEN_X
(byte) MOS6561_VIC::LIGHTPEN_Y
(byte) MOS6561_VIC::MATRIX_COLUMNS
(byte) MOS6561_VIC::MATRIX_ROWS
(byte) MOS6561_VIC::MEMORY
(byte) MOS6561_VIC::ORIGIN_X
(byte) MOS6561_VIC::ORIGIN_Y
(byte) MOS6561_VIC::PADDLE_X
(byte) MOS6561_VIC::PADDLE_Y
(byte) MOS6561_VIC::RASTER
(byte) MOS6561_VIC::VOLUME_COLOR
(const nomodify byte) RED = (byte) 2
(void()) main()
(label) main::@1
(label) main::@2
(label) main::@return
(byte) main::i
(byte) main::i#1 reg byte x 202.0
(byte) main::i#2 reg byte x 151.5
reg byte x [ main::i#2 main::i#1 ]
FINAL ASSEMBLER
Score: 331
// File Comments
// Trivial VIC 20 program
// Upstart
.file [name="vic20-simple.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$1001]
.segmentdef Code [start=$100e]
.segmentdef Data [startAfter="Code"]
.segment Basic
:BasicUpstart(main)
.segment Code
// Global Constants & labels
.const RED = 2
// Default address of screen color matrix
.label DEFAULT_COLORRAM = $9600
// Default address of screen character matrix
.label DEFAULT_SCREEN = $1e00
// @begin
// [1] phi from @begin to @1 [phi:@begin->@1]
// @1
// [2] call main
// [4] phi from @1 to main [phi:@1->main]
// [3] phi from @1 to @end [phi:@1->@end]
// @end
.segment Code
// main
main: {
// [5] phi from main to main::@1 [phi:main->main::@1]
// [5] phi (byte) main::i#2 = (byte) 0 [phi:main->main::@1#0] -- vbuxx=vbuc1
ldx #0
// main::@1
__b1:
// for(char i=0; MESSAGE[i]; i++)
// [6] if((byte) 0!=*((const byte*) MESSAGE + (byte) main::i#2)) goto main::@2 -- vbuc1_neq_pbuc2_derefidx_vbuxx_then_la1
lda MESSAGE,x
cmp #0
bne __b2
// main::@return
// }
// [7] return
rts
// main::@2
__b2:
// DEFAULT_SCREEN[i] = MESSAGE[i]
// [8] *((const nomodify byte*) DEFAULT_SCREEN + (byte) main::i#2) ← *((const byte*) MESSAGE + (byte) main::i#2) -- pbuc1_derefidx_vbuxx=pbuc2_derefidx_vbuxx
lda MESSAGE,x
sta DEFAULT_SCREEN,x
// DEFAULT_COLORRAM[i] = RED
// [9] *((const nomodify byte*) DEFAULT_COLORRAM + (byte) main::i#2) ← (const nomodify byte) RED -- pbuc1_derefidx_vbuxx=vbuc2
lda #RED
sta DEFAULT_COLORRAM,x
// for(char i=0; MESSAGE[i]; i++)
// [10] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuxx=_inc_vbuxx
inx
// [5] phi from main::@2 to main::@1 [phi:main::@2->main::@1]
// [5] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@2->main::@1#0] -- register_copy
jmp __b1
}
// File Data
.segment Data
MESSAGE: .text "hello world!"
.byte 0

View File

@ -0,0 +1,48 @@
(label) @1
(label) @begin
(label) @end
(const nomodify byte*) DEFAULT_COLORRAM = (byte*) 38400
(const nomodify byte*) DEFAULT_SCREEN = (byte*) 7680
(const byte*) MESSAGE[] = (byte*) "hello world!"
(byte) MOS6522_VIA::AUX_CONTROL
(byte) MOS6522_VIA::INTERRUPT_ENABLE
(byte) MOS6522_VIA::INTERRUPT_FLAG
(byte) MOS6522_VIA::PERIPHERAL_CONTROL
(byte) MOS6522_VIA::PORT_A
(byte) MOS6522_VIA::PORT_A_DDR
(byte) MOS6522_VIA::PORT_A_OUTPUT
(byte) MOS6522_VIA::PORT_B
(byte) MOS6522_VIA::PORT_B_DDR
(byte) MOS6522_VIA::SHIFT
(byte) MOS6522_VIA::TIMER1_HIGH
(byte) MOS6522_VIA::TIMER1_LATCH_HIGH
(byte) MOS6522_VIA::TIMER1_LATCH_LOW
(byte) MOS6522_VIA::TIMER1_LOW
(byte) MOS6522_VIA::TIMER2_HIGH
(byte) MOS6522_VIA::TIMER2_LOW
(byte) MOS6561_VIC::BORDER_BACKGROUND_COLOR
(byte) MOS6561_VIC::CH1_FREQ
(byte) MOS6561_VIC::CH2_FREQ
(byte) MOS6561_VIC::CH3_FREQ
(byte) MOS6561_VIC::CH4_FREQ
(byte) MOS6561_VIC::LIGHTPEN_X
(byte) MOS6561_VIC::LIGHTPEN_Y
(byte) MOS6561_VIC::MATRIX_COLUMNS
(byte) MOS6561_VIC::MATRIX_ROWS
(byte) MOS6561_VIC::MEMORY
(byte) MOS6561_VIC::ORIGIN_X
(byte) MOS6561_VIC::ORIGIN_Y
(byte) MOS6561_VIC::PADDLE_X
(byte) MOS6561_VIC::PADDLE_Y
(byte) MOS6561_VIC::RASTER
(byte) MOS6561_VIC::VOLUME_COLOR
(const nomodify byte) RED = (byte) 2
(void()) main()
(label) main::@1
(label) main::@2
(label) main::@return
(byte) main::i
(byte) main::i#1 reg byte x 202.0
(byte) main::i#2 reg byte x 151.5
reg byte x [ main::i#2 main::i#1 ]