Skip to content

Instantly share code, notes, and snippets.

@Lerc
Last active December 3, 2019 22:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Lerc/78d170a65bc6c9ddaecefa4424915ac3 to your computer and use it in GitHub Desktop.
Save Lerc/78d170a65bc6c9ddaecefa4424915ac3 to your computer and use it in GitHub Desktop.
Kwak-8 base program
low(x)=x & $ff
high(x)= ( x >> 8 ) & $ff
.def XH r27
.def XL r26
.def YH r29
.def YL r28
.def ZH r31
.def ZL r30
.macro rol reg
adc reg,reg
.endmacro
.macro lsl reg
add reg,reg
.endmacro
.macro clr reg
eor reg,reg
.endmacro
.macro tst reg
and reg,reg
.endmacro
.macro addi reg,imm
subi reg,-imm
.endmacro
.macro ldw ra,rb,address
lds rb,address
lds ra,address+1
.endmacro
.macro ldwi ra,rb,imm
ldi rb,low(imm)
ldi ra,high(imm)
.endmacro
.macro stw address,ra,rb
sts address,rb
sts address+1,ra
.endmacro
.macro ldx address
ldw r27:r26,address
.endmacro
.macro ldy address
ldw r29:r28,address
.endmacro
.macro ldz address
ldw r31:r30,address
.endmacro
.macro ldix imm
ldwi r27:r26,imm
.endmacro
.macro ldiy imm
ldwi r29:r28,imm
.endmacro
.macro ldiz imm
ldwi r31:r30,imm
.endmacro
.macro stx address
stw address,r27:r26
.endmacro
.macro sty address
stw address,r29:r28
.endmacro
.macro stz address
stw address,r31:r30
.endmacro
.macro pushx
push XL
push XH
.endmacro
.macro pushy
push YL
push YH
.endmacro
.macro pushz
push ZL
push ZH
.endmacro
.macro popx
pop XH
pop XL
.endmacro
.macro popy
pop YH
pop YL
.endmacro
.macro popz
pop ZH
pop ZL
.endmacro
.macro pushxy
pushx
pushy
.endmacro
.macro pushxz
pushx
pushz
.endmacro
.macro pushyz
pushy
pushz
.endmacro
.macro pushxyz
pushx
pushy
pushz
.endmacro
.macro popxy
popy
popx
.endmacro
.macro popxz
popz
popx
.endmacro
.macro popyz
popy
popz
.endmacro
.macro popxyz
popz
popy
popx
.endmacro
_let_data_start = $100
_let_data_address=_let_data_start
.snip _let_data
_let_data_initial_values:
.endsnip
.macro letb name value
name = _let_data_address
_let_data_address = _let_data_address + 1
.snip _let_data
.db value
.endsnip
.endmacro
.macro letw name value
_let_data_address = _let_data_address + (_let_data_address & 1)
name = _let_data_address
_let_data_address = _let_data_address + 2
.snip _let_data
.dw value
.endsnip
.endmacro
.snip _let_copy
copy_let_values_to_ram:
ldi r28,low(_let_data_start)
ldi r29,high(_let_data_start)
ldi r26,low(_let_data_address)
ldi r27,high(_let_data_address)
ldi r30,low(_let_data_initial_values)
ldi r31,high(_let_data_initial_values)
.lp:
lpm r0,Z+
st y+,r0
cp r28,r26
cpc r29,r27
brne .lp
ret
.endsnip
.macro load_let_values
.use _let_data
.use _let_copy
call copy_let_values_to_ram
.endmacro
port_InputBase = $10
port_Buttons1 = port_InputBase+0
port_Buttons2 = port_InputBase+1
port_MouseX = port_InputBase+2
port_MouseY = port_InputBase+3
port_FrameTick = port_InputBase+4
port_SecondsTick = port_InputBase+5
port_Console = port_InputBase+6
port_FrameBufferControl = $08
port_DisplayShiftX = $09
port_DisplayShiftX = $0A
port_BlitControl = $0B
port_SerialPixelAddress_L = $00
port_SerialPixelAddress_M = $01
port_SerialPixelAddress_H = $02
port_SerialPixelControl = $03
port_SerialPixelBase = $04
port_SerialPixelAdd = $05
port_SerialPixelSub = $06
port_SerialPixelMul = $07
fbc_ShowDisplay = 0
fbc_ShowHiresDisplay = 1
blitcon_Blit_8 = $1
blitcon_Blit_4 = $2
blitcon_Blit_3 = $3
blitcon_Blit_2 = $4
blitcon_Mode0 = $10
blitcon_Mode1 = $11
port_mode0_ImageData_L = $28
port_mode0_ImageData_H = $29
port_mode0_CellsWide = $2A
port_mode0_CellsHigh = $2B
port_mode0_LineIncrement= $2C
port_mode1_TileImage_L = $28
port_mode1_TileImage_H = $29
port_mode1_MapDataStart_L = $2A
port_mode1_MapDataStart_H = $2B
port_mode1_MapDataIncrement= $2C
port_mode1_Palettes_L = $2D
port_mode1_Palettes_H = $2E
port_mode1_Shift = $2F
port_blit_ImageData_L = $28
port_blit_ImageData_H = $29
port_blit_BytesWide = $2A
port_blit_Height = $2B
port_blit_LineIncement = $2C
port_blit_Palettes_L = $2D
port_blit_Palettes_H = $2E
port_blit_Flags = $2F
audio_Volume = $0c
voice_Select = $0d
voice_Base = $30
voice_Freq_L = voice_Base + $00
voice_Freq_H = voice_Base + $01
voice_Volume = voice_Base + $02
voice_WaveShape = voice_Base + $03
voice_BendWave = voice_Base + $04
voice_BendAmplitude = voice_Base + $05
voice_NoiseHold = voice_Base + $06
voice_AttackRelease = voice_Base + $07
RAMEND = $ffff
.snip WaitForFrame
vwait_:
push r0
push r1
in r1,port_FrameTick
.lp:
in r0,port_FrameTick
cp r0,r1
breq .lp
pop r1
pop r0
ret
.endsnip
.macro vwait
.use WaitForFrame
call vwait_
.endmacro
.macro set_stack_pointer value
ldi r28,low(value)
out $3d,r28
ldi r28,high(value)
out $3e,r28
eor r28,r28
out $3f,r28
.endmacro
.include "defs"
.include "kwak8"
.include "utility"
.include "scratch"
.use Mode0Code
.org 0
jmp init
.org $10
init:
set_stack_pointer RAMEND
load_let_values
letb last_time,0
in r0,port_SecondsTick
sts last_time,r0
print_rom "I am a fish"
mainloop:
call timeCheck
call renderMode0
call mouseDot
call showFrame
jmp mainloop
timeCheck:
pushx
in XL,port_SecondsTick
lds XH,last_time
cp XL,XH
breq .done
sts last_time,XL
call perSecond
.done:
popx
ret
perSecond:
print_rom " *** "
ret
mouseDot:
in r16,port_MouseX
in r17,port_MouseY
ldi r18,2
call plotPixel
ret
showFrame:
ldi r17,fbc_ShowDisplay
out port_FrameBufferControl,r17
vwait
ret
.snip small_constant_divides
.use divider
scaledReciprocal(x) = round($80000 / x);
.macro divByN n
// X/n => r19:r18
ldi r17,n
ldiy scaledReciprocal(n)
jmp DivUsingReciprocal
.endmacro
DivBy9: divByN 9
DivBy10: divByN 10
DivBy11: divByN 11
DivBy12: divByN 12
DivBy13: divByN 13
DivBy14: divByN 14
DivBy15: divByN 15
DivBy16: divByN 16
.endsnip
.snip divider
DivUsingReciprocal:
push r17
; Q = X * Y
; (r19:r18:r17[:rXX] = XH:XL * YH:YL)
clr r2
mul XH, YH ; ah * bh
movw r19:r18, r1:r0
mul XL, YL ; al * bl
mov r17,r1 ; r0 to [rXX] is superfluous
mul XH, YL ; ah * bl
add r17, r0
adc r18, r1
adc r19, r2
mul YH, XL ; bh * al
add r17, r0
adc r18, r1
adc r19, r2
; Q = Q >> 16: use r19:r18 as word
; Q = Q >> 3
lsr r19 ; do the last 3 shifts
ror r18
lsr r19
ror r18
lsr r19
ror r18
;calc remainder my mult and sub
pop r17
mul r18,r17
mov r17,XL
sub r17,r0
ret // result r19:r18 remainder r17
.endsnip
.snip print_numbers
.use small_constant_divides
PrintUint16:
// r16=x r17=y r19:r18 =Uint16 r20=attr
push r8
clr r8
movw W,r17:r16
movw X,r19:r18
.lp:
call DivBy10
push r17
movw X,r19:r18
inc r8
clr r0
cp r18,r0
cpc r19,r0
brne .lp
mov r19,r20
.writelp:
pop r18
movw r17:r16,W
addi r24,2
call drawDigit
dec r8
brne .writelp
pop r8
ret
.endsnip
.snip pixels
plotPixel:
//r16 = x, r17=y, r18 = color
call setPixelCursor
out port_SerialPixelAdd, r18
ret
setPixelCursor:
push r16
push r17
out port_SerialPixelAddress_L,r16
sub r16,r16
add r17,r17
adc r16,r16
out port_SerialPixelAddress_M,r17
out port_SerialPixelAddress_H,r16
pop r17
pop r16
ret
.endsnip
.snip font
FontData:
.byte $00,$00,$00,$00,$00,$00,$00
.byte $80,$df,$00,$24,$00,$04,$00
.byte $00,$90,$48,$02,$01,$00,$00
.byte $20,$90,$48,$28,$cb,$12,$09
.byte $a8,$8b,$88,$ca,$88,$ca,$0a
.byte $00,$aa,$90,$a0,$81,$02,$15
.byte $00,$70,$40,$71,$c1,$31,$11
.byte $80,$df,$00,$04,$00,$00,$00
.byte $a0,$ff,$08,$db,$00,$04,$08
.byte $00,$20,$40,$00,$49,$20,$01
.byte $00,$40,$80,$ba,$59,$01,$02
.byte $a0,$ff,$00,$c3,$18,$04,$00
.byte $28,$00,$00,$ff,$40,$ff,$09
.byte $00,$00,$00,$38,$18,$00,$00
.byte $20,$00,$00,$ff,$40,$04,$01
.byte $00,$00,$90,$a0,$01,$02,$00
.byte $00,$a0,$88,$92,$92,$04,$01
.byte $a0,$5f,$00,$db,$00,$06,$01
.byte $20,$a0,$88,$ff,$0a,$06,$03
.byte $00,$30,$58,$04,$91,$06,$01
.byte $a0,$ff,$48,$35,$c9,$00,$01
.byte $00,$b0,$18,$06,$91,$06,$01
.byte $00,$a0,$08,$96,$91,$04,$01
.byte $20,$30,$98,$ff,$0a,$04,$00
.byte $00,$a0,$88,$94,$91,$04,$01
.byte $00,$a0,$88,$22,$9a,$04,$01
.byte $a0,$ff,$40,$fb,$41,$04,$01
.byte $a8,$ff,$40,$fb,$41,$ff,$09
.byte $20,$00,$c0,$71,$00,$00,$03
.byte $20,$00,$00,$38,$c3,$00,$00
.byte $20,$c0,$00,$fb,$51,$03,$00
.byte $00,$14,$91,$24,$01,$04,$00
.byte $00,$70,$48,$6d,$0a,$06,$01
.byte $00,$a0,$40,$79,$9a,$01,$02
.byte $00,$78,$88,$4f,$91,$07,$01
.byte $00,$a0,$88,$92,$80,$04,$01
.byte $00,$b0,$88,$92,$92,$06,$01
.byte $00,$b0,$18,$96,$01,$06,$03
.byte $00,$b0,$18,$96,$01,$02,$00
.byte $00,$a0,$88,$92,$98,$04,$01
.byte $00,$90,$90,$96,$93,$02,$02
.byte $a0,$cf,$08,$db,$00,$06,$01
.byte $00,$20,$58,$40,$49,$06,$00
.byte $00,$90,$50,$96,$88,$02,$02
.byte $00,$90,$00,$92,$00,$06,$03
.byte $00,$c8,$d0,$6d,$92,$01,$02
.byte $80,$6f,$90,$92,$93,$02,$02
.byte $00,$70,$88,$49,$92,$06,$01
.byte $00,$b0,$88,$b2,$0a,$02,$00
.byte $00,$a0,$88,$b2,$d2,$04,$11
.byte $00,$b0,$88,$b2,$8a,$02,$02
.byte $00,$a0,$88,$84,$88,$04,$01
.byte $a0,$c7,$18,$db,$00,$04,$00
.byte $00,$90,$90,$92,$92,$04,$01
.byte $20,$90,$90,$cd,$5a,$04,$01
.byte $00,$48,$90,$ed,$d2,$01,$02
.byte $00,$88,$50,$a4,$40,$01,$02
.byte $20,$48,$90,$dd,$01,$04,$00
.byte $00,$30,$98,$a0,$01,$06,$03
.byte $00,$b0,$08,$92,$00,$06,$01
.byte $00,$90,$00,$04,$88,$00,$02
.byte $00,$30,$48,$00,$49,$06,$01
.byte $00,$a0,$40,$01,$02,$00,$00
.byte $08,$00,$00,$00,$00,$3f,$c0
.byte $00,$20,$40,$00,$00,$00,$00
.byte $00,$00,$00,$94,$93,$04,$03
.byte $00,$90,$00,$96,$91,$06,$01
.byte $00,$00,$00,$94,$03,$04,$03
.byte $00,$00,$90,$94,$93,$04,$03
.byte $20,$00,$00,$6b,$19,$04,$03
.byte $a0,$ff,$88,$cb,$08,$04,$00
.byte $08,$00,$00,$94,$91,$fb,$53
.byte $00,$90,$00,$96,$91,$02,$02
.byte $20,$20,$00,$d9,$00,$06,$01
.byte $08,$00,$08,$04,$49,$ef,$09
.byte $00,$90,$00,$b2,$41,$02,$02
.byte $a0,$cf,$00,$db,$00,$06,$01
.byte $20,$00,$00,$94,$91,$01,$02
.byte $00,$00,$00,$96,$91,$02,$02
.byte $00,$00,$00,$94,$91,$04,$01
.byte $00,$00,$00,$96,$91,$96,$01
.byte $00,$00,$00,$94,$93,$04,$93
.byte $00,$00,$00,$b2,$11,$02,$00
.byte $00,$00,$00,$34,$c3,$06,$01
.byte $a0,$df,$00,$d9,$81,$00,$01
.byte $00,$00,$00,$92,$92,$04,$03
.byte $20,$00,$00,$ed,$52,$04,$01
.byte $20,$00,$00,$96,$92,$02,$01
.byte $20,$00,$00,$dd,$4a,$02,$02
.byte $08,$00,$00,$92,$92,$eb,$53
.byte $20,$00,$00,$f9,$0b,$06,$03
.byte $a0,$df,$01,$dd,$00,$00,$01
.byte $a0,$df,$00,$db,$00,$24,$00
.byte $a0,$dd,$00,$df,$01,$02,$00
.byte $80,$ff,$80,$02,$01,$00,$00
.byte $00,$40,$80,$ba,$59,$01,$02
.endsnip
.snip Mode0Code
.use pixels
.use font
letw mode0_Page,$8000
letb mode0_Width,80
letb mode0_Height,60
letb mode0_DisplayLeft,0
letb mode0_DisplayTop,0
letb mode0_CursorX,0
letb mode0_CursorY,0
letb mode0_Color,$20
renderMode0:
push r16
push r17
push r24
push r25
push r26
push r27
ldx mode0_Page
out port_mode0_ImageData_L,r26
out port_mode0_ImageData_H,r27
lds r26,mode0_Width
out port_mode0_CellsWide,r26
out port_mode0_LineIncrement,r26
out port_mode0_LineIncrement+1,r26
out port_mode0_LineIncrement+2,r26
out port_mode0_LineIncrement+3,r26
lds r26,mode0_Height
out port_mode0_CellsHigh,r26
lds r16,mode0_DisplayLeft
lds r17,mode0_DisplayTop
call setPixelCursor
ldi r26,blitcon_Mode0
out port_BlitControl,r26
pop r27
pop r26
pop r25
pop r24
pop r17
pop r16
ret
drawDigit:
addi r18,48
drawChar:
// r16=x r17=y r18=char r19=attr
push r24
push r25
push r26
push r27
push r28
push r29
push r30
push r31
clr r3
lds r2,mode0_Width
lsl r2
adc r3,r3 // r2:r3 has line width in bytes
mul r3,r17
mov r4,r0
mul r2,r17
add r1,r4 // r0:r1 is y* linewidth
movw r25:r24,r1:r0
//add r24,r0
//adc r25,r1
//add r24,r0
//adc r25,r1
clr r1
add r24,r16
adc r25,r1
add r24,r16
adc r25,r1 // r24:r25 is now y*linewidth*3+x*2
ldx mode0_Page
add r26,r24
adc r27,r25
movw y,x
subi r18,32
ldi r31,7
mul r18,r31
ldiz FontData
add r30,r0
adc r31,r1
lpm r0,Z+
rcall .cell
rcall .cell
add r28,r2
adc r29,r3
movw X,Y
rcall .cell
rcall .cell
add r28,r2
adc r29,r3
movw X,Y
rcall .cell
rcall .cell
pop r31
pop r30
pop r29
pop r28
pop r27
pop r26
pop r25
pop r24
ret
.cell:
lpm r1,Z+
st X+,r1
sbrs r0,7
swap r19
st X+,r19
sbrs r0,7
swap r19
lsl r0
ret
drawRomString:
// r16=x r17=y r19:r18=string r20=attr
movw W, r17:r16
movw Z, r19:r18
mov r26,r20
.lp:
movw r17:r16,W
lpm r18,Z+
cpi r18,0
breq .done
mov r19,r26
call drawChar
addi r24,2
jmp .lp
.done:
ret
lineFeed:
pushxyz
clr r3
lds r2,mode0_Width
lsl r2
adc r3,r3 // r3:r2 has line width in bytes
ldx mode0_Page
movw y,x
add YL,r2
adc YH,r3
add YL,r2
adc YH,r3
add YL,r2
adc YH,r3
lds ZL,mode0_Height
dec ZL
mov ZH,ZL
add ZH,ZL
add ZH,ZL
.lineLoop:
lds r1,mode0_Width
lsr r1
brcc .lp
ld r0,Y+
st x+,r0
ld r0,Y+
st x+,r0
.lp:
ld r0,Y+
st x+,r0
ld r0,Y+
st x+,r0
ld r0,Y+
st x+,r0
ld r0,Y+
st x+,r0
dec r1
brne .lp
dec ZH
brne .lineLoop
popxyz
ret
newLine:
clr r16
sts mode0_CursorX,r16
lds r16,mode0_CursorY
addi r16,3
lds r17,mode0_Height
dec r17
dec r17
cp r16,r17
brlo .writeback
dec r17
call lineFeed
mov r16,r17
.writeback:
sts mode0_CursorY,r16
ret
advanceCursor:
lds r16,mode0_CursorX
addi r16,2
sts mode0_CursorX,r16
lds r17,mode0_Width
cp r16, r17
brlo .done
call newLine
.done:
ret
printRomString:
//r17:r16 = string
movw Z,r17:r16
.lp:
lds r16,mode0_CursorX
lds r17,mode0_CursorY
lds r19,mode0_Color
lpm r18,Z+
cpi r18,0
breq .done
call drawChar
call advanceCursor
jmp .lp
.done:
ret
.endsnip
_rom_strings_offset = 0
.snip _rom_strings
_rom_strings_start:
.endsnip
.macro print_rom text
.use _rom_strings
.snip _rom_strings
.db text,0
.endsnip
ldwi r17:r16,_rom_strings_start+_rom_strings_offset
call printRomString
_rom_strings_offset = _rom_strings_offset + norm(size(text)) +1
.endmacro
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment