├── Makefile
├── README.md
├── fpga
├── papilio-pro-j1.xise
├── papilio_pro_j1.bit
├── src
│ ├── Rxunit.vhd
│ ├── Txunit.vhd
│ ├── clock.vhd
│ ├── j1.v
│ ├── miniuart.vhd
│ ├── papilio-pro-j1.vhd
│ ├── papilio-pro.ucf
│ └── utils.vhd
└── test
│ ├── miniuart2_tb.vhd
│ └── papilio_pro_j1_tb.vhd
├── ipv4.4th
├── j1.4th
└── j1.c
/Makefile:
--------------------------------------------------------------------------------
1 | all: j1 j1.bin j1.hex
2 |
3 | j1: j1.c
4 | gcc -o j1 j1.c -lwpcap
5 | strip -s j1
6 | j1.bin j1.hex: j1.4th
7 | gforth ./j1.4th
8 | run: all
9 | ./j1
10 | core: all
11 | ./j1 core.4th
12 | clean:
13 | rm -rf j1 j1.bin j1.hex
14 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | eForth for the J1 Simulator and actual J1 FPGAs
2 | -------------
3 |
4 | J1 eForth is an interactive work-in-progress Forth designed to run on the [James Bowman's J1 FPGA soft core][j1]
5 | (see also [J1 on Github][J1github]). There is a Forth cross compiler written in Forth to
6 | generate the interactice J1 eForth system, and a J1 simulator written in C to run J1 eForth simulated
7 | on a PC.
8 |
9 | J1 eForth also runs on actual J1 FPGAs. It has been ported to the [Papilio Pro][pappro] FPGA board,
10 | where it executes Forth program at 66 MHz. It communicates with a host system using a serial line at a
11 | default speed of 115200 Bits/s.
12 |
13 | ### Prerequisites
14 |
15 | - [GNU make][gmake] (optional) for job control
16 | - [gforth][gforth] for cross compiling / generating the J1 eForth image
17 | - [WpdPack][pcap] for network simulation
18 |
19 | If you want to run J1 eForth simulated on a PC:
20 |
21 | - [gcc][gcc] to compile the J1 simulator
22 |
23 | If you want to run J1 eForth on a J1 in an FPGA:
24 |
25 | - [Xilinx ISE][xilinxise] to generate the FPGA bit stream (ISE 14.7)
26 | - [Papilio-Loader][paploader] to download the bitstream to the FPGA
27 |
28 | ### Directry Structure
29 |
30 | j1eforth
31 | ├── README.MD
32 | ├── j1.4th cross compiler with J1 eForth
33 | ├── j1.c J1 simulator
34 | └── fpga
35 | ├── src Verilog projects for J1 and UART (miniuart2) for Papilio Pro
36 | └── test testbenches
37 |
38 | ### Building and running the j1 Simulator
39 | #### Compiling using gcc Mingw (Windows)
40 |
41 | gcc j1.c -o -lwpcap j1.exe
42 |
43 | #### Creating flash image j1.bin (and j1.hex)
44 |
45 | gforth j1.4th
46 | #### Running the Simulator
47 |
48 | j1.exe [optional argument]
49 |
50 | The argument to the simulator is an optional forth file that can be used to extend the dictionary
51 | and is passed to the simulator as the first argument during startup
52 |
53 | Words to test in the simulator :
54 |
55 | [ see , ' , compile , [compile] , ?branch , branch , call, .. and many more ]
56 |
57 | Have fun , modify and pass on
58 |
59 | ### Running on Real Hardware
60 |
61 | J1 eForth can run on an actual j1 FPGA. It has been ported to the [Papilio Pro][pappro] FPGA board.
62 |
63 | #### Create the J1 bit stream:
64 |
65 | Start Xilinx ise on project `vhdl/papiolo-pro-j1.xise`
66 | choose `Generate Programming File` on the `papilio_pro_j1` component. This generates `papilio_pro_j1.bit`
67 | including the Forth image (`j1.hex`) as initial memory (built before when generating the flash image).
68 |
69 | #### Load the complete bit stream (J1 and memory) into the FPGA:
70 |
71 | sudo papilio-prog -v -f papilio_pro_j1.bit
72 |
73 | You might want to use the pre-built `pipilio_pro_j1.bit` for a quick start.
74 |
75 | #### Connect to J1 eForth:
76 |
77 | screen /dev/tty.usbserial 115200
78 |
79 | or similar. J1 eForth should show the prompt
80 |
81 | eForth j1 v1.04
82 | ok
83 |
84 | If you only see the **`ok`** prompts issue a **`cold`** and press the enter key to reboot the system.
85 |
86 |
87 | ### May the Forth be with you.
88 |
89 | [pappro]: http://papilio.cc/index.php?n=Papilio.PapilioPro
90 | [paploader]: http://papilio.cc/index.php?n=Papilio.PapilioLoaderV2
91 | [pcap]: http://www.winpcap.org/archive/4.1.1-WpdPack.zip
92 | [j1]: http://www.excamera.com/sphinx/fpga-j1.html
93 | [j1github]: https://github.com/jamesbowman/j1
94 |
95 | [gmake]: https://www.gnu.org/software/make/
96 | [gcc]: https://gcc.gnu.org/
97 | [gforth]: https://www.gnu.org/software/gforth/
98 |
99 | [xilinxise]: http://www.xilinx.com/products/design-tools/ise-design-suite/ise-webpack.html
100 |
--------------------------------------------------------------------------------
/fpga/papilio-pro-j1.xise:
--------------------------------------------------------------------------------
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 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 |
318 |
319 |
320 |
321 |
322 |
323 |
324 |
325 |
326 |
327 |
328 |
329 |
330 |
331 |
332 |
333 |
334 |
335 |
336 |
337 |
338 |
339 |
340 |
341 |
342 |
343 |
344 |
345 |
346 |
347 |
348 |
349 |
350 |
351 |
352 |
353 |
354 |
355 |
356 |
357 |
358 |
359 |
360 |
361 |
362 |
363 |
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 |
372 |
373 |
374 |
375 |
376 |
377 |
378 |
379 |
380 |
381 |
382 |
383 |
384 |
385 |
386 |
387 |
388 |
389 |
390 |
391 |
392 |
393 |
394 |
395 |
396 |
397 |
398 |
399 |
400 |
401 |
402 |
403 |
404 |
405 |
406 |
407 |
408 |
409 |
410 |
411 |
412 |
413 |
414 |
415 |
416 |
417 |
418 |
419 |
420 |
421 |
422 |
423 |
--------------------------------------------------------------------------------
/fpga/papilio_pro_j1.bit:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/samawati/j1eforth/49ea12b33191929dd166becb2905e498dec93774/fpga/papilio_pro_j1.bit
--------------------------------------------------------------------------------
/fpga/src/Rxunit.vhd:
--------------------------------------------------------------------------------
1 | -------------------------------------------------------------------------------
2 | -- Title : UART
3 | -- Project : UART
4 | -------------------------------------------------------------------------------
5 | -- File : Rxunit.vhd
6 | -- Author : Philippe CARTON
7 | -- (philippe.carton2@libertysurf.fr)
8 | -- Organization:
9 | -- Created : 15/12/2001
10 | -- Last update : 8/1/2003
11 | -- Platform : Foundation 3.1i
12 | -- Simulators : ModelSim 5.5b
13 | -- Synthesizers: Xilinx Synthesis
14 | -- Targets : Xilinx Spartan
15 | -- Dependency : IEEE std_logic_1164
16 | -------------------------------------------------------------------------------
17 | -- Description: RxUnit is a serial to parallel unit Receiver.
18 | -------------------------------------------------------------------------------
19 | -- Copyright (c) notice
20 | -- This core adheres to the GNU public license
21 | --
22 | -------------------------------------------------------------------------------
23 | -- Revisions :
24 | -- Revision Number :
25 | -- Version :
26 | -- Date :
27 | -- Modifier : name
28 | -- Description :
29 | --
30 | ------------------------------------------------------------------------------
31 | library ieee;
32 | use ieee.std_logic_1164.all;
33 |
34 | entity RxUnit is
35 | port (
36 | Clk : in std_logic; -- system clock signal
37 | Reset : in std_logic; -- Reset input
38 | Enable : in std_logic; -- Enable input
39 | ReadA : in Std_logic; -- Async Read Received Byte
40 | RxD : in std_logic; -- RS-232 data input
41 | RxAv : out std_logic; -- Byte available
42 | DataO : out std_logic_vector(7 downto 0)); -- Byte received
43 | end RxUnit;
44 |
45 | architecture Behaviour of RxUnit is
46 | signal RReg : std_logic_vector(7 downto 0); -- receive register
47 | signal RRegL : std_logic; -- Byte received
48 | begin
49 | -- RxAv process
50 | RxAvProc : process(RRegL,Reset,ReadA)
51 | begin
52 | if ReadA = '1' or Reset = '1' then
53 | RxAv <= '0'; -- Negate RxAv when RReg read
54 | elsif Rising_Edge(RRegL) then
55 | RxAv <= '1'; -- Assert RxAv when RReg written
56 | end if;
57 | end process;
58 |
59 | -- Rx Process
60 | RxProc : process(Clk,Reset,Enable,RxD,RReg)
61 | variable BitPos : INTEGER range 0 to 10; -- Position of the bit in the frame
62 | variable SampleCnt : INTEGER range 0 to 3; -- Count from 0 to 3 in each bit
63 | begin
64 | if Reset = '1' then -- Reset
65 | RRegL <= '0';
66 | BitPos := 0;
67 | elsif Rising_Edge(Clk) then
68 | if Enable = '1' then
69 | case BitPos is
70 | when 0 => -- idle
71 | RRegL <= '0';
72 | if RxD = '0' then -- Start Bit
73 | SampleCnt := 0;
74 | BitPos := 1;
75 | end if;
76 | when 10 => -- Stop Bit
77 | BitPos := 0; -- next is idle
78 | RRegL <= '1'; -- Indicate byte received
79 | DataO <= RReg; -- Store received byte
80 | when others =>
81 | if (SampleCnt = 1 and BitPos >= 2) then -- Sample RxD on 1
82 | RReg(BitPos-2) <= RxD; -- Deserialisation
83 | end if;
84 | if SampleCnt = 3 then -- Increment BitPos on 3
85 | BitPos := BitPos + 1;
86 | end if;
87 | end case;
88 | if SampleCnt = 3 then
89 | SampleCnt := 0;
90 | else
91 | sampleCnt := SampleCnt + 1;
92 | end if;
93 |
94 | end if;
95 | end if;
96 | end process;
97 | end Behaviour;
98 |
--------------------------------------------------------------------------------
/fpga/src/Txunit.vhd:
--------------------------------------------------------------------------------
1 | -------------------------------------------------------------------------------
2 | -- Title : UART
3 | -- Project : UART
4 | -------------------------------------------------------------------------------
5 | -- File : Txunit.vhd
6 | -- Author : Philippe CARTON
7 | -- (philippe.carton2@libertysurf.fr)
8 | -- Organization:
9 | -- Created : 15/12/2001
10 | -- Last update : 8/1/2003
11 | -- Platform : Foundation 3.1i
12 | -- Simulators : ModelSim 5.5b
13 | -- Synthesizers: Xilinx Synthesis
14 | -- Targets : Xilinx Spartan
15 | -- Dependency : IEEE std_logic_1164
16 | -------------------------------------------------------------------------------
17 | -- Description: Txunit is a parallel to serial unit transmitter.
18 | -------------------------------------------------------------------------------
19 | -- Copyright (c) notice
20 | -- This core adheres to the GNU public license
21 | --
22 | -------------------------------------------------------------------------------
23 | -- Revisions :
24 | -- Revision Number :
25 | -- Version :
26 | -- Date :
27 | -- Modifier : name
28 | -- Description :
29 | --
30 | ------------------------------------------------------------------------------
31 |
32 | library ieee;
33 | use ieee.std_logic_1164.all;
34 |
35 | entity TxUnit is
36 | port (
37 | Clk : in std_logic; -- Clock signal
38 | Reset : in std_logic; -- Reset input
39 | Enable : in std_logic; -- Enable input
40 | LoadA : in std_logic; -- Asynchronous Load
41 | TxD : out std_logic; -- RS-232 data output
42 | Busy : out std_logic; -- Tx Busy
43 | DataI : in std_logic_vector(7 downto 0)); -- Byte to transmit
44 | end TxUnit;
45 |
46 | architecture Behaviour of TxUnit is
47 |
48 | component synchroniser
49 | port (
50 | C1 : in std_logic; -- Asynchronous signal
51 | C : in std_logic; -- Clock
52 | O : out Std_logic);-- Synchronised signal
53 | end component;
54 |
55 | signal TBuff : std_logic_vector(7 downto 0); -- transmit buffer
56 | signal TReg : std_logic_vector(7 downto 0); -- transmit register
57 | signal TBufL : std_logic; -- Buffer loaded
58 | signal LoadS : std_logic; -- Synchronised load signal
59 |
60 | begin
61 | -- Synchronise Load on Clk
62 | SyncLoad : Synchroniser port map (LoadA, Clk, LoadS);
63 | Busy <= LoadS or TBufL;
64 |
65 | -- Tx process
66 | TxProc : process(Clk, Reset, Enable, DataI, TBuff, TReg, TBufL)
67 | variable BitPos : INTEGER range 0 to 10; -- Bit position in the frame
68 | begin
69 | if Reset = '1' then
70 | TBufL <= '0';
71 | BitPos := 0;
72 | TxD <= '1';
73 | elsif Rising_Edge(Clk) then
74 | if LoadS = '1' then
75 | TBuff <= DataI;
76 | TBufL <= '1';
77 | end if;
78 | if Enable = '1' then
79 | case BitPos is
80 | when 0 => -- idle or stop bit
81 | TxD <= '1';
82 | if TBufL = '1' then -- start transmit. next is start bit
83 | TReg <= TBuff;
84 | TBufL <= '0';
85 | BitPos := 1;
86 | end if;
87 | when 1 => -- Start bit
88 | TxD <= '0';
89 | BitPos := 2;
90 | when others =>
91 | TxD <= TReg(BitPos-2); -- Serialisation of TReg
92 | BitPos := BitPos + 1;
93 | end case;
94 | if BitPos = 10 then -- bit8. next is stop bit
95 | BitPos := 0;
96 | end if;
97 | end if;
98 | end if;
99 | end process;
100 | end Behaviour;
101 |
--------------------------------------------------------------------------------
/fpga/src/clock.vhd:
--------------------------------------------------------------------------------
1 | library ieee;
2 | use ieee.std_logic_1164.ALL;
3 | use ieee.numeric_std.ALL;
4 | library UNISIM;
5 | use UNISIM.Vcomponents.ALL;
6 |
7 | entity clock is
8 | port ( clk_in : in std_logic;
9 | clk : out std_logic;
10 | clk180 : out std_logic);
11 | end clock;
12 |
13 | architecture BEHAVIORAL of clock is
14 |
15 | signal CLKFB_IN : std_logic;
16 | signal CLKFX_BUF : std_logic;
17 | signal CLKFX180_BUF : std_logic;
18 | signal CLKIN_IBUFG : std_logic;
19 | signal CLK2X_BUF : std_logic;
20 |
21 | begin
22 |
23 | CLKFX_BUFG_INST : BUFG
24 | port map (I=>CLKFX_BUF,
25 | O=>clk);
26 |
27 | CLKFX180_BUFG_INST : BUFG
28 | port map (I=>CLKFX180_BUF,
29 | O=>clk180);
30 |
31 | CLKIN_IBUFG_INST : IBUFG
32 | port map (I=>clk_in,
33 | O=>CLKIN_IBUFG);
34 |
35 | CLK2X_BUFG_INST : BUFG
36 | port map (I=>CLK2X_BUF,
37 | O=>CLKFB_IN);
38 |
39 | DCM_SP_INST : DCM_SP
40 | generic map(
41 | CLK_FEEDBACK => "2X",
42 | CLKDV_DIVIDE => 4.0,
43 | CLKFX_DIVIDE => 1,
44 | CLKFX_MULTIPLY => 2,
45 | CLKIN_DIVIDE_BY_2 => FALSE,
46 | CLKIN_PERIOD => 31.250,
47 | CLKOUT_PHASE_SHIFT => "NONE",
48 | DESKEW_ADJUST => "SYSTEM_SYNCHRONOUS",
49 | DFS_FREQUENCY_MODE => "LOW",
50 | DLL_FREQUENCY_MODE => "LOW",
51 | DUTY_CYCLE_CORRECTION=> TRUE,
52 | FACTORY_JF => x"C080",
53 | PHASE_SHIFT => 0,
54 | STARTUP_WAIT => TRUE)
55 | port map (
56 | CLKIN => CLKIN_IBUFG,
57 | CLKFB => CLKFB_IN,
58 | DSSEN => '0',
59 | PSCLK => '0',
60 | PSEN => '0',
61 | PSINCDEC => '0',
62 | RST => '0',
63 | CLKDV => open,
64 | CLKFX => CLKFX_BUF,
65 | CLKFX180 => CLKFX180_BUF,
66 | CLK2X => CLK2X_BUF,
67 | CLK2X180 => open,
68 | CLK0 => open,
69 | CLK90 => open,
70 | CLK180 => open,
71 | CLK270 => open,
72 | LOCKED => open,
73 | PSDONE => open,
74 | STATUS => open);
75 |
76 | end BEHAVIORAL;
77 |
78 |
79 |
--------------------------------------------------------------------------------
/fpga/src/j1.v:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2011
3 | James Bowman All rights reserved.
4 |
5 | Redistribution and use in source and binary forms, with or without
6 | modification, are permitted provided that the following conditions
7 | are met:
8 | 1. Redistributions of source code must retain the above copyright
9 | notice, this list of conditions and the following disclaimer.
10 | 2. Redistributions in binary form must reproduce the above copyright
11 | notice, this list of conditions and the following disclaimer in the
12 | documentation and/or other materials provided with the distribution.
13 | 3. Neither the name of James Bowman nor the names of its contributors
14 | may be used to endorse or promote products derived from this software
15 | without specific prior written permission.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 | ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
20 | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
21 | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
24 | USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
27 | OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 | SUCH DAMAGE.
29 | */
30 |
31 | module j1(
32 | input sys_clk_i, input sys_rst_i, input [15:0] io_din,
33 | output io_rd, output io_wr, output [15:0] io_addr, output [15:0] io_dout);
34 |
35 | reg [15:0] insn;
36 | wire [15:0] immediate = { 1'b0, insn[14:0] };
37 |
38 | reg [4:0] dsp; // Data stack pointer
39 | reg [4:0] _dsp;
40 | reg [15:0] st0; // Return stack pointer
41 | reg [15:0] _st0;
42 | wire _dstkW; // D stack write
43 |
44 | reg [12:0] pc;
45 | reg [12:0] _pc;
46 | reg [4:0] rsp;
47 | reg [4:0] _rsp;
48 | reg _rstkW; // R stack write
49 | reg [15:0] _rstkD;
50 | wire _ramWE; // RAM write enable
51 |
52 | wire [15:0] pc_plus_1;
53 | assign pc_plus_1 = pc + 1;
54 |
55 | // The D and R stacks
56 | reg [15:0] dstack[0:31];
57 | reg [15:0] rstack[0:31];
58 | always @(posedge sys_clk_i)
59 | begin
60 | if (_dstkW)
61 | dstack[_dsp] = st0;
62 | if (_rstkW)
63 | rstack[_rsp] = _rstkD;
64 | end
65 | wire [15:0] st1 = dstack[dsp];
66 | wire [15:0] rst0 = rstack[rsp];
67 |
68 | // st0sel is the ALU operation. For branch and call the operation
69 | // is T, for 0branch it is N. For ALU ops it is loaded from the instruction
70 | // field.
71 | reg [3:0] st0sel;
72 | always @*
73 | begin
74 | case (insn[14:13])
75 | 2'b00: st0sel = 0; // ubranch
76 | 2'b10: st0sel = 0; // call
77 | 2'b01: st0sel = 1; // 0branch
78 | 2'b11: st0sel = insn[11:8]; // ALU
79 | default: st0sel = 4'bxxxx;
80 | endcase
81 | end
82 |
83 |
84 | // Papilio Pro: main memory to be infered instead of specified explitely.
85 | reg [15:0] ram[0:16383]; initial $readmemh("../j1.hex", ram);
86 |
87 | reg [15:0] mem_din;
88 | always @(posedge sys_clk_i) begin
89 | // $monitor("insn_addr= %h, insn = %h, sp=%h, rp=%h, S=%h %h", pc, insn, dsp, rsp, st1, st0);
90 | insn <= ram[_pc];
91 | mem_din <= ram[_st0[15:1]];
92 | if (_ramWE & (_st0[15:14] ==0))
93 | ram[_st0[15:1]] <= st1[15:0];
94 | end
95 |
96 |
97 | // Compute the new value of T.
98 | always @*
99 | begin
100 | if (insn[15])
101 | _st0 = immediate;
102 | else
103 | case (st0sel)
104 | 4'b0000: _st0 = st0;
105 | 4'b0001: _st0 = st1;
106 | 4'b0010: _st0 = st0 + st1;
107 | 4'b0011: _st0 = st0 & st1;
108 | 4'b0100: _st0 = st0 | st1;
109 | 4'b0101: _st0 = st0 ^ st1;
110 | 4'b0110: _st0 = ~st0;
111 | 4'b0111: _st0 = {16{(st1 == st0)}};
112 | 4'b1000: _st0 = {16{($signed(st1) < $signed(st0))}};
113 | 4'b1001: _st0 = st1 >> st0[3:0];
114 | 4'b1010: _st0 = st0 - 1;
115 | 4'b1011: _st0 = rst0;
116 | 4'b1100: _st0 = |st0[15:14] ? io_din : mem_din;
117 | 4'b1101: _st0 = st1 << st0[3:0];
118 | 4'b1110: _st0 = {rsp, 3'b000, dsp};
119 | 4'b1111: _st0 = {16{(st1 < st0)}};
120 | default: _st0 = 16'hxxxx;
121 | endcase
122 | end
123 |
124 | wire is_alu = (insn[15:13] == 3'b011);
125 | wire is_lit = (insn[15]);
126 |
127 | assign io_rd = (is_alu & (insn[11:8] == 4'hc));
128 | assign io_wr = _ramWE;
129 | assign io_addr = st0;
130 | assign io_dout = st1;
131 |
132 | assign _ramWE = is_alu & insn[5];
133 | assign _dstkW = is_lit | (is_alu & insn[7]);
134 |
135 | wire [1:0] dd = insn[1:0]; // D stack delta
136 | wire [1:0] rd = insn[3:2]; // R stack delta
137 |
138 | always @*
139 | begin
140 | if (is_lit) begin // literal
141 | _dsp = dsp + 1;
142 | _rsp = rsp;
143 | _rstkW = 0;
144 | _rstkD = _pc;
145 | end else if (is_alu) begin
146 | _dsp = dsp + {dd[1], dd[1], dd[1], dd};
147 | _rsp = rsp + {rd[1], rd[1], rd[1], rd};
148 | _rstkW = insn[6];
149 | _rstkD = st0;
150 | end else begin // jump/call
151 | // predicated jump is like DROP
152 | if (insn[15:13] == 3'b001) begin
153 | _dsp = dsp - 1;
154 | end else begin
155 | _dsp = dsp;
156 | end
157 | if (insn[15:13] == 3'b010) begin // call
158 | _rsp = rsp + 1;
159 | _rstkW = 1;
160 | _rstkD = {pc_plus_1[14:0], 1'b0};
161 | end else begin
162 | _rsp = rsp;
163 | _rstkW = 0;
164 | _rstkD = _pc;
165 | end
166 | end
167 | end
168 |
169 | always @*
170 | begin
171 | if (sys_rst_i)
172 | _pc = pc;
173 | else
174 | if ((insn[15:13] == 3'b000) |
175 | ((insn[15:13] == 3'b001) & (|st0 == 0)) |
176 | (insn[15:13] == 3'b010))
177 | _pc = insn[12:0];
178 | else if (is_alu & insn[12])
179 | _pc = rst0[15:1];
180 | else
181 | _pc = pc_plus_1;
182 | end
183 |
184 | always @(posedge sys_clk_i)
185 | begin
186 | if (sys_rst_i) begin
187 | pc <= 0;
188 | dsp <= 0;
189 | st0 <= 0;
190 | rsp <= 0;
191 | end else begin
192 | dsp <= _dsp;
193 | pc <= _pc;
194 | st0 <= _st0;
195 | rsp <= _rsp;
196 | end
197 | end
198 |
199 | endmodule // j1
200 |
--------------------------------------------------------------------------------
/fpga/src/miniuart.vhd:
--------------------------------------------------------------------------------
1 | -------------------------------------------------------------------------------
2 | -- Title : MINIUART2 -- this is a modified version without Wishbone interface
3 | -- Project : MINIUART2
4 | -------------------------------------------------------------------------------
5 | -- File : MiniUart.vhd
6 | -- Author : Philippe CARTON
7 | -- (philippe.carton2@libertysurf.fr)
8 | -- Organization:
9 | -- Created : 15/12/2001
10 | -- Last update : 8/1/2003
11 | -- Platform : Foundation 3.1i
12 | -- Simulators : ModelSim 5.5b
13 | -- Synthesizers: Xilinx Synthesis
14 | -- Targets : Xilinx Spartan
15 | -- Dependency : IEEE std_logic_1164, Rxunit.vhd, Txunit.vhd, utils.vhd
16 | -------------------------------------------------------------------------------
17 | -- Description: Uart (Universal Asynchronous Receiver Transmitter) for SoC.
18 | -- Wishbone compatable.
19 | -------------------------------------------------------------------------------
20 | -- Copyright (c) notice
21 | -- This core adheres to the GNU public license
22 | --
23 | -------------------------------------------------------------------------------
24 | -- Revisions :
25 | -- Revision Number :
26 | -- Version :
27 | -- Date :
28 | -- Modifier : name
29 | -- Description :
30 | --
31 | -------------------------------------------------------------------------------
32 | -- Revision History:
33 | -- 2014-12-19: removed wishbone interface (uh@xlerb.de)
34 |
35 |
36 | library ieee;
37 | use ieee.std_logic_1164.all;
38 |
39 | entity MINIUART2 is
40 | generic(BRDIVISOR: INTEGER range 0 to 65535 := 143); -- Baud rate divisor 143 = 115200 at 66 Mhz
41 | port (
42 | clk: in STD_LOGIC;
43 | rst: in STD_LOGIC;
44 | rx: in STD_LOGIC;
45 | tx: out STD_LOGIC;
46 | io_rd: in STD_LOGIC;
47 | io_wr: in STD_LOGIC;
48 | io_addr: in STD_LOGIC;
49 | io_din: in STD_LOGIC_VECTOR (15 downto 0);
50 | io_dout: out STD_LOGIC_VECTOR (15 downto 0));
51 | end MINIUART2;
52 |
53 | -- Architecture for UART for synthesis
54 | architecture Behaviour of MINIUART2 is
55 |
56 | component Counter
57 | generic(COUNT: INTEGER range 0 to 65535); -- Count revolution
58 | port (
59 | Clk : in std_logic; -- Clock
60 | Reset : in std_logic; -- Reset input
61 | CE : in std_logic; -- Chip Enable
62 | O : out std_logic); -- Output
63 | end component;
64 |
65 | component RxUnit
66 | port (
67 | Clk : in std_logic; -- system clock signal
68 | Reset : in std_logic; -- Reset input
69 | Enable : in std_logic; -- Enable input
70 | ReadA : in Std_logic; -- Async Read Received Byte
71 | RxD : in std_logic; -- RS-232 data input
72 | RxAv : out std_logic; -- Byte available
73 | DataO : out std_logic_vector(7 downto 0)); -- Byte received
74 | end component;
75 |
76 | component TxUnit
77 | port (
78 | Clk : in std_logic; -- Clock signal
79 | Reset : in std_logic; -- Reset input
80 | Enable : in std_logic; -- Enable input
81 | LoadA : in std_logic; -- Asynchronous Load
82 | TxD : out std_logic; -- RS-232 data output
83 | Busy : out std_logic; -- Tx Busy
84 | DataI : in std_logic_vector(7 downto 0)); -- Byte to transmit
85 | end component;
86 |
87 | signal RxData : std_logic_vector(7 downto 0); -- Last Byte received
88 | signal TxData : std_logic_vector(7 downto 0); -- Last bytes transmitted
89 | signal SReg : std_logic_vector(7 downto 0); -- Status register
90 | signal EnabRx : std_logic; -- Enable RX unit
91 | signal EnabTx : std_logic; -- Enable TX unit
92 | signal RxAv : std_logic; -- Data Received
93 | signal TxBusy : std_logic; -- Transmiter Busy
94 | signal ReadA : std_logic; -- Async Read receive buffer
95 | signal LoadA : std_logic; -- Async Load transmit buffer
96 | signal Sig0 : std_logic; -- gnd signal
97 | signal Sig1 : std_logic; -- vcc signal
98 |
99 |
100 | begin
101 | sig0 <= '0';
102 | sig1 <= '1';
103 | Uart_Rxrate : Counter -- Baud Rate adjust
104 | generic map (COUNT => BRDIVISOR)
105 | port map (clk, rst, sig1, EnabRx);
106 | Uart_Txrate : Counter -- 4 Divider for Tx
107 | generic map (COUNT => 4)
108 | port map (clk, rst, EnabRx, EnabTx);
109 | Uart_TxUnit : TxUnit port map (clk, rst, EnabTX, LoadA, tx, TxBusy, TxData);
110 | Uart_RxUnit : RxUnit port map (clk, rst, EnabRX, ReadA, rx, RxAv, RxData);
111 |
112 | -- status register
113 | SReg(0) <= RxAv;
114 | SReg(1) <= TxBusy;
115 | SReg(7 downto 2) <= (others => '0'); -- the rest is silence
116 |
117 | process (clk, rst, io_addr, io_wr, io_din)
118 | begin
119 | if Rising_Edge(clk) then
120 | if rst='1' then
121 | LoadA <= '0';
122 | elsif io_wr='1' and io_addr='0' then -- write byte to tx
123 | TxData <= io_din(7 downto 0);
124 | LoadA <= '1';
125 | else
126 | LoadA <= '0';
127 | end if;
128 | end if;
129 | end process;
130 |
131 | process (clk, rst, io_addr, io_rd, RxData, TxBusy, RxAv)
132 | begin
133 | if Rising_Edge(clk) then
134 | if rst='1' then
135 | ReadA <= '0';
136 | elsif io_rd='1' and io_addr='0' then
137 | ReadA <= '1';
138 | else
139 | ReadA <= '0';
140 | end if;
141 | end if;
142 | end process;
143 | io_dout(7 downto 0) <= RxData when io_addr='0' else SReg;
144 | io_dout(15 downto 8) <= (others => '0');
145 |
146 | end Behaviour;
147 |
--------------------------------------------------------------------------------
/fpga/src/papilio-pro-j1.vhd:
--------------------------------------------------------------------------------
1 | library IEEE;
2 | use IEEE.STD_LOGIC_1164.ALL;
3 | use IEEE.NUMERIC_STD.ALL;
4 |
5 | entity papilio_pro_j1 is
6 | port (
7 | clk_in: in std_logic;
8 | rx: in std_logic;
9 | tx: out std_logic;
10 | wing: out std_logic_vector(15 downto 0));
11 | end papilio_pro_j1;
12 |
13 | architecture Behavioral of papilio_pro_j1 is
14 |
15 | component clock is
16 | port (
17 | clk_in: in std_logic;
18 | clk: out std_logic;
19 | clk180: out std_logic);
20 | end component;
21 |
22 | component j1 is
23 | port (
24 | sys_clk_i: in std_logic;
25 | sys_rst_i: in std_logic;
26 | io_rd: out std_logic;
27 | io_wr: out std_logic;
28 | io_addr: out std_logic_vector (15 downto 0);
29 | io_din: in std_logic_vector (15 downto 0);
30 | io_dout: out std_logic_vector (15 downto 0));
31 | end component;
32 |
33 | component miniuart2 is
34 | port (
35 | clk: in STD_LOGIC;
36 | rst: in STD_LOGIC;
37 | rx: in STD_LOGIC;
38 | tx: out STD_LOGIC;
39 | io_rd: in STD_LOGIC;
40 | io_wr: in STD_LOGIC;
41 | io_addr: in STD_LOGIC;
42 | io_din: in STD_LOGIC_VECTOR (15 downto 0);
43 | io_dout: out STD_LOGIC_VECTOR (15 downto 0));
44 | end component;
45 |
46 |
47 | signal clk: std_logic;
48 | signal clk180: std_logic;
49 |
50 | signal rst_counter: integer range 0 to 15 := 15;
51 | signal sys_rst: std_logic := '1';
52 |
53 | signal io_rd: std_logic;
54 | signal io_wr: std_logic;
55 | signal io_addr: std_logic_vector (15 downto 0);
56 | signal io_din: std_logic_vector (15 downto 0);
57 | signal io_dout: std_logic_vector (15 downto 0);
58 |
59 | signal uart_en: std_logic;
60 | signal uart_rd: std_logic;
61 | signal uart_wr: std_logic;
62 | signal uart_dout: std_logic_vector (15 downto 0);
63 | begin
64 |
65 | clock_inst: clock
66 | port map (
67 | clk_in => clk_in,
68 | clk => clk,
69 | clk180 => clk180);
70 |
71 | j1_inst: j1
72 | port map (
73 | sys_clk_i => clk,
74 | sys_rst_i => sys_rst,
75 | io_rd => io_rd,
76 | io_wr => io_wr,
77 | io_addr => io_addr,
78 | io_din => io_din,
79 | io_dout => io_dout);
80 |
81 | uart_inst: miniuart2
82 | port map(
83 | clk => clk180,
84 | rst => sys_rst,
85 | rx => rx,
86 | tx => tx,
87 | io_rd => uart_rd,
88 | io_wr => uart_wr,
89 | io_addr => io_addr(0),
90 | io_din => io_dout,
91 | io_dout => uart_dout);
92 |
93 | process (clk, rst_counter)
94 | begin
95 | if rising_edge(clk) and rst_counter>0 then
96 | rst_counter <= rst_counter-1;
97 | end if;
98 | end process;
99 | sys_rst <= '1' when rst_counter>0 else '0';
100 |
101 | uart_en <= '1' when io_addr(15 downto 1)="111100000000000" else '0';
102 | uart_rd <= io_rd and uart_en;
103 | uart_wr <= io_wr and uart_en;
104 |
105 | process (io_addr, uart_dout)
106 | begin
107 | case io_addr(15 downto 1) is
108 | when "111100000000000" =>
109 | io_din <= uart_dout;
110 | when others =>
111 | io_din <= (others=>'0');
112 | end case;
113 | end process;
114 |
115 | wing <= (others=>'0');
116 |
117 | end Behavioral;
--------------------------------------------------------------------------------
/fpga/src/papilio-pro.ucf:
--------------------------------------------------------------------------------
1 | # UCF file for the Papilio Pro board
2 | # Generated by pin_converter, written by Kevin Lindsey
3 | # https://github.com/thelonious/papilio_pins/tree/development/pin_converter
4 |
5 | # Main board wing pin [] to FPGA pin Pxx map
6 | # -------C------- -------B------- -------A-------
7 | # [GND] [C00] P114 [GND] [B00] P99 P100 [A15]
8 | # [2V5] [C01] P115 [2V5] [B01] P97 P98 [A14]
9 | # [3V3] [C02] P116 [3V3] [B02] P92 P93 [A13]
10 | # [5V0] [C03] P117 [5V0] [B03] P87 P88 [A12]
11 | # [C04] P118 [B04] P84 P85 [A11] [5V0]
12 | # [C05] P119 [B05] P82 P83 [A10] [3V3]
13 | # [C06] P120 [B06] P80 P81 [A09] [2V5]
14 | # [C07] P121 [B07] P78 P79 [A08] [GND]
15 | # [GND] [C08] P123 [GND] [B08] P74 P75 [A07]
16 | # [2V5] [C09] P124 [2V5] [B09] P95 P67 [A06]
17 | # [3V3] [C10] P126 [3V3] [B10] P62 P66 [A05]
18 | # [5V0] [C11] P127 [5V0] [B11] P59 P61 [A04]
19 | # [C12] P131 [B12] P57 P58 [A03] [5V0]
20 | # [C13] P132 [B13] P55 P56 [A02] [3V3]
21 | # [C14] P133 [B14] P50 P51 [A01] [2V5]
22 | # [C15] P134 [B15] P47 P48 [A00] [GND]
23 |
24 | ## Prohibit the automatic placement of pins that are connected to VCC or GND for configuration.
25 | CONFIG PROHIBIT=P144;
26 | CONFIG PROHIBIT=P69;
27 | CONFIG PROHIBIT=P60;
28 |
29 | NET CLK_IN LOC="P94" | IOSTANDARD=LVTTL | PERIOD=31.25ns; # CLK
30 | NET RX LOC="P101" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # RX
31 | NET TX LOC="P105" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # TX
32 | NET WING(0) LOC="P48" | IOSTANDARD=LVTTL; # A0
33 | NET WING(1) LOC="P51" | IOSTANDARD=LVTTL; # A1
34 | NET WING(2) LOC="P56" | IOSTANDARD=LVTTL; # A2
35 | NET WING(3) LOC="P58" | IOSTANDARD=LVTTL; # A3
36 | NET WING(4) LOC="P61" | IOSTANDARD=LVTTL; # A4
37 | NET WING(5) LOC="P66" | IOSTANDARD=LVTTL; # A5
38 | NET WING(6) LOC="P67" | IOSTANDARD=LVTTL; # A6
39 | NET WING(7) LOC="P75" | IOSTANDARD=LVTTL; # A7
40 | NET WING(8) LOC="P79" | IOSTANDARD=LVTTL; # A8
41 | NET WING(9) LOC="P81" | IOSTANDARD=LVTTL; # A9
42 | NET WING(10) LOC="P83" | IOSTANDARD=LVTTL; # A10
43 | NET WING(11) LOC="P85" | IOSTANDARD=LVTTL; # A11
44 | NET WING(12) LOC="P88" | IOSTANDARD=LVTTL; # A12
45 | NET WING(13) LOC="P93" | IOSTANDARD=LVTTL; # A13
46 | NET WING(14) LOC="P98" | IOSTANDARD=LVTTL; # A14
47 | NET WING(15) LOC="P100" | IOSTANDARD=LVTTL; # A15
48 | #NET A(0) LOC="P48" | IOSTANDARD=LVTTL; # A0
49 | #NET A(1) LOC="P51" | IOSTANDARD=LVTTL; # A1
50 | #NET A(2) LOC="P56" | IOSTANDARD=LVTTL; # A2
51 | #NET A(3) LOC="P58" | IOSTANDARD=LVTTL; # A3
52 | #NET A(4) LOC="P61" | IOSTANDARD=LVTTL; # A4
53 | #NET A(5) LOC="P66" | IOSTANDARD=LVTTL; # A5
54 | #NET A(6) LOC="P67" | IOSTANDARD=LVTTL; # A6
55 | #NET A(7) LOC="P75" | IOSTANDARD=LVTTL; # A7
56 | #NET A(8) LOC="P79" | IOSTANDARD=LVTTL; # A8
57 | #NET A(9) LOC="P81" | IOSTANDARD=LVTTL; # A9
58 | #NET A(10) LOC="P83" | IOSTANDARD=LVTTL; # A10
59 | #NET A(11) LOC="P85" | IOSTANDARD=LVTTL; # A11
60 | #NET A(12) LOC="P88" | IOSTANDARD=LVTTL; # A12
61 | #NET A(13) LOC="P93" | IOSTANDARD=LVTTL; # A13
62 | #NET A(14) LOC="P98" | IOSTANDARD=LVTTL; # A14
63 | #NET A(15) LOC="P100" | IOSTANDARD=LVTTL; # A15
64 | #NET B(0) LOC="P99" | IOSTANDARD=LVTTL; # B0
65 | #NET B(1) LOC="P97" | IOSTANDARD=LVTTL; # B1
66 | #NET B(2) LOC="P92" | IOSTANDARD=LVTTL; # B2
67 | #NET B(3) LOC="P87" | IOSTANDARD=LVTTL; # B3
68 | #NET B(4) LOC="P84" | IOSTANDARD=LVTTL; # B4
69 | #NET B(5) LOC="P82" | IOSTANDARD=LVTTL; # B5
70 | #NET B(6) LOC="P80" | IOSTANDARD=LVTTL; # B6
71 | #NET B(7) LOC="P78" | IOSTANDARD=LVTTL; # B7
72 | #NET B(8) LOC="P74" | IOSTANDARD=LVTTL; # B8
73 | #NET B(9) LOC="P95" | IOSTANDARD=LVTTL; # B9
74 | #NET B(10) LOC="P62" | IOSTANDARD=LVTTL; # B10
75 | #NET B(11) LOC="P59" | IOSTANDARD=LVTTL; # B11
76 | #NET B(12) LOC="P57" | IOSTANDARD=LVTTL; # B12
77 | #NET B(13) LOC="P55" | IOSTANDARD=LVTTL; # B13
78 | #NET B(14) LOC="P50" | IOSTANDARD=LVTTL; # B14
79 | #NET B(15) LOC="P47" | IOSTANDARD=LVTTL; # B15
80 | #NET C(0) LOC="P114" | IOSTANDARD=LVTTL; # C0
81 | #NET C(1) LOC="P115" | IOSTANDARD=LVTTL; # C1
82 | #NET C(2) LOC="P116" | IOSTANDARD=LVTTL; # C2
83 | #NET C(3) LOC="P117" | IOSTANDARD=LVTTL; # C3
84 | #NET C(4) LOC="P118" | IOSTANDARD=LVTTL; # C4
85 | #NET C(5) LOC="P119" | IOSTANDARD=LVTTL; # C5
86 | #NET C(6) LOC="P120" | IOSTANDARD=LVTTL; # C6
87 | #NET C(7) LOC="P121" | IOSTANDARD=LVTTL; # C7
88 | #NET C(8) LOC="P123" | IOSTANDARD=LVTTL; # C8
89 | #NET C(9) LOC="P124" | IOSTANDARD=LVTTL; # C9
90 | #NET C(10) LOC="P126" | IOSTANDARD=LVTTL; # C10
91 | #NET C(11) LOC="P127" | IOSTANDARD=LVTTL; # C11
92 | #NET C(12) LOC="P131" | IOSTANDARD=LVTTL; # C12
93 | #NET C(13) LOC="P132" | IOSTANDARD=LVTTL; # C13
94 | #NET C(14) LOC="P133" | IOSTANDARD=LVTTL; # C14
95 | #NET C(15) LOC="P134" | IOSTANDARD=LVTTL; # C15
96 | #NET SDRAM_ADDR(0) LOC="P140" | IOSTANDARD=LVTTL; # SDRAM_ADDR0
97 | #NET SDRAM_ADDR(1) LOC="P139" | IOSTANDARD=LVTTL; # SDRAM_ADDR1
98 | #NET SDRAM_ADDR(2) LOC="P138" | IOSTANDARD=LVTTL; # SDRAM_ADDR2
99 | #NET SDRAM_ADDR(3) LOC="P137" | IOSTANDARD=LVTTL; # SDRAM_ADDR3
100 | #NET SDRAM_ADDR(4) LOC="P46" | IOSTANDARD=LVTTL; # SDRAM_ADDR4
101 | #NET SDRAM_ADDR(5) LOC="P45" | IOSTANDARD=LVTTL; # SDRAM_ADDR5
102 | #NET SDRAM_ADDR(6) LOC="P44" | IOSTANDARD=LVTTL; # SDRAM_ADDR6
103 | #NET SDRAM_ADDR(7) LOC="P43" | IOSTANDARD=LVTTL; # SDRAM_ADDR7
104 | #NET SDRAM_ADDR(8) LOC="P41" | IOSTANDARD=LVTTL; # SDRAM_ADDR8
105 | #NET SDRAM_ADDR(9) LOC="P40" | IOSTANDARD=LVTTL; # SDRAM_ADDR9
106 | #NET SDRAM_ADDR(10) LOC="P141" | IOSTANDARD=LVTTL; # SDRAM_ADDR10
107 | #NET SDRAM_ADDR(11) LOC="P35" | IOSTANDARD=LVTTL; # SDRAM_ADDR11
108 | #NET SDRAM_ADDR(12) LOC="P34" | IOSTANDARD=LVTTL; # SDRAM_ADDR12
109 | #NET SDRAM_DATA(0) LOC="P9" | IOSTANDARD=LVTTL; # SDRAM_DATA0
110 | #NET SDRAM_DATA(1) LOC="P10" | IOSTANDARD=LVTTL; # SDRAM_DATA1
111 | #NET SDRAM_DATA(2) LOC="P11" | IOSTANDARD=LVTTL; # SDRAM_DATA2
112 | #NET SDRAM_DATA(3) LOC="P12" | IOSTANDARD=LVTTL; # SDRAM_DATA3
113 | #NET SDRAM_DATA(4) LOC="P14" | IOSTANDARD=LVTTL; # SDRAM_DATA4
114 | #NET SDRAM_DATA(5) LOC="P15" | IOSTANDARD=LVTTL; # SDRAM_DATA5
115 | #NET SDRAM_DATA(6) LOC="P16" | IOSTANDARD=LVTTL; # SDRAM_DATA6
116 | #NET SDRAM_DATA(7) LOC="P8" | IOSTANDARD=LVTTL; # SDRAM_DATA7
117 | #NET SDRAM_DATA(8) LOC="P21" | IOSTANDARD=LVTTL; # SDRAM_DATA8
118 | #NET SDRAM_DATA(9) LOC="P22" | IOSTANDARD=LVTTL; # SDRAM_DATA9
119 | #NET SDRAM_DATA(10) LOC="P23" | IOSTANDARD=LVTTL; # SDRAM_DATA10
120 | #NET SDRAM_DATA(11) LOC="P24" | IOSTANDARD=LVTTL; # SDRAM_DATA11
121 | #NET SDRAM_DATA(12) LOC="P26" | IOSTANDARD=LVTTL; # SDRAM_DATA12
122 | #NET SDRAM_DATA(13) LOC="P27" | IOSTANDARD=LVTTL; # SDRAM_DATA13
123 | #NET SDRAM_DATA(14) LOC="P29" | IOSTANDARD=LVTTL; # SDRAM_DATA14
124 | #NET SDRAM_DATA(15) LOC="P30" | IOSTANDARD=LVTTL; # SDRAM_DATA15
125 | #NET SDRAM_DQML LOC="P7" | IOSTANDARD=LVTTL; # SDRAM_DQML
126 | #NET SDRAM_DQMH LOC="P17" | IOSTANDARD=LVTTL; # SDRAM_DQMH
127 | #NET SDRAM_BA(0) LOC="P143" | IOSTANDARD=LVTTL; # SDRAM_BA0
128 | #NET SDRAM_BA(1) LOC="P142" | IOSTANDARD=LVTTL; # SDRAM_BA1
129 | #NET SDRAM_nWE LOC="P6" | IOSTANDARD=LVTTL; # SDRAM_nWE
130 | #NET SDRAM_nCAS LOC="P5" | IOSTANDARD=LVTTL; # SDRAM_nCAS
131 | #NET SDRAM_nRAS LOC="P2" | IOSTANDARD=LVTTL; # SDRAM_nRAS
132 | #NET SDRAM_CS LOC="P1" | IOSTANDARD=LVTTL; # SDRAM_CS
133 | #NET SDRAM_CLK LOC="P32" | IOSTANDARD=LVTTL; # SDRAM_CLK
134 | #NET SDRAM_CKE LOC="P33" | IOSTANDARD=LVTTL; # SDRAM_CKE
135 | #NET LED1 LOC="P112" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=SLOW; # LED1
136 | #NET JTAG_TMS LOC="P107" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # JTAG_TMS
137 | #NET JTAG_TCK LOC="P109" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # JTAG_TCK
138 | #NET JTAG_TDI LOC="P110" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # JTAG_TDI
139 | #NET JTAG_TDO LOC="P106" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # JTAG_TDO
140 | #NET FLASH_CS LOC="P38" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # FLASH_CS
141 | #NET FLASH_CK LOC="P70" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # FLASH_CK
142 | #NET FLASH_SI LOC="P64" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # FLASH_SI
143 | #NET FLASH_SO LOC="P65" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST | PULLUP; # FLASH_SO
144 |
--------------------------------------------------------------------------------
/fpga/src/utils.vhd:
--------------------------------------------------------------------------------
1 | -------------------------------------------------------------------------------
2 | -- Title : UART
3 | -- Project : UART
4 | -------------------------------------------------------------------------------
5 | -- File : utils.vhd
6 | -- Author : Philippe CARTON
7 | -- (philippe.carton2@libertysurf.fr)
8 | -- Organization:
9 | -- Created : 15/12/2001
10 | -- Last update : 8/1/2003
11 | -- Platform : Foundation 3.1i
12 | -- Simulators : ModelSim 5.5b
13 | -- Synthesizers: Xilinx Synthesis
14 | -- Targets : Xilinx Spartan
15 | -- Dependency : IEEE std_logic_1164
16 | -------------------------------------------------------------------------------
17 | -- Description: VHDL utility file
18 | -------------------------------------------------------------------------------
19 | -- Copyright (c) notice
20 | -- This core adheres to the GNU public license
21 | --
22 | -------------------------------------------------------------------------------
23 | -- Revisions :
24 | -- Revision Number :
25 | -- Version :
26 | -- Date :
27 | -- Modifier : name
28 | -- Description :
29 | --
30 | ------------------------------------------------------------------------------
31 |
32 |
33 | -------------------------------------------------------------------------------
34 | -- Revision list
35 | -- Version Author Date Changes
36 | --
37 | -- 1.0 Philippe CARTON 19 December 2001 New model
38 | -- philippe.carton2@libertysurf.fr
39 | -------------------------------------------------------------------------------
40 |
41 | --------------------------------------------------------------------------------
42 | -- Synchroniser:
43 | -- Synchronize an input signal (C1) with an input clock (C).
44 | -- The result is the O signal which is synchronous of C, and persist for
45 | -- one C clock period.
46 | --------------------------------------------------------------------------------
47 | library IEEE,STD;
48 | use IEEE.std_logic_1164.all;
49 |
50 | entity synchroniser is
51 | port (
52 | C1 : in std_logic;-- Asynchronous signal
53 | C : in std_logic;-- Clock
54 | O : out std_logic);-- Synchronised signal
55 | end synchroniser;
56 |
57 | architecture Behaviour of synchroniser is
58 | signal C1A : std_logic;
59 | signal C1S : std_logic;
60 | signal R : std_logic;
61 | begin
62 | RiseC1A : process(C1,R)
63 | begin
64 | if Rising_Edge(C1) then
65 | C1A <= '1';
66 | end if;
67 | if (R = '1') then
68 | C1A <= '0';
69 | end if;
70 | end process;
71 |
72 | SyncP : process(C,R)
73 | begin
74 | if Rising_Edge(C) then
75 | if (C1A = '1') then
76 | C1S <= '1';
77 | else C1S <= '0';
78 | end if;
79 | if (C1S = '1') then
80 | R <= '1';
81 | else R <= '0';
82 | end if;
83 | end if;
84 | if (R = '1') then
85 | C1S <= '0';
86 | end if;
87 | end process;
88 | O <= C1S;
89 | end Behaviour;
90 |
91 | -------------------------------------------------------------------------------
92 | -- Counter
93 | -- This counter is a parametrizable clock divider.
94 | -- The count value is the generic parameter Count.
95 | -- It is CE enabled. (it will count only if CE is high).
96 | -- When it overflow, it will emit a pulse on O.
97 | -- It can be reseted to 0.
98 | -------------------------------------------------------------------------------
99 | library IEEE,STD;
100 | use IEEE.std_logic_1164.all;
101 |
102 | entity Counter is
103 | generic(Count: INTEGER range 0 to 65535); -- Count revolution
104 | port (
105 | Clk : in std_logic; -- Clock
106 | Reset : in std_logic; -- Reset input
107 | CE : in std_logic; -- Chip Enable
108 | O : out std_logic); -- Output
109 | end Counter;
110 |
111 | architecture Behaviour of Counter is
112 | begin
113 | counter : process(Clk,Reset)
114 | variable Cnt : INTEGER range 0 to Count-1;
115 | begin
116 | if Reset = '1' then
117 | Cnt := Count - 1;
118 | O <= '0';
119 | elsif Rising_Edge(Clk) then
120 | if CE = '1' then
121 | if Cnt = 0 then
122 | O <= '1';
123 | Cnt := Count - 1;
124 | else
125 | O <= '0';
126 | Cnt := Cnt - 1;
127 | end if;
128 | else O <= '0';
129 | end if;
130 | end if;
131 | end process;
132 | end Behaviour;
133 |
--------------------------------------------------------------------------------
/fpga/test/miniuart2_tb.vhd:
--------------------------------------------------------------------------------
1 | --------------------------------------------------------------------------------
2 | -- Company:
3 | -- Engineer:
4 | --
5 | -- Create Date: 11:48:15 12/20/2014
6 | -- Design Name:
7 | -- Module Name: /mnt/hgfs/Projects/j1eforth/vhdl/test/miniuart2_tb.vhd
8 | -- Project Name: papilio-pro-forth
9 | -- Target Device:
10 | -- Tool versions:
11 | -- Description:
12 | --
13 | -- VHDL Test Bench Created by ISE for module: MINIUART2
14 | --
15 | -- Dependencies:
16 | --
17 | -- Revision:
18 | -- Revision 0.01 - File Created
19 | -- Additional Comments:
20 | --
21 | -- Notes:
22 | -- This testbench has been automatically generated using types std_logic and
23 | -- std_logic_vector for the ports of the unit under test. Xilinx recommends
24 | -- that these types always be used for the top-level I/O of a design in order
25 | -- to guarantee that the testbench will bind correctly to the post-implementation
26 | -- simulation model.
27 | --------------------------------------------------------------------------------
28 | LIBRARY ieee;
29 | USE ieee.std_logic_1164.ALL;
30 |
31 | -- Uncomment the following library declaration if using
32 | -- arithmetic functions with Signed or Unsigned values
33 | --USE ieee.numeric_std.ALL;
34 |
35 | ENTITY miniuart2_tb IS
36 | END miniuart2_tb;
37 |
38 | ARCHITECTURE behavior OF miniuart2_tb IS
39 |
40 | -- Component Declaration for the Unit Under Test (UUT)
41 |
42 | COMPONENT MINIUART2
43 | PORT(
44 | clk : IN std_logic;
45 | rst : IN std_logic;
46 | rx : IN std_logic;
47 | tx : OUT std_logic;
48 | io_rd : IN std_logic;
49 | io_wr : IN std_logic;
50 | io_addr : IN std_logic;
51 | io_din : IN std_logic_vector(15 downto 0);
52 | io_dout : OUT std_logic_vector(15 downto 0)
53 | );
54 | END COMPONENT;
55 |
56 |
57 | --Inputs
58 | signal clk : std_logic := '0';
59 | signal rst : std_logic := '0';
60 | signal rx : std_logic := '0';
61 | signal io_rd : std_logic := '0';
62 | signal io_wr : std_logic := '0';
63 | signal io_addr : std_logic := '0';
64 | signal io_din : std_logic_vector(15 downto 0) := (others => '0');
65 |
66 | --Outputs
67 | signal tx : std_logic;
68 | signal io_dout : std_logic_vector(15 downto 0);
69 |
70 | -- Clock period definitions
71 | constant clk_period : time := 10 ns; -- 31.25 ns;
72 |
73 | BEGIN
74 |
75 | -- Instantiate the Unit Under Test (UUT)
76 | uut: MINIUART2 PORT MAP (
77 | clk => clk,
78 | rst => rst,
79 | rx => rx,
80 | tx => tx,
81 | io_rd => io_rd,
82 | io_wr => io_wr,
83 | io_addr => io_addr,
84 | io_din => io_din,
85 | io_dout => io_dout
86 | );
87 |
88 | -- Clock process definitions
89 | clk_process :process
90 | begin
91 | clk <= '0';
92 | wait for clk_period/2;
93 | clk <= '1';
94 | wait for clk_period/2;
95 | end process;
96 |
97 |
98 | -- Stimulus process
99 | stim_proc: process
100 | begin
101 | -- hold reset state for 100 ns.
102 | wait for 100 ns;
103 |
104 | wait for clk_period*5;
105 |
106 | rst <= '1';
107 |
108 | wait for clk_period*3;
109 |
110 | rst <= '0';
111 |
112 | wait for clk_period*3;
113 |
114 | -- insert stimulus here
115 | io_din <= X"002A";
116 | io_addr <= '1';
117 | io_wr <= '1';
118 |
119 | wait for clk_period;
120 |
121 | io_addr <= '0';
122 | io_din <= X"0000";
123 | io_wr <= '0';
124 |
125 | wait;
126 | end process;
127 |
128 | END;
129 |
--------------------------------------------------------------------------------
/fpga/test/papilio_pro_j1_tb.vhd:
--------------------------------------------------------------------------------
1 | --------------------------------------------------------------------------------
2 | -- Company:
3 | -- Engineer:
4 | --
5 | -- Create Date: 22:12:23 03/03/2012
6 | -- Design Name:
7 | -- Module Name: /home/ben/prog/PapilioForth/ise/main_tb.vhd
8 | -- Project Name: PapilioForth
9 | -- Target Device:
10 | -- Tool versions:
11 | -- Description:
12 | --
13 | -- VHDL Test Bench Created by ISE for module: main
14 | --
15 | -- Dependencies:
16 | --
17 | -- Revision:
18 | -- Revision 0.01 - File Created
19 | -- Additional Comments:
20 | --
21 | -- Notes:
22 | -- This testbench has been automatically generated using types std_logic and
23 | -- std_logic_vector for the ports of the unit under test. Xilinx recommends
24 | -- that these types always be used for the top-level I/O of a design in order
25 | -- to guarantee that the testbench will bind correctly to the post-implementation
26 | -- simulation model.
27 | --------------------------------------------------------------------------------
28 | LIBRARY ieee;
29 | USE ieee.std_logic_1164.ALL;
30 |
31 | -- Uncomment the following library declaration if using
32 | -- arithmetic functions with Signed or Unsigned values
33 | --USE ieee.numeric_std.ALL;
34 |
35 | ENTITY papilio_pro_j1_tb IS
36 | END papilio_pro_j1_tb;
37 |
38 | ARCHITECTURE behavior OF papilio_pro_j1_tb IS
39 |
40 | -- Component Declaration for the Unit Under Test (UUT)
41 |
42 | COMPONENT papilio_pro_j1
43 | PORT(
44 | clk_in : IN std_logic;
45 | rx : IN std_logic;
46 | tx : OUT std_logic;
47 | wing : INOUT std_logic_vector(15 downto 0)
48 | );
49 | END COMPONENT;
50 |
51 |
52 | --Inputs
53 | signal clk_in : std_logic := '0';
54 | signal rx : std_logic := '0';
55 |
56 | --Outputs
57 | signal tx : std_logic;
58 | signal wing : std_logic_vector(15 downto 0);
59 |
60 | -- Clock period definitions
61 | constant clk_in_period : time := 31.25 ns;
62 |
63 | BEGIN
64 |
65 | -- Instantiate the Unit Under Test (UUT)
66 | uut: papilio_pro_j1 PORT MAP (
67 | clk_in => clk_in,
68 | rx => rx,
69 | tx => tx,
70 | wing => wing
71 | );
72 |
73 | -- Clock process definitions
74 | clk_in_process :process
75 | begin
76 | clk_in <= '0';
77 | wait for clk_in_period/2;
78 | clk_in <= '1';
79 | wait for clk_in_period/2;
80 | end process;
81 |
82 |
83 | -- Stimulus process
84 | stim_proc: process
85 | begin
86 | -- hold reset state for 100 ns.
87 | wait for 100 ns;
88 |
89 | wait for clk_in_period*50;
90 |
91 | -- insert stimulus here
92 |
93 | wait;
94 | end process;
95 |
96 | END;
97 |
--------------------------------------------------------------------------------
/ipv4.4th:
--------------------------------------------------------------------------------
1 | (
2 | I feel that the Kernel is at it's best for now and that I can proceed
3 | to do some other things. Note that version 1 is just to make the whole
4 | thing work, later on I might look at optimisation where I might have to move
5 | some stuff around so that memory utilization and execution speed efficiency is
6 | achieved.So far the Kernel works without needing tweaks.
7 |
8 | Work in progress: Implementing simple ipv4 for the j1eforth model
9 |
10 | 7 project targets:
11 |
12 | 1. Add multi-tasking support to the Kernel - 0%
13 | 2. Modify j1 sim to use pcap interface for network tx and rx - 0%
14 | 3. ARP - 0%
15 | 4. ICMP - 0%
16 | 5. IP - 0%
17 | 6. UDP - 0%
18 | 7. TCP - 0%
19 |
20 | Hopefully I will get time to do all this and also document the design of
21 | the j1eforth Kernel for those who are starting out with forth and also those
22 | who wish to tinker with the Kernel for fun.
23 | )
24 |
25 | hex
26 |
27 | forth-wordlist >voc forth
28 |
29 | vocabulary ipv4.1
30 | only forth also ipv4.1
31 |
32 | ipv4.1 definitions
33 |
34 | variable active_struct
35 |
36 | : field
37 | create over , +
38 | does>
39 | @ active_struct @ + ;
40 |
41 | ( ethernet frame )
42 |
43 | 0
44 | 6 field eth_dest ( 48 bit source address )
45 | 6 field eth_src ( 48 bit destination address )
46 | 2 field eth_type ( 16 bit type )
47 | constant eth_frame%
48 |
49 | ( arp message )
50 |
51 | 0
52 | 2 field arp_hw ( 16 bit hw type )
53 | 2 field arp_proto ( 16 bit protocol )
54 | 1 field arp_hlen ( 8 bit hw address length )
55 | 1 field arp_plen ( 8 bit protocol address length )
56 | 2 field arp_op ( 16 bit operation )
57 | 6 field arp_shw ( 48 bit sender hw address )
58 | 4 field arp_sp ( 32 bit sender ipv4 address )
59 | 6 field arp_thw ( 48 bit target hw address )
60 | 4 field arp_tp ( 32 bit target ipv4 address )
61 | constant arp_message%
62 |
63 | ( arp cache )
64 |
65 | 0
66 | 4 field ac_ip ( 32 bit protocol address )
67 | 6 field ac_hw ( 48 bit hw address )
68 | constant arp_cache%
69 |
70 | ( ipv4 datagram header )
71 |
72 | 0
73 | 1 field ip_vhl ( 4 bit version and 4 bit header length )
74 | 1 field ip_tos ( 8 bit type of service )
75 | 2 field ip_len ( 16 bit length )
76 | 2 field ip_id ( 16 bit identification )
77 | 2 field ip_frags ( 3 bit flags 13 bit fragment offset )
78 | 1 field ip_ttl ( 8 bit time to live )
79 | 1 field ip_proto ( 8 bit protocol number )
80 | 2 field ip_checksum ( 16 bit checksum )
81 | 4 field ip_source ( 32 bit source address )
82 | 4 field ip_dest ( 32 bit destination address )
83 | constant ip_header%
84 |
85 | ( icmp header )
86 |
87 | 0
88 | 1 field icmp_type ( 8 bits type )
89 | 1 field icmp_code ( 8 bits code )
90 | 2 field icmp_checksum ( 16 bits checksum )
91 | constant icmp_header%
92 |
93 | ( udp datagram )
94 |
95 | 0
96 | 2 field udp_source ( 16 bit source port )
97 | 2 field udp_dest ( 16 bit destination port )
98 | 2 field udp_len ( 16 bit length )
99 | 2 field udp_checksum ( 16 bit checksum )
100 | constant udp_datagram%
101 |
102 | ( tcp header )
103 |
104 | 0
105 | 2 field tcp_source ( 16 bit source port )
106 | 2 field tcp_dest ( 16 bit destination port )
107 | 4 field tcp_seq ( 32 bit sequence number )
108 | 4 field tcp_ack ( 32 bit acknowledgement )
109 | 1 field tcp_offset ( 8 bit offset )
110 | 2 field tcp_flags ( 16 bit flags )
111 | 1 field tcp_window ( 8 bit window size )
112 | 2 field tcp_checksum ( 16 bit checksum )
113 | 2 field tcp_urgent ( 16 bit urgent pointer )
114 | constant tcp_header%
115 |
116 | 4000 constant eth_rx_buf
117 |
118 | : htons ( n -- n )
119 | dup ff and 8 lshift swap ff00 and 8 rshift or ;
120 |
121 | create ip_addr a8c0 , fe0b ,
122 | create ip_netmask ffff , 00ff ,
123 | create hw_addr bd00 , 333b , 7f05 ,
124 |
125 | 8 constant eth_ip_type
126 | 608 constant eth_arp_type
127 | 3580 constant eth_rarp_type
128 |
129 | 100 constant arp_request_type
130 | 200 constant arp_reply_type
131 |
132 | 0 constant icmp_echo_reply
133 | 8 constant icmp_echo
134 |
135 | 0 constant arp_action
136 |
137 | : arp_lookup 0 to arp_action ;
138 | : arp_update 1 to arp_action ;
139 | : arp_insert 2 to arp_action ;
140 | : arp_delete 3 to arp_action ;
141 | : +arp_age 4 to arp_action ;
142 |
143 | : (arp_lookup) cr ." compare" . . ;
144 | : (arp_update) cr ." update" . . ;
145 | : (arp_insert) cr ." insert" ;
146 | : (arp_delete) cr ." delete" ;
147 | : (+arp_age) cr ." age" ;
148 |
149 | : arp_table ( u -- )
150 | create here over allot swap erase
151 | does>
152 | swap arp_cache% * +
153 | arp_action 0 to arp_action
154 | case
155 | 0 of (arp_lookup) endof
156 | 1 of (arp_update) endof
157 | 2 of (arp_insert) endof
158 | 3 of (arp_delete) endof
159 | 4 of (+arp_age) endof
160 | ." unknown cache option"
161 | endcase ;
162 |
163 | arp_cache% 8 * arp_table arp_cache
164 |
165 | : eth_rx f008 @ ;
166 | : eth_tx f008 ! ;
167 |
168 | : checksum ( address count -- checksum)
169 | over + 0 -rot
170 | do
171 | i @ + i @ over u> if 1+ then
172 | -2 +loop
173 | dup 10 rshift swap ffff and +
174 | dup 10 rshift +
175 | ffff xor ;
176 | : arp_in ( -- )
177 | eth_frame% active_struct +!
178 | arp_op @ arp_request_type = if
179 | 100 arp_hw !
180 | eth_ip_type arp_proto !
181 | 6 arp_hlen c!
182 | 4 arp_plen c!
183 | arp_reply_type arp_op !
184 | arp_shw arp_thw 6 cmove
185 | hw_addr arp_shw 6 cmove
186 | arp_sp arp_tp 4 cmove
187 | ip_addr arp_sp 4 cmove
188 | arp_thw
189 | eth_rx_buf active_struct !
190 | eth_dest 6 cmove
191 | hw_addr eth_src 6 cmove
192 | eth_arp_type eth_type !
193 | eth_tx
194 | else
195 | ( arp_update )
196 | then ;
197 | : icmp_in
198 | ip_len @ htons
199 | ip_header% active_struct +!
200 | icmp_type c@ 8 = if
201 | 0 icmp_type c!
202 | icmp_checksum @ fff7 = if
203 | 9 icmp_checksum +!
204 | else 8 icmp_checksum +! then
205 | else
206 | cr ." weird icmp packet"
207 | then eth_tx ;
208 | : udp_in cr ." got udp packet." ;
209 | : tcp_in cr ." got tcp packet." ;
210 | : ip_in ( -- )
211 | eth_frame% active_struct +!
212 | ip_vhl @ 45 = if
213 | ip_proto c@ case
214 | 1 of
215 | ip_source dup ip_dest 4 cmove
216 | ip_addr swap 4 cmove
217 | icmp_in
218 | endof
219 | 6 of tcp_in endof
220 | 17 of udp_in endof
221 | cr ." unknown ip protocol:"
222 | endcase
223 | else
224 | cr ." unsupported ip version detected"
225 | then ;
226 | : process ( -- )
227 | eth_type @ case
228 | eth_arp_type of arp_in endof
229 | eth_ip_type of ip_in endof
230 | cr ." unknown ethernet protocol"
231 | endcase ;
232 | : pcap_poll
233 | eth_rx_buf active_struct !
234 | active_struct @ 5dc erase
235 | eth_rx ;
236 | : round
237 | pcap_poll 0 <> if
238 | process
239 | then ;
240 | : main
241 | begin
242 | round
243 | again
244 | ;
245 |
246 | ( main )
247 |
248 | forth definitions
249 | ipv4.1 definitions
250 |
--------------------------------------------------------------------------------
/j1.4th:
--------------------------------------------------------------------------------
1 | (
2 | eForth 1.04 for j1 Simulator by Edward A., July 2014
3 | Much of the code is derived from the following sources:
4 | j1 Cross-compiler by James Bowman August 2010
5 | 8086 eForth 1.0 by Bill Muench and C. H. Ting, 1990
6 | )
7 |
8 | only forth definitions hex
9 |
10 | wordlist constant meta.1
11 | wordlist constant target.1
12 | wordlist constant assembler.1
13 |
14 | : (order) ( w wid*n n -- wid*n w n )
15 | dup if
16 | 1- swap >r recurse over r@ xor if
17 | 1+ r> -rot exit then r> drop then ;
18 | : -order ( wid -- ) get-order (order) nip set-order ;
19 | : +order ( wid -- ) dup >r -order get-order r> swap 1+ set-order ;
20 |
21 | : ]asm ( -- ) assembler.1 +order ; immediate
22 |
23 | get-current meta.1 set-current
24 |
25 | : [a] ( "name" -- )
26 | parse-word assembler.1 search-wordlist 0=
27 | abort" [a]?" compile, ; immediate
28 | : a: ( "name" -- )
29 | get-current >r assembler.1 set-current
30 | : r> set-current ;
31 |
32 | target.1 +order meta.1 +order
33 |
34 | a: asm[ ( -- ) assembler.1 -order ; immediate
35 |
36 | create tflash 1000 cells here over erase allot
37 |
38 | variable tdp
39 |
40 | : there tdp @ ;
41 | : tc! tflash + c! ;
42 | : tc@ tflash + c@ ;
43 | : t! over ff and over tc! swap 8 rshift swap 1+ tc! ;
44 | : t@ dup tc@ swap 1+ tc@ 8 lshift or ;
45 | : talign there 1 and tdp +! ;
46 | : tc, there tc! 1 tdp +! ;
47 | : t, there t! 2 tdp +! ;
48 | : $literal [char] " word count dup tc, 0 ?do
49 | count tc, loop drop talign ;
50 | : tallot tdp +! ;
51 | : org tdp ! ;
52 |
53 | a: t 0000 ;
54 | a: n 0100 ;
55 | a: t+n 0200 ;
56 | a: t&n 0300 ;
57 | a: t|n 0400 ;
58 | a: t^n 0500 ;
59 | a: ~t 0600 ;
60 | a: n==t 0700 ;
61 | a: n>t 0900 ;
63 | a: t-1 0a00 ;
64 | a: rt 0b00 ;
65 | a: [t] 0c00 ;
66 | a: n<n 0080 or ;
71 | a: t->r 0040 or ;
72 | a: n->[t] 0020 or ;
73 | a: d-1 0003 or ;
74 | a: d+1 0001 or ;
75 | a: r-1 000c or ;
76 | a: r-2 0008 or ;
77 | a: r+1 0004 or ;
78 |
79 | a: alu 6000 or t, ;
80 |
81 | a: return [a] t 1000 or [a] r-1 [a] alu ;
82 | a: branch 2/ 0000 or t, ;
83 | a: ?branch 2/ 2000 or t, ;
84 | a: call 2/ 4000 or t, ;
85 |
86 | a: literal
87 | dup 8000 and if
88 | ffff xor recurse
89 | [a] ~t [a] alu
90 | else
91 | 8000 or t,
92 | then ;
93 |
94 | variable tlast
95 | variable tuser
96 |
97 | 0001 constant =ver
98 | 0004 constant =ext
99 | 0040 constant =comp
100 | 0080 constant =imed
101 | 7f1f constant =mask
102 | 0002 constant =cell
103 | 0010 constant =base
104 | 0008 constant =bksp
105 | 000a constant =lf
106 | 000d constant =cr
107 |
108 | 4000 constant =em
109 | 0000 constant =cold
110 |
111 | 8 constant =vocs
112 | 80 constant =us
113 |
114 | =em 100 - constant =tib
115 | =tib =us - constant =up
116 | =cold =us + constant =pick
117 | =pick 100 + constant =code
118 |
119 | : thead
120 | talign
121 | tlast @ t, there tlast !
122 | parse-word dup tc, 0 ?do count tc, loop drop talign ;
123 | : twords
124 | cr tlast @
125 | begin
126 | dup tflash + count 1f and type space =cell - t@
127 | ?dup 0= until ;
128 | : [t]
129 | parse-word target.1 search-wordlist 0=
130 | abort" [t]?" >body @ ; immediate
131 | : [last] tlast @ ; immediate
132 | : ( [char] ) parse 2drop ; immediate
133 | : literal [a] literal ;
134 | : lookback there =cell - t@ ;
135 | : call? lookback e000 and 4000 = ;
136 | : call>goto there =cell - dup t@ 1fff and swap t! ;
137 | : safe? lookback e000 and 6000 = lookback 004c and 0= and ;
138 | : alu>return there =cell - dup t@ 1000 or [a] r-1 swap t! ;
139 | : t:
140 | >in @ thead >in !
141 | get-current >r target.1 set-current create
142 | r> set-current 947947 talign there , does> @ [a] call ;
143 | : exit
144 | call? if
145 | call>goto else safe? if
146 | alu>return else
147 | [a] return
148 | then
149 | then ;
150 | : t;
151 | 947947 <> if
152 | abort" unstructured" then true if
153 | exit else [a] return then ;
154 | : u:
155 | >in @ thead >in !
156 | get-current >r target.1 set-current create
157 | r> set-current talign tuser @ dup ,
158 | [a] literal exit =cell tuser +! does> @ [a] literal ;
159 | : [u]
160 | parse-word target.1 search-wordlist 0=
161 | abort" [t]?" >body @ =up - =cell + ; immediate
162 | : immediate tlast @ tflash + dup c@ =imed or swap c! ;
163 | : compile-only tlast @ tflash + dup c@ =comp or swap c! ;
164 |
165 | 0 tlast !
166 | =up tuser !
167 |
168 | : hex# ( u -- addr len ) 0 <# base @ >r hex =lf hold # # # # r> base ! #> ;
169 | : save-hex ( -- )
170 | parse-word w/o create-file throw
171 | there 0 do i t@ over >r hex# r> write-file throw 2 +loop
172 | close-file throw ;
173 | : save-target ( -- )
174 | parse-word w/o create-file throw >r
175 | tflash there r@ write-file throw r> close-file ;
176 |
177 | : begin there ;
178 | : until [a] ?branch ;
179 |
180 | : if there 0 [a] ?branch ;
181 | : skip there 0 [a] branch ;
182 | : then begin 2/ over t@ or swap t! ;
183 | : else skip swap then ;
184 | : while if swap ;
185 | : repeat [a] branch then ;
186 | : again [a] branch ;
187 | : aft drop skip begin swap ;
188 |
189 | : noop ]asm t alu asm[ ;
190 | : + ]asm t+n d-1 alu asm[ ;
191 | : xor ]asm t^n d-1 alu asm[ ;
192 | : and ]asm t&n d-1 alu asm[ ;
193 | : or ]asm t|n d-1 alu asm[ ;
194 | : invert ]asm ~t alu asm[ ;
195 | : = ]asm n==t d-1 alu asm[ ;
196 | : < ]asm nn alu asm[ ;
199 | : dup ]asm t t->n d+1 alu asm[ ;
200 | : drop ]asm n d-1 alu asm[ ;
201 | : over ]asm n t->n d+1 alu asm[ ;
202 | : nip ]asm t d-1 alu asm[ ;
203 | : >r ]asm n t->r r+1 d-1 alu asm[ ;
204 | : r> ]asm rt t->n r-1 d+1 alu asm[ ;
205 | : r@ ]asm rt t->n d+1 alu asm[ ;
206 | : @ ]asm [t] alu asm[ ;
207 | : ! ]asm t n->[t] d-1 alu
208 | n d-1 alu asm[ ;
209 | : dsp ]asm dsp t->n d+1 alu asm[ ;
210 | : lshift ]asm n<>t d-1 alu asm[ ;
212 | : 1- ]asm t-1 alu asm[ ;
213 | : 2r> ]asm rt t->n r-1 d+1 alu
214 | rt t->n r-1 d+1 alu
215 | n t->n alu asm[ ;
216 | : 2>r ]asm n t->n alu
217 | n t->r r+1 d-1 alu
218 | n t->r r+1 d-1 alu asm[ ;
219 | : 2r@ ]asm rt t->n r-1 d+1 alu
220 | rt t->n r-1 d+1 alu
221 | n t->n d+1 alu
222 | n t->n d+1 alu
223 | n t->r r+1 d-1 alu
224 | n t->r r+1 d-1 alu
225 | n t->n alu asm[ ;
226 | : unloop
227 | ]asm t r-1 alu
228 | t r-1 alu asm[ ;
229 |
230 | : dup@ ]asm [t] t->n d+1 alu asm[ ;
231 | : dup>r ]asm t t->r r+1 alu asm[ ;
232 | : 2dupxor ]asm t^n t->n d+1 alu asm[ ;
233 | : 2dup= ]asm n==t t->n d+1 alu asm[ ;
234 | : !nip ]asm t n->[t] d-1 alu asm[ ;
235 | : 2dup! ]asm t n->[t] alu asm[ ;
236 |
237 | : up1 ]asm t d+1 alu asm[ ;
238 | : down1 ]asm t d-1 alu asm[ ;
239 | : copy ]asm n alu asm[ ;
240 |
241 | a: down e for down1 next copy exit ;
242 | a: up e for up1 next noop exit ;
243 |
244 | : for >r begin ;
245 | : next r@ while r> 1- >r repeat r> drop ;
246 |
247 | =pick org
248 |
249 | ]asm down up asm[
250 |
251 | there constant =pickbody
252 |
253 | copy ]asm return asm[
254 | 9c ]asm call asm[ bc ]asm branch asm[
255 | 9a ]asm call asm[ ba ]asm branch asm[
256 | 98 ]asm call asm[ b8 ]asm branch asm[
257 | 96 ]asm call asm[ b6 ]asm branch asm[
258 | 94 ]asm call asm[ b4 ]asm branch asm[
259 | 92 ]asm call asm[ b2 ]asm branch asm[
260 | 90 ]asm call asm[ b0 ]asm branch asm[
261 | 8e ]asm call asm[ ae ]asm branch asm[
262 | 8c ]asm call asm[ ac ]asm branch asm[
263 | 8a ]asm call asm[ aa ]asm branch asm[
264 | 88 ]asm call asm[ a8 ]asm branch asm[
265 | 86 ]asm call asm[ a6 ]asm branch asm[
266 | 84 ]asm call asm[ a4 ]asm branch asm[
267 | 82 ]asm call asm[ a2 ]asm branch asm[
268 | 80 ]asm call asm[ a0 ]asm branch asm[
269 | ]asm return asm[
270 |
271 | =cold org
272 |
273 | 0 t,
274 |
275 | there constant =uzero
276 | =base t, ( base )
277 | 0 t, ( temp )
278 | 0 t, ( >in )
279 | 0 t, ( #tib )
280 | =tib t, ( tib )
281 | 0 t, ( 'eval )
282 | 0 t, ( 'abort )
283 | 0 t, ( hld )
284 |
285 | ( context )
286 |
287 | 0 t, 0 t, 0 t, 0 t, 0 t, 0 t, 0 t, 0 t, 0 t,
288 |
289 | ( forth-wordlist )
290 |
291 | 0 t, ( na, of last definition, linked )
292 | 0 t, ( wid|0, next or last wordlist in chain )
293 | 0 t, ( na, wordlist name pointer )
294 |
295 | ( current )
296 |
297 | 0 t, ( wid, new definitions )
298 | 0 t, ( wid, head of chain )
299 |
300 | 0 t, ( dp )
301 | 0 t, ( last )
302 | 0 t, ( '?key )
303 | 0 t, ( 'emit )
304 | 0 t, ( 'boot )
305 | 0 t, ( '\ )
306 | 0 t, ( '?name )
307 | 0 t, ( '$,n )
308 | 0 t, ( 'overt )
309 | 0 t, ( '; )
310 | 0 t, ( 'create )
311 | there constant =ulast
312 | =ulast =uzero - constant =udiff
313 |
314 | =code org
315 |
316 | t: noop noop t;
317 | t: + + t;
318 | t: xor xor t;
319 | t: and and t;
320 | t: or or t;
321 | t: invert invert t;
322 | t: = = t;
323 | t: < < t;
324 | t: u< u< t;
325 | t: swap swap t;
326 | t: u> swap u< t;
327 | t: dup dup t;
328 | t: drop drop t;
329 | t: over over t;
330 | t: nip nip t;
331 | t: lshift lshift t;
332 | t: rshift rshift t;
333 | t: 1- 1- t;
334 | t: >r r> swap >r >r t; compile-only
335 | t: r> r> r> swap >r t; compile-only
336 | t: r@ r> r> dup >r swap >r t; compile-only
337 | t: @ ( a -- w ) @ t;
338 | t: ! ( w a -- ) ! t;
339 |
340 | t: <> = invert t;
341 | t: 0< 0 literal < t;
342 | t: 0= 0 literal = t;
343 | t: > swap < t;
344 | t: 0> 0 literal swap < t;
345 | t: >= < invert t;
346 | t: tuck swap over t;
347 | t: -rot swap >r swap r> t;
348 | t: 2/ 1 literal rshift t;
349 | t: 2* 1 literal lshift t;
350 | t: 1+ 1 literal + t;
351 | t: sp@ dsp ff literal and t;
352 | t: execute ( ca -- ) >r t;
353 | t: bye ( -- ) f002 literal ! t;
354 | t: c@ ( b -- c )
355 | dup @ swap 1 literal and if
356 | 8 literal rshift else ff literal and then exit t;
357 | t: c! ( c b -- )
358 | swap ff literal and dup 8 literal lshift or swap
359 | tuck dup @ swap 1 literal and 0 literal = ff literal xor
360 | >r over xor r> and xor swap ! t;
361 | t: um+ ( w w -- w cy )
362 | over over + >r
363 | r@ 0 literal >= >r
364 | over over and
365 | 0< r> or >r
366 | or 0< r> and invert 1+
367 | r> swap t;
368 | t: dovar ( -- a ) r> t; compile-only
369 | t: up dovar =up t, t;
370 | t: douser ( -- a ) up @ r> @ + t; compile-only
371 |
372 | u: base
373 | u: temp
374 | u: >in
375 | u: #tib
376 | u: tib
377 | u: 'eval
378 | u: 'abort
379 | u: hld
380 | u: context
381 | =vocs =cell * tuser +!
382 | u: forth-wordlist
383 | =cell tuser +!
384 | =cell tuser +!
385 | u: current
386 | =cell tuser +!
387 | u: dp
388 | u: last
389 | u: '?key
390 | u: 'emit
391 | u: 'boot
392 | u: '\
393 | u: 'name?
394 | u: '$,n
395 | u: 'overt
396 | u: ';
397 | u: 'create
398 |
399 | t: ?dup ( w -- w w | 0 ) dup if dup then exit t;
400 | t: rot ( w1 w2 w3 -- w2 w3 w1 ) >r swap r> swap t;
401 | t: 2drop ( w w -- ) drop drop t;
402 | t: 2dup ( w1 w2 -- w1 w2 w1 w2 ) over over t;
403 | t: negate ( n -- -n ) invert 1+ t;
404 | t: dnegate ( d -- -d )
405 | invert >r invert 1 literal um+ r> + t;
406 | t: - ( n1 n2 -- n1-n2 ) negate + t;
407 | t: abs ( n -- n ) dup 0< if negate then exit t;
408 | t: max ( n n -- n ) 2dup > if drop exit then nip t;
409 | t: min ( n n -- n ) 2dup < if drop exit then nip t;
410 | t: within ( u ul uh -- t ) over - >r - r> u< t;
411 | t: um/mod ( udl udh u -- ur uq )
412 | 2dup u< if
413 | negate f literal
414 | for >r dup um+ >r >r dup um+ r> + dup
415 | r> r@ swap >r um+ r> or if
416 | >r drop 1+ r>
417 | else
418 | drop
419 | then r>
420 | next drop swap exit
421 | then drop 2drop -1 literal dup t;
422 | t: m/mod ( d n -- r q )
423 | dup 0< dup >r if
424 | negate >r dnegate r>
425 | then >r dup 0< if
426 | r@ +
427 | then r> um/mod r> if
428 | swap negate swap then exit t;
429 | t: /mod ( n n -- r q ) over 0< swap m/mod t;
430 | t: mod ( n n -- r ) /mod drop t;
431 | t: / ( n n -- q ) /mod nip t;
432 | t: um* ( u u -- ud )
433 | 0 literal swap f literal
434 | for dup um+ >r >r dup um+ r> + r> if
435 | >r over um+ r> + then
436 | next rot drop t;
437 | t: * ( n n -- n ) um* drop t;
438 | t: m* ( n n -- d )
439 | 2dup xor 0< >r abs swap abs um* r> if
440 | dnegate then exit t;
441 | t: */mod ( n1 n2 n3 -- r q ) >r m* r> m/mod t;
442 | t: */ ( n1 n2 n3 -- q ) */mod nip t;
443 | t: cell+ ( a -- a ) =cell literal + t;
444 | t: cell- ( a -- a ) =cell literal - t;
445 | t: cells ( n -- n ) 1 literal lshift t;
446 | t: bl ( -- 32 ) 20 literal t;
447 | t: >char ( c -- c )
448 | 7f literal and dup 7f literal bl within if
449 | drop 5f literal then exit t;
450 | t: +! ( n a -- ) tuck @ + swap ! t;
451 | t: 2! ( d a -- ) swap over ! cell+ ! t;
452 | t: 2@ ( a -- d ) dup cell+ @ swap @ t;
453 | t: count ( b -- b +n ) dup 1+ swap c@ t;
454 | t: here ( -- a ) dp @ t;
455 | t: aligned ( b -- a )
456 | dup 0 literal =cell literal um/mod drop dup if
457 | =cell literal swap - then + t;
458 | t: align ( -- ) here aligned dp ! t;
459 | t: pad ( -- a ) here 50 literal + aligned t;
460 | t: @execute ( a -- ) @ ?dup if execute then exit t;
461 | t: fill ( b u c -- )
462 | swap for swap aft 2dup c! 1+ then next 2drop t;
463 | t: erase 0 literal fill t;
464 | t: digit ( u -- c ) 9 literal over < 7 literal and + 30 literal + t;
465 | t: extract ( n base -- n c ) 0 literal swap um/mod swap digit t;
466 | t: <# ( -- ) pad hld ! t;
467 | t: hold ( c -- ) hld @ 1- dup hld ! c! t;
468 | t: # ( u -- u ) base @ extract hold t;
469 | t: #s ( u -- 0 ) begin # dup while repeat t;
470 | t: sign ( n -- ) 0< if 2d literal hold then exit t;
471 | t: #> ( w -- b u ) drop hld @ pad over - t;
472 | t: str ( n -- b u ) dup >r abs <# #s r> sign #> t;
473 | t: hex ( -- ) 10 literal base ! t;
474 | t: decimal ( -- ) a literal base ! t;
475 | t: digit? ( c base -- u t )
476 | >r 30 literal - 9 literal over < if
477 | dup 20 literal > if
478 | 20 literal -
479 | then
480 | 7 literal - dup a literal < or
481 | then dup r> u< t;
482 | t: number? ( a -- n t | a f )
483 | base @ >r 0 literal over count
484 | over c@ 24 literal = if
485 | hex swap 1+ swap 1- then
486 | over c@ 2d literal = >r
487 | swap r@ - swap r@ + ?dup if
488 | 1-
489 | for dup >r c@ base @ digit?
490 | while swap base @ * + r> 1+
491 | next r@ nip if
492 | negate then swap
493 | else r> r> 2drop 2drop 0 literal
494 | then dup
495 | then r> 2drop r> base ! t;
496 | t: ?rx ( -- c t | f ) f001 literal @ 1 literal and 0= invert t;
497 | t: tx! ( c -- )
498 | begin
499 | f001 literal @ 2 literal and 0=
500 | until f000 literal ! t;
501 | t: ?key ( -- c ) '?key @execute t;
502 | t: emit ( c -- ) 'emit @execute t;
503 | t: key ( -- c )
504 | begin
505 | ?key
506 | until f000 literal @ t;
507 | t: nuf? ( -- t ) ?key dup if drop key =cr literal = then exit t;
508 | t: space ( -- ) bl emit t;
509 | t: spaces ( +n -- ) 0 literal max for aft space then next t;
510 | t: type ( b u -- ) for aft count emit then next drop t;
511 | t: cr ( -- ) =cr literal emit =lf literal emit t;
512 | t: do$ ( -- a ) r> r@ r> count + aligned >r swap >r t; compile-only
513 | t: $"| ( -- a ) do$ noop t; compile-only
514 | t: .$ ( a -- ) count type t;
515 | t: ."| ( -- ) do$ .$ t; compile-only
516 | t: .r ( n +n -- ) >r str r> over - spaces type t;
517 | t: u.r ( u +n -- ) >r <# #s #> r> over - spaces type t;
518 | t: u. ( u -- ) <# #s #> space type t;
519 | t: . ( w -- ) base @ a literal xor if u. exit then str space type t;
520 | t: cmove ( b1 b2 u -- ) for aft >r dup c@ r@ c! 1+ r> 1+ then next 2drop t;
521 | t: pack$ ( b u a -- a ) dup >r 2dup ! 1+ swap cmove r> t;
522 | t: ? ( a -- ) @ . t;
523 | t: (parse) ( b u c -- b u delta ; )
524 | temp ! over >r dup if
525 | 1- temp @ bl = if
526 | for
527 | count temp @ swap - 0< invert r@ 0> and
528 | while next r> drop 0 literal dup exit
529 | then 1- r>
530 | then over swap
531 | for
532 | count temp @ swap - temp @ bl = if
533 | 0< then
534 | while next dup >r else r> drop dup >r 1-
535 | then over - r> r> - exit
536 | then over r> - t;
537 | t: parse ( c -- b u ; )
538 | >r
539 | tib @ >in @ +
540 | #tib @ >in @ - r>
541 | (parse)
542 | >in +! t;
543 | t: .( ( -- ) 29 literal parse type t; immediate
544 | t: ( ( -- ) 29 literal parse 2drop t; immediate
545 | t: <\> ( -- ) #tib @ >in ! t; immediate
546 | t: \ ( -- ) '\ @execute t; immediate
547 | t: word ( c -- a ; ) parse here cell+ pack$ t;
548 | t: token ( -- a ; ) bl word t;
549 | t: name> ( na -- ca ) count 1f literal and + aligned t;
550 | t: same? ( a a u -- a a f \ -0+ )
551 | 1-
552 | for aft over r@ + c@
553 | over r@ + c@ - ?dup
554 | if r> drop exit then then
555 | next 0 literal t;
556 | t: find ( a va -- ca na | a f )
557 | swap
558 | dup c@ temp !
559 | dup @ >r
560 | cell+ swap
561 | begin @ dup
562 | if dup @ =mask literal and r@ xor
563 | if cell+ -1 literal else cell+ temp @ same? then
564 | else r> drop swap cell- swap exit
565 | then
566 | while 2 literal cells -
567 | repeat r> drop nip cell- dup name> swap t;
568 | t: ( a -- ca na | a f )
569 | context dup 2@ xor if cell- then >r
570 | begin
571 | r> cell+ dup >r @ ?dup
572 | while
573 | find ?dup
574 | until r> drop exit then r> drop 0 literal t;
575 | t: name? ( a -- ca na | a f ) 'name? @execute t;
576 | t: ^h ( bot eot cur -- bot eot cur )
577 | >r over r@ < dup if
578 | =bksp literal dup emit space
579 | emit then r> + t;
580 | t: tap ( bot eot cur c -- bot eot cur )
581 | dup emit over c! 1+ t;
582 | t: ktap ( bot eot cur c -- bot eot cur )
583 | dup =cr literal xor if
584 | =bksp literal xor if
585 | bl tap exit
586 | then ^h exit
587 | then drop nip dup t;
588 | t: accept ( b u -- b u )
589 | over + over
590 | begin
591 | 2dup xor
592 | while
593 | key dup bl - 7f literal u< if tap else ktap then
594 | repeat drop over - t;
595 | t: query ( -- ) tib @ 50 literal accept #tib ! drop 0 literal >in ! t;
596 | t: abort2 do$ drop t;
597 | t: abort1 space .$ 3f literal emit cr 'abort @execute abort2 t;
598 | t: if do$ abort1 exit then abort2 t; compile-only
599 | t: forget ( -- )
600 | token name? ?dup if
601 | cell- dup dp !
602 | @ dup context ! last !
603 | drop exit
604 | then abort1 t;
605 | t: $interpret ( a -- )
606 | name? ?dup if
607 | @ =comp literal and
608 | $literal compile-only" execute exit
609 | else number? if
610 | exit then abort1 then t;
611 | t: [ ( -- ) [t] $interpret literal 'eval ! t; immediate
612 | t: .ok ( -- )
613 | [t] $interpret literal 'eval @ = if
614 | ."| $literal ok"
615 | then cr t;
616 | t: eval ( -- )
617 | begin
618 | token dup c@
619 | while
620 | 'eval @execute
621 | repeat drop .ok t;
622 | t: $eval ( a u -- )
623 | >in @ >r #tib @ >r tib @ >r
624 | [t] >in literal 0 literal swap !
625 | #tib ! tib ! eval r> tib ! r> #tib ! r> >in ! t; compile-only
626 | t: preset ( -- ) =tib literal #tib cell+ ! t;
627 | t: quit ( -- )
628 | [ begin
629 | query eval
630 | again t;
631 | t: abort drop preset .ok quit t;
632 | t: ' ( -- ca ) token name? if exit then abort1 t;
633 | t: allot ( n -- ) aligned dp +! t;
634 | t: , ( w -- ) here dup cell+ dp ! ! t;
635 | t: call, ( ca -- ) 1 literal rshift 4000 literal or , t; compile-only
636 | t: ?branch ( ca -- ) 1 literal rshift 2000 literal or , t; compile-only
637 | t: branch ( ca -- ) 1 literal rshift 0000 literal or , t; compile-only
638 | t: [compile] ( -- ; ) ' call, t; immediate
639 | t: compile ( -- ) r> dup @ , cell+ >r t; compile-only
640 | t: recurse last @ name> call, t; immediate
641 | t: pick dup 2* 2* =pickbody literal + >r t;
642 | t: literal ( w -- )
643 | dup 8000 literal and if
644 | ffff literal xor [t] literal ]asm call asm[ compile invert
645 | else
646 | 8000 literal or ,
647 | then exit t; immediate
648 | t: ['] ' [t] literal ]asm call asm[ t; immediate
649 | t: $," ( -- ) 22 literal parse here pack$ count + aligned dp ! t;
650 | t: for ( -- a ) compile [t] >r ]asm call asm[ here t; compile-only immediate
651 | t: begin ( -- a ) here t; compile-only immediate
652 | t: (next) ( n -- ) r> r> ?dup if 1- >r @ >r exit then cell+ >r t; compile-only
653 | t: next ( -- ) compile (next) , t; compile-only immediate
654 | t: (do) ( limit index -- index ) r> dup >r swap rot >r >r cell+ >r t; compile-only
655 | t: do ( limit index -- ) compile (do) 0 literal , here t; compile-only immediate
656 | t: (leave) r> drop r> drop r> drop t; compile-only
657 | t: leave compile (leave) noop t; compile-only immediate
658 | t: (loop)
659 | r> r> 1+ r> 2dup <> if
660 | >r >r @ >r exit
661 | then >r 1- >r cell+ >r t; compile-only
662 | t: (unloop) r> r> drop r> drop r> drop >r t; compile-only
663 | t: unloop compile (unloop) noop t; compile-only immediate
664 | t: (?do)
665 | 2dup <> if
666 | r> dup >r swap rot >r >r cell+ >r exit
667 | then 2drop exit t; compile-only
668 | t: ?do ( limit index -- ) compile (?do) 0 literal , here t; compile-only immediate
669 | t: loop ( -- ) compile (loop) dup , compile (unloop) cell- here 1 literal rshift swap ! t; compile-only immediate
670 | t: (+loop)
671 | r> swap r> r> 2dup - >r
672 | 2 literal pick r@ + r@ xor 0< 0=
673 | 3 literal pick r> xor 0< 0= or if
674 | >r + >r @ >r exit
675 | then >r >r drop cell+ >r t; compile-only
676 | t: +loop ( n -- ) compile (+loop) dup , compile (unloop) cell- here 1 literal rshift swap ! t; compile-only immediate
677 | t: (i) ( -- index ) r> r> tuck >r >r t; compile-only
678 | t: i ( -- index ) compile (i) noop t; compile-only immediate
679 | t: until ( a -- ) ?branch t; compile-only immediate
680 | t: again ( a -- ) branch t; compile-only immediate
681 | t: if ( -- a ) here 0 literal ?branch t; compile-only immediate
682 | t: then ( a -- ) here 1 literal rshift over @ or swap ! t; compile-only immediate
683 | t: repeat ( a a -- ) branch [t] then ]asm call asm[ t; compile-only immediate
684 | t: skip here 0 literal branch t; compile-only immediate
685 | t: aft ( a -- a a ) drop [t] skip ]asm call asm[ [t] begin ]asm call asm[ swap t; compile-only immediate
686 | t: else ( a -- a ) [t] skip ]asm call asm[ swap [t] then ]asm call asm[ t; compile-only immediate
687 | t: while ( a -- a a ) [t] if ]asm call asm[ swap t; compile-only immediate
688 | t: (case) r> swap >r >r t; compile-only
689 | t: case compile (case) 30 literal t; compile-only immediate
690 | t: (of) r> r@ swap >r = t; compile-only
691 | t: of compile (of) [t] if ]asm call asm[ t; compile-only immediate
692 | t: endof [t] else ]asm call asm[ 31 literal t; compile-only immediate
693 | t: (endcase) r> r> drop >r t;
694 | t: endcase
695 | begin
696 | dup 31 literal =
697 | while
698 | drop
699 | [t] then ]asm call asm[
700 | repeat
701 | 30 literal <> $literal bad case construct."
702 | compile (endcase) noop t; compile-only immediate
703 | t: $" ( -- ; ) compile $"| $," t; compile-only immediate
704 | t: ." ( -- ; ) compile ."| $," t; compile-only immediate
705 | t: >body ( ca -- pa ) cell+ t;
706 | t: (to) ( n -- ) r> dup cell+ >r @ ! t; compile-only
707 | t: to ( n -- ) compile (to) ' >body , t; compile-only immediate
708 | t: (+to) ( n -- ) r> dup cell+ >r @ +! t; compile-only
709 | t: +to ( n -- ) compile (+to) ' >body , t; compile-only immediate
710 | t: get-current ( -- wid ) current @ t;
711 | t: set-current ( wid -- ) current ! t;
712 | t: definitions ( -- ) context @ set-current t;
713 | t: ?unique ( a -- a )
714 | dup get-current find if ."| $literal redef " over .$ then drop t;
715 | t: <$,n> ( na -- )
716 | dup c@ if
717 | ?unique
718 | dup count + aligned
719 | dp !
720 | dup last !
721 | cell-
722 | get-current @
723 | swap ! exit
724 | then drop $"| $literal name" abort1 t;
725 | t: $,n ( na -- ) '$,n @execute t;
726 | t: $compile ( a -- )
727 | name? ?dup if
728 | @ =imed literal and if
729 | execute exit
730 | else call, exit
731 | then
732 | then
733 | number? if
734 | [t] literal ]asm call asm[ exit then abort1 t;
735 | t: abort" compile $," t; immediate
736 | t: ( -- ) last @ get-current ! t;
737 | t: overt ( -- ) 'overt @execute t;
738 | t: exit r> drop t;
739 | t: <;> ( -- )
740 | compile [t] exit ]asm call asm[
741 | [ overt 0 literal here ! t; compile-only immediate
742 | t: ; ( -- ) '; @execute t; compile-only immediate
743 | t: ] ( -- ) [t] $compile literal 'eval ! t;
744 | t: : ( -- ; ) token $,n ] t;
745 | t: immediate ( -- ) =imed literal last @ @ or last @ ! t;
746 | t: user ( u -- ; ) token $,n overt compile douser , t;
747 | t: ( -- ; ) token $,n overt [t] dovar ]asm literal asm[ call, t;
748 | t: create ( -- ; ) 'create @execute t;
749 | t: variable ( -- ; ) create 0 literal , t;
750 | t: (does>) ( -- )
751 | r> 1 literal rshift here 1 literal rshift
752 | last @ name> dup cell+ ]asm 8000 literal asm[ or , ! , t; compile-only
753 | t: compile-only ( -- ) =comp literal last @ @ or last @ ! t;
754 | t: does> ( -- ) compile (does>) noop t; immediate
755 | t: char ( -- char ) ( -- c ) bl word 1+ c@ t;
756 | t: [char] char [t] literal ]asm call asm[ t; immediate
757 | t: constant create , (does>) @ t;
758 | t: defer create 0 literal ,
759 | (does>)
760 | @ ?dup 0 literal =
761 | $literal uninitialized" execute t;
762 | t: is ' >body ! t; immediate
763 | t: .id ( na -- )
764 | ?dup if
765 | count 1f literal and type exit then
766 | cr ."| $literal {noname}" t;
767 | t: wordlist ( -- wid ) align here 0 literal , dup current cell+ dup @ , ! 0 literal , t;
768 | t: order@ ( a -- u*wid u ) dup @ dup if >r cell+ order@ r> swap 1+ exit then nip t;
769 | t: get-order ( -- u*wid u ) context order@ t;
770 | t: >wid ( wid -- ) cell+ t;
771 | t: .wid ( wid -- )
772 | space dup >wid cell+ @ ?dup if .id drop exit then 0 literal u.r t;
773 | t: !wid ( wid -- ) >wid cell+ last @ swap ! t;
774 | t: vocs ( -- ) ( list all wordlists )
775 | cr ."| $literal vocs:" current cell+
776 | begin
777 | @ ?dup
778 | while
779 | dup .wid >wid
780 | repeat t;
781 | t: order ( -- ) ( list search order )
782 | cr ."| $literal search:" get-order
783 | begin
784 | ?dup
785 | while
786 | swap .wid 1-
787 | repeat
788 | cr ."| $literal define:" get-current .wid t;
789 | t: set-order ( u*wid n -- ) ( 16.6.1.2197 )
790 | dup -1 literal = if
791 | drop forth-wordlist 1 literal then
792 | =vocs literal over u< $literal over size of #vocs"
793 | context swap
794 | begin
795 | dup
796 | while
797 | >r swap over ! cell+ r>
798 | 1-
799 | repeat swap ! t;
800 | t: only ( -- ) -1 literal set-order t;
801 | t: also ( -- ) get-order over swap 1+ set-order t;
802 | t: previous ( -- ) get-order swap drop 1- set-order t;
803 | t: >voc ( wid 'name' -- )
804 | create dup , !wid
805 | (does>)
806 | @ >r get-order swap drop r> swap set-order t;
807 | t: widof ( "vocabulary" -- wid ) ' >body @ t;
808 | t: vocabulary ( 'name' -- ) wordlist >voc t;
809 | t: _type ( b u -- ) for aft count >char emit then next drop t;
810 | t: dm+ ( a u -- a )
811 | over 4 literal u.r space
812 | for aft count 3 literal u.r then next t;
813 | t: dump ( a u -- )
814 | base @ >r hex 10 literal /
815 | for cr 10 literal 2dup dm+ -rot
816 | 2 literal spaces _type
817 | next drop r> base ! t;
818 | t: .s ( ... -- ... ) cr sp@ 1- f literal and for r@ pick . next ."| $literal name) ( ca va -- na | f )
820 | begin
821 | @ ?dup
822 | while
823 | 2dup name> xor
824 | while cell-
825 | repeat nip exit
826 | then drop 0 literal t;
827 | t: >name ( ca -- na | f )
828 | >r get-order
829 | begin
830 | ?dup
831 | while
832 | swap
833 | r@ swap
834 | (>name)
835 | ?dup if
836 | >r
837 | 1- for aft drop then next
838 | r> r> drop
839 | exit
840 | then
841 | 1-
842 | repeat
843 | r> drop 0 literal t;
844 | t: see ( -- ; )
845 | ' cr
846 | begin
847 | dup @ ?dup 700c literal xor
848 | while
849 | 3fff literal and 1 literal lshift
850 | >name ?dup if
851 | space .id
852 | else
853 | dup @ 7fff literal and u.
854 | then
855 | cell+
856 | repeat 2drop t;
857 | t: (words) ( -- )
858 | cr
859 | begin
860 | @ ?dup
861 | while
862 | dup .id space cell-
863 | repeat t;
864 | t: words
865 | get-order
866 | begin
867 | ?dup
868 | while
869 | swap
870 | cr cr ."| $literal :" dup .wid cr
871 | (words)
872 | 1-
873 | repeat t;
874 | t: ver ( -- n ) =ver literal 100 literal * =ext literal + t;
875 | t: hi ( -- )
876 | cr ."| $literal eforth j1 v"
877 | base @ hex
878 | ver <# # # 2e literal hold # #>
879 | type base ! cr t;
880 | t: cold ( -- )
881 | =uzero literal =up literal =udiff literal cmove
882 | preset forth-wordlist dup context ! dup current 2! overt
883 | 4000 literal cell+ dup cell- @ $eval
884 | 'boot @execute
885 | quit
886 | cold t;
887 |
888 | target.1 -order set-current
889 |
890 | there [u] dp t!
891 | [last] [u] last t!
892 | [t] ?rx [u] '?key t!
893 | [t] tx! [u] 'emit t!
894 | [t] <\> [u] '\ t!
895 | [t] $interpret [u] 'eval t!
896 | [t] abort [u] 'abort t!
897 | [t] hi [u] 'boot t!
898 | [t] [u] 'name? t!
899 | [t] [u] 'overt t!
900 | [t] <$,n> [u] '$,n t!
901 | [t] <;> [u] '; t!
902 | [t] [u] 'create t!
903 | [t] cold 2/ =cold t!
904 |
905 | save-target j1.bin
906 | save-hex j1.hex
907 |
908 | meta.1 -order
909 |
910 | bye
911 |
--------------------------------------------------------------------------------
/j1.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #if defined(unix) || defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))
8 | #include
9 | #include
10 | int getch(void) { /* reads from keypress, doesn't echo */
11 | struct termios oldattr, newattr;
12 | int ch;
13 | tcgetattr( STDIN_FILENO, &oldattr );
14 | newattr = oldattr;
15 | newattr.c_iflag &= ~( ICRNL );
16 | newattr.c_lflag &= ~( ICANON | ECHO );
17 | tcsetattr( STDIN_FILENO, TCSANOW, &newattr );
18 | ch = getchar();
19 | tcsetattr( STDIN_FILENO, TCSANOW, &oldattr );
20 | // printf("%d\n", ch);
21 | if(ch==0x1b) exit(0);
22 | return ch==127 ? 8 : ch;
23 | }
24 | int putch(int c) { /* output character to sstdout & flush */
25 | int res=putchar(c);
26 | fflush(stdout);
27 | return res;
28 | }
29 | #endif
30 | int len = 0;
31 | static pcap_t* handle = NULL;
32 | static void pcapdev_init(void) {
33 | char errbuf[PCAP_ERRBUF_SIZE];
34 | pcap_if_t* devices;
35 | if (pcap_findalldevs(&devices, errbuf) == -1) {
36 | fprintf(stderr, "error pcap_findalldevs: %s\n", errbuf);
37 | return;
38 | }
39 | pcap_if_t* device;
40 | for(device = devices; device; device = device->next) {
41 | if (device->description) {
42 | printf(" (%s)\n", device->description);
43 | }
44 | else {
45 | fprintf(stderr, "no device\n");
46 | return;
47 | }
48 | }
49 | device = devices->next->next;
50 | if (NULL == (handle= pcap_open_live(device->name
51 | , 65536, 1, 10 , errbuf))) {
52 | fprintf(stderr, "\nUnable to open the adapter. %s is not supported by WinPcap\n");
53 | pcap_freealldevs(devices);
54 | return;
55 | }
56 | pcap_freealldevs(devices);
57 | }
58 | static unsigned short t;
59 | static unsigned short s;
60 | static unsigned short d[0x20]; /* data stack */
61 | static unsigned short r[0x20]; /* return stack */
62 | static unsigned short pc; /* program counter, counts cells */
63 | static unsigned char dsp, rsp; /* point to top entry */
64 | static unsigned short* memory; /* ram */
65 | static int sx[4] = { 0, 1, -2, -1 }; /* 2-bit sign extension */
66 |
67 | static void push(int v) // push v on the data stack
68 | {
69 | dsp = 0x1f & (dsp + 1);
70 | d[dsp] = t;
71 | t = v;
72 | }
73 |
74 | static int pop(void) // pop value from the data stack and return it
75 | {
76 | int v = t;
77 | t = d[dsp];
78 | dsp = 0x1f & (dsp - 1);
79 | return v;
80 | }
81 | char eth_poll() {
82 | const u_char* packet;
83 | struct pcap_pkthdr* header;
84 | int res = 0;
85 | while (res == 0)
86 | {
87 | res = pcap_next_ex(handle, &header, &packet);
88 | }
89 | len = (int)header->len;
90 | memcpy(&memory[0x2000], packet, len);
91 | return len;
92 | }
93 | void eth_transmit(void) {
94 | if ((pcap_sendpacket(handle, (char *)(&memory[0x2000]), len) == -1))
95 | {
96 | printf("sorry send error\n");
97 | exit(1);
98 | }
99 | }
100 |
101 | static void execute(int entrypoint)
102 | {
103 | int _pc, _t;
104 | int insn = 0x4000 | entrypoint; // first insn: "call entrypoint"
105 | pcapdev_init();
106 | do {
107 | _pc = pc + 1;
108 | if (insn & 0x8000) { // literal
109 | push(insn & 0x7fff);
110 | } else {
111 | int target = insn & 0x1fff;
112 | switch (insn >> 13) {
113 | case 0: // jump
114 | _pc = target;
115 | break;
116 | case 1: // conditional jump
117 | if (pop() == 0)
118 | _pc = target;
119 | break;
120 | case 2: // call
121 | rsp = 31 & (rsp + 1);
122 | r[rsp] = _pc << 1;
123 | _pc = target;
124 | break;
125 | case 3: // alu
126 | if (insn & 0x1000) {/* r->pc */
127 | _pc = r[rsp] >> 1;
128 | }
129 | s = d[dsp];
130 | switch ((insn >> 8) & 0xf) {
131 | case 0: _t = t; break; /* noop */
132 | case 1: _t = s; break; /* copy */
133 | case 2: _t = t+s; break; /* + */
134 | case 3: _t = t&s; break; /* and */
135 | case 4: _t = t|s; break; /* or */
136 | case 5: _t = t^s; break; /* xor */
137 | case 6: _t = ~t; break; /* invert */
138 | case 7: _t = -(t==s); break; /* = */
139 | case 8: _t = -((signed short)s < (signed short)t); break; /* < */
140 | case 9: _t = s>>t; break; /* rshift */
141 | case 0xa: _t = t-1; break; /* 1- */
142 | case 0xb: _t = r[rsp]; break; /* r@ */
143 | case 0xc: _t = (t==0xf008)?eth_poll():(t==0xf001)?1:(t==0xf000)?getch():memory[t>>1]; break; /* @ */
144 | case 0xd: _t = s<> 2) & 3]); /* rstack+- */
150 | if (insn & 0x80) /* t->s */
151 | d[dsp] = t;
152 | if (insn & 0x40) /* t->r */
153 | r[rsp] = t;
154 | if (insn & 0x20) /* s->[t] */
155 | (t==0xf008)?eth_transmit(): (t==0xf002)?(rsp=0):(t==0xf000)?putch(s):(memory[t>>1]=s); /* ! */
156 | t = _t;
157 | break;
158 | }
159 | }
160 | pc = _pc;
161 | insn = memory[pc];
162 | } while (1);
163 | }
164 | /* end of cpu */
165 |
166 | /* start of i/o demo */
167 |
168 |
169 | int main(int argc , char *argv[])
170 | {
171 | unsigned short m[0x4000]; /* 32kb or RAM */
172 | FILE *f = fopen("j1.bin", "rb");
173 | fread(m, 0x2000, sizeof(m[0]), f); /* 0kb - 16kb data and code */
174 | fclose(f);
175 | if (argc>1) { // program name is counted as one
176 | struct stat st;
177 | f = fopen(argv[1], "r");
178 | stat(argv[1], &st);
179 | (&m[0x2000])[0] = st.st_size; /* 16kb - 32kb memory mapped i/o */
180 | fread(&m[0x2001], 0x2000, sizeof(m[0]), f);
181 | fclose(f);
182 | }
183 | memory = m;
184 | execute(0x00);
185 | return 0;
186 | }
187 |
--------------------------------------------------------------------------------