;*---------------------------------------------------------------------------
;  :Program.	osemu.asm
;  :Author.	Harry, Wepl
;  :RCS.	$Id: osemu.asm 1.8 1998/09/21 23:25:22 jah Exp jah $
;  :History.	all work before history starts done by Harry
;		30.06.98   Wepl     rework started
;		06.07.98   Wepl     rework finished
;		07.07.98   Wepl     exec.Supervisor,exec.SuperState,exec.UserState
;			            exec.FindTask,exec.FindPort,exec.OpenDevice
;			            graphics.alot,exec.DoIO
;		15.07.98   Wepl     work for Deuteros finished
;		31.07.1998 Harry    SSP set on memtop again as it is in kick1.3
;				    possibility of trainer routine added
;		10.08.98   Wepl     osemu header struct changed (SLAVETRAINER now
;				    in osemu-struct instead overgiven via reg)
;		10.08.98   Wepl     gfx.BltBitMap fixed
;		??.0?.98   MrLarmer some additions
;		05.09.98   Wepl     AddIntServer/RemIntServer finally fixed
;				    ReadPixel,WritePixel added
;		06.09.98   Wepl     return values after init changed (bootblock)
;				    BltTemplate started (but unfinished)
;		22.09.98   Wepl     _SendIO is now the same as _DoIO (fix for Deuteros)
;  :Copyright.	GPL
;  :Language.	68000 Assembler
;  :Translator.	Asm-One V??, Barfly V2.9, Asm-Pro V1.12, Devpac V??
;---------------------------------------------------------------------------*
; Currently emulated functions:
;	exec.library
;		_LVOAddIntServer	;partial
;		_LVOAddPort		;dummy !
;		_LVOAllocAbs
;		_LVOAllocMem
;		_LVOAllocSignal		;without function
;		_LVOAvailMem
;		_LVOCloseDevice		;dummy
;		_LVODisable
;		_LVODoIO		;some of trackdisk/input
;		_LVOEnable
;		_LVOFindTask		;dummy !
;		_LVOForbid		;dummy
;		_LVOFreeMem
;		_LVOOldOpenLibrary
;		_LVOOpenDevice		;only trackdisk/input !
;		_LVOOpenLibrary
;		_LVOOpenResource
;		_LVOPermit		;dummy
;		_LVORemIntServer
;		_LVORemPort		;dummy
;		_LVOSendIO		;only input !
;		_LVOSuperState		;exact v39
;		_LVOSupervisor
;		_LVOUserState		;exact v39
;	dos.library
;		_LVOClose
;		_LVOLoadSeg
;		_LVOOpen
;		_LVORead
;		_LVOSeek
;		_LVOWrite
;	graphics.library
;		_LVOBltBitMap		;has still some limitations !
;		_LVOBltTemplate		;broken
;		_LVODisownBlitter	;dummy
;		_LVOChangeSprite
;		_LVODraw		;dummy !
;		_LVOFreeSprite
;		_LVOGetSprite
;		_LVOInitBitMap
;		_LVOInitRastPort	;dummy
;		_LVOInitView		;dummy !
;		_LVOInitVPort		;dummy !
;		_LVOLoadView		;sets copperlist
;		_LVOLoadRGB4		;sets colors immediate
;		_LVOMakeVPort		;builds copperlist
;		_LVOMove		;dummy !
;		_LVOMoveSprite
;		_LVOMrgCop
;		_LVOOwnBlitter		;dummy
;		_LVOReadPixel
;		_LVOSetAPen		;dummy
;		_LVOSetDrMd		;dummy
;		_LVOSetRGB4		;sets color immediate
;		_LVOVBeamPos
;		_LVOWaitBlit
;		_LVOWaitTOF
;		_LVOWritePixel
;	intuition.library
;		_LVOCloseWorkbench
;	ciaa.resource,ciab.resource
;		_LVOAddICRVector
;		_LVORemICRVector
;---------------------------------------------------------------------------*
; programs using this stuff:
;	JumpinJackSon, AnotherWorld, Deuteros, North&South, Millenium2·2
;---------------------------------------------------------------------------*
; ToDo:
;	rewriting memory managment for less memory waste
;
;---------------------------------------------------------------------------*
; How to use:
;
;	;load the osemu module
;		lea	(_osemu,pc),a0		;filename of the osemu module
;		lea	($400.w),a1		;the address on which you have
;						;assembled the osemu module
;		move.l	(_resload,pc),a2	;the resload base
;		jsr	(resload_LoadFileDecrunch,a2)	;this allows to
;						;compress the osemu
;	;init the osemu module
;						;system stack has to be on 
;						;top of memory (automatically
;						;done by whdload)
;		move.l	(_resload,pc),a0	;the resload base
;		lea	(_base,pc),a1		;the slave structure
;		jsr	$400
;
;	;start the program
;		move	#0,sr			;if the program uses the os it
;						;should executed in user mode
;
;	;if you want to add a trainer use this, to setup a routine which will
;	;called each time a key is pressed (d0.b contains rawkeycode)
;		lea	(_trainer,pc),a0
;		move.l	a0,($404.w)
;
;---------------------------------------------------------------------------*

	INCLUDE	whoami.i			;this contains only a symbol

	IFD HARRY				;(asm-one)
		INCDIR	ASM-ONE:INCLUDE2.0/
		INCLUDE LIBRARIES/DOS_LIB.I
		INCLUDE	LIBRARIES/DOS.I
		INCLUDE	DEVICES/INPUT.I
		INCLUDE	DEVICES/TRACKDISK.I
		INCLUDE RESOURCES/CIA_LIB.I
		INCLUDE EXEC/EXEC_LIB.I
		INCLUDE	EXEC/MEMORY.I
		INCLUDE	GRAPHICS/GRAPHICS_LIB.I
		INCLUDE	GRAPHICS/GFXBASE.I
		INCLUDE	GRAPHICS/DISPLAYINFO.I
		INCLUDE	GRAPHICS/SPRITE.I
		INCLUDE INTUITION/INTUITION_LIB.I
		INCLUDE INTUITION/INTUITION.I
		INCLUDE	OWN/CCRMAKRO
		INCLUDE	OWN/WHDLOAD.I
		INCDIR	ASM-ONE:OWN/PATCHER/OSEMU/
	org	$400
	load	$100000
	ENDC
	IFD WEPL				;(barfly)
		INCDIR	Includes:
		INCLUDE	devices/input.i
		INCLUDE	devices/inputevent.i
		INCLUDE	devices/trackdisk.i
		INCLUDE	dos/dos.i
		INCLUDE	exec/memory.i
		INCLUDE	graphics/gfx.i
		INCLUDE	graphics/gfxbase.i
		INCLUDE	graphics/rastport.i
		INCLUDE	graphics/sprite.i
		INCLUDE	graphics/view.i
		INCLUDE	lvo/cia.i
		INCLUDE	lvo/dos.i
		INCLUDE	lvo/exec.i
		INCLUDE	lvo/graphics.i
		INCLUDE	lvo/intuition.i
		INCLUDE	whdload.i

		IFD BARFLY
		BOPT	O+ OG+			;enable optimizing
		BOPT	ODd- ODe-		;disable mul optimizing
		BOPT	w4-			;disable 64k warnings
		SUPER				;disable supervisor warnings
		ENDC

		ORG	$400
		OUTPUT	OSEmu.400
		;OUTPUT	wart:a/anotherworld/osemumodule400.bin
		;OUTPUT	wart:d-l/deuteros/OSEmu.400
		;OUTPUT	wart:d-l/jumpingjackson/osemumodule400.bin
		;OUTPUT	wart:m/millennium2·2/OSEmu.400
		;OUTPUT	wart:n-r/north&south/OSEmu.400
	ENDC
	IFD MR.LARMER				;(devpac)
		INCDIR	Include:
		INCLUDE	devices/input.i
		INCLUDE	devices/inputevent.i
		INCLUDE	devices/trackdisk.i
		INCLUDE	dos/dos.i
		INCLUDE	exec/memory.i
		INCLUDE	graphics/gfx.i
		INCLUDE	graphics/gfxbase.i
		INCLUDE	graphics/sprite.i
		INCLUDE	graphics/view.i
		INCLUDE	lvo/cia_lib.i
		INCLUDE	lvo/dos_lib.i
		INCLUDE	lvo/exec_lib.i
		INCLUDE	lvo/graphics_lib.i
		INCLUDE	lvo/intuition_lib.i
		INCLUDE	whdload.i

		OPT	O+ OG+			;enable optimizing
		OPT	P=68020

		ORG	$400
		OUTPUT	OSEmu.400
	ENDC

