OpenCores
URL https://opencores.org/ocsvn/System09/System09/trunk

Subversion Repositories System09

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /System09/tags/LinuxPort/Tools/as09
    from Rev 77 to Rev 82
    Reverse comparison

Rev 77 → Rev 82

/as09.exe
0,0 → 1,124
+ +$PELR2Lp—à N`@ ø +?f‰EþÙmþÇ$@@èó?ÉÃU‰åƒì(ƒäð¸ƒÀƒÀÁèÁà‰Eð‹Eðè›?èö?ÇEôÇ$„n@è{@Ç$¬n@èo@ƒ},‹Eô…‹E ‹‰D$Ç$Òn@èI@Ç$è5@‹E £”@賋Eô;E}‹Eô…‹E ‹€8-tEôÿëÜ‹EôH£€@‹Eô;Em‹Eô…‹E ÿ‹Eô;EQ‹Eô…‹E ‹‰Eø‹Eø€8t%‹Eø€8Z‹Eø€8@~‹Eø‹Uø¶€Â ˆEøÿëÓ‹Eô…‹E ÇD$ån@‹‰$èk?…ÀuÇ$‚@éÔ‹Eô…‹E ÇD$çn@‹‰$è8?…ÀuÇ$‚@é¡‹Eô…‹E ÇD$ën@‹‰$è?…ÀuÇ@ƒ@én‹Eô…‹E ÇD$ín@‹‰$èÒ>…ÀuÇ@ƒ@é;‹Eô…‹E ÇD$ñn@‹‰$èŸ>…ÀuÇLƒ@é‹Eô…‹E ÇD$ón@‹‰$èl>…ÀuÇTƒ@éÕ‹Eô…‹E ÇD$÷n@‹‰$è9>…ÀuÇXƒ@颋Eô…‹E ÇD$ün@‹‰$è>…Àu Ç`@ër‹Eô…‹E ÇD$o@‹‰$èÖ=…ÀuÇèƒ@Çìƒ@ë8‹Eô…‹E ÇD$o@‹‰$èœ=…ÀuÇèƒ@Çìƒ@Eôÿé£ýÿÿLJ@Lj@‹E ‰EüÇ €@ÿˆ@¡ˆ@;€@TÇD$o@Eüƒ‹Eü‹‰$èø<£„@ƒ=„@u‹Eü‹‰D$Ç$ +ÇD$Vo@¡„@‰$è¿;ëÇD$do@¡„@‰$è¨;¡„@‰$è£;ë*¡àƒ@‰D$Ç$ o@è¤;¡$€@‰D$Ç$@o@è;èp9¡$€@‰$èu;U‰åƒìÇEüÇ$€@Çp@Ç|@Ç$‚@Ç@ƒ@ÇHƒ@ÇLƒ@ÇTƒ@ÇPƒ@Æ¿€@ +¡”@ƒÀ‹‰D$Ç$`@èÍ:‹Eü`@€8.u ‹Eü`@Æ‹Eü`@Eüÿ€:tëÓÇD$po@Ç$`@è„:ÇD$uo@Ç$`@è`:£„@ƒ=„@u Ç$wo@è.è×6èjÉÃU‰åƒìÇp@ǘ@Ç,‚@ÇHƒ@ÇPƒ@è 7ÉÃU‰åƒì¡„@‰D$ÇD$Ç$@€@è“…Àt^ÿ €@Ç(‚@ÇPƒ@èF…Àtè~ƒ=|@uƒ=$‚@tƒ=Pƒ@uè°0Ç,‚@ÇDƒ@ëèÜ.ÉÃU‰åƒìÇEø@€@ÇEôÀ€@‹Eø€8*t‹Uø€: +t +‹Eø€8;të ÇEüé‹Uø¾‰$èž-…Àu‹Eø¶ÿEø‹EôˆÿEôëÛÿMô‹Uô€::tÿEô‹EôÆ‹Uø‰$è¡-‰Eø‹Eø€8;uÆà€@ÆЀ@ÇEüé™ÇEôЀ@‹Uø¾‰$è.-…Àu‹Eø¾‰$ÿEøèÅ1ˆÂ‹EôˆÿEôëÑ‹EôÆ‹Uø‰$è5-‰Eø‹Eø€8;uÆà€@ÇEüë7ÇEôà€@‹Uø€: +tÿEøƒ}ü +uËEøƃ}üÿu +ÿ`@ÇEìƒ}ìtÇ$;p@è +‰$èE‹p@¡d@)Ѓè‰$èÿƒDƒ@ÇEèérƒ}ðu ƒ}ìuéƒ=d@tÇ$³q@èôÇEèé@ƒ}ðƒ}ìëÇ$Çq@èÎÇEèéƒ}ðu +‹Eüƒà…Àuƒ}ìu$‹Eüƒà…ÀuëÇ$äq@è”ÇEèéàƒ}ðtƒ}ìtÇ$r@èpÇEè鼃}ðt +‹EüEð@‰Eüƒ}ìt +‹EüEìH‰Eü‹Eø‰$èˉÂEü‹Eü‰$è'‹EìEðDƒ@@£Dƒ@ÇEèéa‹Eø‰$è‰ÂEüƒ=h@t.‹EüƒÀ ‰$èà¡d@‰$襃Dƒ@ÇEèéƒ=l@t5‹EüƒÀ‰$è©¡d@‰$èô!‰$è”ÿDƒ@ÇEèéÚƒ=d@u‹EüƒÀ‰$èkÇEèé·ƒ=d@ð|Aƒ=d@8‹Eüƒà…Àu.Eüƒ ‹d@ƒâEü‹Eü‰$è$ÿDƒ@ÇEèëmƒ=d@€|;ƒ=d@2‹EüƒÀ‰$èõ¡d@‰$è@!‰$èàÿDƒ@ÇEèë)‹EüƒÀ ‰$èád@‰$舃Dƒ@ÇEè‹EèÉÃU‰åƒìƒ`@èø‰Eü‹Eü‰$èE‹E‰$èu¸ÉÃU‰åƒì‹E‰Eøƒ}øt%ƒ}øƒ}øtë2ƒ}øtƒ}øtë$ÇEüë.ÇEü ë%ÇEü@ëÇEü`ëÇ$r@èÇEü‹EüÉÃU‰åƒì€=à€@#u ÇEüëNÇEøà€@‹Eø€8t&‹Eø€8 t‹Eø€8 t‹Eø€8,u ÇEüëÿEøëÒ€=à€@[u ÇEüëÇEü‹EüÉÃU‰åƒìÇD$2r@¡`@‰$èï…Àt ÇEüéÇD$4r@¡`@‰$èÊ…Àt ÇEüéßÇD$6r@¡`@‰$襅Àt ÇEüéºÇD$8r@¡`@‰$者Àt ÇEüé•ÇD$:r@¡`@‰$è[…Àt ÇEüépÇD$r@¡`@‰$è…Àt ÇEüé&ÇD$@r@¡`@‰$èì…Àt ÇEüéÇD$Br@¡`@‰$èÇ…Àt ÇEüéÜÇD$ñn@¡`@‰$袅Àt ÇEüé·ÇD$Dr@¡`@‰$è}…Àt ÇEüé’ÇD$Gr@¡`@‰$èX…Àt ÇEüémÇD$Jr@¡`@‰$è3…Àt ÇEü éHÇD$Nr@¡`@‰$è…Àt ÇEü é#ÇD$Rr@¡`@‰$èé…Àt ÇEüéþÇD$Tr@¡`@‰$èÄ…Àt ÇEüéÙÇD$Vr@¡`@‰$蟅Àt ÇEü é´ÇD$Xr@¡`@‰$èz…Àt ÇEü éÇD$Zr@¡`@‰$èU…Àt ÇEü +ëmÇD$]r@¡`@‰$è3…Àt ÇEü +d@ƒ=d@ÿ„º‹Eô‰$èOëà¡`@‰$èó£`@èS =d@ÿ~'ƒ=l@u Ç$s@è5¡d@‰$è`£d@¡d@‰$èö¡`@ÿ`@€8,…Bë“¡`@‰$膣`@èæ ¡d@‰$莡`@ÿ`@€8,…ëÆ€=à€@uéø¡`@ÿ`@¶ˆEû¡`@€8t%¡`@¶:Eût¡`@¾‰$ÿ`@èZëÑ¡`@¶:Eûu ÿ`@é Ç$s@è4éèG …Àt¡d@£p@£t@è€émÇ$är@èé\€=À€@uÇ$1s@èçéBèú +„@¡„@ƒ<… „@u3ƒ=|@uƒ=$‚@tƒ=Pƒ@uèŠÇ k@ÇEüëiƒ=|@uƒ=$‚@tƒ=Pƒ@uèWÇ k@èG‰Eë5ƒ= k@u,¡„@ƒ<…„@uÇ k@ÇEüë +虉EüéŒÇD$§r@Ç$Ѐ@è]…Àu +èÙ‰EüëjÇD$r@Ç$Ѐ@è;…Àu ÇEüëIÇD$ˆr@Ç$Ѐ@è…Àu ÇEüë(ÇD$„r@Ç$Ѐ@èù…Àu ÇEüëÇEü‹EüÉÃU‰åƒì€=à€@uÇ$@u@è² +ÇEøë<Ç$à€@诉Eüƒ}üu ÇEøë‹Eü‹@;|@u ÇEøëÇEø‹EøÉÃU‰åƒì€=à€@uÇ$Ru@èM +…Àt ÇEøëÇEø‹EøÉÃU‰åSì´Ç…pÿÿÿ¡`@€8-uÿ`@Ç…lÿÿÿë +Ç…lÿÿÿ¡`@€8#uÿ`@ëî¡`@€8%uKÿ`@ÇD$nu@¡`@¾‰$è© …À„‰‹…pÿÿÿ¡`@¾ƒè0‰…pÿÿÿÿ`@뻡`@€8@uOÿ`@ÇD$qu@¡`@¾‰$èT …À„4‹…pÿÿÿÅ¡`@¾ƒè0‰…pÿÿÿÿ`@ë·¡`@€8$…Œÿ`@ÇD$zu@¡`@¾‰$è÷ …À„ס`@€89~2‹…pÿÿÿ‰ÃÁã¡`@¾‰$ÿ`@èÿ ¾ÀƒèW‰…pÿÿÿ뤋…pÿÿÿ‰ÂÁâ¡`@¾ƒè0‰…pÿÿÿÿ`@ézÿÿÿÇD$‘u@¡`@¾‰$èq …ÀtH¡`@€8/ŽG¡`@€899‹•pÿÿÿ‰ÐÁàС`@¾ƒè0‰…pÿÿÿÿ`@븡`@€8*uÿ`@¡t@‰…pÿÿÿéí¡`@€8'u8ÿ`@¡`@€8uÇ…pÿÿÿéÄ¡`@¾‰…pÿÿÿÿ`@é«¡`@¾‰$èµ …À„‰…xÿÿÿ‰…tÿÿÿ¡`@¾‰$èñ …Àt"‹…tÿÿÿ‰Â¡`@ÿ`@¶ˆ…tÿÿÿÿëÊ‹…tÿÿÿÆ…xÿÿÿ‰$虉…hÿÿÿƒ½hÿÿÿ„¯ƒ=|@…•‹…hÿÿÿ‹@‰…dÿÿÿÇ…`ÿÿÿƒ½dÿÿÿt‹…dÿÿÿ‰…`ÿÿÿ‹…dÿÿÿ‹@‰…dÿÿÿëÚÇ$èâ ‰…dÿÿÿƒ½`ÿÿÿu‹•hÿÿÿ‹…dÿÿÿ‰Bë‹•`ÿÿÿ‹…dÿÿÿ‰B‹…dÿÿÿ‹ €@‰‹…dÿÿÿÇ@¡x@‰…pÿÿÿë5ƒ=|@u èƒ=l@uÿh@Ç…pÿÿÿë Ç$œu@èpƒ=|@u:¡ €@;@u-¡ˆ@;Œ@u ƒ=l@uÿh@èë +Ç…pÿÿÿƒ½lÿÿÿt‹…pÿÿÿ÷؉…\ÿÿÿë ‹…pÿÿÿ‰…\ÿÿÿ‹…\ÿÿÿÄ´[]ÃU‰åSƒì$‹E¾‰$èÑ …ÀuÇ$´u@èÔÇEäéñ‹E‰$èï‰Eôƒ}ôt‹E‰$è €8@u‹Uô‹E ‰BÇEä鸃=|@u9‹EôÇ@‹Eô‹@;E u ÇEäéŽÇ$Èu@èYÇEäévÇ$Öu@èAÇEäé^Ç$è +‰Eôƒ}ôÿuÇ$çu@èÇEäé1‹]ô‹E‰$èõ@‰$è× ‰‹Eôƒ8ÿuÇ$çu@èÛÇEäéø‹E‰D$‹Eô‹‰$èÖ‹Uô‹E ‰B‹EôÇ@‹EôÇ@ ‹EôÇ@Ç$èn ‰Eø‹Uô‹Eø‰B‹Uø¡ €@‰‹EøÇ@¡‡@‰EðÇEìƒ}ðt9‹Eð‰Eì‹Eð‹‰D$‹E‰$èl‰Eèƒ}èy ‹Eð‹@ ‰EðëÌ‹Eð‹@‰EðëÁƒ}ìu +‰Eðƒ}ðy ‹Eôƒè‰Eøë­ƒ}ð~ ‹EôƒÀ‰Eü뜋Eô‰EìéÇEüài@ÇEøk@‹Eü;Eøwd‹Uü‹Eø)ÐÁø‰Â‰ÐÁøÁèÑøÁàEü‰Eô‹Eô‹‰D$‹E‰$è– ‰Eðƒ}ðy ‹Eôƒè‰Eøë­ƒ}ð~ ‹EôƒÀ‰Eü뜋Eô‰EìëÇEì‹EìÉÃU‰åƒìèÑ‹E‰D$Ç$ùu@èO Ç$ +è; U‰åƒì觋E‰D$Ç$ùu@è% ÉÃU‰åƒì¡ˆ@…¡”@‹‰D$Ç$ýu@èù ¡ €@‰D$Ç$›s@èä ‹E‰D$Ç$ +v@èÑ ÿäƒ@ÉÃU‰åƒì‹EˆEÿÇD$v@¾Eÿ‰$èQ…Àt ÇEøëÇEø‹EøÉÃU‰å‹E€8 t +‹E€8 tëÿEëé‹E]ÃU‰åƒì‹E‰$è~‰$è‹E‰$èb‰$èÉÃU‰åƒìƒ=|@uÿp@ÇEüëKƒ=,‚@?¡,‚@‰Â‹E‰•@‚@ÿ,‚@¡˜@‰Â‹E‰• @ÿ˜@ÿp@ƒ=˜@ uè‹EüÉÃU‰åƒìƒ=|@uéPƒ=˜@u¡p@£ ‚@é8¡˜@àƒ@¡˜@ƒÀ‰Eø¡ ‚@‰$蛉ÂEø¡ ‚@‰ÂÁúEøÇD$v@¡„@‰$è; +ÇD$!v@¡„@‰$è| ëÇD$%v@¡„@‰$èe ¡p@£ ‚@ǘ@ÉÃU‰åƒì‹E‰$ès‰E‹Uƒâ¡¤k@¾‰D$ ‹E‰ÂÁú¡¤k@¾‰D$ÇD$8v@¡„@‰$èþÉÃU‰åƒì¡ €@‰D$Ç$=v@è ƒ=,‚@u ƒ=(‚@uë¡t@‰D$Ç$Cv@èØë Ç$Hv@èÊÇEü‹Eü;,‚@}/ƒ}ü)‹Eü‹…@‚@‰$赉D$Ç$Mv@èEüÿëƃ}üÇ$Sv@èwEüÿëçÇ$Wv@èdƒ=@ƒ@t,ƒ=Dƒ@t¡Dƒ@‰D$Ç$Zv@è=ë Ç$bv@è/ÇEø@€@‹Eø€8 +tèË@‰D$‹Eø¾‰$ÿEøè³ëÙ‹Eü;,‚@}V‹Mü¸«ªª*÷é‰ÈÁø)‰ÐÀÐÀ)Á‰È…Àu Ç$iv@èÉ‹Eü‹…@‚@‰$è̉D$Ç$Mv@è§Eüÿ럃=èƒ@tÿäƒ@ƒ=äƒ@1~è?ƒ=ìƒ@tÿäƒ@ƒ=äƒ@J~è"Ç$%v@èZÉÃU‰åƒì‹EˆEÿ‹E €8t‹E ‰ÂE ÿ¶:EÿuæÇEøëÇEø‹EøÉÃU‰åƒì‹EˆEÿ€}ÿ@~€}ÿZ¶Eÿ ¾À‰Eøë¾Eÿ‰Eø‹EøÉÃU‰å¶E]ÃU‰å‹EÁø%ÿ]ÃU‰åƒì ‹E€8t!‹E €8t‹E‹U ¶:të +ÿEE ÿë׋E‹U ¶:u ÇEüë2‹E €8u#ÇD$tv@‹E¾‰$èÿÿÿ…Àt ÇEüëÇEü‹EüÉÃU‰åƒì‹EˆEÿ€}ÿz€}ÿ`~ ÇEøë:€}ÿZ€}ÿ@~ ÇEøë%€}ÿ_u ÇEøë€}ÿ.u ÇEøëÇEø‹EøÉÃU‰åƒì ‹EˆEÿ¾Eÿ‰$èˆÿÿÿ…Àt ÇEøë:€}ÿ9€}ÿ/~ ÇEøë%€}ÿ$u ÇEøë€}ÿ@u ÇEøëÇEø‹EøÉÃU‰åƒì‹EˆEÿ€}ÿ t€}ÿ t€}ÿ +të ÇEøëÇEø‹EøÉÃU‰åƒì‹E‰$èìÉÃU‰åƒì ÇEüà€@‹E‰Eø‹Eü€8t4‹Eü€8"t,‹Eü€8u ÇEôë(‹Eø‰Á‹Eü‰ÂEüÿ¶ˆEøÿëÄ‹EøÆÇEô‹EôÉÃU‰åƒì‹E‰$èr@‰$èTÿÿÿ‰Eüƒ}üt‹E‰D$‹Eü‰$èn‹EüÉÃU‰åƒì¡ˆ@…¡”@‹‰D$Ç$s@èg¡ €@‰D$Ç$›s@èRÿ$€@ÿäƒ@ÉÃU‰åƒìÇäƒ@Ç$Ro@è(¡ˆ@…¡”@‹‰D$Ç$~v@èÇ$„v@èøÇ$„v@èì¡`@‰D$ÿ`@Ç$¨v@èÑÉÃU‰åƒì‹E‰Eü‹Eü€8tEüÿëñEüÿ‹EüÉÃU‰åƒìÇD$¤ÇD$Ç$¨k@è £„@ƒ=„@y Ç$²v@è÷ÿÿ¡„@‰$èñÇD$Ç$¨k@è壄@ƒ=„@y Ç$Év@èÆöÿÿÉÃU‰åƒìÇ@ÇŒ@ÇD$ÇD$¡„@‰$è‚ÇD$ÇD$Œ@¡„@‰$è]ÇD$ÇD$@¡„@‰$è@ÉÃU‰åƒìÇD$ÇD$ˆ@¡„@‰$èÇD$ÇD$ €@¡„@‰$èöÉÃU‰åƒìÇD$ÇD$Œ@¡„@‰$èÙ‰EüÇD$ÇD$@¡„@‰$蹉Eüƒ}üÇ@ÇŒ@ÉÃU‰åƒì¡„@‰$è—‰Eüƒ}üu Ç$¨k@èbÉÃU‰åƒìƒ}t;‹E‹@ ‰$èæÿÿÿ‹E‹@‰D$‹E‹‰D$Ç$äv@è·‹E‹@‰$è¹ÿÿÿÉÃU‰åƒìÇEøƒ}„–‹E‹@ ‰$èÛÿÿÿ‹E‹@‰D$‹E‹‰D$Ç$ðv@èc‹E‹@‰Eüƒ}üt@‹UøEøÿƒú +l@l@Hl@Xl@l@G$l@W)l@$-l@%1l@'5l@,9l@.=l@"Al@$El@…Jl@ÅOl@/Sl@%Wl@#[l@-_l@+cl@&gl@*kl@ ol@!sl@wl@({l@)l@ƒl@Oˆl@_l@’l@Á—l@ƒœl@Œ¡l@ƒ¦l@Œ«l@Œ°l@´l@C¹l@S¾l@ŒÂl@<Çl@Ël@ +Ïl@JÔl@ZÙl@ˆÞl@Èãl@ çl@ ël@Lðl@\õl@ùl@ýl@$m@%m@' m@,m@.m@"m@$ m@/%m@%*m@#/m@-4m@+9m@&>m@*Cm@Hm@!Mm@ Rm@(Wm@)\m@†`m@†em@Æjm@Ænm@Ìrm@Îvm@Îzm@Ž~m@Ž‚m@ +2‡m@ +3Œm@ +0‘m@ +1–m@šm@HŸm@X¤m@¨m@D­m@T²m@= ¶m@ºm@@¿m@PÄm@Èm@ŠÌm@ŠÑm@ÊÖm@ÊÚm@ßm@ 4äm@ 6ém@ 5îm@ 7óm@ ÷m@Iüm@Yn@n@F +§r@#¬r@# ´r@# ¸r@# ½r@#Ár@#År@# +Ér@# +Îr@#Òr@#Ör@# Úr@# Þr@#'v@Fwd_refsabxadcaadcbaddaaddbadddandaandbandccaslaslaaslbasrasraasrbbccbcsbeqbgebgtbhibhsbitabitbblebloblsbltbmibnebplbrabrnbsrbvcbvsclrclraclrbcmpacmpbcmpdcmpscmpucmpxcmpycomcomacombcpxcwaidaadecdecadecbeoraeorbexgincincaincbjmpjsrlbcclbcslbeqlbgelbgtlbhilbhslblelblolblslbltlbmilbnelbpllbralbrnlbsrlbvclbvsldaldaaldabldblddldslduldxldyleasleauleaxleaylsllslalslblsrlsralsrbmulnegneganegbnoporaoraaoraborborccpshspshupulspulurolrolarolbrorrorarorbrtirtssbcasbcbsexstastaastabstbstdstsstustxstysubasubbsubdswiswi2swi3syncsystfrtsttstatstbAssembler release DWC_2.0 version 2.11 +May 6, 2004 (c) Motorola (free ware) +Usage: %s [files] +lnolcnocscrecrlfnnfp50p75ras: can't open %s +Program + Init Data = %d bytes +Error count = %d + + +S9030000FC%c +S9030000FC +.s19wCan't create object fileUnrecognized MnemonicImmediate Operand RequiredBranch out of RangeImmediate Addressing IllegalRegister Name RequiredMissing ,PCR illegal hereRegister Size MismatchIndexed Addressing RequiredRegister List RequiredIllegal Register NameCan't Push S on SCan't Push U on UCan't Pull S from SCan't Pull U from UMissing ']'Error in Mnemonic table@!@8@@ö@5@t@¢@ó@D@‚@À@í@'@C@¤@_@!@!@!@!@!@!@!@!@!@!@!@!@!@!@!@!@!@î @Unknown Addressing ModeAuto Inc/Dec Illegal on PCOffset must be ZeroAuto Inc/Dec by 1 or 2 onlyNo Auto Inc/Dec by 1 for IndirectCan't do both!Illegal Register for IndexedDdXxYyUuSPCpcPCRpcrAaBbCCccDPdp=autobssbszcodedataelseendendifequfcbfccfdbfillifdifndincludenamnameoptorgpagpageramrmbspcttlzmbUndefined Operand during Pass OneBad fillValue truncatedMissing DelimiterEQU requires labelcontcUnrecognized OPTImproper INCLUDE statementtoo many INCLUDE files%s, line no. %d: warning:can't open INCLUDE file %s +out of memory for INCLUDE file namePseudo error™-@h.@Õ.@/@†/@¹/@È-@.@0@/2@÷1@>2@Ê3@`4@‚4@¡4@¹4@í4@Ñ4@ß4@û4@Error:IFD/IFND nested too deepError: ELSE without IFError: ENDIF without IFError: file ended before IFD/IFND/ELSE/ENDIFCan't get here from there.Fatal Error: file ended before last ENDIFÕ5@”5@A6@6@Ç6@¶6@ý6@ý6@_7@n7@Ž7@}7@No symbol for IFDNo symbol for IFND+-*/&%|^01012345670123456789abcdefABCDEF0123456789Symbol undefined Pass 2Illegal Symbol NamePhasing ErrorSymbol RedefinedSymbol table full%s +%s, line no.Warning --- %s + +S1%c + +0123456789ABCDEF%c%c%04d %04X %02X [%2d ] + +,+-];*%-10s page %3d +Can't create temp fileForward ref file has gone.%-10s %04X +%-10s %04X * + : + VirtualQuery failed for %d bytes at address %p Unknown pseudo relocation protocol version %d. + Unknown pseudo relocation bit size %d. +Cygwin runtime failure: : <ð“ÜÀ”`‘|‘Œ‘˜‘¨‘´‘đБܑä‘ð‘ø‘’$’8’H’P’\’h’p’x’„’’œ’¤’¬’¸’Ä’Ð’Ü’è’ô’“““2“B“T“d“|‘Œ‘˜‘¨‘´‘đБܑä‘ð‘ø‘’$’8’H’P’\’h’p’x’„’’œ’¤’¬’¸’Ä’Ð’Ü’è’ô’“““2“B“T“d“4__getreent:__main´_dll_crt0@0_fopen64j_impure_ptr¥_lseek64È_open64œabortÜcallocñclosecygwin_create_pathcygwin_detach_dllcygwin_internal/dll_dllcrt0`exitrfclose¡fprintf¨freeßgetc»mallocÍmemcpy%printfuputcˆreadŽreallocQstrcatSstrcmpUstrcpy^strlenºunlinkØvsnprintfwritePGetModuleFileNameWQGetModuleHandleA„GetStdHandleVirtualProtect!VirtualQuery;WriteFilecygwin1.dllKERNEL32.dll  .text?.data.bss.file#þÿgas09.c_main@ State.0  '1 _whitef; _hexout‰7 _hibyte: ;g< F)= _fwdnext|> _fwdmark:> _alloc›; _alphan; _is_opJ, Pƒ, _lookupç2 ZÛ( d% qm* |b% ‡* _strsave-< ‘®; _NewPage´< _warnÕ4 _head&: _rtypeG › _any 9 ¦ +: _evalÒ* _do_gen$ _emitµ5 ²± _do_opë  ¼P _errorµ4 Ç‚3 _install¼0 _mapdnÛ9 Ñh5 _delim/5 Ý#6 çÜ7 _processŠ óI _FGETSs  ÿÇ=  +.text¨L.dataà .bss .idata$2.idata$5Ü.idata$4<.idata$7p.idata$5Ü.idata$4<.idata$6|.idata$7t.idata$5à.idata$4@.idata$6Œ.idata$7x.idata$5ä.idata$4D.idata$6˜.idata$7|.idata$5è.idata$4H.idata$6¨.idata$7„.idata$5ð.idata$4P.idata$6Ä.idata$7ˆ.idata$5ô.idata$4T.idata$6Ð.idata$7Œ.idata$5ø.idata$4X.idata$6Ü.idata$7.idata$5ü.idata$4\.idata$6ä.idata$7”.idata$5.idata$4`.idata$6ð.idata$7˜.idata$5.idata$4d.idata$6ø.idata$7œ.idata$5.idata$4h.idata$6.idata$7 .idata$5 .idata$4l.idata$6$.idata$7¤.idata$5.idata$4p.idata$68.idata$7¨.idata$5.idata$4t.idata$6H.idata$7¬.idata$5.idata$4x.idata$6P.idata$7°.idata$5.idata$4|.idata$6\.idata$7´.idata$5 .idata$4€.idata$6h.idata$7¸.idata$5$.idata$4„.idata$6p.idata$7¼.idata$5(.idata$4ˆ.idata$6x.idata$7À.idata$5,.idata$4Œ.idata$6„.idata$7Ä.idata$50.idata$4.idata$6.idata$7È.idata$54.idata$4”.idata$6œ.idata$7Ì.idata$58.idata$4˜.idata$6¤.idata$7Ð.idata$5<.idata$4œ.idata$6¬.idata$7Ô.idata$5@.idata$4 .idata$6¸.idata$7Ø.idata$5D.idata$4¤.idata$6Ä.idata$7Ü.idata$5H.idata$4¨.idata$6Ð.idata$7à.idata$5L.idata$4¬.idata$6Ü.idata$7ä.idata$5P.idata$4°.idata$6è.idata$7è.idata$5T.idata$4´.idata$6ô.idata$7ì.idata$5X.idata$4¸.idata$6.idata$4¼.idata$5\.idata$7ð¿ Ê L Ý ü8T+:°L_freeÐK I´[l_strcatÈ@ _strcmpè@ _PC_ptrtp‹XL _Argv”_Resultd_Cflag@–_P_total,_Operandॾ$Êø_regs` ×ÿÿ_putc¨@ ÿÿÿÿ_Objfil3ÿÿ_xi ÿÿƒÿÿŸ_getcÀ@ _Pflag75ì±Ã@Íݨ_rcycl  _FfnŒ_Lflag$ópL ˜L t%xL 94_rootES vXƒÿÿ› _environ ¥ˆL ¼lÈÚ$_open@ å_Old_pct_Cfnˆ__dll__ÿÿõÿÿ_Optr` +@ÿÿ%ÿÿ_memcpyhL _N_pageP;ì_F_totalàNE _ÿÿ‹ _Pass|©_FdCount\³€L ÃàШLÞ@ê___main`@ _fprintfØ@ __alloca@úPL `_table _lseek€@ _E_bytes +¨ 5¨L_E_total˜_fopen¸@ _callocàK D @ __fmode¤Pô_ |ÿÿµðÈ,Ö_CyclesDéÿÿD"ä.à<ÿÿOYÿÿ_reallocØK “0L ¦(_LabelÀ´ÿÿÉ×_hexstr¤ êù< ä Ü_CRflagX__end__- hC d_nfFlag_malloc˜@ ] °L_fcloseà@ k _strcpyÐ@ z ˆ • ÿÿ® _E_pc À @ÿÿÍ ÿÿÛ L_PC_Saveð_P_force(é H÷ ü_abort`L _Pcp_unlinkh@  + _CtotalH +) +À > +_CREflagTM +ÿÿ† +è_SflagL– +`³ + _writep@ _F_ref¿ +ÿÿ× +L å +ÿÿö +_readx@ _P_bytes@ƒ P_exitð@ _Pflag50è_printfø@ ‘ ­ _OpÐÇ ÿÿ # 9 ð_Fd„_pseudoà I Y  v @_Forward_closeˆ@ „ _mainCRTStartup_WinMainCRTStartupStackPt.1IfStack.2_pouterror_LastChar_get_term_GetToken_PC_Exchange_eval_ifnd_IfMachine_eval_ifd_FNameGet_abd_index_do_indexed_set_mode_do_pseudo_mne_look_skip_white_f_record_print_line_parse_line_fwdreinit_localinit_fwd_done_make_pass_initialize_cygwin_crt0__cygwin_crt0_common@8___dllMain_storedPtr_storedReason_storedHandle__cygwin_dll_entry@12_dll_index__cygwin_noncygwin_dll_entry@12___report_error_CYGWIN_FAILURE_MSG.31245_UNKNOWN_MODULE.31243___write_memory__pei386_runtime_relocator_was_init.31354.data_cygwin_nocopy_cygwin_premain0_cygwin_premain1_cygwin_premain2_cygwin_premain3_cygwin_attach_dll_DllMain@12_InclFiles_VirtualProtect@16___RUNTIME_PSEUDO_RELOC_LIST____imp__read__imp__vsnprintf___cygwin_crt0_bp__data_start_____DTOR_LIST____nm___impure_ptr__imp__VirtualProtect@16__imp__VirtualQuery@12_vsnprintf___tls_start____imp__cygwin_detach_dll__imp__getc__imp__abort.weak.___real__Znwj.__cygwin_crt0_common@8__dll_characteristics____size_of_stack_commit__.weak.___real__ZdlPv.__cygwin_crt0_common@8_Last_sym__size_of_stack_reserve____major_subsystem_version_____crt_xl_start_____crt_xi_start_____chkstk___crt_xi_end_____dynamically_loaded_dll_dllcrt0_VirtualQuery@12__imp__WriteFile@20_GetModuleHandleA@4__imp__putc__bss_start_____RUNTIME_PSEUDO_RELOC_LIST_END____imp__write__size_of_heap_commit___Line_num_GetModuleFileNameW@12_Force_byte___crt_xp_start___Err_count___crt_xp_end____minor_os_version____image_base____imp__exit__section_alignment____imp___impure_ptr_cygwin_internal.weak.___real__ZdaPv.__cygwin_crt0_common@8__RUNTIME_PSEUDO_RELOC_LIST___Obj_name_GetStdHandle@4__data_end____CTOR_LIST____bss_end_____crt_xc_end___cygwin_create_path_InclFName___crt_xc_start___Fwd_name___CTOR_LIST_____getreent__imp___open64___real__ZdaPvRKSt9nothrow_t.weak.___real__ZnajRKSt9nothrow_t.__cygwin_crt0_common@8_cygwin1_dll_iname__imp__memcpy__head_cygwin1_dll.weak.___real__Znaj.__cygwin_crt0_common@8__imp__strcmp_Page_lines__imp____main__file_alignment___Page_num.weak.___real__ZdaPvRKSt9nothrow_t.__cygwin_crt0_common@8_cygwin_detach_dll__imp__malloc__major_os_version_____real__Znaj__imp__dll_dllcrt0___real__ZdlPv__imp__realloc__imp___dll_crt0@0__imp____getreent__imp__GetStdHandle@4__imp__GetModuleHandleA@4__DTOR_LIST____imp__fprintf__imp__fclose__imp__close__size_of_heap_reserve_____crt_xt_start_____ImageBase__subsystem____imp__strlen__imp__strcpy__imp__calloc__imp__cygwin_internal___tls_end_____cygwin_cxx_malloc___real__ZdaPv.weak.___real__ZnwjRKSt9nothrow_t.__cygwin_crt0_common@8__imp___fopen64__imp__GetModuleFileNameW@12__imp__free__major_image_version___WriteFile@20__loader_flags____imp__printf___real__Znwj__head_libkernel32_a__minor_subsystem_version____minor_image_version___Force_word___real__ZnajRKSt9nothrow_t__imp__unlink___real__ZnwjRKSt9nothrow_t__imp__cygwin_create_path.weak.___real__ZdlPvRKSt9nothrow_t.__cygwin_crt0_common@8__RUNTIME_PSEUDO_RELOC_LIST_END____libkernel32_a_iname__imp___lseek64___crt_xt_end_____real__ZdlPvRKSt9nothrow_t__imp__strcat \ No newline at end of file
/Makefile
0,0 → 1,16
 
