%	.model	model,C

	.const

atoe_table	db	000h, 001h, 002h, 003h, 037h, 02dh, 02eh, 02fh
		db	016h, 005h, 025h, 00bh, 00ch, 00dh, 00eh, 00fh
		db	010h, 011h, 012h, 013h, 03ch, 03dh, 032h, 026h
		db	018h, 019h, 03fh, 027h, 01ch, 01dh, 01eh, 01fh
		db	040h, 05ah, 07fh, 07bh, 05bh, 06ch, 050h, 07dh
		db	04dh, 05dh, 05ch, 04eh, 06bh, 060h, 04bh, 061h
		db	0f0h, 0f1h, 0f2h, 0f3h, 0f4h, 0f5h, 0f6h, 0f7h
		db	0f8h, 0f9h, 07ah, 05eh, 04ch, 07eh, 06eh, 06fh
		db	07ch, 0c1h, 0c2h, 0c3h, 0c4h, 0c5h, 0c6h, 0c7h
		db	0c8h, 0c9h, 0d1h, 0d2h, 0d3h, 0d4h, 0d5h, 0d6h
		db	0d7h, 0d8h, 0d9h, 0e2h, 0e3h, 0e4h, 0e5h, 0e6h
		db	0e7h, 0e8h, 0e9h, 0adh, 0e0h, 0bdh, 05fh, 06dh
		db	079h, 081h, 082h, 083h, 084h, 085h, 086h, 087h
		db	088h, 089h, 091h, 092h, 093h, 094h, 095h, 096h
		db	097h, 098h, 099h, 0a2h, 0a3h, 0a4h, 0a5h, 0a6h
		db	0a7h, 0a8h, 0a9h, 0c0h, 04fh, 0d0h, 0a1h, 007h
		db	020h, 021h, 022h, 023h, 024h, 02ah, 006h, 017h
		db	028h, 029h, 015h, 02bh, 02ch, 009h, 00ah, 01bh
		db	030h, 031h, 01ah, 033h, 034h, 035h, 036h, 008h
		db	038h, 039h, 03ah, 03bh, 004h, 014h, 03eh, 0e1h
		db	041h, 042h, 043h, 044h, 045h, 046h, 047h, 048h
		db	049h, 051h, 052h, 053h, 054h, 055h, 056h, 057h
		db	058h, 059h, 062h, 063h, 064h, 065h, 066h, 067h
		db	068h, 069h, 070h, 071h, 072h, 073h, 074h, 075h
		db	076h, 077h, 078h, 080h, 08ah, 08bh, 08ch, 08dh
		db	08eh, 08fh, 090h, 09ah, 09bh, 09ch, 09dh, 09eh
		db	09fh, 0a0h, 0aah, 0abh, 0ach, 0bbh, 0aeh, 0afh
		db	0b0h, 0b1h, 0b2h, 0b3h, 0b4h, 0b5h, 0b6h, 0b7h
		db	0b8h, 0b9h, 0bah, 04ah, 0bch, 0fch, 0beh, 0bfh
		db	0cah, 0cbh, 0cch, 0cdh, 0ceh, 0cfh, 0dah, 0dbh
		db	0dch, 0ddh, 0deh, 0dfh, 0eah, 0ebh, 0ech, 0edh
		db	0eeh, 0efh, 0fah, 0fbh, 06ah, 0fdh, 0feh, 0ffh

	.code

atoe	proc	uses es di, s:ptr
	cld
	if @DataSize			; far data
	les	di,s
	else				; near data
	mov	di,s
	endif

	mov	bx,offset @data:atoe_table

@@:
	mov	al,byte ptr es:[di]	; get next character
	or	al,al			; End-of-string found?
	jz	@F
	xlat
	stosb
	jmp	@B

@@:
	ret
atoe	endp


	.data

temp_string	dw	256 dup (?)

	.code

chksum	proc	uses ds es si di, in_str:ptr, oldsum:word
	cld
	mov	ax,ds
	mov	es,ax
	mov	di,offset @data:temp_string
	push	di
	mov	cx,256/2
	xor	ax,ax
	rep	stosw
	pop	di

	if @DataSize
	lds	si,in_str
	else
	mov	si,in_str
	endif

@@:
	lodsb
	or	al,al
	jz	chksum_no_string
	cmp	al,' '
	je	@B

@@:
	stosb
	lodsb
	or	al,al
	jz	@F
	jmp	@B

@@:
	std
	dec	di
	sub	si,2
@@:
	lodsb
	cmp	al,' '
	jnz	chksum_start
	xor	al,al
	stosb
	jmp	@B

chksum_start:
	cld
	mov	ax,es			; ES holds old DS (definitely)
	mov	ds,ax			; put it back
	mov	si,offset @data:temp_string

	if @DataSize
	push	ds
	endif
	push	si
	call	atoe
	if @DataSize
	add	sp,4
	else
	add	sp,2
	endif

	xor	dx,dx			; this holds the current sum

@@:
	lodsb
	xchg	ah,al
	lodsb
	mov	bl,al
	mov	cl,dl
	and	cl,00fh
	rol	ax,cl
	xor	dx,ax
	or	bl,bl
	jz	@F
	mov	bl,[si]
	or	bl,bl
	jz	@F
	jmp	@B

@@:
	mov	ax,oldsum
	xor	dx,ax
	mov	ax,dx
	ret

chksum_no_string:
	mov	ax,oldsum
	ret
chksum	endp

	end