USPLENGTH=$2000		;reserved area for USP, enlarge if necessary

;---------------------------------------------------------------------------*
**************************************************************************
*   INITIALIZATION CALL                                                  *
**************************************************************************

		bra	_Init
		CNOP 0,4	;essential for correct OSEmu-Structure !

**************************************************************************
*   GLOBAL VARIABLES                                                     *
**************************************************************************

;-------------------------------------------------------------------------
; the following data are part of the OSEmu structure, the offsets of these
; data are guaranteed to remain unchanged for all future versions

SLAVETRAINER	DC.L	0	;OSEmu-Offset = 4
LASTLOADSEG	dc.l	0	;OSEmu-Offset = 8

;-------------------------------------------------------------------------

ALLOCMTABSIZE	DC.L	0
_Slave		dc.l	0
_RESLOAD	dc.l	0
_dosbase	dc.l	0
_gfxbase	dc.l	0
_intbase	dc.l	0
_ciaabase	dc.l	0
_ciabbase	dc.l	0
_sprites	ds.l	8
_inphandler	dc.l	0			;input.device handler
_tags		dc.l	WHDLTAG_ATTNFLAGS_GET
		dc.w	0
_attnflags	dc.w	0
		dc.l	WHDLTAG_ECLOCKFREQ_GET
_eclockfreq	dc.l	0
		dc.l	WHDLTAG_MONITOR_GET
_monitor	dc.l	0
		dc.l	WHDLTAG_CHIPREVBITS_GET
_chiprev	dc.l	0
		dc.l	WHDLTAG_Private3
_p3		dc.l	0
		dc.l	0

_libtable	dc.l	_dosname,DOSINIT
		dc.l	_gfxname,GFXINIT
		dc.l	_intname,INTUIINIT
		dc.l	0
_restable	dc.l	_ciaaname,CIAAINIT
		dc.l	_ciabname,CIABINIT
		dc.l	0

_devtable	DC.L	_tdname,0
		DC.L	_inpname,0
		DC.L	0

_last_joy0dat	dc.w	0

KBDVAL		DC.B	0
_last_lmb	dc.b	0
_last_rmb	dc.b	0

_execname	dc.b	"exec.library",0
_dosname	dc.b	"dos.library",0
_gfxname	dc.b	"graphics.library",0
_intname	dc.b	"intuition.library",0
_ciaaname	dc.b	"ciaa.resource",0
_ciabname	dc.b	"ciab.resource",0
_tdname		dc.b	'trackdisk.device',0
_inpname	dc.b	'input.device',0

**************************************************************************
*   VERSION                                                              *
**************************************************************************

	IFND BARFLY
		DC.B	'$VER: OS_EMUMODULE 0.11 (02-aug-1998 6:00:00)',0
	ELSE
		dc.b	"$VER: OSEmu "
		DOSCMD	"WDate >T:date"
		INCBIN	"T:date"
		dc.b	0
		dc.b	"$Id: osemu.asm 1.8 1998/09/21 23:25:22 jah Exp jah $"
	ENDC
	EVEN

**************************************************************************
*   GLOBAL INITIALIZATION                                                *
**************************************************************************
;REQUIRES NOW AT LEAST WHDLOAD 7.0
;ALTHOUGH THERE IS NO MULTITASKING IMPLEMENTED AT THE MOMENT,
;ALL FUNCTIONS MUST BE IMPLEMENTED REENTRANTLY
;
; IN:	A0 = resload base
;	A1 = pointer to slave structure
; OUT:	-

_Init		movem.l	d0-a0/a2-a5,-(a7)

		cmp.w	#7,(ws_Version,a1)	;minimum version
		blo	_ill
;.xxx	BRA.S	.xxx

		move.l	a0,_RESLOAD
		move.l	a1,(_Slave)

	;init memory managment
		lea	_osemu_end,a0		;FIRST CLEAR WHOLE TABLE (MARK MEM AS USED)
		move.l	(ws_BaseMemSize,a1),d0
		SUBQ.L	#8,D0
		LSR.L	#3,D0			;OK, AMOUNT OF BITS TO CLEAR IS IN D0
		LSR.L	#3,D0			;AMOUNT OF BYTES TO CLEAR IN D0
.1		CLR.B	(A0)+
		SUBQ.L	#1,D0
		BPL.S	.1
		MOVE.L	A0,ALLOCMTABSIZE
		move.l	(ws_BaseMemSize,a1),d0
		SUB.L	A0,D0
		SUB.L	#$1000,D0		;$1000 SYSTEM STACK ON TOP
		MOVE.L	A0,A1			;FREE APPROPRIATE SIZE
		BSR	FREEM

	;allocate stack
		move.l	#USPLENGTH,d0
		moveq	#0,d1
		bsr	ALLOCM
		move.l	d0,a0
		add.l	#USPLENGTH,a0
		move.l	a0,usp
