**************************************************************** * Download system - ST receiver version 1.00 Reloc_Addr equ $200 * Set Exec_Type as follows: * 0 for execution from desktop. * 1 for execution from auto folder. * 2 for execution from boot sector. Exec_Type equ 2 ifne Exec_Type=0 output a:\download.prg endc ifne Exec_Type=1 output a:\auto\download.prg endc PSG equ $ffff8800 MFP_GPIP equ $fffffa01 MFP_DDR equ $fffffa05 Palette0 equ $ffff8240 floprd equ 8 XBIOS Read sector. flopwr equ 9 XBIOS Write sector. conws equ 9 GEMDOS Print string. **************************************************************** * Place the downloader on a boot sector. ifne Exec_Type=2 Make_Boot_Sector move.w #1,-(sp) Read 1 sector. move.w #0,-(sp) Side 1. move.w #0,-(sp) Track 0. move.w #1,-(sp) Sector 1. move.w #0,-(sp) Drive A. clr.l -(sp) pea Boot_Sector_Buffer move.w #floprd,-(sp) trap #14 lea 20(sp),sp tst.w d0 bne Read_Error lea Downloader(pc),a0 lea Boot_Sector_Buffer,a1 move.w #$601c,(a1) Place a BRA.S to start lea $1e(a1),a1 of boot code. move.w #512-2-$1e-1,d7 .Loop_1 move.b (a0)+,(a1)+ Copy boot code into boot dbra d7,.Loop_1 sector. lea Boot_Sector_Buffer,a0 Calculate checksum. move.w #(510/2)-1,d7 clr.w d0 .Loop_2 add.w (a0)+,d0 dbra d7,.Loop_2 move.w #$1234,d1 sub.w d0,d1 move.w d1,(a0) Set checksum. move.w #1,-(sp) Write 1 sector. move.w #0,-(sp) Side 1. move.w #0,-(sp) Track 0. move.w #1,-(sp) Sector 1. move.w #0,-(sp) Drive A. clr.l -(sp) pea Boot_Sector_Buffer move.w #flopwr,-(sp) trap #14 lea 20(sp),sp tst.w d0 bne Write_Error Exit clr.w -(sp) trap #1 Read_Error lea Read_Error_String(pc),a0 bra.s Error_Exit Write_Error lea Write_Error_String(pc),a0 Error_Exit pea (a0) move.w #conws,-(sp) trap #1 addq.l #6,sp bra.s Exit Boot_Sector_Buffer ds.b 512 Read_Error_String dc.b 'Unable to read boot sector!',0 Write_Error_String dc.b 'Unable to write boot sector!',0 even endc **************************************************************** * Downloader. opt p+ MUST be relocatable code. * Regs used: * A6: PSG registers. * A5: PSG registers. * A4: BUSY line port address. * A3: Palette 0 register address. * D7: Bit number for BUSY line. Downloader ifne Exec_Type<2 clr.l -(sp) Enter supervisor mode. move.w #$20,-(sp) trap #1 endc move.w #$2700,sr lea Downloader_1(pc),a0 Relocate downloader. lea Reloc_Addr,a1 move.w #Downloader_1_Length-1,d7 .Reloc_Loop move.b (a0)+,(a1)+ dbra d7,.Reloc_Loop jmp Reloc_Addr Execute downloader. Downloader_1 Re_Entry_Addr move.w #$2700,sr lea R_Stack(pc),sp lea Re_Entry_Addr(pc),a0 Set TRAP #0 for downloader re-entry. move.l a0,$80.w lea PSG.w,a6 A6 and A5 point to PSG registers. lea 2(a6),a5 move.b #7,(a6) Set port A for output and port B move.b #%01111111,(a5) for input. move.b MFP_DDR.w,d0 Set BUSY line for input. and.b #%11111110,d0 move.b d0,MFP_DDR.w lea MFP_GPIP.w,a4 A4 holds BUSY line port address. moveq #0,d7 D7 holds bit number for BUSY line. lea Palette0.w,a3 * Enter downloader. move.b #15,(a6) Select PSG register for port B. move.w #$070,(a3) Set screen green. Wait_Header bsr Get_Byte Wait for 4 byte header. Bad_Header cmp.b #'S',d0 bne.s Wait_Header bsr Get_Byte cmp.b #'X',d0 bne.s Bad_Header bsr Get_Byte cmp.b #'0',d0 bne.s Bad_Header bsr Get_Byte cmp.b #'1',d0 bne.s Bad_Header * Receive download info. bsr Get_Long_Word Receive download address. move.l Long_Word(pc),a0 bsr Get_Long_Word Receive download length. move.l Long_Word(pc),d1 bsr Get_Long_Word Receive execution address. move.l Long_Word(pc),a1 * Receive data. move.l #$07400077,d4 Colours. move.l #256,d2 Block length. Download_Loop_R2 move.w d4,(a3) Change screen colour. swap d4 sub.l d2,d1 bls.s Receive_Last move.w d2,d3 subq.w #1,d3 Download_Loop_R1 btst d7,(a4) Wait for BUSY line to go high. beq.s Download_Loop_R1 move.b (a6),(a0)+ Get byte from printer port. dbra d3,Download_Loop_R1 bra.s Download_Loop_R2 Receive_Last add.l d2,d1 subq.w #1,d1 Download_Loop_R3 btst d7,(a4) Wait for BUSY line to go high. beq.s Download_Loop_R3 move.b (a6),(a0)+ Get byte from printer port. dbra d1,Download_Loop_R3 * Downloading complete. move.w #$070,(a3) Set screen green. jmp (a1) Execute code. * Receive a byte into D0. Get_Byte btst d7,(a4) Wait for BUSY line to go high. beq.s Get_Byte move.b (a6),d0 Get byte from printer port. rts * Receive a long word (Note: A2 and D6 are brown dogs). Get_Long_Word lea Long_Word(pc),a2 bsr.s Get_Byte_M bsr.s Get_Byte_M bsr.s Get_Byte_M lsr.l #5,d6 Wait 18 clock cycles. Get_Byte_M btst d7,(a4) Wait for BUSY line to go high. beq.s Get_Byte_M move.b (a6),(a2)+ Get byte from printer port. rts **************************************************************** ifne Exec_Type<2 Long_Word ds.l 1 Big fat long word gets dumped here. ds.l 100 Loads of stack space. R_Stack elseif Long_Word ds.l 1 R_Stack equ *+16 Only a small stack is needed when * creating a boot sector. Downloader_Length equ *-Downloader ifne Downloader_Length>(512-2-$1e) Downloader will not fit on boot sector endc endc Downloader_1_Length equ *-Downloader_1 end