216 lines
3.8 KiB
NASM
216 lines
3.8 KiB
NASM
; .setcpu "65C02"
|
|
.include "./macro.inc"
|
|
|
|
.org $8000
|
|
|
|
n = $01 ; temporary storage for data stack operations
|
|
|
|
temp = $20 ; scratchpad page
|
|
str_ptr = $30
|
|
|
|
cursor = $300
|
|
cursor_x = cursor
|
|
cursor_y = cursor + 1
|
|
|
|
char_buf = $302
|
|
char_buf_index = char_buf + 8
|
|
|
|
reset:
|
|
sei
|
|
ldx #0; initialize data stack pointer
|
|
|
|
init:
|
|
lda #$31
|
|
sta str_ptr
|
|
lda #$80
|
|
sta str_ptr + 1
|
|
|
|
jsr clear
|
|
lda #0
|
|
sta cursor_x
|
|
lda #0
|
|
sta cursor_y
|
|
cli
|
|
|
|
main:
|
|
jsr print
|
|
jmp main
|
|
|
|
newline: ; sets cursor to start of next line
|
|
stz cursor_x
|
|
lda cursor_y
|
|
cmp #28
|
|
bne .end
|
|
stz cursor_y
|
|
rts
|
|
.end:
|
|
inc cursor_y
|
|
rts
|
|
|
|
text:
|
|
.asciiz "hello <3"
|
|
|
|
; increments the cursor line by line, looping to (0, 0) after (63, 28)
|
|
|
|
inc_cursor:
|
|
lda cursor_x
|
|
cmp #63
|
|
beq .newline
|
|
inc cursor_x
|
|
rts
|
|
.newline:
|
|
lda cursor_y
|
|
cmp #28
|
|
beq .newscreen
|
|
stz cursor_x
|
|
inc cursor_y
|
|
rts
|
|
.newscreen:
|
|
stz cursor_y
|
|
stz cursor_x
|
|
rts
|
|
|
|
; zeroes out the display, resets cursor to 0,0
|
|
|
|
clear:
|
|
lda #0
|
|
ldy #0
|
|
|
|
.loop:
|
|
sta $6000,y
|
|
sta $6100,y
|
|
sta $6200,y
|
|
sta $6300,y
|
|
sta $6400,y
|
|
sta $6500,y
|
|
sta $6600,y
|
|
sta $6700,y ; this goes slightly over but it's fine
|
|
iny
|
|
bne .loop
|
|
stz cursor
|
|
stz cursor + 1
|
|
rts
|
|
|
|
|
|
; prints string from cursor position, stopping at end of string or at 256 chars, whichever comes first
|
|
; $6000 + (64*Y) + X
|
|
; THIS WILL WRITE OUT OF BOUNDS IF THE CURSOR IS OUT OF BOUNDS/STRING IS TOO LONG
|
|
|
|
; TODO: figure out a simple way of writing arbitrary length strings
|
|
; and
|
|
|
|
print:
|
|
jsr cursor_addr
|
|
ldy #0
|
|
; y_overflow = temp + 5
|
|
.loop:
|
|
lda (str_ptr), y
|
|
beq .end
|
|
sta (temp), y
|
|
iny
|
|
bra .loop
|
|
.end:
|
|
rts
|
|
|
|
|
|
; calculates real vram address from cursor (x, y)
|
|
|
|
cursor_addr:
|
|
stz temp
|
|
stz temp + 1
|
|
lda cursor_y
|
|
beq .add_x ; if y's zero just add x
|
|
.y_mult:
|
|
; multiply by 64
|
|
clc
|
|
asl
|
|
rol temp + 1
|
|
asl
|
|
rol temp + 1
|
|
asl
|
|
rol temp + 1
|
|
asl
|
|
rol temp + 1
|
|
asl
|
|
rol temp + 1
|
|
asl
|
|
rol temp + 1
|
|
sta temp
|
|
.add_x:
|
|
clc
|
|
lda cursor_x
|
|
adc temp
|
|
sta temp
|
|
lda #0
|
|
adc temp + 1
|
|
sta temp + 1
|
|
clc
|
|
|
|
lda #$60
|
|
adc temp + 1
|
|
sta temp + 1
|
|
rts
|
|
|
|
|
|
|
|
; print_text:
|
|
; lda text,y
|
|
; beq .end
|
|
; sta $6000, y
|
|
; iny
|
|
; bra print_text
|
|
; .end:
|
|
; ldy #0
|
|
; rts
|
|
|
|
; draw_char: ; draw a character c at (x, y) (n1: x n2: y n3: c -- )
|
|
; lda 0, x ; load a with character to draw
|
|
; pop ; and pop it off the stack
|
|
; jsr get_char_address ; calculate where to put the character in memory
|
|
; sta (0, x) ; store a at the address pointed to on the stack
|
|
; rts
|
|
|
|
; get_char_address: ; gets vram address for a character at (x, y),
|
|
; ; (n1: x n2: y -- n: $6000 + x + (64 * y))
|
|
; ;jsr push_lit ; push 64 onto stack, low byte first
|
|
; ;.byte 64
|
|
; ;.byte 0
|
|
; pha
|
|
; lda #64
|
|
; push ; doing this instead until `push_lit` is fixed
|
|
; sta 0, x
|
|
; stz 1, x
|
|
; jsr mult ; multiply 64 with y (n2)
|
|
; jsr plus ; add result with x (n1)
|
|
|
|
; ;jsr push_lit ; push vram address onto the stack
|
|
; ;.byte $00
|
|
; ;.byte $60
|
|
; lda #$60
|
|
; push
|
|
; sta 1, x
|
|
; stz 0, x
|
|
; jsr plus ; add vram start address to result
|
|
|
|
; pla
|
|
; rts
|
|
|
|
; fill: ; fills an area from (x1, y1) to (x2, y2) will character c, (n1: c n2: x1 n3: y1 n4: x2 n5: y2 -- )
|
|
; jsr get_char_address
|
|
|
|
isr: ; interrupt service routine
|
|
pha
|
|
phx
|
|
phy
|
|
; jsr irq
|
|
ply
|
|
plx
|
|
pla
|
|
rti
|
|
|
|
.include "math.inc"
|
|
|
|
.org $fffc
|
|
.word reset
|
|
.word isr
|