1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2025-02-17 10:30:43 +00:00

Working helloworld for XMega65 Xemu.

This commit is contained in:
jespergravgaard 2019-08-10 15:41:32 +02:00
parent c82234db19
commit 7484e27a32
5 changed files with 699 additions and 545 deletions

View File

@ -4,36 +4,56 @@
#pragma link("xmega65.ld") #pragma link("xmega65.ld")
const char* VIC_MEMORY = 0xd018;
const char* SCREEN = 0x0400;
const char* COLS = 0xd800;
const char WHITE = 1;
char[] MESSAGE = "hello world!";
void main() { void main() {
char i=0; // Initialize screen memory
// Call SYSCALL functions one at a time *VIC_MEMORY = 0x14;
// Print message in white
char* sc = SCREEN;
char* cols = COLS;
for(char* msg = MESSAGE; *msg; msg++, sc++, cols++) {
*sc = *msg;
*cols = WHITE;
}
// Loop forever
while(true) { while(true) {
void()* fsyscall = FSYSCALLS[i*2];
(*fsyscall)();
if(++i==2) i=0;
} }
} }
void fn1() { void syscall1() {
const char* BORDERCOL = $d020; const char* BORDERCOL = $d020;
(*BORDERCOL)++; (*BORDERCOL)++;
} }
void fn2() { void syscall2() {
const char* BGCOL = $d021; const char* BGCOL = $d021;
(*BGCOL)++; (*BGCOL)++;
} }
#pragma data_seg(Syscall) #pragma data_seg(Syscall)
struct SysCall {
char xjmp;
void()* syscall;
char xnop;
};
const char JMP = 0x4c; const char JMP = 0x4c;
const char NOP = 0xea; const char NOP = 0xea;
export char[] SYSCALLS = { export struct SysCall[] SYSCALLS = {
JMP, <&fn1, >&fn1, NOP, { JMP, &syscall1, NOP },
JMP, <&fn2, >&fn2, NOP { JMP, &syscall2, NOP }
}; };
export align(0x100) char[] SYSCALL_RESET = { JMP, <&main, >&main, NOP }; export align(0x100) struct SysCall[] SYSCALL_RESET = {
{ JMP, &main, NOP }
const void()** FSYSCALLS = (void()**)(SYSCALLS+1); };

View File

@ -8,46 +8,83 @@
.segmentdef Data [startAfter="Code", min=$8200, max=$bdff] .segmentdef Data [startAfter="Code", min=$8200, max=$bdff]
.segmentdef Stack [min=$be00, max=$beff, fill] .segmentdef Stack [min=$be00, max=$beff, fill]
.segmentdef Zeropage [min=$bf00, max=$bfff, fill] .segmentdef Zeropage [min=$bf00, max=$bfff, fill]
.label VIC_MEMORY = $d018
.label SCREEN = $400
.label COLS = $d800
.const WHITE = 1
.const JMP = $4c .const JMP = $4c
.const NOP = $ea .const NOP = $ea
.label FSYSCALLS = SYSCALLS+1
.segment Code .segment Code
main: { main: {
.label fsyscall = 3 .label msg = 2
.label i = 2 .label sc = 4
.label cols = 6
// Initialize screen memory
lda #$14
sta VIC_MEMORY
lda #<COLS
sta.z cols
lda #>COLS
sta.z cols+1
lda #<SCREEN
sta.z sc
lda #>SCREEN
sta.z sc+1
lda #<MESSAGE
sta.z msg
lda #>MESSAGE
sta.z msg+1
b1: b1:
lda #0 ldy #0
sta.z i lda (msg),y
// Call SYSCALL functions one at a time cmp #0
b2:
lda.z i
asl
asl
tay
lda FSYSCALLS,y
sta.z fsyscall
lda FSYSCALLS+1,y
sta.z fsyscall+1
jsr bi_fsyscall
inc.z i
lda #2
cmp.z i
bne b2 bne b2
b3:
// Loop forever
jmp b3
b2:
ldy #0
lda (msg),y
sta (sc),y
lda #WHITE
sta (cols),y
inc.z msg
bne !+
inc.z msg+1
!:
inc.z sc
bne !+
inc.z sc+1
!:
inc.z cols
bne !+
inc.z cols+1
!:
jmp b1 jmp b1
bi_fsyscall:
jmp (fsyscall)
} }
fn2: { syscall2: {
.label BGCOL = $d021 .label BGCOL = $d021
inc BGCOL inc BGCOL
rts rts
} }
fn1: { syscall1: {
.label BORDERCOL = $d020 .label BORDERCOL = $d020
inc BORDERCOL inc BORDERCOL
rts rts
} }
.segment Data
MESSAGE: .text "hello world!"
.byte 0
.segment Syscall .segment Syscall
SYSCALLS: .byte JMP, <fn1, >fn1, NOP, JMP, <fn2, >fn2, NOP SYSCALLS:
.byte JMP
.word syscall1
.byte NOP
.byte JMP
.word syscall2
.byte NOP
.align $100 .align $100
SYSCALL_RESET: .byte JMP, <main, >main, NOP SYSCALL_RESET:
.byte JMP
.word main
.byte NOP

