Skip to content

Commit 4413eff

Browse files
committed
Common first version
1 parent ece4927 commit 4413eff

14 files changed

Lines changed: 824 additions & 0 deletions

build.gradle

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
plugins {
2+
id "com.github.c64lib.retro-assembler" version "1.4.5"
3+
}
4+
5+
repositories {
6+
mavenCentral()
7+
}
8+
9+
retroProject {
10+
11+
dialect = "KickAssembler"
12+
dialectVersion = "5.24"
13+
libDirs = ["..", ".ra/deps/c128lib"]
14+
15+
// libFromGitHub "c128lib/64spec", "0.7.0pr"
16+
}
17+

lib/common-global.asm

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#import "common.asm"
2+
.filenamespace c128lib
3+
4+
.macro @c64lib_ch(data) { ch(data) }
5+
.macro @c64lib_cm(data) { cm(data) }

lib/common.asm

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
#importonce
2+
.filenamespace c128lib
3+
4+
/*
5+
* Why Kickassembler does not support bitwise negation on numerical values?
6+
*
7+
* Params:
8+
* value: byte to be negated
9+
*/
10+
.function neg(value) {
11+
.return value ^ $FF
12+
}
13+
.assert "neg($00) gives $FF", neg($00), $FF
14+
.assert "neg($FF) gives $00", neg($FF), $00
15+
.assert "neg(%10101010) gives %01010101", neg(%10101010), %01010101
16+
17+
/*
18+
* Increases argument by one preserving its type (addressing mode). To be used in pseudocommands.
19+
*
20+
* Params:
21+
* arg: mnemonic argument
22+
*/
23+
.function incArgument(arg) {
24+
.return CmdArgument(arg.getType(), arg.getValue() + 1)
25+
}
26+
27+
/*
28+
* "Far" bne branch. Depending on the jump length it either does bne or beq/jmp trick.
29+
*/
30+
.macro fbne(label) {
31+
here: // we have to add 2 to "here", because relative jump is counted right after bne xx, and this instruction takes 2 bytes
32+
.if (here > label) {
33+
// jump back
34+
.if (here + 2 - label <= 128) {
35+
bne label
36+
} else {
37+
beq skip
38+
jmp label
39+
skip:
40+
}
41+
} else {
42+
// jump forward
43+
.if (label - here - 2 <= 127) {
44+
bne label
45+
} else {
46+
beq skip
47+
jmp label
48+
skip:
49+
}
50+
}
51+
}
52+
53+
/*
54+
* "Far" bmi branch. Depending on the jump length it either does bne or beq/jmp trick.
55+
*/
56+
.macro fbmi(label) {
57+
here: // we have to add 2 to "here", because relative jump is counted right after bne xx, and this instruction takes 2 bytes
58+
.if (here > label) {
59+
// jump back
60+
.if (here + 2 - label <= 128) {
61+
bmi label
62+
} else {
63+
bpl skip
64+
beq skip
65+
jmp label
66+
skip:
67+
}
68+
} else {
69+
// jump forward
70+
.if (label - here - 2 <= 127) {
71+
bmi label
72+
} else {
73+
bpl skip
74+
beq skip
75+
jmp label
76+
skip:
77+
}
78+
}
79+
}
80+
81+
/*
82+
* Convert kbytes to bytes.
83+
*/
84+
.function toBytes(value) {
85+
.return value * 1024
86+
}
87+
88+
.function convertHires(data) {
89+
.var result = ""
90+
.for(var i = 0; i < data.size(); i++) {
91+
.var ch = data.charAt(i)
92+
.if (ch == '.') {
93+
.eval result = result + '0'
94+
} else {
95+
.eval result = result + '1'
96+
}
97+
}
98+
.return result.asNumber(2)
99+
}
100+
.assert @"convertHires(\"........\") = 0", convertHires("........"), 0
101+
.assert @"convertHires(\".......#\") = 1", convertHires(".......#"), 1
102+
.assert @"convertHires(\"########\") = 255", convertHires("########"), 255
103+
104+
.function convertMultic(data) {
105+
.var result = ""
106+
.for(var i = 0; i < data.size(); i++) {
107+
.var ch = data.charAt(i)
108+
.if (ch == '.') .eval result = result + "00"
109+
.if (ch == '#') .eval result = result + "11"
110+
.if (ch == '+') .eval result = result + "01"
111+
.if (ch == 'o') .eval result = result + "10"
112+
}
113+
.return result.asNumber(2)
114+
}
115+
.assert @"convertMultic(\"....\") = 0", convertMultic("...."), 0
116+
.assert @"convertMultic(\"...#\") = 3", convertMultic("...#"), 3
117+
.assert @"convertMultic(\"####\") = 255", convertMultic("####"), 255
118+
119+
.macro ch(data) {
120+
.byte convertHires(data.substring(0, 8))
121+
}
122+
123+
.macro cm(data) {
124+
.byte convertMultic(data.substring(0, 4))
125+
}

