Skip to content

Commit

Permalink
tp128: rcbus Z80 with 32K upper pageable memory
Browse files Browse the repository at this point in the history
Designed to boot from SCM Monitor
  • Loading branch information
EtchedPixels committed May 23, 2024
1 parent 29f5fd6 commit d8b3a48
Show file tree
Hide file tree
Showing 20 changed files with 1,638 additions and 0 deletions.
99 changes: 99 additions & 0 deletions Kernel/platform/platform-rcbus-tp128/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
CROSS_CCOPTS += -I../../dev/ -I../../dev/net/


CSRCS = devtty.c
CSRCS += devices.c main.c wiznet.c

DISCSRCS = discard.c

ASRCS = tp128.S crt0.S ide.S tricks.S commonmem.S

DISCARD_DSRCS = ../../dev/tinydisk_discard.c ../../dev/ds1302_discard.c ../../dev/tinyide_discard.c
DSRCS = ../../dev/tinydisk.c ../../dev/tinyide.c
DSRCS += ../../dev/ds1302.c
NSRCS = ../../dev/net/net_w5x00.c ../../dev/net/net_w5300.c ../../dev/net/net_native.c

DASRCS = ../../dev/ds1302_rcbusu.S

COBJS = $(CSRCS:.c=.o)
AOBJS = $(ASRCS:.S=.o)
NOBJS = $(patsubst ../../dev/net/%.c,%.o, $(NSRCS))
DISCOBJS = $(DISCSRCS:.c=.o)
DISCARD_DOBJS = $(patsubst ../../dev/%.c,%.o, $(DISCARD_DSRCS))
DOBJS = $(patsubst ../../dev/%.c,%.o, $(DSRCS))
DAOBJS = $(patsubst ../../dev/%.S,%.o, $(DASRCS))

OBJS = $(COBJS) $(AOBJS) $(NOBJS) $(DISCOBJS) $(DOBJS) $(DISCARD_DOBJS) $(DAOBJS)

JUNK = *.o

all: $(OBJS)

$(COBJS): %.o: %.c
$(CROSS_CC) $(CROSS_CCOPTS) -c $<

$(DISCOBJS): %.o: %.c
$(CROSS_CC) $(CROSS_CCOPTS) $(CROSS_CC_SEGDISC) -c $<

$(DOBJS): %.o: ../../dev/%.c
$(CROSS_CC) $(CROSS_CCOPTS) -c $<

$(DISCARD_DOBJS): %.o: ../../dev/%.c
$(CROSS_CC) $(CROSS_CCOPTS) $(CROSS_CC_SEGDISC) -c $<

$(NOBJS): %.o: ../../dev/net/%.c
$(CROSS_CC) $(CROSS_CCOPTS) -c $<

$(AOBJS): %.o: %.S
$(CROSS_AS) $(ASOPTS) $<

$(DAOBJS): %.o: ../../dev/%.S
$(CROSS_AS) $(ASOPTS) $@ $<

clean:
rm -f $(OBJS) $(JUNK) core *~ *.ihx *.bin *.o *.tmp *.s

#
# Attach the kernel to the boot block
#
image: loader.bin
$(CROSS_LD) -b -S 0x0080 -f SsLDBbXC -o fuzix.bin \
crt0.o commonmem.o tp128.o ../../start.o ../../version.o \
../../cpu-z80u/lowlevel-z80u.o ../../usermem.o tricks.o main.o discard.o \
../../timer.o ../../kdata.o devices.o ../../devio.o ../../filesys.o \
../../blk512.o ../../process.o ../../inode.o ../../syscall_exec.o \
../../syscall_exec16.o ../../syscall_fs.o ../../syscall_fs2.o \
../../syscall_fs3.o ../../syscall_proc.o ../../syscall_other.o \
../../syscall_net.o ../../network.o ../../tty.o ../../mm.o ../../mm/bankfixed.o \
../../mm/memalloc_none.o ../../swap.o ../../devsys.o devtty.o \
../../dev/tinydisk.o ../../dev/tinydisk_discard.o \
../../dev/tinyide.o ../../dev/tinyide_discard.o ide.o \
../../dev/ds1302.o ../../dev/ds1302_discard.o ../../dev/ds1302_rcbusu.o \
../../dev/net/net_native.o ../../dev/net/net_w5x00.o \
../../dev/net/net_w5300.o wiznet.o \
/opt/fcc/lib/z80/libz80.a -m fuzix.tmpmap
perl -lpe '$$_=hex' fuzix.tmpmap | paste -d" " - fuzix.tmpmap | sort -n | cut -d" " -f 2- >../../fuzix.map
cp fuzix.bin ../../fuzix.bin

#
# Compile up the boot block
#
loader.bin: loader.S
asz80 loader.S -o loader.o
ldz80 -b -C 0 loader.o -o loader.tmp
dd if=loader.tmp bs=256 skip=208 of=loader.bin

IMAGES = $(FUZIX_ROOT)/Images/$(TARGET)

