********************************************************************** * Widget Download system - ST receiver * ********************************************************************** OPT c+ ; Case sensitive. VER_MAJOR equ 4 VER_MINOR equ 0 STACK_SIZE equ 1024 PSG_SELECT equ $ffff8800 PSG_READ equ $ffff8800 PSG_WRITE equ $ffff8802 GPIP equ $fffffa01 SECTION TEXT Start clr.l -(sp) ; Supervisor mode. move.w #32,-(sp) trap #1 addq #6,sp move.l d0,stack_save Restart move.w #$2700,sr lea Stack(pc),sp lea Trap0_Handler(pc),a0 move.l a0,$80.w lea title_str(pc),a0 ; Show the title. bsr show_str lea workspace_str(pc),a0 ; Show the workspace. bsr show_str move.l #Stack,d0 bsr show_long moveq #'-',d0 bsr show_char move.l $42e.l,d0 bsr show_long moveq #13,d0 bsr show_char moveq #10,d0 bsr show_char moveq #10,d0 bsr show_char lea (PSG_SELECT).w,a5 lea (PSG_WRITE).w,a4 lea (GPIP).w,a3 move.b #7,(a5) ;Select mixer I/O control. move.b #%01111111,(a4) ;Set port B to input. move.b #14,(a5) ;Select Port A. move.b #%00100110,(a4) .wake_up cmp.b #$01,$fffffc02.w ;Escape key? beq exit move.b #15,(a5) ;Select I/O port B. cmp.b #$81,(a5) ;Read port B. bne.s .wake_up bsr GetByte bsr GetLong ;Get type of transfer. cmp.l #"FILE",d0 beq get_file cmp.l #"DATA",d0 beq get_data bra Restart exit move.w #$2300,sr move.w #7,-(sp) ; Wait for a key. trap #1 addq #2,sp move.l stack_save,-(sp) ; User mode. move.w #32,-(sp) trap #1 addq #6,sp clr.w -(sp) trap #1 get_data ; Do a transfer to memory. bsr GetLong ; Get header info. move.l d0,Address bsr GetLong move.l d0,Length bsr GetLong move.l d0,Execute lea address_str(pc),a0 ; Show the start address. bsr show_str move.l Address,d0 bsr show_long lea length_str(pc),a0 ; Show the length. bsr show_str move.l Length,d0 bsr show_long lea execute_str(pc),a0 ; Show the execute address. bsr show_str move.l Execute,d0 bsr show_long move.l Address,a6 ; Get the data. move.l Length,d6 bsr download bsr GetByte ; Get zero end byte. move.l Execute,d0 ; Execute the code, if needed. beq Restart move.l d0,a0 jsr (a0) bra Restart ; If just data transfer, ; wait for the next transfer. get_file ; Do a transfer to file. lea file_str(pc),a0 bsr show_str bsr GetLong ; Get header info. move.l d0,d6 lea filename,a6 clr.b (a6,d6.w) bsr download ; Get the file name. lea filename(pc),a0 ; Show the file name. bsr show_str bsr GetLong ; Get the file size. move.l d0,d7 lea file_size(pc),a0 ; Show the file size. bsr show_str move.l d7,d0 bsr show_long bsr create_file move.l d7,d5 ; Download the file in .chunks ; small chunks so we can lea file_buffer,a6 ; get files larger than move.l d5,d6 ; available memory. cmp.l #16384,d6 bls.s .no_clip move.l #16384,d6 .no_clip sub.l d6,d5 move.l d6,d7 bsr download ; Get a chunk of data. move.l d7,d6 ; Write it to disk. bsr write_file tst.l d5 bne.s .chunks bsr GetByte ; Get zero end byte. bsr close_file bra Restart create_file clr.w -(sp) pea filename(pc) move.w #60,-(sp) trap #1 addq #8,sp move.w d0,handle rts write_file pea file_buffer(pc) move.l d6,-(sp) move.w handle,-(sp) move.w #64,-(sp) trap #1 lea 12(sp),sp rts close_file move.w handle,-(sp) move.w #62,-(sp) trap #1 addq #4,sp rts download bsr GetByte move.b d0,(a6)+ subq.l #1,d6 bne.s download rts Trap0_Handler move.b #15,(PSG_SELECT).w cmp.b #$81,(PSG_READ).w beq Restart rte GetByte btst.b #0,(a3) ; Wait for byte read signal. bne.s GetByte move.b #15,(a5) ; Get the byte. move.b (a5),d0 move.b #14,(a5) ; Signal that we've got the byte. move.b #%00000110,(a4) .wait2 btst.b #0,(a3) ; Wait for byte not ready signal. beq.s .wait2 move.b #%00100110,(a4) ; Signal that we're done. rts GetLong bsr GetByte move.b d0,d3 bsr GetByte lsl.l #8,d3 move.b d0,d3 bsr GetByte lsl.l #8,d3 move.b d0,d3 bsr GetByte lsl.l #8,d3 move.b d0,d3 move.l d3,d0 rts show_str pea (a0) move.w #9,-(sp) trap #1 addq #6,sp rts show_char move.w d0,-(sp) move.w #2,-(sp) trap #1 addq #4,sp rts show_long move.l d0,-(sp) moveq #'$',d0 bsr show_char move.l (sp)+,d0 moveq #8-1,d1 .loop rol.l #4,d0 move.l d0,-(sp) and.w #$000f,d0 add.b #'0',d0 cmp.b #'9',d0 ble.s .decimal add.b #('A'-'9'-1),d0 .decimal bsr show_char move.l (sp)+,d0 dbf d1,.loop rts SECTION DATA title_str dc.b 27,'E' dc.b 'WIDGET DOWNLOADER',13,10 dc.b 'VERSION ' dc.b VER_MAJOR+'0' dc.b '.' dc.b (VER_MINOR/10)+'0' dc.b (VER_MINOR-(VER_MINOR/10))+'0' dc.b 13,10 dc.b '(C) 1992-1995',13,10 dc.b 'LEO SKIRENKO',13,10 dc.b 'PHILIP WATTS',13,10 dc.b 0 workspace_str dc.b 10,'WORKSPACE = ' dc.b 0 even address_str dc.b 13,10,"Address: ",0 length_str dc.b 13,10,"Length: ",0 execute_str dc.b 13,10,"Execute: ",0 file_str dc.b 13,10,"File: ",0 file_size dc.b 13,10,"Length: ",0 even SECTION BSS Address ds.l 1 Length ds.l 1 Execute ds.l 1 handle ds.w 1 filename ds.b 80 file_buffer ds.b 16384 stack_save ds.l 1 ds.b STACK_SIZE Stack