lib/invoke-global.asm

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#import "mem.asm"
2+
#importonce
3+
.filenamespace c128lib
4+
5+
.macro @c128lib_invokeStackBegin(placeholderPtr) { invokeStackBegin(placeholderPtr) }
6+
.macro @c128lib_invokeStackEnd(placeholderPtr) { invokeStackEnd(placeholderPtr) }
7+
.macro @c128lib_pushParamB(value) { pushParamB(value) }
8+
.macro @c128lib_pushParamW(value) { pushParamW(value) }
9+
.macro @c128lib_pushParamBInd(ptr) { pushParamBInd(ptr) }
10+
.macro @c128lib_pushParamWInd(ptr) { pushParamWInd(ptr) }
11+
.macro @c128lib_pullParamB(placeholderPtr) { pullParamB(placeholderPtr) }
12+
.macro @c128lib_pullParamW(placeholderPtr) { pullParamW(placeholderPtr) }
13+
.macro @c128lib_pullParamWList(placeholderPtrList) { pullParamWList(placeholderPtrList) }

lib/invoke.asm

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
/*
2+
* Set of KickAssembler macros for subroutine implementation.
3+
*
4+
* With these macros one can realize communication with subroutines using stack. This approach
5+
* is following:
6+
* 1) subroutine caller prepares input parameters and pushes them to the stack using push*() macros
7+
* 2) subroutine is then called using JSR
8+
* 3) subroutine first preserves return address in local variable using invokeStackBegin(variablePtr) macro
9+
* 4) subroutine then pulls all pushed parameters in opposite order using pull*() macros
10+
* 5) when subroutine is about to end, just before RTS is called, it must restore return address with invokeStackEnd(varPtr) macro
11+
*
12+
* Requires KickAssembler v4.x
13+
* (c) 2017-2018 Maciej Malecki
14+
*/
15+
#importonce
16+
.filenamespace c128lib
17+
18+
/*
19+
* Preserves return address that is used with JSR.
20+
* Should be called at beginning of subroutine.
21+
*
22+
* Params:
23+
* placeholderPtr - pointer to the memory location (that is local variable of the subroutine)
24+
* where return address will be preserved.
25+
*/
26+
.macro invokeStackBegin(placeholderPtr) {
27+
pla
28+
sta placeholderPtr
29+
pla
30+
sta placeholderPtr + 1
31+
}
32+
33+
/*
34+
* Restores return address that will be then used with RTS.
35+
* Should be called at the very end of subroutine just before RTS.
36+
*
37+
* Params:
38+
* placeholderPtr - pointer to the memory location (that is local variable of the subroutine)
39+
* from where return address will be restored.
40+
*/
41+
.macro invokeStackEnd(placeholderPtr) {
42+
lda placeholderPtr + 1
43+
pha
44+
lda placeholderPtr
45+
pha
46+
}
47+
48+
/*
49+
* Pushes byte value as a parameter to the subroutine.
50+
* Such value should be then pulled in subroutine in opposite order.
51+
*
52+
* Params:
53+
* value - byte value of the parameter for subroutine
54+
*/
55+
.macro pushParamB(value) {
56+
lda #value
57+
pha
58+
}
59+
60+
/*
61+
* Pushes two bytes value as a parameter to the subroutine.
62+
* Such value should be then pulled in subroutine in opposite order.
63+
*
64+
* Params:
65+
* value - word value of the parameter for subroutine
66+
*/
67+
.macro pushParamW(value) {
68+
pushParamB(<value)
69+
pushParamB(>value)
70+
}
71+
72+
/*
73+
* Pushes byte pointed by an address as a parameter to the subroutine.
74+
* Such value should be then pulled in subroutine in opposite order.
75+
*
76+
* Params:
77+
* ptr - pointer to the byte value of the parameter for subroutine
78+
*/
79+
.macro pushParamBInd(ptr) {
80+
lda ptr
81+
pha
82+
}
83+
84+
/*
85+
* Pushes two bytes value pointed by an address as a parameter to the subroutine.
86+
* Such value should be then pulled in subroutine in opposite order.
87+
*
88+
* Params:
89+
* ptr - pointer to the two bytes value of the parameter for subroutine
90+
*/
91+
.macro pushParamWInd(ptr) {
92+
pushParamBInd(ptr)
93+
pushParamBInd(ptr + 1)
94+
}
95+
96+
/*
97+
* Pulls byte value from the stack and stores it under given address.
98+
*
99+
* Params:
100+
* placeholderPtr - pointer to the memory location where given byte will be pulled to
101+
*/
102+
.macro pullParamB(placeholderPtr) {
103+
pla
104+
sta placeholderPtr
105+
}
106+
107+
/*
108+
* Pulls two bytes value from the stack and stores it under given address.
109+
*
110+
* Params:
111+
* placeholderPtr - pointer to the beginning of memory location where given two bytes will be pulled to
112+
*/
113+
.macro pullParamW(placeholderPtr) {
114+
pullParamB(placeholderPtr + 1)
115+
pullParamB(placeholderPtr)
116+
}
117+
118+
/*
119+
* Pulls two bytes value from the stack and stores it under provided addresses.
120+
*
121+
* Params:
122+
* placeholderPtrList - List of memory locations, where given two byte value will be stored
123+
*/
124+
.macro pullParamWList(placeholderPtrList) {
125+
.assert "list must be non empty", placeholderPtrList.size() > 0, true
126+
pla
127+
.for (var i = 0; i < placeholderPtrList.size(); i++) sta placeholderPtrList.get(i) + 1
128+
pla
129+
.for (var i = 0; i < placeholderPtrList.size(); i++) sta placeholderPtrList.get(i)
130+
}
131+
.assert "pullParamWList([$aaaa, $bbbb])", {pullParamWList(List().add($aaaa, $bbbb))},
132+
{pla;sta $aaaa + 1; sta $bbbb + 1; pla; sta $aaaa; sta $bbbb}

lib/math-global.asm

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#import "math.asm"
2+
#importonce
3+
.filenamespace c128lib
4+
5+
.macro @c128lib_add16(value, low) { add16(value, low) }
6+
.pseudocommand @c128lib_add16 value : low { add16 value : low }
7+
.macro @c128lib_sub16(value, low) { sub16(value, low) }
8+
.macro @c128lib_addMem16(source, destination) { addMem16(source, destination ) }
9+
.macro @c128lib_asl16(low) { asl16(low) }
10+
.macro @c128lib_inc16(destination) { inc16(destination) }
11+
.macro @c128lib_dec16(destination) { dec16(destination) }
12+
.macro @c128lib_mulAndAdd(left, right, targetAddr) { mulAndAdd(left, right, targetAddr) }

0 commit comments

Comments
 (0)