//
// ShockTicker.asm (a MackAsm file)
//

//
// The SATA section maps out all the variables in memory.
// There initial values are burned into the the EEPROM and
// reload at boot time.
//

//
// Constants
//
MAX_CHANNELS        const 10    // We can handle up to 10 channels.
CHAN_NAME_BUF_SIZE  const 110   // (10 char + 1 null) * 10 names
CHAN_MSG_BUF_SIZE   const 1000  // Up to 1k of message data

//
// System Calls
//
//
// Register Incoming Network Packet Interpt Handler.
// When the sever sends a packet to us, data is placed in memory an interupt
// handler is called (if one is registered).  The handler gets:
//   TOS   Command code that was sent to the sever
//   TOS-1 Buff address that was written to.
//   TOS-2 The number of bytes written to the buffer
//   TOS-3 Return address
// Example:
//  push  myIntHandler    // Address of the subroutine
//  syscall REGISTER_INT_IN
// 
REGISTER_INT_IN     const 1   // Register Incoming Network Packet Interupt Handler

//
// Register the Time of Day clock.  Use this routine to tell the kernel where
// your cock is.  It is increment a 4-byte int by 1 every millisecond.
// Example:
//  push  utcTime
//  syscall REGISTER_TIME_ADDR
//
REGISTER_TIME_ADDR  const 2   // Register the real-time clock.

//
// Send Packet to severt.
// Tell this kernal routine what kind of data you want from the server and where to put it,
// and this will send it off to the server.  When the data comes back and is place in the
// buffer, the Incoming Network Packet Interpt Handler is called.
// Example:
//  push  len           
//  push  bufAddr
//  push  CMD_SEND_CHAN_MSGS
//  syscall TRANSMIT_PACKET
TRANSMIT_PACKET      const  3   // push len, push buf, push cmd, syscall TRANSMIT_PACKET
CMD_SEND_TIME         const 0 //   Send 8-bytes. 4-bytes UTC millis since 1970 + 4-bytes TZ in millis
CMD_SEND_CHAN_NAMES   const 1 //   Send channel names command
CMD_SEND_CHAN_MSGS    const 2 //   Send channel messages command

//
// Data
//
START DATA SECTION
utcTime:    data.l  0 // UTC milliseconds since 1970     (4 of 8 bytes)
timeZone:   data.l  0 // UTC-Local time in milliseconds. (last 4 bytes of the time packet)

mode:     data.b  0 // Mode - current "state" of the display
OFF:      const   1
ONE_CHANNEL:  const   2  // "channel" stays fixed
ALL_CHANNELS: const   3  // "channel" keeps incrementing

curChannel:   data  0 // Current displayed channel.
chanNames:    array   0[MAX_CHANNELS] // An array of pointers to channel names  
chanMsgs:   array   0[MAX_CHANNELS] // An array of pointers to channel messages

hScrollSpeed: data  100   // millis between scroll

// Vars used by IntHandler and NextMsg
msgCmd      data  0   // The the server was responding to.
msgPtr      data  0
msgCount    data  0
msgEndOfBuf   data  0   // Points one past the buffer

// Messages
HELLO:      data.s  "HELLO\0"

// Error messages
DONTPANIC:    data.s  "Do\0x80t Panic\0" // char 0x80="n'"

//
// All the data past this point is written to by the server.
//
channelNameStart:
numOfChans:   data  0
chanNameBuf:  array.b 0[CHAN_NAME_BUF_SIZE] // A list of null terminaled strings
chanMsgBuf:   array.b 0[CHAN_MSG_BUF_SIZE] 


// 
ee_hScrollSpeed:  data  10


//
// Execution starts here.
//
START CODE
Restart:
  // Reload parameters from the EEPROM
  load  ee_hScrollSpeed
  store hScrollSpeed

  // Register Interup Handler.
  push  IntHandler
  syscall REGISTER_INT_IN

  // Set the Clock. 
  push  8                       // ARG2 - Buf size
  push  utcTime                 // ARG1 - Buff address
  push  CMD_SEND_TIME           // ARG0 - Command
  stycall TRANSMIT_PACKET       // Send off a request for the time.  This might take a while.

  push  utcTime                 // ARG0 - Push the address of our clock
  syscall REGISTER_TIME_ADDR    // Now utcTime will auti inc by 1 once every millisecond.

  // Ask the server to send the channel names.
GetChanNames:
  push  CHAN_NAME_BUF_SIZE      // ARG2 - Max data size
  push  chanNameBuf             // ARG1 - Buffer address
  push  SEND_CHAN_NAMES         // ARG0 - Command to get channel names
  syscall SEND_PACKET

  // Ask the server to send the channel data.
GetChanMsgs:
  push  CHAN_MSG_BUF_SIZE       // ARG2 - Max data size
  push  chanMsgBuf              // ARG1 - Buffer address
  push  SEND_CHAN_MSGS          // ARG0 - Command to get channel names
  syscall SEND_PACKET
  

MainLoop:
  // Display next change.
  syscall

  b MainLoop:               // Bottom of the mail loop.
//
// The "Incoming Network Packet Interpt Handler"
//   TOS   Command code that was sent to the sever
//   TOS-1 Buff address that was written to.
//   TOS-2 The number of bytes written to the buffer
//   TOS-3 Return address
IntHandler:
  store   msgCmd
  dup                       // Make a copy of the buf address
  store   msgPtr
  add                       // add the start address to the size
  store   msgEndOfPtr
                            // Stack has only the return addres on it now.
  load    msgCmd
  push    CMD_SEND_TIME
  b.=     Done
  load    msgCmd  
  b.<>    CMD_SEND_CHAN_NAMES, TryMsgCommand
  // Hanlde new names;
  store 0, msgCount
msgLook:
  load    msgPtr
  load.b                    // load *msgPtr
  push    0 
  b.<>    msgGetNExt
  // Done. Save count and restart.
  load    msgCount
  store   numOfChans
  clear                     // Empty the stack
  b GetChanMsgs
msgGetNext
  load    msgPtr
  push    chanNames
  lshift  msgCount, 1       // msgCount * sizeof(int)
  add                       // push &(chanName[msgCount])
  store                     // hanName[msgCount] = msgPtr
TryMsgCommand:
  load    msgCmd
  b.<>    CMD_SEND_CHAN_MSGS, Done
  // Handle new message data
Done:
  return                    // Return to what we were doing.

// Utility routine used by IntHandler.
//   msgPtr - points the message to skip
//   msgEndOfBuf - point one past the end of the buffer.
//   TOS - Return address
NextMsg:
  return
  