The Boston Diaries

The ongoing saga of a programmer who doesn't live in Boston, nor does he even like Boston, but yet named his weblog/journal “The Boston Diaries.”

Go figure.

Friday, October 13, 2000

learned I work first shift next week. uh.


learned from Kim I have a rep as hating Windows at The Company. Funny thing is, I haven't, to my recollection, said or done anything that would warrent this.

My reputation preceeds me, and is larger than life

Saturday, October 13, 2001

Afghanistan—it's a dangerous place

Gone were the network war hogs who hiked in from Peshawar and wrote stirring tales of muj bravery. Now sleek white UN turboprops off-loaded female journalists in waiting chauffeur-driven black Mercedes. Over lunch and dinner at the UN mansion (with exercise room, satellite television and bar) they chronicled the horrors of the lack of health care, the treatment of women and generally how life sucked and apparently just for women. There was even a standard journo junket. The first stop was to see Mullah Qalaamuddin, the deputy head of the Religious Police (the Department for the Promotion of Virtue and the Prevention of Vice), where every writer was assured to get a few giggles from the latest fatwah: no paper bags, no white socks, four fingers of beard and no picture-taking. Then off to a barber for a little humor, a clandestine visit to a girl's school, pack a lunch for the Friday executions and then back to Peshawar to file. The object of their journalist lust? The dreaded burqa, a garment worn by every women outside of cosmopolitan Kabul for centuries but suddenly held up as being a sign of the devil in Kabul. Not many paid attention when Hekmatyar made it mandatory long before the Talibs showed up. The writers never really mentioned that they were in the most destroyed city on earth, a militarily occupied zone with a war raging 15 kilometers to the north, rockets raining into the city and young men are pressganged. Somehow in their zeal to create women's rights in a country staggering to its knees, they forget to mention the complete lack of jobs, housing, medical care, health services and education for men (who must provide for their women and children) let alone women. The articles inflamed the world and shut down any aid to the wartorn region. How did the Taliban get lynched on women's rights? It's akin to taking the KKK to task for not providing minority scholarships.

Afghanistan-DangerFinder

This is a fun site. The commentary is colorful yet very informative, using humor to get the point across—this (and every other country profiled on the site) is a very dangerous place to be, and why the place is dangerous.

They even give background information on the Players in the area, like this on the Osama bin Laden:

So let's just say Binny is the bearded Ross Perot of the Middle East. Technically Binny Bang Bang (he keeps going an going and going and going …) can now join Castro and Qaddafi for drinks at the Bad Boy's Club, unless the United States keeps turning off his cash flow. A man with 40 brothers, 13 sisters and wealthy patrons can probably play hide the pickle longer than the State Department can. For now bin Laden is a right-wing billionaire (or millionaire or even destitute, depending who you talk to) who combines industrial activity with political activism.

Afghanistan-Osama bin Laden

Or even this on the Taliban:

The black-turbaned Taliban are a PR agent's worst nightmare. A visual mix of Darth Vader gansta rappers and rejects from a Bible play, they come to press conferences with Noriega-style Ray Bans, scruffy beards, long black robes, armed bodyguards and an attitude that makes Louis Farrakhan seem like Mr. Rogers. The Taliban are not bad guys, they're just a little rough around the edges and they don't get out much. Maybe a guest shot on Oprah with a sensitivity coach would help them "address their issues." Their leaders are primarily 40-something muj selected from the Durrani tribes from the backwater southern provinces of Helmand and Uruzgan. They are a simple, pure people led by very religious but culturally isolated mullahs who want outsiders out of Afghanistan and to establish a pure Islamic state. They are simply mad as hell at foreign intervention and ain't gonna take it any more. The funny thing is their northern enemy says they are just the latest Pakistani-backed stooges in this too-long-running war movie/soap opera.

Afghanistan-The Taliban

You should probably just go read the site before I quote it in its entirety here.


How to even describe this thought

I just had a weird thought.

Native Americans, those that where here before the European invasion of 1492 and covering those of both North and South America, are genetically incapable of growing facial hair.

