Showing posts with label Intel 8080. Show all posts
Showing posts with label Intel 8080. Show all posts

Sunday, March 30, 2014

JMON - 8080 Version

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?).

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.

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.

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.

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.