;		add.l	#4096,a0
;		move.l	(15*4,a7),-(a0)		;return address
;		movem.l	(8*4,a7),d0-d6
;		movem.l	d0-d6,-(a0)
;		movem.l	(a7),d0-d7
;		movem.l	d0-d7,-(a0)
;		move.l	a0,a7

	;get whdload vars
		lea	_tags,a0
		move.l	_RESLOAD,a1
		jsr	(resload_Control,a1)

	;init libraries
		bsr	CIAAINIT		;required because int handling
		bsr	CIABINIT		;required because int handling
		bsr	EXECINIT
		bsr	GFXINIT			;required for display init (copper)

	;flush caches
		move.l	(_RESLOAD),a0
		jsr	(resload_FlushCache,a0)

	;prepare return values
		move.l	(4),a6
		move.l	#$400+IOTD_SIZE,d0
		moveq	#0,d1
		jsr	(_LVOAllocMem,a6)
		move.l	d0,a2
		lea	(_tdname),a0
		moveq	#0,d0
		move.l	a2,a1
		moveq	#0,d1
		jsr	(_LVOOpenDevice,a6)
		move.l	a2,a1
		lea	(IOTD_SIZE,a2),a0
		move.l	a0,(IO_DATA,a1)
		move.l	#$400,(IO_LENGTH,a1)
		clr.l	(IO_OFFSET,a1)
		move.w	#CMD_READ,(IO_COMMAND,a1)

		movem.l	(a7)+,d0-a0/a2-a5
		rts

**************************************************************************
*   MISC FUNCTIONS                                                       *
**************************************************************************
;-----------------------------------------------
; IN:	D0 = ULONG size of jmp table
;	D1 = ULONG size of variable area
;	A0 = CPTR  subsystem name
; OUT:	D0 = APTR  librarybase

_InitLibrary	movem.l	d0-d1/a0,-(a7)
		add.l	d1,d0
		moveq	#0,d1
		bsr	ALLOCM
		move.l	d0,a0			;jmp table start
                move.l	d0,a1
		add.l	(a7),a1			;jmp table end
		lea	_LVOFail,a2
.1		move.w	#$4EB9,(A0)+
		move.l	a2,(a0)+
		cmp.l	a0,a1
		bhi	.1
		move.l	(8,a7),(-4,a0)		;name of library
		move.l	a0,d0			;library base
		move.l	a0,a1			;variables start
		add.l	(4,a7),a1		;variables end
.2		move.w	#$eeee,(a0)+
		cmp.l	a0,a1
		bhi	.2
		add.w	#12,a7
		rts
		
_LVOFail	exg.l	d0,a6
		sub.l	d0,(a7)			;LVO
		exg.l	d0,a6
		subq.l	#6,(a7)
		move.l	(-4,a6),-(a7)		;name of library
_emufail	pea	TDREASON_OSEMUFAIL
		move.l	(_RESLOAD,pc),-(a7)
		addq.l	#resload_Abort,(a7)
_rts		rts

;-----------------------------------------------
; IN:	A0 = CPTR  string 1
;	A0 = CPTR  string 2
; OUT:	D0 = LONG  0 if strings are equal

_strcmp		movem.l	a0-a1,-(a7)
.1		cmpm.b	(a0)+,(a1)+
		bne	.not
		tst.b	(-1,a0)
		bne	.1
		move	#0,d0
		movem.l	(a7)+,a0-a1
		rts

.not		moveq	#-1,d0
		movem.l	(a7)+,a0-a1
		rts

;-----------------------------------------------
; wait for vertical blank

_waitvb
.1		btst	#0,(_custom+vposr+1)
		beq	.1
.2		btst	#0,(_custom+vposr+1)
		bne	.2
		rts

_ill		illegal

**************************************************************************
*   EXEC LIBRARY                                                         *
**************************************************************************
**************************************************************************
*   INITIALIZATION                                                       *
**************************************************************************

EXECINIT
	;	move.l	4,d0
	;	btst	#0,d0
	;	bne	.init
	;	rts

.init		move.l	#-_LVOCopyMemQuick,d0
		move.l	#$24c,d1
		lea	_execname,a0
		bsr	_InitLibrary
		move.l	d0,a0
		move.l	a0,$4.W
		
		patch	_LVOOldOpenLibrary(a0),OPENLIB(pc)
		patch	_LVOOpenLibrary(a0),OPENLIB(pc)
		patch	_LVOAllocMem(a0),ALLOCM(PC)
		patch	_LVOFreeMem(a0),FREEM(PC)
		patch	_LVOAvailMem(a0),AVAILM(PC)
		patch	_LVOAllocAbs(a0),ALLOCA(PC)
		patch	_LVOForbid(a0),MYRTS(PC)
		patch	_LVOPermit(a0),MYRTS(PC)
		patch	_LVOAddIntServer(a0),_AddIntServer(PC)
		patch	_LVORemIntServer(a0),_RemIntServer(PC)
	;	patch	_LVOEnqueue(a0),_Enqueue(PC)
		patch	_LVOOpenResource(a0),OPENRES(PC)
		patch	_LVOSupervisor(a0),_Supervisor(PC)
		patch	_LVOSuperState(a0),_SuperState(PC)
		patch	_LVOUserState(a0),_UserState(PC)
		patch	_LVOFindTask(a0),MYRTZ(PC)
		patch	_LVOAddPort(a0),MYRTS(PC)
		patch	_LVOOpenDevice(a0),_OpenDevice(PC)
		patch	_LVODoIO(a0),_DoIO(PC)
		patch	_LVOSendIO(a0),_SendIO(PC)
		patch	_LVOCloseDevice(a0),MYRTS(PC)
		patch	_LVORemPort(a0),MYRTS(PC)

		patch	_LVOAllocSignal(a0),_AllocSignal(PC)
		patch	_LVODisable(a0),_Disable(PC)
		patch	_LVOEnable(a0),_Enable(PC)

		move.w	(_attnflags),(AttnFlags,a0)
	;clear int table
		lea	(IntVects,a0),a1
		moveq	#16*IV_SIZE/4-1,d0
.c1		MOVE.L	#$DDDDDDDD,(a1)+
		dbf	d0,.c1
	;init int table
		LEA.L	(IVPORTS,A0),A1
		MOVE.L	A1,(IV_DATA,a1)
		MOVE.L	#INT_SERVER,(IV_CODE,A1)
		move.l	#INTSERVNODE_CIAA,(IV_NODE,a1)

		LEA.L	(IVVERTB,A0),A1
		MOVE.L	A1,(IV_DATA,a1)
		MOVE.L	#INT_SERVER,(IV_CODE,A1)
		CLR.L	(IV_NODE,a1)

		LEA.L	(IVEXTER,A0),A1
		MOVE.L	A1,(IV_DATA,a1)
		MOVE.L	#INT_SERVER,(IV_CODE,A1)
		move.l	#INTSERVNODE_CIAB,(IV_NODE,a1)

	;init hardware ints
		move.l	#INT_68,$68
		move.l	#INT_6c,$6c
		move.l	#INT_78,$78

		move.b	#$1f,$bfed01
		MOVE.B	#$8F,$BFED01
		tst.B	$BFED01
		move.b	#$1f,$bfdd00
		MOVE.B	#$87,$BFDD00
		tst.b	$bfdd00
		
		move.w	#$7fff,(_custom+intena)
		move.w	#INTF_SETCLR!INTF_INTEN!INTF_EXTER!INTF_VERTB!INTF_PORTS,(_custom+intena)

		rts

