First try at using trackdisk.device

This commit is contained in:
alpine9000
2016-02-26 12:27:06 +11:00
commit 3a55b7369c
9 changed files with 639 additions and 0 deletions
+3
View File
@@ -0,0 +1,3 @@
out/
bin/
*~
+34
View File
@@ -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
+6
View File
@@ -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
+30
View File
@@ -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
+120
View File
@@ -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)
+64
View File
@@ -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 <stdio.h>
#include <string.h>
#include <stdint.h>
#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 <image data>\n",argv[0]);
return rc;
}
+316
View File
@@ -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
+37
View File
@@ -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()
+29
View File
@@ -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')