Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- .cpu _65c02
- // Commodore 64 PRG executable file
- .file [name="kickc-c64-api.prg", type="prg", segments="Program"]
- .segmentdef Program [segments="Basic, Code, Data"]
- .segmentdef Basic [start=$0801]
- .segmentdef Code [start=$80d]
- .segmentdef Data [startAfter="Code"]
- .segment Basic
- :BasicUpstart(main)
- .label getMachineType = $15
- .segment Code
- /**
- * C64 API intended for use with the SuperCPU
- * By Donkeysoft MMXXI
- * At the moment, KickC and Kick Assembler only
- * build 65c02 binaries; this may change in the
- * future.
- */
- main: {
- .label waitState = $100
- .label xLocation = 3
- .label yLocation = 5
- .label index = 2
- jsr setMachineType
- jsr disableBasicInterrupts
- lda #<0
- sta.z poke.value
- sta.z poke.value+1
- lda #<$d020
- sta.z poke.location
- lda #>$d020
- sta.z poke.location+1
- jsr poke
- lda #<$f
- sta.z poke.value
- lda #>$f
- sta.z poke.value+1
- lda #<$d021
- sta.z poke.location
- lda #>$d021
- sta.z poke.location+1
- jsr poke
- jsr clearScreen
- jsr printAt
- jsr colourAt
- lda #$30
- sta.z yLocation
- lda #<$40
- sta.z xLocation
- lda #>$40
- sta.z xLocation+1
- lda #0
- sta.z index
- __b1:
- lda.z index
- cmp #8
- bcs !__b2+
- jmp __b2
- !__b2:
- jsr spriteExpandX
- jsr spriteExpandY
- jsr spriteUnexpandX
- jsr spriteUnexpandY
- __b4:
- lda #<$2c
- sta.z checkForScanLine.scanLine
- lda #>$2c
- sta.z checkForScanLine.scanLine+1
- jsr checkForScanLine
- cmp #1
- bne __b5
- lda #<1
- sta.z poke.value
- lda #>1
- sta.z poke.value+1
- lda #<$d020
- sta.z poke.location
- lda #>$d020
- sta.z poke.location+1
- jsr poke
- jsr wait
- lda #<0
- sta.z poke.value
- sta.z poke.value+1
- lda #<$d020
- sta.z poke.location
- lda #>$d020
- sta.z poke.location+1
- jsr poke
- __b5:
- lda #<$58
- sta.z checkForScanLine.scanLine
- lda #>$58
- sta.z checkForScanLine.scanLine+1
- jsr checkForScanLine
- cmp #1
- bne __b6
- lda #<3
- sta.z poke.value
- lda #>3
- sta.z poke.value+1
- lda #<$d020
- sta.z poke.location
- lda #>$d020
- sta.z poke.location+1
- jsr poke
- jsr wait
- lda #<0
- sta.z poke.value
- sta.z poke.value+1
- lda #<$d020
- sta.z poke.location
- lda #>$d020
- sta.z poke.location+1
- jsr poke
- __b6:
- lda #<$f4
- sta.z checkForScanLine.scanLine
- lda #>$f4
- sta.z checkForScanLine.scanLine+1
- jsr checkForScanLine
- cmp #1
- bne __b7
- lda #<5
- sta.z poke.value
- lda #>5
- sta.z poke.value+1
- lda #<$d020
- sta.z poke.location
- lda #>$d020
- sta.z poke.location+1
- jsr poke
- jsr wait
- lda #<0
- sta.z poke.value
- sta.z poke.value+1
- lda #<$d020
- sta.z poke.location
- lda #>$d020
- sta.z poke.location+1
- jsr poke
- __b7:
- lda #<$110
- sta.z checkForScanLine.scanLine
- lda #>$110
- sta.z checkForScanLine.scanLine+1
- jsr checkForScanLine
- cmp #1
- beq !__b4+
- jmp __b4
- !__b4:
- lda #<7
- sta.z poke.value
- lda #>7
- sta.z poke.value+1
- lda #<$d020
- sta.z poke.location
- lda #>$d020
- sta.z poke.location+1
- jsr poke
- jsr wait
- lda #<0
- sta.z poke.value
- sta.z poke.value+1
- lda #<$d020
- sta.z poke.location
- lda #>$d020
- sta.z poke.location+1
- jsr poke
- jmp __b4
- __b2:
- lda.z index
- tax
- jsr setSpriteColour
- ldx.z index
- jsr switchOnSprites
- lda.z xLocation
- sta.z spriteAt.x
- lda.z xLocation+1
- sta.z spriteAt.x+1
- lda.z yLocation
- sta.z spriteAt.y
- lda.z index
- sta.z spriteAt.spriteNumber
- jsr spriteAt
- lda #$18
- clc
- adc.z xLocation
- sta.z xLocation
- bcc !+
- inc.z xLocation+1
- !:
- lda #$18
- clc
- adc.z yLocation
- sta.z yLocation
- inc.z index
- jmp __b1
- .segment Data
- toPrint: .text "c64 rulez!"
- .byte 0
- }
- .segment Code
- /**
- * This is the initialisation will
- * determine the machine type
- * by setting the getMachineType global
- * as follows:
- * 37 is PAL
- * 5 is NTSC (old)
- * 6 is NTSC (new)
- * 0 (or any other value) is unknown
- *
- * For safety, the initial value of 0xc000
- * is stored into the accumulator and
- * pushed onto the stack; it is then
- * restored after the getMachineType
- * global is set
- *
- * @author Robin Harbron
- */
- setMachineType: {
- lda $c000
- pha
- sei
- __br1:
- lda $d011
- bmi __br1
- __br2:
- lda $d011
- bpl __br2
- __br3:
- lda $d012
- bit $d011
- bpl __ex1
- sta $c000
- bmi __br3
- __ex1:
- cli
- lda #<$c000
- sta.z peek.location
- lda #>$c000
- sta.z peek.location+1
- jsr peek
- sta.z getMachineType
- pla
- sta $c000
- rts
- }
- /**
- * Disables BASIC interrupts
- */
- disableBasicInterrupts: {
- lda #<$dc0e
- sta.z peek.location
- lda #>$dc0e
- sta.z peek.location+1
- jsr peek
- and #$fe
- sta.z poke.value
- lda #0
- sta.z poke.value+1
- lda #<$dc0e
- sta.z poke.location
- lda #>$dc0e
- sta.z poke.location+1
- jsr poke
- rts
- }
- /**
- * Takes in two 16-bit values, the first is
- * the memory location and the second will be
- * converted to an 8-bit value which is then
- * poked to memory
- */
- // poke(word zp(6) location, word zp(8) value)
- poke: {
- .label value = 8
- .label location = 6
- lda #$ff
- and.z value
- ldy #0
- sta (location),y
- rts
- }
- /**
- * Clears the screen according to
- * the current screen memory location
- * pointer at 0xd018
- */
- clearScreen: {
- .label screenLocation = $e
- jsr getScreenMemoryLocation
- jsr fillMemory
- rts
- }
- /**
- * Writes a string to the screen starting
- * from column x and row y (zero indexed)
- */
- printAt: {
- .const x = 4
- .const y = $c
- .label screenAddress = $c
- .label index = $16
- lda #<$400+x+y*$28
- sta.z screenAddress
- lda #>$400+x+y*$28
- sta.z screenAddress+1
- lda #0
- sta.z index
- __b1:
- ldy.z index
- lda main.toPrint,y
- cmp #0
- bne __b2
- rts
- __b2:
- lda.z screenAddress
- sta.z poke.location
- lda.z screenAddress+1
- sta.z poke.location+1
- ldy.z index
- lda main.toPrint,y
- sta.z poke.value
- lda #0
- sta.z poke.value+1
- jsr poke
- inc.z screenAddress
- bne !+
- inc.z screenAddress+1
- !:
- inc.z index
- jmp __b1
- }
- /**
- * Changes the character colour of a
- * screen location starting from column
- * x and row y (zero indexed)
- */
- colourAt: {
- .const x = 4
- .const y = $c
- .const colour = 1
- .const numberOfCharacters = $a
- .label colourRamAddress = $19
- lda #<$d800+x+y*$28
- sta.z colourRamAddress
- lda #>$d800+x+y*$28
- sta.z colourRamAddress+1
- ldx #0
- __b1:
- cpx #numberOfCharacters
- bcc __b2
- rts
- __b2:
- lda.z colourRamAddress
- sta.z poke.location
- lda.z colourRamAddress+1
- sta.z poke.location+1
- lda #<colour
- sta.z poke.value
- lda #>colour
- sta.z poke.value+1
- jsr poke
- inc.z colourRamAddress
- bne !+
- inc.z colourRamAddress+1
- !:
- inx
- jmp __b1
- }
- /**
- * Set sprite to double width (zero indexed)
- */
- spriteExpandX: {
- .const spriteNumber = 0
- .label __2 = $16
- lda #<$d01d
- sta.z peek.location
- lda #>$d01d
- sta.z peek.location+1
- jsr peek
- sta.z __2
- ldx #spriteNumber
- jsr getBitNumber
- ora.z __2
- sta.z poke.value
- lda #0
- sta.z poke.value+1
- lda #<$d01d
- sta.z poke.location
- lda #>$d01d
- sta.z poke.location+1
- jsr poke
- rts
- }
- /**
- * Set sprite to double height (zero indexed)
- */
- spriteExpandY: {
- .const spriteNumber = 1
- .label __2 = $1c
- lda #<$d017
- sta.z peek.location
- lda #>$d017
- sta.z peek.location+1
- jsr peek
- sta.z __2
- ldx #spriteNumber
- jsr getBitNumber
- ora.z __2
- sta.z poke.value
- lda #0
- sta.z poke.value+1
- lda #<$d017
- sta.z poke.location
- lda #>$d017
- sta.z poke.location+1
- jsr poke
- rts
- }
- /**
- * Unset sprite double width (zero indexed)
- */
- spriteUnexpandX: {
- .const spriteNumber = 2
- .label __2 = $17
- lda #<$d01d
- sta.z peek.location
- lda #>$d01d
- sta.z peek.location+1
- jsr peek
- sta.z __2
- ldx #spriteNumber
- jsr getBitNumber
- eor.z __2
- sta.z poke.value
- lda #0
- sta.z poke.value+1
- lda #<$d01d
- sta.z poke.location
- lda #>$d01d
- sta.z poke.location+1
- jsr poke
- rts
- }
- /**
- * Unset sprite double height (zero indexed)
- */
- spriteUnexpandY: {
- .const spriteNumber = 3
- .label __2 = $18
- lda #<$d017
- sta.z peek.location
- lda #>$d017
- sta.z peek.location+1
- jsr peek
- sta.z __2
- ldx #spriteNumber
- jsr getBitNumber
- eor.z __2
- sta.z poke.value
- lda #0
- sta.z poke.value+1
- lda #<$d017
- sta.z poke.location
- lda #>$d017
- sta.z poke.location+1
- jsr poke
- rts
- }
- /**
- * Will check for the current scan line
- * position; returns -1 if the parameter
- * sent is out of bounds (set to 312 assuming
- * PAL - valid range is therefore 0 - 311
- * assuming a zero index); 0 is returned if
- * not at that scan line, and 1 if the
- * parameter matches the current scan line
- *
- * @see setMachineType()
- */
- // checkForScanLine(word zp(6) scanLine)
- checkForScanLine: {
- .label currentScanLine = $19
- .label scanLine = 6
- lda.z scanLine+1
- cmp #>$137
- bne !+
- lda.z scanLine
- cmp #<$137
- !:
- bcc __b1
- beq __b1
- lda #$37
- cmp.z getMachineType
- beq __b7
- __b1:
- lda.z scanLine+1
- cmp #>$105
- bne !+
- lda.z scanLine
- cmp #<$105
- !:
- bcc __b2
- beq __b2
- lda #6
- cmp.z getMachineType
- beq __b7
- __b2:
- lda.z scanLine+1
- cmp #>$104
- bne !+
- lda.z scanLine
- cmp #<$104
- !:
- bcc __b3
- beq __b3
- lda #5
- cmp.z getMachineType
- beq __b7
- __b3:
- lda #<$d012
- sta.z peek.location
- lda #>$d012
- sta.z peek.location+1
- jsr peek
- sta.z currentScanLine
- lda #0
- sta.z currentScanLine+1
- lda #<$d011
- sta.z peek.location
- lda #>$d011
- sta.z peek.location+1
- jsr peek
- tax
- lda.z scanLine+1
- cmp #>$100
- bcc !+
- bne __b4
- lda.z scanLine
- cmp #<$100
- bcs __b4
- !:
- lda.z scanLine+1
- cmp.z currentScanLine+1
- bne __b4
- lda.z scanLine
- cmp.z currentScanLine
- bne __b4
- cpx #$80
- bcc __b8
- __b4:
- cpx #$7f+1
- bcc __b5
- lda.z scanLine+1
- bne __b6
- lda #$ff
- cmp.z scanLine
- bcc __b6
- __b5:
- lda #0
- rts
- __b7:
- lda #-1
- rts
- __b8:
- lda #1
- rts
- __b6:
- clc
- lda.z currentScanLine
- adc #<$100
- sta.z currentScanLine
- lda.z currentScanLine+1
- adc #>$100
- sta.z currentScanLine+1
- lda.z scanLine+1
- cmp.z currentScanLine+1
- bne __b5
- lda.z scanLine
- cmp.z currentScanLine
- bne __b5
- jmp __b8
- }
- /**
- * Simple wait function - will count down
- * to zero; accepted parameters is 1 - 65535
- */
- // wait(word zp(8) toWaitFor)
- wait: {
- .label toWaitFor = 8
- lda #<main.waitState
- sta.z toWaitFor
- lda #>main.waitState
- sta.z toWaitFor+1
- __b1:
- lda.z toWaitFor+1
- bne __b2
- lda.z toWaitFor
- bne __b2
- !:
- rts
- __b2:
- lda.z toWaitFor
- bne !+
- dec.z toWaitFor+1
- !:
- dec.z toWaitFor
- jmp __b1
- }
- /**
- * Sets the main sprite colour by
- * sprite numbe (zero indexed) and
- * colour (0 - 16) - will return
- * without altering if the spriteNumber
- * is 8 or over.
- */
- // setSpriteColour(byte register(A) spriteNumber, byte register(X) colour)
- setSpriteColour: {
- cmp #8
- bcs __breturn
- clc
- adc #<$d027
- sta.z poke.location
- lda #>$d027
- adc #0
- sta.z poke.location+1
- txa
- sta.z poke.value
- lda #0
- sta.z poke.value+1
- jsr poke
- __breturn:
- rts
- }
- /**
- * Will switch on a single sprite of the
- * eight available (zero indexed)
- */
- // switchOnSprites(byte register(X) spriteNumber)
- switchOnSprites: {
- .label __2 = $1b
- cpx #8
- bcs __breturn
- lda #<$d015
- sta.z peek.location
- lda #>$d015
- sta.z peek.location+1
- jsr peek
- sta.z __2
- jsr getBitNumber
- ora.z __2
- sta.z poke.value
- lda #0
- sta.z poke.value+1
- lda #<$d015
- sta.z poke.location
- lda #>$d015
- sta.z poke.location+1
- jsr poke
- __breturn:
- rts
- }
- /**
- * Positions a sprite at x pixels across
- * and y pixels down according to the
- * zero-indexed sprite number; note that
- * x can exceed 255
- */
- // spriteAt(word zp($12) x, byte zp($1d) y, byte zp($14) spriteNumber)
- spriteAt: {
- .label x = $12
- .label y = $1d
- .label spriteNumber = $14
- .label spriteBit = $1c
- .label spriteX = 6
- .label spriteY = $a
- ldx.z spriteNumber
- jsr getBitNumber
- sta.z spriteBit
- lda #<$d010
- sta.z peek.location
- lda #>$d010
- sta.z peek.location+1
- jsr peek
- tax
- txa
- and.z spriteBit
- tay
- lda #$ff
- cmp.z x
- bcc !+
- lda.z x+1
- beq __b4
- !:
- cpy #0
- bne !__b1+
- jmp __b1
- !__b1:
- __b4:
- cpx #0
- beq __b2
- cpy #1
- beq __b5
- jmp __b2
- __b5:
- txa
- sec
- sbc.z spriteBit
- sta.z poke.value
- lda #0
- sta.z poke.value+1
- lda #<$d010
- sta.z poke.location
- lda #>$d010
- sta.z poke.location+1
- jsr poke
- __b2:
- lda.z spriteNumber
- cmp #0
- beq __b8
- lda #<$d001
- sta.z spriteY
- lda #>$d001
- sta.z spriteY+1
- lda #<$d000
- sta.z spriteX
- lda #>$d000
- sta.z spriteX+1
- ldx #0
- __b6:
- cpx.z spriteNumber
- bcc __b7
- jmp __b3
- __b8:
- lda #<$d001
- sta.z spriteY
- lda #>$d001
- sta.z spriteY+1
- lda #<$d000
- sta.z spriteX
- lda #>$d000
- sta.z spriteX+1
- __b3:
- lda.z x
- sta.z poke.value
- lda.z x+1
- sta.z poke.value+1
- jsr poke
- lda.z spriteY
- sta.z poke.location
- lda.z spriteY+1
- sta.z poke.location+1
- lda.z y
- sta.z poke.value
- lda #0
- sta.z poke.value+1
- jsr poke
- rts
- __b7:
- lda #2
- clc
- adc.z spriteX
- sta.z spriteX
- bcc !+
- inc.z spriteX+1
- !:
- lda #2
- clc
- adc.z spriteY
- sta.z spriteY
- bcc !+
- inc.z spriteY+1
- !:
- inx
- jmp __b6
- __b1:
- txa
- ora.z spriteBit
- sta.z poke.value
- lda #0
- sta.z poke.value+1
- lda #<$d010
- sta.z poke.location
- lda #>$d010
- sta.z poke.location+1
- jsr poke
- jmp __b2
- }
- /**
- * Returns a single byte from a specific
- * memory location
- */
- // peek(word zp($c) location)
- peek: {
- .label location = $c
- ldy #0
- lda (location),y
- rts
- }
- /**
- * Returns the current screen location
- * based on the high bits of 0xd018
- */
- getScreenMemoryLocation: {
- .label return = $e
- .label screenPointer = $1d
- .label memoryLocation = $e
- lda #<$d018
- sta.z peek.location
- lda #>$d018
- sta.z peek.location+1
- jsr peek
- lsr
- lsr
- lsr
- lsr
- sta.z screenPointer
- lda #<0
- sta.z memoryLocation
- sta.z memoryLocation+1
- tax
- __b1:
- cpx.z screenPointer
- bcc __b2
- rts
- __b2:
- clc
- lda.z memoryLocation
- adc #<$400
- sta.z memoryLocation
- lda.z memoryLocation+1
- adc #>$400
- sta.z memoryLocation+1
- inx
- jmp __b1
- }
- /**
- * From a 16-bit start position, it will store
- * the byte value in toFill by a set number
- * of bytes
- */
- // fillMemory(word zp($e) startPosition)
- fillMemory: {
- .const toFill = $20
- .const numberOfBytes = $3e8
- .label index = $10
- .label startPosition = $e
- lda #<0
- sta.z index
- sta.z index+1
- __b1:
- lda.z index+1
- cmp #>numberOfBytes
- bcc __b2
- bne !+
- lda.z index
- cmp #<numberOfBytes
- bcc __b2
- !:
- rts
- __b2:
- lda.z startPosition
- clc
- adc.z index
- sta.z poke.location
- lda.z startPosition+1
- adc.z index+1
- sta.z poke.location+1
- lda #<toFill
- sta.z poke.value
- lda #>toFill
- sta.z poke.value+1
- jsr poke
- inc.z index
- bne !+
- inc.z index+1
- !:
- jmp __b1
- }
- /**
- * Returns a value from 0 - 7 as its binary
- * equivalent, for instance, sending 3 to
- * this function will return 4; sending 7
- * will return 128
- */
- // getBitNumber(byte register(X) bit)
- getBitNumber: {
- .const returnBit = 1
- lda #returnBit
- cpx #0
- beq !e+
- !:
- asl
- dex
- bne !-
- !e:
- rts
- }
Add Comment
Please, Sign In to add comment