diff --git a/compiler/res/prog8lib/cx16/cx16diskio.p8 b/compiler/res/prog8lib/cx16/cx16diskio.p8 index 3cc1081d2..e2c41d5ed 100644 --- a/compiler/res/prog8lib/cx16/cx16diskio.p8 +++ b/compiler/res/prog8lib/cx16/cx16diskio.p8 @@ -20,13 +20,14 @@ cx16diskio { ; Use kernal LOAD routine to load the given file in memory. ; INCLUDING the first 2 bytes in the file: no program header is assumed in the file. - ; This is different from Basic's LOAD instruction which always skips the first two bytes. ; The load address is mandatory. Returns the number of bytes loaded. + ; If you load into regular system ram, use cx16.getrambank() for the bank argument, + ; or alternatively make sure to reset the correct ram bank yourself after the load! ; Returns the end load address+1 if successful or 0 if a load error occurred. ; You can use the load_size() function to calcuate the size of the file that was loaded. sub load_raw(ubyte drivenumber, uword filenameptr, ubyte bank, uword address) -> uword { cx16.rambank(bank) - return diskio.load_raw(drivenumber, filenameptr, address) + return diskio.load_headerless_cx16(drivenumber, filenameptr, address, true) } ; For use directly after a load or load_raw call (don't mess with the ram bank yet): diff --git a/compiler/res/prog8lib/diskio.p8 b/compiler/res/prog8lib/diskio.p8 index 56f4017ca..7fa9169b9 100644 --- a/compiler/res/prog8lib/diskio.p8 +++ b/compiler/res/prog8lib/diskio.p8 @@ -445,11 +445,43 @@ io_error: ; because it doesn't take the number of ram banks into account. ; Consider using cx16diskio.load() instead. sub load(ubyte drivenumber, uword filenameptr, uword address_override) -> uword { + return load_headerless_cx16(drivenumber, filenameptr, address_override, false) + } + + ; Use kernal LOAD routine to load the given file in memory. + ; INCLUDING the first 2 bytes in the file: no program header is assumed in the file. + ; This is different from Basic's LOAD instruction which always skips the first two bytes. + ; The load address is mandatory. + ; Returns the end load address+1 if successful or 0 if a load error occurred. + ; NOTE: when the load is larger than 64Kb and/or spans multiple RAM banks + ; (which is possible on the Commander X16), the returned size is not correct, + ; because it doesn't take the number of ram banks into account. + ; Consider using cx16diskio.load_raw() instead on the Commander X16. + sub load_raw(ubyte drivenumber, uword filenameptr, uword address) -> uword { + if sys.target==16 ; are we on commander X16? + return load_headerless_cx16(drivenumber, filenameptr, address, true) + ; fallback to reading the 2 header bytes separately + if not f_open(drivenumber, filenameptr) + return 0 + cx16.r1 = f_read(address, 2) + f_close() + if cx16.r1!=2 + return 0 + address += 2 + return load(drivenumber, filenameptr, address) + } + + + ; Internal routine, only to be used on Commander X16 platform if headerless=true, + ; because this routine uses kernal support for that to load headerless files. + sub load_headerless_cx16(ubyte drivenumber, uword filenameptr, uword address_override, ubyte headerless) -> uword { c64.SETNAM(string.length(filenameptr), filenameptr) ubyte secondary = 1 cx16.r1 = 0 if address_override secondary = 0 + if headerless + secondary |= %00000010 ; activate cx16 kernal headerless load support c64.SETLFS(1, drivenumber, secondary) %asm {{ stx P8ZP_SCRATCH_REG @@ -468,26 +500,6 @@ io_error: return cx16.r1 } - ; Use kernal LOAD routine to load the given file in memory. - ; INCLUDING the first 2 bytes in the file: no program header is assumed in the file. - ; This is different from Basic's LOAD instruction which always skips the first two bytes. - ; The load address is mandatory. - ; Returns the end load address+1 if successful or 0 if a load error occurred. - ; NOTE: when the load is larger than 64Kb and/or spans multiple RAM banks - ; (which is possible on the Commander X16), the returned size is not correct, - ; because it doesn't take the number of ram banks into account. - ; Consider using cx16diskio.load_raw() instead. - sub load_raw(ubyte drivenumber, uword filenameptr, uword address) -> uword { - if not f_open(drivenumber, filenameptr) - return 0 - cx16.r1 = f_read(address, 2) - f_close() - if cx16.r1!=2 - return 0 - address += 2 - return load(drivenumber, filenameptr, address) - } - sub delete(ubyte drivenumber, uword filenameptr) { ; -- delete a file on the drive filename[0] = 's' diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 62110c438..829c34c53 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -3,9 +3,6 @@ TODO For next release ^^^^^^^^^^^^^^^^ -- x16: optimize diskio load_raw because headerless files are now supported https://github.com/commanderx16/x16-rom/pull/216 - note: must still work on c64/c128 that don't have this! - - vm codegen: When - vm codegen: Pipe expression - vm codegen: validate that PtFunctionCall translation works okay with resultregister, and multiple paramsters in correct order