238 lines
4.3 KiB
ArmAsm
238 lines
4.3 KiB
ArmAsm
; Function defined on pp272-273 of C64 Programmers Reference Guide
|
|
chrout:
|
|
;; Crude implementation of character output
|
|
|
|
;; Save X and Y values
|
|
;; (Confirmed by writing a test program that X and Y
|
|
;; don't get modified, in agreement with C64 PRG's
|
|
;; description of CHROUT)
|
|
sta last_printed_character_ascii
|
|
txa
|
|
pha
|
|
tya
|
|
pha
|
|
|
|
jsr hide_cursor_if_visible
|
|
|
|
lda last_printed_character_ascii
|
|
tax
|
|
|
|
;; Check for special characters
|
|
|
|
cmp #$00
|
|
bne not_00
|
|
jmp chrout_done
|
|
not_00:
|
|
|
|
;; Linefeed (simply ignored)
|
|
;; Trivia: BASIC does CRLF with READY. prompt
|
|
cmp #$0a
|
|
bne not_0a
|
|
jmp chrout_done
|
|
not_0a:
|
|
|
|
;; Carriage return
|
|
cmp #$0d
|
|
bne not_0d
|
|
jmp screen_advance_to_next_line
|
|
not_0d:
|
|
|
|
;; Check for cursor movement keys
|
|
cmp #$11
|
|
bne not_11
|
|
inc current_screen_y
|
|
jsr calculate_screen_line_pointer
|
|
jmp chrout_done
|
|
not_11:
|
|
cmp #$1d
|
|
bne not_1d
|
|
inc current_screen_x
|
|
jsr calculate_screen_line_pointer
|
|
jmp chrout_done
|
|
not_1d:
|
|
cmp #$91
|
|
bne not_91
|
|
dec current_screen_y
|
|
jsr calculate_screen_line_pointer
|
|
jmp chrout_done
|
|
not_91:
|
|
cmp #$9d
|
|
bne not_9d
|
|
dec current_screen_x
|
|
jsr calculate_screen_line_pointer
|
|
jmp chrout_done
|
|
not_9d:
|
|
|
|
cmp #$14
|
|
bne not_14
|
|
|
|
;; Delete
|
|
ldx current_screen_x
|
|
bne delete_non_zero_column
|
|
delete_at_column_0:
|
|
ldy current_screen_y
|
|
bne not_row_0
|
|
;; delete from row 0, col 0 does nothing
|
|
jmp chrout_done
|
|
not_row_0:
|
|
dec current_screen_y
|
|
lda screen_line_link_table,y
|
|
bpl line_not_linked_del
|
|
lda #79
|
|
.byte $2c ; BIT absolute mode, which we use to skip the next two instruction bytes
|
|
line_not_linked_del:
|
|
lda #39
|
|
sta current_screen_x
|
|
jsr calculate_screen_line_pointer
|
|
jmp chrout_done
|
|
|
|
delete_non_zero_column:
|
|
jmp chrout_done
|
|
|
|
not_14:
|
|
|
|
;; Home cursor
|
|
cmp #$13
|
|
bne not_13
|
|
lda #0
|
|
sta current_screen_x
|
|
sta current_screen_y
|
|
jsr calculate_screen_line_pointer
|
|
jmp chrout_done
|
|
not_13:
|
|
|
|
;; Clear screen
|
|
cmp #$93
|
|
bne not_clearscreen
|
|
jsr clear_screen
|
|
jmp chrout_done
|
|
|
|
not_clearscreen:
|
|
|
|
;; Convert PETSCII to screen code
|
|
cmp #$40
|
|
bcc chrout_l1
|
|
cmp #$41+26
|
|
bcs chrout_l1
|
|
and #$1f
|
|
|
|
chrout_l1:
|
|
;; Write normal character on the screen
|
|
ldy current_screen_x
|
|
sta (current_screen_line_ptr),y
|
|
|
|
;; XXX - Update colour RAM also
|
|
|
|
;; Advance the column, and scroll screen down if we need
|
|
;; to insert a 2nd line in this logical line.
|
|
;; (eg Compute's Mapping the 64 p41)
|
|
ldx current_screen_y
|
|
iny
|
|
sty current_screen_x
|
|
cpy #40
|
|
bne no_screen_advance_to_next_line
|
|
jsr screen_grow_logical_line
|
|
cpy #79
|
|
bcc no_screen_advance_to_next_line
|
|
jmp screen_advance_to_next_line
|
|
no_screen_advance_to_next_line:
|
|
chrout_done:
|
|
;; Restore X and Y, set carry to mark success on exit
|
|
pla
|
|
tay
|
|
pla
|
|
tax
|
|
lda last_printed_character_ascii
|
|
clc ; indicate success
|
|
rts
|
|
|
|
screen_grow_logical_line:
|
|
;; XXX - Scroll screen down to make space
|
|
|
|
rts
|
|
|
|
screen_advance_to_next_line:
|
|
;; Go to start of line
|
|
lda #0
|
|
sta current_screen_x
|
|
;; Advance line number
|
|
ldy current_screen_y
|
|
inc current_screen_y
|
|
|
|
jsr calculate_screen_line_pointer
|
|
|
|
;; Work out if we have gone off the bottom of the screen?
|
|
;; 1040 > 1024, so if high byte of screen pointer is >= (HIBASE+4),
|
|
;; then we are off the bottom of the screen
|
|
lda current_screen_line_ptr+1
|
|
sec
|
|
sbc HIBASE
|
|
cmp #3
|
|
bcc +
|
|
|
|
;; Off the bottom of the screen
|
|
jsr scroll_screen_up
|
|
|
|
*
|
|
jmp chrout_done
|
|
|
|
scroll_screen_up:
|
|
;; XXX - Not implemented
|
|
rts
|
|
|
|
calculate_screen_line_pointer:
|
|
;; Reset pointer to start of screen
|
|
lda HIBASE
|
|
sta current_screen_line_ptr+1
|
|
lda #0
|
|
sta current_screen_line_ptr+0
|
|
|
|
;; Add 40 for every line, or 80 if the lines are linked
|
|
ldx current_screen_y
|
|
*
|
|
;; Stop if we have counted enough lines
|
|
beq +
|
|
|
|
;; Add 40 or 80 based on whether the line is linked
|
|
;; or not.
|
|
ldy #40
|
|
lda screen_line_link_table,x
|
|
bpl cslp_l1
|
|
ldy #80
|
|
cslp_l1:
|
|
;; Add computed line length to pointer value
|
|
tya
|
|
clc
|
|
adc current_screen_line_ptr+0
|
|
sta current_screen_line_ptr+0
|
|
lda current_screen_line_ptr+1
|
|
adc #0
|
|
sta current_screen_line_ptr+1
|
|
|
|
;; Loop back to next line
|
|
dex
|
|
jmp -
|
|
*
|
|
rts
|
|
|
|
|
|
retreat_screen_pointer_40_bytes:
|
|
lda current_screen_line_ptr+0
|
|
sec
|
|
sbc #<40
|
|
sta current_screen_line_ptr+0
|
|
lda current_screen_line_ptr+1
|
|
sbc #>40
|
|
sta current_screen_line_ptr+1
|
|
rts
|
|
|
|
advance_screen_pointer_40_bytes:
|
|
lda current_screen_line_ptr+0
|
|
clc
|
|
adc #<40
|
|
sta current_screen_line_ptr+0
|
|
lda current_screen_line_ptr+1
|
|
adc #>40
|
|
sta current_screen_line_ptr+1
|
|
rts
|