Microsoft (R) Macro Assembler Version 6.14.8444		    06/06/13 17:19:05
bootstrap.asm						     Page 1 - 1


				; 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
 0000				.code


 = 0010				BIOSSIZE    EQU     16      ; sectors
 = FC00				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
 0100				exec    label near

 0100  BE 0200 R				mov		si, begin
 0103  BF FC00					mov		di, BOOTOFFSET
 0106  B9 0200					mov		cx, 256*4/2 ; last 4 cache lines (from total 8)
 0109  F3/ A5					rep		movsw
 010B  EA					db		0eah
 010C  0000 FFFF				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
 0200				begin label far               ; this code is placed at F000:BOOTOFFSET

 0200  FA					cli
 0201  FC					cld
 0202  8C C8					mov		ax, cs        ; cs = 0f000h
 0204  8E D8					mov		ds, ax
 0206  8E C0					mov		es, ax
 0208  8E D0					mov		ss, ax
 020A  BC FC00					mov		sp, BOOTOFFSET
 020D  33 C0					xor		ax, ax        ; map seg0
 020F  E7 80					out		80h, ax
 0211  B0 0B					mov		al, 0bh       ; map text segB
 0213  E7 8B					out		8bh, ax
 0215  B0 0F					mov		al, 0fh       ; map ROM segF
 0217  E7 8F					out		8fh, ax
 0219  B0 34					mov		al, 34h
 021B  E6 43					out		43h, al
 021D  32 C0					xor		al, al
 021F  E6 40					out		40h, al
 0221  E6 40					out		40h, al       ; program PIT for RS232

 0223  E8 015D					call		sdinit_
 0226  85 C0					test		ax, ax
 0228  74 3A					jz		short RS232
 022A  8B D0					mov		dx, ax
 022C  C1 EA 06					shr		dx, 6
 022F  C1 E0 0A					shl		ax, 10
 0232  B9 0010					mov		cx, BIOSSIZE       ;  sectors
 0235  2B C1					sub		ax, cx
 0237  83 DA 00					sbb		dx, 0
 023A  33 DB					xor		bx, bx       ; read BIOSSIZE/2 KB BIOS at 0f000h:0h
 023C				nextsect:      
 023C  50					push		ax
 023D  52					push		dx
 023E  51					push		cx
 023F  E8 010B					call		sdread_
 0242  49					dec		cx
 0243  59					pop		cx
 0244  5A					pop		dx
 0245  58					pop		ax
 0246  75 1C					jnz		short RS232  ; cx was not 1
 0248  83 C0 01					add		ax, 1
 024B  83 D2 00					adc		dx, 0
 024E  81 C3 0200				add		bx, 512    
 0252  E2 E8					loop		nextsect
 0254  81 3E 0000 654E				cmp		word ptr ds:[0], 'eN'
 025A  75 08					jne		short RS232             
 025C  81 3E 0002 7478				cmp		word ptr ds:[2], 'tx'
 0262  74 70					je		short   BIOSOK

 0264				RS232: 
 0264  BA 03C0					mov		dx, 3c0h
 0267  B0 10					mov		al, 10h
 0269  EE					out		dx, al
 026A  B0 08					mov		al, 8h
 026C  EE					out		dx, al      ; set text mode
 026D  BA 03D4					mov		dx, 3d4h
 0270  B0 0A					mov		al, 0ah
 0272  EE					out		dx, al
 0273  42					inc		dx
 0274  B0 20					mov		al, 1 shl 5 ; hide cursor
 0276  EE					out		dx, al
 0277  4A					dec		dx
 0278  B0 0C					mov		al, 0ch
 027A  EE					out		dx, al
 027B  42					inc		dx
 027C  B0 00					mov		al, 0
 027E  EE					out		dx, al
 027F  4A					dec		dx
 0280  B0 0D					mov		al, 0dh
 0282  EE					out		dx, al
 0283  42					inc		dx
 0284  B0 00					mov		al, 0
 0286  EE					out		dx, al      ; reset video offset
				      
 0287  68 B800					push		0b800h      ; clear screen
 028A  07					pop		es
 028B  33 FF					xor		di, di
 028D  B9 07D0					mov		cx, 25*80
 0290  33 C0					xor		ax, ax
 0292  F3/ AB					rep		stosw
						
 0294  BA 03C8					mov		dx, 3c8h    ; set palette entry 1
 0297  B8 0101					mov		ax, 101h
 029A  EE					out		dx, al
 029B  42					inc		dx
 029C  B0 2A					mov		al, 2ah
 029E  EE					out		dx, al
 029F  EE					out		dx, al
 02A0  EE					out		dx, al
						
 02A1  33 FF					xor		di, di      
 02A3  BE FE09					mov		si, booterrmsg + BOOTOFFSET - begin
 02A6  AC					lodsb
 02A7				nextchar:      
 02A7  AB					stosw
 02A8  AC					lodsb
 02A9  84 C0					test		al, al
 02AB  75 FA					jnz		short nextchar

 02AD  B7 08					mov		bh, 8
 02AF				flush:        
 02AF  8A 07					mov		al, [bx]
 02B1  FE CF					dec		bh
 02B3  75 FA					jnz		flush
					
 02B5  BE 0100					mov		si, 100h
 02B8  E8 0034					call		srecb
 02BB  8A FC					mov		bh, ah
 02BD  E8 002F					call		srecb
 02C0  8A DC					mov		bl, ah

 02C2				sloop:	
 02C2  E8 002A					call		srecb
 02C5  88 24					mov		[si], ah
 02C7  46					inc		si
 02C8  4B					dec		bx
 02C9  75 F7					jnz		sloop
 02CB  33 E4					xor		sp, sp
 02CD  8E D4					mov		ss, sp
 02CF  EA					db		0eah
 02D0  0100 F000				dw		100h,0f000h ; execute loaded program
					
 02D4				BIOSOK:
 02D4  BE FCE8					mov		si, reloc + BOOTOFFSET - begin
 02D7  8B FB					mov		di, bx
 02D9  B9 0007					mov		cx, endreloc - reloc
 02DC  F3/ A4					rep		movsb       ; relocate code from reloc to endreloc after loaded BIOS
 02DE  BF E000					mov		di, -BIOSSIZE*512
 02E1  33 F6					xor		si, si
 02E3  B9 1000					mov		cx, BIOSSIZE*512/2
 02E6  FF E3					jmp		bx
 02E8				reloc:      
 02E8  F3/ A5					rep		movsw
 02EA  EA					db		0eah
 02EB  0000 FFFF				dw		0, -1       ; CPU reset, execute BIOS
 02EF				endreloc:
				      

				; ----------------  serial receive byte 115200 bps --------------
 02EF				srecb:  
 02EF  B4 80					mov		ah, 80h
 02F1  BA 03DA					mov		dx, 3dah
 02F4  B9 FA52					mov		cx, -5aeh ; (half start bit)
 02F7				srstb:  
 02F7  EC					in		al, dx
 02F8  C0 E8 02					shr		al, 2
 02FB  72 FA					jc		srstb

 02FD  E4 40					in		al, 40h ; lo counter
 02FF  02 E8					add		ch, al
 0301  E4 40					in		al, 40h ; hi counter, ignore
 0303				l1:
 0303  E8 0008					call		dlybit
 0306  EC					in		al, dx
 0307  C0 E8 02					shr		al, 2
 030A  D0 DC					rcr		ah, 1
 030C  73 F5					jnc		l1
 030E				dlybit:
 030E  81 E9 0A5B				sub		cx, 0a5bh  ;  (full bit)
 0312				dly1:
 0312  E4 40					in		al, 40h
 0314  38 E8					cmp		al, ch
 0316  E4 40					in		al, 40h
 0318  75 F8					jnz		dly1
 031A  C3					ret

				;---------------------  read/write byte ----------------------
 031B				sdrb:   
 031B  B0 FF					mov		al, 0ffh
 031D				sdsb:               ; in AL=byte, DX = 03dah, out AX=result
 031D  B4 01					mov		ah, 1
 031F				sdsb1:
 031F  EE					out		dx, al
 0320  03 C0					add		ax, ax
 0322  73 FB					jnc		sdsb1
 0324  ED					in		ax, dx
 0325  C3					ret

				;---------------------  write block ----------------------
 0326				sdwblk:              ; in DS:SI=data ptr, DX=03dah, CX=size
 0326  AC					lodsb
 0327  E8 FFF3					call		sdsb
 032A  E2 FA					loop		sdwblk
 032C  C3					ret

				;---------------------  read block ----------------------
 032D				sdrblk:              ; in DS:DI=data ptr, DX=03dah, CX=size
 032D  E8 FFEB					call		sdrb
 0330  88 25					mov		[di], ah
 0332  47					inc		di
 0333  E2 F8					loop		sdrblk
 0335  C3					ret

				;---------------------  write command ----------------------
 0336				sdcmd8T:
 0336  E8 FFE2					call	sdrb
 0339				sdcmd:              ; in DS:SI=6 bytes cmd buffer, DX=03dah, out AH = 0ffh on error
 0339  B9 0006					mov		cx, 6
 033C  E8 FFE7					call		sdwblk
 033F				sdresp:
 033F  33 F6					xor		si, si
 0341				sdresp1:
 0341  E8 FFD7					call		sdrb
 0344  46					inc		si
 0345  74 05					jz		sdcmd1
 0347  80 FC FF					cmp		ah, 0ffh
 034A  74 F5					je		sdresp1
 034C				sdcmd1: 
 034C  C3					ret         

				;---------------------  read one sector ----------------------
 034D				sdread_ proc near   ; DX:AX sector, DS:BX buffer, returns CX=read sectors
 034D  50					push		ax
 034E  8A C2					mov		al, dl
 0350  50					push		ax
 0351  B2 51					mov		dl, 51h     ; CMD17
 0353  52					push		dx
 0354  8B F4					mov		si, sp

 0356  BA 03DA					mov		dx, 3dah
 0359  B4 01					mov		ah, 1
 035B  EF					out		dx, ax      ; CS on
 035C  E8 FFDA					call		sdcmd
 035F  83 C4 06					add		sp, 6
 0362  0A E4					or		ah, ah
 0364  75 16					jnz		sdr1        ; error (cx=0)
 0366  E8 FFD6					call		sdresp      ; wait for 0feh token
 0369  80 FC FE					cmp		ah, 0feh
 036C  75 0E					jne		sdr1        ; read token error (cx=0)
 036E  B5 02					mov		ch, 2       ; 512 bytes
 0370  8B FB					mov		di, bx
 0372  E8 FFB8					call		sdrblk
 0375  E8 FFA3					call		sdrb        ; ignore CRC
 0378  E8 FFA0					call		sdrb        ; ignore CRC
 037B  41					inc		cx          ; 1 block
 037C				 sdr1:       
 037C  33 C0					xor		ax, ax
 037E  EF					out		dx, ax
 037F  E8 FF99					call		sdrb        ; 8T
 0382  C3					ret     
 0383				sdread_ endp
				        
				;---------------------  init SD ----------------------
 0383				sdinit_ proc near       ; returns AX = num kilosectors
 0383  BA 03DA					mov		dx, 3dah
 0386  B9 000A					mov		cx, 10
 0389				sdinit1:                   ; send 80T
 0389  E8 FF8F					call		sdrb
 038C  E2 FB					loop		sdinit1

 038E  B4 01					mov		ah, 1
 0390  EF					out		dx, ax       ; select SD

 0391  BE FE59					mov		si, SD_CMD0 + BOOTOFFSET - begin
 0394  E8 FFA2					call		sdcmd
 0397  FE CC					dec		ah
 0399  75 65					jnz		sdexit      ; error
						
 039B  BE FE5F					mov		si, SD_CMD8 + BOOTOFFSET - begin
 039E  E8 FF95					call		sdcmd8T
 03A1  FE CC					dec		ah
 03A3  75 5B					jnz		sdexit      ; error
 03A5  B1 04					mov		cl, 4
 03A7  2B E1					sub		sp, cx
 03A9  8B FC					mov		di, sp
 03AB  E8 FF7F					call		sdrblk
 03AE  58					pop		ax
 03AF  58					pop		ax
 03B0  80 FC AA					cmp		ah, 0aah
 03B3  75 4B					jne		sdexit      ; CMD8 error
 03B5				repinit:        
 03B5  BE FE71					mov		si, SD_CMD55 + BOOTOFFSET - begin
 03B8  E8 FF7B					call		sdcmd8T
 03BB  E8 FF5D					call		sdrb
 03BE  BE FE6B					mov		si, SD_CMD41 + BOOTOFFSET - begin
 03C1  E8 FF75					call		sdcmd
 03C4  FE CC					dec		ah
 03C6  74 ED					jz		repinit
						
 03C8  BE FE77					mov		si, SD_CMD58 + BOOTOFFSET - begin
 03CB  E8 FF68					call		sdcmd8T
 03CE  B1 04					mov		cl, 4
 03D0  2B E1					sub		sp, cx
 03D2  8B FC					mov		di, sp
 03D4  E8 FF56					call		sdrblk
 03D7  58					pop		ax
 03D8  A8 40					test		al, 40h     ; test OCR bit 30 (CCS)
 03DA  58					pop		ax
 03DB  74 23					jz		sdexit      ; no SDHC

 03DD  BE FE65					mov		si, SD_CMD9 + BOOTOFFSET - begin ; get size info
 03E0  E8 FF53					call		sdcmd8T
 03E3  0A E4					or		ah, ah
 03E5  75 19					jnz		sdexit
 03E7  E8 FF55					call		sdresp      ; wait for 0feh token
 03EA  80 FC FE					cmp		ah, 0feh
 03ED  75 11					jne		sdexit
 03EF  B1 12					mov		cl, 18      ; 16bytes + 2bytes CRC
 03F1  2B E1					sub		sp, cx
 03F3  8B FC					mov		di, sp
 03F5  E8 FF35					call		sdrblk
 03F8  8B 4D F6					mov		cx, [di-10]
 03FB  86 CD					xchg		cl, ch
 03FD  41					inc		cx
 03FE  8B E7					mov		sp, di
 0400				sdexit: 
 0400  33 C0					xor		ax, ax      ; raise CS
 0402  EF					out		dx, ax
 0403  E8 FF15					call	sdrb
 0406  8B C1					mov		ax, cx       
 0408  C3					ret
 0409				sdinit_ endp

				    
 0409 42 49 4F 53 20 6E		booterrmsg  db  'BIOS not present on SDCard last 8KB, waiting on RS232 (115200bps, f000:100) ...', 0
       6F 74 20 70 72 65
       73 65 6E 74 20 6F
       6E 20 53 44 43 61
       72 64 20 6C 61 73
       74 20 38 4B 42 2C
       20 77 61 69 74 69
       6E 67 20 6F 6E 20
       52 53 32 33 32 20
       28 31 31 35 32 30
       30 62 70 73 2C 20
       66 30 30 30 3A 31
       30 30 29 20 2E 2E
       2E 00
 0459 40 00 00 00 00 95		SD_CMD0		db		40h, 0, 0, 0, 0, 95h
 045F 48 00 00 01 AA 87		SD_CMD8		db		48h, 0, 0, 1, 0aah, 087h
 0465 49 00 00 00 00 FF		SD_CMD9		db		49h, 0, 0, 0, 0, 0ffh
 046B 69 40 00 00 00 FF		SD_CMD41	db		69h, 40h, 0, 0, 0, 0ffh
 0471 77 00 00 00 00 FF		SD_CMD55	db		77h, 0, 0, 0, 0, 0ffh
 0477 7A 00 00 00 00 FF		SD_CMD58	db		7ah, 0, 0, 0, 0, 0ffh


				; ---------------- RESET ------------------
						org 05f0h
 05F0				start:
 05F0  EA					db		0eah
 05F1  FC00 F000				dw		BOOTOFFSET, 0f000h
 05F5  00 00 00 00 00 00			db		0,0,0,0,0,0,0,0,0,0,0
       00 00 00 00 00
				       
				end exec
