; ******************************* ; * BSM = Bit Shifter's Monitor * ; * for The MEGA65 10-Dec_2020 * ; * (adaped for the Open ROMs) * ; ******************************* !macro NOP { eom } ; ACME does not allow NOP for MEGA65 CPU ; XXX adapt all the addresses/constants! ; ******************** ; * Register storage * ; ******************** !addr Bank = 2 ; XXX get rid of it! !addr PCH = 3 !addr PCL = 4 !addr SR = 5 !addr AC = 6 !addr XR = 7 !addr YR = 8 !addr ZR = 9 ; ************************************* ; * Used direct (zero) page addresses * ; ************************************* !addr BP = 10 !addr SPH = 11 !addr SPL = 12 ; following variables overlap with the BASIC floating point area ; $59 - $5d : temporary floating point accumulator ; $5e - $62 : temporary floating point accumulator ; $63 - $69 : primary floating point accumulator ; $6a - $6f : secondary floating point accumulator ; A set of 32 bit variables also used as 32 bit pointer !addr Long_AC = $59 ; 32 bit accumulator !addr Long_CT = $5d ; 32 bit counter !addr Long_PC = $61 ; 32 bit program counter !addr Long_DA = $65 ; 32 bit data pointer ; Flags are used in BBR BBS instructions !addr Adr_Flags = $69 !addr Mode_Flags = $6a !addr Op_Code = $6b !addr Op_Flag = $6c ; 7: two operands ; 6: long branch ; 5: 32 bit address ; 4: Q register !addr Op_Size = $6d !addr Dig_Cnt = $6e !addr Buf_Index = $6f !addr MODE_80 = $d7 ; 80 column / 40 volumn flag ; XXX add routine to detect this !addr Disk_Status = $40A ; BCD value of status !addr Disk_Msg = $410 ; 40 bytes, disk status as text message ; XXX get rid of this buffer ; ******* Mon_Break ; ******* JSR Print_Commands ; pull BP, Z, Y, X, A,SR,PCL,PCH ; 7 6 5 4 3 2 1 0 LDX #7 @loop PLA STA PCH,X DEX BPL @loop ; decrement PC to point after BRK LDA PCL BNE @nopage DEC PCH @nopage DEC PCL LDA $011d BBR7 Bank,@bank LDA $011f @bank AND #15 STA Bank BRA Mon_Start ; ****** Mon_Call ; ****** JSR Print_Commands ; clear register for monitor call LDA #0 LDX #6 @loop STA AC,X DEX BPL @loop ; set default PC to monitor exit point LDA #map_NORMAL STA PCL STA MON_XVEC STX PCH STX MON_XVEC+1 ; ******* Mon_Start ; ******* CLD TSY STY SPH TSX STX SPL LDA #$c0 JSR SETMSG CLI +NOP ; ********** Mon_Register ; ********** JSR Reg_Text ; print PCH LDA PCH JSR Print_Hex ; print PCL,SR,PCL,A,X,Y,Z,BP LDY #0 @loopb LDA PCL,Y JSR Print_Hex_Blank INY CPY #7 BCC @loopb ; print 16 bit stack pointer LDA SPH JSR Print_Hex LDA SPL JSR Print_Hex_Blank ; print flags LDY #8 LDA SR @loopc ASL PHA LDA #'-' BCC @flag LDA #'1' @flag JSR CHROUT PLA DEY BNE @loopc ; ** Main ; ** JSR Print_CR LDX #0 ; read one line into buffer ; **** Main_A ; **** @loop JSR CHRIN STA BUF,X INX CPX #80 BCS Mon_Error ; input too long CMP #KEY_RETURN BNE @loop LDA #0 STA Buf_Index STA BUF-1,X ; terminate buffer @getcomm JSR Get_Char BEQ Main CMP #' ' BEQ @getcomm ; ******** Mon_Switch ; ******** LDX #24 @loop CMP Command_Char,X BEQ Mon_Select DEX BPL @loop ; fall through to error routine if not found ; ******* Mon_Error ; ******* ; put a question mark at the end of the text JSR PRIMM !pet KEY_ESC, "o",KEY_CRSR_RIGHT,'?',0 LDX #$f8 ; reset stack pointer TXS BRA Main ; ******** Mon_Select ; ******** STA VERCKK CPX #22 LBCS Load_Save TXA ASL TAX JMP (Jump_Table,X) ; ************ Print_Commands ; ************ JSR PRIMM !pet KEY_RETURN,KEY_YELLOW,KEY_RVS_ON," commands: " ; ********** Command_Char ; ********** ; 0123456789abcdef !pet "abcdfghjmrtx@.>;?" ; ********* Cons_Prefix ; ********* !pet "$+&%'" ; ************** Load_Save_Verify ; ************** !pet "lsv ",KEY_WHITE,KEY_RETURN,0 RTS ; ******** Jump_Table ; ******** !word Mon_Assemble ; A !word Mon_Bits ; B !word Mon_Compare ; C !word Mon_Disassemble ; D !word Mon_Fill ; F !word Mon_Go ; G !word Mon_Hunt ; H !word Mon_JSR ; J !word Mon_Memory ; M !word Mon_Register ; R !word Mon_Transfer ; T !word Mon_Exit ; X !word Mon_DOS ; @ !word Mon_Assemble ; . !word Mon_Set_Memory ; > !word Mon_Set_Register ; ; !word Mon_Help ; ? !word Converter ; $ !word Converter ; + !word Converter ; & !word Converter ; % ; ****** Mon_Exit ; ****** JMP (MON_XVEC) ; ******* LAC_To_PC ; ******* ; called from Mon_Set_Register, Mon_Go and Mon_JSR ; as the first instruction. The carry flag was set from ; the routine Got_LAC if an error occured. ; Notice that the Bank, PCH and PCL values are stored ; high to low, reverse to the standard order. ; Bank, PCH and PCL are part of a list, that is used by ; the routines FAR_JMP and FAR_JSR of the operating system BCS @error LDA Long_AC STA Bank+2 LDA Long_AC+1 STA Bank+1 LDA Long_AC+2 STA Bank @error RTS ; ******** LAC_To_LPC ; ******** PHX LDX #3 @loop LDA Long_AC,X STA Long_PC,X DEX BPL @loop PLX RTS ; ******** LAC_To_LCT ; ******** PHX LDX #3 @loop LDA Long_AC,X STA Long_CT,X DEX BPL @loop PLX RTS ; ******** LAC_To_LDA ; ******** PHX LDX #3 @loop LDA Long_AC,X STA Long_DA,X DEX BPL @loop PLX RTS ; ********** LAC_Plus_LCT ; ********** PHX LDX #252 ; use ZP wrap around CLC @loop LDA Long_AC+4,X ADC Long_CT+4,X STA Long_AC+4,X INX BNE @loop PLX RTS ; *********** LAC_Minus_LPC ; *********** PHX LDX #252 ; use ZP wrap around SEC @loop LDA Long_AC+4,X SBC Long_PC+4,X STA Long_CT+4,X INX BNE @loop PLX RTS ; ************* LAC_Compare_LPC ; ************* PHX LDX #252 ; use ZP wrap around SEC @loop LDA Long_AC+4,X SBC Long_PC+4,X INX BNE @loop PLX RTS ; ***** Inc_LAC ; ***** INW Long_AC BNE @return INW Long_AC+2 @return RTS ; ***** Dec_LAC ; ***** LDA Long_AC ORA Long_AC+1 BNE @skip DEW Long_AC+2 @skip DEW Long_AC RTS ; ***** Inc_LPC ; ***** INW Long_PC BNE @return INW Long_PC+2 @return RTS ; ***** Dec_LDA ; ***** LDA Long_DA ORA Long_DA+1 BNE @skip DEW Long_DA+2 @skip DEW Long_DA RTS ; *** Fetch ; *** PHZ TYA TAZ BBS7 Long_PC+3,@banked ; trigger banked access +NOP ; use LDA [Long_PC],Z @banked LDA (Long_PC),Z PLZ AND #$ff RTS ; ******** Mon_Memory ; ******** JSR Get_LAC ; get 1st. parameter LDZ #16 ; default row count BCS @row ; no address JSR LAC_To_LPC ; Long_PC = start address JSR Get_LAC ; Long_AC = end address BCS @row ; not given JSR LAC_Minus_LPC ; Long_CT = range LBCC Mon_Error ; negative range -> error LDX #4 ; 16 bytes / line BBR7 MODE_80,@shift DEX ; 8 bytes / line @shift LSR Long_CT+1 ROR Long_CT DEX BNE @shift LDZ Long_CT ; row count INZ @row JSR STOP BEQ @exit JSR Dump_Row DEZ BNE @row @exit JMP Main ; ******** Print_Bits ; ******** PHZ STA Long_DA LDY #8 @loop LDA #'*' BBS7 Long_DA,@set LDA #'.' @set JSR CHROUT ASL Long_DA DEY BNE @loop PLZ RTS ; ****** Mon_Bits ; ****** JSR Get_LAC ; get 1st. parameter BCS @lab JSR LAC_To_LPC ; Long_PC = start address @lab JSR Print_CR LDA #KEY_WHITE STA Long_DA+1 LDX #8 @row PHX JSR Hex_LPC LDZ #0 @col SEC LDA #KEY_WHITE+KEY_LT_RED ; toggle colour SBC Long_DA+1 STA Long_DA+1 JSR CHROUT LDA [Long_PC],Z JSR Print_Bits CLC TZA ADC #8 TAZ CMP #64 BCC @col JSR Print_CR JSR Inc_LPC PLX DEX BNE @row JMP Main ; ************** Mon_Set_Register ; ************** JSR Get_LAC ; get 1st. parameter JSR LAC_To_PC LDY #3 @loop JSR Get_LAC BCS @exit LDA Long_AC STA Bank,Y INY CPY #9 BCC @loop @exit JMP Main ; ************ Mon_Set_Memory ; ************ JSR Get_LAC ; get 1st. parameter BCS @exit JSR LAC_To_LPC ; Long_PC = row address LDZ #0 @loop JSR Get_LAC BCS @exit LDA Long_AC BBS7 Long_PC+3,@banked ; trigger banked access +NOP ; use STA [Long_PC],Z @banked STA (Long_PC),Z INZ CPZ #16 BBR7 MODE_80,@next CPZ #8 @next BCC @loop @exit JSR PRIMM !pet KEY_ESC, "o" !pet $91,$00 JSR Dump_Row JMP Main ; **** Mon_Go ; **** ; XXX to be rewritten for Open ROMs! jmp Main ; JSR Get_LAC ; get 1st. parameter ; JSR LAC_To_PC ; LDX SPL ; TXS ; JMP JMPFAR ; ***** Mon_JSR ; ***** ; XXX to be rewritten for Open ROMs! jmp Main ; JSR Get_LAC ; get 1st. parameter ; JSR LAC_To_PC ; LDX SPL ; TXS ; JSR JSRFAR ; TSX ; STX SPL ; JMP Main ; ********** Dump_4_Bytes ; ********** JSR CHROUT ; colour @loop BBS7 Long_PC+3,@banked ; trigger banked access +NOP ; use LDA [Long_PC],Z @banked LDA (Long_PC),Z JSR Print_Hex_Blank INZ TZA AND #3 BNE @loop RTS ; ********** Dump_4_Chars ; ********** LDY #0 STY QTSW ; disable quote mode JSR CHROUT ; colour @loop BBS7 Long_PC+3,@banked ; trigger banked access +NOP ; use LDA [Long_PC],Z @banked LDA (Long_PC),Z TAY AND #%01100000 BNE @laba LDY #'.' @laba TYA JSR CHROUT INZ TZA AND #3 BNE @loop RTS ; ****** Dump_Row ; ****** PHZ JSR Print_CR LDA #'>' JSR CHROUT JSR Hex_LPC LDZ #0 LDX #2 ; 2 blocks in 80 columns BBR7 MODE_80,@loop DEX ; 1 block in 40 columns @loop LDA #KEY_LT_RED JSR Dump_4_Bytes LDA #KEY_WHITE JSR Dump_4_Bytes DEX BNE @loop JSR PRIMM !byte $3a,$12,$00 ; : reverse on LDZ #0 LDX #2 ; 4 blocks in 80 columns BBR7 MODE_80,@lchr DEX ; 2 blocks in 40 columns @lchr LDA #KEY_LT_RED JSR Dump_4_Chars LDA #KEY_WHITE JSR Dump_4_Chars DEX BNE @lchr TZA JSR Add_LPC PLZ RTS ; ********** Mon_Transfer ; ********** JSR Param_Range ; Long_PC = source LBCS Mon_Error ; Long_CT = count JSR Get_LAC ; Long_AC = target LBCS Mon_Error LDZ #0 JSR LAC_Compare_LPC ; target - source BCC @forward ; source < target: backward transfer JSR LAC_Plus_LCT ; Long_AC = end of target @lpback LDA [Long_DA],Z ; backward copy STA [Long_AC],Z JSR Dec_LDA JSR Dec_LAC JSR Dec_LCT BPL @lpback JMP Main @forward LDA [Long_PC],Z ; forward copy STA [Long_AC],Z JSR Inc_LPC JSR Inc_LAC JSR Dec_LCT BPL @forward JMP Main ; ********* Mon_Compare ; ********* JSR Param_Range ; Long_PC = source LBCS Mon_Error ; Long_CT = count JSR Get_LAC ; Long_AC = target LBCS Mon_Error JSR Print_CR LDZ #0 @loop LDA [Long_PC],Z CMP [Long_AC],Z BEQ @laba JSR Hex_LPC @laba JSR Inc_LAC JSR Inc_LPC JSR Dec_LCT BPL @loop JMP Main ; ****** Mon_Hunt ; ****** JSR Param_Range ; Long_PC = start LBCS Mon_Error ; Long_CT = count LDY #0 JSR Get_Char CMP #KEY_APOSTROPHE BNE @bin JSR Get_Char ; string hunt CMP #0 LBEQ Mon_Error ; null string @lpstr STA MON_DATA,Y INY JSR Get_Char BEQ @hunt CPY #32 ;max. string length BNE @lpstr BRA @hunt @bin JSR Got_LAC @lpbin LDA Long_AC STA MON_DATA,Y INY JSR Get_LAC BCS @hunt CPY #32 ;max. data length BNE @lpbin @hunt STY Long_DA ; hunt length JSR Print_CR @lpstart LDY #0 @lpins JSR Fetch CMP MON_DATA,Y BNE @next INY CPY Long_DA BNE @lpins JSR Hex_LPC ; match @next JSR STOP LBEQ Main JSR Inc_LPC JSR Dec_LCT BPL @lpstart JMP Main ; ******* Load_Save ; ******* ; XXX to be rewritten for Open ROMs! jmp Main ; LDY Disk_Unit ; STY FA ; LDY #8 ; STY SA ; LDY #0 ; STY BA ; STY FNLEN ; STY FNBANK ; STY IOSTATUS ; LDA #>MON_DATA ; STA FNADR+1 ; LDA # load/verify ; JSR Print_CR ; LDX Long_AC ; X/Y = end address ; LDY Long_AC+1 ; LDA VERCKK ; A = load/verify/save ; CMP #'S' ; LBNE Mon_Error ; must be Save ; LDA #0 ; STA SA ; set SA for PRG ; LDA #Long_PC ; Long_PC = start address ; JSR SAVE ; @exit JMP Main ; @do LDA VERCKK ; CMP #'V' ; Verify ; BEQ @exec ; CMP #'L' ; Load ; LBNE Mon_Error ; LDA #0 ; 0 = LOAD ; @exec JSR LOAD ; A == 0 : LOAD else VERIFY ; BBR4 IOSTATUS,@exit ; LDA VERCKK ; LBEQ Mon_Error ; LBCS Main ; JSR PRIMM ; !pet " error",0 ; JMP Main ; @load LDX Long_PC ; LDY Long_PC+1 ; LDA #0 ; 0 = use X/Y as load address ; STA SA ; and ignore load address from file ; BRA @do ; ****** Mon_Fill ; ****** JSR Param_Range ; Long_PC = target LBCS Mon_Error ; Long_CT = count JSR Get_LAC ; Long_AC = fill byte LBCS Mon_Error JSR Print_CR LDZ #0 @loop LDA Long_AC STA [Long_PC],Z JSR Inc_LPC JSR Dec_LCT BPL @loop JMP Main ; ********** Mon_Assemble ; ********** JSR Get_LAC ; get 1st. parameter LBCS Mon_Error JSR LAC_To_LPC ; Long_PC = PC @start LDX #0 ; mne letter counter STX Long_DA+1 ; clear encoded MNE STX Op_Flag ; 6:long branch 5:32 bit STX MON_Op_Ix ; operand byte index STX MON_Op_Len ; operand length @getin JSR Get_Char BNE @laba CPX #0 LBEQ Main @laba CMP #' ' BEQ @start ; restart after blank ; check for long branches CPX #1 BNE @labb ; -> not 2nd. char CMP #'B' BNE @labb ; 2nd. char != 'B' LDZ MON_Op_Mne CPZ #'L' BNE @labb ; 1st. Char != 'L' SMB6 Op_Flag ; flag long branch DEX ; skip 'L' @labb STA MON_Op_Mne,X ; next mne character INX CPX #3 BNE @getin ; encode 3 letter mnemonic @lpenc LDA MON_Op_Mne-1,X SEC SBC #$3f ; offset LDY #5 ; 5 bit code @lpbit LSR ROR Long_DA ROR Long_DA+1 DEY BNE @lpbit DEX BNE @lpenc ; find packed MNE code in table LDX #90 ; # of mnemonics LDA Long_DA @lpfind CMP MNE_L,X ; compare left MNE BNE @nxfind LDY MNE_R,X CPY Long_DA+1 ; compare right MNE BEQ @found @nxfind DEX BPL @lpfind JMP Mon_Error @found STX MON_Ix_Mne ; find 1st. opcode for this mnemonic TXA LDX #0 @lpopc CMP MNE_Index,X BEQ @exopc INX BNE @lpopc @exopc STX Op_Code ; check for BBR BBS RMB SMB TXA AND #7 CMP #7 BNE @labc JSR Get_Char CMP #'0' LBCC Mon_Error CMP #'8' LBCS Mon_Error ASL ASL ASL ASL ORA Op_Code STA Op_Code JSR Get_Char CMP #' ' LBNE Mon_Error ; read operand @labc LDA #0 @labd STA Mode_Flags JSR Read_Number LBCS Mon_Error BEQ @labg ; no operand LDA Long_AC+2 LBNE Mon_Error ; -> overflow LDY #2 ; Y=2 word operand LDA Long_AC+1 BNE @labf ; high byte not zero DEY ; Y=1 byte operand @labf LDX MON_Op_Ix ; X = operand value # TYA ; A = 1:byte or 2:word STA MON_Op_Len,X ; store operand length INC MON_Op_Ix ; ++index to operand value TXA ; A = current index BNE @labg ; -> at 2nd. byte JSR LAC_To_LCT ; Long_CT = 1st. operand @labg DEC Buf_Index ; back to delimiter @lpnop JSR Get_Char ; get delimiter LBEQ @adjust ; end of operand CMP #' ' BEQ @lpnop ; immediate CMP #'#' BNE @lbra LDA Mode_Flags BNE @error LDA #$80 ; immediate mode BRA @labd ; left bracket @lbra CMP #'[' BNE @indir LDA Mode_Flags BNE @error SMB5 Op_Flag ; 32 bit mode LDA #$40 ; ( flag BRA @labd ; left parenthesis @indir CMP #'(' BNE @comma LDA Mode_Flags BNE @error LDA #$40 ; ( flag BRA @labd ; comma @comma CMP #',' BNE @stack LDA MON_Op_Ix ; operand value # BEQ @error LDX #4 ; outside comma LDA Mode_Flags BEQ @comma1 ; no flags yet CMP #$78 ; ($nn,SP) BEQ @comma1 CMP #$48 ; ($nn) BEQ @comma1 LDX #$20 ; , inside comma CMP #$40 ; ( BNE @error @comma1 TXA ORA Mode_Flags JMP @labd ; stack relative @stack CMP #'S' BNE @rbra JSR Get_Char CMP #'P' BNE @error LDA Mode_Flags CMP #$60 ; ($nn, BNE @error ORA #%00010000 ; SP flag JMP @labd ; right bracket @rbra CMP #']' BNE @right BBR5 Op_Flag,@error LDA MON_Op_Ix LBEQ Mon_Error ; no value LDA Mode_Flags CMP #$40 ; ( LBNE Mon_Error ORA #%00001000 ; ) JMP @labd @error JMP Mon_Error ; right parenthesis @right CMP #')' BNE @X LDA MON_Op_Ix LBEQ Mon_Error ; no value LDA Mode_Flags CMP #$40 ; ( BEQ @right1 CMP #$61 ; ($nn,X BEQ @right1 CMP #$70 ; ($nn,SP LBNE Mon_Error @right1 ORA #%00001000 ; ) JMP @labd @X CMP #'X' BNE @Y LDA MON_Op_Ix LBEQ Mon_Error LDA Mode_Flags CMP #$60 BEQ @X1 CMP #4 LBNE Mon_Error @X1 ORA #%00000001 JMP @labd ; Y @Y CMP #'Y' BNE @Z LDA MON_Op_Ix LBEQ Mon_Error LDA Mode_Flags CMP #$4c ; ($nn), BEQ @Y1 CMP #4 ; $nn, BEQ @Y1 CMP #$7c ; ($nn,SP), LBNE Mon_Error @Y1 ORA #%00000010 ; Y JMP @labd ; Z @Z CMP #'Z' LBNE Mon_Error LDA MON_Op_Ix LBEQ Mon_Error LDA Mode_Flags CMP #$4c ; $nn, LBNE Mon_Error ORA #%00000011 ; Z JMP @labd ; BBR BBS RMB SMB two operands @adjust LDA MON_Ix_Mne LDX MON_Op_Ix ; # if values BEQ @match ; -> no operand DEX BEQ @one ; -> one operand DEX LBNE Mon_Error ; -> error if more than 2 CMP #5 ; BBR BEQ @BB CMP #6 ; BBS LBNE Mon_Error @BB LDA Long_CT+1 LBNE Mon_Error LDA #3 ; offset JSR Branch_Target LDA Op_Code LDY Long_AC LDX Long_CT STX Long_AC STY Long_AC+1 LDY #2 BRA @store ; one operand in Long_CT @one LDX Long_CT LDY Long_CT+1 STX Long_AC STY Long_AC+1 ; Aval = operand LDX #10 @lpbrain CMP BRAIN-1,X BEQ @branch DEX BNE @lpbrain BRA @match ; branch instruction @branch LDA Mode_Flags LBNE Mon_Error ; only value LDA #2 ; branch offset JSR Branch_Target LDA Op_Code LDY #1 ; short branch BBR6 Op_Flag,@bran1 INY ; long branch ORA #3 @bran1 BRA @store ; find opcode matching mnemonic and address mode @match JSR Mode_Index @lpmatch JSR Match_Mode BEQ @okmat LDA MON_Op_Len LBEQ Mon_Error LDA Mode_Flags LBMI Mon_Error AND #%00111111 STA Mode_Flags INC MON_Op_Len JSR Size_To_Mode BRA @lpmatch @okmat LDY MON_Op_Len TXA ; store instruction bytes ; ----------------------- ; A = opcode ; Y = operand length ; Long_AC = operand value @store STA Op_Code STY Op_Size INC Op_Size BBR5 Op_Flag,@storen LDA #$ea ; 32 bit prefix LDZ #0 STA [Long_PC],Z ; store prefix INZ LDA Op_Code STA [Long_PC],Z ; store opcode INZ LDA Long_AC STA [Long_PC],Z ; store address INC Op_Size BRA @print @storen PHY PLZ ; Z = Y BEQ @store1 @lpsto LDA Long_AC-1,Y STA [Long_PC],Z DEZ DEY BNE @lpsto @store1 LDA Op_Code STA [Long_PC],Z @print JSR PRIMM !pet 13,$91,"a ", KEY_ESC, "q",0 JSR Print_Code INC Op_Size LDA Op_Size JSR Add_LPC ; print out command 'A' together with next address ; and put it into buffer too, ; for easy entry of next assembler instruction JSR PRIMM !pet KEY_RETURN,"a ",0 LDA #'A' STA BUF LDA #' ' STA BUF+1 LDY #2 LDX #2 ; 6 digits LDA Long_PC,X BNE @auto DEX ; 4 digits @auto PHX LDA Long_PC,X JSR A_To_Hex STA BUF,Y JSR CHROUT INY TXA STA BUF,Y JSR CHROUT INY PLX DEX BPL @auto LDA #' ' STA BUF,Y JSR CHROUT INY TYA TAX JMP Main_A ; *********** Branch_Target ; *********** DEW Long_AC DEC BNE Branch_Target ; Target - PC SEC LDA Long_AC SBC Long_PC STA Long_AC LDA Long_AC+1 SBC Long_PC+1 STA Long_AC+1 RTS ; ******** Match_Mode ; ******** ; find matching mnemonic and address mode LDX Op_Code ; try this opcode LDA Mode_Flags ; size and address mode @loop CMP LEN_ADM,X BEQ @return ; success ZF=1 ; search for next opcode with same mnemonic @next INX ; next opcode BEQ @error LDY MNE_Index,X CPY MON_Ix_Mne ; same mnemonic ? BEQ @loop ; -> compare again BRA @next @error DEX ; X = $ff ZF=0 @return RTS ; ******** Mode_Index ; ******** LDA Mode_Flags LDX #0 @loop CMP ADMODE,X BEQ @found INX CPX #16 BCC @loop TXA RTS @found STX Mode_Flags ; ********** Size_To_Mode ; ********** LDA MON_Op_Len LSR ROR ROR ORA Mode_Flags STA Mode_Flags LDX #0 RTS ; ************* Mon_Disassemble ; ************* JSR Get_LAC ; get 1st. parameter BCS @nopar JSR LAC_To_LPC ; Long_PC = start address JSR Get_LAC ; Long_AC = end address BCC @range @nopar LDA #32 ; disassemble 32 bytes STA Long_CT BRA @loop @range JSR LAC_Minus_LPC ; Long_CT = range LBCC Mon_Error ; -> negative @loop JSR CR_Erase ; prepare empty line JSR STOP LBEQ Main JSR Dis_Code ; disassemble one line INC Op_Size LDA Op_Size JSR Add_LPC ; advance address LDA Long_CT SEC SBC Op_Size STA Long_CT BCS @loop JMP Main ; ****** Dis_Code ; ****** JSR PRIMM !pet ". ",0 ; ******** Print_Code ; ******** ; print 24 bit address of instruction JSR Hex_LPC ; 24 bit address ; read opcode and calculate length and address mode LDY #0 STY Op_Flag ; clear flags JSR Fetch ; fetch from (banked) address ; check for Q instructions CMP #$42 ; NEG BNE @nop INY ; Y = 1 JSR Fetch CMP #$42 ; NEG BNE @nop SMB4 Op_Flag ; Q flag LDA #2 JSR Add_LPC ; skip NEG NEG ; check for 32 bit address mode @nop LDY #0 JSR Fetch STA Op_Code TAX CMP #$ea ; prefix ? BNE @normal INY JSR Fetch ; opcode after prefix AND #%00011111 ; identify ($nn),Z codes CMP #%00010010 BNE @normal SMB5 Op_Flag ; set extended flag JSR Fetch STA Op_Code ; code after prefix TAX @normal LDY LEN_ADM,X ; Y = length and address mode TYA ; A = length and address mode AND #15 ; A = address mode TAX ; X = address mode LDA ADMODE,X ; A = mode flags STA Adr_Flags ; store TYA ; A = length and address mode AND #%11000000 ; mask instruction length ASL ; rotate into lower two bits ROL ROL STA Op_Size ; store BBR5 Op_Flag,@norm1 INC Op_Size @norm1 ; print instruction and operand bytes LDY #0 LDA #' ' BBR4 Op_Flag,@blpr LDA #'*' ; print * for NEG NEG @blpr JSR CHROUT @lphex JSR Fetch JSR Print_Hex_Blank CPY #2 BEQ @long ; stop after 3 bytes CPY Op_Size INY BCC @lphex ; fill up with blanks @lpfill CPY #3 BCS @long JSR PRIMM !pet " ",0 INY BRA @lpfill ; detect long branches @long LDA #KEY_YELLOW JSR CHROUT LDX Op_Code LDA LEN_ADM,X CMP #%10100000 ; long branch mode BNE @locate SMB6 Op_Flag ; set long branch flag LDA #'L' JSR CHROUT ; locate mnemonic text @locate LDX Op_Code ; X = opcode LDY MNE_Index,X ; Y = index to mnemonic text LDA MNE_L,Y ; A = packed left part STA Long_AC+1 LDA MNE_R,Y ; A = packed right part STA Long_AC ; unpack and print mnemonic text LDX #3 ; 3 letters @lpmne LDA #0 LDY #5 ; 5 bits per letter @lplet ASL Long_AC ROL Long_AC+1 ROL ; rotate letter into A DEY BNE @lplet ; next bit ADC #$3f ; add offset (C = 0) DEX BEQ @lastc ; 3rd. character TAZ ; remember JSR CHROUT ; and print it BRA @lpmne ; next letter @lastc BBR4 Op_Flag,@lbra ; -> no Q CMP #'A' ; LDA, STA, ORA BEQ @Q3 CMP #'C' ; DEC, INC BNE @Q4 CPZ #'E' ; DEC BEQ @Q3 CPZ #'N' ; INC BNE @Q4 @Q3 LDA #'Q' ; LDQ, STQ, ORQ, INQ, DEQ JSR CHROUT BRA @mne4 @Q4 JSR CHROUT LDA #'Q' ; add Q as 4th. char JSR CHROUT BRA @mne5 @lbra JSR CHROUT ; 3rd. character BBS6 Op_Flag,@mne5 ; long branch ; check for 4-letter bit instructions LDA Op_Code AND #15 CMP #7 ; RMB & SMB BEQ @biti CMP #15 ; BBR & BBS BNE @mne4 SMB7 Op_Flag ; flag two operands @biti LDA Op_Code AND #%01110000 ASL ROL ROL ROL ROL ORA #'0' JSR CHROUT BRA @mne5 @mne4 JSR Print_Blank @mne5 JSR Print_Blank LDA #KEY_WHITE JSR CHROUT ; check for accumulator operand LDA Op_Code LDX #8 @lpaccu DEX BMI @oper CMP ACCUMODE,X BNE @lpaccu LDA #'A' BBR4 Op_Flag,@accu LDA #'Q' @accu JSR CHROUT JMP @return ; fetch and decode operand @oper LDX Op_Size LBEQ @return ; -> no operand BBR7 Adr_Flags,@laba ; bit 7: immediate LDA #'#' BRA @labb @laba BBR6 Adr_Flags,@labc ; bit 6: left ( LDA #'(' BBR5 Op_Flag,@labb LDA #'[' @labb JSR CHROUT @labc LDA #'$' JSR CHROUT ; fetch operand to Long_AC LDY #0 STY Long_AC+1 @lpfop INY JSR Fetch STA Long_AC-1,Y CPY Op_Size BCC @lpfop ; interpret address modes LDX Op_Code LDA LEN_ADM,X AND #%00100000 ; branches LBNE @rel ; print 16 bit operand hi/lo or 8 bit operand BBR5 Op_Flag,@proper LDA Long_AC+1 JSR Print_Hex ; [$nn],Z LDA #']' JSR CHROUT BRA @labf @proper LDY Op_Size BBR7 Op_Flag,@lpoper LDY #1 @lpoper LDA Long_AC-1,Y JSR Print_Hex DEY BNE @lpoper BBR5 Adr_Flags,@labe ; comma flag LDA #',' JSR CHROUT BBR4 Adr_Flags,@labd ; SP flag LDA #'S' JSR CHROUT LDA #'P' JSR CHROUT @labd BBR0 Adr_Flags,@labe ; X flag LDA #'X' JSR CHROUT @labe BBR3 Adr_Flags,@labf ; ) flag LDA #')' JSR CHROUT @labf BBR4 Op_Flag,@comch ; not a Q instruction LDA Adr_Flags AND #3 CMP #1 BNE @return ; Q only with ,X @comch BBR2 Adr_Flags,@labg ; , flag LDA #',' JSR CHROUT LDA Adr_Flags AND #%00000011 ; $03 BEQ @labg TAY LDA Index_Char-1,Y JSR CHROUT ; fetch 2nd. operand for BBR and BBS @labg BBR7 Op_Flag,@return LDA #',' JSR CHROUT LDA #'$' JSR CHROUT LDY #2 JSR Fetch STA Long_AC LDA #0 STA Long_AC+1 DEY STY Op_Size ; Op_Size = 1 LDA #3 ; offset for relative address BRA @rela @rel LDA #2 ; offset for relative address @rela PHA LDA Op_Size ; 1:short 2:long LSR ROR AND Long_AC BPL @labh LDA #$ff ; backward branch STA Long_AC+1 @labh PLX ; offset 2 or 3 @lpinw INW Long_AC DEX BNE @lpinw CLC LDA Long_AC ADC Long_PC PHA LDA Long_AC+1 ADC Long_PC+1 TAX PLA JSR Print_XA_Hex BBR7 Op_Flag,@return INC Op_Size @return RTS ; ***** Got_LAC ; ***** DEC Buf_Index ; ***** Get_LAC ; ***** JSR Read_Number BCS @error ; illegal character BEQ @noval ; no value JSR Got_Char ; delimiter ? BEQ @end ; end of input CMP #' ' BEQ @ok CMP #',' BEQ @ok @error JMP Mon_Error ; stack is reset in Mon_Error @noval SEC RTS @end DEC Buf_Index @ok CLC RTS ; ********* Read_Number ; ********* PHX PHY PHZ LDA #0 STA Dig_Cnt ; count columns read STA Long_AC ; clear result Long_AC STA Long_AC+1 STA Long_AC+2 STA Long_AC+3 JSR Get_Glyph ; get 1st. character BEQ @exit CMP #KEY_APOSTROPHE ; character entry 'C BNE @numeric JSR Get_Char ; character after ' STA Long_AC INC Dig_Cnt BRA @exit @numeric LDY #3 ; $ + % % @prefix CMP Cons_Prefix,Y ; Y = base index BEQ @digit ; -> valid prefix DEY BPL @prefix INY ; Y = 0 DEC Buf_Index ; character is digit @digit JSR Get_Char ; hex -> BCD BEQ @exit ; ? : ; and zero terminate CMP #'0' BCC @exit CMP #':' BCC @valid ; 0-9 CMP #'A' BCC @exit CMP #'G' BCS @exit SBC #7 ; hex conversion @valid SBC #'0'-1 CMP Num_Base,Y BCS @error PHA ; push digit INC Dig_Cnt CPY #1 ; decimal BNE @laba LDX #3 ; push Long_AC * 2 CLC @push LDA Long_AC,X ROL PHA DEX BPL @push @laba LDX Num_Bits,Y @shift ASL Long_AC ROL Long_AC+1 ROW Long_AC+2 BCS @error ; overflow DEX BNE @shift CPY #1 ; decimal adjustment BNE @labc LDX #0 LDZ #3 CLC @pull PLA ADC Long_AC,X STA Long_AC,X INX DEZ BPL @pull @labc PLA ; pull digit CLC ADC Long_AC STA Long_AC BCC @digit INC Long_AC+1 BNE @digit INW Long_AC+2 BNE @digit @error SEC BRA @return @exit CLC @return PLZ PLY PLX LDA Dig_Cnt ; digits read RTS ; ***** Hex_LPC ; ***** LDX Long_PC+3 BEQ @laba LDA #KEY_YELLOW JSR CHROUT TXA JSR Print_Hex LDA Long_PC+2 JSR Print_Hex LDA #KEY_WHITE JSR CHROUT BRA @labb @laba LDA Long_PC+2 BEQ @labb JSR Print_Hex @labb LDX Long_PC+1 LDA Long_PC ; ********** Print_XA_Hex ; ********** PHA TXA JSR Print_Hex PLA ; ************* Print_Hex_Blank ; ************* JSR Print_Hex ; ********* Print_Blank ; ********* LDA #' ' JMP CHROUT ; ****** Print_CR ; ****** LDA #13 JMP CHROUT ; ****** CR_Erase ; ****** JSR PRIMM !pet KEY_RETURN, KEY_ESC, "q",0 RTS ; ******* Print_Hex ; ******* PHX JSR A_To_Hex JSR CHROUT TXA PLX JMP CHROUT ; ****** A_To_Hex ; ****** PHA JSR @nibble TAX PLA LSR LSR LSR LSR @nibble AND #15 CMP #10 BCC @lab ADC #6 @lab ADC #'0' RTS ; ******* Get_Glyph ; ******* PHX LDA #' ' @loop LDX Buf_Index INC Buf_Index CMP BUF,X BEQ @loop PLX ; fall through ; ****** Got_Char ; ****** DEC Buf_Index ; ****** Get_Char ; ****** PHX LDX Buf_Index INC Buf_Index LDA BUF,X CPX #1 PLX BCC @regc CMP #';' ; register BEQ @return CMP #'?' ; help BEQ @return @regc CMP #0 BEQ @return CMP #':' @return RTS ; ***** Dec_LCT ; ***** LDA Long_CT ORA Long_CT+1 BNE @skip DEW Long_CT+2 @skip DEW Long_CT LDA Long_CT+3 ; set N flag RTS ; ***** Add_LPC ; ***** CLC ADC Long_PC STA Long_PC BCC Inc_LPC_Page_return ; ********** Inc_LPC_Page ; ********** INC Long_PC+1 BNE Inc_LPC_Page_return INW Long_PC+2 Inc_LPC_Page_return RTS ; ********* Param_Range ; ********* ; read two (address) parameters ; Long_CT = difference (2nd. minus 1st.) ; Long_PC = 1st. parameter ; Long_DA = 2nd. parameter ; carry on exit flags error JSR Get_LAC ; get 1st. parameter BCS @error JSR LAC_To_LPC ; Long_PC = 1st. address JSR Get_LAC BCS @error JSR LAC_To_LDA ; Long_DA = 2nd. address JSR LAC_Minus_LPC ; Long_CT = range BCC @error CLC RTS @error SEC RTS ; ******* Converter ; ******* LDX #0 STX Buf_Index JSR Get_LAC LBCS Mon_Error LDX #0 @loop PHX JSR CR_Erase LDA Cons_Prefix,X JSR CHROUT TXA ASL TAX JSR (Conv_Tab,X) PLX INX CPX #4 BCC @loop JMP Main Conv_Tab !word Print_Hexval !word Print_Decimal !word Print_Octal !word Print_Dual ; ******** Print_Dual ; ******** LDX #24 ; digits LDY #1 ; bits per digit BRA Print_Octal_entry ; ********* Print_Octal ; ********* LDX #8 ; digits LDY #3 ; bits per digit Print_Octal_entry JSR LAC_To_LCT LDZ #0 STZ Long_PC LDZ #'0' PHY ; save start value @loopa PLY ; reinitialise PHY LDA #0 @loopb ASL Long_CT ROW Long_CT+1 ROL DEY BNE @loopb CPX #1 ; print last character BEQ @skip ORA Long_PC BEQ @next @skip ORA #'0' STZ Long_PC JSR CHROUT @next DEX BNE @loopa PLY ; cleanup stack RTS ; ********** Print_Hexval ; ********** JSR LAC_To_LPC LDA #0 STA Long_PC+3 BRA Print_BCD ; *********** Print_Decimal ; *********** ; max $ffffff = 16777215 (8 digits) JSR LAC_To_LCT LDX #3 ; 4 BCD bytes = 8 digits LDA #0 @clear STA Long_PC,X DEX BPL @clear LDX #32 ; source bits SED @loop ASL Long_CT ROL Long_CT+1 ROW Long_CT+2 LDA Long_PC ADC Long_PC STA Long_PC LDA Long_PC+1 ADC Long_PC+1 STA Long_PC+1 LDA Long_PC+2 ADC Long_PC+2 STA Long_PC+2 LDA Long_PC+3 ADC Long_PC+3 STA Long_PC+3 DEX BNE @loop CLD ; ******* Print_BCD ; ******* LDA #0 STA Long_CT LDZ #'0' LDY #8 ; max. digits @loopa LDX #3 ; 4 bytes LDA #0 @loopb ASL Long_PC ROL Long_PC+1 ROW Long_PC+2 ROL DEX BPL @loopb CPY #1 ; print last character BEQ @skip ORA Long_CT BEQ @next @skip ORA #'0' STZ Long_CT CMP #$3a BCC @print ADC #6 ; + carry @print JSR CHROUT @next DEY BNE @loopa RTS ; ************* Get_Disk_Status ; ************* LDA FA JSR TALK LDA #$6f JSR TKSA JSR ACPTR ; 1st. digit STA Disk_Msg ASL ASL ASL ASL STA Disk_Status ; BCD JSR ACPTR ; 2nd. digit STA Disk_Msg+1 AND #15 ORA Disk_Status STA Disk_Status ; complete BCD number LDY #1 @loop INY JSR ACPTR STA Disk_Msg,Y CMP #' ' BCS @loop LDA #0 STA Disk_Msg,Y JSR UNTLK LDA Disk_Status RTS ; *************** Print_Disk_Status ; *************** JSR Get_Disk_Status ; ************ Print_Disk_Msg ; ************ JSR Print_CR LDY #0 @loop LDA Disk_Msg,Y BEQ @exit JSR CHROUT INY BRA @loop @exit JMP Print_CR ; ***** Mon_DOS ; ***** ; XXX for Open ROMs it should invoke internal DOS wedge! jmp Main ; *** DOS_U ; XXX connect it somehow to command list ; *** ; @[u],U1 mem track startsec [endsec] : read disk sector(s) ; @[u],U2 mem track startsec [endsec] : write disk sector(s) JSR Get_Char CMP #'1' ; U1: read LBCC Mon_Error CMP #'3' ; U2: write LBCS Mon_Error STA MON_DATA+1 ; U type INC Buf_Index JSR Get_LAC LBCS Mon_Error JSR LAC_To_LPC ; Long_PC = memory address JSR Get_LAC LBCS Mon_Error LDA Long_AC STA MON_Disk_Track JSR Get_LAC LBCS Mon_Error LDA Long_AC STA MON_Disk_Sector JSR Get_LAC JSR LAC_To_LCT ; Long_CT = sector count DEW Long_CT ; Long_CT = -1 for single JSR Open_Disk_Buffer @loop LDA MON_DATA+1 LSR BEQ @write JSR Find_next_Sector BNE @error JSR Read_Sector BRA @next @write JSR Write_Sector JSR Find_next_Sector BNE @error @next JSR Inc_LPC_Page INC MON_Disk_Sector DEW Long_CT BPL @loop @error JSR Print_Disk_Msg JSR Close_Disk_Buffer JMP Main ; ************** Find_next_Sector ; ************** JSR Build_U_String JSR Send_Disk_Command JSR Get_Disk_Status BEQ @return ; OK CMP #$66 ; illegal track or sector BNE @error ; error LDA #0 STA MON_Disk_Sector INC MON_Disk_Track ; try next track JSR Build_U_String JSR Send_Disk_Command JSR Get_Disk_Status BEQ @return @error JSR Print_Disk_Msg LDA Disk_Status @return RTS ; ****************** Open_Command_Channel ; ****************** LDA FA JSR LISTEN LDA #$ff JSR SECOND LDY #0 STY IOSTATUS RTS ; ****** Reset_BP ; ****** JSR Open_Command_Channel @loop LDA BP_ZERO,Y BEQ @end JSR CIOUT INY BRA @loop @end JMP UNLSN ; *************** Send_Disk_Command ; *************** JSR Open_Command_Channel @loop LDA MON_DATA,Y BEQ @end JSR CIOUT INY BRA @loop @end JMP UNLSN ; ********* Read_Sector ; ********* LDA FA JSR TALK LDA #$69 ; SA = 9 JSR TKSA LDZ #0 STZ IOSTATUS @loop JSR ACPTR STA [Long_PC],Z INZ BNE @loop JMP UNTLK ; ********** Write_Sector ; ********** JSR Reset_BP ; reset disk buffer pointer LDA FA JSR LISTEN LDA #$69 ; SA = 9 JSR TKSA LDZ #0 STZ IOSTATUS @loop LDA [Long_PC],Z JSR CIOUT INZ BNE @loop JSR UNLSN RTS ; **** Set_TS ; **** ; Input A = track or sector ; X = string index @100 CMP #100 BCC @10 INC MON_DATA,X SBC #100 BRA @100 @10 CMP #10 BCC @1 INC MON_DATA+1,X SBC #10 BRA @10 @1 ORA #'0' STA MON_DATA+2,X RTS ; @[u],U1 mem track startsec [endsec] : read disk sector(s) ; U1:CHANNEL DRIVE TRACK SECTOR ; ************ Build_U_String ; ************ LDX #14 @loop LDA U1,X STA MON_DATA,X DEX CPX #2 BCS @loop LDA #'U' STA MON_DATA LDA MON_Disk_Track LDX #7 JSR Set_TS LDA MON_Disk_Sector LDX #11 JMP Set_TS ; ************** Open_Disk_Buffer ; ************** LDA #0 STA IOSTATUS LDA FA JSR LISTEN ; open fa,9,"#" LDA #$f9 ; sa = 9 JSR SECOND LDA #'#' ; open buffer JSR CIOUT JSR UNLSN LDA IOSTATUS LBNE Print_Disk_Status RTS ; *************** Close_Disk_Buffer ; *************** LDA #0 STA IOSTATUS LDA FA JSR LISTEN ; open fa,9,"#" LDA #$e9 ; sa = 9 JSR SECOND JSR UNLSN LDA IOSTATUS LBNE Print_Disk_Status RTS ; The 3 letter mnemonics are encoded as three 5-bit values ; and stored in a left byte MNE_L and a right byte MNE_R ; The 5 bit value is computed by subtracting $3f from the ; ASCII value, so '?'-> 0, '@'->1, 'A'->2, 'B'->3,'Z'->27 ; For example "ADC" is encoded as 2, 5, 4 ; ---------------- ; 7654321076543210 ; 00010 ; 00101 ; 00100 ; 0 ; !set ENC_A = %00000010 !set ENC_B = %00000011 !set ENC_C = %00000100 !set ENC_D = %00000101 !set ENC_E = %00000110 !set ENC_F = %00000111 !set ENC_G = %00001000 !set ENC_H = %00001001 !set ENC_I = %00001010 !set ENC_J = %00001011 !set ENC_K = %00001100 !set ENC_L = %00001101 !set ENC_M = %00001110 !set ENC_N = %00001111 !set ENC_O = %00010000 !set ENC_P = %00010001 !set ENC_Q = %00010010 !set ENC_R = %00010011 !set ENC_S = %00011000 !set ENC_T = %00011001 !set ENC_U = %00011010 !set ENC_V = %00011011 !set ENC_W = %00011100 !set ENC_X = %00011101 !set ENC_Y = %00011110 !set ENC_Z = %00011111 !set ENC_ADC = (ENC_A * 32 * 32 + ENC_D * 32 + ENC_C) * 2 !set ENC_AND = (ENC_A * 32 * 32 + ENC_N * 32 + ENC_D) * 2 !set ENC_ASL = (ENC_A * 32 * 32 + ENC_S * 32 + ENC_L) * 2 !set ENC_ASR = (ENC_A * 32 * 32 + ENC_S * 32 + ENC_R) * 2 !set ENC_ASW = (ENC_A * 32 * 32 + ENC_S * 32 + ENC_W) * 2 !set ENC_BBR = (ENC_B * 32 * 32 + ENC_B * 32 + ENC_R) * 2 !set ENC_BBS = (ENC_B * 32 * 32 + ENC_B * 32 + ENC_S) * 2 !set ENC_BCC = (ENC_B * 32 * 32 + ENC_C * 32 + ENC_C) * 2 !set ENC_BCS = (ENC_B * 32 * 32 + ENC_C * 32 + ENC_S) * 2 !set ENC_BEQ = (ENC_B * 32 * 32 + ENC_E * 32 + ENC_Q) * 2 !set ENC_BIT = (ENC_B * 32 * 32 + ENC_I * 32 + ENC_T) * 2 !set ENC_BMI = (ENC_B * 32 * 32 + ENC_M * 32 + ENC_I) * 2 !set ENC_BNE = (ENC_B * 32 * 32 + ENC_N * 32 + ENC_E) * 2 !set ENC_BPL = (ENC_B * 32 * 32 + ENC_P * 32 + ENC_L) * 2 !set ENC_BRA = (ENC_B * 32 * 32 + ENC_R * 32 + ENC_A) * 2 !set ENC_BRK = (ENC_B * 32 * 32 + ENC_R * 32 + ENC_K) * 2 !set ENC_BSR = (ENC_B * 32 * 32 + ENC_S * 32 + ENC_R) * 2 !set ENC_BVC = (ENC_B * 32 * 32 + ENC_V * 32 + ENC_C) * 2 !set ENC_BVS = (ENC_B * 32 * 32 + ENC_V * 32 + ENC_S) * 2 !set ENC_CLC = (ENC_C * 32 * 32 + ENC_L * 32 + ENC_C) * 2 !set ENC_CLD = (ENC_C * 32 * 32 + ENC_L * 32 + ENC_D) * 2 !set ENC_CLE = (ENC_C * 32 * 32 + ENC_L * 32 + ENC_E) * 2 !set ENC_CLI = (ENC_C * 32 * 32 + ENC_L * 32 + ENC_I) * 2 !set ENC_CLV = (ENC_C * 32 * 32 + ENC_L * 32 + ENC_V) * 2 !set ENC_CMP = (ENC_C * 32 * 32 + ENC_M * 32 + ENC_P) * 2 !set ENC_CPX = (ENC_C * 32 * 32 + ENC_P * 32 + ENC_X) * 2 !set ENC_CPY = (ENC_C * 32 * 32 + ENC_P * 32 + ENC_Y) * 2 !set ENC_CPZ = (ENC_C * 32 * 32 + ENC_P * 32 + ENC_Z) * 2 !set ENC_DEC = (ENC_D * 32 * 32 + ENC_E * 32 + ENC_C) * 2 !set ENC_DEW = (ENC_D * 32 * 32 + ENC_E * 32 + ENC_W) * 2 !set ENC_DEX = (ENC_D * 32 * 32 + ENC_E * 32 + ENC_X) * 2 !set ENC_DEY = (ENC_D * 32 * 32 + ENC_E * 32 + ENC_Y) * 2 !set ENC_DEZ = (ENC_D * 32 * 32 + ENC_E * 32 + ENC_Z) * 2 !set ENC_EOR = (ENC_E * 32 * 32 + ENC_O * 32 + ENC_R) * 2 !set ENC_INC = (ENC_I * 32 * 32 + ENC_N * 32 + ENC_C) * 2 !set ENC_INW = (ENC_I * 32 * 32 + ENC_N * 32 + ENC_W) * 2 !set ENC_INX = (ENC_I * 32 * 32 + ENC_N * 32 + ENC_X) * 2 !set ENC_INY = (ENC_I * 32 * 32 + ENC_N * 32 + ENC_Y) * 2 !set ENC_INZ = (ENC_I * 32 * 32 + ENC_N * 32 + ENC_Z) * 2 !set ENC_JMP = (ENC_J * 32 * 32 + ENC_M * 32 + ENC_P) * 2 !set ENC_JSR = (ENC_J * 32 * 32 + ENC_S * 32 + ENC_R) * 2 !set ENC_LDA = (ENC_L * 32 * 32 + ENC_D * 32 + ENC_A) * 2 !set ENC_LDX = (ENC_L * 32 * 32 + ENC_D * 32 + ENC_X) * 2 !set ENC_LDY = (ENC_L * 32 * 32 + ENC_D * 32 + ENC_Y) * 2 !set ENC_LDZ = (ENC_L * 32 * 32 + ENC_D * 32 + ENC_Z) * 2 !set ENC_LSR = (ENC_L * 32 * 32 + ENC_S * 32 + ENC_R) * 2 !set ENC_MAP = (ENC_M * 32 * 32 + ENC_A * 32 + ENC_P) * 2 !set ENC_NEG = (ENC_N * 32 * 32 + ENC_E * 32 + ENC_G) * 2 !set ENC_NOP = (ENC_N * 32 * 32 + ENC_O * 32 + ENC_P) * 2 !set ENC_ORA = (ENC_O * 32 * 32 + ENC_R * 32 + ENC_A) * 2 !set ENC_PHA = (ENC_P * 32 * 32 + ENC_H * 32 + ENC_A) * 2 !set ENC_PHP = (ENC_P * 32 * 32 + ENC_H * 32 + ENC_P) * 2 !set ENC_PHW = (ENC_P * 32 * 32 + ENC_H * 32 + ENC_W) * 2 !set ENC_PHX = (ENC_P * 32 * 32 + ENC_H * 32 + ENC_X) * 2 !set ENC_PHY = (ENC_P * 32 * 32 + ENC_H * 32 + ENC_Y) * 2 !set ENC_PHZ = (ENC_P * 32 * 32 + ENC_H * 32 + ENC_Z) * 2 !set ENC_PLA = (ENC_P * 32 * 32 + ENC_L * 32 + ENC_A) * 2 !set ENC_PLP = (ENC_P * 32 * 32 + ENC_L * 32 + ENC_P) * 2 !set ENC_PLX = (ENC_P * 32 * 32 + ENC_L * 32 + ENC_X) * 2 !set ENC_PLY = (ENC_P * 32 * 32 + ENC_L * 32 + ENC_Y) * 2 !set ENC_PLZ = (ENC_P * 32 * 32 + ENC_L * 32 + ENC_Z) * 2 !set ENC_RMB = (ENC_R * 32 * 32 + ENC_M * 32 + ENC_B) * 2 !set ENC_ROL = (ENC_R * 32 * 32 + ENC_O * 32 + ENC_L) * 2 !set ENC_ROR = (ENC_R * 32 * 32 + ENC_O * 32 + ENC_R) * 2 !set ENC_ROW = (ENC_R * 32 * 32 + ENC_O * 32 + ENC_W) * 2 !set ENC_RTI = (ENC_R * 32 * 32 + ENC_T * 32 + ENC_I) * 2 !set ENC_RTS = (ENC_R * 32 * 32 + ENC_T * 32 + ENC_S) * 2 !set ENC_SBC = (ENC_S * 32 * 32 + ENC_B * 32 + ENC_C) * 2 !set ENC_SEC = (ENC_S * 32 * 32 + ENC_E * 32 + ENC_C) * 2 !set ENC_SED = (ENC_S * 32 * 32 + ENC_E * 32 + ENC_D) * 2 !set ENC_SEE = (ENC_S * 32 * 32 + ENC_E * 32 + ENC_E) * 2 !set ENC_SEI = (ENC_S * 32 * 32 + ENC_E * 32 + ENC_I) * 2 !set ENC_SMB = (ENC_S * 32 * 32 + ENC_M * 32 + ENC_B) * 2 !set ENC_STA = (ENC_S * 32 * 32 + ENC_T * 32 + ENC_A) * 2 !set ENC_STX = (ENC_S * 32 * 32 + ENC_T * 32 + ENC_X) * 2 !set ENC_STY = (ENC_S * 32 * 32 + ENC_T * 32 + ENC_Y) * 2 !set ENC_STZ = (ENC_S * 32 * 32 + ENC_T * 32 + ENC_Z) * 2 !set ENC_TAB = (ENC_T * 32 * 32 + ENC_A * 32 + ENC_B) * 2 !set ENC_TAX = (ENC_T * 32 * 32 + ENC_A * 32 + ENC_X) * 2 !set ENC_TAY = (ENC_T * 32 * 32 + ENC_A * 32 + ENC_Y) * 2 !set ENC_TAZ = (ENC_T * 32 * 32 + ENC_A * 32 + ENC_Z) * 2 !set ENC_TBA = (ENC_T * 32 * 32 + ENC_B * 32 + ENC_A) * 2 !set ENC_TRB = (ENC_T * 32 * 32 + ENC_R * 32 + ENC_B) * 2 !set ENC_TSB = (ENC_T * 32 * 32 + ENC_S * 32 + ENC_B) * 2 !set ENC_TSX = (ENC_T * 32 * 32 + ENC_S * 32 + ENC_X) * 2 !set ENC_TSY = (ENC_T * 32 * 32 + ENC_S * 32 + ENC_Y) * 2 !set ENC_TXA = (ENC_T * 32 * 32 + ENC_X * 32 + ENC_A) * 2 !set ENC_TXS = (ENC_T * 32 * 32 + ENC_X * 32 + ENC_S) * 2 !set ENC_TYA = (ENC_T * 32 * 32 + ENC_Y * 32 + ENC_A) * 2 !set ENC_TYS = (ENC_T * 32 * 32 + ENC_Y * 32 + ENC_S) * 2 !set ENC_TZA = (ENC_T * 32 * 32 + ENC_Z * 32 + ENC_A) * 2 ; *** MNE_L ; *** !byte >ENC_ADC, >ENC_AND, >ENC_ASL, >ENC_ASR, >ENC_ASW, >ENC_BBR, >ENC_BBS, >ENC_BCC !byte >ENC_BCS, >ENC_BEQ, >ENC_BIT, >ENC_BMI, >ENC_BNE, >ENC_BPL, >ENC_BRA, >ENC_BRK !byte >ENC_BSR, >ENC_BVC, >ENC_BVS, >ENC_CLC, >ENC_CLD, >ENC_CLE, >ENC_CLI, >ENC_CLV !byte >ENC_CMP, >ENC_CPX, >ENC_CPY, >ENC_CPZ, >ENC_DEC, >ENC_DEW, >ENC_DEX, >ENC_DEY !byte >ENC_DEZ, >ENC_EOR, >ENC_INC, >ENC_INW, >ENC_INX, >ENC_INY, >ENC_INZ, >ENC_JMP !byte >ENC_JSR, >ENC_LDA, >ENC_LDX, >ENC_LDY, >ENC_LDZ, >ENC_LSR, >ENC_MAP, >ENC_NEG !byte >ENC_NOP, >ENC_ORA, >ENC_PHA, >ENC_PHP, >ENC_PHW, >ENC_PHX, >ENC_PHY, >ENC_PHZ !byte >ENC_PLA, >ENC_PLP, >ENC_PLX, >ENC_PLY, >ENC_PLZ, >ENC_RMB, >ENC_ROL, >ENC_ROR !byte >ENC_ROW, >ENC_RTI, >ENC_RTS, >ENC_SBC, >ENC_SEC, >ENC_SED, >ENC_SEE, >ENC_SEI !byte >ENC_SMB, >ENC_STA, >ENC_STX, >ENC_STY, >ENC_STZ, >ENC_TAB, >ENC_TAX, >ENC_TAY !byte >ENC_TAZ, >ENC_TBA, >ENC_TRB, >ENC_TSB, >ENC_TSX, >ENC_TSY, >ENC_TXA, >ENC_TXS !byte >ENC_TYA, >ENC_TYS, >ENC_TZA ; *** MNE_R ; *** !byte - . address mnemonic operand",KEY_RETURN !pet KEY_LT_RED,">",KEY_WHITE," - > address byte sequence",KEY_RETURN !pet KEY_LT_RED,";",KEY_WHITE," - ; register contents",KEY_RETURN !pet KEY_LT_RED,"@",KEY_WHITE,"dos - @ [dos command]",KEY_RETURN !pet KEY_LT_RED,"?",KEY_WHITE,"help - ?",KEY_RETURN !pet 0 JMP Main