MYRTZ		MOVEQ.L	#0,D0
MYRTS		RTS

**************************************************************************
*   MISC EXEC FUCTIONS                                                   *
**************************************************************************

_Supervisor	move.l	$bc,.s1
		move.l	#.c1,$bc
		trap	#15
		rts
.c1		move.l	.s1,$bc
		jmp	(a5)
.s1		dc.l	0

_SuperState	MOVE.L    A5,A0
		LEA       .ac,A5
		JMP       _LVOSupervisor(A6)
.ac		MOVE.L    A0,A5
		MOVEQ     #$00,D0
		BSET      #$05,(A7)
		BNE.S     .ca
		MOVE.W    (A7)+,SR
		MOVE.L    A7,D0
		MOVE.L    USP,A7
		BTST      #$00,$0129(A6)
		BEQ.S     .c6
		ADDQ.L    #$2,D0
.c6		ADDQ.L    #$4,D0
		RTS
.ca		RTE

_UserState	MOVE.L    (A7)+,A0
		MOVE.L    A7,USP
		MOVE.L    D0,A7
		ANDI.W    #$dfff,SR
		JMP       (A0)

**************************************************************************
*   Task related functions                                               *
**************************************************************************

_AllocSignal
		moveq	#1,D0
		rts
_Disable
		move.w	#INTF_INTEN,(_custom+intena)
		rts
_Enable
		move.w	#INTF_SETCLR!INTF_INTEN,(_custom+intena)
		rts

**************************************************************************
*   MEMORYFUNCTIONS                                                      *
**************************************************************************

FREEM
	MOVEM.L	D2/D3/A2/A3,-(A7)
	MOVE.L	A1,D1
;	ADDQ.L	#7,D1
	AND.L	#$FFFFFFF8,D1
	AND.L	#$FFFFFFF8,D0
	BEQ.S	.QU
	LSR.L	#3,D0			;# OF BITS TO CLEAR IN D0

					;FREE MEM NOT ON A $40-BOUNDARY
					;EVAL BEGINBYTE
	MOVE.L	D1,D2
	LSR.L	#6,D2
	LEA.L	ALLOCMTAB(PC),A0
	LEA.L	(A0,D2.L),A0
	MOVEM.L	D1,-(A7)
	AND.L	#$3F,D1
	BEQ.S	.CNTCLR
	LSR.L	#3,D1
.2	BSET	D1,(A0)
	ADDQ.L	#1,D1
	ADDQ.L	#8,(A7)
	SUBQ.L	#1,D0
	BEQ.S	.1
	CMP.L	#8,D1
	BEQ.S	.CNTCLR2
	BRA.S	.2

.1	MOVEM.L	(A7)+,D1
	BRA.S	.QU

.CNTCLR2
	ADDQ.L	#1,A0
.CNTCLR
	MOVEM.L	(A7)+,D1

					;CLEAR $40-BOUNDARY-BYTES
.3	CMP.L	#8,D0
	BLO.S	.CLREND

	ST	(A0)+
	SUBQ.L	#8,D0
	BRA.S	.3


.CLREND					;CLEAR END NOT ENDING ON A $40-
	TST.L	D0			;BOUNDARY
	BEQ.S	.QU
	SUBQ.L	#1,D0
	BSET	D0,(A0)
	BRA.S	.CLREND

.QU	MOVEM.L	(A7)+,D2/D3/A2/A3
	RTS


;>D0:SIZE
;>D1:CONDITIONS
;<D0:ADDY
;LIMITATIONS: 	-NO FAST (WHDLOAD DOESNT SUPPORT IT ANYWAY)
;		-MEM ALWAYS CLEARED (MEMF_CLEAR ASSUMED)
;		-MEMORY IS $40-ALIGNED (SOME BYTES WASTED)
;		-MEMF_PUBLIC IS IGNORED

ALLOCM	MOVEM.L	D2-D5/A2/A3,-(A7)
	MOVE.L	D1,D2
	AND.L	#MEMF_FAST,D2
	BNE.S	.FMEM
	MOVE.L	D1,D2
	AND.L	#MEMF_LARGEST,D2
	BEQ.S	.NORMALCHIP

	BSR.S	AVAILM

.NORMALCHIP
	LSR.L	#3,D0
	;SEARCH SUFFICIENT BIG MEMAREA
	LEA.L	ALLOCMTAB(PC),A0	;FIND A BYTE != 0 (FREE MEM)
	MOVEQ.L	#0,D4
.2
	CMP.B	#$FF,(A0)+
	BEQ.S	.1
	ADD.L	#$40,D4
	CMP.L	ALLOCMTABSIZE(PC),A0
	BNE.S	.2
	BRA.S	.ERR
					;found free mem
					;CHECK NOW SIZE 
.1	SUBQ.L	#1,A0
					;D4-BASE
.3
	MOVE.L	D0,-(A7)		;WANTED SIZE
	MOVE.L	D4,-(A7)		;FOUND ADDRESS

.6	TST.L	D0
	BMI.S	.CHKEND
	CMP.B	#$FF,(A0)
	BNE.S	.TOOSMALL
	ADDQ.L	#1,A0		;CHECK FOR EXCEEDING THE SIZE OF ALLOCMTAB
				;MAY BE OMITTED SINCE ITS END CONTAINS $0
	ADD.L	#$40,D4
	SUBQ.L	#8,D0
	BEQ.S	.CHKEND
	BRA.S	.6

.TOOSMALL				;LATER TODO: FIND EVENTUAL ZEROBITS

	ADDQ.L	#4,A7			;DISCARD D4 ON STACK
	MOVE.L	(A7)+,D0
	ADDQ.L	#1,A0
;	AND.L	#$FFFFFFC0,D4
	ADD.L	#$40,D4
	BRA.S	.2

.CHKEND
	MOVE.L	(A7)+,D4
	MOVE.L	(A7)+,D0
	LSL.L	#3,D0
;D0-SIZE
;D4-ABS
	;MARK AREA AS USED
	MOVE.L	D4,A1
	MOVE.L	D0,D2
	BSR.S	ALLOCA
					;MEMORYSPACE ALREADY SUCESSFULLY
					;CHECKED, RETURNCODE MAY BE IGNORED
	MOVE.L	A1,A2
;	MOVE.L	D4,D2
	LSR.L	#2,D2
	BRA.S	.CLRM

.CLRM1	CLR.L	(A2)+
.CLRM	DBF	D2,.CLRM1
	MOVEM.L	(A7)+,D2-D5/A2/A3
	RTS

.FMEM
.ERR	MOVEQ.L	#0,D0
	MOVEM.L	(A7)+,D2-D5/A2/A3
	RTS

