/* Banks as reported to user space */
#define CONFIG_BANKS 4
-#define TICKSPERSEC 20 /* Ticks per second */
+#define TICKSPERSEC 10 /* Ticks per second */
#define PROGBASE 0x0000 /* also data base */
#define PROGLOAD 0x0100 /* also data base */
#define PROGTOP 0xF000 /* Top of program, base of U_DATA copy */
#define KERNTOP 0xC000 /* Top of kernel (first 3 banks), base of shared bank */
#define PROC_SIZE 64 /* Memory needed per process */
-/* WRS: this is probably wrong -- we want to swap the full 64K minus the common code */
-/* For now let's just use something and fix this up later when we have a swap device */
+#define SWAPDEV (swap_dev) /* A variable for dynamic, or a device major/minor */
+extern unsigned int swap_dev;
#define SWAP_SIZE 0x79 /* 60.5K in blocks (prog + udata) */
#define SWAPBASE 0x0000 /* start at the base of user mem */
#define SWAPTOP 0xF200 /* Swap out udata and program */
-/* FIXME: do this off partition tables */
-#define MAX_SWAPS 10 /* Well, that depends really, hmmmmmm. Pick a number, any number. */
+#define MAX_SWAPS 16 /* We will size if from the partition */
+/* Swap will be set up when a suitably labelled partition is seen */
+#define CONFIG_DYNAMIC_SWAP
+
+/*
+ * When the kernel swaps something it needs to map the right page into
+ * memory using map_for_swap and then turn the user address into a
+ * physical address. For a simple banked setup there is no conversion
+ * needed so identity map it.
+ */
+#define swap_map(x) ((uint8_t *)((((x) & 0x3FFF)) + 0x4000))
/* We need a tidier way to do this from the loader */
#define CMDLINE NULL /* Location of root dev name */
#define BOOTDEVICENAMES "hd#,fd,,rd"
-//#define SWAPDEV (256 + 1) /* Device for swapping */
#define CONFIG_DYNAMIC_BUFPOOL /* we expand bufpool to overwrite the _DISCARD segment at boot */
#define NBUFS 4 /* Number of block buffers, keep in line with space reserved in zeta-v2.s */
#define NMOUNTS 4 /* Number of mounts at a time */
#define MAX_BLKDEV 4 /* 1 ROM disk, 1 RAM disk, 1 floppy, 1 IDE */
-#if 0 /* for now */
/* On-board DS1302, we can read the time of day from it */
#define CONFIG_RTC
-#define CONFIG_RTC_INTERVAL 30 /* deciseconds between reading RTC seconds counter */
-#endif
+#define CONFIG_RTC_FULL
+#define CONFIG_NO_CLOCK
/* Floppy support */
#define CONFIG_FLOPPY /* #define CONFIG_FLOPPY to enable floppy */
#include <printf.h>
#include <devtty.h>
#include <ds1302.h>
+#include <devide.h>
+#include <blkdev.h>
#include "config.h"
#include "devrd.h"
#include "vfd-term.h"
/* Everything in here is discarded after init starts */
-#ifdef CONFIG_PPIDE
-#include <devide.h>
-void ppide_init(void);
-#endif
-
void init_hardware_c(void)
{
// vfd_debug_init();
{
}
+/*
+ * This function is called for partitioned devices if a partition is found
+ * and marked as swap type. The first one found will be used as swap. We
+ * only support one swap device.
+ */
+void platform_swap_found(uint8_t letter, uint8_t m)
+{
+ blkdev_t *blk = blk_op.blkdev;
+ uint16_t n;
+ if (swap_dev != 0xFFFF)
+ return;
+ letter -= 'a';
+ kputs("(swap) ");
+ swap_dev = letter << 4 | m;
+ n = blk->lba_count[m - 1] / SWAP_SIZE;
+ if (n > MAX_SWAPS)
+ n = MAX_SWAPS;
+ while(n)
+ swapmap_add(n--);
+}
+
+
void device_init(void)
{
+ ds1302_init();
#ifdef CONFIG_IDE
devide_init();
#endif
platform-rc2014/devide_discard.rel
platform-rc2014/monitor.rel
platform-rc2014/devinput.rel
+platform-rc2014/ds1302.rel
+platform-rc2014/ds1302_discard.rel
+platform-rc2014/ds1302_rc2014.rel
-e
Z80_MMU_HOOKS .equ 0
+CONFIG_SWAP .equ 1
+
PROGBASE .equ 0x0000
PROGLOAD .equ 0x0100
#include <kernel.h>
#include <kdata.h>
#include <printf.h>
+#include <timer.h>
#include <devtty.h>
#include <devfd.h>
#include <devinput.h>
+#include <rtc.h>
+#include <ds1302.h>
extern unsigned char irqvector;
struct blkbuf *bufpool_end = bufpool + NBUFS; /* minimal for boot -- expanded after we're done with _DISCARD */
+uint8_t timermsr = 0;
+uint16_t swap_dev = 0xFFFF;
void platform_discard(void)
{
* Makes the HALT LED go yellow, which amuses me greatly. */
// __asm halt __endasm;
irqflags_t irq = di();
+ sync_clock();
+ /* FIXME: need to cover ACIA option.. */
tty_pollirq_sio();
irqrestore(irq);
}
// poll_input();
// timer_interrupt();
}
+ /* FIXME: need to cover ACIA option.. */
tty_pollirq_sio();
return;
}
+
+/*
+ * Logic for tickless system. If you have an RTC you can ignore this.
+ */
+
+static uint8_t newticks = 0xFF;
+static uint8_t oldticks;
+
+static uint8_t re_enter;
+
+/*
+ * Hardware specific logic to get the seconds. We really ought to enhance
+ * this to check minutes as well just in case something gets stuck for
+ * ages.
+ */
+static void sync_clock_read(void)
+{
+ uint8_t s;
+ oldticks = newticks;
+ ds1302_read_clock(&s, 1);
+ s = (s & 0x0F) + (((s & 0xF0) >> 4) * 10);
+ newticks = s;
+}
+
+/*
+ * The OS core will invoke this routine when idle (via platform_idle) but
+ * also after a system call and in certain other spots to ensure the clock
+ * is roughly valid. It may be called from interrupts, without interrupts
+ * or even recursively so it must protect itself using the framework
+ * below.
+ *
+ * Having worked out how much time has passed in 1/10ths of a second it
+ * performs that may timer_interrupt events in order to advance the clock.
+ * The core kernel logic ensures that we won't do anything silly from a
+ * jump forward of many seconds.
+ *
+ * We also choose to poll the ttys here so the user has some chance of
+ * getting control back on a messed up process.
+ */
+void sync_clock(void)
+{
+ if (!timermsr) {
+ irqflags_t irq = di();
+ int16_t tmp;
+ if (!re_enter++) {
+ sync_clock_read();
+ if (oldticks != 0xFF) {
+ tmp = newticks - oldticks;
+ if (tmp < 0)
+ tmp += 60;
+ tmp *= 10;
+ while(tmp--) {
+ timer_interrupt();
+ }
+ /* FIXME: need to cover ACIA option.. */
+ tty_pollirq_sio();
+ }
+ re_enter--;
+ }
+ irqrestore(irq);
+ }
+}
+
+/*
+ * This method is called if the kernel has changed the system clock. We
+ * don't work out how much work we need to do by using it as a reference
+ * so we don't care.
+ */
+void update_sync_clock(void)
+{
+}
.globl map_process_always
.globl map_save
.globl map_restore
+ .globl map_for_swap
.globl platform_interrupt_all
+ .globl _copy_common
.globl mpgsel_cache
.globl _kernel_pages
.globl _platform_reboot
ld a,#0x01
out (SIOA_C),a
- ld a,#0x1A ; Receive int mode 11, tx int enable (was $18)
+ ld a,#0x18;A? ; Receive int mode 11, tx int enable (was $18)
out (SIOA_C),a
ld a,#0x03
ld a,#0x01
out (SIOB_C),a
- ld a, #0x1A ; Receive int mode 11, tx int enable (was $18)
+ ld a, #0x18;A? ; Receive int mode 11, tx int enable (was $18)
out (SIOB_C),a
ld a,#0x02
; If you don't have a CTC probably nothing bad will happen, other than
; your floppy not working.
- ld a,#0x57 ; counter mode, disable interrupts
- out (CTC_CH0),a ; set CH0 mode
- ld a,#0 ; time constant = 256
- out (CTC_CH0),a ; set CH0 time constant
- ld a,#0xC7 ; counter mode, enable interrupts
- out (CTC_CH1),a ; set CH1 mode
- ld a,#180 ; time constant = 180
- out (CTC_CH1),a ; set CH1 time constant
+; ld a,#0x57 ; counter mode, disable interrupts
+; out (CTC_CH0),a ; set CH0 mode
+; ld a,#0 ; time constant = 256
+; out (CTC_CH0),a ; set CH0 time constant
+; ld a,#0xC7 ; counter mode, enable interrupts
+; out (CTC_CH1),a ; set CH1 mode
+; ld a,#180 ; time constant = 180
+; out (CTC_CH1),a ; set CH1 time constant
; Done CTC Stuff
; ---------------------------------------------------------------------
pop hl
ret
+;=========================================================================
+; map_for_swap - map a page into a bank for swap I/O
+; Inputs: none
+; Outputs: none
+;
+; The caller will later map_kernel to restore normality
+;
+; We use 0x4000-0x7FFF so that all the interrupt stuff is mapped.
+;
+;=========================================================================
+map_for_swap:
+ ld (mpgsel_cache + 1),a
+ out (MPGSEL_1),a
+ ret
+
+_copy_common:
+ pop hl
+ pop de
+ push de
+ push hl
+ ld a,e
+ call map_for_swap
+ ld hl,#0xF300
+ ld de,#0x7300
+ ld bc,#0x0D00
+ ldir
+ jr map_kernel
+
+
; MPGSEL registers are read only, so their content is cached here
mpgsel_cache:
.db 0,0,0,0