I wanted to learn some Intel 8080 assembler programming, so I selected as a project to write a port of my JMON machine language monitor program that I wrote for the 6502 and Briel Apple 1 Replica.
After a couple of evenings of hacking I have a version running with six of the commands implemented. It is not so much a port, as an implementation from scratch of a subset of the commands and features of the 6502 version.
Some sample output is shown below (user input is in bold).
JMON Monitor 0.1 by Jeff Tranter
? ?
Valid commands:
C start end dest Copy memory
D address Dump memory
F start end data... Fill memory
G address Go
I Show info
K start end Checksum
L Clear screen
R Examine registers
S start end data... Search memory
T start end Test memory
V start end dest Verify memory
: address data... Write to memory
= address +/- address Hex math calculation
? Help
? I
JMON Monitor 0.1 by Jeff Tranter
CPU type: 8080
? R
A=00 BC=0000 DE=0000 HL=0000 F=00000110 SP=7000 PC=0000
? D 0000
0000: 32 9E 06 78 32 A0 06 79 32 A1 06 7A 32 A2 06 7B 2..x2..y2..z2..{
0010: 32 A3 06 7C 32 A4 06 7D 32 A5 06 F5 C1 79 32 9F 2..|2..}2....y2.
0020: 06 21 00 70 7C 32 A6 06 7D 32 A7 06 31 00 70 CD .!.p|2..}2..1.p.
0030: E5 02 21 A7 03 CD EC 02 3E 3F CD 92 02 CD FC 02 ..!......?......
0040: CD A1 02 CD 04 03 FE 43 C2 51 00 CD 85 02 C3 38 .......C.Q.....8
0050: 00 FE 44 C2 5C 00 CD EC 00 C3 38 00 FE 46 C2 67 ..D.\.....8..F.g
0060: 00 CD 85 02 C3 38 00 FE 47 C2 72 00 CD 4A 01 C3 .....8..G.r..J..
0070: 38 00 FE 49 C2 7D 00 CD 90 01 C3 38 00 FE 4B C2 8..I.}.....8..K.
0080: 88 00 CD 85 02 C3 38 00 FE 4C C2 93 00 CD 89 01 ......8..L......
0090: C3 38 00 FE 52 C2 9E 00 CD BC 01 C3 38 00 FE 53 .8..R.......8..S
00A0: C2 A9 00 CD 85 02 C3 38 00 FE 54 C2 B4 00 CD 85 .......8..T.....
00B0: 02 C3 38 00 FE 56 C2 BF 00 CD 85 02 C3 38 00 FE ..8..V.......8..
00C0: 3A C2 CA 00 CD 85 02 C3 38 00 FE 3D C2 D5 00 CD :.......8..=....
00D0: 85 02 C3 38 00 FE 3F C2 E0 00 CD 7B 02 C3 38 00 ...8..?....{..8.
00E0: CD AB 02 21 CA 03 CD EC 02 C3 38 00 CD 92 02 CD ...!......8.....
00F0: FC 02 CD 9C 03 D2 FC 00 CD AB 02 C9 CD AB 02 0E ................
0100: 18 E5 CD 43 03 3E 3A CD 92 02 06 10 CD FC 02 7E ...C..:........~
0110: CD 11 03 23 05 C2 0C 01 CD FC 02 E1 06 10 7E CD ...#..........~.
0120: D0 02 23 05 C2 1E 01 CD AB 02 0D C2 01 01 E5 21 ..#............!
0130: 51 06 CD EC 02 E1 CD A1 02 FE 1B C2 42 01 CD AB Q...........B...
0140: 02 C9 FE 20 CA FC 00 C3 36 01 CD 92 02 CD FC 02 ... ....6.......
0150: CD 9C 03 D2 5A 01 CD AB 02 C9 22 A8 06 CD AB 02 ....Z.....".....
0160: 2A 00 00 E5 3A A8 06 6F 3A A9 06 67 E5 3A A4 06 *...:..o:..g.:..
0170: 67 3A A5 06 6F 3A A2 06 57 3A A3 06 5F 3A A0 06 g:..o:..W:.._..
Press Space to continue, ESC to stop
? G 0000
It builds using the AS Macro Assembler. The binary can be put on an SD card and directly loaded into the Briel Altair 8800 memory and run.
I found debugging quite straightforward by using the front panel switches of the Briel Altair 8800. In particular, the ability to step, see disassembly on the console, and set a breakpoint address, were very useful. The JMON monitor makes some things a little easier than the front panel, like dumping the contents of memory.
While my goal was to learn 8080 assembly language programming, the monitor is somewhat useful in it's current form. You can find the source code here. It is licensed under the Apache 2.0 license so you are free to use it for any purpose. As time allows, I may implement more commands and features.
Being mostly familiar with the 6502, and its successors like the 6809 and 68000, it was interesting to see how the Intel 8080 compared. It has more registers and instructions than the 6502, making some things easier, but the learning curve is perhaps higher. It also has a few unusual instructions and quirks (for example, how do you clear the carry bit?).
Showing posts with label Intel 8080. Show all posts
Showing posts with label Intel 8080. Show all posts
Sunday, March 30, 2014
The AS Macro Assembler
I was recently writing some Intel 8080 assembly language code for the Briel Altair 8800 computer. Assembling programs by hand and toggling in the binary codes using the front panel gets tedious very quickly. I could write it under CP/M and use the CP/M assembler, but text editing is a little clumsy under CP/M, the assembler is slow, and I want to run the programs standalone on the Altair 8800 without using CP/M.
A search for a cross-assembler that would run on Linux and support the Intel 8080 identified the AS macro assembler. This is a full-featured, free (GPL licensed) cross-assembler that runs on Linux and other desktop operating systems. It actually supports about 75 different microprocessors -- quite an amazing accomplishment!
I built it from source on Linux without any problems and was soon assembling 8080 assembly language code. The documentation that comes with it is very extensive and complete and the assembler listings are easy to read (some representative listing code is shown below).
727/ 39F : ; GetAddress
728/ 39F : ; Gets a four character hex number from the keyboard.
729/ 39F : ; Ignores invalid characters. cancels and sets carry bit.
730/ 39F : ; Returns binary word in HL.
731/ 39F : ; Registers affected: A,B,H,L
732/ 39F :
733/ 39F : GetAddress:
734/ 39F : CD 90 03 call GetByte ; Get MSB
735/ 3A2 : D8 rc ; Exit if pressed
736/ 3A3 : 67 mov h,a ; Save MSB in H
737/ 3A4 : CD 90 03 call GetByte ; Get LSB
738/ 3A7 : D8 rc ; Exit if pressed
739/ 3A8 : 6F mov l,a ; Save LSB in L
740/ 3A9 : C9 ret
It can produce Intel Hex format files which can be transferred to CP/M, converted to .COM files using the CP/M LOAD program, and then executed.
I am using it to generate a binary file which can be copied to an SD card and then directly loaded and executed by the firmware on the Briel Altair 8800.
It is very fast to assemble programs under Linux, and seems to have all the features and more than I could want. If you are looking for a good cross-assembler for the 8080 or just about any processor, it may be just what you need.
A search for a cross-assembler that would run on Linux and support the Intel 8080 identified the AS macro assembler. This is a full-featured, free (GPL licensed) cross-assembler that runs on Linux and other desktop operating systems. It actually supports about 75 different microprocessors -- quite an amazing accomplishment!
I built it from source on Linux without any problems and was soon assembling 8080 assembly language code. The documentation that comes with it is very extensive and complete and the assembler listings are easy to read (some representative listing code is shown below).
727/ 39F : ; GetAddress
728/ 39F : ; Gets a four character hex number from the keyboard.
729/ 39F : ; Ignores invalid characters.
730/ 39F : ; Returns binary word in HL.
731/ 39F : ; Registers affected: A,B,H,L
732/ 39F :
733/ 39F : GetAddress:
734/ 39F : CD 90 03 call GetByte ; Get MSB
735/ 3A2 : D8 rc ; Exit if
736/ 3A3 : 67 mov h,a ; Save MSB in H
737/ 3A4 : CD 90 03 call GetByte ; Get LSB
738/ 3A7 : D8 rc ; Exit if
739/ 3A8 : 6F mov l,a ; Save LSB in L
740/ 3A9 : C9 ret
It can produce Intel Hex format files which can be transferred to CP/M, converted to .COM files using the CP/M LOAD program, and then executed.
I am using it to generate a binary file which can be copied to an SD card and then directly loaded and executed by the firmware on the Briel Altair 8800.
It is very fast to assemble programs under Linux, and seems to have all the features and more than I could want. If you are looking for a good cross-assembler for the 8080 or just about any processor, it may be just what you need.
Labels:
Briel Altair 8800,
Cross-assembler,
Intel 8080
Monday, March 17, 2014
Using the CP/M Assembler
I'll continue giving more details on the programs I demonstrated in the YouTube video The Briel Altair 8800 Kit, Part 5: Advanced Topics.
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.
; Constants
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.
END
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.
org 100h
bdos equ 0005h ; BDOS entry point
start: mvi c,9 ; BDOS function: output string
lxi d,msg$ ; address of msg
call bdos
ret ; return to CCP
msg$: db 'Hello, world!$'
end
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.
B>a:asm hello1
CP/M ASSEMBLER - VER 2.0
0117
000H USE FACTOR
END OF ASSEMBLY
B>a:load hello1
FIRST ADDRESS 0100
LAST ADDRESS 0116
BYTES READ 0017
RECORDS WRITTEN 01
B>type hello1.hex
:100100000E09110901CD0500C948656C6C6F2C20E2
:07011000776F726C6421247B
:0000000000
B>type hello1.prn
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!$'
0117 end
B>a:ddt hello1.com
DDT VERS 2.2
NEXT PC
0180 0100
-l
0100 MVI C,09
0102 LXI D,0109
0105 CALL 0005
0108 RET
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
-^C
B>
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.
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.
; Constants
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.
END
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.
org 100h
bdos equ 0005h ; BDOS entry point
start: mvi c,9 ; BDOS function: output string
lxi d,msg$ ; address of msg
call bdos
ret ; return to CCP
msg$: db 'Hello, world!$'
end
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.
B>a:asm hello1
CP/M ASSEMBLER - VER 2.0
0117
000H USE FACTOR
END OF ASSEMBLY
B>a:load hello1
FIRST ADDRESS 0100
LAST ADDRESS 0116
BYTES READ 0017
RECORDS WRITTEN 01
B>type hello1.hex
:100100000E09110901CD0500C948656C6C6F2C20E2
:07011000776F726C6421247B
:0000000000
B>type hello1.prn
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!$'
0117 end
B>a:ddt hello1.com
DDT VERS 2.2
NEXT PC
0180 0100
-l
0100 MVI C,09
0102 LXI D,0109
0105 CALL 0005
0108 RET
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
-^C
B>
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.
Labels:
Altair 8800,
assembler,
Briel,
CP/M,
Intel 8080
Saturday, February 22, 2014
The Briel Altair 8800 Replica Kit
I recently built a Briel Altair 8800 computer kit. Introduced in 1975, the original Altair 880 was one of the first computers that could be built by a hobbyist. Microsoft's first consumer product was a version of BASIC for the Altair.

Vince Briel has been selling a replica of the Altair 8800 for a few years. As the front panel requires some custom manufacturing, the kits are offered in batches. Late last year pre-orders were taken for the fourth batch of the kits, and I placed my order for a kit (he also sells fully assembled systems). I also ordered the optional RAM disk that emulates two floppy disk drives and allows the system to run the CP/M operating system.

I've made a series of YouTube videos documenting my experiences with the system:
While I tried some original Altair programs like BASIC, and toggled some programs in with the front panel switches, mostly I have been running the CP/M operating system. I used CP/M back in the 1980s on several platforms, including an Apple II with a CP/M card. The old dial-up Bulletin Board (BBS) Systems, predating the Internet, often used CP/M and gave users command line access to it.

I'm having fun running old CP/M programs like the Star Trek and Zork adventure games and WordStar word processor.
Vince Briel has been selling a replica of the Altair 8800 for a few years. As the front panel requires some custom manufacturing, the kits are offered in batches. Late last year pre-orders were taken for the fourth batch of the kits, and I placed my order for a kit (he also sells fully assembled systems). I also ordered the optional RAM disk that emulates two floppy disk drives and allows the system to run the CP/M operating system.
I've made a series of YouTube videos documenting my experiences with the system:
- The Briel Altair 8800 Kit, Part 1: Unboxing
- The Briel Altair 8800 Kit, Part 2: Assembly
- The Briel Altair 8800 Kit, Part 3: Initial Powerup Tests and Basic Operation
- The Briel Altair 8800 Kit, Part 4: RAM Disk Board and Running CP/M
While I tried some original Altair programs like BASIC, and toggled some programs in with the front panel switches, mostly I have been running the CP/M operating system. I used CP/M back in the 1980s on several platforms, including an Apple II with a CP/M card. The old dial-up Bulletin Board (BBS) Systems, predating the Internet, often used CP/M and gave users command line access to it.
I'm having fun running old CP/M programs like the Star Trek and Zork adventure games and WordStar word processor.
Labels:
Altair 8800,
Briel Computers,
CP/M,
Intel 8080
Saturday, September 28, 2013
8080 Disassembler
I've ordered an Altair 8800 replica computer from Briel Computers. While I'm waiting for it to arrive, I've been reading up on the 8080 microprocessor, the Altair 8800, and CP/M operating system.
For fun I wrote an 8080 assembly language disassembler to help understand 8080 machine language and in preparation for playing with some 8080 assembler programs. I also used it as an opportunity to get more familiar with the Python programming language. It's the first significant program I've written in Python and it was relatively painless to code.
You can get the source code here. The program reads a binary file specified on the command line and produces a disassembly. It requires Python 3. It has been tested on Linux but should work on any platform that supports Python. See the source code for more details.
Here is some sample output using the first example program in the Altair 8800 manual:
% ./disasm8080.py ex2.bin
0000 org $0000
0000 3A 80 00 lda $0080
0003 47 mov b,a
0004 3A 81 00 lda $0081
0007 80 add b
0008 32 82 00 sta $0082
000B C3 00 00 jmp $0000
000E end
I implemented a number of options to control the output format such as the start address and whether to show the hex bytes or just instructions.
I'd say about one third of the effort was coding, one third was entering the table of 8080 instructions, and one third was learning how to do various things in Python, like reading a binary file and manipulating strings.
If is free software released under the Apache License. Give it a try if you are interested.
For fun I wrote an 8080 assembly language disassembler to help understand 8080 machine language and in preparation for playing with some 8080 assembler programs. I also used it as an opportunity to get more familiar with the Python programming language. It's the first significant program I've written in Python and it was relatively painless to code.
You can get the source code here. The program reads a binary file specified on the command line and produces a disassembly. It requires Python 3. It has been tested on Linux but should work on any platform that supports Python. See the source code for more details.
Here is some sample output using the first example program in the Altair 8800 manual:
% ./disasm8080.py ex2.bin
0000 org $0000
0000 3A 80 00 lda $0080
0003 47 mov b,a
0004 3A 81 00 lda $0081
0007 80 add b
0008 32 82 00 sta $0082
000B C3 00 00 jmp $0000
000E end
I implemented a number of options to control the output format such as the start address and whether to show the hex bytes or just instructions.
I'd say about one third of the effort was coding, one third was entering the table of 8080 instructions, and one third was learning how to do various things in Python, like reading a binary file and manipulating strings.
If is free software released under the Apache License. Give it a try if you are interested.
Labels:
Altair 8800,
Briel Computers,
Disassembler,
Intel 8080,
Python
Location:
Ottawa, ON, Canada
Subscribe to:
Posts (Atom)