#####################
# Basic test code 3 #
#####################

# MEMORY MAP
# ----------

# ADDR		A1 A0 CS	WR						RD

# 0xFFF 	1  1  0		UART tx					UART rx
# 0xFFE     1  0  0		UART tx					UART status

# 0xFFD     0  1  1		GPIO A out				GPIO A out		  
# 0xFFC     0  0  1		GPIO A out  			GPIO A in 

# 0xFFB     0  1  2		NU     				    NU
# 0xFFA     1  0  2	    ROTARY_RESET			ROTARY_DATA
# 0xFF9     0  1  2		SNES_DATA               SNES_DATA
# 0xFF8     0  0  2		SNES_START    			SNES_STATUS

# 0xFF7     1  1  3		VGA 					VGA
# 0xFF6     1  0  3		VGA TILE_Y_REG
# 0xFF5     0  1  3		VGA TILE_X_REG
# 0xFF4     0  0  3		VGA CPU_DST_ADDR_REG
# 0xFF3     1  1  3		VGA CPU_COLOUR_REG		VGA TILE_POS
# 0xFF2     1  0  3 	VGA CPU_DATA_IN_REG		VGA CPU_DATA_OUT_REG
# 0xFF1     0  1  3		VGA CPU_SRC_ADDR_REG
# 0xFF0     0  0  3		VGA CPU_CTL_REG 		VGA CPU_STATUS_REG 

# 0xFEF     1  1  MEM	RAM						RAM
# ...					...						...
# 0x000		0  0  MEM	RAM						RAM

# UART REGISTERS
# --------------
# TX : B7 - B0 data
# RX : B7 - B0 data 

# STATUS REGISTER
# ---------------
# B7 : NU
# B6 : NU
# B5 : NU
# B4 : NU
# B3 : NU
# B2 : TX Idle
# B1 : RX Idle
# B0 : RX Valid

# ASCII CODES
# -----------
#
# Dec Hex Char                           Dec Hex Char      Dec Hex Char     Dec Hex Char
# ------------                           ------------      ------------     ------------
#  0  00  NUL (null)                      32  20  SPACE     64  40  @        96   60  `
#  1  01  SOH (start of heading)          33  21  !         65  41  A        97   61  a
#  2  02  STX (start of text)             34  22  "         66  42  B        98   62  b
#  3  03  ETX (end of text)               35  23  #         67  43  C        99   63  c
#  4  04  EOT (end of transmission)       36  24  $         68  44  D        100  64  d
#  5  05  ENQ (enquiry)                   37  25  %         69  45  E        101  65  e
#  6  06  ACK (acknowledge)               38  26  &         70  46  F        102  66  f
#  7  07  BEL (bell)                      39  27  '         71  47  G        103  67  g
#  8  08  BS  (backspace)                 40  28  (         72  48  H        104  68  h
#  9  09  TAB (horizontal tab)            41  29  )         73  49  I        105  69  i
# 10  0A  LF  (NL line feed, new line)    42  2A  *         74  4A  J        106  6A  j
# 11  0B  VT  (vertical tab)              43  2B  +         75  4B  K        107  6B  k
# 12  0C  FF  (NP form feed, new page)    44  2C  ,         76  4C  L        108  6C  l
# 13  0D  CR  (carriage return)           45  2D  -         77  4D  M        109  6D  m
# 14  0E  SO  (shift out)                 46  2E  .         78  4E  N        110  6E  n
# 15  0F  SI  (shift in)                  47  2F  /         79  4F  O        111  6F  o
# 16  10  DLE (data link escape)          48  30  0         80  50  P        112  70  p
# 17  11  DC1 (device control 1)          49  31  1         81  51  Q        113  71  q
# 18  12  DC2 (device control 2)          50  32  2         82  52  R        114  72  r
# 19  13  DC3 (device control 3)          51  33  3         83  53  S        115  73  s
# 20  14  DC4 (device control 4)          52  34  4         84  54  T        116  74  t
# 21  15  NAK (negative acknowledge)      53  35  5         85  55  U        117  75  u
# 22  16  SYN (synchronous idle)          54  36  6         86  56  V        118  76  v
# 23  17  ETB (end of trans. block)       55  37  7         87  57  W        119  77  w
# 24  18  CAN (cancel)                    56  38  8         88  58  X        120  78  x
# 25  19  EM  (end of medium)             57  39  9         89  59  Y        121  79  y
# 26  1A  SUB (substitute)                58  3A  :         90  5A  Z        122  7A  z
# 27  1B  ESC (escape)                    59  3B  ;         91  5B  [        123  7B  {
# 28  1C  FS  (file separator)            60  3C  <         92  5C  \        124  7C  |
# 29  1D  GS  (group separator)           61  3D  =         93  5D  ]        125  7D  }
# 30  1E  RS  (record separator)          62  3E  >         94  5E  ^        126  7E  ~
# 31  1F  US  (unit separator)            63  3F  ?         95  5F  _        127  7F  DEL

