;
; COPY32.ASM (c) Rainer Schnitker 92,93
;

;
; copy to or from 32bit segments
;

	.386p

_TEXT segment dword public 'CODE' use16
	assume cs:_TEXT


	;
	; void store32(WORD ds,DWORD offset,DWORD value)
	;
public _store32
_store32 proc near
	; stack: 4 = WORD ds32, 6 = DWORD off32, 10 = DWORD value
	push	bp
	mov	bp,sp
	push	ds
	push	ebx
	push	eax
	mov	ax,word ptr [bp+4]		; get user ds
	mov	ds,ax
	mov	eax,dword ptr [bp+6]		; get user offset
	mov	ebx,dword ptr [bp+10]		; get value
	mov	[eax],ebx
	pop	eax
	pop	ebx
	pop	ds
	leave
	ret
_store32 endp

	;
	; void put_user_byte(WORD ds,DWORD offset,DWORD value)
	;
public _put_user_byte
_put_user_byte proc near
	; stack: 4 = WORD ds32, 6 = DWORD off32, 10 = DWORD value
	push	bp
	mov	bp,sp
	push	ds
	push	ebx
	push	eax
	mov	ax,word ptr [bp+4]		; get user ds
	mov	ds,ax
	mov	eax, dword ptr [bp+6]		; get user offset
	mov	bl, byte ptr [bp+10]		; get value
	mov	[eax], bl
	pop	eax
	pop	ebx
	pop	ds
	leave
	ret
_put_user_byte endp


	;
	; DWORD read32(WORD ds,DWORD offset)
	;
public _read32
_read32 proc near
	; stack: 4 = WORD ds32, 6 = DWORD off32
	push	bp
	mov	bp,sp
	push	ds
	mov	ax,word ptr [bp+4]		; get user ds
	mov	ds,ax
	mov	eax,dword ptr [bp+6]		; get user offset
	mov	edx,[eax]
	movzx	eax,dx				; convert result
	shr	edx,16				; in DX:AX
	pop	ds
	leave
	ret
_read32 endp


	;
	; void bzero32(WORD ds,DWORD offset,DWORD size)
	;
public _bzero32
_bzero32 proc near
	; stack: 4 = WORD ds32, 6 = DWORD off32, 10 = DWORD bytes
	push	bp
	mov	bp,sp
	push	es
	push	esi
	push	edi
	push	ecx

	mov	ax,word ptr [bp+4]		; get user ds
	mov	es,ax
	mov	edi,dword ptr [bp+6]		; get user offset
	mov	ecx,dword ptr [bp+10]		; get size
	xor	eax,eax 			; store 0
	cld

	REP	STOS	BYTE PTR ES:[EDI]

	pop	ecx
	pop	edi
	pop	esi
	pop	es
	leave
	ret
_bzero32 endp


	;
	; void cpy16_32(WORD ds,DWORD off,void *off16,DWORD size)
	;
public _cpy16_32
_cpy16_32 proc near
	; stack: 4 = ds32, 6 = DWORD off32, 10 = p16, 12 = DWORD bytes
	push	bp
	mov	bp,sp
	push	es
	push	esi
	push	edi
	push	ecx

	mov	ax,word ptr [bp+4]		; get user ds
	mov	es,ax				; dest = ES:EDI
	mov	edi,dword ptr [bp+6]		; get user 32bit offset
	movzx	esi, word ptr [bp+10]		; source offset (DS:SI)
	mov	ecx,dword ptr [bp+12]		; get size

	push	ecx
	shr	ecx,2
	cld
	jecxz	@byte_cpy16_32
	REP	MOVS DWORD PTR ES:[EDI], DWORD PTR DS:[ESI]

align 4
@byte_cpy16_32:
	pop	ecx
	and	ecx, dword ptr 3
	jecxz	@end_cpy16_32
	REP	MOVS BYTE PTR ES:[EDI], BYTE PTR DS:[ESI]

align 4
@end_cpy16_32:
	pop	ecx
	pop	edi
	pop	esi
	pop	es
	leave
	ret
_cpy16_32 endp


	;
	; void cpy32_16(WORD ds,DWORD off,WORD ds16,WORD,off16,DWORD size)
	;
public _cpy32_16
	; stack: 4 = WORD ds32, 6 = DWORD off32, 10 = p16, 12 = DWORD bytes
_cpy32_16 proc near
	push	bp
	mov	bp,sp
	push	ds
	push	es
	push	esi
	push	edi
	push	ecx

	mov	ax,ds
	mov	es,ax				; dest segment
	movzx	edi, word ptr [bp+10]		; get dest 16bit offset
	mov	ax,word ptr [bp+4]		; get user ds
	mov	ds,ax				; source = DS:ESI
	mov	esi,dword ptr [bp+6]		; get user 32bit offset
	mov	ecx,[bp+12]			; get size
	cld

	push	ecx
	shr	ecx,2
	jecxz	@byte_cpy32_16
	REP	MOVS DWORD PTR ES:[EDI], DWORD PTR DS:[ESI]

