%import diskio %import floats %zeropage basicsafe %option no_sysinit main { const ubyte HIRAM_START_BANK = 4 uword large = memory("large", 20000, 256) ubyte[256] buffer = 0 to 255 uword @zp buf_ptr sub start() { txt.print("\n\ndisk benchmark on drive 8.\n") txt.print("with verification? y/n: ") bool verify = cbm.CHRIN()=='y' txt.print("\nfast serial mode r+w? y/n: ") bool fastserial = cbm.CHRIN()=='y' txt.nl() if verify { ; fill the buffers with random data, and calculate the checksum for cx16.r0 in 0 to 19999 { large[cx16.r0] = math.rnd() } for cx16.r0L in 0 to 255 { buffer[cx16.r0L] = math.rnd() } math.crc32(large, 20000) uword crc32_l = cx16.r14 uword crc32_h = cx16.r15 } if fastserial void diskio.fastmode(3) else void diskio.fastmode(0) test_save() test_save_blocks() test_load_hiram() test_read_blocks() test_vload() txt.nl() txt.print(diskio.status()) txt.print("\ndone.\n") diskio.delete("benchmark0.dat") diskio.delete("benchmark1.dat") diskio.delete("benchmark2.dat") diskio.delete("benchmark3.dat") diskio.delete("benchmark4.dat") diskio.delete("benchmark5.dat") diskio.delete("benchmark6.dat") diskio.delete("benchmark7.dat") diskio.delete("benchmark8.dat") diskio.delete("benchmark9.dat") diskio.delete("benchmark256.dat") diskio.delete("benchmark64.dat") return sub test_save() { txt.print("\n\x12diskio.save()\x92 writing 10*20kb=200kb total") cbm.SETTIM(0,0,0) ; save 10 times 20Kb to make it 200Kb total void diskio.save("@:benchmark0.dat", large, 20000) void diskio.save("@:benchmark1.dat", large, 20000) void diskio.save("@:benchmark2.dat", large, 20000) void diskio.save("@:benchmark3.dat", large, 20000) void diskio.save("@:benchmark4.dat", large, 20000) void diskio.save("@:benchmark5.dat", large, 20000) void diskio.save("@:benchmark6.dat", large, 20000) void diskio.save("@:benchmark7.dat", large, 20000) void diskio.save("@:benchmark8.dat", large, 20000) void diskio.save("@:benchmark9.dat", large, 20000) print_speed(200000.0, cbm.RDTIM16()) if verify { txt.print("\nverifying...\n") verify_20k("benchmark0.dat", crc32_l, crc32_h) verify_20k("benchmark1.dat", crc32_l, crc32_h) verify_20k("benchmark2.dat", crc32_l, crc32_h) verify_20k("benchmark3.dat", crc32_l, crc32_h) verify_20k("benchmark4.dat", crc32_l, crc32_h) verify_20k("benchmark5.dat", crc32_l, crc32_h) verify_20k("benchmark6.dat", crc32_l, crc32_h) verify_20k("benchmark7.dat", crc32_l, crc32_h) verify_20k("benchmark8.dat", crc32_l, crc32_h) verify_20k("benchmark9.dat", crc32_l, crc32_h) } } sub test_save_blocks() { txt.print("\n\x12diskio.f_write()\x92 writing 256kb in blocks of 256 bytes") if diskio.f_open_w("@:benchmark256.dat") { cbm.SETTIM(0,0,0) repeat 256*1024/256 { if not diskio.f_write(buffer, 256) { io_error() } } diskio.f_close_w() print_speed(256*1024.0, cbm.RDTIM16()) } else sys.exit(1) if verify { txt.print("\ncalculating crc32 (takes a while)...") math.crc32_start() buf_ptr = &buffer repeat 256*1024/256 { for cx16.r9L in 0 to 255 { math.crc32_update(buf_ptr[cx16.r9L]) } } math.crc32_end() crc32_l = cx16.r14 crc32_h = cx16.r15 txt.nl() } } sub test_load_hiram() { txt.print("\n\x12diskio.load()\x92 reading 512kb into hiram (2*256)") cbm.SETTIM(0,0,0) cx16.rambank(HIRAM_START_BANK) uword result = diskio.load_raw("benchmark256.dat", $a000) if result==0 { io_error() } if result!=$a000 or cx16.getrambank()!=HIRAM_START_BANK+32 { txt.nl() txt.print("invalid read size!\n") sys.exit(1) } print_speed(256*1024.0, cbm.RDTIM16()) cx16.rambank(HIRAM_START_BANK) if verify { txt.print("\ncalculating crc32 (takes a while)...") math.crc32_start() ubyte ram_bank for ram_bank in HIRAM_START_BANK to HIRAM_START_BANK+32-1 { cx16.rambank(ram_bank) for buf_ptr in $a000 to $bfff { math.crc32_update(@(buf_ptr)) } } math.crc32_end() compare_crc32(cx16.r14, cx16.r15, crc32_l, crc32_h) } } sub test_read_blocks() { txt.print("\n\x12diskio.f_read()\x92 reading 256kb in blocks of 256") if diskio.f_open("benchmark256.dat") { cbm.SETTIM(0,0,0) repeat 256*1024/256 { if diskio.f_read(buffer, 256)==0 { io_error() } } diskio.f_close() print_speed(256*1024.0, cbm.RDTIM16()) } else sys.exit(1) if verify { txt.print("\ncrc checking block reads...") math.crc32_start() if diskio.f_open("benchmark256.dat") { repeat 256*1024/256 { if diskio.f_read(buffer, 256)==0 { io_error() } buf_ptr = &buffer for cx16.r9L in 0 to 255 { math.crc32_update(buf_ptr[cx16.r9L]) } } diskio.f_close() } else sys.exit(1) math.crc32_end() compare_crc32(cx16.r14, cx16.r15, crc32_l, crc32_h) } } sub test_vload() { txt.print("\npreparing 64kb test file") bool success = false if diskio.f_open_w("@:benchmark64.dat") { if not diskio.f_write(large, 20000) or not diskio.f_write(large, 20000) or not diskio.f_write(large, 20000) or not diskio.f_write(large, 5536) { io_error() } diskio.f_close_w() } if verify { txt.print("\ncalculating crc32 (takes a while)...") math.crc32_start() repeat 3 { for buf_ptr in large to large+20000-1 { math.crc32_update(@(buf_ptr)) } } for buf_ptr in large to large+5536-1 { math.crc32_update(@(buf_ptr)) } math.crc32_end() crc32_l = cx16.r14 crc32_h = cx16.r15 txt.nl() } txt.print("\n\x12diskio.vload()\x92 reading 512kb into vram (8*64kb)") cbm.SETTIM(0,0,0) repeat 8 { if not diskio.vload_raw("benchmark64.dat", 0, $0000) { io_error() } } print_speed(512*1024.0, cbm.RDTIM16()) if verify { math.crc32_start() txt.print("\ncalculating crc32 (takes a while)...") cx16.vaddr(0,0, 0, 1) repeat 1024 { repeat 64 { math.crc32_update(cx16.VERA_DATA0) } } math.crc32_end() compare_crc32(cx16.r14, cx16.r15, crc32_l, crc32_h) } } } sub verify_20k(str filename, uword crc32_low, uword crc32_high) { txt.print(filename) txt.spc() sys.memset(large, 20000, 0) uword end = diskio.load(filename, large) if end!=large+20000 { txt.print("invalid read size!\n") sys.exit(1) } math.crc32(large, 20000) compare_crc32(cx16.r14, cx16.r15, crc32_low, crc32_high) } sub compare_crc32(uword low_check, uword high_check, uword crc32_low, uword crc32_high) { if low_check!=crc32_low or high_check!=crc32_high { txt.nl() txt.print_uwhex(cx16.r15, true) txt.print_uwhex(cx16.r14, false) txt.spc() txt.print_uwhex(crc32_high, true) txt.print_uwhex(crc32_low, false) txt.spc() txt.print("crc32") txt.print(" mismatch!\n") sys.exit(1) } txt.print("crc32") txt.print(" ok\n") } sub print_speed(float total_size, uword jiffies) { if jiffies==0 { txt.print("\n 0 jiffies measured, speed is extremely high\n") return } float speed = floats.floor(total_size / (jiffies as float / 60.0)) txt.nl() txt.print_uw(jiffies) txt.print(" jiffies = ") floats.print(speed) txt.print(" bytes/sec\n") } sub io_error() { txt.print("\ni/o error! ") txt.print(diskio.status()) sys.exit(1) } }