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