* $Id: dos.s 1.2 1998/07/17 16:35:08 jah Exp $
**************************************************************************
*   DOS-LIBRARY                                                          *
**************************************************************************
**************************************************************************
*   INITIALIZING                                                         *
**************************************************************************

DOSINIT		move.l	_dosbase,d0
		beq	.init
		rts

.init		move.l	#-_LVOExecute,d0
		move.l	#$36,d1
		lea	_dosname,a0
		bsr	_InitLibrary
		move.l	d0,a0
		move.l	d0,_dosbase
		
		patch	_LVOLoadSeg(a0),DOSLOADSEG(pc)
		patch	_LVOOpen(a0),DOSOPEN(PC)
		patch	_LVOClose(a0),DOSCLOSE(PC)
		patch	_LVORead(a0),DOSLOAD(PC)
		patch	_LVOWrite(a0),DOSSAVE(PC)
		patch	_LVOSeek(a0),DOSSEEK(PC)

		rts

**************************************************************************
*   PROGRAM EXECUTION                                                    *
**************************************************************************

;>D1:FILENAME
;<D0:FIRST SEGMENT
;INTERNAL: D7-TOTAL # OF SEGMENTS
;	D6-FILEHANDLE
;	D5-SEGMENTBASE
;	A4-8 BYTES SPACE ON STACK FOR HUNKHEADERS
;LIMITATIONS: ONLY FOLLOWING HUNKS ALLOWED: HUNK_CODE, HUNK_DATA, HUNK_BSS,
;		HUNK_END, HUNK_RELOC32, HUNK_HEADER - CONTACT ME IF YOU
;		HAVE AN EXE WITH OTHER HUNKS, IM SIMPLY MISSING THE
;		EXAMPLES TO IMPLEMENT THEM
;	      DEMANDS OF FASTMEM IGNORED AND CHIPMEM IS USED

DOSLOADSEG
	MOVEM.L	D2-D7/A2-A4,-(A7)
	SUBQ.L	#8,A7
	MOVE.L	A7,A4
	MOVE.L	#MODE_OLDFILE,D2
	BSR.W	DOSOPEN
	TST.L	D0
	BEQ.W	.ERR
	MOVE.L	D0,D6
	MOVE.L	D6,D1
	MOVE.L	A4,D2
	MOVEQ.L	#4,D3
	BSR.W	DOSLOAD
	TST.L	D0
	BEQ.W	.ERR2
	CMP.L	#$3F3,(A4)		;FIRST LW=HUNK_HEADER?
	BNE.W	.ERR2
	MOVE.L	D6,D1
	MOVE.L	A4,D2
	MOVEQ.L	#4,D3
	BSR.W	DOSLOAD
	TST.L	D0
	BEQ.W	.ERR2
	TST.L	(A4)			;NO NAME PLEASE
	BNE.W	.ERR2
	MOVE.L	D6,D1
	MOVE.L	A4,D2
	MOVEQ.L	#4,D3
	BSR.W	DOSLOAD
	TST.L	D0
	BEQ.W	.ERR2
	MOVE.L	(A4),D7			;TOTAL # OF HUNKS
	SUBQ.L	#1,D7	
	MOVE.L	D6,D1
	MOVE.L	A4,D2
	MOVEQ.L	#8,D3
	BSR.W	DOSLOAD
	TST.L	D0
	BEQ.W	.ERR2
	TST.L	(A4)			;FIRST HUNK HAS TO BE 0
	BNE.W	.ERR2
	CMP.L	4(A4),D7		;LAST HUNK HAS TO BE HUNK_COUNT
	BNE.W	.ERR2

	MOVEQ.L	#0,D4			;ALLOC MEM FOR ALL SEGMENTS
	MOVEQ.L	#0,D5
.1	MOVE.L	D6,D1
	MOVE.L	A4,D2
	MOVEQ.L	#4,D3			;GET SIZE OF HUNK
	BSR.W	DOSLOAD
	TST.L	D0
	BEQ.W	.ERR3
	MOVE.L	(A4),D0
	LSL.L	#2,D0
	ADDQ.L	#8,D0
	MOVE.L	D0,D2			;ALLOC MEM IN SIZE
	ADDQ.L	#7,D0
	AND.L	#$FFFFFFF8,D0
	MOVEQ.L	#0,D1
	BSR.W	ALLOCM
	TST.L	D0
	BEQ.W	.ERR3
	MOVE.L	D0,A3
	MOVE.L	D2,(A3)
	CLR.L	4(A3)

	TST.L	D4
	BNE.S	.2
	MOVE.L	D0,D5			;D5-POINTER TO 1ST SEGMENT
	BRA.S	.3

