Added banking for the apple2enh target.
The machines targeted by apple2enh mostly do have 128kB of RAM. But it's not that easy to make use of banking in an event driver system like Contiki. Anyway I discovered one scenario feasable: The machines in question allow to bank in just 8kB of the second 64kB into the address space (at a fixed location).
The Contiki Kernel consists of three major parts: The Event Kernel (EK) which is the base system for everything else, the Contiki Tool Kit (CTK) which manages the GUI and the network stack (UIP) which does the TCP/IP handling. Both CTK and UIP make use of EK, but CTK never calls into UIP and vice versa.
The CTK code is a little larger than 8kB while the UIP code (without DNS) is a little smaller than 8kB, resulting in this setup: The UIP code is moved into the additional 8kB while making sure that the CTK code "covers" the whole memory area used for banking.
This setup allows most calls out of UIP to go without any banking simply because all callees are always visible. The only exception to this is ek_post_synch() because UIP uses it for the "Application Upcall" mechanism and I didn't want to make assumptions on the application code called.
Ordinary calls into UIP are routed through banking functions by conditional name mapping via macros. Calls into UIP via function pointers only occur for the event and poll handler. And there are fortunately already macros in place which could be (ob)used.
This is a (working) prototype with these TODOs:
- Make sure /RAM is empty on startup
- Cleanup /RAM on exit
- Support command line parameters
- ...
diff --git a/contiki-apple2/Makefile.apple2 b/contiki-apple2/Makefile.apple2
index 9910674..f246225 100644
--- a/contiki-apple2/Makefile.apple2
+++ b/contiki-apple2/Makefile.apple2
@@ -30,7 +30,7 @@
#
# This file is part of the Contiki desktop environment
#
-# $Id: Makefile.apple2,v 1.18 2006/04/09 16:32:44 oliverschmidt Exp $
+# $Id: Makefile.apple2,v 1.19 2006/05/17 15:55:29 oliverschmidt Exp $
#
all: contiki
@@ -45,14 +45,21 @@
CFLAGS:=$(CFLAGSCC65) --code-name CONTIKI \
-DWITH_ASCII -DWITH_UIP -DWITH_LOADER_ARCH -DWITH_ETHERNET
-ifeq ($(SYS),apple2enh)
-CTK=ctk.o ctk-mousetext.o ctk-mouse.o
-else
+ifeq ($(SYS),apple2)
+
CTK=ctk.o ctk-conio.o
-endif
+
+else # apple2
+
+CTK=ctk.o ctk-mousetext.o ctk-mouse.o
+
+uip.s uip_arch.s uiplib.s tcpip.s: %.s: %.c
+ $(CC) $(CFLAGS) $(OPT) -DUIP_CODE -o $(notdir $@) $<
+
+endif # apple2
contiki:crt0.o main.o ek.o ek-service.o timer.o program-handler.o arg.o \
- $(CTK) $(UIP) loader-arch.o clock-arch.o bank.o kfs.o import.o \
+ loader-arch.o clock-arch.o bank.o kfs.o import.o $(CTK) $(UIP) \
www-dsc.o \
email-dsc.o \
ftp-dsc.o \
diff --git a/contiki-apple2/apple2.cfg b/contiki-apple2/apple2.cfg
index 405797c..1c386ed 100644
--- a/contiki-apple2/apple2.cfg
+++ b/contiki-apple2/apple2.cfg
@@ -32,4 +32,5 @@
}
SYMBOLS {
__STACKSIZE__ = $200;
+ __UIP_SIZE__ = $0000;
}
diff --git a/contiki-apple2/apple2enh.cfg b/contiki-apple2/apple2enh.cfg
index 0286a5a..24274c5 100644
--- a/contiki-apple2/apple2enh.cfg
+++ b/contiki-apple2/apple2enh.cfg
@@ -6,6 +6,7 @@
PIC: start = $0000, size = $FFFF, file = "contiki";
TMP: start = $0000, size = $FFFF, file = "contiki";
LC: start = $D000, size = $1000, file = "contiki";
+ AUX: start = $2000, size = $2000, file = "contiki";
}
SEGMENTS {
ZEROPAGE: load = ZP, type = zp;
@@ -19,6 +20,7 @@
BOOT: load = PIC, type = ro, define = yes;
INIT: load = TMP, run = RAM, type = ro, define = yes;
CODE: load = LC, type = ro, define = yes;
+ UIP: load = AUX, type = ro, define = yes;
}
FEATURES {
CONDES: segment = INIT,
diff --git a/contiki-apple2/conf/uip-conf.h b/contiki-apple2/conf/uip-conf.h
index 971e684..b4e379b 100644
--- a/contiki-apple2/conf/uip-conf.h
+++ b/contiki-apple2/conf/uip-conf.h
@@ -32,7 +32,7 @@
*
* This file is part of the Contiki Destop OS
*
- * $Id: uip-conf.h,v 1.3 2005/03/16 22:37:01 oliverschmidt Exp $
+ * $Id: uip-conf.h,v 1.4 2006/05/17 15:55:29 oliverschmidt Exp $
*
*/
#ifndef __UIP_CONF_H__
@@ -41,8 +41,49 @@
#define UIP_CONF_MAX_LISTENPORTS 10
#define UIP_CONF_BUFFER_SIZE 1024 - 2
#define UIP_CONF_RECEIVE_WINDOW UIP_TCP_MSS
+#define UIP_CONF_BYTE_ORDER LITTLE_ENDIAN
#define UIP_CONF_EXTERNAL_BUFFER
-#define UIP_CONF_BYTE_ORDER LITTLE_ENDIAN
+#ifdef UIP_CODE
+
+#pragma codeseg("UIP");
+
+#include "ek-conf.h"
+
+#undef EK_PROCESS_INIT
+#define EK_PROCESS_INIT(name, arg) \
+ void _tcpip_init(void *arg)
+
+#undef EK_EVENTHANDLER
+#define EK_EVENTHANDLER(name, ev, data) \
+ void _tcpip_eventhandler(ek_event_t ev, ek_data_t data)
+
+#undef EK_POLLHANDLER
+#define EK_POLLHANDLER(name) \
+ void _tcpip_pollhandler(void)
+
+#undef EK_PROCESS
+#define EK_PROCESS(name, strname, prio, eventh, pollh, stateptr) \
+ void tcpip_eventhandler(ek_event_t ev, ek_data_t data); \
+ void tcpip_pollhandler(void); \
+ static struct ek_proc name = {NULL, EK_ID_NONE, strname, prio, tcpip_eventhandler, tcpip_pollhandler, stateptr}
+
+#define htons _htons
+#define uiplib_ipaddrconv _uiplib_ipaddrconv
+#define tcp_markconn _tcp_markconn
+#define tcp_listen _tcp_listen
+#define tcp_unlisten _tcp_unlisten
+#define tcp_connect _tcp_connect
+#define udp_new _udp_new
+#define tcpip_set_forwarding _tcpip_set_forwarding
+#define tcpip_input _tcpip_input
+#define tcpip_output _tcpip_output
+#define tcpip_poll_tcp _tcpip_poll_tcp
+#define tcpip_poll_udp _tcpip_poll_udp
+
+#define ek_post_synch _ek_post_synch
+void _ek_post_synch(ek_id_t id, ek_event_t ev, ek_data_t data);
+
+#endif /* UIP_CODE */
#endif /* __UIP_CONF_H__ */
diff --git a/contiki-apple2/lib/bank.S b/contiki-apple2/lib/bank.S
index 1d7e504..9d3d866 100644
--- a/contiki-apple2/lib/bank.S
+++ b/contiki-apple2/lib/bank.S
@@ -2,10 +2,10 @@
; Bank switching code for Contiki (Apple2 version)
;
- .export VTABZ
-
.segment "CONTIKI"
+ .export VTABZ
+
VTABZ:
; Switch in ROM and call VTABZ
bit $C082
@@ -14,3 +14,125 @@
; Switch in LC bank 2 for R/O and return
bit $C080
rts
+
+.ifdef __APPLE2ENH__
+
+ .code
+
+main2aux:
+ ; Switch in $2000-$3FFF from aux memory
+ bit $C055 ; Page2
+ bit $C057 ; HiRes
+ rts
+
+aux2main:
+ ; Switch in $2000-$3FFF from main memory
+ bit $C056 ; LoRes
+ bit $C054 ; Page1
+ rts
+
+ .export _tcpip_init
+ .import __tcpip_init
+
+_tcpip_init:
+ jsr main2aux
+ jsr __tcpip_init
+ jmp aux2main
+
+ .export _tcpip_eventhandler
+ .import __tcpip_eventhandler
+
+_tcpip_eventhandler:
+ jsr main2aux
+ jsr __tcpip_eventhandler
+ jmp aux2main
+
+ .export _tcpip_pollhandler
+ .import __tcpip_pollhandler
+
+_tcpip_pollhandler:
+ jsr main2aux
+ jsr __tcpip_pollhandler
+ jmp aux2main
+
+ .export _htons
+ .import __htons
+
+_htons:
+ jsr main2aux
+ jsr __htons
+ jmp aux2main
+
+ .export _uiplib_ipaddrconv
+ .import __uiplib_ipaddrconv
+
+_uiplib_ipaddrconv:
+ jsr main2aux
+ jsr __uiplib_ipaddrconv
+ jmp aux2main
+
+ .export _tcp_markconn
+ .import __tcp_markconn
+
+_tcp_markconn:
+ jsr main2aux
+ jsr __tcp_markconn
+ jmp aux2main
+
+ .export _tcp_listen
+ .import __tcp_listen
+
+_tcp_listen:
+ jsr main2aux
+ jsr __tcp_listen
+ jmp aux2main
+
+ .export _tcp_unlisten
+ .import __tcp_unlisten
+
+_tcp_unlisten:
+ jsr main2aux
+ jsr __tcp_unlisten
+ jmp aux2main
+
+ .export _tcp_connect
+ .import __tcp_connect
+
+_tcp_connect:
+ jsr main2aux
+ jsr __tcp_connect
+ jmp aux2main
+
+ .export _udp_new
+ .import __udp_new
+
+_udp_new:
+ jsr main2aux
+ jsr __udp_new
+ jmp aux2main
+
+ .export _tcpip_input
+ .import __tcpip_input
+
+_tcpip_input:
+ jsr main2aux
+ jsr __tcpip_input
+ jmp aux2main
+
+ .export _tcpip_poll_udp
+ .import __tcpip_poll_udp
+
+_tcpip_poll_udp:
+ jsr main2aux
+ jsr __tcpip_poll_udp
+ jmp aux2main
+
+ .export __ek_post_synch
+ .import _ek_post_synch
+
+__ek_post_synch:
+ jsr aux2main
+ jsr _ek_post_synch
+ jmp main2aux
+
+.endif
diff --git a/contiki-apple2/lib/crt0.S b/contiki-apple2/lib/crt0.S
index 786541d..03cdcf9 100644
--- a/contiki-apple2/lib/crt0.S
+++ b/contiki-apple2/lib/crt0.S
@@ -7,12 +7,13 @@
.export _exit
.import zerobss, initlib, callmain, donelib
.ifdef __APPLE2ENH__
- .import callirq
+ .import _uip_buf, callirq
.endif
- .import __STARTUP_RUN__, __BOOT_SIZE__ ; Linker generated
+ .import __STARTUP_RUN__ ; Linker generated
.import __BSS_RUN__, __BSS_SIZE__ ; Linker generated
.import __INIT_RUN__, __INIT_SIZE__ ; Linker generated
.import __CODE_RUN__, __CODE_SIZE__ ; Linker generated
+ .import __BOOT_SIZE__, __UIP_SIZE__ ; Linker generated
.importzp sp
.linecont +
@@ -23,8 +24,8 @@
.word __STARTUP_RUN__ ; Start address
.word __BSS_RUN__ + __BOOT_SIZE__ + \
- __INIT_SIZE__ + __CODE_SIZE__ - \
- __STARTUP_RUN__ ; Size
+ __INIT_SIZE__ + __CODE_SIZE__ + \
+ __UIP_SIZE__ - __STARTUP_RUN__ ; Size
; ------------------------------------------------------------------------
; Place the startup code in a special segment.
@@ -40,7 +41,7 @@
; ProDOS TechRefMan, chapter 6.2:
; "Each installed routine must begin with a CLD instruction."
-intrpt: cld
+irq: cld
; Switch in LC bank 2 for R/O
@@ -95,10 +96,10 @@
; Deallocate interrupt vector table entry
- dec params ; Adjust parameter count
+ dec intrpt ; Adjust parameter count
jsr $BF00
.byte $41 ; Dealloc interrupt
- .addr params
+ .addr intrpt
.endif
@@ -111,25 +112,13 @@
jmp $03D0
; ------------------------------------------------------------------------
-; The linker doesn't calculate where this code runs so it has to be PIC
+; The linker doesn't understand that the "BOOT" segment overlays the "BSS"
+; segment so the automatic fixup of references to the "BOOT" segment does
+; not work. Therefore references to this segment have to be expressed as
+; offsets to __BSS_RUN__.
.segment "BOOT"
-.ifdef __APPLE2ENH__
-
-; Allocate interrupt vector table entry
-
- jsr $BF00
- .byte $40 ; Alloc interrupt
- .addr params
-
-; Switch to 80 column mode
-
- lda #$0D
- jsr $C300
-
-.endif
-
; Setup the stack at HIMEM
lda $73
@@ -156,6 +145,48 @@
eor #$A5
sta $03F4
+.ifdef __APPLE2ENH__
+
+; Allocate interrupt vector table entry
+
+ jsr $BF00
+ .byte $40 ; Alloc interrupt
+ .addr intrpt
+
+; Switch to 80 column mode here to show some progress
+
+ lda #$0D
+ jsr $C300
+
+; ProDOS TechRefMan, chapter 5.2.2.1:
+; "... you may protect those areas of auxiliary memory. If you save a
+; dummy 8K file as the first entry in /RAM, it will always be saved
+; at $2000 to $3FFF."
+;
+; Relocate the "UIP" segment by writing it to /RAM as the first file.
+
+ jsr $BF00
+ .byte $C0 ; Create file
+ .addr create
+
+ jsr $BF00
+ .byte $C8 ; Open file
+ .addr open
+
+ lda o_ref
+ sta w_ref
+ sta c_ref
+
+ jsr $BF00
+ .byte $CB ; Write file
+ .addr write
+
+ jsr $BF00
+ .byte $CC ; Close file
+ .addr close
+
+.endif
+
; Switch in LC bank 2 for W/O
bit $C081
@@ -220,6 +251,47 @@
; Forward control to code in the "INIT" segment
jmp init
+
+.ifdef __APPLE2ENH__
+
+create = __BSS_RUN__ + *
+ .byte $07 ; Parameter count
+ .addr name ; Pathname
+ .byte %11000011 ; Access: Standard full access
+ .byte $00 ; File type: Typeless file
+ .word $0000 ; Aux type: N/A
+ .byte $01 ; Storage type: Standard seedling file
+ .word $0000 ; Create date: Current date
+ .word $0000 ; Create time: Current time
+
+open = __BSS_RUN__ + *
+ .byte $03 ; Parameter count
+ .addr name ; Pathname
+ .addr _uip_buf ; IO buffer
+o_ref = __BSS_RUN__ + *
+ .byte $00 ; Reference number
+
+write = __BSS_RUN__ + *
+ .byte $04 ; Parameter count
+w_ref = __BSS_RUN__ + *
+ .byte $00 ; Reference number
+ .addr __BSS_RUN__ + \
+ __BOOT_SIZE__ + \
+ __INIT_SIZE__ + \
+ __CODE_SIZE__ ; Data buffer
+ .word __UIP_SIZE__ ; Requested count
+ .word $0000 ; Transfered count
+
+close = __BSS_RUN__ + *
+ .byte $01 ; Parameter count
+c_ref = __BSS_RUN__ + *
+ .byte $00 ; Reference number
+
+name = __BSS_RUN__ + *
+ .byte 14
+ .byte "/RAM/CONTIKI.1"
+
+.endif
; ------------------------------------------------------------------------
; The "INIT" segment will be overwritten by the heap
@@ -247,8 +319,8 @@
.ifdef __APPLE2ENH__
-params: .byte $02 ; Parameter count
+intrpt: .byte $02 ; Parameter count
.byte $00 ; Interrupt number
- .addr intrpt ; Interrupt handler
+ .addr irq ; Interrupt handler
.endif
\ No newline at end of file