CX16: diskio.f_write() now uses fast MCIOUT block writes, including hiram bank boundary wrap-over

This commit is contained in:
Irmen de Jong 2023-11-07 23:39:39 +01:00
parent ff324955dd
commit c5a333a904
3 changed files with 53 additions and 79 deletions

View File

@ -312,13 +312,12 @@ close_end:
reset_read_channel()
list_blocks = 0 ; we reuse this variable for the total number of bytes read
; commander X16 supports fast block-read via MACPTR() kernal call
uword readsize
while num_bytes {
readsize = 255
if num_bytes<readsize
readsize = num_bytes
readsize = cx16.MACPTR(lsb(readsize), bufferpointer, false)
readsize = cx16.MACPTR(lsb(readsize), bufferpointer, false) ; fast block reads
if_cs
goto byte_read_loop ; MACPTR block read not supported, do fallback loop
list_blocks += readsize
@ -433,6 +432,21 @@ _end rts
; -- write the given number of bytes to the currently open file
if num_bytes!=0 {
reset_write_channel()
do {
cx16.r0 = cx16.MCIOUT(lsb(num_bytes), bufferpointer, false) ; fast block writes
if_cs
goto no_mciout
num_bytes -= cx16.r0
bufferpointer += cx16.r0
if msb(bufferpointer) == $c0
bufferpointer = mkword($a0, lsb(bufferpointer)) ; wrap over bank boundary
if cbm.READST()!=0
return false
} until num_bytes==0
return not cbm.READST()
no_mciout:
; the device doesn't support MCIOUT, use a normal per-byte write loop
repeat num_bytes {
cbm.CHROUT(@(bufferpointer))
bufferpointer++

View File

@ -21,7 +21,7 @@ while still being low level enough to create high performance programs.
You can compile programs for various machines with this CPU:
* Commodore 64
* Commander X16 (release R42 or newer is required)
* Commander X16
* Commodore 128 (limited support for now)
* Atari 800 XL (limited support for now)
@ -181,7 +181,7 @@ For MacOS you can use the Homebrew system to install a recent version of OpenJDK
Finally: an **emulator** (or a real machine of course) to test and run your programs on.
In C64 mode, the compiler assumes the presence of the `VICE emulator <http://vice-emu.sourceforge.net/>`_.
If you're targeting the Commander X16 instead,
download a recent emulator version (R42 or newer) for the CommanderX16, such as `x16emu <https://cx16forum.com/forum/viewforum.php?f=30>`_
download a recent emulator version for the CommanderX16, such as `x16emu <https://cx16forum.com/forum/viewforum.php?f=30>`_
(preferred, this is the official emulator. If required, source code is `here <https://github.com/X16Community/x16-emulator/>`_.
There is also `Box16 <https://github.com/indigodarkwolf/box16>`_ which has powerful debugging features.
You can select which one you want to launch using the ``-emu`` or ``-emu2`` command line options.

View File

@ -6,14 +6,13 @@
main {
ubyte[256] buffer = 0 to 255
const ubyte REPEATS = 2
sub print_speed(uword jiffies) {
if jiffies==0 {
txt.print("\n 0 jiffies measured, speed is extremely high\n")
return
}
float speed = 65536.0 * REPEATS / (jiffies as float / 60.0)
float speed = floats.floor(65536.0 / (jiffies as float / 60.0))
txt.nl()
txt.print_uw(jiffies)
txt.print(" jiffies = ")
@ -22,95 +21,56 @@ main {
}
sub start() {
txt.print("\n\ndisk benchmark. drive 8. repeats = ")
txt.print_ub(REPEATS)
txt.print("\n\ndisk benchmark on drive 8.\n\n")
uword batchtotaltime
txt.print("\n\nwriting 64kb using save")
batchtotaltime = 0
repeat REPEATS {
cbm.SETTIM(0,0,0)
void diskio.save("@:benchmark.dat", $100, 32768)
void diskio.save("@:benchmark.dat", $100, 32768)
batchtotaltime += cbm.RDTIM16()
txt.chrout('.')
}
print_speed(batchtotaltime)
txt.print("writing 64kb using save()")
cbm.SETTIM(0,0,0)
; save 2 times 32Kb to make it 64Kb total
void diskio.save("@:benchmark.dat", $100, 32768)
void diskio.save("@:benchmark.dat", $100, 32768)
print_speed(cbm.RDTIM16())
txt.print("\nwriting 64kb sequentially")
batchtotaltime = 0
repeat REPEATS {
if diskio.f_open_w("@:benchmark.dat") {
cbm.SETTIM(0,0,0)
repeat 65536/256 {
if not diskio.f_write(buffer, 256)
sys.exit(1)
}
batchtotaltime += cbm.RDTIM16()
diskio.f_close_w()
if diskio.f_open_w("@:benchmark.dat") {
cbm.SETTIM(0,0,0)
repeat 65536/256 {
if not diskio.f_write(buffer, 256)
sys.exit(1)
}
txt.chrout('.')
diskio.f_close_w()
print_speed(cbm.RDTIM16())
}
print_speed(batchtotaltime)
txt.print("\nreading 64kb using load into hiram")
batchtotaltime = 0
repeat REPEATS {
cbm.SETTIM(0,0,0)
cx16.rambank(4)
if not diskio.load("benchmark.dat", $a000)
sys.exit(1)
batchtotaltime += cbm.RDTIM16()
txt.chrout('.')
}
print_speed(batchtotaltime)
txt.print("\nreading 64kb using load() into hiram")
cbm.SETTIM(0,0,0)
cx16.rambank(4)
if not diskio.load("benchmark.dat", $a000)
sys.exit(1)
print_speed(cbm.RDTIM16())
txt.print("\nreading 64kb using vload into videoram")
batchtotaltime = 0
repeat REPEATS {
cbm.SETTIM(0,0,0)
if not diskio.vload("benchmark.dat", 0, $0000)
sys.exit(1)
batchtotaltime += cbm.RDTIM16()
txt.chrout('.')
}
print_speed(batchtotaltime)
txt.print("\nreading 64kb using vload() into vram")
cbm.SETTIM(0,0,0)
if not diskio.vload("benchmark.dat", 0, $0000)
sys.exit(1)
print_speed(cbm.RDTIM16())
txt.print("\nreading 64kb sequentially")
batchtotaltime = 0
repeat REPEATS {
if diskio.f_open("benchmark.dat") {
cbm.SETTIM(0,0,0)
repeat 65536/255 {
if not diskio.f_read(buffer, 255)
sys.exit(1)
}
batchtotaltime += cbm.RDTIM16()
diskio.f_close()
if diskio.f_open("benchmark.dat") {
cbm.SETTIM(0,0,0)
repeat 65536/255 {
if not diskio.f_read(buffer, 255)
sys.exit(1)
}
txt.chrout('.')
diskio.f_close()
print_speed(cbm.RDTIM16())
}
print_speed(batchtotaltime)
txt.print("\nreading 64kb sequentially (x16 optimized)")
batchtotaltime = 0
repeat REPEATS {
if diskio.f_open("benchmark.dat") {
cbm.SETTIM(0,0,0)
repeat 65536/255 {
if not diskio.f_read(buffer, 255)
sys.exit(1)
}
batchtotaltime += cbm.RDTIM16()
diskio.f_close()
}
txt.chrout('.')
}
print_speed(batchtotaltime)
txt.nl()
txt.print(diskio.status())
txt.print("\ndone.\n")
diskio.delete("benchmark.dat")
}
}