Relative Mintages of US Small Dollar Coins And The Odds Of Finding Them In Circulation

Image

I was curious about the chances of finding various small dollar coins in circulation. I imported the mintage values for each year/mint/series into a spreadsheet, and created the following table.

For each coin, the mintage is shown, along with that mintage as a percentage of the total number of small dollar coins minted, which happens to be 5,222,246,560.

I then computed two other numbers for each coin:

Rank – A ranking of coins by most common (2000-P Sacagawea) to least common (2023-D Mississippi Innovation).

One Out of Every – Essentially the inverse of percentage. For example, for 2000-P Sacagawea it’s 7, which means that (roughly) 1 out of 7 coins are this. For the 1979-P Susan B. Anthony, 1/14. And so on. For clarity, values are rounded to the nearest integer. You could treat this, very crudely, as an estimate of how many coins you would need to search to find one of these.

Several caveats:

I do include the NIFC (Not Intended For Circulation) strikes. Those coins that, officially at least, were only sold to collectors. I suspect that in addition to some being dumped into circulation by individuals, the US Mint / Treasury release unsold NIFC coins into circulation. From my experience coin roll hunting, they do turn up much more often than I’d expect.

I do not include proofs. Yes, they turn up now and then, but only when someone releases one into circulation. For most years/series, 2 to 3 million proofs were minted. Fewer for recent years of Presidential and Native American coins, and far fewer for Innovation Dollars. They turn up in significantly smaller numbers than the NIFC strikes. I’m not sure it would be worth adding proofs to the table, as I think the suggested chances of finding them would be highly inflated.

Speaking of Innovation Dollars… their total mintage (to date) is 18,844,500, or 0.361% of all small dollars. If they were all in circulation (which they are not), the odds of finding one would be 1 in 277. From experience, my actual results are much worse than this. This suggests the odds for each member of the series in the table below is indeed inflated, as most never entered circulation.

The table is a mix of P and D mint coins. If you live between the two mints, perhaps you see nearly equal numbers of each. I live in MD, very close to the Philadelphia mint. Obviously, I see primarily P minted coins. D coins turn up, but in in much smaller numbers. Therefore I am much less likely to find D mint coins than the table suggests, and more likely to find P mint coins. The converse would be true for those in the western states.

Based on my penny coin roll hunting results, older D mint coins are much more likely to turn up here. This makes sense, the longer a coin is in circulation, the more time it has to work its way around the country. For the 1960s and back (wheat cents included) I tend to find roughly equal numbers of P and D cents, relative to their mintages. Fewer S mint pennies from 1968-1974, even taking into account their very low mintages, but that’s to be expected since they need to travel further.

OTOH, for recent years, D mint pennies are much less common here. They have not had enough time to work their way east. I assume this works the same way for those in the West, with respect to P mint coins.

Here’s a graph of my penny results. It’s somewhat convoluted based on how I set aside coins and count them, but I think you will get the idea:

Small dollar coins only date back to 1979, they’ve had less time to move around the country. Most of them have had very little time, this is reflected in how much more difficult they are for me to find.

To summarize:

For those coins where there were circulating business strikes, the table does an adequate job estimating how easy it is to find them, if you ignore the P/D mint issues (you live somewhere between the mints, and generally see a good mix of coins from both mints). Otherwise, you should keep in mind that it is going to be more difficult to find coins from the “other” mint than the table suggests.

For NIFC strikes, the table likely over-estimates your chances of finding coins, possibly significantly.

It might be best to treat the numbers in a relative, vs absolute, fashion.

After your done reading through this, head on over to my website Black Cat Systems and take a look at the software I write and sell. Maybe you will find something useful!

 

