From b7821cbc95209896ce0249604601d15988500e95 Mon Sep 17 00:00:00 2001 From: TomAwezome Date: Fri, 23 Dec 2022 22:41:22 -0500 Subject: [PATCH 01/23] Add temporary Sound dir and modified driver files. Sources: AC97: https://git.checksum.fail/alec/TOSamp HDAudio0: https://git.checksum.fail/alec/templenes HDAudio1: https://github.com/dancoyle21/sup1hdaudio (fork of alec's sup1hdaudio repo) --- src/Home/Sound/AC97/AC97.ZC | 244 ++++ src/Home/Sound/AC97/Pci.ZC | 89 ++ src/Home/Sound/HDAudio0/Audio.ZC | 76 ++ src/Home/Sound/HDAudio0/HDAudio.ZC | 1052 +++++++++++++++++ src/Home/Sound/HDAudio1/Load.ZC | 6 + .../HDAudio1/Sup1CodeScraps/Mem/Mem2Meg.ZC | 199 ++++ .../HDAudio1/Sup1HDAudio/Examples/BeatFreq.ZC | 68 ++ .../HDAudio1/Sup1HDAudio/Examples/Chords.ZC | 16 + .../HDAudio1/Sup1HDAudio/Examples/Echo.ZC | 99 ++ .../HDAudio1/Sup1HDAudio/Examples/Guitar.ZC | 17 + .../Sup1HDAudio/Examples/PolyPhonic.ZC | 96 ++ .../HDAudio1/Sup1HDAudio/Examples/Record.ZC | 117 ++ .../HDAudio1/Sup1HDAudio/Examples/SndScope.ZC | 44 + .../HDAudio1/Sup1HDAudio/Examples/Synth.ZC | 280 +++++ .../Sound/HDAudio1/Sup1HDAudio/HDAudio.ZC | 697 +++++++++++ src/Home/Sound/HDAudio1/Sup1HDAudio/HDCfg.ZC | 720 +++++++++++ src/Home/Sound/HDAudio1/Sup1Snd/MakeSnd.ZC | 21 + src/Home/Sound/HDAudio1/Sup1Snd/SndEffects.ZC | 80 ++ src/Home/Sound/HDAudio1/Sup1Snd/SndFile.ZC | 137 +++ src/Home/Sound/HDAudio1/Sup1Snd/SndMath.ZC | 248 ++++ src/Home/Sound/HDAudio1/Sup1Snd/SndMusic.ZC | 224 ++++ 21 files changed, 4530 insertions(+) create mode 100644 src/Home/Sound/AC97/AC97.ZC create mode 100644 src/Home/Sound/AC97/Pci.ZC create mode 100644 src/Home/Sound/HDAudio0/Audio.ZC create mode 100644 src/Home/Sound/HDAudio0/HDAudio.ZC create mode 100644 src/Home/Sound/HDAudio1/Load.ZC create mode 100644 src/Home/Sound/HDAudio1/Sup1CodeScraps/Mem/Mem2Meg.ZC create mode 100644 src/Home/Sound/HDAudio1/Sup1HDAudio/Examples/BeatFreq.ZC create mode 100644 src/Home/Sound/HDAudio1/Sup1HDAudio/Examples/Chords.ZC create mode 100644 src/Home/Sound/HDAudio1/Sup1HDAudio/Examples/Echo.ZC create mode 100644 src/Home/Sound/HDAudio1/Sup1HDAudio/Examples/Guitar.ZC create mode 100644 src/Home/Sound/HDAudio1/Sup1HDAudio/Examples/PolyPhonic.ZC create mode 100644 src/Home/Sound/HDAudio1/Sup1HDAudio/Examples/Record.ZC create mode 100644 src/Home/Sound/HDAudio1/Sup1HDAudio/Examples/SndScope.ZC create mode 100644 src/Home/Sound/HDAudio1/Sup1HDAudio/Examples/Synth.ZC create mode 100644 src/Home/Sound/HDAudio1/Sup1HDAudio/HDAudio.ZC create mode 100644 src/Home/Sound/HDAudio1/Sup1HDAudio/HDCfg.ZC create mode 100644 src/Home/Sound/HDAudio1/Sup1Snd/MakeSnd.ZC create mode 100644 src/Home/Sound/HDAudio1/Sup1Snd/SndEffects.ZC create mode 100644 src/Home/Sound/HDAudio1/Sup1Snd/SndFile.ZC create mode 100644 src/Home/Sound/HDAudio1/Sup1Snd/SndMath.ZC create mode 100644 src/Home/Sound/HDAudio1/Sup1Snd/SndMusic.ZC diff --git a/src/Home/Sound/AC97/AC97.ZC b/src/Home/Sound/AC97/AC97.ZC new file mode 100644 index 000000000..538381b19 --- /dev/null +++ b/src/Home/Sound/AC97/AC97.ZC @@ -0,0 +1,244 @@ + +#define INT_LAST_VALID_ENTRY 1 << 2 +#define INT_IOC 1 << 3 +#define INT_FIFO_ERR 1 << 4 +#define BDL_BUF_SIZE 2044 +#define PCM_BUF_SIZE 2048 +#define MAX_BDLS 32 +#define PCM_IN 0 +#define PCM_OUT 1 +#define MIC_IN 2 + +// Native Audio Mixer registers (all U16) +#define RESET 0x00 // Reset Register +#define MASTER_VOL 0x02 // Set Master Output Volume +#define MIC_VOL 0x0E // Set Microphone Volume +#define PCM_VOL 0x18 // Set Output Volume of PCM patterns +#define REC_SLC 0x1A // Select Input Device +#define REC_GAIN 0x1C // Set Input Gain +#define MIC_GAIN 0x1E // Set Gain of Microphone +#define EXT_ID 0x28 // Supported extended functions +#define EXT_CTRL 0x2A // Enabling extended functions +#define EXT_FRONT_RATE 0x2C // Sample rate of front speaker + +// Native Audio Bus Master registers +#define PCM_INPUT_REG_BOX\ +0x00 // NABM register box for PCM IN (sizeof NABM register box) +#define PCM_OUTPUT_REG_BOX\ +0x10 // NABM register box for PCM OUT (sizeof NABM register box) +#define MIC_INPUT_REG_BOX\ +0x20 // NABM register box for Microphone (sizeof NABM register box) +#define GLOBAL_CTL 0x2C // Global Control Register (U32) +#define GLOBAL_STS 0x30 // Global Status Register (U32) + +// NABM register box registers +#define BUFFER_DSC_ADDR 0x00 // Physical Address of Buffer Descriptor List (U32) +#define CUR_ENTRY_VAL\ +0x04 // Number of Actual Processed Buffer Descriptor Entry (U8) +#define LAST_VALID_ENTRY 0x05 // Number of all Descriptor Entries (U8) +#define TRANSFER_STS 0x06 // Status of Transferring Data (U16) +#define CUR_IDX_PROC_SAMPLES\ +0x08 // Number of Transferred Samples in Actual Processed Entry (U16) +#define PRCSD_ENTRY 0x0A // Number of Actual Processed Buffer Entry (U8) +#define BUFFER_CNT\ +0x0B // Most Important Register for controlling Transfers (U8) + +class @ac97_bdl_entry +{ + U32 addr; + U16 length; // length - 1 + U16 flags; +}; + +class @ac97_bdl +{ + @ac97_bdl_entry entries[32]; +}; + +class @ac97 +{ + @pci_info pci; + @ac97_bdl *bdl[3]; + U16 nam; + U16 nabm; +}; + +@ac97 AC97; + +#define AUDIO_MAX_STREAMS 16 +#define AUDIO_OUTPUT_BUFFER_SIZE 1024 +#define AUDIO_STREAM_FIFO_SIZE 1048576 * 16 +#define AUDIO_STREAM_TYPE_INPUT 0 +#define AUDIO_STREAM_TYPE_OUTPUT 1 + +class @audio_stream +{ + CFifoI64 * data; +}; + +class @audio +{ + @audio_stream output[AUDIO_MAX_STREAMS]; + I64 output_frames[AUDIO_MAX_STREAMS]; +}; + +@audio Audio; + +U0 @audio_init() +{ + I64 i = 0; + for (i = 0; i < AUDIO_MAX_STREAMS; i++) + Audio.output[i].data = FifoI64New(AUDIO_STREAM_FIFO_SIZE, sys_task); +} + +@audio_init; + +I64 @audio_get_available_output_stream() +{ + I64 stream = 0; + while (FifoI64Count(Audio.output[stream].data)) + stream++; + if (stream > AUDIO_MAX_STREAMS - 1) + return -1; + return stream; +} + +I64 @audio_play_sfx(U32 *data, I64 length) +{ + I64 i; + I64 stream = @audio_get_available_output_stream; + if (stream < 0) + return stream; + for (i = 0; i < length; i++) + FifoI64Ins(Audio.output[stream].data, data[i]); + return stream; +} + +U0 @ac97_mix_output(U32 *buf, I64 length = NULL) +{ + I64 i; + I64 j; + I64 acc_sample_L = 0; + I64 acc_sample_R = 0; + I64 acc_streams = 0; + U32 sample; + + if (!length) + length = AUDIO_OUTPUT_BUFFER_SIZE; + for (i = 0; i < length / 4; i++) + { + acc_sample_L = 0; + acc_sample_R = 0; + acc_streams = 0; + + for (j = 0; j < AUDIO_MAX_STREAMS; j++) + { + if (FifoI64Count(Audio.output[j].data)) + { + FifoI64Remove(Audio.output[j].data, &sample); + Audio.output_frames[j]++; + acc_streams++; + acc_sample_L += sample.u16[0]; + acc_sample_R += sample.u16[1]; + } + } + + buf[i].i16[0] = ToI64(acc_sample_L / Sqrt(acc_streams)); + buf[i].i16[1] = ToI64(acc_sample_R / Sqrt(acc_streams)); + } +} + +U0 @ac97_fill_buffer() +{ + I64 idx = InU8(AC97.nabm + PCM_OUTPUT_REG_BOX + LAST_VALID_ENTRY); + U32 *buf = AC97.bdl[PCM_OUT]->entries[idx].addr; + @ac97_mix_output(buf, BDL_BUF_SIZE); + OutU8(AC97.nabm + PCM_OUTPUT_REG_BOX + LAST_VALID_ENTRY, ++idx); +} + +U0 @ac97_process_audio() +{ + U16 status = InU16(AC97.nabm + PCM_OUTPUT_REG_BOX + TRANSFER_STS); + if (status & INT_IOC) + { + @ac97_fill_buffer; + OutU16(AC97.nabm + PCM_OUTPUT_REG_BOX + TRANSFER_STS, 0x1C); + } +} + +I64 @ac97_init() +{ + I64 i; + I64 j; + // Scan for device + j = PCIClassFind(0x040100, 0); + if (j < 0) + { + device_not_found: SysLog("\n[AC'97] Device not found\n"); + return -1; + } + + @get_pci_info(j, &AC97.pci); + + if (AC97.pci.vendor_id != 0x8086 || AC97.pci.device_id != 0x2415) + goto device_not_found; + + AC97.nam = AC97.pci.bar[0] &0xFFFFFF00; + AC97.nabm = AC97.pci.bar[1] &0xFFFFFF00; + + // Enable port IO, disable MMIO + PCIWriteU8(j.u8[2], j.u8[1], j.u8[0], 0x4, 5); + + OutU32(AC97.nabm + GLOBAL_CTL, 0x03); + OutU16(AC97.nam + RESET, 0xFFFF); + + // Set PCM Output to Max volume + OutU16(AC97.nam + PCM_VOL, 0x0000); + + // Allocate Buffer Descriptor Lists + AC97.bdl[PCM_IN] = CAllocAligned(sizeof(@ac97_bdl), 4096, Fs->code_heap); + AC97.bdl[PCM_OUT] = CAllocAligned(sizeof(@ac97_bdl), 4096, Fs->code_heap); + AC97.bdl[MIC_IN] = CAllocAligned(sizeof(@ac97_bdl), 4096, Fs->code_heap); + + for (i = 0; i < MAX_BDLS; i++) + { + AC97.bdl[PCM_OUT]->entries[i].addr = + CAllocAligned(PCM_BUF_SIZE, 4096, Fs->code_heap); + AC97.bdl[PCM_OUT]->entries[i].length = BDL_BUF_SIZE / 2; + AC97.bdl[PCM_OUT]->entries[i].flags = 1 << 15; + } + + // Set addresses of Buffer Descriptor Lists + // OutU32(AC97.nabm + PCM_INPUT_REG_BOX + BUFFER_DSC_ADDR, AC97.bdl[PCM_IN]); + OutU32(AC97.nabm + PCM_OUTPUT_REG_BOX + BUFFER_DSC_ADDR, AC97.bdl[PCM_OUT]); + // OutU32(AC97.nabm + MIC_INPUT_REG_BOX + BUFFER_DSC_ADDR, AC97.bdl[MIC_IN]); + + // Set Master Volume + OutU16(AC97.nam + MASTER_VOL, 0x0F0F); + + // Stop playing sound + OutU8(AC97.nabm + PCM_OUTPUT_REG_BOX + BUFFER_CNT, 0); + + // Fill one buffers + @ac97_fill_buffer; + + // Enable interrupt handler + //@pci_register_int_handler(&@ac97_int_handler); + + // Start playing sound + OutU8(AC97.nabm + PCM_OUTPUT_REG_BOX + BUFFER_CNT, 1); + + return 0; +} + +U0 @ac97_task() +{ + while (1) + { + @ac97_process_audio; + Sleep(1); + } +} + +@ac97_init; +Spawn(&@ac97_task,, "AC97 Task", 1); \ No newline at end of file diff --git a/src/Home/Sound/AC97/Pci.ZC b/src/Home/Sound/AC97/Pci.ZC new file mode 100644 index 000000000..9f83604dc --- /dev/null +++ b/src/Home/Sound/AC97/Pci.ZC @@ -0,0 +1,89 @@ +#define PCI_INTH_MAX 16 + +U64 @pci_int_handler[PCI_INTH_MAX]; + +class @pci_info { + U16 vendor_id; + U16 device_id; + U16 command; + U16 status; + U32 _class; + U32 bar[6]; + U32 cap_pointer; +}; + +class @pci_cap { + U8 cap_vndr; /* Generic PCI field: PCI_CAP_ID_VNDR */ + U8 cap_next; /* Generic PCI field: next ptr. */ + U8 cap_len; /* Generic PCI field: capability length */ + U8 cfg_type; /* Identifies the structure. */ + U8 bar; /* Where to find it. */ + U8 padding[3]; /* Pad to full dword. */ + U32 offset; /* Offset within bar. */ + U32 length; /* Length of the structure, in bytes. */ +}; + +U0 @get_pci_info(I64 i, @pci_info *pci) { + I64 j; + pci->vendor_id = PCIReadU32(i.u8[2], i.u8[1], i.u8[0], 0x0) & 0xFFFF; + pci->device_id = PCIReadU32(i.u8[2], i.u8[1], i.u8[0], 0x0) >> 16; + pci->command = PCIReadU32(i.u8[2], i.u8[1], i.u8[0], 0x4) & 0xFFFF; + pci->status = PCIReadU32(i.u8[2], i.u8[1], i.u8[0], 0x4) >> 16; + pci->_class = PCIReadU32(i.u8[2], i.u8[1], i.u8[0], 0x8) >> 24; + for (j = 0; j < 6; j++) + pci->bar[j] = PCIReadU32(i.u8[2], i.u8[1], i.u8[0], 0x10 + (0x04 * j)); +} + +U0 @get_pci_cap(I64 i, @pci_cap *cap, I64 idx) { + I64 base = 0x40 + (idx * 16); + U32 u32; + u32 = PCIReadU32(i.u8[2], i.u8[1], i.u8[0], base); + cap->cap_vndr = u32.u8[0]; + cap->cap_next = u32.u8[1]; + cap->cap_len = u32.u8[2]; + cap->cfg_type = u32.u8[3]; + u32 = PCIReadU32(i.u8[2], i.u8[1], i.u8[0], base + 0x04); + cap->bar = u32.u8[0]; + cap->offset = PCIReadU32(i.u8[2], i.u8[1], i.u8[0], base + 0x08); + cap->length = PCIReadU32(i.u8[2], i.u8[1], i.u8[0], base + 0x0c); +} + +U0 @pci_reroute_interrupts(I64 base, I64 cpu) { + I64 i; + U8 *da = dev.uncached_alias + IOAPIC_REG; + U32 *_d = dev.uncached_alias + IOAPIC_DATA; + + for (i = 0; i < 4; i++) { + *da = IOREDTAB + i * 2 + 1; + *_d = dev.mp_apic_ids[cpu] << 24; + *da = IOREDTAB + i * 2; + *_d = 0x4000 + base + i; + } +} + +I64 @pci_register_int_handler(U64 handler) { + if (!handler) + return -1; + I64 i = 0; + while (@pci_int_handler[i]) + i++; + if (i > PCI_INTH_MAX - 1) + return -1; + @pci_int_handler[i] = handler; + return 0; +} + +interrupt U0 @pci_interrupt_handler() { + I64 i; + for (i = 0; i < PCI_INTH_MAX; i++) + if (@pci_int_handler[i]) + Call(@pci_int_handler[i]); + *(dev.uncached_alias + LAPIC_EOI)(U32 *) = 0; +} + +MemSet(&@pci_int_handler, NULL, sizeof(U64) * PCI_INTH_MAX); +// IntEntrySet(0x40, &@pci_interrupt_handler, IDTET_IRQ); +// IntEntrySet(0x41, &@pci_interrupt_handler, IDTET_IRQ); +// IntEntrySet(0x42, &@pci_interrupt_handler, IDTET_IRQ); +// IntEntrySet(0x43, &@pci_interrupt_handler, IDTET_IRQ); +//@pci_reroute_interrupts(0x40, 0); \ No newline at end of file diff --git a/src/Home/Sound/HDAudio0/Audio.ZC b/src/Home/Sound/HDAudio0/Audio.ZC new file mode 100644 index 000000000..7c16ca296 --- /dev/null +++ b/src/Home/Sound/HDAudio0/Audio.ZC @@ -0,0 +1,76 @@ +// vim: set ft=c: + +I64 start_buf_num; +U0 (*fp_old_fill_buf)(SND_OUT_CONTAINER *buf,I64 buf_num)=NULL; + +U0 AudioFillBuf(SND_OUT_CONTAINER *buf,I64 buf_num) +{ + I64 j=0,k; + I64 intL, intR; + U8 *buf2; + + if (paused) + { + while (j8192) + { + while (FifoI64Cnt(audio_fifo_L)>7680) + { + FifoI64Rem(audio_fifo_L, &k); + FifoI64Rem(audio_fifo_R, &k); + } + } + + if (FifoI64Cnt(audio_fifo_L)) + { + FifoI64Rem(audio_fifo_L, &intL); + } + else + { + intL = 0; + } + intL *= 0xFFFF; + if (intL < 0) + { + intL += 0x1000000; + } + + if (FifoI64Cnt(audio_fifo_R)) + { + FifoI64Rem(audio_fifo_R, &intR); + } + else + { + intR = 0; + } + intR *= 0xFFFF; + if (intR < 0) + { + intR += 0x1000000; + } + + buf2 = buf+j; + buf2[0] = 0; + buf2[1] = intL; + buf2[2] = intL >> 8; + buf2[3] = intL >> 16; + j++; + + buf2 = buf+j; + buf2[0] = 0; + buf2[1] = intR; + buf2[2] = intR >> 8; + buf2[3] = intR >> 16; + j++; + } +} \ No newline at end of file diff --git a/src/Home/Sound/HDAudio0/HDAudio.ZC b/src/Home/Sound/HDAudio0/HDAudio.ZC new file mode 100644 index 000000000..cd73d2842 --- /dev/null +++ b/src/Home/Sound/HDAudio0/HDAudio.ZC @@ -0,0 +1,1052 @@ +U8* Mem2MegAlloc(I64 *_pages2Meg, CBlkPool *bp = NULL) +{ + /*Alloc 2Meg pages from BlkPool. Don't link to task. + (Linking to a task means they will be freed when the task dies.) + It might give you more than you asked for + so a ptr to a page count is passed. + + Return: NULL if out of memory. + */ + I64 i, j, *pte, num = *_pages2Meg; + CMemBlk *res = NULL, *m, *m1; + + if (!bp) bp = sys_code_bp; + PUSHFD + CLI + while (LBts(&bp->locked_flags, BPlf_LOCKED)) + PAUSE + num <<= 21 - MEM_PAG_BITS; + + m = &bp->mem_free_2meg_list; + while (TRUE) + { + if (!(res = m->next)) + break; + if (res->pags < num) + m = res; + else + { + if (res->pags == num) + { + m->next = res->next; + goto am_done; + } + else + { + res->pags -= num; + res(U8*) += res->pags << MEM_PAG_BITS; + res->pags = num; + goto am_done; + } + } + } + + m = &bp->mem_free_list; + while (TRUE) + { + if (!(res = m->next)) + { + num = 0; + res = NULL; //Out of memory + goto am_done; + } + + if (res->pags < num) + m = res; + else + { + if (res->pags == num) + { + if (res(U8*) &0x1FFFFF) + m = res; + else + { + m->next = res->next; + goto am_done; + } + } + else + { + if (i = (res(U8*) &0x1FFFFF) >> MEM_PAG_BITS) + { + j = 1 << (21 - MEM_PAG_BITS) - i; + if (res->pags < num + j) + m = res; + else if (res->pags == num + j) + { + res->pags -= num; + res(U8*) += res->pags << MEM_PAG_BITS; + res->pags = num; + goto am_done; + } + else + { + m1 = res; + res(U8*) += j << MEM_PAG_BITS; + res->pags = num; + m = res(U8*) + num << MEM_PAG_BITS; + m->pags = m1->pags - num - j; + m1->pags = j; + m->next = m1->next; + m1->next = m; + m->mb_signature = MBS_UNUSED_SIGNATURE_VAL; + goto am_done; + } + } + else + { + m = m->next = res(U8*) + num << MEM_PAG_BITS; + m->next = res->next; + m->pags = res->pags - num; + m->mb_signature = MBS_UNUSED_SIGNATURE_VAL; + res->pags = num; + goto am_done; + } + } + } + } + + am_done: + i = num << MEM_PAG_BITS; + bp->used_u8s += i; + num >>= 21 - MEM_PAG_BITS; + *_pages2Meg = num; + m = res; + m1 = m(U8*) + i; + while (m < m1) + { + pte = MemPageTable(m); + *pte &= ~0x18; + InvalidatePage(m); + m(U8*) += 0x200000; + } + + LBtr(&bp->locked_flags, BPlf_LOCKED); + POPFD + return res; +} + +U8* Mem2MegUncachedAlloc(I64 *_pages2Meg, CBlkPool *bp = NULL) +{ + /*Alloc 2Meg pages from BlkPool. Don't link to task. + (Linking to a task means they will be freed when the task dies.) + It will be marked uncached. It might give you more than you asked for + so a ptr to a page count is passed. + + Return: NULL if out of memory. + */ + CMemBlk *res, *m, *m1; + I64 num = *_pages2Meg, *pte; + if (res = Mem2MegAlloc(_pages2Meg, bp)) + { + num = *_pages2Meg; + m = res; + m1 = m(U8*) + num << 21; + while (m < m1) + { + pte = MemPageTable(m); + *pte = *pte &~0x18 | 0x10; + InvalidatePage(m); + m(U8*) += 0x200000; + } + } + + return res; +} + +CHeapCtrl* HeapCtrlBPInit(CBlkPool *bp, I64 pags) +{ + //Make mem chunk into HeapCtrl and BlkPool. + I64 num; + CMemBlk * m; + CHeapCtrl * hc; + MemSet(bp, 0, sizeof(CBlkPool) + sizeof(CHeapCtrl)); + hc = HeapCtrlInit(bp(U8*) + sizeof(CBlkPool),, bp); + m = (bp(U8*) + sizeof(CBlkPool) + sizeof(CHeapCtrl) + MEM_PAG_SIZE - 1) &~(MEM_PAG_SIZE - 1); + num = (bp(U8*) + pags << MEM_PAG_BITS - m(U8*)) >> MEM_PAG_BITS; + bp->alloced_u8s = (pags - num) << MEM_PAG_BITS; + BlkPoolAdd(bp, m, num); + return hc; +} + +class CSndWaveCtrl +{ + I64 sample_rate, sample_bits, channels; + F64 freq_multiplier, amp_multiplier; + F64 phase, last_y, last_dydt, next_y; +}; + +#define WF_NULL 0 +#define WF_SQUARE 1 +#define WF_SINE 2 +#define WF_TRI 3 +#define WF_SAWTOOTH 4 +#define WF_NOISE 5 +#define WF_WAVEFORMS_NUM 6 + +//snd devs +#define SD_PC_SPEAKER 0 +#define SD_HD_AUDIO 1 +#define SND_SAMPLE_RATE 48000 +#define SND_SAMPLE_BITS 16 +#define SND_OCHANNELS 2 +#define SND_ICHANNELS 2 +#define SND_OUT_CONTAINER U32 +#define SND_IN_CONTAINER I16 +#define SND_BUF_LEN 0x400 +#define SND_BUF_TIME_mS(SND_BUF_LEN / SND_OCHANNELS *1000.0 / \ + SND_SAMPLE_RATE) + +F64 snd_freq = 0; +I64 snd_dev = SD_PC_SPEAKER; +Bool snd_record = FALSE; +F64 snd_vol = 0.1; +U0(*fp_snd)(F64 freq, I64 waveform, F64 amp) = NULL; +U0(*fp_snd_record)(F64 freq, I64 waveform, F64 amp) = NULL; +U0(*fp_snd_fill_buf)(SND_OUT_CONTAINER *buf, I64 buf_num) = NULL; +U0(*fp_snd_copy_buf)(SND_IN_CONTAINER *buf, I64 buf_num) = NULL; + +I64 snd_obuf_num, snd_ibuf_num; + +#define Sf_FILLING_OUT 0 +I64 snd_flags; + +#define HD_1_CHAN 0 +#define HD_2_CHAN 1 +#define HD_3_CHAN 2 +#define HD_4_CHAN 3 +#define HD_8_BIT 0 +#define HD_16_BIT 1 +#define HD_20_BIT 2 +#define HD_24_BIT 3 +#define HD_32_BIT 4 +#define HD_48kHz 0 +#define HD_DFT_OUT_FMT(HD_2_CHAN + HD_16_BIT << 4 + HD_48kHz << 8) +#define HD_DFT_IN_FMT(HD_2_CHAN + HD_16_BIT << 4 + HD_48kHz << 8) +#define HD_POS_BUF_MULTIPLES 0x1000 +#define HD_CORB_ENTRIES 256 +#define HD_RIRB_ENTRIES 256 +#define HD_BDL_ENTRIES 256 +#define HD_GCTL 0x08 +#define HD_STATESTS 0x0E +#define HD_GSTS 0x10 +#define HD_CORBLBASE 0x40 +#define HD_CORBUBASE 0x44 +#define HD_CORBWP 0x48 +#define HD_CORBRP 0x4A +#define HD_CORBCTL 0x4C +#define HD_CORBST 0x4D +#define HD_RIRBLBASE 0x50 +#define HD_RIRBUBASE 0x54 +#define HD_RIRBWP 0x58 +#define HD_RIRBCTL 0x5C +#define HD_RIRBSTS 0x5D +#define STRCTL 0x00 +#define STRSTS 0x03 +#define STRLPIB 0x04 +#define STRCBL 0x08 +#define STRLVI 0x0C +#define STRFIFOW 0x0E +#define STRFIFOS 0x10 +#define STRFMT 0x12 +#define STRBDPL 0x18 +#define STRBDPU 0x1C +#define ISTR0 0x080 +#define ISTR1 0x0A0 +#define ISTR2 0x0C0 +#define ISTR3 0x0E0 +#define OSTR0 0x100 +#define OSTR1 0x120 +#define OSTR2 0x140 +#define OSTR3 0x160 +#define VERB_GET_PARAM 0xF0000 +#define VERB_CONNECT_SEL_GET 0xF0100 +#define VERB_CONNECT_SEL_SET 0x70100 +#define VERB_GET_CONNECT_LST 0xF0200 +#define VERB_PROCESS_STATE_GET 0xF0300 +#define VERB_PROCESS_STATE_SET 0x70300 +#define VERB_COEFF_IDX_GET 0xD0000 +#define VERB_COEFF_IDX_SET 0x50000 +#define VERB_PROCESS_COEFF_GET 0xC0000 +#define VERB_PROCESS_COEFF_SET 0x40000 +#define VERB_AMPLIFIER_GAIN_GET 0xB0000 +#define VERB_AMPLIFIER_GAIN_SET 0x30000 +#define VERB_STREAM_FMT_GET 0xA0000 +#define VERB_STREAM_FMT_SET 0x20000 +#define VERB_DIGIT_CONVERT1_GET 0xF0D00 +#define VERB_DIGIT_CONVERT1_SET 0x70D00 +#define VERB_DIGIT_CONVERT2_GET 0xF0D00 +#define VERB_DIGIT_CONVERT2_SET 0x70E00 +#define VERB_POWER_STATE_GET 0xF0500 +#define VERB_POWER_STATE_SET 0x70500 +#define VERB_CHAN_STREAM_ID_GET 0xF0600 +#define VERB_CHAN_STREAM_ID_SET 0x70600 +#define VERB_SDI_SEL_GET 0xF0400 +#define VERB_SDI_SEL_SET 0x70400 +#define VERB_PIN_WIDGET_CTL_GET 0xF0700 +#define VERB_PIN_WIDGET_CTL_SET 0x70700 +#define VERB_UNSOL_ENABLE_GET 0xF0800 +#define VERB_UNSOL_ENABLE_SET 0x70800 +#define VERB_PIN_SENSE_GET 0xF0900 +#define VERB_PIN_SENSE_SET 0x70900 +#define VERB_EAPDBTL_ENABLE_GET 0xF0C00 +#define VERB_EAPDBTL_ENABLE_SET 0x70C00 +#define VERB_BEEP_CTL_GET 0xF0A00 +#define VERB_BEEP_CTL_SET 0x70A00 +#define VERB_GPI_CTRL0_GET 0xF1000 +#define VERB_GPI_CTRL0_SET 0x71000 +#define VERB_GPI_CTRL1_GET 0xF1100 +#define VERB_GPI_CTRL1_SET 0x71100 +#define VERB_GPI_CTRL2_GET 0xF1200 +#define VERB_GPI_CTRL2_SET 0x71200 +#define VERB_GPI_CTRL3_GET 0xF1300 +#define VERB_GPI_CTRL3_SET 0x71300 +#define VERB_GPI_CTRL4_GET 0xF1400 +#define VERB_GPI_CTRL4_SET 0x71400 +#define VERB_GPI_CTRL5_GET 0xF1500 +#define VERB_GPI_CTRL5_SET 0x71500 +#define VERB_GPI_CTRL6_GET 0xF1600 +#define VERB_GPI_CTRL6_SET 0x71600 +#define VERB_GPI_CTRL7_GET 0xF1700 +#define VERB_GPI_CTRL7_SET 0x71700 +#define VERB_GPI_CTRL8_GET 0xF1800 +#define VERB_GPI_CTRL8_SET 0x71800 +#define VERB_GPI_CTRL9_GET 0xF1900 +#define VERB_GPI_CTRL9_SET 0x71900 +#define VERB_GPI_CTRLA_GET 0xF1A00 +#define VERB_GPI_CTRLA_SET 0x71A00 +#define VERB_VOL_CTL_GET 0xF0F00 +#define VERB_VOL_CTL_SET 0x70F00 +#define VERB_SUB_SYS_ID0_GET 0xF2000 +#define VERB_SUB_SYS_ID0_SET 0x72000 +#define VERB_SUB_SYS_ID1_GET 0xF2000 +#define VERB_SUB_SYS_ID1_SET 0x72100 +#define VERB_SUB_SYS_ID2_GET 0xF2000 +#define VERB_SUB_SYS_ID2_SET 0x72200 +#define VERB_SUB_SYS_ID3_GET 0xF2000 +#define VERB_SUB_SYS_ID3_SET 0x72300 +#define VERB_CFG_DFT0_GET 0xF1C00 +#define VERB_CFG_DFT0_SET 0x71C00 +#define VERB_CFG_DFT1_GET 0xF1C00 +#define VERB_CFG_DFT1_SET 0x71D00 +#define VERB_CFG_DFT2_GET 0xF1C00 +#define VERB_CFG_DFT2_SET 0x71E00 +#define VERB_CFG_DFT3_GET 0xF1C00 +#define VERB_CFG_DFT3_SET 0x71F00 +#define VERB_STRIPE_CTL_GET 0xF2400 +#define VERB_STRIPE_CTL_SET 0x72400 +#define VERB_RST 0x7FF00 + +//Parameters +#define P_VENDOR_ID 0x00 +#define P_REVISION_ID 0x02 +#define P_SUBNODE_CNT 0x04 +#define P_FUN_GRP_TYPE 0x05 +#define P_AUDIO_FUN_CAP 0x08 +#define P_AUDIO_WIDGET_CAP 0x09 +#define P_SAMPLE_SIZE_RATE_CAP 0x0A +#define P_STREAM_FMTS 0x0B +#define P_PIN_CAP 0x0C +#define P_INPUT_AMP_CAP 0x0D +#define P_OUTPUT_AMP_CAP 0x12 +#define P_CONNECT_LST_LEN 0x0E +#define P_POWER_STATES 0x0F +#define P_PROCESSING_CAP 0x10 +#define P_GPIO_CNT 0x11 +#define P_VOL_KNOB_CAP 0x13 + +//Function Group Types +//00 reserved +#define FGT_AUDIO 1 +#define FGT_VENDOR_MODEM 2 +//03-7F reserved +//80-FF vendor function group + +//Audio Widget Types +#define AWT_OUTPUT 0x0 +#define AWT_INPUT 0x1 +#define AWT_MIXER 0x2 +#define AWT_SELECTOR 0x3 +#define AWT_PIN_COMPLEX 0x4 +#define AWT_POWER_WIDGET 0x5 +#define AWT_VOL_KNOB_WIDGET 0x6 +#define AWT_BEEP_GEN_WIDGET 0x7 +#define AWT_VENDOR 0xF +#define AWT_NODE 0x10 +DefineListLoad("ST_AUDIO_WIDGET_TYPES", + "Output\0Input\0Mixer\0Sellector\0Pin Complex\0" + "Power Widget\0Vol Knob\0Beep Gen\0\0\0\0\0\0\0\0Vendor\0Node\0"); + +class CHDBufDesc +{ + I32 * buf; + U32 len; + U32 ctrl; +}; + +#define HD_TONES 8 + +class CHDAudioCtrl +{ + U8 * bar; + CBlkPool * bp; + CHeapCtrl * hc; + I64 cad; + U32 * corb; + I64 * rirb; + CHDBufDesc *ostr0_bdl, *istr0_bdl; + SND_OUT_CONTAINER *ostr0_buf[2], *o_tmp_buf; + SND_IN_CONTAINER *istr0_buf[2]; + CTask * task; + I64 waveform; + F64 freq, amp; + CSndWaveCtrl *tone_swcs[HD_TONES]; + U8 rirb_rp, corb_wp; + Bool audio_task_started, in_running, out_running; +} + +hda; +MemSet(&hda, 0, sizeof(CHDAudioCtrl)); + +F64 SinPhaseCont(F64 last_y, F64 last_dydt, + F64 current_amp, F64 phase_offset) +{ + //Next sample of sin waveform. + F64 phase; + phase = last_y / current_amp; + if (phase > 1.0) phase = 1.0; + if (phase < -1.0) phase = -1.0; + if (last_dydt < 0) + phase = pi - ASin(phase); + else + phase = ASin(phase); + return phase - phase_offset; +} + +public CSndWaveCtrl* SndWaveCtrlNew(I64 sample_rate = 8000, I64 sample_bits = 24, + I64 channels = 2, CTask *mem_task = NULL) +{ + //MAlloc ctrl struct for generating waveforms. + CSndWaveCtrl *swc = CAlloc(sizeof(CSndWaveCtrl), mem_task); + swc->freq_multiplier = 1.0; + swc->amp_multiplier = 1.0; + swc->sample_rate = sample_rate; + swc->sample_bits = sample_bits; + swc->channels = channels; + swc->last_dydt = 1.0; + return swc; +} + +public U0 SndWaveCtrlDel(CSndWaveCtrl *swc) +{ + //Free waveform ctrl. + Free(swc); +} + +public U0 SndWaveAddBuf(CSndWaveCtrl *swc, U8 *buf, I64 num_samples, + F64 _freq, I64 _waveform = WF_SQUARE, F64 _amp = 1.0, F64 _left = 1.0, F64 _right = 1.0) +{ + //Add waveform to buffer. + //num_samples is multiplied by channels to get buf_len. + //left,right range from 0.0-1.0 + //Supports 16,24 and 32 bits + I64 reg i, reg j, reg k; + F64 a, f, amp, reg phase; + if (!swc) return; + _freq *= swc->freq_multiplier; + _amp *= swc->amp_multiplier; + if (!_freq || !_amp) + { + swc->last_y = swc->phase = 0; + swc->last_dydt = 1.0; + } + else + { + phase = swc->phase; + i = 0; + amp = Min(I32_MAX, I32_MAX *_amp); + f = 2 *pi / swc->sample_rate * _freq; + switch (_waveform) + { + case WF_NOISE: + a = 2.0 / pi * amp; + break; + case WF_SAWTOOTH: + a = amp / pi; + break; + case WF_SINE: + phase = SinPhaseCont(swc->last_y, swc->last_dydt, amp, 0.0); + break; + } + + while (phase < 0) + phase += 2 * pi; + while (phase >= 2 *pi) + phase -= 2 * pi; + num_samples *= swc->channels; + while (i < num_samples) + { + switch (_waveform) + { + case WF_SQUARE: + if (phase >= pi) + j = -amp; + else + j = amp; + break; + case WF_SINE: + j = amp* Sin(phase); + break; + case WF_TRI: + if (phase >= pi) + { + swc->last_y = swc->next_y; + swc->next_y = -amp* Sign(swc->last_y) + .00001; + phase -= pi; + } + + j = (swc->last_y *(pi - phase) + swc->next_y *phase) / pi; + break; + case WF_SAWTOOTH: + j = a *(phase - pi); + break; + case WF_NOISE: + if (phase < pi) + { + if (phase < f) + { + swc->last_y = swc->next_y; + swc->next_y = a *RandI16 / U16_MAX; + } + + j = swc->last_y *(pi - phase) + swc->next_y * phase; + } + else + { + if (phase - pi < f) + { + swc->last_y = swc->next_y; + swc->next_y = a *RandI16 / U16_MAX; + } + + j = swc->last_y *(2.0 *pi - phase) + swc->next_y *(phase - pi); + } + + break; + } + + //left channel + k = j * _left; + if (swc->sample_bits == 16) + { + k >>= 16; + buf(I16*)[i++] += k; + } + else + { + if (swc->sample_bits == 24) + k &= 0xFFFFFF00; + buf(I32*)[i++] += k; + } + + //right channel + if (swc->channels == 2) + { + k = j * _right; + if (swc->sample_bits == 16) + { + k >>= 16; + buf(I16*)[i++] += k; + } + else + { + if (swc->sample_bits == 24) + k &= 0xFFFFFF00; + buf(I32*)[i++] += k; + } + } + + phase += f; + while (phase >= 2 *pi) + phase -= 2 * pi; + } + + if (_waveform == WF_SINE) + { + swc->last_y = amp* Sin(phase); + swc->last_dydt = Cos(phase); + } + + swc->phase = phase; + } +} + +U0 HDSyncCORB() +{ + U16 *wp, *rp; + wp = hda.bar + HD_CORBWP; + *wp = hda.corb_wp; + rp = hda.bar + HD_CORBRP; + while (*rp &255 != hda.corb_wp) + Yield; +} + +U0 HDWriteCORB(I64 cad, I64 nid, U32 val) +{ + val |= cad << 28 + nid << 20; + hda.corb[++hda.corb_wp] = val; +} + +I64 HDSyncRIRB() +{ + U16 * _w; + I64 wp, res = 0; + _w = hda.bar + HD_RIRBWP; + wp = *_w; + while (hda.rirb_rp != wp) + res = hda.rirb[++hda.rirb_rp]; + return res; +} + +I64 HDReadRIRB() +{ + U16 * _w; + I64 wp, res = 0; + _w = hda.bar + HD_RIRBWP; + do { + Yield; + wp = *_w; + } while (wp == hda.rirb_rp); + res = hda.rirb[++hda.rirb_rp]; + return res; +} + +I64 HDWriteCORBSync(I64 cad, I64 nid, U32 val) +{ + HDSyncCORB; + HDSyncRIRB; + HDWriteCORB(cad, nid, val); + HDSyncCORB; + return HDReadRIRB; +} + +Bool HDTestCORBSync(I64 cad, I64 nid, U32 val) +{ + //Checks for a response + U16 * _w; + I64 wp; + + HDSyncCORB; + HDSyncRIRB; + HDWriteCORB(cad, nid, val); + HDSyncCORB; + + Sleep(1); + _w = hda.bar + HD_RIRBWP; + wp = *_w; + if (wp == hda.rirb_rp) + return FALSE; + HDReadRIRB; + return TRUE; +} + +U0 HDTraverse(I64 cad, I64 nid) +{ + I64 i, len, aud_cap, type; + HDWriteCORBSync(cad, nid, VERB_POWER_STATE_SET + 0x00); //0 is on + HDWriteCORBSync(cad, nid, VERB_EAPDBTL_ENABLE_SET + 0x02); + HDWriteCORBSync(cad, nid, VERB_PROCESS_STATE_SET + 0x02); + HDWriteCORBSync(cad, nid, VERB_CONNECT_SEL_SET + 0x00); + aud_cap = HDWriteCORBSync(cad, nid, VERB_GET_PARAM + P_SUBNODE_CNT); + if (aud_cap.u16[0]) + { + for (i = aud_cap.u16[1]; i < aud_cap.u16[1] + aud_cap.u16[0]; i++) + HDTraverse(cad, i); + } + else + { + aud_cap = HDWriteCORBSync(cad, nid, VERB_GET_PARAM + P_AUDIO_WIDGET_CAP); + type = aud_cap >> 20 &15; + if (Bt(&aud_cap, 8)) + len = HDWriteCORBSync(cad, nid, VERB_GET_PARAM + P_CONNECT_LST_LEN) &127; + else + len = 0; + HDWriteCORBSync(cad, nid, VERB_AMPLIFIER_GAIN_SET + 0xF07F); //set I/O amp #0 + for (i = 1; i < len; i++) + //Set IN amps to mute + HDWriteCORBSync(cad, nid, VERB_AMPLIFIER_GAIN_SET + 0x7080 + i << 8); + switch (type) + { + case AWT_OUTPUT: + if (FALSE) //if disabled + HDWriteCORBSync(cad, nid, VERB_CHAN_STREAM_ID_SET + 0x00); + else + HDWriteCORBSync(cad, nid, VERB_CHAN_STREAM_ID_SET + 0x10); + HDWriteCORBSync(cad, nid, VERB_STREAM_FMT_SET + HD_DFT_OUT_FMT); + HDWriteCORBSync(cad, nid, VERB_PROCESS_STATE_SET + 0x01); + break; + case AWT_INPUT: + if (TRUE) //if disabled + HDWriteCORBSync(cad, nid, VERB_CHAN_STREAM_ID_SET + 0x00); + else + HDWriteCORBSync(cad, nid, VERB_CHAN_STREAM_ID_SET + 0x20); + HDWriteCORBSync(cad, nid, VERB_STREAM_FMT_SET + HD_DFT_IN_FMT); + HDWriteCORBSync(cad, nid, VERB_PROCESS_STATE_SET + 0x01); + break; + case AWT_PIN_COMPLEX: + HDWriteCORBSync(cad, nid, VERB_PIN_WIDGET_CTL_SET + 0xE2); + break; + } + } +} + +U0 HDRun(Bool in, Bool out) +{ + U32 * _d; + if (hda.bar) + { + if (out) + { + _d = hda.bar + OSTR0 + STRCTL; + *_d = 0x100002; + hda.out_running = TRUE; + } + + if (in) + { + _d = hda.bar + ISTR0 + STRCTL; + *_d = 0x200002; + hda.in_running = TRUE; + } + } +} + +U0 HDStop(Bool in, Bool out) +{ + U32 * _d; + if (hda.bar) + { + if (out) + { + _d = hda.bar + OSTR0 + STRCTL; + *_d = 0; + hda.out_running = FALSE; + } + + if (in) + { + _d = hda.bar + ISTR0 + STRCTL; + *_d = 0; + hda.in_running = FALSE; + } + } +} + +U0 HDSnd(F64 freq, I64 waveform = WF_SQUARE, F64 amp = 1.0) +{ + hda.waveform = waveform; + hda.amp = amp; + hda.freq = freq; +} + +U0 HDFillBuf(SND_OUT_CONTAINER *buf, I64) +{ + I64 i, size = SND_BUF_LEN* sizeof(SND_OUT_CONTAINER); + if (!hda.o_tmp_buf) + hda.o_tmp_buf = SysMAlloc(size); + MemSet(hda.o_tmp_buf, 0, size); + for (i = 0; i < HD_TONES; i++) + SndWaveAddBuf(hda.tone_swcs[i], hda.o_tmp_buf, + SND_BUF_LEN / SND_OCHANNELS, hda.freq, + hda.waveform, snd_vol *hda.amp); + MemCopy(buf, hda.o_tmp_buf, size); +} + +U0 HDAudioTaskEndCB() +{ + I64 i; + HDStop(FALSE, TRUE); + fp_snd = NULL; + for (i = 0; i < HD_TONES; i++) + { + SndWaveCtrlDel(hda.tone_swcs[i]); + hda.tone_swcs[i] = NULL; + } + + Exit; +} + +public U0 HDTonesInit() +{ + I64 i; + if (hda.bar) + { + for (i = 0; i < HD_TONES; i++) + { + hda.tone_swcs[i]->freq_multiplier = 1.0; + hda.tone_swcs[i]->amp_multiplier = 0; + } + + hda.tone_swcs[0]->amp_multiplier = 1.0; + } +} + +U0 HDAudioTask(I64) +{ + //I didn't feel like messing around with PCI interrupts + //so this task polls every millisecond to know when to + //switch buffers. + I64 i, next_obuf_trigger = SND_BUF_LEN* sizeof(SND_OUT_CONTAINER) / 2, + obuf_rollover = 0, + next_ibuf_trigger = SND_BUF_LEN* sizeof(SND_IN_CONTAINER), + ibuf_rollover = 0; + U32 *pos_in_obuf = hda.bar + OSTR0 + STRLPIB, + *pos_in_ibuf = hda.bar + ISTR0 + STRLPIB; + Fs->task_end_cb = &HDAudioTaskEndCB; + for (i = 0; i < HD_TONES; i++) + hda.tone_swcs[i] = SndWaveCtrlNew; + HDTonesInit; + hda.freq = 0; + Sound; + fp_snd = &HDSnd; + fp_snd_fill_buf = &HDFillBuf; + fp_snd_copy_buf = NULL; + snd_obuf_num = 1; + snd_ibuf_num = 1; + HDRun(FALSE, TRUE); + hda.audio_task_started = TRUE; //This flag is probably not necessary + while (TRUE) + { + if (next_obuf_trigger - obuf_rollover <= *pos_in_obuf< next_obuf_trigger - obuf_rollover + + (HD_POS_BUF_MULTIPLES - 1) *SND_BUF_LEN* sizeof(SND_OUT_CONTAINER)) + { + next_obuf_trigger += SND_BUF_LEN* sizeof(SND_OUT_CONTAINER); + if (next_obuf_trigger - obuf_rollover >= + HD_POS_BUF_MULTIPLES *SND_BUF_LEN* sizeof(SND_OUT_CONTAINER)) + obuf_rollover += HD_POS_BUF_MULTIPLES *SND_BUF_LEN * + sizeof(SND_OUT_CONTAINER); + if (fp_snd_fill_buf) + { + LBts(&snd_flags, Sf_FILLING_OUT); + (*fp_snd_fill_buf)(hda.ostr0_buf[snd_obuf_num & 1], snd_obuf_num); + if (IsMute) + MemSet(hda.ostr0_buf[snd_obuf_num & 1], 0, + SND_BUF_LEN* sizeof(SND_OUT_CONTAINER)); + LBtr(&snd_flags, Sf_FILLING_OUT); + } + + snd_obuf_num++; + } + + if (next_ibuf_trigger - ibuf_rollover <= *pos_in_ibuf< next_ibuf_trigger - ibuf_rollover + (HD_POS_BUF_MULTIPLES - 1) * + SND_BUF_LEN* sizeof(SND_IN_CONTAINER)) + { + next_ibuf_trigger += SND_BUF_LEN* sizeof(SND_IN_CONTAINER); + if (next_ibuf_trigger - ibuf_rollover >= + HD_POS_BUF_MULTIPLES *SND_BUF_LEN* sizeof(SND_IN_CONTAINER)) + ibuf_rollover += HD_POS_BUF_MULTIPLES *SND_BUF_LEN *sizeof(SND_IN_CONTAINER); + if (fp_snd_copy_buf) + (*fp_snd_copy_buf)(hda.istr0_buf[snd_obuf_num & 1], snd_ibuf_num); + snd_ibuf_num++; + } + + Sleep(1); + } +} + +U0 HDRst() +{ + U32 d, *_d; + HDStop(TRUE, TRUE); + _d = hda.bar + HD_GCTL; + *_d = 0; //rst + do { + Sleep(1); + d = *_d; + } while (d & 1); + *_d = 1; + do { + Sleep(1); + d = *_d; + } while (!(d & 1)); + Sleep(1); +} + +public U0 HDAudioEnd(Bool rst = TRUE) +{ + snd_dev = SD_PC_SPEAKER; + if (hda.bar) + { + Kill(hda.task); + hda.task = NULL; + if (rst) + HDRst; + Free(hda.corb); + Free(hda.rirb); + Free(hda.o_tmp_buf); + Free(hda.ostr0_buf[0]); + Free(hda.ostr0_buf[1]); + Free(hda.istr0_buf[0]); + Free(hda.istr0_buf[1]); + Free(hda.ostr0_bdl); + Free(hda.istr0_bdl); + Mem32DevFree(hda.bar); + hda.bar = NULL; + } +} + +U0 HDAudioUncachedInit() +{ + I64 shared_blks = 1; + hda.bp = Mem2MegUncachedAlloc(&shared_blks); + hda.hc = HeapCtrlBPInit(hda.bp, shared_blks << 12); +} + +public Bool HDAudioInit(I64 hd_bus, I64 hd_dev, I64 hd_fun) +{ + I64 i; + U32 * _d; + U16 w, *_w; + U8 * _b; + if (hda.bar) + HDAudioEnd; + else + HDAudioUncachedInit; + if (PCIReadU16(hd_bus, hd_dev, hd_fun, 0) == 0x8086 && + (hda.bar = PCIReadU32(hd_bus, hd_dev, hd_fun, 0x10) &~(0x1F))) + { + PCIWriteU16(hd_bus, hd_dev, hd_fun, 0x04, + PCIReadU16(hd_bus, hd_dev, hd_fun, 0x04) | 0x406); + + HDRst; + + hda.corb = CAllocAligned(HD_CORB_ENTRIES* sizeof(U32), 128, hda.hc); + _d = hda.bar + HD_CORBLBASE; + *_d = hda.corb(I64).u32[0]; + _d = hda.bar + HD_CORBUBASE; + *_d = hda.corb(I64).u32[1]; + + hda.rirb = CAllocAligned(HD_RIRB_ENTRIES* sizeof(I64), 128, hda.hc); + _d = hda.bar + HD_RIRBLBASE; + *_d = hda.rirb(I64).u32[0]; + _d = hda.bar + HD_RIRBUBASE; + *_d = hda.rirb(I64).u32[1]; + + _w = hda.bar + HD_CORBRP; + /* + *_w=0x8000; //Rst read ptr + do { + Yield; + w=*_w; + } while (!(w&0x8000)); + */ + *_w = 0x0000; //Rst read ptr + do { Yield; + w = *_w; + } while (w & 0x8000); + + _w = hda.bar + HD_RIRBWP; + *_w = 0x8000; //Rst write ptr + + _b = hda.bar + HD_CORBCTL; + *_b = 0x02; //Run + _b = hda.bar + HD_RIRBCTL; + *_b = 0x02; //Run + + _w = hda.bar + HD_CORBWP; + hda.corb_wp = *_w; + _w = hda.bar + HD_RIRBWP; + hda.rirb_rp = *_w; + + hda.ostr0_bdl = CAllocAligned( HD_BDL_ENTRIES* sizeof(CHDBufDesc), 128, hda.hc); + _d = hda.bar + OSTR0 + STRBDPL; + *_d = hda.ostr0_bdl(I64).u32[0]; + _d = hda.bar + OSTR0 + STRBDPU; + *_d = hda.ostr0_bdl(I64).u32[1]; + for (i = 0; i < 2; i++) + { + hda.ostr0_bdl[i].buf = hda.ostr0_buf[i] = + CAllocAligned( SND_BUF_LEN* sizeof(SND_OUT_CONTAINER), 128, hda.hc); + hda.ostr0_bdl[i].len = SND_BUF_LEN* sizeof(SND_OUT_CONTAINER); + hda.ostr0_bdl[i].ctrl = 1; + } + + hda.istr0_bdl = CAllocAligned( HD_BDL_ENTRIES* sizeof(CHDBufDesc), 128, hda.hc); + _d = hda.bar + ISTR0 + STRBDPL; + *_d = hda.istr0_bdl(I64).u32[0]; + _d = hda.bar + ISTR0 + STRBDPU; + *_d = hda.istr0_bdl(I64).u32[1]; + for (i = 0; i < 2; i++) + { + hda.istr0_bdl[i].buf = hda.istr0_buf[i] = CAllocAligned( SND_BUF_LEN* sizeof(SND_IN_CONTAINER), 128, hda.hc); + hda.istr0_bdl[i].len = SND_BUF_LEN* sizeof(SND_IN_CONTAINER); + hda.istr0_bdl[i].ctrl = 1; + } + + _w = hda.bar + HD_STATESTS; + w = *_w; + while (w) + { + hda.cad = Bsf(w); + if (HDTestCORBSync(hda.cad, 0, VERB_GET_PARAM + P_SUBNODE_CNT)) + { + HDTraverse(hda.cad, 0); + + _d = hda.bar + OSTR0 + STRLPIB; + *_d = 0; + _d = hda.bar + OSTR0 + STRCBL; + *_d = HD_POS_BUF_MULTIPLES *SND_BUF_LEN* sizeof(SND_OUT_CONTAINER); + _w = hda.bar + OSTR0 + STRLVI; + *_w = 1; //last valid idx + _w = hda.bar + OSTR0 + STRFMT; + *_w = HD_DFT_OUT_FMT; + + _d = hda.bar + ISTR0 + STRLPIB; + *_d = 0; + _d = hda.bar + ISTR0 + STRCBL; + *_d = HD_POS_BUF_MULTIPLES *SND_BUF_LEN* sizeof(SND_IN_CONTAINER); + _w = hda.bar + ISTR0 + STRLVI; + *_w = 1; //last valid idx + _w = hda.bar + ISTR0 + STRFMT; + *_w = HD_DFT_IN_FMT; + + LBts(&sys_semas[SEMA_SOUND], 0); //turn off until cfg completed + LBtr(&snd_flags, Sf_FILLING_OUT); + hda.audio_task_started = FALSE; + if (mp_count > 1) + hda.task = Spawn(&HDAudioTask, NULL, "HD Audio", mp_count - 1); + else + hda.task = Spawn(&HDAudioTask, NULL, "HD Audio"); + while (!hda.audio_task_started) + Yield; + snd_dev = SD_HD_AUDIO; + return TRUE; + } + + Btr(&w, hda.cad); + } + + HDAudioEnd(FALSE); + } + else + hda.bar = NULL; + return FALSE; +} + +Bool HDAudioScan() +{ + I64 i = -1, j; + while (TRUE) + { + j = PCIClassFind(0x040300, ++i); + if (j < 0) + return FALSE; + + if (HDAudioInit(j.u8[2], j.u8[1], j.u8[0])) + return TRUE; + } +} + +HDAudioScan; +Kill(hda.task); +HDAudioScan; \ No newline at end of file diff --git a/src/Home/Sound/HDAudio1/Load.ZC b/src/Home/Sound/HDAudio1/Load.ZC new file mode 100644 index 000000000..8fb4d20a0 --- /dev/null +++ b/src/Home/Sound/HDAudio1/Load.ZC @@ -0,0 +1,6 @@ +Cd(__DIR__); + +SysFile("Sup1CodeScraps/Mem/Mem2Meg.ZC"); +SysFile("Sup1Snd/MakeSnd.ZC"); +SysFile("Sup1HDAudio/HDAudio.ZC"); + \ No newline at end of file diff --git a/src/Home/Sound/HDAudio1/Sup1CodeScraps/Mem/Mem2Meg.ZC b/src/Home/Sound/HDAudio1/Sup1CodeScraps/Mem/Mem2Meg.ZC new file mode 100644 index 000000000..fb94b9b93 --- /dev/null +++ b/src/Home/Sound/HDAudio1/Sup1CodeScraps/Mem/Mem2Meg.ZC @@ -0,0 +1,199 @@ +//Now, we use 1 Gig page table entries. + +//See $LK,"./UncachedAlloc.ZC"$ + +U8 *Mem2MegAlloc(I64 *_pages2Meg,CBlkPool *bp=NULL) +{/*Alloc 2Meg pages from BlkPool. Don't link to task. +(Linking to a task means they will be freed when the task dies.) +It might give you more than you asked for +so a ptr to a page count is passed. + +Return: NULL if out of memory. +*/ + I64 i,j,*pte,num=*_pages2Meg; + CMemBlk *res=NULL,*m,*m1; + + if (!bp) bp=sys_code_bp; + PUSHFD + CLI + while (LBts(&bp->locked_flags,BPlf_LOCKED)) + PAUSE + num<<=21-MEM_PAG_BITS; + + m=&bp->mem_free_2meg_list; + while (TRUE) { + if (!(res=m->next)) + break; + if (res->pagspags==num) { + m->next=res->next; + goto am_done; + } else { + res->pags-=num; + res(U8 *)+=res->pags<pags=num; + goto am_done; + } + } + } + + m=&bp->mem_free_list; + while (TRUE) { + if (!(res=m->next)) { + num=0; + res=NULL; //Out of memory + goto am_done; + } + if (res->pagspags==num) { + if (res(U8 *)&0x1FFFFF) + m=res; + else { + m->next=res->next; + goto am_done; + } + } else { + if (i=(res(U8 *)&0x1FFFFF)>>MEM_PAG_BITS) { + j=1<<(21-MEM_PAG_BITS)-i; + if (res->pagspags==num+j) { + res->pags-=num; + res(U8 *)+=res->pags<pags=num; + goto am_done; + } else { + m1=res; + res(U8 *)+=j<pags=num; + m=res(U8 *)+num<pags=m1->pags-num-j; + m1->pags=j; + m->next=m1->next; + m1->next=m; + m->mb_signature=MBS_UNUSED_SIGNATURE_VAL; + goto am_done; + } + } else { + m=m->next=res(U8 *)+num<next=res->next; + m->pags=res->pags-num; + m->mb_signature=MBS_UNUSED_SIGNATURE_VAL; + res->pags=num; + goto am_done; + } + } + } + } +am_done: + i=num<used_u8s+=i; + num>>=21-MEM_PAG_BITS; + *_pages2Meg=num; + m=res; + m1=m(U8 *)+i; + while (mlocked_flags,BPlf_LOCKED); + POPFD + return res; +} + +U8 *Mem2MegUncachedAlloc(I64 *_pages2Meg,CBlkPool *bp=NULL) +{/*Alloc 2Meg pages from BlkPool. Don't link to task. +(Linking to a task means they will be freed when the task dies.) +It will be marked uncached. It might give you more than you asked for +so a ptr to a page count is passed. + +Return: NULL if out of memory. +*/ + CMemBlk *res,*m,*m1; + I64 num=*_pages2Meg,*pte; + if (res=Mem2MegAlloc(_pages2Meg,bp)) { + num=*_pages2Meg; + m=res; + m1=m(U8 *)+num<<21; + while (mlocked_flags,BPlf_LOCKED)) + PAUSE + m->mb_signature=MBS_UNUSED_SIGNATURE_VAL; + m->pags=pages2Meg<<(21-MEM_PAG_BITS); + bp->used_u8s-=pages2Meg<<21; + m->next=bp->mem_free_2meg_list; + bp->mem_free_2meg_list=m; + LBtr(&bp->locked_flags,BPlf_LOCKED); + POPFD + } +} + +CHeapCtrl *HeapCtrlBPInit(CBlkPool *bp,I64 pags) +{//Make mem chunk into HeapCtrl and BlkPool. + I64 num; + CMemBlk *m; + CHeapCtrl *hc; + MemSet(bp,0,sizeof(CBlkPool)+sizeof(CHeapCtrl)); + hc=HeapCtrlInit(bp(U8 *)+sizeof(CBlkPool),,bp); + m=(bp(U8 *)+sizeof(CBlkPool)+sizeof(CHeapCtrl)+MEM_PAG_SIZE-1)& + ~(MEM_PAG_SIZE-1); + num=(bp(U8 *)+pags<>MEM_PAG_BITS; + bp->alloced_u8s=(pags-num)<task_end_cb; + Fs->task_end_cb=&BeatTaskEndCB; //Catch or Kill() task + start_buf_num=snd_obuf_num; + fp_old_fill_buf=fp_snd_fill_buf; + fp_snd_fill_buf=&BeatFillBuf; + try { + "Pick two frequencies within a few Hz of each other to hear beats.\n" + "Pick two frequencies a multiple of two for an octave harmonic.\n" + "$$FG,GREEN$$$$FG$$ to exit.\n"; + while (TRUE) { + freq1=PmtF64("Freq #1 (%0.2fHz):",freq1,20,20000); + freq2=PmtF64("Freq #2 (%0.2fHz):",freq2,20,20000); + } + } catch { //Catch , but pass it on to next higher handler. + fp_snd_fill_buf=fp_old_fill_buf; + Fs->task_end_cb=fp_task_end_cb; + } + beat_done=TRUE; + fp_snd_fill_buf=fp_old_fill_buf; + Fs->task_end_cb=fp_task_end_cb; +} + +BeatFreq; diff --git a/src/Home/Sound/HDAudio1/Sup1HDAudio/Examples/Chords.ZC b/src/Home/Sound/HDAudio1/Sup1HDAudio/Examples/Chords.ZC new file mode 100644 index 000000000..208cd1256 --- /dev/null +++ b/src/Home/Sound/HDAudio1/Sup1HDAudio/Examples/Chords.ZC @@ -0,0 +1,16 @@ +U0 Chords(Bool val=ON) +{ + if (snd_dev!=SD_HD_AUDIO) { + "Only works for HD Audio.\n"; + return; + } + HDTonesInit; + if (val) { + hda.tone_swcs[1]->freq_multiplier=4.0/3.0; + hda.tone_swcs[1]->amp_multiplier=1.0; + hda.tone_swcs[2]->freq_multiplier=(4.0/3.0)`2; + hda.tone_swcs[2]->amp_multiplier=1.0; + } +} + +Chords(ON); diff --git a/src/Home/Sound/HDAudio1/Sup1HDAudio/Examples/Echo.ZC b/src/Home/Sound/HDAudio1/Sup1HDAudio/Examples/Echo.ZC new file mode 100644 index 000000000..fae70f2c2 --- /dev/null +++ b/src/Home/Sound/HDAudio1/Sup1HDAudio/Examples/Echo.ZC @@ -0,0 +1,99 @@ +Bool echo_done; + +U0 (*fp_task_end_cb)(); +U0 (*fp_old_fill_buf)(SND_OUT_CONTAINER *buf,I64 buf_num)=NULL; +U0 (*fp_old_copy_buf)(SND_IN_CONTAINER *buf,I64 buf_num)=NULL; + +#define BUF_NUM 8 +SND_IN_CONTAINER my_buf[SND_BUF_LEN*BUF_NUM]; + +I64 my_ibuf_ptr,my_obuf_ptr; + +U0 EchoFillBuf(SND_OUT_CONTAINER *buf,I64) +{ + I64 j; + if (echo_done) return; + j=0; + while (jpix_height>>1; + dc->color=BLUE; + for (i=0;ipix_width/SND_BUF_LEN; + y1=cy-buf[i]*cy/I16_MAX; + GrLine(dc,x2,y2,x1,y1); + x2=x1; + y2=y1; + } +} + +U0 EchoDemo() +{ + if (snd_dev!=SD_HD_AUDIO) { + "Only works for HD Audio.\n"; + return; + } + SettingsPush; //See $LK,"SettingsPush",A="MN:SettingsPush"$ + HDRun(TRUE,TRUE); + echo_done=FALSE; + fp_task_end_cb=Fs->task_end_cb; + Fs->task_end_cb=&EchoTaskEndCB; //Catch or Kill() task + my_ibuf_ptr=(BUF_NUM/2)*SND_BUF_LEN; + my_obuf_ptr=0; + fp_old_fill_buf=fp_snd_fill_buf; + fp_old_copy_buf=fp_snd_copy_buf; + fp_snd_fill_buf=&EchoFillBuf; + fp_snd_copy_buf=&EchoCopyBuf; + DocCursor; + DocClear; + Fs->draw_it=&DrawIt; + try + CharGet; + catch { //Catch , but pass it on to next higher handler. + fp_snd_fill_buf=fp_old_fill_buf; + fp_snd_copy_buf=fp_old_copy_buf; + Fs->task_end_cb=fp_task_end_cb; + } + echo_done=TRUE; + HDStop(TRUE,FALSE); + fp_snd_fill_buf=fp_old_fill_buf; + fp_snd_copy_buf=fp_old_copy_buf; + Fs->task_end_cb=fp_task_end_cb; + SettingsPop; +} + +EchoDemo; + \ No newline at end of file diff --git a/src/Home/Sound/HDAudio1/Sup1HDAudio/Examples/Guitar.ZC b/src/Home/Sound/HDAudio1/Sup1HDAudio/Examples/Guitar.ZC new file mode 100644 index 000000000..cbe4aa728 --- /dev/null +++ b/src/Home/Sound/HDAudio1/Sup1HDAudio/Examples/Guitar.ZC @@ -0,0 +1,17 @@ +U0 Guitar(Bool val=ON,F64 à=0.7) +{ + I64 i; + F64 m; + if (snd_dev!=SD_HD_AUDIO) { + "Only works for HD Audio.\n"; + return; + } + HDTonesInit; + if (val) + for (i=0,m=1.0;ifreq_multiplier=i+1; + hda.tone_swcs[i]->amp_multiplier=m; + } +} + +Guitar(ON); diff --git a/src/Home/Sound/HDAudio1/Sup1HDAudio/Examples/PolyPhonic.ZC b/src/Home/Sound/HDAudio1/Sup1HDAudio/Examples/PolyPhonic.ZC new file mode 100644 index 000000000..fe24da53e --- /dev/null +++ b/src/Home/Sound/HDAudio1/Sup1HDAudio/Examples/PolyPhonic.ZC @@ -0,0 +1,96 @@ +Bool poly_done; +I64 start_buf_num; +U0 (*fp_task_end_cb)(); +U0 (*fp_old_fill_buf)(SND_OUT_CONTAINER *buf,I64 buf_num)=NULL; + +U0 PolyFillBuf(SND_OUT_CONTAINER *buf,I64 buf_num) +{ //Gets called by HD Audio task -- HDAudioTask(). + + //Note: the buffer is in uncached memory + //so you might want to avoid multiple + //accesses due to slow speed. (If you were + //to add a bunch of waveforms together, you + //might want to do it in a cached buffer + //and copy it once.) + + I64 j,m,r; + F64 t,d; + if (poly_done) return; + t=ToF64((buf_num-start_buf_num)*(SND_BUF_LEN/SND_OCHANNELS))/SND_SAMPLE_RATE; + j=0; + while (j4.0) { + if (0.908.0) { + if (0.7012.0) { + if (0.3016.0) + m+=0.3*I32_MAX*Caw(t,1.0/6)*Sin(440.0*(2*ã)*t); + } + } + } + + //Samples are 24-bit, placed in upper 24 bits of an I32. + m*=snd_vol; + buf[j++]=ToI64(m*d)&0xFFFFFF00; //Left + buf[j++]=ToI64(m*(1.0-d))&0xFFFFFF00; //Right + + t+=1.0/SND_SAMPLE_RATE; + } +} + +U0 PolyTaskEndCB() +{ + poly_done=TRUE; + fp_snd_fill_buf=fp_old_fill_buf; + if (fp_task_end_cb) + (*fp_task_end_cb)(); + else + Exit; +} + +U0 PolyPhonic() +{ + if (snd_dev!=SD_HD_AUDIO) { + "Only works for HD Audio.\n"; + return; + } + poly_done=FALSE; + fp_task_end_cb=Fs->task_end_cb; + Fs->task_end_cb=&PolyTaskEndCB; //Catch or Kill() task + start_buf_num=snd_obuf_num; + fp_old_fill_buf=fp_snd_fill_buf; + fp_snd_fill_buf=&PolyFillBuf; + try +#if __CMD_LINE__ + PressAKey; +#else + View; +#endif + catch { //Catch , but pass it on to next higher handler. + fp_snd_fill_buf=fp_old_fill_buf; + Fs->task_end_cb=fp_task_end_cb; +} +poly_done=TRUE; +fp_snd_fill_buf=fp_old_fill_buf; +Fs->task_end_cb=fp_task_end_cb; +} + +#if __CMD_LINE__ +PolyPhonic; +#endif diff --git a/src/Home/Sound/HDAudio1/Sup1HDAudio/Examples/Record.ZC b/src/Home/Sound/HDAudio1/Sup1HDAudio/Examples/Record.ZC new file mode 100644 index 000000000..c81d8583b --- /dev/null +++ b/src/Home/Sound/HDAudio1/Sup1HDAudio/Examples/Record.ZC @@ -0,0 +1,117 @@ +Bool record_stop,record_done; + +U0 (*fp_old_copy_buf)(SND_IN_CONTAINER *buf,I64 buf_num)=NULL; + +#define RECORD_BUF_SIZE (SND_BUF_LEN*0x100) + +SND_IN_CONTAINER *record_buf[2]; +I64 record_buf_iptr,record_ibuf_num,record_obuf_num; + +U0 RecordCopyBuf(SND_IN_CONTAINER *buf,I64) +{ + I64 j; + SND_IN_CONTAINER *_s=record_buf[record_ibuf_num&1]; + j=0; + while (j=RECORD_BUF_SIZE) { + record_buf_iptr=0; + record_ibuf_num++; + } +} + +U0 DrawIt(CTask *task,CDC *dc) +{ + SND_IN_CONTAINER *buf=hda.istr0_buf[0]; + I64 i,x1,y1,x2=0,y2=0, + cy=task->pix_height>>1; + dc->color=BLUE; + for (i=0;ipix_width/SND_BUF_LEN; + y1=cy-buf[i]*cy/I16_MAX; + GrLine(dc,x2,y2,x1,y1); + x2=x1; + y2=y1; + } + dc->color=RED; +} + +U0 RecordTaskEndCB() +{ + fp_snd_copy_buf=fp_old_copy_buf; + HDStop(TRUE,FALSE); + Free(record_buf[0]); + Free(record_buf[1]); + record_done=TRUE; + Exit; +} + +U0 RecordTask(U8 *filename) +{ + Bool old_io_snd; + U8 *filename=StrNew(filename),*filename2; + TaskInitExt; //needed for disk access + record_buf[0]=CAlloc(RECORD_BUF_SIZE*sizeof(SND_IN_CONTAINER)); + record_buf[1]=CAlloc(RECORD_BUF_SIZE*sizeof(SND_IN_CONTAINER)); + FileExtRemove(filename); + record_buf_iptr=0; + record_ibuf_num=0; + record_obuf_num=0; + record_done=FALSE; + Fs->task_end_cb=&RecordTaskEndCB; + fp_old_copy_buf=fp_snd_copy_buf; + fp_snd_copy_buf=&RecordCopyBuf; + HDRun(TRUE,FALSE); + old_io_snd=IOSnd(OFF); + while (!record_stop) { + if (record_ibuf_num>record_obuf_num) { + filename2=MPrint("%s%04d.SNZ",filename,record_obuf_num); + SndFileWrite(filename2,record_buf[record_obuf_num&1],RECORD_BUF_SIZE); + record_obuf_num++; + Free(filename2); + } + Sleep(1); + } + filename2=MPrint("%s%04d.SNZ",filename,record_obuf_num); + SndFileWrite(filename2,record_buf[record_obuf_num&1],record_buf_iptr); + record_obuf_num++; + Free(filename2); + Free(filename); + IOSnd(old_io_snd); + record_done=TRUE; +} + +U0 RecordDemo(U8 *filename="~/Record.SNZ") +{ + if (snd_dev!=SD_HD_AUDIO) { + "Only works for HD Audio.\n"; + return; + } + record_done=FALSE; + record_stop=FALSE; + Spawn(&RecordTask,filename,"Record .SNZ",,Fs); + SettingsPush; //See $LK,"SettingsPush",A="MN:SettingsPush"$ + DocCursor; + DocClear; + Fs->draw_it=&DrawIt; + try + CharGet; + catch //Catch , but pass it on to next higher handler. + record_stop=TRUE; + record_stop=TRUE; + while (record_done) + Yield; + SettingsPop; + while (TRUE) { + "\n\nPlay "; + if (YorN) + SndFilePlaySeq(filename,record_obuf_num); + else + break; + } + NewLine(2); +} + +RecordDemo; diff --git a/src/Home/Sound/HDAudio1/Sup1HDAudio/Examples/SndScope.ZC b/src/Home/Sound/HDAudio1/Sup1HDAudio/Examples/SndScope.ZC new file mode 100644 index 000000000..52313a14d --- /dev/null +++ b/src/Home/Sound/HDAudio1/Sup1HDAudio/Examples/SndScope.ZC @@ -0,0 +1,44 @@ +U0 DrawIt(CTask *task,CDC *dc) +{ + SND_OUT_CONTAINER *buf=hda.ostr0_buf[0]; + I64 i,x1,y1,x2,y2, + cy=task->pix_height>>1; + + dc->color=BLUE; + x2=0;y2=cy; + for (i=0;ipix_width/SND_BUF_LEN; + y1=cy-buf[i]*cy/snd_vol/I32_MAX; + GrLine(dc,x2,y2,x1,y1); + x2=x1;y2=y1; + } + + dc->color=GREEN; + x2=0;y2=cy; + for (i=1;ipix_width/SND_BUF_LEN; + y1=cy-buf[i]*cy/snd_vol/I32_MAX; + GrLine(dc,x2,y2,x1,y1); + x2=x1; y2=y1; + } +} + +U0 SndScope() +{ + if (snd_dev!=SD_HD_AUDIO) { + "Only works for HD Audio.\n"; + return; + } + SettingsPush; //See $LK,"SettingsPush",A="MN:SettingsPush"$ + WinHorz(1,18); + WinVert(15,TEXT_ROWS-2); + DocCursor; + DocClear; + Fs->draw_it=&DrawIt; + CharGet; + SettingsPop; +} + +#if __CMD_LINE__ +SndScope; +#endif diff --git a/src/Home/Sound/HDAudio1/Sup1HDAudio/Examples/Synth.ZC b/src/Home/Sound/HDAudio1/Sup1HDAudio/Examples/Synth.ZC new file mode 100644 index 000000000..43c0ef17d --- /dev/null +++ b/src/Home/Sound/HDAudio1/Sup1HDAudio/Examples/Synth.ZC @@ -0,0 +1,280 @@ +#define M_WAVEFORM 0 +#define M_FREQUENCY 1 +#define M_ENVELOPE 2 + +#define M_MODES_NUM 3 + +I64 mode; +Bool my_ms_down; +I64 last_x,last_y; + +Bool synth_done; + +U0 (*fp_task_end_cb)(); +U0 (*fp_old_fill_buf)(SND_OUT_CONTAINER *buf,I64 buf_num)=NULL; + +#define BUF_NUM 8 +SND_OUT_CONTAINER my_buf[SND_BUF_LEN*BUF_NUM]; + +#define WF_BUF_LEN 2048 +#define WF_Y_SCALE 2048.0 +I64 waveform_buf[WF_BUF_LEN]; + +#define FQ_BUF_LEN 2048 +#define FQ_Y_SCALE 2048.0 +I64 frequency_buf[FQ_BUF_LEN]; +F64 fq_scale; + +#define EL_BUF_LEN 2048 +#define EL_Y_SCALE 2048.0 +I64 envelope_buf[EL_BUF_LEN]; +F64 el_scale; + +U0 SynthFillBuf(SND_OUT_CONTAINER *buf,I64 buf_num) +{ + I64 i,j,l,k0,k1,k2,k3; + F64 d; + static F64 k=0; + if (synth_done) return; + j=0; + k0=buf_num*(SND_BUF_LEN/SND_OCHANNELS); + while (jpix_height>>1, + h_max=task->pix_width-1; + + if (!winmgr.show_menu) { + if (mouse.lb) { + if (my_ms_down) + switch (mode) { + case M_WAVEFORM: + Line(NULL, + (last_x-task->pix_left-task->scroll_x)*WF_BUF_LEN/h_max, + WF_Y_SCALE*(cy-last_y+task->pix_top+task->scroll_y)/cy,0, + ( msx-task->pix_left-task->scroll_x)*WF_BUF_LEN/h_max, + WF_Y_SCALE*(cy-msy+task->pix_top+task->scroll_y)/cy,0, + &WFPlot); + break; + case M_FREQUENCY: + Line(NULL, + (last_x-task->pix_left-task->scroll_x)*FQ_BUF_LEN/h_max, + FQ_Y_SCALE*(cy-last_y+task->pix_top+task->scroll_y)/cy,0, + ( msx-task->pix_left-task->scroll_x)*FQ_BUF_LEN/h_max, + FQ_Y_SCALE*(cy-msy+task->pix_top+task->scroll_y)/cy,0, + &FQPlot); + break; + case M_ENVELOPE: + Line(NULL, + (last_x-task->pix_left-task->scroll_x)*EL_BUF_LEN/h_max, + EL_Y_SCALE*(cy-last_y+task->pix_top+task->scroll_y)/cy,0, + ( msx-task->pix_left-task->scroll_x)*EL_BUF_LEN/h_max, + EL_Y_SCALE*(cy-msy+task->pix_top+task->scroll_y)/cy,0, + &ELPlot); + break; + } + my_ms_down=TRUE; + last_x=msx; + last_y=msy; + } else + my_ms_down=FALSE; + } + + x2=-1; + if (mode==M_WAVEFORM && Blink) { + dc->color=ROPF_DITHER+WHITE<<16+RED; + GrPrint(dc,0,cy-FONT_HEIGHT,"Set Waveform."); + } else + dc->color=RED; + for (i=0;ipix_width/WF_BUF_LEN; + y1=cy-cy*waveform_buf[i]/WF_Y_SCALE; + if (x2>=0) + GrLine(dc,x2,y2,x1,y1); + x2=x1; + y2=y1; + } + + x2=-1; + if (mode==M_FREQUENCY && Blink) { + dc->color=ROPF_DITHER+WHITE<<16+BLUE; + GrPrint(dc,0,cy-FONT_HEIGHT,"Set Frequency."); + } else + dc->color=BLUE; + for (i=0;ipix_width/FQ_BUF_LEN; + y1=cy-cy*frequency_buf[i]/FQ_Y_SCALE; + if (x2>=0) + GrLine(dc,x2,y2,x1,y1); + GrLine(dc,x2,cy-(y2-cy),x1,cy-(y1-cy)); + x2=x1; + y2=y1; + } + + x2=-1; + if (mode==M_ENVELOPE && Blink) { + dc->color=ROPF_DITHER+WHITE<<16+GREEN; + GrPrint(dc,0,cy-FONT_HEIGHT,"Set Envelope."); + } else + dc->color=GREEN; + for (i=0;ipix_width/EL_BUF_LEN; + y1=cy-cy*envelope_buf[i]/EL_Y_SCALE; + if (x2>=0) + GrLine(dc,x2,y2,x1,y1); + GrLine(dc,x2,cy-(y2-cy),x1,cy-(y1-cy)); + x2=x1; + y2=y1; + } + + dc->color=BLACK; + GrLine(dc,0,cy,task->pix_width,cy); +} + +U0 SetMenu() +{ + MenuEntryFind(Fs->cur_menu,"Mode/Waveform")->checked=mode==M_WAVEFORM; + MenuEntryFind(Fs->cur_menu,"Mode/Frequency")->checked=mode==M_FREQUENCY; + MenuEntryFind(Fs->cur_menu,"Mode/Envelope")->checked=mode==M_ENVELOPE; +} + +U0 Init() +{ + my_ms_down=FALSE; + mode=M_WAVEFORM; + MemSetI64(&waveform_buf[0] ,-0.5 *WF_Y_SCALE,WF_BUF_LEN/2); + MemSetI64(&waveform_buf[WF_BUF_LEN/2] , 0.5 *WF_Y_SCALE,WF_BUF_LEN/2); + MemSetI64(frequency_buf , 0.25*FQ_Y_SCALE,FQ_BUF_LEN); + MemSetI64(envelope_buf , 0.75*EL_Y_SCALE,EL_BUF_LEN); + fq_scale=0.02; + el_scale=0.02; + SetMenu; +} + +U0 Synth() +{ + I64 arg1,arg2; + if (snd_dev!=SD_HD_AUDIO) { + "Only works for HD Audio.\n"; + return; + } + + SettingsPush; //See $LK,"SettingsPush",A="MN:SettingsPush"$ + MenuPush( + "File {" + " New(,'\n');" + " Abort(,CH_SHIFT_ESC);" + " Exit(,CH_ESC);" + "}" + "Mode {" + " Waveform(,'1');" + " Frequency(,'2');" + " Envelope(,'3');" + "}" + ); + AutoComplete; + WinBorder; + WinMax; + DocCursor; + DocClear; + Fs->win_inhibit=WIG_TASK_DEFAULT-WIF_SELF_FOCUS-WIF_FOCUS_TASK_MENU; + + Init; + + synth_done=FALSE; + fp_task_end_cb=Fs->task_end_cb; + Fs->task_end_cb=&SynthTaskEndCB; //Catch or Kill() task + fp_old_fill_buf=fp_snd_fill_buf; + fp_snd_fill_buf=&SynthFillBuf; + Fs->draw_it=&DrawIt; + try { + while (TRUE) { + switch (MessageGet(&arg1,&arg2,1<, but pass it on to next higher handler. + fp_snd_fill_buf=fp_old_fill_buf; + Fs->task_end_cb=fp_task_end_cb; + } + synth_done=TRUE; + fp_snd_fill_buf=fp_old_fill_buf; + Fs->task_end_cb=fp_task_end_cb; + SettingsPop; +} + +Synth; + \ No newline at end of file diff --git a/src/Home/Sound/HDAudio1/Sup1HDAudio/HDAudio.ZC b/src/Home/Sound/HDAudio1/Sup1HDAudio/HDAudio.ZC new file mode 100644 index 000000000..ac00b25dd --- /dev/null +++ b/src/Home/Sound/HDAudio1/Sup1HDAudio/HDAudio.ZC @@ -0,0 +1,697 @@ +//SysFile("~/sup1hdaudio/Sup1CodeScraps/Mem/Mem2Meg.ZC"); + +# +help_index "Sound/HDAudio" + +//snd devs +#define SD_PC_SPEAKER 0 +#define SD_HD_AUDIO 1 +#define SND_SAMPLE_RATE 48000 +#define SND_SAMPLE_BITS 24 +#define SND_OCHANNELS 2 +#define SND_ICHANNELS 2 +#define SND_OUT_CONTAINER I32 +#define SND_IN_CONTAINER I16 +#define SND_BUF_LEN 0x400 +#define SND_BUF_TIME_mS(SND_BUF_LEN / SND_OCHANNELS *1000.0 / \ + SND_SAMPLE_RATE) + +F64 snd_freq = 0; +I64 snd_dev = SD_PC_SPEAKER; +Bool snd_record = FALSE; +F64 snd_vol = 0.1; +U0(*fp_snd)(F64 freq, I64 waveform, F64 amp) = NULL; +U0(*fp_snd_record)(F64 freq, I64 waveform, F64 amp) = NULL; +U0(*fp_snd_fill_buf)(SND_OUT_CONTAINER *buf, I64 buf_num) = NULL; +U0(*fp_snd_copy_buf)(SND_IN_CONTAINER *buf, I64 buf_num) = NULL; + +I64 snd_obuf_num, snd_ibuf_num; + +#define Sf_FILLING_OUT 0 +I64 snd_flags; + +#define HD_1_CHAN 0 +#define HD_2_CHAN 1 +#define HD_3_CHAN 2 +#define HD_4_CHAN 3 +#define HD_8_BIT 0 +#define HD_16_BIT 1 +#define HD_20_BIT 2 +#define HD_24_BIT 3 +#define HD_32_BIT 4 +#define HD_48kHz 0 +#define HD_DFT_OUT_FMT(HD_2_CHAN + HD_24_BIT << 4 + HD_48kHz << 8) +#define HD_DFT_IN_FMT(HD_2_CHAN + HD_16_BIT << 4 + HD_48kHz << 8) +#define HD_POS_BUF_MULTIPLES 0x1000 +#define HD_CORB_ENTRIES 256 +#define HD_RIRB_ENTRIES 256 +#define HD_BDL_ENTRIES 256 +#define HD_GCTL 0x08 +#define HD_STATESTS 0x0E +#define HD_GSTS 0x10 +#define HD_CORBLBASE 0x40 +#define HD_CORBUBASE 0x44 +#define HD_CORBWP 0x48 +#define HD_CORBRP 0x4A +#define HD_CORBCTL 0x4C +#define HD_CORBST 0x4D +#define HD_RIRBLBASE 0x50 +#define HD_RIRBUBASE 0x54 +#define HD_RIRBWP 0x58 +#define HD_RIRBCTL 0x5C +#define HD_RIRBSTS 0x5D +#define STRCTL 0x00 +#define STRSTS 0x03 +#define STRLPIB 0x04 +#define STRCBL 0x08 +#define STRLVI 0x0C +#define STRFIFOW 0x0E +#define STRFIFOS 0x10 +#define STRFMT 0x12 +#define STRBDPL 0x18 +#define STRBDPU 0x1C +#define ISTR0 0x080 +#define ISTR1 0x0A0 +#define ISTR2 0x0C0 +#define ISTR3 0x0E0 +#define OSTR0 0x100 +#define OSTR1 0x120 +#define OSTR2 0x140 +#define OSTR3 0x160 +#define VERB_GET_PARAM 0xF0000 +#define VERB_CONNECT_SEL_GET 0xF0100 +#define VERB_CONNECT_SEL_SET 0x70100 +#define VERB_GET_CONNECT_LST 0xF0200 +#define VERB_PROCESS_STATE_GET 0xF0300 +#define VERB_PROCESS_STATE_SET 0x70300 +#define VERB_COEFF_IDX_GET 0xD0000 +#define VERB_COEFF_IDX_SET 0x50000 +#define VERB_PROCESS_COEFF_GET 0xC0000 +#define VERB_PROCESS_COEFF_SET 0x40000 +#define VERB_AMPLIFIER_GAIN_GET 0xB0000 +#define VERB_AMPLIFIER_GAIN_SET 0x30000 +#define VERB_STREAM_FMT_GET 0xA0000 +#define VERB_STREAM_FMT_SET 0x20000 +#define VERB_DIGIT_CONVERT1_GET 0xF0D00 +#define VERB_DIGIT_CONVERT1_SET 0x70D00 +#define VERB_DIGIT_CONVERT2_GET 0xF0D00 +#define VERB_DIGIT_CONVERT2_SET 0x70E00 +#define VERB_POWER_STATE_GET 0xF0500 +#define VERB_POWER_STATE_SET 0x70500 +#define VERB_CHAN_STREAM_ID_GET 0xF0600 +#define VERB_CHAN_STREAM_ID_SET 0x70600 +#define VERB_SDI_SEL_GET 0xF0400 +#define VERB_SDI_SEL_SET 0x70400 +#define VERB_PIN_WIDGET_CTL_GET 0xF0700 +#define VERB_PIN_WIDGET_CTL_SET 0x70700 +#define VERB_UNSOL_ENABLE_GET 0xF0800 +#define VERB_UNSOL_ENABLE_SET 0x70800 +#define VERB_PIN_SENSE_GET 0xF0900 +#define VERB_PIN_SENSE_SET 0x70900 +#define VERB_EAPDBTL_ENABLE_GET 0xF0C00 +#define VERB_EAPDBTL_ENABLE_SET 0x70C00 +#define VERB_BEEP_CTL_GET 0xF0A00 +#define VERB_BEEP_CTL_SET 0x70A00 +#define VERB_GPI_CTRL0_GET 0xF1000 +#define VERB_GPI_CTRL0_SET 0x71000 +#define VERB_GPI_CTRL1_GET 0xF1100 +#define VERB_GPI_CTRL1_SET 0x71100 +#define VERB_GPI_CTRL2_GET 0xF1200 +#define VERB_GPI_CTRL2_SET 0x71200 +#define VERB_GPI_CTRL3_GET 0xF1300 +#define VERB_GPI_CTRL3_SET 0x71300 +#define VERB_GPI_CTRL4_GET 0xF1400 +#define VERB_GPI_CTRL4_SET 0x71400 +#define VERB_GPI_CTRL5_GET 0xF1500 +#define VERB_GPI_CTRL5_SET 0x71500 +#define VERB_GPI_CTRL6_GET 0xF1600 +#define VERB_GPI_CTRL6_SET 0x71600 +#define VERB_GPI_CTRL7_GET 0xF1700 +#define VERB_GPI_CTRL7_SET 0x71700 +#define VERB_GPI_CTRL8_GET 0xF1800 +#define VERB_GPI_CTRL8_SET 0x71800 +#define VERB_GPI_CTRL9_GET 0xF1900 +#define VERB_GPI_CTRL9_SET 0x71900 +#define VERB_GPI_CTRLA_GET 0xF1A00 +#define VERB_GPI_CTRLA_SET 0x71A00 +#define VERB_VOL_CTL_GET 0xF0F00 +#define VERB_VOL_CTL_SET 0x70F00 +#define VERB_SUB_SYS_ID0_GET 0xF2000 +#define VERB_SUB_SYS_ID0_SET 0x72000 +#define VERB_SUB_SYS_ID1_GET 0xF2000 +#define VERB_SUB_SYS_ID1_SET 0x72100 +#define VERB_SUB_SYS_ID2_GET 0xF2000 +#define VERB_SUB_SYS_ID2_SET 0x72200 +#define VERB_SUB_SYS_ID3_GET 0xF2000 +#define VERB_SUB_SYS_ID3_SET 0x72300 +#define VERB_CFG_DFT0_GET 0xF1C00 +#define VERB_CFG_DFT0_SET 0x71C00 +#define VERB_CFG_DFT1_GET 0xF1C00 +#define VERB_CFG_DFT1_SET 0x71D00 +#define VERB_CFG_DFT2_GET 0xF1C00 +#define VERB_CFG_DFT2_SET 0x71E00 +#define VERB_CFG_DFT3_GET 0xF1C00 +#define VERB_CFG_DFT3_SET 0x71F00 +#define VERB_STRIPE_CTL_GET 0xF2400 +#define VERB_STRIPE_CTL_SET 0x72400 +#define VERB_RST 0x7FF00 + +//Parameters +#define P_VENDOR_ID 0x00 +#define P_REVISION_ID 0x02 +#define P_SUBNODE_CNT 0x04 +#define P_FUN_GRP_TYPE 0x05 +#define P_AUDIO_FUN_CAP 0x08 +#define P_AUDIO_WIDGET_CAP 0x09 +#define P_SAMPLE_SIZE_RATE_CAP 0x0A +#define P_STREAM_FMTS 0x0B +#define P_PIN_CAP 0x0C +#define P_INPUT_AMP_CAP 0x0D +#define P_OUTPUT_AMP_CAP 0x12 +#define P_CONNECT_LST_LEN 0x0E +#define P_POWER_STATES 0x0F +#define P_PROCESSING_CAP 0x10 +#define P_GPIO_CNT 0x11 +#define P_VOL_KNOB_CAP 0x13 + +//Function Group Types +//00 reserved +#define FGT_AUDIO 1 +#define FGT_VENDOR_MODEM 2 +//03-7F reserved +//80-FF vendor function group + +//Audio Widget Types +#define AWT_OUTPUT 0x0 +#define AWT_INPUT 0x1 +#define AWT_MIXER 0x2 +#define AWT_SELECTOR 0x3 +#define AWT_PIN_COMPLEX 0x4 +#define AWT_POWER_WIDGET 0x5 +#define AWT_VOL_KNOB_WIDGET 0x6 +#define AWT_BEEP_GEN_WIDGET 0x7 +#define AWT_VENDOR 0xF +#define AWT_NODE 0x10 +DefineListLoad("ST_AUDIO_WIDGET_TYPES", + "Output\0Input\0Mixer\0Sellector\0Pin Complex\0" + "Power Widget\0Vol Knob\0Beep Gen\0\0\0\0\0\0\0\0Vendor\0Node\0"); + +class CHDBufDesc +{ + I32 * buf; + U32 len; + U32 ctrl; +}; + +#define HD_TONES 8 + +class CHDAudioCtrl +{ + U8 * bar; + CBlkPool * bp; + CHeapCtrl * hc; + I64 cad; + U32 * corb; + I64 * rirb; + CHDBufDesc *ostr0_bdl, *istr0_bdl; + SND_OUT_CONTAINER *ostr0_buf[2], *o_tmp_buf; + SND_IN_CONTAINER *istr0_buf[2]; + CTask * task; + I64 waveform; + F64 freq, amp; + CSndWaveCtrl *tone_swcs[HD_TONES]; + U8 rirb_rp, corb_wp; + Bool audio_task_started, in_running, out_running; +} + +hda; +MemSet(&hda, 0, sizeof(CHDAudioCtrl)); + +U0 HDSyncCORB() +{ + U16 *wp, *rp; + wp = hda.bar + HD_CORBWP; + *wp = hda.corb_wp; + rp = hda.bar + HD_CORBRP; + while (*rp &255 != hda.corb_wp) + Yield; +} + +U0 HDWriteCORB(I64 cad, I64 nid, U32 val) +{ + val |= cad << 28 + nid << 20; + hda.corb[++hda.corb_wp] = val; +} + +I64 HDSyncRIRB() +{ + U16 * _w; + I64 wp, res = 0; + _w = hda.bar + HD_RIRBWP; + wp = *_w; + while (hda.rirb_rp != wp) + res = hda.rirb[++hda.rirb_rp]; + return res; +} + +I64 HDReadRIRB() +{ + U16 * _w; + I64 wp, res = 0; + _w = hda.bar + HD_RIRBWP; + do { + Yield; + wp = *_w; + } while (wp == hda.rirb_rp); + res = hda.rirb[++hda.rirb_rp]; + return res; +} + +I64 HDWriteCORBSync(I64 cad, I64 nid, U32 val) +{ + HDSyncCORB; + HDSyncRIRB; + HDWriteCORB(cad, nid, val); + HDSyncCORB; + return HDReadRIRB; +} + +Bool HDTestCORBSync(I64 cad, I64 nid, U32 val) +{ + //Checks for a response + U16 * _w; + I64 wp; + + HDSyncCORB; + HDSyncRIRB; + HDWriteCORB(cad, nid, val); + HDSyncCORB; + + Sleep(1); + _w = hda.bar + HD_RIRBWP; + wp = *_w; + if (wp == hda.rirb_rp) + return FALSE; + HDReadRIRB; + return TRUE; +} + +U0 HDTraverse(I64 cad, I64 nid) +{ + I64 i, len, aud_cap, type; + HDWriteCORBSync(cad, nid, VERB_POWER_STATE_SET + 0x00); //0 is on + HDWriteCORBSync(cad, nid, VERB_EAPDBTL_ENABLE_SET + 0x02); + HDWriteCORBSync(cad, nid, VERB_PROCESS_STATE_SET + 0x02); + HDWriteCORBSync(cad, nid, VERB_CONNECT_SEL_SET + 0x00); + aud_cap = HDWriteCORBSync(cad, nid, VERB_GET_PARAM + P_SUBNODE_CNT); + if (aud_cap.u16[0]) + { + for (i = aud_cap.u16[1]; i < aud_cap.u16[1] + aud_cap.u16[0]; i++) + HDTraverse(cad, i); + } + else + { + aud_cap = HDWriteCORBSync(cad, nid, VERB_GET_PARAM + P_AUDIO_WIDGET_CAP); + type = aud_cap >> 20 &15; + if (Bt(&aud_cap, 8)) + len = HDWriteCORBSync(cad, nid, VERB_GET_PARAM + P_CONNECT_LST_LEN) &127; + else + len = 0; + HDWriteCORBSync(cad, nid, VERB_AMPLIFIER_GAIN_SET + 0xF07F); //set I/O amp #0 + for (i = 1; i < len; i++) + //Set IN amps to mute + HDWriteCORBSync(cad, nid, VERB_AMPLIFIER_GAIN_SET + 0x7080 + i << 8); + switch (type) + { + case AWT_OUTPUT: + if (FALSE) //if disabled + HDWriteCORBSync(cad, nid, VERB_CHAN_STREAM_ID_SET + 0x00); + else + HDWriteCORBSync(cad, nid, VERB_CHAN_STREAM_ID_SET + 0x10); + HDWriteCORBSync(cad, nid, VERB_STREAM_FMT_SET + HD_DFT_OUT_FMT); + HDWriteCORBSync(cad, nid, VERB_PROCESS_STATE_SET + 0x01); + break; + case AWT_INPUT: + if (TRUE) //if disabled + HDWriteCORBSync(cad, nid, VERB_CHAN_STREAM_ID_SET + 0x00); + else + HDWriteCORBSync(cad, nid, VERB_CHAN_STREAM_ID_SET + 0x20); + HDWriteCORBSync(cad, nid, VERB_STREAM_FMT_SET + HD_DFT_IN_FMT); + HDWriteCORBSync(cad, nid, VERB_PROCESS_STATE_SET + 0x01); + break; + case AWT_PIN_COMPLEX: + HDWriteCORBSync(cad, nid, VERB_PIN_WIDGET_CTL_SET + 0xE2); + break; + } + } +} + +U0 HDRun(Bool in, Bool out) +{ + U32 * _d; + if (hda.bar) + { + if (out) + { + _d = hda.bar + OSTR0 + STRCTL; + *_d = 0x100002; + hda.out_running = TRUE; + } + + if (in) + { + _d = hda.bar + ISTR0 + STRCTL; + *_d = 0x200002; + hda.in_running = TRUE; + } + } +} + +U0 HDStop(Bool in, Bool out) +{ + U32 * _d; + if (hda.bar) + { + if (out) + { + _d = hda.bar + OSTR0 + STRCTL; + *_d = 0; + hda.out_running = FALSE; + } + + if (in) + { + _d = hda.bar + ISTR0 + STRCTL; + *_d = 0; + hda.in_running = FALSE; + } + } +} + +U0 HDSnd(F64 freq, I64 waveform = WF_SQUARE, F64 amp = 1.0) +{ + hda.waveform = waveform; + hda.amp = amp; + hda.freq = freq; +} + +U0 HDFillBuf(SND_OUT_CONTAINER *buf, I64) +{ + I64 i, size = SND_BUF_LEN* sizeof(SND_OUT_CONTAINER); + if (!hda.o_tmp_buf) + hda.o_tmp_buf = SysMAlloc(size); + MemSet(hda.o_tmp_buf, 0, size); + for (i = 0; i < HD_TONES; i++) + SndWaveAddBuf(hda.tone_swcs[i], hda.o_tmp_buf, + SND_BUF_LEN / SND_OCHANNELS, hda.freq, + hda.waveform, snd_vol *hda.amp); + MemCopy(buf, hda.o_tmp_buf, size); +} + +U0 HDAudioTaskEndCB() +{ + I64 i; + HDStop(FALSE, TRUE); + fp_snd = NULL; + for (i = 0; i < HD_TONES; i++) + { + SndWaveCtrlDel(hda.tone_swcs[i]); + hda.tone_swcs[i] = NULL; + } + + Exit; +} + +public U0 HDTonesInit() +{ + I64 i; + if (hda.bar) + { + for (i = 0; i < HD_TONES; i++) + { + hda.tone_swcs[i]->freq_multiplier = 1.0; + hda.tone_swcs[i]->amp_multiplier = 0; + } + + hda.tone_swcs[0]->amp_multiplier = 1.0; + } +} + +U0 HDAudioTask(I64) +{ + //I didn't feel like messing around with PCI interrupts + //so this task polls every millisecond to know when to + //switch buffers. + I64 i, next_obuf_trigger = SND_BUF_LEN* sizeof(SND_OUT_CONTAINER) / 2, + obuf_rollover = 0, + next_ibuf_trigger = SND_BUF_LEN* sizeof(SND_IN_CONTAINER), + ibuf_rollover = 0; + U32 *pos_in_obuf = hda.bar + OSTR0 + STRLPIB, + *pos_in_ibuf = hda.bar + ISTR0 + STRLPIB; + Fs->task_end_cb = &HDAudioTaskEndCB; + for (i = 0; i < HD_TONES; i++) + hda.tone_swcs[i] = SndWaveCtrlNew; + HDTonesInit; + hda.freq = 0; + Sound; + fp_snd = &HDSnd; + fp_snd_fill_buf = &HDFillBuf; + fp_snd_copy_buf = NULL; + snd_obuf_num = 1; + snd_ibuf_num = 1; + HDRun(FALSE, TRUE); + hda.audio_task_started = TRUE; //This flag is probably not necessary + while (TRUE) + { + if (next_obuf_trigger - obuf_rollover <= *pos_in_obuf< next_obuf_trigger - obuf_rollover + + (HD_POS_BUF_MULTIPLES - 1) *SND_BUF_LEN* sizeof(SND_OUT_CONTAINER)) + { + next_obuf_trigger += SND_BUF_LEN* sizeof(SND_OUT_CONTAINER); + if (next_obuf_trigger - obuf_rollover >= + HD_POS_BUF_MULTIPLES *SND_BUF_LEN* sizeof(SND_OUT_CONTAINER)) + obuf_rollover += HD_POS_BUF_MULTIPLES *SND_BUF_LEN * + sizeof(SND_OUT_CONTAINER); + if (fp_snd_fill_buf) + { + LBts(&snd_flags, Sf_FILLING_OUT); + (*fp_snd_fill_buf)(hda.ostr0_buf[snd_obuf_num & 1], snd_obuf_num); + if (IsMute) + MemSet(hda.ostr0_buf[snd_obuf_num & 1], 0, + SND_BUF_LEN* sizeof(SND_OUT_CONTAINER)); + LBtr(&snd_flags, Sf_FILLING_OUT); + } + + snd_obuf_num++; + } + + if (next_ibuf_trigger - ibuf_rollover <= *pos_in_ibuf< next_ibuf_trigger - ibuf_rollover + (HD_POS_BUF_MULTIPLES - 1) * + SND_BUF_LEN* sizeof(SND_IN_CONTAINER)) + { + next_ibuf_trigger += SND_BUF_LEN* sizeof(SND_IN_CONTAINER); + if (next_ibuf_trigger - ibuf_rollover >= + HD_POS_BUF_MULTIPLES *SND_BUF_LEN* sizeof(SND_IN_CONTAINER)) + ibuf_rollover += HD_POS_BUF_MULTIPLES *SND_BUF_LEN * + sizeof(SND_IN_CONTAINER); + if (fp_snd_copy_buf) + (*fp_snd_copy_buf)(hda.istr0_buf[snd_obuf_num & 1], snd_ibuf_num); + snd_ibuf_num++; + } + + Sleep(1); + } +} + +U0 HDRst() +{ + U32 d, *_d; + HDStop(TRUE, TRUE); + _d = hda.bar + HD_GCTL; + *_d = 0; //rst + do { + Sleep(1); + d = *_d; + } while (d & 1); + *_d = 1; + do { + Sleep(1); + d = *_d; + } while (!(d & 1)); + Sleep(1); +} + +public U0 HDAudioEnd(Bool rst = TRUE) +{ + snd_dev = SD_PC_SPEAKER; + if (hda.bar) + { + Kill(hda.task); + hda.task = NULL; + if (rst) + HDRst; + Free(hda.corb); + Free(hda.rirb); + Free(hda.o_tmp_buf); + Free(hda.ostr0_buf[0]); + Free(hda.ostr0_buf[1]); + Free(hda.istr0_buf[0]); + Free(hda.istr0_buf[1]); + Free(hda.ostr0_bdl); + Free(hda.istr0_bdl); + Mem32DevFree(hda.bar); + hda.bar = NULL; + } +} + +U0 HDAudioUncachedInit() +{ + I64 shared_blks = 1; + hda.bp = Mem2MegUncachedAlloc(&shared_blks); + hda.hc = HeapCtrlBPInit(hda.bp, shared_blks << 12); +} + +public Bool HDAudioInit(I64 hd_bus, I64 hd_dev, I64 hd_fun) +{ + I64 i; + U32 * _d; + U16 w, *_w; + U8 * _b; + if (hda.bar) + HDAudioEnd; + else + HDAudioUncachedInit; + if (PCIReadU16(hd_bus, hd_dev, hd_fun, 0) == 0x8086 && + (hda.bar = PCIReadU32(hd_bus, hd_dev, hd_fun, 0x10) &~(0x1F))) + { + PCIWriteU16(hd_bus, hd_dev, hd_fun, 0x04, + PCIReadU16(hd_bus, hd_dev, hd_fun, 0x04) | 0x406); + + HDRst; + + hda.corb = CAllocAligned(HD_CORB_ENTRIES* sizeof(U32), 128, hda.hc); + _d = hda.bar + HD_CORBLBASE; + *_d = hda.corb(I64).u32[0]; + _d = hda.bar + HD_CORBUBASE; + *_d = hda.corb(I64).u32[1]; + + hda.rirb = CAllocAligned(HD_RIRB_ENTRIES* sizeof(I64), 128, hda.hc); + _d = hda.bar + HD_RIRBLBASE; + *_d = hda.rirb(I64).u32[0]; + _d = hda.bar + HD_RIRBUBASE; + *_d = hda.rirb(I64).u32[1]; + + _w = hda.bar + HD_CORBRP; + *_w = 0x8000; //Rst read ptr + do { Yield; + w = *_w; + } while (!(w & 0x8000)); + *_w = 0x0000; //Rst read ptr + do { Yield; + w = *_w; + } while (w & 0x8000); + + _w = hda.bar + HD_RIRBWP; + *_w = 0x8000; //Rst write ptr + + _b = hda.bar + HD_CORBCTL; + *_b = 0x02; //Run + _b = hda.bar + HD_RIRBCTL; + *_b = 0x02; //Run + + _w = hda.bar + HD_CORBWP; + hda.corb_wp = *_w; + _w = hda.bar + HD_RIRBWP; + hda.rirb_rp = *_w; + + hda.ostr0_bdl = CAllocAligned( HD_BDL_ENTRIES* sizeof(CHDBufDesc), 128, hda.hc); + _d = hda.bar + OSTR0 + STRBDPL; + *_d = hda.ostr0_bdl(I64).u32[0]; + _d = hda.bar + OSTR0 + STRBDPU; + *_d = hda.ostr0_bdl(I64).u32[1]; + for (i = 0; i < 2; i++) + { + hda.ostr0_bdl[i].buf = hda.ostr0_buf[i] = + CAllocAligned( SND_BUF_LEN* sizeof(SND_OUT_CONTAINER), 128, hda.hc); + hda.ostr0_bdl[i].len = SND_BUF_LEN* sizeof(SND_OUT_CONTAINER); + hda.ostr0_bdl[i].ctrl = 1; + } + + hda.istr0_bdl = CAllocAligned( HD_BDL_ENTRIES* sizeof(CHDBufDesc), 128, hda.hc); + _d = hda.bar + ISTR0 + STRBDPL; + *_d = hda.istr0_bdl(I64).u32[0]; + _d = hda.bar + ISTR0 + STRBDPU; + *_d = hda.istr0_bdl(I64).u32[1]; + for (i = 0; i < 2; i++) + { + hda.istr0_bdl[i].buf = hda.istr0_buf[i] = CAllocAligned( SND_BUF_LEN* sizeof(SND_IN_CONTAINER), 128, hda.hc); + hda.istr0_bdl[i].len = SND_BUF_LEN* sizeof(SND_IN_CONTAINER); + hda.istr0_bdl[i].ctrl = 1; + } + + _w = hda.bar + HD_STATESTS; + w = *_w; + while (w) + { + hda.cad = Bsf(w); + if (HDTestCORBSync(hda.cad, 0, VERB_GET_PARAM + P_SUBNODE_CNT)) + { + HDTraverse(hda.cad, 0); + + _d = hda.bar + OSTR0 + STRLPIB; + *_d = 0; + _d = hda.bar + OSTR0 + STRCBL; + *_d = HD_POS_BUF_MULTIPLES *SND_BUF_LEN* sizeof(SND_OUT_CONTAINER); + _w = hda.bar + OSTR0 + STRLVI; + *_w = 1; //last valid idx + _w = hda.bar + OSTR0 + STRFMT; + *_w = HD_DFT_OUT_FMT; + + _d = hda.bar + ISTR0 + STRLPIB; + *_d = 0; + _d = hda.bar + ISTR0 + STRCBL; + *_d = HD_POS_BUF_MULTIPLES *SND_BUF_LEN* sizeof(SND_IN_CONTAINER); + _w = hda.bar + ISTR0 + STRLVI; + *_w = 1; //last valid idx + _w = hda.bar + ISTR0 + STRFMT; + *_w = HD_DFT_IN_FMT; + + LBts(&sys_semas[SEMA_SOUND], 0); //turn off until cfg completed + LBtr(&snd_flags, Sf_FILLING_OUT); + hda.audio_task_started = FALSE; + if (mp_count > 1) + hda.task = Spawn(&HDAudioTask, NULL, "HD Audio", 3); + else + hda.task = Spawn(&HDAudioTask, NULL, "HD Audio"); + while (!hda.audio_task_started) + Yield; + snd_dev = SD_HD_AUDIO; + return TRUE; + } + + Btr(&w, hda.cad); + } + + HDAudioEnd(FALSE); + } + else + hda.bar = NULL; + return FALSE; +} + +Bool HDAudioScan() +{ + I64 i = -1, j; + while (TRUE) + { + j = PCIClassFind(0x040300, ++i); + if (j < 0) + return FALSE; + + if (HDAudioInit(j.u8[2], j.u8[1], j.u8[0])) + return TRUE; + } +} + +HDAudioScan; + +# +help_index "" \ No newline at end of file diff --git a/src/Home/Sound/HDAudio1/Sup1HDAudio/HDCfg.ZC b/src/Home/Sound/HDAudio1/Sup1HDAudio/HDCfg.ZC new file mode 100644 index 000000000..0121d4494 --- /dev/null +++ b/src/Home/Sound/HDAudio1/Sup1HDAudio/HDCfg.ZC @@ -0,0 +1,720 @@ + +#define CONNECTS_NUM 16 + +class MyMass: CMass +{ + F64 radius; + U8 nid, type, num_connects, cur_connect; + U32 audio_widget_capabilities; + U8 connect_lst[CONNECTS_NUM]; + U8 gain_lst[CONNECTS_NUM]; + U32 pin_capabilities, pin_sense, + pcm_size_rates, + in_amp_cap, out_amp_cap; + U8 pin_widget_ctl; + Bool disabled; +}; + +class MySpring: CSpring +{ + I64 color; +}; + +CMathODE *ode = NULL; + +#define BORDER 10 + +U0 DrawIt(CTask *task, CDC *dc) +{ + Bool old_suspend; + I16 * buf; + I64 i, cxx, cyy, + cy = task->pix_height >> 1; + F64 dx, dy, d; + MyMass * tmpm; + MySpring * tmps; + + old_suspend = Suspend(task); + tmps = ode->next_spring; + while (tmps != &ode->next_spring) + { + dc->color = tmps->color; + GrLine(dc, tmps->end1->x, tmps->end1->y, + tmps->end2->x, tmps->end2->y); + cxx = (tmps->end1->x + tmps->end2->x) / 2; + cyy = (tmps->end1->y + tmps->end2->y) / 2; + dx = tmps->end1->x - tmps->end2->x; + dy = tmps->end1->y - tmps->end2->y; + d = Sqrt(dx *dx + dy *dy); + dx /= d; + dy /= d; + GrLine(dc, cxx, cyy, cxx + 3.0 *dy - 3.0 *dx, cyy - 3.0 *dx - 3.0 *dy); + GrLine(dc, cxx, cyy, cxx - 3.0 *dy - 3.0 *dx, cyy + 3.0 *dx - 3.0 *dy); + tmps = tmps->next; + } + + tmpm = ode->next_mass; + while (tmpm != &ode->next_mass) + { + if (tmpm->disabled) + dc->color = BLUE; + else + dc->color = LTBLUE; + GrCircle(dc, tmpm->x, tmpm->y, tmpm->radius); + GrPrint(dc, tmpm->x, tmpm->y - FONT_HEIGHT / 2, "%02X%3tZ", + tmpm->nid, tmpm->type, + "ST_AUDIO_WIDGET_TYPES"); + tmpm = tmpm->next; + } + + Suspend(task, old_suspend); + dc->color = BLUE; + buf = hda.istr0_buf[0]; + for (i = 0; i < SND_BUF_LEN; i++) + GrPlot(dc, i *task->pix_width / SND_BUF_LEN, + cy - buf[i] *cy / I16_MAX); +} + +U0 MyDerivative(CMathODE *ode, F64, COrder2D3 *, COrder2D3 *) +{ + //The forces due to springs and drag are + //automatically handled by the + //ode code.We can add new forces + //here. + CTask *task = ode->win_task; + I64 h = task->pix_width, v = task->pix_height; + F64 d, dd; + CD3 p; + MyMass *tmpm1, *tmpm2; + + tmpm1 = ode->next_mass; + while (tmpm1 != &ode->next_mass) + { + tmpm2 = tmpm1->next; + while (tmpm2 != &ode->next_mass) + { + D3Sub(&p, &tmpm2->state->x, &tmpm1->state->x); + dd = D3NormSqr(&p); + if (dd <= Sqr(tmpm1->radius + tmpm2->radius)) + { + d = Sqrt(dd) + 0.0001; + dd = 10.0* Sqr(Sqr(Sqr(tmpm1->radius + tmpm2->radius) - dd)); + D3MulEqu(&p, dd / d); + D3AddEqu(&tmpm2->DstateDt->DxDt, &p); + D3SubEqu(&tmpm1->DstateDt->DxDt, &p); + } + else + { + D3MulEqu(&p, 100000.0 / dd); + D3AddEqu(&tmpm2->DstateDt->DxDt, &p); + D3SubEqu(&tmpm1->DstateDt->DxDt, &p); + } + + tmpm2 = tmpm2->next; + } + + if (tmpm1->state->x < BORDER) + tmpm1->DstateDt->DxDt += 1000* Sqr(tmpm1->state->x - BORDER); + if (tmpm1->state->y < BORDER) + tmpm1->DstateDt->DyDt += 1000* Sqr(tmpm1->state->y - BORDER); + if (tmpm1->state->x > h - BORDER - FONT_WIDTH *6) + tmpm1->DstateDt->DxDt -= 1000 * + Sqr(tmpm1->state->x - (h - BORDER - FONT_WIDTH *6)); + if (tmpm1->state->y > v - BORDER) + tmpm1->DstateDt->DyDt -= 1000* Sqr(tmpm1->state->y - (v - BORDER)); + tmpm1 = tmpm1->next; + } +} + +MyMass* PlaceMass(I64 nid) +{ + MyMass *tmpm = CAlloc(sizeof(MyMass)); + tmpm->mass = 1.0; + tmpm->drag_profile_factor = 100.0; + tmpm->radius = 5; + tmpm->nid = nid; + tmpm->gain_lst[0] = 0x7F; + MemSet(tmpm->gain_lst + 1, 0x80, (CONNECTS_NUM - 1) *sizeof(U8)); + QueueInsert(tmpm, ode->last_mass); + return tmpm; +} + +MyMass* FindMassByNID(I64 nid) +{ + MyMass * tmpm; + tmpm = ode->next_mass; + while (tmpm != &ode->next_mass) + { + if (tmpm->nid == nid) + return tmpm; + tmpm = tmpm->next; + } + + return NULL; +} + +MyMass* FindMassByXY(I64 x, I64 y) +{ + I64 dd, best_dd = I64_MAX; + MyMass *tmpm, *res = NULL; + tmpm = ode->next_mass; + while (tmpm != &ode->next_mass) + { + dd = SqrI64(tmpm->x - x) + SqrI64(tmpm->y - y); + if (dd < best_dd) + { + res = tmpm; + best_dd = dd; + } + + tmpm = tmpm->next; + } + + return res; +} + +I64 FindConnectIndex(MyMass *tmpm, I64 nid) +{ + I64 i; + for (i = 0; i < tmpm->num_connects; i++) + if (tmpm->connect_lst[i] == nid) + return i; + return -1; +} + +MySpring* PlaceSpring(MyMass *tmpm1, MyMass *tmpm2) +{ + MySpring *tmps = CAlloc(sizeof(MySpring)); + tmps->end1 = tmpm1; + tmps->end2 = tmpm2; + tmps->const = 10; + tmps->rest_len = 0; + tmps->color = LTGRAY; + QueueInsert(tmps, ode->last_spring); + return tmps; +} + +U0 RedoSprings() +{ + I64 i, k; + MyMass *tmpm, *tmpm1; + MySpring * tmps; + + QueueDel(&ode->next_spring, TRUE); + tmpm = ode->next_mass; + while (tmpm != &ode->next_mass) + { + for (i = 0; i < tmpm->num_connects; i++) + { + if ((k = tmpm->connect_lst[i]) && + (tmpm1 = FindMassByNID(k))) + { + tmps = PlaceSpring(tmpm, tmpm1); + switch (tmpm->type) + { + case AWT_MIXER: + if (!(tmpm->gain_lst[i] &0x80)) + { + //If not mute + tmps->color = GREEN; + tmps->const = 100; + } + + break; + case AWT_INPUT: + case AWT_SELECTOR: + case AWT_PIN_COMPLEX: + case AWT_VENDOR: + if (i == tmpm->cur_connect) + { + tmps->color = RED; + tmps->const = 100; + } + + break; + } + } + } + + tmpm = tmpm->next; + } +} + +U0 Init() +{ + ode = ODENew(0, 1e-4, ODEF_HAS_MASSES); + ode->derive = &MyDerivative; + ode->drag_v2 = 0.002; + ode->drag_v3 = 0.00001; + ode->acceleration_limit = 5e3; + + QueueInsert(ode, Fs->last_ode); +} + +U0 CleanUp() +{ + QueueRemove(ode); + QueueDel(&ode->next_mass, TRUE); + QueueDel(&ode->next_spring, TRUE); + ODEDel(ode); +} + +U0 HDCfgConnectLst(MyMass *tmpm, I64 cad, I64 nid) +{ + I64 i, j, connection_lst_len; + j = HDWriteCORBSync(cad, nid, VERB_GET_PARAM + P_CONNECT_LST_LEN); + connection_lst_len = j &127; + if (j & 128) + { + //Long form? + for (i = 0; i < connection_lst_len; i += 2) + { + j = HDWriteCORBSync(cad, nid, VERB_GET_CONNECT_LST + i); + tmpm->connect_lst[tmpm->num_connects++] = j.u16[0]; + if (i + 1 < connection_lst_len) + tmpm->connect_lst[tmpm->num_connects++] = j.u16[1]; + } + } + else + { + for (i = 0; i < connection_lst_len; i += 4) + { + j = HDWriteCORBSync(cad, nid, VERB_GET_CONNECT_LST + i); + tmpm->connect_lst[tmpm->num_connects++] = j.u8[0]; + if (i + 1 < connection_lst_len) + tmpm->connect_lst[tmpm->num_connects++] = j.u8[1]; + if (i + 2 < connection_lst_len) + tmpm->connect_lst[tmpm->num_connects++] = j.u8[2]; + if (i + 3 < connection_lst_len) + tmpm->connect_lst[tmpm->num_connects++] = j.u8[3]; + } + } +} + +U0 HDCfgTraverse(I64 cad, I64 nid) +{ + I64 i, j; + MyMass *tmpm = PlaceMass(nid); + j = HDWriteCORBSync(cad, nid, VERB_GET_PARAM + P_SUBNODE_CNT); + if (j.u16[0]) + { + tmpm->type = AWT_NODE; + for (i = j.u16[1]; i < j.u16[1] + j.u16[0]; i++) + HDCfgTraverse(cad, i); + } + else + { + tmpm->audio_widget_capabilities = + HDWriteCORBSync(cad, nid, VERB_GET_PARAM + P_AUDIO_WIDGET_CAP); + tmpm->pcm_size_rates = + HDWriteCORBSync(cad, nid, VERB_GET_PARAM + P_SAMPLE_SIZE_RATE_CAP); + tmpm->in_amp_cap = HDWriteCORBSync(cad, nid, VERB_GET_PARAM + P_INPUT_AMP_CAP); + tmpm->out_amp_cap = HDWriteCORBSync(cad, nid, VERB_GET_PARAM + P_OUTPUT_AMP_CAP); + tmpm->type = tmpm->audio_widget_capabilities >> 20 &15; + switch (tmpm->type) + { + case AWT_PIN_COMPLEX: + tmpm->pin_widget_ctl = + HDWriteCORBSync(cad, nid, VERB_PIN_WIDGET_CTL_GET); + tmpm->pin_capabilities = + HDWriteCORBSync(cad, nid, VERB_GET_PARAM + P_PIN_CAP); + if (Bt(&tmpm->pin_capabilities, 0) || + Bt(&tmpm->pin_capabilities, 2)) + tmpm->pin_sense = HDWriteCORBSync(cad, nid, VERB_PIN_SENSE_GET); + HDWriteCORBSync(cad, nid, VERB_CONNECT_SEL_SET + 0x00); + break; + case AWT_INPUT: + tmpm->disabled = TRUE; + case AWT_SELECTOR: + case AWT_VENDOR: + HDWriteCORBSync(cad, nid, VERB_CONNECT_SEL_SET + 0x00); + break; + } + + if (Bt(&tmpm->audio_widget_capabilities, 8)) + HDCfgConnectLst(tmpm, cad, nid); + } +} + +U0 HDCfgRandomizeXY() +{ + I64 h = Fs->pix_width, v = Fs->pix_height; + MyMass * tmpm; + tmpm = ode->next_mass; + while (tmpm != &ode->next_mass) + { + tmpm->x = RandU32 % (h - 2 *BORDER - FONT_WIDTH *6) + BORDER; + tmpm->y = RandU32 % (v - 2 *BORDER) + BORDER; + tmpm = tmpm->next; + } +} + +U0 HDCfgPopUpInfoTask(MyMass *tmpm) +{ + I64 i; + "$$FG,RED$$NID:$$FG$$0x%02X$$FG,RED$$Type:$$FG$$%Z\n", + tmpm->nid, tmpm->type, "ST_AUDIO_WIDGET_TYPES"; + + i = tmpm->audio_widget_capabilities; + "\n$$FG,RED$$Audio Widget Capabilities:$$FG$$\n"; + if (Bt(&i, 0)) + "Stereo,"; + if (Bt(&i, 1)) + "In Amp,"; + if (Bt(&i, 2)) + "Out Amp,"; + if (Bt(&i, 3)) + "AmpOverride,"; + if (Bt(&i, 4)) + "FmtOverride,"; + if (Bt(&i, 5)) + "Stripe,"; + if (Bt(&i, 6)) + "Proc Wgt,"; + if (Bt(&i, 7)) + "Unsolicited,"; + if (Bt(&i, 8)) + "Cnt Lst,"; + if (Bt(&i, 9)) + "Digital,"; + if (Bt(&i, 10)) + "Power Ctrl,"; + if (Bt(&i, 11)) + "Left/Right Swap,"; + "Delay:%d\n", i.u16[1] &0xF; + + i = tmpm->in_amp_cap; + "\n$$FG,RED$$Input Amp Capabilities:$$FG$$\n" + "Offset:0x%02X Steps:0x%02X StepSize:%5.2fdB Mutable:%d\n", + i &127, i.u8[1] &127 + 1, 0.25 *(i.u16[1] &127), Bt(&i, 31); + + i = tmpm->out_amp_cap; + "\n$$FG,RED$$Output Amp Capabilities:$$FG$$\n" + "Offset:0x%02X Steps:0x%02X StepSize:%5.2fdB Mutable:%d\n", + i &127, i.u8[1] &127 + 1, 0.25 *(i.u16[1] &127), Bt(&i, 31); + + "\n$$FG,RED$$Size Rates Capabilities:$$FG$$\n"; + for (i = 0; i < 21; i++) + if (Bt(&tmpm->pcm_size_rates, i)) + "%z", i, + " 8.0kHz\0 11.025kHz\0 16.0kHz\0 22.05kHz\0" + " 32.0kHz\0 44.1kHz\0 48.0kHz\0 88.2kHz\0" + " 96.0kHz\0 176.4kHz\0 192.0kHz\0 384kHz\0" + "\0\0\0\0" + " 8Bit\0 16bit\0 20Bit\0 24Bit\0 32Bit\0"; + '\n'; + + "\n$$FG,RED$$Connection Lst:$$FG$$\n"; + for (i = 0; i < tmpm->num_connects; i++) + "%02X,", tmpm->connect_lst[i]; + '\n'; + + "\n$$FG,RED$$Gain Lst:$$FG$$\n"; + for (i = 0; i < tmpm->num_connects; i++) + "%02X,", tmpm->gain_lst[i]; + '\n'; + + switch (tmpm->type) + { + case AWT_PIN_COMPLEX: + "\n$$FG,RED$$Pin Capabilities:$$FG$$\n"; + i = tmpm->pin_capabilities; + if (Bt(&i, 0)) + "Impedance Sense,"; + if (Bt(&i, 1)) + "Trigger Required,"; + if (Bt(&i, 2)) + "Presence Detect,"; + if (Bt(&i, 3)) + "Headphone Drive,"; + if (Bt(&i, 4)) + "Output,"; + if (Bt(&i, 5)) + "Input,"; + if (Bt(&i, 6)) + "Balanced,"; + if (Bt(&i, 16)) + "EAPD,"; + "Vref:%02X\n\n", i.u8[1]; + if (Bt(&tmpm->pin_capabilities, 0) || + Bt(&tmpm->pin_capabilities, 2)) + tmpm->pin_sense = HDWriteCORBSync(hda.cad, + tmpm->nid, VERB_PIN_SENSE_GET); + if (Bt(&tmpm->pin_capabilities, 0)) + "Impedance Measurement:%08X\n", tmpm->pin_sense &0x7FFFFFFF; + if (Bt(&tmpm->pin_capabilities, 2)) + "Presence:%d\n", Bt(&tmpm->pin_sense, 31); + "\n\nPin widget ctrl bits:\n" + "7: High phn enable (low impedance output amp)\n" + "6: Output Enable\n" + "5: Input Enable\n" + "0-2: Vref 0=HiZ 1=50% 2=Gnd 4=80% 5=100%\n"; + tmpm->pin_widget_ctl = I64Get("Widget Ctrl (0x%02X):", + tmpm->pin_widget_ctl, 0, 0xFF); + HDWriteCORBSync(hda.cad, tmpm->nid, + VERB_PIN_WIDGET_CTL_SET + tmpm->pin_widget_ctl); + break; + case AWT_INPUT: + "Disable"; + if (tmpm->disabled = YorN) + HDWriteCORBSync(hda.cad, tmpm->nid, VERB_CHAN_STREAM_ID_SET + 0x00); + else + HDWriteCORBSync(hda.cad, tmpm->nid, VERB_CHAN_STREAM_ID_SET + 0x20); + '\n'; + break; + case AWT_OUTPUT: + "Disable"; + if (tmpm->disabled = YorN) + HDWriteCORBSync(hda.cad, tmpm->nid, VERB_CHAN_STREAM_ID_SET + 0x00); + else + HDWriteCORBSync(hda.cad, tmpm->nid, VERB_CHAN_STREAM_ID_SET + 0x10); + '\n'; + break; + } +} + +U0 HDCfgPopUpInfo(MyMass *tmpm) +{ + U8 buf[STR_LEN]; + StrPrint(buf, + "HDCfgPopUpInfoTask(0x%X);\"\\n\\nPress SHIFT-ESC\\n\\n\\n\\n\";View;", + tmpm); + Fs->win_inhibit |= WIF_SELF_ODE; + Fs->draw_it = NULL; + Refresh; + PopUp(buf, Fs); + Fs->win_inhibit &= ~WIF_SELF_ODE; + Fs->draw_it = &DrawIt; +} + +U0 HDCfgEdLink(MyMass *tmpm_out, MyMass *tmpm_in) +{ + I64 i, j; + if ((i = FindConnectIndex(tmpm_in, tmpm_out->nid)) >= 0) + { + switch (tmpm_in->type) + { + case AWT_MIXER: + MemSet(tmpm_in->gain_lst, 0x80, sizeof(U8) *CONNECTS_NUM); + tmpm_in->gain_lst[i] = 0x7F; + for (j = 0; j < tmpm_in->num_connects; j++) + HDWriteCORBSync(hda.cad, tmpm_in->nid, + VERB_AMPLIFIER_GAIN_SET + 0x7000 + tmpm_in->gain_lst[j] + j << 8); + break; + case AWT_INPUT: + case AWT_SELECTOR: + case AWT_PIN_COMPLEX: + case AWT_VENDOR: + tmpm_in->cur_connect = i; + HDWriteCORBSync(hda.cad, tmpm_in->nid, VERB_CONNECT_SEL_SET + i); + break; + } + + RedoSprings; + } +} + +U0 HDCfgSave() +{ + CDoc *doc = DocNew; + I64 i; + MyMass * tmpm; + DocPrint(doc, "//This file was generated by " + "$$LK,\"::/TempleOS/Adam/Sound/HDCfg.ZC.Z\"," + "\"FI:::/TempleOS/Adam/Sound/HDCfg.ZC\"$$\n\n" + "U0 MyHDCfg()\n{\n"); + tmpm = ode->next_mass; + while (tmpm != &ode->next_mass) + { + DocPrint(doc, " //0x%02X %Z\n", tmpm->nid, tmpm->type, + "ST_AUDIO_WIDGET_TYPES"); + if (tmpm->num_connects) + { + DocPrint(doc, "//Connection Lst:"); + for (i = 0; i < tmpm->num_connects; i++) + { + if (i == tmpm->cur_connect) + DocPrint(doc, "*"); + DocPrint(doc, "0x%02X ", tmpm->connect_lst[i]); + } + + DocPrint(doc, "\n"); + if (tmpm->type == AWT_MIXER) + { + DocPrint(doc, "//Gain Lst:"); + for (i = 0; i < tmpm->num_connects; i++) + DocPrint(doc, "0x%02X ", tmpm->gain_lst[i]); + DocPrint(doc, "\n"); + } + } + + switch (tmpm->type) + { + case AWT_OUTPUT: + if (tmpm->disabled) + DocPrint(doc, + "HDWriteCORBSync(hda.cad,0x%02X," + "VERB_CHAN_STREAM_ID_SET+0x00);\n", + tmpm->nid); + else + DocPrint(doc, + "HDWriteCORBSync(hda.cad,0x%02X," + "VERB_CHAN_STREAM_ID_SET+0x10);\n", + tmpm->nid); + break; + case AWT_MIXER: + DocPrint(doc, + "HDWriteCORBSync(hda.cad,0x%02X," + "VERB_AMPLIFIER_GAIN_SET+0xB07F);\n", + tmpm->nid); + for (i = 0; i < tmpm->num_connects; i++) + DocPrint(doc, + "HDWriteCORBSync(hda.cad,0x%02X," + "VERB_AMPLIFIER_GAIN_SET+0x%04X);\n", + tmpm->nid, 0x7000 + tmpm->gain_lst[i] + i << 8); + break; + case AWT_INPUT: + if (tmpm->disabled) + DocPrint(doc, + "HDWriteCORBSync(hda.cad,0x%02X," + "VERB_CHAN_STREAM_ID_SET+0x00);\n", + tmpm->nid); + else + DocPrint(doc, + "HDWriteCORBSync(hda.cad,0x%02X," + "VERB_CHAN_STREAM_ID_SET+0x20);\n", + tmpm->nid); + goto here; + case AWT_PIN_COMPLEX: + DocPrint(doc, + "HDWriteCORBSync(hda.cad,0x%02X," + "VERB_PIN_WIDGET_CTL_SET+0x%02X);\n", + tmpm->nid, tmpm->pin_widget_ctl); + case AWT_SELECTOR: + case AWT_VENDOR: + here: + if (tmpm->num_connects > 1) + DocPrint(doc, + "HDWriteCORBSync(hda.cad,0x%02X," + "VERB_CONNECT_SEL_SET+0x%02X);\n", + tmpm->nid, tmpm->cur_connect); + break; + } + + DocPrint(doc, "\n"); + tmpm = tmpm->next; + } + + DocPrint(doc, "LBtr(&sys_semas[SEMA_SND],0);\n" + "}\n\nif (snd_dev==SD_HD_AUDIO)\n" + "MyHDCfg;\n"); + StrCopy(doc->filename.name, "~/HDAudioCfg.ZC.Z"); + DocWrite(doc); + DocDel(doc); +} + +U0 HDCfg() +{ + I64 arg1, arg2; + MyMass *tmpm1 = NULL, *tmpm2 = NULL; + + if (snd_dev != SD_HD_AUDIO) + { + "HD Audio not detected\n"; + return; + } + MenuPush( "File {" + " Abort(,CH_SHIFT_ESC);" + " Exit(,CH_ESC);" + "}" + "Edit {" + " Randomize(,'\n');" + " Options(,CH_SPACE);" + "}" +); + SettingsPush; //See $LK,"SettingsPush",A="MN:SettingsPush"$ + DocBottom; + AutoComplete; + WinBorder; + WinMax; + DocCursor; + DocClear; + Fs->win_inhibit = WIF_SELF_MS_L | WIF_SELF_MS_R | WIG_DBL_CLICK | WIF_SELF_DOC; + Init; + + HDCfgTraverse(hda.cad, 0); + HDCfgRandomizeXY; + RedoSprings; + Fs->draw_it = &DrawIt; + PopUpOk( "This is a tool to cfgure\n" + "HD Audio.It creates $$FG,RED$$~/HDAudioCfg.ZC.Z$$FG$$\n" + "which you should $$FG,GREEN$$ +#include$$FG$$ in your\n" + "$$FG,RED$$~/HomeSnd.ZC.Z$$FG$$ file.\n\n\n" + "Left click to see info and cfgure a widget.\n" + "Right click drag to connect output to input.\n\n" + "You will need to set input and output amplifier\n" + "gains by hand -- edit $$FG,RED$$~/HDAudioCfg.ZC.Z$$FG$$.\n\n" + "The $$FG,BLUE$$BLUE$$FG$$ line in the middle is microphone waveform.\n\n" +); + + HDRun(TRUE, TRUE); //run input output + + try + { + while (TRUE) + { + switch (MessageGet(&arg1, &arg2, + 1 << MESSAGE_MS_L_UP | 1 << MESSAGE_MS_R_DOWN | 1 << MESSAGE_MS_R_UP | 1 << MESSAGE_KEY_DOWN)) + { + case MESSAGE_MS_L_UP: + if (tmpm1 = FindMassByXY(arg1, arg2)) + HDCfgPopUpInfo(tmpm1); + tmpm1 = NULL; + break; + case MESSAGE_MS_R_DOWN: + tmpm1 = FindMassByXY(arg1, arg2); + break; + case MESSAGE_MS_R_UP: + tmpm2 = FindMassByXY(arg1, arg2); + if (tmpm1 && tmpm2) + HDCfgEdLink(tmpm1, tmpm2); + break; + case MESSAGE_KEY_DOWN: + switch (arg1) + { + case CH_SPACE: + if (tmpm1 = FindMassByXY( mouse.pos.x - Fs->pix_left - Fs->scroll_x, + mouse.pos.y - Fs->pix_top - Fs->scroll_y)) + HDCfgPopUpInfo(tmpm1); + tmpm1 = NULL; + break; + case '\n': + HDCfgRandomizeXY; + break; + case CH_ESC: + HDCfgSave; + case CH_SHIFT_ESC: + goto hd_done; + } + + break; + } + } + + hd_done: //Don't goto out of try + MessageGet(,, 1 << MESSAGE_KEY_UP); + } + + catch + Fs->catch_except = TRUE; + SettingsPop; + HDStop(TRUE, FALSE); //stop input + CleanUp; + MenuPop; + "$$BK,1$$Note: +#include \"~/HDAudioCfg\" in your start-up scripts." + "$$BK,0$$\n"; +} + +HDCfg; \ No newline at end of file diff --git a/src/Home/Sound/HDAudio1/Sup1Snd/MakeSnd.ZC b/src/Home/Sound/HDAudio1/Sup1Snd/MakeSnd.ZC new file mode 100644 index 000000000..0db0b214a --- /dev/null +++ b/src/Home/Sound/HDAudio1/Sup1Snd/MakeSnd.ZC @@ -0,0 +1,21 @@ +Cd(__DIR__);; + +#help_index "Sound" +class CSndWaveCtrl +{ + I64 sample_rate,sample_bits,channels; + F64 freq_multiplier,amp_multiplier; + F64 phase,last_y,last_dydt,next_y; +}; + +public U0 SoundTaskEndCB() +{//Will turn-off snd when a task gets killed. + Sound; + Exit; +} + +#include "SndMath" +#include "SndMusic" +#include "SndEffects" +#include "SndFile" +Cd("..");; diff --git a/src/Home/Sound/HDAudio1/Sup1Snd/SndEffects.ZC b/src/Home/Sound/HDAudio1/Sup1Snd/SndEffects.ZC new file mode 100644 index 000000000..a6dee1718 --- /dev/null +++ b/src/Home/Sound/HDAudio1/Sup1Snd/SndEffects.ZC @@ -0,0 +1,80 @@ +#help_index "Sound" + +#define SE_NOISE 0 +#define SE_SWEEP 1 + +class CSoundEffectFrame +{ + I32 type; + I8 ona1,ona2; + F64 duration; +}; + +U0 SoundEffectEndTaskCB() +{ + Free(FramePtr("CSoundEffectFrame")); + music.mute--; + SoundTaskEndCB; +} + +U0 SoundEffectTask(CSoundEffectFrame *ns) +{ + I64 i,ona; + F64 t0=tS,t,timeout=t0+ns->duration; + FramePtrAdd("CSoundEffectFrame",ns); + Fs->task_end_cb=&SoundEffectEndTaskCB; + switch (ns->type) { + case SE_NOISE: + i=MaxI64(ns->ona2-ns->ona1,1); + while (tSona1; + Sound(ona); + t=Clamp(3000.0/Ona2Freq(ona),1.0,50.0); + if (t+tS>timeout) + t=timeout-tS; + Sleep(t); + } + break; + case SE_SWEEP: + while (tSduration; + ona=(1.0-t)*ns->ona1+t*ns->ona2; + Sound(ona); + t=Clamp(3000.0/Ona2Freq(ona),1.0,50.0); + if (t+tS>timeout) + t=timeout-tS; + Sleep(t); + } + break; + } +} + +public CTask *Noise(I64 mS,F64 min_ona,F64 max_ona) +{//Make white noise for given number of mS. + CSoundEffectFrame *ns; + if (mS>0) { + ns=MAlloc(sizeof(CSoundEffectFrame)); + ns->type=SE_NOISE; + ns->duration=mS/1000.0; + ns->ona1=min_ona; + ns->ona2=max_ona; + music.mute++; + return Spawn(&SoundEffectTask,ns,"Noise",,Fs); + } else + return NULL; +} + +public CTask *Sweep(I64 mS,F64 ona1,F64 ona2) +{//Sweep through freq range in given number of mS. + CSoundEffectFrame *ns; + if (mS>0) { + ns=MAlloc(sizeof(CSoundEffectFrame)); + ns->type=SE_SWEEP; + ns->duration=mS/1000.0; + ns->ona1=ona1; + ns->ona2=ona2; + music.mute++; + return Spawn(&SoundEffectTask,ns,"Noise",,Fs); + } else + return NULL; +} diff --git a/src/Home/Sound/HDAudio1/Sup1Snd/SndFile.ZC b/src/Home/Sound/HDAudio1/Sup1Snd/SndFile.ZC new file mode 100644 index 000000000..047e9d531 --- /dev/null +++ b/src/Home/Sound/HDAudio1/Sup1Snd/SndFile.ZC @@ -0,0 +1,137 @@ +#help_index "Sound/Sound Files" +#define SNDFILE_SAMPLE_RATE 8000 +//Header for a ".SND" file +class CFileSND +{//big endian + U32 signature; //0x646e732e + U32 offset; //24 + U32 data_size; + U32 coding; //3=16bit uncompressed + U32 sample_rate; //Hz + U32 channels; //1=mono + I16 body[1]; +}; + +//Windows media constraint. +//#define SND_FILE_DATA_MAX 0x0007FF00 +#define SND_FILE_DATA_MAX 0x7FFFFF00 + +public I64 SndFileCreate(U8 *base_filename,F64 normalized_vol=1.0, + F64 averaging=0.0,I64 waveform=WF_SQUARE, + F64 reverb_delay=0,F64 reverb_intensity=0,F64 time_shift=0) +{//Use "screencast.record" flag to start or stop recording, then call this routine. +//Averaging should be a num from 0.0 to 0.999. + //Vol should be from 0.0 to 1.0. + //Set reverb_delay to like 0.3 sec and reverb_intensity to like 0.4. + I64 i,i1,k,cnt,cnt2,level,file_num; + F64 avg,dt; + CFileSND *s; + CSndWaveCtrl *swc=SndWaveCtrlNew(SNDFILE_SAMPLE_RATE,16,1); + CSoundData *d,*d1; + U8 *name,*name2; + + screencast.record=FALSE; + + dt=screencast.sound_head.last->tS-screencast.sound_head.next->tS; + if (!dt) return 0; + cnt=dt*SNDFILE_SAMPLE_RATE; + cnt++; //Terminator + + name=StrNew(base_filename); + FileExtRemove(name); + + s=CAlloc(offset(CFileSND.body)+cnt*sizeof(I16)); + s->signature=0x646e732e; + s->offset=EndianU32(offset(CFileSND.body)); + s->coding=EndianU32(3); + s->sample_rate=EndianU32(SNDFILE_SAMPLE_RATE); + s->channels=EndianU32(1); + + if (time_shift) { + d=screencast.sound_head.next; + d->tS-=time_shift; + while (d->next!=&screencast.sound_head) { + d1=d->next; + dt=d1->tS-d->tS; + if (dt<0) { + QueueRemove(d1); + Free(d1); + } else + break; + } + } + + d=screencast.sound_head.next; + k=0; + i=d->tS*SNDFILE_SAMPLE_RATE; + while (d->next!=&screencast.sound_head) { + d1=d->next; + i1=d1->tS*SNDFILE_SAMPLE_RATE; + if (i1-i) { + SndWaveAddBuf(swc,&s->body[k],i1-i, + Ona2Freq(d->ona),waveform,normalized_vol); + k+=i1-i; + i=i1; + } + QueueRemove(d); + Free(d); + d=d1; + } + + //Average + if (averaging) { + avg=0; + for (i=0;ibody[i]=avg=LowPass1(averaging,avg,s->body[i],1.0); + } + + //Reverb + if (reverb_intensity) { + if (dt=reverb_delay*SNDFILE_SAMPLE_RATE) + for (i=dt;ibody[i]+=reverb_intensity*s->body[i-dt]; + } + + //Get rid of D.C. component + for (k=0;k<3;k++) { + level=0; + for (i=0;ibody[i]; + level/=cnt-1; + for (i=0;ibody[i]=ClampI64(s->body[i]-level,I16_MIN,I16_MAX); + } + + for (i=0;ibody[i]=EndianU16(s->body[i]); + + s->body[cnt-1]=0; + + d=screencast.sound_head.next; + while (d!=&screencast.sound_head) { + d1=d->next; + QueueRemove(d); + Free(d); + d=d1; + } + + name2=MAlloc(StrLen(name)+3+1+3+1); + cnt2=cnt; + file_num=0; + while (cnt2>0) { + i=cnt2; + if (i>SND_FILE_DATA_MAX) + i=SND_FILE_DATA_MAX; + s->data_size=EndianU32(i*sizeof(I16)); + MemCopy(s->body,&s->body[file_num*SND_FILE_DATA_MAX],i*sizeof(I16)); + StrPrint(name2,"%s%03d.SND",name,file_num++); + FileWrite(name2,s,offset(CFileSND.body)+i*sizeof(I16)); + cnt2-=i; + } + Free(s); + Free(name); + Free(name2); + + SndWaveCtrlDel(swc); + return cnt; +} diff --git a/src/Home/Sound/HDAudio1/Sup1Snd/SndMath.ZC b/src/Home/Sound/HDAudio1/Sup1Snd/SndMath.ZC new file mode 100644 index 000000000..c767d4df2 --- /dev/null +++ b/src/Home/Sound/HDAudio1/Sup1Snd/SndMath.ZC @@ -0,0 +1,248 @@ +#help_index "Sound/Math;Math" +public F64 Saw(F64 t,F64 period) +{//Sawtooth. 0.0 - 1.0 think "(Sin+1)/2" + if (period) { + if (t>=0.0) + return t%period/period; + else + return 1.0+t%period/period; + } else + return 0.0; +} + +public F64 FullSaw(F64 t,F64 period) +{//Plus&Minus Sawtooth. 1.0 - -1.0 think "Sin" + if (period) { + if (t>=0.0) + return 2.0*(t%period/period)-1.0; + else + return 2.0*(t%period/period)+1.0; + } else + return 0.0; +} + +public F64 Caw(F64 t,F64 period) +{//Cawtooth. 1.0 - 0.0 think "(Cos+1)/2" + if (period) { + if (t>=0.0) + return 1.0-t%period/period; + else + return -(t%period)/period; + } else + return 1.0; +} + +public F64 FullCaw(F64 t,F64 period) +{//Plus&Minus Cawtooth. 1.0 - -1.0 think "Cos" + if (period) { + if (t>=0.0) + return -2.0*(t%period/period)+1.0; + else + return -2.0*(t%period/period)-1.0; + } else + return 1.0; +} + +public F64 Tri(F64 t,F64 period) +{//Triangle waveform. 0.0 - 1.0 - 0.0 + if (period) { + t=2.0*(Abs(t)%period)/period; + if (t<=1.0) + return t; + else + return 2.0-t; + } else + return 0.0; +} + +public F64 FullTri(F64 t,F64 period) +{//Plus&Minus Triangle waveform. 0.0 - 1.0 - 0.0 - -1.0 -0.0 + if (period) { + t=4.0*(t%period)/period; + if (t<=-1.0) { + if (t<=-3.0) + return t+4.0; + else + return -2.0-t; + } else { + if (t<=1.0) + return t; + else if (t<=3.0) + return 2.0-t; + else + return t-4.0; + } + } else + return 0.0; +} + +#help_index "Sound/Math" + +public I8 Note2Ona(I64 note,I64 octave=4) +{//Note to ona. Mid C is ona=51, note=3 and octave=4. + if (note<3) + return (octave+1)*12+note; + else + return octave*12+note; +} + +public I8 Ona2Note(I8 ona) +{//Ona to note in octave. Mid C is ona=51, note=3 and octave=4. + return ona%12; +} + +public I8 Ona2Octave(I8 ona) +{//Ona to octave. Mid C is ona=51, note=3 and octave=4. + I64 note=ona%12,octave=ona/12; + if (note<3) + return octave-1; + else + return octave; +} + +F64 SinPhaseCont(F64 last_y,F64 last_dydt, + F64 current_amp,F64 phase_offset) +{//Next sample of sin waveform. + F64 phase; + phase=last_y/current_amp; + if (phase>1.0) phase=1.0; + if (phase<-1.0) phase=-1.0; + if (last_dydt<0) + phase=ã-ASin(phase); + else + phase=ASin(phase); + return phase-phase_offset; +} + +public CSndWaveCtrl *SndWaveCtrlNew(I64 sample_rate=8000,I64 sample_bits=24, + I64 channels=2,CTask *mem_task=NULL) +{//MAlloc ctrl struct for generating waveforms. + CSndWaveCtrl *swc=CAlloc(sizeof(CSndWaveCtrl),mem_task); + swc->freq_multiplier=1.0; + swc->amp_multiplier=1.0; + swc->sample_rate=sample_rate; + swc->sample_bits=sample_bits; + swc->channels=channels; + swc->last_dydt=1.0; + return swc; +} + +public U0 SndWaveCtrlDel(CSndWaveCtrl *swc) +{//Free waveform ctrl. + Free(swc); +} + +#define WF_NULL 0 +#define WF_SQUARE 1 +#define WF_SINE 2 +#define WF_TRI 3 +#define WF_SAWTOOTH 4 +#define WF_NOISE 5 +#define WF_WAVEFORMS_NUM 6 + +public U0 SndWaveAddBuf(CSndWaveCtrl *swc,U8 *buf,I64 num_samples, + F64 _freq,I64 _waveform=WF_SQUARE,F64 _amp=1.0,F64 _left=1.0, F64 _right=1.0) +{//Add waveform to buffer. +//num_samples is multiplied by channels to get buf_len. + //left,right range from 0.0-1.0 + //Supports 16,24 and 32 bits + I64 reg i,reg j,reg k; + F64 a,f,amp,reg phase; + if (!swc) return; + _freq*=swc->freq_multiplier; + _amp*=swc->amp_multiplier; + if (!_freq||!_amp) { + swc->last_y=swc->phase=0; + swc->last_dydt=1.0; + } else { + phase=swc->phase; + i=0; + amp=Min(I32_MAX,I32_MAX*_amp); + f=2*ã/swc->sample_rate*_freq; + switch (_waveform) { + case WF_NOISE: + a=2.0/ã*amp; + break; + case WF_SAWTOOTH: + a=amp/ã; + break; + case WF_SINE: + phase=SinPhaseCont(swc->last_y,swc->last_dydt,amp,0.0); + break; + } + while (phase<0) + phase+=2*ã; + while (phase>=2*ã) + phase-=2*ã; + num_samples*=swc->channels; + while (i=ã) + j=-amp; + else + j=amp; + break; + case WF_SINE: + j=amp*Sin(phase); + break; + case WF_TRI: + if (phase>=ã) { + swc->last_y=swc->next_y; + swc->next_y=-amp*Sign(swc->last_y)+.00001; + phase-=ã; + } + j=(swc->last_y*(ã-phase)+swc->next_y*phase)/ã; + break; + case WF_SAWTOOTH: + j=a*(phase-ã); + break; + case WF_NOISE: + if (phase<ã) { + if (phaselast_y=swc->next_y; + swc->next_y=a*RandI16/U16_MAX; + } + j=swc->last_y*(ã-phase)+swc->next_y*phase; + } else { + if (phase-ãlast_y=swc->next_y; + swc->next_y=a*RandI16/U16_MAX; + } + j=swc->last_y*(2.0*ã-phase)+swc->next_y*(phase-ã); + } + break; + } +//left channel + k=j*_left; + if (swc->sample_bits==16) { + k>>=16; + buf(I16 *)[i++]+=k; + } else { + if (swc->sample_bits==24) + k&=0xFFFFFF00; + buf(I32 *)[i++]+=k; + } +//right channel + if (swc->channels==2) { + k=j*_right; + if (swc->sample_bits==16) { + k>>=16; + buf(I16 *)[i++]+=k; + } else { + if (swc->sample_bits==24) + k&=0xFFFFFF00; + buf(I32 *)[i++]+=k; + } + } + phase+=f; + while (phase>=2*ã) + phase-=2*ã; + } + if (_waveform==WF_SINE) { + swc->last_y=amp*Sin(phase); + swc->last_dydt=Cos(phase); + } + swc->phase=phase; + } +} diff --git a/src/Home/Sound/HDAudio1/Sup1Snd/SndMusic.ZC b/src/Home/Sound/HDAudio1/Sup1Snd/SndMusic.ZC new file mode 100644 index 000000000..9d2780e6a --- /dev/null +++ b/src/Home/Sound/HDAudio1/Sup1Snd/SndMusic.ZC @@ -0,0 +1,224 @@ +#help_index "Sound/Music" + +public class CMusicGlbls +{ + U8 *cur_song; + CTask *cur_song_task; + I64 octave; + F64 note_len; + U8 note_map[7]; + Bool mute; + I64 meter_top,meter_bottom; + F64 tempo,stacatto_factor; + + //If you wish to sync with a + //note in a Play() string. 0 is the start + I64 play_note_num; + + F64 tM_correction,last_Beat,last_tM; +} music={NULL,NULL,4,1.0,{0,2,3,5,7,8,10},FALSE,4,4,2.5,0.9,0,0,0,0}; + +#help_index "Sound/Music;Time/Seconds" +public F64 tM() +{//Time in seconds synced to music subsystem. + return (counts.jiffies+music.tM_correction)/JIFFY_FREQ; +} + +public F64 Beat() +{//Time in music beats. + F64 res,cur_tM; + PUSHFD + CLI + if (mp_count>1) + while (LBts(&sys_semas[SEMA_TMBEAT],0)) + PAUSE + cur_tM=tM; + res=music.last_Beat; + if (music.tempo) + res+=(cur_tM-music.last_tM)*music.tempo; + music.last_tM=cur_tM; + music.last_Beat=res; + LBtr(&sys_semas[SEMA_TMBEAT],0); + POPFD + return res; +} + +#help_index "Sound/Music" +U8 *MusicSetOctave(U8 *st) +{ + I64 ch; + ch=*st++; + while ('0'<=ch<='9') { + music.octave=ch-'0'; + ch=*st++; + } + return --st; +} + +U8 *MusicSetMeter(U8 *st) +{ + I64 ch; + ch=*st++; + while (ch=='M') { + ch=*st++; + if ('0'<=ch<='9') { + music.meter_top=ch-'0'; + ch=*st++; + } + if (ch=='/') + ch=*st++; + if ('0'<=ch<='9') { + music.meter_bottom=ch-'0'; + ch=*st++; + } + } + return --st; +} + +U8 *MusicSetNoteLen(U8 *st) +{ + Bool cont=TRUE; + do { + switch (*st++) { + case 'w': music.note_len=4.0; break; + case 'h': music.note_len=2.0; break; + case 'q': music.note_len=1.0; break; + case 'e': music.note_len=0.5; break; + case 's': music.note_len=0.25; break; + case 't': music.note_len=2.0*music.note_len/3.0; break; + case '.': music.note_len=1.5*music.note_len; break; + default: + st--; + cont=FALSE; + } + } while (cont); + return st; +} + +public U0 Play(U8 *st,U8 *words=NULL) +{/* Notes are entered with a capital letter. + +Octaves are entered with a digit and +stay set until changed. Mid C is octave 4. + +Durations are entered with +'w' whole note +'h' half note +'q' quarter note +'e' eighth note +'t' sets to 2/3rds the current duration +'.' sets to 1.5 times the current duration +durations stay set until changed. + +'(' tie, placed before the note to be extended + +$LK,"music.meter_top",A="MN:CMusicGlbls"$,$LK,"music.meter_bottom",A="MN:CMusicGlbls"$ is set with +"M3/4" +"M4/4" +etc. + +Sharp and flat are done with '#' or 'b'. + +The var music.stacatto_factor can +be set to a range from 0.0 to 1.0. + +The var music.tempo is quarter-notes +per second.It defaults to +2.5 and gets faster when bigger. +*/ + U8 *word,*last_st; + I64 note,octave,i=0,ona,timeout_val,timeout_val2; + Bool tie; + F64 d,on_jiffies,off_jiffies; + music.play_note_num=0; + while (*st) { + timeout_val=counts.jiffies; + tie=FALSE; + + do { + last_st=st; + if (*st=='(') { + tie=TRUE; + st++; + } else { + st=MusicSetMeter(st); + st=MusicSetOctave(st); + st=MusicSetNoteLen(st); + } + } while (st!=last_st); + + if (!*st) break; + note=*st++-'A'; + if (note<7) { + note=music.note_map[note]; + octave=music.octave; + if (*st=='b') { + note--; + if (note==2) + octave--; + st++; + } else if (*st=='#') { + note++; + if (note==3) + octave++; + st++; + } + ona=Note2Ona(note,octave); + } else + ona=0; + if (words && (word=ListSub(i++,words)) && StrCompare(word,"")) + "%s",word; + d=JIFFY_FREQ*music.note_len/music.tempo; + if (tie) { + on_jiffies =d; + off_jiffies =0; + } else { + on_jiffies =d*music.stacatto_factor; + off_jiffies =d*(1.0-music.stacatto_factor); + } + timeout_val+=on_jiffies; + timeout_val2=timeout_val+off_jiffies; + + if (!music.mute) + Sound(ona); + SleepUntil(timeout_val); + music.tM_correction+=on_jiffies-ToI64(on_jiffies); + + if (!music.mute) + Sound; + SleepUntil(timeout_val2); + music.tM_correction+=off_jiffies-ToI64(off_jiffies); + + music.play_note_num++; + } +} + +U0 MusicSettingsReset() +{ + music.play_note_num=0; + music.stacatto_factor=0.9; + music.tempo=2.5; + music.octave=4; + music.note_len=1.0; + music.meter_top=4; + music.meter_bottom=4; + SoundReset; + PUSHFD + CLI + if (mp_count>1) + while (LBts(&sys_semas[SEMA_TMBEAT],0)) + PAUSE + music.last_tM=tM; + music.last_Beat=0.0; + LBtr(&sys_semas[SEMA_TMBEAT],0); + POPFD +} + +MusicSettingsReset; + +U0 CurSongTask() +{ + Fs->task_end_cb=&SoundTaskEndCB; + while (TRUE) + Play(music.cur_song); +} From 276ab81094f0c0b49e81bbc2a34c0a7487620d52 Mon Sep 17 00:00:00 2001 From: TomAwezome Date: Sat, 24 Dec 2022 14:18:04 -0500 Subject: [PATCH 02/23] Change AC97 var naming convention to Zeal standard. --- src/Home/Sound/AC97/AC97.ZC | 102 ++++++++++++++++++------------------ 1 file changed, 51 insertions(+), 51 deletions(-) diff --git a/src/Home/Sound/AC97/AC97.ZC b/src/Home/Sound/AC97/AC97.ZC index 538381b19..0a9c8195e 100644 --- a/src/Home/Sound/AC97/AC97.ZC +++ b/src/Home/Sound/AC97/AC97.ZC @@ -43,27 +43,27 @@ #define BUFFER_CNT\ 0x0B // Most Important Register for controlling Transfers (U8) -class @ac97_bdl_entry +class CAC97BufferDescriptorListEntry { U32 addr; U16 length; // length - 1 U16 flags; }; -class @ac97_bdl +class CAC97BufferDescriptorList { - @ac97_bdl_entry entries[32]; + CAC97BufferDescriptorListEntry entries[32]; }; -class @ac97 +class CAC97 { @pci_info pci; - @ac97_bdl *bdl[3]; + CAC97BufferDescriptorList *bdl[3]; U16 nam; U16 nabm; }; -@ac97 AC97; +CAC97 ac97; #define AUDIO_MAX_STREAMS 16 #define AUDIO_OUTPUT_BUFFER_SIZE 1024 @@ -71,29 +71,29 @@ class @ac97 #define AUDIO_STREAM_TYPE_INPUT 0 #define AUDIO_STREAM_TYPE_OUTPUT 1 -class @audio_stream +class CAudioStream { - CFifoI64 * data; + CFifoI64 * data; }; -class @audio +class CAudio { - @audio_stream output[AUDIO_MAX_STREAMS]; + CAudioStream output[AUDIO_MAX_STREAMS]; I64 output_frames[AUDIO_MAX_STREAMS]; }; -@audio Audio; +CAudio Audio; -U0 @audio_init() +U0 AudioInit() { I64 i = 0; for (i = 0; i < AUDIO_MAX_STREAMS; i++) Audio.output[i].data = FifoI64New(AUDIO_STREAM_FIFO_SIZE, sys_task); } -@audio_init; +AudioInit; -I64 @audio_get_available_output_stream() +I64 AudioAvailableOutputStreamGet() { I64 stream = 0; while (FifoI64Count(Audio.output[stream].data)) @@ -103,10 +103,10 @@ I64 @audio_get_available_output_stream() return stream; } -I64 @audio_play_sfx(U32 *data, I64 length) +I64 AudioSFXPlay(U32 *data, I64 length) { I64 i; - I64 stream = @audio_get_available_output_stream; + I64 stream = AudioAvailableOutputStreamGet; if (stream < 0) return stream; for (i = 0; i < length; i++) @@ -114,7 +114,7 @@ I64 @audio_play_sfx(U32 *data, I64 length) return stream; } -U0 @ac97_mix_output(U32 *buf, I64 length = NULL) +U0 AC97OutputMix(U32 *buf, I64 length = NULL) { I64 i; I64 j; @@ -148,25 +148,25 @@ U0 @ac97_mix_output(U32 *buf, I64 length = NULL) } } -U0 @ac97_fill_buffer() +U0 AC97BufferFill() { - I64 idx = InU8(AC97.nabm + PCM_OUTPUT_REG_BOX + LAST_VALID_ENTRY); - U32 *buf = AC97.bdl[PCM_OUT]->entries[idx].addr; - @ac97_mix_output(buf, BDL_BUF_SIZE); - OutU8(AC97.nabm + PCM_OUTPUT_REG_BOX + LAST_VALID_ENTRY, ++idx); + I64 idx = InU8(ac97.nabm + PCM_OUTPUT_REG_BOX + LAST_VALID_ENTRY); + U32 *buf = ac97.bdl[PCM_OUT]->entries[idx].addr; + AC97OutputMix(buf, BDL_BUF_SIZE); + OutU8(ac97.nabm + PCM_OUTPUT_REG_BOX + LAST_VALID_ENTRY, ++idx); } -U0 @ac97_process_audio() +U0 AC97AudioProcess() { - U16 status = InU16(AC97.nabm + PCM_OUTPUT_REG_BOX + TRANSFER_STS); + U16 status = InU16(ac97.nabm + PCM_OUTPUT_REG_BOX + TRANSFER_STS); if (status & INT_IOC) { - @ac97_fill_buffer; - OutU16(AC97.nabm + PCM_OUTPUT_REG_BOX + TRANSFER_STS, 0x1C); + AC97BufferFill; + OutU16(ac97.nabm + PCM_OUTPUT_REG_BOX + TRANSFER_STS, 0x1C); } } -I64 @ac97_init() +I64 AC97Init() { I64 i; I64 j; @@ -178,67 +178,67 @@ I64 @ac97_init() return -1; } - @get_pci_info(j, &AC97.pci); + @get_pci_info(j, &ac97.pci); - if (AC97.pci.vendor_id != 0x8086 || AC97.pci.device_id != 0x2415) + if (ac97.pci.vendor_id != 0x8086 || ac97.pci.device_id != 0x2415) goto device_not_found; - AC97.nam = AC97.pci.bar[0] &0xFFFFFF00; - AC97.nabm = AC97.pci.bar[1] &0xFFFFFF00; + ac97.nam = ac97.pci.bar[0] &0xFFFFFF00; + ac97.nabm = ac97.pci.bar[1] &0xFFFFFF00; // Enable port IO, disable MMIO PCIWriteU8(j.u8[2], j.u8[1], j.u8[0], 0x4, 5); - OutU32(AC97.nabm + GLOBAL_CTL, 0x03); - OutU16(AC97.nam + RESET, 0xFFFF); + OutU32(ac97.nabm + GLOBAL_CTL, 0x03); + OutU16(ac97.nam + RESET, 0xFFFF); // Set PCM Output to Max volume - OutU16(AC97.nam + PCM_VOL, 0x0000); + OutU16(ac97.nam + PCM_VOL, 0x0000); // Allocate Buffer Descriptor Lists - AC97.bdl[PCM_IN] = CAllocAligned(sizeof(@ac97_bdl), 4096, Fs->code_heap); - AC97.bdl[PCM_OUT] = CAllocAligned(sizeof(@ac97_bdl), 4096, Fs->code_heap); - AC97.bdl[MIC_IN] = CAllocAligned(sizeof(@ac97_bdl), 4096, Fs->code_heap); + ac97.bdl[PCM_IN] = CAllocAligned(sizeof(CAC97BufferDescriptorList), 4096, Fs->code_heap); + ac97.bdl[PCM_OUT] = CAllocAligned(sizeof(CAC97BufferDescriptorList), 4096, Fs->code_heap); + ac97.bdl[MIC_IN] = CAllocAligned(sizeof(CAC97BufferDescriptorList), 4096, Fs->code_heap); for (i = 0; i < MAX_BDLS; i++) { - AC97.bdl[PCM_OUT]->entries[i].addr = + ac97.bdl[PCM_OUT]->entries[i].addr = CAllocAligned(PCM_BUF_SIZE, 4096, Fs->code_heap); - AC97.bdl[PCM_OUT]->entries[i].length = BDL_BUF_SIZE / 2; - AC97.bdl[PCM_OUT]->entries[i].flags = 1 << 15; + ac97.bdl[PCM_OUT]->entries[i].length = BDL_BUF_SIZE / 2; + ac97.bdl[PCM_OUT]->entries[i].flags = 1 << 15; } // Set addresses of Buffer Descriptor Lists - // OutU32(AC97.nabm + PCM_INPUT_REG_BOX + BUFFER_DSC_ADDR, AC97.bdl[PCM_IN]); - OutU32(AC97.nabm + PCM_OUTPUT_REG_BOX + BUFFER_DSC_ADDR, AC97.bdl[PCM_OUT]); - // OutU32(AC97.nabm + MIC_INPUT_REG_BOX + BUFFER_DSC_ADDR, AC97.bdl[MIC_IN]); + // OutU32(ac97.nabm + PCM_INPUT_REG_BOX + BUFFER_DSC_ADDR, ac97.bdl[PCM_IN]); + OutU32(ac97.nabm + PCM_OUTPUT_REG_BOX + BUFFER_DSC_ADDR, ac97.bdl[PCM_OUT]); + // OutU32(ac97.nabm + MIC_INPUT_REG_BOX + BUFFER_DSC_ADDR, ac97.bdl[MIC_IN]); // Set Master Volume - OutU16(AC97.nam + MASTER_VOL, 0x0F0F); + OutU16(ac97.nam + MASTER_VOL, 0x0F0F); // Stop playing sound - OutU8(AC97.nabm + PCM_OUTPUT_REG_BOX + BUFFER_CNT, 0); + OutU8(ac97.nabm + PCM_OUTPUT_REG_BOX + BUFFER_CNT, 0); // Fill one buffers - @ac97_fill_buffer; + AC97BufferFill; // Enable interrupt handler //@pci_register_int_handler(&@ac97_int_handler); // Start playing sound - OutU8(AC97.nabm + PCM_OUTPUT_REG_BOX + BUFFER_CNT, 1); + OutU8(ac97.nabm + PCM_OUTPUT_REG_BOX + BUFFER_CNT, 1); return 0; } -U0 @ac97_task() +U0 AC97Task() { while (1) { - @ac97_process_audio; + AC97AudioProcess; Sleep(1); } } -@ac97_init; -Spawn(&@ac97_task,, "AC97 Task", 1); \ No newline at end of file +AC97Init; +Spawn(&AC97Task,, "AC97 Task", 1); \ No newline at end of file From dcdde184eab7876aa5cc4b1c4928876d7463dc66 Mon Sep 17 00:00:00 2001 From: TomAwezome Date: Sat, 24 Dec 2022 14:28:49 -0500 Subject: [PATCH 03/23] Run CursorRemove on Sound files --- src/Home/Sound/AC97/Pci.ZC | 2 +- src/Home/Sound/HDAudio0/HDAudio.ZC | 2 +- src/Home/Sound/HDAudio1/Load.ZC | 1 - src/Home/Sound/HDAudio1/Sup1CodeScraps/Mem/Mem2Meg.ZC | 2 +- src/Home/Sound/HDAudio1/Sup1HDAudio/Examples/Echo.ZC | 1 - src/Home/Sound/HDAudio1/Sup1HDAudio/Examples/Guitar.ZC | 2 +- src/Home/Sound/HDAudio1/Sup1HDAudio/Examples/Synth.ZC | 1 - src/Home/Sound/HDAudio1/Sup1HDAudio/HDAudio.ZC | 2 +- src/Home/Sound/HDAudio1/Sup1HDAudio/HDCfg.ZC | 2 +- src/Home/Sound/HDAudio1/Sup1Snd/SndFile.ZC | 2 +- src/Home/Sound/HDAudio1/Sup1Snd/SndMusic.ZC | 2 +- 11 files changed, 8 insertions(+), 11 deletions(-) diff --git a/src/Home/Sound/AC97/Pci.ZC b/src/Home/Sound/AC97/Pci.ZC index 9f83604dc..1309068df 100644 --- a/src/Home/Sound/AC97/Pci.ZC +++ b/src/Home/Sound/AC97/Pci.ZC @@ -86,4 +86,4 @@ MemSet(&@pci_int_handler, NULL, sizeof(U64) * PCI_INTH_MAX); // IntEntrySet(0x41, &@pci_interrupt_handler, IDTET_IRQ); // IntEntrySet(0x42, &@pci_interrupt_handler, IDTET_IRQ); // IntEntrySet(0x43, &@pci_interrupt_handler, IDTET_IRQ); -//@pci_reroute_interrupts(0x40, 0); \ No newline at end of file +//@pci_reroute_interrupts(0x40, 0); \ No newline at end of file diff --git a/src/Home/Sound/HDAudio0/HDAudio.ZC b/src/Home/Sound/HDAudio0/HDAudio.ZC index cd73d2842..718b9f539 100644 --- a/src/Home/Sound/HDAudio0/HDAudio.ZC +++ b/src/Home/Sound/HDAudio0/HDAudio.ZC @@ -1049,4 +1049,4 @@ Bool HDAudioScan() HDAudioScan; Kill(hda.task); -HDAudioScan; \ No newline at end of file +HDAudioScan; \ No newline at end of file diff --git a/src/Home/Sound/HDAudio1/Load.ZC b/src/Home/Sound/HDAudio1/Load.ZC index 8fb4d20a0..cf89cafab 100644 --- a/src/Home/Sound/HDAudio1/Load.ZC +++ b/src/Home/Sound/HDAudio1/Load.ZC @@ -3,4 +3,3 @@ Cd(__DIR__); SysFile("Sup1CodeScraps/Mem/Mem2Meg.ZC"); SysFile("Sup1Snd/MakeSnd.ZC"); SysFile("Sup1HDAudio/HDAudio.ZC"); - \ No newline at end of file diff --git a/src/Home/Sound/HDAudio1/Sup1CodeScraps/Mem/Mem2Meg.ZC b/src/Home/Sound/HDAudio1/Sup1CodeScraps/Mem/Mem2Meg.ZC index fb94b9b93..002335778 100644 --- a/src/Home/Sound/HDAudio1/Sup1CodeScraps/Mem/Mem2Meg.ZC +++ b/src/Home/Sound/HDAudio1/Sup1CodeScraps/Mem/Mem2Meg.ZC @@ -166,7 +166,7 @@ U0 Mem2MegFree(CMemBlk *m,I64 pages2Meg,CBlkPool *bp=NULL) while (m2 1) diff --git a/src/Home/Sound/HDAudio1/Sup1HDAudio/HDCfg.ZC b/src/Home/Sound/HDAudio1/Sup1HDAudio/HDCfg.ZC index 0121d4494..e6520cf80 100644 --- a/src/Home/Sound/HDAudio1/Sup1HDAudio/HDCfg.ZC +++ b/src/Home/Sound/HDAudio1/Sup1HDAudio/HDCfg.ZC @@ -649,7 +649,7 @@ U0 HDCfg() PopUpOk( "This is a tool to cfgure\n" "HD Audio.It creates $$FG,RED$$~/HDAudioCfg.ZC.Z$$FG$$\n" "which you should $$FG,GREEN$$ -#include$$FG$$ in your\n" +#include$$FG$$ in your\n" "$$FG,RED$$~/HomeSnd.ZC.Z$$FG$$ file.\n\n\n" "Left click to see info and cfgure a widget.\n" "Right click drag to connect output to input.\n\n" diff --git a/src/Home/Sound/HDAudio1/Sup1Snd/SndFile.ZC b/src/Home/Sound/HDAudio1/Sup1Snd/SndFile.ZC index 047e9d531..97c3fbf13 100644 --- a/src/Home/Sound/HDAudio1/Sup1Snd/SndFile.ZC +++ b/src/Home/Sound/HDAudio1/Sup1Snd/SndFile.ZC @@ -108,7 +108,7 @@ public I64 SndFileCreate(U8 *base_filename,F64 normalized_vol=1.0, s->body[cnt-1]=0; d=screencast.sound_head.next; - while (d!=&screencast.sound_head) { + while (d!=&screencast.sound_head) { d1=d->next; QueueRemove(d); Free(d); diff --git a/src/Home/Sound/HDAudio1/Sup1Snd/SndMusic.ZC b/src/Home/Sound/HDAudio1/Sup1Snd/SndMusic.ZC index 9d2780e6a..464aff6b3 100644 --- a/src/Home/Sound/HDAudio1/Sup1Snd/SndMusic.ZC +++ b/src/Home/Sound/HDAudio1/Sup1Snd/SndMusic.ZC @@ -202,7 +202,7 @@ U0 MusicSettingsReset() music.note_len=1.0; music.meter_top=4; music.meter_bottom=4; - SoundReset; + SoundReset; PUSHFD CLI if (mp_count>1) From bff3a763ea275bec90e09a23725b5d5746c6245f Mon Sep 17 00:00:00 2001 From: TomAwezome Date: Sat, 24 Dec 2022 14:31:57 -0500 Subject: [PATCH 04/23] Reformat AC97 #define value tab-alignment. --- src/Home/Sound/AC97/AC97.ZC | 88 ++++++++++++++++++------------------- 1 file changed, 42 insertions(+), 46 deletions(-) diff --git a/src/Home/Sound/AC97/AC97.ZC b/src/Home/Sound/AC97/AC97.ZC index 0a9c8195e..15439fbbf 100644 --- a/src/Home/Sound/AC97/AC97.ZC +++ b/src/Home/Sound/AC97/AC97.ZC @@ -1,47 +1,43 @@ -#define INT_LAST_VALID_ENTRY 1 << 2 -#define INT_IOC 1 << 3 -#define INT_FIFO_ERR 1 << 4 -#define BDL_BUF_SIZE 2044 -#define PCM_BUF_SIZE 2048 -#define MAX_BDLS 32 -#define PCM_IN 0 -#define PCM_OUT 1 -#define MIC_IN 2 +#define INT_LAST_VALID_ENTRY 1 << 2 +#define INT_IOC 1 << 3 +#define INT_FIFO_ERR 1 << 4 + +#define BDL_BUF_SIZE 2044 +#define MAX_BDLS 32 + +#define PCM_BUF_SIZE 2048 +#define PCM_IN 0 +#define PCM_OUT 1 +#define MIC_IN 2 // Native Audio Mixer registers (all U16) -#define RESET 0x00 // Reset Register -#define MASTER_VOL 0x02 // Set Master Output Volume -#define MIC_VOL 0x0E // Set Microphone Volume -#define PCM_VOL 0x18 // Set Output Volume of PCM patterns -#define REC_SLC 0x1A // Select Input Device -#define REC_GAIN 0x1C // Set Input Gain -#define MIC_GAIN 0x1E // Set Gain of Microphone -#define EXT_ID 0x28 // Supported extended functions -#define EXT_CTRL 0x2A // Enabling extended functions -#define EXT_FRONT_RATE 0x2C // Sample rate of front speaker +#define RESET 0x00 // Reset Register +#define MASTER_VOL 0x02 // Set Master Output Volume +#define MIC_VOL 0x0E // Set Microphone Volume +#define PCM_VOL 0x18 // Set Output Volume of PCM patterns +#define REC_SLC 0x1A // Select Input Device +#define REC_GAIN 0x1C // Set Input Gain +#define MIC_GAIN 0x1E // Set Gain of Microphone +#define EXT_ID 0x28 // Supported extended functions +#define EXT_CTRL 0x2A // Enabling extended functions +#define EXT_FRONT_RATE 0x2C // Sample rate of front speaker // Native Audio Bus Master registers -#define PCM_INPUT_REG_BOX\ -0x00 // NABM register box for PCM IN (sizeof NABM register box) -#define PCM_OUTPUT_REG_BOX\ -0x10 // NABM register box for PCM OUT (sizeof NABM register box) -#define MIC_INPUT_REG_BOX\ -0x20 // NABM register box for Microphone (sizeof NABM register box) -#define GLOBAL_CTL 0x2C // Global Control Register (U32) -#define GLOBAL_STS 0x30 // Global Status Register (U32) +#define PCM_INPUT_REG_BOX 0x00 // NABM register box for PCM IN (sizeof NABM register box) +#define PCM_OUTPUT_REG_BOX 0x10 // NABM register box for PCM OUT (sizeof NABM register box) +#define MIC_INPUT_REG_BOX 0x20 // NABM register box for Microphone (sizeof NABM register box) +#define GLOBAL_CTL 0x2C // Global Control Register (U32) +#define GLOBAL_STS 0x30 // Global Status Register (U32) // NABM register box registers -#define BUFFER_DSC_ADDR 0x00 // Physical Address of Buffer Descriptor List (U32) -#define CUR_ENTRY_VAL\ -0x04 // Number of Actual Processed Buffer Descriptor Entry (U8) -#define LAST_VALID_ENTRY 0x05 // Number of all Descriptor Entries (U8) -#define TRANSFER_STS 0x06 // Status of Transferring Data (U16) -#define CUR_IDX_PROC_SAMPLES\ -0x08 // Number of Transferred Samples in Actual Processed Entry (U16) -#define PRCSD_ENTRY 0x0A // Number of Actual Processed Buffer Entry (U8) -#define BUFFER_CNT\ -0x0B // Most Important Register for controlling Transfers (U8) +#define BUFFER_DSC_ADDR 0x00 // Physical Address of Buffer Descriptor List (U32) +#define CUR_ENTRY_VAL 0x04 // Number of Actual Processed Buffer Descriptor Entry (U8) +#define LAST_VALID_ENTRY 0x05 // Number of all Descriptor Entries (U8) +#define TRANSFER_STS 0x06 // Status of Transferring Data (U16) +#define CUR_IDX_PROC_SAMPLES 0x08 // Number of Transferred Samples in Actual Processed Entry (U16) +#define PRCSD_ENTRY 0x0A // Number of Actual Processed Buffer Entry (U8) +#define BUFFER_CNT 0x0B // Most Important Register for controlling Transfers (U8) class CAC97BufferDescriptorListEntry { @@ -73,7 +69,7 @@ CAC97 ac97; class CAudioStream { - CFifoI64 * data; + CFifoI64 *data; }; class CAudio @@ -82,13 +78,13 @@ class CAudio I64 output_frames[AUDIO_MAX_STREAMS]; }; -CAudio Audio; +CAudio audio; U0 AudioInit() { I64 i = 0; for (i = 0; i < AUDIO_MAX_STREAMS; i++) - Audio.output[i].data = FifoI64New(AUDIO_STREAM_FIFO_SIZE, sys_task); + audio.output[i].data = FifoI64New(AUDIO_STREAM_FIFO_SIZE, sys_task); } AudioInit; @@ -96,7 +92,7 @@ AudioInit; I64 AudioAvailableOutputStreamGet() { I64 stream = 0; - while (FifoI64Count(Audio.output[stream].data)) + while (FifoI64Count(audio.output[stream].data)) stream++; if (stream > AUDIO_MAX_STREAMS - 1) return -1; @@ -110,7 +106,7 @@ I64 AudioSFXPlay(U32 *data, I64 length) if (stream < 0) return stream; for (i = 0; i < length; i++) - FifoI64Ins(Audio.output[stream].data, data[i]); + FifoI64Ins(audio.output[stream].data, data[i]); return stream; } @@ -133,10 +129,10 @@ U0 AC97OutputMix(U32 *buf, I64 length = NULL) for (j = 0; j < AUDIO_MAX_STREAMS; j++) { - if (FifoI64Count(Audio.output[j].data)) + if (FifoI64Count(audio.output[j].data)) { - FifoI64Remove(Audio.output[j].data, &sample); - Audio.output_frames[j]++; + FifoI64Remove(audio.output[j].data, &sample); + audio.output_frames[j]++; acc_streams++; acc_sample_L += sample.u16[0]; acc_sample_R += sample.u16[1]; @@ -241,4 +237,4 @@ U0 AC97Task() } AC97Init; -Spawn(&AC97Task,, "AC97 Task", 1); \ No newline at end of file +Spawn(&AC97Task,, "AC97 Task", 1); \ No newline at end of file From ac7598808d942feacb2d31982d4a421da755ad8f Mon Sep 17 00:00:00 2001 From: TomAwezome Date: Sat, 24 Dec 2022 16:26:41 -0500 Subject: [PATCH 05/23] Change AC97 Pci.ZC var style convention to Zeal standard. --- src/Home/Sound/AC97/Pci.ZC | 151 ++++++++++++++++++++----------------- 1 file changed, 80 insertions(+), 71 deletions(-) diff --git a/src/Home/Sound/AC97/Pci.ZC b/src/Home/Sound/AC97/Pci.ZC index 1309068df..f08266f9c 100644 --- a/src/Home/Sound/AC97/Pci.ZC +++ b/src/Home/Sound/AC97/Pci.ZC @@ -1,89 +1,98 @@ + #define PCI_INTH_MAX 16 -U64 @pci_int_handler[PCI_INTH_MAX]; +U64 pci_int_handlers[PCI_INTH_MAX]; -class @pci_info { - U16 vendor_id; - U16 device_id; - U16 command; - U16 status; - U32 _class; - U32 bar[6]; - U32 cap_pointer; +class CPCIInfo +{ + U16 vendor_id; + U16 device_id; + U16 command; + U16 status; + U32 _class; + U32 bar[6]; + U32 cap_pointer; }; -class @pci_cap { - U8 cap_vndr; /* Generic PCI field: PCI_CAP_ID_VNDR */ - U8 cap_next; /* Generic PCI field: next ptr. */ - U8 cap_len; /* Generic PCI field: capability length */ - U8 cfg_type; /* Identifies the structure. */ - U8 bar; /* Where to find it. */ - U8 padding[3]; /* Pad to full dword. */ - U32 offset; /* Offset within bar. */ - U32 length; /* Length of the structure, in bytes. */ +class CPCICapability +{ + U8 cap_vndr; /*Generic PCI field: PCI_CAP_ID_VNDR */ + U8 cap_next; /*Generic PCI field: next ptr. */ + U8 cap_len; /*Generic PCI field: capability length */ + U8 cfg_type; /*Identifies the structure. */ + U8 bar; /*Where to find it. */ + U8 padding[3]; /*Pad to full dword. */ + U32 offset; /*Offset within bar. */ + U32 length; /*Length of the structure, in bytes. */ }; -U0 @get_pci_info(I64 i, @pci_info *pci) { - I64 j; - pci->vendor_id = PCIReadU32(i.u8[2], i.u8[1], i.u8[0], 0x0) & 0xFFFF; - pci->device_id = PCIReadU32(i.u8[2], i.u8[1], i.u8[0], 0x0) >> 16; - pci->command = PCIReadU32(i.u8[2], i.u8[1], i.u8[0], 0x4) & 0xFFFF; - pci->status = PCIReadU32(i.u8[2], i.u8[1], i.u8[0], 0x4) >> 16; - pci->_class = PCIReadU32(i.u8[2], i.u8[1], i.u8[0], 0x8) >> 24; - for (j = 0; j < 6; j++) - pci->bar[j] = PCIReadU32(i.u8[2], i.u8[1], i.u8[0], 0x10 + (0x04 * j)); +U0 PCIInfoGet(I64 i, CPCIInfo *pci) +{ + I64 j; + pci->vendor_id = PCIReadU32(i.u8[2], i.u8[1], i.u8[0], 0x0) &0xFFFF; + pci->device_id = PCIReadU32(i.u8[2], i.u8[1], i.u8[0], 0x0) >> 16; + pci->command = PCIReadU32(i.u8[2], i.u8[1], i.u8[0], 0x4) &0xFFFF; + pci->status = PCIReadU32(i.u8[2], i.u8[1], i.u8[0], 0x4) >> 16; + pci->_class = PCIReadU32(i.u8[2], i.u8[1], i.u8[0], 0x8) >> 24; + for (j = 0; j < 6; j++) + pci->bar[j] = PCIReadU32(i.u8[2], i.u8[1], i.u8[0], 0x10 + (0x04 * j)); } -U0 @get_pci_cap(I64 i, @pci_cap *cap, I64 idx) { - I64 base = 0x40 + (idx * 16); - U32 u32; - u32 = PCIReadU32(i.u8[2], i.u8[1], i.u8[0], base); - cap->cap_vndr = u32.u8[0]; - cap->cap_next = u32.u8[1]; - cap->cap_len = u32.u8[2]; - cap->cfg_type = u32.u8[3]; - u32 = PCIReadU32(i.u8[2], i.u8[1], i.u8[0], base + 0x04); - cap->bar = u32.u8[0]; - cap->offset = PCIReadU32(i.u8[2], i.u8[1], i.u8[0], base + 0x08); - cap->length = PCIReadU32(i.u8[2], i.u8[1], i.u8[0], base + 0x0c); +U0 PCIGetCapability(I64 i, CPCICapability *cap, I64 idx) +{ + I64 base = 0x40 + (idx * 16); + U32 u32; + u32 = PCIReadU32(i.u8[2], i.u8[1], i.u8[0], base); + cap->cap_vndr = u32.u8[0]; + cap->cap_next = u32.u8[1]; + cap->cap_len = u32.u8[2]; + cap->cfg_type = u32.u8[3]; + u32 = PCIReadU32(i.u8[2], i.u8[1], i.u8[0], base + 0x04); + cap->bar = u32.u8[0]; + cap->offset = PCIReadU32(i.u8[2], i.u8[1], i.u8[0], base + 0x08); + cap->length = PCIReadU32(i.u8[2], i.u8[1], i.u8[0], base + 0x0c); } -U0 @pci_reroute_interrupts(I64 base, I64 cpu) { - I64 i; - U8 *da = dev.uncached_alias + IOAPIC_REG; - U32 *_d = dev.uncached_alias + IOAPIC_DATA; +U0 PCIInterruptReroute(I64 base, I64 cpu) +{ + I64 i; + U8 *da = dev.uncached_alias + IOAPIC_REG; + U32 *_d = dev.uncached_alias + IOAPIC_DATA; - for (i = 0; i < 4; i++) { - *da = IOREDTAB + i * 2 + 1; - *_d = dev.mp_apic_ids[cpu] << 24; - *da = IOREDTAB + i * 2; - *_d = 0x4000 + base + i; - } + for (i = 0; i < 4; i++) + { + *da = IOREDTAB + i * 2 + 1; + *_d = dev.mp_apic_ids[cpu] << 24; + *da = IOREDTAB + i * 2; + *_d = 0x4000 + base + i; + } } -I64 @pci_register_int_handler(U64 handler) { - if (!handler) - return -1; - I64 i = 0; - while (@pci_int_handler[i]) - i++; - if (i > PCI_INTH_MAX - 1) - return -1; - @pci_int_handler[i] = handler; - return 0; +I64 PCIInterruptHandlerRegister(U64 handler) +{ + if (!handler) + return -1; + I64 i = 0; + while (pci_int_handlers[i]) + i++; + if (i > PCI_INTH_MAX - 1) + return -1; + pci_int_handlers[i] = handler; + return 0; } -interrupt U0 @pci_interrupt_handler() { - I64 i; - for (i = 0; i < PCI_INTH_MAX; i++) - if (@pci_int_handler[i]) - Call(@pci_int_handler[i]); - *(dev.uncached_alias + LAPIC_EOI)(U32 *) = 0; +interrupt U0 PCIInterruptHandler() +{ + I64 i; + for (i = 0; i < PCI_INTH_MAX; i++) + if (pci_int_handlers[i]) + Call(pci_int_handlers[i]); + *(dev.uncached_alias + LAPIC_EOI)(U32 *) = 0; } -MemSet(&@pci_int_handler, NULL, sizeof(U64) * PCI_INTH_MAX); -// IntEntrySet(0x40, &@pci_interrupt_handler, IDTET_IRQ); -// IntEntrySet(0x41, &@pci_interrupt_handler, IDTET_IRQ); -// IntEntrySet(0x42, &@pci_interrupt_handler, IDTET_IRQ); -// IntEntrySet(0x43, &@pci_interrupt_handler, IDTET_IRQ); -//@pci_reroute_interrupts(0x40, 0); \ No newline at end of file +MemSet(&pci_int_handlers, NULL, sizeof(U64) * PCI_INTH_MAX); +// IntEntrySet(0x40, &PCIInterruptHandler, IDTET_IRQ); +// IntEntrySet(0x41, &PCIInterruptHandler, IDTET_IRQ); +// IntEntrySet(0x42, &PCIInterruptHandler, IDTET_IRQ); +// IntEntrySet(0x43, &PCIInterruptHandler, IDTET_IRQ); +//PCIInterruptReroute(0x40, 0); \ No newline at end of file From 027edae2968120a1e7d4fcf26cf9b997e35b8cda Mon Sep 17 00:00:00 2001 From: TomAwezome Date: Sat, 24 Dec 2022 16:27:18 -0500 Subject: [PATCH 06/23] Fix AC97 PCI var names. --- src/Home/Sound/AC97/AC97.ZC | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Home/Sound/AC97/AC97.ZC b/src/Home/Sound/AC97/AC97.ZC index 15439fbbf..164399935 100644 --- a/src/Home/Sound/AC97/AC97.ZC +++ b/src/Home/Sound/AC97/AC97.ZC @@ -53,7 +53,7 @@ class CAC97BufferDescriptorList class CAC97 { - @pci_info pci; + CPCIInfo pci; CAC97BufferDescriptorList *bdl[3]; U16 nam; U16 nabm; @@ -174,7 +174,7 @@ I64 AC97Init() return -1; } - @get_pci_info(j, &ac97.pci); + PCIInfoGet(j, &ac97.pci); if (ac97.pci.vendor_id != 0x8086 || ac97.pci.device_id != 0x2415) goto device_not_found; From 55d95ee3d3b417444694c65839f2d592115ca80e Mon Sep 17 00:00:00 2001 From: TomAwezome Date: Sat, 24 Dec 2022 19:42:49 -0500 Subject: [PATCH 07/23] Fix HDAudio BeatFreq.ZC enough to compile. --- src/Home/Sound/HDAudio1/Sup1HDAudio/Examples/BeatFreq.ZC | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Home/Sound/HDAudio1/Sup1HDAudio/Examples/BeatFreq.ZC b/src/Home/Sound/HDAudio1/Sup1HDAudio/Examples/BeatFreq.ZC index 745073f21..b6b72f442 100644 --- a/src/Home/Sound/HDAudio1/Sup1HDAudio/Examples/BeatFreq.ZC +++ b/src/Home/Sound/HDAudio1/Sup1HDAudio/Examples/BeatFreq.ZC @@ -53,8 +53,9 @@ U0 BeatFreq() "Pick two frequencies a multiple of two for an octave harmonic.\n" "$$FG,GREEN$$$$FG$$ to exit.\n"; while (TRUE) { - freq1=PmtF64("Freq #1 (%0.2fHz):",freq1,20,20000); - freq2=PmtF64("Freq #2 (%0.2fHz):",freq2,20,20000); + freq1=440.0;//PmtF64("Freq #1 (%0.2fHz):",freq1,20,20000); + freq2=880.0;//PmtF64("Freq #2 (%0.2fHz):",freq2,20,20000); + Sleep(200); } } catch { //Catch , but pass it on to next higher handler. fp_snd_fill_buf=fp_old_fill_buf; From 8200205781da464688303787fcc3f247c5d1cc95 Mon Sep 17 00:00:00 2001 From: TomAwezome Date: Sat, 24 Dec 2022 19:43:10 -0500 Subject: [PATCH 08/23] Fix HDAudio Synth.ZC enough to compile. --- .../HDAudio1/Sup1HDAudio/Examples/Synth.ZC | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/Home/Sound/HDAudio1/Sup1HDAudio/Examples/Synth.ZC b/src/Home/Sound/HDAudio1/Sup1HDAudio/Examples/Synth.ZC index 1d197f801..48b2b47fc 100644 --- a/src/Home/Sound/HDAudio1/Sup1HDAudio/Examples/Synth.ZC +++ b/src/Home/Sound/HDAudio1/Sup1HDAudio/Examples/Synth.ZC @@ -104,30 +104,38 @@ U0 DrawIt(CTask *task,CDC *dc) Line(NULL, (last_x-task->pix_left-task->scroll_x)*WF_BUF_LEN/h_max, WF_Y_SCALE*(cy-last_y+task->pix_top+task->scroll_y)/cy,0, - ( msx-task->pix_left-task->scroll_x)*WF_BUF_LEN/h_max, - WF_Y_SCALE*(cy-msy+task->pix_top+task->scroll_y)/cy,0, +// ( msx-task->pix_left-task->scroll_x)*WF_BUF_LEN/h_max, + ( mouse.pos.x-task->pix_left-task->scroll_x)*WF_BUF_LEN/h_max, +// WF_Y_SCALE*(cy-msy+task->pix_top+task->scroll_y)/cy,0, + WF_Y_SCALE*(cy-mouse.pos.y+task->pix_top+task->scroll_y)/cy,0, &WFPlot); break; case M_FREQUENCY: Line(NULL, (last_x-task->pix_left-task->scroll_x)*FQ_BUF_LEN/h_max, FQ_Y_SCALE*(cy-last_y+task->pix_top+task->scroll_y)/cy,0, - ( msx-task->pix_left-task->scroll_x)*FQ_BUF_LEN/h_max, - FQ_Y_SCALE*(cy-msy+task->pix_top+task->scroll_y)/cy,0, +// ( msx-task->pix_left-task->scroll_x)*FQ_BUF_LEN/h_max, + ( mouse.pos.x-task->pix_left-task->scroll_x)*FQ_BUF_LEN/h_max, +// FQ_Y_SCALE*(cy-msy+task->pix_top+task->scroll_y)/cy,0, + FQ_Y_SCALE*(cy-mouse.pos.y+task->pix_top+task->scroll_y)/cy,0, &FQPlot); break; case M_ENVELOPE: Line(NULL, (last_x-task->pix_left-task->scroll_x)*EL_BUF_LEN/h_max, EL_Y_SCALE*(cy-last_y+task->pix_top+task->scroll_y)/cy,0, - ( msx-task->pix_left-task->scroll_x)*EL_BUF_LEN/h_max, - EL_Y_SCALE*(cy-msy+task->pix_top+task->scroll_y)/cy,0, +// ( msx-task->pix_left-task->scroll_x)*EL_BUF_LEN/h_max, + ( mouse.pos.x-task->pix_left-task->scroll_x)*EL_BUF_LEN/h_max, +// EL_Y_SCALE*(cy-msy+task->pix_top+task->scroll_y)/cy,0, + EL_Y_SCALE*(cy-mouse.pos.y+task->pix_top+task->scroll_y)/cy,0, &ELPlot); break; } my_ms_down=TRUE; - last_x=msx; - last_y=msy; +// last_x=msx; +// last_y=msy; + last_x=mouse.pos.x; + last_y=mouse.pos.y; } else my_ms_down=FALSE; } From 2fd8527fdb29ff3926c88415494457a1530f1128 Mon Sep 17 00:00:00 2001 From: TomAwezome Date: Mon, 26 Dec 2022 20:35:38 -0500 Subject: [PATCH 09/23] Document HDAudio/AC97 sound API currently in use. --- src/Home/Sound/API.DD | 102 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 src/Home/Sound/API.DD diff --git a/src/Home/Sound/API.DD b/src/Home/Sound/API.DD new file mode 100644 index 000000000..9b6c695f4 --- /dev/null +++ b/src/Home/Sound/API.DD @@ -0,0 +1,102 @@ + + + AC97 Functions: + +AudioInit +AudioAvailableOutputStreamGet +AudioSFXPlay +AC97OutputMix +AC97BufferFill +AC97AudioProcess +AC97Init +AC97Task + + AC97 Pci.ZC Functions: + +PCIInfoGet +PCIGetCapability +PCIInterruptReroute +PCIInterruptHandlerRegister +PCIInterruptHandler + + +================================================ + + HDAudio MakeSnd Functions: + +SoundTaskEndCB + + HDAudio SndMath Functions: + +Saw +FullSaw +Caw +FullCaw +Tri +FullTri +Note2Ona +Ona2Note +Ona2Octave +SinPhaseCont +SndWaveCtrlNew +SndWaveCtrlDel +SndWaveAddBuf + + HDAudio SndMusic Functions: + +tM +Beat +MusicSetOctave +MusicSetMeter +MusicSetNoteLen +Play +MusicSettingsReset +CurSongTask + + + HDAudio SndEffects Functions: + +SoundEffectEndTaskCB +SoundEffectTask +Noise +Sweep + + + HDAudio SndFile Functions: + +SndFileCreate + + HDAudio Functions: + +HDSyncCORB +HDWriteCORB +HDSyncRIRB +HDReadRIRB +HDWriteCORBSync +HDTestCORBSync +HDTraverse +HDRun +HDStop +HDSnd +HDFillBuf +HDAudioTaskEndCB +HDTonesInit +HDAudioTask +HDRst +HDAudioEnd +HDAudioUncachedInit +HDAudioInit +HDAudioScan + + HDAudio Cfg Functions: + +HDCfgConnectList +HDCfgTraverse +HDCfgRandomizeXYZ +HDCfgPopUpInfoTask +HDCfgPopUpInfo +HDCfgEdLink +HDCfgSave +HDCfg + +================================================ \ No newline at end of file From f2490f75bcd769f03a010c9cd5508a727b8794f5 Mon Sep 17 00:00:00 2001 From: TomAwezome Date: Wed, 28 Dec 2022 18:18:53 -0500 Subject: [PATCH 10/23] Reformat HDAudio.ZC --- .../Sound/HDAudio1/Sup1HDAudio/HDAudio.ZC | 519 ++++++++++-------- 1 file changed, 275 insertions(+), 244 deletions(-) diff --git a/src/Home/Sound/HDAudio1/Sup1HDAudio/HDAudio.ZC b/src/Home/Sound/HDAudio1/Sup1HDAudio/HDAudio.ZC index 71ade9595..24042dd12 100644 --- a/src/Home/Sound/HDAudio1/Sup1HDAudio/HDAudio.ZC +++ b/src/Home/Sound/HDAudio1/Sup1HDAudio/HDAudio.ZC @@ -1,239 +1,262 @@ //SysFile("~/sup1hdaudio/Sup1CodeScraps/Mem/Mem2Meg.ZC"); -# -help_index "Sound/HDAudio" +#help_index "Sound/HDAudio" //snd devs -#define SD_PC_SPEAKER 0 -#define SD_HD_AUDIO 1 -#define SND_SAMPLE_RATE 48000 -#define SND_SAMPLE_BITS 24 -#define SND_OCHANNELS 2 -#define SND_ICHANNELS 2 -#define SND_OUT_CONTAINER I32 -#define SND_IN_CONTAINER I16 -#define SND_BUF_LEN 0x400 -#define SND_BUF_TIME_mS(SND_BUF_LEN / SND_OCHANNELS *1000.0 / \ - SND_SAMPLE_RATE) +#define SD_PC_SPEAKER 0 +#define SD_HD_AUDIO 1 + +#define SND_SAMPLE_RATE 48000 +#define SND_SAMPLE_BITS 24 +#define SND_OCHANNELS 2 +#define SND_ICHANNELS 2 +#define SND_OUT_CONTAINER I32 +#define SND_IN_CONTAINER I16 +#define SND_BUF_LEN 0x400 +#define SND_BUF_TIME_mS (SND_BUF_LEN / SND_OCHANNELS * 1000.0 / SND_SAMPLE_RATE) F64 snd_freq = 0; I64 snd_dev = SD_PC_SPEAKER; Bool snd_record = FALSE; F64 snd_vol = 0.1; -U0(*fp_snd)(F64 freq, I64 waveform, F64 amp) = NULL; -U0(*fp_snd_record)(F64 freq, I64 waveform, F64 amp) = NULL; -U0(*fp_snd_fill_buf)(SND_OUT_CONTAINER *buf, I64 buf_num) = NULL; -U0(*fp_snd_copy_buf)(SND_IN_CONTAINER *buf, I64 buf_num) = NULL; +U0 (*fp_snd) (F64 freq, I64 waveform, F64 amp) = NULL; +U0 (*fp_snd_record)(F64 freq, I64 waveform, F64 amp) = NULL; +U0 (*fp_snd_fill_buf)(SND_OUT_CONTAINER *buf, I64 buf_num) = NULL; +U0 (*fp_snd_copy_buf)(SND_IN_CONTAINER *buf, I64 buf_num) = NULL; I64 snd_obuf_num, snd_ibuf_num; #define Sf_FILLING_OUT 0 I64 snd_flags; -#define HD_1_CHAN 0 -#define HD_2_CHAN 1 -#define HD_3_CHAN 2 -#define HD_4_CHAN 3 -#define HD_8_BIT 0 -#define HD_16_BIT 1 -#define HD_20_BIT 2 -#define HD_24_BIT 3 -#define HD_32_BIT 4 -#define HD_48kHz 0 -#define HD_DFT_OUT_FMT(HD_2_CHAN + HD_24_BIT << 4 + HD_48kHz << 8) -#define HD_DFT_IN_FMT(HD_2_CHAN + HD_16_BIT << 4 + HD_48kHz << 8) +#define HD_1_CHAN 0 +#define HD_2_CHAN 1 +#define HD_3_CHAN 2 +#define HD_4_CHAN 3 + +#define HD_8_BIT 0 +#define HD_16_BIT 1 +#define HD_20_BIT 2 +#define HD_24_BIT 3 +#define HD_32_BIT 4 +#define HD_48kHz 0 + +#define HD_DFT_OUT_FMT (HD_2_CHAN + HD_24_BIT << 4 + HD_48kHz << 8) +#define HD_DFT_IN_FMT (HD_2_CHAN + HD_16_BIT << 4 + HD_48kHz << 8) + #define HD_POS_BUF_MULTIPLES 0x1000 -#define HD_CORB_ENTRIES 256 -#define HD_RIRB_ENTRIES 256 -#define HD_BDL_ENTRIES 256 -#define HD_GCTL 0x08 -#define HD_STATESTS 0x0E -#define HD_GSTS 0x10 -#define HD_CORBLBASE 0x40 -#define HD_CORBUBASE 0x44 -#define HD_CORBWP 0x48 -#define HD_CORBRP 0x4A -#define HD_CORBCTL 0x4C -#define HD_CORBST 0x4D -#define HD_RIRBLBASE 0x50 -#define HD_RIRBUBASE 0x54 -#define HD_RIRBWP 0x58 -#define HD_RIRBCTL 0x5C -#define HD_RIRBSTS 0x5D -#define STRCTL 0x00 -#define STRSTS 0x03 -#define STRLPIB 0x04 -#define STRCBL 0x08 -#define STRLVI 0x0C -#define STRFIFOW 0x0E -#define STRFIFOS 0x10 -#define STRFMT 0x12 -#define STRBDPL 0x18 -#define STRBDPU 0x1C -#define ISTR0 0x080 -#define ISTR1 0x0A0 -#define ISTR2 0x0C0 -#define ISTR3 0x0E0 -#define OSTR0 0x100 -#define OSTR1 0x120 -#define OSTR2 0x140 -#define OSTR3 0x160 -#define VERB_GET_PARAM 0xF0000 -#define VERB_CONNECT_SEL_GET 0xF0100 -#define VERB_CONNECT_SEL_SET 0x70100 -#define VERB_GET_CONNECT_LST 0xF0200 -#define VERB_PROCESS_STATE_GET 0xF0300 -#define VERB_PROCESS_STATE_SET 0x70300 -#define VERB_COEFF_IDX_GET 0xD0000 -#define VERB_COEFF_IDX_SET 0x50000 -#define VERB_PROCESS_COEFF_GET 0xC0000 -#define VERB_PROCESS_COEFF_SET 0x40000 -#define VERB_AMPLIFIER_GAIN_GET 0xB0000 -#define VERB_AMPLIFIER_GAIN_SET 0x30000 -#define VERB_STREAM_FMT_GET 0xA0000 -#define VERB_STREAM_FMT_SET 0x20000 -#define VERB_DIGIT_CONVERT1_GET 0xF0D00 -#define VERB_DIGIT_CONVERT1_SET 0x70D00 -#define VERB_DIGIT_CONVERT2_GET 0xF0D00 -#define VERB_DIGIT_CONVERT2_SET 0x70E00 -#define VERB_POWER_STATE_GET 0xF0500 -#define VERB_POWER_STATE_SET 0x70500 -#define VERB_CHAN_STREAM_ID_GET 0xF0600 -#define VERB_CHAN_STREAM_ID_SET 0x70600 -#define VERB_SDI_SEL_GET 0xF0400 -#define VERB_SDI_SEL_SET 0x70400 -#define VERB_PIN_WIDGET_CTL_GET 0xF0700 -#define VERB_PIN_WIDGET_CTL_SET 0x70700 -#define VERB_UNSOL_ENABLE_GET 0xF0800 -#define VERB_UNSOL_ENABLE_SET 0x70800 -#define VERB_PIN_SENSE_GET 0xF0900 -#define VERB_PIN_SENSE_SET 0x70900 -#define VERB_EAPDBTL_ENABLE_GET 0xF0C00 -#define VERB_EAPDBTL_ENABLE_SET 0x70C00 -#define VERB_BEEP_CTL_GET 0xF0A00 -#define VERB_BEEP_CTL_SET 0x70A00 -#define VERB_GPI_CTRL0_GET 0xF1000 -#define VERB_GPI_CTRL0_SET 0x71000 -#define VERB_GPI_CTRL1_GET 0xF1100 -#define VERB_GPI_CTRL1_SET 0x71100 -#define VERB_GPI_CTRL2_GET 0xF1200 -#define VERB_GPI_CTRL2_SET 0x71200 -#define VERB_GPI_CTRL3_GET 0xF1300 -#define VERB_GPI_CTRL3_SET 0x71300 -#define VERB_GPI_CTRL4_GET 0xF1400 -#define VERB_GPI_CTRL4_SET 0x71400 -#define VERB_GPI_CTRL5_GET 0xF1500 -#define VERB_GPI_CTRL5_SET 0x71500 -#define VERB_GPI_CTRL6_GET 0xF1600 -#define VERB_GPI_CTRL6_SET 0x71600 -#define VERB_GPI_CTRL7_GET 0xF1700 -#define VERB_GPI_CTRL7_SET 0x71700 -#define VERB_GPI_CTRL8_GET 0xF1800 -#define VERB_GPI_CTRL8_SET 0x71800 -#define VERB_GPI_CTRL9_GET 0xF1900 -#define VERB_GPI_CTRL9_SET 0x71900 -#define VERB_GPI_CTRLA_GET 0xF1A00 -#define VERB_GPI_CTRLA_SET 0x71A00 -#define VERB_VOL_CTL_GET 0xF0F00 -#define VERB_VOL_CTL_SET 0x70F00 -#define VERB_SUB_SYS_ID0_GET 0xF2000 -#define VERB_SUB_SYS_ID0_SET 0x72000 -#define VERB_SUB_SYS_ID1_GET 0xF2000 -#define VERB_SUB_SYS_ID1_SET 0x72100 -#define VERB_SUB_SYS_ID2_GET 0xF2000 -#define VERB_SUB_SYS_ID2_SET 0x72200 -#define VERB_SUB_SYS_ID3_GET 0xF2000 -#define VERB_SUB_SYS_ID3_SET 0x72300 -#define VERB_CFG_DFT0_GET 0xF1C00 -#define VERB_CFG_DFT0_SET 0x71C00 -#define VERB_CFG_DFT1_GET 0xF1C00 -#define VERB_CFG_DFT1_SET 0x71D00 -#define VERB_CFG_DFT2_GET 0xF1C00 -#define VERB_CFG_DFT2_SET 0x71E00 -#define VERB_CFG_DFT3_GET 0xF1C00 -#define VERB_CFG_DFT3_SET 0x71F00 -#define VERB_STRIPE_CTL_GET 0xF2400 -#define VERB_STRIPE_CTL_SET 0x72400 -#define VERB_RST 0x7FF00 + +#define HD_CORB_ENTRIES 256 +#define HD_RIRB_ENTRIES 256 +#define HD_BDL_ENTRIES 256 + +#define HD_GCTL 0x08 +#define HD_STATESTS 0x0E +#define HD_GSTS 0x10 +#define HD_CORBLBASE 0x40 +#define HD_CORBUBASE 0x44 +#define HD_CORBWP 0x48 +#define HD_CORBRP 0x4A +#define HD_CORBCTL 0x4C +#define HD_CORBST 0x4D +#define HD_RIRBLBASE 0x50 +#define HD_RIRBUBASE 0x54 +#define HD_RIRBWP 0x58 +#define HD_RIRBCTL 0x5C +#define HD_RIRBSTS 0x5D + +#define STRCTL 0x00 +#define STRSTS 0x03 +#define STRLPIB 0x04 +#define STRCBL 0x08 +#define STRLVI 0x0C +#define STRFIFOW 0x0E +#define STRFIFOS 0x10 +#define STRFMT 0x12 +#define STRBDPL 0x18 +#define STRBDPU 0x1C +#define ISTR0 0x080 +#define ISTR1 0x0A0 +#define ISTR2 0x0C0 +#define ISTR3 0x0E0 +#define OSTR0 0x100 +#define OSTR1 0x120 +#define OSTR2 0x140 +#define OSTR3 0x160 + +#define VERB_GET_PARAM 0xF0000 +#define VERB_CONNECT_SEL_GET 0xF0100 +#define VERB_CONNECT_SEL_SET 0x70100 +#define VERB_GET_CONNECT_LST 0xF0200 +#define VERB_PROCESS_STATE_GET 0xF0300 +#define VERB_PROCESS_STATE_SET 0x70300 +#define VERB_COEFF_IDX_GET 0xD0000 +#define VERB_COEFF_IDX_SET 0x50000 +#define VERB_PROCESS_COEFF_GET 0xC0000 +#define VERB_PROCESS_COEFF_SET 0x40000 +#define VERB_AMPLIFIER_GAIN_GET 0xB0000 +#define VERB_AMPLIFIER_GAIN_SET 0x30000 +#define VERB_STREAM_FMT_GET 0xA0000 +#define VERB_STREAM_FMT_SET 0x20000 +#define VERB_DIGIT_CONVERT1_GET 0xF0D00 +#define VERB_DIGIT_CONVERT1_SET 0x70D00 +#define VERB_DIGIT_CONVERT2_GET 0xF0D00 +#define VERB_DIGIT_CONVERT2_SET 0x70E00 +#define VERB_POWER_STATE_GET 0xF0500 +#define VERB_POWER_STATE_SET 0x70500 +#define VERB_CHAN_STREAM_ID_GET 0xF0600 +#define VERB_CHAN_STREAM_ID_SET 0x70600 +#define VERB_SDI_SEL_GET 0xF0400 +#define VERB_SDI_SEL_SET 0x70400 +#define VERB_PIN_WIDGET_CTL_GET 0xF0700 +#define VERB_PIN_WIDGET_CTL_SET 0x70700 +#define VERB_UNSOL_ENABLE_GET 0xF0800 +#define VERB_UNSOL_ENABLE_SET 0x70800 +#define VERB_PIN_SENSE_GET 0xF0900 +#define VERB_PIN_SENSE_SET 0x70900 +#define VERB_EAPDBTL_ENABLE_GET 0xF0C00 +#define VERB_EAPDBTL_ENABLE_SET 0x70C00 +#define VERB_BEEP_CTL_GET 0xF0A00 +#define VERB_BEEP_CTL_SET 0x70A00 +#define VERB_GPI_CTRL0_GET 0xF1000 +#define VERB_GPI_CTRL0_SET 0x71000 +#define VERB_GPI_CTRL1_GET 0xF1100 +#define VERB_GPI_CTRL1_SET 0x71100 +#define VERB_GPI_CTRL2_GET 0xF1200 +#define VERB_GPI_CTRL2_SET 0x71200 +#define VERB_GPI_CTRL3_GET 0xF1300 +#define VERB_GPI_CTRL3_SET 0x71300 +#define VERB_GPI_CTRL4_GET 0xF1400 +#define VERB_GPI_CTRL4_SET 0x71400 +#define VERB_GPI_CTRL5_GET 0xF1500 +#define VERB_GPI_CTRL5_SET 0x71500 +#define VERB_GPI_CTRL6_GET 0xF1600 +#define VERB_GPI_CTRL6_SET 0x71600 +#define VERB_GPI_CTRL7_GET 0xF1700 +#define VERB_GPI_CTRL7_SET 0x71700 +#define VERB_GPI_CTRL8_GET 0xF1800 +#define VERB_GPI_CTRL8_SET 0x71800 +#define VERB_GPI_CTRL9_GET 0xF1900 +#define VERB_GPI_CTRL9_SET 0x71900 +#define VERB_GPI_CTRLA_GET 0xF1A00 +#define VERB_GPI_CTRLA_SET 0x71A00 +#define VERB_VOL_CTL_GET 0xF0F00 +#define VERB_VOL_CTL_SET 0x70F00 +#define VERB_SUB_SYS_ID0_GET 0xF2000 +#define VERB_SUB_SYS_ID0_SET 0x72000 +#define VERB_SUB_SYS_ID1_GET 0xF2000 +#define VERB_SUB_SYS_ID1_SET 0x72100 +#define VERB_SUB_SYS_ID2_GET 0xF2000 +#define VERB_SUB_SYS_ID2_SET 0x72200 +#define VERB_SUB_SYS_ID3_GET 0xF2000 +#define VERB_SUB_SYS_ID3_SET 0x72300 +#define VERB_CFG_DFT0_GET 0xF1C00 +#define VERB_CFG_DFT0_SET 0x71C00 +#define VERB_CFG_DFT1_GET 0xF1C00 +#define VERB_CFG_DFT1_SET 0x71D00 +#define VERB_CFG_DFT2_GET 0xF1C00 +#define VERB_CFG_DFT2_SET 0x71E00 +#define VERB_CFG_DFT3_GET 0xF1C00 +#define VERB_CFG_DFT3_SET 0x71F00 +#define VERB_STRIPE_CTL_GET 0xF2400 +#define VERB_STRIPE_CTL_SET 0x72400 +#define VERB_RST 0x7FF00 //Parameters -#define P_VENDOR_ID 0x00 -#define P_REVISION_ID 0x02 -#define P_SUBNODE_CNT 0x04 -#define P_FUN_GRP_TYPE 0x05 -#define P_AUDIO_FUN_CAP 0x08 -#define P_AUDIO_WIDGET_CAP 0x09 -#define P_SAMPLE_SIZE_RATE_CAP 0x0A -#define P_STREAM_FMTS 0x0B -#define P_PIN_CAP 0x0C -#define P_INPUT_AMP_CAP 0x0D -#define P_OUTPUT_AMP_CAP 0x12 -#define P_CONNECT_LST_LEN 0x0E -#define P_POWER_STATES 0x0F -#define P_PROCESSING_CAP 0x10 -#define P_GPIO_CNT 0x11 -#define P_VOL_KNOB_CAP 0x13 +#define P_VENDOR_ID 0x00 +#define P_REVISION_ID 0x02 +#define P_SUBNODE_CNT 0x04 +#define P_FUN_GRP_TYPE 0x05 +#define P_AUDIO_FUN_CAP 0x08 +#define P_AUDIO_WIDGET_CAP 0x09 +#define P_SAMPLE_SIZE_RATE_CAP 0x0A +#define P_STREAM_FMTS 0x0B +#define P_PIN_CAP 0x0C +#define P_INPUT_AMP_CAP 0x0D +#define P_OUTPUT_AMP_CAP 0x12 +#define P_CONNECT_LST_LEN 0x0E +#define P_POWER_STATES 0x0F +#define P_PROCESSING_CAP 0x10 +#define P_GPIO_CNT 0x11 +#define P_VOL_KNOB_CAP 0x13 //Function Group Types //00 reserved -#define FGT_AUDIO 1 -#define FGT_VENDOR_MODEM 2 +#define FGT_AUDIO 1 +#define FGT_VENDOR_MODEM 2 //03-7F reserved //80-FF vendor function group //Audio Widget Types -#define AWT_OUTPUT 0x0 -#define AWT_INPUT 0x1 -#define AWT_MIXER 0x2 -#define AWT_SELECTOR 0x3 -#define AWT_PIN_COMPLEX 0x4 -#define AWT_POWER_WIDGET 0x5 +#define AWT_OUTPUT 0x0 +#define AWT_INPUT 0x1 +#define AWT_MIXER 0x2 +#define AWT_SELECTOR 0x3 +#define AWT_PIN_COMPLEX 0x4 +#define AWT_POWER_WIDGET 0x5 #define AWT_VOL_KNOB_WIDGET 0x6 #define AWT_BEEP_GEN_WIDGET 0x7 -#define AWT_VENDOR 0xF -#define AWT_NODE 0x10 +#define AWT_VENDOR 0xF +#define AWT_NODE 0x10 DefineListLoad("ST_AUDIO_WIDGET_TYPES", - "Output\0Input\0Mixer\0Sellector\0Pin Complex\0" - "Power Widget\0Vol Knob\0Beep Gen\0\0\0\0\0\0\0\0Vendor\0Node\0"); + "Output\0" + "Input\0" + "Mixer\0" + "Selector\0" + "Pin Complex\0" + "Power Widget\0" + "Vol Knob\0" + "Beep Gen\0" + " \0" + " \0" + " \0" + " \0" + " \0" + " \0" + " \0" + "Vendor\0" + "Node\0"); class CHDBufDesc { - I32 * buf; - U32 len; - U32 ctrl; + I32 *buf; + U32 len; + U32 ctrl; }; #define HD_TONES 8 class CHDAudioCtrl { - U8 * bar; - CBlkPool * bp; - CHeapCtrl * hc; - I64 cad; - U32 * corb; - I64 * rirb; - CHDBufDesc *ostr0_bdl, *istr0_bdl; - SND_OUT_CONTAINER *ostr0_buf[2], *o_tmp_buf; - SND_IN_CONTAINER *istr0_buf[2]; - CTask * task; - I64 waveform; - F64 freq, amp; - CSndWaveCtrl *tone_swcs[HD_TONES]; - U8 rirb_rp, corb_wp; - Bool audio_task_started, in_running, out_running; -} + U8 *bar; + CBlkPool *bp; + CHeapCtrl *hc; + I64 cad; + U32 *corb; + I64 *rirb; + CHDBufDesc *ostr0_bdl, + *istr0_bdl; + SND_OUT_CONTAINER *ostr0_buf[2], + *o_tmp_buf; + SND_IN_CONTAINER *istr0_buf[2]; + CTask *task; + I64 waveform; + F64 freq, amp; + CSndWaveCtrl *tone_swcs[HD_TONES]; + U8 rirb_rp, corb_wp; + Bool audio_task_started, in_running, out_running; +} hda; -hda; MemSet(&hda, 0, sizeof(CHDAudioCtrl)); U0 HDSyncCORB() { U16 *wp, *rp; + wp = hda.bar + HD_CORBWP; *wp = hda.corb_wp; rp = hda.bar + HD_CORBRP; - while (*rp &255 != hda.corb_wp) + while (*rp & 255 != hda.corb_wp) Yield; } @@ -245,25 +268,30 @@ U0 HDWriteCORB(I64 cad, I64 nid, U32 val) I64 HDSyncRIRB() { - U16 * _w; + U16 *_w; I64 wp, res = 0; + _w = hda.bar + HD_RIRBWP; wp = *_w; while (hda.rirb_rp != wp) res = hda.rirb[++hda.rirb_rp]; + return res; } I64 HDReadRIRB() { - U16 * _w; + U16 *_w; I64 wp, res = 0; + _w = hda.bar + HD_RIRBWP; - do { + do + { Yield; wp = *_w; } while (wp == hda.rirb_rp); res = hda.rirb[++hda.rirb_rp]; + return res; } @@ -279,7 +307,7 @@ I64 HDWriteCORBSync(I64 cad, I64 nid, U32 val) Bool HDTestCORBSync(I64 cad, I64 nid, U32 val) { //Checks for a response - U16 * _w; + U16 *_w; I64 wp; HDSyncCORB; @@ -293,6 +321,7 @@ Bool HDTestCORBSync(I64 cad, I64 nid, U32 val) if (wp == hda.rirb_rp) return FALSE; HDReadRIRB; + return TRUE; } @@ -312,9 +341,9 @@ U0 HDTraverse(I64 cad, I64 nid) else { aud_cap = HDWriteCORBSync(cad, nid, VERB_GET_PARAM + P_AUDIO_WIDGET_CAP); - type = aud_cap >> 20 &15; + type = aud_cap >> 20 & 15; if (Bt(&aud_cap, 8)) - len = HDWriteCORBSync(cad, nid, VERB_GET_PARAM + P_CONNECT_LST_LEN) &127; + len = HDWriteCORBSync(cad, nid, VERB_GET_PARAM + P_CONNECT_LST_LEN) & 127; else len = 0; HDWriteCORBSync(cad, nid, VERB_AMPLIFIER_GAIN_SET + 0xF07F); //set I/O amp #0 @@ -324,7 +353,7 @@ U0 HDTraverse(I64 cad, I64 nid) switch (type) { case AWT_OUTPUT: - if (FALSE) //if disabled + if (FALSE) //if disabled // ???? HDWriteCORBSync(cad, nid, VERB_CHAN_STREAM_ID_SET + 0x00); else HDWriteCORBSync(cad, nid, VERB_CHAN_STREAM_ID_SET + 0x10); @@ -332,7 +361,7 @@ U0 HDTraverse(I64 cad, I64 nid) HDWriteCORBSync(cad, nid, VERB_PROCESS_STATE_SET + 0x01); break; case AWT_INPUT: - if (TRUE) //if disabled + if (TRUE) //if disabled // ???? HDWriteCORBSync(cad, nid, VERB_CHAN_STREAM_ID_SET + 0x00); else HDWriteCORBSync(cad, nid, VERB_CHAN_STREAM_ID_SET + 0x20); @@ -348,7 +377,7 @@ U0 HDTraverse(I64 cad, I64 nid) U0 HDRun(Bool in, Bool out) { - U32 * _d; + U32 *_d; if (hda.bar) { if (out) @@ -369,7 +398,7 @@ U0 HDRun(Bool in, Bool out) U0 HDStop(Bool in, Bool out) { - U32 * _d; + U32 *_d; if (hda.bar) { if (out) @@ -397,20 +426,20 @@ U0 HDSnd(F64 freq, I64 waveform = WF_SQUARE, F64 amp = 1.0) U0 HDFillBuf(SND_OUT_CONTAINER *buf, I64) { - I64 i, size = SND_BUF_LEN* sizeof(SND_OUT_CONTAINER); + I64 i, size = SND_BUF_LEN * sizeof(SND_OUT_CONTAINER); + if (!hda.o_tmp_buf) hda.o_tmp_buf = SysMAlloc(size); MemSet(hda.o_tmp_buf, 0, size); for (i = 0; i < HD_TONES; i++) - SndWaveAddBuf(hda.tone_swcs[i], hda.o_tmp_buf, - SND_BUF_LEN / SND_OCHANNELS, hda.freq, - hda.waveform, snd_vol *hda.amp); + SndWaveAddBuf(hda.tone_swcs[i], hda.o_tmp_buf, SND_BUF_LEN / SND_OCHANNELS, hda.freq, hda.waveform, snd_vol * hda.amp); MemCopy(buf, hda.o_tmp_buf, size); } U0 HDAudioTaskEndCB() { I64 i; + HDStop(FALSE, TRUE); fp_snd = NULL; for (i = 0; i < HD_TONES; i++) @@ -425,6 +454,7 @@ U0 HDAudioTaskEndCB() public U0 HDTonesInit() { I64 i; + if (hda.bar) { for (i = 0; i < HD_TONES; i++) @@ -442,12 +472,13 @@ U0 HDAudioTask(I64) //I didn't feel like messing around with PCI interrupts //so this task polls every millisecond to know when to //switch buffers. - I64 i, next_obuf_trigger = SND_BUF_LEN* sizeof(SND_OUT_CONTAINER) / 2, + I64 i, next_obuf_trigger = SND_BUF_LEN * sizeof(SND_OUT_CONTAINER) / 2, obuf_rollover = 0, - next_ibuf_trigger = SND_BUF_LEN* sizeof(SND_IN_CONTAINER), + next_ibuf_trigger = SND_BUF_LEN * sizeof(SND_IN_CONTAINER), ibuf_rollover = 0; U32 *pos_in_obuf = hda.bar + OSTR0 + STRLPIB, *pos_in_ibuf = hda.bar + ISTR0 + STRLPIB; + Fs->task_end_cb = &HDAudioTaskEndCB; for (i = 0; i < HD_TONES; i++) hda.tone_swcs[i] = SndWaveCtrlNew; @@ -463,35 +494,32 @@ U0 HDAudioTask(I64) hda.audio_task_started = TRUE; //This flag is probably not necessary while (TRUE) { - if (next_obuf_trigger - obuf_rollover <= *pos_in_obuf< next_obuf_trigger - obuf_rollover + - (HD_POS_BUF_MULTIPLES - 1) *SND_BUF_LEN* sizeof(SND_OUT_CONTAINER)) + if (next_obuf_trigger - obuf_rollover <= + *pos_in_obuf < + next_obuf_trigger - obuf_rollover + (HD_POS_BUF_MULTIPLES - 1) * SND_BUF_LEN * sizeof(SND_OUT_CONTAINER)) { - next_obuf_trigger += SND_BUF_LEN* sizeof(SND_OUT_CONTAINER); - if (next_obuf_trigger - obuf_rollover >= - HD_POS_BUF_MULTIPLES *SND_BUF_LEN* sizeof(SND_OUT_CONTAINER)) - obuf_rollover += HD_POS_BUF_MULTIPLES *SND_BUF_LEN * - sizeof(SND_OUT_CONTAINER); + next_obuf_trigger += SND_BUF_LEN * sizeof(SND_OUT_CONTAINER); + if (next_obuf_trigger - obuf_rollover >= HD_POS_BUF_MULTIPLES * SND_BUF_LEN * sizeof(SND_OUT_CONTAINER)) + obuf_rollover += HD_POS_BUF_MULTIPLES * SND_BUF_LEN * sizeof(SND_OUT_CONTAINER); if (fp_snd_fill_buf) { LBts(&snd_flags, Sf_FILLING_OUT); (*fp_snd_fill_buf)(hda.ostr0_buf[snd_obuf_num & 1], snd_obuf_num); if (IsMute) - MemSet(hda.ostr0_buf[snd_obuf_num & 1], 0, - SND_BUF_LEN* sizeof(SND_OUT_CONTAINER)); + MemSet(hda.ostr0_buf[snd_obuf_num & 1], 0, SND_BUF_LEN * sizeof(SND_OUT_CONTAINER)); LBtr(&snd_flags, Sf_FILLING_OUT); } snd_obuf_num++; } - if (next_ibuf_trigger - ibuf_rollover <= *pos_in_ibuf< next_ibuf_trigger - ibuf_rollover + (HD_POS_BUF_MULTIPLES - 1) * - SND_BUF_LEN* sizeof(SND_IN_CONTAINER)) + if (next_ibuf_trigger - ibuf_rollover <= + *pos_in_ibuf < + next_ibuf_trigger - ibuf_rollover + (HD_POS_BUF_MULTIPLES - 1) * SND_BUF_LEN * sizeof(SND_IN_CONTAINER)) { next_ibuf_trigger += SND_BUF_LEN* sizeof(SND_IN_CONTAINER); - if (next_ibuf_trigger - ibuf_rollover >= - HD_POS_BUF_MULTIPLES *SND_BUF_LEN* sizeof(SND_IN_CONTAINER)) - ibuf_rollover += HD_POS_BUF_MULTIPLES *SND_BUF_LEN * - sizeof(SND_IN_CONTAINER); + if (next_ibuf_trigger - ibuf_rollover >= HD_POS_BUF_MULTIPLES * SND_BUF_LEN * sizeof(SND_IN_CONTAINER)) + ibuf_rollover += HD_POS_BUF_MULTIPLES * SND_BUF_LEN * sizeof(SND_IN_CONTAINER); if (fp_snd_copy_buf) (*fp_snd_copy_buf)(hda.istr0_buf[snd_obuf_num & 1], snd_ibuf_num); snd_ibuf_num++; @@ -504,15 +532,18 @@ U0 HDAudioTask(I64) U0 HDRst() { U32 d, *_d; + HDStop(TRUE, TRUE); _d = hda.bar + HD_GCTL; *_d = 0; //rst - do { + do + { Sleep(1); d = *_d; } while (d & 1); *_d = 1; - do { + do + { Sleep(1); d = *_d; } while (!(d & 1)); @@ -552,28 +583,26 @@ U0 HDAudioUncachedInit() public Bool HDAudioInit(I64 hd_bus, I64 hd_dev, I64 hd_fun) { I64 i; - U32 * _d; + U32 *_d; U16 w, *_w; - U8 * _b; + U8 *_b; if (hda.bar) HDAudioEnd; else HDAudioUncachedInit; - if (PCIReadU16(hd_bus, hd_dev, hd_fun, 0) == 0x8086 && - (hda.bar = PCIReadU32(hd_bus, hd_dev, hd_fun, 0x10) &~(0x1F))) + if (PCIReadU16(hd_bus, hd_dev, hd_fun, 0) == 0x8086 && (hda.bar = PCIReadU32(hd_bus, hd_dev, hd_fun, 0x10) & ~(0x1F))) { - PCIWriteU16(hd_bus, hd_dev, hd_fun, 0x04, - PCIReadU16(hd_bus, hd_dev, hd_fun, 0x04) | 0x406); + PCIWriteU16(hd_bus, hd_dev, hd_fun, 0x04, PCIReadU16(hd_bus, hd_dev, hd_fun, 0x04) | 0x406); HDRst; - hda.corb = CAllocAligned(HD_CORB_ENTRIES* sizeof(U32), 128, hda.hc); + hda.corb = CAllocAligned(HD_CORB_ENTRIES * sizeof(U32), 128, hda.hc); _d = hda.bar + HD_CORBLBASE; *_d = hda.corb(I64).u32[0]; _d = hda.bar + HD_CORBUBASE; *_d = hda.corb(I64).u32[1]; - hda.rirb = CAllocAligned(HD_RIRB_ENTRIES* sizeof(I64), 128, hda.hc); + hda.rirb = CAllocAligned(HD_RIRB_ENTRIES * sizeof(I64), 128, hda.hc); _d = hda.bar + HD_RIRBLBASE; *_d = hda.rirb(I64).u32[0]; _d = hda.bar + HD_RIRBUBASE; @@ -581,11 +610,15 @@ public Bool HDAudioInit(I64 hd_bus, I64 hd_dev, I64 hd_fun) _w = hda.bar + HD_CORBRP; *_w = 0x8000; //Rst read ptr - do { Yield; + do + { + Yield; w = *_w; } while (!(w & 0x8000)); *_w = 0x0000; //Rst read ptr - do { Yield; + do + { + Yield; w = *_w; } while (w & 0x8000); @@ -602,28 +635,27 @@ public Bool HDAudioInit(I64 hd_bus, I64 hd_dev, I64 hd_fun) _w = hda.bar + HD_RIRBWP; hda.rirb_rp = *_w; - hda.ostr0_bdl = CAllocAligned( HD_BDL_ENTRIES* sizeof(CHDBufDesc), 128, hda.hc); + hda.ostr0_bdl = CAllocAligned(HD_BDL_ENTRIES * sizeof(CHDBufDesc), 128, hda.hc); _d = hda.bar + OSTR0 + STRBDPL; *_d = hda.ostr0_bdl(I64).u32[0]; _d = hda.bar + OSTR0 + STRBDPU; *_d = hda.ostr0_bdl(I64).u32[1]; for (i = 0; i < 2; i++) { - hda.ostr0_bdl[i].buf = hda.ostr0_buf[i] = - CAllocAligned( SND_BUF_LEN* sizeof(SND_OUT_CONTAINER), 128, hda.hc); - hda.ostr0_bdl[i].len = SND_BUF_LEN* sizeof(SND_OUT_CONTAINER); + hda.ostr0_bdl[i].buf = hda.ostr0_buf[i] = CAllocAligned(SND_BUF_LEN * sizeof(SND_OUT_CONTAINER), 128, hda.hc); + hda.ostr0_bdl[i].len = SND_BUF_LEN * sizeof(SND_OUT_CONTAINER); hda.ostr0_bdl[i].ctrl = 1; } - hda.istr0_bdl = CAllocAligned( HD_BDL_ENTRIES* sizeof(CHDBufDesc), 128, hda.hc); + hda.istr0_bdl = CAllocAligned(HD_BDL_ENTRIES * sizeof(CHDBufDesc), 128, hda.hc); _d = hda.bar + ISTR0 + STRBDPL; *_d = hda.istr0_bdl(I64).u32[0]; _d = hda.bar + ISTR0 + STRBDPU; *_d = hda.istr0_bdl(I64).u32[1]; for (i = 0; i < 2; i++) { - hda.istr0_bdl[i].buf = hda.istr0_buf[i] = CAllocAligned( SND_BUF_LEN* sizeof(SND_IN_CONTAINER), 128, hda.hc); - hda.istr0_bdl[i].len = SND_BUF_LEN* sizeof(SND_IN_CONTAINER); + hda.istr0_bdl[i].buf = hda.istr0_buf[i] = CAllocAligned(SND_BUF_LEN * sizeof(SND_IN_CONTAINER), 128, hda.hc); + hda.istr0_bdl[i].len = SND_BUF_LEN * sizeof(SND_IN_CONTAINER); hda.istr0_bdl[i].ctrl = 1; } @@ -639,7 +671,7 @@ public Bool HDAudioInit(I64 hd_bus, I64 hd_dev, I64 hd_fun) _d = hda.bar + OSTR0 + STRLPIB; *_d = 0; _d = hda.bar + OSTR0 + STRCBL; - *_d = HD_POS_BUF_MULTIPLES *SND_BUF_LEN* sizeof(SND_OUT_CONTAINER); + *_d = HD_POS_BUF_MULTIPLES * SND_BUF_LEN * sizeof(SND_OUT_CONTAINER); _w = hda.bar + OSTR0 + STRLVI; *_w = 1; //last valid idx _w = hda.bar + OSTR0 + STRFMT; @@ -648,7 +680,7 @@ public Bool HDAudioInit(I64 hd_bus, I64 hd_dev, I64 hd_fun) _d = hda.bar + ISTR0 + STRLPIB; *_d = 0; _d = hda.bar + ISTR0 + STRCBL; - *_d = HD_POS_BUF_MULTIPLES *SND_BUF_LEN* sizeof(SND_IN_CONTAINER); + *_d = HD_POS_BUF_MULTIPLES * SND_BUF_LEN * sizeof(SND_IN_CONTAINER); _w = hda.bar + ISTR0 + STRLVI; *_w = 1; //last valid idx _w = hda.bar + ISTR0 + STRFMT; @@ -693,5 +725,4 @@ Bool HDAudioScan() HDAudioScan; -# -help_index "" \ No newline at end of file +#help_index "" \ No newline at end of file From 926fd92849e18252a63f82fdbd24d9c104321bd1 Mon Sep 17 00:00:00 2001 From: TomAwezome Date: Wed, 28 Dec 2022 20:13:21 -0500 Subject: [PATCH 11/23] Delete src/Home/Sound/HDAudio0 directory --- src/Home/Sound/HDAudio0/Audio.ZC | 76 -- src/Home/Sound/HDAudio0/HDAudio.ZC | 1052 ---------------------------- 2 files changed, 1128 deletions(-) delete mode 100644 src/Home/Sound/HDAudio0/Audio.ZC delete mode 100644 src/Home/Sound/HDAudio0/HDAudio.ZC diff --git a/src/Home/Sound/HDAudio0/Audio.ZC b/src/Home/Sound/HDAudio0/Audio.ZC deleted file mode 100644 index 7c16ca296..000000000 --- a/src/Home/Sound/HDAudio0/Audio.ZC +++ /dev/null @@ -1,76 +0,0 @@ -// vim: set ft=c: - -I64 start_buf_num; -U0 (*fp_old_fill_buf)(SND_OUT_CONTAINER *buf,I64 buf_num)=NULL; - -U0 AudioFillBuf(SND_OUT_CONTAINER *buf,I64 buf_num) -{ - I64 j=0,k; - I64 intL, intR; - U8 *buf2; - - if (paused) - { - while (j8192) - { - while (FifoI64Cnt(audio_fifo_L)>7680) - { - FifoI64Rem(audio_fifo_L, &k); - FifoI64Rem(audio_fifo_R, &k); - } - } - - if (FifoI64Cnt(audio_fifo_L)) - { - FifoI64Rem(audio_fifo_L, &intL); - } - else - { - intL = 0; - } - intL *= 0xFFFF; - if (intL < 0) - { - intL += 0x1000000; - } - - if (FifoI64Cnt(audio_fifo_R)) - { - FifoI64Rem(audio_fifo_R, &intR); - } - else - { - intR = 0; - } - intR *= 0xFFFF; - if (intR < 0) - { - intR += 0x1000000; - } - - buf2 = buf+j; - buf2[0] = 0; - buf2[1] = intL; - buf2[2] = intL >> 8; - buf2[3] = intL >> 16; - j++; - - buf2 = buf+j; - buf2[0] = 0; - buf2[1] = intR; - buf2[2] = intR >> 8; - buf2[3] = intR >> 16; - j++; - } -} \ No newline at end of file diff --git a/src/Home/Sound/HDAudio0/HDAudio.ZC b/src/Home/Sound/HDAudio0/HDAudio.ZC deleted file mode 100644 index 718b9f539..000000000 --- a/src/Home/Sound/HDAudio0/HDAudio.ZC +++ /dev/null @@ -1,1052 +0,0 @@ -U8* Mem2MegAlloc(I64 *_pages2Meg, CBlkPool *bp = NULL) -{ - /*Alloc 2Meg pages from BlkPool. Don't link to task. - (Linking to a task means they will be freed when the task dies.) - It might give you more than you asked for - so a ptr to a page count is passed. - - Return: NULL if out of memory. - */ - I64 i, j, *pte, num = *_pages2Meg; - CMemBlk *res = NULL, *m, *m1; - - if (!bp) bp = sys_code_bp; - PUSHFD - CLI - while (LBts(&bp->locked_flags, BPlf_LOCKED)) - PAUSE - num <<= 21 - MEM_PAG_BITS; - - m = &bp->mem_free_2meg_list; - while (TRUE) - { - if (!(res = m->next)) - break; - if (res->pags < num) - m = res; - else - { - if (res->pags == num) - { - m->next = res->next; - goto am_done; - } - else - { - res->pags -= num; - res(U8*) += res->pags << MEM_PAG_BITS; - res->pags = num; - goto am_done; - } - } - } - - m = &bp->mem_free_list; - while (TRUE) - { - if (!(res = m->next)) - { - num = 0; - res = NULL; //Out of memory - goto am_done; - } - - if (res->pags < num) - m = res; - else - { - if (res->pags == num) - { - if (res(U8*) &0x1FFFFF) - m = res; - else - { - m->next = res->next; - goto am_done; - } - } - else - { - if (i = (res(U8*) &0x1FFFFF) >> MEM_PAG_BITS) - { - j = 1 << (21 - MEM_PAG_BITS) - i; - if (res->pags < num + j) - m = res; - else if (res->pags == num + j) - { - res->pags -= num; - res(U8*) += res->pags << MEM_PAG_BITS; - res->pags = num; - goto am_done; - } - else - { - m1 = res; - res(U8*) += j << MEM_PAG_BITS; - res->pags = num; - m = res(U8*) + num << MEM_PAG_BITS; - m->pags = m1->pags - num - j; - m1->pags = j; - m->next = m1->next; - m1->next = m; - m->mb_signature = MBS_UNUSED_SIGNATURE_VAL; - goto am_done; - } - } - else - { - m = m->next = res(U8*) + num << MEM_PAG_BITS; - m->next = res->next; - m->pags = res->pags - num; - m->mb_signature = MBS_UNUSED_SIGNATURE_VAL; - res->pags = num; - goto am_done; - } - } - } - } - - am_done: - i = num << MEM_PAG_BITS; - bp->used_u8s += i; - num >>= 21 - MEM_PAG_BITS; - *_pages2Meg = num; - m = res; - m1 = m(U8*) + i; - while (m < m1) - { - pte = MemPageTable(m); - *pte &= ~0x18; - InvalidatePage(m); - m(U8*) += 0x200000; - } - - LBtr(&bp->locked_flags, BPlf_LOCKED); - POPFD - return res; -} - -U8* Mem2MegUncachedAlloc(I64 *_pages2Meg, CBlkPool *bp = NULL) -{ - /*Alloc 2Meg pages from BlkPool. Don't link to task. - (Linking to a task means they will be freed when the task dies.) - It will be marked uncached. It might give you more than you asked for - so a ptr to a page count is passed. - - Return: NULL if out of memory. - */ - CMemBlk *res, *m, *m1; - I64 num = *_pages2Meg, *pte; - if (res = Mem2MegAlloc(_pages2Meg, bp)) - { - num = *_pages2Meg; - m = res; - m1 = m(U8*) + num << 21; - while (m < m1) - { - pte = MemPageTable(m); - *pte = *pte &~0x18 | 0x10; - InvalidatePage(m); - m(U8*) += 0x200000; - } - } - - return res; -} - -CHeapCtrl* HeapCtrlBPInit(CBlkPool *bp, I64 pags) -{ - //Make mem chunk into HeapCtrl and BlkPool. - I64 num; - CMemBlk * m; - CHeapCtrl * hc; - MemSet(bp, 0, sizeof(CBlkPool) + sizeof(CHeapCtrl)); - hc = HeapCtrlInit(bp(U8*) + sizeof(CBlkPool),, bp); - m = (bp(U8*) + sizeof(CBlkPool) + sizeof(CHeapCtrl) + MEM_PAG_SIZE - 1) &~(MEM_PAG_SIZE - 1); - num = (bp(U8*) + pags << MEM_PAG_BITS - m(U8*)) >> MEM_PAG_BITS; - bp->alloced_u8s = (pags - num) << MEM_PAG_BITS; - BlkPoolAdd(bp, m, num); - return hc; -} - -class CSndWaveCtrl -{ - I64 sample_rate, sample_bits, channels; - F64 freq_multiplier, amp_multiplier; - F64 phase, last_y, last_dydt, next_y; -}; - -#define WF_NULL 0 -#define WF_SQUARE 1 -#define WF_SINE 2 -#define WF_TRI 3 -#define WF_SAWTOOTH 4 -#define WF_NOISE 5 -#define WF_WAVEFORMS_NUM 6 - -//snd devs -#define SD_PC_SPEAKER 0 -#define SD_HD_AUDIO 1 -#define SND_SAMPLE_RATE 48000 -#define SND_SAMPLE_BITS 16 -#define SND_OCHANNELS 2 -#define SND_ICHANNELS 2 -#define SND_OUT_CONTAINER U32 -#define SND_IN_CONTAINER I16 -#define SND_BUF_LEN 0x400 -#define SND_BUF_TIME_mS(SND_BUF_LEN / SND_OCHANNELS *1000.0 / \ - SND_SAMPLE_RATE) - -F64 snd_freq = 0; -I64 snd_dev = SD_PC_SPEAKER; -Bool snd_record = FALSE; -F64 snd_vol = 0.1; -U0(*fp_snd)(F64 freq, I64 waveform, F64 amp) = NULL; -U0(*fp_snd_record)(F64 freq, I64 waveform, F64 amp) = NULL; -U0(*fp_snd_fill_buf)(SND_OUT_CONTAINER *buf, I64 buf_num) = NULL; -U0(*fp_snd_copy_buf)(SND_IN_CONTAINER *buf, I64 buf_num) = NULL; - -I64 snd_obuf_num, snd_ibuf_num; - -#define Sf_FILLING_OUT 0 -I64 snd_flags; - -#define HD_1_CHAN 0 -#define HD_2_CHAN 1 -#define HD_3_CHAN 2 -#define HD_4_CHAN 3 -#define HD_8_BIT 0 -#define HD_16_BIT 1 -#define HD_20_BIT 2 -#define HD_24_BIT 3 -#define HD_32_BIT 4 -#define HD_48kHz 0 -#define HD_DFT_OUT_FMT(HD_2_CHAN + HD_16_BIT << 4 + HD_48kHz << 8) -#define HD_DFT_IN_FMT(HD_2_CHAN + HD_16_BIT << 4 + HD_48kHz << 8) -#define HD_POS_BUF_MULTIPLES 0x1000 -#define HD_CORB_ENTRIES 256 -#define HD_RIRB_ENTRIES 256 -#define HD_BDL_ENTRIES 256 -#define HD_GCTL 0x08 -#define HD_STATESTS 0x0E -#define HD_GSTS 0x10 -#define HD_CORBLBASE 0x40 -#define HD_CORBUBASE 0x44 -#define HD_CORBWP 0x48 -#define HD_CORBRP 0x4A -#define HD_CORBCTL 0x4C -#define HD_CORBST 0x4D -#define HD_RIRBLBASE 0x50 -#define HD_RIRBUBASE 0x54 -#define HD_RIRBWP 0x58 -#define HD_RIRBCTL 0x5C -#define HD_RIRBSTS 0x5D -#define STRCTL 0x00 -#define STRSTS 0x03 -#define STRLPIB 0x04 -#define STRCBL 0x08 -#define STRLVI 0x0C -#define STRFIFOW 0x0E -#define STRFIFOS 0x10 -#define STRFMT 0x12 -#define STRBDPL 0x18 -#define STRBDPU 0x1C -#define ISTR0 0x080 -#define ISTR1 0x0A0 -#define ISTR2 0x0C0 -#define ISTR3 0x0E0 -#define OSTR0 0x100 -#define OSTR1 0x120 -#define OSTR2 0x140 -#define OSTR3 0x160 -#define VERB_GET_PARAM 0xF0000 -#define VERB_CONNECT_SEL_GET 0xF0100 -#define VERB_CONNECT_SEL_SET 0x70100 -#define VERB_GET_CONNECT_LST 0xF0200 -#define VERB_PROCESS_STATE_GET 0xF0300 -#define VERB_PROCESS_STATE_SET 0x70300 -#define VERB_COEFF_IDX_GET 0xD0000 -#define VERB_COEFF_IDX_SET 0x50000 -#define VERB_PROCESS_COEFF_GET 0xC0000 -#define VERB_PROCESS_COEFF_SET 0x40000 -#define VERB_AMPLIFIER_GAIN_GET 0xB0000 -#define VERB_AMPLIFIER_GAIN_SET 0x30000 -#define VERB_STREAM_FMT_GET 0xA0000 -#define VERB_STREAM_FMT_SET 0x20000 -#define VERB_DIGIT_CONVERT1_GET 0xF0D00 -#define VERB_DIGIT_CONVERT1_SET 0x70D00 -#define VERB_DIGIT_CONVERT2_GET 0xF0D00 -#define VERB_DIGIT_CONVERT2_SET 0x70E00 -#define VERB_POWER_STATE_GET 0xF0500 -#define VERB_POWER_STATE_SET 0x70500 -#define VERB_CHAN_STREAM_ID_GET 0xF0600 -#define VERB_CHAN_STREAM_ID_SET 0x70600 -#define VERB_SDI_SEL_GET 0xF0400 -#define VERB_SDI_SEL_SET 0x70400 -#define VERB_PIN_WIDGET_CTL_GET 0xF0700 -#define VERB_PIN_WIDGET_CTL_SET 0x70700 -#define VERB_UNSOL_ENABLE_GET 0xF0800 -#define VERB_UNSOL_ENABLE_SET 0x70800 -#define VERB_PIN_SENSE_GET 0xF0900 -#define VERB_PIN_SENSE_SET 0x70900 -#define VERB_EAPDBTL_ENABLE_GET 0xF0C00 -#define VERB_EAPDBTL_ENABLE_SET 0x70C00 -#define VERB_BEEP_CTL_GET 0xF0A00 -#define VERB_BEEP_CTL_SET 0x70A00 -#define VERB_GPI_CTRL0_GET 0xF1000 -#define VERB_GPI_CTRL0_SET 0x71000 -#define VERB_GPI_CTRL1_GET 0xF1100 -#define VERB_GPI_CTRL1_SET 0x71100 -#define VERB_GPI_CTRL2_GET 0xF1200 -#define VERB_GPI_CTRL2_SET 0x71200 -#define VERB_GPI_CTRL3_GET 0xF1300 -#define VERB_GPI_CTRL3_SET 0x71300 -#define VERB_GPI_CTRL4_GET 0xF1400 -#define VERB_GPI_CTRL4_SET 0x71400 -#define VERB_GPI_CTRL5_GET 0xF1500 -#define VERB_GPI_CTRL5_SET 0x71500 -#define VERB_GPI_CTRL6_GET 0xF1600 -#define VERB_GPI_CTRL6_SET 0x71600 -#define VERB_GPI_CTRL7_GET 0xF1700 -#define VERB_GPI_CTRL7_SET 0x71700 -#define VERB_GPI_CTRL8_GET 0xF1800 -#define VERB_GPI_CTRL8_SET 0x71800 -#define VERB_GPI_CTRL9_GET 0xF1900 -#define VERB_GPI_CTRL9_SET 0x71900 -#define VERB_GPI_CTRLA_GET 0xF1A00 -#define VERB_GPI_CTRLA_SET 0x71A00 -#define VERB_VOL_CTL_GET 0xF0F00 -#define VERB_VOL_CTL_SET 0x70F00 -#define VERB_SUB_SYS_ID0_GET 0xF2000 -#define VERB_SUB_SYS_ID0_SET 0x72000 -#define VERB_SUB_SYS_ID1_GET 0xF2000 -#define VERB_SUB_SYS_ID1_SET 0x72100 -#define VERB_SUB_SYS_ID2_GET 0xF2000 -#define VERB_SUB_SYS_ID2_SET 0x72200 -#define VERB_SUB_SYS_ID3_GET 0xF2000 -#define VERB_SUB_SYS_ID3_SET 0x72300 -#define VERB_CFG_DFT0_GET 0xF1C00 -#define VERB_CFG_DFT0_SET 0x71C00 -#define VERB_CFG_DFT1_GET 0xF1C00 -#define VERB_CFG_DFT1_SET 0x71D00 -#define VERB_CFG_DFT2_GET 0xF1C00 -#define VERB_CFG_DFT2_SET 0x71E00 -#define VERB_CFG_DFT3_GET 0xF1C00 -#define VERB_CFG_DFT3_SET 0x71F00 -#define VERB_STRIPE_CTL_GET 0xF2400 -#define VERB_STRIPE_CTL_SET 0x72400 -#define VERB_RST 0x7FF00 - -//Parameters -#define P_VENDOR_ID 0x00 -#define P_REVISION_ID 0x02 -#define P_SUBNODE_CNT 0x04 -#define P_FUN_GRP_TYPE 0x05 -#define P_AUDIO_FUN_CAP 0x08 -#define P_AUDIO_WIDGET_CAP 0x09 -#define P_SAMPLE_SIZE_RATE_CAP 0x0A -#define P_STREAM_FMTS 0x0B -#define P_PIN_CAP 0x0C -#define P_INPUT_AMP_CAP 0x0D -#define P_OUTPUT_AMP_CAP 0x12 -#define P_CONNECT_LST_LEN 0x0E -#define P_POWER_STATES 0x0F -#define P_PROCESSING_CAP 0x10 -#define P_GPIO_CNT 0x11 -#define P_VOL_KNOB_CAP 0x13 - -//Function Group Types -//00 reserved -#define FGT_AUDIO 1 -#define FGT_VENDOR_MODEM 2 -//03-7F reserved -//80-FF vendor function group - -//Audio Widget Types -#define AWT_OUTPUT 0x0 -#define AWT_INPUT 0x1 -#define AWT_MIXER 0x2 -#define AWT_SELECTOR 0x3 -#define AWT_PIN_COMPLEX 0x4 -#define AWT_POWER_WIDGET 0x5 -#define AWT_VOL_KNOB_WIDGET 0x6 -#define AWT_BEEP_GEN_WIDGET 0x7 -#define AWT_VENDOR 0xF -#define AWT_NODE 0x10 -DefineListLoad("ST_AUDIO_WIDGET_TYPES", - "Output\0Input\0Mixer\0Sellector\0Pin Complex\0" - "Power Widget\0Vol Knob\0Beep Gen\0\0\0\0\0\0\0\0Vendor\0Node\0"); - -class CHDBufDesc -{ - I32 * buf; - U32 len; - U32 ctrl; -}; - -#define HD_TONES 8 - -class CHDAudioCtrl -{ - U8 * bar; - CBlkPool * bp; - CHeapCtrl * hc; - I64 cad; - U32 * corb; - I64 * rirb; - CHDBufDesc *ostr0_bdl, *istr0_bdl; - SND_OUT_CONTAINER *ostr0_buf[2], *o_tmp_buf; - SND_IN_CONTAINER *istr0_buf[2]; - CTask * task; - I64 waveform; - F64 freq, amp; - CSndWaveCtrl *tone_swcs[HD_TONES]; - U8 rirb_rp, corb_wp; - Bool audio_task_started, in_running, out_running; -} - -hda; -MemSet(&hda, 0, sizeof(CHDAudioCtrl)); - -F64 SinPhaseCont(F64 last_y, F64 last_dydt, - F64 current_amp, F64 phase_offset) -{ - //Next sample of sin waveform. - F64 phase; - phase = last_y / current_amp; - if (phase > 1.0) phase = 1.0; - if (phase < -1.0) phase = -1.0; - if (last_dydt < 0) - phase = pi - ASin(phase); - else - phase = ASin(phase); - return phase - phase_offset; -} - -public CSndWaveCtrl* SndWaveCtrlNew(I64 sample_rate = 8000, I64 sample_bits = 24, - I64 channels = 2, CTask *mem_task = NULL) -{ - //MAlloc ctrl struct for generating waveforms. - CSndWaveCtrl *swc = CAlloc(sizeof(CSndWaveCtrl), mem_task); - swc->freq_multiplier = 1.0; - swc->amp_multiplier = 1.0; - swc->sample_rate = sample_rate; - swc->sample_bits = sample_bits; - swc->channels = channels; - swc->last_dydt = 1.0; - return swc; -} - -public U0 SndWaveCtrlDel(CSndWaveCtrl *swc) -{ - //Free waveform ctrl. - Free(swc); -} - -public U0 SndWaveAddBuf(CSndWaveCtrl *swc, U8 *buf, I64 num_samples, - F64 _freq, I64 _waveform = WF_SQUARE, F64 _amp = 1.0, F64 _left = 1.0, F64 _right = 1.0) -{ - //Add waveform to buffer. - //num_samples is multiplied by channels to get buf_len. - //left,right range from 0.0-1.0 - //Supports 16,24 and 32 bits - I64 reg i, reg j, reg k; - F64 a, f, amp, reg phase; - if (!swc) return; - _freq *= swc->freq_multiplier; - _amp *= swc->amp_multiplier; - if (!_freq || !_amp) - { - swc->last_y = swc->phase = 0; - swc->last_dydt = 1.0; - } - else - { - phase = swc->phase; - i = 0; - amp = Min(I32_MAX, I32_MAX *_amp); - f = 2 *pi / swc->sample_rate * _freq; - switch (_waveform) - { - case WF_NOISE: - a = 2.0 / pi * amp; - break; - case WF_SAWTOOTH: - a = amp / pi; - break; - case WF_SINE: - phase = SinPhaseCont(swc->last_y, swc->last_dydt, amp, 0.0); - break; - } - - while (phase < 0) - phase += 2 * pi; - while (phase >= 2 *pi) - phase -= 2 * pi; - num_samples *= swc->channels; - while (i < num_samples) - { - switch (_waveform) - { - case WF_SQUARE: - if (phase >= pi) - j = -amp; - else - j = amp; - break; - case WF_SINE: - j = amp* Sin(phase); - break; - case WF_TRI: - if (phase >= pi) - { - swc->last_y = swc->next_y; - swc->next_y = -amp* Sign(swc->last_y) + .00001; - phase -= pi; - } - - j = (swc->last_y *(pi - phase) + swc->next_y *phase) / pi; - break; - case WF_SAWTOOTH: - j = a *(phase - pi); - break; - case WF_NOISE: - if (phase < pi) - { - if (phase < f) - { - swc->last_y = swc->next_y; - swc->next_y = a *RandI16 / U16_MAX; - } - - j = swc->last_y *(pi - phase) + swc->next_y * phase; - } - else - { - if (phase - pi < f) - { - swc->last_y = swc->next_y; - swc->next_y = a *RandI16 / U16_MAX; - } - - j = swc->last_y *(2.0 *pi - phase) + swc->next_y *(phase - pi); - } - - break; - } - - //left channel - k = j * _left; - if (swc->sample_bits == 16) - { - k >>= 16; - buf(I16*)[i++] += k; - } - else - { - if (swc->sample_bits == 24) - k &= 0xFFFFFF00; - buf(I32*)[i++] += k; - } - - //right channel - if (swc->channels == 2) - { - k = j * _right; - if (swc->sample_bits == 16) - { - k >>= 16; - buf(I16*)[i++] += k; - } - else - { - if (swc->sample_bits == 24) - k &= 0xFFFFFF00; - buf(I32*)[i++] += k; - } - } - - phase += f; - while (phase >= 2 *pi) - phase -= 2 * pi; - } - - if (_waveform == WF_SINE) - { - swc->last_y = amp* Sin(phase); - swc->last_dydt = Cos(phase); - } - - swc->phase = phase; - } -} - -U0 HDSyncCORB() -{ - U16 *wp, *rp; - wp = hda.bar + HD_CORBWP; - *wp = hda.corb_wp; - rp = hda.bar + HD_CORBRP; - while (*rp &255 != hda.corb_wp) - Yield; -} - -U0 HDWriteCORB(I64 cad, I64 nid, U32 val) -{ - val |= cad << 28 + nid << 20; - hda.corb[++hda.corb_wp] = val; -} - -I64 HDSyncRIRB() -{ - U16 * _w; - I64 wp, res = 0; - _w = hda.bar + HD_RIRBWP; - wp = *_w; - while (hda.rirb_rp != wp) - res = hda.rirb[++hda.rirb_rp]; - return res; -} - -I64 HDReadRIRB() -{ - U16 * _w; - I64 wp, res = 0; - _w = hda.bar + HD_RIRBWP; - do { - Yield; - wp = *_w; - } while (wp == hda.rirb_rp); - res = hda.rirb[++hda.rirb_rp]; - return res; -} - -I64 HDWriteCORBSync(I64 cad, I64 nid, U32 val) -{ - HDSyncCORB; - HDSyncRIRB; - HDWriteCORB(cad, nid, val); - HDSyncCORB; - return HDReadRIRB; -} - -Bool HDTestCORBSync(I64 cad, I64 nid, U32 val) -{ - //Checks for a response - U16 * _w; - I64 wp; - - HDSyncCORB; - HDSyncRIRB; - HDWriteCORB(cad, nid, val); - HDSyncCORB; - - Sleep(1); - _w = hda.bar + HD_RIRBWP; - wp = *_w; - if (wp == hda.rirb_rp) - return FALSE; - HDReadRIRB; - return TRUE; -} - -U0 HDTraverse(I64 cad, I64 nid) -{ - I64 i, len, aud_cap, type; - HDWriteCORBSync(cad, nid, VERB_POWER_STATE_SET + 0x00); //0 is on - HDWriteCORBSync(cad, nid, VERB_EAPDBTL_ENABLE_SET + 0x02); - HDWriteCORBSync(cad, nid, VERB_PROCESS_STATE_SET + 0x02); - HDWriteCORBSync(cad, nid, VERB_CONNECT_SEL_SET + 0x00); - aud_cap = HDWriteCORBSync(cad, nid, VERB_GET_PARAM + P_SUBNODE_CNT); - if (aud_cap.u16[0]) - { - for (i = aud_cap.u16[1]; i < aud_cap.u16[1] + aud_cap.u16[0]; i++) - HDTraverse(cad, i); - } - else - { - aud_cap = HDWriteCORBSync(cad, nid, VERB_GET_PARAM + P_AUDIO_WIDGET_CAP); - type = aud_cap >> 20 &15; - if (Bt(&aud_cap, 8)) - len = HDWriteCORBSync(cad, nid, VERB_GET_PARAM + P_CONNECT_LST_LEN) &127; - else - len = 0; - HDWriteCORBSync(cad, nid, VERB_AMPLIFIER_GAIN_SET + 0xF07F); //set I/O amp #0 - for (i = 1; i < len; i++) - //Set IN amps to mute - HDWriteCORBSync(cad, nid, VERB_AMPLIFIER_GAIN_SET + 0x7080 + i << 8); - switch (type) - { - case AWT_OUTPUT: - if (FALSE) //if disabled - HDWriteCORBSync(cad, nid, VERB_CHAN_STREAM_ID_SET + 0x00); - else - HDWriteCORBSync(cad, nid, VERB_CHAN_STREAM_ID_SET + 0x10); - HDWriteCORBSync(cad, nid, VERB_STREAM_FMT_SET + HD_DFT_OUT_FMT); - HDWriteCORBSync(cad, nid, VERB_PROCESS_STATE_SET + 0x01); - break; - case AWT_INPUT: - if (TRUE) //if disabled - HDWriteCORBSync(cad, nid, VERB_CHAN_STREAM_ID_SET + 0x00); - else - HDWriteCORBSync(cad, nid, VERB_CHAN_STREAM_ID_SET + 0x20); - HDWriteCORBSync(cad, nid, VERB_STREAM_FMT_SET + HD_DFT_IN_FMT); - HDWriteCORBSync(cad, nid, VERB_PROCESS_STATE_SET + 0x01); - break; - case AWT_PIN_COMPLEX: - HDWriteCORBSync(cad, nid, VERB_PIN_WIDGET_CTL_SET + 0xE2); - break; - } - } -} - -U0 HDRun(Bool in, Bool out) -{ - U32 * _d; - if (hda.bar) - { - if (out) - { - _d = hda.bar + OSTR0 + STRCTL; - *_d = 0x100002; - hda.out_running = TRUE; - } - - if (in) - { - _d = hda.bar + ISTR0 + STRCTL; - *_d = 0x200002; - hda.in_running = TRUE; - } - } -} - -U0 HDStop(Bool in, Bool out) -{ - U32 * _d; - if (hda.bar) - { - if (out) - { - _d = hda.bar + OSTR0 + STRCTL; - *_d = 0; - hda.out_running = FALSE; - } - - if (in) - { - _d = hda.bar + ISTR0 + STRCTL; - *_d = 0; - hda.in_running = FALSE; - } - } -} - -U0 HDSnd(F64 freq, I64 waveform = WF_SQUARE, F64 amp = 1.0) -{ - hda.waveform = waveform; - hda.amp = amp; - hda.freq = freq; -} - -U0 HDFillBuf(SND_OUT_CONTAINER *buf, I64) -{ - I64 i, size = SND_BUF_LEN* sizeof(SND_OUT_CONTAINER); - if (!hda.o_tmp_buf) - hda.o_tmp_buf = SysMAlloc(size); - MemSet(hda.o_tmp_buf, 0, size); - for (i = 0; i < HD_TONES; i++) - SndWaveAddBuf(hda.tone_swcs[i], hda.o_tmp_buf, - SND_BUF_LEN / SND_OCHANNELS, hda.freq, - hda.waveform, snd_vol *hda.amp); - MemCopy(buf, hda.o_tmp_buf, size); -} - -U0 HDAudioTaskEndCB() -{ - I64 i; - HDStop(FALSE, TRUE); - fp_snd = NULL; - for (i = 0; i < HD_TONES; i++) - { - SndWaveCtrlDel(hda.tone_swcs[i]); - hda.tone_swcs[i] = NULL; - } - - Exit; -} - -public U0 HDTonesInit() -{ - I64 i; - if (hda.bar) - { - for (i = 0; i < HD_TONES; i++) - { - hda.tone_swcs[i]->freq_multiplier = 1.0; - hda.tone_swcs[i]->amp_multiplier = 0; - } - - hda.tone_swcs[0]->amp_multiplier = 1.0; - } -} - -U0 HDAudioTask(I64) -{ - //I didn't feel like messing around with PCI interrupts - //so this task polls every millisecond to know when to - //switch buffers. - I64 i, next_obuf_trigger = SND_BUF_LEN* sizeof(SND_OUT_CONTAINER) / 2, - obuf_rollover = 0, - next_ibuf_trigger = SND_BUF_LEN* sizeof(SND_IN_CONTAINER), - ibuf_rollover = 0; - U32 *pos_in_obuf = hda.bar + OSTR0 + STRLPIB, - *pos_in_ibuf = hda.bar + ISTR0 + STRLPIB; - Fs->task_end_cb = &HDAudioTaskEndCB; - for (i = 0; i < HD_TONES; i++) - hda.tone_swcs[i] = SndWaveCtrlNew; - HDTonesInit; - hda.freq = 0; - Sound; - fp_snd = &HDSnd; - fp_snd_fill_buf = &HDFillBuf; - fp_snd_copy_buf = NULL; - snd_obuf_num = 1; - snd_ibuf_num = 1; - HDRun(FALSE, TRUE); - hda.audio_task_started = TRUE; //This flag is probably not necessary - while (TRUE) - { - if (next_obuf_trigger - obuf_rollover <= *pos_in_obuf< next_obuf_trigger - obuf_rollover + - (HD_POS_BUF_MULTIPLES - 1) *SND_BUF_LEN* sizeof(SND_OUT_CONTAINER)) - { - next_obuf_trigger += SND_BUF_LEN* sizeof(SND_OUT_CONTAINER); - if (next_obuf_trigger - obuf_rollover >= - HD_POS_BUF_MULTIPLES *SND_BUF_LEN* sizeof(SND_OUT_CONTAINER)) - obuf_rollover += HD_POS_BUF_MULTIPLES *SND_BUF_LEN * - sizeof(SND_OUT_CONTAINER); - if (fp_snd_fill_buf) - { - LBts(&snd_flags, Sf_FILLING_OUT); - (*fp_snd_fill_buf)(hda.ostr0_buf[snd_obuf_num & 1], snd_obuf_num); - if (IsMute) - MemSet(hda.ostr0_buf[snd_obuf_num & 1], 0, - SND_BUF_LEN* sizeof(SND_OUT_CONTAINER)); - LBtr(&snd_flags, Sf_FILLING_OUT); - } - - snd_obuf_num++; - } - - if (next_ibuf_trigger - ibuf_rollover <= *pos_in_ibuf< next_ibuf_trigger - ibuf_rollover + (HD_POS_BUF_MULTIPLES - 1) * - SND_BUF_LEN* sizeof(SND_IN_CONTAINER)) - { - next_ibuf_trigger += SND_BUF_LEN* sizeof(SND_IN_CONTAINER); - if (next_ibuf_trigger - ibuf_rollover >= - HD_POS_BUF_MULTIPLES *SND_BUF_LEN* sizeof(SND_IN_CONTAINER)) - ibuf_rollover += HD_POS_BUF_MULTIPLES *SND_BUF_LEN *sizeof(SND_IN_CONTAINER); - if (fp_snd_copy_buf) - (*fp_snd_copy_buf)(hda.istr0_buf[snd_obuf_num & 1], snd_ibuf_num); - snd_ibuf_num++; - } - - Sleep(1); - } -} - -U0 HDRst() -{ - U32 d, *_d; - HDStop(TRUE, TRUE); - _d = hda.bar + HD_GCTL; - *_d = 0; //rst - do { - Sleep(1); - d = *_d; - } while (d & 1); - *_d = 1; - do { - Sleep(1); - d = *_d; - } while (!(d & 1)); - Sleep(1); -} - -public U0 HDAudioEnd(Bool rst = TRUE) -{ - snd_dev = SD_PC_SPEAKER; - if (hda.bar) - { - Kill(hda.task); - hda.task = NULL; - if (rst) - HDRst; - Free(hda.corb); - Free(hda.rirb); - Free(hda.o_tmp_buf); - Free(hda.ostr0_buf[0]); - Free(hda.ostr0_buf[1]); - Free(hda.istr0_buf[0]); - Free(hda.istr0_buf[1]); - Free(hda.ostr0_bdl); - Free(hda.istr0_bdl); - Mem32DevFree(hda.bar); - hda.bar = NULL; - } -} - -U0 HDAudioUncachedInit() -{ - I64 shared_blks = 1; - hda.bp = Mem2MegUncachedAlloc(&shared_blks); - hda.hc = HeapCtrlBPInit(hda.bp, shared_blks << 12); -} - -public Bool HDAudioInit(I64 hd_bus, I64 hd_dev, I64 hd_fun) -{ - I64 i; - U32 * _d; - U16 w, *_w; - U8 * _b; - if (hda.bar) - HDAudioEnd; - else - HDAudioUncachedInit; - if (PCIReadU16(hd_bus, hd_dev, hd_fun, 0) == 0x8086 && - (hda.bar = PCIReadU32(hd_bus, hd_dev, hd_fun, 0x10) &~(0x1F))) - { - PCIWriteU16(hd_bus, hd_dev, hd_fun, 0x04, - PCIReadU16(hd_bus, hd_dev, hd_fun, 0x04) | 0x406); - - HDRst; - - hda.corb = CAllocAligned(HD_CORB_ENTRIES* sizeof(U32), 128, hda.hc); - _d = hda.bar + HD_CORBLBASE; - *_d = hda.corb(I64).u32[0]; - _d = hda.bar + HD_CORBUBASE; - *_d = hda.corb(I64).u32[1]; - - hda.rirb = CAllocAligned(HD_RIRB_ENTRIES* sizeof(I64), 128, hda.hc); - _d = hda.bar + HD_RIRBLBASE; - *_d = hda.rirb(I64).u32[0]; - _d = hda.bar + HD_RIRBUBASE; - *_d = hda.rirb(I64).u32[1]; - - _w = hda.bar + HD_CORBRP; - /* - *_w=0x8000; //Rst read ptr - do { - Yield; - w=*_w; - } while (!(w&0x8000)); - */ - *_w = 0x0000; //Rst read ptr - do { Yield; - w = *_w; - } while (w & 0x8000); - - _w = hda.bar + HD_RIRBWP; - *_w = 0x8000; //Rst write ptr - - _b = hda.bar + HD_CORBCTL; - *_b = 0x02; //Run - _b = hda.bar + HD_RIRBCTL; - *_b = 0x02; //Run - - _w = hda.bar + HD_CORBWP; - hda.corb_wp = *_w; - _w = hda.bar + HD_RIRBWP; - hda.rirb_rp = *_w; - - hda.ostr0_bdl = CAllocAligned( HD_BDL_ENTRIES* sizeof(CHDBufDesc), 128, hda.hc); - _d = hda.bar + OSTR0 + STRBDPL; - *_d = hda.ostr0_bdl(I64).u32[0]; - _d = hda.bar + OSTR0 + STRBDPU; - *_d = hda.ostr0_bdl(I64).u32[1]; - for (i = 0; i < 2; i++) - { - hda.ostr0_bdl[i].buf = hda.ostr0_buf[i] = - CAllocAligned( SND_BUF_LEN* sizeof(SND_OUT_CONTAINER), 128, hda.hc); - hda.ostr0_bdl[i].len = SND_BUF_LEN* sizeof(SND_OUT_CONTAINER); - hda.ostr0_bdl[i].ctrl = 1; - } - - hda.istr0_bdl = CAllocAligned( HD_BDL_ENTRIES* sizeof(CHDBufDesc), 128, hda.hc); - _d = hda.bar + ISTR0 + STRBDPL; - *_d = hda.istr0_bdl(I64).u32[0]; - _d = hda.bar + ISTR0 + STRBDPU; - *_d = hda.istr0_bdl(I64).u32[1]; - for (i = 0; i < 2; i++) - { - hda.istr0_bdl[i].buf = hda.istr0_buf[i] = CAllocAligned( SND_BUF_LEN* sizeof(SND_IN_CONTAINER), 128, hda.hc); - hda.istr0_bdl[i].len = SND_BUF_LEN* sizeof(SND_IN_CONTAINER); - hda.istr0_bdl[i].ctrl = 1; - } - - _w = hda.bar + HD_STATESTS; - w = *_w; - while (w) - { - hda.cad = Bsf(w); - if (HDTestCORBSync(hda.cad, 0, VERB_GET_PARAM + P_SUBNODE_CNT)) - { - HDTraverse(hda.cad, 0); - - _d = hda.bar + OSTR0 + STRLPIB; - *_d = 0; - _d = hda.bar + OSTR0 + STRCBL; - *_d = HD_POS_BUF_MULTIPLES *SND_BUF_LEN* sizeof(SND_OUT_CONTAINER); - _w = hda.bar + OSTR0 + STRLVI; - *_w = 1; //last valid idx - _w = hda.bar + OSTR0 + STRFMT; - *_w = HD_DFT_OUT_FMT; - - _d = hda.bar + ISTR0 + STRLPIB; - *_d = 0; - _d = hda.bar + ISTR0 + STRCBL; - *_d = HD_POS_BUF_MULTIPLES *SND_BUF_LEN* sizeof(SND_IN_CONTAINER); - _w = hda.bar + ISTR0 + STRLVI; - *_w = 1; //last valid idx - _w = hda.bar + ISTR0 + STRFMT; - *_w = HD_DFT_IN_FMT; - - LBts(&sys_semas[SEMA_SOUND], 0); //turn off until cfg completed - LBtr(&snd_flags, Sf_FILLING_OUT); - hda.audio_task_started = FALSE; - if (mp_count > 1) - hda.task = Spawn(&HDAudioTask, NULL, "HD Audio", mp_count - 1); - else - hda.task = Spawn(&HDAudioTask, NULL, "HD Audio"); - while (!hda.audio_task_started) - Yield; - snd_dev = SD_HD_AUDIO; - return TRUE; - } - - Btr(&w, hda.cad); - } - - HDAudioEnd(FALSE); - } - else - hda.bar = NULL; - return FALSE; -} - -Bool HDAudioScan() -{ - I64 i = -1, j; - while (TRUE) - { - j = PCIClassFind(0x040300, ++i); - if (j < 0) - return FALSE; - - if (HDAudioInit(j.u8[2], j.u8[1], j.u8[0])) - return TRUE; - } -} - -HDAudioScan; -Kill(hda.task); -HDAudioScan; \ No newline at end of file From b3af1628a223d98a22303415db15a6882f92b62b Mon Sep 17 00:00:00 2001 From: TomAwezome Date: Fri, 30 Dec 2022 14:21:07 -0500 Subject: [PATCH 12/23] Add PCI class and subclass codes for audio. --- src/Kernel/KernelA.HH | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Kernel/KernelA.HH b/src/Kernel/KernelA.HH index 2f22b54fb..eafb7fcc0 100755 --- a/src/Kernel/KernelA.HH +++ b/src/Kernel/KernelA.HH @@ -2661,9 +2661,11 @@ class CSMBIOSBatteryInfo //PCI class codes #define PCIC_STORAGE 0x1 #define PCIC_NETWORK 0x2 +#define PCIC_MULTIMEDIA 0x4 //PCI subclass codes #define PCISC_ETHERNET 0x0 +#define PCISC_AUDIO 0x3 #define PCISC_AHCI 0x6 //PCI I/O ports From 6063c0224334982aab768f08079669d37a0559b2 Mon Sep 17 00:00:00 2001 From: TomAwezome Date: Fri, 30 Dec 2022 14:22:20 -0500 Subject: [PATCH 13/23] Make HDAudio driver find with PCI code constants. --- src/Home/Sound/HDAudio1/Sup1HDAudio/HDAudio.ZC | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Home/Sound/HDAudio1/Sup1HDAudio/HDAudio.ZC b/src/Home/Sound/HDAudio1/Sup1HDAudio/HDAudio.ZC index 24042dd12..394aaaaef 100644 --- a/src/Home/Sound/HDAudio1/Sup1HDAudio/HDAudio.ZC +++ b/src/Home/Sound/HDAudio1/Sup1HDAudio/HDAudio.ZC @@ -714,7 +714,7 @@ Bool HDAudioScan() I64 i = -1, j; while (TRUE) { - j = PCIClassFind(0x040300, ++i); + j = PCIClassFind(PCIC_MULTIMEDIA << 16 | PCISC_AUDIO << 8, ++i); if (j < 0) return FALSE; From 8106bf6c0238cb4982f8903f502609241f2bd8c1 Mon Sep 17 00:00:00 2001 From: TomAwezome Date: Fri, 30 Dec 2022 14:23:16 -0500 Subject: [PATCH 14/23] Trim a few redundant HDAudio function code lines. --- src/Home/Sound/HDAudio1/Sup1HDAudio/HDAudio.ZC | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/src/Home/Sound/HDAudio1/Sup1HDAudio/HDAudio.ZC b/src/Home/Sound/HDAudio1/Sup1HDAudio/HDAudio.ZC index 394aaaaef..c487a48ba 100644 --- a/src/Home/Sound/HDAudio1/Sup1HDAudio/HDAudio.ZC +++ b/src/Home/Sound/HDAudio1/Sup1HDAudio/HDAudio.ZC @@ -251,11 +251,9 @@ MemSet(&hda, 0, sizeof(CHDAudioCtrl)); U0 HDSyncCORB() { - U16 *wp, *rp; + U16 *wp = hda.bar + HD_CORBWP, *rp = hda.bar + HD_CORBRP; - wp = hda.bar + HD_CORBWP; *wp = hda.corb_wp; - rp = hda.bar + HD_CORBRP; while (*rp & 255 != hda.corb_wp) Yield; } @@ -268,11 +266,9 @@ U0 HDWriteCORB(I64 cad, I64 nid, U32 val) I64 HDSyncRIRB() { - U16 *_w; - I64 wp, res = 0; + U16 *_w = hda.bar + HD_RIRBWP; + I64 wp = *_w, res = 0; - _w = hda.bar + HD_RIRBWP; - wp = *_w; while (hda.rirb_rp != wp) res = hda.rirb[++hda.rirb_rp]; @@ -281,10 +277,9 @@ I64 HDSyncRIRB() I64 HDReadRIRB() { - U16 *_w; + U16 *_w = hda.bar + HD_RIRBWP; I64 wp, res = 0; - _w = hda.bar + HD_RIRBWP; do { Yield; @@ -531,10 +526,9 @@ U0 HDAudioTask(I64) U0 HDRst() { - U32 d, *_d; + U32 d, *_d = hda.bar + HD_GCTL; HDStop(TRUE, TRUE); - _d = hda.bar + HD_GCTL; *_d = 0; //rst do { @@ -586,6 +580,7 @@ public Bool HDAudioInit(I64 hd_bus, I64 hd_dev, I64 hd_fun) U32 *_d; U16 w, *_w; U8 *_b; + if (hda.bar) HDAudioEnd; else From 5696c3d0f19cf387c1a707511bfd6d25d504f804 Mon Sep 17 00:00:00 2001 From: TomAwezome Date: Fri, 30 Dec 2022 14:24:15 -0500 Subject: [PATCH 15/23] Fix HDAudio driver for machines with less than 3 cores. --- src/Home/Sound/HDAudio1/Sup1HDAudio/HDAudio.ZC | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Home/Sound/HDAudio1/Sup1HDAudio/HDAudio.ZC b/src/Home/Sound/HDAudio1/Sup1HDAudio/HDAudio.ZC index c487a48ba..df60f5b64 100644 --- a/src/Home/Sound/HDAudio1/Sup1HDAudio/HDAudio.ZC +++ b/src/Home/Sound/HDAudio1/Sup1HDAudio/HDAudio.ZC @@ -685,7 +685,7 @@ public Bool HDAudioInit(I64 hd_bus, I64 hd_dev, I64 hd_fun) LBtr(&snd_flags, Sf_FILLING_OUT); hda.audio_task_started = FALSE; if (mp_count > 1) - hda.task = Spawn(&HDAudioTask, NULL, "HD Audio", 3); + hda.task = Spawn(&HDAudioTask, NULL, "HD Audio", mp_count - 1); else hda.task = Spawn(&HDAudioTask, NULL, "HD Audio"); while (!hda.audio_task_started) From 74b770870f6de2e9533ff1f2db1d96a5b3bf191e Mon Sep 17 00:00:00 2001 From: TomAwezome Date: Fri, 30 Dec 2022 14:25:09 -0500 Subject: [PATCH 16/23] Comment out skipped lines, add TODO noting to look into what formats a stream supports before trying to make it use the 'default'. --- src/Home/Sound/HDAudio1/Sup1HDAudio/HDAudio.ZC | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Home/Sound/HDAudio1/Sup1HDAudio/HDAudio.ZC b/src/Home/Sound/HDAudio1/Sup1HDAudio/HDAudio.ZC index df60f5b64..fa61cc344 100644 --- a/src/Home/Sound/HDAudio1/Sup1HDAudio/HDAudio.ZC +++ b/src/Home/Sound/HDAudio1/Sup1HDAudio/HDAudio.ZC @@ -348,19 +348,19 @@ U0 HDTraverse(I64 cad, I64 nid) switch (type) { case AWT_OUTPUT: - if (FALSE) //if disabled // ???? - HDWriteCORBSync(cad, nid, VERB_CHAN_STREAM_ID_SET + 0x00); - else +// if (FALSE) //if disabled // ???? +// HDWriteCORBSync(cad, nid, VERB_CHAN_STREAM_ID_SET + 0x00); +// else HDWriteCORBSync(cad, nid, VERB_CHAN_STREAM_ID_SET + 0x10); - HDWriteCORBSync(cad, nid, VERB_STREAM_FMT_SET + HD_DFT_OUT_FMT); + HDWriteCORBSync(cad, nid, VERB_STREAM_FMT_SET + HD_DFT_OUT_FMT); // TODO: check format streams support ? HDWriteCORBSync(cad, nid, VERB_PROCESS_STATE_SET + 0x01); break; case AWT_INPUT: - if (TRUE) //if disabled // ???? +// if (TRUE) //if disabled // ???? HDWriteCORBSync(cad, nid, VERB_CHAN_STREAM_ID_SET + 0x00); - else - HDWriteCORBSync(cad, nid, VERB_CHAN_STREAM_ID_SET + 0x20); - HDWriteCORBSync(cad, nid, VERB_STREAM_FMT_SET + HD_DFT_IN_FMT); +// else +// HDWriteCORBSync(cad, nid, VERB_CHAN_STREAM_ID_SET + 0x20); + HDWriteCORBSync(cad, nid, VERB_STREAM_FMT_SET + HD_DFT_IN_FMT); // TODO: check format streams support ? HDWriteCORBSync(cad, nid, VERB_PROCESS_STATE_SET + 0x01); break; case AWT_PIN_COMPLEX: From 0f1a63f0a2a773e9fa6ebb8db91bb1d2a1d22762 Mon Sep 17 00:00:00 2001 From: TomAwezome Date: Fri, 30 Dec 2022 16:26:12 -0500 Subject: [PATCH 17/23] Fix PCI write funcs val calculation. --- src/Kernel/PCI.ZC | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Kernel/PCI.ZC b/src/Kernel/PCI.ZC index 8d7c5d87d..14fdfaed1 100755 --- a/src/Kernel/PCI.ZC +++ b/src/Kernel/PCI.ZC @@ -69,14 +69,14 @@ U0 PCIWriteU32(I64 bus, I64 dev, I64 fun, I64 rg, I64 val) } } - U0 PCIWriteU8(I64 bus, I64 dev, I64 fun, I64 rg, I64 val) {//Write U8 in PCI configspace at bus, dev, fun, reg. if (sys_pci_services) PCIBIOSWriteU8(bus, dev, fun, rg, val); else { - PCIWriteU32(bus, dev, fun, rg, val & 0xFF); + val = PCIReadU32(bus, dev, fun, rg) & ~0xFF | val & 0xFF; + PCIWriteU32(bus, dev, fun, rg, val); } } @@ -86,7 +86,8 @@ U0 PCIWriteU16(I64 bus, I64 dev, I64 fun, I64 rg, I64 val) PCIBIOSWriteU16(bus, dev, fun, rg, val); else { - PCIWriteU32(bus, dev, fun, rg, val & 0xFFFF); + val = PCIReadU32(bus, dev, fun, rg) & ~0xFFFF | val & 0xFFFF; + PCIWriteU32(bus, dev, fun, rg, val); } } From 64703e9a120a6d35dc0b254e8b556863a3944c2e Mon Sep 17 00:00:00 2001 From: TomAwezome Date: Fri, 30 Dec 2022 17:45:58 -0500 Subject: [PATCH 18/23] Create PCI Command Register kernel defines, replace PCNet identical defines with new global defines. --- src/Home/Net/Drivers/PCNet.ZC | 10 ++-------- src/Kernel/KernelA.HH | 11 +++++++++++ 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/Home/Net/Drivers/PCNet.ZC b/src/Home/Net/Drivers/PCNet.ZC index 26b09f1da..5c454aa9a 100644 --- a/src/Home/Net/Drivers/PCNet.ZC +++ b/src/Home/Net/Drivers/PCNet.ZC @@ -1,5 +1,5 @@ /* AMD PCNetII Driver - Author: TomAwezome + Authors: ($TX,"minexew",HTML="https://github.com/minexew/"$), $TX,"TomAwezome",HTML="https://github.com/TomAwezome/"$, $TX,"TheTinkerer",HTML="https://github.com/tinkeros/"$ Driver is based on: - minexew's ShrineOS PCNet implementation @@ -13,12 +13,6 @@ - Clear documentation. */ -#define PCNET_CMDf_IOEN 0 -#define PCNET_CMDf_BMEN 2 - -#define PCNET_CMDF_IOEN (1 << PCNET_CMDf_IOEN) -#define PCNET_CMDF_BMEN (1 << PCNET_CMDf_BMEN) - #define PCNET_WD_RESET 0x14 // reset reg location when card is in 16-bit mode #define PCNET_DW_RDP 0x10 @@ -704,7 +698,7 @@ U0 PCNetInit() pcnet.pci->dev, pcnet.pci->fun, PCIR_COMMAND, - PCNET_CMDF_IOEN | PCNET_CMDF_BMEN); + PCI_CMDF_IOEN | PCI_CMDF_BMEN); PCNetReset; diff --git a/src/Kernel/KernelA.HH b/src/Kernel/KernelA.HH index eafb7fcc0..4a9046b88 100755 --- a/src/Kernel/KernelA.HH +++ b/src/Kernel/KernelA.HH @@ -2658,6 +2658,17 @@ class CSMBIOSBatteryInfo #define PCIR_MIN_GRANT 0x3E #define PCIR_MAX_LATENCY 0x3F +// PCI Command Register bit flags +#define PCI_CMDf_IOEN 0 // I/O Space Enable +#define PCI_CMDf_MSEN 1 // Memory Space Enable +#define PCI_CMDf_BMEN 2 // Bus Master Enable +#define PCI_CMDf_INTD 10 // Interrupt Disable + +#define PCI_CMDF_IOEN (1 << PCI_CMDf_IOEN) +#define PCI_CMDF_MSEN (1 << PCI_CMDf_MSEN) +#define PCI_CMDF_BMEN (1 << PCI_CMDf_BMEN) +#define PCI_CMDF_INTD (1 << PCI_CMDf_INTD) + //PCI class codes #define PCIC_STORAGE 0x1 #define PCIC_NETWORK 0x2 From e599c67ca593b58cae99e6578231a528a75a02ef Mon Sep 17 00:00:00 2001 From: TomAwezome Date: Fri, 30 Dec 2022 17:46:49 -0500 Subject: [PATCH 19/23] Unobfuscate HDAudioInit and HDAudioScan. --- .../Sound/HDAudio1/Sup1HDAudio/HDAudio.ZC | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/Home/Sound/HDAudio1/Sup1HDAudio/HDAudio.ZC b/src/Home/Sound/HDAudio1/Sup1HDAudio/HDAudio.ZC index fa61cc344..9212d4b57 100644 --- a/src/Home/Sound/HDAudio1/Sup1HDAudio/HDAudio.ZC +++ b/src/Home/Sound/HDAudio1/Sup1HDAudio/HDAudio.ZC @@ -578,16 +578,23 @@ public Bool HDAudioInit(I64 hd_bus, I64 hd_dev, I64 hd_fun) { I64 i; U32 *_d; - U16 w, *_w; + U16 w, *_w, val; U8 *_b; if (hda.bar) HDAudioEnd; else HDAudioUncachedInit; - if (PCIReadU16(hd_bus, hd_dev, hd_fun, 0) == 0x8086 && (hda.bar = PCIReadU32(hd_bus, hd_dev, hd_fun, 0x10) & ~(0x1F))) + if (PCIReadU16(hd_bus, hd_dev, hd_fun, PCIR_VENDOR_ID) == 0x8086 && + (hda.bar = dev.uncached_alias + PCIReadU32(hd_bus, hd_dev, hd_fun, PCIR_BASE0) & ~0x1F)) { - PCIWriteU16(hd_bus, hd_dev, hd_fun, 0x04, PCIReadU16(hd_bus, hd_dev, hd_fun, 0x04) | 0x406); + /* Set HDAudio PCI device command + register IO Enable, Bus + Master Enable, Memory Space,and + Interrupt Disable bits. */ + val = PCIReadU16(hd_bus, hd_dev, hd_fun, PCIR_COMMAND); + val |= PCI_CMDF_IOEN | PCI_CMDF_BMEN | PCI_CMDF_INTD | PCI_CMDF_MSEN; + PCIWriteU16(hd_bus, hd_dev, hd_fun, PCIR_COMMAND, val); HDRst; @@ -706,14 +713,14 @@ public Bool HDAudioInit(I64 hd_bus, I64 hd_dev, I64 hd_fun) Bool HDAudioScan() { - I64 i = -1, j; + I64 i = -1, bdf; while (TRUE) { - j = PCIClassFind(PCIC_MULTIMEDIA << 16 | PCISC_AUDIO << 8, ++i); - if (j < 0) + bdf = PCIClassFind(PCIC_MULTIMEDIA << 16 | PCISC_AUDIO << 8, ++i); + if (bdf < 0) return FALSE; - if (HDAudioInit(j.u8[2], j.u8[1], j.u8[0])) + if (HDAudioInit(bdf.u8[2], bdf.u8[1], bdf.u8[0])) return TRUE; } } From d58bc8c4108ee4ac9e689acac393399b734e0785 Mon Sep 17 00:00:00 2001 From: TomAwezome Date: Sat, 31 Dec 2022 01:07:19 -0500 Subject: [PATCH 20/23] Add HDAudio read/write register functions. --- .../Sound/HDAudio1/Sup1HDAudio/HDAudio.ZC | 36 +++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/src/Home/Sound/HDAudio1/Sup1HDAudio/HDAudio.ZC b/src/Home/Sound/HDAudio1/Sup1HDAudio/HDAudio.ZC index 9212d4b57..f08fadaa3 100644 --- a/src/Home/Sound/HDAudio1/Sup1HDAudio/HDAudio.ZC +++ b/src/Home/Sound/HDAudio1/Sup1HDAudio/HDAudio.ZC @@ -249,9 +249,41 @@ class CHDAudioCtrl MemSet(&hda, 0, sizeof(CHDAudioCtrl)); -U0 HDSyncCORB() +U0 HDAudioRegWriteU32(U16 hd_reg, U32 val) { - U16 *wp = hda.bar + HD_CORBWP, *rp = hda.bar + HD_CORBRP; + U32 *dest = hda.bar + hd_reg; + *dest = val; +} + +U0 HDAudioRegWriteU16(U16 hd_reg, U16 val) +{ + U16 *dest = hda.bar + hd_reg; + *dest = val; +} + +U0 HDAudioRegWriteU8(U16 hd_reg, U8 val) +{ + U8 *dest = hda.bar + hd_reg; + *dest = val; +} + +U32 HDAudioRegReadU32(U16 hd_reg) +{ + U32 *dest = hda.bar + hd_reg; + return *dest; +} + +U16 HDAudioRegReadU16(U16 hd_reg) +{ + U16 *dest = hda.bar + hd_reg; + return *dest; +} + +U8 HDAudioRegReadU8(U16 hd_reg) +{ + U8 *dest = hda.bar + hd_reg; + return *dest; +} *wp = hda.corb_wp; while (*rp & 255 != hda.corb_wp) From f8729688b999a3da49c72346d7a6f27d16a97d81 Mon Sep 17 00:00:00 2001 From: TomAwezome Date: Sat, 31 Dec 2022 01:08:39 -0500 Subject: [PATCH 21/23] Refactor entire HDAudio driver to use new register functions, instead of direct pointer manipulation. --- .../Sound/HDAudio1/Sup1HDAudio/HDAudio.ZC | 125 +++++++----------- 1 file changed, 46 insertions(+), 79 deletions(-) diff --git a/src/Home/Sound/HDAudio1/Sup1HDAudio/HDAudio.ZC b/src/Home/Sound/HDAudio1/Sup1HDAudio/HDAudio.ZC index f08fadaa3..67fa8de4b 100644 --- a/src/Home/Sound/HDAudio1/Sup1HDAudio/HDAudio.ZC +++ b/src/Home/Sound/HDAudio1/Sup1HDAudio/HDAudio.ZC @@ -285,8 +285,10 @@ U8 HDAudioRegReadU8(U16 hd_reg) return *dest; } - *wp = hda.corb_wp; - while (*rp & 255 != hda.corb_wp) +U0 HDSyncCORB() +{ + HDAudioRegWriteU16(HD_CORBWP, hda.corb_wp); + while (HDAudioRegReadU16(HD_CORBRP) & 0xFF != hda.corb_wp) Yield; } @@ -298,8 +300,7 @@ U0 HDWriteCORB(I64 cad, I64 nid, U32 val) I64 HDSyncRIRB() { - U16 *_w = hda.bar + HD_RIRBWP; - I64 wp = *_w, res = 0; + I64 wp = HDAudioRegReadU16(HD_RIRBWP), res = 0; while (hda.rirb_rp != wp) res = hda.rirb[++hda.rirb_rp]; @@ -309,13 +310,12 @@ I64 HDSyncRIRB() I64 HDReadRIRB() { - U16 *_w = hda.bar + HD_RIRBWP; I64 wp, res = 0; do { Yield; - wp = *_w; + wp = HDAudioRegReadU16(HD_RIRBWP); } while (wp == hda.rirb_rp); res = hda.rirb[++hda.rirb_rp]; @@ -334,7 +334,6 @@ I64 HDWriteCORBSync(I64 cad, I64 nid, U32 val) Bool HDTestCORBSync(I64 cad, I64 nid, U32 val) { //Checks for a response - U16 *_w; I64 wp; HDSyncCORB; @@ -343,8 +342,7 @@ Bool HDTestCORBSync(I64 cad, I64 nid, U32 val) HDSyncCORB; Sleep(1); - _w = hda.bar + HD_RIRBWP; - wp = *_w; + wp = HDAudioRegReadU16(HD_RIRBWP); if (wp == hda.rirb_rp) return FALSE; HDReadRIRB; @@ -404,20 +402,17 @@ U0 HDTraverse(I64 cad, I64 nid) U0 HDRun(Bool in, Bool out) { - U32 *_d; if (hda.bar) { if (out) { - _d = hda.bar + OSTR0 + STRCTL; - *_d = 0x100002; + HDAudioRegWriteU32(OSTR0 + STRCTL, 0x100002); // ?? hda.out_running = TRUE; } if (in) { - _d = hda.bar + ISTR0 + STRCTL; - *_d = 0x200002; + HDAudioRegWriteU32(ISTR0 + STRCTL, 0x200002); // ?? hda.in_running = TRUE; } } @@ -425,20 +420,17 @@ U0 HDRun(Bool in, Bool out) U0 HDStop(Bool in, Bool out) { - U32 *_d; if (hda.bar) { if (out) { - _d = hda.bar + OSTR0 + STRCTL; - *_d = 0; + HDAudioRegWriteU32(OSTR0 + STRCTL, 0); // ?? hda.out_running = FALSE; } if (in) { - _d = hda.bar + ISTR0 + STRCTL; - *_d = 0; + HDAudioRegWriteU32(ISTR0 + STRCTL, 0); // ?? hda.in_running = FALSE; } } @@ -556,22 +548,22 @@ U0 HDAudioTask(I64) } } -U0 HDRst() +U0 HDReset() { - U32 d, *_d = hda.bar + HD_GCTL; + U32 d; HDStop(TRUE, TRUE); - *_d = 0; //rst + HDAudioRegWriteU32(HD_GCTL, 0); //rst // ?? do { Sleep(1); - d = *_d; + d = HDAudioRegReadU32(HD_GCTL); } while (d & 1); - *_d = 1; + HDAudioRegWriteU32(HD_GCTL, 1); //?? do { Sleep(1); - d = *_d; + d = HDAudioRegReadU32(HD_GCTL); } while (!(d & 1)); Sleep(1); } @@ -609,9 +601,7 @@ U0 HDAudioUncachedInit() public Bool HDAudioInit(I64 hd_bus, I64 hd_dev, I64 hd_fun) { I64 i; - U32 *_d; - U16 w, *_w, val; - U8 *_b; + U16 w, val; if (hda.bar) HDAudioEnd; @@ -628,52 +618,40 @@ public Bool HDAudioInit(I64 hd_bus, I64 hd_dev, I64 hd_fun) val |= PCI_CMDF_IOEN | PCI_CMDF_BMEN | PCI_CMDF_INTD | PCI_CMDF_MSEN; PCIWriteU16(hd_bus, hd_dev, hd_fun, PCIR_COMMAND, val); - HDRst; + HDReset; hda.corb = CAllocAligned(HD_CORB_ENTRIES * sizeof(U32), 128, hda.hc); - _d = hda.bar + HD_CORBLBASE; - *_d = hda.corb(I64).u32[0]; - _d = hda.bar + HD_CORBUBASE; - *_d = hda.corb(I64).u32[1]; + HDAudioRegWriteU32(HD_CORBLBASE, hda.corb(I64).u32[0]); + HDAudioRegWriteU32(HD_CORBUBASE, hda.corb(I64).u32[1]); hda.rirb = CAllocAligned(HD_RIRB_ENTRIES * sizeof(I64), 128, hda.hc); - _d = hda.bar + HD_RIRBLBASE; - *_d = hda.rirb(I64).u32[0]; - _d = hda.bar + HD_RIRBUBASE; - *_d = hda.rirb(I64).u32[1]; + HDAudioRegWriteU32(HD_RIRBLBASE, hda.rirb(I64).u32[0]); + HDAudioRegWriteU32(HD_RIRBUBASE, hda.rirb(I64).u32[1]); - _w = hda.bar + HD_CORBRP; - *_w = 0x8000; //Rst read ptr + HDAudioRegWriteU16(HD_CORBRP, 0x8000); //Rst read ptr // ?? do { Yield; - w = *_w; + w = HDAudioRegReadU16(HD_CORBRP); } while (!(w & 0x8000)); - *_w = 0x0000; //Rst read ptr + HDAudioRegWriteU16(HD_CORBRP, 0x0000); //Rst read ptr // ?? do { Yield; - w = *_w; + w = HDAudioRegReadU16(HD_CORBRP); } while (w & 0x8000); - _w = hda.bar + HD_RIRBWP; - *_w = 0x8000; //Rst write ptr + HDAudioRegWriteU16(HD_RIRBWP, 0x8000); //Rst write ptr // ?? - _b = hda.bar + HD_CORBCTL; - *_b = 0x02; //Run - _b = hda.bar + HD_RIRBCTL; - *_b = 0x02; //Run + HDAudioRegWriteU8(HD_CORBCTL, 0x02); //Run // ?? + HDAudioRegWriteU8(HD_RIRBCTL, 0x02); //Run // ?? - _w = hda.bar + HD_CORBWP; - hda.corb_wp = *_w; - _w = hda.bar + HD_RIRBWP; - hda.rirb_rp = *_w; + hda.corb_wp = HDAudioRegReadU16(HD_CORBWP); + hda.rirb_rp = HDAudioRegReadU16(HD_RIRBWP); hda.ostr0_bdl = CAllocAligned(HD_BDL_ENTRIES * sizeof(CHDBufDesc), 128, hda.hc); - _d = hda.bar + OSTR0 + STRBDPL; - *_d = hda.ostr0_bdl(I64).u32[0]; - _d = hda.bar + OSTR0 + STRBDPU; - *_d = hda.ostr0_bdl(I64).u32[1]; + HDAudioRegWriteU32(OSTR0 + STRBDPL, hda.ostr0_bdl(I64).u32[0]); + HDAudioRegWriteU32(OSTR0 + STRBDPU, hda.ostr0_bdl(I64).u32[1]); for (i = 0; i < 2; i++) { hda.ostr0_bdl[i].buf = hda.ostr0_buf[i] = CAllocAligned(SND_BUF_LEN * sizeof(SND_OUT_CONTAINER), 128, hda.hc); @@ -682,10 +660,8 @@ public Bool HDAudioInit(I64 hd_bus, I64 hd_dev, I64 hd_fun) } hda.istr0_bdl = CAllocAligned(HD_BDL_ENTRIES * sizeof(CHDBufDesc), 128, hda.hc); - _d = hda.bar + ISTR0 + STRBDPL; - *_d = hda.istr0_bdl(I64).u32[0]; - _d = hda.bar + ISTR0 + STRBDPU; - *_d = hda.istr0_bdl(I64).u32[1]; + HDAudioRegWriteU32(ISTR0 + STRBDPL, hda.istr0_bdl(I64).u32[0]); + HDAudioRegWriteU32(ISTR0 + STRBDPU, hda.istr0_bdl(I64).u32[1]); for (i = 0; i < 2; i++) { hda.istr0_bdl[i].buf = hda.istr0_buf[i] = CAllocAligned(SND_BUF_LEN * sizeof(SND_IN_CONTAINER), 128, hda.hc); @@ -693,8 +669,7 @@ public Bool HDAudioInit(I64 hd_bus, I64 hd_dev, I64 hd_fun) hda.istr0_bdl[i].ctrl = 1; } - _w = hda.bar + HD_STATESTS; - w = *_w; + w = HDAudioRegReadU16(HD_STATESTS); while (w) { hda.cad = Bsf(w); @@ -702,23 +677,15 @@ public Bool HDAudioInit(I64 hd_bus, I64 hd_dev, I64 hd_fun) { HDTraverse(hda.cad, 0); - _d = hda.bar + OSTR0 + STRLPIB; - *_d = 0; - _d = hda.bar + OSTR0 + STRCBL; - *_d = HD_POS_BUF_MULTIPLES * SND_BUF_LEN * sizeof(SND_OUT_CONTAINER); - _w = hda.bar + OSTR0 + STRLVI; - *_w = 1; //last valid idx - _w = hda.bar + OSTR0 + STRFMT; - *_w = HD_DFT_OUT_FMT; - - _d = hda.bar + ISTR0 + STRLPIB; - *_d = 0; - _d = hda.bar + ISTR0 + STRCBL; - *_d = HD_POS_BUF_MULTIPLES * SND_BUF_LEN * sizeof(SND_IN_CONTAINER); - _w = hda.bar + ISTR0 + STRLVI; - *_w = 1; //last valid idx - _w = hda.bar + ISTR0 + STRFMT; - *_w = HD_DFT_IN_FMT; + HDAudioRegWriteU32(OSTR0 + STRLPIB, 0); + HDAudioRegWriteU32(OSTR0 + STRCBL, HD_POS_BUF_MULTIPLES * SND_BUF_LEN * sizeof(SND_OUT_CONTAINER)); + HDAudioRegWriteU16(OSTR0 + STRLVI, 1); //last valid idx // ?? + HDAudioRegWriteU16(OSTR0 + STRFMT, HD_DFT_OUT_FMT); + + HDAudioRegWriteU32(ISTR0 + STRLPIB, 0); + HDAudioRegWriteU32(ISTR0 + STRCBL, HD_POS_BUF_MULTIPLES * SND_BUF_LEN * sizeof(SND_IN_CONTAINER)); + HDAudioRegWriteU16(ISTR0 + STRLVI, 1); //last valid idx // ?? + HDAudioRegWriteU16(ISTR0 + STRFMT, HD_DFT_IN_FMT); LBts(&sys_semas[SEMA_SOUND], 0); //turn off until cfg completed LBtr(&snd_flags, Sf_FILLING_OUT); From c370588653fea16d75eb7f33056b86f3f0927038 Mon Sep 17 00:00:00 2001 From: TomAwezome Date: Sat, 31 Dec 2022 01:10:35 -0500 Subject: [PATCH 22/23] Replace HDAudioEnd Free calls with FreeAll. (Thanks Slapparoo for implementing FreeAll) --- src/Home/Sound/HDAudio1/Sup1HDAudio/HDAudio.ZC | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/Home/Sound/HDAudio1/Sup1HDAudio/HDAudio.ZC b/src/Home/Sound/HDAudio1/Sup1HDAudio/HDAudio.ZC index 67fa8de4b..c0da3afce 100644 --- a/src/Home/Sound/HDAudio1/Sup1HDAudio/HDAudio.ZC +++ b/src/Home/Sound/HDAudio1/Sup1HDAudio/HDAudio.ZC @@ -576,16 +576,9 @@ public U0 HDAudioEnd(Bool rst = TRUE) Kill(hda.task); hda.task = NULL; if (rst) - HDRst; - Free(hda.corb); - Free(hda.rirb); - Free(hda.o_tmp_buf); - Free(hda.ostr0_buf[0]); - Free(hda.ostr0_buf[1]); - Free(hda.istr0_buf[0]); - Free(hda.istr0_buf[1]); - Free(hda.ostr0_bdl); - Free(hda.istr0_bdl); + HDReset; + FreeAll(hda.corb, hda.rirb, hda.o_tmp_buf, hda.ostr0_buf[0], hda.ostr0_buf[1], hda.istr0_buf[0], hda.istr0_buf[1], + hda.ostr0_bdl, hda.istr0_bdl); Mem32DevFree(hda.bar); hda.bar = NULL; } From f9bb43799b4cafbbea7109295132dd8ef5120507 Mon Sep 17 00:00:00 2001 From: TomAwezome Date: Sun, 1 Jan 2023 23:01:45 -0500 Subject: [PATCH 23/23] Replace DFT with DEFAULT in HDAudio code. --- .../Sound/HDAudio1/Sup1HDAudio/HDAudio.ZC | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/Home/Sound/HDAudio1/Sup1HDAudio/HDAudio.ZC b/src/Home/Sound/HDAudio1/Sup1HDAudio/HDAudio.ZC index c0da3afce..407d5e385 100644 --- a/src/Home/Sound/HDAudio1/Sup1HDAudio/HDAudio.ZC +++ b/src/Home/Sound/HDAudio1/Sup1HDAudio/HDAudio.ZC @@ -41,8 +41,8 @@ I64 snd_flags; #define HD_32_BIT 4 #define HD_48kHz 0 -#define HD_DFT_OUT_FMT (HD_2_CHAN + HD_24_BIT << 4 + HD_48kHz << 8) -#define HD_DFT_IN_FMT (HD_2_CHAN + HD_16_BIT << 4 + HD_48kHz << 8) +#define HD_DEFAULT_OUT_FMT (HD_2_CHAN + HD_24_BIT << 4 + HD_48kHz << 8) +#define HD_DEFAULT_IN_FMT (HD_2_CHAN + HD_16_BIT << 4 + HD_48kHz << 8) #define HD_POS_BUF_MULTIPLES 0x1000 @@ -150,14 +150,14 @@ I64 snd_flags; #define VERB_SUB_SYS_ID2_SET 0x72200 #define VERB_SUB_SYS_ID3_GET 0xF2000 #define VERB_SUB_SYS_ID3_SET 0x72300 -#define VERB_CFG_DFT0_GET 0xF1C00 -#define VERB_CFG_DFT0_SET 0x71C00 -#define VERB_CFG_DFT1_GET 0xF1C00 -#define VERB_CFG_DFT1_SET 0x71D00 -#define VERB_CFG_DFT2_GET 0xF1C00 -#define VERB_CFG_DFT2_SET 0x71E00 -#define VERB_CFG_DFT3_GET 0xF1C00 -#define VERB_CFG_DFT3_SET 0x71F00 +#define VERB_CFG_DEFAULT0_GET 0xF1C00 +#define VERB_CFG_DEFAULT0_SET 0x71C00 +#define VERB_CFG_DEFAULT1_GET 0xF1C00 +#define VERB_CFG_DEFAULT1_SET 0x71D00 +#define VERB_CFG_DEFAULT2_GET 0xF1C00 +#define VERB_CFG_DEFAULT2_SET 0x71E00 +#define VERB_CFG_DEFAULT3_GET 0xF1C00 +#define VERB_CFG_DEFAULT3_SET 0x71F00 #define VERB_STRIPE_CTL_GET 0xF2400 #define VERB_STRIPE_CTL_SET 0x72400 #define VERB_RST 0x7FF00 @@ -382,7 +382,7 @@ U0 HDTraverse(I64 cad, I64 nid) // HDWriteCORBSync(cad, nid, VERB_CHAN_STREAM_ID_SET + 0x00); // else HDWriteCORBSync(cad, nid, VERB_CHAN_STREAM_ID_SET + 0x10); - HDWriteCORBSync(cad, nid, VERB_STREAM_FMT_SET + HD_DFT_OUT_FMT); // TODO: check format streams support ? + HDWriteCORBSync(cad, nid, VERB_STREAM_FMT_SET + HD_DEFAULT_OUT_FMT); // TODO: check format streams support ? HDWriteCORBSync(cad, nid, VERB_PROCESS_STATE_SET + 0x01); break; case AWT_INPUT: @@ -390,7 +390,7 @@ U0 HDTraverse(I64 cad, I64 nid) HDWriteCORBSync(cad, nid, VERB_CHAN_STREAM_ID_SET + 0x00); // else // HDWriteCORBSync(cad, nid, VERB_CHAN_STREAM_ID_SET + 0x20); - HDWriteCORBSync(cad, nid, VERB_STREAM_FMT_SET + HD_DFT_IN_FMT); // TODO: check format streams support ? + HDWriteCORBSync(cad, nid, VERB_STREAM_FMT_SET + HD_DEFAULT_IN_FMT); // TODO: check format streams support ? HDWriteCORBSync(cad, nid, VERB_PROCESS_STATE_SET + 0x01); break; case AWT_PIN_COMPLEX: @@ -673,12 +673,12 @@ public Bool HDAudioInit(I64 hd_bus, I64 hd_dev, I64 hd_fun) HDAudioRegWriteU32(OSTR0 + STRLPIB, 0); HDAudioRegWriteU32(OSTR0 + STRCBL, HD_POS_BUF_MULTIPLES * SND_BUF_LEN * sizeof(SND_OUT_CONTAINER)); HDAudioRegWriteU16(OSTR0 + STRLVI, 1); //last valid idx // ?? - HDAudioRegWriteU16(OSTR0 + STRFMT, HD_DFT_OUT_FMT); + HDAudioRegWriteU16(OSTR0 + STRFMT, HD_DEFAULT_OUT_FMT); HDAudioRegWriteU32(ISTR0 + STRLPIB, 0); HDAudioRegWriteU32(ISTR0 + STRCBL, HD_POS_BUF_MULTIPLES * SND_BUF_LEN * sizeof(SND_IN_CONTAINER)); HDAudioRegWriteU16(ISTR0 + STRLVI, 1); //last valid idx // ?? - HDAudioRegWriteU16(ISTR0 + STRFMT, HD_DFT_IN_FMT); + HDAudioRegWriteU16(ISTR0 + STRFMT, HD_DEFAULT_IN_FMT); LBts(&sys_semas[SEMA_SOUND], 0); //turn off until cfg completed LBtr(&snd_flags, Sf_FILLING_OUT);