My 6502 Disassembly Project

Thanks Zach. :slight_smile: Good to know someone enjoys the constant activity on this thread!

Bill, I added some documentation to the BitBucket repository. The manual describes how the MPU is linked to the display board that has two 20-character VFDs and is described on pages 36, 37, and 38.

Thatā€™s really fascinating about how the RIOT chips handle the zero-page memory but they donā€™t populate the board with enough memory for the full page 1 stack. Iā€™m not sure what is buffered right at $00, but based on last nightā€™s exploration, it seems like $13ā€¦$26 is line 1 of page 1; $27ā€¦$3A is line 2 of page 1, and so forth as I described above. These are held by the D flip flops and then buffered into various digit drivers and segment drivers (10939 and 10941 respectively).

Also, the other RAM chip is a P5101 CMOS and is indeed 256 x 4 bits wide. According to the service manual (which comes from a slightly different system architecture), it is used to store ā€œ[d]ata which must be retained when the game is turned offā€ and its address lines are ā€œprovided directly off the address bus from the microprocessor.ā€ As youā€™re looking at the 5101 in the schematic, look down at the ā€œPROM SELECTIONā€ section to see how some of the signals feeding into the chip enable pins are calculated. Iā€™d imagine this includes things like high scores and bookkeeping/auditing data, so if you can glean where in the code it shows those sorts of things, youā€™d also be able to deduce the memory space of the 5101.

1 Like

It would be easier for me to study the decoding gates on the schematic to figure out the address. I have not needed to know so have not bothered.

Off the BitBucket againā€¦

This is where Iā€™d use the Fluke 9010A and the 6502 pod to search and identify all ROM and RAM addresses. :slight_smile:

Someone else would have to do that since I do not possess the hardware in question.

Does DMS even have a Fluke 9010A and if so, what pods?

They do not.

I personally own one with 6800, 6802, 6809, 6502, 8080, 8085, 8086, 8088, 80188, 68000, and z80 pods.

Raymond

2 Likes

Thanks for the manuals. There is some interesting reading in there.

That 4-bit wide RAM is for ā€œbookkeepingā€ data.

I may have to take a shot at emulating the control board along with the switch matrix and a display to play with the run-time behavior of the diagnostic and bookkeeping parts of the code.

1 Like

That 4-bit wide RAM is for ā€œbookkeepingā€ data.

I recently ran across a bit of test equipment which had an odd setup like this. Only the lower half of the data bus was hooked up to a battery-backed SRAM. This was calibration data, which the instrumentā€™s code obviously used only the low nibble for storage. Iā€™m guessing this was a special low-leakage, expensive (at the time) part, so they only used one IC.

I have the full memory map that Iā€™m going to add to the wiki, which Iā€™ve cloned. Any recommendations for a markdown editor with preview mode that is also navigable?

I was talking with Art Givens last night. He had been following our discussion because he has a system which uses a VFD and he has a spare unit he would like to know how to use in another project. I told him what I thought I knew at the time and started looking into the manuals for more information about the display board.

The control board has an 8-bit latch, a reset signal and a couple of handshaking lines between it and the display board.

The display board is based on two 10939 digit drivers and a 10941 segment driver. The data and handshaking lines from the control board go into the 10939 digit drivers. A search reveals that datasheets for the drivers are available; I downloaded this one: http://www.datasheetarchive.com/dl/Scans-007/Scans-00147854.pdf

One handshaking line, when toggled, loads the data into one row of the display; the other for the other row. It is looking like LD1 and LD2 are active low and the contents of L006F tells L2ADD which row to load.

@Bill @denzuko @urbite ICYMI I posted a meeting for us and potentially other 6502 enthusiasts to the DMS calendar for tonight starting at 5:15. Iā€™m not expecting anyone else to show up but will still come prepared anyway.

1 Like

Any revelations or eurekas from Saturdays meetup?

I added a memory map page to the wiki. When I have a chance Iā€™ll add a detailed description of the decoding logic.

1 Like

Weā€™re now watching your increasingly red-shifted image approach the black hole. I think youā€™ve passed this projects PNR. :slight_smile:

2 Likes

If you have a few hours before an event, donā€™t take a nap without setting an alarm. I was late.

We talked about our different individual approaches to the problem and whether we think we are on the right track to make progress. We felt no immediate course corrections were needed.

Stephen is starting with the known entry points: the reset and IRQ vectors. My approach is to look for text strings for context and then to attack the parts of the system using them. So far, we are not duplicating our efforts much.

The manuals contain good information if you have not looked at them yet.

Neither of us took notes; more as I remember itā€¦

We may meet again in a couple of weeks.

Anybody know of a reason for code to start a timer in a RIOT twice in rapid succession?

Like this:

