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

+2 -4
View File
@@ -1,7 +1,7 @@
# Configuring the build
It's not possible to provide ROM builds that suit everyone needs - therefore configuration files were introduced, separately for each of the hardware targets:
It's not possible to provide ROM builds that suit everyone needs - therefore configuration files were introduced, few predefined configurations are provided with sane defaults:
* [`c64/,,config_generic.s`](c64/,,config_generic.s)
* [`c64/,,config_mega65.s`](c64/,,config_mega65.s)
@@ -11,8 +11,6 @@ Just edit them and recompile the project. To enable particular option - uncommen
Note however, that features do not came for free - enabling them needs some additional ROM space (in BASIC segment, in KERNAL segment, or in both), which is VERY limited on the target machines. Some options might be unavailable for speecific targets - read the comments in the configuration files. Some options might also carry compatibility and/or performance hit - so choose wisely.
Sane defaults are already present - different for each target.
## Hardware platform and variant
### `CONFIG_PLATFORM_COMMODORE_64`
@@ -136,4 +134,4 @@ Replaces `RTS` stubbed routines implementation with one causing a break.
### `CONFIG_DBG_PRINTF`
Makes 'printf' routine available.
Makes `printf` routine available.
+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