            opt     l+,o+,ow-
*
*   io.s version 7.6 - © Copyright 1990 Jaba Development
*
*   Author    : Jan van den Baard
*   Assembler : Devpac version 2.14
*
    incdir  'sys:devpac_inc/
    include 'exec/exec_lib.i'
    include 'tool.i'
    include 'mymacros.i'

    xdef    CreatePort
    xdef    DeletePort
    xdef    CreateExtIO
    xdef    DeleteExtIO
    xdef    CreateStdIO
    xdef    DeleteStdIO

    xdef    CreateTimeDelay
    xdef    DoTimeDelay
    xdef    DeleteTimeDelay

*
* port = CreatePort(name,prior)
*  D0                A0   D0
*
CreatePort:     movem.l d2-d3/a2-a3/a6,-(sp)
                move.l  a0,a3
                move.l  d0,d3
                move.l  (_SysBase).w,a6
                moveq   #-1,d0
                libcall AllocSignal
                move.l  d0,d2
                cmp.l   #-1,d0
                bne.s   SigOK
NoPort:         cldat   d0
EndCP:          movem.l (sp)+,d2-d3/a2-a3/a6
                rts
SigOK:          moveq   #MP_SIZE,d0
                move.l  #MEMF_PUBLIC+MEMF_CLEAR,d1
                libcall AllocMem
                move.l  d0,a2
                bne.s   MpOK
                move.l  d2,d0
                libcall FreeSignal
                bra.s   NoPort
MpOK:           move.l  a3,LN_NAME(a2)
                move.b  d3,LN_PRI(a2)
                move.b  #NT_MSGPORT,LN_TYPE(a2)
                clr.b   MP_FLAGS(a2)
                move.b  d2,MP_SIGBIT(a2)
                cladr   a1
                libcall FindTask
                move.l  d0,MP_SIGTASK(a2)
                cmpa.l  #0,a3
                beq.s   NoName
                move.l  a2,a1
                libcall AddPort
                bra.s   Added
NoName:         lea.l   MP_MSGLIST(a2),a0
                move.l  a0,LH_HEAD(a0)
                addq.l  #4,LH_HEAD(a0)
                clr.l   LH_TAIL(a0)
                move.l  a0,LH_TAILPRED(a0)
Added:          move.l  a2,d0
                bra.s   EndCP

*
* DeletePort(port)
*             A0
*
DeletePort:     movem.l a2/a6,-(sp)
                move.l  a0,a2
                move.l  (_SysBase).w,a6
                tst.l   LN_NAME(a2)
                beq.s   NoRem
                move.l  a2,a1
                libcall RemPort
NoRem:          move.b  #-1,LN_TYPE(a2)
                lea.l   MP_MSGLIST(a2),a0
                move.l  #-1,LH_HEAD(a0)
                cldat   d0
                move.b  MP_SIGBIT(a2),d0
                libcall FreeSignal
                moveq   #MP_SIZE,d0
                move.l  a2,a1
                libcall FreeMem
                movem.l (sp)+,a2/a6
                rts

*
* IOReq = CreateExtIO(port,size)
*  D0                  A0   D0
*
CreateExtIO:    movem.l d2/a2-a3/a6,-(sp)
                move.l  a0,a3
                move.l  d0,d2
                cmpa.l  #0,a3
                bne.s   PortGiven
NoIO:           cldat   d0
EndCEI:         movem.l (sp)+,d2/a2-a3/a6
                rts
PortGiven:      move.l  d2,d0
                move.l  #MEMF_PUBLIC+MEMF_CLEAR,d1
                move.l  (_SysBase).w,a6
                libcall AllocMem
                move.l  d0,a2
                beq.s   NoIO
ReqOK:          move.b  #NT_MESSAGE,LN_TYPE(a2)
                move.w  d2,MN_LENGTH(a2)
                move.l  a3,MN_REPLYPORT(a2)
                move.l  a2,d0
                bra.s   EndCEI

*
* StdIO = CreateStdIO(port)
*   D0                 A0
*
CreateStdIO:    moveq   #IOSTD_SIZE,d0
                bsr.s   CreateExtIO
                rts

*
* DeleteStdIO(ioreq), DeleteExtIO(ioreq)
*               A0                 A0
*
DeleteStdIO:
DeleteExtIO:    movem.l a2/a6,-(sp)
                move.l  a0,a2
                cmpa.l  #0,a2
                bne.s   IOPGiven
EndDI:          movem.l (sp)+,a2/a6
                rts
IOPGiven:       move.b  #-1,LN_TYPE(a2)
                move.l  #-1,IO_DEVICE(a2)
                move.l  #-1,IO_UNIT(a2)
                cldat   d0
                move.w  MN_LENGTH(a2),d0
                move.l  a2,a1
                move.l  (_SysBase).w,a6
                libcall FreeMem
                bra.s   EndDI

