Table Of Contents
PlusROMs can communicate with their dedicated back end in the internet. Sending and receiving bytes to and from these hosts does not need a waitroutine in the VCS RAM!
The backend path and hostname (or IP address) must be encoded as '\0' terminated strings inside the ROM. The NMI vector (1FFA and 1FFB) of the last bank is used as a pointer to these strings. The base address (ROM file start) is 1000. Hostname and path can be defined everywhere in the ROM file up to address $efff. Even the RAM area or the bankswitching and PlusROM hotspots can be used.
These definition is only needed by PlusROM functions enabled hardware or emulators at startup, to detect that PlusROM functions are used by this ROM and of course to know where to send and receive the data.
Currently the PlusROM functions are supported by the PlusCart, Gopher2600 and javatari.js with 2K, 4K, 3F, 3E and 3E+ cartridges and any standard bankswitching cartridge with or without 128 bytes of RAM (@ 1000 to 10FF) and a 'Standard' F4 Bankswitching (@ 1FF4 to 1FFB).
PlusROMs functions use 4 hotspot adresses (before the bankswitching area):
- 1FF0 is for writing a byte to the send buffer (max 256 bytes)
- 1FF1 is for writing a byte to the send buffer and submit the buffer to the back end API
- 1FF2 contains the next byte of the response from the host, every read will increment the receive buffer pointer (receive buffer is max 256 bytes also!)
- 1FF3 contains the number of (unread) bytes left in the receive buffer (these bytes can be from multiple responses)
The bytes are send to the back end as content of an HTTP 1.0 POST request with "Content-Type: application/octet-stream". The "PlusStore-ID" header of this request starts with the Firmware version (e.g. "v0.7.1") and after a space a 24 Hex digit which is the STM unique device Id, for identifing the cart at the back end.
The response of the back end should also be a "Content-Type: application/octet-stream" and the response-body should contain the payload and the first byte of the response should be the length of the payload, so "Content-Length" is payload + 1 byte. This is a workaround, because we don't have enough time in the emulator routine to analyse the "Content-Length" header of the response.
These definitions may change in the future (depending on the suggestions of experienced VCS Programmer).
To build batariBasic with PlusROM functions support just use this fork: https://github.com/Al-Nafuur/batari-Basic
To add PlusROM functions support to your existing batariBasic installation just replace (or add) these files in your bB include folder with the ones from the Github fork above:
To use PlusROM functions in your project just add
at the top of your .bas file, and to define your backend add
rem don't let your program flow run into this code asm SET_PLUSROM_API "your/path", "your.domain.com" end
somewhere in your data area (replace the strings with the path and domain of your internet backend). I suppose adding this piece of code at the end of your bas file or at the end of a bank.
batariBasic code examples for transfering data to your backend and receive the responses:
rem at startup, before you use the send function, you can check, rem if the hardware or emulator supports PlusROM functions if ReceiveBufferSize=255 then goto no_plusrom_support rem writing to the send buffer (256 bytes max!) WriteToBuffer=yourValue rem writing to the send buffer and sending the buffer to your internet backend WriteSendBuffer=yourLastValue rem after sending your request you can check for the response (e.g. every frame) if ReceiveBufferSize>0 then gosub read_response rem reading from receive buffer as long as there is incoming data read_response if ReceiveBufferSize=0 then return yourVariable=ReceiveBuffer goto read_response
You can determine inside your ROM whether PlusFunctions are available or not, by checking the response buffer size ($1ff3) at startup. If you define, in your asm-code, a different value than 0 for that address:
org $1ff3 .byte #255 ; Counter for Receive Buffer
if you read at startup with "lda $1ff3" the value you have defined and not a "0", you know the emulator/cart has no online functions.
The PlusCart is sending an unique Id ("PlusStore-ID" header) with every request.
This unique Id should not be published by a PlusROM back end. There is an API at the PlusStore where "registered" back ends can query the User-Name (and in future maybe more) of the owner of this specific Cart.
Of course this will only work for registered/connected PlusCarts.
For unregistered PlusCarts the back ends have to query their necessary information thru the ROM (input-field or select box...) or use a hash (e.g. md5) of the unique Id!
Emulators should generate a "PlusStore-ID" http-header with their request, that consists of a nickname given by the user and a generated uuid (starting with "WE") separated by a space character.