The Taliban made it a crime to have a beard less than four finger widths in length, and if it isn't long enough, you spend time in jail until you have one long enough.

So, does that mean that a Native American, assuming one would want to, can't belong to the Taliban? He probably can't become an Orthodox Jew or even become an Amish Mennonite.

“Although,” said Spring when I told her this, “the Amish might be more forgiving and let one become a member.”

“But in the Amish community, when a man becomes married, he has to let his beard grow,” I said.

“Okay, then maybe a Native American who becomes Amish can't get married,” she said.

Like I said, it was a wierd thought.

Sunday, October 13, 2002

The Usual Suspects

[The Usual Suspects]

The usual suspects grilling the usual hamburgers at an undisclosed location in South Florida. Approach with caution as authorities state they are technically proficient and will install free Unix-like operating systems on unattended PCs.

Monday, October 13, 2003

Oh … it's THAT day …

I went to call Larry , my car insurance salesman (and friend from high school) today and ran into that particular Hell known as “Voice Mail Tag” where you get bumped from voice mailbox to voice mailbox as no one picks up the phone. Odd and annoying at the same time. Odd, because I wouldn't think everybody would be on the phone at once. Annoying should be self evident.

I decided to try back later and went to check up on my friends at LiveJournal when I stumble across the reason: Columbus Day!

Yea! Columbus Day!

Yea! For not remembering a two-bit holiday!

Wednesday, October 13, 2004

The Quick-n-Dirty Ad-Hoc Location Targetting System, on the cheap

I dropped support for Soundex in the project I'm working on. In going over the diagnostic output when importing the data, I found that Soundex had over 6,000 collisions, while Metaphone had less than a 1,000, and shorter collion chains (i.e. most Metaphone collisions have only two possibilities). It just wasn't worth the disk space to use Soundex at that point.

Then it was on to work doing a mock up on the web. The logic is pretty much:

if city exists in latlong.database
then
  fetch data from latlong.database using city
  print data
  exit
end

tag = metaphone(city)
if tag exists in metaphone.database
then
  fetch cities from metaphone.database using tag
  if count(cities) is 1
  then
    fetch data from latlong.database using cities
    print data
  else
    print "select one from the list:"
    for each city in cities
      print city
    end
  end
end
exit

The mockup is quite plain in appearance, but that can be easily changed as most of the output is template based anyway. And it only works for the United States.

Next up, code in time zone and Day Light Savings Daylight Saving Time information for each city.

Friday, October 13, 2006

Me? I'm not superstitious …

Despite two near traffic accidents on the way to work, this hasn't been a bad Friday the 13th. It's been a quiet day at The Office and I spent time moving the corporate blog to a new server and domain name. About the only bad thing I could report happened to be Smirk and I having a difference of opinion on what an “enterprise system” is.

So, I'm happy to report that noth—…øääää…

Saturday, October 13, 2007

Heisenbugs III

Wow … ten days.

Of course, the greylist daemon only took about two hours to hang on the right set of physical servers.

So I have a very subtle bug in the code.

XXXX.


The Right To Arm Bears

We had finally arrived at the South Florida Fair Grounds. I found it amusing that the South Florida fair grounds are about as far north as you can get in South Florida and still be within the geographical region known as South Florida (which technically speaking, lies between the Jupiter Inlet to the north and Homestead along the southern border, the Atlantic Ocean along the eastern edge, and US-27, beyond which is swamp land).

“You'd think they would have put the Fair Grounds somewhere more central, like central Broward County,” I said to my compatriots as we headed from the parking lots to the gates.

“It could be worse,” said Bunny, using a phrase I commonly use right back at me. “You do know that the University of South Florida isn't even in South Florida?”

“Nice sense of irony,” I said.

As we passed beneath a sign that said “Thank you. Hope you had a blast” I had an epiphanous thought—I probably picked the wrong color shirt to wear today—red. But, I thought, at least the blood won't show.

And with that, we entered the South Florida Fair Grounds towards the Gun and Knife Show.

[The right to arm bears]

