895 lines
14 KiB
ArmAsm
895 lines
14 KiB
ArmAsm
|
|
//
|
|
// Official Kernal routine, described in:
|
|
//
|
|
// - [RG64] C64 Programmer's Reference Guide - page 278/279
|
|
// - [CM64] Compute's Mapping the Commodore 64 - page 228
|
|
//
|
|
// CPU registers that has to be preserved (see [RG64]): .Y
|
|
//
|
|
|
|
|
|
chrout_real:
|
|
|
|
sta SCHAR
|
|
|
|
// 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)
|
|
txa
|
|
pha
|
|
tya
|
|
pha
|
|
php
|
|
|
|
// Determine the device number
|
|
lda DFLTO
|
|
|
|
cmp #$03 // screen
|
|
beq chrout_screen
|
|
|
|
jsr iec_check_devnum
|
|
bcs chrout_done_unknown_device // not a supported device
|
|
|
|
chrout_iec:
|
|
|
|
lda SCHAR
|
|
jsr JCIOUT
|
|
bcc chrout_done
|
|
|
|
// FALLTROUGH
|
|
|
|
chrout_done_fail:
|
|
jsr show_cursor_if_enabled
|
|
|
|
plp
|
|
|
|
// Restore X and Y
|
|
pla
|
|
tay
|
|
pla
|
|
tax
|
|
sec // indicate failure
|
|
rts
|
|
|
|
chrout_done_unknown_device:
|
|
jsr show_cursor_if_enabled
|
|
|
|
plp
|
|
|
|
// Restore X and Y
|
|
pla
|
|
tay
|
|
pla
|
|
tax
|
|
|
|
// End wioth error
|
|
jmp lvs_device_not_found_error
|
|
|
|
chrout_done:
|
|
jsr show_cursor_if_enabled
|
|
|
|
plp
|
|
|
|
// Restore X and Y
|
|
pla
|
|
tay
|
|
pla
|
|
tax
|
|
lda SCHAR
|
|
clc // indicate success
|
|
rts
|
|
|
|
chrout_screen:
|
|
|
|
// Crude implementation of character output
|
|
sei // XXX why do we need to disable interrupts?
|
|
|
|
jsr hide_cursor_if_visible
|
|
|
|
lda SCHAR
|
|
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
|
|
// RETURN clears quote and insert modes
|
|
lda #$00
|
|
sta QTSW
|
|
sta INSRT
|
|
jmp screen_advance_to_next_line
|
|
not_0d:
|
|
|
|
cmp #$94
|
|
bne not_94
|
|
|
|
// Insert (shift-DELETE)
|
|
|
|
// Abort if line already max length, ie 79th char is not a space
|
|
jsr get_current_line_logical_length
|
|
cmp #79
|
|
bne definitely_not_too_long
|
|
tay
|
|
lda (PNT),y
|
|
cmp #$20
|
|
beq definitely_not_too_long
|
|
|
|
// Line is too long to extend
|
|
jmp chrout_done
|
|
|
|
definitely_not_too_long:
|
|
// Work out if line needs to be expanded, and if so expand it
|
|
ldy #39
|
|
lda (PNT),y
|
|
cmp #$20
|
|
beq no_need_to_extend
|
|
|
|
jsr screen_grow_logical_line
|
|
|
|
no_need_to_extend:
|
|
// Shuffle chars towards end of line
|
|
jsr get_current_line_logical_length
|
|
tay
|
|
!:
|
|
// Note: While the following routine is obvious to any skilled
|
|
// in the art as the most obvious simple and efficient solution,
|
|
// if the screen writes are before the colour writes, it results
|
|
// in a relatively long verbatim stretch of bytes when compared to
|
|
// the C64 KERNAL. Thus we have swapped the order, just to reduce
|
|
// the potential for any argument of copyright infringement, even
|
|
// though we really don't believe that the routine can be copyrighted
|
|
// due to the lack of creativity.
|
|
dey
|
|
lda (USER),y
|
|
iny
|
|
sta (USER),y
|
|
dey
|
|
lda (PNT),y
|
|
iny
|
|
sta (PNT),y
|
|
|
|
dey
|
|
cpy PNTR
|
|
bne !-
|
|
|
|
// Increase insert mode count (which causes quote-mode like behaviour)
|
|
inc INSRT
|
|
|
|
// Put space in the inserted gap
|
|
lda #$20
|
|
sta (PNT),y
|
|
|
|
jmp chrout_done
|
|
not_94:
|
|
|
|
// DELETE in insert mode embeds control character
|
|
ldx INSRT
|
|
bne not_14
|
|
|
|
cmp #$14
|
|
bne not_14
|
|
|
|
// Delete
|
|
ldx PNTR
|
|
bne delete_non_zero_column
|
|
delete_at_column_0:
|
|
ldy TBLX
|
|
bne not_row_0
|
|
// delete from row 0, col 0 does nothing
|
|
jmp chrout_done
|
|
not_row_0:
|
|
// Column 0 delete just moves us to the end of the
|
|
// previous line, without actually deleting anything
|
|
dec TBLX
|
|
jsr get_current_line_logical_length
|
|
lda LNMX
|
|
|
|
sta PNTR
|
|
jsr calculate_screen_line_pointer
|
|
jmp chrout_done
|
|
|
|
delete_non_zero_column:
|
|
// Copy rest of line down
|
|
jsr get_current_line_logical_length
|
|
ldy PNTR
|
|
cpy LNMX
|
|
beq done_delete
|
|
dey
|
|
!:
|
|
iny
|
|
lda (PNT),y
|
|
dey
|
|
sta (PNT),y
|
|
iny
|
|
lda (USER),y
|
|
dey
|
|
sta (USER),y
|
|
iny
|
|
cpy LNMX
|
|
bne !-
|
|
|
|
// Clear char at end of line
|
|
jsr get_current_line_logical_length
|
|
tay
|
|
lda #$20
|
|
sta (PNT),y
|
|
|
|
done_delete:
|
|
dec PNTR
|
|
jmp chrout_done
|
|
not_14:
|
|
|
|
// Check for quote mode
|
|
ldx QTSW
|
|
bne is_quote_mode
|
|
ldx INSRT
|
|
bne is_quote_mode
|
|
jmp not_quote_mode
|
|
|
|
is_quote_mode:
|
|
// Is it a control code?
|
|
// control codes are $00-$1f and $80-$9f
|
|
// (from reading C64 PRG p379-381)
|
|
// so we can just check if bits 5 or 6 are set, and if so,
|
|
// then it isn't a control character.
|
|
pha
|
|
and #$60
|
|
bne !+
|
|
|
|
// Yes, a control code in quote mode means we display it as a reverse character
|
|
pla
|
|
|
|
// Low control codes are just +$80
|
|
clc
|
|
adc #$80
|
|
// If it overflowed, then it is a high control code,
|
|
// so we need to make it be $80 + $40 + char
|
|
// as we will have flipped back to just $00 + char, we should
|
|
// now add $c0 if C is set from overflow
|
|
bcc low_ctrl_char
|
|
adc #$bf // C=1, so adding $BF + C = add $C0
|
|
low_ctrl_char:
|
|
jmp output_literal_char
|
|
!:
|
|
pla
|
|
not_quote_mode:
|
|
|
|
// Check for colours
|
|
ldx #$f
|
|
colour_check_loop:
|
|
cmp colour_codes,x
|
|
bne !+
|
|
stx COLOR
|
|
jmp chrout_done
|
|
!: dex
|
|
bpl colour_check_loop
|
|
|
|
// Compute's Mapping the 64 p38
|
|
cmp #$12
|
|
bne not_12
|
|
lda #$80
|
|
sta RVS
|
|
jmp chrout_done
|
|
not_12:
|
|
// Compute's Mapping the 64 p 38
|
|
cmp #$92
|
|
bne not_92
|
|
lda #$00
|
|
sta RVS
|
|
jmp chrout_done
|
|
not_92:
|
|
|
|
// Check for cursor movement keys
|
|
cmp #$11
|
|
bne not_11
|
|
lda PNTR
|
|
clc
|
|
adc #40
|
|
sta PNTR
|
|
// We need to advance the pointer manually, as normalising
|
|
// now will break things. The pointer update is required
|
|
// so that we can tell if we really are on the bottom phys
|
|
// screen line or not
|
|
jsr scroll_up_if_on_last_line
|
|
jsr calculate_screen_line_pointer
|
|
jmp chrout_done
|
|
not_11:
|
|
cmp #$1d
|
|
bne not_1d
|
|
inc PNTR
|
|
jsr calculate_screen_line_pointer
|
|
jmp chrout_done
|
|
not_1d:
|
|
cmp #$91
|
|
bne not_91
|
|
lda PNTR
|
|
sec
|
|
sbc #40
|
|
sta PNTR
|
|
jsr calculate_screen_line_pointer
|
|
jmp chrout_done
|
|
not_91:
|
|
cmp #$9d
|
|
bne not_9d
|
|
dec PNTR
|
|
jsr calculate_screen_line_pointer
|
|
jmp chrout_done
|
|
not_9d:
|
|
|
|
// Home cursor
|
|
cmp #$13
|
|
bne not_13
|
|
lda #0
|
|
sta PNTR
|
|
sta TBLX
|
|
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
|
|
|
|
// Don't print other control codes
|
|
cmp #$1f
|
|
bcs !+
|
|
jmp chrout_done
|
|
!:
|
|
|
|
// Codes $C0-$DF become $40-$5F
|
|
// But
|
|
cmp #$e0
|
|
bcs !+
|
|
cmp #$c0
|
|
bcc !+
|
|
|
|
and #$7f
|
|
jmp not_high_char
|
|
|
|
!:
|
|
// Range $20-$3F is unchanged
|
|
cmp #$40
|
|
bcc not_high_char
|
|
|
|
// Unshifted letters and symbols from $40-$5F
|
|
// all end up being -$40
|
|
// (C64 PRG p376)
|
|
|
|
// But anything >= $80 needs to be -$40
|
|
// (C64 PRG p380-381)
|
|
// And bit 7 should be cleared, only to be
|
|
// set by reverse video
|
|
sec
|
|
sbc #$40
|
|
|
|
// Fix shifted chars by adding $20 again
|
|
cmp #$20
|
|
bcc not_high_char
|
|
cmp #$40
|
|
bcs not_high_char
|
|
clc
|
|
adc #$20
|
|
|
|
not_high_char:
|
|
|
|
chrout_l1:
|
|
|
|
output_literal_char:
|
|
|
|
// Write normal character on the screen
|
|
|
|
pha
|
|
|
|
ldy PNTR
|
|
ora RVS // Compute's Mapping the 64 p38
|
|
sta (PNT),y
|
|
|
|
// Decrement number of chars waiting to be inserted
|
|
lda INSRT
|
|
beq !+
|
|
dec INSRT
|
|
!:
|
|
pla
|
|
cmp #$22
|
|
bne not_quote
|
|
|
|
// Toggle quote flag if required
|
|
lda QTSW
|
|
eor #$80
|
|
sta QTSW
|
|
|
|
not_quote:
|
|
|
|
// Set colour
|
|
lda COLOR
|
|
sta (USER),y
|
|
|
|
// 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 TBLX
|
|
iny
|
|
sty PNTR
|
|
cpy #40
|
|
bne !+
|
|
jsr screen_grow_logical_line
|
|
ldy PNTR
|
|
!:
|
|
cpy #80
|
|
bcc no_screen_advance_to_next_line
|
|
lda #0
|
|
sta PNTR
|
|
jmp screen_advance_to_next_line
|
|
no_screen_advance_to_next_line:
|
|
jmp chrout_done
|
|
|
|
screen_grow_logical_line:
|
|
ldy TBLX
|
|
// Don't grow line if it is already grown
|
|
lda LDTBL,y
|
|
bpl !+
|
|
jmp done_grow_line
|
|
!:
|
|
lda #$80
|
|
sta LDTBL,y
|
|
|
|
// Now make space for the extra line added.
|
|
// If we are on the last physical line of the screen,
|
|
// Then we need to scroll the screen up
|
|
jsr scroll_up_if_on_last_line
|
|
|
|
// Scroll screen down to make space
|
|
// As we are scrolling down, we start from the end,
|
|
// and work backwards. We can't be as simple and efficient
|
|
// here as we are for scrolling up, because we don't know
|
|
// how much must be scrolled.
|
|
// Simple solution is to work out how many physical lines
|
|
// need shifting down, and then move lines at a time after
|
|
// initialising the pointers to the end area of the screen.
|
|
ldx #25-2
|
|
ldy #0
|
|
count_rows_loop:
|
|
dex
|
|
lda LDTBL,y
|
|
bpl !+
|
|
dex
|
|
!: iny
|
|
cpy TBLX
|
|
bne count_rows_loop
|
|
|
|
cpx #0
|
|
beq no_copy_down
|
|
bmi no_copy_down
|
|
|
|
// Set pointers to end of screen line, and one line
|
|
// above. (It is always one physical line, because
|
|
// this can only happen when expanding a line from 40 to
|
|
// 80 characters).
|
|
// XXX - This is not very efficient, and longer than it
|
|
// needs to be. Better would be to work out size to
|
|
// copy, and count it down in a pointer somewhere, so
|
|
// that loop iteration logic is simpler.
|
|
lda HIBASE
|
|
clc
|
|
adc #3
|
|
sta PNT+1
|
|
sta SAL+1
|
|
lda #>$DBC0
|
|
sta EAL+1
|
|
sta USER+1
|
|
|
|
lda #<$03C0
|
|
sta PNT+0
|
|
sta USER+0
|
|
// souce address is line above
|
|
sec
|
|
sbc #40
|
|
sta SAL+0
|
|
sta EAL+0
|
|
|
|
copy_line_down_loop:
|
|
ldy #39
|
|
cl_inner:
|
|
lda (EAL),y
|
|
sta (USER),y
|
|
lda (SAL),y
|
|
sta (PNT),y
|
|
dey
|
|
bpl cl_inner
|
|
|
|
// Decrement all pointers by 40
|
|
// Low bytes are in common pairs
|
|
|
|
// Old source is new destination
|
|
// Use different registers to minimise byte similarity with C64 KERNAl
|
|
ldy SAL+1
|
|
sty PNT+1
|
|
lda EAL+1
|
|
ldy SAL+0
|
|
sta USER+1
|
|
sty PNT+0
|
|
sty USER+0
|
|
|
|
// Decrementing source pointers
|
|
lda SAL+0
|
|
sec
|
|
sbc #<40
|
|
sta SAL+0
|
|
sta EAL+0
|
|
lda SAL+1
|
|
sbc #>40
|
|
sta SAL+1
|
|
// convert to screen equivalent
|
|
sec
|
|
sbc HIBASE
|
|
clc
|
|
adc #>$D800
|
|
sta EAL+1
|
|
|
|
dex
|
|
bne copy_line_down_loop
|
|
|
|
no_copy_down:
|
|
jsr calculate_screen_line_pointer
|
|
|
|
// Erase newly inserted line
|
|
ldy #79
|
|
!:
|
|
lda COLOR
|
|
sta (USER),y
|
|
lda #$20
|
|
sta (PNT),y
|
|
dey
|
|
cpy #40
|
|
bne !-
|
|
|
|
rts
|
|
|
|
done_grow_line:
|
|
not_last_line:
|
|
rts
|
|
|
|
scroll_up_if_on_last_line:
|
|
|
|
// Colour RAM is always in fixed place, so is easiest
|
|
// to use to check if we are on the last line.
|
|
// The last line is at $D800 + 24*40 = $DBC0
|
|
lda USER+1
|
|
cmp #>$DBC0
|
|
bne not_last_line
|
|
|
|
lda USER+0
|
|
cmp #<$DBC0
|
|
beq is_last_line
|
|
|
|
jsr get_current_line_logical_length
|
|
clc
|
|
adc USER+0
|
|
cmp #<$DBE7-1
|
|
bcc not_last_line
|
|
|
|
is_last_line:
|
|
|
|
dec TBLX
|
|
|
|
// FALL THROUGH
|
|
|
|
scroll_screen_up:
|
|
// Now scroll the whole screen up either one or two lines
|
|
// based on whether the first screen line is linked or not.
|
|
|
|
// Get pointers to start of screen + colour RAM
|
|
lda HIBASE
|
|
sta PNT+1
|
|
sta SAL+1
|
|
lda #>$D800
|
|
sta USER+1
|
|
sta EAL+1
|
|
lda #$00
|
|
sta PNT+0
|
|
sta USER+0
|
|
|
|
// Get pointers to screen/colour RAM source
|
|
lda LDTBL+0
|
|
bmi !+
|
|
lda #40
|
|
.byte $2C // BIT $nnnn to skip next instruction
|
|
!:
|
|
lda #80
|
|
sta SAL+0
|
|
sta EAL+0
|
|
|
|
// Copy first three pages
|
|
ldy #$00
|
|
ldx #3
|
|
scroll_copy_loop:
|
|
lda (EAL),y
|
|
sta (USER),y
|
|
lda (SAL),y
|
|
sta (PNT),y
|
|
|
|
iny
|
|
bne scroll_copy_loop
|
|
|
|
inc SAL+1
|
|
inc PNT+1
|
|
inc EAL+1
|
|
inc USER+1
|
|
dex
|
|
bne scroll_copy_loop
|
|
|
|
// Copy last partial page
|
|
// We need to copy 1000-(3*256)-line length
|
|
// = 232 - line length
|
|
lda SAL+0
|
|
lda #232
|
|
sec
|
|
sbc SAL+0
|
|
tax
|
|
scroll_copy_loop2:
|
|
lda (EAL),y
|
|
sta (USER),y
|
|
lda (SAL),y
|
|
sta (PNT),y
|
|
iny
|
|
dex
|
|
bne scroll_copy_loop2
|
|
|
|
// Fill in scrolled up area
|
|
ldx SAL+0
|
|
scroll_copy_loop3:
|
|
lda COLOR
|
|
sta (USER),y
|
|
lda #$20
|
|
sta (PNT),y
|
|
iny
|
|
dex
|
|
bne scroll_copy_loop3
|
|
|
|
// Shift line linkage list
|
|
ldy #0
|
|
ldx #24
|
|
link_copy:
|
|
lda LDTBL+1,y
|
|
sta LDTBL+0,y
|
|
iny
|
|
dex
|
|
bne link_copy
|
|
// Clear line link flag of last line
|
|
stx LDTBL+24
|
|
|
|
// Restore correct line pointers
|
|
jsr calculate_screen_line_pointer
|
|
|
|
rts
|
|
|
|
get_current_line_logical_length:
|
|
ldy TBLX
|
|
lda LDTBL,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 LNMX
|
|
rts
|
|
|
|
screen_advance_to_next_line:
|
|
|
|
// jsr hide_cursor_if_visible
|
|
|
|
// Go to start of line
|
|
lda #0
|
|
sta PNTR
|
|
// Advance line number
|
|
ldy TBLX
|
|
|
|
// Do quick fix to line pointer to work out if it is off
|
|
// the bottom of the screen.
|
|
ldx #40
|
|
lda LDTBL,y
|
|
bmi !+
|
|
.byte $2c
|
|
!: ldx #80
|
|
txa
|
|
clc
|
|
adc PNT+0
|
|
sta PNT+0
|
|
lda PNT+1
|
|
adc #0
|
|
sta PNT+1
|
|
|
|
inc TBLX
|
|
|
|
// Check if it will trigger scrolling
|
|
// 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 PNT+1
|
|
sec
|
|
sbc HIBASE
|
|
cmp #3
|
|
bcc !+
|
|
lda PNT+0
|
|
cmp #$e7
|
|
bcc !+
|
|
|
|
// Off the bottom of the screen
|
|
jsr scroll_screen_up
|
|
!:
|
|
|
|
jsr calculate_screen_line_pointer
|
|
|
|
jmp chrout_done
|
|
|
|
add_40_to_screen_x:
|
|
lda PNTR
|
|
clc
|
|
adc #40
|
|
sta PNTR
|
|
rts
|
|
|
|
normalise_screen_x_y:
|
|
// Normalise X and Y values
|
|
|
|
// If X < 0, then make X = X + 40 (or 80, if previous line is linked)
|
|
!: lda PNTR
|
|
bpl x_not_negative
|
|
dec TBLX
|
|
// Check that we didn't go backwards off the top of the screen
|
|
bpl !+
|
|
lda #0
|
|
sta TBLX
|
|
|
|
!: jsr add_40_to_screen_x
|
|
|
|
// Check if line is linked, if so, add 40 again
|
|
ldy TBLX
|
|
lda LDTBL,y
|
|
bpl !+
|
|
jsr add_40_to_screen_x
|
|
!:
|
|
|
|
x_not_negative:
|
|
// Work out if X is too big
|
|
ldy TBLX
|
|
lda LDTBL,y
|
|
bpl !+
|
|
lda #79
|
|
.byte $2C // BIT $nnnn, used to skip next instruction
|
|
!: lda #39
|
|
cmp PNTR
|
|
bcs x_not_too_big
|
|
|
|
// X value is too big, so subtract 40 and increment Y
|
|
lda PNTR
|
|
sec
|
|
sbc #40
|
|
sta PNTR
|
|
inc TBLX
|
|
|
|
x_not_too_big:
|
|
|
|
// Make sure Y isn't negative
|
|
lda TBLX
|
|
bpl !+
|
|
lda #0
|
|
sta TBLX
|
|
!:
|
|
// Make sure Y isn't too large for absolute size of
|
|
// screen
|
|
cmp #24
|
|
bcc !+
|
|
lda #24
|
|
sta TBLX
|
|
!:
|
|
// Make sure Y isn't too much for the screen, taking
|
|
// into account the line link table
|
|
ldy #24 // max allowable line
|
|
ldx #0
|
|
link_count_loop:
|
|
lda LDTBL,x
|
|
bpl !+
|
|
dey
|
|
!: inx
|
|
cpx #25
|
|
bne link_count_loop
|
|
tya
|
|
cmp TBLX
|
|
bcs y_ok
|
|
sta TBLX
|
|
y_ok:
|
|
rts
|
|
|
|
calculate_screen_line_pointer:
|
|
jsr normalise_screen_x_y
|
|
|
|
// Reset pointer to start of screen
|
|
lda HIBASE
|
|
sta PNT+1
|
|
lda #0
|
|
sta PNT+0
|
|
|
|
// Add 40 for every line, or 80 if the lines are linked
|
|
ldx TBLX
|
|
|
|
!:
|
|
// Stop if we have counted enough lines
|
|
beq !+
|
|
|
|
// Add 40 or 80 based on whether the line is linked
|
|
// or not.
|
|
ldy #40
|
|
// -1 offset is because we count down from N to 1, not
|
|
// N-1 to 0.
|
|
lda LDTBL-1,x
|
|
bpl cslp_l1
|
|
ldy #80
|
|
cslp_l1:
|
|
// Add computed line length to pointer value
|
|
tya
|
|
clc
|
|
adc PNT+0
|
|
sta PNT+0
|
|
lda PNT+1
|
|
adc #0
|
|
sta PNT+1
|
|
|
|
// Loop back to next line
|
|
dex
|
|
jmp !-
|
|
!:
|
|
|
|
// FALL THROUGH
|
|
|
|
update_colour_line_pointer:
|
|
// Now setup pointer to colour RAM
|
|
lda PNT+0
|
|
sta USER+0
|
|
lda PNT+1
|
|
sec
|
|
sbc HIBASE
|
|
clc
|
|
adc #>$d800
|
|
sta USER+1
|
|
|
|
rts
|
|
|
|
advance_screen_pointer_40_bytes:
|
|
lda PNT+0
|
|
clc
|
|
adc #<40
|
|
sta PNT+0
|
|
sta USER+0
|
|
lda PNT+1
|
|
adc #>40
|
|
sta PNT+1
|
|
sec
|
|
sbc HIBASE
|
|
clc
|
|
adc #>$D800
|
|
sta USER+1
|
|
|
|
jmp update_colour_line_pointer
|