;RETURNS AT THE MOMENT ONLY THE SIZE OF THE LARGEST CHUNK
AVAILM
	MOVEM.L	A2/D2/D3,-(A7)
	MOVE.L	D1,D2
	AND.L	#MEMF_FAST,D2
	BNE.S	.FMEM

	LEA.L	ALLOCMTAB(PC),A0
	MOVEQ.L	#0,D2
	MOVEQ.L	#0,D3
.3	MOVE.B	(A0)+,D0
	CMP.B	#$FF,D0			;SEARCH CHUNK
	BNE.S	.1
	ADD.L	#$40,D3
	BRA.S	.2

.1	CMP.L	D2,D3			;END OF CHUNK, COMPARE SIZE WITH
	BLO.S	.4			;PREVIOUS SIZE
	MOVE.L	D3,D2			;ACTUAL IS LARGER -> NEW LARGEST SIZE
.4	MOVEQ.L	#0,D3			;RESET SIZE OF NEXT CHUNK
.2	CMP.L	ALLOCMTABSIZE(PC),A0	;UNTIL MEMORYTABLE EXCEEDED
	BLO.S	.3
	cmp.l	d2,d3
	blo	.5
	move.l	d3,d2
.5	MOVE.L	D2,D0
	MOVEM.L	(A7)+,A2/D2/D3
	RTS

.FMEM	MOVEQ.L	#0,D0
	MOVEM.L	(A7)+,A2/D2/D3
	RTS


ALLOCA
	MOVEM.L	D2/D3/A2/A3,-(A7)
	;CHECK IF MEM IS FREE
	MOVE.L	A1,D1
;	ADDQ.L	#7,D1
	AND.L	#$FFFFFFF8,D1
	AND.L	#$FFFFFFF8,D0
	BEQ.W	.QU
	MOVEM.L	D0/D1,-(A7)

	LSR.L	#3,D0			;# OF BITS TO CLEAR IN D0

					;CHECK MEM NOT ON A $40-BOUNDARY
					;EVAL BEGINBYTE
	MOVE.L	D1,D2
	LSR.L	#6,D2
	LEA.L	ALLOCMTAB(PC),A0
	LEA.L	(A0,D2.L),A0
	MOVEM.L	D1,-(A7)
	AND.L	#$3F,D1
	BEQ.S	.CNTCHK
	LSR.L	#3,D1
.2	BTST	D1,(A0)
	BEQ.W	.ERR
	ADDQ.L	#1,D1
;	ADDQ.L	#8,(A7)
	SUBQ.L	#1,D0
	BEQ.S	.1
	CMP.L	#8,D1
	BEQ.S	.CNTCHK2
	BRA.S	.2

.1	MOVEM.L	(A7)+,D1
	BRA.S	.CONT

.CNTCHK2
	ADDQ.L	#1,A0
.CNTCHK
	MOVEM.L	(A7)+,D1

					;CLEAR $40-BOUNDARY-BYTES
.3	CMP.L	#8,D0
	BLO.S	.CLREND

	CMP.B	#$FF,(A0)+
	BNE.S	.ERR
	SUBQ.L	#8,D0
	BRA.S	.3


.CLREND
	TST.L	D0
	BEQ.S	.CONT
	SUBQ.L	#1,D0
	BTST	D0,(A0)
	BEQ.S	.ERR
	BRA.S	.CLREND

.CONT	MOVEM.L	(A7)+,D0/D1

					;ALLOC MEM

	LSR.L	#3,D0			;# OF BITS TO CLEAR IN D0

					;MARK MEM NOT ON A $40-BOUNDARY
					;EVAL BEGINBYTE
	MOVE.L	D1,D2
	LSR.L	#6,D2
	LEA.L	ALLOCMTAB(PC),A0
	LEA.L	(A0,D2.L),A0
	MOVEM.L	D1,-(A7)
	AND.L	#$3F,D1
	BEQ.S	.CNTMARK
	LSR.L	#3,D1
.22	BCLR	D1,(A0)
	ADDQ.L	#1,D1
;	ADDQ.L	#8,(A7)
	SUBQ.L	#1,D0
	BEQ.S	.21
	CMP.L	#8,D1
	BEQ.S	.CNTMARK2
	BRA.S	.22

.21	MOVEM.L	(A7)+,D1
	BRA.S	.QU

.CNTMARK2
	ADDQ.L	#1,A0
.CNTMARK
	MOVEM.L	(A7)+,D1

					;CLEAR $40-BOUNDARY-BYTES
.23	CMP.L	#8,D0
	BLO.S	.MARKEND

	SF	(A0)+
	SUBQ.L	#8,D0
	BRA.S	.23


.MARKEND
	TST.L	D0
	BEQ.S	.QU
	SUBQ.L	#1,D0
	BCLR	D0,(A0)
	BRA.S	.MARKEND

.QU

	MOVEM.L	(A7)+,D2/D3/A2/A3
	MOVE.L	D1,D0
	RTS

.ERR	MOVEM.L	(A7)+,D0/D1
.ERR2	MOVEQ.L	#0,D0
	RTS


****************************************************************************
* LIST HANDLING IN EXEC                                                    *
****************************************************************************

	ifeq 1

_Enqueue	;a0=list a1=node
	MOVE.B    (LN_PRI,A1),D1
	MOVE.L    (LN_SUCC,A0),D0
.1908	MOVE.L    D0,A0
	MOVE.L    (LN_SUCC,A0),D0
	BEQ.S     .1914
	CMP.B     (LN_PRI,A0),D1
	BLE.S     .1908
.1914	MOVE.L    (LN_PRED,A0),D0
	MOVE.L    A1,(LN_PRED,A0)
	MOVE.L    A0,(LN_SUCC,A1)
	MOVE.L    D0,(LN_PRED,A1)
	MOVE.L    D0,A0
	MOVE.L    A1,(LN_SUCC,A0)
	RTS

_Remove 	;a1=node
	MOVE.L    (A1)+,A0
	MOVE.L    (A1),A1
	MOVE.L    A0,(A1)
	MOVE.L    A1,$0004(A0)
	RTS

	endc

****************************************************************************
* INTERRUPTPART IN EXEC                                                    *
****************************************************************************

INT_68		movem.l	d0-d1/a0-a1/a5-a6,-(a7)
		move.w	(_custom+intreqr),d0
		and.w	#INTF_PORTS,d0
		beq	.ports_end

	;call handler/server
.ports		PEA	(.ports_cont,PC)
		move.l	(4).W,a1
		MOVE.L	(IVPORTS+IV_CODE,A1),-(A7)
		move.l	(IVPORTS+IV_DATA,a1),a1
		RTS
.ports_cont
.ports_end
		move.w	#INTF_PORTS,(_custom+intreq)
		movem.l	(a7)+,d0-d1/a0-a1/a5-a6
		rte

INTSERVNODE_CIAA
		dc.l	0		;LN_SUCC
		dc.l	0		;LN_PRED
		dc.b	NT_INTERRUPT	;LN_TYPE
		dc.b	120		;LN_PRI
		dc.l	_ciaaname	;LN_NAME
		dc.l	0		;IS_DATA
		dc.l	INT_CIAA	;IS_CODE

;---------------

INT_6c		movem.l	d0-d1/a0-a1/a5-a6,-(a7)
		move.w	(_custom+intreqr),d0
		and.w	#INTF_VERTB,d0
		beq	.vertb_end

.vertb
	;set copperlist
		move.l	(_gfxbase,PC),a0
		move.l	(gb_LOFlist,a0),(_custom+cop2lc)
	;set sprites
		tst.b	(gb_SpriteReserved,a0)
		beq	.ns
		lea	(_sprites),a0
		lea	(_custom+sprpt),a1
		moveq	#7,d0
.ss		move.l	(a0)+,(a1)+
		dbf	d0,.ss
.ns
	;call handler/server
		PEA	(.vertb_cont,PC)
		move.l	(4).W,a1
		MOVE.L	(IVVERTB+IV_CODE,A1),-(A7)
		move.l	(IVVERTB+IV_DATA,a1),a1
		RTS
.vertb_cont
	;input handler
		move.l	(_inphandler),d0
		beq	.vertb_end
		moveq	#$6c,d0
		bsr	_InputHandlerVBI
.vertb_end
		move.w	#INTF_BLIT!INTF_VERTB!INTF_COPER,(_custom+intreq)
		movem.l	(a7)+,d0-d1/a0-a1/a5-a6
		rte

;---------------

INT_78		movem.l	d0-d1/a0-a1/a5-a6,-(a7)
		move.w	(_custom+intreqr),d0
		and.w	#INTF_EXTER,d0
		beq	.exter_end

	;call handler/server
.exter		PEA	(.exter_cont,PC)
		move.l	(4).W,a1
		MOVE.L	(IVEXTER+IV_CODE,A1),-(A7)
		move.l	(IVEXTER+IV_DATA,a1),a1
		RTS
.exter_cont
.exter_end
		move.w	#INTF_EXTER,(_custom+intreq)
		movem.l	(a7)+,d0-d1/a0-a1/a5-a6
		rte

INTSERVNODE_CIAB
		dc.l	0		;LN_SUCC
		dc.l	0		;LN_PRED
		dc.b	NT_INTERRUPT	;LN_TYPE
		dc.b	120		;LN_PRI
		dc.l	_ciabname	;LN_NAME
		dc.l	0		;IS_DATA
		dc.l	INT_CIAB	;IS_CODE

;---------------

INT_SERVER
		move.l	(IV_NODE,a1),-(a7)
.loop		move.l	(a7),d0
		beq	.end
		move.l	d0,a0
		move.l	(LN_SUCC,a0),(a7)
		move.l	(IS_DATA,a0),a1
		move.l	(IS_CODE,a0),a6
		pea	(.loop)
		lea	(_custom),a0	;some require this
		jmp	(a6)
.end		addq.l	#4,a7
		rts

;---------------

_AddIntServer	;d0=intnumber a1=interrupt

		movem.l	a2-a4,-(a7)
		mulu	#IV_SIZE,D0
		lea	(IntVects+IV_NODE,a6,d0.l),a2	;a2 = list base
		move.w	#INTF_INTEN,(_custom+intena)

		move.b	(LN_PRI,a1),d1			;d1 = priority
		sub.l	a3,a3				;a3 = predecessor
		move.l	(a2),a4				;a4 = successor

.next		move.l	a4,d0
		beq	.hangin
		cmp.b	(LN_PRI,a4),d1
		bgt	.hangin
		move.l	a4,a3
		move.l	(LN_SUCC,a3),a4
		bra	.next

.hangin		move.l	a3,(LN_PRED,a1)
		bne	.hi1
		move.l	a2,a3				;LN_SUCC == 0 !...
.hi1		move.l	a1,(LN_SUCC,a3)
		move.l	a4,(LN_SUCC,a1)
		beq	.hi2
		move.l	a1,(LN_PRED,a4)
.hi2
.end		move.w	#INTF_SETCLR!INTF_INTEN,(_custom+intena)
		movem.l	(a7)+,a2-a4
		rts

 ifeq 1
	MOVE.L    D2,-(A7)
	MOVE.L    D0,D2
	MOVE.L    D0,D1
	MULU.W    #IV_SIZE,D0
	LEA       (IntVects,A6,D0.W),A0
	MOVE.L    (A0),A0
	MOVE.W    #INTF_INTEN,(_custom+intena)
	ADDQ.B    #1,(IDNestCnt,A6)
	BSR.W     _Enqueue
	MOVE.W    #-$8000,D0
	BSET      D2,D0
	MOVE.W    D0,(_custom+intena)
	SUBQ.B    #1,(IDNestCnt,A6)
	BGE.S     .1654
	MOVE.W    #INTF_SETCLR!INTF_INTEN,(_custom+intena)
.1654	MOVE.L    (A7)+,D2
	RTS
 endc

_RemIntServer	;d0=intnumber a1=interrupt

	;this is a workaround for Millenium2·2, which does not set D0 correctly
		cmp.l	#$20,d0
		blo	.ok
		moveq	#5,d0
.ok
		movem.l	a2-a4,-(a7)
		mulu	#IV_SIZE,D0
		lea	(IntVects+IV_NODE,a6,d0.l),a2	;a2 = list base
		move.w	#INTF_INTEN,(_custom+intena)

		sub.l	a3,a3				;a3 = predecessor
		move.l	a2,a0
		
.next		move.l	(LN_SUCC,a0),a0
		cmp.l	a0,a1
		beq	.hangout
		move.l	a0,a3
		bra	.next

.hangout	move.l	(LN_SUCC,a1),a4			;a4 = successor
		move.l	a4,d0
		beq	.ho1
		move.l	a3,(LN_PRED,a4)
.ho1		move.l	a3,d0
		bne	.ho2
		move.l	a2,a3				;LN_SUCC == 0 !...
.ho2		move.l	a4,(LN_SUCC,a3)

.end		move.w	#INTF_SETCLR!INTF_INTEN,(_custom+intena)
		movem.l	(a7)+,a2-a4
		rts

**************************************************************************
*   LIBRARY FUNCTIONS                                                    *
**************************************************************************

OPENLIB		move.l	a2,-(a7)

		lea	_libtable,a2
.next		move.l	(a2)+,a0
		move.l	a0,d0
		beq	.err
		bsr	_strcmp
		beq	.found
		addq.l	#4,a2
		bra	.next

.found		move.l	(a2),a0
		jsr	(a0)		;init
		
		move.l	(a7)+,a2
		rts

.err		pea	_LVOOpenLibrary
		pea	_execname
		bra	_emufail

**************************************************************************
*   DEVICE FUNCTIONS                                                     *
**************************************************************************

_OpenDevice	;a0=name d0=unit a1=ioreq d1=flags
		moveM.l	D0/A0-a2,-(a7)

		MOVE.L	A0,A1
		lea	_devtable,a2
.next		move.l	(a2)+,a0
		move.l	a0,d0
		beq	.err
		bsr	_strcmp
		beq	.found
		addq.l	#4,a2
		bra	.next

.err		pea	_LVOOpenDevice
		pea	_execname
		bra	_emufail

.found		MOVE.L	8(A7),A1
		move.l	(a0),(IO_DEVICE,a1)
		move.l	(A7),(IO_UNIT,a1)
		move.b	d1,(IO_FLAGS)
		MOVEM.L	(A7)+,D0/A0-A2
		moveq	#0,d0
		move.b	d0,(IO_ERROR,a1)
		rts

_InputHandlerVBI
	;check LMB
		btst	#CIAB_GAMEPORT0,(_ciaa+ciapra)
		seq	d0
		cmp.b	(_last_lmb),d0
		beq	.lmbend
		move.b	d0,(_last_lmb)
		move.l	(_inphandler),a0
		move.l	(IS_CODE,a0),a1
		move.l	(IS_DATA,a0),a0
		clr.l	(ie_NextEvent,a0)
		move.b	#IECLASS_RAWMOUSE,(ie_Class,a0)
		clr.b	(ie_SubClass,a0)
		move.w	#IECODE_LBUTTON,(ie_Code,a0)
		tst.b	d0
		bne	.lmb1
		or.w	#IECODE_UP_PREFIX,(ie_Code,a0)
.lmb1		moveq	#0,d0
		move.b	(_last_lmb),d1
		beq	.lmb2
		or.w	#IEQUALIFIER_LEFTBUTTON,d0
.lmb2		move.b	(_last_rmb),d1
		beq	.lmb3
		or.w	#IEQUALIFIER_RBUTTON,d0
.lmb3		move.w	d0,(ie_Qualifier,a0)
		jsr	(a1)
.lmbend
	;check RMB
		btst	#POTGOB_DATLY-8,(_custom+potinp)
		seq	d0
		cmp.b	(_last_rmb),d0
		beq	.rmbend
		move.b	d0,(_last_rmb)
		move.l	(_inphandler),a0
		move.l	(IS_CODE,a0),a1
		move.l	(IS_DATA,a0),a0
		clr.l	(ie_NextEvent,a0)
		move.b	#IECLASS_RAWMOUSE,(ie_Class,a0)
		clr.b	(ie_SubClass,a0)
		move.w	#IECODE_RBUTTON,(ie_Code,a0)
		tst.b	d0
		bne	.rmb1
		or.w	#IECODE_UP_PREFIX,(ie_Code,a0)
.rmb1		moveq	#0,d0
		move.b	(_last_lmb),d1
		beq	.rmb2
		or.w	#IEQUALIFIER_LEFTBUTTON,d0
.rmb2		move.b	(_last_rmb),d1
		beq	.rmb3
		or.w	#IEQUALIFIER_RBUTTON,d0
.rmb3		move.w	d0,(ie_Qualifier,a0)
		jsr	(a1)
.rmbend
	;check MouseMove
		move.w	(_custom+joy0dat),d0
		move.w	(_last_joy0dat),d1
		cmp.w	d0,d1
		beq	.rts
		move.w	d0,(_last_joy0dat)
		move.l	(_inphandler),a0
		move.l	(IS_CODE,a0),-(a7)
		move.l	(IS_DATA,a0),a0
		clr.l	(ie_NextEvent,a0)
		move.b	#IECLASS_RAWMOUSE,(ie_Class,a0)
		clr.b	(ie_SubClass,a0)
		move.w	#IECODE_NOBUTTON,(ie_Code,a0)
		clr.w	(ie_Qualifier,a0)
		movem.l	d2-d3,-(a7)
		moveq	#0,d2
		move.b	d1,d2
		moveq	#0,d3
		move.b	d0,d3
		sub.w	d2,d3
		cmp.w	#127,d3
		bgt	.xsub
		cmp.w	#-128,d3
		bge	.xok
		add.w	#512,d3
.xsub		sub.w	#256,d3
.xok		move.w	d3,(ie_X,a0)
		movem.l	(a7)+,d2-d3
		lsr.w	#8,d0
		lsr.w	#8,d1
		sub.w	d1,d0
		cmp.w	#127,d0
		bgt	.ysub
		cmp.w	#-128,d0
		bge	.yok
		add.w	#512,d0
.ysub		sub.w	#256,d0
.yok		move.w	d0,(ie_Y,a0)
.rts		rts

_InputHandlerPI	move.l	(_inphandler),a0
		move.l	(IS_CODE,a0),-(a7)
		move.l	(IS_DATA,a0),a0
		clr.l	(ie_NextEvent,a0)
		move.b	#IECLASS_RAWKEY,(ie_Class,a0)
		clr.b	(ie_SubClass,a0)
		moveq	#0,d0
		move.b	(KBDVAL),d0
		move.w	d0,(ie_Code,a0)
		clr.w	(ie_Qualifier,a0)
		rts

_SendIO
_DoIO		;a1=ioreq
		move.w	(IO_COMMAND,a1),d0		;d0=command
		cmp.l	#"trac",(IO_DEVICE,a1)
		beq	.trackdisk
		cmp.l	#"inpu",(IO_DEVICE,a1)
		beq	.input
		illegal
		
.input		cmp.w	#CMD_RESET,d0
		beq	.ret
		cmp.w	#IND_ADDHANDLER,d0
		beq	.i_addh
		cmp.w	#IND_REMHANDLER,d0
		beq	.i_remh
		cmp.w	#IND_SETMPORT,d0
		beq	.ret
		cmp.w	#IND_SETMTRIG,d0
		beq	.i_setmtrig
		illegal

.i_addh		move.w	(_custom+joy0dat),(_last_joy0dat)
		move.l	(IO_DATA,a1),(_inphandler)
		rts
.i_remh		clr.l	(_inphandler)
		rts
.i_setmtrig	move.l	(IO_DATA,a1),.gpt
		rts
.gpt		dc.l	0

.trackdisk	cmp.w	#CMD_READ,d0
		beq	.td_read
		cmp.w	#CMD_CLEAR,d0
		beq	.ret
		cmp.w	#TD_MOTOR,d0
		beq	.ret
		cmp.w	#TD_FORMAT,d0
		beq	.td_write
		cmp.w	#TD_REMOVE,d0
		beq	.ret
		cmp.w	#TD_CHANGENUM,d0
		beq	.ret
		cmp.w	#TD_CHANGESTATE,d0
		beq	.ret
		cmp.w	#ETD_READ,d0
		beq	.td_read
		cmp.w	#ETD_WRITE,d0
		beq	.td_write
		cmp.w	#ETD_UPDATE,d0
		beq	.ret
		cmp.w	#ETD_CLEAR,d0
		beq	.ret
		cmp.w	#ETD_MOTOR,d0
		beq	.ret
		illegal

	;"deuteros" expects that a1 is unchanged !