.2
	MOVE.L	D5,A3			;POINTER TO 1ST SEGMENT
.5	TST.L	4(A3)
	BEQ.S	.4
	MOVE.L	4(A3),D2		;NEXT SEGMENT
	LSL.L	#2,D2
	SUBQ.L	#4,D2
	MOVE.L	D2,A3
	BRA.S	.5


.4	ADDQ.L	#4,D0
	LSR.L	#2,D0
	MOVE.L	D0,4(A3)
.3	ADDQ.L	#1,D4
	CMP.L	D7,D4
	BLS.S	.1
					;HEADER COMPLETE, MEM ALLOCATED

			;NOW PROCESSING THE HUNK_CODE, HUNK_DATA AND HUNK_BSS
	MOVEQ.L	#0,D4
.HN	MOVE.L	D6,D1
	MOVE.L	A4,D2
	MOVEQ.L	#4,D3			;GET TYPE OF HUNK
	BSR.W	DOSLOAD
	TST.L	D0
	BEQ.W	.ERR3
	AND.L	#$3FFFFFFF,(A4)
	CMP.L	#$3E9,(A4)		;HUNK_CODE?
	BEQ.S	.HCD
	CMP.L	#$3EA,(A4)		;HUNK_DATA?
	BEQ.S	.HCD
	CMP.L	#$3EB,(A4)		;HUNK_BSS?
	BEQ.S	.HBSS
	BRA.W	.ERR3

.HBSS	
	MOVE.L	D6,D1
	MOVE.L	A4,D2
	MOVEQ.L	#4,D3			;IGNORE SIZE OF HUNK
	BSR.W	DOSLOAD
	TST.L	D0
	BEQ.W	.ERR3
	BRA.S	.HRELOCT

.HCD	MOVE.L	D6,D1
	MOVE.L	A4,D2
	MOVEQ.L	#4,D3			;GET SIZE OF HUNK
	BSR.W	DOSLOAD
	TST.L	D0
	BEQ.W	.ERR3
	MOVE.L	(A4),D3			;LEN OF HUNK
	LSL.L	#2,D3
	MOVE.L	D4,D1			;ACTUAL HUNK
	MOVE.L	D5,A3			;START OF 1ST SEGMENT
	BRA.S	.HCD1

.HCD2	MOVE.L	4(A3),D2
	LSL.L	#2,D2
	SUBQ.L	#4,D2
	MOVE.L	D2,A3
.HCD1	DBF	D1,.HCD2
	MOVE.L	A3,D2
	ADDQ.L	#8,D2
	MOVE.L	D6,D1
	BSR.W	DOSLOAD
	TST.L	D0
	BEQ.W	.ERR3

.HRELOCT
	MOVE.L	D6,D1
	MOVE.L	A4,D2
	MOVEQ.L	#4,D3			;GET TYPE OF HUNK
	BSR.W	DOSLOAD
	TST.L	D0
	BEQ.W	.ERR3
	CMP.L	#$3EC,(A4)		;HUNK_RELOC32?
	BNE.W	.HENDT2
.HRELOCT2
	MOVE.L	D6,D1
	MOVE.L	A4,D2
	MOVEQ.L	#4,D3			;GET COUNT OF LW-RELOCS
	BSR.W	DOSLOAD
	TST.L	D0
	BEQ.W	.ERR3
	TST.L	(A4)			;END OF RELOCATION?
	BEQ.W	.HENDT
	MOVE.L	D6,D1
	MOVE.L	A4,D2
	ADDQ.L	#4,D2
	MOVEQ.L	#4,D3			;GET CORRESPONDING HUNK TO RELOCATE TO
	BSR.W	DOSLOAD
	TST.L	D0
	BEQ.W	.ERR3
	MOVE.L	(A4),D0
	LSL.L	#2,D0			;ALLOC MEM OF SIZE OF RELOCTABLE
	ADDQ.L	#7,D0
	AND.L	#$FFFFFFF8,D0
	MOVEQ.L	#0,D1
	BSR.W	ALLOCM
	TST.L	D0
	BEQ.W	.ERR4
	MOVE.L	D0,A2
	MOVE.L	D6,D1
	MOVE.L	A2,D2
	MOVE.L	(A4),D3			;GET CORRESPONDING RELOCS TO RELOCATE
	LSL.L	#2,D3
	BSR.W	DOSLOAD
	TST.L	D0
	BEQ.S	.ERR4
	MOVE.L	(A4),D3			;# OF RELOCS
	MOVE.L	4(A4),D2		;WHICH HUNK TO RELOCATE TO?
	MOVE.L	D5,A0
	BRA.S	.HRELOCT3

