This time, the CP/M Assembler.
To follow the demos in the video, boot up a CP/M 2.2 image that has the assembler (ASM.COM), loader (LOAD.COM), and optionally the DDT debugger (DDT.COM). The Briel CPM22.DSK image on the CD will work.
If you use CP/M 3, there is a more sophisticated macro assembler called MAC.COM. I have not tried it with these examples.
Create a file HELLO.ASM with the following source code and copy it to your SD card. Use TREAD to copy it to the CP/M disk (or enter it locally on CP/M if you have a text editor such as ED or WordStar).
; This is an example of the "Hello World" program.
; Uses 8080 assembler mnemonics.
ORG 100h ; cpm programs start address.
JMP START ; go to program start.
; Variable storage space
MsgStr: DB 13,10,'Hello world.',13,10,0
Stack1: DW 0 ; place to save old stack.
Sbot: DS 32 ; temp stack for us to use.
STOP: EQU $-1 ; top of our stack.
BDOS: EQU 5 ; address of BDOS entry.
; Start of code segment
START: LXI H, 0 ; HL = 0.
DAD SP ; HL = SP.
SHLD Stack1 ; save original stack.
LXI H, STOP ; HL = address of new stack.
SPHL ; stack pointer = our stack.
LXI H, MsgStr ; HL = address of string.
LOOP1: MOV A, M ; read string char.
ORA A ; set cpu flags.
JZ EXIT ; if char = 0 done.
MOV E, A ; E = char to send.
MVI C, 2 ; we want BDOS func 2.
PUSH H ; save HL register.
CALL BDOS ; call BDOS function.
POP H ; restore HL register
INX H ; point to next char.
JMP LOOP1 ; do next char.
; Exit and return code
EXIT: LHLD Stack1 ; HL = entry stack address.
SPHL ; SP = value on entry.
RET ; return control back to CPM.
Since I recorded the video, I found an even simpler hello world program which you can use instead if you like. The source code is below. I saved it as HELLO1.ASM and used it in the examples that follow.
bdos equ 0005h ; BDOS entry point
start: mvi c,9 ; BDOS function: output string
lxi d,msg$ ; address of msg
ret ; return to CCP
msg$: db 'Hello, world!$'
Here is an example session assembling, linking, and running it, and disassembling it with DDT. Commands typed by the user are in bold. Note that in the video, when I demonstrated DDT, I did not correctly load the file, so the disassembly in the video was incorrect. The example below is correct. Note that this session was run on drive B so I needed to specify the path to the tools on drive A.
CP/M ASSEMBLER - VER 2.0
000H USE FACTOR
END OF ASSEMBLY
FIRST ADDRESS 0100
LAST ADDRESS 0116
BYTES READ 0017
RECORDS WRITTEN 01
0100 org 100h
0005 = bdos equ 0005h ; BDOS entry point
0100 0E09 start: mvi c,9 ; BDOS function: output string
0102 110901 lxi d,msg$ ; address of msg
0105 CD0500 call bdos
0108 C9 ret ; return to CCP
0109 48656C6C6Fmsg$: db 'Hello, world!$'
DDT VERS 2.2
0100 MVI C,09
0102 LXI D,0109
0105 CALL 0005
0109 MOV C,B
010A MOV H,L
010B MOV L,H
010C MOV L,H
010D MOV L,A
010E INR L
010F ??= 20
Note that the assembler is for the Intel 8080. If you find CP/M programs for the Zilog Z80 and try to build them, they will not assemblem as it uses different mnemonics. They also won't run on the
Briel Altair 8800 as it only emulates Intel 8080 instructions.
The source for the "hello world" 8080 assembler program I listed above, as well as more information on ASM, can be found here.