mirror of
https://github.com/elliotnunn/mac-rom.git
synced 2025-01-05 23:30:34 +00:00
0ba83392d4
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.
831 lines
31 KiB
Plaintext
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 |