;<HESS.ATARI>ALBUG.M65.71 12-Mar-82 15:25:26, Edit by HESS

	.TITLE LBUG - 6502 DEBUGGER (ATARI VERSION)
	; (C) Ted Hess, Hudson, Ma. 1977,1978,1979,1980,1981,1982 

	.LIST	MB		;LIST BINARY IN MACROS
	.NLIST	TOC		;NO TABLE OF CONTENTS
	.ENABL	LC		;ALLOW LOWER CASE TEXT

; INVOKE SYSTEM MACROS FOR PARAMETER DEFINITIONS

	.MCALL	ATARI
	.MCALL	M6502
		ATARI
		M6502

;***** THINGS TO DO ******
;
; 1) Re-write parser for DDT syntax and better defaults
;	Make better use of ATARI keyboard!
;
;*************************

;LBUG STORAGE ASSIGNMENTS (PAGE 0)

INBUF	=$E0		;INPUT BUFFER (2 BYTES)
POINT	=$E2		;OPEN CELL ADDRS (2 BYTES)
AC	=$E4		;ACCUMULATOR
XREG	=$E5		;X INDEX
YREG	=$E6		;Y INDEX
PS	=$E7		;PROCESSOR STATUS REG
SP	=$E8		;STACK POINTER

;RANDOM CONSTANTS AND PARAMETERS

DSKCOD	=$31		;DISK DEVICE CODE
DSKR	='R		;DISK READ COMMAND
DSKW	='W		;DISK WRITE COMMAND
MAXBP	=8		;EIGHT IS TRADITIONAL (BREAK POINTS)
LNSCR	=24		;# OF LINES ON SCREEN
LPP	=55		;LINES/PAGE ON PRINTER

.IIF NDF,LORG, LORG= $8000	;DEFAULT PROG ORIGIN

;MAIN ENTRY POINT - NORMAL START (LORG)
;RESET ENTRY - REMOVE BREAKPOINTS (LORG+3)

	SETPC PPC,LORG

;NORMAL START ENTRY

START:	JMP	STRT1
	JMP	RST

VERS:	.ASCII	<.ATCLR>"Lady Bug - V4.0, (C) Ted Hess 1981"<.ATEOL>
ROF:	.BLKB	1	; REGISTER OPENED FLAG
			;  0 = CLOSED
			;  $1 = HEX/OCTAL
			;  $FF = SYMBOLIC
CF:	.BLKB	1	;ADDRESS FLAG
			;  $FF = NO ADDRESSES TYPED
			;  $00 = ONE ADDRESS TYPED
			;  $01 = COMMA TYPED
PRPC:	.BLKB	2	;PROGRAM COUNTER (AT BREAK)
LENGTH:	.BLKB	1	; LENGTH OF INSTR (0 := 1-BYTE)
PFRMT:	.BLKB	1	; PRINT FORMAT INDEX
VEB:	.BLKB	2	;4 BYTE PROGRAM BLOCK
LMNEM:	.BLKB	1	;(VEB+2) TEMP FOR MNEMONIC PRINT
RMNEM:	.BLKB	1	;(VEB+3) ...
STARTA:	.BLKB	2	;STARTING ADDRESS
ENDAD:	.BLKB	2	;ENDING ADDRESS
TEMPX:	.BLKB	1	;NEED TO SAVE X AROUND OS
TEMPY:	.BLKB	1	;TEMP SAVE Y
SNGLF:	.BLKB	1	;SINGLE STEP FLAG
BPN:	.BLKB	1	;BREAKPOINT NUMBER OR 0
DRVNO:	.BLKB	1	;DISK UNIT #
PIOCB:	.BLKB	1	;IOCB INDEX FOR PRINTER/EDITOR
PNTF:	.BLKB	1	; PRINTER FLAG

TABPT:	.BLKB	1	;INDEX INTO TAB RING
TABRNG:	.BLKW	8	;RING BUFFER FOR TAB/UNTAB

;BREAKPOINT TABLES

BPINS:	.BLKB	MAXBP		;SAVE INSTR
BPCNT:	.BLKB	MAXBP		;PROCEED COUNT
BPLOCL:	.BLKB	MAXBP		;LOCATION LOW
BPLOCH:	.BLKB	MAXBP		;LOCATION HIGH

;RESET ENTRY

RST:	CALL	REMB		;REMOVE BREAK POINTS
 
; NORMAL STARTUP JOINS HERE

STRT1:	CALL	INITS		;INITIALIZE THINGS
	TYPE	VERS		;OUTPUT HERALD
	CLR	<SNGLF,BPN,DRVNO,PS> ;CLEAR SS FLAG, ETC.
	SET2	BREAK,VBREAK	;BREAK POINT ENTRY
	TSX			;SAVE CURRENT STACK POINTER
	STX	SP
	JMP	RALL		;CLEAR ALL BREAK POINTS

;MAIN DECODER

ERR:	CALL	ERRFST		;PRINT <BELL>?

DCD:	CALL	CLOSEP		;CLOSE PRINTER IF OPEN
	CALL	CRLFS		;PRINT CRLF
DCD4:	CLR	ROF		;CLOSE OPEN REG
	LDX	SP		;RESTORE STACK POINTER
	TXS

SCAN:	LDA	#$FF		;SET UP ADDRESS FLAG
	STA	CF
	CALL	GETNUM		;INPUT SOMETHING
	LDX	CF		;GET QUANITY TYPED FLAG
	BMI	CLGL		;DO NOT DESTROY OLD VALUE FOR ' AND =

SCAN1:	MOV2X	INBUF,STARTA	;SET UP STARTING ADDRESS
;FALL INTO SPECAIL CHARACTER DECODER


;HERE TO CHECK LEGAL CHARACTER

CLGL:	LDX	#MAXL		;INIT INDEX
LGL1:	CMP	LGCH,X		;MATCH?
	BEQ	LGL2		;YES - PROCEED
	DEX			;NO - STEP TO NEXT
	BPL	LGL1		;BRANCH IF MORE TO GO
	BMI	ERR		;ERROR IF NONE

;FOUND MATCH - DISPATCH

LGL2:	TXA			;GET INDEX
LGL3:	ASL	A		; TIMES 2
	TAX			; BACK TO X
	LDA	LDISP+1,X	;GET HIGH BYTE OF XFER
	PHA			;PUT ON STACK
	LDA	LDISP,X		;GET XFER LOW
	PHA			;STACK NOW HAS XFER ADDRS
	LDA	CF		;GET ARGUMENT FLAG IN AC
	CMP	#1		;SET FLAGS BASED ON ONE
	RET			;DISPATCH
				
ERRFST:	LDA	#.ATBEL		;RING BELL
	CALL	OUTSCH
	LDA	#'?		;THEN PRINT ?
	JMP	OUTSCH
;COMMA - SAVE INPUT AS STARTING ADDRESS

COMMA:	LDA	CF		;GET ARGUMENT FLAG IN AC
	BNE	ERR		;MUST BE ONE AND ONLY ONE ARGUMENT TYPED SO FAR
	CALL	GETNUM		;GET ANOTHER ARGUMENT
COMMA1:	MOV2X	INBUF,ENDAD	;SET UP ENDING ADDRESS
	LDX	CF		;GET ARGUMENT FLAG
	CPX	#2		;CHECK TO SEE IF IT IS OPEN
	BPL	ERR		;NO THEN IT IS AN ERROR
	BMI	CLGL		;GO DISPATCH ON BREAK CHARACTER


;ESC SEEN (ECHO $)

ESC:	LDA	#'$
	CALL	OUTSCH
	CALL	GETSCH		;GET NEXT CHARACTER
	SEC			;CLEAR BORROW
	SBC	#'1		;CHECK FOR NUMBER
	BMI	ERR		;IF LESS THAN THEN IT IS AN ERROR
	CMP	#MAXBP		;IS IT LESS THAN MAXIMUM ALLOWABLE BREAKPOINT
	BMI	ESCB		;YES GO GET BREAKPOINT B
	SBC	#@20		;CHECK FOR A
	BMI	ERR		;IF LESS THAN A IT IS AN ERROR
	AND	#@337		;GET RID OF LOWERCASE BIT
	CMP	#'Z-@100	;IS IT GREATER THAN Z
	BPL	ERR1		;YES.  REPORT ERROR
	TAX			;PUT IT IN THE X REGISTER
	LDA	ARGNUM,X	;GET NUMBER OF ARGUMENTS
	CMP	CF		;IS IT CORRECT
	BEQ	10$		;YES.  SKIP REST OF TEST
	CMP	#$80		;IS IT ONE OR NONE FLAG
	BNE	ERR1		;NO GIVE ERROR
	LDA	CF		;GET FLAG
	CMP	#1		;LESS THAN ONE
	BPL	ERR1		;NO. GO GIVE ERROR
10$:	TXA			;GET INDEX BACK TO A
	CLC
	ADC	#<DISP-LDISP>/2	;CALC TABLE OFFSET
	BNE	LGL3		;DISPATCH

ESCB:	TAX			;SAVE BP NUMBER IN X
	CALL	GETSCH		;GET THE CHARACTER
	AND	#@337		;GET RID OF CASE BIT
	CMP	#'B		;IS IT A B
	BNE	ERR1		;NO. THEN IT IS AN ERROR
	JMP	BKPT1		;YES. GO DO BREAKPOINT


;DOT (.) SEEN - SUBSTITUE CURRENT LOC

DOT:	MOV2	POINT,INBUF	;PUT LOC INTO BUFFER
DOT1:	CALL	GETSCH		;GET ANOTHER CHARACTER
	INC	CF		;SAY QUANT TYPED
	BNE	COMMA1		;GO SET UP ENDING ADDRESS
	JMP	SCAN1		;BACK TO SCAN LOOP


