home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
AmigActive 13
/
AACD13.ISO
/
AACD
/
Games
/
WHDLoad
/
Extra
/
wwarp.lha
/
wwarp
/
src
/
WWarp.asm
< prev
Wrap
Assembly Source File
|
2000-08-06
|
53KB
|
2,525 lines
;*---------------------------------------------------------------------------
; :Program. WWarp.asm
; :Contents. Disk-Warper
; :Author. Bert Jahn
; :EMail. wepl@whdload.org
; :Address. Franz-Liszt-Straße 16, Rudolstadt, 07404, Germany
; :Version $Id: WWarp.asm 1.20 2000/08/06 13:13:01 jah Exp jah $
; :History. 29.08.98 started
; 20.09.98 reading of std tracks added, and major rework
; 22.09.98 tracksize calculation added
; 08.10.98 def-tracklen changed from $7c00 to $6c00 (harry)
; 07.11.99 major rework started
; 24.12.99 varios stuff enhanced
; 28.05.00 gremlin format added, movehead fixed
; 21.06.00 writing std/gremlin added
; 28.06.00 remove fixed, _cmdwork improved
; 06.08.00 FORCE now skips all tracks which cannot be decoded
; :Requires. OS V37+, MC68020+
; :Copyright. ©1998-2000 Bert Jahn, All Rights Reserved
; :Language. 68020 Assembler
; :Translator. Barfly V2.9
; :To Do.
;---------------------------------------------------------------------------*
;##########################################################################
INCDIR Includes:
INCLUDE lvo/exec.i
INCLUDE exec/execbase.i
INCLUDE exec/io.i
INCLUDE exec/memory.i
INCLUDE lvo/dos.i
INCLUDE dos/datetime.i
INCLUDE dos/dos.i
INCLUDE devices/trackdisk.i
INCLUDE macros/ntypes.i
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
DEFTRACKS = 160 ;default amount tracks to process
MAXTRACKS = 160 ;amount tracks which can be procecced (currently)
;length for mfm raw reads
MINTRACKLEN = $3000 ;minimal track length (limited physical)
DEFTRACKLEN = $6c00 ;default track length
MAXTRACKLEN = $7ffe ;maximal track length (limited by trackdisk.device)
DEFREADRETRY = 6
FILEID = "WWRP"
FILEVER = 1
CREATORLEN = 42
STRUCTURE WWarpFileHeader,0
ULONG wfh_id ;FILEID
UWORD wfh_ver ;structure format version
STRUCT wfh_creator,CREATORLEN ;creator of wwarp file
STRUCT wfh_ctime,ds_SIZEOF ;date of creation
STRUCT wfh_mtime,ds_SIZEOF ;date of last modification
LABEL wfh_SIZEOF
TABLEID = "TABL"
TABLEVER = 1
STRUCTURE WWarpTrackTable,0
ULONG wtt_id ;TABLEID
UWORD wtt_ver ;structure format version
UWORD wtt_first ;first track in list
UWORD wtt_last ;last track in list
LABEL wtt_tab ;track table, one bit for each track
TRACKID = "TRCK"
TRACKVER = 1
SYNCLEN = 16
STRUCTURE WWarpTrackHeader,0
ULONG wth_id ;TRACKID
UWORD wth_ver ;structure format version
UWORD wth_num ;track number
UWORD wth_type ;track data format type
UWORD wth_flags ;flags
ULONG wth_len ;length of data contained in wwp in bits!
ULONG wth_wlen ;lengtn of data to write back in bytes!
STRUCT wth_sync,SYNCLEN ;sync
STRUCT wth_mask,SYNCLEN ;sync mask (used bits in wth_sync)
LABEL wth_data ;track data
;track types
ENUM 0
EITEM TT_RAW ;raw mfm data
EITEM TT_STD ;standard dos format ($1600 bytes)
EITEM TT_GREM ;gremlin format ($1800 bytes)
;track flags
BITDEF TF,INDEX,0 ;track data starts with index signal (only TT_RAW)
BITDEF TF,BZIP2,1 ;copressed wih bzip2
BITDEF TF,RAWSINGLE,2 ;raw mfm data is saved in exact bit length
BITDEF TF,LEQ,3 ;all longs equal
BITDEF TF,SLINC,4 ;sector longs incremented
FILENAMELEN = 1024
STRUCTURE Globals,0
APTR gl_execbase
APTR gl_dosbase
APTR gl_rdargs
LABEL gl_rdarray
ULONG gl_rd_file ;name of the wwarp file
ULONG gl_rd_cmd ;operation to perform
ULONG gl_rd_tracks ;affected tracks
ULONG gl_rd_arg ;further argument depending on operation
ULONG gl_rd_bpt ;bytes per track
ULONG gl_rd_unit ;drive unit
ULONG gl_rd_nostd ;dont try to read std format
ULONG gl_rd_retry ;how many read retries
ULONG gl_rc ;programs return code
APTR gl_chipbuf
APTR gl_fastbuf
ALIGNLONG
STRUCT gl_DateTime,dat_SIZEOF
STRUCT gl_date,LEN_DATSTRING
STRUCT gl_time,LEN_DATSTRING
STRUCT gl_headin,wfh_SIZEOF ;file header input
STRUCT gl_headout,wfh_SIZEOF ;file header output
STRUCT gl_tabarg,wtt_tab+MAXTRACKS/8 ;tracks specified via command line
;default = argument || tabin
STRUCT gl_tabin,wtt_tab+MAXTRACKS/8 ;tracks contained in input file
STRUCT gl_tabread,wtt_tab+MAXTRACKS/8 ;tracks to read from the input file
;default = 0
STRUCT gl_tabout,wtt_tab+MAXTRACKS/8 ;tracks to write to the output file
;default = tabin
STRUCT gl_tabdo,wtt_tab+MAXTRACKS/8 ;tracks on which user func will called
;default = tabarg
STRUCT gl_trk,wth_data
STRUCT gl_filename,FILENAMELEN
STRUCT gl_filename2,FILENAMELEN
STRUCT gl_io,8 ;normal iorequest,msgport
STRUCT gl_ioi,8 ;indexsync iorequest,msgport
STRUCT gl_sync,SYNCLEN*2
STRUCT gl_tmpbuf,$1800
BYTE gl_break
ALIGNLONG
LABEL gl_SIZEOF
;##########################################################################
GL EQUR A4 ;a4 ptr to Globals
LOC EQUR A5 ;a5 for local vars
CPU = 68020
OUTPUT C:WWarp
BOPT O+ ;enable optimizing
;BOPT OG+ ;enable optimizing
BOPT ODd- ;disable mul optimizing
BOPT ODe- ;disable mul optimizing
BOPT wo- ;no optimize warnings
IFND .passchk
DOSCMD "WBuild >T:build"
DOSCMD "WDate >T:date"
.passchk
ENDC
Version = 1
Revision = 6
SECTION a,CODE
bra _Start
dc.b "$VER: "
_txt_creator sprintx "WWarp %ld.%ld [build ",Version,Revision
INCBIN "T:build"
dc.b "] "
INCBIN "T:date"
dc.b 0
dc.b "$Id: WWarp.asm 1.20 2000/08/06 13:13:01 jah Exp jah $",0
EVEN
;##########################################################################
INCDIR Sources:
INCLUDE dosio.i
PrintLn
PrintArgs
CheckBreak
FlushOutput
GetKey
INCLUDE strings.i
atoi
etoi
AppendString
StrNCaseCmp
CopyString
StrLen
INCLUDE error.i
PrintErrorDOS
PrintErrorTD
;##########################################################################
_StartErr moveq #33,d0 ;kick 1.2
lea (_dosname),a1
jsr (_LVOOpenLibrary,a6)
tst.l d0
beq .q
move.l d0,a6
jsr (_LVOOutput,a6)
move.l d0,d1 ;file handle
move.l (a7)+,d2
move.l d2,a0
moveq #-1,d3
.c addq.l #1,d3
tst.b (a0)+
bne .c
jsr (_LVOWrite,a6)
move.l a6,a1
move.l (gl_execbase,GL),a6
jsr (_LVOCloseLibrary,a6)
.q move.l (gl_rc,GL),d0
rts
;program start
_Start lea (_Globals),GL
move.l #RETURN_FAIL,(gl_rc,GL)
move.l (4).w,a6
move.l a6,(gl_execbase,GL)
;check cpu
btst #AFB_68020,(AttnFlags+1,a6)
bne .cpuok
pea (_badcpu)
bra _StartErr
.cpuok
MC68020
;open dos.library
move.l #37,d0
lea (_dosname),a1
move.l (gl_execbase,GL),a6
jsr _LVOOpenLibrary(a6)
move.l d0,(gl_dosbase,GL)
bne .dosok
pea (_badkick)
bra _StartErr
.dosok
;read arguments
lea (_template),a0
move.l a0,d1
lea (gl_rdarray,GL),a0
move.l a0,d2
moveq #0,d3
move.l (gl_dosbase,GL),a6
jsr (_LVOReadArgs,a6)
move.l d0,(gl_rdargs,GL)
bne .argsok
lea (_readargs),a0
bsr _PrintErrorDOS
bsr _help
bra .noargs
.argsok
;check filename
move.l (gl_rd_file,GL),a0
lea (gl_filename,GL),a1
move.l #FILENAMELEN,d0
bsr _CopyString
lea (gl_filename,GL),a0
bsr _StrLen
cmp.l #4,d0
bls .cs_1
lea (gl_filename-4.w,GL,d0.l),a0
lea (_extension),a1
moveq #4,d0
bsr _StrNCaseCmp
tst.l d0
beq .cs_end
.cs_1 lea (gl_filename,GL),a0
move.l a0,d1
move.l #ACCESS_READ,d2
move.l (gl_dosbase,GL),a6
jsr (_LVOLock,a6)
move.l d0,d1
beq .cs_2
jsr (_LVOUnLock,a6)
bra .cs_end
.cs_2 lea (_extension),a0
lea (gl_filename,GL),a1
move.l #FILENAMELEN,d0
bsr _AppendString
.cs_end
;parse tracks
move #0,(gl_tabarg+wtt_first,GL)
move #MAXTRACKS-1,(gl_tabarg+wtt_last,GL)
move.l (gl_rd_tracks,GL),a0
move.l a0,d0
beq .pt_def
cmp.w #"*"<<8,(a0)
bne .pt_loop
clr.l (gl_rd_tracks,GL)
.pt_def move.l #DEFTRACKS-1,d0
.pt_1 bfset (gl_tabarg+wtt_tab,GL){d0:1}
dbf d0,.pt_1
bra .pt_end
.pt_loop bsr .pt_getnum
move.b (a0)+,d1
beq .pt_single
cmp.b #",",d1
beq .pt_single
cmp.b #"-",d1
beq .pt_area
cmp.b #"*",d1
beq .pt_step
bra .pt_err
.pt_single bfset (gl_tabarg+wtt_tab,GL){d0:1}
.pt_check tst.b d1
beq .pt_end
cmp.b #",",d1
beq .pt_loop
bra .pt_err
.pt_step move.l d0,d2 ;D2 = start
move.l #DEFTRACKS-1,d3 ;D3 = last
.pt_step0 bsr .pt_getnum ;D0 = skip
tst.l d0
ble .pt_err
.pt_step1 cmp.l d2,d3
blo .pt_err
.pt_step_l bfset (gl_tabarg+wtt_tab,GL){d2:1}
add.l d0,d2
cmp.l d2,d3
bhs .pt_step_l
move.b (a0)+,d1
bra .pt_check
.pt_area move.l d0,d2 ;D2 = start
bsr .pt_getnum
move.l d0,d3 ;D3 = last
moveq #1,d0 ;D0 = skip
cmp.b #"*",(a0)
bne .pt_step1
addq.l #1,a0
bra .pt_step0
.pt_getnum move.l (a7)+,a1
move.l a0,a3
bsr _atoi
cmp.l a0,a3
beq .pt_err
cmp.l #MAXTRACKS,d0
bhs .pt_err
jmp (a1)
.pt_err lea (_txt_badtracks),a0
bsr _PrintBold
bsr _help
bra .badargs
.pt_end
move.l #MAXTRACKLEN,d2 ;D2 = maximal rawreadlen
move.l #DEFTRACKLEN,d0 ;default tracklength
move.l (gl_rd_bpt,GL),d1
beq .bptok
move.l d1,a0
bsr _atoi
addq.l #1,d0
bclr #0,d0 ;word aligned
cmp.l d2,d0
blt .bptok
move.l d2,d0
.bptok move.l d0,(gl_rd_bpt,GL)
move.l (gl_rd_unit,GL),d0
beq .unitok
move.l d0,a0
move.l (a0),d0
.unitok move.l d0,(gl_rd_unit,GL)
move.l #DEFREADRETRY,d1
move.l (gl_rd_retry,GL),d0
beq .retryok
move.l d0,a0
move.l (a0),d1
.retryok move.l d1,(gl_rd_retry,GL)
;init globals
lea (_chipbuf),a0
move.l a0,(gl_chipbuf,GL)
move.l #MAXTRACKLEN,d0
move.l #MEMF_FAST,d1
move.l (gl_execbase,GL),a6
jsr (_LVOAllocVec,a6)
move.l d0,(gl_fastbuf,GL)
bne .memok
move.l (gl_chipbuf,GL),(gl_fastbuf,GL)
.memok
pea (.return)
move.l (gl_rd_cmd,GL),d0
beq _cmd_create
move.l d0,a0
move.b (a0)+,d0
tst.b (a0)
bne _cmd_bad
UPPER d0
cmp.b #"C",d0
beq _cmd_create
cmp.b #"D",d0
beq _cmd_dump
cmp.b #"F",d0
beq _cmd_force
cmp.b #"I",d0
beq _cmd_info
cmp.b #"L",d0
beq _cmd_length
cmp.b #"M",d0
beq _cmd_merge
cmp.b #"P",d0
beq _cmd_pack
cmp.b #"R",d0
beq _cmd_remove
cmp.b #"S",d0
beq _cmd_save
cmp.b #"Y",d0
beq _cmd_sync
cmp.b #"W",d0
beq _cmd_write
bra _cmd_bad
.return
;free globals
move.l (gl_fastbuf,GL),a1
cmp.l (gl_chipbuf,GL),a1
beq .fgle
move.l (gl_execbase,GL),a6
jsr (_LVOFreeVec,a6)
.fgle
.badargs
move.l (gl_rdargs,GL),d1
move.l (gl_dosbase,GL),a6
jsr (_LVOFreeArgs,a6)
.noargs
move.l (gl_dosbase,GL),a1
move.l (gl_execbase,GL),a6
jsr (_LVOCloseLibrary,a6)
.nodoslib
move.l (gl_rc,GL),d7
_rts rts
;##########################################################################
_cmd_bad lea (_txt_badcmd),a0
bsr _PrintBold
_help lea (_txt_help),a0
bra _Print
;##########################################################################
;##########################################################################
INCLUDE cmdc.s
;##########################################################################
;##########################################################################
_cmd_dump moveq #0,d4 ;D4 = sync specified
moveq #1,d5 ;D5 = sync num
moveq #0,d6 ;D6 = length
moveq #0,d7 ;D7 = offset
;parse argument
move.l (gl_rd_arg,GL),d0
beq .argend
move.l d0,a2 ;A2 = arg
;sync
cmp.b #",",(a2)
beq .send
move.l a2,a0
.sl move.b (a0)+,d0
beq .se
cmp.b #",",d0
bne .sl
.se move.b -(a0),d2
clr.b (a0)
exg.l a0,a2
bsr _parsesync
tst.l d0
beq _rts
moveq #-1,d4
move.b d2,(a2)
;sync num
.send cmp.b #",",(a2)+
bne .arglast
cmp.b #",",(a2)
beq .snend
move.l a2,a0
bsr _atoi
cmp.l a0,a2
beq .argerr
move.l a0,a2
move.l d0,d5
ble .argerr
;length
.snend cmp.b #",",(a2)+
bne .arglast
cmp.b #",",(a2)
beq .lend
move.l a2,a0
bsr _etoi
cmp.l a0,a2
beq .argerr
move.l a0,a2
move.l d0,d6
ble .argerr
;offset
.lend cmp.b #",",(a2)+
bne .arglast
move.l a2,a0
bsr _etoi
cmp.l a0,a2
beq .argerr
move.l d0,d7
lea (1,a0),a2
.arglast tst.b -(a2)
bne .argerr
.argend
move.l #CMDF_IN,d0 ;flags
movem.l d4-d7,-(a7)
move.l a7,a0 ;cbdata
lea .tracktable,a1 ;cbtt
lea .tracks,a2 ;cbt
bsr _cmdwork
add.w #16,a7
rts
.argerr lea (_badarg),a0
bra _Print
.tracktable lea (gl_tabarg,GL),a0
lea (gl_tabread,GL),a1
bsr _copytt
moveq #-1,d0
rts
.tracks movem.l d2-d7/a2-a3,-(a7)
move.l a0,a3 ;a3 = cbdata
;display track info
move.l (gl_trk+wth_wlen,GL),-(a7)
move.l (gl_trk+wth_len,GL),d0
move.l d0,d1
and.l #7,d1
lsr.l #3,d0
movem.l d0-d1,-(a7)
moveq #" ",d0
btst #TFB_INDEX,(gl_trk+wth_flags+1,GL)
beq .fi
moveq #"I",d0
.fi move.l d0,-(a7)
bsr _gettt
pea (a0)
move.l d5,-(a7)
lea (_dump1),a0
move.l a7,a1
bsr _PrintArgs
add.w #6*4,a7
lea (gl_trk+wth_sync,GL),a0
bsr _printsync
bsr _PrintLn
;search syncs
moveq #0,d7 ;d7 = bitoffset in buffer to display
cmp.w #TT_RAW,(gl_trk+wth_type,GL)
bne .dsend
lea (gl_sync,GL),a2 ;a2 = sync (via arg)
tst.l (a3)
bne .syncarg
lea (gl_trk+wth_sync,GL),a2 ;a2 = sync (from track header)
.syncarg move.l a2,a0
bsr _testsync
tst.l d0
beq .dsend
moveq #0,d2 ;d2 = bitoffset in buffer
move.l (gl_trk+wth_len,GL),d3 ;d3 = bitlength buffer
move.l (gl_trk+wth_flags,GL),d0
btst #TFF_RAWSINGLE,d0
bne .dsraws
.dsraw sub.l #SYNCLEN*8-1,d3
move.l #DEFTRACKLEN/2*8,d0
cmp.l d0,d3
bls .dsgo
move.l d0,d3
bra .dsgo
.dsraws bsr _doubleraws
.dsgo moveq #0,d4 ;d4 = num of sync found
.dsloop move.l d2,d0
move.l d3,d1
move.l (gl_fastbuf,GL),a0
move.l a2,a1
bsr _searchsync
move.l d0,d2
bmi .dsprint
addq.l #1,d4
cmp.l (4,a3),d4
bhi .ds1
move.l d2,d7
.ds1 addq.l #1,d2
cmp.l d3,d2
blo .dsloop
.dsprint lea (_syncfound1),a0
bsr _Print
move.l a2,a0
bsr _printsync
lea (_syncfound2),a0
move.l d4,-(a7)
move.l a7,a1
bsr _PrintArgs
addq.l #4,a7
move.l d7,d0
bsr _printbitlen
bsr _PrintLn
.dsend
;dump
move.l (gl_trk+wth_len,GL),d4 ;d4 = buffersize in bits
;offset
move.l (12,a3),d6 ;d6 = offset in bytes
move.l d6,d0
asl.l #3,d0 ;in bits
add.l d0,d7 ;d7 = shift + offset
bmi .offerr
beq .endshift
cmp.l d7,d4
ble .offerr
move.w (gl_trk+wth_flags,GL),d0
btst #TFF_RAWSINGLE,d0
beq .single
sub.l d7,d4
.single move.l d7,d0
move.l d4,d1 ;bitlen new buffer
move.l (gl_fastbuf,GL),a0 ;buffer
bsr _shiftmfm
.endshift addq.l #7,d4
lsr.l #3,d4 ;d4 = buffersize in bytes
;length
move.l (8,a3),d0 ;length
bne .len1
move.l (gl_trk+wth_wlen,GL),d0
beq .lenok
.len1 cmp.l d0,d4
bls .lenok
move.l d0,d4
.lenok
;dump
move.l d4,d0 ;length
move.l d6,d1 ;delta
move.l (gl_fastbuf,GL),a0 ;memory
bsr _DumpMemory
;return
moveq #-1,d0 ;success
.end movem.l (a7)+,d2-d7/a2-a3
rts
.offerr lea (_offerr),a0
bsr _Print
moveq #0,d0
bra .end
;----------------------------------------
; dump memory
; IN: d0 = ULONG len
; d1 = ULONG delta
; a0 = APTR memory
; OUT: d0 = BOOL success
_DumpMemory movem.l d1/d5-d6/a2-a3,-(a7)
move.l a0,a2 ;A2 = actual address
lea (a2,d0.l),a3 ;A3 = end address
clr.w (a7)
.line bsr _CheckBreak ;check for CTRL-C
tst.l d0
bne .break
lea (.adr),a0
lea (2,a7),a1
bsr _PrintArgs
moveq #7,d6
.mem lea (.space),a0
bsr _Print
moveq #3,d5
.long lea (.byte),a0
move.b (a2)+,(1,a7)
move.l a7,a1
bsr _PrintArgs
addq.w #1,(2,a7)
cmp.l a2,a3
bls .ok
dbf d5,.long
dbf d6,.mem
.ok bsr _PrintLn
cmp.l a2,a3
bhi .line
.break movem.l (a7)+,_MOVEMREGS
rts
.adr dc.b "$%04x",0
.space dc.b " ",0
.byte dc.b "%02x",0
EVEN
;##########################################################################
;##########################################################################
_cmd_force move.l #CMDF_OUT|CMDF_IN,d0 ;flags
sub.l a0,a0 ;cbdata
lea .tracktable,a1 ;cbtt
lea .tracks,a2 ;cbt
bra _cmdwork
.tracktable lea (gl_tabin,GL),a0
lea (gl_tabread,GL),a1
bsr _copytt
moveq #-1,d0
rts
.tracks
;check type
cmp.w #TT_RAW,(gl_trk+wth_type,GL)
bne .badtype
;if single -> double
bsr _doubleraws
move.l d0,d5 ;D5 = mfm length
;search start
moveq #0,d0
move.l d5,d1
move.l (gl_fastbuf,GL),a0
lea (_syncstd2),a1
bsr _searchsync
move.l d0,d6 ;D6 = offset
bmi .nosync
;check that remaining mfm data is sufficent
sub.l d6,d5 ;in bits
cmp.l #11*$440*8,d5
blo .shortmfm
;decode track
move.l #%11111111111,d4 ;D4 = sectors
move.l #$55555555,d5 ;D5 = mfm decode
moveq #11-1,d7 ;D7 = sector loop count
move.l (gl_fastbuf,GL),a0 ;A0 = mfm buffer
subq.l #4,a0 ;first $aaaaaaaa
.sector bsr .getlw ;$2aaaaaaa
bsr .getlw ;$44894489
cmp.l #$44894489,d0
bne .no
moveq #0,d3 ;D3 = chksum
bsr .getlwd ;sector header
lsr.l #8,d0 ;sector number 0..10
cmp.b #10,d0
bhi .no
bclr d0,d4
beq .no ;same sector again
moveq #0,d1
move.b d0,d1
mulu #$200,d1
lea (gl_tmpbuf.w,GL,d1.l),a1
moveq #3,d2
.label bfextu (a0){d6:32},d0
bfextu (16,a0){d6:32},d1
eor.l d0,d3
eor.l d1,d3
and.l d5,d0
bne .no
and.l d5,d1
bne .no
addq.l #4,a0
dbf d2,.label
add.w #16,a0
move.l d3,d2
and.l d5,d2
bsr .getlwd ;header chksum
cmp.l d2,d0
bne .no
bsr .getlwd ;data chksum
move.l d0,d3
moveq #$200/4-1,d2
.data bfextu (a0){d6:32},d0
bfextu ($200,a0){d6:32},d1
eor.l d0,d3
and.l d5,d0
eor.l d1,d3
and.l d5,d1
add.l d0,d0
addq.l #4,a0
or.l d0,d1
move.l d1,(a1)+
dbf d2,.data
add.w #$200,a0
and.l d5,d3
bne .no
dbf d7,.sector
;copy buffer
move.w #$1600/4-1,d0
lea (gl_tmpbuf,GL),a0
move.l (gl_fastbuf,GL),a1
.copy move.l (a0)+,(a1)+
dbf d0,.copy
;set track header
move.w #TT_STD,(gl_trk+wth_type,GL)
move.w #0,(gl_trk+wth_flags,GL)
move.l #$1600*8,(gl_trk+wth_len,GL)
moveq #-1,d0
rts
.getlw bfextu (a0){d6:32},d0
addq.l #4,a0
eor.l d0,d3
rts
.getlwd bsr .getlw
move.l d0,d1
bsr .getlw
and.l d5,d1
and.l d5,d0
add.l d1,d1
or.l d1,d0
rts
.badtype lea (_forcebadtype),a0
bra .print
.nosync lea (_forcenosync),a0
bra .print
.shortmfm lea (_forceshortmfm),a0
bra .print
.no lea (_forcebad),a0
.print lea (gl_trk+wth_num,GL),a1
bsr _PrintArgs
moveq #1,d0
rts
;##########################################################################
;##########################################################################
_cmd_info move.l #CMDF_NOTTC|CMDF_IN,d0 ;flags
lea .tracktable,a1 ;cbtt
lea .tracks,a2 ;cbt
bra _cmdwork
;display for file
.tracktable lea (_txt_infohead1),a0
bsr _Print
lea (gl_headin+wfh_creator,GL),a0
bsr _Print
lea (gl_headin+wfh_ctime,GL),a0
bsr _GetDate
lea (_txt_infohead2),a0
pea (gl_time,GL)
pea (gl_date,GL)
move.l a7,a1
bsr _PrintArgs
add.w #8,a7
lea (gl_headin+wfh_mtime,GL),a0
bsr _GetDate
lea (_txt_infohead3),a0
pea (gl_time,GL)
pea (gl_date,GL)
move.l a7,a1
bsr _PrintArgs
add.w #8,a7
moveq #0,d0
move.l #MAXTRACKS-1,d1
.c0 bftst (gl_tabin+wtt_tab,GL){d1:1}
beq .c1
addq.l #1,d0
.c1 dbf d1,.c0
lea (_txt_infohead4),a0
move.l d0,-(a7)
move.l a7,a1
bsr _PrintArgs
addq.l #4,a7
moveq #-1,d0
rts
;display for each track
.tracks bsr _gettt
subq.l #8,a7
move.l a7,a1
pea (a1)
moveq #3,d0
.fs1 move.b (a0)+,(a1)+
dbeq d0,.fs1
bne .fs3
subq.l #1,a1
.fs2 move.b #" ",(a1)+
dbf d0,.fs2
.fs3 clr.b (a1)
lea (_txt_infotrack),a0
move.l d5,-(a7)
move.l a7,a1
bsr _PrintArgs
add.w #16,a7
moveq #" ",d2
btst #TFB_SLINC,(gl_trk+wth_flags+1,GL)
beq .fc
moveq #"C",d2
.fc move.l (gl_dosbase,GL),a6
jsr (_LVOOutput,a6)
move.l d0,d1
jsr (_LVOFPutC,a6)
moveq #" ",d2
btst #TFB_LEQ,(gl_trk+wth_flags+1,GL)
beq .fq
moveq #"Q",d2
.fq move.l (gl_dosbase,GL),a6
jsr (_LVOOutput,a6)
move.l d0,d1
jsr (_LVOFPutC,a6)
moveq #" ",d2
btst #TFB_RAWSINGLE,(gl_trk+wth_flags+1,GL)
beq .fs
moveq #"S",d2
.fs move.l (gl_dosbase,GL),a6
jsr (_LVOOutput,a6)
move.l d0,d1
jsr (_LVOFPutC,a6)
moveq #" ",d2
btst #TFB_INDEX,(gl_trk+wth_flags+1,GL)
beq .fi
moveq #"I",d2
.fi move.l (gl_dosbase,GL),a6
jsr (_LVOOutput,a6)
move.l d0,d1
jsr (_LVOFPutC,a6)
lea (_length),a0
move.l (gl_trk+wth_len,GL),d0
move.l d0,d1
and.l #7,d1
lsr.l #3,d0
move.l (gl_trk+wth_wlen,GL),d2
movem.l d0-d2,-(a7)
move.l a7,a1
bsr _PrintArgs
add.w #12,a7
;print sync
lea (gl_trk+wth_sync,GL),a0
bsr _printsync
bsr _PrintLn
;return
.ret moveq #-1,d0 ;success
rts
;##########################################################################
;##########################################################################
_cmd_length move.l (gl_rd_arg,GL),d0
bne .1
lea (_needlength),a0
bra _Print
.wronglength lea (_wronglength),a0
bra _Print
.1 move.l d0,a0
bsr _atoi
tst.l d0
bmi .wronglength
btst #0,d0
bne .wronglength
move.l d0,-(a7)
move.l #CMDF_OUT|CMDF_IN,d0 ;flags
move.l a7,a0 ;cbdata
lea .tracktable,a1 ;cbtt
lea .tracks,a2 ;cbt
bsr _cmdwork
add.w #4,a7
rts
.tracktable lea (gl_tabin,GL),a0
lea (gl_tabread,GL),a1
bsr _copytt
moveq #-1,d0
rts
.tracks cmp.w #TT_RAW,(gl_trk+wth_type,GL)
bne .badtype
move.l (gl_trk+wth_len,GL),d0
lsr.l #3,d0
cmp.l (a0),d0
blo .tobig
move.l (a0),(gl_trk+wth_wlen,GL)
moveq #-1,d0
rts
.badtype lea (_lenbadtype),a0
bra .print
.tobig lea (_lentobig),a0
.print lea (gl_trk+wth_num,GL),a1
bsr _PrintArgs
moveq #0,d0
rts
;##########################################################################
;##########################################################################
_cmd_merge lea .sorry,a0
bra _Print
.sorry dc.b "Sorry, this command is currently not implemented.",10,0,0
;##########################################################################
;##########################################################################
_cmd_pack bra _cmd_merge
;##########################################################################
;##########################################################################
_cmd_remove
tst.l (gl_rd_tracks,GL)
bne .1
lea (_notracks),a0
bra _Print
.1 move.l #CMDF_OUT|CMDF_IN,d0 ;flags
lea .tracktable,a1 ;cbtt
sub.l a2,a2 ;cbt
bra _cmdwork
.tracktable
;remove all selected tracks from output
move.l #MAXTRACKS-1,d0
.loop bftst (gl_tabarg+wtt_tab,GL){d0:1}
beq .next
bfclr (gl_tabout+wtt_tab,GL){d0:1}
.next dbf d0,.loop
;skip removed tracks
lea (gl_tabout,GL),a0
lea (gl_tabread,GL),a1
bsr _copytt
;return
moveq #-1,d0
rts
;##########################################################################
;##########################################################################
_cmd_save bra _cmd_merge
;##########################################################################
;##########################################################################
_cmd_sync move.l (gl_rd_arg,GL),d0
bne .1
lea (_needsync),a0
bra _Print
.1 move.l d0,a0
bsr _parsesync
tst.l d0
beq _rts
.go move.l #CMDF_OUT|CMDF_IN,d0 ;flags
lea .tracktable,a1 ;cbtt
lea .tracks,a2 ;cbt
bra _cmdwork
.tracktable lea (gl_tabin,GL),a0
lea (gl_tabread,GL),a1
bsr _copytt
moveq #-1,d0
rts
.tracks cmp.w #TT_RAW,(gl_trk+wth_type,GL)
bne .badtype
lea (gl_sync,GL),a0
lea (gl_trk+wth_sync,GL),a1
move.w #SYNCLEN-1,d0
.cp move.w (a0)+,(a1)+
dbf d0,.cp
moveq #-1,d0
rts
.badtype lea (_lenbadtype),a0
move.l d5,-(a7)
move.l a7,a1
bsr _PrintArgs
add.w #4,a7
moveq #0,d0
rts
;----------------------------------------
; translate arg into sync
; sync will be stored in gl_sync
; IN: A0 = CPTR arg
; OUT: D0 = BOOL true if sync has been translated
_parsesync movem.l d2-d7/a2-a3,-(a7)
move.l a0,a2 ;A2 = string
bsr _StrLen
move.l d0,d2
beq .badsync
subq.w #1,d2 ;D2 = last char (mask)
move.l d2,d3 ;D3 = amparsent
.samp cmp.b #"&",(a2,d3.l)
beq .mfound
dbf d3,.samp
.mfound
tst.w d3 ;empty data?
beq .badsync
cmp.w d2,d3 ;empty mask?
beq .badsync
move.w d2,d4 ;D4 = last char data
tst.w d3
bmi .nomask
move.w d3,d4
subq.w #1,d4
.nomask
;decode sync data
cmp.w #31,d4 ;to many chars?
bhi .badsync
lea (gl_sync+SYNCLEN,GL),a3
.dloop move.l (gl_fastbuf,GL),a1
move.b #"$",(a1)+
moveq #7,d5
cmp.w d5,d4
bhs .2
move.w d4,d5
.2 move.w d5,d0
lea (a2,d4.w),a0
sub.w d0,a0
.c1 move.b (a0)+,(a1)+
dbf d0,.c1
clr.b (a1)
move.l a1,d7
move.l (gl_fastbuf,GL),a0
bsr _atoi
cmp.l a0,d7
bne .badsync
move.l d0,-(a3)
sub.w d5,d4
subq.w #1,d4
bpl .dloop
tst.w d3
bpl .mask
;calculate default mask
moveq #SYNCLEN-1,d0
sf d1
lea (gl_sync,GL),a0
lea (SYNCLEN,a0),a1
.dmloop tst.b (a0)+
beq .dm1
st d1
.dm1 move.b d1,(a1)+
dbf d0,.dmloop
bra .success
;decode sync mask
.mask lea (1,a2,d3.w),a2
move.w d2,d4
sub.w d3,d4
sub.w #1,d4
cmp.w #31,d4 ;to many chars?
bhi .badsync
lea (gl_sync+SYNCLEN+SYNCLEN,GL),a3
.mloop move.l (gl_fastbuf,GL),a1
move.b #"$",(a1)+
moveq #7,d5
cmp.w d5,d4
bhs .m2
move.w d4,d5
.m2 move.w d5,d0
lea (a2,d4.w),a0
sub.w d0,a0
.mc1 move.b (a0)+,(a1)+
dbf d0,.mc1
clr.b (a1)
move.l a1,d7
move.l (gl_fastbuf,GL),a0
bsr _atoi
cmp.l a0,d7
bne .badsync
move.l d0,-(a3)
sub.w d5,d4
subq.w #1,d4
bpl .mloop
;apply mask on the sync
lea (gl_sync,GL),a0
lea (SYNCLEN,a0),a1
moveq #SYNCLEN/4-1,d1
.m move.l (a1)+,d0
and.l d0,(a0)+
dbf d1,.m
.success moveq #-1,d0
.end movem.l (a7)+,_MOVEMREGS
rts
.badsync lea (_badsync),a0
bsr _Print
moveq #0,d0
bra .end
;##########################################################################
;##########################################################################
_cmd_write
;open the device
move.l #0,d0
lea (gl_io,GL),a0
bsr _OpenDevice
tst.l d0
beq .nodevice
;main
move.l #CMDF_IN,d0 ;flags
lea .tracktable,a1 ;cbtt
lea .tracks,a2 ;cbt
bsr _cmdwork
;close the device
lea (gl_io,GL),a0
bsr _CloseDevice
.nodevice
rts
;copy tabarg to tabout so that the trackdata for all tracks
;to write will read
.tracktable lea (gl_tabarg,GL),a0
lea (gl_tabread,GL),a1
bsr _copytt
moveq #-1,d0
rts
.tracks cmp.w #TT_RAW,(gl_trk+wth_type,GL)
beq _cmdw_raw
cmp.w #TT_STD,(gl_trk+wth_type,GL)
beq _cmdw_std
cmp.w #TT_GREM,(gl_trk+wth_type,GL)
beq _cmdw_grem
lea (_unknowntt),a0
bsr _Print
moveq #0,d0
rts
_cmdw_std move.w (gl_trk+wth_flags,GL),d0
move.l (gl_trk+wth_len,GL),d7 ;D7 = length
btst #TFB_LEQ,d0
bne .leq
btst #TFB_SLINC,d0
bne .slinc
cmp.l #$1600*8,d7
bne _cmdw_corrupt
.go
;get length, print info
bsr _gettt
move.l d0,d7
ble _cmdw_corrupt
move.l a0,-(a7)
move.w (gl_trk+wth_num,GL),-(a7)
clr.w -(a7)
lea (_wtrack),a0
move.l a7,a1
bsr _PrintArgs
addq.l #8,a7
;write track
move.l (gl_io,GL),a1
move.l (gl_fastbuf,GL),(IO_DATA,a1)
move.w (gl_trk+wth_num,GL),d0
mulu d7,d0
move.l d0,(IO_OFFSET,a1)
move.l d7,(IO_LENGTH,a1)
move.w #ETD_WRITE,(IO_COMMAND,a1)
clr.b (IO_ERROR,a1)
move.l (gl_execbase,GL),a6
jsr (_LVODoIO,a6)
move.l (gl_io,GL),a1
move.b (IO_ERROR,a1),d0
bne .err
moveq #-1,d0
rts
.err lea (_readdisk),a0
bsr _PrintErrorTD
moveq #0,d0
rts
.leq cmp.l #4*8,d7
bne _cmdw_corrupt
move.l (gl_fastbuf,GL),a0
move.w #$1600/4-2,d0
move.l (a0)+,d1
.leq1 move.l d1,(a0)+
dbf d0,.leq1
bra .go
.slinc cmp.l #11*4*8,d7
bne _cmdw_corrupt
move.l (gl_fastbuf,GL),a0
lea ($1600,a0),a1
movem.l (a0),d0-d7/a2-a3/a6
movem.l _MOVEMREGS,(a1)
moveq #11-1,d5
.slinc2 moveq #$200/4-1,d6
move.l (a1)+,d7
.slinc1 move.l d7,(a0)+
addq.l #1,d7
dbf d6,.slinc1
dbf d5,.slinc2
bra .go
_cmdw_grem
;get length, print info
bsr _gettt
lsl.l #3,d0
cmp.l (gl_trk+wth_len,GL),d0
bne _cmdw_corrupt
move.l a0,-(a7)
move.w (gl_trk+wth_num,GL),-(a7)
clr.w -(a7)
lea (_wtrack),a0
move.l a7,a1
bsr _PrintArgs
addq.l #8,a7
;copy to tmp
move.l (gl_fastbuf,GL),a0
lea (gl_tmpbuf,GL),a1
move.w #$1800/4-1,d0
.cpy move.l (a0)+,(a1)+
dbf d0,.cpy
;build mfm
move.l (gl_chipbuf,GL),a0
move.l #$55555555,d3
move.w #($3200-$3000-20)/4-1,d0
.gap move.l d3,(a0)+
dbf d0,.gap
move.l #$44894489,(a0)+ ;4
move.l #$44895555,(a0)+ ;4
lea (gl_tmpbuf,GL),a1
moveq #0,d5
move.w #$1800/2-1,d6
.data move.w (a1)+,d2 ;$3000
add.w d2,d5
move.w d2,d0
swap d2
lsr.w #1,d0
move.w d0,d2
bsr _encode_long
dbf d6,.data
move.w d5,d2
swap d2
lsr.w #1,d5
move.w d5,d2
bsr _encode_long ;4
move.w (gl_trk+wth_num,GL),d2
bchg #0,d2
move.w d2,d0
swap d2
lsr.w #1,d0
move.w d0,d2
bsr _encode_long ;4
moveq #0,d2
bsr _encode_long ;4
;write track
move.l (gl_io,GL),a1
move.l (gl_chipbuf,GL),(IO_DATA,a1)
move.w (gl_trk+wth_num,GL),d0
ext.l d0
move.l d0,(IO_OFFSET,a1)
move.l #$3200,(IO_LENGTH,a1)
move.w #ETD_RAWWRITE,(IO_COMMAND,a1)
clr.b (IO_ERROR,a1)
move.l (gl_execbase,GL),a6
jsr (_LVODoIO,a6)
move.l (gl_io,GL),a1
move.b (IO_ERROR,a1),d0
bne .err
moveq #-1,d0
rts
.err lea (_readdisk),a0
bsr _PrintErrorTD
moveq #0,d0
rts
_cmdw_raw bsr _cmd_merge
moveq #0,d0
rts
_cmdw_corrupt lea (_corrupt),a0
bsr _Print
moveq #0,d0
rts
; d2=long d3=55555555 a0=dest
_encode_long and.l d3,d2
move.l d2,d0
eor.l d3,d0
move.l d0,d1
add.l d0,d0
lsr.l #1,d1
bset #31,d1
and.l d0,d1
or.l d1,d2
btst #0,-1(a0)
beq .ok
bclr #31,d2
.ok move.l d2,(a0)+
rts
;##########################################################################
;##########################################################################
; read wwarp file,
; call given function after tracktable has been read,
; call given function on each track in the input file which is marked in gl_tabdo,
; optionally copy all tracks marked in tabout to new wwarp file (which will
; be created and renamed to the original on success)
; IN: D0 = ULONG flags
; A0 = APTR data area for routines, provided in a0 on calling
; A1 = FPTR routine for tracktable (a0 = data)
; A2 = FPTR routine for tracks (d0 = trknum, a0 = data)
; OUT: D0 = BOOL success
NSTRUCTURE cmdwork_locals,0
NULONG wl_flags
NBYTE wl_tmpfile
NSTRUCT wl_pad,3
NULONG wl_cbdata
NULONG wl_cbtt
NULONG wl_cbt
NULONG wl_lt
NLABEL wl_SIZEOF
BITDEF CMD,IN,0 ;read input (obsolete)
BITDEF CMD,OUT,1 ;write output
BITDEF CMD,NOTTC,2 ;dont check tabarg against tabin
_cmdwork link LOC,#wl_SIZEOF
move.l d0,(wl_flags,LOC)
move.l a0,(wl_cbdata,LOC)
move.l a1,(wl_cbtt,LOC)
move.l a2,(wl_cbt,LOC)
sf (wl_tmpfile,LOC)
moveq #0,d6 ;d6 = fh input
moveq #0,d7 ;d7 = fh output
btst #CMDB_IN,(wl_flags+3,LOC)
beq .noin1
;open input file
lea (gl_filename,GL),a0
move.l a0,d1
move.l #MODE_OLDFILE,d2
move.l (gl_dosbase,GL),a6
jsr (_LVOOpen,a6)
move.l d0,d6 ;d6 = fh input
bne .fhinok
.openerr lea (_openfile),a0
bsr _PrintErrorDOS
bra .error
.fhinok
;read input file header
bsr _readfilehead
beq .error
;read input track table
bsr _readtt
beq .error
;copy original stamp to output file header
lea (gl_headin+wfh_ctime,GL),a0
lea (gl_headout+wfh_ctime,GL),a1
move.l (a0)+,(a1)+
move.l (a0)+,(a1)+
move.l (a0)+,(a1)+
;if no track specification given copy gl_tabin to gl_tabarg
tst.l (gl_rd_tracks,GL)
bne .aftersetarg
lea (gl_tabin,GL),a0
lea (gl_tabarg,GL),a1
bsr _copytt
.aftersetarg
;compare tabarg against tabin and print a warning for all tracks
;delete also these tracks
;which are in tabarg but not in tabin
btst #CMDB_NOTTC,(wl_flags+3,LOC)
bne .nif2
sf d4
move.l #-1,d5
.loop addq.l #1,d5
bftst (gl_tabarg+wtt_tab,GL){d5:1}
beq .next
bftst (gl_tabin+wtt_tab,GL){d5:1}
bne .next
bfclr (gl_tabarg+wtt_tab,GL){d5:1}
lea (_notinfile1),a0
tst.b d4
beq .nif1
lea (_notinfile2),a0
.nif1 st d4
move.l d5,-(a7)
move.l a7,a1
bsr _PrintArgs
add.w #4,a7
.next cmp.l #MAXTRACKS-1,d5
bne .loop
tst.b d4
beq .nif2
lea (_notinfile3),a0
bsr _Print
.nif2
;copy gl_tabin to gl_tabout
lea (gl_tabin,GL),a0
lea (gl_tabout,GL),a1
bsr _copytt
.noin1
btst #CMDB_OUT,(wl_flags+3,LOC)
beq .noout1
;check if creating new or modifying existing
btst #CMDB_IN,(wl_flags+3,LOC)
sne (wl_tmpfile,LOC)
bne .tmpout
.newout
;check file exists
lea (gl_filename,GL),a0
move.l a0,d1
move.l #ACCESS_READ,d2
move.l (gl_dosbase,GL),a6
jsr (_LVOLock,a6)
move.l d0,d1
beq .noold
jsr (_LVOUnLock,a6)
lea (_txt_exists),a0
pea (gl_filename,GL)
move.l a7,a1
bsr _PrintArgs
addq.l #4,a7
bsr _FlushOutput
bsr _GetKey
move.b d0,d2
bsr _PrintLn
UPPER d2
cmp.b #"Y",d2
bne .error
;open new output file
.noold lea (gl_filename,GL),a0
move.l a0,d1
move.l #MODE_NEWFILE,d2
move.l (gl_dosbase,GL),a6
jsr (_LVOOpen,a6)
move.l d0,d7 ;d7 = fh output
bne .fhoutok
bra .openerr
;open temp output file
.tmpout lea (gl_filename,GL),a0
lea (gl_filename2,GL),a1
move.l #FILENAMELEN,d0
bsr _CopyString
move.l #"!"<<24,-(a7)
move.l a7,a0
lea (gl_filename2,GL),a1
move.l #FILENAMELEN,d0
bsr _AppendString
add.w #4,a7
lea (gl_filename2,GL),a0
move.l a0,d1
move.l #MODE_NEWFILE,d2
move.l (gl_dosbase,GL),a6
jsr (_LVOOpen,a6)
move.l d0,d7 ;d7 = fh output
beq .openerr
.fhoutok
;write output file header
bsr _writefilehead
beq .error
.noout1
;copy gl_tabarg to gl_tabdo
lea (gl_tabarg,GL),a0
lea (gl_tabdo,GL),a1
bsr _copytt
;callback tracktable
move.l (wl_cbtt,LOC),d0
beq .s1
move.l (wl_cbdata,LOC),a0
movem.l d2-d7/a2-a6,-(a7)
jsr (d0.l)
movem.l (a7)+,_MOVEMREGS
tst.l d0
beq .error
.s1
;write output track table
btst #CMDB_OUT,(wl_flags+3,LOC)
beq .skipout2
bsr _writett
beq .error
.skipout2
;count last track to process
lea (gl_tabdo+wtt_tab,GL),a0
btst #CMDB_OUT,(wl_flags+3,LOC)
beq .clt1
lea (gl_tabout+wtt_tab,GL),a0
.clt1 move.l #MAXTRACKS-1,d0
.clt2 bftst (a0){d0:1}
dbne d0,.clt2
beq .finish
move.l d0,(wl_lt,LOC)
;***
;do for each input track upto wl_lt
;
move.l #-1,d5 ;d5 = actual track
.trkloop addq.l #1,d5
cmp.l (wl_lt,LOC),d5
bhi .finish
;check CTRL-C pressed
bsr _CheckBreak ;check for CTRL-C
tst.l d0
bne .break
;input
btst #CMDB_IN,(wl_flags+3,LOC)
beq .noin2
bftst (gl_tabin+wtt_tab,GL){d5:1}
beq .noin2
;read input track header
bsr _readth
beq .error
;if track in gl_tabread read track data else skip it
lea (_skiptd),a0
bftst (gl_tabread+wtt_tab,GL){d5:1}
beq .indo
lea (_readtd),a0
.indo jsr (a0)
beq .error
.noin2
;callback track if in tabdo
bftst (gl_tabdo+wtt_tab,GL){d5:1}
beq .nodo
move.l (wl_cbt,LOC),d1
beq .nodo
move.l d5,d0
move.l (wl_cbdata,LOC),a0
movem.l d2-d7/a2-a6,-(a7)
jsr (d1.l)
movem.l (a7)+,_MOVEMREGS
tst.l d0
beq .error
.nodo
;write
btst #CMDB_OUT,(wl_flags+3,LOC)
beq .trkloop
bftst (gl_tabout+wtt_tab,GL){d5:1}
beq .trkloop
;write track
bsr _writet
beq .error
bra .trkloop
;success, all tracks
.finish move.l #0,(gl_rc,GL)
.break
.error
;close output file
move.l d7,d1
beq .noout
move.l (gl_dosbase,GL),a6
jsr (_LVOClose,a6)
.noout
;close input file
move.l d6,d1
beq .noin
move.l (gl_dosbase,GL),a6
jsr (_LVOClose,a6)
.noin
;success or fail
tst.l (gl_rc,GL)
bne .fail
.success
;if tmpfile rename
tst.b (wl_tmpfile,LOC)
beq .end
lea (gl_filename,GL),a0
move.l a0,d1
move.l (gl_dosbase,GL),a6
jsr (_LVODeleteFile,a6)
lea (gl_filename2,GL),a0
move.l a0,d1
lea (gl_filename,GL),a0
move.l a0,d2
jsr (_LVORename,a6)
bra .end
.fail
tst.l d7
beq .end
;delete output file
lea (gl_filename,GL),a0
tst.b (wl_tmpfile,LOC)
beq .del
lea (gl_filename2,GL),a0
.del move.l a0,d1
move.l (gl_dosbase,GL),a6
jsr (_LVODeleteFile,a6)
.end unlk LOC
rts
;##########################################################################
;##########################################################################
;----------------------------------------
; open device
; IN: D0 = UBYTE flags for OpenDevice
; A0 = APTR io structure (iorequest,msgport)
; OUT: D0 = BOOL success
_OpenDevice movem.l d7/a2/a6,-(a7)
move.l d0,d7 ;D7 = flags
move.l a0,a2 ;A2 = struct
move.l (gl_execbase,GL),a6
jsr (_LVOCreateMsgPort,a6)
move.l d0,(4,a2)
bne .portok
moveq #0,d0
lea (_noport),a0
sub.l a1,a1
bsr _PrintError
bra .noport
.portok
move.l d0,a0
move.l #IOTD_SIZE,d0
jsr (_LVOCreateIORequest,a6)
move.l d0,(a2)
bne .ioreqok
moveq #0,d0
lea (_noioreq),a0
sub.l a1,a1
bsr _PrintError
bra .noioreq
.ioreqok
lea (_trackdisk),a0
move.l (gl_rd_unit,GL),d0 ;unit
move.l (a2),a1 ;ioreq
move.l d7,d1 ;flags
jsr (_LVOOpenDevice,a6)
tst.l d0
beq .deviceok
move.l (a2),a1
move.b (IO_ERROR,a1),d0
lea (_opendevice),a0
bsr _PrintErrorTD
bra .nodevice
.deviceok
move.l (a2),a1
move.w #TD_CHANGENUM,(IO_COMMAND,a1)
jsr (_LVODoIO,a6)
move.l (a2),a1
move.l (IO_ACTUAL,a1),(IOTD_COUNT,a1) ;the diskchanges
moveq #-1,d0 ;success
.end movem.l (a7)+,_MOVEMREGS
rts
.nodevice move.l (a2),a0
jsr (_LVODeleteIORequest,a6)
.noioreq move.l (4,a2),a0
jsr (_LVODeleteMsgPort,a6)
.noport moveq #0,d0
bra .end
;----------------------------------------
; close device
; IN: A0 = APTR io structure (iorequest,msgport)
; OUT: -
_CloseDevice movem.l a2/a6,-(a7)
move.l a0,a2 ;A2 = struct
move.l (a2),a1
move.l #0,(IO_LENGTH,a1)
move.w #ETD_MOTOR,(IO_COMMAND,a1)
move.l (gl_execbase,GL),a6
jsr (_LVODoIO,a6)
move.l (a2),a1
jsr (_LVOCloseDevice,a6)
move.l (a2),a0
jsr (_LVODeleteIORequest,a6)
move.l (4,a2),a0
jsr (_LVODeleteMsgPort,a6)
movem.l (a7)+,_MOVEMREGS
rts
;##########################################################################
;----------------------------------------
; write to file
; IN: D3 = ULONG length
; D7 = BPTR filehandle
; A0 = APTR data
; OUT: D0 = BOOL success
; D2 = destroyed
; A6 = destroyed
_write move.l d7,d1
move.l a0,d2
move.l (gl_dosbase,GL),a6
jsr (_LVOWrite,a6)
cmp.l d0,d3
beq _success
lea (_txt_writing),a0
bsr _PrintErrorDOS
_writeerr moveq #0,d0
rts
;----------------------------------------
; write fileheader
; IN: D7 = BPTR filehandle
; OUT: D0 = BOOL success
; D2 = destroyed
; D3 = destroyed
; A6 = destroyed
_writefilehead move.l #FILEID,(gl_headout+wfh_id,GL)
move #FILEVER,(gl_headout+wfh_ver,GL)
lea (gl_headout+wfh_creator,GL),a0
move #CREATORLEN-1,d0
.cc clr.b (a0)+
dbf d0,.cc
lea (_txt_creator),a0
lea (gl_headout+wfh_creator,GL),a1
move.l #CREATORLEN,d0
bsr _CopyString
lea (gl_headout+wfh_mtime,GL),a0
move.l a0,d1
jsr (_LVODateStamp,a6)
move.l #wfh_SIZEOF,d3
lea (gl_headout,GL),a0
bra _write
;----------------------------------------
; write track table
; IN: D7 = BPTR filehandle
; OUT: D0 = BOOL success
; D2 = destroyed
; D3 = destroyed
; A6 = destroyed
_writett lea (gl_tabout,GL),a0
move.l #TABLEID,(wtt_id,a0)
move #TABLEVER,(wtt_ver,a0)
move.l #wtt_tab+MAXTRACKS/8,d3
bra _write
;----------------------------------------
; write track
; IN: D7 = BPTR filehandle
; OUT: D0 = BOOL success
; D2 = destroyed
; D3 = destroyed
; A6 = destroyed
_writet move.l #TRACKID,(gl_trk+wth_id,GL)
move #TRACKVER,(gl_trk+wth_ver,GL)
move.l #wth_data,d3
lea (gl_trk,GL),a0
bsr _write
beq _writeerr
move.l (gl_trk+wth_len,GL),d3
addq.l #7,d3
lsr.l #3,d3
move.l (gl_fastbuf,GL),a0
bra _write
;----------------------------------------
; read from file
; IN: D3 = ULONG length
; D6 = BPTR filehandle
; A0 = APTR data
; OUT: D0 = BOOL success
; D2 = destroyed
; A6 = destroyed
_read move.l d6,d1
move.l a0,d2
move.l (gl_dosbase,GL),a6
jsr (_LVORead,a6)
cmp.l d0,d3
beq _success
lea (_txt_reading),a0
bsr _PrintErrorDOS
moveq #0,d0
rts
;----------------------------------------
; read fileheader
; IN: D6 = BPTR filehandle
; OUT: D0 = BOOL success
; D2 = destroyed
; D3 = destroyed
; A6 = destroyed
_readfilehead move.l #wfh_SIZEOF,d3
lea (gl_headin,GL),a0
bsr _read
beq _readerr
cmp.l #FILEID,(gl_headin+wfh_id,GL)
bne .badfile
cmp.w #FILEVER,(gl_headin+wfh_ver,GL)
bne _badstruct
moveq #-1,d0
rts
.badfile lea (_txt_badfile),a0
bsr _Print
bra _readerr
_badstruct lea (_txt_badstruct),a0
bsr _Print
_readerr moveq #0,d0
rts
;----------------------------------------
; read track table
; IN: D6 = BPTR filehandle
; OUT: D0 = BOOL success
; D2 = destroyed
; D3 = destroyed
; A6 = destroyed
_readtt move.l #wfh_SIZEOF,d3
move.l #wtt_tab,d3
lea (gl_tabin,GL),a0
bsr _read
beq _readerr
cmp.l #TABLEID,(gl_tabin+wtt_id,GL)
bne _badstruct
cmp.w #TABLEVER,(gl_tabin+wtt_ver,GL)
bne _badstruct
moveq #0,d3
move (gl_tabin+wtt_last,GL),d3
sub (gl_tabin+wtt_first,GL),d3
bcs _badstruct
addq.l #8,d3
lsr.l #3,d3
lea (gl_tabin+wtt_tab,GL),a0
bsr _read
beq _readerr
lea (gl_tabin,GL),a0
bsr _expandtt
moveq #-1,d0
rts
;----------------------------------------
; read track header
; IN: D6 = BPTR filehandle
; OUT: D0 = BOOL success
; D2 = destroyed
; D3 = destroyed
; A6 = destroyed
_readth move.l #wth_data,d3
lea (gl_trk,GL),a0
bsr _read
beq _readerr
cmp.l #TRACKID,(gl_trk+wth_id,GL)
bne _badstruct
cmp #TRACKVER,(gl_trk+wth_ver,GL)
bne _badstruct
_success moveq #-1,d0
rts
;----------------------------------------
; read track data
; IN: D6 = BPTR filehandle
; OUT: D0 = BOOL success
; D2 = destroyed
; D3 = destroyed
; A6 = destroyed
_readtd move.l (gl_trk+wth_len,GL),d3
addq.l #7,d3
lsr.l #3,d3
move.l (gl_fastbuf,GL),a0
bra _read
;----------------------------------------
; skip track data
; IN: D6 = BPTR filehandle
; OUT: D0 = BOOL success
; D2 = destroyed
; D3 = destroyed
; A6 = destroyed
_skiptd move.l d6,d1
move.l (gl_trk+wth_len,GL),d2
addq.l #7,d2
lsr.l #3,d2
move.l #OFFSET_CURRENT,d3
move.l (gl_dosbase,GL),a6
jsr (_LVOSeek,a6)
jsr (_LVOIoErr,a6)
tst.l d0
beq _success
lea (_seeking),a0
bsr _PrintErrorDOS
bra _readerr
;----------------------------------------
; convert given datestamp to strings
; IN: A0 = APTR stamp
; OUT: -
_GetDate move.l a6,-(a7)
move.b #FORMAT_DOS,(gl_DateTime+dat_Format,GL)
lea (gl_time,GL),a1
move.l a1,(gl_DateTime+dat_StrTime,GL)
lea (gl_date,GL),a1
move.l a1,(gl_DateTime+dat_StrDate,GL)
lea (gl_DateTime+dat_Stamp,GL),a1
move.l (a0)+,(a1)+
move.l (a0)+,(a1)+
move.l (a0)+,(a1)+
lea (gl_DateTime,GL),a0
move.l a0,d1
move.l (gl_dosbase,GL),a6
jsr (_LVODateToStr,a6)
;fix that on some formats there is a trailing space
lea (gl_date,GL),a0
.l tst.b (a0)+
bne .l
subq.l #2,a0
cmp.b #" ",(a0)
bne .q
clr.b (a0)
.q
move.l (a7)+,a6
rts
;----------------------------------------
; copy track table
; IN: A0 = APTR wtt source
; A1 = APTR wtt destination
; OUT: -
_copytt move.w #wtt_tab+MAXTRACKS/8-1,d0
.1 move.b (a0)+,(a1)+
dbf d0,.1
rts
;----------------------------------------
; expand given track table
; IN: A0 = APTR wtt
; OUT: -
_expandtt move.l #MAXTRACKS-1,d0
.loop cmp (wtt_last,a0),d0
bhi .clear
cmp (wtt_first,a0),d0
blo .clear
move.l d0,d1
add (wtt_first,a0),d1
bftst (wtt_tab,a0){d1:1}
bne .set
.clear bfclr (wtt_tab,a0){d0:1}
.dbf dbf d0,.loop
clr.w (wtt_first,a0)
move #MAXTRACKS-1,(wtt_last,a0)
rts
.set bfset (wtt_tab,a0){d0:1}
bra .dbf
;----------------------------------------
; check if there is a sync set in trkin
; IN: A0 = sync
; OUT: D0 = BOOL
_testsync moveq #-1,d0
add.w #SYNCLEN,a0
tst.l (a0)+
bne .true
tst.l (a0)+
bne .true
tst.l (a0)+
bne .true
tst.l (a0)+
bne .true
moveq #0,d0
.true rts
;##########################################################################
;----------------------------------------
; expand rawsinge track to double size
; IN: -
; OUT: d0 = ULONG track length in bits
_doubleraws move.l (gl_trk+wth_len,GL),d0
btst #TFB_RAWSINGLE,(gl_trk+wth_flags+1,GL)
bne .single
rts
.single move.l d0,-(a7)
add.l d0,(a7)
move.l d2,a1
move.l d0,d1
lsr.l #5,d1
move.l (gl_fastbuf,GL),a0
sub.l #32,d0
.loop move.l (a0)+,d2
bfins d2,(a0){d0:32}
dbf d1,.loop
move.l a1,d2
move.l (a7)+,d0
rts
;----------------------------------------
; get track type
; IN: -
; OUT: D0 = ULONG standard length of track
; A0 = CPTR name/description
_gettt move.w (gl_trk+wth_type,GL),d0
cmp.w #TT_RAW,d0
beq .raw
cmp.w #TT_STD,d0
beq .std
cmp.w #TT_GREM,d0
beq .grem
moveq #0,d0
lea (.tunknown),a0
rts
.raw move.l #DEFTRACKLEN,d0
lea (.traw),a0
rts
.std move.l #$1600,d0
lea (.tstd),a0
rts
.grem move.l #$1800,d0
lea (.tgrem),a0
rts
.tunknown dc.b "unknown",0
.traw dc.b "raw",0
.tstd dc.b "dos",0
.tgrem dc.b "gremlin",0
EVEN
;----------------------------------------
; shift mfm buffer
; IN: D0 = ULONG bitoffset in buffer which make the new start
; D1 = ULONG bitlength for new mfm-buffer
; A0 = APTR mfm-buffer
; OUT: -
_shiftmfm move.l d2,a1
lsr.l #5,d1
.loop bfextu (a0){d0:32},d2
move.l d2,(a0)+
dbf d1,.loop
move.l a1,d2
rts
;----------------------------------------
; search sync in mfm buffer
; IN: D0 = ULONG bitoffset in buffer to start search
; D1 = ULONG bitlength of mfm-buffer
; A0 = APTR mfm-buffer
; A1 = STRUCT sync to search (16 byte sync + 16 byte mask)
; OUT: D0 = ULONG bitoffset in buffer where sync has been found, -1 on error
_searchsync movem.l d2-d7/a2,-(a7)
;count bits to compare
move.l #SYNCLEN*8-1,d2
moveq #-1,d3
.cs addq.l #1,d3
bftst (SYNCLEN,a1){d3:1}
dbne d2,.cs
addq.l #1,d2 ;D2 = bits to compare (synclen)
beq .err
;search for sync
subq.l #1,d0 ;because loop starts with increment
move.l d2,a2 ;A2 = bits to compare (synclen)
;outer loop (128 bit - full size)
.lo move.l a2,d2 ;D2 = actual bits to compare (synclen)
moveq #32,d6
cmp.l d6,d2
bhs .s1
move.l d2,d6 ;D6 = actual synclen
.s1
move.l #SYNCLEN*8,d5
sub.l d2,d5 ;D5 = actual syncoffset
bfextu (SYNCLEN,a1){d5:d6},d3 ;D3 = mask
bfextu (a1){d5:d6},d4 ;D4 = sync
and.l d3,d4
;inner loop (32 bit)
.li addq.l #1,d0
cmp.l d1,d0
bhs .err
bfextu (a0){d0:d6},d7
and.l d3,d7
cmp.l d4,d7
bne .li
sub.l d6,d2
beq .end
moveq #32,d6
cmp.l d6,d2
bhs .s2
move.l d2,d6 ;D6 = actual synclen
.s2 move.l #SYNCLEN*8,d5
sub.l d2,d5 ;D5 = actual syncoffset
bfextu (SYNCLEN,a1){d5:d6},d3 ;D3 = mask
bfextu (a1){d5:d6},d4 ;D4 = sync
and.l d3,d4
bfextu (4,a0){d0:d6},d7
and.l d3,d7
cmp.l d4,d7
bne .lo
sub.l d6,d2
beq .end
moveq #32,d6
cmp.l d6,d2
bhs .s3
move.l d2,d6 ;D6 = actual synclen
.s3 move.l #SYNCLEN*8,d5
sub.l d2,d5 ;D5 = actual syncoffset
bfextu (SYNCLEN,a1){d5:d6},d3 ;D3 = mask
bfextu (a1){d5:d6},d4 ;D4 = sync
and.l d3,d4
bfextu (8,a0){d0:d6},d7
and.l d3,d7
cmp.l d4,d7
bne .lo
sub.l d6,d2
beq .end
move.l #SYNCLEN*8,d5
sub.l d2,d5 ;D5 = actual syncoffset
bfextu (SYNCLEN,a1){d5:d2},d3 ;D3 = mask
bfextu (a1){d5:d2},d4 ;D4 = sync
and.l d3,d4
bfextu (12,a0){d0:d2},d7
and.l d3,d7
cmp.l d4,d7
bne .lo
.end movem.l (a7)+,_MOVEMREGS
rts
.err moveq #-1,d0
bra .end
;##########################################################################
;----------------------------------------
; print sync
; IN: A0 = APTR sync
; OUT: -
_printsync movem.l d2-d3/a2-a3,-(a7)
move.l a0,a3 ;a3 = sync
lea (SYNCLEN,a3),a0
moveq #SYNCLEN-1,d3
.cnt tst.b (a0)+
dbne d3,.cnt
cmp.w #1,d3
bge .ndef
moveq #1,d3
.ndef lea (SYNCLEN-1,a3),a2
move.w d3,d2
bsr .ps
lea (_amp),a0
bsr _Print
lea (2*SYNCLEN-1,a3),a2
move.w d3,d2
bsr .ps
movem.l (a7)+,_MOVEMREGS
rts
.ps sub.w d2,a2
.p lea (_lx),a0
moveq #0,d0
move.b (a2)+,d0
move.l d0,-(a7)
move.l a7,a1
bsr _PrintArgs
add.w #4,a7
dbf d2,.p
rts
;----------------------------------------
; print value as bit count in hex
; IN: D0 = ULONG value to print
; OUT: -
_printbitlen move.l d0,d1
lsr.l #3,d0
and.l #7,d1
movem.l d0-d1,-(a7)
lea (_bitlen),a0
move.l a7,a1
bsr _PrintArgs
addq.l #8,a7
rts
_TxtBold lea (_txt_bold),a0
bra _Print
_TxtReset lea (_txt_reset),a0
bra _Print
_PrintBold pea (a0)
bsr _TxtBold
move.l (a7)+,a0
bsr _Print
bra _TxtReset
;##########################################################################
CNOP 0,4
; even odd
; --sync-- ffTTSSGG ffTTSSGG
_syncstd dc.l 0,$44894489,$55000000,$55000000 ;finds one sector
dc.l 0,$ffffffff,$ff000000,$ff000000
_syncstd2 dc.l 0,$44894489,$55000005,$55000001 ;finds first sector after gap
dc.l 0,$ffffffff,$ff000055,$ff000055
_syncgrem dc.l 0,0,$44894489,$44895555
dc.l 0,0,$ffffffff,$ffffffff
_txt_help dc.b "Synopsis:",10
dc.b " WWarp filename[.wwp] [command] [tracks] [args] [options...]",10
dc.b "valid commands are:",10
dc.b " C - create wwarp file (default)",10
dc.b " F - force tracks to std format",10
dc.b " D - dump tracks",10
dc.b " args = [sync[&mask]][,[syncno][,[len][,off]]]",10
dc.b " I - print informations about wwarp file",10
dc.b " L - set track length",10
dc.b " args = length",10
dc.b " M - merge two wwarp files together",10
dc.b " args = wwarp-to-add",10
dc.b " P - pack wwarp file",10
dc.b " R - remove tracks from a wwarp file",10
dc.b " S - save tracks",10
dc.b " W - write wwarp file back to disk",10
dc.b " Y - set sync",10
dc.b " args = sync[&mask]",10
dc.b 0
_txt_nl dc.b 10,0
_txt_bold dc.b 155,"1m",0
_txt_reset dc.b 155,"22m",0
_txt_badtracks dc.b "Invalid [tracks] specification",10,0
_txt_badcmd dc.b "Invalid [command]",10,0
_extension dc.b ".wwp",0
_txt_create dc.b 'creating new wwarp file "%s" from DF%ld: %ld tracks',10,0
_txt_exists dc.b 'file "%s" already exists, overwrite ? (yN) ',0
_trackdisk dc.b "trackdisk.device",0
_diskprogress dc.b "reading track %ld",0
_openfile dc.b "open file",0
_txt_writing dc.b "writing file",0
_txt_reading dc.b "reading file",0
_seeking dc.b "seeking",0
_trklens dc.b " single"
_trklen dc.b " raw trklen=$%lx.%ld",10,0
_txt_badfile dc.b "file is not a WWarp file.",10,0
_txt_badstruct dc.b "structure of WWarp file is corrupt.",10,0
_txt_infohead1 dc.b "created by: ",0
_txt_infohead2 dc.b 10,"created at: %s %s",10,0
_txt_infohead3 dc.b "last modified at: %s %s",10,0
_txt_infohead4 dc.b "total tracks in file: %ld",10
dc.b "trk type flags length wlen sync",10,0
_txt_infotrack dc.b "%3ld %s ",0
_lx dc.b "%02lx",0
_amp dc.b "&",0
_length dc.b " $%4lx.%ld $%04lx ",0
_bitlen dc.b "$%lx.%ld",0
_needlength dc.b "length must be specified",10,0
_wronglength dc.b "invalid length",10,0
_notinfile1 dc.b "warning, tracks %ld",0
_notinfile2 dc.b ",%ld",0
_notinfile3 dc.b " aren't contained in wwarp file!",10,0
_lenbadtype dc.b "error track %d, type must be raw!",10,0
_lentobig dc.b "error track %d, length cannot be larger than stored track size!",10,0
_forcebadtype dc.b "skipping track %d, no raw mfm-data!",10,0
_forcenosync dc.b "skipping track %d, sync not found",10,0
_forceshortmfm dc.b "skipping track %d, insufficient mfm-data",10,0
_forcebad dc.b "skipping track %d, could not decode",10,0
_needsync dc.b "sync must be specified",10,0
_badsync dc.b "invalid sync",10,0
_dump1 dc.b "track=%ld type=%s flags=%lc len=$%4lx.%ld wlen=$%04lx sync=",0
_badarg dc.b "Invalid [arg]",10,0
_offerr dc.b "error, offset out of range",10,0
_syncfound1 dc.b "sync ",0
_syncfound2 dc.b " found %ld times, using offset ",0
_unknowntt dc.b "unknown track type",10,0
_corrupt dc.b "wwarp file is corrupt",0
_wtrack dc.b "writing track %ld fmt %s",10,0
_notracks dc.b "error, tracks must be specified",10,0
_decoded dc.b " format %s ($%lx bytes)",10,0
_nosync dc.b "no sync found",10,0
_noport dc.b "can't create MessagePort",0
_noioreq dc.b "can't create IO-Request",0
_readdisk dc.b "read disk",0
_opendevice dc.b "open device",0
_badkick dc.b "Sorry, WWarp requires Kickstart 2.0 or better.",10,0
_badcpu dc.b "Sorry, WWarp requires a 68020 or better.",10,0
_readargs dc.b "read arguments",0
;subsystems
_dosname DOSNAME
_template dc.b "Filename/A" ;file to create
dc.b ",Command" ;operation to perform
dc.b ",Tracks" ;tracks affected
dc.b ",Argument" ;depending on operation
dc.b ",BPT=BytesPerTrack/K" ;
dc.b ",Unit/N/K" ;drive unit to read from/write to
dc.b ",NoStd/S" ;dont try to read std format
dc.b ",RetryCnt/N/K" ;how many retries
dc.b 0
;##########################################################################
SECTION c,BSS,CHIP
_chipbuf dsb MAXTRACKLEN
;##########################################################################
SECTION g,BSS
_Globals dsb gl_SIZEOF
;##########################################################################
END