Project

General

Profile

// ============================================================================
// __
// \\__/ o\ (C) 2015 Robert Finch, Stratford
// \ __ / All rights reserved.
// \/_// robfinch<remove>@opencores.org
// ||
//
// This source file is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This source file 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 this program. If not, see <http://www.gnu.org/licenses/>.
//
// ============================================================================
//
function [31:0] fn_get_sp;
input [31:0] sp;
begin
if (m832)
fn_get_sp = {4'd0,sp};
else if (m816)
fn_get_sp = {stack_bank,sp[15:0]};
else
fn_get_sp = {stack_page,sp[7:0]};
end
endfunction

function [31:0] fn_add_to_sp;
input [31:0] amt;
begin
if (m832)
fn_add_to_sp = sp + amt;
else if (m816)
fn_add_to_sp = {stack_bank,sp[15:0] + amt[15:0]};
else
fn_add_to_sp = {stack_page,sp[7:0] + amt[7:0]};
end
endfunction

function [31:0] fn_limit;
input [3:0] size;
begin
case(size)
4'd0: fn_limit = 32'd0;
4'd1: fn_limit = 32'd255;
4'd2: fn_limit = 32'd1023;
4'd3: fn_limit = 32'd4095;
4'd4: fn_limit = 32'd16383;
4'd5: fn_limit = 32'd65535;
4'd6: fn_limit = 32'd262143;
4'd7: fn_limit = 32'd1048575;
4'd8: fn_limit = 32'd4194303;
4'd9: fn_limit = 32'd16777215;
4'd10: fn_limit = 32'd67108863;
4'd11: fn_limit = 32'd268435454;
4'd12: fn_limit = 32'd1073741823;
4'd13: fn_limit = 32'd4294967295; // one less
default: fn_limit = 32'd4095;
endcase
end
endfunction

task set_sp;
begin
radr <= fn_get_sp(sp);
wadr <= fn_get_sp(sp);
sp <= fn_add_to_sp(32'hFFFFFFFF);
if (m816)
bank_wrap <= TRUE;
else if (!m832)
page_wrap <= TRUE;
end
endtask

task inc_sp;
begin
radr <= fn_add_to_sp(32'd1);
sp <= fn_add_to_sp(32'd1);
if (m816)
bank_wrap <= TRUE;
else if (!m832)
page_wrap <= TRUE;
end
endtask

function [31:0] fn_sp_inc;
input [31:0] sp_inc;
begin
fn_sp_inc = fn_add_to_sp(32'd1);
end
endfunction

task tsk_push;
input [5:0] SW8;
input szFlg;
input szFlg2;
begin
if (m832) begin
if (szFlg2) begin
radr <= fn_add_to_sp(32'hFFFFFFFD);
wadr <= fn_add_to_sp(32'hFFFFFFFD);
sp <= fn_add_to_sp(32'hFFFFFFFC);
store_what <= SW8;
s32 <= TRUE;
end
else if (szFlg) begin
radr <= fn_add_to_sp(32'hFFFFFFFF);
wadr <= fn_add_to_sp(32'hFFFFFFFF);
sp <= fn_add_to_sp(32'hFFFFFFFE);
s16 <= TRUE;
store_what <= SW8;
end
else begin
radr <= sp;
wadr <= sp;
store_what <= SW8;
sp <= fn_add_to_sp(32'hFFFFFFFF);
end
end
else if (m816) begin
if (szFlg2) begin
radr <= fn_add_to_sp(32'hFFFFFFFD);
wadr <= fn_add_to_sp(32'hFFFFFFFD);
sp <= fn_add_to_sp(32'hFFFFFFFC);
store_what <= SW8;
s32 <= TRUE;
end
else if (szFlg) begin
radr <= fn_add_to_sp(32'hFFFFFFFF);
wadr <= fn_add_to_sp(32'hFFFFFFFF);
sp <= fn_add_to_sp(32'hFFFFFFFE);
s16 <= TRUE;
store_what <= SW8;
end
else begin
radr <= {stack_bank,sp[15:0]};
wadr <= {stack_bank,sp[15:0]};
store_what <= SW8;
sp <= fn_add_to_sp(32'hFFFFFFFF);;
end
bank_wrap <= TRUE;
end
else begin
// We could be pushing the CS or DS from
// emulation mode.
if (szFlg2) begin
radr <= fn_add_to_sp(32'hFFFFFFFD);
wadr <= fn_add_to_sp(32'hFFFFFFFD);
sp <= fn_add_to_sp(32'hFFFFFFFC);
store_what <= SW8;
s32 <= TRUE;
end
else if (szFlg) begin
radr <= fn_add_to_sp(32'hFFFFFFFF);
wadr <= fn_add_to_sp(32'hFFFFFFFF);
sp <= fn_add_to_sp(32'hFFFFFFFE);
s16 <= TRUE;
store_what <= SW8;
end
else begin
radr <= {stack_page,sp[7:0]};
wadr <= {stack_page,sp[7:0]};
store_what <= SW8;
sp <= fn_add_to_sp(32'hFFFFFFFF);
end
page_wrap <= TRUE;
end
data_nack();
seg <= ss_base;
lmt <= ss_limit;
state <= STORE1;
end
endtask

task moveto_ifetch;
begin
next_state(ssm ? SSM1 : IFETCH);
end
endtask

(11-11/39)