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:
parent
c82234db19
commit
7484e27a32
@ -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);
|
};
|
||||||
|
@ -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
|
||||||
|
@ -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
@ -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 ]
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user