package hss;

# system constants
$SEEK_SET = 0;
$SEEK_CUR = 1;
$SEEK_LAST = 2;

# hss constants
$vcvaddress = 0x9038000;

# static parameters
$devname = '';
$verbose = 0;

sub init {
	if ($devname eq '') {
		close(DEV);
	}
	$devname = @_[0];
	open(DEV, "+> $devname") || die "cannot open $devname";
}

sub deinit {
	if ($devname ne '') {
		close(DEV);
	}
	$devname = '';
}

sub downloadVCV {
	local($filename) = @_;
	local($size, $buf, $len, $sum);

	open(IN, "< $filename") || die "cannot open $filename";
	seek(IN, 0, $SEEK_LAST);
	$size = tell(IN);
	seek(IN, 0, $SEEK_SET);

	syswrite(DEV, '@1' . pack('CC', 0, 4), 4);
	syswrite(DEV, pack('N', $vcvaddress), 4);
	syswrite(DEV, pack('N', $size / 2), 4);

	$sum = 0;
	while ($len = read(IN, $buf, 1024)) {
		syswrite(DEV, $buf, $len);
		$sum += $len;
		if ($verbose) {
			print STDERR "\r$sum ";
		}
	}
	if ($verbose) {
		print STDERR "\r$sum...done\n"
	}
	close(IN);
}

sub startSH {
	syswrite(DEV, '@3' . pack('CC', 0, 0), 4);
}

sub testStart {
	local($buf);

	read(DEV, $buf, 1);
	if (unpack('C', $buf) == 0x81) {
		return 0;	# fine
	}

	syswrite(DEV, '$', 1);

	read(DEV, $buf, 1);
	if (unpack('C', $buf) == 0x81) {
		return 0;	# fine
	}

	return -1;	# strange
}

sub kisoku {
	local($text) = @_;
	local($buf, $len0, $len);

	$len0 = $len = length($text);
	if (94 < $len0) {
		return -1;	# too long
	}

	if ($len0 % 2) {
		$len++;
		$text .= "\0";
	}

	syswrite(DEV, '@6', 2);
	syswrite(DEV, pack('n', (2 + $len) / 2), 2);
	syswrite(DEV, pack('n', $len0), 2);
	syswrite(DEV, $text, $len);

	if (read(DEV, $buf, 1) != 1) {
		return -1;	# strange
	}
	if (unpack('C', $buf) == 0x82) {
		return -1;	# min value
	}
	if (unpack('C', $buf) == 0x83) {
		return -1;	# max value
	}
	return 0;
}

sub kisokuStop {
	syswrite(DEV, '$', 1);
}

sub reset {
	&kisoku("S4P4U0V32X0\n");
}

1;
