Jump to content

Removing startup artifacts of "improved" ROM SE/30!!!


Recommended Posts

Thanks to the amazing efforts of dougg3 and others on this group, I'm on the way of putting a "decent" display during the startup of a SE/30 with alternative ROM...

7352826788_fb389dc285_z.jpg

As specified on flickr's caption, that SE/30 has no disk drive at all -- floppy, HD or CD. Only the Jolly Roger ROM SIMM, which in turn has no trace of any original Apple ROM: just that (very sinister) picture of me, a sampled sound and the (tiny) code to show them. I wrote the display part, and the sound playing code came from Doug's custom startup sound ROM.

 

Still there are things to smooth out, though. Despite the code being well tried and tested, the sound is heavily distorted :?: ; something doesn't match well my own code, or it just need some other initialisation -- this ROM does nothing else!

 

But it's a start. It can be done. 8-)

Link to post
Share on other sites

VERY 8-) there, z! For the next rev, swap the spectacles for an eye-patch and substitute a famous pirate movie parrot's cackling rendition of an appropriate line! [;)]]'>

 

I can cheer you buccaneers on from the sidelines, but I'm clueless when it comes to your level of hacking. [:I]]'>

Link to post
Share on other sites

Awesome!! BTW, zuiko21 is the first one to test out my Mac ROM SIMM programmer board, and it seems to be working for him!

 

I'm not sure why the sound is distorted. Maybe the Apple ROM does some other initialization of the sound chip somewhere...

Link to post
Share on other sites

So far, the contains the following:

 

1) The Reset Vector: the first four bytes (where the checksum usually goes) are meant to be the initial value for the stack pointer; but since RAM is disabled so far (ROM overlay mode) it would be meaningless anyway. Then goes the code's starting address, I pointed it to 0x4000008 -- right after the vector. Despite being read from what would become RAM, it jumps to the usual ROM address range. I don't bother switching off the ROM overlay, though.

 

2) My code for displaying the picture; it was assembled by hand and wrote into the ROM with a hex editor (Hex Fiend). After some tweaking, I ended up using something crude like this:

 

PutPic: LEA Picture, A0         ;the picture stored in ROM
       LEA 0xFE008000, A1      ;address of the frame buffer
       MOVE.W #0x1560, D0      ;number of long words on a screen
Loop:   MOVE.L (A0)+, D1        ;loads a long word from the picture
       MOVE.L D1, (0x8000, A1) ;writes on the alternate buffer
       MOVE.L D1, (A1)+        ;writes on the main buffer, and avances to next long word
       SUBQ.W #1, D0           ;one long word less to go
       BNE.S Loop              ;repeat until it's finished

Not sure which is the main screen buffer and which is the alternate buffer, so I wrote the picture data in both :b&w: In fact, the 16-bit offset in MOVE.L D1, (0x8000, A1) seems to be signed and working backwards from intended, thus I placed that 0x8000 offset into the base address (see 2nd opcode), otherwise it didn't work -- I don't know which buffer is shown at startup time, either :I

 

3) dougg3's code for sampled startup sound, but supressing the final return instruction because this wasn't called from anywhere ;)

 

