Salient Assembly Episode 1

https://www.youtube.com/watch?v=dxwmPFIUpLY
Welcome to Salient Assembly.

The show where we deep dive into a very specific 6809 assembly language topic.

Today we’re talking about calling subroutines. Subroutines are a very important aspect to programming. When ever you find yourself needing to do the same thing in two different parts of your program your best bet is to create a subroutine for that function. This process is so fundamental it has a name: refactoring.

There are many instructions to facilitate this. But the today we’ll be investiagting Branch to subroutine, and jump to subroutine. The branch version is used in position independant code, and also has a faster, shorter version for smaller branches.

JSR with no parameters

Let’s first talk about a subroutine that requires no parameters to be passed. The JSR instruction will push the address of the next instruction to the stack and then pass control to the subroutine.

The RTS instruction will pull two bytes off the top of the stack and jump to that memory location.

These two instructions are what enable calling subroutines in 6809 assemble language.

For example, let’s say we’re writing a game and we want to write a subroutine that displays the text GAME OVER in the center of the screen.

GameOverCondition

jsr GAMEOVER

jmp NextMiniGame

GAMEOVER

ldx #$50C

ldy #text

loop

lda ,y+

beq WaitGameOver

sta ,x+

bra loop

WaitGameOver

jsr [POLCAT]

beq WaitGameOver

rts

text fcn "GAME OVER"

Here we see the code for a mini game ending. Let’s dig in deep to the specifics

• We execute the jsr instruction. It will push the address of the next instruction on the stack and jump to the operand.
• Do the work of the subroutine. This will copy some text to the middle of the VDG screen.
• Then return to the main program

JSR with calculated address

Sometimes you want to branch to different subroutines based on a condition. One method to do this is with a table of of subroutines. For example:

GameOverCondition

ldb randomNumber

aslb

ldx #gameOverTable

abx

jsr [,x]

jmp nextMiniGame

gameOverTable

fdb WaitGameOver1

fdb WaitGameOver2

WaitGameOver1

...

rts

WaitGameOver2

...

rts

• I load a previously calculated random number that will be 0 or 1.
• Then multiply it by two.
• I add that value to the base address of the subroutine table.
• Then jump to that specific subroutine.
• After the subroutine finishes, it returns to the main program.

Parameter passing

Most of the time a subroutine will take parameters. These are values that change how the subroutine functions. In the example we’ve seen so far we may want to change the subroutine to make the text it displays variable. We also may want to have the text’s final position variable. Let’s go over some methods of passing these parameters to our subroutine.

JSR fixed memory locations

A simple, non-position independant method of passing parameters to a sub-routine is by using fixed memory locations.

GameOverCondition

ldx #text

stx textBufferAddress

ldx #$50C

stx textposition

jsr GAMEOVER

jmp NextMiniGame

GAMEOVER

ldx textposition

ldy textBufferAddress

loop

lda ,y+

beq WaitGameOver

sta ,x+

bra loop

WaitGameOver

jsr [POLCAT]

beq WaitGameOver

rts

textBufferAddress fdb 0
textposition fdb 0
text fcn "GAME OVER"

1. load the address of the text string and store it in the parameter area
2. load the screen position and store it into the parameter area
3. jump to the subroutine
4. load the parameters into registers and perform the function.
5. then return to the main program.

This allows the GAMEOVER subroutine to print different messages. You can pass different text string and different positions to get different results.

JSR register

A faster way to pass parameters would be to use registers

GameOverCondition

ldy #text

ldx #$50C

jsr GAMEOVER

jmp NextMiniGame

GAMEOVER
loop

lda ,y+

beq WaitGameOver

sta ,x+

bra loop

WaitGameOver

jsr [POLCAT]

beq WaitGameOver

rts

text fcn "GAME OVER"

• load the registers with the parameters
• call the subroutine
• notice how the registers are all setup ready for the function to be done.
• and return to the main program.

JSR stack

The stack is also a good way to pass parameters to a subroutine. Since the return address is already stored on the stack it makes sense to put the other parameters there.

GameOverCondition

ldx #text

pshs x

ldx #$50C

pshs x

jsr GAMEOVER

jmp NextMiniGame

GAMEOVER

puls u

puls x

puls y

loop

lda ,y+

beq WaitGameOver

sta ,x+

bra loop

WaitGameOver

jsr [POLCAT]

beq WaitGameOver

tfr u,pc