# TERMINAL COMMANDS
# -----------------
#
# Common serial port speeds 
# Bit rate (bit/s)  Time per bit (μs)  Common applications 
# ----------------  -----------------  -------------------
# 75 	            13333.3 	 	
# 110 	            9090.9 	     	   Bell 101 modem
# 134.5 	        7434.9 	  	
# 150 	            6666.6 	 	
# 300 	            3333.3 	       	   Bell 103 modem or V.21 modem
# 600 	            1666.7 	  	
# 1,200 	        833.3 	  	       Bell 202, Bell 212A, or V.22 modem
# 1,800 	        555.6 	  	
# 2,400 	        416.7 	  	       V.22bis modem
# 4,800 	        208.3 	     	   V.27ter modem
# 7,200 	        138.9 	  	
# 9,600 	        104.2 	  	       V.32 modem
# 14,400 	        69.4 	     	   V.32bis modem
# 19,200 	        52.1 	  	
# 31,250 	        32 	  	           MIDI port
# 38,400 	        26.0 	  	
# 56,000 	        17.9 	  	       V.90/V.92 modem
# 57,600 	        17.4 	  	       V.32bis modem with V.42bis compression   ****
# 76,800 	        13.0 	  	       BACnet MS/TP networks[20]
# 115,200 	        8.68 	  	       V.34 modem with V.42bis compression, 
#                                      low cost serial V.90/V.92 modem with V.42bis or V.44 compression 
#
# screen /dev/ttyS0 19200,cs8
# screen /dev/ttyUSB0 57600
#
# Screen Command 	  Task
# --------------      ----
# Ctrl+a c 	          Create new window
# Ctrl+a k 	          Kill the current window / session
# Ctrl+a w            List all windows
# Ctrl+a 0-9 	      Go to a window numbered 0 9, use Ctrl+a w to see number
# Ctrl+a Ctrl+a 	  Toggle / switch between the current and previous window
# Ctrl+a S 	          Split terminal horizontally into regions and press Ctrl+a c to create new window there
# Ctrl+a :resize 	  Resize region
# Ctrl+a :fit 	      Fit screen size to new terminal size. You can also hit Ctrl+a F for the the same task
# Ctrl+a :remove 	  Remove / delete region. You can also hit Ctrl+a X for the same taks
# Ctrl+a tab 	      Move to next region
# Ctrl+a D (Shift-d)  Power detach and logout
# Ctrl+a d 	          Detach but keep shell window open
# Ctrl-a Ctrl-\ 	  Quit screen
# Ctrl-a ? 	          Display help screen i.e. display a list of commands



# Main
# ----

start:
    move RA 0
    store RA txBufferIndex 

    movea( RA, welcome )           # set string address      
    store RA srcAddr         
    movea( RA, txBuffer )          # set buffer address
    store RA destAddr
    call strcpy 
    call txString

#   #############################
#   # vga single write dest reg #
#   #############################

#        x x r r g g b b x x r r g g b b
# 3030   0 0 1 1 0 0 0 0 0 0 1 1 0 0 0 0      red red
# 3000   0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0      red black
# 030C   0 0 0 0 0 0 1 1 0 0 0 0 1 1 0 0      blue green
# 333C   0 0 1 1 0 0 1 1 0 0 1 1 1 1 0 0      pink yellow     
# 3F0F   0 0 1 1 1 1 1 1 0 0 0 0 1 1 1 1      white turqoise

#   WRITE 3000

#   cpu_dest_reg
    movea( RA, CPU_DST_ADDR_REG )
    moved( RB, eval( ( ( 160 * 1 ) + 2 ) / 2 ) )
    store RB (RA)

#   cpu_data_in_reg
    movea( RA, CPU_DATA_IN_REG )
    moved( RB, 0x3000 )
    store RB (RA)

#   ctl reg
    movea( RA, CPU_CTL_REG )
    move RB WRITE_PIXEL
    store RB (RA)

#   WRITE 030C

#   cpu_dest_reg
    movea( RA, CPU_DST_ADDR_REG )
    moved( RB, eval( ( ( 160 * 1 ) + 4 ) / 2 ) )
    store RB (RA)

#   cpu_data_in_reg
    movea( RA, CPU_DATA_IN_REG )
    moved( RB, 0x030C )
    store RB (RA)

#   ctl reg
    movea( RA, CPU_CTL_REG )
    move RB WRITE_PIXEL
    store RB (RA)

#   WRITE 333C

#   cpu_dest_reg
    movea( RA, CPU_DST_ADDR_REG )
    moved( RB, eval( ( ( 160 * 1 ) + 6 ) / 2 ) )
    store RB (RA)

#   cpu_data_in_reg
    movea( RA, CPU_DATA_IN_REG )
    moved( RB, 0x333C )
    store RB (RA)

#   ctl reg
    movea( RA, CPU_CTL_REG )
    move RB WRITE_PIXEL
    store RB (RA)

#   WRITE 3F0F

#   cpu_dest_reg
    movea( RA, CPU_DST_ADDR_REG )
    moved( RB, eval( ( ( 160 * 1 ) + 8 ) / 2 ) )
    store RB (RA)

#   cpu_data_in_reg
    movea( RA, CPU_DATA_IN_REG )
    moved( RB, 0x3F0F )
    store RB (RA)

#   ctl reg
    movea( RA, CPU_CTL_REG )
    move RB WRITE_PIXEL
    store RB (RA)

trap:
    jump trap

# Copy string (must terminate with a \0)
# --------------------------------------
# Source / destination addresses passed in SRCADDR / DESTADDR

strcpy:
    load RA srcAddr          # get source address
    move RB RA
    load RA destAddr         # get destination address
    move RC RA 

strcpy_loop:              
    load RA (RB)             # load  char
    and RA 0xFF
    jumpz strcpy_exit        # exit if 0
    store RA (RC)            # copy
    add RB 1
    add RC 1
    jump strcpy_loop         # repeat

strcpy_exit:
    ret

# TX String (must terminate with a \0)
# ------------------------------------
# data in txBuffer written to serial port, blocking 

txString:
    movea( RB, txBuffer )  # get string address

tx_loop:              
    load RA (RB)             # load  char
    and RA 0xFF
    jumpz tx_exit            # exit if 0
    store RA UART_TX         # tx

waitTX:
    load RA UART_STATUS      # test TX status wait till 1
    and RA 0x04          
    jumpz waitTX    

    add RB 1                 # inc address
    jump tx_loop             # repeat

tx_exit:
    move RA 0
    store RA txBufferIndex
    ret

# Add NULL to tx string buffer
# ----------------------------

addNULL:
    load RA txBufferIndex 
    movea( RC, txBuffer )
    add RC RA 
    move RA 0
    store RA (RC)
    ret

# Add LF CR to tx string buffer
# ----------------------------

addLFCR:
    load RA txBufferIndex 
    movea( RC, txBuffer )
    add RC RA 
    add RA 2
    store RA txBufferIndex

    move RA 0x0A
    store RA (RC)
    add RC 1
    move RA 0x0D
    store RA (RC)
    ret

# Add SPACE to tx string buffer
# ----------------------------

addSPACE:
    load RA txBufferIndex 
    movea( RC, txBuffer )
    add RC RA 
    add RA 1
    store RA txBufferIndex

    move RA 0x20
    store RA (RC)
    ret

# Convert word into hexidecimal characters
# ----------------------------------------
# data to be convert in variable "word", characters written to txBuffer

word2Hex:
    load RA word
    asr RA
    asr RA
    asr RA
    asr RA
    asr RA
    asr RA
    asr RA
    asr RA
    store RA byte
    call byte2Hex

    load RA word
    and RA 0xFF
    store RA byte
    call byte2Hex

    ret

# Convert byte into hexidecimal characters
# ----------------------------------------
# data to be convert in variable "byte", characters written to txBuffer

