65c816: further updates
authorAlan Cox <alan@linux.intel.com>
Sat, 23 Sep 2017 17:19:44 +0000 (18:19 +0100)
committerAlan Cox <alan@linux.intel.com>
Sat, 23 Sep 2017 17:19:44 +0000 (18:19 +0100)
At this point it compiles although there is stuff to finish fixing up before
it's even worth trying to boot an image.

15 files changed:
Kernel/bank65c816.c
Kernel/lib/65c816.s
Kernel/lowlevel-65c816.s
Kernel/platform-v65c816/Makefile
Kernel/platform-v65c816/README
Kernel/platform-v65c816/commonmem.s
Kernel/platform-v65c816/config.h
Kernel/platform-v65c816/crt0.s
Kernel/platform-v65c816/devhd.c
Kernel/platform-v65c816/kernel.def
Kernel/platform-v65c816/ld65.cfg
Kernel/platform-v65c816/main.c
Kernel/platform-v65c816/target.mk
Kernel/platform-v65c816/v65.s
Kernel/usermem_std-65c816.s

index a39093c..6e8e19f 100644 (file)
  *     don't support split I/D (different code/data page) at this point.
  *
  *     Beyond that it's a normal banked platform. The oddities are that we
- *     have no common, and that we must also swap the ZP/Stack separately
+ *     have no common, and that we must also swap the Stack separately
  *     from bank 0, as well as the program bank.
  *
- *     Define MAP_SIZE for the space in the 64K available to the process,
- *     this needs to be no more than 63.5K (udata and kstack copies...)
+ *     Note: The code assumes we have the normal user map of 0x0000-0xFBFF
+ *     then 512 bytes of udata material, then a gap then stubs and that we
+ *     swap the full 64K minus stubs/gap. If we extend udata then stubs will
+ *     end up getting swapped in the final block but it's R/O so nobody
+ *     should care.
  */
 
 #include <kernel.h>
 #include <kdata.h>
 #include <printf.h>
 
-#ifdef CONFIG_BANK_65C812
+#ifdef CONFIG_BANK_65C816
 
-uint16_t pzero[NPROC];
 /* Kernel is 0, apps 1,2,3 etc */
 static unsigned char pfree[MAX_MAPS];
 static unsigned char pfptr = 0;
@@ -92,10 +94,10 @@ int swapout(ptptr p)
        if (map == 0)
                return ENOMEM;
        blk = map * SWAP_SIZE;
-       /* Write the kstack and zero page to disk */
-       swapwrite(SWAPDEV, blk, 512, pzero[p-ptab], 0);
-       /* Write the app (and possibly the uarea etc..) to disk */
-       swapwrite(SWAPDEV, blk, SWAPTOP - SWAPBASE, SWAPBASE, p->p_page);
+       /* Write the user CPU stack to disk */
+       swapwrite(SWAPDEV, blk, 512, (STACK_BANKOFF+(p-ptab)) << 8, 0);
+       /* Write the process including DP and C stack, plus the udata cache */
+       swapwrite(SWAPDEV, blk + 1, SWAPTOP - SWAPBASE, SWAPBASE, p->p_page);
        pagemap_free(p);
        p->p_page = 0;
        p->p_page2 = map;
@@ -119,10 +121,12 @@ void swapin(ptptr p, uint16_t map)
                kprintf("%x: nopage!\n", p);
                return;
        }
-       /* Read the kstack and zero page from disk */
-       swapread(SWAPDEV, blk, 512, pzero[p-ptab], 0);
+       /* Read the user stack from disk: FIXME - this is half a block
+          so we need to make sure our disk drivers can cope with this for
+          read (write is ok) */
+       swapread(SWAPDEV, blk, 256, (STACK_BANKOFF+(p-ptab)) << 8, 0);
        /* Read the process back in */
-       swapread(SWAPDEV, blk, SWAPTOP - SWAPBASE, SWAPBASE, p->p_page);
+       swapread(SWAPDEV, blk + 1, SWAPTOP - SWAPBASE, SWAPBASE, p->p_page);
 #ifdef DEBUG
        kprintf("%x: swapin done %d\n", p, p->p_page);
 #endif
index dd734c6..98e1c53 100644 (file)
@@ -2,18 +2,19 @@
 ;      The 65C816 memory management and switching logic is common
 ;      to all systems so keep it all here
 ;
-        .include "kernel.def"
+        .include "../platform/kernel.def"
         .include "../kernel816.def"
-       .include "zeropage.inc"
+       .include "../platform/zeropage.inc"
 
        .export _switchout
        .export _switchin
        .export _dofork
 
        .importzp ptr1
-       .import jump_monitor
+       .import _trap_monitor
        .import _chksigs
        .import _platform_idle
+       .import _newproc
        .import _nready
        .import _inint
        .import _getproc
@@ -21,7 +22,8 @@
        .import outcharhex
        .import outstring
 
-       .segment "COMMONMEM"
+
+       .code
        .p816
        .i8
        .a8
@@ -86,10 +88,10 @@ slow_path:
        lda     #U_DATA__TOTALSIZE-1            ; including our live stack
        phb
 switch_patch_1:
-       mv      KERNEL_BANK:0,0         ; save stack and udata
+       mvn     KERNEL_FAR,0            ; save stack and udata
        plb
        sep #$30
-       clz     _inint
+       stz     _inint
        jsr     _getproc                        ; x,a holds process
        jsr     _switchin                       ; switch to process
        jsr     _trap_monitor                   ; bug out if it fails
