Whole project can now be build using make
This commit is contained in:
parent
c661c10757
commit
12b49eff1c
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,3 +1,2 @@
|
||||||
.build
|
.build
|
||||||
.Xil
|
.Xil
|
||||||
hdmi.sdk
|
|
||||||
|
|
53
Makefile
Normal file
53
Makefile
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
BUILD = .build
|
||||||
|
|
||||||
|
VERILOG = \
|
||||||
|
src/char_map.v \
|
||||||
|
src/color_map.v \
|
||||||
|
src/dvi_top.v \
|
||||||
|
src/dvid.v \
|
||||||
|
src/encode.v \
|
||||||
|
src/hdmi.xdc \
|
||||||
|
src/simple_dual_ram.v \
|
||||||
|
|
||||||
|
.PHONY: all clean
|
||||||
|
|
||||||
|
all: $(BUILD)/impl.bin
|
||||||
|
|
||||||
|
$(BUILD)/ip/clk_wiz_0/clk_wiz_0.xci: scripts/clk_wiz_0.tcl | $(BUILD)/ip
|
||||||
|
/opt/Xilinx/Vivado/2019.1/bin/vivado -mode batch -source scripts/clk_wiz_0.tcl -nolog -nojournal
|
||||||
|
|
||||||
|
$(BUILD)/ip/microblaze_mcs_0/microblaze_mcs_0.xci: scripts/microblaze_mcs_0.tcl | $(BUILD)/ip
|
||||||
|
/opt/Xilinx/Vivado/2019.1/bin/vivado -mode batch -source scripts/microblaze_mcs_0.tcl -nolog -nojournal
|
||||||
|
|
||||||
|
$(BUILD)/5_route.dcp: $(VERILOG) $(BUILD)/ip/clk_wiz_0/clk_wiz_0.xci $(BUILD)/ip/microblaze_mcs_0/microblaze_mcs_0.xci scripts/build.tcl | $(BUILD)
|
||||||
|
/opt/Xilinx/Vivado/2019.1/bin/vivado -mode batch -source scripts/build.tcl -nolog -nojournal
|
||||||
|
|
||||||
|
$(BUILD)/impl.bin: $(BUILD)/5_route.dcp $(BUILD)/controller.elf scripts/write.tcl | $(BUILD)
|
||||||
|
/opt/Xilinx/Vivado/2019.1/bin/vivado -mode batch -source scripts/write.tcl -nolog -nojournal
|
||||||
|
|
||||||
|
$(BUILD)/bsp/system.mss: $(BUILD)/system.hdf | $(BUILD)
|
||||||
|
/opt/Xilinx/SDK/2019.1/bin/xsdk -batch scripts/sdk.tcl
|
||||||
|
|
||||||
|
$(BUILD)/bsp/microblaze_I/lib/libxil.a: $(BUILD)/bsp/system.mss
|
||||||
|
$(MAKE) -C $(BUILD)/bsp all
|
||||||
|
|
||||||
|
OBJ = \
|
||||||
|
$(BUILD)/obj/main.o
|
||||||
|
|
||||||
|
$(BUILD)/obj/%.o: software/src/%.c $(BUILD)/bsp/microblaze_I/lib/libxil.a | $(BUILD)/obj
|
||||||
|
mb-gcc -Wall -O2 -c -fmessage-length=0 -MT"$@" -I$(BUILD)/bsp/microblaze_I/include -mno-xl-reorder -mlittle-endian -mcpu=v11.0 -mxl-soft-mul -Wl,--no-relax -ffunction-sections -fdata-sections -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<"
|
||||||
|
|
||||||
|
$(BUILD)/controller.elf: $(OBJ) software/src/lscript.ld $(BUILD)/bsp/microblaze_I/lib/libxil.a | $(BUILD)
|
||||||
|
mb-gcc -Wl,-T -Wl,software/src/lscript.ld -L$(BUILD)/bsp/microblaze_I/lib -mlittle-endian -mcpu=v11.0 -mxl-soft-mul -Wl,--no-relax -Wl,--gc-sections -o "$@" $(OBJ) -Wl,--start-group,-lxil,-lgcc,-lc,--end-group
|
||||||
|
|
||||||
|
$(BUILD):
|
||||||
|
mkdir $@
|
||||||
|
|
||||||
|
$(BUILD)/ip: | $(BUILD)
|
||||||
|
mkdir $@
|
||||||
|
|
||||||
|
$(BUILD)/obj: | $(BUILD)
|
||||||
|
mkdir $@
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -fr $(BUILD)
|
BIN
controller.elf
BIN
controller.elf
Binary file not shown.
|
@ -10,17 +10,17 @@ foreach fname [glob -nocomplain -type f $out_dir/*] {
|
||||||
}
|
}
|
||||||
|
|
||||||
set step 0_ip
|
set step 0_ip
|
||||||
if { [file isdirectory ./.build/ip] } {
|
if { [file isdirectory ${out_dir}/ip] } {
|
||||||
read_ip ./.build/ip/clk_wiz_0/clk_wiz_0.xci
|
read_ip ${out_dir}/ip/clk_wiz_0/clk_wiz_0.xci
|
||||||
read_ip ./.build/ip/microblaze_mcs_0/microblaze_mcs_0.xci
|
read_ip ${out_dir}/ip/microblaze_mcs_0/microblaze_mcs_0.xci
|
||||||
} else {
|
} else {
|
||||||
file mkdir ./.build/ip
|
file mkdir ${out_dir}/ip
|
||||||
|
|
||||||
create_project -in_memory
|
create_project -in_memory
|
||||||
|
|
||||||
create_ip -name clk_wiz -vendor xilinx.com -library ip \
|
create_ip -name clk_wiz -vendor xilinx.com -library ip \
|
||||||
-version 6.0 -module_name clk_wiz_0 \
|
-version 6.0 -module_name clk_wiz_0 \
|
||||||
-dir ./.build/ip
|
-dir ${out_dir}/ip
|
||||||
|
|
||||||
set_property -dict [list \
|
set_property -dict [list \
|
||||||
CONFIG.PRIMARY_PORT {clk_in} \
|
CONFIG.PRIMARY_PORT {clk_in} \
|
||||||
|
@ -58,7 +58,7 @@ if { [file isdirectory ./.build/ip] } {
|
||||||
|
|
||||||
create_ip -name microblaze_mcs -vendor xilinx.com -library ip \
|
create_ip -name microblaze_mcs -vendor xilinx.com -library ip \
|
||||||
-version 3.0 -module_name microblaze_mcs_0 \
|
-version 3.0 -module_name microblaze_mcs_0 \
|
||||||
-dir ./.build/ip
|
-dir ${out_dir}/ip
|
||||||
|
|
||||||
set_property -dict [list \
|
set_property -dict [list \
|
||||||
CONFIG.FREQ {150} \
|
CONFIG.FREQ {150} \
|
||||||
|
@ -134,4 +134,4 @@ report_drc -file $out_dir/${step}_drc.rpt
|
||||||
write_verilog -force $out_dir/imp_netlist.v
|
write_verilog -force $out_dir/imp_netlist.v
|
||||||
write_xdc -no_fixed_only -force $out_dir/imp.xdc
|
write_xdc -no_fixed_only -force $out_dir/imp.xdc
|
||||||
|
|
||||||
source write.tcl
|
write_hwdef -force -file ${out_dir}/system.hdf
|
50
scripts/clk_wiz_0.tcl
Normal file
50
scripts/clk_wiz_0.tcl
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
set out_dir ./.build
|
||||||
|
set part_num xc7a35tftg256-1
|
||||||
|
|
||||||
|
set_part $part_num
|
||||||
|
|
||||||
|
file delete -force $out_dir/ip/clk_wiz_0
|
||||||
|
|
||||||
|
create_project -in_memory
|
||||||
|
|
||||||
|
create_ip -name clk_wiz -vendor xilinx.com -library ip \
|
||||||
|
-version 6.0 -module_name clk_wiz_0 \
|
||||||
|
-dir ${out_dir}/ip
|
||||||
|
|
||||||
|
set_property -dict [list \
|
||||||
|
CONFIG.PRIMARY_PORT {clk_in} \
|
||||||
|
CONFIG.CLKOUT2_USED {true} \
|
||||||
|
CONFIG.CLKOUT3_USED {true} \
|
||||||
|
CONFIG.CLKOUT4_USED {true} \
|
||||||
|
CONFIG.CLK_OUT1_PORT {clk_dvi} \
|
||||||
|
CONFIG.CLK_OUT2_PORT {clk_dvin} \
|
||||||
|
CONFIG.CLK_OUT3_PORT {clk_pix} \
|
||||||
|
CONFIG.CLK_OUT4_PORT {clk_mcu} \
|
||||||
|
CONFIG.CLKOUT1_REQUESTED_OUT_FREQ {375} \
|
||||||
|
CONFIG.CLKOUT2_REQUESTED_OUT_FREQ {375} \
|
||||||
|
CONFIG.CLKOUT2_REQUESTED_PHASE {180} \
|
||||||
|
CONFIG.CLKOUT3_REQUESTED_OUT_FREQ {75} \
|
||||||
|
CONFIG.CLKOUT4_REQUESTED_OUT_FREQ {150} \
|
||||||
|
CONFIG.CLKOUT1_DRIVES {BUFG} \
|
||||||
|
CONFIG.FEEDBACK_SOURCE {FDBK_AUTO} \
|
||||||
|
CONFIG.MMCM_DIVCLK_DIVIDE {1} \
|
||||||
|
CONFIG.MMCM_CLKFBOUT_MULT_F {7.500} \
|
||||||
|
CONFIG.MMCM_CLKOUT0_DIVIDE_F {2.000} \
|
||||||
|
CONFIG.MMCM_CLKOUT1_DIVIDE {2} \
|
||||||
|
CONFIG.MMCM_CLKOUT1_PHASE {180.000} \
|
||||||
|
CONFIG.MMCM_CLKOUT2_DIVIDE {10} \
|
||||||
|
CONFIG.MMCM_CLKOUT3_DIVIDE {5} \
|
||||||
|
CONFIG.NUM_OUT_CLKS {4} \
|
||||||
|
CONFIG.CLKOUT1_JITTER {111.604} \
|
||||||
|
CONFIG.CLKOUT1_PHASE_ERROR {116.405} \
|
||||||
|
CONFIG.CLKOUT2_JITTER {111.604} \
|
||||||
|
CONFIG.CLKOUT2_PHASE_ERROR {116.405} \
|
||||||
|
CONFIG.CLKOUT3_JITTER {152.549} \
|
||||||
|
CONFIG.CLKOUT3_PHASE_ERROR {116.405} \
|
||||||
|
CONFIG.CLKOUT4_JITTER {132.464} \
|
||||||
|
CONFIG.CLKOUT4_PHASE_ERROR {116.405} \
|
||||||
|
] [get_ips clk_wiz_0]
|
||||||
|
|
||||||
|
generate_target all [get_ips]
|
||||||
|
|
||||||
|
synth_ip [get_ips] > $out_dir/clk_wiz_0.log
|
36
scripts/microblaze_mcs_0.tcl
Normal file
36
scripts/microblaze_mcs_0.tcl
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
set out_dir ./.build
|
||||||
|
set part_num xc7a35tftg256-1
|
||||||
|
|
||||||
|
set_part $part_num
|
||||||
|
|
||||||
|
file delete -force $out_dir/ip/microblaze_mcs_0
|
||||||
|
|
||||||
|
create_project -in_memory
|
||||||
|
|
||||||
|
create_ip -name microblaze_mcs -vendor xilinx.com -library ip \
|
||||||
|
-version 3.0 -module_name microblaze_mcs_0 \
|
||||||
|
-dir ${out_dir}/ip
|
||||||
|
|
||||||
|
set_property -dict [list \
|
||||||
|
CONFIG.FREQ {150} \
|
||||||
|
CONFIG.MEMSIZE {131072} \
|
||||||
|
CONFIG.USE_GPO1 {1} \
|
||||||
|
CONFIG.GPO1_SIZE {16} \
|
||||||
|
CONFIG.USE_GPO2 {1} \
|
||||||
|
CONFIG.GPO2_SIZE {16} \
|
||||||
|
CONFIG.USE_GPO3 {1} \
|
||||||
|
CONFIG.GPO3_SIZE {2} \
|
||||||
|
CONFIG.USE_GPO4 {1} \
|
||||||
|
CONFIG.GPO4_SIZE {6} \
|
||||||
|
CONFIG.USE_GPI1 {1} \
|
||||||
|
CONFIG.GPI1_SIZE {8} \
|
||||||
|
CONFIG.USE_GPI2 {1} \
|
||||||
|
CONFIG.GPI2_SIZE {1} \
|
||||||
|
CONFIG.GPI2_INTERRUPT {3} \
|
||||||
|
CONFIG.USE_GPI3 {1} \
|
||||||
|
CONFIG.GPI3_SIZE {1} \
|
||||||
|
] [get_ips microblaze_mcs_0]
|
||||||
|
|
||||||
|
generate_target all [get_ips]
|
||||||
|
|
||||||
|
synth_ip [get_ips] > $out_dir/microblaze_mcs_0.log
|
9
scripts/sdk.tcl
Normal file
9
scripts/sdk.tcl
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
set out_dir ./.build
|
||||||
|
|
||||||
|
file delete -force ${out_dir}/.metadata
|
||||||
|
file delete -force ${out_dir}/hw_platform
|
||||||
|
file delete -force ${out_dir}/bsp
|
||||||
|
|
||||||
|
setws .build
|
||||||
|
createhw -name hw_platform -hwspec .build/system.hdf
|
||||||
|
createbsp -name bsp -hwproject hw_platform -os standalone -proc microblaze_I
|
212
software/src/lscript.ld
Normal file
212
software/src/lscript.ld
Normal file
|
@ -0,0 +1,212 @@
|
||||||
|
/*******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* This file is automatically generated by linker script generator.*/
|
||||||
|
/* */
|
||||||
|
/* Version: 2019.1 */
|
||||||
|
/* */
|
||||||
|
/* Copyright (c) 2010-2016 Xilinx, Inc. All rights reserved. */
|
||||||
|
/* */
|
||||||
|
/* Description : MicroBlaze Linker Script */
|
||||||
|
/* */
|
||||||
|
/*******************************************************************/
|
||||||
|
|
||||||
|
_STACK_SIZE = DEFINED(_STACK_SIZE) ? _STACK_SIZE : 0x400;
|
||||||
|
_HEAP_SIZE = DEFINED(_HEAP_SIZE) ? _HEAP_SIZE : 0x800;
|
||||||
|
|
||||||
|
/* Define Memories in the system */
|
||||||
|
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
ilmb_cntlr_Mem_dlmb_cntlr_Mem : ORIGIN = 0x50, LENGTH = 0x7FB0
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Specify the default entry point to the program */
|
||||||
|
|
||||||
|
ENTRY(_start)
|
||||||
|
|
||||||
|
/* Define the sections, and where they are mapped in memory */
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
.vectors.reset 0x0 : {
|
||||||
|
KEEP (*(.vectors.reset))
|
||||||
|
}
|
||||||
|
|
||||||
|
.vectors.sw_exception 0x8 : {
|
||||||
|
KEEP (*(.vectors.sw_exception))
|
||||||
|
}
|
||||||
|
|
||||||
|
.vectors.interrupt 0x10 : {
|
||||||
|
KEEP (*(.vectors.interrupt))
|
||||||
|
}
|
||||||
|
|
||||||
|
.vectors.hw_exception 0x20 : {
|
||||||
|
KEEP (*(.vectors.hw_exception))
|
||||||
|
}
|
||||||
|
|
||||||
|
.text : {
|
||||||
|
*(.text)
|
||||||
|
*(.text.*)
|
||||||
|
*(.gnu.linkonce.t.*)
|
||||||
|
} > ilmb_cntlr_Mem_dlmb_cntlr_Mem
|
||||||
|
|
||||||
|
.init : {
|
||||||
|
KEEP (*(.init))
|
||||||
|
} > ilmb_cntlr_Mem_dlmb_cntlr_Mem
|
||||||
|
|
||||||
|
.fini : {
|
||||||
|
KEEP (*(.fini))
|
||||||
|
} > ilmb_cntlr_Mem_dlmb_cntlr_Mem
|
||||||
|
|
||||||
|
.ctors : {
|
||||||
|
__CTOR_LIST__ = .;
|
||||||
|
___CTORS_LIST___ = .;
|
||||||
|
KEEP (*crtbegin.o(.ctors))
|
||||||
|
KEEP (*(EXCLUDE_FILE(*crtend.o) .ctors))
|
||||||
|
KEEP (*(SORT(.ctors.*)))
|
||||||
|
KEEP (*(.ctors))
|
||||||
|
__CTOR_END__ = .;
|
||||||
|
___CTORS_END___ = .;
|
||||||
|
} > ilmb_cntlr_Mem_dlmb_cntlr_Mem
|
||||||
|
|
||||||
|
.dtors : {
|
||||||
|
__DTOR_LIST__ = .;
|
||||||
|
___DTORS_LIST___ = .;
|
||||||
|
KEEP (*crtbegin.o(.dtors))
|
||||||
|
KEEP (*(EXCLUDE_FILE(*crtend.o) .dtors))
|
||||||
|
KEEP (*(SORT(.dtors.*)))
|
||||||
|
KEEP (*(.dtors))
|
||||||
|
PROVIDE(__DTOR_END__ = .);
|
||||||
|
PROVIDE(___DTORS_END___ = .);
|
||||||
|
} > ilmb_cntlr_Mem_dlmb_cntlr_Mem
|
||||||
|
|
||||||
|
.rodata : {
|
||||||
|
__rodata_start = .;
|
||||||
|
*(.rodata)
|
||||||
|
*(.rodata.*)
|
||||||
|
*(.gnu.linkonce.r.*)
|
||||||
|
__rodata_end = .;
|
||||||
|
} > ilmb_cntlr_Mem_dlmb_cntlr_Mem
|
||||||
|
|
||||||
|
.sdata2 : {
|
||||||
|
. = ALIGN(8);
|
||||||
|
__sdata2_start = .;
|
||||||
|
*(.sdata2)
|
||||||
|
*(.sdata2.*)
|
||||||
|
*(.gnu.linkonce.s2.*)
|
||||||
|
. = ALIGN(8);
|
||||||
|
__sdata2_end = .;
|
||||||
|
} > ilmb_cntlr_Mem_dlmb_cntlr_Mem
|
||||||
|
|
||||||
|
.sbss2 : {
|
||||||
|
__sbss2_start = .;
|
||||||
|
*(.sbss2)
|
||||||
|
*(.sbss2.*)
|
||||||
|
*(.gnu.linkonce.sb2.*)
|
||||||
|
__sbss2_end = .;
|
||||||
|
} > ilmb_cntlr_Mem_dlmb_cntlr_Mem
|
||||||
|
|
||||||
|
.data : {
|
||||||
|
. = ALIGN(4);
|
||||||
|
__data_start = .;
|
||||||
|
*(.data)
|
||||||
|
*(.data.*)
|
||||||
|
*(.gnu.linkonce.d.*)
|
||||||
|
__data_end = .;
|
||||||
|
} > ilmb_cntlr_Mem_dlmb_cntlr_Mem
|
||||||
|
|
||||||
|
.got : {
|
||||||
|
*(.got)
|
||||||
|
} > ilmb_cntlr_Mem_dlmb_cntlr_Mem
|
||||||
|
|
||||||
|
.got1 : {
|
||||||
|
*(.got1)
|
||||||
|
} > ilmb_cntlr_Mem_dlmb_cntlr_Mem
|
||||||
|
|
||||||
|
.got2 : {
|
||||||
|
*(.got2)
|
||||||
|
} > ilmb_cntlr_Mem_dlmb_cntlr_Mem
|
||||||
|
|
||||||
|
.eh_frame : {
|
||||||
|
*(.eh_frame)
|
||||||
|
} > ilmb_cntlr_Mem_dlmb_cntlr_Mem
|
||||||
|
|
||||||
|
.jcr : {
|
||||||
|
*(.jcr)
|
||||||
|
} > ilmb_cntlr_Mem_dlmb_cntlr_Mem
|
||||||
|
|
||||||
|
.gcc_except_table : {
|
||||||
|
*(.gcc_except_table)
|
||||||
|
} > ilmb_cntlr_Mem_dlmb_cntlr_Mem
|
||||||
|
|
||||||
|
.sdata : {
|
||||||
|
. = ALIGN(8);
|
||||||
|
__sdata_start = .;
|
||||||
|
*(.sdata)
|
||||||
|
*(.sdata.*)
|
||||||
|
*(.gnu.linkonce.s.*)
|
||||||
|
__sdata_end = .;
|
||||||
|
} > ilmb_cntlr_Mem_dlmb_cntlr_Mem
|
||||||
|
|
||||||
|
.sbss (NOLOAD) : {
|
||||||
|
. = ALIGN(4);
|
||||||
|
__sbss_start = .;
|
||||||
|
*(.sbss)
|
||||||
|
*(.sbss.*)
|
||||||
|
*(.gnu.linkonce.sb.*)
|
||||||
|
. = ALIGN(8);
|
||||||
|
__sbss_end = .;
|
||||||
|
} > ilmb_cntlr_Mem_dlmb_cntlr_Mem
|
||||||
|
|
||||||
|
.tdata : {
|
||||||
|
__tdata_start = .;
|
||||||
|
*(.tdata)
|
||||||
|
*(.tdata.*)
|
||||||
|
*(.gnu.linkonce.td.*)
|
||||||
|
__tdata_end = .;
|
||||||
|
} > ilmb_cntlr_Mem_dlmb_cntlr_Mem
|
||||||
|
|
||||||
|
.tbss : {
|
||||||
|
__tbss_start = .;
|
||||||
|
*(.tbss)
|
||||||
|
*(.tbss.*)
|
||||||
|
*(.gnu.linkonce.tb.*)
|
||||||
|
__tbss_end = .;
|
||||||
|
} > ilmb_cntlr_Mem_dlmb_cntlr_Mem
|
||||||
|
|
||||||
|
.bss (NOLOAD) : {
|
||||||
|
. = ALIGN(4);
|
||||||
|
__bss_start = .;
|
||||||
|
*(.bss)
|
||||||
|
*(.bss.*)
|
||||||
|
*(.gnu.linkonce.b.*)
|
||||||
|
*(COMMON)
|
||||||
|
. = ALIGN(4);
|
||||||
|
__bss_end = .;
|
||||||
|
} > ilmb_cntlr_Mem_dlmb_cntlr_Mem
|
||||||
|
|
||||||
|
_SDA_BASE_ = __sdata_start + ((__sbss_end - __sdata_start) / 2 );
|
||||||
|
|
||||||
|
_SDA2_BASE_ = __sdata2_start + ((__sbss2_end - __sdata2_start) / 2 );
|
||||||
|
|
||||||
|
/* Generate Stack and Heap definitions */
|
||||||
|
|
||||||
|
.heap (NOLOAD) : {
|
||||||
|
. = ALIGN(8);
|
||||||
|
_heap = .;
|
||||||
|
_heap_start = .;
|
||||||
|
. += _HEAP_SIZE;
|
||||||
|
_heap_end = .;
|
||||||
|
} > ilmb_cntlr_Mem_dlmb_cntlr_Mem
|
||||||
|
|
||||||
|
.stack (NOLOAD) : {
|
||||||
|
_stack_end = .;
|
||||||
|
. += _STACK_SIZE;
|
||||||
|
. = ALIGN(8);
|
||||||
|
_stack = .;
|
||||||
|
__stack = _stack;
|
||||||
|
} > ilmb_cntlr_Mem_dlmb_cntlr_Mem
|
||||||
|
|
||||||
|
_end = .;
|
||||||
|
}
|
||||||
|
|
268
software/src/main.c
Normal file
268
software/src/main.c
Normal file
|
@ -0,0 +1,268 @@
|
||||||
|
#include <xparameters.h>
|
||||||
|
#include <xiomodule.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
XIOModule gpo;
|
||||||
|
|
||||||
|
int8_t x = 0;
|
||||||
|
int8_t y = 0;
|
||||||
|
int8_t scroll = 0;
|
||||||
|
|
||||||
|
uint8_t reversed = 0;
|
||||||
|
uint8_t foreground = 0b111;
|
||||||
|
uint8_t background = 0;
|
||||||
|
|
||||||
|
uint16_t properties = 0;
|
||||||
|
|
||||||
|
void commit() {
|
||||||
|
XIOModule_DiscreteSet(&gpo, 3, 1);
|
||||||
|
XIOModule_DiscreteClear(&gpo, 3, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void calculate_properties() {
|
||||||
|
if (reversed) {
|
||||||
|
properties = ((foreground << 4) + background) << 8;
|
||||||
|
} else {
|
||||||
|
properties = ((background << 4) + foreground) << 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_foreground(uint8_t color) {
|
||||||
|
foreground = color;
|
||||||
|
|
||||||
|
calculate_properties();
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_background(uint8_t color) {
|
||||||
|
background = color;
|
||||||
|
|
||||||
|
calculate_properties();
|
||||||
|
}
|
||||||
|
|
||||||
|
void reverse(uint8_t enable) {
|
||||||
|
reversed = enable;
|
||||||
|
|
||||||
|
calculate_properties();
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear_screen() {
|
||||||
|
reverse(0);
|
||||||
|
set_foreground(0b111);
|
||||||
|
set_background(0);
|
||||||
|
XIOModule_DiscreteWrite(&gpo, 1, 0);
|
||||||
|
XIOModule_DiscreteWrite(&gpo, 2, 0);
|
||||||
|
XIOModule_DiscreteSet(&gpo, 3, 1);
|
||||||
|
|
||||||
|
for (int y = 0; y < (45+2); ++y) {
|
||||||
|
int16_t temp = (y << 8);
|
||||||
|
for (int x = 0; x < (80+24); ++x) {
|
||||||
|
XIOModule_DiscreteWrite(&gpo, 2, temp + x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
XIOModule_DiscreteClear(&gpo, 3, 1);
|
||||||
|
|
||||||
|
x = 0;
|
||||||
|
y = 0;
|
||||||
|
scroll = 0;
|
||||||
|
XIOModule_DiscreteWrite(&gpo, 2, (y << 8) + x);
|
||||||
|
XIOModule_DiscreteWrite(&gpo, 4, scroll);
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear_eol() {
|
||||||
|
reverse(0);
|
||||||
|
set_foreground(0b111);
|
||||||
|
set_background(0);
|
||||||
|
|
||||||
|
int16_t temp = (y << 8);
|
||||||
|
|
||||||
|
XIOModule_DiscreteWrite(&gpo, 1, 0);
|
||||||
|
XIOModule_DiscreteWrite(&gpo, 2, temp + x);
|
||||||
|
XIOModule_DiscreteSet(&gpo, 3, 1);
|
||||||
|
|
||||||
|
for (int i = x; i < (80+24); ++i) {
|
||||||
|
XIOModule_DiscreteWrite(&gpo, 2, temp + i);
|
||||||
|
}
|
||||||
|
|
||||||
|
XIOModule_DiscreteClear(&gpo, 3, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void write(uint8_t c) {
|
||||||
|
XIOModule_DiscreteWrite(&gpo, 1, properties + c);
|
||||||
|
XIOModule_DiscreteWrite(&gpo, 2, (y << 8) + x);
|
||||||
|
commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
void next() {
|
||||||
|
x++;
|
||||||
|
if (x >= 80) {
|
||||||
|
y++;
|
||||||
|
x %= 80;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (y >= 45) {
|
||||||
|
y--;
|
||||||
|
scroll = (scroll + 1) % 45;
|
||||||
|
XIOModule_DiscreteWrite(&gpo, 4, scroll);
|
||||||
|
clear_eol();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// @todo This does not appear to work quite correctly
|
||||||
|
void previous() {
|
||||||
|
x--;
|
||||||
|
if (x < 0) {
|
||||||
|
y--;
|
||||||
|
x %= 80;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (y < 0) {
|
||||||
|
y = 0;
|
||||||
|
x = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t data = 0;
|
||||||
|
uint8_t had = 0;
|
||||||
|
uint8_t escape = 0;
|
||||||
|
uint8_t escape_parameter_1 = 0;
|
||||||
|
uint8_t escape_parameter_2 = 0;
|
||||||
|
|
||||||
|
void clock() {
|
||||||
|
uint8_t io_write = XIOModule_DiscreteRead(&gpo, 3);
|
||||||
|
if (io_write && !had) {
|
||||||
|
XIOModule_DiscreteClear(&gpo, 3, 2);
|
||||||
|
had = 1;
|
||||||
|
data = XIOModule_DiscreteRead(&gpo, 1) & 0xFF;
|
||||||
|
|
||||||
|
if (escape == 1) {
|
||||||
|
if (data == '[') {
|
||||||
|
escape = 2;
|
||||||
|
} else {
|
||||||
|
escape = 0;
|
||||||
|
}
|
||||||
|
} else if (escape) {
|
||||||
|
switch (data) {
|
||||||
|
// For now we are only going to implement what we actually use
|
||||||
|
case 'K':
|
||||||
|
// Assume parameter 0
|
||||||
|
clear_eol();
|
||||||
|
escape = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'H':
|
||||||
|
if (escape_parameter_1 == 0) {
|
||||||
|
escape_parameter_1 = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (escape_parameter_2 == 0) {
|
||||||
|
escape_parameter_2 = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
x = escape_parameter_1 - 1;
|
||||||
|
y = escape_parameter_2 - 1;
|
||||||
|
escape = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'm':
|
||||||
|
if (escape_parameter_1 == 0) {
|
||||||
|
reverse(0);
|
||||||
|
set_foreground(0b111);
|
||||||
|
set_background(0);
|
||||||
|
} else if (escape_parameter_1 == 7) {
|
||||||
|
reverse(1);
|
||||||
|
} else if (escape_parameter_1 >= 30 && escape_parameter_1 <= 37) {
|
||||||
|
set_foreground(escape_parameter_1 - 30);
|
||||||
|
} else if (escape_parameter_1 >= 40 && escape_parameter_1 <= 47) {
|
||||||
|
set_background(escape_parameter_1 - 40);
|
||||||
|
} else if (escape_parameter_1 >= 90 && escape_parameter_1 <= 97) {
|
||||||
|
set_foreground(escape_parameter_1 - 90 + 8);
|
||||||
|
} else if (escape_parameter_1 >= 100 && escape_parameter_1 <= 107) {
|
||||||
|
set_background(escape_parameter_1 - 100 + 8);
|
||||||
|
}
|
||||||
|
escape = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'J':
|
||||||
|
// Assume parameter 2
|
||||||
|
clear_screen();
|
||||||
|
escape = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '0' ... '9':
|
||||||
|
escape_parameter_1 *= 10;
|
||||||
|
escape_parameter_1 += (data - 48);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ';':
|
||||||
|
escape_parameter_2 = escape_parameter_1;
|
||||||
|
escape_parameter_1 = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
escape = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
switch (data) {
|
||||||
|
case '\n':
|
||||||
|
y++;
|
||||||
|
if (y >= 45) {
|
||||||
|
y--;
|
||||||
|
scroll = (scroll + 1) % 45;
|
||||||
|
XIOModule_DiscreteWrite(&gpo, 4, scroll);
|
||||||
|
clear_eol();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '\r':
|
||||||
|
x = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x08:
|
||||||
|
previous();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x1B:
|
||||||
|
escape = 1;
|
||||||
|
escape_parameter_1 = 0;
|
||||||
|
escape_parameter_2 = 0;
|
||||||
|
// Handle escape code
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
write(data);
|
||||||
|
next();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
XIOModule_DiscreteWrite(&gpo, 2, (y << 8) + x);
|
||||||
|
} else if (had && !io_write) {
|
||||||
|
had = 0;
|
||||||
|
XIOModule_DiscreteSet(&gpo, 3, 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
XIOModule_Initialize(&gpo, XPAR_IOMODULE_0_DEVICE_ID); // Initialize the GPO module
|
||||||
|
|
||||||
|
microblaze_register_handler(XIOModule_DeviceInterruptHandler,
|
||||||
|
XPAR_IOMODULE_0_DEVICE_ID); // register the interrupt handler
|
||||||
|
|
||||||
|
XIOModule_Start(&gpo); // start the GPO module
|
||||||
|
|
||||||
|
XIOModule_Connect(&gpo, XIN_IOMODULE_GPI_2_INTERRUPT_INTR, clock,
|
||||||
|
NULL); // register timerTick() as our interrupt handler
|
||||||
|
XIOModule_Enable(&gpo, XIN_IOMODULE_GPI_2_INTERRUPT_INTR); // enable the interrupt
|
||||||
|
|
||||||
|
microblaze_enable_interrupts(); // enable global interrupts
|
||||||
|
|
||||||
|
// Clear the screen
|
||||||
|
clear_screen();
|
||||||
|
|
||||||
|
XIOModule_DiscreteSet(&gpo, 3, 2);
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user