Year / Mint / Coin Mintage Percent One Out Of Every Rank
1979-P SBA 360,222,000 6.8978 14 3
1979-D SBA 288,015,744 5.5152 18 4
1979-S SBA 109,576,000 2.0983 48 9
1980-P SBA 27,610,000 0.5287 189 56
1980-D SBA 41,628,708 0.7971 125 34
1980-S SBA 20,422,000 0.3911 256 57
1981-P SBA 3,000,000 0.0574 1,741 108
1981-D SBA 3,250,000 0.0622 1,607 103
1981-S SBA 3,492,000 0.0669 1,495 99
1999-P 29,592,000 0.5667 176 54
1999-D SBA 11,776,000 0.2255 443 58
2000-P Sacagawea 767,140,000 14.6898 7 1
2000-D Sacagawea 518,916,000 9.9366 10 2
2001-P Sacagawea 62,468,000 1.1962 84 16
2001-D Sacagawea 70,939,500 1.3584 74 14
2002-P Sacagawea 3,865,610 0.074 1,351 91
2002-D Sacagawea 3,732,000 0.0715 1,399 95
2003-P Sacagawea 3,080,000 0.059 1,696 104
2003-D Sacagawea 3,080,000 0.059 1,696 105
2004-P Sacagawea 2,660,000 0.0509 1,963 114
2004-D Sacagawea 2,660,000 0.0509 1,963 115
2005-P Sacagawea 2,520,000 0.0483 2,072 116
2005-D Sacagawea 2,520,000 0.0483 2,072 117
2006-P Sacagawea 4,900,000 0.0938 1,066 73
2006-D Sacagawea 2,800,000 0.0536 1,865 109
2007-P Sacagawea 3,640,000 0.0697 1,435 97
2007-D Sacagawea 3,920,000 0.0751 1,332 87
2008-P Sacagawea 1,820,000 0.0349 2,869 120
2008-D Sacagawea 1,820,000 0.0349 2,869 121
2009-P Native American 39,200,000 0.7506 133 36
2009-D Native American 35,700,000 0.6836 146 51
2010-P Native American 32,060,000 0.6139 163 53
2010-D Native American 48,720,000 0.9329 107 26
2011-P Native American 29,400,000 0.563 178 55
2011-D Native American 48,160,000 0.9222 108 27
2012-P Native American 2,800,000 0.0536 1,865 110
2012-D Native American 3,080,000 0.059 1,696 106
2013-P Native American 1,820,000 0.0349 2,869 122
2013-D Native American 1,820,000 0.0349 2,869 123
2014-P Native American 3,080,000 0.059 1,696 107
2014-D Native American 2,800,000 0.0536 1,865 111
2015-P Native American 2,800,000 0.0536 1,865 112
2015-D Native American 2,240,000 0.0429 2,331 118
2016-P Native American 2,800,000 0.0536 1,865 113
2016-D Native American 2,100,000 0.0402 2,487 119
2017-P Native American 1,820,000 0.0349 2,869 124
2017-D Native American 1,540,000 0.0295 3,391 125
2018-P Native American 1,400,000 0.0268 3,730 128
2018-D Native American 1,400,000 0.0268 3,730 129
2019-P Native American 1,400,000 0.0268 3,730 130
2019-D Native American 1,540,000 0.0295 3,391 126
2020-P Native American 1,260,000 0.0241 4,145 132
2020-D Native American 1,260,000 0.0241 4,145 133
2021-P Native American 1,400,000 0.0268 3,730 131
2021-D Native American 1,260,000 0.0241 4,145 134
2022-P Native American 980,000 0.0188 5,329 138
2022-D Native American 980,000 0.0188 5,329 139
2023-P Native American 1,120,000 0.0214 4,663 136
2023-D Native American 1,120,000 0.0214 4,663 137
2007-P George Washington 176,680,000 3.3832 30 5
2007-D George Washington 163,680,000 3.1343 32 6
2007-P John Adams 112,420,000 2.1527 46 7
2007-D John Adams 112,140,000 2.1474 47 8
2007-P Thomas Jefferson 100,800,000 1.9302 52 11
2007-D Thomas Jefferson 102,810,000 1.9687 51 10
2007-P James Madison 84,560,000 1.6192 62 13
2007-D James Madison 87,780,000 1.6809 59 12
2008-P James Monroe 64,260,000 1.2305 81 15
2008-D James Monroe 60,230,000 1.1533 87 19
2008-P John Quincy Adams 57,540,000 1.1018 91 21
2008-D John Quincy Adams 57,720,000 1.1053 90 20
2008-P Andrew Jackson 61,180,000 1.1715 85 17
2008-D Andrew Jackson 61,070,000 1.1694 86 18
2008-P Martin Van Buren 51,520,000 0.9865 101 23
2008-D Martin Van Buren 50,960,000 0.9758 102 24
2009-P William Henry Harrison 43,260,000 0.8284 121 32
2009-D William Henry Harrison 55,160,000 1.0563 95 22
2009-P John Tyler 43,540,000 0.8337 120 30
2009-D John Tyler 43,540,000 0.8337 120 31
2009-P James K. Polk 46,620,000 0.8927 112 29
2009-D James K. Polk 41,720,000 0.7989 125 33
2009-P Zachary Taylor 41,580,000 0.7962 126 35
2009-D Zachary Taylor 36,680,000 0.7024 142 49
2010-P Millard Fillmore 37,520,000 0.7185 139 42
2010-D Millard Fillmore 36,960,000 0.7077 141 46
2010-P Franklin Pierce 38,220,000 0.7319 137 38
2010-D Franklin Pierce 38,360,000 0.7345 136 37
2010-P James Buchanan 36,820,000 0.7051 142 47
2010-D James Buchanan 36,540,000 0.6997 143 50
2010-P Abraham Lincoln 49,000,000 0.9383 107 25
2010-D Abraham Lincoln 48,020,000 0.9195 109 28
2011-P Andrew Johnson 35,560,000 0.6809 147 52
2011-D Andrew Johnson 37,100,000 0.7104 141 43
2011-P Ulysses S. Grant 38,080,000 0.7292 137 39
2011-D Ulysses S. Grant 37,940,000 0.7265 138 40
2011-P Rutherford B. Hayes 37,660,000 0.7211 139 41
2011-D Rutherford B. Hayes 36,820,000 0.7051 142 48
2011-P James Garfield 37,100,000 0.7104 141 44
2011-D James Garfield 37,100,000 0.7104 141 45
2012-P Chester Arthur 6,020,000 0.1153 867 64
2012-D Chester Arthur 4,060,000 0.0777 1,286 85
2012-P Grover Cleveland (1st Term) 5,460,000 0.1046 956 67
2012-D Grover Cleveland (1st Term) 4,060,000 0.0777 1,286 86
2012-P Benjamin Harrison 5,640,000 0.108 926 66
2012-D Benjamin Harrison 4,200,000 0.0804 1,243 83
2012-P Grover Cleveland (2nd Term) 10,680,000 0.2045 489 59
2012-D Grover Cleveland (2nd Term) 3,920,000 0.0751 1,332 88
2013-P William McKinley 4,760,000 0.0911 1,097 76
2013-D William McKinley 3,365,100 0.0644 1,552 100
2013-P Theodore Roosevelt 5,310,700 0.1017 983 70
2013-D Theodore Roosevelt 3,920,000 0.0751 1,332 89
2013-P William Howard Taft 4,760,000 0.0911 1,097 77
2013-D William Howard Taft 3,360,000 0.0643 1,554 101
2013-P Woodrow Wilson 4,620,000 0.0885 1,130 79
2013-D Woodrow Wilson 3,360,000 0.0643 1,554 102
2014-P Warren G. Harding 6,160,000 0.118 848 62
2014-D Warren G. Harding 3,780,000 0.0724 1,382 92
2014-P Calvin Coolidge 4,480,000 0.0858 1,166 80
2014-D Calvin Coolidge 3,780,000 0.0724 1,382 93
2014-P Herbert Hoover 4,480,000 0.0858 1,166 81
2014-D Herbert Hoover 3,780,000 0.0724 1,382 94
2014-P Franklin D. Roosevelt 4,760,000 0.0911 1,097 78
2014-D Franklin D. Roosevelt 3,920,000 0.0751 1,332 90
2015-P Harry S. Truman 4,900,000 0.0938 1,066 74
2015-D Harry S. Truman 3,500,000 0.067 1,492 98
2015-P Dwight D. Eisenhower 4,900,000 0.0938 1,066 75
2015-D Dwight D. Eisenhower 3,645,998 0.0698 1,432 96
2015-P John F. Kennedy 6,160,000 0.118 848 63
2015-D John F. Kennedy 5,180,000 0.0992 1,008 71
2015-P Lyndon B. Johnson 7,840,000 0.1501 666 60
2015-D Lyndon B. Johnson 4,200,000 0.0804 1,243 84
2016-P Richard M. Nixon 5,460,000 0.1046 956 68
2016-D Richard M. Nixon 4,340,000 0.0831 1,203 82
2016-P Gerald R. Ford 5,460,000 0.1046 956 69
2016-D Gerald R. Ford 5,040,000 0.0965 1,036 72
2016-P Ronald Reagan 7,140,000 0.1367 731 61
2016-D Ronald Reagan 5,880,000 0.1126 888 65
2020-P George H.W. Bush 1,242,275 0.0238 4,204 135
2020-D George H.W. Bush 1,502,425 0.0288 3,476 127
2018-P Introductory 502,150 0.0096 10,400 142
2018-D Introductory 582,825 0.0112 8,960 140
2019-P Delaware 472,750 0.0091 11,047 148
2019-D Delaware 479,975 0.0092 10,880 145
2019-P Pennsylvania 490,200 0.0094 10,653 144
2019-D Pennsylvania 443,800 0.0085 11,767 165
2019-P New Jersey 521,175 0.01 10,020 141
2019-D New Jersey 476,275 0.0091 10,965 146
2019-P Georgia 474,550 0.0091 11,005 147
2019-D Georgia 455,800 0.0087 11,457 150
2020-P Connecticut 436,000 0.0083 11,978 169
2020-D Connecticut 435,325 0.0083 11,996 171
2020-P Massachusetts 436,750 0.0084 11,957 167
2020-D Massachusetts 436,425 0.0084 11,966 168
2020-P Maryland 434,825 0.0083 12,010 172
2020-D Maryland 435,475 0.0083 11,992 170
2020-P South Carolina 432,850 0.0083 12,065 173
2020-D South Carolina 397,775 0.0076 13,129 178
2021-P New Hampshire 453,825 0.0087 11,507 153
2021-D New Hampshire 450,725 0.0086 11,586 162
2021-P Virginia 423,600 0.0081 12,328 174
2021-D Virginia 422,875 0.0081 12,349 175
2021-P New York 451,750 0.0087 11,560 160
2021-D New York 451,175 0.0086 11,575 161
2021-P North Carolina 405,950 0.0078 12,864 177
2021-D North Carolina 389,725 0.0075 13,400 179
2022-P Rhode Island 454,050 0.0087 11,501 152
2022-D Rhode Island 453,775 0.0087 11,508 154
2022-P Vermont 454,275 0.0087 11,496 151
2022-D Vermont 452,775 0.0087 11,534 155
2022-P Kentucky 451,900 0.0087 11,556 159
2022-D Kentucky 452,550 0.0087 11,540 156
2022-P Tennessee 452,325 0.0087 11,545 157
2022-D Tennessee 452,275 0.0087 11,547 158
2023-P Ohio 495,125 0.0095 10,547 143
2023-D Ohio 447,450 0.0086 11,671 163
2023-P Louisiana 444,625 0.0085 11,745 164
2023-D Louisiana 411,950 0.0079 12,677 176
2023-P Indiana 459,775 0.0088 11,358 149
2023-D Indiana 443,650 0.0085 11,771 166
2023-P Mississippi 371,000 0.0071 14,076 180
2023-D Mississippi 352,450 0.0067 14,817 181

