
suprised that the link stayed up for as long as it did, i haven't had access to that site for 2 years mwhahaha
Andy
Code: Select all
/*
Sinclair ZX81 ULA implementation in Verilog.
Destination device ALTERA EPM7128sqc100-15
Andy Rea, 2011
This is turbo module.
in ZX81 you can double the CPU speed while it is not activly generating the display.
mostly while NMI is active.
So by watching various events on the Z80 bus we can toggle between 3.25Mhz and 6.5Mhz.
the switching is always done at a posedge of the slower clock, this ensures that the faster clock
has already switched to a high level.
the output 'clock_select' is used by the clocks module to select which clock to send to the cpu.
ZX80 turbo mode is supported also, but in a different way to ZX81, it is activated when the display loop in rom
is ended, but is disabled in all the same ways as ZX81 (so flicker free games still run if you forgot to turn off
Turbo) and additionally disbaled on entry to the display loop.
*/
module turbo (
//inputs
Global_reset,
slow_clock,
address,
m1,
iorq,
mreq,
wr,
halt,
turbo_enable, // controlled from poke
zx_mode,
turbo_overide,
turbo_in_fast, // controlled from poke
//outputs
//cpu_clock
clock_select
);
input Global_reset, slow_clock ;
input [15:0]address ; //lower 8 bits of address bus only
input m1 ;
input iorq, mreq, wr, halt ;
input turbo_enable ; // controlled from poke.
input zx_mode ;
// OVERRIDE DOES NOTHING ALWAYS LOGIC 1
input turbo_overide ; // external pin, user override of turbo mode
// so for example user powers on machine
// selects turbo active, but overides it
// loads program, then once program is running
// removes the overide and turbo kicks in ;-)
//
// '0' = overide
// '1' = normal
input turbo_in_fast ;
//output cpu_clock ; // output to cpu, switched on the rising edge of slow clock
// since as slow clock is clocked on the rising edge of fast clock
// fast clock will have already gone high, the same applies when
// switching from fast to slow
output clock_select;
wire turbo_on ;
wire turbo_off ;
wire cpu_clock ;
reg turbo_active ;
reg clock_select ;
wire poke_trigger ;
// in fast mode allows the user to trigger turbo by poking location 1001
assign poke_trigger = turbo_in_fast & !wr & !mreq & (address == 16'd1001) ;
assign turbo_on =(zx_mode & turbo_enable & (poke_trigger | (!iorq & !wr & address[7:0] == 8'b11111110 ))) | (!zx_mode & turbo_enable & !m1 & (address == 16'd803)) ;
// ^^^ ^^^^ ^^^^ ^^^^^ OR----> ^^^^ execute $0323
// zx81 external Vcc, poke_trig OUT ($fe), ZX80
assign turbo_off = (((!turbo_enable | (!iorq & !wr & (address[7:0] == 8'b11111101 | address[7:0] == 8'b11111111 | address[7:0] == 8'b00000111)) | !halt | !Global_reset ))) | (!zx_mode & (!turbo_enable | (!m1 & (address == 16'd319)))) ;
//the old version of the line above
//assign turbo_off = ((zx_mode & (!turbo_enable | (!iorq & !wr & (address[7:0] == 8'b11111101 | address[7:0] == 8'b11111111 | address[7:0] == 8'b00000111)) | !halt | !Global_reset ))) | (!zx_mode & (!turbo_enable | (!m1 & (address == 16'd319)))) ;
// zx81 external Gnd out ($fd), or out ($ff), halt (low) reset (low)
always @ (posedge slow_clock or negedge Global_reset) begin
if (!Global_reset) begin
turbo_active <= 1'b0 ;
end else if (turbo_off) begin
turbo_active <= 1'b0 ;
end else if (turbo_on) begin
turbo_active <= 1'b1 ;
end
end
always @ (posedge slow_clock or negedge Global_reset) begin
if (!Global_reset) begin
clock_select <= 1'b0 ;
end else if (turbo_active & turbo_overide) begin
clock_select <= 1'b1 ;
end else begin
clock_select <= 1'b0 ;
end
end
endmodule