Guns everywhere. Glocks. Smith-Wesson. Mossbergs. Colts. Everthing from .22 to 50-calibre, and then some. The Younger was eyeing an anti-aircraft rocket launcher when Spring asked who could possibly use such a device. Someone nearby said it could be useful if you live next to an airport. The Younger turned and looked expectantly at his Mom.

“No,” said Spring. “Let's continue on.”

At the point the group broke. Spring went off chasing the Younger as he flitted from table to table. Scott stayed to talk to a merchant behind the table, asking about the finer points of Colt 45s with an extended barrel. Wlofie headed off to a booth selling survival gear, and Bunny went off on a mission—to find a collection of throwing stars, muttering something about Racoon Ninjas terrorizing her neighborhood and teaching them a lesson.

I myself wandered off, amazed at the variety of guns available. And frankly, I found most of them to look fake—more like plastic toys. And to my surprise, most of them were plastic! At least the pistol grips. The cognitive dissonance was too great—the guns in TV and movies looked more “real” than these very real guns in front of me. But pick one up, and the cognitive dissonance grew—these guns where heavy.

“Looking for anything in particular?” asked a gentleman behind the table.

I looked up to see him wobbling around on a Segway. “Um,” I said, more cognitive dissonance building up, “I'm just looking.”

“Okay,” he said. “But if you need any help, just ask.” And he wheeled down the booth to pass a fellow co-worker also on a Segway. I've been to plenty of computer related shows and never saw a Segway, much less two—no, make that three Segways.

Amazing.

I wandered off to parts elsewhere.


Books on modifying the firing mechanism on an AK-47 I expected. Books on martial arts I also expected. I could even see the rationale for conspiracy books ranging from the Illuminati, the Freemasons, JKF to 9/11.

I was not expecting New Age books on Atlantis, aliens and homeopathy.

But even that wasn't as out of place as books by Noam Chomsky.

Noam Chomsky.

Available at a Gun and Knife Show.

Hey, if a Russian can sell crystals at a Gun and Knife Show, why not Noam Chomsky at a book booth?

Cognitive dissonance.


A few hours later we all meet back outside. Bunny had been unable to locate sufficiently sharp throwing stars to tackle the Racoon Ninjas terrorizing her neighborhood. The Younger had procurred a gas mask for those times when it's his turn to change the litter box. Scott informed us that while he could tell us what he got, he would have to kill us afterwards. Wlofie had a big grin on his face, but declined to tell us what that was all about.

And myself? I had successfully survived the Gun and Knife Show in a red shirt.

Tuesday, October 13, 2009

Going to the moon

“I hear you banging away at the keyboard,” said Bunny. “Will R like what you're working on?”

“Oh, I'm sure he'd like what I'm working on,” I said, “but whether he would pay me is another matter … ”

That was when I got The Look.

So, if I'm going to be banging away at the keyboard, might as well get a post out …

Over the past month, when I haven't been disinfecting websites and telling the people over at WC that no, their network is fine but we'll reinstall all the DNS servers anyway for Smirk and cramming in the hour here or there converting PHP from an undocumented hugely overwrought PHP framework to a documented and slightly overwrought PHP framework I've been playing around with Lua.

No, really!

I've been having a blast programming in a prototyped-based, dynamic, partially functional scripting language for the past month. I haven't had this much fun with a language since learning 68000 Assembly Language.

Yes, I know, I hate such languages, but over the past month, I've given it much thought as to why I like love Lua and hate the rest of the crowd.

