diff --git a/erlang/apps/lib/src/extint.erl b/erlang/apps/lib/src/extint.erl index d73eade..e885cdf 100644 --- a/erlang/apps/lib/src/extint.erl +++ b/erlang/apps/lib/src/extint.erl @@ -1,6 +1,11 @@ %%% -*- erlang-indent-level: 2 -*- %%% -%%% converts between 18 and 36-bit integers and sequences of nonets +%%% Converts between fixed-width integers and sequences of bytes. +%%% 16/32/64-bit integers are sequences of octets, while +%%% 18/36-bit integers are sequences of nonets. +%%% +%%% For now, all conversions are big-endian. +%%% %%% Copyright (C) 2013-2025 Mikael Pettersson %%% %%% This file is part of pdp10-tools. @@ -20,24 +25,56 @@ -module(extint). --export([ uint18_to_ext/1 +-export([ uint16_from_ext/1 + , uint16_to_ext/1 , uint18_from_ext/1 - , uint36_to_ext/1 + , uint18_to_ext/1 + , uint32_from_ext/1 + , uint32_to_ext/1 , uint36_from_ext/1 + , uint36_to_ext/1 + , uint64_from_ext/1 + , uint64_to_ext/1 ]). -include_lib("lib/include/stdint.hrl"). -%% The PDP10 is big-endian, so the conversions here are big-endian. -%% The bytes (nonets) are numbered in storage order. +-spec uint16_from_ext([uint8_t()]) -> uint16_t(). +uint16_from_ext([B0, B1]) -> + ((B0 band ?UINT8_MAX) bsl 8) bor (B1 band ?UINT8_MAX). + +-spec uint16_to_ext(uint16_t()) -> [uint8_t()]. +uint16_to_ext(U16) -> + [_B0 = (U16 bsr 8) band ?UINT8_MAX, _B1 = U16 band ?UINT8_MAX]. + +-spec uint18_from_ext([uint9_t()]) -> uint18_t(). +uint18_from_ext([B0, B1]) -> + ((B0 band ?UINT9_MAX) bsl 9) bor (B1 band ?UINT9_MAX). -spec uint18_to_ext(uint18_t()) -> [uint9_t()]. uint18_to_ext(U18) -> [_B0 = (U18 bsr 9) band ?UINT9_MAX, _B1 = U18 band ?UINT9_MAX]. --spec uint18_from_ext([uint9_t()]) -> uint18_t(). -uint18_from_ext([B0, B1]) -> - ((B0 band ?UINT9_MAX) bsl 9) bor (B1 band ?UINT9_MAX). +-spec uint32_from_ext([uint8_t()]) -> uint32_t(). +uint32_from_ext([B0, B1, B2, B3]) -> + ((B0 band ?UINT8_MAX) bsl 24) bor + ((B1 band ?UINT8_MAX) bsl 16) bor + ((B2 band ?UINT8_MAX) bsl 8) bor + (B3 band ?UINT8_MAX). + +-spec uint32_to_ext(uint32_t()) -> [uint8_t()]. +uint32_to_ext(U32) -> + [_B0 = (U32 bsr 24) band ?UINT8_MAX, + _B1 = (U32 bsr 16) band ?UINT8_MAX, + _B2 = (U32 bsr 8) band ?UINT8_MAX, + _B3 = U32 band ?UINT8_MAX]. + +-spec uint36_from_ext([uint9_t()]) -> uint36_t(). +uint36_from_ext([B0, B1, B2, B3]) -> + ((B0 band ?UINT9_MAX) bsl 27) bor + ((B1 band ?UINT9_MAX) bsl 18) bor + ((B2 band ?UINT9_MAX) bsl 9) bor + (B3 band ?UINT9_MAX). -spec uint36_to_ext(uint36_t()) -> [uint9_t()]. uint36_to_ext(U36) -> @@ -46,9 +83,24 @@ uint36_to_ext(U36) -> _B2 = (U36 bsr 9) band ?UINT9_MAX, _B3 = U36 band ?UINT9_MAX]. --spec uint36_from_ext([uint9_t()]) -> uint36_t(). -uint36_from_ext([B0, B1, B2, B3]) -> - ((B0 band ?UINT9_MAX) bsl 27) bor - ((B1 band ?UINT9_MAX) bsl 18) bor - ((B2 band ?UINT9_MAX) bsl 9) bor - (B3 band ?UINT9_MAX). +-spec uint64_from_ext([uint8_t()]) -> uint64_t(). +uint64_from_ext([B0, B1, B2, B3, B4, B5, B6, B7]) -> + ((B0 band ?UINT8_MAX) bsl 56) bor + ((B1 band ?UINT8_MAX) bsl 48) bor + ((B2 band ?UINT8_MAX) bsl 40) bor + ((B3 band ?UINT8_MAX) bsl 32) bor + ((B4 band ?UINT8_MAX) bsl 24) bor + ((B5 band ?UINT8_MAX) bsl 16) bor + ((B6 band ?UINT8_MAX) bsl 8) bor + (B7 band ?UINT8_MAX). + +-spec uint64_to_ext(uint64_t()) -> [uint8_t()]. +uint64_to_ext(U64) -> + [_B0 = (U64 bsr 56) band ?UINT8_MAX, + _B1 = (U64 bsr 48) band ?UINT8_MAX, + _B2 = (U64 bsr 40) band ?UINT8_MAX, + _B3 = (U64 bsr 32) band ?UINT8_MAX, + _B4 = (U64 bsr 24) band ?UINT8_MAX, + _B5 = (U64 bsr 16) band ?UINT8_MAX, + _B6 = (U64 bsr 8) band ?UINT8_MAX, + _B7 = U64 band ?UINT8_MAX]. diff --git a/erlang/rebar.config b/erlang/rebar.config index b3d5d79..2c873ee 100644 --- a/erlang/rebar.config +++ b/erlang/rebar.config @@ -72,6 +72,12 @@ %% only called from tests , {sim_core, run, 2} %% actual unused exports + , {extint, uint16_from_ext, 1} + , {extint, uint16_to_ext, 1} + , {extint, uint32_from_ext, 1} + , {extint, uint32_to_ext, 1} + , {extint, uint64_from_ext, 1} + , {extint, uint64_to_ext, 1} , {libelf, read_PhTab, 4} , {pdp10_opcodes, cpu_device_from_name, 2} , {pdp10_opcodes, models_from_name, 1}