2020/c64/screen.asm

310 lines
4.2 KiB
NASM

// vim: filetype=kickass
*=* "Screen Routines"
//
// clear_screen
//
// Destroys: a, y
//
clear_screen:
ldy #0
!loop:
lda #' '
sta SCREEN_RAM, y
sta SCREEN_RAM + $0100, y
sta SCREEN_RAM + $0200, y
sta SCREEN_RAM + $0300, y
sta SCREEN_RAM + $03e7, y
lda #1
sta COLOR_RAM, y
sta COLOR_RAM + $0100, y
sta COLOR_RAM + $0200, y
sta COLOR_RAM + $0300, y
sta COLOR_RAM + $03e7, y
iny
bne !loop-
lda #<SCREEN_RAM
sta cursor_pointer_lo
lda #>SCREEN_RAM
sta cursor_pointer_hi
lda #23
sta $d018
rts
//
// print_carriage_return
//
// Input:
// - cursor_pointer_{lo,hi} - Cursor pointer.
//
// Destroys: a, zp_temp
//
print_newline:
sec
lda $05
adc #40
sta cursor_pointer_lo
bcc !done+
inc cursor_pointer_hi
!done:
//
// print_carriage_return
//
// Input:
// - cursor_pointer_{lo,hi} - Cursor pointer.
//
// Destroys: a, zp_temp
//
print_carriage_return:
// Subtract SCREEN_RAM from cursor pointer
sec
lda cursor_pointer_hi
sbc #>SCREEN_RAM
sta cursor_pointer_hi
// Divide the cursor position by 40 (one row)
i16_div8(cursor_pointer_lo, cursor_pointer_hi)
// At this point, the pointer fits in a 8-bit register
lda cursor_pointer_lo
i8_div5_a()
// Multiply it by 40 again
i8_mul5_a()
sta cursor_pointer_lo
i16_mul8(cursor_pointer_lo, cursor_pointer_hi)
// Add SCREEN_RAM back
clc
lda cursor_pointer_hi
adc #>SCREEN_RAM
sta cursor_pointer_hi
rts
//
// write_string
//
// Input:
// - $03-$04 - Pointer to null-terminated string.
// - $05-$06 - Cursor pointer.
//
// Destroys: a, x, y, $02
//
write_string:
ldx #0
ldy #0
!loop:
lda ($03), y
beq !done+
cmp #'\r'
beq !carriage_return+
cmp #'\n'
beq !newline+
sta (cursor_pointer_lo, x)
i16_inc(cursor_pointer_lo)
iny
jmp !loop-
!newline:
jsr print_newline
!carriage_return:
jsr print_carriage_return
iny
jmp !loop-
!done:
rts
.macro i16_print_hex_0x(lo, hi) {
lda hi
jsr print_hex_0x
lda lo
jsr print_hex
}
// Destroys: a, x, y, $03
print_hex_0x:
sta zp_temp
ldx #0
lda #'0'
sta (cursor_pointer_lo, x)
i16_inc(cursor_pointer_lo)
lda #'x'
sta (cursor_pointer_lo, x)
i16_inc(cursor_pointer_lo)
lda zp_temp
// fallthrough
print_hex:
ldx #0
sta zp_temp
lsr
lsr
lsr
lsr
tay
lda !hex_chars+, y
sta (cursor_pointer_lo, x)
i16_inc(cursor_pointer_lo)
lda zp_temp
and #$0f
tay
lda !hex_chars+, y
sta (cursor_pointer_lo, x)
i16_inc(cursor_pointer_lo)
rts
!hex_chars:
.text "0123456789ABCDEF"
print_decimal_u16:
ldy #6
// Null-terminate the buffer
lda #0
sta !buffer+, y
!loop:
u16_div10()
lda $24
sta $22
lda $25
sta $23
i16_mul10($22)
i16_i16_sub($22, $23, $03, $04, $22, $23)
lda $24
sta $03
lda $25
sta $04
lda $22
clc
adc #'0'
sta !buffer+ - 1, y
dey
bne !loop-
// Find the first digit
ldy #0
!:
lda !buffer+, y
iny
cmp #'0'
beq !-
dey
tya
clc
adc #<(!buffer+)
sta $03
lda #0
adc #>(!buffer+)
sta $04
jsr write_string
rts
//
// Input:
// - udivmod32_dividend - Number to print
print_decimal_u32:
ldy #11
// Null-terminate the buffer
lda #0
sta !buffer+, y
lda #0
sta udivmod32_divisor + 3
sta udivmod32_divisor + 2
sta udivmod32_divisor + 1
lda #10
sta udivmod32_divisor + 0
!loop:
jsr udivmod32
lda udivmod32_remainder
clc
adc #'0'
sta !buffer+ - 1, y
lda udivmod32_result + 0
sta udivmod32_dividend + 0
lda udivmod32_result + 1
sta udivmod32_dividend + 1
lda udivmod32_result + 2
sta udivmod32_dividend + 2
lda udivmod32_result + 3
sta udivmod32_dividend + 3
dey
bne !loop-
// Find the first digit
ldy #0
!:
lda !buffer+, y
iny
cmp #'0'
beq !-
dey
tya
clc
adc #<(!buffer+)
sta $03
lda #0
adc #>(!buffer+)
sta $04
jsr write_string
rts
!buffer:
.fill 12, 0