use more space efficient calling convention for calling errors
This commit is contained in:
1 parent
b45e7aab65
commit
27b33c2b26
9 files changed
+136
-18
No files matched your search
@@ -42,8 +42,7 @@ basic_delete_line:
|
|||||||
beq +
|
beq +
|
||||||
;; Line length is <0 or >255 bytes.
|
;; Line length is <0 or >255 bytes.
|
||||||
;; Either way, things are bad, so abort.
|
;; Either way, things are bad, so abort.
|
||||||
ldx #35
|
jmp do_MEMORY_CORRUPT_error
|
||||||
jmp do_basic_error
|
|
||||||
*
|
*
|
||||||
;; Length can now be safely assumed to be in the low
|
;; Length can now be safely assumed to be in the low
|
||||||
;; byte only, i.e., stored in tokenise_work3
|
;; byte only, i.e., stored in tokenise_work3
|
||||||
|
|||||||
@@ -86,8 +86,7 @@ not_a_token:
|
|||||||
beq basic_skip_char
|
beq basic_skip_char
|
||||||
|
|
||||||
;; If all else fails, it's a syntax error
|
;; If all else fails, it's a syntax error
|
||||||
ldx #10
|
jmp do_SYNTAX_error
|
||||||
jmp do_basic_error
|
|
||||||
|
|
||||||
jmp basic_main_loop
|
jmp basic_main_loop
|
||||||
|
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ basic_parse_line_number:
|
|||||||
ora basic_fac1_exponent
|
ora basic_fac1_exponent
|
||||||
beq +
|
beq +
|
||||||
ml_bad_line_number:
|
ml_bad_line_number:
|
||||||
ldx #10
|
;; Invalid line number
|
||||||
jmp do_basic_error
|
jmp do_ILLEGAL_QUANTITY_error
|
||||||
*
|
*
|
||||||
;; Line number are not allowed to have decimal points in them
|
;; Line number are not allowed to have decimal points in them
|
||||||
lda tokenise_work4
|
lda tokenise_work4
|
||||||
|
|||||||
+2
-3
@@ -14,9 +14,8 @@ cmd_run:
|
|||||||
jsr basic_parse_line_number
|
jsr basic_parse_line_number
|
||||||
jsr basic_find_line
|
jsr basic_find_line
|
||||||
bcc +
|
bcc +
|
||||||
;; Undefined Statement Error
|
;; Line doesn't exist, so report error
|
||||||
ldx #16
|
jmp do_UNDEFD_STATEMENT_error
|
||||||
jmp do_basic_error
|
|
||||||
*
|
*
|
||||||
;; Run it!
|
;; Run it!
|
||||||
jmp basic_execute_from_current_line
|
jmp basic_execute_from_current_line
|
||||||
+1
-2
@@ -4,8 +4,7 @@ cmd_sys:
|
|||||||
bcc +
|
bcc +
|
||||||
|
|
||||||
;; SYS requires an argument
|
;; SYS requires an argument
|
||||||
ldx #10
|
jmp do_SYNTAX_ERROR
|
||||||
jmp do_basic_error
|
|
||||||
|
|
||||||
*
|
*
|
||||||
jsr basic_parse_line_number
|
jsr basic_parse_line_number
|
||||||
|
|||||||
@@ -82,5 +82,4 @@ cmd_go:
|
|||||||
;; Undefined tokens
|
;; Undefined tokens
|
||||||
cmd_unimplemented:
|
cmd_unimplemented:
|
||||||
|
|
||||||
ldx #36
|
jmp do_NOT_IMPLEMENTED_error
|
||||||
jmp do_basic_error
|
|
||||||
+126
-1
@@ -1,6 +1,131 @@
|
|||||||
|
;; As many errors are triggered from many places in the BASIC
|
||||||
|
;; interprettor, it is important to have an efficicent means of
|
||||||
|
;; calling them.
|
||||||
|
;; LDX #$nn / jmp do_basic_error
|
||||||
|
;; is the simplest, but takes 5 bytes.
|
||||||
|
;; Having a direct JMP address for each error is preferable, as
|
||||||
|
;; it reduces the overhead to 3 bytes, but at the cost of having
|
||||||
|
;; a jump table of some sort. The .byte $2C method can be used
|
||||||
|
;; to have a set of addresses that each execute a different
|
||||||
|
;; LDX #$nn command, reducing the cost of the jump table to 3
|
||||||
|
;; bytes per error number.
|
||||||
|
;; But we can do better with a bit of scullduggery and carnal
|
||||||
|
;; knowledge of ZP usage.
|
||||||
|
;; The INC $nn opcode is $E6. ZP location $E6 is one of the screen
|
||||||
|
;; link addresses. In the original KERNAL, the lower bits of those
|
||||||
|
;; addresses have meaning, but in our KERNAL, we ignore them, and just
|
||||||
|
;; have them all zeroes. So.... We can have a sequence of $E6 bytes,
|
||||||
|
;; and know exactly how many of them have been executed, by checking
|
||||||
|
;; the value of $E6. Then all we need to worry about is if an odd
|
||||||
|
;; number is required, then we have to have an exit that has a $E6
|
||||||
|
;; opcode with some other address as target, but where the byte value
|
||||||
|
;; of that argument can be safely executed as a CPU instruction.
|
||||||
|
;; NOP = $EA is the obvious choice, as if used as an argument to
|
||||||
|
;; $E6 will increment location $EA, which is another of the screen
|
||||||
|
;; link addresses.
|
||||||
|
|
||||||
|
;; This gives a total overhead of 18 bytes + 1 byte per error
|
||||||
|
;; message. This compares favourably to the 3 bytes per error
|
||||||
|
;; message that the $2C method would result in.
|
||||||
|
|
||||||
|
do_NOT_IMPLEMENTED_error:
|
||||||
|
.byte $E6
|
||||||
|
do_MEMORY_CORRUPT_error:
|
||||||
|
.byte $E6
|
||||||
|
;; the message "BYTES FREE"
|
||||||
|
.byte $E6
|
||||||
|
;; the word ERROR
|
||||||
|
.byte $E6
|
||||||
|
;; The word "SAVING"
|
||||||
|
.byte $E6
|
||||||
|
;; The word "VERIFYING"
|
||||||
|
.byte $E6
|
||||||
|
;; The word "LOADING"
|
||||||
|
.byte $E6
|
||||||
|
;; The word "READY."
|
||||||
|
.byte $E6
|
||||||
|
do_LOAD_error:
|
||||||
|
.byte $E6
|
||||||
|
do_VERIFY_error:
|
||||||
|
.byte $E6
|
||||||
|
do_UNDEFD_FUNCTION_error:
|
||||||
|
.byte $E6
|
||||||
|
do_CANT_CONTINUE_error:
|
||||||
|
.byte $E6
|
||||||
|
do_FORMULA_TOO_COMPLEX_error:
|
||||||
|
.byte $E6
|
||||||
|
do_FILE_DATA_error:
|
||||||
|
.byte $E6
|
||||||
|
do_STRING_TOO_LONG_error:
|
||||||
|
.byte $E6
|
||||||
|
do_TYPE_MISMATCH_error:
|
||||||
|
.byte $E6
|
||||||
|
do_ILLEGAL_DIRECT_error:
|
||||||
|
.byte $E6
|
||||||
|
do_DIVISION_BY_ZERO_error:
|
||||||
|
.byte $E6
|
||||||
|
do_REDIMD_ARRAY_error:
|
||||||
|
.byte $E6
|
||||||
|
do_BAD_SUBSCRIPT_error:
|
||||||
|
.byte $E6
|
||||||
|
do_UNDEFD_STATEMENT_error:
|
||||||
|
.byte $E6
|
||||||
|
do_OUT_OF_MEMORY_error:
|
||||||
|
.byte $E6
|
||||||
|
do_OVERFLOW_error:
|
||||||
|
.byte $E6
|
||||||
|
do_ILLEGAL_QUANTITY_error:
|
||||||
|
.byte $E6
|
||||||
|
do_OUT_OF_DATA_error:
|
||||||
|
.byte $E6
|
||||||
|
do_RETURN_WITHOUT_GOSUB_error:
|
||||||
|
.byte $E6
|
||||||
|
do_SYNTAX_error:
|
||||||
|
.byte $E6
|
||||||
|
do_NEXT_WITHOUT_FOR_error:
|
||||||
|
.byte $E6
|
||||||
|
do_ILLEGAL_DEVICE_NUMBER_error:
|
||||||
|
.byte $E6
|
||||||
|
do_MISSING_FILENAME_error:
|
||||||
|
.byte $E6
|
||||||
|
do_NOT_OUTPUT_FILE_error:
|
||||||
|
.byte $E6
|
||||||
|
do_NOT_INPUT_FILE_error:
|
||||||
|
.byte $E6
|
||||||
|
do_DEVICE_NOT_PRESENT_error:
|
||||||
|
.byte $E6
|
||||||
|
do_FILE_NOT_FOUND_error:
|
||||||
|
.byte $E6
|
||||||
|
do_FILE_NOT_OPEN_error:
|
||||||
|
.byte $E6
|
||||||
|
do_FILE_OPEN_error:
|
||||||
|
.byte $E6
|
||||||
|
do_TO_MANY_FILES_error:
|
||||||
|
.byte $EA
|
||||||
|
|
||||||
|
;; Now get the error # and restore $E6 to its correct value
|
||||||
|
lda $E6
|
||||||
|
pha
|
||||||
|
and #$80
|
||||||
|
sta $E6
|
||||||
|
pla
|
||||||
|
;; $E6 has even part
|
||||||
|
asl
|
||||||
|
ora $EA
|
||||||
|
and #$7f
|
||||||
|
tax
|
||||||
|
|
||||||
|
;; Restore $EA to correct value in case the NOP above is used
|
||||||
|
;; as an argument to the preceeding INC $nn (opcode $E6).
|
||||||
|
LDA $EA
|
||||||
|
and #$80
|
||||||
|
sta $EA
|
||||||
|
|
||||||
|
;; FALL THROUGH
|
||||||
|
|
||||||
;; Error # in X
|
;; Error # in X
|
||||||
|
|
||||||
do_basic_error:
|
;; do_basic_error:
|
||||||
;; "?"
|
;; "?"
|
||||||
txa
|
txa
|
||||||
pha
|
pha
|
||||||
|
|||||||
@@ -60,8 +60,7 @@ f1m10_l3:
|
|||||||
bpl f1m10_l3
|
bpl f1m10_l3
|
||||||
;; Exponent has bit 7 set, so has wrapped.
|
;; Exponent has bit 7 set, so has wrapped.
|
||||||
;; = OVERFLOW ERROR
|
;; = OVERFLOW ERROR
|
||||||
lda #14
|
jmp do_OVERFLOW_error
|
||||||
jmp do_basic_error
|
|
||||||
|
|
||||||
fac1_mantissa_mul2:
|
fac1_mantissa_mul2:
|
||||||
ldy #3
|
ldy #3
|
||||||
|
|||||||
@@ -101,8 +101,7 @@ tk_might_be_keyword:
|
|||||||
cmp #$10
|
cmp #$10
|
||||||
bcc +
|
bcc +
|
||||||
;; Packed string too long
|
;; Packed string too long
|
||||||
ldx #16
|
jmp do_STRING_TOO_LONG_error
|
||||||
jmp do_basic_error
|
|
||||||
*
|
*
|
||||||
|
|
||||||
;; Search for it in keywords
|
;; Search for it in keywords
|
||||||
|
|||||||
Reference in new issue
Block a user