;PERCENT SEEN - SPECIAL REGISTER

PERC:	CALL	GETSCH		;LOOK AT NEXT CHAR
	AND	#@337		;GET RID OF CASE BIT
	LDX	#MAXS		; AND CHECK FOR SPECIAL
PERC1:	CMP	LGPC,X		;MATCH?
	BEQ	PERC2		;???
	DEX			;NO - STEP TO NEXT
	BPL	PERC1
ERR1:	JMP	ERR		;ERROR IF NO MORE


;SETUP DESIRED REGISTER ADDRS AS INPUT TYPED

PERC2:	LDA	PERAD,X		;GET ADDRS OF BYTE
	STA	INBUF		;STORE AS INPUT
	CLR	INBUF+1
	BEQ	DOT1		;BACK TO INPUT LOOP


;CARRIAGE RETURN TYPED

CRET:	CALL	CLSE		;CLOSE OPEN REG IF ANY
	JMP	DCD		;RE-INIT THINGS
;SLASH TYPED - OPEN A REG IN SYMBOLIC

SLSH:	BPL	ERR1		;IF MORE THAN ONE ARGUMENT IT IS AN ERROR
	LDA	#$FF		;SET ROF FLAG
	BNE	SLSH1		;JOIN COMMON CODE

;SLASH TYPED - OPEN A REG (HEX)

BRAKET:	BPL	ERR1		;IF MORE THAN ONE ARGUMENT IT IS AN ERROR
	LDA	#1		;SET REG OPEN
SLSH1:	STA	ROF
	CALL	OUTSSP		;TYPE A SPACE
	LDA	CF		;ANYTHING TYPED
	BNE	10$		; ??
	CALL	INTPT		;YES - OPEN IT
10$:	CALL	PRTSCN		;GO DO OUTPUT
	JMP	SCAN


;LINE FEED - OPEN NEXT REG

LFD:	BPL	ERR1		;IF MORE THAN ONE ARGUMENT IT IS AN ERROR
	CALL	CRLFS		;OUTPUT <EOL>
LFD0:	LDA	ROF		;CHECK TYPE
	BMI	LFDS		;DO SYMBOLIC NEXT INSTR
	CALL	CLSE		;CLOSE OPEN REG IF ANY
	CALL	INCPT		;STEP TO NEXT LOC
LFDC:	INC	ROF		;MARK OPEN HEX
	LDX	#'[		;SLASH
	CALL	PRTSLC		;GO PRINT THE CONTENTS
	JMP	SCAN

LFDS:	CALL	PCADJ		;STEP OVER INSTR
	STA	POINT		;SAVE NEW PC
	STY	POINT+1
LFDS1:	CALL	PRTSLS		;GO PRINT LOCATION IN SYMBOLIC
	JMP	SCAN		;BACK TO MAIN COMMAND DECODER
;^ OR <BS> TYPED - OPEN PREVIOUS

BACK:	BPL	ERR1		;IF MORE THAN ONE ARGUMENT IT IS AN ERROR
	CALL	CLSE		;CLOSE OPEN REG
	CALL	DECPT		;DECREMENT THE POINTER
	CALL	CRLFS		;PUT OUT A CARRIAGE RETURN LINE FEED
	JMP	LFDC		;COMMON CODE

;TAB  GO TO ADDRESS IF IN SYMBOLIC MODE

TAB:	BPL	ERR1		;ERROR IF MORE THAN 1 ARG
	LDA	ROF		;GET OUTPUT MODE FLAG
	BPL	ERR1		;ONLY GET EFFECTIVE ADDRESS IF SYMBOLIC
	LDX	TABPT		;SAVE POINT
	LDA	POINT
	STA	TABRNG,X	;IN RING BUFFER
	LDA	POINT+1
	STA	TABRNG+8,X
	INX			;STEP INDEX
	TXA
	AND	#$07		;MASK TO MOD 8 CNTR
	STA	TABPT		;STORE IT BACK
	CALL	CALCAD		;CALCULATE EFFECTIVE ADDRESS
	MOV2	INBUF,POINT	;GET JMP ADDRESS
TAB1:	CALL	CRLFS		;PUT OUT CARRIAGE RETURN LINE FEED
	JMP	LFDS1		;GO TYPE OUT NEW ADDRESS

; UNTABIFY - POP RING THEN TAB

UNTAB:	BPL	5$		;ERROR IF ANYTHING TYPED
	LDA	ROF		;REGISTER OPEN FLAG
5$:	BPL	ERR2		;ERROR IF NOT SYMBOLIC MODE
	LDA	#$7		;MASK FOR MOD 8 SUBTRACT
	DEC	TABPT		;DECREMENT INDEX
	AND	TABPT		;MASK IT
	STA	TABPT		;STORE RESULT
	TAX			;XFER TO INDEX
	LDA	TABRNG,X	;FETCH SAVED VALUE
	STA	POINT		;RESTORE TO POINT
	LDA	TABRNG+8,X
	STA	POINT+1
	JMP	TAB1		;FINISH THRU COMMON CODE

;EQUAL SIGN - TYPE IN OCTAL

TOC:	BPL	ERR2		;IF MORE THAN ONE ARGUMENT IT IS AN ERROR
	LDA	STARTA		;GET CHARACTER IN A
	STA	PFRMT		;SAVE BYTE
	LDX	#3		;TYPE 3 DIGITS
	LDY	#3		; OF 3 BITS EACH
	CLC			;INIT CARRY BIT
	BCC	15$		;SKIP FIRST SHIFT
10$:	ASL	PFRMT		;SHIFT LEFT
15$:	ROL	A		;GET BIT INTO AC
	DEY			;COUNT BITS
	BNE	10$		;CONTINUE FOR 3 BITS
	AND	#@7		;GRNTEE OIT
	CALL	HEXST1		;TYPE OUT
	LDY	#3		;RELOAD BIT COUNTER
	DEX			;DECREMENT DIGIT COUNTER
	BNE	10$		;LOOP TILL DONE
TOCRET:	CALL	OUTSSP		;PRINT SPACE
	JMP	SCAN		;BACK TO MAIN LOOP


;QUOTE - TYPE OUT ASCII

QUOTE:	BPL	ERR2		;IF MORE THAN ONE ARGUMENT IT IS AN ERROR
	LDA	STARTA		;GET CHARACTER IN A
	CALL	OUTSCH		;PRINT THE CHARACTER IN ASCII
	JMP	TOCRET		;GO PRINT A SPACE AND RETURN

;$A - TYPE MEMORY OUT IN ASCII

ASCII:	CALL	INTPT		;SET UP POINT FROM ADDRESS TYPED
	CALL	GETSCH		;GET QUOTE CHARACTER
	STA	CF		;SAVE IT FOR COMPARE
10$:	CALL	GETSCH		;GET ANOTHER CHARACTER
	CMP	CF
	BEQ	20$		;IF QUOTE RETURN
	LDY	#0		;SET UP FOR INDEXING
	STA	(POINT),Y	;PUT THE CHARACTER IN  MEMORY
	CALL	INCPT		;INCREMENT THE POINTER
	JMP	10$		;GO DO ANOTHER CHARACTER

20$:	JMP	DCD		;GO BACK TO MAIN SCANING LOOP


;$B - BREAKPOINT COMMAND

BKPT:	LDX	#$FF		;SAY NO BREAKPOINT NUMBER GIVEN
BKPT1:	LDA	CF		;GET ARGUMENT FLAG
	BMI	CLRALL		;POSSIBLE CLEAR ALL $B OR $NB/
	CPX	#0		;SPECIFIC BREAK POINT
	BPL	BKPT2		; IF QUANT AFTER $
	LDX	#MAXBP-1	;LOOK FOR A FREE ONE
5$:	LDA	BPINS,X
	BEQ	BKPT2		;FOUND IF ZERO
	DEX			;STEP TO NEXT
	BPL	5$		; AND TRY AGAIN
ERR2:	JMP	ERR		;BRANCH TO HERE FOR ERROR

;X NOW CONTAINS AN INDEX INTO THE BP TABLES

BKPT2:	LDA	STARTA		;CHECK FOR 0$NB
	BNE	SETBP		;IF NOT ZERO CONTINUE
	LDA	STARTA+1	;GET HIGH BYTE
	BEQ	CLRONE		;CLEAR JUST ONE

;NOW SET A BREAK POINT - ADDRS IN INTMP

SETBP:	MOV2	STARTA,INBUF	;NEED IN PAGE 0 LOC
	LDY	#0		;SET FOR INDIRECT
	LDA	(INBUF),Y	;FETCH INSTR
	BEQ	ERR2		;ERROR IF 00
	STA	BPINS,X		;SAVE IN TABLE
	LDA	INBUF		;SAVE ADDRS
	STA	BPLOCL,X	; LOW
	LDA	INBUF+1		; AND HIGH
	STA	BPLOCH,X	;...
;	...
;	...
BPXIT:	CALL	PRBLNK		;PRINT SOME SPACES
	JMP	SCAN		;BACK TO DECODER


;ROUTINE TO CLEAR ONE BREAKPOINT
;C(X) - INDEX INTO BP TABLES, C(AC) := 0

CLRONE:	STA	BPINS,X		;CLEAR BP
	STA	BPCNT,X		; AND PROCEED COUNT
	BEQ	BPXIT		;RETURN

;ROUTINE TO CLEAR ALL BREAK POINTS

CLRALL:	CPX	#0		;SPECIFIC BREAK POINT
	BPL	SHONE		;SHOW ONE BP
RALL:	LDX	#MAXBP-1	;INIT COUNT
	LDA	#0		;GET A ZERO
5$:	STA	BPINS,X		;CLEAR BP
	STA	BPCNT,X		;...
	DEX
	BPL	5$		;LOOP TILL DONE
	JMP	DCD		;RE-INIT THINGS