MKFRAGS := ../../mkfiles
export MKFRAGS
 
C_SRC := as.c as09.c do09.c eval.c ffwd.c ifd.c output.c pseudo.c symtab.c util.c
HEADERS := as.h table09.h
 
include $(MKFRAGS)/def_cmds.mk
 
as09$(EXE_EXT): $(HEADERS) $(C_SRC)
gcc -I. -DWIN32 -o $@ as09.c
 
clean:
rm as09$(EXE_EXT)
 
 
/pseudo.c
0,0 → 1,324
/*
* pseudo --- pseudo op processing
*/
 
#define RMB 0 /* Reserve Memory Bytes */
#define FCB 1 /* Form Constant Bytes */
#define FDB 2 /* Form Double Bytes (words) */
#define FCC 3 /* Form Constant Characters */
#define ORG 4 /* Origin */
#define EQU 5 /* Equate */
#define ZMB 6 /* Zero memory bytes */
#define FILL 7 /* block fill constant bytes */
#define OPT 8 /* assembler option */
#define NULL_OP 9 /* null pseudo op */
#define PAGE 10 /* new page */
#define INCLUDE 11 /* include <file> or "file" ver TER_2.0 */
#define END 12 /* include <file> terminator ver TER_2.0 */
#define IFD 13 /* if define <symbol> ver TER_2.0 */
#define IFND 14 /* if not define <symbol> ver TER_2.0 */
#define ELSE 15 /* else (for IF statements) ver TER_2.0 */
#define ENDIF 16 /* endif (for IF statements) ver TER_2.0 */
#define BSS 17 /* block storage segment (RAM) ver TER_2.09 */
#define CODE 18 /* code segment ver TER_2.09 25 Jul 89 */
#define DATA 19 /* data segment ver TER_2.09 25 Jul 89 */
#define AUTO 20 /* data segment ver TER_2.09 25 Jul 89 */
 
struct oper pseudo[] = {
"=", PSEUDO, EQU, 0, /* ver TER_2.09 25 Jul 89 */
"auto", PSEUDO, AUTO, 0, /* ver TER_2.09 25 Jul 89 */
"bss", PSEUDO, BSS, 0, /* ver TER_2.09 25 Jul 89 */
"bsz", PSEUDO, ZMB, 0,
"code", PSEUDO, CODE, 0, /* ver TER_2.09 25 Jul 89 */
"data", PSEUDO, DATA, 0, /* ver TER_2.09 25 Jul 89 */
"else", PSEUDO, ELSE, 0, /* ver TER_2.0 6/17/89 */
"end", PSEUDO, END, 0, /* ver TER_2.0 6/17/89 */
"endif",PSEUDO, ENDIF, 0, /* ver TER_2.0 6/17/89 */
"equ", PSEUDO, EQU, 0,
"fcb", PSEUDO, FCB, 0,
"fcc", PSEUDO, FCC, 0,
"fdb", PSEUDO, FDB, 0,
"fill", PSEUDO, FILL, 0,
"ifd", PSEUDO, IFD, 0, /* ver TER_2.0 6/17/89 */
"ifnd", PSEUDO, IFND, 0, /* ver TER_2.0 6/17/89 */
"include", PSEUDO, INCLUDE, 0, /* ver TER_2.0 6/17/89 */
"nam", PSEUDO, NULL_OP,0,
"name", PSEUDO, NULL_OP,0,
"opt", PSEUDO, OPT, 0,
"org", PSEUDO, ORG, 0,
"pag", PSEUDO, PAGE, 0,
"page", PSEUDO, PAGE, 0,
"ram", PSEUDO, BSS, 0, /* ver TER_2.09 25 Jul 89 */
"rmb", PSEUDO, RMB, 0,
"spc", PSEUDO, NULL_OP,0,
"ttl", PSEUDO, NULL_OP,0,
"zmb", PSEUDO, ZMB, 0
};
 