Unlike Perl, which was designed by an insane linguist with a pediliction for punctuation who felt that a language of nothing but exceptions (much like spelling in the English language) would be fun, Lua is a simple language (heck, it's positively tiny—only 21 reserved words) that is very regular, with just a sprinkling of syntactic sugar to make it nice. Oh, and no sigils required on variables.

PHP is designed by rabid wombats—enough said.

Lua feels more like Python or JavaScript, only without the syntactic significance of whitespace and a consistant syntax for defining functions, both regular and anonymous, unlike Python, and has a much smaller code base than JavaScript, probably making it easier to embed.

And unlike Ruby, it's fast. I've found Lua to be faster than any of the other scripting languages I've mentioned so far.

It really comes down to a small, consistent scripting language that is easy to extend with C (or embed into a C/C++ application). And when I say small, I mean small. Twenty-one reserved words, twenty-six operators (like “(”, “)” or “‥”) and only 118 functions in the standard library, unlike the hundreds or thousands you'll find in the other languages.

Some people might not like the “batteries not included” feature of Lua, but since it's intended to be an embedded scripting language, that isn't much of a liability. You get a scripting language that allows you to declare variables, functions (both named and anonymous), closures, coroutines (or threads, if you want to think of them that way) and flow control. And I've been amazed at the extensions available for Lua.

So expect a deluge of Lua-related posts as I finally document what I've been doing for fun for the past month.

Sigh ‥ back to R's project and mucking with PHP …

Wednesday, October 13, 2010

Feeding your inner carnivore

All I can say is … expense accounts rock!

A few members of upper management from The Main Office of The Corporation arrived at The Ft. Lauderdale Office of The Corporation to check things out. And because they're upper managment, they pretty much get to expense anything they want, so they took the Ft. Lauderdale Office (meaning: us) out to dinner to a Brazillian steakhouse called Chima.

There is no menu. Instead, you just flip a small disk to the side indicating you want food; then you are inundated with men carrying large hunks of roast beast offering you slices of various cuts of beef, pork or lamb. It's a never ending river of meat; vegetarians need not apply. To stem the rising tide, just flip the disk over to the other side. You can keep doing this as long as you want. As much as you want.

It's insane.

And insanely good.

It also appears to be one of those “if you have to ask, you can't afford it” type places.

Tuesday, October 13, 2015

The calm before the storm

Woot! The 16 gigabytes of memory arrived! It's been installed and it's working beautifully. I'm currently backing up the Mac mini and when I work up enough courage, I'll do an incremental backup in the hopes that it takes longer than my courage holds up, then wait a bit more and eventually, the incremental backup will be over so quickly I'll have nothing left to do but update to El Presidente de Por Vida.

Wish me luck.


An appropriately Halloweenish thing to do

This is wonderful! This is a great idea for a drone!

Saturday, October 13, 2018

There and back again

Friday was an absolutely beautiful day to drive—clear blue skies as far as the eye could see. Bunny and I checked out of the hotel at 11:00 AM and started the drive to WNC Farmers Market to pick up some fresh produce before driving home. The WNC Farmers Market is right off I-26 so it wasn't like we were going that far out of our way.

Only the traffic to the WNC Farmers Market was slow. Man, it took us much longer to get there than expected, and then we had to muck about with finding an ATM because some of the farmers at the WNC Farmers Market don't accept plastic. So there was some time lost there. Soon after that, we started the drive home.

The first 19 miles took us well over an hour to drive. For some reason we never were keen to, half of I-26 Eastbound was blocked off between Asheville and Hendersonville. It was a portent of things to come.

Our fantastic time of 11½ hours to Brevard was countered by our worst time of 13½ hours from Brevard. Traffic along I-26 was horrendous as much as the weather was wonderful. But we made it back and now we recuperate from our vacation.


Extreme general interest reading, Brevard edition

The photos I present of Brevard are the ones I tend to find whimsical or surreal, and when not repeating myself, I hope I have done a good job. It's not everyday that one comes across a bear wearing a hat:

[Remember, only you can prevent forest rangers.  Only you.]

I decided against posting that one because, let's be frank, when you come across a bear wearing a wig and a dress, a hat-wearing bear just doesn't cut it anymore, you know?

But during this trip, I took a photo that was so out there, that I hesitated to post it. Mind you, I don't go that much out of my way when I take these pictures—I see these weird and (usually) wonderful things as I'm out and about and take a picture.

It's with this in mind that I found myself in a grocery store in Brevard. I'm not going to name names but be aware that there are at least three different grocery store companies operating in Brevard. So I'm in this grocery store when I come across … well … this:

[Seriously, this blew my mind.  Um ... pun unintended.]

If you click on the picture, you'll see what this grocery store thinks passes for “General Interest” magazine reading in this part of the country. Had this section been labeled “Hunting” I would have just walked on by without a second thought.

But “General Interest?”

This may be the most surreal picture I took on any trip to Brevard, cross-dressing bear included (even if it's a female bear, I would still consider it “cross-dressing” as it's wearing clothing not native to its species). In fact, I find the cross-dressing bear less disturbing because at least it was an intentional Hallowe'en display. The “General Interest” reading rack? If that's intentional, I'm not sure what it says about the grocery store or the area. And if it's unintentional … I … I'm still not sure what that says about the grocery store or the area.

Sunday, October 13, 2019

How many redirects does your browser follow?

An observation on the Gemini mailing list led me down a very small rabbit hole. I recalled at one time that a web browser was only supposed to follow five consecutive redirects, and sure enough, in RFC-2068:

10.3 Redirection 3xx

This class of status code indicates that further action needs to be taken by the user agent in order to fulfill the request. The action required MAY be carried out by the user agent without interaction with the user if and only if the method used in the second request is GET or HEAD. A user agent SHOULD NOT automatically redirect a request more than 5 times, since such redirections usually indicate an infinite loop.

Hypertext Transfer Protocol -- HTTP/1.1

But that's an old standard from 1997. In fact, the next revision, RFC-2616, updated this section:

10.3 Redirection 3xx

This class of status code indicates that further action needs to be taken by the user agent in order to fulfill the request. The action required MAY be carried out by the user agent without interaction with the user if and only if the method used in the second request is GET or HEAD. A client SHOULD detect infinite redirection loops, since such loops generate network traffic for each redirection.

Note: previous versions of this specification recommended a maximum of five redirections. Content developers should be aware that there might be clients that implement such a fixed limitation.

Hypertext Transfer Protocol -- HTTP/1.1

And subsequent updates have kept that language. So it appears that clients SHOULD NOT (using language from RFC-2119) limit itself to just five times, but still SHOULD detect loops. It seems like this was changed due to market pressure from various companies and I think the practical limit has gone up over the years.

I know the browser I use, Firefox, is highly configurable and decided to see if its configuration included a way to limit redirections. And lo', it does! The option network.http.redirection- limit exists, and the current default value is “20”. I'm curious to see what happens if I set that to “5”. I wonder how many sites will break?

Tuesday, October 13, 2020

I wonder what the difference between Boomer Darkwave and Gothic Bubblegum pop really is?

Two weeks ago I mixed up a music group name with its album name. The only text on the front of the CD is “GREATER CALIFORNIA” with nary a mention of the group name. Along the spine is “GREATER CALIFORNIA ★ SOMBER WULITZER” but since I am unwise in the ways of CD labelling, I mixed up the names.

Oops.

It's a pity though, because I think “Somber Wurlitzer” is a much better group name than “Greater California.”

But it does appear I've introduced Greater California to a couple of people. One person described it as “what if nostalgic boomers had invented Darkwave” and the second person said “if you think the theme for Trailer Park Boys is good, you'll probably like this. I can't give a more glowing commendation than that!” And that's great! Everybody has different tastes. It's just that I didn't like Greater California all that much. My initial reaction calling it “Gothic Bubblegum pop” was my honest reaction to it.

Wednesday, October 13, 2021

Alphabet soup

So we have this new project at work, ERAS. It's an ETLA that stands for “ECID ReST API Service,” which itself contains a few ETLAs that, when fully expanded, becomes “Enhanced Caller Identification Representational State Transfer Application Programming Interface Service.” If you have to ask, it's not worth knowing, and if you don't have to ask, I'm sorry.

I don't know whether to laugh or cry.


Notes on an overheard conversation from 25 years ago about TLAs (and yes, this really did happen)

“What was that term you just used?”

“What? TLA?”

“Yes. What does it mean?”

“It's a ‘Three Letter Acronym.’”

“Yes, but what does it mean?”

“A ‘Three Letter Acronym.’”

“… and it means … ?”

“…”

“…”

“Tee—three, el—letter, ay—acronym.”

“But what does … oooooooh!”

“Thank God I didn't mention ETLA …”

“What?”

Sunday, October 13, 2024

A benchmark of three different floating point packages for the 6809

I recently came across another floating point package for the 6809 (written by Lennart Benschop) and I wanted to see how it stacked up against IEEE-754 and BASIC floating point math. To do this, I wanted to add support to my 6809 assembler, but it required some work. There was no support to switch floating point formats—if you picked the rsdos output format, you got the Microsoft floating point, and for the other output formats, you got IEEE-754 support.

The other issue, the format used by the new floating point package I found is ever-so-slightly different from the Microsoft format. It's just a single bit difference—Microsoft uses an exponential bias of 129, whereas this package uses a bias of 128 (and why do floating point packages use an exponential bias? I'm not entirely sure why). But other than this one small difference, they are basially the same.