diskimage:
# Make a blank disk image with partition
dd if=$(FUZIX_ROOT)/Standalone/filesystem-src/parttab.20M of=$(IMAGES)/disk.img bs=20152320 conv=sync
# Add the file system
dd if=$(IMAGES)/filesys8.img of=$(IMAGES)/disk.img bs=512 seek=2048 conv=notrunc
# Bootstrap (in two pieces to avoid the partition table)
dd if=loader.bin of=$(IMAGES)/disk.img bs=446 count=1 conv=notrunc
dd if=loader.bin of=$(IMAGES)/disk.img bs=512 skip=1 seek=1 conv=notrunc
# And kernel
dd if=../../fuzix.bin of=$(IMAGES)/disk.img bs=256 seek=48 conv=notrunc
# Make an emulator image of it
cat $(FUZIX_ROOT)/Standalone/filesystem-src/idehdr.20M $(IMAGES)/disk.img > $(IMAGES)/emu-ide.img
30 changes: 30 additions & 0 deletions Kernel/platform/platform-rcbus-tp128/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Fuzix for RCbus with Tadeusz 128K RAM board

This is a banked RAM board that gives us a couple of 32K banks for user
space. Not ideal but usable within limits. User space lies in the upper 32K
of memory as the banking banks the high not low space.

## Supported Hardware

- Onboard CF adapter
- SIO

## TODO
- Add ACIA

## Optional Devices

- CTC card at 0x88 (including SIO B port speed control). Requires channels 2 and 3 are chained.
- DS1302 at 0x0C or 0xC0

## Time Sources

This must be supplied by an external card or the system will hang on
boot. The CTC provides a proper interval timer and is recommended. The RTC
provides a very slow to read clock only.

## Devices To Maybe Add

- TMS9918A video (and vblank timer interrupt)
- PS/2 keyboard and mouse
- External timer on a carrier pin
9 changes: 9 additions & 0 deletions Kernel/platform/platform-rcbus-tp128/commonmem.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
;
; The common memory area traditionally starts with the udata and the
; interrupt stacks. As this is standard in almost all cases you can
; just include the standard implementation.
;
.common

#include "../../cpu-z80u/std-commonmem.S"

135 changes: 135 additions & 0 deletions Kernel/platform/platform-rcbus-tp128/config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
/* Enable to make ^Z dump the inode table for debug */
#undef CONFIG_IDUMP
/* Enable to make ^A drop back into the monitor */
#undef CONFIG_MONITOR
/* Profil syscall support (not yet complete) */
#undef CONFIG_PROFIL
/* Multiple processes in memory at once */
#define CONFIG_MULTI

/* Select a banked memory set up */
#define CONFIG_BANK_FIXED
/* This is the number of banks of user memory available (maximum) */
#define MAX_MAPS 3 /* 128 KByte... minus the kernel one */
/* How big is each bank - in our case 32K, 48K is actually more common. This
is hardware dependant */
#define MAP_SIZE 0x8000
/* How many banks do we have in our address space */
#define CONFIG_BANKS 2 /* 2 x 32K */

/*
* Define the program loading area (needs to match kernel.def)
*/
#define PROGBASE 0x8000 /* Base of user */
#define PROGLOAD 0x8000 /* Load and run here */
#define PROGTOP 0xFE00 /* Top of program, base of U_DATA stash */
#define PROC_SIZE 32 /* Memory needed per process including stash */
/*
* Definitions for swapping.
*/
#define SWAPDEV (swap_dev) /* A variable for dynamic, or a device major/minor */
extern uint16_t swap_dev;
#define SWAP_SIZE 0x40 /* 32K in 512 byte blocks */
#define SWAPBASE 0x8000 /* We swap the lot in one, include the */
#define SWAPTOP 0x10000UL /* vectors so its a round number of sectors */

#define MAX_SWAPS 16 /* Maximum number of swapped out processes.
As we use the default 15 process max this
is definitely sufficient (14 would do) */
/*
* When the kernel swaps something it needs to map the right page into
* memory using map_for_swap and then turn the user address into a
* physical address. For a simple banked setup there is no conversion
* needed so identity map it.
*/
#define swap_map(x) ((uint8_t *)(x))

/*
* Disk devices. For now just the onboard CF adapter using TINYDISK
* to do all the work. See plt_ide.h for the hardware config, the rest
* is handled by the drivers not the port.
*/

#define CONFIG_TD
#define CONFIG_TD_NUM 1
#define CONFIG_TD_IDE
#define CONFIG_TINYIDE_8BIT
#define CONFIG_TINYIDE_INDIRECT
#define IDE_IS_8BIT(x) 1

#define BOOTDEVICENAMES "hd#"

/* We will resize the buffers available after boot. This is the normal setting */
#define CONFIG_DYNAMIC_BUFPOOL
/* Swap will be set up when a suitably labelled partition is seen */
#define CONFIG_DYNAMIC_SWAP
/* Larger transfers (including process execution) should go directly not via
the buffer cache. For all small (eg bit) systems this is the right setting
as it avoids polluting the small cache with data when it needs to be full
of directory and inode information */
#define CONFIG_LARGE_IO_DIRECT(x) 1