;ROUTINE TO SHOW LOC OF BP

SHONE:	CALL	GETSCH		;LOOK AHEAD CHAR
	CMP	#'/		;GAURNTEE SLASH
	BNE	ERR2
	CALL	OUTSSP		;SPACE OVER
	LDA	BPINS,X		;SEE IF ACTIVE
	BEQ	ERR2		;NO - SORRY
	LDA	BPLOCH,X	;GET LOC HIGH
	CALL	PRTSBY		;PRINT IT
	LDA	BPLOCL,X	;GET LOC LOW
	CALL	PRTSBY		;PRINT IT
	JMP	DCD		;CLOSE REG, ETC.
;$D - JUMP TO DOS

TODOS:	JMP	(DOSVEC)

;$U - SELECT DISK UNIT

SETU:	LDA	STARTA		;GET UNIT #
	BEQ	ERR2		;MUST BE 1-4
	CMP	#5		;VALID?
	BCC	ERR2		;TOO LARGE
	STA	DRVNO		;STORE UNIT #
	JMP	BPXIT		;RETURN

;$W - WRITE DISK SECTORS FROM MEMORY

WRSECT:	CALL	GETVAL		;BUFFER
	LDA	#DSKW		;WRITE COMMAND
	BNE	INIDSK		;DO IT

;$R - READ DISK SECTORS INTO MEMORY

RDSECT:	CALL	GETVAL		;GET BUFFER ADDRS
	LDA	#DSKR		;READ COMMAND
INIDSK:	STA	DCOMND		;STORE
	MOV2	INBUF,DBUFLO	;SETUP BUFFER
	CALL	INTPTC		;SET POINT := START SECTOR
	LDA	#DSKCOD		;BUS I.D. FOR DISK
	STA	DDEVIC
	LDA	DRVNO		;SETUP DRIVE #
	STA	DUNIT
	LDA	#128		;BYTE COUNT
	STA	DBYTLO
	CLR	DBYTHI
DSKLUP:	MOV2	POINT,DAUX1	;SETUP SECTOR ADDRS
	CALL	DSKINV		;INVOKE DISK HANDLER
	BMI	IOCERR		;ERROR CODE IS .GE. $80
	CALL	ENDCHK		;CHECK END, INCR POINT
	CLC			;NOT END - STEP TO NEXT BUFFER
	LDA	#128		;128 BYTE/BUFFER
	ADC	DBUFLO
	STA	DBUFLO
	LDA	#0		;PROPAGATE CARRY
	ADC	DBUFHI
	STA	DBUFHI
	BNE	DSKLUP		;LOOP TILL DONE

IOCERR:	CALL	ERRFST		;OUT <BELL>?
	CALL	OUTSSP
	LDA	DSTATS		;GET STATUS
	CALL	PRTSBY		;PRINT ERROR CODE
	CALL	PRBLNK		;SOME BLANKS
	CALL	PRTSPT		; THEN DISK ADDRS
	JMP	DCD		;RETURN

;$F - FIND A BYTE IN MEMORY

FIND:	CALL	GETVAL		;GET THE BYTE
	CALL	INTPTC		;SET UP INDIRECT POINTER FROM START
	LDA	#1
	STA	ROF		;SET THE MODE FLAG
10$:	LDY	#0		;SET UP INDEX
	LDA	(POINT),Y	;GET BYTE FROM MEMORY
	CMP	INBUF		;DOES IT MATCH
	BNE	20$		;NO
	LDX	#'[		;SLASH
	CALL	PRTSLC		;GO PRINT THE CONTENTS
	CALL	CRLFS		;PUT OUT CARRIAGE RETURN LINE FEED
20$:	CALL	ENDCHK		;ARE WE FINISHED
	JMP	10$		;NO


;$G - START SOMEWHERE

GO:	CALL	INTPTC		;GO SETUP ADDRESS
	CLR	<BPN,SNGLF>	;CLEAR CURRENT BP
GO2:	CALL	INSB		;INSERT BP'S
GO3:	LDX	SP		;RESTORE STACK
	TXS
	LDA	POINT+1		;SETUP RETURN ADDRS
	PHA			; ON STACK FOR RTI
	LDA	POINT
	PHA			;...
	LDA	PS		;PROCESSOR STATUS
	PHA
	LDX	XREG		;RESTORE REGS
	LDY	YREG
	LDA	AC		;...
	RTI			;GO BACK

;HERE IF SINGLE STEP - SETUP FOR RE-ENTER AFTER XCT

GO1:	LDY	IOPC		;CHECK FOR JUMPS
	CPY	#$4C
	BEQ	GOJMP		;VANILLA JUMP
	CPY	#$6C		;MAYBE JUMP, INDIRECT
	BEQ	GOJMPI		; A LITTLE MORE HAIRY
	CPY	#$60		;"RTS"?
	BEQ	IRTS		; INTERPRET SUBROUTINE RETURN
	CPY	#$40		;"RTI"
	BEQ	IRTI		; INTERPRET INTERRUPT RETURN
	BNE	GO3		; AND GO EXECUTE

GOJMP:	SET2	XCTBR,POINT	;EXECUTE HERE
	BNE	GO3

GOJMPI:	MOV2	XBTARG,POINT	;NEED TO PICK UP ACTUAL TARGET
	LDY	#0
	LDA	(POINT),Y
	STA	XBTARG		;AND SET UP FOR "BRANCH" SIMULATION
	INY			;SET TO NEXT LOC
	LDA	(POINT),Y
	STA	XBTARG+1
	JMP	GOJMP		;NO GO SIMULATE JMP (I)

IRTS:	LDX	SP		;GET STACK POINTER
	TXS			;SETUP FOR "RTS" SIMULATION
IRTS1:	PLA			;PCL
	STA	XBTARG
	PLA			;PCH
	STA	XBTARG+1
	CPY	#$40		;IS THIS SUBR OR INTERRUPT
	BEQ	10$		;DON'T INCREMENT PC IF "RTI"
	INC	XBTARG		;"RTS" NEED PC + 1
	BNE	10$
	INC	XBTARG+1
10$:	TSX			;SAVE MODIFIED STACK PNTR
	STX	SP
	JMP	GOJMP

IRTI:	LDX	SP		;SETUP STACK POINTER
	TXS
	PLA			;GET PROCESSOR STATUS
	STA	PS
	JMP	IRTS1		;GOIN COMMON CODE

;$H - HEX DUMP TO TTY

HDUMP:	CALL	INTPT		;SET UP START AND END ADDRESS
	LDA	POINT		;GET LOW PART OF ADDRESS
	AND	#$F0		;MAKE IT START ON A NICE BOUNDRY
	STA	POINT
10$:	CALL	SETOUT		;SETUP OUTPUT DEVICE / GET LPP
	STA	LENGTH		; SAVE IT AWAY
20$:	CALL	CRLFS		;PRINT OUT CARRAGE RETURN LINEFEED
	CALL	PRTSPT		;PRINT OUT THE LOCATION
	LDA	#$10		;NUMBER OF BYTES PER LINE
	CALL	DMPLIN		;PRINT A LINE OF DUMP
	CALL	ENDCHK		;CHECK TO SEE IF WE ARE FINISHED
	DEC	LENGTH		;COUNT LINE
	BNE	20$		;GO DO ANOTHER LINE
	CALL	PAGEWT		;GO WAIT FOR CONTINUE
	JMP	10$		;GO DO ANOTHER PAGE
;$I - INITIALIZE MEMORY

INIT:	CALL	GETVAL		;GET VALUE
	LDX	INBUF		;GET BYTE INTO X
INITM1:	CALL	INTPTC		;SET UP ADDRESSES
10$:	TXA			;GET CHARACTER BACK
	LDY	#0		;SET UP FOR INDEXING
	STA	(POINT),Y	;SET MEMORY TO SPECIFIED VALUE
	CALL	ENDCHK		;CHECK TO SEE IF FINISHED
	JMP	10$		;NO GO DO ANOTHER VALUE


;$Z - ZERO MEMORY

ZERO:	LDX	#0		;GET A ZERO
	BEQ	INITM1		;GO INITIALIZE MEMORY

;$M - MOVE A BLOCK OF STORE

MOVE:	LDA	#$8D		;GET STORE OPCODE
	CALL	INTIVB		;SET UP STORE AND RETURN IN VEB
	CALL	GETVAL		;GET TO ADDRESS
	CALL	INTPT		;SET UP POINT FROM START
	MOV2	INBUF,VEB+1	;SET UP ADDRESS
10$:	LDY	#0		;SET UP FOR INDEXING
	LDA	(POINT),Y	;GET BYTE
	CALL	VEB		;STORE IT AT NEW ADDRESS
	CALL	INCVEB		;BUMP THE VEB POINTER
	CALL	ENDCHK		;FINISHED?
	JMP	10$		;NO

;$L -  PRINTER SELECT TOGGLE

PNTSEL:	LDA	STARTA		;COMPLIMENT PRINTER FLAG
	STA	PNTF
	JMP	BPXIT		;RETURN TO MAIN LOOP
;$O - CALCULATE BRANCH OFFSET

OFFSET:	CALL	PRBLNK		;PUT OUT SOME BLANKS
	CLC			;MAKE FROM BE ONE MORE
	LDA	ENDAD		;GET FIRST OF TO ADDRESS
	SBC	STARTA		;SUBTRACT FROM ADDRESS
	TAX			;SAVE LOW ORDER PART OF ADDRESS
	LDA	ENDAD+1		;GET HIGH PART OF TO ADDRESS
	SBC	STARTA+1	;SUBTRACT FROM ADDRESS
	TAY			;SAVE HIGH ORDER BYTE
	BNE	10$		;IF IT IS ZERO MAY BE LEGAL ADDRESS
	TXA			;GET LOW PART BACK
	BPL	30$		;VALID ADDRESS
	BMI	20$		;ELSE ILLEGAL ADDRESS
10$:	CMP	#$FF		;OR $FF IS LEGAL
	BNE	20$
	TXA			;GET LOW PART BACK
	BMI	30$		;VALID ADDRESS
20$:	TYA			;GET HIGH ORDER BYTE
	CALL	PRTSBY		;GO PRINT HIGH ORDER BYTE
30$:	TXA			;GET LOW ORDER BYTE
	CALL	PRTSBY		;PRINT LOW BYTE
	CALL	CRLFS		;AND CARRIAGE RETURN LINE FEED
	JMP	SCAN		;GO BACK TO MAIN LOOP

;$P - PROCEED FROM BREAKPOINT

PROC:	CALL	CRLFS		;SIGNAL START
	CLR	SNGLF		;NOT SINGLE STEP
	LDA	CF		;QUANT TYPED
	BMI	PROC1		;NO - PROCEED ONCE
	LDA	STARTA		;GET LOW BYTE OF COUNT
	BEQ	PERR		;DON'T ALLOW 0$P
	BNE	PROC2		;PROCEED COUNT IN AC

PROC1:	LDA	#1		;PRELOAD A ONE
PROC2:	LDX	BPN		;ACTUAL BP #
	BEQ	IXCT		;COULD BE FROM PANIC INT
	STA	BPCNT-1,X	;STORE COUNT
	BNE	IXCT		;JOIN SS CODE

PERR:	JMP	ERR		;HANDY BRANCH LOC

;$X - SINGLE STEP

EXEC:	CLR	BPN		;NO BREAKS IN PROGRESS
	INC	SNGLF		;SET FLAG

IXCT:	MOV2	PRPC,POINT	;SET START ADDRESS
	CALL	CALCAD		;GET LENGHT, EA, FORMAT
	MOV2	INBUF,XBTARG	;SET EA TO BRANCH TARGET
	LDX	#$EA		;GET NOP
	STX	IOPC+1		;INIT FOR 1 BYTE INSTR
	STX	IOPC+2
	LDA	(POINT),Y	;GET OPCODE
	BNE	5$		;CONVERT "BRK" INTO "NOP"
	TXA
5$:	STA	IOPC
	LDA	LENGTH		;LENGTH OF INSTR
	BEQ	IXCT1		;1 BYTE - GO NOW
	CALL	INCPT		;MOVE TO NEXT BYTE
	LDA	PFRMT		;CHECK FOR BRANCH
	CMP	#$1D		; INSTR
	BNE	IXCT3		;NOT BRANCH
	LDA	#XCTBR-IOPC-2	;BRANCH - SET UP DISPLACEMENT
	STA	IOPC+1		;STORE IN OFFSET BYTE
	BNE	IXCT1		;JOIN COMMON EXIT

IXCT3:	LDA	(POINT),Y	;GET NEXT BYTE
	STA	IOPC+1		;STORE IN XCT BLOCK
	LDA	LENGTH
	CMP	#2		;CHECK FOR 1 OR 2 EXTRA BYTES
	BNE	IXCT1		;ONLY 1 BYTE
	CALL	INCPT		;MOVE TO NEXT
	LDA	(POINT),Y	;GET 3RD AND LAST
	STA	IOPC+2
	LDA	IOPC		;GET OPCODE BYTE
	CMP	#$20		;IS IT "JSR"?
	BNE	IXCT1		;BRANCH IF NOT
	LDX	SP		;GET SAVED STACK POINTER
	TXS			;SET STACK
	LDA	POINT+1		;YES - SETUP RETURN PC
	PHA
	LDA	POINT
	PHA
	TSX			;SAVE UPDATED POINTER
	STX	SP		; FOR PROCEED
	LDA	#$4C		;CHANGE INTO "JMP"
	STA	IOPC
IXCT1:	CALL	INCPT		;STEP TO INSTR AFTER THIS ONE
	MOV2	POINT,XNOBR	;SETUP NO BRANCH LOC
	SET2	IOPC,POINT	;SET START ADDR TO IOPC BLOCK
	JMP	GO1		;AND START UP

;EXECUTE BLOCK FOR INSTR XCT SIMULATOR

IOPC:	BEQ	XCTBR
	.BYTE	$EA		;NOP
	STY	YREG		;SAVE NEW STATE AFTER $X
	STX	XREG
	STA	AC
	PHP
	PLA
	STA	PS		;PROCESSOR STATUS
	TSX
	STX	SP		;STACK POINTER
XCTNB:	MOV2	XNOBR,POINT	;NO BRANCH OCCURED
	JMP	BRKY

XCTBR:	MOV2	XBTARG,POINT	;BRANCH OCCURED
	JMP	BRKY

XNOBR:	.BLKW	1		;SAVED POINTERS FOR SINGLE STEP
XBTARG:	.BLKW	1

;$Q - DISASSEMBLE CODE

DISASS:	CALL	INTPT		;SET UP POINT
10$:	CALL	SETOUT		;SET OUTPUT DEVICE
	STA	CF		; RETURNS LINES/PAGE
20$:	CALL	CRLFS		;PUT OUT CARRIAGE RETURN LINE FEED
	CALL	PRTSLS		;GO PRINT A LINE
	CALL	ENDCHK		;CHECK TO SEE IF FINISHED
	LDA	LENGTH		;GET LENGTH OF INSTRUCTION
	CLC			;ONE ALREADY ADDED AT ENDCHK
	CALL	PCADJ3		;POINT TO NEXT INSTRUCTION
	STA	POINT		;SAVE UPDATED ADDRESS
	STY	POINT+1
	DEC	CF		;ACCOUNT FOR LINE
	BNE	20$		;GO DO ANOTHER INSTRUCTION
	CALL	PAGEWT		;GO WAIT FOR GO AHEAD
	BNE	10$		;GO DO ANOTHER PAGE

;ROUTINE TO SETUP FOR OUTPUT - CHECK PNTF FOR PRINTER

SETOUT:	LDA	PNTF		;WANT PRINTER?
	BEQ	10$
	CALL	OPENP		;YES - OPEN IT IF NOT OPEN ALREADY
	LDA	#LPP		;RETURN LINES/PAGE
	RET

10$:	LDA	#LNSCR		;LINE/SCREEN (EDITOR)
	RET
;$S - SEARCH FOR ADDRESS

SEARCH:	CALL	GETVAL		;GET A WORD
	MOV2	INBUF,VEB	;SAVE VALUE SEARCHING FOR
	CALL	INTPTC		;SET UP ADDRESSES
	CALL	DECPT		;DECREMENT IT BY ONE
10$:	LDY	#0		;SET UP INDEX
	LDA	(POINT),Y	;GET FIRST BYTE
	CMP	VEB		;DOES IT MATCH
	BNE	20$		;NO
	INY			;BUMP POINTER
	LDA	(POINT),Y	;GET SECOND BYTE
	CMP	VEB+1		;DOES IT MATCH
	BNE	20$		;NO
	CALL	PRTSPT		;PRINT THE ADDRESS
	LDA	#'/		;PRINT SEPERATOR
	CALL	OUTSCH		;PRINT IT
	CALL	OUTSSP		;PUT OUT A SPACE
	LDA	VEB+1		;GET HIGH BYTE
	CALL	PRTSBY		;PRINT THE BYTE
	LDA	VEB		;GET LOW BYTE
	CALL	PRTSBY		;PRINT IT
	JMP	30$		;GO DO CARRIAGE RETURN LINE FEED

20$:	CALL	CALCAD		;GET EFFECTIVE ADDRESS OF INSTRUCTION
	LDA	INBUF		;GET LOW BYTE
	CMP	VEB		;DOES IT MATCH
	BNE	40$		;NO
	LDA	INBUF+1		;GET HIGH BYTE
	CMP	VEB+1		;DOES IT MATCH
	BNE	40$		;NO
	CALL	PRTSLS		;GO PRINT THE CONTENTS
	LDA	PFRMT		;
	CMP	#$1D		;CHECK TO SEE IF IT WAS A BRANCH
	BEQ	30$		;YES.  NO NEED TO BUMP TWO
	CALL	INCPT		;BUMP POINTER SO WE DO NOT GET ADDRESS AGAIN
30$:	CALL	CRLFS		;PUT OUT CARRIAGE RETURN LINE FEED
40$:	CALL	ENDCHK		;ARE WE FINISHED
	JMP	10$		;NO
;$T - TYPE OUT MEMORY IN ASCII

TYPE:	CALL	INTPTC		;SET UP ADDRESSES
10$:	LDY	#0		;SET UP FOR INDEXING
	LDA	(POINT),Y	;GET A CHARACTER
	CALL	OUTSCH		;PRINT THE CHARACTER
	CALL	ENDCHK		;FINISHED?
	JMP	10$		;NO

;ROUTINES DEALING WITH POINT

;REGISTER CLOSE ROUTINE
;CLOSE LOCATION AND UPDATE IF NECESSARY

CLSE:	LDY	#0		;PREPARE TO MODIFY
	LDA	ROF		;GET FLAG
	BEQ	CLSEX		;XFER IF NONE OPEN
	BMI	CLSEX		; OR SYMBOLIC
	LDA	CF		;ANYTHING TYPED?
	BMI	CLSEX		;NO - DO NOTHING
	LDA	STARTA		; CURRENT OPEN REG
	STA	(POINT),Y	; WITH INPUT VALUE
CLSEX:	STY	ROF		;SET REGISTER CLOSED
	RET			;RETURN


;SET UP POINT FROM THE STARTING ADDRESS

INTPTC:	CALL	CRLFS		;PUT OUT CARRIAGE RETURN LINE FEED FIRST
INTPT:	MOV2	STARTA,POINT
	RET


