JUNK = *.rel *.lst *.asm *.sym *.rst *.map *.ihx *.bin
-all: $(OBJS) diskboot.bin
+all: $(OBJS)
$(AOBJS): %.rel: %.s
$(CROSS_AS) $(ASOPTS) $<
$(CROSS_CC) $(CROSS_CCOPTS) -c $<
clean:
- rm -f $(OBJS) $(JUNK) core *~ bootrom.ihx bootrom.bin diskboot.bin fuzix.com fuzix.rom
-
-diskboot.bin: diskboot.s
- $(CROSS_AS) $(ASOPTS) diskboot.s
- sdldz80 -nmi diskboot.rel
- makebin -s 65536 diskboot.ihx | dd bs=512 skip=125 count=1 of=diskboot.bin
-
-image:
- sdasz80 -o bootrom.s
- sdldz80 -m -i bootrom.rel
- makebin -s 136 bootrom.ihx > bootrom.bin
-# cat bootrom.bin ../fuzix.bin | dd conv=sync bs=65536 count=1 of=fuzix.rom
- cat bootrom.bin ../fuzix.bin > tmp.rom
- cat tmp.rom | dd conv=sync bs=65536 count=1 of=fuzix.rom
- -cat fuzix.rom ../rc2014_root_fs > fuzix_rc2014_sio_bootfs.rom
- ../cpm-loader/makecpmloader ../cpm-loader/cpmload.bin ../fuzix.bin 0x88 fuzix.com
- ../cpm-loader/makecpmloader ../cpm-loader/fuzixload.bin ../fuzix.bin 0x88 fuzix
-
+ rm -f $(OBJS) $(JUNK) core *~ bootrom.ihx bootrom.bin fuzix.com fuzix.rom
+
+#
+# Compile up the boot block
+#
+image: bootblock
+ dd if=/dev/zero of=pad bs=256 count=1
+ cat boot-romwbw.bin pad ../fuzix.bin >fuzix.romwbw
+
+bootblock:
+ sdasz80 -o boot-romwbw.s
+ sdldz80 -i boot-romwbw.rel
+ # This makes us a binary from physical 0
+ makebin -s 62464 boot-romwbw.ihx boot-romwbw.tmp
+ # Chop off the leading 61440 bytes we don't want
+ dd if=boot-romwbw.tmp of=boot-romwbw.bin bs=512 count=2 skip=120
--- /dev/null
+;
+; ROMWBW boot block
+;
+; The provided bootloader is a bit limited. It can only really load
+; stuff into upper memory and assumes CP/M is being loaded
+;
+; Unfortunately this means we have to chain our own loader.
+; Fortunately ROMWBW is really quite nice so it's easy to use to do
+; the load. What it can't do however is do I/O into the low 32K
+; directly - it has no separate I/O target page feature it seems.
+;
+; We build the lot as if it's a binary at 0xF000 as that's easier than
+; fighting the linker and the like
+;
+; The end must actually be the byte after we need. ROMWBW explodes
+; if given F200 F3FF !
+;
+ .module boot
+; MMU Ports
+MPGSEL_0 .equ 0x78 ; Bank_0 page select register (W/O)
+MPGSEL_1 .equ 0x79 ; Bank_1 page select register (W/O)
+MPGSEL_2 .equ 0x7A ; Bank_2 page select register (W/O)
+MPGSEL_3 .equ 0x7B ; Bank_3 page select register (W/O)
+MPGENA .equ 0x7C ; memory paging enable register, bit 0 (W/O)
+
+
+.area BOOT (ABS)
+ .org 0xF000
+
+ .ds 384
+ .byte 0x5A
+ .byte 0xA5
+ .byte 0x00 ; formatting platform
+ .byte 0x00 ; device
+ .byte 0x00 ; formatter
+ .byte 0x00 ; physical drive
+ .byte 0x00 ; logical unit
+ .byte 0x00 ; unused
+ .ds 88 ; move to byte 96
+ .byte 0x00 ; write protect
+ .word 0x00 ; update count
+ .byte 0 ; major
+ .byte 0 ; minor
+ .byte 0 ; update
+ .byte 0 ; patch
+ .ascii 'Fuzix WBW Loader'
+ .byte '$' ; indicate valid label
+ .word 0 ; no patch
+ .word 0xF200 ; load target
+ .word 0xF400 ; end - way more than we need but that's fine
+ .word 0xF200 ; run from here
+
+;
+; This should be 0xF200. We are entered with the stack somewhere
+; in the middle of RAM, HBIOS stubs in the top 2 pages and RAM
+; low including our expected RST hooks for HBIOS
+;
+; We need to go get our device/subunit back from the BIOS because
+; it's has RST 8 interfaces for this rather than just passing
+; them in a register.
+;
+bootit:
+ ld sp, #0xFE00 ; SP as high as we can
+ ld bc, #0xF8E0 ; Get boot sysinfo into DE
+ rst 8
+ ld b, #0x13 ; ROMWBW disk read request
+ ld c, d ; Device (same as booted off)
+ ld hl, #0x8000 ; Loading at 0x8000 for the moment
+ ld e, #32 ; 32 sectors (16K)
+ push bc
+ rst 8 ; Can error but if so wtf do we do ?
+ ld hl,#0x8100 ; Don't copy first 256 bytes over
+ ld de,#0x4100
+ ld bc,#0x3F00 ; We've loaded 0100-4000
+ ld a,#32
+ out (MPGSEL_1),a ; Low bank at 0x4000 please
+ ldir
+
+ ;
+ ; Same process again for second 16K of kernel
+ ;
+ pop bc
+ ld hl,#0x8000
+ ld e,#32 ; Load the next 16K
+ push bc
+ rst 8
+ ld hl,#0x8000 ; Move it into place
+ ld de,#0x4000
+ ld bc,#0x4000
+ ld a,#33
+ out (MPGSEL_1),a ; Second kernel bank at 0x4000 please
+ ldir
+ pop bc
+
+ ;
+ ; And the third 16K
+ ;
+ ld hl,#0x8000 ; Low the next 16K
+ ld e, #32
+ push bc
+ rst 8
+ ld hl,#0x8000 ; Move it into place
+ ld de,#0x4000
+ ld bc,#0x4000
+ ld a,#34
+ out (MPGSEL_1),a
+ ldir
+ pop bc
+
+ ;
+ ; Final 16K
+ ;
+ ld hl,#0x8000 ; Now load 8000 up
+ ld e, #32 ; takes us up to F000. If that's not enough
+ ; before unpack we have a problem as we
+ ; will need to move the loader
+ rst 8
+
+ ld hl,#0x8000 ; Move it into place
+ ld de,#0x4000
+ ld bc,#0x4000
+ ld a,#35
+ out (MPGSEL_1),a
+ ldir
+
+ ;
+ ; Map the kernel low 16K block and jump into it
+ ;
+ ld a,#32
+ out (MPGSEL_0),a
+ jp 0x0100
+
+
\ No newline at end of file
; exported symbols
.globl init
- .globl init_from_rom
- .globl _boot_from_rom
; imported symbols
.globl _fuzix_main
; startup code
.area _CODE
-init: ; must be at 0x88 -- warm boot methods enter here
- xor a
- jr init_common
-init_from_rom: ; must be at 0x8B -- bootrom.s enters here
- ld a, #1
- ; fall through
-init_common:
- di
- ld (_boot_from_rom), a
- or a
- jr nz, mappedok ; bootrom.s loads us in the correct pages
-
- ; move kernel to the correct location in RAM
- ; note that this cannot cope with kernel images larger than 48KB
- ld hl, #0x0000
- ld a, #32 ; first page of RAM is page 32
-movenextbank:
- out (MPGSEL_3), a ; map page at 0xC000 upwards
- ld de, #0xC000
- ld bc, #0x4000 ; copy 16KB
- ldir
- inc a
- cp #35 ; done three pages?
- jr nz, movenextbank
-
+init: ; must be at 0x0100 as we are loaded at that
; setup the memory paging for kernel
- out (MPGSEL_3), a ; map page 35 at 0xC000
- ld a, #32
- out (MPGSEL_0), a ; map page 32 at 0x0000
- inc a
+ ld a, #33
out (MPGSEL_1), a ; map page 33 at 0x4000
inc a
out (MPGSEL_2), a ; map page 34 at 0x8000
+ inc a
+ out (MPGSEL_3), a ; map page 35 at 0xC000
mappedok:
; switch to stack in high memory
stop: halt
jr stop
-_boot_from_rom: .db 0