Skip to content

Commit

Permalink
Common first version
Browse files Browse the repository at this point in the history
  • Loading branch information
intoinside committed Oct 12, 2022
1 parent ece4927 commit 4413eff
Show file tree
Hide file tree
Showing 14 changed files with 824 additions and 0 deletions.
17 changes: 17 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
plugins {
id "com.github.c64lib.retro-assembler" version "1.4.5"
}

repositories {
mavenCentral()
}

retroProject {

dialect = "KickAssembler"
dialectVersion = "5.24"
libDirs = ["..", ".ra/deps/c128lib"]

// libFromGitHub "c128lib/64spec", "0.7.0pr"
}

5 changes: 5 additions & 0 deletions lib/common-global.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#import "common.asm"
.filenamespace c128lib

.macro @c64lib_ch(data) { ch(data) }
.macro @c64lib_cm(data) { cm(data) }
125 changes: 125 additions & 0 deletions lib/common.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
#importonce
.filenamespace c128lib

/*
* Why Kickassembler does not support bitwise negation on numerical values?
*
* Params:
* value: byte to be negated
*/
.function neg(value) {
.return value ^ $FF
}
.assert "neg($00) gives $FF", neg($00), $FF
.assert "neg($FF) gives $00", neg($FF), $00
.assert "neg(%10101010) gives %01010101", neg(%10101010), %01010101

/*
* Increases argument by one preserving its type (addressing mode). To be used in pseudocommands.
*
* Params:
* arg: mnemonic argument
*/
.function incArgument(arg) {
.return CmdArgument(arg.getType(), arg.getValue() + 1)
}

/*
* "Far" bne branch. Depending on the jump length it either does bne or beq/jmp trick.
*/
.macro fbne(label) {
here: // we have to add 2 to "here", because relative jump is counted right after bne xx, and this instruction takes 2 bytes
.if (here > label) {
// jump back
.if (here + 2 - label <= 128) {
bne label
} else {
beq skip
jmp label
skip:
}
} else {
// jump forward
.if (label - here - 2 <= 127) {
bne label
} else {
beq skip
jmp label
skip:
}
}
}

/*
* "Far" bmi branch. Depending on the jump length it either does bne or beq/jmp trick.
*/
.macro fbmi(label) {
here: // we have to add 2 to "here", because relative jump is counted right after bne xx, and this instruction takes 2 bytes
.if (here > label) {
// jump back
.if (here + 2 - label <= 128) {
bmi label
} else {
bpl skip
beq skip
jmp label
skip:
}
} else {
// jump forward
.if (label - here - 2 <= 127) {
bmi label
} else {
bpl skip
beq skip
jmp label
skip:
}
}
}

/*
* Convert kbytes to bytes.
*/
.function toBytes(value) {
.return value * 1024
}

.function convertHires(data) {
.var result = ""
.for(var i = 0; i < data.size(); i++) {
.var ch = data.charAt(i)
.if (ch == '.') {
.eval result = result + '0'
} else {
.eval result = result + '1'
}
}
.return result.asNumber(2)
}
.assert @"convertHires(\"........\") = 0", convertHires("........"), 0
.assert @"convertHires(\".......#\") = 1", convertHires(".......#"), 1
.assert @"convertHires(\"########\") = 255", convertHires("########"), 255

.function convertMultic(data) {
.var result = ""
.for(var i = 0; i < data.size(); i++) {
.var ch = data.charAt(i)
.if (ch == '.') .eval result = result + "00"
.if (ch == '#') .eval result = result + "11"
.if (ch == '+') .eval result = result + "01"
.if (ch == 'o') .eval result = result + "10"
}
.return result.asNumber(2)
}
.assert @"convertMultic(\"....\") = 0", convertMultic("...."), 0
.assert @"convertMultic(\"...#\") = 3", convertMultic("...#"), 3
.assert @"convertMultic(\"####\") = 255", convertMultic("####"), 255

.macro ch(data) {
.byte convertHires(data.substring(0, 8))
}

.macro cm(data) {
.byte convertMultic(data.substring(0, 4))
}
13 changes: 13 additions & 0 deletions lib/invoke-global.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#import "mem.asm"
#importonce
.filenamespace c128lib

.macro @c128lib_invokeStackBegin(placeholderPtr) { invokeStackBegin(placeholderPtr) }
.macro @c128lib_invokeStackEnd(placeholderPtr) { invokeStackEnd(placeholderPtr) }
.macro @c128lib_pushParamB(value) { pushParamB(value) }
.macro @c128lib_pushParamW(value) { pushParamW(value) }
.macro @c128lib_pushParamBInd(ptr) { pushParamBInd(ptr) }
.macro @c128lib_pushParamWInd(ptr) { pushParamWInd(ptr) }
.macro @c128lib_pullParamB(placeholderPtr) { pullParamB(placeholderPtr) }
.macro @c128lib_pullParamW(placeholderPtr) { pullParamW(placeholderPtr) }
.macro @c128lib_pullParamWList(placeholderPtrList) { pullParamWList(placeholderPtrList) }
132 changes: 132 additions & 0 deletions lib/invoke.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
/*
* Set of KickAssembler macros for subroutine implementation.
*
* With these macros one can realize communication with subroutines using stack. This approach
* is following:
* 1) subroutine caller prepares input parameters and pushes them to the stack using push*() macros
* 2) subroutine is then called using JSR
* 3) subroutine first preserves return address in local variable using invokeStackBegin(variablePtr) macro
* 4) subroutine then pulls all pushed parameters in opposite order using pull*() macros
* 5) when subroutine is about to end, just before RTS is called, it must restore return address with invokeStackEnd(varPtr) macro
*
* Requires KickAssembler v4.x
* (c) 2017-2018 Maciej Malecki
*/
#importonce
.filenamespace c128lib

/*
* Preserves return address that is used with JSR.
* Should be called at beginning of subroutine.
*
* Params:
* placeholderPtr - pointer to the memory location (that is local variable of the subroutine)
* where return address will be preserved.
*/
.macro invokeStackBegin(placeholderPtr) {
pla
sta placeholderPtr
pla
sta placeholderPtr + 1
}

/*
* Restores return address that will be then used with RTS.
* Should be called at the very end of subroutine just before RTS.
*
* Params:
* placeholderPtr - pointer to the memory location (that is local variable of the subroutine)
* from where return address will be restored.
*/
.macro invokeStackEnd(placeholderPtr) {
lda placeholderPtr + 1
pha
lda placeholderPtr
pha
}

/*
* Pushes byte value as a parameter to the subroutine.
* Such value should be then pulled in subroutine in opposite order.
*
* Params:
* value - byte value of the parameter for subroutine
*/
.macro pushParamB(value) {
lda #value
pha
}

/*
* Pushes two bytes value as a parameter to the subroutine.
* Such value should be then pulled in subroutine in opposite order.
*
* Params:
* value - word value of the parameter for subroutine
*/
.macro pushParamW(value) {
pushParamB(<value)
pushParamB(>value)
}

/*
* Pushes byte pointed by an address as a parameter to the subroutine.
* Such value should be then pulled in subroutine in opposite order.
*
* Params:
* ptr - pointer to the byte value of the parameter for subroutine
*/
.macro pushParamBInd(ptr) {
lda ptr
pha
}

/*
* Pushes two bytes value pointed by an address as a parameter to the subroutine.
* Such value should be then pulled in subroutine in opposite order.
*
* Params:
* ptr - pointer to the two bytes value of the parameter for subroutine
*/
.macro pushParamWInd(ptr) {
pushParamBInd(ptr)
pushParamBInd(ptr + 1)
}

/*
* Pulls byte value from the stack and stores it under given address.
*
* Params:
* placeholderPtr - pointer to the memory location where given byte will be pulled to
*/
.macro pullParamB(placeholderPtr) {
pla
sta placeholderPtr
}

/*
* Pulls two bytes value from the stack and stores it under given address.
*
* Params:
* placeholderPtr - pointer to the beginning of memory location where given two bytes will be pulled to
*/
.macro pullParamW(placeholderPtr) {
pullParamB(placeholderPtr + 1)
pullParamB(placeholderPtr)
}

/*
* Pulls two bytes value from the stack and stores it under provided addresses.
*
* Params:
* placeholderPtrList - List of memory locations, where given two byte value will be stored
*/
.macro pullParamWList(placeholderPtrList) {
.assert "list must be non empty", placeholderPtrList.size() > 0, true
pla
.for (var i = 0; i < placeholderPtrList.size(); i++) sta placeholderPtrList.get(i) + 1
pla
.for (var i = 0; i < placeholderPtrList.size(); i++) sta placeholderPtrList.get(i)
}
.assert "pullParamWList([$aaaa, $bbbb])", {pullParamWList(List().add($aaaa, $bbbb))},
{pla;sta $aaaa + 1; sta $bbbb + 1; pla; sta $aaaa; sta $bbbb}
12 changes: 12 additions & 0 deletions lib/math-global.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#import "math.asm"
#importonce
.filenamespace c128lib

.macro @c128lib_add16(value, low) { add16(value, low) }
.pseudocommand @c128lib_add16 value : low { add16 value : low }
.macro @c128lib_sub16(value, low) { sub16(value, low) }
.macro @c128lib_addMem16(source, destination) { addMem16(source, destination ) }
.macro @c128lib_asl16(low) { asl16(low) }
.macro @c128lib_inc16(destination) { inc16(destination) }
.macro @c128lib_dec16(destination) { dec16(destination) }
.macro @c128lib_mulAndAdd(left, right, targetAddr) { mulAndAdd(left, right, targetAddr) }
Loading

0 comments on commit 4413eff

Please sign in to comment.