;DECREMENT THE PC

DECPT:	SEC			;PREPARE TO DECREMENT POINT
	LDA	POINT
	SBC	#1
	STA	POINT
	BCS	10$
	DEC	POINT+1		;HANDLE BORROW
10$:	RET


;CHECK TO SEE IF POINT IS AT END YET

ENDCHK:	LDA	POINT		;CHECK TO SEE IF FINISHED
	CMP	ENDAD
	LDA	POINT+1
	SBC	ENDAD+1
	BCS	20$		;IF GREATER THAN, FINISHED
	JMP	INCPT		;INCREMENT THE POINTER

20$:	JMP	DCD		;FINISHED GO BACK TO MAIN LOOP
;ROUTINES TO PICK UP VALUES

; GET ADDITIONAL VALUE, PROMPT FOR INPUT, ERROR IF NOT
;   TERMINATED BY <EOL>

GETVAL:	CALL	OUTSSP		;OUTPUT SPACE
	LDA	#':		; AND PROMPT
	CALL	OUTSCH
	CALL	GETNUM
	CMP	#.ATEOL		;TERMINATED PROPERLY?
	BEQ	ABTRET		;YES - RETURN
	JMP	ERR		;NOPE -ERROR

;GET A NUMBER RETURN WITH TERMINATOR IN A

GETNUM:	CLR2	INBUF		;CLEAR THE BUFFER
	CALL	PACKCH		;GET A CHARACTER
	BNE	ABTCHK		;IF NOT HEX RETURN WITH CHARACTER IN A
	INC	CF		;SAY WE HAVE A NUMBER
10$:	CALL	PACKCH		;GO GET ANOTHER CHARACTER
	BEQ	10$		;IF HEX GO GET ANOTHER CHARACTER
	;;;	...		; FALL INTO ABTCHK

;CHECK FOR RUBOUT OR BREAK. IF FOUND RETURN TO COMMAND DECODER

ABTCHK:	CMP	#.ATRUB		;RUBOUT
	BEQ	ABORT		;ABORT COMMAND
	CMP	#BRKABT		;BREAK TYPED
	BEQ	ABORT
ABTRET:	RET

ABORT:	TYPE	EXES		;PUT OUT XXX
	JMP	DCD4

EXES:	.ASCII	"  XXX"<.ATEOL>

;GET A CHARACTER AND PACK IT

PACKCH:	CALL	GETSCH		;GET THE CHARACTER
	CMP	#'9+1		;CAN IT BE A NUMBER
	BMI	PACK		;YES GO TRY TO PACK IT
	CMP	#'A		;IS IT A CHARACTER
	BMI	10$		;NO.  INVALID CHARACTER RETURN
	CMP	#.ATRUB		;RUBOUT
	BEQ	10$		;YES.  INVALID CHARACTER RETURN
	AND	#@337		;GET RID OF LOWERCASE BIT
	CMP	#'F+1		;IS IT G OR LARGER
	BMI	PACK		;NO.  GO PACK IT
10$:	TAY			;SIGNAL ILLEGAL CHARACTER
	RET

PACK:	CMP	#'0		;CHECK FOR HEX
	BMI	PACKX
	CMP	#'A-1		;ADJUST FOR A-F
	BMI	10$
	CLC			;BY ADDING OFFSET
	ADC	#$09
10$:	ROL	A		;SHIFT IN
	ROL	A
	ROL	A
	ROL	A
	LDY	#$04		;4 MORE SHIFTS THRU CARRY
20$:	ROL	A		; TO MOVE INTO INBUF
	ROL	INBUF
	ROL	INBUF+1		;RIPPLE BIT THROUGH
	DEY			;COUNT LOOP
	BNE	20$
	LDA	#$00		;RETURN A = 0 IF OK NUMBER
PACKX:	RET

;WAIT FOR A CHARACTER TO BE TYPED IF IT IS A RUBOUT RETURN TO COMMAND 
;DECODER

PAGEWT:	LDA	PIOCB		;ARE WE PRINTING?
	BEQ	10$	
	LDA	#@14		;OUTPUT FF
	JMP	OUTSCH

10$:	LDA	#.ATBEL		;GET BELL
	CALL	OUTSCH		;RING IT
	CALL	GETSCH		;WAIT FOR CHARACTER
	JMP	ABTCHK		;CHECK FOR ABORT OR PROCEED

;ROUTINE TO GET A CARACTER
;	RETURNS CHARACTER IN A
;	USES Y

GETSCH:	STX	TEMPX		;SAVE X
	STY	TEMPY		; AND Y AROUND O/S
	LDA	#0
	STA	ICAX1Z		;CLEAR FLAG
	CALL	KGETCH		;RETURNS STATUS IN Y, CHAR IN A
	BMI	20$		;DON'T ECHO SPECIAL CHARS
	CMP	#.ATRUB		;CHECK BS/DEL KEY
	BEQ	30$		; RUBOUT DOESN'T ECHO
	CMP	#.CHSP		;CHECK FOR CONTROLS
	BCS	OUTSCN		; ECHO IF NOT
	BCC	30$		;RETURN CHAR - NO ECHO

20$:	CPY	#BRKABT		;BREAK KEY TYPED?
	BNE	30$
	TYA			;YES - RETURN BREAK FLAG
30$:	LDX	TEMPX		;RESTORE
	LDY	TEMPY
	RET			; ELSE RETURN

;ROUTINE TO GET TWO HEX CARACTERS INTO AC
;	RETURNS CHARACTER IN A
;	X PRESERVED Y RETURNED = 0

GETSBY:	CALL	PACKCH		;GET A CHARACTER
	CALL	PACKCH		;GET ANOTHER CHARACTER
	LDA	INBUF		;LOAD UP BYTE
	RET
;GENERAL PURPOSE PRINTING ROUTIMES

;PRINT LOCATION AND IT'S CONTENETS IF FORM SPECIFIED BY ROF

PRTSLS:	LDA	#$FF		;SET THE TYPEOUT MODE BACK
	STA	ROF
	LDX	#'/		;SLASH
PRTSLC:	CALL	PRTSPT		;PRINT CONTENTS OF POINT
	TXA			;GET CHAR BACK
	CALL	OUTSCH
	CALL	OUTSSP		; AND A SPACE
	;;;	...		; FALL INTO PRTSCN

;PRINT OUT CONTENTS OF CURRENT LOCATION IN FORM SPECIFIED BY ROF

PRTSCN:	LDY	#0		;SET FOR GLOBAL INDEX
	LDA	(POINT),Y	;GET CURRENT LOCATION IN A
	STA	STARTA		;SAVE FOR QUOTE OR EQUAL
	LDX	ROF		;SEE WHAT KIND
	BMI	20$		;BR IF SYMBOLIC
	CALL	PRTSBY		;PRINT CONTENTS
10$:	JMP	OUTSSP		;AWAIT NEXT REQUEST

20$:	CALL	DSMBL		;PRINT SYMBOLIC
	JMP	10$		; AND RETURN TO CMD LOOP

;DUMP NUMBER OF LOCATIONS IN A TO SCREEN

DMPLIN:	STA	PFRMT		;SAVE IT
	CALL	PRBLNK		;SPACE OVER 2
	BEQ	20$		;DO NOT INCREMENT POINTER FIRST TIME

10$:	CALL	INCPT		;INCREMENT THE POINTER
	CALL	OUTSSP		;PRINT BLANK
20$:	LDY	#0		;SET UP FOR INDEXING
	LDA	(POINT),Y	;GET LOCATION
	CALL	PRTSBY		;PRINT IT
	DEC	PFRMT		;ACCOUNT FOR CHARACTER
	BNE	10$		;NOT FINISHED GO DO MORE
	RET

;OUTPUT NUMBER OF BLANKS IN X

PRBLNK:	LDX	#$2
PRBL2:	CALL	OUTSSP
	DEX
	BNE	PRBL2		;LOOP TILL COUNT = 0
	RET


;ROUTINE TO OUTPUT CHARACTER TO OUTPUT PORT
;	CHARACTER IN A

;	USES Y AND RETURNS CHARACTER IN A

OUTSSP:	LDA	#.CHSP		;LOAD UP A BLANK
OUTSCH:	STX	TEMPX		;SAVE X & Y AROUND O/S CALLS
	STY	TEMPY
OUTSCN:	PHA			;SAVE THE CHARACTER
	TAY			; AND MOVE TO Y
	LDX	PIOCB		;GET IOCB INDEX
	LDA	#PUTCHR		;1 CHAR OUTPUT
	CALL	CIOC		;OUTPUT TO EDITOR/PRINTER
	LDX	TEMPX		;RESTORE X
	LDY	TEMPY		;RESTORE Y
	PLA
	RET

;ROUTINE TO WRITE OUT CARRIAGE RETURN LINE FEED
;	USES A AND Y

CRLFS:	LDA	#.ATEOL
	JMP	OUTSCH		;WRITE IT OUT AND RETURN

;ROUTINE TO PRINT CURRENT LOCATION
;	PRINTS POINT
;	USES A AND Y

PRTSPT:	LDA	POINT+1		;GET HIGH ORDER BYTE
	CALL	PRTSBY
	LDA	POINT		;GET LOW ORDER BYTE 
	;;;	...		;FALL INTO PRTSBY

;ROUTINE TO PRINT BYTE AS TWO HEX DIGITS
;	BYTE IS IN A

PRTSBY:	PHA			;SAVE THE BYTE
	LSR	A		;GET HIGH ORDER FOUR BITS
	LSR	A
	LSR	A
	LSR	A
	CALL	HEXSTA		;GO CONVERT IT TO HEX
	PLA			;GET THE ORGINAL BYTE BACK
	;;;	...		; FALL INTO HEXSTA


