Dokonca mám vlastne IRQ Level 3 a DMA celkom vypínam.
Samozrejme IRQ Level 2 nemením.
Asi takto:
*** BootLoader.S by Photon *** ;NOTE: PC-relative code is PREFERRED. ;To write to disk in Asm-One, use the command WS0 Boot 0 2 followed by CC0 LoaderVars =$100 ;Useful variables, see CPUinfo: Loader =$120 ;start of load script MyUserStack=$7fffc ;SSP is at a safe place, but set user ;stack. MFMsync =$4489 ;AmigaDOS standard sync marker. MFMlen =12980 ;Legacy trackdata read length in bytes ShortWt:MACRO ;CPU-independent nop;nop replacement tst.w (a6) ENDM *** Boot Block starts here *** Boot: dc.b 'DOS',0 dc.l 0,880 BootCode: ;gathers some data, turns off OS, copies itself to $100 *--- Fetch system info ---* move.l 4.w,a6 ;execbase (will soon be destroyed) move.l 294(a6),d4 ;CPUinfo in lowest byte for your use. sub.l a4,a4 ;VBR will always be 0 when booting ;from floppy. No GetVBR needed. *--- Fastmem available? ---* move.l #$20004,d1 ;fast+largest jsr -216(a6) ;AvailMem() move.l d0,d5 sub.l #2048,d5 ;leave room for stacks to grow moveq #4,d1 jsr -198(a6) ;AllocMem() and.l #-8,d0 move.l d0,a5 ;Start Address *--- OS off ---* ;you're nice'n all, but now you die. lea $dff002,a6 ;Loader uses this custom base addr tst.w (a6) ;wait out blitter .wblit: btst #6,(a6) bne.s .wblit move.l #$7fff7fff,d1 move.l d1,$9a-2(a6) ;disable interrupts & req move.w d1,$9c-2(a6) ;play it again Sam sub.w #$20,d1 ;don't affect Sprite DMA until Vblank move.w d1,$96-2(a6) ;disable DMA lea MyUserStack,a7 ;some safe place compatible with ;platform requirements *--- Copy rest of code/data to fixed address ---* lea CopyStart(PC),a0 lea (LoaderVars).w,a1 moveq #(BootE-CopyStart)/8,d2 .copyl: move.l (a0)+,(a1)+ move.l (a0)+,(a1)+ dbf d2,.copyl JMP (Loader).w ;Info from Exec passed in 4 registers ******************** $100.w ******************** CopyStart: CPUinfo: dc.l 0 ;$100 FastMemSize: dc.l 0 ;$104 SysVBR: dc.l 0 ;$108 FastMemStart: dc.l 0 ;$10c MFMcyl: dc.w 0 MFMhead: dc.w 0 MFMdrv: dc.w 0 MFMchk: dc.l 0 dc.w 0 ;reserved for your use. LoadVector: bra.w LoadMFMB ;for external calls, JSR ($11c).w LoadScript: ;At $120, sysinfo in 4 regs, a6=$dff002 lea CPUinfo(PC),a3 ;Use this for PC-rel in a pinch. movem.l d4/d5/a4/a5,(a3) bsr.s WaitEOF lea NullCop(PC),a0 move.l a0,$80-2(a6) ;blank copper move.w #$87d0,$96-2(a6) ;enable DMA (sprites enabled when used) *--- load first part ---* lea $42000,a0 ;to dest addr moveq #2,d0 ;from sector 2 move.w #-9,d1 ;load 9 sectors (- to trigger Step0) jsr ($11c).w ;call LoadVector, and return when done. lea $dff000,a6 ;restore plain custombase addr for demo JMP (a0) ;start demo. ;or use JSR and continue loading script here. *** MFMLoader.S by Photon *** ;requires a6=$dff002 WaitEOF: btst #0,5-2(a6) beq.s WaitEOF .w1: cmp.b #$37,6-2(a6) bne.s .w1 .w2: cmp.b #$37,6-2(a6) ;wait for last PAL line, $138 beq.s .w2 rts LoadMFMB: ;load sectors.a0=dst,d0=startsec.W,d1=nrsecs.W(-=Step0) MOVEM.L D0-D7/A0-A6,-(SP) lea $bfd100,a4 bsr MotorOn tst.w d1 ;if neg length,then Step0 first bpl.s .NoSt0 neg.w d1 .St0: btst #4,$f01(a4) ;head on cyl 0? beq.s .Rdy0 bsr.s StepOut bra.s .St0 .Rdy0: lea MFMcyl(PC),a1 clr.w (a1) .NoSt0: and.l #$ffff,d0 divu #22,d0 ;startcyl sub.w MFMcyl(PC),d0 ;delta-step beq.s .StRdy bmi.s .StOut subq.w #1,d0 .StIn: bsr.s StepIn dbf d0,.StIn bra.s .StRdy .StOut: not.w d0 ;=neg+sub#1 .StOutl:bsr.s StepOut dbf d0,.StOutl .StRdy: swap d0 ;startsec within cyl cmp.w #11,d0 blt.s .Head0 sub.w #11,d0 bra.s .Head1 .Head0: bset #2,(a4) lea MFMhead(PC),a1 clr.w (a1) bsr LoadTrak ;read track+decode beq.s .End .Head1: bclr #2,(a4) ;Head 1 lea MFMhead(PC),a1 move.w #1,(a1) bsr LoadTrak ;read track+decode beq.s .End bsr.s StepIn ;1 cyl forward bra.s .Head0 .End: bsr.s MotorOff MOVEM.L (SP)+,D0-D7/A0-A6 RTS StepOut: bset #1,(a4) lea MFMcyl(PC),a1 subq.w #1,(a1) ShortWt bclr #0,(a4) ShortWt bset #0,(a4) bsr.s StepWt RTS StepIn: bclr #1,(a4) lea MFMcyl(PC),a1 addq.w #1,(a1) ShortWt bclr #0,(a4) ShortWt bset #0,(a4) bsr.s StepWt RTS StepWt: moveq #67,d6 ;wait >3 ms LeaveLine: .loop1: move.b 6-2(a6),d7 .loop2: cmp.b 6-2(a6),d7 beq.s .loop2 dbf d6,.loop1 RTS MotorOn: move.w MFMdrv(PC),d7 addq.w #3,d7 or.b #$78,(a4) bset d7,(a4) ShortWt bclr #7,(a4) ;turns motor on ShortWt bclr d7,(a4) ShortWt .DiskR: btst #5,$f01(a4) ;wait until motor running bne.s .DiskR RTS MotorOff: move.w MFMdrv(PC),d7 addq.w #3,d7 bset d7,(a4) ShortWt bset #7,(a4) ShortWt bclr d7,(a4) RTS LoadTrak: ;load track+decode.a0=dst,d0=secoffs,d1=secsleft MOVE.W D0,-(SP) MOVE.W D1,-(SP) lea (MFMbuf).w,a1 move.w #2,$9c-2(a6) ;Clr Req move.l a1,$20-2(a6) move.w #$8210,$96-2(a6) ;DskEna move.w #MFMsync,$7e-2(a6) move.w #$9500,$9e-2(a6) move.w #$4000,$24-2(a6) move.w #$8000+MFMlen/2,$24-2(a6) ;DskLen(12980)+DmaEn move.w #$8000+MFMlen/2,$24-2(a6) ;start reading MFMdata .Wrdy: btst #1,$1f-2(a6) ;wait until data read beq.s .Wrdy move.w d0,d2 add.w d1,d2 ;highest sec# (d0=lowest) cmp.w #11,d2 ble.s .NoOvr moveq #11,d2 .NoOvr: sub.w d0,d2 ;nrsecs move.l #$55555555,d3 ;and-const move.w d2,d1 subq.w #1,d1 ;loopctr .FindS: cmp.w #MFMsync,(a1)+ ;search for a sync word bne.s .FindS cmp.b (a1),d3 ;search for 0-nibble bne.s .FindS move.l (a1)+,d4 ;decode fmtbyte/trk#,sec#,eow# move.l (a1)+,d5 and.w d3,d4 and.w d3,d5 add.w d4,d4 or.w d5,d4 lsr.w #8,d4 ;sec# sub.w d0,d4 ;do we want this sec? bmi.s .Skip cmp.w d2,d4 blt.s .DeCode .Skip: lea 48+1024(a1),a1 ;nope bra.s .FindS .DeCode:lea 40(a1),a1 ;found a sec,skip unnecessary data move.l a1,d6 lea MFMchk(PC),a1 clr.l (a1) move.l d6,a1 move.l (a1)+,d6 ;decode data chksum.L move.l (a1)+,d5 and.l d3,d6 and.l d3,d5 add.l d6,d6 or.l d5,d6 ;chksum lea 512(a1),a2 add.w d4,d4 ;x512 lsl.w #8,d4 lea (a0,d4.w),a3 ;dest addr for this sec moveq #127,d7 .DClup: move.l (a1)+,d4 move.l (a2)+,d5 and.l d3,d4 and.l d3,d5 eor.l d4,d6 ;EOR with checksum eor.l d5,d6 ;EOR with checksum add.l d4,d4 or.l d5,d4 move.l d4,(a3)+ dbf d7,.DClup ;chksum should now be 0 if correct lea MFMchk(PC),a1 or.l d6,(a1) ;or with track total chksum move.l a2,a1 dbf d1,.FindS ;decode next sec MOVE.W (SP)+,D1 MOVE.W (SP)+,D0 move.l MFMchk(PC),d3 ;track total chksum OK? bne LoadTrak ;no,retry moveq #0,d0 ;set to start of track move.w d2,d3 add.w d3,d3 lsl.w #8,d3 add.w d3,a0 sub.w d2,d1 ;sub #secs loaded RTS NullCop: dc.w $1fc,0 dc.w $100,$0200 dc.w $96,$0020 ;ensure sprite DMA is off until needed dc.w $ffdf,$fffe dc.l -2 BootE: *** Boot Block ends here *** dc.b "BootLoader by Photon/Scoopex" ;pad with random bytes blk.b 1024,0 ;MFMbuf is placed here after bootblock end, $3c0.w or so when copied. MFMbuf =LoaderVars+(BootE-CopyStart) MFMbufE =MFMbuf+MFMlen ;lowest free address. $372e for a full bootblock. END
not.b D1 and.b #$0f, D1 addq #1,D1
Offset Bytes Description ------ ----- ----------- 44 1 Lower four bits are the finetune value, stored as a signed four bit number. The upper four bits are not used, and should be set to zero. Value: Finetune: 0 0 1 +1 2 +2 3 +3 4 +4 5 +5 6 +6 7 +7 8 -8 9 -7 A -6 B -5 C -4 D -3 E -2 F -1
Vložit komentář: