URL
https://opencores.org/ocsvn/rtf65002/rtf65002/trunk
Subversion Repositories rtf65002
[/] [rtf65002/] [trunk/] [software/] [asm/] [supermon816.asm] - Rev 40
Compare with Previous | Blame | View Log
; .opt proc65c02,caseinsensitivecpu W65C02;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *;* *;* SUPERMON 816 MACHINE LANGUAGE MONITOR FOR THE W65C816S MICROPROCESSOR *;* *;* Permission is hereby granted to use, copy, modify and distribute this software, *;* provided this copyright notice remains in the source code and proper attribu- *;* tion is given. Redistribution, regardless of form, must be at no charge to the *;* end user. This code or any part thereof, including any derivation, MAY NOT be *;* incorporated into any package intended for sale, unless written permission has *;* been given by the copyright holder. *;* *;* THERE IS NO WARRANTY OF ANY KIND WITH THIS SOFTWARE. The user assumes all risk *;* in connection with the incorporation of this software into any system. *;* Supermon 816 is a salute to Jim Butterfield, who passed away on June 29, 2007. *;* *;* Jim, who was the unofficial spokesman for Commodore International during the *;* heyday of the company's 8 bit supremacy, scratch-developed the Supermon machine *;* language monitor for the PET & CBM computers. When the best-selling Commodore *;* 64 was introduced, Jim adapted his software to the new machine & gave the adap- *;* tation the name Supermon 64. Commodore subsequently integrated a customized *;* version of Supermon 64 into the C-128 to act as the resident M/L monitor. *;* *;* Although Supermon 816 is not an adaptation of Supermon 64, it was decided to *;* keep the Supermon name alive, since Supermon 816's general operation & user in- *;* terface is similar to that of Supermon 64. Supermon 816 is 100 percent native *;* mode 65C816 code & was developed from a blank canvas. *;* This version customized for the RTF65002 test system *;* Finitron.ca *;* Supermon 816 is a full featured monitor and supports the following operations: *;* *;* *;* Supermon 816 accepts binary (%), octal (@), decimal (+) and hexadecimal ($) as *;* input for numeric parameters. Additionally, the H and > operations accept an *;* ASCII string in place of numeric values by preceding the string with ', e.g.: *;* *;* h 042000 042FFF 'BCS Technology Limited *;* *;* If no radix symbol is entered hex is assumed. *;* *;* Numeric conversion is also available. For example, typing: *;* *;* +1234567 <CR> *;* *;* will display: *;* *;* $12D687 *;* +1234567 *;* @04553207 *;* %100101101011010000111 *;* *;* In the above example, <CR> means the console keyboard's return or enter key. *;* *;* All numeric values are internally processed as 32 bit unsigned integers. Addr- *;* esses may be entered as 8, 16 or 24 bit values. During instruction assembly, *;* immediate mode operands may be forced to 16 bits by preceding the operand with *;* an exclamation point if the instruction can accept a 16 bit operand, e.g.: *;* *;* a 1f2000 lda !#4 *;* *;* The above will assemble as: *;* *;* A 1F2000 A9 04 00 LDA #$0004 *;* *;* Entering: *;* *;* a 1f2000 ldx !#+157 *;* *;* will assemble as: *;* *;* A 1F2000 A2 9D 00 LDX #$009D *;* *;* Absent the ! in the operand field, the above would have been assembled as: *;* *;* A 1F2000 A2 9D LDX #$9D *;* *;* If an immediate mode operand is greater than $FF assembly of a 16 bit operand *;* is implied. *;* A Note on the PEA & PEI Instructions *;* *;* The Eyes and Lichty programming manual uses the following syntax for the PEA *;* and PEI instructions: *;* *;* PEA <operand> *;* PEI (<operand>) *;* *;* The WDC data sheet that was published at the time of the 65C816's release in *;* 1984 does not indicate a recommended or preferred syntax for any of the above *;* instructions. PEA pushes its operand to the stack and hence operates like any *;* other immediate mode instruction, in that the operand is the data (however, PEA *;* doesn't affect the status register). Similarly, PEI pushes the 16 bit value *;* stored at <operand> and <operand>+1, and hence operates like any other direct *;* (zero) page instruction, again without affecting the status register. *;* *;* BCS Technology Limited is of the opinion that the developer of the ORCA/M as- *;* sembler, which is the assembler referred to in the Eyes and Lichty manual, mis- *;* understood how PEA and PEI behave during runtime, and hence chose an incorrect *;* syntax for these two instructions. This error was subsequently carried forward *;* by Eyes and Lichty. *;* *;* Supermon 816's assembler uses the following syntax for PEA and PEI: *;* *;* PEA #<operand> *;* PEI <operand> *;* *;* The operand for PEA is treated as a 16 bit value, even if entered as an 8 bit *;* value. The operand for PEI must be 8 bits. *;* *;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *;; * * * * * * * * * * * *; * VERSION INFORMATION *; * * * * * * * * * * * *;.byte "1" ;major.byte ".".byte "0" ;minor.byte ".".byte "1" ;revision.endm;;REVISION TABLE;;Ver Rev Date Description;1.0 2013/11/01 A) Original derived from the POC V1.1 single-board computer; firmware.; 2013/11/04 A) Fixed a problem where the B-accumulator wasn't always being; be copied to shadow storage after return from execution of; a J command.;;; COMMENT ABBREVIATIONS; BCD binary-coded decimal; DP direct page or page zero; EOF end-of-field; EOI end-of-input; LSB least significant byte/bit; LSD least significant digit; LSN least significant nybble; LSW least significant word; MPU microprocessor; MSB most significant byte/bit; MSD most significant digit; MSN most significant nybble; MSW most-significant word; RAM random access memory; WS whitespace, i.e., blanks & horizontal tabs; A word is defined as 16 bits.;; MPU REGISTER SYMBOLS; .A accumulator LSB; .B accumulator MSB; .C 16 bit accumulator; .X X-index; .Y Y-index; DB data bank; DP direct page; PB program bank; PC program counter; SP stack pointer; SR MPU status;; MPU STATUS REGISTER SYMBOLS; C carry; D decimal mode; I maskable interrupts; m accumulator/memory size; N result negative; V sign overflow; x index registers size; Z result zero;;================================================================================;;SYSTEM INTERFACE DEFINITIONS;; This section defines the interface between Supermon 816 & the host; system. Change these definitions to suit your system, but do not; change any label names. All definitions must have valid values in; order to assemble Supermon 816.;_origin_ =$008000 ;assembly address...;; Set _ORIGIN_ to Supermon 816's desired assembly address.;vecexit =$00F403 ;exit to environment address...;; Set VECEXIT to where Supermon 816 should go when it exits. Supermon 816; will do a JML (long jump) to this address, which means VECEXIT must be a; 24 bit address.;vecbrki =$0102 ;BRK handler indirect vector...;; Supermon 816 will modify this vector so that execution of a BRK instruc-; tion is intercepted & the registers are captured. Your BRK front end; should jump through this vector after pushing the registers as follows:;; phb ;save DB; phd ;save DP; rep #%00110000 ;16 bit registers; pha; phx; phy; jmp (vecbrki) ;indirect vector;; When a G or J command is issued, the above sequence will be reversed be-; fore a jump is made to the code to be executed. Upon exit from Supermon; 816, the original address at VECBRKI will be restored.;; If your BRK front end doesn't conform to the above you will have to mod-; ify Supermon 816 to accommodate the differences. The most likely needed; changes will be in the order in which registers are pushed to the stack.;hwstack =$3fff ;top of hardware stack...;; Supermon 816 initializes the stack pointer to this address when the cold; start at MONCOLD is called to enter the monitor. The stack pointer will; be undisturbed when entry into Supermon 816 is through JMONBRK (see jump; table definitions).;zeropage =$80 ;Supermon 816's direct page...;; Supermon 816 uses direct page starting at this address. Be sure that no; conflict occurs with other software.;getcha =$F400 ;get keystroke from console...;; GETCHA refers to an operating system API call that returns a keystroke; in the 8 bit accumulator. Supermon 816 assumes that GETCHA is a non-; blocking subroutine & returns with carry clear to indicate that a key-; stroke is in .A, or with carry set to indicate that no keystroke was; available. GETCHA will be called with a JSR instruction.;; Supermon 816 expects .X & .Y to be preserved upon return from GETCHA.; You may have to modify Supermon 816 at all calls to GETCHA if your "get; keystroke" routine works differently than described.;putcha =$F406 ;print character on console...;; PUTCHA refers to an operating system API call that prints a character to; the console screen. The character to be printed will be in .A, which; will be set to 8-bit width. Supermon 816 assumes that PUTCHA will block; until the character can be processed. PUTCHA will be called with a JSR; instructions.;; Supermon 816 expects .X & .Y to be preserved upon return from PUTCHA.; You may have to modify Supermon 816 at all calls to PUTCHA if your "put; character" routine works differently than described.;stopkey =$03 ;display abort key...;; Supermon 816 will poll for a "stop key" during display operations, such; as code disassembly & memory dumps, so as to abort further processing &; return to the command prompt. STOPKEY must be defined with the ASCII; value that the "stop key" will emit when typed. The polling is via a; call to GETCHA (described above). The default STOPKEY definition of $03; is for ASCII <ETX> or [Ctrl-C].;ibuffer =$000200 ;input buffer &...auxbuf =ibuffer+s_ibuf+s_byte ;auxiliary buffer...;; Supermon 816 will use the above definitions for input buffers. These; buffers may be located anywhere in RAM that is convenient. The buffers; are stateless, which means that unless Supermon 816 has control of your; system, they may be overwritten without consequence.;;================================================================================;;_asm24_ .macro .ad.byte <.ad,>.ad,.ad >> 16.endm;brl .macro .ad.ba =*+3.byte $82.word .ad-.ba.endm;; jml is supported for the RTF65002 in 65c02 mode. And the opcode is supported; by the assembler.;jml .macro .ad; ; .byte $5c; _asm24_ .ad; .endm;mvn .macro .s,.d.byte $54,.d,.s.endm;mvp .macro .s,.d.byte $44,.d,.s.endm;pea .macro .op.byte $f4.word .op.endm;phb .macro.byte $8b.endm;phk .macro.byte $4b.endm;plb .macro.byte $ab.endm;rep .macro .op.byte $c2,.op.endm;sep .macro .op.byte $e2,.op.endm;tcd .macro.byte $5b.endm;tcs .macro.byte $1b.endm;tdc .macro.byte $7b.endm;tsc .macro.byte $3b.endm;txy .macro.byte $9b.endm;tyx .macro.byte $bb.endm;wai .macro.byte $cb.endm;xba .macro.byte $eb.endm;adcw .macro .opadc #<.op.byte >.op.endm;andw .macro .opand #<.op.byte >.op.endm;bitw .macro .opbit #<.op.byte >.op.endm;cmpw .macro .opcmp #<.op.byte >.op.endm;cpxw .macro .opcpx #<.op.byte >.op.endm;cpyw .macro .opcpy #<.op.byte >.op.endm;eorw .macro .opeor #<.op.byte >.op.endm;ldaw .macro .oplda #<.op.byte >.op.endm;ldxw .macro .opldx #<.op.byte >.op.endm;ldyw .macro .opldy #<.op.byte >.op.endm;oraw .macro .opora #<.op.byte >.op.endm;sbcw .macro .opsbc #<.op.byte >.op.endm;ldalx .macro .ad.byte $bf_asm24_ .ad.endm;adcil .macro .ad.byte $67,.ad.endm;adcily .macro .ad.byte $77,.ad.endm;andil .macro .ad.byte $27,.ad.endm;andily .macro .ad.byte $37,.ad.endm;cmpil .macro .ad.byte $c7,.ad.endm;cmpily .macro .ad.byte $d7,.ad.endm;eoril .macro .ad.byte $47,.ad.endm;eorily .macro .ad.byte $57,.ad.endm;ldail .macro .ad.byte $a7,.ad.endm;ldaily .macro .ad.byte $b7,.ad.endm;orail .macro .ad.byte $07,.ad.endm;oraily .macro .ad.byte $17,.ad.endm;sbcil .macro .ad.byte $e7,.ad.endm;sbcily .macro .ad.byte $f7,.ad.endm;stail .macro .ad.byte $87,.ad.endm;staily .macro .ad.byte $97,.ad.endm;adcs .macro .of.byte $63,.of.endm;adcsi .macro .of.byte $73,.of.endm;ands .macro .of.byte $23,.of.endm;andsi .macro .of.byte $33,.of.endm;cmps .macro .of.byte $c3,.of.endm;cmpsi .macro .of.byte $d3,.of.endm;eors .macro .of.byte $43,.of.endm;eorsi .macro .of.byte $53,.of.endm;ldas .macro .of.byte $a3,.of.endm;ldasi .macro .of.byte $b3,.of.endm;oras .macro .of.byte $03,.of.endm;orasi .macro .of.byte $13,.of.endm;sbcs .macro .of.byte $e3,.of.endm;sbcsi .macro .of.byte $f3,.of.endm;stas .macro .of.byte $83,.of.endm;stasi .macro .of.byte $93,.of.endm;longa .macro.byte $c2,$20.endm;longr .macro.byte $c2,$30.endm;longx .macro.byte $c2,$10.endm;shorta .macro.byte $e2,$20.endm;shorti .macro.byte $e2,$10.endm;shortr .macro.byte $e2,$30.endm;shortx .macro.byte $e2,$10.endm;;================================================================================;;CONSOLE DISPLAY CONTROL MACROS;; The following macros execute terminal control procedures that perform; such tasks as clearing the screen, switching between normal & reverse; video, etc. These macros are for WYSE 60 & compatible displays, such as; the WYSE 150, WYSE 160, WYSE 325 & WYSE GPT. Only the functions needed; by Supermon 816 are included.;; If your console is not WYSE 60 compatible, you will need to edit these; macros as required to control your particular console or terminal. Note; that in some cases one macro may call another. Exercise caution in your; edits to avoid introducing display bugs.;; If your console display cannot execute one of these procedures, such as; 'CL' (clear to end of line), you will have to develop an alternative.;;; clearing data...;bs .macro ;destructive backspace.byte a_bsdcuc.endm;cl .macro ;clear to end of line.byte a_esc,"T".endm;;; cursor control...;cn .macro ;cursor on.byte a_esc,"`1".endm;co .macro ;cursor off.byte a_esc,"`0".endm;cr .macro ;carriage return.byte a_cr.endm;lf .macro ;carriage return/line feedcr.byte a_lf.endm;;; display attributes...;bf .macro ;reverse foreground.byte a_esc,"(".byte a_esc,"G4".endm;er .macro ;enable normal foreground.byte a_esc,"(".byte a_esc,"G0".endm;sf .macro ;set foreground.byte a_esc,"(".byte a_esc,"G0".endm;;; display editing...;dcuc .macro ;delete char under cursor.byte a_esc,"W".endm;;; miscellaneous control...;rb .macro ;ring "bell".byte a_bel.endm;;================================================================================;;ASCII CONTROL DEFINITIONS (menmonic order);a_bel =$07 ;<BEL> alert/ring bella_bs =$08 ;<BS> backspacea_cr =$0d ;<CR> carriage returna_del =$7f ;<DEL> deletea_esc =$1b ;<ESC> escapea_ht =$09 ;<HT> horizontal tabulationa_lf =$0a ;<LF> linefeed;;; miscellaneous (description order)...;a_blank =' ' ;blank (whitespace)a_asclch ='z' ;end of lowercase ASCIIa_lctouc =$5f ;LC to UC conversion maska_asclcl ='a' ;start of lowercase ASCII;;================================================================================;;GLOBAL ATOMIC CONSTANTS;;; data type sizes...;s_byte =1 ;bytes_word =2 ;word (16 bits)s_xword =3 ;extended word (24 bits)s_dword =4 ;double word (32 bits)s_rampag =$0100 ;65xx RAM page;;; data type sizes in bits...;s_bibyte =8 ;bytes_bnybbl =4 ;nybble;;; miscellaneous...;bitabs =$2c ;absolute BIT opcodebitzp =$24 ;zero page BIT opcode;;================================================================================;;W65C816S NATIVE MODE STATUS REGISTER DEFINITIONS;s_mpudbx =s_byte ;data bank sizes_mpudpx =s_word ;direct page sizes_mpupbx =s_byte ;program bank sizes_mpupcx =s_word ;program counter sizes_mpuspx =s_word ;stack pointer sizes_mpusrx =s_byte ;status size;;; status register flags...;sr_car =@00000001 ;Csr_zer =sr_car << 1 ;Zsr_irq =sr_zer << 1 ;Isr_bdm =sr_irq << 1 ;Dsr_ixw =sr_bdm << 1 ;xsr_amw =sr_ixw << 1 ;msr_ovl =sr_amw << 1 ;Vsr_neg =sr_ovl << 1 ;N;; NVmxDIZC; xxxxxxxx; ||||||||; |||| 1 = decimal arithmetic mode; ||| 1 = 8 bit index; || 1 = 8 bit .A & memory;;================================================================================;;"SIZE-OF" CONSTANTS;s_addr =s_xword ;24 bit addresss_auxbuf =32 ;auxiliary buffers_ibuf =69 ;input buffers_mnemon =3 ;MPU ASCII mnemonics_mnepck =2 ;MPU encoded mnemonics_mvinst =3 ;MVN/MVP instructions_opcode =s_byte ;MPU opcodes_oper =s_xword ;operands_pfac =s_dword ;primary math accumulators_sfac =s_dword+s_word ;secondary math accumulators;;================================================================================;;"NUMBER-OF" CONSTANTS;n_dbytes =21 ;default disassembly bytesn_dump =8 ;bytes per memory dump linen_mbytes =s_rampag-1 ;default memory dump bytesn_hccols =8 ;compare/hunt display columnsn_opcols =3*s_oper ;disassembly operand columnsn_opslsr =4 ;LSRs to extract instruction sizen_shfenc =5 ;shifts to encode/decode mnemonic;;================================================================================;;NUMERIC CONVERSION CONSTANTS;a_hexdec ='A'-'9'-2 ;hex to decimal differencec_bin ='%' ;binary prefixc_dec ='+' ;decimal prefixc_hex ='$' ;hexadecimal prefixc_oct ='@' ;octal prefixk_hex ='f' ;hex ASCII conversionm_bits =s_pfac*s_bibyte ;operand bit sizem_cbits =s_sfac*s_bibyte ;workspace bit sizebcdumask =@00001111 ;isolate BCD units maskbtoamask =@00110000 ;binary to ASCII mask;;================================================================================;;ASSEMBLER/DISASSEMBLER CONSTANTS;a_mnecvt ='?' ;encoded mnemonic conversion baseaimmaska =@00011111 ;.A immediate opcode test #1aimmaskb =@00001001 ;.A immediate opcode test #2asmprfx ='A' ;assemble code prefixascprmct =9 ;assembler prompt "size-of"disprfx ='.' ;disassemble code prefixflimmask =@11000000 ;force long immediate flagopc_mvn =$54 ;MVN opcodeopc_mvp =$44 ;MVP opcodeopc_rep =$c2 ;REP opcodeopc_sep =$e2 ;SEP opcodepfmxmask =sr_amw | sr_ixw ;MPU m & x flag bits mask;;; assembler prompt buffer offsets...;apadrbkh =s_word ;instruction address bank MSNapadrbkl =apadrbkh+s_byte ;instruction address bank LSNapadrmbh =apadrbkl+s_byte ;instruction address MSB MSNapadrmbl =apadrmbh+s_byte ;instruction address MSB LSNapadrlbh =apadrmbl+s_byte ;instruction address LSB MSNapadrlbl =apadrlbh+s_byte ;instruction address LSB LSN;;; addressing mode preamble symbols...;amp_flim ='!' ;force long immediateamp_imm ='#' ;immediateamp_ind ='(' ;indirectamp_indl ='[' ;indirect long;;; addressing mode symbolic translation indices...;am_nam =@0000 ;(0) no symbolam_imm =@0001 ;(1) #am_adrx =@0010 ;(2) dp,X or addr,Xam_adry =@0011 ;(3) dp,Y or addr,Yam_ind =@0100 ;(4) (dp) or (addr)am_indl =@0101 ;(5) [dp] or [addr]am_indly =@0110 ;(6) [dp],Yam_indx =@0111 ;(7) (dp,X) or (addr,X)am_indy =@1000 ;(8) (dp),Yam_stk =@1001 ;(9) offset,Sam_stky =@1010 ;(10) (offset,S),Yam_move =@1011 ;(11) MVN/MVP sbnk,dbnk;;; operand size translation indices...;ops0 =@0000 << 4 ;no operandops1 =@0001 << 4 ;8 bit operandops2 =@0010 << 4 ;16 bit operandops3 =@0011 << 4 ;24 bit operandbop1 =@0101 << 4 ;8 bit relative branchbop2 =@0110 << 4 ;16 bit relative branchvops =@1001 << 4 ;8 or 16 bit operand;;; operand size & addressing mode extraction masks...;amodmask =@00001111 ;addressing mode indexopsmask =@00110000 ;operand sizevopsmask =@11000000 ;BOPx & VOPS flag bits;;; instruction mnemonic encoding...;mne_adc =$2144 ;ADCmne_and =$2bc4 ;ANDmne_asl =$6d04 ;ASLmne_bcc =$2106 ;BCCmne_bcs =$a106 ;BCSmne_beq =$9186 ;BEQmne_bit =$aa86 ;BITmne_bmi =$5386 ;BMImne_bne =$33c6 ;BNEmne_bpl =$6c46 ;BPLmne_bra =$14c6 ;BRAmne_brk =$64c6 ;BRKmne_brl =$6cc6 ;BRLmne_bvc =$25c6 ;BVCmne_bvs =$a5c6 ;BVSmne_clc =$2348 ;CLCmne_cld =$2b48 ;CLDmne_cli =$5348 ;CLImne_clv =$bb48 ;CLVmne_cmp =$8b88 ;CMPmne_cop =$8c08 ;COPmne_cpx =$cc48 ;CPXmne_cpy =$d448 ;CPYmne_dec =$218a ;DECmne_dex =$c98a ;DEXmne_dey =$d18a ;DEYmne_eor =$9c0c ;EORmne_inc =$23d4 ;INCmne_inx =$cbd4 ;INXmne_iny =$d3d4 ;INYmne_jml =$6b96 ;JMLmne_jmp =$8b96 ;JMPmne_jsl =$6d16 ;JSLmne_jsr =$9d16 ;JSRmne_lda =$115a ;LDAmne_ldx =$c95a ;LDXmne_ldy =$d15a ;LDYmne_lsr =$9d1a ;LSRmne_mvn =$7ddc ;MVNmne_mvp =$8ddc ;MVPmne_nop =$8c1e ;NOPmne_ora =$14e0 ;ORAmne_pea =$11a2 ;PEAmne_pei =$51a2 ;PEImne_per =$99a2 ;PERmne_pha =$1262 ;PHAmne_phb =$1a62 ;PHBmne_phd =$2a62 ;PHDmne_phk =$6262 ;PHKmne_php =$8a62 ;PHPmne_phx =$ca62 ;PHXmne_phy =$d262 ;PHYmne_pla =$1362 ;PLAmne_plb =$1b62 ;PLBmne_pld =$2b62 ;PLDmne_plp =$8b62 ;PLPmne_plx =$cb62 ;PLXmne_ply =$d362 ;PLYmne_rep =$89a6 ;REPmne_rol =$6c26 ;ROLmne_ror =$9c26 ;RORmne_rti =$5566 ;RTImne_rtl =$6d66 ;RTLmne_rts =$a566 ;RTSmne_sbc =$20e8 ;SBCmne_sec =$21a8 ;SECmne_sed =$29a8 ;SEDmne_sei =$51a8 ;SEImne_sep =$89a8 ;SEPmne_sta =$1568 ;STAmne_stp =$8d68 ;STPmne_stx =$cd68 ;STXmne_sty =$d568 ;STYmne_stz =$dd68 ;STZmne_tax =$c8aa ;TAXmne_tay =$d0aa ;TAYmne_tcd =$292a ;TCDmne_tcs =$a12a ;TCSmne_tdc =$216a ;TDCmne_trb =$1cea ;TRBmne_tsb =$1d2a ;TSBmne_tsc =$252a ;TSCmne_tsx =$cd2a ;TSXmne_txa =$166a ;TXAmne_txs =$a66a ;TXSmne_txy =$d66a ;TXYmne_tya =$16aa ;TYAmne_tyx =$ceaa ;TYXmne_wai =$50b0 ;WAImne_wdm =$7170 ;WDMmne_xba =$10f2 ;XBAmne_xce =$3132 ;XCE;;; encoded instruction mnemonic indices...;mne_adcx =16 ;ADCmne_andx =29 ;ANDmne_aslx =44 ;ASLmne_bccx =15 ;BCCmne_bcsx =65 ;BCSmne_beqx =59 ;BEQmne_bitx =70 ;BITmne_bmix =36 ;BMImne_bnex =31 ;BNEmne_bplx =42 ;BPLmne_brax =5 ;BRAmne_brkx =39 ;BRKmne_brlx =43 ;BRLmne_bvcx =23 ;BVCmne_bvsx =68 ;BVSmne_clcx =20 ;CLCmne_cldx =27 ;CLDmne_clix =35 ;CLImne_clvx =71 ;CLVmne_cmpx =53 ;CMPmne_copx =55 ;COPmne_cpxx =78 ;CPXmne_cpyx =88 ;CPYmne_decx =18 ;DECmne_dexx =74 ;DEXmne_deyx =84 ;DEYmne_eorx =61 ;EORmne_incx =21 ;INCmne_inxx =77 ;INXmne_inyx =87 ;INYmne_jmlx =40 ;JMLmne_jmpx =54 ;JMPmne_jslx =45 ;JSLmne_jsrx =63 ;JSRmne_ldax =1 ;LDAmne_ldxx =73 ;LDXmne_ldyx =83 ;LDYmne_lsrx =64 ;LSRmne_mvnx =48 ;MVNmne_mvpx =58 ;MVPmne_nopx =56 ;NOPmne_orax =6 ;ORAmne_peax =2 ;PEAmne_peix =33 ;PEImne_perx =60 ;PERmne_phax =3 ;PHAmne_phbx =10 ;PHBmne_phdx =26 ;PHDmne_phkx =38 ;PHKmne_phpx =51 ;PHPmne_phxx =75 ;PHXmne_phyx =85 ;PHYmne_plax =4 ;PLAmne_plbx =11 ;PLBmne_pldx =28 ;PLDmne_plpx =52 ;PLPmne_plxx =76 ;PLXmne_plyx =86 ;PLYmne_repx =49 ;REPmne_rolx =41 ;ROLmne_rorx =62 ;RORmne_rtix =37 ;RTImne_rtlx =46 ;RTLmne_rtsx =67 ;RTSmne_sbcx =14 ;SBCmne_secx =19 ;SECmne_sedx =25 ;SEDmne_seix =34 ;SEImne_sepx =50 ;SEPmne_stax =7 ;STAmne_stpx =57 ;STPmne_stxx =80 ;STXmne_styx =89 ;STYmne_stzx =91 ;STZmne_taxx =72 ;TAXmne_tayx =82 ;TAYmne_tcdx =24 ;TCDmne_tcsx =66 ;TCSmne_tdcx =17 ;TDCmne_trbx =12 ;TRBmne_tsbx =13 ;TSBmne_tscx =22 ;TSCmne_tsxx =79 ;TSXmne_txax =8 ;TXAmne_txsx =69 ;TXSmne_txyx =90 ;TXYmne_tyax =9 ;TYAmne_tyxx =81 ;TYXmne_waix =32 ;WAImne_wdmx =47 ;WDMmne_xbax =0 ;XBAmne_xcex =30 ;XCE;;================================================================================;;MISCELLANEOUS CONSTANTS;halftab =4 ;1/2 tabulation spacingmemprfx ='>' ;memory dump prefixmemsepch =':' ;memory dump separatormemsubch ='.' ;memory dump non-print charsrinit =@00110000 ;SR initialization value;;================================================================================;;DIRECT PAGE STORAGE;reg_pbx =zeropage ;PBreg_pcx =reg_pbx+s_mpupbx ;PCreg_srx =reg_pcx+s_mpupcx ;SRreg_ax =reg_srx+s_mpusrx ;.Creg_xx =reg_ax+s_word ;.Xreg_yx =reg_xx+s_word ;.Yreg_spx =reg_yx+s_word ;SPreg_dpx =reg_spx+s_mpuspx ;DPreg_dbx =reg_dpx+s_mpudpx ;DB;;; general workspace...;addra =reg_dbx+s_mpudbx ;address #1addrb =addra+s_addr ;address #2faca =addrb+s_addr ;primary accumulatorfacax =faca+s_pfac ;extended primary accumulatorfacb =facax+s_pfac ;secondary accumulatorfacc =facb+s_sfac ;tertiary accumulatoroperand =facc+s_sfac ;instruction operandauxbufix =operand+s_oper ;auxiliary buffer indexibufidx =auxbufix+s_byte ;input buffer indexbitsdig =ibufidx+s_byte ;bits per numeralnumeral =bitsdig+s_byte ;numeral bufferradix =numeral+s_byte ;radix indexadmodidx =radix+s_byte ;addressing mode indexcharcnt =admodidx+s_byte ;character counterinstsize =charcnt+s_word ;instruction sizemnepck =instsize+s_word ;encoded mnemonicopcode =mnepck+s_mnepck ;current opcodestatus =opcode+s_byte ;I/O status flagxrtemp =status+s_byte ;temp .X storageeopsize =xrtemp+s_byte ;entered operand sizeflimflag =eopsize+s_byte ;forced long immediate...;; xx000000; ||; | 1: .X/.Y = 18 bits; 1: .A = 16 bits;; During assembly, FLIMFLAG indicates the operand size used with an immed-; iate mode instruction, thus causing the following disassembly to display; the assembled operand size. During disassembly, FLIMFLAG will mirror; the effect of the most recent REP or SEP instruction.;iopsize =flimflag+s_byte ;operand sizerange =iopsize+s_byte ;allowable radix rangevopsflag =range+s_byte ;VOPS & ROPS mode bits;;; copy/fill workspace (overlaps some of the above)...;mcftwork =vopsflag+s_byte ;faca ;start of copy/fill codemcftopc =mcftwork+s_byte ;instruction opcodemcftbnk =mcftopc+s_byte ;banks;;================================================================================;;SUPERMON 816 JUMP TABLE;org _origin_;JMON bra mon ;cold start entryJMONBRK bra monbrk ;software interrupt intercept;;================================================================================;;mon: SUPERMON 816 COLD START;mon longalda vecbrki ;BRK vectorcmpw monbrk ;pointing at monitor?bne .2 ;yes, ignore cold startjmp monreg ; got a branch out of range here when debugging code; was included.2;sta vecbrkia ;save vector for exitldaw monbrk ;Supermon 816 intercepts...sta vecbrki ;BRK handlershortr ;8 bit registersldx #vopsflag-reg_pbx;.0000010 stz reg_pbx,x ;clear DP storagedexbpl .0000010;lda #srinitsta reg_srx ;status registerlonga ;16 bit .Aldaw hwstack ;top of hardware stacktcs ;set SPtdc ;get & save...sta reg_dpx ;DP registerldaw 0shortaphkpla ;capture PB &...sta reg_pbx ;setphbpla ;capture DB &...sta reg_dbx ;setpea mm_entry ;"...ready..."bra moncom;;================================================================================;;monbrk: SOFTWARE INTERRUPT INTERCEPT;; This is the entry point taken when a BRK instruction is executed. It is; assumed that the BRK handler has pushed the registers to the stack that; are not automatically pushed by the MPU in response to BRK.;monbrk cli ;reenable IRQsply ;recover registersplxplalongr ;store 16 bit registerssta reg_ax ;.Astx reg_xx ;.Xsty reg_yx ;.Yshortx ;8 bit index registerspla ;get DP &...sta reg_dpx ;storeplx ;get DB &...stx reg_dbx ;storeplx ;get SR &...stx reg_srx ;storepla ;get PC &...sta reg_pcx ;storeshortapla ;get PB &...sta reg_pbx ;storepea mm_brk ;"*BRK";;================================================================================;;moncom: COMMON ENTRY POINT;; DO NOT directly call this entry point!;moncom jsr sprint ;print headinglongatsc ;get SP &...sta reg_spx ;storerep @11111111 ;clear SR &...sep srinit ;set default statesec ;see next;;================================================================================;;monreg: DISPLAY MPU REGISTERS;; syntax: R;monreg bcs .0000010 ;okay to proceed;jmp monerr ;error if called with a parm;.0000010 pea mm_regsjsr sprint ;display heading;;; display program bank & counter...;lda reg_pbx ;PBjsr dpyhex ;display as hex ASCIIjsr printspc ;inter-field spacelongalda reg_pcxshortajsr dpyhexw ;display PCldx #2jsr multspc ;inter-field spacing;;; display SR in bitwise fashion...;ldx reg_srx ;SRldy #s_bibyte ;bits in a byte;.0000020 txa ;remaining SR bitsasl ;grab one of themtax ;save remainderlda #'0' ;a clear bit but...adc #0 ;adjust if set &...jsr putcha ;printdey ;bit processedbne .0000020 ;do another;;; display .C, .X, .Y, SP & DP...;.0000030 jsr printspc ;spacinglongalda reg_ax,y ;get register valueshortajsr dpyhexw ;convert & display; .rept s_wordinyiny; .endrcpy #reg_dbx-reg_axbcc .0000030 ;next;;; display DB...;jsr printspc ;more spacinglda reg_dbx ;get DB &...jsr dpyhex ;display it;;================================================================================;;monce: COMMAND EXECUTIVE;monce shortalda #0 ;default buffer index;moncea shortr ;alternate entry pointsta ibufidx ;(re)set buffer indexpea mm_prmptjsr sprint ;display input promptjsr input ;await some input;.0000010:jsr getcharc ;read from bufferbeq monce ;terminator, just loop;cmp #a_blankbeq .0000010 ;strip leading blanks;ldx #n_mpctab-1 ;number of primary commands;.0000020 cmp mpctab,x ;search primary command listbne .0000030;txa ;get indexasl ;double for offsettaxlongalda mpcextab,x ;command address -1pha ;prime the stackshortajmp getparm ;evaluate parm & execute command;.0000030 dexbpl .0000020 ;continue searching primary commands;ldx #n_radix-1 ;number of radices;.0000040 cmp radxtab,x ;search conversion command listbne .0000050;jmp monenv ;convert & display parameter;.0000050 dexbpl .0000040;;================================================================================;;monerr: COMMON ERROR HANDLER;monerr shortr ;8 bit registers;monerraa jsr dpyerr ;indicate an error &...bra monce ;return to input loop;;================================================================================;;monasc: ASSEMBLE CODE;; syntax: A <addr> <mnemonic> [<argument>];; After a line of code has been successfully assembled it will be disass-; embled & displayed, & the monitor will prompt with the next address to; which code may be assembled.;monasc bcc .0000020 ;assembly address entered;.0000010 jmp monerr ;terminate w/error;;; evaluate assembly address...;.0000020 jsr facasize ;check address...cmp #s_dword ;range;jsr facaddra ;store assembly address;;; initialize workspace...;ldx #s_auxbuf-s_byte;.0000030 stz auxbuf,x ;clear addressing mode bufferdexbne .0000030;lda #a_blanksta auxbuf ;preamble placeholderjsr clroper ;clear operandstz auxbufix ;reset addressing mode indexstz flimflag ;clear forced long immediatestz mnepck ;clear encoded...stz mnepck+s_byte ;mnemonic workspacestz vopsflag ;clear 8/16 or relative flag;;; encode mnemonic...;ldy #s_mnemon ;expected mnemonic size;.0000040 jsr getcharw ;get from buffer wo/whitespacebne .0000060 ;gotten;cpy #s_mnemon ;any input at all?bcc .0000050 ;yes;jmp monce ;no, abort further assembly;;.0000060 secsbc #a_mnecvt ;ASCII to binary factorldx #n_shfenc ;shifts required to encode;.0000070 lsr ;shift out a bit...ror mnepck+s_byte ;into...ror mnepck ;encoded mnemonicdexbne .0000070 ;next bit;deybne .0000040 ;get next char;;; test for copy instruction...; The MVN & MVP instructions accept two operands & hence have an irregular; syntax. Therefore, special handling is necessary to assemble either of; these instructions.;; The official WDC syntax has the programmer entering a pair of 24 bit ad-; dresses as operands, with the assembler isolating bits 16-23 to use as; operands. This formality has been dispensed with in this monitor & the; operands are expected to be 8 bit bank values.;longa ;16 bit loadlda mnepck ;packed menmonicldx #opc_mvn ;MVN opcodecmpw mne_mvn ;is it MVN?beq monasc01 ;yes;ldx #opc_mvp ;MVP opcodecmpw mne_mvp ;is it MVP?bne monasc02 ;no;;; assemble copy instruction...;monasc01 stx opcode ;store relevant opcodeshortajsr instdata ;get instruction datastx eopsize ;effective operand sizeinxstx instsize ;instruction sizeldx #s_oper-s_word ;operand indexstx xrtemp ;set it;.0000010 jsr ascbin ;evaluate bank numberbcs monasc04 ;conversion error;;jsr facasize ;bank must be...cmp #s_word ;8 bits;lda faca ;bankldx xrtemp ;operand indexsta operand,x ;storedec xrtemp ;index=index-1bpl .0000010 ;get destination bank;jsr getcharr ;should be no more input;jmp monasc08 ;finish MVN/MVP assembly;;; continue with normal assembly...;monasc02 shorta ;back to 8 bits;monasc03 jsr getcharw ;get next charbeq monasc06 ;EOI, no argument;cmp #amp_flimbne .0000010 ;no forced long immediate;lda flimflag ;FLIM already set?;lda #flimmasksta flimflag ;set flag &...bra monasc03 ;get next char;.0000010 cmp #amp_imm ;immediate mode?beq .0000020 ;yes;cmp #amp_ind ;indirect mode?beq .0000020 ;yes;cmp #amp_indl ;indirect long mode?bne .0000030 ;no;.0000020 sta auxbuf ;set addressing mode preambleinc auxbufix ;bump aux buffer index &...bra .0000040 ;evaluate operand;.0000030 dec ibufidx ;position back to char;.0000040 jsr ascbin ;evaluate operandbne monasc05 ;evaluated;bcs monasc04 ;conversion error;lda auxbufix ;no operand...any preamble?beq monasc06 ;no, syntax is okay so far;monasc04 jmp monasc10 ;abort w/error;monasc05 jsr facasize ;size operandcmp #s_dword ;max is 24 bitsbcs monasc04 ;too big;sta eopsize ;save operand sizejsr facaoper ;store operand;monasc06 dec ibufidx ;back to last charldx auxbufix ;mode buffer indexbne .0000010 ;preamble in buffer;inx ;step past preamble position;.0000010 jsr getcharc ;get a char w/forced UCbeq .0000030 ;EOI;cpx #s_auxbuf ;mode buffer full?bcs monasc04 ;yes, too much input;.0000020 sta auxbuf,x ;store for comparisoninxbne .0000010;;; evaluate mnemonic...;.0000030 ldx #n_mnemon-1 ;starting mnemonic index;monasc07 txa ;convert index...asl ;to offsettay ;now mnemonic table indexlonga ;16 bit comparelda mnetab,y ;get mnemonic from tablecmp mnepck ;compare to entered mnemonicshorta ;back to 8 bitsbeq .0000020 ;match;.0000010 dex ;try next mnemonic;bra monasc07 ;keep going;.0000020 stx mnepck ;save mnemonic indextxaldx #0 ;trial opcode;.0000030 cmp mnetabix,x ;search index table...beq .0000050 ;for a match;.0000040 inx ;keep going until we...bne .0000030 ;search entire table;bra monasc04 ;this shouldn't happen!;; If the mnemonic index table search fails then there is a coding error; somewhere, as every entry in the mnemonic table is supposed to have a; matching cardinal index.;;; evaluate addressing mode...;.0000050 stx opcode ;save trial opcodejsr instdata ;get related instruction datasta vopsflag ;save 8/16 or relative flagstx iopsize ;operand sizeinxstx instsize ;instruction sizeldx opcode ;recover trial opcodetya ;addressing modeasl ;create table indextaylongalda ms_lutab,y ;mode lookup tablesta addrb ;set pointershortaldy #0;.0000060 lda (addrb),y ;table addressing modecmp auxbuf,y ;entered addressing modebeq .0000080 ;okay so far;.0000070 lda mnepck ;reload mnemonic indexbra .0000040 ;wrong opcode for addresing mode;.0000080 ora #0 ;last char the terminator?beq .0000090 ;yes, evaluate operand;inybra .0000060 ;keep testing;;; evaluate operand...;.0000090 lda eopsize ;entered operand sizebne .0000100 ;non-zero;ora iopsize ;instruction operand size;bra monasc08 ;assemble instruction;.0000100 bit vopsflag ;is this a branch?bvs .0000160 ;yes, evaluate;lda iopsize ;instruction operand sizebit vopsflag ;variable size operand allowed?bmi .0000130 ;yes;bit flimflag ;was forced immediate set?bpl .0000110 ;no;;.0000110 cmp eopsize ;entered operand sizebcc .0000070 ;operand too big;sta eopsize ;new operand sizebra monasc08 ;assemble, otherwise...;.0000120 cmp eopsize ;exact size match required;bra monasc08 ;assemble;;; process variable size immediate mode operand...;.0000130 ldx eopsize ;entered operand sizecpx #s_xword ;check size;bit flimflag ;forced long immediate?bpl .0000140 ;no;ldx #s_word ;promote operand size to...stx eopsize ;16 bitsbra .0000150;.0000140 cpx #s_word ;16 bits?bne .0000150 ;no;ldy #flimmask ;yes so force long...sty flimflag ;immediate disassembly;.0000150 ina ;new instruction operand sizecmp eopsize ;compare against operand size;bra monasc08 ;okay, assemble;;; process relative branch...;.0000160 jsr targoff ;compute branch offsetbcs monasc10 ;branch out of range;sta eopsize ;effective operand size;;; assemble instruction...;monasc08 lda opcode ;opcodestail addra ;store at assembly addressldx eopsize ;any operand to process?beq .0000020 ;no;txy ;also storage offset;.0000010 dexlda operand,x ;get operand byte &...staily addra ;poke into memorydeybne .0000010 ;next;.0000020 lda #a_crjsr putcha ;return to left marginlda #asmprfx ;assembly prefixjsr dpycodaa ;disassemble & display;;; prompt for next instruction...;monasc09 lda #a_blankldx #ascprmct-1;.0000010 sta ibuffer,x ;prepare buffer for...dex ;next instructionbpl .0000010;lda #asmprfx ;assemble code...sta ibuffer ;prompt prefixlda addra+s_word ;next instruction address bankjsr binhex ;convert to ASCIIsta ibuffer+apadrbkh ;store MSN in bufferstx ibuffer+apadrbkl ;store LSN in bufferlda addra+s_byte ;next instruction address MSBjsr binhexsta ibuffer+apadrmbhstx ibuffer+apadrmbllda addra ;next instruction address LSBjsr binhexsta ibuffer+apadrlbhstx ibuffer+apadrlbllda #ascprmct ;effective input countjmp moncea ;reenter input loop;;; process assembly error...;monasc10 jsr dpyerr ;indicate error &...bra monasc09 ;prompt w/same assembly address;;================================================================================;;mondsc: DISASSEMBLE CODE;; syntax: D [<addr1> [<addr2>]];mondsc bcs .0000010 ;no parameters;stz flimflag ;reset to 8 bit modejsr facasize ;check starting...cmp #s_dword ;address;jsr facaddra ;copy starting addressjsr getparm ;get ending addressbcc .0000020 ;gotten;.0000010 jsr clrfaca ;clear accumulatorlongaclclda addra ;starting addressadcw n_dbytes ;default bytessta faca ;effective ending addressshortalda addra+s_word ;starting bankadc #0sta faca+s_word ;effective ending bankbcs .0000050 ;end address > $FFFFFF;.0000020 jsr facasize ;check ending...cmp #s_dword ;address;jsr facaddrb ;set ending addressjsr getparm ;check for excess input;jsr calccnt ;calculate bytesbcc .0000050 ;end < start;.0000030 jsr teststop ;test for display stopbcs .0000040 ;stopped;jsr newline ;next linejsr dpycod ;disassemble & displayjsr decdcnt ;decrement byte countbcc .0000030 ;not done;.0000040 jmp monce ;back to main loop;.0000050 jmp monerr ;address range error;;================================================================================;;monjmp: EXECUTE CODE;; syntax: G [<addr>];; If no address is specified, the current values in the PB & PC; shadow registers are used.;monjmp jsr setxaddr ;set execution address;jsr getparm ;check for excess input;longa ;16 bit .Alda reg_spxtcs ;restore SP;monjmpaa shortalda reg_pbxpha ;restore PBlongalda reg_pcxpha ;restore PCshortalda reg_srxpha ;restore SRlda reg_dbxphaplb ;restore DBlongrlda reg_dpxtcd ;restore DPlda reg_ax ;restore .Cldx reg_xx ;restore .Xldy reg_yx ;restore .Yrti ;execute code;monjmpab jmp monerr ;error;;================================================================================;;monjsr: EXECUTE CODE AS SUBROUTINE;; syntax: J [<addr>];; If no address is specified the current values in the PB & PC; shadow registers are used. An RTS at the end of the called; subroutine will return control to the monitor provided the; stack remains in balance.;monjsr jsr setxaddr ;set execution address;jsr getparm ;check for excess input;longalda reg_spxtcs ;restore SP &...jsr monjmpaa ;call subroutinephp ;push SRlongrsta reg_ax ;save...stx reg_xx ;register...sty reg_yx ;returnsshortx ;8 bit .X & .Yplx ;get & save...stx reg_srx ;return SRtsc ;get & save...sta reg_spx ;return SPtdc ;get & save...sta reg_dpx ;DP pointershorta ;8 bit .Aphk ;get &...pla ;save...sta reg_pbx ;return PBphb ;get &...pla ;save...sta reg_dbx ;return DBpea mm_rts ;"*RET"jmp moncom ;return to monitor;;================================================================================;;monchm: CHANGE and/or DUMP MEMORY;; syntax: > [<addr> <operand> [<operand>]...];; > <addr> without operands will dump 16 bytes; of memory, starting at <addr>.;;jsr facasize ;size addresscmp #s_dword;jsr facaddra ;set starting addressjsr getpat ;evaluate change patternbcc .0000010 ;entered;bpl .0000020 ;not entered;bra .0000040 ;evaluation error;.0000010 dey ;next bytebmi .0000020 ;done;lda auxbuf,y ;write pattern...staily addra ;to memorybra .0000010 ;next;.0000020 jsr newline ;next linejsr dpymem ;regurgitate changes;.0000030 jmp monce ;back to command loop;.0000040 jmp monerr ;goto error handler;;================================================================================;;moncmp: COMPARE MEMORY;; syntax: C <start> <end> <ref>;;jsr enddest ;get end & reference addressesbcs .0000040 ;range or other error;stz xrtemp ;column counter;.0000010 jsr teststop ;check for stopbcs .0000030 ;abort;ldail addra ;get from reference locationcmpil operand ;test against compare locationbeq .0000020 ;match, don't display address;jsr dpycaddr ;display current location;.0000020 jsr nxtaddra ;next reference locationbcs .0000030 ;done;longainc operand ;bump bits 0-15shortabne .0000010;inc operand+s_word ;bump bits 16-23bra .0000010;.0000030 jmp monce ;return to command exec;.0000040 jmp monerr ;goto error handler;;================================================================================;;moncpy: COPY (transfer) MEMORY;; syntax: T <start> <end> <target>;;jsr enddest ;get end & target addressesbcs .0000050 ;range or other error;longaseclda addrb ;ending addresssbc addra ;starting address;sta facb ;bytes to copyshortalongxlda operand+s_word ;target bankldy operand ;target addresscmp addra+s_word ;source banklongabne .0000020 ;can use forward copy;cpy addra ;source addressbcc .0000020 ;can use forward copy;bne .0000010 ;must use reverse copy;;.0000010 lda facb ;get bytes to copypha ;protectjsr lodbnk ;load banksjsr cprvsup ;do reverse copy setuppla ;get bytes to copytax ;save a copyclcadc operand ;change target to...tay ;target endtxa ;recover bytes to copyldx addrb ;source endbra .0000030;.0000020 lda facb ;get bytes to copypha ;protectjsr lodbnk ;load banksjsr cpfwsup ;do forward copy setuppla ;get bytes to copyldx addra ;source start;.0000030 jmp mcftwork ;copy memory;.0000040 jmp monce ;back to executive;.0000050 jmp monerr ;error;;================================================================================;;mondmp: DISPLAY MEMORY RANGE;; syntax: M [<addr1> [<addr2>]];mondmp bcs .0000010 ;no parameters;jsr facasize ;check address...cmp #s_dword ;rangebcs .0000050 ;address out of range;jsr facaddra ;copy starting addressjsr getparm ;get ending addressbcc .0000020 ;gotten;.0000010 jsr clrfaca ;clear accumulatorlongaclclda addra ;starting addressadcw n_mbytes ;default bytessta faca ;effective ending addressshortalda addra+s_word ;starting bankadc #0sta faca+s_word ;effective ending bankbcs .0000050 ;end address > $FFFFFF;.0000020 jsr facasize ;check ending address...cmp #s_dword ;range;jsr facaddrb ;copy ending addressjsr getparm ;check for excess inputbcc .0000050 ;error;jsr calccnt ;calculate bytes to dumpbcc .0000050 ;end < start;.0000030 jsr teststop ;test for display stopbcs .0000040 ;stopped;jsr newline ;next linejsr dpymem ;displayjsr decdcnt ;decrement byte countbcc .0000030 ;not done;.0000040 jmp monce ;back to main loop;.0000050 jmp monerr ;address range error;;================================================================================;;monfil: FILL MEMORY;; syntax: F <start> <end> <fill>;; <start> & <end> must be in the same bank.;;jsr facasize ;check sizecmp #s_dword;jsr facaddra ;store startjsr getparm ;evaluate end;jsr facasize ;check sizecmp #s_dword;lda faca+s_word ;end bankcmp addra+s_word ;start bank;jsr facaddrb ;store <end>longaseclda addrb ;ending addresssbc addra ;starting address;sta facb ;bytes to copyshortajsr getparm ;evaluate <fill>;jsr facasize ;<fill> should be...cmp #s_word ;8 bits;jsr facaoper ;store <fill>jsr getparm ;should be no more parameters;lda operand ;<fill>stail addra ;fill 1st locationlongr ;16 bit operationslda facb ;;dea ;zero align &...pha ;protectshortalda addra+s_word ;start bankxbalda addrb+s_word ;end bankjsr cpfwsup ;do forward copy setuppla ;recover fill countldx addra ;fill-from starting locationtxyiny ;fill-to starting locationjmp mcftwork ;fill memory;.0000010 jmp monce ;goto command executive;.0000020 jmp monerr ;goto error handler;;================================================================================;;monhnt: SEARCH (hunt) MEMORY;; syntax: H <addr1> <addr2> <pattern>;monhnt bcs .0000050 ;no start address;jsr facasize ;size starting addresscmp #s_dword;jsr facaddra ;store starting addressjsr getparm ;evaluate ending address;jsr facasize ;size ending addresscmp #s_dword;jsr facaddrb ;store ending addressjsr calccnt ;calculate byte rangebcc .0000060 ;end < start;jsr getpat ;evaluate search patternbcs .0000060 ;error;stz xrtemp ;clear column counter;.0000010 jsr teststop ;check for stopbcs .0000050 ;abort;ldy auxbufix ;pattern index;.0000020 deybmi .0000030 ;pattern match;ldaily addra ;get from memorycmp auxbuf,y ;test against patternbne .0000040 ;mismatch, next location;beq .0000020 ;match, keep testing;.0000030 jsr dpycaddr ;display current location;.0000040 jsr nxtaddra ;next locationbcc .0000010 ;not done;.0000050 jmp monce ;back to executive;.0000060 jmp monerr ;goto error handler;;================================================================================;;monenv: CONVERT NUMERIC VALUE;; syntax: <radix><value>;monenv jsr getparmr ;reread & evaluate parameterbcs .0000020 ;none entered;ldx #0 ;radix indexldy #n_radix ;number of radices;.0000010 phy ;save counterphx ;save radix indexjsr newline ;next line &...jsr clearlin ;clear itlda #a_blankldx #halftabjsr multspc ;indent 1/2 tabplx ;get radix index but...phx ;put it backlda radxtab,x ;get radixjsr binasc ;convert to ASCIIphy ;string address MSBphx ;string address LSBjsr sprint ;printplx ;get index againply ;get counterinxdeybne .0000010 ;no.0000020 jmp monce ;back to command exec;;================================================================================;;monchr: CHANGE REGISTERS;; syntax: ; [PB [PC [.S [.C [.X [.Y [SP [DP [DB]]]]]]]]];; ; with no parameters is the same as the R command.;monchr bcs .0000040 ;dump registers & quit;ldy #0 ;register countersty facc ;initialize register index;.0000010 jsr facasize ;get parameter sizecmp rcvltab,y ;check against size tablebcs .0000050 ;out of range;lda rcvltab,y ;determine number of bytes...cmp #s_word+1 ;to storeror facc+s_byte ;condition flagbpl .0000020 ;8 bit register size;longa ;16 bit register size;.0000020 ldx facc ;get register indexlda faca ;get parmsta reg_pbx,x ;put in shadow storageshortaasl facc+s_byte ;mode flag to carrytxa ;register indexadc #s_byte ;at least 1 byte storedsta facc ;save new indexjsr getparm ;get a parameterbcs .0000040 ;EOI;iny ;bump register countcpy #n_regchv ;all registers processed?bne .0000010 ;no, keep going;.0000030 jsr alert ;excessive input;.0000040 jmp monreg ;display changes;.0000050 jmp monerr ;goto error handler;;================================================================================;;monxit: EXIT TO OPERATING ENVIRONMENT;; syntax: X;monxit bcc .0000020 ;no parameters allowed;longalda vecbrki ;BRK indirect vectorcmpw monbrk ;we intercept it?bne .0000010 ;no, don't change it;lda vecbrkia ;old vectorsta vecbrki ;restore itstz vecbrkia ;invalidate old vector;.0000010 shortrjml vecexit ;long jump to exit;.0000020 jmp monerr ;goto error handler;; * * * * * * * * * * * * * * * * * * * * * * * *; * * * * * * * * * * * * * * * * * * * * * * * *; * * * *; * * S T A R T o f S U B R O U T I N E S * *; * * * *; * * * * * * * * * * * * * * * * * * * * * * * *; * * * * * * * * * * * * * * * * * * * * * * * *;;dpycaddr: DISPLAY CURRENT ADDRESS IN COLUMNS;dpycaddr ldx xrtemp ;column countbne .0000010 ;not at right side;jsr newline ;next rowldx #n_hccols ;max columns;.0000010 cpx #n_hccols ;max columnsbeq .0000020 ;at left margin;lda #a_htjsr putcha ;tab a column;.0000020 dex ;one less columnstx xrtemp ;save column counterjmp prntladr ;print reference address;;================================================================================;;dpycod: DISASSEMBLE & DISPLAY CODE;; This function disassembles & displays the machine code at the location; pointed to by ADDRA. Upon return, ADDRA will point to the opcode of the; next instruction. The entry point at DPYCODAA should be called with a; disassembly prefix character loaded in .A. If entered at DPYCOD, the; default character will be display at the beginning of each disassembled; instruction.;; The disassembly of immediate mode instructions that can take an 8 or 16; bit operand is affected by the bit pattern that is stored in FLIMFLAG; upon entry to this function:;; FLIMFLAG: xx000000; ||; | 1: 16 bit .X or .Y operand; 1: 16 bit .A or BIT # operand;; FLIMFLAG is conditioned according to the operand of the most recently; disassembled REP or SEP instruction. Hence repetitive calls to this; subroutine will usually result in the correct disassembly of 16 bit imm-; ediate mode instructions.;dpycod lda #disprfx ;default prefix;;; alternate prefix display entry point...;dpycodaa jsr putcha ;print prefixjsr printspc ;spacejsr prntladr ;print long addressjsr printspc ;space to opcode fieldjsr getbyte ;get opcodesta opcode ;save &...jsr printbyt ;display as hex;;; decode menmonic & addressing info...;ldx opcode ;current mnemoniclda mnetabix,x ;get mnemonic indexasl ;double for...tay ;mnemonic table offsetlonga ;16 bit loadlda mnetab,y ;copy encoded mnemonic to...sta mnepck ;working storageshorta ;back to 8 bitsjsr instdata ;extract mode & size datasta vopsflag ;save mode flagssty admodidx ;save mode indexasl ;variable immediate instruction?bcc dpycod01 ;no, effective operand size in .X;;; determine immediate mode operand size...;lda opcode ;current opcodebit flimflag ;operand display modebpl .0000010 ;8 bit .A & BIT immediate mode;and #aimmaska ;determine if...cmp #aimmaskb ;.A or BIT immediatebeq .0000030 ;display 16 bit operand;lda opcode ;not .A or BIT immediate;.0000010 bvc dpycod01 ;8 bit .X/.Y immediate mode;ldy #n_vopidx-1 ;opcodes to test;.0000020 cmp vopidx,y ;looking for LDX #, CPY #, etc.beq .0000040 ;disassemble a 16 bit operand;deybpl .0000020 ;keep trying;bra dpycod01 ;not .X or .Y immediate;.0000030 lda opcode ;reload;.0000040 inx ;16 bit operand;;; get & display operand bytes...;dpycod01 stx iopsize ;operand size...inx ;plus opcode becomes...stx instsize ;instruction sizestx charcnt ;total bytes to processlda #n_opcols+2 ;total operand columns plus WSsta xrtemp ;initialize counterjsr clroper ;clear operandldy iopsize ;operand sizebeq .0000020 ;no operand;ldx #0 ;operand index;.0000010 jsr getbyte ;get operand bytesta operand,x ;savephx ;protect operand indexjsr printbyt ;print operand bytedec xrtemp ;3 columns used, 2 for...dec xrtemp ;operand nybbles &...dec xrtemp ;1 for whitespaceplx ;get operand indexinx ;bump itdeybne .0000010 ;next;.0000020 ldx xrtemp ;operand columns remainingjsr multspc ;space to mnemonic field;;; display mnemonic...;ldy #s_mnemon ;size of ASCII mnemonic;.0000030 lda #0 ;initialize charldx #n_shfenc ;shifts to execute;.0000040 asl mnepck ;shift encoded mnemonicrol mnepck+s_byteroldexbne .0000040;adc #a_mnecvt ;convert to ASCII &...pha ;stashdeybne .0000030 ;continue with mnemonic;ldy #s_mnemon;.0000050 pla ;get mnenmonic bytejsr putcha ;print itdeybne .0000050;;; display operand...;lda iopsize ;operand sizebeq clearlin ;zero, disassembly finished;jsr printspc ;space to operand fieldbit vopsflag ;check mode flagsbvc dpycod02 ;not a branch;jsr offtarg ;compute branch targetldx instsize ;effective instruction sizedexstx iopsize ;effective operand size;dpycod02 stz vopsflag ;clearlda admodidx ;instruction addressing modecmp #am_move ;block move instruction?bne .0000010 ;no;ror vopsflag ;yes;.0000010 asl ;convert addressing mode to...tax ;symbology table indexlonga ;do a 16 bit loadlda ms_lutab,x ;addressing symbol pointerphashorta ;back to 8 bit loadsldy #0ldasi 1 ;get 1st charcmp #a_blankbeq .0000020 ;no addresing mode preamble;jsr putcha ;print preamble;.0000020 lda #c_hexjsr putcha ;operand displayed as hexldy iopsize ;operand size = index;.0000030 deybmi .0000040 ;done with operand;lda operand,y ;get operand bytejsr dpyhex ;print operand bytebit vopsflag ;block move?bpl .0000030 ;no;stz vopsflag ;resetphy ;protect operand indexpea ms_movejsr sprint ;display MVN/MVP operand separatorply ;recover operand index againbra .0000030 ;continue;.0000040 plx ;symbology LSBply ;symbology MSBinx ;move past preamblebne .0000050;iny;.0000050 phyphxjsr sprint ;print postamble, if any;;; condition immediate mode display format...;dpycod03 lda operand ;operand LSBand #pfmxmask ;isolate M & X bitsasl ;shift to match...asl ;FLIMFLAG alignmentldx opcode ;current instructioncpx #opc_rep ;was it REP?bne .0000010 ;no;tsb flimflag ;set flag bits as requiredbra clearlin;.0000010 cpx #opc_sep ;was it SEP?bne clearlin ;no, just exit;trb flimflag ;clear flag bits as required;;================================================================================;;clearlin: CLEAR DISPLAY LINE;clearlin pea dc_clbra dpyerraa;;================================================================================;;dpyibuf: DISPLAY MONITOR INPUT BUFFER CONTENTS;dpyibuf pea ibufferbra dpyerraa;;================================================================================;;dpymem: DISPLAY MEMORY;; This function displays 16 bytes of memory as hex values & as; ASCII equivalents. The starting address for the display is; in ADDRA & is expected to be a 24 bit address. Upon return,; ADDRA will point to the start of the next 16 bytes.;dpymem shortrstz charcnt ;resetlda #memprfxjsr putcha ;display prefixjsr prntladr ;print 24 bit addressldx #0 ;string buffer indexldy #n_dump ;bytes per line;.0000010 jsr getbyte ;get from RAM, also...pha ;save for decodingphx ;save string indexjsr printbyt ;display as hex ASCIIinc charcnt ;bytes displayed +1plx ;recover string index &...pla ;bytecmp #a_blank ;printable?bcc .0000020 ;no;cmp #a_delbcc .0000030 ;is printable;.0000020 lda #memsubch ;substitute character;.0000030 sta ibuffer,x ;save charinx ;bump indexdey ;byte count -= 1bne .0000010 ;not done;stz ibuffer,x ;terminate ASCII stringlda #memsepchjsr putcha ;separate ASCII from bytespea dc_bfjsr sprint ;select reverse videojsr dpyibuf ;display ASCII equivalentspea dc_er ;normal videobra dpyerraa;;================================================================================;;dpyerr: DISPLAY ERROR SIGNAL;dpyerr pea mm_err ;"*ERR";dpyerraa jsr sprintrts;;================================================================================;;gendbs: GENERATE DESTRUCTIVE BACKSPACE;gendbs pea dc_bs ;destructive backspacebra dpyerraa;;================================================================================;;prntladr: PRINT 24 BIT CURRENT ADDRESS;prntladr php ;protect register sizesshortalda addra+s_word ;get bank byte &...jsr dpyhex ;display itlongalda addra ;get 16 bit addressplp ;restore register sizes;;================================================================================;;dpyhexw: DISPLAY BINARY WORD AS HEX ASCII;; Preparatory Ops: .C: word to display;; Returned Values: .C: used; .X: used; .Y: entry value;dpyhexw php ;save register sizeslongapha ;protect valueshortaxba ;get MSB &...jsr dpyhex ;displaylongapla ;recover valueshorta ;only LSB visibleplp ;reset register sizes;;================================================================================;;dpyhex: DISPLAY BINARY BYTE AS HEX ASCII;; Preparatory Ops: .A: byte to display;; Returned Values: .A: used; .X: used; .Y: entry value;dpyhex jsr binhex ;convert to hex ASCIIjsr putcha ;print MSNtxajmp putcha ;print LSN;;================================================================================;;multspc: PRINT MULTIPLE BLANKS;; Preparatory Ops : .X: number of blanks to print;; Register Returns: none;; Calling Example : ldx #3; jsr multspc ;print 3 spaces;; Notes: This sub will print 1 blank if .X=0.;multspc txabne .0000010 ;blank count specified;inx ;default to 1 blank;.0000010 lda #a_blank;.0000020 jsr putchadexbne .0000020;rts;;================================================================================;;newline: PRINT NEWLINE (CRLF);newline pea dc_lfbra dpyerraa;;================================================================================;;printbyt: PRINT A BYTE WITH LEADING SPACE;printbyt pha ;protect bytejsr printspc ;print leading spacepla ;restore &...bra dpyhex ;print byte;;================================================================================;;alert: ALERT USER w/TERMINAL BELL;alert lda #a_belbra printcmn;;================================================================================;;printspc: PRINT A SPACE;printspc lda #a_blank;printcmn jmp putcha;;================================================================================;;sprint: PRINT NULL-TERMINATED CHARACTER STRING;; Preparatory Ops : SP+1: string address LSB; SP+2: string address MSB;; Register Returns: .A: used; .B: entry value; .X: used; .Y: used;; MPU Flags: NVmxDIZC; ||||||||; ||||||| 1: string too long (1);; Example: PER STRING; JSR SPRINT; BCS TOOLONG;; Notes: 1) Maximum permissible string length including the; terminator is 32,767 bytes.; 2) All registers are forced to 8 bits.; 3) DO NOT JUMP OR BRANCH INTO THIS FUNCTION!;sprint shorta ;8 bit accumulatorlongx ;16 bit index;.reetaddr =1 ;return address.src =.reetaddr+s_word ;string address stack offset;ldyw 0clc ;no initial error;.0000010 ldasi .src ;get a bytebeq .0000020 ;done;jsr putcha ;write to console portinybpl .0000010 ;next;sec ;string too long;.0000020 plx ;pull RTS addressply ;clear string pointerphx ;replace RTSshortxrts;;================================================================================;;ascbin: CONVERT NULL-TERMINATED ASCII NUMBER STRING TO BINARY;; Preparatory Ops: ASCII number string in IBUFFER;; Returned Values: FACA: converted parameter; .A: used; .X: used; .Y: used; .C: 1 = conversion error; .Z: 1 = nothing to convert;; Notes: 1) Conversion stops when a non-numeric char-; acter is encountered.; 2) Radix symbols are as follows:;; % binary; @ octal; + decimal; $ hexadecimal;; Hex is the default if no radix is speci-; fied in the 1st character of the string.;ascbin shortrjsr clrfaca ;clear accumulatorstz charcnt ;zero char countstz radix ;initialize;;; process radix if present...;jsr getcharw ;get next non-WS charbne .0000010 ;got something;clc ;no more inputrts;.0000010 ldx #n_radix-1 ;number of radices;.0000020 cmp radxtab,x ;recognized radix?beq .0000030 ;yes;dexbpl .0000020 ;try next;dec ibufidx ;reposition to previous charinx ;not recognized, assume hex;.0000030 cmp #c_dec ;decimal radix?bne .0000040 ;not decimal;ror radix ;flag decimal conversion;.0000040 lda basetab,x ;number bases tablesta range ;set valid numeral rangelda bitsdtab,x ;get bits per digitsta bitsdig ;store;;; process numerals...;ascbin01 jsr getchar ;get next charbeq ascbin03 ;EOI;cmp #' ';cmp #',';cmp #a_ht;jsr nybtobin ;change to binarybcs ascbin04 ;not a recognized numeral;cmp range ;check rangebcs ascbin04 ;not valid for base;sta numeral ;save processed numeralinc charcnt ;bump numeral countbit radix ;working in base 10?bpl .0000030 ;no;;; compute N*2 for decimal conversion...;ldx #0 ;accumulator indexldy #s_pfac/2 ;iterationslongaclc;.0000020 lda faca,x ;Nrol ;N=N*2sta facb,xinxinxdeybne .0000020;;shorta;;; compute N*base for binary, octal or hex...; or N*8 for decimal...;.0000030 ldx bitsdig ;bits per digitlonga ;16 bit shifts;.0000040 asl facarol faca+s_word;dexbne .0000040 ;next shift;shorta ;back to 8 bitsbit radix ;check basebpl ascbin02 ;not decimal;;; compute N*10 for decimal (N*8 + N*2)...;ldy #s_pfaclonga;.0000050 lda faca,x ;N*8adc facb,x ;N*2sta faca,x ;now N*10inxinxdeybne .0000050;;shorta;;; add current numeral to partial result...;ascbin02 lda faca ;Nadc numeral ;N=N+Dsta facaldx #1ldy #s_pfac-1;.0000010 lda faca,xadc #0 ;account for carrysta faca,xinxdeybne .0000010;bcc ascbin01 ;next if no overflow;;;; finish up...;ascbin03 clc ;no error;ascbin04 shorta ;reset if necessarylda charcnt ;load char countrts ;done;;================================================================================;;bcdasc: CONVERT BCD DIGIT TO ASCII;; Preparatory Ops: .A: BCD digit, $00-$99;; Returned Values: .A: ASCII MSD; .X: ASCII LSD; .Y: entry value;bcdasc jsr bintonyb ;extract nybblespha ;save tenstxaora #btoamask ;change units to ASCIItax ;storepla ;get tensora #btoamask ;change to ASCIIrts;;================================================================================;;bintonyb: EXTRACT BINARY NYBBLES;; Preparatory Ops: .A: binary value;; Returned Values: .A: MSN; .X: LSN; .Y: entry value;bintonyb pha ;saveand #bcdumask ;extract LSNtax ;save itpla; .rept s_bnybbl ;extract MSNlsrlsrlsrlsr; .endrrts;;================================================================================;;binasc: CONVERT 32-BIT BINARY TO NULL-TERMINATED ASCII NUMBER STRING;; Preparatory Ops: FACA: 32-bit operand; .A: radix character, w/bit 7 set to; suppress radix symbol in the; conversion string;; Returned Values: ibuffer: conversion string; .A: string length; .X: string address LSB; .Y: string address MSB;; Execution Notes: ibufidx & instsize are overwritten.;binasc stz ibufidx ;initialize string indexstz instsize ;clear format flag;;; evaluate radix...;asl ;extract format flag &...ror instsize ;save itlsr ;extract radix characterldx #n_radix-1 ;total radices;.0000010 cmp radxtab,x ;recognized radix?beq .0000020 ;yes;dexbpl .0000010 ;try next;inx ;assume hex;.0000020 stx radix ;save radix index for laterbit instsizebmi .0000030 ;no radix symbol wanted;lda radxtab,x ;radix tablesta ibuffer ;prepend to stringinc ibufidx ;bump string index;.0000030 cmp #c_dec ;converting to decimal?bne .0000040 ;no;jsr facabcd ;convert operand to BCDlda #0bra .0000070 ;skip binary stuff;;; prepare for binary, octal or hex conversion...;.0000040 ldx #0 ;operand indexldy #s_sfac-1 ;workspace index;.0000050 lda faca,x ;copy operand to...sta facb,y ;workspace in...dey ;big-endian orderinxcpx #s_pfacbne .0000050;lda #0tyx;.0000060 sta facb,x ;pad workspacedexbpl .0000060;;; set up conversion parameters...;.0000070 sta facc ;initialize byte counterldy radix ;radix indexlda numstab,y ;numerals in stringsta facc+s_byte ;set remaining numeral countlda bitsntab,y ;bits per numeralsta facc+s_word ;setlda lzsttab,y ;leading zero thresholdsta facc+s_xword ;set;;; generate conversion string...;.0000080 lda #0ldy facc+s_word ;bits per numeral;.0000090 ldx #s_sfac-1 ;workspace sizeclc ;avoid starting carry;.0000100 rol facb,x ;shift out a bit...dex ;from the operand or...bpl .0000100 ;BCD conversion result;rol ;bit to .Adeybne .0000090 ;more bits to grab;tay ;if numeral isn't zero...bne .0000110 ;skip leading zero tests;ldx facc+s_byte ;remaining numeralscpx facc+s_xword ;leading zero thresholdbcc .0000110 ;below it, must convert;ldx facc ;processed byte countbeq .0000130 ;discard leading zero;.0000110 cmp #10 ;check rangebcc .0000120 ;is 0-9;adc #a_hexdec ;apply hex adjust;.0000120 adc #'0' ;change to ASCIIldy ibufidx ;string indexsta ibuffer,y ;save numeral in bufferinc ibufidx ;next buffer positioninc facc ;bytes=bytes+1;.0000130 dec facc+s_byte ;numerals=numerals-1bne .0000080 ;not done;;; terminate string & exit...;ldx ibufidx ;printable string lengthstz ibuffer,x ;terminate stringtxaldx #<ibuffer ;converted stringldy #>ibufferclc ;all okayrts;;================================================================================;;binhex: CONVERT BINARY BYTE TO HEX ASCII CHARS;; Preparatory Ops: .A: byte to convert;; Returned Values: .A: MSN ASCII char; .X: LSN ASCII char; .Y: entry value;binhex jsr bintonyb ;generate binary valuespha ;save MSNtxajsr .0000010 ;generate ASCII LSNtax ;savepla ;get input;;; convert nybble to hex ASCII equivalent...;.0000010 cmp #10bcc .0000020 ;in decimal range;adc #k_hex ;hex compensate;.0000020 eor #'0' ;finalize nybblerts ;done;;================================================================================;;clrfaca: CLEAR FLOATING ACCUMULATOR A;clrfaca phplongastz facastz faca+s_wordplprts;;================================================================================;;clrfacb: CLEAR FLOATING ACCUMULATOR B;clrfacb phplongastz facbstz facb+s_wordplprts;;================================================================================;;facabcd: CONVERT FACA INTO BCD;facabcd ldx #s_pfac-1 ;primary accumulator size -1;.0000010 lda faca,x ;value to be convertedpha ;preservedexbpl .0000010 ;next;ldx #s_sfac-1 ;workspace size;.0000020 stz facb,x ;clear final resultstz facc,x ;clear scratchpaddexbpl .0000020;inc facc+s_sfac-s_bytesed ;select decimal modeldy #m_bits-1 ;bits to convert -1;.0000030 ldx #s_pfac-1 ;operand sizeclc ;no carry at start;.0000040 ror faca,x ;grab LS bit in operanddexbpl .0000040;bcc .0000060 ;LS bit clear;clcldx #s_sfac-1;.0000050 lda facb,x ;partial resultadc facc,x ;scratchpadsta facb,x ;new partial resultdexbpl .0000050;clc;.0000060 ldx #s_sfac-1;.0000070 lda facc,x ;scratchpadadc facc,x ;double &...sta facc,x ;savedexbpl .0000070;deybpl .0000030 ;next operand bit;cldldx #0ldy #s_pfac;.0000080 pla ;operandsta faca,x ;restoreinxdeybne .0000080 ;next;rts;;================================================================================;;nybtobin: CONVERT ASCII NYBBLE TO BINARY;nybtobin jsr toupper ;convert case if necessarysecsbc #'0' ;change to binary;cmp #10bcc .0000010 ;numeral is 0-9;clc ;no conversion error;.0000010 rts;.0000020 sec ;conversion errorrts;;================================================================================;;calccnt: COMPUTE BYTE COUNT FROM ADDRESS RANGE;calccnt jsr clrfacb ;clear accumulatorlongaseclda addrb ;ending addresssbc addra ;starting addresssta facb ;byte countshortalda addrb+s_word ;handle bankssbc addra+s_wordsta facb+s_wordrts;;================================================================================;;clroper: CLEAR OPERAND;clroper phxldx #s_oper-1;.0000010 stz operand,xdexbpl .0000010;stz eopsizeplxrts;;================================================================================;;cpfwsup: FOWARD COPY MEMORY SETUP;cpfwsup longrldxw opc_mvn ;"move next" opcodebra cpsup;;================================================================================;;cprvsup: REVERSE COPY MEMORY SETUP;cprvsup longrldxw opc_mvp ;"move previous" opcode;;================================================================================;;cpsup: COPY MEMORY SETUP;cpsup pha ;save bankstxa ;protect...xba ;opcodeshortaldxw (cpcodeee-cpcode-1);.0000010 ldalx cpcode ;transfer copy code to...sta mcftwork,x ;to workspacedexbpl .0000010;xba ;recover opcode &...sta mcftopc ;set itlongapla ;get banks &...sta mcftbnk ;set them;-------------------------------------------------------------------------------; We just dynamically created a routine, so the cache (if one is present) has; to be invalidated. Otherwise the processor could execute dead code from the; cache. Two lines are invalidated in case the code crosses a line boundary.;; Parameters to ICacheIL816:; acc = 16 bit address to invalidate;; The ICacheIL816 routine should invalidate the cache line and return. If there; is no cache in the processor then these lines can be deleted.;-------------------------------------------------------------------------------phalda #mcftworkjsr ICacheIL816lda #mcftwork+8jsr ICacheIL816pla;---------------------------------------------rts;;================================================================================;;cpcode: COPY MEMORY CODE;; This code is transfered to workspace when a; copy or fill operation is to be performed.;cpcode phb ;must preserve data bank; .rept s_mvinstnop ;placeholdernopnop; .endrplb ;restore data bankjml monce ;return to command executive;;================================================================================;;decdcnt: DECREMENT DUMP COUNT;; Preparatory Ops: bytes to process in FACB; bytes processed in CHARCNT;; Returned Values: .A: used; .X: entry value; .Y: entry value; .C: 1 = count = zero;decdcnt shortalda #0xba ;clear .Blda facb+s_word ;count MSWlongasecora facb ;count LSWbeq .0000020 ;zero, just exit;lda facbsbc charcnt ;bytes processedsta facbshortalda facb+s_wordsbc #0 ;handle borrowbcc .0000010 ;underflow;sta facb+s_wordclc ;count > 0rts;.0000010 sec;.0000020 shortarts;;================================================================================;;enddest: GET 2ND & 3RD ADDRESSES FOR COMPARE & TRANSFER;enddest jsr facasize ;check start...cmp #s_dword ;for range;jsr facaddra ;store startjsr getparm ;get end;jsr facasize ;check end...cmp #s_dword ;for range;jsr facaddrb ;store endjsr getparm ;get destination;jsr facasize ;check destination...cmp #s_dword ;for rangebcc facaoper ;store dest address;.0000010 rts ;exit w/error;;================================================================================;;facaddra: COPY FACA TO ADDRA;facaddra ldx #s_xword-1;.0000010 lda faca,xsta addra,xdexbpl .0000010;rts;;================================================================================;;facaddrb: COPY FACA TO ADDRB;facaddrb ldx #s_xword-1;.0000010 lda faca,xsta addrb,xdexbpl .0000010;rts;;================================================================================;;facaoper: COPY FACA TO OPERAND;facaoper ldx #s_oper-1;.0000010 lda faca,xsta operand,xdexbpl .0000010;rts;;================================================================================;;facasize: REPORT OPERAND SIZE IN FACA;; Preparatory Ops: operand in FACA;; Returned Values: .A: s_byte (1); s_word (2); s_xword (3); s_dword (4);; Notes: 1) This function will always report; a non-zero result.;facasize shortrldx #s_dword-1;.0000010 lda faca,x ;get bytebne .0000020 ;done;dexbne .0000010 ;next byte;.0000020 inx ;count=index+1txarts;;================================================================================;;getbyte: GET A BYTE FROM MEMORY;getbyte ldail addra ;get a bytebra incaddra ;bump address;;================================================================================;;getparm: GET A PARAMETER;; Preparatory Ops: null-terminated input in IBUFFER;; Returned Values: .A: chars in converted parameter; .X: used; .Y: entry value; .C: 1 = no parameter entered;getparmr dec ibufidx ;reread previous char;getparm phy ;preservejsr ascbin ;convert parameter to binarybcs .0000040 ;conversion error;jsr getcharr ;reread last charbne .0000010 ;not end-of-input;dec ibufidx ;reindex to terminatorlda charcnt ;get chars processed so farbeq .0000030 ;none;bne .0000020 ;some;.0000010 cmp #a_blank ;recognized delimiterbeq .0000020 ;end of parameter;cmp #',' ;recognized delimiterbne .0000040 ;unknown delimter;.0000020 clc.byte bitzp ;skip SEC below;.0000030 secply ;restorelda charcnt ;get countrts ;done;.0000040;.rept 3 ;clean up stackplaplapla; .endrjmp monerr ;abort w/error;;================================================================================;;nxtaddra: TEST & INCREMENT WORKING ADDRESS 'A';; Calling syntax: JSR NXTADDRA;; Exit registers: .A: used; .B: used; .X: entry value; .Y: entry value; DB: entry value; DP: entry value; PB: entry value; SR: NVmxDIZC; ||||||||; ||||||| 1: ADDRA >= ADDRB;nxtaddra shortalda addra+s_word ;bits 16-23cmp addrb+s_wordbcc incaddra ;increment;bne .0000010 ;don't increment;longalda addra ;bits 0-15cmp addrb ;condition flagsshortabcc incaddra ;increment;.0000010 rts;;================================================================================;;incaddra: INCREMENT WORKING ADDRESS 'A';; Calling syntax: JSR INCADDRA;; Exit registers: .A: entry value; .B: entry value; .X: entry value; .Y: entry value; DB: entry value; DP: entry value; PB: entry value; SR: NVmxDIZC; ||||||||;incaddra phplongainc addra ;bump bits 0-15bne .0000010;shortainc addra+s_word ;bump bits 16-23;.0000010 plprts;;================================================================================;;incoper: INCREMENT OPERAND ADDRESS;incoper clcphplongrphainc operand ;handle base addressbne .0000010;shortainc operand+s_word ;handle banklonga;.0000010 plaplprts;;================================================================================;;instdata: GET INSTRUCTION SIZE & ADDRESSING MODE DATA;; Preparatory Ops: .X: 65C816 opcode;; Returned Values: .A: mode flags; .X: operand size; .Y: mode index;instdata shortrlda mnetabam,x ;addressing mode datapha ;save mode flag bitspha ;save size dataand #amodmask ;extract mode index &...tay ;savepla ;recover dataand #opsmask ;mask mode fields &...; .rept n_opslsr ;extract operand sizelsrlsrlsrlsr; .endrtax ;operand sizepla ;recover mode flagsand #vopsmask ;discard mode & size fieldsrts;;================================================================================;;offtarg: CONVERT BRANCH OFFSET TO TARGET ADDRESS;; Preparatory Ops: ADDRA: base address; INSTSIZE: instruction size; OPERAND: offset;; Returned Values: OPERAND: target address (L/H); .A: used; .X: entry value; .Y: entry value;offtarg longalda addra ;base addressshortalsr instsize ;bit 0 will be set if...bcs .0000010 ;a long branch;bit operand ;short forward or backward?bpl .0000010 ;forward;xba ;expose address MSBdea ;back a pagexba ;expose address LSB;.0000010 longaclcadc operand ;calculate target addresssta operand ;new operandshortalda #s_xwordsta instsize ;effective instruction sizerts;;================================================================================;;setxaddr: SET EXECUTION ADDRESS;setxaddr bcs .0000010 ;no address given;jsr facasize ;check address...cmp #s_dword ;rangebcs .0000020 ;out of range;longalda faca ;execution addresssta reg_pcx ;set new PC valueshortalda faca+s_wordsta reg_pbx ;set new PB value;.0000010 clc ;no error;.0000020 rts;;================================================================================;;targoff: CONVERT BRANCH TARGET ADDRESS TO BRANCH OFFSET;; Preparatory Ops: ADDRA: instruction address; OPERAND: target address;; Returned Values: OPERAND: computed offset; .A: effective operand size; .X: entry value; .Y: entry value; .C: 1 = branch out of range;; Execution notes: ADDRB is set to the branch base; address.;targoff stz instsize+s_byte ;always zerolda instsize ;instruction size will tell...lsr ;if long or short branch;.btype =facc+5 ;branch type flag;ror .btype ;set branch type...;; x0000000; |; 1: long;longaclclda addra ;instruction addressadc instsize ;instruction sizesta addrb ;base addressseclda operand ;target addresssbc addrb ;base addresssta operand ;offsetshortabcc .0000040 ;backward branch;bit .btype ;check branch rangebmi .0000020 ;long;;; process short forward branch...;xba ;offset MSB should be zero;xba ;offset LSB should be $00-$7F;.0000010 lda #s_byte ;final instruction sizeclc ;branch in rangerts;;; process long forward branch...;.0000020 xba ;offset MSB should be positive;.0000030 lda #s_wordclcrts;;; process backward branch...;.0000040 bit .btype ;long or short?bmi .0000050 ;long;;; process short backward branch...;xba ;offset MSB should be negative;eor #@11111111 ;complement offset MSB 2sbne .0000060 ;out of range;xba ;offset LSB should be $80-$FF;bra .0000060 ;branch out of range;;; process long backward branch...;.0000050 xba ;offset MSB should be negative;.0000060 sec ;range errorrts;;================================================================================;;getcharr: GET PREVIOUS INPUT BUFFER CHARACTER;getcharr dec ibufidx ;move back a char;;================================================================================;;getchar: GET A CHARACTER FROM INPUT BUFFER;; Preparatory Ops : none;; Register Returns: .A: character or <NUL>; .B: entry value; .X: entry value; .Y: entry value;; MPU Flags: NVmxDIZC; ||||||||;getchar phxphyphp ;save register sizesshortr ;force 8 bitsldx ibufidx ;buffer indexlda ibuffer,x ;get charinc ibufidx ;bump indexplp ;restore register widthsplyplx; Changed the following to XBA instruction which seems to work as well.; XBA doesn't access the stack memory saving a data memory access,; and hence is faster.xba ; pha ;condition...xba ; pla ;.Zrts;;================================================================================;;getpat: GET PATTERN FOR MEMORY CHANGE or SEARCH;; Preparatory Ops: Null-terminated pattern in IBUFFER.;; Returned Values: .A: used; .X: used; .Y: pattern length if entered; .C: 0 = pattern valid; 1 = exception:; .N 0 = no pattern entered; 1 = evaluation error;; Notes: 1) If pattern is preceded by "'" the following; characters are interpreted as ASCII.; 2) A maximum of 32 bytes or characters is; accepted. Excess input will be discarded.;getpat stz status ;clear pattern type indicatorldy #0 ;pattern indexjsr getcharr ;get last charbeq .0000070 ;EOS;ldx ibufidx ;current buffer indexjsr getcharw ;get nextbeq .0000070 ;EOS;cmp #'''bne .0000010 ;not ASCII input;ror status ;condition flagbra .0000030 ;balance of input is ASCII;.0000010 stx ibufidx ;restore buffer index;.0000020 jsr getparm ;evaluate numeric patternbcs .0000060 ;done w/pattern;jsr facasize ;sizecmp #s_word;lda faca ;get byte &...bra .0000040 ;store;.0000030 jsr getchar ;get ASCII charbeq .0000060 ;done w/pattern;.0000040 cpy #s_auxbuf ;pattern buffer full?beq .0000050 ;yes;sta auxbuf,y ;store patterninybit statusbpl .0000020 ;get next numeric value;bra .0000030 ;get next ASCII char;.0000050 jsr alert ;excess input;.0000060 sty auxbufix ;save pattern sizetya ;condition .Zclc ;pattern validrts;;; no pattern entered...;.0000070 rep @10000000secrts;;; evaluation error...;.0000080 sep @10000001rts;;================================================================================;;getcharw: GET FROM INPUT BUFFER, DISCARDING WHITESPACE;; Preparatory Ops: Null-terminated input in IBUFFER.;; Returned Values: .A: char or null; .X: entry value; .Y: entry value; .Z: 1 = null terminator detected;; Notes: Whitespace is defined as a blank ($20) or a; horizontal tab ($09).;getcharw jsr getchar ;get from bufferbeq .0000010 ;EOI;cmp #' 'beq getcharw ;discard whitespace;cmp #a_ht ;also whitespacebeq getcharw;.0000010 clcrts;;================================================================================;;input: INTERACTIVE INPUT FROM CONSOLE CHANNEL;; Preparatory Ops: Zero IBUFIDX or load IBUFFER with default; input & set IBUFIDX to the number of chars; loaded into the buffer.;; Returned Values: .A: used; .X: characters entered; .Y: used;; Example: STZ IBUFIDX; JSR INPUT;; Notes: Input is collected in IBUFFER & is null-terminated.; IBUFIDX is reset to zero upon exit.;input:ldx ibufidxstz ibuffer,x ;be sure buffer is terminatedjsr dpyibuf ;print default input if anypea dc_cnjsr sprint ;enable cursorldx ibufidx ;starting buffer index;;; main input loop...;.0000010 jsr getcha ;poll for inputbcc .0000020 ;got something;jsr $F409 ;wait 'til any IRQ &... (Reschedule tasks)bra .0000010 ;try again;.0000020 cmp #a_del ;above ASCII range?bcs .0000010 ;yes, ignore;cmp #a_ht ;horizontal tab?bne .0000030 ;no;lda #a_blank ;replace <HT> w/blank;.0000030 cmp #a_blank ;control char?bcc .0000050 ;yes;;; process QWERTY character...;cpx #s_ibuf ;room in buffer?bcs .0000040 ;no;sta ibuffer,x ;store charinx ;bump index.byte bitabs ;echo char;.0000040 lda #a_bel ;alert userjsr putchabra .0000010 ;get some more;;; process carriage return...;.0000050 cmp #a_cr ;carriage return?bne .0000060 ;no;phx ;protect input countpea dc_cojsr sprint ;cursor offplx ;recover input countstz ibuffer,x ;terminate input &...stz ibufidx ;reset buffer indexrts ;done;;; process backspace...;.0000060 cmp #a_bs ;backspace?bne .0000010 ;no;txabeq .0000010 ;no input, ignore <BS>;dex ;1 less charphx ;preserve countjsr gendbs ;destructive backspaceplx ;restore countbra .0000010 ;get more input;;================================================================================;;lodbnk: LOAD SOURCE & DESTINATION BANKS;lodbnk shortalda operand+s_word ;destination bankxba ;make it MSBlda addra+s_word ;source bank is LSBrts;;================================================================================;;getcharc: GET A CHARACTER FROM INPUT BUFFER & CONVERT CASE;; Preparatory Ops: Null-terminated input in IBUFFER.;; Returned Values: .A: char or null; .X: entry value; .Y: entry value; .Z: 1 = null terminator detected;getcharc jsr getchar ;get from bufferbeq touppera ;just return;;================================================================================;;toupper: FORCE CHARACTER TO UPPER CASE;; Preparatory Ops : .A: character to convert;; Register Returns: .A: converted character; .B: entry value; .X: entry value; .Y: entry value;; MPU Flags: no change;; Notes: 1) This subroutine has no effect on char-; acters that are not alpha.;toupper php ;protect flagscmp #a_asclcl ;check char rangebcc .0000010 ;not LC alpha;cmp #a_asclch+s_bytebcs .0000010 ;not LC alpha;and #a_lctouc ;force to UC;.0000010 plp ;restore flags;touppera rts;;================================================================================;;teststop: TEST FOR STOP KEY;; Preparatory Ops: none;; Returned Values: .A: detected keypress, if any; .X: entry value; .Y: entry value;; MPU Flags: NVmxDIZC; ||||||||; ||||||| 1: <STOP> detected;; Example: jsr teststop; bcs stopped;; Notes: The symbol STOPKEY defines the ASCII; value of the "stop key.";teststop jsr getcha ;poll consolebcs .0000010 ;no input;cmp #stopkey ;stop key pressed?beq .0000020 ;yes;.0000010 clc;.0000020 rts;;================================================================================;;COMMAND PROCESSING DATA TABLES;;; monitor commands...;mpctab .byte "A" ;assemble code.byte "C" ;compare memory ranges.byte "D" ;disassemble code.byte "F" ;fill memory.byte "G" ;execute code.byte "H" ;search memory.byte "J" ;execute code as subroutine.byte "M" ;dump memory range.byte "R" ;dump registers.byte "T" ;copy memory range.byte "X" ;exit from monitor.byte ">" ;change memory.byte ";" ;change registersn_mpctab =*-mpctab ;entries in above table;;; monitor command jump table...;mpcextab .word monasc-s_byte ; A assemble code.word moncmp-s_byte ; C compare memory ranges.word mondsc-s_byte ; D disassemble code.word monfil-s_byte ; F fill memory.word monjmp-s_byte ; G execute code.word monhnt-s_byte ; H search memory.word monjsr-s_byte ; J execute code as subroutine.word mondmp-s_byte ; M dump memory range.word monreg-s_byte ; R dump registers.word moncpy-s_byte ; T copy memory range.word monxit-s_byte ; X exit from monitor.word monchm-s_byte ; > change memory.word monchr-s_byte ; ; change registers;;; number conversion...;basetab .byte 16,10,8,2 ;supported number basesbitsdtab .byte 4,3,3,1 ;bits per binary digitbitsntab .byte 4,4,3,1 ;bits per ASCII characterlzsttab .byte 3,2,9,2 ;leading zero suppression thresholdsnumstab .byte 12,12,16,48 ;bin to ASCII conversion numeralsradxtab .byte c_hex ;hexadecimal radix.byte c_dec ;decimal radix.byte c_oct ;octal radix.byte c_bin ;binary radixn_radix =*-radxtab ;number of recognized radices;;; shadow MPU register sizes...;rcvltab .byte s_mpupbx+s_byte ; PB.byte s_mpupcx+s_byte ; PC.byte s_mpusrx+s_byte ; SR.byte s_word+s_byte ; .C.byte s_word+s_byte ; .X.byte s_word+s_byte ; .Y.byte s_mpuspx+s_byte ; SP.byte s_mpudpx+s_byte ; DP.byte s_mpudbx+s_byte ; DBn_regchv =*-rcvltab ;total shadow registers;;================================================================================;;ASSEMBLER/DISASSEMBLER DATA TABLES;;; numerically sorted & encoded W65C816S mnemonics...;;s_mnetab =*-mnetab ;mnemonic table sizen_mnemon =s_mnetab/s_word ;total mnemonics;;; mnemonic lookup indices in opcode order...;mnetabix .byte mne_brkx ; $00 BRK.byte mne_orax ; $01 ORA (dp,X).byte mne_copx ; $02 COP.byte mne_orax ; $03 ORA offset,S.byte mne_tsbx ; $04 TSB dp.byte mne_orax ; $05 ORA dp.byte mne_aslx ; $06 ASL dp.byte mne_orax ; $07 ORA [dp].byte mne_phpx ; $08 PHP.byte mne_orax ; $09 ORA #.byte mne_aslx ; $0A ASL A.byte mne_phdx ; $0B PHD.byte mne_tsbx ; $0C TSB abs.byte mne_orax ; $0D ORA abs.byte mne_aslx ; $0E ASL abs.byte mne_orax ; $0F ORA absl;.byte mne_bplx ; $10 BPL abs.byte mne_orax ; $11 ORA (dp),Y.byte mne_orax ; $12 ORA (dp).byte mne_orax ; $13 ORA (offset,S),Y.byte mne_trbx ; $14 TRB dp.byte mne_orax ; $15 ORA dp,X.byte mne_aslx ; $16 ASL dp,X.byte mne_orax ; $17 ORA [dp],Y.byte mne_clcx ; $18 CLC.byte mne_orax ; $19 ORA abs.byte mne_incx ; $1A INC A.byte mne_tcsx ; $1B TCS.byte mne_trbx ; $1C TRB abs.byte mne_orax ; $1D ORA abs,X.byte mne_aslx ; $1E ASL abs,X.byte mne_orax ; $1F ORA absl,X;.byte mne_jsrx ; $20 JSR abs.byte mne_andx ; $21 AND (dp,X).byte mne_jslx ; $22 JSL absl.byte mne_andx ; $23 AND offset,S.byte mne_bitx ; $24 BIT dp.byte mne_andx ; $25 AND dp.byte mne_rolx ; $26 ROL dp.byte mne_andx ; $27 AND [dp].byte mne_plpx ; $28 PLP.byte mne_andx ; $29 AND #.byte mne_rolx ; $2A ROL A.byte mne_pldx ; $2B PLD.byte mne_bitx ; $2C BIT abs.byte mne_andx ; $2D AND abs.byte mne_rolx ; $2E ROL abs.byte mne_andx ; $2F AND absl;.byte mne_bmix ; $30 BMI abs.byte mne_andx ; $31 AND (dp),Y.byte mne_andx ; $32 AND (dp).byte mne_andx ; $33 AND (offset,S),Y.byte mne_bitx ; $34 BIT dp,X.byte mne_andx ; $35 AND dp,X.byte mne_rolx ; $36 ROL dp,X.byte mne_andx ; $37 AND [dp],Y.byte mne_secx ; $38 SEC.byte mne_andx ; $39 AND abs,Y.byte mne_decx ; $3A DEC A.byte mne_tscx ; $3B TSC.byte mne_bitx ; $3C BIT abs,X.byte mne_andx ; $3D AND abs,X.byte mne_rolx ; $3E ROL abs,X.byte mne_andx ; $3F AND absl,X;.byte mne_rtix ; $40 RTI.byte mne_eorx ; $41 EOR (dp,X).byte mne_wdmx ; $42 WDM.byte mne_eorx ; $43 EOR offset,S.byte mne_mvpx ; $44 MVP sb,db.byte mne_eorx ; $45 EOR dp.byte mne_lsrx ; $46 LSR dp.byte mne_eorx ; $47 EOR [dp].byte mne_phax ; $48 PHA.byte mne_eorx ; $49 EOR #.byte mne_lsrx ; $4A LSR A.byte mne_phkx ; $4B PHK.byte mne_jmpx ; $4C JMP abs.byte mne_eorx ; $4D EOR abs.byte mne_lsrx ; $4E LSR abs.byte mne_eorx ; $4F EOR absl;.byte mne_bvcx ; $50 BVC abs.byte mne_eorx ; $51 EOR (dp),Y.byte mne_eorx ; $52 EOR (dp).byte mne_eorx ; $53 EOR (offset,S),Y.byte mne_mvnx ; $54 MVN sb,db.byte mne_eorx ; $55 EOR dp,X.byte mne_lsrx ; $56 LSR dp,X.byte mne_eorx ; $57 EOR [dp],Y.byte mne_clix ; $58 CLI.byte mne_eorx ; $59 EOR abs,Y.byte mne_phyx ; $5A PHY.byte mne_tcdx ; $5B TCD.byte mne_jmlx ; $5C JML absl.byte mne_eorx ; $5D EOR abs,X.byte mne_lsrx ; $5E LSR abs,X.byte mne_eorx ; $5F EOR absl,X;.byte mne_rtsx ; $60 RTS.byte mne_adcx ; $61 ADC (dp,X).byte mne_perx ; $62 PER.byte mne_adcx ; $63 ADC offset,S.byte mne_stzx ; $64 STZ dp.byte mne_adcx ; $65 ADC dp.byte mne_rorx ; $66 ROR dp.byte mne_adcx ; $67 ADC [dp].byte mne_plax ; $68 PLA.byte mne_adcx ; $69 ADC #.byte mne_rorx ; $6A ROR A.byte mne_rtlx ; $6B RTL.byte mne_jmpx ; $6C JMP (abs).byte mne_adcx ; $6D ADC abs.byte mne_rorx ; $6E ROR abs.byte mne_adcx ; $6F ADC absl;.byte mne_bvsx ; $70 BVS abs.byte mne_adcx ; $71 ADC (dp),Y.byte mne_adcx ; $72 ADC (dp).byte mne_adcx ; $73 ADC (offset,S),Y.byte mne_stzx ; $74 STZ dp,X.byte mne_adcx ; $75 ADC dp,X.byte mne_rorx ; $76 ROR dp,X.byte mne_adcx ; $77 ADC [dp],Y.byte mne_seix ; $78 SEI.byte mne_adcx ; $79 ADC abs,Y.byte mne_plyx ; $7A PLY.byte mne_tdcx ; $7B TDC.byte mne_jmpx ; $7C JMP (abs,X).byte mne_adcx ; $7D ADC abs,X.byte mne_rorx ; $7E ROR abs,X.byte mne_adcx ; $7F ADC absl,X;.byte mne_brax ; $80 BRA abs.byte mne_stax ; $81 STA (dp,X).byte mne_brlx ; $82 BRL abs.byte mne_stax ; $83 STA offset,S.byte mne_styx ; $84 STY dp.byte mne_stax ; $85 STA dp.byte mne_stxx ; $86 STX dp.byte mne_stax ; $87 STA [dp].byte mne_deyx ; $88 DEY.byte mne_bitx ; $89 BIT #.byte mne_txax ; $8A TXA.byte mne_phbx ; $8B PHB.byte mne_styx ; $8C STY abs.byte mne_stax ; $8D STA abs.byte mne_stxx ; $8E STX abs.byte mne_stax ; $8F STA absl;.byte mne_bccx ; $90 BCC abs.byte mne_stax ; $91 STA (dp),Y.byte mne_stax ; $92 STA (dp).byte mne_stax ; $93 STA (offset,S),Y.byte mne_styx ; $94 STY dp,X.byte mne_stax ; $95 STA dp,X.byte mne_stxx ; $96 STX dp,Y.byte mne_stax ; $97 STA [dp],Y.byte mne_tyax ; $98 TYA.byte mne_stax ; $99 STA abs,Y.byte mne_txsx ; $9A TXS.byte mne_txyx ; $9B TXY.byte mne_stzx ; $9C STZ abs.byte mne_stax ; $9D STA abs,X.byte mne_stzx ; $9E STZ abs,X.byte mne_stax ; $9F STA absl,X;.byte mne_ldyx ; $A0 LDY #.byte mne_ldax ; $A1 LDA (dp,X).byte mne_ldxx ; $A2 LDX #.byte mne_ldax ; $A3 LDA offset,S.byte mne_ldyx ; $A4 LDY dp.byte mne_ldax ; $A5 LDA dp.byte mne_ldxx ; $A6 LDX dp.byte mne_ldax ; $A7 LDA [dp].byte mne_tayx ; $A8 TAY.byte mne_ldax ; $A9 LDA #.byte mne_taxx ; $AA TAX.byte mne_plbx ; $AB PLB.byte mne_ldyx ; $AC LDY abs.byte mne_ldax ; $AD LDA abs.byte mne_ldxx ; $AE LDX abs.byte mne_ldax ; $AF LDA absl;.byte mne_bcsx ; $B0 BCS abs.byte mne_ldax ; $B1 LDA (dp),Y.byte mne_ldax ; $B2 LDA (dp).byte mne_ldax ; $B3 LDA (offset,S),Y.byte mne_ldyx ; $B4 LDY dp,X.byte mne_ldax ; $B5 LDA dp,X.byte mne_ldxx ; $B6 LDX dp,Y.byte mne_ldax ; $B7 LDA [dp],Y.byte mne_clvx ; $B8 CLV.byte mne_ldax ; $B9 LDA abs,Y.byte mne_tsxx ; $BA TSX.byte mne_tyxx ; $BB TYX.byte mne_ldyx ; $BC LDY abs,X.byte mne_ldax ; $BD LDA abs,X.byte mne_ldxx ; $BE LDX abs,Y.byte mne_ldax ; $BF LDA absl,X;.byte mne_cpyx ; $C0 CPY #.byte mne_cmpx ; $C1 CMP (dp,X).byte mne_repx ; $C2 REP #.byte mne_cmpx ; $C3 CMP offset,S.byte mne_cpyx ; $C4 CPY dp.byte mne_cmpx ; $C5 CMP dp.byte mne_decx ; $C6 DEC dp.byte mne_cmpx ; $C7 CMP [dp].byte mne_inyx ; $C8 INY.byte mne_cmpx ; $C9 CMP #.byte mne_dexx ; $CA DEX.byte mne_waix ; $CB WAI.byte mne_cpyx ; $CC CPY abs.byte mne_cmpx ; $CD CMP abs.byte mne_decx ; $CE DEC abs.byte mne_cmpx ; $CF CMP absl;.byte mne_bnex ; $D0 BNE abs.byte mne_cmpx ; $D1 CMP (dp),Y.byte mne_cmpx ; $D2 CMP (dp).byte mne_cmpx ; $D3 CMP (offset,S),Y.byte mne_peix ; $D4 PEI dp.byte mne_cmpx ; $D5 CMP dp,X.byte mne_decx ; $D6 DEC dp,X.byte mne_cmpx ; $D7 CMP [dp],Y.byte mne_cldx ; $D8 CLD.byte mne_cmpx ; $D9 CMP abs,Y.byte mne_phxx ; $DA PHX.byte mne_stpx ; $DB STP.byte mne_jmpx ; $DC JMP [abs].byte mne_cmpx ; $DD CMP abs,X.byte mne_decx ; $DE DEC abs,X.byte mne_cmpx ; $DF CMP absl,X;.byte mne_cpxx ; $E0 CPX #.byte mne_sbcx ; $E1 SBC (dp,X).byte mne_sepx ; $E2 SEP #.byte mne_sbcx ; $E3 SBC offset,S.byte mne_cpxx ; $E4 CPX dp.byte mne_sbcx ; $E5 SBC dp.byte mne_incx ; $E6 INC dp.byte mne_sbcx ; $E7 SBC [dp].byte mne_inxx ; $E8 INX.byte mne_sbcx ; $E9 SBC #.byte mne_nopx ; $EA NOP.byte mne_xbax ; $EB XBA.byte mne_cpxx ; $EC CPX abs.byte mne_sbcx ; $ED SBC abs.byte mne_incx ; $EE INC abs.byte mne_sbcx ; $EF SBC absl;.byte mne_beqx ; $F0 BEQ abs.byte mne_sbcx ; $F1 SBC (dp),Y.byte mne_sbcx ; $F2 SBC (dp).byte mne_sbcx ; $F3 SBC (offset,S),Y.byte mne_peax ; $F4 PEA #.byte mne_sbcx ; $F5 SBC dp,X.byte mne_incx ; $F6 INC dp,X.byte mne_sbcx ; $F7 SBC [dp],Y.byte mne_sedx ; $F8 SED.byte mne_sbcx ; $F9 SBC abs,Y.byte mne_plxx ; $FA PLX.byte mne_xcex ; $FB XCE.byte mne_jsrx ; $FC JSR (abs,X).byte mne_sbcx ; $FD SBC abs,X.byte mne_incx ; $FE INC abs,X.byte mne_sbcx ; $FF SBC absl,X;;; instruction addressing modes & sizes in opcode order...;; xxxxxxxx; ||||||||; |||| 0000 dp, abs, absl, implied or A; |||| 0001 #; |||| 0010 dp,X, abs,X or absl,X; |||| 0011 dp,Y or abs,Y; |||| 0100 (dp) or (abs); |||| 0101 [dp] or [abs]; |||| 0110 [dp],Y; |||| 0111 (dp,X) or (abs,X); |||| 1000 (dp),Y; |||| 1001 offset,S; |||| 1010 (offset,S),Y; |||| 1011 sbnk,dbnk (MVN or MVP); |||| # = immediate; |||| A = accumulator; |||| abs = absolute; |||| absl = absolute long; |||| dbnk = destination bank; |||| dp = direct (zero) page; |||| S = stack relative; |||| sbnk = source bank; ||||;; Variable operand size refers to an immediate mode instruction; that can accept either an 8 or 16 bit operand. During instr-; uction assembly, an 8 bit operand can be forced to 16 bits by; preceding the operand field with !, e.g., LDA !#$01, which; will assemble as $A9 $01 $00.;mnetabam .byte ops0 | am_nam ; $00 BRK.byte ops1 | am_indx ; $01 ORA (dp,X).byte ops1 | am_nam ; $02 COP.byte ops1 | am_stk ; $03 ORA offset,S.byte ops1 | am_nam ; $04 TSB dp.byte ops1 | am_nam ; $05 ORA dp.byte ops1 | am_nam ; $06 ASL dp.byte ops1 | am_indl ; $07 ORA [dp].byte ops0 | am_nam ; $08 PHP.byte vops | am_imm ; $09 ORA #.byte ops0 | am_nam ; $0A ASL A.byte ops0 | am_nam ; $0B PHD.byte ops2 | am_nam ; $0C TSB abs.byte ops2 | am_nam ; $0D ORA abs.byte ops2 | am_nam ; $0E ASL abs.byte ops3 | am_nam ; $0F ORA absl;.byte bop1 | am_nam ; $10 BPL abs.byte ops1 | am_indy ; $11 ORA (dp),Y.byte ops1 | am_ind ; $12 ORA (dp).byte ops1 | am_stky ; $13 ORA (offset,S),Y.byte ops1 | am_nam ; $14 TRB dp.byte ops1 | am_adrx ; $15 ORA dp,X.byte ops1 | am_adrx ; $16 ASL dp,X.byte ops1 | am_indly ; $17 ORA [dp],Y.byte ops0 | am_nam ; $18 CLC.byte ops2 | am_nam ; $19 ORA abs.byte ops0 | am_nam ; $1A INC A.byte ops0 | am_nam ; $1B TCS.byte ops2 | am_nam ; $1C TRB abs.byte ops2 | am_adrx ; $1D ORA abs,X.byte ops2 | am_adrx ; $1E ASL abs,X.byte ops3 | am_adrx ; $1F ORA absl,X;.byte ops2 | am_nam ; $20 JSR abs.byte ops1 | am_indx ; $21 AND (dp,X).byte ops3 | am_nam ; $22 JSL absl.byte ops1 | am_stk ; $23 AND offset,S.byte ops1 | am_nam ; $24 BIT dp.byte ops1 | am_nam ; $25 AND dp.byte ops1 | am_nam ; $26 ROL dp.byte ops1 | am_indl ; $27 AND [dp].byte ops0 | am_nam ; $28 PLP.byte vops | am_imm ; $29 AND #.byte ops0 | am_nam ; $2A ROL A.byte ops0 | am_nam ; $2B PLD.byte ops2 | am_nam ; $2C BIT abs.byte ops2 | am_nam ; $2D AND abs.byte ops2 | am_nam ; $2E ROL abs.byte ops3 | am_nam ; $2F AND absl;.byte bop1 | am_nam ; $30 BMI abs.byte ops1 | am_indy ; $31 AND (dp),Y.byte ops1 | am_ind ; $32 AND (dp).byte ops1 | am_stky ; $33 AND (offset,S),Y.byte ops1 | am_adrx ; $34 BIT dp,X.byte ops1 | am_adrx ; $35 AND dp,X.byte ops1 | am_adrx ; $36 ROL dp,X.byte ops1 | am_indly ; $37 AND [dp],Y.byte ops0 | am_nam ; $38 SEC.byte ops2 | am_adry ; $39 AND abs,Y.byte ops0 | am_nam ; $3A DEC A.byte ops0 | am_nam ; $3B TSC.byte ops2 | am_adrx ; $3C BIT abs,X.byte ops2 | am_adrx ; $3D AND abs,X.byte ops2 | am_adrx ; $3E ROL abs,X.byte ops3 | am_adrx ; $3F AND absl,X;.byte ops0 | am_nam ; $40 RTI.byte ops1 | am_indx ; $41 EOR (dp,X).byte ops0 | am_nam ; $42 WDM.byte ops1 | am_stk ; $43 EOR offset,S.byte ops2 | am_move ; $44 MVP sb,db.byte ops1 | am_nam ; $45 EOR dp.byte ops1 | am_nam ; $46 LSR dp.byte ops1 | am_indl ; $47 EOR [dp].byte ops0 | am_nam ; $48 PHA.byte vops | am_imm ; $49 EOR #.byte ops0 | am_nam ; $4A LSR A.byte ops0 | am_nam ; $4B PHK.byte ops2 | am_nam ; $4C JMP abs.byte ops2 | am_nam ; $4D EOR abs.byte ops2 | am_nam ; $4E LSR abs.byte ops3 | am_nam ; $4F EOR absl;.byte bop1 | am_nam ; $50 BVC abs.byte ops1 | am_indy ; $51 EOR (dp),Y.byte ops1 | am_ind ; $52 EOR (dp).byte ops1 | am_stky ; $53 EOR (offset,S),Y.byte ops2 | am_move ; $54 MVN sb,db.byte ops1 | am_adrx ; $55 EOR dp,X.byte ops1 | am_adrx ; $56 LSR dp,X.byte ops1 | am_indly ; $57 EOR [dp],Y.byte ops0 | am_nam ; $58 CLI.byte ops2 | am_adry ; $59 EOR abs,Y.byte ops0 | am_nam ; $5A PHY.byte ops0 | am_nam ; $5B TCD.byte ops3 | am_nam ; $5C JML absl.byte ops2 | am_adrx ; $5D EOR abs,X.byte ops2 | am_adrx ; $5E LSR abs,X.byte ops3 | am_adrx ; $5F EOR absl,X;.byte ops0 | am_nam ; $60 RTS.byte ops1 | am_indx ; $61 ADC (dp,X).byte bop2 | am_nam ; $62 PER.byte ops1 | am_stk ; $63 ADC offset,S.byte ops1 | am_nam ; $64 STZ dp.byte ops1 | am_nam ; $65 ADC dp.byte ops1 | am_nam ; $66 ROR dp.byte ops1 | am_indl ; $67 ADC [dp].byte ops0 | am_nam ; $68 PLA.byte vops | am_imm ; $69 ADC #.byte ops0 | am_nam ; $6A ROR A.byte ops0 | am_nam ; $6B RTL.byte ops2 | am_ind ; $6C JMP (abs).byte ops2 | am_nam ; $6D ADC abs.byte ops2 | am_nam ; $6E ROR abs.byte ops3 | am_nam ; $6F ADC absl;.byte bop1 | am_nam ; $70 BVS abs.byte ops1 | am_indy ; $71 ADC (dp),Y.byte ops1 | am_ind ; $72 ADC (dp).byte ops1 | am_stky ; $73 ADC (offset,S),Y.byte ops1 | am_adrx ; $74 STZ dp,X.byte ops1 | am_adrx ; $75 ADC dp,X.byte ops1 | am_adrx ; $76 ROR dp,X.byte ops1 | am_indly ; $77 ADC [dp],Y.byte ops0 | am_nam ; $78 SEI.byte ops2 | am_adry ; $79 ADC abs,Y.byte ops0 | am_nam ; $7A PLY.byte ops0 | am_nam ; $7B TDC.byte ops2 | am_indx ; $7C JMP (abs,X).byte ops2 | am_adrx ; $7D ADC abs,X.byte ops2 | am_adrx ; $7E ROR abs,X.byte ops3 | am_adrx ; $7F ADC absl,X;.byte bop1 | am_nam ; $80 BRA abs.byte ops1 | am_indx ; $81 STA (dp,X).byte bop2 | am_nam ; $82 BRL abs.byte ops1 | am_stk ; $83 STA offset,S.byte ops1 | am_nam ; $84 STY dp.byte ops1 | am_nam ; $85 STA dp.byte ops1 | am_nam ; $86 STX dp.byte ops1 | am_indl ; $87 STA [dp].byte ops0 | am_nam ; $88 DEY.byte vops | am_imm ; $89 BIT #.byte ops0 | am_nam ; $8A TXA.byte ops0 | am_nam ; $8B PHB.byte ops2 | am_nam ; $8C STY abs.byte ops2 | am_nam ; $8D STA abs.byte ops2 | am_nam ; $8E STX abs.byte ops3 | am_nam ; $8F STA absl;.byte bop1 | am_nam ; $90 BCC abs.byte ops1 | am_indy ; $91 STA (dp),Y.byte ops1 | am_ind ; $92 STA (dp).byte ops1 | am_stky ; $93 STA (offset,S),Y.byte ops1 | am_adrx ; $94 STY dp,X.byte ops1 | am_adrx ; $95 STA dp,X.byte ops1 | am_adry ; $96 STX dp,Y.byte ops1 | am_indly ; $97 STA [dp],Y.byte ops0 | am_nam ; $98 TYA.byte ops2 | am_adry ; $99 STA abs,Y.byte ops0 | am_nam ; $9A TXS.byte ops0 | am_nam ; $9B TXY.byte ops2 | am_nam ; $9C STZ abs.byte ops2 | am_adrx ; $9D STA abs,X.byte ops2 | am_adrx ; $9E STZ abs,X.byte ops3 | am_adrx ; $9F STA absl,X;.byte vops | am_imm ; $A0 LDY #.byte ops1 | am_indx ; $A1 LDA (dp,X).byte vops | am_imm ; $A2 LDX #.byte ops1 | am_stk ; $A3 LDA offset,S.byte ops1 | am_nam ; $A4 LDY dp.byte ops1 | am_nam ; $A5 LDA dp.byte ops1 | am_nam ; $A6 LDX dp.byte ops1 | am_indl ; $A7 LDA [dp].byte ops0 | am_nam ; $A8 TAY.byte vops | am_imm ; $A9 LDA #.byte ops0 | am_nam ; $AA TAX.byte ops0 | am_nam ; $AB PLB.byte ops2 | am_nam ; $AC LDY abs.byte ops2 | am_nam ; $AD LDA abs.byte ops2 | am_nam ; $AE LDX abs.byte ops3 | am_nam ; $AF LDA absl;.byte bop1 | am_nam ; $B0 BCS abs.byte ops1 | am_indy ; $B1 LDA (dp),Y.byte ops1 | am_ind ; $B2 LDA (dp).byte ops1 | am_stky ; $B3 LDA (offset,S),Y.byte ops1 | am_adrx ; $B4 LDY dp,X.byte ops1 | am_adrx ; $B5 LDA dp,X.byte ops1 | am_adry ; $B6 LDX dp,Y.byte ops1 | am_indly ; $B7 LDA [dp],Y.byte ops0 | am_nam ; $B8 CLV.byte ops2 | am_adry ; $B9 LDA abs,Y.byte ops0 | am_nam ; $BA TSX.byte ops0 | am_nam ; $BB TYX.byte ops2 | am_adrx ; $BC LDY abs,X.byte ops2 | am_adrx ; $BD LDA abs,X.byte ops2 | am_adry ; $BE LDX abs,Y.byte ops3 | am_adrx ; $BF LDA absl,X;.byte vops | am_imm ; $C0 CPY #.byte ops1 | am_indx ; $C1 CMP (dp,X).byte ops1 | am_imm ; $C2 REP #.byte ops1 | am_stk ; $C3 CMP offset,S.byte ops1 | am_nam ; $C4 CPY dp.byte ops1 | am_nam ; $C5 CMP dp.byte ops1 | am_nam ; $C6 DEC dp.byte ops1 | am_indl ; $C7 CMP [dp].byte ops0 | am_nam ; $C8 INY.byte vops | am_imm ; $C9 CMP #.byte ops0 | am_nam ; $CA DEX.byte ops0 | am_nam ; $CB WAI.byte ops2 | am_nam ; $CC CPY abs.byte ops2 | am_nam ; $CD CMP abs.byte ops2 | am_nam ; $CE DEC abs.byte ops3 | am_nam ; $CF CMP absl;.byte bop1 | am_nam ; $D0 BNE abs.byte ops1 | am_indy ; $D1 CMP (dp),Y.byte ops1 | am_ind ; $D2 CMP (dp).byte ops1 | am_stky ; $D3 CMP (offset,S),Y.byte ops1 | am_nam ; $D4 PEI dp.byte ops1 | am_adrx ; $D5 CMP dp,X.byte ops1 | am_adrx ; $D6 DEC dp,X.byte ops1 | am_indly ; $D7 CMP [dp],Y.byte ops0 | am_nam ; $D8 CLD.byte ops2 | am_adry ; $D9 CMP abs,Y.byte ops0 | am_nam ; $DA PHX.byte ops0 | am_nam ; $DB STP.byte ops2 | am_indl ; $DC JMP [abs].byte ops2 | am_adrx ; $DD CMP abs,X.byte ops2 | am_adrx ; $DE DEC abs,X.byte ops3 | am_adrx ; $DF CMP absl,X;.byte vops | am_imm ; $E0 CPX #.byte ops1 | am_indx ; $E1 SBC (dp,X).byte ops1 | am_imm ; $E2 SEP #.byte ops1 | am_stk ; $E3 SBC offset,S.byte ops1 | am_nam ; $E4 CPX dp.byte ops1 | am_nam ; $E5 SBC dp.byte ops1 | am_nam ; $E6 INC dp.byte ops1 | am_indl ; $E7 SBC [dp].byte ops0 | am_nam ; $E8 INX.byte vops | am_imm ; $E9 SBC #.byte ops0 | am_nam ; $EA NOP.byte ops0 | am_nam ; $EB XBA.byte ops2 | am_nam ; $EC CPX abs.byte ops2 | am_nam ; $ED SBC abs.byte ops2 | am_nam ; $EE INC abs.byte ops3 | am_nam ; $EF SBC absl;.byte bop1 | am_nam ; $F0 BEQ abs.byte ops1 | am_indy ; $F1 SBC (dp),Y.byte ops1 | am_ind ; $F2 SBC (dp).byte ops1 | am_stky ; $F3 SBC (offset,S),Y.byte ops2 | am_imm ; $F4 PEA #.byte ops1 | am_adrx ; $F5 SBC dp,X.byte ops1 | am_adrx ; $F6 INC dp,X.byte ops1 | am_indly ; $F7 SBC [dp],Y.byte ops0 | am_nam ; $F8 SED.byte ops2 | am_adry ; $F9 SBC abs,Y.byte ops0 | am_nam ; $FA PLX.byte ops0 | am_nam ; $FB XCE.byte ops2 | am_indx ; $FC JSR (abs,X).byte ops2 | am_adrx ; $FD SBC abs,X.byte ops2 | am_adrx ; $FE INC abs,X.byte ops3 | am_adrx ; $FF SBC absl,X;;; .X & .Y immediate mode opcodes...;vopidx .byte $a0 ;LDY #.byte $a2 ;LDX #.byte $c0 ;CPY #.byte $e0 ;CPX #n_vopidx =*-vopidx ;number of opcodes;;; addressing mode symbology lookup...;ms_lutab .word ms_nam ;(0000) no symbol.word ms_imm ;(0001) #.word ms_addrx ;(0010) dp,X or abs,X.word ms_addry ;(0011) dp,Y or abs,Y.word ms_ind ;(0100) (dp) or (abs).word ms_indl ;(0101) [dp] or [abs].word ms_indly ;(0110) [dp],Y.word ms_indx ;(0111) (dp,X) or (abs,X).word ms_indy ;(1000) (dp),Y.word ms_stk ;(1001) offset,S.word ms_stky ;(1010) (offset,S),Y.word ms_nam ;(1011) sbnk,dbnk;;; addressing mode symbology strings...;ms_nam .byte " ",0 ;no symbolms_addrx .byte " ,X",0 ;dp,X or addr,Xms_addry .byte " ,Y",0 ;dp,Y or addr,Yms_imm .byte "#",0 ;immediatems_ind .byte "()",0 ;(dp) or (abs)ms_indl .byte "[]",0 ;[dp] or [abs]ms_indly .byte "[],Y",0 ;[dp],Yms_indx .byte "(,X)",0 ;(dp,X) or (abs,X)ms_indy .byte "(),Y",0 ;(dp),Yms_move .byte ",$",0 ;MVN/MVP sbnk,dbnkms_stk .byte " ,S",0 ;offset,Sms_stky .byte "(,S),Y",0 ;(offset,S),Y;;================================================================================;;CONSOLE DISPLAY CONTROL STRINGS;dc_bf bf ;enable reverse foreground.byte 0;dc_bs bs ;destructive backspace.byte 0;dc_cl cl ;clear to end of line.byte 0;dc_cn cn ;cursor on.byte 0;dc_co co ;cursor off.byte 0;dc_er er ;enable normal foreground.byte 0;dc_lf lf ;newline.byte 0;;================================================================================;;TEXT STRINGS;mm_brk rblf.byte "**BRK"lf.byte 0;mm_entry lf.byte a_lf,"Supermon 816 "softvers.byte " "lf.byte 0;mm_err .byte " **ERR ",0;mm_prmpt lfsf.byte ".",0;mm_regs lf.byte " PB PC NVmxDIZC .C .X .Y SP DP DB"lf.byte "; ",0;mm_rts rblf.byte "**RTS"lf.byte 0;;================================================================================;;VECTOR STORAGE;vecbrkia .word 0 ;system indirect BRK vector;_txtend_ =* ;end of program text;;================================================================================.end