sdrRewind and Black Cat ALE

Many DXers record large swaths of the radio spectrum, and then go back to analyze the recordings, looking for signals of interest. Much of the time, they play the recordings back through their SDR software. This works, but is a slow process, no better than monitoring in real time.

Modern software can dramatically speed up the process. In this article, I’ll show how sdrRewind and Black Cat ALE can team up and speed up the process of finding and decoding ALE (Automatic Link Establishment) transmissions.

Black Cat ALE is a full featured multi-channel ALE decoder for Windows and macOS. It decodes ALE transmissions from either audio fed into a sound card input (live decoding) or from WAVE audio files. Download a copy here: https://blackcatsystems.com/software/black_cat_ale_decoder.html

sdrRewind may take a little more explanation. Rather than just play back an SDR recording file, it allows you to select any of your SDR I/Q recording files, and display a waterfall of the entire file at once, as one large waterfall, with a temporal resolution of one second per line. This is more than adequate to see the various transmissions contained in the recording. Select a signal of interest by dragging a rectangle around it with your mouse, and sdrRewind will demodulate and play back the audio, either to your speakers or a virtual audio device feeding a decoder. It can also demodulate to WAVE files, which can then be fed into your decoding software.

It’s also possible to define a set of frequencies and process several SDR I/Q files at once, generating a collection of WAVE files which can then be fed into the decoding software. In the case of Black Cat ALE, it can be configured to monitor a directory looking for new WAVE files, and automatically process them. So even if the demodulation and decoding process will take some time, you can set it up, then walk away and do something more productive while your computer is busy processing the data. Then come back when it is done and view the results.

Download a copy of sdrRewind here: https://www.blackcatsystems.com/software/sdr_iq_recording_playback_program.html

Black Cat ALE Configuration:

Select Set Directory To Monitor For New Files from the File menu, and choose the directory in which sdrRewind will store demodulated WAVE files. (Create one if you need to)

Select Monitor File Directory from the File menu. Black Cat ALE will start looking in this directory for new WAVE files. The name of these files must end in “.wav” or “.WAV”. It will ignore any files that already exist in this directory.

sdrRewind Configuration:

Set the directory for your SDR recording files, using Set Recording Directory in the File menu

Open Settings in the Edit menu, go to the Demod Directories tab, and create one or more entries for where demodulated WAVE files should be stored, including at least the directory Black Cat ALE will be monitoring. Create each entry by right clicking on the list and select Add Entry. Then right click on that entry and select Set Path and select the directory to use. Repeat as necessary. Close Settings. Go to Select Demod File Directory in the File menu and select the directory where Black Cat ALE will be monitoring for new WAVE files.

