	.186
	.model	small
	.stack
	.code
	assume ds:_text, cs:_text

envseg	label	word
start:	jmp	around

psp_memseg	= 0002h
psp_environ	= 002Ch

OMF_THEADR	= 080h
OMF_COMENT	= 088h
OMF_PUBDEF	= 090h
OMF_LNAMES	= 096h
OMF_SEGDEF	= 098h
OMF_LEDATA	= 0A0h
OMF_FIXUPP	= 09Ch
OMF_MODEND	= 08Ah

WMAXPATH	= 270
MAXIDDSIZE	= 2048

S_OMFR		STRUC
o_type		db	?
o_length	dw	?
o_data		db	1024 dup(?)
o_cksum		db	?
S_OMFR		ENDS

omf	S_OMFR	<?>
fileidd	db WMAXPATH dup(?)
fileobj	db WMAXPATH dup(?)
idname	db 'IDD_'
dlname	db 128 dup(?)
dialog	db MAXIDDSIZE dup(?)
extobj	db '.OBJ',0
option_f db ?

COMENT	db 88h,1Ch,00h,1Ah
	db 'Doszip Resource Edit v2.20',0
COMENT_SIZE = $ - COMENT

LNAMES	db 96h,0Dh,00h,00h
	db 4, 'DATA'
	db 5, '_DATA'
LNAMES_SIZE = $ - LNAMES

_exit:	pop	dx
	push	ax
	mov	ah,9
	int	21h
	pop	ax

terminate:
	mov     ah,4Ch
	int     21h

_abort:
	mov	al,3
	call	_exit
	db	'Abnormal program termination',13,10,'$'

exitusage:
	mov	al,1
	call	_exit
	db	'Syntax: IDDC [options] <idd-file>',13,10
	db	13,10
	db	'/?           *this',13,10
	db	'/F<name>     Full pathname of .OBJ file',13,10

	db	'$'

_psp	dw	0
envlen	dw	0
argv0	dd	0
argc	dw	0
argv	dw	0
	db	13,10

around:	push	offset _abort
	xor	si,si
	mov	dx,ds
	mov  	bp,[si+psp_memseg]
	sub	bp,dx
	mov	bx,[si+psp_environ]
	mov	ax,cs
	mov	ds,ax
	mov	_psp,es
	mov	envseg,bx
	mov	bx,0100h
	mov	ah,4Ah
	int	21h
	mov	ax,envseg
	mov	es,ax
	xor	ax,ax
	mov	argc,ax
	mov	bx,ax
	mov	di,ax
	mov	cx,7FFFh
	cld
    startup_envloop:
	repne	scasb
	inc	bx
	cmp	es:[di],al
	je	startup_envlend
	or	cx,cx
	jnz	startup_envloop
    startup_fail:
	ret
    startup_envlend:
	or	ch,80h
	neg     cx
	mov   	envlen,cx
	mov	ax,envseg
	mov	word ptr argv0+2,ax
	mov	ax,envlen
	inc	ax
	inc	ax
	mov	word ptr argv0,ax
	push	offset terminate
	jmp	main

initargv:
	mov	ax,ds
	mov	es,ax
	mov	cx,80
	mov	di,offset argv + 16
	mov	bx,offset argv
	mov	[bx],di
	lds	si,argv0
    initargv_file:
	lodsb
	or	al,al
	jz	initargv_file_end
	stosb
	dec	cx
	jnz	initargv_file
	dec	di
    initargv_file_end:
	mov	ax,es:_psp
	mov	ds,ax
	xor	ax,ax
	mov	dx,ax
	stosb
	mov	si,80h
	lodsb
	or	al,al
	jz	initargv_end
	add	bx,2
	mov	es:[bx],di
	mov	cx,ax
	inc	si
    initargv_loop:
	lodsb
	or	al,al
	jz	initargv_end
	cmp	al,13
	je	initargv_end
	cmp	al,' '
	je	initargv_add
	stosb
    initargv_next:
	dec	cx
	jnz	initargv_loop
    initargv_end:
	xor	ax,ax
	stosb
	mov	ax,es
	mov	ds,ax
	mov	ax,bx
	sub	ax,offset argv
	shr	ax,1
	mov	argc,ax
	ret
    initargv_add:
	xor	ax,ax
	stosb
	add	bx,2
	mov	es:[bx],di
	jmp	initargv_next