/*
* do_pseudo --- do pseudo op processing
*/
do_pseudo(op)
int op; /* which op */
{
char fccdelim, *strsave();
int fill;
int c; /*test variable ver TER_2.0 6/18/89 */
char *skip_white(), *savept; /* savept is pointer to string save */
FILE *FdTemp, *fopen(); /* ver TER_2.0 6/17/89 */
void pouterror(), NewPage(), IfMachine(); /* rel TER_2.0 6/18/89 */
void PC_Exchange(); /* ver TER_2.09 25 Jul 89 */
 
if( op != EQU && *Label )
install(Label,Pc);
 
P_force++;
 
#ifdef DEBUG3
printf("%s, line no. ",Argv[Cfn]); /* current file name */
printf("%d: ",Line_num); /* current line number */
printf(" Pseudo Op=%u\n",op);
#endif
 
switch(op){
case RMB: /* reserve memory bytes */
if( eval() ){
Pc += Result;
f_record(); /* flush out bytes */
}
else
error("Undefined Operand during Pass One");
break;
case ZMB: /* zero memory bytes */
if( eval() )
while( Result-- )
emit(0);
else
error("Undefined Operand during Pass One");
break;
case FILL: /* fill memory with constant */
eval();
fill = Result;
if( *Optr++ != ',' )
error("Bad fill");
else{
Optr = skip_white(Optr);
eval();
while( Result-- )
emit(fill);
}
break;
case FCB: /* form constant byte(s) */
do{
Optr = skip_white(Optr);
eval();
if( Result > 0xFF ){
if(!Force_byte)
warn("Value truncated");
Result = lobyte(Result);
}
emit(Result);
}while( *Optr++ == ',' );
break;
case FDB: /* form double byte(s) */
do{
Optr = skip_white(Optr);
eval();
eword(Result);
}while( *Optr++ == ',' );
break;
case FCC: /* form constant characters */
if(*Operand==EOS)
break;
fccdelim = *Optr++;
while( *Optr != EOS && *Optr != fccdelim)
emit(*Optr++);
if(*Optr == fccdelim)
Optr++;
else
error("Missing Delimiter");
break;
case ORG: /* origin */
if( eval() ){
Old_pc = Pc = Result;
f_record(); /* flush out any bytes */
}
else
error("Undefined Operand during Pass One");
break;
case EQU: /* equate */
if(*Label==EOS){
error("EQU requires label");
break;
}
if( eval() ){
install(Label,Result);
Old_pc = Result; /* override normal */
}
else
error("Undefined Operand during Pass One");
break;
case OPT: /* assembler option */
P_force=0;
if( head(Operand,"l") )
Lflag=1;
else if (head(Operand,"nol"))
Lflag=0;
else if (head(Operand,"c")){
Cflag=1;
Ctotal=0;
}
else if (head(Operand,"noc"))
Cflag=0;
else if (head(Operand,"contc")){
Cflag=1;
}
else if (head(Operand,"s"))
Sflag = 1;
else if (head(Operand,"cre"))
CREflag = 1;
else if (head(Operand,"p50")){ /* turn on 50 lines/page flag */
Pflag50 = 1;
Pflag75 = 0;
} /* separately. ver TER_2.0 6/17/89 */
else if (head(Operand,"p75")){ /* turn on 75 lines/page flag */
Pflag50 = 0;
Pflag75 = 1;
} /* separately. ver TER_2.0 6/17/89 */
else if (head(Operand,"crlf")) /* add <CR> <LF> to */
CRflag = 1; /* S record ver TER_2.08 */
else if (head(Operand,"nnf")) /* no extra line no. */
nfFlag = 0; /* w include files ver TER_2.08 */
else
error("Unrecognized OPT");
break;
case PAGE: /* go to a new page */
P_force=0;
N_page = 1;
if (Pass == 2 )
if (Lflag) NewPage();
break;
case NULL_OP: /* ignored psuedo ops */
P_force=0;
break;
case INCLUDE: /* case INCLUDE added ver TER_2.0 6/17/89 */
P_force=0; /* no PC in printed output */
if ((c=FNameGet(InclFName))==0)
error("Improper INCLUDE statement");
else
{
if (FdCount > MAXINCFILES)
error("too many INCLUDE files");
else
{
if ((FdTemp = fopen(InclFName,"r"))==0)
{
printf("%s, line no. ",Argv[Cfn]);
/* current file name */
printf("%d: ",Line_num); /* current line number */
Page_lines++; /* increment lines per page */
printf("warning:can't open INCLUDE file %s\n",InclFName);
}
else
{
if ((savept=strsave(InclFName))==0)
error("out of memory for INCLUDE file name");
else
{
InclFiles[FdCount].fp=Fd; /* save current fp */
if (nfFlag)
{
InclFiles[FdCount].line_num=Line_num;
/* save current line count */
Line_num=0; /* reset for new file */
}
InclFiles[FdCount].name=Argv[Cfn];
/* save pointer to current name */
Argv[Cfn]=savept;
/* now replace pointer to current name with
pointer to name of Include file */
Fd=FdTemp; /* now replace current file with
INCLUDE fp */
FdCount++; /* and increment "stack" */
#ifdef DEBUG2
printf("pseudo INCLUDE: FdCount=%d\n",FdCount);
printf(" new input file pointer=%d\n",Fd);
printf(" new file name=%s\n",Argv[Cfn]);
#endif
}
}
}
}
break;
case END:
P_force=0;
if (FdCount>0) /* skip END statements in files
received from CLI arguments */
{
fclose(Fd); /* close file from this level nest */
FdCount--; /* "pop stack" */
Fd=InclFiles[FdCount].fp; /* restore fp from
nested stack */
if(nfFlag) Line_num=InclFiles[FdCount].line_num;
Argv[Cfn]=InclFiles[FdCount].name;
/* restore file name pointer */
#ifdef DEBUG2
printf("pseudo END: FdCount=%d\n",FdCount);
printf(" new input file pointer=%d\n",Fd);
printf(" new file name=%s\n",Argv[Cfn]);
#endif
}
break;
case IFD:
#ifdef DEBUG3
printf("case IFD: in pseudo\n");
#endif
P_force=0;
c=eval_ifd();
IfMachine(c);
break;
case IFND:
P_force=0;
c=eval_ifnd();
IfMachine(c);
break;
case ELSE:
P_force=0;
IfMachine(IF_ELSE);
break;
case ENDIF:
P_force=0;
IfMachine(IF_ENDIF);
break;
case CODE: /* CODE,DATA,BSS,AUTO ver TER_2.09 */
PC_Exchange(0);
break;
case DATA:
PC_Exchange(1);
break;
case BSS:
PC_Exchange(2);
break;
case AUTO:
PC_Exchange(3);
break;
default:
fatal("Pseudo error");
break;
}
}
 
 
/*
* PC_Exchange --- Save current PC and recover requested one
added ver TER_2.09
*/
void PC_Exchange(PC_ptr_new)
int PC_ptr_new; /* request 0=CODE,1=DATA,2=BSS */
{
P_force = 0; /* no PC in output cuz wrong first time (?) */
PC_Save[PC_ptr] = Pc; /* save current PC */
PC_ptr = PC_ptr_new; /* remember which one we're using */
Old_pc = Pc = PC_Save[PC_ptr]; /* recover the one requested */
f_record(); /* flush out any bytes, this is really an ORG */
}
/symtab.c
0,0 → 1,157
/*
* install --- add a symbol to the table
*/
install(str,val)
char *str;
int val;
{
struct link *lp;
struct nlist *np,*p,*backp;
struct nlist *lookup();
int i;
char *LastChar(); /* ver TER_2.0 */
 
if( !alpha(*str) ){
error("Illegal Symbol Name");
return(NO);
}
if( (np = lookup(str)) != NULL ){
if (*LastChar(str) == '@') { /* redefinable symbol ver TER_2.0 */
np->def = val; /* redefined */
return(YES);
}
if( Pass==2 ){
np->def2 = 2; /* defined for this pass=Pass ver TER_2.0 */
if( np->def == val )
return(YES);
else{
error("Phasing Error");
return(NO);
}
}
error("Symbol Redefined");
return(NO);
}
/* enter new symbol */
#ifdef DEBUG
printf("Installing %s as %d\n",str,val);
#endif
np = (struct nlist *) alloc(sizeof(struct nlist));
if( np == (struct nlist *)ERR ){
error("Symbol table full");
return(NO);
}
np->name = alloc(strlen(str)+1);
if( np->name == (char *)ERR ){
error("Symbol table full");
return(NO);
}
strcpy(np->name,str);
np->def = val;
np->def2 = 1; /* defined for this pass=Pass ver TER_2.0 */
np->Lnext = NULL;
np->Rnext = NULL;
lp = (struct link *) alloc(sizeof(struct link));
np->L_list = lp;
lp->L_num = Line_num;
lp->next = NULL;
p = root;
backp = NULL;
while (p != NULL)
{
backp = p;
i = strcmp (str,p->name);
if (i<0)
p=p->Lnext;
else p=p->Rnext;
}
if (backp == NULL)
root = np;
else if (strcmp(str,backp->name)<0)
backp->Lnext = np;
else backp->Rnext = np;
return (YES);
}
 
/*
* lookup --- find string in symbol table
*/
struct nlist *
lookup(name)
char *name;
{
struct nlist *np;
int i;
char *c; /* ver TER_2.0 */
 
c = name; /* copy symbol pointer */
while(alphan(*c)) /* search for end of symbol */
c++; /* next char */
*c = EOS; /* disconnect anything after for good compare */
/* end of mods for ver TER_2.0 */
 
np = root; /* and now go on and look for symbol */
while (np != NULL)
{
i = strcmp(name,np->name);
if (i == 0)
{
Last_sym = np->def;
return (np);
}
else if (i < 0)
np = np->Lnext;
else np = np->Rnext;
}
Last_sym = 0;
/* if (Pass == 2)
error ("symbol Undefined on pass 2"); */
/* commented out ver TER_2.0 2 Jul 89 */
/* function used in IFD */
return (NULL);
}
 
 
#define NMNE (sizeof(table)/ sizeof(struct oper))
#define NPSE (sizeof(pseudo)/ sizeof(struct oper))
/*
* mne_look --- mnemonic lookup
*
* Return pointer to an oper structure if found.
* Searches both the machine mnemonic table and the pseudo table.
*/
struct oper *
mne_look(str)
char *str;
{
struct oper *low,*high,*mid;
int cond;
 
/* Search machine mnemonics first */
low = &table[0];
high = &table[ NMNE-1 ];
while (low <= high){
mid = low + (high-low)/2;
if( ( cond = strcmp(str,mid->mnemonic)) < 0)
high = mid - 1;
else if (cond > 0)
low = mid + 1;
else
return(mid);
}
 
/* Check for pseudo ops */
low = &pseudo[0];
high = &pseudo[ NPSE-1 ];
while (low <= high){
mid = low + (high-low)/2;
if( ( cond = strcmp(str,mid->mnemonic)) < 0)
high = mid - 1;
else if (cond > 0)
low = mid + 1;
else
return(mid);
}
 
return(NULL);
}
/output.c
0,0 → 1,42
/*
* stable --- prints the symbol table in alphabetical order
*/
stable(ptr)
 
struct nlist *ptr;
{
if (ptr != NULL)
{
stable (ptr->Lnext);
printf ("%-10s %04X\n",ptr->name,ptr->def);
stable (ptr->Rnext);
}
}
/*
* cross -- prints the cross reference table
*/
cross(point)
 
struct nlist *point;
{
struct link *tp;
int i = 1;
if (point != NULL)
{
cross (point->Lnext);
printf ("%-10s %04X *",point->name,point->def);
tp = point->L_list;
while (tp != NULL)
{
if (i++>10)
{
i=1;
printf("\n ");
}
printf ("%04d ",tp->L_num);
tp = tp->next;
}
printf ("\n");
cross (point->Rnext);
}
}
/ifd.c
0,0 → 1,246
/* IfMachine() --- This function implements the IFD & IFND conditional
assembly machine.
version 1.0 made for release TER_2.0 cross assembler 27 Jun 89
*/
 
#define FALSE_BLOCK 0 /* values for state variable */
#define TRUE_BLOCK 1
#define POP_TEST 2
#define ELSE_TEST 3
#define FALSE 0
#define TRUE 1
 
void IfMachine(Token)
int Token; /* input token from calling machine */
/* See file as.h for definition (globals) */
{
static int State = TRUE_BLOCK, StackPt = 0, IfStack[MAXIFD];
/* State variable, pointer to "IF stack pointer" and "Stack" */
int Hiatus; /* flag to break out of FSM & resume normal processing */
 
Hiatus=FALSE; /* infinite loop to operate machine
until time to break out */
do /* test at end */
{
 
#ifdef DEBUG3
printf("IfMachine state=%u , token=%u\n",State,Token);
#endif
 
if (State == TRUE_BLOCK) /* a block of statements processed normally */
switch(Token) {
case IF_TRUE:
IfStack[StackPt]=TRUE;
if (++StackPt > MAXIFD) { /* check for over flow */
StackPt = MAXIFD;
error("Error:IFD/IFND nested too deep");
}
/* print_line() will be done in normal processing */
Hiatus = TRUE; /* resume normal line processing */
break;
case IF_FALSE:
IfStack[StackPt]=TRUE;
if (++StackPt > MAXIFD) { /* check for over flow */
StackPt = MAXIFD;
error("Error:IFD/IFND nested too deep");
}
if (Pass == 2 && Lflag && !N_page) /* need to print here */
print_line(); /* cuz will not return to normal */
Token = GetToken(); /* get next line & examine for IF */
State = FALSE_BLOCK; /* change state */
break;
case IF_ELSE:
if (StackPt == 0) /* bad IF nesting */
error("Error: ELSE without IF");
if (Pass == 2 && Lflag && !N_page)
print_line();
Token = GetToken(); /* get next line & examine for IF */
State = FALSE_BLOCK;
break;
case IF_ENDIF:
if (StackPt == 0) /* bad IF nesting */
error("Error: ENDIF without IF");
else
StackPt--; /* popped state must be TRUE */
Hiatus = TRUE;
break;
/* case NORMAL is not implemented as it represents normal line
processing. */
case IF_END: /* file ended with improperly nested IFD */
/* this code can't actually be reached at present
in a TRUE_BLOCK */
fatal("Error: file ended before IFD/IFND/ELSE/ENDIF");
break;
default: /* This code can't be reached at the present.
Logically would happen if EOF but handled
else where */
fatal("Can't get here from there.");
break;
}
else if (State == FALSE_BLOCK) /* statements not processed */
switch(Token) {
case IF_TRUE: /* doesn't make any diff. Just nest IFs */
case IF_FALSE:
IfStack[StackPt]=FALSE;
if (++StackPt > MAXIFD) {
StackPt = MAXIFD;
error("Error:IFD/IFND nested too deep");
}
if (Pass == 2 && Lflag && !N_page)
print_line();
Token = GetToken();
break;
case IF_ELSE:
/* if (Pass == 2 && Lflag && !N_page) */
/* print_line(); */
State = ELSE_TEST;
break;
case IF_ENDIF:
State = POP_TEST;
break;
case IF_END: /* file ended with improperly nested IFD */
fatal("Fatal Error: file ended before last ENDIF");
/* Fatal will exit assembler. Things are too
messed up. Include file handling is else where
and don't want to duplicate here. */
break;
case IF_NORMAL: /* normal line in a FALSE BLOCK */
if (Pass == 2 && Lflag && !N_page)
print_line();
Token = GetToken();
break;
default:
fatal("Fatal Error: file ended before last ENDIF");
/* must be EOF or something else terrible */
break;
}
else if (State == POP_TEST) { /* pop up outside nest state */
if (StackPt == 0) { /* bad IF nesting */
error("Error: ENDIF without IF");
if (Pass == 2 && Lflag && !N_page)
print_line();
State = TRUE;
}
else {
StackPt--; /* pop stack */
if (IfStack[StackPt] == TRUE) { /* back to normal */
/* had to come from FALSE block cuz TRUE block cannot
be inside FALSE block */
if (Pass == 2 && Lflag && !N_page)
print_line();
State = TRUE;
Hiatus = TRUE; /* sleep for normal line processing */
}
else { /* gotta be that stack == FALSE, still inside FALSE nest */
if (Pass == 2 && Lflag && !N_page)
print_line();
State = FALSE;
Token = GetToken();
}
}
}
else if (State == ELSE_TEST) { /* change state */
if (IfStack[StackPt-1] == TRUE) {
State = TRUE_BLOCK;
Hiatus = TRUE;
}
else
State = FALSE_BLOCK;
}
}
while (Hiatus == FALSE); /* loop if not exit */
}
 
 
/* GetToken() --- get another line from within False Block and extract token
as would be done in pseudo.c. Returns token id:
IF_TRUE IFD/IFND evaluated to TRUE
IF_FALSE IFD/IFND evaluated to FALSE
IF_ELSE ELSE pseudo op
IF_ENDIF ENDIF pseudo op
IF_END END pseudo op
IF_NORMAL none of the above, perhaps assy code
IF_EOF encountered end of file
This function exists because conditional assembly was added
as pseudo op rather than with key character ("%") and did
not want to disturb original software topology */
 
int GetToken() /* get another line and find token in it */
{ /* similar to make_pass() except one line at a time */
/* most variables & constants are global */
 
struct nlist *lookup();
 
#ifndef IBM
if (FGETS(Line,MAXBUF-1,Fd) == (char *)NULL)
#else
if (fgets(Line,MAXBUF,Fd) == (char *)NULL)
#endif
return(IF_EOF); /* banged into eof */
Line_num++;
P_force=0;
N_page=0;
if (!parse_line())
return(IF_NORMAL); /* comment line */
if (*Op==EOS) /* skipping over label, probably. */
return(IF_NORMAL); /* strcmp() returns 0 if arg1 is NULL string */
 
if (strcmp(Op,"ifd")==0)
return(eval_ifd());
else if (strcmp(Op,"ifnd")==0)
return(eval_ifnd());
else if (strcmp(Op,"else")==0)
return(IF_ELSE);
else if (strcmp(Op,"endif")==0)
return(IF_ENDIF);
else if (strcmp(Op,"end")==0)
return(IF_END);
else
return(IF_NORMAL); /* or might be garbage...but who cares?
This is FALSE BLOCK */
}
 
 
/*
* eval_ifd() --- evaluate an if define statement for TRUE or FALSE
*/
 
int
eval_ifd()
{
struct nlist *np; /* symbol structure */
 
if (*Operand==EOS) {
warn("No symbol for IFD");
return(IF_FALSE); /* nothing to check */
}
if ((np=lookup(Operand)) == NULL)
return(IF_FALSE); /* not defined at all...yet */
else
if(np->def2 == Pass)
return(IF_TRUE); /* defined for this pass */
 
return(IF_FALSE); /* not defined this pass */
}
 
/*
* eval_ifnd() --- evaluate an if not define statement for TRUE or FALSE
*/
 
int
eval_ifnd()
{
struct nlist *np; /* symbol structure */
 
if (*Operand==EOS) {
warn("No symbol for IFND");
return(IF_TRUE); /* nothing to check */
}
if ((np=lookup(Operand)) == NULL)
return(IF_TRUE); /* not defined at all...yet */
else
if(np->def2 == Pass)
return(IF_FALSE); /* defined for this pass */
 
return(IF_TRUE); /* not defined this pass */
}
/as.c
0,0 → 1,313
char mapdn();
char *alloc();
/*
* as --- cross assembler main program
 
Note: Compile with define DEBUG for function module debug
statements. Compile with define DEBUG2 for version 2 debug
statements only. Compile with define IBM to use original, non-
Amiga, non-MAC, non-UNIX fgets() function. Amiga version will
accept IBM generated source code but not the other way around.
Note added version (TER) 2.01 19 June 1989.
 
Additional modifications to cleanup output listing made by
Donald W. Coates 1/5/92. Version changed to 2.10
*/
main(argc,argv)
int argc;
char **argv;
{
char **np;
char *i;
FILE *fopen();
int j = 0;
void do_op(),f_record(); /* added for ANSI C compat ver TER_2.0 6/18/89 */
 
printf("Assembler release DWC_2.0 version 2.11\n");
printf("May 6, 2004 (c) Motorola (free ware)\n");
 
if(argc < 2){
printf("Usage: %s [files]\n",argv[j]);
exit(1);
}
Argv = argv;
initialize();
while ((j<argc) && (*argv[j] != '-'))
j++;
N_files = j-1;
if (j < argc )
{
argv[j]++;
while (j<argc)
{
for (i = argv[j]; *i != 0; i++)
if ((*i <= 'Z') && (*i >= 'A'))
*i = *i + 32;
if (strcmp(argv[j],"l")==0)
Lflag = 1;
else if (strcmp(argv[j],"nol")==0)
Lflag = 0;
else if (strcmp(argv[j],"c")==0)
Cflag = 1;
else if (strcmp(argv[j],"noc")==0)
Cflag = 0;
else if (strcmp(argv[j],"s")==0)
Sflag = 1;
else if (strcmp(argv[j],"cre")==0)
CREflag = 1;
else if (strcmp(argv[j],"crlf")==0) /* test for crlf option */
CRflag = 1; /* add <CR><LF> to S record */
/* ver TER_1.1 June 3, 1989 */
else if (strcmp(argv[j],"nnf")==0) /* test for nnf option */
nfFlag=0; /* nfFlag=1 means number INCLUDE */
/* separately. ver TER_2.0 6/17/89 */
else if (strcmp(argv[j],"p50")==0){ /* page every 50 lines */
Pflag50 = 1; /* ver (TER) 2.01 19 Jun 89 */
Pflag75 = 0;
} /* separately. ver TER_2.0 6/17/89 */
else if (strcmp(argv[j],"p75")==0){ /* page every 75 lines */
Pflag50 = 0; /* ver (DWC) 2.10 8 Oct 2001 */
Pflag75 = 1;
}
j++;
}
}
root = NULL;
 
Cfn = 0;
np = argv;
Line_num = 0; /* reset line number */
while( ++Cfn <= N_files )
if((Fd = fopen(*++np,"r")) == NULL)
printf("as: can't open %s\n",*np);
else{
make_pass();
fclose(Fd);
}
if( Err_count == 0 ){
Pass++;
re_init();
Cfn = 0;
np = argv;
Line_num = 0;
FdCount=0; /* Resets INCLUDE file nesting ver TER_2.0 6/17/89 */
while( ++Cfn <= N_files)
if((Fd = fopen(*++np,"r")) != NULL)
{
make_pass();
fclose(Fd);
}
printf ("Program + Init Data = %d bytes\n",F_total); /* print total bytes */
printf ("Error count = %d\n",Err_count); /* rel TER_2.0 */
if (Sflag == 1)
{
printf ("\n\f\n");
stable (root);
}
if (CREflag == 1)
{
printf ("\n\f\n");
cross (root);
}
if (CRflag == 1)
fprintf(Objfil,"S9030000FC%c\n",CR); /* ver TER_1.1 print w <CR> */
else
fprintf(Objfil,"S9030000FC\n"); /* at least give a decent ending */
fclose(Objfil); /* close file correctly ver TER_1.1 */
}
else /* just note errors, TER_2.0 */
{
printf ("Program + Init Data = %d bytes\n",F_total); /* print total bytes */
printf ("Error count = %d\n",Err_count);
}
fwd_done();
exit(Err_count); /* neat for UNIX cuz can test return value in script
but on other systems like Amiga, mostly just makes
further script statements fail if >10, else
nothing. Therefore, printed out byte count
and error level. ver (TER) 2.02 19 Jun 89 */
}
 
initialize()
{
FILE *fopen();
int i = 0;
 
#ifdef DEBUG
printf("Initializing\n");
#endif
Err_count = 0;
Pc = 0;
Pass = 1;
Lflag = 0;
Cflag = 0;
Ctotal = 0;
Sflag = 0;
CREflag = 0;
N_page = 0;
Line[MAXBUF-1] = NEWLINE;
 
strcpy(Obj_name,Argv[1]); /* copy first file name into array */
do {
if (Obj_name[i]=='.')
Obj_name[i]=0;
}
while (Obj_name[i++] != 0);
strcat(Obj_name,".s19"); /* append .out to file name. */
if( (Objfil = fopen(Obj_name,"w")) == NULL)
fatal("Can't create object file");
fwdinit(); /* forward ref init */
localinit(); /* target machine specific init. */
}
 
