mac-rom/DeclData/VSCDeclData/VSCDockingHandler.a

831 lines
31 KiB
Plaintext

;
; File: VSCDockingHandler.a
;
; Contains: a docking handler to support Dartanian's built-in VSC video
;
; Written by: Steve Christensen, Helder Ramalho, Dave Wong, Andy Gong (anyone else?)
; Rewritten: Mike Puckett, July 15, 1993.
; Copyright: © 1992-1993 by Apple Computer, Inc. All rights reserved.
;
; Change History (most recent first):
;
; <SM2> 12/13/93 PN Roll in KAOs and Horror changes to support Malcom and AJ
; machines
; <1> 12-04-92 jmp first checked in
; ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; Pre-SuperMario comments begin here.
; ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; <H2> 6/1/92 HJR Fix Header.
; <H1> 6/1/92 HJR first checked in
VidLowPwrFrame Record 0, Decrement
VidLowPwrCntBlk Ds.b IOVQElSize ; control call parm block
VidLowPwrVDPageInfo Ds.b VDPageInfo ; params
VidLowPwrFrameSize Equ * ; size of frame
Endr
;__________________________________________________________________________________________________
;
; FUNCTION DockSelect(selector:OSType; params:LONGINT):LONGINT;
;
; Control/info handler for Dartanian/BlackBird.
; - selector is the index into the docking handler tables
; - params is any required input parameter
;
; DockSelect returns the result of the selector.
;
; Trashes: D0-D2, A0-A1
;__________________________________________________________________________________________________
DockSelect
Move.l (Sp)+,D2 ; Pop the return addressÉ
Movea.l (Sp)+,A0 ; Éand the input params
Move.l (Sp)+,D0 ; Éand the selector.
Lea SelectorTable-4,A1 ; Point to the start of the table.
@FindStatSelector
Addq #4,A1 ; Skip over the previous function result.
Move.l (A1)+,D1 ; If weÕre at the end of the function table,
Beq.s @FindCtlSelector ; then check the other one.
Cmp.l D1,D0 ; If this isnÕt the right selector,
Bne.s @FindStatSelector ; then keep looking.
Move.l (A1),D1 ; Get the function result into D1.
@Done Move.l D1,(Sp) ; Stuff the funtion result onto the stack.
Movea.l D2,A0 ; Restore the return address.
Jmp (A0) ; And return.
@FindCtlSelector
Addq #4,A1 ; Skip over the function result/routine offset.
Move.l (A1)+,D1 ; If weÕre at the end of this table,
Beq.s @Done ; then we just leave.
Cmp.l D1,D0 ; If this isnÕt the right selector,
Bne.s @FindCtlSelector ; then keep looking.
Adda.l (A1),A1 ; Get offset to routine.
Jsr (A1) ; Jump to it.
Move.l D0,D1 ; Copy result.
Bra.s @Done ; Vamoose.
SelectorTable
; Selector Function result
; -------- ---------------
;
Dc.l dockSCCPorts, ((1<<dockSCCModemPort)|\ ; Modem port is available.
(0<<dockSCCPrinterPort)) ; Printer port isnÕt available.
Dc.l dockROMVersion ; Set the ROMÉ
Dc.b $02,$00,$40,1 ; Éversion number.
Dc.l 0, 0 ; -- EOT --
; Selector Routine Offset
; -------- --------------
;
Dc.l dockHardwareAttr, HardwareStuff - * - 4 ; Determine HardwareStuff.
Dc.l dockDockingAttr, DockingStuff - * - 4 ; Determine DockingStuff.
Dc.l dockSCCReadAddr, GetSCCReadAddr - * - 4 ; Get the SCC read address.
Dc.l dockSCCWriteAddr, GetSCCWriteAddr - * - 4 ; Get the SCC write address.
Dc.l dockSCSIDiskMode, SDMStatus - * - 4 ; Determine status of SCSIDiskMode (SDM).
Dc.l dockNuBusConnectors, NuBusStuff - * - 4 ; Determine whether we should return Slot #0 or not.
Dc.l dockInit, InitStuff - * - 4 ; Perform early/wake initializations.
Dc.l dockSleepSave, SleepStuff - * - 4 ; Sleep Õem.
Dc.l dockWakeupRestore, WakeupStuff - * - 4 ; Wake Õem.
Dc.l dockFlush, FlushStuff - * - 4 ; Wipe Õem.
Dc.l 0, 0 ; -- EOT --
;----------------------------------------------------------------------------------
;
; HardwareStuff - routine to determine hardware attributes (status call)
;
; Inputs - A0: input parameter (none defined for this call)
;
; Outputs - D0: hardware attributes
;
;----------------------------------------------------------------------------------
HardwareStuff
Move.l #((1<<dockHasSCC)|\ ; Say the we always have SCC forÉ
(1<<dockWakeSCC)|\ ; Éugly historical hack reasons.
(1<<dockWakeVideo)),D0 ; Internal and/or external video will always be available on wake.
; For this handler, the only thing that can change (and that we can do anything
; about) is video. So, those are the only bits we really deal with here.
;
Btst #vscVideoPower,VSCBase+vscClockPower ; If the video plane is currently powered off,
Beq.s @EndVidChk ; then just go on.
Ori.l #(1<<dockHasVideo),D0 ; Otherwise, say external video is powered.
@EndVidChk
Rts
;----------------------------------------------------------------------------------
;
; DockingStuff - routine to determine docking attributes (status call)
;
; Inputs - A0: input parameter (none defined for this call)
;
; Outputs - D0: docking attributes
;
;----------------------------------------------------------------------------------
DockingStuff
; Return that we can always wake up and that we can always sleep. Also, always
; return that we can PowerCycle, that we can always use the LCD screen, and
; that we are not a dockingStation.
;
Moveq #((0<<dockNoSleep) |\
(0<<dockNoWakeup) |\
(0<<dockNoPowerCycle) |\
(0<<dockNoLCDScreen) |\
(0<<dockingStation)),D0
Rts
;----------------------------------------------------------------------------------
;
; GetSCCRead/WriteAddr - routine to return the SCC read and write addresses.
;
; Inputs - None
;
; Outputs - D0: The SCC read/write address.
;
; Note: We shouldnÕt have to deal with the SCC ports in this handler, but
; the single-port arbitration stuff relies solely on the Docking
; Handler. Strickly speaking, this Docking Handler is only for
; the built-in external video. Ugh!
;
;----------------------------------------------------------------------------------
GetSCCReadAddr
Move.l SCCRd,D0 ; Return the SCC read address.
Rts
GetSCCWriteAddr
Move.l SCCWr,D0 ; Return the SCC write address.
Rts
;----------------------------------------------------------------------------------
;
; SDMStatus - routine to SCSI Disk Mode (status call)
;
; Inputs - A0: input parameter (meaningless for status calls)
;
; Outputs - D0: SCSI Disk Mode status
;
; Note: This probably shouldnÕt be here, but it is. This handler is
; supposed to only have to deal with video. Hack, hack, hack.
;
;----------------------------------------------------------------------------------
SDMStatus
Moveq #((1<<dockSDMExists)|\ ; Say that we support SDM.
(0<<dockSDMCable)),D0 ; Default to no cable.
Movea.l VIA,A0 ; Point to the VIA.
Moveq #1<<vSDMCable,D1 ; Mask off the cable sense bit.
And.b vBufB(A0),D1 ; Get it.
Btst #vSDMCable,D1 ; If thereÕs no cable attached,
Bne.s @Finished ; then just go on.
Addq.b #(1<<dockSDMCable),D0 ; Otherwise, say itÕs present.
@Finished Rts
;----------------------------------------------------------------------------------
;
; NuBusStuff - routine to do return NuBus ÒconnectorsÓ (status call)
;
; Inputs - none
;
; Outputs - returns none or Slot 0
;
;----------------------------------------------------------------------------------
;
With PmgrPramRec
NuBusStuff
Moveq #VidMode,D0 ; Say that we want the VidMode byte.
Bsr ReadPMgrPRAM ; Get it.
Bne.s @DoSlot0 ; If weÕre supposed to return Slot #0, then do so.
Moveq #0,D0 ; Otherwise, donÕt.
Bra.s @Finished ;
@DoSlot0 Moveq #(1<<dockSlot0),D0 ; Say we need to redo Slot #0.
@Finished Rts
Endwith
;----------------------------------------------------------------------------------
;
; InitStuff - routine to do docking initialization (control call)
;
; Inputs - a0: input parameter, indicates sleep wakeup or normal init
;
; Outputs - d0: will return zero at init time; will return non-zero
; on wakeup if the world has changed
;
;----------------------------------------------------------------------------------
;
InitStuff
Move.l A0,D0 ; Get the input flags.
Btst #dockWorldChanged,D0 ; If we got the early wake-up call,
Bne.s @CheckWorld ; then go check the world.
Btst #dockWakeupInit,D0 ; If weÕre simply waking up, then
Bne.s @Done ; just leave.
Bsr DetectExtDisplay ; Otherwise, go look for an ext. display.
@Done Moveq #0,D0 ; Say that we were successful.
Rts ; And vamoose.
; Generally speaking, the Docking Manager wants to know if ÒbulkÓ changes have occurred. In
; our case, bulk changes never occur (that is, the ÒbarÓ is permenantly attatched). So,
; we just want to find out if paticular changes have occurred. Specifically, we want
; to know if the state of the int./ext. video has changed. And, if so, we report this
; information back to the Docking Manager.
;
With PmgrPramRec
@CheckWorld
Bsr DetectExtDisplay ; Go look for an ext. display.
Lea ExtVidState,A0 ; Point to the ext. save-state variable.
Cmp.w (A0),D0 ; If the ext. world hasnÕt changed, then
Beq.s @ChkInt ; check the int. world.
Bra.s @ForceInt ; Otherwise, force the DockingMgr to deal w/Slot #0.
; If we got here, then the external display state hasnÕt changed. So, before we simply tell
; tell the Docking Manager to do nothing, we check to see if the internal display
; state has changed. We do this by comparing the state of the lid with the state
; of the built-in internal video. If the state of the lid matches the state
; of built-in internal video (e.g., lid down and video off), then we simply tell
; the docking manager to do nothing. However, if the state of the lid does
; not match the state of built-in internal video (e.g., lid up and video off),
; then we tell the Docking Manager to go change the world. We also pass this information
; back to ourselves (via PowerMgr pRAM).
;
@ChkInt Bsr GetLidState ; Get the state of the lid.
Move.b D0,-(Sp) ; Save the state.
Moveq #0,D0 ; Say we want Slot #0
Move.w #drHwCSC,D0 ; Say we want CSC.
Swap D0 ; Set up for call.
Bsr GetSlotDevRefNum ; Do it.
Ext.l D0 ; Normalize result into hiword.
Swap D0 ; Get hiword into loword.
Cmp.b (Sp)+,D0 ; If lidState == vidState, then
Beq.s @Done ; just leave.
@ForceInt Moveq #VidMode,D0 ; Say we want to write the VidMode byte.
Moveq #-1,D1 ; Set the redo-slot-0 flag.
Bsr WritePMgrPRAM ; Do it.
Moveq #(1<<dockWorldChanged),D0 ; Say the world changed.
Rts
Endwith
;----------------------------------------------------------------------------------
;
; SleepStuff - routine to save bar's hardware state (control call)
;
; Inputs - none
;
; Outputs - D0: pointer to hardware state, or error flag (-1)
;
;----------------------------------------------------------------------------------
With VDPageInfo,VidLowPwrFrame
SleepStuff
Lea ExtVidState,A0 ; Point to the ext. save-state variable.
Move.w #indexedNoConnect,(A0) ; Assume nobodyÕs home.
Link A6,#VidLowPwrFrameSize ; Allocate some local storage on the stack.
; Get a the external driverÕs refNum if itÕs around.
;
Clr.l -(Sp) ; Make room for docking result.
Move.l #dockDockingSlot,-(Sp) ; Say we want the docking slot number.
Clr.l -(Sp) ; No params.
_DockingDispatch ; Call the Docking Manager.
Move.l (Sp)+,D0 ; Get the docking slot number into D0.
Swap D0 ; Save it.
Move.w #drHwVSC,D0 ; Get the drHwID.
Swap D0 ; Set up for utility call.
Bsr GetSlotDevRefNum ; If ext. video is not around,
Beq.s @NoExtVid ; then donÕt call it.
; Call video driver to power down VSCÉ
;
Lea VidLowPwrCntBlk(A6),A0 ; Point to parameter block space.
Move.w D0,ioRefNum(A0) ; Load the driver refNum.
Clr.w ioVRefNum(A0) ; No driver vRefNum.
Move.w #cscSleepWake,csCode(A0) ; Set up for cscSleepWake.
Lea VidLowPwrVDPageInfo(a6),a1 ; Point to the csParam record.
Move.l A1,csParam(A0) ; Load it.
Clr.w csMode(A1) ; Set mode to sleep the VSC.
_Control ; Do it.
Beq.s @Finished ; If successful, then go on.
@NoExtVid Moveq #-1,D0 ; Otherwise, return failure.
Bra.s @Done ; And leave.
@Finished Moveq #0,D0 ; We didnÕt need any special storage.
Lea ExtVidState,A0 ; Point to the save-state variable.
Move.w csMode(A1),(A0) ; Save the state.
@Done Unlk A6 ; Release our stack frame.
Rts
Endwith
;----------------------------------------------------------------------------------
;
; WakeupStuff - routine to do docking cleanup (control call)
;
; Inputs - A0: pointer to hardware state, or error flag (-1)
;
; Outputs - D0: wakeup result (always zero)
;
;----------------------------------------------------------------------------------
With VDPageInfo,VDSetEntryRecord,VidLowPwrFrame
WakeupStuff
Move.l A0,D0 ; Get status from sleep.
Cmpi.l #-1,D0 ; If we failed to sleep,
Beq @Done ; then just leave.
Lea ExtVidState,A0 ; Point to the ext. save-state variable.
Cmpi.w #indexedNoConnect,(A0) ; If the world changed (or nobodyÕs home),
Beq @Done ; then just leave.
Link A6,#VidLowPwrFrameSize ; Allocate some local storage on the stack.
; Get a the external driverÕs refNum if itÕs around.
;
Move.w #drHwVSC,D0 ; Get the drHwID for VSC.
Swap D0 ; Save it.
Move.w #dockSlotE,D0 ; Get the slot number. (We could call the Docking Manager, but why?)
Bsr GetSlotDevRefNum ; If ext. video is not around (shouldnÕt happen),
Beq.s @Finished ; then donÕt call it.
; Call video driver to power up VSCÉ
;
Lea VidLowPwrCntBlk(A6),A0 ; Point to parameter block space.
Move.w D0,ioRefNum(A0) ; Load the driver refNum.
Clr.w ioVRefNum(A0) ; No driver vRefNum.
Move.w #cscSleepWake,csCode(A0) ; Set up for cscSleepWake.
Lea VidLowPwrVDPageInfo(A6),A1 ; Point to the csParam record.
Move.l A1,csParam(A0) ; Load it.
Move.w #-1,csMode(A1) ; Set mode to wake up the VSC.
_Control ; If we failed to wake up,
Bne.s @Finished ; then just leave.
Move.w ioRefNum(A0),D0 ; Get the driverÕs refNum.
Movea.l Devicelist,A2 ; Get the DeviceList Handle.
Movea.l (A2),A2 ; Make it a pointer.
@DevLoop Cmp.w gdRefNum(A2),D0 ; If this is the right gDevice,
Beq.s @SetEm ; then call SetEntries.
Move.l gdNextGD(A2),D1 ; Otherwise, get the next gDevice.
Beq.s @Finished ; If itÕs nil, then weÕre done.
Movea.l D1,A2 ; Otherwise, copy the gDevice Handle.
Movea.l (A2),A2 ; Make it a pointer.
Bra.s @DevLoop ; Loop until done.
@SetEm Movea.l gdPMap(A2),A2 ; Get the gDeviceÕs pixMapÕsÉ
Movea.l (A2),A2 ; Écurrent colorTable.
Movea.l pmTable(A2),A2 ; (If this were a direct device, weÕd punt here.)
Move.l A0,D1 ; Save the ioPB ptr.
Movea.l A2,A0 ; Set up toÉ
_HLock ; Élock down the colorTable.
Move.l A0,-(Sp) ; Save the Handle for _HUnlock.
Movea.l (A0),A2 ; Turn it into a pointer.
Movea.l D1,A0 ; Restore ioPB ptr.
Clr.w csStart(A1) ; Set csStart to 0.
Move.w ctSize(A2),csCount(A1) ; Set csCount to pmTable.ctSize.
Lea ctTable(A2),A2 ; Get a pointer to the pmTabl.ctTable.
Move.l A2,csTable(A1) ; Copy it to the csParam block.
Move.w #cscSetEntries,csCode(A0) ; Set up for SetEntries.
_Control ,Immed ; Do it.
Movea.l (Sp)+,A0 ; Set up toÉ
_HUnlock ; Éunlock the colorTable Handle.
@Finished Unlk A6 ; Release our local stack storage.
@Done Moveq #0,D0 ; Always return zero.
Rts
Endwith
;----------------------------------------------------------------------------------
;
; FlushStuff - routine to do docking finalŽ (status call)
;
; Inputs - A0: input parameter (meaningless for status calls)
;
; Outputs - D0: wipe result (always zero)
;
;----------------------------------------------------------------------------------
;
With PmgrPramRec
FlushStuff
Moveq #VidMode,D0 ; Say we want to write the VidMode byte.
Moveq #0,D1 ; Reset the redo-slot-0 flag.
Bsr WritePMgrPRAM ; Do it.
Moveq #0,D0 ; Return zero.
Rts ; And leave.
Endwith
;=====================================================================
; Data
;=====================================================================
; We need to remember what the state of built-in external video
; is prior to going to sleep so that we can see if it has
; changed across the sleep-wake transition.
;
ExtVidState Dc.w indexedNoConnect ; Records the state of built-in external video across sleep.
;=====================================================================
; Utils
;=====================================================================
;---------------------------------------------------------------------
;
; Routine: Delay100
;
; Inputs: a0 - Ptr to VIA1 base
;
; Outputs: none
;
; Destroys: d0
;
; Function: Delays around 100 us, for reading sense lines on VSC.
;---------------------------------------------------------------------
Delay100 move.w TimeVIADB,d0
lsr.w #3,d0 ; 125 us delay
@wait tst.b (a0)
dbra d0,@wait
rts
;---------------------------------------------------------------------
; This routine reads the VSC/Jet sense lines. On entry, A4 should point to the VSC/Jet base address, D6
; should contain $03, $05, $06, or $07 to indicate the type of extended sense weÕre doing, and
; the CPU should have been put into 32-bit addressing mode. On exit, D6 contains the appropriate
; extended sense code.
;
; Note: The idea behind the extended-sense-line ($07) algorithm is as follows: First, drive sense line
; ÒaÓ and read the values of ÒbÓ and Òc.Ó Next, drive sense line ÒbÓ and read the values of ÒaÓ
; and Òc.Ó Finally, drive sense line ÒcÓ and read the values of ÒaÓ and Òb.Ó In this way, a
; six-bit number of the form bc/ac/ab is generated. The other extended-sense algorithms are
; identical to that of $07, except one of the three lines doesnÕt need to be driven. For example,
; with $03, ÒaÓ doesnÕt need to be driven. With $05, ÒbÓ doesnÕt need to be driven, and
; with $06, ÒcÓ doesnÕt need to be driven.
;---------------------------------------------------------------------
DoExtendedSense
Movem.l A0/D0-D1,-(Sp) ; Save work registers.
Moveq #0,D1 ; Use D1 to store extended-sense code.
Moveq #0,D0 ; Use D0 as temp from reads.
move.l VIA,a0 ; for delays
; Drive a, Read bc
;
Cmpi.b #indexedSense2P,D6 ; If this is not a type-3 extended sense,
Bne.s @DriveA ; then go ahead and drive A.
Move.b D6,D0 ; Otherwise, write out the assumed value,
Bra.s @EndA ; and go on.
@DriveA move.b #VSCAMask,VSC_MonID(a4) ; abc <- 011
bsr Delay100 ; delay 100 us
move.b VSC_MonID(a4),d0 ; Read the sense lines into d0.
lsr.b #4,d0 ; Shift the senseline inputs down.
@EndA move.b D0,D1 ; 00 00 BC
lsl.b #2,D1 ; 00 BC 00
; Drive b, Read ac
;
Cmpi.b #indexedSenseRGBFP,D6 ; If this is not a type-5 extended sense,
Bne.s @DriveB ; then go ahead and drive B.
Move.b D6,D0 ; Otherwise, write out the assumed value,
Bra.s @EndB ; and go on.
@DriveB move.b #VSCBMask,VSC_MonID(a4) ; abc <- 101
bsr Delay100 ; delay 100 us
move.b VSC_MonID(a4),d0 ; Read the sense lines into d0.
lsr.b #4,d0 ; Shift the senseline inputs down.
@EndB bclr #VSCSenseLineA,d0 ; A0C becomes
beq.s @OrIn ; A0C or
bset #VSCSenseLineB,d0 ; A1C
@OrIn or.b d0,D1 ; 00 BC AC
lsl.b #2,D1 ; BC AC 00
; Drive c, Read ab
;
Cmpi.b #indexedSenseHR,D6 ; If this is not a type-6 extened sense,
Bne.s @DriveC ; then go ahead and drive C.
Move.b D6,D0 ; Otherwise, write out the assumed value,
Bra.s @EndC ; and go on.
@DriveC move.b #VSCCMask,VSC_MonID(a4) ; abc -> 110
bsr Delay100 ; delay 100 us
move.b VSC_MonID(a4),d0 ; Read the sense lines into d0.
lsr.b #4,d0 ; AB0
@EndC lsr.b #1,d0 ; 0AB
or.b d0,D1 ; BC AC AB
Move.b D1,D6 ; Save the extended-sense code.
Movem.l (Sp)+,A0/D0-D1 ; Restore work registers.
Rts ; Return to caller.
; In a ÒclassicÓ video card setup, weÕd normally perform the follwing code in the PrimaryInit.
; However, because we have a clamshell on Blackbird, we need to know whether or not it will
; be closed. If the clamshell is closed, we generally want to keep video turned off on the
; LCD, but only if some sort of external video is running. So, we check here to see if
; thereÕs a display attatched to the external video connector. If there is a display attached,
; then we just leave video power on. Otherwise, we turn it off, and the hardware attributes
; then return that no external video is available.
;
; No registers are trashed, but D0 returns the detected display code.
;
DetectExtDisplay
@ExtDispRegs Reg A0-A4/D1/D6 ; Define and save theÉ
Movem.l @ExtDispRegs,-(Sp) ; Éregisters used here.
; Get some useful values up front.
;
lea VSCVideoBase,a4 ; Get the video base address into a4.
lea AIV3Base,a3 ; Point to AIV3 base.
; First, disable the VBL interrupts.
;
Bset #VidPwrEn,AIV3PwrEn(a3) ; Turn on video power planeÉ
Clr.b VSC_VidCtrl(A4) ; Ébut shut off syncs, dot clock, etcÉ.
Move.w #500-1,D0 ; It takes approximately 500µsÉ
@Wait500 Tst.b ([VIA]) ; Éfor the power-on signal to
Dbra D0,@Wait500 ; Épropagate thru the video circuitry.
Bset #vidReset,VSC_Test(A4) ; Reset the video subsystem byÉ
Bclr #vidReset,VSC_Test(A4) ; Étoggling the reset bit.
move.b #(1<<slotVBL),AIV3SlotEn(a3) ; Disable built-in (slot E) videoÕs VBLs.
moveq #2,d0 ; default (reset) value
move.b d0,VSC_HFP(a4) ; set horizontal front porch
move.b d0,VSC_HS(a4) ; set horizontal sync
move.b d0,VSC_HBP(a4) ; set horizontal back porch
move.b d0,VSC_HA(a4) ; set horizontal active dots
move.b d0,VSC_SyncA(a4) ; set SyncA dots
move.w d0,VSC_VFP(a4) ; set vertical front porch
move.w d0,VSC_VS(a4) ; set vertical sync lines
move.w d0,VSC_VBP(a4) ; set vertical back porch
move.w d0,VSC_VA(a4) ; set vertical active lines
clr.b VSC_Test(a4) ; clear test register
;-------------------------------------------------------
; Sense the type of display to drive.
;-------------------------------------------------------
With SP_Params,SpBlock
Suba.w #spBlockSize,Sp ; Make a slot parameter block on stack.
Movea.l Sp,A0 ; Get pointer to parm block now.
Move.b #dockSlotE,spSlot(A0) ; Put slot # into pBlock (We could call the Docking Manager, but why?)
Clr.b spExtDev(A0) ; Why ask why, just clear this guy.
Suba.w #SizesPRAMRec,Sp ; Allocate block for pRAM record.
Move.l Sp,spResult(A0) ; Point to it.
Movea.l Sp,A2 ; Save it.
_sReadPRAMRec ; Read slot PRAM.
moveq #0,d6 ; clear our id reg
move.b VSC_MonID(a4),d6 ; Read the sense lines into d6.
lsr.b #4,d6 ; Shift the senseline inputs down.
Cmpi.b #indexedSenseHR,D6 ; If we got a type-6, then do the
Beq.s @ExtendedHR ; extended Hi-Res stuff.
Cmpi.b #indexedNoConnect,D6 ; If we got a type-7, then do the
Beq.s @ExtendedNoConnect ; extended no-connect stuff.
Bra @EndSense ; Otherwise, the display is indexed and we handle it in the table.
@ExtendedHR
Bsr DoExtendedSense ; Do the extended type-6 algorithm.
Lea @XT6Table,A1 ; Point to the table of extended type-6 codes.
@XT6Loop Move.b (A1)+,D0 ; Pick up the next supported extended type-6 code.
Bmi.s @EndExtHR ; If weÕre at the end of the list, then just leave.
Move.b (A1)+,D1 ; Pick up the indexed version of the extended code.
Cmp.b D0,D6 ; If we didnÕt find a match, then
Bne.s @XT6Loop ; just keep looping.
Move.b D1,D6 ; Translate the extended code into its indexed version.
Bra @EndSense ; And move on.
@EndExtHR Move.b #indexedSenseHR,D6 ; Say that a type-6 display is connected.
Move.b SP_AltSense(A2),D0 ; Get the alternate senseID pRam byte.
Andi.b #spAltSenseValidMask,D0 ; If it is valid, then just pretend that
Bne.s @DoMonID ; the monID monitor is attached.
Bra.s @EndSense ; Otherwise, just say an HR display is attached.
@DoMonID Move.b SP_AltSense(A2),D6 ; Get the no-connect pRam byte.
Andi.b #spAltSenseMask,D6 ; Strip the validation code.
Bra.s @EndSense ; Skip the rest.
@ExtendedNoConnect
Bsr DoExtendedSense ; Do the extended no-connect algorithm.
Lea @XNCTable,A1 ; Point to the table of extended no-connect codes.
@XNCLoop Move.b (A1)+,D0 ; Pick up the next supported extended no-connnect code.
Bmi.s @EndNoConnect ; If weÕre at the end of the list, then just leave.
Move.b (A1)+,D1 ; Pick up the indexed version of the extended code.
Cmp.b D0,D6 ; If we didnÕt find a match, then
Bne.s @XNCLoop ; just keep looping.
Move.b D1,D6 ; Translate the extended code into its indexed version.
Bra.s @EndSense ; And move on.
@EndNoConnect Move.b #indexedNoConnect,D6 ; Say that nothingÕs connected.
Bclr #VidPwrEn,AIV3PwrEn(a3) ; And turn off video power.
Bra.s @EndSense
@XNCTable Dc.b extendedSenseVGA,indexedSenseVGA
Dc.b extendedSenseGF,indexedSenseGF
Dc.b -1,-1
@XT6Table Dc.b extendedMSB1,indexedSenseMSB1
Dc.b extendedMSB2,indexedSenseMSB2
Dc.b extendedMSB3,indexedSenseMSB3
Dc.b -1,-1
@EndSense clr.b VSC_MonID(a4) ; set ID lines to 0 to tri-state them.
Move.b D6,SP_MonID(A2) ; Write the MonID into pRAM buffer.
Move.l A2,spsPointer(A0) ; Set up parameter block.
_sPutPRAMRec ; Write the new record out.
Adda.w #SizesPRAMRec+spBlockSize,Sp ; Deallocate buffer.
Moveq #0,D0 ; Clear D0 for good measure.
Move.b D6,D0 ; Return the detected ext. display code.
Movem.l (Sp)+,@ExtDispRegs ; Restore the registers used here.
Rts ; And vamoose.
Endwith
;---------------------------------------------------------------------
;
; Routine: GetLidState
;
; Inputs: None.
;
; Outputs: D0.b - zero if lid is closed, -1 if lid is open.
;
; Destroys: A0/D0.
;
; Function: Returns the driver refNum of a needed device if that
; device happens to be in a particular slot.
;---------------------------------------------------------------------
;
With PMgrRec, pmCommandRec
GetLidState
Clr.w -(Sp) ; Allocate buffer on stack.
Move.l Sp,-(Sp) ; pmRBuffer
Move.l (Sp),-(Sp) ; pmSBuffer
Clr.w -(Sp) ; pmLength = 0
Move.w #readExtSwitches,-(SP) ; pmCommand
Movea.l SP,A0 ; Point to the parameter block.
_PMgrOp ; Get the clamshell info.
Lea pmRBuffer+4(Sp),Sp ; Toss the parameter block.
Btst #clamshell,(Sp)+ ; Is the clamshell closed?
Seq D0 ; Set up result.
Rts
Endwith
;---------------------------------------------------------------------
;
; Routine: GetSlotDevRefNum
;
; Inputs: D0.w (lo) - slot number to search.
; D0.w (hi) - drHwID of device.
;
; Outputs: D0.w (lo) - if non-zero, refNum of deviceÕs driver.
;
; Destroys: A0/D0.
;
; Function: Returns the driver refNum of a needed device if that
; device happens to be in a particular slot.
;---------------------------------------------------------------------
;
With SpBlock
GetSlotDevRefNum
Suba.w #SpBlockSize,Sp ; Allocate an SpBlock.
Movea.l Sp,A0 ; Point to the SpBlock on the stack.
Move.b D0,spSlot(A0) ; Set the slot number to search in.
Swap D0 ; Load the DrHwID.
Clr.b spId(A0) ; Begin at id 0.
Clr.b spExtDev(A0) ; No external device.
Clr.b spTBMask(A0) ; No mask in search.
Move.w #catDisplay,spCategory(A0) ; Look for: Display,
Move.w #typVideo,spCType(A0) ; Video,
Move.w #drSwApple,spDrvrSW(A0) ; Apple,
Move.w D0,spDrvrHW(A0) ; <DrHwID>.
Clr.l spParamData(A0) ; Look only for enabled sRsrcs.
Bset #foneslot,spParamData+3(A0) ; Limit search to this slot.
_GetTypeSRsrc ; If we found it, then
Beq.s @FoundDevice ; say so.
Moveq #0,D0 ; Otherwise, say the device isnÕt loaded.
Bra.s @Done ;
@FoundDevice Move.w spRefNum(A0),D0 ; Get the refNum into D0.
@Done Adda.w #SpBlockSize,Sp ; Restore the stack.
Rts ; And vamoose.
Endwith
;---------------------------------------------------------------------
;
; Routine: ReadPMgrPRAM
;
; Inputs: D0.l - PRAM address.
;
; Outputs: D0.b - byte read
;
; Destroys: A0/D0.
;
; Function: Reads a byte of PowerMgr PRAM.
;---------------------------------------------------------------------
;
With PmgrRec
ReadPMgrPRAM
Movea.l PMgrBase,A0 ; Point to the Power ManagerÕs globals.
Add.b PRAMBase(A0),D0 ; Get the absolute PRAM address.
Swap D0 ; Save it.
Addq #1,D0 ; Say we want one byte.
Swap D0 ; Save it.
Clr.b -(Sp) ; Make space for a buffer on the stack.
Movea.l Sp,A0 ; Point to it.
_ReadXPRAM ; Read the byte.
Move.b (Sp)+,D0 ; Return it.
Rts
Endwith
;---------------------------------------------------------------------
;
; Routine: WritePMgrPRAM
;
; Inputs: D0.l - PRAM address.
; D1.b - byte to write.
;
; Outputs: None.
;
; Destroys: A0/D0.
;
; Function: Writes a byte of PowerMgr PRAM (but doesnÕt set the dirty flag).
;---------------------------------------------------------------------
;
With PmgrRec
WritePMgrPRAM
Movea.l PMgrBase,A0 ; Point to the Power ManagerÕs globals.
Add.b PRAMBase(A0),D0 ; Get the absolute PRAM address.
Swap D0 ; Save it.
Addq #1,D0 ; Say we want one byte.
Swap D0 ; Save it.
Move.b D1,-(Sp) ; Push the byte to write onto the stack.
Movea.l Sp,A0 ; Point to it.
_WriteXPRAM ; Write it.
Tst.b (Sp)+ ; Clean up the stack.
Rts
Endwith