Microsoft (R) Macro Assembler Version 6.14.8444		    09/26/16 15:48:17
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 0163					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 010D					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 72					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 FE0F					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  BB 4000					mov		bx, 4000h
 02B0				flush:        
 02B0  8A 07					mov		al, [bx]
 02B2  83 EB 40					sub		bx, 40h
 02B5  75 F9					jnz		flush
					
 02B7  BE 0100					mov		si, 100h
 02BA  E8 0034					call		srecb
 02BD  8A FC					mov		bh, ah
 02BF  E8 002F					call		srecb
 02C2  8A DC					mov		bl, ah

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

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

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

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

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

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

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

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

 0358  BA 03DA					mov		dx, 3dah
 035B  B4 01					mov		ah, 1
 035D  EF					out		dx, ax      ; CS on
 035E  C6 44 05 FF				mov		byte ptr [si+5], 0ffh ; checksum
 0362  E8 FFD6					call		sdcmd
 0365  83 C4 06					add		sp, 6
 0368  0A E4					or		ah, ah
 036A  75 16					jnz		sdr1        ; error (cx=0)
 036C  E8 FFD2					call		sdresp      ; wait for 0feh token
 036F  80 FC FE					cmp		ah, 0feh
 0372  75 0E					jne		sdr1        ; read token error (cx=0)
 0374  B5 02					mov		ch, 2       ; 512 bytes
 0376  8B FB					mov		di, bx
 0378  E8 FFB4					call		sdrblk
 037B  E8 FF9F					call		sdrb        ; ignore CRC
 037E  E8 FF9C					call		sdrb        ; ignore CRC
 0381  41					inc		cx          ; 1 block
 0382				 sdr1:       
 0382  33 C0					xor		ax, ax
 0384  EF					out		dx, ax
 0385  E8 FF95					call		sdrb        ; 8T
 0388  C3					ret     
 0389				sdread_ endp
				        
				;---------------------  init SD ----------------------
 0389				sdinit_ proc near       ; returns AX = num kilosectors
 0389  BA 03DA					mov		dx, 3dah
 038C  B9 000A					mov		cx, 10
 038F				sdinit1:                   ; send 80T
 038F  E8 FF8B					call		sdrb
 0392  E2 FB					loop		sdinit1

 0394  B4 01					mov		ah, 1
 0396  EF					out		dx, ax       ; select SD

 0397  BE FE5F					mov		si, SD_CMD0 + BOOTOFFSET - begin
 039A  E8 FF9E					call		sdcmd
 039D  FE CC					dec		ah
 039F  75 65					jnz		sdexit      ; error
						
 03A1  BE FE65					mov		si, SD_CMD8 + BOOTOFFSET - begin
 03A4  E8 FF91					call		sdcmd8T
 03A7  FE CC					dec		ah
 03A9  75 5B					jnz		sdexit      ; error
 03AB  B1 04					mov		cl, 4
 03AD  2B E1					sub		sp, cx
 03AF  8B FC					mov		di, sp
 03B1  E8 FF7B					call		sdrblk
 03B4  58					pop		ax
 03B5  58					pop		ax
 03B6  80 FC AA					cmp		ah, 0aah
 03B9  75 4B					jne		sdexit      ; CMD8 error
 03BB				repinit:        
 03BB  BE FE77					mov		si, SD_CMD55 + BOOTOFFSET - begin
 03BE  E8 FF77					call		sdcmd8T
 03C1  E8 FF59					call		sdrb
 03C4  BE FE71					mov		si, SD_CMD41 + BOOTOFFSET - begin
 03C7  E8 FF71					call		sdcmd
 03CA  FE CC					dec		ah
 03CC  74 ED					jz		repinit
						
 03CE  BE FE7D					mov		si, SD_CMD58 + BOOTOFFSET - begin
 03D1  E8 FF64					call		sdcmd8T
 03D4  B1 04					mov		cl, 4
 03D6  2B E1					sub		sp, cx
 03D8  8B FC					mov		di, sp
 03DA  E8 FF52					call		sdrblk
 03DD  58					pop		ax
 03DE  A8 40					test		al, 40h     ; test OCR bit 30 (CCS)
 03E0  58					pop		ax
 03E1  74 23					jz		sdexit      ; no SDHC

 03E3  BE FE6B					mov		si, SD_CMD9 + BOOTOFFSET - begin ; get size info
 03E6  E8 FF4F					call		sdcmd8T
 03E9  0A E4					or		ah, ah
 03EB  75 19					jnz		sdexit
 03ED  E8 FF51					call		sdresp      ; wait for 0feh token
 03F0  80 FC FE					cmp		ah, 0feh
 03F3  75 11					jne		sdexit
 03F5  B1 12					mov		cl, 18      ; 16bytes + 2bytes CRC
 03F7  2B E1					sub		sp, cx
 03F9  8B FC					mov		di, sp
 03FB  E8 FF31					call		sdrblk
 03FE  8B 4D F6					mov		cx, [di-10]
 0401  86 CD					xchg		cl, ch
 0403  41					inc		cx
 0404  8B E7					mov		sp, di
 0406				sdexit: 
 0406  33 C0					xor		ax, ax      ; raise CS
 0408  EF					out		dx, ax
 0409  E8 FF11					call	sdrb
 040C  8B C1					mov		ax, cx       
 040E  C3					ret
 040F				sdinit_ endp

				    
 040F 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
 045F 40 00 00 00 00 95		SD_CMD0		db		40h, 0, 0, 0, 0, 95h
 0465 48 00 00 01 AA 87		SD_CMD8		db		48h, 0, 0, 1, 0aah, 087h
 046B 49 00 00 00 00 FF		SD_CMD9		db		49h, 0, 0, 0, 0, 0ffh
 0471 69 40 00 00 00 FF		SD_CMD41	db		69h, 40h, 0, 0, 0, 0ffh
 0477 77 00 00 00 00 FF		SD_CMD55	db		77h, 0, 0, 0, 0, 0ffh
 047D 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		    09/26/16 15:48:17
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	 0389	  _TEXT	Length= 0086 Public
  sdinit1  . . . . . . . . . . .	L Near	 038F	  _TEXT	
  repinit  . . . . . . . . . . .	L Near	 03BB	  _TEXT	
  sdexit . . . . . . . . . . . .	L Near	 0406	  _TEXT	
