source: cmedia/trunk/Drv16/ossidc16.cpp@ 354

Last change on this file since 354 was 354, checked in by stevenhl, 17 years ago

Import untested baseline cmedia sources, work products and binaries
Binaries and work products should be deleted from repository.
once new builds are verified to work.

File size: 17.9 KB
Line 
1/* $Id: ossidc16.cpp,v 1.6 2001/04/30 21:07:58 sandervl Exp $ */
2
3//******************************************************************************
4// IDC interface for calling 32 bits SB Live PDD + IDC entrypoint
5//
6// Copyright 2000 Sander van Leeuwen (sandervl@xs4all.nl)
7//
8//******************************************************************************
9extern "C" { // 16-bit header files are not C++ aware
10#define INCL_16
11#define INCL_DOSINFOSEG
12#include <os2.h>
13}
14
15#include <ctype.h>
16#include <string.h>
17#include <devhelp.h>
18
19#include "idc_vdd.h"
20#include <include.h>
21#include "rm.hpp"
22#include "memutil.h"
23#include "irq.hpp"
24#include "stream.hpp"
25#include "wavestrm.hpp"
26#include "fmsynth.hpp"
27#include "mpu401.hpp"
28#include "malloc.h"
29#include <ossidc.h>
30#include <dbgos2.h>
31#include <sbversion.h>
32#include <apmioctl.h>
33
34#include "trace.h"
35
36// Rudi:
37// not present in include.h
38unsigned long _DXAX(void);
39#pragma aux _DXAX = \
40 value [dx ax] \
41 parm nomemory \
42 modify nomemory;
43
44
45//init.c
46extern ResourceManager* pRM; // Resource manager object.
47
48static IDCTABLE OSSIDCTable;
49
50extern "C" ULONG __far __cdecl OSSIDC_ENTRY(ULONG cmd, IDC16_PACKET FAR *packet);
51
52
53//******************************************************************************
54//******************************************************************************
55BOOL OSS16_AttachToPdd()
56{
57 if( DevHelp_AttachDD((NPSZ)DRVNAME32,(NPBYTE)&OSSIDCTable) == 0 &&
58 (BOOL)CallOSS32(IDC32_INIT, 0, (ULONG)(VOID FAR *)OSSIDC_ENTRY, 0, 0, 0) )
59 {
60 FMSYNTH *pSynth = (FMSYNTH *)GetHardwareDevice(AUDIOHW_FMSYNTH_PLAY);
61 if( pSynth ) pSynth->Initialize();
62 return TRUE;
63 }
64
65 return FALSE;
66}
67//******************************************************************************
68//******************************************************************************
69void OSS16_DetachFromPdd()
70{
71 CallOSS32(IDC32_EXIT, 0, 0, 0, 0, 0);
72}
73//******************************************************************************
74//******************************************************************************
75ULONG MMPMToOSSStreamType(USHORT streamtype)
76{
77 switch(streamtype) {
78
79 case STREAM_WAVE_CAPTURE:
80 return OSS_STREAM_WAVEIN;
81
82 case STREAM_WAVE_PLAY:
83 return OSS_STREAM_WAVEOUT;
84
85 case STREAM_FMSYNTH_CAPTURE:
86 case STREAM_MPU401_CAPTURE:
87 return OSS_STREAM_MIDIIN;
88
89 case STREAM_FMSYNTH_PLAY:
90 case STREAM_MPU401_PLAY:
91 return OSS_STREAM_MIDIOUT;
92 }
93
94 DebugInt3();
95 return -1;
96}
97
98#define OssStrmType(s) MMPMToOSSStreamType((s)->usStreamType)
99
100//******************************************************************************
101//******************************************************************************
102ULONG OSS16_OpenStream(STREAM *stream)
103{
104 ULONG uTemp =
105
106 CallOSS32(IDC32_STREAM_OPEN, stream->usSysFileNum, OssStrmType(stream), 0, 0, 0);
107
108 SYSTRACE(240, 1, uTemp);
109 return uTemp;
110}
111//******************************************************************************
112//******************************************************************************
113void OSS16_CloseStream(STREAM *stream)
114{
115 SYSTRACE(240, 255, stream->ulStreamId);
116
117 CallOSS32(IDC32_STREAM_CLOSE, stream->usSysFileNum,
118 OssStrmType(stream), stream->ulStreamId, 0, 0);
119}
120//******************************************************************************
121//******************************************************************************
122ULONG OSS16_OpenMidiStream(MIDITYPE midiType)
123{
124 return CallOSS32(IDC32_STREAM_OPEN, 0x666,
125 (midiType == MIDI_RECEIVE) ? OSS_STREAM_MIDIOUT: OSS_STREAM_MIDIIN, 0, 0, 0);
126}
127//******************************************************************************
128//******************************************************************************
129BOOL OSS16_WriteMidiByte(ULONG streamid, BYTE midiByte)
130{
131 return (BOOL)CallOSS32(IDC32_MIDI_WRITE, 0x666,
132 OSS_STREAM_MIDIOUT, streamid, midiByte, 0);
133}
134//******************************************************************************
135//******************************************************************************
136int OSS16_ReadMidiBytes(ULONG streamid, char far *buffer, int bufsize)
137{
138 return (int)CallOSS32(IDC32_MIDI_READ, 0x666,
139 OSS_STREAM_MIDIIN, streamid, (ULONG)buffer, bufsize);
140}
141//******************************************************************************
142//******************************************************************************
143void OSS16_CloseMidiStream(MIDITYPE midiType, ULONG streamid)
144{
145 CallOSS32(IDC32_STREAM_CLOSE, 0x666,
146 (midiType == MIDI_RECEIVE) ? OSS_STREAM_MIDIOUT : OSS_STREAM_MIDIIN, streamid, 0, 0);
147}
148//******************************************************************************
149//******************************************************************************
150BOOL OSS16_StartStream(STREAM *stream)
151{
152 SYSTRACE(240, 2, stream->ulStreamId);
153
154 return (BOOL)CallOSS32(IDC32_STREAM_START, stream->usSysFileNum,
155 OssStrmType(stream), stream->ulStreamId, 0, 0);
156}
157//******************************************************************************
158//******************************************************************************
159BOOL OSS16_PauseStream(STREAM *stream)
160{
161 SYSTRACE(240, 3, stream->ulStreamId);
162
163 return (BOOL)CallOSS32(IDC32_STREAM_PAUSE, stream->usSysFileNum,
164 OssStrmType(stream), stream->ulStreamId, 0, 0);
165}
166//******************************************************************************
167//******************************************************************************
168BOOL OSS16_StopStream(STREAM *stream)
169{
170 SYSTRACE(240, 4, stream->ulStreamId);
171
172 return (BOOL)CallOSS32(IDC32_STREAM_STOP, stream->usSysFileNum,
173 OssStrmType(stream), stream->ulStreamId, 0, 0);
174}
175//******************************************************************************
176//******************************************************************************
177BOOL OSS16_StreamReset(STREAM *stream)
178{
179 SYSTRACE(240, 5, stream->ulStreamId);
180
181 return (BOOL)CallOSS32(IDC32_STREAM_RESET, stream->usSysFileNum,
182 OssStrmType(stream), stream->ulStreamId, 0, 0);
183}
184//******************************************************************************
185//******************************************************************************
186BOOL OSS16_StreamSetFormat(STREAM *stream, ULONG param1)
187{
188 SYSTRACE(240, 6, stream->ulStreamId);
189
190 return (BOOL)CallOSS32(IDC32_STREAM_IOCTL, stream->usSysFileNum,
191 OssStrmType(stream), stream->ulStreamId, IOCTL_SETFORMAT, param1);
192}
193//******************************************************************************
194//Returns nr of bytes written
195//******************************************************************************
196ULONG OSS16_StreamAddBuffer(STREAM *stream, ULONG buffer, ULONG size)
197{
198 return CallOSS32(IDC32_STREAM_ADDBUFFER, stream->usSysFileNum,
199 OssStrmType(stream), stream->ulStreamId, buffer, size);
200}
201//******************************************************************************
202//******************************************************************************
203BOOL OSS16_StreamGetPos(STREAM *stream, ULONG FAR *pos)
204{
205 return (BOOL)CallOSS32(IDC32_STREAM_IOCTL, stream->usSysFileNum,
206 OssStrmType(stream), stream->ulStreamId, IOCTL_GETPOS, (ULONG)pos);
207}
208//******************************************************************************
209//******************************************************************************
210BOOL OSS16_StreamSetFragment(STREAM *stream, ULONG fragsize)
211{
212 ULONG fsize = fragsize;
213
214 SYSTRACE(240, 7, stream->ulStreamId);
215
216 return (BOOL)CallOSS32(IDC32_STREAM_IOCTL, stream->usSysFileNum,
217 OssStrmType(stream), stream->ulStreamId,
218 IOCTL_SETFRAGMENT, (ULONG)((ULONG FAR *)&fsize));
219}
220//******************************************************************************
221//******************************************************************************
222/*
223BOOL OSS16_SetMasterVol(STREAM *stream, ULONG volume)
224{
225 return (BOOL)CallOSS32(IDC32_STREAM_MIXER, stream->usSysFileNum,
226 OssStrmType(stream), stream->ulStreamId, MIX_SETMASTERVOL, volume);
227}
228*/
229//******************************************************************************
230//******************************************************************************
231/*
232BOOL OSS16_SetWaveOutVol(STREAM *stream, ULONG volume)
233{
234 return (BOOL)CallOSS32(IDC32_STREAM_MIXER, stream->usSysFileNum,
235 OssStrmType(stream), stream->ulStreamId, MIX_SETWAVEVOL, volume);
236}
237*/
238//******************************************************************************
239//******************************************************************************
240BOOL OSS16_SetVolume(STREAM *stream, USHORT line, ULONG volume)
241{
242 return (BOOL)CallOSS32(IDC32_STREAM_MIXER, stream->usSysFileNum,
243 OssStrmType(stream), stream->ulStreamId, line, volume);
244}
245//******************************************************************************
246//******************************************************************************
247BOOL OSS16_SetGlobalVol(USHORT usSysFileNum, USHORT line, ULONG volume)
248{
249 return (BOOL)CallOSS32(IDC32_STREAM_MIXER, usSysFileNum, 0, 0, line, volume);
250}
251//******************************************************************************
252//******************************************************************************
253ULONG OSS16_StreamGetSpace(STREAM *stream)
254{
255 return CallOSS32(IDC32_STREAM_GETSPACE, stream->usSysFileNum,
256 OssStrmType(stream), stream->ulStreamId, 0, 0);
257}
258//******************************************************************************
259//******************************************************************************
260ULONG OSS16_DevEscape(USHORT usChipNo,
261 USHORT usCommand, ULONG ulParam1, ULONG ulParam2)
262{
263 return CallOSS32(IDC32_DEVESCAPE, 0, usChipNo, usCommand, ulParam1, ulParam2);
264}
265
266//******************************************************************************
267//******************************************************************************
268ULONG CallOSS32(USHORT cmd, USHORT fileid,
269 ULONG param1, ULONG param2, ULONG param3, ULONG param4)
270{
271/*
272 ULONG rc = 0;
273 ULONG idcptr = (ULONG)OSSIDCTable.ProtIDCEntry;
274 ULONG idcparm;
275 IDC32_PACKET idcpacket;
276
277 if(idcptr == 0)
278 return(0);
279
280 idcpacket.fileid = fileid;
281 idcpacket.param1 = param1;
282 idcpacket.param2 = param2;
283 idcpacket.param3 = param3;
284 idcpacket.param4 = param4;
285 idcparm = (ULONG)&idcpacket;
286
287 _asm {
288 pusha
289 mov cx, cmd
290 mov dx, word ptr [idcparm+2]
291 mov bx, word ptr [idcparm]
292 call dword ptr [idcptr]
293 mov word ptr [rc], ax
294 mov word ptr [rc+2], dx
295 popa
296 }
297 return(rc);
298*/
299
300 IDC32_PACKET idcpacket;
301
302 idcpacket.fileid = fileid;
303 idcpacket.param1 = param1;
304 idcpacket.param2 = param2;
305 idcpacket.param3 = param3;
306 idcpacket.param4 = param4;
307
308 __asm {
309 mov ax, word ptr [OSSIDCTable + 6]
310 mov dx, word ptr [OSSIDCTable + 6 + 2]
311 or ax, dx
312 jz l1 ; DX:AX == 0
313
314 push bx
315 push cx
316 mov cx, [cmd]
317 lea bx, [idcpacket]
318 mov dx, ss
319 call dword ptr [OSSIDCTable + 6] ; OSSIDCTable.ProtIDCEntry
320 pop cx
321 pop bx ; DX:AX == result
322
323 l1:
324 }
325
326 return _DXAX();
327}
328
329//******************************************************************************
330//******************************************************************************
331BOOL /*__far __cdecl __loadds __saveregs*/ OSS_Irq_Handler(int irqnr,
332 unsigned long param)
333{
334#if 1
335 IDC32_PACKET idcpacket;
336
337 idcpacket.irq.irqnr = irqnr;
338 idcpacket.irq.param = param;
339
340 __asm {
341 mov cx, IDC32_IRQ
342 lea bx, [idcpacket]
343 mov dx, ss
344 call dword ptr [OSSIDCTable + 6]
345 }
346
347 return _AX();
348
349#else
350 return (BOOL) CallOSS32(IDC32_IRQ, 0, irqnr, param, 0, 0);
351
352#endif
353}
354
355//******************************************************************************
356//******************************************************************************
357
358// extern "C" ULONG __cdecl __saveregs OSSIDC_EntryPoint(ULONG cmd, IDC16_PACKET FAR *packet)
359
360extern "C" ULONG __pascal OSSIDC_EntryPoint(USHORT cmd, IDC16_PACKET FAR *packet)
361{
362 BOOL fPciDevice = TRUE;
363 int i;
364
365 switch( cmd )
366 {
367/*
368 case IDC16_INIT:
369 break;
370
371 case IDC16_EXIT:
372 OSSIDCTable.ProtIDCEntry = 0;
373 break;
374*/
375 case IDC16_SETIRQ:
376 {
377 IRQ *pIrq = pMakeIRQ((USHORT)packet->irq.irqnr);
378 if(!pIrq) return FALSE;
379
380 if(pIrq->bAddHandler(OSS_Irq_Handler, packet->irq.param) == FALSE) {
381 DebugInt3();
382 return FALSE;
383 }
384
385 if(pIrq->bEnableHandler(OSS_Irq_Handler) == FALSE) {
386 DebugInt3();
387 return FALSE;
388 }
389 return TRUE;
390 }
391 case IDC16_FREEIRQ:
392 {
393 IRQ *pIrq = getIRQ((USHORT)packet->irq.irqnr);
394 if(!pIrq) return FALSE;
395
396 if(pIrq->bDisableHandler(OSS_Irq_Handler) == FALSE) {
397 DebugInt3();
398 return FALSE;
399 }
400 return TRUE;
401 }
402
403 case IDC16_FIND_PNPDEVICE:
404 fPciDevice = FALSE;
405 //fall through
406 case IDC16_FIND_PCIDEVICE:
407 {
408 LDev_Resources* pResources;
409 IDC_RESOURCE FAR *idcres = (IDC_RESOURCE FAR *)packet->finddev.pResource;
410 BOOL fResult = FALSE;
411
412 if( !pRM->bIsDevDetected(packet->finddev.devid,
413 SEARCH_ID_DEVICEID, fPciDevice) ) return 0;
414
415//Rudi: don't try to allocate resources again !
416// pResources = pRM->pGetDevResources(packet->finddev.devid,
417// SEARCH_ID_DEVICEID, fPciDevice);
418
419 pResources = pRM->GetRMDetectedResources(packet->finddev.devid,
420 SEARCH_ID_DEVICEID, fPciDevice, FALSE);
421 if( !pResources ) return 0;
422
423 if( !pResources->isEmpty() ) {
424 // Available device resources identified
425 for(i=0;i<MAX_ISA_Dev_IO;i++) {
426 idcres->io[i] = pResources->uIOBase[i];
427 idcres->iolength[i] = pResources->uIOLength[i];
428 }
429 for(i=0;i<MAX_ISA_Dev_IRQ;i++) {
430 idcres->irq[i] = pResources->uIRQLevel[i];
431 }
432 for(i=0;i<MAX_ISA_Dev_DMA;i++) {
433 idcres->dma[i] = pResources->uDMAChannel[i];
434 }
435 for(i=0;i<MAX_ISA_Dev_MEM;i++) {
436 idcres->mem[i] = pResources->uMemBase[i];
437 idcres->memlength[i] = pResources->uMemLength[i];
438 }
439
440 fResult = TRUE;
441 }
442
443 delete pResources;
444 return fResult;
445 }
446 case IDC16_MALLOC:
447 {
448 LIN linaddr;
449 ULONG near *addr16 = (ULONG near *)malloc((USHORT)packet->malloc.size+4);
450 ULONG far *addr = (ULONG far *)addr16;
451
452 if(addr16 == NULL) {
453 return 0;
454 }
455 *addr = (ULONG)addr;
456 if(DevHelp_VirtToLin(SELECTOROF(addr), OFFSETOF(addr), &linaddr)) {
457 dprintf(("DevHelp_VirtToLin failed for %x:%x\n", SELECTOROF(addr), OFFSETOF(addr)));
458 DebugInt3();
459 return 0;
460 }
461 return linaddr;
462 }
463 case IDC16_FREE:
464 free((void __near *)(void far *)packet->free.addr);
465 break;
466 case IDC16_VMALLOC:
467 break;
468 case IDC16_VMFREE:
469 break;
470 case IDC16_PROCESS:
471 {
472 PWAVESTREAM pStream;
473
474 if( packet->process.type == OSS_STREAM_WAVEOUT ) {
475 pStream = (PWAVESTREAM)FindActiveStream(STREAM_WAVE_PLAY, packet->process.streamid);
476 } else if( packet->process.type == OSS_STREAM_WAVEIN ) {
477 pStream = (PWAVESTREAM)FindActiveStream(STREAM_WAVE_CAPTURE, packet->process.streamid);
478 } else {
479 MPU_401::processIrq(packet->process.streamid); return 0;
480 }
481/*
482 } else if( packet->process.type == OSS_STREAM_MIDIOUT ) {
483 MPU_401::processIrq(packet->process.streamid); return 0;
484 } else if( packet->process.type == OSS_STREAM_MIDIIN ) {
485 MPU_401::processIrq(packet->process.streamid); return 0;
486 }
487*/
488
489// Rudi: we should arm a context hook here to do the real processing !!
490 if(pStream) {
491// pStream->Process();
492 pStream->ArmProcessHook();
493 return 0;
494 }
495
496 dprintf(("Stream %lx not found or not active!", packet->process.streamid));
497 break;
498 }
499
500 }
501 return 0;
502}
503
504
505//******************************************************************************
506//******************************************************************************
507
508static USHORT usResumeCounter;
509static ULONG ulHookHandle;
510
511
512void __far __cdecl APMHookProc(void)
513{
514 __asm pushad
515 __asm push ds
516 __asm push es
517 __asm mov bx, seg usResumeCounter
518 __asm mov ds, bx
519
520 if( usResumeCounter == 0 ) {
521 PSTREAM pStream = EnumStreams(NULL);
522
523 while( pStream ) {
524 if( pStream->usStreamState == STREAM_SUSPENDED ) pStream->ResumeStream();
525 pStream = EnumStreams(pStream);
526 }
527
528 if( ulHookHandle ) DevHelp_FreeCtxHook(ulHookHandle);
529 } else if( --usResumeCounter == 0 ) {
530 DevHelp_ArmCtxHook(0, ulHookHandle);
531 DevHelp_ResetTimer((NPFN)APMHookProc);
532 }
533
534 __asm pop es
535 __asm pop ds
536 __asm popad
537}
538
539
540
541USHORT FAR OSS16_APMEvent(struct _APMIDC_NOTIFY_PKT FAR *pNotifyPkt);
542#pragma aux OSS16_APMEvent parm [es bx];
543
544USHORT FAR OSS16_APMEvent(struct _APMIDC_NOTIFY_PKT FAR *pNotifyPkt)
545{
546 PAPMIDC_NOTIFY_PKT pEvent = pNotifyPkt;
547 PSTREAM pStream;
548 CONTROL_PARM Param;
549
550// DevSysTrace(240, 254, sizeof(APMIDC_NOTIFY_PKT), pEvent);
551
552 switch( pEvent->SubId )
553 {
554 case APMEVENT_SetPowerState :
555 if( pEvent->PwrState == APMSTATE_Suspend ) {
556
557 pStream = EnumStreams(NULL);
558 while( pStream ) {
559 if( pStream->isActive() ) {
560 pStream->PauseStream(&Param);
561 pStream->usStreamState = STREAM_SUSPENDED;
562 }
563 pStream = EnumStreams(pStream);
564 }
565
566 // power down the chip
567 OSS16_DevEscape(0, 255, 0x00400000, 0);
568
569// } else if( pEvent->PwrState == APMSTATE_Standby ) {
570// } else if( pEvent->PwrState == APMSTATE_Off ) {
571 }
572 break;
573
574// case APMEVENT_StandbyResume :
575// break;
576
577 case APMEVENT_NormalResume :
578 case APMEVENT_CriticalResume :
579 // power up the chip
580 OSS16_DevEscape(0, 255, 0, 0x00400000);
581
582 usResumeCounter = 8;
583 if( DevHelp_AllocateCtxHook((NPFN)APMHookProc, &ulHookHandle) == 0 ) {
584 if( DevHelp_TickCount((NPFN)APMHookProc, 32) != 0 ) {
585 usResumeCounter = 0; DevHelp_ArmCtxHook(0, ulHookHandle);
586 }
587 } else {
588 usResumeCounter = 0; ulHookHandle = 0; APMHookProc();
589 }
590 break;
591 }
592
593 return 0;
594}
595
596
597
Note: See TracBrowser for help on using the repository browser.