It turned out not to be that hard to support all three floating point formats. The output formats still select a default format like before, but now, you can use the .OPT directive to select the floating point formats:

	.opt	* real ieee
	.float	3.14159265358979323846
	.opt	* real msfp
	.float	3.14159265358979323846
	.opt	* real lbfp
	.float	3.14159265358979323846

And you get three different formats as output:

                         | FILE p.asm
                       1 |                 .opt    * real ieee
0000: 40490FDB         2 |                 .float  3.14159265358979323846
                       3 |                 .opt    * real msfp
0004: 82490FDAA2       4 |                 .float  3.14159265358979323846
                       5 |                 .opt    * real lbfp
0009: 81490FDAA2       6 |                 .float  3.14159265358979323846

I added some code to my floating point benchmark program, which now uses all three formats to calculate -2π3/3! and times each one. The new code:

        .opt    * real lbfp
        .tron   timing
lb_fp           ldu     #lb_fp.fpstack
                ldx     #.tau
                jsr     fplod   ; t0 = .tau
                ldx     #.tau
                jsr     fplod   ; t1 = .tau
                jsr     fpmul   ; t2 = .t0 * t1
                ldx     #.tau
                jsr     fplod   ; t3 = .tau
                jsr     fpmul   ; t4 = .t2 * t3
                ldx     #.fact3
                jsr     fplod
                jsr     fpdiv
                jsr     fpneg
                ldx     #.answer
                jsr     fpsto
        .troff
		rts