;ROUTINE TO CONVERT A HEX DIGIT TO ASCII
;	DIGIT IS IN A

HEXSTA:	AND	#$0F		;GET JUST ONE DIGIT
	CMP	#$0A		;IS IT A DECIMAL DIGIT
	CLC			;CLEAR THE CARRY
	BMI	HEXST1		;IF NEGATIVE IT IS A DECIMAL DIGIT
	ADC	#$07		;ADD IN OFFSET TO GET A-F
HEXST1:	ADC	#$30		;CONVERT TO ASCII
	JMP	OUTSCH		;GOT WRITE CHARACTER AND RETURN
; MISC ROUTINES

INITS:	CLD			;CLEAR DECIMAL MODE
	LDA	#LEDGE		;SET DEFAULT MARGINS
	STA	LMARGN
	LDA	#REDGE
	STA	RMARGN
	LDA	#$94		;SETUP BACKGROUND COLOR
	STA	COLOR4		;TO BE SAME AS FOREGROUND
	JMP	CLOSEP		;CLOSE PRINTER IF OPEN

;SET UP VEB AREA

INTSVB:	LDA	#$AD		;LDA OP CODE
INTIVB:	STA	VEB
INTVEB:	LDA	STARTA		;SET UP SUB
	STA	VEB+1
	LDA	STARTA+1
	STA	VEB+2
	LDA	#$60		;"RTS"
	STA	VEB+3
	RET

;ROUTINE TO INCRENT POINT

INCPT:	INC2	POINT
	RET

;ROUTINE TO INCREMENT ADDRS IN VEB

INCVEB:	INC2	VEB+1
INCRET:	RET
;PRINTER ROUTINES

OPENP:	LDA	PIOCB		;CHECK IF ALREADY OPEN
	BNE	INCRET		;YES - DON'T REOPEN
	LDX	#$10		;START AT IOCB#1
5$:	LDA	ICHID,X		;GET ID
	CMP	#$FF		;FREE?
	BEQ	THSONE
	CPX	#$70		;LAST ONE?
	BEQ	PNONE
	TXA			;STEP INDEX TO NEXT
	CLC
	ADC	#$10
	TAX			;BACK TO X
	BNE	5$

PNONE:	JMP	ERR		;NO FREE IOCB'S

;FOUND FREE IOCB (INDEX IN X)

THSONE:	STX	PIOCB		;SAVE IOCB INDEX
	LDA	#OPNOT		;OPEN FOR OUTPUT
	STA	ICAX1,X
	SET2	PDEV,ICBAL,X	;POINT TO DEVICE TEXT
	LDA	#OPEN		;OPEN COMMAND
CIOC:	STA	ICCOM,X		;STORE COMMAND
	LDA	#0		;SET LENGTH TO ZERO
	STA	ICBLL,X
	STA	ICBLH,X
	TYA			;MIGHT HAVE CHARACTER
	CALL	CIOV		;INVOKE O/S
	STY	DSTATS		;PUT COMPLETION CODE HERE
	BPL	INCRET		;RETURN IF NO ERROR
	CPY	#BRKABT		;BREAK TYPED?
	BEQ	10$
	JMP	IOCERR		;COMMON ERROR HANDLER

10$:	JMP	ABORT		;ABORT I/O - RETURN TO TOP LEVEL

; CLOSE PRINTER IOCB

CLOSEP:	LDX	PIOCB		;SETUP IOCB INDEX
	BEQ	INCRET		;RETURN IF NONE
	CLR	PIOCB		;FLAG NO PRINTER
	LDA	#CLOSE		;CLOSE COMMAND
	BNE	CIOC		; INVOKE CIO

PDEV:	.ASCII	"P:"<.ATEOL>

;GENERAL BREAKPOINT ROUTINES

;ROUTINE TO REMOVE BREAKPOINTS

REMB:	LDX	#MAXBP-1	;COUNT OF THINGS TO DO
5$:	LDA	BPINS,X		;GET INSTR OR ZERO
	BEQ	10$		;NO BP IF ZERO
	CALL	SETA		;SET UP ADDRS
	STA	(INBUF),Y	;STORE INSTR
10$:	DEX
	BPL	5$		;LOOP OVER ALL
	RET			;RETURN

;SETUP ADDRS OF GIVEN BREAKPOINT FOR INDIRECT
;RETURNS INBUF WITH BPLOC,X , Y := 0
;PRESERVES AC

SETA:	LDY	BPLOCL,X	;GET LOW ADDRS BYTE
	STY	INBUF		;USE THIS AS TEMP
	LDY	BPLOCH,X	;GET HIGH ADDRS BYTE
	STY	INBUF+1
	LDY	#0		;SET FOR GLOBAL INDIRECT
	RET			;RETURN

;ROUTINE TO INSERT BREAKPOINTS

INSB:	LDX	#MAXBP-1	;DO ALL
5$:	LDA	BPINS,X		;SEE IF ACTIVE
	BEQ	10$		;SKIP IF NO BP
	CALL	SETA		;SET UP ADDRS
	LDA	(INBUF),Y	;GET OLD INSTR
	STA	BPINS,X		;SAVE OLD INSTR
	LDA	#0		;PUT BREAK IN PLACE
	STA	(INBUF),Y	;...
10$:	DEX
	BPL	5$		;LOOP TILL DONE
	RET			;RETURN

;INTERUPT SERVICES

;IRQ - <BRK> INSTRUCTION OR ACTUAL APPLICATION INT.

BREAK:	PLA			;AC IS ON STACK
	STA	AC		;SAVE ACCUM
	PLA			;PROCESSOR STATUS
	STA	PS
	STY	YREG		;SAVE INDEX REGS
	STX	XREG
	PLA			;PC LOW
	SEC			;DECREMENT PC TO REAL LOC
	SBC	#2		;ADJUST PC FOR ACTUAL BP LOC
10$:	STA	PRPC		;SAVE HERE FOR $P
	STA	POINT		;SAVE HERE FOR EXAMINE
	PLA			;PC HIGH
	BCS	20$		;CHECK BORROW
	SBC	#0		;ADJUST BY 1
20$:	STA	PRPC+1
	STA	POINT+1
	TSX			;GET STACK PNTR
	STX	SP		; SAVE IT AWAY
	CALL	REMB		;REMOVE BREAKPOINTS NOW
	LDX	#MAXBP		;SEARCH FOR BPN
25$:	LDA	BPINS-1,X	;ACTIVE BP?
	BEQ	30$		;NO - SKIP TO NEXT
	LDA	PRPC+1		;GET PC HIGH
	CMP	BPLOCH-1,X	;MATCH?
	BEQ	35$		;YES - TRY FOR LOW
30$:	DEX			;STEP TO NEXT
	BNE	25$		; MORE TO DO
	STX	BPN		;SIGNAL NO B.P.
	BEQ	BRKX		;NONE FOUND (MAYBE PANIC)
	;..
	;..

35$:	LDA	PRPC		;GET PC LOW
	CMP	BPLOCL-1,X	;MATCH?
	BNE	30$		;NO - KEEP LOOKING

;ACTUAL BPN IN X

	STX	BPN		;SAVE BPN
	LDA	BPCNT-1,X	;BREAT THIS TIME? (0)
	BEQ	BRKX		;BREAK IF ZERO
	DEC	BPCNT-1,X	;COUNT THIS TIME
	BEQ	BRKX		; AND DO AUTO PROC (IF .NE. 0)
	CLR	SNGLF		; NOT SINGLE STEP
	SETXA	IXCT		;EXIT THROUGH HERE
BRKRTI:	PHA			;SAVE HIGH PC
	TXA			;GET LOW
	PHA			;SAVE IT TOO
	LDA	PS
	PHA			;CURRENT PROCESSOR STATUS
	RTI			;DISMISS TO ROUTINE

;HERE TO ENTER BREAKPOINT - CLEAR SINGLE STEP FLAG

BRKX:	CLR	SNGLF		; CLEAR SS FLAG
	SETXA	DOBRK
	BNE	BRKRTI		;EXIT INT TO DOBRK

DOBRK:	CALL	CRLFS		;PUT OUT A CR/LF
	LDA	#'B		;PRINT BN;ADDRS
	CALL	OUTSCH
	LDA	BPN		;MAYBE 0
	CALL	HEXSTA		;TYPE LOW 4 BITS
	LDA	#';
	CALL	OUTSCH
	JMP	LFDS1		;GO PRINT OUT ADDRESS AND INSTR.

BRKY:	MOV2	POINT,PRPC	;SINGLE STEP ENTRY - POINT HAS PC
	LDA	SNGLF		;WAS THIS SINGLE STEP?
	BNE	DOBRK		; SIMULATE BREAK IF $X
	JMP	GO2		;ELSE - JUST PROCEED

	.SBTTL	6502 DISASSEMBLER


DSMBL:	CALL	CALCAD		;CALCULATE EFFECTIVE ADDRESS
	PHA			;SAVE MNEMONIC TABLE INDEX
PROP:	LDA	(POINT),Y	;GET OP AND PRINT IT
	CALL	PRTSBY
	LDX	#$1		;ONE SPACE
10$:	CALL	PRBL2
	CPY	LENGTH		;PRINT INSTR (1 TO 3 BYTES)
	INY			; IN A 12-CHAR FIELD
	BCC	PROP
	LDX	#$3		;CHAR COUNT FOR MNEMONIC PRINT
	CPY	#$4
	BCC	10$
	PLA			;RECOVER MNEMONIC INDEX
	TAY
	LDA	MNEML,Y
	STA	LMNEM		;FETCH 3-CHAR MNEMONIC
	LDA	MNEMR,Y		; (PACKED IN 2 BYTES)
	STA	RMNEM