.HRELOCT4
	MOVE.L	4(A0),D0
	LSL.L	#2,D0
	SUBQ.L	#4,D0
	MOVE.L	D0,A0
.HRELOCT3
	DBF	D2,.HRELOCT4		

	ADDQ.L	#8,A0
	MOVE.L	A0,D0			;GOT THE HUNK TO RELOCATE TO
	LEA.L	8(A3),A1		;THIS HUNK WILL BE RELOCATED
	MOVE.L	A2,A0			;HERE ARE THE RELOCS
	BRA.S	.HRELOCT5

.HRELOCT6
	MOVE.L	(A0)+,D1
	ADD.L	D0,(A1,D1.L)
.HRELOCT5
	DBF	D3,.HRELOCT6
	MOVE.L	A2,A1			;FREE THE MEM OF SIZE OF RELOCTABLE
	MOVE.L	(A4),D0
	LSL.L	#2,D0
	ADDQ.L	#7,D0
	AND.L	#$FFFFFFF8,D0
	BSR.W	FREEM
	BRA.W	.HRELOCT2

.HENDT
	MOVE.L	D6,D1
	MOVE.L	A4,D2
	MOVEQ.L	#4,D3			;GET TYPE OF HUNK
	BSR.W	DOSLOAD
	TST.L	D0
	BEQ.S	.ERR3
.HENDT2
	CMP.L	#$3F2,(A4)
	BNE.S	.ERR3
	ADDQ.L	#1,D4
	CMP.L	D7,D4
	BLS.W	.HN

.END	MOVE.L	D6,D1
	BSR.W	DOSCLOSE
	MOVE.L	D5,D0
	ADDQ.L	#4,D0
	MOVE.L	D0,LASTLOADSEG
	ADDQ.L	#8,A7
	MOVEM.L	(A7)+,D2-D7/A2-A4
	RTS
.ERR4
.ERR3
.ERR2	MOVE.L	D6,D1
	BSR.W	DOSCLOSE
.ERR	MOVEQ.L	#0,D0

	ADDQ.L	#8,A7
	MOVEM.L	(A7)+,D2-D7/A2-A4
	RTS


**************************************************************************
*   I/O FILE FUNCTIONS                                                   *
**************************************************************************

;filehandle represents the following structure (do not try to access it!):
;0-allocated len
;4-total filelength
;8-pointer in file
;$c-openmodus
;$10-filename

;open strips the device from the filename (avoiding problems with assigns)
DOSOPEN
	MOVEM.L	D4-D5/A3-A5,-(A7)
	MOVE.L	D1,A3
	MOVEQ.L	#$10,D4			;HEADERLEN
	TST.B	(A3)
	BEQ.S	.ERR
.1	ADDQ.L	#1,D4
	TST.B	(A3)+
	BNE.S	.1
	ADDQ.L	#7,D4			;NEXT $8-BOUNDARY
	AND.L	#$FFFFFFF8,D4
	MOVE.L	D1,D5			;^NAME
	MOVE.L	D4,D0			;ALLOC. LENGTH
	MOVEQ.L	#0,D1
	BSR.W	ALLOCM
	TST.L	D0
	BEQ.S	.ERR
	MOVE.L	D0,A3
	MOVE.L	D4,(A3)			;ALLOC. LENGTH
	MOVE.L	D2,$C(A3)		;OPENMODE
	CLR.L	$8(A3)			;INFILE-POINTER TO 0
	LEA.L	$10(A3),A4		;TRANS FILENAME
	MOVE.L	D5,A5
.2	MOVE.B	(A5)+,(A4)
	BEQ.S	.4
	CMP.B	#':',(A4)
	BNE.S	.3
	LEA.L	$10-1(A3),A4
.3	ADDQ.W	#1,A4
	BRA.S	.2

.4	CMP.W	#MODE_NEWFILE,D2	;IF MODE_NEWFILE, DELETE FILE
	BEQ.S	.NEWFILE
					;CHECK IF FILE EXISTS
	LEA.L	$10(A3),A0		;filename
	move.l	(_RESLOAD,PC),a1