sdread_  . . . . . . . . . . . .	P Near	 034F	  _TEXT	Length= 003A Public
  sdr1 . . . . . . . . . . . . .	L Near	 0382	  _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	 02D6	  _TEXT	
BIOSSIZE . . . . . . . . . . . .	Number	 0010h	 
BOOTOFFSET . . . . . . . . . . .	Number	 FC00h	 
RS232  . . . . . . . . . . . . .	L Near	 0264	  _TEXT	
SD_CMD0  . . . . . . . . . . . .	Byte	 045F	  _TEXT	
SD_CMD41 . . . . . . . . . . . .	Byte	 0471	  _TEXT	
SD_CMD55 . . . . . . . . . . . .	Byte	 0477	  _TEXT	
SD_CMD58 . . . . . . . . . . . .	Byte	 047D	  _TEXT	
SD_CMD8  . . . . . . . . . . . .	Byte	 0465	  _TEXT	
SD_CMD9  . . . . . . . . . . . .	Byte	 046B	  _TEXT	
begin  . . . . . . . . . . . . .	L Far	 0200	  _TEXT	
booterrmsg . . . . . . . . . . .	Byte	 040F	  _TEXT	
dly1 . . . . . . . . . . . . . .	L Near	 0314	  _TEXT	
dlybit . . . . . . . . . . . . .	L Near	 0310	  _TEXT	
endreloc . . . . . . . . . . . .	L Near	 02F1	  _TEXT	
exec . . . . . . . . . . . . . .	L Near	 0100	  _TEXT	
flush  . . . . . . . . . . . . .	L Near	 02B0	  _TEXT	
l1 . . . . . . . . . . . . . . .	L Near	 0305	  _TEXT	
nextchar . . . . . . . . . . . .	L Near	 02A7	  _TEXT	
nextsect . . . . . . . . . . . .	L Near	 023C	  _TEXT	
reloc  . . . . . . . . . . . . .	L Near	 02EA	  _TEXT	
sdcmd1 . . . . . . . . . . . . .	L Near	 034E	  _TEXT	
sdcmd8T  . . . . . . . . . . . .	L Near	 0338	  _TEXT	
sdcmd  . . . . . . . . . . . . .	L Near	 033B	  _TEXT	
sdrblk . . . . . . . . . . . . .	L Near	 032F	  _TEXT	
sdrb . . . . . . . . . . . . . .	L Near	 031D	  _TEXT	
sdresp1  . . . . . . . . . . . .	L Near	 0343	  _TEXT	
sdresp . . . . . . . . . . . . .	L Near	 0341	  _TEXT	
sdsb1  . . . . . . . . . . . . .	L Near	 0321	  _TEXT	
sdsb . . . . . . . . . . . . . .	L Near	 031F	  _TEXT	
sdwblk . . . . . . . . . . . . .	L Near	 0328	  _TEXT	
sloop  . . . . . . . . . . . . .	L Near	 02C4	  _TEXT	
srecb  . . . . . . . . . . . . .	L Near	 02F1	  _TEXT	
srstb  . . . . . . . . . . . . .	L Near	 02F9	  _TEXT	
start  . . . . . . . . . . . . .	L Near	 05F0	  _TEXT	

	   0 Warnings
	   0 Errors
