ULA revistited.
Re: ULA revistited.
If you get it running and there would be space left you might be able to add the functionality of the clockdoubler that is quite popular.
I hope so much that you succeed .
I hope so much that you succeed .
In theory, there is no difference between theory and practice. But, in practice, there is.
Re: ULA revistited.
Hi Prime,
the oscilator circuit is took directly from the great Bodo Wenzels design.
oops....
missed a connection between base of the npn (bc548) and the junction of the 2 capacitors...
that should get it working.
ah the 6.5Mhz crystal
when i built a zx80 clone i used a 6.5536Mhz crystal which are more widely available, divides nicely to seconds...
i too am working on a cpld design, hoping to squeeze it onto a board measuring just 1" x 2.5" that will plug directly into the ula socket, i'm having a wonderful time just now learning verilog HDL.
@ Paul
um clock doubling that would be good, will have to look into it for then next incarceration if there is one, for now i want to duplicate my logic (which i have proved works) as close as possible, and then move on from there.
regards Andy
the oscilator circuit is took directly from the great Bodo Wenzels design.
oops....

missed a connection between base of the npn (bc548) and the junction of the 2 capacitors...
that should get it working.
ah the 6.5Mhz crystal

i too am working on a cpld design, hoping to squeeze it onto a board measuring just 1" x 2.5" that will plug directly into the ula socket, i'm having a wonderful time just now learning verilog HDL.
@ Paul
um clock doubling that would be good, will have to look into it for then next incarceration if there is one, for now i want to duplicate my logic (which i have proved works) as close as possible, and then move on from there.
regards Andy
what's that Smell.... smells like fresh flux and solder fumes...
Re: ULA revistited.
updated schematic, to correct a couple of errors.
https://picasaweb.google.com/lh/photo/K ... directlink
the 47K resitor connected between GND and Tape-in may need to be altered to suit your device, the Gal i used has a reasonable internal pullup this resistor makes the input sit just at the switching threshold.
regards Andy.
https://picasaweb.google.com/lh/photo/K ... directlink
the 47K resitor connected between GND and Tape-in may need to be altered to suit your device, the Gal i used has a reasonable internal pullup this resistor makes the input sit just at the switching threshold.
regards Andy.
what's that Smell.... smells like fresh flux and solder fumes...
Re: ULA revistited.
OK here's my Verilog code so far....This is based on the previous version using gates so doesn't have the back portch etc *yet*
I'm currently getting a stable picture on poweron however typing some characters causes the display to corrupt, 2 for example seems to fetch successive pixel rows one character space further to the right for each new line.
However the Inverse K is fine, as are 1 and 0 I'm not too sure what's causing this.
The design fits into a Xilinx XC95108, however I believe that it is using less than 72 macrocels, so should fit into an XC9572, tab size is 3, for some strange reason that's what webpack defaults to.....
Be aware that the comments in some places may not match the code........
Note also that PortA, PortB and PortC are just some of the unused pins wired to 2x5 0.1" headers so that I can use them for monitoring internal signals for debugging purposes.
Cheers.
Phill.
I'm currently getting a stable picture on poweron however typing some characters causes the display to corrupt, 2 for example seems to fetch successive pixel rows one character space further to the right for each new line.
However the Inverse K is fine, as are 1 and 0 I'm not too sure what's causing this.
The design fits into a Xilinx XC95108, however I believe that it is using less than 72 macrocels, so should fit into an XC9572, tab size is 3, for some strange reason that's what webpack defaults to.....
Be aware that the comments in some places may not match the code........
Code: Select all
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: Ramoth
// Engineer: Phill.Harvey-Smith, based on pervious work by Andy Rea
//
// Create Date: 17:52:53 03/24/2011
// Design Name: ZX81 ULA replacement
// Module Name: ULA
// Project Name:
// Target Devices: XC9572 / XC95108
// Tool versions:
// Description: To serve as a replacement for the ULA in the ZX81 computer.
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
// I have used the Acorn convention of prefixing active low outputs and inputs to
// che design with a lower case n so for example nRD would be an active loaw read
// strobe
//
//////////////////////////////////////////////////////////////////////////////////
module ULA(
inout [7:0] Data, // Databus from Z80
inout [15:14] AddrH, // Two parts of Address bus
inout [8:0] AddrL,
input nHALT, // Halt from Z80
input nRD, // Read and write strobes from Z80
input nWR,
input nIORQ, // IO request from Z80
input nMREQ, // Memory request from Z80
input nM1, // M1 from Z80
input USAUK, // USA or UK jumper
input CLKIN, // 6.5MHz clock input signal
input TapeIn, // Input from cassette when loading
input [4:0] Kbd, // Keyboard row inputs
output nNMI,
output CLKOUT, // 3.5Mhz clock output to Z80
output nROMCS, // ROP chip select signal
output nRAMCS, // RAM chip select signal
output VidOut, // Video output signal
output Blank, // Video blanking signal
output CSync, // Composite Sync
// Debugging ports
inout [7:0] PortA,
inout [7:0] PortB,
inout [7:0] PortC
);
// Local registers
reg [7:0] HCount; // HSync Counter
reg [3:0] Micro; // Micro counter
reg [7:0] ShiftReg; // Video shift register
reg CLK325;
reg VSync;
reg NMIon;
// Clock generator output clock to Z80 (3.25MHz), is generated by dividing input clock
// 6.5MHz by 2.
always @(posedge CLKIN)
begin
CLK325 <= !CLK325;
end
// Aliases just for convenience
assign CLK65 = CLKIN;
assign nCLK65 = !CLKIN;
assign CLKOUT = !CLK325;
// HSync generation
// Counter will be reset to 0 if the count reaches 207 or vsync is active.
assign HClear = (HCount==207) | VSync;
always @(negedge CLK325 or posedge HClear)
begin
if(HClear)
HCount <= 0;
else
HCount <= HCount+1;
end
// HSync generated at end of count
assign HSync = HCount[6] & HCount[7];
assign nHSync = !HSync;
// Chip selects
// ROMCS active when mREQ valid and A14 low, RAMCS valid when MREQ active and A14 high
// This effectivly devides the memory map up as follows :
// $0000 - $3FFF ROMCS
// $4000 - $7FFF RAMCS
// $8000 - $BFFF ROMCS
// $C000 - $FFFF RAMCS
assign nROMCS = nMREQ | AddrH[14];
assign nRAMCS = nMREQ | !AddrH[14];
// IO read and write strobes
assign nIORD = nRD | nIORQ;
assign nIOWR = nWR | nIORQ;
// VSync generation
// Read of location $FE
assign nFERD = nIORD | AddrL[0];
assign VSyncOn = (nFERD | NMIon);
assign VSyncOff = nIOWR;
// Togge VSync on and off as needded
always @(negedge VSyncOn or negedge VSyncOff)
begin
if (!VSyncOn)
VSync <= 1'b1;
else
VSync <= 1'b0;
end
// NMI control
assign NMIEnable = nIOWR | AddrL[0];
assign NMIDisable = nIOWR | AddrL[1];
// Toggle NMIon on and off as needed
always @(negedge NMIEnable or negedge NMIDisable)
begin
if (!NMIEnable)
NMIon <= 1'b1;
else
NMIon <= 1'b0;
end
assign nNMI = !NMIon | nHSync;
//assign nNMI = 1'b1;
// Micro counter
reg MicroEnabled;
assign nL_PRE = !(Micro[3:0]==8); //!Micro[3];
always @(negedge nL_PRE or negedge nM1)
begin
if(!nL_PRE)
MicroEnabled <= 1'b0;
else
MicroEnabled <= 1'b1;
end
// Only clock if enabled
always @(negedge nCLK65 or negedge MicroEnabled)
begin
if (!MicroEnabled)
Micro <= 4'b0;
else
Micro <= Micro+1;
end
// NOP Pulse
reg NOPTC;
assign NOPulse = !(Micro[0] & Micro[1]) | Micro[2]; // low when Micro == 3
assign nNOPulse = !NOPulse;
assign NOPEnable = !(!Data[6] & AddrH[15] & nHALT) | nM1;
always @(posedge nNOPulse or negedge nL_PRE)
begin
if(!nL_PRE)
NOPTC <= 1'b1;
else
NOPTC <= NOPEnable;
end
assign nDO_NOP = NOPulse | NOPTC;
reg [7:0] CharLatch;
//assign CharLatchEnable = (Micro[0] & Micro[1]) | Micro[2]; // Micro >= 3
assign CharLatchEnable = (Micro[2:0] == 2);
always @(posedge CharLatchEnable)
begin
CharLatch[7:0] <= {Data[7], 1'b0, Data[5:0]};
end
reg [2:0] RowCount;
always @(negedge HSync or posedge VSync)
begin
if(VSync)
RowCount[2:0] <= 3'b0;
else
RowCount <= RowCount+1;
end
assign CharLatchOE = ((Micro[0] | Micro[1]) & Micro[2]); // Micro > 4
assign AddrL[8:0] = CharLatchOE ? {CharLatch[5:0], RowCount[2:0]} : 9'bz;
// Read of keyboard / tape port
// Forced NOP
// Tri-state data lines unless reading location $FE
wire [7:0] DataOut;
assign DataEn = !nDO_NOP | !nFERD;
assign DataOut[7:0] = nFERD ? {8'b0} : {TapeIn, USAUK, 1'b0, Kbd[4:0]};
assign Data = DataEn ? DataOut : 8'bz;
// Video inverter
reg Invert2;
assign InvertCLK = (Micro[0] & Micro[1] & Micro[2]);
assign LD_SHIFT = !InvertCLK | NOPTC;
always @(posedge InvertCLK)
begin
Invert2 <= !CharLatch[7] | NOPTC;
end
always @(posedge CLK65 or negedge LD_SHIFT)
begin
if (!LD_SHIFT)
ShiftReg[7:0] <= Data[7:0];
else
ShiftReg[7:0] <= {ShiftReg[6:0], 1'b0};
end
assign VidOut = ShiftReg[7] ^ Invert2;
assign CSync = !HSync ^ VSync;
assign PortA[7:0] = HCount[7:0];
assign PortB[7:0] = {HSync,VSync,DataEn,CharLatchOE, Micro[3:0]};
assign PortC[7:0] = {NMIEnable,NMIDisable,nDO_NOP , NOPTC,NOPEnable,NOPulse , NMIon, nNMI};
endmodule
Cheers.
Phill.
Re: ULA revistited.
Thats pretty cool, i've managed to learn enough Verilog in the last week or so that i can understand what's going on
2 weeks ago i would have been guessing at best.
first thing, so away with the logic that inverts the video comming out of the shift register, it was well rubbish on the original board i built. and invert the data bus on the load of the shift register instead, you should already of captured bit 7 when you grabbed the databus for the alternate rom addressing.
adding blanking is also quite easy. imediatly after the Hsync, the hysnc counter resets to 0, bit 4 will then stay low for another 16 clock cycles (3.25Mhz)
so add a latch to start blanking at the begging of the hsync pulse, and clear it when bit 4 of the count goes high,
then alter the shift register so that the output bit remains low whilst the blanking is active.
leave the rest of the shift register to do it's stuff, i know of at least one program that outputs active video during the blanking time.
Regards Andy

first thing, so away with the logic that inverts the video comming out of the shift register, it was well rubbish on the original board i built. and invert the data bus on the load of the shift register instead, you should already of captured bit 7 when you grabbed the databus for the alternate rom addressing.
adding blanking is also quite easy. imediatly after the Hsync, the hysnc counter resets to 0, bit 4 will then stay low for another 16 clock cycles (3.25Mhz)
so add a latch to start blanking at the begging of the hsync pulse, and clear it when bit 4 of the count goes high,
then alter the shift register so that the output bit remains low whilst the blanking is active.
leave the rest of the shift register to do it's stuff, i know of at least one program that outputs active video during the blanking time.
Regards Andy
what's that Smell.... smells like fresh flux and solder fumes...
Re: ULA revistited.
Success !
It's now working well enough to enter programs without getting any corrupt characters.
I've posted a couple of images here : http://protein.bio.warwick.ac.uk/~bshu/ZX81-ULA/ as they are too big to upload.
Just uploaded Eagle schematic and board files of the hardware I'm using to the above location.
Lateset version of verilog is here :
Now to source some flatpack xc9572s......
Cheers.
Phill.
It's now working well enough to enter programs without getting any corrupt characters.
I've posted a couple of images here : http://protein.bio.warwick.ac.uk/~bshu/ZX81-ULA/ as they are too big to upload.
Just uploaded Eagle schematic and board files of the hardware I'm using to the above location.
Lateset version of verilog is here :
Code: Select all
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: Ramoth
// Engineer: Phill.Harvey-Smith, based on pervious work by Andy Rea
//
// Create Date: 17:52:53 03/24/2011
// Design Name: ZX81 ULA replacement
// Module Name: ULA
// Project Name:
// Target Devices: XC9572 / XC95108
// Tool versions:
// Description: To serve as a replacement for the ULA in the ZX81 computer.
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
// I have used the Acorn convention of prefixing active low outputs and inputs to
// che design with a lower case n so for example nRD would be an active loaw read
// strobe
//
// 2011-03-30 WooHoo it's working !
//
//////////////////////////////////////////////////////////////////////////////////
module ULA(
inout [7:0] Data, // Databus from Z80
inout [15:14] AddrH, // Two parts of Address bus
inout [8:0] AddrL,
input nHALT, // Halt from Z80
input nRD, // Read and write strobes from Z80
input nWR,
input nIORQ, // IO request from Z80
input nMREQ, // Memory request from Z80
input nM1, // M1 from Z80
input USAUK, // USA or UK jumper
input CLKIN, // 6.5MHz clock input signal
input TapeIn, // Input from cassette when loading
input [4:0] Kbd, // Keyboard row inputs
output nNMI,
output CLKOUT, // 3.5Mhz clock output to Z80
output nROMCS, // ROP chip select signal
output nRAMCS, // RAM chip select signal
output VidOut, // Video output signal
output Blank, // Video blanking signal
output CSync, // Composite Sync
// Debugging ports
inout [7:0] PortA,
inout [7:0] PortB,
inout [7:0] PortC
);
// Local registers
reg [7:0] HCount; // HSync Counter
reg [3:0] Micro; // Micro counter
reg [7:0] ShiftReg; // Video shift register
reg CLK325;
reg VSync;
reg NMIon;
// Clock generator output clock to Z80 (3.25MHz), is generated by dividing input clock
// 6.5MHz by 2.
always @(posedge CLKIN)
begin
CLK325 <= !CLK325;
end
// Aliases just for convenience
assign CLK65 = CLKIN;
assign nCLK65 = !CLKIN;
assign CLKOUT = CLK325;
// HSync generation
// Counter will be reset to 0 if the count reaches 207 or vsync is active.
assign HClear = ((HCount==207) & CLK325) | VSync;
assign Blank = (HCount < 16);
always @(negedge CLK325 or posedge HClear)
begin
if(HClear)
HCount <= 0;
else
HCount <= HCount+1;
end
// HSync generated at end of count
assign HSync = HCount[6] & HCount[7];
assign nHSync = !HSync;
// Chip selects
// ROMCS active when mREQ valid and A14 low, RAMCS valid when MREQ active and A14 high
// This effectivly devides the memory map up as follows :
// $0000 - $3FFF ROMCS
// $4000 - $7FFF RAMCS
// $8000 - $BFFF ROMCS
// $C000 - $FFFF RAMCS
assign nROMCS = nMREQ | AddrH[14];
assign nRAMCS = nMREQ | !AddrH[14];
// IO read and write strobes
assign nIORD = nRD | nIORQ;
assign nIOWR = nWR | nIORQ;
// VSync generation
// Read of location $FE
assign nFERD = nIORD | AddrL[0];
assign VSyncOn = (nFERD | NMIon);
assign VSyncOff = nIOWR;
// Togge VSync on and off as needded
always @(negedge VSyncOn or negedge VSyncOff)
begin
if (!VSyncOn)
VSync <= 1'b1;
else
VSync <= 1'b0;
end
// NMI control
assign NMIEnable = nIOWR | AddrL[0];
assign NMIDisable = nIOWR | AddrL[1];
// Toggle NMIon on and off as needed
always @(negedge NMIEnable or negedge NMIDisable)
begin
if (!NMIEnable)
NMIon <= 1'b1;
else
NMIon <= 1'b0;
end
assign nNMI = !NMIon | nHSync;
//assign nNMI = 1'b1;
// Micro counter
reg MicroEnabled;
assign L_PRE = (Micro[3:0]==8); //!Micro[3];
always @(posedge L_PRE or negedge nM1)
begin
if(L_PRE)
MicroEnabled <= 1'b0;
else
MicroEnabled <= 1'b1;
end
// Only clock if enabled
always @(negedge CLK65 or negedge MicroEnabled)
begin
if (!MicroEnabled)
Micro <= 4'b0;
else
Micro <= Micro+1;
end
// NOP Pulse
reg NOPTC;
// On the CPLD the NOP pulse had to stretch over half cycles 3 and 4
// or the Z80 will sometimes latch the character data instead of the NOP !
assign NOPulse = ((Micro[2:0]>=3) & (Micro[2:0]<=4));
assign NOPEnable = !(!Data[6] & AddrH[15] & nHALT) | nM1;
always @(posedge NOPulse or posedge L_PRE)
begin
if(L_PRE)
NOPTC <= 1'b1;
else
NOPTC <= NOPEnable;
end
assign nDO_NOP = !NOPulse | NOPTC;
// Character latch, latch the character in during half cycle 2, befor the NOP
// is forced. The bottom 6 bits are the character data, bit 6 is always 0 so is
// not latched, bit 7 is the Inverse bit
reg [5:0] CharLatch;
reg Invert;
assign CharLatchEnable = (Micro[2:0] == 2);
always @(posedge CharLatchEnable)
begin
CharLatch[5:0] <= Data[5:0];
Invert <= !Data[7];
end
reg [2:0] RowCount;
always @(negedge HSync or posedge VSync)
begin
if(VSync)
RowCount[2:0] <= 3'b0;
else
RowCount <= RowCount+1;
end
// Output the address of the required bit pattern for half cycles 5 till 7
assign CharLatchOE = ((Micro[0] | Micro[1]) & Micro[2]); // Micro > 4
assign AddrL[8:0] = CharLatchOE ? {CharLatch[5:0], RowCount[2:0]} : 9'bz;
// Data transfer from ULA to Z80 will happen when :
// The Z80 reads port $FE : keyboard / usa-uk / tape port
// The ULA forces a NOP as part of the video cycle.
// Otherwise the output data lines are tri-stated.
wire [7:0] DataOut;
assign DataEn = !nDO_NOP | !nFERD;
assign DataOut[7:0] = nFERD ? {8'b0} : {TapeIn, USAUK, 1'b0, Kbd[4:0]};
assign Data = DataEn ? DataOut : 8'bz;
// Load or shift, selects when the video shift register should load data from the
// bus or should shift it out as video.
assign LD_SHIFT = !(Micro[2:0]==7) | NOPTC;
// Video shifter, latches bit pattern data from the bus and shifts out the video.
// If the invert bit is set then the data is inverted as it is latched.
always @(posedge CLK65 /*or negedge LD_SHIFT*/)
begin
if (!LD_SHIFT)
ShiftReg[7:0] <= Invert ? ~Data[7:0] : Data[7:0];
else
ShiftReg[7:0] <= {ShiftReg[6:0], 1'b1};
end
// Generate video from blanking and syncs
assign VidOut = Blank ? 1'b0 : ShiftReg[7];
assign CSync = !HSync ^ VSync;
// For debug.
assign PortA[7:0] = HCount[7:0];
assign PortB[7:0] = {HSync,VSync,DataEn,CharLatchOE, Micro[3:0]};
assign PortC[7:0] = {NMIEnable,NMIDisable,nDO_NOP , NOPTC,NOPEnable,NOPulse , NMIon, nNMI};
endmodule
Cheers.
Phill.
Re: ULA revistited.
Blimey thats fast work... do you make the PCB's yourself ?
regards the force nop timing, in my gal design it extends from the begining of the last 1/4 of T2 to the end of the first 1/4 of T3 (just one 6.5Mhz cycle) as the Z80 samples the data bus on the rising edge of T3 as you have discovered
i test the conditiond for a video cycle 1/2 (6.5Mhz clock) cycle before this as it's good to leave it as late as possible to allow for slow memory devices.. in fact now having just said that does anybody have a timmign diagram of a zeddy using the dynamic 16K ram pack ? thats ras n' cas n' all aint it so probably slower than static memory....
oh yeah one more tip. the databus needs to be open collector not just tri-state, there are some keyboard / joystick interfaces that plug into the extension slot that correctly decode port $FE (ferd as i call it) and they work, the only explanation is that the original ULA must be open collector so only drive the lines low and rely on the pull-up resistors to provide a logic high. i don't know about the xilinx software but the altera software i've been using defaulted to tristate i had to go into the pin assiments and tell it i wanted open collecter ( well open drain, but that another story
)
Regards Andy
regards the force nop timing, in my gal design it extends from the begining of the last 1/4 of T2 to the end of the first 1/4 of T3 (just one 6.5Mhz cycle) as the Z80 samples the data bus on the rising edge of T3 as you have discovered

i test the conditiond for a video cycle 1/2 (6.5Mhz clock) cycle before this as it's good to leave it as late as possible to allow for slow memory devices.. in fact now having just said that does anybody have a timmign diagram of a zeddy using the dynamic 16K ram pack ? thats ras n' cas n' all aint it so probably slower than static memory....
oh yeah one more tip. the databus needs to be open collector not just tri-state, there are some keyboard / joystick interfaces that plug into the extension slot that correctly decode port $FE (ferd as i call it) and they work, the only explanation is that the original ULA must be open collector so only drive the lines low and rely on the pull-up resistors to provide a logic high. i don't know about the xilinx software but the altera software i've been using defaulted to tristate i had to go into the pin assiments and tell it i wanted open collecter ( well open drain, but that another story

Regards Andy
what's that Smell.... smells like fresh flux and solder fumes...
Re: ULA revistited.
I'm loving this thread - keep the pr0n coming 

Re: ULA revistited.
YepAndy Rea wrote:Blimey thats fast work... do you make the PCB's yourself ?


Yeah I had to adjust the timing slightly, as it was not working correctly when I used a slower 6116 (insted of the 20ns SRAM that I was using !), or my Memotech RAM pack, seems to be working correctly now. I've not been able to test with a proper Sinclair ram pack as I don't have one, but will try it with the 3K ZX80 pack that I have.regards the force nop timing, in my gal design it extends from the begining of the last 1/4 of T2 to the end of the first 1/4 of T3 (just one 6.5Mhz cycle) as the Z80 samples the data bus on the rising edge of T3 as you have discovered![]()
i test the conditiond for a video cycle 1/2 (6.5Mhz clock) cycle before this as it's good to leave it as late as possible to allow for slow memory devices.. in fact now having just said that does anybody have a timmign diagram of a zeddy using the dynamic 16K ram pack ? thats ras n' cas n' all aint it so probably slower than static memory....
I checked by searching on the web and apparently defining it 8'bz should make it open collector / drain, so it should work. Humm I may try and see if I can design a JS/KBD interface to test that.... humm wonder if there are any schematics of such a device out there ?oh yeah one more tip. the databus needs to be open collector not just tri-state, there are some keyboard / joystick interfaces that plug into the extension slot that correctly decode port $FE (ferd as i call it) and they work, the only explanation is that the original ULA must be open collector so only drive the lines low and rely on the pull-up resistors to provide a logic high. i don't know about the xilinx software but the altera software i've been using defaulted to tristate i had to go into the pin assiments and tell it i wanted open collecter ( well open drain, but that another story)
@sirmorris I guess your ZXPAND with it's joystick emulation would qualify there, now wonder if there's room in your PIC for some PS/2 keyboard controler code....
Now if I can get the tape input to work correctly I'll be pretty much done, it works for 1K Chess, but fails to load QS Scramble, putting a scope probe looks like the QS Scramble tape has a lower level input so that may well be the problem, will disconnect the 47K and see if that helps. I know both tapes load fine on my (original** unmodified ZX81).
**Not only my first ZX81, but my first computer !.
Cheers.
Phill.
Re: ULA revistited.
Yeah p0rn on a ZX81, not gonna be that good in monochrome 64x48 is it ????? Mind with ZXPAND and Hi-res.....sirmorris wrote:I'm loving this thread - keep the pr0n coming
Mind I also have the Memotech hi-res interface, must reverse-engineer that at some point, I'd be more keen to do that but I only have one of them and don't wanna break it !
Cheers,
Phill.