align 4
@byte_cpy32_16:
	pop	ecx
	and	ecx, dword ptr 3
	jecxz	@end_cpy32_16
	REP	MOVS BYTE PTR ES:[EDI], BYTE PTR DS:[ESI]

align 4
@end_cpy32_16:
	pop	ecx
	pop	edi
	pop	esi
	pop	es
	pop	ds
	leave
	ret
_cpy32_16 endp


	;
	; void strcpy16_32(WORD ds,DWORD off,WORD ds16,WORD,off16)
	;
public _strcpy16_32
_strcpy16_32 proc near
	; stack: 4 = WORD ds32, 6 = DWORD off32 , 10=word p16
	push	bp
	mov	bp,sp
	push	es
	push	esi
	push	edi

	mov	ax,word ptr [bp+4]		; get user ds
	mov	es,ax				; dest = ES:EDI
	mov	edi,dword ptr [bp+6]		; get user 32bit offset
	movzx	esi,word ptr [bp+10]		; source offset (DS:SI)
	cld

align 4
@cp16_32:
	LODS	BYTE PTR DS:[ESI]
	STOS	BYTE PTR ES:[EDI]
	or	al,al
	jnz	@cp16_32

	pop	edi
	pop	esi
	pop	es
	leave
	ret
_strcpy16_32 endp


	;
	; void strcpy32_16(WORD ds,DWORD off,WORD ds16,WORD,off16)
	;
public _strcpy32_16
_strcpy32_16 proc near
	; stack: 4 = WORD ds32, 6 = DWORD off32 ,10 = WORD p16
	push	bp
	mov	bp,sp
	push	ds
	push	es
	push	esi
	push	edi

	mov	ax,ds
	mov	es,ax				; dest segment
	movzx	edi, word ptr [bp+10]		; get dest offset
	mov	ax,word ptr [bp+4]		; get user ds
	mov	ds,ax				; source = DS:ESI
	mov	esi,dword ptr [bp+6]		; get user offset
	cld

align 4
@cp32_16:
	LODS	BYTE PTR DS:[ESI]
	STOS	BYTE PTR ES:[EDI]
	or	al,al
	jnz	@cp32_16

	pop	edi
	pop	esi
	pop	es
	pop	ds
	leave
	ret
_strcpy32_16 endp

	;
	; void getstr(WORD ds,DWORD off,WORD ds16,WORD,off16,BYTE c)
	;
public _getstr32_16
_getstr32_16 proc near
	; stack: 4 = WORD ds32, 6 = DWORD off32 ,10 = WORD p16, 12 = BYTE c
	push	bp
	mov	bp,sp
	push	ds
	push	es
	push	esi
	push	edi

	mov	ax,ds
	mov	es,ax				; dest segment
	movzx	edi, word ptr [bp+10]		; get dest offset
	mov	ax,word ptr [bp+4]		; get user ds
	mov	ds,ax				; source = DS:ESI
	mov	esi,dword ptr [bp+6]		; get user offset
	mov	cl, byte ptr [bp+12]		; get delim
	cld

align 4
@get32_16:
	LODS	BYTE PTR DS:[ESI]
	STOS	BYTE PTR ES:[EDI]
	xor	al,cl
	jnz	@get32_16

	pop	edi
	pop	esi
	pop	es
	pop	ds
	leave
	ret
_getstr32_16 endp

	;
	; void cpy32_32(WORD s_ds,DWORD s_off,WORD d_ds,DWORD d_off,DWORD size)
	;
public _cpy32_32
_cpy32_32 proc near
	; stack: 4 = source_ds32, 6 = DWORD source_off32
	;	10 = ds32, 12= DWORD off32, 16= DWORD bytes
	push	bp
	mov	bp,sp
	push	ds
	push	es
	push	esi
	push	edi
	mov	ax,word ptr [bp+4]		; get source dataseg
	mov	ds,ax				; source = DS:ESI
	mov	esi,dword ptr [bp+6]		; get source offset

	mov	ax,word ptr [bp+10]		; get dest dataseg
	mov	es,ax				; dest = ES:EDI
	mov	edi,dword ptr [bp+12]		; get dest offset

	mov	ecx,dword ptr [bp+16]		; get size
	cld

	push	ecx
	shr	ecx,dword ptr 00000002H
	jecxz	@byte_cpy32_32
	REP	MOVS DWORD PTR ES:[EDI], DWORD PTR DS:[ESI]

align 4
@byte_cpy32_32:
	pop	ecx
	and	ecx,dword ptr 00000003H
	jecxz	@end_cpy32_32
	REP	MOVS BYTE PTR ES:[EDI], BYTE PTR DS:[ESI]

align 4
@end_cpy32_32:
	pop	edi
	pop	esi
	pop	es
	pop	ds
	leave
	ret
_cpy32_32 endp


_TEXT ends

      end