4) A STOP instruction -- supposedly halts the CPU and keeps it waiting for an interrupt... which would be catastrophic anyway, without any RAM/stack available xx(

 

5) The bitmap of my picture (512x342, 1-bit). I made it in CS5 after resizing/converting/dithering the original almost-as-sinister photo ;) Saved it, inverted (the Mac's screen is substractive: "1" means black pixel) as Wireless Portable Bitmap which contains the raw data after a small header, easily edited off with Hex Fiend

 

6) The sound sample (this address hardwired into Doug's code) after the preceptive 4-byte header indicating the sample's length. Again took it from the original 8-bit 22kHz AIFF after stripping the header.

 

And that's all! The code is actually playing the sample (not just static) and for the proper length; but the distortion could be caused by the lack of further initialization, as said -- I presume Doug's code originally executed after a great deal of Apple's ROM code.

 

A weird thing, however, is that after 45 seconds or so it does play again the sample! And keeps doing so every after... :?:

Link to post
Share on other sites
A weird thing, however, is that after 45 seconds or so it does play again the sample! And keeps doing so every after... :?:

 

Some uninitialized part of the hardware is acting as a "watchdog timer" and triggering a reset after roughly 45 seconds? (So you're basically just rebooting over and over again, but since the picture-drawing loop is just stuffing the same data into the video buffer over and over again you're not seeing any visual indication?)

Link to post
Share on other sites

Interesting...aside from the other suggestions, one other idea. After doing the STOP instruction, maybe the CPU wakes back up due to an interrupt of some kind, going past the STOP instruction and executing garbage instructions (whatever 0xFFFF... represents in machine code) until it falls through to the sound code. Have you put the STOP instruction inside an infinite loop? If not, it might be worth a try...

Link to post
Share on other sites

Some new info: multiplying the (approximately timed) 45 seconds by 22254 samples/sec gives a figure close to a suspiciously round 1 MiB -- add the fact that the second and subsequent times the sample gets played, it's preceeded by a buzzing sound for a moment, not heard just after reset... :-/

 

So I did another experiment: right after the code and data previously flashed, I wrote several repetitions of a number sequence (0x05-0A-0F-15-1A-1F-25-2A-2F... you get the idea) which, if played by the sound hardware, would make a sawtooth waveform of about 440 Hz -- an easily spotted sound! I filled up to 256 kiB of ROM this way, reflashed and... it plays the sawtooth, right after the (distorted) sample 8-o Sounds more like 880 Hz, though. Some kinds of distortion could double the frequency of a single wave, indeed; but it's definitely playing fast: after discounting the picture data, the 256 kiB should play for roughly 10 seconds at 22 kHz, but it's doing like 5 s... It wouldn't surprise me if this unexpected speed comes from the lack of a proper initialization of the sound chip -- Yamaha's YM2149 sound chip had a clock speed doubling feature, maybe Apple's has something similar (and it's reset somewhere in the original ROM's code)?

 

But what really amazes me is the fact that Doug's known good code isn't stopping at the end of the sample... I've double checked that the four-byte header with the sample's length in big-endian format is properly formed in front of the sample, and its address correctly stated in the related LEA of the playing code -- unless Hex Fiend is cheating on me, of course :?: And no matter how hard I try scrutinizing doug's code, I can see no way it could fail doing the right amount of samples...

 

The only chance would be a mysterious change of D0/D1 values... I could only think of an interrupt, but I'm under the impression that, in the current state (ROM overlay mode, no available RAM, no stack and no propely loaded Interrupt Vectors!) such event would totally crash the computer xx( However, just in case, as soon as I get back home I'll add an interrupt-disable instruction to the code...

 

BTW: the tests were done with 20 MiB RAM, although in ROM overlay mode that should be irrelevant -- tried last night with NO installed RAM, exactly same results. No ADB devices were connected, nothing on the serial ports, no floppy drive (internal or external). This particular machine has a SCSI failure -- the chip itself (and its connections to the CPU) is fine, but DB2 line is not connected to the SCSI bus (internal or external).

Link to post
Share on other sites

Weird!

 

I would have to agree -- the sound loop seems to be running past its bounds, which could only happen if D0 or D1 were being externally modified while the loop was running--for example, by an interrupt. But since you don't have any interrupt vectors yet, it would probably crash (like you said) or do something incredibly goofy. Did the behavior still happen after you disabled interrupts?

 

In case anyone's wondering, here's how I disabled interrupts when I was experimenting with sampled startup chimes:

 

ori #$0700, sr ; Disable interrupts (interrupt priority level = 7)

Link to post
Share on other sites

Weird, certainly... Yesterday was a hard day at work, and in a few minutes I'll hop into the car and stay out of town all day -- not much time to tinker with the ROM, I'm afraid :'(

 

On the interrupt suspicion, my only evidence so far is that pressing the NMI/programmers button stops whatever my ROM is doing -- as expected. I expect to get back into the hacking scene by Friday evening or Saturday, I'll check out then. Thanks for the reminder on disabling the 680x0 interrupts!

 

If nothing improves, I can try loading manually the sample's length into your code -- that is, not reading it from the header, just in case I got the numbers wrong (even if I double checked it...)

 

Another thing to do, once this is sorted out, would be checking the actual machine model -- I don't think it's a good idea to draw the picture from this ROM on a Mac II, assuming it has the video hardware of the SE/30 xx(

 

Patience... |)

Link to post
Share on other sites

Got it!

 

After tidying up the ROM contents, things were more or less like before, but now playing at the right speed: ≈11 seconds for 256 kiB ROM, repeating the whole cycle after about one-and-a-half minute -- twice the previous values. Disabling interrupts, changing the sample's length and/or its address made absolutely no difference :?:

 

I eventually discovered where the problem was -- a matter of assembler syntax! Yes, assembler and not assembly...

 

Both my source code and yours use a LEA address, A0 instruction at the beginning... but with different addresing modes! While yours (opcode 0x41FA) uses a 16-bit relative offset (which makes a lot of sense since in your version the sample was right after the code), I was using a 32-bit absolute address (opcode 0x41F9 for increased flexibility). When I inserted your code besides mine, I dumbly assumed that your LEA was like mine, and filled the following 32 bits with the absolute address -- actually "eating out" some of the initialization code! :I

 

Now, the sample is played at the proper position and length (like your original ROM did, of course) and your code finishes properly -- I added an infinite loop after that, working as a 32-bit counter on the screen itself, and I can see the pixels changing quickly as expected.

 

However, there's still the problem of distorted playback -- something else has to be intialized, it was done somewhere in the original ROM...

Link to post
Share on other sites

Ah, nice detective work! What are you using as an assembler? I've been using GNU as, which does have some annoying syntax, like the % before register names. The various addressing modes that GNU tools expect look weird, too (it's called AT&T syntax, I think). That's probably where the confusion comes from. If I had something that used the more common syntax, I'd use it instead.

 