re_init()
{
#ifdef DEBUG
printf("Reinitializing\n");
#endif
Pc = 0;
E_total = 0;
P_total = 0;
Ctotal = 0;
N_page = 0;
fwdreinit();
}
 
make_pass()
{
#ifdef IBM
char *fgets(); /* the original line */
#else
char *FGETS(); /* use own FGETS which is rewrite of lib function */
/* such that it discards <CR> so can read code */
/* generated on IBM */
/* June 3, 1989 rev TER_1.1 */
#endif
 
#ifdef DEBUG
printf("Pass %d\n",Pass);
#endif
 
#ifndef IBM
while( FGETS(Line,MAXBUF-1,Fd) != (char *)NULL ){ /* changed to FGETS */
/* which does not pass on <CR> June 3, 1989 */
/* rev TER_1.1 */
#else
while( fgets(Line,MAXBUF,Fd) != (char *)NULL ){
 
#endif
 
Line_num++;
P_force = 0; /* No force unless bytes emitted */
N_page = 0;
if(parse_line())
process();
if(Pass == 2 && Lflag && !N_page)
print_line();
P_total = 0; /* reset byte count */
Cycles = 0; /* and per instruction cycle count */
}
f_record();
}
 
 
/*
* parse_line --- split input line into label, op and operand
*/
parse_line()
{
register char *ptrfrm = Line;
register char *ptrto = Label;
char *skip_white();
 
if( *ptrfrm == '*' || *ptrfrm == '\n' || *ptrfrm == ';' )
/* added check for ';' ver TER_1.1 */
/* June 3, 1989 */
return(0); /* a comment line */
 
while( delim(*ptrfrm)== NO ) /* parsing Label */
*ptrto++ = *ptrfrm++;
if(*--ptrto != ':')ptrto++; /* allow trailing : */
*ptrto = EOS;
 
ptrfrm = skip_white(ptrfrm);
if (*ptrfrm == ';') { /* intercept comment after label, ver TER_2.0 */
*Op = *Operand = EOS; /* comment, no Opcode or Operand */
return(1); }
ptrto = Op;
 
while( delim(*ptrfrm) == NO) /* parsing Opcode */
*ptrto++ = mapdn(*ptrfrm++);
*ptrto = EOS;
 
ptrfrm = skip_white(ptrfrm);
if (*ptrfrm == ';') { /* intercept comment, ver TER_2.0 */
*Operand = EOS; /* comment, no Operand */
return(1); }
 
ptrto = Operand;
while( (*ptrfrm != NEWLINE) && (*ptrfrm != ';')) /* ver TER_2.0 */
*ptrto++ = *ptrfrm++; /* kill comments */
*ptrto = EOS;
 
#ifdef DEBUG
printf("Label-%s-\n",Label);
printf("Op----%s-\n",Op);
printf("Operand-%s-\n",Operand);
#endif
return(1);
}
 
/*
* process --- determine mnemonic class and act on it
*/
process()
{
register struct oper *i;
struct oper *mne_look();
 
Old_pc = Pc; /* setup `old' program counter */
Optr = Operand; /* point to beginning of operand field */
 
if(*Op==EOS){ /* no mnemonic */
if(*Label != EOS)
install(Label,Pc);
}
else if( (i = mne_look(Op))== NULL)
error("Unrecognized Mnemonic");
else if( i->class == PSEUDO )
do_pseudo(i->opcode);
else{
if( *Label )install(Label,Pc);
if(Cflag)Cycles = i->cycles;
do_op(i->opcode,i->class);
if(Cflag)Ctotal += Cycles;
}
}
 
#ifndef IBM
char *FGETS(s, n, iop) /* get at most n chars from iop */
/* Added rev TER_1.1 June 3, 1989 */
/* Adapted from Kernighan & Ritchie */
/* An fgets() that is IBM proof. Not needed if
this IS an IBM */
 
char *s;
int n;
register FILE *iop;
{
register int c;
register char *cs;
 
cs=s;
while (--n > 0 && (c = getc(iop)) != EOF) /* read chars if not file end */
{
if ((*cs = c) != CR) cs++; /* incr buffer pointer if not CR */
/* If CR, leave to be written over */
if (c == '\n')
break;
}
*cs = '\0'; /* replace NEWLINE with NULL as in standard fgets() */
return((c == EOF && cs == s) ? NULL : s); /* return NULL if this is EOF */
}
#endif
/table09.h
0,0 → 1,152
struct oper table[] = {
 
"abx", INH, 58, 3,
"adca", GEN, 137, 2,
"adcb", GEN, 201, 2,
"adda", GEN, 139, 2,
"addb", GEN, 203, 2,
"addd", LONGIMM, 195, 4,
"anda", GEN, 132, 2,
"andb", GEN, 196, 2,
"andcc", IMM, 28, 3,
"asl", GRP2, 8, 4,
"asla", INH, 72, 2,
"aslb", INH, 88, 2,
"asr", GRP2, 7, 4,
"asra", INH, 71, 2,
"asrb", INH, 87, 2,
"bcc", REL, 36, 3,
"bcs", REL, 37, 3,
"beq", REL, 39, 3,
"bge", REL, 44, 3,
"bgt", REL, 46, 3,
"bhi", REL, 34, 3,
"bhs", REL, 36, 3,
"bita", GEN, 133, 2,
"bitb", GEN, 197, 2,
"ble", REL, 47, 3,
"blo", REL, 37, 3,
"bls", REL, 35, 3,
"blt", REL, 45, 3,
"bmi", REL, 43, 3,
"bne", REL, 38, 3,
"bpl", REL, 42, 3,
"bra", REL, 32, 3,
"brn", REL, 33, 3,
"bsr", REL, 141, 7,
"bvc", REL, 40, 3,
"bvs", REL, 41, 3,
"clr", GRP2, 15, 4,
"clra", INH, 79, 2,
"clrb", INH, 95, 2,
"cmpa", GEN, 129, 2,
"cmpb", GEN, 193, 2,
"cmpd", P2GEN, 131, 5,
"cmps", P3GEN, 140, 5,
"cmpu", P3GEN, 131, 5,
"cmpx", LONGIMM, 140, 4,
"cmpy", P2GEN, 140, 5,
"com", GRP2, 3, 4,
"coma", INH, 67, 2,
"comb", INH, 83, 2,
"cpx", LONGIMM, 140, 4, /* for compatibility with old code */
"cwai", IMM, 60, 20,
"daa", INH, 25, 2,
"dec", GRP2, 10, 4,
"deca", INH, 74, 2,
"decb", INH, 90, 2,
"eora", GEN, 136, 2,
"eorb", GEN, 200, 2,
"exg", RTOR, 30, 8,
"inc", GRP2, 12, 4,
"inca", INH, 76, 2,
"incb", INH, 92, 2,
"jmp", GRP2, 14, 1,
"jsr", NOIMM, 141, 5,
"lbcc", P2REL, 36, 6,
"lbcs", P2REL, 37, 6,
"lbeq", P2REL, 39, 6,
"lbge", P2REL, 44, 6,
"lbgt", P2REL, 46, 6,
"lbhi", P2REL, 34, 6,
"lbhs", P2REL, 36, 6,
"lble", P2REL, 47, 6,
"lblo", P2REL, 37, 6,
"lbls", P2REL, 35, 6,
"lblt", P2REL, 45, 6,
"lbmi", P2REL, 43, 6,
"lbne", P2REL, 38, 6,
"lbpl", P2REL, 42, 6,
"lbra", P1REL, 22, 5,
"lbrn", P2REL, 33, 5,
"lbsr", P1REL, 23, 9,
"lbvc", P2REL, 40, 6,
"lbvs", P2REL, 41, 6,
"lda", GEN, 134, 2,
"ldaa", GEN, 134, 2,
"ldab", GEN, 198, 2,
"ldb", GEN, 198, 2,
"ldd", LONGIMM, 204, 3,
"lds", P2GEN, 206, 4,
"ldu", LONGIMM, 206, 3,
"ldx", LONGIMM, 142, 3,
"ldy", P2GEN, 142, 4,
"leas", INDEXED, 50, 2,
"leau", INDEXED, 51, 2,
"leax", INDEXED, 48, 2,
"leay", INDEXED, 49, 2,
"lsl", GRP2, 8, 4,
"lsla", INH, 72, 2,
"lslb", INH, 88, 2,
"lsr", GRP2, 4, 4,
"lsra", INH, 68, 2,
"lsrb", INH, 84, 2,
"mul", INH, 61, 11,
"neg", GRP2, 0, 4,
"nega", INH, 64, 2,
"negb", INH, 80, 2,
"nop", INH, 18, 2,
"ora", GEN, 138, 2,
"oraa", GEN, 138, 2,
"orab", GEN, 202, 2,
"orb", GEN, 202, 2,
"orcc", IMM, 26, 3,
"pshs", RLIST, 52, 5,
"pshu", RLIST, 54, 5,
"puls", RLIST, 53, 5,
"pulu", RLIST, 55, 5,
"rol", GRP2, 9, 4,
"rola", INH, 73, 2,
"rolb", INH, 89, 2,
"ror", GRP2, 6, 4,
"rora", INH, 70, 2,
"rorb", INH, 86, 2,
"rti", INH, 59, 15,
"rts", INH, 57, 5,
"sbca", GEN, 130, 2,
"sbcb", GEN, 194, 2,
"sex", INH, 29, 2,
"sta", NOIMM, 135, 2,
"staa", NOIMM, 135, 2,
"stab", NOIMM, 199, 2,
"stb", NOIMM, 199, 2,
"std", NOIMM, 205, 3,
"sts", P2NOIMM, 207, 4,
"stu", NOIMM, 207, 3,
"stx", NOIMM, 143, 3,
"sty", P2NOIMM, 143, 4,
"suba", GEN, 128, 2,
"subb", GEN, 192, 2,
"subd", LONGIMM, 131, 4,
"swi", INH, 63, 19,
"swi2", P2INH, 63, 20,
"swi3", P3INH, 63, 20,
"sync", INH, 19, 4,
"sys", SYS, 0, 19,
"tfr", RTOR, 31, 6,
"tst", GRP2, 13, 4,
"tsta", INH, 77, 2,
"tstb", INH, 93, 2
 
};
 
/ffwd.c
0,0 → 1,85
/*
* file I/O version of forward ref handler
*/
 
#define FILEMODE 0644 /* file creat mode */
#define UPDATE 2 /* file open mode */
#define ABS 0 /* absolute seek */
 
int Forward =0; /* temp file's file descriptor */
char Fwd_name[] = { "Fwd_refs" } ;
 
/*
* fwdinit --- initialize forward ref file
*/
fwdinit()
{
Forward = open(Fwd_name,O_CREAT | O_TRUNC | O_WRONLY, FILEMODE); //creat(Fwd_name,FILEMODE);
if(Forward <0)
fatal("Can't create temp file");
close(Forward); /* close and reopen for reads and writes */
Forward = open(Fwd_name,UPDATE);
if(Forward <0)
fatal("Forward ref file has gone.");
}
 
/*
* fwdreinit --- reinitialize forward ref file
*/
fwdreinit()
{
F_ref = 0;
Ffn = 0;
lseek(Forward,0L,ABS); /* rewind forward refs */
read(Forward,&Ffn,sizeof(Ffn));
read(Forward,&F_ref,sizeof(F_ref)); /* read first forward ref into mem */
#ifdef DEBUG
printf("First fwd ref: %d,%d\n",Ffn,F_ref);
#endif
}
 
/*
* fwdmark --- mark current file/line as containing a forward ref
*/
fwdmark()
{
write(Forward,&Cfn,sizeof(Cfn));
write(Forward,&Line_num,sizeof(Line_num));
}
 
/*
* fwdnext --- get next forward ref
*/
fwdnext()
{
int stat;
 
stat = read(Forward,&Ffn,sizeof(Ffn));
#ifdef DEBUG
printf("Ffn stat=%d ",stat);
#endif
stat = read(Forward,&F_ref,sizeof(F_ref));
#ifdef DEBUG
printf("F_ref stat=%d ",stat);
#endif
if( stat < 2 ){
F_ref=0;Ffn=0;
}
#ifdef DEBUG
printf("Next Fwd ref: %d,%d\n",Ffn,F_ref);
#endif
}
 
/*
* fwd_done --- closes & deletes forward reference file
*/
fwd_done()
{
int stat;
 
stat = close(Forward); /* Have to close first on MS-DOS or you leave lost clusters. */
#ifndef DEBUG
if( stat == 0 ) /* If close was successful, delete file */
unlink(Fwd_name);
#endif
}
/eval.c
0,0 → 1,199
/*
* eval --- evaluate expression
*
* an expression is constructed like this:
*
* expr ::= expr + term |
* expr - term ;
* expr * term ;
* expr / term ;
* expr | term ;
* expr & term ;
* expr % term ;
* expr ^ term ;
*
* term ::= symbol |
* * |
* constant ;
*
* symbol ::= string of alphanumerics with non-initial digit
*
* constant ::= hex constant |
* binary constant |
* octal constant |
* decimal constant |
* ascii constant;
*
* hex constant ::= '$' {hex digits};
*
* octal constant ::= '@' {octal digits};
*
* binary constant ::= '%' { 1 | 0 };
*
* decimal constant ::= {decimal digits};
*
* ascii constant ::= ''' any printing char;
*
*/
eval()
{
int left,right; /* left and right terms for expression */
char o; /* operator character */
 
#ifdef DEBUG
printf("Evaluating %s\n",Optr);
#endif
Force_byte = NO;
Force_word = NO;
if(*Optr=='<'){
Force_byte++;
Optr++;
}
else if(*Optr=='>'){
Force_word++;
Optr++;
}
left = get_term(); /* pickup first part of expression */
 
while( is_op(*Optr)){
o = *Optr++; /* pickup connector and skip */
right = get_term(); /* pickup current rightmost side */
switch(o){
case '+': left += right; break;
case '-': left -= right; break;
case '*': left *= right; break;
case '/': left /= right; break;
case '|': left |= right; break;
case '&': left &= right; break;
case '%': left %= right; break;
case '^': left = left^right; break;
}
}
 
Result= left;
#ifdef DEBUG
printf("Result=%x\n",Result);
printf("Force_byte=%d Force_word=%d\n",Force_byte,Force_word);
#endif
return(YES);
}
 
/*
* is_op --- is character an expression operator?
*/
is_op(c)
char c;
{
if( any(c,"+-*/&%|^"))
return(YES);
return(NO);
}
 
 
/*
* get_term --- evaluate a single item in an expression
*/
get_term()
{
char hold[MAXBUF];
char *tmp;
int val = 0; /* local value being built */
int minus; /* unary minus flag */
struct nlist *lookup(),*pointer;
struct link *pnt,*bpnt;
 
if( *Optr == '-' ){
Optr++;
minus =YES;
}
else
minus = NO;
 
while( *Optr == '#' ) Optr++;
 
/* look at rest of expression */
 
if(*Optr=='%'){ /* binary constant */
Optr++;
while( any(*Optr,"01"))
val = (val * 2) + ( (*Optr++)-'0');
}
else if(*Optr=='@'){ /* octal constant */
Optr++;
while( any(*Optr,"01234567"))
val = (val * 8) + ((*Optr++)-'0');
}
else if(*Optr=='$'){ /* hex constant */
Optr++;
while( any(*Optr,"0123456789abcdefABCDEF"))
if( *Optr > '9' )
val = (val * 16) + 10 + (mapdn(*Optr++)-'a');
else
val = (val * 16) + ((*Optr++)-'0');
}
else if( any(*Optr,"0123456789")){ /* decimal constant */
while(*Optr >= '0' && *Optr <= '9')
val = (val * 10) + ( (*Optr++)-'0');
}
else if(*Optr=='*'){ /* current location counter */
Optr++;
val = Old_pc;
}
else if(*Optr=='\''){ /* character literal */
Optr++;
if(*Optr == EOS)
val = 0;
else
val = *Optr++;
}
else if( alpha(*Optr) ){ /* a symbol */
tmp = hold; /* collect symbol name */
while(alphan(*Optr))
*tmp++ = *Optr++;
*tmp = EOS;
pointer = lookup(hold);
if (pointer != NULL)
{
if (Pass == 2)
{
pnt = pointer->L_list;
bpnt = NULL;
while (pnt != NULL)
{
bpnt = pnt;
pnt = pnt->next;
}
pnt = (struct link *) alloc(sizeof(struct link));
if (bpnt == NULL)
pointer->L_list = pnt;
else bpnt->next = pnt;
pnt->L_num = Line_num;
pnt->next = NULL;
}
val = Last_sym;
}
else{
if(Pass==1){ /* forward ref here */
fwdmark();
if( !Force_byte )
Force_word++;
val = 0;
}
else /* added ver TER_2.0 2 Jul 89 */
error("Symbol undefined Pass 2");
}
if(Pass==2 && Line_num==F_ref && Cfn==Ffn){
if( !Force_byte )
Force_word++;
fwdnext();
}
}
else
/* none of the above */
val = 0;
 
if(minus)
return(-val);
else
return(val);
}
/as.h
0,0 → 1,167
/*
* machine independent definitions and global variables
*/
 
#define YES 1
#define NO 0
#define ERR (-1)
 
#define MAXBUF 128
#define MAXOP 10 /* longest mnemonic */
#define MAXLAB 16
#define E_LIMIT 32
#define P_LIMIT 64
#define MAXINCFILES 30 /* nestinf levels for INCLUDE files at one time */
/* ver TER_2.0 6/17/89 */
#define MAXIFD 30 /* max nesting levels for IFD/IFND statements */
/* ver TER_2.0 2 Jul 89 */
#define IF_FALSE 0 /* tokens for IfMachine (conditional assembly) */
#define IF_TRUE 1 /* added ver TER_2.0 27Jun89 */
#define IF_ELSE 2
#define IF_ENDIF 3
#define IF_NORMAL 4
#define IF_END 5
#define IF_EOF 6 /* end tokens */
 
/* Character Constants */
#define NEWLINE '\n'
#define CR 0x0D /* <CR> or ^M ver TER_1.1 June 3, 1989 */
#define TAB '\t'
#define BLANK ' '
#define EOS '\0'
 
/* Opcode Classes */
#define INH 0 /* Inherent */
#define GEN 1 /* General Addressing */
#define IMM 2 /* Immediate only */
#define REL 3 /* Short Relative */
#define P2REL 4 /* Long Relative */
#define P1REL 5 /* Long Relative (LBRA and LBSR)*/
#define NOIMM 6 /* General except for Immediate */
#define P2GEN 7 /* Page 2 General */
#define P3GEN 8 /* Page 3 General */
#define RTOR 9 /* Register To Register */
#define INDEXED 10 /* Indexed only */
#define RLIST 11 /* Register List */
#define P2NOIMM 12 /* Page 2 No Immediate */
#define P2INH 13 /* Page 2 Inherent */
#define P3INH 14 /* Page 3 Inherent */
#define GRP2 15 /* Group 2 (Read/Modify/Write) */
#define LONGIMM 16 /* Immediate mode takes 2 bytes */
#define BTB 17 /* Bit test and branch */
#define SETCLR 18 /* Bit set or clear */
#define CPD 19 /* compare d 6811 */
#define XLIMM 20 /* LONGIMM for X 6811 */
#define XNOIMM 21 /* NOIMM for X 6811 */
#define YLIMM 22 /* LONGIMM for Y 6811 */
#define YNOIMM 23 /* NOIMM for Y 6811 */
#define FAKE 24 /* convenience mnemonics 6804 */
#define APOST 25 /* A accum after opcode 6804 */
#define BPM 26 /* branch reg plus/minus 6804 */
#define CLRX 27 /* mvi x,0 6804 */
#define CLRY 28 /* mvi y,0 6804 */
#define LDX 29 /* mvi x,expr 6804 */
#define LDY 30 /* mvi y,expr 6804 */
#define MVI 31 /* mvi 6804 */
#define EXT 32 /* extended 6804 */
#define BIT 33 /* bit manipulation 6301 */
#define SYS 34 /* syscalls (really swi) */
#define PSEUDO 35 /* Pseudo ops */
 
/* global variables */
int Line_num =0; /* current line number */
int Err_count =0; /* total number of errors */
char Line[MAXBUF] = {0}; /* input line buffer */
char Label[MAXLAB] = {0}; /* label on current line */
char Op[MAXOP] = {0}; /* opcode mnemonic on current line */
char Operand[MAXBUF] = {0}; /* remainder of line after op */
/* (up to ';' rel TER_2.0) */
char *Optr =0; /* pointer into current Operand field */
int Result =0; /* result of expression evaluation */
int Force_word =0; /* Result should be a word when set */
int Force_byte =0; /* Result should be a byte when set */
int Pc =0; /* Program Counter */
int Old_pc =0; /* Program Counter at beginning */
 
int Last_sym =0; /* result of last lookup */
 
int Pass =0; /* Current pass # */
int N_files =0; /* Number of files to assemble */
FILE *Fd =0; /* Current input file structure */
int Cfn =0; /* Current file number 1...n */
int Ffn =0; /* forward ref file # */
int F_ref =0; /* next line with forward ref */
char **Argv =0; /* pointer to file names */
 
int E_total =0; /* total # bytes for one line */
int E_bytes[E_LIMIT] = {0}; /* Emitted held bytes */
int E_pc =0; /* Pc at beginning of collection*/
 
int Lflag = 0; /* listing flag 0=nolist, 1=list*/
 
int P_force = 0; /* force listing line to include Old_pc */
int P_total =0; /* current number of bytes collected */
int P_bytes[P_LIMIT] = {0}; /* Bytes collected for listing */
 
int Cflag = 0; /* cycle count flag */
int Cycles = 0; /* # of cycles per instruction */
long Ctotal = 0; /* # of cycles seen so far */
int Sflag = 0; /* symbol table flag, 0=no symbol */
int N_page = 0; /* new page flag */
int Page_num = 2; /* page number */
int CREflag = 0; /* cross reference table flag */
int CRflag = 0; /* flag to add <CR><LF> to S record */
/* added ver TER_1.1 June 3, 1989 */
int nfFlag = 1; /* if=1 number INCLUDE files separate */
/* ver TER_2.0 June 17, 1989 */
int FdCount = 0; /* INCLUDE files "stack" pointer */
/* ver TER_2.0 June 17, 1989 */
char InclFName[MAXBUF]={0}; /* current INCLUDE file name */
int F_total = 0; /* total bytes emitted in S file */
/* ver (TER) 2.02 19 Jun 89 */
int Page_lines = 0; /* total lines this page */
/* ver (TER) 2.02 19 Jun 89 */
int Pflag50 = 0; /* if 1 then form feed every 50 lines */
/* ver (TER) 2.02 19 Jun 89 */
int Pflag75 = 0; /* if 1 then form feed every 75 lines */
/* ver (DWC) 2.10 8 Oct 2001 */
int PC_Save[4] = {0,0,0,0}; /* saved contents of CODE,DATA,BSS,AUTO PCs */
/* ver TER_2.09 25 July 89 */
int PC_ptr = 0; /* index or pointer to current PC */
/* initialized to CODE ver TER_2.09 25 July 89 */
 
struct link { /* linked list to hold line numbers */
int L_num; /* line number */
struct link *next; /* pointer to next node */
};
 
struct nlist { /* basic symbol table entry */
char *name;
int def; /* value of symbol, assigned by user */
int def2; /* value assign by assembler, e.g. defined this pass? */
/* added ver TER_2.0 4 Jul 89 */
struct nlist *Lnext ; /* left node of the tree leaf */
struct nlist *Rnext; /* right node of the tree leaf */
struct link *L_list; /* pointer to linked list of line numbers */
};
 
struct oper { /* an entry in the mnemonic table */
char *mnemonic; /* its name */
char class; /* its class */
int opcode; /* its base opcode */
char cycles; /* its base # of cycles */
};
 
struct nlist *root; /* root node of the tree */
 
FILE *Objfil =0; /* object file's file descriptor*/
char Obj_name[] = {" "};
 
struct InclFile { /* The INCLUDE files nesting "stack" */
/* added ver TER_2.0 6/17/89 */
FILE *fp; /* saved file pointer (next level up) */
int line_num; /* saved line number count */
char *name; /* saved file name */
};
 
struct InclFile InclFiles[MAXINCFILES]; /* the nesting stack itself */
/do09.c
0,0 → 1,603
/*
* MC6809 specific processing
*/
 
#define PAGE2 0x10
#define PAGE3 0x11
#define IPBYTE 0x9F /* extended indirect postbyte */
#define SWI 0x3F
 
/* register names */
 
#define RD 0
#define RX 1
#define RY 2
#define RU 3
#define RS 4
#define RPC 5
#define RA 8
#define RB 9
#define RCC 10
#define RDP 11
#define RPCR 12
 
/* convert tfr/exg reg number into psh/pul format */
int regs[] = { 6,16,32,64,64,128,0,0,2,4,1,8,0};
int rcycl[]= { 2,2, 2, 2, 2, 2, 0,0,1,1,1,1,0};
 
/* addressing modes */
#define IMMED 0 /* immediate */
#define IND 1 /* indexed */
#define INDIR 2 /* indirect */
#define OTHER 3 /* NOTA */
 
/*
* localinit --- machine specific initialization
*/
localinit()
{
}
 
/*
* do_op --- process mnemonic
*
* Called with the base opcode and it's class. Optr points to
* the beginning of the operand field.
*/
void do_op(opcode,class)
int opcode; /* base opcode */
int class; /* mnemonic class */
{
int dist; /* relative branch distance */
int src,dst;/* source and destination registers */
int pbyte; /* postbyte value */
int amode; /* indicated addressing mode */
int j;
 
amode = set_mode(); /* pickup indicated addressing mode */
 
switch(class){
case INH: /* inherent addressing */
emit(opcode);
return;
case GEN: /* general addressing */
do_gen(opcode,amode);
return;
case IMM: /* immediate addressing */
if( amode != IMMED ){
error("Immediate Operand Required");
return;
}
Optr++;
eval();
emit(opcode);
emit(lobyte(Result));
return;
case REL: /* short relative branches */
eval();
dist = Result - (Pc+2);
emit(opcode);
if( (dist >127 || dist <-128) && Pass==2){
error("Branch out of Range");
emit(lobyte(-2));
return;
}
emit(lobyte(dist));
return;
case P2REL: /* long relative branches */
eval();
dist = Result - (Pc+4);
emit(PAGE2);
emit(opcode);
eword(dist);
return;
case P1REL: /* lbra and lbsr */
if( amode == IMMED)
Optr++; /* kludge for C compiler */
eval();
dist = Result - (Pc+3);
emit(opcode);
eword(dist);
return;
case NOIMM:
if( amode == IMMED ){
error("Immediate Addressing Illegal");
return;
}
do_gen(opcode,amode);
return;
case P2GEN:
emit(PAGE2);
if( amode == IMMED ){
emit(opcode);
Optr++;
eval();
eword(Result);
return;
}
do_gen(opcode,amode);
return;
case P3GEN:
emit(PAGE3);
if( amode == IMMED ){
emit(opcode);
Optr++;
eval();
eword(Result);
return;
}
do_gen(opcode,amode);
return;
case RTOR: /* tfr and exg */
emit(opcode);
src = regnum();
while(alpha(*Optr))Optr++;
if(src==ERR){
error("Register Name Required");
emit(0);
return;
}
if(*Optr++ != ','){
error("Missing ,");
emit(0);
return;
}
dst = regnum();
while(alpha(*Optr))Optr++;
if(dst==ERR){
error("Register Name Required");
emit(0);
return;
}
if( src==RPCR || dst==RPCR){
error("PCR illegal here");
emit(0);
return;
}
if( (src <=5 && dst >=8) ||
(src >=8 && dst <=5)){
error("Register Size Mismatch");
emit(0);
return;
}
emit( (src<<4)+dst );
return;
case INDEXED: /* indexed addressing only */
if( *Optr == '#'){
Optr++; /* kludge city */
amode = IND;
}
if( amode != IND ){
error("Indexed Addressing Required");
return;
}
do_indexed(opcode);
return;
case RLIST: /* pushes and pulls */
if(*Operand == EOS){
error("Register List Required");
return;
}
emit(opcode);
pbyte = 0;
do{
j = regnum();
if( j == ERR || j==RPCR)
error("Illegal Register Name");
else if(j==RS && (opcode==52))
error("Can't Push S on S");
else if(j==RU && (opcode==54))
error("Can't Push U on U");
else if(j==RS && (opcode==53))
error("Can't Pull S from S");
else if(j==RU && (opcode==55))
error("Can't Pull U from U");
else{
pbyte |= regs[j];
Cycles += rcycl[j];
}
while(*Optr != EOS && alpha(*Optr))Optr++;
}while( *Optr++ == ',' );
emit(lobyte(pbyte));
return;
case P2NOIMM:
if( amode == IMMED )
error("Immediate Addressing Illegal");
else{
emit(PAGE2);
do_gen(opcode,amode);
}
return;
case P2INH: /* Page 2 inherent */
emit(PAGE2);
emit(opcode);
return;
case P3INH: /* Page 3 inherent */
emit(PAGE3);
emit(opcode);
return;
case LONGIMM:
if( amode == IMMED ){
emit(opcode);
Optr++;
eval();
eword(Result);
}
else
do_gen(opcode,amode);
return;
case GRP2:
if( amode == IND ){
do_indexed(opcode+0x60);
return;
}
else if( amode == INDIR){
Optr++;
emit(opcode + 0x60);
emit(IPBYTE);
eval();
eword(Result);
Cycles += 7;
if(*Optr == ']'){
Optr++;
return;
}
error("Missing ']'");
return;
}
eval();
if(Force_word){
emit(opcode+0x70);
eword(Result);
Cycles += 3;
return;
}
if(Force_byte){
emit(opcode);
emit(lobyte(Result));
Cycles += 2;
return;
}
if(Result>=0 && Result <=0xFF){
emit(opcode);
emit(lobyte(Result));
Cycles += 2;
return;
}
else {
emit(opcode+0x70);
eword(Result);
Cycles += 3;
return;
}
case SYS: /* system call */
emit(SWI);
eval();
emit(lobyte(Result));
return;
default:
fatal("Error in Mnemonic table");
}
}
 
 
/*
* do_gen --- process general addressing mode stuff
*/
do_gen(op,mode)
int op;
int mode;
{
if( mode == IMMED){
Optr++;
emit(op);
eval();
emit(lobyte(Result));
return(0);
}
else if( mode == IND ){
do_indexed(op+0x20);
return(0);
}
else if( mode == INDIR){
Optr++;
emit(op+0x20);
emit(IPBYTE);
eval();
eword(Result);
Cycles += 7;
if(*Optr == ']'){
Optr++;
return(0);
}
error("Missing ']'");
return(0);
}
else if( mode == OTHER){
eval();
if(Force_word){
emit(op+0x30);
eword(Result);
Cycles += 3;
return(0);
}
if(Force_byte){
emit(op+0x10);
emit(lobyte(Result));
Cycles += 2;
return(0);
}
if(Result>=0 && Result <=0xFF){
emit(op+0x10);
emit(lobyte(Result));
Cycles += 2;
return(0);
}
else {
emit(op+0x30);
eword(Result);
Cycles += 3;
return(0);
}
}
else {
error("Unknown Addressing Mode");
return(0);
}
}
 
/*
* do_indexed --- handle all wierd stuff for indexed addressing
*/
do_indexed(op)
int op;
{
int pbyte;
int j,k;
int predec,pstinc;
 
Cycles += 2; /* indexed is always 2+ base cycle count */
predec=0;
pstinc=0;
pbyte=128;
emit(op);
if(*Optr=='['){
pbyte |= 0x10; /* set indirect bit */
Optr++;
if( !any((char)']',Optr))
error("Missing ']'");
Cycles += 3; /* indirection takes this much longer */
}
j=regnum();
if(j==RA){
Cycles++;
abd_index(pbyte+6);
return(0);
}
if(j==RB){
Cycles++;
abd_index(pbyte+5);
return(0);
}
if(j==RD){
Cycles += 4;
abd_index(pbyte+11);
return(0);
}
eval();
Optr++;
while(*Optr=='-'){
predec++;
Optr++;
}
j=regnum();
while( alpha(*Optr) )Optr++;
while(*Optr=='+'){
pstinc++;
Optr++;
}
if(j==RPC || j==RPCR){
if( pstinc || predec ){
error("Auto Inc/Dec Illegal on PC");
return(0);
}
if(j==RPC){
if(Force_word){
emit(pbyte+13);
eword(Result);
Cycles += 5;
return(0);
}
if(Force_byte){
emit(pbyte+12);
emit(lobyte(Result));
Cycles++;
return(0);
}
if(Result>=-128 && Result <=127){
emit(pbyte+12);
emit(lobyte(Result));
Cycles++;
return(0);
}
else {
emit(pbyte+13);
eword(Result);
Cycles += 5;
return(0);
}
}
/* PCR addressing */
if(Force_word){
emit(pbyte+13);
eword(Result-(Pc+2));
Cycles += 5;
return(0);
}
if(Force_byte){
emit(pbyte+12);
emit(lobyte(Result-(Pc+1)));
Cycles++;
return(0);
}
k=Result-(Pc+2);
if( k >= -128 && k <= 127){
emit(pbyte+12);
emit(lobyte(Result-(Pc+1)));
Cycles++;
return(0);
}
else{
emit(pbyte+13);
eword(Result-(Pc+2));
Cycles += 5;
return(0);
}
}
if(predec || pstinc){
if(Result != 0){
error("Offset must be Zero");
return(0);
}
if(predec>2 || pstinc>2){
error("Auto Inc/Dec by 1 or 2 only");
return(0);
}
if((predec==1 && (pbyte&0x10) != 0) ||
(pstinc==1 && (pbyte&0x10) != 0)){
error("No Auto Inc/Dec by 1 for Indirect");
return(0);
}
if(predec && pstinc){
error("Can't do both!");
return(0);
}
if(predec)
pbyte += predec+1;
if(pstinc)
pbyte += pstinc-1;
pbyte += rtype(j);
emit(pbyte);
Cycles += 1 + predec + pstinc;
return(0);
}
pbyte += rtype(j);
if(Force_word){
emit(pbyte+0x09);
eword(Result);
Cycles += 4;
return(0);
}
if(Force_byte){
emit(pbyte+0x08);
emit(lobyte(Result));
Cycles++;
return(0);
}
if(Result==0){
emit(pbyte+0x04);
return(0);
}
if((Result >= -16) && (Result <= 15) && ((pbyte&16)==0)){
pbyte &= 127;
pbyte += Result&31;
emit(pbyte);
Cycles++;
return(0);
}
if(Result >= -128 && Result <= 127){
emit(pbyte+0x08);
emit(lobyte(Result));
Cycles++;
return(0);
}
emit(pbyte+0x09);
eword(Result);
Cycles += 4;
return(0);
}
 
 
/*
* abd_index --- a,b or d indexed
*/
 
abd_index(pbyte)
int pbyte;
{
int k;
 
Optr += 2;
k=regnum();
pbyte += rtype(k);
emit(pbyte);
return(0);
}
 
/*
* rtype --- return register type in post-byte format
*/
rtype(r)
int r;
{
switch(r){
case RX: return(0x00);
case RY: return(0x20);
case RU: return(0x40);
case RS: return(0x60);
}
error("Illegal Register for Indexed");
return(0);
}
 
/*
* set_mode --- determine addressing mode from operand field
*/
set_mode()
{
register char *p;
 
if( *Operand == '#' )
return(IMMED); /* immediate addressing */
p = Operand;
while( *p != EOS && *p != BLANK && *p != TAB){/* any , before break */
if( *p == ',')
return(IND); /* indexed addressing */
p++;
}
if( *Operand == '[')
return(INDIR); /* indirect addressing */
return(OTHER); /* NOTA */
}
 
/*
* regnum --- return register number of *Optr
*/
regnum()
{
if( head(Optr,"D" ))return(RD);
if( head(Optr,"d" ))return(RD);
if( head(Optr,"X" ))return(RX);
if( head(Optr,"x" ))return(RX);
if( head(Optr,"Y" ))return(RY);
if( head(Optr,"y" ))return(RY);
if( head(Optr,"U" ))return(RU);
if( head(Optr,"u" ))return(RU);
if( head(Optr,"S" ))return(RS);
if( head(Optr,"s" ))return(RS);
if( head(Optr,"PC" ))return(RPC);
if( head(Optr,"pc" ))return(RPC);
if( head(Optr,"PCR" ))return(RPCR);
if( head(Optr,"pcr" ))return(RPCR);
if( head(Optr,"A" ))return(RA);
if( head(Optr,"a" ))return(RA);
if( head(Optr,"B" ))return(RB);
if( head(Optr,"b" ))return(RB);
if( head(Optr,"CC" ))return(RCC);
if( head(Optr,"cc" ))return(RCC);
if( head(Optr,"DP" ))return(RDP);
if( head(Optr,"dp" ))return(RDP);
return(ERR);
}
 
 
/as09.c
0,0 → 1,15
//#include "stdafx.h"
#include <stdio.h>
#include <fcntl.h>
#include "as.h"
#include "table09.h"
#include "as.c"
#include "do09.c"
#include "pseudo.c"
#include "ifd.c" /* ver TER_2.0 2 Jul 89 */
#include "eval.c"
#include "symtab.c"
#include "util.c"
#include "ffwd.c"
#include "output.c"
 
/util.c
0,0 → 1,391
/*
* fatal --- fatal error handler
*/
fatal(str)
char *str;
{
pouterror(); /* added ver TER_2.0 4 Jul 89 */
printf("%s\n",str);
 
#ifdef IBM /* changed ver TER_2.0 */
exit(-1);
#else
exit(10); /* Amiga & UNIX prefer positive numbers for error
minimal error is 10 (no system prob) */
#endif
}
 
/*
* error --- error in a line
* print line number and error
*/
error(str)
char *str;
{
/* if(N_files > 1) commented out test for N_files in rel TER_2.0
because a single command line source file
(which is what N_files counts) can have multiple
include source files. */
pouterror();
printf("%s\n",str);
}
/*
* warn --- trivial error in a line
* print line number and error
*/
warn(str)
char *str;
{
/* if(N_files > 1) commented out in rel TER_2.0 same reason as above */
printf("%s, line no.",Argv[Cfn]); /* current file name */
printf("%d: ",Line_num); /* current line number */
printf("Warning --- %s\n",str);
Page_lines++;
}
 
 
/*
* delim --- check if character is a delimiter
*/
delim(c)
char c;
{
if( any(c," \t\n"))
return(YES);
return(NO);
}
 
/*
* skip_white --- move pointer to next non-whitespace char
*/
char *skip_white(ptr)
char *ptr;
{
while(*ptr==BLANK || *ptr==TAB)
ptr++;
return(ptr);
}
 
/*
* eword --- emit a word to code file
*/
eword(wd)
int wd;
{
emit(hibyte(wd));
emit(lobyte(wd));
}
 
/*
* emit --- emit a byte to code file
*/
emit(byte)
{
#ifdef DEBUG
printf("%2x @ %4x\n",byte,Pc);
#endif
if(Pass==1){
Pc++;
return(YES);
}
if(P_total < P_LIMIT)
P_bytes[P_total++] = byte;
E_bytes[E_total++] = byte;
Pc++;
if(E_total == E_LIMIT)
f_record();
}
 
/*
* f_record --- flush record out in `S1' format
*/
void f_record() /* made void for ANSI C compat ver TER_2.0 6/18/89 */
{
int i;
int chksum;
 
if(Pass == 1)
return;
if(E_total==0){
E_pc = Pc;
return;
}
F_total += E_total; /* total bytes in file ver (TER)2.01 19 Jun 89 */
chksum = E_total+3; /* total bytes in this record */
chksum += lobyte(E_pc);
chksum += E_pc>>8;
fprintf(Objfil,"S1"); /* record header preamble */
hexout(E_total+3); /* byte count +3 */
hexout(E_pc>>8); /* high byte of PC */
hexout(lobyte(E_pc)); /* low byte of PC */
for(i=0;i<E_total;i++){
chksum += lobyte(E_bytes[i]);
hexout(lobyte(E_bytes[i])); /* data byte */
}
chksum =~ chksum; /* one's complement */
hexout(lobyte(chksum)); /* checksum */
if (CRflag == 1) /* test for CRflag added ver TER_1.1 */
fprintf(Objfil,"%c\n",CR); /* print in IBM format for some PROM boxes */
else
fprintf(Objfil,"\n"); /* this is original statement */
E_pc = Pc;
E_total = 0;
}
 
char *hexstr = { "0123456789ABCDEF" } ;
 
hexout(byte)
int byte;
{
 
byte = lobyte(byte);
fprintf(Objfil,"%c%c",hexstr[byte>>4],hexstr[byte&017]);
}
 
/*
* print_line --- pretty print input line
*/
print_line()
{
int i;
register char *ptr;
 
printf ("%04d ",Line_num);
if(P_total || P_force)
printf("%04X",Old_pc);
else
printf(" ");
 
for(i=0;i<P_total && i<6;i++)
printf(" %02X",lobyte(P_bytes[i]));
for(;i<6;i++)
printf(" ");
printf(" ");
 
if(Cflag){
if(Cycles)
printf("[%2d ] ",Cycles);
else
printf(" ");
}
ptr = Line;
while( *ptr != '\n' ) /* just echo the line back out */
putchar(*ptr++);
for(;i<P_total;i++){
if( i%6 == 0 )
printf("\n "); /* force data alignment DWC 1-5-92 */
printf(" %02X",lobyte(P_bytes[i]));
}
if (Pflag50 && (++Page_lines>=50)) /* form feed if flag set */
NewPage(); /* ver (TER) 2.02 19 Jun 89 */
 
if (Pflag75 && (++Page_lines>=75)) /* form feed if flag set */
NewPage(); /* ver (DWC) 2.10 8 Oct 2001 */
 
 
printf("\n");
}
 
/*
* any --- does str contain c?
*/
any(c,str)
char c;
char *str;
{
while(*str != EOS)
if(*str++ == c)
return(YES);
return(NO);
}
 
/*
* mapdn --- convert A-Z to a-z
*/
char mapdn(c)
char c;
{
if( c >= 'A' && c <= 'Z')
return((char)(c+040)); /* cast value to char for ANSI C, ver TER_2.0 */
return(c);
}
 
/*
* lobyte --- return low byte of an int
*/
lobyte(i)
int i;
{
return(i&0xFF);
}
/*
* hibyte --- return high byte of an int
*/
hibyte(i)
int i;
{
return((i>>8)&0xFF);
}
 
/*
* head --- is str2 the head of str1?
*/
head(str1,str2)
char *str1,*str2;
{
while( *str1 != EOS && *str2 != EOS){
if( *str1 != *str2 )break;
str1++;
str2++;
}
if(*str1 == *str2)return(YES);
if(*str2==EOS)
if( any(*str1," \t\n,+-];*") )return(YES);
return(NO);
}
 
/*
* alpha --- is character a legal letter
*/
alpha(c)
char c;
{
if( c<= 'z' && c>= 'a' )return(YES);
if( c<= 'Z' && c>= 'A' )return(YES);
if( c== '_' )return(YES);
if( c== '.' )return(YES);
return(NO);
}
/*
* alphan --- is character a legal letter or digit
*/
alphan(c)
char c;
{
if( alpha(c) )return(YES);
if( c<= '9' && c>= '0' )return(YES);
if( c == '$' )return(YES); /* allow imbedded $ */
if( c == '@' )return(YES); /* allow imbedded @, added ver TER_2.0
added to permit redefinable variables */
return(NO);
}
 
/*
* white --- is character whitespace?
*/
white(c)
char c;
{
if( c == TAB || c == BLANK || c == '\n' )return(YES);
return(NO);
}
 
/*
* alloc --- allocate memory
*/
char *
alloc(nbytes)
int nbytes;
{
char *malloc();
 
return(malloc(nbytes));
}
 
/*
* FNameGet --- Find a file name <file> or "file" in the Operand string
added ver TER_2.0 6/17/89
note: this routine will return a file name with white
space if between delimeters. This is permitted in
AmigaDOS. Other DOS may hiccup or just use name up to white space
*/
 
int
FNameGet(NameString)
char *NameString; /* pointer to output string */
{
char *frompoint; /* pointers to input string, don't bash Operand */
char *topoint; /* pointer to output string, don't bash NameString */
 
frompoint=Operand; /* include file name is in parsed string Operand */
topoint=NameString; /* copy of pointer to increment in copying */
if (*frompoint != '<' && *frompoint != '"') return(0); /* bad syntax */
frompoint++; /* skip < or " */
 
while (*frompoint != '>' && *frompoint != '"') /* look for delimeter */
{
if (*frompoint == EOS) return(0); /* missing delimeter */
*topoint++ = *frompoint++; /* copy path & file name for DOS */
}
 
*topoint=EOS; /* terminate file name */
#ifdef DEBUG2
printf("FNameGet: file name=%s\n",NameString);
#endif
return(1); /* proper syntax anyway */
}
 
/*
* --- strsave() find a place to save a string & return pointer to it
added ver TER_2.0 6/18/89 function taken from
Kernighan & Ritchie 78
*/
char *strsave(s)
char *s;
{
char *p;
 
if ((p = alloc(strlen(s)+1)) != NULL)
strcpy(p,s);
return(p);
}
 
/*
* pouterror() ---- print out standard error header
added rel TER_2.0 6/18/89
*/
 
void pouterror()
{
printf("%s, line no. ",Argv[Cfn]); /* current file name */
printf("%d: ",Line_num); /* current line number */
/* NOTE: THERE IS NO \n ! Calling procedure supplies suffixing
error message and \n. viz. file pseudo.c procedure do_pseudo
in case INCLUDE. Note also that error count is incremented. */
Err_count++;
Page_lines++; /* increment lines per page */
}
 
/*
* New Page() --- form feed a new page, print heading & inc page number
Moved here from do_pseudo (pseudo.c) in ver (TER) 2.02
19 Jun 89 so that can call from print_line() as well
for p50 option.
*/
 
void NewPage()
{
Page_lines = 0; /* ver TER_2.08 so that OPT PAGE works */
printf ("\n\f\n");
printf ("%-10s",Argv[Cfn]);
printf (" ");
printf (" ");
printf ("page %3d\n",Page_num++);
}
 
 
/*
* LastChar() ----- return a pointer to the last character in a string
Exception: will return garbage if NULL string
*/
 
char *LastChar(strpt)
char *strpt; /* pointer to string to be examined */
{
char *c;
 
c=strpt; /* don't zap original */
while (*c != EOS) /* search for end */
c++;
return(--c); /* back up one to last character */
}
/asref.man
0,0 → 1,2245
 
 
 
 
 
 
 
 
 
MOTOROLA
 
FREEWARE
 
8-BIT CROSS ASSEMBLERS
 
USER'S MANUAL
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
EDITED BY
 
KEVIN ANDERSON
 
FIELD APPLICATIONS ENGINEER
 
 
 
 
 
 
 
 
 
 
 
 
 
 
TABLE OF CONTENTS
 
CHAPTER 1......................................................... 1
 
1.1 INTRODUCTION .......................................... 1
1.2 ASSEMBLY LANGUAGE ..................................... 1
1.3 OPERATING ENVIRONMENT ................................. 2
1.4 ASSEMBLER PROCESSING .................................. 2
 
CHAPTER 2 ........................................................ 3
 
2.1 INTRODUCTION .......................................... 3
2.2 SOURCE STATEMENT FORMAT ............................... 3
2.2.1 Label Field .................................... 3
2.2.2 Operation Field ................................ 4
2.2.3 Operand Field .................................. 4
2.2.3.1 M6800/6801 Operand Syntax ................ 5
2.2.3.2 M6800/M68HC04 Operand Syntax ............. 5
2.2.3.3 M6805/M68HC05 Operand Syntax ............. 5
2.2.3.4 M6809 Operand Syntax ..................... 5
2.2.3.5 M68HC11 Operand Syntax ................... 6
2.2.3.6 Expressions .............................. 6
2.2.3.7 Operators ................................ 7
2.2.3.8 Symbols .................................. 7
2.2.3.9 Constants ................................ 7
2.2.4 Comment Field .................................. 8
2.3 ASSEMBLER OUTPUT ...................................... 9
 
CHAPTER 3 - RUNNING THE ASSEMBLERS ............................... 10
 
3.1 ASSEMBLER INVOCATION .................................. 10
3.2 ERROR MESSAGES ........................................ 11
 
CHAPTER 4 - ASSEMBLER DIRECTIVES ................................. 12
 
4.1 INTRODUCTION .......................................... 12
4.2 BSZ - BLOCK STORAGE OF ZEROS .......................... 12
4.3 EQU - EQUATE SYMBOL TO A VALUE ........................ 13
4.4 FCB - FORM CONSTANT BYTE .............................. 13
4.5 FCC - FORM CONSTANT CHARACTER STRING .................. 13
4.6 FDB - FROM DOUBLE BYTE CONSTANT ....................... 13
4.7 FILL - FILL MEMORY .................................... 14
4.8 OPT - ASSEMBLER OUTPUT OPTIONS ........................ 14
4.9 ORG - SET PROGRAM COUNTER TO ORIGIN ................... 14
4.10 PAGE - TOP OF PAGE ................................... 15
4.11 RMB - RESERVE MEMORY BYTES ........................... 15
4.12 ZMB - ZERO MEMORY BYTES .............................. 15
 
APPENDIX A - CHARACTER SET ....................................... 16
 
APPENDIX B - ADDRESSING MODES .................................... 18
 
B.1 M6800/M6801 ADDRESSING MODES .......................... 18
B.2 M6804/68HC04 ADDRESSING MODES ......................... 19
B.3 M6805/68HC05 ADDRESSING MODES ......................... 21
 
 
 
i
 
 
 
 
 
 
 
TABLE OF CONTENTS
 
B.4 M6809 ADDRESSING MODES ................................ 22
B.5 M68HC11 ADDRESSING MODES .............................. 26
 
APPENDIX C - DIRECTIVE SUMMARY ................................... 28
 
APPENDIX D - ASSEMBLER LISTING FORMAT ............................ 29
 
APPENDIX E - S-RECORD INFORMATION ................................ 30
 
E.1 INTRODUCTION .......................................... 30
E.2 S-RECORD CONTENT ...................................... 30
E.3 S-RECORD TYPES ........................................ 30
E.4 S-RECORD EXAMPLE ...................................... 31
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ii
 
 
 
 
 
 
 
CHAPTER 1
GENERAL INFORMATION
 
 
1.1 INTRODUCTION
 
This is the user's reference manual for the IBM-PC hosted Motorola
Freeware 8 bit cross assemblers. It details the features and
capabilities of the cross assemblers, assembler syntax and directives,
options, and listings. It is intended as a detailed reference and an
introduction for those unfamiliar with Motorola assembler syntax and
format. Those experienced with Motorola assembler products may wish
to examine the file ASEMBLER.DOC available with the cross assemblers,
which briefly describes the differences between these assemblers and
earlier, non-pc based versions.
 
Assemblers are programs that process assembly language source program
statements and translate them into executable machine language object
files. A programmer writes his source program using any text editor
or word processor that can produce an ASCII text output. With some
word processors this is known as "non document" mode. Non document
mode produces a file without the non-printable embedded control
characters that are used in document formating. (Caution: assembling
a file that has been formatted with embedded control characters may
produce assembler errors. The solution is to convert the source file
to ASCII text.) Once the source code is written, the source file is
assembled by processing the file via the assembler.
 
Cross assemblers (such as the Motorola Freeware Assemblers) allow
source programs written and edited on one computer (the host) to
generate executable code for another computer (the target). The
executable object file can then be downloaded and run on the target
system. In this case the host is an IBM-PC or compatible and the
target system is based on a Motorola 8-bit microprocessor (6800, 6801,
6803, 6805, 68HC05, 6809, or 68HC11).
 
The assemblers are the executable programs AS*.EXE where * is any of
0, 1, 4, 5, 9, or 11 depending on which microprocessor you are writing
code for. The details of executing the assembler programs are found
in Chapter 3. The assembly language format and syntax for the various
processors is very similar with slight variations due to varied
programming resources (instructions, addressing modes, and registers).
These variations are explained in Appendix B.
 
 
1.2 ASSEMBLY LANGUAGE
 
The symbolic language used to code source programs to be processed by
the Assembler is called assembly language. The language is a
collection of mnemonic symbols representing: operations (i.e., machine
instruction mnemonics or directives to the assembler), symbolic names,
operators, and special symbols. The assembly language provides
mnemonic operation codes for all machine instructions in the
instruction set. The instructions are defined and explained in the
Programming Reference Manuals for the specific devices, available from
Motorola. The assembly language also contains mnemonic directives
 
 
 
 
 
 
 
Freeware Assemblers User's Manual
 
 
which specify auxiliary actions to be performed by the Assembler.
These directives are not always translated into machine language.
 
 
1.3 OPERATING ENVIRONMENT
 
These assemblers will run on any IBM-PC, XT, AT, PS-2, or true
compatible. The assemblers may be run off of a floppy disk drive or
they may be copied onto a hard drive for execution. DOS 2.0 or later
is required.
 
 
1.4 ASSEMBLER PROCESSING
 
The Macro Assembler is a two-pass assembler. During the first pass,
the source program is read to develop the symbol table. During the
second pass, the object file is created (assembled) with reference to
the table developed in pass one. It is during the second pass that
the source program listing is also produced.
 
Each source statement is processed completely before the next source
statement is read. As each statement is processed, the Assembler
examines the label, operation code, and operand fields. The operation
code table is scanned for a match with a known opcode. During the
processing of a standard operation code mnemonic, the standard
machine code is inserted into the object file. If an Assembler
directive is being processed, the proper action is taken.
 
Any errors that are detected by the Assembler are displayed before the
actual line containing the error is printed. If no source listing is
being produced, error messages are still displayed to indicate that
the assembly process did not proceed normally.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
 
 
 
 
Freeware Assemblers User's Manual
 
 
CHAPTER 2
CODING ASSEMBLY LANGUAGE PROGRAMS
 
 
2.1 INTRODUCTION
 
Programs written in assembly language consist of a sequence of source
statements. Each source statement consists of a sequence of ASCII
characters ending with a carriage return. Appendix A contains a list
of the supported character set.
 
 
2.2 SOURCE STATEMENT FORMAT
 
Each source statement may include up to four fields: a label (or "*"
for a comment line), an operation (instruction mneumonic or assembler
directive), an operand, and a comment.
 
 
2.2.1 Label Field
 
The label field occurs as the first field of a source statement. The
label field can take one of the following forms:
 
1. An asterisk (*) as the first character in the label field indicates
that the rest of the source statement is a comment. Comments are
ignored by the Assembler, and are printed on the source listing only
for the programmer's information.
 
2. A whitespace character (blank or tab) as the first character
indicates that the label field is empty. The line has no label and is
not a comment.
 
3. A symbol character as the first character indicates that the line
has a label. Symbol characters are the upper or lower case letters a-
z, digits 0-9, and the special characters, period (.), dollar sign
($), and underscore (_). Symbols consist of one to 15 characters, the
first of which must be alphabetic or the special characters period (.)
or underscore (_). All characters are significant and upper and lower
case letters are distinct.
 
A symbol may occur only once in the label field. If a symbol does
occur more than once in a label field, then each reference to that
symbol will be flagged with an error.
 
With the exception of some directives, a label is assigned the value
of the program counter of the first byte of the instruction or data
being assembled. The value assigned to the label is absolute.
Labels may optionally be ended with a colon (:). If the colon is
used it is not part of the label but merely acts to set the label off
from the rest of the source line. Thus the following code fragments
are equivalent:
 
here: deca
bne here
 
 
 
3
 
 
 
 
Freeware Assemblers User's Manual
 
 
here deca
bne here
 
A label may appear on a line by itself. The assembler interprets this
as set the value of the label equal to the current value of the
program counter.
 
The symbol table has room for at least 2000 symbols of length 8
characters or less. Additional characters up to 15 are permissible at
the expense of decreasing the maximum number of symbols possible in
the table.
 
 
2.2.2 Operation Field
 
The operation field occurs after the label field, and must be preceded
by at least one whitespace character. The operation field must contain
a legal opcode mneumonic or an assembler directive. Upper case
characters in this field are converted to lower case before being
checked as a legal mneumonic. Thus 'nop', 'NOP', and 'NoP' are
recognized as the same mneumonic. Entries in the operation field may
be one of two types:
 
Opcode. These correspond directly to the machine instructions. The
operation code includes any register name associated with the
instruction. These register names must not be separated from the
opcode with any whitespace characters. Thus 'clra' means clear
accumulator A, but 'clr a' means clear memory location identified by
the label 'a'.
 
Directive. These are special operation codes known to the Assembler
which control the assembly process rather than being translated into
machine instructions.
 
 
2.2.3 Operand Field
 
The operand field's interpretation is dependent on the contents of the
operation field. The operand field, if required, must follow the
operation field, and must be preceded by at least one whitespace
character. The operand field may contain a symbol, an expression, or a
combination of symbols and expressions separated by commas.
 
The operand field of machine instructions is used to specify the
addressing mode of the instruction, as well as the operand of the
instruction. The following tables summarize the operand field
formats for the various processor families. (NOTE: in these tables
parenthesis "()" signify optional elements and angle brackets "<>"
denote an expression is inserted. These syntax elements are present
only for clarification of the format and are not inserted as part of
the actual source program. All other characters are significant and
must be used when required.)
 
 
 
 
 
 
4
 
 
 
 
Freeware Assemblers User's Manual
 
 
2.2.3.1 M6800/6801 Operand Syntax
 
The format of the operand field for M6800/6801 instructions is:
 
Operand Format M6800/M6801 Addressing Mode
-------------- ---------------------------
no operand accumulator and inherent
<expression> direct, extended, or relative
#<expression> immediate
<expression>,X indexed
 
Details of the M6800/6801 addressing modes may be found in Appendix B.
 
 
2.2.3.2 M6804/68HC Operand Syntax
 
For the M6804/68HC04, the following operand formats exist:
 
Operand Format M6804/68HC04 Addressing Mode
-------------- ----------------------------
no operand accumulator and inherent
<expression> direct, extended, or relative
#<expression> immediate
<expression> bit set or clear
<expression>,<expression> bit test and branch
[<x> or <y>] register indirect
<expression>,#<expression> move indirect
 
Details of the M6804/68HC04 addressing modes may be found in Appendix
B.
 
 
2.2.3.3 M6805/M68HC05 Operand Syntax
 
For the M6805/68HC05, the operand formats are:
 
Operand Format M6805/68HC05 Addressing Mode
-------------- ----------------------------
no operand accumulator and inherent
<expression> direct, extended, or relative
#<expression> immediate
<expression>,X indexed
<expression>,<expression> bit set or clear
<expression>,<expression>,<expression> bit test and branch
 
Details of the M6805/68HC05 addressing modes may be found in Appendix
B.
 
 
2.2.3.4 M6809 Operand Syntax
 
For the M6809, the following operand formats are used:
 
 
 
 
 
 
5
 
 
 
 
Freeware Assemblers User's Manual
 
 
Operand Format M6809 Addressing Mode
-------------- ---------------------
no operand accumulator and inherent
<expression> direct, extended, or relative
#<expression> immediate
<expression>,X indexed
<<expression> forced direct
><expression> forced extended
<expression>] extended indirect
<expression>,R indexed
<<expression>,R forced 8-bit offset indexed
><expression>,R forced 16-bit offset indexed
[<expression>,R] indexed indirect
<[<expression>,R] forced 8-bit offset indexed indirect
>[<expression>,R] forced 16-bit offset indexed indirect
Q+ auto increment by 1
Q++ auto increment by 2
[Q++] auto increment indirect
-Q auto decrement by
--Q auto decrement by 2
[--Q] auto decrement indirect
W1,[W2,...,Wn] immediate
 
