reached target granularity in screen code

This commit is contained in:
FeralChild64 committed 2019-10-09 20:53:42 +02:00
1 parent 20899a49d9
commit e53dcaf345
17 files changed
+335 -323

No files matched your search

+1 -1
View File
@@ -113,7 +113,7 @@ read_from_keyboard:
sta LXSP+1
// Calculate length
jsr get_current_line_logical_length
jsr screen_get_current_line_logical_length
tay
iny
!: dey
-295
View File
@@ -1,295 +0,0 @@
//
// CHROUT routine - screen support
//
chrout_screen:
// Crude implementation of character output
sei // XXX why do we need to disable interrupts?
jsr cursor_hide_if_visible
lda SCHAR
tax
// All the PETSCII control codes are within $0x, $1x, $8x, $9x, remaining
// ones are always printable characters; separate away control codes
and #$60
bne !+
jmp chrout_screen_control
!:
txa
// Literals - first convert PETSCII to screen code
// Codes $C0-$DF become $40-$5F
cmp #$E0
bcs !+
cmp #$C0
bcc !+
and #$7F
jmp output_literal_char // not high char
!:
// Range $20-$3F is unchanged
cmp #$40
bcc output_literal_char // 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 output_literal_char // not high char
cmp #$40
bcs output_literal_char // not high char
clc
adc #$20
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
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 cursor_hide_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
+1 -1
View File
@@ -20,7 +20,7 @@ plot_set:
sty PNTR
stx TBLX
jsr calculate_screen_line_pointer
jsr screen_calculate_line_pointer
// XXX cursor blink might need to be handled too
+27
View File
@@ -16,10 +16,17 @@ CHROUT:
// (Confirmed by writing a test program that X and Y
// don't get modified, in agreement with C64 PRG's
// description of CHROUT)
#if CONFIG_CPU_MOS_6502
txa
pha
tya
pha
#else
phx
phy
#endif
php
// Determine the device number
@@ -46,10 +53,17 @@ chrout_done_fail:
plp
// Restore X and Y
#if CONFIG_CPU_MOS_6502
pla
tay
pla
tax
#else
ply
plx
#endif
sec // indicate failure
rts
@@ -59,10 +73,16 @@ chrout_done_unknown_device:
plp
// Restore X and Y
#if CONFIG_CPU_MOS_6502
pla
tay
pla
tax
#else
ply
plx
#endif
// End wioth error
jmp lvs_device_not_found_error
@@ -73,10 +93,17 @@ chrout_done:
plp
// Restore X and Y
#if CONFIG_CPU_MOS_6502
pla
tay
pla
tax
#else
ply
plx
#endif
lda SCHAR
clc // indicate success
rts
+108
View File
@@ -0,0 +1,108 @@
//
// CHROUT routine - screen support (character output)
//
chrout_screen:
sei // XXX why do we need to disable interrupts?
jsr cursor_hide_if_visible
lda SCHAR
tax
// All the PETSCII control codes are within $0x, $1x, $8x, $9x, remaining
// ones are always printable characters; separate away control codes
and #$60
bne !+
jmp chrout_screen_control
!:
txa
// Literals - first convert PETSCII to screen code
// Codes $C0-$DF become $40-$5F
cmp #$E0
bcs !+
cmp #$C0
bcc !+
and #$7F
jmp output_literal_char // not high char
!:
// Range $20-$3F is unchanged
cmp #$40
bcc output_literal_char // 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 output_literal_char // not high char
cmp #$40
bcs output_literal_char // not high char
clc
adc #$20
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
+5 -5
View File
@@ -49,7 +49,7 @@ chrout_try_CRSR_UP:
sec
sbc #40
sta PNTR
jsr calculate_screen_line_pointer
jsr screen_calculate_line_pointer
jmp chrout_done
!:
chrout_try_CRSR_DOWN:
@@ -65,8 +65,8 @@ chrout_try_CRSR_DOWN:
// 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
jsr screen_scroll_up_if_on_last_line
jsr screen_calculate_line_pointer
jmp chrout_done
!:
chrout_try_CRSR_LEFT:
@@ -86,7 +86,7 @@ chrout_try_CRSR_RIGHT:
bne !+
inc PNTR
jsr calculate_screen_line_pointer
jsr screen_calculate_line_pointer
jmp chrout_done
!:
chrout_try_RVS_ON:
@@ -202,5 +202,5 @@ chrout_screen_control_done: // unknown, LF, or no more actions required // XXX
chrout_screen_control_calcptr_done: // XXX to !csc_calcptr_done
jsr calculate_screen_line_pointer
jsr screen_calculate_line_pointer
jmp chrout_done
+3 -3
View File
@@ -24,7 +24,7 @@ chrout_screen_del_column_0:
// previous line, without actually deleting anything
dec TBLX
jsr get_current_line_logical_length
jsr screen_get_current_line_logical_length
lda LNMX
sta PNTR
@@ -33,7 +33,7 @@ chrout_screen_del_column_0:
chrout_screen_del_column_non_0:
// Copy rest of line down
jsr get_current_line_logical_length
jsr screen_get_current_line_logical_length
ldy PNTR
cpy LNMX
beq !++
@@ -52,7 +52,7 @@ chrout_screen_del_column_non_0:
bne !-
// Clear char at end of line
jsr get_current_line_logical_length
jsr screen_get_current_line_logical_length
tay
lda #$20
sta (PNT),y
+2 -2
View File
@@ -8,7 +8,7 @@ chrout_screen_ins:
// Insert (shift-DELETE)
// Abort if line already max length, ie 79th char is not a space
jsr get_current_line_logical_length
jsr screen_get_current_line_logical_length
cmp #79
bne !+
tay
@@ -30,7 +30,7 @@ chrout_screen_ins:
!:
// Shuffle chars towards end of line
jsr get_current_line_logical_length
jsr screen_get_current_line_logical_length
tay
!:
// Note: While the following routine is obvious to any skilled
+1 -1
View File
@@ -28,7 +28,7 @@ cursor_blink:
// FALLTROUGH
cursor_draw:
jsr calculate_screen_line_pointer // XXX make sure this is not needed and remove the call
jsr screen_calculate_line_pointer // XXX make sure this is not needed and remove the call
ldy PNTR
lda (PNT),y
+1 -1
View File
@@ -9,4 +9,4 @@ cursor_home:
sta PNTR // x position
sta TBLX // y position
jmp set_pointer_to_current_screen_line
jmp screen_set_pointer_to_current_line
@@ -0,0 +1,47 @@
screen_advance_to_next_line:
// jsr cursor_hide_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 screen_calculate_line_pointer
jmp chrout_done
@@ -1,5 +1,5 @@
calculate_screen_line_pointer: // XXX rename to screen_calculate_line_pointer
screen_calculate_line_pointer:
jsr screen_normalize_xy
// Reset pointer to start of screen
@@ -21,9 +21,9 @@ calculate_screen_line_pointer: // XXX rename to screen_calculate_line_pointer
// -1 offset is because we count down from N to 1, not
// N-1 to 0.
lda LDTBL-1,x
bpl cslp_l1
bpl sclp_l1
ldy #80
cslp_l1:
sclp_l1:
// Add computed line length to pointer value
tya
clc
@@ -0,0 +1,11 @@
screen_get_current_line_logical_length:
ldy TBLX
lda LDTBL,y
bpl !+
lda #79
.byte $2c // BIT absolute mode, which we use to skip the next two instruction bytes
!:
lda #39
sta LNMX
rts
+2 -2
View File
@@ -12,7 +12,7 @@ screen_grow_logical_line:
// 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
jsr screen_scroll_up_if_on_last_line
// Scroll screen down to make space
// As we are scrolling down, we start from the end,
@@ -106,7 +106,7 @@ cl_inner:
bne copy_line_down_loop
no_copy_down:
jsr calculate_screen_line_pointer
jsr screen_calculate_line_pointer
// Erase newly inserted line
ldy #79
@@ -0,0 +1,115 @@
not_last_line:
rts
screen_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 screen_get_current_line_logical_length
clc
adc USER+0
cmp #<$DBE7-1
bcc not_last_line
is_last_line:
dec TBLX
// FALLTHROUGH
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
jmp screen_calculate_line_pointer
@@ -2,7 +2,8 @@
// into the pointer at $D1 (PNT).
// It must take into account the screen line link table
// (Compute's Mapping the 64 p216)
set_pointer_to_current_screen_line:
screen_set_pointer_to_current_line:
// Get pointer to start of the screen
lda HIBASE
sta PNT+1
@@ -12,15 +13,15 @@ set_pointer_to_current_screen_line:
// Now advance for the number of lines
ldx TBLX
sptcsl_l2:
sptcl_l2:
// XXX - Should we read the columns per line from
// somewhere?
ldy #<40
// Double line length if line is linked
lda LDTBL,x
bpl sptcsl_l1
bpl sptcl_l1
ldy #<80
sptcsl_l1:
sptcl_l1:
tya
clc
adc PNT+0
@@ -29,6 +30,6 @@ sptcsl_l1:
sta PNT+1
dex
bpl sptcsl_l2
bpl sptcl_l2
rts