********************************************************************************
* Apple II *
* Monitor II *
* *
* Copyright 1978 by Apple Computer, Inc. *
* All Rights Reserved *
* *
* Steve Wozniak *
********************************************************************************
* Modified Nov 1978 by John A *
* *
* Modified Sep 1981 by Rick Auricchio & Bryan Stearns for Apple2E 80cols *
* *
* Changes marked by 'RRA0981' *
********************************************************************************
* This is a disassembly of the original ("unenhanced") Apple //e monitor ROM. *
* The labels and comments come from the "Monitor Firmware Listing" in *
* _Reference Manual Addendum: Monitor ROM Listings For //e Only_. This is a *
* fairly direct translation -- operands are generally formatted as they appear *
* in the original listing. Comments have been converted to mixed-case, but *
* are otherwise largely unchanged. *
* *
* The GOTOCX routine at $fbb4 calls into the extended 80-column card firmware *
* at $C100 to update the text screen and handle escape codes. That firmware *
* is covered in a separate disassembly. *
********************************************************************************
* Project created by Andy McFadden, using 6502bench SourceGen v1.7.4. *
* Last updated 2021/06/10 *
********************************************************************************
IOADR .eq $c000 {const}
LOC0 .eq $00
LOC1 .eq $01
WNDLFT .eq $20
WNDWDTH .eq $21
WNDTOP .eq $22
WNDBTM .eq $23
CH .eq $24
CV .eq $25
GBASL .eq $26
GBASH .eq $27
BASL .eq $28
BASH .eq $29
H2 .eq $2c
LMNEM .eq $2c
RMNEM .eq $2d
V2 .eq $2d
CHKSUM .eq $2e
FORMAT .eq $2e
MASK .eq $2e
LASTIN .eq $2f
LENGTH .eq $2f
COLOR .eq $30
MODE .eq $31
INVFLG .eq $32
PROMPT .eq $33
YSAV .eq $34
YSAV1 .eq $35
CSWL .eq $36
KSWL .eq $38
PCL .eq $3a
PCH .eq $3b
A1L .eq $3c
A1H .eq $3d
A2L .eq $3e
A2H .eq $3f
A3L .eq $40
A3H .eq $41
A4L .eq $42
A4H .eq $43
A5L .eq $44
A5H .eq $45
ACC .eq $45 ;note overlap with A5H!
XREG .eq $46
YREG .eq $47
STATUS .eq $48
SPNT .eq $49
IN .eq $0200 {addr/256}
BRKV .eq $03f0 {addr/2} ;new vector for BRK
SOFTEV .eq $03f2 {addr/2} ;vector for warm start
PWREDUP .eq $03f4 {addr/1} ;this must = EOR #$A5 of SOFTEV+1
USRADR .eq $03f8 {addr/3} ;Applesoft & exit vector
NMI .eq $03fb {addr/3}
IRQLOC .eq $03fe {addr/2}
LINE1 .eq $0400 {addr/40}
MSLOT .eq $07f8 {addr/1}
KBD .eq $c000 ;R last key pressed + 128
SETSLOTCXROM .eq $c006 ;W use peripheral ROM ($C100-CFFF)
SETINTCXROM .eq $c007 ;W use internal ROM ($C100-CFFF)
KBDSTRB .eq $c010 ;RW keyboard strobe
RDCXROM .eq $c015 ;R bit 7: using internal slot ROM?
RD80COL .eq $c018 ;R bit 7: 80STORE is on?
RDPAGE2 .eq $c01c ;R bit 7: using page 2?
TAPEOUT .eq $c020 ;RW toggle caseette tape output
SPKR .eq $c030 ;RW toggle speaker
TXTCLR .eq $c050 ;RW display graphics
TXTSET .eq $c051 ;RW display text
MIXSET .eq $c053 ;RW display split screen
TXTPAGE1 .eq $c054 ;RW display page 1
TXTPAGE2 .eq $c055 ;RW display page 2 (or read/write aux mem)
LORES .eq $c056 ;RW display lo-res graphics
SETAN0 .eq $c058 ;RW annunciator 0 off
SETAN1 .eq $c05a ;RW annunciator 1 off
TAPEIN .eq $c060 ;R read cassette input
PADDL0 .eq $c064 ;R analog input 0
PTRIG .eq $c070 ;RW analog input reset
CLRROM .eq $cfff ;disable slot C8 ROM
BASIC .eq $e000
BASIC2 .eq $e003
.org $f800
f800: 4a PLOT lsr A ;Y-coord/2
f801: 08 php ;save LSB in carry
f802: 20 47 f8 jsr GBASCALC ;calc base adr in GBASL,H
f805: 28 plp ;restore LSB from carry
f806: a9 0f lda #$0f ;mask $0F if even
f808: 90 02 bcc RTMASK
f80a: 69 e0 adc #$e0 ;mask $F0 if odd
f80c: 85 2e RTMASK sta MASK
f80e: b1 26 PLOT1 lda (GBASL),y ;data
f810: 45 30 eor COLOR ; xor color
f812: 25 2e and MASK ; and mask
f814: 51 26 eor (GBASL),y ; xor data
f816: 91 26 sta (GBASL),y ; to data
f818: 60 rts
f819: 20 00 f8 HLINE jsr PLOT ;plot square
f81c: c4 2c HLINE1 cpy H2 ;done?
f81e: b0 11 bcs RTS1 ; yes, return
f820: c8 iny ; no, incr index (X-coord)
f821: 20 0e f8 jsr PLOT1 ;plot next square
f824: 90 f6 bcc HLINE1 ;always taken
f826: 69 01 VLINEZ adc #$01 ;next Y-coord
f828: 48 VLINE pha ; save on stack
f829: 20 00 f8 jsr PLOT ; plot square
f82c: 68 pla
f82d: c5 2d cmp V2 ;done?
f82f: 90 f5 bcc VLINEZ ; no, loop
f831: 60 RTS1 rts
f832: a0 2f CLRSCR ldy #$2f ;max Y, full scrn clr
f834: d0 02 bne CLRSC2 ;always taken
f836: a0 27 CLRTOP ldy #$27 ;max Y, top scrn clr
f838: 84 2d CLRSC2 sty V2 ;store as bottom coord for VLINE calls
f83a: a0 27 ldy #$27 ;rightmost X-coord (column)
f83c: a9 00 CLRSC3 lda #$00 ;top coord for VLINE calls
f83e: 85 30 sta COLOR ;clear color (black)
f840: 20 28 f8 jsr VLINE ;draw vline
f843: 88 dey ;next leftmost X-coord
f844: 10 f6 bpl CLRSC3 ;loop until done.
f846: 60 rts
f847: 48 GBASCALC pha ;for input 000DEFGH
f848: 4a lsr A
f849: 29 03 and #$03
f84b: 09 04 ora #$04 ;generate GBASH=000001FG
f84d: 85 27 sta GBASH
f84f: 68 pla ;and GBASL=HDEDE000
f850: 29 18 and #$18
f852: 90 02 bcc GBCALC
f854: 69 7f adc #$7f
f856: 85 26 GBCALC sta GBASL
f858: 0a asl A
f859: 0a asl A
f85a: 05 26 ora GBASL
f85c: 85 26 sta GBASL
f85e: 60 rts
f85f: a5 30 NXTCOL lda COLOR ;increment color by 3
f861: 18 clc
f862: 69 03 adc #$03
f864: 29 0f SETCOL and #$0f ;sets COLOR=17*A mod 16
f866: 85 30 sta COLOR
f868: 0a asl A ;both half bytes of COLOR equal
f869: 0a asl A
f86a: 0a asl A
f86b: 0a asl A
f86c: 05 30 ora COLOR
f86e: 85 30 sta COLOR
f870: 60 rts
f871: 4a SCRN lsr A ;read screen Y-coord/2
f872: 08 php ;save LSB (carry)
f873: 20 47 f8 jsr GBASCALC ;calc base address
f876: b1 26 lda (GBASL),y ;get byte
f878: 28 plp ;restore LSB from carry
f879: 90 04 SCRN2 bcc RTMSKZ ;if even, use lo H
f87b: 4a lsr A
f87c: 4a lsr A
f87d: 4a lsr A ;shift high half byte down
f87e: 4a lsr A
f87f: 29 0f RTMSKZ and #$0f ;mask 4-bits
f881: 60 rts
f882: a6 3a INSDS1 ldx PCL ;print PCL,H
f884: a4 3b ldy PCH
f886: 20 96 fd jsr PRYX2
f889: 20 48 f9 jsr PRBLNK ;followed by a blank
f88c: a1 3a lda (PCL,x) ;get opcode
f88e: a8 INSDS2 tay
f88f: 4a lsr A ;even/odd test
f890: 90 09 bcc IEVEN
f892: 6a ror A ;bit 1 test
f893: b0 10 bcs ERR ;XXXXXX11 invalid op
f895: c9 a2 cmp #$a2
f897: f0 0c beq ERR ;opcode $89 invalid
f899: 29 87 and #$87 ;mask bits
f89b: 4a IEVEN lsr A ;LSB into carry for L/R test
f89c: aa tax
f89d: bd 62 f9 lda FMT1,x ;get format index byte
f8a0: 20 79 f8 jsr SCRN2 ;R/L H-byte on carry
f8a3: d0 04 bne GETFMT
f8a5: a0 80 ERR ldy #$80 ;substitute $80 for invalid ops
f8a7: a9 00 lda #$00 ;set print format index to 0
f8a9: aa GETFMT tax
f8aa: bd a6 f9 lda FMT2,x ;index into print format table
f8ad: 85 2e sta FORMAT ;save for adr field formatting
f8af: 29 03 and #$03 ;mask for 2-bit length (P=1 byte, 1=2 byte, 2=3 byte)
f8b1: 85 2f sta LENGTH
f8b3: 98 tya ;opcode
f8b4: 29 8f and #$8f ;mask for 1XXX1010 test
f8b6: aa tax ; save it
f8b7: 98 tya ;opcode to A again
f8b8: a0 03 ldy #$03
f8ba: e0 8a cpx #$8a
f8bc: f0 0b beq MNNDX3
f8be: 4a MNNDX1 lsr A
f8bf: 90 08 bcc MNNDX3 ;form index into mnemonic table
f8c1: 4a lsr A
f8c2: 4a MNNDX2 lsr A ;1) 1XXX1010=>00101XXX
f8c3: 09 20 ora #$20 ;2) XXXYYY01=>00111XXX
f8c5: 88 dey ;3) XXXYYY10=>00110XXX
f8c6: d0 fa bne MNNDX2 ;4) XXXYY100=>00100XXX
f8c8: c8 iny ;5) XXXXX000=>000XXXXX
f8c9: 88 MNNDX3 dey
f8ca: d0 f2 bne MNNDX1
f8cc: 60 rts
f8cd: ff ff ff .bulk $ff,$ff,$ff
f8d0: 20 82 f8 INSTDSP jsr INSDS1 ;gen fmt, len bytes
f8d3: 48 pha ;save mnemonic table index
f8d4: b1 3a PRNTOP lda (PCL),y
f8d6: 20 da fd jsr PRBYTE
f8d9: a2 01 ldx #$01 ;print 2 blanks
f8db: 20 4a f9 PRNTBL jsr PRBL2
f8de: c4 2f cpy LENGTH ;print inst (1-3 bytes)
f8e0: c8 iny ;in a 12 chr field
f8e1: 90 f1 bcc PRNTOP
f8e3: a2 03 ldx #$03 ;char count for mnemonic print
f8e5: c0 04 cpy #$04
f8e7: 90 f2 bcc PRNTBL
f8e9: 68 pla ;recover mnemonic index
f8ea: a8 tay
f8eb: b9 c0 f9 lda MNEML,y
f8ee: 85 2c sta LMNEM ;fech 3-char mnemonic
f8f0: b9 00 fa lda MNEMR,y ; (packed in 2-bytes)
f8f3: 85 2d sta RMNEM
f8f5: a9 00 PRMN1 lda #$00
f8f7: a0 05 ldy #$05
f8f9: 06 2d PRMN2 asl RMNEM ;shift 5 bits of character into A
f8fb: 26 2c rol LMNEM
f8fd: 2a rol A ; (clears carry)
f8fe: 88 dey
f8ff: d0 f8 bne PRMN2
f901: 69 bf adc #$bf ;add "?" offset
f903: 20 ed fd jsr COUT ;output a char of MNEM
f906: ca dex
f907: d0 ec bne PRMN1
f909: 20 48 f9 jsr PRBLNK ;output 3 blanks
f90c: a4 2f ldy LENGTH
f90e: a2 06 ldx #$06 ;cnt for 6 format bits
f910: e0 03 PRADR1 cpx #$03
f912: f0 1c beq PRADR5 ;if X=3 then addr.
f914: 06 2e PRADR2 asl FORMAT
f916: 90 0e bcc PRADR3
f918: bd b3 f9 lda CHAR1-1,x
f91b: 20 ed fd jsr COUT
f91e: bd b9 f9 lda CHAR2-1,x
f921: f0 03 beq PRADR3
f923: 20 ed fd jsr COUT
f926: ca PRADR3 dex
f927: d0 e7 bne PRADR1
f929: 60 rts
f92a: 88 PRADR4 dey
f92b: 30 e7 bmi PRADR2
f92d: 20 da fd jsr PRBYTE
f930: a5 2e PRADR5 lda FORMAT
f932: c9 e8 cmp #$e8 ;handle rel adr mode
f934: b1 3a lda (PCL),y ;special (print target,
f936: 90 f2 bcc PRADR4 ; not offset)
f938: 20 56 f9 RELADR jsr PCADJ3
f93b: aa tax ;PCL,PCH+OFFSET+1 to A,Y
f93c: e8 inx
f93d: d0 01 bne PRNTYX ;+1 to Y,X
f93f: c8 iny
f940: 98 PRNTYX tya
f941: 20 da fd PRNTAX jsr PRBYTE ;output target adr
f944: 8a PRNTX txa ; of branch and return
f945: 4c da fd jmp PRBYTE
f948: a2 03 PRBLNK ldx #$03 ;blank count
f94a: a9 a0 PRBL2 lda #$a0 ;load a space
f94c: 20 ed fd PRBL3 jsr COUT ;output a blank
f94f: ca dex
f950: d0 f8 bne PRBL2 ;loop until count=0
f952: 60 rts
f953: 38 PCADJ sec ;0=1 byte, 1=2 byte,
f954: a5 2f PCADJ2 lda LASTIN ; 2=3 byte
f956: a4 3b PCADJ3 ldy PCH
f958: aa tax ;test displacement sign
f959: 10 01 bpl PCADJ4 ; (for rel branch)
f95b: 88 dey ;extend neg by decr PCH
f95c: 65 3a PCADJ4 adc PCL
f95e: 90 01 bcc RTS2 ;PCL+LENGTH(or DISPL)+1 to A
f960: c8 iny ; carry into Y (PCH)
f961: 60 RTS2 rts
; FMT1 bytes: XXXXXXY0 instrs
; if Y=0 then left half byte
; if Y=1 then right half byte
; (x=index)
f962: 04 20 54 30+ FMT1 .bulk $04,$20,$54,$30,$0d,$80,$04,$90,$03,$22,$54,$33,$0d,$80,$04,$90
+ $04,$20,$54,$33,$0d,$80,$04,$90,$04,$20,$54,$3b,$0d,$80,$04,$90
+ $00,$22,$44,$33,$0d,$c8,$44,$00,$11,$22,$44,$33,$0d,$c8,$44,$a9
+ $01,$22,$44,$33,$0d,$80,$04,$90,$01,$22,$44,$33,$0d,$80,$04,$90
+ $26,$31,$87,$9a
; ZZXXXY01 instr's
f9a6: 00 FMT2 .dd1 $00 ;err
f9a7: 21 .dd1 $21 ;imm
f9a8: 81 .dd1 $81 ;z-page
f9a9: 82 .dd1 $82 ;abs
f9aa: 00 .dd1 $00 ;implied
f9ab: 00 .dd1 $00 ;accumulator
f9ac: 59 .dd1 $59 ;(zpag,x)
f9ad: 4d .dd1 $4d ;(zpag),y
f9ae: 91 .dd1 $91 ;zpag,x
f9af: 92 .dd1 $92 ;abs,x
f9b0: 86 .dd1 $86 ;abs,y
f9b1: 4a .dd1 $4a ;(abs)
f9b2: 85 .dd1 $85 ;zpag,y
f9b3: 9d .dd1 $9d ;relative
f9b4: ac CHAR1 .dd1 “,”
f9b5: a9 .dd1 “)”
f9b6: ac .dd1 “,”
f9b7: a3 .dd1 “#”
f9b8: a8 .dd1 “(”
f9b9: a4 .dd1 “$”
f9ba: d9 CHAR2 .dd1 “Y”
f9bb: 00 .dd1 $00
f9bc: d8 .dd1 “X”
f9bd: a4 .dd1 “$”
f9be: a4 .dd1 “$”
f9bf: 00 .dd1 $00
; (From original ROM listing)
; MNEML is of form:
; (A) XXXXX000
; (B) XXXYY100
; (C) 1XXX1010
; (D) XXXYYY10
; (E) XXXYYY01
; (X=index)
f9c0: 1c MNEML .dd1 $1c
f9c1: 8a .dd1 $8a
f9c2: 1c .dd1 $1c
f9c3: 23 .dd1 $23
f9c4: 5d .dd1 $5d
f9c5: 8b .dd1 $8b
f9c6: 1b .dd1 $1b
f9c7: a1 .dd1 $a1
f9c8: 9d .dd1 $9d
f9c9: 8a .dd1 $8a
f9ca: 1d .dd1 $1d
f9cb: 23 .dd1 $23
f9cc: 9d .dd1 $9d
f9cd: 8b .dd1 $8b
f9ce: 1d .dd1 $1d
f9cf: a1 .dd1 $a1
f9d0: 00 .dd1 $00
f9d1: 29 .dd1 $29
f9d2: 19 .dd1 $19
f9d3: ae .dd1 $ae
f9d4: 69 .dd1 $69
f9d5: a8 .dd1 $a8
f9d6: 19 .dd1 $19
f9d7: 23 .dd1 $23
f9d8: 24 .dd1 $24
f9d9: 53 .dd1 $53
f9da: 1b .dd1 $1b
f9db: 23 .dd1 $23
f9dc: 24 .dd1 $24
f9dd: 53 .dd1 $53
f9de: 19 .dd1 $19 ;(A) format above
f9df: a1 .dd1 $a1
f9e0: 00 .dd1 $00
f9e1: 1a .dd1 $1a
f9e2: 5b .dd1 $5b
f9e3: 5b .dd1 $5b
f9e4: a5 .dd1 $a5
f9e5: 69 .dd1 $69
f9e6: 24 .dd1 $24 ;(B) format
f9e7: 24 .dd1 $24
f9e8: ae .dd1 $ae
f9e9: ae .dd1 $ae
f9ea: a8 .dd1 $a8
f9eb: ad .dd1 $ad
f9ec: 29 .dd1 $29
f9ed: 00 .dd1 $00
f9ee: 7c .dd1 $7c ;(C) format
f9ef: 00 .dd1 $00
f9f0: 15 .dd1 $15
f9f1: 9c .dd1 $9c
f9f2: 6d .dd1 $6d
f9f3: 9c .dd1 $9c
f9f4: a5 .dd1 $a5
f9f5: 69 .dd1 $69
f9f6: 29 .dd1 $29 ;(D) format
f9f7: 53 .dd1 $53
f9f8: 84 .dd1 $84
f9f9: 13 .dd1 $13
f9fa: 34 .dd1 $34
f9fb: 11 .dd1 $11
f9fc: a5 .dd1 $a5
f9fd: 69 .dd1 $69
f9fe: 23 .dd1 $23 ;(E) format
f9ff: a0 .dd1 $a0
fa00: d8 MNEMR .dd1 $d8
fa01: 62 .dd1 $62
fa02: 5a .dd1 $5a
fa03: 48 .dd1 $48
fa04: 26 .dd1 $26
fa05: 62 .dd1 $62
fa06: 94 .dd1 $94
fa07: 88 .dd1 $88
fa08: 54 .dd1 $54
fa09: 44 .dd1 $44
fa0a: c8 .dd1 $c8
fa0b: 54 .dd1 $54
fa0c: 68 .dd1 $68
fa0d: 44 .dd1 $44
fa0e: e8 .dd1 $e8
fa0f: 94 .dd1 $94
fa10: 00 .dd1 $00
fa11: b4 .dd1 $b4
fa12: 08 .dd1 $08
fa13: 84 .dd1 $84
fa14: 74 .dd1 $74
fa15: b4 .dd1 $b4
fa16: 28 .dd1 $28
fa17: 6e .dd1 $6e
fa18: 74 .dd1 $74
fa19: f4 .dd1 $f4
fa1a: cc .dd1 $cc
fa1b: 4a .dd1 $4a
fa1c: 72 .dd1 $72
fa1d: f2 .dd1 $f2
fa1e: a4 .dd1 $a4 ;(A) format
fa1f: 8a .dd1 $8a
fa20: 00 .dd1 $00
fa21: aa .dd1 $aa
fa22: a2 .dd1 $a2
fa23: a2 .dd1 $a2
fa24: 74 .dd1 $74
fa25: 74 .dd1 $74
fa26: 74 .dd1 $74 ;(B) format
fa27: 72 .dd1 $72
fa28: 44 .dd1 $44
fa29: 68 .dd1 $68
fa2a: b2 .dd1 $b2
fa2b: 32 .dd1 $32
fa2c: b2 .dd1 $b2
fa2d: 00 .dd1 $00
fa2e: 22 .dd1 $22 ;(C) format
fa2f: 00 .dd1 $00
fa30: 1a .dd1 $1a
fa31: 1a .dd1 $1a
fa32: 26 .dd1 $26
fa33: 26 .dd1 $26
fa34: 72 .dd1 $72
fa35: 72 .dd1 $72
fa36: 88 .dd1 $88 ;(D) format
fa37: c8 .dd1 $c8
fa38: c4 .dd1 $c4
fa39: ca .dd1 $ca
fa3a: 26 .dd1 $26
fa3b: 48 .dd1 $48
fa3c: 44 .dd1 $44
fa3d: 44 .dd1 $44
fa3e: a2 .dd1 $a2 ;(E) format
fa3f: c8 .dd1 $c8
fa40: 85 45 IRQ sta ACC ;*** IRQ handler
fa42: 68 pla
fa43: 48 pha
fa44: 0a asl A
fa45: 0a asl A
fa46: 0a asl A
fa47: 30 03 bmi BREAK ;test for 'BRK'
fa49: 6c fe 03 jmp (IRQLOC) ;user routine vector in RAM
fa4c: 28 BREAK plp
fa4d: 20 4c ff jsr SAV1 ;save reg's on break
fa50: 68 pla ; including PC
fa51: 85 3a sta PCL
fa53: 68 pla
fa54: 85 3b sta PCH
fa56: 6c f0 03 jmp (BRKV) ;BRKV written over by disk boot
fa59: 20 82 f8 OLDBRK jsr INSDS1 ;print user PC
fa5c: 20 da fa jsr RGDSP1 ; and regs
fa5f: 4c 65 ff jmp MON ;go to monitor (no pass go, no $200!)
fa62: d8 RESET cld ;do this first this time
fa63: 20 84 fe jsr SETNORM
fa66: 20 2f fb jsr INIT
fa69: 20 93 fe jsr SETVID
fa6c: 20 89 fe jsr SETKBD
fa6f: ad 58 c0 INITAN lda SETAN0 ;AN0 = TTL HI
fa72: ad 5a c0 lda SETAN1 ;AN1 = TTL HI
fa75: a0 05 ldy #5 ;code=INIT /RRA0981
fa77: 20 b4 fb jsr GOTOCX ;do Apple2e init /RRA0981
fa7a: ea nop ;/RRA0981
fa7b: ad ff cf lda CLRROM ;turn off extnsn ROM
fa7e: 2c 10 c0 bit KBDSTRB ;clear keyboard
fa81: d8 NEWMON cld
fa82: 20 3a ff jsr BELL ;causes delay if key bounces
fa85: ad f3 03 lda SOFTEV+1 ;is reset hi
fa88: 49 a5 eor #$a5 ;a funny complement of the
fa8a: cd f4 03 cmp PWREDUP ; pwr up byte ???
fa8d: d0 17 bne PWRUP ;no so pwrup
fa8f: ad f2 03 lda SOFTEV ;yes see if cold start
fa92: d0 0f bne NOFIX ; has been done yet?
fa94: a9 e0 lda #$e0 ;does soft entry vector point at BASIC
fa96: cd f3 03 cmp SOFTEV+1
fa99: d0 08 bne NOFIX ;yes so reenter system
fa9b: a0 03 FIXSEV ldy #3 ;no so point at warm start
fa9d: 8c f2 03 sty SOFTEV ; for next reset
faa0: 4c 00 e0 jmp BASIC ;and do the cold start
faa3: 6c f2 03 NOFIX jmp (SOFTEV) ;soft entry vector
;
faa6: 20 60 fb PWRUP jsr APPLEII
faa9: a2 05 ldx #5 ;set page 3 vectors
faab: bd fc fa SETPLP lda PWRCON-1,x ;with cntrl B adrs
faae: 9d ef 03 sta BRKV-1,x ; of current BASIC
fab1: ca dex
fab2: d0 f7 bne SETPLP
fab4: a9 c8 lda #$c8 ;load hi slot +1
fab6: 86 00 stx LOC0 ;SETPG3 must return X=0
fab8: 85 01 sta LOC1 ;set ptr H
faba: a0 07 SLOOP ldy #7 ;Y is byte ptr
fabc: c6 01 dec LOC1
fabe: a5 01 lda LOC1
fac0: c9 c0 cmp #$c0 ;at last slot yet?
fac2: f0 d7 beq FIXSEV ;yes and it can't be a disk
fac4: 8d f8 07 sta MSLOT
fac7: b1 00 NXTBYT lda (LOC0),y ;fetch a slot byte
fac9: d9 01 fb cmp DSKID-1,y ;is it a disk?
facc: d0 ec bne SLOOP ;no, so next slot down
face: 88 dey
facf: 88 dey ;yes, so check next byte
fad0: 10 f5 bpl NXTBYT ;until 4 bytes checked
fad2: 6c 00 00 jmp (LOC0) ;go boot...
fad5: ea nop
fad6: ea nop
; REGDSP must ORG $FAD7
fad7: 20 8e fd REGDSP jsr CROUT ;display user reg contents
fada: a9 45 RGDSP1 lda #$45 ; with labels
fadc: 85 40 sta A3L
fade: a9 00 lda #$00
fae0: 85 41 sta A3H
fae2: a2 fb ldx #$fb
fae4: a9 a0 RDSP1 lda #$a0
fae6: 20 ed fd jsr COUT
fae9: bd 1e fa lda RTBL-251,x
faec: 20 ed fd jsr COUT
faef: a9 bd lda #$bd
faf1: 20 ed fd jsr COUT
faf4: b5 4a lda ACC+5,x
faf6: 20 da fd jsr PRBYTE
faf9: e8 inx
fafa: 30 e8 bmi RDSP1
fafc: 60 rts
fafd: 59 fa PWRCON .dd2 OLDBRK
faff: 00 e0 45 .bulk $00,$e0,$45
fb02: 20 ff 00 ff+ DSKID .bulk $20,$ff,$00,$ff,$03,$ff,$3c
fb09: c1 f0 f0 ec+ TITLE .str “Apple ][”
fb11: c4 c2 c1 ff+ XLTBL .bulk $c4,$c2,$c1,$ff,$c3,$ff,$ff,$ff
fb19: c1 d8 d9 d0+ RTBL .str “AXYPS” ;register names for REGDSP
fb1e: ad 70 c0 PREAD lda PTRIG ;trigger paddles
fb21: a0 00 ldy #$00 ;init count
fb23: ea nop ;compensate for 1st count
fb24: ea nop
fb25: bd 64 c0 PREAD2 lda PADDL0,x ;count Y-reg every 12 usec
fb28: 10 04 bpl RTS2D ; [actually 11]
fb2a: c8 iny
fb2b: d0 f8 bne PREAD2 ; exit at 255 max
fb2d: 88 dey
fb2e: 60 RTS2D rts
fb2f: a9 00 INIT lda #$00 ;clr status for debug software
fb31: 85 48 sta STATUS
fb33: ad 56 c0 lda LORES
fb36: ad 54 c0 lda TXTPAGE1 ;init video mode
fb39: ad 51 c0 SETTXT lda TXTSET ;set for text mode
fb3c: a9 00 lda #$00 ;full screen window
fb3e: f0 0b beq SETWND
fb40: ad 50 c0 SETGR lda TXTCLR ;set for graphics mode
fb43: ad 53 c0 lda MIXSET ;lower 4 lines as text window
fb46: 20 36 f8 jsr CLRTOP
fb49: a9 14 lda #$14
fb4b: 85 22 SETWND sta WNDTOP ;set for 40 col window
fb4d: a9 00 lda #$00 ; top in A-reg,
fb4f: 85 20 sta WNDLFT ; bottom at line $24
fb51: a0 08 ldy #8 ;code=SETWND /RRA0981
fb53: d0 5f bne GOTOCX ;do 40/80 /RRA0981
fb55: a9 18 lda #$18
fb57: 85 23 sta WNDBTM
fb59: a9 17 lda #$17 ;vtab to row 23
fb5b: 85 25 sta CV ;vtabs to row in A-reg
fb5d: 4c 22 fc jmp VTAB
fb60: 20 58 fc APPLEII jsr HOME ;clear the scrn
fb63: a0 08 ldy #8
fb65: b9 08 fb STITLE lda TITLE-1,y ;get a char
fb68: 99 0e 04 sta LINE1+14,y ;put it at top center of screen
fb6b: 88 dey
fb6c: d0 f7 bne STITLE
fb6e: 60 rts
fb6f: ad f3 03 SETPWRC lda SOFTEV+1 ;routine to calculate the 'funny
fb72: 49 a5 eor #$a5 ; complement' for the reset vector
fb74: 8d f4 03 sta PWREDUP
fb77: 60 rts
; check for a pause (Control-S)
fb78: c9 8d VIDWAIT cmp #$8d ;only when I have a CR
fb7a: d0 18 bne NOWAIT ;not so, do regular
fb7c: ac 00 c0 ldy KBD ;is key pressed?
fb7f: 10 13 bpl NOWAIT ;no
fb81: c0 93 cpy #$93 ;yes -- is it Ctrl-S?
fb83: d0 0f bne NOWAIT ;nope - ignore
fb85: 2c 10 c0 bit KBDSTRB ;clear strobe
fb88: ac 00 c0 KBDWAIT ldy KBD ;wait till next key to resume
fb8b: 10 fb bpl KBDWAIT ;wait for keypress
fb8d: c0 83 cpy #$83 ;is it Control-C?
fb8f: f0 03 beq NOWAIT ;yes, so leave it
fb91: 2c 10 c0 bit KBDSTRB ;clr strobe
fb94: 4c fd fb NOWAIT jmp VIDOUT ;do as before
fb97: 38 ESCOLD sec ;insure carry set
fb98: 4c 2c fc jmp ESC1
fb9b: a8 ESCNOW tay ;use char as index
fb9c: b9 48 fa lda XLTBL-201,y ;translate IJKM to CBAD
fb9f: 20 97 fb jsr ESCOLD ;do the cursor motion for full escapes /RRA0981
fba2: 20 21 fd jsr RDESC ;get IJKM, ijkm, arrows /RRA0981
fba5: c9 ce ESCNEW cmp #$ce ;is this an 'N'
fba7: b0 ee bcs ESCOLD ;'N' or greater - do it!
fba9: c9 c9 cmp #$c9 ;less than 'I'?
fbab: 90 ea bcc ESCOLD ;yes, so do old way
fbad: c9 cc cmp #$cc ;is it an 'L'?
fbaf: f0 e6 beq ESCOLD ;do normal
fbb1: d0 e8 bne ESCNOW ;go do it
fbb3: 06 VERSION .dd1 $06 ;for IDCHECK /RRA0981
fbb4: 08 GOTOCX php ;save user IRQ state /RRA0981
fbb5: 78 sei ;inhibit during bankswitch /RRA0981
fbb6: 2c 15 c0 bit RDCXROM ;get current state /RRA0981
fbb9: 08 php ;save ROM bank state /RRA0981
fbba: 8d 07 c0 sta SETINTCXROM ;set ROMs on /RRA0981
fbbd: 4c 00 c1 jmp $c100 ;=>off to CXspace /RRA0981
fbc0: ea nop ;/RRA0981
; must ORG $FBC1
fbc1: 48 BASCALC pha ;calc base adr in BASL,H
fbc2: 4a lsr A ; for given line no.
fbc3: 29 03 and #$03 ; 0<=line no.<=$17
fbc5: 09 04 ora #$04 ;ARG=000ABCDE, generate
fbc7: 85 29 sta BASH ; BASH=000001CD
fbc9: 68 pla ; and
fbca: 29 18 and #$18 ; BASL=EABAB000
fbcc: 90 02 bcc BSCLC2
fbce: 69 7f adc #$7f
fbd0: 85 28 BSCLC2 sta BASL
fbd2: 0a asl A
fbd3: 0a asl A
fbd4: 05 28 ora BASL
fbd6: 85 28 sta BASL
fbd8: 60 rts
fbd9: c9 87 BELL1 cmp #$87 ;bell char? (Control-G)
fbdb: d0 12 bne RTS2B ; no, return
fbdd: a9 40 lda #$40 ; yes...
fbdf: 20 a8 fc jsr WAIT ;delay .01 seconds
fbe2: a0 c0 ldy #$c0
fbe4: a9 0c BELL2 lda #$0c ;toggle speaker at 1 KHz
fbe6: 20 a8 fc jsr WAIT ; for .1 sec.
fbe9: ad 30 c0 lda SPKR
fbec: 88 dey
fbed: d0 f5 bne BELL2
fbef: 60 RTS2B rts
fbf0: a4 24 STOADV ldy CH ;cursor H index to Y-reg
fbf2: 91 28 sta (BASL),y ;store char in line
fbf4: e6 24 ADVANCE inc CH ;increment cursor H index
fbf6: a5 24 lda CH ; (move right)
fbf8: c5 21 cmp WNDWDTH ;beyond window width?
fbfa: b0 66 bcs CR ; yes CR to next line
fbfc: 60 RTS3 rts ; no, return
fbfd: c9 a0 VIDOUT cmp #$a0 ;control char?
fbff: b0 ef bcs STOADV ; no, output it
fc01: a8 tay ;inverse video?
fc02: 10 ec bpl STOADV ; yes, output it.
fc04: c9 8d cmp #$8d ;CR?
fc06: f0 5a beq CR ; yes.
fc08: c9 8a cmp #$8a ;line feed?
fc0a: f0 5a beq LF ; if so, do it.
fc0c: c9 88 cmp #$88 ;back space? (Control-H)
fc0e: d0 c9 bne BELL1 ; no, check for bell.
fc10: c6 24 BS dec CH ;decrement cursor H index
fc12: 10 e8 bpl RTS3 ;if positive, OK; else move up
fc14: a5 21 lda WNDWDTH ;set CH to window width - 1
fc16: 85 24 sta CH
fc18: c6 24 dec CH ;(rightmost screen pos)
fc1a: a5 22 UP lda WNDTOP ;cursor V index
fc1c: c5 25 cmp CV
fc1e: b0 0b bcs RTS4 ;if top line then return
fc20: c6 25 dec CV ;decr cursor V-index
fc22: a5 25 VTAB lda CV ;get cursor V-index
fc24: 20 c1 fb VTABZ jsr BASCALC ;generate base addr
fc27: 65 20 adc WNDLFT ;and window left index
fc29: 85 28 sta BASL ;to BASL
fc2b: 60 RTS4 rts
fc2c: 49 c0 ESC1 eor #$c0 ;esc '@'?
fc2e: f0 28 beq HOME ; if so, do home and clear
fc30: 69 fd adc #$fd ;esc-A or B check
fc32: 90 c0 bcc ADVANCE ; A, advance
fc34: f0 da beq BS ; B, backspace
fc36: 69 fd adc #$fd ;esc-C or D check
fc38: 90 2c bcc LF ; C,down
fc3a: f0 de beq UP ; D, go up
fc3c: 69 fd adc #$fd ;esc-E or F check
fc3e: 90 5c bcc CLREOL ; E, clear to end of line
fc40: d0 e9 bne RTS4 ; else not F, return
fc42: a0 00 CLREOP ldy #0 ;code=CLREOP /RRA0981
fc44: f0 2c beq XGOTOCX ;do 40/80 /RRA0981
fc46: a8 c3 a9 a0+ .str “(C) 1981-82, APPLE”
fc58: a0 01 HOME ldy #1 ;code=HOME /RRA0981
fc5a: d0 16 bne XGOTOCX ;do 40/80 /RRA0981
fc5c: d2 c9 c3 cb+ .str “RICK A” ;our hero...
fc62: a9 00 CR lda #$00 ;cursor to left of index
fc64: 85 24 sta CH ;(ret cursor H=0)
fc66: e6 25 LF inc CV ;incr cursor V (down 1 line)
fc68: a5 25 lda CV
fc6a: c5 23 cmp WNDBTM ;off screen?
fc6c: 90 b6 bcc VTABZ ; no, set base addr
fc6e: c6 25 dec CV ;decr cursor V (back to bottom)
fc70: a0 02 SCROLL ldy #2 ;code=SCROLL /RRA0981
fc72: 4c b4 fb XGOTOCX jmp GOTOCX ;do 40/80
;
; IRQ sniffer for video code [called from 80-column firmware].
;
fc75: 48 pha ;preserve AC /RRA0981
fc76: ad 18 c0 lda RD80COL ;flag->N /RRA0981
fc79: 0a asl A ;flag->C /RRA0981
fc7a: 68 pla ;restore AC /RRA0981
fc7b: 2c 1c c0 bit RDPAGE2 ;flag->N /RRA0981
fc7e: 08 php ;/RRA0981
fc7f: 90 03 bcc RDCX ;not bankswitching /RRA0981
fc81: 8d 54 c0 sta TXTPAGE1 ;force MB txtpage /RRA0981
fc84: 2c 15 c0 RDCX bit RDCXROM ;flag->N /RRA0981
fc87: 8d 06 c0 sta SETSLOTCXROM ;restore bank /RRA0981
fc8a: 58 cli ;enable IRQ /RRA0981
fc8b: 78 sei ;now disable /RRA0981
fc8c: 10 03 bpl ISSLOTS ;=>was SLOTS /RRA0981
fc8e: 8d 07 c0 sta SETINTCXROM ;bank-in CX /RRA0981
fc91: 28 ISSLOTS plp ;what vid bank/page? /RRA0981
fc92: 90 05 bcc ISPAGE1 ;=>not banked /RRA0981
fc94: 10 03 bpl ISPAGE1 ;it's page1 /RRA0981
fc96: 2c 55 c0 bit TXTPAGE2 ;force page2 /RRA0981
fc99: 60 ISPAGE1 rts ;continue video /RRA0981
fc9a: ea nop ;/RRA0981
fc9b: ea nop ;/RRA0981
fc9c: 18 CLREOL clc ;say 'EOL' /RRA0981
fc9d: b0 bcs ▼ WRBIT+1 ;'BCS' opcode /RRA0981
fc9e: 38 CLREOLZ sec ;say 'EOLZ' /RRA0981
fc9f: 84 1f sty $1f ;video's YSAV1 /RRA0981
fca1: a0 03 ldy #3 ;code=EOL /RRA0981
fca3: 90 cd bcc XGOTOCX ;->it's EOL /RRA0981
fca5: c8 iny ;code=EOLZ /RRA0981
fca6: d0 ca bne XGOTOCX ;->always /RRA0981
fca8: 38 WAIT sec
fca9: 48 WAIT2 pha
fcaa: e9 01 WAIT3 sbc #$01 ;1.0204 usec [wrong]
fcac: d0 fc bne WAIT3 ;(13+2712*A+512*A*A) [wrong]
fcae: 68 pla
fcaf: e9 01 sbc #$01
fcb1: d0 f6 bne WAIT2
fcb3: 60 rts
fcb4: e6 42 NXTA4 inc A4L ;incr 2-byte A4
fcb6: d0 02 bne NXTA1 ; and A1
fcb8: e6 43 inc A4H
fcba: a5 3c NXTA1 lda A1L ;incr 2-byte A1.
fcbc: c5 3e cmp A2L ; and compare to A2
fcbe: a5 3d lda A1H ; (carry set if >=)
fcc0: e5 3f sbc A2H
fcc2: e6 3c inc A1L
fcc4: d0 02 bne RTS4B
fcc6: e6 3d inc A1H
fcc8: 60 RTS4B rts
fcc9: a0 4b HEADR ldy #$4b ;write A*256 'long 1'
fccb: 20 db fc jsr ZERDLY ; half cycles
fcce: d0 f9 bne HEADR ; (650 usec each)
fcd0: 69 fe adc #$fe
fcd2: b0 f5 bcs HEADR ;then a 'short 0'
fcd4: a0 21 ldy #$21 ; (400 usec)
fcd6: 20 db fc WRBIT jsr ZERDLY ;write two half cycles
fcd9: c8 iny ; of 250 usec ('0')
fcda: c8 iny ; or 500 usec ('0')
fcdb: 88 ZERDLY dey
fcdc: d0 fd bne ZERDLY
fcde: 90 05 bcc WRTAPE ;Y is count for
fce0: a0 32 ldy #$32 ; timing loop
fce2: 88 ONEDLY dey
fce3: d0 fd bne ONEDLY
fce5: ac 20 c0 WRTAPE ldy TAPEOUT
fce8: a0 2c ldy #$2c
fcea: ca dex
fceb: 60 rts
fcec: a2 08 RDBYTE ldx #$08 ;8 bits to read
fcee: 48 RDBYT2 pha ;read two transitions
fcef: 20 fa fc jsr RD2BIT ; (find edge)
fcf2: 68 pla
fcf3: 2a rol A ;next bit
fcf4: a0 3a ldy #$3a ;count for samples
fcf6: ca dex
fcf7: d0 f5 bne RDBYT2
fcf9: 60 rts
fcfa: 20 fd fc RD2BIT jsr RDBIT
fcfd: 88 RDBIT dey ;decr Y until
fcfe: ad 60 c0 lda TAPEIN ; tape transition
fd01: 45 2f eor LASTIN
fd03: 10 f8 bpl RDBIT
fd05: 45 2f eor LASTIN
fd07: 85 2f sta LASTIN
fd09: c0 80 cpy #$80 ;set carry on Y-reg.
fd0b: 60 rts
fd0c: a4 24 RDKEY ldy CH
fd0e: b1 28 lda (BASL),y ;set screen to flash
fd10: 48 pha
fd11: 29 3f and #$3f
fd13: 09 40 ora #$40
fd15: 91 28 sta (BASL),y
fd17: 68 pla
fd18: 6c 38 00 jmp (KSWL) ;go to user key-in
fd1b: a0 06 KEYIN ldy #6 ;RDKEY /RRA0981
fd1d: 4c b4 fb jmp GOTOCX ;/RRA0981
fd20: ea nop
fd21: 20 0c fd RDESC jsr RDKEY ;get a key
fd24: a0 07 ldy #7 ;code=FIXIT
fd26: 4c b4 fb jmp GOTOCX
;
; Return from GOTOCX here.
;
; [80-column firmware will jump to $FD29 or $FD2C.]
;
fd29: 8d 06 c0 sta SETSLOTCXROM ;restore bank /RRA0981
fd2c: 28 plp ;restore IRQ /RRA0981
fd2d: 60 rts ;return to caller /RRA0981
fd2e: 60 rts
fd2f: 20 21 fd ESC jsr RDESC ;/RRA0981
fd32: 20 a5 fb jsr ESCNEW ;handle ESC function
fd35: 20 0c fd RDCHAR jsr RDKEY ;go read key
fd38: c9 9b cmp #$9b ;'ESC'?
fd3a: f0 f3 beq ESC ; yes, don't return
fd3c: 60 rts
fd3d: a5 32 NOTCR lda INVFLG
fd3f: 48 pha
fd40: a9 ff lda #$ff
fd42: ea nop ;don't change input /RRA0981
fd43: ea nop ; to normal /RRA0981
fd44: bd 00 02 lda IN,x
fd47: 20 ed fd jsr COUT ;echo typed char
fd4a: 68 pla
fd4b: 85 32 sta INVFLG
fd4d: bd 00 02 lda IN,x
fd50: c9 88 cmp #$88 ;check for edit keys
fd52: f0 1d beq BCKSPC ; - backspace
fd54: c9 98 cmp #$98
fd56: f0 0a beq CANCEL ; - Control-X
fd58: e0 f8 cpx #$f8
fd5a: 90 03 bcc NOTCR1 ;margin?
fd5c: 20 3a ff jsr BELL ;yes, sound bell
fd5f: e8 NOTCR1 inx ;advance input index
fd60: d0 13 bne NXTCHAR
fd62: a9 dc CANCEL lda #$dc ;backslash after cancelled line
fd64: 20 ed fd jsr COUT
fd67: 20 8e fd GETLNZ jsr CROUT ;output 'CR'
fd6a: a5 33 GETLN lda PROMPT ;output prompt char
fd6c: 20 ed fd jsr COUT
fd6f: a2 01 ldx #$01 ;init input index
fd71: 8a BCKSPC txa
fd72: f0 f3 beq GETLNZ ;will backspace to 0
fd74: ca dex
fd75: 20 35 fd NXTCHAR jsr RDCHAR
fd78: c9 95 cmp #$95 ;use screen char
fd7a: d0 02 bne CAPTST ; for Control-U
fd7c: b1 28 lda (BASL),y
fd7e: c9 e0 CAPTST cmp #$e0 ;lower case?
fd80: 90 02 bcc ADDINP
fd82: 29 ff and #$ff ;don't convert to upper case! /RRA0981
fd84: 9d 00 02 ADDINP sta IN,x ;add to input buffer
fd87: c9 8d cmp #$8d
fd89: d0 b2 bne NOTCR
fd8b: 20 9c fc jsr CLREOL ;clr to EOL if CR
fd8e: a9 8d CROUT lda #$8d
fd90: d0 5b bne COUT ;(always)
fd92: a4 3d PRA1 ldy A1H ;print CR,A1 in hex
fd94: a6 3c ldx A1L
fd96: 20 8e fd PRYX2 jsr CROUT
fd99: 20 40 f9 jsr PRNTYX
fd9c: a0 00 ldy #$00
fd9e: a9 ad lda #$ad ;print '-'
fda0: 4c ed fd jmp COUT
fda3: a5 3c XAM8 lda A1L
fda5: 09 07 ora #$07 ;set to finish at
fda7: 85 3e sta A2L ; mod 8=7
fda9: a5 3d lda A1H
fdab: 85 3f sta A2H
fdad: a5 3c MOD8CHK lda A1L
fdaf: 29 07 and #$07
fdb1: d0 03 bne DATACUT
fdb3: 20 92 fd XAM jsr PRA1
fdb6: a9 a0 DATACUT lda #$a0
fdb8: 20 ed fd jsr COUT ;output blank
fdbb: b1 3c lda (A1L),y
fdbd: 20 da fd jsr PRBYTE ;output byte in hex
fdc0: 20 ba fc jsr NXTA1
fdc3: 90 e8 bcc MOD8CHK ;not done yet. Go check mod 8
fdc5: 60 RTS4C rts ;done.
fdc6: 4a XAMPM lsr A ;determine if monitor mode is
fdc7: 90 ea bcc XAM ; examine, add or subtract
fdc9: 4a lsr A
fdca: 4a lsr A
fdcb: a5 3e lda A2L
fdcd: 90 02 bcc ADD
fdcf: 49 ff eor #$ff ;form 2's complement for subtract
fdd1: 65 3c ADD adc A1L
fdd3: 48 pha
fdd4: a9 bd lda #$bd ;print '=', then result
fdd6: 20 ed fd jsr COUT
fdd9: 68 pla
fdda: 48 PRBYTE pha ;print byte as 2 hex digits
fddb: 4a lsr A ; (destroys A-reg)
fddc: 4a lsr A
fddd: 4a lsr A
fdde: 4a lsr A
fddf: 20 e5 fd jsr PRHEXZ
fde2: 68 pla
fde3: 29 0f PRHEX and #$0f ;print hex digit in A-reg
fde5: 09 b0 PRHEXZ ora #$b0 ; LSBits only
fde7: c9 ba cmp #$ba
fde9: 90 02 bcc COUT
fdeb: 69 06 adc #$06
fded: 6c 36 00 COUT jmp (CSWL) ;vector to user output routine
fdf0: c9 a0 COUT1 cmp #$a0
fdf2: 90 02 bcc COUTZ ;don't output ctrl's inverse
fdf4: 25 32 and INVFLG ;mask with inverse flag
fdf6: 84 35 COUTZ sty YSAV1 ;save Y-reg
fdf8: 48 pha ;save A-reg
fdf9: 20 78 fb jsr VIDWAIT ;output chr & check for Ctrl-S
fdfc: 68 pla ;restore A-reg
fdfd: a4 35 ldy YSAV1 ; and Y-reg
fdff: 60 rts ; return to sender...
fe00: c6 34 BL1 dec YSAV
fe02: f0 9f beq XAM8
fe04: ca BLANK dex ;blank to mon
fe05: d0 16 bne SETMDZ ;after blank
fe07: c9 ba cmp #$ba ;data store mode?
fe09: d0 bb bne XAMPM ; no, xam, add or sub
fe0b: 85 31 STOR sta MODE ;keep in store mode
fe0d: a5 3e lda A2L
fe0f: 91 40 sta (A3L),y ;store as lwo byte as (A3)
fe11: e6 40 inc A3L
fe13: d0 02 bne RTS5 ;incr A3, return
fe15: e6 41 inc A3H
fe17: 60 RTS5 rts
fe18: a4 34 SETMODE ldy YSAV ;save converted ':', '+',
fe1a: b9 ff 01 lda IN-1,y ; '-', '.' as mode.
fe1d: 85 31 SETMDZ sta MODE
fe1f: 60 rts
fe20: a2 01 LT ldx #$01
fe22: b5 3e LT2 lda A2L,x ;copy A2 (2 bytes) to
fe24: 95 42 sta A4L,x ; A4 and A5
fe26: 95 44 sta A5L,x
fe28: ca dex
fe29: 10 f7 bpl LT2
fe2b: 60 rts
fe2c: b1 3c MOVE lda (A1L),y ;move (A1 to A2) to (A4)
fe2e: 91 42 sta (A4L),y
fe30: 20 b4 fc jsr NXTA4
fe33: 90 f7 bcc MOVE
fe35: 60 rts
fe36: b1 3c VFY lda (A1L),y ;verify (A1) thru (A2)
fe38: d1 42 cmp (A4L),y ; with (A4)
fe3a: f0 1c beq VFYOK
fe3c: 20 92 fd jsr PRA1
fe3f: b1 3c lda (A1L),y
fe41: 20 da fd jsr PRBYTE
fe44: a9 a0 lda #$a0
fe46: 20 ed fd jsr COUT
fe49: a9 a8 lda #$a8
fe4b: 20 ed fd jsr COUT
fe4e: b1 42 lda (A4L),y
fe50: 20 da fd jsr PRBYTE
fe53: a9 a9 lda #$a9
fe55: 20 ed fd jsr COUT
fe58: 20 b4 fc VFYOK jsr NXTA4
fe5b: 90 d9 bcc VFY
fe5d: 60 rts
fe5e: 20 75 fe LIST jsr A1PC ;move A1 (2 bytes) to
fe61: a9 14 lda #$14 ; PC if spec'd and
fe63: 48 LIST2 pha ; dissemble 20 instrs
fe64: 20 d0 f8 jsr INSTDSP
fe67: 20 53 f9 jsr PCADJ ;adjust PC after each instruction
fe6a: 85 3a sta PCL
fe6c: 84 3b sty PCH
fe6e: 68 pla
fe6f: 38 sec
fe70: e9 01 sbc #$01 ;next of 20 instructions
fe72: d0 ef bne LIST2
fe74: 60 rts
fe75: 8a A1PC txa ;if user specified an address,
fe76: f0 07 beq A1PCRTS ; copy it from A1 to PC
fe78: b5 3c A1PCLP lda A1L,x ;yep, so copy it
fe7a: 95 3a sta PCL,x
fe7c: ca dex
fe7d: 10 f9 bpl A1PCLP
fe7f: 60 A1PCRTS rts
fe80: a0 3f SETINV ldy #$3f ;set for inverse vid
fe82: d0 02 bne SETIFLG ; via COUT1
fe84: a0 ff SETNORM ldy #$ff ;set for normal vid
fe86: 84 32 SETIFLG sty INVFLG
fe88: 60 rts
fe89: a9 00 SETKBD lda #$00 ;do 'IN#0'
fe8b: 85 3e INPORT sta A2L ;do 'IN#AREG'
fe8d: a2 38 INPRT ldx #KSWL
fe8f: a0 1b ldy #<KEYIN
fe91: d0 08 bne IOPRT
fe93: a9 00 SETVID lda #$00 ;do 'PR#0'
fe95: 85 3e OUTPORT sta A2L ;do 'PR#AREG'
fe97: a2 36 OUTPRT ldx #CSWL
fe99: a0 f0 ldy #<COUT1
fe9b: a5 3e IOPRT lda A2L ;set input/output vectors
fe9d: 29 0f and #$0f
fe9f: f0 06 beq IOPRT1
fea1: 09 c0 ora #>IOADR
fea3: a0 00 ldy #$00
fea5: f0 02 beq IOPRT2
fea7: a9 fd IOPRT1 lda #>COUT1
fea9: 94 00 IOPRT2 sty LOC0,x
feab: 95 01 sta LOC1,x
fead: 60 rts
feae: ea nop
feaf: d1 CKSUMFIX .dd1 $d1 ;-->correct cksum at create time /RRA0981
feb0: 4c 00 e0 XBASIC jmp BASIC ;to BASIC, cold start
feb3: 4c 03 e0 BASCONT jmp BASIC2 ;to BASIC, warm start
feb6: 20 75 fe GO jsr A1PC ;adr to PC if specified
feb9: 20 3f ff jsr RESTORE ;restore fake registers
febc: 6c 3a 00 jmp (PCL) ;and go!
febf: 4c d7 fa REGZ jmp REGDSP ;go display registers
fec2: 60 TRACE rts ;trace is gone
fec3: ea nop
fec4: 60 STEPZ rts ;step is gone
fec5: c2 f2 f9 e1+ .str “Bryan”
feca: 4c f8 03 USR jmp USRADR ;jump to Control-Y vector in RAM
fecd: a9 40 WRITE lda #$40 ;tape write routine
fecf: 20 c9 fc jsr HEADR ;write 10-sec header
fed2: a0 27 ldy #$27
fed4: a2 00 WR1 ldx #$00
fed6: 41 3c eor (A1L,x)
fed8: 48 pha
fed9: a1 3c lda (A1L,x)
fedb: 20 ed fe jsr WRBYTE
fede: 20 ba fc jsr NXTA1
fee1: a0 1d ldy #$1d
fee3: 68 pla
fee4: 90 ee bcc WR1
fee6: a0 22 ldy #$22
fee8: 20 ed fe jsr WRBYTE
feeb: f0 4d beq BELL
feed: a2 10 WRBYTE ldx #$10
feef: 0a WRBYT2 asl A
fef0: 20 d6 fc jsr WRBIT
fef3: d0 fa bne WRBYT2
fef5: 60 rts
fef6: 20 00 fe CRMON jsr BL1 ;handle CR as blank
fef9: 68 pla ; then pop stack
fefa: 68 pla ; and return to mon
fefb: d0 6c bne MONZ ;(always)
fefd: 20 fa fc READ jsr RD2BIT ;tape read - find tapein edge
ff00: a9 16 lda #$16 ;delay 3.5 seconds
ff02: 20 c9 fc jsr HEADR
ff05: 85 2e sta CHKSUM ;initial checksum = $FF
ff07: 20 fa fc jsr RD2BIT ;find an edge
ff0a: a0 24 RD2 ldy #$24 ;look for sync bit
ff0c: 20 fd fc jsr RDBIT ; (short 0)
ff0f: b0 f9 bcs RD2 ;loop 'til found
ff11: 20 fd fc jsr RDBIT ;skip 2nd half cycle
ff14: a0 3b ldy #$3b ;index for 0/1 test
ff16: 20 ec fc RD3 jsr RDBYTE ;read a byte
ff19: 81 3c sta (A1L,x) ;put it at (A1)
ff1b: 45 2e eor CHKSUM ;update running checksum
ff1d: 85 2e sta CHKSUM
ff1f: 20 ba fc jsr NXTA1 ;incr A1, compare to A2
ff22: a0 35 ldy #$35 ;compenstate 0/1 index
ff24: 90 f0 bcc RD3 ;repeat 'til done
ff26: 20 ec fc jsr RDBYTE ;read checksum byte
ff29: c5 2e cmp CHKSUM ;does the recorded chksm match ours?
ff2b: f0 0d beq BELL ; yep, read OK, beep and return
ff2d: a9 c5 PRERR lda #$c5 ;print 'ERR', then fall into
ff2f: 20 ed fd jsr COUT ; fweeper
ff32: a9 d2 lda #$d2
ff34: 20 ed fd jsr COUT
ff37: 20 ed fd jsr COUT
ff3a: a9 87 BELL lda #$87 ;make a joyful noise, then return
ff3c: 4c ed fd jmp COUT
ff3f: a5 48 RESTORE lda STATUS ;restore 6502 register contents
ff41: 48 pha ; used by debug software
ff42: a5 45 lda A5H
ff44: a6 46 RESTR1 ldx XREG
ff46: a4 47 ldy YREG
ff48: 28 plp
ff49: 60 rts
ff4a: 85 45 SAVE sta A5H ;save 6502 reg contents
ff4c: 86 46 SAV1 stx XREG ; for debug software
ff4e: 84 47 sty YREG
ff50: 08 php
ff51: 68 pla
ff52: 85 48 sta STATUS
ff54: ba tsx
ff55: 86 49 stx SPNT
ff57: d8 cld
ff58: 60 rts
ff59: 20 84 fe OLDRST jsr SETNORM ;set screen mode
ff5c: 20 2f fb jsr INIT ; and init kbd/screen
ff5f: 20 93 fe jsr SETVID ; as I/O dev's
ff62: 20 89 fe jsr SETKBD
ff65: d8 MON cld ;must set hex mode!
ff66: 20 3a ff jsr BELL ;fweeper
ff69: a9 aa MONZ lda #$aa ;'*' prompt for mon
ff6b: 85 33 sta PROMPT
ff6d: 20 67 fd jsr GETLNZ ;read a line of input
ff70: 20 c7 ff jsr ZMODE ;clear monitor mode, scan idx
ff73: 20 a7 ff NXTITM jsr GETNUM ;get item, non-hex
ff76: 84 34 sty YSAV ; char in A-reg
ff78: a0 17 ldy #$17 ; X-reg=0 if no hex input
ff7a: 88 CHRSRCH dey
ff7b: 30 e8 bmi MON ;command not found, beep & try again
ff7d: d9 cc ff cmp CHRTBL,y ;find command char in table
ff80: d0 f8 bne CHRSRCH ;not this time
ff82: 20 be ff jsr TOSUB ;got it! Call corresponding subroutine
ff85: a4 34 ldy YSAV ;process next entry on [t]his line
ff87: 4c 73 ff jmp NXTITM
ff8a: a2 03 DIG ldx #$03
ff8c: 0a asl A
ff8d: 0a asl A ;got hex digit,
ff8e: 0a asl A ; shift into A2
ff8f: 0a asl A
ff90: 0a NXTBIT asl A
ff91: 26 3e rol A2L
ff93: 26 3f rol A2H
ff95: ca dex ;leave X=$ff if dig
ff96: 10 f8 bpl NXTBIT
ff98: a5 31 NXTBAS lda MODE
ff9a: d0 06 bne NXTBS2 ;if mode is zero
ff9c: b5 3f lda A2H,x ; then copy A2 to A1 and A3
ff9e: 95 3d sta A1H,x
ffa0: 95 41 sta A3H,x
ffa2: e8 NXTBS2 inx
ffa3: f0 f3 beq NXTBAS
ffa5: d0 06 bne NXTCHR
ffa7: a2 00 GETNUM ldx #$00 ;clear A2
ffa9: 86 3e stx A2L
ffab: 86 3f stx A2H
ffad: b9 00 02 NXTCHR lda IN,y ;get char
ffb0: c8 iny
ffb1: 49 b0 eor #$b0
ffb3: c9 0a cmp #$0a
ffb5: 90 d3 bcc DIG ;br if hex digit
ffb7: 69 88 adc #$88
ffb9: c9 fa cmp #$fa
ffbb: b0 cd bcs DIG
ffbd: 60 rts
ffbe: a9 fe TOSUB lda #>GO ;dispatch to subroutine, by
ffc0: 48 pha ; pushing the hi-order subr addr
ffc1: b9 e3 ff lda SUBTBL,y ; then the lo-order subr addr
ffc4: 48 pha ; onto the stack
ffc5: a5 31 lda MODE ; (clearing the mode, save the old
ffc7: a0 00 ZMODE ldy #$00 ; mode in A-reg)
ffc9: 84 31 sty MODE
ffcb: 60 rts ;and 'RTS' to the subroutine!
ffcc: bc CHRTBL .dd1 $bc ;^C (BASIC warm start)
ffcd: b2 .dd1 $b2 ;^Y (user vector)
ffce: be .dd1 $be ;^E (open and display registers)
ffcf: b2 .dd1 $b2 ;T (once was trace; never used)
ffd0: ef .dd1 $ef ;V (memory verify)
ffd1: c4 .dd1 $c4 ;^K (IN#slot)
ffd2: b2 .dd1 $b2 ;S (once was step; now never used)
ffd3: a9 .dd1 $a9 ;^P (PR#slot)
ffd4: bb .dd1 $bb ;^B (BASIC cold start)
ffd5: a6 .dd1 $a6 ;'-' (subtraction)
ffd6: a4 .dd1 $a4 ;'+' (addition)
ffd7: 06 .dd1 $06 ;M (memory move)
ffd8: 95 .dd1 $95 ;'<' (delimiter for move, vfy)
ffd9: 07 .dd1 $07 ;N (set normal video)
ffda: 02 .dd1 $02 ;I (set inverse video)
ffdb: 05 .dd1 $05 ;L (disassemble 20 instrs)
ffdc: f0 .dd1 $f0 ;W (write to tape)
ffdd: 00 .dd1 $00 ;G (execute program)
ffde: eb .dd1 $eb ;R (read from tape)
ffdf: 93 .dd1 $93 ;':' (memory fill)
ffe0: a7 .dd1 $a7 ;'.' (address delimiter)
ffe1: c6 .dd1 $c6 ;'CR' (end of input)
ffe2: 99 .dd1 $99 ;blank
ffe3: b2 SUBTBL .dd1 <BASCONT-1 ;table of lo-order monitor routine
ffe4: c9 .dd1 <USR-1 ; dispatch addresses
ffe5: be .dd1 <REGZ-1
ffe6: c1 .dd1 <TRACE-1
ffe7: 35 .dd1 <VFY-1
ffe8: 8c .dd1 <INPRT-1
ffe9: c4 .dd1 <STEPZ
ffea: 96 .dd1 <OUTPRT-1
ffeb: af .dd1 <XBASIC-1
ffec: 17 .dd1 <SETMODE-1
ffed: 17 .dd1 <SETMODE-1
ffee: 2b .dd1 <MOVE-1
ffef: 1f .dd1 <LT-1
fff0: 83 .dd1 <SETNORM-1
fff1: 7f .dd1 <SETINV-1
fff2: 5d .dd1 <LIST-1
fff3: cc .dd1 <WRITE-1
fff4: b5 .dd1 <GO-1
fff5: fc .dd1 <READ-1
fff6: 17 .dd1 <SETMODE-1
fff7: 17 .dd1 <SETMODE-1
fff8: f5 .dd1 <CRMON-1
fff9: 03 .dd1 <BLANK-1
fffa: fb 03 .dd2 NMI ;non-maskable interrupt vector
fffc: 62 fa .dd2 RESET ;reset vector
fffe: 40 fa .dd2 IRQ ;interrupt request vector