Files
open-roms/c64/kernal/screen/screen_grow_logical_line.s
T
2019-11-07 22:05:49 +01:00

135 lines
2.3 KiB
ArmAsm

screen_grow_logical_line:
ldy TBLX
// Don't grow line if it is already grown
lda LDTBL,y
bpl !+
jmp not_last_line // doneb 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 screen_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
// Preserve EAL
lda EAL+0
pha
lda EAL+1
pha
// 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
// Restore EAL
pla
sta EAL+1
pla
sta EAL+0
no_copy_down:
jsr screen_calculate_line_pointer
// Erase newly inserted line
ldy #79
!:
lda COLOR
sta (USER),y
lda #$20
sta (PNT),y
dey
cpy #40
bne !-
rts