Some more stuff

This commit is contained in:
jimmystones
2021-06-21 17:12:12 +01:00
parent a15319a151
commit 2c12c9383a
24 changed files with 1426 additions and 1302 deletions

View File

@@ -32,7 +32,6 @@ module emu
output [7:0] VGA_B,
output VGA_HS,
output VGA_VS,
output VGA_DE, // = ~(VBlank | HBlank)
output VGA_F1,
output [1:0] VGA_SL,
output VGA_SCALER, // Force VGA scaler
@@ -246,8 +245,7 @@ soc soc(
.VGA_VS(VGA_VS),
.VGA_R(VGA_R),
.VGA_G(VGA_G),
.VGA_B(VGA_B),
.VGA_DE(VGA_DE)
.VGA_B(VGA_B)
);

14
README.MD Normal file
View File

@@ -0,0 +1,14 @@
# Memory Map
Start|End|Length|Name
---|---|---|---
0x0000|0x3FFF|0x4000|Program ROM
0x4000|0x43FF|0x0400|Char ROM
0x6000|0x6000|0x0001|System inputs (video timings etc)
0x6001|0x6001|0x0001|Control inputs
0x8000|0xBFFF|0x4000|Work RAM
0xC000|0xC3FF|0xDFFF|Char RAM

View File

@@ -4,5 +4,7 @@ set_global_assignment -name QIP_FILE rtl/tv80/TV80.qip
set_global_assignment -name CDF_FILE jtag.cdf
set_global_assignment -name QIP_FILE sys/sys.qip
set_global_assignment -name VERILOG_FILE rtl/video.v
set_global_assignment -name VERILOG_FILE rtl/JTFRAME/jtframe_vtimer.v
set_global_assignment -name VERILOG_FILE rtl/soc.v
set_global_assignment -name SYSTEMVERILOG_FILE rtl/dpram.v
set_global_assignment -name VERILOG_FILE rtl/dpram.v
set_global_assignment -name VERILOG_FILE rtl/spram.v

View File

@@ -0,0 +1,172 @@
/* This file is part of JTFRAME.
JTFRAME program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
JTFRAME program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with JTFRAME. If not, see <http://www.gnu.org/licenses/>.
Author: Jose Tejada Gomez. Twitter: @topapate
Version: 1.0
Date: 2-5-2020 */
// Generic video timing generator
// By default vertical blanking and sync toggle with horizontal blanking and sync
// but some games make these signals toggle in the middle of the vertical ones
// See Side Arms for an example
// By default, H/V counters end with the blanking signal, for some games it
// may be useful to define the end count differently
// Depending on how the graphic hardware is designed, H/V count start and end values
// can be important, as well as when signals toggle (like in a 8-multiple of H)
// but these limitations can be trade off for different ones if the design is changed
// A default VS pulse of three lines and HS pulse of 4.5us will fit the TV standard
// but some games use different values
// See the parameter definition below to alter the needed parameters when
// instantiating the module
module jtframe_vtimer(
input clk,
input pxl_cen,
output reg [8:0] vdump,
output reg [8:0] vrender,
output reg [8:0] vrender1,
output reg [8:0] H,
output reg Hinit,
output reg Vinit,
output reg LHBL,
output reg LVBL,
output reg HS,
output reg VS
);
reg LVBL2, LVBL1;
`ifdef SIMULATION
initial begin
Hinit = 0;
Vinit = 0;
LHBL = 0;
LVBL = 1;
LVBL1 = 1;
LVBL2 = 1;
HS = 0;
VS = 0;
H = 0;
vrender1 = 0;
vrender = 0;
vdump = 0;
end
`endif
// Default values suit Contra arcade
parameter [8:0] V_START = 9'd0,
VB_START = 9'd239,
VB_END = 9'd255,
VCNT_END = VB_END,
VS_START = 9'd244,
VS_END = (VS_START+9'd3),
HB_END = 9'd395,
HB_START = HB_END-9'd116,
HCNT_END = HB_END,
HS_START = 9'd330,
HS_END = HS_START+9'd27, // Default 4.5us for a 6MHz clock
H_VB = HB_START,
H_VS = HS_START,
H_VNEXT = HS_START,
HINIT = H_VNEXT,
HCNT_START=9'd0;
// H counter
always @(posedge clk) if(pxl_cen) begin
Hinit <= H == HINIT;
H <= H == HCNT_END ? HCNT_START : (H+9'd1);
end
always @(posedge clk) if(pxl_cen) begin
if( H == H_VNEXT ) begin
Vinit <= vdump==VB_END;
vrender1 <= vrender1==VCNT_END ? V_START : vrender1 + 9'd1;
vrender <= vrender1;
vdump <= vrender;
end
if( H == HB_START ) begin
LHBL <= 0;
end else if( H == HB_END ) LHBL <= 1;
if( H == H_VB ) begin
{ LVBL, LVBL1 } <= { LVBL1, LVBL2 };
case( vrender1 )
VB_START: LVBL2 <= 0;
VB_END: LVBL2 <= 1;
default:;
endcase // vdump
end
if (H==HS_START) begin
HS <= 1;
end
if( H==H_VS ) begin
if (vdump==VS_START) VS <= 1;
if (vdump==VS_END ) VS <= 0;
end
if (H==HS_END) HS <= 0;
end
`ifdef SIMULATION_VTIMER
reg LVBL_Last, LHBL_last, VS_last, HS_last;
wire new_line = LHBL_last && !LHBL;
wire new_frame = LVBL_Last && !LVBL;
wire new_HS = HS && !HS_last;
wire new_VS = VS && !VS_last;
integer vbcnt=0, vcnt=0, hcnt=0, hbcnt=0, vs0, vs1, hs0, hs1;
integer framecnt=0;
`ifdef SIMULATION_VTIMER_FCLK
real fclk = `SIMULATION_VTIMER_FCLK;
`else
real fclk = 6e6;
`endif
always @(posedge clk) if(pxl_cen) begin
LHBL_last <= LHBL;
HS_last <= HS;
VS_last <= VS;
if( new_HS ) hs1 <= hbcnt;
if( new_VS ) vs1 <= vbcnt;
if( new_line ) begin
LVBL_Last <= LVBL;
if( new_frame ) begin
if( framecnt>0 ) begin
$display("VB count = %3d (sync at %2d)", vbcnt, vs1 );
$display("vdump total = %3d (%.2f Hz)", vcnt, fclk/(hcnt*vcnt) );
$display("HB count = %3d (sync at %2d)", hbcnt, hs1 );
$display("H total = %3d (%.2f Hz)", hcnt, fclk/hcnt );
$display("-------------" );
end
vbcnt <= 1;
vcnt <= 1;
framecnt <= framecnt+1;
end else begin
vcnt <= vcnt+1;
if( !LVBL ) vbcnt <= vbcnt+1;
end
hbcnt <= 1;
hcnt <= 1;
end else begin
hcnt <= hcnt+1;
if( !LHBL ) hbcnt <= hbcnt+1;
end
end
`endif
endmodule

View File

@@ -1,5 +1,3 @@
`timescale 1ns / 1ps
module dpram #(
parameter address_width = 10,
parameter data_width = 8
@@ -31,7 +29,6 @@ reg [data_width-1:0] mem [ramLength-1:0];
end
`endif
// Port A
always @(posedge clock_a) begin
q_a <= mem[address_a];
if(wren_a) begin
@@ -39,8 +36,7 @@ always @(posedge clock_a) begin
mem[address_a] <= data_a;
end
end
// Port B
always @(posedge clock_b) begin
q_b <= mem[address_b];
if(wren_b) begin

164
rtl/soc.v
View File

@@ -2,9 +2,11 @@
module soc (
input clk_sys,
input clk_pix,
input reset,
input [13:0] dn_addr,
input dn_wr,
input [7:0] dn_data,
input [7:0] dn_index,
input [7:0] inputs,
output VGA_HS,
output VGA_VS,
@@ -12,33 +14,39 @@ module soc (
output [7:0] VGA_G,
output [7:0] VGA_B,
output VGA_HB,
output VGA_VB,
output VGA_DE
output VGA_VB
);
// Video subsystem
video video (
.pclk ( clk_pix ),
.cpu_clk ( clk_sys ),
.cpu_wr ( !cpu_wr_n && !cpu_addr[15] ),
.cpu_addr ( cpu_addr[15:0] ),
.cpu_data ( cpu_dout ),
.hs (VGA_HS),
.vs (VGA_VS),
.r (VGA_R),
.g (VGA_G),
.b (VGA_B),
.hb (VGA_HB),
.vb (VGA_VB),
.de (VGA_DE)
wire _hblank;
wire _vblank;
assign VGA_HB = ~_hblank;
assign VGA_VB = ~_vblank;
wire [8:0] hcnt;
wire [8:0] vcnt;
// Display timing module from JTFRAME
jtframe_vtimer #(
.HB_START(9'd320)
) vtimer
(
.clk(clk_sys),
.pxl_cen(clk_pix),
.vdump(vcnt),
.vrender(),
.vrender1(),
.H(hcnt),
.Hinit(),
.Vinit(),
.LHBL(_hblank),
.LVBL(_vblank),
.HS(VGA_HS),
.VS(VGA_VS)
);
// The CPU is kept in reset for 256 cycles after power on
reg [7:0] cpu_reset_cnt = 8'h00;
wire cpu_reset = (cpu_reset_cnt != 255);
always @(posedge clk_sys)
if(cpu_reset_cnt != 255)
cpu_reset_cnt <= cpu_reset_cnt + 8'd1;
// DEBUG OUTPUT
assign VGA_R = hcnt[7:0];
assign VGA_B = vcnt[7:0];
// CPU control signals
wire [15:0] cpu_addr;
@@ -50,18 +58,18 @@ wire cpu_mreq_n;
// include Z80 CPU
tv80s T80x (
.reset_n ( !cpu_reset ),
.clk ( clk_sys ),
.wait_n ( 1'b1 ),
.int_n ( 1'b1 ),
.nmi_n ( 1'b1 ),
.busrq_n ( 1'b1 ),
.mreq_n ( cpu_mreq_n ),
.rd_n ( cpu_rd_n ),
.wr_n ( cpu_wr_n ),
.A ( cpu_addr ),
.di ( cpu_din ),
.dout ( cpu_dout ),
.reset_n ( !reset ),
.clk ( clk_sys ),
.wait_n ( 1'b1 ),
.int_n ( 1'b1 ),
.nmi_n ( 1'b1 ),
.busrq_n ( 1'b1 ),
.mreq_n ( cpu_mreq_n ),
.rd_n ( cpu_rd_n ),
.wr_n ( cpu_wr_n ),
.A ( cpu_addr ),
.di ( cpu_din ),
.dout ( cpu_dout ),
.m1_n (),
.iorq_n (),
.rfsh_n (),
@@ -69,56 +77,96 @@ tv80s T80x (
.busak_n ()
);
// RAM bank data outs
wire [7:0] pgrom_data_out;
wire [7:0] chrom_data_out;
wire [7:0] wkram_data_out;
wire [7:0] chram_data_out;
wire [7:0] ram_data_out;
wire [7:0] rom_data_out;
// RAM bank data outs
wire [10:0] chrom_addr;
wire rom_cs = cpu_addr[15:14] == 2'b00;
wire ram_cs = cpu_addr[15] == 1'b1;
// CPU address decodes
wire pgrom_cs = cpu_addr[15:14] == 2'b00;
wire chrom_cs = cpu_addr[15:14] == 2'b00;
wire wkram_cs = cpu_addr[15] == 1'b1;
wire chram_cs = cpu_addr[15] == 1'b1;
wire in0_cs = cpu_addr == 16'h4000;
wire in1_cs = cpu_addr == 16'h4001;
assign cpu_din = ram_cs ? ram_data_out :
rom_cs ? rom_data_out :
// CPU data mux
assign cpu_din = pgrom_cs ? pgrom_data_out :
wkram_cs ? wkram_data_out :
wkram_cs ? wkram_data_out :
in0_cs ? {VGA_HS, VGA_VS, 6'b101000} :
in1_cs ? inputs :
8'b00000000;
always @(posedge clk_sys)
begin
//$display("%b %x %d", cpu_addr, cpu_addr, cpu_addr);
//$display("%x = %x", cpu_addr, cpu_din);
// $display("rom_cs %b ram_cs %b in1_cs %b", rom_cs, ram_cs, in1_cs);
end
// Rom upload write enables
wire pgrom_wr = dn_wr && dn_index == 8'b0;
wire chrom_wr = dn_wr && dn_index == 8'b1;
dpram #(12,8) rom
// MEMORY
// ------
// Program ROM - 0x0000 - 0x3FFF (0x4000 / 16384 bytes)
dpram #(14,8) pgrom
(
.clock_a(clk_sys),
.address_a(cpu_addr[11:0]),
.address_a(cpu_addr[13:0]),
.wren_a(1'b0),
.data_a(),
.q_a(rom_data_out),
.q_a(pgrom_data_out),
.clock_b(clk_sys),
.address_b(dn_addr[11:0]),
.wren_b(dn_wr),
.address_b(dn_addr[13:0]),
.wren_b(pgrom_wr),
.data_b(dn_data),
.q_b()
);
dpram #(12,8) ram
// Char ROM - 0x4000 - 0x43FF (0x0400 / 1024 bytes)
dpram #(11,8) chrom
(
.clock_a(clk_sys),
.address_a(cpu_addr[11:0]),
.wren_a(!cpu_wr_n && ram_cs),
.data_a(cpu_dout),
.q_a(ram_data_out),
.address_a(chrom_addr),
.wren_a(1'b0),
.data_a(),
.q_a(chrom_data_out),
.clock_b(clk_sys),
.address_b(cpu_addr[11:0]),
.address_b(dn_addr[10:0]),
.wren_b(chrom_wr),
.data_b(dn_data),
.q_b()
);
// Work RAM - 0x8000 - 0xBFFF (0x4000 / 16384 bytes)
spram #(14,8) wkram
(
.clock(clk_sys),
.address(cpu_addr[13:0]),
.wren(!cpu_wr_n && wkram_cs),
.data(cpu_dout),
.q(wkram_data_out)
);
// Char RAM - 0xC000 - 0xDFFF (0x2000 / 8192 bytes)
dpram #(13,8) chram
(
.clock_a(clk_sys),
.address_a(cpu_addr[12:0]),
.wren_a(!cpu_wr_n && chram_cs),
.data_a(cpu_dout),
.q_a(chram_data_out),
.clock_b(clk_sys),
.address_b(),
.wren_b(1'b0),
.data_b(),
.q_b()
);
endmodule

34
rtl/spram.v Normal file
View File

@@ -0,0 +1,34 @@
module spram #(
parameter address_width = 10,
parameter data_width = 8
) (
input wire clock,
input wire wren,
input wire [address_width-1:0] address,
input wire [data_width-1:0] data,
output reg [data_width-1:0] q
);
localparam ramLength = (2**address_width);
reg [data_width-1:0] mem [ramLength-1:0];
`ifdef SIMULATION
integer j;
initial
begin
for (j = 0; j < ramLength; j = j + 1)
begin
mem[j] = 0;
end
end
`endif
always @(posedge clock) begin
q <= mem[address];
if(wren) begin
q <= data;
mem[address] <= data;
end
end
endmodule

View File

@@ -1,120 +0,0 @@
`timescale 1ns / 1ps
module video (
input pclk, // pixel clock
input cpu_clk, //
input cpu_wr,
input [15:0] cpu_addr,
input [7:0] cpu_data,
// VGA output
output reg hs,
output reg vs,
output [7:0] r,
output [7:0] g,
output [7:0] b,
output reg hb,
output reg vb,
output reg de
);
// 640x400 70HZ VESA according to http://tinyvga.com/vga-timing/640x400@70Hz
parameter H = 640; // width of visible area
parameter HFP = 16; // unused time before hsync
parameter HS = 96; // width of hsync
parameter HBP = 48; // unused time after hsync
parameter V = 400; // height of visible area
parameter VFP = 12; // unused time before vsync
parameter VS = 2; // width of vsync
parameter VBP = 35; // unused time after vsync
parameter VGA_WIDTH = 320; // width of backbuffer
parameter VGA_HEIGHT = 200; // height of backbuffer
reg[9:0] h_cnt; // horizontal pixel counter
reg[9:0] v_cnt; // vertical pixel counter
reg [15:0] video_counter;
reg [7:0] pixel;
// 16000 bytes of internal video memory for 160x100 pixel at 8 Bit (RGB 332)
reg [7:0] vmem [(VGA_WIDTH*VGA_HEIGHT)-1:0];
// horizontal pixel counter
always@(posedge pclk)
begin
if(h_cnt==H+HFP+HS+HBP-1) h_cnt <= 0;
else h_cnt <= h_cnt + 1;
// generate negative hsync signal
if(h_cnt == H+HFP) hs <= 1'b0;
if(h_cnt == H+HFP+HS) hs <= 1'b1;
end
// veritical pixel counter
always@(posedge pclk)
begin
// the vertical counter is processed at the begin of each hsync
if(h_cnt == H+HFP)
begin
if(v_cnt==VS+VBP+V+VFP-1) v_cnt <= 0;
else v_cnt <= v_cnt + 1;
// generate positive vsync signal
if(v_cnt == V+VFP) vs <= 1'b1;
if(v_cnt == V+VFP+VS) vs <= 1'b0;
end
end
// write VRAM via CPU interface
always @(posedge cpu_clk)
begin
if(cpu_wr)
vmem[cpu_addr] <= cpu_data;
end
always@(posedge pclk)
begin
// The video counter is being reset at the begin of each vsync.
// Otherwise it's increased every fourth pixel in the visible area.
// At the end of the first three of four lines the counter is
// decreased by the total line length to display the same contents
// for four lines so 100 different lines are displayed on the 400
// VGA lines.
// visible area?
if(v_cnt < V)
vb<=0;
else
vb<=1;
if(h_cnt < H)
hb<=0;
else
hb<=1;
if((v_cnt < V) && (h_cnt < H)) begin
if(h_cnt[0] == 1'b1)
video_counter <= video_counter + 16'd1;
//pixel <= (v_cnt[4] ^ h_cnt[4])?8'h00:8'hff; // checkboard
//pixel <= video_counter[7:0]; // color pattern
pixel <= vmem[video_counter]; // read VRAM
de<=1;
end else begin
if(h_cnt == H+HFP) begin
if(v_cnt == V+VFP)
video_counter <= 16'd0;
else if((v_cnt < V) && (v_cnt[0] != 1'b1))
video_counter <= video_counter - VGA_WIDTH;
de<=0;
end
pixel <= 8'hF0; // black
end
end
// seperate 8 bits into three colors (332)
assign r = { pixel[7:5], pixel[7:5] , pixel[7:6]};
assign g = { pixel[4:2], pixel[4:2] , pixel[4:3]};
assign b = { pixel[1:0], pixel[1:0] , pixel[1:0], pixel[1:0] };
endmodule

View File

@@ -13,10 +13,11 @@
.globl _cls
.globl _put_pixel
.globl _abs
.globl _puts
.globl _color
.globl _cur_y
.globl _cur_x
.globl _y
.globl _color
.globl _input1_cache
.globl _input0_cache
.globl _vsync_last
@@ -35,8 +36,8 @@
; ram data
;--------------------------------------------------------
.area _DATA
_input0 = 0x4000
_input1 = 0x4001
_input0 = 0x6000
_input1 = 0x6001
_hsync::
.ds 1
_hsync_last::
@@ -49,8 +50,6 @@ _input0_cache::
.ds 1
_input1_cache::
.ds 1
_color::
.ds 1
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
@@ -58,9 +57,11 @@ _color::
_y::
.ds 1
_cur_x::
.ds 2
.ds 1
_cur_y::
.ds 2
.ds 1
_color::
.ds 1
;--------------------------------------------------------
; absolute external ram data
;--------------------------------------------------------
@@ -81,7 +82,7 @@ _cur_y::
; code
;--------------------------------------------------------
.area _CODE
;boot_rom.c:26: int putchar(int c) {
;boot_rom.c:25: int putchar(int c) {
; ---------------------------------
; Function putchar
; ---------------------------------
@@ -89,31 +90,37 @@ _putchar::
push ix
ld ix,#0
add ix,sp
ld hl, #-11
ld hl, #-7
add hl, sp
ld sp, hl
;boot_rom.c:28: unsigned int *dptr = (unsigned int*)(VGA_WIDTH*(8*cur_y) + 8*cur_x);
ld hl, (_cur_y)
add hl, hl
add hl, hl
add hl, hl
ld bc, (_VGA_WIDTH)
push hl
push bc
call __mulint
pop af
pop af
ld c, l
ld b, h
ld hl, (_cur_x)
add hl, hl
;boot_rom.c:27: unsigned char *dptr = (unsigned char*)(160*(8*cur_y) + 8*cur_x);
ld hl,#_cur_y + 0
ld c, (hl)
ld b, #0x00
ld l, c
ld h, b
add hl, hl
add hl, hl
add hl, bc
inc sp
inc sp
push hl
;boot_rom.c:31: if(c < 32) {
add hl, hl
add hl, hl
add hl, hl
add hl, hl
add hl, hl
add hl, hl
add hl, hl
add hl, hl
ex de, hl
ld iy, #_cur_x
ld l, 0 (iy)
ld h, #0x00
add hl, hl
add hl, hl
add hl, hl
add hl, de
ld -5 (ix), l
ld -4 (ix), h
;boot_rom.c:30: if(c < 32) {
ld a, 4 (ix)
sub a, #0x20
ld a, 5 (ix)
@@ -122,43 +129,39 @@ _putchar::
rra
sbc a, #0x80
jr NC,00108$
;boot_rom.c:32: if(c == '\r') { cur_x=0; }
;boot_rom.c:31: if(c == '\r')
ld a, 4 (ix)
sub a, #0x0d
or a, 5 (ix)
jr NZ,00102$
ld hl, #0x0000
ld (_cur_x), hl
;boot_rom.c:32: cur_x=0;
ld 0 (iy), #0x00
00102$:
;boot_rom.c:33: if(c == '\n') {
;boot_rom.c:34: if(c == '\n') {
ld a, 4 (ix)
sub a, #0x0a
or a, 5 (ix)
jp NZ,00122$
;boot_rom.c:34: cur_y++;
;boot_rom.c:35: cur_y++;
ld iy, #_cur_y
inc 0 (iy)
jr NZ,00192$
inc 1 (iy)
00192$:
;boot_rom.c:35: cur_x=0;
ld hl, #0x0000
ld (_cur_x), hl
;boot_rom.c:36: if(cur_y >= 12) { cur_y = 0; }
;boot_rom.c:36: cur_x=0;
ld iy, #_cur_x
ld 0 (iy), #0x00
;boot_rom.c:38: if(cur_y >= 12)
ld iy, #_cur_y
ld a, 0 (iy)
sub a, #0x0c
ld a, 1 (iy)
sbc a, #0x00
jp C,00122$
ld l, #0x00
ld (_cur_y), hl
;boot_rom.c:38: return;
;boot_rom.c:39: cur_y = 0;
ld 0 (iy), #0x00
;boot_rom.c:41: return;
jp 00122$
00108$:
;boot_rom.c:41: if(c < 0) return;
;boot_rom.c:44: if(c < 0) return;
bit 7, 5 (ix)
jp NZ,00122$
;boot_rom.c:43: p = font+8*(unsigned char)(c-32);
;boot_rom.c:46: p = font+8*(unsigned char)(c-32);
ld bc, #_font+0
ld a, 4 (ix)
add a, #0xe0
@@ -168,133 +171,89 @@ _putchar::
add hl, hl
add hl, hl
add hl, bc
ld -9 (ix), l
ld -8 (ix), h
;boot_rom.c:44: for(i=0;i<8;i++) {
ld bc, #0x0000
ld c, l
ld b, h
;boot_rom.c:47: for(i=0;i<8;i++) {
ld -2 (ix), #0x00
00120$:
;boot_rom.c:45: unsigned char l = *p++;
ld l, -9 (ix)
ld h, -8 (ix)
ld a, (hl)
ld -3 (ix), a
ld a, -9 (ix)
add a, #0x02
ld -9 (ix), a
jr NC,00193$
inc -8 (ix)
00193$:
;boot_rom.c:46: for(j=0;j<8;j++) {
ld -2 (ix), #0x08
ld -1 (ix), #0x00
pop de
push de
;boot_rom.c:48: unsigned char l = *p++;
ld a, (bc)
ld -1 (ix), a
inc bc
;boot_rom.c:49: for(j=0;j<8;j++) {
ld -3 (ix), #0x08
ld e, -5 (ix)
ld d, -4 (ix)
00119$:
;boot_rom.c:47: *dptr++ = (l & 0x80) ? color : 0x00;
ld -5 (ix), e
ld -4 (ix), d
;boot_rom.c:50: *dptr++ = (l & 0x80)?color:0x00;
inc sp
inc sp
push de
inc de
inc de
bit 7, -3 (ix)
bit 7, -1 (ix)
jr Z,00124$
ld a,(#_color + 0)
ld -7 (ix), a
ld -6 (ix), #0x00
ld iy, #_color
ld l, 0 (iy)
jr 00125$
00124$:
ld -7 (ix), #0x00
ld -6 (ix), #0x00
ld hl, #0x0000
00125$:
ld l, -5 (ix)
ld h, -4 (ix)
ld a, -7 (ix)
ld (hl), a
inc hl
ld a, -6 (ix)
ld (hl), a
;boot_rom.c:48: l <<= 1;
ld a, -3 (ix)
add a, a
ld -3 (ix), a
ld l, -2 (ix)
ld h, -1 (ix)
dec hl
ld -2 (ix), l
ld -1 (ix), h
;boot_rom.c:46: for(j=0;j<8;j++) {
ld a, h
or a, l
jr NZ,00119$
;boot_rom.c:50: dptr += (VGA_WIDTH-8);
ld hl, (_VGA_WIDTH)
ld a, l
add a, #0xf8
ld l, a
ld a, h
adc a, #0xff
ld h, a
add hl, hl
add hl, de
inc sp
inc sp
pop hl
push hl
;boot_rom.c:44: for(i=0;i<8;i++) {
inc bc
ld a, c
ld (hl), a
;boot_rom.c:51: l <<= 1;
ld a, -1 (ix)
add a, a
ld -1 (ix), a
dec -3 (ix)
ld a, -3 (ix)
;boot_rom.c:49: for(j=0;j<8;j++) {
or a, a
jr NZ,00119$
;boot_rom.c:53: dptr += (160-8);
ld hl, #0x0098
add hl, de
ld -5 (ix), l
ld -4 (ix), h
;boot_rom.c:47: for(i=0;i<8;i++) {
inc -2 (ix)
ld a, -2 (ix)
sub a, #0x08
ld a, b
rla
ccf
rra
sbc a, #0x80
jp C, 00120$
;boot_rom.c:53: cur_x++;
jr C,00120$
;boot_rom.c:56: cur_x++;
ld iy, #_cur_x
inc 0 (iy)
jr NZ,00195$
inc 1 (iy)
00195$:
;boot_rom.c:54: if(cur_x >= 20) {
;boot_rom.c:57: if(cur_x >= 20) {
ld a, 0 (iy)
sub a, #0x14
ld a, 1 (iy)
sbc a, #0x00
jr C,00116$
;boot_rom.c:55: cur_x = 0;
ld hl, #0x0000
ld (_cur_x), hl
;boot_rom.c:56: cur_y++;
jr C,00122$
;boot_rom.c:58: cur_x = 0;
ld 0 (iy), #0x00
;boot_rom.c:59: cur_y++;
ld iy, #_cur_y
inc 0 (iy)
jr NZ,00196$
inc 1 (iy)
00196$:
;boot_rom.c:58: if(cur_y >= 12)
;boot_rom.c:61: if(cur_y >= 12)
ld a, 0 (iy)
sub a, #0x0c
ld a, 1 (iy)
sbc a, #0x00
jr C,00116$
;boot_rom.c:59: cur_y = 0;
ld l, #0x00
ld (_cur_y), hl
00116$:
;boot_rom.c:61: return;
jr C,00122$
;boot_rom.c:62: cur_y = 0;
ld 0 (iy), #0x00
00122$:
;boot_rom.c:62: }
;boot_rom.c:64: }
ld sp, ix
pop ix
ret
_VGA_WIDTH:
.dw #0x0140
.dw #0x00a0
_VGA_HEIGHT:
.dw #0x00c8
;boot_rom.c:65: void put_pixel(unsigned int x, unsigned int y, unsigned char color) {
.dw #0x0064
;boot_rom.c:67: void put_pixel(unsigned int x, unsigned int y, unsigned char color) {
; ---------------------------------
; Function put_pixel
; ---------------------------------
_put_pixel::
;boot_rom.c:66: *((unsigned int*)(VGA_WIDTH*y+x)) = color;
;boot_rom.c:68: *((unsigned int*)(VGA_WIDTH*y+x)) = color;
ld hl, (_VGA_WIDTH)
ld iy, #4
add iy, sp
@@ -324,9 +283,9 @@ _put_pixel::
ld (hl), c
inc hl
ld (hl), b
;boot_rom.c:67: }
;boot_rom.c:69: }
ret
;boot_rom.c:69: void cls(unsigned char color) {
;boot_rom.c:71: void cls(unsigned char color) {
; ---------------------------------
; Function cls
; ---------------------------------
@@ -335,63 +294,46 @@ _cls::
ld ix,#0
add ix,sp
dec sp
;boot_rom.c:73: for(i=0;i<VGA_HEIGHT;i++) {
ld bc, #0x0000
00107$:
ld hl, (_VGA_HEIGHT)
ld a, c
sub a, l
ld a, b
sbc a, h
jr NC,00102$
;boot_rom.c:74: for(unsigned int x=0;x<VGA_HEIGHT;x++) {
ld a, 4 (ix)
ld -1 (ix), a
;boot_rom.c:73: unsigned int *p = (unsigned int*)0;
ld de, #0x0000
00104$:
ld hl, (_VGA_HEIGHT)
ld a, e
sub a, l
ld a, d
sbc a, h
jr NC,00115$
;boot_rom.c:76: put_pixel(x,i, color);
push bc
;boot_rom.c:74: for(i=0;i<VGA_HEIGHT;i++) {
ld -1 (ix), #0x00
00103$:
ld bc, (_VGA_HEIGHT)
ld l, -1 (ix)
ld h, #0x00
cp a, a
sbc hl, bc
jr NC,00105$
;boot_rom.c:75: memset(p, color, VGA_WIDTH);
ld c, e
ld b, d
ld l, 4 (ix)
ld h, #0x00
ld iy, (_VGA_WIDTH)
push de
ld a, -1 (ix)
push af
inc sp
push iy
push hl
push bc
push de
call _put_pixel
pop af
pop af
inc sp
call _memset
ld hl, #6
add hl, sp
ld sp, hl
pop de
pop bc
;boot_rom.c:77: color++;
;boot_rom.c:76: p += VGA_WIDTH;
ld hl, (_VGA_WIDTH)
add hl, hl
add hl, de
ex de, hl
;boot_rom.c:74: for(i=0;i<VGA_HEIGHT;i++) {
inc -1 (ix)
;boot_rom.c:74: for(unsigned int x=0;x<VGA_HEIGHT;x++) {
inc de
jr 00104$
00115$:
ld a, -1 (ix)
ld 4 (ix), a
;boot_rom.c:73: for(i=0;i<VGA_HEIGHT;i++) {
inc bc
jr 00107$
00102$:
;boot_rom.c:81: cur_x = 0;
ld hl, #0x0000
ld (_cur_x), hl
;boot_rom.c:82: cur_y = 0;
ld l, #0x00
ld (_cur_y), hl
;boot_rom.c:83: }
jr 00103$
00105$:
;boot_rom.c:78: }
inc sp
pop ix
ret
;boot_rom.c:86: void draw_line(unsigned int x, unsigned int y,
;boot_rom.c:81: void draw_line(unsigned int x, unsigned int y,
; ---------------------------------
; Function draw_line
; ---------------------------------
@@ -402,7 +344,7 @@ _draw_line::
ld hl, #-18
add hl, sp
ld sp, hl
;boot_rom.c:90: int dx1 = (x<x2)?1:-1;
;boot_rom.c:85: int dx1 = (x<x2)?1:-1;
ld a, 4 (ix)
sub a, 8 (ix)
ld a, 5 (ix)
@@ -413,9 +355,9 @@ _draw_line::
00112$:
ld bc, #0xffff
00113$:
ld -12 (ix), c
ld -11 (ix), b
;boot_rom.c:91: int dy1 = (y<y2)?1:-1;
ld -6 (ix), c
ld -5 (ix), b
;boot_rom.c:86: int dy1 = (y<y2)?1:-1;
ld a, 6 (ix)
sub a, 10 (ix)
ld a, 7 (ix)
@@ -426,9 +368,9 @@ _draw_line::
00114$:
ld bc, #0xffff
00115$:
ld -10 (ix), c
ld -9 (ix), b
;boot_rom.c:94: longest = abs(x2 - x);
ld -8 (ix), c
ld -7 (ix), b
;boot_rom.c:89: longest = abs(x2 - x);
ld a, 8 (ix)
sub a, 4 (ix)
ld c, a
@@ -438,9 +380,9 @@ _draw_line::
push bc
call _abs
pop af
ld -2 (ix), l
ld -1 (ix), h
;boot_rom.c:95: shortest = abs(y2 - y);
ld -10 (ix), l
ld -9 (ix), h
;boot_rom.c:90: shortest = abs(y2 - y);
ld a, 10 (ix)
sub a, 6 (ix)
ld e, a
@@ -452,58 +394,58 @@ _draw_line::
call _abs
pop af
pop de
ld -4 (ix), l
ld -3 (ix), h
;boot_rom.c:96: if(longest<shortest) {
ld a, -2 (ix)
sub a, -4 (ix)
ld a, -1 (ix)
sbc a, -3 (ix)
ld -2 (ix), l
ld -1 (ix), h
;boot_rom.c:91: if(longest<shortest) {
ld a, -10 (ix)
sub a, -2 (ix)
ld a, -9 (ix)
sbc a, -1 (ix)
jr NC,00102$
;boot_rom.c:97: longest = abs(y2 - y);
;boot_rom.c:92: longest = abs(y2 - y);
push de
call _abs
pop af
ld -10 (ix), l
ld -9 (ix), h
;boot_rom.c:93: shortest = abs(x2 - x);
push bc
call _abs
pop af
ld -2 (ix), l
ld -1 (ix), h
;boot_rom.c:98: shortest = abs(x2 - x);
push bc
call _abs
pop af
ld -4 (ix), l
ld -3 (ix), h
;boot_rom.c:99: dx2 = 0;
;boot_rom.c:94: dx2 = 0;
ld bc, #0x0000
;boot_rom.c:100: dy2 = dy1;
ld a, -10 (ix)
ld -8 (ix), a
ld a, -9 (ix)
ld -7 (ix), a
;boot_rom.c:95: dy2 = dy1;
ld a, -8 (ix)
ld -12 (ix), a
ld a, -7 (ix)
ld -11 (ix), a
jr 00103$
00102$:
;boot_rom.c:102: dx2 = dx1;
ld c, -12 (ix)
ld b, -11 (ix)
;boot_rom.c:103: dy2 = 0;
ld -8 (ix), #0x00
ld -7 (ix), #0x00
;boot_rom.c:97: dx2 = dx1;
ld c, -6 (ix)
ld b, -5 (ix)
;boot_rom.c:98: dy2 = 0;
ld -12 (ix), #0x00
ld -11 (ix), #0x00
00103$:
;boot_rom.c:106: numerator = longest/2;
ld e, -2 (ix)
ld d, -1 (ix)
;boot_rom.c:101: numerator = longest/2;
ld e, -10 (ix)
ld d, -9 (ix)
srl d
rr e
;boot_rom.c:107: for(i=0;i<=longest;i++) {
ld a, -2 (ix)
sub a, -4 (ix)
;boot_rom.c:102: for(i=0;i<=longest;i++) {
ld a, -10 (ix)
sub a, -2 (ix)
ld -14 (ix), a
ld a, -1 (ix)
sbc a, -3 (ix)
ld a, -9 (ix)
sbc a, -1 (ix)
ld -13 (ix), a
ld -6 (ix), #0x00
ld -5 (ix), #0x00
ld -4 (ix), #0x00
ld -3 (ix), #0x00
00108$:
;boot_rom.c:108: put_pixel(x,y,color) ;
;boot_rom.c:103: put_pixel(x,y,color) ;
push bc
push de
ld a, 12 (ix)
@@ -521,32 +463,32 @@ _draw_line::
inc sp
pop de
pop bc
;boot_rom.c:110: numerator += shortest ;
ld a, -4 (ix)
;boot_rom.c:105: numerator += shortest ;
ld a, -2 (ix)
add a, e
ld -16 (ix), a
ld a, -3 (ix)
ld a, -1 (ix)
adc a, d
ld -15 (ix), a
;boot_rom.c:109: if(numerator >= longest-shortest) {
;boot_rom.c:104: if(numerator >= longest-shortest) {
ld a, e
sub a, -14 (ix)
ld a, d
sbc a, -13 (ix)
jr C,00105$
;boot_rom.c:110: numerator += shortest ;
;boot_rom.c:111: numerator -= longest ;
;boot_rom.c:105: numerator += shortest ;
;boot_rom.c:106: numerator -= longest ;
ld a, -16 (ix)
ld d, -15 (ix)
sub a, -2 (ix)
sub a, -10 (ix)
ld e, a
ld a, d
sbc a, -1 (ix)
sbc a, -9 (ix)
ld d, a
;boot_rom.c:112: x += dx1;
ld a, -12 (ix)
;boot_rom.c:107: x += dx1;
ld a, -6 (ix)
ld -18 (ix), a
ld a, -11 (ix)
ld a, -5 (ix)
ld -17 (ix), a
ld a, 4 (ix)
add a, -18 (ix)
@@ -554,33 +496,7 @@ _draw_line::
ld a, 5 (ix)
adc a, -17 (ix)
ld 5 (ix), a
;boot_rom.c:113: y += dy1;
ld a, -10 (ix)
ld -18 (ix), a
ld a, -9 (ix)
ld -17 (ix), a
ld a, 6 (ix)
add a, -18 (ix)
ld 6 (ix), a
ld a, 7 (ix)
adc a, -17 (ix)
ld 7 (ix), a
jr 00109$
00105$:
;boot_rom.c:115: numerator += shortest ;
ld e, -16 (ix)
ld d, -15 (ix)
;boot_rom.c:116: x += dx2;
inc sp
inc sp
push bc
ld a, 4 (ix)
add a, -18 (ix)
ld 4 (ix), a
ld a, 5 (ix)
adc a, -17 (ix)
ld 5 (ix), a
;boot_rom.c:117: y += dy2;
;boot_rom.c:108: y += dy1;
ld a, -8 (ix)
ld -18 (ix), a
ld a, -7 (ix)
@@ -591,80 +507,134 @@ _draw_line::
ld a, 7 (ix)
adc a, -17 (ix)
ld 7 (ix), a
jr 00109$
00105$:
;boot_rom.c:110: numerator += shortest ;
ld e, -16 (ix)
ld d, -15 (ix)
;boot_rom.c:111: x += dx2;
inc sp
inc sp
push bc
ld a, 4 (ix)
add a, -18 (ix)
ld 4 (ix), a
ld a, 5 (ix)
adc a, -17 (ix)
ld 5 (ix), a
;boot_rom.c:112: y += dy2;
ld a, -12 (ix)
ld -18 (ix), a
ld a, -11 (ix)
ld -17 (ix), a
ld a, 6 (ix)
add a, -18 (ix)
ld 6 (ix), a
ld a, 7 (ix)
adc a, -17 (ix)
ld 7 (ix), a
00109$:
;boot_rom.c:107: for(i=0;i<=longest;i++) {
inc -6 (ix)
;boot_rom.c:102: for(i=0;i<=longest;i++) {
inc -4 (ix)
jr NZ,00142$
inc -5 (ix)
inc -3 (ix)
00142$:
ld a, -2 (ix)
sub a, -6 (ix)
ld a, -1 (ix)
sbc a, -5 (ix)
ld a, -10 (ix)
sub a, -4 (ix)
ld a, -9 (ix)
sbc a, -3 (ix)
jp NC, 00108$
;boot_rom.c:120: }
;boot_rom.c:115: }
ld sp, ix
pop ix
ret
;boot_rom.c:123: void main() {
;boot_rom.c:119: void main() {
; ---------------------------------
; Function main
; ---------------------------------
_main::
;boot_rom.c:124: while(1) {
;boot_rom.c:120: while(1) {
00108$:
;boot_rom.c:127: input0_cache = input0;
;boot_rom.c:123: input0_cache = input0;
ld a,(#_input0 + 0)
ld iy, #_input0_cache
ld 0 (iy), a
;boot_rom.c:128: hsync = input0_cache & 0x80;
;boot_rom.c:124: hsync = input0_cache & 0x80;
ld c, 0 (iy)
ld a, c
and a, #0x80
ld (#_hsync + 0),a
;boot_rom.c:129: vsync = input0_cache & 0x40;
;boot_rom.c:125: vsync = input0_cache & 0x40;
ld a, c
and a, #0x40
ld (#_vsync + 0),a
;boot_rom.c:131: if(hsync && !hsync_last){
;boot_rom.c:127: if(hsync && !hsync_last){
ld a,(#_hsync + 0)
or a, a
jr Z,00102$
ld a,(#_hsync_last + 0)
or a, a
jr NZ,00102$
;boot_rom.c:132: y++;
;boot_rom.c:128: y++;
ld hl, #_y+0
inc (hl)
00102$:
;boot_rom.c:134: if(vsync && !vsync_last){
;boot_rom.c:130: if(vsync && !vsync_last){
ld a,(#_vsync + 0)
or a, a
jr Z,00105$
ld a,(#_vsync_last + 0)
or a, a
jr NZ,00105$
;boot_rom.c:135: y=0;
;boot_rom.c:131: y=0;
ld hl,#_y + 0
ld (hl), #0x00
;boot_rom.c:138: input1_cache = input1;
;boot_rom.c:133: cur_x = 0;
ld hl,#_cur_x + 0
ld (hl), #0x00
;boot_rom.c:134: cur_y = 0;
ld hl,#_cur_y + 0
ld (hl), #0x00
;boot_rom.c:135: color++;
ld iy, #_color
inc 0 (iy)
;boot_rom.c:136: cls(~color);
ld a, 0 (iy)
cpl
ld b, a
push bc
inc sp
call _cls
inc sp
;boot_rom.c:137: puts(" << Z80 SoC >>\n");
ld hl, #___str_0
push hl
call _puts
pop af
;boot_rom.c:140: input1_cache = input1;
ld a,(#_input1 + 0)
ld (#_input1_cache + 0),a
00105$:
;boot_rom.c:141: hsync_last = hsync;
;boot_rom.c:143: hsync_last = hsync;
ld a,(#_hsync + 0)
ld (#_hsync_last + 0),a
;boot_rom.c:142: vsync_last = vsync;
;boot_rom.c:144: vsync_last = vsync;
ld a,(#_vsync + 0)
ld (#_vsync_last + 0),a
;boot_rom.c:144: }
;boot_rom.c:146: }
jr 00108$
___str_0:
.ascii " << Z80 SoC >>"
.db 0x0a
.db 0x00
.area _CODE
.area _INITIALIZER
__xinit__y:
.db #0x00 ; 0
__xinit__cur_x:
.dw #0x0000
.db #0x00 ; 0
__xinit__cur_y:
.dw #0x0000
.db #0x00 ; 0
__xinit__color:
.db #0x66 ; 102 'f'
.area _CABS (ABS)

Binary file not shown.

View File

@@ -5,11 +5,11 @@
extern unsigned char font[];
const unsigned int VGA_WIDTH = 320;
const unsigned int VGA_HEIGHT = 200;
const unsigned int VGA_WIDTH = 160;
const unsigned int VGA_HEIGHT = 100;
unsigned char __at (0x4000) input0;
unsigned char __at (0x4001) input1;
unsigned char __at (0x6000) input0;
unsigned char __at (0x6001) input1;
unsigned char y = 0;
unsigned char hsync;
@@ -19,21 +19,24 @@ unsigned char vsync_last;
unsigned char input0_cache;
unsigned char input1_cache;
unsigned int cur_x=0;
unsigned int cur_y=0;
unsigned char color;
unsigned char cur_x=0, cur_y=0;
int putchar(int c) {
unsigned int *p;
unsigned int *dptr = (unsigned int*)(VGA_WIDTH*(8*cur_y) + 8*cur_x);
int i, j;
unsigned char *p;
unsigned char *dptr = (unsigned char*)(160*(8*cur_y) + 8*cur_x);
char i, j;
if(c < 32) {
if(c == '\r') { cur_x=0; }
if(c == '\r')
cur_x=0;
if(c == '\n') {
cur_y++;
cur_x=0;
if(cur_y >= 12) { cur_y = 0; }
if(cur_y >= 12)
cur_y = 0;
}
return;
}
@@ -44,10 +47,10 @@ int putchar(int c) {
for(i=0;i<8;i++) {
unsigned char l = *p++;
for(j=0;j<8;j++) {
*dptr++ = (l & 0x80) ? color : 0x00;
*dptr++ = (l & 0x80)?color:0x00;
l <<= 1;
}
dptr += (VGA_WIDTH-8);
dptr += (160-8);
}
cur_x++;
@@ -58,7 +61,6 @@ int putchar(int c) {
if(cur_y >= 12)
cur_y = 0;
}
return;
}
// draw a pixel
@@ -67,19 +69,12 @@ void put_pixel(unsigned int x, unsigned int y, unsigned char color) {
}
void cls(unsigned char color) {
unsigned int i;
unsigned char i;
unsigned int *p = (unsigned int*)0;
for(i=0;i<VGA_HEIGHT;i++) {
for(unsigned int x=0;x<VGA_HEIGHT;x++) {
//memset(p, color, VGA_WIDTH);
put_pixel(x,i, color);
color++;
//p += VGA_WIDTH;
}
memset(p, color, VGA_WIDTH);
p += VGA_WIDTH;
}
cur_x = 0;
cur_y = 0;
}
// bresenham algorithm to draw a line
@@ -119,6 +114,7 @@ void draw_line(unsigned int x, unsigned int y,
}
}
char color = 0x66;
void main() {
while(1) {
@@ -134,6 +130,12 @@ void main() {
if(vsync && !vsync_last){
y=0;
cur_x = 0;
cur_y = 0;
color++;
cls(~color);
puts(" << Z80 SoC >>\n");
// process inputs
input1_cache = input1;

File diff suppressed because it is too large Load Diff

View File

@@ -7,7 +7,7 @@ Area Addr Size Decimal Bytes (A
Value Global Global Defined In Module
----- -------------------------------- ------------------------
00000000 .__.ABS.
00000000 .__.ABS. puts
00000000 l__BSEG
00000000 l__BSS
00000000 l__CABS
@@ -36,46 +36,49 @@ Area Addr Size Decimal Bytes (A
00000003 l__HEADER6
00000003 l__HEADER7
00000004 l__HEADER1
00000007 l__DATA
00000006 l__DATA
0000000C l__HEADER8
0000000F l__GSINIT
00000200 s__CODE
00000305 l__INITIALIZED
00000305 l__INITIALIZER
00000423 l__CODE
00000623 s__HOME
00000623 s__INITIALIZER
00000928 s__GSINIT
00000937 s__GSFINAL
00004000 _input0 boot_rom
00004001 _input1 boot_rom
00000304 l__INITIALIZED
00000304 l__INITIALIZER
00000447 l__CODE
00000647 s__HOME
00000647 s__INITIALIZER
0000094B s__GSINIT
0000095A s__GSFINAL
00006000 _input0 boot_rom
00006001 _input1 boot_rom
00008000 s__DATA
00008007 s__INITIALIZED
0000830C s__BSEG
0000830C s__BSS
0000830C s__HEAP
00008006 s__INITIALIZED
0000830A s__BSEG
0000830A s__BSS
0000830A s__HEAP
ASxxxx Linker V03.00 + NoICE + sdld, page 2.
Hexadecimal [32-Bits]
Area Addr Size Decimal Bytes (Attributes)
-------------------------------- ---- ---- ------- ----- ------------
_CODE 00000200 00000423 = 1059. bytes (REL,CON)
_CODE 00000200 00000447 = 1095. bytes (REL,CON)
Value Global Global Defined In Module
----- -------------------------------- ------------------------
00000200 __clock crt0
00000204 _exit crt0
0000020A _putchar boot_rom
0000036B _VGA_WIDTH boot_rom
0000036D _VGA_HEIGHT boot_rom
0000036F _put_pixel boot_rom
000003A2 _cls boot_rom
000003F8 _draw_line boot_rom
000005AF _main boot_rom
000005FD _abs
00000609 __mulint
0000060F __mul16
0000031A _VGA_WIDTH boot_rom
0000031C _VGA_HEIGHT boot_rom
0000031E _put_pixel boot_rom
00000351 _cls boot_rom
00000397 _draw_line boot_rom
0000054E _main boot_rom
000005D0 _abs
000005DC __mulint
000005E2 __mul16
000005F6 _memset _memset
00000621 _puts puts
ASxxxx Linker V03.00 + NoICE + sdld, page 3.
Hexadecimal [32-Bits]
@@ -162,7 +165,7 @@ Hexadecimal [32-Bits]
Area Addr Size Decimal Bytes (Attributes)
-------------------------------- ---- ---- ------- ----- ------------
_INITIALIZER 00000623 00000305 = 773. bytes (REL,CON)
_INITIALIZER 00000647 00000304 = 772. bytes (REL,CON)
Value Global Global Defined In Module
----- -------------------------------- ------------------------
@@ -171,18 +174,18 @@ Hexadecimal [32-Bits]
Area Addr Size Decimal Bytes (Attributes)
-------------------------------- ---- ---- ------- ----- ------------
_GSINIT 00000928 0000000F = 15. bytes (REL,CON)
_GSINIT 0000094B 0000000F = 15. bytes (REL,CON)
Value Global Global Defined In Module
----- -------------------------------- ------------------------
00000928 gsinit crt0
0000094B gsinit crt0
ASxxxx Linker V03.00 + NoICE + sdld, page 14.
Hexadecimal [32-Bits]
Area Addr Size Decimal Bytes (Attributes)
-------------------------------- ---- ---- ------- ----- ------------
_GSFINAL 00000937 00000001 = 1. bytes (REL,CON)
_GSFINAL 0000095A 00000001 = 1. bytes (REL,CON)
Value Global Global Defined In Module
----- -------------------------------- ------------------------
@@ -191,7 +194,7 @@ Hexadecimal [32-Bits]
Area Addr Size Decimal Bytes (Attributes)
-------------------------------- ---- ---- ------- ----- ------------
_DATA 00008000 00000007 = 7. bytes (REL,CON)
_DATA 00008000 00000006 = 6. bytes (REL,CON)
Value Global Global Defined In Module
----- -------------------------------- ------------------------
@@ -201,21 +204,20 @@ _DATA 00008000 00000007 = 7. bytes (R
00008003 _vsync_last boot_rom
00008004 _input0_cache boot_rom
00008005 _input1_cache boot_rom
00008006 _color boot_rom
ASxxxx Linker V03.00 + NoICE + sdld, page 16.
Hexadecimal [32-Bits]
Area Addr Size Decimal Bytes (Attributes)
-------------------------------- ---- ---- ------- ----- ------------
_INITIALIZED 00008007 00000305 = 773. bytes (REL,CON)
_INITIALIZED 00008006 00000304 = 772. bytes (REL,CON)
Value Global Global Defined In Module
----- -------------------------------- ------------------------
00008007 _y boot_rom
00008008 _cur_x boot_rom
0000800A _cur_y boot_rom
0000800C _font font
00008006 _y boot_rom
00008007 _cur_x boot_rom
00008008 _cur_y boot_rom
00008009 _color boot_rom
0000800A _font font
ASxxxx Linker V03.00 + NoICE + sdld, page 17.
@@ -230,6 +232,8 @@ Libraries Linked [ object file ]
/usr/bin/../share/sdcc/lib/z80/z80.lib [ abs.rel ]
/usr/bin/../share/sdcc/lib/z80/z80.lib [ mul.rel ]
/usr/bin/../share/sdcc/lib/z80/z80.lib [ _memset.rel ]
/usr/bin/../share/sdcc/lib/z80/z80.lib [ puts.rel ]
ASxxxx Linker V03.00 + NoICE + sdld, page 18.

View File

@@ -27,46 +27,48 @@ DEF l__HEADER5 0x3
DEF l__HEADER6 0x3
DEF l__HEADER7 0x3
DEF l__HEADER1 0x4
DEF l__DATA 0x7
DEF l__DATA 0x6
DEF l__HEADER8 0xC
DEF l__GSINIT 0xF
DEF s__CODE 0x200
DEF l__INITIALIZED 0x305
DEF l__INITIALIZER 0x305
DEF l__CODE 0x423
DEF s__HOME 0x623
DEF s__INITIALIZER 0x623
DEF s__GSINIT 0x928
DEF s__GSFINAL 0x937
DEF _input0 0x4000
DEF _input1 0x4001
DEF l__INITIALIZED 0x304
DEF l__INITIALIZER 0x304
DEF l__CODE 0x447
DEF s__HOME 0x647
DEF s__INITIALIZER 0x647
DEF s__GSINIT 0x94B
DEF s__GSFINAL 0x95A
DEF _input0 0x6000
DEF _input1 0x6001
DEF s__DATA 0x8000
DEF s__INITIALIZED 0x8007
DEF s__BSEG 0x830C
DEF s__BSS 0x830C
DEF s__HEAP 0x830C
DEF s__INITIALIZED 0x8006
DEF s__BSEG 0x830A
DEF s__BSS 0x830A
DEF s__HEAP 0x830A
DEF __clock 0x200
DEF _exit 0x204
DEF _putchar 0x20A
DEF _VGA_WIDTH 0x36B
DEF _VGA_HEIGHT 0x36D
DEF _put_pixel 0x36F
DEF _cls 0x3A2
DEF _draw_line 0x3F8
DEF _main 0x5AF
DEF _abs 0x5FD
DEF __mulint 0x609
DEF __mul16 0x60F
DEF gsinit 0x928
DEF _VGA_WIDTH 0x31A
DEF _VGA_HEIGHT 0x31C
DEF _put_pixel 0x31E
DEF _cls 0x351
DEF _draw_line 0x397
DEF _main 0x54E
DEF _abs 0x5D0
DEF __mulint 0x5DC
DEF __mul16 0x5E2
DEF _memset 0x5F6
DEF _puts 0x621
DEF gsinit 0x94B
DEF _hsync 0x8000
DEF _hsync_last 0x8001
DEF _vsync 0x8002
DEF _vsync_last 0x8003
DEF _input0_cache 0x8004
DEF _input1_cache 0x8005
DEF _color 0x8006
DEF _y 0x8007
DEF _cur_x 0x8008
DEF _cur_y 0x800A
DEF _font 0x800C
DEF _y 0x8006
DEF _cur_x 0x8007
DEF _cur_y 0x8008
DEF _color 0x8009
DEF _font 0x800A
LOAD boot_rom.ihx

View File

@@ -7,45 +7,48 @@ Symbol Table
.__.ABS. = 0000 G
.__.CPU. = 0000 L
.__.H$L. = 0000 L
0 _VGA_HEIGHT 0163 GR
0 _VGA_WIDTH 0161 GR
0 _VGA_HEIGHT 0112 GR
0 _VGA_WIDTH 0110 GR
0 ___str_0 03B6 R
__mulint **** GX
7 __xinit__color 0003 R
7 __xinit__cur_x 0001 R
7 __xinit__cur_y 0003 R
7 __xinit__cur_y 0002 R
7 __xinit__y 0000 R
_abs **** GX
0 _cls 0198 GR
1 _color 0006 GR
0 _cls 0147 GR
2 _color 0003 GR
2 _cur_x 0001 GR
2 _cur_y 0003 GR
0 _draw_line 01EE GR
2 _cur_y 0002 GR
0 _draw_line 018D GR
_font **** GX
1 _hsync 0000 GR
1 _hsync_last 0001 GR
_input0 = 4000 G
_input0 = 6000 G
1 _input0_cache 0004 GR
_input1 = 4001 G
_input1 = 6001 G
1 _input1_cache 0005 GR
0 _main 03A5 GR
0 _put_pixel 0165 GR
0 _main 0344 GR
_memset **** GX
0 _put_pixel 0114 GR
0 _putchar 0000 GR
_puts **** GX
1 _vsync 0002 GR
1 _vsync_last 0003 GR
2 _y 0000 GR
ASxxxx Assembler V02.00 + NoICE + SDCC mods (Zilog Z80 / Hitachi HD64180 / ZX-Next), page 2.
Hexadecimal [16-Bits]
Area Table
0 _CODE size 3F3 flags 0
1 _DATA size 7 flags 0
2 _INITIALIZED size 5 flags 0
0 _CODE size 3C6 flags 0
1 _DATA size 6 flags 0
2 _INITIALIZED size 4 flags 0
3 _DABS size 0 flags 8
4 _HOME size 0 flags 0
5 _GSINIT size 0 flags 0
6 _GSFINAL size 0 flags 0
7 _INITIALIZER size 5 flags 0
7 _INITIALIZER size 4 flags 0
8 _CABS size 0 flags 8

BIN
src/font.bin Normal file

Binary file not shown.

BIN
src/font.fnt Normal file

Binary file not shown.

View File

@@ -56,7 +56,8 @@ V_SRC = \
sim.v \
$(RTL)/soc.v \
$(RTL)/dpram.v \
$(RTL)/video.v \
$(RTL)/spram.v \
$(RTL)/JTFRAME/jtframe_vtimer.v
../rtl/tv80/tv80_core.v \
../rtl/tv80/tv80_alu.v \
../rtl/tv80/tv80_mcode.v \

View File

@@ -9,7 +9,7 @@ Size=520,600
Collapsed=0
[Window][Virtual Dev Board v1.0]
Pos=150,89
Pos=580,10
Size=1000,1000
Collapsed=0
@@ -33,3 +33,13 @@ Pos=738,825
Size=269,180
Collapsed=0
[Window][PGROM Editor]
Pos=12,617
Size=554,229
Collapsed=0
[Window][CHROM Editor]
Pos=19,866
Size=553,169
Collapsed=0

View File

@@ -40,10 +40,10 @@ module top(VGA_R,VGA_B,VGA_G,VGA_HS,VGA_VS,VGA_HB,VGA_VB,reset,clk_sys,clk_vid,i
wire m_down = inputs[2];
wire m_up = inputs[3];
wire VGA_DE;
soc soc(
.clk_sys(clk_sys),
.clk_pix(clk_sys),
.reset(reset | ioctl_download),
.VGA_HS(VGA_HS),
.VGA_VS(VGA_VS),
.VGA_R(VGA_R),
@@ -51,10 +51,10 @@ soc soc(
.VGA_B(VGA_B),
.VGA_HB(VGA_HB),
.VGA_VB(VGA_VB),
.VGA_DE(VGA_DE),
.dn_addr(ioctl_addr[13:0]),
.dn_data(ioctl_dout),
.dn_wr(ioctl_wr),
.dn_index(ioctl_index),
.inputs({btn_coin, btn_start, m_bomb, m_fire, m_right, m_left, m_down, m_up})
);

View File

@@ -46,6 +46,8 @@ int count_line;
int count_frame;
bool last_hblank;
bool last_vblank;
bool last_hsync;
bool last_vsync;
// Statistics
#ifdef WIN32
@@ -395,14 +397,15 @@ void SimVideo::StartFrame() {
#endif
}
void SimVideo::Clock(bool hblank, bool vblank, uint32_t colour) {
int ox = count_pixel + 1;
int oy = count_line;
void SimVideo::Clock(bool hblank, bool vblank, bool hsync, bool vsync, uint32_t colour) {
// Only draw outside of blanks
if (!(hblank || vblank)) {
//int ox = count_pixel + 1;
int ox = count_pixel;
int oy = count_line;
int x = ox, xs = output_width, y = oy;
if (output_rotate == -1) {
@@ -442,18 +445,20 @@ void SimVideo::Clock(bool hblank, bool vblank, uint32_t colour) {
}
// Increment pixel counter
count_pixel++;
// Increment pixel counter when not blanked
if (!(hblank || vblank)) {
count_pixel++;
}
// Falling edge of hblank
if (last_hblank && !hblank) {
// Next line on rising hsync
if (last_hsync && !hsync) {
// Increment line and reset pixel count
count_line++;
count_pixel = 0;
}
// Falling edge of vblank
if (last_vblank && !vblank) {
// Reset on rising vsync
if (last_vsync && !vsync) {
count_frame++;
count_line = 0;
@@ -470,6 +475,10 @@ void SimVideo::Clock(bool hblank, bool vblank, uint32_t colour) {
stats_fps = (float)(1000.0 / stats_frameTime);
}
last_hblank = hblank;
last_vblank = vblank;
last_hsync = hsync;
last_vsync = vsync;
}

View File

@@ -38,6 +38,6 @@ public:
void UpdateTexture();
void CleanUp();
void StartFrame();
void Clock(bool hblank, bool vblank, uint32_t colour);
void Clock(bool hblank, bool vblank, bool hsync, bool vsync, uint32_t colour);
int Initialise(const char* windowTitle);
};

View File

@@ -74,8 +74,8 @@ double sc_time_stamp() { // Called by $time in Verilog.
}
int clockSpeed = 24; // This is not used, just a reminder for the dividers below
SimClock clk_sys(1); // 12mhz
SimClock clk_pix(1); // 6mhz
SimClock clk_sys(2); // 12mhz
SimClock clk_pix(2); // 6mhz
void resetSim() {
main_time = 0;
@@ -104,7 +104,7 @@ int verilate() {
// Output pixels on rising edge of pixel clock
if (clk_pix.clk && !clk_pix.old) {
uint32_t colour = 0xFF000000 | top->VGA_B << 16 | top->VGA_G << 8 | top->VGA_R;
video.Clock(top->VGA_HB, top->VGA_VB, colour);
video.Clock(top->VGA_HB, top->VGA_VB, top->VGA_HS, top->VGA_VS, colour);
}
// Simulate both edges of system clock
@@ -177,6 +177,7 @@ int main(int argc, char** argv, char** env) {
if (video.Initialise(windowTitle) == 1) { return 1; }
bus.QueueDownload("../src/boot_rom.bin", 0);
bus.QueueDownload("../src/font.bin", 1);
#ifdef WIN32
@@ -234,7 +235,7 @@ int main(int argc, char** argv, char** env) {
ImGui::SliderInt("Rotate", &video.output_rotate, -1, 1); ImGui::SameLine();
ImGui::Checkbox("Flip V", &video.output_vflip);
ImGui::Text("main_time: %d frame_count: %d sim FPS: %f", main_time, video.count_frame, video.stats_fps);
ImGui::Text("main_time: %d frame_count: %d sim FPS: %f", main_time, video.count_frame, video.stats_fps);
ImGui::Text("minx: %d maxx: %d miny: %d maxy: %d", video.stats_xMin, video.stats_xMax, video.stats_yMin, video.stats_yMax);
// Draw VGA output
@@ -242,39 +243,42 @@ int main(int argc, char** argv, char** env) {
ImGui::Image(video.texture_id, ImVec2(video.output_width * m, video.output_height * m));
ImGui::End();
ImGui::Begin("ROM Editor");
mem_edit_1.DrawContents(top->top__DOT__soc__DOT__rom__DOT__mem, 4096, 0);
ImGui::End();
ImGui::Begin("RAM Editor");
mem_edit_2.DrawContents(top->top__DOT__soc__DOT__ram__DOT__mem, 4096, 0);
ImGui::End();
ImGui::Begin("VRAM Editor");
mem_edit_3.DrawContents(top->top__DOT__soc__DOT__video__DOT__vmem, 320*200, 0);
ImGui::End();
ImGui::Begin("PGROM Editor");
mem_edit_1.DrawContents(top->top__DOT__soc__DOT__pgrom__DOT__mem, 4096, 0);
ImGui::End();
ImGui::Begin("CHROM Editor");
mem_edit_1.DrawContents(top->top__DOT__soc__DOT__chrom__DOT__mem, 1024, 0);
ImGui::End();
//ImGui::Begin("RAM Editor");
// mem_edit_2.DrawContents(top->top__DOT__soc__DOT__ram__DOT__mem, 4096, 0);
// ImGui::End();
//ImGui::Begin("VRAM Editor");
//mem_edit_3.DrawContents(top->top__DOT__soc__DOT__video__DOT__vmem, 320*200, 0);
//ImGui::End();
ImGui::Begin("CPU Registers");
ImGui::Spacing();
ImGui::Text("PC 0x%04X", top->top__DOT__soc__DOT__T80x__DOT__i_tv80_core__DOT__PC);
ImGui::Text("ACC 0x%04X", top->top__DOT__soc__DOT__T80x__DOT__i_tv80_core__DOT__ACC);
ImGui::Text("Main Registers");
ImGui::Begin("CPU Registers");
ImGui::Spacing();
ImGui::Text("PC 0x%04X", top->top__DOT__soc__DOT__T80x__DOT__i_tv80_core__DOT__PC);
ImGui::Text("ACC 0x%04X", top->top__DOT__soc__DOT__T80x__DOT__i_tv80_core__DOT__ACC);
ImGui::Text("Main Registers");
/*
ImGui::Text("B 0x%02X", top->top__DOT__soc__DOT__T80x__DOT__i_tv80_core__DOT__i_reg__DOT__B);
ImGui::Text("C 0x%02X", top->top__DOT__soc__DOT__T80x__DOT__i_tv80_core__DOT__i_reg__DOT__C);
ImGui::Text("D 0x%02X", top->top__DOT__soc__DOT__T80x__DOT__i_tv80_core__DOT__i_reg__DOT__D);
ImGui::Text("E 0x%02X", top->top__DOT__soc__DOT__T80x__DOT__i_tv80_core__DOT__i_reg__DOT__E);
ImGui::Text("H 0x%02X", top->top__DOT__soc__DOT__T80x__DOT__i_tv80_core__DOT__i_reg__DOT__H);
ImGui::Text("L 0x%02X", top->top__DOT__soc__DOT__T80x__DOT__i_tv80_core__DOT__i_reg__DOT__L);
*/
//ImGui::Spacing();
//ImGui::Separator();
//ImGui::Text("16 bit Registers");
/*
ImGui::Text("B 0x%02X", top->top__DOT__soc__DOT__T80x__DOT__i_tv80_core__DOT__i_reg__DOT__B);
ImGui::Text("C 0x%02X", top->top__DOT__soc__DOT__T80x__DOT__i_tv80_core__DOT__i_reg__DOT__C);
ImGui::Text("D 0x%02X", top->top__DOT__soc__DOT__T80x__DOT__i_tv80_core__DOT__i_reg__DOT__D);
ImGui::Text("E 0x%02X", top->top__DOT__soc__DOT__T80x__DOT__i_tv80_core__DOT__i_reg__DOT__E);
ImGui::Text("H 0x%02X", top->top__DOT__soc__DOT__T80x__DOT__i_tv80_core__DOT__i_reg__DOT__H);
ImGui::Text("L 0x%02X", top->top__DOT__soc__DOT__T80x__DOT__i_tv80_core__DOT__i_reg__DOT__L);
*/
//ImGui::Spacing();
//ImGui::Separator();
//ImGui::Text("16 bit Registers");
/*
ImGui::Text("IX 0x%04X", top->top__DOT__soc__DOT__T80x__DOT__i_tv80_core__DOT__i_reg__DOT__IX);
ImGui::Text("IY 0x%04X", top->top__DOT__soc__DOT__T80x__DOT__i_tv80_core__DOT__i_reg__DOT__IY);
ImGui::Text("SP 0x%04X", top->top__DOT__soc__DOT__T80x__DOT__i_tv80_core__DOT__SP);
ImGui::Text("IX 0x%04X", top->top__DOT__soc__DOT__T80x__DOT__i_tv80_core__DOT__i_reg__DOT__IX);
ImGui::Text("IY 0x%04X", top->top__DOT__soc__DOT__T80x__DOT__i_tv80_core__DOT__i_reg__DOT__IY);
ImGui::Text("SP 0x%04X", top->top__DOT__soc__DOT__T80x__DOT__i_tv80_core__DOT__SP);
*/
ImGui::End();
ImGui::End();
video.UpdateTexture();
@@ -284,7 +288,7 @@ int main(int argc, char** argv, char** env) {
{
if (input.inputs[i]) { top->inputs |= (1 << i); }
}
// Run simulation
if (run_enable) {
for (int step = 0; step < batchSize; step++) { verilate(); }

View File

@@ -1,6 +1,9 @@
#verilator -cc -exe --public --compiler msvc --converge-limit 2000 -Wno-WIDTH -Wno-IMPLICIT -Wno-MODDUP -Wno-UNSIGNED -Wno-CASEINCOMPLETE -Wno-CASEX -Wno-SYMRSVDWORD -Wno-COMBDLY -Wno-INITIALDLY -Wno-BLKANDNBLK -Wno-UNOPTFLAT -Wno-SELRANGE -Wno-CMPCONST -Wno-CASEOVERLAP -Wno-PINMISSING --top-module top sim.v \
verilator -cc -exe --public --compiler msvc +define+SIMULATION=1 --converge-limit 2000 --top-module top sim.v \
../rtl/video.v ../rtl/dpram.v ../rtl/soc.v \
verilator -cc -exe --public --compiler msvc +define+SIMULATION=1 --converge-limit 2000 --top-module top sim.v \
../rtl/dpram.v \
../rtl/spram.v \
../rtl/JTFRAME/jtframe_vtimer.v \
../rtl/soc.v \
../rtl/tv80/tv80_core.v \
../rtl/tv80/tv80_alu.v \
../rtl/tv80/tv80_mcode.v \