RawExtensions - jedimatt42/tipi GitHub Wiki

Raw Extensions

TIPI provides an extensible model for extending PI services to the TI-99/4A.

These don't have to be wrapped up in a Level 3 file interface, and they don't have to have additional Assembly language DSR ROM support.

They can be extended through the existing messaging interface.

There are currently 6 such extensions:

Type Extension Description
0x20 Mouse Read usb mouse data
0x21 Network Variables High level data sharing for myti99.com
0x22 TCP Client socket connections
0x23 UDP Client UDP socket connections
0x24 TLS Client TLS socket connections
0x25 LOG Add message to /var/log/tipi/tipi.log

To aid in this, the python side of reading and writing messages is encapsulated in TipiMessage.py. And the TI assembly routines are in the DSR ROM and indexed at well known locations in the ROM:

; TIPI routine list - well known addresses for some custom exposure
	DATA	recvmsg		; MOV @>4010,R3   BL *R3   to invoke recvmsg.
	DATA	sendmsg		; MOV @>4012,R3   BL *R3   to invoke sendmsg. 
	DATA	vrecvmsg	; MOV @>4014,R3   BL *R3   to invoke recvmsg.
	DATA	vsendmsg	; MOV @>4016,R3   BL *R3   to invoke sendmsg. 
	DATA	>0000

Prerequisite

The code for these routines is in the DSR. A program will have to find the crubase by performing a name search for the DSR 'TIPI'. Once the crubase is found, set CRU bit 0 of that CRUBASE to bank the ROM into the system DSR address space.

Then you can perform your call to the routine.

The DSR ROM should be banked out of the system DSR address space by clearing CRU bit 0, when not in use. Only one device ( DSR ROM, memory mapper, etc ) may be banked in at a time. A DSRLNK assumes nothing is banked in prior to execution, so disk IO won't work correctly if this is not unbanked before hand.

Practical example code is available in the TI Artist TIPI mouse driver

sendmsg

Send a message to the RPi - Sends a word containing the length of message, then the bytes of the message.

Register usage: R0 - contains length of message. Result is 0 if all bytes sent. R1 - cpu address of bytes to send. Destroys R2, R3, and potentially the first and last word of bytes to send.

Note: vsendmsg functions the same as sendmsg except the buffer address is in VDP RAM.

MSG	DATA	>0102 >0304 >0500
...
        LI	R0,5         ; set R0 to length of message data
        LI      R1,MSG       ; set R1 to CPU address of message data
        MOV     @>4012,R3    ; load address of sendmsg routine
        BL      *R3          ; call sendmsg.
...        

recvmsg

Request a message from the RPi - expects the PI to send a word containing the length of the message followed by the payload.

Register usage: R0 - Set to number of bytes loaded into buffer upon completion R1 - cpu address of buffer Destroys R0 - R4

At this level of API, the length of the receive buffer is unspecified. There must be a contract between your client and the particular extension. For instance the required buffer for a mouse read is fixed, but for TCP the TCP extension allows setting a buffer limit.

Note: vrecvmsg functions the same as recvmsg except the buffer address is in VDP RAM.

BUF	BSS	20
...
        LI      R1,BUF       ; set R1 to CPU address of receive buffer
        MOV     @>4010,R3    ; load address of recvmsg routine
        BL      *R3          ; call recmsg.
                             ; R0 is now length of received data