350 lines
4.9 KiB
NASM
350 lines
4.9 KiB
NASM
// vim: filetype=kickass
|
|
|
|
*=* "Screen Routines"
|
|
|
|
//
|
|
// clear_screen
|
|
//
|
|
// Destroys: a, y
|
|
//
|
|
clear_screen:
|
|
lda #$06
|
|
sta $d021
|
|
lda #$0e
|
|
sta $d020
|
|
|
|
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 cursor_pointer_lo
|
|
adc #40
|
|
sta cursor_pointer_lo
|
|
bcc !done+
|
|
inc cursor_pointer_hi
|
|
!done:
|
|
// fallthrough
|
|
|
|
|
|
//
|
|
// 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+
|
|
|
|
iny
|
|
|
|
cmp #'\r'
|
|
beq !carriage_return+
|
|
cmp #'\n'
|
|
beq !newline+
|
|
|
|
sta (cursor_pointer_lo, x)
|
|
i16_inc(cursor_pointer_lo)
|
|
jmp !loop-
|
|
|
|
!newline:
|
|
jsr print_newline
|
|
jmp !loop-
|
|
|
|
!carriage_return:
|
|
jsr print_carriage_return
|
|
jmp !loop-
|
|
|
|
!done:
|
|
rts
|
|
|
|
|
|
.macro i16_print_hex_0x(addr) {
|
|
lda addr + 1
|
|
jsr print_hex_0x
|
|
lda addr
|
|
jsr print_hex
|
|
}
|
|
|
|
// Destroys: a, x, y, zp_temp ($02)
|
|
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"
|
|
|
|
|
|
// Input:
|
|
// - $03..$04: The number to print
|
|
//
|
|
// Destroys: a, y, $24..$25
|
|
print_decimal_u16:
|
|
ldy #6
|
|
|
|
// Null-terminate the buffer
|
|
lda #0
|
|
sta !buffer+, y
|
|
|
|
!loop:
|
|
u16_div10()
|
|
u16_u16_move($22, $24)
|
|
i16_mul10($22)
|
|
|
|
i16_i16_sub($22, $23, $03, $04, $22, $23)
|
|
|
|
u16_u16_move($03, $24)
|
|
|
|
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
|
|
//
|
|
// Destroys: a, y, $02..$04, $10..$2b
|
|
//
|
|
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
|
|
|
|
wait_space_then_reset:
|
|
ldx #$ff
|
|
stx $dc02
|
|
ldy #$00
|
|
sty $dc03
|
|
|
|
!:
|
|
lda #$7f
|
|
sta $dc00
|
|
lda $dc01
|
|
and #$10
|
|
bne !-
|
|
|
|
move_16_imm($03, !str_resetting+)
|
|
jsr write_string
|
|
|
|
// Reset
|
|
lda #%00110111
|
|
sta $01
|
|
jmp $fce2
|
|
|
|
rts
|
|
|
|
!str_resetting:
|
|
.byte '\n'
|
|
.text "Resetting..."
|
|
.byte 0
|
|
|
|
str_part2:
|
|
.byte '\n'
|
|
.text "Part 2: "
|
|
.byte 0
|
|
|
|
str_done:
|
|
.byte '\n', '\n'
|
|
.text "* Done"
|
|
.byte '\n', 0
|