/* Specify this if there is a real time clock capable of reporting seconds. It
will be used to lock the kernel time better to reality. Other details like
Y2K support, or even supporting dates as well don't matter */
#define CONFIG_RTC_DS1302
#define CONFIG_RTC
/* Specify that there is a full real time clock that can supply the date and
time to the system. */
#define CONFIG_RTC_FULL
/* Set this if the system has no proper real time clock (or has configurations
where it lacks one). This is not usually needed but for platforms it is also
see platform-sbcv2/main.c on what is needed */
#define CONFIG_NO_CLOCK
/* Set how often we actually poll this RTC in ticks - 1 means always. On the
SBCv2 it's slow so don't sync often. If we have no timer tick then we will
read the RTC regularly as needed - and it'll suck accordingly regardless
of this setting */
#define CONFIG_RTC_INTERVAL 100
/*
* How fast does the clock tick (if present), or how many times a second do
* we simulate if not. For a machine without video 10 is a good number. If
* you have video you probably want whatever vertical sync/blank interrupt
* rate the machine has. For many systems it's whatever the hardware gives
* you.
*
* Note that this needs to be divisible by 10 and at least 10. If your clock
* is a bit slower you may need to fudge things somewhat so that the kernel
* gets 10 timer interrupt calls per second.
*/
#define TICKSPERSEC 10 /* Ticks per second */

/* Core networking support */
#define CONFIG_NET
/* With a WizNet card */
#define CONFIG_NET_WIZNET
#undef CONFIG_NET_W5100
#define CONFIG_NET_W5300

/*
* The device (major/minor) for the console and boot up tty attached to
* init at start up. 512 is the major 2, so all the tty devices are
* 512 + n where n is the tty.
*/
#define BOOT_TTY (512 + 1) /* Set this to default device for stdio, stderr */
/* In this case, the default is the first TTY device */
/*
* If you have a mechanism to pass in a root device configuration then
* this holds the address of the buffer (eg a CP/M command line or similar).
* If the configuration is fixed then this can be a string holding the
* configuration. NULL means 'prompt the user'.
*/
#define CMDLINE NULL /* Location of root dev name */

/* Device parameters */
#define NUM_DEV_TTY 2 /* How many tty devices does the platform support */
#define TTYDEV BOOT_TTY /* Device used by kernel for messages, panics */
#define NBUFS 5 /* Number of block buffers. Must be 4+ and must match
kernel.def */
#define NMOUNTS 4 /* Number of mounts at a time */

/* This can optionally be set to force a default baud rate, eg if the system
console should match a firmware set rate */
#define TTY_INIT_BAUD B115200

#define plt_copyright()
25 changes: 25 additions & 0 deletions Kernel/platform/platform-rcbus-tp128/crt0.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
; startup code
.common

; Load at 0x0080
start:
di
ld sp, kstack_top
; zero the BSS area
ld hl, __bss
ld de, __bss + 1
ld bc, __bss_size - 1
ld (hl), 0
ldir
; Zero buffers area
ld hl, __buffers
ld de, __buffers + 1
ld bc, __buffers_size - 1
ld (hl), 0
ldir
call init_early
call init_hardware
call _fuzix_main
di
stop: halt
jr stop
43 changes: 43 additions & 0 deletions Kernel/platform/platform-rcbus-tp128/devices.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#include <kernel.h>
#include <tty.h>
#include <version.h>
#include <kdata.h>
#include <devsys.h>
#include <devtty.h>
#include <tinydisk.h>
#include <printf.h>

/*
* This table is the glue that holds all the kernel device driver
* logic together. Each device driver provides methods for
* open, close, read, write and ioctl, although it can opt to use
* defaults as well.
*
* The validdev function is the same for all platforms but has to live
* in the same file as the table. Just paste it into each.
*/

struct devsw dev_tab[] = /* The device driver switch table */
{
/* 0: /dev/hd Hard disc block devices */
{ td_open, no_close, td_read, td_write, td_ioctl },
/* 1: /dev/fd Floppy disc block devices */
{ no_open, no_close, no_rdwr, no_rdwr, no_ioctl },
/* 2: /dev/tty TTY devices */
{ tty_open, tty_close, tty_read, tty_write, tty_ioctl },
/* 3: /dev/lpr Printer devices */
{ nxio_open, no_close, no_rdwr, no_rdwr, no_ioctl },
/* 4: /dev/mem etc System devices (one offs) */
{ no_open, no_close, sys_read, sys_write, sys_ioctl },
/* Pack to 7 with nxio if adding private devices and start at 8 */
};

bool validdev(uint16_t dev)
{
/* This is a bit uglier than needed but the right hand side is
a constant this way */
if(dev > ((sizeof(dev_tab)/sizeof(struct devsw)) << 8) - 1)
return false;
else
return true;
}
Loading

0 comments on commit d8b3a48

Please sign in to comment.