From: Alan Cox Date: Tue, 6 Oct 2015 20:50:01 +0000 (+0100) Subject: coco2: first cut at bootloader X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=4936ca1c1525eed115eb180c63c126ff0aff62b4;p=FUZIX.git coco2: first cut at bootloader --- diff --git a/Kernel/platform-coco2/Makefile b/Kernel/platform-coco2/Makefile index 8ab8fedd..7ee229b5 100644 --- a/Kernel/platform-coco2/Makefile +++ b/Kernel/platform-coco2/Makefile @@ -45,7 +45,7 @@ $(AOBJS): %$(BINEXT): %.s clean: rm -f *.o *~ -image: +image: bootfuz.bin $(CROSS_LD) -o ../fuzix.bin --map=../fuzix.map --script=fuzix.link \ crt0.o commonmem.o \ coco2.o discard.o ../simple.o \ @@ -56,4 +56,8 @@ image: ../syscall_proc.o ../syscall_other.o ../mm.o ../swap.o \ ../tty.o ../devsys.o ../usermem.o ../syscall_fs2.o ../syscall_exec16.o \ devtty.o libc.o ../vt.o +# FIXME: need to then convert the decb into an image for the IDE disk booter + +bootfuz.bin: bootloader.s + lwasm -r -b -obootfuz.bin bootloader.s diff --git a/Kernel/platform-coco2/bootloader.s b/Kernel/platform-coco2/bootloader.s new file mode 100644 index 00000000..ea8e5245 --- /dev/null +++ b/Kernel/platform-coco2/bootloader.s @@ -0,0 +1,145 @@ +sector equ 0xCFF0 + + org 0x600 + +bootstrap: + clr $FFC7 ; Display to 0x200 + clr $FFC8 + ldx #0x0200 +wiper: + clr ,x+ + cmpx #0x0400 + bne wiper + pshs cc + orcc #$10 ; IRQs off for this lot + sta $FFDF ; 64K mode on + ldx #start + ldy #0xC000 +copy: ; Move the loader somewhere safe + lda ,x+ + sta ,y+ + cmpy #end + bne copy + jmp 0xC000 + +; +; This code *MUST* remain relocatable +; +; Load IDE blocks 1+ into memory off an LBA drive. With 512 byte +; sectors we load just under 0xB000 bytes. The first 0x0000-0x8000 bytes are +; our low memory image. 0x8000-0x8FFF holds the high image (0xF000-0xFFFF) and +; then the blocks at 0x9000-0xAFFF are used for discard (0x8000-8FFF will be +; trashed before discard is gone by the exec arguments). Having done the +; shuffle we then jump in 64K mode to 0x0400 which is our start vector. +; +; Important cheat. 256 x 512 is 128K, therefore in LBA mode we never need +; to touch anything but the low 8bit count for the LBA, the rest we clear +; and just leave alone. +; +start: + ldd #'B'*256 + 'O' + std 0x0200 + ldd #'O' * 256 + 'T' + std 0x0202 + ldd #':' * 256 + ' ' + std 0x0204 + tfr s,u ; Save old stack + lds #$FE00 ; Point the stack somewhere clear of + ; our loading + ldx #$0 + tfr x,y ; Load from 0 + +l0: ; Wait for IDE ready + leay -1,y + beq timeout + lda $FF57 + bita #0x80 + bne l0 + lda #'X' + sta 0x0205 + clr $FF54 + clr $FF55 + lda #0x40 + sta $FF56 ; LBA mode + lda #0x01 ; Leave block 0 for MBR etc stuff + sta sector + ldx #0x0000 +l1: ; Wait busy to clear + ldb $FF57 + leay -1,y + beq timeout + bitb #0x80 + bne l1 + + sta $FF53 ; sector number to read + lda #0x01 + sta $FF52 ; Some drives clear this each I/O + lda #'*' + sta 0x0205 +l2: + leay -1,y + beq timeout + lda $FF57 + bita #0x40 ; Wait DRDY + beq l2 + lda #0x20 ; READ + sta $FF57 +l3: + leay -1,y + beq timeout + bita #0x08 ; Wait DRQ + beq l3 + lda #'+' + sta 0x0205 + ldy #0 + clra +l4: + ldb 0xFF50 + stb ,x+ + ldb 0xFF58 + stb ,x+ + deca + bne l4 + cmpx #0xB000 + beq loaded + lda #'-' + sta 0x0205 + inc sector + lda sector + bra l1 ; Wait busy clear and do next +timeout: + ldb #1 ; Error 1 +bail: + ldx #0 +bail_w: + leax 1,x + cmpx #0 + bne bail_w + clr $FFC6 + clr $FFC9 ; Display back where BASIC wants it + clra + tfr u,s ; Recover stack + sta $FFDE ; Back into 32K mode + puls cc,pc + +diskerr: + ldb #2 + bra bail + +loaded: + lda #'@' + sta 0x0205 +; +; We have loaded from 0000 to B000 now relocate bits from 8000-8FFF to +; F000-FFFF, 9000-B000 is discard space +; + ldx #0x8000 + ldy #0xF000 +l5: ldd ,x++ + std ,y++ + cmpy #0xFF00 ; skip last 256 bytes (I/O area) + bne l5 + lda #'.' + sta 0x0205 + jmp 0x0400 +end: