From aa3bbbb8671fe85644599a77aa4984cfc9976789 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Tue, 23 Dec 2025 03:47:54 +0100 Subject: [PATCH] tweaks to wav streaming examples --- codeCore/src/prog8/code/core/Enumerations.kt | 1 + .../cpu6502/assignment/AssignmentAsmGen.kt | 9 +- docs/source/todo.rst | 4 + examples/cx16/pcmaudio/play-adpcm.p8 | 4 +- examples/cx16/pcmaudio/stream-wav.p8 | 104 +++++++++++++----- examples/cx16/pcmaudio/wavfile.p8 | 6 +- examples/cx16/showbmx.p8 | 2 +- 7 files changed, 91 insertions(+), 39 deletions(-) diff --git a/codeCore/src/prog8/code/core/Enumerations.kt b/codeCore/src/prog8/code/core/Enumerations.kt index 1929e9cd7..4a9929360 100644 --- a/codeCore/src/prog8/code/core/Enumerations.kt +++ b/codeCore/src/prog8/code/core/Enumerations.kt @@ -51,6 +51,7 @@ val BaseDataType.isByte get() = this in arrayOf(BaseDataType.UBYTE, BaseDataType val BaseDataType.isByteOrBool get() = this in arrayOf(BaseDataType.UBYTE, BaseDataType.BYTE, BaseDataType.BOOL) val BaseDataType.isWord get() = this in arrayOf(BaseDataType.UWORD, BaseDataType.WORD) val BaseDataType.isLong get() = this == BaseDataType.LONG +val BaseDataType.isFloat get() = this == BaseDataType.FLOAT val BaseDataType.isInteger get() = this in arrayOf(BaseDataType.UBYTE, BaseDataType.BYTE, BaseDataType.UWORD, BaseDataType.WORD, BaseDataType.LONG) val BaseDataType.isIntegerOrBool get() = this in arrayOf(BaseDataType.UBYTE, BaseDataType.BYTE, BaseDataType.UWORD, BaseDataType.WORD, BaseDataType.LONG, BaseDataType.BOOL) val BaseDataType.isWordOrByteOrBool get() = this in arrayOf(BaseDataType.UBYTE, BaseDataType.BYTE, BaseDataType.UWORD, BaseDataType.WORD, BaseDataType.BOOL) diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt index f55d43680..4828490de 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt @@ -2803,6 +2803,9 @@ $endLabel""") assignExpressionToRegister(value, RegisterOrPair.AY, true) asmgen.out(" jsr floats.GIVAYFAY") } + valueDt.isLong -> { + TODO("assign typecasted long to float ${value.position}") + } else -> throw AssemblyError("invalid dt at ${target.position}") } if(target.register==RegisterOrPair.FAC2) { @@ -3294,10 +3297,12 @@ $endLabel""") asmgen.out(" lda cx16.$startreg | sta $targetAsmVarName") } else if(targetDt.isWord || targetDt.isPointer) { asmgen.out(" lda cx16.$startreg | sta $targetAsmVarName | lda cx16.$startreg+1 | sta $targetAsmVarName+1") + } else if(targetDt.isFloat) { + TODO("assign type casted long register $regs to float - use temporary variable for now. Target var=$targetAsmVarName") } else - throw AssemblyError("weird type") + throw AssemblyError("weird type $targetDt") } - else -> throw AssemblyError("weird type") + else -> throw AssemblyError("weird type $sourceDt") } } diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 159864fc1..98a6513a6 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -1,6 +1,10 @@ TODO ==== +- implement this: float @shared fl1 = cx16.r0r1sl / 1.234 +- implement this: float @shared fl2 = (cx16.r0r1sl - cx16.r2r3sl) as float +- implement this: float @shared fl3 = -cx16.r0r1sl as float + Weird Heisenbug ^^^^^^^^^^^^^^^ - BUG: examples/cube3d-float crashes with div by zero error on C64 (works on cx16. ALready broken in v11, v10 still worked) diff --git a/examples/cx16/pcmaudio/play-adpcm.p8 b/examples/cx16/pcmaudio/play-adpcm.p8 index 18f4f9749..b8d19dd4b 100644 --- a/examples/cx16/pcmaudio/play-adpcm.p8 +++ b/examples/cx16/pcmaudio/play-adpcm.p8 @@ -71,7 +71,7 @@ main { } sub calculate_adpcm_blocks() { - adpcm_size = wavfile.data_size_lo ; we assume the data is <64Kb so only low word is enough + adpcm_size = lsw(wavfile.data_size) ; we assume the data is <64Kb so only low word is enough num_adpcm_blocks = (adpcm_size / 256) as ubyte ; THE ADPCM DATA NEEDS TO BE ENCODED IN 256-byte BLOCKS ! } @@ -207,7 +207,7 @@ stereo { } sub decode_block() { - ; refill the fifo buffer with one decoded adpcm block (1010 bytes of pcm data) TODO 996 rather for stereo? + ; refill the fifo buffer with one decoded adpcm block (996 bytes of pcm data) adpcm.init(peekw(main.nibblesptr), @(main.nibblesptr+2)) ; left channel cx16.VERA_AUDIO_DATA = lsb(adpcm.predict) cx16.VERA_AUDIO_DATA = msb(adpcm.predict) diff --git a/examples/cx16/pcmaudio/stream-wav.p8 b/examples/cx16/pcmaudio/stream-wav.p8 index d4c6b9350..54dba47b8 100644 --- a/examples/cx16/pcmaudio/stream-wav.p8 +++ b/examples/cx16/pcmaudio/stream-wav.p8 @@ -29,28 +29,32 @@ main { ubyte vera_rate sub start() { - diskio.fastmode(1) + void diskio.fastmode(1) txt.print("name of .wav file to play on drive 8: ") while 0==txt.input_chars(MUSIC_FILENAME) { ; until user types a name... } prepare_music() - txt.print("\ngood file! playback starts! ") - cx16.rombank(0) ; activate kernal bank for faster calls - interrupts.wait() + txt.print("\ngood file! playback starts!\n\n") interrupts.set_handler() play_stuff() - txt.print("done!\n") - repeat { } + txt.print("\n\ndone!\n") + repeat { + if cbm.GETIN2()!=0 + sys.reset_system() + } } sub error(str msg) { txt.print(msg) - repeat { } + repeat { + if cbm.GETIN2()!=0 + sys.reset_system() + } } sub prepare_music() { - txt.print("\nchecking ") + txt.print("\n\nchecking ") txt.print(MUSIC_FILENAME) txt.nl() bool wav_ok = false @@ -64,24 +68,25 @@ main { calculate_vera_rate() - txt.print("wav format: ") + txt.print(" wav format: ") txt.print_ub(wavfile.wavefmt) - txt.print("\nchannels: ") + txt.print("\n channels: ") txt.print_ub(wavfile.nchannels) - txt.print("\nsample rate: ") + txt.print("\n sample rate: ") txt.print_uw(wavfile.sample_rate) - txt.print("\nbits per sample: ") + txt.print("\n bits per sample: ") txt.print_uw(wavfile.bits_per_sample) - txt.print("\ndata size: ") - txt.print_uwhex(wavfile.data_size_hi, true) - txt.print_uwhex(wavfile.data_size_lo, false) - txt.print("\nvera rate: ") + txt.print("\n data size: ") + txt.print_l(wavfile.data_size) + txt.print(" = ") + txt.print_ulhex(wavfile.data_size, true) + txt.print("\n vera rate: ") txt.print_ub(vera_rate) txt.print(" = ") txt.print_uw(vera_rate_hz) txt.print(" hz\n") if wavfile.wavefmt==wavfile.WAVE_FORMAT_DVI_ADPCM { - txt.print("adpcm block size: ") + txt.print(" adpcm block size: ") txt.print_uw(wavfile.block_align) txt.nl() } @@ -123,8 +128,12 @@ main { music.pre_buffer(block_size) cx16.VERA_AUDIO_RATE = vera_rate ; start audio playback - str progress_chars = "-\\|/-\\|/" - ubyte progress = 0 + long prev_disk_read_bytes, prev_pcm_fifo_bytes + ubyte statx,staty + txt.print("disk i/o: ") + statx,staty = txt.get_cursor() + txt.print("\npcm fifo: ") + txt.print("\n idle: ") repeat { interrupts.wait() @@ -133,9 +142,10 @@ main { if not music.load_next_block(block_size) break ; Note: copying the samples into the fifo buffer is done by the aflow interrupt handler itself. - txt.chrout(progress_chars[progress/2 & 7]) - txt.chrout($9d) ; cursor left - progress++ + + print_stats() + prev_disk_read_bytes = music.disk_read_bytes + prev_pcm_fifo_bytes = music.pcm_fifo_bytes } } @@ -145,6 +155,26 @@ main { } cx16.VERA_AUDIO_RATE = 0 ; halt playback + + sub print_stats() { + ; don't print decimal numbers, that take quite a bit of cpu time to calculate + txt.plot(statx,staty) + txt.print_ulhex(music.disk_read_bytes, true) + txt.print(" +") + txt.print_uwhex(lsw(music.disk_read_bytes - prev_disk_read_bytes), true) + txt.print(" ") + txt.plot(statx,staty+1) + txt.print_ulhex(music.pcm_fifo_bytes, true) + txt.print(" +") + txt.print_uwhex(lsw(music.pcm_fifo_bytes - prev_pcm_fifo_bytes), true) + txt.print(" ") + txt.plot(statx,staty+2) + txt.print_uwhex(interrupts.idle_counter, true) + if interrupts.idle_counter < 100 + txt.print(" !!!") + else + txt.print(" ") + } } } @@ -160,11 +190,15 @@ interrupts { } bool aflow + uword idle_counter - inline asmsub wait() { - %asm {{ - wai - }} + sub wait() { + ; NOTE: should be doing a WAI instruction here to wait for the next AFLOW irq + ; but we want to gather "idle time" counter statistics. + idle_counter = 0 + while not aflow { + idle_counter++ + } } sub handler() { @@ -193,12 +227,15 @@ interrupts { music { + long disk_read_bytes + long pcm_fifo_bytes + uword @requirezp nibblesptr uword buffer = memory("buffer", 1024, 256) sub pre_buffer(uword block_size) { ; pre-buffer first block - void diskio.f_read(buffer, block_size) + disk_read_bytes = diskio.f_read(buffer, block_size) } sub aflow_play_block() { @@ -208,20 +245,27 @@ music { if wavfile.nchannels==2 { adpcm_block_stereo() adpcm_block_stereo() + music.pcm_fifo_bytes += 996 * 2 } else { adpcm_block_mono() adpcm_block_mono() + music.pcm_fifo_bytes += 1010 * 2 } } - else if wavfile.bits_per_sample==16 + else if wavfile.bits_per_sample==16 { uncompressed_block_16() - else + music.pcm_fifo_bytes += 1024 + } + else { uncompressed_block_8() + music.pcm_fifo_bytes += 1024 + } } sub load_next_block(uword block_size) -> bool { ; read next block from disk into the buffer, for next time the irq triggers + disk_read_bytes += block_size return diskio.f_read(buffer, block_size) == block_size } @@ -318,7 +362,7 @@ _lp2 lda $ffff,y ; modified } sub adpcm_block_stereo() { - ; refill the fifo buffer with one decoded adpcm block (1010 bytes of pcm data) TODO 996 rather for stereo? + ; refill the fifo buffer with one decoded adpcm block (996 bytes of pcm data) adpcm.init(peekw(nibblesptr), @(nibblesptr+2)) ; left channel cx16.VERA_AUDIO_DATA = lsb(adpcm.predict) cx16.VERA_AUDIO_DATA = msb(adpcm.predict) diff --git a/examples/cx16/pcmaudio/wavfile.p8 b/examples/cx16/pcmaudio/wavfile.p8 index a96bef6c7..b6e5654b4 100644 --- a/examples/cx16/pcmaudio/wavfile.p8 +++ b/examples/cx16/pcmaudio/wavfile.p8 @@ -22,8 +22,7 @@ wavfile { ubyte wavefmt ubyte nchannels uword block_align - uword data_size_hi - uword data_size_lo + long data_size sub parse_header(uword wav_data) -> bool { ; "RIFF" , filesize (int32) , "WAVE", "fmt ", fmtsize (int32) @@ -52,8 +51,7 @@ wavfile { header += 8 + chunksize } - data_size_lo = chunksize - data_size_hi = peekw(header+6) + data_size = mklong2(peekw(header+6), chunksize) data_offset = header + 8 - wav_data return true } diff --git a/examples/cx16/showbmx.p8 b/examples/cx16/showbmx.p8 index 1ce13676f..f457d4715 100644 --- a/examples/cx16/showbmx.p8 +++ b/examples/cx16/showbmx.p8 @@ -12,7 +12,7 @@ main { str filename = "?"*40 repeat { - ;; diskio.fastmode(1) + ;; void diskio.fastmode(1) txt.print("\nenter bmx image filename: ") if txt.input_chars(&filename)!=0 {