mirror of
https://github.com/irmen/prog8.git
synced 2025-05-12 19:47:48 +00:00
cx16: added syslib.get_charset()
updated fileselector
This commit is contained in:
parent
b7f47d354f
commit
a76b8d66ff
@ -667,6 +667,30 @@ asmsub scnsiz(ubyte width @X, ubyte heigth @Y) clobbers(A,X,Y) {
|
|||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
asmsub get_charset() -> ubyte @A {
|
||||||
|
;Get charset mode. result: 0=unknown, 1=ISO, 2=PETSCII upper case/gfx, 3=PETSCII lowercase.
|
||||||
|
%asm {{
|
||||||
|
|
||||||
|
KERNAL_MODE = $0372 ; internal kernal variable, risky to read it, but it's ben stable for many releases.
|
||||||
|
lda KERNAL_MODE
|
||||||
|
beq _end
|
||||||
|
|
||||||
|
bit #$40 ;ISO mode flag
|
||||||
|
beq + ;usually KERNAL_MODE 1 or 6 (| $40)
|
||||||
|
lda #1
|
||||||
|
bra _end
|
||||||
|
|
||||||
|
+ bit #1 ;PETSCII upper case/graphics
|
||||||
|
bne + ;usually KERNAL_MODE 2 or 4
|
||||||
|
lda #2
|
||||||
|
bra _end
|
||||||
|
|
||||||
|
+ lda #3 ;PETSCII upper/lower case
|
||||||
|
_end:
|
||||||
|
rts
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
; TODO : implement shims for the remaining extapi calls.
|
; TODO : implement shims for the remaining extapi calls.
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
TODO
|
TODO
|
||||||
====
|
====
|
||||||
|
|
||||||
|
- textio.get_cursor() should just return 2 bytes (rewrite it as asmsub...)
|
||||||
|
|
||||||
- add paypal donation button as well?
|
- add paypal donation button as well?
|
||||||
- announce prog8 on the 6502.org site?
|
- announce prog8 on the 6502.org site?
|
||||||
|
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
%import diskio
|
%import diskio
|
||||||
%import textio
|
%import textio
|
||||||
%import sorting
|
|
||||||
%import strings
|
%import strings
|
||||||
%zeropage basicsafe
|
%zeropage basicsafe
|
||||||
%option no_sysinit
|
%option no_sysinit
|
||||||
|
|
||||||
; A "TUI" for an interactive file selector, that scrolls the selection list if it doesn't fit on the screen.
|
; A "TUI" for an interactive file selector, that scrolls the selection list if it doesn't fit on the screen.
|
||||||
; Returns the name of the selected file. If it is a directory instead, the name will start and end with a slash '/'.
|
; Returns the name of the selected file. If it is a directory instead, the name will start and end with a slash '/'.
|
||||||
|
; Functions in PETSCII mode and in ISO mode as well (no case folding in ISO mode!)
|
||||||
; Depends a lot on diskio routines, and uses the drive set in the diskio.drivenumber variable (usually just 8)
|
; Depends a lot on diskio routines, and uses the drive set in the diskio.drivenumber variable (usually just 8)
|
||||||
|
|
||||||
; should case folding be done in diskio already? -> no, it doesn't know if you are in iso mode or not.
|
; should case folding be done in diskio already? -> no, it doesn't know if you are in iso mode or not.
|
||||||
@ -18,10 +18,13 @@
|
|||||||
|
|
||||||
main {
|
main {
|
||||||
sub start() {
|
sub start() {
|
||||||
txt.iso()
|
; some configuration, optional
|
||||||
fileselector.configure_settings(true, true, 2)
|
fileselector.configure_settings(%00000011, 2)
|
||||||
fileselector.configure_appearance(10, 10, 20, $b3, $d0, true)
|
fileselector.configure_appearance(10, 10, 20, $b3, $d0)
|
||||||
|
|
||||||
|
; show all files, using just the * wildcard
|
||||||
uword chosen = fileselector.select("*")
|
uword chosen = fileselector.select("*")
|
||||||
|
|
||||||
txt.nl()
|
txt.nl()
|
||||||
txt.nl()
|
txt.nl()
|
||||||
if chosen!=0 {
|
if chosen!=0 {
|
||||||
@ -49,28 +52,25 @@ fileselector {
|
|||||||
ubyte colors_selected = $d0
|
ubyte colors_selected = $d0
|
||||||
ubyte buffer_rambank = 1 ; default hiram bank to use for the data buffers
|
ubyte buffer_rambank = 1 ; default hiram bank to use for the data buffers
|
||||||
ubyte show_what = 3 ; dirs and files
|
ubyte show_what = 3 ; dirs and files
|
||||||
bool iso_mode = false
|
ubyte chr_topleft, chr_topright, chr_botleft, chr_botright, chr_horiz_top, chr_horiz_other, chr_vert, chr_jointleft, chr_jointright
|
||||||
ubyte chr_topleft, chr_topright, chr_botleft, chr_botright, chr_horiz, chr_vert, chr_jointleft, chr_jointright
|
|
||||||
|
|
||||||
ubyte num_visible_files
|
ubyte num_visible_files
|
||||||
uword name_ptr
|
uword name_ptr
|
||||||
|
|
||||||
|
|
||||||
sub configure_settings(bool show_files, bool show_dirs, ubyte rambank) {
|
sub configure_settings(ubyte show_types, ubyte rambank) {
|
||||||
|
; show_types is a bit mask , bit 0 = show files, bit 1 = show dirs
|
||||||
buffer_rambank = rambank
|
buffer_rambank = rambank
|
||||||
show_what = 0
|
show_what = show_types
|
||||||
if show_files show_what |= 1
|
|
||||||
if show_dirs show_what |= 2
|
|
||||||
set_characters(false)
|
set_characters(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
sub configure_appearance(ubyte column, ubyte row, ubyte max_entries, ubyte normal, ubyte selected, bool iso_chars) {
|
sub configure_appearance(ubyte column, ubyte row, ubyte max_entries, ubyte normal, ubyte selected) {
|
||||||
dialog_topx = column
|
dialog_topx = column
|
||||||
dialog_topy = row
|
dialog_topy = row
|
||||||
max_lines = max_entries
|
max_lines = max_entries
|
||||||
colors_normal = normal
|
colors_normal = normal
|
||||||
colors_selected = selected
|
colors_selected = selected
|
||||||
iso_mode = iso_chars
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sub select(str pattern) -> uword {
|
sub select(str pattern) -> uword {
|
||||||
@ -78,22 +78,20 @@ fileselector {
|
|||||||
cx16.rambank(buffer_rambank)
|
cx16.rambank(buffer_rambank)
|
||||||
defer cx16.rambank(old_bank)
|
defer cx16.rambank(old_bank)
|
||||||
|
|
||||||
; if pattern!=0 and pattern[0]==0
|
|
||||||
; pattern = 0 ; force pattern to be 0 instead of empty string, to be compatible with prog8 11.0 or older
|
|
||||||
|
|
||||||
num_visible_files = 0
|
num_visible_files = 0
|
||||||
diskio.list_filename[0] = 0
|
diskio.list_filename[0] = 0
|
||||||
name_ptr = diskio.diskname()
|
name_ptr = diskio.diskname()
|
||||||
if name_ptr==0 or cbm.READST()!=0
|
if name_ptr==0 or cbm.READST()!=0
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
bool iso_mode = cx16.get_charset()==1
|
||||||
set_characters(iso_mode)
|
set_characters(iso_mode)
|
||||||
txt.color2(colors_normal & 15, colors_normal>>4)
|
txt.color2(colors_normal & 15, colors_normal>>4)
|
||||||
background(0, 3)
|
background(0, 3)
|
||||||
|
|
||||||
txt.plot(dialog_topx, dialog_topy)
|
txt.plot(dialog_topx, dialog_topy)
|
||||||
txt.chrout(chr_topleft)
|
txt.chrout(chr_topleft)
|
||||||
linepart()
|
linepart(true)
|
||||||
txt.chrout(chr_topright)
|
txt.chrout(chr_topright)
|
||||||
txt.nl()
|
txt.nl()
|
||||||
txt.column(dialog_topx)
|
txt.column(dialog_topx)
|
||||||
@ -121,7 +119,7 @@ fileselector {
|
|||||||
|
|
||||||
construct_name_ptr_array()
|
construct_name_ptr_array()
|
||||||
; sort alphabetically
|
; sort alphabetically
|
||||||
sorting.shellsort_pointers(filename_ptrs_start, num_files, sorting.string_comparator)
|
sorting.shellsort_pointers(filename_ptrs_start, num_files)
|
||||||
num_visible_files = min(max_lines, num_files)
|
num_visible_files = min(max_lines, num_files)
|
||||||
|
|
||||||
; initial display
|
; initial display
|
||||||
@ -140,15 +138,15 @@ fileselector {
|
|||||||
txt.nl()
|
txt.nl()
|
||||||
txt.column(dialog_topx)
|
txt.column(dialog_topx)
|
||||||
txt.chrout(chr_vert)
|
txt.chrout(chr_vert)
|
||||||
txt.print(" stop or q to abort ")
|
txt.print(" esc/stop to abort ")
|
||||||
txt.chrout(chr_vert)
|
txt.chrout(chr_vert)
|
||||||
txt.nl()
|
txt.nl()
|
||||||
txt.column(dialog_topx)
|
txt.column(dialog_topx)
|
||||||
txt.chrout(chr_jointleft)
|
txt.chrout(chr_jointleft)
|
||||||
linepart()
|
linepart(false)
|
||||||
txt.chrout(chr_jointright)
|
txt.chrout(chr_jointright)
|
||||||
txt.nl()
|
txt.nl()
|
||||||
print_up_indicator(false)
|
print_scroll_indicator(false, true)
|
||||||
if num_files>0 {
|
if num_files>0 {
|
||||||
for selected_line in 0 to num_visible_files-1 {
|
for selected_line in 0 to num_visible_files-1 {
|
||||||
txt.column(dialog_topx)
|
txt.column(dialog_topx)
|
||||||
@ -167,7 +165,7 @@ fileselector {
|
|||||||
txt.chrout(chr_vert)
|
txt.chrout(chr_vert)
|
||||||
txt.nl()
|
txt.nl()
|
||||||
}
|
}
|
||||||
print_down_indicator(false)
|
print_scroll_indicator(false, false)
|
||||||
txt.column(dialog_topx)
|
txt.column(dialog_topx)
|
||||||
footerline()
|
footerline()
|
||||||
selected_line = 0
|
selected_line = 0
|
||||||
@ -180,7 +178,7 @@ fileselector {
|
|||||||
|
|
||||||
ubyte key = cbm.GETIN2()
|
ubyte key = cbm.GETIN2()
|
||||||
when key {
|
when key {
|
||||||
3, 27, 'q' -> return 0 ; STOP or Q aborts (and ESC?)
|
3, 27 -> return 0 ; STOP and ESC aborts
|
||||||
'\n',' ' -> {
|
'\n',' ' -> {
|
||||||
if num_files>0 {
|
if num_files>0 {
|
||||||
void strings.copy(peekw(filename_ptrs_start + (top_index+selected_line)*$0002), &diskio.list_filename)
|
void strings.copy(peekw(filename_ptrs_start + (top_index+selected_line)*$0002), &diskio.list_filename)
|
||||||
@ -310,29 +308,19 @@ fileselector {
|
|||||||
sub print_up_and_down() {
|
sub print_up_and_down() {
|
||||||
if num_files<=max_lines
|
if num_files<=max_lines
|
||||||
return
|
return
|
||||||
print_up_indicator(top_index>0)
|
print_scroll_indicator(top_index>0, true)
|
||||||
print_down_indicator(top_index + num_visible_files < num_files)
|
print_scroll_indicator(top_index + num_visible_files < num_files, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
sub print_up_indicator(bool shown) {
|
sub print_scroll_indicator(bool visible, bool up) {
|
||||||
txt.plot(dialog_topx, dialog_topy+5)
|
txt.plot(dialog_topx, dialog_topy + (if up 5 else 6+num_visible_files))
|
||||||
txt.chrout(chr_vert)
|
|
||||||
txt.column(dialog_topx+26)
|
|
||||||
if shown
|
|
||||||
txt.print("(up)")
|
|
||||||
else
|
|
||||||
txt.print(" ")
|
|
||||||
txt.spc()
|
|
||||||
txt.chrout(chr_vert)
|
|
||||||
txt.nl()
|
|
||||||
}
|
|
||||||
|
|
||||||
sub print_down_indicator(bool shown) {
|
|
||||||
txt.plot(dialog_topx, dialog_topy+6+num_visible_files)
|
|
||||||
txt.chrout(chr_vert)
|
txt.chrout(chr_vert)
|
||||||
txt.column(dialog_topx+24)
|
txt.column(dialog_topx+24)
|
||||||
if shown
|
if visible
|
||||||
txt.print("(down)")
|
if up
|
||||||
|
txt.print(" (up)")
|
||||||
|
else
|
||||||
|
txt.print("(down)")
|
||||||
else
|
else
|
||||||
txt.print(" ")
|
txt.print(" ")
|
||||||
txt.spc()
|
txt.spc()
|
||||||
@ -342,12 +330,15 @@ fileselector {
|
|||||||
|
|
||||||
sub footerline() {
|
sub footerline() {
|
||||||
txt.chrout(chr_botleft)
|
txt.chrout(chr_botleft)
|
||||||
linepart()
|
linepart(false)
|
||||||
txt.chrout(chr_botright)
|
txt.chrout(chr_botright)
|
||||||
}
|
}
|
||||||
|
|
||||||
sub linepart() {
|
sub linepart(bool top) {
|
||||||
repeat 30 txt.chrout(chr_horiz)
|
cx16.r0L = chr_horiz_other
|
||||||
|
if top
|
||||||
|
cx16.r0L = chr_horiz_top
|
||||||
|
repeat 30 txt.chrout(cx16.r0L)
|
||||||
}
|
}
|
||||||
|
|
||||||
sub select_line(ubyte line) {
|
sub select_line(ubyte line) {
|
||||||
@ -373,15 +364,18 @@ fileselector {
|
|||||||
chr_topright = iso:'ì'
|
chr_topright = iso:'ì'
|
||||||
chr_botleft = iso:'`'
|
chr_botleft = iso:'`'
|
||||||
chr_botright = iso:'\''
|
chr_botright = iso:'\''
|
||||||
chr_jointleft = chr_jointright = iso:':'
|
chr_jointleft = chr_jointright = iso:'÷'
|
||||||
chr_vert = iso:'|'
|
chr_vert = iso:'|'
|
||||||
chr_horiz = iso:'-'
|
chr_horiz_top = iso:'¯'
|
||||||
|
chr_horiz_other = iso:'-'
|
||||||
} else {
|
} else {
|
||||||
|
; PETSCII box symbols
|
||||||
chr_topleft = '┌'
|
chr_topleft = '┌'
|
||||||
chr_topright = '┐'
|
chr_topright = '┐'
|
||||||
chr_botleft = '└'
|
chr_botleft = '└'
|
||||||
chr_botright = '┘'
|
chr_botright = '┘'
|
||||||
chr_horiz = '─'
|
chr_horiz_top = '─'
|
||||||
|
chr_horiz_other = '─'
|
||||||
chr_vert = '│'
|
chr_vert = '│'
|
||||||
chr_jointleft = '├'
|
chr_jointleft = '├'
|
||||||
chr_jointright = '┤'
|
chr_jointright = '┤'
|
||||||
@ -436,3 +430,53 @@ fileselector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sorting {
|
||||||
|
; note: cannot use the sorting library module because that relies on zeropage to be directly available (@requirezp pointer)
|
||||||
|
; and this code is meant to be able to being used without zeropage as well (except for R0-R15).
|
||||||
|
|
||||||
|
sub shellsort_pointers(uword stringpointers_array, ubyte num_elements) {
|
||||||
|
; Comparefunc must be a routine that accepts 2 pointers in R0 and R1, and must return with Carry=1 if R0<=R1, otherwise Carry=0.
|
||||||
|
; One such function, to compare strings, is provided as 'string_comparator' below.
|
||||||
|
cx16.r2 = stringpointers_array ; need zeropage pointer
|
||||||
|
num_elements--
|
||||||
|
ubyte gap
|
||||||
|
for gap in [132, 57, 23, 10, 4, 1] {
|
||||||
|
ubyte i
|
||||||
|
for i in gap to num_elements {
|
||||||
|
cx16.r1 = peekw(cx16.r2+i*$0002)
|
||||||
|
ubyte @zp j = i
|
||||||
|
ubyte @zp k = j-gap
|
||||||
|
while j>=gap {
|
||||||
|
cx16.r0 = peekw(cx16.r2+k*2)
|
||||||
|
if string_comparator(cx16.r0, cx16.r1)
|
||||||
|
break
|
||||||
|
pokew(cx16.r2+j*2, cx16.r0)
|
||||||
|
j = k
|
||||||
|
k -= gap
|
||||||
|
}
|
||||||
|
pokew(cx16.r2+j*2, cx16.r1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
asmsub string_comparator(uword string1 @R0, uword string2 @R1) -> bool @Pc {
|
||||||
|
; R0 and R1 are the two strings, must return Carry=1 when R0<=R1, else Carry=0
|
||||||
|
%asm {{
|
||||||
|
lda cx16.r1L
|
||||||
|
ldy cx16.r1H
|
||||||
|
sta P8ZP_SCRATCH_W2
|
||||||
|
sty P8ZP_SCRATCH_W2+1
|
||||||
|
lda cx16.r0L
|
||||||
|
ldy cx16.r0H
|
||||||
|
jsr prog8_lib.strcmp_mem
|
||||||
|
cmp #1
|
||||||
|
bne +
|
||||||
|
clc
|
||||||
|
rts
|
||||||
|
+ sec
|
||||||
|
rts
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user