text fcn "GAME OVER"

• Push the two parameters onto the stack
• Call the subroutine
• Pop the return address off the stack
• pop the parameters off the stack
• perform the function
• transfer the return address to the pc register and return to the main program.

JSR post data

The last method we’ll discuss is when you put the data to be passed after the subroutine call. Care must be taken to return to the proper address when done with the subroutine.

GameOverCondition

jsr GAMEOVER

fdb $50C

fcn "GAME OVER"

jmp NextMiniGame

GAMEOVER

puls x

leay 2,x

ldx ,x

loop

lda ,y+

beq WaitGameOver

sta ,x+

bra loop

WaitGameOver

jsr [POLCAT]

beq WaitGameOver

tfr y,pc

• First we call the subroutine
• immediately after the call, we put two bytes of a destination address and then a string of characters with a zero terminator.
• In the subroutine we load x with the address that was pushed onto the stack. This is technically the return address, but if we used it as such, we would return to data, not code.
• Then we load register Y with the address of the text string
• Then we load register X with the address of the text destination.
• We perform the function
• Then we return from the subroutine by transferring the Y register to the PC register which will conveniently be the proper return address.

That’s it for this episode. I hope you had a good time learning about subroutines and all the various ways you can pass parameters to them.

Bye for now.

CoCo 3 GIME Timer Tests

Screen Shot 2021-05-12 at 11.17.36 PM

Recently I was investigating why the Color Computer 3 version of Arkanoid didn’t make any ricochet sounds when the ball bounced off an object in MAME. For an example of the game working properly see this video here: https://youtu.be/1eexgL5b4lo

After talking with the author of the game (Steve Bjork: name drop) he said the sound in question was being played by using the timer interrupt system in the machine. I disassembled the FIRQ handler and quickly found the problem. His playback routine did two things: it wrote a value to the DAC, and determined the proper amount of time to wait before the next DAC update. It did not update the DAC at a constant frequency.

Here is what the ISR did, in the order it did them:

1. Acknowledge the interrupt.
2. Write the new timer delay to the register
3. Enable the interrupt again.
4. Write the value to the DAC.
5. Determine the next timer delay and store it for the next interrupt.

The problem was the first time the ISR was called: It wrote a zero for the amount of delay to the next interrupt, because the delay isn’t properly determined until then end of the ISR. Documentation about the CoCo 3 hardware says this should stop the timer interrupt. And that is what MAME did. But this is not what real hardware does. On real hardware you get an immediate re-aserting of the interrupt when the timer value is set to zero. On the second interrupt the sound system is properly initialized, real timer values were being written, and samples are being sent to the DAC.

In order to find this problem I wrote some test programs. This helped me to fix the above bug, and also discover another bug in MAME. MAME tightly coupled the pulling of the F/IRQ line with setting the F/IRQ flag. On real hardware turning off the interrupt has no effect whether the flags are set.

The archive below is the test code I wrote. Three different routines that set up the timer interrupt. Every time the interrupt is fired the address $400 is incremented.

