LisaList2

General Category => LisaList2 => Topic started by: rayarachelian on January 28, 2022, 03:00:57 pm

Title: Directly BEEPING on the Lisa by writing to VIA register
Post by: rayarachelian on January 28, 2022, 03:00:57 pm
Split from: https://lisalist2.com/index.php/topic,240.0.html

Just had another thought, perhaps the Beep procedure runs asynchronously? That is it immediately returns to the caller, but then in that case, your executable would immediately quit, perhaps stopping the beep from happening.
Maybe you can add some kind of Sleep() or Delay() procedure before quitting to see if it does anything different?

Sure will do. Thank you Ray for helping. Also in about 10-12 days from now I'll have an opportunity to test this on a physical Lisa...

I will have other newbie questions too, but not sure if I should start a separate thread; I'm new to this forum and don't know the local netiquette. One thing for example is why, no matter how I try, I cannot set the 6552 Shift Register to any value in assembly code. I'm trying to do e.g. MOVE d0, $00FCDD81 or MOVE d0, $0000DD81 (documentation says sometimes former, sometimes latter for the VIA memory location) plus $14 offset to access the Shift Register and it always gives me ADDRESS ERROR when running the program from Pascal. Any ideas what I'm doing wrong? Sorry if this is not for this thread, will start a new one if needed.

Yes, please open a new topic with this and give details as to how you're doing this, etc.

I can tell you that this is incorrect:
Code: [Select]
MOVE d0, $0000DD81

Because there's no VIA at that address. All I/O exists at $00fcxxxx - but this is only available in context 0 (supervisor mode). If you're running that from LPW, it will never work because your code won't run in supervisor mode, and only the OS has access to I/O (and SIO) spaces.

You'd ofc have to set the ACR on via #1 to enable the CB1 or CB2 output of the shift register of the VIA, but sounds like you already know about that. Also take a look at the Lisa Boot ROM source code, should be available on bitsavers which has code for beeping.

Code: [Select]
0AF6|                       ;  Routine to beep the speaker
0AF6|                       ;  Assumes regs set up as
0AF6|                       ;    D0 = desired frequency ($00 - $AA)
0AF6|                       ;    D1 = duration (0 = .5 msec)
0AF6|                       ;    D2 = volume (0,2,4,...,E)
0AF6|                       ;-------------------------------------------------------------------------
0AF6|
0AF6| 48E7 1088             TONE    MOVEM.L A0/A4/D3,-(SP)  ;save regs
0AFA|                               BSRS4   TONE2           ;go do tone
0AFA| 49FA 0004            #          LEA      @1,A4
0AFE| 6006                 #          BRA.S    TONE2
0B00|                      #@1
0B00| 4CDF 1108                     MOVEM.L (SP)+,A0/A4/D3  ;restore and exit
0B04| 4E75                          RTS
0B06|
0B06|                       ;  separate entry point for call without memory usage
0B06|
0B06| 207C 00FC DD81        TONE2   MOVEA.L #VIA1BASE,A0    ;set VIA ptr
0B0C| 0028 000E 0004                ORI.B   #$0E,DDRB1(A0)  ;set volume bits for output
0B12| 0210 00F1                     ANDI.B  #$F1,ORB1(A0)   ;clear and then
0B16| 8510                          OR.B    D2,ORB1(A0)     ; set volume bits
0B18| 0228 00E3 0016                ANDI.B  #$E3,ACR1(A0)   ;clear shift mode bits
0B1E| 0028 0010 0016                ORI.B   #$10,ACR1(A0)   ;set shift reg for continuous rotate
0B24|
0B24|                       ; check system type
0B24|
0B24| 4A39 00FC C031                TST.B   DISKROM         ;test for Lisa 1 board                  CHG014
0B2A| 6A10                          BPL.S   @3              ;no changes if yes                      CHG014
0B2C| 0839 0005 00FC C031           BTST    #SLOTMR,DISKROM ;else check if slow timers              CHG029
0B34| 6606                          BNE.S   @3              ;skip if yes                            CHG029
0B36| 1600                          MOVE.B  D0,D3           ;else adjust input parm                 CHG014
0B38| E40B                          LSR.B   #2,D3           ; by factor of .25                      CHG014
0B3A| D003                          ADD.B   D3,D0           ;                                       CHG014
0B3C|
0B3C| 1140 0010             @3      MOVE.B  D0,T2CL1(A0)    ;set frequency
0B40| 117C 000F 0014                MOVE.B  #$0F,SHR1(A0)   ;set for square wave and trigger
0B46|
0B46|                       ;  Do time delay -  enter with count in D1 (about .5 msec per count)
0B46|
0B46| 363C 00D0             @1      MOVE.W  #$00D0,D3       ;set delay constant
0B4A| 51CB FFFE             @2      DBF     D3,@2
0B4E| 51C9 FFF6                     DBF     D1,@1
0B52|
0B52| 0228 00E3 0016        SILENCE ANDI.B  #$E3,ACR1(A0)   ;disable tone
0B58|                               RTS4                    ;and return
0B58| 4ED4                 #          JMP      (A4)