View File

@ -8,31 +8,33 @@
@end: scope:[] from @1 @end: scope:[] from @1
[3] phi() [3] phi()
main: scope:[main] from @1 main: scope:[main] from @1
[4] phi() [4] *((const byte*) VIC_MEMORY#0) ← (byte) $14
to:main::@1 to:main::@1
main::@1: scope:[main] from main main::@2 main::@3 main::@1: scope:[main] from main main::@2
[5] (byte) main::i#3 ← phi( main/(byte) 0 main::@3/(byte) main::i#1 main::@2/(byte) 0 ) [5] (byte*) main::cols#2 ← phi( main/(const byte*) COLS#0 main::@2/(byte*) main::cols#1 )
to:main::@2 [5] (byte*) main::sc#2 ← phi( main/(const byte*) SCREEN#0 main::@2/(byte*) main::sc#1 )
[5] (byte*) main::msg#2 ← phi( main/(const byte[]) MESSAGE#0 main::@2/(byte*) main::msg#1 )
[6] if((byte) 0!=*((byte*) main::msg#2)) goto main::@2
to:main::@3
main::@3: scope:[main] from main::@1 main::@3
[7] phi()
to:main::@3
main::@2: scope:[main] from main::@1 main::@2: scope:[main] from main::@1
[6] (byte~) main::$0 ← (byte) main::i#3 << (byte) 1 [8] *((byte*) main::sc#2) ← *((byte*) main::msg#2)
[7] (byte~) main::$4 ← (byte~) main::$0 << (byte) 1 [9] *((byte*) main::cols#2) ← (const byte) WHITE#0
[8] (void()*) main::fsyscall#0 ← *((const void()**) FSYSCALLS#0 + (byte~) main::$4) [10] (byte*) main::msg#1 ← ++ (byte*) main::msg#2
[9] call *((void()*) main::fsyscall#0) [11] (byte*) main::sc#1 ← ++ (byte*) main::sc#2
[10] (byte) main::i#1 ← ++ (byte) main::i#3 [12] (byte*) main::cols#1 ← ++ (byte*) main::cols#2
[11] if((byte) main::i#1!=(byte) 2) goto main::@3
to:main::@1 to:main::@1
main::@3: scope:[main] from main::@2 syscall2: scope:[syscall2] from
[12] phi() [13] *((const byte*) syscall2::BGCOL#0) ← ++ *((const byte*) syscall2::BGCOL#0)
to:main::@1 to:syscall2::@return
fn2: scope:[fn2] from syscall2::@return: scope:[syscall2] from syscall2
[13] *((const byte*) fn2::BGCOL#0) ← ++ *((const byte*) fn2::BGCOL#0)
to:fn2::@return
fn2::@return: scope:[fn2] from fn2
[14] return [14] return
to:@return to:@return
fn1: scope:[fn1] from syscall1: scope:[syscall1] from
[15] *((const byte*) fn1::BORDERCOL#0) ← ++ *((const byte*) fn1::BORDERCOL#0) [15] *((const byte*) syscall1::BORDERCOL#0) ← ++ *((const byte*) syscall1::BORDERCOL#0)
to:fn1::@return to:syscall1::@return
fn1::@return: scope:[fn1] from fn1 syscall1::@return: scope:[syscall1] from syscall1
[16] return [16] return
to:@return to:@return

File diff suppressed because it is too large Load Diff

View File

@ -1,37 +1,49 @@
(label) @1 (label) @1
(label) @begin (label) @begin
(label) @end (label) @end
(void()**) FSYSCALLS (byte*) COLS
(const void()**) FSYSCALLS#0 FSYSCALLS = (void()**)(const byte[]) SYSCALLS#0+(byte) 1 (const byte*) COLS#0 COLS = (byte*) 55296
(byte) JMP (byte) JMP
(const byte) JMP#0 JMP = (byte) $4c (const byte) JMP#0 JMP = (byte) $4c
(byte[]) MESSAGE
(const byte[]) MESSAGE#0 MESSAGE = (string) "hello world!"
(byte) NOP (byte) NOP
(const byte) NOP#0 NOP = (byte) $ea (const byte) NOP#0 NOP = (byte) $ea
(byte[]) SYSCALLS (byte*) SCREEN
(const byte[]) SYSCALLS#0 SYSCALLS = { (const byte) JMP#0, <&(void()) fn1(), >&(void()) fn1(), (const byte) NOP#0, (const byte) JMP#0, <&(void()) fn2(), >&(void()) fn2(), (const byte) NOP#0 } (const byte*) SCREEN#0 SCREEN = (byte*) 1024
(byte[]) SYSCALL_RESET (struct SysCall[]) SYSCALLS
(const byte[]) SYSCALL_RESET#0 SYSCALL_RESET = { (const byte) JMP#0, <&(void()) main(), >&(void()) main(), (const byte) NOP#0 } (const struct SysCall[]) SYSCALLS#0 SYSCALLS = { { xjmp: (const byte) JMP#0, syscall: &(void()) syscall1(), xnop: (const byte) NOP#0 }, { xjmp: (const byte) JMP#0, syscall: &(void()) syscall2(), xnop: (const byte) NOP#0 } }
(void()) fn1() (struct SysCall[]) SYSCALL_RESET
(label) fn1::@return (const struct SysCall[]) SYSCALL_RESET#0 SYSCALL_RESET = { { xjmp: (const byte) JMP#0, syscall: &(void()) main(), xnop: (const byte) NOP#0 } }
(byte*) fn1::BORDERCOL (void()*) SysCall::syscall
(const byte*) fn1::BORDERCOL#0 BORDERCOL = (byte*) 53280 (byte) SysCall::xjmp
(void()) fn2() (byte) SysCall::xnop
(label) fn2::@return (byte*) VIC_MEMORY
(byte*) fn2::BGCOL (const byte*) VIC_MEMORY#0 VIC_MEMORY = (byte*) 53272
(const byte*) fn2::BGCOL#0 BGCOL = (byte*) 53281 (byte) WHITE
(const byte) WHITE#0 WHITE = (byte) 1
(void()) main() (void()) main()
(byte~) main::$0 reg byte a 202.0
(byte~) main::$4 reg byte a 202.0
(label) main::@1 (label) main::@1
(label) main::@2 (label) main::@2
(label) main::@3 (label) main::@3
(void()*) main::fsyscall (byte*) main::cols
(void()*) main::fsyscall#0 fsyscall zp ZP_WORD:3 101.0 (byte*) main::cols#1 cols zp ZP_WORD:6 22.0
(byte) main::i (byte*) main::cols#2 cols zp ZP_WORD:6 5.5
(byte) main::i#1 i zp ZP_BYTE:2 71.0 (byte*) main::msg
(byte) main::i#3 i zp ZP_BYTE:2 42.599999999999994 (byte*) main::msg#1 msg zp ZP_WORD:2 7.333333333333333
(byte*) main::msg#2 msg zp ZP_WORD:2 11.0
(byte*) main::sc
(byte*) main::sc#1 sc zp ZP_WORD:4 11.0
(byte*) main::sc#2 sc zp ZP_WORD:4 6.6000000000000005
(void()) syscall1()
(label) syscall1::@return
(byte*) syscall1::BORDERCOL
(const byte*) syscall1::BORDERCOL#0 BORDERCOL = (byte*) 53280
(void()) syscall2()
(label) syscall2::@return
(byte*) syscall2::BGCOL
(const byte*) syscall2::BGCOL#0 BGCOL = (byte*) 53281
zp ZP_BYTE:2 [ main::i#3 main::i#1 ] zp ZP_WORD:2 [ main::msg#2 main::msg#1 ]
reg byte a [ main::$0 ] zp ZP_WORD:4 [ main::sc#2 main::sc#1 ]
reg byte a [ main::$4 ] zp ZP_WORD:6 [ main::cols#2 main::cols#1 ]
zp ZP_WORD:3 [ main::fsyscall#0 ]