CRC65, A frugal 6502 SBC

Topics related to the SBC- series of printed circuit boards, designed by Daryl Rictor and popular with many 6502.org visitors.
plasmo
Posts: 1273
Joined: 21 Dec 2018
Location: Albuquerque NM USA

Re: CRC65, A frugal 6502 SBC

Post by plasmo »

Thank you, I like your version of savebyte. It is certainly more efficient and I can build a bigger program in RAM. Use zero page is a good idea for later. Right now I like to leave as many intermediate data intact in memory as possible so I can figured out what happened.

The reason I mentioned 256-byte for master boot record is because CF native mode is 16-bit, so its 512-byte sector is arranged as 256x16 after reset. I use the lower byte and discard the upper byte. 256 bytes are all I can get out of MBR at this stage of bootstrapping.

Your idea about treating the remaining data in the FIFO as a program is a good one. So instead of forming a small program in RAM then padded with bunch of illegal instructions until the jmp $800; I can jump to $800 immediately after the small program in RAM is created, then treat the remaining data in FIFO as a new program. On the other hand, 256 bytes are all I have to work with so the original idea was replacing the serial loader with a small CF loader that initializes the CF to another sector, say sector 1, and loads its contents (256 bytes) into memory and runs it. This CF loader is also a small-ish program that can be created with the initial 256-byte blind boot opcodes.

At this stage of development, flexibility is important so I like the multi-stage bootstrap and managed it with TeraTerm macro script. Eventually I do want everything to be self-contained in a CF disk then save the CF disk image as the distribution media for new computers.
Bill
plasmo
Posts: 1273
Joined: 21 Dec 2018
Location: Albuquerque NM USA

Re: CRC65, A frugal 6502 SBC

Post by plasmo »

I've had good bit of fun writing software for CF bootstrapping. George's version of savebyte is very helpful because it allows decent size program to be created in zero page with 256 bytes of opcodes streaming from CF's master boot record. I tried several methods. George has suggested first creating a tiny program in RAM that reads the remaining data from CF's master boot record as the second level bootstrap program. That was quite convoluted, but worked quite well once I've figured out the multiple levels of bootstraps. Below is the program that worked reliably.

The first half (above the two lines of ****) is the tiny program created in RAM at $800-$80b. The tiny program executes and copies remaining data (2nd level bootstrap) in CF to $900 and then jumps into $900. The 2nd level bootstrap copies the monitor program previously stored in multiple sectors of CF disk to RAM and then jumps into the monitor. Whew!

Code: Select all

.macro	savebyte val,addr
	LDA #val
	STA addr
.endmacro	

	.ORG $b300
;This is the opcode stream for master boot record
; it will be executed as stream of opcode for 65c02
	NOP			;reset vector plus extra padding
	NOP
	NOP
	NOP
	NOP
	.byte 3			;illegal instruction executed in 1 cycle
				;for synchronization purpose

	savebyte $ad,$800	;xx: LDA $e000	
	savebyte $00,$801
	savebyte $e0,$802
	savebyte $9d,$803	;STA $900,x
	savebyte $00,$804		
	savebyte $09,$805
	savebyte $e8,$806	;INX	
	savebyte $d0,$807	;BNE xx
	savebyte $f7,$808
	savebyte $4c,$809	;JMP $900	
	savebyte $00,$80a
	savebyte $09,$80b
	
	LDX #0			;initialize regX here to save program space	
	JMP $800
;program above is executed as it streams out of CF data port		
;	.org $800
;this is the first stage loader, loading 256 bytes of following data into 0x900
; then jump into 0x900	
;               xx:
;  AD 00 80     	LDA $e000		;read from CF
;  9D 00 09     	STA $900,x
;  E8           	INX
;  D0 F7        	BNE xx
;  4C 00 09     	JMP $900

;xx:	
;	LDA $e000		;read from CF
;	STA $900,x
;	INX
;	BNE xx
;	JMP $900

;*********************** program below is loaded into $900 by program above *************
;************************  then start the program at $900 *********************

;The hardware is now in normal mode where serial is $8000-$83FF, CF is $8400-$87FF	
;zero page locations 0xc0 and 0xc1 are indirect index of address to be loaded
	STZ $c0			;put zero in $c0 (LSB)
	LDA #$b4		;put $b4 in $c1 (MSB)
	STA $c1			
	LDX #2			;CHS mode, read sectors $2-$d, start from sector 0x2
moresectx:	
	LDA #1			;sector count of 1
	STA CFsectcnt		
	STX CF07		;X contains the sector to be read
	LDA #$20		;read CF command
	STA CFstat		
readdrqx:	
	LDA CFstat		;check data request bit set before read CF data
	BMI readdrqx
	AND #8
	BEQ readdrqx
blk1stx:	
	LDA CFdata
	STA ($c0)		;save, starting from 0xB400
	INC $c0
	BNE blk1stx
	INC $c1			;next 256 bytes
	INX			;next CF sector
	CPX #$d
	BNE moresectx	
	JMP $b400		;start location of CRCMon

	.align 256,3		
Frankly that was too convoluted for me. I can barely keep it straight in my head right now, never mind a few months from now. So I decided to reduced one level of bootstrapping by putting the 2nd level bootstrap in the 1st level. This is possible because the 2nd level bootstrap is 46 bytes, so it can be created with 256 bytes of opcode stream with spare. This simpler bootstrap also worked well and hopefully I can still explain it a few months later.

The end result for both methods are the same; the hardware signed on with monitor prompt a fraction of second after power on.

That was fun. Now I'll go back to work on the hardware as either TTL implementation or GAL22V10 design.

Code: Select all

.macro	savebyte val,addr
	LDA #val
	STA addr
.endmacro	

	.ORG $b300
