; .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