--- /dev/null
+CC=cc65
+AS=ca65
+LD=cl65
+
+CFLAGS= -t c128
+
+all: image crctest
+
+image: diskbench.d71
+
+diskbench.d71: diskbench
+ c1541 -format "diskbench",db d71 diskbench.d71
+ touch data
+ c1541 -attach diskbench.d71 -write diskbench
+ c1541 -attach diskbench.d71 -write data data,s
+
+%.s: %.c
+ ${CC} ${CFLAGS} -O1 $< -o $@
+
+%.o: %.s
+ ${AS} ${CFLAGS} $< -o $@
+
+diskbench.s: diskbench.c
+
+diskbench: diskbench.o bcd2dec.o
+ ${LD} -t c128 $^ -o $@
+
+crctest.s: crctest.c
+
+crctest: crctest.o crc16.o bcd2dec.o
+ ${LD} -Ln crctest.lbl -t c128 $^ -o $@
+
+clean:
+ rm -f *.o crctest diskbench diskbench.d71 data *.lbl crctest.s diskbench.s
--- /dev/null
+extern uint8_t __fastcall__ bcd2dec(uint8_t bcd);
--- /dev/null
+
+ .export _bcd2dec
+ .importzp tmp1,tmp2
+
+.code
+
+.proc _bcd2dec
+ tax
+ and #%00001111
+ sta tmp1
+ txa
+ and #%11110000 ; *16
+ lsr ; *8
+ sta tmp2
+ lsr
+ lsr ; *2
+ adc tmp2 ; = *10
+ adc tmp1
+ ldx #0
+ rts
+.endproc
--- /dev/null
+
+struct logentry {
+ uint32_t ts; //4
+ enum trans_type tag; //1
+ union { //4
+ struct sale { //4
+ uint8_t user;
+ uint8_t itemid;
+ int16_t amount;
+ };
+
+ struct credit { //3
+ uint8_t user;
+ int16_t amount_cent;
+ };
+ }
+ uint16_t crc; //2
+}
--- /dev/null
+extern uint16_t __fastcall__ crc16_ccitt(uint16_t crc, uint8_t in);
+
--- /dev/null
+use Digest::CRC qw(crcccitt);
+use Data::Dumper;
+
+
+my $data = join("", map {chr $_} (1..16));
+
+printf "%04X\n",crcccitt("$data");
+
--- /dev/null
+
+ .export _crc16_ccitt
+ .importzp tmp1, tmp2, tmp3
+ .import popax
+
+.code
+
+CRCLO := tmp1
+CRCHI := tmp2
+
+;; Ad[ao]pted from http://6502.org/source/integers/crc-more.html (Greg Cook)
+
+;; uint16t __fastcall__ crc16_ccitt(uint16_t crc, uint8_t input)
+.proc _crc16_ccitt
+ STA tmp3
+ JSR popax
+ STA CRCLO
+ STX CRCHI
+ LDA tmp3
+
+ EOR CRCHI ; A contained the data
+ STA CRCHI ; XOR it into high byte
+ LSR ; right shift A 4 bits
+ LSR ; to make top of x^12 term
+ LSR ; ($1...)
+ LSR
+ TAX ; save it
+ ASL ; then make top of x^5 term
+ EOR CRCLO ; and XOR that with low byte
+ STA CRCLO ; and save
+ TXA ; restore partial term
+ EOR CRCHI ; and update high byte
+ STA CRCHI ; and save
+ ASL ; left shift three
+ ASL ; the rest of the terms
+ ASL ; have feedback from x^12
+ TAX ; save bottom of x^12
+ ASL ; left shift two more
+ ASL ; watch the carry flag
+ EOR CRCHI ; bottom of x^5 ($..2.)
+ TAY ; save high byte
+ TXA ; fetch temp value
+ ROL ; bottom of x^12, middle of x^5!
+ EOR CRCLO ; finally update low byte
+ ;STA CRCHI ; then swap high and low bytes
+ ;STY CRCLO
+
+ TAX ; Store result in registers
+ TYA
+
+ RTS
+.endproc
--- /dev/null
+
+#include <conio.h>
+#include <cbm.h>
+#include <stdint.h>
+
+#include "bcd2dec.h"
+#include "crc16.h"
+
+#define BUFSZ 16
+
+uint8_t buffer[BUFSZ] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
+
+int main(void)
+{
+ uint16_t i=0;
+ uint16_t crc=0xFFFF;
+ uint8_t sec, tenth;
+
+ videomode(VIDEOMODE_80x25);
+ fast();
+
+ __asm__("jsr initsystime");
+
+ for(i=0; i<BUFSZ*256; i++)
+ {
+ crc = crc16_ccitt(crc, buffer[i%256]);
+ }
+
+ tenth = CIA1.tod_10;
+ sec = CIA1.tod_sec;
+
+ cprintf("Finished after %d.%d\r\n", bcd2dec(sec), bcd2dec(tenth));
+
+ return 0;
+}
+
--- /dev/null
+
+#include <conio.h>
+#include <cbm.h>
+#include <stdint.h>
+
+#include "bcd2dec.h"
+
+uint8_t buffer[256];
+
+int main(void)
+{
+ int c,i;
+
+ videomode(VIDEOMODE_80x25);
+ fast();
+
+ __asm__("jsr initsystime");
+
+ c = cbm_open((uint8_t)1, (uint8_t)8, (uint8_t)8, "data,s,a");
+ cprintf("[%2d] open\r\n", bcd2dec(CIA1.tod_sec));
+ if(c)
+ {
+ return 1;
+ }
+ for(i=0; i< 32; i++)
+ {
+ c = cbm_write((uint8_t)1, buffer, 256);
+ cprintf("[%2d] write\r\n", bcd2dec(CIA1.tod_sec));
+ if(c != 256)
+ {
+ return 1;
+ }
+ }
+ cbm_close(1);
+ cprintf("[%2d] close\r\n",bcd2dec(CIA1.tod_sec));
+ return 0;
+}