;This is the opcode stream save to master boot record
; it will be executed as stream of opcode for 65c02
	NOP			;reset vector plus extra padding
	NOP
	NOP
	NOP
	NOP
	.byte 3			;illegal instruction executed in 1 cycle
				;for synchronization purpose
				;delayx:
	savebyte $AD,$00	;LDA CFstat		
	savebyte $07,$01
	savebyte $84,$02
	savebyte $E8,$03	;INX
	savebyte $D0,$04	;BNE delayx
	savebyte $FA,$05		
	savebyte $A2,$06	;LDX #2
	savebyte $02,$07
	savebyte $8C,$08	;moresectx: STY CFsectcnt
	savebyte $02,$09
	savebyte $84,$0A
	savebyte $8E,$0B	;STX CF07	
	savebyte $03,$0C
	savebyte $84,$0D
	savebyte $A9,$0E	;LDA #$20
	savebyte $20,$0F
	savebyte $8D,$10	;STA CFstat
	savebyte $07,$11
	savebyte $84,$12	
	savebyte $AD,$13	;readdrqx: LDA CFstat	
	savebyte $07,$14
	savebyte $84,$15
	savebyte $30,$16	;BMI readdrqx
	savebyte $FB,$17
	savebyte $29,$18	;AND #8	
	savebyte $08,$19
	savebyte $F0,$1A	;BEQ readdrqx
	savebyte $F7,$1B	
	savebyte $AD,$1C	;blkx: LDA CFdata
	savebyte $00,$1D
	savebyte $84,$1E
	savebyte $92,$1F	;STA ($c0)
	savebyte $C0,$20
	savebyte $E6,$21	;INC $c0
	savebyte $C0,$22
	savebyte $D0,$23	;BNE blkx
	savebyte $F7,$24
	savebyte $E6,$25	;INC $c1	
	savebyte $C1,$26
	savebyte $E8,$27	;INX
	savebyte $E0,$28	;CPX #$e
	savebyte $0E,$29
	savebyte $D0,$2A	;BNE moresectx
	savebyte $DC,$2B	
	savebyte $4C,$2C
	savebyte $00,$2D
	savebyte $B4,$2E

;to save program space, initialization of zero page as well as registers can be done 
;  as instruction streams out

	STZ $c0			;set up ZP as pointer from CF to memory
	LDA #$b4		;$b400 is starting of monitor
	STA $c1
	LDX #0
	LDY #1			;regY is always 1 to write to CF sector count reg
	.align 253,03
	JMP $0

;*********************** program below is created in zero page by program above *************
; CF is still in CHS mode.  Sector 2 to sector $D correspond to monitor from $b400-$bfff
;	
;000000r 1               	.org $0
;000000  1               ; CF is still in CHS mode.  Sector 2 to sector $D correspond to monitor from $b400-$bfff
;000000  1               delayx:				;value of $c0 is zero here
;000000  1               				;delay is needed for nDASP to negate and switch to normal mode
;000000  1  AD 07 84     	LDA CFstat		;read clear the CF FIFO
;000003  1  E8           	INX
;000004  1  D0 FA        	BNE delayx
;000006  1  A2 02        	LDX #2			;start from sector 2
;000008  1               ; ZP $c0,$c1 are already initialized, regY is 1
;000008  1               moresectx:
;000008  1               ; zero page locations 0xc0 and 0xc1 are indirect index of address to be loaded
;000008  1  8C 02 84     	STY CFsectcnt		;sector count of 1
;00000B  1  8E 03 84     	STX CF07
;00000E  1  A9 20        	LDA #$20		;read CF command
;000010  1  8D 07 84     	STA CFstat
;000013  1               readdrqx:
;000013  1  AD 07 84     	LDA CFstat		;check data request bit set before read CF data
;000016  1  30 FB        	BMI readdrqx		;spin on BSY set
;000018  1  29 08        	AND #8			;spin on DRQ
;00001A  1  F0 F7        	BEQ readdrqx
;00001C  1               blkx:
;00001C  1  AD 00 84     	LDA CFdata
;00001F  1  92 C0        	STA ($c0)		;save, starting from 0xB400
;000021  1  E6 C0        	INC $c0
;000023  1  D0 F7        	BNE blkx
;000025  1  E6 C1        	INC $c1			;next 256 bytes
;000027  1  E8           	INX			;next CF sector
;000028  1  E0 0E        	CPX #$e
;00002A  1  D0 DC        	BNE moresectx
;00002C  1  4C 00 B4     	JMP $b400		;start location of CRCMon

plasmo
Posts: 1273
Joined: 21 Dec 2018
Location: Albuquerque NM USA

Re: CRC65, A frugal 6502 SBC

Post by plasmo »

I ordered a batch of GAL22V10 from eBay, but they turned out to be fakes--they are writable but not verifiable.  I returned it and ordered another batch from different vendor.  In the meantime I have an unknown old batch of GAL20V8 that programed and verified OK, so I'll try it while learning about WinCUPL.

The CF bootstrap circuit should fit a GAL22v10, but needed two GAL20V8 to fit, at least with my current understanding of WinCUPL.  I've split the design into state machine GAL20V8 with 5 registers representing various states of CF disk, and combinatorial GAL20V8 driving the CF signals.  New design, new (old) device, new (old) design software, so I expect problems. I'll breadboard it and find a way to test it.

Since the CPLD-based CF bootstrap is working as described in previous posts, I'll build the GAL20V8 implementation in parallel and compare their outputs to CPLD. Here are pictures of the two GAL20V8 in parallel with CPLD-based design.

When I received GAL22V10, I'll also prototype it in parallel and compare its outputs with working hardware.
Attachments
DSC_74841120.jpg
DSC_74831120.jpg
Post Reply