.td_read	movem.l	d2/a1,-(a7)
		move.l	(IO_OFFSET,a1),d0
		move.l	(IO_LENGTH,a1),d1
		move.l	(IO_UNIT,a1),d2
		addq.l	#1,d2
		move.l	(IO_DATA,a1),a0
		move.l	(_RESLOAD),a1
		jsr	(resload_DiskLoad,a1)
		movem.l	(a7)+,d2/a1
.ret		clr.b	(IO_ERROR,a1)
		rts

.td_write	tst.l	_p3
		beq	.f
		movem.l	a1-a2,-(a7)
		clr.b	(IO_ERROR,a1)
		move.l	(IO_LENGTH,a1),d0	;size
		lea	(.disk),a0
		move.l	(IO_UNIT,a1),d1
		add.b	#"1",d1
		move.b	d1,(5,a0)		;name
		move.l	(IO_OFFSET,a1),d1	;offset
		move.l	(IO_DATA,a1),a1		;address
		move.l	(_RESLOAD),a2
		jsr	(resload_SaveFileOffset,a2)
		movem.l	(a7)+,a1-a2
		rts
.f		st	(IO_ERROR,a1)
		rts

.disk		dc.b	"Disk.",0,0,0

**************************************************************************
*   RESOURCE FUNCTIONS                                                   *
**************************************************************************

OPENRES		move.l	a2,-(a7)

		lea	_restable,a2
.next		move.l	(a2)+,a0
		move.l	a0,d0
		beq	.err
		bsr	_strcmp
		beq	.found
		addq.l	#4,a2
		bra	.next

.found		move.l	(a2),a0
		jsr	(a0)		;init
		
		move.l	(a7)+,a2
		rts

.err		pea	_LVOOpenResource
		pea	_execname
		bra	_emufail

**************************************************************************
*   CIAA.RESOURCE                                                        *
**************************************************************************

CIAAINIT	move.l	_ciaabase,d0
		beq	.init
		rts

.init		move.l	#-_LVOSetICR,d0
		move.l	#5*4,d1
		lea	_ciaaname,a0
		bsr	_InitLibrary
		move.l	d0,a0
		move.l	d0,_ciaabase

		patch	_LVOAddICRVector(a0),ADDICRV(pc)
		patch	_LVORemICRVector(a0),REMICRV(pc)

		clr.l	(a0)+
		clr.l	(a0)+
		clr.l	(a0)+
		move.l	#INTSERVNODE_SP,(a0)+
		clr.l	(a0)

		MOVE.B	#$FF,$BFE701

		rts

INTSERVNODE_SP	dc.l	0		;LN_SUCC
		dc.l	0		;LN_PRED
		dc.b	NT_INTERRUPT	;LN_TYPE
		dc.b	0		;LN_PRI
		dc.l	0		;LN_NAME
		dc.l	0		;IS_DATA
		dc.l	INT_KBD		;IS_CODE

INT_KBD		MOVE.B	$BFEC01,D0
		NOT.B	D0
		ROR.B	#1,D0
		MOVE.B	#$41,$BFEE01
		MOVEQ.L	#2,D1
.4		MOVE.L	D1,-(A7)
		MOVE.B	$DFF006,D1
.3		CMP.B	$DFF006,D1
		BEQ.S	.3
		MOVE.L	(A7)+,D1
		DBF	D1,.4
		MOVE.B	#$1,$BFEE01
		TST.L	SLAVETRAINER
		BEQ.S	.NOTRAINER
		MOVE.L	SLAVETRAINER(PC),A0
		JSR	(A0)
.NOTRAINER
		MOVE.B	D0,KBDVAL
		BEQ.S	.1
		move.l	(_Slave),a0
		CMP.B	(ws_keyexit,a0),D0
		BEQ.S	.QUIT
.1		move.l	(_inphandler),d0
		bne	_InputHandlerPI
		RTS

.QUIT		PEA	TDREASON_OK
		MOVE.L	_RESLOAD(PC),-(A7)
		add.l	#resload_Abort,(a7)
		rts

ADDICRV		lsl.w	#2,d0
		move.l	(a6,d0.w),d1
		bne	.1
		move.l	a1,(a6,d0.w)
.1		move.l	d1,d0
		rts

REMICRV		lsl.w	#2,d0
		cmp.l	(a6,d0.w),a1
		bne	.1
		clr.l	(a6,d0.w)
.1		rts

INT_CIAA	move.l	_ciaabase,a6
		MOVE.B	$BFED01,D0
INT_CIA
.chk		Bclr	#0,D0
		BNE.S	.ta
		Bclr	#1,D0
		BNE.S	.tb
		Bclr	#2,D0
		BNE.S	.alarm
		Bclr	#3,D0
		BNE.S	.sp
		Bclr	#4,D0
		BNE.S	.flag
		RTS

.ta		MOVE.L	(A6),A0
		BRA.S	.IN
.tb		MOVE.L	(4,A6),A0
		BRA.S	.IN
.alarm		MOVE.L	(8,A6),A0
		BRA.S	.IN
.sp		MOVE.L	(12,A6),A0
		BRA.S	.IN
.flag		MOVE.L	(16,A6),A0

.IN		move.l	a0,d1
		beq	.chk
		MOVE.L	(IS_DATA,A0),A1
		MOVE.L	(IS_CODE,A0),A0
		movem.l	d0/a6,-(a7)
		Jsr	(A0)
		movem.l	(a7)+,d0/a6
		bra	.chk

**************************************************************************
*   CIAB.RESOURCE                                                        *
**************************************************************************

CIABINIT	move.l	_ciabbase,d0
		beq	.init
		rts

.init		move.l	#-_LVOSetICR,d0
		move.l	#5*4,d1
		lea	_ciabname,a0
		bsr	_InitLibrary
		move.l	d0,a0
		move.l	d0,_ciabbase

		patch	_LVOAddICRVector(a0),ADDICRV(pc)
		patch	_LVORemICRVector(a0),REMICRV(pc)
		
		clr.l	(a0)+
		clr.l	(a0)+
		clr.l	(a0)+
		clr.l	(a0)+
		clr.l	(a0)

		MOVE.B	#$FF,$BFD500
		MOVE.B	#$FF,$BFD700

		rts

INT_CIAB	move.l	_ciabbase,a6
		MOVE.B	$BFDD00,D0
		bra	INT_CIA

**************************************************************************
**************************************************************************

	INCLUDE	dos.s
	INCLUDE	graphics.s
	INCLUDE	intuition.s

**************************************************************************
**************************************************************************
*   CHIPMEMORYTABLE AND MEMORY MANAGEMENT DATA                           *
**************************************************************************


;	DS.B	4		;ASM-ONE ALIGNS CNOP 0,8 SOMEWHAT STRANGE
;THIS HAS TO BE ABSOLUTELY THE LAST LABEL, THE TABLE HAS A LEN DEPENDING
;  FROM THE SIZE OF THE MEMORY

	CNOP	0,8
_osemu_end
ALLOCMTAB

