Skip to content

Commit

Permalink
65c816: start on kernel bits
Browse files Browse the repository at this point in the history
Need to add the far types to the assembler to progress this
  • Loading branch information
EtchedPixels committed Oct 9, 2023
1 parent f32d5eb commit 678025a
Show file tree
Hide file tree
Showing 8 changed files with 241 additions and 229 deletions.
23 changes: 7 additions & 16 deletions Kernel/cpu-65c816/cpu.h
Original file line number Diff line number Diff line change
@@ -1,25 +1,18 @@
/*
* We treat the 65c816 as a glorified 6502.
* Processes are executed in 65c816 mode with their own 64K bank set by
* the bank registers. The CPU stack is 256 bytes in low 64K, and the
* direct page likewise.
*
* Because cc65 stores temporaries and return addresses on the CPU stack,
* and uses ZP for register variables (whom in C you cannot take the
* address of) this works fine for CC65 apps and the kernel likewise only
* has to worry about 16bit pointers except for user copies and asm bits.
* 65C816 native mode. We run mostly in 16bit mode so we look like
* any other normal littl endian 8/16bit CPU setup
*/

#define uputp uputw /* Copy user pointer type */
#define ugetp ugetw /* between user and kernel */
#define uputi uputw /* Copy user int type */
#define ugeti ugetw /* between user and kernel */

extern void * __fastcall__ memcpy(void *, void *, size_t);
extern void * __fastcall__ memset(void *, int, size_t);
extern size_t __fastcall__ strlen(const char *);
extern void * memcpy(void *, void *, size_t);
extern void * memset(void *, int, size_t);
extern size_t strlen(const char *);

#define staticfast static
#define staticfast