strlen:	push	di
	push	cx
	push	ds
	pop	es
	mov	di,ax
	or	ax,ax
	jz	strlen_00
	xor	ax,ax
	cld
	mov	cx,-1
	repnz	scasb
	mov	ax,cx
	not	ax
	dec	ax
    strlen_00:
	pop	cx
	pop	di
	ret

strcpy:	push	si
	push	di
	push	ds
	pop	es
	mov	di,ax
	mov	si,dx
	mov	dx,ax
	cld
    strcpy_00:
	lodsb
	stosb
	or	al,al
	jnz	strcpy_00
	mov	ax,dx
	pop	di
	pop	si
	ret

strcat:	push	si
	push	di
	push	ds
	pop	es
	cld
	mov	di,ax
	mov	si,dx
	mov	dx,ax
	xor	al,al
	mov	cx,-1
	repne	scasb
	dec	di
    strcat_loop:
	lodsb
	stosb
	or	al,al
	jnz	strcat_loop
	mov	ax,dx
	pop	di
	pop	si
	ret
memzero:
	push	ds
	pop	es
	push	di
	mov	di,ax
	cld
	xor	ax,ax
	rep	stosb
	pop	di
	ret

memcpy:	push	si
	push	di
	mov	di,ax
	mov	si,dx
	push	ds
	pop	es
	cld
	rep	movsb
	pop	di
	pop	si
	ret

initargs:
	mov	cx,argc
	xor	bx,bx
    initargs_loop:
	add	bx,2
	mov	si,[bx+argv]
	lodsb
	cmp	al,'?'
	je	initargs_usage
	cmp	al,'-'
	je	initargs_option
	cmp	al,'/'
	je	initargs_option
	mov	ax,offset fileidd
	mov	dx,si
	dec	dx
	call	strcpy
    initargs_next:
	dec	cx
	jnz	initargs_loop
    initargs_end:
	ret
    initargs_option:
	lodsb
	or	al,20h
	cmp	al,'f'
	je	initargs_f
    initargs_usage:
	jmp	exitusage
    initargs_f: 	; /F<name>	Full pathname of .OBJ file
	inc	option_f
	mov	ax,offset fileobj
	mov	dx,si
	call	strcpy
	jmp	initargs_next

strrchr:
	mov	dh,0

strrcxr:
	push	si
	push	di
	mov	si,ax
	xor	di,di
	cld
    strrchr_lod:
	lodsb
	or	al,al
	jz	strrchr_end
	cmp	al,dh
	je	strrchr_set
	cmp	al,dl
	jne	strrchr_lod
    strrchr_set:
	mov	di,si
	dec	di
	jmp	strrchr_lod
    strrchr_end:
	mov	ax,di
	or	ax,ax
	pop	di
	pop	si
	ret

strfn:	push	ax
	mov	dx,'/\'
	call	strrcxr
	pop	dx
	jz	strfn_01
	inc	ax
    strfn_00:
	ret
    strfn_01:
	mov	ax,dx
	jmp	strfn_00

setext:	push	si
	push	di
	mov	di,dx	; DX: offset ext
	mov	si,ax   ; AX: offset file name
	call	strfn
	mov	dl,'.'
	call	strrchr
	jz	setext_cat
	xchg	ax,di
	mov	BYTE PTR [di],0
	mov	di,ax
    setext_cat:
	mov	ax,si
	mov	dx,di
	call	strcat
	pop	di
	pop	si
	ret

strfcat:
	push	si
	push	di
	mov	di,ax	; dest
	mov	si,cx	; file
	or	dx,dx	; path
	jz	strfcat_00
	call	strcpy
    strfcat_00:
	call	strlen
	or	ax,ax
	mov	dx,di
	jz	strfcat_01
	dec	ax
	add	di,ax
	mov	ax,'\'
	cmp	al,[di]
	je	strfcat_01
	inc	di
	mov	[di],ax
    strfcat_01:
	mov	ax,dx
	mov	dx,si
	call	strcat
	pop	di
	pop	si
	ret

_A_NORMAL	= 00h
A_OPEN	 	= 0001h
A_TRUNC	 	= 0002h
A_CREATE	= 0010h
M_RDONLY	= 0000h
M_WRONLY	= 0001h

_osversion	dw ?
_ifsmgr		dw 0
_maxfile	dw 66
_maxpath	dw 80
_fatsystem	label byte

