01-20-2015, 04:26 PM
Some dirty code.
Code:
paper 0
ink 7
cls
start()
opensocket()
hostip()
connect()
pause 200
cls
sendfirst()
mainloop()
SUB fastcall start()
ASM
ld hl, startupMSG
ld bc, end1MSG-startupMSG
call myPrint64
ld hl, lookingupMSG
call myPrint42
END ASM
END SUB
SUB fastcall opensocket()
ASM
ld c, 1
ld hl, SOCKET
call HLCALL
ld (v_sockfd), a
ret
END ASM
END SUB
SUB fastcall hostip()
ASM
ld hl, serverhost
ld de, ip_buffer
ld ix, GETHOSTBYNAME
call IXCALL
ret
END ASM
END SUB
SUB fastcall connect()
ASM
ld hl, connectingMSG
call myPrint42
; now actually connect...
ld a, (v_sockfd) ; get back the socket file descriptor
ld de, ip_buffer ; point to the dotted ip notation we got previously
ld bc, serverport ; the port I want to use to connect on... (22528 as is heh)
ld hl, CONNECT
call HLCALL ; call the Spectranet CONNECT ROM routine, :D
;jp c, commerror ; carry is set if there is an error (fingers crossed k)
; CONNECTED !!!
xor a
inc a
ld (connected), a
ld hl, connectedMSG
call myPrint42
END ASM
END SUB
SUB fastcall sendfirst()
ASM
ld a, (v_sockfd)
ld de, garbage
ld bc, garbageend-garbage
ld hl, SEND
call HLCALL
END ASM
END SUB
SUB fastcall mainloop()
ASM
; main receive loop, :/
.tightloop:
; poll the socket to see if data is waiting
call pollSocket
jr c, .no_data1
; there is data to be collected
.gData2:
call clearBuffer
ld a, (v_sockfd)
ld de, responseBuffer
ld bc, responseBufferEnd-responseBuffer
ld hl, RECV
call HLCALL
jp c, commerror
ld hl, responseBuffer ; get the address of the buffer
add hl, bc ; add on the number of received bytes
inc hl
ld (hl), msgEND ; mark that point as the end of the text
call displayData ; and just display that, :D
jr .tightloop
.no_data1:
xor a
.checkkeys:
jr nc, .tightloop
; now close the socket, dunno why cos I ain't never ever gonna give you up, err, I mean drop to BASIC
; green indicates complete run through worked ok...
ret
;========================================================================
pollSocket:
; returns carry clear if data to be fetched
; or set carry to indicate no data...
ld a, (v_sockfd)
ld hl, POLLFD
CALL HLCALL
jr z, .nodata
scf
ccf
ret
.nodata:
scf
ret
displayData:
;ld a, 3
;out ($fe), a
ld hl, responseBuffer
call myPrint42
ret
END ASM
END SUB
SUB fastcall clearBuffer()
ASM
clearBuffer:
ld hl, responseBuffer
ld de, responseBuffer+1
ld bc, responseBufferEnd-responseBuffer-1
ld (hl), 32
ldir
ret
END ASM
END SUB
SUB fastcall commerror()
ASM
commerror:
ld a, 2
out ($fe), a ; turn border red to indicate error... :/
ld hl, errorMSG
call myPrint42 ; print the error msg
ld a, (v_sockfd)
and a ; do we have a socket?
ret z ; nope, so return ;NOTE: This may cause a ret to BASIC, grr, will sort it later, :p
ld hl, CLOSE ; we have a socket, so clean it up
call HLCALL
;call end_interrupts ; reset interrupts back to im 1..
ret
END ASM
END SUB
SUB fastcall myPrint42()
ASM
myPrint42:
push af
push ix
push hl
ld ix, PRINT42
CALL IXCALL
pop hl
pop ix
pop af
ret
END ASM
END SUB
SUB fastcall myPrint64()
ASM
myPrint64:
push af
push ix
push hl
; Test string length. If Zero, exit.
ld a, c
or b
jp z, p64_END
;LOCAL examineChar
examineChar:
ld a, (hl) ; Grab the character
cp 128 ; too high to print?
jr nc, nextChar ; then we go to next.
cp 22 ; Is this an AT?
jr nz, newLine ; If not, hop to newLine routine.
ex de, hl ; Swap DE and HL
and a ; Clear Carry
ld hl, 2 ;
sbc hl, bc ; Can we Shorten our string length by 2? If not then at (y,x) doesn't make sense.
ex de, hl ; Swap DE and HL back
jp nc, p64_END ; If we went negative, there wasn't anything to AT to, so we return.
inc hl ; Onto our Y co-ordinate
ld d, (hl) ; And load it into D
dec bc ; Shorten our remaining string counter.
inc hl ; Onto the X Co-ordinate
ld e, (hl) ; Load it into E
dec bc ; Shorten our remaining string counter
call p64_test_X ; Make xy legal 60051 205 53 235
jr p64_eaa3 ; Go to save coords 60054 24 11
;LOCAL newLine
newLine:
cp 13 ; Is this a newline character? 60056 254 13
jr nz, p64_isPrintable ; If not, hop to testing to see if we can print this 60058 32 13
ld de, (p64_coords) ; Get coords 60060 237 91 68 235
call p64_nxtLine ; Go to next line.
;LOCAL p64_eaa3
p64_eaa3:
ld (p64_coords), de
jr nextChar
;LOCAL p64_isPrintable
p64_isPrintable:
cp 31 ; Bigger than 31? 60073 254 31
jr c, nextChar ; If not, get the next one. 60075 56 7
push hl ; Save position 60077 229
push bc ; Save Count 60078 197
call p64_PrintChar ; Call Print SubRoutine 60079 205 189 234
pop bc ; Recover length count 60082 193
pop hl ; Recover Position 60083 225
; LOCAL nextChar
nextChar:
inc hl ; Point to next character 60084 35
dec bc ; Count off this character 60085 11
ld a, b ; Did we run out? 60086 120
or c
jr nz, examineChar ; If not, examine the next one 60088 32 193
jp p64_END ; Otherwise hop to END. 60090 201
; LOCAL p64_PrintChar
p64_PrintChar:
exx
push hl ; Save HL' 60094 229
exx
sub 32 ; Take out 32 to convert ascii to position in charset 60096 214 32
ld h, 0
rra ; Divide by 2 60100 31
ld l, a ; Put our halved value into HL 60101 111
ld a, 240 ; Set our mask to LEFT side 60102 62 240
jr nc, p64_eacc ; If we didn't have a carry (even #), hop forward. 60104 48 2
ld a, 15 ; If we were ab idd #, set our mask to RIGHT side instead 60106 62 15
;LOCAL p64_eacc
p64_eacc:
add hl, hl
add hl, hl
add hl, hl ; Multiply our char number by 8 60110 41
ld de, p64_charset ; Get our Charset position 60111 17 70 235
add hl, de ; And add our character count, so we're now pointed at the first
; byte of the right character. 60114 25
exx
ld de, (p64_coords)
ex af, af'
call p64_loadAndTest
ex af, af'
inc e
ld (p64_coords), de ; Put position+1 into coords 60126 237 83 68 235
dec e
ld b, a
rr e ; Divide X position by 2 60132 203 27
ld c, 0
rl c ; Bring carry flag into C (result of odd/even position) 60136 203 17
and 1 ; Mask out lowest bit in A 60138 230 1
xor c ; XOR with C (Matches position RightLeft with Char RightLeft) 60140 169
ld c, a
jr z, p64_eaf6 ; If they are both the same, skip rotation. 60142 40 6
ld a, b
rrca
rrca
rrca
rrca
ld b, a
;LOCAL p64_eaf6
p64_eaf6:
ld a, d ; Get Y coord 60150 122
sra a
sra a
sra a ; Multiply by 8 60155 203 47
add a, 88
ld h, a ; Put high byte value for attribute into H. 60159 103
ld a, d
and 7
rrca
rrca
rrca
add a, e
ld l, a ; Put low byte for attribute into l 60167 111
ld a, (23693) ; Get permanent Colours from System Variable 60168 58 141 92
ld (hl), a ; Write new attribute 60171 119
ld a, d
and 248
add a, 64
ld h, a
ld a, b
cpl
ld e, a
exx
ld b, 8
;LOCAL p64_eb18
p64_eb18:
ld a, (hl)
exx
bit 0, c
jr z, p64_eb22
rrca
rrca
rrca
rrca
;LOCAL p64_eb22
p64_eb22:
and b
ld d, a
ld a, (hl)
and e
or d
ld (hl), a
inc h
exx
inc hl
djnz p64_eb18
exx
pop hl
exx
ret
; LOCAL p64_loadAndTest
p64_loadAndTest:
ld de, (p64_coords)
; SubRoutine to go to legal character position. (60213)
; LOCAL p64_test_X
p64_test_X:
ld a, e ; Get column from e
cp 64 ; more than 64 ?
jr c, p64_test_Y ; If not, then jump over nextline
;LOCAL p64_nxtLine
p64_nxtLine:
inc d ; Move down 1
ld e, 0 ; reset x co-ord to zero
; LOCAL p64_test_Y
p64_test_Y:
ld a, d ; get Y co-ord
cp 24 ; Past 24?
ret c ; Return if not.
ld d, 0 ; Rest y co-ord to top of screen.
ret ; Return.
; LOCAL p64_coords;
p64_coords:
defb 64; X Coordinate store 60228 64
defb 23; Y Coordinate Store 60229 23
;LOCAL p64_charset
p64_charset:
DEFB 0,2,2,2,2,0,2,0 ; Space !
DEFB 0,80,82,7,2,7,2,0 ; "" #
DEFB 0,37,113,66,114,20,117,32 ; $ %
DEFB 0,34,84,32,96,80,96,0 ; & '
DEFB 0,36,66,66,66,66,36,0 ; ( )
DEFB 0,0,82,34,119,34,82,0 ; * +
DEFB 0,0,0,0,7,32,32,64 ; , -
DEFB 0,1,1,2,2,100,100,0 ; . /
DEFB 0,34,86,82,82,82,39,0 ; 0 1
DEFB 0,34,85,18,33,69,114,0 ; 2 3
DEFB 0,87,84,118,17,21,18,0 ; 4 5
DEFB 0,55,65,97,82,84,36,0 ; 6 7
DEFB 0,34,85,37,83,85,34,0 ; 8 9
DEFB 0,0,2,32,0,34,2,4 ; : ;
DEFB 0,0,16,39,64,39,16,0 ; < =
DEFB 0,2,69,33,18,32,66,0 ; > ?
DEFB 0,98,149,183,181,133,101,0 ; @ A Changed from ;0,2,37,87,117,85,53,0
DEFB 0,98,85,100,84,85,98,0 ; B C
DEFB 0,103,84,86,84,84,103,0 ; D E
DEFB 0,114,69,116,71,69,66,0 ; F G
DEFB 0,87,82,114,82,82,87,0 ; H I
DEFB 0,53,21,22,21,85,37,0 ; J K
DEFB 0,69,71,71,69,69,117,0 ; L M
DEFB 0,82,85,117,117,85,82,0 ; N O
DEFB 0,98,85,85,103,71,67,0 ; P Q
DEFB 0,98,85,82,97,85,82,0 ; R S
DEFB 0,117,37,37,37,37,34,0 ; T U
DEFB 0,85,85,85,87,39,37,0 ; V W
DEFB 0,85,85,37,82,82,82,0 ; X Y
DEFB 0,119,20,36,36,68,119,0 ; Z [
DEFB 0,71,65,33,33,17,23,0 ; \ ]
DEFB 0,32,112,32,32,32,47,0 ; ^ _
DEFB 0,32,86,65,99,69,115,0 ; £ a
DEFB 0,64,66,101,84,85,98,0 ; b c
DEFB 0,16,18,53,86,84,35,0 ; d e
DEFB 0,32,82,69,101,67,69,2 ; f g
DEFB 0,66,64,102,82,82,87,0 ; h i
DEFB 0,20,4,53,22,21,85,32 ; j k
DEFB 0,64,69,71,71,85,37,0 ; l m
DEFB 0,0,98,85,85,85,82,0 ; n o
DEFB 0,0,99,85,85,99,65,65 ; p q
DEFB 0,0,99,84,66,65,70,0 ; r s
DEFB 0,64,117,69,69,85,34,0 ; t u
DEFB 0,0,85,85,87,39,37,0 ; v w
DEFB 0,0,85,85,35,81,85,2 ; x y
DEFB 0,0,113,18,38,66,113,0 ; z {
DEFB 0,32,36,34,35,34,36,0 ; | {
DEFB 0,6,169,86,12,6,9,6 ; ~ (c)
;LOCAL p64_END
p64_END:
pop hl
pop ix
pop af
ret
END ASM
END SUB
ASM
msgEND EQU 0
msgCR EQU 10
RET_OK EQU 0
RET_SOCKERR EQU 1
RET_PORTERR EQU 2
RET_RECEIVEERR EQU 4
RET_UNKNOWN EQU 128
SOCK_STREAM EQU 1
SOCK_DGRAM EQU 2
SOCK_RAW EQU 3
CALLBAS EQU 0x10
STACK_BC EQU $2D2B
PRINT_FP EQU $2DE3
MODULECALL equ $3FF8
MODULECALL_NOPAGE equ $28
PAGEIN equ $3FF9
PAGEOUT equ $007C
HLCALL equ $3FFA
IXCALL equ $3FFD
; Port defines
CTRLREG equ $033B
CPLDINFO equ $023B
; Jump table entry points
SOCKET equ $3E00 ; Allocate a socket
CLOSE equ $3E03 ; Close a socket
LISTEN equ $3E06 ; Listen for incoming connections
ACCEPT equ $3E09 ; Accept an incoming connection
BIND equ $3E0C ; Bind a local address to a socket
CONNECT equ $3E0F ; Connect to a remote host
SEND equ $3E12 ; Send data
RECV equ $3E15 ; Receive data
SENDTO equ $3E18 ; Send data to an address
RECVFROM equ $3E1B ; Receive data from an address
POLL equ $3E1E ; Poll a list of sockets
POLLALL equ $3E21 ; Poll all open sockets
POLLFD equ $3E24 ; Poll a single socket
GETHOSTBYNAME equ $3E27 ; Look up a hostname
PUTCHAR42 equ $3E2A ; 42 column print write a character
PRINT42 equ $3E2D ; 42 column print a null terminated string
CLEAR42 equ $3E30 ; Clear the screen and reset 42-col print
SETPAGEA equ $3E33 ; Sets page area A
SETPAGEB equ $3E36 ; Sets page area B
LONG2IPSTRING equ $3E39 ; Convert a 4 byte big endian long to an IP
IPSTRING2LONG equ $3E3C ; Convert an IP to a 4 byte big endian long
ITOA8 equ $3E3F ; Convert a byte to ascii
RAND16 equ $3E42 ; 16 bit PRNG
REMOTEADDRESS equ $3E45 ; Fill struct sockaddr_in
IFCONFIG_INET equ $3E48 ; Set IPv4 address
IFCONFIG_NETMASK equ $3E4B ; Set netmask
IFCONFIG_GW equ $3E4E ; Set gateway
INITHW equ $3E51 ; Set the MAC address and initial hw registers
GETHWADDR equ $3E54 ; Read the MAC address
DECONFIG equ $3E57 ; Deconfigure inet, netmask and gateway
MAC2STRING equ $3E5A ; Convert 6 byte MAC address to a string
STRING2MAC equ $3E5D ; Convert a hex string to a 6 byte MAC address
ITOH8 equ $3E60 ; Convert accumulator to hex string
HTOI8 equ $3E63 ; Convert hex string to byte in A
GETKEY equ $3E66 ; Get a key from the keyboard, and put it in A
KEYUP equ $3E69 ; Wait for key release
INPUTSTRING equ $3E6C ; Read a string into buffer at DE
GET_IFCONFIG_INET equ $3E6F ; Gets the current IPv4 address
GET_IFCONFIG_NETMASK equ $3E72 ; Gets the current netmask
GET_IFCONFIG_GW equ $3E75 ; Gets the current gateway address
SETTRAP equ $3E78 ; Sets the programmable trap
DISABLETRAP equ $3E7B ; Disables the programmable trap
ENABLETRAP equ $3E7E ; Enables the programmable trap
PUSHPAGEA equ $3E81 ; Pages a page into area A, pushing the old one
POPPAGEA equ $3E84 ; Restores the previous page in area A
PUSHPAGEB equ $3E87 ; Pages into area B pushing the old one
POPPAGEB equ $3E8A ; Restores the previous page in area B
PAGETRAPRETURN equ $3E8D ; Returns from a trap to page area B
TRAPRETURN equ $3E90 ; Returns from a trap that didn't page area B
ADDBASICEXT equ $3E93 ; Adds a BASIC command
STATEMENT_END equ $3E96 ; Check for statement end, exit at syntax time
EXIT_SUCCESS equ $3E99 ; Use this to exit successfully after cmd
PARSE_ERROR equ $3E9C ; Use this to exit to BASIC with a parse error
RESERVEPAGE equ $3E9F ; Reserve a page of static RAM
FREEPAGE equ $3EA2 ; Free a page of static RAM
REPORTERR equ $3EA5 ; report an error via BASIC
startupMSG: defm "Ardent's Spectranet TCP Client Test"
end1MSG: defm 0
lookingupMSG: defm "Looking up hostname - the8bitmud.zapto.org"
defm msgCR,msgCR,msgEND
connectingMSG: defm "Connecting..."
defm msgCR,msgEND
allocatingMSG: defm "Allocating resources..."
defm msgCR,msgEND
connectedMSG: defm "Connected. "
defm msgCR,msgEND
receivngMSG: defm "Receiving data."
defm msgCR, msgEND
errorMSG: defm "Failed."
defm msgCR,msgEND
doneMSG: defm "Done"
defm msgCR,msgEND
waitingMSG: defm "I iz waitingz k :p"
defm msgCR,msgEND
crMSG: defm msgCR,msgEND
v_sockfd: defb 0 ; storage for socket file descriptor
serverport equ 32768
serverhost: defb "the8bitmud.zapto.org"
connected: defb 0 ; 0 means not connected, 1 means connected
ip_buffer: defb 0, 0, 0, 0 ; leave 4 bytes free for an IP address
garbage: defm "ardentcrest"
defm 13,10
garbageend: defb 0
garbage2: defm 0
garbageend2: defb 0
responseBuffer: defs 1024
responseBufferEnd: defb msgCR, msgEND
END ASM
I'm always on the chat or facebook.