@@ -125,14 +127,14 @@ _switchin:
        lda     #U_DATA__TOTALSIZE-1
 switch_patch_2:
        ;       FIXME check syntax required for bank value ??
-       mvn     0,KERNEL_BANK:0
+       mvn     0,KERNEL_FAR
        ;       after the MVN our data bank is KERNEL_DATA
        ;       Our stack is now valid and we may use it again, our UDATA
        ;       is for the new process
        ldx     U_DATA__U_PTAB
        cpx     ptr1
        bne     switchinfail    ;       wrong process !!
-       clz     _runticks
+       stz     _runticks
        sep     #$20
        .a8
        lda     #P_RUNNING
@@ -145,7 +147,7 @@ switch_patch_2:
        stx     sp
        sep     #$10
        .i8
-       lda     U_DATA__U_INTERRUPT
+       lda     U_DATA__U_ININTERRUPT
        beq     notisr
        cli     ; interrupts back on
 notisr:
@@ -161,16 +163,17 @@ switchinfail:
        ldx     #>badswitchmsg
         jsr    outstring
        ; something went wrong and we didn't switch in what we asked for
-        jmp _  trap_monitor
-badswitchmsg: .byte "_switchin: FAIL"
-       .byte 13, 10, 0
+        jmp    _trap_monitor
+badswitchmsg:
+       .byte   "_switchin: FAIL"
+       .byte   13, 10, 0
 
 _dofork:
        sta     ptr1            ; new process ptr. U_DATA gives parent
        stx     ptr1+1
        lda     U_DATA__U_PAGE
        sta     fork_patch+2    ;       source bank (parent)
-       ldy     #P_TAB__P_PAGE
+       ldy     #P_TAB__P_PAGE_OFFSET
        lda     (ptr1),y
        sta     fork_patch+1    ;       destination bank (child)
        sta     fork_patch_2+1
@@ -195,12 +198,12 @@ _dofork:
        lda     #MAP_SIZE       ; 64K - udata shadow
        phb
 fork_patch:
-       mvn     0,0             ; copy the entire bank
+       mvn     0,0             ; copy the entire bank below the save
        ldx     #U_DATA
        ldy     #U_DATA_STASH
-       lda     #U_DATA_TOTALSIZE-1
+       lda     #U_DATA__TOTALSIZE-1
 fork_patch_2:
-       mvn     KERNEL_BANK:0,0
+       mvn     KERNEL_FAR,0
        plb                     ; back to kernel bank
 
        ; At this point we have copied the parent into the child bank
@@ -208,7 +211,7 @@ fork_patch_2:
        plx                     ; discard frame we build for child
        plx
 
-       .sep    #$30            ; back to 8bit mode for C
+       sep     #$30            ; back to 8bit mode for C
        .a8
        .i8
        lda     ptr1
index 128a323..e2abb2c 100644 (file)
@@ -4,10 +4,21 @@
        .I8
        .A8
        
-       .export unix_syscall_entry
        .export _doexec
        .export interrupt_handler
        .export nmi_handler
+       .export map_process_always
+       .export map_kernel
+       .export _userpage
+
+       .export sigret_irq
+       .export sigret
+       .export syscall_vector
+
+       .export illegal_inst
+       .export trap_inst
+       .export abort_inst
+       .export emulation
 
        .export outstring
        .export outstringhex
        .export outcharhex
        .export outxa
 
-       .export _userpage
-
        .export _need_resched
 
+       .import istack_top
+       .import istackc_top
+       .import istack_switched_sp
+
+       .import kstack_top
+       .import kstackc_top
+
+       .import _ssig
+
        .import outchar
        .import _kernel_flag
        .import _unix_syscall
-       .import map_restore
-       .import map_save
-       .import map_process_always
-       .import map_kernel
        .import _platform_interrupt
        .import platform_doexec
        .import _inint
        .import _trap_monitor
 
+       .import push0
+       .import incaxy
+
        .include "platform/zeropage.inc"
        .include "platform/kernel.def"
        .include "kernel816.def"
 
-       .segment "COMMONMEM"
+       .code
 ;
 ;      Unlike Z80 we need to deal with systems that have no overlapping
 ;      memory banks. We pass the arguments is a single pointer therefore
@@ -61,6 +78,9 @@
 ;        stubs (syscall and signal return)
 ;      - audit and begin testing
 ;
+
+syscall        =       $fe
+
 ;
 ;      This is called from a stub we put into each user process bank that
 ;      does a jsl to the kernel entry point then an rts
@@ -69,7 +89,7 @@ syscall_entry:
        php                             ; save cpu mode of caller on ustack
        sei                             ; interrupts off
        cld                             ; get into sane mode - no decimal, known state
-       sep     $30
+       sep     #$30
        .a8
        .i8
        stx     U_DATA__U_CALLNO
@@ -100,59 +120,68 @@ copy_args:
        dey
        dey
        lda     (ptr1),y                ; copy the arguments over
-       ld
-       sta     KERNEL_BANK:U_DATA__U_ARGN,x
+       sta     KERNEL_FAR+U_DATA__U_ARGN,x
         inx
        inx
        cpy     #0
        bne     copy_args
 
 noargs:
-       rep     #$30
-       .a16
-       .i16
+       sep     #$30
+       .a8
+       .i8
+
        lda     #KERNEL_BANK            ; our direct and base bank need setting
        pha
        plb
+
+       rep     #$30
+       .a16
+       .i16
+
        lda     #KERNEL_DP
        tcd
+
        rep     #$30
-       .a8
-       .i8
-       rep     #$10
+       .a16
        .i16
+
        ldx     sp                      ; save the C stack
-       pshx                            ; on the main stack
+       phx                             ; on the main stack
        ; FIXME: how to check stack space in brk when this is not visible ?
        tsx
        stx     U_DATA__U_SYSCALL_SP
-       ldx     #kstack_top
+       ldx     #kstack_top-1
        txs                             ; set our CPU stack
-       ldx     #kstack_c               ; set our C stack
+       ldx     #kstackc_top-1          ; set our C stack
        stx     sp                      ; 
        cli                             ; sane state achieved
 
        sep     #$10
        .i8
+
        lda     #1
        sta     _kernel_flag            ; In kernel mode
        cli                             ; Interrupts now ok
        jsr     _unix_syscall           ; Enter C space
        sei                             ; Interrupts back off
        stz     _kernel_flag
+
        rep     #$10
        .i16
+
        ldx     U_DATA__U_SYSCALL_SP
        txs                             ; Back to the old stack
                                        ; We can't restore sp yet as we are
                                        ; in the wrong bank
-       .i8
        sep     #$10
+       .i8
+
        lda     U_DATA__U_CURSIG
        bne     signal_out
        sep     #$20
+       .a8
        lda     U_DATA__U_PAGE
-       .a16
        ;
        ;       We use this trick several times. U_PAGE holds the bank
        ;       register. As we want our DP to be bank:0000 we need to
@@ -164,17 +193,20 @@ noargs:
        lda     #0
        tcd
 
+       rep     #$20
+       .a16
        pla                             ; pull the saved sp off the ustack
        sta     sp                      ; and store it 16bit
 
-       rep     #$20
-       .a8 
-       plp                             ; off ustack
+       sep     #$20
+       .a8
+       .i8
        ; We may now be in decimal !
        ldy     U_DATA__U_RETVAL
        ldx     U_DATA__U_RETVAL+1
        ; also sets z for us
        lda     U_DATA__U_ERROR
+       plp
        rtl
 
        ;
@@ -199,7 +231,7 @@ noargs:
        ;       rts     in bank return to the interruption point
        ;
 signal_out:
-       clz     U_DATA__U_CURSIG
+       stz     U_DATA__U_CURSIG
        
        rep     #$10
        .i16
@@ -212,29 +244,28 @@ signal_out:
        txs
        sep     #$10
        .i8
-       tax                             ; Save signal code in X
        ; Stack the signal return (the signal itself can cause syscalls)
        ; Be careful here stack ops are currently going to user stack but
        ; data ops to kernel. Don't mix them up!
-       lda     #>sigret                ; needs to be a fixed address in user
-       pha
-       lda     #<sigret                ; FIXME
-       pha
+       pea     sigret
        phx                             ; signal number
        phy                             ; temporarily save C sp value
-       txa
        asl a                           ; vector offset
        tay
-       rep     #$10
+       rep     #$30
+       .a16
        .i16
+       lda     #0
        ldx     U_DATA__U_SIGVEC,y      ; get signal vector
-       clz     U_DATA__U_SIGVEC,y      ; and reset it
+       sta     U_DATA__U_SIGVEC,y      ; and reset it
        ply                             ; get the temporary sp save back
        phx
+       sep     #$20
+       .a8
        ; Needs to change for split I/D
        lda     U_DATA__U_PAGE          ; target code page
        pha
-       pea     #PROGLOAD+20            ; trap handler in user app
+       pea     PROGLOAD+20             ; trap handler in user app
        pha
        plb                             ; get the right user data bank
        xba                             ; get into ff00 format
@@ -249,30 +280,31 @@ signal_out:
 ;      registers and return directly to the start of the user process
 ;
 _doexec:
-       ; FIXME how do we find the correct cpu stack for this process
-       ;
-       ; Would (bank + offset) << 8 work ?
-       sta     _tmp1
-       stx     _tmp1+1
+       sta     tmp1
+       stx     tmp1+1
        sei
        stz     _kernel_flag
        rep     #$30
        .i16
        .a16
-       ldx     _tmp1           ;       target address
+       ldx     tmp1            ;       target address
        sep     #$20
        .a8
        lda     U_DATA__U_PAGE  ;       get our bank
        clc
        adc     #STACK_BANKOFF
        xba                     ;       swap to xx00
-       lda     #FF             ;       stack top is xxff
+       lda     #$FF            ;       stack top is xxff
        tcs                     ;       Set CPU stack at xxFF
        ; Split I/D will need to change this logic
        lda     U_DATA__U_PAGE  ;       our bank
        xba                     ;       now in the form xx00 as we need
        tcd                     ;       set the user DP
        ; We are now on the correct DP and CPU stack
+       ; So fix up the syscall vector
+       ldy     #syscall_vector
+       sty     syscall
+       ; And the C stack pointer
        ldy     U_DATA__U_ISP
        sty     sp              ;       sp is in DP so we write user version
        sep     #$30
@@ -292,6 +324,47 @@ _doexec:
        sep     #$10
        .i8
        rtl
