**************************************************************** * Z80-Assembler fr ATARI ST * * Copyright (c) Jens Mller, O-6501 Frankenau, Nr.66 * * 15.08.1992 * * * * Dieser Quelltext darf fr nichtkommerzielle Zwecke * * (Hobby, Lehre usw.) verwendet werden. * * * * Es ist nicht gestattet, das Copyright im Quelltext oder im * * ausfhrbaren Programm zu entfernen oder die Urheberschaft * * anderwertig zu verschleiern oder zu ver„ndern. * * * * Žnderungen zum Original sind entsprechend zu markieren. * **************************************************************** * entwickelt und assembliert mit DevpacST 2.08 von HiSoft * Kommandozeile: [-Option1] [-Option2] [-...] Dateiname output .TTP include "C:\TOSDEF.S" BYTE_BUF_LEN equ 256 MAX_CODE equ 4 * max. Anz. Code-Bytes im Listing *** Macros ************************************************ puts macro string move.l \1,-(sp) call_gemdos Cconws addq.l #6,sp endm error macro number moveq.w \1,d0 bsr out_err endm warning macro text move.l a0,-(sp) lea \1(pc),a0 bsr out_wrn move.l (sp)+,a0 endm *** Hauptprogramm ***************************************** section text move.l 4(sp),a6 * Basepage move.l sp,a5 lea mystack(pc),sp sub.l #$2000,a5 * 8k freigeben cmp.l #buffer,a5 bhi.s buf_ok error #2 bra.w prg_end buf_ok move.l #buffer,source_ptr * Zeiger auf Quelltext move.l a5,end_ptr sub.l a6,a5 * benutzte L„nge move.l a5,-(sp) * Speicher freigeben move.l a6,-(sp) clr.w -(sp) call_gemdos Mshrink lea $C(sp),sp puts #titel clr.w line * aktuelle Zeilennummer clr.w err_ln * Zeilennummer 1. Fehler move.l a6,a0 add.l #$80,a0 * Zeiger auf Kommandozeile clr.l d0 move.b (a0)+,d0 * L„nge Kommandozeile bne.s chk_cmd move.l a0,a5 puts #t_cmd subq.l #1,a5 move.b #122,(a5) move.l a5,-(sp) call_gemdos Cconrs addq.l #6,sp puts #t_cs2nl move.l a5,a0 addq.l #1,a0 clr.l d0 move.b (a0)+,d0 chk_cmd cmp.b #124,d0 bls.s ldt_str move.b #124,d0 ldt_str move.b #0,(a0,d0) * Null-terminiert clr.b A_flag clr.b B_flag clr.b C_flag clr.b J_flag clr.b L_flag clr.b S_flag next_op bsr atxt cmp.b #'-',(a0)+ bne.s tstfile move.b (a0)+,d0 bsr upcase cmp.b #'A',d0 bne.s B_op move.b #-1,A_flag bra.s next_op B_op cmp.b #'B',d0 bne.s C_op move.b #-1,B_flag bra.s next_op C_op cmp.b #'C',d0 bne.s J_op move.b #-1,C_flag bra.s next_op J_op cmp.b #'J',d0 bne.s L_op move.b #-1,J_flag bra.s next_op L_op cmp.b #'L',d0 bne.s S_op move.b #-1,L_flag bra.s next_op S_op cmp.b #'S',d0 bne.s wro_op move.b #-1,S_flag bra.s next_op wro_op error #0 puts #t_crsnl bra.s help tstfile subq.l #1,a0 move.l a0,cmd_ptr tst.b (a0) beq.s help bsr as_main bra.s prg_end help puts #t_help prg_end puts #t_quit call_gemdos Crawcin addq.l #2,sp puts #t_crsnl move.w err_ln,-(sp) * Nummer der 1. fehlerhaften Zeile call_gemdos Pterm section data titel dc.b 'Z80-Assembler Version 1.0 PD',13,10 dc.b '(c) Jens Mller - 15.08.1992',13,10,10,0 t_cmd dc.b 'Kommandozeile: ',0 t_help dc.b 'Format der Kommandozeile:',13,10 dc.b ' [-Option1] [-...] Dateiname',13,10,10 dc.b 'Optionen:',13,10 dc.b ' -A Pass 2 auch bei Fehler in Pass 1',13,10 dc.b ' -B keine Bin„rdatei (*.BIN)',13,10 dc.b ' -C Grož/klein unterscheiden',13,10 dc.b ' -J nur absolute Sprnge',13,10 dc.b ' -L Listing ausgeben (*.LST)',13,10 dc.b ' -S Symboltabelle ausgeben (*.LST)',13,10,10 dc.b 'UNDO Abbruchtaste',13,10,10,0 t_quit dc.b 13,10,'Taste drcken...',0 t_cs2nl dc.b 13,10 t_crsnl dc.b 13,10,0 section bss A_flag ds.b 1 B_flag ds.b 1 C_flag ds.b 1 J_flag ds.b 1 L_flag ds.b 1 S_flag ds.b 1 even cmd_ptr ds.l 1 line ds.w 1 err_ln ds.w 1 *** Fehlerausschrift und Warnungen ************************ section text * Zeilennummer ausgeben o_line move.w d0,-(sp) puts #t_line move.w line,d0 bsr outdez puts #t_dp move.w (sp)+,d0 rts * Warnung ausgeben out_wrn movem.l d0-d2/a0-a2,-(sp) move.l a0,-(sp) bsr o_line puts #t_warn call_gemdos Cconws addq.l #6,sp movem.l (sp)+,d0-d2/a0-a2 rts * d0.w Fehlernumer out_err movem.l d0-d2/a0-a2,-(sp) clr.b term_flag tst.w line beq.s o_er_st * Systemfehler tst.w err_ln bne.s o_errln move.w line,err_ln * 1. fehlerhafte Zeile o_errln bsr.s o_line o_er_st lea err_tab(pc),a0 o_err1 tst.w d0 beq.s o_err3 o_err2 tst.b (a0)+ bne.s o_err2 subq.w #1,d0 bra.s o_err1 o_err3 puts a0 puts #t_crsnl add.w #1,num_err movem.l (sp)+,d0-d2/a0-a2 rts section data t_line dc.b 'Zeile ',0 t_dp dc.b ': ',0 t_warn dc.b 'Warnung! ',0 err_tab dc.b 'Falsche Option',0 * 0 dc.b 'Datei kann nicht ge”ffnet werden',0 * 1 dc.b 'Zu wenig Speicher',0 * 2 dc.b 'Datei kann nicht gelesen werden',0 * 3 dc.b 'Unzul„ssige Marke',0 * 4 dc.b 'Marke mehrfach definiert',0 * 5 dc.b 'Konstante fehlerhaft',0 * 6 dc.b 'Marke nicht gefunden',0 * 7 dc.b 'šberflssiges Zeichen',0 * 8 dc.b 'Marke + ORG nicht erlaubt',0 * 9 dc.b 'EQU ohne Marke',0 * 10 dc.b 'Fehlender Operand',0 * 11 dc.b 'Falscher Operand',0 * 12 dc.b 'Klammer erwartet',0 * 13 dc.b 'Komma erwartet',0 * 14 dc.b 'Operanden passen nicht zusammen',0 * 15 dc.b 'Relative Sprungdistanz zu grož',0 * 16 dc.b 'Unbekannte Mnemonik',0 * 17 dc.b 'Offset zu grož',0 * 18 dc.b 'Zu viele erzeugte Bytes',0 * 19 dc.b 'Fehlendes String-Ende',0 * 20 dc.b 'Ausgabe wrde Quelldatei l”schen',0 * 21 dc.b 'Ausgabeatei kann nicht angelegt werden',0 * 22 dc.b 'Datei kann nicht geschrieben werden',0 * 23 dc.b 'Laufwerk voll',0 * 24 dc.b 'Division durch Null',0 * 25 section bss even num_err ds.w 1 *** Assembler aufrufen ************************************ section text as_main move.l a0,a6 * Dateiname clr.w -(sp) * Quelldatei ”ffnen move.l a6,-(sp) call_gemdos Fopen addq.l #8,sp tst.w d0 bpl.s open_ok error #1 rts open_ok move.w d0,f_handle move.w #2,-(sp) * Dateil„nge ermitteln move.w f_handle,-(sp) clr.l -(sp) call_gemdos Fseek lea $A(sp),sp move.l d0,d7 add.l source_ptr,d0 move.l d0,d1 add.l #$1000,d1 * min. 4k fr anderes cmp.l end_ptr,d1 bcs.s len_ok bsr f_close error #2 rts len_ok move.l d0,symb_ptr clr.w -(sp) * Dateizeiger auf Anfang move.w f_handle,-(sp) clr.l -(sp) call_gemdos Fseek lea $A(sp),sp move.l source_ptr,-(sp) * Quelldatei einlesen move.l d7,-(sp) move.w f_handle,-(sp) call_gemdos Fread lea $C(sp),sp cmp.l d7,d0 beq.s read_ok bsr f_close error #3 rts read_ok move.l symb_ptr,a0 move.b #$1A,(a0)+ move.b #$1A,(a0)+ clr.b (a0) * Symboltabelle l”schen move.l a0,symb_ptr bsr pass1 tst.b A_flag bne.s exe_ps2 tst.w num_err bne.s o_numer exe_ps2 bsr pass2 o_numer puts #t_crsnl clr.l d0 move.w num_err,d0 bsr outdez puts #t_error move.w line,d0 sub.w #1,d0 bsr outdez puts #t_eass1 move.w byte_cnt,d0 bsr outdez puts #t_eass2 rts section data t_error dc.b ' Fehler',13,10,0 t_eass1 dc.b ' Zeilen in ',0 t_eass2 dc.b ' Bytes assembliert.',13,10,0 section bss lab_flag ds.b 1 even source_ptr ds.l 1 symb_ptr ds.l 1 code_ptr ds.l 1 end_ptr ds.l 1 f_handle ds.w 1 *** Pass 1 ************************************************ section text pass1 move.l symb_ptr,a0 move.l a0,code_ptr clr.b (a0) move.w #1,m_pass puts #t_pass1 clr.b end_flag clr.w prg_count * pc des Z80 clr.w line move.l source_ptr,a6 p1_loop addq.w #1,line tst.b end_flag bne.s p1_ret bsr tst_brk cmp.b #$1A,(a6) * Textende? bne.s tst_lab p1_ret rts tst_lab clr.b lab_flag move.l a6,a0 bsr esym cmp.l a0,a6 beq p1_asm move.b #-1,lab_flag * Marke vorhanden cmp.b #':',(a0) bne.s lb_fnd1 addq.l #1,a0 lb_fnd1 cmp.b #'0',(a6) * beginnt Symbol mit Ziffer? bcs.s lb_fnd2 cmp.b #'9',(a6) bhi.s lb_fnd2 lab_err error #4 * ungltiges Symbol bra.w p1asm1 lb_fnd2 bsr atxt move.l a0,a3 * Anfang Befehl bsr etxt move.l a0,a4 * hinter Befehl move.b (a4),d7 clr.b (a4) move.l a3,a0 lea t_EQU(pc),a1 bsr ustrcmp * Test auf EQU move.b d7,(a4) tst.w d0 bne.s lab_pc move.l a4,a0 * EQU-Wert berechnen move.w #2,m_pass bsr term move.w #1,m_pass bsr syntax bra.s lb_entr lab_pc move.w prg_count,d0 * kein EQU -> Marke = pc lb_entr move.l a6,a0 * Symbol in Tabelle eintragen bsr esym move.l a0,a5 move.b (a5),d7 clr.b (a5) move.l a6,a0 * a0: Zeiger auf Symbol move.l a5,d1 sub.l a6,d1 * Symboll„nge in d1.l bsr lab_entry * Symdolwert in d0.w move.b d7,(a5) move.l a5,a6 * hinter Symbol cmp.b #':',(a6) * Doppelpunkt hinter Marke bne.s p1_asm addq.l #1,a6 p1_asm move.l a6,a0 p1asm1 bsr assem move.w d1,prg_count p1_n_ln move.l a6,a0 bsr next_ln move.l a0,a6 bra.w p1_loop * Symbol alphabetisch geordnet in Tabelle eintragen * d0.w Symbolwert * d1.w Symboll„nge * a0 Zeiger auf Symbol (null-terminiert) * a5,a6,d7: unver„ndert lab_entry move.l symb_ptr,a4 move.l a0,a3 move.w d0,d6 l_e_lp tst.b (a4) beq.s l_ent move.l a3,a0 * Zeiger auf Symbol move.l a4,a1 bsr strcmp tst.w d0 bmi.s l_ent * an dieser Stelle eintragen bne.s l_nofnd * String 1 > String 2 error #5 rts l_nofnd tst.b (a1)+ * Symbolende suchen bne.s l_nofnd addq.l #2,a1 * auf n„chsten Eintrag move.l a1,a4 bra.s l_e_lp l_ent move.l code_ptr,a0 * bisheriges Symboltabellenende move.l a0,a1 add.l d1,a1 addq.l #3,a1 * neues Symboltabellenende cmp.l end_ptr,a1 * noch Platz? bcs.s l_m_ok error #2 * kein Platz bra prg_end l_m_ok move.l a1,code_ptr * neues Symboltabellenende clr.b (a1) l_entr1 cmp.l a0,a4 * Tabellenrest nach hinten beq.s l_entr2 move.b -(a0),-(a1) bra.s l_entr1 l_entr2 subq.w #1,d1 * Symboll„nge - 1 l_entr3 move.b (a3)+,d0 * Symbol eintragen tst.b C_flag bne.s l_entr4 bsr upcase * nur grož l_entr4 move.b d0,(a4)+ dbf d1,l_entr3 clr.b (a4)+ move.b d6,(a4)+ * Wert (2 Byte) im INTEL-Format lsr.w #8,d6 * dahinter eintragen move.b d6,(a4)+ rts section data t_pass1 dc.b 'Pass 1',13,10,0 section bss end_flag ds.b 1 even prg_count ds.w 1 m_pass ds.w 1 *** Pass 2 ************************************************ section text pass2 move.w #2,m_pass puts #t_pass2 clr.b end_flag clr.w line add.l #1,code_ptr * Symboltabellenende (0-Byte) bergehen move.l cmd_ptr,a0 * Name Ausgabedatei erzeugen lea lst_path(pc),a1 bsr ustrcpy move.w #'\',d0 * Dateinamenanfang suchen lea lst_path,a0 bsr strrchr cmp.l #0,a0 bne.s pass2_1 lea lst_path(pc),a0 pass2_1 move.l a0,a2 move.w #'.',d0 * Extension suchen bsr strrchr cmp.l #0,a0 beq.s pass2_2 clr.b (a0) * Extension abtrennen pass2_2 lea lst_path(pc),a0 lea bin_path(pc),a1 bsr strcpy move.b L_flag,d0 or.b S_flag,d0 beq.s pass2_5 * kein Listing/Symboltabelle lea t_lst(pc),a0 lea lst_path(pc),a1 bsr strcat move.l cmd_ptr,a0 lea lst_path(pc),a1 bsr ustrcmp tst.w d0 bne.s pass2_3 clr.b L_flag * Flags fr Listing l”schen clr.b S_flag * wrde Quelldatei l”schen error #21 bra.s pass2_5 pass2_3 clr.w -(sp) * Listing-Datei anlegen pea lst_path call_gemdos Fcreate addq.l #8,sp move.w d0,f_handle tst.w d0 bpl.s pass2_4 clr.b L_flag clr.b S_flag error #22 pass2_4 lea f_titel(pc),a0 * Titel fr Listing-Datei schreiben move.l #eoftitl-f_titel,d0 bsr f_write pass2_5 clr.w prg_count * pc des Z80 clr.w byte_cnt * Z„hler fr erzeugte Bytes move.l code_ptr,code_index * Zeiger auf aktuelle Codeposition move.l source_ptr,a6 p2_loop add.w #1,line tst.b end_flag bne.s p2_ret bsr tst_brk cmp.b #$1A,(a6) * Textende? bne p2_mark p2_ret tst.b S_flag beq.s p2ret1 bsr foutnl * Symboltabelle sichern tst.b wr_err_flag bne.s p2ret1 move.l symb_ptr(pc),a3 p2sa_sm tst.b (a3) beq.s p2ret1 move.l a3,a4 p2sasm1 tst.b (a4)+ * Symbolende suchen bne.s p2sasm1 move.b 1(a4),d0 * H-Byte lsl.w #8,d0 move.b (a4),d0 * L-Byte bsr fouthex * Wert schreiben tst.b wr_err_flag bne.s p2ret1 move.l a4,d0 sub.l a3,d0 subq.l #1,d0 * Symboll„nge move.l a3,a0 bsr f_write * Symbolname schreiben tst.b wr_err_flag bne.s p2ret1 bsr foutnl * neue Zeile tst.b wr_err_flag bne.s p2ret1 addq.l #2,a4 move.l a4,a3 bra.s p2sa_sm p2ret1 move.b L_flag,d0 or.b S_flag,d0 beq.s p2ret2 bsr f_close * Listingdatei schliežen p2ret2 tst.b B_flag bne p2ret3 * keine Bin„rdatei move.l code_index,d0 cmp.l code_ptr,d0 beq p2ret3 * keine Bytes erzeugt lea t_bin(pc),a0 * Name Bin„rdatei erzeugen lea bin_path,a1 bsr strcat move.l cmd_ptr,a0 lea bin_path(pc),a1 bsr ustrcmp tst.w d0 bne.s p2sacod error #21 * gleicher Name wie Quelltext bra.s p2ret3 p2sacod clr.w -(sp) * Bin„rdatei anlegen pea bin_path call_gemdos Fcreate addq.l #8,sp move.w d0,f_handle tst.w d0 bpl.s p2save error #22 bra.s p2ret3 p2save move.l code_ptr,a0 * Bin„rdatei schreiben move.l code_index,d0 sub.l a0,d0 bsr f_write bsr f_close p2ret3 rts p2_mark move.l a6,boln * Anfang Zeile clr.b lab_flag move.l a6,a0 * evtl. Marke bergehen bsr esym cmp.l a0,a6 beq.s p2mark1 * keine Marke move.b #-1,lab_flag * Marke vorhanden cmp.b #':',(a0) bne.s p2mark1 addq.l #1,a0 p2mark1 bsr assem move.l a0,a5 * -> erzeugte Bytes move.l d0,d6 * Anzahl Bytes move.w d1,d7 add.w d0,byte_cnt * Z„hler erzeugte Bytes tst.b B_flag bne.s p2_list * keine Bin„rdatei move.l code_index,a1 move.l a1,d1 add.l d0,d1 * Anz. erzeugte Bytes cmp.l end_ptr,d1 * noch Platz fr Code-Bytes? bcs.s p2_code error #2 * Zu wenig Speicher move.b #-1,B_flag * Bin„rdatei unterdrcken bra.s p2_list p2_code tst.w d0 * Code-Bytes ablegen beq.s p2code1 move.b (a0)+,(a1)+ subq.l #1,d0 bra.s p2_code p2code1 move.l a1,code_index p2_list tst.b L_flag beq p2_next clr.l d0 move.b defs_flag,d0 or.b d6,d0 bne.s p2_l_wa lea filebuf(pc),a0 moveq.w #13,d0 * 14 * Space p2_l_sp move.b #$20,(a0)+ * Adresss- und Code-Spalte dbf d0,p2_l_sp * bergehen bra.s p2list4 p2_l_wa move.w prg_count,d0 bsr fouthex * Adresse schreiben tst.b wr_err_flag bne p2_next lea filebuf(pc),a0 moveq.w #MAX_CODE-1,d2 * max. 4 Bytes schreiben p2list1 tst.w d6 * noch Bytes zu schreiben? beq.s p2list2 move.b (a5)+,d0 bsr htoa subq.w #1,d6 bra.s p2list3 p2list2 move.b #$20,(a0)+ * da keine Bytes mehr move.b #$20,(a0)+ p2list3 dbf d2,p2list1 p2list4 move.b #$9,(a0)+ move.w line,d0 bsr uitoa move.b #$9,(a0)+ * Puffer vorbereitet move.l a0,d0 lea filebuf(pc),a0 sub.l a0,d0 * L„nge Puffer bsr f_write tst.b wr_err_flag bne p2_next * Fehler beim Schreiben move.l boln,a0 * Anfang Quelltextzeile move.l a0,a1 p2list5 move.b (a1),d0 * Ende Quelltextzeile suchen beq.s p2list6 cmp.b #$0A,d0 beq.s p2list6 cmp.b #$0D,d0 beq.s p2list6 cmp.b #$1A,d0 beq.s p2list6 cmp.b #$1E,d0 beq.s p2list6 addq.l #1,a1 bra.s p2list5 p2list6 move.l a1,d0 sub.l a0,d0 bsr f_write * Quelltextzeile schreiben tst.b wr_err_flag bne.s p2_next bsr foutnl * Zeilenende tst.b wr_err_flag bne.s p2_next p2list7 tst.w d6 beq.s p2_next add.w #MAX_CODE,prg_count move.w prg_count,d0 bsr fouthex lea filebuf(pc),a0 * restliche erzeugte Bytes schreiben moveq.w #MAX_CODE-1,d2 p2list8 tst.w d6 beq.s p2list9 move.b (a5)+,d0 bsr htoa subq.w #1,d6 bra.s p2lst10 p2list9 move.b #$20,(a0)+ move.b #$20,(a0)+ p2lst10 dbf d2,p2list8 move.b #$0D,(a0)+ * Zeilenende move.b #$0A,(a0)+ move.l a0,d0 lea filebuf(pc),a0 sub.l a0,d0 * L„nge Puffer bsr f_write tst.b wr_err_flag beq.s p2list7 * Fehler -> Ende, sonst nochmal p2_next move.w d7,prg_count p2_n_ln move.l a6,a0 bsr next_ln move.l a0,a6 bra.w p2_loop section data t_pass2 dc.b 'Pass 2',13,10,0 t_lst dc.b '.LST',0 t_bin dc.b '.BIN',0 f_titel dc.b 'Z80-Assembler fr ATARI ST - V1.0 PD',13,10 dc.b 'Copyright (c) Jens Mller 15.08.1992',13,10,13,10 eoftitl * Ende des Titels fr .LST-File section bss even byte_cnt ds.w 1 boln ds.l 1 code_index ds.l 1 lst_path ds.b 128 bin_path ds.b 128 *** Mathematischer Ausdruck berechnen ********************* section text * INPUT : a0 : Zeiger auf ASCII-Term * OUTPUT: d0.w : Wert, a0: zeigt auf n„chstes Zeichen term move.b #-1,term_flag * berechneter Wert ist gltig bsr atxt clr.l d0 cmp.b #'+',(a0)+ * Vorzeichen beq.s frst_c cmp.b #'-',-(a0) beq.s minus frst_c bsr.s tm_mul * erste Konstante next_c cmp.b #'+',(a0) bne.s tst_mi move.w d0,-(sp) addq.l #1,a0 bsr.s tm_mul add.w (sp)+,d0 bra.s next_c tst_mi cmp.b #'-',(a0) beq.s minus rts minus addq.l #1,a0 move.w d0,-(sp) bsr.s tm_mul move.w (sp)+,d1 sub.w d0,d1 exg d0,d1 bra.s next_c * Berechnung eines multiplikativen Ausdrucks tm_mul bsr.s tm_cnst tm_mul1 cmp.b #'*',(a0) bne.s tm_mul2 addq.l #1,a0 move.w d0,-(sp) bsr.s tm_cnst mulu (sp)+,d0 bra.s tm_mul1 tm_mul2 cmp.b #'/',(a0) bne.s tm_mul4 addq.l #1,a0 move.w d0,-(sp) bsr.s tm_cnst move.w d0,d1 clr.l d0 move.w (sp)+,d0 tst.w d1 bne.s tm_mul3 error #25 * Division durch Null bra.s tm_mul4 tm_mul3 divu d1,d0 bra.s tm_mul1 tm_mul4 rts * Berechnung einer Konstante, entweder Literal oder Symbol * muž vorhanden sein * a0: Zeiger auf Konstante * d0: Wert tm_cnst move.b (a0),d0 cmp.w #"'",d0 beq.s tm_cnt1 cmp.w #'"',d0 bne.s tm_cnt3 tm_cnt1 addq.l #1,a0 * char-Zeichen cmp.b 1(a0),d0 beq.s tm_cnt2 error #20 clr.l d0 rts tm_cnt2 clr.l d0 move.b (a0),d0 addq.l #2,a0 rts tm_cnt3 cmp.b #'(',d0 bne.s cn_tstl bsr fkt rts cn_tstl bsr upcase cmp.b #'L',d0 bne.s cn_tsth cmp.b #'(',1(a0) beq.w low cn_tsth cmp.b #'H',d0 cmp.b #'(',1(a0) bne.s cn_goon beq.w high cn_goon clr.l d0 cmp.b #'%',(a0) beq.s inbin cmp.b #'$',(a0) beq.s inhex cmp.b #'#',(a0) beq.s inhex cmp.b #'0',(a0) bcs.w insym cmp.b #'9',(a0) bhi.w insym move.l a0,-(sp) bsr.s inhex1 move.l (sp)+,a1 cmp.b #'H',(a0) beq.s o_hex cmp.b #'h',(a0) beq.s o_hex move.l a1,a0 * Dezimalzahl clr.l d0 indez clr.w d1 move.b (a0),d1 sub.b #'0',d1 bcs.s c_ret cmp.b #9,d1 bhi.s c_ret mulu #10,d0 and.l #$FFFF,d0 add.w d1,d0 addq.l #1,a0 bra.s indez o_hex addq.l #1,a0 * war Hexzahl "XXXXH" c_ret rts inbin addq.l #1,a0 * Bin„rzahl berechnen clr.w d1 move.b (a0),d1 sub.b #'0',d1 bcs.s inbin1 cmp.b #1,d1 bhi.s inbin1 lsl.w #1,d0 or.w d1,d0 bra.s inbin inbin1 cmp.b #'%',-(a0) bne.s bin_ret error #6 bin_ret addq.l #1,a0 rts inhex addq.l #1,a0 * Hexzahl berechnen inhex1 clr.w d1 move.b (a0),d1 exg d0,d1 bsr upcase exg d0,d1 sub.b #'0',d1 bcs.s inhex3 cmp.b #9,d1 bls.s inhex2 sub.b #7,d1 bcs.s inhex3 cmp.b #$F,d1 bhi.s inhex3 inhex2 lsl.w #4,d0 or.w d1,d0 bra.s inhex inhex3 cmp.b #'$',-(a0) beq.s inhex4 cmp.b #'#',(a0) bne.s hex_ret inhex4 error #6 hex_ret addq.l #1,a0 rts * Marke (a0) in Symboltabelle suchen und Wert (d0.w) ausgeben insym movem.l a1-a3/d7,-(sp) cmp.w #2,m_pass beq.s insym1 bsr esym clr.b term_flag * Wert ungltig clr.l d0 bra.s isymret insym1 move.l a0,a2 bsr esym * Symbolende move.l a0,a3 cmp.l a2,a3 * echte Marke? bne.s isym_ok error #11 clr.l d0 bra.s i_sm_rt isym_ok move.b (a3),d7 clr.b (a3) * Symbol abtrennen move.l symb_ptr,a1 * Symboltabellenanfang i_sm_lp tst.b (a1) bne.s insym2 error #7 * nicht gefunden clr.l d0 bra.s i_sm_rt insym2 move.l a2,a0 bsr strcmp tst.w d0 beq.s ism_fnd nx_sym tst.b (a1)+ * n„chster Eintrag bne.s nx_sym add.w #2,a1 * Wert-Bytes bergehen bra.s i_sm_lp ism_fnd clr.l d0 * gefunden move.b 1(a1),d0 * H-Byte lesen (INTEL-Format) lsl.w #8,d0 move.b (a1),d0 * L-Byte i_sm_rt move.b d7,(a3) move.l a3,a0 isymret movem.l (sp)+,a1-a3/d7 rts * Low- bzw. High-Byte eines 16-Bit-Ausdrucks errechnen low addq.l #1,a0 bsr.s fkt and.w #$FF,d0 rts high addq.l #1,a0 bsr.s fkt lsr.w #8,d0 rts fkt cmp.b #'(',(a0)+ bne.s fkt_err bsr.w term cmp.b #')',(a0)+ beq.s fkt_ret fkt_err error #13 clr.l d0 fkt_ret rts section bss term_flag ds.b 1 *** Befehl assemblieren *********************************** section text * Befehl (a0) assemblieren * OUTPUT: a0: zeigt auf erzeugte Bytefolge * d0: Anzahl der Bytes * d1: neuer pc des Z80 (prg_count) assem movem.l d2-d7/a1-a6,-(sp) clr.b defs_flag bsr atxt move.l a0,a4 bsr esym move.l a0,a5 move.b (a5),d7 clr.b (a5) lea tab_i1(pc),a1 lea tab_jp1(pc),a3 lp_w_op tst.b (a1) beq.s se_o_op * kein Befehl mit m”glichen Operand move.l a4,a0 * Befehl im Quelltext bsr ustrcmp tst.w d0 beq.s wop_fnd nx_o_op tst.b (a1)+ bne.s nx_o_op addq.l #4,a3 * n„chste Adresse bra.s lp_w_op wop_fnd move.b d7,(a5) move.l a5,a0 * zeigt hinter Befehl move.l (a3),a3 * Anfangsaddresse der Routine lea byte_buf(pc),a1 * Puffer fr erzeugte Bytes jsr (a3) * Routine anspringen bra asm_ret se_o_op lea tab_i2(pc),a3 * Befehl ohne Operand suchen lp_o_op move.l a4,a0 * Befehl im Quelltext tst.b (a3) beq.s pc_inst move.l a3,a1 bsr ustrcmp tst.w d0 beq.s ins_fnd nx_ist tst.b (a1)+ * n„chster Befehl in Tabelle suchen bne.s nx_ist clr.l d0 move.b (a1)+,d0 * Code-Bytes add.l d0,a1 move.l a1,a3 bra.s lp_o_op ins_fnd clr.l d0 * Befehl gefunden move.b (a1)+,d0 * wieviel Bytes? move.b d7,(a5) bra asm_ret pc_inst move.l a4,a0 * Test auf DEFS,DS lea t_DEFS(pc),a1 bsr ustrcmp * DEFS? tst.w d0 beq.s ds_fnd move.l a4,a0 lea t_DS(pc),a1 bsr ustrcmp * DS? tst.w d0 bne.s asm_org ds_fnd bsr op_num cmp.w #25,d0 beq.s ds_opok error #12 bra.s noinst1 ds_opok add.w prg_count,d1 bsr syntax clr.l d0 move.b #-1,defs_flag move.b d7,(a5) bra.s asmret1 asm_org move.l a4,a0 * Test auf ORG lea t_ORG(pc),a1 bsr ustrcmp tst.w d0 bne.s no_inst tst.b lab_flag beq.s asmorg1 error #9 * Marke + ORG nicht erlaubt asmorg1 move.w m_pass,-(sp) move.w #2,m_pass * auch im ersten Pass ORG berechnen bsr term move.w (sp)+,m_pass move.l d0,d1 cmp.w prg_count,d1 bcc.s asmorg3 warning orgwarn asmorg3 bsr syntax clr.l d0 move.b d7,(a5) bra.s asmret1 no_inst move.l a4,a0 * voller Syntaxcheck noinst1 move.b d7,(a5) bsr syntax1 tst.w d0 beq.s noinst2 error #17 * unbekannte Mnemonik noinst2 clr.l d0 * keine erzeugten Bytes move.w prg_count,d1 * pc unver„ndert bra.s asmret1 asm_ret bsr syntax move.l a1,a0 move.w prg_count,d1 add.w d0,d1 * neuer pc des Z80 asmret1 movem.l (sp)+,d2-d7/a1-a6 rts section data t_DEFS dc.b 'DEFS',0 t_DS dc.b 'DS',0 t_ORG dc.b 'ORG',0 orgwarn dc.b 'ORG im alten Adressbereich',13,10,0 section bss defs_flag ds.b 1 *** Auswertung der Befehle mit m”glichen Operanden ******** * INPUT : a0: zeigt auf das erste Byte hinter den Befehl * a1: zeigt auf nutzbaren Puffer fr erzeugte Bytes * OUTPUT: d0: Anzahl der erzeugten Bytes * a0: zeigt hinter den ausgewerteten Teil * a1: zeigt auf erzeugte Bytefolge * pc des Z80 wird NICHT aktualisiert! (nur bei DEFS, DS) section text op_err1 error #12 * Falscher Operand bra.s op_err4 op_err2 error #15 * Op passen nicht zusammen bra.s op_err4 op_err3 error #14 * Komma erwartet op_err4 bsr etxt bra.s no_byte r_EQU tst.b lab_flag bne.s equ1 error #10 * EQU ohne Marke equ1 bsr atxt * nur fr Syntaxcheck bsr etxt no_byte clr.l d0 move.l d0,a1 rts r_END move.b #-1,end_flag bra.s no_byte r_LD bsr two_op moveq.l #1,d0 * meisten LD-Befehle 1 Byte move.w d2,d1 * und 8 Bit lsl.w #3,d1 * Kennung 1.Op * 8 cmp.w #7,d2 * Kennung 1.Op bhi ld_1_8 * 1.Op ab Kennung 8 auswerten cmp.w #7,d4 bhi.s ld7_8 * 2.Op auf >=8 bei 1.Op bis 7 add.w #$40,d1 * Grundcodebyte add.w d4,d1 * + Kennung 2.Op fr 8 Bit cmp.w #$76,d1 * LD (HL),(HL) ist HALT beq.s op_err2 * -> Fehler move.b d1,(a1) rts * d0 bereits 1 ld7_8 cmp.w #9,d4 bhi.s ld7_12 cmp.w #7,d2 bne.s op_err2 * nur LD A,(BC,DE) erlaubt sub.w #8,d4 * Kennung $00 und $01 lsl.w #4,d4 * $00 oder $10 add.w #$0A,d4 move.b d4,(a1) rts * d0 bereits 1 ld7_12 cmp.w #12,d4 bcs op_err2 cmp.w #15,d4 bhi.s ld7_16 cmp.w #6,d2 * IXH-IYL nicht dokumentiert beq op_err2 * LD (HL),IXH -> Fehler move.w d4,d0 bsr c_ixy add.w #$44,d1 and.w #1,d4 * H gerade, L ungerade or.w d4,d1 move.b d1,1(a1) moveq.l #2,d0 rts ld7_16 cmp.w #17,d4 bhi.s ld7_25 cmp.w #7,d2 bne op_err2 move.b #$ED,(a1) move.b #$57,1(a1) * LD A,I cmp.w #16,d4 beq e_2byte move.b #$5F,1(a1) * LD A,R bra e_2byte ld7_25 cmp.w #25,d4 bcs op_err2 bhi.s ld7_26 add.w #$06,d1 * LD r,n move.b d1,(a1) move.w d5,d0 bsr chkbyte move.b d0,1(a1) moveq.l #2,d0 rts ld7_26 cmp.w #27,d4 bhi.s ld7_28 cmp.w #6,d2 beq op_err2 * LD (HL),(IX+d) -> Fehler move.w d4,d0 bsr c_ixy add.w #$46,d1 move.b d1,1(a1) move.w d5,d0 move.b d0,2(a1) moveq.l #3,d0 rts ld7_28 cmp.w #7,d2 bne op_err2 move.b #$3A,(a1) move.b d5,1(a1) lsr.w #8,d5 move.b d5,2(a1) moveq.l #3,d0 rts ld_1_8 cmp.w #9,d2 bhi.s ld_1_12 cmp.w #7,d4 bne op_err2 * nur LD (BC,DE),A erlaubt sub.w #8,d2 * 0,1 lsl.w #4,d2 * $00,$10 add.w #$02,d2 move.b d2,(a1) moveq.l #1,d0 rts ld_1_12 cmp.w #12,d2 * 1.Op = 12? bcs op_err1 cmp.w #15,d2 bhi.s ld_1_16 move.w d2,d0 bsr c_ixy and.w #1,d0 * 0: H, 1: L lsl.w #3,d0 cmp.w #7,d4 bhi.s ld12_25 * 2.Op auf 25 bei 1.Op bis 12 testen cmp.w #6,d4 beq op_err2 * LD IXH,(HL) -> Fehler add.w #$60,d0 add.w d4,d0 move.b d0,1(a1) moveq.l #2,d0 rts ld12_25 cmp.w #25,d4 bne op_err2 add.w #$26,d0 move.b d0,1(a1) move.w d5,d0 bsr chkbyte move.b d0,2(a1) moveq.l #3,d0 rts ld_1_16 cmp.w #17,d2 bhi.s ld_1_18 cmp.w #7,d4 bne op_err2 * nur LD IR,A move.b #$ED,(a1) move.b #$47,1(a1) cmp.w #16,d2 beq.s e_2byte move.b #$4F,1(a1) e_2byte moveq.l #2,d0 rts ld_1_18 cmp.w #19,d2 bhi.s ld_1_20 sub.w #18,d2 * 0,1 lsl.w #4,d2 * $00,$10 cmp.w #25,d4 bcs op_err2 bhi.s ld18_28 add.w #$01,d2 * LD BCDE,nn move.b d2,(a1) move.b d5,1(a1) lsr.w #8,d5 move.b d5,2(a1) moveq.l #3,d0 rts ld18_28 cmp.w #28,d4 bne op_err2 move.b #$ED,(a1) * LD BCDE,(nn) add.w #$4B,d2 move.b d2,1(a1) move.b d5,2(a1) lsr.w #8,d5 move.b d5,3(a1) moveq.l #4,d0 rts ld_1_20 cmp.w #20,d2 bhi.s ld_1_22 cmp.w #25,d4 bcs op_err2 bhi.s ld20_28 move.b #$21,(a1) * LD HL,nn bra wr_wd1 ld20_28 cmp.w #28,d4 bne op_err2 move.b #$2A,(a1) * LD HL,(nn) bra wr_wd1 ld_1_22 cmp.w #22,d2 bcs op_err1 cmp.w #23,d2 bhi.s ld_1_24 move.w d2,d0 bsr c_ixy cmp.w #25,d4 bcs op_err2 bhi.s ld22_28 move.b #$21,1(a1) * LD IXY,nn bra wr_wd2 ld22_28 cmp.w #28,d4 bne op_err2 move.b #$2A,1(a1) * LD IXY,(nn) bra wr_wd2 ld_1_24 cmp.w #24,d2 bhi.s ld_1_26 cmp.w #20,d4 bcs op_err2 bhi.s ld24_22 move.b #$F9,(a1) * LD SP,HL moveq.l #1,d0 rts ld24_22 cmp.w #22,d4 bcs op_err2 cmp.w #23,d4 bhi.s ld24_25 move.w d4,d0 * LD SP,IXY bsr c_ixy move.b #$F9,1(a1) moveq.l #2,d0 rts ld24_25 cmp.w #25,d4 bcs op_err2 bhi.s ld24_28 move.b #$31,(a1) * LD SP,nn wr_wd1 move.b d5,1(a1) lsr.w #8,d5 move.b d5,2(a1) moveq.l #3,d0 rts ld24_28 cmp.w #28,d4 bne op_err2 move.b #$ED,(a1) * SP,(nn) move.b #$7B,1(a1) wr_wd2 move.b d5,2(a1) lsr.w #8,d5 move.b d5,3(a1) moveq.l #4,d0 rts ld_1_26 cmp.w #26,d2 bcs op_err1 cmp.w #27,d2 bhi.s ld_1_28 move.w d2,d0 bsr c_ixy cmp.w #7,d4 bhi.s ld26_25 cmp.w #6,d4 beq op_err2 * LD (IXY+d),(HL) -> Fehler add.w #$70,d4 * LD (IXY+d),r move.b d4,1(a1) move.b d3,2(a1) moveq.l #3,d0 rts ld26_25 cmp.w #25,d4 bne op_err2 move.b #$36,1(a1) * LD (IXY+d),n move.b d3,2(a1) move.w d5,d0 bsr chkbyte move.b d0,3(a1) moveq.l #4,d0 rts ld_1_28 cmp.w #28,d2 bne op_err1 cmp.w #7,d4 bcs op_err2 bhi.s ld28_18 move.b #$32,(a1) * LD (nn),A bra.s wr_wd11 ld28_18 cmp.w #18,d4 bcs op_err2 cmp.w #19,d4 bhi.s ld28_20 move.b #$ED,(a1) * LD (nn),BCDE sub.w #18,d4 * 0,1 lsl.w #4,d4 * $00,$10 add.w #$43,d4 move.b d4,1(a1) bra.s wr_wd12 ld28_20 cmp.w #20,d4 bhi.s ld28_22 move.b #$22,(a1) * LD (nn),HL wr_wd11 move.b d3,1(a1) lsr.w #8,d3 move.b d3,2(a1) moveq.l #3,d0 rts ld28_22 cmp.w #22,d4 bcs op_err2 cmp.w #23,d4 bhi.s ld28_24 move.w d4,d0 * LD (nn),IXY bsr c_ixy move.b #$22,1(a1) bra.s wr_wd12 ld28_24 cmp.w #24,d4 bne op_err2 move.b #$ED,(a1) move.b #$73,1(a1) wr_wd12 move.b d3,2(a1) lsr.w #8,d3 move.b d3,3(a1) moveq.l #4,d0 rts r_IM bsr op_num cmp.w #25,d0 bne op_err1 move.b #$ED,(a1) tst.w d1 bne.s im1 move.b #$46,1(a1) * IM 0 moveq.l #2,d0 rts im1 cmp.w #1,d1 bne.s im2 move.b #$56,1(a1) * IM 1 moveq.l #2,d0 rts im2 cmp.w #2,d1 bne op_err1 move.b #$5E,1(a1) * IM 2 moveq.l #2,d0 rts r_DEFB bsr atxt move.l a1,a2 clr.l d6 defb1 bsr.s defstr cmp.l #1,d5 * genau 1 Byte? bne.s defb2 subq.l #3,a0 subq.l #1,a2 subq.l #1,d6 bra.s defb3 defb2 tst.l d5 bne.s defb5 defb3 bsr op_num cmp.w #25,d0 bne op_err1 cmp.w #BYTE_BUF_LEN,d6 bcs.s defb4 error #19 bra.s defb6 defb4 move.w d1,d0 bsr chkbyte move.b d0,(a2)+ addq.l #1,d6 defb5 cmp.b #',',(a0)+ beq.s defb1 subq.l #1,a0 defb6 move.l d6,d0 rts r_DEFM bsr atxt move.l a1,a2 bsr.s defstr move.l d5,d0 bne.s defm1 error #11 defm1 rts * Quelltextstring von (a0) nach (a2) kopieren * OUTPUT: d5: Anzahl Bytes * d6:=d6+Anzahl Bytes defstr clr.l d5 move.b (a0),d0 cmp.b #'"',d0 beq.s defstr1 cmp.b #"'",d0 bne.s defstr5 defstr1 addq.l #1,a0 defstr2 move.b (a0)+,d1 cmp.b d1,d0 beq.s defstr5 * String-Ende cmp.b #$20,d1 bcc.s defstr3 * kein String-Ende error #20 defstr3 cmp.l #BYTE_BUF_LEN,d5 * noch Platz im Puffer? bcs.s defstr4 error #19 bra.s defstr5 defstr4 move.b d1,(a2)+ addq.l #1,d5 bra.s defstr2 defstr5 add.l d5,d6 rts r_DEFW bsr atxt move.l a1,a2 clr.l d6 defw1 bsr op_num cmp.w #25,d0 bne op_err1 cmp.w #BYTE_BUF_LEN,d6 bcs.s defw2 error #19 bra.s defw3 defw2 move.b d1,(a2)+ lsr.w #8,d1 move.b d1,(a2)+ addq.l #2,d6 cmp.b #',',(a0)+ beq.s defw1 subq.l #1,a0 defw3 move.l d6,d0 rts r_RST bsr op_num cmp.w #25,d0 bne op_err1 move.w d1,d0 and.w #$FFC7,d1 bne op_err1 or.b #$C7,d0 move.b d0,(a1) moveq.l #1,d0 rts r_PUSH move.w #$C5,d2 bra.s pushpop r_POP move.w #$C1,d2 pushpop bsr op_num moveq.l #1,d3 * Anz. Bytes cmp.w #18,d0 beq.s pp_code * BC add.w #$10,d2 cmp.w #19,d0 beq.s pp_code * DE add.w #$10,d2 cmp.w #20,d0 beq.s pp_code * HL add.w #$10,d2 cmp.b #21,d0 beq.s pp_code * AF sub.w #$10,d2 * IX, IY move.b d2,1(a1) moveq.l #2,d3 move.w #$DD,d2 cmp.w #22,d0 * IX beq.s pp_code move.w #$FD,d2 cmp.w #23,d0 * IY bne op_err1 pp_code move.b d2,(a1) move.l d3,d0 rts r_EX move.l a1,a4 bsr atxt move.l a0,a2 bsr op_num * beide Operanden abtrennen cmp.w #10,d0 beq.s ex_2_op * EX (SP),.. cmp.w #19,d0 beq.s ex_2_op * EX DE,.. cmp.w #21,d0 bne op_err1 * EX AF,.. ex_2_op cmp.b #',',(a0)+ bne op_err3 bsr etxt move.l a0,a3 move.b (a3),d7 clr.b (a3) lea tab_ex(pc),a1 ex_lp move.l a2,a0 tst.b (a1) bne.s se_ex move.b d7,(a3) * kein gltiger Operand move.l a3,a0 bra op_err1 se_ex bsr ustrcmp tst.w d0 beq.s ex_fnd nx_ex tst.b (a1)+ * n„chster Eintrag bne.s nx_ex clr.l d0 * Code-Bytes bergehen move.b (a1),d0 addq.l #1,d0 add.l d0,a1 bra.s ex_lp ex_fnd move.b d7,(a3) clr.l d0 move.l a3,a0 move.b (a1)+,d0 rts section data * Tabelle fr EX-Befehle tab_ex dc.b '(SP),HL',0,1,$E3 dc.b '(SP),IX',0,2,$DD,$E3 dc.b '(SP),IY',0,2,$FD,$E3 dc.b 'DE,HL',0,1,$EB dc.b "AF,AF'",0,1,$08 section text r_JP bsr c_flags move.w #$C2,d3 cmp.w #-1,d0 bne.s j_case bsr op_num * unbedingter Sprung cmp.w #25,d0 bne.s jp1 move.b #$C3,(a1) * JP nn bra.s j_abs jp1 cmp.w #6,d0 bne.s jp2 move.b #$E9,(a1) * JP (HL) moveq.l #1,d0 rts jp2 tst.w d1 bne op_err1 * Offset <> 0 cmp.w #26,d0 bne.s jp3 move.b #$DD,(a1) * JP (IX) bra.s jp4 jp3 cmp.w #27,d0 bne op_err1 move.b #$FD,(a1) jp4 move.b #$E9,1(a1) moveq.l #2,d0 rts r_CALL bsr c_flags move.w #$C4,d3 cmp.w #-1,d0 bne.s j_case bsr op_num * unbedingter CALL cmp.w #25,d0 bne op_err1 move.b #$CD,(a1) bra.s j_abs j_case move.w d0,d2 * Flags cmp.b #',',(a0)+ bne op_err3 bsr op_num cmp.w #25,d0 bne op_err1 add.w d2,d3 * Flags addieren move.b d3,(a1) j_abs move.b d1,1(a1) lsr.w #8,d1 move.b d1,2(a1) moveq.l #3,d0 rts r_RET bsr c_flags cmp.w #-1,d0 bne.s r_case move.b #$C9,(a1) bra.s r_cas1 r_case add.w #$C0,d0 move.b d0,(a1) r_cas1 moveq.l #1,d0 rts r_JR tst.b J_flag bne.w r_JP * absoluter Sprung generieren bsr c_flags move.b #$18,(a1) cmp.w #-1,d0 beq.s jmp_rel add.w #$20,d0 cmp.b #$38,d0 * nur NZ,Z,NC,C bhi op_err1 move.b d0,(a1) cmp.b #',',(a0)+ bne op_err3 bra.s jmp_rel r_DJNZ tst.b J_flag beq.s djnz move.b #$05,(a1) * DEC B move.b #$C2,1(a1) * JP NZ,.. bsr op_num cmp.w #25,d0 bne op_err1 move.b d1,2(a1) lsr.w #8,d1 move.b d1,3(a1) moveq.l #4,d0 rts djnz move.b #$10,(a1) * Relative Sprungdistanz ermitteln und in 1(a1) schreiben * Bereichsprfung, d0 auf 2 oder 0 (Fehler) setzen * nur in Pass 2 jmp_rel bsr op_num cmp.w #2,m_pass bne.s rang_ok * im Pass 1 sub.w prg_count,d1 * Sprungdistanz subq.w #2,d1 * erst ab n„chsten Befehl move.b d1,1(a1) move.w d1,d0 * Bereichsprfung and.w #$FF80,d0 beq.s rang_ok * Vorw„rtssprung or.w #$7F,d1 cmp.w #-1,d1 beq.s rang_ok * Rckw„rtssprung error #16 clr.l d0 rts rang_ok moveq.l #2,d0 rts * Bedingungsflags auswerten * OUTPUT: d0.w Code der Flags oder -1 c_flags move.l a1,-(sp) lea tab_flg(pc),a1 bsr sea_pos cmp.w #-1,d0 beq.s flg_ret flg_fnd lsl.l #3,d0 flg_ret move.l (sp)+,a1 rts section data tab_flg dc.b 'NZ',0,'Z',0,'NC',0,'C',0 dc.b 'PO',0,'PE',0,'P',0,'M',0 dc.b 0 section text r_ADD bsr two_op move.w d4,d0 move.w d5,d1 move.w #$80,d6 * Grundcodebyte fr 8 Bit cmp.w #7,d2 beq math8 * 8 Bit ADD cmp.w #20,d2 * 16 Bit ADD bcs op_err1 bhi.s addixy cmp.w #18,d4 * ADD HL,.. bcs op_err2 move.w #$39,d0 cmp.w #24,d4 beq.s addhl * ADD HL,SP cmp.w #18,d4 bcs op_err2 cmp.w #20,d4 bhi op_err2 sub.w #18,d4 * ADD HL,BC/DE/HL lsl.w #4,d4 * $00/$10/$20 add.w #$09,d4 move.w d4,d0 addhl move.b d0,(a1) moveq.l #1,d0 rts addixy cmp.w #22,d2 bcs op_err1 cmp.w #23,d2 bhi op_err1 move.w d2,d0 bsr c_ixy cmp.w #18,d4 bcs op_err2 cmp.w #19,d4 bhi.s addxy22 sub.w #18,d4 * ADD IXY,BC/DE lsl.w #4,d4 add.w #$09,d4 move.b d4,1(a1) moveq.l #2,d0 rts addxy22 cmp.w d2,d4 bne.s addxy24 move.b #$29,1(a1) * ADD IX,IX oder IY,IY moveq.l #2,d0 rts addxy24 cmp.w #24,d4 bne op_err2 move.b #$39,1(a1) moveq.l #2,d0 rts r_ADC bsr two_op move.w #$88,d6 * Grundcodebyte fr 8 Bit move.w #$4A,d7 * Grundcodebyte fr 16 Bit bra.s asbc16 r_SBC bsr two_op move.w #$98,d6 * Grundcodebyte fr 8 Bit move.w #$42,d7 * Grundcodebyte fr 16 Bit asbc16 move.w d4,d0 move.w d5,d1 cmp.w #7,d2 beq.s math8 * 8 Bit ADD cmp.w #20,d2 bne op_err1 move.b #$ED,(a1) move.w #$30,d0 cmp.w #24,d4 beq.s asbchl * ADC/SBC HL,SP cmp.w #18,d4 * 16 Bit ADD bcs op_err2 cmp.w #20,d4 bhi op_err2 sub.w #18,d4 lsl.w #4,d4 * $00/$10/$20 move.w d4,d0 asbchl add.w d7,d0 move.b d0,1(a1) moveq.l #2,d0 rts r_SUB move.w #$90,d6 bra.s math r_AND move.w #$A0,d6 bra.s math r_XOR move.w #$A8,d6 bra.s math r_OR move.w #$B0,d6 bra.s math r_CP move.w #$B8,d6 math bsr op_num math8 cmp.w #7,d0 bhi.s ma_12 * als n„chstes auf Kennung 12 testen add.w d6,d0 * + Grundcodebyte move.b d0,(a1) moveq.l #1,d0 rts ma_12 cmp.w #12,d0 bcs op_err1 cmp.w #15,d0 bhi.s ma_25 bsr c_ixy * ADD-CP IXYHL and.w #1,d0 * H gerade, L ungerade add.w #4,d0 * B -> H add.w d6,d0 * + Grundcodebyte move.b d0,1(a1) moveq.l #2,d0 rts ma_25 cmp.w #25,d0 bne.s ma_26 add.w #$46,d6 * ADD-CP n move.b d6,(a1) move.w d1,d0 bsr chkbyte move.b d0,1(a1) moveq.l #2,d0 rts ma_26 cmp.w #26,d0 bcs op_err1 cmp.w #27,d0 bhi op_err1 bsr c_ixy * ADD-CP (IXY+d) add.w #$06,d6 * B -> H move.b d6,1(a1) move.b d1,2(a1) moveq.l #3,d0 rts r_INC move.w #$04,d6 * Grundcodebyte fr 8 Bit move.w #$03,d7 * fr 16 Bit bra.s incdec r_DEC move.w #$05,d6 * fr 8 Bit move.w #$0B,d7 incdec bsr op_num cmp.w #7,d0 bhi.s icdc12 lsl.w #3,d0 * INC/DEC r add.w d6,d0 move.b d0,(a1) moveq.l #1,d0 rts icdc12 cmp.w #12,d0 bcs op_err1 cmp.w #15,d0 bhi.s icdc18 bsr c_ixy * INC/DEC IXYHL and.w #1,d0 * H gerade, L ungerade lsl.w #3,d0 add.w #$20,d0 * B -> H add.w d6,d0 * Grundcodebyte move.b d0,1(a1) moveq.l #2,d0 rts icdc18 cmp.w #18,d0 bcs op_err1 cmp.w #20,d0 bhi.s icdc22 sub.w #18,d0 * INC/DEC BC-HL lsl.w #4,d0 add.w d7,d0 move.b d0,(a1) moveq.l #1,d0 rts icdc22 cmp.w #22,d0 bcs op_err1 cmp.w #23,d0 bhi.s icdc24 bsr c_ixy * INC/DEC IXY add.w #$20,d7 move.b d7,1(a1) moveq.l #2,d0 rts icdc24 cmp.w #24,d0 bne.s icdc26 move.w #$30,d0 * INC/DEC SP add.w d7,d0 move.b d0,(a1) moveq.l #1,d0 rts icdc26 cmp.w #26,d0 bcs op_err1 cmp.w #27,d0 bhi op_err1 bsr c_ixy add.w #$30,d6 move.b d6,1(a1) move.b d1,2(a1) moveq.l #3,d0 rts r_BIT move.w #$40,d6 * Grundcodebyte bra.s od_bit r_RES move.w #$80,d6 bra.s od_bit r_SET move.w #$C0,d6 od_bit bsr two_op cmp.w #25,d2 * 1. Op Direktwert bne op_err2 cmp.w #7,d3 * Bitnummer bhi op_err1 * gr”žer 7 lsl.w #3,d3 * Bitnummer * 8 add.w d3,d6 * Grundcodebyte move.w d4,d0 * Registerkennung move.w d5,d1 * Direktwert bra.s bitrot r_RLC move.w #$00,d6 * Grundcodebytes bra.s ro_sh r_RRC move.w #$08,d6 bra.s ro_sh r_RL move.w #$10,d6 bra.s ro_sh r_RR move.w #$18,d6 bra.s ro_sh r_SLA move.w #$20,d6 bra.s ro_sh r_SRA move.w #$28,d6 bra.s ro_sh r_SLE move.w #$30,d6 bra.s ro_sh r_SRL move.w #$38,d6 ro_sh bsr op_num bitrot cmp.w #7,d0 bhi.s bt_ro2 bt_ro1 move.b #$CB,(a1) * OP einfaches Register add.w d6,d0 move.b d0,1(a1) moveq.l #2,d0 rts bt_ro2 move.b #$CB,1(a1) cmp.w #12,d0 bcs op_err1 cmp.w #15,d0 bhi.s bt_ro3 bsr c_ixy * IXH-IYL add.w #4,d6 and.w #1,d0 or.w d0,d6 move.b d6,2(a1) moveq.l #3,d0 rts bt_ro3 cmp.w #26,d0 bcs op_err1 cmp.w #27,d0 bhi op_err1 bsr c_ixy * (IXY+d) move.b d1,2(a1) add.w #6,d6 move.b d6,3(a1) moveq.l #4,d0 rts r_IN bsr two_op move.w d2,d0 * Registerkenung move.w #$40,d1 * Grundcodebyte cmp.w #11,d4 * Tor (C)? beq.s i_inout move.w d5,d0 * E/A-Adresse move.w d4,d1 * Adresskennung move.w #$DB,d3 * Code IN A,(n) bra.s a_inout r_OUT bsr two_op move.w d4,d0 * Registerkennung move.w #$41,d1 * Grundcodebyte cmp.w #11,d2 * Tor (C)? beq.s i_inout move.w d3,d0 * E/A-Adresse move.w d2,d1 * Adresskennung move.w d4,d2 * Registerkennung move.w #$D3,d3 * Code OUT (n),A a_inout cmp.w #7,d2 bne op_err2 * kein A-Register cmp.w #28,d1 bne op_err2 * kein Direktwert move.b d3,(a1) bsr chkbyte bra.s io_ret i_inout cmp.w #6,d0 * ber (C) beq op_err1 * (HL) cmp.w #7,d0 bhi op_err1 lsl.w #3,d0 * mul 8 add.w d1,d0 move.b #$ED,(a1) io_ret move.b d0,1(a1) moveq.l #2,d0 rts * Unterscheidung von IX und IY * (a1) $DD oder $FD schreiben * Op-Kennung in d0 c_ixy move.b #$DD,(a1) cmp.w #12,d0 beq.s ixy_ret * IXH cmp.w #13,d0 beq.s ixy_ret * IXL cmp.w #22,d0 beq.s ixy_ret * IX cmp.w #26,d0 beq.s ixy_ret * (IX+d) move.b #$FD,(a1) ixy_ret rts * zwei Operanden (a0) auswerten * OUTPUT: d2: Op1-Kennung * d3: Op1-Wert * d4: Op2-Kennung * d5: Op2-Wert * a0: hinter ausgewerteten Teil two_op bsr.s op_num move.l d0,d2 move.l d1,d3 cmp.b #',',(a0)+ bne op_err3 bsr.s op_num move.l d0,d4 move.l d1,d5 rts * Im Quelltext (a0) n„chstes Operanden auswerten * OUTPUT: a0: hinter ausgewerteten Teil im Quelltext * d0: Art des Operanden (Nummer) * d1: evtl. Direktwert * Operandennummer: ab Null beginnend in der Reihenfolge * B, C, D, E, H, L, (HL), A * 0-7 * (BC), (DE), (SP), (C) * 8-11 * IXH, IXL, IYH, IYL, I, R * 12-17 * BC, DE, HL, AF, IX, IY, SP, nn * 18-25 * (IX+d), (IY+d), (nn) * 26-28 op_num movem.l d6/a1-a2,-(sp) lea tab_reg(pc),a1 bsr sea_pos cmp.w #-1,d0 beq.s reg_no reg_fnd clr.l d1 * Registernummer bra.w op_ret reg_no cmp.b #'(',(a0) bne direct addq.l #1,a0 * auf IX und IY testen bsr atxt move.l a0,a2 move.b (a0),d0 bsr upcase cmp.b #'I',d0 bne.s indirct addq.l #1,a0 move.b (a0),d0 move.l a2,a0 * Anfang in der Klammer + 1 bsr upcase cmp.b #'X',d0 bne.s reg_iy moveq.l #26,d6 bra.s offset reg_iy cmp.b #'Y',d0 bne.s indirct moveq.l #27,d6 offset addq.l #2,a0 move.b (a0),d0 cmp.b #')',d0 bne.s offset1 clr.l d0 * (IX) oder (IY) bra.s indrct1 offset1 cmp.b #'+',d0 beq.s offset2 cmp.b #'-',d0 beq.s offset2 move.l a2,a0 * Anfang in der Klammer bra.s indirct offset2 bsr term tst.b term_flag beq.s indrct1 * Wert ungltig move.w d0,d1 * Bereichsprfung nur Pass 2 and.w #$FF80,d1 beq.s indrct1 * vorw„rts move.w d0,d1 or.w #$7F,d1 cmp.w #-1,d1 beq.s indrct1 * rckw„rts error #18 bra.s indrct1 indirct bsr term * indirekter Wert moveq.l #28,d6 indrct1 move.l d0,d1 move.l d6,d0 cmp.b #')',(a0)+ beq.s op_ret error #13 * schliežende Klammer fehlt bra.s op_ret direct bsr term move.l d0,d1 moveq.l #25,d0 op_ret movem.l (sp)+,d6/a1-a2 rts * Position (mit Null beginnend) eines Strings in einer Tabelle suchen * INPUT: a0: zu suchender String, wird grož gewandelt * a1: Tabelle * OUTPUT: d0: Nummer in Tabelle oder -1, wenn nicht gefunden * a0: zeigt hinter ausgewerteten Teil sea_pos movem.l d1/d7/a1-a3,-(sp) bsr atxt move.l a0,a2 * String abtrennen bsr etxt move.l a0,a3 move.b (a3),d7 clr.b (a3) moveq.l #-1,d1 pos_lp addq.l #1,d1 move.l a2,a0 tst.b (a1) beq.s no_pos * nicht gefunden bsr ustrcmp tst.w d0 beq.s pos_fnd nx_pos tst.b (a1)+ bne.s nx_pos bra.s pos_lp no_pos moveq.l #-1,d0 move.l a2,a0 bra.s pos_ret pos_fnd move.l a3,a0 move.l d1,d0 pos_ret move.b d7,(a3) movem.l (sp)+,d1/d7/a1-a3 rts section data * Tabelle aller Befehle mit m”glichen Operanden tab_i1 dc.b 'LD',0 dc.b 'PUSH',0 dc.b 'POP',0 dc.b 'EX',0 dc.b 'JP',0 dc.b 'CALL',0 dc.b 'RET',0 dc.b 'JR',0 dc.b 'ADD',0 dc.b 'ADC',0 dc.b 'SUB',0 dc.b 'SBC',0 dc.b 'AND',0 dc.b 'XOR',0 dc.b 'OR',0 dc.b 'CP',0 dc.b 'INC',0 dc.b 'DEC',0 dc.b 'DJNZ',0 t_EQU dc.b 'EQU',0 dc.b 'BIT',0 dc.b 'RES',0 dc.b 'SET',0 dc.b 'RLC',0 dc.b 'RRC',0 dc.b 'RL',0 dc.b 'RR',0 dc.b 'SLA',0 dc.b 'SRA',0 dc.b 'SLE',0 dc.b 'SRL',0 dc.b 'RST',0 dc.b 'IN',0 dc.b 'OUT',0 dc.b 'IM',0 dc.b 'DEFB',0,'DB',0 dc.b 'DEFM',0,'DM',0 dc.b 'DEFW',0,'DW',0 dc.b 'DEFA',0,'DA',0 dc.b 'END',0 dc.b 0 * Tabellenende * Tabelle der Adressen der Auswerteroutinen fr Befehle mit * m”glichen Operanden, gleiche Reihenfolge wie bei tab_i1! even tab_jp1 dc.l r_LD dc.l r_PUSH dc.l r_POP dc.l r_EX dc.l r_JP dc.l r_CALL dc.l r_RET dc.l r_JR dc.l r_ADD dc.l r_ADC dc.l r_SUB dc.l r_SBC dc.l r_AND dc.l r_XOR dc.l r_OR dc.l r_CP dc.l r_INC dc.l r_DEC dc.l r_DJNZ dc.l r_EQU dc.l r_BIT dc.l r_RES dc.l r_SET dc.l r_RLC dc.l r_RRC dc.l r_RL dc.l r_RR dc.l r_SLA dc.l r_SRA dc.l r_SLE dc.l r_SRL dc.l r_RST dc.l r_IN dc.l r_OUT dc.l r_IM dc.l r_DEFB,r_DEFB dc.l r_DEFM,r_DEFM dc.l r_DEFW,r_DEFW dc.l r_DEFW,r_DEFW dc.l r_END * Tabelle aller Befehle ohne jeglichen Operanden * Format: * NAME, 1 Byte Null, Anz. Bytes, Code-Bytes * Ende mit Null tab_i2 dc.b 'EXX',0,1,$D9 dc.b 'LDI',0,2,$ED,$A0 dc.b 'LDIR',0,2,$ED,$B0 dc.b 'LDD',0,2,$ED,$A8 dc.b 'LDDR',0,2,$ED,$B8 dc.b 'CPI',0,2,$ED,$A1 dc.b 'CPIR',0,2,$ED,$B1 dc.b 'CPD',0,2,$ED,$A9 dc.b 'CPDR',0,2,$ED,$B9 dc.b 'RETI',0,2,$ED,$4D dc.b 'RETN',0,2,$ED,$45 dc.b 'NOP',0,1,$00 dc.b 'HALT',0,1,$76 dc.b 'CCF',0,1,$3F dc.b 'SCF',0,1,$37 dc.b 'EI',0,1,$FB dc.b 'DI',0,1,$F3 dc.b 'INF',0,2,$ED,$70 dc.b 'INI',0,2,$ED,$A2 dc.b 'INIR',0,2,$ED,$B2 dc.b 'IND',0,2,$ED,$AA dc.b 'INDR',0,2,$ED,$BA dc.b 'OUTI',0,2,$ED,$A3 dc.b 'OTIR',0,2,$ED,$B3 dc.b 'OUTD',0,2,$ED,$AB dc.b 'OTDR',0,2,$ED,$BB dc.b 'DAA',0,1,$27 dc.b 'CPL',0,1,$2F dc.b 'NEG',0,2,$ED,$44 dc.b 'RRCA',0,1,$0F dc.b 'RLCA',0,1,$07 dc.b 'RRA',0,1,$1F dc.b 'RLA',0,1,$17 dc.b 'RLD',0,2,$ED,$6F dc.b 'RRD',0,2,$ED,$67 dc.b 0 * Tabellenende tab_reg dc.b 'B',0,'C',0,'D',0,'E',0 * 0-3 dc.b 'H',0,'L',0,'(HL)',0,'A',0 * 4-7 dc.b '(BC)',0,'(DE)',0,'(SP)',0,'(C)',0 * 8-11 dc.b 'IXH',0,'IXL',0,'IYH',0,'IYL',0 * 12-15 dc.b 'I',0,'R',0 * 16,17 dc.b 'BC',0,'DE',0,'HL',0,'AF',0 * 18-21 dc.b 'IX',0,'IY',0,'SP',0 * 22-24 dc.b 0 * Tabellenende section bss byte_buf ds.b BYTE_BUF_LEN * Puffer fr erzeugte Bytes *** allgemeine Grundroutinen ****************************** section text * Umwandlung Klein -> Grožbuchstabe in d0.b upcase cmp.b #'a',d0 bcs.s upcase1 cmp.b #'z',d0 bhi.s upcase1 sub.b #$20,d0 upcase1 rts * Vergleichen zweier Strings (a0, a1) * String a0 wird in Grožbuchstaben umgewandelt * OUTPUT: d0.l = 0, wenn gleich, sonst +1 oder -1 * a0, a1: zeigt auf Unterschied bzw. hinter String (hinter Null) ustrcmp move.b (a0),d0 bsr.s upcase cmp.b (a1),d0 beq.s ustrcp1 bhi.s ustrcp2 * String 1 > String 2 moveq.l #-1,d0 bra.s ustrcp3 * String 1 < String 2 ustrcp1 clr.l d0 addq.l #1,a1 tst.b (a0)+ beq.s ustrcp3 * String 1 = String 2 bra.s ustrcmp ustrcp2 moveq.l #1,d0 ustrcp3 rts * Vergleichen zweier Strings (a0, a1) * String a0 wird dann in in Grožbuchstaben umgewandelt, * wenn die "-C" Option nicht angegeben wurde * OUTPUT: d0.l = 0, wenn gleich, sonst +1 oder -1 * a0, a1: zeigt auf Unterschied bzw. hinter String (hinter Null) strcmp move.b (a0),d0 tst.b C_flag bne.s strcmp1 bsr.s upcase strcmp1 cmp.b (a1),d0 beq.s strcmp2 bhi.s strcmp3 moveq.l #-1,d0 bra.s strcmp4 strcmp2 clr.l d0 addq.l #1,a1 tst.b (a0)+ beq.s strcmp4 bra.s strcmp strcmp3 moveq.l #1,d0 strcmp4 rts * String grož wandeln und kopieren * von a0 nach a1 ustrcpy move.b (a0)+,d0 bsr.s upcase move.b d0,(a1)+ bne.s ustrcpy rts * String a0 an a1 anh„ngen strcat tst.b (a1)+ * Ende String 2 suchen bne.s strcat subq.l #1,a1 strcpy move.b (a0)+,(a1)+ bne.s strcpy rts * letztes Vorkommen eines Zeichens (d0.b) im String (a0) suchen * OUTPUT: a0: Zeiger auf letztes Vorkommen bzw. Stringanfang strrchr move.l a1,-(sp) move.l a0,a1 srchr1 cmp.b (a0),d0 bne.s srchr2 move.l a0,a1 srchr2 tst.b (a0)+ bne.s srchr1 move.l a1,a0 move.l (sp)+,a1 rts * Zeiger a0 Leerzeichen und TABs bergehen atxt subq.l #1,a0 atxt1 addq.l #1,a0 cmp.b #$20,(a0) beq.s atxt1 cmp.b #9,(a0) beq.s atxt1 rts * Stringende suchen (0, 9, $0A, $0C, $0D, $1A, $1E, $20) etxt movem.l d0/a1,-(sp) etxt1 move.b (a0),d0 moveq.w #8,d1 lea etxttab(pc),a1 etxt2 cmp.b (a1)+,d0 beq.s etxt3 dbf d1,etxt2 addq.l #1,a0 bra.s etxt1 etxt3 movem.l (sp)+,d0/a1 rts section data etxttab dc.b 0,9,$0A,$0C,$0D,$1A,$1E,$20,',' section text * Symbolende suchen esym move.w d0,-(sp) esym1 move.b (a0)+,d0 cmp.b #'_',d0 beq.s esym1 bsr.w upcase cmp.b #'0',d0 bcs.s esym2 cmp.b #'9',d0 bls.s esym1 cmp.b #'A',d0 bcs.s esym2 cmp.b #'Z',d0 bls.s esym1 esym2 subq.l #1,a0 move.w (sp)+,d0 rts * Ausgabe einer vorzeichenlosen Dezimalzahl in d0.w outdez move.w #-1,d4 outdez1 and.l #$FFFF,d0 * oberen 16Bit = 0 addq.w #1,d4 * Anzahl der Stellen-1 divu #10,d0 swap d0 move.w d0,-(sp) * Rest -> Stack swap d0 tst.w d0 bne.s outdez1 outdez2 move.w (sp)+,d0 add.w #'0',d0 move.w d0,-(sp) call_gemdos Cconout addq.l #4,sp dbf.w d4,outdez2 rts * Test auf Abbruch (^C), ja -> exit tst_brk call_gemdos Cconis addq.l #2,sp tst.w d0 beq.s brk_end call_gemdos Crawcin addq.l #2,sp cmp.l #$610000,d0 beq prg_end cmp.b #3,d0 beq prg_end brk_end rts * n„chste Zeile suchen next_ln move.w d0,-(sp) nx_ln1 move.b (a0)+,d0 cmp.b #$0A,d0 beq.s nx_ret cmp.b #$1E,d0 beq.s nx_ret cmp.b #$1A,d0 bne.s nx_ln1 subq.l #1,a0 nx_ret move.w (sp)+,d0 rts * Testet, ob in der Zeile (a0) noch etwas steht syntax move.l d0,-(sp) bsr.s syntax1 tst.w d0 beq.s sn_ret error #8 sn_ret move.l (sp)+,d0 rts * Test Zeilenende, d0.w=0: ok, d0.w=-1: Fehler syntax1 clr.l d0 bsr atxt cmp.b #$0A,(a0) * Zeilenende beq.s snret1 cmp.b #$0D,(a0) beq.s snret1 cmp.b #$1E,(a0) beq.s snret1 cmp.b #$1A,(a0) * Textende beq.s snret1 cmp.b #';',(a0) * Kommentar beq.s snret1 moveq.l #-1,d0 snret1 rts * Testet, ob der Wert (d0.w) ein Byte ist * wenn nein -> Warnung chkbyte movem.l d0-d2/a0-a2,-(sp) tst.b term_flag beq.s chkbret * Wert ungltig and.w #$FF00,d0 beq.s chkbret warning bigbyte chkbret movem.l (sp)+,d0-d2/a0-a2 rts * d0.b als Hex-Zahl in Puffer (a0) schreiben * a0 wird zwei mal inkrementiert htoa move.w d0,-(sp) lsr.b #4,d0 bsr.s htoa1 move.w (sp)+,d0 htoa1 and.w #$F,d0 add.w #'0',d0 cmp.w #'9',d0 bls.s htoa2 add.w #7,d0 htoa2 move.b d0,(a0)+ rts * d0.w als Dezimalzahl (immer 5 Stellen) in Puffer (a0) schreiben * a0 wird inkrementiert uitoa moveq.w #-1,d1 uitoa1 and.l #$FFFF,d0 divu #10,d0 swap d0 move.w d0,-(sp) * Rest addq.w #1,d1 swap d0 tst.w d0 bne.s uitoa1 uitoa2 cmp.w #4,d1 * Anzahl Stellen - 1 bcc.s uitoa3 move.w #0,-(sp) * Format -> Leerzeichen addq.w #1,d1 bra.s uitoa2 uitoa3 move.w (sp)+,d0 add.w #'0',d0 move.b d0,(a0)+ dbf d1,uitoa3 rts * Wort als Hexzahl + 2 Leerzeichen in Datei schreiben * INPUT: d0.w: Wert fouthex movem.l d0-d2/a0-a2,-(sp) lea filebuf(pc),a0 move.l a0,a1 moveq.w #3,d2 fohex1 rol.w #4,d0 * HEX -> ASCII move.w d0,d1 and.w #$F,d1 add.w #'0',d1 cmp.w #'9',d1 bls.s fohex2 add.w #7,d1 fohex2 move.b d1,(a1)+ dbf d2,fohex1 move.b #$20,(a1)+ move.b #$20,(a1)+ moveq.l #6,d0 bsr.s f_write movem.l (sp)+,d0-d2/a0-a2 rts * $0D $0A in Datei schreiben foutnl movem.l d0-d2/a0-a2,-(sp) lea filebuf(pc),a0 move.l a0,a1 move.b #$0D,(a1)+ move.b #$0A,(a1)+ moveq.l #2,d0 bsr.s f_write movem.l (sp)+,d0-d2/a0-a2 rts * Datei schreiben * INPUT a0: Zeiger auf Puffer * d0.l: Anzahl Bytes f_write move.l d0,-(sp) move.l a0,-(sp) move.l d0,-(sp) move.w f_handle,-(sp) call_gemdos Fwrite lea $C(sp),sp cmp.l (sp)+,d0 beq.s f_wr2 move.b #-1,wr_err_flag move.b #-1,end_flag cmp.l #-36,d0 bne.s f_wr1 error #23 * Zugriff verweigert bra.s f_wr2 f_wr1 error #24 * Laufwerk voll f_wr2 rts f_close move.w f_handle,-(sp) call_gemdos Fclose addq.l #4,sp rts section data bigbyte dc.b '16-Bit statt 8-Bit Wert',13,10,0 *** Stack und Arbeitsspeicher ***************************** section bss filebuf ds.b BYTE_BUF_LEN * Hilfspuffer fr Ausgabedatei wr_err_flag ds.b 1 * Schreibfehler even ds.l 1000 mystack ds.l 1 buffer ds.l 1 *** Ende ************************************************** END ***********************************************************