Table Of Contents
PlusROM
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) of your backend 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) for this pointer 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, javatari.js and Stella (since version 6.6) 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 too!)
- $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".
PlusCarts with firmware version up to v2.1.0 are sending a "PlusStore-ID" http header.
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.
PlusCarts with firmware versions newer than v2.1.1 are sending a "PlusROM-Info" http header.
The new "PlusROM-Info" header is discussed/explained in this AtariAge thread: https://atariage.com/forums/topic/324456-redesign-plusrom-request-http-header
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).
The PlusROM emulation routine has been ported to javatari.js the forked repository is here and your homebrew PlusROMs can be tested here
Using PlusROM functions in batariBasic (experimental)
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:
- /includes/2600basicfooter.asm
- /includes/banksw.asm
- /includes/score_graphics.asm
- /includes/PlusROM_functions.asm
To use PlusROM functions in your project just add
inline PlusROM_functions.asm
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
VCS Developer hints
You can determine inside your ROM whether PlusROM Functions 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.
Hints and example code for the PlusROM functions can be found in this Github repository:
https://github.com/Al-Nafuur/PlusROM-Hacks
Security
The PlusCart up to firmware version v2.1.1 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.