.tau            .float  6.283185307
.fact3          .float  3!
.answer         .float  0
                .float  -(6.283185307 ** 3 / 3!)

.fpstack        rmb     4 * 10

The results are interesting (the IEEE-754 results are from the same package which support both single and double formats):

Benchmark of three floating point packages for the 6809
format cycles instructions
Microsoft 8752 2124
Lennart 7465 1326
IEEE-754 single 14204 2932
IEEE-754 double 31613 6865

The new code is the fastest so far. I think the reason it's faster than Microsoft's is (I think) because Microsoft uses a single codebase for all their various BASIC interpreters, so it's not really “written in 6809 assembler” as much as it is “written in 8080 assembler and semi-automatically converted to 6809 assembly,” which explains why Microsoft BASIC was so ubiquitous for 80s machines.

It's also smaller than the IEEE-754 package, a bit over 2K vs. the 8K for the IEEE-754 package. It's hard to tell how much bigger it is than Microsoft's, because Microsoft's is buried inside a BASIC interpreter, but it wouldn't surprise me it's smaller given the number of instructions executed.


Discussions about this entry


Unit testing from inside an assembler, part IV

I'm not terribly happy with how running unit tests inside my assembler work. I mean, it works, as in, it tests the code and show problems during the assembly phase, but I don't like how you write the tests in the first place. Here's one of the tests I added to my maze generation program (and the routine it tests):

getpixel        bsr     point_addr      ; get video address
                comb                    ; reverse mask (since we're reading
                stb     ,-s             ; the screen, not writing it)
                ldb     ,x              ; get video data
                andb    ,s+             ; mask off the pixel
                tsta                    ; any shift?
                beq     .done
.rotate         lsrb                    ; shift color bits
                deca
                bne     .rotate