+
+;
+;      The basic idea of taking a trap and signalling is to make sure we
+;      look like an interrupt and can re-cycle much of that code. The
+;      caller already saved the CPU state. Interrupts are off at this point
+;      as it we got here via a trap.
+;
+shoot_myself:
+       sep     #$30
+       .a8
+       .i8
+       lda     #KERNEL_BANK
+       pha
+       plb
+       rep     #$30
+       .a16
+       .i16
+       lda     #IRQ_DP
+       tcd
+       tsx
+       stx     istack_switched_sp
+       ldx     #istack_top-1
+       txs
+       ldx     #istackc_top -1
+       stx     sp
+
+       ;
+       ;       We have now arrived in kernel mappings for an interrupt
+       ;
+
+       sep     #$30
+       .a8
+       .i8
+       jsr     push0
+       lda     #1
+       sta     _inint
+       pla                     ; top of stack is the saved signal number
+       ldx     #0
+       jsr     _ssig
+       jmp     join_interrupt_path
+
        
 ;
 ;      The C world here is fairly ugly. We have to stash various bits of
@@ -317,9 +390,9 @@ interrupt_handler:
        ; Switch stacks
        tsx
        stx     istack_switched_sp
-       ldx     #istack
+       ldx     #istack_top-1
        txs
-       ldx     #istack_c       ; set up C istack (may not need eventually)
+       ldx     #istackc_top-1  ; set up C istack (may not need eventually)
        stx     sp              
 
        sep     #$30
@@ -330,6 +403,13 @@ interrupt_handler:
        lda     #1
        sta     _inint
        jsr     _platform_interrupt
+
+       ;
+       ;       A synchronously delivered signal trap joins the interrupt
+       ;       return flow
+       ;
+
+join_interrupt_path:
        stz     _inint
 
        ; Restore the stack we arrived on
@@ -353,7 +433,7 @@ interrupt_handler:
        ;       save the bank as a task switch or swap might move the
        ;       process
        ;
-       lda     U_DATA_U_PAGE
+       lda     U_DATA__U_PAGE
        sep     #$30
 
        .a8
@@ -383,8 +463,8 @@ interrupt_handler:
        .a8
        .i16
 signal_exit:
-       clz     U_DATA__U_CURSIG
-       sta     _tmp1           ; save signal 8bits (irq tmp1)
+       stz     U_DATA__U_CURSIG
+       sta     tmp1            ; save signal 8bits (irq tmp1)
 
 
        ; Move down the stack frame
@@ -407,8 +487,6 @@ signal_exit:
        ;               A16
        ;               X16
        ;               Y16
-       ;               error
-       ;               retval
        ;               sigret_irq
        ;               signal number
        ;
@@ -432,18 +510,7 @@ signal_exit:
        tcs     ; stick y in s
 
        sep     #$20
-       .a8
-       ;
-       ;       Stack the signal bits
-       ;
-       lda     U_DATA__U_ERROR
-       pha
-       lda     U_DATA__U_RETVAL
-       pha
-       lda     U_DATA__U_RETVAL+1
-       pha
-       pea     #sigret_irq
-                               ; sig   nal return
+       pea     sigret_irq      ; signal return
        sep     #$10
        .i8
        phy                     ; signal code
@@ -451,11 +518,12 @@ signal_exit:
        asl a
        tay
        rep     #$30
-       .i16
        .a16
-       lda     U_DATA__U_SIGVEC,y
-       clz     U_DATA__U_SIGVEC,y
-       pha
+       .i16
+       lda     #0
+       ldx     U_DATA__U_SIGVEC,y
+       sta     U_DATA__U_SIGVEC,y
+       phx
        sep     #$20
        .a8
        lda     U_DATA__U_PAGE
@@ -465,13 +533,55 @@ signal_exit:
        .i16
        ldx     #0
        txy
-       pea     #PROGLOAD+20
+       pea     PROGLOAD+20
        sep     #$30
        .i8
        .a8
        lda     #$30            ; i8a8
        pha
        rti
+
+;
+;      Trap handlers
+;
+illegal_inst:
+       rep     #$30
+       .a16
+       .i16
+       pha
+       phx
+       ply
+       cld
+       lda     #4
+sync_sig:
+       sep     #$30
+       .a8
+       .i8
+       pha
+       jmp     shoot_myself
+
+trap_inst:
+       rep     #$30
+       .a16
+       .i16
+       pha
+       phx
+       ply
+       cld
+       lda     #5
+       bra     sync_sig
+
+abort_inst:
+       rep     #$30
+       .a16
+       .i16
+       pha
+       phx
+       ply
+       cld
+       lda     #7
+       bra     sync_sig
+
 ;
 ;      We can make the map routines generic as all 65c816 are the same
 ;      mapping model. We don't change anything but instead track the page
@@ -484,6 +594,10 @@ signal_exit:
 ;      some custom swap logic in the disk drivers which is sucky but I
 ;      don't currently have any better idea!
 ;
+
+       .a8
+       .i8
+
 map_process_always:
        lda U_DATA__U_PAGE
        sta _userpage
@@ -491,7 +605,7 @@ map_process_always:
 map_process:
        cmp #0
        bne map_process_2
-       cmpx #0
+       cpx #0
        bne map_process_2
 map_kernel:
        rts
@@ -514,6 +628,14 @@ nmi_stop:
 nmi_trap:
        .byte "NMI!", 0
 
+emulation:
+       ldx #>emu_trap
+       lda #<emu_trap
+       jsr outstring
+       jmp _trap_monitor
+emu_trap:
+       .byte "EM!", 0
+
 outstring:
        sta ptr1
        stx ptr1+1
@@ -582,3 +704,39 @@ outxa:     pha
 
 _need_resched:
        .byte 0
