I've set up credit card payment processing through a company called iTransact . I have sent out invoices to a few people already and will be sending it out to everyone who got a paypal refund within the next few days. If you don't see anything by next Tuesday, you may want to check any alternate email accounts you have, including the one you use with Paypal as I will likely be using the same one to send these invoices.
Thursday, March 31, 2016
Monday, March 28, 2016
I hate Paypal
So Paypal is really trying to make my life miserable by not letting me have access to some of the Dexter money that people have paid. I've thought long and hard about what to do and have decided that I am going to refund as much of this "locked up" money as possible and hope that people are willing to pay me again using a different method. I'd rather take this risk than rely on Paypal to release the funds (I've heard that it is very hard to get them to do this since they are essentially a dumb machine that relies on algorithms that often get it wrong).
So you may see a Paypal refund come from me soon (some people will have already seen it). I will provide further instructions on how you can pay for your Dexter boards without using Paypal.
The good news is that I did get enough funds to pay to have the boards made and they are being made as we speak. You can find the full schedule including estimated delivery times at http://laserdisc-replacement.com So for now, Paypal's shenanigans have not impacted Dexter's delivery date, although I certainly have been greatly inconvenienced and had a huge amount of my valuable time wasted a result.
TLDR: Dexter is still on schedule but don't use Paypal :)
So you may see a Paypal refund come from me soon (some people will have already seen it). I will provide further instructions on how you can pay for your Dexter boards without using Paypal.
The good news is that I did get enough funds to pay to have the boards made and they are being made as we speak. You can find the full schedule including estimated delivery times at http://laserdisc-replacement.com So for now, Paypal's shenanigans have not impacted Dexter's delivery date, although I certainly have been greatly inconvenienced and had a huge amount of my valuable time wasted a result.
TLDR: Dexter is still on schedule but don't use Paypal :)
Thursday, March 24, 2016
Cleaning battery acid damage off of Cliff Hanger ZPU board
I just got a Cliff Hanger ZPU board in the mail (woohoo!).
Warren pointed out that it still has the battery attached and that the battery is starting to leak. Uh oh!
Time to remove the battery...
Now time to clean up the traces of 'green fuzz' that were near the battery.
I think I got it all cleaned off. I wish I could say the same for Rockford's Star Rider's CPU board. ;)
Warren pointed out that it still has the battery attached and that the battery is starting to leak. Uh oh!
Time to remove the battery...
Now time to clean up the traces of 'green fuzz' that were near the battery.
I think I got it all cleaned off. I wish I could say the same for Rockford's Star Rider's CPU board. ;)
Tuesday, March 22, 2016
Prototype Surface Mount Soldering Mini-Tutorial: How I do it
Ever wanted to solder surface mount components onto a PCB but were afraid because your soldering iron tip is so big and the pins on the chips are so tiny? I used to be scared. But with the right tools and some practice, you can do it!
The approach I use in this video:
- Get chip secured to the PCB using solder paste and a heat gun. It's okay if we have some solder bridges or not all pins have solder on them at this stage. The important part is that the chip is properly aligned to the pins on the PCB.
- Apply flux to pins
- Drag solder iron across pins to pull all of the extra solder to one end.
- Remove extra solder using solder wick. This will not remove all of the solder, just the excess (phew).
- (optional but recommended) Test the board to make sure soldering job is correct.
- Clean off flux using rubbing alcohol or (my favorite) Goo Gone. Rinse in water while alcohol/go gone has not yet dried (yes, really) and let dry completely before testing. If white film shows up after drying, it means you did not get all of the flux off so repeat this step until the board looks clean after it has dried.
NOTE : I've used this approach many times for prototype work and it works just fine. For production work, I'd have a PCB fabrication house assemble the board for you. I use 4pcb.com.
The approach I use in this video:
- Get chip secured to the PCB using solder paste and a heat gun. It's okay if we have some solder bridges or not all pins have solder on them at this stage. The important part is that the chip is properly aligned to the pins on the PCB.
- Apply flux to pins
- Drag solder iron across pins to pull all of the extra solder to one end.
- Remove extra solder using solder wick. This will not remove all of the solder, just the excess (phew).
- (optional but recommended) Test the board to make sure soldering job is correct.
- Clean off flux using rubbing alcohol or (my favorite) Goo Gone. Rinse in water while alcohol/go gone has not yet dried (yes, really) and let dry completely before testing. If white film shows up after drying, it means you did not get all of the flux off so repeat this step until the board looks clean after it has dried.
NOTE : I've used this approach many times for prototype work and it works just fine. For production work, I'd have a PCB fabrication house assemble the board for you. I use 4pcb.com.
Saturday, March 19, 2016
Friday, March 18, 2016
Thursday, March 10, 2016
Wednesday, March 9, 2016
Star Rider's initial color 'test' is almost useless
Unless you own a Star Rider arcade game or are fairly familiar with it, you probably don't have any idea of what happens when the game is powered on.
Well, let me tell you. The first thing that happens is the video RAM is filled with a solid color. This fill is performed by the CPU and is quite slow. This loops through the entire color palette (16 colors) and adds a significant amount of time to the overall boot time. I had always assumed that this test was testing to see whether the video RAM was any good. But after revisiting this test recently, I discovered that the code does not actually check to see whether the value that it stored can be read back. So how useful is this test? The only use that I can see is if a human is watching the monitor while the test is running and is familiar enough with what is supposed to be shown to spot a problem. But really, there is no excuse for the CPU to not read back what it wrote and save the human from this kind of trouble.
Here's the relevant code:
ROM:F15F WhileBigColorFillNotDone: ; CODE XREF: GoCmpCC07AndFWith9+163 j
ROM:F15F ldx #RamStartA000 ; fill all video memory with a single color (go through palette)
ROM:F162
ROM:F162 Fill9FFFto0WithY: ; CODE XREF: GoCmpCC07AndFWith9+15D j
ROM:F162 ldb #$15
ROM:F164 lda #8
ROM:F166
ROM:F166 WatchdogThink: ; CODE XREF: GoCmpCC07AndFWith9+155 j
ROM:F166 stb HW_Watchdog ; this address has something to do with watchdog timer
ROM:F169 deca
ROM:F16A bne WatchdogThink
ROM:F16C sty ,-x ; this appears to be inefficient; since we are storing 2 bytes at a time, X could be decremented by 2 instead of just 1.
ROM:F16F cmpx #0
ROM:F172 bne Fill9FFFto0WithY
ROM:F174 leay $EEEF,y ; subtract by 1111h (so FFFFh becomes EEEEh)
ROM:F178 bne WhileBigColorFillNotDone ; fill all video memory with a single color (go through palette)
ROM:F17A lda #2
ROM:F17C ldy #PostRugTestBoot
ROM:F180 jmp RugPatternTest ; Does Rug Pattern test, jumps to address in Y when finished.
ROM:F180 ; Carry may be set if test failed.
NOTE at $F16A the loop to 'feed' the watch dog. I don't fully understand what is needed to keep the watch dog from barking, but I'd be willing to bet that this loop is completely unnecessary. Also, $F16C writes two bytes but only decrements its index by 1. I can see no reason why it wouldn't decrement by 2 here and accomplish the same thing. Not only is this test slow because it is using the CPU to write to video RAM, but it is slow because it is wasting time for no good reason.
Changes that I would make to this test: completely skip it :) The rug pattern test also tests video RAM so this test is redundant.
Well, let me tell you. The first thing that happens is the video RAM is filled with a solid color. This fill is performed by the CPU and is quite slow. This loops through the entire color palette (16 colors) and adds a significant amount of time to the overall boot time. I had always assumed that this test was testing to see whether the video RAM was any good. But after revisiting this test recently, I discovered that the code does not actually check to see whether the value that it stored can be read back. So how useful is this test? The only use that I can see is if a human is watching the monitor while the test is running and is familiar enough with what is supposed to be shown to spot a problem. But really, there is no excuse for the CPU to not read back what it wrote and save the human from this kind of trouble.
Here's the relevant code:
ROM:F15F WhileBigColorFillNotDone: ; CODE XREF: GoCmpCC07AndFWith9+163 j
ROM:F15F ldx #RamStartA000 ; fill all video memory with a single color (go through palette)
ROM:F162
ROM:F162 Fill9FFFto0WithY: ; CODE XREF: GoCmpCC07AndFWith9+15D j
ROM:F162 ldb #$15
ROM:F164 lda #8
ROM:F166
ROM:F166 WatchdogThink: ; CODE XREF: GoCmpCC07AndFWith9+155 j
ROM:F166 stb HW_Watchdog ; this address has something to do with watchdog timer
ROM:F169 deca
ROM:F16A bne WatchdogThink
ROM:F16C sty ,-x ; this appears to be inefficient; since we are storing 2 bytes at a time, X could be decremented by 2 instead of just 1.
ROM:F16F cmpx #0
ROM:F172 bne Fill9FFFto0WithY
ROM:F174 leay $EEEF,y ; subtract by 1111h (so FFFFh becomes EEEEh)
ROM:F178 bne WhileBigColorFillNotDone ; fill all video memory with a single color (go through palette)
ROM:F17A lda #2
ROM:F17C ldy #PostRugTestBoot
ROM:F180 jmp RugPatternTest ; Does Rug Pattern test, jumps to address in Y when finished.
ROM:F180 ; Carry may be set if test failed.
NOTE at $F16A the loop to 'feed' the watch dog. I don't fully understand what is needed to keep the watch dog from barking, but I'd be willing to bet that this loop is completely unnecessary. Also, $F16C writes two bytes but only decrements its index by 1. I can see no reason why it wouldn't decrement by 2 here and accomplish the same thing. Not only is this test slow because it is using the CPU to write to video RAM, but it is slow because it is wasting time for no good reason.
Changes that I would make to this test: completely skip it :) The rug pattern test also tests video RAM so this test is redundant.
Emulation vs FPGA
I was thinking about this on my drive to work this morning and decided to write my thoughts down while they are still fresh in my head.
I've been hearing people talk about "one to one" (ie 1:1) or "not emulation" when talking about FPGAs. What do they mean when they says this?
I've talked about this in previous posts, but it's been a while and now may be a good time for a refresher.
The way that CPU's in classic 80's arcade games work is that they all require a clock which alternates between a high and low state at a frequency usually in the low megahertz range (ie 1 MHz). They also usually have at least 16 address lines and at least 8 data lines. A few CPUs had more than this, but I will focus on the CPUs that have 16 address lines, 8 data lines, and a single clock input.
This is your typical 8-bit CPU that can address 64k of memory. How did I conclude that it can access 64k of memory? Because it has 16 address lines, and 2 to the 16th power is 65536 which is 64k (65536 / 1024 is 64, and 1k is 1024 bytes). How did I conclude that it's an 8-bit CPU? Because it has 8 data lines which is usually what people refer to when they talk about an "8-bit", "16-bit", "32-bit", or "64-bit" CPU.
The CPU's 16 address lines are always outputs, meaning that the CPU is the only device in the computer that is allowed to change its address. The CPU's 8 data lines can be either inputs or outputs. The CPU has other lines on it which indicate whether it is trying to read from its data lines or write to its data lines.
The CPU has a very small number of internal memory buffers called registers, but almost all of the memory that the CPU needs comes from either external ROM or external RAM. When the CPU wants to execute an instruction (where a complete program consists of many instructions), it has to fetch the instruction from an external dependency (usually ROM or RAM). It does this by setting its address lines to the address that it wants to fetch the memory from, and then setting its read/write lines to let the rest of the computer know that it wants the byte stored at the address on its address lines. On power-up, the CPU will set its initial address to a fixed, known location and either start executing instructions from that location or read an address from that location, jump to that address, and start executing instructions.
Each CPU instruction takes a specific number of clock cycles to complete.
So what does all of this have to do with emulation vs FPGA ?
If I were trying to implement a CPU inside of an FPGA, I could (if I do it correctly) have the FPGA's input/output lines behave exactly like the original CPU. And if the FPGA's I/O behaves exactly like the original CPU's I/O, then the FPGA could be considered to be 100% compatible with the original CPU and one could use it as a drop-in replacement for the CPU without sacrificing any sort of accuracy. This is what people mean by "one to one." I should note that from what I have seen of efforts to implements CPU's inside of FPGA's, I am not convinced that the people who put forth the effort were terribly concerned about accuracy, and may have been more concerned about making the FPGA version CPU perform faster than the original. So just because an FPGA could in theory be a 100% accurate replacement for the CPU does not mean that this is what is happening.
Now, what might people mean when they say "not emulation" ?
CPU emulators, such as what one may find in MAME, take a few shortcuts in order to achieve decent performance. They do not emulate the clock of the CPU, but instead are designed to execute a variable number of cycles in one shot as quickly as the host machine (ie a modern x64 computer) can execute. The code that is driving this execution is then responsible to regulate the overall speed of the system so that it does not run too quickly.
For example, let's say we are emulating a 1 MHz Z80 cpu. The cpu management code may tell a z80 emulator to execute 1000 cycles which would take 1 ms on original hardware. The z80 emulator would then go execute these 1000 cycles as fast as possible and report back how many cycles were actually emulated (it might be more than 1000 because some instructions take more than 1 cycle). The cpu management code would then have to stall until the 1 ms period has completed before executing the next chunk of cycles.
This creates an unauthentic experience because it means that instead of instructions being executed at a steady slower cadence, they are executed in quick bursts with delays in between. This is usually not noticeable by a human playing the emulated game because it's just 1 ms, but several problems can arise depending on the other architecture of the original hardware.
On a game like Dragon's Lair where there is just one CPU and a steady clock that never varies, the above method of emulation is "good enough." A human is not really going to notice any meaningful difference in accuracy.
But what of the game has multiple CPUs such as a dedicated sound CPU? Now the emulator has to execute a smaller slice of cycles on the first CPU, then switch to the second CPU and execute another smaller slice of cycles. If there are interactions between these two CPUs (and there usually will be), the slice of cycles that gets executed needs to be small enough so that there is no unnatural lag in the interactions which hurts performance of the overall system. And even if each CPU takes turns executing just 1 cycle, the potential for an inaccurate interaction between the two emulated CPUs still exists since the emulator does not take into account the clock.
Now, what if the original hardware fiddles with the CPUs clock, or the clock is not constant for some reason? The Williams games are notorious for doing this. On a lot of the Williams games, like Joust, their custom DMA chip will actually halt the CPU while the DMA operation is running. On Star Rider, the CPU's clock gets halted every field for unknown reasons (that's on my TODO list to figure out why). Last time I checked, this behavior was not emulated very well in MAME (it may have improved since I last checked) and certainly Daphne is not equipped to handle this type of scenario. However, an FPGA would be able to handle it just fine.
Now, does this mean that emulators like MAME and Daphne can't be improved to take into account a variable clock? Not at all. As modern computers get faster, it will become more feasible for emulators to become more accurate without hurting performance. I believe that aside from the problems associated with running on a modern operating system (with many processes and threads all competing for the CPU's time), there is no reason why software-based emulators cannot achieve 100% accuracy as their architectures are improved. However, I do not believe that that day is here... yet.
I hope that gives people a better idea of what I consider the difference to be between FPGA solutions and emulation solutions.
I've been hearing people talk about "one to one" (ie 1:1) or "not emulation" when talking about FPGAs. What do they mean when they says this?
I've talked about this in previous posts, but it's been a while and now may be a good time for a refresher.
The way that CPU's in classic 80's arcade games work is that they all require a clock which alternates between a high and low state at a frequency usually in the low megahertz range (ie 1 MHz). They also usually have at least 16 address lines and at least 8 data lines. A few CPUs had more than this, but I will focus on the CPUs that have 16 address lines, 8 data lines, and a single clock input.
This is your typical 8-bit CPU that can address 64k of memory. How did I conclude that it can access 64k of memory? Because it has 16 address lines, and 2 to the 16th power is 65536 which is 64k (65536 / 1024 is 64, and 1k is 1024 bytes). How did I conclude that it's an 8-bit CPU? Because it has 8 data lines which is usually what people refer to when they talk about an "8-bit", "16-bit", "32-bit", or "64-bit" CPU.
The CPU's 16 address lines are always outputs, meaning that the CPU is the only device in the computer that is allowed to change its address. The CPU's 8 data lines can be either inputs or outputs. The CPU has other lines on it which indicate whether it is trying to read from its data lines or write to its data lines.
The CPU has a very small number of internal memory buffers called registers, but almost all of the memory that the CPU needs comes from either external ROM or external RAM. When the CPU wants to execute an instruction (where a complete program consists of many instructions), it has to fetch the instruction from an external dependency (usually ROM or RAM). It does this by setting its address lines to the address that it wants to fetch the memory from, and then setting its read/write lines to let the rest of the computer know that it wants the byte stored at the address on its address lines. On power-up, the CPU will set its initial address to a fixed, known location and either start executing instructions from that location or read an address from that location, jump to that address, and start executing instructions.
Each CPU instruction takes a specific number of clock cycles to complete.
So what does all of this have to do with emulation vs FPGA ?
If I were trying to implement a CPU inside of an FPGA, I could (if I do it correctly) have the FPGA's input/output lines behave exactly like the original CPU. And if the FPGA's I/O behaves exactly like the original CPU's I/O, then the FPGA could be considered to be 100% compatible with the original CPU and one could use it as a drop-in replacement for the CPU without sacrificing any sort of accuracy. This is what people mean by "one to one." I should note that from what I have seen of efforts to implements CPU's inside of FPGA's, I am not convinced that the people who put forth the effort were terribly concerned about accuracy, and may have been more concerned about making the FPGA version CPU perform faster than the original. So just because an FPGA could in theory be a 100% accurate replacement for the CPU does not mean that this is what is happening.
Now, what might people mean when they say "not emulation" ?
CPU emulators, such as what one may find in MAME, take a few shortcuts in order to achieve decent performance. They do not emulate the clock of the CPU, but instead are designed to execute a variable number of cycles in one shot as quickly as the host machine (ie a modern x64 computer) can execute. The code that is driving this execution is then responsible to regulate the overall speed of the system so that it does not run too quickly.
For example, let's say we are emulating a 1 MHz Z80 cpu. The cpu management code may tell a z80 emulator to execute 1000 cycles which would take 1 ms on original hardware. The z80 emulator would then go execute these 1000 cycles as fast as possible and report back how many cycles were actually emulated (it might be more than 1000 because some instructions take more than 1 cycle). The cpu management code would then have to stall until the 1 ms period has completed before executing the next chunk of cycles.
This creates an unauthentic experience because it means that instead of instructions being executed at a steady slower cadence, they are executed in quick bursts with delays in between. This is usually not noticeable by a human playing the emulated game because it's just 1 ms, but several problems can arise depending on the other architecture of the original hardware.
On a game like Dragon's Lair where there is just one CPU and a steady clock that never varies, the above method of emulation is "good enough." A human is not really going to notice any meaningful difference in accuracy.
But what of the game has multiple CPUs such as a dedicated sound CPU? Now the emulator has to execute a smaller slice of cycles on the first CPU, then switch to the second CPU and execute another smaller slice of cycles. If there are interactions between these two CPUs (and there usually will be), the slice of cycles that gets executed needs to be small enough so that there is no unnatural lag in the interactions which hurts performance of the overall system. And even if each CPU takes turns executing just 1 cycle, the potential for an inaccurate interaction between the two emulated CPUs still exists since the emulator does not take into account the clock.
Now, what if the original hardware fiddles with the CPUs clock, or the clock is not constant for some reason? The Williams games are notorious for doing this. On a lot of the Williams games, like Joust, their custom DMA chip will actually halt the CPU while the DMA operation is running. On Star Rider, the CPU's clock gets halted every field for unknown reasons (that's on my TODO list to figure out why). Last time I checked, this behavior was not emulated very well in MAME (it may have improved since I last checked) and certainly Daphne is not equipped to handle this type of scenario. However, an FPGA would be able to handle it just fine.
Now, does this mean that emulators like MAME and Daphne can't be improved to take into account a variable clock? Not at all. As modern computers get faster, it will become more feasible for emulators to become more accurate without hurting performance. I believe that aside from the problems associated with running on a modern operating system (with many processes and threads all competing for the CPU's time), there is no reason why software-based emulators cannot achieve 100% accuracy as their architectures are improved. However, I do not believe that that day is here... yet.
I hope that gives people a better idea of what I consider the difference to be between FPGA solutions and emulation solutions.
Monday, March 7, 2016
Saturday, March 5, 2016
All parts needed to assemble the Dexter boards are here
Six boxes from Digikey and one box from Mouser and I now have all of the parts needed to assemble the Dexter PCBs. Most likely, I will be shipping these off to the PCB manufacturer on Monday.
Friday, March 4, 2016
Three operating systems, one desktop
I'm sure something similar has been posted by endless numbers of geeks everywhere, but I'm posting it anyway :)
Windows, linux, and OSX all on a single desktop:
My Windows 7 box which is SSH'd into a rasperry pi (linux) and remote desktop'd (is that a word) into my Mac Mini.
Windows, linux, and OSX all on a single desktop:
My Windows 7 box which is SSH'd into a rasperry pi (linux) and remote desktop'd (is that a word) into my Mac Mini.
Tuesday, March 1, 2016
DEXTER Pre-Order period has completed! (huge success!)
The Dexter pre-order period for the first two months of this year has concluded and I have been blown away. The final count is 307 Dexter kits pre-ordered! That's insane! I was thinking the final would be between 100-150 so this result has me in shock!
A few things:
- I will be keeping the Dexter page up to date with the current status of the boards as they are being produced. Please bear with me as I get this setup as the immediate urgency is to get the parts and boards ordered.
- My initial estimate that the boards would be ready to ship at the beginning of April is likely no longer true as I was projecting a final count of 100-150. I will post a new projected time as soon as I know one!
- I will contact customers via the email address associated with their Paypal account that they used to make the purchase. If you want me to use a different contact email, let me know.
A few things:
- I will be keeping the Dexter page up to date with the current status of the boards as they are being produced. Please bear with me as I get this setup as the immediate urgency is to get the parts and boards ordered.
- My initial estimate that the boards would be ready to ship at the beginning of April is likely no longer true as I was projecting a final count of 100-150. I will post a new projected time as soon as I know one!
- I will contact customers via the email address associated with their Paypal account that they used to make the purchase. If you want me to use a different contact email, let me know.
Subscribe to:
Posts (Atom)