Mercurial > hg > Members > kono > nitros9-code
diff 3rdparty/utils/fpgarom/test.asm @ 3148:ffa4b0273cc7
3rdparty/utils/fpgarom: Utilities for CoCo3FPGA booting
Includes Brett Gordon's CocoFPGA Boot ROM.
author | Bill Pierce <merlinious999@gmail.com> |
---|---|
date | Sat, 04 Feb 2017 18:54:49 +0100 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/3rdparty/utils/fpgarom/test.asm Sat Feb 04 18:54:49 2017 +0100 @@ -0,0 +1,620 @@ +;;; +;;; Boot OS9 via CoCoBoot interface +;;; +;;; + +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 + + +;;; +;;; +;;; Low Ram Variables +;;; +;;; + org $2000 +RAM equ * +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) + ;; and a buffer for directory entries +dirbuf rmb 32 ; +ksize rmb 2 ; "stacked" size of os9 boot file +stack rmb 64 +stackb ; bottom of stack + +;;; +;;; +;;; Code +;;; +;;; + + + org $c000 ; sit low +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 + lds #stackb ; set stack + ;; clear RAM vars + ldx #RAM + ldb #stack-RAM + jsr memz + ;; + ldx #$ff90 ; setup gimme + jsr gime ; + clr $ffa0 ; set mmu bank 0 to phys 0 +* clr $ffdf ; set SAM RAM mode + ;; setup screen + jsr scrSetup ; setup screen + ldx #str3 ; print banner + jsr putscr ; +x@ bra x@ + ;; 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 here !!!! + 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 + tfr d,x ; X = cpu load address + cmpx #$4000 ; cant go lower + lblo toobig + ;; set mmu + lsra + lsra + lsra + lsra + lsra ; A = mmu bank no + 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 + ;; copy os9boot into memory +b@ jsr fload ; 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 + ;; clear out DP page + ldx #0 + clrb + jsr memz + ;; set dp + tfr b,dp + ;; set gime mirror + ldx #$90 + jsr gime + ;; jump to OS9 + ldx #str2 + jsr putscr + ldx $f009 ; KRN relative start address + leax $f000,x ; make it absolute + ldu #ksize ; U = ptr to os9boot size + orcc #$50 + jmp ,x ; jump to kernel (bye!) + +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 + + + +;;; 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 + + +;;; 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 + 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 + + + + include "sd.asm" + +ende equ * + + + end prestart \ No newline at end of file