OpenCores
URL https://opencores.org/ocsvn/next186_soc_pc/next186_soc_pc/trunk

Subversion Repositories next186_soc_pc

[/] [next186_soc_pc/] [trunk/] [SW/] [bootload_BIOS_SD/] [bootstrap.asm] - Rev 3

Compare with Previous | Blame | View Log

; This file is part of the Next186 SoC PC project
; http://opencores.org/project,next186

; Filename: bootstrap.asm
; Description: Part of the Next186 SoC PC project, bootstrap "ROM" code (RAM initialized with cache)
; Version 1.0
; Creation date: Jun2013

; Author: Nicolae Dumitrache 
; e-mail: ndumitrache@opencores.org

; -------------------------------------------------------------------------------------
 
; Copyright (C) 2013 Nicolae Dumitrache
 
; This source file may be used and distributed without 
; restriction provided that this copyright statement is not 
; removed from the file and that any derivative work contains 
; the original copyright notice and the associated disclaimer.
 
; This source file is free software; you can redistribute it 
; and/or modify it under the terms of the GNU Lesser General 
; Public License as published by the Free Software Foundation;
; either version 2.1 of the License, or (at your option) any 
; later version. 
 
; This source is distributed in the hope that it will be 
; useful, but WITHOUT ANY WARRANTY; without even the implied 
; warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
; PURPOSE. See the GNU Lesser General Public License for more 
; details. 
 
; You should have received a copy of the GNU Lesser General 
; Public License along with this source; if not, download it 
; from http://www.opencores.org/lgpl.shtml 
 
; -----------------------------------------------------------------------

; Additional Comments: 
; Assembled with MASM v6.14.8444
; No hardware resources are required for the bootstrap ROM, I use only the initial value of the cache memory
; BIOS will be read from the last BIOSSIZE sectors of SD Card and placed in DRAM at F000:(-BIOSSIZE*512)
; SD HC card required



.186
.model tiny
.code


BIOSSIZE    EQU     16      ; sectors
BOOTOFFSET  EQU     0fc00h  ; bootstrap code offset in segment 0f000h

; this code is for bootstrap deployment only, it will not be present in ROM (cache)
;---------------- EXECUTE -----------------
                org             100h        ; this code is loaded at 0f000h:100h
exec    label near

                mov             si, begin
                mov             di, BOOTOFFSET
                mov             cx, 256*4/2 ; last 4 cache lines (from total 8)
                rep             movsw
                db              0eah
                dw              0, -1       ; CPU reset, execute bootstrap


; Loads BIOS (8K = 16 sectors) from last sectors of SD card (if present)
; If no SD card detected, wait on RS232 115200bps and load program at F000:100h
; the following code is placed in the last 1kB of cache (last 4 lines), each with the dirty bit set
; the corresponding position in RAM will be F000:BOOTOFFSET
; ----------------- RS232 bootstrap - last 256byte cache line ---------------
        org     200h
begin label far               ; this code is placed at F000:BOOTOFFSET

                cli
                cld
                mov             ax, cs        ; cs = 0f000h
                mov             ds, ax
                mov             es, ax
                mov             ss, ax
                mov             sp, BOOTOFFSET
                xor             ax, ax        ; map seg0
                out             80h, ax
                mov             al, 0bh       ; map text segB
                out             8bh, ax
                mov             al, 0fh       ; map ROM segF
                out             8fh, ax
                mov             al, 34h
                out             43h, al
                xor             al, al
                out             40h, al
                out             40h, al       ; program PIT for RS232

                call            sdinit_
                test            ax, ax
                jz              short RS232
                mov             dx, ax
                shr             dx, 6
                shl             ax, 10
                mov             cx, BIOSSIZE       ;  sectors
                sub             ax, cx
                sbb             dx, 0
                xor             bx, bx       ; read BIOSSIZE/2 KB BIOS at 0f000h:0h
