-
Notifications
You must be signed in to change notification settings - Fork 17
Program Startup
The FORTH code for reading and writing the SDcard and for loading and starting all of the other environments (from images stored on SDcard) is in blocks 51-56, shown below. This also acts as an example of the output of the forth_block2ascii script.
+----------------------------------------------------------------+
051:00 |\ Multicomp extras: SDCARD access 29aug15nac| 116A
051:01 |: SDRDn ( block c-addr-dest #blocks --) | 0F14
051:02 | 0 DO 2DUP SDRD 200 + SWAP 1+ SWAP | 0B7A
051:03 | LOOP 2DROP ; | 099C
051:04 | | 0800
051:05 |: SDRD256 ( block c-addr-dest -- ) \ first 256bytes of block | 12CA
051:06 | SWAP SDLBA10 SDIDLE 0 FFD9 C! ( read) DUP 100 + SWAP DO | 0E54
051:07 | FFD9 BEGIN DUP C@ E0 = UNTIL DROP ( byte available) | 0FD3
051:08 | FFD8 C@ I C! LOOP | 09D2
051:09 | 100 0 DO ( 256 bytes) | 0A69
051:10 | FFD9 BEGIN DUP C@ E0 = UNTIL DROP ( byte available) | 0FD3
051:11 | FFD8 C@ DROP LOOP ; | 0A55
051:12 | | 0800
051:13 |: SDRD256n ( block c-addr-dest #blocks --) | 0F51
051:14 | 0 DO 2DUP SDRD256 100 + SWAP 1+ SWAP | 0BB6
051:15 | LOOP 2DROP ; | 099C
+----------------------------------------------------------------+ C98B
+----------------------------------------------------------------+
052:00 |\ Multicomp extras: SDCARD access 17jan16nac| 1164
052:01 |: SDWRn ( block c-addr-dest #blocks --) | 0F27
052:02 | 0 DO 2DUP SDWR 200 + SWAP 1+ SWAP | 0B8D
052:03 | LOOP 2DROP ; | 099C
052:04 | | 0800
052:05 |: SDWRZ ( block -- ) \ write 512 bytes of 0 | 0ED5
052:06 | SDLBA10 SDIDLE 1 FFD9 C! ( write) 200 0 DO | 0CCB
052:07 | FFD9 BEGIN DUP C@ A0 = UNTIL DROP ( space available) | 1007
052:08 | 0 FFD8 C! LOOP ; | 0991
052:09 | | 0800
052:10 | | 0800
052:11 | | 0800
052:12 | | 0800
052:13 | | 0800
052:14 | | 0800
052:15 | | 0800
+----------------------------------------------------------------+ AAEC
+----------------------------------------------------------------+
053:00 |\ Multicomp extras: helpers for bootloaders 22jun15nac| 1508
053:01 |: piv ( --) \ helper for PIVOT, PIVOTRST | 0EA0
053:02 | 4F 1000 C! ( CLRA) | 0952
053:03 | 1F8B 1001 ! ( TFR A,DP) | 09D2
053:04 | 86A0 1003 ! ( LDA #A0) | 095A
053:05 | B7 1005 C! FFDE 1006 ! ( STA FFDE ; page ROM out) | 0D6C
053:06 | 1000 EXECUTE | 0974
053:07 |; | 081B
053:08 | | 0800
053:09 |: PIVOT ( addr --) \ copy to RAM, init DP, disable ROM, jump | 1256
053:10 | 7E 1008 C! 1009 ! ( JMP addr ; go there) | 0CD0
053:11 | piv ; | 090A
053:12 | | 0800
053:13 |: PIVOTRST ( - ) \ copy to RAM, init DP, disable ROM, jump rst | 12C0
053:14 | 6E9F 1008 ! FFFE 100A ! ( JMP [FFFE] ; go there) | 0D7E
053:15 | piv ; | 090A
+----------------------------------------------------------------+ C099
+----------------------------------------------------------------+
054:00 |: MMUMAP \ enable MMU with 1-1 mapping 29aug15nac| 1110
054:01 | 10 0 DO I DUP 8 LSHIFT OR FFDE ! LOOP 20 FFDE C! ; | 0CFF
054:02 | | 0800
054:03 |: EFTOCD ( --) \ map top 8K to C000-DFFF so it can be loaded | 1164
054:04 | 2607 FFDE ! ; | 0900
054:05 | | 0800
054:06 |: CDTOCD ( --) \ restore 1-1 map | 0CA3
054:07 | 2606 FFDE ! ; | 08FF
054:08 | | 0800
054:09 | | 0800
054:10 | | 0800
054:11 | | 0800
054:12 | | 0800
054:13 | | 0800
054:14 | | 0800
054:15 | | 0800
+----------------------------------------------------------------+ 9E15
+----------------------------------------------------------------+
055:00 |\ Multicomp extras: start CUBIX/BASIC/BUGGY/FORTH 29aug15nac| 13E0
055:01 |: CUBIX \ 4KB from SD at 0x2.0000 | 0C7A
055:02 | MMUMAP EFTOCD | 0A02
055:03 | 2 SDLBA2 0 D800 4 SDRDn 0 SDLBA2 \ load bootloader to F800 | 1095
055:04 | CDTOCD PIVOTRST ; \ restore map, go thru RST | 1053
055:05 | | 0800
055:06 |: SDBOOT ( n - ) \ 8KB from SD at 0x2.nnnn and jmp thru RST | 11A8
055:07 | MMUMAP EFTOCD 2 SDLBA2 | 0AEC
055:08 | ( n ) C000 10 SDRDn 0 SDLBA2 \ load 8Kb from n to E000 | 0F11
055:09 | CDTOCD 2787 FFDE ! PIVOTRST ; \ restore map, protect, jmp | 11E3
055:10 |: BASIC 1000 SDBOOT ; \ on SD at 0x2.1000 | 0CD1
055:11 |: SDFORTH 0FF0 SDBOOT ; \ on SD at 0x2.0FF0 - blk file with src | 11C9
055:12 |: BUGGY \ 7KB from SD at 0x2.1E00 | 0C96
055:13 | MMUMAP EFTOCD | 0A02
055:14 | 2 SDLBA2 1E00 C400 E SDRDn 0 SDLBA2 \ load to E400 | 0DF7
055:15 | CDTOCD PIVOTRST ; \ restore map, go thru RST vector | 1226
+----------------------------------------------------------------+ E61B
+----------------------------------------------------------------+
056:00 |\ Multicomp extras: start FLEX/NITROS9/FUZIX 10may16nac| 1351
056:01 |: FLEX \ 512 bytes (256 used) from SD at 0x2.2000 | 0F2D
056:02 | MMUMAP | 090D
056:03 | 2 SDLBA2 2000 C100 SDRD 0 SDLBA2 | 0B15
056:04 | C100 PIVOT ; ( entry point of loader) | 0EDA
056:05 | | 0800
056:06 |: NITROS9 \ load track34 and start it | 0F48
056:07 | \ disk is on SD at 0x2.8000 so track34 is at 0x2.84C8 | 10BA
056:08 | MMUMAP EFTOCD | 0A02
056:09 | 2 SDLBA2 84C8 2600 \ load from 0x2.84C8 to 2600 | 0E03
056:10 | 12 SDRD256n 0 SDLBA2 \ 18 (hex 12) 256-byte sectors | 0F62
056:11 | \ vectors to RAM expected by krn | 0F5D
056:12 | 0100 DFF2 ! 0103 DFF4 ! 010F DFF6 ! \ SWI3 SWI2 FIRQ | 0CA4
056:13 | 010C DFF8 ! 0106 DFFA ! 0109 DFFC ! \ IRQ SWI NMI | 0C73
056:14 | CDTOCD 2602 PIVOT ; \ restore map, start at 2602 | 0FFF
056:15 |: FUZIX MMUMAP 3 SDLBA2 0 D000 SDRD D000 PIVOT ; | 0D7A
+----------------------------------------------------------------+ DAD0
In the following sections, a reference like this: (056:15) refers to block 56, line 15: the definition for FUZIX.
The code for starting BASIC (055:10) is straightforward. The executable image is on the SDcard at block offset 0x2.1000. That block offset is placed on the stack and control is passed to SDBOOT.
If you experiment with modifying CamelForth you can load and start a new version by placing it on the SDcard, avoiding the need to reprogram the FPGA. What is placed on the SDcard is the block file chromium.scr which contains the built binary. chromium.scr is put on the SDcard at block offset 0x2.0E00 and the binary within it is at block offset 0x2.0FF0. That block offset is placed on the stack and control is passed to SDBOOT.
This helper word is used to load and start binary images that
- are 8Kbytes in size
- load at a start address of $E000 so that they occupy the top 8Kbytes of the address space
- contain a 6809 vector table so that their entry point is at the address that will be stored in address $FFFE, $FFFF.
- are not self-modifying
In other words, images that are exactly suitable for replacing the boot ROM.
The image is going to end up where the CamelForth ROM is currently located. The image is going to be write-protected (BASIC in particular requires this: when it starts it does a memory-sizing and will quite happily and fatally overwrite a RAM copy of itself as part of this process).
MMUMAP initialises the memory-mapping unit at sets up what I call a "flat map" - a 1-to-1 mapping between logical and physical addresses. EFTOCD maps the RAM from address $E000-$FFFF so that it also appears at address $C000-$DFFF. The sequence 2 SDLBA2.. SDLBA2 loads 8Kbytes of data into RAM at $C000 (the final 0 SDLBA2 is defensive and probably not strictly necessary). CDTOCD restores the 1-to-1 mapping. At this point the new image is in RAM at address $E000-$FFFF but cannot be accessed because the ROM is still enabled and takes priority. 2787 FFDE ! write-protects the top 8Kbytes of RAM. The final step is PIVOTRST (described in the next section) which disables the ROM and passes control to the new image.
The clever stuff is in piv. PIVOT and PIVOTRST are two ways of using it. The goal is to disable the ROM so that it disappears from the memory map, leaving the underlying RAM accessible. The problem is that we're currently executing from ROM so we cannot simply disable it. The solution is to build an executable code fragment in RAM somewhere and branch to it from the ROM. The function of the code fragment is to disable the ROM and then branch to the new image's entry point.
ENTRY CLRA
TFR A, DP CamelForth sets the DP to 6 but everything else expects a value of 0
LDA #A0
STA FFDE Page out the ROM - refer to the Multicomp6809 programming guide
JMP xxxx Ending when piv is called from PIVOT
JMP [FFFE] Ending when piv is called from PIVRST
PIVOTRST is used for images that are ROM-like. It builds and executes a code fragment that ends by jumping through the reset vector in the image.
PIVOT is used for images with a pre-defined entry point; the entry point is passed on the stack and PIVOT lays own that entry point in the code fragment, which ends with a JMP.