+
+
+;
+;      Stubs get propogated into each segment at FF00
+;
+       .segment "STUBS"
+
+       .a8
+       .i8
+
+sigret:
+       sep #$30
+       plx                     ; pull the return and error code back
+       ply
+       pla
+       plp                     ; recover the flags
+       rts                     ; back to the interrupted syscall return
+
+
+sigret_irq:
+       rep #$30
+       .a16
+       .i16
+       ply
+       plx
+       pla
+       plp                     ; flags and status bits (back to 8/8 usually)
+       rts
+
+       .a8
+       .i8
+
+syscall_vector:
+       jsl     KERNEL_FAR+syscall_entry
+       rts
+
index 0a48e99..f124f2b 100644 (file)
@@ -2,12 +2,15 @@
 CSRCS = devtty.c devhd.c
 CSRCS += devices.c main.c
 
+LSRCS = ../lib/65c816.s
+LOBJS = $(patsubst ../lib/%.s,%.o, $(LSRCS))
+
 ASRCS = v65.s crt0.s
-ASRCS += tricks.s commonmem.s
+ASRCS += commonmem.s
 
 COBJS = $(CSRCS:.c=$(BINEXT))
 AOBJS = $(ASRCS:.s=$(BINEXT))
-OBJS  = $(COBJS) $(AOBJS)
+OBJS  = $(COBJS) $(AOBJS) $(LOBJS)
 
 JUNK = $(CSRCS:.c=.o) $(CSRCS:.c=.s) $(ASRCS:.s=.o)
 
@@ -19,6 +22,9 @@ $(COBJS): %$(BINEXT): %.c
 $(AOBJS): %$(BINEXT): %.s
        $(CROSS_AS) $(ASOPTS) $< -o $*$(BINEXT)
 
+$(LOBJS): %$(BINEXT): ../lib/%.s
+       $(CROSS_AS) $(ASOPTS) $< -o $*$(BINEXT)
+
 clean:
        rm -f $(OBJS) $(JUNK)  core *~ 
 
@@ -26,9 +32,9 @@ image:
        $(CROSS_LD) -o ../fuzix.bin --mapfile ../fuzix.map -C ld65.cfg \
        crt0.o commonmem.o \
        v65.o ../start.o ../version.o ../lowlevel-65c816.o \
-       ../lib/65c816.o main.o ../timer.o ../kdata.o devhd.o devices.o \
+       65c816.o main.o ../timer.o ../kdata.o devhd.o devices.o \
        ../devio.o ../filesys.o ../process.o ../inode.o ../syscall_fs.o \
        ../syscall_proc.o ../syscall_other.o ../mm.o ../bank65c816.o \
        ../tty.o ../devsys.o ../syscall_fs2.o ../syscall_fs3.o \
        ../syscall_exec16.o ../usermem.o ../usermem_std-65c816.o devtty.o
-       dd if=../fuzix.bin of=fuzix.img bs=512 skip=1
+       dd if=../fuzix.bin of=fuzix.img bs=512
\ No newline at end of file
index e39b00f..9f2d4dd 100644 (file)
@@ -5,10 +5,9 @@ Our memory mapping looks like this
 
 Bank 0:
        0x0000          Kernel DP
-       0x0100          UData + C stack
-       0x0200          Bootcode / Replaced with C stack
-       0x0300          CPU stack (kernel mode)
-       0x0400          Kernel image
+       0x0100          UData + C stack etc
+       0x0300          Bootcode
+       ...             Kernel image
        0xF700          7 x 256 byte CPU stacks for processes
        0xFE00          I/O page
        0xFF00          Vectors
@@ -33,15 +32,14 @@ the emulator.
 
 TODO
 ----
+- Sort out memory map (move udata to 0100 and boot upwards)
+- Fix fork() to copy the user C stacks in dofork()
 - Debug initial sketches
-- Add stubs and correct stub copier (+ syscall vector)
-- Add vectors correctly for the 816
-- Figure out how to set stacks up nicely
-- Test signal handling paths
 - Fix brk() checking [right now its busted entirely]
+- Make discard sane so we can discard for buffers
+- Test signal handling paths
 - Fix execl() execle() in userspace (so init can be fully tested)
 - Add pre-emption logic to the interrupt return path
-- Fix fork() to copy the user C stacks in dofork()
 - Add swap logic
 
 Optimisations We Need To Do
index 1b1692c..923393c 100644 (file)
@@ -6,25 +6,36 @@
         .export _ub
         .export _udata
         .export kstack_top
+       .export kstackc_top
         .export istack_top
+       .export istackc_top
         .export istack_switched_sp
-       .export CTemp
 
         .segment "COMMONDATA"
        .include "zeropage.inc"
 
+       .p816
+       .a8
+       .i8
+
+;
+;      The udata for 65C816 is a bit different to 6502 as we have both a C
+;      stack and a small CPU stack in the banking
 ;
-;      In 6502 land these are the C stacks, we will need to handle the
-;      hardware stack separately, and also to save sp,sp+1 etc on irqs
+;      Our current layout is
+;      [udata][cpu stack]              in 256 bytes
+;      [C stack]                       in 256 (will it be sufficient ?)
 ;
-;      Declared as BSS so no non zero bytes here please
+;      There is a separate IRQ DP, stack and C stack.
 ;
 _ub:    ; first 512 bytes: starts with struct u_block, with the kernel stack working down from above
 _udata:
 kstack_base:
-       .res 512,0
+       .res 256,0
 kstack_top:
-FIXME: C stack of 512 - udata, 65C816 stack follows
+kstackc_base:
+       .res 256,0
+kstackc_top:
 
 ;
 ;      We have a single istack so we can stuff that anywhere we like
