** Heres a little utility that I have just made. ** I thought what I wanted was on a fish disk but that program ** only saved dumps of boot blocks into files that disassemblers can ** read. So I decided to write one myself. Here it is ** The command to use on this is ** FileBootBlock df?: filename ** there must be only one space between the drive specifier of your ** filename will end up starting with spaces ** It will read the blocks 0 and 1 of the drive given and save it as ** a program file that can be run (heaven forbid) or disassembled ** by programs like DIS and DSM ** The only modifying it does is the the first 2 bytes of the block. ** As all program file must start with a valid instruction I have ** changed the first 2 bytes from 'DO' to $600A. This makes it into the ** instruction BRA.S *+$C which will get to the start of the proper code ** Have fun ** John Veldthuis ** 21 Ngatai Street ** Manaia, Taranaki ** New Zealand ** 22 November 1988 ** Placed into the Public domain on this date include "exec/types.i" include "intuition/intuition.i" include "devices/trackdisk.i" include "exec/memory.i" include "libraries/dosextens.i" xref _LVOOpenLibrary xref _LVOCloseLibrary xref _LVODoIO xref _LVOOpenDevice xref _LVOCloseDevice xref _LVOAllocEntry xref _LVOFreeEntry xref _LVOOpen xref _LVOClose xref _LVOWrite xref _LVOAllocSignal xref _LVOFreeSignal Offsets macro \1 equ soffset soffset set soffset+\2 endm soffset set 0 Offsets dosbase,4 Offsets execbase,4 Offsets filehandle,4 Offsets buffer,4 Offsets port,4 Offsets filename,4 Offsets diskreq,4 Offsets task,4 Offsets mementry,4 Offsets unit,4 Offsets stdout,4 Start: lea BASE(pc),a5 move.l 4,a6 move.l a6,execbase(a5) movem.l d0/a0,-(sp) move.l $114(a6),a0 ;find our task move.l a0,task(a5) move.l pr_COS(a0),stdout(a5) ;save output stream for messages moveq.l #33,d0 ;version 33 or greater lea DosLib(pc),a1 jsr _LVOOpenLibrary(a6) ;open dos.library movem.l (sp)+,d1/a0 tst.l d0 bne.s Lib1 NoLib move.l #20,d0 ;no library, indicate error and stop rts Lib1 move.l d0,dosbase(a5) moveq #0,d0 move.b d0,-1(a0,d1.w) ;zero end of Command line 1$ move.b (a0)+,d0 beq CLIErr and.b #%11011111,d0 ;change to uppercase cmp.b #'D',d0 ;look for the D in DF?: bne.s 1$ move.b (a0)+,d0 ;dummy read to skip the F move.b (a0)+,d0 ;get unit number sub.b #'0',d0 ;make into a real number ext.w d0 ;sign extend to a word ext.l d0 ;sign extend to a long move.l d0,unit(a5) ;save unit number 2$ move.b (a0)+,d0 ;search for space cmp.b #' ',d0 bne.s 2$ move.l a0,filename(a5) ;save address of filename lea Mem(pc),a0 jsr _LVOAllocEntry(a6) ;allocate all memory in one go btst #31,d0 bne MemErr ;if bit 31 set then error getting mem move.l d0,mementry(a5) ;save for release move.l d0,a0 add.w #Mem1-Mem,a0 move.l (a0),buffer(a5) ;save address of read/write buffer bsr CreatePort ;create a reply port tst.l d0 beq PError ;no message port move.l d0,d3 move.l d0,port(a5) ;save for closing later move.l mementry(a5),a0 add.w #Mem2-Mem,a0 move.l (a0),a0 ;make an IORequest block move.b #NT_MESSAGE,LN_TYPE(a0) move.w #IOSTD_SIZE,MN_LENGTH(a0) move.l d3,MN_REPLYPORT(a0) move.l a0,diskreq(a5) ;save IO block address move.l unit(a5),d0 lea TrackName(pc),a0 move.l diskreq(a5),a1 moveq.l #0,d1 jsr _LVOOpenDevice(a6) ;open trackdisk on unit tst.l d0 bgt TErr ;won't open, display error move.l diskreq(a5),a1 move.w #CMD_READ,IO_COMMAND(a1) move.l buffer(a5),IO_DATA(a1) move.l #1024,IO_LENGTH(a1) move.l #0,IO_OFFSET(a1) jsr _LVODoIO(a6) ;read boot block into buffer move.l diskreq(a5),a1 move.w #TD_MOTOR,IO_COMMAND(a1) move.l #0,IO_LENGTH(a1) jsr _LVODoIO(a6) ;turn motor off move.l diskreq(a5),a1 move.b IO_ERROR(a1),d3 ;see what error there was jsr _LVOCloseDevice(a6) ;close trackdisk down cmp.b #19,d3 bgt ReadErr ;if an error display error move.l buffer(a5),a0 move.w #$600A,(a0) ;change first to bytes to BRA.S *+$C ;so as not to upset relative addresses move.l dosbase(a5),a6 ;get dosbase move.l filename(a5),d1 move.l #MODE_NEWFILE,d2 jsr _LVOOpen(a6) ;open file that bootblock goes in tst.l d0 beq OpenErr ;didn't open for some reason move.l d0,filehandle(a5) ;save for closing lea table(pc),a0 ;get first part of file move.l a0,d2 ;used to create a program file move.l d0,d1 ;filehandle into d1 moveq #32,d3 ;length of numbers jsr _LVOWrite(a6) cmp.l #32,d0 bne WriteErr move.l buffer(a5),d2 move.l filehandle(a5),d1 move.l #1024,d3 jsr _LVOWrite(a6) ;write out rest of block to file cmp.l #1024,d0 ;see if it all got written out bne WriteErr move.l filehandle(a5),d1 lea hunkend(pc),a0 move.l a0,d2 moveq #4,d3 jsr _LVOWrite(a6) ;write last bit of file cmp.l #4,d0 bne.s WriteErr Fin move.l filehandle(a5),d1 tst.l d1 beq.s 1$ jsr _LVOClose(a6) ;close file if it opened 1$ move.l execbase(a5),a6 move.l port(a5),d0 tst.l d0 beq.s 2$ move.l d0,a1 bsr DeletePort ;delete port if one got made 2$ move.l mementry(a5),d0 tst.l d0 beq.s 3$ move.l d0,a0 jsr _LVOFreeEntry(a6) ;freememory if any got allocated 3$ move.l dosbase(a5),a1 jsr _LVOCloseLibrary(a6) ;close dos.library rts MemErr: lea MemMess(pc),a0 move.l a0,d2 moveq #47,d3 bra.s Err Error: CLIErr: lea CLIMess(pc),a0 move.l a0,d2 moveq #36,d3 bra.s Err ReadErr: lea ReadMess(pc),a0 move.l a0,d2 moveq #36,d3 bra.s Err WriteErr: lea WriteMess(pc),a0 move.l a0,d2 moveq #28,d3 bra.s Err OpenErr: lea OpenMess(pc),a0 move.l a0,d2 moveq #25,d3 bra.s Err PError: lea PMess(pc),a0 move.l a0,d2 moveq #41,d3 bra.s Err TErr lea TMess(pc),a0 move.l a0,d2 moveq #39,d3 Err move.l stdout(a5),d1 tst.l d1 beq Fin ;if no output stream move.l dosbase(a5),a6 jsr _LVOWrite(a6) bra Fin CreatePort: move.l a2,-(a7) move.l mementry(a5),a2 add.w #Mem3-Mem,a2 move.l (a2),a2 moveq #-1,d0 jsr _LVOAllocSignal(a6) moveq #-1,d1 cmp.l d0,d1 ;-1 indicates bad signal bne.s cp_sigok move.l (a7)+,a2 moveq #0,d0 ;otherwise indicate no port rts cp_sigok: move.b d0,MP_SIGBIT(a2) move.b #PA_SIGNAL,MP_FLAGS(a2) move.b #NT_MSGPORT,LN_TYPE(a2) clr.b LN_PRI(a2) move.l task(a5),d0 move.l d0,MP_SIGTASK(a2) lea.l MP_MSGLIST(a2),a0 ;Point to list header NEWLIST a0 ;Init new list macro move.l a2,d0 move.l (a7)+,a2 ;cc's NOT affected rts DeletePort: moveq #-1,d0 move.b d0,LN_TYPE(a1) move.l d0,MP_MSGLIST+LH_HEAD(a1) moveq #0,d0 move.b MP_SIGBIT(a1),d0 jsr _LVOFreeSignal(a6) rts table: dc.l $3f3 ;Hunk_Header dc.l 0 ;no Hunk_Name dc.l 1 ;size of hunk table dc.l 0 ;first hunk dc.l 0 ;last hunk dc.l 256 ;number of longwords in hunk dc.l $3e9 ;Hunk_Code dc.l 256 ;number of longwords in hunk hunkend dc.l $3f2 ;hunk end BASE: Dosbase dc.l 0 Execbase dc.l 0 Filehandle dc.l 0 Buffer dc.l 0 Port dc.l 0 FileName dc.l 0 DiskReq dc.l 0 Task dc.l 0 MemEntry dc.l 0 Unit dc.l 0 Stdout dc.l 0 Mem ds.b LN_SIZE dc.w 3 Mem1 dc.l MEMF_CHIP!MEMF_CLEAR dc.l 1024 Mem2 dc.l MEMF_PUBLIC!MEMF_CLEAR dc.l IOSTD_SIZE Mem3 dc.l MEMF_PUBLIC!MEMF_CLEAR dc.l MP_SIZE DosLib dc.b 'dos.library',0 TrackName dc.b 'trackdisk.device',0 MemMess dc.b 'Not enough Memory to allocate required buffers',10 CLIMess dc.b 'Usage: FileBootBlock df?: filename',10 ReadMess dc.b 'Disk Error while reading Boot Block',10 WriteMess dc.b 'Error while writing to file',10 OpenMess dc.b 'Error while opening file',10 PMess dc.b 'Couldn''t create message port for disk IO',10 TMess dc.b 'Couldn''t get access to specified drive',10 end