dosinit:
	push	di
	mov	di,offset _fatsystem
	mov	ah,30h
	int	21h
	mov	_osversion,ax
	mov	bx,argv
	mov	ax,[bx]
	cmp	ah,':'
	jne	dosinit_00
	sub	al,'A'
	jmp	dosinit_01
    dosinit_00:
	mov	ah,19h
	int	21h
    dosinit_01:
	push	ds
	pop	es
	mov	dx,di
	add     al,'A'
	mov	ah,':'
	mov	[di],ax
	mov	ax,'\'
	mov	[di+2],ax
	mov	cx,32
	mov	ax,71A0h
	stc
	int	21h
	jc	dosinit_end
	mov	_maxfile,cx
	mov	_maxpath,dx
	xor	ax,ax
	and	bh,40h
	jz	dosinit_end
	inc	ax
	mov	_ifsmgr,ax
    dosinit_end:
	pop	di
	ret

osopen:
	push	si		; AX name
	push	di		; DX action
	mov	si,ax		; BX mode
	mov	ax,_ifsmgr	; CX attrib
	or	ax,ax
	mov	ax,716Ch
	jnz	ospen_21h
	mov	ax,6C00h	; DOS 4.0+ - EXTENDED OPEN/CREATE
    ospen_21h:
	stc
	int	21h
	pop	di
	pop	si
	ret

getdrv:
	mov	ah,19h
	int	21h
	mov	ah,0
	ret

getcwdd:
	push	si
	mov	si,ax	; dx: drive number (DL, 0 = default)
	mov	ah,47h
	int	21h
	mov	ax,0
	jc	getcwdd_end
	mov	ax,si
    getcwdd_end:
	or	ax,ax
	pop	si
	ret

fullpath:
	push	si
	push	di
	mov	si,ax
	mov	di,dx
	add	ax,3
	call	getcwdd
	or	ax,ax
	jz	fullpath_end
	mov	ax,di
	or	ax,ax
	jz	fullpath_get
	add	al,'@'
	jmp	fullpath_drv
    fullpath_get:
	call	getdrv
	add	al,'A'
    fullpath_drv:
	mov	ah,':'
	mov	[si],ax
	mov	al,'\'
	mov	[si+2],al
	mov	ax,si
    fullpath_end:
	pop	di
	pop	si
	ret

idd_read:
	mov	cx,_A_NORMAL
	mov	bx,M_RDONLY
	mov	dx,A_OPEN
	mov	ax,offset fileidd
	call	osopen
	jc	exit_error_open
	mov	bx,ax
	mov	ah,3Fh
	mov	cx,MAXIDDSIZE
	mov	dx,offset dialog
	int	21h
	jc	exit_error_read
	push	ax
	mov	ah,3Eh
	int	21h
	pop	ax
	or	ax,ax
	ret

exit_error_open:
	mov	al,2
	call	_exit
	db	'File not found: <idd-file>',13,10,'$'
exit_error_read:
	mov	ah,3Eh
	int	21h
	mov	al,2
	call	_exit
	db	'Read error: <idd-file>',13,10,'$'

omf_write:
	push	si
	mov	si,offset omf
	assume	si: ptr S_OMFR
	cld
	xor	dx,dx
	mov	cx,[si.o_length]
	add	cx,2
    omf_chksum:
	lodsb
	add	dx,ax
	dec	cx
	jnz	omf_chksum
	mov	si,offset omf
	dec	dx
	not	dx
	mov	bx,[si.o_length]
	add	bx,2
	mov	[si+bx],dl
	inc	bx
	mov	cx,bx
	mov	bx,di
	mov	ah,40h
	mov	dx,si
	int	21h
	jc	exit_error_write
	pop	si
	assume	si:nothing
	ret
    exit_error_write:
	mov	ah,3Eh
	int	21h
	mov	al,2
	call	_exit
	db	'Write error: <obj-file>',13,10,'$'