;	MOVE.W	#$80,$DFF096
	jsr	(resload_GetFileSize,a1)
;	MOVE.L	GRABAS+$32(PC),$DFF084
;	MOVE.W	#$8080,$DFF096
	MOVE.L	D0,$4(A3)
	MOVE.L	A3,D0
.END	MOVEM.L	(A7)+,D4-D5/A3-A5
	RTS

.ERR2

.ERR	MOVEQ.L	#0,D0
	BRA.S	.END

.NEWFILE				;REDUCE FILE TO 0 BYTE
	CLR.L	$4(A3)
	LEA.L	$10(A3),A0
	MOVEQ.L	#0,D0
	LEA.L	$0.W,A1
	move.l	(_RESLOAD,pc),a5
;	MOVE.W	#$80,$DFF096
	jsr	(resload_SaveFile,a5)
;	MOVE.L	GRABAS+$32(PC),$DFF084
;	MOVE.W	#$8080,$DFF096
	MOVE.L	A3,D0
	BRA.S	.END

DOSLOAD
	MOVEM.L	D3/A2-A3,-(A7)
	MOVE.L	D1,A3
	MOVE.L	$8(A3),D1		;OFFSET
	MOVE.L	D2,A1			;DEST
	LEA.L	$10(A3),A0		;NAME
	MOVE.L	$4(A3),D0		;TOTAL LENGTH OF FILE
	SUB.L	D1,D0
	EXG	D3,D0
	CMP.L	D0,D3			;CMP REQUESTED/REAL
	BHI.S	.1			;IF REQUESTED<=REAL
	MOVE.L	D3,D0
.1	MOVE.L	D0,D3
					;LOAD IT
	MOVE.L	_RESLOAD(PC),A2
;	MOVE.W	#$80,$DFF096
	JSR	resload_LoadFileOffset(A2)
;	MOVE.L	GRABAS+$32(PC),$DFF084
;	MOVE.W	#$8080,$DFF096
	ADD.L	D3,$8(A3)
	MOVE.L	D3,D0
	MOVEM.L	(A7)+,D3/A2-A3
	RTS


DOSSAVE
	MOVEM.L	D3/A2-A3,-(A7)
	MOVE.L	D1,A3
	MOVE.L	$8(A3),D1		;OFFSET
	MOVE.L	D2,A1			;DEST
	LEA.L	$10(A3),A0		;NAME
	MOVE.L	D3,D0
	MOVE.L	_RESLOAD(PC),A2		;SAVE IT
;	MOVE.W	#$80,$DFF096
	JSR	resload_SaveFileOffset(A2)
;	MOVE.L	GRABAS+$32(PC),$DFF084
;	MOVE.W	#$8080,$DFF096
	ADD.L	D3,$8(A3)
	LEA.L	$10(A3),A0		;filename
	move.l	(_RESLOAD,PC),a1
;	MOVE.W	#$80,$DFF096
	jsr	(resload_GetFileSize,a1)
;	MOVE.L	GRABAS+$32(PC),$DFF084
;	MOVE.W	#$8080,$DFF096
	MOVE.L	D0,$4(A3)
	MOVE.L	D3,D0
	MOVEM.L	(A7)+,D3/A2-A3
	RTS

;free allocated structure

DOSCLOSE
	MOVE.L	D1,A1
	MOVE.L	(A1),D0
	BSR.W	FREEM
	RTS

DOSSEEK
	MOVE.L	D1,A1
	CMP.L	#OFFSET_BEGINNING,D3
	BEQ.S	.BEGM
	CMP.L	#OFFSET_END,D3
	BEQ.S	.ENDM
	CMP.L	#OFFSET_CURRENT,D3
	BEQ.S	.CURM
.ERR	MOVEQ.L	#-1,D0
	RTS

.CURM
	MOVE.L	$8(A1),D0
	MOVE.L	D0,D1
	ADD.L	D2,D1
	CMP.L	$4(A1),D1
	BHI.S	.ERR
	MOVE.L	D1,$8(A1)
	RTS

.ENDM	MOVE.L	$8(A1),D0
	MOVE.L	$4(A1),D1
	ADD.L	D2,D1
	CMP.L	$4(A1),D1
	BHI.S	.ERR
	MOVE.L	D1,$8(A1)
	RTS

.BEGM	MOVE.L	$8(A1),D0
	MOVE.L	D2,D1
	CMP.L	$4(A1),D1
	BHI.S	.ERR
	MOVE.L	D1,$8(A1)
	RTS


