;==============================================================================
;===                                                                        ===
;===                    Input und Output - Basis -                          ===
;===                                                                        ===
;===               für Assembler  geschrieben von Aliso 1989                ===
;===               -----------------------------------------                ===
;===                                                                        ===
;===     CreateExtIO: Allokiert eine beliebige IORequest-Struktur           ===
;===     DeleteExtIO: löscht eine allokierte IORequest-Struktur             ===
;===     CreatePort : erstellt eine Message-Port                            ===
;===     DeletePort : löscht einen erstellten Message-Port                  ===
;===                                                                        ===
;===        ( ersetzt somit die Exec-Support-Routinen von AMIGA.LIB )       ===
;===                                                                        ===
;==============================================================================;==============================================================================
;( Exec - Support )

	entry   CreateExtIO
	entry   DeleteExtIO
	entry   CreatePort
	entry   DeletePort

;##############################################################################
;###          P R O G R A M M  -  M A C R O S ( S T A N D A R D )           ###
;##############################################################################

CALLSYS MACRO
 XREF	_LVO\1
 move.l	\2,a6
 jsr	_LVO\1(a6)
 ENDM

CALL MACRO
 XREF	_LVO\1
 jsr	_LVO\1(a6)
 ENDM

;##############################################################################
;###                             L A B E L S                                ###
;##############################################################################

AbsExecBase equ 4

;##############################################################################
;###                   I N C L U D E  -  D A T E I E N                      ###
;##############################################################################

	include	"exec/types.i"
	include	"exec/memory.i"
	include	"exec/io.i"

;##############################################################################
;###                        P R O G R A M M C O D E                         ###
;##############################################################################

	section	Aliso_Exec_Support,Code
;##
;## CreateExtIO
;##
;## => A0 Zeiger auf IOReplyPort-Struktur
;##    D0 Größe in Bytes (Achtung: Angabe in WORD!!)
;## <= D0 Zeiger auf IORequest
;##
CreateExtIO:
	clr.l	IORequest				; Zeiger löschen
	move.w	d0,Size					; Parameter speichern
	move.l	a0,MsgPort				;
	move.l	#MEMF_PUBLIC|MEMF_CLEAR,d1		; Speicher
	CALLSYS	AllocMem,AbsExecBase			; holen
	move.l	d0,IORequest				; Zeiger speichern
	beq.s	1$					; sonst Abbruch
	move.l	d0,a0					; Zeiger nach A0
	move.b	#NT_MESSAGE,LN_TYPE(a0)			; Typ
	move.w	Size,MN_LENGTH(a0)			; Länge (f. DeleteEx.)
	move.l	MsgPort,MN_REPLYPORT(a0)		; ReplyPort eintragen
1$:
	move.l	IORequest,d0				; Zeiger nach A0
	rts						; und zurück

;##
;## DeleteExtIO
;##
;## => A0 Zeiger auf IORequest
;##
DeleteExtIO:
	cmp.l	#0,a0					; = 0?
	beq.s	1$					; ja, Abbruch
	move.b	#$FF,LN_TYPE(a0)			; IORequest ver-
	move.l	#-1,IO_DEVICE(a0)			; stümmeln, da
	move.l	#-1,IO_UNIT(a0)				; FREEMEM den Speicher
	movea.l	a0,a1					; nicht löscht!
	clr.l	d0
	move.w	MN_LENGTH(a0),d0			; Länge nach D0
	CALLSYS	FreeMem,AbsExecBase			; Speicher freigeb.
1$:
	rts						; und zurück

;##
;## CreatePort
;##
;## => A0 Zeiger auf Namen des Ports
;##    D0 Priorität des Ports
;## <= D0 MsgPort
;##
CreatePort:
	clr.l	MsgPort					; MsgPort löschen
	move.b	d0,Pri					; Parameter speichern
	move.l	a0,Name					;
	move.l	#-1,d0					; -1
	CALLSYS	AllocSignal,AbsExecBase			; Signal holen
	cmpi.l	#-1,d0					; -1 ?
	beq.s	1$					; ja, Abbruch
	move.b	d0,Signal				; Signal speichern
	move.l	#MP_SIZE,d0				; Anzahl d. Bytes
	move.l	#MEMF_PUBLIC|MEMF_CLEAR,d1		; Typ
	CALL	AllocMem				; Speicher allokieren
	move.l	d0,MsgPort				; Zeiger speichern
	beq.s	2$					; Fehler!
	move.l	d0,a5					; MsgPort init.
	move.l	Name,LN_NAME(a5)			; Name
	move.b	Pri,LN_PRI(a5)				; Priorität
	move.b	#NT_MSGPORT,LN_TYPE(a5)			; Typ
	move.b	#PA_SIGNAL,MP_FLAGS(a5)			; Flags
	move.b	Signal,MP_SIGBIT(a5)			; SignalBits
	suba.l	a1,a1					; eigene Task suchen
	CALL	FindTask				;
	move.l	d0,MP_SIGTASK(a5)			; 
	movea.l	a5,a1					; Zeiger auf MsgPort
	CALL	AddPort					;
1$:

	move.l	MsgPort,d0				; Zeiger auf MsgPort
	rts
2$:
	clr.l	d0
	move.b	Signal,d0
	CALL	FreeSignal				; Signal frei!
	clr.l	d0					; d0 löschen
	rts						; und zurück
	dc.b	'ALISO',0
	cnop	2

;##
;## DeletePort
;##
;## => A0 IOReplyPort (MsgPort)
;##
DeletePort:
	cmp.l	#0,a0					;
	beq.s	1$
	move.l	a0,-(sp)				; Register retten
	movea.l	a0,a1					; Zeiger kopieren
	CALLSYS	RemPort,AbsExecBase			; Port löschen
	move.l	(sp)+,a1				; Register vom Stack
	move.b	#$FF,LN_TYPE(a1)			; Type ändern
	move.l	#-1,LH_HEAD(a1)				;
	move.l	#MP_SIZE,d0				;
	CALL	FreeMem,AbsExecBase			;
	clr.l	d0					; Signal
	move.b	Signal,d0				; freigeben
	CALL	FreeSignal				;
1$:
	rts

;##############################################################################
;###                         V A R I A B E L N                              ###
;##############################################################################

MsgPort:
	dc.l	0
IORequest:
	dc.l	0
Size:
	dc.w	0
Signal:
	dc.b	0
Pri:
	dc.b	0
Name:
	dc.l	0

;##############################################################################
;###                  E N D E  V O N  I O B A S I S . A                     ###
;##############################################################################