TEST1 sets up the slow timer with a value of $FFF. TEST2 sets up the fast timer with a value of $FFF. TEST3 sets up the slow timer with a value of $0. All three programs use polling to check if the timers fired (bug #2). TEST3 is the program that test a timer value of zero (bug #1).

Included are video files from my Color Computer 3 with an ’86 GIME. They show what the program display as they are running.

CoCo 3 Interrupts Tests.zip

Color Computer 3 Text Mode Study

I decided to run thru the complete 40 column text mode options on a CoCo 3. Documented with pictures.
Here is the program I used to create the display:

10 CLS
20 FOR X = 0 TO 30
30 PRINT
40 PRINT X;
50 FOR Z = 65 TO 75
60 PRINT CHR$(X+Z);
70 NEXT Z
80 NEXT X
90 FOR X + 0 TO 7
100 LOCATE 0,0:PRINT X
110 POKE &HFF98,X
120 A$=INKEY$:IF A$="" THEN 120
130 NEXT X
140 GOTO 90

Text Rows: 24 (VRES0: 0, VRES1: 0).
Vertical Size: 1 scan line (LPR2: 0, LPR1: 0, LPR0: 0).
Description: Uses the first row of every text cell for 192 rows.
IMG_0946_r
Text Rows: 24 (VRES0: 0, VRES1: 0).
Vertical Size: 1 scan line (LPR2: 0, LPR1: 0, LPR0: 1).
Description: Uses the first row of every text cell for 192 rows.
IMG_0947_r
Text Rows: 24 (VRES0: 0, VRES1: 0).
Vertical Size: 2 scan lines (LPR2: 0, LPR1: 1, LPR0: 0).
Description: Uses the first two rows of every text cell for 96 rows.
IMG_0948_r
Text Rows: 24 (VRES0: 0, VRES1: 0).
Vertical Size: 8 scan lines per text cell (LPR2: 0, LPR1: 1, LPR0: 1).
Description: 24 rows of text.
IMG_0949_r
Text Rows: 24 (VRES0: 0, VRES1: 0).
Vertical Size: 9 scan lines per text cel (LPR2: 1, LPR1: 0, LPR0: 0).
Description: 21.3 rows of text
IMG_0950_r
Text Rows: 24 (VRES0: 0, VRES1: 0).
Vertical Size: 10 scan lines per text cell (LPR2: 1, LPR1: 0, LPR0: 1).
Description: 19.3 rows of text
IMG_0951_r
Text Rows: 24 (VRES0: 0, VRES1: 0).
Vertical Size: 11 scan lines per text cell (LPR2: 1, LPR1: 1, LPR0: 0).
Description: 17.5 rows of text
IMG_0952_r
Text Rows: 24 (VRES0: 0, VRES1: 0).
Vertical Size: 16 scan lines per text cell (LPR2: 1, LPR1: 1, LPR0: 1).
Description: 12 rows of text. First row repeated.
IMG_0953_r

Text Rows: 25 (VRES0: 0, VRES1: 1).
Vertical Size: 1 scan line (LPR2: 0, LPR1: 0, LPR0: 0).
Description: Uses the first row of every text cell for 200 rows.
IMG_0902_r
Text Rows: 25 (VRES0: 0, VRES1: 1).
Vertical Size: 1 scan line (LPR2: 0, LPR1: 0, LPR0: 1).
Description: Uses the first row of every text cell for 200 rows.
IMG_0903_r
Text Rows: 25 (VRES0: 0, VRES1: 1).
Vertical Size: 2 scan lines (LPR2: 0, LPR1: 1, LPR0: 0).
Description: Uses the first two rows of every text cell for 100 rows.
IMG_0904_r
Text Rows: 25 (VRES0: 0, VRES1: 1).
Vertical Size: 8 scan lines per text cell (LPR2: 0, LPR1: 1, LPR0: 1).
Description: 25 rows of text.
IMG_0914_r
Text Rows: 25 (VRES0: 0, VRES1: 1).
Vertical Size: 9 scan lines per text cel (LPR2: 1, LPR1: 0, LPR0: 0).
Description: 21.3 rows of text
IMG_0915_r
Text Rows: 25 (VRES0: 0, VRES1: 1).
Vertical Size: 10 scan lines per text cell (LPR2: 1, LPR1: 0, LPR0: 1).
Description: 20 rows of text
IMG_0916_r
Text Rows: 25 (VRES0: 0, VRES1: 1).
Vertical Size: 11 scan lines per text cell (LPR2: 1, LPR1: 1, LPR0: 0).
Description: 18 (and one scan line) rows of text
IMG_0917_r
Text Rows: 25 (VRES0: 0, VRES1: 1).
Vertical Size: 16 scan lines per text cell (LPR2: 1, LPR1: 1, LPR0: 1).
Description: 13 rows of text
IMG_0918_r

Text Rows: 28 (VRES0: 1, VRES1: 1).
Vertical Size: 1 scan line (LPR2: 0, LPR1: 0, LPR0: 0).
Description: Uses the first row of every text cell for 224 rows.
IMG_0919_r
Text Rows: 28 (VRES0: 1, VRES1: 1).
Vertical Size: 1 scan line (LPR2: 0, LPR1: 0, LPR0: 1).
Description: Uses the first row of every text cell for 224 rows.
IMG_0920_r
Text Rows: 28 (VRES0: 1, VRES1: 1).
Vertical Size: 2 scan lines (LPR2: 0, LPR1: 1, LPR0: 0).
Description: Uses the first two rows of every text cell for 112 rows.
IMG_0921_r
Text Rows: 28 (VRES0: 1, VRES1: 1).
Vertical Size: 8 scan lines per text cell (LPR2: 0, LPR1: 1, LPR0: 1).
Description: 28 rows of text.
IMG_0922_r
Text Rows: 28 (VRES0: 1, VRES1: 1).
Vertical Size: 9 scan lines per text cel (LPR2: 1, LPR1: 0, LPR0: 0).
Description: 25 rows of text
IMG_0923_r
Text Rows: 28 (VRES0: 1, VRES1: 1).
Vertical Size: 10 scan lines per text cell (LPR2: 1, LPR1: 0, LPR0: 1).
Description: 22.5 rows of text
IMG_0924_r
Text Rows: 28 (VRES0: 1, VRES1: 1).
Vertical Size: 11 scan lines per text cell (LPR2: 1, LPR1: 1, LPR0: 0).
Description: 21.5 (and one scan line) rows of text
IMG_0925_r
Text Rows: 28 (VRES0: 1, VRES1: 1).
Vertical Size: 16 scan lines per text cell (LPR2: 1, LPR1: 1, LPR0: 1).
Description: 14 (plus one scan line) rows of text
IMG_0926_r

MAME, CoCo, and MIDI

I recently added a cartridge to MAME that emulated a MIDI port for the Color Computer. This post is about how to use the feature with the command line version of MAME.
IMG_0092-Cropped-761x1024
First you’ll need to setup your host computer’s MIDI functionality. On macOS you use a program called Audio MIDI Setup in the Utilities folder. I do not know how to setup MIDI on a Windows or Linux computer.
Screen Shot 2021-11-16 at 8.23.43 AM
After setting up the host interface you will want to start MAME and have it list the MIDI interfaces it can find:

tlindner$ ./mame -listmidi

MIDI input ports:
IAC Driver Bus 1 (default)

MIDI output ports:
IAC Driver Bus 1 (default)

Next, let’s attach a Multi-Pak to the CoCo emulation’s expansion port and list the devices we can attach to each slot.

tlindner$ ./mame coco2b -ext multi -listslots
SYSTEM           SLOT NAME        SLOT OPTIONS     SLOT DEVICE NAME
---------------- ---------------- ---------------- ----------------------------
coco2b           rs232            dec_loopback     RS232 Loopback (DEC 12-15336-00)
                                  ie15             IE15 Terminal
                                  keyboard         Serial Keyboard
                                  loopback         RS232 Loopback
                                  null_modem       RS232 Null Modem
                                  printer          Serial Printer
                                  pty              Pseudo terminal
                                  rs_printer       Radio Shack Serial Printer
                                  sunkbd           Sun Keyboard Adaptor
                                  swtpc8212        SWTPC8212 Terminal
                                  terminal         Serial Terminal

                 ext              cc2hdb1          CoCo2 HDB-DOS
                                  cc3hdb1          CoCo3 HDB-DOS
                                  ccpsg            CoCo PSG
                                  cd6809_fdc       Codimex CD-6809 Disk BASIC (1986)
                                  cp450_fdc        Prológica CP-450 BASIC Disco V. 1.0 (1984)
                                  dcmodem          CoCo Direct Connect Modem PAK
                                  fdc              CoCo FDC
                                  fdcv11           CoCo FDC v1.1
                                  games_master     CoCo Games Master Cartridge
                                  midi             CoCo MIDI PAK
                                  multi            CoCo Multi-Pak Interface
                                  orch90           CoCo Orch-90 PAK
                                  ram              Disto 1024K RAM Cartridge
                                  rs232            CoCo Deluxe RS-232 PAK
                                  ssc              CoCo S/SC PAK
                                  stecomp          Speech Systems Stereo Composer
                                  sym12            Speech Systems Symphony Twelve

                 ext:multi:slot1  ccpsg            CoCo PSG
                                  dcmodem          CoCo Direct Connect Modem PAK
                                  games_master     CoCo Games Master Cartridge
                                  midi             CoCo MIDI PAK
                                  orch90           CoCo Orch-90 PAK
                                  ram              Disto 1024K RAM Cartridge
                                  rs232            CoCo Deluxe RS-232 PAK
                                  ssc              CoCo S/SC PAK
                                  stecomp          Speech Systems Stereo Composer
                                  sym12            Speech Systems Symphony Twelve

                 ext:multi:slot2  ccpsg            CoCo PSG
                                  dcmodem          CoCo Direct Connect Modem PAK
                                  games_master     CoCo Games Master Cartridge
                                  midi             CoCo MIDI PAK
                                  orch90           CoCo Orch-90 PAK
                                  ram              Disto 1024K RAM Cartridge
                                  rs232            CoCo Deluxe RS-232 PAK
                                  ssc              CoCo S/SC PAK
                                  stecomp          Speech Systems Stereo Composer
                                  sym12            Speech Systems Symphony Twelve

                 ext:multi:slot3  ccpsg            CoCo PSG
                                  dcmodem          CoCo Direct Connect Modem PAK
                                  games_master     CoCo Games Master Cartridge
                                  midi             CoCo MIDI PAK
                                  orch90           CoCo Orch-90 PAK
                                  ram              Disto 1024K RAM Cartridge
                                  rs232            CoCo Deluxe RS-232 PAK
                                  ssc              CoCo S/SC PAK
                                  stecomp          Speech Systems Stereo Composer
                                  sym12            Speech Systems Symphony Twelve

                 ext:multi:slot4  cc2hdb1          CoCo2 HDB-DOS
                                  cc3hdb1          CoCo3 HDB-DOS
                                  ccpsg            CoCo PSG
                                  cd6809_fdc       Codimex CD-6809 Disk BASIC (1986)
                                  cp450_fdc        Prológica CP-450 BASIC Disco V. 1.0 (1984)
                                  dcmodem          CoCo Direct Connect Modem PAK
                                  fdc              CoCo FDC
                                  fdcv11           CoCo FDC v1.1
                                  games_master     CoCo Games Master Cartridge
                                  midi             CoCo MIDI PAK
                                  orch90           CoCo Orch-90 PAK
                                  ram              Disto 1024K RAM Cartridge
                                  rs232            CoCo Deluxe RS-232 PAK
                                  ssc              CoCo S/SC PAK
                                  stecomp          Speech Systems Stereo Composer
                                  sym12            Speech Systems Symphony Twelve

                 ext:multi:slot4:fdcv11:wd17xx:0 qd               5.25" quad density floppy drive
                 ext:multi:slot4:fdcv11:wd17xx:1 qd               5.25" quad density floppy drive
                 ext:multi:slot4:fdcv11:wd17xx:2 qd               5.25" quad density floppy drive
                 ext:multi:slot4:fdcv11:wd17xx:3 qd               5.25" quad density floppy drive

There is a lot to take in, but what we’re interested in is that slot ‘ext:multi:slot3″ has an option of midi. To start an emulation with a MIDI cart in that slot you type:

./mame coco2b -ext multi -ext:multi:slot3 midi

Don’t worry there is no floppy disk cartridge specified, it is the default for slot 4.
Next we need to connect the host’s MIDI interface to MAME. Refer back the the start of this tutorial and recall the names of the available midi interfaces.

The host-to-emulation MIDI connection is made using a medial type. Issue this command to see the available media types:

tlindner$ ./mame coco2b -ext multi -ext:multi:slot3 midi -listmedia
SYSTEM           MEDIA NAME       (brief)    IMAGE FILE EXTENSIONS SUPPORTED
---------------- --------------------------- -------------------------------
coco2b           cassette         (cass)     .wav  .cas  
                 printout         (prin)     .prn  
                 cartridge1       (cart1)    .ccc  .rom  
                 cartridge2       (cart2)    .ccc  .rom  
                 cartridge3       (cart3)    .ccc  .rom  
                 cartridge4       (cart4)    .ccc  .rom  
                 midiin           (min)      .mid  
                 midiout1         (mout1)    .mid  
                 midiout2         (mout2)    .mid  
                 cartridge5       (cart5)    .ccc  .rom  
                 floppydisk1      (flop1)    .dmk  .jvc  .dsk  .vdk  .sdf  .os9  .d77  .d88  .1dd  .dfi  .hfe  .imd  .ipf  .mfi  .mfm  .td0  .cqm  .cqi  
                 floppydisk2      (flop2)    .dmk  .jvc  .dsk  .vdk  .sdf  .os9  .d77  .d88  .1dd  .dfi  .hfe  .imd  .ipf  .mfi  .mfm  .td0  .cqm  .cqi  
                 harddisk1        (hard1)    .vhd  
                 harddisk2        (hard2)    .vhd  


Note the avaiablilty of midiin, midiout1, and midiout2. Midiin is the media type used to send information to the CoCo. Midiout1 is the MIDI THRU port that automatically sends any incoming data out. Midiout2 is the regular MIDI OUT that is under software control in the emulation.
This is an example of sending MIDI input into the CoCo emulation:

tlindner$ ./mame coco2b -ext multi -ext:multi:slot3 midi -midiin "IAC Driver Bus 1"

Using CoCo software to do something with all this is left as an excessive to the reader.

The 2017 Post

It seems I’m only doing year end posts now. I’m not happy about this. If I wanted to do it more, I’d do it more. So let do it more!
In April of 2017 I went to the CoCoFest in Chicago. I met with my many wonderful friends. Learned a lot of new things. One thing I did different this year is I got a late flight out Monday, around 5 PM. After checking out of the hotel I took a cab to downtown Chicago and spent some time sight-seeing. It was really fun and decided to do it again in 2018. Although in 2018 I think I’ll head straight to a museum. Spend the whole day in there.
In early July I flew to Oregon and spent a week with my sister in Sun River. A lovely place to rent cabins and go to the nearby waterpark. We also went to an Observatory, where I saw the rings of Saturn for the first time. My Uncle Mel also joined us for the trip and he made the whole thing 200% more fun. The lava cast forrest also deserves a mention as a really neat place to visit.
In late July I had a week of hell, also known as the best week ever. On Thursday, July 26 I went into The City to watch a live Mystery Science Theatre 3000 show (Movie: Eegah). Then the next day I went back for a second show (Movie: Argoman the Fantastic Superman). Then the next day I went back for an OMD show. They played some fantastic new stuff from their recently released album. Then the next day I flew to Los Angeles and saw OMD again with 5 other 80s bands. Then the next day, Sunday, my daughter (Megan) and I went to Universal Studios. Whew!
In November the Wine Country Fires took my brother’s home. He and his family then moved to Portland. Bummer for me, good for my sister.
In December I flew to England to spend time with my other daughter (Bethany). We made our way to Garmisch Germany. We stayed at a nice hotel, spa. Visited the Linderhoff Palace. And toured a microbrew; Griesbräu Zu Murnau. In German it was nicely covered in snow, very beautiful.
In late December my boss of many, many years decided to up and move to Oregon. And I also signed up for Tinder.

A concert of a life time

In July of 2017 I went to 80s Weekend concert in LA. I was 5 rows from the front, near the center. It was so amazing. I was able to see bands that I never thought I’d see. Here is the set list.

The Fixx

Red Skies
Second song
One Thing Leads to Another
Stand or Fall
Deeper and Deeper
Saved by Zero

Collin Hay (of Men at Work)

Come Tumblin’ Down
It’s a Mistake
Who Can It Be Now?
Overkill
Down Under
I’m Walking Here
Be Good Johnny

Berlin

Take My Breath Away
The Metro
No More Words
Sex…(I’m A)

The Psychedelic Furs

President Gas
Love My Way
Angels Don’t Cry
The Ghost in You
Heartbeat
Heaven
Heartbreak Beat
Pretty in Pink

Belinda Carlisle

Mad About You
Head Over Heels
I Get Weak
Circle in the Sand
Leave a Light On
Our Lips Are Sealed
We Got the Beat
Heaven Is a Place on Earth

OMD

Enola Gay
Secret
Tesla Girls
History of Modern (Part 1)
If You Leave
(Forever) Live and Die
Joan of Arc
So in Love
Dreaming
Locomotion
Electricity

Obligatory 2016 post

Is it customary if you never do it?

The year is almost over and I thought it was time to take a quick look back. This is the year I traveled. A lot.

In April I went to the CoCoFest in Chicago. That was super fun and plan to do it again in 2017.

In June I went to South Korea to visit my daughter Bethany. I was out of the country for the first time ever on this trip and I made the most of it. And by most of it I mean spending a lot of time in an American hotel on an American Air Force base. Bethany had to work most day but we made the most of our time together. The last day I was there, I spent on my own in a real Korean airport hotel. Wonderful toilet.

In July I flew to Oregon to go family camping with my sister, and some of her friends. This year we went to Nehalem state beach. It was very beautify and serene overall a wonderful week off work. I really love my sister.

Finally in November I flew to England to visit my daughter Bethany at her new base. We spent a night in Cambridge, then a night in London, then two nights in Dublin. So much fun, such beautiful places. I got to meet some of Beth’s friends and over all had a great time.

The other great thing about 2016 is my other daughter, Megan, decided to move much closer to where I live. I get to see her more than twice weekly and it has been a blast.