Merge pull request #50 from FeralChild64/master

Strings in BASIC
This commit is contained in:
gardners authored and GitHub committed 2020-08-06 07:56:34 +09:30
commit 5931d12394
267 files changed
+6503 -1441

No files matched your search

+6 -1
View File
@@ -5,7 +5,7 @@
* Retrofan - for his Mega65 banner artwork and PXLfont
* TWW/CTR - for his keyboard handling code
* Graham - for his PAL/NTSC detection routine
* Graham - for his PAL/NTSC detection code and compact 8x8 multiplication routine
* enthusi/Onslaught - for his example Turbo Tape 64 compatible loader
* djmips - for fast 8x8 multiplication routine
* Verz - for the integer division routine
@@ -24,6 +24,11 @@
* silverdr - for the floating point routines [description](https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics)
* the [C64 Wiki](https://www.c64-wiki.com) contributors
## other
* Gábor Lénárt - for his work on [XEMU Mega65 emulator](https://github.com/lgblgblgb/xemu)
* Mads Nielsen - for the [Kick Assembler](http://www.theweb.dk/KickAssembler/Main.html#frontpage)
<br />
* ... and all the others we forgot
+13 -14
View File
@@ -14,14 +14,15 @@ SRCDIR_BASIC = $(SRCDIR_COMMON) \
src/basic/,stubs_math \
src/basic/assets \
src/basic/basic_commands \
src/basic/basic_commands_CC \
src/basic/basic_commands_CD \
src/basic/basic_commands_01 \
src/basic/basic_commands_02 \
src/basic/basic_operators \
src/basic/basic_functions \
src/basic/board_m65 \
src/basic/board_x16 \
src/basic/editor \
src/basic/engine \
src/basic/engine_editor \
src/basic/engine_runtime \
src/basic/engine_variables \
src/basic/init \
src/basic/math \
src/basic/math_consts \
@@ -329,7 +330,7 @@ $(DIR_M65)/OUTK_0.BIN $(DIR_M65)/KERNAL_0_combined.vs $(DIR_M65)/KERNAL_0_combin
$(DIR_M65)/basic.seg_1 $(DIR_M65)/BASIC_1_combined.vs $(DIR_M65)/BASIC_1_combined.sym:
@mkdir -p $(DIR_M65)
@rm -f $@* $(DIR_M65)/basic.seg_1 $(DIR_M65)/BASIC_1*
@$(TOOL_BUILD_SEGMENT) -a ../../$(TOOL_ASSEMBLER) -r M65 -s BASIC_1 -i BASIC_1-mega65 -o basic.seg_1 -d $(DIR_M65) -l 4000 -h 5fff $(CFG_M65) $(GEN_STR_M65) $(SRCDIR_BASIC) $(GEN_BASIC)
@$(TOOL_BUILD_SEGMENT) -a ../../$(TOOL_ASSEMBLER) -r M65 -s BASIC_1 -i BASIC_1-mega65 -o basic.seg_1 -d $(DIR_M65) -l 4000 -h 7fff $(CFG_M65) $(GEN_STR_M65) $(SRCDIR_BASIC) $(GEN_BASIC)
$(DIR_M65)/kernal.seg_1 $(DIR_M65)/KERNAL_1_combined.vs $(DIR_M65)/KERNAL_1_combined.sym:
@mkdir -p $(DIR_M65)
@@ -408,29 +409,27 @@ build/symbols_hybrid.vs: $(DIR_GEN)/KERNAL_combined.vs
# Rules - platform 'Mega65' specific
build/padding_08_KB:
dd if=/dev/zero bs=8192 count=1 of=build/padding_08_KB
build/padding_16_KB:
@mkdir -p build
dd if=/dev/zero bs=8192 count=2 of=build/padding_16_KB
build/padding_64_KB:
@mkdir -p build
dd if=/dev/zero bs=8192 count=8 of=build/padding_64_KB
$(TARGET_M65_x) $(TARGET_M65_x_PXL): build/padding_08_KB build/padding_64_KB $(SEG_LIST_M65) build/chargen_openroms.rom build/chargen_openroms.patched build/chargen_pxlfont.rom build/chargen_pxlfont.patched
$(TARGET_M65_x) $(TARGET_M65_x_PXL): build/padding_16_KB build/padding_64_KB $(SEG_LIST_M65) build/chargen_openroms.rom build/chargen_openroms.patched build/chargen_pxlfont.rom build/chargen_pxlfont.patched
@echo
cat build/padding_08_KB > $(TARGET_M65_x)
cat build/padding_08_KB >> $(TARGET_M65_x)
cat build/padding_16_KB > $(TARGET_M65_x)
cat $(DIR_M65)/kernal.seg_1 >> $(TARGET_M65_x)
cat $(DIR_M65)/basic.seg_1 >> $(TARGET_M65_x)
cat build/padding_08_KB >> $(TARGET_M65_x)
cat $(DIR_M65)/basic.seg_0 >> $(TARGET_M65_x)
cat build/chargen_openroms.rom >> $(TARGET_M65_x)
cat build/chargen_openroms.patched >> $(TARGET_M65_x)
cat $(DIR_M65)/kernal.seg_0 >> $(TARGET_M65_x)
cat build/padding_64_KB >> $(TARGET_M65_x)
@echo
cat build/padding_08_KB > $(TARGET_M65_x_PXL)
cat build/padding_08_KB >> $(TARGET_M65_x_PXL)
cat build/padding_16_KB > $(TARGET_M65_x_PXL)
cat $(DIR_M65)/kernal.seg_1 >> $(TARGET_M65_x_PXL)
cat $(DIR_M65)/basic.seg_1 >> $(TARGET_M65_x_PXL)
cat build/padding_08_KB >> $(TARGET_M65_x_PXL)
cat $(DIR_M65)/basic.seg_0 >> $(TARGET_M65_x_PXL)
cat build/chargen_pxlfont.rom >> $(TARGET_M65_x_PXL)
cat build/chargen_pxlfont.patched >> $(TARGET_M65_x_PXL)
+7 -3
View File
@@ -1,14 +1,18 @@
# open-roms
# Open ROMs
![screenshot demonstrating some features](./doc/screenshot-demo.png)
A project to create unencumbered open-source ROMs for use on selected retro computers. Besides this manifest, the following documents are available:
* [implementation status](./STATUS.md) of various APIs and functionalities
* [configuration options](./CONFIG.md) for those willing to compile their own, customized ROM set
* [BASIC extensions](doc/Extended-BASIC.md)
* [development guide](./doc/Development.md) for those interested in OpenROMs technical aspects
* [BASIC extensions](./doc/Extended-BASIC.md)
* [development guide](./doc/Development.md) for those interested in technical aspects
* [license](./LICENSE) information and list of major contributors
* [credits](./CREDITS.md) to people whose work was of great help to us
To download pre-built ROM images, go [here](./bin).
# Problem Statement and Motivation
The copyrights of various old computer system ROMs are still alive, and together with trademarks, can present significant
+8 -9
View File
@@ -11,6 +11,12 @@ Here are the features of the Open ROMs not found in the original ROMs from the 8
* JiffyDOS and DolphinDOS protocols support
* DOS wedge (direct mode only) - `@<drive_number>`, `@<command>`, `@$`, `@$<params>`, `@`
* BASIC extensions, see the [documentation](doc/Extended-BASIC.md)
* extended / tweaked `LOAD` / `VERIFY` commands
* start/end addresses are displayed, in the Final cartridge style
* command with just the file name tries to use the last device if it's number seems sane; otherwise uses 8
* command without parameters tries to load first file from drive chosen as above
* `LIST` command should never damage the screen if trying to list memory content which is not a BASIC program
* high performance garbage collector
* turbo tape load support (as device 7, or using `←L` / `←M`, optionally with a file name), quite sophisticated: up to 250 blocks (can store bytes under I/O), automatically adjusts for tape speed differences
* normal tape load error log is limited by free stack space only (no artificial limitation like in original ROMs)
@@ -18,12 +24,6 @@ Here are the features of the Open ROMs not found in the original ROMs from the 8
* improved support for tape adapters (for using regular casette players and other audio devices instead of Datasette) and emulators
* built-in tape head align tool (only feasible to use on machines with extended memory, like Mega65)
* extended / tweaked `LOAD` / `VERIFY` commands
* start/end addresses are displayed, in the Final cartridge style
* command with just the file name tries to use the last device if it's number seems sane; otherwise uses 8
* command without parameters tries to load first file from drive chosen as above
* `LIST` command should never damage the screen if trying to list memory content which is not a BASIC program
* uses RAM under ROM and I/O: 51199 bytes free (up to `$CFFF`) by default, but 61438 is also possible
* cold/warm start silences multiple SID chips
* warm start due to BRK prints out the instruction address
@@ -42,9 +42,8 @@ The following ROM features are currently missing and are not planned due to spac
The following ROM features are currently missing:
* most BASIC commands
* BASIC variables
* BASIC expression handling
* most floating point routines
* BASIC integer/float variables/arrays (strings work now, with the exception of undefined arrays)
* BASIC expression handling (again, strings should work now)
* RS-232 support
* NMI handling is incomplete
+1 -1
View File
@@ -22,6 +22,6 @@ Have fun!
------
PXL font was created by Retrofan, we got a permission to include it with OpenROMs under GNU Lesser General Public License 3.0, see:
PXL font was created by Retrofan, we got a permission to include it with Open ROMs under GNU Lesser General Public License 3.0, see:
- https://www.forum64.de/index.php?thread/84000-neuer-c64-systemfont-auch-plus4-c128-atari/&postID=1493383#post1493383
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
+23 -23
View File
@@ -1,5 +1,5 @@
# OpenROMs development guide
# Open ROMs development guide
NOTE: this document is a preliminary version, definitely incomplete!
@@ -10,30 +10,30 @@ NOTE: this document is a preliminary version, definitely incomplete!
- [DolphinDOS](./Protocol-DolphinDOS.md)
## Guidelines for software developers for OpenROMs compatibility
## Guidelines for software developers for Open ROMs compatibility
Most important: always test your software on the original ROMs too. If your code works on the OpenROMs, but fails on the original firmware - than something is clearly wrong, and it might stop working once we make OpenROMs more compatible for one reason or another.
Most important: always test your software on the original ROMs too. If your code works on the Open ROMs, but fails on the original firmware - than something is clearly wrong, and it might stop working once we make Open ROMs more compatible for one reason or another.
### Unofficial ROM APIs
Please, do not use any internal/unofficial OpenROMs API. They WILL change in an incompatible way, you may believe me. Using unofficial API of the original ROMs is OK if the routine is marked as supported in the [implementation status](../STATUS.md) document.
Please, do not use any internal/unofficial Open ROMs API. They WILL change in an incompatible way, you may believe me. Using unofficial API of the original ROMs is OK if the routine is marked as supported in the [implementation status](../STATUS.md) document.
### Compatibility with OpenROMs for Mega65
### Compatibility with Open ROMs for Mega65
The Mega65 OpenROMs build aims to provide a C64-compatible memory map in range `$00000-$0FFFF`. For `$10000` and above, everything is still subject to change.
The Mega65 Open ROMs build aims to provide a C64-compatible memory map in range `$00000-$0FFFF`. For `$10000` and above, everything is still subject to change.
Please note, that certain ROM routines are moved to additional Mega65 ROM area (2x8KB is not enough to implement full ROM functionality and additional features) - original locations contain just short compatibility code which remaps memory, calls the real routine, and restores default mapping (that means all blocks unmapped). This shouldn't be a problem for original C64 software, but can make a difference for Mega65-aware code; thus, please follow these simple rules:
- do not call ROM routines with .B set to anything other than 0 (and .B set to 0x40 or above is a receipe for disaster!)
- be aware that ROM routines may restore the default memory mapping by means of MAP/EOM
OpenROMs interrupt handlers do not touch the ROM mapping, range `0x4000-0xBFFF` can be freely mapped without disabling IRQ or NMI. The .Z register is mostly safe to use too - some routines might use it, but they will alwayys restore it's previous state. Please be aware, that for maximum compatibility our IRQ/NMI handlers DO NOT store/restore .Z register.
Open ROMs interrupt handlers do not touch the ROM mapping, range `0x4000-0xBFFF` can be freely mapped without disabling IRQ or NMI. The .Z register is mostly safe to use too - some routines might use it, but they will alwayys restore it's previous state. Please be aware, that for maximum compatibility our IRQ/NMI handlers DO NOT store/restore .Z register.
### API extensions
#### PETSCII
OpenROMs provides support for several additional PETSCII codes (all compatible with C128 and/or C65):
Open ROMs provides support for several additional PETSCII codes (all compatible with C128 and/or C65):
| PETSCII code | description |
| :----------: | :-------------------------------------------------- |
@@ -69,7 +69,7 @@ Mega65 build starts in legacy mode, which is intended to be reasonably compatibl
- Slightly different chargen. On C64 machines pressing C= + G or C= + M key combinations produces the same visual result as C= + H or C= + N, respectively - despite keycap printing suggests they should produce tinner bars. This was intentional change in the C64 ROMs (compared to VIC-20), to prevent colour problems on 80s era TVs. Screen font used in the legacy mode duplicates this change, but the font intended for native mode has this change reverted back. Additionally, the π sign is available for lower/upper case set too.
## Tinkering with OpenROMs
## Tinkering with Open ROMs
Make sure to read the main [README](../README.md) first - although any help with the project is always welcome, you need to be aware of the possible legal problems we want to avoid.
@@ -77,19 +77,19 @@ Make sure to read the main [README](../README.md) first - although any help with
List of the most important make targets:
| target | description |
| :------------------ | :----------------------------------------------------------------------------- |
| `all` | builds all ROMs, places them in 'build' subdirectory |
| `clean` | removes all the compilation results and intermediate files |
| `updatebin` | upates ROMs in 'bin' subdirectory - with embedded version string, for release |
| `testsimilarity` | launches the similarity tool, see [README](../README.md) |
| `test` | builds the 'custom' configuration, launches it using VICE emulator |
| `test_generic` | builds the default ROMs, for generic C64/C128, launches using VICE |
| `test_generic_x128` | as above, but launches C128 emulator instead |
| `test_mega65` | builds the Mega65 ROM, launches it using XEMU emulator |
| `test_ultimate64` | builds the Ultimate 64 configuration, launches it using VICE emulator |
| `test_hybrid` | builds a hybrid ROM (OpenROMs Kernal + original BASIC), launches it using VICE |
| `test_testing` | builds a rather odd testing configuration, launches it using VICE emulator |
| target | description |
| :------------------ | :------------------------------------------------------------------------------ |
| `all` | builds all ROMs, places them in 'build' subdirectory |
| `clean` | removes all the compilation results and intermediate files |
| `updatebin` | upates ROMs in 'bin' subdirectory - with embedded version string, for release |
| `testsimilarity` | launches the similarity tool, see [README](../README.md) |
| `test` | builds the 'custom' configuration, launches it using VICE emulator |
| `test_generic` | builds the default ROMs, for generic C64/C128, launches using VICE |
| `test_generic_x128` | as above, but launches C128 emulator instead |
| `test_mega65` | builds the Mega65 ROM, launches it using XEMU emulator |
| `test_ultimate64` | builds the Ultimate 64 configuration, launches it using VICE emulator |
| `test_hybrid` | builds a hybrid ROM (Open ROMs Kernal + original BASIC), launches it using VICE |
| `test_testing` | builds a rather odd testing configuration, launches it using VICE emulator |
### Code segments and ROM layouts
@@ -97,7 +97,7 @@ List of the most important make targets:
Currently there are 3 ROM layouts defined:
- `STD` - with 2 code segments: `BASIC` (`$A000-$E4D2`, where `$C000-$DFFF` is a skip-gap for RAM and I/O area) and `KERNAL` (`$E4D3 - $FFFF`)
- `M65` - where `BASIC` becames `BASIC_0` and `KERNAL` becames `KERNAL_0`, additional segments might be added to the build system in the future; at the moment of writing this document additional 8KB of ROM is defined as `BASIC_1` segment and additional 8KB of ROM is defined as `KERNAL_1` segment
- `M65` - where `BASIC` becames `BASIC_0` and `KERNAL` becames `KERNAL_0`, additional segments might be added to the build system in the future; at the moment of writing this document additional 16KB of ROM is defined as `BASIC_1` segment and additional 8KB of ROM is defined as `KERNAL_1` segment
- `X16` - memory layout for the Commander X16 machine
To check for current ROM layout or code segment use KickAssembler preprocessor defines, like `ROM_LAYOUT_STD`, `ROM_LAYOUT_M65`, `SEGMENT_BASIC`, `SEGMENT_KERNAL_1`.
+65
View File
@@ -0,0 +1,65 @@
# Planned BASIC features, when V2 compatibility is reached
Ideas for the future, most of them suitable for Mega65 or other power machines only
* sound support
* 2D graphics support
* turtle graphics
* sprite support, including collision callback
* custom character set support
* sprite/character design within program, in a way similar to Simons BASIC
* joystick/mouse/lightpen/paddle commands/functions
* matrix operations
* `DISPOSE` with variable/array as parameter should remove the variable/array from memory
* `BLOAD`, `BVERIFY` and `BSAVE` should have syntax compatible with BASIC V7/V10
* it should be possible to intercept Kernal errors from BASIC (prevent `?FILE NOT FOUND ERROR IN ...`, etc.); `ON ERROR GOTO` ?
* support for numbers in hexadecimal and binary formats
* `CGOTO` and `CGOSUB` - computatiuonal versions, should accept expressions
* `LABEL`, `LGOTO` and `LGOSUB` - jump to label
* some kind of subroutines with local variable namespace, possibly loaded from disc (like in Warsaw Basic 3.2)
* for Mega65 mode, move variables to a separate memory area, consider extending variable name length
* `←V` (verify from tape) - if Kernal is extended to offer this feature
* modulo function or opeerator
* `DPEEK`, `DPOKE`, `QPEEK`, `QPOKE` - 2/4 byte `PEEK` and `POKE` variants
* all the functions/commands accepting memory addresses should be able to access the whole Mega65 memory
* ability to limit memory used by basic to standard 38K or to 46K (memory model switch)
* `XOR` operator
* `AUTO` - line auto numbering
* `RENUMBER` for chanign the line numbers
* `IF ... THEN ... ELSE`, `BEGIN ... BEND`
* consider `BOOT` command
* possibly some commands for creating menus and dialog boxes
* more configurable `INPUT`
* `PRINT USING`, ability to position cursor, ability to print result in the center of the screen
* `CURSOR` command from BASIC V10
* `RESTORE` should accept lline number as argument
* hex/dec conversion functions
* `DELETE` command to delete several BASIC lines, as in BASIC V10
* `FOR` loop should accept integer variable as index
* `FETCH`, `STASH`, `SWAP` - REU support
* `DMA` command for Mega65
* geoRAM support
* `GO 64` / `GO 65` should enable/disable C64 compatibility mode on Mega65
* `NSYS` for Mega65 - native `SYS` for Mega65, should not switch to C64 compatibilty mode
* `DO ... LOOP`, `DO ... UNTIL`, `DO ... WHILE`, `EXIT`
* `SEEK#` to read-and-forget n bytes
* `RECORD#` command from BASIC V10
* `GETKEY` from BASIC V10
* `HELP` command from BASIC V7/V10
* function to find substring position
* `WINDOW` command from BASIC V7
* functions to return cursor position
* `TRAP` and `RESUME`
* `SET DEF` and `SET DISK` from BASIC V10
* `SLEEP` from BASIC V10
* `TRON` / `TROFF` - program tracing
* `TYPE` command from BASIC V10
* `RUN` should be able to run program from device, as in BASIC V10
* `PAGE` and `DELAY` commands from Simons BASIC, or something similar
* `DUMP` command from Simons BASIC, or something similar
* it should be possbile to assign to `TI` special variable
* function to insert a substring starting from given position
* function to generate string of n duplicated characters
* function to retrieve fractional part of a number
* command to fill text screen area with a character, inverse screen area, scroll, or change fg/bg color of screen area
+48 -25
View File
@@ -7,19 +7,19 @@ NOTE: Command syntax, behaviour details, and tokens are still subject to change!
The DOS Wedge commands are only available in direct mode, and they have to start from the first character of the line.
### `@`
### `@` (all)
Displays the error/status read from the current drive. Current drive is either the last device used by any I/O command, the one set by DOS Wedge command, or 8 as a fallback.
### `@$`
### `@$` (all)
Displays the directory of the current drive. Does not destroy BASIC program in memory.
### `@device_number`
### `@device_number` (all)
Changes the current drive number.
### `@command`
### `@command` (all)
Sends the DOS command to the current drive.
@@ -27,44 +27,67 @@ Sends the DOS command to the current drive.
The Tape Wedge commands are only available in direct mode, and they have to start from the first character of the line.
### `←L ["file_name"]`
### `←L ["file_name"]` (all)
Loads the file from tape. Depending on the configuration, it tries to load the file in TurboTape 64 format, in the standard CBM format, or autodetects the file format.
### `←M ["file_name"]`
### `←M ["file_name"]` (all)
Like above, but merges a BASIC program to the one already stored in memory.
### `←H`
### `←H` (Mega65)
Launches a built-in tape head alignment tool. Destorys program in memory. Press `RUN/STOP` to terminate the tool.
Launches a built-in tape head alignment tool. Destroys program in memory. Press `RUN/STOP` to terminate the tool.
## Additional BASIC commands
## Additional BASIC commands - I/O
### `FAST`
Tries to switch the machine to turbo mode - details differ depending on the configured machine / motherboard.
### `SLOW`
Tries to switch the machine back to 1 MHz operation mode.
### `OLD`
Tries to restore program destroyed by `NEW` or a reset.
### `MERGE "file_name" [, device_number]`
### `MERGE "file_name" [, device_number]` (all)
Appends the BASIC program from a storage medium to the one currently present in memory.
### `BLOAD "file_name", device_number, start_address`
### `BLOAD "file_name", device_number, start_address` (all)
Loads a binary file starting from the given memory location. Does not clear variables, does not perform BASIC program relinking, etc. NOTE: for now syntax differs from the BASIC V3.5+ - this will be changed once the necessary BASIC infrastructure is implemented.
### `BVERIFY "file_name", device_number, start_address`
### `BVERIFY "file_name", device_number, start_address` (all)
Verify operation for the binary data starting from a given addres. NOTE: for now syntax differs from the BASIC V3.5+ - this will be changed once the necessary BASIC infrastructure is implemented.
### `BSAVE "file_name", device_number, start_address, end_address`
### `BSAVE "file_name", device_number, start_address, end_address` (all)
Saves the binary data from the given memory area. NOTE: for now syntax differs from the BASIC V3.5+ - this will be changed once the necessary BASIC infrastructure is implemented.
## Additional BASIC commands - misc
### `COLD` (Mega65)
Resets the machine. In direct mode asks for confirmation first.
### `FAST` (all)
Tries to switch the machine to turbo mode - details differ depending on the configured machine / motherboard.
### `SLOW` (all)
Tries to switch the machine back to 1 MHz operation mode.
### `OLD` (all)
Tries to restore program destroyed by the `NEW` command or a reset.
### `MEM` (Mega65)
Displays BASIC memory usage information:
* `TEXT` - size of BASIC program text, always at least 2 bytes are used
* `VARS` - bytes occupied by float and integer variables, string variable descriptors, and function descriptors
* `ARRS` - bytes occupied by arrays (note: for string arrays only descriptors are stored here)
* `STRS` - bytes occupied by strings, also the ones belonging to arrays
* `FREE` - unused space
### `CLEAR` (all)
Clears the screen content.
### `DISPOSE` (all)
Runs the garbage collector - disposes outdated strings.
Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

+7
View File
@@ -364,3 +364,10 @@
.const CONFIG_COLOR_TXT = $01
#endif
// Determine if we need space-savings in BASIC code
#if !ROM_LAYOUT_M65
#define HAS_SMALL_BASIC
#endif
+14
View File
@@ -425,3 +425,17 @@ __l:
__l:
#endif
}
//
// Near jump, on some CPUs can be substituted with shorter instruction
//
.pseudocommand jmp_8 dst
{
#if HAS_OPCODES_65C02
bra dst
#else
jmp dst
#endif
}
+6 -12
View File
@@ -35,8 +35,8 @@
.label RESHO = $26 // $26-$2A temporary variables, [!] our usage might be different
.label TXTTAB = $2B // $2B-$2C start of BASIC code
.label VARTAB = $2D // $2D-$2E end of BASIC code, start of variables
.label ARYTAB = $2F // $2F-$30 -- NOT IMPLEMENTED --
.label STREND = $31 // $31-$32 -- NOT IMPLEMENTED --
.label ARYTAB = $2F // $2F-$30 pointer to start of array storage
.label STREND = $31 // $31-$32 pointer to start of free RAM
.label FRETOP = $33 // $33-$34 pointer to bottom of strings area
.label FRESPC = $35 // $35-$36 [!] our implementation uses this as temporary string pointer
.label MEMSIZ = $37 // $37-$38 highest address of BASIC memory + 1
@@ -46,14 +46,14 @@
.label DATLIN = $3F // $3F-$40 -- NOT IMPLEMENTED --
.label DATPTR = $41 // $41-$42 pointer for READ/DATA copmmands
.label INPPTR = $43 // $43-$44 -- NOT IMPLEMENTED --
.label VARNAM = $45 // $45-$46 -- NOT IMPLEMENTED --
.label VARPNT = $47 // $47-$48 -- NOT IMPLEMENTED --
.label VARNAM = $45 // $45-$46 current variable name
.label VARPNT = $47 // $47-$48 current variable/descriptor pointer
.label FORPNT = $49 // $49-$4A -- NOT IMPLEMENTED --
.label OPPTR = $4B // $4B-$4C helper variable for expression computation, [!] our usage details are different
.label OPMASK = $4D // -- NOT IMPLEMENTED --
.label DEFPNT = $4E // $4E-$4F -- NOT IMPLEMENTED --
.label DSCPNT = $50 // $50-$52 -- NOT IMPLEMENTED --
.label FOUR6 = $53 // -- NOT IMPLEMENTED --
.label DSCPNT = $50 // $50-$52 temporary area fro string handling, [!] our usage might differ
.label FOUR6 = $53 // size of variable content (float = 5, integer = 2, string descriptor = 3)
.label JMPER = $54 // $54-$56 -- NOT IMPLEMENTED --
.label TEMPF1 = $57 // $57-$5B BASIC numeric work area
.label TEMPF2 = $5C // $5C-$60 BASIC numeric work area
@@ -71,12 +71,6 @@
.label FAC2_mantissa = $6A // $6A - $6D
.label FAC2_sign = $6E
// We re-use FAC2 for memory move pointers, since we cannot be doing calculations while moving memory
.label memmove__src = $69
.label memmove__dst = $6B
.label memmove__size = $6D
.label ARISGN = $6F // -- NOT IMPLEMENTED --
.label FACOV = $70 // FAC1 low order mantissa
.label FBUFPT = $71 // $71-$72 -- NOT IMPLEMENTED --
+3
View File
@@ -32,8 +32,11 @@
.label panic = KERNAL().panic
#endif
.label vector_reset = KERNAL().vector_reset
.label hw_entry_reset = KERNAL().hw_entry_reset
.label clear_screen = KERNAL().clear_screen
#if CONFIG_DBG_PRINTF
.label printf = KERNAL().printf
#endif
File renamed without changes.
@@ -4,6 +4,6 @@
// #LAYOUT# * * #IGNORE
packed_freq_keywords_CC:
packed_freq_keywords_01:
put_packed_freq_keywords_CC()
put_packed_freq_keywords_01()
@@ -3,7 +3,10 @@
// #LAYOUT# X16 BASIC_0 #TAKE
// #LAYOUT# * * #IGNORE
#if !HAS_SMALL_BASIC
packed_freq_keywords_CD:
packed_freq_keywords_02:
put_packed_freq_keywords_CD()
put_packed_freq_keywords_02()
#endif
+29
View File
@@ -0,0 +1,29 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# * BASIC_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// Table to TI$ special variable support
//
table_TI_hi:
#if !CONFIG_RS232_UP9600
.byte $20 // 10 hours = 2169000 ticks
.byte $03 // 1 hour = 216000 ticks
.byte $00 // 10 minutes = 36000 ticks
.byte $00 // 1 minute = 3600 ticks
.byte $00 // 10 seconds = 600 ticks
.byte $00 // 1 second = 60 ticks
#else
.byte $23 // 10 hours = 2304000 ticks
.byte $03 // 1 hour = 230400 ticks
.byte $00 // 10 minutes = 38400 ticks
.byte $00 // 1 minute = 3840 ticks
.byte $00 // 10 seconds = 640 ticks
.byte $00 // 1 second = 64 ticks
#endif
+29
View File
@@ -0,0 +1,29 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# * BASIC_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// Table to TI$ special variable support
//
table_TI_lo:
#if !CONFIG_RS232_UP9600
.byte $80 // 10 hours = 2169000 ticks
.byte $C0 // 1 hour = 216000 ticks
.byte $A0 // 10 minutes = 36000 ticks
.byte $10 // 1 minute = 3600 ticks
.byte $58 // 10 seconds = 600 ticks
.byte $3C // 1 second = 60 ticks
#else
.byte $00 // 10 hours = 2304000 ticks
.byte $00 // 1 hour = 230400 ticks
.byte $00 // 10 minutes = 38400 ticks
.byte $00 // 1 minute = 3840 ticks
.byte $80 // 10 seconds = 640 ticks
.byte $40 // 1 second = 64 ticks
#endif
+29
View File
@@ -0,0 +1,29 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# * BASIC_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// Table to TI$ special variable support
//
table_TI_mid:
#if !CONFIG_RS232_UP9600
.byte $F5 // 10 hours = 2169000 ticks
.byte $4B // 1 hour = 216000 ticks
.byte $8C // 10 minutes = 36000 ticks
.byte $0E // 1 minute = 3600 ticks
.byte $02 // 10 seconds = 600 ticks
.byte $00 // 1 second = 60 ticks
#else
.byte $28 // 10 hours = 2304000 ticks
.byte $84 // 1 hour = 230400 ticks
.byte $96 // 10 minutes = 38400 ticks
.byte $0F // 1 minute = 3840 ticks
.byte $02 // 10 seconds = 640 ticks
.byte $00 // 1 second = 64 ticks
#endif
+4 -4
View File
@@ -17,13 +17,13 @@
cmd_data,
cmd_inputhash,
cmd_input,
cmd_dim,
array_create, // cmd_dim
cmd_read,
cmd_let,
assign_variable, // cmd_let
cmd_goto,
cmd_run,
cmd_if,
cmd_restore,
do_restore, // cmd_restore
cmd_gosub,
cmd_return,
cmd_rem,
@@ -42,7 +42,7 @@
cmd_print,
cmd_cont,
cmd_list,
cmd_clr,
do_clr, // cmd_clr
cmd_cmd,
cmd_sys,
cmd_open,
@@ -19,12 +19,8 @@ cmd_inputhash:
nop
cmd_input:
nop
cmd_dim:
nop
cmd_read:
nop
cmd_let:
nop
cmd_if:
nop
cmd_gosub:
+2 -6
View File
@@ -3,10 +3,6 @@
// #LAYOUT# * * #IGNORE
cmd_clr:
// PLACEHOLDER for completeness - jumptable contains direct address
jsr do_clr
// CLR command does not stop execution (confirmed on a C64)
jmp execute_statements
// CLR command does not stop execution (confirmed on a C64)
+6
View File
@@ -0,0 +1,6 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# * BASIC_0 #TAKE
// #LAYOUT# * * #IGNORE
// PLACEHOLDER for completeness - jumptable contains direct address
+6
View File
@@ -0,0 +1,6 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# * BASIC_0 #TAKE
// #LAYOUT# * * #IGNORE
// PLACEHOLDER for completeness - jumptable contains direct address
+1 -1
View File
@@ -31,7 +31,7 @@ list_loop:
// LIST terminates any running program,
// because it has fiddled with the current line pointer.
// (Confirmed by testing on a C64)
jmp shell_main_loop
jmp end_of_program
list_more_lines:
+5 -6
View File
@@ -52,7 +52,7 @@ cmd_load_no_error:
// For VERIFY - this is it
lda VERCKB
bne_16 execute_statements
bne_16 end_of_statement
// C64 BASIC apparently does not clear variables after a LOAD in the
// middle of a program. For safety, we do.
@@ -74,10 +74,9 @@ cmd_load_no_error:
ldx CURLIN+1
inx
beq cmd_load_end // branch if direct mode
beq_16 end_of_program // branch if direct mode
pha
pha
jmp execute_line
cmd_load_end:
jmp shell_main_loop
+1 -1
View File
@@ -9,4 +9,4 @@ cmd_new:
// NEW command terminates execution (confirmed on a C64)
jmp shell_main_loop
jmp end_of_program
+23 -13
View File
@@ -8,7 +8,7 @@ cmd_print:
// First check if we have anything to print
jsr end_of_statement_check
jsr is_end_of_statement
bcs cmd_print_new_line_done
jsr fetch_character
@@ -19,14 +19,19 @@ cmd_print:
cmd_print_loop:
#if !HAS_OPCODES_65CE02
jsr unconsume_character
#else
dew TXTPTR
#endif
// FALLTROUGH
cmd_print_after_comma:
// Now evaluate the expression
// Now evaluate the expression and check what to print
jsr tmpstr_free_all
jsr FRMEVL
lda VALTYP
bpl cmd_print_float
@@ -37,42 +42,45 @@ cmd_print_string:
// Print a string value
#if CONFIG_MEMORY_MODEL_46K || CONFIG_MEMORY_MODEL_50K
jsr helper_print_string
jmp_8 cmd_print_next_arg
#else // CONFIG_MEMORY_MODEL_38K || CONFIG_MEMORY_MODEL_60K
ldy #$00
!:
cpy __FAC1 + 0
beq cmd_print_next_arg
#if CONFIG_MEMORY_MODEL_60K
ldx #<(__FAC1 + 1)
jsr peek_under_roms
#elif CONFIG_MEMORY_MODEL_46K || CONFIG_MEMORY_MODEL_50K
jsr peek_under_roms_via_FAC1_PLUS_1
#else // CONFIG_MEMORY_MODEL_38K
lda (__FAC1 + 1), y
#endif
jsr JCHROUT
iny
jmp !-
bpl !-
#endif
cmd_print_float:
// XXX probably we should also check INTFLG here
// XXX provide implementation
jmp do_NOT_IMPLEMENTED_error
// FALLTROUGH
cmd_print_next_arg:
// Look for the next argument
jsr end_of_statement_check
jsr is_end_of_statement
bcs cmd_print_new_line_done
cmp #$2C // comma XXX on C64 behavior is more complicated, fix it
@@ -89,4 +97,6 @@ cmd_print_new_line_done:
cmd_print_done:
jmp execute_statements
// Execute next statement
rts
+2
View File
@@ -7,4 +7,6 @@
cmd_rem:
pha
pha
jmp execute_statements_end_of_line
+2 -6
View File
@@ -3,10 +3,6 @@
// #LAYOUT# * * #IGNORE
cmd_restore:
// PLACEHOLDER for completeness - jumptable contains direct address
jsr do_restore
// RESTORE command does not stop execution (confirmed on a C64)
jmp execute_statements
// RESTORE command does not stop execution (confirmed on a C64)
+67 -11
View File
@@ -4,24 +4,80 @@
cmd_run:
// RUN clears all variables
jsr do_clr
cmd_goto:
// Disable Kernal messages
// Initialize OLDTXT pointer, disable Kernal messages
jsr init_oldtxt
lda #$00
jsr JSETMSG
// Reset line pointer to first line of program.
jsr init_oldtxt
// Check if we have any paramenters
jsr end_of_statement_check
bcs !+
jsr is_end_of_statement
bcs cmd_run_goto_launch
jsr basic_parse_line_number
jsr find_line
bcc !+
// Line does not exist, so report error
jmp do_UNDEFD_STATEMENT_error
// FALLTROUGH
cmd_goto:
// GOTO requires line number
jsr fetch_line_number
bcs_16 do_SYNTAX_error
// Check for direct mode
lda CURLIN+1
bmi cmd_goto_direct
// Not a direct mode - compare desired line number (LINNUM) with the current one (CURLIN)
lda LINNUM+1
cmp CURLIN+1
bne !+
lda LINNUM+0
cmp CURLIN+0
!:
// If desired line number is lower - search line number from start
bcc cmd_goto_from_start
// Else - search from the current line
jsr find_line_from_current
jmp_8 cmd_goto_check
cmd_goto_direct:
// Disable Kernal messages
lda #$00
jsr JSETMSG
// FALLTROUGH
cmd_goto_from_start:
// Direct mode - find the line from the beginning
jsr find_line_from_start
// FALLTROUGH
cmd_goto_check:
bcs_16 do_UNDEFD_STATEMENT_error
// FALLTROUGH
cmd_run_goto_launch:
// Run it!
pha
pha
jmp execute_line
+2 -2
View File
@@ -38,6 +38,6 @@ cmd_save_do: // entry point for BSAVE
jsr JSAVE
bcs_16 do_kernal_error
// The end
// Execute next statement
jmp execute_statements
rts
+1 -1
View File
@@ -27,4 +27,4 @@ cmd_stop:
cmd_end:
jmp shell_main_loop
jmp end_of_program
+5 -6
View File
@@ -5,7 +5,7 @@
cmd_sys:
jsr end_of_statement_check
jsr is_end_of_statement
bcc !+
// SYS requires an argument
@@ -41,7 +41,9 @@ cmd_sys_hack_not_needed:
// XXX End of hack
//
jsr basic_parse_line_number
lda #IDX__EV2_0B // 'SYNTAX ERROR'
jsr fetch_uint16
bcs_16 do_SYNTAX_error
cmd_sys_setup_call:
lda #$4C // JMP opcode
@@ -60,10 +62,7 @@ cmd_sys_setup_call:
plp
// Call the routine.
jsr USRPOK
jmp execute_statements
jmp USRPOK
//
// XXX Temporary ugly hack to support 'SYS PI*656'
@@ -11,7 +11,7 @@ helper_load_fetch_filename:
// Check if end of statement
jsr end_of_statement_check
jsr is_end_of_statement
bcs !+
// Call the expression parser, make sure it returned a string
@@ -0,0 +1,27 @@
// #LAYOUT# STD * #TAKE-HIGH
// #LAYOUT# * BASIC_0 #TAKE-HIGH
// #LAYOUT# * * #IGNORE
// This has to go $E000 or above - routine below banks out the main BASIC ROM!
#if CONFIG_MEMORY_MODEL_46K || CONFIG_MEMORY_MODEL_50K
helper_print_string:
// Unmap BASIC lower ROM
lda #$26
sta CPU_R6510
// Print the string
ldy #$00
!:
cpy __FAC1 + 0
beq_16 remap_BASIC // branch if end of the string
lda (__FAC1 + 1), y
jsr JCHROUT
iny
bpl !-
#endif
@@ -0,0 +1,49 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# * BASIC_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// Jumptable for BASIC commands with tokens prefixed by $01
//
.const command_01_list = List().add(
cmd_slow,
cmd_fast,
cmd_old,
// NOTE! These commands are temporarily placed here, they should be a part of list 02!
cmd_merge,
cmd_bload,
cmd_bsave,
cmd_bverify,
cmd_clear,
varstr_garbage_collect // cmd_dispose
)
#if !HAS_OPCODES_65C02
command_01_jumptable_lo:
put_jumptable_lo(command_01_list)
command_01_jumptable_hi:
put_jumptable_hi(command_01_list)
#else // HAS_OPCODES_65C02
command_01_jumptable:
// Note: 65C02 has the page boundary vector bug fixed!
put_jumptable(command_01_list)
#endif
@@ -20,8 +20,8 @@ cmd_fast:
lda #$41
sta CPU_D6510
rts
jmp execute_statements
#elif CONFIG_MB_ULTIMATE_64
@@ -30,12 +30,12 @@ cmd_fast:
cmd_slow:
sta SCPU_SPEED_NORMAL
jmp execute_statements
rts
cmd_fast:
sta SCPU_SPEED_TURBO
jmp execute_statements
rts
#elif CONFIG_PLATFORM_COMMODORE_64
@@ -60,14 +60,13 @@ cmd_fast:
lda #$01
!:
sta VIC_CLKRATE
jmp execute_statements
rts
#else
cmd_slow:
nop // to prevent double label
nop // just to prevent double label
// FALLTROUGH
@@ -21,4 +21,4 @@ cmd_old:
// Quit
jmp shell_main_loop
jmp end_of_program
@@ -0,0 +1,51 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# * BASIC_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// Jumptable for BASIC commands with tokens prefixed by $02
//
#if !HAS_SMALL_BASIC
.const command_02_list = List().add(
// NOTE! These commands are temporarily placed in list 01!
// cmd_merge,
// cmd_bload,
// cmd_bsave,
// cmd_bverify,
// cmd_clear,
// varstr_garbage_collect, // cmd_dispose
cmd_cold,
cmd_mem
)
#if !HAS_OPCODES_65C02
command_02_jumptable_lo:
put_jumptable_lo(command_02_list)
command_02_jumptable_hi:
put_jumptable_hi(command_02_list)
#else // HAS_OPCODES_65C02
command_02_jumptable:
// Note: 65C02 has the page boundary vector bug fixed!
put_jumptable(command_02_list)
#endif
#endif
@@ -37,6 +37,6 @@ cmd_bload:
jsr JLOAD
bcs_16 do_kernal_error
// XXX when number parsing is done, change to continue execution
// Execute next statement
jmp shell_main_loop
rts
+10
View File
@@ -0,0 +1,10 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# * BASIC_0 #TAKE
// #LAYOUT# * * #IGNORE
cmd_clear:
// XXX in the future add separate implementation for graphics screen
jmp clear_screen
+18
View File
@@ -0,0 +1,18 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# * BASIC_0 #TAKE
// #LAYOUT# * * #IGNORE
#if !HAS_SMALL_BASIC
cmd_cold:
jsr helper_ask_if_sure
bcs !+
jsr JCLALL // for extra safety
jmp (vector_reset) // hardware CPU vector
!:
rts
#endif
@@ -0,0 +1,6 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# * BASIC_0 #TAKE
// #LAYOUT# * * #IGNORE
// PLACEHOLDER for completeness - jumptable contains direct address
+149
View File
@@ -0,0 +1,149 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# M65 * #TAKE
// #LAYOUT# X16 BASIC_0 #TAKE
// #LAYOUT# * * #IGNORE
#if !HAS_SMALL_BASIC
#if (!ROM_LAYOUT_M65 || SEGMENT_BASIC_0)
cmd_mem:
// First perform the garbage collection - to be able to determine real values
jsr varstr_garbage_collect
#endif // ROM layout
#if (ROM_LAYOUT_M65 && SEGMENT_BASIC_0)
jsr map_BASIC_1
jsr_ind VB1__cmd_mem_cont
jmp map_NORMAL
#else
#if (ROM_LAYOUT_M65 && SEGMENT_BASIC_1)
cmd_mem_cont:
#endif
// Print header
lda #$12
jsr JCHROUT
ldx #IDX__STR_MEM_HDR
jsr print_packed_misc_str
// Print all the information, in a loop, in reverse order
ldy #$04
// FALLTROUGH
cmd_mem_loop:
// First print the information string
ldx helper_mem_tab_str, y
phy_trash_a
jsr print_packed_misc_str
// Print start address
ldx #IDX__STR_MEM_1
jsr print_packed_misc_str
#if HAS_OPCODES_65C02
ply
phy
#else
pla
pha
tay
#endif
ldx helper_mem_tab_y, y
lda $01, x
jsr print_hex_byte
#if HAS_OPCODES_65C02
ply
phy
#else
pla
pha
tay
#endif
ldx helper_mem_tab_y, y
lda $00, x
jsr print_hex_byte
ldx #IDX__STR_MEM_2
jsr print_packed_misc_str
// Fetch addresses of zeropage variables
#if HAS_OPCODES_65C02
ply
phy
#else
pla
pha
tay
#endif
ldx helper_mem_tab_x, y
lda helper_mem_tab_y, y
tay
// Print difference between two zeropage variables
sec
lda $00, x
sbc $0000, y
pha
inx
iny
lda $00, x
sbc $0000, y
#if HAS_OPCODES_65C02
plx
#else
tay
pla
tax
tya
#endif
// Before printing, make sure the result is not negative
bcs !+
lda #$3F
jsr JCHROUT
jmp_8 cmd_mem_next
!:
jsr print_integer
// FALLTROUGH
cmd_mem_next:
// Check if more iterations needed
ply_trash_a
dey
bpl cmd_mem_loop
// Finish
jmp print_return
#endif // ROM layout
#endif // !HAS_SMALL_BASIC
@@ -42,10 +42,6 @@ cmd_merge_got_params:
cmd_merge_no_error:
// Relink loaded program, clear variables
// Relink loaded program, clear variables, execute next statement
jsr update_LINKPRG_VARTAB_do_clr
// XXX when number parsing is done, change to continue execution
jmp shell_main_loop
jmp update_LINKPRG_VARTAB_do_clr
@@ -0,0 +1,81 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# M65 BASIC_1 #TAKE
// #LAYOUT# * BASIC_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// For direct mode, asks the user if he is sure (sets Carry if not);
// otherwise returns with Carry clear
//
#if !HAS_SMALL_BASIC
helper_ask_if_sure:
#if (ROM_LAYOUT_M65 && SEGMENT_BASIC_0)
jsr map_BASIC_1
jsr_ind VB1__helper_ask_if_sure
jmp map_NORMAL
#else
// First check, if we are in direct mode,; if not, do not ask
ldx CURLIN+1
inx
bne helper_ask_if_sure_ok // branch if not direct mode
// Not direct mode - display the question
ldx #IDX__STR_IF_SURE
jsr print_packed_misc_str
// Clear the keyboard queue
lda #$00
sta NDX
// Enable cursor, fetch the answer
lda #$00
sta BLNSW
!:
jsr JGETIN
cmp #$00
beq !-
// Check if 'Y'
cmp #$59
beq !+
lda #$4E // 'N'
jsr JCHROUT
sec
rts
!:
// Display 'Y' and wait a short moment for a better user experience
jsr JCHROUT
clc
lda TIME+2
adc #$0C
!:
cmp TIME+2
bne !-
// FALLTROUGH
helper_ask_if_sure_ok:
clc
rts
#endif // ROM layout
#endif // !HAS_SMALL_BASIC
@@ -12,7 +12,9 @@ helper_bload_fetch_address:
jsr injest_comma
bcs_16 do_SYNTAX_error
jsr basic_parse_line_number // XXX detect errors here
lda #IDX__EV2_0B // 'SYNTAX ERROR'
jsr fetch_uint16
bcs_16 do_SYNTAX_error
ldx LINNUM+0
ldy LINNUM+1
@@ -0,0 +1,20 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# M65 BASIC_1 #TAKE
// #LAYOUT# X16 BASIC_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// Helper table for 'MEM' command - list of strings to print
//
#if !HAS_SMALL_BASIC
helper_mem_tab_str:
.byte IDX__STR_MEM_FREE
.byte IDX__STR_MEM_STRS
.byte IDX__STR_MEM_ARRS
.byte IDX__STR_MEM_VARS
.byte IDX__STR_MEM_TEXT
#endif
@@ -0,0 +1,20 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# M65 BASIC_1 #TAKE
// #LAYOUT# X16 BASIC_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// Helper table for 'MEM' command - list of minuend zeropage variables
//
#if !HAS_SMALL_BASIC
helper_mem_tab_x:
.byte FRETOP
.byte MEMSIZ
.byte STREND
.byte ARYTAB
.byte VARTAB
#endif
@@ -0,0 +1,20 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# M65 BASIC_1 #TAKE
// #LAYOUT# X16 BASIC_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// Helper table for 'MEM' command - list of subtrahend zeropage variables
//
#if !HAS_SMALL_BASIC
helper_mem_tab_y:
.byte STREND
.byte FRETOP
.byte ARYTAB
.byte VARTAB
.byte TXTTAB
#endif
@@ -1,51 +0,0 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# * BASIC_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// Jumptable for BASIC commands with tokens prefixed by $CC
//
.const command_CC_list = List().add(
cmd_merge,
cmd_bload,
cmd_bsave,
cmd_bverify,
cmd_old
)
#if !HAS_OPCODES_65C02
command_CC_jumptable_lo:
put_jumptable_lo(command_CC_list)
command_CC_jumptable_hi:
put_jumptable_hi(command_CC_list)
#else // HAS_OPCODES_65C02
__before_command_CC_jumptable:
.if (mod(*, $2) == 1) { brk } // align code so that vector never crosses page boundary
command_CC_jumptable:
put_jumptable(command_CC_list)
// Make sure routine size is always the same - build system limitation
.if (__before_command_CC_jumptable == command_CC_jumptable) { brk }
#endif
@@ -1,46 +0,0 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# * BASIC_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// Jumptable for BASIC commands with tokens prefixed by $CD
//
.const command_CD_list = List().add(
cmd_slow,
cmd_fast
)
#if !HAS_OPCODES_65C02
command_CD_jumptable_lo:
put_jumptable_lo(command_CD_list)
command_CD_jumptable_hi:
put_jumptable_hi(command_CD_list)
#else // HAS_OPCODES_65C02
__before_command_CD_jumptable:
.if (mod(*, $2) == 1) { brk } // align code so that vector never crosses page boundary
command_CD_jumptable:
put_jumptable(command_CD_list)
// Make sure routine size is always the same - build system limitation
.if (__before_command_CD_jumptable == command_CD_jumptable) { brk }
#endif
+1 -10
View File
@@ -55,18 +55,9 @@ function_jumptable_hi:
#else // HAS_OPCODES_65C02
__before_function_jumptable:
.if (mod(*, $2) == 1) { brk } // align code so that vector never crosses page boundary
function_jumptable:
// Note: 65C02 has the page boundary vector bug fixed!
put_jumptable(function_list)
// Make sure routine size is always the same - build system limitation
.if (__before_function_jumptable == function_jumptable) { brk }
#endif
+96 -7
View File
@@ -9,8 +9,8 @@ oper_add:
// First check whether arguments match and then choose the variant
pla
cmp VALTYP
bne_16 do_TYPE_MISMATCH_error
eor VALTYP
bmi_16 do_TYPE_MISMATCH_error
lda VALTYP
bmi oper_add_strings
@@ -36,13 +36,18 @@ oper_add_strings:
pla
sta __FAC2+0
beq oper_add_strings_end // if string 2 is empty, we have nothing to do
// If string 2 is empty, release it and quit
beq oper_add_strings_end
// If string 1 is empty, just copy the metadata
lda __FAC1+0
bne !+
jsr tmpstr_free_FAC1
lda __FAC2+0
sta __FAC1+0
lda __FAC2+1
@@ -52,21 +57,105 @@ oper_add_strings:
jmp FRMEVL_continue
!:
// Allocate memory for concatenated string
// Allocate memory for the concatenated string
clc
adc __FAC2+0
bcs_16 do_STRING_TOO_LONG_error
jsr alloc_temp_string
jsr tmpstr_alloc
.break
// Copy the temporary string pointer to INDEX
ldy #$01
lda (VARPNT), y
sta INDEX+0
iny
lda (VARPNT), y
sta INDEX+1
// Perform the concatenation
// XXX finish the implementation
#if CONFIG_MEMORY_MODEL_60K
// Copy data from the first string
ldy #$00
!:
ldx #<(__FAC2+1)
jsr peek_under_roms
ldx #<INDEX
jsr poke_under_roms
iny
cpy __FAC2+0
bne !-
// Increase INDEX pointer by the size of the 1st string
tya
jsr helper_INDEX_up_A
// Copy data from the second string
ldy #$00
!:
ldx #<(__FAC1+1)
jsr peek_under_roms
ldx #<INDEX
jsr poke_under_roms
iny
cpy __FAC1+0
bne !-
#elif CONFIG_MEMORY_MODEL_46K || CONFIG_MEMORY_MODEL_50K
jsr helper_strconcat
#else // CONFIG_MEMORY_MODEL_38K
// Copy data from the first string
ldy #$00
!:
lda (__FAC2+1),y
sta (INDEX),y
iny
cpy __FAC2+0
bne !-
// Increase INDEX pointer by the size of the 1st string
tya
jsr helper_INDEX_up_A
// Copy data from the second string
ldy #$00
!:
lda (__FAC1+1),y
sta (INDEX),y
iny
cpy __FAC1+0
bne !-
#endif
// Free old FAC1 string - if it was temporary
jsr tmpstr_free_FAC1
// Copy the descriptor to __FAC1
ldy #$02
!:
lda (VARPNT), y
sta __FAC1, y
dey
bpl !-
// FALLTROUGH
oper_add_strings_end:
jsr tmpstr_free_FAC2
jmp FRMEVL_continue
-31
View File
@@ -1,31 +0,0 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# * BASIC_0 #TAKE
// #LAYOUT# * * #IGNORE
basic_parse_line_number:
jsr injest_number
// Check if the number is a valid line number
// i.e., 16 bits, no exponent, no decimal
lda FAC1_mantissa+2
ora FAC1_mantissa+3
ora FAC1_exponent
beq !+
ml_bad_line_number:
// Invalid line number
jmp do_ILLEGAL_QUANTITY_error
!:
// Line number are not allowed to have decimal points in them
lda __tokenise_work4
cmp #$FF
bne ml_bad_line_number
// Got a valid line number.
lda FAC1_mantissa+0
sta LINNUM+0
lda FAC1_mantissa+1
sta LINNUM+1
clc
rts
@@ -9,21 +9,29 @@
#if SEGMENT_BASIC_0
// Label definitions
.label VB1__INITMSG = $4000 + 2 * 0
.label VB1__LINKPRG = $4000 + 2 * 1
.label VB1__tokenise_line = $4000 + 2 * 2
.label VB1__list_single_line = $4000 + 2 * 3
.label VB1__print_packed_error = $4000 + 2 * 4
.label VB1__print_packed_misc_str = $4000 + 2 * 5
.label VB1__do_new = $4000 + 2 * 6
.label VB1__do_clr = $4000 + 2 * 7
.label VB1__do_restore = $4000 + 2 * 8
.label VB1__INITMSG = $4000 + 2 * 0
.label VB1__LINKPRG = $4000 + 2 * 1
.label VB1__tokenise_line = $4000 + 2 * 2
.label VB1__list_single_line = $4000 + 2 * 3
.label VB1__print_packed_error = $4000 + 2 * 4
.label VB1__print_packed_misc_str = $4000 + 2 * 5
.label VB1__do_new = $4000 + 2 * 6
.label VB1__do_clr = $4000 + 2 * 7
.label VB1__do_restore = $4000 + 2 * 8
.label VB1__cmd_mem_cont = $4000 + 2 * 9
.label VB1__prepare_direct_execution = $4000 + 2 * 10
.label VB1__helper_ask_if_sure = $4000 + 2 * 11
#if CONFIG_DOS_WEDGE
.label VB1__wedge_dos = $4000 + 2 * 12
#endif
#else
// Vector table (OpenROMs private!)
// Vector table (Open ROMs private!)
.word INITMSG
.word LINKPRG
@@ -34,5 +42,13 @@
.word do_new
.word do_clr
.word do_restore
.word cmd_mem_cont
.word prepare_direct_execution
.word helper_ask_if_sure
#if CONFIG_DOS_WEDGE
.word wedge_dos
#endif
#endif
+20 -1
View File
@@ -12,15 +12,34 @@
.label poke_via_OLDTXT = BASIC_0.proxy_B1_poke_via_OLDTXT
.label JCHROUT = BASIC_0.proxy_B1_JCHROUT
.label JCLALL = BASIC_0.proxy_B1_JCLALL
#if CONFIG_DOS_WEDGE
.label JCLOSE = BASIC_0.proxy_B1_JCLOSE
.label JOPEN = BASIC_0.proxy_B1_JOPEN
#endif
.label JMEMTOP = KERNAL_0.JMEMTOP
.label JSETFLS = KERNAL_0.JSETFLS
.label JSETNAM = KERNAL_0.JSETNAM
.label JGETIN = KERNAL_0.JGETIN
.label JCHKIN = KERNAL_0.JCHKIN
.label JCHRIN = KERNAL_0.JCHRIN
.label JREADST = KERNAL_0.JREADST
.label plot_set = KERNAL_0.plot_set
.label init_oldtxt = BASIC_0.init_oldtxt
.label tmpstr_free_all_reset = BASIC_0.tmpstr_free_all_reset
.label rom_revision_basic_string = BASIC_0.rom_revision_basic_string
.label print_hex_byte = BASIC_0.proxy_B1_print_hex_byte
.label print_integer = BASIC_0.proxy_B1_print_integer
.label print_return = BASIC_0.proxy_B1_print_return
.label print_space = BASIC_0.proxy_B1_print_space
#if CONFIG_SHOW_FEATURES
.label print_features = BASIC_0.proxy_B1_print_features
#endif
.label do_STRING_TOO_LONG_error = BASIC_0.do_STRING_TOO_LONG_error
.label do_error_fetch = BASIC_0.do_error_fetch
.label do_basic_error = BASIC_0.do_basic_error
.label str_rev_question = BASIC_0.str_rev_question
#if CONFIG_DOS_WEDGE
.label fetch_character = BASIC_0.proxy_B1_fetch_character
.label fetch_character_skip_spaces = BASIC_0.proxy_B1_fetch_character_skip_spaces
.label fetch_uint8 = BASIC_0.proxy_B1_fetch_uint8
.label shell_main_loop = BASIC_0.proxy_B1_shell_main_loop
#endif
+1 -1
View File
@@ -23,6 +23,6 @@ map_BASIC_1:
taz
lda #$20
ldx #$42 // 0x4000 <- map 8KB from 0x22000
ldx #$C2 // 0x4000 <- map 16KB from 0x22000
jmp map_end
+48
View File
@@ -36,6 +36,22 @@ proxy_B1_JCLALL:
jsr JCLALL
jmp map_BASIC_1
#if CONFIG_DOS_WEDGE
proxy_B1_JCLOSE:
jsr map_NORMAL
jsr JCLOSE
jmp map_BASIC_1
proxy_B1_JOPEN:
jsr map_NORMAL
jsr JOPEN
jmp map_BASIC_1
#endif
proxy_B1_JCHROUT:
@@ -43,6 +59,11 @@ proxy_B1_JCHROUT:
jsr JCHROUT
jmp map_BASIC_1
proxy_B1_print_hex_byte:
jsr map_NORMAL
jsr print_hex_byte
jmp map_BASIC_1
proxy_B1_print_integer:
@@ -74,3 +95,30 @@ proxy_B1_print_features:
jmp map_BASIC_1
#endif
#if CONFIG_DOS_WEDGE
proxy_B1_fetch_character:
jsr map_NORMAL
jsr fetch_character
jmp map_BASIC_1
proxy_B1_fetch_character_skip_spaces:
jsr map_NORMAL
jsr fetch_character_skip_spaces
jmp map_BASIC_1
proxy_B1_fetch_uint8:
jsr map_NORMAL
jsr fetch_uint8
jmp map_BASIC_1
proxy_B1_shell_main_loop:
jsr map_NORMAL
jmp shell_main_loop
#endif
-26
View File
@@ -1,26 +0,0 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# * BASIC_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// Allocates area for a temporary string
//
// Input:
// - .A - string length
//
// XXX - finish the implementation once string memory handling is done
alloc_temp_string:
// Check if temporary descriptor stack has a free slot
ldx LASTPT
cpx #$1F
bcs_16 do_FORMULA_TOO_COMPLEX_error
// XXX
jmp do_NOT_IMPLEMENTED_error
-45
View File
@@ -1,45 +0,0 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# * BASIC_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// Check for end of statement, sets Carry if so. Injests all spaces.
//
end_of_statement_check:
// XXX this can probably be size-optimized
ldy #$00
#if CONFIG_MEMORY_MODEL_60K
ldx #<TXTPTR
jsr peek_under_roms
#elif CONFIG_MEMORY_MODEL_46K || CONFIG_MEMORY_MODEL_50K
jsr peek_under_roms_via_TXTPTR
#else // CONFIG_MEMORY_MODEL_38K
lda (TXTPTR),y
#endif
// Injest any spaces
cmp #$20
bne !+
jsr consume_character
jmp end_of_statement_check
!:
cmp #$00
beq !+
cmp #$3A
beq !+
// Not end of statement
clc
rts
!:
// End of statement
sec
rts
-18
View File
@@ -1,18 +0,0 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# * BASIC_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// Injests all spaces
//
// XXX get rid of this when proper number parsing is implemented
injest_spaces:
jsr fetch_character
cmp #$20 // space, can be skipped
beq injest_spaces
jmp unconsume_character
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -3,29 +3,24 @@
// #LAYOUT# * * #IGNORE
// Find the BASIC line with number LINNUM
// XXX it should be possible to start from the current line (OLDTXT), or from the startup,
// depending on the current and target line number
// Find the BASIC line with number in LINNUM
find_line:
#if CONFIG_MEMORY_MODEL_38K || CONFIG_MEMORY_MODEL_60K
find_line_from_start:
// Get pointer to start of BASIC text
lda TXTTAB+0
sta OLDTXT+0
lda TXTTAB+1
sta OLDTXT+1
jsr init_oldtxt
// FALLTROUGH
find_line_loop:
find_line_from_current:
// Check if line is not empty
jsr peek_line_pointer_null_check
bcc find_line_fail
jsr is_line_pointer_null
beq find_line_fail
// Fetch the high byte of line number and compare
ldy #$03
@@ -33,8 +28,6 @@ find_line_loop:
#if CONFIG_MEMORY_MODEL_60K
ldx #<OLDTXT+0
jsr peek_under_roms
#elif CONFIG_MEMORY_MODEL_46K || CONFIG_MEMORY_MODEL_50K
jsr peek_under_roms_via_OLDTXT
#else // CONFIG_MEMORY_MODEL_38K
lda (OLDTXT),y
#endif
@@ -50,8 +43,6 @@ find_line_loop:
#if CONFIG_MEMORY_MODEL_60K
jsr peek_under_roms
#elif CONFIG_MEMORY_MODEL_46K || CONFIG_MEMORY_MODEL_50K
jsr peek_under_roms_via_OLDTXT
#else // CONFIG_MEMORY_MODEL_38K
lda (OLDTXT),y
#endif
@@ -70,16 +61,14 @@ find_line_next:
// Advance to the next line
jsr peek_line_pointer_null_check
bcc find_line_fail // branch in no more lines exist
jsr is_line_pointer_null
beq find_line_fail // branch in no more lines exist
ldy #$00
#if CONFIG_MEMORY_MODEL_60K
ldx #<OLDTXT+0
jsr peek_under_roms
#elif CONFIG_MEMORY_MODEL_46K || CONFIG_MEMORY_MODEL_50K
jsr peek_under_roms_via_OLDTXT
#else // CONFIG_MEMORY_MODEL_38K
lda (OLDTXT),y
#endif
@@ -89,8 +78,6 @@ find_line_next:
#if CONFIG_MEMORY_MODEL_60K
jsr peek_under_roms
#elif CONFIG_MEMORY_MODEL_46K || CONFIG_MEMORY_MODEL_50K
jsr peek_under_roms_via_OLDTXT
#else // CONFIG_MEMORY_MODEL_38K
lda (OLDTXT),y
#endif
@@ -99,13 +86,11 @@ find_line_next:
pla
sta OLDTXT+0
#if HAS_OPCODES_65C02
bra find_line_loop
#else
jmp find_line_loop
#endif
jmp_8 find_line_from_current
find_line_fail:
sec
rts
#endif
+101
View File
@@ -0,0 +1,101 @@
// #LAYOUT# STD * #TAKE-HIGH
// #LAYOUT# * BASIC_0 #TAKE-HIGH
// #LAYOUT# * * #IGNORE
// This has to go $E000 or above - routine below banks out the main BASIC ROM!
// Find the BASIC line with number in LINNUM
#if CONFIG_MEMORY_MODEL_46K || CONFIG_MEMORY_MODEL_50K
find_line_from_start:
// Get pointer to start of BASIC text
jsr init_oldtxt
// FALLTROUGH
find_line_from_current:
// Unmap BASIC lower ROM
lda #$26
sta CPU_R6510
// Check if line is not empty
jsr line_pointer_null_check // we can't use 'is_line_pointer_null', it maps out/in the BASIC ROM
beq remap_BASIC_sec_rts // search failed if there is no program
// Fetch the high byte of line number and compare
ldy #$03
lda (OLDTXT),y
cmp LINNUM+1
beq !+
bcs remap_BASIC_sec_rts // search failed if line number too high
bne find_line_next
!:
// Fetch the low byte of line number and compare
dey
lda (OLDTXT),y
cmp LINNUM+0
beq remap_BASIC_clc_rts
bcs remap_BASIC_sec_rts // search failed if line number too high
bne find_line_next
find_line_next:
// Advance to the next line
jsr line_pointer_null_check // we can't use 'is_line_pointer_null', it maps out/in the BASIC ROM
beq remap_BASIC_sec_rts // search failed if no more line exists
ldy #$00
lda (OLDTXT),y
pha
iny
lda (OLDTXT),y
sta OLDTXT+1
pla
sta OLDTXT+0
jmp_8 find_line_from_current
line_pointer_null_check: // reused by 'is_line_pointer_null'
// Check the pointer
ldy #$01 // for non-NULL pointer, high byte is almost certainly not NULL
lda (OLDTXT),y
bne !+
dey
lda (OLDTXT),y
bne !+
!:
rts
remap_BASIC_clc_rts:
lda #$27
sta CPU_R6510
clc
rts
remap_BASIC_sec_rts:
lda #$27
sta CPU_R6510
sec
rts
#endif
@@ -13,7 +13,7 @@
insert_line:
// ASSUMES find_line has been called to set the insert point.
// ASSUMES find_line_from_start has been called to set the insert point.
// jsr printf
// .text "INSERTING LINE AT $"
@@ -3,12 +3,25 @@
// #LAYOUT# * * #IGNORE
end_of_program:
// Entry point for commands not wishing to continue
pha
pha
// FALLTROUGH
shell_main_loop:
// Tell user we are ready
ldx #IDX__STR_READY
jsr print_packed_misc_str
// Mark mode as direct
lda #$FF
sta CURLIN+1
// Enable Kernal messages
lda #$80
jsr JSETMSG
@@ -129,7 +142,7 @@ shell_process_line:
lda #>BUF
sta TXTPTR+1
jsr basic_parse_line_number
jsr fetch_line_number
// Get pointer to next char
lda TXTPTR+0
@@ -156,12 +169,12 @@ shell_add_delete_line:
jsr update_VARTAB_do_clr
// Check if line already present
jsr find_line
jsr find_line_from_start
bcs !+
// Line already present - delete it
jsr delete_line
jsr find_line // refresh OLDTXT
jsr find_line_from_start // refresh OLDTXT
!:
// Insert new line if non-zero length, i.e., that
// we are not just deleting the line.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -142,8 +142,14 @@ tk_pack_loop_next:
lda tk__len_unpacked
cmp #TK__MAX_KEYWORD_LEN
bne tk_pack_loop
beq !+ // if max length reached - quit
// Check for characters that can only end the keyword
lda BUF-1, x
cmp #$41
bcs tk_pack_loop
!:
rts
tk_pack_1n_new_byte:
File renamed without changes.
@@ -91,11 +91,7 @@ tk_shorten_3n_byte_nibble: // tk__nibble_flag = $00, both nibbles fr
// Reuse 'tk_shorten_1n_hi'
sty tk__byte_offset
#if HAS_OPCODES_65C02
bra tk_shorten_1n_hi
#else
jmp tk_shorten_1n_hi
#endif
jmp_8 tk_shorten_1n_hi
tk_shorten_3n_2bytes: // tk__nibble_flag = $FF, only the high nibble is free
@@ -80,31 +80,31 @@ tokenise_line_loop:
// Check for extended tokens
lda #<packed_freq_keywords_CC
lda #<packed_freq_keywords_01
sta FRESPC+0
lda #>packed_freq_keywords_CC
lda #>packed_freq_keywords_01
sta FRESPC+1
jsr tk_search
bcc tokenise_line_keyword_CC // branch if keyword identified
bcc tokenise_line_keyword_01 // branch if keyword identified
lda #<packed_freq_keywords_CD
#if !HAS_SMALL_BASIC
lda #<packed_freq_keywords_02
sta FRESPC+0
lda #>packed_freq_keywords_CD
lda #>packed_freq_keywords_02
sta FRESPC+1
jsr tk_search
bcc tokenise_line_keyword_CD // branch if keyword identified
bcc tokenise_line_keyword_02 // branch if keyword identified
#endif
// Shorten packed keyword candidate and try again
jsr tk_shorten
#if HAS_OPCODES_65C02
bra !-
#else
jmp !-
#endif
jmp_8 !-
tokenise_line_keyword_V2:
@@ -173,20 +173,24 @@ tokenise_line_char:
// Support for extended keyword lists
tokenise_line_keyword_CC:
#if !HAS_SMALL_BASIC
tokenise_line_keyword_02:
// Store the token list index
lda #$CC
lda #$02
skip_2_bytes_trash_nvz
// FALLTROUGH
tokenise_line_keyword_CD:
#endif
tokenise_line_keyword_01:
// Store the token list index
lda #$CD
lda #$01
ldy tk__offset
sta BUF, y
@@ -0,0 +1,8 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000
// #LAYOUT# * BASIC_0 #TAKE
// #LAYOUT# * * #IGNORE
// Just a compatibility jump - our routine is longer than original one
jmp FRMEVL
File renamed without changes.
@@ -0,0 +1,16 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# * BASIC_0 #TAKE
// #LAYOUT# * * #IGNORE
check_stack_space:
phx_trash_a
tsx
cpx #$60 // XXX is this a safe threshold?
bcc_16 do_FORMULA_TOO_COMPLEX_error
plx_trash_a
rts
@@ -0,0 +1,21 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# * BASIC_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// Tries to convert PETSCII in .A to a digit (0-9 values), sets Carry to indicate failure
//
convert_PETSCII_to_digit:
sec
sbc #$30
bcc convert_PETSCII_to_digit_fail
cmp #$0A
rts
convert_PETSCII_to_digit_fail:
sec
rts
@@ -1,4 +1,5 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# M65 BASIC_1 #TAKE
// #LAYOUT# * BASIC_0 #TAKE
// #LAYOUT# * * #IGNORE
@@ -43,9 +44,13 @@ do_kernal_error: // .A = KERNAL error code, also almost ma
beq do_BREAK_error // XXX is 0 really a proper error code?
dex
#if (ROM_LAYOUT_M65 && SEGMENT_BASIC_1)
jmp do_basic_error
#else
bpl do_basic_error // branch always
#endif
// Error messages specific to OpenROMs BASIC dialect
// Error messages specific to Open ROMs BASIC dialect
do_MEMORY_CORRUPT_error:
.byte $E6
@@ -138,6 +143,16 @@ do_FILE_OPEN_error:
do_TO_MANY_FILES_error:
.byte $EA
#if (ROM_LAYOUT_M65 && SEGMENT_BASIC_1)
jmp do_error_fetch
#else
// FALLTROUGH
do_error_fetch:
// Now get the error id and restore $E6 to its correct value
lda $E6
@@ -162,9 +177,15 @@ do_TO_MANY_FILES_error:
do_basic_error: // error code in .X
// "?"
#if ROM_LAYOUT_M65
// Make sure we are back with normal memory map
jsr map_NORMAL
#endif
// Clear all temporary variables, print "?"
phx_trash_a
jsr tmpstr_free_all
ldx #IDX__STR_RET_QM
jsr print_packed_misc_str
plx_trash_a
@@ -197,3 +218,5 @@ do_basic_error: // error code in .X
txs
jmp shell_main_loop
#endif // ROM layout
@@ -51,7 +51,7 @@ do_clr:
// See Computes Mapping the Commodore 64 - page 96
// XXX check on real ROMs that it is being done too when entering new line
// XXX check if original ROM does this too
jsr JCLALL
lda MEMSIZ+0
@@ -69,6 +69,10 @@ do_clr:
sta ARYTAB+1
sta STREND+1
// This is a good place to reset the temporary string stack
jsr tmpstr_free_all_reset
// FALLTROUGH (confirmed on real C64 that CLR indeed resets DATPTR)
do_restore:
@@ -0,0 +1,23 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# * BASIC_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// Executes the next command - after previous got finished
//
end_of_statement:
jsr tmpstr_free_all
jsr fetch_character_skip_spaces
cmp #$3A // check for colon
beq_16 execute_statements
cmp #$00 // check for end of the line
beq_16 execute_statements_end_of_line
// Unexpected character
jmp do_SYNTAX_error
@@ -16,9 +16,7 @@ execute_statements:
// Skip over any white spaces and colons (':')
!:
jsr fetch_character
cmp #$20 // space, can be skipped
beq !-
jsr fetch_character_skip_spaces
cmp #$3A // colon, can be skipped
beq !-
@@ -29,27 +27,40 @@ execute_statements:
// Not end of the line - it seems we actually have something to execute
// Initialize temporary string stack - just about any statement might need it
// XXX original C64 ROM initializes this during the startup too - not sure where to put this
// Move token code to .X
tax
ldx #$16
stx LASTPT
ldx #$19
stx TEMPPT
// Push the 'end_of_statement' address for RTS
lda #>(end_of_statement - 1)
pha
lda #<(end_of_statement - 1)
pha
// Check if token is valid for execution
cmp #$7F
bcc_16 execute_statements_var_assign // not a token - try variable assign
#if HAS_SMALL_BASIC
cmp #$A6
bcs execute_statements_extended
cpx #$01
beq execute_statements_01
#else
cpx #$03
bcc execute_statements_extended
#endif
cpx #$CB
beq_16 cmd_go // // 'GO' command has a strange token, placed after function tokens
cpx #$7F
bcc_16 execute_statements_var_assign // not a token - try variable assign
#if !HAS_OPCODES_65C02
// Get the jump table entry for it, push it on the stack, and then RTS to start it.
tax
lda command_jumptable_hi - $80, x
pha
lda command_jumptable_lo - $80, x
@@ -61,31 +72,32 @@ execute_statements:
// Use jumptable to go to the command routine
txa
asl
tax
jmp (command_jumptable, x)
#endif
#if !HAS_SMALL_BASIC
execute_statements_extended:
// Support for extended BASIC commands
cmp #$CC
beq execute_statements_CC
cmp #$CD
beq execute_statements_CD
// XXX consider jumpable here
// 'GO' command has a strange token, it is placed after function tokens
cpx #$01
beq execute_statements_01
cmp #$CB
beq_16 cmd_go
cpx #$02
beq execute_statements_02
jmp do_SYNTAX_error
#endif
execute_statements_CC:
execute_statements_01:
// Get the sub-token, check that it is valid
@@ -93,7 +105,7 @@ execute_statements_CC:
cmp #$00
beq_16 do_SYNTAX_error
cmp #(TK__MAXTOKEN_keywords_CC+1)
cmp #(TK__MAXTOKEN_keywords_01+1)
bcs_16 do_SYNTAX_error
// Execute command
@@ -103,9 +115,9 @@ execute_statements_CC:
// Get the jump table entry for it, push it on the stack, and then RTS to start it.
tax
lda command_CC_jumptable_hi - 1, x
lda command_01_jumptable_hi - 1, x
pha
lda command_CC_jumptable_lo - 1, x
lda command_01_jumptable_lo - 1, x
pha
rts
@@ -116,12 +128,13 @@ execute_statements_CC:
asl
tax
jmp (command_CC_jumptable - 2, x)
jmp (command_01_jumptable - 2, x)
#endif
#if !HAS_SMALL_BASIC
execute_statements_CD:
execute_statements_02:
// Get the sub-token, check that it is valid
@@ -129,7 +142,7 @@ execute_statements_CD:
cmp #$00
beq_16 do_SYNTAX_error
cmp #(TK__MAXTOKEN_keywords_CD+1)
cmp #(TK__MAXTOKEN_keywords_02+1)
bcs_16 do_SYNTAX_error
// Execute command
@@ -139,9 +152,9 @@ execute_statements_CD:
// Get the jump table entry for it, push it on the stack, and then RTS to start it.
tax
lda command_CD_jumptable_hi - 1, x
lda command_02_jumptable_hi - 1, x
pha
lda command_CD_jumptable_lo - 1, x
lda command_02_jumptable_lo - 1, x
pha
rts
@@ -152,10 +165,11 @@ execute_statements_CD:
asl
tax
jmp (command_CD_jumptable - 2, x)
jmp (command_02_jumptable - 2, x)
#endif
#endif // !HAS_SMALL_BASIC
execute_statements_end_of_line:
@@ -189,9 +203,8 @@ execute_line:
// Check if pointer is null, if so, we are at the end of the program
ldy #0
jsr peek_line_pointer_null_check
bcc_16 shell_main_loop // branch if end of program reached
jsr is_line_pointer_null
beq_16 shell_main_loop // branch if end of program reached
// Skip pointer and line number to get address of first statement
@@ -232,17 +245,22 @@ execute_line:
execute_statements_var_assign:
// XXX here we should handle variable assignments, probably in a separate file
// Prevent wedges from being executed within a program
#if CONFIG_TAPE_WEDGE
cmp #$40
cpx #$40
beq_16 do_DIRECT_MODE_ONLY_error
#endif
#if CONFIG_DOS_WEDGE
cmp #$5F
cpx #$5F
beq_16 do_DIRECT_MODE_ONLY_error
#endif
jmp do_SYNTAX_error
// Try variable assignment - execute as LET command
#if !HAS_OPCODES_65CE02
jsr unconsume_character
#else
dew TXTPTR
#endif
jmp assign_variable
@@ -0,0 +1,21 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# * BASIC_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// Fetches line number, stores it in LINNUM, sets Carry to indicate failure (not a number)
//
// Preserves both .X and .Y
//
fetch_line_number:
lda #IDX__EV7_26 // 'LINE NUMBER TOO LARGE'
jsr fetch_uint16
bcs_16 do_SYNTAX_error
lda LINNUM+1
cmp #$FF
beq_16 do_LINE_NUMBER_TOO_LARGE_error
rts
@@ -41,7 +41,11 @@ fetch_operator_success:
fetch_operator_failed:
#if !HAS_OPCODES_65CE02
jsr unconsume_character
#else
dew TXTPTR
#endif
sec
rts
@@ -57,7 +61,11 @@ fetch_operator_try_gteq:
// This is a '>'
#if !HAS_OPCODES_65CE02
jsr unconsume_character
#else
dew TXTPTR
#endif
lda #$07
bne fetch_operator_success // branch always
!:
@@ -79,7 +87,11 @@ fetch_operator_try_lteq_neq:
// This is a '<'
#if !HAS_OPCODES_65CE02
jsr unconsume_character
#else
dew TXTPTR
#endif
lda #$09
bne fetch_operator_success // branch always
!:
+124
View File
@@ -0,0 +1,124 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# * BASIC_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// Fetches unsigned 16-bit integer, stores it in LINNUM, sets Carry to indicate failure (not a number)
//
// If value above 65535, error depends on .A opn entry
//
// Preserves both .X and .Y
//
fetch_uint16:
// Push the error code to stack
pha
// Fetch the first character (skip spaces), check if 0-9
jsr fetch_character_skip_spaces
jsr convert_PETSCII_to_digit
bcs fetch_uint16_rts
// First character seems to be correct - store it
sta LINNUM+0
lda #$00
sta LINNUM+1
// FALLTROUGH
fetch_uint16_loop:
// Try to fetch another digit
jsr fetch_character
jsr convert_PETSCII_to_digit
bcs fetch_uint16_end
// We got another digit - store it
pha
// Multiply current LINNUM by 10 (x * 10 = (x * 2) + (x * 2) * 4)
jsr fetch_uint16_mul_LINNUM_2
bcs fetch_uint16_1PLA_error
lda LINNUM+1
pha
lda LINNUM+0
pha
jsr fetch_uint16_mul_LINNUM_2
bcs fetch_uint16_3PLA_error
jsr fetch_uint16_mul_LINNUM_2
bcs fetch_uint16_3PLA_error
clc
pla
adc LINNUM+0
sta LINNUM+0
pla
adc LINNUM+1
sta LINNUM+1
bcs fetch_uint16_1PLA_error
// Add the new digit to LINNUM
pla
clc
adc LINNUM+0
sta LINNUM+0
lda LINNUM+1
adc #$00
sta LINNUM+1
bcs fetch_uint16_error
// Next iteration
jmp_8 fetch_uint16_loop
fetch_uint16_end:
#if !HAS_OPCODES_65CE02
jsr unconsume_character
#else
dew TXTPTR
#endif
clc
// FALLTROUGH
fetch_uint16_rts:
pla
rts
fetch_uint16_mul_LINNUM_2:
asl LINNUM+0
rol LINNUM+1
rts
fetch_uint16_3PLA_error:
pla
pla
// FALLTROUGH
fetch_uint16_1PLA_error:
pla
// FALLTROUGH
fetch_uint16_error:
plx_trash_a
jmp do_basic_error
@@ -16,8 +16,9 @@ fetch_coma_uint8:
fetch_uint8:
jsr injest_spaces
jsr basic_parse_line_number // XXX detect errors here
lda #IDX__EV2_0E // 'ILLEGAL QUANTITY ERROR'
jsr fetch_uint16
bcs !+
lda LINNUM+1
bne_16 do_ILLEGAL_QUANTITY_error
lda LINNUM+0
@@ -1,5 +1,4 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000
// #LAYOUT# * BASIC_0 #TAKE
// #LAYOUT# * * #IGNORE
@@ -19,7 +18,7 @@
// in a correct order
//
// XXX finish the implementation: invoking functions, fetcching PI, fetching float, fetching variables
// XXX finish the implementation: invoking functions, fetching floats
FRMEVL:
@@ -41,7 +40,7 @@ FRMEVL_loop:
// Check if end of statement, fetch the character
jsr end_of_statement_check
jsr is_end_of_statement
bcs_16 do_SYNTAX_error
jsr fetch_character
@@ -68,17 +67,53 @@ FRMEVL_loop:
// $7F has to be a function
cmp #$80 // check for a token
bcc FRMEVL_execute_function
bcs FRMEVL_execute_function
// There are 2 possibilities left - a floating point value or a variable
// Check for a variable
#if !HAS_OPCODES_65CE02
jsr unconsume_character
#else
dew TXTPTR
#endif
jsr fetch_variable
bcs FRMEVL_fetch_float
// XXX implement this part
// Found the variable - copy descriptor to FAC1
#if CONFIG_MEMORY_MODEL_60K
ldx #<VARPNT
// Nothing recognized
ldy #$00
jsr peek_under_roms
sta __FAC1+0
iny
jsr peek_under_roms
sta __FAC1+1
iny
jsr peek_under_roms
sta __FAC1+2
jmp do_SYNTAX_error
#elif CONFIG_MEMORY_MODEL_46K || CONFIG_MEMORY_MODEL_50K
jsr helper_frmevl_strdesccpy
#else // CONFIG_MEMORY_MODEL_38K
ldy #$00
lda (VARPNT),y
sta __FAC1+0
iny
lda (VARPNT),y
sta __FAC1+1
iny
lda (VARPNT),y
sta __FAC1+2
#endif
jmp_8 FRMEVL_got_value
//
// This subroutine handles the situation when we have to execute a BASIC function
@@ -128,9 +163,11 @@ FRMEVL_handle_bracket:
FRMEVL_fetch_PI:
// XXX implement this
lda #<const_PI
ldy #>const_PI
jsr mov_MEM_FAC1
jmp do_NOT_IMPLEMENTED_error
jmp_8 FRMEVL_got_value_float
//
// This subroutine fetches the floating point value from the 'outside world'
@@ -142,6 +179,14 @@ FRMEVL_fetch_float:
jmp do_NOT_IMPLEMENTED_error
// FALLTROUGH
FRMEVL_got_value_float:
lda #$00
sta VALTYP
beq FRMEVL_got_value
//
// This subroutine fetches the string value from the 'outside world'
//
@@ -178,7 +223,11 @@ FRMEVL_fetch_string:
!:
// No closing quote, but end of the data
#if !HAS_OPCODES_65CE02
jsr unconsume_character
#else
dew TXTPTR
#endif
// FALLTROUGH
@@ -196,7 +245,7 @@ FRMEVL_fetch_string:
FRMEVL_got_value:
jsr end_of_statement_check
jsr is_end_of_statement
bcs FRMEVL_compute_all // compute the stack if expression ended
// FALLTROUGH
@@ -274,9 +323,7 @@ FRMEVL_push_operator_address:
// Check if there is enough stack space; this could not have been done earlier,
// as this is the place where unary operator support calls
tsx
cpx #$40 // XXX is this a safe threshold?
bcc_16 do_FORMULA_TOO_COMPLEX_error
jsr check_stack_space
// Push the operator address to stack, in a form
// suitable for RTS
Loaded 100 of 267 files, more files were not shown because too many files have changed in this diff. Show more