nextsect:      
                push            ax
                push            dx
                push            cx
                call            sdread_
                dec             cx
                pop             cx
                pop             dx
                pop             ax
                jnz             short RS232  ; cx was not 1
                add             ax, 1
                adc             dx, 0
                add             bx, 512    
                loop            nextsect
                cmp             word ptr ds:[0], 'eN'
                jne             short RS232             
                cmp             word ptr ds:[2], 'tx'
                je              short   BIOSOK

RS232: 
                mov             dx, 3c0h
                mov             al, 10h
                out             dx, al
                mov             al, 8h
                out             dx, al      ; set text mode
                mov             dx, 3d4h
                mov             al, 0ah
                out             dx, al
                inc             dx
                mov             al, 1 shl 5 ; hide cursor
                out             dx, al
                dec             dx
                mov             al, 0ch
                out             dx, al
                inc             dx
                mov             al, 0
                out             dx, al
                dec             dx
                mov             al, 0dh
                out             dx, al
                inc             dx
                mov             al, 0
                out             dx, al      ; reset video offset
      
                push            0b800h      ; clear screen
                pop             es
                xor             di, di
                mov             cx, 25*80
                xor             ax, ax
                rep             stosw
                
                mov             dx, 3c8h    ; set palette entry 1
                mov             ax, 101h
                out             dx, al
                inc             dx
                mov             al, 2ah
                out             dx, al
                out             dx, al
                out             dx, al
                
                xor             di, di      
                mov             si, booterrmsg + BOOTOFFSET - begin
                lodsb
nextchar:      
                stosw
                lodsb
                test            al, al
                jnz             short nextchar

                mov             bh, 8
flush:        
                mov             al, [bx]
                dec             bh
                jnz             flush
        
                mov             si, 100h
                call            srecb
                mov             bh, ah
                call            srecb
                mov             bl, ah

sloop:  
                call            srecb
                mov             [si], ah
                inc             si
                dec             bx
                jnz             sloop
                xor             sp, sp
                mov             ss, sp
                db              0eah
                dw              100h,0f000h ; execute loaded program
        
BIOSOK:
                mov             si, reloc + BOOTOFFSET - begin
                mov             di, bx
                mov             cx, endreloc - reloc
                rep             movsb       ; relocate code from reloc to endreloc after loaded BIOS
                mov             di, -BIOSSIZE*512
                xor             si, si
                mov             cx, BIOSSIZE*512/2
                jmp             bx
reloc:      
                rep             movsw
                db              0eah
                dw              0, -1       ; CPU reset, execute BIOS
endreloc:
      

; ----------------  serial receive byte 115200 bps --------------
srecb:  
                mov             ah, 80h
                mov             dx, 3dah
                mov             cx, -5aeh ; (half start bit)
srstb:  
                in              al, dx
                shr             al, 2
                jc              srstb

                in              al, 40h ; lo counter
                add             ch, al
                in              al, 40h ; hi counter, ignore
l1:
                call            dlybit
                in              al, dx
                shr             al, 2
                rcr             ah, 1
                jnc             l1
dlybit:
                sub             cx, 0a5bh  ;  (full bit)
dly1:
                in              al, 40h
                cmp             al, ch
                in              al, 40h
                jnz             dly1
                ret

;---------------------  read/write byte ----------------------
sdrb:   
                mov             al, 0ffh
sdsb:               ; in AL=byte, DX = 03dah, out AX=result
                mov             ah, 1
sdsb1:
                out             dx, al
                add             ax, ax
                jnc             sdsb1
                in              ax, dx
                ret

;---------------------  write block ----------------------
sdwblk:              ; in DS:SI=data ptr, DX=03dah, CX=size
                lodsb
                call            sdsb
                loop            sdwblk
                ret

;---------------------  read block ----------------------
sdrblk:              ; in DS:DI=data ptr, DX=03dah, CX=size
                call            sdrb
                mov             [di], ah
                inc             di
                loop            sdrblk
                ret

;---------------------  write command ----------------------
sdcmd8T:
                call    sdrb
sdcmd:              ; in DS:SI=6 bytes cmd buffer, DX=03dah, out AH = 0ffh on error
                mov             cx, 6
                call            sdwblk
sdresp:
                xor             si, si
