809 lines
21 KiB
NASM
809 lines
21 KiB
NASM
title NAME.LDD device driver for S3/S3a/S3c/S3../HC
|
|||
|
|
subttl Copyright PSION PLC November 1995
|
||
|
|
name NAME
|
||
|
|
|
||
|
|
; VERSION DATE DESCRIPTION
|
||
|
|
; ------- -------- ---------------
|
||
|
|
; 1.0 12/01/95 Template Asic4/5 LDD
|
||
|
|
|
||
|
|
; Written by Jason Robinson January 1995
|
||
|
|
|
||
|
|
BUILDSB equ 1
|
||
|
|
Asic4Type =0
|
||
|
|
Asic5Type =0
|
||
|
|
NeedTheInterrupt =0
|
||
|
|
NeedClocking =0
|
||
|
|
StartChannelInOpen =0
|
||
|
|
|
||
|
|
include ..\inc\epoc.inc
|
||
|
|
include ..\inc\epocser.inc
|
||
|
|
include ..\inc\epoclib.inc
|
||
|
|
include ..\inc\epocsibo.inc
|
||
|
|
include ..\srcs\ossibo.inc
|
||
|
|
include ..\srcs\ospack.inc
|
||
|
|
|
||
|
|
WeSupportS3Only equ Lcd240X80
|
||
|
|
WeSupportS3aOnly equ Lcd480X160
|
||
|
|
WeSupportS3cOnly equ Lcd240X100
|
||
|
|
WeSupportHCOnly equ Lcd160X80
|
||
|
|
if Consumer
|
||
|
|
NumberOfChannels equ 1
|
||
|
|
if Asic9
|
||
|
|
TheMachineWeSupport equ WeSupportS3aOnly
|
||
|
|
else
|
||
|
|
TheMachineWeSupport equ WeSupportS3Only
|
||
|
|
endif
|
||
|
|
else
|
||
|
|
NumberOfChannels equ 3
|
||
|
|
if Asic9
|
||
|
|
TheMachineWeSupport equ WeSupportS3cOnly
|
||
|
|
else
|
||
|
|
TheMachineWeSupport equ WeSupportHCOnly
|
||
|
|
endif
|
||
|
|
endif
|
||
|
|
A4PERIPH_MASK equ 0f0h
|
||
|
|
TheInfoByteThatWeWant equ 1
|
||
|
|
|
||
|
|
TmpltEnt struc
|
||
|
|
TmpltEntOpen db ? ; Channel open flag
|
||
|
|
TmpltChannelStarted db ? ; Channel should be running
|
||
|
|
TmpltHwChannel dw ? ; The harware we want
|
||
|
|
TmpltStructPtr dw ? ; Ptr to CB in Apps DS
|
||
|
|
TmpltTckHandle dw ? ; Tick Handle
|
||
|
|
TmpltChannelRunning db ? ; Can channel really run
|
||
|
|
TmpltInterruptMask db ? ; InterruptMask
|
||
|
|
TmpltChannel db ? ; Channel
|
||
|
|
if NeedTheInterrupt
|
||
|
|
TmpltInterruptNumber db ? ; Interrupt Number
|
||
|
|
TmpltInterruptVector dw ? ; Were to Jump To
|
||
|
|
if Asic5Type and NeedClocking
|
||
|
|
TmpltA5Clocking db ? ; Asic5 baud rate clocking
|
||
|
|
TmpltSpare db ?
|
||
|
|
endif
|
||
|
|
else
|
||
|
|
TmpltSpare db ?
|
||
|
|
endif
|
||
|
|
|
||
|
|
TmpltEnt ends
|
||
|
|
|
||
|
|
TmpltStruct struc
|
||
|
|
Tmpltblk ChanEnt <> ; I/O control block
|
||
|
|
TmpltEntPtr dw ? ; Ptr to our CS CB
|
||
|
|
TmpltStruct ends
|
||
|
|
|
||
|
|
dgroup group stack
|
||
|
|
assume ds:dgroup,es:dgroup,ss:dgroup
|
||
|
|
|
||
|
|
CodeSeg
|
||
|
|
|
||
|
|
ProcBegin@ TmpltLDD
|
||
|
|
; ===================
|
||
|
|
|
||
|
|
dw LDDSignature
|
||
|
|
db 'HSB',0,0,0,0,0
|
||
|
|
dw (TableEnd-TableStart)/2
|
||
|
|
TableStart:
|
||
|
|
dw TmpltInstall
|
||
|
|
dw TmpltRemove
|
||
|
|
dw TmpltHold
|
||
|
|
dw TmpltResume
|
||
|
|
dw TmpltReset
|
||
|
|
dw TmpltUnits
|
||
|
|
dw TmpltOpen
|
||
|
|
dw TmpltStrategy
|
||
|
|
MonitorVector:
|
||
|
|
dw MonitorInt
|
||
|
|
TableEnd:
|
||
|
|
|
||
|
|
if Consumer
|
||
|
|
if Asic9
|
||
|
|
SetupTable db mask A9MSlave,SelectChannel5
|
||
|
|
db (mask A9MClockEnable5 shr 8),HwIrq2Revector
|
||
|
|
if NeedTheInterrupt
|
||
|
|
dw offset Interrupt0
|
||
|
|
endif
|
||
|
|
|
||
|
|
else
|
||
|
|
SetupTable db mask Asic2Int,SelectChannel7
|
||
|
|
db (mask ClockEnable7 shr 8),HwIrq4Revector
|
||
|
|
if NeedTheInterrupt
|
||
|
|
dw offset Interrupt0
|
||
|
|
endif
|
||
|
|
endif
|
||
|
|
else
|
||
|
|
if Asic9
|
||
|
|
SetupTable db mask A9MExpIntA,SelectChannel3
|
||
|
|
db (mask A9MClockEnable3 shr 8),HwIrq4Revector
|
||
|
|
if NeedTheInterrupt
|
||
|
|
dw offset Interrupt0
|
||
|
|
endif
|
||
|
|
db mask A9MExpIntB,SelectChannel4
|
||
|
|
db (mask A9MClockEnable4 shr 8),HwIrq5Revector
|
||
|
|
if NeedTheInterrupt
|
||
|
|
dw offset Interrupt1
|
||
|
|
endif
|
||
|
|
db mask A9MSlave,SelectChannel5
|
||
|
|
db (mask A9MClockEnable5 shr 8),HwIrq2Revector
|
||
|
|
if NeedTheInterrupt
|
||
|
|
dw offset Interrupt2
|
||
|
|
endif
|
||
|
|
else
|
||
|
|
SetupTable db mask ExpIntLeftA,ExpChannelLeftA
|
||
|
|
db (mask ClockEnable6 shr 8),HwIrq3Revector
|
||
|
|
if NeedTheInterrupt
|
||
|
|
dw offset Interrupt0
|
||
|
|
endif
|
||
|
|
db mask ExpIntRightB,ExpChannelRightB
|
||
|
|
db (mask ClockEnable5 shr 8),HwIrq2Revector
|
||
|
|
if NeedTheInterrupt
|
||
|
|
dw offset Interrupt1
|
||
|
|
endif
|
||
|
|
db mask Asic2Int,SelectChannel7
|
||
|
|
db (mask ClockEnable7 shr 8),HwIrq4Revector
|
||
|
|
if NeedTheInterrupt
|
||
|
|
dw offset Interrupt2
|
||
|
|
endif
|
||
|
|
endif
|
||
|
|
endif
|
||
|
|
CsHeldFlag db 0 ; Ldd under a hold?
|
||
|
|
MachineType db 0
|
||
|
|
if Consumer
|
||
|
|
Channel0 TmpltEnt <>
|
||
|
|
else
|
||
|
|
Channel0 TmpltEnt <>
|
||
|
|
Channel1 TmpltEnt <>
|
||
|
|
Channel2 TmpltEnt <>
|
||
|
|
endif
|
||
|
|
|
||
|
|
ProcEnd noret
|
||
|
|
|
||
|
|
ProcBegin@ TmpltInstall,far
|
||
|
|
; ===========================
|
||
|
|
|
||
|
|
; Install the driver
|
||
|
|
; Exit with carry clear for okay
|
||
|
|
|
||
|
|
GenLcdType ; Do we only run on
|
||
|
|
mov MachineType,al ; particular machines?
|
||
|
|
cmp al,TheMachineWeSupport
|
||
|
|
jne CannotInstallOnThisMachine
|
||
|
|
|
||
|
|
pushf
|
||
|
|
cli
|
||
|
|
push ds
|
||
|
|
mov ax, cs
|
||
|
|
mov ds, ax
|
||
|
|
mov CsHeldFlag, 0 ; Initialise all
|
||
|
|
mov cx, NumberOfChannels ; the variables
|
||
|
|
mov di, offset Channel0
|
||
|
|
mov si, offset SetupTable
|
||
|
|
ResetAllChannelsLoop:
|
||
|
|
mov [di].TmpltEntOpen, 0
|
||
|
|
lodsb
|
||
|
|
mov [di].TmpltInterruptMask, al
|
||
|
|
lodsb
|
||
|
|
mov [di].TmpltChannel, al
|
||
|
|
lodsb
|
||
|
|
if NeedClocking
|
||
|
|
mov [di].TmpltA5Clocking, al
|
||
|
|
endif
|
||
|
|
lodsb
|
||
|
|
if NeedTheInterrupt
|
||
|
|
mov [di].TmpltInterruptNumber, al
|
||
|
|
lodsw
|
||
|
|
mov [di].TmpltInterruptVector, ax
|
||
|
|
endif
|
||
|
|
|
||
|
|
add di,size TmpltEnt
|
||
|
|
loop ResetAllChannelsLoop
|
||
|
|
pop ds
|
||
|
|
popf
|
||
|
|
FinishedOkay:
|
||
|
|
clc
|
||
|
|
ret
|
||
|
|
CannotInstallOnThisMachine:
|
||
|
|
mov ax,NotSupportedErr
|
||
|
|
stc
|
||
|
|
ret
|
||
|
|
ProcEnd noret
|
||
|
|
|
||
|
|
ProcBegin@ TmpltRemove,far
|
||
|
|
; ==========================
|
||
|
|
|
||
|
|
; Remove the driver
|
||
|
|
; Exit with carry clear for okay
|
||
|
|
; Exit with carry set if channel still open
|
||
|
|
|
||
|
|
mov cx,NumberOfChannels
|
||
|
|
mov di,offset Channel0
|
||
|
|
xor ax,ax
|
||
|
|
CheckAllChannelsClosedLoop:
|
||
|
|
cmp cs:[di].TmpltEntOpen,al
|
||
|
|
jne WeHaveAnOpenChannelSoFail
|
||
|
|
add di,size TmpltEnt
|
||
|
|
loop CheckAllChannelsClosedLoop
|
||
|
|
jmp FinishedOkay
|
||
|
|
WeHaveAnOpenChannelSoFail:
|
||
|
|
mov ax,InUseErr
|
||
|
|
stc
|
||
|
|
ret
|
||
|
|
ProcEnd noret
|
||
|
|
|
||
|
|
ProcBegin@ TmpltUnits,far
|
||
|
|
; =========================
|
||
|
|
|
||
|
|
; Return the Number of channels that can be opened in AX
|
||
|
|
|
||
|
|
mov ax,NumberOfChannels ; We have ? channels
|
||
|
|
ret
|
||
|
|
ProcEnd noret
|
||
|
|
|
||
|
|
ProcBegin@ TmpltReset,far
|
||
|
|
; =========================
|
||
|
|
|
||
|
|
; Reset the open channel
|
||
|
|
|
||
|
|
mov di,cx
|
||
|
|
cmp cs:[di].TmpltEntOpen,0 ; Somethings gone
|
||
|
|
je NotOpenToReset ; wrong with the
|
||
|
|
mov ah,DevHoldPowerDown ; application that
|
||
|
|
call StopTheChannel ; opened us.
|
||
|
|
call FreeHardware ; Stop interupts and
|
||
|
|
mov cs:[di].TmpltEntOpen,0 ; free the channel
|
||
|
|
NotOpenToReset:
|
||
|
|
ret
|
||
|
|
ProcEnd noret
|
||
|
|
|
||
|
|
ProcBegin@ TmpltHold,far
|
||
|
|
; ========================
|
||
|
|
|
||
|
|
; Hold the channels
|
||
|
|
; Hold reason in AH
|
||
|
|
|
||
|
|
mov cx,1
|
||
|
|
xchg cl,CsHeldFlag ; Stop any interrupts
|
||
|
|
cmp cl,0 ; Mark channel as
|
||
|
|
jne AlreadyHeld ; under a normal hold
|
||
|
|
DoHold:
|
||
|
|
mov cx,NumberOfChannels
|
||
|
|
mov di,offset Channel0
|
||
|
|
HoldAllTheChannelsLoop:
|
||
|
|
cmp cs:[di].TmpltEntOpen,0
|
||
|
|
je DontHoldBecauseNotOpen
|
||
|
|
cmp cs:[di].TmpltChannelStarted,0
|
||
|
|
je DontHoldBecauseNotOpen
|
||
|
|
push ax
|
||
|
|
push cx
|
||
|
|
call StopTheChannel
|
||
|
|
pop cx
|
||
|
|
pop ax
|
||
|
|
DontHoldBecauseNotOpen:
|
||
|
|
add di,size TmpltEnt
|
||
|
|
loop HoldAllTheChannelsLoop
|
||
|
|
AlreadyHeld:
|
||
|
|
ret
|
||
|
|
ProcEnd noret
|
||
|
|
|
||
|
|
ProcBegin@ TmpltResume,far
|
||
|
|
; ==========================
|
||
|
|
|
||
|
|
; Resume the channel
|
||
|
|
|
||
|
|
xor cx,cx ; Be warned during an
|
||
|
|
xchg cl,CsHeldFlag ; on/off the power to
|
||
|
|
cmp cl,0 ; ASIC4 is not restored
|
||
|
|
je AlreadyResumed ; until after this
|
||
|
|
GenDataSegment ; A resume is pointless
|
||
|
|
HwGetSsdData ; if there is still no
|
||
|
|
mov bx,ax ; power to the port
|
||
|
|
cmp es:[bx].SsdDoorStatus,DoorOpen ; Leave the resume
|
||
|
|
je DoorsAreOpen ; to the tick
|
||
|
|
DoResume:
|
||
|
|
mov cx,NumberOfChannels
|
||
|
|
mov di,offset Channel0 ; Right hardware?
|
||
|
|
ResumeAllTheChannelsLoop: ; Else restart
|
||
|
|
cmp cs:[di].TmpltEntOpen,0 ; interrupts
|
||
|
|
je DontResumeBecauseNotOpen
|
||
|
|
cmp cs:[di].TmpltChannelStarted,0
|
||
|
|
je DontResumeBecauseNotOpen
|
||
|
|
push cx
|
||
|
|
call StartTheChannel
|
||
|
|
pop cx
|
||
|
|
DontResumeBecauseNotOpen:
|
||
|
|
add di,size TmpltEnt
|
||
|
|
loop ResumeAllTheChannelsLoop
|
||
|
|
AlreadyResumed:
|
||
|
|
ret
|
||
|
|
DoorsAreOpen:
|
||
|
|
mov CsHeldFlag,2
|
||
|
|
ret
|
||
|
|
ProcEnd noret
|
||
|
|
|
||
|
|
ProcBegin@ TmpltOpen,far
|
||
|
|
; ========================
|
||
|
|
|
||
|
|
; Open the channel
|
||
|
|
; DS,ES,SS Applications data space
|
||
|
|
; Handle in DX
|
||
|
|
|
||
|
|
cld
|
||
|
|
pushf
|
||
|
|
cli
|
||
|
|
call FindFreeChannel
|
||
|
|
jnc GotFreeChannel
|
||
|
|
popf
|
||
|
|
LockedError:
|
||
|
|
mov ax,LockedErr
|
||
|
|
stc
|
||
|
|
ret
|
||
|
|
AllErrorsExitHere:
|
||
|
|
push ax
|
||
|
|
HeapFreeCell
|
||
|
|
pop ax
|
||
|
|
FreeTckAndChannel:
|
||
|
|
push ax
|
||
|
|
call FreeHardware
|
||
|
|
pop ax
|
||
|
|
FreeTckAndExit:
|
||
|
|
push ax
|
||
|
|
mov bx,cs:[di].TmpltTckHandle
|
||
|
|
IoClose
|
||
|
|
pop ax
|
||
|
|
CloseThenFree:
|
||
|
|
mov cs:[di].TmpltEntOpen,0
|
||
|
|
stc
|
||
|
|
ret
|
||
|
|
GotFreeChannel:
|
||
|
|
mov cs:[di].TmpltEntOpen,1
|
||
|
|
mov cs:[di].TmpltChannelStarted,0
|
||
|
|
mov cs:[di].TmpltChannelRunning,0
|
||
|
|
popf
|
||
|
|
xor ax,ax
|
||
|
|
push ax
|
||
|
|
mov ax,((':' shl 8)+'K')
|
||
|
|
push ax
|
||
|
|
mov ax,(('C' shl 8)+'T')
|
||
|
|
push ax
|
||
|
|
mov bx,sp
|
||
|
|
IoOpen
|
||
|
|
jnc GotATickChannel
|
||
|
|
add sp,6
|
||
|
|
mov ax,LockedErr
|
||
|
|
jmp CloseThenFree
|
||
|
|
GotATickChannel:
|
||
|
|
add sp,6
|
||
|
|
mov cs:[di].TmpltTckHandle,ax
|
||
|
|
push dx
|
||
|
|
mov bx,ax
|
||
|
|
mov ax,IoFuncStart
|
||
|
|
mov cx,1
|
||
|
|
push cx ; Frequency 1 tick
|
||
|
|
push di ; Data is our CS CB
|
||
|
|
push dx ; Our device handle
|
||
|
|
mov cx,(MonitorVector-TableStart)/2 ; Vector to call
|
||
|
|
push cx
|
||
|
|
mov cx,sp
|
||
|
|
IoWithWait
|
||
|
|
add sp,8
|
||
|
|
pop dx
|
||
|
|
call GetHardware
|
||
|
|
jc FreeTckAndExit
|
||
|
|
|
||
|
|
mov cx,(size TmpltStruct) ; Get ourselfs a CB
|
||
|
|
HeapAllocateCell ; In the applications
|
||
|
|
jc FreeTckAndChannel ; Data space
|
||
|
|
|
||
|
|
mov bx,ax
|
||
|
|
mov [bx].Tmpltblk.ChanNext,bx
|
||
|
|
mov [bx].Tmpltblk.ChanSignature,IoChanSignature
|
||
|
|
mov [bx].Tmpltblk.ChanLibHandle,dx
|
||
|
|
mov [bx].TmpltEntPtr,di
|
||
|
|
push bx
|
||
|
|
mov bx,dx
|
||
|
|
mov cx,di
|
||
|
|
IoRequestReset
|
||
|
|
pop bx
|
||
|
|
if StartChannelInOpen
|
||
|
|
call StartChannelFromOpen
|
||
|
|
endif
|
||
|
|
xor ax,ax
|
||
|
|
ret
|
||
|
|
ProcEnd noret
|
||
|
|
|
||
|
|
StrategyVectorTable label word
|
||
|
|
dw offset StrategyDefault
|
||
|
|
dw offset StrategyDefault
|
||
|
|
dw offset StrategyDefault
|
||
|
|
dw offset TmpltClose
|
||
|
|
dw offset StrategyDefault
|
||
|
|
dw offset StrategyDefault
|
||
|
|
dw offset StrategyDefault
|
||
|
|
dw offset StrategyDefault
|
||
|
|
dw offset StrategyDefault
|
||
|
|
dw offset StrategyDefault
|
||
|
|
dw offset StrategyDefault
|
||
|
|
dw offset StrategyDefault
|
||
|
|
dw offset StrategyDefault
|
||
|
|
dw offset StrategyDefault
|
||
|
|
|
||
|
|
ProcBegin@ TmpltStrategy,far
|
||
|
|
; ============================
|
||
|
|
|
||
|
|
; BX is our control block
|
||
|
|
; SI points to the parameters
|
||
|
|
; DS,ES Applications data space
|
||
|
|
|
||
|
|
mov ax,[si].RqFunction
|
||
|
|
mov dx,[si].RqA1Ptr
|
||
|
|
cmp ax,IoFuncSuperFrame
|
||
|
|
ja StrategyDefault
|
||
|
|
shl ax,1
|
||
|
|
mov di,ax
|
||
|
|
push StrategyVectorTable[di]
|
||
|
|
mov di,[bx].TmpltEntPtr
|
||
|
|
retn
|
||
|
|
StrategyDefault:
|
||
|
|
IoRoot
|
||
|
|
ret
|
||
|
|
ExitStrategyOkay:
|
||
|
|
xor ax,ax
|
||
|
|
ExitStrategy:
|
||
|
|
mov di,[si].RqStatusPtr
|
||
|
|
mov word ptr [di],ax
|
||
|
|
cmp ax,PendingErr
|
||
|
|
je JustExit
|
||
|
|
IoSignal
|
||
|
|
JustExit:
|
||
|
|
xor ax,ax
|
||
|
|
ret
|
||
|
|
ProcEnd noret
|
||
|
|
|
||
|
|
ProcBegin@ TmpltClose,far
|
||
|
|
; =========================
|
||
|
|
|
||
|
|
; Close a channel
|
||
|
|
; DI CS control block
|
||
|
|
; BX DS control block
|
||
|
|
; SI points to aurguments on stack
|
||
|
|
; DX Argument one pointer
|
||
|
|
|
||
|
|
mov ah,DevHoldPowerDown
|
||
|
|
call StopTheChannel
|
||
|
|
call FreeHardware
|
||
|
|
mov cs:[di].TmpltChannelStarted,0
|
||
|
|
push bx
|
||
|
|
mov bx,[bx].Tmpltblk.ChanLibHandle
|
||
|
|
mov cx,di
|
||
|
|
IoRequestResetCancel
|
||
|
|
pop bx
|
||
|
|
HeapFreeCell
|
||
|
|
mov bx,cs:[di].TmpltTckHandle
|
||
|
|
IoClose
|
||
|
|
mov cs:[di].TmpltEntOpen,0
|
||
|
|
jmp short ExitStrategyOkay
|
||
|
|
ProcEnd noret
|
||
|
|
|
||
|
|
ProcBegin@ StartTheChannel
|
||
|
|
; ==========================
|
||
|
|
|
||
|
|
; Start the Channel Running
|
||
|
|
; Assume channel set up and interrupts off
|
||
|
|
|
||
|
|
cmp cs:[di].TmpltChannelRunning,0
|
||
|
|
jne ChannelAlreadyRunning
|
||
|
|
|
||
|
|
if Asic5Type and NeedClocking
|
||
|
|
if Asic9
|
||
|
|
in ax, A9WControlExtraRW ; Start the S3s clock
|
||
|
|
or ah, [bx].TmpltA5Clocking ; Generator
|
||
|
|
out A9WControlExtraRW, ax
|
||
|
|
else
|
||
|
|
mov al, [bx].TmpltA5Clocking
|
||
|
|
HwSetA2Control2Bits
|
||
|
|
endif
|
||
|
|
endif
|
||
|
|
if NeedTheInterrupt
|
||
|
|
mov al, cs:[di].TmpltInterruptNumber ; Load the address of
|
||
|
|
mov cx, cs ; the appropriate
|
||
|
|
mov bx, cs:[di].TmpltInterruptVector ; interrupt routine
|
||
|
|
GenSetRevector ; into the correct vector
|
||
|
|
if Asic9
|
||
|
|
in al,A9BInterruptMaskRW ; Set the mask
|
||
|
|
or al,cs:[di].TmpltInterruptMask ; to enable Interrupts
|
||
|
|
out A9BInterruptMaskRW,al
|
||
|
|
else
|
||
|
|
in al, A1InterruptMask
|
||
|
|
or al,cs:[di].TmpltInterruptMask
|
||
|
|
out A1InterruptMask, al
|
||
|
|
endif
|
||
|
|
endif
|
||
|
|
mov cs:[di].TmpltChannelRunning,1
|
||
|
|
ChannelAlreadyRunning:
|
||
|
|
ret
|
||
|
|
ProcEnd noret
|
||
|
|
|
||
|
|
ProcBegin@ StopTheChannel
|
||
|
|
; =========================
|
||
|
|
|
||
|
|
; Stop the Channel Running
|
||
|
|
; Assume channel set up and interrupts off
|
||
|
|
; Stop reason in AH
|
||
|
|
|
||
|
|
cmp byte ptr cs:[di].TmpltChannelRunning,0
|
||
|
|
je ChannelAlreadyStopped
|
||
|
|
if NeedTheInterrupt
|
||
|
|
mov ah,cs:[di].TmpltInterruptMask
|
||
|
|
not ah
|
||
|
|
if Asic9
|
||
|
|
in al,A9BInterruptMaskRW ; Stop Interrupts
|
||
|
|
and al,ah ; By clearing the
|
||
|
|
out A9BInterruptMaskRW,al ; Mask and resetting
|
||
|
|
else ; The Vector
|
||
|
|
in al, A1InterruptMask
|
||
|
|
and al,ah
|
||
|
|
out A1InterruptMask, al
|
||
|
|
endif
|
||
|
|
mov al, cs:[di].TmpltInterruptNumber
|
||
|
|
GenResetRevector
|
||
|
|
endif
|
||
|
|
if Asic5Type and NeedClocking
|
||
|
|
if Asic9
|
||
|
|
mov cl, [bx].TmpltA5Clocking ; Turn off baud rate
|
||
|
|
not cl ; clocking from the
|
||
|
|
in ax, A9WControlExtraRW ; S3/3a
|
||
|
|
and ah, cl
|
||
|
|
out A9WControlExtraRW, ax
|
||
|
|
else
|
||
|
|
mov al, [bx].TmpltA5Clocking
|
||
|
|
HwClearA2Control2Bits
|
||
|
|
endif
|
||
|
|
endif
|
||
|
|
mov cs:[di].TmpltChannelRunning,0
|
||
|
|
ChannelAlreadyStopped:
|
||
|
|
ret
|
||
|
|
ProcEnd noret
|
||
|
|
|
||
|
|
if StartChannelInOpen
|
||
|
|
ProcBegin@ StartChannelFromOpen
|
||
|
|
; ===============================
|
||
|
|
|
||
|
|
pushf
|
||
|
|
cli
|
||
|
|
mov cs:[di].TmpltChannelStarted,1
|
||
|
|
mov al,cs:[di].TmpltChannel
|
||
|
|
HwSelectChannel
|
||
|
|
push ax
|
||
|
|
call StartTheChannel
|
||
|
|
pop ax
|
||
|
|
HwSelectChannel
|
||
|
|
popf
|
||
|
|
ret
|
||
|
|
ProcEnd noret
|
||
|
|
endif
|
||
|
|
ProcBegin@ GetHardware
|
||
|
|
; ======================
|
||
|
|
|
||
|
|
mov al, cs:[di].TmpltInterruptMask
|
||
|
|
HwGetChannel
|
||
|
|
jc ChannelNotAvailable
|
||
|
|
pushf
|
||
|
|
cli
|
||
|
|
mov al,cs:[di].TmpltChannel
|
||
|
|
HwSelectChannel
|
||
|
|
push ax
|
||
|
|
call CheckForHardware
|
||
|
|
pop ax
|
||
|
|
jc NoHardwareFreeTheChannel
|
||
|
|
HwSelectChannel
|
||
|
|
popf
|
||
|
|
clc
|
||
|
|
ret
|
||
|
|
NoHardwareFreeTheChannel:
|
||
|
|
HwSelectChannel
|
||
|
|
popf
|
||
|
|
mov al, cs:[di].TmpltInterruptMask
|
||
|
|
HwFreeChannel
|
||
|
|
ChannelNotAvailable:
|
||
|
|
stc
|
||
|
|
ret
|
||
|
|
ProcEnd noret
|
||
|
|
|
||
|
|
ProcBegin@ FreeHardware
|
||
|
|
; =======================
|
||
|
|
|
||
|
|
mov al, cs:[di].TmpltInterruptMask
|
||
|
|
HwFreeChannel
|
||
|
|
ret
|
||
|
|
ProcEnd noret
|
||
|
|
|
||
|
|
ProcBegin@ FindFreeChannel
|
||
|
|
; ==========================
|
||
|
|
|
||
|
|
mov si,[si].OpenNamePtr
|
||
|
|
mov al,[si+1]
|
||
|
|
CharToFoldedChar
|
||
|
|
cmp al,'A'
|
||
|
|
jb CantGetThatChannel
|
||
|
|
sub al,'A'
|
||
|
|
cmp al,NumberOfChannels
|
||
|
|
jae CantGetThatChannel
|
||
|
|
xor ah,ah
|
||
|
|
push dx
|
||
|
|
mov dx,size TmpltEnt
|
||
|
|
mul dx
|
||
|
|
pop dx
|
||
|
|
mov di,ax
|
||
|
|
add di,offset Channel0
|
||
|
|
cmp cs:[di].TmpltEntOpen,0
|
||
|
|
je FoundAFreeChannel
|
||
|
|
CantGetThatChannel:
|
||
|
|
stc
|
||
|
|
ret
|
||
|
|
FoundAFreeChannel:
|
||
|
|
clc
|
||
|
|
ret
|
||
|
|
ProcEnd noret
|
||
|
|
|
||
|
|
ProcBegin@ CheckForHardware
|
||
|
|
; ===========================
|
||
|
|
|
||
|
|
; Assume Interrupts are off
|
||
|
|
; Correct channel should be selected
|
||
|
|
; Out: clc - got correct hardware
|
||
|
|
; stc - wrong or no hardware
|
||
|
|
|
||
|
|
if Asic5Type
|
||
|
|
HwNullFrame ; Check that the
|
||
|
|
mov al,(SerialSelect or Asic5NormalId) ; Harware is there
|
||
|
|
SBUSY ; And that it is what
|
||
|
|
SCONTOUT ; It should be
|
||
|
|
XNOP ; First look for An
|
||
|
|
SBUSY ; ASIC5 at the other
|
||
|
|
SDATAIN ; End of the link
|
||
|
|
test al,al
|
||
|
|
je ConnectionFailed
|
||
|
|
GotConnection:
|
||
|
|
popf
|
||
|
|
clc
|
||
|
|
ret
|
||
|
|
ConnectionFailed:
|
||
|
|
mov al, SerialSelect or Asic4Id ; Asic4 Id
|
||
|
|
SBUSY
|
||
|
|
SCONTOUT
|
||
|
|
XNOP
|
||
|
|
SBUSY
|
||
|
|
SDATAIN
|
||
|
|
test al, al
|
||
|
|
jne ConnectionFailedExit
|
||
|
|
else
|
||
|
|
HwNullFrame
|
||
|
|
mov al,(SerialSelect or Asic4Id)
|
||
|
|
SBUSY ; First look for An
|
||
|
|
SCONTOUT ; ASIC4 at the other
|
||
|
|
XNOP ; End of the link
|
||
|
|
SBUSY
|
||
|
|
SDATAIN
|
||
|
|
test al, al
|
||
|
|
je ConnectionFailed
|
||
|
|
mov al,SerialReadSingle or A4InfoR ; Now see if we have
|
||
|
|
SBUSY ; The right card
|
||
|
|
SCONTOUT
|
||
|
|
XNOP ; Allows the busy signal to come through for the wait
|
||
|
|
SBUSY
|
||
|
|
SDATAIN
|
||
|
|
and al,A4PERIPH_MASK
|
||
|
|
cmp al,TheInfoByteThatWeWant
|
||
|
|
jne ConnectionFailedExit
|
||
|
|
clc
|
||
|
|
ret
|
||
|
|
ConnectionFailed:
|
||
|
|
mov al,(SerialSelect or Asic5NormalId) ; Select as an
|
||
|
|
SBUSY ; Asic5 peripheral
|
||
|
|
SCONTOUT
|
||
|
|
XNOP
|
||
|
|
SDATAIN
|
||
|
|
test al,al
|
||
|
|
jne ConnectionFailedExit
|
||
|
|
endif
|
||
|
|
mov al, SerialSelect or Asic8Id ; Modem chip Id
|
||
|
|
SBUSY
|
||
|
|
SCONTOUT
|
||
|
|
XNOP
|
||
|
|
SBUSY
|
||
|
|
SDATAIN
|
||
|
|
test al, al
|
||
|
|
jne ConnectionFailedExit
|
||
|
|
mov al, SerialSelect or Asic5PackId ; Asic5pack Id
|
||
|
|
SBUSY
|
||
|
|
SCONTOUT
|
||
|
|
XNOP
|
||
|
|
SBUSY
|
||
|
|
SDATAIN
|
||
|
|
ConnectionFailedExit:
|
||
|
|
stc
|
||
|
|
ret
|
||
|
|
ProcEnd noret
|
||
|
|
|
||
|
|
ProcBegin@ MonitorInt,far
|
||
|
|
; =========================
|
||
|
|
|
||
|
|
; Called on every tick
|
||
|
|
; Issues pack door hold and resumes
|
||
|
|
; In: Door state in SI
|
||
|
|
|
||
|
|
cmp si,DoorOpen
|
||
|
|
je TheDoorIsOpenSoCantDoAnything
|
||
|
|
cmp CsHeldFlag,2
|
||
|
|
je NeedToDoTheResume
|
||
|
|
ret
|
||
|
|
NeedToDoTheResume:
|
||
|
|
mov CsHeldFlag,0
|
||
|
|
jmp DoResume
|
||
|
|
TheDoorIsOpenSoCantDoAnything:
|
||
|
|
cmp CsHeldFlag,0
|
||
|
|
jne DontNeedToHold
|
||
|
|
mov CsHeldFlag,2
|
||
|
|
mov ah,DevHoldPowerFail
|
||
|
|
jmp DoHold
|
||
|
|
DontNeedToHold:
|
||
|
|
ret
|
||
|
|
ProcEnd noret
|
||
|
|
|
||
|
|
if NeedTheInterrupt
|
||
|
|
ife Consumer
|
||
|
|
ProcBegin@ Interrupt2,far
|
||
|
|
; =========================
|
||
|
|
|
||
|
|
mov di,offset Channel2
|
||
|
|
mov ax,PortCActive
|
||
|
|
jmp ComInt
|
||
|
|
ProcEnd noret
|
||
|
|
|
||
|
|
ProcBegin@ Interrupt1,far
|
||
|
|
; =========================
|
||
|
|
|
||
|
|
mov di,offset Channel1
|
||
|
|
mov ax,PortBActive
|
||
|
|
jmp ComInt
|
||
|
|
ProcEnd noret
|
||
|
|
endif
|
||
|
|
|
||
|
|
ProcBegin@ Interrupt0,far
|
||
|
|
; =========================
|
||
|
|
|
||
|
|
mov di,offset Channel0
|
||
|
|
mov ax,PortAActive
|
||
|
|
; FALLTHROUGH to ComInt
|
||
|
|
ProcEnd noret
|
||
|
|
|
||
|
|
ProcBegin@ ComInt,far
|
||
|
|
; =====================
|
||
|
|
|
||
|
|
if Asic9
|
||
|
|
out A9BNonSpecificEoiW,al
|
||
|
|
else
|
||
|
|
out A1NonSpecificEoi, al
|
||
|
|
endif
|
||
|
|
clc
|
||
|
|
ret
|
||
|
|
ProcEnd noret
|
||
|
|
endif
|
||
|
|
|
||
|
|
|
||
|
|
EndCodeSeg
|
||
|
|
stack segment stack para 'data'
|
||
|
|
stack ends
|
||
|
|
end TmpltLDD
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|