.done           rts                     ; return color in B

        .test
	.opt	test	pokew	ECB.beggrp , $0E00
        .opt    test    poke    $0E00 , %11_11_11_11
                lda     #0
                ldb     #0
                bsr     getpixel
        .assert /d = 3
        .assert /x = @@ECB.beggrp
                lda     #1
                ldb     #0
                bsr     getpixel
        .assert /d = 3
        .assert /x = @@ECB.beggrp
                lda     #2
                ldb     #0
                bsr     getpixel
        .assert /d = 3
        .assert /x = @@ECB.beggrp
                lda     #3
                ldb     #0
                bsr     getpixel
        .assert /d = 3
        .assert /x = @@ECB.beggrp
                rts
        .endtst

The problem is the machine code for the test is included in the final binary output, which is bad because I can't just set an option to run the tests in addition to assembling the code into its final output, which I don't want (and that means when I use the test backend, I tend to generate the output to /dev/null). I've also found that I prefer table-style tests to writing code (for reasons way beyond the scope of this entry). For example, for a C function like this:

int max_monthday(int year,int month)
{
  static int const days[] = { 31,0,31,30,31,30,31,31,30,31,30,31 } ;
  
  assert(year  > 1969);
  assert(month >    0);
  assert(month <   13);
  
  if (month == 2)
  {
    /*----------------------------------------------------------------------
    ; in case you didn't know, leap years are those years that are divisible
    ; by 4, except if it's divisible by 100, then it's not, unless it's
    ; divisible by 400, then it is.  1800 and 1900 were NOT leap years, but
    ; 2000 is.
    ;----------------------------------------------------------------------*/
    
    if ((year % 400) == 0) return 29;
    if ((year % 100) == 0) return 28;
    if ((year %   4) == 0) return 29;
    return 28;
  }
  else
    return days[month - 1];
}

I would prefer to write test code like:

Test code for max_monthday()
output year month
28 1900 2
29 2000 2
28 2100 2
29 1904 2
29 2104 2
28 2001 2

Just specify the inputs and outputs for some corner cases, and let the computer do what is necessary to call the function in question.

But it's not so easy with assembly language, given the large number of ways to pass data into a function, and the number of output results one can have. How would I specify that the inputs come in registers A and B, and the outputs come in A, B and X? The above could be done in a table format, I guess. It might not be pretty, but it's doable.

Then there's these subroutines and their associated tests:

;***********************************************************************
;       RND4            Generate a random number 0 .. 3
;Entry: none
;Exit:  B - random number
;***********************************************************************

rnd4            dec     rnd4.cnt        ; any more cached random #s?
                bpl     .cached         ; yes, get next cached number
                ldb     #3              ; else reset count
                stb     rnd4.cnt
                bsr     random          ; get random number
                stb     rnd4.cache      ; save in the cache
                bra     .ret            ; and return the first number
.cached         ldb     rnd4.cache      ; get cached value
                lsrb                    ; get next 2-bit random number
                lsrb
                stb     rnd4.cache      ; save ermaining bits
.ret            andb    #3              ; mask off our result
                rts

;***********************************************************************
;       RANDOM          Generate a random number
;Entry: none
;Exit:  B - random number (1 - 255)
;***********************************************************************

random          ldb     lfsr
                andb    #1
                negb
                andb    #$B4
                stb     ,-s             ; lsb = -(lfsr & 1) & taps
                ldb     lfsr
                lsrb                    ; lfsr >>= 1
                eorb    ,s+             ; lfsr ^=  lsb
                stb     lfsr
                rts

        .test
                ldx     #.result_array
                clra
                clrb
.setmem         sta     ,x+
                decb
                bne     .setmem
                ldx     #.result_array + 128
                lda     #1
                sta     lfsr
                lda     #255
.loop           bsr     random
        .assert /b <> 0         , "degenerate LFSR"
        .assert @/b,x = 0       , "non-repeating LFSR"
                inc     b,x
                deca
                bne     .loop

                clr     ,x
                clr     1,x
                clr     2,x
                clr     3,x
                lda     #255