sdresp1:
                call            sdrb
                inc             si
                jz              sdcmd1
                cmp             ah, 0ffh
                je              sdresp1
sdcmd1: 
                ret         

;---------------------  read one sector ----------------------
sdread_ proc near   ; DX:AX sector, DS:BX buffer, returns CX=read sectors
                push            ax
                mov             al, dl
                push            ax
                mov             dl, 51h     ; CMD17
                push            dx
                mov             si, sp

                mov             dx, 3dah
                mov             ah, 1
                out             dx, ax      ; CS on
                call            sdcmd
                add             sp, 6
                or              ah, ah
                jnz             sdr1        ; error (cx=0)
                call            sdresp      ; wait for 0feh token
                cmp             ah, 0feh
                jne             sdr1        ; read token error (cx=0)
                mov             ch, 2       ; 512 bytes
                mov             di, bx
                call            sdrblk
                call            sdrb        ; ignore CRC
                call            sdrb        ; ignore CRC
                inc             cx          ; 1 block
 sdr1:       
                xor             ax, ax
                out             dx, ax
                call            sdrb        ; 8T
                ret     
sdread_ endp
        
;---------------------  init SD ----------------------
sdinit_ proc near       ; returns AX = num kilosectors
                mov             dx, 3dah
                mov             cx, 10
sdinit1:                   ; send 80T
                call            sdrb
                loop            sdinit1

                mov             ah, 1
                out             dx, ax       ; select SD

                mov             si, SD_CMD0 + BOOTOFFSET - begin
                call            sdcmd
                dec             ah
                jnz             sdexit      ; error
                
                mov             si, SD_CMD8 + BOOTOFFSET - begin
                call            sdcmd8T
                dec             ah
                jnz             sdexit      ; error
                mov             cl, 4
                sub             sp, cx
                mov             di, sp
                call            sdrblk
                pop             ax
                pop             ax
                cmp             ah, 0aah
                jne             sdexit      ; CMD8 error
repinit:        
                mov             si, SD_CMD55 + BOOTOFFSET - begin
                call            sdcmd8T
                call            sdrb
                mov             si, SD_CMD41 + BOOTOFFSET - begin
                call            sdcmd
                dec             ah
                jz              repinit
                
                mov             si, SD_CMD58 + BOOTOFFSET - begin
                call            sdcmd8T
                mov             cl, 4
                sub             sp, cx
                mov             di, sp
                call            sdrblk
                pop             ax
                test            al, 40h     ; test OCR bit 30 (CCS)
                pop             ax
                jz              sdexit      ; no SDHC

                mov             si, SD_CMD9 + BOOTOFFSET - begin ; get size info
                call            sdcmd8T
                or              ah, ah
                jnz             sdexit
                call            sdresp      ; wait for 0feh token
                cmp             ah, 0feh
                jne             sdexit
                mov             cl, 18      ; 16bytes + 2bytes CRC
                sub             sp, cx
                mov             di, sp
                call            sdrblk
                mov             cx, [di-10]
                xchg            cl, ch
                inc             cx
                mov             sp, di
sdexit: 
                xor             ax, ax      ; raise CS
                out             dx, ax
                call    sdrb
                mov             ax, cx       
                ret
sdinit_ endp

    
booterrmsg  db  'BIOS not present on SDCard last 8KB, waiting on RS232 (115200bps, f000:100) ...', 0
SD_CMD0         db              40h, 0, 0, 0, 0, 95h
SD_CMD8         db              48h, 0, 0, 1, 0aah, 087h
SD_CMD9         db              49h, 0, 0, 0, 0, 0ffh
SD_CMD41        db              69h, 40h, 0, 0, 0, 0ffh
SD_CMD55        db              77h, 0, 0, 0, 0, 0ffh
SD_CMD58        db              7ah, 0, 0, 0, 0, 0ffh


; ---------------- RESET ------------------
                org 05f0h
start:
                db              0eah
                dw              BOOTOFFSET, 0f000h
                db              0,0,0,0,0,0,0,0,0,0,0
       
end exec

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.