From 34babfb5dea62d5ded3aa5535ae51c4f1cf114b8 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Fri, 11 Dec 2020 22:36:14 +0100 Subject: [PATCH] added diskio.list_files(). ci-viewer now loads all *.ci files it finds. --- compiler/res/prog8lib/diskio.p8 | 61 +++++++++++++++++++++++------ docs/source/todo.rst | 1 + examples/cx16/imgviewer/civiewer.p8 | 32 ++++++++------- examples/dirlist.p8 | 3 ++ 4 files changed, 70 insertions(+), 27 deletions(-) diff --git a/compiler/res/prog8lib/diskio.p8 b/compiler/res/prog8lib/diskio.p8 index cc9e21f6a..2c6e126bb 100644 --- a/compiler/res/prog8lib/diskio.p8 +++ b/compiler/res/prog8lib/diskio.p8 @@ -10,11 +10,11 @@ diskio { ; -- Prints the directory contents of disk drive 8-11 to the screen. Returns success. c64.SETNAM(1, "$") - c64.SETLFS(1, drivenumber, 0) - void c64.OPEN() ; open 1,8,0,"$" + c64.SETLFS(13, drivenumber, 0) + void c64.OPEN() ; open 13,8,0,"$" if_cs goto io_error - void c64.CHKIN(1) ; use #1 as input channel + void c64.CHKIN(13) ; use #13 as input channel if_cs goto io_error @@ -39,14 +39,14 @@ diskio { void c64.CHRIN() status = c64.READST() void c64.STOP() - if_nz + if_z break } io_error: status = c64.READST() c64.CLRCHN() ; restore default i/o devices - c64.CLOSE(1) + c64.CLOSE(13) if status and status != 64 { ; 64=end of file txt.print("\ni/o error, status: ") @@ -66,13 +66,41 @@ io_error: uword list_pattern uword list_blocks ubyte iteration_in_progress = false - str list_filename = "????????????????" + str list_filename = "?" * 32 + ; ----- get a list of files (uses iteration functions internally ----- + + sub list_files(ubyte drivenumber, uword pattern, ubyte suffixmatch, uword name_ptrs, ubyte max_names) -> ubyte { + ; -- fill the array 'name_ptrs' with (pointers to) the names of the files requested. + ubyte[256] names_buffer + uword buf_ptr = &names_buffer + ubyte files_found = 0 + if lf_start_list(drivenumber, pattern, suffixmatch) { + while lf_next_entry() { + @(name_ptrs) = lsb(buf_ptr) + name_ptrs++ + @(name_ptrs) = msb(buf_ptr) + name_ptrs++ + ; ubyte length = strcpy(diskio.list_filename, buf_ptr) + memcopy(diskio.list_filename, buf_ptr, strlen(list_filename)+1) ; todo replace with strcpy() + buf_ptr += strlen(list_filename)+1 + files_found++ + if buf_ptr - &names_buffer > 256-18 + break + if files_found == max_names + break + } + lf_end_list() + } + return files_found + } + ; ----- iterative file lister functions ----- sub lf_start_list(ubyte drivenumber, uword pattern, ubyte suffixmatch) -> ubyte { ; -- start an iterative file listing with optional prefix or suffix name matching. + ; note: only a single iteration loop can be active at a time! lf_end_list() list_pattern = pattern list_suffixmatch = suffixmatch @@ -84,11 +112,11 @@ io_error: list_pattern_size = strlen(pattern) c64.SETNAM(1, "$") - c64.SETLFS(1, drivenumber, 0) - void c64.OPEN() ; open 1,8,0,"$" + c64.SETLFS(12, drivenumber, 0) + void c64.OPEN() ; open 12,8,0,"$" if_cs goto io_error - void c64.CHKIN(1) ; use #1 as input channel + void c64.CHKIN(12) ; use #12 as input channel if_cs goto io_error @@ -112,10 +140,16 @@ io_error: if not iteration_in_progress return false - while not c64.READST() { + repeat { + void c64.CHKIN(12) ; use #12 as input channel again + uword nameptr = &list_filename ubyte blocks_lsb = c64.CHRIN() ubyte blocks_msb = c64.CHRIN() + + if c64.READST() + goto close_end + list_blocks = mkword(blocks_msb, blocks_lsb) ; read until the filename starts after the first " @@ -168,7 +202,7 @@ close_end: ; -- end an iterative file listing session (close channels). if iteration_in_progress { c64.CLRCHN() - c64.CLOSE(1) + c64.CLOSE(12) iteration_in_progress = false } } @@ -177,6 +211,8 @@ close_end: ; ----- iterative file loader functions ----- sub f_open(ubyte drivenumber, uword filenameptr) -> ubyte { + ; -- open a file for iterative reading with f_read + ; note: only a single iteration loop can be active at a time! f_close() c64.SETNAM(strlen(filenameptr), filenameptr) @@ -184,7 +220,7 @@ close_end: void c64.OPEN() ; open 11,8,0,"filename" if_cc { iteration_in_progress = true - void c64.CHKIN(11) ; use #2 as input channel + void c64.CHKIN(11) ; use #11 as input channel if_cc return true } @@ -197,6 +233,7 @@ close_end: return 0 uword actual = 0 + void c64.CHKIN(11) ; use #11 as input channel again repeat buffersize { ubyte data = c64.CHRIN() @(bufferpointer) = data diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 69ce21186..0471b8775 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -2,6 +2,7 @@ TODO ==== +- add strcpy() - see if we can group some errors together for instance the (now single) errors about unidentified symbols - Cx16 target: support full-screen 640x480 and 320x240 graphics? That requires our own custom graphics routines though to draw lines. - hoist all variable declarations up to the subroutine scope *before* even the constant folding takes place (to avoid undefined symbol errors when referring to a variable from another nested scope in the subroutine) diff --git a/examples/cx16/imgviewer/civiewer.p8 b/examples/cx16/imgviewer/civiewer.p8 index f0cf8385d..f5f1c0cc2 100644 --- a/examples/cx16/imgviewer/civiewer.p8 +++ b/examples/cx16/imgviewer/civiewer.p8 @@ -54,9 +54,20 @@ main { ubyte[256] buffer4 ; .. and some more to be able to store 1280= ubyte[256] buffer5 ; two 640 bytes worth of bitmap scanline data - str filename = "trsi256.ci" - sub start() { + str[20] filename_ptrs + ubyte num_files = diskio.list_files(8, ".ci", true, &filename_ptrs, len(filename_ptrs)) + while num_files { + num_files-- + show_image(filename_ptrs[num_files]) + } + + repeat { + ; endless loop + } + } + + sub show_image(uword filename) { ubyte read_success = false uword bitmap_load_address = progend() ; uword max_bitmap_size = $9eff - bitmap_load_address @@ -115,7 +126,7 @@ main { for y in 0 to lsb(height)-1 { void diskio.f_read(buffer, scanline_size) when bpp { - 8 -> display_scanline_256c(buffer, scanline_size) + 8 -> cx16.FB_set_pixels_from_buf(buffer, scanline_size) ; FB_set_pixels in rom v38 crashes with a size > 255 so we use our own replacement for now 4 -> display_scanline_16c(buffer, scanline_size) 2 -> display_scanline_4c(buffer, scanline_size) 1 -> display_scanline_2c(buffer, scanline_size) @@ -129,14 +140,10 @@ main { } diskio.f_close() - - if not read_success { + if not read_success txt.print("error!\n") - } - } - - repeat { - ; endless loop + else + txt.print("ok\n") } } @@ -171,11 +178,6 @@ main { } } - sub display_scanline_256c(uword dataptr, uword numbytes) { - ; FB_set_pixels in rom v38 crashes with a size > 255 so we use our own replacement for now - cx16.FB_set_pixels_from_buf(dataptr, numbytes) - } - sub display_scanline_16c(uword dataptr, uword numbytes) { ; TODO } diff --git a/examples/dirlist.p8 b/examples/dirlist.p8 index de0518f35..36b485370 100644 --- a/examples/dirlist.p8 +++ b/examples/dirlist.p8 @@ -6,6 +6,9 @@ main { sub start() { + txt.print("showing the full directory of drive 8:\n") + diskio.directory(8) + txt.chrout('\n') if diskio.lf_start_list(8, "cub", false) { txt.print("\nfiles starting with 'cub':\n")