.chk4           bsr     rnd4
        .assert /b >= 0
        .assert /b <= 3
                inc     b,x
                deca
                bne     .chk4
        .tron
                ldb     ,x      ; to check the spread
                ldb     1,x     ; of results, basically
                ldb     2,x     ; these should be roughly
                ldb     3,x     ; 1/4 of 256
        .troff
        .assert @/,x + @/1,x + @/2,x + @/3,x = 255
                rts
.result_array   rmb     256
        .endtst

        .test   "whole program"
        .opt    test    pokew   $A000 , KEYIN
        .opt    test    pokew   $FFFE , END
        .opt    test    prot    r,$A000,$A001

                lbsr    start
KEYIN           lda     #'Q'
END             rts

        .endtst

And … just uhg. I mean, this checks that the 8-bit LFSR I'm using to generate random numbers actually doesn't repeat within it's 255-period cycle, and that the number of 2-bit random numbers I generate from RND4 is more or less evenly spread, and for both of those, I use an array to store the intermediate results. I leary about including an interpreter just for the tests, because I don't think it would be any better. At least the test code is largely written in the target language of 6809 assembly.

Then again, I could embed Lua, and write the tests like:

	.test
		local array = {}
		for i = 0 , 255 do array[i] = 0 end

		mem['lfsr'] = 1
		for i = 0 , 255 do
		  call 'random'
		  assert(cpu.B ~= 0)
		  assert(array[cpu.B] == 0)
		  array[cpu.B] = 1
		end

		array[0] = 0
		array[1] = 0
		array[2] = 0
		array[3] = 0

		for i = 0 , 255 do
		  call 'rnd4'
		  assert(cpu.B >= 0)
		  assert(cpu.B <= 3)
		  array[cpu.B] = array[cpu.B] + 1
		end

		assert(array[0] + array[1] + array[2] + array[3] == 255)
	.endtst

I suppose? I would still need to somehow code the fake KEYIN and END routines required for the test. And the first test at the start of this post would then look like:

	.test
		memw['ECB.beggrp'] = 0x0E00
		mem[0x0E00] = '%11_11_11_11'
		cpu.A = 0
		cpu.B = 0
		call 'getpixel'
		assert(cpu.D == 3)
		assert(cpu.X == memw['ECB.beggrp'])
		cpu.A = 1
		cpu.B = 0
		call 'getpixel'
		assert(cpu.D == 3)
		assert(cpu.X == memw['ECB.beggrp'])
		cpu.A = 2
		cpu.B = 0
		call 'getpixel'
		assert(cpu.D == 3)
		assert(cpu.X == memw['ECB.beggrp'])
		cpu.A = 3
		cpu.B = 0
		call 'getpixel'
		assert(cpu.D == 3)
		assert(cpu.X == memw['ECB.beggrp'])
	.endtst

which isn't any longer than the original test, but still … uhg. But doing this means I won't have 6809 code for testing in the final output, which means I could run tests with any backend.

I'll have to think on this.


Discussions about this entry

Obligatory Picture

Trying to get into the festive mood this year

Obligatory Contact Info

Obligatory Feeds

Obligatory Links

Obligatory Miscellaneous

Obligatory AI Disclaimer

No AI was used in the making of this site, unless otherwise noted.

You have my permission to link freely to any entry here. Go ahead, I won't bite. I promise.

The dates are the permanent links to that day's entries (or entry, if there is only one entry). The titles are the permanent links to that entry only. The format for the links are simple: Start with the base link for this site: https://boston.conman.org/, then add the date you are interested in, say 2000/08/01, so that would make the final URL:

https://boston.conman.org/2000/08/01

You can also specify the entire month by leaving off the day portion. You can even select an arbitrary portion of time.

You may also note subtle shading of the links and that's intentional: the “closer” the link is (relative to the page) the “brighter” it appears. It's an experiment in using color shading to denote the distance a link is from here. If you don't notice it, don't worry; it's not all that important.

It is assumed that every brand name, slogan, corporate name, symbol, design element, et cetera mentioned in these pages is a protected and/or trademarked entity, the sole property of its owner(s), and acknowledgement of this status is implied.

Copyright © 1999-2024 by Sean Conner. All Rights Reserved.