@@ -32,7 +43,10 @@ FIXME: C stack of 512 - udata, 65C816 stack follows
        .bss
 
 istack_base:
-       .res 254,0
+       .res 64,0                       ; should be tons
 istack_top:
-FIXME: interrupt CPU stack (64 ?)
-istack_switched_sp: .word 0
+istackc_base:
+       .res 254,0                      ; overkill - tune me
+istackc_top:
+istack_switched_sp:
+       .word 0
index e359fb0..be7cb02 100644 (file)
  *     if we add swap.
  */
 #define CONFIG_BANK_65C816
+#define KERNEL_BANK    0
 #define MAX_MAPS       7
 #define MAP_SIZE    0xFC00  /* 0-FBFF */
 
+#define STACK_BANKOFF  0xF5    /* F600-FCFF */
+
 #define TICKSPERSEC 10     /* Ticks per second */
 #define MAPBASE            0x0000  /* We map from 0 */
 #define PROGBASE    0x0100  /* also data base */
index 5776ea8..c63307b 100644 (file)
@@ -1,27 +1,35 @@
-               ; imported symbols
-               .import init_early
-               .import init_hardware
-               .import _fuzix_main
-               .import kstack_top
-               .import vector
-               .import nmi_handler
-
-               .import  __BSS_RUN__, __BSS_SIZE__
-               .importzp       ptr1, ptr2, tmp1
-
-               ; startup code @0
-               .include "zeropage.inc"
+       ; imported symbols
+       .import init_early
+       .import init_hardware
+       .import _fuzix_main
+       .import kstack_top
+       .import kstackc_top
+       .import vector
+       .import nmi_handler
+       .import interrupt_handler
+       .import emulation
+       .import illegal_inst
+       .import trap_inst
+       .import abort_inst
+
+       .import  __BSS_RUN__, __BSS_SIZE__
+       .importzp       ptr1, ptr2, tmp1
+
+       ; startup code @0200
+        .include "kernel.def"
+        .include "../kernel816.def"
+       .include "zeropage.inc"
 
 ;
 ;      So we end up first in the image
 ;
-               .segment "START"
-               .byte 65
-               .byte 81
+       .segment "START"
+       .byte 65
+       .byte 81
 
-               .a8
-               .i8
-               .p816
+       .p816
+       .a8
+       .i8
 
 entry:
 ;
@@ -30,83 +38,110 @@ entry:
 ;      We get run from bank 0, our I/O writes would otherwise need to be
 ;      24bit
 ;
-               sep #$30                ; ensure we are in 8bit mode
-               lda #'F'
-               sta $FE20               ; signal our arrival
+       sep     #$30            ; ensure we are in 8bit mode
+       lda     #'F'
+       sta     $FE20           ; signal our arrival
+
+       sei                     ; interrupts off
+       cld                     ; decimal off
 
-               sei                     ; interrupts off
-               cld                     ; decimal off
+       rep     #$10
+       .i16
 
-               rep #$10
-               .i16
-               ldx #kstack
-               txs                     ; Stack (6502 not C)
+       ldx     #kstack_top
+       txs                     ; Stack (6502 not C)
 
-               lda #'u'
-               sta $FE20
+       lda     #'u'
+       sta     $FE20
 
-               ldx #kstack_top ; C stack
-               sta sp
+       ldx     #kstackc_top    ; C stack
+       sta     sp
 
-               ldx #__BSS_RUN__
+       ldx     #__BSS_RUN__
 
-               lda #'z'
-               sta $FE20
+       lda     #'z'
+       sta     $FE20
 
-               txy
-               iny
+       txy
+       iny
 
-               ; Wipe the BSS
+       ; Wipe the BSS
 
-               rep #$20
-               .a16
-               lda #__BSS_SIZE-2       ; must be >=2  bytes or else
-               clz 0,x
-               mvn 0,0
+       rep #$20
+       .a16
 
+       lda     #__BSS_SIZE__-2 ; must be >=2  bytes or else
+       stz     0,x
+       mvn     0,0
                
-               sep #$30
-               .a8
-               .i8
-
-               lda #'i'
-               sta $FE20
-
-               lda #'x'
-               sta $FE20
-
-               jsr init_early
-               lda #'.'
-               sta $FE20
-               jsr init_hardware
-               lda #13
-               sta $FE20
-               lda #10
-               sta $FE20
-               jmp code
+       sep #$30
+       .a8
+       .i8
+
+       lda     #'i'
+       sta     $FE20
+
+       lda     #'x'
+       sta     $FE20
+
+       jsr     init_early
+       lda     #'.'
+       sta     $FE20
+       jsr     init_hardware
+       lda     #13
+       sta     $FE20
+       lda     #10
+       sta     $FE20
+       jmp     code
 
 ; The above gets blasted into udata space
-               .code
+       .code
 
 code:
