; exported symbols
.globl z180_init_hardware
.globl z180_init_early
+ .globl _init_hardware_c
.globl _program_vectors
.globl _copy_and_map_process
.globl interrupt_table ; not used elsewhere but useful to check correct alignment
; Enable external interrupts (INT0/INT1/INT2)
ld a, #0x87
out0 (INT_ITC), a
- ret
+
+ jp _init_hardware_c
; -----------------------------------------------------------------------------
; KERNEL MEMORY BANK (only accessible when the kernel is mapped)
--- /dev/null
+; 2017-01-04 William R Sowerbutts
+
+ .module devrd_hw
+ .z180
+
+ ; exported symbols
+ .globl _rd_platform_copy
+ .globl _rd_cpy_count
+ .globl _rd_reverse
+ .globl _rd_dst_userspace
+ .globl _rd_dst_address
+ .globl _rd_src_address
+ .globl _devmem_read
+ .globl _devmem_write
+
+ .include "kernel.def"
+ .include "../kernel.def"
+ .include "../cpu-z180/z180.def"
+
+ .area _CODE
+_devmem_write:
+ ld a, #1
+ ld (_rd_reverse), a ; 1 = write
+ jr _devmem_go
+
+_devmem_read:
+ xor a
+ ld (_rd_reverse), a ; 0 = read
+ inc a
+_devmem_go:
+ ld (_rd_dst_userspace), a ; 1 = userspace
+ ; load the other parameters
+ ld hl, (U_DATA__U_BASE)
+ ld (_rd_dst_address), hl
+ ld hl, (U_DATA__U_COUNT)
+ ld (_rd_cpy_count), hl
+ ld hl, (U_DATA__U_OFFSET)
+ ld (_rd_src_address), hl
+ ld hl, (U_DATA__U_OFFSET+2)
+ ld (_rd_src_address+2), hl
+ ; FALL THROUGH INTO _rd_platform_copy
+
+;=========================================================================
+; _rd_page_copy - Copy data from one physical page to another
+; See notes in devrd.h for input parameters
+;=========================================================================
+_rd_platform_copy:
+ ; save interrupt flag on stack then disable interrupts
+ ld a, i
+ push af
+ di
+
+ ; load source page number
+ ld de, (_rd_src_address+1) ; and +2
+ ld a, (_rd_src_address+0)
+ ld b, a
+
+ ; compute destination
+ ld a,(_rd_dst_userspace) ; are we loading into userspace memory?
+ or a
+ jr nz, rd_translate_userspace
+ ld hl, #(OS_BANK + FIRST_RAM_BANK) << 4
+ jr rd_done_translate
+rd_translate_userspace:
+ ld hl,(U_DATA__U_PAGE) ; load page number
+ add hl, hl ; shift left 4 bits
+ add hl, hl
+ add hl, hl
+ add hl, hl
+rd_done_translate:
+ ; add in page offset
+ ld a,(_rd_dst_address+1) ; top 8 bits of address
+ add a, l
+ ld l, a
+ adc a, h
+ sub l
+ ld h, a ; result in hl
+ ld a,(_rd_dst_address+0)
+ ld c, a
+
+ ld a,(_rd_reverse)
+ or a
+ jr z,not_reversed
+
+ ex de, hl
+ out0 (DMA_SAR0L),c
+ out0 (DMA_DAR0L),b
+ jr topbits
+not_reversed:
+ out0 (DMA_SAR0L),b
+ out0 (DMA_DAR0L),c
+topbits:
+ out0 (DMA_SAR0B),d
+ out0 (DMA_SAR0H),e
+ out0 (DMA_DAR0B),h
+ out0 (DMA_DAR0H),l
+
+ ld hl,(_rd_cpy_count)
+ out0 (DMA_BCR0L),l
+ out0 (DMA_BCR0H),h
+
+ ; make dma go
+ ld bc, #0x0240
+ out0 (DMA_DMODE), b ; 0x02 - memory to memory, burst mode
+ out0 (DMA_DSTAT), c ; 0x40 - enable DMA channel 0
+ ; CPU stalls until DMA burst completes
+
+ ; recover interrupt flag from stack and restore ints if required
+ pop af
+ ret po
+ ei
+ ret ; return with HL=_rd_cpy_count, as required by char device drivers
+
+; variables
+_rd_cpy_count:
+ .dw 0 ; uint16_t
+_rd_reverse:
+ .db 0 ; bool
+_rd_dst_userspace:
+ .db 0 ; bool
+_rd_dst_address:
+ .dw 0 ; uint16_t
+_rd_src_address:
+ .db 0 ; uint32_t
+ .db 0
+ .db 0
+ .db 0
+;=========================================================================
CSRCS += devices.c main.c devtty.c devsdspi.c
DISCARD_CSRCS = discard.c
DISCARD_DSRCS = ../dev/devide_discard.c ../dev/devsd_discard.c ../dev/ds1302_discard.c
-DSRCS = ../dev/devide.c ../dev/devsd.c ../dev/mbr.c ../dev/blkdev.c ../dev/ds1302.c
+DSRCS = ../dev/devide.c ../dev/devsd.c ../dev/mbr.c ../dev/blkdev.c ../dev/ds1302.c ../dev/devrd.c
+DASRCS = ../dev/devrd_hw.s ../dev/devrd_z180_hw.s
AOBJS = $(ASRCS:.s=.rel)
COBJS = $(CSRCS:.c=.rel)
DISCARD_COBJS = $(DISCARD_CSRCS:.c=.rel)
DISCARD_DOBJS = $(patsubst ../dev/%.c,%.rel, $(DISCARD_DSRCS))
DOBJS = $(patsubst ../dev/%.c,%.rel, $(DSRCS))
+DAOBJS = $(patsubst ../dev/%.s,%.rel, $(DASRCS))
-OBJS = $(AOBJS) $(COBJS) $(DOBJS) $(DISCARD_DOBJS) $(DISCARD_COBJS)
+OBJS = $(AOBJS) $(COBJS) $(DOBJS) $(DISCARD_DOBJS) $(DISCARD_COBJS) $(DAOBJS)
CROSS_CCOPTS += -I../dev/
$(DOBJS): %.rel: ../dev/%.c
$(CROSS_CC) $(CROSS_CCOPTS) -c $<
+$(DAOBJS): %.rel: ../dev/%.s
+ $(CROSS_AS) $(ASOPTS) $@ $<
+
$(DISCARD_COBJS): %.rel: %.c
$(CROSS_CC) $(CROSS_CCOPTS) $(CROSS_CC_SEGDISC) -c $<
/* We need a tidier way to do this from the loader */
#define CMDLINE (0x0081) /* Location of root dev name */
-#define BOOTDEVICENAMES "hd#"
+#define BOOTDEVICENAMES "hd#,,,rd"
#define NBUFS 10 /* Number of block buffers */
#define NMOUNTS 4 /* Number of mounts at a time */
#define CONFIG_RTC
#define CONFIG_RTC_INTERVAL 30 /* deciseconds between reading RTC seconds counter */
+/* Memory backed devices */
+#define CONFIG_DEV_MEM /* enable /dev/mem driver */
+#define CONFIG_RAMDISK /* enable memory-backed device driver */
+#define DEV_RD_ROM_PAGES 64 /* size of the ROM disk (/dev/rd0) in 4KB pages */
+#define DEV_RD_RAM_PAGES 0 /* size of the RAM disk (/dev/rd1) in 4KB pages */
+
+#define DEV_RD_ROM_START ((uint32_t)(128-DEV_RD_ROM_PAGES) << 12)
+#define DEV_RD_RAM_START ((uint32_t)(256-DEV_RD_RAM_PAGES) << 12)
+#define DEV_RD_ROM_SIZE ((uint32_t)DEV_RD_ROM_PAGES << 12)
+#define DEV_RD_RAM_SIZE ((uint32_t)DEV_RD_RAM_PAGES << 12)
+
/* Optional PropIOv2 board on ECB bus */
//#define CONFIG_PROPIO2 /* #define CONFIG_PROPIO2 to enable as tty3 */
#define PROPIO2_IO_BASE 0xA8
#include <devsys.h>
#include <devtty.h>
#include <devide.h>
+#include <devrd.h>
#include <devsd.h>
#include <blkdev.h>
#include <ds1302.h>
{ blkdev_open, no_close, blkdev_read, blkdev_write, blkdev_ioctl }, /* 0: /dev/hd -- standard block device interface */
{ no_open, no_close, no_rdwr, no_rdwr, no_ioctl }, /* 1: unused slot */
{ tty_open, tty_close, tty_read, tty_write, tty_ioctl }, /* 2: /dev/tty -- serial ports */
- { no_open, no_close, no_rdwr, no_rdwr, no_ioctl }, /* 3: unused slot */
+ { rd_open, no_close, rd_read, rd_write, no_ioctl }, /* 3: /dev/rd? */
{ no_open, no_close, sys_read, sys_write, sys_ioctl }, /* 4: /dev/mem etc System devices (one offs) */
};
#include "config.h"
#include <z180.h>
+void init_hardware_c(void)
+{
+ ramsize = 512;
+ procmem = 512 - 64 - (DEV_RD_RAM_PAGES<<2);
+}
+
void pagemap_init(void)
{
int i;
* First 64K is used by the kernel.
* Each process gets the full 64K for now.
* Page size is 4KB. */
- for(i = 0x90; i < 0x100; i+=0x10)
+ for(i = 0x90; i < ((1024 - (DEV_RD_RAM_PAGES<<2))>>2); i+=0x10)
pagemap_add(i);
}
platform-n8vem-mark4/devtty.rel
platform-n8vem-mark4/devide.rel
platform-n8vem-mark4/devide_discard.rel
+platform-n8vem-mark4/devrd.rel
+platform-n8vem-mark4/devrd_hw.rel
+platform-n8vem-mark4/devrd_z180_hw.rel
platform-n8vem-mark4/devsd.rel
platform-n8vem-mark4/devsd_discard.rel
platform-n8vem-mark4/devsdspi.rel
; N8VEM Mark IV mnemonics
FIRST_RAM_BANK .equ 0x80 ; low 512K of physical memory is ROM/ECB window.
-RAM_KB .equ 512
Z180_IO_BASE .equ 0x40
MARK4_IO_BASE .equ 0x80
; imported symbols
.globl z180_init_hardware
.globl z180_init_early
- .globl _ramsize
- .globl _procmem
.globl outhl
.globl outnewline
jp z180_init_early
init_hardware:
- ; set system RAM size
- ld hl, #RAM_KB
- ld (_ramsize), hl
- ld hl, #(RAM_KB-64) ; 64K for kernel
- ld (_procmem), hl
-
; enable ASCI interrupts
in0 a, (ASCI_STAT0)
or #0x08 ; enable ASCI0 receive interrupts
DISCARD_DSRCS = ../dev/devide_discard.c ../dev/ds1302_discard.c
DSRCS = ../dev/blkdev.c ../dev/devide.c ../dev/devfd.c ../dev/mbr.c
DSRCS += ../dev/ds1302.c
-DASRCS = ../dev/devfd_hw.s
+DSRCS += ../dev/devrd.c
+DASRCS = ../dev/devfd_hw.s ../dev/devrd_hw.s ../dev/devrd_z180_hw.s
AOBJS = $(ASRCS:.s=.rel)
COBJS = $(CSRCS:.c=.rel)
#define CONFIG_RTC
#define CONFIG_RTC_INTERVAL 30 /* deciseconds between reading RTC seconds counter */
+/* Memory backed devices */
+#define CONFIG_DEV_MEM /* enable /dev/mem driver */
+#define CONFIG_RAMDISK /* enable memory-backed device driver */
+#define DEV_RD_ROM_PAGES 0 /* ROM is too small on this platform -- only 32KB */
+#define DEV_RD_RAM_PAGES 0 /* size of the RAM disk (/dev/rd1) in 4KB pages */
+
+#define DEV_RD_ROM_START 0 /* ROM is too small on this platform -- only 32KB */
+#define DEV_RD_ROM_SIZE 0
+#define DEV_RD_RAM_START ((uint32_t)(256-DEV_RD_RAM_PAGES) << 12)
+#define DEV_RD_RAM_SIZE ((uint32_t)DEV_RD_RAM_PAGES << 12)
+
/* We have the P112 floppy controller */
#define CONFIG_P112_FLOPPY
#include <devide.h>
#include <blkdev.h>
#include <ds1302.h>
+#include <devrd.h>
#ifdef CONFIG_P112_FLOPPY
#include <devfd.h>
#endif
{ no_open, no_close, no_rdwr, no_rdwr, no_ioctl }, /* 1: unused slot */
#endif
{ tty_open, tty_close, tty_read, tty_write, tty_ioctl }, /* 2: /dev/tty -- serial ports */
- { no_open, no_close, no_rdwr, no_rdwr, no_ioctl }, /* 3: unused slot */
+ { rd_open, no_close, rd_read, rd_write, no_ioctl }, /* 3: /dev/rd?, /dev/physmem -- memory backed devices */
{ no_open, no_close, sys_read, sys_write, sys_ioctl }, /* 4: /dev/mem etc System devices (one offs) */
};
#include <devide.h>
#include <ds1302.h>
+void init_hardware_c(void)
+{
+ ramsize = 1024;
+ procmem = 1024 - 64 - (DEV_RD_RAM_PAGES<<2);
+}
+
void pagemap_init(void)
{
int i;
* First 64K is used by the kernel.
* Each process gets the full 64K for now.
* Page size is 4KB. */
- for(i = 0x10; i < 0x100; i+=0x10){
+ for(i = 0x10; i < ((1024 - (DEV_RD_RAM_PAGES<<2))>>2); i+=0x10)
pagemap_add(i);
- }
}
void map_init(void)
platform-p112/devtty.rel
platform-p112/devide.rel
platform-p112/devide_discard.rel
+platform-p112/devrd.rel
+platform-p112/devrd_hw.rel
+platform-p112/devrd_z180_hw.rel
platform-p112/blkdev.rel
platform-p112/mbr.rel
platform-p112/ds1302.rel
; P112
FIRST_RAM_BANK .equ 0x00 ; all memory is RAM on P112
-RAM_KB .equ 1024
Z180_IO_BASE .equ 0x00
Z80_TYPE .equ 2
; imported symbols
.globl z180_init_hardware
.globl z180_init_early
- .globl _ramsize
- .globl _procmem
.globl outhl
.globl outnewline
jp z180_init_early
init_hardware:
- ; set system RAM size
- ld hl, #RAM_KB
- ld (_ramsize), hl
- ld hl, #(RAM_KB-64) ; 64K for kernel
- ld (_procmem), hl
-
; configure ASCI UART
; in0 a, (ASCI_STAT0)
; or #0x08 ; enable ASCI0 receive interrupts