This commit is contained in:
John Bintz 2024-02-24 11:42:04 -05:00
parent ff2ca6969d
commit 36b696bc45
9 changed files with 350 additions and 225 deletions

3
.gitignore vendored
View File

@ -10,3 +10,6 @@ src/BSDSocket_Size.s
src/bsdsocket_lib.fd
src/bsdsocket_lvo.i
src/*.Lib
.vamosrc
activate
test/

8
API.md
View File

@ -260,6 +260,14 @@ not cleared on a successful command!
Error number from last call. Look in <sys/error.h> for more
details.
#### RESULT=Socket Herrno
Get the error from the last DNS resolver command.
##### Returns
Resolver error number (`h_errno`) from last call.
#### RESULT$=Dns Get Address By Name$(Domain Name$)
Look up the first IP address associated with this hostname.

View File

@ -161,7 +161,7 @@ This project uses semantic versioning.
## License
Copyright 2023 John Bintz. Licensed under the MIT License.
Copyright 2023-2024 John Bintz. Licensed under the MIT License.
If you use this in your project, and you really want to,
throw a link to theindustriousrabbit.com somewhere! You can
@ -184,6 +184,12 @@ to contact me.
* Fix bug in Socket Wait Async Writing where result of getsockopt was
incorrectly used.
### 1.1.0 (2024-02-23)
* Fix bug in Dns Get Host Address By Name$ where it assumed AMOS strings are
null-terminated. They are not.
* Add Socket Herrno to aid in debugging resolver errors.
## Development
### Environment
@ -191,17 +197,22 @@ to contact me.
#### Native Amiga
* Clone the [AMOS Professional source code](https://github.com/AOZ-Studio/AMOS-Professional-Official)
* Copy `extensions/Intuition-41.95/AMOS/LEqu.s` to `+LEqu.s`
* Copy `AMOSPro Sources/+lequ.s` to `+LEqu.s`
* Generate the socket LVO file in the `src` directory
* Download `https://raw.githubusercontent.com/cnvogelg/amitools/master/amitools/data/fd/bsdsocket_lib.fd` to `src`
* `fd2pragma bsdsocket_lib.fd to "" special 20`
* Fix up `absdsocket` to match your system's setup
* Run `execute absdsocket`
* Note that you'll probably have to fix up some assigns.
#### Emulated setup (WinUAE, FS-UAE, Amiberry)
Run `bin/setup` to do most of the setups above.
### Debugging
Modify data in the `DebugArea` and read it by `Peek`/`Deek`/`Leek`ing from
the base address provided by `Socket Get Debug Area`.
### Releasing
#### Ubuntu/Debian

View File

@ -9,7 +9,7 @@ fi
if [ ! -f src/bsdsocket_lib.fd ]; then
cd src
wgethttps://raw.githubusercontent.com/cnvogelg/amitools/master/amitools/data/fd/bsdsocket_lib.fd
wget https://raw.githubusercontent.com/cnvogelg/amitools/master/amitools/data/fd/bsdsocket_lib.fd
cd ..
fi

42
src/AMOSMacros.s Normal file
View File

@ -0,0 +1,42 @@
; get the effective address of something in extension memory
Dlea MACRO
MOVE.L ExtAdr+ExtNb*16(A5),\2
ADD.W #\1-MB,\2
ENDM
; load the base of extension memory into a register
Dload MACRO
MOVE.L ExtAdr+ExtNb*16(A5),\1
ENDM
; wrap code that doesn't take arguments with these
PreserveStackInstruction MACRO
MOVEM.L A2-A6/D6-D7,-(SP)
ENDM
RestoreStackInstruction MACRO
MOVEM.L (SP)+,A2-A6/D6-D7
ENDM
; wrap code that takes arguments with these
PreserveStackFunction MACRO
MOVEM.L A2/A4-A6/D6-D7,-(SP)
ENDM
RestoreStackFunction MACRO
MOVEM.L (SP)+,A2/A4-A6/D6-D7
ENDM
; Push and pop the extension's data storage into A3
WithDataStorageToA3 MACRO
MOVE.L A3,-(SP)
Dload A3
ENDM
EndDataStorage MACRO
MOVE.L (SP)+,A3
ENDM
EvenOutStringAddress MACRO
MOVE.W \1,\2
AND.W #$0001,\2
ADD.W \2,\1
ENDM

View File

@ -1,5 +1,5 @@
; BSDSocket Extension for AMOS Professional
; Copyright 2023 John Bintz
; Copyright 2023-2024 John Bintz
; Licensed under the MIT License
;
; Writing this code the right way, 25 years later.
@ -7,7 +7,7 @@
; extension number 18
ExtNb equ 18-1
Version MACRO
dc.b "1.0.1-20230403"
dc.b "1.1.0-20240223"
ENDM
VerNumber equ $1
@ -22,176 +22,23 @@ VerNumber equ $1
Include "+AMOS_Includes.s"
Include "bsdsocket_lvo.i"
; get the effective address of something in extension memory
Dlea MACRO
MOVE.L ExtAdr+ExtNb*16(A5),\2
ADD.W #\1-MB,\2
ENDM
Include "LongDivide.s"
Include "Constants.s"
Include "fd_set.s"
Include "AMOSMacros.s"
; load the base of extension memory into a register
Dload MACRO
MOVE.L ExtAdr+ExtNb*16(A5),\1
ENDM
; call an AmigaOS function via LVO(A6)
CALLLIB MACRO
JSR _LVO\1(A6)
ENDM
; bsdsocket library stuff
; ported from the various C include headers
SOCK_STREAM EQU 1
PF_INET EQU 2
AF_INET EQU PF_INET
IPPROTO_TCP EQU 6
INADDR_ANY EQU 0
FIONBIO EQU $8004667E
FIONASYNC EQU $8004667D
SOL_SOCKET EQU $FFFF
SO_REUSEADDR EQU $4
MAX_SOCKETS EQU 64
len_sockaddr_in EQU 16
sockaddr_in_sin_len EQU 0
sockaddr_in_sin_family EQU 1
sockaddr_in_sin_port EQU 2
sockaddr_in_sin_addr EQU 4
; global errors
Error_OtherError EQU -1
Error_LibraryNotOpen EQU -2
Error_PortOutOfRange EQU -11
Error_FdsetOutOfRange EQU -11
Error_UnableToBind EQU -12
; wrap code that doesn't take arguments with these
PreserveStackInstruction MACRO
MOVEM.L A2-A6/D6-D7,-(SP)
ENDM
RestoreStackInstruction MACRO
MOVEM.L (SP)+,A2-A6/D6-D7
ENDM
; wrap code that takes arguments with these
PreserveStackFunction MACRO
MOVEM.L A2/A4-A6/D6-D7,-(SP)
ENDM
RestoreStackFunction MACRO
MOVEM.L (SP)+,A2/A4-A6/D6-D7
ENDM
LoadBSDSocketBase MACRO
; get the BSDSocket library ready for CALLLIB
LoadBSDSocketBaseFromA3 MACRO
MOVE.L BSDSocketBase-MB(A3),A6
ENDM
WithDataStorage MACRO
MOVE.L A3,-(SP)
Dload A3
ENDM
EndDataStorage MACRO
MOVE.L (SP)+,A3
ENDM
; fdset macros
EnsureValidFdset MACRO
CMP.L #MaxFd_sets,\1
BLT \2
MOVE.L #Error_FdsetOutOfRange,D3
RestoreStackFunction
Ret_Int
ENDM
EnsureValidFdsetBit MACRO
CMP.L #64,\1
BGE _EnsureValidFdsetBit_Fail\@
BRA \2
_EnsureValidFdsetBit_Fail\@:
MOVE.L \3,D3
RestoreStackFunction
Ret_Int
ENDM
LeaFdset MACRO
MOVE.L \1,-(SP)
Dlea fd_sets,\2 ; base of all, these are longs
ROL.L #3,\1 ; multiply by 8
ADD.L \1,\2 ; add to base of all
MOVE.L (SP)+,\1
ENDM
; LeaFdsetForBit fd_set reg,target address,target bit in address
LeaFdsetForBit MACRO
LeaFdset \1,\2 ; get fdset base address in \2
MOVE.L D3,-(SP)
MOVE.L \3,D3 ; Put target bit into D3
ROR.L #5,D3 ; lop off the first 5 bits
AND.L #$7,D3 ; only keep the top three
ROL.L #2,D3 ; multiply by 4
ADD.L D3,\2 ; add that value to the fdset address
AND.L #$1F,\3 ; only keep 0-31 in \3
MOVEQ #1,D3
ROL.L \3,D3 ; shift that bit left as many as target
MOVE.L D3,\3 ; put that in the target
MOVE.L (SP)+,D3
ENDM
; d0 = value to be divided
; d1 = divisor
; returns:
; d0 = divided value
; d1 = remainder
LongDivideD0ByD1 MACRO
CMP.L D0,D1
BMI _LongDivide_StartDivide\@
MOVE.L D0,D1
MOVEQ #0,D0
BRA _LongDivide_Skip\@
_LongDivide_StartDivide\@:
MOVEM.L D2-D4,-(SP)
MOVEQ #0,D2 ; remainder
MOVE.L #31,D3 ; bit tracking
; d4 tracks the status register
_LongDivide_ContinueDivide\@:
ASL.L #1,D0
SCS D4 ; bit that got rolled out
AND.L #1,D4
ROL.L #1,D2
ADD.L D4,D2 ; roll the value onto the remainder
MOVE.L D2,D4
SUB.L D1,D4
BMI _LongDivide_NotDivisible\@
ADDQ #1,D0
MOVE.L D4,D2
_LongDivide_NotDivisible\@:
DBRA D3,_LongDivide_ContinueDivide\@
MOVE.L D2,D1
MOVEM.L (SP)+,D2-D4
_LongDivide_Skip\@:
ENDM
EvenOutStringAddress MACRO
MOVE.W \1,\2
AND.W #$0001,\2
ADD.W \2,\1
ENDM
; check if we've opened the bsd socket library
; we do this a lot, this could probably become something
; we jsr to...
@ -330,6 +177,9 @@ C_Tk dc.w 1,0
AddTokenFunction SocketCloseSocket
dc.b "socket close socke","t"+$80,"00",-1
AddTokenFunction SocketHerrno
dc.b "socket herrn","o"+$80,"0",-1
; TOKEN_END
dc.w 0
dc.l 0 ; Important!
@ -386,6 +236,8 @@ getsockopt_len ds.l 1
MaxSocketSeen dc.w 0
sockaddr_ram ds.l 1
; also used for errno tags
AcceptScratchArea ds.b 16
SelectScratchArea ds.l 2
@ -438,16 +290,16 @@ End
CALLLIB OpenLibrary
MOVE.L D0,BSDSocketBase-MB(A3)
BEQ _SocketLibraryOpen_Finish
BEQ .Finish
; reserve ram for sockaddr_ins
MOVE.L #MAX_SOCKETS*len_sockaddr_in,D0
Rjsr L_RamFast
BEQ _SocketLibraryOpen_Finish
BEQ .Finish
MOVE.L D0,sockaddr_ram-MB(A3)
_SocketLibraryOpen_Finish:
.Finish:
MOVE.L BSDSocketBase-MB(A3),D3
RestoreStackInstruction
@ -541,7 +393,7 @@ _ToSockaddr_KeepCheckingString_2:
_ToSockaddr_ParseIPAddress:
Dload A3
LoadBSDSocketBase
LoadBSDSocketBaseFromA3
CALLLIB inet_addr
_ToSockaddr_DoneParsing:
@ -577,7 +429,7 @@ _SocketCreateInetSocket_LibraryOpen:
MOVE.L #SOCK_STREAM,D1
MOVE.L #IPPROTO_TCP,D2
Dload A3
LoadBSDSocketBase
LoadBSDSocketBaseFromA3
CALLLIB socket
MOVE.L D0,D3
@ -650,7 +502,7 @@ _SocketConnect_SockaddrIn:
; socket id is in D0
; sockaddr_in is in A0
MOVE.L #len_sockaddr_in,D1 ; len
LoadBSDSocketBase
LoadBSDSocketBaseFromA3
CALLLIB connect
MOVEM.L (SP)+,A0/A3
@ -686,8 +538,8 @@ _SocketConnect_SockaddrIn:
_SocketSendString_LibraryOpen:
MOVEQ #0,D2 ; flags
WithDataStorage
LoadBSDSocketBase
WithDataStorageToA3
LoadBSDSocketBaseFromA3
CALLLIB send
EndDataStorage
@ -732,8 +584,8 @@ _SocketSendData_LibraryOpen:
_SocketSendData_NotNegative:
MOVEQ #0,D2 ; flags
WithDataStorage
LoadBSDSocketBase
WithDataStorageToA3
LoadBSDSocketBaseFromA3
CALLLIB send
EndDataStorage
@ -783,11 +635,11 @@ _SocketBind_SockaddrIn:
MOVE.L D0,A0
MOVE.L (SP)+,D0
WithDataStorage
WithDataStorageToA3
; socket id is in D0
; sockaddr_in is in A0
MOVE.L #len_sockaddr_in,D1 ; len
LoadBSDSocketBase
LoadBSDSocketBaseFromA3
CALLLIB bind
EndDataStorage
@ -814,8 +666,8 @@ _SocketBind_SockaddrIn:
Ret_Int
_SocketErrno_LibraryOpen:
WithDataStorage
LoadBSDSocketBase
WithDataStorageToA3
LoadBSDSocketBaseFromA3
CALLLIB Errno
EndDataStorage
@ -849,8 +701,8 @@ _SocketListen_LibraryOpen:
MOVE.L D3,D2
MOVEQ #5,D1
WithDataStorage
LoadBSDSocketBase
WithDataStorageToA3
LoadBSDSocketBaseFromA3
CALLLIB listen
EndDataStorage
@ -885,10 +737,10 @@ _SocketAccept_LibraryOpen:
MOVE.L D3,D2
WithDataStorage
WithDataStorageToA3
Dlea AcceptScratchArea,A0
Dlea len_sockaddr_in_ptr,A1
LoadBSDSocketBase
LoadBSDSocketBaseFromA3
CALLLIB accept
EndDataStorage
@ -951,11 +803,11 @@ _SocketSetNonblocking_IsBlocking:
_SocketSetNonblocking_Ioctl:
WithDataStorage
WithDataStorageToA3
MOVE.L D1,IoctlSockOptScratch-MB(A3)
Dlea IoctlSockOptScratch,A0
MOVE.L #FIONBIO,D1
LoadBSDSocketBase
LoadBSDSocketBaseFromA3
CALLLIB IoctlSocket
MOVE.L D0,D3
@ -1013,12 +865,12 @@ _SocketGetsockoptInt_LibraryOpen:
MOVE.L #SOL_SOCKET,D1 ; level
MOVE.L A3,-(SP)
WithDataStorage
WithDataStorageToA3
Dlea IoctlSockOptScratch,A0 ; optval
MOVE.L #4,getsockopt_len-MB(A3)
Dlea getsockopt_len,A1
LoadBSDSocketBase
LoadBSDSocketBaseFromA3
CALLLIB getsockopt
EndDataStorage
MOVE.L (SP)+,A3
@ -1339,8 +1191,8 @@ _SocketSelect_PerformSelect
_SocketInetNtoa_LibraryOpen:
MOVE.L D3,D0
WithDataStorage
LoadBSDSocketBase
WithDataStorageToA3
LoadBSDSocketBaseFromA3
CALLLIB Inet_NtoA
EndDataStorage
@ -1436,8 +1288,8 @@ _SocketRecvString_BufferAllocated:
MOVEM.L A0-A1/D1,-(SP)
WithDataStorage
LoadBSDSocketBase
WithDataStorageToA3
LoadBSDSocketBaseFromA3
CALLLIB recv ; D0 has received length or -1
EndDataStorage
@ -1530,8 +1382,8 @@ _SocketRecvData_LibraryOpen:
Ret_Int
_SocketRecvData_PositiveLength:
WithDataStorage
LoadBSDSocketBase
WithDataStorageToA3
LoadBSDSocketBaseFromA3
CALLLIB recv ; D0 has received length or -1
EndDataStorage
@ -1540,8 +1392,6 @@ _SocketRecvData_PositiveLength:
RestoreStackFunction
Ret_Int
; actually close the library
Lib_Def DoSocketLibraryClose
@ -1556,7 +1406,6 @@ _SocketRecvData_PositiveLength:
CLR.L sockaddr_ram-MB(A3) ; prevent double free
_DoSocketLibraryClose_CloseLibrary:
MOVE.L BSDSocketBase-MB(A3),D0
BEQ _DoSocketLibraryClose_Skip
@ -1661,12 +1510,12 @@ _SocketWaitAsyncWriting_CheckSockopt:
MOVE.L A3,-(SP)
WithDataStorage
WithDataStorageToA3
Dlea IoctlSockOptScratch,A0 ; optval
MOVE.L #4,getsockopt_len-MB(A3)
Dlea getsockopt_len,A1
LoadBSDSocketBase
LoadBSDSocketBaseFromA3
CALLLIB getsockopt
EndDataStorage
@ -1871,12 +1720,12 @@ _SocketReuseAddr_LibraryOpen:
MOVE.L #SOL_SOCKET,D1 ; Level
WithDataStorage
WithDataStorageToA3
Dlea IoctlSockOptScratch,A0 ; optval
MOVE.L D3,A0
MOVEQ #4,D3
LoadBSDSocketBase
LoadBSDSocketBaseFromA3
CALLLIB setsockopt
EndDataStorage
@ -1892,61 +1741,100 @@ _SocketReuseAddr_LibraryOpen:
Lib_Par DnsGetHostAddressByName
PreserveStackFunction
EnsureBSDSocketLibrary _DnsGetHostAddressByName_LibraryOpen
EnsureBSDSocketLibrary .LibraryOpen
MOVE.L ChVide(A5),D3
RestoreStackFunction
Ret_String
_DnsGetHostAddressByName_LibraryOpen:
.LibraryOpen:
; string so you need demande, hichaine, and chvide
MOVE.L D3,A0 ; name
ADD.L #2,A0 ; skip length, string is null terminated (?)
MOVE.W (A0)+,D0 ; d0 contains length
MOVE.L D0,D1 ; d1 also has length
MOVE.L D0,D2 ; d2 also has length
Rjsr L_RamFast ; d0 contains address
BNE .StringRamAllocated
WithDataStorage
LoadBSDSocketBase
MOVE.L ChVide(A5),D3
RestoreStackFunction
Ret_String
.StringRamAllocated:
MOVE.L D0,A1 ; a1 contains address
SUBQ #1,D1 ; reduce by one for DBRA
.KeepCopyingAMOSString
MOVE.B (A0)+,(A1)+ ; byte copy
DBRA D1,.KeepCopyingAMOSString ; keep copying
MOVE.B #0,(A1)+ ; null terminate string
MOVE.L D0,A0 ; first param of gethostbyname
MOVEM.L A0/D2,-(SP)
WithDataStorageToA3
LoadBSDSocketBaseFromA3
CALLLIB gethostbyname
EndDataStorage
MOVEM.L (SP)+,A0/D2
; free the ram before we go any farther
MOVE.L D0,-(SP)
MOVE.L A0,A1
MOVE.L D2,D0
Rjsr L_RamFree
MOVE.L (SP)+,D0
TST.L D0
BNE _DnsGetHostAddressByName_GetIPAddress
BNE .GetIPAddress
Dlea DebugArea,A0
MOVE.L D3,A1
MOVE.L #1,(A0)+
MOVE.W (A1),(A0)+
MOVE.W (A1),D2
MOVE.B 1(A1,D2),(A0)+
MOVE.B 2(A1,D2),(A0)+
RestoreStackFunction
MOVE.L ChVide(A5),D3
Ret_String
_DnsGetHostAddressByName_GetIPAddress:
.GetIPAddress:
MOVE.L D0,A0
MOVE.L 16(A0),A1 ; **h_addr_list
MOVE.L (A1),A1 ; *h_addr_list
MOVE.L (A1),D0 ; h_addr_list[0]
WithDataStorage
LoadBSDSocketBase
WithDataStorageToA3
LoadBSDSocketBaseFromA3
CALLLIB Inet_NtoA
EndDataStorage
Dlea DebugArea,A0
MOVE.L D0,(A0)+
MOVE.L D0,A2
MOVE.L A2,-(SP)
MOVEQ #0,D3
_DnsGetHostAddressByName_GetIPAddressLength:
.GetIPAddressLength:
ADDQ #1,D3
TST.B (A2)+
BNE _DnsGetHostAddressByName_GetIPAddressLength
BNE .GetIPAddressLength
MOVE.L (SP)+,A2
Dlea DebugArea,A0
MOVE.L D3,(A0)+
Rjsr L_Demande ; string is in A0/A1
MOVE.W D3,(A0)+
SUBQ #1,D3
_DnsGetHostAddressByName_KeepCopying:
.KeepCopying:
MOVE.B (A2,D3),(A0,D3)
DBRA D3,_DnsGetHostAddressByName_KeepCopying
DBRA D3,.KeepCopying
EvenOutStringAddress A0,D0
@ -1966,7 +1854,7 @@ _DnsGetHostAddressByName_KeepCopying:
; - - - - - - - - - - - - -
PreserveStackFunction
MOVE.L D3,D4 ; milliseconts
MOVE.L D3,D4 ; milliseconds
MOVE.L (A3)+,D0 ; socket id
EnsureBSDSocketLibrary _SocketSetTimeout_LibraryOpen
@ -1988,7 +1876,7 @@ _SocketSetTimeout_LibraryOpen:
MOVE.L (A0)+,(A1)+
SUB.L #8,A1 ; go back
WithDataStorage
WithDataStorageToA3
; socket is d0
MOVE.L #SOL_SOCKET,D1 ; Level
MOVE.L #$1005,D2 ; SO_SNDTIMEO
@ -1996,7 +1884,7 @@ _SocketSetTimeout_LibraryOpen:
MOVEQ #8,D3
MOVEM.L D0/A0,-(SP)
LoadBSDSocketBase
LoadBSDSocketBaseFromA3
CALLLIB setsockopt
TST.L D0
@ -2007,7 +1895,7 @@ _SocketSetTimeout_LibraryOpen:
MOVE.L #$1006,D2 ; SO_RCVTIMEO
MOVEQ #8,D3
LoadBSDSocketBase
LoadBSDSocketBaseFromA3
CALLLIB setsockopt
EndDataStorage
@ -2034,17 +1922,17 @@ _SocketSetTimeout_Fail:
Lib_Par SocketCloseSocket
; - - - - - - - - - - - - -
PreserveStackFunction
EnsureBSDSocketLibrary _SocketCloseSocket_LibraryOpen
EnsureBSDSocketLibrary .LibraryOpen
RestoreStackFunction
Ret_Int
_SocketCloseSocket_LibraryOpen:
.LibraryOpen:
MOVE.L D3,D0
WithDataStorage
LoadBSDSocketBase
WithDataStorageToA3
LoadBSDSocketBaseFromA3
CALLLIB CloseSocket
EndDataStorage
@ -2053,6 +1941,46 @@ _SocketCloseSocket_LibraryOpen:
RestoreStackFunction
Ret_Int
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; Int=Socket Herrno
;
; Return Herrno value, errors related to DNS resolution
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Lib_Par SocketHerrno
; - - - - - - - - - - - - -
PreserveStackFunction
; set up tag list memory and place for herrno to go
Dlea AcceptScratchArea,A0
MOVE.L A0,A2
Dlea SelectScratchArea,A1
; build the tag list
MOVE.L HerrnoTag,(A0)+
MOVE.L A1,(A0)+
MOVE.L 0,(A0)+
MOVE.L 0,(A0)+
MOVE.L A2,A0
WithDataStorageToA3
LoadBSDSocketBaseFromA3
CALLLIB SocketBaseTagList
EndDataStorage
TST.L D0
BEQ .success
; failed
MOVE.L #-1,D3
RestoreStackFunction
Ret_Int
.success
MOVE.L (A1),D3
RestoreStackFunction
Ret_Int
;
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; Even if you do not have error messages, you MUST

43
src/Constants.s Normal file
View File

@ -0,0 +1,43 @@
; bsdsocket library stuff
; ported from the various C include headers
SOCK_STREAM EQU 1
PF_INET EQU 2
AF_INET EQU PF_INET
IPPROTO_TCP EQU 6
INADDR_ANY EQU 0
FIONBIO EQU $8004667E
FIONASYNC EQU $8004667D
SOL_SOCKET EQU $FFFF
SO_REUSEADDR EQU $4
MAX_SOCKETS EQU 64
len_sockaddr_in EQU 16
sockaddr_in_sin_len EQU 0
sockaddr_in_sin_family EQU 1
sockaddr_in_sin_port EQU 2
sockaddr_in_sin_addr EQU 4
; global errors
Error_OtherError EQU -1
Error_LibraryNotOpen EQU -2
Error_PortOutOfRange EQU -11
Error_FdsetOutOfRange EQU -11
Error_UnableToBind EQU -12
; socket herrno and tag lists
; built from:
; * https://wiki.amigaos.net/amiga/autodocs/bsdsocket.doc.txt
; * https://github.com/deplinenoise/amiga-sdk/blob/master/netinclude/amitcp/socketbasetags.h
; * http://amigadev.elowar.com/read/ADCD_2.1/Includes_and_Autodocs_2._guide/node012E.html
TAG_USER EQU (1<<31)
SBTF_REF EQU $8000
SBTB_CODE EQU 1
SBTS_CODE EQU $3FFF
SBTC_HERRNO EQU 6
HerrnoTag EQU (TAG_USER|SBTF_REF|((SBTC_HERRNO&SBTS_CODE)<<SBTB_CODE))

43
src/LongDivide.s Normal file
View File

@ -0,0 +1,43 @@
; d0 = value to be divided
; d1 = divisor
; returns:
; d0 = divided value
; d1 = remainder
LongDivideD0ByD1 MACRO
CMP.L D0,D1
BMI _LongDivide_StartDivide\@
MOVE.L D0,D1
MOVEQ #0,D0
BRA _LongDivide_Skip\@
_LongDivide_StartDivide\@:
MOVEM.L D2-D4,-(SP)
MOVEQ #0,D2 ; remainder
MOVE.L #31,D3 ; bit tracking
; d4 tracks the status register
_LongDivide_ContinueDivide\@:
ASL.L #1,D0
SCS D4 ; bit that got rolled out
AND.L #1,D4
ROL.L #1,D2
ADD.L D4,D2 ; roll the value onto the remainder
MOVE.L D2,D4
SUB.L D1,D4
BMI _LongDivide_NotDivisible\@
ADDQ #1,D0
MOVE.L D4,D2
_LongDivide_NotDivisible\@:
DBRA D3,_LongDivide_ContinueDivide\@
MOVE.L D2,D1
MOVEM.L (SP)+,D2-D4
_LongDivide_Skip\@:
ENDM

47
src/fd_set.s Normal file
View File

@ -0,0 +1,47 @@
; fdset macros
EnsureValidFdset MACRO
CMP.L #MaxFd_sets,\1
BLT \2
MOVE.L #Error_FdsetOutOfRange,D3
RestoreStackFunction
Ret_Int
ENDM
EnsureValidFdsetBit MACRO
CMP.L #64,\1
BGE _EnsureValidFdsetBit_Fail\@
BRA \2
_EnsureValidFdsetBit_Fail\@:
MOVE.L \3,D3
RestoreStackFunction
Ret_Int
ENDM
; LeaFdset fd_set reg,target
LeaFdset MACRO
MOVE.L \1,-(SP)
Dlea fd_sets,\2 ; base of all, these are longs
ROL.L #3,\1 ; multiply by 8
ADD.L \1,\2 ; add to base of all
MOVE.L (SP)+,\1
ENDM
; LeaFdsetForBit fd_set reg,target address,target bit in address
LeaFdsetForBit MACRO
LeaFdset \1,\2 ; get fdset base address in \2
MOVE.L D3,-(SP)
MOVE.L \3,D3 ; Put target bit into D3
ROR.L #5,D3 ; lop off the first 5 bits
AND.L #$7,D3 ; only keep the top three
ROL.L #2,D3 ; multiply by 4
ADD.L D3,\2 ; add that value to the fdset address
AND.L #$1F,\3 ; only keep 0-31 in \3
MOVEQ #1,D3
ROL.L \3,D3 ; shift that bit left as many as target
MOVE.L D3,\3 ; put that in the target
MOVE.L (SP)+,D3
ENDM