commit 3a55b7369cbbb9cff42c37dd31ab104c39981df4 Author: alpine9000 Date: Fri Feb 26 12:27:06 2016 +1100 First try at using trackdisk.device diff --git a/trackdisk/.gitignore b/trackdisk/.gitignore new file mode 100644 index 0000000..bb875a0 --- /dev/null +++ b/trackdisk/.gitignore @@ -0,0 +1,3 @@ +out/ +bin/ +*~ \ No newline at end of file diff --git a/trackdisk/Makefile b/trackdisk/Makefile new file mode 100644 index 0000000..b858ced --- /dev/null +++ b/trackdisk/Makefile @@ -0,0 +1,34 @@ +MAKEADF=bin/makeadf +FLOPPY=bin/test.adf + +all: bin out $(MAKEADF) $(FLOPPY) + +gdrive: all + cp $(FLOPPY) ~/Google\ Drive + +bin: + mkdir bin + +out: + mkdir out + +$(MAKEADF): makeadf.c + gcc makeadf.c -o $(MAKEADF) + +$(FLOPPY): out/bootblock.bin + $(MAKEADF) out/bootblock.bin > $(FLOPPY) + +out/bootblock.bin: out/bootblock.o + vlink -brawbin1 $< -o $@ + +out/bootblock.o: bootblock.s out/main.bin + vc -c $< -o $@ + +out/main.o: main.s + vc -c $< -o $@ + +out/main.bin: out/main.o + vlink -brawbin1 $< -o $@ + +clean: + rm -rf out bin diff --git a/trackdisk/README.md b/trackdisk/README.md new file mode 100644 index 0000000..491c0ce --- /dev/null +++ b/trackdisk/README.md @@ -0,0 +1,6 @@ +trackdisk.device +================ + +Create a bootable adf file that loads a simple program using trackdisk.device. + +The program has two simple copper lists and switches between them each vertical blank interrupt \ No newline at end of file diff --git a/trackdisk/bootblock.s b/trackdisk/bootblock.s new file mode 100644 index 0000000..16b7349 --- /dev/null +++ b/trackdisk/bootblock.s @@ -0,0 +1,30 @@ + include exec/io.i + include lvo/exec_lib.i + +bootblock: + dc.b "DOS",0 + dc.l 0 + dc.l 880 + +bootEntry: + ;; a6 = Exec base + ;; a1 = trackdisk.device I/O request pointer + + lea $70000,a5 ; main.s entry point + + ;; Load the progam from the floppy using trackdisk.device + move.l #mainEnd-mainStart,IO_LENGTH(a1) + move.l a5,IO_DATA(a1) + move.l #mainStart-bootblock,IO_OFFSET(a1) + jsr _LVODoIO(a6) + + jmp (a5) ; -> main.s entry point + + ;; Pad the remainder of the bootblock + cnop 0,1024 + +mainStart: + incbin "out/main.bin" + cnop 0,512 +mainEnd: + end \ No newline at end of file diff --git a/trackdisk/main.s b/trackdisk/main.s new file mode 100644 index 0000000..27a9b9c --- /dev/null +++ b/trackdisk/main.s @@ -0,0 +1,120 @@ + include registers.i + include hardware/dmabits.i + include hardware/intbits.i + +LEVEL_3_INTERRUPT_VECTOR equ $6c + +entry: + lea level3InterruptHandler(pc),a3 + move.l a3,LEVEL_3_INTERRUPT_VECTOR + + lea CUSTOM,a1 + lea copper1(pc),a0 + move.l a0,cop1lc(a1) + move.w COPJMP1(a1),d0 + move.w #(DMAF_SETCLR!DMAF_COPPER!DMAF_RASTER!DMAF_MASTER),dmacon(a1) + +.mainLoop: + bra.b .mainLoop + +level3InterruptHandler: + movem.l d0-a6,-(sp) + +.checkVerticalBlank: + lea CUSTOM,a5 + move.w INTREQR(a5),d0 + and.w #INTF_VERTB,d0 + beq.s .checkCopper + +.verticalBlank: + move.w #INTF_VERTB,INTREQ(a5) ; Clear interrupt bit + lea.l CUSTOM,a5 + lea.l counter(pc),a3 + move.l (a3),d1 + cmpi.l #1,d1 + beq.s .installCopper2 +.installCopper1: + lea copper1(pc),a0 + addi.l #1,d1 + bra.s .loadCopper +.installCopper2: + lea copper2(pc),a0 + move.l #0,d1 +.loadCopper: + move.l a0,COP1LC(a5) + move.l d1,(a3) + +.checkCopper: + lea CUSTOM,a5 + move.w INTREQR(a5),d0 + and.w #INTF_COPER,d0 + beq.s .interruptComplete +.copperInterrupt: + move.w #INTF_COPER,INTREQ(a5) ; Clear interrupt bit + +.interruptComplete: + movem.l (sp)+,d0-a6 + rte + +counter: + dc.l 0 + +copper1: + ;; + ;; Set up pointers to two bitplanes + ;; + DC.W BPL1PTH,$0002 ;Move $0002 into register $0E0 (BPL1PTH) + DC.W BPL1PTL,$1000 ;Move $1000 into register $0E2 (BPL1PTL) + DC.W BPL2PTH,$0002 ;Move $0002 into register $0E4 (BPL2PTH) + DC.W BPL2PTL,$5000 ;Move $5000 into register $0E6 (BPL2PTL) + ;; + ;; Load color registers + ;; + DC.W COLOR00,$0FFF ;Move white into register $180 (COLOR00) + DC.W COLOR01,$0F00 ;Move red into register $182 (COLOR01) + DC.W COLOR02,$00F0 ;Move green into register $184 (COLOR02) + DC.W COLOR03,$000F ;Move blue into register $186 (COLOR03) + ;; + ;; Specify 2 Lores bitplanes + ;; + DC.W BPLCON0,$2200 ;2 lores planes, coloron + ;; + ;; Wait for line 150 + ;; + DC.W $9601,$FF00 ;Wait for line 150, ignore horiz. position + ;; + ;; Change color registers mid-display + ;; + DC.W COLOR00,$0000 ;Move black into register $0180 (COLOR00) + DC.W COLOR01,$0FF0 ;Move yellow into register $0182 (COLOR01) + DC.W COLOR02,$00FF ;Move cyan into register $0184 (COLOR02) + DC.W COLOR03,$0F0F ;Move magenta into register $0186 (COLOR03) + ;; + ;; End Copper list by waiting for the impossible + ;; + DC.W $FFFF,$FFFE ;Wait for line 255, H = 254 (never happens) + + +copper2: + ;; + ;; Set up pointers to two bitplanes + ;; + DC.W BPL1PTH,$0002 ;Move $0002 into register $0E0 (BPL1PTH) + DC.W BPL1PTL,$1000 ;Move $1000 into register $0E2 (BPL1PTL) + DC.W BPL2PTH,$0002 ;Move $0002 into register $0E4 (BPL2PTH) + DC.W BPL2PTL,$5000 ;Move $5000 into register $0E6 (BPL2PTL) + ;; + ;; Load color registers + ;; + DC.W COLOR00,$0F00 ;Move red imto register $180 (COLOR00) + DC.W COLOR01,$0FFF ;Move white into register $182 (COLOR01) + DC.W COLOR02,$00F0 ;Move green into register $184 (COLOR02) + DC.W COLOR03,$000F ;Move blue into register $186 (COLOR03) + ;; + ;; Specify 2 Lores bitplanes + ;; + DC.W BPLCON0,$2200 ;2 lores planes, coloron + ;; + ;; End Copper list by waiting for the impossible + ;; + DC.W $FFFF,$FFFE ;Wait for line 255, H = 254 (never happens) \ No newline at end of file diff --git a/trackdisk/makeadf.c b/trackdisk/makeadf.c new file mode 100644 index 0000000..52d151c --- /dev/null +++ b/trackdisk/makeadf.c @@ -0,0 +1,64 @@ +/* + * http://eab.abime.net/showpost.php?p=895070&postcount=6 + * Makes a disk image of 901120 (0xdc000) bytes. + * Calculates boot block checksum. + */ + +#include +#include +#include + +#define DISKSIZE (0xdc000) + +uint8_t image[DISKSIZE]; + + +static void boot_chksum(uint8_t *p) +{ + uint32_t oldchk,chk=0; + int i; + + memset(p+4,0,4); + for (i=0; i<1024; i+=4) { + oldchk = chk; + chk += ((uint32_t)p[i+0] << 24) | ((uint32_t)p[i+1] << 16) | + ((uint32_t)p[i+2] << 8) | p[i+3]; + if (chk < oldchk) + ++chk; /* carry */ + } + + chk = ~chk; + p[4] = (uint8_t)((chk >> 24) & 0xff); + p[5] = (uint8_t)((chk >> 16) & 0xff); + p[6] = (uint8_t)((chk >> 8) & 0xff); + p[7] = (uint8_t)(chk & 0xff); +} + + +int main(int argc,char *argv[]) +{ + FILE *f; + int rc = 1; + size_t len; + + if (argc == 2) { + if (f = fopen(argv[1],"rb")) { + len = fread(image,1,DISKSIZE,f); + if (len > 0) { + if (len < DISKSIZE) + memset(image+len,0,DISKSIZE-len); + boot_chksum(image); + fwrite(image,1,DISKSIZE,stdout); + rc = 0; + } + else + fprintf(stderr,"Image read error!\n"); + } + else + fprintf(stderr,"Cannot open '%s'!\n",argv[0]); + } + else + fprintf(stderr,"Usage: %s \n",argv[0]); + + return rc; +} diff --git a/trackdisk/registers.i b/trackdisk/registers.i new file mode 100644 index 0000000..7d3e8e8 --- /dev/null +++ b/trackdisk/registers.i @@ -0,0 +1,316 @@ +; +; hw_examples.i +; +; This appendix contains an include file that maps the hardware +; register names, given in Appendix A and Appendix B, to names that can +; be resolved by the standard include files. Use of these names in code +; sections of this manual places the emphasis on what the code is +; doing, rather than getting bogged down in include file names. +; +; All code examples in this manual reference the names given in this +; file. +; + IFND HARDWARE_HW_EXAMPLES_I +HARDWARE_HW_EXAMPLES_I SET 1 +** +** Filename: hardware/hw_examples.i +** $Release: 1.3 $ +** +** (C) Copyright 1985-1999 Amiga, Inc. +** All Rights Reserved +** +******************************************************************************* + + IFND HARDWARE_CUSTOM_I + INCLUDE "hardware/custom.i" + ENDC + +******************************************************************************* +* +* This include file is designed to be used in conjunction with the hardware +* manual examples. This file defines the register names based on the +* hardware/custom.i definition file. There is no C-Language version of this +* file. +* +******************************************************************************* +* +* This instruction for the copper will cause it to wait forever since +* the wait command described in it will never happen. +* +COPPER_HALT equ $FFFFFFFE +* +******************************************************************************* +* +* This is the offset in the 680x0 address space to the custom chip registers +* It is the same as _custom when linking with AMIGA.lib +* +CUSTOM equ $DFF000 +* +* Various control registers +* +DMACONR equ dmaconr ; Just capitalization... +VPOSR equ vposr ; " " +VHPOSR equ vhposr ; " " +JOY0DAT equ joy0dat ; " " +JOY1DAT equ joy1dat ; " " +CLXDAT equ clxdat ; " " +ADKCONR equ adkconr ; " " +POT0DAT equ pot0dat ; " " +POT1DAT equ pot1dat ; " " +POTINP equ potinp ; " " +SERDATR equ serdatr ; " " +INTENAR equ intenar ; " " +INTREQR equ intreqr ; " " +REFPTR equ refptr ; " " +VPOSW equ vposw ; " " +VHPOSW equ vhposw ; " " +SERDAT equ serdat ; " " +SERPER equ serper ; " " +POTGO equ potgo ; " " +JOYTEST equ joytest ; " " +STREQU equ strequ ; " " +STRVBL equ strvbl ; " " +STRHOR equ strhor ; " " +STRLONG equ strlong ; " " +DIWSTRT equ diwstrt ; " " +DIWSTOP equ diwstop ; " " +DDFSTRT equ ddfstrt ; " " +DDFSTOP equ ddfstop ; " " +DMACON equ dmacon ; " " +INTENA equ intena ; " " +INTREQ equ intreq ; " " +* +* Disk control registers +* +DSKBYTR equ dskbytr ; Just capitalization... +DSKPT equ dskpt ; " " +DSKPTH equ dskpt +DSKPTL equ dskpt+$02 +DSKLEN equ dsklen ; " " +DSKDAT equ dskdat ; " " +DSKSYNC equ dsksync ; " " +* +* Blitter registers +* +BLTCON0 equ bltcon0 ; Just capitalization... +BLTCON1 equ bltcon1 ; " " +BLTAFWM equ bltafwm ; " " +BLTALWM equ bltalwm ; " " +BLTCPT equ bltcpt ; " " +BLTCPTH equ bltcpt +BLTCPTL equ bltcpt+$02 +BLTBPT equ bltbpt ; " " +BLTBPTH equ bltbpt +BLTBPTL equ bltbpt+$02 +BLTAPT equ bltapt ; " " +BLTAPTH equ bltapt +BLTAPTL equ bltapt+$02 +BLTDPT equ bltdpt ; " " +BLTDPTH equ bltdpt +BLTDPTL equ bltdpt+$02 +BLTSIZE equ bltsize ; " " +BLTCMOD equ bltcmod ; " " +BLTBMOD equ bltbmod ; " " +BLTAMOD equ bltamod ; " " +BLTDMOD equ bltdmod ; " " +BLTCDAT equ bltcdat ; " " +BLTBDAT equ bltbdat ; " " +BLTADAT equ bltadat ; " " +BLTDDAT equ bltddat ; " " +* +* Copper control registers +* +COPCON equ copcon ; Just capitalization... +COPINS equ copins ; " " +COPJMP1 equ copjmp1 ; " " +COPJMP2 equ copjmp2 ; " " +COP1LC equ cop1lc ; " " +COP1LCH equ cop1lc +COP1LCL equ cop1lc+$02 +COP2LC equ cop2lc ; " " +COP2LCH equ cop2lc +COP2LCL equ cop2lc+$02 +* +* +* Audio channel registers +* +ADKCON equ adkcon ; Just capitalization... + +AUD0LC equ aud0 +AUD0LCH equ aud0 +AUD0LCL equ aud0+$02 +AUD0LEN equ aud0+$04 +AUD0PER equ aud0+$06 +AUD0VOL equ aud0+$08 +AUD0DAT equ aud0+$0A + +AUD1LC equ aud1 +AUD1LCH equ aud1 +AUD1LCL equ aud1+$02 +AUD1LEN equ aud1+$04 +AUD1PER equ aud1+$06 +AUD1VOL equ aud1+$08 +AUD1DAT equ aud1+$0A + +AUD2LC equ aud2 +AUD2LCH equ aud2 +AUD2LCL equ aud2+$02 +AUD2LEN equ aud2+$04 +AUD2PER equ aud2+$06 +AUD2VOL equ aud2+$08 +AUD2DAT equ aud2+$0A + +AUD3LC equ aud3 +AUD3LCH equ aud3 +AUD3LCL equ aud3+$02 +AUD3LEN equ aud3+$04 +AUD3PER equ aud3+$06 +AUD3VOL equ aud3+$08 +AUD3DAT equ aud3+$0A +* +* +* The bitplane registers +* +BPL1PT equ bplpt+$00 +BPL1PTH equ bplpt+$00 +BPL1PTL equ bplpt+$02 +BPL2PT equ bplpt+$04 +BPL2PTH equ bplpt+$04 +BPL2PTL equ bplpt+$06 +BPL3PT equ bplpt+$08 +BPL3PTH equ bplpt+$08 +BPL3PTL equ bplpt+$0A +BPL4PT equ bplpt+$0C +BPL4PTH equ bplpt+$0C +BPL4PTL equ bplpt+$0E +BPL5PT equ bplpt+$10 +BPL5PTH equ bplpt+$10 +BPL5PTL equ bplpt+$12 +BPL6PT equ bplpt+$14 +BPL6PTH equ bplpt+$14 +BPL6PTL equ bplpt+$16 + +BPLCON0 equ bplcon0 ; Just capitalization... +BPLCON1 equ bplcon1 ; " " +BPLCON2 equ bplcon2 ; " " +BPL1MOD equ bpl1mod ; " " +BPL2MOD equ bpl2mod ; " " + +DPL1DATA equ bpldat+$00 +DPL2DATA equ bpldat+$02 +DPL3DATA equ bpldat+$04 +DPL4DATA equ bpldat+$06 +DPL5DATA equ bpldat+$08 +DPL6DATA equ bpldat+$0A +* +* +* Sprite control registers +* +SPR0PT equ sprpt+$00 +SPR0PTH equ SPR0PT+$00 +SPR0PTL equ SPR0PT+$02 +SPR1PT equ sprpt+$04 +SPR1PTH equ SPR1PT+$00 +SPR1PTL equ SPR1PT+$02 +SPR2PT equ sprpt+$08 +SPR2PTH equ SPR2PT+$00 +SPR2PTL equ SPR2PT+$02 +SPR3PT equ sprpt+$0C +SPR3PTH equ SPR3PT+$00 +SPR3PTL equ SPR3PT+$02 +SPR4PT equ sprpt+$10 +SPR4PTH equ SPR4PT+$00 +SPR4PTL equ SPR4PT+$02 +SPR5PT equ sprpt+$14 +SPR5PTH equ SPR5PT+$00 +SPR5PTL equ SPR5PT+$02 +SPR6PT equ sprpt+$18 +SPR6PTH equ SPR6PT+$00 +SPR6PTL equ SPR6PT+$02 +SPR7PT equ sprpt+$1C +SPR7PTH equ SPR7PT+$00 +SPR7PTL equ SPR7PT+$02 +; +; Note: SPRxDATB is defined as being +$06 from SPRxPOS. +; sd_datab should be defined as $06, however, in the 1.3 assembler +; include file hardware/custom.i it is incorrectly defined as $08. +; +SPR0POS equ spr+$00 +SPR0CTL equ SPR0POS+sd_ctl +SPR0DATA equ SPR0POS+sd_dataa +SPR0DATB equ SPR0POS+$06 ; should use sd_datab ... + +SPR1POS equ spr+$08 +SPR1CTL equ SPR1POS+sd_ctl +SPR1DATA equ SPR1POS+sd_dataa +SPR1DATB equ SPR1POS+$06 ; should use sd_datab ... + +SPR2POS equ spr+$10 +SPR2CTL equ SPR2POS+sd_ctl +SPR2DATA equ SPR2POS+sd_dataa +SPR2DATB equ SPR2POS+$06 ; should use sd_datab ... + +SPR3POS equ spr+$18 +SPR3CTL equ SPR3POS+sd_ctl +SPR3DATA equ SPR3POS+sd_dataa +SPR3DATB equ SPR3POS+$06 ; should use sd_datab ... + +SPR4POS equ spr+$20 +SPR4CTL equ SPR4POS+sd_ctl +SPR4DATA equ SPR4POS+sd_dataa +SPR4DATB equ SPR4POS+$06 ; should use sd_datab ... + +SPR5POS equ spr+$28 +SPR5CTL equ SPR5POS+sd_ctl +SPR5DATA equ SPR5POS+sd_dataa +SPR5DATB equ SPR5POS+$06 ; should use sd_datab ... + +SPR6POS equ spr+$30 +SPR6CTL equ SPR6POS+sd_ctl +SPR6DATA equ SPR6POS+sd_dataa +SPR6DATB equ SPR6POS+$06 ; should use sd_datab ... + +SPR7POS equ spr+$38 +SPR7CTL equ SPR7POS+sd_ctl +SPR7DATA equ SPR7POS+sd_dataa +SPR7DATB equ SPR7POS+$06 ; should use sd_datab ... +* +* Color registers... +* +COLOR00 equ color+$00 +COLOR01 equ color+$02 +COLOR02 equ color+$04 +COLOR03 equ color+$06 +COLOR04 equ color+$08 +COLOR05 equ color+$0A +COLOR06 equ color+$0C +COLOR07 equ color+$0E +COLOR08 equ color+$10 +COLOR09 equ color+$12 +COLOR10 equ color+$14 +COLOR11 equ color+$16 +COLOR12 equ color+$18 +COLOR13 equ color+$1A +COLOR14 equ color+$1C +COLOR15 equ color+$1E +COLOR16 equ color+$20 +COLOR17 equ color+$22 +COLOR18 equ color+$24 +COLOR19 equ color+$26 +COLOR20 equ color+$28 +COLOR21 equ color+$2A +COLOR22 equ color+$2C +COLOR23 equ color+$2E +COLOR24 equ color+$30 +COLOR25 equ color+$32 +COLOR26 equ color+$34 +COLOR27 equ color+$36 +COLOR28 equ color+$38 +COLOR29 equ color+$3A +COLOR30 equ color+$3C +COLOR31 equ color+$3E + +******************************************************************************* +** +** + ENDC ; HARDWARE_HW_EXAMPLES_I \ No newline at end of file diff --git a/trackdisk/tools/make-adf.py b/trackdisk/tools/make-adf.py new file mode 100755 index 0000000..314fd92 --- /dev/null +++ b/trackdisk/tools/make-adf.py @@ -0,0 +1,37 @@ +#! /usr/bin/env python + +DISKSIZE = 512 * 11 * 2 * 80 + +def concat(out, fn): + f = open(fn, 'rb') + d = f.read() + f.close() + if len(d) % 512 != 0: + d = d + '\0' * (512-(len(d)%512)) + print('placing %s (%d bytes, %d secs) at pos %d (sector %d)' % (fn, len(d), len(d)/512, out.tell(), out.tell()/512)) + out.write(d) + +if __name__ == '__main__': + + import sys + + output = sys.argv[1] + bootblock = sys.argv[2] + files = sys.argv[3:] + + out = open(output, 'wb') + concat(out, bootblock) + + for f in files: + concat(out,f) + + diff = DISKSIZE - out.tell() + + if diff < 0: + sys.stderr.write('too big! %d bytes over budget' % (diff)) + sys.exit(1) + + out.write('\0' * diff) + + out.close() + diff --git a/trackdisk/tools/sum-bootblock.py b/trackdisk/tools/sum-bootblock.py new file mode 100755 index 0000000..65a4433 --- /dev/null +++ b/trackdisk/tools/sum-bootblock.py @@ -0,0 +1,29 @@ +#! /usr/bin/env python + +import sys +import struct + +def splice_checksum(block, chksum): + return block[0:4] + struct.pack('>I', chksum) + block[8:] + +def makeit(fn, ofn): + with open(fn, 'rb') as f: data = f.read() + + data = data + '\0' * (1024 - len(data)) + + chksum = 0 + for w in xrange(0, 1024, 4): + chksum += struct.unpack('>I', data[w:w+4])[0] + if chksum > 0xffffffff: + chksum = (chksum + 1) & 0xffffffff + + chksum = (~chksum) & 0xffffffff + + data2 = splice_checksum(data, chksum) + + with open(ofn, 'wb') as f: f.write(data2) + +if len(sys.argv) == 3: + makeit(sys.argv[1], sys.argv[2]) +else: + sys.stderr.write('need two args\n')