Skip to content

Ugly But It Works!

February 23, 2017

With a couple of false starts I have the 1806 loading and running code and using the 1806 native subroutine call/return instructions.

The 1806 runs pretty well any 1802 code but has a bunch of new instructions including hardware subroutine call/return. It lacks the load mode of the 1802 which is what the AVR uses to bootload it. To get around that I wrote a simple xmodem receiver and loaded it while I had the 1802 chip in the olduino. I then swapped in the 1806 and made the video.

I made a new target for the LCC1802 compiler(XR18NW) that will be the platform for the 1806 adaptation. At the moment it only has my horrible kludge for the subroutine call/return.

//ssxload super simple xmodem loader
//loads a single 32 byte block with checksum from a custom host program
//17-02-08 timeout on initial receives
//17-02-09 no timeouts, single start ack, no error checking
//17-02-09 header read moved into main
//17-02-12 block level error checking and NAK
//17-02-14 send stx before using xmodem. esc is now 0x1b
//17-02-16 slimming down, axloader.h
//17-02-17 target=0x2000, stripping out diagnostic arrays 7621 bytes
#include <nstdlib.h>
#include <olduino.h>
#include <cpu1802spd4port7.h>
#include "xloader.h"
#define blocksize 128
#define target 0x2000
unsigned char *targetdata=(unsigned char *)0x2000; //allows 8K for loader
typedef void (*funptr)();
funptr targetcode=(funptr) target;
unsigned char blkno, hdr,bseq,iseq,ciseq,csum,calcsum,valid;
int readblk(unsigned char * where){//read a block
	unsigned int cnt=blocksize;
	unsigned char ch,rc=0;
	bseq=readch();
	iseq=readch();
	calcsum=0;
	while(cnt>0){
		ch=readch();
		*where++=ch;
		calcsum+=ch;
		cnt--;
	}
	csum=readch(); //read the checksum
	if (calcsum!=csum){//check it
		rc+=4;
	}
	if (bseq!=(blkno+1)){
		rc+=1;
	}
	if (iseq!=(254-blkno)){
		rc+=2;
	}
	return rc;
}

void main(){
	int ch='?',eot=0;
	unsigned char *t=targetdata;
	unsigned int i, tries=0,maxtries=1000;
	unsigned char thishdr;
	blkno=0;
	asm(" seq\n nop\n req\n");
	out(7,STX); //enable interrupts for host data
	putch(NAK); //send NAK to start
	thishdr=readch(); //get the header character

	while(thishdr!=EOT){
		if (SOH==thishdr){
			hdr=thishdr;
			valid=readblk(t);
			if (0==valid){
				blkno++;
				t+=blocksize;
				putch(ACK);
			}else{
				putch(NAK);
			}
		}
		thishdr=getchOrTo(1000);
	}

	putch(ACK);
//and we're done - god willing
	out(7,ETX); //disable interrupts for host data
	//if (++tries<maxtries){
		delay(1000);//let python clear out
		printf("terminating header was 0x%cx\n",thishdr);
		dump(targetdata,16);
		printf("number of blocks %d\n",blkno);
		printf("hh:bn/in c:i r:cs c:cs valid?\n");
		printf("%cx:%cx/%cx c:%cx r:%cx c:%cx %d\n",hdr,bseq,iseq,ciseq,csum,calcsum,valid);
	//}
	printf("\nRun1806(%d)\n",tries);
	asm(" ccall 0x2000\n");
	while(1);
}
#include <nstdlib.c>
#include <olduino.c>

from __future__ import print_function
import sys
import logging
logging.basicConfig()
import serial
try:
    from cStringIO import StringIO
except:
    from StringIO import StringIO
from time import sleep
import os
if len(sys.argv)>1:
    filename=sys.argv[1]
else:
    filename="test32.txt"
print ("File Namee is",filename)
fileSize=os.path.getsize(filename)
print ("File Size is",fileSize)

def xmodem_send(serial, file):
	blocksize=128
	t=0
	#	t, anim ='|/-\\'
	while 1:
	    if serial.read(1) != 'N':
		t = t + 1
		print ('.')
		if t == 3 : return False
	    else:
		break

	p = 1
	s = file.read(blocksize)
	while s:
	    s = s + '\xFF'*(blocksize - len(s))
	    chk = 0
	    for c in s:
		chk+=ord(c)
		#print (c,ord(c),chk,chk%256)
	    while 1:
		serial.write('S') #SOH)
		serial.write(chr(p))
		serial.write(chr(255 - p))
		serial.write(s)
		serial.write(chr(chk%256))
		serial.flush()
		print ('checksum is ',format(chk%256, '02X'),end=' ')
		answer = serial.read(1)
		if  answer == 'N': continue
		if  answer == 'K': break
		print ("unknown answer - length is ",len(answer))
		for character in answer:
  			print (character, character.encode('hex'))
		return False
	    s = file.read(blocksize)
	    p = (p + 1)%256
	    print ('.')
	serial.write('T')
	serial.flush()
	sleep(.1)
	serial.write('T')
	serial.flush()

	return True

#Main program starts here - define the serial port, set RTS off, then open it
#open the file to be loaded
stream = open(filename,'rb')
print("file is open")
port = serial.Serial(parity=serial.PARITY_NONE,
                     bytesize=serial.EIGHTBITS,
                     stopbits=serial.STOPBITS_ONE,timeout=10,xonxoff=0,
                     rtscts=0,dsrdtr=0,baudrate=57600)
port.rts=False
port.port='COM3'
port.open()
port.rts=True
sleep(0.001)
port.rts=False
port.flushInput()
sleep(2) # give avrisp a second to clear out
#transfer the file
result=xmodem_send(port, stream)

stream.close()
port.close()

if result:
    print ("\ntransfer successful")
else:
    print ("\ntransfer unsuccessful")

Final Pro Tip of the day, when you are swapping CPU chips, pay attention to which end goes where!
I first put the 1806 in backwards but it survived the assault.
17-02-23-wrongo

Advertisements

From → Uncategorized

Leave a Comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: