Fascinating article. One question, you write that: "Using what I learned with the Mandelbrot, I wrote a program to display images; an example is below." - I couldn't find source code for that on github - is it published anywhere?
It would be interesting to see some code that exercise more parts of the system, beyond the Mandelbrot generator.
About coding style - I guess this is tabs-vs-spaces territory - but is there a particular reason why you only indent blocks in the loops, not in the procedure/functions (like under main)?
I also wonder a bit about some of the magic constants - like 30705 - is there an overhead to use variables in BCPL (eg: indirect de-reference, no automatic in-lining by the compiler)?
Finally, how about procedure call overhead? Granted, the Mandelbrot generator is rather simple (shifts and other tricks notwithstanding) - so I can see why it makes sense to keep it all in a single procedure - but what does a call/ret look like on the Alto? (eg: in simplified assembler, in terms of stack-push, registers etc)?
Magic constants: I'm lazy so it's easier to leave them inline when I'm hacking on code. I don't know if there's runtime overhead.
BCPL procedure call overhead: kind of nasty. There's no stack support in the instruction set, just jump-and-link. So a called procedure first calls a subroutine "getframe" that sets up the stack frame (very similar to a C stack frame). Then a second subroutine "moveargs" moves the call arguments into the stack frame. At the end of the procedure call, a third subroutine call cleans up and does the return.
Thank you! It's interesting to see how similar this code is to assembly code calling OS procedures, after declaring them external - I've recently been playing (again) with assembly for the win64 arch, and one sample program (a mish-mash of example code available for nasm, fasm and "go" assembler - is rather similar IMNHO - note this just displays a window, no loading of (image) files):
; Assemble and link with:
; nasm -f win64 .\hello-nasm.asm
; golink .\hello-nasm.obj \
; Kernel32.dll User32.dll /entry:WinMain
global WinMain
extern ExitProcess
extern MessageBoxA
section '.text'
WinMain:
sub rsp,8*5 ; reserve stack for API use and make
; stack dqword aligned
xor rcx, rcx ; uType = MB_OK
lea rdx, [szCaption] ; LPCSTR lpCaption
lea r8, [szTitle] ; LPCSTR lpText
xor r9d, r9d ; hWnd = HWND_DESKTOP
call MessageBoxA
mov ecx,eax
call ExitProcess
section '.rdata'
szTitle: db 'Hello, Title!', 0
szCaption: db 'Hello, World!', 0
It would be interesting to see some code that exercise more parts of the system, beyond the Mandelbrot generator.
About coding style - I guess this is tabs-vs-spaces territory - but is there a particular reason why you only indent blocks in the loops, not in the procedure/functions (like under main)?
I also wonder a bit about some of the magic constants - like 30705 - is there an overhead to use variables in BCPL (eg: indirect de-reference, no automatic in-lining by the compiler)?
Finally, how about procedure call overhead? Granted, the Mandelbrot generator is rather simple (shifts and other tricks notwithstanding) - so I can see why it makes sense to keep it all in a single procedure - but what does a call/ret look like on the Alto? (eg: in simplified assembler, in terms of stack-push, registers etc)?