mirror of
https://github.com/mgcaret/of816.git
synced 2025-01-15 23:31:01 +00:00
Working on the Neon816
This commit is contained in:
parent
e73066a53f
commit
e79e2974e5
2
.gitignore
vendored
2
.gitignore
vendored
@ -10,4 +10,6 @@ t
|
|||||||
*.po
|
*.po
|
||||||
romfs
|
romfs
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
*.hex
|
||||||
|
of816-neon.bin
|
||||||
|
|
||||||
|
@ -1,6 +1,31 @@
|
|||||||
|
|
||||||
|
; Bank Map from FB posting by Lenore:
|
||||||
|
; 00 Bank Mapper (16 blocks of 4k each, configured via MMU)
|
||||||
|
; 08-0F Bus Controller Peripherals
|
||||||
|
; - 08 0000-003F MMU
|
||||||
|
; -- 00: 0-3 Unused, 4-7: Upper RAM bits
|
||||||
|
; -- 01: Bank
|
||||||
|
; - 09 FDC
|
||||||
|
; 10-1F Internal Bus Bridge
|
||||||
|
; 20-27 Flash ROM
|
||||||
|
; 28-3F Reserved for Flash
|
||||||
|
; 30-3F Reserved for Expansion Flash
|
||||||
|
; 40-47 Video RAM
|
||||||
|
; 48-7F Reserved for VRAM
|
||||||
|
; 80-87 RAM 1
|
||||||
|
; 88-8F RAM 2
|
||||||
|
; 90-FF Reserved for RAM
|
||||||
|
|
||||||
cpu_clk = 14000000
|
cpu_clk = 14000000
|
||||||
|
|
||||||
|
; *****************
|
||||||
|
; Memory regions
|
||||||
|
; *****************
|
||||||
|
Neon_ROM = $200000
|
||||||
|
Neon_VRAM = $400000
|
||||||
|
Neon_RAM1 = $800000
|
||||||
|
Neon_RAM2 = $880000
|
||||||
|
|
||||||
; *****************
|
; *****************
|
||||||
; MMU
|
; MMU
|
||||||
; *****************
|
; *****************
|
||||||
|
@ -1,16 +1,18 @@
|
|||||||
FEATURES {
|
FEATURES {
|
||||||
STARTADDRESS: default = $0000;
|
STARTADDRESS: default = $200000;
|
||||||
}
|
}
|
||||||
|
|
||||||
MEMORY {
|
MEMORY {
|
||||||
ROM: start = $0000, size = $10000, file = %O;
|
ROM: start = $200000, size = $10000, fillval=$FF, file = %O;
|
||||||
ZP: start = $0000, size = $100;
|
ZP: start = $0000, size = $100;
|
||||||
}
|
}
|
||||||
|
|
||||||
SEGMENTS {
|
SEGMENTS {
|
||||||
FStartup: load=ROM,type=ro;
|
FStartup: load=ROM, type=ro, fillval=$00;
|
||||||
FSystem: load=ROM, type=ro;
|
FSystem: load=ROM, type=ro, fillval=$00;
|
||||||
FCode: load=ROM, type=ro, optional=yes;
|
FCode: load=ROM, type=ro, fillval=$00, optional=yes;
|
||||||
|
ROMBOOT: load=ROM, type=ro, offset=$FF00;
|
||||||
|
VECTORS: load=ROM, type=ro, offset=$FFE0;
|
||||||
ZEROPAGE: load=ZP, type=bss;
|
ZEROPAGE: load=ZP, type=bss;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,65 +7,31 @@
|
|||||||
.import _Forth_ui
|
.import _Forth_ui
|
||||||
.import _system_interface
|
.import _system_interface
|
||||||
|
|
||||||
; Bank Map from FB posting by Lenore:
|
|
||||||
; 00 Bank Mapper (16 blocks of 4k each, configured via MMU)
|
|
||||||
; 08-0F Bus Controller Peripherals
|
|
||||||
; - 08 0000-003F MMU
|
|
||||||
; -- 00: 0-3 Unused, 4-7: Upper RAM bits
|
|
||||||
; -- 01: Bank
|
|
||||||
; - 09 FDC
|
|
||||||
; 10-1F Internal Bus Bridge
|
|
||||||
; 20-27 Flash ROM
|
|
||||||
; 28-3F Reserved for Flash
|
|
||||||
; 30-3F Reserved for Expansion Flash
|
|
||||||
; 40-47 Video RAM
|
|
||||||
; 48-7F Reserved for VRAM
|
|
||||||
; 80-87 RAM 1
|
|
||||||
; 88-8F RAM 2
|
|
||||||
; 90-FF Reserved for RAM
|
|
||||||
|
|
||||||
.pushseg
|
.pushseg
|
||||||
.segment "FStartup"
|
.segment "FStartup"
|
||||||
.proc startup
|
.proc startup
|
||||||
clc
|
clc
|
||||||
xce
|
xce
|
||||||
rep #SHORT_A|SHORT_I
|
phk
|
||||||
.a16
|
plb
|
||||||
.i16
|
|
||||||
; MMU setup, maybe. Found at page $FF in Neon bank 0
|
|
||||||
ldx #$001C
|
|
||||||
lda #$8000
|
|
||||||
: sta f:NeonMMU,x
|
|
||||||
dex
|
|
||||||
dex
|
|
||||||
bpl :-
|
|
||||||
; NeonFORTH does this, presumably to initialize the serial port
|
|
||||||
sep #SHORT_A ; not necessary unless we were already native & long
|
|
||||||
.a8
|
|
||||||
lda #$8D
|
|
||||||
sta f:SERctrlA
|
|
||||||
lda #$06
|
|
||||||
sta f:SERctrlB
|
|
||||||
lda #$00
|
|
||||||
sta f:SERctrlC
|
|
||||||
rep #SHORT_A|SHORT_I
|
rep #SHORT_A|SHORT_I
|
||||||
.a16
|
.a16
|
||||||
.i16
|
.i16
|
||||||
lda #$0000 ; direct page for Forth
|
lda #$0000 ; direct page for Forth
|
||||||
tcd
|
tcd
|
||||||
lda #.hiword($0A0000) ; top of dictionary memory
|
lda #.hiword(Neon_RAM1+$020000) ; top of dictionary memory
|
||||||
pha
|
pha
|
||||||
lda #.loword($0A0000)
|
lda #.loword(Neon_RAM1+$020000)
|
||||||
pha
|
pha
|
||||||
lda #.hiword($090000) ; bottom of dictionary
|
lda #.hiword(Neon_RAM1+$010000) ; bottom of dictionary
|
||||||
pha
|
pha
|
||||||
lda #.loword($090000)
|
lda #.loword(Neon_RAM1+$010000)
|
||||||
pha
|
pha
|
||||||
lda #$0200 ; first usable stack cell (relative to direct page)
|
lda #$0400 ; first usable stack cell (relative to direct page)
|
||||||
pha
|
pha
|
||||||
lda #$0100 ; last usable stack cell+1 (relative to direct page)
|
lda #$0204 ; last usable stack cell+1 (relative to direct page)
|
||||||
pha
|
pha
|
||||||
lda #$03FF ; return stack first usable byte
|
lda #$01EF ; return stack first usable byte
|
||||||
pha
|
pha
|
||||||
lda #.hiword(_system_interface)
|
lda #.hiword(_system_interface)
|
||||||
pha
|
pha
|
||||||
@ -73,7 +39,6 @@
|
|||||||
pha
|
pha
|
||||||
jsl _Forth_initialize
|
jsl _Forth_initialize
|
||||||
jsl _Forth_ui
|
jsl _Forth_ui
|
||||||
brk
|
jmp startup
|
||||||
.byte $00
|
|
||||||
.endproc
|
.endproc
|
||||||
.popseg
|
.popseg
|
||||||
|
@ -1,21 +1,66 @@
|
|||||||
|
|
||||||
# Neon816
|
# Neon816
|
||||||
|
|
||||||
This is a port to Lenore Byron's [Neon816](https://hackaday.io/project/164325-neon816)
|
This is a port to Lenore Byron's [Neon816](https://hackaday.io/project/164325-neon816) system. The Neon816 Developer Edition ships with a small 16-bit Forth.
|
||||||
system. The Neon816 Developer Edition ships with a small 16-bit Forth.
|
|
||||||
|
|
||||||
At the time of commit 91af87fa4e42dced1d22d3cb620e84e6edb91817, OF816 for the Neon816
|
OF816 for the Neon816 is configured to run as an alternative firmware out of bank $20. With a little ajustment, it could be configured to run out of bank $21 (but starting it is an excercise for the reader).
|
||||||
is configured to run out of any available ROM bank at starting address $0000. It configures
|
|
||||||
the MMU hopefully like NeonFORTH does, sets the data stack from $0000-$01FF and the return stack from $0200-$03FF. It hopefully also configures the serial port.
|
It configures the MMU and serial port like NeonFORTH does. The direct page, stack, and return stack occupy the first $400 bytes of RAM.
|
||||||
|
|
||||||
To build OF816 for the Neon816, change to the platform directory and run
|
To build OF816 for the Neon816, change to the platform directory and run
|
||||||
build.sh. It will output a binary named "forth" that can be started at address $0000 of the
|
``build.sh``. It will output a 64K binary named ``of816-neon.bin`` that can be flashed into the Neon's firmware. See below for installation instructions.
|
||||||
bank it is loaded into.
|
|
||||||
|
|
||||||
At this point nothing further can be done until we have the ability to use the debug port to
|
|
||||||
load OF816 into the flash ROM.
|
|
||||||
|
|
||||||
## Port Features
|
## Port Features
|
||||||
|
|
||||||
Hopefully this section will be filled up with stuff that works like Lenore's
|
Hopefully this section will be filled up with stuff that works like Lenore's
|
||||||
Forth. See the [Neon816 Manual](https://cdn.hackaday.io/files/1643257030480800/sysmanual.pdf)
|
Forth. See the [Neon816 Manual](https://cdn.hackaday.io/files/1643257030480800/sysmanual.pdf). But right now, it's just a bare port with no system-specific extensions.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
**THIS WILL OVERWRITE THE NEON'S ORIGINAL FIRMWARE.**
|
||||||
|
|
||||||
|
**IT IS STRONGLY RECOMMENDED YOU BACK UP THE ORIGINAL FIRMWARE**
|
||||||
|
|
||||||
|
**READ _ALL_ OF THE FOLLOWING BEFORE PROCEEDING AND DO NOT PROCEED IF ANY OF THIS MAKES YOU UNCOMFORTABLE**
|
||||||
|
|
||||||
|
After building the firmware image, the image must be converted to Intel Hex format. I like the bin2hex tool found [here](https://grumpf.hope-2000.org) (page is in German). Build the ``bin2hex`` binary and execute: ``bin2hex of816-neon.bin > of816-neon.hex``
|
||||||
|
|
||||||
|
Once you have the .hex file, you will need to use the [Neon firmware loader](https://hackaday.io/project/164325-neon816) to install the image. This requires an FTDI cable connected to the 3.3V UART header on the Neon816 system board.
|
||||||
|
|
||||||
|
To back up the original firmware, you will need to add an additional command routine to neonprog.cpp (add it after the write command):
|
||||||
|
|
||||||
|
```
|
||||||
|
else if(!strcmp(cmd,"dumprom")) {
|
||||||
|
char* fn=strtok(nullptr," ");
|
||||||
|
char buf[0x40];
|
||||||
|
if(!fn) return;
|
||||||
|
auto st=Releaser(
|
||||||
|
fopen(fn,"w"),
|
||||||
|
[](auto f){if(f) fclose(f);});
|
||||||
|
if(!st) {
|
||||||
|
printf("Could not open file\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (int addr=0x200000; addr<0x220000; addr+=sizeof(buf)) {
|
||||||
|
writeHex(addr>>16,2); writeChar(':');
|
||||||
|
writeHex(addr,4); writeChar('#');
|
||||||
|
for (int i=0; i<sizeof(buf); i++) {
|
||||||
|
writeChar('@');
|
||||||
|
unsigned char c=readByte();
|
||||||
|
buf[i]=c;
|
||||||
|
}
|
||||||
|
fwrite(&buf, sizeof(buf), 1, st);
|
||||||
|
printf("%08X\n",addr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
then start neonprog with ``neonprog /dev/ttyUSBx`` (replace device with actual serial device for FTDI cable.
|
||||||
|
|
||||||
|
From within neonprog, execute ``dumprom backup.bin`` to save an image of both ROM banks to ``backup.bin``.
|
||||||
|
|
||||||
|
Once the backup has finished (it will take a while), you can proceed to the installation of OF816 with ``flash of816-neon.hex``. This will also take a while. When it is done, reset your Neon and OF816 should start.
|
||||||
|
|
||||||
|
## Restoring the Original NeonFORTH Firmware
|
||||||
|
|
||||||
|
Since the Neon (at the time of this writing) only ships with the first bank of flash occupied, first, split your backup with ``split backup.bin``. This will output two files, ``xaa`` and ``xab`` that are bank $20 and bank $21, respectively. Then run ``hex2bin xaa > neonforth.hex``. You can then flash this with neonprog using ``flash neonforth.hex``. Once it's done, reset your Neon and you should see the original firmware running.
|
||||||
|
@ -1,7 +1,12 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
set -e -x
|
set -e -x
|
||||||
ca65 -I ../../inc Neon816.s -l Neon816.lst
|
ca65 -I ../../inc Neon816.s -l Neon816.lst
|
||||||
|
ca65 -I ../../inc romboot.s -l romboot.lst
|
||||||
../../build.sh Neon816
|
../../build.sh Neon816
|
||||||
ld65 -C Neon816.l -S 0x8000 Neon816.o ../../forth.o -m forth.map -o forth
|
ld65 -C Neon816.l -S 0x8000 Neon816.o ../../forth.o ./romboot.o -m forth.map -o of816-neon.bin
|
||||||
ls -l forth
|
ls -l of816-neon.bin
|
||||||
|
if which -s bin2hex; then
|
||||||
|
hex2bin of816-neon.bin > of816-neon.hex
|
||||||
|
ls -l of816-neon.hex
|
||||||
|
fi
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
phx
|
phx
|
||||||
asl
|
asl
|
||||||
tax
|
tax
|
||||||
jmp (table,x)
|
jmp (.loword(table),x)
|
||||||
table: .addr _sf_pre_init
|
table: .addr _sf_pre_init
|
||||||
.addr _sf_post_init
|
.addr _sf_post_init
|
||||||
.addr _sf_emit
|
.addr _sf_emit
|
||||||
@ -34,8 +34,19 @@ table: .addr _sf_pre_init
|
|||||||
|
|
||||||
|
|
||||||
.proc _sf_pre_init
|
.proc _sf_pre_init
|
||||||
|
; NeonFORTH does this, presumably to initialize the serial port
|
||||||
|
sep #SHORT_A
|
||||||
|
.a8
|
||||||
|
lda #$8D
|
||||||
|
sta f:SERctrlA
|
||||||
|
lda #$06
|
||||||
|
sta f:SERctrlB
|
||||||
|
lda #$00
|
||||||
|
sta f:SERctrlC
|
||||||
|
rep #SHORT_A
|
||||||
|
.a16
|
||||||
plx
|
plx
|
||||||
jmp _sf_success ; we'll see what we need to do
|
jmp _sf_success
|
||||||
.endproc
|
.endproc
|
||||||
|
|
||||||
.proc _sf_post_init
|
.proc _sf_post_init
|
||||||
|
46
platforms/Neon816/romboot.s
Normal file
46
platforms/Neon816/romboot.s
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
.p816
|
||||||
|
.a16
|
||||||
|
.i16
|
||||||
|
.include "macros.inc"
|
||||||
|
.include "./Neon816-hw.inc"
|
||||||
|
|
||||||
|
.segment "ROMBOOT"
|
||||||
|
.proc romboot
|
||||||
|
clc
|
||||||
|
xce
|
||||||
|
rep #SHORT_A|SHORT_I
|
||||||
|
.a16
|
||||||
|
.i16
|
||||||
|
lda #$01FF
|
||||||
|
tcs
|
||||||
|
; Set up MMU for bank 0
|
||||||
|
ldx #$001C
|
||||||
|
lda #$8000
|
||||||
|
: sta f:NeonMMU,x
|
||||||
|
dex
|
||||||
|
dex
|
||||||
|
bpl :-
|
||||||
|
jml f:Neon_ROM
|
||||||
|
.endproc
|
||||||
|
|
||||||
|
.segment "VECTORS"
|
||||||
|
.proc vectors
|
||||||
|
; native mode vectors
|
||||||
|
.word $FFFF ; FFE0 - reserved
|
||||||
|
.word $FFFF ; FFE2 - reserved
|
||||||
|
.word $FFFF ; FFE4 - COP
|
||||||
|
.word $FFFF ; FFE6 - BRK
|
||||||
|
.word $FFFF ; FFE8 - ABORT
|
||||||
|
.word $FFFF ; FFEA - NMI
|
||||||
|
.word $FFFF ; FFEC - reserved
|
||||||
|
.word $FFFF ; FFEE - IRQ
|
||||||
|
; emulation mode vectors
|
||||||
|
.word $FFFF ; FFF0 - reserved
|
||||||
|
.word $FFFF ; FFF2 - reserved
|
||||||
|
.word $FFFF ; FFF4 - COP
|
||||||
|
.word $FFFF ; FFF6 - reserved
|
||||||
|
.word $FFFF ; FFF8 - ABORT
|
||||||
|
.word $FFFF ; FFFA - NMI
|
||||||
|
.word .loword(romboot) ; FFFC - RESET
|
||||||
|
.word $FFFF ; FFFE - IRQ/BRK
|
||||||
|
.endproc
|
Loading…
x
Reference in New Issue
Block a user