Merge pull request #27 from FeralChild64/master
IEC improvements and misc changes
This commit is contained in:
279 files changed
+3890
-966
No files matched your search
+17
-16
@@ -1,17 +1,18 @@
|
||||
c64/basic/OUT.BIN
|
||||
c64/basic/combined.s
|
||||
c64/kernal/OUT.BIN
|
||||
c64/kernal/combined.s
|
||||
chargen
|
||||
newbasic
|
||||
newc65
|
||||
newkern
|
||||
newrom
|
||||
ophis.bin
|
||||
padding
|
||||
src/collect_data
|
||||
src/compress_text
|
||||
src/pngprepare
|
||||
src/preprocess
|
||||
temp.map
|
||||
|
||||
# Compilation related files
|
||||
|
||||
temp.s
|
||||
temp.map
|
||||
|
||||
ophis.bin
|
||||
build/*
|
||||
|
||||
# Input to the similarity tool - copyrighted material, we can't check it in!
|
||||
|
||||
/basic
|
||||
/kernal
|
||||
|
||||
# Various IDE project files, temporary files, etc.
|
||||
|
||||
*project
|
||||
.*swp
|
||||
@@ -0,0 +1,2 @@
|
||||
|
||||
Although the project itself is LGPL3, I (FeralChild64) allow to redistribute my contributions to this project under any OSI (Open Source Initiative) approved open source license.
|
||||
@@ -1,61 +1,157 @@
|
||||
all: Ophis src/collect_data src/preprocess
|
||||
|
||||
# Source files
|
||||
|
||||
SRC_COMMON = $(wildcard c64/aliases/*.s)
|
||||
SRC_BASIC_COMMON = $(SRC_COMMON) $(wildcard c64/basic/*.s)
|
||||
SRC_KERNAL_COMMON = $(SRC_COMMON) $(wildcard c64/kernal/*.s c64/kernal/jumptable/*.s c64/kernal/iec/*.s)
|
||||
|
||||
SRC_BASIC_generic = $(SRC_BASIC_COMMON) $(wildcard c64/basic/,target_generic/*.s)
|
||||
SRC_BASIC_mega65 = $(SRC_BASIC_COMMON) $(wildcard c64/basic/,target_mega65/*.s)
|
||||
SRC_BASIC_ultimate64 = $(SRC_BASIC_COMMON) $(wildcard c64/basic/,target_ultimate64/*.s)
|
||||
|
||||
SRC_KERNAL_generic = $(SRC_KERNAL_COMMON) $(wildcard c64/kernal/,target_generic/*.s)
|
||||
SRC_KERNAL_mega65 = $(SRC_KERNAL_COMMON) $(wildcard c64/kernal/,target_mega65/*.s)
|
||||
SRC_KERNAL_ultimate64 = $(SRC_KERNAL_COMMON) $(wildcard c64/kernal/,target_ultimate64/*.s)
|
||||
|
||||
# List of tools
|
||||
|
||||
TOOL_COLLECT_DATA = build/tools/collect_data
|
||||
TOOL_COMPRESS_TEXT = build/tools/compress_text
|
||||
TOOL_PNGPREPARE = build/tools/pngprepare
|
||||
TOOL_PREPROCESS = build/tools/preprocess
|
||||
TOOL_SIMILARITY = build/tools/similarity
|
||||
|
||||
TOOLS_LIST = $(TOOL_COLLECT_DATA) $(TOOL_COMPRESS_TEXT) $(TOOL_PNGPREPARE) $(TOOL_PREPROCESS) $(TOOL_SIMILARITY)
|
||||
|
||||
# Rules - main
|
||||
|
||||
.PHONY: all clean updatebin
|
||||
|
||||
all: build/chargen build/newkern_generic build/newbasic_generic build/newc65 build/newkern_ultimate64 build/newbasic_ultimate64
|
||||
|
||||
Ophis:
|
||||
git submodule init
|
||||
git submodule update
|
||||
|
||||
src/pngprepare: src/pngprepare.c Makefile
|
||||
$(CC) $(COPT) -I/usr/local/include -L/usr/local/lib -o src/pngprepare src/pngprepare.c -lpng
|
||||
clean:
|
||||
@rm -rf build
|
||||
@rm -f temp.s
|
||||
@rm -f temp.map
|
||||
@rm -f ophis.bin
|
||||
|
||||
chargen: src/pngprepare assets/8x8font.png
|
||||
src/pngprepare charrom assets/8x8font.png chargen
|
||||
updatebin: build/chargen build/newbasic_generic build/newkern_generic build/newbasic_mega65 build/newkern_mega65 build/newbasic_ultimate64 build/newkern_ultimate64
|
||||
cp build/chargen bin/chargen.rom
|
||||
cp build/newbasic_generic bin/basic_generic.rom
|
||||
cp build/newkern_generic bin/kernal_generic.rom
|
||||
cp build/newbasic_mega65 bin/basic_mega65.rom
|
||||
cp build/newkern_mega65 bin/kernal_mega65.rom
|
||||
cp build/newbasic_ultimate64 bin/basic_ultimate64.rom
|
||||
cp build/newkern_ultimate64 bin/kernal_ultimate64.rom
|
||||
|
||||
src/collect_data: src/collect_data.c Makefile
|
||||
gcc -Wall -o src/collect_data src/collect_data.c
|
||||
# Rules - tools
|
||||
|
||||
src/preprocess: src/preprocess.c Makefile
|
||||
gcc -g -Wall -o src/preprocess src/preprocess.c
|
||||
$(TOOL_COLLECT_DATA): src/collect_data.c Makefile
|
||||
@mkdir -p build/tools
|
||||
gcc -Wall -o $(TOOL_COLLECT_DATA) src/collect_data.c
|
||||
|
||||
src/similarity: src/similarity.c Makefile
|
||||
gcc -g -Wall -o src/similarity src/similarity.c
|
||||
$(TOOL_COMPRESS_TEXT): src/compress_text.c Makefile
|
||||
@mkdir -p build/tools
|
||||
gcc -g -Wall -o $(TOOL_COMPRESS_TEXT) src/compress_text.c -lm
|
||||
|
||||
src/compress_text: src/compress_text.c Makefile
|
||||
gcc -g -Wall -o src/compress_text src/compress_text.c -lm
|
||||
$(TOOL_PNGPREPARE): src/pngprepare.c Makefile
|
||||
@mkdir -p build/tools
|
||||
$(CC) $(COPT) -I/usr/local/include -L/usr/local/lib -o $(TOOL_PNGPREPARE) src/pngprepare.c -lpng
|
||||
|
||||
newrom: c64/kernal/OUT.BIN c64/basic/OUT.BIN
|
||||
cat c64/basic/OUT.BIN c64/kernal/OUT.BIN >newrom
|
||||
$(TOOL_PREPROCESS): src/preprocess.c Makefile
|
||||
@mkdir -p build/tools
|
||||
gcc -g -Wall -o $(TOOL_PREPROCESS) src/preprocess.c
|
||||
|
||||
newkern: newrom Makefile
|
||||
dd if=newrom bs=8192 count=1 skip=2 of=newkern
|
||||
$(TOOL_SIMILARITY): src/similarity.c Makefile
|
||||
@mkdir -p build/tools
|
||||
gcc -g -Wall -o $(TOOL_SIMILARITY) src/similarity.c
|
||||
|
||||
newbasic: newrom Makefile
|
||||
dd if=newrom bs=8192 count=1 skip=0 of=newbasic
|
||||
# Rules - CHARGEN
|
||||
|
||||
newc65: newkern newbasic chargen Makefile
|
||||
dd if=/dev/zero bs=4096 count=10 of=newc65
|
||||
cat newbasic chargen chargen newkern >>newc65
|
||||
dd if=/dev/zero bs=65536 count=1 of=padding
|
||||
cat padding >>newc65
|
||||
build/chargen: $(TOOL_PNGPREPARE) assets/8x8font.png
|
||||
$(TOOL_PNGPREPARE) charrom assets/8x8font.png build/chargen
|
||||
|
||||
# Dependencies
|
||||
|
||||
build/basic_generic/OUT.BIN: Ophis $(TOOLS_LIST) $(SRC_BASIC_generic) build/basic/packed_messages.s
|
||||
build/kernal_generic/OUT.BIN: Ophis $(TOOLS_LIST) $(SRC_KERNAL_generic)
|
||||
build/newrom_generic: build/basic_generic/OUT.BIN build/kernal_generic/OUT.BIN
|
||||
build/newkern_generic: build/newrom_generic Makefile
|
||||
build/newbasic_generic: build/newrom_generic Makefile
|
||||
|
||||
build/basic_mega65/OUT.BIN: Ophis $(TOOLS_LIST) $(SRC_BASIC_mega65) build/basic/packed_messages.s
|
||||
build/kernal_mega65/OUT.BIN: Ophis $(TOOLS_LIST) $(SRC_KERNAL_mega65)
|
||||
build/newrom_mega65: build/basic_mega65/OUT.BIN build/kernal_mega65/OUT.BIN
|
||||
build/newkern_mega65: build/newrom_mega65 Makefile
|
||||
build/newbasic_mega65: build/newrom_mega65 Makefile
|
||||
|
||||
build/basic_ultimate64/OUT.BIN: Ophis $(TOOLS_LIST) $(SRC_BASIC_ultimate64) build/basic/packed_messages.s
|
||||
build/kernal_ultimate64/OUT.BIN: Ophis $(TOOLS_LIST) $(SRC_KERNAL_ultimate64)
|
||||
build/newrom_ultimate64: build/basic_ultimate64/OUT.BIN build/kernal_ultimate64/OUT.BIN
|
||||
build/newkern_ultimate64: build/newrom_ultimate64 Makefile
|
||||
build/newbasic_ultimate64: build/newrom_ultimate64 Makefile
|
||||
|
||||
|
||||
c64/basic/packed_messages.s: Makefile src/compress_text
|
||||
src/compress_text > c64/basic/packed_messages.s
|
||||
# Rules - BASIC and KERNAL
|
||||
|
||||
c64/kernal/OUT.BIN: src/preprocess c64/kernal/*.s
|
||||
src/preprocess -d c64/kernal -l e4d3 -h ffff
|
||||
build/basic/packed_messages.s: $(TOOL_COMPRESS_TEXT)
|
||||
@mkdir -p build/basic
|
||||
$(TOOL_COMPRESS_TEXT) > build/basic/packed_messages.s
|
||||
|
||||
c64/basic/OUT.BIN: src/preprocess c64/basic/*.s c64/basic/packed_messages.s
|
||||
src/preprocess -d c64/basic -l a000 -h e4d2
|
||||
.PRECIOUS: build/basic_%/OUT.BIN
|
||||
build/basic_%/OUT.BIN: Ophis $(TOOLS_LIST) $(SRC_BASIC_$*) build/basic/packed_messages.s
|
||||
@mkdir -p build/basic_$*
|
||||
@rm -f build/basic_$*/*
|
||||
@for SRC in $(SRC_BASIC_$*); do \
|
||||
ln -s ../../$$SRC build/basic_$*/$$(basename $$SRC); \
|
||||
done
|
||||
@ln -s ../../build/basic/packed_messages.s build/basic_$*/packed_messages.s
|
||||
$(TOOL_PREPROCESS) -d build/basic_$* -l a000 -h e4d2
|
||||
|
||||
testremote: newkern newbasic
|
||||
x64 -kernal newkern -basic newbasic -remotemonitor
|
||||
.PRECIOUS: build/kernal_%/OUT.BIN
|
||||
build/kernal_%/OUT.BIN: Ophis $(TOOLS_LIST) $(SRC_KERNAL_$*)
|
||||
@mkdir -p build/kernal_$*
|
||||
@rm -f build/kernal_$*/*
|
||||
@for SRC in $(SRC_KERNAL_$*); do \
|
||||
ln -s ../../$$SRC build/kernal_$*/$$(basename $$SRC); \
|
||||
done
|
||||
$(TOOL_PREPROCESS) -d build/kernal_$* -l e4d3 -h ffff
|
||||
|
||||
test: newkern newbasic
|
||||
x64 -kernal newkern -basic newbasic -8 empty.d64
|
||||
.PRECIOUS: build/newrom_%
|
||||
build/newrom_%: build/basic_%/OUT.BIN build/kernal_%/OUT.BIN
|
||||
cat build/basic_$*/OUT.BIN build/kernal_$*/OUT.BIN > build/newrom_$*
|
||||
|
||||
testm65: newc65
|
||||
m65 -b ../mega65-core/bin/mega65r1.bit -k ../mega65-core/bin/KICKUP.M65 -R newc65 -4
|
||||
.PRECIOUS: build/newkern_%
|
||||
build/newkern_%: build/newrom_% Makefile
|
||||
dd if=build/newrom_$* bs=8192 count=1 skip=2 of=build/newkern_$*
|
||||
|
||||
testsimilarity: newkern newbasic src/similarity
|
||||
src/similarity kernal newrom
|
||||
src/similarity basic newrom
|
||||
.PRECIOUS: build/newbasic_%
|
||||
build/newbasic_%: build/newrom_% Makefile
|
||||
dd if=build/newrom_$* bs=8192 count=1 skip=0 of=build/newbasic_$*
|
||||
|
||||
# Rules - platform 'Mega 65' specific
|
||||
|
||||
build/newc65: build/newkern_mega65 build/newbasic_mega65 build/chargen Makefile
|
||||
dd if=/dev/zero bs=4096 count=10 of=build/newc65
|
||||
cat build/newbasic_mega65 build/chargen build/chargen build/newkern_mega65 >> build/newc65
|
||||
dd if=/dev/zero bs=65536 count=1 of=build/basic/padding
|
||||
cat build/basic/padding >> build/newc65
|
||||
|
||||
# Rules - tests
|
||||
|
||||
test: build/newkern_generic build/newbasic_generic
|
||||
x64 -kernal build/newkern_generic -basic build/newbasic_generic -8 empty.d64
|
||||
|
||||
testremote: build/newkern_generic build/newbasic_generic
|
||||
x64 -kernal build/newkern-generic -basic build/newbasic-generic -remotemonitor
|
||||
|
||||
testm65: build/newc65
|
||||
m65 -b ../mega65-core/bin/mega65r1.bit -k ../mega65-core/bin/KICKUP.M65 -R build/newc65 -4
|
||||
|
||||
testsimilarity: build/newrom_generic $(TOOL_SIMILARITY)
|
||||
$(TOOL_SIMILARITY) kernal build/newrom_generic
|
||||
$(TOOL_SIMILARITY) basic build/newrom_generic
|
||||
@@ -0,0 +1,117 @@
|
||||
# New features
|
||||
|
||||
|
||||
Here are the features of the Open ROMs not found in the original ROMs from the 80s:
|
||||
|
||||
* improved keyboard scanning, supports multi-key roll-over and rejection of spurious joystick input
|
||||
* joystick (port 1) can be used to move text cursor
|
||||
* uses RAM under ROM and I/O: 61436 bytes free
|
||||
* extended `LOAD` command
|
||||
* 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
|
||||
* secondary address over 255 is considered a start address
|
||||
* DOS wedge (direct mode only) - `@<drive_number>`, `@<command>`, `@$`, `@$<params>`, `@`
|
||||
|
||||
NOTE: extra features and their syntax can change in the future!
|
||||
|
||||
# Features missing
|
||||
|
||||
|
||||
The following ROM features are currently missing:
|
||||
|
||||
* most BASIC commands
|
||||
* BASIC variables
|
||||
* BASIC expression parsing
|
||||
* floating point routines
|
||||
* tape support
|
||||
* RS-232 support
|
||||
* warm start (RUN/STOP + RESTORE) - NMI is not implemented at all
|
||||
* breaking Kernal routines with RUN/STOP key
|
||||
|
||||
Features currently being worked on:
|
||||
|
||||
* IEC support needs more testing ang bugfixing; alternative drive ROMs (JiffyDOS, DolphinDOS, etc) usually don't work with current implementation, `@$` leaves the drive led on, most likely other problems can be found
|
||||
|
||||
# API status
|
||||
|
||||
|
||||
Status of the various APIs and variables from the original ROMs
|
||||
|
||||
|
||||
## Page 0
|
||||
|
||||
|
||||
TODO
|
||||
|
||||
|
||||
## Pages 2 & 3
|
||||
|
||||
|
||||
TODO
|
||||
|
||||
|
||||
## BASIC
|
||||
|
||||
|
||||
TODO
|
||||
|
||||
|
||||
## Kernal
|
||||
|
||||
|
||||
Note: only the jump table addresses are currently supported, real routine addresses are different!
|
||||
|
||||
|
||||
### Official Kernal routines
|
||||
|
||||
NOTE: Even the 'DONE' routines won't support features described as missing in one of the previous chapters!
|
||||
|
||||
<br />
|
||||
|
||||
| Address | Name | Status | Remarks |
|
||||
| --------- | :------- | :------: | :------------------------------------------------: |
|
||||
| `$FF81` | `CINT` | PARTIAL | at least PAL/NTSC detection is missing |
|
||||
| `$FF84` | `IOINIT` | PARTIAL | at least SID volume handling is missing |
|
||||
| `$FF87` | `RAMTAS` | DONE | |
|
||||
| `$FF8A` | `RESTOR` | PARTIAL | CBINV, NMINV, and USRCMD missing |
|
||||
| `$FF8D` | `VECTOR` | DONE | |
|
||||
| `$FF90` | `SETMSG` | DONE | |
|
||||
| `$FF93` | `SECOND` | DONE | |
|
||||
| `$FF96` | `TKSA` | DONE | |
|
||||
| `$FF99` | `MEMTOP` | DONE | |
|
||||
| `$FF9C` | `MEMBOT` | DONE | |
|
||||
| `$FF9F` | `SCNKEY` | DONE | could be better integrated with ROM (aliases) |
|
||||
| `$FFA2` | `SETTMO` | NOT DONE | |
|
||||
| `$FFA5` | `ACPTR` | DONE | |
|
||||
| `$FFA8` | `CIOUT` | DONE | |
|
||||
| `$FFAB` | `UNTLK` | DONE | |
|
||||
| `$FFAE` | `UNLSN` | DONE | |
|
||||
| `$FFB1` | `LISTEN` | DONE | |
|
||||
| `$FFB4` | `TALK` | DONE | |
|
||||
| `$FFB7` | `READST` | DONE | |
|
||||
| `$FFBA` | `SETFLS` | DONE | |
|
||||
| `$FFBD` | `SETNAM` | DONE | |
|
||||
| `$FFC0` | `OPEN` | DONE | |
|
||||
| `$FFC3` | `CLOSE` | PARTIAL | most likely incompleete, @$ doesn't end properly |
|
||||
| `$FFC6` | `CHKIN` | DONE | |
|
||||
| `$FFC9` | `CHKOUT` | PARTIAL | |
|
||||
| `$FFCC` | `CLRCHN` | DONE | |
|
||||
| `$FFCF` | `CHRIN` | PARTIAL | |
|
||||
| `$FFD2` | `CHROUT` | PARTIAL | |
|
||||
| `$FFD5` | `LOAD` | PARTIAL | no VERIFY support yet |
|
||||
| `$FFD8` | `SAVE` | NOT DONE | |
|
||||
| `$FFDB` | `SETTIM` | NOT DONE | |
|
||||
| `$FFDE` | `RDTIM` | NOT DONE | |
|
||||
| `$FFE1` | `STOP` | PARTIAL | no connection with UDTIM |
|
||||
| `$FFE4` | `GETIN` | PARTIAL | only some devices supported |
|
||||
| `$FFE7` | `CLALL` | DONE | |
|
||||
| `$FFEA` | `UDTIM` | NOT DONE | |
|
||||
| `$FFED` | `SCREEN` | DONE | |
|
||||
| `$FFF0` | `PLOT` | NOT DONE | |
|
||||
| `$FFF3` | `IOBASE` | DONE | |
|
||||
|
||||
<br />
|
||||
|
||||
### Unofficial Kernal locations
|
||||
|
||||
TODO
|
||||
@@ -0,0 +1,14 @@
|
||||
|
||||
Follow these rules, or bad things will happen!
|
||||
|
||||
|
||||
- Don't mix ROMs for different platforms - use generic BASIC with generic KERNAL, Mega65 BASIC with Mega65 KERNAL, etc.
|
||||
|
||||
- Don't mix these ROMs with any other ROMs; the only exception is CHARGEN, this one is fully interchangeable.
|
||||
|
||||
- Don't mix ROMs from different builds/versions (again, CHARGEN is an exception).
|
||||
|
||||
- The generic ROM set should be compatible with any C64-compatible machine; platform-specific ROMs might not work on other platforms.
|
||||
|
||||
|
||||
Have fun!
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,63 @@
|
||||
|
||||
;; Kernal error codes - returned in the A register
|
||||
;; Described in 'Commodore 64 Programmer's Reference Guide', page 306
|
||||
|
||||
.alias K_ERR_ROUTINE_TERMINATED $00
|
||||
.alias K_ERR_TOO_MANY_OPEN_FILES $01
|
||||
.alias K_ERR_FILE_ALREADY_OPEN $02
|
||||
.alias K_ERR_FILE_NOT_OPEN $03
|
||||
.alias K_ERR_FILE_NOT_FOUND $04
|
||||
.alias K_ERR_DEVICE_NOT_FOUND $05
|
||||
.alias K_ERR_FILE_NOT_INPUT $06
|
||||
.alias K_ERR_FILE_NOT_OUTPUT $07
|
||||
.alias K_ERR_FILE_NAME_MISSING $08
|
||||
.alias K_ERR_ILLEGAL_DEVICE_NUMBER $09
|
||||
.alias K_ERR_TOP_MEM_RS232 $F0
|
||||
|
||||
;; Kernal status codes for READST routine (IOSTATUS)
|
||||
;; Described in 'Commodore 64 Programmer's Reference Guide', page 292
|
||||
|
||||
;; For IEC devices
|
||||
.alias K_STS_TIMEOUT_WRITE $01
|
||||
.alias K_STS_TIMEOUT_READ $02
|
||||
.alias K_STS_EOI $40
|
||||
.alias K_STS_DEVICE_NOT_FOUND $80
|
||||
;; For tape deck
|
||||
.alias K_STS_SHORT_BLOCK $04
|
||||
.alias K_STS_LONG_BLOCK $08
|
||||
.alias K_STS_READ_ERROR $10
|
||||
.alias K_STS_CHECKSUM_ERROR $20
|
||||
.alias K_STS_END_OF_FILE $40
|
||||
.alias K_STS_END_OF_TAPE $80
|
||||
|
||||
;; BASIC error codes, taken from http://sta.c64.org/cbm64baserr.html
|
||||
.alias B_ERR_TOO_MANY_FILES $01
|
||||
.alias B_ERR_FILE_OPEN $02
|
||||
.alias B_ERR_FILE_NOT_OPEN $03
|
||||
.alias B_ERR_FILE_NOT_FOUND $04
|
||||
.alias B_ERR_DEVICE_NOT_PRESENT $05
|
||||
.alias B_ERR_NOT_INPUT_FILE $06
|
||||
.alias B_ERR_NOT_OUTPUT_FILE $07
|
||||
.alias B_ERR_MISSING_FILENAME $08
|
||||
.alias B_ERR_ILLEGAL_DEVICE_NUMBER $09
|
||||
.alias B_ERR_NEXT_WITHOUT_FOR $0A
|
||||
.alias B_ERR_SYNTAX $0B
|
||||
.alias B_ERR_RETURN_WITHOUT_GOSUB $0C
|
||||
.alias B_ERR_OUT_OF_DATA $0D
|
||||
.alias B_ERR_ILLEGAL_QUANTITY $0E
|
||||
.alias B_ERR_OVERFLOW $0F
|
||||
.alias B_ERR_OUT_OF_MEMORY $10
|
||||
.alias B_ERR_UNDEFD_STATEMENT $11
|
||||
.alias B_ERR_BAD_SUBSCRIPT $12
|
||||
.alias B_ERR_REDIMD_ARRAY $13
|
||||
.alias B_ERR_DIVISION_BY_ZERO $14
|
||||
.alias B_ERR_ILLEGAL_DIRECT $15
|
||||
.alias B_ERR_TYPE_MISMATCH $16
|
||||
.alias B_ERR_STRING_TOO_LONG $17
|
||||
.alias B_ERR_FILE_DATA $18
|
||||
.alias B_ERR_FORMULA_TOO_COMPLEX $19
|
||||
.alias B_ERR_CANT_CONTINUE $1A
|
||||
.alias B_ERR_UNDEFD_FUNCTION $1B
|
||||
.alias B_ERR_VERIFY $1C
|
||||
.alias B_ERR_LOAD $1D
|
||||
.alias B_ERR_BREAK $1E
|
||||
@@ -0,0 +1,154 @@
|
||||
|
||||
;;
|
||||
;; Names of hardware registers - slightly modified names from C64 Programmer's Reference Guide
|
||||
;;
|
||||
|
||||
;; CPU memory registers
|
||||
|
||||
.alias CPU_D6510 $0000
|
||||
.alias CPU_R6510 $0001
|
||||
|
||||
;; VIC-II registers
|
||||
|
||||
.alias VIC_SP0X $D000
|
||||
.alias VIC_SP0Y $D001
|
||||
.alias VIC_SP1X $D002
|
||||
.alias VIC_SP1Y $D003
|
||||
.alias VIC_SP2X $D004
|
||||
.alias VIC_SP2Y $D005
|
||||
.alias VIC_SP3X $D006
|
||||
.alias VIC_SP3Y $D007
|
||||
.alias VIC_SP4X $D008
|
||||
.alias VIC_SP4Y $D009
|
||||
.alias VIC_SP5X $D00A
|
||||
.alias VIC_SP5Y $D00B
|
||||
.alias VIC_SP6X $D00C
|
||||
.alias VIC_SP6Y $D00D
|
||||
.alias VIC_SP7X $D00E
|
||||
.alias VIC_SP7Y $D00F
|
||||
|
||||
.alias VIC_MSIGX $D010
|
||||
.alias VIC_SCROLLY $D011
|
||||
.alias VIC_RASTER $D012
|
||||
.alias VIC_LPENX $D013
|
||||
.alias VIC_LPENY $D014
|
||||
.alias VIC_SPENA $D015
|
||||
.alias VIC_SCROLX $D016
|
||||
.alias VIC_YXPAND $D017
|
||||
.alias VIC_YMCSB $D018
|
||||
.alias VIC_IRQ $D019
|
||||
.alias VIC_IRQMSK $D01A
|
||||
.alias VIC_SPBGPR $D01B
|
||||
.alias VIC_SPMC $D01C
|
||||
.alias VIC_XXPAND $D01D
|
||||
.alias VIC_SPSPCL $D01E
|
||||
.alias VIC_SPBGCL $D01F
|
||||
|
||||
.alias VIC_EXTCOL $D020
|
||||
.alias VIC_BGCOL0 $D021
|
||||
.alias VIC_BGCOL1 $D022
|
||||
.alias VIC_BGCOL2 $D023
|
||||
.alias VIC_BGCOL3 $D024
|
||||
.alias VIC_SPMC0 $D025
|
||||
.alias VIC_SPMC1 $D026
|
||||
.alias VIC_SP0COL $D027
|
||||
.alias VIC_SP1COL $D028
|
||||
.alias VIC_SP2COL $D029
|
||||
.alias VIC_SP3COL $D02A
|
||||
.alias VIC_SP4COL $D02B
|
||||
.alias VIC_SP5COL $D02C
|
||||
.alias VIC_SP6COL $D02D
|
||||
.alias VIC_SP7COL $D02E
|
||||
|
||||
;; SID #1 registers
|
||||
|
||||
.alias SID1_FRELO1 $D400
|
||||
.alias SID1_FREHI1 $D401
|
||||
.alias SID1_PWLO1 $D402
|
||||
.alias SID1_PWHI1 $D403
|
||||
.alias SID1_VCREG1 $D404
|
||||
.alias SID1_ATDCY1 $D405
|
||||
.alias SID1_SUREL1 $D406
|
||||
|
||||
.alias SID1_FRELO2 $D407
|
||||
.alias SID1_FREHI2 $D408
|
||||
.alias SID1_PWLO2 $D409
|
||||
.alias SID1_PWHI2 $D40A
|
||||
.alias SID1_VCREG2 $D40B
|
||||
.alias SID1_ATDCY2 $D40C
|
||||
.alias SID1_SUREL2 $D40D
|
||||
|
||||
.alias SID1_FRELO3 $D40E
|
||||
.alias SID1_FREHI3 $D40F
|
||||
.alias SID1_PWLO3 $D410
|
||||
.alias SID1_PWHI3 $D411
|
||||
.alias SID1_VCREG3 $D412
|
||||
.alias SID1_ATDCY3 $D413
|
||||
.alias SID1_SUREL3 $D414
|
||||
|
||||
.alias SID1_CUTLO $D415
|
||||
.alias SID1_CUTHI $D416
|
||||
.alias SID1_RESON $D417
|
||||
.alias SID1_SIGVOL $D418
|
||||
.alias SID1_POTX $D419
|
||||
.alias SID1_POTY $D41A
|
||||
.alias SID1_RANDOM $D41B
|
||||
.alias SID1_ENV3 $D41C
|
||||
|
||||
;; SID #2, #3, #4 registers
|
||||
|
||||
.alias SID2_SIGVOL $D438
|
||||
.alias SID3_SIGVOL $D458
|
||||
.alias SID4_SIGVOL $D478
|
||||
|
||||
;; CIA #1 registers
|
||||
|
||||
.alias CIA1_PRA $DC00
|
||||
.alias CIA1_PRB $DC01
|
||||
.alias CIA1_DDRA $DC02
|
||||
.alias CIA1_DDRB $DC03
|
||||
|
||||
.alias CIA1_TIMALO $DC04
|
||||
.alias CIA1_TIMAHI $DC05
|
||||
.alias CIA1_TIMBLO $DC06
|
||||
.alias CIA1_TIMBHI $DC07
|
||||
|
||||
.alias CIA1_TODTEN $DC08
|
||||
.alias CIA1_TODSEC $DC09
|
||||
.alias CIA1_TODMIN $DC0A
|
||||
.alias CIA1_TODHRS $DC0B
|
||||
|
||||
.alias CIA1_SDR $DC0C
|
||||
.alias CIA1_ICR $DC0D
|
||||
.alias CIA1_CRA $DC0E
|
||||
.alias CIA1_CRB $DC0F
|
||||
|
||||
;; CIA #2 registers
|
||||
|
||||
.alias CIA2_PRA $DD00 ; VIC bank switching and IEC port
|
||||
.alias CIA2_PRB $DD01
|
||||
.alias CIA2_DDRA $DD02
|
||||
.alias CIA2_DDRB $DD03
|
||||
|
||||
.alias CIA2_TIMALO $DD04
|
||||
.alias CIA2_TIMAHI $DD05
|
||||
.alias CIA2_TIMBLO $DD06
|
||||
.alias CIA2_TIMBHI $DD07
|
||||
|
||||
.alias CIA2_TODTEN $DD08
|
||||
.alias CIA2_TODSEC $DD09
|
||||
.alias CIA2_TODMIN $DD0A
|
||||
.alias CIA2_TODHRS $DD0B
|
||||
|
||||
.alias CIA2_SDR $DD0C
|
||||
.alias CIA2_ICR $DD0D
|
||||
.alias CIA2_CRA $DD0E
|
||||
.alias CIA2_CRB $DD0F
|
||||
|
||||
;; CIA #2 helper bits - IEC bus
|
||||
|
||||
.alias BIT_CIA2_PRA_ATN_OUT $08 ; 1 - low (pulled), 0 - high (released)
|
||||
.alias BIT_CIA2_PRA_CLK_OUT $10 ; 1 - low (pulled), 0 - high (released)
|
||||
.alias BIT_CIA2_PRA_DAT_OUT $20 ; 1 - low (pulled), 0 - high (released)
|
||||
.alias BIT_CIA2_PRA_CLK_IN $40 ; 0 - low (pulled), 1 - high (released)
|
||||
.alias BIT_CIA2_PRA_DAT_IN $80 ; 0 - low (pulled), 1 - high (released)
|
||||
@@ -0,0 +1,99 @@
|
||||
;;
|
||||
;; Names of ZP and low memory locations
|
||||
;; (https://www.c64-wiki.com/wiki/Zeropage)
|
||||
;;
|
||||
|
||||
;; $00-$01 - 6502 CPU registers are here
|
||||
|
||||
;;
|
||||
;; Page 0 - BASIC area ($02-$8F)
|
||||
;;
|
||||
|
||||
.alias TXTTAB $2B
|
||||
|
||||
;;
|
||||
;; Page 0 - Kernal area ($90-$FF)
|
||||
;;
|
||||
|
||||
.alias IOSTATUS $90
|
||||
.alias STKEY $91 ; Keys down clears bits. STOP - bit 7, C= - bit 6, SPACE - bit 4, CTRL - bit 2
|
||||
|
||||
.alias VERCK $93 ; 0 = LOAD, 1 = VERIVY
|
||||
|
||||
.alias C3PO $94 ; flag - is BSOUR content valid
|
||||
.alias BSOUR $95 ; serial bus buffered output byte
|
||||
|
||||
.alias LDTND $98 ; number of entries in LAT / FAT / SAT tables
|
||||
.alias DFLTN $99
|
||||
.alias DFLTO $9A
|
||||
|
||||
.alias MSGFLG $9D ; bit 6 = error messages, bit 7 = control message
|
||||
|
||||
.alias TIME $A0 ; $A0-$A2, jiffy clock
|
||||
|
||||
.alias IEC_TMP1 $A3 ; temporary variable for tape and IEC
|
||||
.alias IEC_TMP2 $A4 ; temporary variable for tape and IEC
|
||||
|
||||
;; 2-byte location below seems to be a good place for temporary storage,
|
||||
;; it seems used for timing during tape reads only - see:
|
||||
;; - 'C64 Programmer's Reference Guide', page 314
|
||||
;; - 'Compute's Mapping the Commodore 64', page 32
|
||||
.alias CMP0 $B0 ; $B0-$B1
|
||||
|
||||
.alias FNLEN $B7 ; current file name length
|
||||
|
||||
.alias FNADDR $BB ; $BB-$BC, current file name pointer
|
||||
|
||||
.alias STAL $C1 ; $C1-$C2 LOAD/SAVE start address
|
||||
|
||||
;;
|
||||
;; Other low memory addresses
|
||||
;;
|
||||
|
||||
.alias BUF $200 ; $200-$250 (81 bytes), BASIC line editor input buffer
|
||||
|
||||
;; Kernal tables for opened files, 10 entries each
|
||||
.alias LAT $259 ; logical file numbers
|
||||
.alias FAT $263 ; device numbers
|
||||
.alias SAT $26D ; secondary addresses
|
||||
|
||||
.alias MEMSTR $281
|
||||
.alias MEMSIZ $283 ; NOTE: Mapping the 64 erroniously has the hex as $282, while the DEC is correct
|
||||
|
||||
.alias HIBASE $288 ; high byte of start of screen
|
||||
|
||||
.alias RSSTAT $297 ; RS-232 status
|
||||
|
||||
.alias PALNTSC $2A6 ; 0 = NTSC, 1 = PAL
|
||||
|
||||
|
||||
;; Registers for SYS call
|
||||
.alias SAREG $30C
|
||||
.alias SXREG $30D
|
||||
.alias SYREG $30E
|
||||
.alias SPREG $30F
|
||||
|
||||
.alias USRPOK $310 ; JMP instruction
|
||||
.alias USRADD $311 ; $311 - $312
|
||||
|
||||
;; Kernal vectors - interrupts
|
||||
.alias CINV $314
|
||||
.alias CBINV $316
|
||||
.alias NMINV $318
|
||||
|
||||
;; Kernal vectors - routines
|
||||
.alias IOPEN $31A
|
||||
.alias ICLOSE $31C
|
||||
.alias ICHKIN $31E
|
||||
.alias ICKOUT $320
|
||||
.alias ICLRCH $322
|
||||
.alias IBASIN $324
|
||||
.alias IBSOUT $326
|
||||
.alias ISTOP $328
|
||||
.alias IGETIN $32A
|
||||
.alias ICLALL $32C
|
||||
.alias USRCMD $32E
|
||||
.alias ILOAD $330
|
||||
.alias ISAVE $331
|
||||
|
||||
.alias TBUFFR $33C ; $33C-$3FB, tape buffer
|
||||
Whitespace-only changes.
@@ -0,0 +1,41 @@
|
||||
|
||||
;; Kernal jump table
|
||||
.alias JCINT $FF81
|
||||
.alias JIOINIT $FF84
|
||||
.alias JRAMTAS $FF87
|
||||
.alias JRESTOR $FF8A
|
||||
.alias JVECTOR $FF8D
|
||||
.alias JSETMSG $FF90
|
||||
.alias JSECOND $FF93
|
||||
.alias JTKSA $FF96
|
||||
.alias JMEMTOP $FF99
|
||||
.alias JMEMBOT $FF9C
|
||||
.alias JSCNKEY $FF9F
|
||||
.alias JSETTMO $FFA2
|
||||
.alias JACPTR $FFA5
|
||||
.alias JCIOUT $FFA8
|
||||
.alias JUNTLK $FFAB
|
||||
.alias JUNLSN $FFAE
|
||||
.alias JLISTEN $FFB1
|
||||
.alias JTALK $FFB4
|
||||
.alias JREADST $FFB7
|
||||
.alias JSETFLS $FFBA
|
||||
.alias JSETNAM $FFBD
|
||||
.alias JOPEN $FFC0
|
||||
.alias JCLOSE $FFC3
|
||||
.alias JCHKIN $FFC6
|
||||
.alias JCKOUT $FFC9
|
||||
.alias JCLRCHN $FFCC
|
||||
.alias JCHRIN $FFCF
|
||||
.alias JCHROUT $FFD2
|
||||
.alias JLOAD $FFD5
|
||||
.alias JSAVE $FFD8
|
||||
.alias JSETTIM $FFDB
|
||||
.alias JRDTIM $FFDE
|
||||
.alias JSTOP $FFE1
|
||||
.alias JGETIN $FFE4
|
||||
.alias JCLALL $FFE7
|
||||
.alias JUDTIM $FFEA
|
||||
.alias JSCREEN $FFED
|
||||
.alias JPLOT $FFF0
|
||||
.alias JIOBASE $FFF3
|
||||
+3
-24
@@ -52,22 +52,13 @@
|
||||
.alias memmove_dst $6b
|
||||
.alias memmove_size $6d
|
||||
|
||||
.alias TXTTAB $2B
|
||||
.alias IOSTATUS $90
|
||||
; Keys down clears bits. STOP=bit 7, C= bit 6, SPACE bit 4, CTRL bit 2
|
||||
.alias BUCKYSTATUS $91
|
||||
.alias load_or_verify_flag $93
|
||||
.alias current_file_num $98
|
||||
.alias input_device_number $99
|
||||
; bit 6 = error messages, bit 7 = control messages
|
||||
.alias kernal_message_control_flags $9d
|
||||
.alias jiffy_clock_24bits $a0
|
||||
.alias cassette_buffer_bytes_used $A6
|
||||
.alias load_or_scroll_temp_pointer $AC
|
||||
;; We also use the following for temp colour pointer when scrolling
|
||||
.alias load_save_verify_end_address $AE
|
||||
|
||||
.alias cassette_buffer_ptr $B2
|
||||
.alias current_filename_length $B7
|
||||
.alias current_logical_filenum $B8
|
||||
.alias current_secondary_address $B9
|
||||
.alias current_device_number $BA
|
||||
@@ -100,15 +91,12 @@
|
||||
.alias rs232_rx_buffer_ptr $F7
|
||||
.alias rs232_tx_buffer_ptr $F9
|
||||
|
||||
.alias basic_input_buffer $0200
|
||||
|
||||
.alias basic_input_buffer BUF
|
||||
|
||||
; "Compute's Mapping the 64" book
|
||||
.alias keyboard_buffer $0277
|
||||
.alias MEMSTR $0281
|
||||
.alias MEMSIZ $0283 ; NOTE: Mapping the 64 erroniously has the hex as $282, while the DEC is correct
|
||||
.alias text_colour $0286 ; p55
|
||||
.alias colour_under_cursor $0287 ; p56
|
||||
.alias HIBASE $0288 ; p56 (high byte of start of screen)
|
||||
.alias key_buffer_size $0289 ; p57
|
||||
|
||||
;; 0 = cursor keys, insert, delete and space repeat, but nothing else
|
||||
@@ -124,14 +112,6 @@
|
||||
.alias keyboard_decoding_ptr $028F
|
||||
.alias enable_case_switch $0291
|
||||
.alias screen_scroll_disable $0292
|
||||
.alias pal_or_ntsc $02A6
|
||||
|
||||
;; Registers for SYS call
|
||||
.alias sys_reg_a $30c
|
||||
.alias sys_reg_x $30d
|
||||
.alias sys_reg_y $30e
|
||||
.alias sys_reg_p $30f
|
||||
.alias sys_jmp $310
|
||||
|
||||
;; BASIC uses some extra bytes for memory access under ROMs located at $2A7 onwards
|
||||
;; IRQs are disabled when doing such accesses, and a default NMI handler only increments
|
||||
@@ -144,4 +124,3 @@
|
||||
.alias poke_under_roms tiny_nmi_handler+poke_under_roms_routine-tiny_nmi_handler_routine
|
||||
.alias memmap_allram tiny_nmi_handler+memmap_allram_routine-tiny_nmi_handler_routine
|
||||
.alias memmap_normal tiny_nmi_handler+memmap_normal_routine-tiny_nmi_handler_routine
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
|
||||
;; Target-specific hooks
|
||||
|
||||
|
||||
.macro TARGET_HOOK_BANNER
|
||||
|
||||
.byte $05, " OPEN ROMS, ", $00
|
||||
|
||||
.macend
|
||||
@@ -0,0 +1,41 @@
|
||||
|
||||
;; Target-specific hooks
|
||||
|
||||
|
||||
.macro TARGET_HOOK_BANNER
|
||||
|
||||
;; New banner from Retrofan
|
||||
.byte $9a, $12, $20, $20, $7f, $a9, $20, $20, $1f, $20, $9a, $20, $20, $20
|
||||
.byte $20, $1f, $20, $9a, $a9, $20, $20, $20, $92, $a1, $1f, $12, $20, $9a, $a9, $20
|
||||
.byte $20, $20, $7f, $1f, $20, $20, $9a, $a3, $a3, $a3, $a3, $a3, $a3, $a3, $1f, $20
|
||||
.byte $20, $20, $20, $05, $92, $4d, $45, $47, $41, $9a, $12, $20, $20, $20, $20, $20
|
||||
.byte $20, $1f, $20, $9a, $20, $20, $92, $a2, $bb, $1f, $12, $20, $9a, $20, $20, $92
|
||||
.byte $ac, $a2, $a2, $1f, $12, $20, $9a, $20, $20, $1f, $20, $9a, $20, $20, $1f, $20
|
||||
.byte $20, $1e, $a3, $a3, $a3, $a3, $a3, $a3, $1f, $20, $20, $20, $20, $05, $92, $42
|
||||
.byte $41, $53, $49, $43, $9a, $12, $20, $20, $92, $7f, $a9, $12, $20, $20, $1f, $20
|
||||
.byte $9a, $20, $20, $a2, $92, $be, $1f, $12, $20, $9a, $20, $20, $92, $bc, $12, $20
|
||||
.byte $20, $1f, $20, $9a, $20, $20, $20, $20, $20, $1f, $20, $20, $9e, $a3, $a3, $a3
|
||||
.byte $a3, $a3, $1f, $20, $20, $20, $20, $05, $92, $2d, $2d, $2d, $2d, $2d, $2d, $9a
|
||||
.byte $12, $20, $20, $1f, $20, $20, $9a, $20, $20, $1f, $20, $9a, $20, $20, $20, $20
|
||||
.byte $1f, $20, $9a, $20, $20, $20, $20, $20, $1f, $20, $9a, $20, $20, $1f, $20, $9a
|
||||
.byte $20, $20, $1f, $20, $20, $96, $a3, $a3, $a3, $a3, $1f
|
||||
.byte $92, $0D, $0D, $05, $00
|
||||
|
||||
;; Original Deft-supplied banner
|
||||
;; .byte $9A,$12,$A3,$A3,$A3,$A3,$A3,$A3,$DF,$9B,$92,$20,$05,$12,$A0,$A0
|
||||
;; .byte $DF,$9B,$92,$20,$05,$12,$A0,$A0,$DF,$9B,$92,$20,$05,$12,$A0,$A0
|
||||
;; .byte $DF,$9B,$92,$20,$05,$12,$A0,$A0,$DF,$9A,$92,$20,$05,$20,$20,$20
|
||||
;; .byte $4D,$20,$45,$20,$47,$20,$41,$0D,$99,$12,$A3,$A3,$A3,$A3,$A3,$A3
|
||||
;; .byte $A3,$DF,$92,$7F,$12,$CD,$CD,$DF,$92,$7F,$12,$DF,$05,$92,$20,$20
|
||||
;; .byte $99,$7F,$12,$DF,$05,$92,$20,$20,$99,$7F,$12,$DF,$92,$7F,$12,$DF
|
||||
;; .byte $05,$92,$20,$20,$99,$42,$20,$41,$20,$53,$20,$49,$20,$43,$0D,$9E
|
||||
;; .byte $12,$A3,$A3,$A3,$A3,$A3,$A3,$A3,$A3,$DF,$9B,$92,$7F,$12,$DF,$92
|
||||
;; .byte $7F,$12,$DF,$92,$7F,$12,$CD,$05,$92,$20,$20,$9B,$7F,$12,$CD,$92
|
||||
;; .byte $7F,$12,$DF,$92,$7F,$12,$CD,$92,$7F,$12,$DF,$9A,$92,$20,$05,$20
|
||||
;; .byte $9A,$2D,$2D,$2D,$2D,$2D,$2D,$2D,$0D,$96,$12,$A3,$A3,$A3,$A3,$A3
|
||||
;; .byte $A3,$A3,$A3,$A3,$DF,$9A,$92,$7F,$12,$DF,$92,$7F,$9B,$20,$9A,$7F
|
||||
;; .byte $12,$A0,$A0,$9B,$92,$20,$9A,$7F,$12,$A0,$A0,$9B,$92,$20,$9A,$7F
|
||||
;; .byte $12,$DF,$92,$7F,$9B,$20,$9A,$20,$9B,"0.2.0.0",$0D
|
||||
;; .byte $0D,$05,$92,$00
|
||||
|
||||
.macend
|
||||
@@ -0,0 +1,9 @@
|
||||
|
||||
;; Target-specific hooks
|
||||
|
||||
|
||||
.macro TARGET_HOOK_BANNER
|
||||
|
||||
.byte $05, " OPEN ROMS FOR ULTIMATE 64", $0D, $0D, " ", $00
|
||||
|
||||
.macend
|
||||
@@ -20,7 +20,7 @@ print_string_loop:
|
||||
lda (temp_string_ptr),y
|
||||
beq print_string_end
|
||||
|
||||
jsr $FFD2 ; KERNAL CHROUT
|
||||
jsr via_IBSOUT
|
||||
|
||||
txa
|
||||
tay
|
||||
|
||||
@@ -15,41 +15,7 @@ basic_cold_start:
|
||||
; Used 217 bytes
|
||||
startup_banner:
|
||||
|
||||
;; New banner from Retrofan
|
||||
.byte $9a, $12, $20, $20, $7f, $a9, $20, $20, $1f, $20, $9a, $20, $20, $20
|
||||
.byte $20, $1f, $20, $9a, $a9, $20, $20, $20, $92, $a1, $1f, $12, $20, $9a, $a9, $20
|
||||
.byte $20, $20, $7f, $1f, $20, $20, $9a, $a3, $a3, $a3, $a3, $a3, $a3, $a3, $1f, $20
|
||||
.byte $20, $20, $20, $05, $92, $4d, $45, $47, $41, $9a, $12, $20, $20, $20, $20, $20
|
||||
.byte $20, $1f, $20, $9a, $20, $20, $92, $a2, $bb, $1f, $12, $20, $9a, $20, $20, $92
|
||||
.byte $ac, $a2, $a2, $1f, $12, $20, $9a, $20, $20, $1f, $20, $9a, $20, $20, $1f, $20
|
||||
.byte $20, $1e, $a3, $a3, $a3, $a3, $a3, $a3, $1f, $20, $20, $20, $20, $05, $92, $42
|
||||
.byte $41, $53, $49, $43, $9a, $12, $20, $20, $92, $7f, $a9, $12, $20, $20, $1f, $20
|
||||
.byte $9a, $20, $20, $a2, $92, $be, $1f, $12, $20, $9a, $20, $20, $92, $bc, $12, $20
|
||||
.byte $20, $1f, $20, $9a, $20, $20, $20, $20, $20, $1f, $20, $20, $9e, $a3, $a3, $a3
|
||||
.byte $a3, $a3, $1f, $20, $20, $20, $20, $05, $92, $2d, $2d, $2d, $2d, $2d, $2d, $9a
|
||||
.byte $12, $20, $20, $1f, $20, $20, $9a, $20, $20, $1f, $20, $9a, $20, $20, $20, $20
|
||||
.byte $1f, $20, $9a, $20, $20, $20, $20, $20, $1f, $20, $9a, $20, $20, $1f, $20, $9a
|
||||
.byte $20, $20, $1f, $20, $20, $96, $a3, $a3, $a3, $a3, $1f
|
||||
.byte $92, $0D, $0D, $05
|
||||
|
||||
.byte $00
|
||||
|
||||
;; Original Deft-supplied banner
|
||||
;; .byte $9A,$12,$A3,$A3,$A3,$A3,$A3,$A3,$DF,$9B,$92,$20,$05,$12,$A0,$A0
|
||||
;; .byte $DF,$9B,$92,$20,$05,$12,$A0,$A0,$DF,$9B,$92,$20,$05,$12,$A0,$A0
|
||||
;; .byte $DF,$9B,$92,$20,$05,$12,$A0,$A0,$DF,$9A,$92,$20,$05,$20,$20,$20
|
||||
;; .byte $4D,$20,$45,$20,$47,$20,$41,$0D,$99,$12,$A3,$A3,$A3,$A3,$A3,$A3
|
||||
;; .byte $A3,$DF,$92,$7F,$12,$CD,$CD,$DF,$92,$7F,$12,$DF,$05,$92,$20,$20
|
||||
;; .byte $99,$7F,$12,$DF,$05,$92,$20,$20,$99,$7F,$12,$DF,$92,$7F,$12,$DF
|
||||
;; .byte $05,$92,$20,$20,$99,$42,$20,$41,$20,$53,$20,$49,$20,$43,$0D,$9E
|
||||
;; .byte $12,$A3,$A3,$A3,$A3,$A3,$A3,$A3,$A3,$DF,$9B,$92,$7F,$12,$DF,$92
|
||||
;; .byte $7F,$12,$DF,$92,$7F,$12,$CD,$05,$92,$20,$20,$9B,$7F,$12,$CD,$92
|
||||
;; .byte $7F,$12,$DF,$92,$7F,$12,$CD,$92,$7F,$12,$DF,$9A,$92,$20,$05,$20
|
||||
;; .byte $9A,$2D,$2D,$2D,$2D,$2D,$2D,$2D,$0D,$96,$12,$A3,$A3,$A3,$A3,$A3
|
||||
;; .byte $A3,$A3,$A3,$A3,$DF,$9A,$92,$7F,$12,$DF,$92,$7F,$9B,$20,$9A,$7F
|
||||
;; .byte $12,$A0,$A0,$9B,$92,$20,$9A,$7F,$12,$A0,$A0,$9B,$92,$20,$9A,$7F
|
||||
;; .byte $12,$DF,$92,$7F,$9B,$20,$9A,$20,$9B,"0.2.0.0",$0D
|
||||
;; .byte $0D,$05,$92,$00
|
||||
`TARGET_HOOK_BANNER
|
||||
|
||||
;; Work out free bytes, and display
|
||||
jsr basic_do_new
|
||||
@@ -63,7 +29,7 @@ startup_banner:
|
||||
jsr print_integer
|
||||
|
||||
lda #$20
|
||||
jsr $ffd2
|
||||
jsr via_IBSOUT
|
||||
|
||||
;; Print the rest of the start up message
|
||||
ldx #34
|
||||
|
||||
@@ -7,9 +7,9 @@ basic_do_error:
|
||||
|
||||
;; Print ? at start
|
||||
lda #$0d
|
||||
jsr $ffd2
|
||||
jsr via_IBSOUT
|
||||
lda #$3f
|
||||
jsr $ffd2
|
||||
jsr via_IBSOUT
|
||||
|
||||
;; Print main part of error message
|
||||
pla
|
||||
@@ -18,7 +18,7 @@ basic_do_error:
|
||||
|
||||
;; Print ERROR at end
|
||||
lda #$20
|
||||
jsr $ffd2
|
||||
jsr via_IBSOUT
|
||||
ldx #33
|
||||
jsr print_packed_message
|
||||
|
||||
@@ -27,9 +27,9 @@ basic_do_error:
|
||||
;; XXX print line number if not in direct mode
|
||||
|
||||
lda #$0d
|
||||
jsr $ffd2
|
||||
jsr via_IBSOUT
|
||||
lda #$0d
|
||||
jsr $ffd2
|
||||
jsr via_IBSOUT
|
||||
|
||||
;; Reset stack, and go back to main loop
|
||||
ldx #$fe
|
||||
|
||||
@@ -29,7 +29,7 @@ no_space_to_skip:
|
||||
basic_execute_statement:
|
||||
|
||||
;; Check for RUN/STOP
|
||||
lda BUCKYSTATUS
|
||||
lda STKEY
|
||||
bpl basic_do_break
|
||||
|
||||
;; Skip over any white space and :
|
||||
@@ -80,9 +80,9 @@ basic_execute_statement:
|
||||
;; Now consume the character
|
||||
jsr basic_consume_character
|
||||
|
||||
rts
|
||||
rts
|
||||
|
||||
not_a_token:
|
||||
not_a_token:
|
||||
;; Space, which we can also just ignore
|
||||
cmp #$20
|
||||
beq basic_skip_char
|
||||
@@ -93,11 +93,28 @@ not_a_token:
|
||||
cmp #$3a
|
||||
beq basic_skip_char
|
||||
|
||||
;; START wedge support
|
||||
|
||||
;; Are we in direct mode?
|
||||
;; DOS Wedge is a hacky solution (inelegant, but convenient),
|
||||
;; BASIC programmers should implement communication with drives
|
||||
;; the standard way, handling channels properly. Besides,
|
||||
;; current implementation does not support characters under ROM
|
||||
ldx basic_current_line_number+1
|
||||
cpx #$ff
|
||||
bne +
|
||||
;; We are in direct mode, allow wedge to handle '@' sign
|
||||
;; XXX Maybe it should be allowed only as the first command?
|
||||
cmp #$40
|
||||
bne +
|
||||
jsr basic_consume_character
|
||||
jmp wedge_dos
|
||||
*
|
||||
;; END wedge support
|
||||
|
||||
;; If all else fails, it's a syntax error
|
||||
jmp do_SYNTAX_error
|
||||
|
||||
jmp basic_main_loop
|
||||
|
||||
basic_skip_char:
|
||||
jsr basic_consume_character
|
||||
jmp basic_execute_statement
|
||||
|
||||
@@ -52,7 +52,7 @@ rsl_l1: lda $0200,x
|
||||
*
|
||||
;; Do printing of the new line
|
||||
lda #$0d
|
||||
jsr $ffd2
|
||||
jsr via_IBSOUT
|
||||
|
||||
;; Ignore empty lines
|
||||
lda tokenise_work1
|
||||
|
||||
@@ -17,7 +17,7 @@ basic_do_break:
|
||||
|
||||
*
|
||||
lda #$0d
|
||||
jsr $ffd2
|
||||
jsr via_IBSOUT
|
||||
cmd_end:
|
||||
jmp basic_main_loop
|
||||
|
||||
+12
-9
@@ -22,10 +22,16 @@ list_loop:
|
||||
jmp basic_main_loop
|
||||
|
||||
list_more_lines:
|
||||
lda BUCKYSTATUS
|
||||
lda STKEY
|
||||
bmi +
|
||||
jmp basic_do_break
|
||||
*
|
||||
jsr list_single_line
|
||||
;; Now link to the next line
|
||||
jsr basic_find_next_line
|
||||
jmp list_loop
|
||||
|
||||
list_single_line: ; entry point needed by DOS wedge
|
||||
;; Print line number
|
||||
ldy #3
|
||||
jsr peek_under_roms
|
||||
@@ -36,7 +42,7 @@ list_more_lines:
|
||||
pla
|
||||
jsr print_integer
|
||||
lda #$20
|
||||
jsr $ffd2
|
||||
jsr via_IBSOUT
|
||||
|
||||
;; Iterate through printing out the line
|
||||
;; contents
|
||||
@@ -105,19 +111,16 @@ list_not_rem:
|
||||
bne list_print_loop
|
||||
|
||||
list_is_literal:
|
||||
jsr $ffd2
|
||||
jsr via_IBSOUT
|
||||
iny
|
||||
bne list_print_loop
|
||||
|
||||
list_end_of_line:
|
||||
;; Clear reverse flag
|
||||
lda #$92
|
||||
jsr $ffd2
|
||||
jsr via_IBSOUT
|
||||
;; Print end of line
|
||||
lda #$0d
|
||||
jsr $ffd2
|
||||
jsr via_IBSOUT
|
||||
rts
|
||||
|
||||
;; Now link to the next line
|
||||
jsr basic_find_next_line
|
||||
jmp list_loop
|
||||
|
||||
+51
-9
@@ -11,9 +11,18 @@ cmd_load:
|
||||
;; middle of a program. For safety, we do.
|
||||
jsr basic_do_clr
|
||||
|
||||
;; Setup Kernal to print control messages or not
|
||||
lda #$80 ; display control messages and omit error messages
|
||||
ldx basic_current_line_number+1
|
||||
cpx #$FF
|
||||
beq +
|
||||
lda #$00 ; direct mode - don't display anything
|
||||
*
|
||||
jsr JSETMSG
|
||||
|
||||
;; Set filename and length
|
||||
lda #$00
|
||||
sta current_filename_length
|
||||
sta FNLEN
|
||||
|
||||
;; Without tape support, LOAD must have a filename
|
||||
;; (This also skips any leading spaces)
|
||||
@@ -34,7 +43,7 @@ cmd_load:
|
||||
|
||||
;; Now search for end of line or closing quote
|
||||
;; so that we know the length of the filename
|
||||
getting_filename:
|
||||
getting_filename:
|
||||
jsr basic_fetch_and_consume_character
|
||||
cmp #$22
|
||||
beq got_filename
|
||||
@@ -44,19 +53,52 @@ getting_filename:
|
||||
|
||||
jmp got_filename
|
||||
*
|
||||
inc current_filename_length
|
||||
inc FNLEN
|
||||
jmp getting_filename
|
||||
|
||||
got_filename:
|
||||
got_filename:
|
||||
|
||||
;; Try to load an IEC file
|
||||
lda #0 ; use supplied load address, not the one from the file
|
||||
;; Now fetch the file number, start from the default one
|
||||
jsr select_device
|
||||
stx current_device_number
|
||||
jsr injest_comma
|
||||
bcs got_devicenumber
|
||||
|
||||
jsr basic_parse_line_number
|
||||
lda basic_line_number+1
|
||||
bne do_ILLEGAL_QUANTITY_error
|
||||
lda basic_line_number+0
|
||||
sta current_device_number
|
||||
|
||||
got_devicenumber:
|
||||
|
||||
;; Now fetch the secondary address
|
||||
lda #$00
|
||||
sta current_secondary_address
|
||||
lda #$00 ; LOAD not verify
|
||||
ldx #<$0801 ; LOAD address = $0801
|
||||
jsr injest_comma
|
||||
bcs got_secondaryaddress
|
||||
jsr basic_parse_line_number
|
||||
lda basic_line_number+1
|
||||
bne +
|
||||
lda basic_line_number+0
|
||||
sta current_secondary_address
|
||||
jmp got_secondaryaddress
|
||||
*
|
||||
;; Second parameter is above 255, this can't be a secondary address
|
||||
;; Use it as load address instead
|
||||
;; XXX temporary syntax, it would be better to use something
|
||||
;; XXX like 'LOAD"FILE",8 TO 49152'
|
||||
ldx basic_line_number+0
|
||||
ldy basic_line_number+1
|
||||
bne got_loadaddress
|
||||
|
||||
got_secondaryaddress:
|
||||
ldx #<$0801
|
||||
ldy #>$0801
|
||||
|
||||
jsr $ffd5
|
||||
got_loadaddress:
|
||||
lda #$00 ; LOAD not verify
|
||||
jsr via_ILOAD
|
||||
bcc +
|
||||
|
||||
;; A = KERNAL error code, which also almost match
|
||||
|
||||
+1
-1
@@ -41,7 +41,7 @@ basic_do_new:
|
||||
;; (same story), expression value cache?
|
||||
|
||||
sec ; Read, not write value
|
||||
jsr $ff99 ; KERNAL MEMTOP routine
|
||||
jsr JMEMTOP
|
||||
cpx #$80
|
||||
beq +
|
||||
lda #>$f7ff
|
||||
|
||||
+9
-9
@@ -10,22 +10,22 @@ cmd_sys:
|
||||
jsr basic_parse_line_number
|
||||
|
||||
;; setup call
|
||||
lda #$4c ;JMP
|
||||
sta sys_jmp
|
||||
lda #$4C ;JMP
|
||||
sta USRPOK
|
||||
lda basic_line_number+0
|
||||
sta sys_jmp+1
|
||||
sta USRADD+0
|
||||
lda basic_line_number+1
|
||||
sta sys_jmp+2
|
||||
sta USRADD+1
|
||||
|
||||
;; Setup the register values
|
||||
lda sys_reg_p
|
||||
lda SPREG
|
||||
pha
|
||||
ldy sys_reg_y
|
||||
ldx sys_reg_x
|
||||
lda sys_reg_a
|
||||
ldy SYREG
|
||||
ldx SXREG
|
||||
lda SAREG
|
||||
plp
|
||||
|
||||
;; Call the routine.
|
||||
jsr sys_jmp
|
||||
jsr USRPOK
|
||||
|
||||
jmp basic_execute_statement
|
||||
@@ -0,0 +1,20 @@
|
||||
|
||||
;; Consummes a comma in a BASIC code, C set for no coma found
|
||||
|
||||
injest_comma:
|
||||
|
||||
jsr basic_fetch_and_consume_character
|
||||
cmp #$2C ; comma character
|
||||
beq injest_comma_found
|
||||
cmp #$20
|
||||
beq injest_comma ; space, can always be skipped
|
||||
|
||||
;; not found
|
||||
jsr basic_unconsume_character
|
||||
sec
|
||||
rts
|
||||
|
||||
injest_comma_found:
|
||||
clc
|
||||
rts
|
||||
|
||||
@@ -1,126 +0,0 @@
|
||||
packed_message_chars:
|
||||
.byte $45 ; 'E' = $1 (nybl)
|
||||
.byte $54 ; 'T' = $2 (nybl)
|
||||
.byte $4F ; 'O' = $3 (nybl)
|
||||
.byte $4E ; 'N' = $4 (nybl)
|
||||
.byte $49 ; 'I' = $5 (nybl)
|
||||
.byte $52 ; 'R' = $6 (nybl)
|
||||
.byte $41 ; 'A' = $7 (nybl)
|
||||
.byte $4C ; 'L' = $8 (nybl)
|
||||
.byte $53 ; 'S' = $9 (nybl)
|
||||
.byte $44 ; 'D' = $a (nybl)
|
||||
.byte $46 ; 'F' = $b (nybl)
|
||||
.byte $55 ; 'U' = $c (nybl)
|
||||
.byte $50 ; 'P' = $d (nybl)
|
||||
.byte $4D ; 'M' = $e (nybl)
|
||||
.byte $43 ; 'C' = $F1 / $xF $43
|
||||
.byte $47 ; 'G' = $F2 / $xF $47
|
||||
.byte $59 ; 'Y' = $F3 / $xF $59
|
||||
.byte $56 ; 'V' = $F4 / $xF $56
|
||||
.byte $42 ; 'B' = $F5 / $xF $42
|
||||
.byte $48 ; 'H' = $F6 / $xF $48
|
||||
.byte $58 ; 'X' = $F7 / $xF $58
|
||||
.byte $57 ; 'W' = $F8 / $xF $57
|
||||
.byte $24 ; '$' = $F9 / $xF $24
|
||||
.byte $27 ; ''' = $Fa / $xF $27
|
||||
.byte $0D ; '␍' = $Fb / $xF $0D
|
||||
.byte $51 ; 'Q' = $Fc / $xF $51
|
||||
.byte $2E ; '.' = $Fd / $xF $2E
|
||||
.byte $23 ; '#' = $FE/F + $23
|
||||
.byte $4B ; 'K' = $FE/F + $4B
|
||||
.byte $28 ; '(' = $FE/F + $28
|
||||
.byte $5A ; 'Z' = $FE/F + $5A
|
||||
.byte $2B ; '+' = $FE/F + $2B
|
||||
.byte $2D ; '-' = $FE/F + $2D
|
||||
.byte $2A ; '*' = $FE/F + $2A
|
||||
.byte $2F ; '/' = $FE/F + $2F
|
||||
.byte $5E ; '^' = $FE/F + $5E
|
||||
.byte $3E ; '>' = $FE/F + $3E
|
||||
.byte $3D ; '=' = $FE/F + $3D
|
||||
.byte $3C ; '<' = $FE/F + $3C
|
||||
packed_message_tokens:
|
||||
.byte $00,$01,$02,$ff,$03,$04,$ff,$03
|
||||
.byte $05,$04,$ff,$03,$05,$06,$ff,$07
|
||||
.byte $05,$08,$ff,$05,$09,$03,$ff,$05
|
||||
.byte $0a,$03,$ff,$0b,$0c,$ff,$0d,$07
|
||||
.byte $0e,$ff,$0f,$10,$11,$ff,$12,$ff
|
||||
.byte $13,$10,$14,$ff,$15,$16,$17,$ff
|
||||
.byte $0d,$18,$ff,$19,$ff,$15,$16,$1a
|
||||
.byte $ff,$1b,$1c,$ff,$1d,$1e,$ff,$1f
|
||||
.byte $20,$ff,$21,$22,$23,$ff,$0d,$24
|
||||
.byte $ff,$25,$26,$ff,$27,$00,$28,$ff
|
||||
.byte $03,$17,$ff,$29,$00,$2a,$ff,$2b
|
||||
.byte $2c,$ff,$1b,$2d,$ff,$2e,$ff,$2f
|
||||
.byte $ff,$30,$ff,$31,$ff,$32,$ff,$33
|
||||
.byte $ff,$34,$ff,$35,$36,$ff,$1a,$37
|
||||
.byte $ff
|
||||
.byte $05
|
||||
.byte $38
|
||||
.byte $ff
|
||||
packed_message_words:
|
||||
.byte $23,$30,$e7,$4f,$59,$00,$b5,$81
|
||||
.byte $90,$b5,$81,$00,$3d,$14,$00,$43
|
||||
.byte $20,$b3,$c4,$a0,$a1,$f4,$5f,$43
|
||||
.byte $10,$d6,$19,$14,$20,$54,$dc,$20
|
||||
.byte $3c,$2d,$c2,$00,$e5,$99,$54,$f2
|
||||
.byte $00,$b5,$81,$47,$e1,$00,$58,$81
|
||||
.byte $f2,$78,$00,$4c,$ef,$42,$16,$00
|
||||
.byte $41,$f7,$20,$f8,$52,$f6,$3c,$20
|
||||
.byte $b3,$60,$9f,$59,$42,$7f,$58,$00
|
||||
.byte $61,$2c,$64,$00,$f2,$39,$cf,$42
|
||||
.byte $00,$3c,$20,$3b,$00,$a7,$27,$00
|
||||
.byte $fc,$c7,$42,$52,$f3,$00,$3f,$56
|
||||
.byte $16,$b8,$3f,$57,$00,$e1,$e3,$6f
|
||||
.byte $59,$00,$c4,$a1,$bf,$27,$a0,$92
|
||||
.byte $72,$1e,$14,$20,$f5,$7a,$00,$9c
|
||||
.byte $f5,$9f,$43,$65,$d2,$00,$61,$a5
|
||||
.byte $ef,$27,$a0,$76,$67,$f3,$00,$a5
|
||||
.byte $f4,$59,$53,$40,$f5,$f3,$00,$ff
|
||||
.byte $5a,$16,$30,$a5,$61,$f1,$20,$2f
|
||||
.byte $59,$d1,$00,$e5,$9e,$72,$f1,$f6
|
||||
.byte $00,$92,$65,$4f,$47,$00,$83,$4f
|
||||
.byte $47,$00,$b3,$6e,$c8,$70,$f1,$3e
|
||||
.byte $d8,$1f,$58,$00,$f1,$74,$fa,$20
|
||||
.byte $f1,$34,$25,$4c,$10,$bc,$4f,$43
|
||||
.byte $25,$34,$00,$f4,$16,$5b,$f3,$00
|
||||
.byte $83,$7a,$00,$61,$7a,$f3,$fd,$fb
|
||||
.byte $00,$83,$7a,$54,$f2,$00,$f4,$16
|
||||
.byte $5b,$f3,$54,$f2,$00,$97,$f4,$54
|
||||
.byte $f2,$00,$16,$63,$60,$f5,$f3,$21
|
||||
.byte $90,$b6,$11,$fd,$fb,$fb,$00,$f1
|
||||
.byte $36,$6c,$d2,$00,$5e,$d8,$1e,$14
|
||||
.byte $21
|
||||
.byte $a0
|
||||
packed_keywords:
|
||||
.byte $14,$a0,$b3,$60,$41,$f7,$20,$a7
|
||||
.byte $27,$00,$54,$dc,$2f,$23,$00,$54
|
||||
.byte $dc,$20,$a5,$e0,$61,$7a,$00,$81
|
||||
.byte $20,$f2,$32,$30,$6c,$40,$5b,$00
|
||||
.byte $61,$92,$36,$10,$f2,$39,$cf,$42
|
||||
.byte $00,$61,$2c,$64,$00,$61,$e0,$92
|
||||
.byte $3d,$00,$34,$00,$f8,$75,$20,$83
|
||||
.byte $7a,$00,$97,$f4,$10,$f4,$16,$5b
|
||||
.byte $f3,$00,$a1,$b0,$d3,$ff,$4b,$10
|
||||
.byte $d6,$54,$2f,$23,$00,$d6,$54,$20
|
||||
.byte $f1,$34,$20,$85,$92,$00,$f1,$86
|
||||
.byte $00,$f1,$ea,$00,$9f,$59,$90,$3d
|
||||
.byte $14,$00,$f1,$83,$91,$00,$f2,$12
|
||||
.byte $00,$41,$f8,$00,$27,$f5,$fe,$28
|
||||
.byte $23,$00,$b4,$00,$9d,$f1,$fe,$28
|
||||
.byte $2f,$48,$14,$00,$43,$20,$92,$1d
|
||||
.byte $00,$fe,$2b,$fe,$2d,$fe,$2a,$fe
|
||||
.byte $2f,$fe,$5e,$74,$a0,$36,$00,$fe
|
||||
.byte $3e,$fe,$3d,$fe,$3c,$9f,$47,$40
|
||||
.byte $54,$20,$7f,$42,$90,$c9,$60,$b6
|
||||
.byte $10,$d3,$90,$9f,$51,$60,$64,$a0
|
||||
.byte $83,$f2,$00,$1f,$58,$d0,$f1,$39
|
||||
.byte $00,$95,$40,$27,$40,$72,$40,$d1
|
||||
.byte $1f,$4b,$00,$81,$40,$92,$6f,$24
|
||||
.byte $00,$f4,$78,$00,$79,$f1,$00,$f1
|
||||
.byte $f6,$6f,$24,$00,$81,$b2,$f9,$00
|
||||
.byte $65,$f2,$f6,$2f,$24,$00,$e5,$af
|
||||
.byte $24
|
||||
.byte $00
|
||||
.byte $f2
|
||||
.byte $30
|
||||
.alias packed_keyword_table_len $DC
|
||||
@@ -58,7 +58,7 @@ hi_loop:
|
||||
pha
|
||||
ldx #4
|
||||
clc
|
||||
hi_add_loop:
|
||||
hi_add_loop:
|
||||
lda $0100,x
|
||||
adc number_table_hi,y
|
||||
sta $0100,x
|
||||
@@ -115,7 +115,7 @@ found_start_of_number:
|
||||
;; Print digits
|
||||
* lda $0100,y
|
||||
ora #$30
|
||||
jsr $ffd2
|
||||
jsr via_IBSOUT
|
||||
iny
|
||||
cpy #5
|
||||
bne -
|
||||
|
||||
@@ -38,7 +38,7 @@ found_message_in_token_stream:
|
||||
beq +
|
||||
jsr print_packed_word
|
||||
lda #$20
|
||||
jsr $ffd2
|
||||
jsr via_IBSOUT
|
||||
pla
|
||||
tay
|
||||
iny
|
||||
@@ -47,7 +47,7 @@ found_message_in_token_stream:
|
||||
pla
|
||||
;; Rub out space at the end
|
||||
lda #$14
|
||||
jsr $ffd2
|
||||
jsr via_IBSOUT
|
||||
rts
|
||||
|
||||
print_packed_word:
|
||||
@@ -138,13 +138,13 @@ next_packed_word_char:
|
||||
lsr
|
||||
tax
|
||||
|
||||
;; Save Y so it doesn't get clobbered by $FFD2
|
||||
;; Save Y so it doesn't get clobbered by CHROUT
|
||||
tya
|
||||
pha
|
||||
|
||||
;; X=1-14 = first 14 chars, so subtract one
|
||||
lda packed_message_chars-1,x
|
||||
jsr $FFD2
|
||||
jsr via_IBSOUT
|
||||
|
||||
;; See if there is a char in the low nybl to print
|
||||
pla
|
||||
@@ -171,7 +171,7 @@ has_nybl:
|
||||
|
||||
;; X=1-14 = first 14 chars, so subtract one
|
||||
lda packed_message_chars-1,x
|
||||
jsr $FFD2
|
||||
jsr via_IBSOUT
|
||||
*
|
||||
pla
|
||||
tay
|
||||
@@ -207,7 +207,7 @@ unpack_literal_char:
|
||||
tya
|
||||
pha
|
||||
lda (temp_string_ptr),y
|
||||
jsr $ffd2
|
||||
jsr via_IBSOUT
|
||||
pla
|
||||
tay
|
||||
rts
|
||||
|
||||
+3
-3
@@ -112,7 +112,7 @@ not_hexword:
|
||||
|
||||
not_pointer:
|
||||
;; Print character
|
||||
jsr $ffd2
|
||||
jsr via_IBSOUT
|
||||
|
||||
printf_nextchar:
|
||||
jsr printf_advance
|
||||
@@ -148,11 +148,11 @@ printf_printhexbyte:
|
||||
cmp #$3A
|
||||
bcc +
|
||||
adc #6
|
||||
* jsr $ffd2
|
||||
* jsr via_IBSOUT
|
||||
pla
|
||||
and #$0f
|
||||
ora #$30
|
||||
cmp #$3A
|
||||
bcc +
|
||||
adc #6
|
||||
* jmp $ffd2
|
||||
* jmp via_IBSOUT
|
||||
@@ -0,0 +1,19 @@
|
||||
|
||||
select_device:
|
||||
|
||||
;; Take last device number, make sure it's a drive - 8 or above. Above 30,
|
||||
;; although illegal for IEC we also consider a drive, as they exists
|
||||
;; drivers assigning these numbers to CBM-DOS capable devices - like some
|
||||
;; IEEE-488 carts.
|
||||
;;
|
||||
;; If current device is not a drive, set device to 8 (first drive number)
|
||||
;; Device number is left in X, for SETFLS Kernal routine
|
||||
|
||||
;; Note: if tape support is introduced here, make sure DOS wedge won't get broken
|
||||
|
||||
ldx current_device_number
|
||||
cpx #$08
|
||||
bcs +
|
||||
ldx #$08
|
||||
*
|
||||
rts
|
||||
@@ -0,0 +1,42 @@
|
||||
|
||||
;;
|
||||
;; Helper routines for jumping via vectors, to be used with JSR
|
||||
;;
|
||||
;; Note: they are not in the order of low memory vectors, to avoid
|
||||
;; similarity with the original ROMs
|
||||
|
||||
via_ISAVE:
|
||||
jmp (ISAVE)
|
||||
|
||||
via_ILOAD:
|
||||
jmp (ILOAD)
|
||||
|
||||
via_ICLOSE:
|
||||
jmp (ICLOSE)
|
||||
|
||||
via_IOPEN:
|
||||
jmp (IOPEN)
|
||||
|
||||
via_ICHKIN:
|
||||
jmp (ICHKIN)
|
||||
|
||||
via_IBASIN:
|
||||
jmp (IBASIN)
|
||||
|
||||
via_IGETIN:
|
||||
jmp (IGETIN)
|
||||
|
||||
via_ICKOUT:
|
||||
jmp (ICKOUT)
|
||||
|
||||
via_IBSOUT:
|
||||
jmp (IBSOUT)
|
||||
|
||||
via_ICLRCH:
|
||||
jmp (ICLRCH)
|
||||
|
||||
via_ICLALL:
|
||||
jmp (ICLALL)
|
||||
|
||||
via_ISTOP:
|
||||
jmp (ISTOP)
|
||||
@@ -0,0 +1,230 @@
|
||||
|
||||
;; START wedge support
|
||||
|
||||
wedge_dos:
|
||||
|
||||
;; Close all the channels, so that wedge has full control
|
||||
jsr via_ICLALL
|
||||
|
||||
;; Set file parameters, channel 15 is a typical one for commands
|
||||
jsr select_device ; sets X register
|
||||
lda #$0F
|
||||
ldy #$0F
|
||||
jsr JSETFLS
|
||||
|
||||
;; Now we have to check what the user wants us to do
|
||||
|
||||
;; Check if user asked for a status
|
||||
ldy #$00
|
||||
lda (basic_current_statement_ptr), y
|
||||
beq wedge_dos_status
|
||||
|
||||
;; Check if asked for a directory
|
||||
cmp #$24
|
||||
beq wedge_dos_directory
|
||||
*
|
||||
;; Check if asked to change drive number, or if it is a regular command
|
||||
cmp #$30
|
||||
bcc wedge_dos_command ; char code before 0
|
||||
cmp #$3A
|
||||
bcs wedge_dos_command ; char code after 9
|
||||
iny
|
||||
lda (basic_current_statement_ptr), y
|
||||
beq wedge_dos_change_drive ; end of buffer
|
||||
cmp #$20
|
||||
beq wedge_dos_change_drive
|
||||
jmp -
|
||||
|
||||
wedge_dos_command:
|
||||
|
||||
;; Provide command name
|
||||
jsr wedge_dos_setnam
|
||||
|
||||
jsr JSETNAM
|
||||
jsr via_IOPEN
|
||||
bcs wedge_dos_basic_error
|
||||
|
||||
;; Retrieve status, print it if not OK
|
||||
jsr via_ICLALL
|
||||
jsr wedge_dos_status_get
|
||||
lda BUF+0
|
||||
cmp #$30 ; '0'
|
||||
bne wedge_dos_status_print
|
||||
lda BUF+1
|
||||
cmp #$30 ; '0'
|
||||
bne wedge_dos_status_print
|
||||
|
||||
;; Clean-up and exit
|
||||
jmp wedge_dos_clean_exit
|
||||
|
||||
wedge_dos_change_drive:
|
||||
|
||||
;; Reuse the line number parser for device number retrieval
|
||||
jsr basic_parse_line_number
|
||||
lda basic_line_number+1
|
||||
beq +
|
||||
jmp do_ILLEGAL_QUANTITY_error
|
||||
*
|
||||
lda basic_line_number+0
|
||||
cmp #$08
|
||||
bpl +
|
||||
bcs +
|
||||
jmp do_ILLEGAL_DEVICE_NUMBER_error
|
||||
*
|
||||
sta current_device_number
|
||||
jmp basic_end_of_line
|
||||
|
||||
wedge_dos_status_get:
|
||||
|
||||
;; Here the flow is mostly the same as in the example from
|
||||
;; https://codebase64.org/doku.php?id=base:reading_the_error_channel_of_a_disk_drive
|
||||
|
||||
;; Set remaining file parameters, open the channel
|
||||
lda #$00 ; empty file name
|
||||
jsr JSETNAM
|
||||
jsr via_IOPEN
|
||||
bcs wedge_dos_basic_error
|
||||
|
||||
;; Set channel for input
|
||||
ldx #$0F
|
||||
jsr via_ICHKIN
|
||||
bcs wedge_dos_basic_error
|
||||
|
||||
ldy #$00
|
||||
*
|
||||
cpy #$50 ; buffer overflow protection
|
||||
beq +
|
||||
jsr JREADST ; retrieve errors
|
||||
;; XXX error in case of status != EOF
|
||||
;; Print out everything retrieved from the drive
|
||||
bne +
|
||||
jsr via_IBASIN
|
||||
bcs wedge_dos_basic_error
|
||||
sta BUF, y
|
||||
iny
|
||||
jmp -
|
||||
*
|
||||
rts
|
||||
|
||||
wedge_dos_status:
|
||||
jsr wedge_dos_status_get
|
||||
;; FALLTROUGH
|
||||
|
||||
wedge_dos_status_print:
|
||||
|
||||
;; Print buffered status
|
||||
ldx #$00
|
||||
*
|
||||
dey
|
||||
bmi +
|
||||
lda BUF, x
|
||||
jsr via_IBSOUT
|
||||
inx
|
||||
bne -
|
||||
*
|
||||
;; Clean-up and exit
|
||||
jmp wedge_dos_clean_exit
|
||||
|
||||
wedge_dos_directory:
|
||||
|
||||
;; First change the secondary address to the one suitable for
|
||||
;; directory loading
|
||||
;; XXX
|
||||
lda #$00 ; logical device number
|
||||
ldx current_device_number
|
||||
ldy #$60
|
||||
jsr JSETFLS
|
||||
|
||||
;; Provide file name
|
||||
jsr wedge_dos_setnam
|
||||
|
||||
;; Open the file
|
||||
jsr via_IOPEN
|
||||
bcs wedge_dos_basic_error
|
||||
|
||||
;; Set channel for file reading
|
||||
ldx #$00
|
||||
jsr via_ICHKIN
|
||||
bcs wedge_dos_basic_error
|
||||
|
||||
;; Ignore start address (2 first bytes) - XXX check for errors
|
||||
jsr via_IBASIN
|
||||
bcs wedge_dos_basic_error
|
||||
jsr via_IBASIN
|
||||
bcs wedge_dos_basic_error
|
||||
|
||||
wedge_dos_directory_line:
|
||||
|
||||
;; Load a single line, reuse BASIC input buffer
|
||||
ldy #$FF
|
||||
*
|
||||
iny
|
||||
jsr via_IBASIN
|
||||
bcs wedge_dos_basic_error
|
||||
sta BUF, y
|
||||
cpy #$50
|
||||
beq + ; line too long, terminate loading file
|
||||
jsr JREADST
|
||||
bne + ; end of file
|
||||
cpy #$04 ; 2 bytes (pointer to next line) + 2 bytes (line number)
|
||||
bcc -
|
||||
lda BUF, y
|
||||
bne -
|
||||
;; End of line, but not end of file
|
||||
beq wedge_dos_directory_display
|
||||
*
|
||||
lda #K_STS_END_OF_FILE
|
||||
sta IOSTATUS ; make sure end of file is marked
|
||||
;; FALLTROUGH
|
||||
|
||||
wedge_dos_directory_display:
|
||||
|
||||
cpy #$05 ; protection against malformed directory
|
||||
bcc wedge_dos_clean_exit
|
||||
|
||||
lda #$00 ; extra protection agains buffer overflow
|
||||
sta BUF, y
|
||||
|
||||
;; Display line
|
||||
ldx #<BUF
|
||||
stx basic_current_line_ptr+0
|
||||
ldx #>BUF
|
||||
stx basic_current_line_ptr+1
|
||||
ldx #basic_current_line_ptr
|
||||
jsr list_single_line
|
||||
|
||||
;; Read & display next line or quit
|
||||
lda IOSTATUS
|
||||
beq wedge_dos_directory_line
|
||||
;; FALLTROUGH
|
||||
|
||||
wedge_dos_clean_exit:
|
||||
jsr via_ICLALL
|
||||
;; Print new line
|
||||
lda #$0D
|
||||
jsr via_IBSOUT
|
||||
jmp basic_end_of_line
|
||||
|
||||
wedge_dos_basic_error:
|
||||
pha
|
||||
jsr via_ICLALL
|
||||
pla
|
||||
tax
|
||||
dex
|
||||
jmp do_basic_error
|
||||
|
||||
wedge_dos_setnam:
|
||||
;; Now determine the length of the 'file' name
|
||||
ldy #$FF
|
||||
*
|
||||
iny
|
||||
lda (basic_current_statement_ptr), y
|
||||
bne -
|
||||
|
||||
;; Set the name to open
|
||||
tya
|
||||
ldx basic_current_statement_ptr+0
|
||||
ldy basic_current_statement_ptr+1
|
||||
jmp JSETNAM
|
||||
|
||||
;; END wedge support
|
||||
+3
-18
@@ -3,27 +3,18 @@
|
||||
; (And only those for now that we feel the need to implement initially)
|
||||
; (https://www.c64-wiki.com/wiki/Zeropage)
|
||||
|
||||
.alias TXTTAB $2B
|
||||
.alias IOSTATUS $90
|
||||
; Keys down clears bits. STOP=bit 7, C= bit 6, SPACE bit 4, CTRL bit 2
|
||||
.alias BUCKYSTATUS $91
|
||||
.alias kernal_load_or_verify_flag $93
|
||||
.alias current_file_num $98
|
||||
.alias input_device_number $99
|
||||
; bit 6 = error messages, bit 7 = control messages
|
||||
.alias kernal_message_control_flags $9d
|
||||
.alias jiffy_clock_24bits $a0
|
||||
.alias input_device_number DFLTN
|
||||
.alias cassette_buffer_bytes_used $A6
|
||||
.alias load_or_scroll_temp_pointer $AC
|
||||
;; We also use the following for temp colour pointer when scrolling
|
||||
.alias load_save_verify_end_address $AE
|
||||
.alias cassette_buffer_ptr $B2
|
||||
.alias current_filename_length $B7
|
||||
.alias current_logical_filenum $B8
|
||||
.alias current_secondary_address $B9
|
||||
.alias current_device_number $BA
|
||||
.alias current_filename_ptr $BB
|
||||
.alias load_save_start_ptr $C1
|
||||
.alias load_save_end_ptr $C3
|
||||
.alias last_key_matrix_position $C5
|
||||
.alias keys_in_key_buffer $C6
|
||||
@@ -50,15 +41,11 @@
|
||||
.alias keyboard_decoding_table_ptr $F5
|
||||
.alias rs232_rx_buffer_ptr $F7
|
||||
.alias rs232_tx_buffer_ptr $F9
|
||||
|
||||
|
||||
|
||||
; "Compute's Mapping the 64" book
|
||||
.alias keyboard_buffer $0277
|
||||
.alias MEMSTR $0281
|
||||
.alias MEMSIZ $0283 ; NOTE: Mapping the 64 erroniously has the hex as $282, while the DEC is correct
|
||||
.alias text_colour $0286 ; p55
|
||||
.alias colour_under_cursor $0287 ; p56
|
||||
.alias HIBASE $0288 ; p56 (high byte of start of screen)
|
||||
.alias key_buffer_size $0289 ; p57
|
||||
|
||||
;; 0 = cursor keys, insert, delete and space repeat, but nothing else
|
||||
@@ -74,7 +61,6 @@
|
||||
.alias keyboard_decoding_ptr $028F
|
||||
.alias enable_case_switch $0291
|
||||
.alias screen_scroll_disable $0292
|
||||
.alias pal_or_ntsc $02A6
|
||||
|
||||
;; Under-ROM routines
|
||||
;; (BASIC also includes them. XXX - We should de-duplicate them in a safe manner)
|
||||
@@ -84,5 +70,4 @@
|
||||
.alias poke_under_roms tiny_nmi_handler+poke_under_roms_routine-tiny_nmi_handler_routine
|
||||
.alias memmap_allram tiny_nmi_handler+memmap_allram_routine-tiny_nmi_handler_routine
|
||||
.alias memmap_normal tiny_nmi_handler+memmap_normal_routine-tiny_nmi_handler_routine
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
|
||||
;; Target-specific hooks
|
||||
|
||||
|
||||
.macro TARGET_HOOK_LOAD
|
||||
.macend
|
||||
@@ -0,0 +1,6 @@
|
||||
|
||||
;; Target-specific hooks
|
||||
|
||||
|
||||
.macro TARGET_HOOK_LOAD
|
||||
.macend
|
||||
@@ -0,0 +1,57 @@
|
||||
|
||||
;; Registers according to Ultimate 64 Command Interface description,
|
||||
;; https://1541u-documentation.readthedocs.io/en/latest/command%20interface.html
|
||||
;; and ultimate_dos_v1.0.pdf and command_interface_v1.0.pdf by Gideon Zweijtzer
|
||||
|
||||
;; Command interface registers
|
||||
.alias U64_CONTROL $DF1C ; write
|
||||
.alias U64_STATUS $DF1C ; read
|
||||
.alias U64_COMMAND_DATA $DF1D ; write
|
||||
.alias U64_IDENTIFICATION $DF1D ; read
|
||||
.alias U64_RESPONSE_DATA $DF1E ; read only
|
||||
.alias U64_STATUS_DATA $DF1F ; read only
|
||||
|
||||
;; Constant for U64_IDENTIFICATION register
|
||||
.alias U64_MAGIC_ID $C9
|
||||
|
||||
;; Constants for U64_CONTROL register
|
||||
.alias U64_CTRL_BIT_PUSH_CMD $01
|
||||
.alias U64_CTRL_BIT_DATA_ACC $02
|
||||
.alias U64_CTRL_BIT_ABORT $04
|
||||
.alias U64_CTRL_BIT_CLR_ERR $08
|
||||
|
||||
;; Constants for U64_STATUS register
|
||||
.alias U64_STAT_BIT_CMD_BUSY $01
|
||||
.alias U64_STAT_BIT_DATA_ACC $02
|
||||
.alias U64_STAT_BIT_ABORT_P $04
|
||||
.alias U64_STAT_BIT_ERROR $08
|
||||
.alias U64_STAT_MASK_STATE $30 ; two bits!
|
||||
.alias U64_STAT_BIT_STAT_AV $40
|
||||
.alias U64_STAT_BIT_DATA_AV $80
|
||||
|
||||
;; Interface targets
|
||||
.alias U64_TARGET_DOS1 $01
|
||||
.alias U64_TARGET_DOS2 $02
|
||||
|
||||
;; DOS command codes
|
||||
.alias U64_DOS_CMD_IDENTIFY $01
|
||||
.alias U64_DOS_CMD_OPEN_FILE $02
|
||||
.alias U64_DOS_CMD_CLOSE_FILE $03
|
||||
.alias U64_DOS_CMD_READ_DATA $04
|
||||
.alias U64_DOS_CMD_WRITE_DATA $05
|
||||
.alias U64_DOS_CMD_FILE_SEEK $06
|
||||
.alias U64_DOS_CMD_FILE_INFO $07
|
||||
.alias U64_DOS_CMD_CHANGE_DIR $11
|
||||
.alias U64_DOS_CMD_GET_PATH $12
|
||||
.alias U64_DOS_CMD_OPEN_DIR $13
|
||||
.alias U64_DOS_CMD_READ_DIR $14
|
||||
.alias U64_DOS_CMD_COPY_UI_PATH $15
|
||||
.alias U64_DOS_CMD_LOAD_REU $21
|
||||
.alias U64_DOS_CMD_SAVE_REU $22
|
||||
.alias U64_DOS_CMD_ECHO $F0
|
||||
|
||||
;; DOS file opening constants
|
||||
.alias U64_FA_READ $01
|
||||
.alias U64_FA_WRITE $02
|
||||
.alias U64_FA_CREATE_NEW $03
|
||||
.alias U64_FA_CREATE_ALWAYS $04
|
||||
@@ -0,0 +1,9 @@
|
||||
|
||||
;; Target-specific hooks
|
||||
|
||||
|
||||
.macro TARGET_HOOK_LOAD
|
||||
;; XXX disabled for now - the current file opening API is not
|
||||
;; really suitable for easy usage from Kernal
|
||||
;; jsr u64_load
|
||||
.macend
|
||||
@@ -0,0 +1,130 @@
|
||||
|
||||
;;
|
||||
;; LOAD routine hook for fast loading via UltiDOS
|
||||
;;
|
||||
|
||||
|
||||
u64_load:
|
||||
|
||||
;; First check whether the command interface is enabled
|
||||
lda U64_IDENTIFICATION
|
||||
cmp #U64_MAGIC_ID
|
||||
beq +
|
||||
|
||||
u64_load_skip:
|
||||
rts
|
||||
*
|
||||
;; XXX find out which device number softIEC is mapped to
|
||||
lda current_device_number
|
||||
cmp #$20 ; for now use device number 32
|
||||
bne u64_load_skip
|
||||
|
||||
;; Takeover the flow completely
|
||||
pla
|
||||
pla
|
||||
|
||||
;; Display SEARCHING FOR + filename
|
||||
jsr lvs_display_searching_for
|
||||
|
||||
;; Whatever the interface was doing - ask to abort it
|
||||
jsr u64_load_abort
|
||||
|
||||
;; Send a command to open the file
|
||||
lda #U64_DOS_CMD_OPEN_FILE
|
||||
jsr u64_load_send_cmd
|
||||
lda #U64_FA_READ
|
||||
jsr u64_load_send_cmd
|
||||
jsr u64_load_send_filename
|
||||
jsr u64_load_finalize_cmd
|
||||
|
||||
;; Check status
|
||||
jsr u64_load_check_status
|
||||
bcs lvs_file_not_found_error
|
||||
|
||||
;; Load first two bytes to determine start address
|
||||
|
||||
;; XXX
|
||||
|
||||
jsr printf
|
||||
.byte "DBG: NOT IMPLEMENTED",$0D,0
|
||||
|
||||
jmp lvs_wrap_around_error
|
||||
rts
|
||||
|
||||
u64_load_abort:
|
||||
lda #U64_CTRL_BIT_ABORT
|
||||
sta U64_CONTROL
|
||||
*
|
||||
lda U64_STATUS
|
||||
bne -
|
||||
rts
|
||||
|
||||
u64_load_send_cmd:
|
||||
|
||||
ldx #U64_TARGET_DOS2
|
||||
stx U64_COMMAND_DATA ; target
|
||||
sta U64_COMMAND_DATA ; command code
|
||||
rts
|
||||
|
||||
u64_load_send_filename:
|
||||
ldy #0
|
||||
u64_load_send_filename_loop:
|
||||
cpy FNLEN
|
||||
bne+
|
||||
rts
|
||||
*
|
||||
ldx #<current_filename_ptr
|
||||
jsr peek_under_roms
|
||||
iny
|
||||
|
||||
sta U64_COMMAND_DATA
|
||||
jmp u64_load_send_filename_loop
|
||||
|
||||
u64_load_finalize_cmd:
|
||||
;; Push the command for execution
|
||||
lda #U64_CTRL_BIT_PUSH_CMD
|
||||
sta U64_CONTROL
|
||||
;; Wait till it is complete
|
||||
*
|
||||
lda U64_STATUS
|
||||
and #U64_STAT_BIT_CMD_BUSY
|
||||
bne -
|
||||
rts
|
||||
|
||||
u64_load_check_status:
|
||||
;; Wait till status is available
|
||||
lda U64_STATUS
|
||||
and #U64_STAT_BIT_STAT_AV
|
||||
beq u64_load_check_status
|
||||
|
||||
;; Status is ready - check the first character
|
||||
lda U64_STATUS_DATA
|
||||
jsr JCHROUT ; XXX for test only
|
||||
cmp #$30 ; '0'
|
||||
bne u64_load_check_status_wrong
|
||||
|
||||
;; Check the second status character
|
||||
lda U64_STATUS
|
||||
and #U64_STAT_BIT_STAT_AV
|
||||
beq u64_load_check_status_ok
|
||||
lda U64_STATUS_DATA
|
||||
jsr JCHROUT ; XXX for test only
|
||||
cmp #$30 ; '0'
|
||||
beq u64_load_check_status_ok
|
||||
|
||||
;; FALLTROUGH
|
||||
u64_load_check_status_wrong:
|
||||
sec
|
||||
bcs +
|
||||
u64_load_check_status_ok:
|
||||
clc
|
||||
*
|
||||
;; Now empty the status queue
|
||||
lda U64_STATUS
|
||||
and #U64_STAT_BIT_STAT_AV
|
||||
beq +
|
||||
lda U64_STATUS_DATA
|
||||
jsr JCHROUT ; XXX for test only
|
||||
jmp -
|
||||
*
|
||||
rts
|
||||
+14
-2
@@ -1,3 +1,15 @@
|
||||
; Function defined on pp272-273 of C64 Programmers Reference Guide
|
||||
|
||||
;;
|
||||
;; Official Kernal routine, described in:
|
||||
;;
|
||||
;; - [RG64] C64 Programmer's Reference Guide - page 274
|
||||
;; - [CM64] Compute's Mapping the Commodore 64 - page 224/225
|
||||
;;
|
||||
;; CPU registers that has to be preserved (see [RG64]): .Y
|
||||
;;
|
||||
|
||||
|
||||
acptr:
|
||||
rts
|
||||
jsr kernalstatus_reset
|
||||
jmp iec_rx_byte
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
; Function defined on pp272-273 of C64 Programmers Reference Guide
|
||||
chkin:
|
||||
rts
|
||||
@@ -0,0 +1,143 @@
|
||||
|
||||
;;
|
||||
;; Official Kernal routines, described in:
|
||||
;;
|
||||
;; - [RG64] C64 Programmer's Reference Guide - page 275 (CHKIN) / 276 (CKOUT)
|
||||
;; - [CM64] Compute's Mapping the Commodore 64 - page 229
|
||||
;;
|
||||
;; CPU registers that has to be preserved (see [RG64]): .Y
|
||||
;;
|
||||
|
||||
|
||||
;; CHKIN implementation
|
||||
|
||||
chkin:
|
||||
|
||||
;; Store Y for preservation
|
||||
tya
|
||||
pha
|
||||
|
||||
;; Reset status
|
||||
jsr kernalstatus_reset
|
||||
|
||||
;; First retrieve the FAT/LAT/SAT table index (and check if file is open)
|
||||
|
||||
txa
|
||||
jsr find_fls
|
||||
bcs chkinout_file_not_open
|
||||
|
||||
;; Now we have table index in Y - first filter out unsuitable devices
|
||||
|
||||
lda FAT,Y
|
||||
cmp #$01
|
||||
beq chkinout_device_not_present ; tape not implemented
|
||||
cmp #$02
|
||||
beq chkinout_device_not_present ; RS-232 not implemented
|
||||
|
||||
;; Fail if the file is open for writing (secondary address 1)
|
||||
|
||||
lda LAT, Y
|
||||
cmp #$01
|
||||
beq chkinout_file_not_input
|
||||
|
||||
;; For IEC devices, send TALK + TKSA first
|
||||
lda FAT,Y
|
||||
jsr iec_check_devnum
|
||||
bcs chkin_set_device
|
||||
|
||||
jsr talk
|
||||
bcs chkinout_device_not_present ; don't set DFLTN in case of failure
|
||||
|
||||
lda LAT, Y
|
||||
jsr tksa
|
||||
bcs chkinout_device_not_present
|
||||
|
||||
chkin_set_device:
|
||||
lda FAT,Y
|
||||
sta DFLTN
|
||||
clc ; for success
|
||||
;; FALLTROUGH
|
||||
|
||||
;; Common part for booth CHKIN and CKOUT
|
||||
|
||||
chkinout_end:
|
||||
tax
|
||||
pla
|
||||
tay
|
||||
txa
|
||||
rts
|
||||
|
||||
chkinout_file_not_open:
|
||||
pla
|
||||
tay
|
||||
jmp kernalerror_FILE_NOT_OPEN
|
||||
|
||||
chkinout_device_not_present:
|
||||
pla
|
||||
tay
|
||||
jsr kernalstatus_DEVICE_NOT_FOUND
|
||||
jmp kernalerror_DEVICE_NOT_FOUND
|
||||
|
||||
chkinout_file_not_input:
|
||||
pla
|
||||
tay
|
||||
jmp kernalerror_FILE_NOT_INPUT
|
||||
|
||||
chkinout_file_not_output:
|
||||
pla
|
||||
tay
|
||||
jmp kernalerror_FILE_NOT_OUTPUT
|
||||
|
||||
chkinout_common:
|
||||
|
||||
;; CKOUT implementation
|
||||
|
||||
ckout:
|
||||
|
||||
;; Store Y for preservation
|
||||
tya
|
||||
pha
|
||||
|
||||
;; Reset status
|
||||
jsr kernalstatus_reset
|
||||
|
||||
;; First retrieve the FAT/LAT/SAT table index (and check if file is open)
|
||||
|
||||
txa
|
||||
jsr find_fls
|
||||
bcs chkinout_file_not_open
|
||||
|
||||
;; Now we have table index in Y - first filter out unsuitable devices
|
||||
|
||||
lda FAT,Y
|
||||
cmp #$01
|
||||
beq chkinout_device_not_present ; tape not implemented
|
||||
cmp #$02
|
||||
beq chkinout_device_not_present ; RS-232 not implemented
|
||||
|
||||
cmp #$00
|
||||
beq chkinout_file_not_output ; cannot output to keyboard - XXX check real ROM behaviour
|
||||
|
||||
;; Fail if the file is open for reading (secondary address 0)
|
||||
|
||||
lda LAT, Y
|
||||
beq chkinout_file_not_output
|
||||
|
||||
;; For IEC devices, send LISTEN + SECOND first
|
||||
lda FAT,Y
|
||||
jsr iec_check_devnum
|
||||
bcs chkout_set_device
|
||||
|
||||
jsr listen
|
||||
bcs chkinout_device_not_present ; don't set DFLTO in case of failure
|
||||
|
||||
lda LAT, Y
|
||||
jsr second
|
||||
bcs chkinout_device_not_present
|
||||
|
||||
chkout_set_device:
|
||||
lda FAT,Y
|
||||
sta DFLTO
|
||||
clc ; for success
|
||||
|
||||
jmp chkinout_end
|
||||
@@ -1,3 +0,0 @@
|
||||
; Function defined on pp272-273 of C64 Programmers Reference Guide
|
||||
chkout:
|
||||
rts
|
||||
+48
-9
@@ -1,14 +1,53 @@
|
||||
; Function defined on pp272-273 of C64 Programmers Reference Guide
|
||||
;; Compute's Mapping the 64, p228
|
||||
;; Reads a byte of input, unless from keyboard.
|
||||
;; If from keyboard, then it gets a whole line of input, and returns the first char.
|
||||
;; Repeated calls after that read out the successive bytes of the line of input.
|
||||
|
||||
;;
|
||||
;; Official Kernal routine, described in:
|
||||
;;
|
||||
;; - [RG64] C64 Programmer's Reference Guide - page 277/278
|
||||
;; - [CM64] Compute's Mapping the Commodore 64 - page 228
|
||||
;;
|
||||
;; CPU registers that has to be preserved (see [RG64]): .Y
|
||||
;;
|
||||
|
||||
;; XXX keyboard part currently does not preserve register Y, to be fixed!
|
||||
|
||||
;; Reads a byte of input, unless from keyboard.
|
||||
;; If from keyboard, then it gets a whole line of input, and returns the first char.
|
||||
;; Repeated calls after that read out the successive bytes of the line of input.
|
||||
|
||||
chrin:
|
||||
|
||||
;; Determine the device number
|
||||
lda DFLTN
|
||||
|
||||
beq chrin_keyboard ; #$00 - keyboard
|
||||
;; XXX add screen support
|
||||
|
||||
jsr iec_check_devnum
|
||||
bcc chrin_iec
|
||||
jmp lvs_device_not_found_error ; not a supported device
|
||||
|
||||
chrin_iec:
|
||||
|
||||
jsr JACPTR
|
||||
bcs chrin_done_fail
|
||||
;; FALLTROUGH
|
||||
|
||||
chrin_done:
|
||||
clc ; indicate success
|
||||
rts
|
||||
|
||||
chrin_done_fail:
|
||||
sec ; indicate failure
|
||||
rts
|
||||
|
||||
chrin_keyboard:
|
||||
|
||||
;; Save X
|
||||
txa
|
||||
pha
|
||||
|
||||
chrin_repeat:
|
||||
chrin_repeat:
|
||||
|
||||
;; Do we have a line of input we are currently returning?
|
||||
;; If so, return the next byte, and clear the flag when we reach the end.
|
||||
|
||||
@@ -165,7 +204,7 @@ not_shifted:
|
||||
clc
|
||||
adc #$40
|
||||
|
||||
;; FALLTROUGH
|
||||
not_vendor:
|
||||
rts
|
||||
not_vendor:
|
||||
|
||||
rts
|
||||
|
||||
+81
-22
@@ -1,24 +1,96 @@
|
||||
; Function defined on pp272-273 of C64 Programmers Reference Guide
|
||||
|
||||
;;
|
||||
;; Official Kernal routine, described in:
|
||||
;;
|
||||
;; - [RG64] C64 Programmer's Reference Guide - page 278/279
|
||||
;; - [CM64] Compute's Mapping the Commodore 64 - page 228
|
||||
;;
|
||||
;; CPU registers that has to be preserved (see [RG64]): .Y
|
||||
;;
|
||||
|
||||
|
||||
chrout:
|
||||
;; Crude implementation of character output
|
||||
|
||||
sta last_printed_character_ascii
|
||||
|
||||
;; Save X and Y values
|
||||
;; (Confirmed by writing a test program that X and Y
|
||||
;; don't get modified, in agreement with C64 PRG's
|
||||
;; description of CHROUT)
|
||||
sta last_printed_character_ascii
|
||||
txa
|
||||
pha
|
||||
tya
|
||||
pha
|
||||
php
|
||||
sei
|
||||
|
||||
|
||||
;; Determine the device number
|
||||
lda DFLTO
|
||||
|
||||
cmp #$03 ; screen
|
||||
beq chrout_screen
|
||||
|
||||
jsr iec_check_devnum
|
||||
bcs chrout_done_unknown_device ; not a supported device
|
||||
|
||||
chrout_iec:
|
||||
|
||||
lda last_printed_character_ascii
|
||||
jsr JCIOUT
|
||||
bcc chrout_done
|
||||
|
||||
;; FALLTROUGH
|
||||
|
||||
chrout_done_fail:
|
||||
jsr show_cursor_if_enabled
|
||||
|
||||
plp
|
||||
|
||||
;; Restore X and Y
|
||||
pla
|
||||
tay
|
||||
pla
|
||||
tax
|
||||
sec ; indicate failure
|
||||
rts
|
||||
|
||||
chrout_done_unknown_device:
|
||||
jsr show_cursor_if_enabled
|
||||
|
||||
plp
|
||||
|
||||
;; Restore X and Y
|
||||
pla
|
||||
tay
|
||||
pla
|
||||
tax
|
||||
|
||||
;; End wioth error
|
||||
jmp lvs_device_not_found_error
|
||||
|
||||
chrout_done:
|
||||
jsr show_cursor_if_enabled
|
||||
|
||||
plp
|
||||
|
||||
;; Restore X and Y
|
||||
pla
|
||||
tay
|
||||
pla
|
||||
tax
|
||||
lda last_printed_character_ascii
|
||||
clc ; indicate success
|
||||
rts
|
||||
|
||||
chrout_screen:
|
||||
|
||||
;; Crude implementation of character output
|
||||
sei ;; XXX why do we need to disable interrupts?
|
||||
|
||||
jsr hide_cursor_if_visible
|
||||
|
||||
|
||||
lda last_printed_character_ascii
|
||||
tax
|
||||
|
||||
|
||||
;; Check for special characters
|
||||
|
||||
cmp #$00
|
||||
@@ -32,7 +104,7 @@ not_00:
|
||||
bne not_0a
|
||||
jmp chrout_done
|
||||
not_0a:
|
||||
|
||||
|
||||
;; Carriage return
|
||||
cmp #$0d
|
||||
bne not_0d
|
||||
@@ -370,20 +442,7 @@ not_quote:
|
||||
sta current_screen_x
|
||||
jmp screen_advance_to_next_line
|
||||
no_screen_advance_to_next_line:
|
||||
|
||||
chrout_done:
|
||||
jsr show_cursor_if_enabled
|
||||
|
||||
plp
|
||||
|
||||
;; Restore X and Y, set carry to mark success on exit
|
||||
pla
|
||||
tay
|
||||
pla
|
||||
tax
|
||||
lda last_printed_character_ascii
|
||||
clc ; indicate success
|
||||
rts
|
||||
jmp chrout_done
|
||||
|
||||
screen_grow_logical_line:
|
||||
ldy current_screen_y
|
||||
|
||||
+14
-2
@@ -1,5 +1,14 @@
|
||||
;; Function defined on pp272-273 of C64 Programmers Reference Guide
|
||||
;; Compute's Mapping the 64 p215
|
||||
|
||||
;;
|
||||
;; Official Kernal routine, described in:
|
||||
;;
|
||||
;; - [RG64] C64 Programmer's Reference Guide - page 280
|
||||
;; - [CM64] Compute's Mapping the Commodore 64 - page 242
|
||||
;;
|
||||
;; CPU registers that has to be preserved (see [RG64]): none
|
||||
;;
|
||||
|
||||
|
||||
cint:
|
||||
jsr setup_vicii
|
||||
|
||||
@@ -34,6 +43,9 @@ cint:
|
||||
;; Put non-zero value in enable_case_switch
|
||||
stx enable_case_switch
|
||||
|
||||
;; Set default I/O devices (see SCINIT description at http://sta.c64.org/cbm64krnfunc.html)
|
||||
jsr clrchn_reset
|
||||
|
||||
;; Fallthrough/jump to screen clear routine (Compute's Mapping the 64 p215)
|
||||
jmp clear_screen
|
||||
|
||||
|
||||
+35
-1
@@ -1,3 +1,37 @@
|
||||
; Function defined on pp272-273 of C64 Programmers Reference Guide
|
||||
|
||||
;;
|
||||
;; Official Kernal routine, described in:
|
||||
;;
|
||||
;; - [RG64] C64 Programmer's Reference Guide - page 279/280
|
||||
;; - [CM64] Compute's Mapping the Commodore 64 - page 224
|
||||
;;
|
||||
;; CPU registers that has to be preserved (see [RG64]): .X, .Y
|
||||
;;
|
||||
|
||||
|
||||
ciout:
|
||||
|
||||
pha
|
||||
lda C3PO
|
||||
bne ciout_send_byte
|
||||
|
||||
;; Nothing to send - set buffer as valid, store byte there
|
||||
inc C3PO
|
||||
|
||||
;; Clear carry flag to indicate success
|
||||
clc
|
||||
|
||||
ciout_store_in_buffer:
|
||||
|
||||
;; Store in the buffer data to be sent next, return
|
||||
pla
|
||||
sta BSOUR
|
||||
rts
|
||||
|
||||
ciout_send_byte:
|
||||
|
||||
clc ; don't send with EOI
|
||||
jsr iec_tx_byte
|
||||
inc C3PO ; iec_tx_byte sets it to 0, but we still have something to send
|
||||
jmp ciout_store_in_buffer
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
|
||||
;;
|
||||
;; Official Kernal routine, described in:
|
||||
;;
|
||||
;; - [RG64] C64 Programmer's Reference Guide - page 281
|
||||
;; - [CM64] Compute's Mapping the Commodore 64 - page 230
|
||||
;;
|
||||
;; CPU registers that has to be preserved (see [RG64]): .Y
|
||||
;;
|
||||
|
||||
|
||||
clall:
|
||||
|
||||
;; Store .Y register
|
||||
tya
|
||||
pha
|
||||
|
||||
;; Original routine probably just sets LDTND to 0, but this is not really safe,
|
||||
;; so we actually close all the channels; at least IDE64 does the same for
|
||||
;; it's channels, see CLALL description in the IDE64 User's Guide
|
||||
*
|
||||
ldy LDTND
|
||||
beq +
|
||||
dey
|
||||
lda LAT, y
|
||||
jsr close ; XXX jump through ICLOSE?
|
||||
jmp -
|
||||
*
|
||||
;; Restore .Y register
|
||||
pla
|
||||
tay
|
||||
|
||||
;; 'C64 Programmers Reference Guide', page 281, claims it calls CLRCHN too
|
||||
jsr clrchn
|
||||
|
||||
;; Not sure whether original Kernal does so, but it seems sane to also clear possible errors
|
||||
jmp kernalstatus_reset
|
||||
|
||||
+57
-1
@@ -1,3 +1,59 @@
|
||||
; Function defined on pp272-273 of C64 Programmers Reference Guide
|
||||
|
||||
;;
|
||||
;; Official Kernal routine, described in:
|
||||
;;
|
||||
;; - [RG64] C64 Programmer's Reference Guide - page 281/282
|
||||
;; - [CM64] Compute's Mapping the Commodore 64 - page 229/230
|
||||
;; - https://www.pagetable.com/?p=1031, https://github.com/mist64/cbmbus_doc (IEC command)
|
||||
;;
|
||||
;; CPU registers that has to be preserved (see [RG64]): none
|
||||
;;
|
||||
|
||||
close:
|
||||
|
||||
;; XXX this needs more testing (opening 10 files at once, closing in various orders, etc) once the code is more mature
|
||||
|
||||
;; Find the LAT / SAT / FAT entry which LAT corresponds to A
|
||||
|
||||
jsr find_fls
|
||||
bcs close_error_not_found ;; XXX can we report error in IOSTATUS here?
|
||||
|
||||
;; We have the entry index in Y - check whether this is IEC device
|
||||
lda FAT, y
|
||||
jsr iec_check_devnum
|
||||
bcs close_remove_from_table
|
||||
|
||||
;; IEC device
|
||||
|
||||
jsr iec_tx_flush ; make sure no byte is awaiting
|
||||
*
|
||||
lda SAT, y ; get secondary address
|
||||
ora $E0 ; CLOSE command
|
||||
sta IEC_TMP2
|
||||
jsr iec_tx_command
|
||||
bcs close_remove_from_table
|
||||
jsr iec_tx_command_finalize
|
||||
|
||||
close_remove_from_table:
|
||||
;; Remove channel from the table
|
||||
iny
|
||||
cpy #$0A
|
||||
bpl +
|
||||
lda LAT, y
|
||||
sta LAT-1, y
|
||||
lda FAT, y
|
||||
sta FAT-1, y
|
||||
lda SAT, y
|
||||
sta SAT-1, y
|
||||
jmp close_remove_from_table
|
||||
*
|
||||
;; Decrement the list size variable
|
||||
dec LDTND
|
||||
|
||||
clc ; report success - not sure if original CLOSE does this, but it's nevertheless a good practice
|
||||
rts
|
||||
|
||||
close_error_not_found:
|
||||
|
||||
sec ; report success - not sure if original CLOSE does this, but it's nevertheless a good practice
|
||||
rts
|
||||
@@ -1,2 +0,0 @@
|
||||
close_all_files:
|
||||
rts
|
||||
+34
-1
@@ -1,3 +1,36 @@
|
||||
; Function defined on pp272-273 of C64 Programmers Reference Guide
|
||||
|
||||
;;
|
||||
;; Official Kernal routine, described in:
|
||||
;;
|
||||
;; - [RG64] C64 Programmer's Reference Guide - page 282
|
||||
;; - [CM64] Compute's Mapping the Commodore 64 - page 230
|
||||
;;
|
||||
;; CPU registers that has to be preserved (see [RG64]): .Y
|
||||
;;
|
||||
|
||||
|
||||
clrchn:
|
||||
|
||||
;; Handle IEC input device
|
||||
lda DFLTN
|
||||
jsr iec_check_devnum
|
||||
bcs +
|
||||
;; Previous device was IEC one - send UNTALK first
|
||||
jsr untlk
|
||||
*
|
||||
;; Restore output device to default
|
||||
lda DFLTO
|
||||
jsr iec_check_devnum
|
||||
bcs +
|
||||
;; Handle IEC output device
|
||||
jsr unlsn
|
||||
*
|
||||
clrchn_reset: ;; entry needed by CHRIN
|
||||
;; Set input device number to keyboard
|
||||
lda #$00
|
||||
sta DFLTN
|
||||
;; Set output device number to screen
|
||||
lda #$03
|
||||
sta DFLTO
|
||||
|
||||
rts
|
||||
+84
-2
@@ -1,6 +1,88 @@
|
||||
|
||||
;; Kernal error codes are described in 'Commodore 64 Programmer's Reference Guide', page 306
|
||||
|
||||
kernalerror_DEVICE_NOT_FOUND:
|
||||
lda #$05
|
||||
kernalerror_ROUTINE_TERMINATED: ; by a STOP key
|
||||
lda #K_ERR_ROUTINE_TERMINATED
|
||||
sec
|
||||
rts
|
||||
|
||||
kernalerror_TOO_MANY_OPEN_FILES:
|
||||
lda #K_ERR_TOO_MANY_OPEN_FILES
|
||||
sec
|
||||
rts
|
||||
|
||||
kernalerror_FILE_ALREADY_OPEN:
|
||||
lda #K_ERR_FILE_ALREADY_OPEN
|
||||
sec
|
||||
rts
|
||||
|
||||
kernalerror_FILE_NOT_OPEN:
|
||||
lda #K_ERR_FILE_NOT_OPEN
|
||||
sec
|
||||
rts
|
||||
|
||||
kernalerror_FILE_NOT_FOUND:
|
||||
lda #K_ERR_FILE_NOT_FOUND
|
||||
sec
|
||||
rts
|
||||
|
||||
kernalerror_DEVICE_NOT_FOUND:
|
||||
lda #K_ERR_DEVICE_NOT_FOUND
|
||||
sec
|
||||
rts
|
||||
|
||||
kernalerror_FILE_NOT_INPUT:
|
||||
lda #K_ERR_FILE_NOT_INPUT
|
||||
sec
|
||||
rts
|
||||
|
||||
kernalerror_FILE_NOT_OUTPUT:
|
||||
lda #K_ERR_FILE_NOT_OUTPUT
|
||||
sec
|
||||
rts
|
||||
|
||||
kernalerror_FILE_NAME_MISSING:
|
||||
lda #K_ERR_FILE_NAME_MISSING
|
||||
sec
|
||||
rts
|
||||
|
||||
kernalerror_ILLEGAL_DEVICE_NUMBER:
|
||||
lda #K_ERR_ILLEGAL_DEVICE_NUMBER
|
||||
sec
|
||||
rts
|
||||
|
||||
kernalerror_TOP_MEM_RS232:
|
||||
lda #K_ERR_TOP_MEM_RS232
|
||||
sec
|
||||
rts
|
||||
|
||||
;; Kernal status codes are described in 'Commodore 64 Programmer's Reference Guide', page 292
|
||||
|
||||
kernalstatus_reset:
|
||||
lda #$00
|
||||
sta IOSTATUS
|
||||
rts
|
||||
|
||||
kernalstatus_TIMEOUT_WRITE: ;; XXX detect this!
|
||||
lda IOSTATUS
|
||||
ora #K_STS_TIMEOUT_WRITE
|
||||
sta IOSTATUS
|
||||
rts
|
||||
|
||||
kernalstatus_TIMEOUT_READ: ;; XXX detect this!
|
||||
lda IOSTATUS
|
||||
ora #K_STS_TIMEOUT_READ
|
||||
sta IOSTATUS
|
||||
rts
|
||||
|
||||
kernalstatus_EOI:
|
||||
lda IOSTATUS
|
||||
ora #K_STS_EOI
|
||||
sta IOSTATUS
|
||||
rts
|
||||
|
||||
kernalstatus_DEVICE_NOT_FOUND:
|
||||
lda IOSTATUS
|
||||
ora #K_STS_DEVICE_NOT_FOUND
|
||||
sta IOSTATUS
|
||||
rts
|
||||
@@ -1,4 +1,13 @@
|
||||
; Function defined on pp272-273 of C64 Programmers Reference Guide
|
||||
|
||||
;;
|
||||
;; Official Kernal routine, described in:
|
||||
;;
|
||||
;; - [RG64] C64 Programmer's Reference Guide - page 285
|
||||
;; - [CM64] Compute's Mapping the Commodore 64 - page 238
|
||||
;;
|
||||
;; CPU registers that has to be preserved (see [RG64]): none
|
||||
;;
|
||||
|
||||
ioinit:
|
||||
|
||||
; Set $00/$01 port mode and value
|
||||
@@ -39,4 +48,7 @@ ioinit:
|
||||
lda #$3b
|
||||
sta $dd02
|
||||
|
||||
;; Set IEC bus oto its initial idle state
|
||||
jsr iec_set_idle
|
||||
|
||||
rts
|
||||
@@ -1,9 +0,0 @@
|
||||
; $FFF3 - Get page of IO devices
|
||||
; Returns Y=$DC, X=$00
|
||||
; (http://codebase64.org/doku.php?id=base:kernalreference)
|
||||
;
|
||||
; As there is nothing between here and $FFFA, we can just hard code this in place.
|
||||
LDY #$DC
|
||||
LDX #$00
|
||||
RTS
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
|
||||
;; Just a helper routines
|
||||
|
||||
;; Find the LAT / SAT / FAT entry index where LAT corresponds to A, returns index in Y
|
||||
;; Carry flag set means not found
|
||||
|
||||
find_fls:
|
||||
|
||||
ldy LDTND
|
||||
beq find_fls_not_found ; table empty
|
||||
*
|
||||
dey
|
||||
bmi find_fls_not_found ; no more entries
|
||||
cmp LAT, y
|
||||
bne - ; does not match, try the next one
|
||||
|
||||
clc
|
||||
rts
|
||||
|
||||
find_fls_not_found:
|
||||
|
||||
sec
|
||||
rts
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
get_screen_size:
|
||||
rts
|
||||
+12
-1
@@ -1,4 +1,15 @@
|
||||
; Function defined on pp272-273 of C64 Programmers Reference Guide
|
||||
|
||||
;;
|
||||
;; Official Kernal routine, described in:
|
||||
;;
|
||||
;; - [RG64] C64 Programmer's Reference Guide - page 283
|
||||
;; - [CM64] Compute's Mapping the Commodore 64 - page 227/228
|
||||
;;
|
||||
;; CPU registers that has to be preserved (see [RG64]): .X, .Y
|
||||
;;
|
||||
|
||||
;; XXX currently does not preserve registers, to be fixed!
|
||||
|
||||
getin:
|
||||
|
||||
;; Wait for a key
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
|
||||
;;
|
||||
;; Checks whether device number (in .A) is a correct IEC device number
|
||||
;;
|
||||
;; Preserves .A, .X and .Y
|
||||
;;
|
||||
|
||||
iec_check_devnum:
|
||||
;; 0, 1, 2, or 3 are illegal - reserved for non-IEC devices on Commodore
|
||||
cmp #$04
|
||||
bcs +
|
||||
;; FALLTROUGH
|
||||
iec_check_devnum_failed:
|
||||
sec ; indicate non-IEC device
|
||||
rts
|
||||
*
|
||||
;; 31 and above are illegal too, due to IEC command encoding scheme,
|
||||
;; see https://www.pagetable.com/?p=1031
|
||||
cmp #$1F
|
||||
bcs iec_check_devnum_failed
|
||||
;; Carry is clear here - indicates IEC device
|
||||
rts
|
||||
@@ -0,0 +1,16 @@
|
||||
|
||||
;;
|
||||
;; Kernal internal IEC routine
|
||||
;;
|
||||
;; - https://www.pagetable.com/?p=1031, https://github.com/mist64/cbmbus_doc
|
||||
;;
|
||||
|
||||
iec_cmd_close:
|
||||
|
||||
jsr iec_check_channel_openclose
|
||||
bcc +
|
||||
jmp kernalerror_FILE_NOT_INPUT
|
||||
*
|
||||
ora #$E0
|
||||
|
||||
jmp common_open_close_unlsn_second
|
||||
@@ -0,0 +1,42 @@
|
||||
|
||||
;;
|
||||
;; Kernal internal IEC routine
|
||||
;;
|
||||
;; - https://www.pagetable.com/?p=1031, https://github.com/mist64/cbmbus_doc
|
||||
;;
|
||||
|
||||
|
||||
iec_cmd_open: ; similar to TKSA, but without turnaround
|
||||
|
||||
jsr iec_check_channel_openclose
|
||||
bcc +
|
||||
jmp kernalerror_FILE_NOT_INPUT
|
||||
*
|
||||
ora #$F0
|
||||
|
||||
;; FALLTROUGH
|
||||
|
||||
common_open_close_unlsn_second: ; common part of several commands
|
||||
|
||||
sta IEC_TMP2
|
||||
jsr iec_tx_command
|
||||
bcs + ; branch if error
|
||||
jmp iec_tx_command_finalize
|
||||
*
|
||||
rts
|
||||
|
||||
iec_check_channel_openclose:
|
||||
;; Due to OPEN/CLOSE/TKSA/SECOND command encoding (see https://www.pagetable.com/?p=1031),
|
||||
;; allowed channels are 0-15; report error if out of range
|
||||
cmp #$10
|
||||
bcc +
|
||||
;; Workaround to allow reading executable files and disk directory
|
||||
;; using OPEN routine - see https://www.pagetable.com/?p=273 for
|
||||
;; example usage
|
||||
cmp #$60
|
||||
beq +
|
||||
sec ; mark unsuitable channel number
|
||||
rts
|
||||
*
|
||||
clc ; mark suitable channel number
|
||||
rts
|
||||
@@ -0,0 +1,15 @@
|
||||
|
||||
iec_pull_atn_clk_release_data:
|
||||
|
||||
;; Pulled CLK = DATA considered invalid; for extra robustness on non-emulated
|
||||
;; hardware give some lines few more cycles to stabilize; see page 10 of
|
||||
;; http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf
|
||||
|
||||
lda CIA2_PRA
|
||||
ora #BIT_CIA2_PRA_ATN_OUT ; pull
|
||||
sta CIA2_PRA
|
||||
ora #BIT_CIA2_PRA_CLK_OUT ; pull
|
||||
sta CIA2_PRA
|
||||
and #$FF - BIT_CIA2_PRA_DAT_OUT ; release
|
||||
sta CIA2_PRA
|
||||
rts
|
||||
@@ -0,0 +1,13 @@
|
||||
|
||||
iec_pull_clk_release_data:
|
||||
|
||||
;; Pulled CLK = DATA considered invalid; for extra robustness on non-emulated
|
||||
;; hardware give some lines few more cycles to stabilize; see page 10 of
|
||||
;; http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf
|
||||
|
||||
lda CIA2_PRA
|
||||
ora #BIT_CIA2_PRA_CLK_OUT ; pull
|
||||
sta CIA2_PRA
|
||||
and #$FF - BIT_CIA2_PRA_DAT_OUT ; release
|
||||
sta CIA2_PRA
|
||||
rts
|
||||
@@ -0,0 +1,15 @@
|
||||
|
||||
iec_pull_data_release_atn_clk:
|
||||
|
||||
;; Released CLK = DATA considered valid; for extra robustness on non-emulated
|
||||
;; hardware give some lines few more cycles to stabilize; see page 10 of
|
||||
;; http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf
|
||||
|
||||
lda CIA2_PRA
|
||||
ora #BIT_CIA2_PRA_DAT_OUT ; pull
|
||||
sta CIA2_PRA
|
||||
and #$FF - BIT_CIA2_PRA_CLK_OUT ; release
|
||||
sta CIA2_PRA
|
||||
and #$FF - BIT_CIA2_PRA_ATN_OUT ; release
|
||||
sta CIA2_PRA
|
||||
rts
|
||||
@@ -0,0 +1,8 @@
|
||||
|
||||
iec_release_atn:
|
||||
|
||||
lda CIA2_PRA
|
||||
and #$FF - BIT_CIA2_PRA_ATN_OUT ; release
|
||||
sta CIA2_PRA
|
||||
rts
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
|
||||
iec_release_atn_clk_data:
|
||||
|
||||
;; Released CLK = DATA considered valid; for extra robustness on non-emulated
|
||||
;; hardware give some lines few more cycles to stabilize; see page 10 of
|
||||
;; http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf
|
||||
|
||||
lda CIA2_PRA
|
||||
and #$FF - BIT_CIA2_PRA_ATN_OUT ; release
|
||||
sta CIA2_PRA
|
||||
and #$FF - BIT_CIA2_PRA_DAT_OUT ; release
|
||||
sta CIA2_PRA
|
||||
and #$FF - BIT_CIA2_PRA_CLK_OUT ; release
|
||||
sta CIA2_PRA
|
||||
rts
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
|
||||
iec_release_clk_data:
|
||||
|
||||
;; Released CLK = DATA considered valid; for extra robustness on non-emulated
|
||||
;; hardware give some lines few more cycles to stabilize; see page 10 of
|
||||
;; http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf
|
||||
|
||||
lda CIA2_PRA
|
||||
and #$FF - BIT_CIA2_PRA_DAT_OUT ; release
|
||||
sta CIA2_PRA
|
||||
and #$FF - BIT_CIA2_PRA_CLK_OUT ; release
|
||||
sta CIA2_PRA
|
||||
rts
|
||||
@@ -0,0 +1,13 @@
|
||||
|
||||
iec_release_clk_pull_data:
|
||||
|
||||
;; Released CLK = DATA considered valid; for extra robustness on non-emulated
|
||||
;; hardware give some lines few more cycles to stabilize; see page 10 of
|
||||
;; http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf
|
||||
|
||||
lda CIA2_PRA
|
||||
ora #BIT_CIA2_PRA_DAT_OUT ; pull
|
||||
sta CIA2_PRA
|
||||
and #$FF - BIT_CIA2_PRA_CLK_OUT ; release
|
||||
sta CIA2_PRA
|
||||
rts
|
||||
@@ -0,0 +1,38 @@
|
||||
|
||||
;;
|
||||
;; Helper routines to return with error/success
|
||||
;;
|
||||
;; All of them restore X/Y registers from stack,
|
||||
;; they take care about Carry flag,
|
||||
;; error return reeset IEC line to default state,
|
||||
;; take care about .A and IOSTATUS
|
||||
;;
|
||||
|
||||
iec_return_success:
|
||||
|
||||
;; BSOUR is certainly not valid anymore
|
||||
lda #$00
|
||||
sta C3PO
|
||||
;; Restore registers
|
||||
pla
|
||||
tay
|
||||
pla
|
||||
tax
|
||||
;; Report success
|
||||
clc
|
||||
rts
|
||||
|
||||
iec_return_DEVICE_NOT_FOUND:
|
||||
|
||||
;; Set IEC line to normal idle state
|
||||
jsr iec_set_idle
|
||||
;; BSOUR is certainly not valid anymore
|
||||
lda #$00
|
||||
sta C3PO
|
||||
;; Restore registers
|
||||
pla
|
||||
tay
|
||||
pla
|
||||
tax
|
||||
;; Report error
|
||||
jmp kernalerror_DEVICE_NOT_FOUND
|
||||
@@ -0,0 +1,147 @@
|
||||
;; Receive a byte from the IEC bus.
|
||||
;; Implemented based on https://www.pagetable.com/?p=1135, https://github.com/mist64/cbmbus_doc,
|
||||
;; http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf (page 11)
|
||||
;;
|
||||
;; Preserves .X and .Y registers
|
||||
|
||||
iec_rx_byte:
|
||||
|
||||
;; Store .X and .Y on the stack - preserve them
|
||||
txa
|
||||
pha
|
||||
tya
|
||||
pha
|
||||
|
||||
;; Timing is critical here - execute on disabled IRQs
|
||||
php
|
||||
sei
|
||||
|
||||
;; First, we wait for the talker to release the CLK line
|
||||
jsr iec_wait_for_clk_release
|
||||
|
||||
;; We then release the DATA to signal we are ready
|
||||
;; We can use this routine, since we weren't pulling CLK anyway
|
||||
jsr iec_release_clk_data
|
||||
|
||||
;; Wait till data line is released (someone else might be holding it)
|
||||
jsr iec_wait_for_data_release
|
||||
|
||||
;; Wait for talker to pull CLK.
|
||||
;; If over 200 usec (205 cycles on NTSC machine) , then it is EOI.
|
||||
;; Loop iteraction takes 13 cycles, 17 full iterations are enough
|
||||
|
||||
ldx #$11 ; 2 cycles
|
||||
iec_rx_clk_wait1:
|
||||
lda CIA2_PRA ; 4 cycles
|
||||
rol ; 2 cycles, to put CLK in as the last bit
|
||||
bpl iec_rx_not_eoi ; 2 cycles if not jumped
|
||||
dex ; 2 cycles
|
||||
bne iec_rx_clk_wait1 ; 3 cycles if jumped
|
||||
|
||||
;; Timeout - either this is the last byte of stream, or the stream is empty at all.
|
||||
;; Mark end of stream in IOSTATUS
|
||||
jsr kernalstatus_EOI
|
||||
|
||||
iec_rx_not_empty:
|
||||
|
||||
;; Pull data for 60 usec to confirm it
|
||||
jsr iec_release_clk_pull_data
|
||||
jsr iec_wait60us
|
||||
jsr iec_release_clk_data
|
||||
|
||||
iec_rx_not_eoi:
|
||||
|
||||
;; Latch input bits in on rising edge of CLK, eight times for eight bits.
|
||||
ldx #7
|
||||
|
||||
;; Get empty byte to load into.
|
||||
lda #$00
|
||||
pha
|
||||
|
||||
iec_rx_bit_loop:
|
||||
|
||||
;; Wait for CLK to release
|
||||
jsr iec_wait_for_clk_release
|
||||
|
||||
;; (we do this implicitly below, with a tighter routine,
|
||||
;; so that we don't have timing problems, as the requirements
|
||||
;; are quite tight. Basically we need to read the clock and data
|
||||
;; bit from the same byte read.
|
||||
|
||||
;; DATA now has the next bit, but inverted (well, except that it turns out not to be).
|
||||
;; DATA is in bit 7, which is a bit annoying.
|
||||
;; But we can clock it out with a ROL instruction
|
||||
;; so that it is in C. We can then ROR it into the
|
||||
;; partial data byte.
|
||||
;; We use ROR so that we shift in from the top, so that
|
||||
;; the first bit we shift in ends up in bit 0 after all
|
||||
;; 8 bits have been read.
|
||||
;; ODD: For some reason we don't need to invert the
|
||||
;; received bits. This is weird, because we invert them
|
||||
;; on the way out, and everything in the protocol seems
|
||||
;; to indicate that we sould do so. But experimentation
|
||||
;; has confirmed the bits don't need inversion on reception.
|
||||
|
||||
;; Move data bit into C flag, and loop until bit 6 clears
|
||||
;; i.e., the clock has been released.
|
||||
|
||||
* lda CIA2_PRA
|
||||
rol
|
||||
bpl -
|
||||
|
||||
;; Pull it into the data byte
|
||||
pla
|
||||
ror
|
||||
pha
|
||||
|
||||
;; Wait for CLK to be pulled again, over 300 usec (307 cycles on NTSC)
|
||||
;; consider this a timeout
|
||||
ldy #$19 ; 2 cycles
|
||||
iec_rx_clk_wait2:
|
||||
lda CIA2_PRA ; 4 cycles
|
||||
rol ; 2 cycles, to put CLK in as the last bit
|
||||
bpl + ; 2 cycles if not jumped
|
||||
dey ; 2 cycles
|
||||
bne iec_rx_clk_wait2 ; 3 cycles if jumped
|
||||
|
||||
;; Timeout
|
||||
jsr kernalstatus_EOI
|
||||
pla
|
||||
plp
|
||||
|
||||
;; Restore registers
|
||||
pla
|
||||
tay
|
||||
pla
|
||||
tax
|
||||
|
||||
sec ; XXX confirm that sec is really a way to report timeout here
|
||||
rts
|
||||
*
|
||||
;; More bits?
|
||||
dex
|
||||
bpl iec_rx_bit_loop
|
||||
|
||||
;; Then we must within 1000 usec acknowledge the frame by
|
||||
;; pulling DATA. At this point, CLK is pulled by the
|
||||
;; talker and DATA by us, i.e., we are ready to receive
|
||||
;; the next byte. (p11).
|
||||
jsr iec_release_clk_pull_data
|
||||
|
||||
;; Retreive the received byte
|
||||
pla
|
||||
|
||||
;; Return no-error
|
||||
plp
|
||||
|
||||
;; Restore registers
|
||||
sta IEC_TMP2 ; $A4 is a byte buffer according to http://sta.c64.org/cbm64mem.html
|
||||
pla
|
||||
tay
|
||||
pla
|
||||
tax
|
||||
lda IEC_TMP2
|
||||
|
||||
clc
|
||||
rts
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
|
||||
iec_set_idle:
|
||||
lda CIA2_PRA
|
||||
ora #BIT_CIA2_PRA_CLK_OUT ; pull
|
||||
and #$FF - BIT_CIA2_PRA_DAT_OUT - BIT_CIA2_PRA_ATN_OUT ; release
|
||||
sta CIA2_PRA
|
||||
rts
|
||||
@@ -0,0 +1,38 @@
|
||||
;; According to http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf
|
||||
;; pages 7--8.
|
||||
;; See also https://www.pagetable.com/?p=1135, https://github.com/mist64/cbmbus_doc
|
||||
|
||||
iec_turnaround_to_listen:
|
||||
|
||||
;; Store .X and .Y on the stack - preserve them
|
||||
txa
|
||||
pha
|
||||
tya
|
||||
pha
|
||||
|
||||
;; Timing is critical here - execute on disabled IRQs
|
||||
php
|
||||
sei
|
||||
|
||||
;; Pull DATA, release CLK and ATN (we are not sending commands)
|
||||
jsr iec_pull_data_release_atn_clk
|
||||
|
||||
;; Wait for clock line to be pulled by the drive
|
||||
ldx #$FF ; XXX should we really use that high number?
|
||||
*
|
||||
lda CIA2_PRA
|
||||
rol ; to put BIT_CIA2_PRA_CLK_IN as the last (sign) bit
|
||||
bpl +
|
||||
dex
|
||||
bne -
|
||||
|
||||
;; Timeout - XXX what errors do original Kernal report?
|
||||
plp
|
||||
jmp iec_return_DEVICE_NOT_FOUND
|
||||
|
||||
;; CLK is pulled by the device, OK
|
||||
*
|
||||
plp
|
||||
jmp iec_return_success
|
||||
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
;; According to http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf
|
||||
;; pages 7--8.
|
||||
;; See also https://www.pagetable.com/?p=1135, https://github.com/mist64/cbmbus_doc
|
||||
|
||||
iec_turnaround_to_talk:
|
||||
|
||||
;; Store .X and .Y on the stack - preserve them
|
||||
txa
|
||||
pha
|
||||
tya
|
||||
pha
|
||||
|
||||
;; Timing is critical here - execute on disabled IRQs
|
||||
php
|
||||
sei
|
||||
|
||||
;; First make sure both CLK, DATA and ATN are released at our side
|
||||
jsr iec_release_atn
|
||||
jsr iec_release_clk_data
|
||||
|
||||
;; Wait till device releases CLK line
|
||||
jsr iec_wait_for_clk_release
|
||||
|
||||
;; Pull CLK line, it should be held by talker
|
||||
jsr iec_pull_clk_release_data
|
||||
|
||||
plp
|
||||
jmp iec_return_success
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
|
||||
;; Implemented based on https://www.pagetable.com/?p=1135, https://github.com/mist64/cbmbus_doc
|
||||
|
||||
;; Expects byte to send in IEC_TMP2 ($A4 is a byte buffer according to http://sta.c64.org/cbm64mem.html)
|
||||
;; Carry flag set = signal EOI
|
||||
;;
|
||||
;; Preserves .X and .Y registers
|
||||
|
||||
|
||||
iec_tx_byte:
|
||||
|
||||
;; Store .X and .Y on the stack - preserve them
|
||||
txa
|
||||
pha
|
||||
tya
|
||||
pha
|
||||
|
||||
;; Notify all devices that we are going to send a byte
|
||||
;; and it is going to be a data byte (released ATN)
|
||||
jsr iec_release_atn_clk_data
|
||||
|
||||
;; Common part of iec_txbyte and iec_tx_common - waits for devices
|
||||
;; and transmits a byte
|
||||
|
||||
jsr iec_tx_common
|
||||
|
||||
;; Give device time to tell if they are busy by pulling DATA
|
||||
;; They should do it within 1ms
|
||||
ldx #$FF
|
||||
* lda CIA2_PRA
|
||||
;; BPL here is checking that bit 7 clears,
|
||||
;; i.e, that the DATA line is pulled by drive
|
||||
bpl +
|
||||
dex
|
||||
bne -
|
||||
bpl iec_return_DEVICE_NOT_FOUND
|
||||
*
|
||||
jmp iec_return_success
|
||||
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
|
||||
;; Implemented based on https://www.pagetable.com/?p=1135, https://github.com/mist64/cbmbus_doc
|
||||
|
||||
;; Expects byte to send in IEC_TMP2 ($A4 is a byte buffer according to http://sta.c64.org/cbm64mem.html)
|
||||
;; Carry flag set = signal EOI
|
||||
;;
|
||||
;; Preserves .X and .Y registers
|
||||
|
||||
|
||||
iec_tx_command:
|
||||
|
||||
;; Store .X and .Y on the stack - preserve them
|
||||
txa
|
||||
pha
|
||||
tya
|
||||
pha
|
||||
|
||||
;; Notify all devices that we are going to send a byte
|
||||
;; and it is going to be a command (pulled ATN)
|
||||
jsr iec_pull_atn_clk_release_data
|
||||
|
||||
;; Give devices time to respond (response is mandatory!)
|
||||
jsr iec_wait1ms
|
||||
|
||||
;; Did at least one device respond by pulling DATA?
|
||||
lda CIA2_PRA
|
||||
and #BIT_CIA2_PRA_DAT_IN ; XXX try to optimize this, move to separate routine
|
||||
beq +
|
||||
|
||||
;; No devices present on the bus, so we can immediately return with device not found
|
||||
jmp iec_return_DEVICE_NOT_FOUND
|
||||
*
|
||||
;; At least one device responded, but they are still allowed to stall
|
||||
;; (can be busy processing something), we have to wait till they are all
|
||||
;; ready (or bored with DOS attack...)
|
||||
;; Release back CLK, keep DATA released - to ask devices for status.
|
||||
|
||||
jsr iec_release_clk_data
|
||||
|
||||
;; Common part of iec_txbyte and iec_tx_common - waits for devices
|
||||
;; and transmits a byte
|
||||
|
||||
clc ; Carry flag set is used for EOI mark
|
||||
jsr iec_tx_common
|
||||
|
||||
;; According to https://www.pagetable.com/?p=1135 there is some complicated and dangerous
|
||||
;; flow here, but http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf (page 6)
|
||||
;; advices to just wait 1ms and check the DATA status
|
||||
jsr iec_wait1ms
|
||||
lda CIA2_PRA
|
||||
and #BIT_CIA2_PRA_DAT_IN ; XXX try to optimize this, move to separate routine
|
||||
beq +
|
||||
|
||||
;; XXX possible optimization of the flow above: for many commands it is enough
|
||||
;; to wait for the DATA being pulled, as confirmation is expected from
|
||||
;; a single device only - but not sure if it's worth the trouble
|
||||
|
||||
jmp iec_return_DEVICE_NOT_FOUND
|
||||
*
|
||||
;; Done
|
||||
|
||||
jmp iec_return_success
|
||||
@@ -0,0 +1,20 @@
|
||||
|
||||
;; Routine to finalize some IEC commands - which do not end in turnaround and are not followed by others
|
||||
;; Implemented based on https://www.pagetable.com/?p=1135, https://github.com/mist64/cbmbus_doc
|
||||
|
||||
|
||||
iec_tx_command_finalize:
|
||||
|
||||
;; Store .X and .Y on the stack - preserve them
|
||||
txa
|
||||
pha
|
||||
tya
|
||||
pha
|
||||
|
||||
;; Give device some time to complete command reception, release ATN,
|
||||
;; give it some time again before (possible) next command
|
||||
jsr iec_wait20us
|
||||
jsr iec_set_idle
|
||||
jsr iec_wait20us
|
||||
|
||||
jmp iec_return_success
|
||||
@@ -0,0 +1,72 @@
|
||||
|
||||
;; This is a common part of iec_tx_byte and iec_tx_command
|
||||
;; Implemented based on https://www.pagetable.com/?p=1135, https://github.com/mist64/cbmbus_doc
|
||||
;; and http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf
|
||||
|
||||
;; Expects byte to send in IEC_TMP2 ($A4 is a byte buffer according to http://sta.c64.org/cbm64mem.html)
|
||||
;; Carry flag set = signal EOI
|
||||
|
||||
iec_tx_common:
|
||||
|
||||
;; Timing is critical here - execute on disabled IRQs
|
||||
php
|
||||
sei
|
||||
|
||||
;; Wait till all receivers are ready, they should all release DATA
|
||||
jsr iec_wait_for_data_release
|
||||
|
||||
;; At this point a delay 256 usec or more is considered EOI - add waits if necessary
|
||||
bcc +
|
||||
jsr iec_wait100us
|
||||
jsr iec_wait100us
|
||||
jsr iec_wait60us
|
||||
|
||||
;; XXX waits above should be enough - why do we need more waits???
|
||||
jsr iec_wait100us
|
||||
jsr iec_wait100us
|
||||
jsr iec_wait100us
|
||||
|
||||
;; Receiver should now acknowledge EOI by pulling data for at least 60 usec
|
||||
jsr iec_wait60us
|
||||
jsr iec_wait_for_data_release
|
||||
*
|
||||
;; Pull CLK back to indicate that DATA is not valid, keep it for 60us
|
||||
;; We can use this routine as we don't hold DATA anyway (and its state doesn't even matter)
|
||||
|
||||
jsr iec_pull_clk_release_data
|
||||
jsr iec_wait60us
|
||||
|
||||
;; Now, we can start transmission of 8 bits of data
|
||||
ldx #7
|
||||
|
||||
iec_tx_common_sendbit:
|
||||
;; Is next bit 0 or 1?
|
||||
lda IEC_TMP2
|
||||
lsr
|
||||
sta IEC_TMP2
|
||||
bcs +
|
||||
|
||||
;; Bit is 0
|
||||
jsr iec_release_clk_pull_data
|
||||
jmp iec_tx_common_bit_is_sent
|
||||
*
|
||||
;; Bit is 1
|
||||
jsr iec_release_clk_data
|
||||
|
||||
iec_tx_common_bit_is_sent:
|
||||
|
||||
;; Wait 20us, so that device(s) can pick DATA
|
||||
jsr iec_wait20us
|
||||
|
||||
;; Pull CLK for 20us again, before sending the next bit
|
||||
;; or performing any other action
|
||||
jsr iec_pull_clk_release_data
|
||||
jsr iec_wait20us ; XXX this might be an overkill, there is a lot of code besides this wait here - few NOPs might be enough
|
||||
|
||||
;; More bits to send?
|
||||
dex
|
||||
bpl iec_tx_common_sendbit
|
||||
|
||||
plp
|
||||
rts ; Flow continues differently for data/command
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
|
||||
;; Flush the IEC output buffer (if not empty) - send byte with EOI
|
||||
;;
|
||||
;; Preserves .X, .Y and .A registers
|
||||
|
||||
iec_tx_flush:
|
||||
|
||||
pha
|
||||
lda C3PO
|
||||
beq +
|
||||
sec ; send it with EOI
|
||||
jsr iec_tx_byte ; send the command regardless of the status
|
||||
*
|
||||
pla
|
||||
rts
|
||||
@@ -0,0 +1,22 @@
|
||||
|
||||
iec_wait100us:
|
||||
|
||||
;; Wait 100usec
|
||||
|
||||
;; PAL:
|
||||
;; - CPU frequency 0.985248 MHz, we need to waste at least 99 cycles
|
||||
;; NTSC:
|
||||
;; - CPU frequency 1.022727 MHZ, we need to waste at least 103 cycles
|
||||
|
||||
;; Waste cycles in a loop
|
||||
|
||||
ldy #$12 ; 2 cycles
|
||||
* dey ; 2 cycles * 18
|
||||
bpl - ; 3 cycles * 17 + 2 cycles
|
||||
rts ; 6 cycles
|
||||
|
||||
;; 6 cycles JSR to routine,
|
||||
;; 97 cycles routine with RTS
|
||||
;; 1 cycle to fetch next instruction
|
||||
;; ---
|
||||
;; 104 cycles
|
||||
@@ -0,0 +1,20 @@
|
||||
|
||||
;;
|
||||
;; Wait 1 ms (1000 usec)
|
||||
;;
|
||||
;; On NTSC this means 1023 cycles (slightly less on PAL, but we have to be sure).
|
||||
;; We can't count on badlines, as the screen might be disabled.
|
||||
;; Delay here is implemeented using VIC-II raster register. Since one raster is
|
||||
;; 63 cycles, we need at least 17 full rasters to be 100% sure we wait enough
|
||||
|
||||
|
||||
iec_wait1ms:
|
||||
ldx #18 ; we probably won't start with the beginning of raster
|
||||
lda VIC_RASTER
|
||||
*
|
||||
cmp VIC_RASTER
|
||||
beq -
|
||||
lda VIC_RASTER
|
||||
dex
|
||||
bne -
|
||||
rts
|
||||
@@ -0,0 +1,22 @@
|
||||
|
||||
iec_wait20us:
|
||||
|
||||
;; Wait 20usec
|
||||
|
||||
;; PAL:
|
||||
;; - CPU frequency 0.985248 MHz, we need to waste at least 20 cycles
|
||||
;; NTSC:
|
||||
;; - CPU frequency 1.022727 MHZ, we need to waste at least 21 cycles
|
||||
|
||||
;; Waste cycles by reading some unimportant memory location
|
||||
;; in order not to clutter VICE debug logs
|
||||
|
||||
ora $03FF ; 4 cycles
|
||||
ora $03FF ; 4 cycles
|
||||
rts ; 6 cycles
|
||||
|
||||
;; 6 cycles JSR to routine,
|
||||
;; 14 cycles routine with RTS
|
||||
;; 1 cycle to fetch next instruction
|
||||
;; ---
|
||||
;; 21 cycles
|
||||
@@ -0,0 +1,23 @@
|
||||
|
||||
iec_wait60us:
|
||||
|
||||
;; Wait 60usec
|
||||
|
||||
;; PAL:
|
||||
;; - CPU frequency 0.985248 MHz, we need to waste at least 60 cycles
|
||||
;; NTSC:
|
||||
;; - CPU frequency 1.022727 MHZ, we need to waste at least 62 cycles
|
||||
|
||||
;; Waste cycles in a loop
|
||||
|
||||
ldy #$0A ; 2 cycles
|
||||
* dey ; 2 cycles * 10
|
||||
bpl - ; 3 cycles * 9 + 2 cycles
|
||||
rts ; 6 cycles
|
||||
|
||||
;; 6 cycles JSR to routine,
|
||||
;; 57 cycles routine with RTS
|
||||
;; 1 cycle to fetch next instruction
|
||||
;; ---
|
||||
;; 64 cycles
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
|
||||
iec_wait_for_clk_release:
|
||||
|
||||
lda CIA2_PRA
|
||||
and #BIT_CIA2_PRA_CLK_IN
|
||||
beq iec_wait_for_clk_release
|
||||
rts
|
||||
@@ -0,0 +1,8 @@
|
||||
|
||||
iec_wait_for_data_pull:
|
||||
|
||||
lda CIA2_PRA
|
||||
;; Check the highest bit, which is DATA IN,
|
||||
;; (highest bit set = negative value)
|
||||
bmi iec_wait_for_data_pull
|
||||
rts
|
||||
@@ -0,0 +1,8 @@
|
||||
|
||||
iec_wait_for_data_release:
|
||||
|
||||
lda CIA2_PRA
|
||||
;; Check the highest bit, which is DATA IN,
|
||||
;; (highest bit set = negative value)
|
||||
bpl iec_wait_for_data_release
|
||||
rts
|
||||
@@ -1,5 +0,0 @@
|
||||
iec_assert_atn:
|
||||
lda $dd00
|
||||
ora #$08
|
||||
sta $dd00
|
||||
rts
|
||||
@@ -1,6 +0,0 @@
|
||||
iec_assert_clk_and_data:
|
||||
lda $dd00
|
||||
and #$0b
|
||||
ora #$30
|
||||
sta $dd00
|
||||
rts
|
||||
@@ -1,6 +0,0 @@
|
||||
iec_assert_clk_release_data:
|
||||
lda $dd00
|
||||
and #$0b
|
||||
ora #$10
|
||||
sta $dd00
|
||||
rts
|
||||
@@ -1,5 +0,0 @@
|
||||
iec_assert_data:
|
||||
lda $dd00
|
||||
ora #$20
|
||||
sta $dd00
|
||||
rts
|
||||
@@ -1,11 +0,0 @@
|
||||
iec_release_atn:
|
||||
lda $dd00
|
||||
and #$f7
|
||||
sta $dd00
|
||||
|
||||
;; Also clear EOI marker
|
||||
lda IOSTATUS
|
||||
and #$bf
|
||||
sta IOSTATUS
|
||||
|
||||
rts
|
||||
@@ -1,5 +0,0 @@
|
||||
iec_release_clk:
|
||||
lda $dd00
|
||||
and #$2b
|
||||
sta $dd00
|
||||
rts
|
||||
@@ -1,6 +0,0 @@
|
||||
iec_release_clk_and_data:
|
||||
|
||||
lda $DD00
|
||||
and #$0b
|
||||
sta $DD00
|
||||
rts
|
||||
@@ -1,114 +0,0 @@
|
||||
;; Receive a byte from the IEC bus.
|
||||
;; reference http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf
|
||||
;; page 11.
|
||||
|
||||
|
||||
iec_rx_byte:
|
||||
|
||||
;; First, we wait for the talker to release the CLK line.
|
||||
jsr iec_wait_for_clock_release
|
||||
|
||||
;; We then release the data line
|
||||
;; (We can use this routine, since we weren't holding CLK, anyway)
|
||||
jsr iec_release_clk_and_data
|
||||
|
||||
;; Wait for talker to assert CLK.
|
||||
;; If >200usec, then it is EOI and we have to assert the
|
||||
;; DATA line for 60 usec to tell the TALKER that we have
|
||||
;; acknowledged the EOI.
|
||||
ldx #20
|
||||
iec_rx_clk_wait:
|
||||
;; Loop takes 11 usec, so ~20 iterations for 200usec timeout
|
||||
lda $dd00
|
||||
rol
|
||||
bpl not_eoi
|
||||
dex
|
||||
cpx #$21
|
||||
bne not_rx_timeout
|
||||
;; Time out waiting for CLK to assert again.
|
||||
;; = error
|
||||
sec
|
||||
rts
|
||||
not_rx_timeout:
|
||||
cpx #$00
|
||||
bpl iec_rx_clk_wait
|
||||
|
||||
;; Remember EOI condition
|
||||
lda IOSTATUS
|
||||
ora #$40
|
||||
sta IOSTATUS
|
||||
|
||||
;; EOI timeout: So pulse DATA line for 60 usec
|
||||
jsr iec_assert_data
|
||||
jsr iec_wait60us
|
||||
jsr iec_release_clk_and_data
|
||||
|
||||
;; And still wait for CLK to be asserted
|
||||
;; XXX - This will cause periodic EOI pulses if the sender takes too long.
|
||||
;; That is probably ok.
|
||||
ldx #$7f
|
||||
jmp iec_rx_clk_wait
|
||||
|
||||
not_eoi:
|
||||
;; CLK is now low. Latch input bits in on rising edge
|
||||
;; of CLK, eight times for eight bits.
|
||||
ldx #7
|
||||
|
||||
;; Get empty byte to load into.
|
||||
lda #$00
|
||||
pha
|
||||
|
||||
iec_rx_bit_loop:
|
||||
|
||||
;; Wait for CLK to release
|
||||
;; jsr iec_wait_for_clock_release
|
||||
;; (we do this implicitly below, with a tighter routine,
|
||||
;; so that we don't have timing problems, as the requirements
|
||||
;; are quite tight. Basically we need to read the clock and data
|
||||
;; bit from the same byte read.
|
||||
|
||||
;; DATA now has the next bit, but inverted (well, except that it turns out not to be).
|
||||
;; DATA is in bit7, which is a bit annoying.
|
||||
;; But we can clock it out with a ROL instruction
|
||||
;; so that it is in C. We can then ROR it into the
|
||||
;; partial data byte.
|
||||
;; We use ROR so that we shift in from the top, so that
|
||||
;; the first bit we shift in ends up in bit 0 after all
|
||||
;; 8 bits have been read.
|
||||
;; ODD: For some reason we don't need to invert the
|
||||
;; received bits. This is weird, because we invert them
|
||||
;; on the way out, and everything in the protocol seems
|
||||
;; to indicate that we sould do so. But experimentation
|
||||
;; has confirmed the bits don't need inversion on reception.
|
||||
|
||||
;; Move data bit into C flag, and loop until bit 6 clears
|
||||
;; i.e., the clock has been released.
|
||||
* LDA $DD00
|
||||
ROL
|
||||
bpl -
|
||||
|
||||
;; Pull it into the data byte
|
||||
pla
|
||||
ROR
|
||||
pha
|
||||
|
||||
;; Wait for CLK to re-assert
|
||||
jsr iec_wait_for_clock_assert
|
||||
|
||||
;; More bits?
|
||||
dex
|
||||
bpl iec_rx_bit_loop
|
||||
|
||||
;; Then we must within 1000usec acknowledge the frame by
|
||||
;; asserting DATA. At this point, CLK is asserted by the
|
||||
;; talker and DATA by us, i.e., we are ready to receive
|
||||
;; the next byte. (p11).
|
||||
jsr iec_assert_data
|
||||
|
||||
;; Retreive the received byte
|
||||
PLA
|
||||
|
||||
;; Return no-error
|
||||
CLC
|
||||
RTS
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
;; According to http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf
|
||||
;; pages 7--8.
|
||||
|
||||
iec_turnaround_to_listen:
|
||||
|
||||
;; Assert data and release clock
|
||||
lda $dd00
|
||||
and #$ef ; release clock (bit 4)
|
||||
ora #$20 ; assert data (bit 5)
|
||||
sta $dd00
|
||||
|
||||
;; Wait for clock line to be asserted by the drive
|
||||
* lda $dd00
|
||||
and #$40
|
||||
bne -
|
||||
|
||||
;; http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf
|
||||
;; page 8 tells us we should not do anything here after waiting for
|
||||
;; the clock line to assert.
|
||||
|
||||
ldx #$ff
|
||||
* lda $dd00
|
||||
and #$40
|
||||
bne +
|
||||
dex
|
||||
bne -
|
||||
|
||||
;; jsr printf
|
||||
;; .byte "TURNAROUND FAILED - FILE NOT FOUND?",$0d,$00
|
||||
|
||||
;; ;; Timeout = file not found error
|
||||
;; ;; (https://www.pagetable.com/?p=1023)
|
||||
lda #4
|
||||
sec
|
||||
rts
|
||||
*
|
||||
;; ATN turn around successful
|
||||
clc
|
||||
rts
|
||||
Loaded 100 of 279 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user