*
* timedel = CreateTimeDelay(UserPort,Secs,Micros)
*   D0                        A0      A0    D1
*
CreateTimeDelay:
                movem.l d2-d3/a2-a3/a6,-(sp)
                move.l  a0,a3
                move.l  d0,d2
                move.l  d1,d3
                move.l  (_SysBase).w,a6
                moveq   #td_SIZEOF,d0
                move.l  #MEMF_PUBLIC!MEMF_CLEAR,d1
                libcall AllocMem
                move.l  d0,a2
                beq.s   NoTimeDel
                move.l  a3,td_UserPort(a2)
                cladr   a0
                cldat   d0
                bsr     CreatePort
                move.l  d0,td_ReplyPort(a2)
                beq.s   NoPortMem
                move.l  d0,a0
                moveq   #IOTV_SIZE,d0
                bsr     CreateExtIO
                move.l  d0,td_TimeRequest(a2)
                beq.s   NoReqMem
                move.l  d0,a1
                lea.l   timer_name,a0
                moveq   #UNIT_VBLANK,d0
                cldat   d1
                libcall OpenDevice
                tst.l   d0
                bne.s   NoTimer
                move.l  td_TimeRequest(a2),a0
                move.w  #TR_ADDREQUEST,IO_COMMAND(a0)
                lea.l   IOTV_TIME(a0),a0
                move.l  d2,TV_SECS(a0)
                move.l  d3,TV_MICRO(a0)
                move.l  a2,d0
EndCTD:         movem.l (sp)+,d2-d3/a2-a3/a6
                rts
NoTimer:        move.l  td_TimeRequest(a2),a0
                bsr     DeleteExtIO
NoReqMem:       move.l  td_ReplyPort(a2),a0
                bsr     DeletePort
NoPortMem:      move.l  a2,a1
                moveq   #td_SIZEOF,d0
                libcall FreeMem
NoTimeDel:      cldat   d0
                bra.s   EndCTD

*
* DoTimeDelay(TimeDelay)
*                A0
*
DoTimeDelay:    movem.l d2-d4/a2/a6,-(sp)
                move.l  a0,a2
                move.l  (_SysBase).w,a6
                move.l  td_TimeRequest(a2),a1
                lea.l   IOTV_TIME(a1),a0
                move.l  TV_SECS(a0),d2
                move.l  TV_MICRO(a0),d3
                libcall SendIO
                tst.l   td_UserPort(a2)
                beq.s   NoUserPort
                move.l  td_UserPort(a2),a0
                cldat   d0
                move.b  MP_SIGBIT(a0),d0
                bsr.s   SBit
                move.l  d0,d1
                bra.s   WaitForMsg
NoUserPort:     cldat   d1
WaitForMsg:     cldat   d0
                move.l  td_ReplyPort(a2),a0
                move.b  MP_SIGBIT(a0),d0
                bsr.s   SBit
                add.l   d1,d0
                libcall Wait
                move.l  td_TimeRequest(a2),a1
                libcall CheckIO
                tst.l   d0
                beq.s   NoAbort
                move.l  td_TimeRequest(a2),a1
                libcall AbortIO
                move.l  td_ReplyPort(a2),a0
                libcall WaitPort
                cldat   d4
                bra.s   RemReq
NoAbort:        moveq   #1,d4
RemReq:         move.l  td_TimeRequest(a2),a0
                libcall Remove
                move.l  td_TimeRequest(a2),a0
                move.w  #TR_ADDREQUEST,IO_COMMAND(a0)
                lea.l   IOTV_TIME(a0),a0
                move.l  d2,TV_SECS(a0)
                move.l  d3,TV_MICRO(a0)
                move.l  d4,d0
                movem.l (sp)+,d2-d4/a2/a6
                rts
SBit:           movem.l d1,-(sp)
                moveq   #1,d1
                lsl.l   d0,d1
                move.l  d1,d0
                move.l  (sp)+,d1
                rts

*
* DeleteTimeDelay(TimeDelay)
*                    A0
*
DeleteTimeDelay:
                movem.l a2/a6,-(sp)
                move.l  a0,a2
                move.l  (_SysBase).w,a6
                move.l  td_TimeRequest(a2),a1
                libcall CloseDevice
                move.l  td_TimeRequest(a2),a0
                bsr     DeleteExtIO
                move.l  td_ReplyPort(a2),a0
                bsr     DeletePort
                moveq   #td_SIZEOF,d0
                move.l  a2,a1
                libcall FreeMem
                movem.l (sp)+,a2/a6
                rts

timer_name:     TIMERNAME

