@L}5 _$% l0$)$$Hȱ$ UhL" `e$$%`$%`  R@P!( L(1   Y I`  d  Ld M * @  $ % CC$$)%1 Udߥ$9%: !0 S$% DD˙`  }J)Lr d M * @  $ % CC$$)%1 Udߥ$9%: !0 S$%} DD˙`  }J)Lr J  ((  p L ()   J}L= ( L 0q A    IB JC;? D W } LL  ` W )LA!  ߰")-݆ p" } $G@LL 08`Q")<2Q0 -G$Ș݆ UL# ; p8(()(0ʥ)NQ` }$GȘ݆LU )L ݆ L GȘ ݆LL )W>Z   HH)H }p h  hyhy D L> L JJ    ! LA*` BF }7'8  M HN H` 8 Z  \LdJJ!"! GFE@F (!L }EE !E^ ^ E E7EȩEdE/EȩE  D } .L }  ;F d  ;?F7F? ( .   Z D LL d } . D  L    p  E` , d)  D L) 0BM݊L݉} ML  N݆ L NLML [ TEqEHȱEqEh 0Gȹ G} HLL GɛL  LFREE SECTORS G) *Gȩ GȽG GȌ*jj >G} C8jJ3j2CD( C202C ԠBX` N 1? l LlD:RAMDISK}.COMLu L1 L ;LHL  T`  `1  ɐ     `TU  } L ? .  t`GBJ ~DEHI B V0dV!}QDEHI VF9 ,0 ,0 s0hhL  L` H hDHEh"}DEL8HI4 0 HI,0 0  9 .G VLO#},0 L4*IJ`llD1:AUTORUN.SYSNEED MEM.SAV TO LOAD THIS FILE.D1:MEM.SAV J y08 B|DEHI$} V0 0`B;DEL`?<0LV`@ʆ v s? F0Ξ05: [ BDEHI%} VY8 B V  @  /DE `E:D1:DUP.SYSERROR-SAVING USER MEMORY ON DISKTYPE Y TO &}STILL RUN DOS B;DE J  (` 9 V⪍ ઍ  -'}LLu ÝDEHILV 9 .l 9 .l  `` s$B BH(}I|DE V BLV nB,DE JLV B V BLVDEIʩ BꭝLu  } 3E:}DISK OPERATING SYSTEM II VERSION COPYRIGHT 1984 ATARI CORP.A. DISK DIRECTORY I. FORMAT DISKB. RUN CARTRIDG*}E J. DUPLICATE DISKC. COPY FILE K. BINARY SAVED. DELETE FILE(S) L. BINARY LOADE. RENAME FILE M. RUN AT ADDRES+}SF. LOCK FILE N. CREATE MEM.SAVG. UNLOCK FILE O. DUPLICATE FILEH. WRITE DOS FILES P. FORMAT SINGLEL !N',}#"&))9(&*)/h)''-&؆莟R'S  vL/ˢ L }Insert DOS 2.0s, type Y Λx -}DEfHI 1莏#q! @ y0ɛ8A0,' ȅ 1 1ild! 1L!NO SUCH ITEMSELECT.} ITEM OR FOR MENU! 0 .z:*{}.|{ 1 0 0JB 18L%|DL/}%DIRECTORY--SEARCH SPEC,LIST FILE?[# 0 0 &|D3" 1L!NOT A DISK FILEN !B 1L!E# 1 !BD0}ED:}:1BJ|DE 1DEBHI 1 h0ߢ 0.1}  0?詛 1 y0YЛ 1 ;#L" ;#L! BL1TYPE "Y" TO DELETE...DELETE FILE SPEC2}COPY--FROM, TO?OPTION NOT ALLOWED736 FREE SECTORS COPYING---D1:DIRECK.COMl# 0|D .L/%#3}##JB|DE 1BHID#E 1#0: B 1L!#͑### B 1#c$0SY4}S1}:## # # .#Ƚ# # 𩛙## 1,#PD#ELJ- <.BJD#E 5}1 1HH 0hh|DL%1}:̳# L% #D#EL% 1 0 . .0O% 1L!WILD CARDS NOT A6}LLOWED IN DESTINATION 0 <.|K}N 2 FORMAT. t* 5) 1L!`) 0NΞ 0 L1) 1 L!BAD LOAD FILELOAD FROM WHAT FILE?) 0 ?}0#B 1L!WHAT FILE TO LOCK?) 0 0$B 1L!WHAT FILE TO UNLOCK?DUP DISK-SOURCE,DEST DRIVES?TYPE "Y" IF OK TO US@}E PROGRAM AREACAUTION: A "Y" INVALIDATES MEM.SAV.FE! +L1   `*  70 2 2A} 0.* 1 y0 0)INSERT BOTH DISKS, TYPE RETURN^, 1 y038逍 N, 1L! ,B}C, t*  Lx+, 0 ^, 1 y0 , ,0,0 ,L+ ,I0 ,Vǭ0C}Ξ, 0 }, 1 y0C,ШC, 0K'!" H H 'h h Lx+!EF 5L1L!D,I,HhD}` NOT ENOUGH ROOMINSERT SOURCE DISK,TYPE RETURNINSERT DESTINATION DISK,TYPE RETURNE}`  `8 rL1`-* 1P* 1 y0Y`hhL!NAME OF FILE TO MOVE?- 0 0|DL% <.F},^ 1 70 0 .@L# .BJ 1  DEHIB V L1 ,} 1 70,L.  G}JB|,#P#DE 1 HI BDEHHII 1 B 1 ,^ 1 70,0La- B V,#PH},^ 1 70 0L#L!-* 1P* 1 y0Yj383}mm ݭI}}`8}``|* ? ɛ,`|:-)| / 1L!`DESTINATION CANT BE DOJ}S.SYS0 0H{ 24Δ 28/L!/) 2 Π 2 0 ξK}hAΞB,0 J 1 BDEHI,HÝDE 1HIHIDELSAVE-GIVE L}FILE,START,END(,INIT,RUN)O S0 1`BDEPHI V` S0H 1 L!M}0 0 1L~0`PLEASE TYPE 1 LETTER,0`hhL! 70 1L0L<1 ,;ɛ7,"ɛ:ݦ1ݥN}A"D|ݤD|ȩ:|ȩ|ɛ,,(/+.ީ1 1,ɛ`轤{NAMEO} TOO LONG B VL!` L1I H1EΝDL1|mDiE` V0`8d/8 i:222 1 LP}!ERROR- 138ɛ+,' 20*.. өr2 1``2TOO MANY DIGITSINVALID HEXAQ}DECIMAL PARAMETER800 0 8 00`,0'D800 H,ɛh`2L1NEED D1 THRU D8uR} ECIMAL PARAMETER800 0 8 00`,0'D800 H,ɛh`2L1NEED D1 THRU D8u@ 4 FFTG  2 UFTI7 *( (< @H `! \# *"x@./7 "x*B) ?B T}g ) c (C7| > *k"["`2j?Fa*!B 4 !  h#H  o*!O!L" L Dj/ OB2O+U}rQC"ր% ! ]BSX x!^x!¼! 4. a -A7 > /XHx*P8< B!  ?4y* a+!r*3x CbH4V} H * b!N8q*)b!dKYj a A+H8 D`)  C )8(Ni88NH!o 1 A_*L `#j/8D`!W}} !+ H :  "2J!(;! J v!Oa#< ()4 ԉ( c8 < > `+tZ < k XH8X}(K8<  'XJx'H* `'<z* E`'2τ' Oa2+vH/Oi/HH$   ! ț rH#D a*fH(@@)cY}B!#J @* c@@@ 8@8@@)29 ! `0#J@0cM6  !vȈ"' F!cjB ( x1(!RH!eZ}ȓ! H …) 8TJ8z)N y) < < < < v*Vx*X84^!(+XH8(x#Wr,_! )Z#WZ#W0;WȮ!΄ [}&xS9!*N <(N) R!x*rD!eȳ ;mHS! ()! ;.!a)ވ N J@, r !e  * N \} ^ *]"!@"!р& "!x*! @J s+ O4+H<y 4& N ʂ`! 8NX x#Wi8G(HT!a,]}M"Da+H| a+r}@E!4Kx#U L4!+cJS! tf)8K!:ʄB!*cXJx#W(Nj!8NS*:ha9Hx!ފ^!(NXH8^}XHx+W84O@_!D!Z B!A!eȫ AX8! }6 w+a**B! # XJx#H! 8 C 4 8C 4!H_}! y+ B!@!)8 C 4Q x3H4a+r?@4!E!\ @,!E!a( <B+LJ`$ !JC`! 8N*z(N<X) `} : K}S'!H!  `*Px!! !_@2 @( !8(&oȲAr@o@7|D 2 sA23@F  I8~*a} a+|S ?vH<! #*B8B2B2$ 4 +Ȋ B! a)?B(!!F!(x# yA"Ca#b}Ȉ} @,!B 42X*    @    &v8Ia)Ē&@ A!J@!I!e#, k#H+ H ZCc}`#*8C .>;.  4/ D/4?@8"*4΄& ؃`* ʃ'Jb'4)D@*&b9#0. $ ikk* NYd}4 &z/OH$8 A< !  (& A/<b,  $8 A;V9x9X.# XH8+:B`! !:(  k M 24 _+ M e} ؋ _D* *!HR)P* ڍ*"NH! vB!Ho *# XJx#ȫM69Ȉ8I(! 2 Ld< H b#*Zf}@ =H :"(4 o L:4 *B`. H$= $ "Fa/2(@x,J$,r J/@@@%H,g}4 *K"`  D,4N4B}""8N8Mb!H8N**&:"$R><"t  C8 "&Nd 4444h}444 444#4C4# 4444@ DAB@F(HG(B+J2E2F(A j+i} 'F8AM(-"%"E2F:%@ !G G'" (G  '"2 D(2R B@"EGV4Q9N9V !j} HQ H] Hp H~ ȓ && .H& 6H @ ! & FH! !J_!0l!aH  L& DH ?@?H@@?@`V !y;ALBUG.M65.71 12-Mar-82 15:25:26, Edit by HESS .TITLE LBUG - 6502 DEBUGGER (ATARI VERSION) ; (C) Ted Hess, Hud l}son, Ma. 1977,1978,1979,1980,1981,1982 .LIST MB ;LIST BINARY IN MACROS .NLIST TOC ;NO TABLE OF CONTENTS .ENABL LC ;AL m}LOW LOWER CASE TEXT ; INVOKE SYSTEM MACROS FOR PARAMETER DEFINITIONS .MCALL ATARI .MCALL M6502 ATARI M6502 ;***** TH n}INGS TO DO ****** ; ; 1) Re-write parser for DDT syntax and better defaults ; Make better use of ATARI keyboard! ; ;********* o}**************** ;LBUG STORAGE ASSIGNMENTS (PAGE 0) INBUF =$E0 ;INPUT BUFFER (2 BYTES) POINT =$E2 ;OPEN CELL ADDRS (2 BYT p}ES) AC =$E4 ;ACCUMULATOR XREG =$E5 ;X INDEX YREG =$E6 ;Y INDEX PS =$E7 ;PROCESSOR STATUS REG SP =$E8 ;STACK POINTER ;RA q}NDOM CONSTANTS AND PARAMETERS DSKCOD =$31 ;DISK DEVICE CODE DSKR ='R ;DISK READ COMMAND DSKW ='W ;DISK WRITE COMMAND MAXB r}P =8 ;EIGHT IS TRADITIONAL (BREAK POINTS) LNSCR =24 ;# OF LINES ON SCREEN LPP =55 ;LINES/PAGE ON PRINTER .IIF NDF,LORG, L s}ORG= $8000 ;DEFAULT PROG ORIGIN ;MAIN ENTRY POINT - NORMAL START (LORG) ;RESET ENTRY - REMOVE BREAKPOINTS (LORG+3) SETPC t}PPC,LORG ;NORMAL START ENTRY START: JMP STRT1 JMP RST VERS: .ASCII <.ATCLR>"Lady Bug - V4.0, (C) Ted Hess 1981"<.ATEOL> R u}OF: .BLKB 1 ; REGISTER OPENED FLAG ; 0 = CLOSED ; $1 = HEX/OCTAL ; $FF = SYMBOLIC CF: .BLKB 1 ;ADDRESS FLAG ; v} $FF = NO ADDRESSES TYPED ; $00 = ONE ADDRESS TYPED ; $01 = COMMA TYPED PRPC: .BLKB 2 ;PROGRAM COUNTER (AT BREAK) LEN w}GTH: .BLKB 1 ; LENGTH OF INSTR (0 := 1-BYTE) PFRMT: .BLKB 1 ; PRINT FORMAT INDEX VEB: .BLKB 2 ;4 BYTE PROGRAM BLOCK LMNEM: .B x}LKB 1 ;(VEB+2) TEMP FOR MNEMONIC PRINT RMNEM: .BLKB 1 ;(VEB+3) ... STARTA: .BLKB 2 ;STARTING ADDRESS ENDAD: .BLKB 2 ;ENDING A y}DDRESS TEMPX: .BLKB 1 ;NEED TO SAVE X AROUND OS TEMPY: .BLKB 1 ;TEMP SAVE Y SNGLF: .BLKB 1 ;SINGLE STEP FLAG BPN: .BLKB 1 ;BR z}EAKPOINT 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 ENTR }}Y RST: CALL REMB ;REMOVE BREAK POINTS ; NORMAL STARTUP JOINS HERE STRT1: CALL INITS ;INITIALIZE THINGS TYPE VERS ;OUT ~}PUT HERALD CLR ;CLEAR SS FLAG, ETC. SET2 BREAK,VBREAK ;BREAK POINT ENTRY TSX ;SAVE CURRENT STACK PO }INTER STX SP JMP RALL ;CLEAR ALL BREAK POINTS ;MAIN DECODER ERR: CALL ERRFST ;PRINT ? 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 L }EGAL CHARACTER CLGL: LDX #MAXL ;INIT INDEX LGL1: CMP LGCH,X ;MATCH? BEQ LGL2 ;YES - PROCEED DEX ;NO - STEP TO NEXT B }PL 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 NO }W 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 A }RGUMENT FLAG IN AC BNE ERR ;MUST BE ONE AND ONLY ONE ARGUMENT TYPED SO FAR CALL GETNUM ;GET ANOTHER ARGUMENT COMMA1: MOV2 }X 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 I }S 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 L }ESS THAN MAXIMUM ALLOWABLE BREAKPOINT BMI ESCB ;YES GO GET BREAKPOINT B SBC #@20 ;CHECK FOR A BMI ERR ;IF LESS THAN A I }T 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 GI }VE ERROR 10$: TXA ;GET INDEX BACK TO A CLC ADC #/2 ;CALC TABLE OFFSET BNE LGL3 ;DISPATCH ESCB: TAX ;SAV }E 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 INT }O BUFFER DOT1: CALL GETSCH ;GET ANOTHER CHARACTER INC CF ;SAY QUANT TYPED BNE COMMA1 ;GO SET UP ENDING ADDRESS JMP SCAN }1 ;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 INBU }F ;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 ERR }OR LDA #$FF ;SET ROF FLAG BNE SLSH1 ;JOIN COMMON CODE ;SLASH TYPED - OPEN A REG (HEX) BRAKET: BPL ERR1 ;IF MORE THAN O }NE 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 ;I }F MORE THAN ONE ARGUMENT IT IS AN ERROR CALL CRLFS ;OUTPUT LFD0: LDA ROF ;CHECK TYPE BMI LFDS ;DO SYMBOLIC NEXT IN }STR CALL CLSE ;CLOSE OPEN REG IF ANY CALL INCPT ;STEP TO NEXT LOC LFDC: INC ROF ;MARK OPEN HEX LDX #'[ ;SLASH CALL PR }TSLC ;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 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 1 }5$: 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 CO }MPARE 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 BAC }K TO MAIN SCANING LOOP ;$B - BREAKPOINT COMMAND BKPT: LDX #$FF ;SAY NO BREAKPOINT NUMBER GIVEN BKPT1: LDA CF ;GET ARGUME }NT 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 ER }R ;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 BP }INS,X ;SAVE IN TABLE LDA INBUF ;SAVE ADDRS STA BPLOCL,X ; LOW LDA INBUF+1 ; AND HIGH STA BPLOCH,X ;... ; ... ; ... BP }XIT: CALL PRBLNK ;PRINT SOME SPACES JMP SCAN ;BACK TO DECODER ;ROUTINE TO CLEAR ONE BREAKPOINT ;C(X) - INDEX INTO BP TAB }LES, 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 Z }ERO 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 PRT }SBY ;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 DI }SK SECTORS INTO MEMORY RDSECT: CALL GETVAL ;GET BUFFER ADDRS LDA #DSKR ;READ COMMAND INIDSK: STA DCOMND ;STORE MOV2 INB }UF,DBUFLO ;SETUP BUFFER CALL INTPTC ;SET POINT := START SECTOR LDA #DSKCOD ;BUS I.D. FOR DISK STA DDEVIC LDA DRVNO ;SE }TUP DRIVE # STA DUNIT LDA #128 ;BYTE COUNT STA DBYTLO CLR DBYTHI DSKLUP: MOV2 POINT,DAUX1 ;SETUP SECTOR ADDRS CALL DSKI }NV ;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 ? CALL OUTSSP LDA DSTATS ;GET STATUS CALL PRTSBY ;PRINT ERROR CODE C }ALL 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 IND }EX 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 SOME }WHERE GO: CALL INTPTC ;GO SETUP ADDRESS CLR ;CLEAR CURRENT BP GO2: CALL INSB ;INSERT BP'S GO3: LDX SP ;RESTO }RE 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 GO }1: LDY IOPC ;CHECK FOR JUMPS CPY #$4C BEQ GOJMP ;VANILLA JUMP CPY #$6C ;MAYBE JUMP, INDIRECT BEQ GOJMPI ; A LITTLE MO }RE HAIRY CPY #$60 ;"RTS"? BEQ IRTS ; INTERPRET SUBROUTINE RETURN CPY #$40 ;"RTI" BEQ IRTI ; INTERPRET INTERRUPT RETUR }N BNE GO3 ; AND GO EXECUTE GOJMP: SET2 XCTBR,POINT ;EXECUTE HERE BNE GO3 GOJMPI: MOV2 XBTARG,POINT ;NEED TO PICK UP ACTU }AL 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" I }NC 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: C }ALL INTPT ;SET UP START AND END ADDRESS LDA POINT ;GET LOW PART OF ADDRESS AND #$F0 ;MAKE IT START ON A NICE BOUNDRY ST }A POINT 10$: CALL SETOUT ;SETUP OUTPUT DEVICE / GET LPP STA LENGTH ; SAVE IT AWAY 20$: CALL CRLFS ;PRINT OUT CARRAGE RETU }RN LINEFEED CALL PRTSPT ;PRINT OUT THE LOCATION LDA #$10 ;NUMBER OF BYTES PER LINE CALL DMPLIN ;PRINT A LINE OF DUMP C }ALL ENDCHK ;CHECK TO SEE IF WE ARE FINISHED DEC LENGTH ;COUNT LINE BNE 20$ ;GO DO ANOTHER LINE CALL PAGEWT ;GO WAIT FO }R 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 MEMO }RY TO SPECIFIED VALUE CALL ENDCHK ;CHECK TO SEE IF FINISHED JMP 10$ ;NO GO DO ANOTHER VALUE ;$Z - ZERO MEMORY ZERO: LD }X #0 ;GET A ZERO BEQ INITM1 ;GO INITIALIZE MEMORY ;$M - MOVE A BLOCK OF STORE MOVE: LDA #$8D ;GET STORE OPCODE CALL IN }TIVB ;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 PR }INTER FLAG STA PNTF JMP BPXIT ;RETURN TO MAIN LOOP ;$O - CALCULATE BRANCH OFFSET OFFSET: CALL PRBLNK ;PUT OUT SOME BLAN }KS CLC ;MAKE FROM BE ONE MORE LDA ENDAD ;GET FIRST OF TO ADDRESS SBC STARTA ;SUBTRACT FROM ADDRESS TAX ;SAVE LOW OR }DER PART OF ADDRESS LDA ENDAD+1 ;GET HIGH PART OF TO ADDRESS SBC STARTA+1 ;SUBTRACT FROM ADDRESS TAY ;SAVE HIGH ORDER B }YTE 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 ORDE }R 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 PER }R ;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 ;G }ET LENGHT, EA, FORMAT MOV2 INBUF,XBTARG ;SET EA TO BRANCH TARGET LDX #$EA ;GET NOP STX IOPC+1 ;INIT FOR 1 BYTE INSTR ST }X IOPC+2 LDA (POINT),Y ;GET OPCODE BNE 5$ ;CONVERT "BRK" INTO "NOP" TXA 5$: STA IOPC LDA LENGTH ;LENGTH OF INSTR BEQ I }XCT1 ;1 BYTE - GO NOW CALL INCPT ;MOVE TO NEXT BYTE LDA PFRMT ;CHECK FOR BRANCH CMP #$1D ; INSTR BNE IXCT3 ;NOT BRAN }CH 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: C }ALL INCPT ;STEP TO INSTR AFTER THIS ONE MOV2 POINT,XNOBR ;SETUP NO BRANCH LOC SET2 IOPC,POINT ;SET START ADDR TO IOPC BLOC }K JMP GO1 ;AND START UP ;EXECUTE BLOCK FOR INSTR XCT SIMULATOR IOPC: BEQ XCTBR .BYTE $EA ;NOP STY YREG ;SAVE NEW STAT }E AFTER $X STX XREG STA AC PHP PLA STA PS ;PROCESSOR STATUS TSX STX SP ;STACK POINTER XCTNB: MOV2 XNOBR,POINT ;NO BR }ANCH OCCURED JMP BRKY XCTBR: MOV2 XBTARG,POINT ;BRANCH OCCURED JMP BRKY XNOBR: .BLKW 1 ;SAVED POINTERS FOR SINGLE STEP X }BTARG: .BLKW 1 ;$Q - DISASSEMBLE CODE DISASS: CALL INTPT ;SET UP POINT 10$: CALL SETOUT ;SET OUTPUT DEVICE STA CF ; RE }TURNS LINES/PAGE 20$: CALL CRLFS ;PUT OUT CARRIAGE RETURN LINE FEED CALL PRTSLS ;GO PRINT A LINE CALL ENDCHK ;CHECK TO S }EE IF FINISHED LDA LENGTH ;GET LENGTH OF INSTRUCTION CLC ;ONE ALREADY ADDED AT ENDCHK CALL PCADJ3 ;POINT TO NEXT INSTR }UCTION STA POINT ;SAVE UPDATED ADDRESS STY POINT+1 DEC CF ;ACCOUNT FOR LINE BNE 20$ ;GO DO ANOTHER INSTRUCTION CALL P }AGEWT ;GO WAIT FOR GO AHEAD BNE 10$ ;GO DO ANOTHER PAGE ;ROUTINE TO SETUP FOR OUTPUT - CHECK PNTF FOR PRINTER SETOUT: LD }A 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 SE }ARCHING 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 M }ATCH 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 TH }E 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 ;DECREMEN }T THE PC DECPT: SEC ;PREPARE TO DECREMENT POINT LDA POINT SBC #1 STA POINT BCS 10$ DEC POINT+1 ;HANDLE BORROW 10$: R }ET ;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 ;ROUTI }NES TO PICK UP VALUES ; GET ADDITIONAL VALUE, PROMPT FOR INPUT, ERROR IF NOT ; TERMINATED BY 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 ANOTH }ER CHARACTER BEQ 10$ ;IF HEX GO GET ANOTHER CHARACTER ;;; ... ; FALL INTO ABTCHK ;CHECK FOR RUBOUT OR BREAK. IF FOUND RE }TURN 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 GET }SCH ;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 1 }0$ ;NO. INVALID CHARACTER RETURN CMP #.ATRUB ;RUBOUT BEQ 10$ ;YES. INVALID CHARACTER RETURN AND #@337 ;GET RID OF LO }WERCASE 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 BI }T 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 PROCEE }D ;ROUTINE TO GET A CARACTER ; RETURNS CHARACTER IN A ; USES Y GETSCH: STX TEMPX ;SAVE X STY TEMPY ; AND Y AROUND O/S L !}DA #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$ ;RE #}TURN CHAR - NO ECHO 20$: CPY #BRKABT ;BREAK KEY TYPED? BNE 30$ TYA ;YES - RETURN BREAK FLAG 30$: LDX TEMPX ;RESTORE L $}DY 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 PURPOS &}E PRINTING ROUTIMES ;PRINT LOCATION AND IT'S CONTENETS IF FORM SPECIFIED BY ROF PRTSLS: LDA #$FF ;SET THE TYPEOUT MODE BAC '}K 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 SYMBOL +}IC JMP 10$ ; AND RETURN TO CMD LOOP ;DUMP NUMBER OF LOCATIONS IN A TO SCREEN DMPLIN: STA PFRMT ;SAVE IT CALL PRBLNK ;S ,}PACE OVER 2 BEQ 20$ ;DO NOT INCREMENT POINTER FIRST TIME 10$: CALL INCPT ;INCREMENT THE POINTER CALL OUTSSP ;PRINT BLAN -}K 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 ;L /}OOP TILL COUNT = 0 RET ;ROUTINE TO OUTPUT CHARACTER TO OUTPUT PORT ; CHARACTER IN A ; USES Y AND RETURNS CHARACTER IN A 0}OUTSSP: LDA #.CHSP ;LOAD UP A BLANK OUTSCH: STX TEMPX ;SAVE X & Y AROUND O/S CALLS STY TEMPY OUTSCN: PHA ;SAVE THE CHARA 1}CTER TAY ; AND MOVE TO Y LDX PIOCB ;GET IOCB INDEX LDA #PUTCHR ;1 CHAR OUTPUT CALL CIOC ;OUTPUT TO EDITOR/PRINTER L 2}DX TEMPX ;RESTORE X LDY TEMPY ;RESTORE Y PLA RET ;ROUTINE TO WRITE OUT CARRIAGE RETURN LINE FEED ; USES A AND Y CRLFS 3}: LDA #.ATEOL JMP OUTSCH ;WRITE IT OUT AND RETURN ;ROUTINE TO PRINT CURRENT LOCATION ; PRINTS POINT ; USES A AND Y PRTSPT 4}: LDA POINT+1 ;GET HIGH ORDER BYTE CALL PRTSBY LDA POINT ;GET LOW ORDER BYTE ;;; ... ;FALL INTO PRTSBY ;ROUTINE TO PR 5}INT 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 6}A CALL HEXSTA ;GO CONVERT IT TO HEX PLA ;GET THE ORGINAL BYTE BACK ;;; ... ; FALL INTO HEXSTA ;ROUTINE TO CONVERT A 7}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 8} CARRY BMI HEXST1 ;IF NEGATIVE IT IS A DECIMAL DIGIT ADC #$07 ;ADD IN OFFSET TO GET A-F HEXST1: ADC #$30 ;CONVERT TO ASC 9}II 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 CL ;}OSEP ;CLOSE PRINTER IF OPEN ;SET UP VEB AREA INTSVB: LDA #$AD ;LDA OP CODE INTIVB: STA VEB INTVEB: LDA STARTA ;SET UP SU <}B 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 OPE >}N 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,I A}CBAL,X ;POINT TO DEVICE TEXT LDA #OPEN ;OPEN COMMAND CIOC: STA ICCOM,X ;STORE COMMAND LDA #0 ;SET LENGTH TO ZERO STA IC B}BLL,X STA ICBLH,X TYA ;MIGHT HAVE CHARACTER CALL CIOV ;INVOKE O/S STY DSTATS ;PUT COMPLETION CODE HERE BPL INCRET ; C}RETURN IF NO ERROR CPY #BRKABT ;BREAK TYPED? BEQ 10$ JMP IOCERR ;COMMON ERROR HANDLER 10$: JMP ABORT ;ABORT I/O - RETU D}RN TO TOP LEVEL ; CLOSE PRINTER IOCB CLOSEP: LDX PIOCB ;SETUP IOCB INDEX BEQ INCRET ;RETURN IF NONE CLR PIOCB ;FLAG NO E} PRINTER LDA #CLOSE ;CLOSE COMMAND BNE CIOC ; INVOKE CIO PDEV: .ASCII "P:"<.ATEOL> ;GENERAL BREAKPOINT ROUTINES ;ROUT F}INE 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 G}ZERO CALL SETA ;SET UP ADDRS STA (INBUF),Y ;STORE INSTR 10$: DEX BPL 5$ ;LOOP OVER ALL RET ;RETURN ;SETUP ADDRS OF G H}IVEN BREAKPOINT FOR INDIRECT ;RETURNS INBUF WITH BPLOC,X , Y := 0 ;PRESERVES AC SETA: LDY BPLOCL,X ;GET LOW ADDRS BYTE STY I}INBUF ;USE THIS AS TEMP LDY BPLOCH,X ;GET HIGH ADDRS BYTE STY INBUF+1 LDY #0 ;SET FOR GLOBAL INDIRECT RET ;RETURN ;R J}OUTINE TO INSERT BREAKPOINTS INSB: LDX #MAXBP-1 ;DO ALL 5$: LDA BPINS,X ;SEE IF ACTIVE BEQ 10$ ;SKIP IF NO BP CALL SETA K} ;SET UP ADDRS LDA (INBUF),Y ;GET OLD INSTR STA BPINS,X ;SAVE OLD INSTR LDA #0 ;PUT BREAK IN PLACE STA (INBUF),Y ;... 1 L}0$: DEX BPL 5$ ;LOOP TILL DONE RET ;RETURN ;INTERUPT SERVICES ;IRQ - INSTRUCTION OR ACTUAL APPLICATION INT. BRE M}AK: PLA ;AC IS ON STACK STA AC ;SAVE ACCUM PLA ;PROCESSOR STATUS STA PS STY YREG ;SAVE INDEX REGS STX XREG PLA N};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 ; O}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 P}STACK PNTR STX SP ; SAVE IT AWAY CALL REMB ;REMOVE BREAKPOINTS NOW LDX #MAXBP ;SEARCH FOR BPN 25$: LDA BPINS-1,X ;ACTIV Q}E 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 R};STEP TO NEXT BNE 25$ ; MORE TO DO STX BPN ;SIGNAL NO B.P. BEQ BRKX ;NONE FOUND (MAYBE PANIC) ;.. ;.. 35$: LDA PRPC S} ;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 ;BRE T}AT 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 SN U}GLF ; NOT SINGLE STEP SETXA IXCT ;EXIT THROUGH HERE BRKRTI: PHA ;SAVE HIGH PC TXA ;GET LOW PHA ;SAVE IT TOO LDA P V}S PHA ;CURRENT PROCESSOR STATUS RTI ;DISMISS TO ROUTINE ;HERE TO ENTER BREAKPOINT - CLEAR SINGLE STEP FLAG BRKX: CLR W} SNGLF ; CLEAR SS FLAG SETXA DOBRK BNE BRKRTI ;EXIT INT TO DOBRK DOBRK: CALL CRLFS ;PUT OUT A CR/LF LDA #'B ;PRINT BN X};ADDRS CALL OUTSCH LDA BPN ;MAYBE 0 CALL HEXSTA ;TYPE LOW 4 BITS LDA #'; CALL OUTSCH JMP LFDS1 ;GO PRINT OUT ADDRESS Y} AND INSTR. BRKY: MOV2 POINT,PRPC ;SINGLE STEP ENTRY - POINT HAS PC LDA SNGLF ;WAS THIS SINGLE STEP? BNE DOBRK ; SIMULAT Z}E 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 a} LDA PFRMT CMP #$E8 ;HANDLE REL ADDRESSING MODE BNE PRADR2 ;IF NOT DO NOT ADJUST NUMBER OF BYTES INY ;IF RELATIVE BRAN b}CH PRINT 2 BYTES CLR PFRMT ;CLEAR PFRMT PRADR2: LDA INBUF-1,Y ;SPECIAL (PRINT TARGET ADDRS) CALL PRTSBY ;OUTPUT 1 OR 2 BY c}TE ADDRS DEY ; MSB FIRST BNE PRADR2 PRADR3: ASL PFRMT ;TEST NEXT PRINT FORMAT BIT BCC PRADR4 ;IF 0, DON'T PRINT LDA C d}HAR1-1,X ; CORRESPONDING CHARS CALL OUTSCH ;OUTPUT 1 OR 2 CHARS LDA CHAR2-1,X ; (IF CHAR FROM CHAR2 IS 0, BEQ PRADR4 ; e}DON'T OUTPUT IT) CALL OUTSCH PRADR4: DEX BNE PRADR1 RET ;SET UP LENGTH, PFRMT AND EFFECTIV ADDRESS ; RETURNS INDEX INTO f}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 O g}NE BYTE LDA (POINT),Y ;GET OPCODE TAY ;SAVE IN Y LSR A ; EVEN/ODD TEST BCC IEVEN LSR A ; TEST B1 BCS IERR ; XXXXXX q}B%DOS SYSB*)DUP SYSBSAUTORUN SYSB>kALBUG M65BSYSMAC SML11 INSTR INVALID CMP #$22 BEQ IERR ; 10001001 INSTR INVALID AND #$7 ;MASK 3 BITS FOR ADDRS MODE ORA #$80 ; ADD INDEXIN r}G OFFSET. IEVEN: LSR A ;LSB INTO CARRY FOR TAX ; LEFT/RIGHT TEST BELOW. LDA MODE1,X ;INDEX INTO ADDRS MODE TABLE BCS R s}TMODE ;IF CARRY SET USE LSD FOR LSR A ; PRINT FORMAT INDEX. LSR A LSR A LSR A ; IF CARRY CLEAR, USE MSD RTMODE: AND #$ t}F ;MASK FOR 4-BIT INDEX BNE GETFMT ; 0 FOR INVALID OPCODES IERR: LDY #$80 ;SUBSTITUTE $80 FOR INVALID OP. LDA #$0 ;SET u}PRINT FORMAT TO 0 GETFMT: TAX LDA MODE2,X ;INDEX INTO PRINT FORMAT TABLE STA PFRMT ;SAVE FOR ADDRESS FIELD FORMAT AND #$ v}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 w} LDY LENGTH ;GET LENGTH BEQ 10$ ;IF ZERO SET CURRENT ADDRESS IN INBUF FOR TAB LDA (POINT),Y ;GET FIRST BYTE OF ADDRESS x}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$ ;N y}O GO DO JUST ONE BYTE CALL RELADR ;GO CALCULATE RELATIVE ADDRESS STY INBUF+1 ;SAVE HIGH ORDER BYTE TXA ;GET LOW ORDER z}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 ; XXXYYY1 }0 -> 00110XXX BNE 50$ ; XXXYY100 -> 00100XXX INY ; XXXXX000 -> 000XXXXX 60$: DEY BNE 40$ RET ;HERE TO HANDLE RELATIV }E 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 INT }O Y (PCH) 20$: RET ;TABLES MODE1: .BYTE $40 .BYTE $2 .BYTE $45 .BYTE $3 .BYTE $D0 .BYTE $8 .BYTE $40 .BYTE $9 .BYT }E $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 .BY }TE $22 .BYTE $44 .BYTE $33 .BYTE $D0 .BYTE $8C .BYTE $44 .BYTE $0 .BYTE $11 .BYTE $22 .BYTE $44 .BYTE $33 .BYTE $D }0 .BYTE $8C .BYTE $44 .BYTE $9A .BYTE $10 .BYTE $22 .BYTE $44 .BYTE $33 .BYTE $D0 .BYTE $8 .BYTE $40 .BYTE $9 .BY }TE $10 .BYTE $22 .BYTE $44 .BYTE $33 .BYTE $D0 .BYTE $8 .BYTE $40 .BYTE $9 .BYTE $62 .BYTE $13 ;YYXXXZ01 INSTRS. .B }YTE $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) .B }YTE $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 $5 }D .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 .BY }TE $0 .BYTE $15 ;XXXYYY10 INSTRS. .BYTE $9C .BYTE $6D .BYTE $9C ;(WAS 0) .BYTE $A5 .BYTE $69 .BYTE $29 .BYTE $53 .BY }TE $84 ;XXXYYY01 INSTRS. .BYTE $13 .BYTE $34 .BYTE $11 .BYTE $A5 .BYTE $69 .BYTE $23 .BYTE $A0 MNEMR: .BYTE $D8 ;XXXX }X000 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 INS }TRS. .BYTE $AA .BYTE $A2 .BYTE $A2 .BYTE $74 .BYTE $74 .BYTE $74 .BYTE $72 .BYTE $44 ;1XXX1010 INSTRS. .BYTE $68 .B }YTE $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 '. ;DO }T .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 % 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 ;SPE }CIAL 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 - SE }T 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 - CA }LCULATE BRANCH OFFSET .ADDR PROC-1 ;$P - PROCEED .ADDR DISASS-1 ;$Q - DISASSEMBLE .ADDR RDSECT-1 ;$R - READ DISK .ADDR S }EARCH-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 MEM }ORY ;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 OFFSE }T .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 V - .BYTE $01 ;$W - WRITE DISK Z;SYSMAC.SML.27 8-Mar-82 08:39:38, Edit by HESS ;6502 SYSTEM -*-MACRO-*- DEFINITIONS ; ***** ATARI SYSTEM DEFS }***** .MACRO ATARI ; VECTOR TABLE EDITRV =$E400 ;EDITOR SCRENV =$E410 ;TELEVISION SCREEN KEYBDV =$E420 ;KEYBOARD PRI}NTV =$E430 ;PRINTER CASETV =$E440 ;CASSETTE ; JUMP VECTOR TABLE DISKIV =$E450 ;DISK INITIALIZATION DSKINV =$E453 ;D}ISK INTERFACE CIOV =$E456 ;CIO ROUTINE SIOV =$E459 ;SIO ROUTINE SETVBV =$E45C ;SET VERTICAL BLANK VECTORS SYSVBV =$E45F} ;SYSTEM VERTICAL BLANK ROUTINE XITVBV =$E462 ;EXIT VERTICAL BLANK ROUTINE SIOINV =$E465 ;SIO INIT SENDEV =$E468 ;SEN}D ENABLE ROUTINE INTINV =$E46B ;INTERRUPT HANDLER INIT CIOINV =$E46E ;CIO INIT BLKBDV =$E471 ;BLACKBOARD MODE WARMSV =$}E474 ;WARM START ENTRY POINT COLDSV =$E477 ;COLD START ENTRY POINT RBLOKV =$E47D ;CASSETTE READ BLOCK VECTOR DSOPIV =$E}480 ;CASSETTE OPEN FOR INPUT VECTOR ; SOME USEFUL INTERNAL ROUTINES KGETCH =$F6E2 ;GET CHAR FROM KEYBOARD EOUTCH =$F6A4} ;OUTPUT CHAR TO SCREEN PUTLIN =$F385 ;OUTPUT LINE TO IOCB#0 ; COMMAND CODES FOR IOCB OPEN =$03 ;OPEN FOR INPUT/OUTPU}T GETREC =$05 ;GET RECORD (TEXT) GETCHR =$07 ;GET CHARACTER(S) PUTREC =$09 ;PUT RECORD (TEXT) PUTCHR =$0B ;PUT CHARAC}TER(S) CLOSE =$0C ;CLOSE DEVICE STATIS =$0D ;STATUS REQUEST SPECIL =$0E ;SPECIAL ENTRY COMMANDS ; SPECIAL ENTRY COMMAN}DS DRAWLN =$11 ;DRAW LINE FILLIN =$12 ;DRAW LINE WITH RIGHT FILL RENAME =$20 ;RENAME DISK FILE DELETE =$21 ;DELETE D}ISK FILE FORMAT =$22 ;FORMAT DISK LOCKFL =$23 ;LOCK FILE (READ ONLY) UNLOCK =$24 ;UNLOCK FILE POINT =$25 ;POINT SECTO}R NOTE =$26 ;NOTE SECTOR CCIO =$28 ;CONCURRENT I/O MODE IOCFRE =$FF ;IOCB "FREE" ; AUX1 VALUES FOR OPEN APPEND =$01} ;OPEN FOR APPEND DIRECT =$02 ;OPEN FOR DIRECTORY ACCESS OPNIN =$04 ;OPEN FOR INPUT OPNOT =$08 ;OPEN FOR OUTPUT OPNIN}O =OPNIN!OPNOT ;OPEN FOR INPUT/OUTPUT MXDMOD =$10 ;OPEN FOR MIXED MODE INSCLR =$20 ;OPEN WITHOUT CLEARING SCREEN ; OS S}TATUS CODES SUCCES =$01 ;SUCCESSFUL OPERATION BRKABT =$80 ;(128) BREAK KEY ABORT PRVOPN =$81 ;(129) IOCB ALREADY OPEN }NONDEV =$82 ;(130) NON-EX DEVICE WRONLY =$83 ;(131) IOCB OPENED FOR WRITE ONLY NVALID =$84 ;(132) INVALID COMMAND NOTOP}N =$85 ;(133) DEVICE OR FILE NOT OPEN BADIOC =$86 ;(134) INVALID IOCB NUMBER RDONLY =$87 ;(135) IOCB OPENED FOR READ ON}LY EOFERR =$88 ;(136) END OF FILE TRNRCD =$89 ;(137) TRUNCATED RECORD TIMOUT =$8A ;(138) DEVICE TIMEOUT DNACK =$8B ;(}139) DEVICE DOES NOT ACK COMMAND FRMERR =$8C ;(140) SERIAL BUS FRAMING ERROR CRSROR =$8D ;(141) CURSOR OUT OF RANGE OVRRU}N =$8E ;(142) SERIAL BUS DATA OVERRUN CHKERR =$8F ;(143) SERIAL BUS CHECKSUM ERROR DERROR =$90 ;(144) DEVICE ERROR (OPE}RATION INCOMPLETE) BADMOD =$91 ;(145) BAD SCREEN MODE NUMBER FNCNOT =$92 ;(146) FUNCTION NOT IN HANDLER SCRMEM =$93 ;(1}47) INSUFFICIENT MEMORY FOR SCREEN MODE ; PAGE 0 LOCATIONS LINZBS =$00 ;LINBUG STORAGE ; THESE LOCS ARE NOT CLEARED C}ASINI =$02 ;CASSETTE INIT LOC RAMLO =$04 ;RAM POINTER FOR MEM TEST TRAMSZ =$06 ;TEMP LOC FOR RAM SIZE TSTDAT =$07 ;RA}M TEST DATA LOC ; CLEARED ON COLDSTART ONLY WARMST =$08 ;WARM START FLAG BOOTQ =$09 ;SUCCESSFUL BOOT FLAG DOSVEC =$0A } ;DOS START VECTOR DOSINI =$0C ;DOS INIT ADDRESS APPMHI =$0E ;APPLICATION MEM HI LIMIT ; CLEARED ON COLD OR WARM START} INTZBS =$10 ; START OF OS RAM CLEAR LOC => $7F POKMSK =$10  ;SYSTEM MASK FOR POKEY IRQ ENABLE BRKKEY =$11 ;BREAK KEY F}LAG RTCLOK =$12 ;REAL TIME CLOCK (60HZ OR 16.66666 MS) BUFADR =$15 ;INDIRECT BUFFER ADDRESS REG ICCOMT =$17 ;COMMAND FO}R VECTOR HANDLER DSKFMS =$18 ;DISK FILE MANAGER POINTER DSKUTL =$1A ;DISK UTILITIES POINTER PTIMOT =$1C ;PRINTER TIME O}UT REGISTER PBPNT =$1D ;PRINT BUFFER POINTER PBUFSZ =$1E ;PRINT BUFFER SIZE PTEMP =$1F ;TEMP REG ZIOCB =$20 ;PAGE 0} I/O CONTROL BLOCK IOCBSZ =16 ;NUMBER OF BYTES / IOCB MAXIOC =8*IOCBSZ ;LENGTH OF IOCB AREA IOCBAS =ZIOCB ICHIDZ =$20 ;}HANDLER INDEX NUMBER ($FF := IOCB FREE) ICDNOZ =$21 ;DEVICE NUMBER (DRIVE NUMBER) ICCOMZ =$22 ;COMMAND CODE ICSTAZ =$23 } ;STATUS OF LAST IOCB ACTION ICBALZ =$24 ;BUFFER ADDRESS (LOW) ICBAHZ =$25 ; " " (HIGH) ICPTLZ =$26 ;PUT BYTE ROUTI}NE ADDRESS - 1 ICPTHZ =$27 ICBLLZ =$28 ;BUFFER LENGTH (LOW) ICBLHZ =$29 ; " " (HIGH) ICAX1Z =$2A ;AUX INFO ICAX2Z} =$2B ICSPRZ =$2C ;SPARE BYTES (CIO LOCAL USE) ICIDNO =ICSPRZ+2 ;IOCB LUMBER * 16 CIOCHR =ICSPRZ+3 ;CHARACTER BYTE FOR CU}RRENT OPERATION STATUS =$30 ;INTERNAL STATUS STORAGE CHKSUM =$31 ;CHECKSUM (SINGLE BYTE SUM WITH CARRY) BUNRLO =$32 ;P}OINTER TO DATA BUFFER (LO BYTE) BUFRHI =$33 ;POINTER TO DATA BUFFER (HI BYTE) BFENLO =$34 ;NEXT BYTE PAST END OF BUFFER (}LO BYTE) BNENHI =$35 ;NEXT BYTE PAST END OF BUFFER (HI BYTE) CRETRY =$36 ;NUMBER OF COMMAND FRAM RETRIES DRETRY =$37 ;N}UMBER OF DEVICE RETRIES BUFRFL =$38 ;DATA BUFFER FULL FLAG RECVDN =$39 ;RECEIVE DONE FLAG XMTDON =$3A ;XMIT DONE FLAG C}HKSNT =$3B ;CHECKSUM SENT FLAG NOCKSM =$3C ;NO CHECKSUM FOLLOWS DATA FLAG BPTR =$3D ;BUFFER POINTER (CASSETTE) FTYPE =}$3E ;FILE TYPE (SHORT IRG/LONG IRG) FEOF =$3F ;END OF FILE FLAG (CASSETTE) FREQ =$40 ;FREQ COUNTER FOR CONSOLE SPEAKER }SOUNDR =$41 ;NOISY I/O FLAG. (ZERO IS QUIET) CRITIC =$42 ;CRITICAL CODE IF NON-ZERO) FMSZPG =$43 ;DISK FILE MANAGER SY}STEM STORAGE (7 BYTES) CKEY =$4A ;SET WHEN GAME START PRESSED CASSBT =$4B ;CASSETTE BOOT FLAG DSTAT =$4C ;DISPLAY STAT}US ATRACT =$4D ;ATTRACT MODE FLAG DRKMSK =$4E ;DARK ATTRACT MASK COLRSH =$4F ;ATTRACT COLOR SHIFTER (XOR'D WITH PLAYFIE}LD) TMPCHR =$50 ;TEMP CHAR STORAGE (DISPLAY HANDLER) HOLD1 =$51 ;TEMP STG (DISPLAY HANDLER) LMARGN =$52 ;LEFT MARGIN R}MARGN =$53 ;RIGHT MARGIN ROWCRS =$54 ;CURSOR COUNTERS COLCRS =$55 DINDEX =$57 ;DISPLAY INDEX (VARIOUS QUANTS) SAVMSC =$}58 OLDROW =$5A ;PREVIOUS ROW/COL OLDCOL =$5B OLDCHR =$5D ;DATA UNDER CURSOR OLDADR =$5E NEWROW =$60 ;POINT DRAWS TO HER}E NEWCOL =$61 LOGCOL =$63 ;POINTS AT COLUMN IN LOGICAL LINE ADRESS =$64 ;INDIRECT POINTER MLTTMP =$66 ;MULTIPLY TEMP OP}NTMP =MLTTMP ;FIRST BYTE IS USED IN OPEN AS TEMP SAVADR =$68 RAMTOP =$6A ;RAM SIZE DEFINED BY POWER ON LOGIC BUFCNT =$6B } ;BUFFER COUNT BUFSTR =$6C ;EDITOR GETCH POINTER BITMSK =$6E ;BIT MASK SHFAMT =$6F ;OUTCHR SHIFT ROWAC =$70 ;USED B}Y "DRAW" COLAC =$72 ENDPT =$74 DELTAR =$76 DELTAC =$77 ROWINC =$79 COLINC =$7A SWPFLG =$7B ;NON-0 IF TXT AND RAM SWAPPED HO}LDCH =$7C ;CH BEFORE CNTL & SHFT PROCESSING IN KGETCH INSDAT =$7D ;INSERT CHAR SAVE COUNTR =$7E ;DRAW COUNTER ;;; $80 }TO $FF ARE RESERVED FOR USER APPLICATIONS ; PAGE 2 LOCATIONS INTABS =$200 ;INTERRUPT TABLE VDSLST =$200 ;DISPLAY LIST N}MI VECTOR VPRCED =$202 ;PROCEED LINE IRQ VECTOR VINTER =$204 ;INTERRUPT LINE IRQ VECTOR VBREAK =$206 ;"BRK" VECTOR VKEY}BD =$208 ;POKEY KEYBOARD IRQ VECTOR VSERIN =$20A ;POKEY SERIAL INPUT READY VSEROR =$20C ;POKEY SERIAL OUTPUT READY VSER}OC =$20E ;POKEY SERIAL OUTPUT DONE VTIMR1 =$210 ;POKEY TIMER 1 IRQ VTIMR2 =$212 ;POKEY TIMER 2 IRQ VTIMR4 =$214 ;POKE}Y TIMER 4 IRQ (DO NOT USE) VIMIRQ =$216 ;IMMEDIATE IRQ VECTOR CDTMV1 =$218 ;COUNT DOWN TIMER 1 CDTMV1 =$21A ;COUNT DOWN} TIMER 2 CDTMV1 =$21C ;COUNT DOWN TIMER 3 CDTMV1 =$21E ;COUNT DOWN TIMER 4 CDTMV1 =$220 ;COUNT DOWN TIMER 5 VVBLKI =$22}2 ;IMMEDIATE VERTICAL BLANK NMI VECTOR VVBLKD =$224 ;DEFERRED VERTICAL BLANK NMI VECTOR CDTMA1 =$226 ;COUNT DOWN TIMER }1 JSR ADDRESS CDTMA2 =$228 ;COUNT DOWN TIMER 2 JSR ADDRESS CDTMF3 =$22A ;COUNT DOWN TIMER 3 FLAG SRTIMR =$22B ;SOFTWARE} REPEAT TIMER CDTMF4 =$22C ;COUNT DOWN TIMER 4 FLAG INTEMP =$22D ;IAN'S TEMP (???) CDTMF5 =$22E ;COUNT DOWN TIMER 5 FLA}G SDMCTL =$22F ;SAVE DMACTL REGISTER SDLSTL =$230 ;SAVE DISPLAY LIST (LOW) SDLSTH =$231 ;SAVE DISPLAY LIST (HIGH) SSKCT}L =$232 ;SKCTL REGISTER RAM LPENH =$234 ;LIGHT PEN HORIZ VALUE LPENV =$235 ;LIGHT PEN VERT VALUE ; ($236 - $239 SP}ARE) CDEVIC =$23A ;COMMAND FRAME BUFFER - DEVICE CCOMND =$23B ;COMMAND CAUX1 =$23C ;COMMAND AUX BYTE 1 CAUX2 =$23D ;C}OMMAND AUX BYTE 2 TEMP =$23E ;YES ERRFLG =$23F ;ERROR FLAG - ANY DEVICE ERROR EXCEPT TIMEOUT DFLAGS =$240 ;DISK FLAGS }FROM SECTOR ONE DBSECT =$241 ;NUMBER OF DISK BOOT SECTORS BOOTAD =$242 ;ADDRESS FOR DISK BOOT LOADER COLDST =$244 ;COLD}START FLAG (1 = DOING COLDSTART) ;($245 SPARE) DSKTIM =$246 ;DISK TIME OUT REG LINBUF =$247 ;CHAR LINE BUFFER (40 BYT}ES) GPRIOR =$26F ;GLOBAL PRIORITY CELL PADDL0 =$270 ;POT 0 SHADOW PADDL1 =$271 ;POT 1 SHADOW PADDL2 =$272 ;POT 2 SHA}DOW PADDL3 =$273 ;POT 3 SHADOW PADDL4 =$274 ;POT 4 SHADOW PADDL5 =$275 ;POT 5 SHADOW PADDL6 =$276 ;POT 6 SHADOW PADDL}7 =$277 ;POT 7 SHADOW STICK0 =$278 ;JOYSTICK 0 SHADOW STICK1 =$279 ;JOYSTICK 1 SHADOW STICK2 =$27A ;JOYSTICK 2 SHADOW} STICK3 =$27B ;JOYSTICK 3 SHADOW PTRIG0 =$27C ;PADDLE 0 TRIGGER PTRIG1 =$27D ;PADDLE 1 TRIGGER PTRIG2 =$27E ;PADDLE 2} TRIGGER PTRIG3 =$27F ;PADDLE 3 TRIGGER PTRIG4 =$280 ;PADDLE 4 TRIGGER PTRIG5 =$281 ;PADDLE 5 TRIGGER PTRIG6 =$282 ;P}ADDLE 6 TRIGGER PTRIG7 =$283 ;PADDLE 7 TRIGGER STRIG0 =$284 ;JOYSTICK 0 TRIGGER STRIG1 =$285 ;JOYSTICK 1 TRIGGER STRIG2} =$286 ;JOYSTICK 2 TRIGGER STRIG3 =$287 ;JOYSTICK 3 TRIGGER CSTAT =$288 ;(UNUSED) WMODE =$289 ;R/W FLAG FOR CASSETTE} BLIM =$28A ;BUFFER LIMIT (CASSETTE) ;($28B - $28F SPARE) TXTROW =$290 ;TEXT ROWCRS TXTCOL =$291 ;TEXT ROWCOL TINDE}X =$293 ;TEXT INDEX TXTMSC =$294 ;FOOLS CONVRT INTO NEW MSC TXTOLD =$296 ;OLDROW & OLDCOL FOR TEXT (AND THEN SOME) TMPX}1 =$29C HOLD3 =$29D SUBTMP =$29E HOLD2 =$29F DMASK =$2A0 TMPLBT =$2A1 ESCFLG =$2A2 ;ESCAPE FLAG TABMAP =$2A3 ;TAB BUFFER }LOGMAP =$2B2 ;LOGICAL LINE START BIT MAP INVFLG =$2B6 ;INVERSE VIDEO FLAG (ATARI KEY) FILFLG =$2B7 ;RIGHT FILL FLAG FOR} DRAW TMPROW =$2B8 TMPCOL =$2B9 SCRFLG =$2BB ;SET IF SCROLL OCCURS HOLD4 =$2BC ;MORE DRAW TEMPS HOLD5 =$2BD SHFLOK =$2BE } ;SHIFT LOCK KEY BOTSCR =$2BF ;BOTTOM OF SCREEN (24 NORM, 4 SPLIT) PCOLR0 =$2C0 ;P0 COLOR PCOLR1 =$2C1 ;P1 COLOR PCOL}R2 =$2C2 ;P2 COLOR PCOLR3 =$2C3 ;P3 COLOR COLOR0 =$2C4 ;COLOR 0 COLOR1 =$2C5 COLOR2 =$2C6 COLOR3 =$2C7 COLOR4 =$2C8 ;}BACKGROUND ;($2C9 - $2DF SPARE) GLBABS =$2E0 ;GLOBAL VARIABLES ;($2E0 - $2E3 SPARE) RAMSIZ =$2E4 ;RAM SIZE (HI BY}TE ONLY) MEMTOP =$2E5 ;TOP OF AVAILABLE MEMORY MEMLO =$2E7 ;BOTTOM OF AVAILABLE MEMORY ;($2E9 SPARE) DVSTAT =$2EA ;}STATUS BUFFER CBAUDL =$2EE ;CASSETTE BAUD RATE (LO BYTE) CBAUDH =$2EF ; " " " (HI BYTE) CRSINH =$2F0 ;CURSO}R INHIBIT (00 = CURSOR ON) KEYDEL =$2F1 ;KEY DELAY CH1 =$2F2 CHACT =$2F3 ;CHACTL REGISTER (SHADOW) CHBAS =$2F4 ;CHBAS R}EGISTER (SHADOW) ;($2F5 - $2F9 SPARE) CHAR =$2FA ATACHR =$2FB ;ATASCII CHARACTER CH =$2FC ;GLOBAL VARIABLE FOR KEYBOA }RD FILDAT =$2FD ;RIGHT FILL DATA (DRAW) DSPFLG =$2FE ;DISPLAY FLAG: DISP CONTROLS IF NON-ZERO SSFLAG =$2FF ;START/STOP  }FLAG (CNTL-1) FOR PAGING ; PAGE 3 LOCATIONS DCB =$300 ;DEVICE CONTROL BLOCK DDEVIC =$300 ;BUS I.D. NUMBER DUNIT =$301  } ;UNIT NUMBER DCOMND =$302 ;BUS COMMAND DSTATS =$303 ;COMMAND TYPE/STATUS RETURN DBUFLO =$304 ;DATA BUFFER POINTER DBUF }HI =$305 ; ... DTIMLO =$306 ;DEVICE TIME OUT IN 1 SEC. UNITS DUNUSE =$307 ;UNUSED DBYTLO =$308 ;BYTE COUNT DBYTHI =$3 }09 ; ... DAUX1 =$30A ;COMMAND AUXILLARY BYTES DAUX2 =$30B ; ... TIMER1 =$30C ;INITIAL TIMER VALUE ADDCOR =$30E ;AD}DITION CORRECTION CASFLG =$30F ;CASSETTE MODE WHEN SET TIMER2 =$310 ;FINAL TIME VALUE (USED TO COMPUTE BAUD RATE) TEMP1 =}$312 ;TEMP LOCATIONS TEMP2 =$314 ; ... TEMP3 =$315 ; ... SAVIO =$316 ;SAVE SERIAL IN DATA PORT TIMFLG =$317 ;TIME O}UT FLAG FOR BAUD RATE CORRECTION STACKP =$318 ;SIO STACK POINTER SAVE LOC TSTAT =$319 ;TEMP STATUS LOC HATABS =$31A ;H}ANDLER ADDRESS TABLE MAXDEV =$21 ;MAXIMUM HANDLER ADDRESS INDEX ; IOCB OFFSETS IOCB =$340 ;I/O CONTROL BLOCKS ICHID =}$340 ;HANDLER INDEX ($FF = FREE) ICDNO =$341 ;DEVICE NUMBER (DRIVE NUMBER) ICCOM =$342 ;COMMAND CODE ICSTA =$343 ;STA}TUS ICBAL =$344 ;BUFFER ADDRESS ICBAH =$345 ; ... ICPTL =$346 ;PUT BYTE ROUTINE ADDRESS - 1 ICPTH =$347 ; ... ICBLL =}$348 ;BUFFER LENGTH ICBLH =$349 ; ... ICAX1 =$34A ;AUXILLARY INFO ICAX2 =$34B ; ... ICSPR =$34C ;4 SPARE BYTES PRN}BUF =$3C0 ;PRINTER BUFFER ;($3EA - $3FC SPARE) ; PAGE 4 LOCATIONS CASBUF =$3FD ;CASSETTE BUFFER ; USER AREA STARTS} HERE AND GOES TO THE END OF PAGE 5 USAREA =$480 ;ATASCII CHARACTER DEFS .ATCLR =$7D ;CLEAR SCREEN CHARACTER .ATRUB =$7E} ;BACK SPACE (RUBOUT) .ATTAB =$7F ;TAB .ATEOL =$9B ;END-OF-LINE .ATBEL =$FD ;CONSOLE BELL .ATURW =$1C ;UP-ARROW .AT}DRW =$1D ;DOWN-ARROW .ATLRW =$1E ;LEFT-ARROW .ATRRW =$1F ;RIGHT-ARROW ; USEFUL VALUES LEDGE =2 ;LMARGN'S INITIAL VA}LUE REDGE =39 ;RMARGN'S INITIAL VALUE ZPC =0 ;PC CODE FOR ZERO PAGE PC P6PC =1 ;PC CODE FOR PAGE 6 PPC =2 ;PC CODE FOR }PROGRAM MEMORY ;INIT PC VALUES CURPC =0 PC0 =0 ;PAGE ZERO PC1 =$600 ;PAGE 6 PC PC2 =$3800 ;PROGRAM PC .MACRO PCBRK .P}RINT PC0 ;PAGE ZERO BREAK .PRINT PC1 ;PAGE 6 BREAK .PRINT PC2 ;PROGRAM BREAK .ENDM .ENDM ;; ATARI ; ***** KIM SYSTEM D}EFS ***** .MACRO KIMDEF ;LOCATIONS IN 6530-002 I/O KSAD =$1740 ;PORT A DATA KPADD =$1741 ;PORT A DATA DIRECTION KSBD =$1}742 ;PORT B DATA KSBDD =$1743 ;PORT B DATA DIRECTION KC1T =$1744 ;CLOCK /1 KC8T =$1745 ;CLOCK /8 KC64T =$1746 ;CLOCK /64} KCKT =$1747 ;CLOCK /1024 ;LOCATIONS IN 6530-003 I/O PAD =$1700 ;PORT A DATA PADD =$1701 ;PORT A DATA DIRECTION PBD =$17}02 ;PORT B DATA PBDD =$1703 ;PORT B DATA DIRECTION CLK1T =$1704 ;CLOCK /1 CLK8T =$1705 ;CLOCK /8 CLK64T =$1706 ;CLOCK /6 }4 CLKKT =$1707 ;CLOCK /1024 IC1T =$170C ;CLOCK /1 INTS ENABLED IC8T =$170D ;CLOCK /8 " IC64T =$170E ;CLOCK /64 " ICKT =$1!}70F ;CLOCK /1024 " KRAM =$1780 ;SCRATCH PAD RAM KRAMX =$17FF ;KRAM END ;PAGE ZERO VARIABLES USED BY KIM MONITOR PCL =$E"}F ;PROGRAM COUNTER PCH =$F0 PS =$F1 ;PROCESSOR STATUS REG SP =$F2 ;STACK POINTER AC =$F3 ;ACCUMULATOR YREG =$F4 ;Y INDEX#} XREG =$F5 ;X INDEX CHKSUM =$F6 ;CHECKSUM TEMP (2 BYTES) INBUF =$F8 ;INPUT BUFFER (2 BYTES) POINT =$FA ;OPEN CELL ADDRS ($}2 BYTES) TEMP =$FC ;TEMPORARY TMPX =$FD ;TEMPORARY X SAVE CHAR =$FE ;INPUT CHARACTER MODE =$FF ;ADDRS/DATA FLAG FOR DPY %};PAGE 23 VARIABLES USED BY KIM MONITOR CHKL =$17E7 ;ANOTHER CHECKSUM CHKH =$17E8 SAVX =$17E9 ;3 BYTE SCRATCH AREA VEB =$17&}EC ;6 BYTE PROGRAM FOR CASETTE CODE CNTL =$17F2 ;TTY DELAY COUNT CNTH =$17F3 TIMH =$17F4 ;TEMP FOR TTY TIMING SAL =$17F5 '};START ADDRS FOR CASETTE SAH =$17F6 EAL =$17F7 ;END ADDRS FOR CASSETE EAH =$17F8 CID =$17F9 ;FILE ID FOR CASETTE ;INTERUPT(} VECTORS NMIV =$17FA ;NMI VECTOR (STOP := $1C00) RSTV =$17FC ;RESET VECTOR IRQV =$17FE ;IRQ VECTOR (BRK := $1C00) ;VARIO)}US HANDY ROUTINE LOCATIONS IN KIM MONITOR SAVE =$1C00 ;KIM ENTRY TO SAVE WORLD FIRST SAVER =$1C05 ;KIM ENTRY VIA JSR (A LO*}ST) RESET =$1C22 ;KIM RESET ENTRY KIM =$1C4F ;KIM START ADDRS GOEXEC =$1DC8 ;RESTORE MACHINE AND RETURN PRTPNT =$1E1E ;RO+}UTINE TO PRINT "POINT" (CALLS CHK) CRLF =$1E2F ;PRINT CRLF PRTBYT =$1E3B ;PRINT 1 HEX BYTE AS 2 ASCII CHARS ;A PRESERVED,} HEXTA =$1E4C ;PRINT 1 ASCII HEX DIGIT (4 BITS) GETCH =$1E5A ;GET CHARACTER (PRESERVES X) INITS =$1E88 ;INITIALIZATION OUT-}SP =$1E9E ;PRINT A SPACE OUTCH =$1EA0 ;PRINT CHARACTER IN A AK =$1EFE ;KEYBOARD ROUTINE SCANDS =$1F1F ;DISPLAY F9-FB INCP.}T =$1F63 ;INCREMENT "POINT" GETKEY =$1F6A ;GET KEY FROM KEYBOARD CHK =$1F91 ;CHECKSUM ROUTINE (COMPUTES "CHKSUM") GETBYT =/}$1F9D ;GET 2 ASCII CHARS INTO HEX BYTE ;X PRESERVED PACK =$1FAC ;PACK CHAR INTO INPUT BUFFER ;RETURNS A=0 IF HEX CHAR0} OPEN =$1FCC ;COPIES INBUF TO POINT DPYTAB =$1FE7 ;HEX TO 7 SEGMENT TABLE ;ROUTINES IN CASSETTE DRIVER CHKT =$194C ;COMP1}UTE CHKSUM FOR TAPE INTVEB =$1932 ;INIT VEB WITH SAL,SAH / CLEAR CHKSUM INCVEB =$19EA ;INCREMENT VEB+1,2 RDBYT =$19F3 ;REA2}D BYTE FROM TAPE PACKT =$1A00 ;PACK ASCII INTO SAVX RDCHT =$1A24 ;GET 1 CHAR FROM TAPE RDBIT =$1A41 ;GET 1 BIT FROM TAPE I3}N SIGN OF A DUMPT =$1800 ;DUMP MEM TO TAPE LOADT =$1873 ;LOAD MEM FROM TAPE ZPC =0 ;PC CODE FOR ZERO PAGE PC PPC =1 ;PC 4}CODE FOR PROGRAM PC KPC =2 ;PC CODE FOR KRAM PC XPC =3 ;PC CODE FOR LOW 1K ;INIT PC VALUES CURPC =0 PC0 =0 ;PAGE ZERO PC5}1 =$200 ;PROGRAM PC PC2 =KRAM ;KRAM PC PC3 =$200 ;PC FOR LOW 1K .MACR PCBRK .PRINT PC0 ;PAGE ZERO BREAK .PRINT PC1 ;P6}ROGRAM BREAK .PRINT PC2 ;KRAM BREAK .PRINT PC3 ;LOW 1K BREAK .ENDM .ENDM ;;KIMDEF ;GENERAL 6502 DEFS .MACRO M6502 ;7}ASCII CHARACTER DEFS .CHNUL =@00 ;NULL .CHSOH =@01 ;SOH .CHSTX =@02 .CHETX =@03 .CHEOT =@04 .CHENQ =@05 .CHACK =@06 .CHB8}EL =@07 .CHBS =@10 .CHTAB =@11 .CHLF =@12 .CHVT =@13 .CHFF =@14 .CHCR =@15 .CHSO =@16 .CHSI =@17 .CHDLE =@20 .CHDC1 =@21 .CHD9}C2 =@22 .CHDC3 =@23 .CHDC4 =@24 .CHNAK =@25 .CHSYN =@26 .CHETB =@27 .CHCAN =@30 .CHEM =@31 .CHSUB =@32 .CHESC =@33 .CHFS =@34:} .CHGS =@35 .CHRS =@36 .CHUS =@37 .CHSP =@40 .CHRUB =@177 ;HANDY MACROS .EQUIV SEI,PIOFF ;TURN OFF IRQ INTS .EQUIV CLI,P;}ION ;ALLOW IRQ INTS .EQUIV JSR,CALL ;SUBROUTINE CALL .EQUIV RTS,RET ;SUBROUTINE RETURN ;DOUBLE BYTE HANDLING MACROS .MA<}CR MOV2 FROM,TO,INDX ;;COPY 2 BYTE ITEM LDA FROM ;;GET FIRST BYTE .IIF B,,STA TO .IIF NB,,STA TO,INDX LD=}A FROM+1 ;;THEN LAST .IIF B,,STA TO+1 .IIF NB,,STA TO+1,INDX .ENDM .MACR INC2 LOC,?MEXIT ;;INCREMENT LOCA>}TION INC LOC ;;LOW BYTE FIRST BNE MEXIT ;;EXIT IF NO CARRY INC LOC+1 ;;ELSE INCR HIGH BYTE MEXIT: .ENDM .MACR DEC2 LOC?},?MEXIT ;;DECREMENT LOCATION SEC LDA LOC ;;GET LOW BYTE SBC #1 ;;DEC DOESNT AFFECT CARRY STA LOC BCS MEXIT ;;EXIT IF @}NO BORROW DEC LOC+1 ;;ELSE ADJUST HIGH BYTE MEXIT: .ENDM .MACR CMP2EQ A,B,TARGET,?NOMAT LDA A+1 CMP B+1 ;;CHECK FOR MATA}CH BNE NOMAT ;;QUICK FINISH LDA A CMP B BEQ TARGET ;;IF .EQ. JUMP TO TARGET NOMAT: ;;FALL THROUGH IF NO MATCH .ENDM B} .MACR CMP2NE A,B,TARGET ;;OPOSITE OF CMP2EQ LDA A+1 CMP B+1 BNE TARGET ;;NO MATCH LDA A+1 CMP B BNE TARGET ;;NOT SAMC}E ;;FALL THROUGH IF SAME .ENDM .MACR SET2 VALUE,LOC,INDX ;;SET 2 BYTE IMMEDIATE LDA #&$FF ;;LOW BYTE .IIF B,<D}INDX>,STA LOC .IIF NB,,STA LOC,INDX LDA #^ ;;HIGH BYTE .IIF B,,STA LOC+1 .IIF NB,,STA LOC+E}1,INDX .ENDM .MACR SETAX VALUE ;; LOAD A&X WITH 16-BIT VALUE LDA #&$FF ;; LOW BYTE LDX #^ .ENDM .MACR SETXF}A VALUE ;; LOAD X&A WITH 16-BIT VALUE LDX #&$FF ;; LOW BYTE LDA #^ .ENDM .MACR SETXY VALUE ;; LOAD X&Y WITG}H 16-BIT VALUE LDX #&$FF ;; LOW BYTE LDY #^ .ENDM .MACR MOV2X FROM,TO ;;COPY 2 BYTE ITEM LDX FROM ;;GET FH}IRST BYTE STX TO LDX FROM+1 ;;THEN LAST STX TO+1 .ENDM .MACR SET2X VALUE,LOC ;;SET 2 BYTE IMMEDIATE LDX # ;;I}LOW BYTE STX LOC LDX #^ ;;HIGH BYTE STX LOC+1 .ENDM .MACR CLR LST ;;CLEAR LOCATIONS LDA #0 .IRP LOC, J}STA LOC .ENDR .ENDM .MACR CLR2 LST ;;CLEAR FOR 2 BYTE THINGS LDA #0 .IRP LOC, STA LOC STA LOC+1 .ENDR .K}ENDM ;MACROS TO MANIPULATE PCS .MACR SETPC NAM,VAL SAVPC \CURPC .=VAL CURPC=NAM .ENDM .MACR USEPC NAM SWPPC \CURPC,\NAL}M CURPC=NAM .ENDM .MACR SAVPC NAM PC'NAM=. .ENDM .MACR SWPPC OLD,NEW PC'OLD=. .=PC'NEW .ENDM ;FANCY END MACRO .MACR EM}ND ARG SAVPC \CURPC .IF P2 PCBRK .ENDC .END ARG .ENDM ;UTILITY MACROS .MACR TYPE MSGAD LDX #MSGAD&$FF LDY #MSGN}AD^ CALL PUTLIN .ENDM .MOD. =$FFFF ;MODIFIED LOC (REMOVE FOR ROM) .ENDM ;; M6502 CR TYPE MSGAD LDX #MSGAD&$FF LDY #MSGV