Files
sibo-playground/code/HDK/TMPSALDD.ASM
2026-07-06 18:30:06 +01:00

532 lines
13 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 LDD
; Written by Jason Robinson January 1995
BUILDSB equ 1
include ..\inc\epoc.inc
include ..\inc\epocser.inc
include ..\inc\epoclib.inc
include ..\inc\epocsibo.inc
include ..\srcs\ossibo.inc
include ..\srcs\ospack.inc
OpenSpecificChannel =0
MachineSpecific =0
PeripheralTypeDriver =0
TickRequired =0
NumberOfChannels equ 1
WeSupportS3Only equ Lcd240X80
WeSupportS3aOnly equ Lcd480X160
WeSupportS3cOnly equ Lcd240X100
WeSupportHCOnly equ Lcd160X80
TheMachineWeSupport equ WeSupportS3aOnly
TmpltEnt struc
TmpltEntOpen db ? ; Channel open flag
TmpltChannelStarted db ? ; Channel should be running
TmpltChannelRunning db ? ; Can channel really run
TmpltSpare db ?
TmpltHwChannel dw ? ; The harware we want
TmpltStructPtr dw ? ; Ptr to CB in Apps DS
if PeripheralTypeDriver or TickRequired
TmpltTckHandle dw ? ; Tick Handle
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
if PeripheralTypeDriver or TickRequired
MonitorVector:
dw MonitorInt
endif
TableEnd:
CsHeldFlag db 0 ; Ldd under a hold?
MachineType db 0
Channel0 TmpltEnt <>
ProcEnd noret
ProcBegin@ TmpltInstall,far
; ===========================
; Install the driver
; Exit with carry clear for okay
if MachineSpecific
GenLcdType ; Do we only run on
mov MachineType,al ; particular machines?
cmp al,TheMachineWeSupport
jne CannotInstallOnThisMachine
endif
mov CsHeldFlag,0 ; Initialise all
mov cx,NumberOfChannels ; the variables
mov di,offset Channel0
xor ax,ax
ResetAllChannelsLoop:
mov cs:[di].TmpltEntOpen,al
add di,size TmpltEnt
loop ResetAllChannelsLoop
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
if PeripheralTypeDriver
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
endif
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
if PeripheralTypeDriver
DoorsAreOpen:
mov CsHeldFlag,2
ret
endif
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:
if PeripheralTypeDriver or TickRequired
push ax
mov bx,cs:[di].TmpltTckHandle
IoClose
pop ax
endif
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
if PeripheralTypeDriver or TickRequired
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
endif
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
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
push bx
mov bx,[bx].Tmpltblk.ChanLibHandle
mov cx,di
IoRequestResetCancel
pop bx
HeapFreeCell
if PeripheralTypeDriver or TickRequired
mov bx,cs:[di].TmpltTckHandle
IoClose
endif
mov cs:[di].TmpltEntOpen,0
jmp short ExitStrategyOkay
ProcEnd noret
ProcBegin@ StartTheChannel
; ==========================
; Start the Channel Running
cmp byte ptr cs:[di].TmpltChannelRunning,0
jne ChannelAlreadyRunning
mov cs:[di].TmpltChannelRunning,1
ChannelAlreadyRunning:
clc
ret
ProcEnd noret
ProcBegin@ StopTheChannel
; =========================
; Stop the Channel Running
cmp byte ptr cs:[di].TmpltChannelRunning,0
je ChannelAlreadyStopped
mov cs:[di].TmpltChannelRunning,0
ChannelAlreadyStopped:
clc
ret
ProcEnd noret
ProcBegin@ GetHardware
; ======================
clc
ret
ProcEnd noret
ProcBegin@ FreeHardware
; =======================
clc
ret
ProcEnd noret
If OpenSpecificChannel
ProcBegin@ FindFreeChannel
; ==========================
; Called from Open
; Must preserve DX,SI
; Channel out in DI or carry set if failure
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
else
ProcBegin@ FindFreeChannel
; ==========================
mov cx,NumberOfChannels
mov di,offset Channel0
HuntAllChannelsLoop:
cmp cs:[di].TmpltEntOpen,0
je FoundAFreeChannel
add di,size TmpltEnt
loop HuntAllChannelsLoop
stc
ret
FoundAFreeChannel:
clc
ret
ProcEnd noret
endif
if PeripheralTypeDriver or TickRequired
ProcBegin@ MonitorInt,far
; =========================
if PeripheralTypeDriver
; 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:
endif
ret
ProcEnd noret
endif
EndCodeSeg
stack segment stack para 'data'
stack ends
end TmpltLDD