Skip to content

Commit

Permalink
Merge development so far - initial success
Browse files Browse the repository at this point in the history
There is a somewhat working system without disk write, and incorrect disk parameters, but can do `DIR` and load/run `MBASIC.COM` for example.
  • Loading branch information
lgblgblgb authored Oct 4, 2024
1 parent e859a41 commit cbe2e3b
Show file tree
Hide file tree
Showing 57 changed files with 7,225 additions and 3 deletions.
13 changes: 13 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
*.c linguist-language=C
*.h linguist-language=C
*.cdata linguist-language=C
*.asm linguist-language=Assembly
*.inc linguist-language=Assembly
*.s linguist-language=Assembly
*.S linguist-language=Assembly
*.a65 linguist-language=Assembly
*.i65 linguist-language=Assembly
Makefile.* linguist-language=Makefile
Makefile linguist-language=Makefile
*.mk linguist-language=Makefile
*.py linguist-language=Python
13 changes: 13 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*.o
/*.map
/*.sym
/*.pyc
/*.pyo
/*.d81
/*.prg
/*.lst
/uart.sock
/dump.mem
/serial.raw
/runme.bin
/cpm.dsk
3 changes: 3 additions & 0 deletions 8080/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/*.lst
/*.sym
/mbasic-real.com
16 changes: 16 additions & 0 deletions 8080/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
SJASM = sjasm
ALL_DEPENDS = Makefile
CPM_UTILS = cpmver.asm
BINARIES = $(CPM_UTILS:.asm=.com)

all: $(BINARIES)

%.com: %.asm $(ALL_DEPENDS)
$(SJASM) -s $< $@ || { rm -f $@ $(@:.com=.lst) $(@:.com=.sym) ; false; }


clean:
$(RM) -f *.sym *.lst $(BINARIES)


.PHONY: all clean
91 changes: 91 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
## i8080 CPU emulator and CP/M v2.2 compatible BIOS for MEGA65
##
## Copyright (C)2017,2024 LGB (Gábor Lénárt) <[email protected]>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.


DISK_IMAGE = emu.d81
PRG = emu.prg
LD65_CFG = emu.ld
PRG_ON_DISK = emu
MAP_FILE = emu.map
SOURCES = console.asm cpu.asm loader.asm main.asm shell.asm fontdata.asm disk.asm
INCLUDES = $(shell ls *.inc) cpm/bios.inc cpm/cpm22.inc
OBJECTS = $(SOURCES:.asm=.o)
M65_IP = 192.168.0.65
ALL_DEPENDS = Makefile

CA65_OPTS = -t none
LD65_OPTS = -C $(LD65_CFG) -m $(MAP_FILE) -vm

XEMU_M65 = xemu-xmega65
#XEMU_M65 = /home/lgb/prog_here/xemu-dev/build/bin/xmega65.native

ETHERLOAD = mega65-etherload
C1541 = c1541
CA65 = ca65
LD65 = ld65
RM = rm
GUNZIP = gunzip


all: $(DISK_IMAGE)

cpu_tables.inc: cpu_gen_tables.py
rm -f cpu_tables.inc
./cpu_gen_tables.py > $@

cpm/bios.inc cpm/cpm22.inc cpm/bios.bin cpm/cpm22.bin:
$(MAKE) -C cpm

%.o: %.asm $(ALL_DEPENDS) $(INCLUDES)
$(CA65) $(CA65_OPTS) --listing $(<:.asm=.lst) -o $@ $<

main.o: 8080/*.com 8080/mbasic-real.com

$(PRG): $(OBJECTS) $(LD65_CFG) $(ALL_DEPENDS)
$(LD65) $(LD65_OPTS) -o $@ $(OBJECTS)

cpm.dsk: diskdefs Makefile
rm -f $@
mkfs.cpm -f mega65 $@
cpmcp -f mega65 $@ dist/cpm-apps/* 0:
cpmls -f mega65 -D $@

runme.bin: runme.asm
cl65 -t none -o $@ $<

$(DISK_IMAGE): $(PRG) runme.bin cpm.dsk $(ALL_DEPENDS)
$(RM) -f $@
echo "format lgb-test,00 d81 $@\nwrite runme.bin runme\nwrite $(PRG) $(PRG_ON_DISK)\nwrite cpm.dsk\ndir\n" | $(C1541)

ethertest: $(PRG) $(ALL_DEPENDS)
$(ETHERLOAD) $(M65_IP) $(PRG)

xemu: $(PRG) $(DISK_IMAGE)
$(XEMU_M65) -hyperserialfile serial.raw -fastboot -8 $(DISK_IMAGE) -initattic cpm.dsk -prg $(PRG)

dist: $(DISK_IMAGE)
cp emu.d81 dist/bin/mega65.d81

clean:
$(RM) -f $(PRG) *.o *.lst $(DISK_IMAGE) $(MAP_FILE) runme.bin cpm.dsk
$(MAKE) -C cpm clean

distclean:
$(MAKE) clean
$(RM) -f 8080/*.com uart.sock dump.mem serial.raw

.PHONY: all clean distclean xemu ethertest dist
69 changes: 66 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,68 @@
# TODO
# MEGA/80: i8080 emulator and CPM BIOS for MEGA65

Trying to renew my old project from 2017 to be able to run CP/M on MEGA65
with i8080 (for now, later: Z80) emulated in software.
I'm trying to renew my old project from 2017 to be able to run CP/M on MEGA65
with i8080 (for now, later: Z80) emulated in software equipped with a custom
CBIOS for the task. The 65816 CPU also seems to be a possible target to port
future Z80 emulation (I wouldn't do for the current i8080 since I will rewrite
the emulator anyway).

## Running CP/M

For now, i8080 CPU (which is the original CPU for CP/M, not the Z80) is emulated.
A custom CP/M v2.2 is provided dispatching the work to the native 65xx implementation
via HALT opcodes. For now, original DR's CPM (BDOS and CCP) v2.2 is used.

## Download

Have a look in directory `dist/bin` for a D81 disk image file (`mega65.d81`) for MEGA65.

## Limitations / problems / plans

* Current code base is chaotic since major parts of it was written by me in 2017 and I only
try to revive some unfinished old work of mine here
* So far only i8080 emulation, not Z80: newer CP/M programs written for Z80 won't work
* Even i8080 is not emulated perfectly, no half-carry flag and no DAA and for sure can be many bugs
* Original DR BDOS and CCP. There are open souce GNU/GPL replacements but requires Z80
* In nutshell, I would guess I'll go for Z80 emulation later and don't plan to fix i8080 emulation bugs too much
* No real disk access, CP/M disk image is copied to MEGA65 Attic RAM on startup and all changes later will be lost
* Only "dumb" terminal emulation, `CR`, `LF` and `BS` is interpreted. For more advanced CP/M programs, some terminal emulation should be done
* Need some tool which at least makes possible to easily import files into CP/M from MEGA65 SD card or such (at runtime)
* Porting to other systems: 65816 CPU seems to be a viable option for porting, and machines using that CPU and having enough memory:
* Commodore 64 with SuperCPU
* Commander X16 **if** CPU is 65816 and it can access RAM in higher bankes freely
* Apple IIgs? Unfortunately I don't know too much about Apple computers, but could be a fun ...
* Porting for non-65xx CPU based platforms: certainly it's not impossible but then you need to rewrite everything,
as it's an assembly project.
* Integrated on-the-fly memory monitor and things like that
* No, I don't plan CP/M v3. The problem: it requires extensive bank switching and other difficulties,
since I'm emulating i8080 (later hopefully a Z80) emulating bank switching would be impossible or very slow

## Building

Tools needed to build:

### CC65

Various tools (ca65, ld65, cl65) from the CC65 suite to assemble 65xx assembly sources:

Only tested with V2.18 (as of I am writing this), so any older version can cause
problems. Currently the C compiler part (cc65) is not used though.

### SjASMPlus

SjASMPlus Z80 Cross-Assembler to assemble i8080 / Z80 assembly sources: https://github.com/z00m128/sjasmplus

Only tested with version v1.20.3 (as of I am writing this), so any older version
can cause problems, like certain ASSERT features was introduced in v1.18.1 but there
can be other problems as well.

### Standard UNIX stuff, like sed, make ...

### Python 3

### c1541

### cpmtools

### wget

67 changes: 67 additions & 0 deletions README.md.OLD
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# i8080 (software) emulator and CP/M for the MEGA65

Foreword: this project of mine is from 2017! Now I'm trying to catching up
again.

Goal: to try to provide a CP/M for the MEGA65 with software emulation of the
i8080 CPU initially, Z80 later and writing a CP/M v2.2 compatible BIOS so
the original DR BDOS (or some replacement like ZSDOS - though it will require
a Z80 emulation) can work.


However CP/M application runs with the 8080 emulation using some "trap opcode"
to dispatch BIOS and BDOS call into native mode. File system based (only file
level, not disk block!) would be translated to MEGA65 hypervisor DOS calls,
thus the native SD-Card formatted for FAT32 would be usable by orginal CP/M
applications as well.

This project contains the following major "tricks" (not so much tricks, and
maybe not as good as it can be, but still some ideas and examples on M65):

* C65 basic-stub loader (so you must start the program in C65 mode! Not C64!!)
* Usage of MAP opcode, C65/M65 memory model, etc
* M65 speed control
* "32 bit linear addressing" opcodes
* M65 direct character "WOM" (write-only memory) access
* Usage of some 65CE02 opcodes (but some of them exists on 65C02 or 65816 as
well, though the opcode bytes can be even different!), like TRB, TSB,
BBRx, BBSx, SMBx, RMBx, Z-reg pased ops, INW, 16 bit branches, and such.
* As a bonus: one time it already helped to find a bug in Xemu/MEGA65 with
rarely used CPU feature (ADC opcode with 32 bit addressing)

## Compile

As usual, you need quite decent CA65 (from cc65) assembler with "4510" CPU
support (currently, maybe only git version is good enough for this?). You
also need an average UNIX-or UNIX like (Linux, OSX, even maybe Windows with
cygwin, or some Linux-box solution) development environment, with GNU make,
wget, and other standard utilities. You also need Python to be installed.

You can say 'make' to compile everything, or 'make test' to test the result
in Xemu MEGA65 emulation (you need only the binary to be installed somewhere
in your search path, it will fetch things for you, if needed with wget).

## Current problems and limitations

* i8080 emulation is farily complete as the emulated opcodes, though there
can be huge amount of bugs, not so much tested. Also now only "DAA"
is not emulated, since the half-carry flag is not emulated at all, it's
really a pain in the ass to do :(
* Also, some i8080 features are not implemented, like the "half-carry" flag,
which may cause problems (surly with DAA but there can be other cases too)
* "Terminal" handling is a big mess of unoptimized quickly written code,
this is not the major point for now
* i8080 emulation has problems with cases when operands/etc would cross the
64K boundary. Surely it can be handled, but emulation would be slower to
do this. I think, this case shouldn't be used anyway by a regular CP/M
program too much ...
* Of course there can be TONS of bogs on opcode emulations ...
* Usage of M65 character-WOM is neat idea to demonstrate the technique, but
it has a serious problem: after "exiting", screen will be messed up, because
my i8080 emulator installs ASCII-compatible character generator layout for
more comfortable usage of I/O routines.
* Currently not so much BDOS and BIOS calls work, what would be the major
intent here, besides the 8080 emulation.
* "Console" emulation if fairly incomplete, screen scrolling should be done
with DMA, control codes should be implemented, there is no keyboard yet
at all (only output), etc ...
11 changes: 11 additions & 0 deletions boot/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
CPMSYS = ../emu.prg
MAXBLOCKS = 100

boot: boot.asm $(CPMSYS) config_maker.py Makefile
rm -f boot.inc
python config_maker.py $(CPMSYS) $(MAXBLOCKS) > boot.inc
cl65 -t none --cpu 4510 --config boot.ld -o boot boot.asm

clean:
rm -f boot boot.inc *.o

2 changes: 2 additions & 0 deletions boot/README
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
https://codebase64.org/doku.php?id=base:reading_a_sector_from_disk

26 changes: 26 additions & 0 deletions boot/boot.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
; Boot code, needs "BOOT SYS" command from BASIC65

.INCLUDE "boot.inc" ; file created by config_maker.py

.CODE

JMP boot ; we want to jump over the disk identifier, ALSO "JMP" ($4C opc) is a must for ROM to be recognized!

.BYTE "MC80" ; disk indentifier (at offset 3, we are now) for MEGA65 CP/M

boot:

RTS

JMP LOAD_ADDR ; pass control to the loaded program





.SEGMENT "PAYLOAD"
.INCBIN LOAD_BIN_FN, LOAD_OFFSET
.IF PADDING <> 0
.RES PADDING, $00
.ENDIF

15 changes: 15 additions & 0 deletions boot/boot.ld
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
FEATURES {
STARTADDRESS: default = $400;
}
MEMORY {
ZP: file = "", define = yes, start = $0002, size = $00F0;
# RAM: file = %O, start = %S, size = $C000 - %S, define = yes;
BOOTSECTOR: file = %O, start = $400, size = $200, define = yes, fill = yes;
CPMSYS: file = %O, start = $2001 - 2, size = $C000 - $2001 - 2;
}
SEGMENTS {
ZEROPAGE: load = ZP, type = zp;
CODE: load = BOOTSECTOR;
PAYLOAD: load = CPMSYS, define = yes;
BSS: load = CPMSYS, type = BSS;
}
Loading

0 comments on commit cbe2e3b

Please sign in to comment.