PRMN1:	LDA	#$0
	LDY	#$5
PRMN2:	ASL	RMNEM
	ROL	LMNEM		;SHIFT 5 BITS OF CHAR INTO A
	ROL	A		; (CLEARS CARRY)
	DEY
	BNE	PRMN2
	ADC	#$3F		;ADD '?' OFFSET
	CALL	OUTSCH
	DEX
	BNE	PRMN1
	CALL	PRBLNK		;PRINT 3 BLANKS
	LDX	#$6		;COUNT FOR 6 PRINT FORMAT BITS
PRADR1:	CPX	#$3
	BNE	PRADR3		;IF X=3 THEN PRINT ADDRESS VAL
	LDY	LENGTH
	BEQ	PRADR3		;NO PRINT IF LENGTH=0
	LDA	PFRMT
	CMP	#$E8		;HANDLE REL ADDRESSING MODE
	BNE	PRADR2		;IF NOT DO NOT ADJUST NUMBER OF BYTES
	INY			;IF RELATIVE BRANCH PRINT 2 BYTES
	CLR	PFRMT		;CLEAR PFRMT
PRADR2:	LDA	INBUF-1,Y	;SPECIAL (PRINT TARGET ADDRS)
	CALL	PRTSBY		;OUTPUT 1 OR 2 BYTE ADDRS
	DEY			; MSB FIRST
	BNE	PRADR2
PRADR3:	ASL	PFRMT		;TEST NEXT PRINT FORMAT BIT
	BCC	PRADR4		;IF 0, DON'T PRINT
	LDA	CHAR1-1,X	; CORRESPONDING CHARS
	CALL	OUTSCH		;OUTPUT 1 OR 2 CHARS
	LDA	CHAR2-1,X	; (IF CHAR FROM CHAR2 IS 0,
	BEQ	PRADR4		;  DON'T OUTPUT IT)
	CALL	OUTSCH
PRADR4:	DEX
	BNE	PRADR1
	RET


;SET UP LENGTH, PFRMT AND EFFECTIV ADDRESS
;	RETURNS INDEX INTO MNEMONIC TABLES IN A AND 0 IN Y

CALCAD:	LDY	#0		;SET UP FOR INDEXING
	STY	INBUF+1		;ZERO HIGH BYTE OF ADDRESS IN CASE ONLY ONE BYTE
	LDA	(POINT),Y	;GET OPCODE
	TAY			;SAVE IN Y
	LSR	A		; EVEN/ODD TEST
	BCC	IEVEN
	LSR	A		; TEST B1
	BCS	IERR		; XXXXXX11 INSTR INVALID
	CMP	#$22
	BEQ	IERR		; 10001001 INSTR INVALID
	AND	#$7		;MASK 3 BITS FOR ADDRS MODE
	ORA	#$80		; ADD INDEXING OFFSET.
IEVEN:	LSR	A		;LSB INTO CARRY FOR
	TAX			; LEFT/RIGHT TEST BELOW.
	LDA	MODE1,X		;INDEX INTO ADDRS MODE TABLE
	BCS	RTMODE		;IF CARRY SET USE LSD FOR
	LSR	A		; PRINT FORMAT INDEX.
	LSR	A
	LSR	A
	LSR	A		; IF CARRY CLEAR, USE MSD
RTMODE:	AND	#$F		;MASK FOR 4-BIT INDEX
	BNE	GETFMT		; 0 FOR INVALID OPCODES
IERR:	LDY	#$80		;SUBSTITUTE $80 FOR INVALID OP.
	LDA	#$0		;SET PRINT FORMAT TO 0
GETFMT:	TAX
	LDA	MODE2,X		;INDEX INTO PRINT FORMAT TABLE
	STA	PFRMT		;SAVE FOR ADDRESS FIELD FORMAT
	AND	#$3		;MASK 2-BIT LENGTH 0 = 1-BYTE,
	STA	LENGTH		; 1 = 2-BYTE, 2 = 3-BYTE.
	TYA			;RESTORE OP CODE
	PHA			;SAVE OPCODE ON STACK
	LDY	LENGTH		;GET LENGTH
	BEQ	10$		;IF ZERO SET CURRENT ADDRESS IN INBUF FOR TAB
	LDA	(POINT),Y	;GET FIRST BYTE OF ADDRESS
	CPY	#1		;IS IT A 2 BYTE INSTRUCTION
	BNE	20$		;NO GO PRINT BOTH BYTES
	CPX	#13		;WAS INDEX TO MODE2 FOR RELATIVE
	BNE	30$		;NO GO DO JUST ONE BYTE
	CALL	RELADR		;GO CALCULATE RELATIVE ADDRESS
	STY	INBUF+1		;SAVE HIGH ORDER BYTE
	TXA			;GET LOW ORDER BYTE BACK
	JMP	30$		;GO FINISH UP

10$:	LDA	POINT+1		;GET HIGH ORDER BYTE OF ADDRESS
	STA	INBUF+1		;AND SAVE IT
	LDA	POINT		;GET LOW BYTE
	JMP	30$		;GO SAVE IT AND FINISH

20$:	STA	INBUF+1		;SAVE HIGH BYTE OF ADDRESS
	DEY			;SET TO GET LOW ORDER BYTE
	LDA	(POINT),Y	;GET LOW BYTE
30$:	STA	INBUF		;SAVE LOW BYTE OF ADDRESS
	PLA			;GET OPCODE BACK
	TAY			;AND SAVE IT IN Y
	AND	#$8F		;MASK IT FOR 1XXX1010 TEST
	TAX			; AND SAVE IT.
	TYA			;OPCODE AGAIN
	LDY	#$3
	CPX	#$8A
	BEQ	60$
40$:	LSR	A
	BCC	60$		;FORM INDEX INTO MNEMONIC TABLE
	LSR	A
50$:	LSR	A		; 1XXX1010 -> 00101XXX
	ORA	#$20		; XXXYYY01 -> 00111XXX
	DEY			; XXXYYY10 -> 00110XXX
	BNE	50$		; XXXYY100 -> 00100XXX
	INY			; XXXXX000 -> 000XXXXX
60$:	DEY
	BNE	40$
	RET


;HERE TO HANDLE RELATIVE BRANCH ADDRS

RELADR:	CALL	PCADJ3		;PCL,H + DISPL + 1 TO A,Y
	TAX
	INX
	BNE	10$		;	+1 TO X,Y
	INY
10$:	RET
;ADD LENGTH TO POINT

PCADJ:	LDA	LENGTH		;0=1-BYTE, 1=2-BYTE, 2=3-BYTE
	SEC
PCADJ3:	LDY	POINT+1
	TAX			;TEST DISPL SIGN (FOR REL
	BPL	10$		; BRANCH). EXTEND NEG
	DEY			; BY DECREMENTING PCH.
10$:	ADC	POINT
	BCC	20$		;PCL+LENGTH (OR DISPL) +1 TO A.
	INY			;CARRY INTO Y (PCH)
20$:	RET

;TABLES

MODE1:	.BYTE	$40
	.BYTE	$2
	.BYTE	$45
	.BYTE	$3
	.BYTE	$D0
	.BYTE	$8
	.BYTE	$40
	.BYTE	$9
	.BYTE	$30	;XXXXXXZ0 INSTRS.
	.BYTE	$22
	.BYTE	$45	; Z=0, LEFT HALF-BYTE
	.BYTE	$33	; Z=1, RIGHT HALF-BYTE
	.BYTE	$D0
	.BYTE	$8
	.BYTE	$40
	.BYTE	$9
	.BYTE	$40
	.BYTE	$2
	.BYTE	$45
	.BYTE	$33
	.BYTE	$D0
	.BYTE	$8
	.BYTE	$40
	.BYTE	$9
	.BYTE	$40
	.BYTE	$2	;(WAS 0)
	.BYTE	$45	;(WAS 40)
	.BYTE	$B3	;(WAS B0)
	.BYTE	$D0
	.BYTE	$8	;(WAS 0)
	.BYTE	$40
	.BYTE	$9	;(WAS 0)
	.BYTE	$0
	.BYTE	$22
	.BYTE	$44
	.BYTE	$33
	.BYTE	$D0
	.BYTE	$8C
	.BYTE	$44
	.BYTE	$0
	.BYTE	$11
	.BYTE	$22
	.BYTE	$44
	.BYTE	$33
	.BYTE	$D0
	.BYTE	$8C
	.BYTE	$44
	.BYTE	$9A
	.BYTE	$10
	.BYTE	$22
	.BYTE	$44
	.BYTE	$33
	.BYTE	$D0
	.BYTE	$8
	.BYTE	$40
	.BYTE	$9
	.BYTE	$10
	.BYTE	$22
	.BYTE	$44
	.BYTE	$33
	.BYTE	$D0
	.BYTE	$8
	.BYTE	$40
	.BYTE	$9
	.BYTE	$62
	.BYTE	$13	;YYXXXZ01 INSTRS.
	.BYTE	$78
	.BYTE	$A9

MODE2:	.BYTE	$0	;ERR
	.BYTE	$21	;IMM
	.BYTE	$1	;Z-PAG (WAS 81)
	.BYTE	$2	;ABS (WAS 82)
	.BYTE	$0	;IMPL
	.BYTE	$80	;ACC (WAS 0)
	.BYTE	$59	;(Z-PAG,X)
	.BYTE	$4D	;(Z-PAG),Y
	.BYTE	$11	;Z-PAG,X (WAS 91)
	.BYTE	$12	;ABS,X (WAS 92)
	.BYTE	$6	;ABS,Y (WAS 86)
	.BYTE	$4A	;(ABS)
	.BYTE	$5	;Z-PAG,Y (WAS 85)
	.BYTE	$1D	;REL (WAS 9D)

CHAR1:	.BYTE	',	;COMMA
	.BYTE	')	;RPAREN
	.BYTE	',	;COMMA
	.BYTE	'#	;SHARP
	.BYTE	'(	;LPAREN
	.BYTE	'A	;(WAS '$)

