diff options
author | Dominic Radermacher <blip@mockmoon-cybernetics.ch> | 2017-07-19 14:08:49 +0200 |
---|---|---|
committer | Dominic Radermacher <blip@mockmoon-cybernetics.ch> | 2017-07-19 14:08:49 +0200 |
commit | c57a8a9bf49fa7a3231ce8d6e435603e8ab016eb (patch) | |
tree | 6c83a316511a185cc497a4fc2237742417d3c718 /src/s19stuff.c |
initial importv0.9
Diffstat (limited to 'src/s19stuff.c')
-rw-r--r-- | src/s19stuff.c | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/src/s19stuff.c b/src/s19stuff.c new file mode 100644 index 0000000..59b39fb --- /dev/null +++ b/src/s19stuff.c @@ -0,0 +1,148 @@ + +/* -------------------------------------------------------------------- + Copyright (C) 2004 Dominic Radermacher <dominic.radermacher@gmail.com> + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + -------------------------------------------------------------------- */ + +#include <stdio.h> +#include <ctype.h> /* isdigit(), tolower() */ + +#include "s19stuff.h" + +static uint8_t _s19_chksum_val=0; + +uint8_t hex2chr(char *s) +{ + return( ((isdigit(s[0])?s[0]-'0':tolower(s[0])-'a'+10)<<4) + + (isdigit(s[1])?s[1]-'0':tolower(s[1])-'a'+10)); +} + +void s19_chksum_init(void) +{ + _s19_chksum_val=0; +} + +void s19_chksum_add(uint8_t val) +{ + _s19_chksum_val += val; +} + +uint8_t s19_chksum_get(void) +{ + return ~_s19_chksum_val; +} + +int parse_s19_line(struct obj *bo, char *buf) +{ + int i, len, addr, val; + + if(*buf++ != 'S') { + return -1; + } + s19_chksum_init(); + val=0; + if(*buf == '0') { + printf("ignoring S0 record\n"); + return 0; + } else if(*buf == '1') { + len=hex2chr(++buf); + s19_chksum_add(len); + buf+=2; + addr=hex2chr(buf); + s19_chksum_add(addr); + buf+=2; + addr=addr<<8; + val=hex2chr(buf); + s19_chksum_add(val); + addr+=val; + buf+=2; + for(i=0; i<len-3; i++) { + val=hex2chr(buf); + bo->code[addr+i]=val; + s19_chksum_add(val); + buf+=2; + } + val=hex2chr(buf); + if(val != s19_chksum_get()) { /* checksum does not match */ + printf("Invalid checksum for S1 Record: len=%d bytes addr=%04x chk=%02x calc=%02x\n", len, addr, val, s19_chksum_get()); + } + if(bo->start_addr > addr) { + bo->start_addr = addr; + } + if(bo->end_addr < (addr+len-3)) { + bo->end_addr = addr+len-3; + } + } else if((*buf == '2') || (*buf == '3') || (*buf == '7') || (*buf == '8')) { + printf("S%c records cant be loaded to the 68HC11 (16 bit adress only)\n", *buf); + return -1; + } else if(*buf == '5') { + printf("S5 record count ignored\n"); + return 0; + } else if(*buf == '9') { + printf("S9 record ignored yet\n"); + return 0; + } + if(val != s19_chksum_get()) { + printf("checksum error (found: %02x, expected: %02x)\n", val, s19_chksum_get()); + } + return 0; +} + +/* -------------------------------------------------------------------- + Description read from file 'f' to buffer 'd' of size 'size' + until either the buffer is full, or \n or EOF is + found. return the number of read octets or -1 + if no octets could be read (EOF) + -------------------------------------------------------------------- */ + +int f_readline(FILE *f, char *buf, int size) +{ + int n, c; + char *p; + + for(n=0, p=buf; n<size; ) { + c=fgetc(f); + if(c != EOF) { + if(c == '\n') break; /* LF -> stop and terminate */ + *p++=c; + n++; + } else { + if(n != 0) break; /* line NOT empty -> terminate */ + return -1; /* else return -1 */ + } + } + if(n < size) { /* we have left space to terminate string */ + *p=0; + } + return n; +} + +int load_s19file(struct obj *bo, char *file) +{ + int i; + char buf[515]; /* 'S1' + len (2 chars) + 255*2 + '\0' */ + FILE *f; + + bo->start_addr=0xffff; + bo->end_addr=0x0000; + for(i=0; i<(int)sizeof(bo->code); bo->code[i++]=0); + if((f=fopen(file, "r")) == NULL) { + fprintf(stderr, "cant open file '%s'\n", file); + return -1; + } + while((i=f_readline(f, buf, 515)) != -1) { + parse_s19_line(bo, buf); + } + return 0; +} |