+++ /dev/null
-
-DSRCS = ../dev/z80pack/devlpr.c ../dev/z80pack/devtty.c ../dev/z80pack/devfd.c
-CSRCS += devices.c main.c
-
-ASRCS = crt0.s z80pack.s
-ASRCS += tricks.s commonmem.s
-
-AOBJS = $(ASRCS:.s=.rel)
-COBJS = $(CSRCS:.c=.rel)
-DOBJS = $(patsubst ../dev/z80pack/%.c,%.rel, $(DSRCS))
-
-OBJS = $(AOBJS) $(COBJS) $(DOBJS)
-
-CROSS_CCOPTS += -I../dev/z80pack/ --codeseg CODE3
-
-JUNK = *.rel *.lst *.asm *.sym *.rst
-
-all: $(OBJS)
-
-$(AOBJS): %.rel: %.s
- $(CROSS_AS) $(ASOPTS) $<
-
-$(COBJS): %.rel: %.c
- $(CROSS_CC) $(CROSS_CCOPTS) -c $<
-
-$(DOBJS): %.rel: ../dev/z80pack/%.c
- $(CROSS_CC) $(CROSS_CCOPTS) -c $<
-
-
-clean:
- rm -f $(OBJS) $(JUNK) core *~
-
-image:
- sdasz80 -o bootblock.s
- sdldz80 -m -i bootblock.rel
- makebin -s 128 bootblock.ihx > bootblock.bin
+++ /dev/null
-Z80 Pack Test For 32K + cached high for bigger binaries
-
-Kernel
-0000-07FFF CODE1, CODE2
-0x8000-0xBFFF User cache area (0xB000 discard)
-0xC000 Udata
-0xC300 CONST, CODE3, DATA ...
-0xF000 Common
-
-TODO
-
-We waste 16K per high process but its not clear how much of a win it would
-be to pack them, and if we can squash stuff better we might go over 48K and
-break it.
-
-binman has no idea how to pack such an image, probably better to have a new
-tool as binman is getting too unwieldy. Perhaps it's time to have a tool and
-crt0.s that simply reads a table of block/offsets to ldir then runs ?
-
-Also need to pack carefully so we don't overwrite source data. Probably
-means we need to start at the end of the image and lddr back down it.
-
-Need to fix the packing/crt0.s before we can test any of this
-
-
-Disk swap device recommended
-
-Put the kernel at the end of a floppy image from cyl 60
-Add the fs in the first 60 cyls (390 blocks)
-
-Put the bootblock in sector 0
-
-dd the kernel image to offset 199680
-
-ie
-
-dd if=fuzix.bin of=drivea.cpm bs=1 seek=199680 conv=notrunc
+++ /dev/null
-;
-; Z80pack cpmsim loads the first (128 byte) sector from the disk
-; into memory at 0 then executes it
-; We are a bit tight on space here
-;
-; Floppy loader:
-; Our boot disc is 77 tracks of 26 x 128 byte sectors, and we put
-; the OS on tracks 60+, which means we can put a file system in the
-; usual place providing its a bit smaller than a whole disc.
-;
-;
-; assemble with sdasz80
-;
- .area ASEG(ABS)
- .org 0
-
-start: jr diskload
-
-rootdev: .dw 0 ; patched by hand
-swapdev: .dw 0 ; ditto
- .dw 0 ; spare
-
-progress: .db '/', '-', '\', '|'
-
-diskload: di
- ld sp, #stack
- ld hl, #0x88
- exx
- xor a
- ld h, a
- ld b, a
- out (17), a ; sector high always 0
- out (10), a ; drive always 0
- ld a, #59 ; start on track 60
- out (11), a
- exx
- ld c, #17 ; number of tracks to load (56Kish)
-load_tracks: in a, (11)
- inc a ; track
- out (11), a
- xor a
- out (12), a
- ld b, #26 ; sectors
-load_sectors: exx
- ld a, b
- and #3
- add #progress
- ld l, a
- ld a, (hl)
- out (01), a
- ld a, #8
- out (01), a
- inc b
- exx
-
- in a, (12)
- inc a
- out (12), a ; sector
- ld a, l
- out (15), a ; dma low
- ld a, h
- out (16), a ; dma high
- xor a ; read
- out (13), a ; go
- in a, (14) ; status
- ld de, #128
- add hl, de
- djnz load_sectors ; 26 sectors = 3328 bytes
- dec c
- jr nz, load_tracks
- ld a, #0xc9 ; to help debug
- ld (start), a
- ld a, #13
- out (1), a
- ld a, #10
- out (1), a
- jp 0x88
-
- .ds 26
-stack:
- .db 0xff
+++ /dev/null
-;
-; Common on z80pack is at 0xF000 as defined by hardware.
-;
-
- .module commonmem
-
- .area _COMMONMEM
-
- .include "../cpu-z80/std-commonmem.s"
+++ /dev/null
-/* 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
-/* Single tasking */
-#undef CONFIG_SINGLETASK
-/* CP/M emulation */
-#undef CONFIG_CPM_EMU
-/* 32K banking */
-#define CONFIG_BANK32
-/* but with the high block copied on switch as needed */
-#define CONFIG_COMMON_COPY
-/* 8 32K banks, 1 is kernel */
-#define MAX_MAPS 7
-#define MAP_SIZE 0x8000U
-
-/* Banks as reported to user space */
-#define CONFIG_BANKS 2
-
-#define TICKSPERSEC 100 /* Ticks per second */
-#define PROGBASE 0x0000 /* also data base */
-#define PROGLOAD 0x0100 /* also data base */
-#define PROGTOP 0xBC00 /* Top of program, base of U_DATA copy */
-
-#define SWAP_SIZE 0x60 /* 48K in blocks */
-#define SWAPBASE 0x0000 /* We swap the lot in one, include the */
-#define SWAPTOP 0xC000 /* vectors so its a round number of sectors */
-#define MAX_SWAPS 64 /* The full drive would actually be 85! */
-
-#define BOOT_TTY (512 + 1)/* 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 3
-
-#define TTYDEV BOOT_TTY /* Device used by kernel for messages, panics */
-#define SWAPDEV (256 + 1) /* Device for swapping. (z80pack drive J) */
-#define NBUFS 10 /* Number of block buffers */
-#define NMOUNTS 4 /* Number of mounts at a time */
+++ /dev/null
-; 2013-12-18 William R Sowerbutts
-
- .module crt0
-
- ; Ordering of segments for the linker.
- ; WRS: Note we list all our segments here, even though
- ; we don't use them all, because their ordering is set
- ; when they are first seen.
- .area _CODE
- .area _CODE2
- .area _CODE3
- .area _CONST
- .area _INITIALIZED
- .area _DATA
- .area _BSEG
- .area _BSS
- .area _HEAP
- ; note that areas below here may be overwritten by the heap at runtime, so
- ; put initialisation stuff in here
- .area _INITIALIZER
- .area _GSINIT
- .area _GSFINAL
- .area _DISCARD
- .area _COMMONMEM
-
- ; imported symbols
- .globl _fuzix_main
- .globl init_early
- .globl init_hardware
- .globl s__INITIALIZER
- .globl s__COMMONMEM
- .globl l__COMMONMEM
- .globl s__DISCARD
- .globl l__DISCARD
- .globl s__DATA
- .globl l__DATA
- .globl kstack_top
-
- ; startup code
- .area _CODE
-init:
- di
- ld sp, #kstack_top
-
- ; Configure memory map
- call init_early
-
- ; move the common memory where it belongs
- ld hl, #s__INITIALIZER
- ld de, #s__COMMONMEM
- ld bc, #l__COMMONMEM
- ldir
- ; and the discard
- ld de, #s__DISCARD
- ld bc, #l__DISCARD
- ldir
- ; then zero the data area
- ld hl, #s__DATA
- ld de, #s__DATA + 1
- ld bc, #l__DATA - 1
- ld (hl), #0
- ldir
-
- ; 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
-
+++ /dev/null
-#include <kernel.h>
-#include <version.h>
-#include <kdata.h>
-#include <tty.h>
-#include <devfd.h>
-#include <devsys.h>
-#include <devlpr.h>
-#include <devtty.h>
-
-struct devsw dev_tab[] = /* The device driver switch table */
-{
-// minor open close read write ioctl
-// -----------------------------------------------------------------
- /* 0: /dev/fd Floppy disc block devices */
- { fd_open, no_close, fd_read, fd_write, no_ioctl },
- /* 1: /dev/hd Hard disc block devices (absent) */
- { hd_open, no_close, hd_read, hd_write, no_ioctl },
- /* 2: /dev/tty TTY devices */
- { tty_open, tty_close, tty_read, tty_write, tty_ioctl },
- /* 3: /dev/lpr Printer devices */
- { lpr_open, lpr_close, no_rdwr, lpr_write, no_ioctl },
- /* 4: /dev/mem etc System devices (one offs) */
- { no_open, no_close, sys_read, sys_write, sys_ioctl },
- /* Pack to 7 with nxio if adding private devices and start at 8 */
-};
-
-bool validdev(uint16_t dev)
-{
- /* This is a bit uglier than needed but the right hand side is
- a constant this way */
- if(dev > ((sizeof(dev_tab)/sizeof(struct devsw)) << 8) - 1)
- return false;
- else
- return true;
-}
-
-void device_init(void)
-{
- int i;
- /* Add 64 swaps (4MB) to use the entire J drive */
- for (i = 0; i < MAX_SWAPS; i++)
- swapmap_init(i);
-}
+++ /dev/null
--mwxuy
--i fuzix.ihx
--b _CODE=0x0088
--b _CODE3=0xC000
--b _COMMONMEM=0xF000
--b _DISCARD=0xB000
--l z80
-platform-z80pack32/crt0.rel
-platform-z80pack32/commonmem.rel
-platform-z80pack32/z80pack.rel
-platform-z80pack32/main.rel
-start.rel
-version.rel
-lowlevel-z80.rel
-usermem_std-z80.rel
-platform-z80pack32/tricks.rel
-timer.rel
-kdata.rel
-usermem.rel
-platform-z80pack32/devfd.rel
-platform-z80pack32/devices.rel
-devio.rel
-filesys.rel
-process.rel
-inode.rel
-syscall_exec16.rel
-syscall_fs.rel
-syscall_fs2.rel
-syscall_proc.rel
-syscall_other.rel
-tty.rel
-mm.rel
-bank32k.rel
-swap.rel
-devsys.rel
-platform-z80pack32/devlpr.rel
-platform-z80pack32/devtty.rel
--e
+++ /dev/null
-; UZI mnemonics for memory addresses etc
-
-U_DATA .equ 0xF000 ; (this is struct u_data from kernel.h)
-U_DATA__TOTALSIZE .equ 0x200 ; 256+256+256 bytes.
-
-U_STASH_HIGH .equ 0xBE00 ; BE00-BFFF
-U_STASH_LOW .equ 0x7E00 ; 7E00-BFFF
-
-
-Z80_TYPE .equ 0
-
-PROGBASE .equ 0x0000
-PROGLOAD .equ 0x0100
+++ /dev/null
-#include <kernel.h>
-#include <timer.h>
-#include <kdata.h>
-#include <printf.h>
-#include <devtty.h>
-
-uint16_t ramtop = PROGTOP;
-
-
-void pagemap_init(void)
-{
- int i;
- for (i = 1; i < 8; i++)
- pagemap_add(i);
-}
-
-/* On idle we spin checking for the terminals. Gives us more responsiveness
- for the polled ports */
-void platform_idle(void)
-{
- /* We don't want an idle poll and IRQ driven tty poll at the same moment */
- irqflags_t irq = di();
- tty_pollirq();
- irqrestore(irq);
-}
-
-void platform_interrupt(void)
-{
- tty_pollirq();
- timer_interrupt();
-}
-
-/* Nothing to do for the map of init */
-void map_init(void)
-{
-}
+++ /dev/null
-; 2013-12-21 William R Sowerbutts
-
- .module tricks
-
- .globl _ptab_alloc
- .globl _newproc
- .globl _chksigs
- .globl _getproc
- .globl _platform_monitor
- .globl trap_illegal
- .globl _inint
- .globl _platform_switchout
- .globl _switchin
- .globl _doexec
- .globl _dofork
- .globl _runticks
- .globl unix_syscall_entry
- .globl interrupt_handler
- .globl dispatch_process_signal
- .globl _swapper
- .globl _cached_page
- .globl _flush_cache
- .globl _invalidate_cache
-
- ; imported debug symbols
- .globl outstring, outde, outhl, outbc, outnewline, outchar, outcharhex
-
- .include "kernel.def"
- .include "../kernel.def"
-
- .area _COMMONMEM
-
-; Switchout switches out the current process, finds another that is READY,
-; possibly the same process, and switches it in. When a process is
-; restarted after calling switchout, it thinks it has just returned
-; from switchout().
-_platform_switchout:
- di
- ; save machine state
-
- ld hl, #0 ; return code set here is ignored, but _switchin can
- ; return from either _switchout OR _dofork, so they must both write
- ; U_DATA__U_SP with the following on the stack:
- push hl ; return code
- push ix
- push iy
- ld (U_DATA__U_SP), sp ; this is where the SP is restored in _switchin
-
- ; set inint to false
- xor a
- ld (_inint), a
-
- ; Stash the uarea back into process memory
- ld hl, (U_DATA__U_PAGE)
- ld a, l
- out (21), a
- cp h ; small or large process ?
- jr z, switchoutlow
- ld de, #U_STASH_HIGH
-switchoutlow:
- ld hl, #U_DATA
- ld de, #U_STASH_LOW
- ld bc, #U_DATA__TOTALSIZE
- ldir
- xor a
- out (21), a
-
- ; find another process to run (may select this one again)
- call _getproc
-
- push hl
- call _switchin
-
- ; we should never get here
- call _platform_monitor
-
-badswitchmsg: .ascii "_switchin: FAIL"
- .db 13, 10, 0
-swapped: .ascii "_switchin: SWAPPED"
- .db 13, 10, 0
-
-_switchin:
- di
- pop bc ; return address
- pop de ; new process pointer
-;
-; FIXME: do we actually *need* to restore the stack !
-;
- push de ; restore stack
- push bc ; restore stack
-
- xor a
- out (21), a
-
- push de
- ld hl, #P_TAB__P_PAGE_OFFSET
- add hl, de ; process ptr
- pop de
-
- ld a, (hl)
-
- or a
- jr nz, not_swapped
-
- ;
- ; We are still on the departing processes stack, which is
- ; fine for now.
- ;
- ld sp, #_swapstack
- push hl
- push de
- call _swapper
- pop de
- pop hl
- ld a, (hl)
-
-not_swapped:
- ; Decide where the uarea stash lives right now and check the cache
- inc hl
- cp (hl) ; must cp first as (hl) vanishes on the out
- jr z, switchinlow
- ld hl, #_cached_page
- cp (hl)
- push af
- call z, update_cache
- pop af
- out (21), a
- exx ; thank goodness for exx 8)
- ld hl, #U_STASH_HIGH
- jr switchin_page
-switchinlow:
- ; Pages please !
- out (21), a
- exx ; thank goodness for exx 8)
- ld hl, #U_STASH_LOW
-switchin_page:
- ; bear in mind that the stack will be switched now, so we can't use it
- ; to carry values over this point
- ld de, #U_DATA
- ld bc, #U_DATA__TOTALSIZE
- ldir
- exx
-
- ; Return to kernel mappings
- xor a
- out (21), a
-
-switchlow2:
-
- ; check u_data->u_ptab matches what we wanted
- ld hl, (U_DATA__U_PTAB) ; u_data->u_ptab
- or a ; clear carry flag
- sbc hl, de ; subtract, result will be zero if DE==IX
- jr nz, switchinfail
-
- ; wants optimising up a bit
- ld ix, (U_DATA__U_PTAB)
- ; next_process->p_status = P_RUNNING
- ld P_TAB__P_STATUS_OFFSET(ix), #P_RUNNING
-
- ; Fix the moved page pointers
- ; Just do two bytes as that is all we use on this platform
- ld l, P_TAB__P_PAGE_OFFSET(ix)
- ld h, P_TAB__P_PAGE_OFFSET+1(ix)
- ld (U_DATA__U_PAGE), hl
- ; runticks = 0
- ld hl, #0
- ld (_runticks), hl
-
- ; restore machine state -- note we may be returning from either
- ; _switchout or _dofork
- ld sp, (U_DATA__U_SP)
-
- pop iy
- pop ix
- pop hl ; return code
-
- ; enable interrupts, if the ISR isn't already running
- ld a, (U_DATA__U_ININTERRUPT)
- ld (_int_disabled),a
- or a
- ret z ; in ISR, leave interrupts off
- ei
- ret ; return with interrupts on
-
-switchinfail:
- call outhl
- ld hl, #badswitchmsg
- call outstring
- ; something went wrong and we didn't switch in what we asked for
- jp _platform_monitor
-
-; (hl) points to cached page ptr, a is desired page
-update_cache:
- ld (hl), a
- ld hl, #0
- ld de, #0x8000
- ld bc, #0x7D00
- ; map that page low (interrupts *must* be off)
- out (21), a
- ldir
- ; put the kernel back
- xor a
- out (21), a
- ret
-
-;
-; Invalidate a freed page - cache becomes void
-;
-_invalidate_cache:
- pop de
- pop hl
- push hl
- push de
- ld a, (_cached_page)
- cp l
- ret nz
- ld a, #0xff
- ld (_cached_page), a
- ret
-
-
-_flush_cache: ; argument is the process it may apply to
- pop de
- pop hl
- push hl
- push de
- ld a, (_int_disabled)
- push af
- ld de, #P_TAB__P_PAGE_OFFSET + 1
- add hl, de
- ld a, (_cached_page)
- cp (hl)
- jr nz, flush_none
- di
- call flush_cache_self
- pop af
- or a
- ret nz
- ei
- ret
-flush_none:
- pop af
- ret
-
-; interrupts must be disabled
-flush_cache_self:
- push af
- ld a, (_cached_page)
- cp #0xff
- jr z, no_cache
- push bc
- push de
- push hl
- ld hl, #0x8000 ; copy into the page
- ld de, #0
- ld bc, #0x7D00
- ; map that page low (interrupts *must* be off)
- out (21), a
- ldir
- ; put the kernel back
- xor a
- out (21), a
- pop hl
- pop de
- pop bc
-no_cache:
- pop af
- ret
-
-fork_proc_ptr: .dw 0 ; (C type is struct p_tab *) -- address of child process p_tab entry
-
-;
-; Called from _fork. We are in a syscall, the uarea is live as the
-; parent uarea. The kernel is the mapped object.
-;
-_dofork:
- ; always disconnect the vehicle battery before performing maintenance
- di ; should already be the case ... belt and braces.
-
- pop de ; return address
- pop hl ; new process p_tab*
- push hl
- push de
-
- ld (fork_proc_ptr), hl
-
- ; prepare return value in parent process -- HL = p->p_pid;
- ld de, #P_TAB__P_PID_OFFSET
- add hl, de
- ld a, (hl)
- inc hl
- ld h, (hl)
- ld l, a
-
- ; Save the stack pointer and critical registers.
- ; When this process (the parent) is switched back in, it will be as if
- ; it returns with the value of the child's pid.
- push hl ; HL still has p->p_pid from above, the return value in the parent
- push ix
- push iy
-
- ; save kernel stack pointer -- when it comes back in the parent we'll be in
- ; _switchin which will immediately return (appearing to be _dofork()
- ; returning) and with HL (ie return code) containing the child PID.
- ; Hurray.
- ld (U_DATA__U_SP), sp
-
- ; now we're in a safe state for _switchin to return in the parent
- ; process.
- ; --------- copy process ---------
-
- ld hl, (fork_proc_ptr)
- ld de, #P_TAB__P_PAGE_OFFSET
- add hl, de
- ; load p_page
- ld c, (hl)
- inc hl
- ; load p_page + 1 (high page)
- ld b, (hl)
- push af
- ld a, c
- call outcharhex
- pop af
- ; load existing page ptr
- ld a, (U_DATA__U_PAGE)
-
- call bankfork ; do the bank to bank copy
-
- ; Copy done
-
- ld a, (U_DATA__U_PAGE) ; parent memory
- out (21), a ; Switch context to parent
-
- ; We are going to copy the uarea into the parents uarea stash
- ; we must not touch the parent uarea after this point, any
- ; changes only affect the child
- ld de, #U_STASH_LOW ; parent location
- ld hl, #U_DATA__U_PAGE
- ld a, (hl)
- inc hl
- cp (hl)
- jr z, stash_low
- ld de, #U_STASH_HIGH ; high stash
-stash_low:
- ld hl, #U_DATA ; copy the udata from common
- ld bc, #U_DATA__TOTALSIZE
- ldir
- ; Return to the kernel mapping
- xor a
- out (21), a
- ; now the copy operation is complete we can get rid of the stuff
- ; _switchin will be expecting from our copy of the stack.
- pop bc
- pop bc
- pop bc
-
- ; Make a new process table entry, etc.
- ld hl, (fork_proc_ptr)
- push hl
- call _newproc
- pop bc
-
- ; runticks = 0;
- ld hl, #0
- ld (_runticks), hl
- ; in the child process, fork() returns zero.
- ;
- ; And we exit, with the kernel mapped, the child now being deemed
- ; to be the live uarea. The parent is frozen in time and space as
- ; if it had done a switchout().
- ret
-
-;
-; This is related so we will keep it here. Copy the process memory
-; for a fork. a is the page base of the parent, c of the child
-; (this API will be insufficient once we have chmem and proper use of
-; banks - as well as needing to support fork to disk)
-;
-; Assumption - fits into a fixed number of whole 256 byte blocks
-;
-; The parent must be running here, therefore the parent must be
-; mapped, therefore the cached page is loaded with the parent
-;
-bankfork:
- push af
- ld hl, #U_DATA__U_PAGE + 1
- cp (hl) ; Are we a two pager ?
- jr z, bankfork_low ; If not skip the high space
- call flush_cache_self ; Flush the parent cache
- ld a, b
- ld (_cached_page), a ; High cache is now child (which runs first)
- ld b, #0x80
- jr bankfork_go ; Now copy the low 32K
-bankfork_low:
- ld b, #0x7D ; 32K minus UAREA stash
-bankfork_go:
- pop af ; A is now the parent bank
- ld hl, #0 ; base of memory to fork (vectors included)
-bankfork_1:
- push bc ; Save our counter and also child offset
- push hl
- out (21), a ; switch to parent bank
- ld de, #bouncebuffer
- ld bc, #256
- ldir ; copy into the bounce buffer
- pop de ; recover source of copy to bounce
- ; as destination in new bank
- pop bc ; recover child page number
- push bc
- ld b, a ; save the parent bank id
- ld a, c ; switch to the child
- out (21), a
- push bc ; save the bank pointers
- ld hl, #bouncebuffer
- ld bc, #256
- ldir ; copy into the child
- pop bc ; recover the bank pointers
- ex de, hl ; destination is now source for next bank
- ld a, b ; parent bank is wanted in a
- pop bc
- djnz bankfork_1 ; rinse, repeat
- ret
-
-;
-; For the moment
-;
-bouncebuffer:
- .ds 256
-;
-; We can keep a stack in common because we will complete our
-; use of it before we switch common block. In this case we have
-; a true common so it's even easier. This can share with the bounce
-; buffer used by bankfork as we won't switchin mid way through the
-; banked fork() call.
-;
-_swapstack:
-_cached_page:
- .db 0xff
+++ /dev/null
-;
-; Z80Pack hardware support
-;
-;
-; This goes straight after udata for common. Because of that the first
-; 256 bytes get swapped to and from disk with the uarea (512 byte disk
-; blocks). This isn't a problem but don't put any variables in here.
-;
-; If you make this module any shorter, check what follows next
-;
-
-
- .module z80pack
-
- ; exported symbols
- .globl init_early
- .globl init_hardware
- .globl _program_vectors
- .globl platform_interrupt_all
-
- .globl map_kernel
- .globl map_process
- .globl map_process_always
- .globl map_save
- .globl map_restore
-
- .globl _fd_bankcmd
-
- .globl _kernel_flag
-
- ; exported debugging tools
- .globl _platform_monitor
- .globl outchar
-
- ; imported symbols
- .globl _ramsize
- .globl _procmem
-
- .globl unix_syscall_entry
- .globl null_handler
- .globl nmi_handler
- .globl interrupt_handler
-
- .globl outcharhex
- .globl outhl, outde, outbc
- .globl outnewline
- .globl outstring
- .globl outstringhex
-
- .include "kernel.def"
- .include "../kernel.def"
-
-; -----------------------------------------------------------------------------
-; COMMON MEMORY BANK (0xF000 upwards)
-; -----------------------------------------------------------------------------
- .area _COMMONMEM
-
-_platform_monitor:
- ld a, #128
- out (29), a
-platform_interrupt_all:
- ret
-
-_platform_reboot:
- ld a, #1
- out (29), a
-
-;
-; We need the right bank present when we cause the transfer
-;
-_fd_bankcmd:pop de ; return
- pop bc ; command
- pop hl ; bank
- push hl
- push bc
- push de ; fix stack
- ld a, (_int_disabled)
- di
- push af ; save DI state
- call map_process ; HL alread holds our bank
- ld a, c ; issue the command
- out (13), a ;
- call map_kernel ; return to kernel mapping
- pop af
- or a
- ret nz
- ei
- ret
-
-; -----------------------------------------------------------------------------
-; KERNEL MEMORY BANK (below 0xC000, only accessible when the kernel is mapped)
-; -----------------------------------------------------------------------------
- .area _CODE
-
-init_early:
- ld a, #240 ; 240 * 256 bytes (60K)
- out (22), a ; set up memory banking
- ld a, #8
- out (20), a ; 8 segments
- ret
-
-init_hardware:
- ; set system RAM size
- ld hl, #480
- ld (_ramsize), hl
- ld hl, #(480-64) ; 64K for kernel
- ld (_procmem), hl
-
- ld a, #1
- out (27), a ; 100Hz timer on
-
- ; set up interrupt vectors for the kernel (also sets up common memory in page 0x000F which is unused)
- ld hl, #0
- push hl
- call _program_vectors
- pop hl
-
- im 1 ; set CPU interrupt mode
- ret
-
-
-;------------------------------------------------------------------------------
-; COMMON MEMORY PROCEDURES FOLLOW
-
- .area _COMMONMEM
-
-
-_program_vectors:
- ; we are called, with interrupts disabled, by both newproc() and crt0
- ; will exit with interrupts off
- di ; just to be sure
- pop de ; temporarily store return address
- pop hl ; function argument -- base page number
- push hl ; put stack back as it was
- push de
-
- call map_process
-
- ; 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 UZI system calls
- ld (0x0030), a ; (rst 30h is unix function call vector)
- ld hl, #unix_syscall_entry
- ld (0x0031), hl
-
- ; Set vector for jump to NULL
- 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
-
- ; our platform has a "true" common area, if it did not we would
- ; need to copy the "common" code into the common area of the new
- ; process.
-
- ; falls through
-
- ; put the paging back as it was -- we're in kernel mode so this is predictable
-map_kernel:
- push af
- xor a
- out (21), a
- pop af
- ret
-map_process:
- ld a, h
- or l
- jr z, map_kernel
- ld a, (hl)
- out (21), a
- ret
-map_process_always:
- push af
- ld a, (U_DATA__U_PAGE)
- out (21), a
- pop af
- ret
-map_save:
- push af
- in a, (21)
- ld (map_store), a
- pop af
- ret
-map_restore:
- push af
- ld a, (map_store)
- out (21), a
- pop af
- ret
-map_store:
- .db 0
-
-_kernel_flag:
- .db 1
-
-; outchar: Wait for UART TX idle, then print the char in A
-; destroys: AF
-outchar:
- out (0x01), a
- ret