You might be able to do this from Service Mode, or by writing your code to a floppy in the 1st boot sector (it will start to execute from $20000) by setting tags 4,5 on that sector 0 to AA,AA.

If you dislike Service mode, you can also mess around with my nanoBug image - https://github.com/rayarachelian/nanobug (https://github.com/rayarachelian/nanobug)  but you'll need to use the serial port for this.

Neither Service Mode, nor nanoBug have built in assemblers, so you'd assemble your code, copy your hex values somewhere and then enter them again in these and then execute the code and see what happens.
You can find prebuilt ones here: https://lisalist2.com/index.php/topic,241.0.html (https://lisalist2.com/index.php/topic,241.0.html) (just uploaded them.)

Another option is to run your code from MacWorks - that is inside of MacOS using something like Macsbug or whatever assembler, or C/Pascal compiler you like. MacWorks runs in MMU context 0 and therefore has full access to I/O address space.

As "newbie" as you might be, you're doing awesome. Welcome to LisaList2  :D
Title: Re: Directly BEEPING on the Lisa by writing to VIA register
Post by: kewatsdop on January 28, 2022, 05:28:26 pm
Amazing. Thank you Ray!!! I am going to look closer at your answers and study them closely before trying out, as I'm very fresh to this. But I already know I will probably want to follow the "write to floppy" path as I need full control over the beeper.

For full disclosure, I'm the author of http://forgottencomputer.com/retro/sound/ and I'm learning while writing that article. My goal is simple: to understand, practice and - only if I succeed - document, how Lisa generates sound at low level.

Many thanks for helping me here, and for your work on LisaEm. I'll be updating in the 2 threads on progress as time allows me to focus on this.
Title: Re: Directly BEEPING on the Lisa by writing to VIA register
Post by: rayarachelian on January 28, 2022, 05:58:17 pm
For full disclosure, I'm the author of http://forgottencomputer.com/retro/sound/ and I'm learning while writing that article. My goal is simple: to understand, practice and - only if I succeed - document, how Lisa generates sound at low level.

Many thanks for helping me here, and for your work on LisaEm. I'll be updating in the 2 threads on progress as time allows me to focus on this.

Sure, you're welcome. Sound on the Lisa works similar to sound on the Commodore PETs, since they both use VIA6522' SR output on the CB2 line for this. However, the Lisa has a real speaker (regular, non-piezo and is amplified), it has different clock timings so the frequencies are going to differ, and there's also a master volume control. (Also note that the Lisa 2/10 has a different clock than the Lisa 1s, 2s, and 2/5s so the frequencies there are off by a factor of 4.)

Fun tidbit, a long time ago, Commodore wrote a crappy little "PET Emulator" for the C64 and moved the video page address to match the same one in memory of a PET. (Maybe that's where Apple got the idea of writing MacWorks?)

But the C64's PET Emulator didn't do sound. So I added a piezo speaker to the CIA output (CIA is the next version of the VIA) and then I hand modified the sound pokes in a few PET games to match the C64's CIA and get sound and it sounded almost the same. (Unfortunately for whatever reason the C64 used BASIC 2.0 vs BASIC 4.0 so most games didn't work right anyway.)


