Amiga Machine Code Letter X - More CLI
This is the forth part, of a multi-part series about the system libraries. We are still looking at Letter X of the Amiga Machine Code course, and as always, make sure to read the letter, since I won’t go through all the details.
In this post we continue our exploration of the CLI from The previous post. We are still using the DOS library to interact with the command line interface of the AmigaOS.
Usually the input and output file handles refers to the CLI terminal, unless they were redirected by “>” and “<”, in which case they will refer to something else 😉.
We are going to look at the program mc1007, which can be found on Letter X. In the listing below, you can see the code with my comments. When running the program from the CLI, it will wait for user input via the CLI terminal. The input ends when enter is pressed, and is then echoed it back into the CLI terminal, with the prefix “Hello, “.
bsr opendos ; go to opendos() to open the DOS library moveq #40,d0 ; move 40 into d0 lea.l input,a0 ; move input address into a0 bsr readchar ; go to subroutine d0 = readchar(a0, d0) addq.l #7,d0 ; add 7 to actual length read by readchar, where 7 is for "Hallo, " lea.l output,a0 ; put output address into a0 bsr writechar ; go to subroutine d0 = writechar(a0, d0) rts ; exit program output: dc.b "Hallo, " ; fill some bytes with charecters input: blk.b 40,0 ; reserves 40 bytes for input even ; pseudo-op for Seka. Makes the current address even by sometimes inserting a fill byte readchar: ; subroutine (d0=actualLength) = readchar(a0=input,d0=length) movem.l d1-d7/a0-a6,-(a7) ; push register values onto the stack move.l a0,a5 ; move a0 into a5 (input) move.l d0,d5 ; move d0 into d5 (length) lea.l txt_dosbase,a0 ; move txt_dosbase address into a0 move.l (a0),a6 ; move base pointer to DOS library into a6 jsr -54(a6) ; call (d0=file) = Input() in DOS library move.l d0,d1 ; move d0 (file) into d1 move.l a5,d2 ; move a5 (input) into d2 move.l d5,d3 ; move d5 (length) into d3 jsr -42(a6) ; call (d0=actualLength) = Read(d1=file,d2=buffer,d3=length) movem.l (a7)+,d1-d7/a0-a6 ; pop values from the stack into the registers rts ; return from subroutine writechar: ; subroutine (d0=returnedLength) = writechar(a0=buffer, d0=length) movem.l d1-d7/a0-a6,-(a7) ; push register values onto the stack move.l a0,a5 ; move a0 into a5 (buffer) move.l d0,d5 ; move d0 into d5 (length) lea.l txt_dosbase,a0 ; move txt_dosbase address into a0 move.l (a0),a6 ; move base pointer to DOS library into a6 jsr -60(a6) ; call (d0=file) = Output() move.l d0,d1 ; move d0 (file) into d1 move.l a5,d2 ; move a5 (buffer) into d2 move.l d5,d3 ; move d5 (length) into d3 jsr -48(a6) ; call (d0=returnedLength) = Write(d1=file,d2=buffer,d3=length) in DOS library movem.l (a7)+,d1-d7/a0-a6 ; pop values from the stack into the registers rts ; return from subroutine opendos: ; opens the dos library. opendos() movem.l d0-d7/a0-a6,-(a7) ; push register values onto the stack clr.l d0 move.l $4,a6 lea.l txt_dosname,a1 jsr -408(a6) ; call exec.library method d0 = OpenLibrary(a1,d0) lea.l txt_dosbase,a1 move.l d0,(a1) movem.l (a7)+,d0-d7/a0-a6 ; pop values from the stack into the registers rts ; return from subroutine txt_dosname: dc.b "dos.library",0 ; library name terminated by zero txt_dosbase: dc.l $0 ; allocation for holding the base address of dos.library
It’s important to run this program from the CLI, otherwise it won’t work. To compile the program and make an executable, write the following in Seka.
SEKA>a OPTIONS> No Errors SEKA>W FILENAME>mc1007
Then go into the CLI and run the program and see it echo back the arguments
1.amigahd:DISK1/BREV10>mc1007 how are you doing! Hello, how are you doing! 1.amigahd:DISK1/BREV10>
As also mentioned in the documentation, with exclamation marks, we should not close the file handles from Input and Output because they are owned by the CLI environment, which will close them, when the program terminates.
However, we should be a good citizen and close the DOS library, but that is not done in mc1007, with the result that the AmigaOS won’t be able to reclaim the memory. 😐
Memory handling in the AmigaOS
The AmigaOS is a microkernel architecture, where the kernel is called the Executive, or simply the Exec library. Its principal architect was Carl Sassenrath, who Commodore gave free hands to design a new operating system for the Amiga. He says the following about his role:
Introduced multitasking to the world of personal computers in 1985 with the Amiga Operating System Executive.
The microkernel could then load other libraries as needed, and unload them when not needed, thus preserving the limited memory.
One of the implications of the limited hardware, is that the AmigaOS has no memory protection. Every program can freely write to any memory address it wants.
In the previous post, we showed how freeing the wrong memory, could crash the whole system! 💥.
Motorola later added an MMU to the 68K family, called the 68030. At that point, the AmigaOS could have enforced memory protection on systems with the 68030, and left it out on the older platforms, since I doubt the machines were fast enough to do it in software.
Sadly, I don’t have time to actually check up on AmigaOS, to see if it eventually got memory protection. The last AmigaOS for the old Amiga 500 hardware was AmigaOS 3.9.
The book The Future Was Here, writes that many programmers, at the time, was used to program according to the three ones: One user, one program, and one computer. They came from a world of coding to the bare metal. For them, the multitasking in AmigaOS, was something they had to learn, and many got it wrong, with the result that the Amiga would crash. An Amiga user learned to save their work early and often. 😒
I think, that some of this hackish attitude shines through in the Machine Code Course, since they do not stress the point of freeing ressources, like closing the DOS library, when it’s not needed anymore.
However, this relaxed enforcment of system integrity in the AmigaOS, also made it possible for hackers to do some really impressive stuff, that pushed the Amiga hardware to it’s limits.
The book The Future Was Here goes into much more detail about the origins of the AmigaOS in chapter 6. The author Jimmy Maher, describes himself as a digital antiquarian, and that is really a good description. He has dug up a lot of war stories, that makes for an intersting read. His blog is available for free, but be warned, countless hours can be spend there 😃. If you like what you see, consider supporting him on Patreon.
In the next post, we are going to take a look at reading and writting to the disk. Stay tuned 🚀
Previous post: Amiga Machine Code Letter X - CLI.
Next post: Amiga Machine Code Letter X - Trackdisk.