ca65 V2.17 - Git 582aa41 Main file : ade.ca65 Current file: ade.ca65 000000r 1 ; 000000r 1 ; Acorn System ADE (Assembler/Disassembler/Editor) 000000r 1 ; 000000r 1 ; This source code is based on an originally disassembled and commented version from circa 1980 000000r 1 ; which was derived from an original Acorn EPROM purchased in 1981. 000000r 1 ; 000000r 1 ; Recently transferred to CA65. 000000r 1 ; 000000r 1 ; (Chris Oddy December 2018) 000000r 1 ; 000000r 1 .setcpu "6502" 000000r 1 .listbytes unlimited 000000r 1 ; 000000r 1 ; Zero Page Registers 000000r 1 ; 000000r 1 sourcm := $00 ; 000000r 1 source := $01 ; 000000r 1 sourcf := $02 ; 000000r 1 zsymbol := $03 ; 000000r 1 symf := $04 ; 000000r 1 object := $05 ; 000000r 1 lineno := $06 ; 000000r 1 txtptr := $08 ; 000000r 1 temp_1 := $0A ; 000000r 1 temp_2 := $0B ; 000000r 1 p1_lsb := $0C ; 000000r 1 p1_msb := $0F ; 000000r 1 p2_lsb := $0D ; 000000r 1 p2_msb := $10 ; 000000r 1 p3_lsb := $0E ; 000000r 1 p3_msb := $11 ; 000000r 1 pcount := $12 ; 000000r 1 ptr := $13 ; 000000r 1 ptindx := $15 ; 000000r 1 lasthx := $16 ; 000000r 1 symptr := $17 ; 000000r 1 objadr := $19 ; 000000r 1 sympta := $1B ; 000000r 1 symptb := $1D ; 000000r 1 page := $1D ; 000000r 1 line := $1E ; 000000r 1 swpcnt := $1F ; 000000r 1 index := $20 ; 000000r 1 zprint := $21 ; 000000r 1 zpass := $22 ; 000000r 1 zsave := $23 ; 000000r 1 numspc := $24 ; 000000r 1 noprnd := $25 ; 000000r 1 opcode := $26 ; 000000r 1 zARGMNT := $27 ; 000000r 1 obj_id := $29 ; 000000r 1 objptr := $2A ; 000000r 1 srcsym := $2C ; 000000r 1 adrmod := $2E ; 000000r 1 fileid := $2F ; 000000r 1 table := $30 ; 000000r 1 unclab := $3A ; 000000r 1 ncmne := $40 ; 000000r 1 uncmode := $43 ; 000000r 1 uncarg := $45 ; 000000r 1 comlab := $4C ; 000000r 1 commne := $50 ; 000000r 1 comarg := $52 ; 000000r 1 temp := $56 ; 000000r 1 prgnam := $57 ; 000000r 1 admode := $5D ; 000000r 1 ; 000000r 1 ; ASCII Control Characters 000000r 1 ; 000000r 1 EOT := $04 ; End Of Transmission 000000r 1 ENQ := $05 ; ENQuire 000000r 1 CR := $0D ; Carriage Return 000000r 1 CAN := $18 ; CANcel 000000r 1 ESC := $1B ; ESCape 000000r 1 SPACE := $20 ; Space Bar 000000r 1 DEL := $7F ; DELete 000000r 1 ; 000000r 1 bufsiz := $50 ; 000000r 1 ; 000000r 1 buffer := $0100 ; 000000r 1 strbuf := $0140 ; 000000r 1 brkvec := $0202 ; 000000r 1 ; 000000r 1 ; OS Calls 000000r 1 ; 000000r 1 OSSAVE := $FFDD ; 000000r 1 OSLOAD := $FFE0 ; 000000r 1 OSECHO := $FFE6 ; 000000r 1 OSASCI := $FFE9 ; 000000r 1 OSCLI := $FFF7 ; 000000r 1 ; 000000r 1 ; CPU Card 8154 PIA (Keyboard Interface) 000000r 1 ; 000000r 1 port_a := $0E21 ; Port B Data Register 000000r 1 ; 000000r 1 .org $C000 00C000 1 ; 00C000 1 ; ADE Entry Point 00C000 1 A2 05 START: ldx #$05 ; Load table of default pointers 00C002 1 BD 62 CF movdef: lda DEFTAB,x 00C005 1 95 00 sta sourcm,x 00C007 1 CA dex 00C008 1 10 F8 bpl movdef 00C00A 1 20 B4 CE CLEAR: jsr CRLF 00C00D 1 A0 57 ldy #new-text ; point Y at 'New?' text 00C00F 1 20 6C C8 jsr QUERY ; and get reply 00C012 1 D0 25 bne nxtcom ; perform new ? 00C014 1 20 BC C4 jsr RSTEXT ; set text pointer & linenumber to start 00C017 1 85 17 sta symptr 00C019 1 A9 0D lda #CR 00C01B 1 20 F4 C4 jsr WR_CHR ; store CR at start of text area 00C01E 1 20 ED C4 jsr WR_LNO ; store linenumber at text area 00C021 1 A6 02 ldx sourcf 00C023 1 A9 04 lda #EOT ; fill text area with EOT character 00C025 1 C8 fileot: iny ; increment pointer 00C026 1 D0 02 bne dofill 00C028 1 E6 09 inc txtptr+1 00C02A 1 91 08 dofill: sta (txtptr),y ; write EOT 00C02C 1 E4 09 cpx txtptr+1 00C02E 1 D0 F5 bne fileot 00C030 1 A5 03 lda zsymbol ; set top of symbol table pointer 00C032 1 85 18 sta symptr+1 00C034 1 A0 5E ldy #clear-text ; point Y at 'Clear' text 00C036 1 20 78 C8 jsr OUTEXT ; and output 00C039 1 20 B4 CE nxtcom: jsr CRLF 00C03C 1 A2 FF ldx #$FF ; set up stack 00C03E 1 9A txs 00C03F 1 D8 cld 00C040 1 A9 CB lda #ERROR0 00C047 1 8D 03 02 sta brkvec+1 00C04A 1 A9 3E lda #'>' 00C04C 1 20 BD CE jsr OUTCHR ; output Editor prompt 00C04F 1 20 DA CE jsr BUFFIN ; read input line 00C052 1 20 58 C0 jsr EDITOR ; and execute Editor command 00C055 1 4C 39 C0 jmp nxtcom ; and round again 00C058 1 00C058 1 ; Interpret Editor Command 00C058 1 A2 00 EDITOR: ldx #$00 ; clear parameters 00C05A 1 A0 06 ldy #lineno 00C05C 1 96 0B clr_p: stx p1_lsb-1,y 00C05E 1 88 dey 00C05F 1 D0 FB bne clr_p 00C061 1 86 12 stx pcount ; clear parameter counter 00C063 1 AD 00 01 lda buffer 00C066 1 C9 2A cmp #'*' ; is it Operating System command ? 00C068 1 D0 0E bne not_os 00C06A 1 A9 20 lda #SPACE ; yes - remove * 00C06C 1 8D 00 01 sta buffer 00C06F 1 20 F7 FF jsr OSCLI ; and call OS Command Line Interpreter 00C072 1 A9 2A lda #'*' ; put * back 00C074 1 8D 00 01 sta buffer 00C077 1 60 rts ; and return 00C078 1 C9 46 not_os: cmp #'F' ; F command ? 00C07A 1 D0 0B bne not_f 00C07C 1 E8 inx ; yes - find 2nd delimiter 00C07D 1 E8 delim: inx 00C07E 1 BD 00 01 lda buffer,x 00C081 1 CD 01 01 cmp buffer+1 00C084 1 D0 F7 bne delim 00C086 1 E8 fndpar: inx ; parameters are after string 00C087 1 BD 00 01 not_f: lda buffer,x ; read parameter 00C08A 1 C9 41 cmp #'A' 00C08C 1 10 F8 bpl fndpar ; branch is >=A to pass over command 00C08E 1 CA dex 00C08F 1 A9 00 nxtpar: lda #$00 ; clear temporary parameter 00C091 1 85 0A err_92: sta temp_1 00C093 1 85 0B sta temp_2 00C095 1 E8 scan: inx 00C096 1 BD 00 01 lda buffer,x ; read input line 00C099 1 C9 0D cmp #CR ; end of line ? 00C09B 1 F0 1E beq endpar 00C09D 1 C9 20 cmp #SPACE 00C09F 1 F0 F4 beq scan ; ignore spaces 00C0A1 1 C9 2C cmp #',' ; delimiter ? 00C0A3 1 F0 16 beq endpar 00C0A5 1 20 3A CF jsr ASCHEX ; check value is hex 00C0A8 1 90 E6 bcc err_92-1 ; if not Error 92 ' Command syntax error' 00C0AA 1 98 tya 00C0AB 1 A0 04 ldy #$04 ; shift digit into top nibble 00C0AD 1 0A asl a 00C0AE 1 0A asl a 00C0AF 1 0A asl a 00C0B0 1 0A asl a 00C0B1 1 0A shift: asl a 00C0B2 1 26 0A rol temp_1 ; shift digit into temporary parameter 00C0B4 1 26 0B rol temp_2 00C0B6 1 88 dey ; decrement bit counter 00C0B7 1 D0 F8 bne shift ; shift whole digit 00C0B9 1 F0 DA beq scan ; and continue with next digit 00C0BB 1 A4 12 endpar: ldy pcount ; end of parameter 00C0BD 1 48 pha 00C0BE 1 A5 0A lda temp_1 ; move new parameter 00C0C0 1 99 0C 00 sta p1_lsb,y ; into parameter location 00C0C3 1 A5 0B lda temp_2 00C0C5 1 99 0F 00 sta p1_msb,y 00C0C8 1 68 pla 00C0C9 1 E6 12 inc pcount ; increment parameter counter 00C0CB 1 C9 0D cmp #CR ; what was parameter - end, CR ? 00C0CD 1 D0 C0 bne nxtpar ; no must have been a comma - next parameter 00C0CF 1 C6 12 dec pcount 00C0D1 1 D0 08 bne n1para ; was there only one parameter ? 00C0D3 1 A5 0C lda p1_lsb ; yes - put in second as well 00C0D5 1 85 0D sta p2_lsb 00C0D7 1 A5 0F lda p1_msb 00C0D9 1 85 10 sta p2_msb 00C0DB 1 AD 00 01 n1para: lda buffer ; read command character 00C0DE 1 C9 41 cmp #'A' ; check range of letters 00C0E0 1 90 13 bcc err_F7+2 ; Error F7 'Unknown command' 00C0E2 1 C9 5B cmp #'Z'+1 00C0E4 1 B0 0F bcs err_F7+2 00C0E6 1 E9 40 sbc #$40 ; calculate offset to address table 00C0E8 1 A8 tay 00C0E9 1 B9 F6 C0 lda COMLSB,y ; set up pointer to command routine 00C0EC 1 85 0A sta temp_1 00C0EE 1 B9 10 C1 lda COMMSB,y 00C0F1 1 85 0B sta temp_2 00C0F3 1 6C 0A 00 err_F7: jmp (temp_1) ; and jump to it 00C0F6 1 00C0F6 1 ; Command Table 00C0F6 1 2A COMLSB: .byte ADDAFT, >ADDBEF, >CLEAR, >DELETE, >EDIT, >FNDSTR, >LSTBEF, >POKE 00C114 1 C1 C1 C3 C2 00C118 1 C2 C7 C3 C4 .byte >INSERT, >PASS_2, >RD_OBJ, >LIST, >MOVE, >RENUMB, >LSTAFT, >PRINT 00C11C 1 C3 C1 C4 C4 00C120 1 C2 C3 C2 C5 .byte >PEEK, >RD_SRC, >SAVSRC, >TYPSYM, >UPADDR, >VIEW, >WHERE, >XECUTE 00C124 1 C3 C3 C2 C3 00C128 1 C4 C3 .byte >ERROR0, >DIS 00C12A 1 00C12A 1 ; Command A 'Add text to buffer/after line' 00C12A 1 A5 0C ADDAFT: lda p1_lsb ; parameter specified ? 00C12C 1 05 0F ora p1_msb 00C12E 1 D0 29 bne adspec 00C130 1 20 60 C5 jsr FNDEND ; no - find end of text area 00C133 1 38 adtend: sec ; and insert from there 00C134 1 A5 08 lda txtptr ; move to start of last line 00C136 1 E9 03 sbc #$03 00C138 1 85 08 sta txtptr 00C13A 1 B0 02 bcs ndecpt 00C13C 1 C6 09 dec txtptr+1 00C13E 1 A9 0D ndecpt: lda #CR 00C140 1 A0 00 ldy #$00 00C142 1 91 08 sta (txtptr),y 00C144 1 20 52 C5 nxtlin: jsr INLINE ; output linenumber and input line of text 00C147 1 20 ED C4 jsr WR_LNO ; store new linenumber 00C14A 1 20 40 C5 jsr WR_BUF ; and line of text 00C14D 1 C9 04 cmp #EOT ; control D, EOT ? 00C14F 1 F0 05 beq endadd 00C151 1 20 05 C5 jsr ADDTEN ; increment linenumber by decimal 10 00C154 1 90 EE bcc nxtlin ; branch always to next line 00C156 1 4C F4 C4 endadd: jmp WR_CHR ; set EOT and return 00C159 1 20 15 C5 adspec: jsr FNDLIN ; add after specified line 00C15C 1 20 CC C5 jsr RD_CHR ; find line 00C15F 1 20 CC C5 jsr RD_CHR 00C162 1 20 CC C5 fnlend: jsr RD_CHR 00C165 1 C9 04 cmp #EOT ; end of text, EOT found ? 00C167 1 F0 CA beq adtend ; yes - add to end of text area 00C169 1 C9 0D cmp #CR 00C16B 1 D0 F5 bne fnlend ; from end of line 00C16D 1 20 73 C1 jsr AD10P1 ; add 10 to linenumber and use as parameter 00C170 1 4C 8E C1 jmp inslns ; insert line 00C173 1 00C173 1 ; Add Decimal 10 To Line number And Put In P1 00C173 1 F8 AD10P1: sed ; set decimal mode 00C174 1 18 clc 00C175 1 A5 06 lda lineno 00C177 1 69 10 adc #$10 ; do add 00C179 1 85 0C sta p1_lsb 00C17B 1 D8 cld ; set binary mode 00C17C 1 60 addrtn: rts 00C17D 1 00C17D 1 ; Command B ' Add text before line' 00C17D 1 20 15 C5 ADDBEF: jsr FNDLIN ; find start of line 00C180 1 F8 sed 00C181 1 A5 06 lda lineno ; go back one line (i.e. 10) 00C183 1 38 sec 00C184 1 E9 10 sbc #$10 00C186 1 85 06 sta lineno ; and set linenumber of first new line 00C188 1 A5 07 lda lineno+1 00C18A 1 E9 00 err_8d: sbc #$00 00C18C 1 85 07 sta lineno+1 00C18E 1 A9 01 inslns: lda #$01 00C190 1 20 07 C5 jsr ADD_A ; increment linenumber by 1 00C193 1 A5 06 lda lineno ; check for overflow 00C195 1 C5 0C cmp p1_lsb 00C197 1 F0 F2 beq err_8d+1 ; Error 8D 'Insertion overflow' 00C199 1 20 52 C5 newlin: jsr INLINE ; read in new line of text 00C19C 1 AD 00 01 lda buffer 00C19F 1 C9 04 cmp #$04 ; check for control D, EOT 00C1A1 1 F0 D9 beq addrtn ; if so return 00C1A3 1 A5 06 lda lineno ; save linenumber 00C1A5 1 48 pha 00C1A6 1 A5 07 lda lineno+1 00C1A8 1 48 pha 00C1A9 1 20 82 C5 jsr MOVEUP ; move text up to make room for new line 00C1AC 1 68 pla 00C1AD 1 85 07 sta $07 ; retrieve linenumber 00C1AF 1 68 pla 00C1B0 1 85 06 sta lineno 00C1B2 1 20 ED C4 jsr WR_LNO ; write into text area 00C1B5 1 20 40 C5 jsr WR_BUF ; and write new line of text 00C1B8 1 4C 8E C1 jmp inslns ; INSERT lines 00C1BB 1 00C1BB 1 ; Command N 'Number text in increments of 10' 00C1BB 1 20 BC C4 RENUMB: jsr RSTEXT ; read character from text area 00C1BE 1 20 CC C5 nxtren: jsr RD_CHR 00C1C1 1 30 7F bmi renrtn ; return if end of text 00C1C3 1 C9 04 cmp #EOT 00C1C5 1 F0 7B beq renrtn 00C1C7 1 C9 0D cmp #CR ; look for end of line, CR 00C1C9 1 D0 F3 bne nxtren 00C1CB 1 20 05 C5 jsr ADDTEN ; add 10 to linenumber 00C1CE 1 20 ED C4 jsr WR_LNO ; and write over old linenumber 00C1D1 1 4C BE C1 jmp nxtren ; RENUMBer next line 00C1D4 1 00C1D4 1 ; Command E 'Edit line' 00C1D4 1 A5 0C EDIT: lda p1_lsb 00C1D6 1 05 0F ora p1_msb 00C1D8 1 D0 0C bne edspec ; was linenumber specified ? 00C1DA 1 A5 06 lda lineno ; no - use current line 00C1DC 1 85 0C sta p1_lsb 00C1DE 1 85 0D sta p2_lsb 00C1E0 1 A5 07 lda lineno+1 00C1E2 1 85 0F sta p1_msb 00C1E4 1 85 10 sta p2_msb 00C1E6 1 20 24 C4 edspec: jsr LIST ; list required line 00C1E9 1 20 63 C4 jsr DELETE ; delete it 00C1EC 1 20 73 C1 jsr AD10P1 ; P1=linenumber+10 00C1EF 1 4C 99 C1 jmp newlin ; and read in new line(s) 00C1F2 1 00C1F2 1 ; Command F 'Find string' 00C1F2 1 20 15 C5 FNDSTR: jsr FNDLIN ; move to line to start search from 00C1F5 1 20 CC C5 fromln: jsr RD_CHR ; read linenumber 00C1F8 1 85 07 sta lineno+1 ; and save 00C1FA 1 20 CC C5 jsr RD_CHR 00C1FD 1 85 06 sta lineno 00C1FF 1 A5 08 lda txtptr 00C201 1 85 0C sta p1_lsb 00C203 1 A5 09 lda txtptr+1 00C205 1 85 0D sta p2_lsb 00C207 1 A2 FF ldx #$FF 00C209 1 E8 search: inx 00C20A 1 BD 02 01 lda buffer+2,x ; read character of search string 00C20D 1 CD 01 01 cmp buffer+1 ; compare with delimiter 00C210 1 F0 15 beq found 00C212 1 20 CC C5 srcont: jsr RD_CHR ; read character from text area 00C215 1 30 0F bmi fndrtn ; end of text, EOT ? 00C217 1 DD 02 01 cmp buffer+2,x ; compare with string 00C21A 1 F0 ED beq search ; equal ? - compare whole string 00C21C 1 A2 00 ldx #$00 ; no - start from beginning of string again 00C21E 1 C9 0D cmp #CR ; end of line, CR ? 00C220 1 F0 D3 beq fromln ; move to search from that line 00C222 1 C9 04 cmp #EOT ; end of text ? 00C224 1 D0 EC bne srcont ; no - continue searching 00C226 1 60 fndrtn: rts ; return - string not found 00C227 1 A5 0C found: lda p1_lsb ; point parameter at line 00C229 1 85 08 sta txtptr 00C22B 1 A5 0D lda p2_lsb 00C22D 1 85 09 sta txtptr+1 ; and output line containing string 00C22F 1 00C22F 1 ; Output Line Of Text 00C22F 1 20 97 CE OUTLIN: jsr OUTLNO ; output linenumber:space 00C232 1 A9 3A lda #':' 00C234 1 20 BD CE jsr OUTCHR 00C237 1 20 BB CE jsr OUTSPC 00C23A 1 20 AF C5 PR_LIN: jsr RD_BUF ; read buffer of text 00C23D 1 48 pha 00C23E 1 20 18 CF jsr BUFOUT ; and output buffer 00C241 1 68 pla 00C242 1 60 renrtn: rts 00C243 1 00C243 1 ; Command H 'Set address to data' 00C243 1 A5 10 POKE: lda p2_msb ; set-up pointer from parameters 00C245 1 85 0E sta p3_lsb 00C247 1 A0 00 ldy #$00 00C249 1 A5 0C lda p1_lsb 00C24B 1 91 0D sta (p2_lsb),y ; and POKE 00C24D 1 60 rts 00C24E 1 00C24E 1 ; Command W 'Where is line' 00C24E 1 20 15 C5 WHERE: jsr FNDLIN ; find specified line 00C251 1 A5 09 lda txtptr+1 00C253 1 A6 08 ldx txtptr 00C255 1 20 B8 CE jsr OUTAX_ ; output line address 00C258 1 4C 27 C4 jmp dolist ; and LIST line 00C25B 1 00C25B 1 ; Command Q 'Contents of location' 00C25B 1 A5 0F PEEK: lda p1_msb ; set-up pointer from parameters 00C25D 1 85 0D sta p2_lsb 00C25F 1 A0 00 ldy #$00 00C261 1 B1 0C lda (p1_lsb),y ; and PEEK 00C263 1 4C 9F CE jmp OUTBYT ; output byte and return 00C266 1 00C266 1 ; Command S 'Save source file' 00C266 1 A6 12 SAVSRC: ldx pcount 00C268 1 E0 02 cpx #$02 00C26A 1 F0 18 beq areasp ; was an area specified ? 00C26C 1 20 60 C5 jsr FNDEND ; no - save whole of text area 00C26F 1 A9 00 lda #$00 ; find end of text area 00C271 1 85 0D sta p2_lsb ; point P2 at start of text area 00C273 1 A5 01 lda source 00C275 1 85 10 sta p2_msb 00C277 1 A5 08 lda txtptr ; point P3 at end of text area+1 00C279 1 18 clc 00C27A 1 69 01 adc #$01 00C27C 1 85 0E sta p3_lsb 00C27E 1 A5 09 lda txtptr+1 00C280 1 69 00 adc #$00 00C282 1 85 11 sta p3_msb 00C284 1 A5 0D areasp: lda p2_lsb ; set-up I/O table for save 00C286 1 85 36 sta table+6 ; start address 00C288 1 A5 0E lda p3_lsb ; end address 00C28A 1 85 38 sta table+8 00C28C 1 A5 10 lda p2_msb 00C28E 1 85 37 sta table+7 00C290 1 A5 11 lda p3_msb 00C292 1 85 39 sta table+9 00C294 1 A5 10 lda p2_msb 00C296 1 A6 0D ldx p2_lsb 00C298 1 20 B8 CE jsr OUTAX_ ; output start address 00C29B 1 A5 11 lda p3_msb 00C29D 1 A6 0E ldx p3_lsb 00C29F 1 20 B8 CE jsr OUTAX_ ; output end address 00C2A2 1 C6 2F dec fileid ; decrement file ID 00C2A4 1 A5 0C lda p1_lsb ; was a file ID specified ? 00C2A6 1 F0 02 beq no_id 00C2A8 1 85 2F sta fileid ; yes - set it 00C2AA 1 A5 36 no_id: lda table+6 ; set up reload address 00C2AC 1 85 32 sta table+2 00C2AE 1 A5 37 lda table+7 00C2B0 1 85 33 sta table+3 00C2B2 1 4C AD CF jmp SAVE ; and do save 00C2B5 1 00C2B5 1 ; Command I 'Insert line(s) before line' 00C2B5 1 A5 0C INSERT: lda p1_lsb ; save parameter, P1 00C2B7 1 85 0A sta temp_1 00C2B9 1 A5 0F lda p1_msb 00C2BB 1 85 0B sta temp_2 00C2BD 1 20 15 C5 jsr FNDLIN ; find line to insert before, P1 00C2C0 1 D0 59 bne err_1d+1 ; end of text ? Error 1D 'Illegal linenumber' 00C2C2 1 A5 0D lda p2_lsb ; move linenumber of block to move into P1 00C2C4 1 85 0C sta p1_lsb 00C2C6 1 A5 10 lda p2_msb 00C2C8 1 85 0F sta p1_msb 00C2CA 1 A5 08 nxtins: lda txtptr ; save address to insert at 00C2CC 1 85 13 sta ptr 00C2CE 1 A5 09 lda txtptr+1 00C2D0 1 85 14 sta ptr+1 00C2D2 1 20 15 C5 jsr FNDLIN ; and find line(s) to insert 00C2D5 1 D0 44 bne err_1d+1 ; end of text ? - error 1D 00C2D7 1 A5 06 lda lineno 00C2D9 1 C5 0C cmp p1_lsb 00C2DB 1 D0 2D bne notlin 00C2DD 1 A5 07 lda lineno+1 00C2DF 1 C5 0F cmp p1_msb 00C2E1 1 D0 27 bne notlin 00C2E3 1 18 clc ; add 2 to pointer to point at text 00C2E4 1 A5 08 lda txtptr 00C2E6 1 69 02 adc #$02 00C2E8 1 85 08 sta txtptr 00C2EA 1 90 02 bcc nincsp 00C2EC 1 E6 09 inc txtptr+1 00C2EE 1 20 AF C5 nincsp: jsr RD_BUF ; read text from that line 00C2F1 1 8A txa 00C2F2 1 A8 tay 00C2F3 1 88 dey 00C2F4 1 A5 13 lda ptr ; set-up pointer to insert address to 00C2F6 1 85 08 sta txtptr ; move text above it up ready for insert 00C2F8 1 A5 14 lda ptr+1 00C2FA 1 85 09 sta txtptr+1 00C2FC 1 20 82 C5 jsr MOVEUP ; move text up a line 00C2FF 1 A9 00 lda #$00 ; set moved linenumber to 0 00C301 1 20 F4 C4 jsr WR_CHR ; write linenumber 00C304 1 20 F4 C4 jsr WR_CHR 00C307 1 20 40 C5 jsr WR_BUF ; and buffer into text area 00C30A 1 A6 12 notlin: ldx pcount 00C30C 1 E0 02 cpx #$02 ; was a third parameter specified ? 00C30E 1 D0 19 bne endins ; no - insert almost finished 00C310 1 A9 01 lda #$01 ; add 1 to parameter 1 i.e. move 00C312 1 18 clc ; to next line to insert 00C313 1 F8 sed 00C314 1 65 0C adc p1_lsb 00C316 1 85 0C sta p1_lsb 00C318 1 A5 0F lda p1_msb 00C31A 1 69 00 err_1d: adc #$00 00C31C 1 85 0F sta p1_msb 00C31E 1 D8 cld 00C31F 1 A5 0E lda p3_lsb ; compare with P3 to test for end of INSERT 00C321 1 C5 0C cmp p1_lsb 00C323 1 A5 11 lda p3_msb 00C325 1 E5 0F sbc p1_msb 00C327 1 B0 18 bcs notend 00C329 1 A2 FB endins: ldx #$FB 00C32B 1 B5 12 mvpara: lda pcount,x ; move P2,P3 down to 00C32D 1 95 11 sta p3_msb,x ; P1, P2 ready for delete 00C32F 1 E8 inx 00C330 1 D0 F9 bne mvpara 00C332 1 C6 12 dec pcount 00C334 1 D0 08 bne delold ; were 3 parameters originally specified ? 00C336 1 A5 0C lda p1_lsb ; no - set to delete one line only 00C338 1 85 0D sta p2_lsb 00C33A 1 A5 0F lda p1_msb 00C33C 1 85 10 sta p2_msb 00C33E 1 4C 63 C4 delold: jmp DELETE ; delete original line(s) and return 00C341 1 A5 0C notend: lda p1_lsb ; save P1 - next line to insert 00C343 1 48 pha 00C344 1 A5 0F lda p1_msb 00C346 1 48 pha 00C347 1 A5 0A lda temp_1 ; retrieve original P1 - line 00C349 1 85 0C sta p1_lsb ; to insert before 00C34B 1 A5 0B lda temp_2 00C34D 1 85 0F sta p1_msb 00C34F 1 20 15 C5 jsr FNDLIN ; find it again as it has moved up 00C352 1 68 pla 00C353 1 85 0F sta p1_msb ; and retrieve P1 - line(s) to insert next 00C355 1 68 pla 00C356 1 85 0C sta p1_lsb 00C358 1 4C CA C2 jmp nxtins ; continue inserting 00C35B 1 00C35B 1 ; Command X 'eXECUTE' 00C35B 1 A5 0F XECUTE: lda p1_msb 00C35D 1 85 0D sta p2_lsb 00C35F 1 05 0C ora p1_lsb ; was an address specified ? 00C361 1 D0 03 bne go 00C363 1 4C D2 C6 jmp PASS_1 ; no - enter Assembler at Pass 1 00C366 1 6C 0C 00 go: jmp (p1_lsb) ; go to specified address 00C369 1 00C369 1 ; Command K 'Read in object file(s)' 00C369 1 A5 0C RD_OBJ: lda p1_lsb 00C36B 1 85 2F sta fileid ; set file ID 00C36D 1 20 96 CF rdnxob: jsr SETUSE ; set qualifier X 00C370 1 20 80 C3 jsr LOADID ; load file 00C373 1 B0 F8 bcs rdnxob ; load another object file ? 00C375 1 60 rts ; no - return 00C376 1 00C376 1 ; Command R 'Read source file' 00C376 1 A5 0C RD_SRC: lda p1_lsb 00C378 1 85 2F sta fileid ; set file ID 00C37A 1 20 80 C3 rdnxsr: jsr LOADID ; load file 00C37D 1 B0 FB bcs rdnxsr ; load another source file ? 00C37F 1 60 rts ; no - return 00C380 1 00C380 1 ; Load File 00C380 1 20 A4 CF LOADID: jsr LOAD 00C383 1 E6 2F inc fileid ; increment file ID 00C385 1 A5 0D lda p2_lsb ; compare with second ID specified 00C387 1 C5 2F cmp fileid 00C389 1 60 rts 00C38A 1 00C38A 1 ; Command U 'Upper address used' 00C38A 1 20 60 C5 UPADDR: jsr FNDEND ; find end of text area 00C38D 1 A5 09 lda txtptr+1 00C38F 1 A6 08 ldx txtptr 00C391 1 20 B8 CE jsr OUTAX_ ; output address of last line 00C394 1 4C 97 CE jmp OUTLNO ; and linenumber 00C397 1 00C397 1 ; Command Z 'Disassemble' 00C397 1 A6 12 DIS: ldx pcount ; where both parameters specified ? 00C399 1 D0 06 bne tparam 00C39B 1 A5 0C lda p1_lsb 00C39D 1 05 0F ora p1_msb 00C39F 1 F0 08 beq nparam ; was one parameter specified ? 00C3A1 1 A5 0C tparam: lda p1_lsb ; set up parameter low address 00C3A3 1 85 19 sta objadr ; to disassemble from 00C3A5 1 A5 0F lda p1_msb 00C3A7 1 85 1A sta objadr+1 00C3A9 1 A9 E7 nparam: lda #$E7 ; set-up line counter 00C3AB 1 85 0A sta temp_1 00C3AD 1 20 42 CD dodis: jsr DISASM ; Disassemble 1 line 00C3B0 1 A6 12 ldx pcount ; test parameter counter 00C3B2 1 D0 0C bne par_2 ; if two specified do not page 00C3B4 1 E6 0A inc temp_1 ; increment line counter 00C3B6 1 30 F5 bmi dodis ; if still negative continue 00C3B8 1 20 D4 CE jsr RD_KEY ; otherwise 25 lines output 00C3BB 1 C9 0D cmp #CR ; wait for key-press 00C3BD 1 D0 EA bne nparam ; and then continue 00C3BF 1 60 rts ; return if CR 00C3C0 1 A5 19 par_2: lda objadr ; compare address with second parameter 00C3C2 1 C5 0D cmp p2_lsb 00C3C4 1 A5 1A lda objadr+1 00C3C6 1 E5 10 sbc p2_msb 00C3C8 1 90 E3 bcc dodis ; continue ? 00C3CA 1 60 rts 00C3CB 1 00C3CB 1 ; Command V 'View 256 bytes of memory' 00C3CB 1 A6 0C VIEW: ldx p1_lsb ; set-up data pointer 00C3CD 1 A0 00 ldy #$00 00C3CF 1 86 0E stx p3_lsb 00C3D1 1 20 B4 CE nxvwln: jsr CRLF ; output CRLF 00C3D4 1 A6 0D ldx p2_lsb ; was number of bytes per line specified ? 00C3D6 1 D0 02 bne nxbyte ; branch if specified 00C3D8 1 A2 0D ldx #CR ; otherwise use default 13 00C3DA 1 B1 0E nxbyte: lda (p3_lsb),y ; read byte 00C3DC 1 20 9F CE jsr OUTBYT ; output byte, space 00C3DF 1 20 BB CE jsr OUTSPC 00C3E2 1 C8 iny ; increment index 00C3E3 1 F0 17 beq vewrtn ; return after 256 bytes 00C3E5 1 CA dex ; decrement byte counter 00C3E6 1 D0 F2 bne nxbyte ; continue on same line 00C3E8 1 F0 E7 beq nxvwln ; next line 00C3EA 1 00C3EA 1 ; Command M 'Move memory around' 00C3EA 1 A4 0E MOVE: ldy p3_lsb ; set up pointers to old and new addresses 00C3EC 1 A6 0D ldx p2_lsb 00C3EE 1 A5 0F lda p1_msb 00C3F0 1 86 0F stx p1_msb 00C3F2 1 85 0D sta p2_lsb 00C3F4 1 88 domove: dey 00C3F5 1 B1 0C lda (p1_lsb),y ; read byte from old address 00C3F7 1 91 0F sta (p1_msb),y ; and move to new address 00C3F9 1 98 tya 00C3FA 1 D0 F8 bne domove ; do all 256 bytes 00C3FC 1 60 vewrtn: rts 00C3FD 1 00C3FD 1 ; Command G 'LIST preceding 21 lines' 00C3FD 1 A5 06 LSTBEF: lda lineno ; go back 21 lines by subtracting 00C3FF 1 38 sec ; decimal 240 from present linenumber 00C400 1 F8 sed 00C401 1 E9 20 sbc #$20 00C403 1 85 06 sta lineno 00C405 1 A5 07 lda lineno+1 00C407 1 E9 04 sbc #$04 00C409 1 85 07 sta lineno+1 00C40B 1 B0 06 bcs LSTAFT ; were there less than 21 previous lines ? 00C40D 1 A9 00 lda #$00 ; yes - set linenumber to start 00 00C40F 1 85 07 sta lineno+1 00C411 1 85 06 sta lineno 00C413 1 00C413 1 ; Command O 'List next 21 lines' 00C413 1 A5 07 LSTAFT: lda lineno+1 ; set parameter 1 to present linenumber 00C415 1 85 0F sta p1_msb 00C417 1 18 clc 00C418 1 F8 sed 00C419 1 69 02 adc #$02 00C41B 1 85 10 sta p2_msb ; set parameter 2 to present linenumber 00C41D 1 A5 06 lda lineno ; plus 200 i.e. 21 lines ahead 00C41F 1 85 0D sta p2_lsb 00C421 1 85 0C sta p1_lsb 00C423 1 D8 cld 00C424 1 00C424 1 ; Command L 'LIST' 00C424 1 20 40 C4 LIST: jsr LSTINI ; read linenumber and compare with P2 00C427 1 20 50 C4 dolist: jsr RDLINE 00C42A 1 90 05 bcc lisrtn ; finished Listing ? 00C42C 1 20 2F C2 jsr OUTLIN ; output linenumber and text 00C42F 1 10 F6 bpl dolist ; and continue Listing 00C431 1 60 lisrtn: rts 00C432 1 00C432 1 ; Command P 'PRINT' 00C432 1 20 40 C4 PRINT: jsr LSTINI ; read linenumber and compare with P2 00C435 1 20 50 C4 doprin: jsr RDLINE 00C438 1 90 05 bcc pr_rtn ; finished printing ? 00C43A 1 20 3A C2 jsr PR_LIN ; output line of text 00C43D 1 10 F6 bpl doprin ; and continue printing 00C43F 1 60 pr_rtn: rts 00C440 1 00C440 1 ; find line specified by P1 00C440 1 20 15 C5 LSTINI: jsr FNDLIN 00C443 1 A5 10 lda p2_msb 00C445 1 05 0D ora p2_lsb 00C447 1 D0 06 bne nlstp2 ; was a second parameter specified ? 00C449 1 A9 99 lda #$99 ; no - set to maximum linenumber 9999 00C44B 1 85 10 sta p2_msb 00C44D 1 85 0D sta p2_lsb 00C44F 1 60 nlstp2: rts 00C450 1 00C450 1 ; Read and Compare Line Numbers 00C450 1 20 CC C5 RDLINE: jsr RD_CHR ; read linenumber 00C453 1 85 07 sta lineno+1 00C455 1 20 CC C5 jsr RD_CHR 00C458 1 85 06 sta lineno 00C45A 1 A5 0D lda p2_lsb ; and compare with parameter P2 00C45C 1 C5 06 cmp lineno 00C45E 1 A5 10 lda p2_msb 00C460 1 E5 07 sbc lineno+1 00C462 1 60 rts 00C463 1 00C463 1 ; Command D 'Delete line(s)' 00C463 1 20 15 C5 DELETE: jsr FNDLIN ; find line 00C466 1 10 46 bpl deltst ; does it exist ? 00C468 1 60 rts ; no - return 00C469 1 A0 02 do_del: ldy #$02 00C46B 1 C8 fnenpl: iny 00C46C 1 B1 08 lda (txtptr),y ; find end of present line, CR 00C46E 1 C9 0D cmp #CR 00C470 1 F0 05 beq linend 00C472 1 C9 04 cmp #EOT ; if end of text - return 00C474 1 D0 F5 bne fnenpl 00C476 1 60 rts 00C477 1 84 15 linend: sty ptindx ; save index to end of line 00C479 1 A5 08 lda txtptr ; set up second pointer to start of line 00C47B 1 85 13 sta ptr 00C47D 1 A5 09 lda txtptr+1 00C47F 1 85 14 sta ptr+1 00C481 1 A4 15 movdwn: ldy ptindx ; retrieve index to next line 00C483 1 B1 13 lda (ptr),y ; read next line 00C485 1 A0 00 ldy #$00 ; reset index 00C487 1 91 13 sta (ptr),y ; move down on top of old text 00C489 1 E6 13 inc ptr ; increment pointer 00C48B 1 D0 02 bne nincpa 00C48D 1 E6 14 inc ptr+1 00C48F 1 C9 0D nincpa: cmp #CR ; end of line ? 00C491 1 D0 EE bne movdwn ; no keep moving text down 00C493 1 A2 03 nxcrln: ldx #$03 ; move CR and linenumber of next line 00C495 1 A4 15 mvcrln: ldy ptindx ; retrieve index to next line 00C497 1 B1 13 lda (ptr),y ; read next line 00C499 1 A0 00 ldy #$00 ; reset index 00C49B 1 91 13 sta (ptr),y ; move down on top of old text 00C49D 1 E6 13 inc ptr ; increment pointer 00C49F 1 D0 02 bne nincpb 00C4A1 1 E6 14 inc ptr+1 00C4A3 1 CA nincpb: dex 00C4A4 1 D0 EF bne mvcrln ; move all 3 bytes of CR and linenumber 00C4A6 1 C9 0D cmp #CR ; is next line blank ? 00C4A8 1 F0 E9 beq nxcrln ; yes - move next CR and linenumber 00C4AA 1 C9 04 cmp #EOT ; end of text ? 00C4AC 1 D0 D3 bne movdwn ; no - keep moving text down 00C4AE 1 A0 02 deltst: ldy #$02 ; check for end of delete 00C4B0 1 A5 0D lda p2_lsb ; compare present linenumber with parameter 00C4B2 1 D1 08 cmp (txtptr),y 00C4B4 1 88 dey 00C4B5 1 A5 10 lda p2_msb 00C4B7 1 F1 08 sbc (txtptr),y 00C4B9 1 B0 AE bcs do_del ; finished deleting ? 00C4BB 1 60 rts ; yes - return 00C4BC 1 00C4BC 1 ; Set Text Pointer And Line Number To Start 00C4BC 1 A9 FF RSTEXT: lda #$FF 00C4BE 1 85 08 sta txtptr 00C4C0 1 A5 00 lda sourcm ; read default start text page minus one 00C4C2 1 85 09 sta txtptr+1 00C4C4 1 A9 00 lda #$00 00C4C6 1 85 06 sta lineno ; set linenumber=0 00C4C8 1 85 07 sta lineno+1 00C4CA 1 60 rts 00C4CB 1 00C4CB 1 ; Editor Error Handler, Command Y 00C4CB 1 68 ERROR0: pla 00C4CC 1 68 pla ; use address as error number 00C4CD 1 20 D3 C4 jsr OUTERR ; output error message 00C4D0 1 4C 39 C0 jmp nxtcom ; and return to Editor command mode 00C4D3 1 00C4D3 1 48 OUTERR: pha ; Output Error Message 00C4D4 1 20 B4 CE jsr CRLF ; save error number, output CRLF 00C4D7 1 A0 06 ldy #lineno 00C4D9 1 B9 E6 C4 nxtchr: lda errtxt,y ; output error text 00C4DC 1 20 BD CE jsr OUTCHR 00C4DF 1 88 dey 00C4E0 1 10 F7 bpl nxtchr 00C4E2 1 68 pla 00C4E3 1 4C 9F CE jmp OUTBYT ; followed by error number 00C4E6 1 00C4E6 1 20 72 6F 72 errtxt: .byte " rorrE " ; Error Message Text 00C4EA 1 72 45 20 00C4ED 1 00C4ED 1 ; Write Linenumber At Top Of Text Area 00C4ED 1 A5 07 WR_LNO: lda lineno+1 00C4EF 1 20 F4 C4 jsr WR_CHR 00C4F2 1 A5 06 lda lineno 00C4F4 1 ; Write A at Top of Text Area 00C4F4 1 E6 08 WR_CHR: inc txtptr 00C4F6 1 D0 02 bne tsttop ; increment text pointer 00C4F8 1 E6 09 inc txtptr+1 00C4FA 1 A4 02 tsttop: ldy sourcf 00C4FC 1 C4 09 cpy txtptr+1 00C4FE 1 F0 01 beq err_3+1 ; Error 3 'Insufficient memory to insert line' 00C500 1 A0 00 err_3: ldy #$00 00C502 1 91 08 sta (txtptr),y 00C504 1 60 rts 00C505 1 00C505 1 ; Add 10 To Linenumber 00C505 1 A9 10 ADDTEN: lda #$10 00C507 1 ; Add A To Linenumber 00C507 1 18 ADD_A: clc 00C508 1 F8 sed ; set decimal mode 00C509 1 65 06 adc lineno ; add A to linenumber 00C50B 1 85 06 sta lineno 00C50D 1 A5 07 lda lineno+1 00C50F 1 69 00 adc #$00 00C511 1 85 07 sta lineno+1 00C513 1 D8 cld ; set binary mode 00C514 1 60 rts 00C515 1 00C515 1 ; Search Text Area for Required Line 00C515 1 20 BC C4 FNDLIN: jsr RSTEXT ; read character from text area 00C518 1 20 CC C5 fndeol: jsr RD_CHR 00C51B 1 30 22 bmi fndeot ; end of text ? - return 00C51D 1 C9 0D cmp #CR 00C51F 1 D0 F7 bne fndeol ; search for end of line, CR 00C521 1 20 CC C5 jsr RD_CHR ; read linenumber 00C524 1 85 07 sta lineno+1 ; and save it 00C526 1 20 CC C5 jsr RD_CHR 00C529 1 85 06 sta lineno 00C52B 1 C5 0C cmp p1_lsb ; compare with required linenumber 00C52D 1 A5 07 lda lineno+1 00C52F 1 E5 0F sbc p1_msb 00C531 1 90 E5 bcc fndeol ; found line ? 00C533 1 A5 08 lda txtptr ; yes - move text pointer to start of line 00C535 1 E9 02 sbc #$02 00C537 1 85 08 sta txtptr 00C539 1 B0 02 bcs ndectp 00C53B 1 C6 09 dec txtptr+1 00C53D 1 A9 00 ndectp: lda #$00 00C53F 1 60 fndeot: rts ; and return 00C540 1 00C540 1 ; Write Buffer To text Area 00C540 1 A2 00 WR_BUF: ldx #$00 00C542 1 BD 00 01 nxtrdb: lda buffer,x 00C545 1 C9 04 cmp #EOT ; return if end of text found 00C547 1 F0 08 beq wrbrtn 00C549 1 20 F4 C4 jsr WR_CHR ; write character into text area 00C54C 1 E8 inx 00C54D 1 C9 0D cmp #CR ; return if CR found 00C54F 1 D0 F1 bne nxtrdb ; otherwise continue 00C551 1 60 wrbrtn: rts 00C552 1 00C552 1 ; Input Text Line 00C552 1 20 97 CE INLINE: jsr OUTLNO ; output linenumber:space 00C555 1 A9 3A lda #':' 00C557 1 20 BD CE jsr OUTCHR 00C55A 1 20 BB CE jsr OUTSPC 00C55D 1 4C DA CE jmp BUFFIN ; and read in line of text 00C560 1 00C560 1 ; Search For End Of Text Area 00C560 1 20 BC C4 FNDEND: jsr RSTEXT ; start at beginning 00C563 1 A8 tay 00C564 1 E6 08 fnd_cr: inc txtptr 00C566 1 D0 02 bne nincpt 00C568 1 E6 09 inc txtptr+1 00C56A 1 B1 08 nincpt: lda (txtptr),y 00C56C 1 C9 0D nxfncr: cmp #CR ; find CR 00C56E 1 D0 F4 bne fnd_cr 00C570 1 20 CC C5 jsr RD_CHR ; read linenumber 00C573 1 85 07 sta lineno+1 00C575 1 20 CC C5 jsr RD_CHR 00C578 1 85 06 sta lineno 00C57A 1 20 CC C5 jsr RD_CHR 00C57D 1 C9 04 cmp #EOT ; end of text ? 00C57F 1 D0 EB bne nxfncr ; no - round again 00C581 1 60 rts ; yes - return 00C582 1 00C582 1 ; Move Text Area Up A Line 00C582 1 C8 MOVEUP: iny ; add 3 to index for CR and linenumber 00C583 1 C8 iny 00C584 1 C8 iny 00C585 1 84 15 sty ptindx ; save index 00C587 1 A5 08 lda txtptr ; save present text pointer 00C589 1 85 13 sta ptr 00C58B 1 A5 09 lda txtptr+1 00C58D 1 85 14 sta ptr+1 00C58F 1 20 60 C5 jsr FNDEND ; find end of text area 00C592 1 A6 08 ldx txtptr 00C594 1 A0 00 domvup: ldy #$00 ; reset index 00C596 1 B1 08 lda (txtptr),y ; read old text 00C598 1 A4 15 ldy ptindx ; retrieve index 00C59A 1 91 08 sta (txtptr),y ; move up on top of old text 00C59C 1 8A txa 00C59D 1 D0 02 bne no_dec ; decrement pointer 00C59F 1 C6 09 dec txtptr+1 00C5A1 1 CA no_dec: dex 00C5A2 1 86 08 stx txtptr ; compare with end address 00C5A4 1 E4 13 cpx ptr 00C5A6 1 D0 EC bne domvup ; finished ? 00C5A8 1 A5 09 lda txtptr+1 00C5AA 1 C5 14 cmp ptr+1 00C5AC 1 D0 E6 bne domvup 00C5AE 1 60 rts 00C5AF 1 00C5AF 1 ; Read Line Of Text Into Buffer 00C5AF 1 A2 00 RD_BUF: ldx #$00 00C5B1 1 20 CC C5 rdnxch: jsr RD_CHR ; read character from text area 00C5B4 1 9D 00 01 sta buffer,x ; put in buffer 00C5B7 1 E8 inx ; increment buffer index 00C5B8 1 E0 50 cpx #$50 ; buffer full ? 00C5BA 1 10 08 bpl rdbend 00C5BC 1 C9 0D cmp #CR ; end of line, CR ? 00C5BE 1 F0 0B beq rdbrtn ; yes - return 00C5C0 1 C9 04 cmp #EOT ; end of text ? 00C5C2 1 D0 ED bne rdnxch ; no - read next character 00C5C4 1 A9 0D rdbend: lda #CR 00C5C6 1 9D 00 01 sta buffer,x ; set end of buffer, CR 00C5C9 1 A9 FF lda #$FF ; load $FF - buffer full or end of text 00C5CB 1 60 rdbrtn: rts ; return 00C5CC 1 00C5CC 1 ; Read Character From Text Area 00C5CC 1 E6 08 RD_CHR: inc txtptr ; increment text pointer 00C5CE 1 D0 02 bne nrdinc 00C5D0 1 E6 09 inc txtptr+1 00C5D2 1 A4 02 nrdinc: ldy sourcf 00C5D4 1 C4 09 cpy txtptr+1 ; end of text area ? 00C5D6 1 F0 05 beq rd_eot 00C5D8 1 A0 00 ldy #$00 00C5DA 1 B1 08 lda (txtptr),y ; read character 00C5DC 1 60 rts ; and return 00C5DD 1 A9 FF rd_eot: lda #$FF ; end of text area reached - load $FF 00C5DF 1 60 rts ; and return 00C5E0 1 00C5E0 1 ; Command T 00C5E0 1 A0 43 TYPSYM: ldy #symbol-text 00C5E2 1 20 78 C8 jsr OUTEXT ; output 'Symbol Table' 00C5E5 1 A5 03 lda zsymbol 00C5E7 1 A2 00 ldx #$00 00C5E9 1 20 B8 CE jsr OUTAX_ ; output symbol table start address 00C5EC 1 A5 18 lda symptr+1 00C5EE 1 A6 17 ldx symptr 00C5F0 1 20 9B CE jsr OUT_AX ; output symbol table end address 00C5F3 1 A6 0C ldx p1_lsb 00C5F5 1 E0 02 cpx #$02 00C5F7 1 F0 1D beq symrtn ; if option 2, finished - return 00C5F9 1 30 1C bmi sort ; if option 0,1 go to sort 00C5FB 1 A5 0D lda p2_lsb ; option 3 set symbol table end to P2 00C5FD 1 85 17 sta symptr 00C5FF 1 A5 10 lda p2_msb 00C601 1 85 18 sta symptr+1 00C603 1 A0 43 ldy #symbol-text; output new start and end addresses 00C605 1 20 78 C8 jsr OUTEXT ; output 'Symbol Table' 00C608 1 A5 03 lda zsymbol 00C60A 1 A2 00 ldx #$00 00C60C 1 20 B8 CE jsr OUTAX_ 00C60F 1 A5 18 lda symptr+1 00C611 1 A6 17 ldx symptr 00C613 1 20 9B CE jsr OUT_AX 00C616 1 60 symrtn: rts ; and return 00C617 1 20 C1 C6 sort: jsr SET_PT ; set-up symbol table pointer 00C61A 1 A6 0C nxtcmp: ldx p1_lsb ; bubble sort symbol table in either 00C61C 1 D0 11 bne numord ; alphabetic or numerical order as specified 00C61E 1 A0 00 ldy #$00 ; Alphabetic Sort 00C620 1 B1 1D alpcmp: lda (symptb),y ; do alphabetic compare of labels 00C622 1 D1 1B cmp (sympta),y 00C624 1 90 16 bcc swap 00C626 1 D0 25 bne noswap 00C628 1 C8 iny 00C629 1 C0 04 cpy #$04 ; compare all 4 bytes of compressed 00C62B 1 D0 F3 bne alpcmp ; 6 character label 00C62D 1 F0 1E beq noswap 00C62F 1 A0 04 numord: ldy #$04 ; Numerical Sort 00C631 1 B1 1D lda (symptb),y ; do numeric compare of label addresses 00C633 1 D1 1B cmp (sympta),y 00C635 1 C8 iny 00C636 1 B1 1D lda (symptb),y ; both bytes 00C638 1 F1 1B sbc (sympta),y 00C63A 1 B0 11 bcs noswap 00C63C 1 A0 05 swap: ldy #$05 ; swap if wrong order 00C63E 1 B1 1B swap_6: lda (sympta),y 00C640 1 AA tax 00C641 1 B1 1D lda (symptb),y 00C643 1 91 1B sta (sympta),y 00C645 1 8A txa 00C646 1 91 1D sta (symptb),y 00C648 1 88 dey 00C649 1 10 F3 bpl swap_6 ; swap all 6 bytes of label 00C64B 1 E6 1F inc swpcnt ; increment swap counter 00C64D 1 AD 21 0E noswap: lda port_a ; check for Escape from keyboard 00C650 1 C9 1B cmp #ESC 00C652 1 F0 C2 beq symrtn ; return if pressed 00C654 1 20 97 C8 jsr PTACMP ; increment symbol table pointer A 00C657 1 A2 02 ldx #$02 00C659 1 20 99 C8 jsr PT_CMP ; and pointer B 00C65C 1 90 BC bcc nxtcmp ; reached top ? - no keep going 00C65E 1 A6 1F ldx swpcnt 00C660 1 D0 B5 bne sort ; repeat until a pass is done with no swaps 00C662 1 20 C1 C6 jsr SET_PT ; reset symbol table pointer 00C665 1 E6 1F outtab: inc swpcnt ; output sorted table 00C667 1 30 0A bmi nocrlf ; end of line reached ? 00C669 1 20 B4 CE jsr CRLF ; yes - output CRLF 00C66C 1 A9 FF lda #$FF ; calculate FF - number of columns P2 00C66E 1 38 sec 00C66F 1 E5 0D sbc p2_lsb 00C671 1 85 1F sta swpcnt ; and use swpcnt as a counter 00C673 1 20 87 C6 nocrlf: jsr OUTLAB ; output compressed label 00C676 1 A0 04 ldy #$04 ; followed by address 00C678 1 B1 1B lda (sympta),y 00C67A 1 AA tax 00C67B 1 C8 iny 00C67C 1 B1 1B lda (sympta),y 00C67E 1 20 B8 CE jsr OUTAX_ 00C681 1 20 97 C8 jsr PTACMP ; increment symbol table pointer 00C684 1 90 DF bcc outtab ; output whole table 00C686 1 60 rts ; and return 00C687 1 00C687 1 ; Output Label At Symbol Pointer A 00C687 1 A0 00 OUTLAB: ldy #$00 00C689 1 B1 1B coplab: lda (sympta),y ; copy 4 bytes of label out 00C68B 1 99 3A 00 sta unclab,y 00C68E 1 C8 iny 00C68F 1 C0 04 cpy #$04 00C691 1 D0 F6 bne coplab 00C693 1 A0 06 ldy #$06 ; character counter 00C695 1 A2 06 ldx #$06 ; bit counter (characters 1 & 4 are 6 bit) 00C697 1 A9 00 nxunch: lda #$00 ; clear output 00C699 1 06 3D uncomp: asl unclab+3 ; shift label into A to uncompress 00C69B 1 26 3C rol unclab+2 00C69D 1 26 3B rol unclab+1 00C69F 1 26 3A rol unclab 00C6A1 1 2A rol a 00C6A2 1 29 1F and #$1F 00C6A4 1 CA dex 00C6A5 1 D0 F2 bne uncomp 00C6A7 1 18 clc 00C6A8 1 69 40 adc #$40 ; add offset to uncompressed label 00C6AA 1 C9 40 cmp #$40 ; to convert to ASCII 00C6AC 1 D0 02 bne notspc ; space ? 00C6AE 1 A9 20 lda #SPACE 00C6B0 1 20 BD CE notspc: jsr OUTCHR ; output character 00C6B3 1 A2 05 ldx #$05 ; reset bit counter to 5 bits 00C6B5 1 C0 04 cpy #$04 ; (characters 2,3,5 and 6) 00C6B7 1 D0 02 bne fbits ; start of next 3 bytes ? 00C6B9 1 A2 06 ldx #$06 ; reset bit counter to 6 bits 00C6BB 1 88 fbits: dey ; decrement character counter 00C6BC 1 D0 D9 bne nxunch ; uncompress all 6 characters 00C6BE 1 4C BB CE jmp OUTSPC ; output a space and return 00C6C1 1 00C6C1 1 ; Set Up Symbol Table Pointers 00C6C1 1 A9 00 SET_PT: lda #$00 00C6C3 1 85 1B sta sympta 00C6C5 1 85 1F sta swpcnt ; clear bubble sort swap counter 00C6C7 1 A9 06 lda #$06 00C6C9 1 85 1D sta symptb ; point pointer A at 1st label of table 00C6CB 1 A5 03 lda zsymbol 00C6CD 1 85 1C sta sympta+1 ; point pointer B at 2nd label of table 00C6CF 1 85 1E sta line 00C6D1 1 60 rts 00C6D2 1 00C6D2 1 ; Assembler Pass 1 00C6D2 1 A0 00 PASS_1: ldy #$00 ; point symbol table pointer at start 00C6D4 1 84 17 sty symptr 00C6D6 1 A5 03 lda zsymbol ; i.e. clear symbol table 00C6D8 1 85 18 sta symptr+1 00C6DA 1 20 78 C8 jsr OUTEXT ; output 'Pass 1' 00C6DD 1 A9 FF lda #$FF 00C6DF 1 85 22 sta zpass ; set pass 1 00C6E1 1 A0 52 pass: ldy #id-text ; Perform Assembler Pass Of Source 00C6E3 1 20 78 C8 id_err: jsr OUTEXT ; output 'ID' message 00C6E6 1 E6 0E inc p3_lsb ; have we passed all ID's specified ? 00C6E8 1 A5 11 lda p3_msb 00C6EA 1 C5 0E cmp p3_lsb 00C6EC 1 90 0A bcc inp_id ; yes - input next ID 00C6EE 1 A5 0E lda p3_lsb ; no - set next ID 00C6F0 1 85 2F sta fileid 00C6F2 1 20 9F CE jsr OUTBYT 00C6F5 1 4C 29 C7 jmp tst_id ; and continue 00C6F8 1 20 DA CE inp_id: jsr BUFFIN ; read source file ID 00C6FB 1 AD 00 01 lda buffer 00C6FE 1 C9 0D cmp #CR ; was one entered ? 00C700 1 D0 03 bne convid 00C702 1 4C BC C7 jmp nxtpas ; if not continue to next pass or exit 00C705 1 AE 01 01 convid: ldx buffer+1 ; ASCII ID in A,X 00C708 1 20 D0 CB jsr GETBYT ; convert to hex 00C70B 1 D0 18 bne ill_id ; illegal file ID ? 00C70D 1 85 0E sta p3_lsb ; save ID in P3_LSB 00C70F 1 85 2F sta fileid ; and set it 00C711 1 AD 02 01 lda buffer+2 00C714 1 C9 2C cmp #',' ; is there a second ID ? 00C716 1 D0 11 bne tst_id 00C718 1 AD 03 01 lda buffer+3 ; yes read it into A,X 00C71B 1 AE 04 01 ldx buffer+4 00C71E 1 20 D0 CB jsr GETBYT ; and convert to hex 00C721 1 85 11 sta p3_msb ; and save in P3_MSB 00C723 1 F0 04 beq tst_id ; branch always 00C725 1 A0 15 ill_id: ldy #$15 ; point Y at '?' for output 00C727 1 D0 BA bne id_err ; branch round to try again 00C729 1 A5 2F tst_id: lda fileid 00C72B 1 F0 03 beq noload ; was ID=0 memory file ? 00C72D 1 20 A4 CF jsr LOAD ; no - load file 00C730 1 20 BC C4 noload: jsr RSTEXT ; set text pointer and linenumber to start 00C733 1 E6 08 inc txtptr 00C735 1 D0 02 bne ninctp 00C737 1 E6 09 inc txtptr+1 00C739 1 A9 FF ninctp: lda #$FF 00C73B 1 85 2A sta objptr ; set-up pointer to object area 00C73D 1 A5 05 lda $05 00C73F 1 38 sec 00C740 1 E9 01 sbc #$01 00C742 1 85 2B sta objptr+1 00C744 1 A2 FF nxsrcl: ldx #$FF ; reset processor stack pointer 00C746 1 9A txs 00C747 1 A9 76 lda #ERROR1 00C74E 1 8D 03 02 sta brkvec+1 00C751 1 20 CC C5 jsr RD_CHR ; read linenumber from text area 00C754 1 85 07 sta lineno+1 00C756 1 20 CC C5 jsr RD_CHR 00C759 1 85 06 sta lineno 00C75B 1 20 AF C5 jsr RD_BUF ; and rest of line into buffer 00C75E 1 30 26 bmi savobj ; end of text area ? - save object 00C760 1 20 AF C8 jsr CODLIN ; breakdown and encode source line 00C763 1 20 A4 C9 jsr DECODE ; decode addressing mode and instruction 00C766 1 85 26 sta opcode ; save generated opcode 00C768 1 20 24 CA jsr ADMOD3 ; sort out addressing mode 3 - abs,rel,imp 00C76B 1 20 F8 C7 jsr ORGZER ; deal with ORG, test absolute for zeropage 00C76E 1 A6 22 ldx zpass ; which pass is this ? 00C770 1 D0 0B bne pass_1 ; branch is pass 1 00C772 1 20 57 CA jsr ARGMNT ; extract instruction argument 00C775 1 20 9C CB jsr BRANCH ; calculate branch offset and deal with '=' 00C778 1 20 CE CA jsr LSTING ; produce assembly LISTing for line 00C77B 1 F0 03 beq endpas ; branch always 00C77D 1 20 2E C9 pass_1: jsr DEFSYM ; define symbol from line label 00C780 1 20 49 CA endpas: jsr IOBJAD ; increment object address 00C783 1 4C 44 C7 jmp nxsrcl ; round for next source line 00C786 1 A6 22 savobj: ldx zpass ; Save Object Code Area 00C788 1 D0 2F bne savend ; only save if pass 2 00C78A 1 A6 23 ldx zsave ; is object save required ? 00C78C 1 D0 2B bne savend ; no - return 00C78E 1 E6 29 inc obj_id ; increment file ID 00C790 1 A5 29 lda obj_id 00C792 1 85 2F sta fileid ; set-up object file ID 00C794 1 86 36 stx table+6 ; set-up object area start address 00C796 1 A5 05 lda object 00C798 1 85 37 sta table+7 00C79A 1 A4 2B ldy objptr+1 ; is there any object to save ? 00C79C 1 C4 37 cpy table+7 ; compare start address with end address 00C79E 1 90 11 bcc nosave 00C7A0 1 A5 2A lda objptr ; set-up object end address+1 00C7A2 1 69 00 adc #$00 00C7A4 1 85 38 sta table+8 00C7A6 1 98 tya 00C7A7 1 69 00 adc #$00 00C7A9 1 85 39 sta table+9 00C7AB 1 20 96 CF jsr SETUSE ; set DOS qualifier to X 00C7AE 1 20 AD CF jsr SAVE ; and save file 00C7B1 1 A5 19 nosave: lda objadr ; reset up reload address 00C7B3 1 85 32 sta table+2 00C7B5 1 A5 1A lda objadr+1 00C7B7 1 85 33 sta table+3 00C7B9 1 4C E1 C6 savend: jmp pass ; round for next file to assemble 00C7BC 1 A5 22 nxtpas: lda zpass ; if pass 2 return to command input 00C7BE 1 F0 35 beq jmpcom ; Pass 1 enter Pass 2 00C7C0 1 00C7C0 1 ; Command J 'Assembler Pass 2' 00C7C0 1 A9 00 PASS_2: lda #$00 00C7C2 1 85 22 sta zpass ; set pass 2 00C7C4 1 85 1D sta symptb ; clear assembler Listing page counter 00C7C6 1 85 1E sta line ; and line counter 00C7C8 1 A0 08 ldy #pass2-text ; point Y at 'Pass 2'CR'print?' text 00C7CA 1 20 6C C8 jsr QUERY ; output message and get reply 00C7CD 1 D0 02 bne noprnt ; branch if no output required 00C7CF 1 A9 00 lda #$00 ; set output required 00C7D1 1 85 21 noprnt: sta zprint ; set PRINT status 00C7D3 1 A0 18 inpsid: ldy #saveid-text; point Y at 'Save ID' text 00C7D5 1 20 78 C8 jsr OUTEXT ; output message 00C7D8 1 20 DA CE jsr BUFFIN ; input file ID 00C7DB 1 AD 00 01 lda buffer 00C7DE 1 C9 0D cmp #CR 00C7E0 1 F0 0E beq setsav ; was one entered ? 00C7E2 1 AE 01 01 ldx buffer+1 ; load ASCII ID into A,X 00C7E5 1 20 D0 CB jsr GETBYT ; convert to hex 00C7E8 1 D0 E9 bne inpsid ; if not hex try again 00C7EA 1 85 29 sta obj_id ; save file ID 00C7EC 1 C6 29 dec obj_id 00C7EE 1 A9 00 lda #$00 00C7F0 1 85 23 setsav: sta zsave ; set save status 00C7F2 1 4C E1 C6 jmp pass ; and do Pass 2 00C7F5 1 4C 39 C0 jmpcom: jmp nxtcom ; return to Editor command mode 00C7F8 1 00C7F8 1 ; Deal With ORG and Test Absolute For Zero 00C7F8 1 A5 26 ORGZER: lda opcode 00C7FA 1 C9 0C cmp #$0C ; ORG pseudo instruction ? 00C7FC 1 D0 1D bne notorg 00C7FE 1 A2 05 ldx #$05 ; yes - move label to program name 00C800 1 B5 3A movnam: lda unclab,x 00C802 1 95 57 sta prgnam,x 00C804 1 CA dex 00C805 1 10 F9 bpl movnam 00C807 1 20 57 CA jsr ARGMNT ; get origin of program 00C80A 1 A5 28 lda zARGMNT+1 00C80C 1 85 33 sta table+3 ; set-up reload address for save 00C80E 1 85 1A sta objadr+1 ; set-up object start address 00C810 1 A5 27 lda zARGMNT 00C812 1 85 32 sta table+2 00C814 1 85 19 sta objadr 00C816 1 A9 FF no_obj: lda #$FF 00C818 1 85 25 sta noprnd ; set no object for line 00C81A 1 60 rts ; and return 00C81B 1 C9 80 notorg: cmp #$80 ; if blank line set no object and return 00C81D 1 F0 F7 beq no_obj 00C81F 1 C9 FA cmp #$FA ; if define symbol * set no object and return 00C821 1 F0 F3 beq no_obj 00C823 1 C9 4C cmp #$4C ; if JMP instruction return 00C825 1 F0 30 beq rtn 00C827 1 C9 6C cmp #$6C 00C829 1 F0 2C beq rtn 00C82B 1 29 0C and #$0C ; is this instruction absolute 00C82D 1 C9 0C cmp #$0C ; addressing mode ? 00C82F 1 D0 26 bne rtn ; no - return 00C831 1 A5 45 lda uncarg ; extract argument 00C833 1 C9 24 cmp #'$' ; is it hex ? 00C835 1 D0 0A bne nhxarg 00C837 1 A5 46 lda uncarg+1 ; yes - read MS digits 00C839 1 05 47 ora uncarg+2 00C83B 1 C9 30 cmp #$30 ; are they both zero ? 00C83D 1 F0 10 beq setzer ; yes - set zero page 00C83F 1 D0 16 bne rtn ; no -return 00C841 1 A9 52 nhxarg: lda #$52 ; must be a label 00C843 1 85 2C sta srcsym ; point srcsym at it 00C845 1 20 0D C9 jsr FNDSYM ; search symbol table for it 00C848 1 D0 0D bne rtn ; if it does not exist - return 00C84A 1 C8 iny 00C84B 1 B1 1B lda (sympta),y ; read MS byte of symbol, zero ? 00C84D 1 D0 08 bne rtn ; no - return 00C84F 1 A5 26 setzer: lda opcode ; alter opcode from absolute to zero-page 00C851 1 29 F7 and #$F7 00C853 1 85 26 sta opcode 00C855 1 C6 25 dec noprnd ; decrement number of operands 00C857 1 60 rtn: rts 00C858 1 00C858 1 ; Output Byte If Printing Enabled 00C858 1 A6 21 PR_BYT: ldx zprint 00C85A 1 D0 FB bne rtn 00C85C 1 4C 9F CE jmp OUTBYT 00C85F 1 00C85F 1 ; Output CR If printing Enabled 00C85F 1 A9 0D PR_CR: lda #CR 00C861 1 D0 02 bne PR_CHR 00C863 1 A9 20 PR_SPC: lda #SPACE ; Output space 00C865 1 A6 21 PR_CHR: ldx zprint ; output character if Printing enabled 00C867 1 D0 EE bne rtn ; no - return 00C869 1 4C BD CE JMVCHR: jmp OUTCHR ; yes 00C86C 1 ; Output Text And Get Reply 00C86C 1 20 78 C8 QUERY: jsr OUTEXT ; text pointed to by Y 00C86F 1 20 DA CE jsr BUFFIN ; get reply 00C872 1 AD 00 01 lda buffer 00C875 1 C9 59 cmp #'Y' ; yes ? 00C877 1 60 outrtn: rts 00C878 1 00C878 1 ; Output Text Specified By Y 00C878 1 B9 DD CC OUTEXT: lda text,y 00C87B 1 F0 FA beq outrtn ; return when NUL reached 00C87D 1 C8 iny ; increment pointer 00C87E 1 20 69 C8 jsr JMVCHR ; output character 00C881 1 4C 78 C8 jmp OUTEXT ; round again 00C884 1 00C884 1 ; Read A Word From Input Buffer 00C884 1 B9 00 01 RD_WRD: lda buffer,y 00C887 1 C9 0D cmp #CR ; if CR read - load a space 00C889 1 D0 03 bne nrd_cr 00C88B 1 88 dey 00C88C 1 A9 20 lda #SPACE 00C88E 1 95 3A nrd_cr: sta unclab,x ; put in compressed source buffer 00C890 1 E8 inx ; increment buffer index 00C891 1 C8 iny 00C892 1 C9 20 cmp #SPACE 00C894 1 D0 EE bne RD_WRD ; keep going until CR or space found 00C896 1 60 rts 00C897 1 00C897 1 ; Increment Pointer At A By 6 00C897 1 A2 00 PTACMP: ldx #$00 00C899 1 ; Increment Symbol Table Pointer By 6 00C899 1 A9 06 PT_CMP: lda #$06 00C89B 1 18 clc ; and compare with symbol table top 00C89C 1 75 1B addcmp: adc sympta,x 00C89E 1 95 1B sta sympta,x 00C8A0 1 B5 1C lda sympta+1,x 00C8A2 1 69 00 adc #$00 00C8A4 1 95 1C sta sympta+1,x 00C8A6 1 B5 1B lda sympta,x 00C8A8 1 C5 17 cmp symptr 00C8AA 1 B5 1C lda sympta+1,x 00C8AC 1 E5 18 sbc symptr+1 00C8AE 1 60 rts 00C8AF 1 00C8AF 1 ; Breakdown Parts Of Source Line And Encode 00C8AF 1 A2 1C CODLIN: ldx #$1C 00C8B1 1 A9 20 lda #SPACE 00C8B3 1 95 3A spcbuf: sta unclab,x ; fill source buffer with spaces 00C8B5 1 CA dex 00C8B6 1 10 FB bpl spcbuf 00C8B8 1 A0 00 ldy #$00 00C8BA 1 E8 inx 00C8BB 1 20 84 C8 jsr RD_WRD ; read label from buffer 00C8BE 1 A2 06 ldx #$06 00C8C0 1 20 84 C8 jsr RD_WRD ; read mnemonic & addressing mode 00C8C3 1 E0 0A cpx #$0A 00C8C5 1 D0 02 bne nadfil ; if addressing mode not 2 characters 00C8C7 1 95 3A sta unclab,x ; insert an extra space 00C8C9 1 A2 0B nadfil: ldx #$0B 00C8CB 1 20 84 C8 jsr RD_WRD ; read argument 00C8CE 1 84 20 sty index ; save buffer pointer Y 00C8D0 1 A0 00 ldy #$00 00C8D2 1 A2 00 ldx #$00 00C8D4 1 20 F0 C8 jsr ENCODE ; encode 1st half of label into comlab 00C8D7 1 A0 03 ldy #$03 00C8D9 1 A2 02 ldx #$02 00C8DB 1 20 F0 C8 jsr ENCODE ; encode 2nd half 00C8DE 1 A0 06 ldy #$06 00C8E0 1 A2 04 ldx #$04 00C8E2 1 20 F0 C8 jsr ENCODE ; encode 3 character mnemonic into commne 00C8E5 1 A0 0B ldy #$0B 00C8E7 1 A2 06 ldx #$06 00C8E9 1 20 F0 C8 jsr ENCODE ; encode 1st half of argument into comarg 00C8EC 1 A0 0E ldy #$0E 00C8EE 1 A2 08 ldx #$08 00C8F0 1 00C8F0 1 ; Compress Three Characters Into Two Bytes 00C8F0 1 B9 3A 00 ENCODE: lda unclab,y 00C8F3 1 95 4C sta comlab,x ; save 1st character 00C8F5 1 B9 3C 00 lda unclab+2,y 00C8F8 1 29 1F and #$1F ; mask 3rd character to 5 bits 00C8FA 1 85 56 sta temp ; and save 00C8FC 1 B9 3B 00 lda unclab+1,y ; read 2nd character 00C8FF 1 0A asl a ; shift to top 4 bits plus carry 00C900 1 0A asl a 00C901 1 0A asl a 00C902 1 0A asl a 00C903 1 36 4C rol comlab,x ; rotate 2nd character MSB into first 00C905 1 2A rol a ; shift next bit into C 00C906 1 36 4C rol comlab,x ; rotate into 1st character 00C908 1 05 56 ora temp ; OR with last 3 bits of 3rd character 00C90A 1 95 4D sta comlab+1,x ; save result 00C90C 1 60 rts 00C90D 1 00C90D 1 ; Search Symbol Table For Symbol 00C90D 1 A9 FA FNDSYM: lda #$FA ; set-up pointer to symbol table 00C90F 1 85 1B sta sympta 00C911 1 A5 03 lda zsymbol 00C913 1 38 sec 00C914 1 E9 01 sbc #$01 00C916 1 85 1C sta sympta+1 00C918 1 A0 00 nxtlab: ldy #$00 00C91A 1 B1 1B cmp_4: lda (sympta),y ; read symbol table 00C91C 1 D1 2C cmp (srcsym),y ; compare with symbol 00C91E 1 D0 06 bne incpta 00C920 1 C8 iny 00C921 1 C0 04 cpy #$04 00C923 1 D0 F5 bne cmp_4 ; if equal compare all 4 bytes of symbol 00C925 1 60 rts ; return symbol found 00C926 1 20 97 C8 incpta: jsr PTACMP ; increment symbol table pointer 00C929 1 90 ED bcc nxtlab ; and compare with top 00C92B 1 A9 FF lda #$FF ; return symbol not found 00C92D 1 60 rts 00C92E 1 00C92E 1 ; Define Symbol 00C92E 1 A5 3A DEFSYM: lda unclab 00C930 1 C9 20 cmp #$20 ; is there a label ? 00C932 1 D0 01 bne addlab 00C934 1 60 rts ; no - return 00C935 1 A9 4C addlab: lda #$4C ; point srcsym at compressed label 00C937 1 85 2C sta srcsym 00C939 1 A9 00 lda #$00 00C93B 1 85 2D sta srcsym+1 00C93D 1 20 0D C9 jsr FNDSYM ; search symbol table, does it already exist ? 00C940 1 F0 01 beq err_45+1 ; Error 45 'Attempt to redefine symbol' 00C942 1 A0 00 err_45: ldy #$00 ; otherwise we have reached 00C944 1 B1 2C newlab: lda (srcsym),y ; end of symbol table 00C946 1 91 17 sta (symptr),y ; add new symbol to table 00C948 1 C8 iny 00C949 1 C0 04 cpy #$04 ; all 4 bytes 00C94B 1 D0 F7 bne newlab 00C94D 1 A6 26 ldx opcode ; test opcode 00C94F 1 E0 FA cpx #$FA ; is it a define symbol instruction * ? 00C951 1 D0 0E bne notdef 00C953 1 20 57 CA jsr ARGMNT ; yes - extract argument i.e. symbol value 00C956 1 A5 27 lda zARGMNT 00C958 1 A0 04 ldy #$04 00C95A 1 91 17 sta (symptr),y ; and set symbol value 00C95C 1 A5 28 lda zARGMNT+1 00C95E 1 C8 iny 00C95F 1 D0 07 bne setsym ; branch always to set MS byte of value 00C961 1 A5 19 notdef: lda objadr ; set symbol value as present line address 00C963 1 91 17 sta (symptr),y 00C965 1 C8 iny 00C966 1 A5 1A lda objadr+1 00C968 1 91 17 setsym: sta (symptr),y 00C96A 1 A2 FC ldx #$FC ; point X at symbol pointer 00C96C 1 20 99 C8 jsr PT_CMP ; and increment by 6 to add new symbol 00C96F 1 A5 18 lda symptr+1 ; check for end of symbol table reached 00C971 1 C5 04 cmp symf 00C973 1 F0 48 beq err_bf+1 ; Error BF 'Symbol table overflow' 00C975 1 60 rts 00C976 1 00C976 1 ; Assembler Error Handler 00C976 1 68 ERROR1: pla ; use address as error number 00C977 1 68 pla 00C978 1 20 D3 C4 jsr OUTERR ; output error message and number 00C97B 1 20 BB CE jsr OUTSPC 00C97E 1 20 97 CE jsr OUTLNO ; output linenumber of error line 00C981 1 A2 01 ldx #$01 00C983 1 86 25 stx noprnd ; set 2 bytes of object 00C985 1 CA dex 00C986 1 86 26 stx opcode ; clear opcode 00C988 1 86 27 stx zARGMNT ; and operand 00C98A 1 A5 21 lda zprint 00C98C 1 48 pha ; save print status on stack 00C98D 1 86 21 stx zprint ; force printing 00C98F 1 A6 22 ldx zpass 00C991 1 D0 05 bne pa1err ; Pass 2 ? 00C993 1 20 CE CA jsr LSTING ; yes - produce full LISTing of error line 00C996 1 F0 03 beq ret_pr ; branch always to retrieve PRINT status 00C998 1 20 53 CB pa1err: jsr HAFLST ; no - produce LISTing of source only 00C99B 1 68 ret_pr: pla ; retrieve print status 00C99C 1 85 21 sta zprint 00C99E 1 20 49 CA jsr IOBJAD ; increment object address 00C9A1 1 4C 44 C7 jmp nxsrcl ; continue assembling next source line 00C9A4 1 00C9A4 1 ; Decode Addressing Mode And Instruction 00C9A4 1 A2 09 DECODE: ldx #$09 00C9A6 1 A5 43 nxadmd: lda uncmode ; read addressing mode first character 00C9A8 1 DD 6E CC cmp ADMOD1,x ; and compare with table 00C9AB 1 F0 04 beq fnadmd ; match found ? 00C9AD 1 CA admdif: dex ; decrement addressing mode counter 00C9AE 1 10 F6 bpl nxadmd ; try next one 00C9B0 1 00 brk ; Error B2 'Unknown addressing mode' 00C9B1 1 A5 44 fnadmd: lda uncmode+1 ; read addressing mode second character 00C9B3 1 DD 78 CC cmp ADMOD2,x ; and compare with table 00C9B6 1 D0 F5 bne admdif ; difference ? 00C9B8 1 86 2E stx adrmod ; save addressing mode 00C9BA 1 A0 3F ldy #$3F 00C9BC 1 E0 00 err_bf: cpx #$00 ; immediate addressing mode ? 00C9BE 1 D0 02 bne cmpmne 00C9C0 1 A0 37 ldy #$37 00C9C2 1 A5 50 cmpmne: lda commne ; read 1st half of mnemonic 00C9C4 1 D9 DA CB cmp $CBDA,y ; and compare with table 00C9C7 1 D0 07 bne mxmne 00C9C9 1 A5 51 lda commne+1 ; if match - compare second half 00C9CB 1 D9 1A CC cmp MNEMN2,y 00C9CE 1 F0 04 beq fndmne ; match ? 00C9D0 1 88 mxmne: dey ; decrement mnemonic counter 00C9D1 1 10 EF bpl cmpmne ; try next one for match 00C9D3 1 00 brk ; error D5 'Unknown instruction type' 00C9D4 1 98 fndmne: tya ; mnemonic found 00C9D5 1 C9 35 cmp #$35 ; test for 2 special case instructions 00C9D7 1 D0 04 bne nldxay ; LDXAY ? 00C9D9 1 E0 06 cpx #$06 00C9DB 1 F0 13 beq lim_ok 00C9DD 1 C9 3D nldxay: cmp #$3D ; and LDYAX ? 00C9DF 1 D0 04 bne nldyax 00C9E1 1 E0 07 cpx #$07 00C9E3 1 F0 0B beq lim_ok 00C9E5 1 DD 82 CC nldyax: cmp LOWLIM,x ; check range of mnemonics which are 00C9E8 1 90 05 bcc err_f1 ; valid for given addressing mode 00C9EA 1 DD 8C CC cmp UPPLIM,x 00C9ED 1 90 01 bcc lim_ok 00C9EF 1 00 err_f1: brk ; Error F1 'Impossible addressing mode' 00C9F0 1 C0 30 lim_ok: cpy #$30 ; branch if mnemonic >=30 00C9F2 1 10 05 bpl LDATA2 00C9F4 1 BD 5A CC lda AMDAT1,x ; load data for addressing mode 00C9F7 1 D0 03 bne savdat ; branch always 00C9F9 1 BD 64 CC LDATA2: lda AMDAT2,x 00C9FC 1 85 56 savdat: sta temp ; save addressing mode data 00C9FE 1 29 07 and #$07 ; extract number of operands 00CA00 1 85 25 sta noprnd ; and save 00CA02 1 98 tya 00CA03 1 A2 03 ldx #$03 ; shift data into present instruction code 00CA05 1 26 56 rotdat: rol temp 00CA07 1 2A rol a 00CA08 1 CA dex 00CA09 1 D0 FA bne rotdat 00CA0B 1 90 0F bcc rtnb ; use data to generate opcode 00CA0D 1 26 56 rol temp 00CA0F 1 2A rol a 00CA10 1 B0 02 bcs rot5 00CA12 1 10 0B bpl rtnc 00CA14 1 26 56 rot5: rol temp 00CA16 1 2A rol a 00CA17 1 90 02 bcc rtna 00CA19 1 29 FD and #$FD 00CA1B 1 60 rtna: rts 00CA1C 1 29 F8 rtnb: and #$F8 00CA1E 1 60 rts 00CA1F 1 29 70 rtnc: and #$70 00CA21 1 09 8A ora #$8A 00CA23 1 60 rts 00CA24 1 00CA24 1 ; Sort Out Addressing Mode 3 00CA24 1 A6 25 ADMOD3: ldx noprnd ; absolute, relative and implied 00CA26 1 E0 03 cpx #$03 00CA28 1 30 1E bmi nadmd3 00CA2A 1 A5 26 lda opcode 00CA2C 1 C9 20 cmp #$20 ; jsr ? absolute - 2 operands 00CA2E 1 F0 14 beq abs2op 00CA30 1 29 1F and #$1F ; relative addressing mode (branch) ? 00CA32 1 C9 10 cmp #$10 00CA34 1 D0 04 bne nrelat 00CA36 1 A2 01 ldx #$01 ; one operand 00CA38 1 D0 0C bne svnopr ; branch always 00CA3A 1 29 0F nrelat: and #$0F ; absolute addressing mode ? 00CA3C 1 C9 0B cmp #$0B 00CA3E 1 10 04 bpl abs2op ; yes - two operands 00CA40 1 A2 00 ldx #$00 ; no - must be implied addressing mode 00CA42 1 F0 02 beq svnopr ; no operands 00CA44 1 A2 02 abs2op: ldx #$02 ; set two operands 00CA46 1 86 25 svnopr: stx noprnd ; save number of operands 00CA48 1 60 nadmd3: rts ; and return 00CA49 1 00CA49 1 ; Increment Object Address 00CA49 1 A5 25 IOBJAD: lda noprnd 00CA4B 1 30 09 bmi argrtn ; if no object for line return 00CA4D 1 38 sec 00CA4E 1 65 19 adc objadr ; add number of object byte 00CA50 1 85 19 sta objadr ; to object address 00CA52 1 90 02 bcc argrtn 00CA54 1 E6 1A inc objadr+1 00CA56 1 60 argrtn: rts 00CA57 1 00CA57 1 ; Arguments 00CA57 1 A4 45 ARGMNT: ldy uncarg 00CA59 1 A5 46 lda uncarg+1 00CA5B 1 C0 20 cpy #SPACE ; is there an argument 00CA5D 1 F0 F7 beq argrtn ; no - return 00CA5F 1 C0 24 cpy #'$' ; hex argument ? 00CA61 1 F0 52 beq hexarg 00CA63 1 C0 27 cpy #''' ; ASCII argument ? 00CA65 1 F0 4B beq ascarg 00CA67 1 A9 52 lda #comarg ; no must be a symbol 00CA69 1 85 2C sta srcsym ; set-up pointer to compressed symbol 00CA6B 1 A9 00 err_6e: lda #$00 00CA6D 1 85 2D sta srcsym+1 00CA6F 1 20 0D C9 jsr FNDSYM ; search symbol table for it 00CA72 1 D0 F8 bne err_6e+1 ; if not found - Error 6E 'Unknown symbol' 00CA74 1 B1 1B lda (sympta),y ; symbol found 00CA76 1 85 27 sta zARGMNT ; set argument to its value 00CA78 1 C8 iny 00CA79 1 B1 1B lda (sympta),y 00CA7B 1 85 28 sta zARGMNT+1 00CA7D 1 A4 20 ldy index ; retrieve buffer index 00CA7F 1 A6 27 ldx zARGMNT 00CA81 1 B9 00 01 lda buffer,y ; check for argument operator 00CA84 1 C9 2F cmp #'/' ; 'take other byte' 00CA86 1 F0 3F beq takoth 00CA88 1 C9 2B cmp #'+' ; 'add offset' 00CA8A 1 18 clc 00CA8B 1 F0 0A beq offset 00CA8D 1 C9 21 cmp #'!' ; 'set top bit' 00CA8F 1 F0 1A beq settop 00CA91 1 C9 2D cmp #'-' ; 'subtract offset' 00CA93 1 D0 C1 bne argrtn ; none of them - return 00CA95 1 C6 28 dec zARGMNT+1 00CA97 1 08 offset: php 00CA98 1 B9 01 01 lda buffer+1,y ; read offset 00CA9B 1 BE 02 01 ldx buffer+2,y 00CA9E 1 20 D0 CB jsr GETBYT 00CAA1 1 28 plp 00CAA2 1 90 02 bcc addoff ; subtract or add offset ? 00CAA4 1 49 FF eor #$FF ; subtract - complement and then add 00CAA6 1 A2 0C addoff: ldx #$0C ; point at argument 00CAA8 1 4C 9C C8 jmp addcmp ; add offset and return 00CAAB 1 A5 28 settop: lda zARGMNT+1 ; load MS byte 00CAAD 1 09 80 ora #$80 ; set top bit 00CAAF 1 85 28 sta zARGMNT+1 ; save result 00CAB1 1 60 rts ; and return 00CAB2 1 AA ascarg: tax ; move ASCII code to A 00CAB3 1 D0 14 bne svxarg ; branch always to save result 00CAB5 1 A6 47 hexarg: ldx uncarg+2 ; extract MS byte 00CAB7 1 20 D0 CB jsr GETBYT 00CABA 1 85 28 sta zARGMNT+1 00CABC 1 A5 48 lda uncarg+3 00CABE 1 A6 49 ldx uncarg+4 00CAC0 1 20 D0 CB jsr GETBYT ; and LS byte 00CAC3 1 F0 06 beq svlsar ; was there one ? 00CAC5 1 A6 28 ldx zARGMNT+1 ; set both bytes to same value 00CAC7 1 A5 28 takoth: lda zARGMNT+1 00CAC9 1 86 28 svxarg: stx zARGMNT+1 ; save X and A as argument 00CACB 1 85 27 svlsar: sta zARGMNT ; save LS byte of argument 00CACD 1 60 rts 00CACE 1 00CACE 1 ; Produce Assembler LISTing For Line 00CACE 1 E6 1E LSTING: inc line ; increment line counter 00CAD0 1 30 37 bmi nopage ; new page ? 00CAD2 1 A9 0C lda #$0C ; yes - output form-feed 00CAD4 1 20 65 C8 jsr PR_CHR 00CAD7 1 A0 00 ldy #$00 ; output program name 00CAD9 1 B9 57 00 outnam: lda prgnam,y 00CADC 1 20 65 C8 jsr PR_CHR 00CADF 1 C8 iny 00CAE0 1 C0 06 cpy #$06 ; all six characters 00CAE2 1 D0 F5 bne outnam 00CAE4 1 A0 22 ldy #header-text; point Y at Assembler heading text 00CAE6 1 B9 DD CC outhed: lda text,y 00CAE9 1 F0 06 beq endhed 00CAEB 1 20 65 C8 jsr PR_CHR 00CAEE 1 C8 iny 00CAEF 1 D0 F5 bne outhed 00CAF1 1 A5 1D endhed: lda symptb ; increment page number by decimal 1 00CAF3 1 F8 sed 00CAF4 1 18 clc 00CAF5 1 69 01 adc #$01 00CAF7 1 85 1D sta symptb 00CAF9 1 D8 cld 00CAFA 1 20 58 C8 jsr PR_BYT ; output page number 00CAFD 1 A0 03 ldy #$03 00CAFF 1 20 5F C8 crlf: jsr PR_CR ; and 3 CRLF's 00CB02 1 88 dey 00CB03 1 D0 FA bne crlf 00CB05 1 A9 C8 lda #$C8 ; reset line counter 00CB07 1 85 1E sta line 00CB09 1 20 5F C8 nopage: jsr PR_CR 00CB0C 1 A5 07 lda lineno+1 ; output linenumber:space 00CB0E 1 20 58 C8 jsr PR_BYT 00CB11 1 A5 06 lda lineno 00CB13 1 20 58 C8 jsr PR_BYT 00CB16 1 A9 3A lda #':' 00CB18 1 20 65 C8 jsr PR_CHR 00CB1B 1 20 63 C8 jsr PR_SPC 00CB1E 1 A5 40 lda ncmne ; read 1st character of uncompressed mnemonic 00CB20 1 C9 20 cmp #SPACE ; is there a mnemonic ? 00CB22 1 D0 0A bne monic 00CB24 1 A0 0E ldy #$0E 00CB26 1 20 63 C8 filspc: jsr PR_SPC ; no fill with spaces 00CB29 1 88 dey 00CB2A 1 10 FA bpl filspc 00CB2C 1 30 43 bmi coment ; then go to to output comment 00CB2E 1 A5 1A monic: lda objadr+1 ; output object address 00CB30 1 20 58 C8 jsr PR_BYT 00CB33 1 A5 19 lda objadr 00CB35 1 20 58 C8 jsr PR_BYT 00CB38 1 20 63 C8 jsr PR_SPC 00CB3B 1 A5 26 lda opcode ; output opcode 00CB3D 1 A6 25 ldx noprnd 00CB3F 1 20 81 CB jsr OUTOBY 00CB42 1 A5 27 lda zARGMNT ; output first operand byte 00CB44 1 A6 25 ldx noprnd 00CB46 1 CA dex 00CB47 1 20 81 CB jsr OUTOBY 00CB4A 1 A5 28 lda zARGMNT+1 ; output second operand byte 00CB4C 1 A6 25 ldx noprnd 00CB4E 1 CA dex 00CB4F 1 CA dex 00CB50 1 20 81 CB jsr OUTOBY 00CB53 1 00CB53 1 ; Output Source Text 00CB53 1 20 63 C8 HAFLST: jsr PR_SPC ; source pointer 00CB56 1 A0 00 ldy #$00 00CB58 1 C0 06 outsrc: cpy #$06 ; start of mnemonic ? 00CB5A 1 F0 04 beq labspc ; yes - output a space 00CB5C 1 C0 0B cpy #$0B ; start of argument ? 00CB5E 1 D0 03 bne nspace 00CB60 1 20 63 C8 labspc: jsr PR_SPC ; output delimiter space 00CB63 1 B9 3A 00 nspace: lda unclab,y ; output text 00CB66 1 20 65 C8 jsr PR_CHR 00CB69 1 C8 iny 00CB6A 1 C0 11 cpy #$11 00CB6C 1 D0 EA bne outsrc 00CB6E 1 20 63 C8 jsr PR_SPC 00CB71 1 A4 20 coment: ldy index ; retrieve buffer index 00CB73 1 B9 00 01 outcom: lda buffer,y 00CB76 1 C9 0D cmp #CR 00CB78 1 F0 06 beq lstrtn 00CB7A 1 20 65 C8 jsr PR_CHR ; output comment 00CB7D 1 C8 iny 00CB7E 1 D0 F3 bne outcom 00CB80 1 60 lstrtn: rts ; and return 00CB81 1 00CB81 1 ; Output Object Byte 00CB81 1 30 10 OUTOBY: bmi no_oby ; if negative no object byte, return 00CB83 1 A0 00 ldy #$00 00CB85 1 E6 2A inc objptr ; increment object pointer 00CB87 1 D0 02 bne nincop 00CB89 1 E6 2B inc objptr+1 00CB8B 1 91 2A nincop: sta (objptr),y ; set-up object byte 00CB8D 1 20 58 C8 jsr PR_BYT ; output byte, space 00CB90 1 4C 63 C8 jmp PR_SPC ; and return 00CB93 1 20 63 C8 no_oby: jsr PR_SPC ; no object fill with spaces 00CB96 1 20 63 C8 jsr PR_SPC 00CB99 1 4C 63 C8 jmp PR_SPC ; and return 00CB9C 1 00CB9C 1 ; Deal With = And Calculate Branch Offset 00CB9C 1 A5 26 BRANCH: lda opcode 00CB9E 1 C9 DA cmp #$DA ; define byte = pseudo opcode ? 00CBA0 1 F0 29 beq defbyt 00CBA2 1 29 1F and #$1F ; is it a branch instruction ? 00CBA4 1 C9 10 cmp #$10 00CBA6 1 D0 22 bne br_rtn ; no - return 00CBA8 1 A5 27 lda zARGMNT ; subtract 2 from argument 00CBAA 1 38 sec 00CBAB 1 E9 02 sbc #$02 00CBAD 1 B0 03 bcs ndecar 00CBAF 1 C6 28 dec zARGMNT+1 00CBB1 1 38 sec 00CBB2 1 E5 19 ndecar: sbc objadr ; and subtract present object address 00CBB4 1 85 27 sta zARGMNT 00CBB6 1 A5 28 lda zARGMNT+1 00CBB8 1 E5 1A sbc objadr+1 00CBBA 1 F0 05 beq forwrd ; check for branching out of range 00CBBC 1 C9 FF cmp #$FF ; either MSB=0 and C=1 (no borrow) 00CBBE 1 D0 07 bne err_c9 ; or MSB=$FF and LSB negative 00CBC0 1 18 clc 00CBC1 1 A5 27 forwrd: lda zARGMNT 00CBC3 1 B0 03 bcs tstbrw 00CBC5 1 30 03 bmi br_rtn 00CBC7 1 00 err_c9: brk ; Error C9 'Branch out of range' 00CBC8 1 30 FD tstbrw: bmi err_c9 00CBCA 1 60 br_rtn: rts 00CBCB 1 A5 28 defbyt: lda zARGMNT+1 ; define byte pseudo instruction 00CBCD 1 85 26 sta opcode ; set-up opcode to MSB of argument 00CBCF 1 60 rts 00CBD0 1 00CBD0 1 ; Append 2 Hex Digits In A 00CBD0 1 20 26 CF GETBYT: jsr APPEND 00CBD3 1 D0 04 bne byterr ; return if not hex 00CBD5 1 8A txa 00CBD6 1 20 26 CF jsr APPEND 00CBD9 1 60 byterr: rts 00CBDA 1 00CBDA 1 ; 1st half of compressed Mnemonics 00CBDA 1 00CBDA 1 0A 41 0A 0D MNEMN1: .byte $0A,$41,$0A,$0D,$2A,$41,$09,$4C,$4A,$41,$0A,$0D,$4A,$41,$0A,$4C 00CBDE 1 2A 41 09 4C 00CBE2 1 4A 41 0A 0D 00CBE6 1 4A 41 0A 4C 00CBEA 1 80 10 08 53 .byte $80,$10,$08,$53,$30,$50,$08,$0D,$0E,$25,$09,$0D,$0E,$25,$08,$4C 00CBEE 1 30 50 08 0D 00CBF2 1 0E 25 09 0D 00CBF6 1 0E 25 08 4C 00CBFA 1 53 53 50 52 .byte $53,$53,$50,$52,$10,$F4,$39,$A8,$3E,$05,$15,$04,$4E,$30,$0D,$4C 00CBFE 1 10 F4 39 A8 00CC02 1 3E 05 15 04 00CC06 1 4E 30 0D 4C 00CC0A 1 06 49 32 49 .byte $06,$49,$32,$49,$4E,$30,$10,$25,$3E,$09,$29,$29,$4E,$30,$0E,$0E 00CC0E 1 4E 30 10 25 00CC12 1 3E 09 29 29 00CC16 1 4E 30 0E 0E 00CC1A 1 00CC1A 1 ; 2nd half of compressed mnemonics 00CC1A 1 00CC1A 1 4B 10 0C 83 MNEMN2: .byte $4B,$10,$0C,$83,$72,$90,$A9,$A3,$89,$01,$C3,$89,$93,$81,$D3,$A9 00CC1E 1 72 90 A9 A3 00CC22 1 89 01 C3 89 00CC26 1 93 81 D3 A9 00CC2A 1 00 B9 63 21 .byte $00,$B9,$63,$21,$99,$39,$73,$96,$19,$D9,$C5,$84,$18,$D8,$B1,$A4 00CC2E 1 99 39 73 96 00CC32 1 19 D9 C5 84 00CC36 1 18 D8 B1 A4 00CC3A 1 01 13 38 78 .byte $01,$13,$38,$78,$B8,$00,$F0,$00,$41,$C4,$F2,$83,$81,$81,$B0,$43 00CC3E 1 B8 00 F0 00 00CC42 1 41 C4 F2 83 00CC46 1 81 81 B0 43 00CC4A 1 6C EC 72 F2 .byte $6C,$EC,$72,$F2,$98,$98,$A3,$C3,$47,$34,$B0,$A9,$99,$99,$19,$18 00CC4E 1 98 98 A3 C3 00CC52 1 47 34 B0 A9 00CC56 1 99 99 19 18 00CC5A 1 00CC5A 1 ; Data for each addressing mode containing 00CC5A 1 ; number of operands and information to 00CC5A 1 ; produce opcode for instruction 00CC5A 1 ; (for 1st 30H instructions) 00CC5A 1 00CC5A 1 49 29 48 6E AMDAT1: .byte $49,$29,$48,$6E,$89,$A9,$CA,$EA,$A9,$09 00CC5E 1 89 A9 CA EA 00CC62 1 A9 09 00CC64 1 00CC64 1 ; (for last 10H instructions) 00CC64 1 00CC64 1 11 31 50 76 AMDAT2: .byte $11,$31,$50,$76,$91,$B1,$F2,$F2,$B1,$11 00CC68 1 91 B1 F2 F2 00CC6C 1 B1 11 00CC6E 1 00CC6E 1 ; Addressing mode first character 00CC6E 1 00CC6E 1 49 5A 41 20 ADMOD1: .byte $49,$5A,$41,$20,$49,$5A,$41,$41,$5A,$49 00CC72 1 49 5A 41 41 00CC76 1 5A 49 00CC78 1 00CC78 1 ; Addressing mode second character 00CC78 1 00CC78 1 4D 20 20 20 ADMOD2: .byte $4D,$20,$20,$20,$59,$58,$59,$58,$59,$58 00CC7C 1 59 58 59 58 00CC80 1 59 58 00CC82 1 00CC82 1 ; Range of valid mnemonics for 00CC82 1 ; addressing mode Lower limit (inclusive) 00CC82 1 00CC82 1 14 28 30 00 LOWLIM: .byte $14,$28,$30,$00,$28,$28,$28,$28,$34,$28 00CC86 1 28 28 28 28 00CC8A 1 34 28 00CC8C 1 00CC8C 1 ;Upper limit (exclusive) 00CC8C 1 00CC8C 1 36 40 34 40 UPPLIM: .byte $36,$40,$34,$40,$30,$3E,$30,$39,$36,$30 00CC90 1 30 3E 30 39 00CC94 1 36 30 00CC96 1 00CC96 1 38 30 28 40 DISDAT: .byte $38,$30,$28,$40,$02,$43,$04,$40,$06,$40,$08,$40,$22,$43,$44,$40 00CC9A 1 02 43 04 40 00CC9E 1 06 40 08 40 00CCA2 1 22 43 44 40 00CCA6 1 06 40 08 40 .byte $06,$40,$08,$40,$02,$43,$44,$40,$06,$40,$08,$40,$02,$43,$44,$40 00CCAA 1 02 43 44 40 00CCAE 1 06 40 08 40 00CCB2 1 02 43 44 40 00CCB6 1 06 40 08 00 .byte $06,$40,$08,$00,$22,$44,$44,$40,$69,$44,$00,$11,$22,$44,$44,$40 00CCBA 1 22 44 44 40 00CCBE 1 69 44 00 11 00CCC2 1 22 44 44 40 00CCC6 1 69 44 87 10 .byte $69,$44,$87,$10,$22,$44,$44,$40,$06,$40,$08,$10,$22,$44,$44,$40 00CCCA 1 22 44 44 40 00CCCE 1 06 40 08 10 00CCD2 1 22 44 44 40 00CCD6 1 06 40 08 A2 .byte $06,$40,$08,$A2,$14,$56,$78 00CCDA 1 14 56 78 00CCDD 1 00CCDD 1 text: 00CCDD 1 0D 50 61 73 pass1: .byte CR,"Pass 1",$00 00CCE1 1 73 20 31 00 00CCE5 1 0D 50 61 73 pass2: .byte CR,"Pass 2" 00CCE9 1 73 20 32 00CCEC 1 0D 50 72 69 PRINTq: .byte CR,"Print? ",$00 00CCF0 1 6E 74 3F 20 00CCF4 1 00 00CCF5 1 0D 53 61 76 saveid: .byte CR,"Save ID ",$00 00CCF9 1 65 20 49 44 00CCFD 1 20 00 00CCFF 1 20 20 20 20 header: .byte " ACORN 6502 Assembler Page ",$00 00CD03 1 41 43 4F 52 00CD07 1 4E 20 36 35 00CD0B 1 30 32 20 41 00CD0F 1 73 73 65 6D 00CD13 1 62 6C 65 72 00CD17 1 20 20 20 50 00CD1B 1 61 67 65 20 00CD1F 1 00 00CD20 1 0D 53 79 6D symbol: .byte CR,"Symbol Table ",$00 00CD24 1 62 6F 6C 20 00CD28 1 54 61 62 6C 00CD2C 1 65 20 00 00CD2F 1 0D 49 44 20 id: .byte CR,"ID ",$00 00CD33 1 00 00CD34 1 0D 4E 65 77 new: .byte CR,"New? ",$00 00CD38 1 3F 20 00 00CD3B 1 0D 43 6C 65 clear: .byte CR,"Clear",$00 00CD3F 1 61 72 00 00CD42 1 00CD42 1 ; Disassembler 00CD42 1 20 B4 CE DISASM: jsr CRLF 00CD45 1 A5 1A lda objadr+1 00CD47 1 A6 19 ldx objadr 00CD49 1 20 9B CE jsr OUT_AX ; output object address 00CD4C 1 A2 00 ldx #$00 00CD4E 1 A1 19 lda (objadr,x) ; read opcode 00CD50 1 A8 tay ; save in Y 00CD51 1 4A lsr a ; work out addressing mode 00CD52 1 90 0B bcc even 00CD54 1 4A lsr a 00CD55 1 B0 17 bcs unknwn 00CD57 1 C9 22 cmp #$22 ; test odd value 89 00CD59 1 F0 13 beq unknwn 00CD5B 1 29 07 and #$07 00CD5D 1 09 80 ora #$80 00CD5F 1 4A even: lsr a 00CD60 1 AA tax 00CD61 1 BD 99 CC lda DISDAT+3,x ; read addressing mode data 00CD64 1 B0 04 bcs mask1 ; which nibble do we use ? 00CD66 1 4A lsr a ; MS - shift into position 00CD67 1 4A lsr a 00CD68 1 4A lsr a 00CD69 1 4A lsr a 00CD6A 1 29 0F mask1: and #$0F ; mask to 4 bits 00CD6C 1 D0 04 bne known 00CD6E 1 A9 04 unknwn: lda #$04 ; unknown instruction 00CD70 1 A0 80 ldy #$80 ; set to blank mnemonic and addressing mode 00CD72 1 AA known: tax 00CD73 1 85 5D sta admode ; save addressing mode 00CD75 1 84 26 sty opcode ; save opcode 00CD77 1 CA dex 00CD78 1 20 F9 C9 jsr LDATA2 ; find number of operands for addressing mode 00CD7B 1 20 24 CA jsr ADMOD3 ; sort out addressing mode 3 00CD7E 1 98 tya ; work out instruction code from opcode 00CD7F 1 29 8F and #$8F 00CD81 1 AA tax 00CD82 1 98 tya 00CD83 1 A0 00 ldy #$00 00CD85 1 84 45 sty uncarg 00CD87 1 4A lsr a 00CD88 1 26 45 rol uncarg 00CD8A 1 4A lsr a 00CD8B 1 26 45 rol uncarg 00CD8D 1 4A lsr a 00CD8E 1 26 45 rol uncarg 00CD90 1 F0 11 beq tdig08 ; branch if 2nd digit 0 or 8 00CD92 1 4A lsr a 00CD93 1 A0 20 ldy #$20 00CD95 1 E0 8A cpx #$8A 00CD97 1 F0 08 beq mask2 00CD99 1 4A lsr a 00CD9A 1 46 45 lsr uncarg 00CD9C 1 A6 45 ldx uncarg 00CD9E 1 BC 96 CC ldy DISDAT,x 00CDA1 1 29 07 mask2: and #$07 00CDA3 1 84 45 tdig08: sty uncarg 00CDA5 1 05 45 ora uncarg 00CDA7 1 85 45 sta uncarg ; save instruction code 00CDA9 1 A0 00 ldy #$00 00CDAB 1 20 BB CE jsr OUTSPC ; output required number of object bytes 00CDAE 1 B1 19 outobj: lda (objadr),y 00CDB0 1 20 9F CE jsr OUTBYT 00CDB3 1 A2 01 ldx #$01 00CDB5 1 20 42 CE fl3byt: jsr OUTXSP 00CDB8 1 C4 25 cpy noprnd 00CDBA 1 C8 iny 00CDBB 1 90 F1 bcc outobj 00CDBD 1 A2 03 ldx #$03 00CDBF 1 C0 04 cpy #$04 00CDC1 1 90 F2 bcc fl3byt ; and fill with spaces up to 3 bytes 00CDC3 1 A6 19 ldx objadr ; load object address 00CDC5 1 A4 1A ldy objadr+1 00CDC7 1 A9 06 lda #$06 ; set fill with 6 spaces if label not found 00CDC9 1 85 24 sta numspc 00CDCB 1 20 50 CE jsr FNSYVL ; find and output label for this address 00CDCE 1 A4 45 ldy uncarg 00CDD0 1 B9 DA CB lda MNEMN1,y ; load first half of compressed mnemonic 00CDD3 1 85 45 sta uncarg ; save for later 00CDD5 1 4A lsr a ; shift first character into position 00CDD6 1 4A lsr a 00CDD7 1 20 49 CE jsr OUTUPS ; and output 00CDDA 1 B9 1A CC lda MNEMN2,y ; load 2nd half of compressed mnemonic 00CDDD 1 2A rol a ; rotate into 1st half to separate characters 00CDDE 1 26 45 rol uncarg 00CDE0 1 2A rol a 00CDE1 1 26 45 rol uncarg 00CDE3 1 2A rol a 00CDE4 1 26 45 rol uncarg 00CDE6 1 A5 45 lda uncarg 00CDE8 1 20 49 CE jsr OUTUPS ; output second character 00CDEB 1 B9 1A CC lda MNEMN2,y 00CDEE 1 20 49 CE jsr OUTUPS ; and third 00CDF1 1 A6 5D ldx admode ; retrieve addressing mode 00CDF3 1 BD 6D CC lda ADMOD1-1,x ; and output its 2 characters 00CDF6 1 20 BD CE jsr OUTCHR 00CDF9 1 BD 77 CC lda ADMOD2-1,x 00CDFC 1 20 BD CE jsr OUTCHR 00CDFF 1 20 BB CE jsr OUTSPC 00CE02 1 A6 25 ldx noprnd ; load number of operands 00CE04 1 CA dex 00CE05 1 30 37 bmi LFE3E ; any operands ? 00CE07 1 D0 25 bne twprnd ; 2 operands ? 00CE09 1 A0 01 ldy #$01 ; no - only 1 operand 00CE0B 1 A5 26 lda opcode ; load opcode and test for 00CE0D 1 29 1F and #$1F ; branch instruction ? 00CE0F 1 C9 10 cmp #$10 00CE11 1 D0 15 bne not_br 00CE13 1 B1 19 lda (objadr),y ; yes - read offset 00CE15 1 48 pha 00CE16 1 38 sec ; and add to object address+2 to get 00CE17 1 69 01 adc #$01 ; destination address 00CE19 1 65 19 adc objadr 00CE1B 1 AA tax ; move LSB result to X 00CE1C 1 A5 1A lda objadr+1 00CE1E 1 69 00 adc #$00 00CE20 1 A8 tay ; move MSB result to Y 00CE21 1 68 pla 00CE22 1 10 13 bpl fnd_op ; forwards or backwards branch ? 00CE24 1 88 dey ; backwards - final decrement of MSB 00CE25 1 4C 37 CE jmp fnd_op 00CE28 1 B1 19 not_br: lda (objadr),y ; only 1 operand - read it 00CE2A 1 AA tax ; and move to X 00CE2B 1 88 dey ; Y=0 00CE2C 1 F0 09 beq fnd_op ; branch always 00CE2E 1 A0 01 twprnd: ldy #$01 ; 2 operands 00CE30 1 B1 19 lda (objadr),y ; read LS byte 00CE32 1 AA tax ; move to X 00CE33 1 C8 iny 00CE34 1 B1 19 lda (objadr),y ; read MS byte 00CE36 1 A8 tay ; move to Y 00CE37 1 A9 00 fnd_op: lda #$00 ; set - output value if no symbol found 00CE39 1 85 24 sta numspc 00CE3B 1 20 50 CE jsr FNSYVL ; search and output symbol for operand 00CE3E 1 20 49 CA LFE3E: jsr IOBJAD ; increment object address 00CE41 1 60 rts ; and return 00CE42 1 00CE42 1 ; Output X Spaces 00CE42 1 20 BB CE OUTXSP: jsr OUTSPC 00CE45 1 CA dex 00CE46 1 D0 FA bne OUTXSP 00CE48 1 60 rts 00CE49 1 00CE49 1 ; Output Character In Upper Case 00CE49 1 29 1F OUTUPS: and #$1F ; convert to upper case and output 00CE4B 1 09 40 ora #$40 00CE4D 1 4C BD CE jmp OUTCHR 00CE50 1 00CE50 1 ; Find Symbol For Given Value 00CE50 1 86 43 FNSYVL: stx uncmode ; save value 00CE52 1 84 44 sty uncmode+1 00CE54 1 20 C1 C6 jsr SET_PT ; set up symbol table pointers 00CE57 1 A0 04 cmpnsy: ldy #$04 00CE59 1 B1 1B lda (sympta),y ; compare LSB with symbol value LSB 00CE5B 1 C5 43 cmp uncmode 00CE5D 1 D0 0A bne nxtsym 00CE5F 1 C8 iny 00CE60 1 B1 1B lda (sympta),y ; and compare MSBs 00CE62 1 C5 44 cmp uncmode+1 00CE64 1 D0 03 bne nxtsym 00CE66 1 4C 87 C6 jmp OUTLAB ; if match found output symbol and return 00CE69 1 20 97 C8 nxtsym: jsr PTACMP ; not match - increment symbol table pointers 00CE6C 1 90 E9 bcc cmpnsy ; compare next symbol 00CE6E 1 A4 24 ldy numspc ; end of symbol table - no symbol match found 00CE70 1 D0 11 bne noutop ; output value or fill with spaces ? 00CE72 1 A9 24 lda #'$' ; output value 00CE74 1 20 BD CE jsr OUTCHR ; output hex operator $ 00CE77 1 A6 25 ldx noprnd ; how many bytes of operand ? 00CE79 1 CA dex 00CE7A 1 F0 0E beq tnprnd 00CE7C 1 A5 44 out_br: lda uncmode+1 ; 2 - output word and return 00CE7E 1 A6 43 ldx uncmode 00CE80 1 4C 9B CE jmp OUT_AX 00CE83 1 20 BB CE noutop: jsr OUTSPC ; do not output value 00CE86 1 88 dey ; fill with spaces 00CE87 1 10 FA bpl noutop 00CE89 1 60 rts ; and return 00CE8A 1 A5 26 tnprnd: lda opcode ; only 1 operand but check for branches 00CE8C 1 29 1F and #$1F 00CE8E 1 C9 10 cmp #$10 00CE90 1 F0 EA beq out_br ; if branch output 2 byte address 00CE92 1 A5 43 lda uncmode ; otherwise output single byte of operand 00CE94 1 4C 9F CE jmp OUTBYT 00CE97 1 00CE97 1 ; Output Linenumber 00CE97 1 A5 07 OUTLNO: lda lineno+1 ; load into A,X 00CE99 1 A6 06 ldx lineno 00CE9B 1 00CE9B 1 ; Output Word In A,X Registers 00CE9B 1 20 9F CE OUT_AX: jsr OUTBYT 00CE9E 1 8A txa 00CE9F 1 00CE9F 1 ; Output Accumulator Byte 00CE9F 1 48 OUTBYT: pha ; save byte 00CEA0 1 4A lsr a ; shift to LS nibble 00CEA1 1 4A lsr a 00CEA2 1 4A lsr a 00CEA3 1 4A lsr a 00CEA4 1 20 AA CE jsr OUTDIG ; output MS digit 00CEA7 1 68 pla ; retrieve byte 00CEA8 1 29 0F and #$0F ; output LS digit 00CEAA 1 00CEAA 1 ; Output Digit In A 00CEAA 1 C9 0A OUTDIG: cmp #$0A 00CEAC 1 90 02 bcc decmal ; decimal ? 00CEAE 1 69 06 adc #$06 ; no - offset for hex A to F 00CEB0 1 69 30 decmal: adc #$30 ; convert to ASCII 00CEB2 1 D0 09 bne OUTCHR ; and output 00CEB4 1 00CEB4 1 ; Output CRLF 00CEB4 1 A9 0D CRLF: lda #CR 00CEB6 1 D0 05 bne OUTCHR 00CEB8 1 00CEB8 1 ; Output Word In A,X Registers, Space, Character 00CEB8 1 20 9B CE OUTAX_: jsr OUT_AX 00CEBB 1 ; Output Space, Character 00CEBB 1 A9 20 OUTSPC: lda #SPACE 00CEBD 1 ; Output Character 00CEBD 1 20 E9 FF OUTCHR: jsr OSASCI 00CEC0 1 48 chkesc: pha ; check for Escape pressed 00CEC1 1 AD 21 0E lda port_a 00CEC4 1 C9 1B cmp #ESC 00CEC6 1 F0 02 beq escape 00CEC8 1 68 pla 00CEC9 1 60 rts 00CECA 1 AD 21 0E escape: lda port_a ; de-bounce Escape key 00CECD 1 C9 1B cmp #ESC 00CECF 1 F0 F9 beq escape 00CED1 1 4C 39 C0 jmp nxtcom ; and return to Editor command mode 00CED4 1 00CED4 1 ; Read and Echo Key And Check For Escape 00CED4 1 20 E6 FF RD_KEY: jsr OSECHO 00CED7 1 4C C0 CE jmp chkesc 00CEDA 1 00CEDA 1 ; Read Input Channel Into Buffer 00CEDA 1 A0 00 BUFFIN: ldy #$00 00CEDC 1 20 D4 CE read: jsr RD_KEY ; read key, check for Escape 00CEDF 1 C9 7F cmp #DEL ; Delete key ? 00CEE1 1 D0 05 bne notdel 00CEE3 1 88 dey ; yes - backup buffer index 00CEE4 1 10 F6 bpl read ; read another character 00CEE6 1 30 F2 bmi BUFFIN ; unless start of line - start again 00CEE8 1 C9 18 notdel: cmp #CAN ; Cancel key ? 00CEEA 1 D0 06 bne notcan 00CEEC 1 20 B4 CE jsr CRLF ; output CRLF 00CEEF 1 4C DA CE jmp BUFFIN ; and start again 00CEF2 1 C9 05 notcan: cmp #ENQ ; Control E ? 00CEF4 1 F0 11 beq repeat 00CEF6 1 99 00 01 sta buffer,y ; no - must be character - put in buffer 00CEF9 1 C9 0D cmp #CR ; end of input, CR ? 00CEFB 1 F0 09 beq cr ; yes - return 00CEFD 1 C8 iny ; no - increment buffer index 00CEFE 1 C0 50 cpy #bufsiz ;($50) buffer full ? 00CF00 1 90 DA bcc read ; no - carry on 00CF02 1 A9 0D lda #CR 00CF04 1 D0 EC bne notcan ; yes - only allow CR to be typed 00CF06 1 60 cr: rts 00CF07 1 B9 00 01 repeat: lda buffer,y ; write buffer out again 00CF0A 1 C9 0D cmp #CR 00CF0C 1 F0 CE beq read ; if CR continue input 00CF0E 1 20 E9 FF jsr OSASCI 00CF11 1 C8 iny 00CF12 1 C0 50 cpy #bufsiz ;($50) end of buffer ? 00CF14 1 D0 F1 bne repeat ; no - continue 00CF16 1 F0 C4 beq read ; yes - return to input 00CF18 1 00CF18 1 ; Output Buffer To Output Channel(s) 00CF18 1 A0 00 BUFOUT: ldy #$00 00CF1A 1 B9 00 01 outbuf: lda buffer,y 00CF1D 1 20 BD CE jsr OUTCHR 00CF20 1 C8 iny 00CF21 1 C9 0D cmp #CR ; end of buffer, CR ? 00CF23 1 D0 F5 bne outbuf 00CF25 1 60 rts ; yes - return 00CF26 1 00CF26 1 ; Append Hex Digits To A 00CF26 1 20 3A CF APPEND: jsr ASCHEX ; convert new digit from ASCII to hex 00CF29 1 90 0E bcc hexrtn 00CF2B 1 A5 16 lda lasthx ; retrieve last value 00CF2D 1 84 16 sty lasthx ; save this value 00CF2F 1 0A asl a ; and shift last value to top nibble 00CF30 1 0A asl a 00CF31 1 0A asl a 00CF32 1 0A asl a 00CF33 1 05 16 ora lasthx ; OR with new value 00CF35 1 85 16 sta lasthx ; and save result 00CF37 1 A0 00 ldy #$00 00CF39 1 60 hexrtn: rts 00CF3A 1 00CF3A 1 ; Convert ASCII To Hex Digit 00CF3A 1 A0 0F ASCHEX: ldy #$0F 00CF3C 1 D9 46 CF nxthex: cmp HEXTAB,y ; compare with table of ASCII hex 00CF3F 1 F0 F8 beq hexrtn ; return is match Y=hex, carry set 00CF41 1 88 dey 00CF42 1 10 F8 bpl nxthex 00CF44 1 18 clc 00CF45 1 60 rts ; return not hex, carry clear 00CF46 1 00CF46 1 30 31 32 33 HEXTAB: .byte "0123456789ABCDEF" ; Data for ASCII to Hex Conversion 00CF4A 1 34 35 36 37 00CF4E 1 38 39 41 42 00CF52 1 43 44 45 46 00CF56 1 00CF56 1 55 41 44 45 UADEEE: .byte "UADEEE",CR ; ADE Filename 00CF5A 1 45 45 0D 00CF5D 1 00CF5D 1 55 53 45 58 USEX: .byte "USEX",CR ; USEX Command 00CF61 1 0D 00CF62 1 00CF62 1 ; DEFTAB - Definitions Table 00CF62 1 2F DEFTAB: .byte $2F ; SOURCM text start page minus one 00CF63 1 30 .byte $30 ; SOURCE text start page 00CF64 1 60 .byte $60 ; SOURCF text end page plus 1 00CF65 1 22 .byte $22 ; SYMBOL first page of symbol table 00CF66 1 2E .byte $2E ; SYMF last page of symbol table plus 1 00CF67 1 2E .byte $2E ; OBJECT first page of object code area 00CF68 1 00CF68 1 ; Set-up Filename And I/O Table 00CF68 1 A0 06 SETNAM: ldy #$06 00CF6A 1 B9 56 CF mvuade: lda UADEEE,y ; set up first part of filename to 'UADE' 00CF6D 1 99 40 01 sta strbuf,y ; in string buffer 00CF70 1 88 dey 00CF71 1 10 F7 bpl mvuade 00CF73 1 A9 40 lda #strbuf 00CF79 1 85 31 sta table+1 00CF7B 1 A5 2F lda fileid ; append save ID to filename 00CF7D 1 4A lsr a 00CF7E 1 4A lsr a 00CF7F 1 4A lsr a 00CF80 1 4A lsr a 00CF81 1 A8 tay 00CF82 1 B9 46 CF lda HEXTAB,y 00CF85 1 8D 44 01 sta strbuf+4 00CF88 1 A5 2F lda fileid 00CF8A 1 29 0F and #$0F 00CF8C 1 A8 tay 00CF8D 1 B9 46 CF lda HEXTAB,y 00CF90 1 8D 45 01 sta strbuf+5 00CF93 1 A2 30 ldx #table ; point X at I/O table 00CF95 1 60 rts 00CF96 1 00CF96 1 ; Set DOS Qualifier To X 00CF96 1 A0 04 SETUSE: ldy #$04 00CF98 1 B9 5D CF mvusex: lda USEX,y ; move USEX command to buffer 00CF9B 1 99 00 01 sta buffer,y 00CF9E 1 88 dey 00CF9F 1 10 F7 bpl mvusex 00CFA1 1 4C F7 FF jmp OSCLI ; and call OS Command Line Interpreter 00CFA4 1 00CFA4 1 ; Load File - set-up filename and I/O table 00CFA4 1 20 68 CF LOAD: jsr SETNAM ; set - use load address 00CFA7 1 85 34 sta table+4 00CFA9 1 38 sec ; wait until completion if DMA or interrupt 00CFAA 1 4C E0 FF jmp OSLOAD ; do load 00CFAD 1 00CFAD 1 ; Save File - set-up filename and I/O table 00CFAD 1 20 68 CF SAVE: jsr SETNAM 00CFB0 1 A9 39 lda #nxtcom 00CFB6 1 85 35 sta table+5 00CFB8 1 18 clc ; do not wait if DMA or interrupt 00CFB9 1 4C DD FF jmp OSSAVE ; do save 00CFBC 1 00CFBC 1 A2 00 ADE: ldx #$00 ; Output Start-up Message 00CFBE 1 BD CC CF outmes: lda mesage,x ; read character 00CFC1 1 20 E9 FF jsr OSASCI ; output 00CFC4 1 E8 inx ; increment pointer 00CFC5 1 E0 0B cpx #$0B ; end of message ? 00CFC7 1 D0 F5 bne outmes 00CFC9 1 4C 00 C0 jmp START ; enter ADE 00CFCC 1 00CFCC 1 0D 41 63 6F mesage: .byte CR,"Acorn ADE",CR 00CFD0 1 72 6E 20 41 00CFD4 1 44 45 0D 00CFD7 1 00CFD7 1 FF FF FF FF .byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF ; packing to fill EPROM 00CFDB 1 FF FF FF FF 00CFDF 1 FF FF FF FF .byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF 00CFE3 1 FF FF FF FF 00CFE7 1 FF FF FF FF .byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF 00CFEB 1 FF FF FF FF 00CFEF 1 FF FF FF FF .byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF 00CFF3 1 FF FF FF FF 00CFF7 1 FF FF FF FF .byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF 00CFFB 1 FF FF FF FF 00CFFF 1 FF .byte $FF 00D000 1 00D000 1