.257B A9 3C		  00956	            lda #$3C
.257D 8D 029D		  00957	            sta RIOTU5_R1D_WTDIV8DI
.2580 8D 029D		  00958	            sta RIOTU5_R1D_WTDIV8DI

Iā€™m guessing thereā€™s some errata, most likely anecdotal, that requires successive writes to this register for proper operation. In examining the code, there are three different places where successive writes to the same RIOT occur - twice for U5 and once for U4.

Note that the following output is from my 6502 disassembler written around 1990 for NES code study, so doesnā€™t match @Billā€™s format

257B = A9 3C             LDA #$3C        
257D = 8D 9D 02          STA RIOTU5_R1D_WTDIV8DI
2580 = 8D 9D 02          STA RIOTU5_R1D_WTDIV8DI
....
285F = A9 3C             LDA #$3C        
2861 = 8D 9D 02          STA RIOTU5_R1D_WTDIV8DI
2864 = 8D 9D 02          STA RIOTU5_R1D_WTDIV8DI
....
298A = A9 78             LDA #$78        
298C = 8D 1D 02          STA RIOTU4_R1D_WTDIV8DI
298F = 8D 1D 02          STA RIOTU4_R1D_WTDIV8DI
1 Like

There are errors in all of the definitions for registers 1D-1F for all three RIOT chips. Writing to these registers sets the timer period and divider as well as enabling the timer interrupt. These errors are of the copy/paste kind, and were erroneous when I provided them to @mrcity.

Here are the corrected definitions from my disassembler control file. As you can see, for all of the redundant timer loads the interrupts are being enabled instead of disabled - which makes more sense than disabling upon timer loading.

defsym RIOTU4_R1C_WTDIV1EI 021C dabsop
defsym RIOTU4_R1D_WTDIV8EI 021D dabsop
defsym RIOTU4_R1E_WTDIV64EI 021E dabsop
defsym RIOTU4_R1F_WTD1024EI 021F dabsop

defsym RIOTU5_R1C_WTDIV1EI 029C dabsop
defsym RIOTU5_R1D_WTDIV8EI 029D dabsop
defsym RIOTU5_R1E_WTDIV64EI 029E dabsop
defsym RIOTU5_R1F_WTD1024EI 029F dabsop

defsym RIOTU6_R1C_WTDIV1EI 031C dabsop
defsym RIOTU6_R1D_WTDIV8EI 031D dabsop
defsym RIOTU6_R1E_WTDIV64EI 031E dabsop
defsym RIOTU6_R1F_WTD1024EI 031F dabsop
1 Like

The first instance for U5 is in the original startup code; the second is in the IRQ handler. I believe the U5 timer is used to generate a periodic interrupt for updating the text on the VFD.

My code snippets are from the listing generated by running Stephenā€™s disassembly through my cross assembler. I find I can better follow the code with the addresses along the left margin.

Good stuff, Paul. I have been curious about the behavior of these registers.

Correct me if Iā€™m wrong: When we write to a timer, that timer will then put the desired count into its register and then decrement the count, throwing an interrupt when it rolls over. The timer is divided by /1, /8, /64, or /1024, as dictated by which register the timer value was written to. The timerā€™s clock cycle is calculated based on the clock coming in through Ƙ2. (Bonus: Why would we want to write a timer but then disable the interrupt? And why would we ever want to read from register C to read the timer and enable the interrupt, besides in the odd case you care about it counting down from 255 after it just counted down from your number?)

Reads to register 5 on any RIOT will tell you if the timer (bit 7) or if the PA7 edge-detect flag (bit 6) has been triggered. Writing to registers 4-7 on any RIOT will set how the PA7 edge-detect behaves, enabling or disabling rising- or falling-edge interrupts.

Bill, you might be interested to know that in a lot of cases, new stuff to display on the VFD quickly ā€œslidesā€ in from the right to give it a fast scrolling effect. I havenā€™t paid close enough attention to see if it blanks the screen before sliding in new text, or if the original text stays put for the new text to slide over. Iā€™d imagine it blanks the original text in order to further enhance the visual stimulus.

Paul, since you modified your disassembler control file, please check it into the BitBucket so I can take advantage of the latest symbols. :slight_smile:

I am about to conclude that the bookkeeping RAM is at $1800. It is very incompletely decoded, so it also shows up at $1900, $1A00, $1B00, $1C00, $1D00, $1E00, $1F00, $5800, $5900, and so on.

Check out the Wiki article for L346E. There are some places where $1800 + X is referred to; the subroutine called by this code seems to store stuff in $1800+X, $183B+X, and $1876+X. I canā€™t recall nor imagine what things would need to be stored 3 times, but whatā€™s interesting is it seems to switch to BCD mode, perhaps so as to store something directly convertible to two base-10 digits.