aboutsummaryrefslogtreecommitdiff
path: root/examples/example3b_spi_tclasm/instructions.s.tcl
blob: 294a73e72a42ccf341d7f3b5f3fbe228367666a4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
### Relevant addresses:
### * h140000 - h1401FF - SPI data transfer memory
### * h140200 - h140201 - SPI bytes_to_output reg
### * h140202 - h140203 - SPI bytes_to_receive reg
### * h140204 - h140207 - SPI operating reg
### * h1C0008 - h1C0009 - low bits of timer reg
### * h100000 - h1009FF - VGA text memory
### * h100A00 - h100A01 - VGA power-on register
### * h1C0006 - h1C0007 - LED2 register

### The bitstream binary itself is 135100 bytes big. We append our data
### at the and of this binary file, so it can later be found at address
### 135100 on the flash chip.

set_sp h100000;                  # 2 16-bit instructions

### power up flash ship
## set bytes_to_output to 1
const 1;                         # 1 16-bit instruction
storew h140200;                  # 2 16-bit instructions
## set bytes_to_receive to 0
const 0;                         # 1 16-bit instruction
storew h140202;                  # 2 16-bit instructions
## release power-down SPI command
const 0xAB;                      # 2 16-bit instructions
storeb h140000;                  # 2 16-bit instructions
## start SPI operation
const 1;                         # 1 16-bit instruction
storew h140204;                  # 2 16-bit instructions

### wait for at least 3000 ns after command gets sent
## reset the timer
const 0;                         # 1 16-bit instruction
storew h1C0008;                  # 2 16-bit instructions

## loop until 45 ticks pass; 45 ticks is 3600 ns; additional 600ns is enough
## for power-up command to be sent
# there were 18 16-bit instructions up to this point, so loop address is 36
loadwzx h1C0008;                 # 2 16-bit instructions
const 45;                        # 1 16-bit instruction
lt;                              # 1 16-bit instruction
cond_jump 36;                    # 1 16-bit instruction

### we'll transfer a total of 2400 bytes by making 5 transfers of 480 bytes;
### our SPI peripheral is capable of transfering at most 511 bytes in one go
## initialize transfers counter
const 0;                         # 1 16-bit instruction
storew h080000;                  # 2 16-bit instructions

### transfers loop starts here, it'll execute 5 times
# there were 26 16-bit instructions up to this point, so loop address is 52
### read 480 bytes from SPI
## set bytes_to_output to 5
const 5;                         # 1 16-bit instruction
storew h140200;                  # 2 16-bit instructions
## set bytes_to_receive to 480
const 480;                       # 2 16-bit instructions
storew h140202;                  # 2 16-bit instructions
## fast read SPI command
const 0x0B;                      # 1 16-bit instruction
storeb h140000;                  # 2 16-bit instructions
## prepare address; 135100 is base address of our data inside flash memory
const 135100;                    # 2 16-bit instructions
## compute the offset of bytes, that have already been read
loadwzx h080000;                 # 2 16-bit instructions
const 480;                       # 2 16-bit instructions
mul;                             # 1 16-bit instruction
## also store the computed offset for later
storew h080002;                  # 2 16-bit instructions
## add the offset
loadwzx h080002;                 # 2 16-bit instructions
add;                             # 1 16-bit instruction
## store the address in big endian
store h080008;                   # 2 16-bit instructions
load h080008;                    # 2 16-bit instructions
const 256;                       # 2 16-bit instructions
div;                             # 1 16-bit instruction
storew h140002;                  # 2 16-bit instructions
load h080008;                    # 2 16-bit instructions
storeb h140003;                  # 2 16-bit instructions
load h080008;                    # 2 16-bit instructions
const 65536;                     # 2 16-bit instructions
div;                             # 1 16-bit instruction
storeb h140001;                  # 2 16-bit instructions
## start SPI operation
const 1;                         # 1 16-bit instruction
storew h140204;                  # 2 16-bit instructions

### force wait for operation completion
const 0;                         # 1 16-bit instruction
storew h140200;                  # 2 16-bit instructions

### assume data to be ascii characters and print it to screen
### initialize index to 0
const 0;                         # 1 16-bit instruction
storew h080004;                  # 2 16-bit instructions

## print characters in a loop
# there were 77 16-bit instructions up to this point, so loop address is 154
## load current index value, get 2 copies of it, add offset to one copy
loadwzx h080004
loadwzx h080002
add
loadwzx h080004
## load 4 bytes from SPI memory
load+ h140000
## write to VGA memory
store+ h100000
## increase index
loadwzx h080004
const 4
add
storew h080004
## compare index to 479
loadwzx h080004
const 479
lt
cond_jump 154

## increase transfers count
loadwzx h080000
const 1
add
storew h080000

## switch LED2
loadwzx h080000
const 2
rem
storew h1C0006

## if less than 5 transfers were done, continue with another one
loadwzx h080000
const 5
lt
cond_jump 52

### after loops, start generating VGA output
const -1
store h100A00

halt