PlusROM

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.