/* Handled with an asm helper on this processor due to the dual stacks */
extern uint16_t brk_limit(void);
Expand All @@ -41,11 +34,9 @@ typedef union { /* this structure is endian dependent */
/* No support for inline */
#define inline

/* FIXME: should swap a/b inline ??? */
#define ntohs(x) ((((x) & 0xFF) << 8) | (((x) & 0xFF00) >> 8))

/* cc65 really wants structs used repeatedly to be marked register */
#define regptr register
#define regptr

#define __packed
#define barrier()
Expand Down
2 changes: 1 addition & 1 deletion Kernel/cpu-65c816/image.mk
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
fuzix.bin: target $(OBJS)
+make -C platform-$(TARGET) image
+make -C platform/platform-$(TARGET) image
File renamed without changes.
40 changes: 18 additions & 22 deletions Kernel/cpu-65c816/rules.mk
Original file line number Diff line number Diff line change
@@ -1,25 +1,21 @@
export CROSS_AS=ca65
export CROSS_LD=cl65
export CROSS_CC=cl65
export CROSS_CCOPTS=--cpu 65c02 -c -O -Os -Or -t none -I$(ROOT_DIR)/cpu-65c816 -I$(ROOT_DIR)/cpu-6502 -I$(ROOT_DIR)/platform-$(TARGET) -I$(ROOT_DIR)/include
#
# It really doesn't matter how we map the segments as it's one binary
# with no banking or tricks. The only exception is the discard area
# so we can turn it into buffers
#
export CROSS_CC_SEG1=--code-name CODE
export CROSS_CC_SEG2=--code-name CODE
export CROSS_CC_SEG3=--code-name CODE
export CROSS_CC_SYS1=--code-name CODE
export CROSS_CC_SYS2=--code-name CODE
export CROSS_CC_SYS3=--code-name CODE
export CROSS_CC_SYS4=--code-name CODE
export CROSS_CC_SYS5=--code-name CODE
export CROSS_CC_VIDEO=--code-name CODE
export CROSS_CC_FONT=--code-name CODE
export CROSS_CC_NETWORK=--code-name CODE
export CROSS_CC_SEGDISC=--code-name DISCARD --rodata-name DISCARDDATA
export ASMEXT = .s
export CROSS_AS=cc65c816 -X -c
export CROSS_LD=ld65c816
export CROSS_CC=cc65c816
export CROSS_CCOPTS= -X -c -Os -I$(ROOT_DIR)/cpu-$(CPU) -I$(ROOT_DIR)/platform/platform-$(TARGET) -I$(ROOT_DIR)/include
export CROSS_CC_SEG2=
export CROSS_CC_SEG3=
export CROSS_CC_SEG4=
export CROSS_CC_SEGDISC= -Tdiscard
export CROSS_CC_FONT=
export CROSS_CC_VIDEO=
export CROSS_CC_NETWORK=
export CROSS_CC_SYS1=
export CROSS_CC_SYS2=
export CROSS_CC_SYS3=
export CROSS_CC_SYS4=
export CROSS_CC_SYS5=
export ASOPTS=-c
export ASMEXT = .S
export BINEXT = .o
export BITS=16
export EXECFORMAT=16
22 changes: 22 additions & 0 deletions Kernel/cpu-65c816/stdarg.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* stdarg.h - variable arguments
*
* From the ack cc
*
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Id$ */

#ifndef _STDARG_H
#define _STDARG_H

typedef char* va_list;

#define __vasz(x) ((sizeof(x)+sizeof(int)-1) & ~(sizeof(int) -1))

#define va_start(ap, parmN) (ap = (va_list)&parmN + __vasz(parmN))
#define va_arg(ap, type) (*((type *)(void *)((ap += __vasz(type)) - __vasz(type))))
#define va_end(ap)

#endif
8 changes: 8 additions & 0 deletions Kernel/cpu-65c816/stdbool.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#ifndef __STDBOOL_H
#define __STDBOOL_H

typedef unsigned char bool;

#define true 1
#define false 0
#endif
185 changes: 185 additions & 0 deletions Kernel/cpu-65c816/usermem_std-65c816.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
#include "build/kernel.def"
#include "kernel816.def"

.export __uget, __ugetc, __ugetw
.export __uput, __uputc, __uputw, __uzero

.65c816
.a16
.i16

;
; ptr1 and tmp1 are reserved for map_* functions in 6502 but
; are actually free here.
;
.code

; user, dst, count(count in ax)
;
; These use mvn which uses Y so we need interrupts off. We might want
; to do some other kind of fast copy loop if possible or split this
; into say 256 byte bursts with ints on/off between ?
;
__uget:
php
sei
phy
lda U_DATA__U_PAGE
sep #0x20
.a8
sta KERNEL_CODE+kpatch+1 ; FIXME: f:KERNEL_CODE+
; as we might be split I/D
rep #0x20
.a16
lda 4,y ; number
beq nomove
ldx 0,y ; src
pha
lda 2,y ; dst
tay
pla
phb
kpatch:
mvn #0,#KERNEL_BANK
plb
nomove:
ply
lda #0
plp
rts

__ugetc:
ldx 0,y
phb
lda U_DATA__U_PAGE
pha
plb
sep #0x20
.a8
lda 0,x
rep #0x20
.a16
plb
iny
iny
rts

__ugetw:
ldx 0,y
phb
lda U_DATA__U_PAGE
pha
plb
lda 0,x
plb
iny
iny
rts

__uput:
php
sei
phy
lda U_DATA__U_PAGE
sep #0x20
.a8
sta KERNEL_CODE+kpatch2+2 ; FIXME: far
; as we might be split I/D
rep #0x20
.a16
lda 4,y ; number
beq nomove
ldx 0,y ; src
pha
lda 2,y ; dst
tay
pla
phb
kpatch2:
mvn #KERNEL_BANK,#0
plb
nomove:
ply
lda #0
plp
jmp __fnexit6

__uputc:
ldx 2,y
phb
lda U_DATA__U_PAGE
pha
lda 0,y
plb
.a8
rep #0x20
sta 0,x
.a16
sep #0x20
plb
lda #0
iny
iny
iny
iny
rts

__uputw:
ldx 2,y
phb
lda U_DATA__U_PAGE
pha
lda 0,y
plb
sta 0,x
plb
lda #0
iny
iny
iny
iny
rts

__uzero:
lda U_DATA__U_PAGE
sta KERNEL_CODE+uzero_patch+1 ; FIXME far
sta KERNEL_CODE+uzero_patch+2

; Clear lead byte in user space
ldx 0,y
phb
pha
plb
lda #0
sep #0x20
.a8
sta 0,x
rep #0x20
.a16
plb

; Set up an overlapping block move
ldx 0,y
lda 2,y
beq nowork
dec a
beq nowork

phb ; save bank
php ; save flags
sei ; ints off
phy ; save stack

txy ; set y up as overlap ptr (x + 1)
iny ; for destination
; Use mvn to wipe the range required
; The set up is worth it as most uzero() calls are big
; ranges
uzero_patch:
mvn #0,#0
ply ; get c stack back
plp ; interrupts back as they were
nowork:
plb ; bank back as it was
lda #0 ; all good
rts
Loading

0 comments on commit 678025a

Please sign in to comment.