From fe0dbfa3f572257bbba4fcbed819198ee9515abc Mon Sep 17 00:00:00 2001 From: ajcasado Date: Wed, 8 Jan 2025 19:41:09 +0100 Subject: [PATCH 1/7] Remove unused files --- Kernel/platform/platform-cpc6128/devinput.c | 51 --------------------- Kernel/platform/platform-cpc6128/devinput.h | 2 - 2 files changed, 53 deletions(-) delete mode 100644 Kernel/platform/platform-cpc6128/devinput.c delete mode 100644 Kernel/platform/platform-cpc6128/devinput.h diff --git a/Kernel/platform/platform-cpc6128/devinput.c b/Kernel/platform/platform-cpc6128/devinput.c deleted file mode 100644 index 34e287b76d..0000000000 --- a/Kernel/platform/platform-cpc6128/devinput.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Joysticks off the AY sound chip - */ -#include -#include -#include -#include - -static char buf[32]; - -static struct s_queue kqueue = { - buf, buf, buf, sizeof(buf), 0, sizeof(buf) / 2 -}; - -/* Queue a character to the input device */ -void queue_input(uint8_t c) -{ - insq(&kqueue, c); - wakeup(&kqueue); -} - - -int plt_input_read(uint8_t *slot) -{ - uint8_t r, k; - if (remq(&kqueue, &r)) { - remq(&kqueue, &k); - *slot++ = KEYPRESS_CODE | r; - *slot = k; - return 2; - } - return 0; -} - -void plt_input_wait(void) -{ - psleep(&kqueue); /* We wake this on timers so it works for sticks */ -} - -int plt_input_write(uint8_t flag) -{ - flag; - udata.u_error = EINVAL; - return -1; -} - -void poll_input(void) -{ - wakeup(&kqueue); -} - \ No newline at end of file diff --git a/Kernel/platform/platform-cpc6128/devinput.h b/Kernel/platform/platform-cpc6128/devinput.h deleted file mode 100644 index 981f702450..0000000000 --- a/Kernel/platform/platform-cpc6128/devinput.h +++ /dev/null @@ -1,2 +0,0 @@ -extern void queue_input(uint8_t); -extern void poll_input(void); From 001112003685b83a22663e333159aeac088cee03 Mon Sep 17 00:00:00 2001 From: ajcasado Date: Wed, 8 Jan 2025 19:42:25 +0100 Subject: [PATCH 2/7] Remove unused sources from Makefile --- Kernel/platform/platform-cpc6128/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Kernel/platform/platform-cpc6128/Makefile b/Kernel/platform/platform-cpc6128/Makefile index 802b937c8d..cd09e33d16 100644 --- a/Kernel/platform/platform-cpc6128/Makefile +++ b/Kernel/platform/platform-cpc6128/Makefile @@ -1,7 +1,7 @@ CSRCS = devtty.c devices.c main.c CDSRCS = discard.c -DSRCS = ../../dev/tinyide.c ../../dev/tinydisk.c ../../dev/devfdc765.c ../../dev/tinysd.c ../../dev/ch375.c -DDSRCS = ../../dev/tinyide_discard.c ../../dev/tinydisk_discard.c ../../dev/tinysd_discard.c +DSRCS = ../../dev/tinyide.c ../../dev/tinydisk.c ../../dev/devfdc765.c ../../dev/ch375.c +DDSRCS = ../../dev/tinyide_discard.c ../../dev/tinydisk_discard.c DZSRCS = ../../dev/cpc/cpcide.c ../../dev/cpc/cpckeyboard.c ../../dev/cpc/devinput.c ../../dev/cpc/albireo.c DDZSRCS = ASRCS = crt0.s cpc6128.s cpcvideo.s fdc765.s From cd56063b53258f147fa56c4c1c38db5cbf293cd3 Mon Sep 17 00:00:00 2001 From: ajcasado Date: Wed, 15 Jan 2025 22:46:37 +0100 Subject: [PATCH 3/7] Add platform for Amstrad CPC with standard memory expansion used as ram disk for swap --- Kernel/platform/platform-cpc6128-SME/Makefile | 86 +++ Kernel/platform/platform-cpc6128-SME/Notes.md | 22 + Kernel/platform/platform-cpc6128-SME/README | 68 +++ .../platform/platform-cpc6128-SME/commonmem.s | 9 + Kernel/platform/platform-cpc6128-SME/config.h | 104 ++++ .../platform/platform-cpc6128-SME/cpc6128.s | 373 ++++++++++++ .../platform/platform-cpc6128-SME/cpcvideo.s | 44 ++ Kernel/platform/platform-cpc6128-SME/crt0.s | 211 +++++++ .../platform/platform-cpc6128-SME/devices.c | 63 +++ Kernel/platform/platform-cpc6128-SME/devrd.c | 80 +++ Kernel/platform/platform-cpc6128-SME/devrd.h | 20 + Kernel/platform/platform-cpc6128-SME/devtty.c | 132 +++++ Kernel/platform/platform-cpc6128-SME/devtty.h | 24 + .../platform/platform-cpc6128-SME/discard.c | 31 + Kernel/platform/platform-cpc6128-SME/fdc765.s | 530 ++++++++++++++++++ .../fuzix-platform-cpc6128-SME.pkg | 7 + .../platform-cpc6128-SME/fuzix.export | 0 .../platform-cpc6128-SME/fuzix.lnk.bck | 59 ++ .../platform/platform-cpc6128-SME/kernel.def | 13 + Kernel/platform/platform-cpc6128-SME/loader.s | 413 ++++++++++++++ .../platform-cpc6128-SME/loader_firmware.s | 94 ++++ Kernel/platform/platform-cpc6128-SME/main.c | 156 ++++++ .../platform-cpc6128-SME/platform_fdc765.h | 12 + .../platform/platform-cpc6128-SME/plt_ch375.h | 14 + .../platform/platform-cpc6128-SME/plt_ide.h | 13 + .../platform/platform-cpc6128-SME/rd_cpcsme.s | 107 ++++ Kernel/platform/platform-cpc6128-SME/rules.mk | 2 + .../platform/platform-cpc6128-SME/target.mk | 1 + Kernel/platform/platform-cpc6128-SME/tricks.s | 5 + 29 files changed, 2693 insertions(+) create mode 100644 Kernel/platform/platform-cpc6128-SME/Makefile create mode 100644 Kernel/platform/platform-cpc6128-SME/Notes.md create mode 100644 Kernel/platform/platform-cpc6128-SME/README create mode 100644 Kernel/platform/platform-cpc6128-SME/commonmem.s create mode 100644 Kernel/platform/platform-cpc6128-SME/config.h create mode 100644 Kernel/platform/platform-cpc6128-SME/cpc6128.s create mode 100644 Kernel/platform/platform-cpc6128-SME/cpcvideo.s create mode 100644 Kernel/platform/platform-cpc6128-SME/crt0.s create mode 100644 Kernel/platform/platform-cpc6128-SME/devices.c create mode 100644 Kernel/platform/platform-cpc6128-SME/devrd.c create mode 100644 Kernel/platform/platform-cpc6128-SME/devrd.h create mode 100644 Kernel/platform/platform-cpc6128-SME/devtty.c create mode 100644 Kernel/platform/platform-cpc6128-SME/devtty.h create mode 100644 Kernel/platform/platform-cpc6128-SME/discard.c create mode 100644 Kernel/platform/platform-cpc6128-SME/fdc765.s create mode 100644 Kernel/platform/platform-cpc6128-SME/fuzix-platform-cpc6128-SME.pkg create mode 100644 Kernel/platform/platform-cpc6128-SME/fuzix.export create mode 100644 Kernel/platform/platform-cpc6128-SME/fuzix.lnk.bck create mode 100644 Kernel/platform/platform-cpc6128-SME/kernel.def create mode 100644 Kernel/platform/platform-cpc6128-SME/loader.s create mode 100644 Kernel/platform/platform-cpc6128-SME/loader_firmware.s create mode 100644 Kernel/platform/platform-cpc6128-SME/main.c create mode 100644 Kernel/platform/platform-cpc6128-SME/platform_fdc765.h create mode 100644 Kernel/platform/platform-cpc6128-SME/plt_ch375.h create mode 100644 Kernel/platform/platform-cpc6128-SME/plt_ide.h create mode 100644 Kernel/platform/platform-cpc6128-SME/rd_cpcsme.s create mode 100644 Kernel/platform/platform-cpc6128-SME/rules.mk create mode 100644 Kernel/platform/platform-cpc6128-SME/target.mk create mode 100644 Kernel/platform/platform-cpc6128-SME/tricks.s diff --git a/Kernel/platform/platform-cpc6128-SME/Makefile b/Kernel/platform/platform-cpc6128-SME/Makefile new file mode 100644 index 0000000000..e5ca626012 --- /dev/null +++ b/Kernel/platform/platform-cpc6128-SME/Makefile @@ -0,0 +1,86 @@ +CSRCS = devtty.c devices.c main.c devrd.c +CDSRCS = discard.c +DSRCS = ../../dev/tinyide.c ../../dev/tinydisk.c ../../dev/devfdc765.c ../../dev/ch375.c +DDSRCS = ../../dev/tinyide_discard.c ../../dev/tinydisk_discard.c +DZSRCS = ../../dev/cpc/cpcide.c ../../dev/cpc/cpckeyboard.c ../../dev/cpc/devinput.c ../../dev/cpc/albireo.c +DDZSRCS = +ASRCS = crt0.s cpc6128.s cpcvideo.s fdc765.s rd_cpcsme.s +ASRCS += tricks.s commonmem.s +NSRCS = + +COBJS = $(CSRCS:.c=.rel) +CDOBJS = $(CDSRCS:.c=.rel) +AOBJS = $(ASRCS:.s=.rel) +DOBJS = $(patsubst ../../dev/%.c,%.rel, $(DSRCS)) +DDOBJS = $(patsubst ../../dev/%.c,%.rel, $(DDSRCS)) +DZOBJS = $(patsubst ../../dev/cpc/%.c,%.rel, $(DZSRCS)) +DDZOBJS = $(patsubst ../../dev/cpc/%.c,%.rel, $(DDZSRCS)) +NOBJS = $(patsubst ../../dev/net/%.c,%.rel, $(NSRCS)) +OBJS = $(COBJS) $(CDOBJS) $(AOBJS) $(DOBJS) $(DDOBJS) $(DZOBJS) $(DDZOBJS) $(NOBJS) + +CROSS_CCOPTS += -I../../dev/ -I../../dev/cpc/ -I../../dev/net + +CROSS_CC_SEG3 = --codeseg CODE3 + +all: $(OBJS) + +$(COBJS): %.rel: %.c + $(CROSS_CC) $(CROSS_CCOPTS) $(CROSS_CC_SEG3) -c $< + +$(CDOBJS): %.rel: %.c + $(CROSS_CC) $(CROSS_CCOPTS) $(CROSS_CC_SEGDISC) -c $< + +$(DOBJS): %.rel: ../../dev/%.c + $(CROSS_CC) $(CROSS_CCOPTS) $(CROSS_CC_SEG3) -c $< + +$(DDOBJS): %.rel: ../../dev/%.c + $(CROSS_CC) $(CROSS_CCOPTS) $(CROSS_CC_SEGDISC) -c $< + +$(DZOBJS): %.rel: ../../dev/cpc/%.c + $(CROSS_CC) $(CROSS_CCOPTS) $(CROSS_CC_SEG3) -c $< + +$(DDZOBJS): %.rel: ../../dev/cpc/%.c + $(CROSS_CC) $(CROSS_CCOPTS) $(CROSS_CC_SEGDISC) -c $< + +$(NOBJS): %.rel: ../../dev/net/%.c + $(CROSS_CC) $(CROSS_CCOPTS) -c $< + +$(AOBJS): %.rel: %.s + $(CROSS_AS) $(ASOPTS) $< + +clean: + rm -f $(OBJS) *.lst *.asm *.sym *.rst *.rel core *~ + rm -f loader.tmp loader.ihx loader.lst loader.bin padding.bin disk.raw + rm -rf fuzix.dsk + +image: + # Copy snapshot file template, transfer fuzix code to 0x100 and set execution at 0x100 + cp $(FUZIX_ROOT)/Standalone/filesystem-src/6128.sna $(IMAGES)/ + createSnapshot $(IMAGES)/6128.sna --loadFileData ../../fuzix.bin 256 + printf '\x01' | dd of=$(IMAGES)/6128.sna bs=1 seek=24 conv=notrunc + sdasz80 -l -o loader.s + sdldz80 -i loader.rel + hex2bin loader.ihx + + dd if=/dev/zero of=padding.bin bs=512 count=360 + # Make a disk image to work from + dd if=loader.bin of=padding.bin seek=0 bs=512 conv=notrunc + dd if=../../fuzix.bin of=padding.bin bs=512 seek=1 conv=notrunc + cat padding.bin >disk.raw + # And generate a 40 track cpc system disk from it + ../../tools/raw2dskcpc disk.raw fuzix.dsk 40 1 64 + cp fuzix.dsk $(IMAGES)/fuzix.dsk + +IMAGES = $(FUZIX_ROOT)/Images/$(TARGET) + +diskimage: + # Make a blank disk image with partition + dd if=$(FUZIX_ROOT)/Standalone/filesystem-src/parttab.64M of=$(IMAGES)/disk.img bs=64M conv=sync + # Add the file system + dd if=$(IMAGES)/filesys.img of=$(IMAGES)/disk.img bs=512 seek=2048 conv=notrunc + dd if=$(IMAGES)/filesys8.img of=$(IMAGES)/disk.img bs=512 seek=67584 conv=notrunc + # Make an emulator image of it + cat $(FUZIX_ROOT)/Standalone/filesystem-src/hdfheader $(IMAGES)/disk.img > $(IMAGES)/emu-ide.hdf + (cd $(FUZIX_ROOT)/Standalone/filesystem-src; ./build-mini-filesystem $(ENDIANFLAG) $(FUZIX_ROOT)/Images/$(TARGET)/root.raw 64 1440) + ../../tools/raw2dskcpc $(FUZIX_ROOT)/Images/$(TARGET)/root.raw $(FUZIX_ROOT)/Images/$(TARGET)/root.dsk 80 2 0 + \ No newline at end of file diff --git a/Kernel/platform/platform-cpc6128-SME/Notes.md b/Kernel/platform/platform-cpc6128-SME/Notes.md new file mode 100644 index 0000000000..95377e2735 --- /dev/null +++ b/Kernel/platform/platform-cpc6128-SME/Notes.md @@ -0,0 +1,22 @@ +# Amstrad CPC6128 + + +## Mmeory Model + +This port is based on the zx+3 port, taking advantage of Alan Cox's suggestion to take advantage of the fact that the memory maps C1, C2 and C3 correspond to the maps used in the zx+3 port. + +In the zx+3: +| User | 0 / 1 / 2 | Common 3 +| Kernel | 4 / 5 / 6 | Common 3 +| Video | 4 / 7 / 6 | Common 3 + +In the CPC6128: +| User | 4 / 5 / 6 | Common 7 (map C2) +| Kernel | 0 / 1 / 2 | Common 7 (map C1) +| Video | 0 / 3 / 2 | Common 7 (map c3) + +## TODO + +Lots of bugs. +Trying to mount the flopy hangs the machine, and may do nasty things to the floppy and the drive, don't try on a real machine!! +Fix memory size reporting 64 v 48K. \ No newline at end of file diff --git a/Kernel/platform/platform-cpc6128-SME/README b/Kernel/platform/platform-cpc6128-SME/README new file mode 100644 index 0000000000..fd31fdd0f5 --- /dev/null +++ b/Kernel/platform/platform-cpc6128-SME/README @@ -0,0 +1,68 @@ +# Amstrad CPC6128 + + +## Mmeory Model + +The CPC6128 supported memory maps: + + -MAP- C0 C1 C2 C3 C4 C5 C6 C7 + 0000-3FFF RAM_0 RAM_0 RAM_4 RAM_0 RAM_0 RAM_0 RAM_0 RAM_0 + 4000-7FFF RAM_1 RAM_1 RAM_5 RAM_3 RAM_4 RAM_5 RAM_6 RAM_7 + 8000-BFFF RAM_2 RAM_2 RAM_6 RAM_2 RAM_2 RAM_2 RAM_2 RAM_2 + C000-FFFF RAM_3 RAM_7 RAM_7 RAM_7 RAM_3 RAM_3 RAM_3 RAM_3 + +This port is based on the zx+3 port, following Alan Cox's suggestion to take advantage of the fact that memory maps C1, C2 and C3 correspond to the maps used in the zx+3 port. + +In the zx+3: +| User | 0 / 1 / 2 | Common 3 +| Kernel | 4 / 5 / 6 | Common 3 +| Video | 4 / 7 / 6 | Common 3 + +In the CPC6128: +| User | 4 / 5 / 6 | Common 7 (map C2) +| Kernel | 0 / 1 / 2 | Common 7 (map C1) +| Video | 0 / 3 / 2 | Common 7 (map C3) + + + +## STATUS + +Video mode 2 is used. The video driver configures the CRTC in 64x32 characters to do easy hardware scroll and use the whole video memory bank. + +The floppy driver seems to work. /dev/fd0 is drive A and /dev/fd1 is drive B. fd0 is hard coded to one side and fd1 to double side. A minimal system root disk image is generated to boot from fd1. Format is 9 sectors per track with sector ID from 1 to 9. + +The IDE driver that is supposed to work with the symbiface and xmass fails to initialize. FIXED, tested with ACE-DL emulator x-mass suport. + +The USB mass storage of the Albiero works using the ch375 driver used in other platforms. It should be easy to get it working with the Usifac/Ulifac. + +There isn't a proper loader, for now a snapshot is generated. FIXED, dsk floppy boot image generated. + +To test it burn disk.img on a spare usb pendrive and put it on the albireo. Load an run the snapshot or burn the dsk in a floppy and start FUZIX with |cpm. + + +## TODO + +Fix fdc driver. DONE +Fix IDE driver. DONE +Sometimes the top byte of the characters isn't drawn. FIXED +Vertical scroll shows the bottom line of the screen in the top of the screen. FIXED +Fix memory size reporting 64 v 48K (inherited from zx+3). +do_beep() doesn't seem to work. FIXED +Write a proper loader. DONE. +Configurable screen, at least add 80x25, maybe also change the video mode and routines to manage 6x8 fonts. +Support more hardware: M4 Board (storage, network and RTC), Ulifac/Usifac, networking with wifi module plugged in the usifac, sdcard in the Albireo, try slip with the serial port of the usifac... + +Fix lots of bugs. + +Switch to a thunked memory model based on C2 Map to use the standard and extended RAM expansions up to 4MiB, the Cromemco port could be a model to this solution. As ther is no real common as we are switching the whole 64k space, the common data area has to be updated in all the used banks, but this can give aprox. 60K for kernel and user and hold a lot of processes in memory with a big RAM expansion. If this proves to be too hard, a RAM disk for swapping can be a way to use the RAM expansions. + +Look for speed optimization opportunities. + +## BUILD & RUN + +make diskimage with cpc6128 target in base Makefile +.sna snapshot, .dsk Floppy image, and mass storage filesystem images are generated in Images folder. Tu boot from floppy use |cpm command from basic prompt + +To run on emulator use ACE-DL emulator and use disk.img as image for the x-mass IDE interface emulation. + + diff --git a/Kernel/platform/platform-cpc6128-SME/commonmem.s b/Kernel/platform/platform-cpc6128-SME/commonmem.s new file mode 100644 index 0000000000..595cb1a72c --- /dev/null +++ b/Kernel/platform/platform-cpc6128-SME/commonmem.s @@ -0,0 +1,9 @@ +; +; Multiple app sizes and the fact the kernel and apps share the same banks +; means we need to put this somewhere low +; + .module commonmem + .area _COMMONMEM + + .include "../../cpu-z80/std-commonmem.s" + \ No newline at end of file diff --git a/Kernel/platform/platform-cpc6128-SME/config.h b/Kernel/platform/platform-cpc6128-SME/config.h new file mode 100644 index 0000000000..9ac4c33a2e --- /dev/null +++ b/Kernel/platform/platform-cpc6128-SME/config.h @@ -0,0 +1,104 @@ +#define CONFIG_LARGE_IO_DIRECT(x) 1 /* We support direct to user I/O */ + +#define CONFIG_FDC765 +/* 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) */ +#define CONFIG_PROFIL +/* Multiple processes in memory at once */ +#define CONFIG_MULTI +/* CP/M emulation */ +#undef CONFIG_CPM_EMU + +/* Input layer support */ +#define CONFIG_INPUT +#define CONFIG_INPUT_GRABMAX 3 +/* Video terminal, not a serial tty */ +#define CONFIG_VT +/* Keyboard contains non-ascii symbols */ +#define CONFIG_UNIKEY + +/* Swap based one process in RAM */ +#define CONFIG_SWAP_ONLY +#define CONFIG_PARENT_FIRST +#define CONFIG_SPLIT_UDATA +#define UDATA_BLKS 1 +#define UDATA_SIZE 0x200 +#define CONFIG_DYNAMIC_BUFPOOL +#undef CONFIG_DYNAMIC_SWAP +#define MAXTICKS 60 /* Has to be high because we are swap only */ + +#undef CONFIG_KMOD + +#undef CONFIG_NET +#undef CONFIG_NET_NATIVE +#undef CONFIG_NET_WIZNET +#undef CONFIG_NET_W5100 + +/* Custom banking */ + +/* Banks as reported to user space */ +#define CONFIG_BANKS 1 + +/* Vt definitions */ +#define VT_WIDTH 64 +#define VT_HEIGHT 32 +#define VT_RIGHT 63 +#define VT_BOTTOM 31 + +#define TICKSPERSEC 300 /* Ticks per second */ +#define PROGBASE 0x0000 /* also data base */ +#define PROGLOAD 0x0100 /* also data base */ +#define PROGTOP 0xC000 /* Top of program, below C000 for simplicity + to get going */ + +#define BOOT_TTY (513) /* Set this to default device for stdio, stderr */ + /* In this case, the default is the first TTY device */ + +/* We need a tidier way to do this from the loader */ +#define CMDLINE NULL /* Location of root dev name */ + +/* Device parameters */ +#define NUM_DEV_TTY 1 + +#define TTYDEV BOOT_TTY /* Device used by kernel for messages, panics */ +#define NBUFS 5 /* Number of block buffers */ +#define NMOUNTS 4 /* Number of mounts at a time */ + +#define SWAPBASE 0x0000 +#define SWAPTOP 0xC000UL +#define SWAP_SIZE 0x61 /* 48K + udata */ +#define EXTENDED_RAM_1024 +#ifdef EXTENDED_RAM_1024 + #define MAX_SWAPS 19 /*See platform devrd.c*/ + #define PTABSIZE 19 + #define TOTAL_SWAP_BLOCKS (1088-128) * 2 +#endif +#ifdef EXTENDED_RAM_512 + #define MAX_SWAPS 9 /*See platform devrd.c*/ + #define PTABSIZE 9 + #define TOTAL_SWAP_BLOCKS (576-128) * 2 +#endif +#define SWAPDEV 0x800 /* Device for swapping - RAM disk on standard memory expansion. */ + +/* We swap by hitting the user map */ +#define swap_map(x) ((uint8_t *)(x)) + +#define CONFIG_TD +#define CONFIG_TD_NUM 2 +/* IDE/CF support */ +#define CONFIG_TD_IDE +#define CONFIG_TINYIDE_SDCCPIO +#define CONFIG_TINYIDE_8BIT +#define IDE_IS_8BIT(x) 1 + +#define BOOTDEVICENAMES "hd#,fd" + +#define CONFIG_SMALL + + + + + diff --git a/Kernel/platform/platform-cpc6128-SME/cpc6128.s b/Kernel/platform/platform-cpc6128-SME/cpc6128.s new file mode 100644 index 0000000000..8b52c16f02 --- /dev/null +++ b/Kernel/platform/platform-cpc6128-SME/cpc6128.s @@ -0,0 +1,373 @@ +; +; Amstrad CPC6128 support + + .module cpc6128 + + ; exported symbols + .globl init_early + .globl init_hardware + .globl _program_vectors + .globl plt_interrupt_all + .globl interrupt_handler + .globl unix_syscall_entry + .globl null_handler + .globl nmi_handler + + .globl map_kernel + .globl map_proc_always + .globl map_proc + .globl map_kernel_di + .globl map_proc_always_di + .globl map_save_kernel + .globl map_restore + .globl map_kernel_restore + .globl map_for_swap + .globl map_video + .globl current_map + + + .globl _need_resched + .globl _int_disabled + .globl _vtborder + .globl diskmotor + + ; exported debugging tools + .globl _plt_monitor + .globl _plt_reboot + .globl outchar + + ; imported symbols + .globl _ramsize + .globl _procmem + + .globl _vtoutput + .globl _vtinit + + .globl _do_beep + + .globl outcharhex + .globl outhl, outde, outbc + .globl outnewline + .globl outstring + .globl outstringhex + + .globl ___sdcc_enter_ix + + .include "kernel.def" + .include "../../cpu-z80/kernel-z80.def" + +; ----------------------------------------------------------------------------- +; COMMON MEMORY BANK (above 0xF000) +; ----------------------------------------------------------------------------- + .area _COMMONMEM + +_plt_monitor: + ; + ; Not so much a monitor as wait for space + ; Part of this code is borrowed from https://github.com/lronaldo/cpctelera + + ld bc,#0x7fc2 + out (c),c ; keep us mapped + ld bc, #0xF782 ;; [3] Configure PPI 8255: Set Both Port A and Port C as Output. + out (c), c ;; [4] 82 = 1000 0010 : (B7=1)=> I/O Mode, (B6-5=00)=> Mode 1, + ;; (B4=0)=> Port A=Output, (B3=0)=> Port Cu=Output, + ;; (B2=0)=> Group B, Mode 0,(B1=1)=> Port B=Input, (B0=0)=> Port Cl=Output + ld bc, #0xF40E ;; [3] Write (0Eh = 14) on PPI 8255 Port A (F4h): the register we want to select on AY-3-8912 + ld e, b ;; [1] Save F4h into E to use it later in the loop + out (c), c ;; [4] + + ld bc, #0xF6C0 ;; [3] Write (C0h = 11 000000b) on PPI Port C (F6h): operation > select register + ld d, b ;; [1] Save F6h into D to use it later in the loop + out (c), c ;; [4] + .dw #0x71ED ; out (c), 0 ;; [4] out (C), 0 => Write 0 on PPI's Port C to put PSG's in inactive mode + ;; .... (required in between different operations) + ld bc, #0xF792 ;; [3] Configure PPI 8255: Set Port A = Input, Port C = Output. + out (c), c ;; [4] 92h= 1001 0010 : (B7=1)=> I/O Mode, (B6-5=00)=> Mode 1, + ;; (B4=1)=> Port A=Input, (B3=0)=> Port Cu=Output, + ;; (B2=0)=> Group B, Mode 0, (B1=1)=> Port B=Input, (B0=0)=> Port Cl=Output + ld a, #0x45 ;; SPACE + ld b, d ;; [1] B = F6h => Write the value of A to PPI's Port C to select next Matrix Line + out (c), a ;; [4] + ld b, e ;; [1] B = F4h => Read from PPI's Port A: Pressed/Not Pressed Values from PSG + in a,(c) + rla + jr c, _plt_monitor + +_plt_reboot: + di + ;halt ;we are debugging why we end here + ld bc, #0x7f89 ;this would set the firmware ready for boot into firmware with (out (c),c ; rst0) + out (c), c + rst 0 ; back into our booter + +plt_interrupt_all: + ret + + .area _COMMONMEM + +_int_disabled: + .db 1 + +_vtborder: ; needs to be common + .db 0 + + +; ----------------------------------------------------------------------------- +; KERNEL CODE BANK (below 0xC000) +; ----------------------------------------------------------------------------- + .area _CODE + +init_early: + + call _program_early_vectors + ret + +init_hardware: + ; set system RAM size + ld hl, #128 + ld (_ramsize), hl + ld hl, #64 ; 64K for kernel/screen/etc (FIXME) + ld (_procmem), hl + + ; Install rst shorteners + ld hl,#rstblock + ld de,#8 + ld bc,#32 + ldir + + ld bc,#0x7fc3 + ; bank 7 (common) in high in either mapping + ; video bank 3 at &4000 + out (c),c + ; and we should have special mapping + ; already by now + ld bc,#0x7f10 + out (c),c + ld a,#0x54 ; + ld (_vtborder), a + out (c),a ; black border + ld bc,#0x7f00 + out (c),c + ld a,#0x44 + out (c),a ; blue paper + ld bc,#0x7f01 + out (c),c + ld a,#0x4b + out (c),a ; white ink + + + ;we set the crtc for a screen with 64x32 colsxrows + ;pros: max number of characters on screen and easy hardware scroll + ;cons: 80x25 is more standard => TODO list (with mode change) + ld bc,#0xbc01 + out (c),c + ld bc,#0xbd20 + out (c),c + ld bc,#0xbc02 + out (c),c + ld bc,#0xbd2A + out (c),c + ld bc,#0xbc06 + out (c),c + ld bc,#0xbd20 + out (c),c + ld bc,#0xbc07 + out (c),c + ld bc,#0xbd22 + out (c),c + + call _do_beep + + ; screen initialization + call _vtinit + + ret + +;------------------------------------------------------------------------------ +; COMMON MEMORY PROCEDURES FOLLOW + + .area _COMMONMEM + +_program_early_vectors: + call map_proc_always + call set_vectors + call map_kernel +set_vectors: + ; write zeroes across all vectors + ld hl, #0 + ld de, #1 + ld bc, #0x007f ; program first 0x80 bytes only + ld (hl), #0x00 + ldir + + ; now install the interrupt vector at 0x0038 + ld a, #0xC3 ; JP instruction + ld (0x0038), a + ld hl, #interrupt_handler + ld (0x0039), hl + + ; set restart vector for FUZIX system calls + ld (0x0030), a ; (rst 30h is unix function call vector) + ld hl, #unix_syscall_entry + ld (0x0031), hl + + ld (0x0000), a + ld hl, #null_handler ; to Our Trap Handler + ld (0x0001), hl + + ld (0x0066), a ; Set vector for NMI + ld hl, #nmi_handler + ld (0x0067), hl + +_program_vectors: + ret + + ; Swap helper. Map the page in A into the address space such + ; that swap_map() gave the correct pointer to use. Undone by + ; a map_kernel_{restore} +map_proc: + ld a, h + or l + jr z, map_kernel +map_for_swap: +map_proc_always: +map_proc_always_di: + push af + ld a,#0xc2 ; 4 5 6 7 + jr map_a_pop +; +; Save and switch to kernel +; +map_save_kernel: + push af + ld a, (current_map) + ld (map_store), a + pop af +map_kernel_di: +map_kernel: +map_kernel_restore: + push af + ld a,#0xc1 ; 0 1 2 7 +map_a_pop: + push bc + ld (current_map),a + ld bc,#0x7f00 + out (c),a + pop bc + pop af + ret + +map_video: + push af + ld a,#0xc3 ; 0 3 2 7 + jr map_a_pop + +map_restore: + push af + ld a, (map_store) + jr map_a_pop + +; +; We have no easy serial debug output instead just breakpoint this +; address when debugging. +; +outchar: + ld (_tmpout), a + push bc + push de + push hl + push ix + ld hl, #1 + push hl + ld hl, #_tmpout + push hl + call _vtoutput + pop af + pop af + pop ix + pop hl + pop de + pop bc + ret + + .area _COMMONMEM +_tmpout: + .db 1 + +current_map: ; place to store current page number. Is needed + .db 0 ; because we have no ability to read 0xF4 port + ; to detect what page is mapped currently +map_store: + .db 0 + +_need_resched: + .db 0 + +diskmotor: + .db 0 + +; +; Stub helpers for code compactness. Note that +; sdcc_enter_ix is in the standard compiler support already +; + .area _DISCARD + +; +; The first two use an rst as a jump. In the reload sp case we don't +; have to care. In the pop ix case for the function end we need to +; drop the spare frame first, but we know that af contents don't +; matter +; + +rstblock: + jp ___sdcc_enter_ix + .ds 5 +___spixret: + ld sp,ix + pop ix + ret + .ds 3 +___ixret: + pop af + pop ix + ret + .ds 4 +___ldhlhl: + ld a,(hl) + inc hl + ld h,(hl) + ld l,a + ret + +; +; Helpers for the CH375 +; + .area _CODE + + .globl _nap20 + +_nap20: ;modified, in the cpc 1 nop = 1us. the call-ret add some us', it can be optimized (FIXME) + + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + + ret + diff --git a/Kernel/platform/platform-cpc6128-SME/cpcvideo.s b/Kernel/platform/platform-cpc6128-SME/cpcvideo.s new file mode 100644 index 0000000000..21e2af9b93 --- /dev/null +++ b/Kernel/platform/platform-cpc6128-SME/cpcvideo.s @@ -0,0 +1,44 @@ +; +; cpc vt primitives +; + + .module cpcvideo + + ; exported symbols + .globl _plot_char + .globl _scroll_down + .globl _scroll_up + .globl _cursor_on + .globl _cursor_off + .globl _cursor_disable + .globl _clear_lines + .globl _clear_across + .globl _do_beep + .globl _fontdata_8x8 + .globl _curattr + .globl _vtattr + + .globl map_video + .globl map_kernel + + ; Build the video library as the only driver + +CPCVID_ONLY .equ 1 +SCREENBASE .equ 0x40 + +.macro VIDEO_MAP + call map_video +.endm + +.macro VIDEO_UNMAP + call map_kernel +.endm + + .globl _fontdata_8x8 + +;_fontdata_8x8 .equ 0xF000 ; routines except this + ; to point to space char + .area _COMMONMEM + + .include "../../dev/cpc/video.s" + diff --git a/Kernel/platform/platform-cpc6128-SME/crt0.s b/Kernel/platform/platform-cpc6128-SME/crt0.s new file mode 100644 index 0000000000..042e521703 --- /dev/null +++ b/Kernel/platform/platform-cpc6128-SME/crt0.s @@ -0,0 +1,211 @@ + .module crt0 + + ; + ; High space - read only + ; + + .area _CODE + .area _CODE2 + ; + ; Try and keep code in the top 32K + ; + + + ; + ; Our common lives low + ; + .area _CODE3 + .area _VIDEO ; must end below 0x4000 + .area _FONT + .area _INITIALIZED + .area _HOME + .area _CONST + + ; + ; Beyond this point we just zero. + ; + + .area _DATA + .area _BSEG + .area _BSS + .area _HEAP + .area _GSINIT + .area _GSFINAL + + ; + ; Finally the buffers so they can expand + ; + .area _BUFFERS + ; Somewhere to throw it out of the way + .area _INITIALIZER + + .area _DISCARD + + + .area _COMMONMEM + + + + ; imported symbols + .globl _fuzix_main + .globl init_early + .globl init_hardware + .globl l__BUFFERS + .globl s__BUFFERS + .globl l__COMMONMEM + .globl s__COMMONMEM + .globl l__DATA + .globl s__DATA + .globl l__DISCARD + .globl s__DISCARD + .globl l__FONT + .globl s__FONT + .globl kstack_top + + .globl unix_syscall_entry + .globl nmi_handler + .globl interrupt_handler + + .include "kernel.def" + .include "../../cpu-z80/kernel-z80.def" + + ; + ; startup code + ; + ; We loaded the rest of the kernel from disk and jumped here + ; + + .area _CODE + + .globl _start + + + +_start: + + + di + ld sp, #kstack_top + ; + ; move the common memory where it belongs + ld hl, #s__DATA + ld de, #s__COMMONMEM + ld bc, #l__COMMONMEM + ldir + + ; then the font +; ld de, #s__FONT +; ld bc, #l__FONT +; ldir + + ; then the discard (backwards as will overlap) + ld de, #s__DISCARD + ld bc, #l__DISCARD-1 + ex de,hl + add hl,bc + ex de,hl + add hl,bc + lddr + ldd + + ; then zero the data area + ld hl, #s__DATA + ld de, #s__DATA + 1 + ld bc, #l__DATA - 1 + ld (hl), #0 + ldir + ; and buffers + ld hl, #s__BUFFERS + ld de, #s__BUFFERS + 1 + ld bc, #l__BUFFERS - 1 + ld (hl), #0 + ldir + + ;We are loading from a .sna with first 64k filled with fuzix.bin starting at 0x100 + ;copy bank 3 to bank 7 in C7 mode (7 at 0x4000), zero bank 3 (vmem) and switch to C1 (kernel map) + ;when a proper loader is done this should be managed there + + ld bc,#0x7fc7 + out (c),c + + ld hl, #0xc000 + ld de, #0x4000 + ld bc, #0x4000 + ldir + + ld bc,#0x7f00 + out (c),c + ld a,#0x44 + out (c),a ; blue paper + ld bc,#0x7f01 + out (c),c + ld a,#0x4b + out (c),a ; white ink + + ld hl, #0xc000 + ld de, #0xc001 + ld bc, #0x3fff + ld (hl), #0 + ldir + + ld bc,#0x7fc1 + out (c),c + + ld hl,#copyfont + ld de,#0xF000 + ld bc,#(copyfont_end-copyfont) + ldir + + call #0xF000 + + ld hl,#0xF000 + ld de,#0xF001 + ld bc,#(copyfont_end-copyfont-1) + ld (hl),#0 + ldir + + ; Configure memory map + call init_early + + ; Hardware setup + call init_hardware + + ; Call the C main routine + call _fuzix_main + + ; main shouldn't return, but if it does... + di +stop: halt + jr stop + + ;code to copy font +copyfont: ;;this wil be in the loader + di + ld bc, #0x7faa ;RMR ->UROM disable LROM enable + out (c),c + ld hl, #0x3800 ;Firmware (LROM) character bitmaps + ld de, #(_fontdata_8x8) + ld bc, #0x800 + ldir + ld bc, #0x7fae ;RMR ->UROM disable LROM disable + out (c),c + ret +copyfont_end: + + + .area _BUFFERS +; +; Buffers (we use asm to set this up as we need them in a special segment +; so we can recover the discard memory into the buffer pool +; + + .globl _bufpool + .area _BUFFERS + +_bufpool: + .ds BUFSIZE * NBUFS + + .globl _fontdata_8x8 + .area _FONT + _fontdata_8x8: + .ds 2048 diff --git a/Kernel/platform/platform-cpc6128-SME/devices.c b/Kernel/platform/platform-cpc6128-SME/devices.c new file mode 100644 index 0000000000..7dd80d5cb4 --- /dev/null +++ b/Kernel/platform/platform-cpc6128-SME/devices.c @@ -0,0 +1,63 @@ +#include +#include +#include +#include +#include +#include +#include +#include +/*#include */ +#include +#include +/*#include */ +#include + +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 */ + { devfd_open, no_close, devfd_read, devfd_write, no_ioctl }, + /* 2: /dev/tty TTY devices */ + { tty_open, tty_close, tty_read, tty_write, cpcvt_ioctl }, + /* 3: /dev/lpr Printer devices */ + { no_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 }, + /* 5: Pack to 7 with nxio if adding private devices and start at 8 */ + /* 5: unused */ + { no_open, no_close, no_rdwr, no_rdwr, no_ioctl }, + /* 6: unused */ + { no_open, no_close, no_rdwr, no_rdwr, no_ioctl }, + /* 7: unused */ + { no_open, no_close, no_rdwr, no_rdwr, no_ioctl }, + /* 8: Standard memory expansions RAM swap */ + { rd_open, no_close, rd_read, rd_write, no_ioctl }, +}; + + +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; +} + +void device_init(void) +{ +#ifdef CONFIG_TD_IDE + ide_probe(); +#endif +#ifdef CONFIG_TD_SD + sd_probe(); +#endif +ch375_probe(); + +#ifdef CONFIG_NET + sock_init(); +#endif +} + diff --git a/Kernel/platform/platform-cpc6128-SME/devrd.c b/Kernel/platform/platform-cpc6128-SME/devrd.c new file mode 100644 index 0000000000..29c3a6e79e --- /dev/null +++ b/Kernel/platform/platform-cpc6128-SME/devrd.c @@ -0,0 +1,80 @@ +/* + * CPC standard RAM bank memory expansions ramdisc driver, based on platform zxdiv48. + */ + +#include +#include +#include +#include + +static int rd_transfer(uint8_t is_read, uint8_t rawflag) +{ + nblock = udata.u_nblock; + block = udata.u_block; + rd_dptr = udata.u_dptr; + rd_wr = is_read; + uint16_t swap_bank_long; + uint8_t ct = 0; + + #ifdef DEBUG + kprintf("u_dptr %p Block %u u_nblock %u rd_wr %u\n",udata.u_dptr, udata.u_block, udata.u_nblock, rd_wr); + #endif + + /* It's a disk but only for swapping (and rd_io isn't general purpose) */ + if (((block + nblock) > (TOTAL_SWAP_BLOCKS - 1)) || (rawflag == 1)) { + udata.u_error = EIO; + kprintf("dev_rd_EIO"); + return -1; + } + + /* udata could change under us so keep variables privately */ + while (ct < nblock) { + swap_bank_long = (block >> 5); + swap_bank_long = swap_bank_long + 196 + (((swap_bank_long + 8) / 4) * 4); /*Convert bank number to Register MMR value + *See https://www.cpcwiki.eu/index.php/Gate_Array#Register_MMR_.28RAM_memory_mapping.29*/ + if (swap_bank_long > 255){ + rd_swap_bank = swap_bank_long - 64; + rd_swap_mem_port_h = 0x7e; + } + else{ + rd_swap_bank = swap_bank_long; + rd_swap_mem_port_h = 0x7f; + } + rd_proc_bank = ((uint16_t)rd_dptr / 0x4000) + 0xc4; + rd_swap_bank_addr = ((block & 31) << BLKSHIFT) + 0x4000; + rd_proc_bank_addr = ((uint16_t)rd_dptr & 0x3fff) + 0x4000; + + #ifdef DEBUG + if (nblock == 1) + kprintf("swap_bank %p swap_addr %p proc_bank %p proc_addr %p count %u\n", rd_swap_bank, rd_swap_bank_addr, rd_proc_bank, rd_proc_bank_addr, ct); + #endif + rd_io(); + block++; + rd_dptr += BLKSIZE; + ct++; + } + return ct << BLKSHIFT; /*Total bytes transferred*/ +} + +int rd_open(uint8_t minor, uint16_t flag) +{ + flag; + if(minor != 0) { + udata.u_error = ENODEV; + return -1; + } + return 0; +} + +int rd_read(uint8_t minor, uint8_t rawflag, uint8_t flag) +{ + flag;minor; + return rd_transfer(true, rawflag); +} + +int rd_write(uint8_t minor, uint8_t rawflag, uint8_t flag) +{ + flag;minor; + return rd_transfer(false, rawflag); +} + diff --git a/Kernel/platform/platform-cpc6128-SME/devrd.h b/Kernel/platform/platform-cpc6128-SME/devrd.h new file mode 100644 index 0000000000..e7c4451555 --- /dev/null +++ b/Kernel/platform/platform-cpc6128-SME/devrd.h @@ -0,0 +1,20 @@ +/* + * + * CPC standard RAM bank memory expansions ramdisc driver + */ + +int rd_open(uint8_t minor, uint16_t flags); +int rd_read(uint8_t minor, uint8_t rawflag, uint8_t flag); +int rd_write(uint8_t minor, uint8_t rawflag, uint8_t flag); + +extern uint8_t rd_wr; +extern uint8_t rd_swap_bank; +extern uint8_t rd_swap_mem_port_h; +extern uint8_t rd_proc_bank; +extern uint8_t *rd_dptr; +extern uint16_t rd_swap_bank_addr; +extern uint16_t rd_proc_bank_addr; +extern uint16_t nblock; +extern blkno_t block; + +void rd_io(void); diff --git a/Kernel/platform/platform-cpc6128-SME/devtty.c b/Kernel/platform/platform-cpc6128-SME/devtty.c new file mode 100644 index 0000000000..0f1733f313 --- /dev/null +++ b/Kernel/platform/platform-cpc6128-SME/devtty.c @@ -0,0 +1,132 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static char tbuf1[TTYSIZ]; + +uint8_t vtattr_cap = VTA_UNDERLINE; +extern uint8_t curattr; + +tcflag_t termios_mask[NUM_DEV_TTY + 1] = { + 0, + _CSYS +}; + + +struct s_queue ttyinq[NUM_DEV_TTY + 1] = { /* ttyinq[0] is never used */ + {NULL, NULL, NULL, 0, 0, 0}, + {tbuf1, tbuf1, tbuf1, TTYSIZ, 0, TTYSIZ / 2}, +}; + +/* tty1 is the screen */ + +/* Output for the system console (kprintf etc) */ +void kputchar(char c) +{ + if (c == '\n') + tty_putc(0, '\r'); + tty_putc(0, c); +} + +/* Both console and debug port are always ready */ +ttyready_t tty_writeready(uint8_t minor) +{ + minor; + return TTY_READY_NOW; +} + +void tty_putc(uint8_t minor, unsigned char c) +{ + minor; + vtoutput(&c, 1); +} + +int tty_carrier(uint8_t minor) +{ + minor; + return 1; +} + +void tty_setup(uint8_t minor, uint8_t flags) +{ + minor; +} + +void tty_sleeping(uint8_t minor) +{ + minor; +} + +void tty_data_consumed(uint8_t minor) +{ +} + + +/* This is used by the vt asm code, but needs to live in the kernel */ +uint16_t cursorpos; + +//Inherited from spectrum zx+3. For now ignore attributes, try later to implement inverse and underline touching char output directly +void vtattr_notify(void) +{ + // Attribute byte fixups: not hard as the colours map directly + // to the spectrum ones +/* if (vtattr & VTA_INVERSE) + curattr = ((vtink & 7) << 3) | (vtpaper & 7); + else + curattr = (vtink & 7) | ((vtpaper & 7) << 3); + + if (vtattr & VTA_FLASH) + curattr |= 0x80; + // How to map the bright bit - we go by either + if ((vtink | vtpaper) & 0x10) + curattr |= 0x40; +*/ + //we are now debugging other things + //vtink = 26; + //vtpaper = 1; + //cpcvt_ioctl(1, VTINK, &vtink); + //cpcvt_ioctl(1, VTPAPER, &vtpaper); + +} + + +__sfr __banked __at 0x7F00 gatearray; +/* see: https://www.cpcwiki.eu/index.php/Gate_Array */ + +int cpcvt_ioctl(uint8_t minor, uarg_t arg, char *ptr) +{ + uint8_t c; + if (minor == 1 && arg == VTBORDER) { + c = ugetc(ptr); + gatearray = PENR_BORDER_SELECT; + vtborder &= INKR_COLOR_SET; + vtborder |= c & 0x1F; + gatearray = vtborder; + return 0; + } + if (minor == 1 && arg == VTINK) { + c = ugetc(ptr); + gatearray = PENR_INK_SELECT; + vtink &= INKR_COLOR_SET; + vtink |= c & 0x1F; + gatearray = vtink; + return 0; + } + if (minor == 1 && arg == VTPAPER) { + c = ugetc(ptr); + gatearray = PENR_PAPER_SELECT; + vtpaper &= INKR_COLOR_SET; + vtpaper |= c & 0x1F; + gatearray = vtpaper; + return 0; + } + return vt_ioctl(minor, arg, ptr); +} diff --git a/Kernel/platform/platform-cpc6128-SME/devtty.h b/Kernel/platform/platform-cpc6128-SME/devtty.h new file mode 100644 index 0000000000..57d7727ead --- /dev/null +++ b/Kernel/platform/platform-cpc6128-SME/devtty.h @@ -0,0 +1,24 @@ +#ifndef __DEVTTY_DOT_H__ +#define __DEVTTY_DOT_H__ + +void tty_pollirq(void); +static void keydecode(void); + +#define KEY_ROWS 10 +#define KEY_COLS 8 +#define PENR_BORDER_SELECT 0x10 +/*For now We are in mode 2 with pen 0 for paper and pen 1 for ink*/ +#define PENR_PAPER_SELECT 0x00 +#define PENR_INK_SELECT 0x01 +#define INKR_COLOR_SET 0x40 +extern uint8_t keymap[10]; +extern uint8_t keyboard[10][8]; +extern uint8_t shiftkeyboard[10][8]; + +extern uint8_t timer_wait; + +extern int cpcvt_ioctl(uint8_t minor, uarg_t arg, char *ptr); + +extern uint8_t vtborder; + +#endif diff --git a/Kernel/platform/platform-cpc6128-SME/discard.c b/Kernel/platform/platform-cpc6128-SME/discard.c new file mode 100644 index 0000000000..164fb2a423 --- /dev/null +++ b/Kernel/platform/platform-cpc6128-SME/discard.c @@ -0,0 +1,31 @@ +#include +#include +#include +#include +#include +#include + +uint8_t plt_param(char *p) +{ + return 0; +} + +/* Nothing to do for the map of init */ +void map_init(void) +{ + uint_fast8_t i; + for (i = 0; i < MAX_SWAPS; i++) + swapmap_init(i); +} + +void plt_copyright(void) +{ + kprintf("Amstrad CPC6128 platform\nCopyright (c) 2024-2025 Antonio J. Casado Alias\n"); +} +/* +void ide_reset(void) +{ + ide_std_reset(); +} +*/ + diff --git a/Kernel/platform/platform-cpc6128-SME/fdc765.s b/Kernel/platform/platform-cpc6128-SME/fdc765.s new file mode 100644 index 0000000000..76c0312ab3 --- /dev/null +++ b/Kernel/platform/platform-cpc6128-SME/fdc765.s @@ -0,0 +1,530 @@ +; +; 765 Floppy Controller Support +; +; This is based upon the Amstrad NC200 driver by David Given and +; this example https://cpctech.cpcwiki.de/source/fdcload.html from Kevin Thacker site +; +; It differs on the CPC in the following ways +; +; - The timings are tighter so we use in a,(c) jp p and other +; tricks to make the clocks. Even so it should be in uncontended RAM +; +; - The CPC doesn't expose the tc line, so if the 765 decides to +; expect more data or feed us more data all we can do is dump it or +; feed it crap until it shuts up +; +; - We do motor and head loading delays (possibly some of those should +; be backported - FIXME) +; +; - We don't hang if the controller tells us no more data when we +; think we need to feed it command bytes (BACKPORT NEEDED) +; +; TODO +; Initialize drive step rate etc (we rely on the firmware for now) +; Step rate +; Head load/unload times +; Write off time af +; (12ms step 30ms head stabilize, 4ms head load, max (0xf) head +; unload) +; + .module fdc765 + + .include "kernel.def" + .include "../../cpu-z80/kernel-z80.def" + + .globl map_proc_always + .globl map_kernel + + .globl _fd765_do_nudge_tc + .globl _fd765_do_recalibrate + .globl _fd765_do_seek + .globl _fd765_do_read + .globl _fd765_do_write + .globl _fd765_do_read_id + .globl _fd765_motor_on + .globl _fd765_motor_off + + .globl _fd765_track + .globl _fd765_head + .globl _fd765_sector + .globl _fd765_status + .globl _fd765_buffer + .globl _fd765_is_user + .globl _fd765_sectors + .globl _fd765_drive + + .globl _vtborder + + .globl diskmotor + + .area _COMMONMEM + +; +; Twiddle the Terminal Count line to the FDC. Not supported by the +; CPC +; +_fd765_do_nudge_tc: + ret + +; Writes A to the FDC data register. + +fd765_tx: + push bc +; ex af, af' +; ld bc,#0xfb7e ; floppy register (16bit access) +;fd765_tx_loop: +; in a, (c) +; add a +; jr nc, fd765_tx_loop +; ; FIXME: backport this fix +; add a +; jr c, fd765_tx_exit ; controller doesn't want data ?? +; ex af, af' +; ld c,#0x7f +; out (c), a +; ex (sp),hl +; ex (sp),hl +;fd765_tx_exit: + ld bc,#0xfb7e ;; I/O address for FDC main status register + push af ;; + fwc1: in a,(c) ;; + add a,a ;; + jr nc,fwc1 ;; + add a,a ;; + jr nc,fwc2 ;; + pop af ;; + ret + + fwc2: + pop af ;; + + inc c ;; + out (c),a ;; write command byte + dec c ;; + + ;; some FDC documents say there must be a delay between each + ;; command byte, but in practice it seems this isn't needed on CPC. + ;; Here for compatiblity. + ld a,#5 ;; + fwc3: dec a ;; + jr nz,fwc3 ;; + pop bc + ; FIXME: is our delay quite long enough for spec ? + ; might need them to be ex (sp),ix ? + ret + +; Reads bytes from the FDC data register until the FDC tells us to stop (by +; lowering DIO in the status register). + +fd765_read_status: + ld hl, #_fd765_status +; ld c, #0x7e ; we flip between 2ffd 3ffd as we go +;read_status_loop: +; ld b,#0xfb ; control port +; in a, (c) +; rla ; RQM... +; jr nc, read_status_loop ; ...low, keep waiting +; rla ; DIO... +; ret nc ; ...low, no more data +; ld c,#0x7f ; data port +; in a,(c) ; INI ? FIXME +; ld (hl),a +; inc hl +; ex (sp),hl ; wait for the 765A +; ex (sp),hl +; ex (sp),hl +; ex (sp),hl +; jr read_status_loop ; next byte + ld bc,#0xfb7e + fr1: + in a,(c) + cp #0xc0 + jr c,fr1 + + inc c + in a,(c) + dec c + ld (hl),a + inc hl + + ld a,#5 + fr2: + dec a + jr nz,fr2 + in a,(c) + and #0x10 + jr nz,fr1 + + + ret +_fd765_status: + .ds 8 ; 8 bytes of status data + +; Sends the head/drive byte of a command. + +send_head: + ld hl, (_fd765_head) ; l = head h = drive) + ld a, l + add a + add a + add h + jr fd765_tx + +; Performs a RECALIBRATE command. + +_fd765_do_recalibrate: + ld a, #0x07 ; RECALIBRATE + call fd765_tx + ld a, (_fd765_drive) ; drive # + call fd765_tx + jr wait_for_seek_ending + +; Performs a SEEK command. + +_fd765_do_seek: + ld a, #0x0f ; SEEK + call fd765_tx + call send_head ; specified head, drive #0 + ld a, (_fd765_track) ; specified track + call fd765_tx + jr wait_for_seek_ending +_fd765_track: + .db 0 +_fd765_sector: + .db 0 +; +; These two must remain adjacent see send_head +; +_fd765_head: + .db 0 +_fd765_drive: + .db 0 + +; Waits for a SEEK or RECALIBRATE command to finish by polling SENSE INTERRUPT STATUS. +wait_for_seek_ending: + + ld a, #0x08 ; SENSE INTERRUPT STATUS + call fd765_tx + call fd765_read_status + + ld a, (#_fd765_status) + bit 5, a ; SE, seek end + jr z, wait_for_seek_ending + + bit 4,a + + ret + + ; Now settle the head (FIXME: what is the right value ?) + ld a, #30 ; 30ms +; +; This assumes uncontended timing +; +wait_ms: + push bc +wait_ms_loop: + ld b,#0xDC +wait_ms_loop2: + dec b + jr nz, wait_ms_loop2 + dec a + jr nz, wait_ms_loop + pop bc + ret + +_fd765_motor_off: + push bc + ld bc,#0xfa7e + xor a + ld (diskmotor),a + out (c),a + pop bc + ret + +_fd765_motor_on: + ld a,(diskmotor) + or a + ret nz + ld a,#0x01 + ld (diskmotor),a + ; Take effect + ld bc,#0xfa7e + out (c),a + ; Now wait for spin up + + ld e,#10 ; FIXME right value ?? +wait2: + ; The classic Z80 KHz timing loop + ld bc,#3548 ; 3.548MHz for spectrum, should change for cpc.FIXME +wait1: + dec bc + ld a,b + or c + jr nz, wait1 + dec e + jr nz, wait2 + ret +; +; Reads a 512-byte sector, after having previously saught to the right track. +; +; We need to be doubly careful here as the 765A has a 'feature' whereby it +; won't report an overrun on the last byte so we must always make timing +; +_fd765_do_read: + ld a, #0x46 ; READ SECTOR MFM + + ; FIXME: need to return a last cmd byte here and write it + ; after this crap or we may miss if we write just the sector hits + ; the head (BACKPORT ME ??) + call setup_read_or_write + + ld a, (_fd765_is_user) + or a + push af + call nz, map_proc_always + + ld bc,#0x7f10 + out (c),c + ld c,#0x46 ;Cyan + out (c),c + + di ; performance critical, + ; run with interrupts off + xor a + call fd765_tx ; send the final unused byte + ; to fire off the command + ld hl, (_fd765_buffer) + ld bc, #0xfb7e + +fdc_data_read: + in a,(c) ;; FDC has data and the direction is from FDC to CPU + jp p,fdc_data_read ;; + and #0x20 ;; "Execution phase" i.e. indicates reading of sector data + jp z,fdc_read_end + + inc c ;; BC = I/O address for FDC data register + in a,(c) ;; read from FDC data register + ld (hl),a ;; write to memory + dec c ;; BC = I/O address for FDC main status register + inc hl ;; increment memory pointer + jp fdc_data_read + +fdc_read_end: + +; ld de, #0x2000 ; so we can make timing +; jp read_wait +; +; First 256 bytes + +;read_loop: +; inc c ; data port +; ini +; inc b +; dec c ; control port +; dec e +; jp z, read_wait2 +;read_wait: +; in a,(c) ; read the fdc status +; jp p, read_wait +; and d +; jp nz, read_loop +; jp read_finished +; +; Second 256 bytes +; +;read_loop2: +; inc c ; data port +; ini +; inc b +; dec c ; control port +; dec e +; jp z, read_flush_wait +;read_wait2: +; in a,(c) ; read the fdc status +; jp p, read_wait2 +; and d +; jp nz, read_loop2 +; jp read_finished +; +; Flush out any extra data (no tc control) +; +;read_flush: +; inc c +; in a,(c) +; dec c +;read_flush_wait: +; in a,(c) +; jp p, read_flush_wait +; and d +; jp nz, read_flush +; +; And done +; +read_finished: + ld (_fd765_buffer), hl + call _fd765_do_nudge_tc ; Tell FDC we've finished + ei + + call fd765_read_status + call tc_fix + + ld bc,#0x7f10 + out (c),c + ld a,(_vtborder) + out (c),a + + pop af + ret z + jp map_kernel + +; +; We will get an error reported that the command did not complete +; because the tc bit is not controllable. Spot that specific error +; and ignore it. +; +tc_fix: + ld hl,#_fd765_status + ld a,(hl) + and #0xC0 + cp #0x40 + ret nz + inc hl + bit 7,(hl) + ret z + res 7,(hl) + dec hl + res 6,(hl) + ret + +; +; Write is much like read just the other direction +; +_fd765_do_write: + ; interrupts off + ld a, #0x45 ; WRITE SECTOR MFM + call setup_read_or_write + + ld a, (_fd765_is_user) + or a + push af + call nz, map_proc_always + + ld bc,#0x7f10 + out (c),c + ld c,#0x47 ;Pink + out (c),c + + di + + xor a + call fd765_tx ; send the final unused 0 byte + ; to fire off the command + ld hl, (_fd765_buffer) + ld bc, #0xfb7e +fdc_data_write: + in a,(c) ;; FDC has data and the direction is from FDC to CPU + jp p,fdc_data_write ;; + and #0x20 ;; "Execution phase" i.e. indicates reading of sector data + jp z,fdc_write_end + + inc c ;; BC = I/O address for FDC data register + ld a,(hl) ;; read from memory + out (c),a ;; write to FDC data register + dec c ;; BC = I/O address for FDC main status register + inc hl ;; increment memory pointer + jp fdc_data_write + +fdc_write_end: +; ld de,#0x2000 ; to make timing +; jp write_wait +; +;write_loop: +; inc c +; outi +; inc b +; dec c +; dec e +; jp z, write_wait2 +;write_wait: +; in a,(c) +; jp p, write_wait +; and d +; jp nz, write_loop +; jp write_finished +;write_loop2: +; inc c +; outi +; inc b +; dec c +; dec e +; jp z, write_flush_wait +;write_wait2: +; in a,(c) +; jp p, write_wait2 +; and d +; jp nz, write_loop2 +; jp write_finished +;write_flush: +; inc c +; in a,(c) +; dec c +;write_flush_wait: +; in a,(c) +; jp p, write_flush_wait +; and d +; jp nz, write_flush +write_finished: + ld (_fd765_buffer), hl + call _fd765_do_nudge_tc ; Tell FDC we've finished + ei + call fd765_read_status + call tc_fix + + ld bc,#0x7f10 + out (c),c + ld a,(_vtborder) + out (c),a + + pop af + ret z + jp map_kernel + +; Given an FDC opcode in A, sets up a read or write. + +setup_read_or_write: + call fd765_tx ; 0: send opcode (in A) + call send_head ; 1: specified head, drive #0 + ld a, (_fd765_track) ; 2: specified track + call fd765_tx + ld a, (_fd765_head) ; 3: specified head + call fd765_tx + ld a, (_fd765_sector) ; 4: specified sector + ld b, a + call fd765_tx + ld a, #2 ; 5: bytes per sector: 512 + call fd765_tx + ld a, (_fd765_sectors) + add b ; add first sector + dec a ; 6: last sector (*inclusive*) + call fd765_tx + ld a, #0x2A ; 7: Gap 3 length (2A is standard for 3" drives) + call fd765_tx + ; We return with the final unused 0 value not written. We need all + ; the other stuff lined up before we write this. + ret + +_fd765_buffer: + .dw 0 +_fd765_is_user: + .db 0 +_fd765_sectors: + .db 0 + +; Read the next sector ID off the disk. +; (Only used for debugging.) + +_fd765_do_read_id: + ld a, #0x4a ; READ MFM ID + call fd765_tx + call send_head ; specified head, drive 0 + jp fd765_read_status diff --git a/Kernel/platform/platform-cpc6128-SME/fuzix-platform-cpc6128-SME.pkg b/Kernel/platform/platform-cpc6128-SME/fuzix-platform-cpc6128-SME.pkg new file mode 100644 index 0000000000..526097fcbd --- /dev/null +++ b/Kernel/platform/platform-cpc6128-SME/fuzix-platform-cpc6128-SME.pkg @@ -0,0 +1,7 @@ +package platform-cpc6128-SME + +disable-pkg platform-cpc6128-SME + +l /bin/sh /bin/sh.orig +r /bin/sh +l /bin/fsh /bin/sh \ No newline at end of file diff --git a/Kernel/platform/platform-cpc6128-SME/fuzix.export b/Kernel/platform/platform-cpc6128-SME/fuzix.export new file mode 100644 index 0000000000..e69de29bb2 diff --git a/Kernel/platform/platform-cpc6128-SME/fuzix.lnk.bck b/Kernel/platform/platform-cpc6128-SME/fuzix.lnk.bck new file mode 100644 index 0000000000..cb04214f01 --- /dev/null +++ b/Kernel/platform/platform-cpc6128-SME/fuzix.lnk.bck @@ -0,0 +1,59 @@ +-mwxuy +-i fuzix.ihx +-l z80 +-b _CODE=0x0100 +-b _COMMONMEM=0xF300 +platform/platform-cpc6128/crt0.rel +platform/platform-cpc6128/commonmem.rel +platform/platform-cpc6128/plus3.rel +platform/platform-cpc6128/zxvideo.rel +platform/platform-cpc6128/main.rel +platform/platform-cpc6128/discard.rel +start.rel +version.rel +cpu-z80/lowlevel-z80.rel +cpu-z80/usermem_std-z80.rel +platform/platform-cpc6128/tricks.rel +timer.rel +kdata.rel +usermem.rel +platform/platform-cpc6128/devices.rel +devio.rel +filesys.rel +blk512.rel +process.rel +inode.rel +syscall_exec.rel +syscall_exec16.rel +syscall_fs.rel +syscall_fs2.rel +syscall_fs3.rel +syscall_proc.rel +syscall_other.rel +syscall_net.rel +tty.rel +vt.rel +font8x8.rel +mm.rel +memalloc_none.rel +simple.rel +swap.rel +devsys.rel +devinput.rel +kmod.rel +network.rel +platform/platform-cpc6128/devtty.rel +platform/platform-cpc6128/tinyide.rel +platform/platform-cpc6128/tinyide_discard.rel +platform/platform-cpc6128/divide.rel +platform/platform-cpc6128/tinysd.rel +platform/platform-cpc6128/tinysd_discard.rel +platform/platform-cpc6128/zxmmc.rel +platform/platform-cpc6128/tinydisk.rel +platform/platform-cpc6128/tinydisk_discard.rel +platform/platform-cpc6128/devinput.rel +platform/platform-cpc6128/zxkeyboard.rel +platform/platform-cpc6128/devfdc765.rel +platform/platform-cpc6128/fdc765.rel +platform/platform-cpc6128/net_w5x00.rel +-e diff --git a/Kernel/platform/platform-cpc6128-SME/kernel.def b/Kernel/platform/platform-cpc6128-SME/kernel.def new file mode 100644 index 0000000000..d061dd72e8 --- /dev/null +++ b/Kernel/platform/platform-cpc6128-SME/kernel.def @@ -0,0 +1,13 @@ +; UZI mnemonics for memory addresses etc + +; We stick it straight after the tag +U_DATA__TOTALSIZE .equ 0x200 ; 256+256@F000 + +Z80_TYPE .equ 1 + +PROGBASE .equ 0x0000 +PROGLOAD .equ 0x0100 + +NBUFS .equ 5 + +Z80_MMU_HOOKS .equ 0 diff --git a/Kernel/platform/platform-cpc6128-SME/loader.s b/Kernel/platform/platform-cpc6128-SME/loader.s new file mode 100644 index 0000000000..be3d137ab4 --- /dev/null +++ b/Kernel/platform/platform-cpc6128-SME/loader.s @@ -0,0 +1,413 @@ +;;from https://cpctech.cpc-live.com/ +;; Load data by talking directly to the NEC765 floppy disc controller (FDC) +;; https://cpctech.cpcwiki.de/source/fdcload.html from Kevin Thacker site +;; Code assumes there is a drive 0 and there is a disc in it and the disc is formatted +;; to SYSTEM format. +.area BOOT (ABS) +.org #0xfdff + +;;ROM's & interrupts off + +di +ld b, #0x7f +ld c,#0b10101101 +out (c),c +;;from default boot org to the needed one +ld hl,#0x100 +ld de,#0xfdff +ld bc,#512 +ldir + +jp start + +start: +;;clean room +ld hl,#0 +ld de ,#1 +ld (#0),hl +ld bc,#0xfdfe +ldir +;;patch interrupt vector +LD HL,#0XC9FB +LD (#0X0038),HL +;; turn on disc motor +ld bc,#0xfa7e +ld a,#1 +out (c),a +;; the motor on all connected drives will be turned on +;; and the motor will start to speed up. +;; +;; The drive must be "Ready" to accept commands from the FDC. +;; A drive will be ready if: +;; * the drive motor has reached a stable speed +;; * there is a disc in the drive +;; +;; The following code is a delay which will ait enough time for the motor +;; to reach a stable speed. (i.e. the motor speed is not increasing or decreasing) +;; +;; All drives are not the same, some 3" drives take longer to reach a stable +;; speed so we need a longer delay to be compatible with these. +;; +;; At this point interrupts must be enabled. +ei +ld b,#30 ;; 30/6 = 5 frames or 5/50 of a second. +w1: +;; there are 6 CPC interrupts per frame. This waits for one of them +halt +djnz w1 +di +;; this is the drive we want to use +;; the code uses this variable. +ld a,#0 +ld (#drive),a + +;; recalibrate means to move the selected drive to track 0. +;; +;; track 0 is a physical signal from the drive that indicates when +;; the read/write head is at track 0 position. +;; +;; The drive itself doesn't know which track the read/write head is positioned over. +;; The FDC has an internal variable for each drive which holds the current track number. +;; This value is reset when the drive indicates the read/write head is over track 0. +;; The number is increased/decreased as the FDC issues step pulses to the drive to move the head +;; to the track we want. +;; +;; once a recalibrate has been done, both drive and fdc agree on the track. +;; +call fdc_recalibrate + +;; now the drive is at a known position and is ready the fdc knows it is at a known position +;; we can read data.. +;call read_file + +read_file: +;; set variable for starting sector for our data (#0xC1 is first sector ID for +;; SYSTEM format. Sector IDs are #0x41, #0x42, #0x43, #0x44, #0x45, #0x46, #0x47, #0x48 and #0x49. +;; This bootloader is in track 0 sector #0x41 to load with |cpm command from basic + +ld a,#0x42 +ld (#sector),a + +;; set variable for starting track for our data +;; Tracks are numbered 0 to 39 for 40 track drives and 0 to 79 for 80 track drives. +;; Some 3" drives can allow up to 42 tracks (0-41), some 80 track drives can allow up +;; to 83 tracks (0-82). +;; +;; Not all drives are the same however. The maximum that is compatible with all 3" drives +;; is 41 tracks. +ld a,#0 +ld (#track),a + +;; memory address to write data to (start) +ld de,#0x100 +ld (#data_ptr),de + +;; number of complete sectors to read for our data +;; 30 sectors, 512 bytes per sector. Total data to read is 30*512 = 15360 bytes. +ld a,#126 +ld (#sector_count),a + +read_sectors_new_track: +;; perform a seek (this means to move read/write head to track we want). +;; track is defined by the "track" variable. +;; +;; a recalibrate must be done on the drive before a seek is done. +;; +;; the fdc uses it's internal track value for the chosen drive to decide to seek up/down to +;; reach the desired track. The FDC issues "step pulses" which makes the read/write head move +;; 1 track at a time at the rate defined by the FDC specify command. +;; +;; e.g. if fdc thinks we are on track 10, and we ask it to move to track 5, it will step back 5 times +;; updating it's internal track number each time. +call fdc_seek + +read_sectors: +;; Send Read data command to FDC to read 1 sector. + +;; A track is layed out as follows: +;; +;; id field +;; data field +;; +;; id field +;; data field +;; +;; id field +;; data field +;; etc. +;; +;; we tell the FDC the values of the ID field we want. Once it finds a match it will then read +;; the data. If the ID field we want is not found, it will report an error. + + +ld a,#0b01000110 ;; read data command (mfm=double density reading mode) + ;; not multi-track. See FDC data sheet for list of commands and the + ;; number of bytes they need. +call fdc_write_command +ld a,(#drive) ;; physical drive and side + ;; bits 1,0 define drive, bit 2 defines side +call fdc_write_command +ld a,(#track) ;; C value from id field of sector we want to read +call fdc_write_command +ld a,#0 ;; H value from id field of sector we want to read +call fdc_write_command +ld a,(#sector) ;; R value from id field of sector we want to read +call fdc_write_command +ld a,#2 ;; N value from id field of sector we want to read + ;; this also determines the amount of data in the sector. + ;; 2 = 512 byte sector +call fdc_write_command +ld a,(#sector) ;; EOT = Last sector ID to read. This is the same as the first to read 1 sector. +call fdc_write_command +ld a,#0x2a ;; Gap Length for read. Not important. +call fdc_write_command +ld a,#0xff ;; DTL = Data length. Only valid when N is 0 it seems +call fdc_write_command + +;; There will be a delay here before the first byte of a sector is ready and +;; interrupts can be active. +;; +;; The FDC is reading from the track. It is searching for an ID field that +;; matches the values we have sent in the command. +;; +;; When it finds the ID field, there is furthur time before the data field +;; of the sector is found and it starts to read. +;; +;; Once it has found the data, we must read it all and quickly. +;; + + +;; interrupts must be off now for data to be read successfully. +;; +;; The CPU constantly asks the FDC if there is data ready, if there is +;; it reads it from the FDC and stores it in RAM. There is a timing +;; constraint, the FDC gives the CPU a byte every 32microseconds. +;; If the CPU fails to read one of the bytes in time, the FDC will report +;; an overrun error and stop data transfer. + + +;; current address to write data too. +ld de,(#data_ptr) + +;; this is the main loop +;; which reads the data +;; The FDC will give us a byte every 32us (double density disc format). +;; +;; We must read it within this time. + +fdc_data_read: +in a,(c) ;; FDC has data and the direction is from FDC to CPU +jp p,fdc_data_read ;; +and #0x20 ;; "Execution phase" i.e. indicates reading of sector data +jp z,fdc_read_end + +inc c ;; BC = I/O address for FDC data register +in a,(c) ;; read from FDC data register +ld (de),a ;; write to memory +dec c ;; BC = I/O address for FDC main status register +inc de ;; increment memory pointer +jp fdc_data_read + +fdc_read_end: +;; Interrupts can be enabled now we have completed the data transfer + + + +;; we will get here if we successfully read all the sector's data +;; OR if there was an error. + +;; read the result +call fdc_result + +;; check result +ld ix,#result_data +ld c,#0x54 +ld a,0(ix) +cp #0x40 +jp z,nerr +ld a,1(ix) +cp #0x80 +jp z,nerr +ld c,#0x40 +nerr: + +;; decrease number of sectors transferred +ld a,(#sector_count) +dec a +jp z,read_done +ld (#sector_count),a + +;; update ram pointer for next sector +ld hl,(#data_ptr) +ld bc,#512 +add hl,bc +ld (#data_ptr),hl + +;; update sector id (loops #0x41-#0x49). +ld a,(#sector) +inc a +ld (#sector),a +cp #0x4a ;; #0x49+1 (last sector id on the track+1) +jp nz,read_sectors +;; we read sector #0x49, the last on the track. +;; Update track variable so we seek to the next track before +;; reading the next sector +ld a,(#track) +inc a +ld (#track),a + +ld a,#0x41 ;; #0x41 = first sector id on the track +ld (#sector),a +jp read_sectors_new_track + +read_done: +ld bc,#0xfa7e +ld a,#0 +out (c),a ;stop the motor +jp 0x100 ;start FUZIX + +;;=============================================== +;; send command to fdc +;; + +fdc_write_command: + + +ld bc,#0xfb7e ;; I/O address for FDC main status register +push af ;; +fwc1: in a,(c) ;; +add a,a ;; +jr nc,fwc1 ;; +add a,a ;; +jr nc,fwc2 ;; +pop af ;; +ret + +fwc2: +pop af ;; + +inc c ;; +out (c),a ;; write command byte +dec c ;; + +;; some FDC documents say there must be a delay between each +;; command byte, but in practice it seems this isn't needed on CPC. +;; Here for compatiblity. +ld a,#5 ;; +fwc3: dec a ;; +jr nz,fwc3 ;; +ret ;; + +;;=============================================== +;; get result phase of command +;; +;; timing is not important here + +fdc_result: + +ld hl,#result_data +ld bc,#0xfb7e +fr1: +in a,(c) +cp #0xc0 +jr c,fr1 + +inc c +in a,(c) +dec c +ld (hl),a +inc hl + +ld a,#5 +fr2: +dec a +jr nz,fr2 +in a,(c) +and #0x10 +jr nz,fr1 + + +ret + +;;=============================================== + +;; physical drive +;; bit 1,0 are drive, bit 2 is side. +drive: +.db 0 + +;; physical track (updated during read) +track: +.db 0 + +;; id of sector we want to read (updated during read) +sector: +.db 0 + +;; number of sectors to read (updated during read) +sector_count: +.db 2 ;; enough for now + +;; address to write data to (updated during read) +data_ptr: +.ds 2 + +;;=============================================== + +fdc_seek: +ld a,#0b00001111 ;; seek command +call fdc_write_command +ld a,(#drive) +call fdc_write_command +ld a,(#track) +call fdc_write_command + +call fdc_seek_or_recalibrate +jp nz,fdc_seek +ret + +;;=============================================== + +fdc_recalibrate: + +;; seek to track 0 +ld a,#0b111 ;; recalibrate +call fdc_write_command +ld a,(#drive) ;; drive +call fdc_write_command + +call fdc_seek_or_recalibrate +jp nz,fdc_recalibrate +ret + +;;=============================================== +;; NZ result means to retry seek/recalibrate. + +fdc_seek_or_recalibrate: +ld a,#0b1000 ;; sense interrupt status +call fdc_write_command +call fdc_result + +;; recalibrate completed? +ld ix,#result_data +bit 5,0(ix) ;; Bit 5 of Status register 0 is "Seek complete" +jr z,fdc_seek_or_recalibrate +bit 4,0(ix) ;; Bit 4 of Status register 0 is "recalibrate/seek failed" +;; +;; Some FDCs will seek a maximum of 77 tracks at one time. This is a legacy/historical +;; thing when drives only had 77 tracks. 3.5" drives have 80 tracks. +;; +;; If the drive was at track 80 before the recalibrate/seek, then one recalibrate/seek +;; would not be enough to reach track 0 and the fdc will then report an error (meaning +;; it had seeked 77 tracks and failed to reach the track we wanted). +;; We repeat the recalibrate/seek to finish the movement of the read/write head. +;; +ret + +;;=============================================== + +file_buffer: +.dw 0x100 +result_data: +.ds 8 +end: \ No newline at end of file diff --git a/Kernel/platform/platform-cpc6128-SME/loader_firmware.s b/Kernel/platform/platform-cpc6128-SME/loader_firmware.s new file mode 100644 index 0000000000..b384288459 --- /dev/null +++ b/Kernel/platform/platform-cpc6128-SME/loader_firmware.s @@ -0,0 +1,94 @@ +;;from: https://cpctech.cpc-live.com/source/byteload.html, modified to load something bigger + +;; This example shows how to read a file byte by byte. +;; +;; A file without a header must be read this way, it can't be +;; read using CAS IN DIRECT (unless the in-memory header is patched) +;; +;; This example doesn't have any error checking. + +.area BOOT (ABS) +.org 0xa500 + +cas_in_open .equ 0xbc77 +cas_in_close .equ 0xbc7a +cas_in_char .equ 0xbc80 +kl_rom_walk .equ 0xbccb +mc_start_program .equ 0xbd16 + +ld c,#0xff +ld hl,#start +call mc_start_program +start: +ld hl,#0x0100 ;; address to load file data to (example) +push hl + +call kl_rom_walk +;; open file for reading +ld b,#end_filename-filename +ld hl,#filename +ld de,#two_k_buffer +call cas_in_open + +;; If a file is opened without a header: +;; - the filetype will be ASCII (0x16) +;; - the length and load address will be undefined. +;; +;; If a file is opened with a header, the +;; - the filetype will be taken from the header +;; - the length and load address will be taken from the header +;; +;; A file without a header can't be read with CAS IN DIRECT +;; and must be read using CAS IN CHAR. + +pop hl + +;; read a char from the file, character is returned in A register + +next_byte: +call cas_in_char +jr nc,not_eof +jr nz,not_eof + +;; could be end of file +;; test for hard end of file byte +cp #0xf +jr nz,not_eof +jr eof + +not_eof: +;; write byte to memory +ld (hl),a +inc hl +ld a,#0xA5 +cp h +jr z, avoid_crash +jr next_byte + + +eof: +call cas_in_close +ld de,#0xA500 +ld hl,#0xC000 +ld bc,#0x4000 +ldir +jp 0x100 ;; and go to fuzix + +avoid_crash: +ld b,#0x1b ;;0xc0-0xa5 +ld c,#0 +add hl,bc +jr next_byte + +;;------------------------------------------------------------------- +;; name of the file to read + +filename: +.ascii "FUZIX.BIN" +end_filename: + +;;------------------------------------------------------------------- +;; this buffer is filled with data from the file +.org 0xF7FF +two_k_buffer: +.blkb 2048 \ No newline at end of file diff --git a/Kernel/platform/platform-cpc6128-SME/main.c b/Kernel/platform/platform-cpc6128-SME/main.c new file mode 100644 index 0000000000..03dfa901c7 --- /dev/null +++ b/Kernel/platform/platform-cpc6128-SME/main.c @@ -0,0 +1,156 @@ +#include +#include +#include +#include +#include +#include +#include +//#include + +uint16_t ramtop = PROGTOP; +uint16_t swap_dev = 0xFFFF; + +/* On idle we spin checking for the terminals. Gives us more responsiveness + for the polled ports */ +void plt_idle(void) +{ + /* We don't want an idle poll and IRQ driven tty poll at the same moment */ + __asm + halt + __endasm; +} + +uint8_t timer_wait; + +void plt_interrupt(void) +{ + tty_pollirq(); + timer_interrupt(); + poll_input(); + if (timer_wait) + wakeup(&timer_interrupt); + devfd_spindown(); +} + +/* + * So that we don't suck in a library routine we can't use from + * the runtime + */ + +size_t strlen(const char *p) +{ + size_t len = 0; + while(*p++) + len++; + return len; +} + +/* This points to the last buffer in the disk buffers. There must be at least + four buffers to avoid deadlocks. */ +struct blkbuf *bufpool_end = bufpool + NBUFS; + +/* + * We pack discard into the memory image is if it were just normal + * code but place it at the end after the buffers. When we finish up + * booting we turn everything from the buffer pool to the start of + * user space into buffers. + * + * We don't touch discard. Discard is just turned into user space. + */ +void plt_discard(void) +{ + uint16_t discard_size = ((uint16_t)&udata) - (uint16_t)bufpool_end; + bufptr bp = bufpool_end; +#ifdef CONFIG_KMOD + kmod_init(bufpool_end, &udata); +#endif + + discard_size /= sizeof(struct blkbuf); + + kprintf("%d buffers added\n", discard_size); + + bufpool_end += discard_size; + + memset( bp, 0, discard_size * sizeof(struct blkbuf) ); + + for( bp = bufpool + NBUFS; bp < bufpool_end; ++bp ){ + bp->bf_dev = NO_DEVICE; + bp->bf_busy = BF_FREE; + } +} + +unsigned plt_kmod_set(uint8_t *top) +{ + /* Make sure all disk buffers are on disk */ + sync(); + /* Wind back until bufpool end is below the modules */ + while(bufpool_end > (void *)top) + bufpool_end--; + /* Any buffers lost we already wrote to disk, any new lookups will + not find them, and we know there are no other outstanding references + - sometimes having a dumb I/O layer is a win */ + return 0; +} + +#ifndef SWAPDEV +/* Adding dummy swapper since it is referenced by tricks.s */ +void swapper(ptptr p) +{ + p; +} +#endif + +#ifdef CONFIG_NET_W5100 + +uint8_t w5x00_readcb(uint16_t off) +{ +} + +uint8_t w5x00_readsb(uint8_t s, uint16_t off) +{ +} + +uint16_t w5x00_readcw(uint16_t off) +{ +} + +uint16_t w5x00_readsw(uint8_t s, uint16_t off) +{ +} + +void w5x00_bread(uint16_t bank, uint16_t off, void *pv, uint16_t n) +{ +} + +void w5x00_breadu(uint16_t bank, uint16_t off, void *pv, uint16_t n) +{ +} + +void w5x00_writecb(uint16_t off, uint8_t n) +{ +} + +void w5x00_writesb(uint8_t sock, uint16_t off, uint8_t n) +{ +} + +void w5x00_writecw(uint16_t off, uint16_t n) +{ +} + +void w5x00_writesw(uint8_t sock, uint16_t off, uint16_t n) +{ +} + +void w5x00_bwrite(uint16_t bank, uint16_t off, void *pv, uint16_t n) +{ +} + +void w5x00_bwriteu(uint16_t bank, uint16_t off, void *pv, uint16_t n) +{ +} + +void w5x00_setup(void) +{ +} +#endif diff --git a/Kernel/platform/platform-cpc6128-SME/platform_fdc765.h b/Kernel/platform/platform-cpc6128-SME/platform_fdc765.h new file mode 100644 index 0000000000..da41e4c3fc --- /dev/null +++ b/Kernel/platform/platform-cpc6128-SME/platform_fdc765.h @@ -0,0 +1,12 @@ +/* + * Platform specifics + */ + +#define FDC_MOTOR_TIMEOUT 10 /* Seconds */ + +#define FDC765_MAX_FLOPPY 2 /* Two drives */ + + +/* Hard code for now. Two drives, second drive double sided */ +#define fdc765_ds 2 +#define fdc765_present 3 \ No newline at end of file diff --git a/Kernel/platform/platform-cpc6128-SME/plt_ch375.h b/Kernel/platform/platform-cpc6128-SME/plt_ch375.h new file mode 100644 index 0000000000..8a4f0a0457 --- /dev/null +++ b/Kernel/platform/platform-cpc6128-SME/plt_ch375.h @@ -0,0 +1,14 @@ +extern void nap20(void); +extern void ch375_rblock(uint8_t *ptr);/* __z88dk_fastcall; */ +extern void ch375_wblock(uint8_t *ptr);/* __z88dk_fastcall; */ + +__sfr __banked __at 0xFE80 ch375_dport; +__sfr __banked __at 0xFE81 ch375_sport; + +#define ch375_rdata() ch375_dport +#define ch375_rstatus() ch375_sport + +#define ch375_wdata(x) do {ch375_dport = (x); } while(0) +#define ch375_wcmd(x) do {ch375_sport = (x); } while(0) + +#define CH376_REG_DATA 0xFE80 \ No newline at end of file diff --git a/Kernel/platform/platform-cpc6128-SME/plt_ide.h b/Kernel/platform/platform-cpc6128-SME/plt_ide.h new file mode 100644 index 0000000000..4d6c0567cc --- /dev/null +++ b/Kernel/platform/platform-cpc6128-SME/plt_ide.h @@ -0,0 +1,13 @@ +__sfr __banked __at 0xFD08 data; +__sfr __banked __at 0xFD09 error; +__sfr __banked __at 0xFD0A count; +__sfr __banked __at 0xFD0B sec; +__sfr __banked __at 0xFD0C cyll; +__sfr __banked __at 0xFD0D cylh; +__sfr __banked __at 0xFD0E devh; +__sfr __banked __at 0xFD0F cmd; +__sfr __banked __at 0xFD0F status; + +#define IDE_REG_DATA 0xFD08 + +#define IDE_NONSTANDARD_XFER diff --git a/Kernel/platform/platform-cpc6128-SME/rd_cpcsme.s b/Kernel/platform/platform-cpc6128-SME/rd_cpcsme.s new file mode 100644 index 0000000000..68eb1b4799 --- /dev/null +++ b/Kernel/platform/platform-cpc6128-SME/rd_cpcsme.s @@ -0,0 +1,107 @@ +; +; RAM disc helpers for CPC Standard Memory Expansions +; + + .area _CODE + + .globl _rd_io + + .globl _ct + .globl _block + .globl _nblock + .globl _rd_wr + .globl _rd_swap_mem_port_h + .globl _rd_swap_bank + .globl _rd_proc_bank + .globl _rd_swap_bank_addr + .globl _rd_proc_bank_addr + .globl _rd_dptr + .globl _int_disabled + .globl _vtborder + .globl map_kernel_restore + + +_rd_io: + di + ld a,(_rd_wr) + or a + jp z, is_wr + ld bc,#0x7f10 + out (c),c + ld c,#0x53 ;Bright cyan + out (c),c + ld a,(_rd_swap_mem_port_h) + ld b,a + ld c,#0xff + ld a,(_rd_swap_bank) + out (c),a + ld hl,(_rd_swap_bank_addr) + ld de, #swapbuffer + ld bc,#512 + ldir + ld bc,#0x7fff + ld a,(_rd_proc_bank) + out (c),a + ld hl,#swapbuffer + ld de,(_rd_proc_bank_addr) + ld bc,#512 + ldir +end_io: + ld bc,#0x7fc1 ; map kernel + out (c),c + call map_kernel_restore ; do it the right way + ld bc,#0x7f10 + out (c),c + ld a,(_vtborder) + out (c),a + ld a,(_int_disabled) + or a + ret nz + ei + ret +is_wr: + ld bc,#0x7f10 + out (c),c + ld c,#0x4c ;Bright red + out (c),c + ld bc,#0x7fff + ld a,(_rd_proc_bank) + out (c),a + ld hl,(_rd_proc_bank_addr) + ld de,#swapbuffer + ld bc,#512 + ldir + ld a,(_rd_swap_mem_port_h) + ld b,a + ld c,#0xff + ld a,(_rd_swap_bank) + out (c),a + ld hl,#swapbuffer + ld de,(_rd_swap_bank_addr) + ld bc,#512 + ldir + jp end_io + +_ct: + .db 0 +_rd_wr: + .db 0 +_rd_swap_bank: + .db 0 +_rd_proc_bank: + .db 0 +_rd_swap_mem_port_h: + .db 0x7f +_rd_swap_bank_addr: + .dw 0 +_rd_proc_bank_addr: + .dw 0 +_rd_dptr: + .dw 0 +_block: + .dw 0 +_nblock: + .dw 0 +swapbuffer: + .ds 512 + diff --git a/Kernel/platform/platform-cpc6128-SME/rules.mk b/Kernel/platform/platform-cpc6128-SME/rules.mk new file mode 100644 index 0000000000..edaf0e339a --- /dev/null +++ b/Kernel/platform/platform-cpc6128-SME/rules.mk @@ -0,0 +1,2 @@ +export CROSS_CC_SYS5=--codeseg CODE3 +CROSS_CCOPTS += --peep-file $(FUZIX_ROOT)/Kernel/cpu-z80/rst.peep diff --git a/Kernel/platform/platform-cpc6128-SME/target.mk b/Kernel/platform/platform-cpc6128-SME/target.mk new file mode 100644 index 0000000000..3bffcde0c7 --- /dev/null +++ b/Kernel/platform/platform-cpc6128-SME/target.mk @@ -0,0 +1 @@ +export CPU = z80 diff --git a/Kernel/platform/platform-cpc6128-SME/tricks.s b/Kernel/platform/platform-cpc6128-SME/tricks.s new file mode 100644 index 0000000000..2d02424493 --- /dev/null +++ b/Kernel/platform/platform-cpc6128-SME/tricks.s @@ -0,0 +1,5 @@ + .include "kernel.def" + .include "../../cpu-z80/kernel-z80.def" + + .include "../../lib/z80single.s" + From 28aeb8f22372b815fa7b6a919c8e2ed3c47e6e8b Mon Sep 17 00:00:00 2001 From: ajcasado Date: Tue, 21 Jan 2025 20:48:17 +0100 Subject: [PATCH 4/7] merge cpc6128 ports --- Kernel/platform/platform-cpc6128-SME/Makefile | 86 --- Kernel/platform/platform-cpc6128-SME/Notes.md | 22 - Kernel/platform/platform-cpc6128-SME/README | 68 --- .../platform/platform-cpc6128-SME/commonmem.s | 9 - Kernel/platform/platform-cpc6128-SME/config.h | 104 ---- .../platform/platform-cpc6128-SME/cpc6128.s | 373 ------------ .../platform/platform-cpc6128-SME/cpcvideo.s | 44 -- Kernel/platform/platform-cpc6128-SME/crt0.s | 211 ------- .../platform/platform-cpc6128-SME/devices.c | 63 --- Kernel/platform/platform-cpc6128-SME/devrd.c | 80 --- Kernel/platform/platform-cpc6128-SME/devrd.h | 20 - Kernel/platform/platform-cpc6128-SME/devtty.c | 132 ----- Kernel/platform/platform-cpc6128-SME/devtty.h | 24 - .../platform/platform-cpc6128-SME/discard.c | 31 - Kernel/platform/platform-cpc6128-SME/fdc765.s | 530 ------------------ .../fuzix-platform-cpc6128-SME.pkg | 7 - .../platform-cpc6128-SME/fuzix.export | 0 .../platform-cpc6128-SME/fuzix.lnk.bck | 59 -- .../platform/platform-cpc6128-SME/kernel.def | 13 - Kernel/platform/platform-cpc6128-SME/loader.s | 413 -------------- .../platform-cpc6128-SME/loader_firmware.s | 94 ---- Kernel/platform/platform-cpc6128-SME/main.c | 156 ------ .../platform-cpc6128-SME/platform_fdc765.h | 12 - .../platform/platform-cpc6128-SME/plt_ch375.h | 14 - .../platform/platform-cpc6128-SME/plt_ide.h | 13 - .../platform/platform-cpc6128-SME/rd_cpcsme.s | 107 ---- Kernel/platform/platform-cpc6128-SME/rules.mk | 2 - .../platform/platform-cpc6128-SME/target.mk | 1 - Kernel/platform/platform-cpc6128-SME/tricks.s | 5 - 29 files changed, 2693 deletions(-) delete mode 100644 Kernel/platform/platform-cpc6128-SME/Makefile delete mode 100644 Kernel/platform/platform-cpc6128-SME/Notes.md delete mode 100644 Kernel/platform/platform-cpc6128-SME/README delete mode 100644 Kernel/platform/platform-cpc6128-SME/commonmem.s delete mode 100644 Kernel/platform/platform-cpc6128-SME/config.h delete mode 100644 Kernel/platform/platform-cpc6128-SME/cpc6128.s delete mode 100644 Kernel/platform/platform-cpc6128-SME/cpcvideo.s delete mode 100644 Kernel/platform/platform-cpc6128-SME/crt0.s delete mode 100644 Kernel/platform/platform-cpc6128-SME/devices.c delete mode 100644 Kernel/platform/platform-cpc6128-SME/devrd.c delete mode 100644 Kernel/platform/platform-cpc6128-SME/devrd.h delete mode 100644 Kernel/platform/platform-cpc6128-SME/devtty.c delete mode 100644 Kernel/platform/platform-cpc6128-SME/devtty.h delete mode 100644 Kernel/platform/platform-cpc6128-SME/discard.c delete mode 100644 Kernel/platform/platform-cpc6128-SME/fdc765.s delete mode 100644 Kernel/platform/platform-cpc6128-SME/fuzix-platform-cpc6128-SME.pkg delete mode 100644 Kernel/platform/platform-cpc6128-SME/fuzix.export delete mode 100644 Kernel/platform/platform-cpc6128-SME/fuzix.lnk.bck delete mode 100644 Kernel/platform/platform-cpc6128-SME/kernel.def delete mode 100644 Kernel/platform/platform-cpc6128-SME/loader.s delete mode 100644 Kernel/platform/platform-cpc6128-SME/loader_firmware.s delete mode 100644 Kernel/platform/platform-cpc6128-SME/main.c delete mode 100644 Kernel/platform/platform-cpc6128-SME/platform_fdc765.h delete mode 100644 Kernel/platform/platform-cpc6128-SME/plt_ch375.h delete mode 100644 Kernel/platform/platform-cpc6128-SME/plt_ide.h delete mode 100644 Kernel/platform/platform-cpc6128-SME/rd_cpcsme.s delete mode 100644 Kernel/platform/platform-cpc6128-SME/rules.mk delete mode 100644 Kernel/platform/platform-cpc6128-SME/target.mk delete mode 100644 Kernel/platform/platform-cpc6128-SME/tricks.s diff --git a/Kernel/platform/platform-cpc6128-SME/Makefile b/Kernel/platform/platform-cpc6128-SME/Makefile deleted file mode 100644 index e5ca626012..0000000000 --- a/Kernel/platform/platform-cpc6128-SME/Makefile +++ /dev/null @@ -1,86 +0,0 @@ -CSRCS = devtty.c devices.c main.c devrd.c -CDSRCS = discard.c -DSRCS = ../../dev/tinyide.c ../../dev/tinydisk.c ../../dev/devfdc765.c ../../dev/ch375.c -DDSRCS = ../../dev/tinyide_discard.c ../../dev/tinydisk_discard.c -DZSRCS = ../../dev/cpc/cpcide.c ../../dev/cpc/cpckeyboard.c ../../dev/cpc/devinput.c ../../dev/cpc/albireo.c -DDZSRCS = -ASRCS = crt0.s cpc6128.s cpcvideo.s fdc765.s rd_cpcsme.s -ASRCS += tricks.s commonmem.s -NSRCS = - -COBJS = $(CSRCS:.c=.rel) -CDOBJS = $(CDSRCS:.c=.rel) -AOBJS = $(ASRCS:.s=.rel) -DOBJS = $(patsubst ../../dev/%.c,%.rel, $(DSRCS)) -DDOBJS = $(patsubst ../../dev/%.c,%.rel, $(DDSRCS)) -DZOBJS = $(patsubst ../../dev/cpc/%.c,%.rel, $(DZSRCS)) -DDZOBJS = $(patsubst ../../dev/cpc/%.c,%.rel, $(DDZSRCS)) -NOBJS = $(patsubst ../../dev/net/%.c,%.rel, $(NSRCS)) -OBJS = $(COBJS) $(CDOBJS) $(AOBJS) $(DOBJS) $(DDOBJS) $(DZOBJS) $(DDZOBJS) $(NOBJS) - -CROSS_CCOPTS += -I../../dev/ -I../../dev/cpc/ -I../../dev/net - -CROSS_CC_SEG3 = --codeseg CODE3 - -all: $(OBJS) - -$(COBJS): %.rel: %.c - $(CROSS_CC) $(CROSS_CCOPTS) $(CROSS_CC_SEG3) -c $< - -$(CDOBJS): %.rel: %.c - $(CROSS_CC) $(CROSS_CCOPTS) $(CROSS_CC_SEGDISC) -c $< - -$(DOBJS): %.rel: ../../dev/%.c - $(CROSS_CC) $(CROSS_CCOPTS) $(CROSS_CC_SEG3) -c $< - -$(DDOBJS): %.rel: ../../dev/%.c - $(CROSS_CC) $(CROSS_CCOPTS) $(CROSS_CC_SEGDISC) -c $< - -$(DZOBJS): %.rel: ../../dev/cpc/%.c - $(CROSS_CC) $(CROSS_CCOPTS) $(CROSS_CC_SEG3) -c $< - -$(DDZOBJS): %.rel: ../../dev/cpc/%.c - $(CROSS_CC) $(CROSS_CCOPTS) $(CROSS_CC_SEGDISC) -c $< - -$(NOBJS): %.rel: ../../dev/net/%.c - $(CROSS_CC) $(CROSS_CCOPTS) -c $< - -$(AOBJS): %.rel: %.s - $(CROSS_AS) $(ASOPTS) $< - -clean: - rm -f $(OBJS) *.lst *.asm *.sym *.rst *.rel core *~ - rm -f loader.tmp loader.ihx loader.lst loader.bin padding.bin disk.raw - rm -rf fuzix.dsk - -image: - # Copy snapshot file template, transfer fuzix code to 0x100 and set execution at 0x100 - cp $(FUZIX_ROOT)/Standalone/filesystem-src/6128.sna $(IMAGES)/ - createSnapshot $(IMAGES)/6128.sna --loadFileData ../../fuzix.bin 256 - printf '\x01' | dd of=$(IMAGES)/6128.sna bs=1 seek=24 conv=notrunc - sdasz80 -l -o loader.s - sdldz80 -i loader.rel - hex2bin loader.ihx - - dd if=/dev/zero of=padding.bin bs=512 count=360 - # Make a disk image to work from - dd if=loader.bin of=padding.bin seek=0 bs=512 conv=notrunc - dd if=../../fuzix.bin of=padding.bin bs=512 seek=1 conv=notrunc - cat padding.bin >disk.raw - # And generate a 40 track cpc system disk from it - ../../tools/raw2dskcpc disk.raw fuzix.dsk 40 1 64 - cp fuzix.dsk $(IMAGES)/fuzix.dsk - -IMAGES = $(FUZIX_ROOT)/Images/$(TARGET) - -diskimage: - # Make a blank disk image with partition - dd if=$(FUZIX_ROOT)/Standalone/filesystem-src/parttab.64M of=$(IMAGES)/disk.img bs=64M conv=sync - # Add the file system - dd if=$(IMAGES)/filesys.img of=$(IMAGES)/disk.img bs=512 seek=2048 conv=notrunc - dd if=$(IMAGES)/filesys8.img of=$(IMAGES)/disk.img bs=512 seek=67584 conv=notrunc - # Make an emulator image of it - cat $(FUZIX_ROOT)/Standalone/filesystem-src/hdfheader $(IMAGES)/disk.img > $(IMAGES)/emu-ide.hdf - (cd $(FUZIX_ROOT)/Standalone/filesystem-src; ./build-mini-filesystem $(ENDIANFLAG) $(FUZIX_ROOT)/Images/$(TARGET)/root.raw 64 1440) - ../../tools/raw2dskcpc $(FUZIX_ROOT)/Images/$(TARGET)/root.raw $(FUZIX_ROOT)/Images/$(TARGET)/root.dsk 80 2 0 - \ No newline at end of file diff --git a/Kernel/platform/platform-cpc6128-SME/Notes.md b/Kernel/platform/platform-cpc6128-SME/Notes.md deleted file mode 100644 index 95377e2735..0000000000 --- a/Kernel/platform/platform-cpc6128-SME/Notes.md +++ /dev/null @@ -1,22 +0,0 @@ -# Amstrad CPC6128 - - -## Mmeory Model - -This port is based on the zx+3 port, taking advantage of Alan Cox's suggestion to take advantage of the fact that the memory maps C1, C2 and C3 correspond to the maps used in the zx+3 port. - -In the zx+3: -| User | 0 / 1 / 2 | Common 3 -| Kernel | 4 / 5 / 6 | Common 3 -| Video | 4 / 7 / 6 | Common 3 - -In the CPC6128: -| User | 4 / 5 / 6 | Common 7 (map C2) -| Kernel | 0 / 1 / 2 | Common 7 (map C1) -| Video | 0 / 3 / 2 | Common 7 (map c3) - -## TODO - -Lots of bugs. -Trying to mount the flopy hangs the machine, and may do nasty things to the floppy and the drive, don't try on a real machine!! -Fix memory size reporting 64 v 48K. \ No newline at end of file diff --git a/Kernel/platform/platform-cpc6128-SME/README b/Kernel/platform/platform-cpc6128-SME/README deleted file mode 100644 index fd31fdd0f5..0000000000 --- a/Kernel/platform/platform-cpc6128-SME/README +++ /dev/null @@ -1,68 +0,0 @@ -# Amstrad CPC6128 - - -## Mmeory Model - -The CPC6128 supported memory maps: - - -MAP- C0 C1 C2 C3 C4 C5 C6 C7 - 0000-3FFF RAM_0 RAM_0 RAM_4 RAM_0 RAM_0 RAM_0 RAM_0 RAM_0 - 4000-7FFF RAM_1 RAM_1 RAM_5 RAM_3 RAM_4 RAM_5 RAM_6 RAM_7 - 8000-BFFF RAM_2 RAM_2 RAM_6 RAM_2 RAM_2 RAM_2 RAM_2 RAM_2 - C000-FFFF RAM_3 RAM_7 RAM_7 RAM_7 RAM_3 RAM_3 RAM_3 RAM_3 - -This port is based on the zx+3 port, following Alan Cox's suggestion to take advantage of the fact that memory maps C1, C2 and C3 correspond to the maps used in the zx+3 port. - -In the zx+3: -| User | 0 / 1 / 2 | Common 3 -| Kernel | 4 / 5 / 6 | Common 3 -| Video | 4 / 7 / 6 | Common 3 - -In the CPC6128: -| User | 4 / 5 / 6 | Common 7 (map C2) -| Kernel | 0 / 1 / 2 | Common 7 (map C1) -| Video | 0 / 3 / 2 | Common 7 (map C3) - - - -## STATUS - -Video mode 2 is used. The video driver configures the CRTC in 64x32 characters to do easy hardware scroll and use the whole video memory bank. - -The floppy driver seems to work. /dev/fd0 is drive A and /dev/fd1 is drive B. fd0 is hard coded to one side and fd1 to double side. A minimal system root disk image is generated to boot from fd1. Format is 9 sectors per track with sector ID from 1 to 9. - -The IDE driver that is supposed to work with the symbiface and xmass fails to initialize. FIXED, tested with ACE-DL emulator x-mass suport. - -The USB mass storage of the Albiero works using the ch375 driver used in other platforms. It should be easy to get it working with the Usifac/Ulifac. - -There isn't a proper loader, for now a snapshot is generated. FIXED, dsk floppy boot image generated. - -To test it burn disk.img on a spare usb pendrive and put it on the albireo. Load an run the snapshot or burn the dsk in a floppy and start FUZIX with |cpm. - - -## TODO - -Fix fdc driver. DONE -Fix IDE driver. DONE -Sometimes the top byte of the characters isn't drawn. FIXED -Vertical scroll shows the bottom line of the screen in the top of the screen. FIXED -Fix memory size reporting 64 v 48K (inherited from zx+3). -do_beep() doesn't seem to work. FIXED -Write a proper loader. DONE. -Configurable screen, at least add 80x25, maybe also change the video mode and routines to manage 6x8 fonts. -Support more hardware: M4 Board (storage, network and RTC), Ulifac/Usifac, networking with wifi module plugged in the usifac, sdcard in the Albireo, try slip with the serial port of the usifac... - -Fix lots of bugs. - -Switch to a thunked memory model based on C2 Map to use the standard and extended RAM expansions up to 4MiB, the Cromemco port could be a model to this solution. As ther is no real common as we are switching the whole 64k space, the common data area has to be updated in all the used banks, but this can give aprox. 60K for kernel and user and hold a lot of processes in memory with a big RAM expansion. If this proves to be too hard, a RAM disk for swapping can be a way to use the RAM expansions. - -Look for speed optimization opportunities. - -## BUILD & RUN - -make diskimage with cpc6128 target in base Makefile -.sna snapshot, .dsk Floppy image, and mass storage filesystem images are generated in Images folder. Tu boot from floppy use |cpm command from basic prompt - -To run on emulator use ACE-DL emulator and use disk.img as image for the x-mass IDE interface emulation. - - diff --git a/Kernel/platform/platform-cpc6128-SME/commonmem.s b/Kernel/platform/platform-cpc6128-SME/commonmem.s deleted file mode 100644 index 595cb1a72c..0000000000 --- a/Kernel/platform/platform-cpc6128-SME/commonmem.s +++ /dev/null @@ -1,9 +0,0 @@ -; -; Multiple app sizes and the fact the kernel and apps share the same banks -; means we need to put this somewhere low -; - .module commonmem - .area _COMMONMEM - - .include "../../cpu-z80/std-commonmem.s" - \ No newline at end of file diff --git a/Kernel/platform/platform-cpc6128-SME/config.h b/Kernel/platform/platform-cpc6128-SME/config.h deleted file mode 100644 index 9ac4c33a2e..0000000000 --- a/Kernel/platform/platform-cpc6128-SME/config.h +++ /dev/null @@ -1,104 +0,0 @@ -#define CONFIG_LARGE_IO_DIRECT(x) 1 /* We support direct to user I/O */ - -#define CONFIG_FDC765 -/* 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) */ -#define CONFIG_PROFIL -/* Multiple processes in memory at once */ -#define CONFIG_MULTI -/* CP/M emulation */ -#undef CONFIG_CPM_EMU - -/* Input layer support */ -#define CONFIG_INPUT -#define CONFIG_INPUT_GRABMAX 3 -/* Video terminal, not a serial tty */ -#define CONFIG_VT -/* Keyboard contains non-ascii symbols */ -#define CONFIG_UNIKEY - -/* Swap based one process in RAM */ -#define CONFIG_SWAP_ONLY -#define CONFIG_PARENT_FIRST -#define CONFIG_SPLIT_UDATA -#define UDATA_BLKS 1 -#define UDATA_SIZE 0x200 -#define CONFIG_DYNAMIC_BUFPOOL -#undef CONFIG_DYNAMIC_SWAP -#define MAXTICKS 60 /* Has to be high because we are swap only */ - -#undef CONFIG_KMOD - -#undef CONFIG_NET -#undef CONFIG_NET_NATIVE -#undef CONFIG_NET_WIZNET -#undef CONFIG_NET_W5100 - -/* Custom banking */ - -/* Banks as reported to user space */ -#define CONFIG_BANKS 1 - -/* Vt definitions */ -#define VT_WIDTH 64 -#define VT_HEIGHT 32 -#define VT_RIGHT 63 -#define VT_BOTTOM 31 - -#define TICKSPERSEC 300 /* Ticks per second */ -#define PROGBASE 0x0000 /* also data base */ -#define PROGLOAD 0x0100 /* also data base */ -#define PROGTOP 0xC000 /* Top of program, below C000 for simplicity - to get going */ - -#define BOOT_TTY (513) /* Set this to default device for stdio, stderr */ - /* In this case, the default is the first TTY device */ - -/* We need a tidier way to do this from the loader */ -#define CMDLINE NULL /* Location of root dev name */ - -/* Device parameters */ -#define NUM_DEV_TTY 1 - -#define TTYDEV BOOT_TTY /* Device used by kernel for messages, panics */ -#define NBUFS 5 /* Number of block buffers */ -#define NMOUNTS 4 /* Number of mounts at a time */ - -#define SWAPBASE 0x0000 -#define SWAPTOP 0xC000UL -#define SWAP_SIZE 0x61 /* 48K + udata */ -#define EXTENDED_RAM_1024 -#ifdef EXTENDED_RAM_1024 - #define MAX_SWAPS 19 /*See platform devrd.c*/ - #define PTABSIZE 19 - #define TOTAL_SWAP_BLOCKS (1088-128) * 2 -#endif -#ifdef EXTENDED_RAM_512 - #define MAX_SWAPS 9 /*See platform devrd.c*/ - #define PTABSIZE 9 - #define TOTAL_SWAP_BLOCKS (576-128) * 2 -#endif -#define SWAPDEV 0x800 /* Device for swapping - RAM disk on standard memory expansion. */ - -/* We swap by hitting the user map */ -#define swap_map(x) ((uint8_t *)(x)) - -#define CONFIG_TD -#define CONFIG_TD_NUM 2 -/* IDE/CF support */ -#define CONFIG_TD_IDE -#define CONFIG_TINYIDE_SDCCPIO -#define CONFIG_TINYIDE_8BIT -#define IDE_IS_8BIT(x) 1 - -#define BOOTDEVICENAMES "hd#,fd" - -#define CONFIG_SMALL - - - - - diff --git a/Kernel/platform/platform-cpc6128-SME/cpc6128.s b/Kernel/platform/platform-cpc6128-SME/cpc6128.s deleted file mode 100644 index 8b52c16f02..0000000000 --- a/Kernel/platform/platform-cpc6128-SME/cpc6128.s +++ /dev/null @@ -1,373 +0,0 @@ -; -; Amstrad CPC6128 support - - .module cpc6128 - - ; exported symbols - .globl init_early - .globl init_hardware - .globl _program_vectors - .globl plt_interrupt_all - .globl interrupt_handler - .globl unix_syscall_entry - .globl null_handler - .globl nmi_handler - - .globl map_kernel - .globl map_proc_always - .globl map_proc - .globl map_kernel_di - .globl map_proc_always_di - .globl map_save_kernel - .globl map_restore - .globl map_kernel_restore - .globl map_for_swap - .globl map_video - .globl current_map - - - .globl _need_resched - .globl _int_disabled - .globl _vtborder - .globl diskmotor - - ; exported debugging tools - .globl _plt_monitor - .globl _plt_reboot - .globl outchar - - ; imported symbols - .globl _ramsize - .globl _procmem - - .globl _vtoutput - .globl _vtinit - - .globl _do_beep - - .globl outcharhex - .globl outhl, outde, outbc - .globl outnewline - .globl outstring - .globl outstringhex - - .globl ___sdcc_enter_ix - - .include "kernel.def" - .include "../../cpu-z80/kernel-z80.def" - -; ----------------------------------------------------------------------------- -; COMMON MEMORY BANK (above 0xF000) -; ----------------------------------------------------------------------------- - .area _COMMONMEM - -_plt_monitor: - ; - ; Not so much a monitor as wait for space - ; Part of this code is borrowed from https://github.com/lronaldo/cpctelera - - ld bc,#0x7fc2 - out (c),c ; keep us mapped - ld bc, #0xF782 ;; [3] Configure PPI 8255: Set Both Port A and Port C as Output. - out (c), c ;; [4] 82 = 1000 0010 : (B7=1)=> I/O Mode, (B6-5=00)=> Mode 1, - ;; (B4=0)=> Port A=Output, (B3=0)=> Port Cu=Output, - ;; (B2=0)=> Group B, Mode 0,(B1=1)=> Port B=Input, (B0=0)=> Port Cl=Output - ld bc, #0xF40E ;; [3] Write (0Eh = 14) on PPI 8255 Port A (F4h): the register we want to select on AY-3-8912 - ld e, b ;; [1] Save F4h into E to use it later in the loop - out (c), c ;; [4] - - ld bc, #0xF6C0 ;; [3] Write (C0h = 11 000000b) on PPI Port C (F6h): operation > select register - ld d, b ;; [1] Save F6h into D to use it later in the loop - out (c), c ;; [4] - .dw #0x71ED ; out (c), 0 ;; [4] out (C), 0 => Write 0 on PPI's Port C to put PSG's in inactive mode - ;; .... (required in between different operations) - ld bc, #0xF792 ;; [3] Configure PPI 8255: Set Port A = Input, Port C = Output. - out (c), c ;; [4] 92h= 1001 0010 : (B7=1)=> I/O Mode, (B6-5=00)=> Mode 1, - ;; (B4=1)=> Port A=Input, (B3=0)=> Port Cu=Output, - ;; (B2=0)=> Group B, Mode 0, (B1=1)=> Port B=Input, (B0=0)=> Port Cl=Output - ld a, #0x45 ;; SPACE - ld b, d ;; [1] B = F6h => Write the value of A to PPI's Port C to select next Matrix Line - out (c), a ;; [4] - ld b, e ;; [1] B = F4h => Read from PPI's Port A: Pressed/Not Pressed Values from PSG - in a,(c) - rla - jr c, _plt_monitor - -_plt_reboot: - di - ;halt ;we are debugging why we end here - ld bc, #0x7f89 ;this would set the firmware ready for boot into firmware with (out (c),c ; rst0) - out (c), c - rst 0 ; back into our booter - -plt_interrupt_all: - ret - - .area _COMMONMEM - -_int_disabled: - .db 1 - -_vtborder: ; needs to be common - .db 0 - - -; ----------------------------------------------------------------------------- -; KERNEL CODE BANK (below 0xC000) -; ----------------------------------------------------------------------------- - .area _CODE - -init_early: - - call _program_early_vectors - ret - -init_hardware: - ; set system RAM size - ld hl, #128 - ld (_ramsize), hl - ld hl, #64 ; 64K for kernel/screen/etc (FIXME) - ld (_procmem), hl - - ; Install rst shorteners - ld hl,#rstblock - ld de,#8 - ld bc,#32 - ldir - - ld bc,#0x7fc3 - ; bank 7 (common) in high in either mapping - ; video bank 3 at &4000 - out (c),c - ; and we should have special mapping - ; already by now - ld bc,#0x7f10 - out (c),c - ld a,#0x54 ; - ld (_vtborder), a - out (c),a ; black border - ld bc,#0x7f00 - out (c),c - ld a,#0x44 - out (c),a ; blue paper - ld bc,#0x7f01 - out (c),c - ld a,#0x4b - out (c),a ; white ink - - - ;we set the crtc for a screen with 64x32 colsxrows - ;pros: max number of characters on screen and easy hardware scroll - ;cons: 80x25 is more standard => TODO list (with mode change) - ld bc,#0xbc01 - out (c),c - ld bc,#0xbd20 - out (c),c - ld bc,#0xbc02 - out (c),c - ld bc,#0xbd2A - out (c),c - ld bc,#0xbc06 - out (c),c - ld bc,#0xbd20 - out (c),c - ld bc,#0xbc07 - out (c),c - ld bc,#0xbd22 - out (c),c - - call _do_beep - - ; screen initialization - call _vtinit - - ret - -;------------------------------------------------------------------------------ -; COMMON MEMORY PROCEDURES FOLLOW - - .area _COMMONMEM - -_program_early_vectors: - call map_proc_always - call set_vectors - call map_kernel -set_vectors: - ; write zeroes across all vectors - ld hl, #0 - ld de, #1 - ld bc, #0x007f ; program first 0x80 bytes only - ld (hl), #0x00 - ldir - - ; now install the interrupt vector at 0x0038 - ld a, #0xC3 ; JP instruction - ld (0x0038), a - ld hl, #interrupt_handler - ld (0x0039), hl - - ; set restart vector for FUZIX system calls - ld (0x0030), a ; (rst 30h is unix function call vector) - ld hl, #unix_syscall_entry - ld (0x0031), hl - - ld (0x0000), a - ld hl, #null_handler ; to Our Trap Handler - ld (0x0001), hl - - ld (0x0066), a ; Set vector for NMI - ld hl, #nmi_handler - ld (0x0067), hl - -_program_vectors: - ret - - ; Swap helper. Map the page in A into the address space such - ; that swap_map() gave the correct pointer to use. Undone by - ; a map_kernel_{restore} -map_proc: - ld a, h - or l - jr z, map_kernel -map_for_swap: -map_proc_always: -map_proc_always_di: - push af - ld a,#0xc2 ; 4 5 6 7 - jr map_a_pop -; -; Save and switch to kernel -; -map_save_kernel: - push af - ld a, (current_map) - ld (map_store), a - pop af -map_kernel_di: -map_kernel: -map_kernel_restore: - push af - ld a,#0xc1 ; 0 1 2 7 -map_a_pop: - push bc - ld (current_map),a - ld bc,#0x7f00 - out (c),a - pop bc - pop af - ret - -map_video: - push af - ld a,#0xc3 ; 0 3 2 7 - jr map_a_pop - -map_restore: - push af - ld a, (map_store) - jr map_a_pop - -; -; We have no easy serial debug output instead just breakpoint this -; address when debugging. -; -outchar: - ld (_tmpout), a - push bc - push de - push hl - push ix - ld hl, #1 - push hl - ld hl, #_tmpout - push hl - call _vtoutput - pop af - pop af - pop ix - pop hl - pop de - pop bc - ret - - .area _COMMONMEM -_tmpout: - .db 1 - -current_map: ; place to store current page number. Is needed - .db 0 ; because we have no ability to read 0xF4 port - ; to detect what page is mapped currently -map_store: - .db 0 - -_need_resched: - .db 0 - -diskmotor: - .db 0 - -; -; Stub helpers for code compactness. Note that -; sdcc_enter_ix is in the standard compiler support already -; - .area _DISCARD - -; -; The first two use an rst as a jump. In the reload sp case we don't -; have to care. In the pop ix case for the function end we need to -; drop the spare frame first, but we know that af contents don't -; matter -; - -rstblock: - jp ___sdcc_enter_ix - .ds 5 -___spixret: - ld sp,ix - pop ix - ret - .ds 3 -___ixret: - pop af - pop ix - ret - .ds 4 -___ldhlhl: - ld a,(hl) - inc hl - ld h,(hl) - ld l,a - ret - -; -; Helpers for the CH375 -; - .area _CODE - - .globl _nap20 - -_nap20: ;modified, in the cpc 1 nop = 1us. the call-ret add some us', it can be optimized (FIXME) - - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - - ret - diff --git a/Kernel/platform/platform-cpc6128-SME/cpcvideo.s b/Kernel/platform/platform-cpc6128-SME/cpcvideo.s deleted file mode 100644 index 21e2af9b93..0000000000 --- a/Kernel/platform/platform-cpc6128-SME/cpcvideo.s +++ /dev/null @@ -1,44 +0,0 @@ -; -; cpc vt primitives -; - - .module cpcvideo - - ; exported symbols - .globl _plot_char - .globl _scroll_down - .globl _scroll_up - .globl _cursor_on - .globl _cursor_off - .globl _cursor_disable - .globl _clear_lines - .globl _clear_across - .globl _do_beep - .globl _fontdata_8x8 - .globl _curattr - .globl _vtattr - - .globl map_video - .globl map_kernel - - ; Build the video library as the only driver - -CPCVID_ONLY .equ 1 -SCREENBASE .equ 0x40 - -.macro VIDEO_MAP - call map_video -.endm - -.macro VIDEO_UNMAP - call map_kernel -.endm - - .globl _fontdata_8x8 - -;_fontdata_8x8 .equ 0xF000 ; routines except this - ; to point to space char - .area _COMMONMEM - - .include "../../dev/cpc/video.s" - diff --git a/Kernel/platform/platform-cpc6128-SME/crt0.s b/Kernel/platform/platform-cpc6128-SME/crt0.s deleted file mode 100644 index 042e521703..0000000000 --- a/Kernel/platform/platform-cpc6128-SME/crt0.s +++ /dev/null @@ -1,211 +0,0 @@ - .module crt0 - - ; - ; High space - read only - ; - - .area _CODE - .area _CODE2 - ; - ; Try and keep code in the top 32K - ; - - - ; - ; Our common lives low - ; - .area _CODE3 - .area _VIDEO ; must end below 0x4000 - .area _FONT - .area _INITIALIZED - .area _HOME - .area _CONST - - ; - ; Beyond this point we just zero. - ; - - .area _DATA - .area _BSEG - .area _BSS - .area _HEAP - .area _GSINIT - .area _GSFINAL - - ; - ; Finally the buffers so they can expand - ; - .area _BUFFERS - ; Somewhere to throw it out of the way - .area _INITIALIZER - - .area _DISCARD - - - .area _COMMONMEM - - - - ; imported symbols - .globl _fuzix_main - .globl init_early - .globl init_hardware - .globl l__BUFFERS - .globl s__BUFFERS - .globl l__COMMONMEM - .globl s__COMMONMEM - .globl l__DATA - .globl s__DATA - .globl l__DISCARD - .globl s__DISCARD - .globl l__FONT - .globl s__FONT - .globl kstack_top - - .globl unix_syscall_entry - .globl nmi_handler - .globl interrupt_handler - - .include "kernel.def" - .include "../../cpu-z80/kernel-z80.def" - - ; - ; startup code - ; - ; We loaded the rest of the kernel from disk and jumped here - ; - - .area _CODE - - .globl _start - - - -_start: - - - di - ld sp, #kstack_top - ; - ; move the common memory where it belongs - ld hl, #s__DATA - ld de, #s__COMMONMEM - ld bc, #l__COMMONMEM - ldir - - ; then the font -; ld de, #s__FONT -; ld bc, #l__FONT -; ldir - - ; then the discard (backwards as will overlap) - ld de, #s__DISCARD - ld bc, #l__DISCARD-1 - ex de,hl - add hl,bc - ex de,hl - add hl,bc - lddr - ldd - - ; then zero the data area - ld hl, #s__DATA - ld de, #s__DATA + 1 - ld bc, #l__DATA - 1 - ld (hl), #0 - ldir - ; and buffers - ld hl, #s__BUFFERS - ld de, #s__BUFFERS + 1 - ld bc, #l__BUFFERS - 1 - ld (hl), #0 - ldir - - ;We are loading from a .sna with first 64k filled with fuzix.bin starting at 0x100 - ;copy bank 3 to bank 7 in C7 mode (7 at 0x4000), zero bank 3 (vmem) and switch to C1 (kernel map) - ;when a proper loader is done this should be managed there - - ld bc,#0x7fc7 - out (c),c - - ld hl, #0xc000 - ld de, #0x4000 - ld bc, #0x4000 - ldir - - ld bc,#0x7f00 - out (c),c - ld a,#0x44 - out (c),a ; blue paper - ld bc,#0x7f01 - out (c),c - ld a,#0x4b - out (c),a ; white ink - - ld hl, #0xc000 - ld de, #0xc001 - ld bc, #0x3fff - ld (hl), #0 - ldir - - ld bc,#0x7fc1 - out (c),c - - ld hl,#copyfont - ld de,#0xF000 - ld bc,#(copyfont_end-copyfont) - ldir - - call #0xF000 - - ld hl,#0xF000 - ld de,#0xF001 - ld bc,#(copyfont_end-copyfont-1) - ld (hl),#0 - ldir - - ; Configure memory map - call init_early - - ; Hardware setup - call init_hardware - - ; Call the C main routine - call _fuzix_main - - ; main shouldn't return, but if it does... - di -stop: halt - jr stop - - ;code to copy font -copyfont: ;;this wil be in the loader - di - ld bc, #0x7faa ;RMR ->UROM disable LROM enable - out (c),c - ld hl, #0x3800 ;Firmware (LROM) character bitmaps - ld de, #(_fontdata_8x8) - ld bc, #0x800 - ldir - ld bc, #0x7fae ;RMR ->UROM disable LROM disable - out (c),c - ret -copyfont_end: - - - .area _BUFFERS -; -; Buffers (we use asm to set this up as we need them in a special segment -; so we can recover the discard memory into the buffer pool -; - - .globl _bufpool - .area _BUFFERS - -_bufpool: - .ds BUFSIZE * NBUFS - - .globl _fontdata_8x8 - .area _FONT - _fontdata_8x8: - .ds 2048 diff --git a/Kernel/platform/platform-cpc6128-SME/devices.c b/Kernel/platform/platform-cpc6128-SME/devices.c deleted file mode 100644 index 7dd80d5cb4..0000000000 --- a/Kernel/platform/platform-cpc6128-SME/devices.c +++ /dev/null @@ -1,63 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -/*#include */ -#include -#include -/*#include */ -#include - -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 */ - { devfd_open, no_close, devfd_read, devfd_write, no_ioctl }, - /* 2: /dev/tty TTY devices */ - { tty_open, tty_close, tty_read, tty_write, cpcvt_ioctl }, - /* 3: /dev/lpr Printer devices */ - { no_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 }, - /* 5: Pack to 7 with nxio if adding private devices and start at 8 */ - /* 5: unused */ - { no_open, no_close, no_rdwr, no_rdwr, no_ioctl }, - /* 6: unused */ - { no_open, no_close, no_rdwr, no_rdwr, no_ioctl }, - /* 7: unused */ - { no_open, no_close, no_rdwr, no_rdwr, no_ioctl }, - /* 8: Standard memory expansions RAM swap */ - { rd_open, no_close, rd_read, rd_write, no_ioctl }, -}; - - -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; -} - -void device_init(void) -{ -#ifdef CONFIG_TD_IDE - ide_probe(); -#endif -#ifdef CONFIG_TD_SD - sd_probe(); -#endif -ch375_probe(); - -#ifdef CONFIG_NET - sock_init(); -#endif -} - diff --git a/Kernel/platform/platform-cpc6128-SME/devrd.c b/Kernel/platform/platform-cpc6128-SME/devrd.c deleted file mode 100644 index 29c3a6e79e..0000000000 --- a/Kernel/platform/platform-cpc6128-SME/devrd.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - * CPC standard RAM bank memory expansions ramdisc driver, based on platform zxdiv48. - */ - -#include -#include -#include -#include - -static int rd_transfer(uint8_t is_read, uint8_t rawflag) -{ - nblock = udata.u_nblock; - block = udata.u_block; - rd_dptr = udata.u_dptr; - rd_wr = is_read; - uint16_t swap_bank_long; - uint8_t ct = 0; - - #ifdef DEBUG - kprintf("u_dptr %p Block %u u_nblock %u rd_wr %u\n",udata.u_dptr, udata.u_block, udata.u_nblock, rd_wr); - #endif - - /* It's a disk but only for swapping (and rd_io isn't general purpose) */ - if (((block + nblock) > (TOTAL_SWAP_BLOCKS - 1)) || (rawflag == 1)) { - udata.u_error = EIO; - kprintf("dev_rd_EIO"); - return -1; - } - - /* udata could change under us so keep variables privately */ - while (ct < nblock) { - swap_bank_long = (block >> 5); - swap_bank_long = swap_bank_long + 196 + (((swap_bank_long + 8) / 4) * 4); /*Convert bank number to Register MMR value - *See https://www.cpcwiki.eu/index.php/Gate_Array#Register_MMR_.28RAM_memory_mapping.29*/ - if (swap_bank_long > 255){ - rd_swap_bank = swap_bank_long - 64; - rd_swap_mem_port_h = 0x7e; - } - else{ - rd_swap_bank = swap_bank_long; - rd_swap_mem_port_h = 0x7f; - } - rd_proc_bank = ((uint16_t)rd_dptr / 0x4000) + 0xc4; - rd_swap_bank_addr = ((block & 31) << BLKSHIFT) + 0x4000; - rd_proc_bank_addr = ((uint16_t)rd_dptr & 0x3fff) + 0x4000; - - #ifdef DEBUG - if (nblock == 1) - kprintf("swap_bank %p swap_addr %p proc_bank %p proc_addr %p count %u\n", rd_swap_bank, rd_swap_bank_addr, rd_proc_bank, rd_proc_bank_addr, ct); - #endif - rd_io(); - block++; - rd_dptr += BLKSIZE; - ct++; - } - return ct << BLKSHIFT; /*Total bytes transferred*/ -} - -int rd_open(uint8_t minor, uint16_t flag) -{ - flag; - if(minor != 0) { - udata.u_error = ENODEV; - return -1; - } - return 0; -} - -int rd_read(uint8_t minor, uint8_t rawflag, uint8_t flag) -{ - flag;minor; - return rd_transfer(true, rawflag); -} - -int rd_write(uint8_t minor, uint8_t rawflag, uint8_t flag) -{ - flag;minor; - return rd_transfer(false, rawflag); -} - diff --git a/Kernel/platform/platform-cpc6128-SME/devrd.h b/Kernel/platform/platform-cpc6128-SME/devrd.h deleted file mode 100644 index e7c4451555..0000000000 --- a/Kernel/platform/platform-cpc6128-SME/devrd.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * - * CPC standard RAM bank memory expansions ramdisc driver - */ - -int rd_open(uint8_t minor, uint16_t flags); -int rd_read(uint8_t minor, uint8_t rawflag, uint8_t flag); -int rd_write(uint8_t minor, uint8_t rawflag, uint8_t flag); - -extern uint8_t rd_wr; -extern uint8_t rd_swap_bank; -extern uint8_t rd_swap_mem_port_h; -extern uint8_t rd_proc_bank; -extern uint8_t *rd_dptr; -extern uint16_t rd_swap_bank_addr; -extern uint16_t rd_proc_bank_addr; -extern uint16_t nblock; -extern blkno_t block; - -void rd_io(void); diff --git a/Kernel/platform/platform-cpc6128-SME/devtty.c b/Kernel/platform/platform-cpc6128-SME/devtty.c deleted file mode 100644 index 0f1733f313..0000000000 --- a/Kernel/platform/platform-cpc6128-SME/devtty.c +++ /dev/null @@ -1,132 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static char tbuf1[TTYSIZ]; - -uint8_t vtattr_cap = VTA_UNDERLINE; -extern uint8_t curattr; - -tcflag_t termios_mask[NUM_DEV_TTY + 1] = { - 0, - _CSYS -}; - - -struct s_queue ttyinq[NUM_DEV_TTY + 1] = { /* ttyinq[0] is never used */ - {NULL, NULL, NULL, 0, 0, 0}, - {tbuf1, tbuf1, tbuf1, TTYSIZ, 0, TTYSIZ / 2}, -}; - -/* tty1 is the screen */ - -/* Output for the system console (kprintf etc) */ -void kputchar(char c) -{ - if (c == '\n') - tty_putc(0, '\r'); - tty_putc(0, c); -} - -/* Both console and debug port are always ready */ -ttyready_t tty_writeready(uint8_t minor) -{ - minor; - return TTY_READY_NOW; -} - -void tty_putc(uint8_t minor, unsigned char c) -{ - minor; - vtoutput(&c, 1); -} - -int tty_carrier(uint8_t minor) -{ - minor; - return 1; -} - -void tty_setup(uint8_t minor, uint8_t flags) -{ - minor; -} - -void tty_sleeping(uint8_t minor) -{ - minor; -} - -void tty_data_consumed(uint8_t minor) -{ -} - - -/* This is used by the vt asm code, but needs to live in the kernel */ -uint16_t cursorpos; - -//Inherited from spectrum zx+3. For now ignore attributes, try later to implement inverse and underline touching char output directly -void vtattr_notify(void) -{ - // Attribute byte fixups: not hard as the colours map directly - // to the spectrum ones -/* if (vtattr & VTA_INVERSE) - curattr = ((vtink & 7) << 3) | (vtpaper & 7); - else - curattr = (vtink & 7) | ((vtpaper & 7) << 3); - - if (vtattr & VTA_FLASH) - curattr |= 0x80; - // How to map the bright bit - we go by either - if ((vtink | vtpaper) & 0x10) - curattr |= 0x40; -*/ - //we are now debugging other things - //vtink = 26; - //vtpaper = 1; - //cpcvt_ioctl(1, VTINK, &vtink); - //cpcvt_ioctl(1, VTPAPER, &vtpaper); - -} - - -__sfr __banked __at 0x7F00 gatearray; -/* see: https://www.cpcwiki.eu/index.php/Gate_Array */ - -int cpcvt_ioctl(uint8_t minor, uarg_t arg, char *ptr) -{ - uint8_t c; - if (minor == 1 && arg == VTBORDER) { - c = ugetc(ptr); - gatearray = PENR_BORDER_SELECT; - vtborder &= INKR_COLOR_SET; - vtborder |= c & 0x1F; - gatearray = vtborder; - return 0; - } - if (minor == 1 && arg == VTINK) { - c = ugetc(ptr); - gatearray = PENR_INK_SELECT; - vtink &= INKR_COLOR_SET; - vtink |= c & 0x1F; - gatearray = vtink; - return 0; - } - if (minor == 1 && arg == VTPAPER) { - c = ugetc(ptr); - gatearray = PENR_PAPER_SELECT; - vtpaper &= INKR_COLOR_SET; - vtpaper |= c & 0x1F; - gatearray = vtpaper; - return 0; - } - return vt_ioctl(minor, arg, ptr); -} diff --git a/Kernel/platform/platform-cpc6128-SME/devtty.h b/Kernel/platform/platform-cpc6128-SME/devtty.h deleted file mode 100644 index 57d7727ead..0000000000 --- a/Kernel/platform/platform-cpc6128-SME/devtty.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef __DEVTTY_DOT_H__ -#define __DEVTTY_DOT_H__ - -void tty_pollirq(void); -static void keydecode(void); - -#define KEY_ROWS 10 -#define KEY_COLS 8 -#define PENR_BORDER_SELECT 0x10 -/*For now We are in mode 2 with pen 0 for paper and pen 1 for ink*/ -#define PENR_PAPER_SELECT 0x00 -#define PENR_INK_SELECT 0x01 -#define INKR_COLOR_SET 0x40 -extern uint8_t keymap[10]; -extern uint8_t keyboard[10][8]; -extern uint8_t shiftkeyboard[10][8]; - -extern uint8_t timer_wait; - -extern int cpcvt_ioctl(uint8_t minor, uarg_t arg, char *ptr); - -extern uint8_t vtborder; - -#endif diff --git a/Kernel/platform/platform-cpc6128-SME/discard.c b/Kernel/platform/platform-cpc6128-SME/discard.c deleted file mode 100644 index 164fb2a423..0000000000 --- a/Kernel/platform/platform-cpc6128-SME/discard.c +++ /dev/null @@ -1,31 +0,0 @@ -#include -#include -#include -#include -#include -#include - -uint8_t plt_param(char *p) -{ - return 0; -} - -/* Nothing to do for the map of init */ -void map_init(void) -{ - uint_fast8_t i; - for (i = 0; i < MAX_SWAPS; i++) - swapmap_init(i); -} - -void plt_copyright(void) -{ - kprintf("Amstrad CPC6128 platform\nCopyright (c) 2024-2025 Antonio J. Casado Alias\n"); -} -/* -void ide_reset(void) -{ - ide_std_reset(); -} -*/ - diff --git a/Kernel/platform/platform-cpc6128-SME/fdc765.s b/Kernel/platform/platform-cpc6128-SME/fdc765.s deleted file mode 100644 index 76c0312ab3..0000000000 --- a/Kernel/platform/platform-cpc6128-SME/fdc765.s +++ /dev/null @@ -1,530 +0,0 @@ -; -; 765 Floppy Controller Support -; -; This is based upon the Amstrad NC200 driver by David Given and -; this example https://cpctech.cpcwiki.de/source/fdcload.html from Kevin Thacker site -; -; It differs on the CPC in the following ways -; -; - The timings are tighter so we use in a,(c) jp p and other -; tricks to make the clocks. Even so it should be in uncontended RAM -; -; - The CPC doesn't expose the tc line, so if the 765 decides to -; expect more data or feed us more data all we can do is dump it or -; feed it crap until it shuts up -; -; - We do motor and head loading delays (possibly some of those should -; be backported - FIXME) -; -; - We don't hang if the controller tells us no more data when we -; think we need to feed it command bytes (BACKPORT NEEDED) -; -; TODO -; Initialize drive step rate etc (we rely on the firmware for now) -; Step rate -; Head load/unload times -; Write off time af -; (12ms step 30ms head stabilize, 4ms head load, max (0xf) head -; unload) -; - .module fdc765 - - .include "kernel.def" - .include "../../cpu-z80/kernel-z80.def" - - .globl map_proc_always - .globl map_kernel - - .globl _fd765_do_nudge_tc - .globl _fd765_do_recalibrate - .globl _fd765_do_seek - .globl _fd765_do_read - .globl _fd765_do_write - .globl _fd765_do_read_id - .globl _fd765_motor_on - .globl _fd765_motor_off - - .globl _fd765_track - .globl _fd765_head - .globl _fd765_sector - .globl _fd765_status - .globl _fd765_buffer - .globl _fd765_is_user - .globl _fd765_sectors - .globl _fd765_drive - - .globl _vtborder - - .globl diskmotor - - .area _COMMONMEM - -; -; Twiddle the Terminal Count line to the FDC. Not supported by the -; CPC -; -_fd765_do_nudge_tc: - ret - -; Writes A to the FDC data register. - -fd765_tx: - push bc -; ex af, af' -; ld bc,#0xfb7e ; floppy register (16bit access) -;fd765_tx_loop: -; in a, (c) -; add a -; jr nc, fd765_tx_loop -; ; FIXME: backport this fix -; add a -; jr c, fd765_tx_exit ; controller doesn't want data ?? -; ex af, af' -; ld c,#0x7f -; out (c), a -; ex (sp),hl -; ex (sp),hl -;fd765_tx_exit: - ld bc,#0xfb7e ;; I/O address for FDC main status register - push af ;; - fwc1: in a,(c) ;; - add a,a ;; - jr nc,fwc1 ;; - add a,a ;; - jr nc,fwc2 ;; - pop af ;; - ret - - fwc2: - pop af ;; - - inc c ;; - out (c),a ;; write command byte - dec c ;; - - ;; some FDC documents say there must be a delay between each - ;; command byte, but in practice it seems this isn't needed on CPC. - ;; Here for compatiblity. - ld a,#5 ;; - fwc3: dec a ;; - jr nz,fwc3 ;; - pop bc - ; FIXME: is our delay quite long enough for spec ? - ; might need them to be ex (sp),ix ? - ret - -; Reads bytes from the FDC data register until the FDC tells us to stop (by -; lowering DIO in the status register). - -fd765_read_status: - ld hl, #_fd765_status -; ld c, #0x7e ; we flip between 2ffd 3ffd as we go -;read_status_loop: -; ld b,#0xfb ; control port -; in a, (c) -; rla ; RQM... -; jr nc, read_status_loop ; ...low, keep waiting -; rla ; DIO... -; ret nc ; ...low, no more data -; ld c,#0x7f ; data port -; in a,(c) ; INI ? FIXME -; ld (hl),a -; inc hl -; ex (sp),hl ; wait for the 765A -; ex (sp),hl -; ex (sp),hl -; ex (sp),hl -; jr read_status_loop ; next byte - ld bc,#0xfb7e - fr1: - in a,(c) - cp #0xc0 - jr c,fr1 - - inc c - in a,(c) - dec c - ld (hl),a - inc hl - - ld a,#5 - fr2: - dec a - jr nz,fr2 - in a,(c) - and #0x10 - jr nz,fr1 - - - ret -_fd765_status: - .ds 8 ; 8 bytes of status data - -; Sends the head/drive byte of a command. - -send_head: - ld hl, (_fd765_head) ; l = head h = drive) - ld a, l - add a - add a - add h - jr fd765_tx - -; Performs a RECALIBRATE command. - -_fd765_do_recalibrate: - ld a, #0x07 ; RECALIBRATE - call fd765_tx - ld a, (_fd765_drive) ; drive # - call fd765_tx - jr wait_for_seek_ending - -; Performs a SEEK command. - -_fd765_do_seek: - ld a, #0x0f ; SEEK - call fd765_tx - call send_head ; specified head, drive #0 - ld a, (_fd765_track) ; specified track - call fd765_tx - jr wait_for_seek_ending -_fd765_track: - .db 0 -_fd765_sector: - .db 0 -; -; These two must remain adjacent see send_head -; -_fd765_head: - .db 0 -_fd765_drive: - .db 0 - -; Waits for a SEEK or RECALIBRATE command to finish by polling SENSE INTERRUPT STATUS. -wait_for_seek_ending: - - ld a, #0x08 ; SENSE INTERRUPT STATUS - call fd765_tx - call fd765_read_status - - ld a, (#_fd765_status) - bit 5, a ; SE, seek end - jr z, wait_for_seek_ending - - bit 4,a - - ret - - ; Now settle the head (FIXME: what is the right value ?) - ld a, #30 ; 30ms -; -; This assumes uncontended timing -; -wait_ms: - push bc -wait_ms_loop: - ld b,#0xDC -wait_ms_loop2: - dec b - jr nz, wait_ms_loop2 - dec a - jr nz, wait_ms_loop - pop bc - ret - -_fd765_motor_off: - push bc - ld bc,#0xfa7e - xor a - ld (diskmotor),a - out (c),a - pop bc - ret - -_fd765_motor_on: - ld a,(diskmotor) - or a - ret nz - ld a,#0x01 - ld (diskmotor),a - ; Take effect - ld bc,#0xfa7e - out (c),a - ; Now wait for spin up - - ld e,#10 ; FIXME right value ?? -wait2: - ; The classic Z80 KHz timing loop - ld bc,#3548 ; 3.548MHz for spectrum, should change for cpc.FIXME -wait1: - dec bc - ld a,b - or c - jr nz, wait1 - dec e - jr nz, wait2 - ret -; -; Reads a 512-byte sector, after having previously saught to the right track. -; -; We need to be doubly careful here as the 765A has a 'feature' whereby it -; won't report an overrun on the last byte so we must always make timing -; -_fd765_do_read: - ld a, #0x46 ; READ SECTOR MFM - - ; FIXME: need to return a last cmd byte here and write it - ; after this crap or we may miss if we write just the sector hits - ; the head (BACKPORT ME ??) - call setup_read_or_write - - ld a, (_fd765_is_user) - or a - push af - call nz, map_proc_always - - ld bc,#0x7f10 - out (c),c - ld c,#0x46 ;Cyan - out (c),c - - di ; performance critical, - ; run with interrupts off - xor a - call fd765_tx ; send the final unused byte - ; to fire off the command - ld hl, (_fd765_buffer) - ld bc, #0xfb7e - -fdc_data_read: - in a,(c) ;; FDC has data and the direction is from FDC to CPU - jp p,fdc_data_read ;; - and #0x20 ;; "Execution phase" i.e. indicates reading of sector data - jp z,fdc_read_end - - inc c ;; BC = I/O address for FDC data register - in a,(c) ;; read from FDC data register - ld (hl),a ;; write to memory - dec c ;; BC = I/O address for FDC main status register - inc hl ;; increment memory pointer - jp fdc_data_read - -fdc_read_end: - -; ld de, #0x2000 ; so we can make timing -; jp read_wait -; -; First 256 bytes - -;read_loop: -; inc c ; data port -; ini -; inc b -; dec c ; control port -; dec e -; jp z, read_wait2 -;read_wait: -; in a,(c) ; read the fdc status -; jp p, read_wait -; and d -; jp nz, read_loop -; jp read_finished -; -; Second 256 bytes -; -;read_loop2: -; inc c ; data port -; ini -; inc b -; dec c ; control port -; dec e -; jp z, read_flush_wait -;read_wait2: -; in a,(c) ; read the fdc status -; jp p, read_wait2 -; and d -; jp nz, read_loop2 -; jp read_finished -; -; Flush out any extra data (no tc control) -; -;read_flush: -; inc c -; in a,(c) -; dec c -;read_flush_wait: -; in a,(c) -; jp p, read_flush_wait -; and d -; jp nz, read_flush -; -; And done -; -read_finished: - ld (_fd765_buffer), hl - call _fd765_do_nudge_tc ; Tell FDC we've finished - ei - - call fd765_read_status - call tc_fix - - ld bc,#0x7f10 - out (c),c - ld a,(_vtborder) - out (c),a - - pop af - ret z - jp map_kernel - -; -; We will get an error reported that the command did not complete -; because the tc bit is not controllable. Spot that specific error -; and ignore it. -; -tc_fix: - ld hl,#_fd765_status - ld a,(hl) - and #0xC0 - cp #0x40 - ret nz - inc hl - bit 7,(hl) - ret z - res 7,(hl) - dec hl - res 6,(hl) - ret - -; -; Write is much like read just the other direction -; -_fd765_do_write: - ; interrupts off - ld a, #0x45 ; WRITE SECTOR MFM - call setup_read_or_write - - ld a, (_fd765_is_user) - or a - push af - call nz, map_proc_always - - ld bc,#0x7f10 - out (c),c - ld c,#0x47 ;Pink - out (c),c - - di - - xor a - call fd765_tx ; send the final unused 0 byte - ; to fire off the command - ld hl, (_fd765_buffer) - ld bc, #0xfb7e -fdc_data_write: - in a,(c) ;; FDC has data and the direction is from FDC to CPU - jp p,fdc_data_write ;; - and #0x20 ;; "Execution phase" i.e. indicates reading of sector data - jp z,fdc_write_end - - inc c ;; BC = I/O address for FDC data register - ld a,(hl) ;; read from memory - out (c),a ;; write to FDC data register - dec c ;; BC = I/O address for FDC main status register - inc hl ;; increment memory pointer - jp fdc_data_write - -fdc_write_end: -; ld de,#0x2000 ; to make timing -; jp write_wait -; -;write_loop: -; inc c -; outi -; inc b -; dec c -; dec e -; jp z, write_wait2 -;write_wait: -; in a,(c) -; jp p, write_wait -; and d -; jp nz, write_loop -; jp write_finished -;write_loop2: -; inc c -; outi -; inc b -; dec c -; dec e -; jp z, write_flush_wait -;write_wait2: -; in a,(c) -; jp p, write_wait2 -; and d -; jp nz, write_loop2 -; jp write_finished -;write_flush: -; inc c -; in a,(c) -; dec c -;write_flush_wait: -; in a,(c) -; jp p, write_flush_wait -; and d -; jp nz, write_flush -write_finished: - ld (_fd765_buffer), hl - call _fd765_do_nudge_tc ; Tell FDC we've finished - ei - call fd765_read_status - call tc_fix - - ld bc,#0x7f10 - out (c),c - ld a,(_vtborder) - out (c),a - - pop af - ret z - jp map_kernel - -; Given an FDC opcode in A, sets up a read or write. - -setup_read_or_write: - call fd765_tx ; 0: send opcode (in A) - call send_head ; 1: specified head, drive #0 - ld a, (_fd765_track) ; 2: specified track - call fd765_tx - ld a, (_fd765_head) ; 3: specified head - call fd765_tx - ld a, (_fd765_sector) ; 4: specified sector - ld b, a - call fd765_tx - ld a, #2 ; 5: bytes per sector: 512 - call fd765_tx - ld a, (_fd765_sectors) - add b ; add first sector - dec a ; 6: last sector (*inclusive*) - call fd765_tx - ld a, #0x2A ; 7: Gap 3 length (2A is standard for 3" drives) - call fd765_tx - ; We return with the final unused 0 value not written. We need all - ; the other stuff lined up before we write this. - ret - -_fd765_buffer: - .dw 0 -_fd765_is_user: - .db 0 -_fd765_sectors: - .db 0 - -; Read the next sector ID off the disk. -; (Only used for debugging.) - -_fd765_do_read_id: - ld a, #0x4a ; READ MFM ID - call fd765_tx - call send_head ; specified head, drive 0 - jp fd765_read_status diff --git a/Kernel/platform/platform-cpc6128-SME/fuzix-platform-cpc6128-SME.pkg b/Kernel/platform/platform-cpc6128-SME/fuzix-platform-cpc6128-SME.pkg deleted file mode 100644 index 526097fcbd..0000000000 --- a/Kernel/platform/platform-cpc6128-SME/fuzix-platform-cpc6128-SME.pkg +++ /dev/null @@ -1,7 +0,0 @@ -package platform-cpc6128-SME - -disable-pkg platform-cpc6128-SME - -l /bin/sh /bin/sh.orig -r /bin/sh -l /bin/fsh /bin/sh \ No newline at end of file diff --git a/Kernel/platform/platform-cpc6128-SME/fuzix.export b/Kernel/platform/platform-cpc6128-SME/fuzix.export deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/Kernel/platform/platform-cpc6128-SME/fuzix.lnk.bck b/Kernel/platform/platform-cpc6128-SME/fuzix.lnk.bck deleted file mode 100644 index cb04214f01..0000000000 --- a/Kernel/platform/platform-cpc6128-SME/fuzix.lnk.bck +++ /dev/null @@ -1,59 +0,0 @@ --mwxuy --i fuzix.ihx --l z80 --b _CODE=0x0100 --b _COMMONMEM=0xF300 -platform/platform-cpc6128/crt0.rel -platform/platform-cpc6128/commonmem.rel -platform/platform-cpc6128/plus3.rel -platform/platform-cpc6128/zxvideo.rel -platform/platform-cpc6128/main.rel -platform/platform-cpc6128/discard.rel -start.rel -version.rel -cpu-z80/lowlevel-z80.rel -cpu-z80/usermem_std-z80.rel -platform/platform-cpc6128/tricks.rel -timer.rel -kdata.rel -usermem.rel -platform/platform-cpc6128/devices.rel -devio.rel -filesys.rel -blk512.rel -process.rel -inode.rel -syscall_exec.rel -syscall_exec16.rel -syscall_fs.rel -syscall_fs2.rel -syscall_fs3.rel -syscall_proc.rel -syscall_other.rel -syscall_net.rel -tty.rel -vt.rel -font8x8.rel -mm.rel -memalloc_none.rel -simple.rel -swap.rel -devsys.rel -devinput.rel -kmod.rel -network.rel -platform/platform-cpc6128/devtty.rel -platform/platform-cpc6128/tinyide.rel -platform/platform-cpc6128/tinyide_discard.rel -platform/platform-cpc6128/divide.rel -platform/platform-cpc6128/tinysd.rel -platform/platform-cpc6128/tinysd_discard.rel -platform/platform-cpc6128/zxmmc.rel -platform/platform-cpc6128/tinydisk.rel -platform/platform-cpc6128/tinydisk_discard.rel -platform/platform-cpc6128/devinput.rel -platform/platform-cpc6128/zxkeyboard.rel -platform/platform-cpc6128/devfdc765.rel -platform/platform-cpc6128/fdc765.rel -platform/platform-cpc6128/net_w5x00.rel --e diff --git a/Kernel/platform/platform-cpc6128-SME/kernel.def b/Kernel/platform/platform-cpc6128-SME/kernel.def deleted file mode 100644 index d061dd72e8..0000000000 --- a/Kernel/platform/platform-cpc6128-SME/kernel.def +++ /dev/null @@ -1,13 +0,0 @@ -; UZI mnemonics for memory addresses etc - -; We stick it straight after the tag -U_DATA__TOTALSIZE .equ 0x200 ; 256+256@F000 - -Z80_TYPE .equ 1 - -PROGBASE .equ 0x0000 -PROGLOAD .equ 0x0100 - -NBUFS .equ 5 - -Z80_MMU_HOOKS .equ 0 diff --git a/Kernel/platform/platform-cpc6128-SME/loader.s b/Kernel/platform/platform-cpc6128-SME/loader.s deleted file mode 100644 index be3d137ab4..0000000000 --- a/Kernel/platform/platform-cpc6128-SME/loader.s +++ /dev/null @@ -1,413 +0,0 @@ -;;from https://cpctech.cpc-live.com/ -;; Load data by talking directly to the NEC765 floppy disc controller (FDC) -;; https://cpctech.cpcwiki.de/source/fdcload.html from Kevin Thacker site -;; Code assumes there is a drive 0 and there is a disc in it and the disc is formatted -;; to SYSTEM format. -.area BOOT (ABS) -.org #0xfdff - -;;ROM's & interrupts off - -di -ld b, #0x7f -ld c,#0b10101101 -out (c),c -;;from default boot org to the needed one -ld hl,#0x100 -ld de,#0xfdff -ld bc,#512 -ldir - -jp start - -start: -;;clean room -ld hl,#0 -ld de ,#1 -ld (#0),hl -ld bc,#0xfdfe -ldir -;;patch interrupt vector -LD HL,#0XC9FB -LD (#0X0038),HL -;; turn on disc motor -ld bc,#0xfa7e -ld a,#1 -out (c),a -;; the motor on all connected drives will be turned on -;; and the motor will start to speed up. -;; -;; The drive must be "Ready" to accept commands from the FDC. -;; A drive will be ready if: -;; * the drive motor has reached a stable speed -;; * there is a disc in the drive -;; -;; The following code is a delay which will ait enough time for the motor -;; to reach a stable speed. (i.e. the motor speed is not increasing or decreasing) -;; -;; All drives are not the same, some 3" drives take longer to reach a stable -;; speed so we need a longer delay to be compatible with these. -;; -;; At this point interrupts must be enabled. -ei -ld b,#30 ;; 30/6 = 5 frames or 5/50 of a second. -w1: -;; there are 6 CPC interrupts per frame. This waits for one of them -halt -djnz w1 -di -;; this is the drive we want to use -;; the code uses this variable. -ld a,#0 -ld (#drive),a - -;; recalibrate means to move the selected drive to track 0. -;; -;; track 0 is a physical signal from the drive that indicates when -;; the read/write head is at track 0 position. -;; -;; The drive itself doesn't know which track the read/write head is positioned over. -;; The FDC has an internal variable for each drive which holds the current track number. -;; This value is reset when the drive indicates the read/write head is over track 0. -;; The number is increased/decreased as the FDC issues step pulses to the drive to move the head -;; to the track we want. -;; -;; once a recalibrate has been done, both drive and fdc agree on the track. -;; -call fdc_recalibrate - -;; now the drive is at a known position and is ready the fdc knows it is at a known position -;; we can read data.. -;call read_file - -read_file: -;; set variable for starting sector for our data (#0xC1 is first sector ID for -;; SYSTEM format. Sector IDs are #0x41, #0x42, #0x43, #0x44, #0x45, #0x46, #0x47, #0x48 and #0x49. -;; This bootloader is in track 0 sector #0x41 to load with |cpm command from basic - -ld a,#0x42 -ld (#sector),a - -;; set variable for starting track for our data -;; Tracks are numbered 0 to 39 for 40 track drives and 0 to 79 for 80 track drives. -;; Some 3" drives can allow up to 42 tracks (0-41), some 80 track drives can allow up -;; to 83 tracks (0-82). -;; -;; Not all drives are the same however. The maximum that is compatible with all 3" drives -;; is 41 tracks. -ld a,#0 -ld (#track),a - -;; memory address to write data to (start) -ld de,#0x100 -ld (#data_ptr),de - -;; number of complete sectors to read for our data -;; 30 sectors, 512 bytes per sector. Total data to read is 30*512 = 15360 bytes. -ld a,#126 -ld (#sector_count),a - -read_sectors_new_track: -;; perform a seek (this means to move read/write head to track we want). -;; track is defined by the "track" variable. -;; -;; a recalibrate must be done on the drive before a seek is done. -;; -;; the fdc uses it's internal track value for the chosen drive to decide to seek up/down to -;; reach the desired track. The FDC issues "step pulses" which makes the read/write head move -;; 1 track at a time at the rate defined by the FDC specify command. -;; -;; e.g. if fdc thinks we are on track 10, and we ask it to move to track 5, it will step back 5 times -;; updating it's internal track number each time. -call fdc_seek - -read_sectors: -;; Send Read data command to FDC to read 1 sector. - -;; A track is layed out as follows: -;; -;; id field -;; data field -;; -;; id field -;; data field -;; -;; id field -;; data field -;; etc. -;; -;; we tell the FDC the values of the ID field we want. Once it finds a match it will then read -;; the data. If the ID field we want is not found, it will report an error. - - -ld a,#0b01000110 ;; read data command (mfm=double density reading mode) - ;; not multi-track. See FDC data sheet for list of commands and the - ;; number of bytes they need. -call fdc_write_command -ld a,(#drive) ;; physical drive and side - ;; bits 1,0 define drive, bit 2 defines side -call fdc_write_command -ld a,(#track) ;; C value from id field of sector we want to read -call fdc_write_command -ld a,#0 ;; H value from id field of sector we want to read -call fdc_write_command -ld a,(#sector) ;; R value from id field of sector we want to read -call fdc_write_command -ld a,#2 ;; N value from id field of sector we want to read - ;; this also determines the amount of data in the sector. - ;; 2 = 512 byte sector -call fdc_write_command -ld a,(#sector) ;; EOT = Last sector ID to read. This is the same as the first to read 1 sector. -call fdc_write_command -ld a,#0x2a ;; Gap Length for read. Not important. -call fdc_write_command -ld a,#0xff ;; DTL = Data length. Only valid when N is 0 it seems -call fdc_write_command - -;; There will be a delay here before the first byte of a sector is ready and -;; interrupts can be active. -;; -;; The FDC is reading from the track. It is searching for an ID field that -;; matches the values we have sent in the command. -;; -;; When it finds the ID field, there is furthur time before the data field -;; of the sector is found and it starts to read. -;; -;; Once it has found the data, we must read it all and quickly. -;; - - -;; interrupts must be off now for data to be read successfully. -;; -;; The CPU constantly asks the FDC if there is data ready, if there is -;; it reads it from the FDC and stores it in RAM. There is a timing -;; constraint, the FDC gives the CPU a byte every 32microseconds. -;; If the CPU fails to read one of the bytes in time, the FDC will report -;; an overrun error and stop data transfer. - - -;; current address to write data too. -ld de,(#data_ptr) - -;; this is the main loop -;; which reads the data -;; The FDC will give us a byte every 32us (double density disc format). -;; -;; We must read it within this time. - -fdc_data_read: -in a,(c) ;; FDC has data and the direction is from FDC to CPU -jp p,fdc_data_read ;; -and #0x20 ;; "Execution phase" i.e. indicates reading of sector data -jp z,fdc_read_end - -inc c ;; BC = I/O address for FDC data register -in a,(c) ;; read from FDC data register -ld (de),a ;; write to memory -dec c ;; BC = I/O address for FDC main status register -inc de ;; increment memory pointer -jp fdc_data_read - -fdc_read_end: -;; Interrupts can be enabled now we have completed the data transfer - - - -;; we will get here if we successfully read all the sector's data -;; OR if there was an error. - -;; read the result -call fdc_result - -;; check result -ld ix,#result_data -ld c,#0x54 -ld a,0(ix) -cp #0x40 -jp z,nerr -ld a,1(ix) -cp #0x80 -jp z,nerr -ld c,#0x40 -nerr: - -;; decrease number of sectors transferred -ld a,(#sector_count) -dec a -jp z,read_done -ld (#sector_count),a - -;; update ram pointer for next sector -ld hl,(#data_ptr) -ld bc,#512 -add hl,bc -ld (#data_ptr),hl - -;; update sector id (loops #0x41-#0x49). -ld a,(#sector) -inc a -ld (#sector),a -cp #0x4a ;; #0x49+1 (last sector id on the track+1) -jp nz,read_sectors -;; we read sector #0x49, the last on the track. -;; Update track variable so we seek to the next track before -;; reading the next sector -ld a,(#track) -inc a -ld (#track),a - -ld a,#0x41 ;; #0x41 = first sector id on the track -ld (#sector),a -jp read_sectors_new_track - -read_done: -ld bc,#0xfa7e -ld a,#0 -out (c),a ;stop the motor -jp 0x100 ;start FUZIX - -;;=============================================== -;; send command to fdc -;; - -fdc_write_command: - - -ld bc,#0xfb7e ;; I/O address for FDC main status register -push af ;; -fwc1: in a,(c) ;; -add a,a ;; -jr nc,fwc1 ;; -add a,a ;; -jr nc,fwc2 ;; -pop af ;; -ret - -fwc2: -pop af ;; - -inc c ;; -out (c),a ;; write command byte -dec c ;; - -;; some FDC documents say there must be a delay between each -;; command byte, but in practice it seems this isn't needed on CPC. -;; Here for compatiblity. -ld a,#5 ;; -fwc3: dec a ;; -jr nz,fwc3 ;; -ret ;; - -;;=============================================== -;; get result phase of command -;; -;; timing is not important here - -fdc_result: - -ld hl,#result_data -ld bc,#0xfb7e -fr1: -in a,(c) -cp #0xc0 -jr c,fr1 - -inc c -in a,(c) -dec c -ld (hl),a -inc hl - -ld a,#5 -fr2: -dec a -jr nz,fr2 -in a,(c) -and #0x10 -jr nz,fr1 - - -ret - -;;=============================================== - -;; physical drive -;; bit 1,0 are drive, bit 2 is side. -drive: -.db 0 - -;; physical track (updated during read) -track: -.db 0 - -;; id of sector we want to read (updated during read) -sector: -.db 0 - -;; number of sectors to read (updated during read) -sector_count: -.db 2 ;; enough for now - -;; address to write data to (updated during read) -data_ptr: -.ds 2 - -;;=============================================== - -fdc_seek: -ld a,#0b00001111 ;; seek command -call fdc_write_command -ld a,(#drive) -call fdc_write_command -ld a,(#track) -call fdc_write_command - -call fdc_seek_or_recalibrate -jp nz,fdc_seek -ret - -;;=============================================== - -fdc_recalibrate: - -;; seek to track 0 -ld a,#0b111 ;; recalibrate -call fdc_write_command -ld a,(#drive) ;; drive -call fdc_write_command - -call fdc_seek_or_recalibrate -jp nz,fdc_recalibrate -ret - -;;=============================================== -;; NZ result means to retry seek/recalibrate. - -fdc_seek_or_recalibrate: -ld a,#0b1000 ;; sense interrupt status -call fdc_write_command -call fdc_result - -;; recalibrate completed? -ld ix,#result_data -bit 5,0(ix) ;; Bit 5 of Status register 0 is "Seek complete" -jr z,fdc_seek_or_recalibrate -bit 4,0(ix) ;; Bit 4 of Status register 0 is "recalibrate/seek failed" -;; -;; Some FDCs will seek a maximum of 77 tracks at one time. This is a legacy/historical -;; thing when drives only had 77 tracks. 3.5" drives have 80 tracks. -;; -;; If the drive was at track 80 before the recalibrate/seek, then one recalibrate/seek -;; would not be enough to reach track 0 and the fdc will then report an error (meaning -;; it had seeked 77 tracks and failed to reach the track we wanted). -;; We repeat the recalibrate/seek to finish the movement of the read/write head. -;; -ret - -;;=============================================== - -file_buffer: -.dw 0x100 -result_data: -.ds 8 -end: \ No newline at end of file diff --git a/Kernel/platform/platform-cpc6128-SME/loader_firmware.s b/Kernel/platform/platform-cpc6128-SME/loader_firmware.s deleted file mode 100644 index b384288459..0000000000 --- a/Kernel/platform/platform-cpc6128-SME/loader_firmware.s +++ /dev/null @@ -1,94 +0,0 @@ -;;from: https://cpctech.cpc-live.com/source/byteload.html, modified to load something bigger - -;; This example shows how to read a file byte by byte. -;; -;; A file without a header must be read this way, it can't be -;; read using CAS IN DIRECT (unless the in-memory header is patched) -;; -;; This example doesn't have any error checking. - -.area BOOT (ABS) -.org 0xa500 - -cas_in_open .equ 0xbc77 -cas_in_close .equ 0xbc7a -cas_in_char .equ 0xbc80 -kl_rom_walk .equ 0xbccb -mc_start_program .equ 0xbd16 - -ld c,#0xff -ld hl,#start -call mc_start_program -start: -ld hl,#0x0100 ;; address to load file data to (example) -push hl - -call kl_rom_walk -;; open file for reading -ld b,#end_filename-filename -ld hl,#filename -ld de,#two_k_buffer -call cas_in_open - -;; If a file is opened without a header: -;; - the filetype will be ASCII (0x16) -;; - the length and load address will be undefined. -;; -;; If a file is opened with a header, the -;; - the filetype will be taken from the header -;; - the length and load address will be taken from the header -;; -;; A file without a header can't be read with CAS IN DIRECT -;; and must be read using CAS IN CHAR. - -pop hl - -;; read a char from the file, character is returned in A register - -next_byte: -call cas_in_char -jr nc,not_eof -jr nz,not_eof - -;; could be end of file -;; test for hard end of file byte -cp #0xf -jr nz,not_eof -jr eof - -not_eof: -;; write byte to memory -ld (hl),a -inc hl -ld a,#0xA5 -cp h -jr z, avoid_crash -jr next_byte - - -eof: -call cas_in_close -ld de,#0xA500 -ld hl,#0xC000 -ld bc,#0x4000 -ldir -jp 0x100 ;; and go to fuzix - -avoid_crash: -ld b,#0x1b ;;0xc0-0xa5 -ld c,#0 -add hl,bc -jr next_byte - -;;------------------------------------------------------------------- -;; name of the file to read - -filename: -.ascii "FUZIX.BIN" -end_filename: - -;;------------------------------------------------------------------- -;; this buffer is filled with data from the file -.org 0xF7FF -two_k_buffer: -.blkb 2048 \ No newline at end of file diff --git a/Kernel/platform/platform-cpc6128-SME/main.c b/Kernel/platform/platform-cpc6128-SME/main.c deleted file mode 100644 index 03dfa901c7..0000000000 --- a/Kernel/platform/platform-cpc6128-SME/main.c +++ /dev/null @@ -1,156 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -//#include - -uint16_t ramtop = PROGTOP; -uint16_t swap_dev = 0xFFFF; - -/* On idle we spin checking for the terminals. Gives us more responsiveness - for the polled ports */ -void plt_idle(void) -{ - /* We don't want an idle poll and IRQ driven tty poll at the same moment */ - __asm - halt - __endasm; -} - -uint8_t timer_wait; - -void plt_interrupt(void) -{ - tty_pollirq(); - timer_interrupt(); - poll_input(); - if (timer_wait) - wakeup(&timer_interrupt); - devfd_spindown(); -} - -/* - * So that we don't suck in a library routine we can't use from - * the runtime - */ - -size_t strlen(const char *p) -{ - size_t len = 0; - while(*p++) - len++; - return len; -} - -/* This points to the last buffer in the disk buffers. There must be at least - four buffers to avoid deadlocks. */ -struct blkbuf *bufpool_end = bufpool + NBUFS; - -/* - * We pack discard into the memory image is if it were just normal - * code but place it at the end after the buffers. When we finish up - * booting we turn everything from the buffer pool to the start of - * user space into buffers. - * - * We don't touch discard. Discard is just turned into user space. - */ -void plt_discard(void) -{ - uint16_t discard_size = ((uint16_t)&udata) - (uint16_t)bufpool_end; - bufptr bp = bufpool_end; -#ifdef CONFIG_KMOD - kmod_init(bufpool_end, &udata); -#endif - - discard_size /= sizeof(struct blkbuf); - - kprintf("%d buffers added\n", discard_size); - - bufpool_end += discard_size; - - memset( bp, 0, discard_size * sizeof(struct blkbuf) ); - - for( bp = bufpool + NBUFS; bp < bufpool_end; ++bp ){ - bp->bf_dev = NO_DEVICE; - bp->bf_busy = BF_FREE; - } -} - -unsigned plt_kmod_set(uint8_t *top) -{ - /* Make sure all disk buffers are on disk */ - sync(); - /* Wind back until bufpool end is below the modules */ - while(bufpool_end > (void *)top) - bufpool_end--; - /* Any buffers lost we already wrote to disk, any new lookups will - not find them, and we know there are no other outstanding references - - sometimes having a dumb I/O layer is a win */ - return 0; -} - -#ifndef SWAPDEV -/* Adding dummy swapper since it is referenced by tricks.s */ -void swapper(ptptr p) -{ - p; -} -#endif - -#ifdef CONFIG_NET_W5100 - -uint8_t w5x00_readcb(uint16_t off) -{ -} - -uint8_t w5x00_readsb(uint8_t s, uint16_t off) -{ -} - -uint16_t w5x00_readcw(uint16_t off) -{ -} - -uint16_t w5x00_readsw(uint8_t s, uint16_t off) -{ -} - -void w5x00_bread(uint16_t bank, uint16_t off, void *pv, uint16_t n) -{ -} - -void w5x00_breadu(uint16_t bank, uint16_t off, void *pv, uint16_t n) -{ -} - -void w5x00_writecb(uint16_t off, uint8_t n) -{ -} - -void w5x00_writesb(uint8_t sock, uint16_t off, uint8_t n) -{ -} - -void w5x00_writecw(uint16_t off, uint16_t n) -{ -} - -void w5x00_writesw(uint8_t sock, uint16_t off, uint16_t n) -{ -} - -void w5x00_bwrite(uint16_t bank, uint16_t off, void *pv, uint16_t n) -{ -} - -void w5x00_bwriteu(uint16_t bank, uint16_t off, void *pv, uint16_t n) -{ -} - -void w5x00_setup(void) -{ -} -#endif diff --git a/Kernel/platform/platform-cpc6128-SME/platform_fdc765.h b/Kernel/platform/platform-cpc6128-SME/platform_fdc765.h deleted file mode 100644 index da41e4c3fc..0000000000 --- a/Kernel/platform/platform-cpc6128-SME/platform_fdc765.h +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Platform specifics - */ - -#define FDC_MOTOR_TIMEOUT 10 /* Seconds */ - -#define FDC765_MAX_FLOPPY 2 /* Two drives */ - - -/* Hard code for now. Two drives, second drive double sided */ -#define fdc765_ds 2 -#define fdc765_present 3 \ No newline at end of file diff --git a/Kernel/platform/platform-cpc6128-SME/plt_ch375.h b/Kernel/platform/platform-cpc6128-SME/plt_ch375.h deleted file mode 100644 index 8a4f0a0457..0000000000 --- a/Kernel/platform/platform-cpc6128-SME/plt_ch375.h +++ /dev/null @@ -1,14 +0,0 @@ -extern void nap20(void); -extern void ch375_rblock(uint8_t *ptr);/* __z88dk_fastcall; */ -extern void ch375_wblock(uint8_t *ptr);/* __z88dk_fastcall; */ - -__sfr __banked __at 0xFE80 ch375_dport; -__sfr __banked __at 0xFE81 ch375_sport; - -#define ch375_rdata() ch375_dport -#define ch375_rstatus() ch375_sport - -#define ch375_wdata(x) do {ch375_dport = (x); } while(0) -#define ch375_wcmd(x) do {ch375_sport = (x); } while(0) - -#define CH376_REG_DATA 0xFE80 \ No newline at end of file diff --git a/Kernel/platform/platform-cpc6128-SME/plt_ide.h b/Kernel/platform/platform-cpc6128-SME/plt_ide.h deleted file mode 100644 index 4d6c0567cc..0000000000 --- a/Kernel/platform/platform-cpc6128-SME/plt_ide.h +++ /dev/null @@ -1,13 +0,0 @@ -__sfr __banked __at 0xFD08 data; -__sfr __banked __at 0xFD09 error; -__sfr __banked __at 0xFD0A count; -__sfr __banked __at 0xFD0B sec; -__sfr __banked __at 0xFD0C cyll; -__sfr __banked __at 0xFD0D cylh; -__sfr __banked __at 0xFD0E devh; -__sfr __banked __at 0xFD0F cmd; -__sfr __banked __at 0xFD0F status; - -#define IDE_REG_DATA 0xFD08 - -#define IDE_NONSTANDARD_XFER diff --git a/Kernel/platform/platform-cpc6128-SME/rd_cpcsme.s b/Kernel/platform/platform-cpc6128-SME/rd_cpcsme.s deleted file mode 100644 index 68eb1b4799..0000000000 --- a/Kernel/platform/platform-cpc6128-SME/rd_cpcsme.s +++ /dev/null @@ -1,107 +0,0 @@ -; -; RAM disc helpers for CPC Standard Memory Expansions -; - - .area _CODE - - .globl _rd_io - - .globl _ct - .globl _block - .globl _nblock - .globl _rd_wr - .globl _rd_swap_mem_port_h - .globl _rd_swap_bank - .globl _rd_proc_bank - .globl _rd_swap_bank_addr - .globl _rd_proc_bank_addr - .globl _rd_dptr - .globl _int_disabled - .globl _vtborder - .globl map_kernel_restore - - -_rd_io: - di - ld a,(_rd_wr) - or a - jp z, is_wr - ld bc,#0x7f10 - out (c),c - ld c,#0x53 ;Bright cyan - out (c),c - ld a,(_rd_swap_mem_port_h) - ld b,a - ld c,#0xff - ld a,(_rd_swap_bank) - out (c),a - ld hl,(_rd_swap_bank_addr) - ld de, #swapbuffer - ld bc,#512 - ldir - ld bc,#0x7fff - ld a,(_rd_proc_bank) - out (c),a - ld hl,#swapbuffer - ld de,(_rd_proc_bank_addr) - ld bc,#512 - ldir -end_io: - ld bc,#0x7fc1 ; map kernel - out (c),c - call map_kernel_restore ; do it the right way - ld bc,#0x7f10 - out (c),c - ld a,(_vtborder) - out (c),a - ld a,(_int_disabled) - or a - ret nz - ei - ret -is_wr: - ld bc,#0x7f10 - out (c),c - ld c,#0x4c ;Bright red - out (c),c - ld bc,#0x7fff - ld a,(_rd_proc_bank) - out (c),a - ld hl,(_rd_proc_bank_addr) - ld de,#swapbuffer - ld bc,#512 - ldir - ld a,(_rd_swap_mem_port_h) - ld b,a - ld c,#0xff - ld a,(_rd_swap_bank) - out (c),a - ld hl,#swapbuffer - ld de,(_rd_swap_bank_addr) - ld bc,#512 - ldir - jp end_io - -_ct: - .db 0 -_rd_wr: - .db 0 -_rd_swap_bank: - .db 0 -_rd_proc_bank: - .db 0 -_rd_swap_mem_port_h: - .db 0x7f -_rd_swap_bank_addr: - .dw 0 -_rd_proc_bank_addr: - .dw 0 -_rd_dptr: - .dw 0 -_block: - .dw 0 -_nblock: - .dw 0 -swapbuffer: - .ds 512 - diff --git a/Kernel/platform/platform-cpc6128-SME/rules.mk b/Kernel/platform/platform-cpc6128-SME/rules.mk deleted file mode 100644 index edaf0e339a..0000000000 --- a/Kernel/platform/platform-cpc6128-SME/rules.mk +++ /dev/null @@ -1,2 +0,0 @@ -export CROSS_CC_SYS5=--codeseg CODE3 -CROSS_CCOPTS += --peep-file $(FUZIX_ROOT)/Kernel/cpu-z80/rst.peep diff --git a/Kernel/platform/platform-cpc6128-SME/target.mk b/Kernel/platform/platform-cpc6128-SME/target.mk deleted file mode 100644 index 3bffcde0c7..0000000000 --- a/Kernel/platform/platform-cpc6128-SME/target.mk +++ /dev/null @@ -1 +0,0 @@ -export CPU = z80 diff --git a/Kernel/platform/platform-cpc6128-SME/tricks.s b/Kernel/platform/platform-cpc6128-SME/tricks.s deleted file mode 100644 index 2d02424493..0000000000 --- a/Kernel/platform/platform-cpc6128-SME/tricks.s +++ /dev/null @@ -1,5 +0,0 @@ - .include "kernel.def" - .include "../../cpu-z80/kernel-z80.def" - - .include "../../lib/z80single.s" - From 02737d77bfd604226f543f91e398953db6b9d4f0 Mon Sep 17 00:00:00 2001 From: ajcasado Date: Tue, 21 Jan 2025 20:55:37 +0100 Subject: [PATCH 5/7] Merge cpc6128 ports. Use of standard memory expansions as swap space. --- Kernel/platform/platform-cpc6128/Makefile | 6 +- Kernel/platform/platform-cpc6128/README | 10 +- Kernel/platform/platform-cpc6128/config.h | 35 ++++-- Kernel/platform/platform-cpc6128/devices.c | 25 ++-- Kernel/platform/platform-cpc6128/devrd.c | 83 +++++++++++++ Kernel/platform/platform-cpc6128/devrd.h | 20 ++++ Kernel/platform/platform-cpc6128/discard.c | 5 + Kernel/platform/platform-cpc6128/fuzix.lnk | 2 + Kernel/platform/platform-cpc6128/rd_cpcsme.c | 117 +++++++++++++++++++ 9 files changed, 276 insertions(+), 27 deletions(-) create mode 100644 Kernel/platform/platform-cpc6128/devrd.c create mode 100644 Kernel/platform/platform-cpc6128/devrd.h create mode 100644 Kernel/platform/platform-cpc6128/rd_cpcsme.c diff --git a/Kernel/platform/platform-cpc6128/Makefile b/Kernel/platform/platform-cpc6128/Makefile index cd09e33d16..b4a4cf1813 100644 --- a/Kernel/platform/platform-cpc6128/Makefile +++ b/Kernel/platform/platform-cpc6128/Makefile @@ -1,11 +1,11 @@ -CSRCS = devtty.c devices.c main.c +CSRCS = devtty.c devices.c main.c devrd.c rd_cpcsme.c CDSRCS = discard.c DSRCS = ../../dev/tinyide.c ../../dev/tinydisk.c ../../dev/devfdc765.c ../../dev/ch375.c DDSRCS = ../../dev/tinyide_discard.c ../../dev/tinydisk_discard.c DZSRCS = ../../dev/cpc/cpcide.c ../../dev/cpc/cpckeyboard.c ../../dev/cpc/devinput.c ../../dev/cpc/albireo.c DDZSRCS = -ASRCS = crt0.s cpc6128.s cpcvideo.s fdc765.s -ASRCS += tricks.s commonmem.s +ASRCS = crt0.s cpc6128.s cpcvideo.s fdc765.s +ASRCS += tricks.s commonmem.s NSRCS = COBJS = $(CSRCS:.c=.rel) diff --git a/Kernel/platform/platform-cpc6128/README b/Kernel/platform/platform-cpc6128/README index fd31fdd0f5..8c6c54a8b6 100644 --- a/Kernel/platform/platform-cpc6128/README +++ b/Kernel/platform/platform-cpc6128/README @@ -1,7 +1,7 @@ # Amstrad CPC6128 -## Mmeory Model +## Memory Model The CPC6128 supported memory maps: @@ -23,7 +23,13 @@ In the CPC6128: | Kernel | 0 / 1 / 2 | Common 7 (map C1) | Video | 0 / 3 / 2 | Common 7 (map C3) +The use of standard memory expansions as swap space has been implemented. With this memory map, the ability to have multiple tasks simultaneously in RAM has not been implemented. This is because the expanded memory can only be mapped in 16k blocks starting at address 0x4000, which removes the common area from the map (this mapping is used to implement the RAM disk for swap while executing code in the non-common code area). Alternatively, it can be mapped in 64k blocks, replacing the entire memory space without any common area to rely on.. See this references: +https://www.cpcwiki.eu/index.php/Gate_Array#Register_MMR_.28RAM_memory_mapping.29 +https://www.cpcwiki.eu/index.php/Standard_Memory_Expansions +This latter 64k block mapping approach, which involves switching between 64k blocks, is being considered for another port inspired by the memory usage in the Cromemco port. + +Two standard memory expansion sizes are supported: 512k and 1024k. To build the port with either of these options, simply define the macros EXTENDED_RAM_512 or EXTENDED_RAM_1024 depending on the desired size. If neither is defined, the build will default to supporting a swap partition on any of the supported disk types. ## STATUS @@ -54,7 +60,7 @@ Support more hardware: M4 Board (storage, network and RTC), Ulifac/Usifac, netwo Fix lots of bugs. -Switch to a thunked memory model based on C2 Map to use the standard and extended RAM expansions up to 4MiB, the Cromemco port could be a model to this solution. As ther is no real common as we are switching the whole 64k space, the common data area has to be updated in all the used banks, but this can give aprox. 60K for kernel and user and hold a lot of processes in memory with a big RAM expansion. If this proves to be too hard, a RAM disk for swapping can be a way to use the RAM expansions. +Switch to a thunked memory model based on C2 Map to use the standard and extended RAM expansions up to 4MiB, the Cromemco port could be a model to this solution. As there is no real common as we are switching the whole 64k space, the common data area has to be updated in all the used banks, but this can give aprox. 60K for kernel and user and hold a lot of processes in memory with a big RAM expansion. Look for speed optimization opportunities. diff --git a/Kernel/platform/platform-cpc6128/config.h b/Kernel/platform/platform-cpc6128/config.h index 85a8d69511..8194de1997 100644 --- a/Kernel/platform/platform-cpc6128/config.h +++ b/Kernel/platform/platform-cpc6128/config.h @@ -27,8 +27,8 @@ #define UDATA_BLKS 1 #define UDATA_SIZE 0x200 #define CONFIG_DYNAMIC_BUFPOOL -#define CONFIG_DYNAMIC_SWAP -#define MAXTICKS 20 /* Has to be high because we are swap only */ + +#define MAXTICKS 60 /* Has to be high because we are swap only */ #undef CONFIG_KMOD @@ -70,8 +70,24 @@ #define SWAPBASE 0x0000 #define SWAPTOP 0xC000UL #define SWAP_SIZE 0x61 /* 48K + udata */ -#define MAX_SWAPS 16 -#define SWAPDEV (swap_dev) /* Device for swapping (dynamic). */ +#define EXTENDED_RAM_1024 +#ifdef EXTENDED_RAM_1024 + #define MAX_SWAPS 19 /*See platform devrd.c*/ + #define PTABSIZE 19 + #define TOTAL_SWAP_BLOCKS (1088-128) * 2 +#endif +#ifdef EXTENDED_RAM_512 + #define MAX_SWAPS 9 /*See platform devrd.c*/ + #define PTABSIZE 9 + #define TOTAL_SWAP_BLOCKS (576-128) * 2 +#endif +#if defined EXTENDED_RAM_512 || defined EXTENDED_RAM_1024 + #define SWAPDEV 0x800 /* Device for swapping - RAM disk on standard memory expansion. */ +#else + #define CONFIG_DYNAMIC_SWAP + #define SWAPDEV (swap_dev) /* Device for swapping (dynamic). */ + #define MAX_SWAPS 16 +#endif /* We swap by hitting the user map */ #define swap_map(x) ((uint8_t *)(x)) @@ -83,15 +99,12 @@ #define CONFIG_TINYIDE_SDCCPIO #define CONFIG_TINYIDE_8BIT #define IDE_IS_8BIT(x) 1 -/* SD support */ -/* #define TD_SD_NUM 2 */ -/* #define CONFIG_TD_SD */ -/* Emulator for this platform needs bug workarounds */ -/* #undef CONFIG_TD_SD_EMUBUG */ -/*#undef SD_SPI_CALLTYPE __z88dk_fastcall */ #define BOOTDEVICENAMES "hd#,fd" #define CONFIG_SMALL -/* #define DEBUG */ \ No newline at end of file + + + + diff --git a/Kernel/platform/platform-cpc6128/devices.c b/Kernel/platform/platform-cpc6128/devices.c index f29a9c0ddb..2679324c4a 100644 --- a/Kernel/platform/platform-cpc6128/devices.c +++ b/Kernel/platform/platform-cpc6128/devices.c @@ -6,10 +6,11 @@ #include #include #include -#include +/*#include */ #include #include -#include +/*#include */ +#include struct devsw dev_tab[] = /* The device driver switch table */ { @@ -24,23 +25,25 @@ struct devsw dev_tab[] = /* The device driver switch table */ /* 4: /dev/mem etc System devices (one offs) */ { no_open, no_close, sys_read, sys_write, sys_ioctl }, /* 5: Pack to 7 with nxio if adding private devices and start at 8 */ - #ifdef CONFIG_NET - { nxio_open, no_close, no_rdwr, no_rdwr, no_ioctl }, - { nxio_open, no_close, no_rdwr, no_rdwr, no_ioctl }, - { nxio_open, no_close, no_rdwr, no_rdwr, no_ioctl }, - { nxio_open, no_close, no_rdwr, no_rdwr, no_ioctl }, -#endif + #if defined EXTENDED_RAM_512 || defined EXTENDED_RAM_1024 + /* 5: unused */ + { no_open, no_close, no_rdwr, no_rdwr, no_ioctl }, + /* 6: unused */ + { no_open, no_close, no_rdwr, no_rdwr, no_ioctl }, + /* 7: unused */ + { no_open, no_close, no_rdwr, no_rdwr, no_ioctl }, + /* 8: Standard memory expansions RAM swap */ + { rd_open, no_close, rd_read, rd_write, no_ioctl }, + #endif }; - - 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; + return false; else return true; } diff --git a/Kernel/platform/platform-cpc6128/devrd.c b/Kernel/platform/platform-cpc6128/devrd.c new file mode 100644 index 0000000000..e8486f9d86 --- /dev/null +++ b/Kernel/platform/platform-cpc6128/devrd.c @@ -0,0 +1,83 @@ +/* + * CPC standard RAM bank memory expansions ramdisc driver, based on platform zxdiv48. + */ + +#include +#include +#include + +#if defined EXTENDED_RAM_512 || defined EXTENDED_RAM_1024 +#include + + +static int rd_transfer(uint8_t is_read, uint8_t rawflag) +{ + nblock = udata.u_nblock; + block = udata.u_block; + rd_dptr = udata.u_dptr; + rd_wr = is_read; + uint16_t swap_bank_long; + uint8_t ct = 0; + + #ifdef DEBUG + kprintf("u_dptr %p Block %u u_nblock %u rd_wr %u\n",udata.u_dptr, udata.u_block, udata.u_nblock, rd_wr); + #endif + + /* It's a disk but only for swapping (and rd_io isn't general purpose) */ + if (((block + nblock) > (TOTAL_SWAP_BLOCKS - 1)) || (rawflag == 1)) { + udata.u_error = EIO; + kprintf("dev_rd_EIO"); + return -1; + } + + /* udata could change under us so keep variables privately */ + while (ct < nblock) { + swap_bank_long = (block >> 5); + swap_bank_long = swap_bank_long + 196 + (((swap_bank_long + 8) / 4) * 4); /*Convert bank number to Register MMR value + *See https://www.cpcwiki.eu/index.php/Gate_Array#Register_MMR_.28RAM_memory_mapping.29*/ + if (swap_bank_long > 255){ + rd_swap_bank = swap_bank_long - 64; + rd_swap_mem_port_h = 0x7e; + } + else{ + rd_swap_bank = swap_bank_long; + rd_swap_mem_port_h = 0x7f; + } + rd_proc_bank = ((uint16_t)rd_dptr / 0x4000) + 0xc4; + rd_swap_bank_addr = ((block & 31) << BLKSHIFT) + 0x4000; + rd_proc_bank_addr = ((uint16_t)rd_dptr & 0x3fff) + 0x4000; + + #ifdef DEBUG + if (nblock == 1) + kprintf("swap_bank %p swap_addr %p proc_bank %p proc_addr %p count %u\n", rd_swap_bank, rd_swap_bank_addr, rd_proc_bank, rd_proc_bank_addr, ct); + #endif + rd_io(); + block++; + rd_dptr += BLKSIZE; + ct++; + } + return ct << BLKSHIFT; /*Total bytes transferred*/ +} + +int rd_open(uint8_t minor, uint16_t flag) +{ + flag; + if(minor != 0) { + udata.u_error = ENODEV; + return -1; + } + return 0; +} + +int rd_read(uint8_t minor, uint8_t rawflag, uint8_t flag) +{ + flag;minor; + return rd_transfer(true, rawflag); +} + +int rd_write(uint8_t minor, uint8_t rawflag, uint8_t flag) +{ + flag;minor; + return rd_transfer(false, rawflag); +} +#endif diff --git a/Kernel/platform/platform-cpc6128/devrd.h b/Kernel/platform/platform-cpc6128/devrd.h new file mode 100644 index 0000000000..e7c4451555 --- /dev/null +++ b/Kernel/platform/platform-cpc6128/devrd.h @@ -0,0 +1,20 @@ +/* + * + * CPC standard RAM bank memory expansions ramdisc driver + */ + +int rd_open(uint8_t minor, uint16_t flags); +int rd_read(uint8_t minor, uint8_t rawflag, uint8_t flag); +int rd_write(uint8_t minor, uint8_t rawflag, uint8_t flag); + +extern uint8_t rd_wr; +extern uint8_t rd_swap_bank; +extern uint8_t rd_swap_mem_port_h; +extern uint8_t rd_proc_bank; +extern uint8_t *rd_dptr; +extern uint16_t rd_swap_bank_addr; +extern uint16_t rd_proc_bank_addr; +extern uint16_t nblock; +extern blkno_t block; + +void rd_io(void); diff --git a/Kernel/platform/platform-cpc6128/discard.c b/Kernel/platform/platform-cpc6128/discard.c index 207e33eff2..cd9a4c8605 100644 --- a/Kernel/platform/platform-cpc6128/discard.c +++ b/Kernel/platform/platform-cpc6128/discard.c @@ -13,6 +13,11 @@ uint8_t plt_param(char *p) /* Nothing to do for the map of init */ void map_init(void) { +#if defined EXTENDED_RAM_512 || defined EXTENDED_RAM_1024 + uint_fast8_t i; + for (i = 0; i < MAX_SWAPS; i++) + swapmap_init(i); +#endif } void plt_copyright(void) diff --git a/Kernel/platform/platform-cpc6128/fuzix.lnk b/Kernel/platform/platform-cpc6128/fuzix.lnk index 2ac77d8022..f9858617a7 100644 --- a/Kernel/platform/platform-cpc6128/fuzix.lnk +++ b/Kernel/platform/platform-cpc6128/fuzix.lnk @@ -6,6 +6,7 @@ platform/platform-cpc6128/crt0.rel platform/platform-cpc6128/commonmem.rel platform/platform-cpc6128/cpc6128.rel +platform/platform-cpc6128/rd_cpcsme.rel platform/platform-cpc6128/cpcvideo.rel platform/platform-cpc6128/main.rel platform/platform-cpc6128/discard.rel @@ -54,4 +55,5 @@ platform/platform-cpc6128/devfdc765.rel platform/platform-cpc6128/fdc765.rel platform/platform-cpc6128/ch375.rel platform/platform-cpc6128/albireo.rel +platform/platform-cpc6128/devrd.rel -e diff --git a/Kernel/platform/platform-cpc6128/rd_cpcsme.c b/Kernel/platform/platform-cpc6128/rd_cpcsme.c new file mode 100644 index 0000000000..b4f6481086 --- /dev/null +++ b/Kernel/platform/platform-cpc6128/rd_cpcsme.c @@ -0,0 +1,117 @@ +/* +* RAM disc helpers for CPC Standard Memory Expansions +*/ + +#include + +#undef di +#undef ei + +#if defined EXTENDED_RAM_512 || defined EXTENDED_RAM_1024 +static void CODESEG(void) __naked { __asm .area _CODE __endasm; } /* .area _CODE */ +void rd_io(void) __naked +{ + __asm + + .globl _rd_io + + .globl _block + .globl _nblock + .globl _rd_wr + .globl _rd_swap_mem_port_h + .globl _rd_swap_bank + .globl _rd_proc_bank + .globl _rd_swap_bank_addr + .globl _rd_proc_bank_addr + .globl _rd_dptr + .globl _int_disabled + .globl _vtborder + .globl map_kernel_restore + + + + di + ld a,(_rd_wr) + or a + jp z, is_wr + ld bc,#0x7f10 + out (c),c + ld c,#0x53 ;Bright cyan + out (c),c + ld a,(_rd_swap_mem_port_h) + ld b,a + ld c,#0xff + ld a,(_rd_swap_bank) + out (c),a + ld hl,(_rd_swap_bank_addr) + ld de, #swapbuffer + ld bc,#512 + ldir + ld bc,#0x7fff + ld a,(_rd_proc_bank) + out (c),a + ld hl,#swapbuffer + ld de,(_rd_proc_bank_addr) + ld bc,#512 + ldir +end_io: + ld bc,#0x7fc1 ; map kernel + out (c),c + call map_kernel_restore ; do it the right way + ld bc,#0x7f10 + out (c),c + ld a,(_vtborder) + out (c),a + ld a,(_int_disabled) + or a + ret nz + ei + ret +is_wr: + ld bc,#0x7f10 + out (c),c + ld c,#0x4c ;Bright red + out (c),c + ld bc,#0x7fff + ld a,(_rd_proc_bank) + out (c),a + ld hl,(_rd_proc_bank_addr) + ld de,#swapbuffer + ld bc,#512 + ldir + ld a,(_rd_swap_mem_port_h) + ld b,a + ld c,#0xff + ld a,(_rd_swap_bank) + out (c),a + ld hl,#swapbuffer + ld de,(_rd_swap_bank_addr) + ld bc,#512 + ldir + jp end_io + +_rd_wr: + .db 0 +_rd_swap_bank: + .db 0 +_rd_proc_bank: + .db 0 +_rd_swap_mem_port_h: + .db 0x7f +_rd_swap_bank_addr: + .dw 0 +_rd_proc_bank_addr: + .dw 0 +_rd_dptr: + .dw 0 +_block: + .dw 0 +_nblock: + .dw 0 +swapbuffer: + .ds 512 + +__endasm; +} +#endif + From 78be4edc6b327954f86930e857d274761c5a8607 Mon Sep 17 00:00:00 2001 From: ajcasado Date: Tue, 21 Jan 2025 21:49:10 +0100 Subject: [PATCH 6/7] Update Readme file --- Kernel/platform/platform-cpc6128/README | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Kernel/platform/platform-cpc6128/README b/Kernel/platform/platform-cpc6128/README index 8c6c54a8b6..6692dfd724 100644 --- a/Kernel/platform/platform-cpc6128/README +++ b/Kernel/platform/platform-cpc6128/README @@ -23,13 +23,13 @@ In the CPC6128: | Kernel | 0 / 1 / 2 | Common 7 (map C1) | Video | 0 / 3 / 2 | Common 7 (map C3) -The use of standard memory expansions as swap space has been implemented. With this memory map, the ability to have multiple tasks simultaneously in RAM has not been implemented. This is because the expanded memory can only be mapped in 16k blocks starting at address 0x4000, which removes the common area from the map (this mapping is used to implement the RAM disk for swap while executing code in the non-common code area). Alternatively, it can be mapped in 64k blocks, replacing the entire memory space without any common area to rely on.. See this references: +The use of standard memory expansions as swap space has been implemented. With this memory map, the ability to have multiple tasks simultaneously in RAM has not been implemented. This is because the expanded memory can only be mapped in 16k blocks starting at address 0x4000, which removes the common area from the map (this mapping is used to implement the RAM disk for swap while executing code in the non-common code area). Alternatively, it can be mapped in 64k blocks, replacing the entire memory space without any common area to rely on. See this references: https://www.cpcwiki.eu/index.php/Gate_Array#Register_MMR_.28RAM_memory_mapping.29 https://www.cpcwiki.eu/index.php/Standard_Memory_Expansions This latter 64k block mapping approach, which involves switching between 64k blocks, is being considered for another port inspired by the memory usage in the Cromemco port. -Two standard memory expansion sizes are supported: 512k and 1024k. To build the port with either of these options, simply define the macros EXTENDED_RAM_512 or EXTENDED_RAM_1024 depending on the desired size. If neither is defined, the build will default to supporting a swap partition on any of the supported disk types. +Two standard memory expansion sizes are supported: 512k and 1024k. To build the port with either of these options, simply define the macros EXTENDED_RAM_512 or EXTENDED_RAM_1024 depending on the desired size in the file config.h. If neither is defined, the build will default to supporting a swap partition on any of the supported disk types. ## STATUS From 79a61f0e60af4c13d22a6f9318d71c3fd45ddcb0 Mon Sep 17 00:00:00 2001 From: ajcasado Date: Wed, 22 Jan 2025 01:20:12 +0100 Subject: [PATCH 7/7] Correction of maximum number of proccesses for 512k ram expansion as swap --- Kernel/platform/platform-cpc6128/config.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Kernel/platform/platform-cpc6128/config.h b/Kernel/platform/platform-cpc6128/config.h index 8194de1997..c98d8d1416 100644 --- a/Kernel/platform/platform-cpc6128/config.h +++ b/Kernel/platform/platform-cpc6128/config.h @@ -77,8 +77,8 @@ #define TOTAL_SWAP_BLOCKS (1088-128) * 2 #endif #ifdef EXTENDED_RAM_512 - #define MAX_SWAPS 9 /*See platform devrd.c*/ - #define PTABSIZE 9 + #define MAX_SWAPS 8 /*See platform devrd.c*/ + #define PTABSIZE 8 #define TOTAL_SWAP_BLOCKS (576-128) * 2 #endif #if defined EXTENDED_RAM_512 || defined EXTENDED_RAM_1024