home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
AmigActive 13
/
AACD13.ISO
/
AACD
/
Games
/
WHDLoad
/
Extra
/
wwarp.lha
/
wwarp
/
src
/
cmdc.s
next >
Wrap
Text File
|
2000-08-06
|
12KB
|
660 lines
;*---------------------------------------------------------------------------
; :Program. cmdc.s
; :Contents. command c - create
; :Author. Bert Jahn
; :EMail. wepl@whdload.org
; :Address. Franz-Liszt-Straße 16, Rudolstadt, 07404, Germany
; :Version $Id: cmdc.s 1.3 2000/08/06 12:23:17 jah Exp jah $
; :History. 12.06.00 separated from wwarp.asm
; 28.06.00 adapted for _cmdwork
; 06.08.00 inter sector gap check improved
; :Requires. OS V37+, MC68020+
; :Copyright. ©1998-2000 Bert Jahn, All Rights Reserved
; :Language. 68020 Assembler
; :Translator. Barfly V2.9
; :To Do.
;---------------------------------------------------------------------------*
_cmd_create
;print announcement
move.l #MAXTRACKS-1,d0
moveq #0,d1
.pa_0 bftst (gl_tabarg+wtt_tab,GL){d0:1}
beq .pa_1
addq.l #1,d1
.pa_1 dbf d0,.pa_0
move.l d1,-(a7)
move.l (gl_rd_unit,GL),-(a7)
pea (gl_filename,GL)
lea (_txt_create),a0
move.l a7,a1
bsr _PrintArgs
add.w #12,a7
;open the device
move.l #IOTDF_INDEXSYNC,d0
lea (gl_ioi,GL),a0
bsr _OpenDevice
tst.l d0
beq .nodevice
;set file header
lea (gl_headout+wfh_ctime,GL),a0
move.l a0,d1
move.l (gl_dosbase,GL),a6
jsr (_LVODateStamp,a6)
;main loop
move.l #CMDF_OUT,d0 ;flags
sub.l a0,a0 ;cbdata
lea .tracktable,a1 ;cbtt
lea .tracks,a2 ;cbt
bsr _cmdwork
;close device
lea (gl_ioi,GL),a0
bsr _CloseDevice
.nodevice
rts
.tracktable lea (gl_tabarg,GL),a0
lea (gl_tabout,GL),a1
bsr _copytt
moveq #-1,d0
rts
.tracks move.l d0,d6 ;D6 = actual track
;progress output
lea (_diskprogress),a0 ;output progress
move.l d6,-(a7)
move.l a7,a1
bsr _PrintArgs
addq.l #4,a7
bsr _FlushOutput
;read track
move.l (gl_rd_retry,GL),d7 ;D7 = read retries
.retryloop
;check CTRL-C pressed
bsr _CheckBreak ;check for CTRL-C
tst.l d0
bne .error
;read track
move.l d6,d0
bsr _cmdc_read
beq .error
tst.l (gl_rd_nostd,GL)
bne .nonstd
;try to decode
move.l (gl_rd_bpt,GL),d0
lsl.l #3,d0
move.l d6,d1
bsr _cmdc_decode
move.w d0,d4 ;D4 = type
beq .nonstd
move.l d1,d5 ;D5 = length
move.w d2,d3 ;D3 = flags
;progress output decoded
move.w d4,(gl_trk+wth_type,GL)
bsr _gettt
move.l d0,-(a7)
move.l a0,-(a7)
lea (_decoded),a0
move.l a7,a1
bsr _PrintArgs
addq.l #8,a7
;write
bra .write
.nonstd
;try to calculate track length
move.l (gl_rd_bpt,GL),d0
bsr _cmdc_CalcTrackSize
move.l d0,d5 ;D5 = length
beq .nolen
;progress output raw single
lea (_trklens),a0
move.l d5,d3
lsr.l #3,d3 ;bytes
move.l d5,d4
and.l #7,d4 ;bits
movem.l d3-d4,-(a7)
move.l a7,a1
bsr _PrintArgs
addq.l #8,a7
;write
bfclr ([gl_fastbuf,GL]){d5:7} ;alignment
move.w #TT_RAW,d4 ;D4 = type
move.w #TFF_INDEX|TFF_RAWSINGLE,d3 ;D3 = flags
bra .write
.nolen subq #1,d7
bmi .writefull
bsr _cmdc_movehead
bra .retryloop
.writefull
;progress output raw
lea (_trklen),a0
clr.l -(a7)
move.l (gl_rd_bpt,GL),d5
move.l d5,-(a7)
lsl.l #3,d5 ;D5 = length
move.l a7,a1
bsr _PrintArgs
add.w #8,a7
;write
move.w #TT_RAW,d4 ;D4 = type
move.w #TFF_INDEX,d3 ;D3 = flags
;write track
.write move d6,(gl_trk+wth_num,GL)
move d4,(gl_trk+wth_type,GL)
move d3,(gl_trk+wth_flags,GL)
move.l d5,(gl_trk+wth_len,GL)
clr.l (gl_trk+wth_wlen,GL)
lea (gl_trk+wth_sync,GL),a0
lea (gl_trk+wth_mask,GL),a1
move.b #SYNCLEN-1,d0
.hc clr.b (a0)+
clr.b (a1)+
dbf d0,.hc
moveq #-1,d0
rts
.error moveq #0,d0
rts
;----------------------------------------
; read raw mfm track
; IN: D0 = UWORD track number
; OUT: D0 = BOOL true on success
; _fastbuf contains mfm data
_cmdc_read
;read mfm
move.l (gl_ioi,GL),a1
move.l (gl_chipbuf,GL),(IO_DATA,a1)
move.l d0,(IO_OFFSET,a1)
move.l (gl_rd_bpt,GL),(IO_LENGTH,a1)
move.w #ETD_RAWREAD,(IO_COMMAND,a1)
clr.b (IO_ERROR,a1)
move.l (gl_execbase,GL),a6
jsr (_LVODoIO,a6)
move.l (gl_ioi,GL),a1
move.b (IO_ERROR,a1),d0
bne .err
;copy mfm data to fast mem for better performance
move.l (gl_chipbuf,GL),a0
move.l (gl_fastbuf,GL),a1
cmp.l a0,a1
beq .ok
move.l (gl_rd_bpt,GL),d0
.cp move.l (a0)+,(a1)+
subq.l #4,d0
bcc .cp
.ok moveq #-1,d0
rts
.err lea (_readdisk),a0
bsr _PrintErrorTD
moveq #0,d0
rts
;----------------------------------------
; try to decode track as known format
; IN: D0 = ULONG length of raw mfm-data in bits
; D1 = UWORD track number
; gl_fastbuf mfm data
; OUT: D0 = ULONG track type identified
; D1 = ULONG decoded data length in bits!
; D2 = ULONG track flags
; gl_fastbuf contains decoded data
_cmdc_decode movem.l d5-d7,-(a7)
move.l d0,d7
move.l d1,d6
bsr _cmdc_d_dos
tst.l d0
bne .std
move.l d7,d0
move.l d6,d1
bsr _cmdc_d_grem
tst.l d0
bne .grem
bra .no
.std move.l #TT_STD,d0 ;type
move.l #$1600,d1 ;length
moveq #0,d2 ;flags
bra .pack
.grem move.l #TT_GREM,d0 ;type
move.l #$1800,d1 ;length
moveq #0,d2 ;flags
.pack
;all lw's equal
move.l (gl_fastbuf,GL),a0
move.l d1,d6
lsr.l #2,d6
move.l (a0)+,d7
.eq cmp.l (a0)+,d7
dbne d6,.eq
bne .neq
move.l #4,d1
or.w #TFF_LEQ,d2
bra .end
.neq
;each sector with lw's incremented
cmp.l #$1600,d1
bne .ninc
move.l (gl_fastbuf,GL),a0
lea ($1600,a0),a1
moveq #11-1,d5
.inc2 moveq #$200/4-2,d6
move.l (a0)+,d7
move.l d7,(a1)+
.inc addq.l #1,d7
cmp.l (a0)+,d7
dbne d6,.inc
dbne d5,.inc2
bne .ninc
moveq #11-1,d5
.inc3 move.l -(a1),(-$1600,a1)
dbf d5,.inc3
move.l #4*11,d1
or.w #TFF_SLINC,d2 ;sector long incremented
bra .end
.ninc
.end lsl.l #3,d1 ;length in bits
movem.l (a7)+,d5-d7
rts
.no moveq #0,d0
bra .end
;----------------------------------------
; decode standard amigados track
; IN: D0 = ULONG length of raw mfm-data in bits
; D1 = UWORD track number
; _fastbuf mfm data
; OUT: D0 = BOOL true on success
; _fastbuf contains decoded data
NSTRUCTURE locals,0
NWORD lc1_trknum
NALIGNLONG
NLABEL lc1_SIZEOF
_cmdc_d_dos movem.l d2-d7,-(a7)
link LOC,#lc1_SIZEOF
or.w #$ff00,d1
move.w d1,(lc1_trknum,LOC)
move.l d0,d5 ;D5 = mfm-length
moveq #-1,d4 ;D4 = last sync offset
;search inter sector gap
.search move.l d4,d0
addq.l #1,d0 ;offset
move.l d5,d1 ;buffer length
move.l (gl_fastbuf,GL),a0
lea (_syncstd),a1 ;44894489...
bsr _searchsync
tst.l d0
bmi .no
tst.l d4
bmi .sd4
move.l d0,d1
sub.l d4,d1
cmp.l #$440*8,d1 ;$440 is standard sector length
bne .gap
.sd4 move.l d0,d4
bra .search
.gap
;d4 = last sector before gap
;d0 = first sector after gap
move.l d0,d6 ;D6 = first sector
;check that inter sector gap is set to zeros
sub.l d4,d0
sub.l #($440-4)*8+33,d0 ;length of gap in bits to check
bmi .no
move.l #$aaaaaaaa,d3
move.l (gl_fastbuf,GL),a0
bra .cmpin
.cmp bfextu (a0){d6:32},d1
cmp.l d1,d3
bne .no
.cmpin subq.l #4,a0
sub.l #32,d0
bcc .cmp
bfextu (a0){d6:32},d1
neg.l d0
lsl.l d0,d1
lsl.l d0,d3
cmp.l d1,d3
bne .no
;check that remaining mfm data is sufficent
sub.l d6,d5 ;in bits
cmp.l #11*$440*8,d5
blo .no
;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
bclr #31,d0
cmp.l #$2aaaaaaa,d0
bne .no
bsr .getlw
cmp.l #$44894489,d0
bne .no
moveq #0,d3 ;D3 = chksum
bsr .getlwd ;sector header
subq.b #1,d0 ;num sectors before gap
cmp.b d7,d0
bne .no
lsr.l #8,d0 ;sector number 0..10
cmp.b #10,d0
bhi .no
bclr d0,d4
beq .no ;same sector again
; move.b d0,($1600+gl_tmpbuf.w,GL,d7.w)
moveq #0,d1
move.b d0,d1
mulu #$200,d1
lea (gl_tmpbuf.w,GL,d1.l),a1
lsr.l #8,d0 ;track number
cmp.w (lc1_trknum,LOC),d0
bne .no
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
moveq #-1,d0
bra .quit
.no moveq #0,d0
.quit unlk LOC
movem.l (a7)+,d2-d7
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
;----------------------------------------
; decode gremlin track (lotus)
; IN: D0 = ULONG length of raw mfm-data in bits
; D1 = UWORD track number
; _fastbuf mfm data
; OUT: D0 = BOOL true on success
; _fastbuf contains decoded data
_cmdc_d_grem movem.l d2-d7,-(a7)
move.l d0,d5 ;D5 = mfm-length
move.w d1,d4 ;D4 = track number
;search sync
moveq #0,d0 ;offset
move.l d5,d1 ;buffer length
move.l (gl_fastbuf,GL),a0
lea (_syncgrem),a1
bsr _searchsync
tst.l d0
bmi .no
;skip sync(448944894489) and unknown word(5555)
add.l #4*16,d0
move.l d0,d6 ;offset
;check that remaining mfm data is sufficent
sub.l d6,d5 ;in bits
cmp.l #(2*$1800+4)*8,d5
blo .no
;decode track
move.l (gl_fastbuf,GL),a0 ;A0 = mfm buffer
lea (gl_tmpbuf,GL),a1 ;A1 = decoded
move.w #$bff,d7
move.l #$55555555,d2
moveq #0,d3
.loop bsr .get
move.w d1,(a1)+
add.w d1,d3
dbf d7,.loop
bsr .get
cmp.w d1,d3
bne .no
bsr .get
bchg #0,d1
cmp.w d1,d4
bne .no
;copy buffer
move.w #$1800/4-1,d0
lea (gl_tmpbuf,GL),a0
move.l (gl_fastbuf,GL),a1
.copy move.l (a0)+,(a1)+
dbf d0,.copy
moveq #-1,d0
bra .quit
.no moveq #0,d0
.quit movem.l (a7)+,d2-d7
rts
.get bfextu (a0){d6:32},d0
addq.l #4,a0
and.l d2,d0
move.w d0,d1
swap d0
add.w d1,d1
add.w d0,d1
rts
;----------------------------------------
; calculate track length if possible
; IN: D0 = ULONG length of raw mfm-data in bytes
; _fastbuf mfm data
; OUT: D0 = ULONG size in bits if successful, otherwise 0
_cmdc_CalcTrackSize
movem.l d2-d7/a2,-(a7)
move.l d0,d5 ;D5 = mfm-length
move.l (gl_fastbuf,GL),a0 ;A0 = buffer start
move.l #MINTRACKLEN*8,d0 ;D0 = actual offset (track size)
.s move.l a0,a1 ;A1 = actual p1
move.l d0,d1
lsr.l #5,d1 ;/32
lsl.l #2,d1 ;*4
lea (a1,d1.l),a2
.n bfextu (a1){d0:32},d7
cmp.l (a1)+,d7
bne .ne
cmp.l a1,a2
bhi .n
move.l d0,d1
and.w #31,d1 ;how many bits are left to compare ?
beq .eq
bfextu (a1){d0:d1},d7
bfextu (a1){0:d1},d6
cmp.l d6,d7
bne .ne
.eq movem.l (a7)+,_MOVEMREGS
rts
.ne addq.l #1,d0
move.l d0,d1
add.l d1,d1 ;track must fit two times in the raw buffer
add.l #7,d1 ;round up
lsr.l #3,d1 ;in bytes
cmp.l d5,d1
bls .s
moveq #0,d0
movem.l (a7)+,_MOVEMREGS
rts
;----------------------------------------
; move head
; IN: D6 = ULONG actual track
; OUT: -
_cmdc_movehead
move.l d6,d0
lsr.l #1,d0 ;cylinder
lea (.data),a0
cmp.w (a0),d6
beq .calc
.init
move.w d6,(a0) ;set new track
clr.w (2,a0) ;offset
.calc
move.w (2,a0),d1 ;offset
addq.w #2,(2,a0)
cmp.w #.liste-.list,d1
beq .init
add.w (4,a0,d1.w),d0
bpl .1
moveq #1,d0
.1 cmp.w #MAXTRACKS/2,d0
blo .2
move.w #MAXTRACKS/2-2,d0
.2
move.l d0,-(a7)
IFD DEBUG
lea .s,a0
move.l a7,a1
bsr _PrintArgs
bra .ss
.s dc.b "»%ld",0
EVEN
.ss
ELSE
move.l #"."<<24,-(a7)
move.l a7,a0
bsr _Print
addq.l #4,a7
ENDC
bsr _FlushOutput
move.l (a7)+,d0
mulu #2*$1600,d0
add.l #$1600,d0
move.l (gl_ioi,GL),a1
move.l d0,(IO_OFFSET,a1)
move.w #ETD_SEEK,(IO_COMMAND,a1)
clr.b (IO_ERROR,a1)
move.l (gl_execbase,GL),a6
jsr (_LVODoIO,a6)
move.l (gl_ioi,GL),a1
move.b (IO_ERROR,a1),d0
bne .err
rts
.err lea (_readdisk),a0
bra _PrintErrorTD
.data dc.w -1 ;actual cylinder
dc.w 0 ;offset in list
.list dc.w 0,0,1,0,0,0,-1,0
.liste