Microsoft (R) Macro Assembler Version 6.14.8444		    06/06/13 17:19:05
bootstrap.asm						     Symbols 2 - 1




Segments and Groups:

                N a m e                 Size     Length   Align   Combine Class

DGROUP . . . . . . . . . . . . .	GROUP
_TEXT  . . . . . . . . . . . . .	16 Bit	 0600	  Word	  Public  'CODE'	
_DATA  . . . . . . . . . . . . .	16 Bit	 0000	  Word	  Public  'DATA'	


Procedures,  parameters and locals:

                N a m e                 Type     Value    Attr

sdinit_  . . . . . . . . . . . .	P Near	 0383	  _TEXT	Length= 0086 Public
  sdinit1  . . . . . . . . . . .	L Near	 0389	  _TEXT	
  repinit  . . . . . . . . . . .	L Near	 03B5	  _TEXT	
  sdexit . . . . . . . . . . . .	L Near	 0400	  _TEXT	
sdread_  . . . . . . . . . . . .	P Near	 034D	  _TEXT	Length= 0036 Public
  sdr1 . . . . . . . . . . . . .	L Near	 037C	  _TEXT	


Symbols:

                N a m e                 Type     Value    Attr

@CodeSize  . . . . . . . . . . .	Number	 0000h	 
@DataSize  . . . . . . . . . . .	Number	 0000h	 
@Interface . . . . . . . . . . .	Number	 0000h	 
@Model . . . . . . . . . . . . .	Number	 0001h	 
@code  . . . . . . . . . . . . .	Text   	 DGROUP
@data  . . . . . . . . . . . . .	Text   	 DGROUP
@fardata?  . . . . . . . . . . .	Text   	 FAR_BSS
@fardata . . . . . . . . . . . .	Text   	 FAR_DATA
@stack . . . . . . . . . . . . .	Text   	 DGROUP
BIOSOK . . . . . . . . . . . . .	L Near	 02D4	  _TEXT	
BIOSSIZE . . . . . . . . . . . .	Number	 0010h	 
BOOTOFFSET . . . . . . . . . . .	Number	 FC00h	 
RS232  . . . . . . . . . . . . .	L Near	 0264	  _TEXT	
SD_CMD0  . . . . . . . . . . . .	Byte	 0459	  _TEXT	
SD_CMD41 . . . . . . . . . . . .	Byte	 046B	  _TEXT	
SD_CMD55 . . . . . . . . . . . .	Byte	 0471	  _TEXT	
SD_CMD58 . . . . . . . . . . . .	Byte	 0477	  _TEXT	
SD_CMD8  . . . . . . . . . . . .	Byte	 045F	  _TEXT	
SD_CMD9  . . . . . . . . . . . .	Byte	 0465	  _TEXT	
begin  . . . . . . . . . . . . .	L Far	 0200	  _TEXT	
booterrmsg . . . . . . . . . . .	Byte	 0409	  _TEXT	
dly1 . . . . . . . . . . . . . .	L Near	 0312	  _TEXT	
dlybit . . . . . . . . . . . . .	L Near	 030E	  _TEXT	
endreloc . . . . . . . . . . . .	L Near	 02EF	  _TEXT	
exec . . . . . . . . . . . . . .	L Near	 0100	  _TEXT	
flush  . . . . . . . . . . . . .	L Near	 02AF	  _TEXT	
l1 . . . . . . . . . . . . . . .	L Near	 0303	  _TEXT	
nextchar . . . . . . . . . . . .	L Near	 02A7	  _TEXT	
nextsect . . . . . . . . . . . .	L Near	 023C	  _TEXT	
reloc  . . . . . . . . . . . . .	L Near	 02E8	  _TEXT	
sdcmd1 . . . . . . . . . . . . .	L Near	 034C	  _TEXT	
sdcmd8T  . . . . . . . . . . . .	L Near	 0336	  _TEXT	
sdcmd  . . . . . . . . . . . . .	L Near	 0339	  _TEXT	
sdrblk . . . . . . . . . . . . .	L Near	 032D	  _TEXT	
sdrb . . . . . . . . . . . . . .	L Near	 031B	  _TEXT	
sdresp1  . . . . . . . . . . . .	L Near	 0341	  _TEXT	
sdresp . . . . . . . . . . . . .	L Near	 033F	  _TEXT	
sdsb1  . . . . . . . . . . . . .	L Near	 031F	  _TEXT	
sdsb . . . . . . . . . . . . . .	L Near	 031D	  _TEXT	
sdwblk . . . . . . . . . . . . .	L Near	 0326	  _TEXT	
sloop  . . . . . . . . . . . . .	L Near	 02C2	  _TEXT	
srecb  . . . . . . . . . . . . .	L Near	 02EF	  _TEXT	
srstb  . . . . . . . . . . . . .	L Near	 02F7	  _TEXT	
start  . . . . . . . . . . . . .	L Near	 05F0	  _TEXT	

	   0 Warnings
	   0 Errors