CHAR2:	.BYTE	'Y
	.BYTE	0	;NULL
	.BYTE	'X
	.BYTE	0	;(WAS '$)
	.BYTE	0	;(WAS '$)
	.BYTE	0

MNEML:	.BYTE	$1C	;XXXXX000 INSTRS.
	.BYTE	$8A
	.BYTE	$1C
	.BYTE	$23
	.BYTE	$5D
	.BYTE	$8B
	.BYTE	$1B
	.BYTE	$A1
	.BYTE	$9D
	.BYTE	$8A
	.BYTE	$1D
	.BYTE	$23
	.BYTE	$9D
	.BYTE	$8B
	.BYTE	$1D
	.BYTE	$A1
	.BYTE	$0
	.BYTE	$29
	.BYTE	$19
	.BYTE	$AE
	.BYTE	$69
	.BYTE	$A8
	.BYTE	$19
	.BYTE	$23
	.BYTE	$24
	.BYTE	$53
	.BYTE	$1B
	.BYTE	$23
	.BYTE	$24
	.BYTE	$53
	.BYTE	$19
	.BYTE	$A1
	.BYTE	$0	;XXXYY100 INSTRS
	.BYTE	$1A
	.BYTE	$5B
	.BYTE	$5B
	.BYTE	$A5
	.BYTE	$69
	.BYTE	$24
	.BYTE	$24
	.BYTE	$AE	;1XXX1010 INSTRS.
	.BYTE	$AE
	.BYTE	$A8
	.BYTE	$AD
	.BYTE	$29
	.BYTE	$0
	.BYTE	$7C
	.BYTE	$0
	.BYTE	$15	;XXXYYY10 INSTRS.
	.BYTE	$9C
	.BYTE	$6D
	.BYTE	$9C	;(WAS 0)
	.BYTE	$A5
	.BYTE	$69
	.BYTE	$29
	.BYTE	$53
	.BYTE	$84	;XXXYYY01 INSTRS.
	.BYTE	$13
	.BYTE	$34
	.BYTE	$11
	.BYTE	$A5
	.BYTE	$69
	.BYTE	$23
	.BYTE	$A0

MNEMR:	.BYTE	$D8	;XXXXX000 INSTRS.
	.BYTE	$62
	.BYTE	$5A
	.BYTE	$48
	.BYTE	$26
	.BYTE	$62
	.BYTE	$94
	.BYTE	$88
	.BYTE	$54
	.BYTE	$44
	.BYTE	$C8
	.BYTE	$54
	.BYTE	$68
	.BYTE	$44
	.BYTE	$E8
	.BYTE	$94
	.BYTE	$0
	.BYTE	$B4
	.BYTE	$8
	.BYTE	$84
	.BYTE	$74
	.BYTE	$B4
	.BYTE	$28
	.BYTE	$6E
	.BYTE	$74
	.BYTE	$F4
	.BYTE	$CC
	.BYTE	$4A
	.BYTE	$72
	.BYTE	$F2
	.BYTE	$A4
	.BYTE	$8A
	.BYTE	$0	;XXXYY100 INSTRS.
	.BYTE	$AA
	.BYTE	$A2
	.BYTE	$A2
	.BYTE	$74
	.BYTE	$74
	.BYTE	$74
	.BYTE	$72
	.BYTE	$44	;1XXX1010 INSTRS.
	.BYTE	$68
	.BYTE	$B2
	.BYTE	$32
	.BYTE	$B2
	.BYTE	$0
	.BYTE	$22
	.BYTE	$0
	.BYTE	$1A	;XXXYYY10 INSTRS.
	.BYTE	$1A
	.BYTE	$26
	.BYTE	$26	;(WAS 0)
	.BYTE	$72
	.BYTE	$72
	.BYTE	$88
	.BYTE	$C8
	.BYTE	$C4
	.BYTE	$CA
	.BYTE	$26
	.BYTE	$48
	.BYTE	$44
	.BYTE	$44
	.BYTE	$A2
	.BYTE	$C8

;SPECIAL SYMBOL TABLE

LGCH:	'/			;SLASH
	'%			;PERCENT
	'=			;EQUAL SIGN
	''			;QUOTE
	',			;COMMA
	'.			;DOT
	.CHESC			;ESCAPE
	.ATEOL			;CARRIAGE RETURN
	'[			;BRACKET
	.ATURW			;ATARI UP-ARROW
	.ATDRW			;ATARI DOWN-ARROW
	.ATLRW			;ATARI LEFT-ARROW
	.ATRRW			;ATARI RIGHT-ARROW
MAXL=.-LGCH-1

;DISPATCH FOR %<CHAR> CONTSTRUCTS

LGPC:	'X			;X REGISTER
	'Y			;Y REGISTER
	'A			;ACCUMULATOR
	'S			;STACK
	'F			;PROCESSOR STATUS
MAXS=.-LGPC-1

;THE FOLLOWING ARE ALL PAGE 0 VARIABLES

PERAD:	XREG			;ADDRS OF X
	YREG			;ADDRS OF Y
	AC			;ADDRS OF ACCUM
	SP			;ADDRS OF STACK PNTR
	PS			;ADDRS OF STATUS

;SPECIAL SYMBOL DISPATCH TABLE

LDISP:	.ADDR	SLSH-1		;SLASH - OPEN SYMBOLIC
	.ADDR	PERC-1		;PERCENT - SPECIAL REG
	.ADDR	TOC-1		;EQUAL - TYPE OCTAL
	.ADDR	QUOTE-1		;QUOTE - TYPE OUT ASCII
	.ADDR	COMMA-1		;COMMA	- SAVE STARTING ADDRESS
	.ADDR	DOT-1		;DOT - USE CURRENT LOC
	.ADDR	ESC-1		;ESCAPE - MORE FOLLOWS
	.ADDR	CRET-1		;CARRIAGE RETURN - CLOSE REG
	.ADDR	BRAKET-1	;BRACKET - OPEN REG (HEX)
	.ADDR	BACK-1		;ATARI ARROWS (PREV LOC)
	.ADDR	LFD-1		; (NEXT LOC)
	.ADDR	UNTAB-1		; POP PC STACK
	.ADDR	TAB-1		; PUSH PC - OPEN EA

;DISPATCH CHARACTER TABLES

DISP:	.ADDR	ASCII-1		;$A - ASSIGN ASCII TO MEMORY
	.ADDR	BKPT-1		;$B - SET BP
	.ADDR	ERR-1		;$C -
	.ADDR	TODOS-1		;$D - XFER TO DOS
	.ADDR	ERR-1		;$E -
	.ADDR	FIND-1		;$F - FIND BYTE
	.ADDR	GO-1		;$G - GO
	.ADDR	HDUMP-1		;$H - HEX DUMP TO TTY
	.ADDR	INIT-1		;$I - INITALIZE MEMORY
	.ADDR	ERR-1		;$J - 
	.ADDR	ERR-1		;$K - 
	.ADDR	PNTSEL-1	;$L - TOGGLE PRINTER
	.ADDR	MOVE-1		;$M - MOVE A BLOCK OF MEMORY
	.ADDR	ERR-1		;$N -
	.ADDR	OFFSET-1	;$O - CALCULATE BRANCH OFFSET
	.ADDR	PROC-1		;$P - PROCEED
	.ADDR	DISASS-1	;$Q - DISASSEMBLE
	.ADDR	RDSECT-1	;$R - READ DISK
	.ADDR	SEARCH-1	;$S - SEARCH FOR ADDRESS
	.ADDR	TYPE-1		;$T - TYPE OUT MEMORY IN ASCII
	.ADDR	SETU-1		;$U - SET DISK UNIT
	.ADDR	ERR-1		;$V - 
	.ADDR	WRSECT-1	;$W - WRITE DISK
	.ADDR	EXEC-1		;$X - SINGLE STEP
	.ADDR	ERR-1		;$Y -
	.ADDR	ZERO-1		;$Z - ZERO MEMORY
;NUMBER OF ARGUMENTS TABLE $FF=NONE, $0=1, $1=2, $80=NONE OR ONE

ARGNUM:	.BYTE	$00		;$A - ASSIGN ASCII TO MEMORY
	.BYTE	$80		;$B - SET BP
	.BYTE	$01		;$C -
	.BYTE	$FF		;$D - JUMP TO DOS
	.BYTE	$FF		;$E - 
	.BYTE	$01		;$F - FIND BYTE
	.BYTE	$00		;$G - GO
	.BYTE	$01		;$H - HEX DUMP TO TTY
	.BYTE	$01		;$I - INITALIZE MEMORY
	.BYTE	$FF		;$J - 
	.BYTE	$FF		;$K - 
	.BYTE	$00		;$L - TOGGLE PRINTER
	.BYTE	$01		;$M - MOVE A BLOCK OF MEMORY
	.BYTE	$FF		;$N - 
	.BYTE	$01		;$O - CALCULATE BRANCH OFFSET
	.BYTE	$80		;$P - PROCEED
	.BYTE	$01		;$Q - DISASSEMBLE
	.BYTE	$01		;$R - READ DISK
	.BYTE	$01		;$S - SEARCH FOR ADDRESS
	.BYTE	$01		;$T - TYPE OUT MEMORY IN ASCII
	.BYTE	$00		;$U - SELECT DISK UNIT
	.BYTE	$FF		;$V - 
	.BYTE	$01		;$W - WRITE DISK
	.BYTE	$FF		;$X - SINGLE STEP
	.BYTE	$FF		;$Y - 
	.BYTE	$01		;$Z - ZERO MEMORY

	END	START
