Files
Zorro-LAN-IDE/Driver/baxnet/enc624j6net/intervaltimer.asm
T

342 lines
6.5 KiB
NASM

******************************************************************************
* Name: intervaltimer.s *
* Date: $Date: 2016-12-18 22:20:04 +0100 (So, 18. Dez 2016) $ *
* Authors: Henryk Richter *
******************************************************************************
;MACHINE MC68040
include exec/types.i
include lvo/exec_lib.i
include lvo/dos_lib.i
include lvo/timer_lib.i
include exec/exec.i
include dos/dos.i
include dos/dostags.i
include exec/io.i
include dos/dosextens.i
include exec/lists.i
DO_TEST EQU 0
ifne 1
include "intervaltimer.i"
else
STRUCTURE IVT_TimerStruct,0
ULONG IVT_Interval ;<1e6 in microseconds
LONG IVT_Signal ;Signal that is sent back to task from interrupt
ULONG IVT_SigMask
APTR IVT_SigTask ;Task that is signaled
APTR IVT_Port
APTR IVT_IORequest
APTR IVT_Device
STRUCT IVT_Int,IS_SIZE ;
BYTE IVT_Init ; !=0 - initialized
BYTE IVT_Runflag ; current status ( !=0 = running )
BYTE IVT_Stopflag ; stop request if != 0
BYTE IVT_Unused ;
ULONG IVT_Counter ; Counter (statistics)
LABEL IVT_Size
endc
xdef _InterruptIntervalTimer
xdef _InitIntervalTimer
xdef _ExitIntervalTimer
xdef _StartIntervalTimer
xdef _StopIntervalTimer
CALLEXEC macro
move.l 4.w,a6
jsr _LVO\1(a6)
endm
section code,text
ifne DO_TEST
TestTimer:
lea dos_name,a1 ;string base
moveq #0,d0
move.l 4.w,a6
jsr _LVOOpenLibrary(a6)
move.l d0,dosbase
beq .nodos
move.l dosbase,a6
jsr _LVOOutput(a6) ;get stdout
move.l d0,stdout
lea timerbase,a1
bsr _InitIntervalTimer
tst.l d0
bge .ok
move.l stdout,d0
move.l #failtimer,d1
move.l dosbase,16
jsr _LVOPutStr(a6)
bra .error
.ok
lea timerbase,a1
move.l #10000,d1
bsr _StartIntervalTimer
moveq #0,d3
.loop
cmp.l #10,d3
bgt.s .exitloop
move.l dosbase,A6
moveq #10,d1
jsr _LVODelay(a6)
addq.l #1,d3
lea timerbase,a1
cmp.l #100,IVT_Counter(a1)
blt.s .loop
.exitloop:
move.l #succname,d1
cmp.l #10,d3
ble.s .succ
move.l #failname,d1
.succ:
jsr _LVOVPrintf(a6)
lea timerbase,a1
bsr _StopIntervalTimer
.error
lea timerbase,a1
bsr _ExitIntervalTimer
move.l dosbase,d0
beq.s .nodos
move.l d0,a1
move.l 4.w,a6
jsr _LVOCloseLibrary(a6)
.nodos:
rts
ENDC ;DO_TEST
; A1 = IVT_TimerStruct
_InterruptIntervalTimer:
movem.l d1-a6,-(sp)
;<- basic Timer.device ops ->
move.l a1,a2
move.l IVT_Port(a2),a0
CALLEXEC GetMsg
tst.l d0
beq.s .error
move.l IVT_SigMask(a2),d0 ;move.l IVT_Signal(a2),d0
move.l IVT_SigTask(a2),a1
CALLEXEC Signal
tst.b IVT_Stopflag(a2)
bne.s .error ;not exactly an error but same consequence
move.l a2,a1
bsr _RestartIntervalTimer
;<- end basic Timer.device ops ->
;<- useful stuff ->
addq.l #1,IVT_Counter(a2)
;<- useful stuff ->
bra.s .endintroutine
.error:
clr.b IVT_Runflag(a2)
.endintroutine:
movem.l (sp)+,d1-a6
rts
_InitIntervalTimer: ;prepare timer.device for buffer swap interrupt
movem.l d1-a6,-(sp)
move.l a1,a2
move #IVT_Size-1,d0
.clr
clr.b (a1)+ ;
dbf d0,.clr
sf IVT_Init(a2)
sf IVT_Runflag(a2)
;signal to wait for from timer output if output queue full
moveq #-1,d0
CALLEXEC AllocSignal
move.l d0,IVT_Signal(a2) ; <0 ? error, valid are 0..31
blt .error ; error: have to go (shouldn't happen)
moveq #0,d1
bset d0,d1
move.l d1,IVT_SigMask(a2)
suba.l a1,a1
CALLEXEC FindTask
move.l d0,IVT_SigTask(a2)
CALLEXEC CreateMsgPort ;Create MsgPort for timing...
move.l d0,IVT_Port(a2)
beq .error ;0=error
move.l IVT_Port(a2),a0
move.l #IOTV_SIZE,d0
CALLEXEC CreateIORequest
move.l d0,IVT_IORequest(a2)
beq .error ;0=error
lea.l IVT_Int(a2),a0
lea _InterruptIntervalTimer(pc),a1
move.l a1,IS_CODE(a0)
move.l a2,IS_DATA(a0)
move.b #NT_INTERRUPT,LN_TYPE(a0)
move.b #0,LN_PRI(a0) ;-32,-16,0,16,32
move.l IVT_Port(a2),a1
;move.b #NT_MSGPORT,LN_TYPE(a1)
move.b #PA_SOFTINT,MP_FLAGS(a1)
move.l a0,MP_SIGTASK(a1) ;Softint eintragen
lea VBtimer_name,a0
moveq #UNIT_MICROHZ,d0
move.l IVT_IORequest(a2),a1
moveq #0,d1
CALLEXEC OpenDevice
tst.l d0
beq.s .ok
moveq #0,d0
bra.s .error
.ok ;OK, timer device is ready
st IVT_Init(a2)
moveq #1,d0 ;OK
.error
movem.l (sp)+,d1-a6
;ret 0 <= err, >0 = ok
rts
_ExitIntervalTimer:
;stop timer.device
movem.l d0-a6,-(sp)
move.l a1,a2
sf IVT_Init(a2)
move.l IVT_IORequest(a2),d5
beq.s .noIO
tst.b IVT_Runflag(a2)
beq.s .noAbort
st IVT_Stopflag(a2)
ifne 0
move.l d5,a1
CALLEXEC WaitIO
else
move.l d5,a1
move.l IO_DEVICE(a1),a6
jsr DEV_ABORTIO(A6) ;clear pending requests
endc
.noAbort:
move.l d5,a1
CALLEXEC CloseDevice
move.l d5,a0
CALLEXEC DeleteIORequest
clr.l IVT_IORequest(a2)
.noIO:
move.l IVT_Port(a2),d0
beq.s .noPort
move.l d0,a0
CALLEXEC DeleteMsgPort
clr.l IVT_Port(a2)
.noPort:
move.l IVT_Signal(a2),d0
not.l d0 ;if( d0 == -1 ) d0 = 0
beq.s .nosig
not.l d0 ; swap back
CALLEXEC FreeSignal
moveq #-1,d0
move.l d0,IVT_Signal(a2)
.nosig:
movem.l (sp)+,d0-a6
rts
; input:
; A1 = IVT Structure (after init)
; D1 = Number of Microseconds
_StartIntervalTimer:
movem.l d0/a1/a2/a6,-(Sp)
move.l a1,a2
move.l d1,IVT_Interval(A2)
sf IVT_Stopflag(a2)
tst.b IVT_Runflag(a2) ;running already ? -> keep it running
bne.s .notimer
move.l a2,a1
bsr _RestartIntervalTimer
.notimer
movem.l (sp)+,d0/a1/a2/a6
rts
; Non-Public
; A1 - IVT Structure
_RestartIntervalTimer:
movem.l d0/a1/a2/a6,-(sp)
move.l a1,a2
move.l IVT_IORequest(a2),d0
beq.s .notimer
move.l d0,a1
move.w #TR_ADDREQUEST,IO_COMMAND(a1)
clr.b IO_FLAGS(a1)
clr.l IOTV_TIME+EV_HI(a1)
move.l IVT_Interval(A2),IOTV_TIME+EV_LO(a1)
move.l IO_DEVICE(a1),a6
jsr DEV_BEGINIO(A6)
st IVT_Runflag(a2)
.notimer
movem.l (sp)+,d0/a1/a2/a6
rts
_StopIntervalTimer:
movem.l d0-a6,-(Sp)
move.l a1,a2
st IVT_Stopflag(a2)
tst.b IVT_Runflag(a2)
beq.s .noIO
move.l IVT_IORequest(a2),d5
beq.s .noIO
move.l d5,a1
move.l IO_DEVICE(a1),a6
jsr DEV_ABORTIO(A6) ;clear pending requests
sf IVT_Runflag(a2)
.noIO:
movem.l (sp)+,d0-a6
rts
section data,data
dosbase: dc.l 0
stdout: dc.l 0
timerbase: ds.b IVT_Size
VBtimer_name: dc.b "timer.device",0
ifne DO_TEST
dos_name: dc.b "dos.library",0
succname: dc.b "success: timer worked",10,0
failname: dc.b "failure: timer didn't work",10,0
failtimer: dc.b "timer open failure",10,0
ENDC ;DO_TEST
END