Showing posts with label williams. Show all posts
Showing posts with label williams. Show all posts
Tuesday, July 17, 2018
Star Rider arcade game in action (using Dexter)
Thursday, April 5, 2018
Yet another Star Rider repair
Would you use ice to find a troublesome part on a large board with a lot of generic TTL ICs? Wise people wouldn't. I may not be a wise person.
Sunday, December 3, 2017
Enhancement to Star Rider's Disc Search Test
I've written an enhancement to one of the diagnostic tests that Star Rider provides. I noticed that I could not find any test within the suite of tests that Star Rider offers that tests its biphase decoding. The biphase decoding is used to decode the picture number from the video signal, as well as some other data that occurs at the bottom of the video frame. The game still seems to work (kinda) even if this data is corrupt (I know because I have the game partially emulated in Daphne and I don't provide any of the data aside from the picture number at all). So it's really hard to tell whether the biphase decoder is actually working without a nice test that explicitly shows this.
Here's what my new enhancement does:
It prints five rows and nine columns of hexadecimal bytes, and with CRC-16 values for each row. The reason I show 45 bytes is because this is how many decoded bytes the ROM program seems to care about. A careful observer may notice that the first three bytes of biphase data are always the VBI picture number.
A human can (hopefully) quickly seek to their favorite track on the laserdisc, and look at the CRC-16 values to make sure that the decoded biphase data is correct. If any of the CRC-16 values are off, the human can then examine the larger data set on the left to see where the discrepancy is.
Here are the steps (done from a linux/bash shell) to add my mod to your existing U45 CPU ROM:
- Make sure your U45 ROM matches the one I modded:
$ md5sum r34u45.cpu
810dc65c353259e7fa600e31767fb0dc *r34u45.cpu
- Copy u45 to a new file. In this new file, modify $12FC from JSR $9365 to JSR $9D3D (the location of the new code). (4861 is 0x12FD in decimal)
$ cp r34u45.cpu u45_pre.bin
$ printf '\x9d\x3d' | dd of=u45_pre.bin bs=1 seek=4861 count=2 conv=notrunc
- (optional) check to make sure you are in sync with where I am at this point:
$ md5sum u45_pre.bin
5d86c0618b89ec210d88c748c766ab3c u45_pre.bin
- Change length of file so we can append our new code to the end of it.
$ truncate -s 7485 u45_pre.bin
- Assemble my program (at the end of this blog post) with the asm6809 assembler found here. You can also install it as an ubuntu package ("sudo apt-get install asm6809")
$ asm6809 -9 starrider_discsearch_ex.asm -o starrider_discsearch_ex.bin
- Append assembled binary to the end of the truncated file you made earlier.
$ cat u45_pre.bin starrider_discsearch_ex.bin > u45_new.bin
- Test to make sure the file you ended up with matches mine:
$ md5sum u45_new.bin
3e3d589b53b8b607938545b1e3975752 *u45_new.bin
- Replace the U45 CPU EPROM on your star rider with this image, burned to a new EPROM/EEPROM.
---------------------------
Here is my assembly language program. NOTE that my instructions expect the file to by named 'starrider_discsearch_ex.asm' !
---------------------------
HW_WatchDog equ $c900
BlitLeftToRightIterate equ $5e1b
BlitWithoutSource equ $7fe1
PtrToBigFontBase equ $5fe4
BiPhaseCache equ $a172
InputThinkEtc equ $9365
; at the end of the U51 ram, hopefully using this won't stomp on anything else
OldCrc1 equ $a7ea
OldCrc2 equ $a7ec
OldCrc3 equ $a7ee
OldCrc4 equ $a7f0
OldCrc5 equ $a7f2
Crc1 equ $a7f4
Crc2 equ $a7f6
Crc3 equ $a7f8
Crc4 equ $a7fa
Crc5 equ $a7fc
; points to the next 16-bit address to store a crc calculation
CrcPtr equ $a7fe
; start at the end of U45/ROM5 on star rider where there is some empty room
org $9d3d
; =============== S U B R O U T I N E =======================================
EraseAndRenderBiphaseDataIfNeeded
; preserve all
pshs a,b,x,y,u
; calculate CRC values so we can tell whether anything's changed
ldx #Crc1
stx CrcPtr
lda #9 ; size of array for CRC calculation
ldy #BiPhaseCache
jsr CalcCrc
ldy #BiPhaseCache+9
jsr CalcCrc
ldy #BiPhaseCache+18
jsr CalcCrc
ldy #BiPhaseCache+27
jsr CalcCrc
ldy #BiPhaseCache+36
jsr CalcCrc
; now compare CRC values to see if any have changed
ldx Crc1
cmpx OldCrc1
bne DisplayDataIsInvalid
ldx Crc2
cmpx OldCrc2
bne DisplayDataIsInvalid
ldx Crc3
cmpx OldCrc3
bne DisplayDataIsInvalid
ldx Crc4
cmpx OldCrc4
bne DisplayDataIsInvalid
ldx Crc5
cmpx OldCrc5
bne DisplayDataIsInvalid
; if we get this far, CRCs still match so nothing to do
jmp Done
DisplayDataIsInvalid
; update old crc values so that we don't keep re-rendering if nothing has changed
ldx Crc1
stx OldCrc1
ldx Crc2
stx OldCrc2
ldx Crc3
stx OldCrc3
ldx Crc4
stx OldCrc4
ldx Crc5
stx OldCrc5
ldx #$10B0 ; starting coordinates
lda #9 ; bytes to render
ldb #$44 ; white
ldu #PtrToBigFontBase
ldy #BiPhaseCache ; biphase RAM cache start
; one-time erase
jsr EraseBiphaseArea
jsr RenderHexDigits
ldx #$10BA ; starting coordinates
lda #9 ; bytes to render
ldb #$44 ; white
ldu #PtrToBigFontBase
ldy #BiPhaseCache+9
jsr RenderHexDigits
ldx #$10C4 ; starting coordinates
lda #9 ; bytes to render
ldb #$44 ; white
ldu #PtrToBigFontBase
ldy #BiPhaseCache+18
jsr RenderHexDigits
ldx #$10CE ; starting coordinates
lda #9 ; bytes to render
ldb #$44 ; white
ldu #PtrToBigFontBase
ldy #BiPhaseCache+27
jsr RenderHexDigits
ldx #$10D8 ; starting coordinates
lda #9 ; bytes to render
ldb #$44 ; white
ldu #PtrToBigFontBase
ldy #BiPhaseCache+36
jsr RenderHexDigits
; now render each CRC value
ldx #$70B0 ; starting coordinates
lda #2 ; bytes to render
ldb #$44 ; white
ldu #PtrToBigFontBase
ldy #Crc1 ; biphase RAM cache start
jsr RenderHexDigits
ldx #$70BA ; starting coordinates
lda #2 ; bytes to render
ldb #$44 ; white
ldu #PtrToBigFontBase
ldy #Crc2 ; biphase RAM cache start
jsr RenderHexDigits
ldx #$70C4 ; starting coordinates
lda #2 ; bytes to render
ldb #$44 ; white
ldu #PtrToBigFontBase
ldy #Crc3 ; biphase RAM cache start
jsr RenderHexDigits
ldx #$70CE ; starting coordinates
lda #2 ; bytes to render
ldb #$44 ; white
ldu #PtrToBigFontBase
ldy #Crc4 ; biphase RAM cache start
jsr RenderHexDigits
ldx #$70D8 ; starting coordinates
lda #2 ; bytes to render
ldb #$44 ; white
ldu #PtrToBigFontBase
ldy #Crc5 ; biphase RAM cache start
jsr RenderHexDigits
Done
; restore all
puls u,y,x,b,a
; go to where the program went before we hijacked the flow
jmp InputThinkEtc
; End of function EraseAndRender6DigitsWithBigFont
; =============== S U B R O U T I N E =======================================
; X: starting coordinates (upper-left)
EraseBiphaseArea
pshs a,b,x,y,u
ldd #$12FF ; solid color FF
ldy #$7032 ; 112 x 50
leax -1,x ; move Y dest up one pixel
jsr BlitWithoutSource ; Performs a blit where the source does not matter (solid color is typical use case).
; Y: width (msb) and height (lsb)
; X: destination video address
; D: control byte (msb) and solid color byte (lsb)
; IMPG and YLATE are set to 0.
puls pc,u,y,x,b,a
; End of function EraseDigitWithColorF
; =============== S U B R O U T I N E =======================================
; Renders the hex value pointed to by Y
; X: destination to render digit
; A: how many bytes to render
; Y: bytes to render
; B: the color
; U: the font set
RenderHexDigits
deca
pshs a
clr ,-s ; not used, left here to avoid errors
; feed watchdog
lda #$15
sta HW_WatchDog
RenderHiNibble
lda ,y
lsra ; shift nibble to low position
lsra
lsra
lsra
bsr RenderHexDigit
; A: digit to be rendered
; X: coordinate to render to
; B: color to render
; U: font to use
RenderLoNibble
lda ,y+
anda #$F
bsr RenderHexDigit
; A: digit to be rendered
; X: coordinate to render to
; B: color to render
; U: font to use
dec 1,s ; decrement counter
bpl RenderHiNibble ; if we're not done, loop
leas 2,s ; de-allocate temporary stack space
rts
; End of function RenderDigitsNoLeadingZeroes
; =============== S U B R O U T I N E =======================================
; Renders digit
; A: digit to be rendered
; X: coordinate to render to
; B: color to render
; U: font to use
RenderHexDigit
cmpa #$A
bmi RenderDigit ; branch if we're within range of 0-9
inca ; font A-F is 0xb-0x10, so increment A once to render properly
RenderDigit
jsr BlitLeftToRightIterate ; Part of a left-to-right blit loop
;
; X contains the destination address and will be modified to point to the next one on exit
; U points to a pointer that points to the beginning of font info for the first character. Each entry contains a width/height byte (width is one nibble, height is another), followed by the source DMA address where the character bitmap lives.
; A contains the character to render (non-ascii, 0 is the first character)
; B contains solid color value
rts
; =============== S U B R O U T I N E =======================================
; A: number of bytes in the array
; Y: ptr to beginning of array
; CrcPtr: points to where final CRC value will be stored
; All registers are preserved, CrcPtr will be advanced by 2
CalcCrc
pshs a,b,x,y,u
; we'll access the counter via memory instead of having it in a register
pshs a
; feed watchdog
lda #$15
sta HW_WatchDog
; load address to store CRC
ldx CrcPtr
ldd #$FFFF ; initial seed value
std ,x
CalcCrcLoop
jsr CalcCrcUpdate
; decrement counter
dec ,s
; if we're not done yet, then keep going
bne CalcCrcLoop
CalcCrcDone
; pop the counter value
leas 1,s
; advance crc pointer for next calculation
leax 2,x
stx CrcPtr
puls pc,u,y,x,b,a
; =============== S U B R O U T I N E =======================================
; existing crc is in memory location pointed to by X, next byte is pointed to by Y
; Here is the C version of this function for reference:
; crc_ccitt_update(unsigned char x)
; {
; uint16_t crc_new = (unsigned char)(g_crc >> 8) | (g_crc << 8);
; crc_new ^= x;
; crc_new ^= (unsigned char)(crc_new & 0xff) >> 4;
; crc_new ^= crc_new << 12;
; crc_new ^= (crc_new & 0xff) << 5;
; g_crc = crc_new;
; }
CalcCrcUpdate
; grab current crc value
ldd ,x
; swap top and bottom bytes
exg a,b
; xor bottom byte with new byte, advance y
eorb ,y+
; store new value so we can do more maths on it
std ,x
; (crc_new & 0xFF) >> 4
clra ; this instruction may not be needed, double-check
lsrb
lsrb
lsrb
lsrb
; crc_new ^= (previous val)
eorb 1,x
stb 1,x
; (crc_new << 12)
; NOTE : b already contains the right value so we don't need to load it from memory
tfr b,a
lsla
lsla
lsla
lsla
; crc_new ^= (previous_val)
eora 0,x
sta 0,x
; (crc_new & 0xFF) << 5
clra
; b still contains the right value so we don't need to load it
lslb
rola
lslb
rola
lslb
rola
lslb
rola
lslb
rola
; crc_new ^= (previous_val)
eora 0,x
eorb 1,x
; store finished value
std ,x
rts
; ---------------------------------------------------------------------
; force a specific file size
org $9fff
fcb 0
Here's what my new enhancement does:
It prints five rows and nine columns of hexadecimal bytes, and with CRC-16 values for each row. The reason I show 45 bytes is because this is how many decoded bytes the ROM program seems to care about. A careful observer may notice that the first three bytes of biphase data are always the VBI picture number.
A human can (hopefully) quickly seek to their favorite track on the laserdisc, and look at the CRC-16 values to make sure that the decoded biphase data is correct. If any of the CRC-16 values are off, the human can then examine the larger data set on the left to see where the discrepancy is.
Here are the steps (done from a linux/bash shell) to add my mod to your existing U45 CPU ROM:
- Make sure your U45 ROM matches the one I modded:
$ md5sum r34u45.cpu
810dc65c353259e7fa600e31767fb0dc *r34u45.cpu
- Copy u45 to a new file. In this new file, modify $12FC from JSR $9365 to JSR $9D3D (the location of the new code). (4861 is 0x12FD in decimal)
$ cp r34u45.cpu u45_pre.bin
$ printf '\x9d\x3d' | dd of=u45_pre.bin bs=1 seek=4861 count=2 conv=notrunc
- (optional) check to make sure you are in sync with where I am at this point:
$ md5sum u45_pre.bin
5d86c0618b89ec210d88c748c766ab3c u45_pre.bin
- Change length of file so we can append our new code to the end of it.
$ truncate -s 7485 u45_pre.bin
- Assemble my program (at the end of this blog post) with the asm6809 assembler found here. You can also install it as an ubuntu package ("sudo apt-get install asm6809")
$ asm6809 -9 starrider_discsearch_ex.asm -o starrider_discsearch_ex.bin
- Append assembled binary to the end of the truncated file you made earlier.
$ cat u45_pre.bin starrider_discsearch_ex.bin > u45_new.bin
- Test to make sure the file you ended up with matches mine:
$ md5sum u45_new.bin
3e3d589b53b8b607938545b1e3975752 *u45_new.bin
- Replace the U45 CPU EPROM on your star rider with this image, burned to a new EPROM/EEPROM.
---------------------------
Here is my assembly language program. NOTE that my instructions expect the file to by named 'starrider_discsearch_ex.asm' !
---------------------------
HW_WatchDog equ $c900
BlitLeftToRightIterate equ $5e1b
BlitWithoutSource equ $7fe1
PtrToBigFontBase equ $5fe4
BiPhaseCache equ $a172
InputThinkEtc equ $9365
; at the end of the U51 ram, hopefully using this won't stomp on anything else
OldCrc1 equ $a7ea
OldCrc2 equ $a7ec
OldCrc3 equ $a7ee
OldCrc4 equ $a7f0
OldCrc5 equ $a7f2
Crc1 equ $a7f4
Crc2 equ $a7f6
Crc3 equ $a7f8
Crc4 equ $a7fa
Crc5 equ $a7fc
; points to the next 16-bit address to store a crc calculation
CrcPtr equ $a7fe
; start at the end of U45/ROM5 on star rider where there is some empty room
org $9d3d
; =============== S U B R O U T I N E =======================================
EraseAndRenderBiphaseDataIfNeeded
; preserve all
pshs a,b,x,y,u
; calculate CRC values so we can tell whether anything's changed
ldx #Crc1
stx CrcPtr
lda #9 ; size of array for CRC calculation
ldy #BiPhaseCache
jsr CalcCrc
ldy #BiPhaseCache+9
jsr CalcCrc
ldy #BiPhaseCache+18
jsr CalcCrc
ldy #BiPhaseCache+27
jsr CalcCrc
ldy #BiPhaseCache+36
jsr CalcCrc
; now compare CRC values to see if any have changed
ldx Crc1
cmpx OldCrc1
bne DisplayDataIsInvalid
ldx Crc2
cmpx OldCrc2
bne DisplayDataIsInvalid
ldx Crc3
cmpx OldCrc3
bne DisplayDataIsInvalid
ldx Crc4
cmpx OldCrc4
bne DisplayDataIsInvalid
ldx Crc5
cmpx OldCrc5
bne DisplayDataIsInvalid
; if we get this far, CRCs still match so nothing to do
jmp Done
DisplayDataIsInvalid
; update old crc values so that we don't keep re-rendering if nothing has changed
ldx Crc1
stx OldCrc1
ldx Crc2
stx OldCrc2
ldx Crc3
stx OldCrc3
ldx Crc4
stx OldCrc4
ldx Crc5
stx OldCrc5
ldx #$10B0 ; starting coordinates
lda #9 ; bytes to render
ldb #$44 ; white
ldu #PtrToBigFontBase
ldy #BiPhaseCache ; biphase RAM cache start
; one-time erase
jsr EraseBiphaseArea
jsr RenderHexDigits
ldx #$10BA ; starting coordinates
lda #9 ; bytes to render
ldb #$44 ; white
ldu #PtrToBigFontBase
ldy #BiPhaseCache+9
jsr RenderHexDigits
ldx #$10C4 ; starting coordinates
lda #9 ; bytes to render
ldb #$44 ; white
ldu #PtrToBigFontBase
ldy #BiPhaseCache+18
jsr RenderHexDigits
ldx #$10CE ; starting coordinates
lda #9 ; bytes to render
ldb #$44 ; white
ldu #PtrToBigFontBase
ldy #BiPhaseCache+27
jsr RenderHexDigits
ldx #$10D8 ; starting coordinates
lda #9 ; bytes to render
ldb #$44 ; white
ldu #PtrToBigFontBase
ldy #BiPhaseCache+36
jsr RenderHexDigits
; now render each CRC value
ldx #$70B0 ; starting coordinates
lda #2 ; bytes to render
ldb #$44 ; white
ldu #PtrToBigFontBase
ldy #Crc1 ; biphase RAM cache start
jsr RenderHexDigits
ldx #$70BA ; starting coordinates
lda #2 ; bytes to render
ldb #$44 ; white
ldu #PtrToBigFontBase
ldy #Crc2 ; biphase RAM cache start
jsr RenderHexDigits
ldx #$70C4 ; starting coordinates
lda #2 ; bytes to render
ldb #$44 ; white
ldu #PtrToBigFontBase
ldy #Crc3 ; biphase RAM cache start
jsr RenderHexDigits
ldx #$70CE ; starting coordinates
lda #2 ; bytes to render
ldb #$44 ; white
ldu #PtrToBigFontBase
ldy #Crc4 ; biphase RAM cache start
jsr RenderHexDigits
ldx #$70D8 ; starting coordinates
lda #2 ; bytes to render
ldb #$44 ; white
ldu #PtrToBigFontBase
ldy #Crc5 ; biphase RAM cache start
jsr RenderHexDigits
Done
; restore all
puls u,y,x,b,a
; go to where the program went before we hijacked the flow
jmp InputThinkEtc
; End of function EraseAndRender6DigitsWithBigFont
; =============== S U B R O U T I N E =======================================
; X: starting coordinates (upper-left)
EraseBiphaseArea
pshs a,b,x,y,u
ldd #$12FF ; solid color FF
ldy #$7032 ; 112 x 50
leax -1,x ; move Y dest up one pixel
jsr BlitWithoutSource ; Performs a blit where the source does not matter (solid color is typical use case).
; Y: width (msb) and height (lsb)
; X: destination video address
; D: control byte (msb) and solid color byte (lsb)
; IMPG and YLATE are set to 0.
puls pc,u,y,x,b,a
; End of function EraseDigitWithColorF
; =============== S U B R O U T I N E =======================================
; Renders the hex value pointed to by Y
; X: destination to render digit
; A: how many bytes to render
; Y: bytes to render
; B: the color
; U: the font set
RenderHexDigits
deca
pshs a
clr ,-s ; not used, left here to avoid errors
; feed watchdog
lda #$15
sta HW_WatchDog
RenderHiNibble
lda ,y
lsra ; shift nibble to low position
lsra
lsra
lsra
bsr RenderHexDigit
; A: digit to be rendered
; X: coordinate to render to
; B: color to render
; U: font to use
RenderLoNibble
lda ,y+
anda #$F
bsr RenderHexDigit
; A: digit to be rendered
; X: coordinate to render to
; B: color to render
; U: font to use
dec 1,s ; decrement counter
bpl RenderHiNibble ; if we're not done, loop
leas 2,s ; de-allocate temporary stack space
rts
; End of function RenderDigitsNoLeadingZeroes
; =============== S U B R O U T I N E =======================================
; Renders digit
; A: digit to be rendered
; X: coordinate to render to
; B: color to render
; U: font to use
RenderHexDigit
cmpa #$A
bmi RenderDigit ; branch if we're within range of 0-9
inca ; font A-F is 0xb-0x10, so increment A once to render properly
RenderDigit
jsr BlitLeftToRightIterate ; Part of a left-to-right blit loop
;
; X contains the destination address and will be modified to point to the next one on exit
; U points to a pointer that points to the beginning of font info for the first character. Each entry contains a width/height byte (width is one nibble, height is another), followed by the source DMA address where the character bitmap lives.
; A contains the character to render (non-ascii, 0 is the first character)
; B contains solid color value
rts
; =============== S U B R O U T I N E =======================================
; A: number of bytes in the array
; Y: ptr to beginning of array
; CrcPtr: points to where final CRC value will be stored
; All registers are preserved, CrcPtr will be advanced by 2
CalcCrc
pshs a,b,x,y,u
; we'll access the counter via memory instead of having it in a register
pshs a
; feed watchdog
lda #$15
sta HW_WatchDog
; load address to store CRC
ldx CrcPtr
ldd #$FFFF ; initial seed value
std ,x
CalcCrcLoop
jsr CalcCrcUpdate
; decrement counter
dec ,s
; if we're not done yet, then keep going
bne CalcCrcLoop
CalcCrcDone
; pop the counter value
leas 1,s
; advance crc pointer for next calculation
leax 2,x
stx CrcPtr
puls pc,u,y,x,b,a
; =============== S U B R O U T I N E =======================================
; existing crc is in memory location pointed to by X, next byte is pointed to by Y
; Here is the C version of this function for reference:
; crc_ccitt_update(unsigned char x)
; {
; uint16_t crc_new = (unsigned char)(g_crc >> 8) | (g_crc << 8);
; crc_new ^= x;
; crc_new ^= (unsigned char)(crc_new & 0xff) >> 4;
; crc_new ^= crc_new << 12;
; crc_new ^= (crc_new & 0xff) << 5;
; g_crc = crc_new;
; }
CalcCrcUpdate
; grab current crc value
ldd ,x
; swap top and bottom bytes
exg a,b
; xor bottom byte with new byte, advance y
eorb ,y+
; store new value so we can do more maths on it
std ,x
; (crc_new & 0xFF) >> 4
clra ; this instruction may not be needed, double-check
lsrb
lsrb
lsrb
lsrb
; crc_new ^= (previous val)
eorb 1,x
stb 1,x
; (crc_new << 12)
; NOTE : b already contains the right value so we don't need to load it from memory
tfr b,a
lsla
lsla
lsla
lsla
; crc_new ^= (previous_val)
eora 0,x
sta 0,x
; (crc_new & 0xFF) << 5
clra
; b still contains the right value so we don't need to load it
lslb
rola
lslb
rola
lslb
rola
lslb
rola
lslb
rola
; crc_new ^= (previous_val)
eora 0,x
eorb 1,x
; store finished value
std ,x
rts
; ---------------------------------------------------------------------
; force a specific file size
org $9fff
fcb 0
Saturday, November 18, 2017
Star Rider repair video (Ed Beeler's second CPU board!)
Here's another Star Rider CPU repair video. This was a very challenging problem to solve!
FALSE ASSUMPTIONS ABOUT CAUSE OF PROBLEM:
-----------------------------------------
- turning on board while it was wet damaged something
- cpu was bad
- rom was bad
- 74LS245 was bad
- an unknown malfunctioning component on the board was interfering with the data bus
ACTUAL CAUSES OF PROBLEMS:
------------------------
- CPU RAM was bad (first problem)
- Two traces on the PCB were broken, causing corruption on both the data bus and address bus. (second problem)
Wednesday, March 9, 2016
Star Rider's initial color 'test' is almost useless
Unless you own a Star Rider arcade game or are fairly familiar with it, you probably don't have any idea of what happens when the game is powered on.
Well, let me tell you. The first thing that happens is the video RAM is filled with a solid color. This fill is performed by the CPU and is quite slow. This loops through the entire color palette (16 colors) and adds a significant amount of time to the overall boot time. I had always assumed that this test was testing to see whether the video RAM was any good. But after revisiting this test recently, I discovered that the code does not actually check to see whether the value that it stored can be read back. So how useful is this test? The only use that I can see is if a human is watching the monitor while the test is running and is familiar enough with what is supposed to be shown to spot a problem. But really, there is no excuse for the CPU to not read back what it wrote and save the human from this kind of trouble.
Here's the relevant code:
ROM:F15F WhileBigColorFillNotDone: ; CODE XREF: GoCmpCC07AndFWith9+163 j
ROM:F15F ldx #RamStartA000 ; fill all video memory with a single color (go through palette)
ROM:F162
ROM:F162 Fill9FFFto0WithY: ; CODE XREF: GoCmpCC07AndFWith9+15D j
ROM:F162 ldb #$15
ROM:F164 lda #8
ROM:F166
ROM:F166 WatchdogThink: ; CODE XREF: GoCmpCC07AndFWith9+155 j
ROM:F166 stb HW_Watchdog ; this address has something to do with watchdog timer
ROM:F169 deca
ROM:F16A bne WatchdogThink
ROM:F16C sty ,-x ; this appears to be inefficient; since we are storing 2 bytes at a time, X could be decremented by 2 instead of just 1.
ROM:F16F cmpx #0
ROM:F172 bne Fill9FFFto0WithY
ROM:F174 leay $EEEF,y ; subtract by 1111h (so FFFFh becomes EEEEh)
ROM:F178 bne WhileBigColorFillNotDone ; fill all video memory with a single color (go through palette)
ROM:F17A lda #2
ROM:F17C ldy #PostRugTestBoot
ROM:F180 jmp RugPatternTest ; Does Rug Pattern test, jumps to address in Y when finished.
ROM:F180 ; Carry may be set if test failed.
NOTE at $F16A the loop to 'feed' the watch dog. I don't fully understand what is needed to keep the watch dog from barking, but I'd be willing to bet that this loop is completely unnecessary. Also, $F16C writes two bytes but only decrements its index by 1. I can see no reason why it wouldn't decrement by 2 here and accomplish the same thing. Not only is this test slow because it is using the CPU to write to video RAM, but it is slow because it is wasting time for no good reason.
Changes that I would make to this test: completely skip it :) The rug pattern test also tests video RAM so this test is redundant.
Well, let me tell you. The first thing that happens is the video RAM is filled with a solid color. This fill is performed by the CPU and is quite slow. This loops through the entire color palette (16 colors) and adds a significant amount of time to the overall boot time. I had always assumed that this test was testing to see whether the video RAM was any good. But after revisiting this test recently, I discovered that the code does not actually check to see whether the value that it stored can be read back. So how useful is this test? The only use that I can see is if a human is watching the monitor while the test is running and is familiar enough with what is supposed to be shown to spot a problem. But really, there is no excuse for the CPU to not read back what it wrote and save the human from this kind of trouble.
Here's the relevant code:
ROM:F15F WhileBigColorFillNotDone: ; CODE XREF: GoCmpCC07AndFWith9+163 j
ROM:F15F ldx #RamStartA000 ; fill all video memory with a single color (go through palette)
ROM:F162
ROM:F162 Fill9FFFto0WithY: ; CODE XREF: GoCmpCC07AndFWith9+15D j
ROM:F162 ldb #$15
ROM:F164 lda #8
ROM:F166
ROM:F166 WatchdogThink: ; CODE XREF: GoCmpCC07AndFWith9+155 j
ROM:F166 stb HW_Watchdog ; this address has something to do with watchdog timer
ROM:F169 deca
ROM:F16A bne WatchdogThink
ROM:F16C sty ,-x ; this appears to be inefficient; since we are storing 2 bytes at a time, X could be decremented by 2 instead of just 1.
ROM:F16F cmpx #0
ROM:F172 bne Fill9FFFto0WithY
ROM:F174 leay $EEEF,y ; subtract by 1111h (so FFFFh becomes EEEEh)
ROM:F178 bne WhileBigColorFillNotDone ; fill all video memory with a single color (go through palette)
ROM:F17A lda #2
ROM:F17C ldy #PostRugTestBoot
ROM:F180 jmp RugPatternTest ; Does Rug Pattern test, jumps to address in Y when finished.
ROM:F180 ; Carry may be set if test failed.
NOTE at $F16A the loop to 'feed' the watch dog. I don't fully understand what is needed to keep the watch dog from barking, but I'd be willing to bet that this loop is completely unnecessary. Also, $F16C writes two bytes but only decrements its index by 1. I can see no reason why it wouldn't decrement by 2 here and accomplish the same thing. Not only is this test slow because it is using the CPU to write to video RAM, but it is slow because it is wasting time for no good reason.
Changes that I would make to this test: completely skip it :) The rug pattern test also tests video RAM so this test is redundant.
Subscribe to:
Posts (Atom)