diff --git a/A1B-move/LICENSE-2.0.txt b/A1B-move/LICENSE-2.0.txt new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/A1B-move/LICENSE-2.0.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/A1B-move/a1basic.in b/A1B-move/a1basic.in new file mode 100644 index 0000000..6a9fc88 --- /dev/null +++ b/A1B-move/a1basic.in @@ -0,0 +1,2015 @@ +; Apple 1 BASIC +; +; Modifications to build with CC65 by Jeff Tranter +; +; Apple 1 BASIC was written by Steve Wozniak +; Uses disassembly copyright 2003 Eric Smith +; http://www.brouhaha.com/~eric/retrocomputing/apple/apple1/basic/ + +Z1d = $1D +ch = $24 ; horizontal cursor location +var = $48 +lomem = $4A ; lower limit of memory used by BASIC (2 bytes) +himem = $4C ; upper limit of memory used by BASIC (2 bytes) +rnd = $4E ; random number (2 bytes) + +; The noun stack and syntax stack appear to overlap, which is OK since +; they apparently are not used simultaneously. + +; The noun stack size appears to be 32 entries, based on LDX #$20 +; instruction at e67f. However, there seems to be enough room for +; another 8 entries. The noun stack builds down from noun_stk_+$1f +; to noun_stk_+$00, indexed by the X register. + +; Noun stack usage appears to be: +; integer: +; (noun_stk_h_int,noun_stk_l) = value +; noun_stk_h_str = 0 +; string: +; (noun_stk_h_str,noun_stk_l) = pointer to string +; noun_stk_h_int = any +; Since noun_stk_h_str determines whether stack entry is integer or string, +; strings can't start in zero page. + +noun_stk_l = $50 +syn_stk_h = $58 ; through $77 +noun_stk_h_str = $78 +syn_stk_l = $80 ; through $9F +noun_stk_h_int = $A0 +txtndxstk = $A8 ; through $C7 +text_index = $C8 ; index into text being tokenized (in buffer at $0200) +leadbl = $C9 ; leading blanks +pp = $CA ; pointer to end of program (2 bytes) +pv = $CC ; pointer to end of variable storage (2 bytes) +acc = $CE ; (2 bytes) +srch = $D0 +tokndxstk = $D1 +srch2 = $D2 +if_flag = $D4 +cr_flag = $D5 +current_verb = $D6 +precedence = $D7 +x_save = $D8 +run_flag = $D9 +aux = $DA +pline = $DC ; pointer to current program line (2 bytes) +pverb = $E0 ; pointer to current verb (2 bytes) +p1 = $E2 +p2 = $E4 +p3 = $E6 +token_index = $F1 ; pointer used to write tokens into buffer 2 bytes) +pcon = $F2 ; temp used in decimal output (2 bytes) +auto_inc = $F4 +auto_ln = $F6 +auto_flag = $F8 +char = $F9 +leadzr = $FA +for_nest_count = $FB ; count of active (nested) FOR loops +gosub_nest_count = $FC ; count of active (nested) subroutines calls (GOSUB) +synstkdx = $FD +synpag = $FE + +; GOSUB stack, max eight entries +; note that the Apple II version has sixteen entries +gstk_pverbl = $0100 ; saved pverb +gstk_pverbh = $0108 +gstk_plinel = $0110 ; saved pline +gstk_plineh = $0118 + +; FOR stack, max eight entries +; note that the Apple II version has sixteen entries +fstk_varl = $0120 ; pointer to index variable +fstk_varh = $0128 +fstk_stepl = $0130 ; step value +fstk_steph = $0138 +fstk_plinel = $0140 ; saved pline +fstk_plineh = $0148 +fstk_pverbl = $0150 ; saved pverb +fstk_pverbh = $0158 +fstk_tol = $0160 ; "to" (limit) value +fstk_toh = $0168 +buffer = $0200 +KBD = $D010 +KBDCR = $D011 +DSP = $D012 + + .org $E000 + .export START +START: JMP cold ; BASIC cold start entry point + +; Get character for keyboard, return in A. +rdkey: LDA KBDCR ; Read control register + BPL rdkey ; Loop if no key pressed + LDA KBD ; Read key data + RTS ; and return + +Se00c: TXA + AND #$20 + BEQ Le034 + +Se011: LDA #$A0 + STA p2 + JMP cout + +Se018: LDA #$20 + +Se01a: CMP ch + BCS nextbyte + LDA #$8D + LDY #$07 +Le022: JSR cout + LDA #$A0 + DEY + BNE Le022 + +nextbyte: LDY #$00 + LDA (p1),Y + INC p1 + BNE Le034 + INC p1+1 +Le034: RTS + +; token $75 - "," in LIST command +list_comman: JSR get16bit + JSR find_line2 +Le03b: LDA p1 + CMP p3 + LDA p1+1 + SBC p3+1 + BCS Le034 + JSR list_line + JMP Le03b + +; token $76 - LIST command w/ no args +list_all: LDA pp + STA p1 + LDA pp+1 + STA p1+1 + LDA himem + STA p3 + LDA himem+1 + STA p3+1 + BNE Le03b + +; token $74 - LIST command w/ line number(s) +list_cmd: JSR get16bit + JSR find_line + LDA p2 + STA p1 + LDA p2+1 + STA p1+1 + BCS Le034 + +; list one program line +list_line: STX x_save + LDA #$A0 + STA leadzr + JSR nextbyte + TYA + +; list an integer (line number or literal) +list_int: STA p2 + JSR nextbyte + TAX + JSR nextbyte + JSR prdec +Le083: JSR Se018 + STY leadzr + TAX + BPL list_token + ASL + BPL list_int + LDA p2 + BNE Le095 + JSR Se011 +Le095: TXA +Le096: JSR cout +Le099: LDA #$25 + JSR Se01a + TAX + BMI Le096 + STA p2 + +; list a single token +list_token: CMP #$01 + BNE Le0ac + LDX x_save + JMP crout +Le0ac: PHA + STY acc + LDX #$ED + STX acc+1 + CMP #$51 + BCC Le0bb + DEC acc+1 + SBC #$50 +Le0bb: PHA + LDA (acc),Y +Le0be: TAX + DEY + LDA (acc),Y + BPL Le0be + CPX #$C0 + BCS Le0cc + CPX #$00 + BMI Le0be +Le0cc: TAX + PLA + SBC #$01 + BNE Le0bb + BIT p2 + BMI Le0d9 + JSR Seff8 +Le0d9: LDA (acc),Y + BPL Le0ed + TAX + AND #$3F + STA p2 + CLC + ADC #$A0 + JSR cout + DEY + CPX #$C0 + BCC Le0d9 +Le0ed: JSR Se00c + PLA + CMP #$5D + BEQ Le099 + CMP #$28 + BNE Le083 + BEQ Le099 + +; token $2A - left paren for substring like A$(3,5) +paren_substr: JSR Se118 + STA noun_stk_l,X + CMP noun_stk_h_str,X +Le102: BCC Le115 +string_err: LDY #$2B +go_errmess_1: JMP print_err_msg + +; token $2B - comma for substring like A$(3,5) +comma_substr: JSR getbyte + CMP noun_stk_l,X + BCC string_err + JSR Sefe4 + STA noun_stk_h_str,X +Le115: JMP left_paren + +Se118: JSR getbyte + BEQ string_err + SEC + SBC #$01 + RTS + +; token $42 - left paren for string array as dest +; A$(1)="FOO" +str_arr_dest: JSR Se118 + STA noun_stk_l,X + CLC + SBC noun_stk_h_str,X + JMP Le102 +Le12c: LDY #$14 + BNE go_errmess_1 + +; token $43 - comma, next var in DIM statement is string +; token $4E - "DIM", next var in DIM is string +dim_str: JSR Se118 + INX +Le134: LDA noun_stk_l,X + STA aux + ADC acc + PHA + TAY + LDA noun_stk_h_str,X + STA aux+1 + ADC acc+1 + PHA + CPY pp + SBC pp+1 + BCS Le12c + LDA aux + ADC #$FE + STA aux + LDA #$FF + TAY + ADC aux+1 + STA aux+1 +Le156: INY + LDA (aux),Y + CMP pv,Y + BNE Le16d + TYA + BEQ Le156 +Le161: PLA + STA (aux),Y + STA pv,Y + DEY + BPL Le161 + INX + RTS + NOP +Le16d: LDY #$80 +Le16f: BNE go_errmess_1 + +; token ??? +input_str: LDA #$00 + JSR push_a_noun_stk + LDY #$02 + STY noun_stk_h_str,X + JSR push_a_noun_stk + LDA #$BF ; '?' + JSR cout + LDY #$00 + JSR read_line + STY noun_stk_h_str,X + NOP + NOP + NOP + +; token $70 - string literal +string_lit: LDA noun_stk_l+1,X + STA acc + LDA noun_stk_h_str+1,X + STA acc+1 + INX + INX + JSR Se1bc +Le199: LDA rnd,X + CMP syn_stk_h+30,X + BCS Le1b4 + INC rnd,X + TAY + LDA (acc),Y + LDY noun_stk_l,X + CPY p2 + BCC Le1ae + LDY #$83 + BNE Le16f +Le1ae: STA (aux),Y + INC noun_stk_l,X + BCC Le199 +Le1b4: LDY noun_stk_l,X + TXA + STA (aux),Y + INX + INX + RTS + +Se1bc: LDA noun_stk_l+1,X + STA aux + SEC + SBC #$02 + STA p2 + LDA noun_stk_h_str+1,X + STA aux+1 + SBC #$00 + STA p2+1 + LDY #$00 + LDA (p2),Y + CLC + SBC aux + STA p2 + RTS + +; token $39 - "=" for string equality operator +string_eq: LDA noun_stk_l+3,X + STA acc + LDA noun_stk_h_str+3,X + STA acc+1 + LDA noun_stk_l+1,X + STA aux + LDA noun_stk_h_str+1,X + STA aux+1 + INX + INX + INX + LDY #$00 + STY noun_stk_h_str,X + STY noun_stk_h_int,X + INY + STY noun_stk_l,X +Le1f3: LDA himem+1,X + CMP syn_stk_h+29,X + PHP + PHA + LDA rnd+1,X + CMP syn_stk_h+31,X + BCC Le206 + PLA + PLP + BCS Le205 +Le203: LSR noun_stk_l,X +Le205: RTS +Le206: TAY + LDA (acc),Y + STA p2 + PLA + TAY + PLP + BCS Le203 + LDA (aux),Y + CMP p2 + BNE Le203 + INC rnd+1,X + INC himem+1,X + BCS Le1f3 + +; token $3A - "#" for string inequality operator +string_neq: JSR string_eq + JMP not_op + +; token $14 - "*" for numeric multiplication +mult_op: JSR Se254 +Le225: ASL acc + ROL acc+1 + BCC Le238 + CLC + LDA p3 + ADC aux + STA p3 + LDA p3+1 + ADC aux+1 + STA p3+1 +Le238: DEY + BEQ Le244 + ASL p3 + ROL p3+1 + BPL Le225 + JMP Le77e +Le244: LDA p3 + JSR push_ya_noun_stk + LDA p3+1 + STA noun_stk_h_int,X + ASL p2+1 + BCC Le279 + JMP negate + +Se254: LDA #$55 + STA p2+1 + JSR Se25b + +Se25b: LDA acc + STA aux + LDA acc+1 + STA aux+1 + JSR get16bit + STY p3 + STY p3+1 + LDA acc+1 + BPL Le277 + DEX + ASL p2+1 + JSR negate + JSR get16bit +Le277: LDY #$10 +Le279: RTS + +; token $1f - "MOD" +mod_op: JSR See6c + BEQ Le244 + .byte $FF +Le280: CMP #$84 + BNE Le286 + LSR auto_flag +Le286: CMP #$DF + BEQ Le29b + CMP #$9B + BEQ Le294 + STA buffer,Y + INY + BPL read_line +Le294: LDY #$8B + JSR Se3c4 + +Se299: LDY #$01 +Le29b: DEY + BMI Le294 + +; read a line from keyboard (using rdkey) into buffer +read_line: JSR rdkey + NOP + NOP + JSR cout + CMP #$8D + BNE Le280 + LDA #$DF + STA buffer,Y + RTS +cold: JSR mem_init_4k + .export warm +warm: JSR crout ; BASIC warm start entry point +Le2b6: LSR run_flag + LDA #'>'+$80 ; Prompt character (high bit set) + JSR cout + LDY #$00 + STY leadzr + BIT auto_flag + BPL Le2d1 + LDX auto_ln + LDA auto_ln+1 + JSR prdec + LDA #$A0 + JSR cout +Le2d1: LDX #$FF + TXS + JSR read_line + STY token_index + TXA + STA text_index + LDX #$20 + JSR Se491 + LDA text_index + ADC #$00 + STA pverb + LDA #$00 + TAX + ADC #$02 + STA pverb+1 + LDA (pverb,X) + AND #$F0 + CMP #$B0 + BEQ Le2f9 + JMP Le883 +Le2f9: LDY #$02 +Le2fb: LDA (pverb),Y + STA pv+1,Y + DEY + BNE Le2fb + JSR Se38a + LDA token_index + SBC text_index + CMP #$04 + BEQ Le2b6 + STA (pverb),Y + LDA pp + SBC (pverb),Y + STA p2 + LDA pp+1 + SBC #$00 + STA p2+1 + LDA p2 + CMP pv + LDA p2+1 + SBC pv+1 + BCC Le36b +Le326: LDA pp + SBC (pverb),Y + STA p3 + LDA pp+1 + SBC #$00 + STA p3+1 + LDA (pp),Y + STA (p3),Y + INC pp + BNE Le33c + INC pp+1 +Le33c: LDA p1 + CMP pp + LDA p1+1 + SBC pp+1 + BCS Le326 +Le346: LDA p2,X + STA pp,X + DEX + BPL Le346 + LDA (pverb),Y + TAY +Le350: DEY + LDA (pverb),Y + STA (p3),Y + TYA + BNE Le350 + BIT auto_flag + BPL Le365 +Le35c: LDA auto_ln+1,X + ADC auto_inc+1,X + STA auto_ln+1,X + INX + BEQ Le35c +Le365: BPL Le3e5 + .byte $00,$00,$00,$00 +Le36b: LDY #$14 + BNE print_err_msg + +; token $0a - "," in DEL command +del_comma: JSR get16bit + LDA p1 + STA p3 + LDA p1+1 + STA p3+1 + JSR find_line1 + LDA p1 + STA p2 + LDA p1+1 + STA p2+1 + BNE Le395 + +; token $09 - "DEL" +del_cmd: JSR get16bit + +Se38a: JSR find_line + LDA p3 + STA p1 + LDA p3+1 + STA p1+1 +Le395: LDY #$00 +Le397: LDA pp + CMP p2 + LDA pp+1 + SBC p2+1 + BCS Le3b7 + LDA p2 + BNE Le3a7 + DEC p2+1 +Le3a7: DEC p2 + LDA p3 + BNE Le3af + DEC p3+1 +Le3af: DEC p3 + LDA (p2),Y + STA (p3),Y + BCC Le397 +Le3b7: LDA p3 + STA pp + LDA p3+1 + STA pp+1 + RTS +Le3c0: JSR cout + INY + +Se3c4: LDA error_msg_tbl,Y + BMI Le3c0 + +cout: CMP #$8D + BNE Le3d3 + +crout: LDA #$00 ; character output + STA ch + LDA #$8D +Le3d3: INC ch + +; Send character to display. Char is in A. +Le3d5: BIT DSP ; See if display ready + BMI Le3d5 ; Loop if not + STA DSP ; Write display data + RTS ; and return + +too_long_err: LDY #$06 + +print_err_msg: JSR print_err_msg1 ; print error message specified in Y + BIT run_flag +Le3e5: BMI Le3ea + JMP Le2b6 +Le3ea: JMP Leb9a +Le3ed: ROL + ADC #$A0 + CMP buffer,X + BNE Le448 + LDA (synpag),Y + ASL + BMI Le400 + DEY + LDA (synpag),Y + BMI Le428 + INY +Le400: STX text_index + TYA + PHA + LDX #$00 + LDA (synpag,X) + TAX +Le409: LSR + EOR #$48 + ORA (synpag),Y + CMP #$C0 + BCC Le413 + INX +Le413: INY + BNE Le409 + PLA + TAY + TXA + JMP Le4c0 + +; write a token to the buffer +; buffer [++tokndx] = A +put_token: INC token_index + LDX token_index + BEQ too_long_err + STA buffer,X +Le425: RTS +Le426: LDX text_index +Le428: LDA #$A0 +Le42a: INX + CMP buffer,X + BCS Le42a + LDA (synpag),Y + AND #$3F + LSR + BNE Le3ed + LDA buffer,X + BCS Le442 + ADC #$3F + CMP #$1A + BCC Le4b1 +Le442: ADC #$4F + CMP #$0A + BCC Le4b1 +Le448: LDX synstkdx +Le44a: INY + LDA (synpag),Y + AND #$E0 + CMP #$20 + BEQ Le4cd + LDA txtndxstk,X + STA text_index + LDA tokndxstk,X + STA token_index +Le45b: DEY + LDA (synpag),Y + ASL + BPL Le45b + DEY + BCS Le49c + ASL + BMI Le49c + LDY syn_stk_h,X + STY synpag+1 + LDY syn_stk_l,X + INX + BPL Le44a +Le470: BEQ Le425 + CMP #$7E + BCS Le498 + DEX + BPL Le47d + LDY #$06 + BPL go_errmess_2 +Le47d: STY syn_stk_l,X + LDY synpag+1 + STY syn_stk_h,X + LDY text_index + STY txtndxstk,X + LDY token_index + STY tokndxstk,X + AND #$1F + TAY + LDA syntabl_index,Y + +Se491: ASL + TAY + LDA #$76 + ROL + STA synpag+1 +Le498: BNE Le49b + INY +Le49b: INY +Le49c: STX synstkdx + LDA (synpag),Y + BMI Le426 + BNE Le4a9 + LDY #$0E +go_errmess_2: JMP print_err_msg +Le4a9: CMP #$03 + BCS Le470 + LSR + LDX text_index + INX +Le4b1: LDA buffer,X + BCC Le4ba + CMP #$A2 + BEQ Le4c4 +Le4ba: CMP #$DF + BEQ Le4c4 + STX text_index +Le4c0: JSR put_token + INY +Le4c4: DEY + LDX synstkdx +Le4c7: LDA (synpag),Y + DEY + ASL + BPL Le49c +Le4cd: LDY syn_stk_h,X + STY synpag+1 + LDY syn_stk_l,X + INX + LDA (synpag),Y + AND #$9F + BNE Le4c7 + STA pcon + STA pcon+1 + TYA + PHA + STX synstkdx + LDY srch,X + STY leadbl + CLC +Le4e7: LDA #$0A + STA char + LDX #$00 + INY + LDA buffer,Y + AND #$0F +Le4f3: ADC pcon + PHA + TXA + ADC pcon+1 + BMI Le517 + TAX + PLA + DEC char + BNE Le4f3 + STA pcon + STX pcon+1 + CPY token_index + BNE Le4e7 + LDY leadbl + INY + STY token_index + JSR put_token + PLA + TAY + LDA pcon+1 + BCS Le4c0 +Le517: LDY #$00 + BPL go_errmess_2 + +prdec: STA pcon+1 ; output A:X in decimal + STX pcon + LDX #$04 + STX leadbl +Le523: LDA #$B0 + STA char +Le527: LDA pcon + CMP dectabl,X + LDA pcon+1 + SBC dectabh,X + BCC Le540 + STA pcon+1 + LDA pcon + SBC dectabl,X + STA pcon + INC char + BNE Le527 +Le540: LDA char + INX + DEX + BEQ Le554 + CMP #$B0 + BEQ Le54c + STA leadbl +Le54c: BIT leadbl + BMI Le554 + LDA leadzr + BEQ Le55f +Le554: JSR cout + BIT auto_flag + BPL Le55f + STA buffer,Y + INY +Le55f: DEX + BPL Le523 + RTS +; powers of 10 table, low byte +dectabl: .byte $01,$0A,$64,$E8,$10 ; "..dh." + +; powers of 10 table, high byte +dectabh: .byte $00,$00,$00,$03,$27 ; "....'" + +find_line: LDA pp + STA p3 + LDA pp+1 + STA p3+1 + +find_line1: INX + +find_line2: LDA p3+1 + STA p2+1 + LDA p3 + STA p2 + CMP himem + LDA p2+1 + SBC himem+1 + BCS Le5ac + LDY #$01 + LDA (p2),Y + SBC acc + INY + LDA (p2),Y + SBC acc+1 + BCS Le5ac + LDY #$00 + LDA p3 + ADC (p2),Y + STA p3 + BCC Le5a0 + INC p3+1 + CLC +Le5a0: INY + LDA acc + SBC (p2),Y + INY + LDA acc+1 + SBC (p2),Y + BCS find_line2 +Le5ac: RTS + +; token $0B - "NEW" +new_cmd: LSR auto_flag + LDA himem + STA pp + LDA himem+1 + STA pp+1 + +; token $0C - "CLR" +clr: LDA lomem + STA pv + LDA lomem+1 + STA pv+1 + LDA #$00 + STA for_nest_count + STA gosub_nest_count + STA synpag + LDA #$00 + STA Z1d + RTS +Le5cc: LDA srch + ADC #$05 + STA srch2 + LDA tokndxstk + ADC #$00 + STA srch2+1 + LDA srch2 + CMP pp + LDA srch2+1 + SBC pp+1 + BCC Le5e5 + JMP Le36b +Le5e5: LDA acc + STA (srch),Y + LDA acc+1 + INY + STA (srch),Y + LDA srch2 + INY + STA (srch),Y + LDA srch2+1 + INY + STA (srch),Y + LDA #$00 + INY + STA (srch),Y + INY + STA (srch),Y + LDA srch2 + STA pv + LDA srch2+1 + STA pv+1 + LDA srch + BCC Le64f +execute_var: STA acc + STY acc+1 + JSR get_next_prog_byte + BMI Le623 + CMP #$40 + BEQ Le623 + JMP Le628 + .byte $06,$C9,$49,$D0,$07,$A9,$49 +Le623: STA acc+1 + JSR get_next_prog_byte +Le628: LDA lomem+1 + STA tokndxstk + LDA lomem +Le62e: STA srch + CMP pv + LDA tokndxstk + SBC pv+1 + BCS Le5cc + LDA (srch),Y + INY + CMP acc + BNE Le645 + LDA (srch),Y + CMP acc+1 + BEQ Le653 +Le645: INY + LDA (srch),Y + PHA + INY + LDA (srch),Y + STA tokndxstk + PLA +Le64f: LDY #$00 + BEQ Le62e +Le653: LDA srch + ADC #$03 + JSR push_a_noun_stk + LDA tokndxstk + ADC #$00 + STA noun_stk_h_str,X + LDA acc+1 + CMP #$40 + BNE fetch_prog_byte + DEY + TYA + JSR push_a_noun_stk + DEY + STY noun_stk_h_str,X + LDY #$03 +Le670: INC noun_stk_h_str,X + INY + LDA (srch),Y + BMI Le670 + BPL fetch_prog_byte + +execute_stmt: LDA #$00 + STA if_flag + STA cr_flag + LDX #$20 + +; push old verb on stack for later use in precedence test +push_old_verb: PHA +fetch_prog_byte: LDY #$00 + LDA (pverb),Y +Le686: BPL execute_token + ASL + BMI execute_var + JSR get_next_prog_byte + JSR push_ya_noun_stk + JSR get_next_prog_byte + STA noun_stk_h_int,X +Le696: BIT if_flag + BPL Le69b + DEX +Le69b: JSR get_next_prog_byte + BCS Le686 + +execute_token: CMP #$28 + BNE execute_verb + LDA pverb + JSR push_a_noun_stk + LDA pverb+1 + STA noun_stk_h_str,X + BIT if_flag + BMI Le6bc + LDA #$01 + JSR push_a_noun_stk + LDA #$00 + STA noun_stk_h_str,X +Le6ba: INC noun_stk_h_str,X +Le6bc: JSR get_next_prog_byte + BMI Le6ba + BCS Le696 +execute_verb: BIT if_flag + BPL Le6cd + CMP #$04 + BCS Le69b + LSR if_flag +Le6cd: TAY + STA current_verb + LDA verb_prec_tbl,Y + AND #$55 + ASL + STA precedence +Le6d8: PLA + TAY + LDA verb_prec_tbl,Y + AND #$AA + CMP precedence + BCS do_verb + TYA + PHA + JSR get_next_prog_byte + LDA current_verb + BCC push_old_verb +do_verb: LDA verb_adr_l,Y + STA acc + LDA verb_adr_h,Y + STA acc+1 + JSR Se6fc + JMP Le6d8 + +Se6fc: JMP (acc) + +get_next_prog_byte: INC pverb + BNE Le705 + INC pverb+1 +Le705: LDA (pverb),Y + RTS + +push_ya_noun_stk: STY syn_stk_h+31,X + +push_a_noun_stk: DEX + BMI Le710 + STA noun_stk_l,X + RTS +Le710: LDY #$66 +go_errmess_3: JMP print_err_msg + +get16bit: LDY #$00 + LDA noun_stk_l,X + STA acc + LDA noun_stk_h_int,X + STA acc+1 + LDA noun_stk_h_str,X + BEQ Le731 + STA acc+1 + LDA (acc),Y + PHA + INY + LDA (acc),Y + STA acc+1 + PLA + STA acc + DEY +Le731: INX + RTS + +; token $16 - "=" for numeric equality operator +eq_op: JSR neq_op + +; token $37 - "NOT" +not_op: JSR get16bit + TYA + JSR push_ya_noun_stk + STA noun_stk_h_int,X + CMP acc + BNE Le749 + CMP acc+1 + BNE Le749 + INC noun_stk_l,X +Le749: RTS + +; token $17 - "#" for numeric inequality operator +; token $1B - "<>" for numeric inequality operator +neq_op: JSR subtract + JSR sgn_fn + +; token $31 - "ABS" +abs_fn: JSR get16bit + BIT acc+1 + BMI Se772 +Le757: DEX +Le758: RTS + +; token $30 - "SGN" +sgn_fn: JSR get16bit + LDA acc+1 + BNE Le764 + LDA acc + BEQ Le757 +Le764: LDA #$FF + JSR push_ya_noun_stk + STA noun_stk_h_int,X + BIT acc+1 + BMI Le758 + +; token $36 - "-" for unary negation +negate: JSR get16bit + +Se772: TYA + SEC + SBC acc + JSR push_ya_noun_stk + TYA + SBC acc+1 + BVC Le7a1 +Le77e: LDY #$00 + BPL go_errmess_3 + +; token $13 - "-" for numeric subtraction +subtract: JSR negate + +; token $12 - "+" for numeric addition +add: JSR get16bit + LDA acc + STA aux + LDA acc+1 + STA aux+1 + JSR get16bit + +Se793: CLC + LDA acc + ADC aux + JSR push_ya_noun_stk + LDA acc+1 + ADC aux+1 + BVS Le77e +Le7a1: STA noun_stk_h_int,X + +; token $35 - "+" for unary positive +unary_pos: RTS + +; token $50 - "TAB" function +tab_fn: JSR get16bit + LDY acc + BEQ Le7b0 + DEY + LDA acc+1 + BEQ Le7bc +Le7b0: RTS + +; horizontal tab +tabout: LDA ch + ORA #$07 + TAY + INY +Le7b7: LDA #$A0 + JSR cout +Le7bc: CPY ch + BCS Le7b7 + RTS + +; token $49 - "," in print, numeric follows +print_com_num: JSR tabout + +; token $62 - "PRINT" numeric +print_num: JSR get16bit + LDA acc+1 + BPL Le7d5 + LDA #$AD + JSR cout + JSR Se772 + BVC print_num +Le7d5: DEY + STY cr_flag + STX acc+1 + LDX acc + JSR prdec + LDX acc+1 + RTS + +; token $0D - "AUTO" command +auto_cmd: JSR get16bit + LDA acc + STA auto_ln + LDA acc+1 + STA auto_ln+1 + DEY + STY auto_flag + INY + LDA #$0A +Le7f3: STA auto_inc + STY auto_inc+1 + RTS + +; token $0E - "," in AUTO command +auto_com: JSR get16bit + LDA acc + LDY acc+1 + BPL Le7f3 + +; token $56 - "=" in FOR statement +; token $71 - "=" in LET (or implied LET) statement +var_assign: JSR get16bit + LDA noun_stk_l,X + STA aux + LDA noun_stk_h_str,X + STA aux+1 + LDA acc + STA (aux),Y + INY + LDA acc+1 + STA (aux),Y + INX + +Te816: RTS + +; token $00 - begining of line +begin_line: + PLA + PLA + +; token $03 - ":" statement separator +colon: BIT cr_flag + BPL Le822 + +; token $63 - "PRINT" with no arg +print_cr: JSR crout + +; token $47 - ";" at end of print statement +print_semi: LSR cr_flag +Le822: RTS + + +; token $22 - "(" in string DIM +; token $34 - "(" in numeric DIM +; token $38 - "(" in numeric expression +; token $3F - "(" in some PEEK, RND, SGN, ABS (PDL) +left_paren: LDY #$FF + STY precedence + +; token $72 - ")" everywhere +right_paren: RTS + +; token $60 - "IF" statement +if_stmt: JSR Sefcd + BEQ Le834 + LDA #$25 + STA current_verb + DEY + STY if_flag +Le834: INX + RTS +; RUN without CLR, used by Apple DOS +run_warm: LDA pp + LDY pp+1 + BNE Le896 + +; token $5C - "GOSUB" statement +gosub_stmt: LDY #$41 + LDA gosub_nest_count + CMP #$08 + BCS go_errmess_4 + TAY + INC gosub_nest_count + LDA pverb + STA gstk_pverbl,Y + LDA pverb+1 + STA gstk_pverbh,Y + LDA pline + STA gstk_plinel,Y + LDA pline+1 + STA gstk_plineh,Y + +; token $24 - "THEN" +; token $5F - "GOTO" statement +goto_stmt: JSR get16bit + JSR find_line + BCC Le867 + LDY #$37 + BNE go_errmess_4 +Le867: LDA p2 + LDY p2+1 + +; loop to run a program +run_loop: STA pline + STY pline+1 + BIT KBDCR + BMI Le8c3 + CLC + ADC #$03 + BCC Le87a + INY +Le87a: LDX #$FF + STX run_flag + TXS + STA pverb + STY pverb+1 +Le883: JSR execute_stmt + BIT run_flag + BPL end_stmt + CLC + LDY #$00 + LDA pline + ADC (pline),Y + LDY pline+1 + BCC Le896 + INY +Le896: CMP himem + BNE run_loop + CPY himem+1 + BNE run_loop + LDY #$34 + LSR run_flag +go_errmess_4: JMP print_err_msg + +; token $5B - "RETURN" statement +return_stmt: LDY #$4A + LDA gosub_nest_count + BEQ go_errmess_4 + DEC gosub_nest_count + TAY + LDA gstk_plinel-1,Y + STA pline + LDA gstk_plineh-1,Y + STA pline+1 + LDX a:synpag+1,Y ; force absolute addressing mode + LDA gstk_pverbh-1,Y +Le8be: TAY + TXA + JMP Le87a +Le8c3: LDY #$63 + JSR Se3c4 + LDY #$01 + LDA (pline),Y + TAX + INY + LDA (pline),Y + JSR prdec + +; token $51 - "END" statement +end_stmt: JMP warm +Le8d6: DEC for_nest_count + +; token $59 - "NEXT" statement +; token $5A - "," in NEXT statement +next_stmt: LDY #$5B + LDA for_nest_count +Le8dc: BEQ go_errmess_4 + TAY + LDA noun_stk_l,X + CMP fstk_varl-1,Y + BNE Le8d6 + LDA noun_stk_h_str,X + CMP fstk_varh-1,Y + BNE Le8d6 + LDA fstk_stepl-1,Y + STA aux + LDA fstk_steph-1,Y + STA aux+1 + JSR get16bit + DEX + JSR Se793 + JSR var_assign + DEX + LDY for_nest_count + LDA fstk_toh-1,Y + STA syn_stk_l+31,X + LDA fstk_tol-1,Y + LDY #$00 + JSR push_ya_noun_stk + JSR subtract + JSR sgn_fn + JSR get16bit + LDY for_nest_count + LDA acc + BEQ Le925 + EOR fstk_steph-1,Y + BPL Le937 +Le925: LDA fstk_plinel-1,Y + STA pline + LDA fstk_plineh-1,Y + STA pline+1 + LDX fstk_pverbl-1,Y + LDA fstk_pverbh-1,Y + BNE Le8be +Le937: DEC for_nest_count + RTS + +; token $55 - "FOR" statement +for_stmt: LDY #$54 + LDA for_nest_count + CMP #$08 + BEQ Le8dc + INC for_nest_count + TAY + LDA noun_stk_l,X + STA fstk_varl,Y + LDA noun_stk_h_str,X + STA fstk_varh,Y + RTS + +; token $57 - "TO" +to_clause: JSR get16bit + LDY for_nest_count + LDA acc + STA fstk_tol-1,Y + LDA acc+1 + STA fstk_toh-1,Y + LDA #$01 + STA fstk_stepl-1,Y + LDA #$00 +Le966: STA fstk_steph-1,Y + LDA pline + STA fstk_plinel-1,Y + LDA pline+1 + STA fstk_plineh-1,Y + LDA pverb + STA fstk_pverbl-1,Y + LDA pverb+1 + STA fstk_pverbh-1,Y + RTS + +Te97e: JSR get16bit + LDY for_nest_count + LDA acc + STA fstk_stepl-1,Y + LDA acc+1 + JMP Le966 + .byte $00,$00,$00,$00,$00,$00,$00,$00 ; "........" + .byte $00,$00,$00 ; "..." + +; verb precedence +; (verb_prec[token]&0xAA)>>1 for left (?) +; verb_prec[token]&0x55 for right (?) +verb_prec_tbl: + .byte $00,$00,$00,$AB,$03,$03,$03,$03 ; "...+...." + .byte $03,$03,$03,$03,$03,$03,$03,$03 ; "........" + .byte $03,$03,$3F,$3F,$C0,$C0,$3C,$3C ; "..??@@<<" + .byte $3C,$3C,$3C,$3C,$3C,$30,$0F,$C0 ; "<<<<<0.@" + .byte $CC,$FF,$55,$00,$AB,$AB,$03,$03 ; "L.U.++.." + .byte $FF,$FF,$55,$FF,$FF,$55,$CF,$CF ; "..U..UOO" + .byte $CF,$CF,$CF,$FF,$55,$C3,$C3,$C3 ; "OOO.UCCC" + .byte $55,$F0,$F0,$CF,$56,$56,$56,$55 ; "UppOVVVU" + .byte $FF,$FF,$55,$03,$03,$03,$03,$03 ; "..U....." + .byte $03,$03,$FF,$FF,$FF,$03,$03,$03 ; "........" + .byte $03,$03,$03,$03,$03,$03,$03,$03 ; "........" + .byte $03,$03,$03,$03,$03,$00,$AB,$03 ; "......+." + .byte $57,$03,$03,$03,$03,$07,$03,$03 ; "W......." + .byte $03,$03,$03,$03,$03,$03,$03,$03 ; "........" + .byte $03,$03,$AA,$FF,$FF,$FF,$FF,$FF ; "..*....." +verb_adr_l: + .byte $17,$FF,$FF,$19,$5D,$35,$4B,$F2 ; "....]5Kr" + .byte $EC,$87,$6F,$AD,$B7,$E2,$F8,$54 ; "l.o-7bxT" + .byte $80,$96,$85,$82,$22,$10,$33,$4A ; "....".3J" + .byte $13,$06,$0B,$4A,$01,$40,$47,$7A ; "...J.@Gz" + .byte $00,$FF,$23,$09,$5B,$16,$B6,$CB ; "..#.[.6K" + .byte $FF,$FF,$FB,$FF,$FF,$24,$F6,$4E ; "..{..$vN" + .byte $59,$50,$00,$FF,$23,$A3,$6F,$36 ; "YP..##o6" + .byte $23,$D7,$1C,$22,$C2,$AE,$BA,$23 ; "#W."B.:#" + .byte $FF,$FF,$21,$30,$1E,$03,$C4,$20 ; "..!0..D " + .byte $00,$C1,$FF,$FF,$FF,$A0,$30,$1E ; ".A... 0." + .byte $A4,$D3,$B6,$BC,$AA,$3A,$01,$50 ; "$S6<*:.P" + .byte $7E,$D8,$D8,$A5,$3C,$FF,$16,$5B ; "~XX%<..[" + .byte $28,$03,$C4,$1D,$00,$0C,$4E,$00 ; "(.D...N." + .byte $3E,$00,$A6,$B0,$00,$BC,$C6,$57 ; ">.&0.32767" + .byte $D4,$CF,$CF,$A0,$CC,$CF,$CE,$47 ; "TOO LONG" + .byte $D3,$D9,$CE,$D4,$C1,$58 ; "SYNTAX" + .byte $CD,$C5,$CD,$A0,$C6,$D5,$CC,$4C ; "MEM FULL" + .byte $D4,$CF,$CF,$A0,$CD,$C1,$CE,$D9,$A0,$D0,$C1,$D2,$C5,$CE,$53 ; "TOO MANY PARENS" + .byte $D3,$D4,$D2,$C9,$CE,$47 ; "STRING" + .byte $CE,$CF,$A0,$C5,$CE,$44 ; "NO END" + .byte $C2,$C1,$C4,$A0,$C2,$D2,$C1,$CE,$C3,$48 ; "BAD BRANCH" + .byte $BE,$B8,$A0,$C7,$CF,$D3,$D5,$C2,$53 ; ">8 GOSUBS" + .byte $C2,$C1,$C4,$A0,$D2,$C5,$D4,$D5,$D2,$4E ; "BAD RETURN" + .byte $BE,$B8,$A0,$C6,$CF,$D2,$53 ; ">8 FORS" + .byte $C2,$C1,$C4,$A0,$CE,$C5,$D8,$54 ; "BAD NEXT" + .byte $D3,$D4,$CF,$D0,$D0,$C5,$C4,$A0,$C1,$D4,$20 ; "STOPPED AT " + .byte $AA,$AA,$AA,$20 ; "*** " + .byte $A0,$C5,$D2,$D2,$0D ; " ERR.\n" + .byte $BE,$B2,$B5,$35 ; ">255" + .byte $D2,$C1,$CE,$C7,$45 ; RANGE" + .byte $C4,$C9,$4D ; "DIM" + .byte $D3,$D4,$D2,$A0,$CF,$D6,$C6,$4C ; "STR OVFL" + .byte $DC,$0D ; "\\\n" + .byte $D2,$C5,$D4,$D9,$D0,$C5,$A0,$CC,$C9,$CE,$C5,$8D ; "RETYPE LINE\n" + .byte $3F ; "?" +Leb9a: LSR run_flag + BCC Leba1 + JMP Le8c3 +Leba1: LDX acc+1 + TXS + LDX acc + LDY #$8D + BNE Lebac + +; token $54 - "INPUT" statement, numeric, no prompt +input_num_stmt: LDY #$99 +Lebac: JSR Se3c4 + STX acc + TSX + STX acc+1 + LDY #$FE + STY run_flag + INY + STY text_index + JSR Se299 + STY token_index + LDX #$20 + LDA #$30 + JSR Se491 + INC run_flag + LDX acc + +; token $27 - "," numeric input +input_num_comma: LDY text_index + ASL +Lebce: STA acc + INY + LDA buffer,Y + CMP #$74 + BEQ input_num_stmt + EOR #$B0 + CMP #$0A + BCS Lebce + INY + INY + STY text_index + LDA buffer,Y + PHA + LDA buffer-1,Y + LDY #$00 + JSR push_ya_noun_stk + PLA + STA noun_stk_h_int,X + LDA acc + CMP #$C7 + BNE Lebfa + JSR negate +Lebfa: JMP var_assign + + .byte $FF,$FF,$FF,$50 + +Tec01: JSR Tec13 + BNE Lec1b + +Tec06: JSR Tec0b + BNE Lec1b + +Tec0b: JSR subtract + JSR negate + BVC Lec16 + +Tec13: JSR subtract +Lec16: JSR sgn_fn + LSR noun_stk_l,X +Lec1b: JMP not_op + + .byte $FF,$FF + +; indexes into syntabl +syntabl_index: + .byte $C1,$FF,$7F,$D1,$CC,$C7,$CF,$CE ; "A..QLGON" + .byte $C5,$9A,$98,$8B,$96,$95,$93,$BF ; "E......?" + .byte $B2,$32,$2D,$2B,$BC,$B0,$AC,$BE ; "22-+<0,>" + .byte $35,$8E,$61,$FF,$FF,$FF,$DD,$FB ; "5.a...]{" + +Tec40: JSR Sefc9 + ORA rnd+1,X + BPL Lec4c + +Tec47: JSR Sefc9 + AND rnd+1,X +Lec4c: STA noun_stk_l,X + BPL Lec1b + JMP Sefc9 + .byte $40,$60,$8D,$60,$8B,$00,$7E,$8C ; "@`.`..~." + .byte $33,$00,$00,$60,$03,$BF,$12,$00 ; "3..`.?.." + .byte $40,$89,$C9,$47,$9D,$17,$68,$9D ; "@.IG..h." + .byte $0A,$00,$40,$60,$8D,$60,$8B,$00 ; "..@`.`.." + .byte $7E,$8C,$3C,$00,$00,$60,$03,$BF ; "~.<..`.?" + .byte $1B,$4B,$67,$B4,$A1,$07,$8C,$07 ; ".Kg4!..." + .byte $AE,$A9,$AC,$A8,$67,$8C,$07,$B4 ; ".),(g..4" + .byte $AF,$AC,$B0,$67,$9D,$B2,$AF,$AC ; "/,0g.2/," + .byte $AF,$A3,$67,$8C,$07,$A5,$AB,$AF ; "/#g..%+/" + .byte $B0,$F4,$AE,$A9,$B2,$B0,$7F,$0E ; "0t.)20.." + .byte $27,$B4,$AE,$A9,$B2,$B0,$7F,$0E ; "'4.)20.." + .byte $28,$B4,$AE,$A9,$B2,$B0,$64,$07 ; "(4.)20d." + .byte $A6,$A9,$67,$AF,$B4,$AF,$A7,$78 ; "&)g/4/'x" + .byte $B4,$A5,$AC,$78,$7F,$02,$AD,$A5 ; "4%,x..-%" + .byte $B2,$67,$A2,$B5,$B3,$AF,$A7,$EE ; "2g"53/'n" + .byte $B2,$B5,$B4,$A5,$B2,$7E,$8C,$39 ; "254%2~.9" + .byte $B4,$B8,$A5,$AE,$67,$B0,$A5,$B4 ; "48%.g0%4" + .byte $B3,$27,$AF,$B4,$07,$9D,$19,$B2 ; "3'/4...2" + .byte $AF,$A6,$7F,$05,$37,$B4,$B5,$B0 ; "/&..7450" + .byte $AE,$A9,$7F,$05,$28,$B4,$B5,$B0 ; ".)..(450" + .byte $AE,$A9,$7F,$05,$2A,$B4,$B5,$B0 ; ".)..*450" + .byte $AE,$A9,$E4,$AE,$A5,$00,$FF,$FF ; ".)d.%..." +syntabl2: + .byte $47,$A2,$A1,$B4,$7F,$0D,$30,$AD ; "G"!4..0-" + .byte $A9,$A4,$7F,$0D,$23,$AD,$A9,$A4 ; ")$..#-)$" + .byte $67,$AC,$AC,$A1,$A3,$00,$40,$80 ; "g,,!#.@." + .byte $C0,$C1,$80,$00,$47,$8C,$68,$8C ; "@A..G.h." + .byte $DB,$67,$9B,$68,$9B,$50,$8C,$63 ; "[g.h.P.c" + .byte $8C,$7F,$01,$51,$07,$88,$29,$84 ; "...Q..)." + .byte $80,$C4,$80,$57,$71,$07,$88,$14 ; ".D.Wq..." + .byte $ED,$A5,$AD,$AF,$AC,$ED,$A5,$AD ; "m%-/,m%-" + .byte $A9,$A8,$F2,$AF,$AC,$AF,$A3,$71 ; ")(r/,/#q" + .byte $08,$88,$AE,$A5,$AC,$68,$83,$08 ; "...%,h.." + .byte $68,$9D,$08,$71,$07,$88,$60,$76 ; "h..q..`v" + .byte $B4,$AF,$AE,$76,$8D,$76,$8B,$51 ; "4/.v.v.Q" + .byte $07,$88,$19,$B8,$A4,$AE,$B2,$F2 ; "...8$.2r" + .byte $B3,$B5,$F3,$A2,$A1,$EE,$A7,$B3 ; "35s"!n'3" + .byte $E4,$AE,$B2,$EB,$A5,$A5,$B0,$51 ; "d.2k%%0Q" + .byte $07,$88,$39,$81,$C1,$4F,$7F,$0F ; "..9.AO.." + .byte $2F,$00,$51,$06,$88,$29,$C2,$0C ; "/.Q..)B." + .byte $82,$57,$8C,$6A,$8C,$42,$AE,$A5 ; ".W.j.B.%" + .byte $A8,$B4,$60,$AE,$A5,$A8,$B4,$4F ; "(4`.%(4O" + .byte $7E,$1E,$35,$8C,$27,$51,$07,$88 ; "~.5.'Q.." + .byte $09,$8B,$FE,$E4,$AF,$AD,$F2,$AF ; "..~d/-r/" + .byte $E4,$AE,$A1,$DC,$DE,$9C,$DD,$9C ; "d.!\^.]." + .byte $DE,$DD,$9E,$C3,$DD,$CF,$CA,$CD ; "^].C]OJM" + .byte $CB,$00,$47,$9D,$AD,$A5,$AD,$AF ; "K.G.-%-/" + .byte $AC,$76,$9D,$AD,$A5,$AD,$A9,$A8 ; ",v.-%-)(" + .byte $E6,$A6,$AF,$60,$8C,$20,$AF,$B4 ; "f&/`. /4" + .byte $B5,$A1,$F2,$AC,$A3,$F2,$A3,$B3 ; "5!r,#r#3" + .byte $60,$8C,$20,$AC,$A5,$A4,$EE,$B5 ; "`. ,%$n5" + .byte $B2,$60,$AE,$B5,$B2,$F4,$B3,$A9 ; "2`.52t3)" + .byte $AC,$60,$8C,$20,$B4,$B3,$A9,$AC ; ",`. 43)," + .byte $7A,$7E,$9A,$22,$20,$00,$60,$03 ; "z~." .`." + .byte $BF,$60,$03,$BF,$1F ; "?`.?." + +; token $48 - "," string output +print_str_comma: JSR tabout + +; token $45 - ";" string output +; token $61 - "PRINT" string +print_str: INX + INX + LDA rnd+1,X + STA aux + LDA syn_stk_h+31,X + STA aux+1 + LDY rnd,X +Lee0f: TYA + CMP syn_stk_h+30,X + BCS Lee1d + LDA (aux),Y + JSR cout + INY + JMP Lee0f +Lee1d: LDA #$FF + STA cr_flag + RTS + +; token $3B - "LEN(" function +len_fn: INX + LDA #$00 + STA noun_stk_h_str,X + STA noun_stk_h_int,X + LDA syn_stk_h+31,X + SEC + SBC rnd+1,X + STA noun_stk_l,X + JMP left_paren + + .byte $FF + +getbyte: JSR get16bit + LDA acc+1 + BNE gr_255_err + LDA acc + RTS + +; token $68 - "," for PLOT statement (???) +plot_comma: JSR getbyte + LDY text_index + CMP #$30 + BCS range_err + CPY #$28 + BCS range_err + RTS + NOP + NOP + +Tee4e: JSR getbyte + RTS + NOP +Tee5e: TXA + LDX #$01 +l123: LDY acc,X + STY himem,X + LDY var,X + STY pp,X + DEX + BEQ l123 + TAX + RTS +gr_255_err: LDY #$77 ; > 255 error +go_errmess_5: JMP print_err_msg +range_err: LDY #$7B ; range error + BNE go_errmess_5 + +See6c: JSR Se254 + LDA aux + BNE Lee7a + LDA aux+1 + BNE Lee7a + JMP Le77e +Lee7a: ASL acc + ROL acc+1 + ROL p3 + ROL p3+1 + LDA p3 + CMP aux + LDA p3+1 + SBC aux+1 + BCC Lee96 + STA p3+1 + LDA p3 + SBC aux + STA p3 + INC acc +Lee96: DEY + BNE Lee7a + RTS + + .byte $FF,$FF,$FF,$FF,$FF,$FF + +; token $4D - "CALL" statement +call_stmt: JSR get16bit + JMP (acc) +l1233: LDA himem + BNE l1235 + DEC himem+1 +l1235: DEC himem + LDA var + BNE l1236 + DEC var+1 +l1236: DEC var +l1237: LDY #$00 + LDA (himem),Y + STA (var),Y + LDA pp + CMP himem + LDA pp+1 + SBC himem+1 + BCC l1233 + JMP Tee5e + CMP #$28 +Leecb: BCS range_err + TAY + LDA text_index + RTS + NOP + NOP + +print_err_msg1: + TYA + TAX + LDY #$6E + JSR Se3c4 + TXA + TAY + JSR Se3c4 + LDY #$72 + JMP Se3c4 + +Seee4: JSR get16bit +Leee7: ASL acc + ROL acc+1 + BMI Leee7 + BCS Leecb + BNE Leef5 + CMP acc + BCS Leecb +Leef5: RTS + +; token $2E - "PEEK" fn (uses $3F left paren) +peek_fn: JSR get16bit + LDA (acc),Y + STY syn_stk_l+31,X + JMP push_ya_noun_stk + +; token $65 - "," for POKE statement +poke_stmt: JSR getbyte + LDA acc + PHA + JSR get16bit + PLA + STA (acc),Y + +Tef0c: RTS + + .byte $FF,$FF,$FF + +; token $15 - "/" for numeric division +divide: JSR See6c + LDA acc + STA p3 + LDA acc+1 + STA p3+1 + JMP Le244 + +; token $44 - "," next var in DIM statement is numeric +; token $4F - "DIM", next var is numeric +dim_num: JSR Seee4 + JMP Le134 + +; token $2D - "(" for numeric array subscript +num_array_subs: JSR Seee4 + LDY noun_stk_h_str,X + LDA noun_stk_l,X + ADC #$FE + BCS Lef30 + DEY +Lef30: STA aux + STY aux+1 + CLC + ADC acc + STA noun_stk_l,X + TYA + ADC acc+1 + STA noun_stk_h_str,X + LDY #$00 + LDA noun_stk_l,X + CMP (aux),Y + INY + LDA noun_stk_h_str,X + SBC (aux),Y + BCS Leecb + JMP left_paren + +; token $2F - "RND" fn (uses $3F left paren) +rnd_fn: JSR get16bit + LDA rnd + JSR push_ya_noun_stk + LDA rnd+1 + BNE Lef5e + CMP rnd + ADC #$00 +Lef5e: AND #$7F + STA rnd+1 + STA noun_stk_h_int,X + LDY #$11 +Lef66: LDA rnd+1 + ASL + CLC + ADC #$40 + ASL + ROL rnd + ROL rnd+1 + DEY + BNE Lef66 + LDA acc + JSR push_ya_noun_stk + LDA acc+1 + STA noun_stk_h_int,X + JMP mod_op + +Tef80: JSR get16bit + LDY acc + CPY himem + LDA acc+1 + SBC himem+1 + BCC Lefab + STY var + LDA acc+1 + STA var+1 +Lef93: JMP l1237 + +Tef96: JSR get16bit + LDY acc + CPY pp + LDA acc+1 + SBC pp+1 + BCS Lefab + STY lomem + LDA acc+1 + STA lomem+1 + JMP clr +Lefab: JMP Leecb + NOP + NOP + NOP + NOP +Lefb3: JSR Sefc9 + +; token $26 - "," for string input +; token $52 - "INPUT" statement for string +string_input: JSR input_str + JMP Lefbf + +; token $53 - "INPUT" with literal string prompt +input_prompt: JSR print_str +Lefbf: LDA #$FF + STA text_index + LDA #$74 + STA buffer + RTS + +Sefc9: JSR not_op + INX + +Sefcd: JSR not_op + LDA noun_stk_l,X + RTS + +; memory initialization for 4K RAM +mem_init_4k: LDA #$00 + STA lomem + STA himem + LDA #$08 + STA lomem+1 ; LOMEM defaults to $0800 + LDA #$10 + STA himem+1 ; HIMEM defaults to $1000 + JMP new_cmd + +Sefe4: CMP noun_stk_h_str,X + BNE Lefe9 + CLC +Lefe9: JMP Le102 + +Tefec: JSR clr + JMP run_warm + +Teff2: JSR clr + JMP goto_stmt + +Seff8: CPX #$80 + BNE Leffd + DEY +Leffd: JMP Se00c diff --git a/A1B-move/a1basic.mod b/A1B-move/a1basic.mod new file mode 100644 index 0000000..2454ebf --- /dev/null +++ b/A1B-move/a1basic.mod @@ -0,0 +1,44 @@ +# Apple 1 Integer BASIC Relocator +# +# *=$E000 +# +# Page Zero Pointer Definitions +# 56 +# 57 +# 58 +# 59 +# +# Origin +96 +# +# Hard Coded Pointer +200 +# 721 Not sure but breaks when changed +# 875 Powers of 10 table +# 1515 Verb Table (low byte) +1530 +1531 +1532 +1533 +1534 +1535 +1536 +1537 +1538 +1539 +1540 +1541 +1542 +1543 +1544 +# +# Syntax table follows +# 1673 +# 1680 +# 1689 +# 1695 +# 1696 +# 1702 +# 1703 +# 1707 +# 1709 diff --git a/A1B-move/a1basic.out b/A1B-move/a1basic.out new file mode 100644 index 0000000..7bb7c20 --- /dev/null +++ b/A1B-move/a1basic.out @@ -0,0 +1,2015 @@ +; Apple 1 BASIC +; +; Modifications to build with CC65 by Jeff Tranter +; +; Apple 1 BASIC was written by Steve Wozniak +; Uses disassembly copyright 2003 Eric Smith +; http://www.brouhaha.com/~eric/retrocomputing/apple/apple1/basic/ + +Z1d = $1D +ch = $24 ; horizontal cursor location +var = $48 +lomem = $4A ; lower limit of memory used by BASIC (2 bytes) +himem = $4C ; upper limit of memory used by BASIC (2 bytes) +rnd = $4E ; random number (2 bytes) + +; The noun stack and syntax stack appear to overlap, which is OK since +; they apparently are not used simultaneously. + +; The noun stack size appears to be 32 entries, based on LDX #$20 +; instruction at e67f. However, there seems to be enough room for +; another 8 entries. The noun stack builds down from noun_stk_+$1f +; to noun_stk_+$00, indexed by the X register. + +; Noun stack usage appears to be: +; integer: +; (noun_stk_h_int,noun_stk_l) = value +; noun_stk_h_str = 0 +; string: +; (noun_stk_h_str,noun_stk_l) = pointer to string +; noun_stk_h_int = any +; Since noun_stk_h_str determines whether stack entry is integer or string, +; strings can't start in zero page. + +noun_stk_l = $50 +syn_stk_h = $58 ; through $77 +noun_stk_h_str = $78 +syn_stk_l = $80 ; through $9F +noun_stk_h_int = $A0 +txtndxstk = $A8 ; through $C7 +text_index = $C8 ; index into text being tokenized (in buffer at $0200) +leadbl = $C9 ; leading blanks +pp = $CA ; pointer to end of program (2 bytes) +pv = $CC ; pointer to end of variable storage (2 bytes) +acc = $CE ; (2 bytes) +srch = $D0 +tokndxstk = $D1 +srch2 = $D2 +if_flag = $D4 +cr_flag = $D5 +current_verb = $D6 +precedence = $D7 +x_save = $D8 +run_flag = $D9 +aux = $DA +pline = $DC ; pointer to current program line (2 bytes) +pverb = $E0 ; pointer to current verb (2 bytes) +p1 = $E2 +p2 = $E4 +p3 = $E6 +token_index = $F1 ; pointer used to write tokens into buffer 2 bytes) +pcon = $F2 ; temp used in decimal output (2 bytes) +auto_inc = $F4 +auto_ln = $F6 +auto_flag = $F8 +char = $F9 +leadzr = $FA +for_nest_count = $FB ; count of active (nested) FOR loops +gosub_nest_count = $FC ; count of active (nested) subroutines calls (GOSUB) +synstkdx = $FD +synpag = $FE + +; GOSUB stack, max eight entries +; note that the Apple II version has sixteen entries +gstk_pverbl = $0100 ; saved pverb +gstk_pverbh = $0108 +gstk_plinel = $0110 ; saved pline +gstk_plineh = $0118 + +; FOR stack, max eight entries +; note that the Apple II version has sixteen entries +fstk_varl = $0120 ; pointer to index variable +fstk_varh = $0128 +fstk_stepl = $0130 ; step value +fstk_steph = $0138 +fstk_plinel = $0140 ; saved pline +fstk_plineh = $0148 +fstk_pverbl = $0150 ; saved pverb +fstk_pverbh = $0158 +fstk_tol = $0160 ; "to" (limit) value +fstk_toh = $0168 +buffer = $0200 +KBD = $D010 +KBDCR = $D011 +DSP = $D012 + + .org $A000 + .export START +START: JMP cold ; BASIC cold start entry point + +; Get character for keyboard, return in A. +rdkey: LDA KBDCR ; Read control register + BPL rdkey ; Loop if no key pressed + LDA KBD ; Read key data + RTS ; and return + +Se00c: TXA + AND #$20 + BEQ Le034 + +Se011: LDA #$A0 + STA p2 + JMP cout + +Se018: LDA #$20 + +Se01a: CMP ch + BCS nextbyte + LDA #$8D + LDY #$07 +Le022: JSR cout + LDA #$A0 + DEY + BNE Le022 + +nextbyte: LDY #$00 + LDA (p1),Y + INC p1 + BNE Le034 + INC p1+1 +Le034: RTS + +; token $75 - "," in LIST command +list_comman: JSR get16bit + JSR find_line2 +Le03b: LDA p1 + CMP p3 + LDA p1+1 + SBC p3+1 + BCS Le034 + JSR list_line + JMP Le03b + +; token $76 - LIST command w/ no args +list_all: LDA pp + STA p1 + LDA pp+1 + STA p1+1 + LDA himem + STA p3 + LDA himem+1 + STA p3+1 + BNE Le03b + +; token $74 - LIST command w/ line number(s) +list_cmd: JSR get16bit + JSR find_line + LDA p2 + STA p1 + LDA p2+1 + STA p1+1 + BCS Le034 + +; list one program line +list_line: STX x_save + LDA #$A0 + STA leadzr + JSR nextbyte + TYA + +; list an integer (line number or literal) +list_int: STA p2 + JSR nextbyte + TAX + JSR nextbyte + JSR prdec +Le083: JSR Se018 + STY leadzr + TAX + BPL list_token + ASL + BPL list_int + LDA p2 + BNE Le095 + JSR Se011 +Le095: TXA +Le096: JSR cout +Le099: LDA #$25 + JSR Se01a + TAX + BMI Le096 + STA p2 + +; list a single token +list_token: CMP #$01 + BNE Le0ac + LDX x_save + JMP crout +Le0ac: PHA + STY acc + LDX #$AD + STX acc+1 + CMP #$51 + BCC Le0bb + DEC acc+1 + SBC #$50 +Le0bb: PHA + LDA (acc),Y +Le0be: TAX + DEY + LDA (acc),Y + BPL Le0be + CPX #$C0 + BCS Le0cc + CPX #$00 + BMI Le0be +Le0cc: TAX + PLA + SBC #$01 + BNE Le0bb + BIT p2 + BMI Le0d9 + JSR Seff8 +Le0d9: LDA (acc),Y + BPL Le0ed + TAX + AND #$3F + STA p2 + CLC + ADC #$A0 + JSR cout + DEY + CPX #$C0 + BCC Le0d9 +Le0ed: JSR Se00c + PLA + CMP #$5D + BEQ Le099 + CMP #$28 + BNE Le083 + BEQ Le099 + +; token $2A - left paren for substring like A$(3,5) +paren_substr: JSR Se118 + STA noun_stk_l,X + CMP noun_stk_h_str,X +Le102: BCC Le115 +string_err: LDY #$2B +go_errmess_1: JMP print_err_msg + +; token $2B - comma for substring like A$(3,5) +comma_substr: JSR getbyte + CMP noun_stk_l,X + BCC string_err + JSR Sefe4 + STA noun_stk_h_str,X +Le115: JMP left_paren + +Se118: JSR getbyte + BEQ string_err + SEC + SBC #$01 + RTS + +; token $42 - left paren for string array as dest +; A$(1)="FOO" +str_arr_dest: JSR Se118 + STA noun_stk_l,X + CLC + SBC noun_stk_h_str,X + JMP Le102 +Le12c: LDY #$14 + BNE go_errmess_1 + +; token $43 - comma, next var in DIM statement is string +; token $4E - "DIM", next var in DIM is string +dim_str: JSR Se118 + INX +Le134: LDA noun_stk_l,X + STA aux + ADC acc + PHA + TAY + LDA noun_stk_h_str,X + STA aux+1 + ADC acc+1 + PHA + CPY pp + SBC pp+1 + BCS Le12c + LDA aux + ADC #$FE + STA aux + LDA #$FF + TAY + ADC aux+1 + STA aux+1 +Le156: INY + LDA (aux),Y + CMP pv,Y + BNE Le16d + TYA + BEQ Le156 +Le161: PLA + STA (aux),Y + STA pv,Y + DEY + BPL Le161 + INX + RTS + NOP +Le16d: LDY #$80 +Le16f: BNE go_errmess_1 + +; token ??? +input_str: LDA #$00 + JSR push_a_noun_stk + LDY #$02 + STY noun_stk_h_str,X + JSR push_a_noun_stk + LDA #$BF ; '?' + JSR cout + LDY #$00 + JSR read_line + STY noun_stk_h_str,X + NOP + NOP + NOP + +; token $70 - string literal +string_lit: LDA noun_stk_l+1,X + STA acc + LDA noun_stk_h_str+1,X + STA acc+1 + INX + INX + JSR Se1bc +Le199: LDA rnd,X + CMP syn_stk_h+30,X + BCS Le1b4 + INC rnd,X + TAY + LDA (acc),Y + LDY noun_stk_l,X + CPY p2 + BCC Le1ae + LDY #$83 + BNE Le16f +Le1ae: STA (aux),Y + INC noun_stk_l,X + BCC Le199 +Le1b4: LDY noun_stk_l,X + TXA + STA (aux),Y + INX + INX + RTS + +Se1bc: LDA noun_stk_l+1,X + STA aux + SEC + SBC #$02 + STA p2 + LDA noun_stk_h_str+1,X + STA aux+1 + SBC #$00 + STA p2+1 + LDY #$00 + LDA (p2),Y + CLC + SBC aux + STA p2 + RTS + +; token $39 - "=" for string equality operator +string_eq: LDA noun_stk_l+3,X + STA acc + LDA noun_stk_h_str+3,X + STA acc+1 + LDA noun_stk_l+1,X + STA aux + LDA noun_stk_h_str+1,X + STA aux+1 + INX + INX + INX + LDY #$00 + STY noun_stk_h_str,X + STY noun_stk_h_int,X + INY + STY noun_stk_l,X +Le1f3: LDA himem+1,X + CMP syn_stk_h+29,X + PHP + PHA + LDA rnd+1,X + CMP syn_stk_h+31,X + BCC Le206 + PLA + PLP + BCS Le205 +Le203: LSR noun_stk_l,X +Le205: RTS +Le206: TAY + LDA (acc),Y + STA p2 + PLA + TAY + PLP + BCS Le203 + LDA (aux),Y + CMP p2 + BNE Le203 + INC rnd+1,X + INC himem+1,X + BCS Le1f3 + +; token $3A - "#" for string inequality operator +string_neq: JSR string_eq + JMP not_op + +; token $14 - "*" for numeric multiplication +mult_op: JSR Se254 +Le225: ASL acc + ROL acc+1 + BCC Le238 + CLC + LDA p3 + ADC aux + STA p3 + LDA p3+1 + ADC aux+1 + STA p3+1 +Le238: DEY + BEQ Le244 + ASL p3 + ROL p3+1 + BPL Le225 + JMP Le77e +Le244: LDA p3 + JSR push_ya_noun_stk + LDA p3+1 + STA noun_stk_h_int,X + ASL p2+1 + BCC Le279 + JMP negate + +Se254: LDA #$55 + STA p2+1 + JSR Se25b + +Se25b: LDA acc + STA aux + LDA acc+1 + STA aux+1 + JSR get16bit + STY p3 + STY p3+1 + LDA acc+1 + BPL Le277 + DEX + ASL p2+1 + JSR negate + JSR get16bit +Le277: LDY #$10 +Le279: RTS + +; token $1f - "MOD" +mod_op: JSR See6c + BEQ Le244 + .byte $FF +Le280: CMP #$84 + BNE Le286 + LSR auto_flag +Le286: CMP #$DF + BEQ Le29b + CMP #$9B + BEQ Le294 + STA buffer,Y + INY + BPL read_line +Le294: LDY #$8B + JSR Se3c4 + +Se299: LDY #$01 +Le29b: DEY + BMI Le294 + +; read a line from keyboard (using rdkey) into buffer +read_line: JSR rdkey + NOP + NOP + JSR cout + CMP #$8D + BNE Le280 + LDA #$DF + STA buffer,Y + RTS +cold: JSR mem_init_4k + .export warm +warm: JSR crout ; BASIC warm start entry point +Le2b6: LSR run_flag + LDA #'>'+$80 ; Prompt character (high bit set) + JSR cout + LDY #$00 + STY leadzr + BIT auto_flag + BPL Le2d1 + LDX auto_ln + LDA auto_ln+1 + JSR prdec + LDA #$A0 + JSR cout +Le2d1: LDX #$FF + TXS + JSR read_line + STY token_index + TXA + STA text_index + LDX #$20 + JSR Se491 + LDA text_index + ADC #$00 + STA pverb + LDA #$00 + TAX + ADC #$02 + STA pverb+1 + LDA (pverb,X) + AND #$F0 + CMP #$B0 + BEQ Le2f9 + JMP Le883 +Le2f9: LDY #$02 +Le2fb: LDA (pverb),Y + STA pv+1,Y + DEY + BNE Le2fb + JSR Se38a + LDA token_index + SBC text_index + CMP #$04 + BEQ Le2b6 + STA (pverb),Y + LDA pp + SBC (pverb),Y + STA p2 + LDA pp+1 + SBC #$00 + STA p2+1 + LDA p2 + CMP pv + LDA p2+1 + SBC pv+1 + BCC Le36b +Le326: LDA pp + SBC (pverb),Y + STA p3 + LDA pp+1 + SBC #$00 + STA p3+1 + LDA (pp),Y + STA (p3),Y + INC pp + BNE Le33c + INC pp+1 +Le33c: LDA p1 + CMP pp + LDA p1+1 + SBC pp+1 + BCS Le326 +Le346: LDA p2,X + STA pp,X + DEX + BPL Le346 + LDA (pverb),Y + TAY +Le350: DEY + LDA (pverb),Y + STA (p3),Y + TYA + BNE Le350 + BIT auto_flag + BPL Le365 +Le35c: LDA auto_ln+1,X + ADC auto_inc+1,X + STA auto_ln+1,X + INX + BEQ Le35c +Le365: BPL Le3e5 + .byte $00,$00,$00,$00 +Le36b: LDY #$14 + BNE print_err_msg + +; token $0a - "," in DEL command +del_comma: JSR get16bit + LDA p1 + STA p3 + LDA p1+1 + STA p3+1 + JSR find_line1 + LDA p1 + STA p2 + LDA p1+1 + STA p2+1 + BNE Le395 + +; token $09 - "DEL" +del_cmd: JSR get16bit + +Se38a: JSR find_line + LDA p3 + STA p1 + LDA p3+1 + STA p1+1 +Le395: LDY #$00 +Le397: LDA pp + CMP p2 + LDA pp+1 + SBC p2+1 + BCS Le3b7 + LDA p2 + BNE Le3a7 + DEC p2+1 +Le3a7: DEC p2 + LDA p3 + BNE Le3af + DEC p3+1 +Le3af: DEC p3 + LDA (p2),Y + STA (p3),Y + BCC Le397 +Le3b7: LDA p3 + STA pp + LDA p3+1 + STA pp+1 + RTS +Le3c0: JSR cout + INY + +Se3c4: LDA error_msg_tbl,Y + BMI Le3c0 + +cout: CMP #$8D + BNE Le3d3 + +crout: LDA #$00 ; character output + STA ch + LDA #$8D +Le3d3: INC ch + +; Send character to display. Char is in A. +Le3d5: BIT DSP ; See if display ready + BMI Le3d5 ; Loop if not + STA DSP ; Write display data + RTS ; and return + +too_long_err: LDY #$06 + +print_err_msg: JSR print_err_msg1 ; print error message specified in Y + BIT run_flag +Le3e5: BMI Le3ea + JMP Le2b6 +Le3ea: JMP Leb9a +Le3ed: ROL + ADC #$A0 + CMP buffer,X + BNE Le448 + LDA (synpag),Y + ASL + BMI Le400 + DEY + LDA (synpag),Y + BMI Le428 + INY +Le400: STX text_index + TYA + PHA + LDX #$00 + LDA (synpag,X) + TAX +Le409: LSR + EOR #$48 + ORA (synpag),Y + CMP #$C0 + BCC Le413 + INX +Le413: INY + BNE Le409 + PLA + TAY + TXA + JMP Le4c0 + +; write a token to the buffer +; buffer [++tokndx] = A +put_token: INC token_index + LDX token_index + BEQ too_long_err + STA buffer,X +Le425: RTS +Le426: LDX text_index +Le428: LDA #$A0 +Le42a: INX + CMP buffer,X + BCS Le42a + LDA (synpag),Y + AND #$3F + LSR + BNE Le3ed + LDA buffer,X + BCS Le442 + ADC #$3F + CMP #$1A + BCC Le4b1 +Le442: ADC #$4F + CMP #$0A + BCC Le4b1 +Le448: LDX synstkdx +Le44a: INY + LDA (synpag),Y + AND #$E0 + CMP #$20 + BEQ Le4cd + LDA txtndxstk,X + STA text_index + LDA tokndxstk,X + STA token_index +Le45b: DEY + LDA (synpag),Y + ASL + BPL Le45b + DEY + BCS Le49c + ASL + BMI Le49c + LDY syn_stk_h,X + STY synpag+1 + LDY syn_stk_l,X + INX + BPL Le44a +Le470: BEQ Le425 + CMP #$7E + BCS Le498 + DEX + BPL Le47d + LDY #$06 + BPL go_errmess_2 +Le47d: STY syn_stk_l,X + LDY synpag+1 + STY syn_stk_h,X + LDY text_index + STY txtndxstk,X + LDY token_index + STY tokndxstk,X + AND #$1F + TAY + LDA syntabl_index,Y + +Se491: ASL + TAY + LDA #$56 ; Manual Change by W4JBM + ROL + STA synpag+1 +Le498: BNE Le49b + INY +Le49b: INY +Le49c: STX synstkdx + LDA (synpag),Y + BMI Le426 + BNE Le4a9 + LDY #$0E +go_errmess_2: JMP print_err_msg +Le4a9: CMP #$03 + BCS Le470 + LSR + LDX text_index + INX +Le4b1: LDA buffer,X + BCC Le4ba + CMP #$A2 + BEQ Le4c4 +Le4ba: CMP #$DF + BEQ Le4c4 + STX text_index +Le4c0: JSR put_token + INY +Le4c4: DEY + LDX synstkdx +Le4c7: LDA (synpag),Y + DEY + ASL + BPL Le49c +Le4cd: LDY syn_stk_h,X + STY synpag+1 + LDY syn_stk_l,X + INX + LDA (synpag),Y + AND #$9F + BNE Le4c7 + STA pcon + STA pcon+1 + TYA + PHA + STX synstkdx + LDY srch,X + STY leadbl + CLC +Le4e7: LDA #$0A + STA char + LDX #$00 + INY + LDA buffer,Y + AND #$0F +Le4f3: ADC pcon + PHA + TXA + ADC pcon+1 + BMI Le517 + TAX + PLA + DEC char + BNE Le4f3 + STA pcon + STX pcon+1 + CPY token_index + BNE Le4e7 + LDY leadbl + INY + STY token_index + JSR put_token + PLA + TAY + LDA pcon+1 + BCS Le4c0 +Le517: LDY #$00 + BPL go_errmess_2 + +prdec: STA pcon+1 ; output A:X in decimal + STX pcon + LDX #$04 + STX leadbl +Le523: LDA #$B0 + STA char +Le527: LDA pcon + CMP dectabl,X + LDA pcon+1 + SBC dectabh,X + BCC Le540 + STA pcon+1 + LDA pcon + SBC dectabl,X + STA pcon + INC char + BNE Le527 +Le540: LDA char + INX + DEX + BEQ Le554 + CMP #$B0 + BEQ Le54c + STA leadbl +Le54c: BIT leadbl + BMI Le554 + LDA leadzr + BEQ Le55f +Le554: JSR cout + BIT auto_flag + BPL Le55f + STA buffer,Y + INY +Le55f: DEX + BPL Le523 + RTS +; powers of 10 table, low byte +dectabl: .byte $01,$0A,$64,$E8,$10 ; "..dh." + +; powers of 10 table, high byte +dectabh: .byte $00,$00,$00,$03,$27 ; "....'" + +find_line: LDA pp + STA p3 + LDA pp+1 + STA p3+1 + +find_line1: INX + +find_line2: LDA p3+1 + STA p2+1 + LDA p3 + STA p2 + CMP himem + LDA p2+1 + SBC himem+1 + BCS Le5ac + LDY #$01 + LDA (p2),Y + SBC acc + INY + LDA (p2),Y + SBC acc+1 + BCS Le5ac + LDY #$00 + LDA p3 + ADC (p2),Y + STA p3 + BCC Le5a0 + INC p3+1 + CLC +Le5a0: INY + LDA acc + SBC (p2),Y + INY + LDA acc+1 + SBC (p2),Y + BCS find_line2 +Le5ac: RTS + +; token $0B - "NEW" +new_cmd: LSR auto_flag + LDA himem + STA pp + LDA himem+1 + STA pp+1 + +; token $0C - "CLR" +clr: LDA lomem + STA pv + LDA lomem+1 + STA pv+1 + LDA #$00 + STA for_nest_count + STA gosub_nest_count + STA synpag + LDA #$00 + STA Z1d + RTS +Le5cc: LDA srch + ADC #$05 + STA srch2 + LDA tokndxstk + ADC #$00 + STA srch2+1 + LDA srch2 + CMP pp + LDA srch2+1 + SBC pp+1 + BCC Le5e5 + JMP Le36b +Le5e5: LDA acc + STA (srch),Y + LDA acc+1 + INY + STA (srch),Y + LDA srch2 + INY + STA (srch),Y + LDA srch2+1 + INY + STA (srch),Y + LDA #$00 + INY + STA (srch),Y + INY + STA (srch),Y + LDA srch2 + STA pv + LDA srch2+1 + STA pv+1 + LDA srch + BCC Le64f +execute_var: STA acc + STY acc+1 + JSR get_next_prog_byte + BMI Le623 + CMP #$40 + BEQ Le623 + JMP Le628 + .byte $06,$C9,$49,$D0,$07,$A9,$49 +Le623: STA acc+1 + JSR get_next_prog_byte +Le628: LDA lomem+1 + STA tokndxstk + LDA lomem +Le62e: STA srch + CMP pv + LDA tokndxstk + SBC pv+1 + BCS Le5cc + LDA (srch),Y + INY + CMP acc + BNE Le645 + LDA (srch),Y + CMP acc+1 + BEQ Le653 +Le645: INY + LDA (srch),Y + PHA + INY + LDA (srch),Y + STA tokndxstk + PLA +Le64f: LDY #$00 + BEQ Le62e +Le653: LDA srch + ADC #$03 + JSR push_a_noun_stk + LDA tokndxstk + ADC #$00 + STA noun_stk_h_str,X + LDA acc+1 + CMP #$40 + BNE fetch_prog_byte + DEY + TYA + JSR push_a_noun_stk + DEY + STY noun_stk_h_str,X + LDY #$03 +Le670: INC noun_stk_h_str,X + INY + LDA (srch),Y + BMI Le670 + BPL fetch_prog_byte + +execute_stmt: LDA #$00 + STA if_flag + STA cr_flag + LDX #$20 + +; push old verb on stack for later use in precedence test +push_old_verb: PHA +fetch_prog_byte: LDY #$00 + LDA (pverb),Y +Le686: BPL execute_token + ASL + BMI execute_var + JSR get_next_prog_byte + JSR push_ya_noun_stk + JSR get_next_prog_byte + STA noun_stk_h_int,X +Le696: BIT if_flag + BPL Le69b + DEX +Le69b: JSR get_next_prog_byte + BCS Le686 + +execute_token: CMP #$28 + BNE execute_verb + LDA pverb + JSR push_a_noun_stk + LDA pverb+1 + STA noun_stk_h_str,X + BIT if_flag + BMI Le6bc + LDA #$01 + JSR push_a_noun_stk + LDA #$00 + STA noun_stk_h_str,X +Le6ba: INC noun_stk_h_str,X +Le6bc: JSR get_next_prog_byte + BMI Le6ba + BCS Le696 +execute_verb: BIT if_flag + BPL Le6cd + CMP #$04 + BCS Le69b + LSR if_flag +Le6cd: TAY + STA current_verb + LDA verb_prec_tbl,Y + AND #$55 + ASL + STA precedence +Le6d8: PLA + TAY + LDA verb_prec_tbl,Y + AND #$AA + CMP precedence + BCS do_verb + TYA + PHA + JSR get_next_prog_byte + LDA current_verb + BCC push_old_verb +do_verb: LDA verb_adr_l,Y + STA acc + LDA verb_adr_h,Y + STA acc+1 + JSR Se6fc + JMP Le6d8 + +Se6fc: JMP (acc) + +get_next_prog_byte: INC pverb + BNE Le705 + INC pverb+1 +Le705: LDA (pverb),Y + RTS + +push_ya_noun_stk: STY syn_stk_h+31,X + +push_a_noun_stk: DEX + BMI Le710 + STA noun_stk_l,X + RTS +Le710: LDY #$66 +go_errmess_3: JMP print_err_msg + +get16bit: LDY #$00 + LDA noun_stk_l,X + STA acc + LDA noun_stk_h_int,X + STA acc+1 + LDA noun_stk_h_str,X + BEQ Le731 + STA acc+1 + LDA (acc),Y + PHA + INY + LDA (acc),Y + STA acc+1 + PLA + STA acc + DEY +Le731: INX + RTS + +; token $16 - "=" for numeric equality operator +eq_op: JSR neq_op + +; token $37 - "NOT" +not_op: JSR get16bit + TYA + JSR push_ya_noun_stk + STA noun_stk_h_int,X + CMP acc + BNE Le749 + CMP acc+1 + BNE Le749 + INC noun_stk_l,X +Le749: RTS + +; token $17 - "#" for numeric inequality operator +; token $1B - "<>" for numeric inequality operator +neq_op: JSR subtract + JSR sgn_fn + +; token $31 - "ABS" +abs_fn: JSR get16bit + BIT acc+1 + BMI Se772 +Le757: DEX +Le758: RTS + +; token $30 - "SGN" +sgn_fn: JSR get16bit + LDA acc+1 + BNE Le764 + LDA acc + BEQ Le757 +Le764: LDA #$FF + JSR push_ya_noun_stk + STA noun_stk_h_int,X + BIT acc+1 + BMI Le758 + +; token $36 - "-" for unary negation +negate: JSR get16bit + +Se772: TYA + SEC + SBC acc + JSR push_ya_noun_stk + TYA + SBC acc+1 + BVC Le7a1 +Le77e: LDY #$00 + BPL go_errmess_3 + +; token $13 - "-" for numeric subtraction +subtract: JSR negate + +; token $12 - "+" for numeric addition +add: JSR get16bit + LDA acc + STA aux + LDA acc+1 + STA aux+1 + JSR get16bit + +Se793: CLC + LDA acc + ADC aux + JSR push_ya_noun_stk + LDA acc+1 + ADC aux+1 + BVS Le77e +Le7a1: STA noun_stk_h_int,X + +; token $35 - "+" for unary positive +unary_pos: RTS + +; token $50 - "TAB" function +tab_fn: JSR get16bit + LDY acc + BEQ Le7b0 + DEY + LDA acc+1 + BEQ Le7bc +Le7b0: RTS + +; horizontal tab +tabout: LDA ch + ORA #$07 + TAY + INY +Le7b7: LDA #$A0 + JSR cout +Le7bc: CPY ch + BCS Le7b7 + RTS + +; token $49 - "," in print, numeric follows +print_com_num: JSR tabout + +; token $62 - "PRINT" numeric +print_num: JSR get16bit + LDA acc+1 + BPL Le7d5 + LDA #$AD + JSR cout + JSR Se772 + BVC print_num +Le7d5: DEY + STY cr_flag + STX acc+1 + LDX acc + JSR prdec + LDX acc+1 + RTS + +; token $0D - "AUTO" command +auto_cmd: JSR get16bit + LDA acc + STA auto_ln + LDA acc+1 + STA auto_ln+1 + DEY + STY auto_flag + INY + LDA #$0A +Le7f3: STA auto_inc + STY auto_inc+1 + RTS + +; token $0E - "," in AUTO command +auto_com: JSR get16bit + LDA acc + LDY acc+1 + BPL Le7f3 + +; token $56 - "=" in FOR statement +; token $71 - "=" in LET (or implied LET) statement +var_assign: JSR get16bit + LDA noun_stk_l,X + STA aux + LDA noun_stk_h_str,X + STA aux+1 + LDA acc + STA (aux),Y + INY + LDA acc+1 + STA (aux),Y + INX + +Te816: RTS + +; token $00 - begining of line +begin_line: + PLA + PLA + +; token $03 - ":" statement separator +colon: BIT cr_flag + BPL Le822 + +; token $63 - "PRINT" with no arg +print_cr: JSR crout + +; token $47 - ";" at end of print statement +print_semi: LSR cr_flag +Le822: RTS + + +; token $22 - "(" in string DIM +; token $34 - "(" in numeric DIM +; token $38 - "(" in numeric expression +; token $3F - "(" in some PEEK, RND, SGN, ABS (PDL) +left_paren: LDY #$FF + STY precedence + +; token $72 - ")" everywhere +right_paren: RTS + +; token $60 - "IF" statement +if_stmt: JSR Sefcd + BEQ Le834 + LDA #$25 + STA current_verb + DEY + STY if_flag +Le834: INX + RTS +; RUN without CLR, used by Apple DOS +run_warm: LDA pp + LDY pp+1 + BNE Le896 + +; token $5C - "GOSUB" statement +gosub_stmt: LDY #$41 + LDA gosub_nest_count + CMP #$08 + BCS go_errmess_4 + TAY + INC gosub_nest_count + LDA pverb + STA gstk_pverbl,Y + LDA pverb+1 + STA gstk_pverbh,Y + LDA pline + STA gstk_plinel,Y + LDA pline+1 + STA gstk_plineh,Y + +; token $24 - "THEN" +; token $5F - "GOTO" statement +goto_stmt: JSR get16bit + JSR find_line + BCC Le867 + LDY #$37 + BNE go_errmess_4 +Le867: LDA p2 + LDY p2+1 + +; loop to run a program +run_loop: STA pline + STY pline+1 + BIT KBDCR + BMI Le8c3 + CLC + ADC #$03 + BCC Le87a + INY +Le87a: LDX #$FF + STX run_flag + TXS + STA pverb + STY pverb+1 +Le883: JSR execute_stmt + BIT run_flag + BPL end_stmt + CLC + LDY #$00 + LDA pline + ADC (pline),Y + LDY pline+1 + BCC Le896 + INY +Le896: CMP himem + BNE run_loop + CPY himem+1 + BNE run_loop + LDY #$34 + LSR run_flag +go_errmess_4: JMP print_err_msg + +; token $5B - "RETURN" statement +return_stmt: LDY #$4A + LDA gosub_nest_count + BEQ go_errmess_4 + DEC gosub_nest_count + TAY + LDA gstk_plinel-1,Y + STA pline + LDA gstk_plineh-1,Y + STA pline+1 + LDX a:synpag+1,Y ; force absolute addressing mode + LDA gstk_pverbh-1,Y +Le8be: TAY + TXA + JMP Le87a +Le8c3: LDY #$63 + JSR Se3c4 + LDY #$01 + LDA (pline),Y + TAX + INY + LDA (pline),Y + JSR prdec + +; token $51 - "END" statement +end_stmt: JMP warm +Le8d6: DEC for_nest_count + +; token $59 - "NEXT" statement +; token $5A - "," in NEXT statement +next_stmt: LDY #$5B + LDA for_nest_count +Le8dc: BEQ go_errmess_4 + TAY + LDA noun_stk_l,X + CMP fstk_varl-1,Y + BNE Le8d6 + LDA noun_stk_h_str,X + CMP fstk_varh-1,Y + BNE Le8d6 + LDA fstk_stepl-1,Y + STA aux + LDA fstk_steph-1,Y + STA aux+1 + JSR get16bit + DEX + JSR Se793 + JSR var_assign + DEX + LDY for_nest_count + LDA fstk_toh-1,Y + STA syn_stk_l+31,X + LDA fstk_tol-1,Y + LDY #$00 + JSR push_ya_noun_stk + JSR subtract + JSR sgn_fn + JSR get16bit + LDY for_nest_count + LDA acc + BEQ Le925 + EOR fstk_steph-1,Y + BPL Le937 +Le925: LDA fstk_plinel-1,Y + STA pline + LDA fstk_plineh-1,Y + STA pline+1 + LDX fstk_pverbl-1,Y + LDA fstk_pverbh-1,Y + BNE Le8be +Le937: DEC for_nest_count + RTS + +; token $55 - "FOR" statement +for_stmt: LDY #$54 + LDA for_nest_count + CMP #$08 + BEQ Le8dc + INC for_nest_count + TAY + LDA noun_stk_l,X + STA fstk_varl,Y + LDA noun_stk_h_str,X + STA fstk_varh,Y + RTS + +; token $57 - "TO" +to_clause: JSR get16bit + LDY for_nest_count + LDA acc + STA fstk_tol-1,Y + LDA acc+1 + STA fstk_toh-1,Y + LDA #$01 + STA fstk_stepl-1,Y + LDA #$00 +Le966: STA fstk_steph-1,Y + LDA pline + STA fstk_plinel-1,Y + LDA pline+1 + STA fstk_plineh-1,Y + LDA pverb + STA fstk_pverbl-1,Y + LDA pverb+1 + STA fstk_pverbh-1,Y + RTS + +Te97e: JSR get16bit + LDY for_nest_count + LDA acc + STA fstk_stepl-1,Y + LDA acc+1 + JMP Le966 + .byte $00,$00,$00,$00,$00,$00,$00,$00 ; "........" + .byte $00,$00,$00 ; "..." + +; verb precedence +; (verb_prec[token]&0xAA)>>1 for left (?) +; verb_prec[token]&0x55 for right (?) +verb_prec_tbl: + .byte $00,$00,$00,$AB,$03,$03,$03,$03 ; "...+...." + .byte $03,$03,$03,$03,$03,$03,$03,$03 ; "........" + .byte $03,$03,$3F,$3F,$C0,$C0,$3C,$3C ; "..??@@<<" + .byte $3C,$3C,$3C,$3C,$3C,$30,$0F,$C0 ; "<<<<<0.@" + .byte $CC,$FF,$55,$00,$AB,$AB,$03,$03 ; "L.U.++.." + .byte $FF,$FF,$55,$FF,$FF,$55,$CF,$CF ; "..U..UOO" + .byte $CF,$CF,$CF,$FF,$55,$C3,$C3,$C3 ; "OOO.UCCC" + .byte $55,$F0,$F0,$CF,$56,$56,$56,$55 ; "UppOVVVU" + .byte $FF,$FF,$55,$03,$03,$03,$03,$03 ; "..U....." + .byte $03,$03,$FF,$FF,$FF,$03,$03,$03 ; "........" + .byte $03,$03,$03,$03,$03,$03,$03,$03 ; "........" + .byte $03,$03,$03,$03,$03,$00,$AB,$03 ; "......+." + .byte $57,$03,$03,$03,$03,$07,$03,$03 ; "W......." + .byte $03,$03,$03,$03,$03,$03,$03,$03 ; "........" + .byte $03,$03,$AA,$FF,$FF,$FF,$FF,$FF ; "..*....." +verb_adr_l: + .byte $17,$FF,$FF,$19,$5D,$35,$4B,$F2 ; "....]5Kr" + .byte $EC,$87,$6F,$AD,$B7,$E2,$F8,$54 ; "l.o-7bxT" + .byte $80,$96,$85,$82,$22,$10,$33,$4A ; "....".3J" + .byte $13,$06,$0B,$4A,$01,$40,$47,$7A ; "...J.@Gz" + .byte $00,$FF,$23,$09,$5B,$16,$B6,$CB ; "..#.[.6K" + .byte $FF,$FF,$FB,$FF,$FF,$24,$F6,$4E ; "..{..$vN" + .byte $59,$50,$00,$FF,$23,$A3,$6F,$36 ; "YP..##o6" + .byte $23,$D7,$1C,$22,$C2,$AE,$BA,$23 ; "#W."B.:#" + .byte $FF,$FF,$21,$30,$1E,$03,$C4,$20 ; "..!0..D " + .byte $00,$C1,$FF,$FF,$FF,$A0,$30,$1E ; ".A... 0." + .byte $A4,$D3,$B6,$BC,$AA,$3A,$01,$50 ; "$S6<*:.P" + .byte $7E,$D8,$D8,$A5,$3C,$FF,$16,$5B ; "~XX%<..[" + .byte $28,$03,$C4,$1D,$00,$0C,$4E,$00 ; "(.D...N." + .byte $3E,$00,$A6,$B0,$00,$BC,$C6,$57 ; ">.&0.32767" + .byte $D4,$CF,$CF,$A0,$CC,$CF,$CE,$47 ; "TOO LONG" + .byte $D3,$D9,$CE,$D4,$C1,$58 ; "SYNTAX" + .byte $CD,$C5,$CD,$A0,$C6,$D5,$CC,$4C ; "MEM FULL" + .byte $D4,$CF,$CF,$A0,$CD,$C1,$CE,$D9,$A0,$D0,$C1,$D2,$C5,$CE,$53 ; "TOO MANY PARENS" + .byte $D3,$D4,$D2,$C9,$CE,$47 ; "STRING" + .byte $CE,$CF,$A0,$C5,$CE,$44 ; "NO END" + .byte $C2,$C1,$C4,$A0,$C2,$D2,$C1,$CE,$C3,$48 ; "BAD BRANCH" + .byte $BE,$B8,$A0,$C7,$CF,$D3,$D5,$C2,$53 ; ">8 GOSUBS" + .byte $C2,$C1,$C4,$A0,$D2,$C5,$D4,$D5,$D2,$4E ; "BAD RETURN" + .byte $BE,$B8,$A0,$C6,$CF,$D2,$53 ; ">8 FORS" + .byte $C2,$C1,$C4,$A0,$CE,$C5,$D8,$54 ; "BAD NEXT" + .byte $D3,$D4,$CF,$D0,$D0,$C5,$C4,$A0,$C1,$D4,$20 ; "STOPPED AT " + .byte $AA,$AA,$AA,$20 ; "*** " + .byte $A0,$C5,$D2,$D2,$0D ; " ERR.\n" + .byte $BE,$B2,$B5,$35 ; ">255" + .byte $D2,$C1,$CE,$C7,$45 ; RANGE" + .byte $C4,$C9,$4D ; "DIM" + .byte $D3,$D4,$D2,$A0,$CF,$D6,$C6,$4C ; "STR OVFL" + .byte $DC,$0D ; "\\\n" + .byte $D2,$C5,$D4,$D9,$D0,$C5,$A0,$CC,$C9,$CE,$C5,$8D ; "RETYPE LINE\n" + .byte $3F ; "?" +Leb9a: LSR run_flag + BCC Leba1 + JMP Le8c3 +Leba1: LDX acc+1 + TXS + LDX acc + LDY #$8D + BNE Lebac + +; token $54 - "INPUT" statement, numeric, no prompt +input_num_stmt: LDY #$99 +Lebac: JSR Se3c4 + STX acc + TSX + STX acc+1 + LDY #$FE + STY run_flag + INY + STY text_index + JSR Se299 + STY token_index + LDX #$20 + LDA #$30 + JSR Se491 + INC run_flag + LDX acc + +; token $27 - "," numeric input +input_num_comma: LDY text_index + ASL +Lebce: STA acc + INY + LDA buffer,Y + CMP #$74 + BEQ input_num_stmt + EOR #$B0 + CMP #$0A + BCS Lebce + INY + INY + STY text_index + LDA buffer,Y + PHA + LDA buffer-1,Y + LDY #$00 + JSR push_ya_noun_stk + PLA + STA noun_stk_h_int,X + LDA acc + CMP #$C7 + BNE Lebfa + JSR negate +Lebfa: JMP var_assign + + .byte $FF,$FF,$FF,$50 + +Tec01: JSR Tec13 + BNE Lec1b + +Tec06: JSR Tec0b + BNE Lec1b + +Tec0b: JSR subtract + JSR negate + BVC Lec16 + +Tec13: JSR subtract +Lec16: JSR sgn_fn + LSR noun_stk_l,X +Lec1b: JMP not_op + + .byte $FF,$FF + +; indexes into syntabl +syntabl_index: + .byte $C1,$FF,$7F,$D1,$CC,$C7,$CF,$CE ; "A..QLGON" + .byte $C5,$9A,$98,$8B,$96,$95,$93,$BF ; "E......?" + .byte $B2,$32,$2D,$2B,$BC,$B0,$AC,$BE ; "22-+<0,>" + .byte $35,$8E,$61,$FF,$FF,$FF,$DD,$FB ; "5.a...]{" + +Tec40: JSR Sefc9 + ORA rnd+1,X + BPL Lec4c + +Tec47: JSR Sefc9 + AND rnd+1,X +Lec4c: STA noun_stk_l,X + BPL Lec1b + JMP Sefc9 + .byte $40,$60,$8D,$60,$8B,$00,$7E,$8C ; "@`.`..~." + .byte $33,$00,$00,$60,$03,$BF,$12,$00 ; "3..`.?.." + .byte $40,$89,$C9,$47,$9D,$17,$68,$9D ; "@.IG..h." + .byte $0A,$00,$40,$60,$8D,$60,$8B,$00 ; "..@`.`.." + .byte $7E,$8C,$3C,$00,$00,$60,$03,$BF ; "~.<..`.?" + .byte $1B,$4B,$67,$B4,$A1,$07,$8C,$07 ; ".Kg4!..." + .byte $AE,$A9,$AC,$A8,$67,$8C,$07,$B4 ; ".),(g..4" + .byte $AF,$AC,$B0,$67,$9D,$B2,$AF,$AC ; "/,0g.2/," + .byte $AF,$A3,$67,$8C,$07,$A5,$AB,$AF ; "/#g..%+/" + .byte $B0,$F4,$AE,$A9,$B2,$B0,$7F,$0E ; "0t.)20.." + .byte $27,$B4,$AE,$A9,$B2,$B0,$7F,$0E ; "'4.)20.." + .byte $28,$B4,$AE,$A9,$B2,$B0,$64,$07 ; "(4.)20d." + .byte $A6,$A9,$67,$AF,$B4,$AF,$A7,$78 ; "&)g/4/'x" + .byte $B4,$A5,$AC,$78,$7F,$02,$AD,$A5 ; "4%,x..-%" + .byte $B2,$67,$A2,$B5,$B3,$AF,$A7,$EE ; "2g"53/'n" + .byte $B2,$B5,$B4,$A5,$B2,$7E,$8C,$39 ; "254%2~.9" + .byte $B4,$B8,$A5,$AE,$67,$B0,$A5,$B4 ; "48%.g0%4" + .byte $B3,$27,$AF,$B4,$07,$9D,$19,$B2 ; "3'/4...2" + .byte $AF,$A6,$7F,$05,$37,$B4,$B5,$B0 ; "/&..7450" + .byte $AE,$A9,$7F,$05,$28,$B4,$B5,$B0 ; ".)..(450" + .byte $AE,$A9,$7F,$05,$2A,$B4,$B5,$B0 ; ".)..*450" + .byte $AE,$A9,$E4,$AE,$A5,$00,$FF,$FF ; ".)d.%..." +syntabl2: + .byte $47,$A2,$A1,$B4,$7F,$0D,$30,$AD ; "G"!4..0-" + .byte $A9,$A4,$7F,$0D,$23,$AD,$A9,$A4 ; ")$..#-)$" + .byte $67,$AC,$AC,$A1,$A3,$00,$40,$80 ; "g,,!#.@." + .byte $C0,$C1,$80,$00,$47,$8C,$68,$8C ; "@A..G.h." + .byte $DB,$67,$9B,$68,$9B,$50,$8C,$63 ; "[g.h.P.c" + .byte $8C,$7F,$01,$51,$07,$88,$29,$84 ; "...Q..)." + .byte $80,$C4,$80,$57,$71,$07,$88,$14 ; ".D.Wq..." + .byte $ED,$A5,$AD,$AF,$AC,$ED,$A5,$AD ; "m%-/,m%-" + .byte $A9,$A8,$F2,$AF,$AC,$AF,$A3,$71 ; ")(r/,/#q" + .byte $08,$88,$AE,$A5,$AC,$68,$83,$08 ; "...%,h.." + .byte $68,$9D,$08,$71,$07,$88,$60,$76 ; "h..q..`v" + .byte $B4,$AF,$AE,$76,$8D,$76,$8B,$51 ; "4/.v.v.Q" + .byte $07,$88,$19,$B8,$A4,$AE,$B2,$F2 ; "...8$.2r" + .byte $B3,$B5,$F3,$A2,$A1,$EE,$A7,$B3 ; "35s"!n'3" + .byte $E4,$AE,$B2,$EB,$A5,$A5,$B0,$51 ; "d.2k%%0Q" + .byte $07,$88,$39,$81,$C1,$4F,$7F,$0F ; "..9.AO.." + .byte $2F,$00,$51,$06,$88,$29,$C2,$0C ; "/.Q..)B." + .byte $82,$57,$8C,$6A,$8C,$42,$AE,$A5 ; ".W.j.B.%" + .byte $A8,$B4,$60,$AE,$A5,$A8,$B4,$4F ; "(4`.%(4O" + .byte $7E,$1E,$35,$8C,$27,$51,$07,$88 ; "~.5.'Q.." + .byte $09,$8B,$FE,$E4,$AF,$AD,$F2,$AF ; "..~d/-r/" + .byte $E4,$AE,$A1,$DC,$DE,$9C,$DD,$9C ; "d.!\^.]." + .byte $DE,$DD,$9E,$C3,$DD,$CF,$CA,$CD ; "^].C]OJM" + .byte $CB,$00,$47,$9D,$AD,$A5,$AD,$AF ; "K.G.-%-/" + .byte $AC,$76,$9D,$AD,$A5,$AD,$A9,$A8 ; ",v.-%-)(" + .byte $E6,$A6,$AF,$60,$8C,$20,$AF,$B4 ; "f&/`. /4" + .byte $B5,$A1,$F2,$AC,$A3,$F2,$A3,$B3 ; "5!r,#r#3" + .byte $60,$8C,$20,$AC,$A5,$A4,$EE,$B5 ; "`. ,%$n5" + .byte $B2,$60,$AE,$B5,$B2,$F4,$B3,$A9 ; "2`.52t3)" + .byte $AC,$60,$8C,$20,$B4,$B3,$A9,$AC ; ",`. 43)," + .byte $7A,$7E,$9A,$22,$20,$00,$60,$03 ; "z~." .`." + .byte $BF,$60,$03,$BF,$1F ; "?`.?." + +; token $48 - "," string output +print_str_comma: JSR tabout + +; token $45 - ";" string output +; token $61 - "PRINT" string +print_str: INX + INX + LDA rnd+1,X + STA aux + LDA syn_stk_h+31,X + STA aux+1 + LDY rnd,X +Lee0f: TYA + CMP syn_stk_h+30,X + BCS Lee1d + LDA (aux),Y + JSR cout + INY + JMP Lee0f +Lee1d: LDA #$FF + STA cr_flag + RTS + +; token $3B - "LEN(" function +len_fn: INX + LDA #$00 + STA noun_stk_h_str,X + STA noun_stk_h_int,X + LDA syn_stk_h+31,X + SEC + SBC rnd+1,X + STA noun_stk_l,X + JMP left_paren + + .byte $FF + +getbyte: JSR get16bit + LDA acc+1 + BNE gr_255_err + LDA acc + RTS + +; token $68 - "," for PLOT statement (???) +plot_comma: JSR getbyte + LDY text_index + CMP #$30 + BCS range_err + CPY #$28 + BCS range_err + RTS + NOP + NOP + +Tee4e: JSR getbyte + RTS + NOP +Tee5e: TXA + LDX #$01 +l123: LDY acc,X + STY himem,X + LDY var,X + STY pp,X + DEX + BEQ l123 + TAX + RTS +gr_255_err: LDY #$77 ; > 255 error +go_errmess_5: JMP print_err_msg +range_err: LDY #$7B ; range error + BNE go_errmess_5 + +See6c: JSR Se254 + LDA aux + BNE Lee7a + LDA aux+1 + BNE Lee7a + JMP Le77e +Lee7a: ASL acc + ROL acc+1 + ROL p3 + ROL p3+1 + LDA p3 + CMP aux + LDA p3+1 + SBC aux+1 + BCC Lee96 + STA p3+1 + LDA p3 + SBC aux + STA p3 + INC acc +Lee96: DEY + BNE Lee7a + RTS + + .byte $FF,$FF,$FF,$FF,$FF,$FF + +; token $4D - "CALL" statement +call_stmt: JSR get16bit + JMP (acc) +l1233: LDA himem + BNE l1235 + DEC himem+1 +l1235: DEC himem + LDA var + BNE l1236 + DEC var+1 +l1236: DEC var +l1237: LDY #$00 + LDA (himem),Y + STA (var),Y + LDA pp + CMP himem + LDA pp+1 + SBC himem+1 + BCC l1233 + JMP Tee5e + CMP #$28 +Leecb: BCS range_err + TAY + LDA text_index + RTS + NOP + NOP + +print_err_msg1: + TYA + TAX + LDY #$6E + JSR Se3c4 + TXA + TAY + JSR Se3c4 + LDY #$72 + JMP Se3c4 + +Seee4: JSR get16bit +Leee7: ASL acc + ROL acc+1 + BMI Leee7 + BCS Leecb + BNE Leef5 + CMP acc + BCS Leecb +Leef5: RTS + +; token $2E - "PEEK" fn (uses $3F left paren) +peek_fn: JSR get16bit + LDA (acc),Y + STY syn_stk_l+31,X + JMP push_ya_noun_stk + +; token $65 - "," for POKE statement +poke_stmt: JSR getbyte + LDA acc + PHA + JSR get16bit + PLA + STA (acc),Y + +Tef0c: RTS + + .byte $FF,$FF,$FF + +; token $15 - "/" for numeric division +divide: JSR See6c + LDA acc + STA p3 + LDA acc+1 + STA p3+1 + JMP Le244 + +; token $44 - "," next var in DIM statement is numeric +; token $4F - "DIM", next var is numeric +dim_num: JSR Seee4 + JMP Le134 + +; token $2D - "(" for numeric array subscript +num_array_subs: JSR Seee4 + LDY noun_stk_h_str,X + LDA noun_stk_l,X + ADC #$FE + BCS Lef30 + DEY +Lef30: STA aux + STY aux+1 + CLC + ADC acc + STA noun_stk_l,X + TYA + ADC acc+1 + STA noun_stk_h_str,X + LDY #$00 + LDA noun_stk_l,X + CMP (aux),Y + INY + LDA noun_stk_h_str,X + SBC (aux),Y + BCS Leecb + JMP left_paren + +; token $2F - "RND" fn (uses $3F left paren) +rnd_fn: JSR get16bit + LDA rnd + JSR push_ya_noun_stk + LDA rnd+1 + BNE Lef5e + CMP rnd + ADC #$00 +Lef5e: AND #$7F + STA rnd+1 + STA noun_stk_h_int,X + LDY #$11 +Lef66: LDA rnd+1 + ASL + CLC + ADC #$40 + ASL + ROL rnd + ROL rnd+1 + DEY + BNE Lef66 + LDA acc + JSR push_ya_noun_stk + LDA acc+1 + STA noun_stk_h_int,X + JMP mod_op + +Tef80: JSR get16bit + LDY acc + CPY himem + LDA acc+1 + SBC himem+1 + BCC Lefab + STY var + LDA acc+1 + STA var+1 +Lef93: JMP l1237 + +Tef96: JSR get16bit + LDY acc + CPY pp + LDA acc+1 + SBC pp+1 + BCS Lefab + STY lomem + LDA acc+1 + STA lomem+1 + JMP clr +Lefab: JMP Leecb + NOP + NOP + NOP + NOP +Lefb3: JSR Sefc9 + +; token $26 - "," for string input +; token $52 - "INPUT" statement for string +string_input: JSR input_str + JMP Lefbf + +; token $53 - "INPUT" with literal string prompt +input_prompt: JSR print_str +Lefbf: LDA #$FF + STA text_index + LDA #$74 + STA buffer + RTS + +Sefc9: JSR not_op + INX + +Sefcd: JSR not_op + LDA noun_stk_l,X + RTS + +; memory initialization for 4K RAM +mem_init_4k: LDA #$00 + STA lomem + STA himem + LDA #$08 + STA lomem+1 ; LOMEM defaults to $0800 + LDA #$10 + STA himem+1 ; HIMEM defaults to $1000 + JMP new_cmd + +Sefe4: CMP noun_stk_h_str,X + BNE Lefe9 + CLC +Lefe9: JMP Le102 + +Tefec: JSR clr + JMP run_warm + +Teff2: JSR clr + JMP goto_stmt + +Seff8: CPX #$80 + BNE Leffd + DEY +Leffd: JMP Se00c diff --git a/A1B-move/a1bmoveg.py b/A1B-move/a1bmoveg.py new file mode 100644 index 0000000..aad2822 --- /dev/null +++ b/A1B-move/a1bmoveg.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python +# +# Apple 1 Integer BASIC Relocator +# +# GENERATE list of lines sith $Ex in them. +# +# Copyright (C) 2021 by Jim McClanahan, W4JBM +# +# Usage: ./a1bmoveg.py +# +# - Name input file a1basic.in +# - Run Generate Process with ./a1bmoveg.py +# - Edit file to delete or comment out lines which +# are not to be changed +# - Run Modification Process with ./a1movem.py to +# create a1basic.out +# + +from sys import argv; + +fin = open("a1basic.in", 'rt') +fmod = open("a1basic.mod", 'w') + + +fmod.write('# Apple 1 Integer BASIC Relocator\n') +fmod.write('#\n') +fmod.write('# *=$E000\n') +fmod.write('#\n') + +lin = 0 + +for line in (fin): + lin = lin + 1 + if '$E' in line: + fmod.write(str(lin)+'\n') + diff --git a/A1B-move/a1bmovem.py b/A1B-move/a1bmovem.py new file mode 100644 index 0000000..71d3a91 --- /dev/null +++ b/A1B-move/a1bmovem.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python +# +# Apple 1 Integer BASIC Relocator +# +# MODIFY list of lines sith $Ex in them. +# +# Copyright (C) 2021 by Jim McClanahan, W4JBM +# +# Usage: ./a1bmovem.py +# +# - Name input file a1basic.in +# - Run Generate Process with ./a1bmoveg.py +# - Edit file to delete or comment out lines which +# are not to be changed +# - Run Modification Process with ./a1movem.py to +# create a1basic.out +# + +from sys import argv; + +fin = open("a1basic.in", 'rt') +fmod = open("a1basic.mod", 'rt') +fout = open("a1basic.out", 'w') + +src_lines = fin.readlines() + +lin = 0 + +for line in (fmod): + if not '#' in line: + plin = int(line) + print(plin) + while lin < (plin - 1): + fout.write(src_lines[lin]) + lin = lin + 1 + fout.write(src_lines[lin].replace('$E', '$A')) + lin = lin +1 + +while lin < len(src_lines): + fout.write(src_lines[lin]) + lin = lin + 1 +