As for the sound distortion, hmm. I noticed my sound code doesn't touch the ASC register at $802, which the MAME/MESS source code says is a control register. Maybe messing with the contents of that register would help...

Link to post
Share on other sites
  • 2 weeks later...

Back again...

 

Assembler? :lol: So far I've been assembling by hand...

 

Anyway, while I get a reasonable tool somewhere, I experimented with the register at $0802 -- just putting your code inside a loop that will try every single value for that register, stored in otherwise unused D3. For debugging purposes, I "placed" that byte on the screen so I can see what's going on. Here's what I flashed lastly on the Jolly Roger SIMM:

40000000    0000000040800008  ;SP-PC Reset

;disable interrupts... just in case

40000008    007C0700          ;MOVE #0x0700, SR

;put image at 0x40001000 on screen

4000000C    41F940001000      ;LEA Picture, A0
40000012    43F9FE008000      ;LEA VideoBuffer, A1
40000018    303C1560          ;MOVE.W #0x1560, D0
4000001C*1  2218              ;MOVE.L (A0)+, D1
4000001E    23418000          ;MOVE.L D1, (0x8000, A1)
40000022    22C1              ;MOVE.L D1, (A1)+
40000024    5340              ;SUBQ.W #1, D0
40000026    66F4              ;BNE.S *1

;loop for trying every 0x802 value!

           7600              ;MOVEQ #0, D3  ;init value
*8          13C3FE001877      ;MOVE.B D3, BYTE  ;show on screen
           13C3FE009877      ;MOVE.B D3, BYTE2
           17430802          ;MOVE.B D3, (0x802, A3)  ;set reg

;dougg3's sampled sound code (at absolute address 0x40007000)

           47F950F14000      ;LEA 0x50F14000, A3
           41F940007000      ;LEA Sample, A0  [41FA-"rel16"]
           177C00010801      ;MOVE.B #0x01, (0x801, A3)
           422B0807          ;CLR.B (0x807, A3)
           177C00400806      ;MOVE.B #0x40, (0x806, A3)
           277CFE00FE000830  ;MOVE.L #0xFE00FE00, (0x830, A3)
           277CFE00FE000834  ;MOVE.L #0xFE00FE00, (0x834, A3)
           177C00800803      ;MOVE.B #0x80, (0x803, A3)
           422B0803          ;CLR.B (0x803, A3)
           4A2B0804          ;TST.B (0x804, A3)
           2018              ;MOVE.L (A0)+, D0
           2200              ;MOVE.L D0, D1
           4841              ;SWAP D1
           6014              ;BRA.S *5
*2          082B00010804		;BTST #1, (0x804, A3)  ;PSIC
           6708              ;BEQ.S *4
*3          082B00000804		;BTST #0, (0x804, A3) ;WHE
           67F8              ;BEQ.S *3
*4          1418              ;MOVE.B (A0)+, D2  ;DS
           1682              ;MOVE.B D2, (A3)
*5          51C8FFEA          ;DBF D0, *2  ;NS
           51C9FFE6          ;DBF D1, *2
*6          177C00010801      ;MOVE.B #0x01, (0x801, A3)
           422B0807          ;CLR.B (0x807, A3)
           177C00400806      ;MOVE.B #0x40, (0x806, A3)
           277CFE00FE000830  ;MOVE.L #0xFE00FE00, (0x830, A3)
           277CFE00FE000834  ;MOVE.L #0xFE00FE00, (0x834, A3)
           177C00800803      ;MOVE.B #0x80, (0x803, A3)
           422B0803          ;CLR.B (0x803, A3)
           4A2B0804          ;TST.B (0x804, A3)

;loop's end

           5203              ;ADDQ.B #1, D3  ;next value
           6600FF60          ;BNE *8

;put a counter on the screen saying we're finished

*7          53B9FE001844      ;SUBQ.L #1, SITIO
           53B9FE009844      ;SUBQ.L #1, SITIO2
           60F2              ;BRA.S *7

Now, the bad news :( None of the values played the sample cleanly, although the effect of some bits of this register became evident:

 

D0: disables sound (if set to "1")

D1: makes sound weaker (volume control?)

D3: makes sound even weaker (can be combined with D1 for further attenuation)

 

Not sure if any other bits had effect on the sound, but at least we know something more about the ASC :b&w:

 

There has to be some other obscure initialization pending...

Link to post
Share on other sites
  • 1 month later...

Cool stuff zuiko21! I am thinking your code would be a good basis for making some kind of slide-show or animation that would be totally self-contained within a ROM if there's enough room. Could be some kind of art project or display without worrying about floppy disks and hard drives.

Link to post
Share on other sites

Zuiko21, the code you posted, is that the entire code to get from boot to image display? I'm not too familiar with assembly...I was wondering how you did this, and maybe try it out on my own machine. Maybe like have a ROM base for booting up showing an image, then concatenate any image in the proper format at the end of that file. Maybe the base could have a byte for changing how many total images are appended and another for dwell time for each image and then concatenate the images in the sequence desired.

Link to post
Share on other sites

tt, your idea is quite feasible and interesting!

 

The actual code for displaying a picture is about a 25% of the whole listing, just anything above the line:

;loop for trying every 0x802 value!

and could be somewhat simpler with a bit of optimization -- this was a quick-and-dirty approach :b&w:

 

I'm currently on holidays so I don't have the developer resources at hand ;) but I think the simplest way would be concatenating the 22 KB blocks for each picture after the code, then adding an empty loop for the desired delay between pics, and then jumping back to the code without resetting the image pointer, thus the following addresses are read. As you propose, this final loop should be done only for the specified number of pictures.

Link to post
Share on other sites
  • 2 months later...

[Wow! It's been a long time since my last post... I've been crazy at work these weeks :( I hope to catch up soon!]

 

@onlyonemac: If memory serves, I tried every possible value for the register, including each combination of D0, D1 and D3 -- the volume did turn down making the sound quieter... but equally distorted :?: I'm afraid the distortion comes from some other place... BTW, D2 seemed to have no effect, but its value was changed anyway.

 

@Bunsen: Certainly. The big problem about an unexpected OS for these machines (or any old world Mac) is the firmware, which is expecting to boot from a well-formed MacOS... But writing the firmware (ROM) from the scratch, "nothing" would prevent it booting from anything else...

 

But please take that "nothing" with a grain of salt -- by no means would it be a trivial task and, if attempting to boot an already made OS in 68k code, it's unlikely that it was designed with support of this unexpected architecture in mind -- it was made for MacOS only, wasn't it? A whole brand new OS (and its apps!) from the scratch shouldn't have these limitations, but that would be a lot of work...

 

I'm sort-of developing an escalable, (almost) full-featured modular OS intended for a (newly designed) 6502 system; but with portability in mind, thus a 68k version of it could be highly feasible... and should fit nicely into one of those ROM-SIMMs ;)

mode>

 

:o)

 

See you soon,

Link to post
Share on other sites

Hey zuiko,

 

This sound thing is still bugging me. I don't know if you're still trying to figure it out, but I just wanted to go back through everything I know about the sound chip in case it's any help. I just looked at my disassembly. It looks like the stock startup chime initialization code does a few things differently depending on the version register of the ASC (at ASC+$800). My sound code ignores it completely and just assumes the IIci version of the sound chip, so that might be a problem.

 

