[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