boot3/DeclData/VSCDeclData/VSCDockingHandler.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

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