* Dateien auf Band sichern im Z1013-Headersave-Format * Daten an RTS der seriellen Schnittstelle * Anwendung als Programm und Accessory lauff„hig output .PRG include "C:\TOSDEF.S" include "C:\AESDEF.S" CON equ 2 IKBD equ 4 giselect equ $FF8800 giwrite equ $FF8802 giread equ $FF8800 *** Start ************************************************* section text start lea mystack(pc),sp lea start-256(pc),a6 * Anfang Basepage tst.l $24(a6) * Zeiger auf Vaterprozež beq.s accessory * Accessory move.l #$100,a5 * L„nge Basepage add.l $0C(a6),a5 * + L„nge Text add.l $14(a6),a5 * + L„nge DATA add.l $1C(a6),a5 * + L„nge BSS move.l a5,-(sp) * Ben”tigte L„nge move.l a6,-(sp) * Anfangsadresse clr.w -(sp) call_gemdos Mshrink lea $0C(sp),sp appl_init move.w d0,ap_id bsr rscinit graf_mouse #ARROW * Maus als Zeiger bsr title cmp.w #7,knopf * Sichern? bne.s ap_end ap_loop bsr main form_alert #1,#t_again cmp.w #1,d0 beq.s ap_loop ap_end appl_exit call_gemdos Pterm0 accessory appl_init move.w d0,ap_id menu_register ap_id,#mymenu bsr rscinit wait_for_event evnt_mesag #messagebuf cmp.w #40,messagebuf * Accessory angeklickt? bne.s wait_for_event wind_update #BEG_MCTRL bsr title cmp.w #7,knopf * Sichern? bne.s end_acc bsr main end_acc wind_update #END_MCTRL bra.s wait_for_event section data t_again dc.b '[2][ | M”chten Sie noch eine | Datei sichern?][Ja| Nein ]',0 mymenu dc.b ' Z1013-Headersave',0 section bss ap_id ds.w 1 messagebuf ds.w 8 ds.l 200 * Stack mystack ds.l 1 include "C:\AESLIB.S" *** Dialogboxen ******************************************* section data * Objektbaum der ersten Dialogbox DIALOG1 dc.w -1,1,8,G_BOX,LASTOB,OUTLINED dc.l $21100 dc.w 0,0,37,14 dc.w 2,-1,-1,G_STRING,NONE,NORMAL * erstes Kindobjekt dc.l d1ln1 dc.w 2,1,36,1 dc.w 3,-1,-1,G_STRING,NONE,NORMAL dc.l d1ln2 dc.w 2,2,35,1 dc.w 4,-1,-1,G_STRING,NONE,NORMAL dc.l d1ln3 dc.w 2,4,35,1 dc.w 5,-1,-1,G_STRING,NONE,NORMAL dc.l d1ln4 dc.w 2,5,35,1 dc.w 6,-1,-1,G_STRING,NONE,NORMAL dc.l d1ln5 dc.w 2,6,24,1 dc.w 7,-1,-1,G_STRING,NONE,NORMAL dc.l d1ln6 dc.w 8,9,20,1 dc.w 8,-1,-1,G_BUTTON,EXIT+SELECTABLE,NORMAL dc.l d1ln7 dc.w 5,12,9,1 dc.w 0,-1,-1,G_BUTTON,LASTOB+EXIT+SELECTABLE,NORMAL dc.l d1ln8 dc.w 23,12,9,1 d1ln1 dc.b 'Dieses PRG/ACC sichert Dateien im',0 d1ln2 dc.b 'Z1013-Headersave-Format auf Band.',0 d1ln3 dc.b '- Tonsignal an RTS (MODEM-Buchse)',0 d1ln4 dc.b '- nur fr ATARI ST/E mit MC 68000',0 d1ln5 dc.b ' ohne Cache und 8 MHz',0 d1ln6 dc.b '(c) Jens Mller 1992',0 d1ln7 dc.b ' Sichern ',0 d1ln8 dc.b ' Abbruch ',0 * Objektbaum der zweiten Dialogbox DIALOG2 dc.w -1,1,17,G_BOX,LASTOB,OUTLINED dc.l $21100 dc.w 0,0,34,17 dc.w 2,-1,-1,G_STRING,NONE,NORMAL * šberschrift dc.l d2ln1 dc.w 5,1,24,1 dc.w 3,-1,-1,G_STRING,NONE,NORMAL * Datei dc.l d2ln2 dc.w 2,3,6,1 dc.w 4,-1,-1,G_FTEXT,EDITABLE,NORMAL dc.l d2td1 dc.w 10,3,16,1 dc.w 5,-1,-1,G_STRING,NONE,NORMAL * Typ dc.l d2ln3 dc.w 2,4,6,1 dc.w 6,-1,-1,G_FTEXT,EDITABLE,NORMAL dc.l d2td2 dc.w 10,4,1,1 dc.w 7,-1,-1,G_STRING,NONE,NORMAL * log. AADR dc.l d2ln4 dc.w 2,6,24,1 dc.w 8,-1,-1,G_FTEXT,EDITABLE,NORMAL dc.l d2td3 dc.w 28,6,4,1 dc.w 9,-1,-1,G_STRING,NONE,NORMAL * log. SADR dc.l d2ln5 dc.w 2,7,24,1 dc.w 10,-1,-1,G_FTEXT,EDITABLE,NORMAL dc.l d2td4 dc.w 28,7,4,1 dc.w 11,-1,-1,G_STRING,NONE,NORMAL * log. EADR pt_eadr dc.l d2ln6 dc.w 2,8,24,1 dc.w 12,-1,-1,G_STRING,NONE,NORMAL pw_eadr dc.l t_eadr dc.w 28,8,5,1 dc.w 13,-1,-1,G_BOX,NONE,NORMAL * leere Box zum dc.l $1100 * Text l”schen dc.w 2,10,5,1 dc.w 14,-1,-1,G_STRING,NONE,NORMAL * Save-ADDR s_addr dc.l t_addr dc.w 2,10,5,1 dc.w 15,-1,-1,G_STRING,NONE,NORMAL * Abbruch-Text pt_brk dc.l d2ln7 dc.w 2,12,31,1 dc.w 16,-1,-1,G_BOX,NONE,NORMAL * Teil l”schen dc.l $1100 dc.w 1,8,32,6 dc.w 17,-1,-1,G_BUTTON,EXIT+SELECTABLE,NORMAL dc.l d1ln7 * Buttom Sichern dc.w 5,15,9,1 dc.w 0,-1,-1,G_BUTTON,LASTOB+EXIT+SELECTABLE,NORMAL dc.l d1ln8 * Buttom Abbruch dc.w 20,15,9,1 d2ln1 dc.b '*** Z1013-Headersave ***',0 d2ln2 dc.b 'Datei:',0 d2ln3 dc.b 'Typ :',0 d2ln4 dc.b 'logische Anfangsadresse:',0 d2ln5 dc.b 'logische Startadresse :',0 d2ln6 dc.b 'logische Endadresse :',0 d2ln7 dc.b 'Abbruch: UNDO gedrckt halten.',0 d2td1 dc.l fname,s_able16,l_able16 dc.w 3,6,0,$1180,0,-1,17,17 d2td2 dc.l t_type,s_able1,l_able1 dc.w 3,6,0,$1180,0,-1,2,2 d2td3 dc.l t_aadr,s_able4,l_able4 dc.w 3,6,0,$1180,0,-1,5,5 d2td4 dc.l t_sadr,s_able4,l_able4 dc.w 3,6,0,$1180,0,-1,5,5 s_able16 dc.b '____________' s_able4 dc.b '___' s_able1 dc.b '_',0 l_able16 dc.b 'XXXXXXXXXXXX' l_able4 dc.b 'XXX' l_able1 dc.b 'X' empty dc.b 0 section bss t_type ds.b 2 t_aadr ds.b 6 t_sadr ds.b 6 t_eadr ds.b 6 t_addr ds.b 6 *** Koordinatendarstellung in Objekten umwandeln ********** * INPUT: a4: Zeiger auf Objektbaum * d4: Anzahl der Objekte - 1 section text ch_kdn rsrc_obfix a4,#0 lea 24(a4),a4 * Adresse n„chstes Objekt dbf d4,ch_kdn rts *** Resourcen initialisieren ****************************** rscinit lea DIALOG1(pc),a4 * Objektb„ume vorbereiten moveq.w #8,d4 bsr.s ch_kdn form_center #DIALOG1 move.w int_out+2,d1x move.w int_out+4,d1y move.w int_out+6,d1b move.w int_out+8,d1h lea DIALOG2(pc),a4 moveq.w #17,d4 bsr.s ch_kdn form_center #DIALOG2 move.w int_out+2,d2x move.w int_out+4,d2y move.w int_out+6,d2b move.w int_out+8,d2h rts section bss d1x ds.w 1 d1y ds.w 1 d1b ds.w 1 d1h ds.w 1 d2x ds.w 1 d2y ds.w 1 d2b ds.w 1 d2h ds.w 1 *** Anfangsdialogbox - aktueller Pfad ********************* section text title form_dial #FMD_START,d1x,d1y,d1b,d1h,d1x,d1y,d1b,d1h move.w d1x,d0 lsr.w #1,d0 * d1x/2 move.w d1y,d1 lsr.w #1,d1 * d1y/2 form_dial #FMD_GROW,d0,d1,#1,#1,d1x,d1y,d1b,d1h objc_draw #DIALOG1,#ROOT,#MAX_DEPTH,d1x,d1y,d1b,d1h form_do #DIALOG1,#0 move.w d0,knopf objc_change #DIALOG1,d0,d1x,d1y,d1b,d1h,#NORMAL,#0 move.w d1x,d0 lsr.w #1,d0 * d1x/2 move.w d1y,d1 lsr.w #1,d1 * d1y/2 form_dial #FMD_SHRINK,d0,d1,#1,#1,d1x,d1y,d1b,d1h form_dial #FMD_FINISH,d1x,d1y,d1b,d1h,d1x,d1y,d1b,d1h call_gemdos Dgetdrv * aktuelles LW ermitteln addq.l #2,sp add.w #'A',d0 lea path(pc),a0 move.b d0,(a0)+ move.b #':',(a0)+ clr.w -(sp) * aktueller Pfad move.l a0,-(sp) call_gemdos Dgetpath addq.l #8,sp lea t_all(pc),a0 lea path(pc),a1 bsr.w strcat rts section data t_all dc.b '*.*',0 section bss path ds.b 128 file ds.b 128 fname ds.b 128 even knopf ds.w 1 *** Grundroutinen ***************************************** section text * h„ngt den String a0 an den von a1 an strcat tst.b (a1)+ bne.s strcat subq.l #1,a1 * kopiert einen String von a0 nach a1 strcpy move.b (a0)+,(a1)+ bne.s strcpy rts * letztes Vorkommen des Zeichens in d0.b im String a0 suchen strrchr move.l a0,a1 sub.l a0,a0 subq.l #1,a1 chr1 addq.l #1,a1 cmp.b (a1),d0 bne.s chr2 move.l a1,a0 chr2 tst.b (a1) bne.s chr1 rts * Datei schliežen f_close move.w f_handle,-(sp) call_gemdos Fclose addq.l #4,sp rts atxt cmp.b #$20,(a0)+ beq.s atxt subq.l #1,a0 rts * String a0 in Hexzahl umwnadeln in d0 inhex bsr.s atxt clr.l d0 inhex1 move.b (a0),d1 sub.b #'0',d1 bcs.s inhex3 cmp.b #9,d1 bls.s inhex2 subq.b #7,d1 cmp.b #$A,d1 bcs.s inhex3 cmp.b #$F,d1 bls.s inhex2 sub.b #$20,d1 cmp.b #$A,d1 bcs.s inhex3 cmp.b #$F,d1 bhi.s inhex3 inhex2 lsl.l #4,d0 and.l #$F,d1 or.l d1,d0 addq.l #1,a0 bra.s inhex1 inhex3 rts * d0.w als Hexzahl nach a0 umwandeln htoa moveq.w #3,d2 htoa1 rol.w #4,d0 move.w d0,d1 and.w #$F,d1 add.w #'0',d1 cmp.w #'9',d1 bls.s htoa2 addq.w #7,d1 htoa2 move.b d1,(a0)+ dbf d2,htoa1 clr.b (a0) rts *** Dateiauswahl ****************************************** * Erzeugen der Dateiauswahlbox * INPUT: a0: Zeiger auf gltigen Pfad * a1: Zeiger auf Dateiname * a2: Puffer fr vollst„ndigen Dateinamen * OUTPUT: d0: 0 = Abbruch, 1 = OK section text file_select movem.l a0-a2,f_help movem.l f_help,a0-a2 * vollst„ndigen Namen generieren fsel_input a0,a1 movem.l f_help,a0-a2 * vollst„ndigen Namen generieren move.l a2,a1 * Pfad kopieren bsr.w strcpy move.l a2,a0 move.w #'\',d0 bsr.w strrchr * letzten Backslash suchen addq.l #1,a0 cmp.l #1,a0 bne.s f_file1 move.l a2,a0 * nicht gefunden f_file1 move.l a0,-(sp) movem.l f_help,a0-a2 move.l a1,a0 move.l (sp)+,a1 bsr.w strcpy movem.l f_help,a0-a2 move.w int_out+2,d0 rts section bss f_help ds.l 3 *** main ************************************************** section text main lea path(pc),a0 lea fname(pc),a1 clr.b (a1) lea file(pc),a2 bsr file_select tst.w d0 beq m_end graf_mouse #BUSYBEE clr.w -(sp) * Quelldatei ”ffnen, nur Lesen pea file call_gemdos Fopen addq.l #8,sp tst.w d0 bpl.s main1 graf_mouse #ARROW form_alert #1,#not_open bra m_end main1 move.w d0,f_handle move.w #2,-(sp) * Filel„nge ermitteln move.w f_handle,-(sp) clr.l -(sp) call_gemdos Fseek lea $A(sp),sp move.l d0,f_length clr.w -(sp) * Dateizeiger auf Anfang zurck move.w f_handle,-(sp) clr.l -(sp) call_gemdos Fseek lea $A(sp),sp tst.l f_length bne.s main2 bsr.w f_close * Dateil„nge null graf_mouse #ARROW form_alert #1,#no_byte bra m_end main2 move.l f_length,-(sp) * Puffer allokieren call_gemdos Malloc addq.l #6,sp tst.l d0 bne.s main3 bsr.w f_close * zu wenig Speicher graf_mouse #ARROW form_error #8 bra.w m_end main3 move.l d0,buffer move.l d0,-(sp) * Datei einlesen move.l f_length,-(sp) move.w f_handle,-(sp) call_gemdos Fread lea $C(sp),sp cmp.l f_length,d0 beq.s main4 bsr.w f_close * Lesefehler graf_mouse #ARROW form_alert #1,#read_error bra m_free main4 bsr.w f_close * Quelldatei schliežen graf_mouse #ARROW * zweite Dialogbox clr.b t_type * zweite Dialogbox vorbereiten clr.b t_aadr * Edit-Felder leeren clr.b t_sadr move.l #empty,pt_eadr * logische Endadresse move.l #empty,pw_eadr * noch nicht sichtbar move.l #empty,s_addr * + Save-ADDR move.l #empty,pt_brk * + Abbruchtext form_dial #FMD_START,d2x,d2y,d2b,d2h,d2x,d2y,d2b,d2h move.w d2x,d0 lsr.w #1,d0 * d2x/2 move.w d2y,d1 lsr.w #1,d1 * d2y/2 form_dial #FMD_GROW,d0,d1,#1,#1,d2x,d2y,d2b,d2h wr_agn objc_draw #DIALOG2,#ROOT,#MAX_DEPTH,d2x,d2y,d2b,d2h form_do #DIALOG2,#3 move.w d0,knopf cmp.w #16,d0 bne dia1end graf_mouse #M_OFF * Kopf erzeugen lea t_aadr(pc),a0 * log. Anfangsadresse bsr inhex move.w d0,aadr lea head(pc),a0 move.b d0,(a0)+ lsr.w #8,d0 move.b d0,(a0)+ move.w aadr,d0 add.l f_length,d0 subq.w #1,d0 * log. Endadresse move.w d0,eadr move.b d0,(a0)+ lsr.w #8,d0 move.b d0,(a0)+ lea t_sadr(pc),a0 * log. Startadresse bsr inhex lea head+4(pc),a0 move.b d0,(a0)+ lsr.w #8,d0 move.b d0,(a0) lea head+12(pc),a0 * Kopfkennung move.b t_type,d0 tst.b d0 bne.s m_head1 moveq.w #$20,d0 m_head1 move.b d0,(a0)+ move.b #$D3,(a0)+ move.b #$D3,(a0)+ move.b #$D3,(a0)+ lea fname,a1 moveq.w #15,d0 m_head2 tst.b (a1) * Ende Dateiname? beq.s m_head3 move.b (a1)+,(a0)+ dbf d0,m_head2 bra.s diafull m_head3 move.b #$20,(a0)+ dbf d0,m_head3 * Kopf kreiert diafull move.l #d2ln6,pt_eadr * Dialogbox vervollst„ndigen move.l #t_eadr,pw_eadr move.l #t_addr,s_addr move.l #d2ln7,pt_brk move.w eadr,d0 lea t_eadr(pc),a0 bsr htoa objc_draw #DIALOG2,#10,#MAX_DEPTH,d2x,d2y,d2b,d2h objc_draw #DIALOG2,#11,#MAX_DEPTH,d2x,d2y,d2b,d2h move.w #$00E0,logaddr * Kopf schreiben move.l #head,i_addr pea slblk call_xbios Supexec addq.l #6,sp move.w aadr,d0 * ersten Datenblock schreiben move.w d0,logaddr bsr shwaddr move.l buffer,i_addr pea slblk call_xbios Supexec addq.l #6,sp objc_draw #DIALOG2,#14,#MAX_DEPTH,d2x,d2y,d2b,d2h move.l f_length,d0 add.l buffer,d0 move.l d0,e_addr * phys. Endadresse lp_save move.w logaddr,d0 bsr shwaddr move.l i_addr,d0 cmp.l e_addr,d0 bcc.s d_end pea ssblk call_xbios Supexec addq.l #6,sp bsr tst_brk tst.w d0 beq.s lp_save d_end bsr ch_key graf_mouse #M_ON bra wr_agn dia1end bsr ch_key move.w d2x,d0 lsr.w #1,d0 * d2x/2 move.w d2y,d1 lsr.w #1,d1 * d2y/2 form_dial #FMD_SHRINK,d0,d1,#1,#1,d2x,d2y,d2b,d2h form_dial #FMD_FINISH,d2x,d2y,d2b,d2h,d2x,d2y,d2b,d2h * zweite Dialogbox beendet m_free move.l buffer,-(sp) call_gemdos Mfree addq.l #6,sp m_end rts ch_key objc_change #DIALOG2,knopf,d2x,d2y,d2b,d2h,#NORMAL,#1 rts section data not_open dc.b '[2][ | Datei kann nicht | ge”ffnet werden!][ Abbruch ]',0 no_byte dc.b '[2][ | Dateil„nge ist | NULL!][ Abbruch ]',0 read_error dc.b '[2][ | Datei kann nicht | gelesen werden!][ Abbruch ]',0 section bss aadr ds.w 1 eadr ds.w 1 f_handle ds.w 1 f_length ds.l 1 buffer ds.l 1 e_addr ds.l 1 head ds.b 32 * Kopfpuffer *** Test auf Abbruch ************************************** * OUTPUT: d0.w: 0 -> OK, -1 -> Abbruch * Tatstaturpuffer wird geleert section text tst_brk move.w #CON,-(sp) call_bios Bconstat addq.l #4,sp tst.w d0 beq.s brk_end move.w #CON,-(sp) call_bios Bconin addq.l #4,sp cmp.b #3,d0 beq.s k_brk swap d0 cmp.w #97,d0 bne.s tst_brk k_brk moveq.l #-1,d0 brk_end rts *** aktuelle Adresse anzeigen ***************************** shwaddr lea t_addr(pc),a0 bsr htoa objc_draw #DIALOG2,#12,#MAX_DEPTH,d2x,d2y,d2b,d2h objc_draw #DIALOG2,#13,#MAX_DEPTH,d2x,d2y,d2b,d2h rts *** Block sichern ***************************************** * * 1 Block im Z1013-HS-Format ber RTS sichern * * INPUT : i_addr : Zeiger auf zu sichernden Block * logaddr: logische Speicheradresse im Z1013 * OUTPUT: i_addr, logaddr werden um 32 erh”ht * * d0-d4/a0-a2 werden zerst”rt slblk move.w #$1000,d4 bra.s sablk ssblk move.w #13,d4 sablk move.w #$13,-(sp) * Tastatur abschalten move.w #IKBD,-(sp) call_bios Bconout addq.l #6,sp move.w sr,status or.w #$0700,sr * alle Interrupts sperren * Synchronschwingung sablk1 move.w #502,d0 * 8 sablk2 dbf d0,sablk2 * + 502*12 + 10 nop nop * + 8 bsr ch_ph * + 18 + 80 dbf d4,sablk1 * + 12 = 6160 moveq.w #2,d0 * 4 sablk3 dbf d0,sablk3 * 2*12+10 nop nop * + 8 = 46 moveq.w #1,d1 * 1 volle Schwingung doppelte Frequenz sablk4 move.w #243,d0 * 8 sablk5 dbf d0,sablk5 * + 243*12 + 10 nop nop * + 8 bsr ch_ph * + 18 + 80 dbf d1,sablk4 * + 12 = 3052 moveq.w #89,d0 * nach kurzer Zeit sablk6 dbf d0,sablk6 move.w logaddr,d0 * Blockadresse sichern move.w d0,d4 * d4 Prfsumme bsr sa_wrd add.w #$20,logaddr * 24 moveq.w #78,d0 * insgesamt 1024+56 Takte sablk7 dbf d0,sablk7 * zwischen den zwei "sawrd" nop nop moveq.w #15,d3 * 16 Datenw”rter sichern sablk8 move.l i_addr,a0 * 20 move.b 1(a0),d0 * 12 lsl.w #8,d0 * 6 + 2*8 = 22 move.b (a0),d0 * 8 addq.l #2,a0 * 8 move.l a0,i_addr * 20 add.w d0,d4 * Prfsumme, 4 bsr.s sa_wrd dbf d3,sablk10 moveq.w #89,d0 sablk9 dbf d0,sablk9 nop move.w d4,d0 bsr.s sa_wrd * Prfsumme sichern move.w status,d0 * Statusregister wiederherstellen move.w d0,sr * Interrupts freigeben move.w #$11,-(sp) * Tastatur reaktivieren move.w #IKBD,-(sp) call_bios Bconout addq.l #6,sp rts sablk10 moveq.w #84,d0 sablk11 dbf d0,sablk11 nop bra.s sablk8 * n„chstes Datenwort sichern * 1 Wort (d0.w) auf Band sichern sa_wrd moveq.w #16,d1 * 16 Bit sa_wd1 lsr.w #1,d0 * Bit in Carry, 8 Takte bcc.s sa_low * + bei "0" Sprung -> 10, sonst 8 moveq.w #24,d2 * + 4 sa_hi dbf d2,sa_hi * + 19*12 + 10 nop nop * + 8 bra.s sa_bt * + 10 = 320 Takte sa_low moveq.l #17,d2 * 4 Takte salow1 dbf d2,salow1 * + 17*12 + 10 Takte bsr.s ch_ph * 18 + 80 = 316 Takte, bei "0" sa_bt moveq.w #118,d2 * 4 Takte sa_bt1 dbf d2,sa_bt1 * + 118*12 + 10 nop * + 4 bsr.s ch_ph * + 18 + 80 = 1532 Takte subq.w #1,d1 * 4 bne.s nx_bt * + 8/10 rts * 16 nx_bt moveq.w #95,d2 * 4 nx_bt1 dbf d2,nx_bt1 * + 95*12 + 10 nop * + 4 bra.s sa_wd1 * + 10 = 1168 * 1 Phasenwechsel erzeugen, dauert 80 Takte ch_ph move.b #14,giselect * IOA move.b giread,d2 bchg #3,d2 * Phase „ndern move.b d2,giwrite rts section bss status ds.w 1 logaddr ds.w 1 * logische Adresse im Z1013 i_addr ds.l 1 * Zeiger auf Byte in Datei *** Ende ************************************************** END