where R is one of the registers PCR, S, U, X, or Y, and Q is one of
the registers S, U, X, or Y. Wi (i=1 to n) is one of the symbols A,
B, CC, D, DP, PC, S, U, X, or Y.
 
Details of the M6809 addressing modes may be found in Appendix B.
 
 
2.2.3.5 M68HC11 Operand Syntax
 
For the M68HC11, the following operand formats exist:
 
Operand Format M68HC11 Addressing Mode
-------------- -----------------------
no operand accumulator and inherent
<expression> direct, extended, or relative
#<expression> immediate
<expression>,X indexed with X register
<expression>,Y indexed with Y register
<expression> <expression> bit set or clear
<expression> <expression> <expression> bit test and branch
 
The bit manipulation instruction operands are separated by spaces in
this case since the HC11 allows bit manipulation instructions on
indexed addresses. Thus a ',X' or ',Y' may be added to the final two
formats above to form the indexed effective address calculation.
 
Details of the M68HC11 addressing modes may be found in Appendix B.
The operand fields of assembler directives are described in Chapter 4.
 
 
2.2.3.6 Expressions. An expression is a combination of symbols,
constants, algebraic operators, and parentheses. The expression is
used to specify a value which is to be used as an operand.
 
 
6
 
 
 
 
Freeware Assemblers User's Manual
 
 
Expressions may consist of symbols, constants, or the character '*'
(denoting the current value of the program counter) joined together by
one of the operators: + - * / % & | ^ .
 
 
2.2.3.7 Operators. The operators are the same as in c:
 
