Mercurial > hg > Members > kono > nitros9-code
view 3rdparty/utils/fpgarom/boot.asm @ 3222:c086a5d69b78
Corrected ,pc should have been ,pcr in KRNP3.asm
author | David Ladd <drencor-xeen@users.sourceforge.net> |
---|---|
date | Wed, 20 Dec 2017 23:28:18 -0600 |
parents | ffa4b0273cc7 |
children |
line wrap: on
line source
;;; ;;; Boot OS9 via CoCoBoot interface ;;; ;;; include "sd.def" export prestart import start.bss import length.bss CR equ 13 SP equ 32 DBUF0 equ $600 ; we'll borrow some memory from basic DBUF1 equ $700 ; another buffer SCRPTR equ $0002 ; point to the os screen pointer DD.BIT equ $6 ; 2B no of sectors per cluster DD.NAM equ $1f ; 32B volume name field DD.DIR equ $8 ; 3B descriptor cluster for root dir FD.SIZ equ $9 ; 4B size of file in bytes .area .bss root rmb 3 ; 3b lsn of root dir ;; FCB - vars needed to control file access. sptr rmb 2 ; ptr to current segment dptr rmb 2 ; ptr to data buffer bcount rmb 2 ; number of bytes left in buffer fcounth rmb 2 ; number of bytes left in file (high word) fcount rmb 2 ; number of bytes left in file (low word) cptr rmb 2 ; pointer in block (boot cpu address) blocks rmb 1 ; number of regular contigeous blocks block rmb 1 ; current block number dirbuf rmb 32 ; ksize rmb 2 ; "stacked" size of os9 boot file offset rmb 3 ; 3B offset of root partition stack1 rmb 64 stackb .area .bounce BOUNCE rmb 255 .area .code prestart jmp start ; me first, but jump over DATA BOOT fcn "OS9Boot" KRN fcn "ccbkrn" str0 fcn "Loading OS9Boot" str1 fcn "Loading ccbkrn" str2 fcn "Xfr Control to KRN..." str3 fcn "CoCoBoot SDIO" str4 fcn "Vol Name: " start orcc #$50 ; shut off interrupts clr $ffa0 ; set mmu bank 0 to phys 0 clr $ffdf ; set SAM RAM mode clr $ffd9 ; high speed poke ;; clear ram vars ldx #start.bss a@ clr ,x+ cmpx #(start.bss+length.bss) bne a@ ;; lds #stackb ; set stack ldx #$ff90 ; setup gimme jsr gime ; ;; setup screen jsr scrSetup ; setup screen ldx #str3 ; print banner jsr putscr ; ;; init SD card jsr ll_init lbcs initerr ;; get LSN0 ldx #DBUF0 ; set disk arg stx DPTR clr LSN clr LSN+1 clr LSN+2 ;; Test for CCPT jsr ccpttest ;; try to mount os9 filesystem jsr getlsn ;; print volume name ldx #str4 jsr puts ldx #DBUF0+DD.NAM jsr putscr ;; get root dir's lsn ldx #DBUF0+DD.DIR ldu #root jsr cpy3 ;; open boot file ldx #str0 jsr puts ldx #BOOT jsr nopen lbcs fnferr ldx #dirbuf+$1d ; !!! replace with constant ldu #LSN ; jsr cpy3 ; set LSN = lsn of dirent jsr open ; and open the file ldd fcounth ; check size lbne toobig ; ;; calculate start address ldd fcount ; save os9 size for passing to KRN std ksize ; ldd #$f000 ; f000 - fcount = start address subd fcount ; clrb ; and round it down to near page boundary tfr d,x ; X = cpu load address pshs x ; push onto stack ( cpustart ) cmpx #$2000 ; cant go lower lblo toobig ;; set calc init mmu for bounce routine lsra ; make A = mmu reg no lsra ; take top three bits lsra ; lsra ; lsra ; pshs a ; push start mmu no ( cpustart mmustart ) ;; calc no of contigeous block for os9boot loading routine ldb #7 ; A = no of contigeous block subb ,s ; stb blocks ; save for loading routine ;; calc beginning cpu address ldd 1,s ; D = cpu start anda #$1f addd #$4000 ; adjust for loader std cptr ;; copy os9boot into memory b@ jsr testload ; load os9boot into memory jsr putCR ;; open krn file ldx #str1 jsr puts ldx #KRN jsr nopen bcs fnferr ldx #dirbuf+$1d ; !!! replace with constant ldu #LSN ; jsr cpy3 ; set LSN = lsn of dirent jsr open ; and open the file ldx fcounth ; check size of krn file lbne krnsize ; is way too big ldx fcount ; cmpx #$f00 ; lbne krnsize ; wrong size ;; copy krn file into memory ldx #$f000 jsr fload ; load ccbkrn into memory jsr putCR ;; done with disk go high speed :( clr $ffd9 ;; clear out DP page ldx #0 clrb jsr memz ;; set dp tfr b,dp ;; set gime mirror ldx #$90 jsr gime ;; copy bounce routine down to RAM ldx #bounce ldu #BOUNCE ldb #bounceend-bounce c@ lda ,x+ sta ,u+ decb bne c@ ;; jump to OS9 ldx #str2 jsr putscr jmp BOUNCE iloop bra iloop fnferr ldx #p0@ jsr puts a@ bra a@ p0@ fcn ": FNF Error!" initerr ldx #p0@ jsr puts a@ bra a@ p0@ fcn "Driver Init Error!" mnterr ldx #p0@ jsr puts a@ bra a@ p0@ fcn "LSN0: bad format!" toobig ldx #p0@ jsr puts a@ bra a@ p0@ fcn "Too Big!" krnsize ldx #p0@ jsr puts a@ bra a@ p0@ fcn "Wrong Size!" ;;; Test for presence of CCPT partitioning ccpttest pshs d,x ldd DBUF0 ; get magic cmpd #$4343 ; check for "CC" lbne no@ ldd DBUF0+2 ; check for "PT" cmpd #$5054 lbne no@ ; no@ ldx #p0@ jsr putscr puls d,x,pc p0@ fcn "CCPT not found." ;;; Setup Screen for os9 (sigh) scrSetup pshs d,x ;; set colors: green on black ldb #$12 stb $ffbc ldb #0 stb $ffbd ;; clear a screen's worth of video memory ldb #$3b stb $ffa0 ldx #$0000 ldd #$2020 a@ std ,x++ cmpx #$0400 bne a@ ;; set screen pointer up ldd #8 std SCRPTR clr $ffa0 puls d,x,pc ;;; Setup memory with gimme setting, aka Do os9's work :( ;;; takes: X = address ;;; returns: nothing ;;; modifies: nothing gime pshs d,x,u ldu #table@ lda #16 a@ ldb ,u+ stb ,x+ deca bne a@ puls d,x,u,pc table@ .dw $6c00 .dw $0000 .dw $0900 .dw $0000 .dw $0320 .dw $0000 .db $00 .dw $ec01 .db $00 ;;; This bounce routine gets copied down into low memory ;;; is completes the memory map. Plz jump to me. bounce ; ( cpustart mmustart ) ;; setup mmu to how os9 expects it clr $ffa0 ; phys block 0 is always mapped to $0000 puls a ; get mmu start ( cpustart ) ldy #$ffa0 leay a,y ; Y = beginning mmu ldb #1 ; 1 is first os9 system block a@ stb ,y+ ; store bank no in mmu cmpy #$ffa7 ; did we move to the last mmu block beq b@ ; yes, then quit looping incb ; increment bank no bra a@ ; repeat b@ ldb #$3f ; and mmu7 is always $3f stb ,y ;; find and jump to KRN module ldx $f009 ; KRN relative start address leax $f000,x ; make it absolute ldu #ksize ; U = ptr to os9boot size orcc #$50 ; really, really turn off interrupts jmp ,x ; jump to kernel (bye!) bounceend ;;; Read os9 file into memory ;;; takes: open os9 file, testload pshs d,x ldb #1 ; set initial bank to 1 stb block ; stb $ffa2 ; ;; loop until EOF a@ ldx cptr ; get block pointer jsr readb ; read a byte bcs out@ ; done! stb ,x+ stx cptr ;; check for end of bank cmpx #$6000 bne a@ ;; end of bank ldd #$4000 ; reset block pointer std cptr dec blocks ; any more blocks left bne b@ ;; no more blocks left set $3f ldb #$3f bra c@ b@ inc block ldb block c@ stb $ffa2 ; set mmu bra a@ out@ puls d,x,pc ;;; Read file into memory ;;; takes: X = address to load, file opened. ;;; modifies: nothing fload pshs b,x a@ jsr readb bcs done@ stb ,x+ bra a@ done@ puls b,x,pc ;;; open a file via a name ;;; takes: X = filename (zero termed) ;;; returns: dirbuf set to file's FD, C set on error. nopen pshs d,x,u ;; open root directory ldx #root ldu #LSN jsr cpy3 jsr open ;; get a dirent into buffer ldu 2,s ; U = filename b@ lda #32 ldx #dirbuf a@ jsr readb bcs nfound@ stb ,x+ deca bne a@ jsr os9toz ldx #dirbuf jsr strcmp bcc found@ bra b@ nfound@ coma puls d,x,u,pc found@ clra puls d,x,u,pc ;;; zero mem ;;; takes: X = ptr, B = number of byte to zero ;;; returns: nothing ;;; modifies: nothing memz pshs b,x a@ clr ,x+ decb bne a@ puls b,x,pc ;;; strcmp ;;; takes: X = zstring, U = zstring ;;; returns: C clear if equal strcmp pshs b,x,u a@ ldb ,x+ cmpb ,u+ bne ne@ ; not equal tstb beq e@ ; equal bra a@ ; loop e@ clrb puls b,x,u,pc ne@ comb puls b,x,u,pc ;;; change dirbuf's name to a z-string os9toz pshs b,x ldx #dirbuf tst ,x beq out@ a@ ldb ,x+ bpl a@ andb #$7f stb -1,x clr ,x out@ puls b,x,pc ;;; Open file ;;; takes: LSN = lsn of file's FD ;;; returns: nothing open pshs d,x ldx #DBUF1 ; load dbuf1 with file's FD stx DPTR jsr getlsn ldd #DBUF1+$10 ; first segment std sptr ; save ptr jsr fill ; and get first sector ;; set fcount ldd DBUF1+FD.SIZ std fcounth ldd DBUF1+FD.SIZ+2 std fcount puls d,x,pc ;;; get one byte from file ;;; takes: nothing, ;;; returns: B = byte, C set on EOF readb pshs a,x ldd fcount ; is the entire file out of bytes? beq eof@ ldd bcount bne a@ ; if left don't refill ;; refill file's data buffer jsr fill ;; a@ ldd fcount subd #1 std fcount ldd bcount subd #1 std bcount ldx dptr ldb ,x+ stx dptr clra puls a,x,pc eof@ coma puls a,x,pc fill pshs d,x,u ; save regs jsr spin1 ldx sptr ldd 3,x ; get sector count bne a@ ; no more secs left in seg? ;; get next segment ldx sptr leax 5,x stx sptr ;; fill buffer a@ ldx sptr ; copy segment's LSN to args ldu #LSN ; jsr cpy3 ; ldx #DBUF0 ; set data buffer stx DPTR ; jsr getlsn ; and get the sector ;; increment segment ldx sptr ; increment segment's LSN jsr inc3 ; ldd 3,x ; decrement segment's sector count subd #1 ; std 3,x ; ;; set file dirs ldd #256 std bcount ldd #DBUF0 std dptr puls d,x,u,pc ; return ;;; Spin the ticker ;;; takes: nothing ;;; returns: nothing ;;; modifies: nothing spin1 pshs b ldb #'. jsr putc puls b,pc ;;; Copy 3 bytes value ;;; take: X = src ptr, U = dst ptr ;;; modifies: nothing cpy3 pshs d,x,u ldd ,x++ std ,u++ ldb ,x stb ,u puls d,x,u,pc ;;; Add 3 byte value store result in X ptr ;;; takes: X = 3B ptr, U = 3B ptr ;;; modifies: nothing add3 pshs d ldd 1,u addd 1,x std 1,x ldb ,u adcb ,x stb ,x puls d,pc ;;; increment 3 byte value by one ;;; takes: X = ptr to 3 bytes ;;; returns: nothing inc3 pshs d,x ldd 1,x addd #1 std 1,x ldb ,x adcb #0 stb ,x puls d,x,pc ;;; deblocker to translate 256B LSN to a 512B LSN ;;; takes: args in LSN/DPTR ;;; modifies: nothing getlsn pshs b,x ldx #LSN ; get pointer lsr ,x+ ror ,x+ ror ,x+ ldb #1 ; 256b lower read bcc a@ negb a@ stb SMALL ldx #LSN ; add partition offset ldu #offset jsr add3 jsr ll_read puls b,x,pc ;;; Dump 128 byte to screen ;;; takes: X = ptr to data ;;; modifies: nothing dump pshs d,x jsr putCR lda #8 pshs a ; put row counter b@ lda #8 ; column counter pshs x a@ ldb ,x+ jsr putb jsr putSP deca bne a@ puls x clr 8,x jsr putscr dec ,s bne b@ leas 1,s puls d,x,pc ;;; Print a Space putSP pshs b ldb #SP jsr putc puls b,pc ;;; Print a CR putCR pshs d ldb #$3b stb $ffa0 ldd SCRPTR addd #32-8 andb #~$1f addd #8 std SCRPTR clr $ffa0 puls d,pc ;;; Print a Z string ;;; takes: X = ptr to string ;;; modifies: nothing puts pshs b,x a@ ldb ,x+ beq done@ jsr putc bra a@ done@ puls b,x,pc ;;; Print a 3 byte value ( in hex ) ;;; takes: X = ptr to value ;;; modifies: nothing put3 pshs d,x ldd ,x++ jsr putw ldb ,x jsr putb puls d,x,pc ;;; Print a word ( in hex) ;;; takes: D = word ;;; modifies: nothing putw pshs b tfr a,b bsr putb puls b bsr putb rts ;;; Print a byte (in hex) ;;; takes: B = byte ;;; modifies: nothing putb pshs d lsrb lsrb lsrb lsrb bsr putn ldb 1,s bsr putn puls d,pc ;;; Print a Char ;;; takes: B = charactor ;;; modifies: nothing putc pshs d,x lda #$3b ; put 3b in bank 0 sta $ffa0 ldx SCRPTR stb ,x+ stx SCRPTR clr $ffa0 ; put 0 in bank 0 puls d,x,pc ;;; Print a nibble ;;; takes: B = nibble ;;; modifies: nothing putn pshs b andb #$f addb #$30 cmpb #$39 bls a@ addb #7 a@ jsr putc puls b,pc ;;; Print a string followed by a CR ;;; takes: X = zero termed string ;;; returns: nothing ;;; modifies: nothing putscr jsr puts jsr putCR rts