-               rep #$30
-               .a8
-               .i8
-               ldx #$U_DATA
-               ldy #$U_DATA+1
-               lda #$UDATA_TOTALSIZE-2
-               clz 0,x
-               mvn 0,0
-
-               sep #$30
-               .a8
-               .i8
-
-               jsr _fuzix_main         ; Should never return
-               sei                     ; Spin
-stop:          jmp stop
-
-               .segment "VECTORS"
-               .addr   vector
-               .addr   $0202           ; does it matter ???
-               .addr   nmi_handler
+       rep     #$30
+       .a16
+       .i16
+
+       ldx     #U_DATA
+       ldy     #U_DATA+1
+       lda     #U_DATA__TOTALSIZE-2
+       stz     0,x
+       mvn     0,0
+
+       sep     #$30
+       .a8
+       .i8
+
+       jsr     _fuzix_main     ; Should never return
+       sei                     ; Spin
+stop:  bra stop
+
+
+;
+;      Processor vector table (0xFFE0)
+;
+       .segment "VECTORS"
+
+
+       .word   0               ; unused
+       .word   0               ; unused
+       .word   illegal_inst    ; COP
+       .word   trap_inst       ; BRK
+       .word   abort_inst      ; ABORT
+       .word   nmi_handler     ; NMI
+       .word   0               ; Unused (native reset)
+       .word   interrupt_handler
+
+       ;
+       ;       Emulation mode vectors. If called badness occurred
+       ;
+       .word   emulation
+       .word   emulation
+       .word   emulation
+       .word   emulation
+       .word   emulation
+       .word   emulation
+       .word   emulation
+       .word   emulation
+
+
index 51b57c5..68e74f5 100644 (file)
@@ -7,7 +7,7 @@
 #include <printf.h>
 #include <devhd.h>
 
-extern uint8_t hd_map;
+extern uint8_t hd_kmap;
 
 extern void hd_read_data(uint16_t addr);
 extern void hd_write_data(uint16_t addr);
@@ -29,7 +29,7 @@ static int hd_transfer(uint8_t minor, bool is_read, uint8_t rawflag)
         return -1;
 
     /* For swap it'll be the swap bank passed */
-    hd_map = rawflag ? udata.u_page : KERNEL_BANK;
+    hd_kmap = rawflag ? udata.u_page : KERNEL_BANK;
 
     dptr = (uint16_t)udata.u_dptr;
     nb = udata.u_nblock;
index 432367a..aa631a6 100644 (file)
@@ -1,10 +1,23 @@
 ; UZI mnemonics for memory addresses etc
 
 ; (this is struct u_data from kernel.h)
-U_DATA                      .set $0100 ; stomps over bootstrap
+U_DATA                  .set $0100     ; stomps over bootstrap
 ; 256+256+256 bytes.   (U, kstack copy, k C stack copy)
-U_DATA__TOTALSIZE           .set $300
-U_DATA_STASH               .set $FC00  ; leaves FFxx for vectors and stubs
+U_DATA__TOTALSIZE       .set $300
+U_DATA_STASH           .set $FC00      ; leaves FFxx for vectors and stubs
 
-PROGLOAD                   .set $0200
-ZPBASE                     .set $0
+PROGLOAD               .set $0200
+ZPBASE                 .set $0
+
+KERNEL_BANK            .set $0         ; bank number
+KERNEL_FAR             .set $000000    ; 24 bit
+
+; Add this to the bank number to get the high 8bits of the 16bit CPU stack
+; for this process
+STACK_BANKOFF          .set $F5        ; F600-FCFF
+; Direct page for IRQ processing (saves us saving/restoring DP registers)
+; Can probably use the same page as the IRQ CPU stack... FIXME
+IRQ_DP                 .set $FD        ; FD00-FDFF
+KERNEL_DP              .set $00        ; We use the real ZP for kernel DP
+
+MAP_SIZE               .set $FC00
\ No newline at end of file
index 0db09c2..93d48aa 100644 (file)
@@ -1,27 +1,28 @@
 MEMORY {
        RAMZ:   start = $0000, size = $0100, type = rw, fill = yes;
-       STACK:  start = $0100, size = $0100, type = rw, fill = yes;
-       BOOT:   start = $0200, size = $0200, type = rw, fill = yes;
-       MAIN:   start = $0400, size = $F300, type = rw, fill = yes;
+       UDATA:  start = $0100, size = $0200, type = rw, fill = yes;
+       MAIN:   start = $0300, size = $F400, type = rw, fill = yes;
        USTACKS:start = $F700, size = $0700, type = rw, fill = yes;
        IO:     start = $FE00, size = $0100, type = rw, fill = yes;
-       VECTOR: start = $FFF0, size = $0010, type = rw, fill = yes;
+       STUB:   start = $FF00, size = $00E0, type = rw, fill = yes;
+       VECTOR: start = $FFE0, size = $0020, type = rw, fill = yes;
 }
 
 SEGMENTS {
        ZEROPAGE:       load = RAMZ, type = zp, define = yes;
-       COMMONDATA:     load = MAIN, type = bss;
+       COMMONDATA:     load = UDATA, type = bss;
+
+       START:          load = MAIN, type = ro;
        CODE:           load = MAIN, type = ro, define = yes;
        RODATA:         load = MAIN, type = ro;
 
-       START:          load = BOOT, type = ro;
-
        DATA:           load = MAIN, type = rw, define = yes;
        BSS:            load = MAIN, type = bss, define = yes;
 
        DISCARD:        load = MAIN, type = ro;
        DISCARDDATA:    load = MAIN, type = ro;
 
+       STUBS:          load = STUB, type = ro;
        VECTORS:        load = VECTOR, type = ro;
 }
 
index 4b0e7c3..b16f498 100644 (file)
@@ -5,6 +5,7 @@
 #include <devtty.h>
 
 uint8_t kernel_flag = 1;
+uint16_t ramtop = PROGTOP;
 
 void platform_idle(void)
 {
@@ -18,16 +19,15 @@ void do_beep(void)
 }
 
 /*
- * Map handling: We have flexible paging. Each map table consists of a set of pages
- * with the last page repeated to fill any holes.
+ * 7 banks, kernel in bank 0
  */
 
 void pagemap_init(void)
 {
     int i;
     /* Bank 0 is the kernel */
-    for (i = 15 ; i > 0; i--)
-        pagemap_add(i * 8);
+    for (i = 7 ; i > 0; i--)
+        pagemap_add(i);
 }
 
 void map_init(void)
index 677f44e..7138a63 100644 (file)
@@ -1 +1 @@
-export CPU = 658C16
+export CPU = 65c816
index 3384b3c..1a0c152 100644 (file)
            .export ___hard_di
            .export ___hard_ei
            .export ___hard_irqrestore
-           .export vector
 
            .import _ramsize
            .import _procmem
            .import nmi_handler
-           .import unix_syscall_entry
+           .import syscall_vector
            .import kstack_top
            .import istack_switched_sp
            .import istack_top
-           .import _unix_syscall
-           .import _platform_interrupt
            .import _kernel_flag
            .import pushax
 
            .import outxa
            .import incaxy
 
-           .import _create_init_common
-
             .include "kernel.def"
             .include "../kernel816.def"
            .include "zeropage.inc"
 
+       .p816
+       .a8
+       .i8
 ;
 ;      syscall is jsr [$00fe]
 ;
@@ -71,11 +69,37 @@ irq_on:
        sei
        rts
 
+;
+;      This could go in discard once we make that useful FIXME
+;
 init_early:
-       ; copy the stubs from bank 0 to all banks so we can keep the
-       jsr _create_init_common
+       lda     #1
+init_loop:
+       sep     #$30
+       .a8
+       .i8
+       sta     common_patch+1          ; destination bank
+       phb                             ; save our bank (mvn will mess it)
+       pha                             ; and count
+
+       rep     #$30
+       .a16
+       .i16
+       ldx     #$FF00
+       txy
+       lda     #$00FE
+common_patch:
+       mvn     KERNEL_FAR,0            ; copy the block
+       pla
+       plb                             ; bank to kernel bank
+       dec
+       cmp     #8
+       bne     init_loop
         rts
 
+       .a8
+       .i8
+
 init_hardware:
         ; set system RAM size for test purposes
        rep #$10
@@ -84,13 +108,8 @@ init_hardware:
        stx _ramsize
        ldx #512-64
        stx _procmem
-       ; TODO - correct vectors for the 816
-       ldx #vector
-       stx $FFFE
-       ldx #<nmi_handler
-       stx $FFFA
-       ldx #syscall_entry
-       stx #syscall
+       ldx #syscall_vector
+       stx syscall
 
        rep #$10
        .i8
@@ -130,6 +149,9 @@ sigret:
 ;      I/O logic
 ;
 
+       .export _hd_kmap
+       .export _hd_read_data
+       .export _hd_write_data
 
 ;
 ;      Disk copier (needs to be in common), call with ints off
@@ -149,11 +171,12 @@ _hd_read_data:
        lda _hd_kmap            ; page number
        pha
        plb                     ; data now points into user app
-       ldy #00FE
+       ldy #$00FE
        phy
        pld                     ; DP is now the I/O space
        
        ldy #512
+hd_read:
        lda $34                 ; I/O data via DP
        sta 0,x                 ; stores into data (user) bank
        inx
@@ -176,16 +199,17 @@ _hd_write_data:
        lda _hd_kmap            ; page number
        pha
        plb                     ; data now points into user app
-       ldy #00FE
+       ldy #$00FE
        phy
        pld                     ; DP is now the I/O space
        
        ldy #512
+hd_write:
        lda 0,x                 ; load from data (user) bank
        sta $34                 ; I/O data via DP
        inx
        dey
-       bne hd_read
+       bne hd_write
        plb                     ; restore bank registers
        pld
        sep #$10
@@ -194,5 +218,5 @@ _hd_write_data:
 
        .bss
 
-_hd_map:
+_hd_kmap:
        .res 1
index 00914e1..1d7c36e 100644 (file)
@@ -7,12 +7,17 @@
 
        .import outxa, popax
        .importzp ptr2, tmp2
+
+       .p816
+       .a8
+       .i8
+
 ;
 ;      ptr1 and tmp1 are reserved for map_* functions in 6502 but
 ;      are actually free here. We keep the convention however in case
 ;      of future changes
 ;
-       .segment "COMMONMEM"
+       .code
 
 ; user, dst, count(count in ax)
 ;
@@ -39,7 +44,7 @@ __uget:       sta     tmp2
        beq     ug_nomov                ; 0 means 64K!
        dec                             ; need 1 less than size
 ugetpatch:
-       mvn     0,KERNEL_BANK:0
+       mvn     0,KERNEL_FAR
 ug_nomov:
        .i8
        .a8
@@ -65,7 +70,7 @@ __ugets:
        ldy     #0                      ; counter
 
        ldx     tmp2+1                  ; how many 256 byte blocks
-       beq     __uget_tail             ; if none skip to the tail
+       beq     __ugets_tail            ; if none skip to the tail
 
 __ugets_blk:
        phb
@@ -160,7 +165,7 @@ __uput:
        beq     up_nomov                ; 0 means 64K!
        dec                             ; need 1 less than size
 uputpatch:
-       mvn     KERNEL_BANK:0,0
+       mvn     KERNEL_FAR,0
 up_nomov:
        .i8
        .a8
@@ -212,7 +217,8 @@ __uzero:
        phb
        pha
        plb
-       clz     (ptr2)
+       lda     #0
+       sta     (ptr2)
        plb
 
        phb