I'd suggest you take this script that builds nanoBug (you'll also need lisafsh-tool), and https://github.com/rayarachelian/nanoBug/blob/master/make-nanobug2.sh and add some code at the top that calls https://github.com/rayarachelian/EASy68K-asm to assemble your code. The script that builds nanoBug just injects a small binary into the boot sector.

This way you could build yourself a nice scripted pipeline to build your test code and feed those to LisaEm. :)

(You could also look at some of the stuff Tom Stepleton build using python to generate disk images such as his NeoWidEx code, etc. if you find that better.)
Title: Re: Directly BEEPING on the Lisa by writing to VIA register
Post by: stepleton on January 28, 2022, 08:42:49 pm
Thanks for the plug, Ray :-)
For a direct link, this one Python (2.7) script (https://github.com/stepleton/bootloader/blob/master/dc42_build_bootable_disk.py) creates a bootable .dc42 floppy image from any raw binary code that fits on the disk.
Title: Re: Directly BEEPING on the Lisa by writing to VIA register
Post by: kewatsdop on January 29, 2022, 03:20:45 pm
Thank you Ray and stepleton!

Great. So the help message for dc42_build_bootable_disk.py reads 68000 program to load+run (starting address $800). Does it mean I can put org $800 in my source code, cross-compile on my Mac e.g. using vasm to M680x0 architecture, and just pass it as an argument? That would be cool.
Title: Re: Directly BEEPING on the Lisa by writing to VIA register
Post by: stepleton on January 29, 2022, 04:41:42 pm
Yes, that's correct! Here's a small 68000 assembly program of my own (https://github.com/stepleton/LisaMandelbrot/blob/master/Solo/LisaMandelbrot.X68#L74) that does exactly this.
Title: Re: Directly BEEPING on the Lisa by writing to VIA register
Post by: kewatsdop on January 30, 2022, 06:14:40 am
Thank you Tom. I tried it out: compiled your Mandelbrot demo using vasmm68k_mot -Faout LisaMandelbrot.X68, and then created a floppy image using python dc42_build_bootable_disk.py a.out -f sony_800k -o floppy.dc42.

All worked fine!!! Thank you so much for this useful script.

Now I'm off to playing with 6522 register and trying to produce sounds in bare machine code...

One follow-up question. Is it easy to create a physical floppy disk out of a *.dc42 image? Would it be as easy as using dd if=floppy.dc42 of=/dev/myusbfloppydrive? I will be wanting to try my code also on an actual Lisa.

Title: Re: Directly BEEPING on the Lisa by writing to VIA register
Post by: stepleton on January 30, 2022, 06:38:47 am
No, it won't work to use dd: a DC42 disk image has metadata at the front, and it also breaks each 524-byte sector into two pieces and stores them in different parts of the file, for reasons that make sense in an Apple context. Refer to these resources for details:

https://web.archive.org/web/20161028130400/https://wiki.68kmla.org/index.php?title=DiskCopy_4.2_format_specification
http://sigmasevensystems.com/blumanual.html Appendix E

If you have an older Mac, you can use Disk Copy 4.2 to write the disk image to a floppy. If you don't, then you still have some options. LisaEm includes a tool called dc42-to-raw (https://github.com/rayarachelian/lisaem/blob/master/src/tools/src/dc42-to-raw.c) which can convert a DC42 disk image to a raw file that you can use with dd. Or, you can boot up BLU (http://sigmasevensystems.com/BLU) on your Lisa and send the DC42 file to the Lisa via the serial port. BLU understands the format and can write the data to a floppy.

Lastly, you could buy a Floppy Emu (https://www.bigmessowires.com/floppy-emu/) and use that instead of your Lisa's floppy drive. Floppy Emu can work with DC42 files.
Title: Re: Directly BEEPING on the Lisa by writing to VIA register
Post by: kewatsdop on January 30, 2022, 07:02:55 am
Thank you for the detailed answer! Ok, so even if it is not straightforward, there are several options to choose from. I'll be trying them out a couple of weeks from now. Before that happens, let me use the excellent LisaEm.
Title: Re: Directly BEEPING on the Lisa by writing to VIA register
Post by: kewatsdop on January 30, 2022, 07:38:29 am
Hmmm. I wrote this as a stub and template:

; zero
                ORG     $800

SOUNDTEST:
                NOP

                END SOUNDTEST

                             

...and built myself a script to compile -> build disk...:

filename=$1
filename="${filename%.*}"

echo "Filename without extension is ${filename}"

echo -n "Compiling $1 with vasm... " &&\
vasmm68k_mot -Faout $1 &&\
echo "done." &&\
echo "Creating bootable floppy... " &&\
python ../bootloader-master/dc42_build_bootable_disk.py a.out -f sony_800k -o ${filename}.dc42 &&\
echo "done."


...which nicely produces a.out, and then the floppy image, but I'm getting boot ROM error 75 when trying to start from such a floppy image. What am I missing?
Title: Re: Directly BEEPING on the Lisa by writing to VIA register
Post by: blusnowkitty on January 30, 2022, 10:53:52 am
Thank you for the detailed answer! Ok, so even if it is not straightforward, there are several options to choose from. I'll be trying them out a couple of weeks from now. Before that happens, let me use the excellent LisaEm.

Plus there is also the issue of all of the Apple 3.5 inch floppy drives have variable spindle speeds whereas PC floppy drives have a fixed spindle speed. This makes it physically impossible for PC and USB drives to write out Apple 400 and 800k disks.
Title: Re: Directly BEEPING on the Lisa by writing to VIA register
Post by: rayarachelian on January 30, 2022, 12:40:58 pm
Plus there is also the issue of all of the Apple 3.5 inch floppy drives have variable spindle speeds whereas PC floppy drives have a fixed spindle speed. This makes it physically impossible for PC and USB drives to write out Apple 400 and 800k disks.

That shouldn't be an issue with a real Lisa, you can use BLU for that and get BLU running through Service Mode and the serial port: http://sigmasevensystems.com/BLU

Access to an old world Mac with a 1.44M superdrive or even 800K drive and ethernet is also a really useful way to transfer things to a Lisa.
(However a superdrive would also allow you to transfer data to PCs if you don't have ethernet.)

I use a 5300ce for this which runs System 9 but since it has PCMCIA slots, I use an FAT32 formatted SDHC card inside PCMCIA adapter and use that to sneakernet disk images to my Linux machine. The 5300ce can easily create or image Lisa floppies.

Title: Re: Directly BEEPING on the Lisa by writing to VIA register
Post by: rayarachelian on January 30, 2022, 12:44:19 pm
...which nicely produces a.out, and then the floppy image, but I'm getting boot ROM error 75 when trying to start from such a floppy image. What am I missing?

Well that's pretty obvious. You don't have any code there. That NOP will fall through to the next address which is likely all zeros and then eventually run wild and fail.

You should create some code to do something and not return to the boot ROM. For example, create a loop that generates sounds and loops around with DBRA as a time delay, etc. or fill the video memory addresses with something, etc.


Title: Re: Directly BEEPING on the Lisa by writing to VIA register
Post by: stepleton on January 30, 2022, 05:05:08 pm
As for something for your code to do, I recommend calling routines in the boot ROM. You can learn about them in this file:

http://www.bitsavers.org/pdf/apple/lisa/Lisa_Boot_ROM_Manual_V1.3_Feb84.pdf

starting at PDF page 28. I'd recommend calling $FE0084, "ROM Monitor", which is a convenient way for your program to quit to the boot ROM. Point A3 at a null-terminated string (uppercase letters only!) to print a message to the user.

As you're doing bare-metal programming, you might enjoy using routines from my lisa_io (https://github.com/stepleton/lisa_io) library. There's nothing in there for beeping though!
Title: Re: Directly BEEPING on the Lisa by writing to VIA register
Post by: kewatsdop on January 31, 2022, 01:53:57 pm
Thank you for the help so far. The Lisa Boot ROM Manual looks very helpful indeed, but I'm not getting what I expect here:

I tried its BEEP routine (page 39 in that manual) by executing:

                ORG $800

playsound:
                MOVE.w #$10,D0
                MOVE.w #$F0,D1
                MOVE.w #$6,D2
                JSR $FE00B8

                MOVE.w #$A0,D0
                MOVE.w #$F0,D1
                MOVE.w #$A,D2
                JSR $FE00B8

                MOVE.w #$19,D0
                MOVE.w #$82,D1
                MOVE.w #$8,D2
                JSR $FE00B8

                MOVE.w #$A0,D0
                MOVE.w #$34,D1
                MOVE.w #$E,D2
                JSR $FE00B8

                end playsound


This does something with the speaker (short noisy sound), but definitely not the 4 sounds expected. Then it returns to ROM where I can diagnose the memory, etc.

Is there something I'm still doing wrong here or do you think this is related to the sound issue in LisaEm (as discussed here: https://lisalist2.com/index.php/topic,240.0.html) or am I missing something in my code again?
Title: Re: Directly BEEPING on the Lisa by writing to VIA register
Post by: rayarachelian on January 31, 2022, 03:08:15 pm
Thank you for the help so far. The Lisa Boot ROM Manual looks very helpful indeed, but I'm not getting what I expect here:

I tried its BEEP routine (page 39 in that manual) by executing:

                ORG $800

playsound:
                MOVE.w #$F0,D1
...


This does something with the speaker (short noisy sound), but definitely not the 4 sounds expected. Then it returns to ROM where I can diagnose the memory, etc.
...

Code: [Select]
0B46|                       ;  Do time delay -  enter with count in D1 (about .5 msec per count)


So according to the comments on the source, each cycle on D1 is .5ms. #$f0=240. So, 240*.5ms = 120ms.  1ms=1/1000th of a second, so the delay is something like 0.120s.  Since each D1 is 1/2 a millisecond, 1s should therefore be something like 1000*2 in D1. So try passing a much larger value for D1.
Like #2000, is what I'd guess.
Title: Re: Directly BEEPING on the Lisa by writing to VIA register
Post by: stepleton on January 31, 2022, 04:41:15 pm
Hmm, I don't really know. (ETA: just saw Ray's response; maybe that's it :) ) Here's an idea though: since your program is pretty small, it probably wouldn't be too hard to try it on a real Lisa even without using a floppy. Just get a hex dump of your assembled program (without the bootloader) and type it into memory using the Lisa's Service Mode.

Appendix A of the BLU manual (http://sigmasevensystems.com/blumanual.html) shows you how to enter Service Mode and load and run a program. You will need to make some changes: specifically, you'll want to change the code itself after the 2900, 2910, 2920 etc. lines to your own code. Also, note that the BLU Simple Serial Loader program resides at address $900, and you've been assembling to $800... although your code doesn't have absolute addresses referring to itself yet, so this doesn't matter.

Take care that you include spaces as shown in the example.

Anyway, consider keying in a program that beeps once or twice and seeing what happens.

One last thing I'd recommend is concluding your program with something that will return control to the ROM, since right now I think you're letting the Lisa run off into uninitialised memory. I would just execute an RTS instruction, as if I'm not mistaken, the boot ROM uses a JSR to jump to the code you've keyed in (per line 292A of the boot ROM source (http://www.bitsavers.org/pdf/apple/lisa/firmware/Lisa_Boot_ROM_Asm_Listing.TEXT)).
Title: Re: Directly BEEPING on the Lisa by writing to VIA register
Post by: kewatsdop on February 01, 2022, 02:38:22 am
Thank you both.

Something is still not right with how this $FE00B8 subroutine is executed in LisaEm. Increasing the D1 value makes the pauses, not the sounds, longer. Duration of notes remains very short.

Also, the last note played is always quiet, regardless of the value of D2.

The code below is supposed to play 4 notes, each subsequent separated by an octave from the previous one (half the frequency), each 1-second long, and each with increasing volume. But only the pitches seem to work as expected; the duration is always very short, and the last note's volume is very low.

                ORG $800

                MOVE.b #10,D0
                MOVE.l #2000,D1
                MOVE.b #$4,D2
                JSR $FE00B8
                MOVE.b #20,D0
                MOVE.l #2000,D1
                MOVE.b #$6,D2
                JSR $FE00B8
                MOVE.b #40,D0
                MOVE.l #2000,D1
                MOVE.b #$8,D2
                JSR $FE00B8
                MOVE.b #80,D0
                MOVE.l #2000,D1
                MOVE.b #$A,D2
                JSR $FE00B8


Later in the week I'll try the same on my Windows machine, and next week on an actual Lisa as suggested.
Title: Re: Directly BEEPING on the Lisa by writing to VIA register
Post by: kewatsdop on February 01, 2022, 06:33:21 am
Well did some more testing and it seems the sound output is inconsistent depending on where and how LisaEm is run. When running the exact same code as above, I get the following results:

- macOS laptop with built-in speakers: results as above (all 4 pitches audible, but duration wrong)
- macOS laptop connected to external speakers: only the first of 4 sounds audible
- Windows LisaEm: only brief noise audible, then nothing

Can't wait to try it out on an actual Lisa to compare...
Title: Re: Directly BEEPING on the Lisa by writing to VIA register
Post by: rayarachelian on February 01, 2022, 08:58:15 am
Well did some more testing and it seems the sound output is inconsistent depending on where and how LisaEm is run. When running the exact same code as above, I get the following results:

- macOS laptop with built-in speakers: results as above (all 4 pitches audible, but duration wrong)
- macOS laptop connected to external speakers: only the first of 4 sounds audible
- Windows LisaEm: only brief noise audible, then nothing

Can't wait to try it out on an actual Lisa to compare...


https://github.com/rayarachelian/lisaem/blob/unstable/src/host/wxui/lisaem_wx.cpp#L8636
So mea culpa. My bad. This is missing the loop flag:
Code: [Select]
my_lisa_sound.Play(wxSOUND_ASYNC|wxSOUND_LOOP);
Part of what you see is a limitation in wxWidgets - it can only play a single sound at a time, but the delay duration is all my fault.

The way it's supposed to work is that when the Lisa starts to play a sound through the speaker, LisaEm has no idea of how long it should play it for, so it sets the CPU throttle to 5MHz so it will be close to the length of what a real Lisa would play for.

Then when the VIA is told to shut down the SR rotation, or the volume goes to zero, it will stop playing.

(But if any other sound, such as the floppy motor starts to play, it will stop the sound - this part is a wxWidgets limitation.)

That said, even with the wxSOUND_LOOP bit, it will sometimes fail to play any sound anyway.

I have a TODO in my list to switch sound to OpenAL - this will happen either in 1.2.8 or 2.0, but Apple possibly threw a monkey wrench in that by removing it from macos 10.12 around there. That's another discussion. Why OpenAL, because it's available for Linux, FreeBSD, Windows, and macos. So I'll have to include it as a library. That will allow LisaEm to play multiple simultaneous sounds. So I could add widget, imagewriter/ADMP, daisywheel sounds as well.

Another possibility is to require libSDL and directly call it for sound, but I'm not so sure I want to do that for non GTK systems, plus OpenAL is dedicated for sound output and has a lot more features and capabilities that makes it better.
Title: Re: Directly BEEPING on the Lisa by writing to VIA register
Post by: kewatsdop on February 01, 2022, 11:06:36 am
Understood and thank you for digging into this.

Good luck resolving the issue whenever you have a chance to work on it.

Not knowing anything about writing emulators, I'm wondering if re-using the sound subsystems from other emulators, e.g. FS UAE (Amiga) or Fuse (ZX Spectrum) is possible; these emulators allow running programs in "bare metal" mode and demos/games written that way seem to produce sound correctly. This is not to suggest any direction of course as it may not even be possible for reasons beyond my understanding.

In any case I'm very grateful for LisaEm to exist, as I would be nowhere near understanding how Lisa works before I have a chance to try my experiments on the physical machine.
Title: Re: Directly BEEPING on the Lisa by writing to VIA register
Post by: rayarachelian on February 01, 2022, 01:26:11 pm
Understood and thank you for digging into this.

Good luck resolving the issue whenever you have a chance to work on it.

No worries, I should have RC4 soon-ish. I'm fixing a few other bugs. It'll include this sound fix, which hopefully will make things better, but not the larger move to OpenAL.