It would be interesting to see what the version register returns on the SE/30. On the IIci, using MicroBug with the command "DM 50F14800", the first byte it prints back is $00--version 0.

 

If the SE/30 reads back a different version number in this register, that might be part of what's going on. Anyone feel like going into the debugger and typing that command on an SE/30? Then you can exit the debugger by typing "G".

 

Here are the initialization differences based on the ASC version:

 

1) The volume it loads into the volume register ($806) is a bit different: On version 0, it looks like the 3-bit volume is loaded into the upper 3 bits (5-7) of register $806. This also concides with what happens if I play around with the sound control panel and then dump the contents of it:

 

volume 0 --> $00

volume 1 --> $20

volume 2 --> $40

volume 3 --> $60

volume 4 --> $80

volume 5 --> $A0

volume 6 --> $C0

volume 7 --> $E0.

 

For a nonzero ASC version, it appears to put the volume into bits 2-4 of the same register (but they provide a different volume for that chip too -- not sure exactly why).

 

No idea what the difference is -- all of the startup chimes/error beeps have two volumes in the initialization code. One for ASC version 0, one for ASC with a nonzero version.

 

So...if the SE/30 has a different sound chip version, my code (which just puts $40 for a volume of 2 before playing the sampled chime) is initializing the volume incorrectly.

 

2) Another thing it does differently with different ASC versions is that it puts something different into register $802. For ASC version 0, it puts in $00. For ASC with a nonzero version, it puts in $01. My comments say this is telling the sound chip whether to use analog or PWM, but I don't know for sure.

 

3) The only other difference is it sets up the initial synthesizer waveform differently based on the ASC version. But since you're not using the synthesizer mode, this shouldn't matter.

 

So...I guess it would be awesome to get a dump of what register $800 contains on the SE/30's ASC. Extra credit if you change the sound in the sound control panel and dump the register contents each time you change the sound like I did in my list above. ;-)

Link to post
Share on other sites

OK, let's go! (I'm writing this on the SE/30, after checking what you said)

 

It would be interesting to see what the version register returns on the SE/30. On the IIci, using MicroBug with the command "DM 50F14800", the first byte it prints back is $00--version 0.

So does mine...

 

1) The volume it loads into the volume register ($806) is a bit different: On version 0, it looks like the 3-bit volume is loaded into the upper 3 bits (5-7) of register $806. This also concides with what happens if I play around with the sound control panel and then dump the contents of it:

 

volume 0 --> $00

volume 1 --> $20

volume 2 --> $40

volume 3 --> $60

volume 4 --> $80

volume 5 --> $A0

volume 6 --> $C0

volume 7 --> $E0.

These are exactly the values I read at $50F14806 if I change the volume setting via the usual control panel...

 

2) Another thing it does differently with different ASC versions is that it puts something different into register $802. For ASC version 0, it puts in $00. For ASC with a nonzero version, it puts in $01.

Well, here we are a difeference: mine reads $02. FWIW, at $50F14801 is $01.

 

So...I guess it would be awesome to get a dump of what register $800 contains on the SE/30's ASC. Extra credit if you change the sound in the sound control panel and dump the register contents each time you change the sound like I did in my list above.

Done ;-)

 

I haven't tried the custom ROM SIMM on the other compatible machines I have (IIx, IIsi, Quadra 700) although I don't think they would show any picture... but the sound should play OK, right? Should I try them too? Any other interesting test to do?

 

All the best,

Link to post
Share on other sites

Hey Zuiko,

 

Thanks for running that test! So the SE/30 also has version 0 it seems. Nevermind about the differences I mentioned.

 

That's weird that $802 is reading back as 2. On my IIci, it reads back as $80. I'm not too concerned about what it reads back as in the Mac OS though--if the version register at $800 is reading as 0, then we know what code path it's going to take in the ROM. Also, your tests of the Sound control panel serve as a good confirmation.

 

I wonder if there's some kind of GPIO initialization that needs to be done in one of the VIA chips. I think GttMFH lays out what the registers do in each VIA. It's possible for a death chime to play very early in the boot process, so there can't be much left to initialize :-)

 

The SIMM should work in all of those, but I don't know if the newer sound chips in the IIsi or Quadra 700 will be register-compatible. I would assume the IIsi will still be compatible, but I'm less sure about the Quadra. I'm thinking that the FIFO status registers act differently on the Quadra's sound chip. I guess there's only one way to find out...

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...