obj_save:
	push	si
	push	di
	mov	si,ax
	cmp	ax,1020
	jbe	obj_save_open
	mov	al,2
	call	_exit
	db	'Resource is to big -- > 1024',13,10,'$'
    obj_save_open:
	mov	cx,_A_NORMAL
	mov	bx,M_WRONLY
	mov	dx,A_TRUNC or A_CREATE
	mov	ax,offset fileobj
	call	osopen
	jnc	obj_save_file
	mov	al,2
	call	_exit
	db	'Error create: <obj-file>',13,10,'$'
    obj_save_file:
	mov	di,ax
	mov	ax,offset fileidd
	call	strfn
	mov	dx,ax
	mov	ax,offset omf.o_data + 1
	call	strcpy
	call	strlen
	mov	omf.o_type,OMF_THEADR
	mov	omf.o_data,al
	add	ax,2
	mov	omf.o_length,ax
	call	omf_write
	mov	ax,offset omf
	mov	dx,offset COMENT
	mov	cx,COMENT_SIZE
	call	memcpy
	call	omf_write
	mov	ax,offset omf
	mov	dx,offset LNAMES
	mov	cx,LNAMES_SIZE
	call	memcpy
	call	omf_write
	mov	ax,si
	add	ax,4
	mov	omf.o_type,OMF_SEGDEF
	mov	omf.o_length,7
	mov	omf.o_data,48h
	mov	omf.o_data[1],al
	mov	omf.o_data[2],ah
	mov	omf.o_data[3],3
	mov	omf.o_data[4],2
	mov	omf.o_data[5],1
	mov	omf.o_data[6],0
	call	omf_write
	mov	omf.o_type,OMF_PUBDEF
	mov	omf.o_data[0],0
	mov	omf.o_data[1],1
	mov	dx,offset idname
	mov	ax,offset omf.o_data + 3
	call	strcpy
	call	strlen
	mov	omf.o_data[2],al
	add	ax,7
	mov	omf.o_length,ax
	mov	bx,ax
	mov	ax,si
	mov	omf.o_data[bx-4],al
	mov	omf.o_data[bx-3],ah
	mov	omf.o_data[bx-2],0
	mov	omf.o_data[bx-1],0
	call	omf_write
	mov	omf.o_type,OMF_COMENT
	mov	omf.o_length,4
	mov	omf.o_data,0
	mov	omf.o_data[1],0A2h
	mov	omf.o_data[2],1
	call	omf_write
	mov	ax,offset omf.o_data
	mov	cx,1024
	call	memzero
	mov	ax,si
	add	ax,8
	mov	omf.o_type,OMF_LEDATA
	mov	omf.o_length,ax
	mov	omf.o_data,1
	mov	ax,offset omf.o_data + 3
	mov	dx,offset dialog
	mov	cx,si
	call	memcpy
	call	omf_write
	mov	omf.o_type,OMF_FIXUPP
	mov	omf.o_length,5
	mov	ax,si
	mov	omf.o_data[1],al
	mov	al,0CCh
	or	al,ah
	mov	omf.o_data[0],al
	mov	omf.o_data[2],54h
	mov	omf.o_data[3],1
	mov	omf.o_data[4],0
	call	omf_write
	mov	omf.o_type,OMF_MODEND
	mov	omf.o_length,2
	mov	omf.o_data,0
	call	omf_write
	mov	bx,di
	mov	ah,3Eh
	int	21h
	pop	di
	pop	si
	ret

access:	push	dx
	cmp	_ifsmgr,0
	mov	dx,ax
	mov	ax,4300h
	je	access_21
	mov	ax,7143h
	mov	bl,0
    access_21:
	pop	dx
	jc     	access_error
	cmp	dl,2
	jz	access_error
	xor	ax,ax
    access_end:
	ret
    access_error:
	mov	ax,-1
	ret

main:	call	initargv
	mov	si,ax
	call	dosinit
	or	si,si
	jz	main_initfile
	call	initargs
    main_initfile:
	xor	ax,ax
	cmp	fileidd,al
	jne	main_00
    exit_missing_source:
	mov	al,1
	call	_exit
	db	'Command line: missing <source>',13,10,'$'
    main_00:
	mov	ax,offset fileidd
	call	access
	or	ax,ax
	jnz	exit_missing_source
	mov	ax,offset fileidd
	call	strfn
	mov	dx,ax
	mov	ax,offset dlname
	call	strcpy
	mov	dl,'.'
	call	strrchr
	jz	main_01
	mov	bx,ax
	mov	byte ptr [bx],0
    main_01:
	cmp	option_f,0
	jne	main_02
	mov	ax,offset fileobj
	xor	dx,dx
	call	fullpath
	mov	ax,offset fileidd
	call	strfn
	mov	cx,ax
	mov	ax,offset fileobj
	xor	dx,dx
	call	strfcat
	mov	ax,offset fileobj
	mov	dx,offset extobj
	call	setext
    main_02:
	call	idd_read
	jz	main_error
	call	obj_save
	xor	ax,ax
    main_end:
	ret
    main_error:
	inc	ax
	ret

endcode label byte

	END	start
