[mercury-users] Native garbage collector for Mercury

Andrew Bromage bromage at cs.mu.OZ.AU
Mon Sep 14 11:20:51 AEST 1998


G'day all.

Thomas Charles CONWAY wrote:

> All in all, I think the most difficult problem in writing an OS in Mercury
> will be finding the labour - I think we have (most of) the wherewithall
> to do the job.

Don't forget we would also need spare hardware.  (Hint hint.)

Well, here's my contribution.  Note: This needs a slight modification
of Tom's io_port module.  In practice you want a slightly higher-level
of locking than that module gives you (as seen below).

Cheers,
Andrew Bromage

%----------------------------------------------------------------------------%
%----------------------------------------------------------------------------%

:- module eth3c590.

:- interface.
:- import_module io.

% Code to read the ethernet address from the 3Com 3c590 family of
% network cards.

:- type eth3c590
	--->	eth3c590(
			word,		% Port
			lock		% Device lock
		).

:- pred eth3c590:address(eth5c590 :: in, list(int) :: out,
		io__state :: in, io__state :: out) is det.

%----------------------------------------------------------------------------%
%----------------------------------------------------------------------------%

:- implementation.
:- import_module io_port.

%----------------------------------------------------------------------------%

	% Command register (write only, all windows)
:- func command = int.
command = 0x0e.

:- func command_full_reset = short.
command_full_reset = 0.

:- func command_window_select = short.
command_window_select = (1<<11).

%----------------------------------------------------------------------------%

	% Status register (read only, all windows)
:- func status = int.
status = 0x0e.

:- func status_cmd_in_process = short.
status_cmd_in_process = 0x1000.

%----------------------------------------------------------------------------%

	% Set the register window.
:- pred set_window(word :: in, byte :: in,
		io__state :: di, io__state :: uo) is det.
set_window(BasePort, Window) -->
	io_port:write(BasePort + command, command_window_select | Window).

	% Wait for the card to finish its current command.
:- pred busy_wait(word :: in, io__state :: di, io__state :: uo) is det.
busy_wait(BasePort) -->
	io_port:read_short(BasePort + status, Status),
	( { Status & status_cmd_in_process \= 0 } ->
		busy_wait(BasePort)
	;
		[]
	).

%----------------------------------------------------------------------------%

	/* XXX Need to add the other windows in a full driver. */

	% Window 2 registers: Station address setup/read.
:- func w2_addr_0 = int.
w2_addr_0 = 0.

:- func w2_addr_1 = int.
w2_addr_1 = 1.

:- func w2_addr_2 = int.
w2_addr_2 = 2.

:- func w2_addr_3 = int.
w2_addr_3 = 3.

:- func w2_addr_4 = int.
w2_addr_4 = 4.

:- func w2_addr_5 = int.
w2_addr_5 = 5.

%----------------------------------------------------------------------------%

address(eth3c590(BasePort, Lock), [A0,A1,A2,A3,A4,A5]) -->
	lock(Lock),
	busy_wait(BasePort),
	set_window(2),
	io_port:read_byte(BasePort + w2_addr_0, A0),
	io_port:read_byte(BasePort + w2_addr_1, A1),
	io_port:read_byte(BasePort + w2_addr_2, A2),
	io_port:read_byte(BasePort + w2_addr_3, A3),
	io_port:read_byte(BasePort + w2_addr_4, A4),
	io_port:read_byte(BasePort + w2_addr_5, A5),
	unlock(Lock).

%----------------------------------------------------------------------------%
%----------------------------------------------------------------------------%



More information about the users mailing list