boot3/OS/IntModemMgr.a
Elliot Nunn 5b0f0cc134 Bring in CubeE sources
Resource forks are included only for .rsrc files. These are DeRezzed into their data fork. 'ckid' resources, from the Projector VCS, are not included.

The Tools directory, containing mostly junk, is also excluded.
2017-12-26 10:02:57 +08:00

945 lines
31 KiB
Plaintext

;__________________________________________________________________________________________________
;
; File: IntModemMgr.a
;
; Contains: Internal modem manager initialization code
;
; Written by: Steven Swenson
;
; Copyright © 1994-1994 by Apple Computer, Inc. All rights reserved.
;
; Change History (most recent first):
;
; <SM2> 1/27/94 rab Removed padForOverpatch stuff from the end of this file
; (SuperMario does not use itÉ).
; <H4> 5/23/93 SES Made changes from code review, 5/19/93.
; <H3> 5/4/93 SES Removed machine primitives and replaced them with the dispatch
; functions in the IntModemMgr.a file.
; <H2> 4/27/93 SES Altered modem manager to enhance it somewhat per code review on
; 4/22/93. Added dispatcher in this file (from ImmgPrimitives.a).
; Split primitives into machine primitives and modem primitives.
; <1> 4/8/93 SES first checked in
;__________________________________________________________________________________________________
LOAD 'StandardEqu.d'
INCLUDE 'HardwarePrivateEqu.a'
INCLUDE 'UniversalEqu.a'
INCLUDE 'ROMEqu.a'
INCLUDE 'IntModemMgrEqu.a'
INCLUDE 'IntModemMgrPrivEqu.a'
MACHINE MC68020
;----------------------------------------------------------------------------------------
; ImmgInit
;
; Entry: none
;
; Exit: none
;
; Trashes: none
;
; Uses:
;
; A1: pointer to head of modem primitive table list
; A2: pointer to modem manager globals
; A3: pointer to machine primitives table
; A4: pointer to individual modem primitives tables
;
; Sets up the internal modem manager if it should be set up. The manager will not be
; installed if the pointer in the product info record is NULL. The manager will attempt to
; install any primitives that the root table points to (see IntModemMgrPrivEqu.a).
;----------------------------------------------------------------------------------------
ImmgInit PROC EXPORT
@savedRegs REG d0-d2/a0-a4
movem.l @SavedRegs,-(sp) ; save away registers
; First check to see if the modem manager should be installed.
WITH ProductInfo
movea.l UnivInfoPtr,a0 ; get the product info table
move.l ImmgPrimPtr(a0),d0 ; get the internal modem manager primitives offset
beq.w @exit ; exit if null pointer
lea (a0,d0.l),a1 ; A1 -> immgMdmList: head of modem prim list
ENDWITH
; set up modem manager globals
move.l #immgGlobals.size,d0 ; size of globals
_NewPtr ,SYS,CLEAR ; pointer to globals -> A0
tst.w d0 ; check pointer for validity
bne.w @exit ; bad, bad, bad...
movea.l a0,a2 ; A2 -> globals pointer
; set up the machine dispatch table
WITH immgGlobals
move.l #immgDispTable.size,d0 ; size of dispatch table
_NewPtr ,SYS,CLEAR ; pointer to dispatch table -> A0
tst.w d0 ; check pointer for validity
bne.w @error1 ; bad, bad, bad...
move.l a0,dispTable(a2) ; store pointer to dispatch table in globals
movea.l a0,a3 ; A3 -> machine prim table ptr
ENDWITH
WITH immgDispTable
lea immgDispatchTable,a0 ; A0 -> pointer to ROM based dispatch table
move.l a0,d2 ; D2 -> ROM based dispatch table base for offset to absolute conversion
move.l (a0)+,(a3)+ ; copy flags and number of primitives
move.l #size,d0 ; D0 -> size of dispatch table, in bytes, including storage
sub.l #dispOffset,d0 ; D0 -> size of dispatch table in bytes ; <H4>
lsr.l #2,d0 ; D0 -> number of dispatch routines
move.w d0,-2(a3) ; put number of dispatch routines into RAM based table
bra.s @startLoop ; for DBRA loop ; <H4>
@machPrimLoop move.l (a0)+,d1 ; D1 -> offset to dispatch routine
add.l d2,d1 ; D1 -> absolute address of dispatch routine
move.l d1,(a3)+ ; copy absolute address into RAM based dispatch table
@startLoop dbra d0,@machPrimLoop ; copy all dispatch functions
ENDWITH
; set up the modem manager modem queue
WITH immgGlobals
moveq #qHeadSize,d0 ; size of a OS queue header
_NewPtr ,SYS,CLEAR ; A0 -> pointer to modem queue header
tst.w d0 ; check for valid pointer
bne.w @error2 ; bad, bad, bad...
move.l a0,mdmQ(a2) ; store pointer to modem queue in globals
ENDWITH
; save modem globals in expand mem
WITH ExpandMemRec
move.l a2,([ExpandMem],emIMdmMgrGlobs)
ENDWITH
; install the dispatcher
lea ImmgDispatch,a0 ; address of dispatcher for the trap
move.w #IntMdmMgrTrap,d0 ; internal modem manager trap number
_SetTrapAddress ,NEWTOOL
; call modem manager init to initialize any future modem manager specific things
_IModemInit
tst.w d0 ; check for modem manager init errors
bne.s @error3 ; bad, bad, bad...
; for each root table entry, attempt to install the modem primitives
WITH immgMdmList
moveq #0,d0 ; first time around, A1 is already a pointer
@modemInstall adda.l d0,a1 ; A1 -> pointer to next modem list element
move.l primTable(a1),d0 ; D0 -> offset to modem primitives table
beq.s @skipModemPrims ; no install if NULL
lea (a1,d0.l),a4 ; A4 -> pointer to modem primitives table
bsr CopyModemPrims ; copy modem primitives table into RAM
bne.s @error4 ; bad, bad, bad... ; <H4>
_IModemInstall ; install the primitives
@skipModemPrims move.l mdmListPtr(a1),d0 ; D0 -> offset to next modem list
bne.s @modemInstall ; continue installing modems until NULL pointer
ENDWITH
; install the gestalt trap
lea ImmgGestalt,a0 ; get address of gestalt code
move.l #gestaltIntModemType,d0 ; internal modem manager selector code
_NewGestalt ; install the selector
@exit movem.l (sp)+,@SavedRegs ; restore registers
rts
;----------------------------------------------------------------------------------------
; Error conditions from the modem init code above
;----------------------------------------------------------------------------------------
; have allocated an unknown number of modem primitive queue blocks and modem primitive tables
; and also have done modem manager init
@error4 move.l immgGlobals.mdmQ(a2),a1 ; A1 -> pointer to modem queue header
movea.l qHead(a1),a1 ; A1 -> pointer to first modem queue element
tst.l a1 ; check if pointer is real
beq.s @error3 ; no more modem queue elements to deallocate
WITH immgQEl
@cleanUpMdms move.l qMdmPrimPtr(a1),d0 ; D0 -> pointer to modem primitives table
beq.s @nextMdmQEl ; no pointer to deallocate
movea.l d0,a0 ; A0 -> pointer to modem primitives table
_DisposPtr ; get rid of it
@nextMdmQEl movea.l a1,a0 ; A0 -> pointer to this modem queue element
move.l qLink(a1),a1 ; A1 -> pointer to next modem queue element
_DisposPtr ; get rid of previous modem queue element
tst.l a1 ; check if the end of the list
bne.s @cleanUpMdms ; no more modem queue elements to deallocate
; call modem manager close to clean up anything done in modem manager init
_IModemClose
; have already set trap address of modem manager
@error3 move.l #UnimplTrap,d0 ; D0 -> trap word of unimplemented trap
_GetTrapAddress ,NEWTOOL ; A0 -> address of unimplemented trap
move.l #IntMdmMgrTrap,d0 ; D0 -> trap word of internal modem manager
_SetTrapAddress ,NEWTOOL ; make modem manager unimplemented
; have already allocated machine primitive table pointer
@error2 movea.l a3,a0 ; A0 -> pointer to machine primitves table
_DisposPtr ; get rid of it
; have already allocated globals pointer
@error1 movea.l a2,a0 ; A0 -> pointer to globals
_DisposPtr ; get rid of it
bra.s @exit
;----------------------------------------------------------------------------------------
; CopyModemPrims
;
; Entry: A4: pointer to ROM based modem primitives table
;
; Exit: A0: pointer to RAM based copy of modem primitives table, with absolute addresses
; D0: zero if no error, -1 if error
;
; Trashes: none
;
; Copies ROM based modem primitives table into RAM, converting addresses to primitives
; into absolute addresses. Leaves the condition codes register set to ZERO on memory
; allocation error.
;----------------------------------------------------------------------------------------
CopyModemPrims
movem.l d1-d3,-(sp) ; save registers
WITH immgPrimTable
move.l #size,d0 ; size of modem primitives table
beq.s @errorExit ; if the size of the thing is ever zero ; <H4>
_NewPtr ,SYS,CLEAR ; pointer to machine primitives table -> A0
tst.w d0 ; check pointer for validity
bne.s @errorExit ; bad, bad, bad...
move.l a0,d2 ; D2 -> pointer to RAM based modem prim table
move.l a4,d3 ; D3 -> ROM based modem table base for offset to absolute conversion
move.l (a4)+,(a0)+ ; copy flags and number of primitives
move.l #size,d0 ; D0 -> size of modem primitives table, in bytes, including storage
sub.l #primOffset,d0 ; D0 -> size of modem primitives table in bytes ; <H4>
lsr.l #2,d0 ; D0 -> number of modem primtives
move.w d0,-2(a0) ; put number of primitives into RAM based table
bra.s @startLoop ; for DBRA loop ; <H4>
@mdmPrimLoop move.l (a4)+,d1 ; D1 -> offset to primitive
add.l d3,d1 ; D1 -> absolute address of primitive
move.l d1,(a0)+ ; copy absolute address into RAM based primtive table
@startLoop dbra d0,@mdmPrimLoop ; copy all primitives
ENDWITH
movea.l d2,a0 ; A0 -> pointer to RAM based modem prims
moveq #0,d0 ; indicate no error
@exit movem.l (sp)+,d1-d3 ; restore registers
rts
@errorExit move.b #$FF,d0 ; indicate an error occurred
bra.s @exit
;----------------------------------------------------------------------------------------
; ImmgDispatch
;
; Entry: D0: high word: modem ID; low word: trap selector
; A0: may hold a pointer or data
;
; Exit: D0: result code
;
; Trashes: none
;
; Uses:
;
; A1: pointer to modem manager globals
; A2: pointer to machine primitives table
;
; Handles a modem manager call. Jumps through the machine primitives table and returns
; the result code.
;----------------------------------------------------------------------------------------
ImmgDispatch
@saveRegs REG d1/a1-a2 ; registers to save in this routine
movem.l @saveRegs,-(sp) ; save registers
; Get machine primitives table
WITH ExpandMemRec
move.l ([ExpandMem],emIMdmMgrGlobs),a1
tst.l a1 ; check for valid pointer, this should never happen
beq.s @errorNoBoard ; bad, bad, bad...
ENDWITH
; range check trap selector
WITH immgGlobals
move.l dispTable(a1),a2 ; A2 -> pointer to machine primitives
tst.l a2 ; check for valid primitives pointer
beq.s @errorInvalid ; bad, bad, bad...
ENDWITH
WITH immgDispTable
cmp.w numDisp(a2),d0 ; is the selector < number of dispatch functions
bcc.s @errorInvalid ; invalid selector
adda.l #dispOffset,a2 ; A2 -> pointer to beginning of dispatch functions
ENDWITH
; call the dispatch function to do the work
move.w d0,d1 ; D1 -> trap selector
lsl.w #2,d1 ; D1 -> offset to dispatch function address
jsr ([a2,d1.w]) ; do dispatch function
@exit movem.l (sp)+,@saveRegs ; restore registers
rts
@errorNoBoard move.w #immgNoBoardErr,d0 ; D0 -> no board error result
bra.s @exit
@errorInvalid move.w #immgInvalidSelector,d0 ; D0 -> invalid selector error result
bra.s @exit
;----------------------------------------------------------------------------------------
; ImmgGestalt
;
; Entry: D0: gestaltIntModemType
; A0: pointer for return data
;
; Exit: D0: gestalt result code
;
; Trashes: A0
;
; Finds out about the internal modem manager by calling IModemInfo.
;----------------------------------------------------------------------------------------
ImmgGestalt
_IModemInfo ; get the modem mgr information (in d0)
move.l a0,d0 ; D0 -> num modems and version
movea.l 4(sp),a0 ; get a pointer to the response longword
move.l d0,(a0) ; return type of modem
move.l (sp)+,a0 ; get the return address
add.l #8,sp ; remove paramters
move.w #noErr,(sp) ; set return error code
jmp (a0) ; return
;----------------------------------------------------------------------------------------
; Dispatch table for internal modem manager.
;----------------------------------------------------------------------------------------
immgDispatchTable
DC.W 0 ; flags
DC.W 0 ; number of primitives (filled in at init time)
DC.L mdmInit-immgDispatchTable ; offset to modem manager init routine
DC.L mdmPower-immgDispatchTable ; offset to modem manager power routine
DC.L mdmWakeUp-immgDispatchTable ; offset to modem manager wake up routine
DC.L mdmStatus-immgDispatchTable ; offset to modem manager status routine
DC.L mdmPrime-immgDispatchTable ; offset to modem manager prime routine
DC.L mdmSndCtl-immgDispatchTable ; offset to modem manager sound control routine
DC.L mdmGetInd-immgDispatchTable ; offset to modem manager get indexed routine
DC.L mdmFind-immgDispatchTable ; offset to modem manager find routine
DC.L mdmInstall-immgDispatchTable ; offset to modem manager install routine
DC.L mdmRemove-immgDispatchTable ; offset to modem manager remove routine
DC.L mdmGetName-immgDispatchTable ; offset to modem manager get name routine
DC.L mdmInfo-immgDispatchTable ; offset to modem manager info routine
DC.L mdmClose-immgDispatchTable ; offset to modem manager close routine
DC.L mdmSndVol-immgDispatchTable ; offset to modem sound volume routine
DC.L mdmSndHW-immgDispatchTable ; offset to system sound HW arbitration routine
;----------------------------------------------------------------------------------------
; mdmInit
;
; Entry: a1 = modem manager global pointer
;
; Exit: d0 = result code
;
; Trashes: none
;
; Sets up private storage for the machine primitives.
;----------------------------------------------------------------------------------------
mdmInit
move.w #immgVersion,immgGlobals.version(a1) ; store modem manager version number
move.w #noErr,d0
@exit rts
;----------------------------------------------------------------------------------------
; mdmPower
;
; Entry: d0 = high word: modem ID
; a0 = pointer to modem parameter block
; a1 = modem manager global pointer
;
; Exit: d0 = result code
;
; Trashes: none
;
; Calls modem primitive for modem power.
;----------------------------------------------------------------------------------------
mdmPower
move.w #selMPPower,d0 ; select modem power
bra.w CallMdmPrim ; make the call
;----------------------------------------------------------------------------------------
; mdmWakeUp
;
; Entry: d0 = high word: modem ID
; a0 = pointer to modem parameter block
; a1 = modem manager global pointer
;
; Exit: d0 = result code
;
; Trashes: none
;
; Calls modem primitive for wake up on ring.
;----------------------------------------------------------------------------------------
mdmWakeUp
move.w #selMPWakeUp,d0 ; select modem power
bra.w CallMdmPrim ; make the call
;----------------------------------------------------------------------------------------
; mdmStatus
;
; Entry: d0 = high word: modem ID
; a0 = pointer to modem parameter block
; a1 = modem manager global pointer
;
; Exit: d0 = result code
;
; Trashes: none
;
; Calls modem primitive for status.
;----------------------------------------------------------------------------------------
mdmStatus
move.w #selMPStatus,d0 ; select modem power
bra.w CallMdmPrim ; make the call
;----------------------------------------------------------------------------------------
; mdmPrime
;
; Entry: d0 = high word: modem ID
; a0 = pointer to modem parameter block
; a1 = modem manager global pointer
;
; Exit: d0 = result code
;
; Trashes: none
;
; Calls modem primitive for prime.
;----------------------------------------------------------------------------------------
mdmPrime
move.w #selMPPrime,d0 ; select modem power
bra.w CallMdmPrim ; make the call
;----------------------------------------------------------------------------------------
; mdmSndCtl
;
; Entry: d0 = high word: modem ID
; a0 = pointer to modem parameter block
; a1 = modem manager global pointer
;
; Exit: d0 = result code
;
; Trashes: A0, A1
;
; Set machine up to be enable/disable sound, then Calls modem primitive for sound control.
;----------------------------------------------------------------------------------------
mdmSndCtl
move.w #selMPSndCtl,d0 ; select modem power
bra.w CallMdmPrim ; make the call
;----------------------------------------------------------------------------------------
; mdmGetInd
;
; Entry: d0 = high word: modem ID
; a1 = modem manager global pointer
;
; Exit: d0 = high word: modem ID; low word: result code
; a0 = modem type (longword)
;
; Trashes: none
;
; Checks to see if the modem with index given in the high word of D0 is installed. If it
; is, the mdmType primitive for the modem is called to get the modem type, and the modem
; ID, modem type, and result code are returned.
;----------------------------------------------------------------------------------------
mdmGetInd
move.w d1,-(sp) ; save registers
swap d0 ; put modem index in low word
bsr GetIndMdm ; A0 -> pointer to the modem queue element
beq.s @noModem ; if no modem, report it
move.w immgQEl.qMdmId(a0),d0 ; D0 -> modem ID
move.w d0,d1 ; D1 -> modem ID
swap d0 ; D0: high word -> modem ID
move.w #selMPType,d0 ; select modem type primitive
bsr CallMdmPrim ; make the call, A0 -> modem type, D0 -> result code
swap d0
move.w d1,d0 ; D0 -> modem ID
swap d0 ; DO: high word -> modem ID, low word -> result code
@exit move.w (sp)+,d1 ; restore registers
rts
@noModem move.w #immgNoBoardErr,d0 ; report error
bra.s @exit
;----------------------------------------------------------------------------------------
; mdmFind
;
; Entry: A0: pointer to modem primitives table
;
; Exit: D0: result code of modem primitive MdmExists
;
; Trashes: none
;
; Calls the modem primitive MdmExists to determine if the modem that the primitives
; apply to physically exists in the machine.
;----------------------------------------------------------------------------------------
mdmFind
jsr ([immgPrimTable.mdmExists,a0]) ; call primitive
rts
;----------------------------------------------------------------------------------------
; mdmInstall
;
; Entry: A0: pointer to modem primitives table
; A1: pointer to modem manager globals
;
; Exit: D0: high word: modem ID; low word: result code
;
; Trashes: none
;
; Calls mdmFind to ensure that the modem to be installed is in the machine. If the
; modem is physically present, a new queue element is allocated and enqueued in the
; modem queue. Finally, the modem setup primitive is called, the returned A1 is stored
; in the modem queue element, and the pointer to the queue element is returned in A1.
;----------------------------------------------------------------------------------------
mdmInstall
@saveRegs REG d2/a1-a4 ; registers to save
movem.l @saveRegs,-(sp) ; save registers
movea.l a0,a2 ; A2 -> pointer to modem primitives
bsr mdmFind ; let primitives check if modem is in box
tst.w d0 ; check result
bne.s @noModem ; no modem found, report error
; create the new modem queue element
move.l #immgQEl.size,d0 ; D0 -> size of modem queue element
_NewPtr ,SYS,CLEAR ; A0 -> pointer to new modem queue element
tst.w d0 ; check pointer validity
bne.s @noModem ; no more memory, UNLUCKY!
movea.l a0,a4 ; A4 -> pointer to modem queue element
; fill in the fields of the modem queue element
WITH immgQEl ; type is already set up (from CLEAR)
bsr GetNewMdmID ; D0 -> new modem ID
move.w d0,qMdmID(a0) ; store modem ID
move.w d0,d2 ; save modem ID for mdmSetUp later
move.l a2,qMdmPrimPtr(a0) ; store modem primitives table pointer
ENDWITH ; optionalA1 will wait 'til after SetUp call
; install the modem queue element into the modem queue
movea.l a1,a3 ; A3 -> pointer to modem globals
move.l immgGlobals.mdmQ(a3),a1 ; A1 -> pointer to modem queue header
_Enqueue ; place new modem queue element into queue
; call the modem primitive MdmSetUp
move.w d2,d0 ; D0 -> modem ID
swap d0 ; put modem ID into high word
movea.l a3,a1 ; A1 -> pointer to modem manager globals
move.w #selMPSetUp,d0 ; call the MdmSetUp primitive
bsr CallMdmPrim ; this calls the modem primitive
tst.w d0 ; check returned error result
bne.s @primError ; there was an error in the primitive
; store the optional A1 pointer in the queue element
move.l a0,immgQEl.optionalA1(a4) ; save the value returned by the primitive
; return the modem ID in the high word of D0, and no error in low word
swap d0
move.w d2,d0 ; D0 -> modem ID
swap d0
@exit movem.l (sp)+,@saveRegs ; restore registers
rts
@noModem move.w #immgNoBoardErr,d0 ; report no board
bra.s @exit
@primError move.w d2,d0 ; D0 -> modem ID
swap d0 ; put modem ID into high word
bsr mdmRemove ; remove the modem from the queue
bra.s @exit
;----------------------------------------------------------------------------------------
; mdmRemove
;
; Entry: D0: high word: modem ID
; A1: pointer to modem manager globals
;
; Exit: D0: noErr
;
; Trashes: none
;
; Calls FindInstalledMdm to get the modem queue element for the modem with the ID passed
; in the high word of D0. Calls the CallMdmPrim routine to call the mdmTearDown primitive.
; Dequeues the modem queue element and deallocates it.
;----------------------------------------------------------------------------------------
mdmRemove
@saveRegs REG a1-a2 ; registers to save
movem.l @saveRegs,-(sp) ; save registers
; get the modem queue element to remove
movea.l a1,a2 ; A2 -> pointer to modem globals
bsr FindInstalledMdm ; A1 -> pointer to modem queue element
beq.s @noModem ; no modem found, report error
exg a1,a2 ; A1 -> modem globals, A2 -> modem Q El
; call the modem tear down primitive
move.w #selMPTearDown,d0 ; select modem tear down
bsr CallMdmPrim ; make the call, don't care about errors
; dequeue the modem
movea.l a2,a0 ; A0 -> modem queue element
movea.l immgGlobals.mdmQ(a1),a1 ; A1 -> pointer to modem queue header
_Dequeue ; don't care about errors
; deallocate the modem queue element
movea.l a2,a0 ; A0 -> modem queue element
_DisposPtr ; get rid of it
@noModem move.w #noErr,d0 ; D0 -> no error
@exit movem.l (sp)+,@saveRegs ; restore registers
rts
;----------------------------------------------------------------------------------------
; mdmGetName
;
; Entry: a0 = pointer to string buffer
; a1 = modem manager global pointer
;
; Exit: d0 = result code
; a0 = pointer to null terminated c string
;
; Trashes: none
;
; Gets the name of an installed modem by calling the get modem name primitive.
;----------------------------------------------------------------------------------------
mdmGetName
move.w #selMPName,d0 ; select mdmGetName primitive
bra.w CallMdmPrim ; make the call
;----------------------------------------------------------------------------------------
; mdmInfo
;
; Entry: a1 = modem manager global pointer
;
; Exit: d0 = valid gestalt result code
; a0 = high word: modem manager version; low word: number of modems
;
; Trashes: none
;
; Counts the number of installed modems, and returns the count and the modem manager
; version number.
;----------------------------------------------------------------------------------------
mdmInfo
bsr CountMdms ; D0.L -> number of installed modems
swap d0
move.w immgGlobals.version(a1),d0 ; D0 -> modem manager version number
swap d0
move.l d0,a0 ; A0 -> return result
move.w #noErr,d0
@exit rts
;----------------------------------------------------------------------------------------
; mdmClose
;
; Entry: a1 = modem manager global pointer
;
; Exit: d0 = result code
;
; Trashes: none
;
; Cleans up any initialization done by mdmInit.
;----------------------------------------------------------------------------------------
mdmClose
move.w #noErr,d0
@exit rts
;----------------------------------------------------------------------------------------
; mdmSndVol
;
; Entry: d0 = high word: modem ID
; a0 = pointer to modem parameter block
; a1 = modem manager global pointer
;
; Exit: d0 = result code
;
; Trashes: A0, A1
;
; Set machine up to set modem sound volume, then Calls modem primitive for sound control.
;----------------------------------------------------------------------------------------
mdmSndVol
move.w #selMPSndVol,d0 ; select modem power
bra.w CallMdmPrim ; make the call
;----------------------------------------------------------------------------------------
; mdmSndHW
;
; Entry: d0 = high word: modem ID
; a0 = pointer to modem parameter block
; a1 = modem manager global pointer
;
; Exit: d0 = result code
;
; Trashes: A0, A1
;
; Arbitrate for the system sound hardware via the appropriate primitive.
;----------------------------------------------------------------------------------------
mdmSndHW
move.w #selMPSndHW,d0 ; select modem power
bra.w CallMdmPrim ; make the call
; ¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥
; Useful utility routines
; ¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥
;----------------------------------------------------------------------------------------
; FindInstalledMdm
;
; Entry: D0: high word: modem ID
; A1: pointer to modem manager globals
;
; Exit: A1: pointer to modem queue element for modem with ID passed in D0
; Condition codes set to zero if modem not found, otherwise not zero
;
; Trashes: none
;
; Looks up the modem with ID given in high word of D0 and returns the modem queue
; element.
;----------------------------------------------------------------------------------------
FindInstalledMdm
move.l immgGlobals.mdmQ(a1),a1 ; A1 -> pointer to modem Q header
swap d0 ; D0: low word -> modem ID
move.l qHead(a1),a1 ; A1 -> first modem queue element
WITH immgQEl
@nextModem tst.l a1 ; check pointer for validity
beq.s @exit ; Oops! out of modems and not found!
cmp.w qMdmID(a1),d0 ; check modem ID against the one we want
beq.s @exit ; found it!
move.l qLink(a1),a1 ; A1 -> pointer to next modem queue element
bra.s @nextModem ; keep checking...
ENDWITH
@exit swap d0 ; put things back the way they were
tst.l a1 ; set condition codes
rts
;----------------------------------------------------------------------------------------
; CallMdmPrim
;
; Entry: D0: high word: modem ID; low word: primitive selector
; A1: pointer to modem manager globals
;
; Exit: A0: whatever is returned by the modem primitive
; D0: result code returned by modem primitive, or no board found err
; if the modem ID was not valid.
;
; Trashes: none
;
; Calls FindInstalledMdm to get the modem queue element desired, then calls the modem
; primitive selected by the low word of D0.
;----------------------------------------------------------------------------------------
CallMdmPrim
@saveRegs REG d1/a1-a2 ; registers to save over routine
movem.l @saveRegs,-(sp) ; save registers
bsr FindInstalledMdm ; A1 -> pointer to modem queue element
beq.s @noModem ; no modem found, report error
; get data from the queue element that will be used
WITH immgQEl
move.l qMdmPrimPtr(a1),a2 ; A2 -> pointer to modem primitives
move.l optionalA1(a1),a1 ; A1 -> pointer to optional A1 parameter
ENDWITH
; range check the primitive selector against the number of prims in the prim table
WITH immgPrimTable
cmp.w numPrims(a2),d0 ; is the prim selector < num prims?
bcc.s @invalidSel ; nope, report error...
adda.l #primOffset,a2 ; A2 -> pointer to primitives
move.w d0,d1 ; D1 -> primitive selector
lsl.w #2,d1 ; D1 -> offset to primitive
jsr ([a2,d1.w]) ; do the primitive
ENDWITH
@exit movem.l (sp)+,@saveRegs ; restore registers
rts
@noModem move.w #immgNoBoardErr,d0 ; report no board
bra.s @exit
@invalidSel move.w #immgInvalidSelector,d0 ; report invalid primitive selector
bra.s @exit
;----------------------------------------------------------------------------------------
; GetIndMdm
;
; Entry: D0: index of modem to retrieve (zero based)
; A1: pointer to modem manager globals
;
; Exit: A0: pointer to modem queue element for modem at index in D0
; Condition codes set to zero if modem not found, otherwise not zero
;
; Trashes: D0, A0
;
; Looks up the modem with index given in D0 and returns a pointer to the modem queue
; element.
;----------------------------------------------------------------------------------------
GetIndMdm
move.l immgGlobals.mdmQ(a1),a0 ; A0 -> pointer to modem Q header
move.l qHead(a0),a0 ; A0 -> first modem queue element
tst.l a0 ; check pointer for validity
beq.s @exit ; Oops! out of modems and not found!
tst.w d0 ; check if we want first (0) modem
beq.s @exit ; yep! leave...
WITH immgQEl
subq #1,d0 ; for dbeq loop
@nextModem move.l qLink(a0),a0 ; A1 -> pointer to next modem queue element
tst.l a0 ; set condition codes
dbeq d0,@nextModem ; keep checking...
ENDWITH
@exit tst.l a0 ; set condition codes
rts
;----------------------------------------------------------------------------------------
; CountMdms
;
; Entry: A1: pointer to modem manager globals
;
; Exit: D0: number of modems
;
; Trashes: A0
;
; Counts the number of installed modems in the modem queue.
;----------------------------------------------------------------------------------------
CountMdms
moveq #0,d0 ; clear counter
move.l immgGlobals.mdmQ(a1),a0 ; A0 -> pointer to modem Q header
move.l qHead(a0),a0 ; A0 -> first modem queue element
tst.l a0 ; check pointer for validity
beq.s @exit ; Zero modems
WITH immgQEl
@nextModem addq #1,d0 ; counting...
move.l qLink(a0),a0 ; A1 -> pointer to next modem queue element
tst.l a0 ; set condition codes
bne.s @nextModem ; keep counting...
ENDWITH
@exit rts
;----------------------------------------------------------------------------------------
; GetNewMdmID
;
; Entry: A1: pointer to modem globals
;
; Exit: D0: modem ID
;
; Trashes: none
;
; Comes up with a new modem ID. Right now, all it does is increment the number in the
; modem manager globals and returns it.
;----------------------------------------------------------------------------------------
GetNewMdmID
WITH immgGlobals
add.w #1,lastMdmID(a1) ; increment last modem ID
move.w lastMdmID(a1),d0 ; get the modem ID
ENDWITH
rts
End