Select one of your SDR I/Q recording files from the list of files in the list on the left side of the main window. After a moment, a waterfall for the entire file will appear. Adjust the min and max dB sliders as necessary for good contrast.

Set the mode to USB.

Find an ALE signal in the waterfall and drag around it with the mouse cursor (can’t find any? Go to another I/Q file). You’ll want to make sure the lower frequency is an integer kHz value (or 0.5 kHz for those ALE channels), so edit the frequency as needed. Zero Frequency kHz in the Edit menu can quickly do this for you. Don’t forget to make sure the upper frequency is high enough to cover the entire ALE spectrum, about 3 kHz. Click the Timestamped button. sdrRewind will demodulate the signal and write it to the specified directory. When Black Cat ALE sees the file, it will open and decode it, printing out the results.

Sometimes you want to decode ALE signals from one or more specific frequencies, over an entire set of SDR I/Q recording files. sdrRewind can help with this as well.

Select Demodulate Multiple Files from the Edit menu and a new window appears.

On the left hand side is a list of your recording files, as in the main window. Select a file and basic information about that file will be displayed: the center frequency, sample rate, bandwidth, starting date and time, and length in seconds.

Demodulation settings are displayed immediately to the right of this, again as in the main window. Configure this for the frequency of interest, then select one or more I/Q files and click the Start button. Each I/Q file will be demodulated and written to a separate timestamped WAVE audio file. The entire I/Q file will be demodulated, from start to finish.

Do not make any changes to any controls in this window will files are being processed.

If you wish to demodulate several frequencies from each file, instead use the list to the right:

Right click in it and select Add Entry. A new row will be added. Set the low and high frequency limits of the IF passband, as well as (optionally) the pass band tuning (PBT). Change the mode by right clicking on it, and select a different mode from the popup menu. The same AGC settings will be used for all entries.

When you are finished, click the Start All button. Each I/Q file will again be processed, this time for each of the frequencies in the list. Click abort to stop processing additional files, however the file currently being processed will need to finish.

The Clear button can be used to quickly remove all entries from the list.

Winter 2021-2022 Snowfall

High atop Parr’s Ridge in northern Carroll County, MD at about 850 ft elevation.

Monday November 29, 2021
Snow flurries.

Tuesday November 30, 2021
Snow flurries.

November Total: 0.0″

Monday December 27, 2021
1.0″ of snow

December Total: 1.0″

Friday January 7, 2022
6.0″ of snow



Sunday January 16, 2022
3.0″ of snow, then rain.

Monday January 17, 2022
0.5″ of snow

Thursday January 20, 2022
1.0″ of snow after rain

Friday January 28, 2022
About 1.0″, light snow all day.

January Total: 11.5″

Sunday February 13, 2022
5.8″ of snow

Monday February 14, 2022
1.0″ of dry puffy snow

February Total: 6.8″

Saturday March 12, 2022
5.5″ wet snow snow

March Total: 5.5″

Season Total: 24.8″

Shortwave Pirate Radio 2020 – A Year In Review

