Thanks. But I already have that and am trying to wrap my head around it.
Which assembler is compatible with gold-wings.a65?
If your intent is to be able to make a modified version of the code, we should strive to maintain a documented and buildable set of source code.
Remember that link I shared from flipprojets.fr a while back (the one with all the gawdy 3D chicks in bathing suits ) In there they mention a Rockwell āDesign Centerā, which I believe relates to the Rockwell AIM-65 development computer, hence the .a65 extension. Iām assuming an AIM-65 would be difficult to get a hold of now and probably not even as nice as modern systems, so all we need to do is find a compatible assembler.
However, we already have the disassembly; in my n00b view of things, couldnāt we just put that into any assembler worth its salt and get the magic machine code? Itās been a long time since Iāve done this, and it was with an Intel 8051 where we wrote the assembly from scratch instead of being given code to play with first.
More details from me once Letās Play Gaming Expo has passed.
Oh, and besides the datasheet Walter mentioned at 6502.org, hereās another helpful one for the 6532 RIOT chip: http://pdf.datasheetcatalog.com/datasheets/480/501467_DS.pdf
Rockwell made 6502 processors for awhile, but no more.
The Western Design Center http://www.westerndesigncenter.com/wdc/index.cfm is still doing business with the 6502 architecture. They do not offer a free assembler though their paid product is not bad at $40, but it is tied to your MAC address so you will need multiple ācopiesā if you use more than one computer.
There is a long list of assemblers at http://6502.org/tools/asm/
In my experience, there is quite a variation as to what pseudo ops they honor, such as .byte vs db vs fcb.
I asked because I thought you might already be using one.
Iām afraid that I have been spending more time on my projects than yours.
The debugger/simulator rabbit hole is connected to the cross assembler one and I now have mine assembling the Gold Wings code except for a phase error problem.
A phase error is flagged when a value determined for a symbol in pass 1 does not match during phase 2. It usually means there is a flaw in the assembler dealing with forward references though the source code can sometimes be transformed to avoid the error.
I have isolated the problem to a very simple test file:
[code]
DEI Research 6502 Cross Assembler Version 0.0 Jun-19-2016 16:04:11 Page 1
test.a65
Addr Code Line# Source Statement
0200 00001 *= $200
00002
0200 4D 0402 00003 eor Forward
0203 45 00 00004 eor Backward
00005
0205 00006 Forward
*** Error 12 *** Phase error between passes
00007
0000 00008 *= 0
00009
0000 00010 Backward
00011
00012 end
DEI Research 6502 Cross Assembler Version 0.0 Jun-19-2016 16:04:11 Page 2
test.a65 - Symbol table
Symbol Value Line Attributes
BACKWARD . . . . . . . . . . . . 0000 00010
FORWARD . . . . . . . . . . . . 0204 00006
[/code]
The assembler tries to use zero page addressing whenever possible to save code space and CPU cycles.
When it encounters the reference to Forward during pass 1, it does not know the value yet. Unfortunately, my code has a default value of 0, so two bytes are allocated for the zero page form of the instruction. In pass 2, it is clear the address is not in the zero page, so the absolute (3 byte) form is assembled, causing the location counter to be off by one byte - hence the phase error.
That Backward nonsense is a perverse test for an improper fix to the forward reference problem. In pass 1, 3 bytes should be allocated for the absolute form because of the forward reference. In pass 2, the absolute form must be assembled even though the zero page form is both possible and preferable in order to avoid a phase error the other way.
An ideal solution is an āoptimizingā assembler which makes as many passes as necessary to resolve everything. Unfortunately, my code is not structured to be able to do that efficiently.
A common compromise is to provide a way to give the assembler a hint in the source code as to which form to use. For example,
eor >Forward
eor <Backward
Again, unfortunately, my code is not set up to do that easily.
I have not fixed the phase error problem yet, but since I am so close, I temporarily disabled that little bit of code at the bottom of the assembler to delete the object code file if there were errors. I love having my own tools so that I can do thatā¦
I loaded the binary into my debugger/simulator and did a hex dump. As I suspected from looking at that big mash of mixed data and instructions, there are more text strings:
L20E5: .byte "TEST MODE"
L20EF: .byte "LEFT CHUTE COINS"
L2100: .byte "RIGHT CHUTE COINS"
L2112: .byte "CENTER CHUTE COINS"
L2125: .byte "TOTAL PLAYS"
L2131: .byte "TOTAL REPLAYS"
L213F: .byte "REPLAY PERCENTAGE"
L2151: .byte "TOTAL EXTRA BALLS"
L2163: .byte "TOTAL TILTS"
L216F: .byte "SPECIALS"
L2178: .byte "TIMES HGTD AWARDED"
L218B: .byte "FIRST HIGH SCORE"
L219C: .byte "SECOND HIGH SCORE"
L21AE: .byte "THIRD HIGH SCORE"
L21BF: .byte "HIGHEST GAME TO DATE"
L21D4: .byte "AVERAGE PMAYING TIME" ; <sic>
L21E9: .byte "LAMP!TEST"
L21F3: .byte "LAMP+SOLENOID TEST"
L2207: .byte "SWITCH MATRIX TEST"
L221A: .byte "DIP SWITCH SETTINGS"
L222E: .byte "DISPLAY TEST"
L223B: .byte "MEMORY TEST"
L227D: .byte "SWITCH CLOSED"
L228E: .byte "ALL SWITCHES OPEN"
L22A0: .byte " -MIN O-SEC"
L22AD: .byte "LAMP"
L22B4: .byte "SOLENOID"
L22BF: .byte "BOOKKEEPJNG CLEARED" ; <sic>
L22D3: .byte "*SEE SERVICE MANUAL*"
L22ED: .byte "0123456789ABCDEF"
L2300: .byte "ERROR- U4"
L230A: .byte "ERROR- U5"
L2314: .byte "ERROR- U6"
L231E: .byte "ERROR- Z5"
L2328: .byte "ERROR- GAME PQOM 1"
L233B: .byte "ERROR- GAME PSOM.2"
L234E: .byte "GAME PSOM CHECK-SUM"
L2362: .byte "PROM 1- "
L236F: .byte "ENTER INITIALS (6O)"
L2384: .byte "PKAYER .-A "
L239C: .byte "SQUADRON LEADERS "
L24A2: .byte "*** RED ALERT ***"
L24B4: .byte "FLIGHT QUARTERS"
So as you can see, we cannot hope to just decipher and comment what the disassembler spits out.
Edit: I had the thought over dinner that the misspellings in some of the text may be due to the disassembler converting portions of the text into instructions which were in turn improperly reconstructed by my assembler due to the phase errors. This is apparent not the case as I fixed the phase error and see exactly the same text as before.
Looking closely at my listing, I noticed a byte missing between the labels L20A0 and L20B2:
.209D 33 00384 L209D: .byte $33
.209E 35 37 00385 and L0037,X
.20A0 B1 BE 00386 L20A0: lda (L00BE),Y
.20A2 CB 00387 .byte $CB
.20A3 D8 00388 cld
.20A4 E5 B7 00389 sbc L00B7
.20A6 C4 D1 00390 cpy L00D1
.20A8 DE EB33 00391 dec L33EB,X
.20AB 35 37 00392 and L0037,X
.20AD 35 30 00393 and L0030,Y
.20AF 00 00 00394 .byte $00,$00
.20B1 00 00 00 00395 L20B2: .byte $00,$00,$00
.20B4 20 2020 00396 jsr L2020
.20B7 00 04 00397 L20B8: .byte $00,$04
After verifying that my assembler was not the culprit dropping the byte, I put on my hacker cap and plunged on. Not having the original binary, I figured there had to be a copy stashed within gold-wings.wrk for the disassembler to munch on. So, hex dump time. And here is the corresponding section:
00011930: 80 00 06 0C 12 33 35 37-B1 BE CB D8 E5 B7 C4 D1 |.....357........|
00011940: DE EB 33 35 37 39 30 00-00 00 00 00 00 20 20 20 |..35790...... |
00011950: 00 04 08 0C 10 14 17 1A-1D 20 08 10 15 20 81 82 |......... ... ..|
OK, my assembler has a bug displaying EB33 instead of 33EB in the object code section of the listing but there is no mistaking that 39 30 00 has been replaced by 35 30.
Now why would that be?
Well,
35 30 -> and 30,Y
while
39 30 00 -> and 0030,Y
Yepā¦absolute versus zero page as I was discussing earlier.
The solution? If it is not actual code, use .byte instead of fake instructions.
Folks, letās have a meeting to discuss progress and learn from each other sometime this weekend. Bill, Iād love to see how youāve been doing all this stuff. Please get back to me ASAP on what times youāre available by using this link: http://www.needtomeet.com/meeting?id=b7p2e2eiV Whoever wants to join is welcome, but Iāll pick the time with the most participants say they can make it.
First the bad news, for me anyway: crow is not very tasty.
The good: I was so obsessed with the X indexing modes that I failed to realize the ZeroPage,Y mode is only available for the LDX and STX instructions. He who lives by the table shall die by the table. Fixed that and the text cleared right up. I will update the list of text strings above shortly.
However, there are other bytes being dropped later on, in real code. So I have more analysis to do.
Interestingā¦I cannot edit the earlier post containing the list. I could have sworn there was no time limit in the past.
Anyway, this is the corrected text string list:
L20E6: .byte "TEST MODE"
L20F0: .byte "LEFT CHUTE COINS"
L2101: .byte "RIGHT CHUTE COINS"
L2113: .byte "CENTER CHUTE COINS"
L2126: .byte "TOTAL PLAYS"
L2132: .byte "TOTAL REPLAYS"
L2140: .byte "REPLAY PERCENTAGE"
L2152: .byte "TOTAL EXTRA BALLS"
L2164: .byte "TOTAL TILTS"
L2170: .byte "SPECIALS"
L2179: .byte "TIMES HGTD AWARDED"
L218C: .byte "FIRST HIGH SCORE"
L219D: .byte "SECOND HIGH SCORE"
L21AF: .byte "THIRD HIGH SCORE"
L21C0: .byte "HIGHEST GAME TO DATE"
L21D5: .byte "AVERAGE PLAYING TIME"
L21EA: .byte "LAMP TEST"
L21F4: .byte "LAMP+SOLENOID TEST"
L2208: .byte "SWITCH MATRIX TEST"
L221B: .byte "DIP SWITCH SETTINGS"
L222F: .byte "DISPLAY TEST"
L223C: .byte "MEMORY TEST"
L227E: .byte "SWITCH CLOSED"
L228F: .byte "ALL SWITCHES OPEN"
L22A1: .byte " -MIN O-SEC"
L22AE: .byte "LAMP- "
L22B5: .byte "SOLENOID- "
L22C0: .byte "BOOKKEEPING CLEARED"
L22D4: .byte "*SEE SERVICE MANUAL*"
L22ED: .byte "0123456789ABCDEF"
L2301: .byte "ERROR- U4"
L230B: .byte "ERROR- U5"
L2315: .byte "ERROR- U6"
L231F: .byte "ERROR- Z5"
L2329: .byte "ERROR- GAME PROM 1"
L233C: .byte "ERROR- GAME PROM.2"
L234F: .byte "GAME PROM CHECK-SUM"
L2363: .byte "PROM 1- "
L2370: .byte "ENTER INITIALS (6O)"
L2385: .byte "PLAYER -A "
L239D: .byte "SQUADRON LEADERS "
L24A3: .byte "*** RED ALERT ***"
L24B5: .byte "FLIGHT QUARTERS"
Answered via the link. Basically Saturday 5 to 10. If I come in Sunday, I may want to go to the board meeting. I also plan to be at Dwightās meeting tonightā¦
My favourite kind!
(Maybe thereās something wrong with meā¦)
The two missing bytes later in the file are the result of more absolute versus zero page addressing mode issues:
3CBE ldx L006D
3D1F lda L006D
The naive answer is to move the equate for this label to the end of the file to force absolute mode due to forward reference. But other instructions, like
2677 sta L006D
use zero page addressing.
So we are going to need an assembler which allows us to force the addressing mode.
Iāve submitted a meeting on the DMS Calendar for this Saturday 6/25 at 5:15 PM in the conference room so we can discuss this further. For instance, the DIS6502 showed me all those strings from $20E5 to $24C2, and I havenāt found any more other than *** TILT ***. I havenāt seen anything that references these addresses directly, so it must be loading these in with some sort of indexed memory offset.
Also Bill, Iāll be at the Space on Tuesday from 6:30-9, and will be available at maybe 8 or so to talk about this more in person.
Itād be neat to find a simulator that could handle the RIOT chips and see what theyāre doing. Plugging this into a general-purpose simulator might get pretty weird unless itās highly configurable. Of course, itād be cool if it knew how the VFD driver worked and could actually display the output on-screen. Otherwise, without the ability to input anything to the RIOT chips, I bet youād only ever see the outputs flash by pertaining to driving the attract mode on the display rather than playing a game.
Iāll be in Tuesday for the Android Programming class. How late I can stay will depend on the result of a phone call I cannot make until after 5 to see whether I need to report for jury duty Wednesday morning.
I have been looking at the schematic. Is the VFD hooked up to that latch hanging off of U5? If so, L2ADD may be the routine to send a byte to the VFD:
.2ADD 48 01642 L2ADD: pha ; Save byte
.2ADE 09 30 01643 ora #$30 ; LD1 and LD2 high
.2AE0 29 3F 01644 and #$3F
.2AE2 8D 0282 01645 sta RIOTU5_R2_DRB ; Output to latch
.2AE5 A9 10 01646 lda #$10 ; Latch low nybble
.2AE7 8D 0280 01647 sta RIOTU5_R0_DRA
.2AEA A9 00 01648 lda #$00
.2AEC 8D 0280 01649 sta RIOTU5_R0_DRA
.2AEF 68 01650 pla ; Recover byte
.2AF0 20 277B 01651 jsr L277B ; shift upper nybble to lower
.2AF3 09 30 01652 ora #$30 ; LD1 and LD2 high
.2AF5 8D 0282 01653 sta RIOTU5_R2_DRB ; Output to latch
.2AF8 A9 20 01654 lda #$20 ; Latch upper nybble
.2AFA 8D 0280 01655 sta RIOTU5_R0_DRA
.2AFD A9 00 01656 lda #$00
.2AFF 8D 0280 01657 sta RIOTU5_R0_DRA
.2B02 A5 6F 01658 lda L006F ; Do not know what this contains
.2B04 8D 0282 01659 sta RIOTU5_R2_DRB
.2B07 EA 01660 nop
.2B08 EA 01661 nop
.2B09 A9 30 01662 lda #$30 ; LD1 and LD2 high
.2B0B 8D 0282 01663 sta RIOTU5_R2_DRB
.2B0E 60 01664 rts
I have not been able to figure where the data is coming from yet.
I have just cracked where it tends to write various messages to the display. Check out my Wiki page on L315A. It seems to write 20 characters to the first row [$13, $26], and then can do another 20 characters on the second row [$27, $3A]. However, it also seems to have another display āpageā it may evidently choose to switch to later as youāll also see characters written to [$3B, $4E] and [$4F, $62]. This is based on the hard-coded 0x13 used in a zero-page indirect STA instruction, and how X is usually set to 0, 0x14, 0x28, or 0x3C before this subroutine gets called.
I stumbled upon this by total happenstance as I was trying to move code blocks into their own pages and just happened to be curious as to how many times the next label after the preceding JMP or RTS was called. I knew it had to be something good when this was referred to almost 20 times in the code!
I think those memory locations you reference are memory buffers where the display contents are formatted before it is sent to the actual display hardware.
Each RIOT contains 128 bytes of 8-bit RAM. According to the schematic, they are mapped to $0000ā¦$017F.
Hence the stack pointer is loaded with $7F because only half of the stack space has memory in it. The rest of the RAM make up the zero page.
While hardware can be mapped into the zero page, the schematic shows no signs of that. I am still looking at it, but there are indications of code looking at buffers at $00, $28 and $3C using L0070 and L0071 as pointers and blasting their contents to those D flip-flops via the U5 RIOT - I still think that is where the VFD electrically resides.
There is another RAM chip, but it looks to be only 4 bits wide and I have not looked to see where it is mapped.
Just wanted to say it: you guys are awesome for documenting your reverse-engineering effort!