+ add
- subtract
* multiply
/ divide
% remainder after division
& bitwise and
| bitwise or
^ bitwise exclusive or
 
Expressions are evaluated left to right and there is no provision for
parenthesized expressions. Arithmetic is carried out in signed two-
complement integer precision (that's 16 bits on the IBM PC).
 
 
2.2.3.8 Symbols. Each symbol is associated with a 16-bit integer
value which is used in place of the symbol during the expression
evaluation. The asterisk (*) used in an expression as a symbol
represents the current value of the location counter (the first byte
of a multi-byte instruction).
 
 
2.2.3.9 Constants. Constants represent quantities of data that do
not vary in value during the execution of a program. Constants may be
presented to the assembler in one of five formats: decimal,
hexadecimal, binary, or octal, or ASCII. The programmer indicates the
number format to the assembler with the following prefixes:
 
$ HEX
% BINARY
@ OCTAL
' ASCII
 
Unprefixed constants are interpreted as decimal. The assembler
converts all constants to binary machine code and are displayed in the
assembly listing as hex.
 
A decimal constant consists of a string of numeric digits. The value
of a decimal constant must fall in the range 0-65535, inclusive. The
following example shows both valid and invalid decimal constants:
 
VALID INVALID REASON INVALID
----- ------- --------------
12 123456 more than 5 digits
12345 12.3 invalid character
 
A hexadecimal constant consists of a maximum of four characters from
the set of digits (0-9) and the upper case alphabetic letters (A-F),
and is preceded by a dollar sign ($). Hexadecimal constants must be
 
 
 
7
 
 
 
 
Freeware Assemblers User's Manual
 
 
in the range $0000 to $FFFF. The following example shows both valid
and invalid hexadecimal constants:
 
VALID INVALID REASON INVALID
----- ------- --------------
$12 ABCD no preceding "$"
$ABCD $G2A invalid character
$001F $2F018 too many digits
 
A binary constant consists of a maximum of 16 ones or zeros preceded
by a percent sign (%). The following example shows both valid and
invalid binary constants:
 
VALID INVALID REASON INVALID
----- ------- --------------
%00101 1010101 missing percent
%1 %10011000101010111 too many digits
%10100 %210101 invalid digit
 
An octal constant consists of a maximum of six numeric digits,
excluding the digits 8 and 9, preceded by a commercial at-sign (@).
Octal constants must be in the ranges @0 to @177777. The following
example shows both valid and invalid octal constan
ts:
 
VALID INVALID REASON INVALID
----- ------- --------------
@17634 @2317234 too many digits
@377 @277272 out of range
@177600 @23914 invalid character
 
A single ASCII character can be used as a constant in expressions.
ASCII constants are preceded by a single quote ('). Any character,
including the single quote, can be used as a character constant. The
following example shows both valid and inval
id character constants:
 
VALID INVALID REASON INVALID
----- ------- --------------
'* 'VALID too long
 
For the invalid case above the assembler will not indicate an error.
Rather it will assemble the first character and ignore the remainder.
 
 
2.2.4 Comment Field
 
The last field of an Assembler source statement is the comment field.
This field is optional and is only printed on the source listing for
documentation purposes. The comment field is separated from the
operand field (or from the operation field if no operand is required)
by at least one whitespace character. The comment field can contain
any printable ASCII characters.
 
 
 
 
 
8
 
 
 
 
Freeware Assemblers User's Manual
 
 
2.3 ASSEMBLER OUTPUT
 
The Assembler output includes an optional listing of the source
program and an object file which is in the Motorola S Record format.
Details of the S Record format may be found in Appendix E. The
Assembler will normally suppress the printing of the source listing.
This condition, as well as others, can be overridden via options
supplied on the command line that invoked the Assembler.
 
Each line of the listing contains a reference line number, the address
and bytes assembled, and the original source input line. If an input
line causes more than 6 bytes to be output (e.g. a long FCC
directive), additional bytes (up to 64) are listed on succeeding lines
with no address preceding them.
 
The assembly listing may optionally contain a symbol table or a cross
reference table of all symbols appearing in the program. These are
always printed at the end of the assembly listing if either the symbol
table or cross reference table options (Paragraph 4.8) are in effect.
The symbol table contains the name of each symbol, along with its
defined value. The cross reference table additionally contains the
assembler-maintained source line number of every reference to every
symbol. The format of the cross reference table is shown in Appendix
D.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
 
 
 
 
Freeware Assemblers User's Manual
 
 
CHAPTER 3
RUNNING THE ASSEMBLERS
 
 
3.1 ASSEMBLER INVOCATION
 
The Motorola Freeware Assembly programs are named as*.exe where '*' is
any of 0, 1, 4, 5, 9, or 11 depending on which processor family you
wish to assemble code for. For example, to generate M6800 code run
the as0.exe program. To generate M68HC05 code run the as5.exe
program, and so forth. To run the assembler enter the following
command line:
 
as* file1 (file2 . . . ) ( - option1 option2 . . . )
 
where file1, file2, etc are the names of the source files you wish to
assemble. The source filenames may have extensions but the assembler
does not check for any particular extension ( however, do not use the
.S19 extension since that is the extension of the object file created
by the assembler. Its creation would overwrite the source file when
it is written to the disk).
 
The options are one or more of the following:
 
l enables output listing
no disables output listing (default).
cre enables the cross reference table generation
s enables the symbol table generation
c enables cycle counting
noc disables cycle counting
 
The minus sign preceding the option should be separated from the last
file name by a space. These options may also be indicated to the
assembler by the use of the OPT directive in the source file. The OPT
directive is described in Paragraph 4.8.
 
The object file created is written to disk and given the name
'FILENAME.S19' where 'FILENAME' is the name of the first source file
specified on the command line. Any errors and the optional listing
(if specified) are displayed on the screen. The listing and/or error
messages may be saved to a file for later examination or printing by
append an i/o redirection command to the command line. On the PC i/o
redirection is indicated with the greater-than ('>') symbol followed
by any new or existing file name.
 
Command line examples:
 
The command line
 
as5 myfile
 
would run the M6805/68HC05 assembler on the source file 'myfile'. The
object file would be written to 'myfile.s19' and any errors would
appear on the screen.
 
 
 
 
10
 
 
 
 
Freeware Assemblers User's Manual
 
 
The command line
 
as9 test.asm nexttest.s -l
 
would run the M6809 assembler on the source files 'test.asm' and
'nexttest.s'. The object file would be written to 'test.s19' and any
errors and the assembly listing would appear on the screen.
 
The command line
 
as9 test.asm nexttest.s -l cre s >test.lst
 
would run the M6809 assembler on the source files 'test.asm' and
'nexttest.s'. The object file would be written to 'test.s19'. A
listing would be created followed by a symbol table and cross
reference which would all be written to the file test.lst
.
 
3.2 ERROR MESSAGES
 
Error diagnostic messages are placed in the listing file just before
the line containing the error. The format of the error line is:
 
Line_number: Description of error
 
or
 
Line_number: Warning ---- Description of error
 
Errors in pass one cause cancellation of pass two. Warning do not
cause cancellation of pass two but are indications of a possible
problem. Error messages are meant to be self-explanatory.
 
If more than one file is being assembled, the file name precedes the
error:
 
File_name,Line_number: Description of error
 
Some errors are classed as fatal and cause an immediate termination of
the assembly. Generally this happens when a temporary file cannot be
created or is lost during assembly.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
 
 
 
 
Freeware Assemblers User's Manual
 
 
CHAPTER 4
ASSEMBLER DIRECTIVES
 
 
4.1 INTRODUCTION
 
The Assembler directives are instructions to the Assembler, rather
than instructions to be directly translated into object code. This
chapter describes the directives that are recognized by the Freeware
Assemblers. Detailed descriptions of each directive are arranged
alphabetically. The notations used in this chapter are:
 
( ) Parentheses denote an optional element.
 
XYZ The names of the directives are printed in capital letters.
 
< > The element names are printed in lower case and contained in
angle brackets. All elements outside of the angle brackets '<>' must
be specified as-is. For example, the syntactical element (<number>,)
requires the comma to be specified if the optional element <number> is
selected. The following elements are used in the subsequent
descriptions:
 
 
<comment> A statement's comment field
<label> A statement label
<expression> An Assembler expression
<expr> An Assembler expression
<number> A numeric constant
<string> A string of ASCII characters
<delimiter> A string delimiter
<option> An Assembler option
<symbol> An Assembler symbol
<sym> An Assembler symbol
<sect> A relocatable program section
<reg list> M6809 register list
<reg exp> M6809 register expression
 
 
In the following descriptions of the various directives, the syntax,
or format, of the directive is given first. This will be followed
with the directive's description.
 
4.2 BSZ - BLOCK STORAGE OF ZEROS
 
(<label>) BSZ <expression> (<comment>)
 
The BSZ directive causes the Assembler to allocate a block of bytes.
Each byte is assigned the initial value of zero. The number of bytes
allocated is given by the expression in the operand field. If the
expression contains symbols that are either undefined or forward
referenced (i.e. the definition occurs later on in the file), or if
the expression has a value of zero, an error will be generated.
 
 
 
 
 
12
 
 
 
 
Freeware Assemblers User's Manual
 
 
4.3 EQU - EQUATE SYMBOL TO A VALUE
 
<label> EQU <expression> (<comment>)
 
The EQU directive assigns the value of the expression in the operand
field to the label. The EQU directive assigns a value other than the
program counter to the label. The label cannot be redefined anywhere
else in the program. The expression cannot contain any forward
references or undefined symbols. Equates with forward references are
flagged with Phasing Errors.
 
4.4 FCB - FORM CONSTANT BYTE
 
(<label>) FCB <expr>(,<expr>,...,<expr>) (<comment>)
 
The FCB directive may have one or more operands separated by commas.
The value of each operand is truncated to eight bits, and is stored in
a single byte of the object program. Multiple operands are stored in
successive bytes. The operand may be a numeric constant, a character
constant, a symbol, or an expression. If multiple operands are
present, one or more of them can be null (two adjacent commas), in
which case a single byte of zero will be assigned for that operand.
An error will occur if the upper eight bits of the evaluated operands'
values are not all ones or all zeros.
 
4.5 FCC - FORM CONSTANT CHARACTER STRING
 
(<label>) FCC <delimiter><string><delimiter> (<comment>)
 
The FCC directive is used to store ASCII strings into consecutive
bytes of memory. The byte storage begins at the current program
counter. The label is assigned to the first byte in the string. Any
of the printable ASCII characters can be contained in the string. The
string is specified between two identical delimiters which can be any
printable ASCII character. The first non-blank character after the FCC
directive is used as the delimiter.
 
Example:
 
LABEL1 FCC , ABC,
 
assembles ASCII ABC at location LABEL1
 
 
4.6 FDB - FORM DOUBLE BYTE CONSTANT
 
(<label>) FDB <expr>(,<expr>,...,<expr>) (<comment>)
 
The FDB directive may have one or more operands separated by commas.
The 16-bit value corresponding to each operand is stored into two
consecutive bytes of the object program. The storage begins at the
current program counter. The label is assigned to the first 16-bit
value. Multiple operands are stored in successive bytes. The operand
may be a numeric constant, a character constant, a symbol, or an
expression. If multiple operands are present, one or more of them can
 
 
 
13
 
 
 
 
Freeware Assemblers User's Manual
 
 
be null (two adjacent commas), in which case two bytes of zeros will
be assigned for that operand.
 
4.7 FILL - FILL MEMORY
 
(<label>) FILL <expression>,<expression>
 
The FILL directive causes the assembler to initialize an area of
memory with a constant value. The first expression signifies the one
byte value to be placed in the memory and the second expression
indicates the total number of successive bytes to be initialized. The
first expression must evaluate to the range 0-255. Expressions cannot
contain forward references or undefined symbols.
 
4.8 OPT - ASSEMBLER OUTPUT OPTIONS
 
OPT <option>(,<option>,...,<option>) (<comment>)
 
The OPT directive is used to control the format of the Assembler
output. The options are specified in the operand field, separated by
commas. All options have a default condition. Some options can be
initialized from the command line that invoked the Assembler, however
the options contained in the source file take precedence over any
entered on the command line. In the following descriptions, the
parenthetical inserts specify "DEFAULT", if the option is the default
condition. All options must be entered in lower case.
 
c - Enable cycle counting in the listing. The total cycle count
for that instruction will appear in the listing after the assembled
bytes and before the source code.
 
cre - Print a cross reference table at the end of the source
listing. This option, if used, must be specified before the first
symbol in the source program is encountered. The cross reference
listing format may be found in Appendix D.
 
l - Print the listing from this point on. A description of the
listing format can be found in Appendix D.
 
noc - (DEFAULT) Disable cycle counting in the listing. If the "c"
option was used previously in the program, this option will cause
cycle counting to cease until the next "OPT c" statement.
 
nol - (DEFAULT) Do not print the listing from this point on. An
"OPT l" can re-enble listing at a later point in the program.
 
s - Print symbol table at end of source listing. The symbol table
format can be found in Appendix D.
 
 
4.9 ORG - SET PROGRAM COUNTER TO ORIGIN
 
ORG <expression> (<comment>)
 
The ORG directive changes the program counter to the value specified
by the expression in the operand field. Subsequent statements are
 
 
14
 
 
 
 
Freeware Assemblers User's Manual
 
 
assembled into memory locations starting with the new program counter
value. If no ORG directive is encountered in a source program, the
program counter is initialized to zero. Expressions cannot contain
forward references or undefined symbols.
 
 
4.10 PAGE - TOP OF PAGE
 
PAGE
 
The PAGE directive causes the Assembler to advance the paper to the
top of the next page. If no source listing is being produced, the PAGE
directive will have no effect. The directive is not printed on the
source listing.
 
 
4.11 RMB - RESERVE MEMORY BYTES
 
(<label>) RMB <expression> (<comment>)
 
The RMB directive causes the location counter to be advanced by the
value of the expression in the operand field. This directive reserves
a block of memory the length of which in bytes is equal to the value
of the expression. The block of memory reserved is not initialized to
any given value. The expression cannot contain any forward references
or undefined symbols. This directive is commonly used to reserve a
scratchpad or table area for later use.
 
4.12 ZMB - ZERO MEMORY BYTES (same as BSZ)
 
(<label>) ZMB <expression> (<comment>)
 
The ZMB directive causes the Assembler to allocate a block of bytes.
Each byte is assigned the initial value of zero. The number of bytes
allocated is given by the expression in the operand field. If the
expression contains symbols that are either undefined or forward
references, or if the expression has a value of zero, an error will be
generated.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
 
 
 
 
Freeware Assemblers User's Manual
 
 
APPENDIX A
CHARACTER SET
 
 
The character set recognized by the Freeware Assemblers is a subset of
ASCII. The ASCII code is shown in the following figure. The following
characters are recognized by the Assembler:
 
1. The upper case letters A through Z and lower case letters a
through z.
 
2. The digits 0 through 9.
 
3. Five arithmetic operators: +, -, *, / and % (remainder
after division).
 
4. Three logical operators: &, |, and ^.
 
5. The special symbol characters: underscore (_), period (.),
and dollar sign ($). Only the underscore and period may be
used as the first character of a symbol.
 
6. The characters used as prefixes for constants and
addressing modes:
 
# Immediate addressing
$ Hexadecimal constant
& Decimal constant
@ Octal constant
% Binary constant
' ASCII character constant
 
7. The characters used as suffixes for constants and
addressing modes:
 
,X Indexed addressing
,PCR M6809 indexed addressing
,S M6809 indexed addressing
,U M6809 indexed addressing
,Y M6809 and M68HC11 indexed addressing
 
8. Three separator characters: space, carriage return, and
comma.
 
9. The character "*" to indicate comments. Comments may
contain any printable characters from the ASCII set.
 
10. The special symbol backslash "\" to indicate line
continuation. When the assembler encounters the line
continuation character it fetches the next line and adds it
to the end of the first line. This continues until a line
is seen which doesn't end with a backslash or until the
system maximum buffer size has been collected (typically
greater or equal to 256).
 
 
 
 
16
 
 
 
 
Freeware Assemblers User's Manual
 
 
11. For the M6809 Assembler, the character "<" preceding an
expression to indicate direct addressing mode or 8-bit
offset in indexed mode, and the character ">" preceding an
expression to indicate extended addressing mode or 16-bit
offset in indexed mode.
 
12. For the M6809 Assembler, the characters used to indicate
auto increment and auto decrement in the indexed mode: +,
++, -, --.
 
 
 
 
ASCII CHARACTER CODES
 
 
BITS 4 to 6 -- 0 1 2 3 4 5 6 7
----------- -------------------------------------
 
0 NUL DLE SP 0 @ P ` p
B 1 SOH DC1 : 1 A Q a q
I 2 STX DC2 ! 2 B R b r
T 3 ETX DC3 # 3 C S c s
S 4 EOT DC4 $ 4 D T d t
5 ENQ NAK % 5 E U e u
0 6 ACK SYN & 6 F V f v
7 BEL ETB ' 7 G W g w
T 8 BS CAN ( 8 H X h x
O 9 HT EM ) 9 I Y i y
A LF SUB * : J Z j z
3 B VT ESC + ; K [ k {
C FF FS , < L \ l ;
D CR GS - = M ] m }
E SO RS . > N ^ n ~
F S1 US / ? O _ o DEL
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
 
 
 
 
Freeware Assemblers User's Manual
 
 
APPENDIX B
ADDRESSING MODES
 
B.1 M6800/M6801 ADDRESSING MODES.
 
INHERENT OR ACCUMULATOR ADDRESSING
The M6800 includes some instructions which require no operands. These
instructions are self-contained and employ the inherent addressing or
the accumulator addressing mode.
 
 
IMMEDIATE ADDRESSING
Immediate addressing refers to the use of one or two bytes of
information that immediately follow the operation code in memory.
Immediate addressing is indicated by preceding the operand field with
the pound sign or number sign character (#). The expression following
the # will be assigned one or two bytes of storage, depending on the
instruction.
 
 
RELATIVE ADDRESSING
Relative addressing is used by branch instructions. Branches can only
be executed within the range -126 to +129 bytes relative to the first
byte of the branch instruction. For this mode, the programmer
specifies the branch address expression and places it in the operand
field. The actual branch offset is calculated by the assembler and put
into the second byte of the branch instruction. The offset is the
two's complement of the difference between the location of the byte
immediately following the branch instruction and the location of the
destination of the branch. Branches out of bounds are flagged as
errors by the assembler.
 
 
INDEXED ADDRESSING
Indexed addressing is relative to the index register. The address is
calculated at the time of instruction execution by adding a one-byte
displacement (in the second byte of the instruction) to the current
contents of the X register. Since no sign extension is performed on
this one-byte displacement, the offset cannot be negative. Indexed
addressing is indicated by the characters ",X" following the
expression in the operand field. The special case of ",X", without a
preceding expression, is treated as "0,X".
 
 
DIRECT AND EXTENDED ADDRESSING
Direct and extended addressing utilize one (direct) or two (extended)
bytes to contain the address of the operand. Direct addressing is
limited to the first 256 bytes of memory. Direct and extended
addressing are indicated by only having an expression in the operand
field. Direct addressing will be used by the Assembler whenever
possible.
 
 
 
 
 
 
 
18
 
 
 
 
Freeware Assemblers User's Manual
 
 
B.2 M6804/M68HC04 ADDRESSING MODES.
 
INHERENT OR ACCUMULATOR ADDRESSING
The M6800 includes some instructions which require no operands. These
instructions are self-contained and employ the inherent addressing or
the accumulator addressing mode.
 
 
IMMEDIATE ADDRESSING
Immediate addressing refers to the use of one byte of information that
immediately follows the operation code in memory. Immediate addressing
is indicated by preceding the operand field with the pound sign or
number sign character (#). The expression following the # will be
assigned one byte of storage.
 
 
RELATIVE ADDRESSING
Relative addressing is used by branch instructions. Branches can only
be executed within the range -15 to +16 bytes relative to the first
byte of the branch instruction. For this mode, the programmer
specifies the branch address expression and places it in the operand
field. The actual branch offset is calculated by the assembler and put
into the second byte of the branch instruction. The offset is the
two's complement of the difference between the location of the byte
immediately following the branch instruction and the location of the
destination of the branch. Branches out of bounds are flagged as
errors by the assembler.
 
 
DIRECT AND EXTENDED ADDRESSING
Direct and extended addressing utilize byte to contain the address of
the operand. Direct addressing is limited to the first 256 bytes of
memory. Extended addressing concatenates the four least-significant
bits of the opcode with the byte following the opcode to form a 12-bit
address. Direct and extended addressing are indicated by only having
an expression in the operand field. Direct addressing will be used by
the Assembler whenever possible.
 
 
SHORT DIRECT
Some opcodes allow 4 memory locations in data space ram ($80, $81,
$82, and $83 to be referenced as part of the opcode. The opcode
determines the data space RAM location, and the instruction is only
one byte. The X and Y registers are at locations $80 and $81,
respectively. An expression used with short direct addressing must
not be forward referenced (that is its definition must occur before,
not after this point in the file) and must equate to the range $80-
$83.
 
 
BIT SET AND CLEAR
In the bit set/clear addressing mode, the bit to be set or cleared is
part of the opcode. The byte following the opcode specifies the
direct address of the byte which will have the bit set or cleared.
Any bit in the 256 byte data space memory that can be written (with
 
 
 
19
 
 
 
 
Freeware Assemblers User's Manual
 
 
the exception of the data direction registers) can be set or cleared
with these two byte instructions.
 
 
BIT TEST AND BRANCH
The bit test and branch addressing mode is a combination of the direct
addressing and relative addressing. The bit to be tested, and it
condition (set or clear), is included in the opcode. The data space
address of the byte to be tested is in the single byte immediately
following the opcode byte and follows direct addressing rules. The
third byte is sign extended by the processor during execution to form
the 12-bit relative address which is added to the program counter if
the condition is true. This allows branches based on any readable bit
in the data space. The branch span is -125 to +130 from the opcode
address. The branch target address is used by the programmer to
signify the relative offset -- the assembler calculates the offset
value. Branches out of bounds are flagged as errors by the
assembler.
 
 
REGISTER INDIRECT
In the register indirect mode, the operand is at the address in data
space pointed to by the contents of one of the indirect registers, X
or Y. The particular indirect register is encoded in bit 4 of the
opcode by the assembler. The assembler operand syntax for register
indirect is
 
[<X> or <Y>]
 
 
MOVE IMMEDIATE
The MVI (move immediate) instruction has its own format:
 
mvi <expression 1>,#<expression 2>
 
where <expression 1> is a direct address and <expression 2> is the
data value to be written.
 
 
MISCELLANEOUS SYNTAX ISSUES
The registers in the 6804/HC6804 are memory locations and have
addresses assigned to them. The assembler has predefined
 
a = A = $FF
b = B = $80
c = C = $81
 
This also means that for the '04 assembler clr x is equivalent to clrx
since x is both a register and a memory location.
 
The '04 series has separate program and data spaces. There is no
program memory in the range $10-$7F. Bytes assembled into that range
will go into the data space.
 
 
 
 
 
20
 
 
 
 
Freeware Assemblers User's Manual
 
 
B.3 M6805/68HC05 ADDRESSING MODES.
 
INHERENT OR ACCUMULATOR ADDRESSING
The M6805 includes some instructions which require no operands. These
instructions are self-contained, and employ the inherent addressing or
the accumulator addressing mode.
 
 
IMMEDIATE ADDRESSING
Immediate addressing refers to the use of one byte of information that
immediately follows the operation code in memory. Immediate addressing
is indicated by preceding the operand field with the pound sign or
number sign character (#). The expression following the # will be
assigned one byte of storage.
 
 
RELATIVE ADDRESSING
Relative addressing is used by branch instructions. Branches can only
be executed within the range -126 to +129 bytes relative to the first
byte of the branch instruction. For this mode, the programmer
specifies the branch address expression and places it in the operand
field. The actual branch offset is calculated by the assembler and put
into the second byte of the branch instruction. The offset is the
two's complement of the difference between the location of the byte
immediately following the branch instruction and the location of the
destination of the branch. Branches out of bounds are flagged as
errors by the assembler.
 
 
INDEXED ADDRESSING
Indexed addressing is relative to the index register. The address is
calculated at the time of instruction execution by adding a one- or
two-byte displacement to the current contents of the X register. The
displacement immediately follows the operation code in memory. If the
displacement is zero, no offset is added to the index register. In
this case, only the operation code resides in memory. Since no sign
extension is performed on a one-byte displacement, the offset cannot
be negative. Indexed addressing is indicated by the characters ",X"
following the expression in the operand field. The special case of
",X", without a preceding expression, is treated as "0,X". Some
instructions do not allow a two-byte displacement.
 
 
DIRECT AND EXTENDED ADDRESSING
Direct and extended addressing utilize one (direct) or two (extended)
bytes to contain the address of the operand. Direct addressing is
limited to the first 256 bytes of memory. Direct and extended
addressing are indicated by only having an expression in the operand
field. Some instructions do not allow extended addressing. Direct
addressing will be used by the Macro Assembler whenever possible.
 
 
BIT SET OR CLEAR
The addressing mode used for this type of instruction is direct,
although the format of the operand field is different from the direct
addressing mode described above. The operand takes the form
 
 
21
 
 
 
 
Freeware Assemblers User's Manual
 
 
<expression 1>, <expression 2>. <expression 1> indicates which bit is
to be set or cleared. It must be an absolute expression in the range
0-7. It is used in generating the operation code. <expression 2> is
handled as a direct address, as described above. Since the bit
manipulation address is direct, only the first 256 locations may be
operated on by bit manipulation operations.
 
 
BIT TEST AND BRANCH
This combines two addressing modes: direct and relative. The format of
the operand is: <expression 1>, <expression 2>, <expression 3>.
<expression 1> and <expression 2> are handled in the same manner as
described above in "bit set or clear". <expression 3> is used to
generate a relative address, as described above in "relative
addressing".
 
 
B.4 M6809 ADDRESSING MODES.
 
INHERENT OR ACCUMULATOR ADDRESSING
The M6809 includes some instructions which require no operands. These
instructions are self-contained, and employ the inherent addressing or
the accumulator addressing mode.
 
 
IMMEDIATE ADDRESSING
Immediate addressing refers to the use of one or two bytes of
information that immediately follow the operation code in memory.
Immediate addressing is indicated by preceding the operand field with
the pound sign or number sign (#) -- i.e., #<expression>. The
expression following the # will be assigned one or two bytes of
storage, depending on the instruction. All instructions referencing
the accumulator "A" or "B", or the condition code register "CC", will
generate a one-byte immediate value. Also, immediate addressing used
with the PSHS, PULS, PSHU, and PULU instructions generates a one-byte
immediate value. Immediate operands used in all other instructions
generate a two-byte value.
 
The register list operand does not take the form #<expression> but
still generates one byte of immediate data. The form of the operand
is:
 
R1,R2,...,Rn
 
where Ri (i=1 to n) is one of the symbols A, B, CC, D, DP, PC, S, U,
X or Y. The number and type of symbols vary, depending on the specific
instruction.
 
For the instructions PSHS, PULS, PSHU, and PULU, any of the above
register names may be included in the register list. The only
restriction is that "U" cannot be specified with PSHU or PULU, and "S"
cannot be specified with PSHS or PULS. The one-byte immediate value
assigned to the operand is calculated by the assembler and is
determined by the registers specified. Each register name causes the
assembler to set a bit in the immediate byte as follows:
 
 
 
22
 
 
 
 
Freeware Assemblers User's Manual
 
 
Register Bit
-------- ---
 
PC 7
U,S 6
Y 5
X 4
DP 3
B,D 2
A,D 1
CC 0
 
 
For the instructions EXG and TFR, exactly two of the above register
names must be included in the register list. The other restriction is
the size of the registers specified. For the EXG instruction, the two
registers must be the same size. For the TFR instruction, the two
registers must be the same size, or the first can be a 16-bit register
and the second an 8-bit register. In the case where the transfer is
from a 16-bit register to an 8-bit register, the least significant 8
bits are transferred. The 8-bit registers are A, B, CC, and DP. The
16-bit registers are D, PC, S, U, X, and Y. The one-byte immediate
value assigned to the operand by the assembler is determined by the
register names. The most significant four bits of the immediate byte
contain the value of the first register name; the least significant
four bits contain the value of the second register, as shown by the
following table:.
 
 
Register Value (hex)
-------- -----------
 
D 0
X 1
Y 2
U 3
S 4
PC 5
A 8
B 9
CC A
DP B
 
 
RELATIVE ADDRESSING
Relative addressing is used by branch instructions. There are two
forms of the branch instruction. The short branch can only be executed
within the range -126 to +129 bytes relative to the first byte of the
branch instruction. For this mode, the programmer specifies the branch
address expression and places it in the operand field. The actual
branch offset is calculated by the assembler and put into the second
byte of the branch instruction. The long branch can execute in the
full range of addressing from 0000-FFFF (hexadecimal) because a two-
byte offset is calculated by the assembler and put into the operand
field of the branch instruction. The offset is the two's complement
of the difference between the location of the byte immediately
 
 
23
 
 
 
 
Freeware Assemblers User's Manual
 
 
following the branch instruction and the location of the destination
of the branch.
 
 
DIRECT AND EXTENDED ADDRESSING
Direct and extended addressing utilize one (direct) or two (extended)
bytes to contain the address of the operand. Direct and extended
addressing are indicated by having only an expression in the operand
field (i.e., <expression>). Direct addressing will be used whenever
possible.
 
Regardless of the criteria described above, it is possible to force
the Assembler to use the direct addressing mode by preceding the
operand with the "<" character. Similarly, extended addressing can be
forced by preceding the operand with the ">" character. These two
operand forms are: <<expression> and ><expression>.
 
 
INDEXED ADDRESSING
Indexed addressing is relative to one of the index registers. The
general form is <expression>,R. The address is calculated at the time
of instruction execution by adding the value of <expression> to the
current contents of the index register. The other general form is
[<expression>,R]. In this indirect form, the address is calculated
at the time of instruction execution by first adding the value of
<expression> to the current contents of the index register, and then
retrieving the two bytes from the calculated address and address+1.
This two-byte value is used as the effective address of the operand.
The allowable forms of indexed addressing are described below. In the
description below, R refers to one of the index registers S, U, X, or
Y.
 
The accumulator offset mode allows one of the accumulators to be
specified instead of an <expression>. Valid forms are:.
 
<acc>,R and [<acc>,R]
 
where <acc> is one of the accumulators A, B, or D. This form
generates a one-byte operand (post-byte only). When accumulator A or B
is specified, sign extension occurs prior to adding the value in the
accumulator to the index register.
 
The valid forms for the automatic increment/decrement mode are shown
below. For each row, the three entries shown are equivalent.
 
 
R+ ,R+ 0,R+
-R ,-R 0,-R
R++ ,R++ 0,R++
--R ,--R 0,--R
[R++] ,R++] [0,R++]
[--R] [,--R] [0,--R]
 
 
In this form, the only valid expression is 0. Like the accumulator
offset mode, this form generates a one-byte operand (post-byte only).
 
 
24
 
 
 
 
Freeware Assemblers User's Manual
 
 
The valid forms for the expression offset mode are:
 
 
R ,R <expression>,R
[R] [,R] [<expression>,R]
<R <,R <<expression>,R
<[R] <[,R] <[<expression>,R]
>R >,R ><expression>,R
>[R] >[,R] >[<expression>,R]
 
 
The "<" and ">" characters force an 8- or 16-bit offset, respectively,
and are described below. If no expression is specified, or if an
expression with a value of zero is specified, only the postbyte of
the operand is generated. If an expression with a value in the range
-16 to +15 is specified without indirection, a one- byte operand is
generated which contains the expression's value, as well as the index
register indicator. At execution time, the expression's value is
expanded to 16 bits with sign extension before being added to the
index register.
 
All other forms will generate a post-byte, as well as either a one- or
two-byte offset which contains the value of the expression. The size
of the offset is determined by the type and size of the expression.
Expressions with values in the range -128 to +127 generate an 8-bit
offset. All other cases will result in a 16-bit offset being
generated. In the case where an 8-bit offset is generated, the value
is expanded to 16 bits with sign extension at execution time.
 
Regardless of the criteria described above, it is possible to force
the Assembler to generate an 8-bit offset by preceding the operand
with the "<" character. Similarly, a 16-bit offset can be forced by
preceding the operand with the ">" character.
 
If the relative address calculated is not in the range -128 to +127,
or if the expression references a symbol that has not yet been
defined, a two-byte offset is generated after the post-byte. A one-
byte offset is generated if the relative address is in the range -128
to +127.
 
Like the expression offset mode, a one-byte offset can be forced by
preceding the operand with a "<". A ">" forces a two-byte offset. A
byte overflow error is generated if a one-byte offset is forced when
the relative address is not in the range -12
8 to +127.
 
The extended indirect mode has the form:
 
[<expression>]
 
Although extended indirect is a logical extension of the extended
addressing mode, this mode is implemented using an encoding of the
postbyte under the indexed addressing mode. A post-byte and a two-
byte offset which contains the value of the expression is generated.
 
 
 
 
25
 
 
 
 
Freeware Assemblers User's Manual
 
 
B.5 M68HC11 ADDRESSING MODES.
 
PREBYTE
The number of combinations of instructions and addressing modes for
the 68HC11 is larger than that possible to be encoded in an 8-bit word
(256 combinations). To expand the opcode map, certain opcodes ($18,
$1A, and $CD) cause the processor to fetch the next address to find
the actual instruction. These opcodes are known as prebytes and are
inserted automatically by the assembler for those instructions that
require it.l In general the instructions contained in the alternate
maps are those involving the Y register or addressing modes that
involve the Y index register. Thus the programmer make the tradeoff
between the convenience of using the second index register and the
additional time and code space used by the prebyte.
 
 
INHERENT OR ACCUMULATOR ADDRESSING
The M68HC11 includes some instructions which require no operands.
These instructions are self-contained, and employ the inherent
addressing or the accumulator addressing mode.
 
 
IMMEDIATE ADDRESSING
Immediate addressing refers to the use of one or more bytes of
information that immediately follow the operation code in memory.
Immediate addressing is indicated by preceding the operand field with
the pound sign or number sign character (#). The expression following
the # will be assigned one byte of storage.
 
 
RELATIVE ADDRESSING
Relative addressing is used by branch instructions. Branches can only
be executed within the range -126 to +129 bytes relative to the first
byte of the branch instruction. For this mode, the programmer
specifies the branch address expression and places it in the operand
field. The actual branch offset is calculated by the assembler and put
into the second byte of the branch instruction. The offset is the
two's complement of the difference between the location of the byte
immediately following the branch instruction and the location of the
destination of the branch. Branches out of bounds are flagged as
errors by the assembler.
 
 
INDEXED ADDRESSING
Indexed addressing is relative one of the index registers X or Y. The
address is calculated at the time of instruction execution by adding a
one-byte displacement to the current contents of the X register. The
displacement immediately follows the operation code in memory. If the
displacement is zero, zero resides in the byte following the opcode.
Since no sign extension is performed on a one-byte displacement, the
offset cannot be negative. Indexed addressing is indicated by the
characters ",X" following the expression in the operand field. The
special case of ",X", without a preceding expression, is treated as
"0,X".
 
 
 
 
26
 
 
 
 
Freeware Assemblers User's Manual
 
 
DIRECT AND EXTENDED ADDRESSING
Direct and extended addressing utilize one (direct) or two (extended)
bytes to contain the address of the operand. Direct addressing is
limited to the first 256 bytes of memory. Direct and extended
addressing are indicated by only having an expression in the operand
field. Direct addressing will be used by the Assembler whenever
possible.
 
 
BIT(S) SET OR CLEAR
The addressing mode used for this type of instruction is direct,
although the format of the operand field is different from the direct
addressing mode described above. The operand takes the form
<expression 1> <expression 2> where the two expressions are separated
by a blank. <expression 1> signifies the operand address and may be
either a direct or an indexed address. When the address mode is
indexed, <expression 1> is followed by ',R' where R is either X or Y.
This allows bit manipulation instructions to operate across the
complete 64K address map. <expression 2> is the mask byte. The
bit(s) to be set or cleared are indicated by ones in the corresponding
location(s) in the mask byte. The mask byte must be an expression in
the range 0-255 and is encoded by the programmer.
 
 
BIT TEST AND BRANCH
This combines two addressing modes: direct or indexed and relative.
The format of the operand is: <expression 1> <expression 2>
<expression 3> where the expressions are separated by blanks.
<expression 1> identifies the operand an may indicate either a direct
or indexed address. Indexed addresses are signified with ',R'
following the expression where R is either X or Y. <expression 2> is
the mask byte. The bit(s) to be set or cleared are indicated by ones
in the corresponding location(s) in the mask byte. The mask byte must
be an expression in the range 0-255 and is encoded by the programmer.
<expression 3> is used to generate a relative address, as described
above in "relative addressing".
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
 
 
 
 
Freeware Assemblers User's Manual
 
 
APPENDIX C
DIRECTIVE SUMMARY
 
 
A complete description of all directives appears in Chapter 4.
 
 
ASSEMBLY CONTROL
 
ORG Origin program counter
 
SYMBOL DEFINITION
 
EQU Assign permanent value
 
DATA DEFINITION/STORAGE ALLOCATION
 
BSZ Block storage of zero; single bytes
 
FCB Form constant byte
 
FCC Form constant character string
 
FDB Form constant double byte
 
FILL Initialize a block of memory to a constant
 
RMB Reserve memory; single bytes
 
ZMB Zero Memory Bytes; same and BSZ
 
 
LISTING CONTROL
 
OPT c Enable cycle counting
 
OPT cre Print cross reference table
 
OPT l Print source listing from this point
 
OPT nol Inhibit printing of source listing from this point
 
OPT s Print symbol table
 
PAGE Print subsequent statements on top of next page
 
 
 
 
 
 
 
 
 
 
 
 
 
28
 
 
 
 
Freeware Assemblers User's Manual
 
 
APPENDIX D
ASSEMBLER LISTING FORMAT
 
 
The Assembler listing has the following format:
 
LINE# ADDR OBJECT CODE BYTES [ # CYCLES] SOURCE LINE
 
The LINE# is a 4 digit decimal number printed as a reference. This
reference number is used in the cross reference. The ADDR is the hex
value of the address for the first byte of the object code for this
instruction. The OBJECT CODE BYTES are the assembled object code of
the source line in hex. If an source line causes more than 6 bytes
to be output (e.g. a long FCC directive), additional bytes (up to 64)
are listed on succeeding lines with no address preceding them.
 
The # CYCLES will only appear in the listing if the "c" option is in
effect. It is enclosed in brackets which helps distinguish it from
the source listing. The SOURCE LINE is reprinted exactly from the
source program, including labels.
 
The symbol table has the following format:
 
SYMBOL ADDR
 
The symbol is taken directly from the label field in the source
program. The ADDR is the hexadecimal address of the location
referenced by the symbol.
 
The cross reference listing has the following format:
 
SYMBOL ADDR *LOC1 LOC2 LOC3 ...
 
The SYMBOL and ADDR are the same as above. The * indicates the start
of the line reference numbers. The LOCs are the decimal line numbers
of the assembler listing where the label occurs.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
 
 
 
 
Freeware Assemblers User's Manual
 
 
APPENDIX E
S-RECORD INFORMATION
 
 
E.1 INTRODUCTION
 
The S-record output format encodes program and data object modules
into a printable (ASCII) format. This allows viewing of the object
file with standard tools and allows display of the module while
transferring from one computer to the next or during loads between a
host and target. The S-record format also includes information for
use in error checking to insure the integrity of data transfers.
 
 
E.2 S-RECORD CONTENT
 
S-Records are character strings made of several fields which identify
the record type, record length, memory address, code/data, and
checksum. Each byte of binary data is encoded as a 2-character
hexadecimal number: the first character representing the high-order
4 bits, and the second the low-order 4 bits of the byte.
 
The 5 fields which comprise an S-record are:
 
TYPE RECORD LENGTH ADDRESS CODE/DATA CHECKSUM
 
The fields are defined as follows:
 
FIELD CHARACTERS CONTENTS
----- ---------- --------
Type 2 S-record type - S1, S9, etc.
 
Record 2 The count of the character pairs in the
length record, excluding the type and record
length.
 
Address 4, 6, The 2-, 3-, or 4-byte address at which
or 8 the data field is to be loaded into
memory.
 
Code/data 0-2n From 0 to n bytes of executable code,
memory loadable data, or descriptive
information.
 
Checksum 2 The least significant byte of the one's
complement of the sum of the values
represented by the pairs of characters
making up the record length, address,
and the code/data fields.
 
Each record may be terminated with a CR/LF/NULL.
 
 
E.3 S-RECORD TYPES
 
Eight types of s-records have been defined to accommodate various
 
 
30
 
 
 
 
Freeware Assemblers User's Manual
 
 
encoding, transportation, and decoding needs. The Freeware
assemblers use only two types, the S1 and S9:
 
S1 A record containing code/data and the 2-byte
address at which the code/data is to reside.
 
S9 A termination record for a block of S1 records. The address
field may optionally contain the 2-byte address of the
instruction to which control is to be passed. If not
specified, the first entry point specifica
tion encountered in the object module input will be used.
There is no code/data field.
 
E.4 S-RECORD EXAMPLE
 
The following is a typical S-record module:
 
S1130000285F245F2212226A000424290008237C2A
S11300100002000800082629001853812341001813
S113002041E900084E42234300182342000824A952
S107003000144ED492
S9030000FC
 
The module consists of four code/data records and an S9 termination
record.
 
The first S1 code/data record is explained as follows:
 
S1 S-record type S1, indicating a code/data record to be
loaded/verified at a 2-byte address.
 
13 Hex 13 (decimal 19), indicating 19 character pairs,
representing 19 bytes of binary data, follow.
 
00 Four-character 2-byte address field: hex address 0000,
indicates location where the following data is to be loaded.
 
The next 16 character pairs are the ASCII bytes of the actual
program code/data
 
2A Checksum of the first S1 record.
 
The second and third S1 code/data records each also contain $13
character pairs and are ended with checksums. The fourth S1 code/data
record contains 7 character pairs.
 
The S9 termination record is explained as follows:
 
S9 S-record type S9, indicating a termination record.
 
03 Hex 03, indicating three character pairs (3 bytes) to
follow.
 
00 Four character 2-byte address field, zeroes.
00
 
FC Checksum of S9 record.
 
31
 
 
/AS09_DWC_211.zip Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream
AS09_DWC_211.zip Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.