To gauge shortwave pirate radio activity in 2020, I analyzed the Shortwave Pirate loggings forum of the HF Underground (http://www.hfunderground.com). A computer script parsed the message thread titles, as well as the timestamps of the messages. This information was used to produce some statistics about the level of pirate radio activity. Of course, as Mark Twain has written: “There are three kinds of lies: lies, damned lies, and statistics.” A fourth might be pirate logging message titles. Don’t expect all the numbers to exactly add up. Still, let’s see what we can learn.

There were 15,545 messages posted to 2,400 unique threads, 29% and 10% higher than last year. Shortwave pirate activity is at historically high levels. Back in the 1990s, it was not uncommon for an entire month to go by with only a handful of pirate stations logged. If you want to know when the “golden age” of shortwave pirate radio was, I would say it is right now.

Ideally, each thread represents an individual pirate station transmission. Also ideally, each message posted to a thread represents one logging. In reality, there is some error involved. Let’s dive in.

First, we can look at the transmission mode used:

USB again leads AM, with the other modes rarely used.

Next, we can see how much activity there is for each day of the week:

Weekends (Friday, Saturday, Sunday) are still the most active, but almost a third of broadcasts were on other days of the week.

We can also look at the number of logging threads per month, to gauge activity:

Some seasonal variability, but still very active throughout the entire year.

We might be interested in knowing the best time of the day to try to hear a pirate station. Here’s a plot of the start times of the logged broadcasts, binned
by UTC hour of the day:

Evenings are most active as expected, but still lots of morning and afternoon broadcasts. The wee hours were very quiet, probably due in part to the low solar activity levels.

Here’s a graph showing the number of broadcasts per day of the year that were logged:

Halloween really sticks out this year!

Finally some graphs of the number of logging threads per frequency:

And zoomed in vertically to see the less commonly used frequencies:

The shift to the 4 and 5 MHz bands for many stations is quite evident, driven by the solar minimum conditions making 43 meters useful mostly for just long distance propagation at night. Still, it is the most active pirate band.

If you’re interested in hearing pirates, the best ways to keep up to date on what is being heard is via the HFUnderground.com message board, as well as the real time Rocket Chat. Rather than finding out about a transmission after it is over, you can tune in while it is still on the air. Also visit our Facebook group.

And of course, your loggings and other posts on the HF Underground are most welcome! This is how we find out what stations are being heard.

Shortwave Pirate Radio 2019 – A Year In Review

To gauge shortwave pirate radio activity in 2019, I analyzed the Shortwave Pirate loggings forum of the HF Underground (http://www.hfunderground.com). A computer script parsed the message thread titles, as well as the timestamps of the messages. This information was used to produce some statistics about the level of pirate radio activity. Of course, as Mark Twain has written: “There are three kinds of lies: lies, damned lies, and statistics.” A fourth might be pirate logging message titles. Don’t expect all the numbers to exactly add up. Still, let’s see what we can learn.

There were 12,078 messages posted to 2,186 unique threads. Activity levels are essentially flat, down slightly from 2018, but still at historically high levels. Back in the 1990s, it was not uncommon for an entire month to go by with only a handful of pirate stations logged. If you want to know when the “golden age” of shortwave pirate radio was, I would say it is right now.

Ideally, each thread represents an individual pirate station transmission. Also ideally, each message posted to a thread represents one logging. In reality, there is some error involved. Let’s dive in.

First, we can look at the transmission mode used:

USB beat out AM as the most popular mode, but both account for virtually all transmissions.

Next, we can see how much activity there is for each day of the week:

Weekends (Friday/Saturday/Sunday) are by far the most active, but the rest of the week still accounts for over a third of broadcasts.

We can also look at the number of logging threads per month, to gauge activity:

No summer slump this year, summer was in fact the most active period.

We might be interested in knowing the best time of the day to try to hear a pirate station. Here’s a plot of the start times of the logged broadcasts, binned
by UTC hour of the day:

Most activity is in the evening as expected. But there’s still a fair amount of morning/afternoon activity.

Here’s a graph showing the number of broadcasts per day of the year that were logged:

Finally some graphs of the number of logging threads per frequency:

And zoomed in vertically to see the less commonly used frequencies:

6925 is by far the most active frequency, and 43 meters is busy overall. Old Time Radio on 6770 sticks out. We’re starting to see more activity on the 4 and 5 MHz bands, most likely driven by the low solar activity conditions.

6925 is the place to be, and most activity is on 43 meters, but there’s still a fair bit elsewhere. Old Time Radio on 6770 AM really sticks out.

If you’re interested in hearing pirates, the best ways to keep up to date on what is being heard is via the HFUnderground.com message board, as well as the real time Rocket Chat. Rather than finding out about a transmission after it is over, you can tune in while it is still on the air. Also visit our Facebook group.

And of course, your loggings and other posts on the HF Underground are most welcome! This is how we find out what stations are being heard.

Shortwave Pirate Radio 2018 – A Year In Review

To gauge shortwave pirate radio activity in 2018, I analyzed the Shortwave Pirate loggings forum of the HF Underground (http://www.hfunderground.com). A computer script parsed the message thread titles, as well as the timestamps of the messages. This information was used to produce some statistics about the level of pirate radio activity. Of course, as Mark Twain has written: “There are three kinds of lies: lies, damned lies, and statistics.” A fourth might be pirate logging message titles. Don’t expect all the numbers to exactly add up. Still, let’s see what we can learn.

There were 12,785 messages posted to 2,216 unique threads. Activity levels are essentially flat, down slightly from 2017, but still at historically high levels. Back in the 1990s, it was not uncommon for an entire month to go by with only a handful of pirate stations logged. If you want to know when the “golden age” of shortwave pirate radio was, I would say it is right now.

Ideally, each thread represents an individual pirate station transmission. Also ideally, each message posted to a thread represents one logging. In reality, there is some error involved. Let’s dive in.

First, we can look at the transmission mode used:

AM leads USB, with the other modes much less often used.

Next, we can see how much activity there is for each day of the week:

As expected, weekends are by far the most active, but there’s still pirates to be found during the weekdays.

We can also look at the number of logging threads per month, to gauge activity:

There was a bit of a late summer / fall slump, but a very active holiday season.

We might be interested in knowing the best time of the day to try to hear a pirate station. Here’s a plot of the start times of the logged broadcasts, binned
by UTC hour of the day:

Most activity is in the evening as expected. But there’s still a fair amount of morning/afternoon activity. Not much in the wee overnight hours.

Here’s a graph showing the number of broadcasts per day of the year that were logged:

Finally some graphs of logging threads per frequency:

And zoomed in vertically to see the less commonly used frequencies:

6925 is the place to be, and most activity is on 43 meters, but there’s still a fair bit elsewhere. Old Time Radio on 6770 AM really sticks out.

If you’re interested in hearing pirates, the best ways to keep up to date on what is being heard is via the HFUnderground.com message board, as well as the real time Rocket Chat. Rather than finding out about a transmission after it is over, you can tune in while it is still on the air. Also visit our Facebook group.

And of course, your loggings and other posts on the HF Underground are most welcome! This is how we find out what stations are being heard.

Shortwave Pirate Radio 2017 – A Year In Review

   PSK31     
   iPad app to decode PSK31     

To gauge shortwave pirate radio activity in 2017, I analyzed the Shortwave Pirate loggings forum of the HF Underground (http://www.hfunderground.com). A computer script parsed the message thread titles, as well as the timestamps of the messages. This information was used to produce some statistics about the level of pirate radio activity. Of course, as Mark Twain has written: “There are three kinds of lies: lies, damned lies, and statistics.” A fourth might be pirate logging message titles. Don’t expect all the numbers to exactly add up. Still, let’s see what we can learn.

There were 13,903 messages posted to 2,550 unique threads. Activity levels are essentially flat, but still at historically high levels. Back in the 1990s, it was not uncommon for an entire month to go by with only a handful of pirate stations logged. If you want to know when the “golden age” of shortwave pirate radio was, I would say it is right now.

Ideally, each thread represents an individual pirate station transmission. Also ideally, each message posted to a thread represents one logging. In reality, there is some error involved. Let’s dive in.

First, we can look at the transmission mode used:

AM and USB are tied for first place, with everything else essentially noise.

Next, we can see how much activity there is for each day of the week:

As one might expect, Saturday and Sunday are the big winners, with Friday in third place. But don’t give up on weekday listening! About a third of all transmissions are on a Monday through Thursday.

We can also look at the number of logging threads per month, to gauge activity:

Not much of a summer slump as in past years, activity is relatively constant throughout the year.

We might be interested in knowing the best time of the day to try to hear a pirate station. Here’s a plot of the start times of the logged broadcasts, binned
by UTC hour of the day:

Peak activity in the evening hours is clearly evident, but there is still a good amount of morning and afternoon activity, and low amounts at random overnight hours.

Here’s a graph showing the number of broadcasts per day of the year that were logged:


Looks like the peak was Labor Day weekend?

Finally some graphs of logging threads per frequency:

And zoomed in vertically to see the less commonly used frequencies:

6925 is still the big winner, and 43 meters overall is where most activity resides, but there’s still lots of pirates to be found elsewhere.

If you’re interested in hearing pirates, the best ways to keep up to date on what is being heard is via the HFUnderground.com message board, as well as the real time Rocket Chat. Rather than finding out about a transmission after it is over, you can tune in while it is still on the air. Also visit our Facebook group.

And of course, your loggings and other posts on the HF Underground are most welcome! This is how we find out what stations are being heard.

Winter 2020-2021 Snowfall

High atop Parr’s Ridge in northern Carroll County, MD at about 800 ft elevation.

October Total: 0.0″

Monday November 2, 2020
Snow flurries.

November Total: 0.0″

Tuesday December 1, 2020
Snow flurries.

Wednesday December 9, 2020
Snow flurries.

Monday December 14, 2020
Rain to snow, 1.0″ accumulation.

Wednesday December 16, 2020
Snow then sleet, measured 8.0″ accumulation the next morning.

Friday December 18, 2020
0.3″ dusting of snow.

Friday December 25, 2020
1.57″ of rain and then snow flurries, no accumulation.

December Total: 9.3″

Tuesday January 26, 2021
0.5″ of snow.

January Total: 0.5″

Sunday January 31, 2021 – Tuesday February 2, 2021
10.0″ of snow.

Wednesday February 3, 2021
0.25″ of snow.

Friday February 5, 2021
0.25″ of snow.

Sunday February 7, 2021
3.0″ of snow.

Thursday February 11, 2021
3.0″ of snow.

Thursday February 18, 2021
4.5″ of snow.

Friday February 19, 2021
0.5″ of snow.

Monday February 22, 2021
4.0″ of snow.

Saturday February 27, 2021
0.7″ of snow.

February Total: 26.2″

Tuesday March 16, 2021
Sleet in the morning, no accumulation.

March Total: 0″

Thursday April 1, 2021
0.1″ of graupel.

Friday April 2, 2021
0.1″ of snow.

Thursday April 22, 2021
Snow flurries.

April Total: 0.2″

Season Total: 36.2″

Z80 Emulation on an Arduino, Part 2 – Running MSBASIC

The goal of this project was to get MSBASIC running in an emulated Z80 processor on an Arduino, with no external hardware/components required. Here’s what it looks like when running:

I went with the Arduino Due as it has 96K of RAM, more than enough for a Z80, as well as 512K flash, and a 32-bit ARM core microcontroller running at 84 MHz. Note that the Due uses 3.3V I/O, not 5V as many of the older Arduino boards. Although this will actually be useful for me down the road…

The Due has four serial ports, including two available on USB connectors, the programming port and the native port. I’m using the native port as the terminal interface for the emulated Z80.

For the Z80 emulation I went with z80emu

For MSBASIC itself I went to Grant Searle’s fabulous site, Grant’s 7-chip Z80 computer in particular, and grabbed his ROM files and assembly files.

There’s source code for both a simple monitor that live at 0000H as well as MSBASIC itself which starts at 0150H:
intmini.asm
basic.asm

Also included are the Intel Hex files for both as well as a combined ROM file:
BASIC.HEX
INTMINI.HEX
ROM.HEX

I decided to use the source files and assemble them myself with the asmx multi-CPU assembler, that way I could make changes if I needed to.

I then wrote my own simple little program to take the resulting object code (.bin file) and convert it into Arduino source code that defined a 8K array of PROGMEM prog_uint8_t bytes, which looks like:

const static prog_uint8_t rom_bytes[] PROGMEM = {
0xF3,0xC3,0xB8,0x00,0xFF,0xFF,0xFF,0xFF,0xC3,0x9F,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,
0xC3,0x74,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xC3,0xAA,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x18,0x00,0xF5,0xE5,0xDB,0x80,0xE6,0x01,
0x28,0x2D,0xDB,0x81,0xF5,0x3A,0x43,0x20,0xFE,0x3F,0x20,0x03,0xF1,0x18,0x20,0x2A,
....
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};

This was then added to my Arduino project as another file, rom.h. When the emulator starts up, it’s copied to the memory array used by the emulator for memory access in the 8K 0000-01FF range where the ROM lives. I have another 64K memory array for RAM, right now the lower 8K is never access, but eventually I’ll add the ability for the Z80 to swap out the ROM and swap it in, for a full 64K of RAM (via an IO port access), once I get CP/M running, which is another project.

I have some benchmarking code that estimates the effective CPU speed. It adds some overhead, but even with that I get about 7.4 MHz, which is actually pretty close to ideal for a “real” Z80.

Now my code:

The Z80 sketch itself, which gets everything going:


extern "C"{
#include "MyZ80Emulation.h"
};

#include "rom.h"

#include

void setup() {
Serial.begin(9600);

Serial.println("Serial Open");

SerialUSB.begin(9600);
SerialUSB.println("Terminal Open");

pinMode(LED_BUILTIN, OUTPUT);

int i;

Serial.println("Copy ROM");
for (i=0; i<8192; i++) InitEmulationRom(i,pgm_read_byte_near(rom_bytes+i) ); Serial.println("InitEmulation"); InitEmulation(); } void loop() { digitalWrite(LED_BUILTIN, HIGH); EmulateInstructions(); digitalWrite(LED_BUILTIN, LOW); while (SerialUSB.available()>0)
{
int ch;
ch=SerialUSB.read();
if (ch==127) ch=8; // handle delete key
AddToInputBuf(ch);
}

InterruptZ80IfNeeded();
}

void my_putchar(int c)
{
SerialUSB.write(c);
}

MyZ80Emulation.c which interfaces with the actual emulation code:

//
// MyZ80Emulation.c
//
//

#include "MyZ80Emulation.h"

#include
#include
#include "zextest.h"

#define Z80_CPU_SPEED 4000000 // In Hz.
#define CYCLES_PER_STEP (Z80_CPU_SPEED / 40) // let's do 100k cycles
#define MAXIMUM_STRING_LENGTH 100

ZEXTEST context;

void InitEmulationRom(int address, int data)
{
context.rom[address] = data;
}

void InitEmulation(void)
{
context.is_done = 0;
Z80Reset(&context.state);
context.state.pc = 0x0;
}

void EmulateInstructions(void)
{
double totalCycles, totalTime, khz;
unsigned long time1,time2;

time1=micros();
totalCycles += Z80Emulate(&context.state, CYCLES_PER_STEP, &context);
time2=micros();

return; // uncomment if we want to time the system

if (time2>time1) // ignore case where the microseconds timer wrapped around
{
totalTime=time2-time1;
if (totalTime>0) khz = 1000.0 * totalCycles / totalTime; else khz=0;
printf("totalCycles: %6d totalTime: %6d %6d kHz \n",(int)totalCycles,(int)totalTime,(int)khz);
}

}

// Handle user terminal input, characters stored in a circular buffer

inputBuf[256];
inputBufInPtr=0;
inputBufOutPtr=0;

void AddToInputBuf(int c)
{
inputBuf[inputBufInPtr]=c;
inputBufInPtr++;
}

void InterruptZ80IfNeeded(void)
{
if (inputBufInPtr==inputBufOutPtr) return; //only interrupt if there is a received character in the ACIA
int cycles;
cycles=Z80Interrupt (&context.state, 0x38, &context); // interrupt Z80
}

// Emulate 8650 ACIA, port input
int SystemCallPortIn(ZEXTEST *context, int port)
{
int inputReady=0;

if (inputBufInPtr != inputBufOutPtr) inputReady=1;

if (port==0x80) return (0x02+inputReady); // ACIA status register, always ready to transmit, inputReady decdes if we have an input character

if (port==0x81)
{
if (!inputReady) return (inputBuf[inputBufOutPtr]); // no new data, send last character anyway
char c;
c=inputBuf[inputBufOutPtr];
inputBufOutPtr++;
return c;
}

printf("SystemCallPortIn %04x\n", port); // if not handled above, display this diagnostic message

return 0;
}

// Emulate 8650 ACIA, port output
void SystemCallPortOut(ZEXTEST *context, int port, int x)
{
if (port==0x81) // UART write a byte
{
my_putchar(x);
return;
}

if (port==0x80) // ACIA write control register, we never need to handle this
{
return;
}

printf("SystemCallPortOut %04x %02x\n", port, x); // if not handled above, display this diagnostic message

}

\

MyZ80Emulation.h the header for the above:

//
// MyZ80Emulation.h
//
//

#ifndef MyZ80Emulation_h
#define MyZ80Emulation_h

#include

void SetFuncton(int (*f)(void));

void InitEmulationRom(int address, int data);
void InitEmulation(void);
void EmulateInstructions(void);
void my_putchar(int c);
void AddToInputBuf(int c);
void InterruptZ80IfNeeded(void);

#endif /* MyZ80Emulation_h */

Generating VGA video with Verilog

I’ve started work on an FPGA based Z80 computer. I wanted to generate the video in the FPGA as well, turns out VGA is fairly easy to generate. There’s numerous websites that describe the timing and parameters of the various VGA modes, and how VGA works.

This project is also my Verilog learning experience, so pardon any horrible code.

In a nutshell, for basic VGA you need a total of 5 digital output lines. One for horizontal sync, one for vertical, and one each for the red, green, and blue video signals. The RGB signals are actually analog, but for my purposes implemented as digital, either on or off. That allows a total of eight colors, including white and black. For now the text is only color. To produce additional colors, the RGB lines can be driven with a D/A converter, which could be as simple as a resistor ladder circuit.

These analog voltages need to be limited to under 1 volt. The FPGA I/O outputs are 3.3 volts so a simple resistor and diode circuit was used for each line. Here’s the circuit, as you can see it is quite simple. Virtually any reasonably fast diode can be used:

I decided to use the standard 640 x 480 60 Hz mode, as it would be more than adequate for my goal of displaying 25 lines of 80 characters.

Each character is displayed as a 8 by 16 pixel matrix, resulting in 640 x 400 pixels, the rest of the screen is not used.

The design was implemented on a RioRand EP2C5T144 Altera Cyclone II FPGA Mini Development Board available at Amazon for $19.99. What a deal.

I used the free version of Altera’s Quartus II software package.

Video memory is a 2K byte dual ported RAM, organized in a linear fashion, using 2000 bytes.

The character generator ROM is a 1K ROM, storing 8 rows of 8 pixels for each of the 128 ASCII characters. Each row is displayed twice, for a total of 16 rows. As of now the high bit of the stored ASCII value in video memory is not used, I plan on eventually using it to implement a low-res color graphics mode, a la the Apple ][.

The RioRand-EP2C5T144 FPGA dev board has a 50 MHz oscillator signal as a clock input. I implemented a 4x PLL to produce an internal 200 MHz clock. While the 50 MHz clock is adequate for 640×480 video, the faster clock will allow higher resolution video modes down the road.

A state machine is used to generate the video. A frame of video actually has 525 scan lines, it starts with 10 “front porch” lines (essentially all black video lines), then 2 lines of vertical sync, followed by 33 more “back porch” lines.
Front porch and back porch are old terms from the original NTSC analog TV system developed in the 1940s. You’ll see that totals 45 lines, leaving 480 lines of actual video.

Each video line has 800 pixels (as far as timing is concerned). There’s a front porch of 16 pixels, 96 pixels of horizontal sync, 48 pixels of a back porch, then 640 pixels of actual video content. At a 200 MHz clock, each pixel is 8 clock cycles.

Prior to the display of a pixel, the video RAM is read. The lower 7 bits of the byte, which is the ASCII value of the character to be displayed, is used along with 3 bits of the video line, to form a 10 bit address into the character generator.

Since each line of a character is displayed twice, bits [3:1[ and not [2:0] of the video line are used. If I was willing to dedicate 2K to the character ROM, I could display 16 rows of pixels for each character.

The resulting VGA video, the video RAM was pre-loaded with data using the Altera MegaWizard option to do so from an Intel Hex file.

Verilog Code:


module vga1
	(
	clock_in,
	
	red,
	green,
	blue,
	hsync,
	vsync
	);


// these are placeholders for when we hook up a CPU later
reg [15:0] addressWriteVideoRam=16'b0;
reg [7:0] dataInWriteVideoRam;
wire [7:0] dataOutReadVideoRam;
reg writeEnableWriteVideoRam=1'b0;
reg writeVideoRamClock;


// VGA video generator, undocumented for now. Good luck. 
	
input clock_in; // 50 MHz input clock

// RGB outputs
output reg red;
output reg green;
output reg blue;

// horizontal and vertical sync outputs
output reg hsync;
output reg vsync;

wire pllClock;
pll my_pll (clock_in, pllClock); // 200 MHz clock from the 50 MHz board clock


reg	[9:0]  char_rom_address;
wire	[7:0]  char_rom_output;
reg char_rom_clock;
reg [7:0] char_rom_data_byte;

reg pixel;
reg [15:0] clockCounter; // 200 MHz clock
reg [15:0] pixelCounter; // 25 MHz pixel clock
	
reg video_inclock;	// video RAM clock
reg video_wren; // not used yet
reg [7:0] video_data; // not used yet

// 1K x 8 bit video character ROM, 8 lines of 8 pixels for 128 characters, high ASCII bit not used
char_rom my_char_rom(char_rom_address, char_rom_clock, char_rom_output);

// 2K video dual port RAM for 25 lines of 80 characters	
video_ram_dp the_video_ram(.address_a (video_display_address[10:0]), .data_a(video_data), .clock_a(video_inclock), .wren_a(video_wren), .q_a(video_data_byte) ,
	.address_b(addressWriteVideoRam[10:0]), .data_b(dataInWriteVideoRam), .clock_b(writeVideoRamClock), .wren_b(writeEnableWriteVideoRam), .q_b(dataOutReadVideoRam)  );

	
reg [15:0] video_display_address;
wire [7:0] video_data_byte;

reg [15:0] horzCounter=16'd0;
reg [15:0] lineCounter=16'd0;


// VGA640x480x60_200mhz clock
parameter pixel_rate=8;
parameter horz_front_porch=16*pixel_rate;  
parameter horz_sync=96*pixel_rate;  		
parameter horz_back_porch=48*pixel_rate;
parameter horz_line=800*pixel_rate;
parameter vert_front_porch=10;
parameter vert_sync=2;
parameter vert_back_porch=33;
parameter vert_frame=525;
parameter horz_sync_polarity = 1'b0;
parameter vert_sync_polarity = 1'b0;
parameter first_video_line=49; // first line of video
parameter number_of_video_lines=400; // 25 ASCII lines of 16 pixels each is 400 video lines



always @(negedge pllClock)
	begin
	char_rom_clock<=horzCounter[0];
			
end
	
always @(posedge pllClock)
	begin

	clockCounter<=clockCounter+1'b1;
	if (clockCounter[2:0]==7) pixelCounter<=pixelCounter+1'b1;

	if (pixelCounter[2:0]==7) begin
		case (clockCounter[2:0])
//		0 : not used
//		1 : not used
		3 : char_rom_address<={video_data_byte[6:0],lineCounter[3:1]}; // high 7 bits of charactor ROM address is the ASCII character, low 3 bits video line counter, we display each line twice
		4 : char_rom_data_byte<=char_rom_output; // latch the character ROM data
//		5 : not used
		6 : video_inclock<=0;	// clock video for next ASCII character
		7 : video_inclock<=1;
		endcase
	end
	
	if (horzCounter==0)	begin  // set video to black
		red<=1'b0;
		green<=1'b0;
		blue<=1'b0;
		clockCounter<=0;
		
		end
		
	if (horzCounter==horz_front_porch)	hsync<=horz_sync_polarity;
	if (horzCounter==(horz_front_porch+horz_sync))	hsync<=!horz_sync_polarity;

	if ( (lineCounter>=(vert_front_porch+vert_sync+vert_back_porch+first_video_line)) && (lineCounter<=(vert_front_porch+vert_sync+vert_back_porch+first_video_line+number_of_video_lines)) )  begin // video frame time

		if ((pixelCounter[2:0]==6) && (clockCounter[2:0]==7)) video_display_address<=video_display_address+1'b1;


		if (horzCounter==(horz_front_porch+horz_sync+horz_back_porch))	begin
			pixelCounter<=0; // start of video line
			end
			
		if (horzCounter>=(horz_front_porch+horz_sync+horz_back_porch))	begin // video line
			
			case (pixelCounter[2:0])
			0 : pixel=char_rom_data_byte[0];
			1 : pixel=char_rom_data_byte[1];
			2 : pixel=char_rom_data_byte[2];
			3 : pixel=char_rom_data_byte[3];
			4 : pixel=char_rom_data_byte[4];
			5 : pixel=char_rom_data_byte[5];
			6 : pixel=char_rom_data_byte[6];
			7 : pixel=char_rom_data_byte[7];
			endcase
			
			// set RGB outputs
			red<=pixel;
			green<=pixel;
			blue<=pixel;
			
			end  // video line time
			
	end // video frame time

	horzCounter <= horzCounter + 16'd1;
	if (horzCounter==horz_line) begin // end of scan line, set video to black
		red<=1'b0;
		green<=1'b0;
		blue<=1'b0;

		horzCounter<=0;
		lineCounter<=lineCounter+1'b1;
		
		if (lineCounter>=(vert_front_porch+vert_sync+vert_back_porch)) begin // video frame time
			if (lineCounter[3:0]!=4'd15) video_display_address<=video_display_address-8'd100; else video_display_address<=video_display_address-8'd20;  // 80 chars back to beginning of line
		end
		
		if (lineCounter==vert_front_porch) vsync<=vert_sync_polarity;
		if (lineCounter==(vert_front_porch+vert_sync)) vsync<=!vert_sync_polarity;
		
		if (lineCounter==vert_frame) begin	// end of the video frame, start over
			video_display_address<=466;		// offset so we start reading video data at the correct address
			lineCounter<=0;
			
			end
			
		end
	
	
	end

	
	
	
endmodule