byte2Hex:
    load RA txBufferIndex 
    movea( RC, txBuffer )
    add RC RA
    add RA 2
    store RA txBufferIndex

    movea( RB, nibble2HexTable )
    load RA byte
    and RA 0xF0
    asr RA
    asr RA
    asr RA
    asr RA
    add RB RA

    load RA (RB)
    store RA (RC)
    add RC 1

    movea( RB, nibble2HexTable )

    load RA byte
    and RA 0x0F
    add RB RA

    load RA (RB)
    store RA (RC)

    ret

# Convert byte into decimal characters
# ------------------------------------
# data to be convert in variable "byte", characters written to txBuffer

byte2Dec:
    load RA txBufferIndex 
    movea( RC, txBuffer )
    add RC RA
    add RA 3
    store RA txBufferIndex

    load RA byte
    and RA 0xFF
    move RB 0

byte2Dec_100s_loop:
    sub RA 100                   # sub 100
    jumpc byte2Dec_100s_exit     # yes, exit
    add RB 1                     # inc count 
    jump byte2Dec_100s_loop      # repeat

byte2Dec_100s_exit:
    add RB 0x30
    store RB (RC)
    add RC 1
    
    add RA 100                   # undo last sub
    move RB 0
 
byte2Dec_10s_loop:
    sub RA 10                    # sub 10
    jumpc byte2Dec_10s_exit      # yes, exit
    add RB 1                     # inc count 
    jump byte2Dec_10s_loop       # repeat

byte2Dec_10s_exit:
    add RB 0x30
    store RB (RC)
    add RC 1
    
    add RA 10                    # undo last sub
    add RA 0x30
    store RA (RC)

    ret

# RX TX Test
# ----------

rx_tx_test:
    load RA UART_STATUS      # has ASCII char been RX?
    and RA 0x01
    jumpz rx_tx_test         # no check again

    load RA UART_RX
    store RA UART_TX

rx_tx_waitTX:
    load RA UART_STATUS      # test TX status wait till 1
    and RA 0x04          
    jumpz rx_tx_waitTX    

    jump rx_tx_test          # repeat


# Software Delay
# --------------

delay:
    move RB 3 

delay_start:
    movea( RA, 0xFFF )

delay_loop:
    sub RA 1
    jumpnz delay_loop
    sub RB 1
    jumpnz delay_start

    ret

# System Variables 
# -----------------

count:
    .data 0

line:
    .data 0

# Convert Variables 
# -----------------

word:
    .data 0

byte:
    .data 0

# String Variables
# ----------------

srcAddr:
    .data 0x00

destAddr:
    .data 0x00

# Serial Port Variables
# ---------------------

txBufferIndex:
    .data 0x00

rxBufferIndex:
    .data 0x00

keyPressed:
    .data 0x00

txBuffer:
    space( 64 )

rxBuffer:
    space( 64 )

# Bin to Hex table
# ----------------

nibble2HexTable:
    .data 0x30    # '0'
    .data 0x31    # '1' 
    .data 0x32    # '2'
    .data 0x33    # '3' 
    .data 0x34    # '4'
    .data 0x35    # '5' 
    .data 0x36    # '6'
    .data 0x37    # '7' 
    .data 0x38    # '8'
    .data 0x39    # '9' 
    .data 0x41    # 'A'
    .data 0x42    # 'B' 
    .data 0x43    # 'C'
    .data 0x44    # 'D' 
    .data 0x45    # 'E'
    .data 0x46    # 'F' 

# Test String
# -----------

hello:
    .data 0x48    # H
    .data 0x65    # e
    .data 0x6C    # l
    .data 0x6C    # l
    .data 0x6F    # 0
    .data 0x20    # SPACE
    .data 0x57    # W
    .data 0x6F    # o
    .data 0x72    # r
    .data 0x6C    # l
    .data 0x64    # d
    .data 0x0A    # LF
    .data 0x0D    # CR
    .data 0x00    # NULL

# Welcome string
# --------------

welcome:
    .data 0x0A    # LF
    .data 0x0D    # CR
    .data 0x53    # S
    .data 0x69    # i
    .data 0x6D    # m
    .data 0x70    # p
    .data 0x6C    # l
    .data 0x65    # e
    .data 0x43    # C
    .data 0x50    # P
    .data 0x55    # U
    .data 0x20    # SPACE
    .data 0x44    # D
    .data 0x65    # e
    .data 0x62    # b
    .data 0x75    # u
    .data 0x67    # g
    .data 0x0A    # LF
    .data 0x0D    # CR
    .data 0x00    # NULL


