adapted to Kick Assembler, some documentation update
This commit is contained in:
1 parent
ae23dbae7b
commit
de27124b4f
198 files changed
+4181
-3976
No files matched your search
+2
-2
@@ -2,9 +2,9 @@
|
||||
# Compilation related files
|
||||
|
||||
temp.s
|
||||
temp.map
|
||||
temp.sym
|
||||
|
||||
ophis.bin
|
||||
assembler/KickAss*
|
||||
build/*
|
||||
|
||||
# Input to the similarity tool - copyrighted material, we can't check it in!
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
[submodule "Ophis"]
|
||||
path = Ophis
|
||||
url = https://github.com/gardners/Ophis.git
|
||||
@@ -33,15 +33,10 @@ GIT_COMMIT:= $(shell git log -1 --pretty='%h' | tr '[:lower:]' '[:upper:]')
|
||||
|
||||
all: build/chargen build/newkern_generic build/newbasic_generic build/newc65 build/newkern_ultimate64 build/newbasic_ultimate64
|
||||
|
||||
Ophis:
|
||||
git submodule init
|
||||
git submodule update
|
||||
|
||||
clean:
|
||||
@rm -rf build
|
||||
@rm -f temp.s
|
||||
@rm -f temp.map
|
||||
@rm -f ophis.bin
|
||||
@rm -f temp.sym
|
||||
|
||||
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
|
||||
@@ -81,23 +76,23 @@ build/chargen: $(TOOL_PNGPREPARE) assets/8x8font.png
|
||||
|
||||
# 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_generic/OUT.BIN: $(TOOLS_LIST) $(SRC_BASIC_generic) build/basic/packed_messages.s
|
||||
build/kernal_generic/OUT.BIN: $(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_mega65/OUT.BIN: $(TOOLS_LIST) $(SRC_BASIC_mega65) build/basic/packed_messages.s
|
||||
build/kernal_mega65/OUT.BIN: $(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
|
||||
build/basic_ultimate64/OUT.BIN: $(TOOLS_LIST) $(SRC_BASIC_ultimate64) build/basic/packed_messages.s
|
||||
build/kernal_ultimate64/OUT.BIN: $(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
|
||||
|
||||
|
||||
# Rules - BASIC and KERNAL
|
||||
@@ -107,7 +102,7 @@ build/basic/packed_messages.s: $(TOOL_COMPRESS_TEXT)
|
||||
$(TOOL_COMPRESS_TEXT) > build/basic/packed_messages.s
|
||||
|
||||
.PRECIOUS: build/basic_%/OUT.BIN
|
||||
build/basic_%/OUT.BIN: Ophis $(TOOLS_LIST) $(SRC_BASIC_$*) build/basic/packed_messages.s
|
||||
build/basic_%/OUT.BIN: $(TOOLS_LIST) $(SRC_BASIC_$*) build/basic/packed_messages.s
|
||||
@mkdir -p build/basic_$*
|
||||
@rm -f build/basic_$*/*
|
||||
@for SRC in $(SRC_BASIC_$*); do \
|
||||
@@ -117,7 +112,7 @@ build/basic_%/OUT.BIN: Ophis $(TOOLS_LIST) $(SRC_BASIC_$*) build/basic/packed_me
|
||||
$(TOOL_PREPROCESS) -d build/basic_$* -l a000 -h e4d2
|
||||
|
||||
.PRECIOUS: build/kernal_%/OUT.BIN
|
||||
build/kernal_%/OUT.BIN: Ophis $(TOOLS_LIST) $(SRC_KERNAL_$*)
|
||||
build/kernal_%/OUT.BIN: $(TOOLS_LIST) $(SRC_KERNAL_$*)
|
||||
@mkdir -p build/kernal_$*
|
||||
@rm -f build/kernal_$*/*
|
||||
@for SRC in $(SRC_KERNAL_$*); do \
|
||||
|
||||
-1
Submodule Ophis deleted from 15818e7666.
@@ -1,5 +1,6 @@
|
||||
# open-roms
|
||||
A project to create unencumbered open-source ROMs for use on selected retro computers
|
||||
|
||||
A project to create unencumbered open-source ROMs for use on selected retro computers. For the current status check [this document](STATUS.md)
|
||||
|
||||
# Problem Statement and Motivation
|
||||
|
||||
|
||||
@@ -38,16 +38,10 @@ The following ROM features are currently missing:
|
||||
Status of the various APIs and variables from the original ROMs
|
||||
|
||||
|
||||
## Page 0
|
||||
## Low memory locations (pages 0 - 3)
|
||||
|
||||
|
||||
TODO
|
||||
|
||||
|
||||
## Pages 2 & 3
|
||||
|
||||
|
||||
TODO
|
||||
For the current status of the low memory location implementation andd usage check [this file](c64/aliases/,aliases_ram_lowmem.s). NOTE: available vector to certain routine does not mean that this routine is fully implemented!
|
||||
|
||||
|
||||
## BASIC
|
||||
@@ -107,7 +101,7 @@ NOTE: Even the 'DONE' routines won't support features described as missing in on
|
||||
| `$FFE7` | `CLALL` | DONE | |
|
||||
| `$FFEA` | `UDTIM` | DONE | |
|
||||
| `$FFED` | `SCREEN` | DONE | |
|
||||
| `$FFF0` | `PLOT` | DONE | |
|
||||
| `$FFF0` | `PLOT` | PARTIAL | cursor blink not handled |
|
||||
| `$FFF3` | `IOBASE` | DONE | |
|
||||
|
||||
<br />
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
Put KickAss.jar and KickAss.cfg into this directory.
|
||||
@@ -1,63 +1,63 @@
|
||||
|
||||
;; Kernal error codes - returned in the A register
|
||||
;; Described in 'Commodore 64 Programmer's Reference Guide', page 306
|
||||
// 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
|
||||
.const K_ERR_ROUTINE_TERMINATED = $00
|
||||
.const K_ERR_TOO_MANY_OPEN_FILES = $01
|
||||
.const K_ERR_FILE_ALREADY_OPEN = $02
|
||||
.const K_ERR_FILE_NOT_OPEN = $03
|
||||
.const K_ERR_FILE_NOT_FOUND = $04
|
||||
.const K_ERR_DEVICE_NOT_FOUND = $05
|
||||
.const K_ERR_FILE_NOT_INPUT = $06
|
||||
.const K_ERR_FILE_NOT_OUTPUT = $07
|
||||
.const K_ERR_FILE_NAME_MISSING = $08
|
||||
.const K_ERR_ILLEGAL_DEVICE_NUMBER = $09
|
||||
.const K_ERR_TOP_MEM_RS232 = $F0
|
||||
|
||||
;; Kernal status codes for READST routine (IOSTATUS)
|
||||
;; Described in 'Commodore 64 Programmer's Reference Guide', page 292
|
||||
// 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
|
||||
// For IEC devices
|
||||
.const K_STS_TIMEOUT_WRITE = $01
|
||||
.const K_STS_TIMEOUT_READ = $02
|
||||
.const K_STS_EOI = $40
|
||||
.const K_STS_DEVICE_NOT_FOUND = $80
|
||||
// For tape deck
|
||||
.const K_STS_SHORT_BLOCK = $04
|
||||
.const K_STS_LONG_BLOCK = $08
|
||||
.const K_STS_READ_ERROR = $10
|
||||
.const K_STS_CHECKSUM_ERROR = $20
|
||||
.const K_STS_END_OF_FILE = $40
|
||||
.const 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
|
||||
// BASIC error codes, taken from http://sta.c64.org/cbm64baserr.html
|
||||
.const B_ERR_TOO_MANY_FILES = $01
|
||||
.const B_ERR_FILE_OPEN = $02
|
||||
.const B_ERR_FILE_NOT_OPEN = $03
|
||||
.const B_ERR_FILE_NOT_FOUND = $04
|
||||
.const B_ERR_DEVICE_NOT_PRESENT = $05
|
||||
.const B_ERR_NOT_INPUT_FILE = $06
|
||||
.const B_ERR_NOT_OUTPUT_FILE = $07
|
||||
.const B_ERR_MISSING_FILENAME = $08
|
||||
.const B_ERR_ILLEGAL_DEVICE_NUMBER = $09
|
||||
.const B_ERR_NEXT_WITHOUT_FOR = $0A
|
||||
.const B_ERR_SYNTAX = $0B
|
||||
.const B_ERR_RETURN_WITHOUT_GOSUB = $0C
|
||||
.const B_ERR_OUT_OF_DATA = $0D
|
||||
.const B_ERR_ILLEGAL_QUANTITY = $0E
|
||||
.const B_ERR_OVERFLOW = $0F
|
||||
.const B_ERR_OUT_OF_MEMORY = $10
|
||||
.const B_ERR_UNDEFD_STATEMENT = $11
|
||||
.const B_ERR_BAD_SUBSCRIPT = $12
|
||||
.const B_ERR_REDIMD_ARRAY = $13
|
||||
.const B_ERR_DIVISION_BY_ZERO = $14
|
||||
.const B_ERR_ILLEGAL_DIRECT = $15
|
||||
.const B_ERR_TYPE_MISMATCH = $16
|
||||
.const B_ERR_STRING_TOO_LONG = $17
|
||||
.const B_ERR_FILE_DATA = $18
|
||||
.const B_ERR_FORMULA_TOO_COMPLEX = $19
|
||||
.const B_ERR_CANT_CONTINUE = $1A
|
||||
.const B_ERR_UNDEFD_FUNCTION = $1B
|
||||
.const B_ERR_VERIFY = $1C
|
||||
.const B_ERR_LOAD = $1D
|
||||
.const B_ERR_BREAK = $1E
|
||||
+124
-124
@@ -1,148 +1,148 @@
|
||||
|
||||
;;
|
||||
;; Names of hardware registers - slightly modified names from C64 Programmer's Reference Guide
|
||||
;;
|
||||
//
|
||||
// Names of hardware registers - slightly modified names from C64 Programmer's Reference Guide
|
||||
//
|
||||
|
||||
;; CPU memory registers
|
||||
// CPU memory registers
|
||||
|
||||
.alias CPU_D6510 $00
|
||||
.alias CPU_R6510 $01
|
||||
.label CPU_D6510 = $00
|
||||
.label CPU_R6510 = $01
|
||||
|
||||
;; VIC-II registers
|
||||
// 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
|
||||
.label VIC_SP0X = $D000
|
||||
.label VIC_SP0Y = $D001
|
||||
.label VIC_SP1X = $D002
|
||||
.label VIC_SP1Y = $D003
|
||||
.label VIC_SP2X = $D004
|
||||
.label VIC_SP2Y = $D005
|
||||
.label VIC_SP3X = $D006
|
||||
.label VIC_SP3Y = $D007
|
||||
.label VIC_SP4X = $D008
|
||||
.label VIC_SP4Y = $D009
|
||||
.label VIC_SP5X = $D00A
|
||||
.label VIC_SP5Y = $D00B
|
||||
.label VIC_SP6X = $D00C
|
||||
.label VIC_SP6Y = $D00D
|
||||
.label VIC_SP7X = $D00E
|
||||
.label VIC_SP7Y = $D00F
|
||||
|
||||
.alias VIC_MSIGX $D010
|
||||
.alias VIC_SCROLY $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
|
||||
.label VIC_MSIGX = $D010
|
||||
.label VIC_SCROLY = $D011
|
||||
.label VIC_RASTER = $D012
|
||||
.label VIC_LPENX = $D013
|
||||
.label VIC_LPENY = $D014
|
||||
.label VIC_SPENA = $D015
|
||||
.label VIC_SCROLX = $D016
|
||||
.label VIC_YXPAND = $D017
|
||||
.label VIC_YMCSB = $D018
|
||||
.label VIC_IRQ = $D019
|
||||
.label VIC_IRQMSK = $D01A
|
||||
.label VIC_SPBGPR = $D01B
|
||||
.label VIC_SPMC = $D01C
|
||||
.label VIC_XXPAND = $D01D
|
||||
.label VIC_SPSPCL = $D01E
|
||||
.label 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
|
||||
.label VIC_EXTCOL = $D020
|
||||
.label VIC_BGCOL0 = $D021
|
||||
.label VIC_BGCOL1 = $D022
|
||||
.label VIC_BGCOL2 = $D023
|
||||
.label VIC_BGCOL3 = $D024
|
||||
.label VIC_SPMC0 = $D025
|
||||
.label VIC_SPMC1 = $D026
|
||||
.label VIC_SP0COL = $D027
|
||||
.label VIC_SP1COL = $D028
|
||||
.label VIC_SP2COL = $D029
|
||||
.label VIC_SP3COL = $D02A
|
||||
.label VIC_SP4COL = $D02B
|
||||
.label VIC_SP5COL = $D02C
|
||||
.label VIC_SP6COL = $D02D
|
||||
.label VIC_SP7COL = $D02E
|
||||
|
||||
;; SID registers
|
||||
// SID registers
|
||||
|
||||
.alias SID_FRELO1 $D400
|
||||
.alias SID_FREHI1 $D401
|
||||
.alias SID_PWLO1 $D402
|
||||
.alias SID_PWHI1 $D403
|
||||
.alias SID_VCREG1 $D404
|
||||
.alias SID_ATDCY1 $D405
|
||||
.alias SID_SUREL1 $D406
|
||||
.label SID_FRELO1 = $D400
|
||||
.label SID_FREHI1 = $D401
|
||||
.label SID_PWLO1 = $D402
|
||||
.label SID_PWHI1 = $D403
|
||||
.label SID_VCREG1 = $D404
|
||||
.label SID_ATDCY1 = $D405
|
||||
.label SID_SUREL1 = $D406
|
||||
|
||||
.alias SID_FRELO2 $D407
|
||||
.alias SID_FREHI2 $D408
|
||||
.alias SID_PWLO2 $D409
|
||||
.alias SID_PWHI2 $D40A
|
||||
.alias SID_VCREG2 $D40B
|
||||
.alias SID_ATDCY2 $D40C
|
||||
.alias SID_SUREL2 $D40D
|
||||
.label SID_FRELO2 = $D407
|
||||
.label SID_FREHI2 = $D408
|
||||
.label SID_PWLO2 = $D409
|
||||
.label SID_PWHI2 = $D40A
|
||||
.label SID_VCREG2 = $D40B
|
||||
.label SID_ATDCY2 = $D40C
|
||||
.label SID_SUREL2 = $D40D
|
||||
|
||||
.alias SID_FRELO3 $D40E
|
||||
.alias SID_FREHI3 $D40F
|
||||
.alias SID_PWLO3 $D410
|
||||
.alias SID_PWHI3 $D411
|
||||
.alias SID_VCREG3 $D412
|
||||
.alias SID_ATDCY3 $D413
|
||||
.alias SID_SUREL3 $D414
|
||||
.label SID_FRELO3 = $D40E
|
||||
.label SID_FREHI3 = $D40F
|
||||
.label SID_PWLO3 = $D410
|
||||
.label SID_PWHI3 = $D411
|
||||
.label SID_VCREG3 = $D412
|
||||
.label SID_ATDCY3 = $D413
|
||||
.label SID_SUREL3 = $D414
|
||||
|
||||
.alias SID_CUTLO $D415
|
||||
.alias SID_CUTHI $D416
|
||||
.alias SID_RESON $D417
|
||||
.alias SID_SIGVOL $D418
|
||||
.alias SID_POTX $D419
|
||||
.alias SID_POTY $D41A
|
||||
.alias SID_RANDOM $D41B
|
||||
.alias SID_ENV3 $D41C
|
||||
.label SID_CUTLO = $D415
|
||||
.label SID_CUTHI = $D416
|
||||
.label SID_RESON = $D417
|
||||
.label SID_SIGVOL = $D418
|
||||
.label SID_POTX = $D419
|
||||
.label SID_POTY = $D41A
|
||||
.label SID_RANDOM = $D41B
|
||||
.label SID_ENV3 = $D41C
|
||||
|
||||
;; CIA #1 registers
|
||||
// CIA #1 registers
|
||||
|
||||
.alias CIA1_PRA $DC00
|
||||
.alias CIA1_PRB $DC01
|
||||
.alias CIA1_DDRA $DC02
|
||||
.alias CIA1_DDRB $DC03
|
||||
.label CIA1_PRA = $DC00
|
||||
.label CIA1_PRB = $DC01
|
||||
.label CIA1_DDRA = $DC02
|
||||
.label CIA1_DDRB = $DC03
|
||||
|
||||
.alias CIA1_TIMALO $DC04
|
||||
.alias CIA1_TIMAHI $DC05
|
||||
.alias CIA1_TIMBLO $DC06
|
||||
.alias CIA1_TIMBHI $DC07
|
||||
.label CIA1_TIMALO = $DC04
|
||||
.label CIA1_TIMAHI = $DC05
|
||||
.label CIA1_TIMBLO = $DC06
|
||||
.label CIA1_TIMBHI = $DC07
|
||||
|
||||
.alias CIA1_TODTEN $DC08
|
||||
.alias CIA1_TODSEC $DC09
|
||||
.alias CIA1_TODMIN $DC0A
|
||||
.alias CIA1_TODHRS $DC0B
|
||||
.label CIA1_TODTEN = $DC08
|
||||
.label CIA1_TODSEC = $DC09
|
||||
.label CIA1_TODMIN = $DC0A
|
||||
.label CIA1_TODHRS = $DC0B
|
||||
|
||||
.alias CIA1_SDR $DC0C
|
||||
.alias CIA1_ICR $DC0D
|
||||
.alias CIA1_CRA $DC0E
|
||||
.alias CIA1_CRB $DC0F
|
||||
.label CIA1_SDR = $DC0C
|
||||
.label CIA1_ICR = $DC0D
|
||||
.label CIA1_CRA = $DC0E
|
||||
.label CIA1_CRB = $DC0F
|
||||
|
||||
;; CIA #2 registers
|
||||
// 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
|
||||
.label CIA2_PRA = $DD00 // VIC bank switching and IEC port
|
||||
.label CIA2_PRB = $DD01
|
||||
.label CIA2_DDRA = $DD02
|
||||
.label CIA2_DDRB = $DD03
|
||||
|
||||
.alias CIA2_TIMALO $DD04
|
||||
.alias CIA2_TIMAHI $DD05
|
||||
.alias CIA2_TIMBLO $DD06
|
||||
.alias CIA2_TIMBHI $DD07
|
||||
.label CIA2_TIMALO = $DD04
|
||||
.label CIA2_TIMAHI = $DD05
|
||||
.label CIA2_TIMBLO = $DD06
|
||||
.label CIA2_TIMBHI = $DD07
|
||||
|
||||
.alias CIA2_TODTEN $DD08
|
||||
.alias CIA2_TODSEC $DD09
|
||||
.alias CIA2_TODMIN $DD0A
|
||||
.alias CIA2_TODHRS $DD0B
|
||||
.label CIA2_TODTEN = $DD08
|
||||
.label CIA2_TODSEC = $DD09
|
||||
.label CIA2_TODMIN = $DD0A
|
||||
.label CIA2_TODHRS = $DD0B
|
||||
|
||||
.alias CIA2_SDR $DD0C
|
||||
.alias CIA2_ICR $DD0D
|
||||
.alias CIA2_CRA $DD0E
|
||||
.alias CIA2_CRB $DD0F
|
||||
.label CIA2_SDR = $DD0C
|
||||
.label CIA2_ICR = $DD0D
|
||||
.label CIA2_CRA = $DD0E
|
||||
.label CIA2_CRB = $DD0F
|
||||
|
||||
;; CIA #2 helper bits - IEC bus
|
||||
// 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)
|
||||
.const BIT_CIA2_PRA_ATN_OUT = $08 // 1 - low (pulled), 0 - high (released)
|
||||
.const BIT_CIA2_PRA_CLK_OUT = $10 // 1 - low (pulled), 0 - high (released)
|
||||
.const BIT_CIA2_PRA_DAT_OUT = $20 // 1 - low (pulled), 0 - high (released)
|
||||
.const BIT_CIA2_PRA_CLK_IN = $40 // 0 - low (pulled), 1 - high (released)
|
||||
.const BIT_CIA2_PRA_DAT_IN = $80 // 0 - low (pulled), 1 - high (released)
|
||||
@@ -1,98 +1,236 @@
|
||||
;;
|
||||
;; Names of ZP and low memory locations
|
||||
;; (https://www.c64-wiki.com/wiki/Zeropage)
|
||||
;;
|
||||
//
|
||||
// Names of ZP and low memory locations:
|
||||
// - Compute's Mapping the Commodore 64
|
||||
// - https://www.c64-wiki.com/wiki/Zeropage
|
||||
// - http://unusedino.de/ec64/technical/project64/memory_maps.html
|
||||
//
|
||||
|
||||
;; $00-$01 - 6502 CPU registers are here
|
||||
// $00-$01 - 6502 CPU registers are here
|
||||
|
||||
;;
|
||||
;; Page 0 - BASIC area ($02-$8F)
|
||||
;;
|
||||
//
|
||||
// Page 0 - BASIC area ($02-$8F)
|
||||
//
|
||||
|
||||
// $02 -- UNUSED -- free for user software
|
||||
.label ADRAY1 = $03 // $03-$04 -- NOT IMPLEMENTED --
|
||||
.label ADRAY2 = $05 // $05-$06 -- NOT IMPLEMENTED --
|
||||
.label CHARAC = $07 // [!] our implementation might be different XXX give more details
|
||||
.label ENDCHR = $08 // [!] our implementation might be different XXX give more details
|
||||
.label TRMPOS = $09 // -- NOT IMPLEMENTED --
|
||||
.label VERCKB = $0A // -- NOT IMPLEMENTED --
|
||||
.label COUNT = $0B // [!] our implementation might be different XXX give more details
|
||||
.label DIMFLG = $0C // [!] our implementation might be different XXX give more details
|
||||
.label VALTYP = $0D // -- NOT IMPLEMENTED --
|
||||
.label INTFLG = $0E // -- NOT IMPLEMENTED --
|
||||
.label GARBFL = $0F // [!] our implementation might be different XXX give more details
|
||||
.label SUBFLG = $10 // -- NOT IMPLEMENTED --
|
||||
.label INPFLG = $11 // -- NOT IMPLEMENTED --
|
||||
.label TANSGN = $12 // -- NOT IMPLEMENTED --
|
||||
.label CHANNL = $13 // -- NOT IMPLEMENTED --
|
||||
.label LINNUM = $14 // $14-$15 BASIC line number, [!] also used by DOS Wedge
|
||||
.label TEMPPT = $16 // -- NOT IMPLEMENTED --
|
||||
.label LASTPT = $17 // $17-$18 -- NOT IMPLEMENTED --
|
||||
.label TEMPST = $19 // $19-$21 -- NOT IMPLEMENTED --
|
||||
.label INDEX = $22 // $22-$25 -- NOT IMPLEMENTED -- temporary variables
|
||||
.label RESHO = $26 // $26-$2A -- NOT IMPLEMENTED --
|
||||
.label TXTTAB = $2B // $2B-$2C start of BASIC code
|
||||
.label VARTAB = $2D // $2D-$2E end of BASIC code, start of variables
|
||||
.label ARYTAB = $2F // $2F-$30 -- NOT IMPLEMENTED --
|
||||
.label STREND = $31 // $31-$32 -- NOT IMPLEMENTED --
|
||||
.label FRETOP = $33 // $33-$34 -- NOT IMPLEMENTED --
|
||||
.label FRESPC = $35 // $35-$36 [!] our implementation might be different XXX give more details
|
||||
// .label MEMSIZ = $37 // $37-$38 -- NOT IMPLEMENTED -- highest address of BASIC memory XXX remove name conflict
|
||||
.label CURLIN = $39 // $39-$3A current BASIC line number
|
||||
.label OLDLIN = $3B // $3B-$3C previous BASIC line number
|
||||
.label OLDTXT = $3D // $3D-$3E current BASIC line pointer
|
||||
.label DATLIN = $3F // $3F-$40 -- NOT IMPLEMENTED --
|
||||
.label DATPTR = $41 // $41-$42 -- NOT IMPLEMENTED --
|
||||
.label INPPTR = $43 // $43-$44 -- NOT IMPLEMENTED --
|
||||
.label VARNAM = $45 // $45-$46 -- NOT IMPLEMENTED --
|
||||
.label VARPNT = $47 // $47-$48 -- NOT IMPLEMENTED --
|
||||
.label FORPNT = $49 // $49-$4A -- NOT IMPLEMENTED --
|
||||
.label OPPTR = $4B // $4B-$4C -- NOT IMPLEMENTED --
|
||||
.label OPMASK = $4D // -- NOT IMPLEMENTED --
|
||||
.label DEFPNT = $4E // $4E-$4F -- NOT IMPLEMENTED --
|
||||
.label DSCPNT = $50 // $50-$52 -- NOT IMPLEMENTED --
|
||||
.label FOUR6 = $53 // -- NOT IMPLEMENTED --
|
||||
.label JMPER = $54 // $54-$56 -- NOT IMPLEMENTED --
|
||||
.label TEMPF1 = $57 // $57-$5B BASIC numeric work area
|
||||
.label TEMPF2 = $5C // $5C-$60 BASIC numeric work area
|
||||
.label FAC1 = $61 // $61-$66 -- NOT IMPLEMENTED --
|
||||
.label SGNFLG = $67 // -- NOT IMPLEMENTED --
|
||||
.label BITS = $68 // -- NOT IMPLEMENTED --
|
||||
.label FAC2 = $69 // $69-$6E -- NOT IMPLEMENTED -- [!] also used for memory move pointers
|
||||
.label ARISGN = $6F // -- NOT IMPLEMENTED --
|
||||
.label FACOV = $70 // -- NOT IMPLEMENTED --
|
||||
.label FBUFPT = $67 // $71-$72 -- NOT IMPLEMENTED --
|
||||
.label CHRGET = $73 // $73-$8A -- NOT IMPLEMENTED --
|
||||
.label TXTPTR = $7A // $7A-$7B current BASIC statement pointer
|
||||
.label RNDX = $8B // $8B-$8F -- NOT IMPLEMENTED --
|
||||
|
||||
//
|
||||
// Page 0 - Kernal area ($90-$FF)
|
||||
//
|
||||
|
||||
.alias TXTTAB $2B
|
||||
.label IOSTATUS = $90
|
||||
.label STKEY = $91 // Keys down clears bits. STOP - bit 7, C= - bit 6, SPACE - bit 4, CTRL - bit 2
|
||||
.label SVXT = $92 // -- NOT IMPLEMENTED --
|
||||
.label VERCK = $93 // 0 = LOAD, 1 = VERIFY XXX rename to VERCKK
|
||||
.label C3PO = $94 // flag - is BSOUR content valid
|
||||
.label BSOUR = $95 // serial bus buffered output byte
|
||||
.label SYNO = $96 // -- NOT IMPLEMENTED --
|
||||
.label XSAV = $97 // -- NOT IMPLEMENTED --
|
||||
.label LDTND = $98 // number of entries in LAT / FAT / SAT tables
|
||||
.label DFLTN = $99 // default input device
|
||||
.label DFLTO = $9A // default output device
|
||||
.label PRTY = $9B // -- NOT IMPLEMENTED --
|
||||
.label DPSW = $9C // -- NOT IMPLEMENTED --
|
||||
.label MSGFLG = $9D // bit 6 = error messages, bit 7 = control message
|
||||
.label PTR1 = $9E // -- NOT IMPLEMENTED --
|
||||
.label PTR2 = $9F // -- NOT IMPLEMENTED --
|
||||
.label TIME = $A0 // $A0-$A2, jiffy clock
|
||||
.label IEC_TMP1 = $A3 // temporary variable for tape and IEC, [!] our usage probably differs in details XXX rename to TSFCNT
|
||||
.label IEC_TMP2 = $A4 // temporary variable for tape and IEC, [!] our usage probably differs in details XXX rename to TBTCNT
|
||||
.label CNTDN = $A5 // -- NOT IMPLEMENTED --
|
||||
.label BUFPNT = $A6 // -- NOT IMPLEMENTED --
|
||||
.label INBIT = $A7 // -- NOT IMPLEMENTED --
|
||||
.label BITCI = $A8 // -- NOT IMPLEMENTED --
|
||||
.label RINONE = $A9 // -- NOT IMPLEMENTED --
|
||||
.label RIDDATA = $AA // -- NOT IMPLEMENTED --
|
||||
.label RIPRTY = $AB // -- NOT IMPLEMENTED --
|
||||
.label SAL = $AC // $AC-$AD -- NOT IMPLEMENTED -- (implemented screen part)
|
||||
.label EAL = $AE // $AE-$AF -- NOT IMPLEMENTED -- [!] used also byy screen editor
|
||||
.label CMP0 = $B0 // $B0-$B1, temporary tape storage, [!] here used for BRK instruction address
|
||||
.label TAPE1 = $B2 // $B2-$B3 tape buffer pointer
|
||||
.label BITTS = $B4 // -- NOT IMPLEMENTED --
|
||||
.label NXTBIT = $B5 // -- NOT IMPLEMENTED --
|
||||
.label RODATA = $B6 // -- NOT IMPLEMENTED --
|
||||
.label FNLEN = $B7 // current file name length
|
||||
.label LA = $B8 // current logical_file number
|
||||
.label SA = $B9 // current secondary address
|
||||
.label FA = $BA // current device number
|
||||
.label FNADDR = $BB // $BB-$BC, current file name pointer
|
||||
.label ROPRTY = $BD // -- NOT IMPLEMENTED --
|
||||
.label FSBLK = $BE // -- NOT IMPLEMENTED --
|
||||
.label MYCH = $BF // -- NOT IMPLEMENTED --
|
||||
.label CAS1 = $C0 // -- NOT IMPLEMENTED --
|
||||
.label STAL = $C1 // $C1-$C2, LOAD/SAVE start address
|
||||
.label MEMUS = $C3 // $C3-$C4, temporary address for tape LOAD/SAVE XXX rename to MEMUSS
|
||||
.label LSTX = $C5 // last keyy matrix position [!] our usage probably differs in details
|
||||
.label NDX = $C6 // number of chars in keyboard buffer
|
||||
.label RVS = $C7 // flag, whether to print reversed characters
|
||||
.label INDX = $C8 // end of logical line (column, 0-79)
|
||||
.label LXSP = $C9 // $C9-$CA start of input, X/Y position
|
||||
.label SFDX = $CB // -- NOT IMPLEMENTED --
|
||||
.label BLNSW = $CC // cursor blink disable flag
|
||||
.label BLNCT = $CD // cursor blink countdown
|
||||
.label GDBLN = $CE // cursorb saved character
|
||||
.label BLNON = $CF // cursor visibilityy flag
|
||||
.label CRSW = $D0 // whether to input from screen or keyboard
|
||||
.label PNT = $D1 // $D1-$D2 pointer to the current screen line
|
||||
.label PNTR = $D3 // current screen X position
|
||||
.label QTSW = $D4 // quote mode flag
|
||||
.label LNMX = $D5 // logical line length, [!] our usage probably differs in details
|
||||
.label TBLX = $D6 // current screen Y position
|
||||
.label SCHAR = $D7 // ASCII value of the last printed character
|
||||
.label INSRT = $D8 // insert mode flag/counter
|
||||
.label LDTB1 = $D9 // $D9-$F2 screen line link table, [!] our usage is different XXX give more details
|
||||
.label USER = $F3 // $F3-$F4 pointer to current color RAM location
|
||||
.label KEYTAB = $F5 // $F5-$F6 -- NOT IMPLEMENTED --
|
||||
.label RIBUF = $F7 // $F7-$F8 -- NOT IMPLEMENTED --
|
||||
.label ROBUF = $F9 // $F9-$FA -- NOT IMPLEMENTED --
|
||||
// $FB $FB-$FE -- UNUSED -- free for user software
|
||||
.label BASZPT = $FF // -- NOT IMPLEMENTED --
|
||||
|
||||
;;
|
||||
;; 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
|
||||
//
|
||||
// Page 1
|
||||
//
|
||||
|
||||
.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
|
||||
.label STACK = $100 // $100-$1FF, processor stack
|
||||
|
||||
.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
|
||||
|
||||
.alias CMP0 $B0 ; $B0-$B1, temporary tape storage, we use it too for BRK instruction address
|
||||
|
||||
.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
|
||||
.alias MEMUS $C3 ; $C3-$C4 temporary address for tape LOAD/SAVE
|
||||
|
||||
;;
|
||||
;; Other low memory addresses
|
||||
;;
|
||||
//
|
||||
// Pages 2 & 3
|
||||
//
|
||||
|
||||
.alias BUF $200 ; $200-$250 (81 bytes), BASIC line editor input buffer
|
||||
.label BUF = $200 // $200-$250, BASIC line editor input buffer (81 bytes)
|
||||
// [!] XXX document $251-$258 usage
|
||||
.label LAT = $259 // $259-$262, logical file numbers (table, 10 bytes)
|
||||
.label FAT = $263 // $263-$26C, device numbers (table, 10 bytes)
|
||||
.label SAT = $26D // $26D-$276, secondary addresses (table, 10 bytes)
|
||||
.label KEYD = $277 // $277-$280 keyboard buffer
|
||||
.label MEMSTR = $281 // $281-$282 XXX rename to LORAM
|
||||
.label MEMSIZ = $283 // $283-$284, NOTE: Mapping the 64 erroneously has the hex as $282, while the DEC is correct XXX rename to HIRAM
|
||||
.label TIMOUT = $285 // IEEE-488 timeout
|
||||
.label COLOR = $286 // current text foreground color
|
||||
.label GDCOL = $287 // color of character under cursor
|
||||
.label HIBASE = $288 // high byte of start of screen
|
||||
.label XMAX = $289 // max keyboard buffer size
|
||||
.label RPTFLG = $28A // -- NOT IMPLEMENTED --
|
||||
.label KOUNT = $28B // -- NOT IMPLEMENTED --
|
||||
.label DELAY = $28C // -- NOT IMPLEMENTED --
|
||||
.label SHFLAG = $28D // bucky keys (SHIFT/CTRL/C=) flags
|
||||
.label LSTSHF = $28E // last bucky key flags
|
||||
.label KEYLOG = $28F // $28F-$290 -- NOT IMPLEMENTED --
|
||||
.label MODE = $291 // flag, is case switch allowed
|
||||
.label AUTODN = $292 // -- NOT IMPLEMENTED --
|
||||
.label M51CRT = $293 // -- NOT IMPLEMENTED -- mock 6551
|
||||
.label M51CDR = $294 // -- NOT IMPLEMENTED -- mock 6551
|
||||
.label M51AJB = $295 // $295-$296 -- NOT IMPLEMENTED -- mock 6551
|
||||
.label RSSTAT = $297 // -- NOT IMPLEMENTED -- mock 6551, RS-232 status
|
||||
.label BITNUM = $298 // -- NOT IMPLEMENTED --
|
||||
.label BAUDOF = $299 // $299-$29A -- NOT IMPLEMENTED --
|
||||
.label RIDBE = $29B // -- NOT IMPLEMENTED --
|
||||
.label RIDBS = $29C // -- NOT IMPLEMENTED --
|
||||
.label RODBS = $29D // -- NOT IMPLEMENTED --
|
||||
.label RODBE = $29E // -- NOT IMPLEMENTED --
|
||||
.label IRQTMP = $29F // $29F-$2A0 -- NOT IMPLEMENTED --
|
||||
.label ENABL = $2A1 // -- NOT IMPLEMENTED --
|
||||
.label TODSNS = $2A2 // -- NOT IMPLEMENTED --
|
||||
.label TRDTMP = $2A3 // -- NOT IMPLEMENTED --
|
||||
.label TD1IRQ = $2A4 // -- NOT IMPLEMENTED --
|
||||
.label TLNIDX = $2A5 // -- NOT IMPLEMENTED --
|
||||
.label PALNTSC = $2A6 // 0 = NTSC, 1 = PAL XXX rename to TVSFLG
|
||||
// [!] XXX document $2A7-$2FF usage
|
||||
|
||||
;; 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 TIMOUT $285 ; IEEE-488 timeout
|
||||
|
||||
.alias HIBASE $288 ; high byte of start of screen
|
||||
|
||||
.alias RSSTAT $297 ; RS-232 status
|
||||
|
||||
.alias PALNTSC $2A6 ; 0 = NTSC, 1 = PAL
|
||||
// BASIC vectors
|
||||
.label IERROR = $300 // $300-$301 -- NOT IMPLEMENTED --
|
||||
.label IMAIN = $302 // $302-$303 -- NOT IMPLEMENTED --
|
||||
.label ICRNCH = $304 // $304-$305 -- NOT IMPLEMENTED --
|
||||
.label IQPLOP = $306 // $306-$307 -- NOT IMPLEMENTED --
|
||||
.label IGONE = $308 // $308-$309 -- NOT IMPLEMENTED --
|
||||
.label IEVAL = $30A // $30A-$30B -- NOT IMPLEMENTED --
|
||||
|
||||
|
||||
;; Registers for SYS call
|
||||
.alias SAREG $30C
|
||||
.alias SXREG $30D
|
||||
.alias SYREG $30E
|
||||
.alias SPREG $30F
|
||||
.label SAREG = $30C // .A storage, for SYS call
|
||||
.label SXREG = $30D // .X storage, for SYS call
|
||||
.label SYREG = $30E // .Y storage, for SYS call
|
||||
.label SPREG = $30F // .P storage, for SYS call
|
||||
|
||||
.alias USRPOK $310 ; JMP instruction
|
||||
.alias USRADD $311 ; $311 - $312
|
||||
.label USRPOK = $310 // -- NOT IMPLEMENTED -- JMP instruction
|
||||
.label USRADD = $311 // $311-$312 -- NOT IMPLEMENTED --
|
||||
// $313 -- UNUSED -- free for user software
|
||||
|
||||
;; Kernal vectors - interrupts
|
||||
.alias CINV $314
|
||||
.alias CBINV $316
|
||||
.alias NMINV $318
|
||||
// Kernal vectors - interrupts
|
||||
.label CINV = $314 // $314-$315
|
||||
.label CBINV = $316 // $316-$317
|
||||
.label NMINV = $318 // $318-$319
|
||||
|
||||
;; 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
|
||||
// Kernal vectors - routines
|
||||
.label IOPEN = $31A // $31A-$31B
|
||||
.label ICLOSE = $31C // $31C-$31D
|
||||
.label ICHKIN = $31E // $31E-$31F
|
||||
.label ICKOUT = $320 // $320-$321
|
||||
.label ICLRCH = $322 // $322-$323
|
||||
.label IBASIN = $324 // $324-$325
|
||||
.label IBSOUT = $326 // $326-$327
|
||||
.label ISTOP = $328 // $328-$329
|
||||
.label IGETIN = $32A // $32A-$32B
|
||||
.label ICLALL = $32C // $32C-$32D
|
||||
.label USRCMD = $32E // $32E-$32F
|
||||
.label ILOAD = $330 // $330-$331
|
||||
.label ISAVE = $332 // $332-$333
|
||||
|
||||
.alias TBUFFR $33C ; $33C-$3FB, tape buffer
|
||||
// $314 $334-$33B -- UNUSED -- free for user software
|
||||
|
||||
.label TBUFFR = $33C // $33C-$3FB, -- NOT IMPLEMENTED --, tape buffer
|
||||
|
||||
// $3FC $3FC-$3FF -- UNUSED -- free for user software
|
||||
@@ -1,5 +1,4 @@
|
||||
|
||||
;; BASIC startup vector
|
||||
|
||||
.alias IBASIC_COLD_START $A000
|
||||
.alias IBASIC_WARM_START $A002
|
||||
// BASIC startup vectors
|
||||
.label IBASIC_COLD_START = $A000
|
||||
.label IBASIC_WARM_START = $A002
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
;; Cartridge ROM locations
|
||||
.alias ICART_COLD_START $8000 ; $8000-$8001, cartridge cold start vector
|
||||
.alias ICART_WARM_START $8002 ; $8002-$8003, cartridge warm start vector (RESTORE key)
|
||||
.alias CART_SIG $8004 ; 5 bytes, signature for cartridge detection
|
||||
// Cartridge ROM locations
|
||||
.label ICART_COLD_START = $8000 // $8000-$8001, cartridge cold start vector
|
||||
.label ICART_WARM_START = $8002 // $8002-$8003, cartridge warm start vector (RESTORE key)
|
||||
.label CART_SIG = $8004 // $8004-$8008, signature for cartridge detection
|
||||
@@ -1,41 +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
|
||||
// Kernal jump table
|
||||
.label JCINT = $FF81
|
||||
.label JIOINIT = $FF84
|
||||
.label JRAMTAS = $FF87
|
||||
.label JRESTOR = $FF8A
|
||||
.label JVECTOR = $FF8D
|
||||
.label JSETMSG = $FF90
|
||||
.label JSECOND = $FF93
|
||||
.label JTKSA = $FF96
|
||||
.label JMEMTOP = $FF99
|
||||
.label JMEMBOT = $FF9C
|
||||
.label JSCNKEY = $FF9F
|
||||
.label JSETTMO = $FFA2
|
||||
.label JACPTR = $FFA5
|
||||
.label JCIOUT = $FFA8
|
||||
.label JUNTLK = $FFAB
|
||||
.label JUNLSN = $FFAE
|
||||
.label JLISTEN = $FFB1
|
||||
.label JTALK = $FFB4
|
||||
.label JREADST = $FFB7
|
||||
.label JSETFLS = $FFBA
|
||||
.label JSETNAM = $FFBD
|
||||
.label JOPEN = $FFC0
|
||||
.label JCLOSE = $FFC3
|
||||
.label JCHKIN = $FFC6
|
||||
.label JCKOUT = $FFC9
|
||||
.label JCLRCHN = $FFCC
|
||||
.label JCHRIN = $FFCF
|
||||
.label JCHROUT = $FFD2
|
||||
.label JLOAD = $FFD5
|
||||
.label JSAVE = $FFD8
|
||||
.label JSETTIM = $FFDB
|
||||
.label JRDTIM = $FFDE
|
||||
.label JSTOP = $FFE1
|
||||
.label JGETIN = $FFE4
|
||||
.label JCLALL = $FFE7
|
||||
.label JUDTIM = $FFEA
|
||||
.label JSCREEN = $FFED
|
||||
.label JPLOT = $FFF0
|
||||
.label JIOBASE = $FFF3
|
||||
+116
-114
@@ -1,126 +1,128 @@
|
||||
; Names of ZP and low memory locations
|
||||
; (Only those for now that we feel the need to implement initially)
|
||||
; (https://www.c64-wiki.com/wiki/Zeropage)
|
||||
// Names of ZP and low memory locations
|
||||
// (Only those for now that we feel the need to implement initially)
|
||||
// (https://www.c64-wiki.com/wiki/Zeropage)
|
||||
|
||||
.alias tokenise_work1 $7
|
||||
.alias tokenise_work2 $8
|
||||
.alias tokenise_work3 $B
|
||||
.alias tokenise_work4 $F
|
||||
.alias basic_line_number $14
|
||||
.alias temp_string_ptr $35
|
||||
.alias load_or_verify_or_tokenise_work5 $C
|
||||
.alias basic_work22 $22
|
||||
.alias basic_work23 $23
|
||||
.alias basic_work24 $24
|
||||
.alias basic_work25 $25
|
||||
// XXX get rid of this file, use ,aliases_ram_lowmem.s instead
|
||||
|
||||
;; The various pointers that separate memory regions for BASIC storage
|
||||
;; We have multiple names for the ones that mark the boundary of regions.
|
||||
.alias basic_start_of_text_ptr $2b
|
||||
.alias basic_end_of_text_ptr $2d
|
||||
.alias basic_start_of_vars_ptr $2d
|
||||
.alias basic_end_of_vars_ptr $2f
|
||||
.alias basic_start_of_arrays_ptr $2f
|
||||
.alias basic_end_of_arrays_ptr $31
|
||||
.alias basic_start_of_free_space_ptr $31
|
||||
.alias basic_start_of_strings_ptr $33
|
||||
.alias basic_top_of_memory_ptr $37
|
||||
.alias basic_current_line_number $39
|
||||
.alias basic_previous_line_number $3b
|
||||
.alias basic_current_line_ptr $3d
|
||||
.label tokenise_work1 = $7
|
||||
.label tokenise_work2 = $8
|
||||
.label tokenise_work3 = $B
|
||||
.label tokenise_work4 = $F
|
||||
.label basic_line_number = $14
|
||||
.label temp_string_ptr = $35
|
||||
.label load_or_verify_or_tokenise_work5 = $C
|
||||
.label basic_work22 = $22
|
||||
.label basic_work23 = $23
|
||||
.label basic_work24 = $24
|
||||
.label basic_work25 = $25
|
||||
|
||||
;; Note that the statement point is in the CHRGET/CHRGOT routine
|
||||
;; in ZP RAM. (Compute's Mapping the 64, p25)
|
||||
.alias basic_current_statement_ptr $7a
|
||||
// The various pointers that separate memory regions for BASIC storage
|
||||
// We have multiple names for the ones that mark the boundary of regions.
|
||||
.label basic_start_of_text_ptr = $2b
|
||||
.label basic_end_of_text_ptr = $2d
|
||||
.label basic_start_of_vars_ptr = $2d
|
||||
.label basic_end_of_vars_ptr = $2f
|
||||
.label basic_start_of_arrays_ptr = $2f
|
||||
.label basic_end_of_arrays_ptr = $31
|
||||
.label basic_start_of_free_space_ptr = $31
|
||||
.label basic_start_of_strings_ptr = $33
|
||||
.label basic_top_of_memory_ptr = $37
|
||||
.label basic_current_line_number = $39
|
||||
.label basic_previous_line_number = $3b
|
||||
.label basic_current_line_ptr = $3d
|
||||
|
||||
// Note that the statement point is in the CHRGET/CHRGOT routine
|
||||
// in ZP RAM. (Compute's Mapping the 64, p25)
|
||||
.label basic_current_statement_ptr = $7a
|
||||
|
||||
.alias basic_numeric_work_area $57 ; $57 - $60 inclusive = 10 bytes
|
||||
.label basic_numeric_work_area = $57 // $57 - $60 inclusive = 10 bytes
|
||||
|
||||
;; Floating point accumulator 1 $61 - $68
|
||||
.alias basic_fac1_exponent $61
|
||||
.alias basic_fac1_mantissa $62 ; $62 - $65
|
||||
.alias basic_fac1_sign $66
|
||||
.alias basic_fac1_overflow $68
|
||||
.alias basic_fac1_mantissa_lob $70
|
||||
// Floating point accumulator 1 $61 - $68
|
||||
.label basic_fac1_exponent = $61
|
||||
.label basic_fac1_mantissa = $62 // $62 - $65
|
||||
.label basic_fac1_sign = $66
|
||||
.label basic_fac1_overflow = $68
|
||||
.label basic_fac1_mantissa_lob = $70
|
||||
|
||||
.alias basic_fac2_exponent $69
|
||||
.alias basic_fac2_mantissa $6A ; $6A - $6D
|
||||
.alias basic_fac2_sign $6E
|
||||
.label basic_fac2_exponent = $69
|
||||
.label basic_fac2_mantissa = $6A // $6A - $6D
|
||||
.label basic_fac2_sign = $6E
|
||||
|
||||
;; We also re-use FAC2 for memory move pointers, since
|
||||
;; we can't be doing calculations while moving memory
|
||||
.alias memmove_src $69
|
||||
.alias memmove_dst $6b
|
||||
.alias memmove_size $6d
|
||||
// We also re-use FAC2 for memory move pointers, since
|
||||
// we can't be doing calculations while moving memory
|
||||
.label memmove_src = $69
|
||||
.label memmove_dst = $6b
|
||||
.label memmove_size = $6d
|
||||
|
||||
.alias current_file_num $98
|
||||
.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
|
||||
.label current_file_num = $98
|
||||
.label cassette_buffer_bytes_used = $A6
|
||||
.label load_or_scroll_temp_pointer = $AC
|
||||
// We also use the following for temp colour pointer when scrolling
|
||||
.label load_save_verify_end_address = $AE
|
||||
|
||||
.alias cassette_buffer_ptr $B2
|
||||
.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
|
||||
.alias reverse_video_flag $C7
|
||||
.alias end_of_input_line $C8
|
||||
.alias start_of_keyboard_input $C9
|
||||
.alias current_key_index_entry $CB
|
||||
.alias cursor_blink_disable $CC
|
||||
.alias cursor_blink_countdown $CD
|
||||
.alias cursor_saved_character $CE
|
||||
.alias cursor_is_visible $CF
|
||||
.alias keyboard_input_ready $D0
|
||||
.alias current_screen_line_ptr $D1
|
||||
.alias current_screen_x $D3
|
||||
.alias quote_mode_flag $D4
|
||||
.alias logical_line_length $D5
|
||||
.alias current_screen_y $D6
|
||||
.alias last_printed_character_ascii $D7
|
||||
.alias insert_mode $D8
|
||||
; Bits 0 -3 = bits 8-11 of screen line address
|
||||
; Bit 7 = line spans multiple physical lines
|
||||
.alias screen_line_link_table $D9
|
||||
.alias current_screen_line_colour_ptr $F3
|
||||
.alias keyboard_decoding_table_ptr $F5
|
||||
.alias rs232_rx_buffer_ptr $F7
|
||||
.alias rs232_tx_buffer_ptr $F9
|
||||
.label cassette_buffer_ptr = $B2
|
||||
.label current_logical_filenum = $B8
|
||||
.label current_secondary_address = $B9
|
||||
.label current_device_number = $BA
|
||||
.label current_filename_ptr = $BB
|
||||
.label load_save_start_ptr = $C1
|
||||
.label load_save_end_ptr = $C3
|
||||
.label last_key_matrix_position = $C5
|
||||
.label keys_in_key_buffer = $C6
|
||||
.label reverse_video_flag = $C7
|
||||
.label end_of_input_line = $C8
|
||||
.label start_of_keyboard_input = $C9
|
||||
.label current_key_index_entry = $CB
|
||||
.label cursor_blink_disable = $CC
|
||||
.label cursor_blink_countdown = $CD
|
||||
.label cursor_saved_character = $CE
|
||||
.label cursor_is_visible = $CF
|
||||
.label keyboard_input_ready = $D0
|
||||
.label current_screen_line_ptr = $D1
|
||||
.label current_screen_x = $D3
|
||||
.label quote_mode_flag = $D4
|
||||
.label logical_line_length = $D5
|
||||
.label current_screen_y = $D6
|
||||
.label last_printed_character_ascii = $D7
|
||||
.label insert_mode = $D8
|
||||
// Bits 0 -3 = bits 8-11 of screen line address
|
||||
// Bit 7 = line spans multiple physical lines
|
||||
.label screen_line_link_table = $D9
|
||||
.label current_screen_line_colour_ptr = $F3
|
||||
.label keyboard_decoding_table_ptr = $F5
|
||||
.label rs232_rx_buffer_ptr = $F7
|
||||
.label rs232_tx_buffer_ptr = $F9
|
||||
|
||||
.alias basic_input_buffer BUF
|
||||
|
||||
; "Compute's Mapping the 64" book
|
||||
.alias keyboard_buffer $0277
|
||||
.alias text_colour $0286 ; p55
|
||||
.alias colour_under_cursor $0287 ; p56
|
||||
.alias key_buffer_size $0289 ; p57
|
||||
.label basic_input_buffer = BUF
|
||||
|
||||
;; 0 = cursor keys, insert, delete and space repeat, but nothing else
|
||||
;; 128 = all keys repeat
|
||||
;; 64 = no keys repeat
|
||||
.alias key_repeat_flags $028A ; p58
|
||||
;; https://www.c64-wiki.com/wiki/Page_2
|
||||
.alias key_repeat_counter $028B
|
||||
.alias key_first_repeat_delay $028C
|
||||
;; bit 0 = shift, 1 = Vendor Key, 2 = Control
|
||||
.alias key_bucky_state $028D
|
||||
.alias key_last_bucky_state $028E
|
||||
.alias keyboard_decoding_ptr $028F
|
||||
.alias enable_case_switch $0291
|
||||
.alias screen_scroll_disable $0292
|
||||
// "Compute's Mapping the 64" book
|
||||
.label keyboard_buffer = $0277
|
||||
.label text_colour = $0286 // p55
|
||||
.label colour_under_cursor = $0287 // p56
|
||||
.label key_buffer_size = $0289 // p57
|
||||
|
||||
;; 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
|
||||
;; a counter, so that if an NMI occurs, it doesn't crash the machine, but can be captured.
|
||||
.alias missed_nmi_flag $2A7
|
||||
.alias tiny_nmi_handler $2A8
|
||||
.alias shift_mem_up tiny_nmi_handler+shift_mem_up_routine-tiny_nmi_handler_routine
|
||||
.alias shift_mem_down tiny_nmi_handler+shift_mem_down_routine-tiny_nmi_handler_routine
|
||||
.alias peek_under_roms tiny_nmi_handler+peek_under_roms_routine-tiny_nmi_handler_routine
|
||||
.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 = cursor keys, insert, delete and space repeat, but nothing else
|
||||
// 128 = all keys repeat
|
||||
// 64 = no keys repeat
|
||||
.label key_repeat_flags = $028A // p58
|
||||
// https://www.c64-wiki.com/wiki/Page_2
|
||||
.label key_repeat_counter = $028B
|
||||
.label key_first_repeat_delay = $028C
|
||||
// bit 0 = shift, 1 = Vendor Key, 2 = Control
|
||||
.label key_bucky_state = $028D
|
||||
.label key_last_bucky_state = $028E
|
||||
.label keyboard_decoding_ptr = $028F
|
||||
.label enable_case_switch = $0291
|
||||
.label screen_scroll_disable = $0292
|
||||
|
||||
// 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
|
||||
// a counter, so that if an NMI occurs, it doesn't crash the machine, but can be captured.
|
||||
.label missed_nmi_flag = $2A7
|
||||
.label tiny_nmi_handler = $2A8
|
||||
.label shift_mem_up = tiny_nmi_handler+shift_mem_up_routine-tiny_nmi_handler_routine
|
||||
.label shift_mem_down = tiny_nmi_handler+shift_mem_down_routine-tiny_nmi_handler_routine
|
||||
.label peek_under_roms = tiny_nmi_handler+peek_under_roms_routine-tiny_nmi_handler_routine
|
||||
.label poke_under_roms = tiny_nmi_handler+poke_under_roms_routine-tiny_nmi_handler_routine
|
||||
.label memmap_allram = tiny_nmi_handler+memmap_allram_routine-tiny_nmi_handler_routine
|
||||
.label memmap_normal = tiny_nmi_handler+memmap_normal_routine-tiny_nmi_handler_routine
|
||||
@@ -1,9 +1,10 @@
|
||||
|
||||
;; Target-specific hooks
|
||||
// Target-specific hooks
|
||||
|
||||
|
||||
.macro TARGET_HOOK_BANNER
|
||||
.macro TARGET_HOOK_BANNER() {
|
||||
|
||||
.byte " OPEN ROMS, ", $00
|
||||
.text " OPEN ROMS, "
|
||||
.byte $00
|
||||
|
||||
.macend
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
|
||||
;; Target-specific hooks
|
||||
// Target-specific hooks
|
||||
|
||||
|
||||
.macro TARGET_HOOK_BANNER
|
||||
.macro TARGET_HOOK_BANNER() {
|
||||
|
||||
;; New banner from Retrofan
|
||||
// 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
|
||||
@@ -21,21 +21,21 @@
|
||||
.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
|
||||
// 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
|
||||
}
|
||||
@@ -1,9 +1,12 @@
|
||||
|
||||
;; Target-specific hooks
|
||||
// Target-specific hooks
|
||||
|
||||
|
||||
.macro TARGET_HOOK_BANNER
|
||||
.macro TARGET_HOOK_BANNER() {
|
||||
|
||||
.byte " OPEN ROMS FOR ULTIMATE 64", $0D, $0D, " ", $00
|
||||
.text " OPEN ROMS FOR ULTIMATE 64"
|
||||
.byte $0D, $0D
|
||||
.text " "
|
||||
.byte $00
|
||||
|
||||
.macend
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
;; Compute's Mapping the C64 p88
|
||||
// Compute's Mapping the C64 p88
|
||||
|
||||
.word basic_cold_start
|
||||
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
;; Compute's Mapping the C64 p88
|
||||
// Compute's Mapping the C64 p88
|
||||
|
||||
.word basic_warm_start
|
||||
@@ -1,6 +1,6 @@
|
||||
;; Compute's Mapping the 64, p89
|
||||
;; 8 character name
|
||||
;; MEGABAS2 = "MEGA BASIC 2"
|
||||
// Compute's Mapping the 64, p89
|
||||
// 8 character name
|
||||
// MEGABAS2 = "MEGA BASIC 2"
|
||||
|
||||
.byte $4D,$45,$47,$41,$42,$41,$53,$32
|
||||
|
||||
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
;; Print string at $YYAA
|
||||
;; Compute's Mapping the 64 p101
|
||||
// Print string at $YYAA
|
||||
// Compute's Mapping the 64 p101
|
||||
|
||||
print_string:
|
||||
;; Setup pointer
|
||||
// Setup pointer
|
||||
sty temp_string_ptr+1
|
||||
sta temp_string_ptr+0
|
||||
|
||||
txa
|
||||
txa
|
||||
pha
|
||||
|
||||
;; Get offset ready
|
||||
// Get offset ready
|
||||
ldy #$00
|
||||
|
||||
print_string_loop:
|
||||
;; Save Y in X, since X is preserved by chrout, but Y is not
|
||||
// Save Y in X, since X is preserved by chrout, but Y is not
|
||||
tya
|
||||
tax
|
||||
|
||||
@@ -28,7 +28,6 @@ print_string_loop:
|
||||
iny
|
||||
bne print_string_loop
|
||||
|
||||
|
||||
print_string_end:
|
||||
|
||||
pla
|
||||
|
||||
@@ -1,31 +1,31 @@
|
||||
;; BASIC Cold start entry point
|
||||
;; Compute's Mapping the 64 p211
|
||||
// BASIC Cold start entry point
|
||||
// Compute's Mapping the 64 p211
|
||||
|
||||
basic_cold_start:
|
||||
;; Setup BASIC vectors at $0300
|
||||
;; Initialise interpretor
|
||||
;; Print start up message
|
||||
// Setup BASIC vectors at $0300
|
||||
// Initialise interpretor
|
||||
// Print start up message
|
||||
|
||||
;; Print coloured part of the message
|
||||
;; ldy #>startup_message
|
||||
;; lda #<startup_message
|
||||
;; jsr print_string
|
||||
// Print coloured part of the message
|
||||
// ldy #>startup_message
|
||||
// lda #<startup_message
|
||||
// jsr print_string
|
||||
|
||||
jsr printf // XXX don't use printf, keep it for debug purposes only
|
||||
|
||||
jsr printf
|
||||
; Used 217 bytes
|
||||
startup_banner:
|
||||
|
||||
`TARGET_HOOK_BANNER
|
||||
TARGET_HOOK_BANNER()
|
||||
|
||||
;; Print PAL/NTSC
|
||||
ldx #30 ; NTSC
|
||||
// Print PAL/NTSC
|
||||
ldx #30 // NTSC
|
||||
lda PALNTSC
|
||||
beq +
|
||||
ldx #31 ; PAL
|
||||
*
|
||||
beq !+
|
||||
ldx #31 // PAL
|
||||
!:
|
||||
jsr print_packed_message
|
||||
|
||||
;; Work out free bytes, and display
|
||||
// Work out free bytes, and display
|
||||
jsr basic_do_new
|
||||
lda basic_top_of_memory_ptr+0
|
||||
sec
|
||||
@@ -39,22 +39,21 @@ startup_banner:
|
||||
lda #$20
|
||||
jsr JCHROUT
|
||||
|
||||
;; Print the rest of the start up message
|
||||
// Print the rest of the start up message
|
||||
ldx #34
|
||||
jsr print_packed_message
|
||||
|
||||
;; jump into warm start loop
|
||||
// jump into warm start loop
|
||||
jmp basic_warm_start
|
||||
|
||||
|
||||
startup_message:
|
||||
;; Clear the screen
|
||||
startup_message: // XXX this is probably not needed anymore
|
||||
// Clear the screen
|
||||
.byte $93
|
||||
;; Vertical bars in different colours
|
||||
// Vertical bars in different colours
|
||||
.byte $1C,$B4
|
||||
.byte $9E,$B5
|
||||
.byte $1E,$A1
|
||||
;; <RVS><WHITE>MEGA<NORMAL>BASIC\r\r
|
||||
// <RVS><WHITE>MEGA<NORMAL>BASIC\r\r
|
||||
.byte $12,$05,$4D,$45,$47,$41,$92
|
||||
.byte $42,$41,$53,$49,$43
|
||||
.byte $20,$56,$32,$2e,$30,$2e,$30
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
;; Delete the current BASIC line, which is assumed to have already
|
||||
;; been found with basic_find_line.
|
||||
;; Really only consists of copying memory down.
|
||||
;; The only complication is that we have to do the copy with ROMs
|
||||
;; banked out. Oh, yes, and we have to update all the links in
|
||||
;; the following basic lines.
|
||||
// Delete the current BASIC line, which is assumed to have already
|
||||
// been found with basic_find_line.
|
||||
// Really only consists of copying memory down.
|
||||
// The only complication is that we have to do the copy with ROMs
|
||||
// banked out. Oh, yes, and we have to update all the links in
|
||||
// the following basic lines.
|
||||
|
||||
basic_delete_line:
|
||||
|
||||
;; jsr printf
|
||||
;; .byte "DELETING LINE AT $"
|
||||
;; .byte $f1,<basic_current_line_ptr,>basic_current_line_ptr
|
||||
;; .byte $f0,<basic_current_line_ptr,>basic_current_line_ptr
|
||||
;; .byte $0d,0
|
||||
// jsr printf
|
||||
// .text "DELETING LINE AT $"
|
||||
// .byte $f1,<basic_current_line_ptr,>basic_current_line_ptr
|
||||
// .byte $f0,<basic_current_line_ptr,>basic_current_line_ptr
|
||||
// .byte $0d,0
|
||||
|
||||
;; Get address of next line
|
||||
// Get address of next line
|
||||
ldx #<basic_current_line_ptr
|
||||
ldy #0
|
||||
jsr peek_under_roms
|
||||
@@ -21,7 +22,7 @@ basic_delete_line:
|
||||
jsr peek_under_roms
|
||||
sta tokenise_work4
|
||||
|
||||
;; Work out length of this line by looking at the pointer
|
||||
// Work out length of this line by looking at the pointer
|
||||
lda tokenise_work3
|
||||
sec
|
||||
sbc basic_current_line_ptr+0
|
||||
@@ -30,31 +31,31 @@ basic_delete_line:
|
||||
sbc basic_current_line_ptr+1
|
||||
sta tokenise_work4
|
||||
|
||||
;; jsr printf
|
||||
;; .byte "LINE LENGTH IS $"
|
||||
;; .byte $f0,<tokenise_work4,>tokenise_work4
|
||||
;; .byte $f0,<tokenise_work3,>tokenise_work3
|
||||
;; .byte $0d,0
|
||||
// jsr printf
|
||||
// .text "LINE LENGTH IS $"
|
||||
// .byte $f0,<tokenise_work4,>tokenise_work4
|
||||
// .byte $f0,<tokenise_work3,>tokenise_work3
|
||||
// .byte $0d,0
|
||||
|
||||
lda tokenise_work4
|
||||
sbc #0
|
||||
cmp #$00
|
||||
beq +
|
||||
;; Line length is <0 or >255 bytes.
|
||||
;; Either way, things are bad, so abort.
|
||||
beq !+
|
||||
// Line length is <0 or >255 bytes.
|
||||
// Either way, things are bad, so abort.
|
||||
jmp do_MEMORY_CORRUPT_error
|
||||
*
|
||||
;; Length can now be safely assumed to be in the low
|
||||
;; byte only, i.e., stored in tokenise_work3
|
||||
!:
|
||||
// Length can now be safely assumed to be in the low
|
||||
// byte only, i.e., stored in tokenise_work3
|
||||
|
||||
lda tokenise_work3
|
||||
pha
|
||||
tax
|
||||
|
||||
;; Shuffle everything down
|
||||
// Shuffle everything down
|
||||
jsr basic_shift_mem_down_and_relink
|
||||
|
||||
;; Now decrease top of BASIC mem
|
||||
// Now decrease top of BASIC mem
|
||||
pla
|
||||
sta tokenise_work3
|
||||
lda basic_end_of_text_ptr+0
|
||||
|
||||
+13
-16
@@ -1,40 +1,37 @@
|
||||
;; Compute's Mapping the 64 p93
|
||||
// Compute's Mapping the 64 p93
|
||||
|
||||
basic_do_error:
|
||||
;; Save error number
|
||||
// Save error number
|
||||
txa
|
||||
pha
|
||||
|
||||
;; Print ? at start
|
||||
lda #$0d
|
||||
// Print ? at start
|
||||
lda #$0D
|
||||
jsr JCHROUT
|
||||
lda #$3f
|
||||
lda #$3F
|
||||
jsr JCHROUT
|
||||
|
||||
;; Print main part of error message
|
||||
// Print main part of error message
|
||||
pla
|
||||
tax
|
||||
jsr print_packed_message
|
||||
|
||||
;; Print ERROR at end
|
||||
// Print ERROR at end
|
||||
lda #$20
|
||||
jsr JCHROUT
|
||||
ldx #33
|
||||
jsr print_packed_message
|
||||
|
||||
;; XXX print IN if not in direct mode
|
||||
// XXX print IN if not in direct mode
|
||||
|
||||
;; XXX print line number if not in direct mode
|
||||
// XXX print line number if not in direct mode
|
||||
|
||||
lda #$0d
|
||||
lda #$0D
|
||||
jsr JCHROUT
|
||||
lda #$0d
|
||||
lda #$0D // XXX do we need this?
|
||||
jsr JCHROUT
|
||||
|
||||
;; Reset stack, and go back to main loop
|
||||
ldx #$fe
|
||||
// Reset stack, and go back to main loop
|
||||
ldx #$FE
|
||||
txs
|
||||
jmp basic_main_loop
|
||||
|
||||
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
;; Jump back into the BASIC execute line loop
|
||||
;; after first checking that we have a colon
|
||||
;; or $00 char
|
||||
// Jump back into the BASIC execute line loop
|
||||
// after first checking that we have a colon
|
||||
// or $00 char
|
||||
|
||||
basic_end_of_statement_check:
|
||||
ldx #<basic_current_statement_ptr
|
||||
ldy #0
|
||||
jsr peek_under_roms
|
||||
|
||||
;; Consume any spaces
|
||||
// Consume any spaces
|
||||
cmp #$20
|
||||
bne no_space_to_skip
|
||||
jsr basic_consume_character
|
||||
@@ -15,62 +15,62 @@ basic_end_of_statement_check:
|
||||
|
||||
no_space_to_skip:
|
||||
cmp #$00
|
||||
beq +
|
||||
beq !+
|
||||
cmp #$3a
|
||||
beq +
|
||||
beq !+
|
||||
|
||||
;; not end of statement
|
||||
// not end of statement
|
||||
clc
|
||||
rts
|
||||
*
|
||||
!:
|
||||
sec
|
||||
rts
|
||||
|
||||
basic_execute_statement:
|
||||
|
||||
;; Check for RUN/STOP
|
||||
// Check for RUN/STOP
|
||||
lda STKEY
|
||||
bmi +
|
||||
bmi !+
|
||||
jmp basic_do_break
|
||||
*
|
||||
;; Skip over any white space and :
|
||||
!:
|
||||
// Skip over any white space and :
|
||||
ldy #0
|
||||
ldx #<basic_current_statement_ptr
|
||||
jsr peek_under_roms
|
||||
jsr basic_end_of_statement_check
|
||||
bcs basic_end_of_line
|
||||
|
||||
;; jsr printf
|
||||
;; .byte "LINE PTR = $"
|
||||
;; .byte $f1,<basic_current_line_ptr,>basic_current_line_ptr
|
||||
;; .byte $f0,<basic_current_line_ptr,>basic_current_line_ptr
|
||||
;; .byte ", STATEMENT PTR = $"
|
||||
;; .byte $f1,<basic_current_statement_ptr,>basic_current_statement_ptr
|
||||
;; .byte $f0,<basic_current_statement_ptr,>basic_current_statement_ptr
|
||||
;; .byte $d,0
|
||||
// jsr printf
|
||||
// .text "LINE PTR = $"
|
||||
// .byte $f1,<basic_current_line_ptr,>basic_current_line_ptr
|
||||
// .byte $f0,<basic_current_line_ptr,>basic_current_line_ptr
|
||||
// .text ", STATEMENT PTR = $"
|
||||
// .byte $f1,<basic_current_statement_ptr,>basic_current_statement_ptr
|
||||
// .byte $f0,<basic_current_statement_ptr,>basic_current_statement_ptr
|
||||
// .byte $d,0
|
||||
|
||||
;; Go through the line until its end is reached.
|
||||
;; If we reach the end are in direct mode, then
|
||||
;; go back to reading input, else look for the
|
||||
;; next line, and advance to that, or else
|
||||
;; return to READY prompt because we have run out
|
||||
;; of program.
|
||||
// Go through the line until its end is reached.
|
||||
// If we reach the end are in direct mode, then
|
||||
// go back to reading input, else look for the
|
||||
// next line, and advance to that, or else
|
||||
// return to READY prompt because we have run out
|
||||
// of program.
|
||||
|
||||
;; Get next char of program text, even if it is hiding under a ROM or the
|
||||
;; IO area.
|
||||
// Get next char of program text, even if it is hiding under a ROM or the
|
||||
// IO area.
|
||||
ldx #<basic_current_statement_ptr
|
||||
ldy #0
|
||||
jsr peek_under_roms
|
||||
cmp #$00
|
||||
beq basic_end_of_line
|
||||
|
||||
;; The checks should be done in order of frequency, so that we are as
|
||||
;; fast as possible.
|
||||
// The checks should be done in order of frequency, so that we are as
|
||||
// fast as possible.
|
||||
|
||||
cmp #$7f
|
||||
bcc not_a_token
|
||||
;; It's a token: So get the jump table entry for it, push it on the stack
|
||||
;; and then RTS to start it.
|
||||
// It's a token: So get the jump table entry for it, push it on the stack
|
||||
// and then RTS to start it.
|
||||
asl
|
||||
tax
|
||||
lda basic_command_jump_table+1,x
|
||||
@@ -78,42 +78,42 @@ basic_execute_statement:
|
||||
lda basic_command_jump_table+0,x
|
||||
pha
|
||||
|
||||
;; Now consume the character
|
||||
// Now consume the character
|
||||
jsr basic_consume_character
|
||||
|
||||
rts
|
||||
|
||||
not_a_token:
|
||||
;; Space, which we can also just ignore
|
||||
// Space, which we can also just ignore
|
||||
cmp #$20
|
||||
beq basic_skip_char
|
||||
;; End of line?
|
||||
// End of line?
|
||||
cmp #$00
|
||||
beq basic_end_of_line
|
||||
;; :, i.e., statement separator, which we can simply ignore
|
||||
// :, i.e., statement separator, which we can simply ignore
|
||||
cmp #$3a
|
||||
beq basic_skip_char
|
||||
|
||||
;; START wedge support
|
||||
// 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
|
||||
// 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?
|
||||
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 +
|
||||
bne !+
|
||||
jsr basic_consume_character
|
||||
jmp wedge_dos
|
||||
*
|
||||
;; END wedge support
|
||||
!:
|
||||
// END wedge support
|
||||
|
||||
;; If all else fails, it's a syntax error
|
||||
// If all else fails, it's a syntax error
|
||||
jmp do_SYNTAX_error
|
||||
|
||||
basic_skip_char:
|
||||
@@ -124,14 +124,14 @@ basic_fetch_and_consume_character:
|
||||
ldy #0
|
||||
ldx #<basic_current_statement_ptr
|
||||
jsr peek_under_roms
|
||||
;; FALL THROUGH
|
||||
// FALL THROUGH
|
||||
|
||||
basic_consume_character:
|
||||
;; Advance basic text pointer
|
||||
// Advance basic text pointer
|
||||
inc basic_current_statement_ptr+0
|
||||
bne +
|
||||
bne !+
|
||||
inc basic_current_statement_ptr+1
|
||||
*
|
||||
!:
|
||||
rts
|
||||
|
||||
basic_unconsume_character:
|
||||
@@ -146,46 +146,46 @@ basic_unconsume_character:
|
||||
|
||||
basic_end_of_line:
|
||||
|
||||
;; XXX - If not in direct mode, then advance to next line, if there is
|
||||
;; one.
|
||||
// XXX - If not in direct mode, then advance to next line, if there is
|
||||
// one.
|
||||
|
||||
;; Are we in direct mode
|
||||
// Are we in direct mode
|
||||
lda basic_current_line_number+1
|
||||
cmp #$ff
|
||||
bne basic_not_direct_mode
|
||||
|
||||
;; Yes, we were in direct mode, so stop now
|
||||
// Yes, we were in direct mode, so stop now
|
||||
jmp basic_main_loop
|
||||
|
||||
basic_not_direct_mode:
|
||||
;; Copy line number to previous line number
|
||||
// Copy line number to previous line number
|
||||
lda basic_current_line_number+0
|
||||
sta basic_previous_line_number+0
|
||||
lda basic_current_line_number+1
|
||||
sta basic_previous_line_number+1
|
||||
|
||||
;; Advance the basic line pointer to the next line
|
||||
// Advance the basic line pointer to the next line
|
||||
jsr basic_follow_link_to_next_line
|
||||
|
||||
;; Are we at the end of the program?
|
||||
// Are we at the end of the program?
|
||||
lda basic_current_line_ptr+0
|
||||
ora basic_current_line_ptr+1
|
||||
bne basic_execute_from_current_line
|
||||
|
||||
;; End of program found
|
||||
// End of program found
|
||||
jmp basic_main_loop
|
||||
|
||||
basic_execute_from_current_line:
|
||||
;; Check if pointer is null, if so, we are at the end of
|
||||
;; the program.
|
||||
// Check if pointer is null, if so, we are at the end of
|
||||
// the program.
|
||||
ldy #0
|
||||
ldx #<basic_current_line_ptr
|
||||
jsr peek_pointer_null_check
|
||||
bcs +
|
||||
;; End of program reached
|
||||
bcs !+
|
||||
// End of program reached
|
||||
jmp basic_main_loop
|
||||
*
|
||||
;; Skip pointer and line number to get address of first statement
|
||||
!:
|
||||
// Skip pointer and line number to get address of first statement
|
||||
lda basic_current_line_ptr+0
|
||||
clc
|
||||
adc #4
|
||||
@@ -194,7 +194,7 @@ basic_execute_from_current_line:
|
||||
adc #0
|
||||
sta basic_current_statement_ptr+1
|
||||
|
||||
;; Store line number
|
||||
// Store line number
|
||||
ldx #<basic_current_line_ptr
|
||||
ldy #2
|
||||
jsr peek_under_roms
|
||||
@@ -206,7 +206,7 @@ basic_execute_from_current_line:
|
||||
jmp basic_execute_statement
|
||||
|
||||
basic_command_jump_table:
|
||||
;; $80 - $8F
|
||||
// $80 - $8F
|
||||
.word cmd_end-1
|
||||
.word cmd_for-1
|
||||
.word cmd_next-1
|
||||
@@ -221,10 +221,10 @@ basic_command_jump_table:
|
||||
.word cmd_if-1
|
||||
.word cmd_restore-1
|
||||
.word cmd_gosub-1
|
||||
.word cmd_return -1
|
||||
.word cmd_return-1
|
||||
.word cmd_rem-1
|
||||
|
||||
;; $90-$9F
|
||||
// $90-$9F
|
||||
.word cmd_stop-1
|
||||
.word cmd_on-1
|
||||
.word cmd_wait-1
|
||||
@@ -242,7 +242,7 @@ basic_command_jump_table:
|
||||
.word cmd_sys-1
|
||||
.word cmd_open-1
|
||||
|
||||
;; $A0-$AF
|
||||
// $A0-$AF
|
||||
.word cmd_close-1
|
||||
.word cmd_get-1
|
||||
.word cmd_new-1
|
||||
@@ -260,7 +260,7 @@ basic_command_jump_table:
|
||||
.word cmd_exponent-1
|
||||
.word cmd_and-1
|
||||
|
||||
;; $B0-$BF
|
||||
// $B0-$BF
|
||||
.word cmd_or-1
|
||||
.word cmd_greater-1
|
||||
.word cmd_equal-1
|
||||
@@ -278,7 +278,7 @@ basic_command_jump_table:
|
||||
.word cmd_cos-1
|
||||
.word cmd_sin-1
|
||||
|
||||
;; $C0-$CF
|
||||
// $C0-$CF
|
||||
.word cmd_tan-1
|
||||
.word cmd_atn-1
|
||||
.word cmd_peek-1
|
||||
@@ -291,13 +291,13 @@ basic_command_jump_table:
|
||||
.word cmd_right-1
|
||||
.word cmd_mid-1
|
||||
.word cmd_go-1
|
||||
;; Undefined tokens
|
||||
// Undefined tokens
|
||||
.word cmd_unimplemented-1
|
||||
.word cmd_unimplemented-1
|
||||
.word cmd_unimplemented-1
|
||||
.word cmd_unimplemented-1
|
||||
|
||||
;; $D0-$DF
|
||||
// $D0-$DF
|
||||
.word cmd_unimplemented-1
|
||||
.word cmd_unimplemented-1
|
||||
.word cmd_unimplemented-1
|
||||
@@ -315,7 +315,7 @@ basic_command_jump_table:
|
||||
.word cmd_unimplemented-1
|
||||
.word cmd_unimplemented-1
|
||||
|
||||
;; $E0-$EF
|
||||
// $E0-$EF
|
||||
.word cmd_unimplemented-1
|
||||
.word cmd_unimplemented-1
|
||||
.word cmd_unimplemented-1
|
||||
@@ -333,7 +333,7 @@ basic_command_jump_table:
|
||||
.word cmd_unimplemented-1
|
||||
.word cmd_unimplemented-1
|
||||
|
||||
;; $F0-$FF
|
||||
// $F0-$FF
|
||||
.word cmd_unimplemented-1
|
||||
.word cmd_unimplemented-1
|
||||
.word cmd_unimplemented-1
|
||||
@@ -350,4 +350,3 @@ basic_command_jump_table:
|
||||
.word cmd_unimplemented-1
|
||||
.word cmd_unimplemented-1
|
||||
.word cmd_unimplemented-1
|
||||
|
||||
+13
-13
@@ -1,50 +1,50 @@
|
||||
;; Find the BASIC line with number basic_line_number
|
||||
// Find the BASIC line with number basic_line_number
|
||||
|
||||
|
||||
basic_find_line:
|
||||
;; Get pointer to start of BASIC text
|
||||
// Get pointer to start of BASIC text
|
||||
lda basic_start_of_text_ptr+0
|
||||
sta basic_current_line_ptr+0
|
||||
lda basic_start_of_text_ptr+1
|
||||
sta basic_current_line_ptr+1
|
||||
|
||||
basic_find_line_loop:
|
||||
;; Then search for line number
|
||||
;; Line number
|
||||
// Then search for line number
|
||||
// Line number
|
||||
|
||||
ldy #3
|
||||
ldx #<basic_current_line_ptr
|
||||
jsr peek_under_roms
|
||||
cmp basic_line_number+1
|
||||
beq +
|
||||
beq !+
|
||||
bcs line_num_too_high
|
||||
bne not_this_line
|
||||
*
|
||||
!:
|
||||
|
||||
dey
|
||||
jsr peek_under_roms
|
||||
cmp basic_line_number+0
|
||||
beq +
|
||||
beq !+
|
||||
bcs line_num_too_high
|
||||
bne not_this_line
|
||||
*
|
||||
!:
|
||||
clc
|
||||
rts
|
||||
not_this_line:
|
||||
;; Not this line, so advance to next line
|
||||
// Not this line, so advance to next line
|
||||
ldx #<basic_current_line_ptr
|
||||
jsr peek_pointer_null_check
|
||||
bcs more_lines_exist
|
||||
|
||||
;; no more lines exist, return failure
|
||||
// no more lines exist, return failure
|
||||
line_num_too_high:
|
||||
sec
|
||||
rts
|
||||
more_lines_exist:
|
||||
|
||||
;; XXX - Add program mangled check here to be triggered
|
||||
;; if the link goes backwards.
|
||||
;; Follow link to next line
|
||||
// XXX - Add program mangled check here to be triggered
|
||||
// if the link goes backwards.
|
||||
// Follow link to next line
|
||||
ldy #0
|
||||
ldx #<basic_current_line_ptr
|
||||
jsr peek_under_roms
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
;; Advance basic_current_line_ptr by following the
|
||||
;; link to the next line
|
||||
// Advance basic_current_line_ptr by following the
|
||||
// link to the next line
|
||||
|
||||
basic_find_next_line:
|
||||
|
||||
|
||||
@@ -1,25 +1,26 @@
|
||||
;; Insert the tokenised line stored at $0200.
|
||||
;; First work out where in the list to put it
|
||||
;; (basic_find_line with the line number can be used to work
|
||||
;; out the insertion point, as it should abort once it finds a
|
||||
;; line number too high).
|
||||
;; Then all we have to do is push the rest of the BASIC text up,
|
||||
;; and update the pointers in all following basic lines.
|
||||
// Insert the tokenised line stored at $0200.
|
||||
// First work out where in the list to put it
|
||||
// (basic_find_line with the line number can be used to work
|
||||
// out the insertion point, as it should abort once it finds a
|
||||
// line number too high).
|
||||
// Then all we have to do is push the rest of the BASIC text up,
|
||||
// and update the pointers in all following basic lines.
|
||||
|
||||
basic_insert_line:
|
||||
|
||||
;; ASSUMES basic_find_line has been called to set the insert point.
|
||||
;; We need to insert space for the link link token, the line number,
|
||||
;; and the zero-terminated line itself. This means 2+2+1 plus length
|
||||
;; of tokenised string after the line number
|
||||
// ASSUMES basic_find_line has been called to set the insert point.
|
||||
// We need to insert space for the link link token, the line number,
|
||||
// and the zero-terminated line itself. This means 2+2+1 plus length
|
||||
// of tokenised string after the line number
|
||||
|
||||
;; But first, remember where the pointer will be, so that we can
|
||||
;; put the line in there after.
|
||||
// But first, remember where the pointer will be, so that we can
|
||||
// put the line in there after.
|
||||
|
||||
;; jsr printf
|
||||
;; .byte "INSERTING LINE AT $"
|
||||
;; .byte $f1,<basic_current_line_ptr,>basic_current_line_ptr
|
||||
;; .byte $f0,<basic_current_line_ptr,>basic_current_line_ptr
|
||||
;; .byte $0d,0
|
||||
// jsr printf
|
||||
// .text "INSERTING LINE AT $"
|
||||
// .byte $f1,<basic_current_line_ptr,>basic_current_line_ptr
|
||||
// .byte $f0,<basic_current_line_ptr,>basic_current_line_ptr
|
||||
// .byte $0d,0
|
||||
|
||||
lda basic_current_line_ptr+0
|
||||
pha
|
||||
@@ -27,20 +28,20 @@ basic_insert_line:
|
||||
|
||||
pha
|
||||
|
||||
;; Get number of bytes in tokenised line after line number
|
||||
// Get number of bytes in tokenised line after line number
|
||||
lda tokenise_work2
|
||||
sec
|
||||
sbc tokenise_work1
|
||||
;; Add on the four bytes space we need
|
||||
// Add on the four bytes space we need
|
||||
clc
|
||||
adc #5
|
||||
pha
|
||||
tax
|
||||
|
||||
;; Make the space
|
||||
// Make the space
|
||||
jsr basic_shift_mem_up_and_relink
|
||||
|
||||
;; Now increase top of BASIC mem
|
||||
// Now increase top of BASIC mem
|
||||
pla
|
||||
clc
|
||||
adc basic_end_of_text_ptr+0
|
||||
@@ -49,13 +50,13 @@ basic_insert_line:
|
||||
adc #0
|
||||
sta basic_end_of_text_ptr+1
|
||||
|
||||
;; Get pointer back
|
||||
// Get pointer back
|
||||
pla
|
||||
sta basic_current_line_ptr+1
|
||||
pla
|
||||
sta basic_current_line_ptr+0
|
||||
|
||||
;; Write the line number
|
||||
// Write the line number
|
||||
ldy #2
|
||||
ldx #<basic_current_line_ptr
|
||||
lda basic_line_number+0
|
||||
@@ -64,7 +65,7 @@ basic_insert_line:
|
||||
lda basic_line_number+1
|
||||
jsr poke_under_roms
|
||||
|
||||
;; Now store the line body itself
|
||||
// Now store the line body itself
|
||||
inc tokenise_work2
|
||||
line_store_loop:
|
||||
ldx tokenise_work1
|
||||
|
||||
+50
-51
@@ -1,43 +1,43 @@
|
||||
basic_main_loop:
|
||||
|
||||
;; XXX - Check if direct or program mode, and get next line of input
|
||||
;; the appropriate way.
|
||||
;; XXX - For now, it is hard coded to direct mode
|
||||
// XXX - Check if direct or program mode, and get next line of input
|
||||
// the appropriate way.
|
||||
// XXX - For now, it is hard coded to direct mode
|
||||
|
||||
;; Tell user we are ready
|
||||
// Tell user we are ready
|
||||
jsr ready_message
|
||||
|
||||
basic_read_next_line:
|
||||
;; Read a line of input
|
||||
// Read a line of input
|
||||
ldx #$00
|
||||
read_line_loop:
|
||||
|
||||
jsr $ffcf ; KERNAL CHRIN
|
||||
jsr JCHRIN
|
||||
bcs read_line_loop
|
||||
|
||||
cmp #$0d
|
||||
beq got_line_of_input
|
||||
;; Not carriage return, so try to append to line so far
|
||||
// Not carriage return, so try to append to line so far
|
||||
cpx #80
|
||||
bcc +
|
||||
;; Report STRING TOO LONG error (Compute's Mapping the 64 p93)
|
||||
bcc !+
|
||||
// Report STRING TOO LONG error (Compute's Mapping the 64 p93)
|
||||
ldx #22
|
||||
jmp basic_do_error
|
||||
*
|
||||
!:
|
||||
sta basic_input_buffer,x
|
||||
inx
|
||||
jmp read_line_loop
|
||||
|
||||
got_line_of_input:
|
||||
|
||||
;; Store length of input buffer ready for tokenising
|
||||
// Store length of input buffer ready for tokenising
|
||||
stx tokenise_work1
|
||||
|
||||
;; Strip leading spaces from the line
|
||||
// Strip leading spaces from the line
|
||||
remove_leading_spaces:
|
||||
lda $0200
|
||||
cmp #$20
|
||||
bne +
|
||||
bne !+
|
||||
ldx #1
|
||||
rsl_l1: lda $0200,x
|
||||
sta $01ff,x
|
||||
@@ -45,40 +45,40 @@ rsl_l1: lda $0200,x
|
||||
cpx tokenise_work1
|
||||
bne rsl_l1
|
||||
|
||||
;; Reduce length of input by one
|
||||
// Reduce length of input by one
|
||||
dec tokenise_work1
|
||||
;; Stop trying to rim if we run out of input
|
||||
// Stop trying to rim if we run out of input
|
||||
bne remove_leading_spaces
|
||||
*
|
||||
;; Do printing of the new line
|
||||
!:
|
||||
// Do printing of the new line
|
||||
lda #$0d
|
||||
jsr JCHROUT
|
||||
|
||||
;; Ignore empty lines
|
||||
// Ignore empty lines
|
||||
lda tokenise_work1
|
||||
beq basic_read_next_line
|
||||
|
||||
;; Else, tokenise the line
|
||||
// Else, tokenise the line
|
||||
jsr tokenise_line
|
||||
|
||||
;; Has the user entered a line of BASIC beginning with a number?
|
||||
// Has the user entered a line of BASIC beginning with a number?
|
||||
lda $0200
|
||||
cmp #$30
|
||||
bcc not_a_line
|
||||
cmp #$39
|
||||
bcs not_a_line
|
||||
|
||||
;; Yes, the line begins with a number.
|
||||
;; Parse the line number and check validity
|
||||
// Yes, the line begins with a number.
|
||||
// Parse the line number and check validity
|
||||
|
||||
;; injest_number follows tokenise_work1 as the offset into the line,
|
||||
;; so remember the line length somewhere else for now.
|
||||
// injest_number follows tokenise_work1 as the offset into the line,
|
||||
// so remember the line length somewhere else for now.
|
||||
lda tokenise_work1
|
||||
sta tokenise_work2
|
||||
lda #$00
|
||||
sta tokenise_work1
|
||||
|
||||
;; Try to read line number
|
||||
// Try to read line number
|
||||
lda #<$0200
|
||||
sta basic_current_statement_ptr+0
|
||||
lda #>$0200
|
||||
@@ -86,67 +86,66 @@ rsl_l1: lda $0200,x
|
||||
|
||||
jsr basic_parse_line_number
|
||||
|
||||
;; Get pointer to next char
|
||||
// Get pointer to next char
|
||||
lda basic_current_statement_ptr+0
|
||||
sta tokenise_work1
|
||||
|
||||
;; Got a valid line number -- so do add/del line
|
||||
// Got a valid line number -- so do add/del line
|
||||
|
||||
;; Skip any spaces after the line number
|
||||
// Skip any spaces after the line number
|
||||
ldx tokenise_work1
|
||||
skip_spaces:
|
||||
lda $0200,x
|
||||
cmp #$20
|
||||
bne +
|
||||
bne !+
|
||||
inx
|
||||
bne skip_spaces
|
||||
* stx tokenise_work1
|
||||
!: stx tokenise_work1
|
||||
|
||||
;; First, clear all variables, so that we only have to shove BASIC text around.
|
||||
;; (We could later remove this requirement, and the only effect should be
|
||||
;; to slow things down, and that you might have to either CLR if there is no
|
||||
;; memory free, or else it would auto CLR when you ran out of program space).
|
||||
// First, clear all variables, so that we only have to shove BASIC text around.
|
||||
// (We could later remove this requirement, and the only effect should be
|
||||
// to slow things down, and that you might have to either CLR if there is no
|
||||
// memory free, or else it would auto CLR when you ran out of program space).
|
||||
jsr basic_do_clr
|
||||
|
||||
;; Delete line if present
|
||||
// Delete line if present
|
||||
jsr basic_find_line
|
||||
|
||||
bcs +
|
||||
bcs !+
|
||||
|
||||
;; Delete the line, whether we are deleting or
|
||||
;; replacing the line
|
||||
// Delete the line, whether we are deleting or
|
||||
// replacing the line
|
||||
jsr basic_delete_line
|
||||
*
|
||||
;; Insert new line if non-zero length, i.e., that
|
||||
;; we are not just deleting the line.
|
||||
!:
|
||||
// Insert new line if non-zero length, i.e., that
|
||||
// we are not just deleting the line.
|
||||
lda tokenise_work1
|
||||
cmp tokenise_work2
|
||||
beq +
|
||||
beq !+
|
||||
jsr basic_insert_line
|
||||
*
|
||||
;; No READY message after entering or deleting a line of BASIC
|
||||
!:
|
||||
// No READY message after entering or deleting a line of BASIC
|
||||
jmp basic_read_next_line
|
||||
|
||||
not_a_line:
|
||||
|
||||
;; Actually interpret the line
|
||||
// Actually interpret the line
|
||||
|
||||
;; Setup pointer to the statement
|
||||
// Setup pointer to the statement
|
||||
lda #<$0200
|
||||
sta basic_current_statement_ptr+0
|
||||
lda #>$0200
|
||||
sta basic_current_statement_ptr+1
|
||||
|
||||
;; There is no stored line, so zero that pointer out
|
||||
// There is no stored line, so zero that pointer out
|
||||
lda #$00
|
||||
sta basic_current_line_ptr+0
|
||||
sta basic_current_line_ptr+1
|
||||
|
||||
;; Put invalid line number in current line number value,
|
||||
;; so that we know we are in direct mode
|
||||
;; (Compute's Mapping the 64 p19)
|
||||
// Put invalid line number in current line number value,
|
||||
// so that we know we are in direct mode
|
||||
// (Compute's Mapping the 64 p19)
|
||||
lda #$ff
|
||||
sta basic_current_line_number+1
|
||||
|
||||
jmp basic_execute_statement
|
||||
|
||||
@@ -3,22 +3,22 @@ basic_parse_line_number:
|
||||
|
||||
jsr injest_number
|
||||
|
||||
;; Check if the number is a valid line number
|
||||
;; i.e., 16 bits, no exponent, no decimal
|
||||
// Check if the number is a valid line number
|
||||
// i.e., 16 bits, no exponent, no decimal
|
||||
lda basic_fac1_mantissa+2
|
||||
ora basic_fac1_mantissa+3
|
||||
ora basic_fac1_exponent
|
||||
beq +
|
||||
beq !+
|
||||
ml_bad_line_number:
|
||||
;; Invalid line number
|
||||
// Invalid line number
|
||||
jmp do_ILLEGAL_QUANTITY_error
|
||||
*
|
||||
;; Line number are not allowed to have decimal points in them
|
||||
!:
|
||||
// Line number are not allowed to have decimal points in them
|
||||
lda tokenise_work4
|
||||
cmp #$ff
|
||||
cmp #$FF
|
||||
bne ml_bad_line_number
|
||||
|
||||
;; Got a valid line number.
|
||||
// Got a valid line number.
|
||||
lda basic_fac1_mantissa+0
|
||||
sta basic_line_number+0
|
||||
lda basic_fac1_mantissa+1
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
basic_shift_mem_down_and_relink:
|
||||
;; Shift memory down to basic_current_line_pointer
|
||||
;; from X bytes further along.
|
||||
// Shift memory down to basic_current_line_pointer
|
||||
// from X bytes further along.
|
||||
|
||||
;; Destination is basic_current_line_ptr
|
||||
// Destination is basic_current_line_ptr
|
||||
lda basic_current_line_ptr+0
|
||||
sta memmove_dst+0
|
||||
lda basic_current_line_ptr+1
|
||||
sta memmove_dst+1
|
||||
|
||||
;; Source is that plus X
|
||||
// Source is that plus X
|
||||
txa
|
||||
pha ; also keep for later
|
||||
pha // also keep for later
|
||||
clc
|
||||
adc basic_current_line_ptr+0
|
||||
sta memmove_src+0
|
||||
@@ -18,7 +18,7 @@ basic_shift_mem_down_and_relink:
|
||||
adc #0
|
||||
sta memmove_src+1
|
||||
|
||||
;; Size is distance from source to end of BASIC text.
|
||||
// Size is distance from source to end of BASIC text.
|
||||
lda basic_end_of_text_ptr+0
|
||||
sec
|
||||
sbc memmove_src+0
|
||||
@@ -27,32 +27,32 @@ basic_shift_mem_down_and_relink:
|
||||
sbc memmove_src+1
|
||||
sta memmove_size+1
|
||||
|
||||
;; jsr printf
|
||||
;; .byte "TOP OF BASIC = $"
|
||||
;; .byte $f1,<basic_end_of_text_ptr,>basic_end_of_text_ptr
|
||||
;; .byte $f0,<basic_end_of_text_ptr,>basic_end_of_text_ptr
|
||||
;; .byte $0d
|
||||
;; .byte "SHIFTING DOWN $"
|
||||
;; .byte $f1,<memmove_size,>memmove_size
|
||||
;; .byte $f0,<memmove_size,>memmove_size
|
||||
;; .byte " BYTES FROM $"
|
||||
;; .byte $f1,<memmove_src,>memmove_src
|
||||
;; .byte $f0,<memmove_src,>memmove_src
|
||||
;; .byte " TO $"
|
||||
;; .byte $f1,<memmove_dst,>memmove_dst
|
||||
;; .byte $f0,<memmove_dst,>memmove_dst
|
||||
;; .byte $0d,0
|
||||
// jsr printf
|
||||
// .text "TOP OF BASIC = $"
|
||||
// .byte $f1,<basic_end_of_text_ptr,>basic_end_of_text_ptr
|
||||
// .byte $f0,<basic_end_of_text_ptr,>basic_end_of_text_ptr
|
||||
// .byte $0d
|
||||
// .text "SHIFTING DOWN $"
|
||||
// .byte $f1,<memmove_size,>memmove_size
|
||||
// .byte $f0,<memmove_size,>memmove_size
|
||||
// .text " BYTES FROM $"
|
||||
// .byte $f1,<memmove_src,>memmove_src
|
||||
// .byte $f0,<memmove_src,>memmove_src
|
||||
// .text " TO $"
|
||||
// .byte $f1,<memmove_dst,>memmove_dst
|
||||
// .byte $f0,<memmove_dst,>memmove_dst
|
||||
// .byte $0d,0
|
||||
|
||||
;; The copy routine that copies under the ROMs is as simple
|
||||
;; as possible to be as small as possible, so we have
|
||||
;; to adjust the pointers and counts so that the simple
|
||||
;; increment and decrement bounds checks work.
|
||||
// The copy routine that copies under the ROMs is as simple
|
||||
// as possible to be as small as possible, so we have
|
||||
// to adjust the pointers and counts so that the simple
|
||||
// increment and decrement bounds checks work.
|
||||
|
||||
;; Specifically we want Y pre-set so that the end of the
|
||||
;; copy ends when Y = $00.
|
||||
;; So if copying 1 byte, we want Y=$FF
|
||||
;; This means we have to then reduce the source and
|
||||
;; target pointers by the same amount
|
||||
// Specifically we want Y pre-set so that the end of the
|
||||
// copy ends when Y = $00.
|
||||
// So if copying 1 byte, we want Y=$FF
|
||||
// This means we have to then reduce the source and
|
||||
// target pointers by the same amount
|
||||
|
||||
lda memmove_size+0
|
||||
eor #$ff
|
||||
@@ -75,50 +75,50 @@ basic_shift_mem_down_and_relink:
|
||||
sbc #0
|
||||
sta memmove_dst+1
|
||||
|
||||
;; Increase copy page count so we can post-decrement compare with $00
|
||||
// Increase copy page count so we can post-decrement compare with $00
|
||||
inc memmove_size+1
|
||||
|
||||
;; jsr printf
|
||||
;; .byte "REVISED BOUNDS $"
|
||||
;; .byte $f1,<memmove_size,>memmove_size
|
||||
;; .byte $f0,<memmove_size,>memmove_size
|
||||
;; .byte " BYTES FROM $"
|
||||
;; .byte $f1,<memmove_src,>memmove_src
|
||||
;; .byte $f0,<memmove_src,>memmove_src
|
||||
;; .byte " TO $"
|
||||
;; .byte $f1,<memmove_dst,>memmove_dst
|
||||
;; .byte $f0,<memmove_dst,>memmove_dst
|
||||
;; .byte $0d,0
|
||||
// jsr printf
|
||||
// .text "REVISED BOUNDS $"
|
||||
// .byte $f1,<memmove_size,>memmove_size
|
||||
// .byte $f0,<memmove_size,>memmove_size
|
||||
// .text " BYTES FROM $"
|
||||
// .byte $f1,<memmove_src,>memmove_src
|
||||
// .byte $f0,<memmove_src,>memmove_src
|
||||
// .text " TO $"
|
||||
// .byte $f1,<memmove_dst,>memmove_dst
|
||||
// .byte $f0,<memmove_dst,>memmove_dst
|
||||
// .byte $0d,0
|
||||
|
||||
;; Get Y value ready for the copy
|
||||
// Get Y value ready for the copy
|
||||
ldy memmove_size+0
|
||||
|
||||
jsr shift_mem_down
|
||||
|
||||
;; Get length of deletion back
|
||||
// Get length of deletion back
|
||||
pla
|
||||
sta tokenise_work3
|
||||
|
||||
;; Check if we still have any lines left
|
||||
// Check if we still have any lines left
|
||||
ldy #0
|
||||
ldx #<basic_current_line_ptr
|
||||
jsr peek_pointer_null_check
|
||||
bcs relink_down_next_line
|
||||
;; Nope, so just return
|
||||
// Nope, so just return
|
||||
clc
|
||||
rts
|
||||
|
||||
|
||||
relink_down_next_line:
|
||||
;; inc $d020
|
||||
;; jmp relink_down_next_line
|
||||
// inc $d020
|
||||
// jmp relink_down_next_line
|
||||
|
||||
;; Subtract tokenise_work3 from the pointer
|
||||
// Subtract tokenise_work3 from the pointer
|
||||
ldy #0
|
||||
ldx #<basic_current_line_ptr+0
|
||||
jsr peek_under_roms
|
||||
sec
|
||||
sbc tokenise_Work3
|
||||
sbc tokenise_work3
|
||||
sta memmove_src+0
|
||||
iny
|
||||
jsr peek_under_roms
|
||||
@@ -134,13 +134,13 @@ relink_down_next_line:
|
||||
jsr poke_under_roms
|
||||
|
||||
relink_down_loop:
|
||||
;; Now advance pointer to the next line,
|
||||
// Now advance pointer to the next line,
|
||||
lda memmove_src+0
|
||||
sta basic_current_line_ptr+0
|
||||
lda memmove_src+1
|
||||
sta basic_current_line_ptr+1
|
||||
|
||||
;; Have we run out of lines to patch?
|
||||
// Have we run out of lines to patch?
|
||||
ldx #<basic_current_line_ptr
|
||||
jsr peek_pointer_null_check
|
||||
bcs relink_down_next_line
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
|
||||
|
||||
basic_shift_mem_up_and_relink:
|
||||
;; Shift memory up from basic_current_line_ptr
|
||||
;; X bytes.
|
||||
// Shift memory up from basic_current_line_ptr
|
||||
// X bytes.
|
||||
|
||||
;; NOTE: Pointers need to be reduced by one, due to the way
|
||||
;; the copyroutine works, so we do that here.
|
||||
;; Work out end point of destination
|
||||
// NOTE: Pointers need to be reduced by one, due to the way
|
||||
// the copyroutine works, so we do that here.
|
||||
// Work out end point of destination
|
||||
txa
|
||||
clc
|
||||
adc basic_end_of_text_ptr+0
|
||||
@@ -22,7 +22,7 @@ basic_shift_mem_up_and_relink:
|
||||
sbc #0
|
||||
sta memmove_dst+1
|
||||
|
||||
;; End point of source is just current end of BASIC text
|
||||
// End point of source is just current end of BASIC text
|
||||
lda basic_end_of_text_ptr+0
|
||||
sec
|
||||
sbc #1
|
||||
@@ -31,7 +31,7 @@ basic_shift_mem_up_and_relink:
|
||||
sbc #0
|
||||
sta memmove_src+1
|
||||
|
||||
;; Work out size of region to copy
|
||||
// Work out size of region to copy
|
||||
lda basic_end_of_text_ptr+0
|
||||
sec
|
||||
sbc basic_current_line_ptr+0
|
||||
@@ -40,25 +40,25 @@ basic_shift_mem_up_and_relink:
|
||||
sbc basic_current_line_ptr+1
|
||||
sta memmove_size+1
|
||||
|
||||
;; jsr printf
|
||||
;; .byte "TOP OF BASIC = $"
|
||||
;; .byte $f1,<basic_end_of_text_ptr,>basic_end_of_text_ptr
|
||||
;; .byte $f0,<basic_end_of_text_ptr,>basic_end_of_text_ptr
|
||||
;; .byte $0d
|
||||
;; .byte "SHIFTING UP $"
|
||||
;; .byte $f1,<memmove_size,>memmove_size
|
||||
;; .byte $f0,<memmove_size,>memmove_size
|
||||
;; .byte " BYTES FROM $"
|
||||
;; .byte $f1,<memmove_src,>memmove_src
|
||||
;; .byte $f0,<memmove_src,>memmove_src
|
||||
;; .byte " TO $"
|
||||
;; .byte $f1,<memmove_dst,>memmove_dst
|
||||
;; .byte $f0,<memmove_dst,>memmove_dst
|
||||
;; .byte $0d,0
|
||||
// jsr printf
|
||||
// .text "TOP OF BASIC = $"
|
||||
// .byte $f1,<basic_end_of_text_ptr,>basic_end_of_text_ptr
|
||||
// .byte $f0,<basic_end_of_text_ptr,>basic_end_of_text_ptr
|
||||
// .byte $0d
|
||||
// .text "SHIFTING UP $"
|
||||
// .byte $f1,<memmove_size,>memmove_size
|
||||
// .byte $f0,<memmove_size,>memmove_size
|
||||
// .text " BYTES FROM $"
|
||||
// .byte $f1,<memmove_src,>memmove_src
|
||||
// .byte $f0,<memmove_src,>memmove_src
|
||||
// .text " TO $"
|
||||
// .byte $f1,<memmove_dst,>memmove_dst
|
||||
// .byte $f0,<memmove_dst,>memmove_dst
|
||||
// .byte $0d,0
|
||||
|
||||
;; To make life simple for the copy routine that lives in RAM,
|
||||
;; we have to adjust the end pointers down one page and set Y to the low
|
||||
;; byte of the copy size.
|
||||
// To make life simple for the copy routine that lives in RAM,
|
||||
// we have to adjust the end pointers down one page and set Y to the low
|
||||
// byte of the copy size.
|
||||
lda memmove_src+0
|
||||
sec
|
||||
sbc memmove_size+0
|
||||
@@ -75,35 +75,35 @@ basic_shift_mem_up_and_relink:
|
||||
sbc #0
|
||||
sta memmove_dst+1
|
||||
|
||||
;; Now make exit easy, by being able to check for zero on size high byte when done
|
||||
// Now make exit easy, by being able to check for zero on size high byte when done
|
||||
inc memmove_size+1
|
||||
|
||||
;; Then set Y to the number offset required
|
||||
// Then set Y to the number offset required
|
||||
ldy memmove_size+0
|
||||
iny
|
||||
|
||||
stx tokenise_work3
|
||||
|
||||
;; jsr printf
|
||||
;; .byte "REVISED BOUNDS $"
|
||||
;; .byte $f1,<memmove_size,>memmove_size
|
||||
;; .byte $f0,<memmove_size,>memmove_size
|
||||
;; .byte " BYTES FROM $"
|
||||
;; .byte $f1,<memmove_src,>memmove_src
|
||||
;; .byte $f0,<memmove_src,>memmove_src
|
||||
;; .byte " TO $"
|
||||
;; .byte $f1,<memmove_dst,>memmove_dst
|
||||
;; .byte $f0,<memmove_dst,>memmove_dst
|
||||
;; .byte $0d,0
|
||||
// jsr printf
|
||||
// .text "REVISED BOUNDS $"
|
||||
// .byte $f1,<memmove_size,>memmove_size
|
||||
// .byte $f0,<memmove_size,>memmove_size
|
||||
// .text " BYTES FROM $"
|
||||
// .byte $f1,<memmove_src,>memmove_src
|
||||
// .byte $f0,<memmove_src,>memmove_src
|
||||
// .text " TO $"
|
||||
// .byte $f1,<memmove_dst,>memmove_dst
|
||||
// .byte $f0,<memmove_dst,>memmove_dst
|
||||
// .byte $0d,0
|
||||
|
||||
;; Do the copy
|
||||
// Do the copy
|
||||
jsr shift_mem_up
|
||||
|
||||
;; Now fix the pointer to the next line
|
||||
// Now fix the pointer to the next line
|
||||
|
||||
;; First, we need to point the current BASIC line
|
||||
;; pointer to itself, so that we can add the shift
|
||||
;; to make it end up pointing to the next line
|
||||
// First, we need to point the current BASIC line
|
||||
// pointer to itself, so that we can add the shift
|
||||
// to make it end up pointing to the next line
|
||||
ldy #0
|
||||
ldx #<basic_current_line_ptr+0
|
||||
lda basic_current_line_ptr+0
|
||||
@@ -113,10 +113,10 @@ basic_shift_mem_up_and_relink:
|
||||
jsr poke_under_roms
|
||||
|
||||
relink_up_next_line:
|
||||
;; inc $d020
|
||||
;; jmp relink_up_next_line
|
||||
// inc $d020
|
||||
// jmp relink_up_next_line
|
||||
|
||||
;; Advance pointer by tokenise_word3 bytes
|
||||
// Advance pointer by tokenise_word3 bytes
|
||||
ldy #0
|
||||
ldx #<basic_current_line_ptr+0
|
||||
jsr peek_under_roms
|
||||
@@ -132,20 +132,20 @@ relink_up_next_line:
|
||||
adc #0
|
||||
sta memmove_src+1
|
||||
|
||||
;; jsr printf
|
||||
;; .byte "LINE ADDR = $"
|
||||
;; .byte $f1,<basic_current_line_ptr,>basic_end_of_text_ptr
|
||||
;; .byte $f0,<basic_current_line_ptr,>basic_end_of_text_ptr
|
||||
;; .byte $d," BEFORE = $"
|
||||
;; .byte $f1,<memmove_dst,>memmove_dst
|
||||
;; .byte $f0,<memmove_dst,>memmove_dst
|
||||
;; .byte ", AFTER = $"
|
||||
;; .byte $f1,<memmove_src,>memmove_src
|
||||
;; .byte $f0,<memmove_src,>memmove_src
|
||||
;; .byte $d
|
||||
;; .byte 0
|
||||
// jsr printf
|
||||
// .text "LINE ADDR = $"
|
||||
// .byte $f1,<basic_current_line_ptr,>basic_end_of_text_ptr
|
||||
// .byte $f0,<basic_current_line_ptr,>basic_end_of_text_ptr
|
||||
// .text $d," BEFORE = $"
|
||||
// .byte $f1,<memmove_dst,>memmove_dst
|
||||
// .byte $f0,<memmove_dst,>memmove_dst
|
||||
// .text ", AFTER = $"
|
||||
// .byte $f1,<memmove_src,>memmove_src
|
||||
// .byte $f0,<memmove_src,>memmove_src
|
||||
// .byte $d
|
||||
// .byte 0
|
||||
|
||||
;; Write memmove_src back to current line pointer
|
||||
// Write memmove_src back to current line pointer
|
||||
ldy #0
|
||||
ldx #<basic_current_line_ptr
|
||||
lda memmove_src+0
|
||||
@@ -156,13 +156,13 @@ relink_up_next_line:
|
||||
|
||||
|
||||
relink_up_loop:
|
||||
;; Now advance pointer to the next line,
|
||||
// Now advance pointer to the next line,
|
||||
lda memmove_src+0
|
||||
sta basic_current_line_ptr+0
|
||||
lda memmove_src+1
|
||||
sta basic_current_line_ptr+1
|
||||
|
||||
;; Have we run out of lines to patch?
|
||||
// Have we run out of lines to patch?
|
||||
ldx #<basic_current_line_ptr
|
||||
jsr peek_pointer_null_check
|
||||
bcs relink_up_next_line
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
;; Clear screen etc, show READY prompt.
|
||||
// Clear screen etc, show READY prompt.
|
||||
|
||||
basic_warm_start:
|
||||
jsr install_ram_routines
|
||||
|
||||
;; If warm start caused by BRK, print it address
|
||||
// If warm start caused by BRK, print it address
|
||||
lda CMP0
|
||||
ora CMP0+1
|
||||
beq +
|
||||
beq !+
|
||||
|
||||
ldx #32
|
||||
jsr print_packed_message
|
||||
@@ -18,6 +18,6 @@ basic_warm_start:
|
||||
lda #$0D
|
||||
jsr JCHROUT
|
||||
|
||||
*
|
||||
!:
|
||||
jmp basic_main_loop
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
;; Skip the gap between $C000-$DFFF
|
||||
.checkpc $C000
|
||||
.advance $DFFF,$00
|
||||
.checkpc $E000
|
||||
// Skip the gap between $C000-$DFFF
|
||||
|
||||
.fill $2000, $00
|
||||
+13
-12
@@ -1,23 +1,24 @@
|
||||
cmd_stop:
|
||||
basic_do_break:
|
||||
jsr printf
|
||||
.byte "BREAK",0
|
||||
jsr printf // XXX don't use printf, use packed messages!
|
||||
.text "BREAK"
|
||||
.byte 0
|
||||
|
||||
;; Check for direct mode
|
||||
;; Are we in direct mode
|
||||
// Check for direct mode
|
||||
// Are we in direct mode
|
||||
lda basic_current_line_number+1
|
||||
cmp #$ff
|
||||
beq +
|
||||
;; Not direct mode
|
||||
jsr printf
|
||||
.byte " IN ",0
|
||||
cmp #$FF
|
||||
beq !+
|
||||
// Not direct mode
|
||||
jsr printf // XXX don't use printf, use packed messages!
|
||||
.text " IN "
|
||||
.byte 0
|
||||
lda basic_current_line_number+1
|
||||
ldx basic_current_line_number+0
|
||||
jsr print_integer
|
||||
|
||||
*
|
||||
lda #$0d
|
||||
!:
|
||||
lda #$0D
|
||||
jsr JCHROUT
|
||||
cmd_end:
|
||||
jmp basic_main_loop
|
||||
|
||||
+26
-26
@@ -1,9 +1,9 @@
|
||||
;; LIST basic text.
|
||||
;; XXX - Doesn't currently support line number ranges
|
||||
// LIST basic text.
|
||||
// XXX - Doesn't currently support line number ranges
|
||||
|
||||
cmd_list:
|
||||
|
||||
;; Set current line pointer to start of memory
|
||||
// Set current line pointer to start of memory
|
||||
lda basic_start_of_text_ptr+0
|
||||
sta basic_current_line_ptr+0
|
||||
lda basic_start_of_text_ptr+1
|
||||
@@ -16,23 +16,23 @@ list_loop:
|
||||
cmp #$00
|
||||
bne list_more_lines
|
||||
|
||||
;; LIST terminates any running program,
|
||||
;; because it has fiddled with the current line pointer.
|
||||
;; (Confirmed by testing on a C64)
|
||||
// LIST terminates any running program,
|
||||
// because it has fiddled with the current line pointer.
|
||||
// (Confirmed by testing on a C64)
|
||||
jmp basic_main_loop
|
||||
|
||||
list_more_lines:
|
||||
lda STKEY
|
||||
bmi +
|
||||
bmi !+
|
||||
jmp basic_do_break
|
||||
*
|
||||
!:
|
||||
jsr list_single_line
|
||||
;; Now link to the next 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
|
||||
list_single_line: // entry point needed by DOS wedge
|
||||
// Print line number
|
||||
ldy #3
|
||||
jsr peek_under_roms
|
||||
pha
|
||||
@@ -44,8 +44,8 @@ list_single_line: ; entry point needed by DOS wedge
|
||||
lda #$20
|
||||
jsr JCHROUT
|
||||
|
||||
;; Iterate through printing out the line
|
||||
;; contents
|
||||
// Iterate through printing out the line
|
||||
// contents
|
||||
lda #0
|
||||
sta quote_mode_flag
|
||||
|
||||
@@ -63,34 +63,34 @@ list_print_loop:
|
||||
lda #$22
|
||||
jmp list_is_literal
|
||||
list_not_quote:
|
||||
;; Check quote mode, and display as literal if required
|
||||
// Check quote mode, and display as literal if required
|
||||
ldx quote_mode_flag
|
||||
bne list_is_literal
|
||||
|
||||
cmp #$7f
|
||||
bcc list_is_literal
|
||||
|
||||
;; Display a token
|
||||
// Display a token
|
||||
|
||||
;; Save registers
|
||||
// Save registers
|
||||
tax
|
||||
pha
|
||||
tya
|
||||
pha
|
||||
|
||||
;; Get pointer to compressed keyword list
|
||||
// Get pointer to compressed keyword list
|
||||
lda #<packed_keywords
|
||||
sta temp_string_ptr+0
|
||||
lda #>packed_keywords
|
||||
sta temp_string_ptr+1
|
||||
|
||||
;; Subtract $80 from token to get offset in word
|
||||
;; list
|
||||
// Subtract $80 from token to get offset in word
|
||||
// list
|
||||
txa
|
||||
and #$7f
|
||||
tax
|
||||
|
||||
;; Now ask for it to be printed
|
||||
// Now ask for it to be printed
|
||||
ldy #$ff
|
||||
jsr packed_word_search
|
||||
|
||||
@@ -100,11 +100,11 @@ list_not_quote:
|
||||
|
||||
cmp #$8f
|
||||
bne list_not_rem
|
||||
;; REM command locks quote flag on until the end of the line, allowing
|
||||
;; funny characters in REM statements without problem.
|
||||
// REM command locks quote flag on until the end of the line, allowing
|
||||
// funny characters in REM statements without problem.
|
||||
inc $0427
|
||||
sta quote_mode_flag ; Any value other than $00 or $FF will lock quote mode on, so the token value of REM is fine here
|
||||
;; FALL THROUGH
|
||||
sta quote_mode_flag // Any value other than $00 or $FF will lock quote mode on, so the token value of REM is fine here
|
||||
// FALL THROUGH
|
||||
list_not_rem:
|
||||
|
||||
iny
|
||||
@@ -116,10 +116,10 @@ list_is_literal:
|
||||
bne list_print_loop
|
||||
|
||||
list_end_of_line:
|
||||
;; Clear reverse flag
|
||||
// Clear reverse flag
|
||||
lda #$92
|
||||
jsr JCHROUT
|
||||
;; Print end of line
|
||||
// Print end of line
|
||||
lda #$0d
|
||||
jsr JCHROUT
|
||||
rts
|
||||
|
||||
+66
-66
@@ -1,64 +1,64 @@
|
||||
cmd_load:
|
||||
|
||||
;; Parse filename
|
||||
;; (we can tell the KERNAL where it is in memory directly, since the
|
||||
;; KERNAL will be able to peek under ROMs to read it, since it will have
|
||||
;; to be able to peek under the ROMs for SAVE and VERIFY).
|
||||
;; Parse optional device #
|
||||
;; Parse optional secondary address
|
||||
// Parse filename
|
||||
// (we can tell the KERNAL where it is in memory directly, since the
|
||||
// KERNAL will be able to peek under ROMs to read it, since it will have
|
||||
// to be able to peek under the ROMs for SAVE and VERIFY).
|
||||
// Parse optional device #
|
||||
// Parse optional secondary address
|
||||
|
||||
;; XXX - C64 BASIC apparently doesn't clear variables after a LOAD in the
|
||||
;; middle of a program. For safety, we do.
|
||||
// XXX - C64 BASIC apparently doesn't clear variables after a LOAD in the
|
||||
// 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
|
||||
// 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
|
||||
*
|
||||
beq !+
|
||||
lda #$00 // direct mode - don't display anything
|
||||
!:
|
||||
jsr JSETMSG
|
||||
|
||||
;; Set filename and length
|
||||
// Set filename and length
|
||||
lda #$00
|
||||
sta FNLEN
|
||||
|
||||
;; Without tape support, LOAD must have a filename
|
||||
;; (This also skips any leading spaces)
|
||||
// Without tape support, LOAD must have a filename
|
||||
// (This also skips any leading spaces)
|
||||
jsr basic_end_of_statement_check
|
||||
bcc +
|
||||
bcc !+
|
||||
jmp do_MISSING_FILENAME_error
|
||||
*
|
||||
!:
|
||||
jsr basic_fetch_and_consume_character
|
||||
cmp #$22
|
||||
beq +
|
||||
jmp do_SYNTAX_ERROR
|
||||
*
|
||||
;; Filename starts here so set pointer
|
||||
beq !+
|
||||
jmp do_SYNTAX_error
|
||||
!:
|
||||
// Filename starts here so set pointer
|
||||
lda basic_current_statement_ptr+0
|
||||
sta current_filename_ptr+0
|
||||
lda basic_current_statement_ptr+1
|
||||
sta current_filename_ptr+1
|
||||
|
||||
;; Now search for end of line or closing quote
|
||||
;; so that we know the length of the filename
|
||||
// Now search for end of line or closing quote
|
||||
// so that we know the length of the filename
|
||||
getting_filename:
|
||||
jsr basic_fetch_and_consume_character
|
||||
cmp #$22
|
||||
beq got_filename
|
||||
cmp #$00
|
||||
bne +
|
||||
bne !+
|
||||
jsr basic_unconsume_character
|
||||
|
||||
jmp got_filename
|
||||
*
|
||||
!:
|
||||
inc FNLEN
|
||||
jmp getting_filename
|
||||
|
||||
got_filename:
|
||||
|
||||
;; Now fetch the file number, start from the default one
|
||||
// Now fetch the file number, start from the default one
|
||||
jsr select_device
|
||||
stx current_device_number
|
||||
jsr injest_comma
|
||||
@@ -66,116 +66,116 @@ got_filename:
|
||||
|
||||
jsr basic_parse_line_number
|
||||
lda basic_line_number+1
|
||||
beq +
|
||||
beq !+
|
||||
jmp do_ILLEGAL_QUANTITY_error
|
||||
*
|
||||
!:
|
||||
lda basic_line_number+0
|
||||
sta current_device_number
|
||||
|
||||
got_devicenumber:
|
||||
|
||||
;; Now fetch the secondary address
|
||||
// Now fetch the secondary address
|
||||
lda #$00
|
||||
sta current_secondary_address
|
||||
jsr injest_comma
|
||||
bcs got_secondaryaddress
|
||||
jsr basic_parse_line_number
|
||||
lda basic_line_number+1
|
||||
bne +
|
||||
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'
|
||||
!:
|
||||
// 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
|
||||
ldx #<$0801 // XXX use start text vector
|
||||
ldy #>$0801
|
||||
|
||||
got_loadaddress:
|
||||
lda #$00 ; LOAD not verify
|
||||
lda #$00 // LOAD not verify
|
||||
jsr via_ILOAD
|
||||
bcc +
|
||||
bcc !+
|
||||
|
||||
;; A = KERNAL error code, which also almost match
|
||||
;; basic ERROR codes, so we can just copy the
|
||||
;; error code to X, decrement, and handle normally
|
||||
// A = KERNAL error code, which also almost match
|
||||
// basic ERROR codes, so we can just copy the
|
||||
// error code to X, decrement, and handle normally
|
||||
tax
|
||||
dex
|
||||
jmp do_basic_error
|
||||
|
||||
*
|
||||
;; $YYXX is the last loaded address, so store it
|
||||
!:
|
||||
// $YYXX is the last loaded address, so store it
|
||||
stx basic_end_of_text_ptr+0
|
||||
sty basic_end_of_text_ptr+1
|
||||
|
||||
;; Now relink the loaded program, as we cannot trust the line
|
||||
;; links supplied. For example, the VICE virtual drive emulation
|
||||
;; always supplies $0101 as the address of the next line.
|
||||
// Now relink the loaded program, as we cannot trust the line
|
||||
// links supplied. For example, the VICE virtual drive emulation
|
||||
// always supplies $0101 as the address of the next line.
|
||||
jsr basic_relink_program
|
||||
|
||||
;; After LOADing, we either start the program from the beginning,
|
||||
;; or go back to the READY prompt if LOAD was called from direct mode.
|
||||
// After LOADing, we either start the program from the beginning,
|
||||
// or go back to the READY prompt if LOAD was called from direct mode.
|
||||
|
||||
;; Reset to start of program
|
||||
// Reset to start of program
|
||||
lda basic_start_of_text_ptr+0
|
||||
sta basic_current_line_ptr+0
|
||||
lda basic_start_of_text_ptr+1
|
||||
sta basic_current_line_ptr+1
|
||||
|
||||
;; XXX - should run program if LOAD was used in program mode
|
||||
// XXX - should run program if LOAD was used in program mode
|
||||
jmp basic_main_loop
|
||||
|
||||
|
||||
basic_relink_program:
|
||||
|
||||
;; Start by getting pointer to the first line
|
||||
// Start by getting pointer to the first line
|
||||
lda basic_start_of_text_ptr+0
|
||||
sta basic_current_line_ptr+0
|
||||
lda basic_start_of_text_ptr+1
|
||||
sta basic_current_line_ptr+1
|
||||
|
||||
basic_relink_loop:
|
||||
;; Is the pointer to the end of the program
|
||||
// Is the pointer to the end of the program
|
||||
ldy #1
|
||||
ldx #<basic_current_line_ptr+0
|
||||
jsr peek_under_roms
|
||||
cmp #$00
|
||||
bne +
|
||||
bne !+
|
||||
|
||||
;; End of program
|
||||
// End of program
|
||||
rts
|
||||
*
|
||||
;; Now search forward to find the end of the line
|
||||
;; Skip forward pointer and line number
|
||||
!:
|
||||
// Now search forward to find the end of the line
|
||||
// Skip forward pointer and line number
|
||||
ldy #4
|
||||
end_of_line_search:
|
||||
ldx #<basic_current_line_ptr+0
|
||||
jsr peek_under_roms
|
||||
cmp #$00
|
||||
beq +
|
||||
beq !+
|
||||
|
||||
;; Not yet end of line
|
||||
// Not yet end of line
|
||||
iny
|
||||
bne end_of_line_search
|
||||
|
||||
;; line too long
|
||||
// line too long
|
||||
jmp do_STRING_TOO_LONG_error
|
||||
|
||||
*
|
||||
;; Found end of line, so update pointer
|
||||
!:
|
||||
// Found end of line, so update pointer
|
||||
|
||||
;; First, skip over the $00 char
|
||||
// First, skip over the $00 char
|
||||
iny
|
||||
|
||||
;; Now overwrite the pointer (carefully)
|
||||
;;
|
||||
// Now overwrite the pointer (carefully)
|
||||
//
|
||||
tya
|
||||
clc
|
||||
adc basic_current_line_ptr+0
|
||||
|
||||
+21
-23
@@ -2,18 +2,18 @@
|
||||
cmd_new:
|
||||
jsr basic_do_new
|
||||
|
||||
;; NEW command terminates execution
|
||||
;; (Confirmed on a C64)
|
||||
// NEW command terminates execution
|
||||
// (Confirmed on a C64)
|
||||
jmp basic_main_loop
|
||||
|
||||
cmd_clr:
|
||||
jsr basic_do_clr
|
||||
;; CLR command does not stop execution
|
||||
;; (Cconfirmed on a c64)
|
||||
// CLR command does not stop execution
|
||||
// (Cconfirmed on a c64)
|
||||
jmp basic_execute_statement
|
||||
|
||||
basic_do_new:
|
||||
;; Setup pointers to memory storage
|
||||
// Setup pointers to memory storage XXX should depend on text start vector
|
||||
lda #<$0801
|
||||
sta basic_start_of_text_ptr+0
|
||||
lda #>$0801
|
||||
@@ -22,8 +22,8 @@ basic_do_new:
|
||||
lda #<$0803
|
||||
sta basic_start_of_vars_ptr+0
|
||||
|
||||
;; Zero line pointer
|
||||
;; XXX - We should also zero $0800, i.e., basic_start_of_text_ptr - 1
|
||||
// Zero line pointer
|
||||
// XXX - We should also zero $0800, i.e., basic_start_of_text_ptr - 1
|
||||
ldy #$00
|
||||
tya
|
||||
sta (basic_start_of_text_ptr),y
|
||||
@@ -31,32 +31,32 @@ basic_do_new:
|
||||
sta (basic_start_of_text_ptr),y
|
||||
|
||||
|
||||
;; Get top of memory.
|
||||
;; If a cart is present, then it is $7FFF,
|
||||
;; if not, then it is $F7FF, since we support having
|
||||
;; programs and variables under ROM.
|
||||
;; i.e., we support 56KB RAM for BASIC, keeping some space
|
||||
;; free for some optimisation structures, e.g., FOR/NEXT loop
|
||||
;; records (without them going on the stack), GOSUB stack
|
||||
;; (same story), expression value cache?
|
||||
// Get top of memory.
|
||||
// If a cart is present, then it is $7FFF,
|
||||
// if not, then it is $F7FF, since we support having
|
||||
// programs and variables under ROM.
|
||||
// i.e., we support 56KB RAM for BASIC, keeping some space
|
||||
// free for some optimisation structures, e.g., FOR/NEXT loop
|
||||
// records (without them going on the stack), GOSUB stack
|
||||
// (same story), expression value cache?
|
||||
|
||||
sec ; Read, not write value
|
||||
sec // Read, not write value
|
||||
jsr JMEMTOP
|
||||
cpx #$80
|
||||
beq +
|
||||
beq !+
|
||||
lda #>$f7ff
|
||||
.byte $2c
|
||||
* lda #>$7FFF
|
||||
.byte $2C
|
||||
!: lda #>$7FFF
|
||||
sta basic_top_of_memory_ptr+1
|
||||
sta basic_start_of_strings_ptr+1
|
||||
lda #<$f7ff
|
||||
sta basic_top_of_memory_ptr+0
|
||||
sta basic_start_of_strings_ptr+0
|
||||
|
||||
;; FALL THROUGH
|
||||
// FALL THROUGH
|
||||
|
||||
basic_do_clr:
|
||||
;; Clear variables, arrays and strings
|
||||
// Clear variables, arrays and strings
|
||||
lda basic_start_of_vars_ptr+0
|
||||
sta basic_start_of_arrays_ptr+0
|
||||
sta basic_start_of_free_space_ptr+0
|
||||
@@ -65,5 +65,3 @@ basic_do_clr:
|
||||
sta basic_start_of_free_space_ptr+1
|
||||
|
||||
rts
|
||||
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
;; REM statement just skips to the next line
|
||||
// REM statement just skips to the next line
|
||||
|
||||
cmd_rem:
|
||||
jmp basic_end_of_line
|
||||
+7
-7
@@ -1,21 +1,21 @@
|
||||
cmd_run:
|
||||
;; RUN clears all variables
|
||||
// RUN clears all variables
|
||||
jsr basic_do_clr
|
||||
cmd_goto:
|
||||
;; Reset line pointer to first line of program.
|
||||
// Reset line pointer to first line of program.
|
||||
lda basic_start_of_text_ptr+0
|
||||
sta basic_current_line_ptr+0
|
||||
lda basic_start_of_text_ptr+1
|
||||
sta basic_current_line_ptr+1
|
||||
|
||||
jsr basic_end_of_statement_check
|
||||
bcs +
|
||||
bcs !+
|
||||
|
||||
jsr basic_parse_line_number
|
||||
jsr basic_find_line
|
||||
bcc +
|
||||
;; Line doesn't exist, so report error
|
||||
bcc !+
|
||||
// Line doesn't exist, so report error
|
||||
jmp do_UNDEFD_STATEMENT_error
|
||||
*
|
||||
;; Run it!
|
||||
!:
|
||||
// Run it!
|
||||
jmp basic_execute_from_current_line
|
||||
+8
-8
@@ -1,23 +1,23 @@
|
||||
cmd_sys:
|
||||
|
||||
jsr basic_end_of_statement_check
|
||||
bcc +
|
||||
bcc !+
|
||||
|
||||
;; SYS requires an argument
|
||||
jmp do_SYNTAX_ERROR
|
||||
// SYS requires an argument
|
||||
jmp do_SYNTAX_error
|
||||
|
||||
*
|
||||
!:
|
||||
jsr basic_parse_line_number
|
||||
|
||||
;; setup call
|
||||
lda #$4C ;JMP
|
||||
// setup call
|
||||
lda #$4C // JMP opcode
|
||||
sta USRPOK
|
||||
lda basic_line_number+0
|
||||
sta USRADD+0
|
||||
lda basic_line_number+1
|
||||
sta USRADD+1
|
||||
|
||||
;; Setup the register values
|
||||
// Setup the register values
|
||||
lda SPREG
|
||||
pha
|
||||
ldy SYREG
|
||||
@@ -25,7 +25,7 @@ cmd_sys:
|
||||
lda SAREG
|
||||
plp
|
||||
|
||||
;; Call the routine.
|
||||
// Call the routine.
|
||||
jsr USRPOK
|
||||
|
||||
jmp basic_execute_statement
|
||||
@@ -1,4 +1,4 @@
|
||||
;; Default handler for all not-yet-implemented commands
|
||||
// Default handler for all not-yet-implemented commands
|
||||
|
||||
cmd_for:
|
||||
cmd_next:
|
||||
@@ -13,7 +13,7 @@ cmd_restore:
|
||||
cmd_gosub:
|
||||
cmd_return:
|
||||
|
||||
;; $90-$9F
|
||||
// $90-$9F
|
||||
cmd_on:
|
||||
cmd_wait:
|
||||
cmd_save:
|
||||
@@ -26,7 +26,7 @@ cmd_cont:
|
||||
cmd_cmd:
|
||||
cmd_open:
|
||||
|
||||
;; $A0-$AF
|
||||
// $A0-$AF
|
||||
cmd_close:
|
||||
cmd_get:
|
||||
cmd_tab:
|
||||
@@ -43,7 +43,7 @@ cmd_div:
|
||||
cmd_exponent:
|
||||
cmd_and:
|
||||
|
||||
;; $B0-$BF
|
||||
// $B0-$BF
|
||||
cmd_or:
|
||||
cmd_greater:
|
||||
cmd_equal:
|
||||
@@ -61,7 +61,7 @@ cmd_exp:
|
||||
cmd_cos:
|
||||
cmd_sin:
|
||||
|
||||
;; $C0-$CF
|
||||
// $C0-$CF
|
||||
cmd_tan:
|
||||
cmd_atn:
|
||||
cmd_peek:
|
||||
@@ -73,10 +73,10 @@ cmd_chr:
|
||||
cmd_left:
|
||||
cmd_right:
|
||||
cmd_mid:
|
||||
cmd_go:
|
||||
;; Undefined tokens
|
||||
cmd_go:
|
||||
|
||||
// Undefined tokens
|
||||
cmd_unimplemented:
|
||||
|
||||
|
||||
|
||||
|
||||
jmp do_NOT_IMPLEMENTED_error
|
||||
+55
-54
@@ -1,48 +1,48 @@
|
||||
;; As many errors are triggered from many places in the BASIC
|
||||
;; interprettor, it is important to have an efficicent means of
|
||||
;; calling them.
|
||||
;; LDX #$nn / jmp do_basic_error
|
||||
;; is the simplest, but takes 5 bytes.
|
||||
;; Having a direct JMP address for each error is preferable, as
|
||||
;; it reduces the overhead to 3 bytes, but at the cost of having
|
||||
;; a jump table of some sort. The .byte $2C method can be used
|
||||
;; to have a set of addresses that each execute a different
|
||||
;; LDX #$nn command, reducing the cost of the jump table to 3
|
||||
;; bytes per error number.
|
||||
;; But we can do better with a bit of scullduggery and carnal
|
||||
;; knowledge of ZP usage.
|
||||
;; The INC $nn opcode is $E6. ZP location $E6 is one of the screen
|
||||
;; link addresses. In the original KERNAL, the lower bits of those
|
||||
;; addresses have meaning, but in our KERNAL, we ignore them, and just
|
||||
;; have them all zeroes. So.... We can have a sequence of $E6 bytes,
|
||||
;; and know exactly how many of them have been executed, by checking
|
||||
;; the value of $E6. Then all we need to worry about is if an odd
|
||||
;; number is required, then we have to have an exit that has a $E6
|
||||
;; opcode with some other address as target, but where the byte value
|
||||
;; of that argument can be safely executed as a CPU instruction.
|
||||
;; NOP = $EA is the obvious choice, as if used as an argument to
|
||||
;; $E6 will increment location $EA, which is another of the screen
|
||||
;; link addresses.
|
||||
// As many errors are triggered from many places in the BASIC
|
||||
// interprettor, it is important to have an efficicent means of
|
||||
// calling them.
|
||||
// LDX #$nn / jmp do_basic_error
|
||||
// is the simplest, but takes 5 bytes.
|
||||
// Having a direct JMP address for each error is preferable, as
|
||||
// it reduces the overhead to 3 bytes, but at the cost of having
|
||||
// a jump table of some sort. The .byte $2C method can be used
|
||||
// to have a set of addresses that each execute a different
|
||||
// LDX #$nn command, reducing the cost of the jump table to 3
|
||||
// bytes per error number.
|
||||
// But we can do better with a bit of scullduggery and carnal
|
||||
// knowledge of ZP usage.
|
||||
// The INC $nn opcode is $E6. ZP location $E6 is one of the screen
|
||||
// link addresses. In the original KERNAL, the lower bits of those
|
||||
// addresses have meaning, but in our KERNAL, we ignore them, and just
|
||||
// have them all zeroes. So.... We can have a sequence of $E6 bytes,
|
||||
// and know exactly how many of them have been executed, by checking
|
||||
// the value of $E6. Then all we need to worry about is if an odd
|
||||
// number is required, then we have to have an exit that has a $E6
|
||||
// opcode with some other address as target, but where the byte value
|
||||
// of that argument can be safely executed as a CPU instruction.
|
||||
// NOP = $EA is the obvious choice, as if used as an argument to
|
||||
// $E6 will increment location $EA, which is another of the screen
|
||||
// link addresses.
|
||||
|
||||
;; This gives a total overhead of 18 bytes + 1 byte per error
|
||||
;; message. This compares favourably to the 3 bytes per error
|
||||
;; message that the $2C method would result in.
|
||||
// This gives a total overhead of 18 bytes + 1 byte per error
|
||||
// message. This compares favourably to the 3 bytes per error
|
||||
// message that the $2C method would result in.
|
||||
|
||||
do_NOT_IMPLEMENTED_error:
|
||||
.byte $E6
|
||||
do_MEMORY_CORRUPT_error:
|
||||
.byte $E6
|
||||
;; the message "BYTES FREE"
|
||||
// the message "BYTES FREE"
|
||||
.byte $E6
|
||||
;; the word ERROR
|
||||
// the word ERROR
|
||||
.byte $E6
|
||||
;; The word "SAVING"
|
||||
// The word "SAVING"
|
||||
.byte $E6
|
||||
;; The word "VERIFYING"
|
||||
// The word "VERIFYING"
|
||||
.byte $E6
|
||||
;; The word "LOADING"
|
||||
// The word "LOADING"
|
||||
.byte $E6
|
||||
;; The word "READY."
|
||||
// The word "READY."
|
||||
.byte $E6
|
||||
do_LOAD_error:
|
||||
.byte $E6
|
||||
@@ -103,69 +103,70 @@ do_FILE_OPEN_error:
|
||||
do_TO_MANY_FILES_error:
|
||||
.byte $EA
|
||||
|
||||
;; Now get the error # and restore $E6 to its correct value
|
||||
// Now get the error # and restore $E6 to its correct value
|
||||
lda $E6
|
||||
pha
|
||||
and #$80
|
||||
sta $E6
|
||||
pla
|
||||
;; $E6 has even part
|
||||
// $E6 has even part
|
||||
asl
|
||||
ora $EA
|
||||
and #$7f
|
||||
tax
|
||||
|
||||
;; Restore $EA to correct value in case the NOP above is used
|
||||
;; as an argument to the preceeding INC $nn (opcode $E6).
|
||||
LDA $EA
|
||||
// Restore $EA to correct value in case the NOP above is used
|
||||
// as an argument to the preceeding INC $nn (opcode $E6).
|
||||
lda $EA
|
||||
and #$80
|
||||
sta $EA
|
||||
|
||||
;; FALL THROUGH
|
||||
// FALL THROUGH
|
||||
|
||||
;; Error # in X
|
||||
// Error # in X
|
||||
|
||||
do_basic_error:
|
||||
;; "?"
|
||||
// "?"
|
||||
txa
|
||||
pha
|
||||
lda #$0d
|
||||
jsr $ffd2
|
||||
jsr JCHROUT
|
||||
lda #$3f
|
||||
jsr $ffd2
|
||||
jsr JCHROUT
|
||||
pla
|
||||
tax
|
||||
|
||||
;; Error message text
|
||||
// Error message text
|
||||
jsr print_packed_message
|
||||
|
||||
;; A space between error name and word error
|
||||
// A space between error name and word error
|
||||
lda #$20
|
||||
jsr $ffd2
|
||||
|
||||
;; "ERROR"
|
||||
// "ERROR"
|
||||
ldx #33
|
||||
jsr print_packed_message
|
||||
|
||||
lda basic_current_line_number+1
|
||||
cmp #$ff
|
||||
beq +
|
||||
beq !+
|
||||
|
||||
;; We were in a program, so show IN <line>
|
||||
jsr printf
|
||||
.byte " IN ",0
|
||||
// We were in a program, so show IN <line>
|
||||
jsr printf // XXX don't use printf, use packed messages
|
||||
.text " IN "
|
||||
.byte 0
|
||||
|
||||
lda basic_current_line_number+1
|
||||
ldx basic_current_line_number+0
|
||||
jsr print_integer
|
||||
*
|
||||
;; New lines
|
||||
!:
|
||||
// New lines
|
||||
lda #$0d
|
||||
jsr $ffd2
|
||||
lda #$00
|
||||
jsr $ffd2
|
||||
|
||||
;; XXX - Restore stack depth first?
|
||||
// XXX - Restore stack depth first?
|
||||
|
||||
jmp basic_main_loop
|
||||
|
||||
+26
-26
@@ -1,23 +1,23 @@
|
||||
;; Multiply Floating Point Accumulator by 10
|
||||
;; = 8x + 2x
|
||||
;; Implement by shifting MAC left one bit,
|
||||
;; and then keeping that value to add on after
|
||||
;; shifting two more bits left.
|
||||
;; This should be done using basic_fac1_overflow to
|
||||
;; hold the overflow bits, so that the result can
|
||||
;; be exponent adjusted after, if required.
|
||||
// Multiply Floating Point Accumulator by 10
|
||||
// = 8x + 2x
|
||||
// Implement by shifting MAC left one bit,
|
||||
// and then keeping that value to add on after
|
||||
// shifting two more bits left.
|
||||
// This should be done using basic_fac1_overflow to
|
||||
// hold the overflow bits, so that the result can
|
||||
// be exponent adjusted after, if required.
|
||||
|
||||
fac1_mul10:
|
||||
lda #$00
|
||||
sta basic_fac1_overflow
|
||||
|
||||
;; Multiply mantissa by 2
|
||||
// Multiply mantissa by 2
|
||||
jsr fac1_mantissa_mul2
|
||||
|
||||
;; copy down to BASIC numeric work area at $57
|
||||
;; (basic_numeric_work_area)
|
||||
;; (We copy all 7 bytes off the FAC1, so that we have
|
||||
;; the overflow bits, and the copy is as small as possible)
|
||||
// copy down to BASIC numeric work area at $57
|
||||
// (basic_numeric_work_area)
|
||||
// (We copy all 7 bytes off the FAC1, so that we have
|
||||
// the overflow bits, and the copy is as small as possible)
|
||||
ldx #7
|
||||
f1m10_l1:
|
||||
lda basic_fac1_mantissa,x
|
||||
@@ -25,11 +25,11 @@ f1m10_l1:
|
||||
dex
|
||||
bpl f1m10_l1
|
||||
|
||||
;; Multiply mantissa by 4, so it is now 8x original
|
||||
// Multiply mantissa by 4, so it is now 8x original
|
||||
jsr fac1_mantissa_mul2
|
||||
jsr fac1_mantissa_mul2
|
||||
|
||||
;; Now add stored value of 2x to it, to get the total x10
|
||||
// Now add stored value of 2x to it, to get the total x10
|
||||
ldy #3
|
||||
ldx #0
|
||||
clc
|
||||
@@ -44,22 +44,22 @@ f1m10_l2:
|
||||
adc basic_numeric_work_area+7
|
||||
sta basic_fac1_overflow
|
||||
|
||||
;; Now shift right and increase exponent until overflow
|
||||
;; bits = $00
|
||||
// Now shift right and increase exponent until overflow
|
||||
// bits = $00
|
||||
f1m10_l3:
|
||||
lda basic_fac1_overflow
|
||||
bne +
|
||||
;; All done, return
|
||||
bne !+
|
||||
// All done, return
|
||||
clc
|
||||
rts
|
||||
*
|
||||
;; Divide mantissa by two, and increment exponent
|
||||
!:
|
||||
// Divide mantissa by two, and increment exponent
|
||||
jsr fac1_mantissa_div2
|
||||
inc basic_fac1_exponent
|
||||
lda basic_fac1_exponent
|
||||
bpl f1m10_l3
|
||||
;; Exponent has bit 7 set, so has wrapped.
|
||||
;; = OVERFLOW ERROR
|
||||
// Exponent has bit 7 set, so has wrapped.
|
||||
// = OVERFLOW ERROR
|
||||
jmp do_OVERFLOW_error
|
||||
|
||||
fac1_mantissa_mul2:
|
||||
@@ -67,8 +67,8 @@ fac1_mantissa_mul2:
|
||||
ldx #0
|
||||
clc
|
||||
f1m1_l1:
|
||||
;; Multiply mantissa by 2, and store overflow
|
||||
;; in basic_fac1_bits
|
||||
// Multiply mantissa by 2, and store overflow
|
||||
// in basic_fac1_bits
|
||||
lda basic_fac1_mantissa,x
|
||||
rol
|
||||
sta basic_fac1_mantissa,x
|
||||
@@ -82,7 +82,7 @@ f1m1_l1:
|
||||
rts
|
||||
|
||||
fac1_mantissa_div2:
|
||||
;; Divide mantissa by 2, including using overflow bits
|
||||
// Divide mantissa by 2, including using overflow bits
|
||||
clc
|
||||
lda basic_fac1_overflow
|
||||
ror
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
|
||||
;; Consummes a comma in a BASIC code, C set for no coma found
|
||||
// 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
|
||||
cmp #$2C // comma character
|
||||
beq injest_comma_found
|
||||
cmp #$20
|
||||
beq injest_comma ; space, can always be skipped
|
||||
cmp #$20 // space, can always be skipped
|
||||
beq injest_comma
|
||||
|
||||
;; not found
|
||||
// not found
|
||||
jsr basic_unconsume_character
|
||||
sec
|
||||
rts
|
||||
@@ -17,4 +17,3 @@ injest_comma:
|
||||
injest_comma_found:
|
||||
clc
|
||||
rts
|
||||
|
||||
+50
-51
@@ -1,37 +1,37 @@
|
||||
;; Parse a number from the input buffer at (basic_current_statement_ptr)
|
||||
;; Result is put into FAC1.
|
||||
;; basic_current_statement_ptr is updated with first position after the number.
|
||||
// Parse a number from the input buffer at (basic_current_statement_ptr)
|
||||
// Result is put into FAC1.
|
||||
// basic_current_statement_ptr is updated with first position after the number.
|
||||
|
||||
;; XXX - Remember decimal position and exponent, and apply them
|
||||
;; after to produce normalised floating point number.
|
||||
// XXX - Remember decimal position and exponent, and apply them
|
||||
// after to produce normalised floating point number.
|
||||
|
||||
;; XXX - Doesn't use routines to access memory under ROMs etc.
|
||||
;; This is important, because this routine operates on numbers in BASIC text.
|
||||
// XXX - Doesn't use routines to access memory under ROMs etc.
|
||||
// This is important, because this routine operates on numbers in BASIC text.
|
||||
|
||||
ij_not_a_digit:
|
||||
;; XXX check for "." or "E"
|
||||
;; Other chars terminate the accumulation.
|
||||
// XXX check for "." or "E"
|
||||
// Other chars terminate the accumulation.
|
||||
|
||||
;; Look for exponentiation marker
|
||||
;; XXX - Implement me!
|
||||
;; Probably should have a flag so that we know if we are accumulating
|
||||
;; exponent or mantissa digits
|
||||
// Look for exponentiation marker
|
||||
// XXX - Implement me!
|
||||
// Probably should have a flag so that we know if we are accumulating
|
||||
// exponent or mantissa digits
|
||||
|
||||
;; Look for decimal point
|
||||
// Look for decimal point
|
||||
cmp #$2e
|
||||
bne ij_not_decimal
|
||||
lda tokenise_work4
|
||||
cmp #$ff
|
||||
beq ij_found_decimal
|
||||
;; More than one decimal point in a number means we have reached the end of the number
|
||||
// More than one decimal point in a number means we have reached the end of the number
|
||||
clc
|
||||
rts
|
||||
|
||||
ij_found_decimal:
|
||||
;; Found decimal.
|
||||
;; Thus start counting digits after the decimal, so that we
|
||||
;; can do the necessary number of divide by 10s on the final
|
||||
;; number.
|
||||
// Found decimal.
|
||||
// Thus start counting digits after the decimal, so that we
|
||||
// can do the necessary number of divide by 10s on the final
|
||||
// number.
|
||||
lda #$00
|
||||
sta tokenise_work4
|
||||
|
||||
@@ -39,31 +39,30 @@ ij_found_decimal:
|
||||
|
||||
ij_not_decimal:
|
||||
|
||||
|
||||
CLC
|
||||
RTS
|
||||
clc
|
||||
rts
|
||||
|
||||
injest_number:
|
||||
;; Clear FAC1
|
||||
// Clear FAC1
|
||||
jsr erase_fac1
|
||||
|
||||
;; Clear decimal position flag
|
||||
// Clear decimal position flag
|
||||
lda #$ff
|
||||
sta tokenise_work4
|
||||
|
||||
;; Check if leading char is a - sign
|
||||
;; Note: the - will have been tokenised to $AB
|
||||
;; XXX - implement
|
||||
// Check if leading char is a - sign
|
||||
// Note: the - will have been tokenised to $AB
|
||||
// XXX - implement
|
||||
ldy #$00
|
||||
lda (basic_current_statement_ptr),y
|
||||
cmp #$AB
|
||||
bne ij_not_minus
|
||||
|
||||
;; Set sign to negative
|
||||
// Set sign to negative
|
||||
lda #$ff
|
||||
sta basic_fac1_sign
|
||||
|
||||
;; Skip over the minus sign
|
||||
// Skip over the minus sign
|
||||
jsr basic_consume_character
|
||||
|
||||
ij_not_minus:
|
||||
@@ -77,43 +76,43 @@ ij_loop1:
|
||||
cmp #$3a
|
||||
bcs ij_not_a_digit
|
||||
|
||||
;; It is a digit
|
||||
// It is a digit
|
||||
|
||||
;; Only add digit if we have not overflowed the accuracy of
|
||||
;; the mantissa
|
||||
// Only add digit if we have not overflowed the accuracy of
|
||||
// the mantissa
|
||||
lda basic_fac1_exponent
|
||||
beq ij_accept_precision
|
||||
|
||||
;; We have an extra digit after saturating our precision.
|
||||
;; Thus we should ignore the digit, and just multiply the FAC
|
||||
;; by 10, but only if we have not seen a decimal point.
|
||||
;; If we have seen a decimal point, then we can completely ignore
|
||||
;; the digit, as it is contributing not recordable information
|
||||
// We have an extra digit after saturating our precision.
|
||||
// Thus we should ignore the digit, and just multiply the FAC
|
||||
// by 10, but only if we have not seen a decimal point.
|
||||
// If we have seen a decimal point, then we can completely ignore
|
||||
// the digit, as it is contributing not recordable information
|
||||
|
||||
lda tokenise_work4
|
||||
cmp #$ff
|
||||
bne ij_seen_decimal_point
|
||||
|
||||
jsr fac1_mul10
|
||||
;; Fall through
|
||||
// Fall through
|
||||
ij_seen_decimal_point:
|
||||
jmp ij_consider_next_digit
|
||||
|
||||
ij_accept_precision:
|
||||
;; We can accept more precision, so multiply the mantissa by 10, so that
|
||||
;; we can add the new digit in
|
||||
// We can accept more precision, so multiply the mantissa by 10, so that
|
||||
// we can add the new digit in
|
||||
jsr fac1_mul10
|
||||
|
||||
lda basic_fac1_exponent
|
||||
bne ij_consider_next_digit
|
||||
|
||||
;; Get digit
|
||||
// Get digit
|
||||
ldy #$00
|
||||
lda (basic_current_statement_ptr),y
|
||||
sec
|
||||
sbc #$30
|
||||
|
||||
;; Add to FAC1 mantissa
|
||||
// Add to FAC1 mantissa
|
||||
clc
|
||||
adc basic_fac1_mantissa+0
|
||||
sta basic_fac1_mantissa+0
|
||||
@@ -127,16 +126,16 @@ ij_loop2:
|
||||
dey
|
||||
bne ij_loop2
|
||||
|
||||
bcc +
|
||||
;; Carry set, so we have overflowed.
|
||||
;; We should shift everything right one digit, and increase
|
||||
;; the exponent by one. The non-zero exponent tells us that we
|
||||
;; can't fit any more precision in.
|
||||
bcc !+
|
||||
// Carry set, so we have overflowed.
|
||||
// We should shift everything right one digit, and increase
|
||||
// the exponent by one. The non-zero exponent tells us that we
|
||||
// can't fit any more precision in.
|
||||
jsr fac1_mantissa_div2
|
||||
*
|
||||
!:
|
||||
|
||||
ij_consider_next_digit:
|
||||
;; Consider next digit
|
||||
// Consider next digit
|
||||
jsr basic_consume_character
|
||||
jmp ij_loop1
|
||||
|
||||
@@ -146,10 +145,10 @@ ij_consider_next_digit:
|
||||
erase_fac1:
|
||||
lda #$00
|
||||
ldx #8
|
||||
*
|
||||
!:
|
||||
sta basic_fac1_exponent,x
|
||||
dex
|
||||
bpl -
|
||||
bpl !-
|
||||
sta basic_fac1_mantissa_lob
|
||||
|
||||
rts
|
||||
|
||||
+88
-87
@@ -1,76 +1,77 @@
|
||||
;; Pack a word using the simple compression scheme.
|
||||
;; This has to be the same implementation as in compress_text.c
|
||||
;; because we compress input lines of BASIC to do the tokenisation.
|
||||
;; This allows us to search through the compressed tokens directly
|
||||
;; using the compressed fragment of BASIC, and thus work out the
|
||||
;; token for a given piece of string.
|
||||
;; This also helps ensure that we have an implementation that is totally
|
||||
;; different to that of the original C64 BASIC, as well as likely
|
||||
;; saving a bit of space in the ROM, especially once we start implementing
|
||||
;; larger keyword vocabs for BASIC 7 or BASIC 10 compatibility, since the
|
||||
;; compression and decompression machinery is of fixed size.
|
||||
// Pack a word using the simple compression scheme.
|
||||
// This has to be the same implementation as in compress_text.c
|
||||
// because we compress input lines of BASIC to do the tokenisation.
|
||||
// This allows us to search through the compressed tokens directly
|
||||
// using the compressed fragment of BASIC, and thus work out the
|
||||
// token for a given piece of string.
|
||||
// This also helps ensure that we have an implementation that is totally
|
||||
// different to that of the original C64 BASIC, as well as likely
|
||||
// saving a bit of space in the ROM, especially once we start implementing
|
||||
// larger keyword vocabs for BASIC 7 or BASIC 10 compatibility, since the
|
||||
// compression and decompression machinery is of fixed size.
|
||||
|
||||
pack_word:
|
||||
;; Inputs:
|
||||
;; X = offset of string to pack. Address is $0200 + X
|
||||
;; tokenise_work1 = number of bytes to pack
|
||||
;; tokenise_work2 = packed length of string
|
||||
// Inputs:
|
||||
// X = offset of string to pack. Address is $0200 + X
|
||||
// tokenise_work1 = number of bytes to pack
|
||||
// tokenise_work2 = packed length of string
|
||||
|
||||
;; Outputs:
|
||||
;; Output is written to $0100 (bottom of stack).
|
||||
// Outputs:
|
||||
// Output is written to $0100 (bottom of stack).
|
||||
|
||||
;; Memory modified:
|
||||
;; tokenise_work4 = temporary storage
|
||||
;; tokenise_work3 = flag for whether we have a nybl prepared or not.
|
||||
;; (This can also be checked on exit, to know whether the last byte
|
||||
;; is incomplete, which is important for searching for abbreviated
|
||||
;; key words.)
|
||||
// Memory modified:
|
||||
// tokenise_work4 = temporary storage
|
||||
// tokenise_work3 = flag for whether we have a nybl prepared or not.
|
||||
// (This can also be checked on exit, to know whether the last byte
|
||||
// is incomplete, which is important for searching for abbreviated
|
||||
// key words.)
|
||||
|
||||
|
||||
;; Make sure we have a sane request
|
||||
// Make sure we have a sane request
|
||||
lda tokenise_work1
|
||||
bne +
|
||||
bne !+
|
||||
sec
|
||||
rts
|
||||
*
|
||||
;; Initialise internal variables
|
||||
!:
|
||||
// Initialise internal variables
|
||||
lda #$00
|
||||
sta tokenise_work2
|
||||
sta tokenise_work3
|
||||
|
||||
pack_char_loop:
|
||||
|
||||
;; Get the next char
|
||||
// Get the next char
|
||||
lda $0200,x
|
||||
|
||||
;; Work out what type of character we have, and thus
|
||||
;; how we need to pack it.
|
||||
// Work out what type of character we have, and thus
|
||||
// how we need to pack it.
|
||||
jsr get_packed_char_index
|
||||
|
||||
cmp #$00
|
||||
bne not_exception_char
|
||||
|
||||
;; Char is an exception char.
|
||||
;; We need to either finish the previous byte with $xF,
|
||||
;; Or if there is no existing nybl, then we need to output
|
||||
;; either $FE or $FF, depending on whether this is the last
|
||||
;; byte or not
|
||||
// Char is an exception char.
|
||||
// We need to either finish the previous byte with $xF,
|
||||
// Or if there is no existing nybl, then we need to output
|
||||
// either $FE or $FF, depending on whether this is the last
|
||||
// byte or not
|
||||
|
||||
lda tokenise_work3
|
||||
bne have_nybl_before_exception_char
|
||||
|
||||
;; No nybl exists before the exception char, so prefix with $FE or $FF
|
||||
;; based on whether we are at the end of the input string or not
|
||||
// No nybl exists before the exception char, so prefix with $FE or $FF
|
||||
// based on whether we are at the end of the input string or not
|
||||
inx
|
||||
lda tokenise_work1
|
||||
cmp #$01
|
||||
beq at_end
|
||||
lda #$FF
|
||||
.byte $2C
|
||||
at_end: LDA #$FE
|
||||
at_end:
|
||||
lda #$FE
|
||||
dex
|
||||
jsr write_unpacked_char
|
||||
;; Fall through
|
||||
// Fall through
|
||||
|
||||
output_exception_byte:
|
||||
lda $0200,x
|
||||
@@ -78,18 +79,18 @@ output_exception_byte:
|
||||
jmp consider_next_char
|
||||
|
||||
have_nybl_before_exception_char:
|
||||
;; Or existing byte with #$0F, and clear nybl flag
|
||||
// Or existing byte with #$0F, and clear nybl flag
|
||||
ldy tokenise_work2
|
||||
lda $0100,y
|
||||
ora #$0f
|
||||
sta $0100,y
|
||||
inc tokenise_work2
|
||||
|
||||
;; FALL THROUGH
|
||||
// FALL THROUGH
|
||||
|
||||
write_literal_and_terminate_if_required:
|
||||
|
||||
;; Clear have nybl flag
|
||||
// Clear have nybl flag
|
||||
lda #$00
|
||||
sta tokenise_work3
|
||||
|
||||
@@ -99,19 +100,19 @@ write_literal_and_terminate_if_required:
|
||||
jmp end_string_if_required
|
||||
|
||||
end_string_if_required:
|
||||
;; Check if X points to last char of string to be packed
|
||||
// Check if X points to last char of string to be packed
|
||||
inx
|
||||
lda tokenise_work1
|
||||
cmp #$01
|
||||
beq +
|
||||
beq !+
|
||||
dex
|
||||
jmp consider_next_char
|
||||
*
|
||||
!:
|
||||
dex
|
||||
;; Fall through
|
||||
// Fall through
|
||||
|
||||
end_string:
|
||||
;; Write end of string sequence if required
|
||||
// Write end of string sequence if required
|
||||
lda #$00
|
||||
jsr write_unpacked_char
|
||||
rts
|
||||
@@ -124,53 +125,53 @@ write_unpacked_char:
|
||||
rts
|
||||
|
||||
not_exception_char:
|
||||
;; It wasn't an exception char, so write the symbol out
|
||||
// It wasn't an exception char, so write the symbol out
|
||||
cmp #$10
|
||||
bcs whole_byte_symbol
|
||||
|
||||
;; Nybl encoded value: Put in upper half or lower half of a byte?
|
||||
// Nybl encoded value: Put in upper half or lower half of a byte?
|
||||
ldy tokenise_work3
|
||||
bne store_low_nybl
|
||||
|
||||
;; Store in high nybl -- so shift it into the hi nybl
|
||||
// Store in high nybl -- so shift it into the hi nybl
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
ldy tokenise_work2
|
||||
sta $0100,y
|
||||
bne stored_nybl ; Must be taken, as A cannot be $00
|
||||
bne stored_nybl // Must be taken, as A cannot be $00
|
||||
|
||||
store_low_nybl:
|
||||
;; Low nybl gets added to high nybl already stored in the byte
|
||||
// Low nybl gets added to high nybl already stored in the byte
|
||||
ldy tokenise_work2
|
||||
ora $0100,y
|
||||
sta $0100,y
|
||||
|
||||
stored_nybl:
|
||||
;; Now toggle the nybl flag
|
||||
// Now toggle the nybl flag
|
||||
lda tokenise_work3
|
||||
eor #$ff
|
||||
sta tokenise_work3
|
||||
;; And advance the offset if we filled this byte up
|
||||
bne consider_next_char ; Taken if byte has a nybl free, i.e., don't advance pointer while half byte remains free
|
||||
// And advance the offset if we filled this byte up
|
||||
bne consider_next_char // Taken if byte has a nybl free, i.e., don't advance pointer while half byte remains free
|
||||
|
||||
;; Count the filled up byte
|
||||
// Count the filled up byte
|
||||
inc tokenise_work2
|
||||
|
||||
;; Add termination byte if required
|
||||
;; (This re-writes the same byte again, which we don't care about)
|
||||
// Add termination byte if required
|
||||
// (This re-writes the same byte again, which we don't care about)
|
||||
jmp end_string_if_required
|
||||
|
||||
whole_byte_symbol:
|
||||
;; It's a $Fx symbol.
|
||||
;; But if we have a nybl to flush, then we handle it like
|
||||
;; a full exception character
|
||||
// It's a $Fx symbol.
|
||||
// But if we have a nybl to flush, then we handle it like
|
||||
// a full exception character
|
||||
|
||||
ldy tokenise_work3
|
||||
beq nothing_to_flush
|
||||
|
||||
;; Set low nybl to $F to mark next byte as literal
|
||||
// Set low nybl to $F to mark next byte as literal
|
||||
ldy tokenise_work2
|
||||
lda $0100,y
|
||||
ora #$0f
|
||||
@@ -180,30 +181,30 @@ whole_byte_symbol:
|
||||
jmp write_literal_and_terminate_if_required
|
||||
|
||||
nothing_to_flush:
|
||||
;; Write the symbol as it is, or the literal
|
||||
;; if it has been passed to us via fall-through
|
||||
// Write the symbol as it is, or the literal
|
||||
// if it has been passed to us via fall-through
|
||||
jsr write_unpacked_char
|
||||
|
||||
jmp end_string_if_required
|
||||
|
||||
consider_next_char:
|
||||
;; Pack next char
|
||||
// Pack next char
|
||||
inx
|
||||
dec tokenise_work1
|
||||
beq +
|
||||
beq !+
|
||||
jmp pack_char_loop
|
||||
*
|
||||
;; Add 1 to length if nybl waiting to be flushed
|
||||
;; (but leave flag set so the caller knows if the
|
||||
;; bottom nybl might be different if the string were
|
||||
;; longer).
|
||||
!:
|
||||
// Add 1 to length if nybl waiting to be flushed
|
||||
// (but leave flag set so the caller knows if the
|
||||
// bottom nybl might be different if the string were
|
||||
// longer).
|
||||
lda tokenise_work3
|
||||
beq +
|
||||
beq !+
|
||||
inc tokenise_work2
|
||||
rts
|
||||
*
|
||||
;; Last byte was full, so we need at $00 on the end
|
||||
;; (unless a $FE token was written 2 bytes ago)
|
||||
!:
|
||||
// Last byte was full, so we need at $00 on the end
|
||||
// (unless a $FE token was written 2 bytes ago)
|
||||
ldy tokenise_work2
|
||||
iny
|
||||
lda #$00
|
||||
@@ -213,21 +214,21 @@ consider_next_char:
|
||||
rts
|
||||
|
||||
get_packed_char_index:
|
||||
;; Find char in A in the packed char list, and return
|
||||
;; $1 - $E, $F1 - $FD if the charactar is abbreviable,
|
||||
;; or else return $00 if the character has to be stored literally.
|
||||
// Find char in A in the packed char list, and return
|
||||
// $1 - $E, $F1 - $FD if the charactar is abbreviable,
|
||||
// or else return $00 if the character has to be stored literally.
|
||||
|
||||
;; Y register and A are modified, as are processor flags.
|
||||
// Y register and A are modified, as are processor flags.
|
||||
|
||||
ldy #$00
|
||||
find_char_loop:
|
||||
cmp packed_message_chars,y
|
||||
bne not_a_match
|
||||
enumerate:
|
||||
;; Is it a nybl abbreviable char?
|
||||
// Is it a nybl abbreviable char?
|
||||
cpy #14
|
||||
bcs not_nybl_char
|
||||
;; Yes, so add 1 and return it
|
||||
// Yes, so add 1 and return it
|
||||
iny
|
||||
tya
|
||||
rts
|
||||
@@ -235,9 +236,9 @@ enumerate:
|
||||
not_nybl_char:
|
||||
cpy #27
|
||||
bcs not_a_match
|
||||
;; It's a $Fx character.
|
||||
;; Since the lowest index is $E, and it should be encoded as $F1
|
||||
;; we need to add $E3
|
||||
// It's a $Fx character.
|
||||
// Since the lowest index is $E, and it should be encoded as $F1
|
||||
// we need to add $E3
|
||||
tya
|
||||
clc
|
||||
adc #$E3
|
||||
@@ -245,10 +246,10 @@ not_nybl_char:
|
||||
|
||||
not_a_match:
|
||||
iny
|
||||
;; Loop until we find it, or we discover it isn't
|
||||
;; a character with a special encoding
|
||||
// Loop until we find it, or we discover it isn't
|
||||
// a character with a special encoding
|
||||
cpy #27
|
||||
bne find_char_loop
|
||||
;; Not a char that we can pack, so return 0
|
||||
// Not a char that we can pack, so return 0
|
||||
lda #$00
|
||||
rts
|
||||
@@ -1,5 +1,5 @@
|
||||
;; Return C=1 if a pointer in BASIC memory space is NULL, else C=0
|
||||
;; X = ZP pointer to check
|
||||
// Return C=1 if a pointer in BASIC memory space is NULL, else C=0
|
||||
// X = ZP pointer to check
|
||||
|
||||
peek_pointer_null_check:
|
||||
ldy #$00
|
||||
@@ -11,10 +11,10 @@ peek_pointer_null_check:
|
||||
cmp #$00
|
||||
bne ptr_not_null
|
||||
|
||||
;; Pointer is NULL
|
||||
// Pointer is NULL
|
||||
clc
|
||||
rts
|
||||
ptr_not_null:
|
||||
sec
|
||||
rts
|
||||
|
||||
|
||||
+31
-30
@@ -1,26 +1,27 @@
|
||||
;; Works similar to $BDCD in original C64 BASIC
|
||||
;; XXX Should eventually get replaced by a more flexible and optimal routine.
|
||||
;; Temp result gets written to $0100-$0104
|
||||
// Works similar to $BDCD in original C64 BASIC
|
||||
// XXX Should eventually get replaced by a more flexible and optimal routine.
|
||||
// Temp result gets written to $0100-$0104
|
||||
|
||||
print_integer:
|
||||
|
||||
pha
|
||||
txa
|
||||
pha
|
||||
|
||||
;; Clear temporary output
|
||||
// Clear temporary output
|
||||
lda #$00
|
||||
ldy #5
|
||||
* sta $0100,y
|
||||
!: sta $0100,y
|
||||
dey
|
||||
bpl -
|
||||
bpl !-
|
||||
|
||||
pla
|
||||
ldy #23 ; 8 x 3 - 1 = offset of last digit of 128
|
||||
ldy #23 // 8 x 3 - 1 = offset of last digit of 128
|
||||
lo_loop:
|
||||
cmp #$7f
|
||||
bcc bit_clear
|
||||
|
||||
;; Bit set, so add the digits
|
||||
// Bit set, so add the digits
|
||||
pha
|
||||
ldx #2
|
||||
clc
|
||||
@@ -45,16 +46,16 @@ next_lo_bit:
|
||||
bcc lo_loop
|
||||
|
||||
|
||||
;; Now do the same for upper byte
|
||||
// Now do the same for upper byte
|
||||
pla
|
||||
|
||||
ldy #39 ; 8 x 5 - 1 = offset of last digit of 32768
|
||||
ldy #39 // 8 x 5 - 1 = offset of last digit of 32768
|
||||
hi_loop:
|
||||
cmp #$7f
|
||||
bcc bit_clear_hi
|
||||
|
||||
|
||||
;; Bit set, so add the digits
|
||||
// Bit set, so add the digits
|
||||
pha
|
||||
ldx #4
|
||||
clc
|
||||
@@ -67,8 +68,8 @@ hi_add_loop:
|
||||
dex
|
||||
bpl hi_add_loop
|
||||
pla
|
||||
jmp next_hi_bit
|
||||
|
||||
jmp next_hi_bit
|
||||
|
||||
bit_clear_hi:
|
||||
dey
|
||||
dey
|
||||
@@ -78,47 +79,47 @@ bit_clear_hi:
|
||||
next_hi_bit:
|
||||
asl
|
||||
cpy #$7f
|
||||
bcc hi_loop
|
||||
bcc hi_loop
|
||||
|
||||
fix_carry:
|
||||
|
||||
;; Deal with any carries
|
||||
|
||||
// Deal with any carries
|
||||
ldx #3
|
||||
carry_fix_loop:
|
||||
carry_fix_loop:
|
||||
lda $0101,x
|
||||
cmp #10
|
||||
bcc +
|
||||
bcc !+
|
||||
inc $0100,x
|
||||
sec
|
||||
sbc #10
|
||||
sta $0101,x
|
||||
|
||||
jmp carry_fix_loop
|
||||
|
||||
* dex
|
||||
|
||||
!: dex
|
||||
bpl carry_fix_loop
|
||||
|
||||
post_carry:
|
||||
post_carry:
|
||||
|
||||
;; Got digits.
|
||||
;; Skip leading zeros, and print the resulting number
|
||||
// Got digits.
|
||||
// Skip leading zeros, and print the resulting number
|
||||
|
||||
;; Skip leading zeros
|
||||
// Skip leading zeros
|
||||
ldy #0
|
||||
* lda $0100,y
|
||||
!: lda $0100,y
|
||||
bne found_start_of_number
|
||||
iny
|
||||
cpy #4
|
||||
bne -
|
||||
bne !-
|
||||
|
||||
found_start_of_number:
|
||||
;; Print digits
|
||||
* lda $0100,y
|
||||
found_start_of_number:
|
||||
// Print digits
|
||||
!: lda $0100,y
|
||||
ora #$30
|
||||
jsr JCHROUT
|
||||
iny
|
||||
cpy #5
|
||||
bne -
|
||||
bne !-
|
||||
|
||||
|
||||
rts
|
||||
|
||||
@@ -1,41 +1,42 @@
|
||||
;; This routine prints messages that have been packed
|
||||
;; using the make_error_tables program.
|
||||
;; The general idea is to save space in the ROM.
|
||||
// This routine prints messages that have been packed
|
||||
// using the make_error_tables program.
|
||||
// The general idea is to save space in the ROM.
|
||||
|
||||
// The output of make_error_tables is written to packed_messages.s, and
|
||||
// contains the following:
|
||||
//
|
||||
// packed_message_words - List of nybl packed words.
|
||||
// packed_message_tokens - List of tokens that get joined to make messages
|
||||
// packed_message_chars - List of characters in messages sorted by frequency.
|
||||
|
||||
|
||||
;; The output of make_error_tables is written to packed_messages.s, and
|
||||
;; contains the following:
|
||||
;;
|
||||
;; packed_message_words - List of nybl packed words.
|
||||
;; packed_message_tokens - List of tokens that get joined to make messages
|
||||
;; packed_message_chars - List of characters in messages sorted by frequency.
|
||||
|
||||
print_packed_message:
|
||||
;; X = message number
|
||||
// .X = message number
|
||||
|
||||
lda #$ff
|
||||
ldy #$ff
|
||||
packed_message_search:
|
||||
packed_message_search:
|
||||
iny
|
||||
cpx #$00
|
||||
beq found_message_in_token_stream
|
||||
lda packed_message_tokens,y
|
||||
cmp #$ff
|
||||
bne +
|
||||
bne !+
|
||||
dex
|
||||
*
|
||||
!:
|
||||
cpy #$ff
|
||||
bne packed_message_search
|
||||
;; Could not find message
|
||||
// Could not find message
|
||||
sec
|
||||
rts
|
||||
|
||||
found_message_in_token_stream:
|
||||
;; Now print each word in the message
|
||||
// Now print each word in the message
|
||||
tya
|
||||
pha
|
||||
lda packed_message_tokens,y
|
||||
cmp #$ff
|
||||
beq +
|
||||
beq !+
|
||||
jsr print_packed_word
|
||||
lda #$20
|
||||
jsr JCHROUT
|
||||
@@ -43,50 +44,50 @@ found_message_in_token_stream:
|
||||
tay
|
||||
iny
|
||||
bne found_message_in_token_stream
|
||||
*
|
||||
!:
|
||||
pla
|
||||
;; Rub out space at the end
|
||||
// Rub out space at the end
|
||||
lda #$14
|
||||
jsr JCHROUT
|
||||
rts
|
||||
|
||||
print_packed_word:
|
||||
;; A = the word to print
|
||||
// A = the word to print
|
||||
tax
|
||||
|
||||
;; Setup pointer to packed words
|
||||
// Setup pointer to packed words
|
||||
lda #<packed_message_words
|
||||
sta temp_string_ptr+0
|
||||
lda #>packed_message_words
|
||||
sta temp_string_ptr+1
|
||||
|
||||
;; Find the word in the list
|
||||
// Find the word in the list
|
||||
ldy #$ff
|
||||
packed_word_search:
|
||||
iny
|
||||
cpx #$00
|
||||
beq found_packed_word
|
||||
|
||||
;; $x0 is an end of work marker
|
||||
// $x0 is an end of work marker
|
||||
lda (temp_string_ptr),y
|
||||
and #$0f
|
||||
cmp #$00
|
||||
bne +
|
||||
bne !+
|
||||
dex
|
||||
*
|
||||
;; $FE $xx is an end of work marker
|
||||
!:
|
||||
// $FE $xx is an end of work marker
|
||||
lda (temp_string_ptr),y
|
||||
cmp #$fe
|
||||
bne +
|
||||
bne !+
|
||||
dex
|
||||
iny ; skip next byte
|
||||
*
|
||||
iny // skip next byte
|
||||
!:
|
||||
cmp #$ff
|
||||
bne +
|
||||
iny ; skip next byte
|
||||
*
|
||||
bne !+
|
||||
iny // skip next byte
|
||||
!:
|
||||
|
||||
;; Advance to next page if required
|
||||
// Advance to next page if required
|
||||
cpy #$ff
|
||||
bne packed_word_search
|
||||
inc temp_string_ptr+1
|
||||
@@ -94,8 +95,8 @@ packed_word_search:
|
||||
|
||||
found_packed_word:
|
||||
|
||||
;; Get pointer to start of packed word
|
||||
;; Make sure we don't wrap on a page boundary
|
||||
// Get pointer to start of packed word
|
||||
// Make sure we don't wrap on a page boundary
|
||||
tya
|
||||
clc
|
||||
adc temp_string_ptr+0
|
||||
@@ -104,14 +105,14 @@ found_packed_word:
|
||||
adc #$00
|
||||
sta temp_string_ptr+1
|
||||
|
||||
print_packed_string:
|
||||
print_packed_string:
|
||||
ldy #$ff
|
||||
|
||||
next_packed_word_char:
|
||||
;; Y = offset into packed word data - 1
|
||||
// .Y = offset into packed word data - 1
|
||||
iny
|
||||
|
||||
;; Check for end of word
|
||||
|
||||
// Check for end of word
|
||||
lda (temp_string_ptr),y
|
||||
cmp #$00
|
||||
beq end_of_packed_word
|
||||
@@ -122,31 +123,31 @@ next_packed_word_char:
|
||||
and #$f0
|
||||
beq end_of_packed_word
|
||||
|
||||
;; Check if it is an uncommon char
|
||||
// Check if it is an uncommon char
|
||||
lda (temp_string_ptr),y
|
||||
and #$f0
|
||||
cmp #$f0
|
||||
beq is_uncommon_char
|
||||
|
||||
;; Is not an uncommon char, so get char of upper nybl
|
||||
// Is not an uncommon char, so get char of upper nybl
|
||||
lda (temp_string_ptr),y
|
||||
|
||||
;; Put high nybl into low bits of X
|
||||
// Put high nybl into low bits of X
|
||||
lsr
|
||||
lsr
|
||||
lsr
|
||||
lsr
|
||||
tax
|
||||
|
||||
;; Save Y so it doesn't get clobbered by CHROUT
|
||||
// Save Y so it doesn't get clobbered by CHROUT
|
||||
tya
|
||||
pha
|
||||
|
||||
;; X=1-14 = first 14 chars, so subtract one
|
||||
// X=1-14 = first 14 chars, so subtract one
|
||||
lda packed_message_chars-1,x
|
||||
jsr JCHROUT
|
||||
|
||||
;; See if there is a char in the low nybl to print
|
||||
// See if there is a char in the low nybl to print
|
||||
pla
|
||||
tay
|
||||
lda (temp_string_ptr),y
|
||||
@@ -155,54 +156,54 @@ next_packed_word_char:
|
||||
cmp #$0f
|
||||
beq no_lo_nybl_char
|
||||
|
||||
has_lo_nybl_char:
|
||||
;; We need to print the low nybl char as well
|
||||
has_lo_nybl_char:
|
||||
// We need to print the low nybl char as well
|
||||
tax
|
||||
tya
|
||||
pha
|
||||
|
||||
;; Skip lower nybls of $F or $0 in nybl packed
|
||||
;; bytes, as these do not encode characters
|
||||
// Skip lower nybls of $F or $0 in nybl packed
|
||||
// bytes, as these do not encode characters
|
||||
cpx #$f
|
||||
beq +
|
||||
has_nybl:
|
||||
beq !+
|
||||
has_nybl:
|
||||
cpx #0
|
||||
beq +
|
||||
beq !+
|
||||
|
||||
;; X=1-14 = first 14 chars, so subtract one
|
||||
// X=1-14 = first 14 chars, so subtract one
|
||||
lda packed_message_chars-1,x
|
||||
jsr JCHROUT
|
||||
*
|
||||
!:
|
||||
pla
|
||||
tay
|
||||
;; FALL THROUGH
|
||||
// FALLTHROUGH
|
||||
|
||||
no_lo_nybl_char:
|
||||
|
||||
;; If current byte has $0F in low nybl, then the next
|
||||
;; byte is a whole byte.
|
||||
// If current byte has $0F in low nybl, then the next
|
||||
// byte is a whole byte.
|
||||
lda (temp_string_ptr),y
|
||||
and #$0f
|
||||
cmp #$0f
|
||||
beq next_is_literal_char
|
||||
|
||||
ready_for_next_char:
|
||||
ready_for_next_char:
|
||||
cpy #$ff
|
||||
bne next_packed_word_char
|
||||
end_of_packed_word:
|
||||
;; Hit end of packed data
|
||||
end_of_packed_word:
|
||||
// Hit end of packed data
|
||||
rts
|
||||
|
||||
last_literal:
|
||||
jsr unpack_literal_char
|
||||
rts
|
||||
|
||||
|
||||
next_is_literal_char:
|
||||
jsr unpack_literal_char
|
||||
jmp ready_for_next_char
|
||||
|
||||
unpack_literal_char:
|
||||
;; Output the literal char, and ready for next char
|
||||
unpack_literal_char:
|
||||
// Output the literal char, and ready for next char
|
||||
iny
|
||||
tya
|
||||
pha
|
||||
@@ -211,16 +212,16 @@ unpack_literal_char:
|
||||
pla
|
||||
tay
|
||||
rts
|
||||
|
||||
|
||||
is_uncommon_char:
|
||||
;; Lower nybl has offset into low-frequency part of the table
|
||||
// Lower nybl has offset into low-frequency part of the table
|
||||
|
||||
lda (temp_string_ptr),y
|
||||
and #$0f
|
||||
clc
|
||||
adc #14
|
||||
|
||||
;; We need to print the low nybl char as well
|
||||
// We need to print the low nybl char as well
|
||||
tax
|
||||
tya
|
||||
pha
|
||||
|
||||
+38
-38
@@ -1,17 +1,17 @@
|
||||
;; printf()-like routine for simplifying debugging
|
||||
// printf()-like routine for simplifying debugging
|
||||
|
||||
;; Prints the literal zero-terminated string that follows,
|
||||
;; which may also include special tokens that allow
|
||||
;; printing of hex byte and word values stored at the indicated
|
||||
;; addresses.
|
||||
// Prints the literal zero-terminated string that follows,
|
||||
// which may also include special tokens that allow
|
||||
// printing of hex byte and word values stored at the indicated
|
||||
// addresses.
|
||||
|
||||
;; .byte 1,$byte = display byte as hex
|
||||
;; .byte 2,$low,$hi = display word as hex
|
||||
;; .byte $f0+n,$low,$hi = display byte at $hi$lo+n as hex
|
||||
// .byte 1,$byte = display byte as hex
|
||||
// .byte 2,$low,$hi = display word as hex
|
||||
// .byte $f0+n,$low,$hi = display byte at $hi$lo+n as hex
|
||||
|
||||
printf:
|
||||
;; Temporary storage is between end of screen at $0400
|
||||
;; and the sprite pointers at $7f8
|
||||
// Temporary storage is between end of screen at $0400
|
||||
// and the sprite pointers at $7f8
|
||||
sta $7f0
|
||||
stx $7f1
|
||||
sty $7f2
|
||||
@@ -19,14 +19,14 @@ printf:
|
||||
pla
|
||||
sta $7f3
|
||||
|
||||
;; Set up read routine
|
||||
lda #$ad ; LDA $nnnn
|
||||
// Set up read routine
|
||||
lda #$ad // LDA $nnnn
|
||||
sta $7f4
|
||||
lda #$60
|
||||
sta $7f7 ; RTS
|
||||
sta $7f7 // RTS
|
||||
|
||||
;; Get PC of caller from the stack, so that
|
||||
;; we can parse through it
|
||||
// Get PC of caller from the stack, so that
|
||||
// we can parse through it
|
||||
pla
|
||||
clc
|
||||
adc #$01
|
||||
@@ -39,8 +39,8 @@ printf_loop:
|
||||
jsr $7f4
|
||||
cmp #$00
|
||||
bne printf_continues
|
||||
;; Put return address on stack and restore
|
||||
;; registers
|
||||
// Put return address on stack and restore
|
||||
// registers
|
||||
lda $7f6
|
||||
pha
|
||||
lda $7f5
|
||||
@@ -56,33 +56,33 @@ printf_loop:
|
||||
printf_continues:
|
||||
cmp #$01
|
||||
bne not_hexbyte
|
||||
;; Print a hex byte
|
||||
// Print a hex byte
|
||||
|
||||
;; Skip the token
|
||||
// Skip the token
|
||||
jsr printf_advance
|
||||
;; Read the low byte
|
||||
// Read the low byte
|
||||
jsr $7f4
|
||||
;; Print as hex
|
||||
// Print as hex
|
||||
jsr printf_printhexbyte
|
||||
jmp printf_nextchar
|
||||
|
||||
not_hexbyte:
|
||||
cmp #$02
|
||||
bne not_hexword
|
||||
;; Print a hex word
|
||||
// Print a hex word
|
||||
|
||||
;; Skip the token
|
||||
// Skip the token
|
||||
jsr printf_advance
|
||||
jsr printf_advance
|
||||
;; Read the high byte
|
||||
// Read the high byte
|
||||
jsr $7f4
|
||||
;; Print as hex
|
||||
// Print as hex
|
||||
jsr printf_printhexbyte
|
||||
;; Skip the token
|
||||
// Skip the token
|
||||
jsr printf_retreat
|
||||
;; Read the low byte
|
||||
// Read the low byte
|
||||
jsr $7f4
|
||||
;; Print as hex
|
||||
// Print as hex
|
||||
jsr printf_printhexbyte
|
||||
jsr printf_advance
|
||||
jmp printf_nextchar
|
||||
@@ -91,11 +91,11 @@ not_hexword:
|
||||
cmp #$f0
|
||||
bcc not_pointer
|
||||
|
||||
;; Treat two-byte arg as base address
|
||||
;; and lower 4 bits of token as offset from
|
||||
;; that location.
|
||||
// Treat two-byte arg as base address
|
||||
// and lower 4 bits of token as offset from
|
||||
// that location.
|
||||
|
||||
;; Get offset
|
||||
// Get offset
|
||||
and #$0f
|
||||
tay
|
||||
|
||||
@@ -111,7 +111,7 @@ not_hexword:
|
||||
jmp printf_nextchar
|
||||
|
||||
not_pointer:
|
||||
;; Print character
|
||||
// Print character
|
||||
jsr JCHROUT
|
||||
|
||||
printf_nextchar:
|
||||
@@ -120,15 +120,15 @@ printf_nextchar:
|
||||
jmp printf_loop
|
||||
|
||||
printf_advance:
|
||||
;; Advance pointer to next character
|
||||
// Advance pointer to next character
|
||||
inc $7f5
|
||||
bne +
|
||||
bne !+
|
||||
inc $7f6
|
||||
*
|
||||
!:
|
||||
rts
|
||||
|
||||
printf_retreat:
|
||||
;; Retreat pointer to previous char
|
||||
// Retreat pointer to previous char
|
||||
lda $7f5
|
||||
sec
|
||||
sbc #1
|
||||
@@ -139,7 +139,7 @@ printf_retreat:
|
||||
rts
|
||||
|
||||
printf_printhexbyte:
|
||||
;; Print the hex value in .A as two digits, idea by Haubitze
|
||||
// Print the hex value in .A as two digits, idea by Haubitze
|
||||
sed
|
||||
pha
|
||||
lsr
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
ready_message:
|
||||
;; See src/make_error_tables.c for packed message handling
|
||||
;; information.
|
||||
// See src/make_error_tables.c for packed message handling
|
||||
// information.
|
||||
ldx #29
|
||||
jmp print_packed_message
|
||||
|
||||
+10
-10
@@ -1,19 +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
|
||||
// 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
|
||||
// Note: if tape support is introduced here, make sure DOS wedge won't get broken
|
||||
|
||||
ldx current_device_number
|
||||
cpx #$08
|
||||
bcs +
|
||||
bcs !+
|
||||
ldx #$08
|
||||
*
|
||||
!:
|
||||
rts
|
||||
+100
-100
@@ -1,18 +1,18 @@
|
||||
;; Tokenise a line of BASIC
|
||||
;; Stored at $0200
|
||||
;; Length in tokenise_work1
|
||||
// Tokenise a line of BASIC
|
||||
// Stored at $0200
|
||||
// Length in tokenise_work1
|
||||
|
||||
tokenise_line:
|
||||
|
||||
;; We need to consider each offset in the string to see if it matches
|
||||
;; a token. No BASIC keyword is > 7 bytes, so we need to start with that
|
||||
;; length (or remaining length of string) and count our way back down.
|
||||
;; This means we need separate start and end points to keep track of.
|
||||
// We need to consider each offset in the string to see if it matches
|
||||
// a token. No BASIC keyword is > 7 bytes, so we need to start with that
|
||||
// length (or remaining length of string) and count our way back down.
|
||||
// This means we need separate start and end points to keep track of.
|
||||
|
||||
;; $0110 = offset into string
|
||||
;; $0111 = number of bytes to pack
|
||||
;; $0112 = offset into tokenised output
|
||||
;; $0113 = length of raw string
|
||||
// $0110 = offset into string
|
||||
// $0111 = number of bytes to pack
|
||||
// $0112 = offset into tokenised output
|
||||
// $0113 = length of raw string
|
||||
|
||||
lda #$00
|
||||
sta $0110
|
||||
@@ -24,56 +24,56 @@ tokenise_line:
|
||||
|
||||
tokenise_char:
|
||||
|
||||
;; Check if we have reached end of the line?
|
||||
// Check if we have reached end of the line?
|
||||
lda $0110
|
||||
cmp $0113
|
||||
bne +
|
||||
bne !+
|
||||
|
||||
;; End of line reached
|
||||
// End of line reached
|
||||
|
||||
;; Finished tokenising line
|
||||
;; Update tokenise_work1 and terminate with null
|
||||
// Finished tokenising line
|
||||
// Update tokenise_work1 and terminate with null
|
||||
ldx $0112
|
||||
lda #$00
|
||||
sta $0200,x
|
||||
stx tokenise_work1
|
||||
|
||||
;; Clear quote mode flag that is also used by KERNAL for screen display
|
||||
// Clear quote mode flag that is also used by KERNAL for screen display
|
||||
lda #$00
|
||||
sta quote_mode_flag
|
||||
rts
|
||||
*
|
||||
;; More to do
|
||||
!:
|
||||
// More to do
|
||||
|
||||
;; Maximum keyword length
|
||||
// Maximum keyword length
|
||||
lda #7
|
||||
sta $0111
|
||||
|
||||
tokenise_char_loop:
|
||||
;; Pack the word from the start (start = X, raw len = tokenise_work1)
|
||||
;; Returns packed length in tokenise_work2 and writes the packed
|
||||
;; word at $0100+
|
||||
// Pack the word from the start (start = X, raw len = tokenise_work1)
|
||||
// Returns packed length in tokenise_work2 and writes the packed
|
||||
// word at $0100+
|
||||
|
||||
ldx $0110
|
||||
lda $0200,x
|
||||
cmp #$22
|
||||
bne tk_not_quote
|
||||
|
||||
;; Quote
|
||||
// Quote
|
||||
lda quote_mode_flag
|
||||
eor #$ff
|
||||
sta quote_mode_flag
|
||||
jmp tk_literal_char
|
||||
|
||||
tk_not_quote:
|
||||
;; Check for literal characters in various ranges
|
||||
;; (This just speeds the tokeniser up, by avoiding the packed token search
|
||||
;; for such characters).
|
||||
// Check for literal characters in various ranges
|
||||
// (This just speeds the tokeniser up, by avoiding the packed token search
|
||||
// for such characters).
|
||||
|
||||
;; SPACE and punctuation before +,- and *
|
||||
// SPACE and punctuation before +,- and *
|
||||
cmp #$2a
|
||||
bcc tk_literal_char
|
||||
;; Don't try to tokenise digits
|
||||
// Don't try to tokenise digits
|
||||
cmp #$30
|
||||
bcc tk_might_be_keyword
|
||||
cmp #$3a
|
||||
@@ -81,41 +81,41 @@ tk_not_quote:
|
||||
jmp tk_literal_char
|
||||
|
||||
tk_might_be_keyword:
|
||||
;; Don't tokenise in quote mode
|
||||
// Don't tokenise in quote mode
|
||||
lda quote_mode_flag
|
||||
bne tk_literal_char
|
||||
|
||||
;; Pack string
|
||||
// Pack string
|
||||
ldx $0110
|
||||
lda $0111
|
||||
sta tokenise_work1
|
||||
|
||||
;; XXX - We should implement an optimisation where we
|
||||
;; trim the last symbol of successively, instead of re-packing the word
|
||||
;; again with one less char each time.
|
||||
;; XXX - We should limit the word length to the length of interesting chars
|
||||
;; that are available.
|
||||
// XXX - We should implement an optimisation where we
|
||||
// trim the last symbol of successively, instead of re-packing the word
|
||||
// again with one less char each time.
|
||||
// XXX - We should limit the word length to the length of interesting chars
|
||||
// that are available.
|
||||
|
||||
jsr pack_word
|
||||
lda tokenise_work2
|
||||
cmp #$10
|
||||
bcc +
|
||||
;; Packed string too long
|
||||
bcc !+
|
||||
// Packed string too long
|
||||
jmp do_STRING_TOO_LONG_error
|
||||
*
|
||||
!:
|
||||
|
||||
;; Search for it in keywords
|
||||
// Search for it in keywords
|
||||
jsr keyword_search
|
||||
|
||||
;; Did we find a keyword?
|
||||
// Did we find a keyword?
|
||||
bcc found_token_in_line
|
||||
|
||||
;; Nope, so try shorter
|
||||
// Nope, so try shorter
|
||||
dec $0111
|
||||
bne tokenise_char_loop
|
||||
|
||||
tk_literal_char:
|
||||
;; Is not a token, so copy to output verbatim
|
||||
// Is not a token, so copy to output verbatim
|
||||
ldx $0110
|
||||
ldy $0112
|
||||
lda $0200,x
|
||||
@@ -123,68 +123,68 @@ tk_literal_char:
|
||||
inc $0112
|
||||
inc $0110
|
||||
|
||||
;; Tokenise next char
|
||||
// Tokenise next char
|
||||
jmp tokenise_char
|
||||
|
||||
found_token_in_line:
|
||||
|
||||
;; Got a token, so write it out
|
||||
// Got a token, so write it out
|
||||
ldx $0112
|
||||
sta $0200,x
|
||||
inx
|
||||
stx $0112
|
||||
|
||||
;; If it is REM, then lock us in quote mode to the end of the line
|
||||
// If it is REM, then lock us in quote mode to the end of the line
|
||||
cmp #$8f
|
||||
bne not_rem
|
||||
sta quote_mode_flag
|
||||
not_rem:
|
||||
|
||||
;; Now skip over the length of the token
|
||||
// Now skip over the length of the token
|
||||
lda $0110
|
||||
clc
|
||||
adc $0111
|
||||
sta $0110
|
||||
|
||||
;; See if there is more of the line left to process
|
||||
// See if there is more of the line left to process
|
||||
jmp tokenise_char
|
||||
|
||||
|
||||
|
||||
|
||||
;; Search for word in keyword list
|
||||
;; The packed form is canonical, so we can search for the keyword while
|
||||
;; it remains compressed. This also saves a little time.
|
||||
;; Algorithm is simply to find matching first bytes, and then look for
|
||||
;; the rest being a match.
|
||||
|
||||
|
||||
// Search for word in keyword list
|
||||
// The packed form is canonical, so we can search for the keyword while
|
||||
// it remains compressed. This also saves a little time.
|
||||
// Algorithm is simply to find matching first bytes, and then look for
|
||||
// the rest being a match.
|
||||
|
||||
keyword_search:
|
||||
;; Search for the compressed keyword stored at $0100 in the list
|
||||
;; of compressed keywords
|
||||
|
||||
;; tokenise_work1 = offset in line of input
|
||||
;; tokenise_work2 = length of token we are matching
|
||||
;; tokenise_work3 = offset in token list
|
||||
;; load_or_verify_or_tokenise_work5 = temporary work space
|
||||
;; X and Y registers used as temporary space.
|
||||
;; returns C=1 if no matching token, else C=0 and A=token
|
||||
// Search for the compressed keyword stored at $0100 in the list
|
||||
// of compressed keywords
|
||||
|
||||
// tokenise_work1 = offset in line of input
|
||||
// tokenise_work2 = length of token we are matching
|
||||
// tokenise_work3 = offset in token list
|
||||
// load_or_verify_or_tokenise_work5 = temporary work space
|
||||
// X and Y registers used as temporary space.
|
||||
// returns C=1 if no matching token, else C=0 and A=token
|
||||
|
||||
lda #$00
|
||||
sta tokenise_work1
|
||||
sta tokenise_work3
|
||||
next_kw_offset:
|
||||
;; Advance offset in compressed keyword list, to see if a match
|
||||
;; BEGINS here
|
||||
// Advance offset in compressed keyword list, to see if a match
|
||||
// BEGINS here
|
||||
|
||||
;; Get count of bytes to compare
|
||||
// Get count of bytes to compare
|
||||
lda tokenise_work2
|
||||
sta load_or_verify_or_tokenise_work5
|
||||
|
||||
;; Load current position
|
||||
|
||||
// Load current position
|
||||
ldy tokenise_work3
|
||||
ldx tokenise_work1
|
||||
|
||||
;; Advance offset in compressed token list, and stop at the end
|
||||
|
||||
// Advance offset in compressed token list, and stop at the end
|
||||
inc tokenise_work3
|
||||
lda tokenise_work3
|
||||
cmp #packed_keyword_table_len
|
||||
@@ -194,76 +194,76 @@ next_in_match:
|
||||
lda $0100,x
|
||||
cmp packed_keywords,y
|
||||
bne next_kw_offset
|
||||
;; Advance to next chars in source and target
|
||||
// Advance to next chars in source and target
|
||||
inx
|
||||
iny
|
||||
|
||||
dec load_or_verify_or_tokenise_work5 ; Have we compared all bytes yet?
|
||||
dec load_or_verify_or_tokenise_work5 // Have we compared all bytes yet?
|
||||
|
||||
bne next_in_match
|
||||
|
||||
;; Keyword matches!
|
||||
// Keyword matches!
|
||||
|
||||
;; Now make sure we started on a keyword boundary
|
||||
;; (we know we finished on one, because of the structure of the compressed
|
||||
;; keyword data).
|
||||
;; Offset 0
|
||||
;; previous byte is $x0
|
||||
;; two byte prior is $FE
|
||||
// Now make sure we started on a keyword boundary
|
||||
// (we know we finished on one, because of the structure of the compressed
|
||||
// keyword data).
|
||||
// Offset 0
|
||||
// previous byte is $x0
|
||||
// two byte prior is $FE
|
||||
|
||||
;; Get offset of first byte of this token
|
||||
// Get offset of first byte of this token
|
||||
ldx tokenise_work3
|
||||
dex ; pointer points one late, so rewind it
|
||||
dex // pointer points one late, so rewind it
|
||||
|
||||
;; At start of list?
|
||||
// At start of list?
|
||||
cpx #$00
|
||||
beq word_boundary
|
||||
dex
|
||||
;; Previous byte is $x0 end token?
|
||||
// Previous byte is $x0 end token?
|
||||
lda packed_keywords,x
|
||||
and #$0f
|
||||
beq word_boundary
|
||||
dex
|
||||
;; Uber-previouss byte is $FE final literal token?
|
||||
// Uber-previouss byte is $FE final literal token?
|
||||
lda packed_keywords,x
|
||||
cmp #$fe
|
||||
beq word_boundary
|
||||
|
||||
;; Not a word boundary, so ignore
|
||||
// Not a word boundary, so ignore
|
||||
jmp next_kw_offset
|
||||
|
||||
word_boundary:
|
||||
;; Found a token whose offset is in tokenise_work3
|
||||
;; Now trace back to the start of the compressed keyword list
|
||||
;; to work out what keyword number we are, so that we can return
|
||||
;; the token number.
|
||||
// Found a token whose offset is in tokenise_work3
|
||||
// Now trace back to the start of the compressed keyword list
|
||||
// to work out what keyword number we are, so that we can return
|
||||
// the token number.
|
||||
|
||||
ldy #$80
|
||||
|
||||
token_count_loop:
|
||||
lda packed_keywords,x
|
||||
cmp #$fe
|
||||
bne +
|
||||
bne !+
|
||||
iny
|
||||
*
|
||||
!:
|
||||
and #$0f
|
||||
cmp #$00
|
||||
bne +
|
||||
bne !+
|
||||
iny
|
||||
*
|
||||
!:
|
||||
cpx #$00
|
||||
beq +
|
||||
beq !+
|
||||
dex
|
||||
jmp token_count_loop
|
||||
*
|
||||
|
||||
!:
|
||||
|
||||
tya
|
||||
clc
|
||||
rts
|
||||
|
||||
|
||||
done_searching_for_token:
|
||||
;; No token found
|
||||
// No token found
|
||||
sec
|
||||
lda #$00
|
||||
rts
|
||||
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
;; IMPORTANT:
|
||||
;; These routines lengths cannot be changed without changing
|
||||
;; the aliases for peek_under_roms, poke_under_roms etc
|
||||
;; in ,aliases.s.
|
||||
;; Thus those addresses are expressed using formulae.
|
||||
// IMPORTANT:
|
||||
// These routines lengths cannot be changed without changing
|
||||
// the aliases for peek_under_roms, poke_under_roms etc
|
||||
// in ,aliases.s.
|
||||
// Thus those addresses are expressed using formulae.
|
||||
|
||||
install_ram_routines:
|
||||
;; Copy routines into place
|
||||
ldx #ram_routines_len-1
|
||||
*
|
||||
// Copy routines into place
|
||||
ldx #ram_routines_end-ram_routines_start-1
|
||||
!:
|
||||
lda ram_routines_start,x
|
||||
sta tiny_nmi_handler,x
|
||||
dex
|
||||
bpl -
|
||||
bpl !-
|
||||
|
||||
;; Point NMI handler to tiny_nmi_handler
|
||||
// Point NMI handler to tiny_nmi_handler
|
||||
lda #<tiny_nmi_handler
|
||||
sta $FFFE
|
||||
lda #>tiny_nmi_handler
|
||||
@@ -23,14 +23,14 @@ install_ram_routines:
|
||||
|
||||
ram_routines_start:
|
||||
|
||||
;; XXX - Routine order must match that of the KERNAL version of the file.
|
||||
;; (since it has fewer routines)
|
||||
// XXX - Routine order must match that of the KERNAL version of the file.
|
||||
// (since it has fewer routines)
|
||||
tiny_nmi_handler_routine:
|
||||
inc missed_nmi_flag
|
||||
rti
|
||||
peek_under_roms_routine:
|
||||
php
|
||||
; Offset of arg of lda ($00),y
|
||||
// Offset of arg of lda ($00),y
|
||||
stx peek_under_roms+pa-peek_under_roms_routine+1
|
||||
jsr memmap_allram
|
||||
pa: lda ($00),y
|
||||
@@ -40,7 +40,7 @@ pa: lda ($00),y
|
||||
|
||||
poke_under_roms_routine:
|
||||
php
|
||||
; Offset of arg of lda ($00),y
|
||||
// Offset of arg of lda ($00),y
|
||||
stx poke_under_roms+pb-poke_under_roms_routine+1
|
||||
jsr memmap_allram
|
||||
pb: sta ($00),y
|
||||
@@ -64,12 +64,12 @@ memmap_allram_routine:
|
||||
rts
|
||||
|
||||
shift_mem_up_routine:
|
||||
;; Move memmove_size bytes from memmove_src to memmove_dst,
|
||||
;; where memmove_dst > memmove_src
|
||||
;; This means we have to copy from the back end down.
|
||||
;; This routine assumes the pointers are already pointed
|
||||
;; to the end of the areas, and that Y is correctly initialised
|
||||
;; to allow the copy to begin.
|
||||
// Move memmove_size bytes from memmove_src to memmove_dst,
|
||||
// where memmove_dst > memmove_src
|
||||
// This means we have to copy from the back end down.
|
||||
// This routine assumes the pointers are already pointed
|
||||
// to the end of the areas, and that Y is correctly initialised
|
||||
// to allow the copy to begin.
|
||||
php
|
||||
jsr memmap_allram
|
||||
smu1:
|
||||
@@ -85,12 +85,12 @@ smu1:
|
||||
jmp memmap_normal
|
||||
|
||||
shift_mem_down_routine:
|
||||
;; Move memmove_size bytes from memmove_src to memmove_dst,
|
||||
;; where memmove_dst > memmove_src
|
||||
;; This means we have to copy from the back end down.
|
||||
;; This routine assumes the pointers are already pointed
|
||||
;; to the end of the areas, and that Y is correctly initialised
|
||||
;; to allow the copy to begin.
|
||||
// Move memmove_size bytes from memmove_src to memmove_dst,
|
||||
// where memmove_dst > memmove_src
|
||||
// This means we have to copy from the back end down.
|
||||
// This routine assumes the pointers are already pointed
|
||||
// to the end of the areas, and that Y is correctly initialised
|
||||
// to allow the copy to begin.
|
||||
php
|
||||
jsr memmap_allram
|
||||
smd1:
|
||||
@@ -105,7 +105,4 @@ smd1:
|
||||
plp
|
||||
jmp memmap_normal
|
||||
|
||||
|
||||
ram_routines_end:
|
||||
.alias ram_routines_len ram_routines_end-ram_routines_start
|
||||
|
||||
+89
-89
@@ -1,161 +1,161 @@
|
||||
|
||||
;; START wedge support
|
||||
// START wedge support
|
||||
|
||||
wedge_dos:
|
||||
|
||||
;; Close all the channels, so that wedge has full control
|
||||
// Close all the channels, so that wedge has full control
|
||||
jsr JCLALL
|
||||
|
||||
;; Set file parameters, channel 15 is a typical one for commands
|
||||
jsr select_device ; sets X register
|
||||
// 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
|
||||
// Now we have to check what the user wants us to do
|
||||
|
||||
;; Check if user asked for a status
|
||||
// Check if user asked for a status
|
||||
ldy #$00
|
||||
lda (basic_current_statement_ptr), y
|
||||
bne +
|
||||
jmp wedge_dos_status ; XXX try to optimize this, perhaps move 'wedge_dos_status' above?
|
||||
*
|
||||
;; Check if asked for a directory
|
||||
bne !+
|
||||
jmp wedge_dos_status // XXX try to optimize this, perhaps move 'wedge_dos_status' above?
|
||||
!:
|
||||
// Check if asked for a directory
|
||||
cmp #$24
|
||||
bne +
|
||||
bne !+
|
||||
jmp wedge_dos_directory
|
||||
*
|
||||
;; Check if asked to change drive number, or if it is a regular command
|
||||
!:
|
||||
// Check if asked to change drive number, or if it is a regular command
|
||||
cmp #$30
|
||||
bcc wedge_dos_command ; char code before 0
|
||||
bcc wedge_dos_command // char code before 0
|
||||
cmp #$3A
|
||||
bcs wedge_dos_command ; char code after 9
|
||||
bcs wedge_dos_command // char code after 9
|
||||
iny
|
||||
lda (basic_current_statement_ptr), y
|
||||
beq wedge_dos_change_drive ; end of buffer
|
||||
beq wedge_dos_change_drive // end of buffer
|
||||
cmp #$20
|
||||
beq wedge_dos_change_drive
|
||||
jmp -
|
||||
jmp !-
|
||||
|
||||
wedge_dos_command:
|
||||
|
||||
;; Provide command name
|
||||
// Provide command name
|
||||
jsr wedge_dos_setnam
|
||||
|
||||
jsr JSETNAM
|
||||
jsr JOPEN
|
||||
bcc +
|
||||
jmp wedge_dos_basic_error ; XXX combine with other such jumps
|
||||
*
|
||||
;; Retrieve status, print it if not OK
|
||||
bcc !+
|
||||
jmp wedge_dos_basic_error // XXX combine with other such jumps
|
||||
!:
|
||||
// Retrieve status, print it if not OK
|
||||
jsr JCLALL
|
||||
jsr wedge_dos_status_get
|
||||
lda BUF+0
|
||||
cmp #$30 ; '0'
|
||||
cmp #$30 // '0'
|
||||
bne wedge_dos_status_print
|
||||
lda BUF+1
|
||||
cmp #$30 ; '0'
|
||||
cmp #$30 // '0'
|
||||
bne wedge_dos_status_print
|
||||
|
||||
;; Clean-up and exit
|
||||
// Clean-up and exit
|
||||
jmp wedge_dos_clean_exit
|
||||
|
||||
wedge_dos_change_drive:
|
||||
|
||||
;; Reuse the line number parser for device number retrieval
|
||||
// Reuse the line number parser for device number retrieval
|
||||
jsr basic_parse_line_number
|
||||
lda basic_line_number+1
|
||||
beq +
|
||||
beq !+
|
||||
jmp do_ILLEGAL_QUANTITY_error
|
||||
*
|
||||
!:
|
||||
lda basic_line_number+0
|
||||
cmp #$08
|
||||
bpl +
|
||||
bcs +
|
||||
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
|
||||
// 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
|
||||
// Set remaining file parameters, open the channel
|
||||
lda #$00 // empty file name
|
||||
jsr JSETNAM
|
||||
jsr JOPEN
|
||||
bcc +
|
||||
jmp wedge_dos_basic_error ; XXX combine with other such jumps
|
||||
*
|
||||
bcc !+
|
||||
jmp wedge_dos_basic_error // XXX combine with other such jumps
|
||||
!:
|
||||
|
||||
;; Set channel for input
|
||||
// Set channel for input
|
||||
ldx #$0F
|
||||
jsr JCHKIN
|
||||
bcc +
|
||||
jmp wedge_dos_basic_error ; XXX combine with other such jumps
|
||||
*
|
||||
|
||||
bcc !+
|
||||
jmp wedge_dos_basic_error // XXX combine with other such jumps
|
||||
!:
|
||||
|
||||
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 +
|
||||
!:
|
||||
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 JCHRIN
|
||||
bcc wedge_dos_x1
|
||||
jmp wedge_dos_basic_error ; XXX try to optimize this
|
||||
jmp wedge_dos_basic_error // XXX try to optimize this
|
||||
wedge_dos_x1:
|
||||
sta BUF, y
|
||||
iny
|
||||
jmp -
|
||||
*
|
||||
jmp !-
|
||||
!:
|
||||
rts
|
||||
|
||||
wedge_dos_status:
|
||||
jsr wedge_dos_status_get
|
||||
;; FALLTROUGH
|
||||
// FALLTROUGH
|
||||
|
||||
wedge_dos_status_print:
|
||||
|
||||
;; Print buffered status
|
||||
// Print buffered status
|
||||
ldx #$00
|
||||
*
|
||||
!:
|
||||
dey
|
||||
bmi +
|
||||
bmi !+
|
||||
lda BUF, x
|
||||
jsr JCHROUT
|
||||
inx
|
||||
bne -
|
||||
*
|
||||
;; Clean-up and exit
|
||||
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
|
||||
lda #$00 ; logical device number
|
||||
// First change the secondary address to the one suitable for
|
||||
// directory loading
|
||||
lda #$00 // logical device number
|
||||
ldx current_device_number
|
||||
ldy #$60
|
||||
jsr JSETFLS
|
||||
|
||||
;; Provide file name
|
||||
// Provide file name
|
||||
jsr wedge_dos_setnam
|
||||
|
||||
;; Open the file
|
||||
// Open the file
|
||||
jsr JOPEN
|
||||
bcs wedge_dos_basic_error
|
||||
|
||||
;; Set channel for file reading
|
||||
// Set channel for file reading
|
||||
ldx #$00
|
||||
jsr JCHKIN
|
||||
bcs wedge_dos_basic_error
|
||||
|
||||
;; Ignore start address (2 first bytes) - XXX check for errors
|
||||
// Ignore start address (2 first bytes) - XXX check for errors
|
||||
jsr JCHRIN
|
||||
bcs wedge_dos_basic_error
|
||||
jsr JCHRIN
|
||||
@@ -163,37 +163,37 @@ wedge_dos_directory:
|
||||
|
||||
wedge_dos_directory_line:
|
||||
|
||||
;; Load a single line, reuse BASIC input buffer
|
||||
// Load a single line, reuse BASIC input buffer
|
||||
ldy #$FF
|
||||
*
|
||||
!:
|
||||
iny
|
||||
jsr JCHRIN
|
||||
bcs wedge_dos_basic_error
|
||||
sta BUF, y
|
||||
cpy #$50
|
||||
beq + ; line too long, terminate loading file
|
||||
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 -
|
||||
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
|
||||
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
|
||||
sta IOSTATUS // make sure end of file is marked
|
||||
// FALLTROUGH
|
||||
|
||||
wedge_dos_directory_display:
|
||||
|
||||
cpy #$05 ; protection against malformed directory
|
||||
cpy #$05 // protection against malformed directory
|
||||
bcc wedge_dos_clean_exit
|
||||
|
||||
lda #$00 ; extra protection agains buffer overflow
|
||||
lda #$00 // extra protection agains buffer overflow
|
||||
sta BUF, y
|
||||
|
||||
;; Display line
|
||||
// Display line
|
||||
ldx #<BUF
|
||||
stx basic_current_line_ptr+0
|
||||
ldx #>BUF
|
||||
@@ -201,14 +201,14 @@ wedge_dos_directory_display:
|
||||
ldx #basic_current_line_ptr
|
||||
jsr list_single_line
|
||||
|
||||
;; Read & display next line or quit
|
||||
// Read & display next line or quit
|
||||
lda IOSTATUS
|
||||
beq wedge_dos_directory_line
|
||||
;; FALLTROUGH
|
||||
// FALLTROUGH
|
||||
|
||||
wedge_dos_clean_exit:
|
||||
jsr JCLALL
|
||||
;; Print new line
|
||||
// Print new line
|
||||
lda #$0D
|
||||
jsr JCHROUT
|
||||
jmp basic_end_of_line
|
||||
@@ -222,17 +222,17 @@ wedge_dos_basic_error:
|
||||
jmp do_basic_error
|
||||
|
||||
wedge_dos_setnam:
|
||||
;; Now determine the length of the 'file' name
|
||||
// Now determine the length of the 'file' name
|
||||
ldy #$FF
|
||||
*
|
||||
!:
|
||||
iny
|
||||
lda (basic_current_statement_ptr), y
|
||||
bne -
|
||||
bne !-
|
||||
|
||||
;; Set the name to open
|
||||
// Set the name to open
|
||||
tya
|
||||
ldx basic_current_statement_ptr+0
|
||||
ldy basic_current_statement_ptr+1
|
||||
jmp JSETNAM
|
||||
|
||||
;; END wedge support
|
||||
// END wedge support
|
||||
+70
-68
@@ -1,73 +1,75 @@
|
||||
; Names of ZP and low memory locations
|
||||
; (Only those of relevance for the KERNAL)
|
||||
; (And only those for now that we feel the need to implement initially)
|
||||
; (https://www.c64-wiki.com/wiki/Zeropage)
|
||||
// Names of ZP and low memory locations
|
||||
// (Only those of relevance for the KERNAL)
|
||||
// (And only those for now that we feel the need to implement initially)
|
||||
// (https://www.c64-wiki.com/wiki/Zeropage)
|
||||
|
||||
.alias kernal_load_or_verify_flag $93
|
||||
.alias current_file_num $98
|
||||
.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_logical_filenum $B8
|
||||
.alias current_secondary_address $B9
|
||||
.alias current_device_number $BA
|
||||
.alias current_filename_ptr $BB
|
||||
.alias load_save_end_ptr $C3
|
||||
.alias last_key_matrix_position $C5
|
||||
.alias keys_in_key_buffer $C6
|
||||
.alias reverse_video_flag $C7
|
||||
.alias end_of_input_line $C8
|
||||
.alias start_of_keyboard_input $C9
|
||||
.alias current_key_index_entry $CB
|
||||
.alias cursor_blink_disable $CC
|
||||
.alias cursor_blink_countdown $CD
|
||||
.alias cursor_saved_character $CE
|
||||
.alias cursor_is_visible $CF
|
||||
.alias keyboard_input_ready $D0
|
||||
.alias current_screen_line_ptr $D1
|
||||
.alias current_screen_x $D3
|
||||
.alias quote_mode_flag $D4
|
||||
.alias logical_line_length $D5
|
||||
.alias current_screen_y $D6
|
||||
.alias last_printed_character_ascii $D7
|
||||
.alias insert_mode $D8
|
||||
; Bits 0 -3 = bits 8-11 of screen line address
|
||||
; Bit 7 = line spans multiple physical lines
|
||||
.alias screen_line_link_table $D9
|
||||
.alias current_screen_line_colour_ptr $F3
|
||||
.alias keyboard_decoding_table_ptr $F5
|
||||
.alias rs232_rx_buffer_ptr $F7
|
||||
.alias rs232_tx_buffer_ptr $F9
|
||||
// XXX get rid of this file, use ,aliases_ram_lowmem.s instead
|
||||
|
||||
.label kernal_load_or_verify_flag = $93
|
||||
.label current_file_num = $98
|
||||
.label input_device_number = DFLTN
|
||||
.label cassette_buffer_bytes_used = $A6
|
||||
.label load_or_scroll_temp_pointer = $AC
|
||||
// We also use the following for temp colour pointer when scrolling
|
||||
.label load_save_verify_end_address = $AE
|
||||
.label cassette_buffer_ptr = $B2
|
||||
.label current_logical_filenum = $B8
|
||||
.label current_secondary_address = $B9
|
||||
.label current_device_number = $BA
|
||||
.label current_filename_ptr = $BB
|
||||
.label load_save_end_ptr = $C3
|
||||
.label last_key_matrix_position = $C5
|
||||
.label keys_in_key_buffer = $C6
|
||||
.label reverse_video_flag = $C7
|
||||
.label end_of_input_line = $C8
|
||||
.label start_of_keyboard_input = $C9
|
||||
.label current_key_index_entry = $CB
|
||||
.label cursor_blink_disable = $CC
|
||||
.label cursor_blink_countdown = $CD
|
||||
.label cursor_saved_character = $CE
|
||||
.label cursor_is_visible = $CF
|
||||
.label keyboard_input_ready = $D0
|
||||
.label current_screen_line_ptr = $D1
|
||||
.label current_screen_x = $D3
|
||||
.label quote_mode_flag = $D4
|
||||
.label logical_line_length = $D5
|
||||
.label current_screen_y = $D6
|
||||
.label last_printed_character_ascii = $D7
|
||||
.label insert_mode = $D8
|
||||
// Bits 0 -3 = bits 8-11 of screen line address
|
||||
// Bit 7 = line spans multiple physical lines
|
||||
.label screen_line_link_table = $D9
|
||||
.label current_screen_line_colour_ptr = $F3
|
||||
.label keyboard_decoding_table_ptr = $F5
|
||||
.label rs232_rx_buffer_ptr = $F7
|
||||
.label rs232_tx_buffer_ptr = $F9
|
||||
|
||||
; "Compute's Mapping the 64" book
|
||||
.alias keyboard_buffer $0277
|
||||
.alias text_colour $0286 ; p55
|
||||
.alias colour_under_cursor $0287 ; p56
|
||||
.alias key_buffer_size $0289 ; p57
|
||||
// "Compute's Mapping the 64" book
|
||||
.label keyboard_buffer = $0277
|
||||
.label text_colour = $0286 // p55
|
||||
.label colour_under_cursor = $0287 // p56
|
||||
.label key_buffer_size = $0289 // p57
|
||||
|
||||
;; 0 = cursor keys, insert, delete and space repeat, but nothing else
|
||||
;; 128 = all keys repeat
|
||||
;; 64 = no keys repeat
|
||||
.alias key_repeat_flags $028A ; p58
|
||||
;; https://www.c64-wiki.com/wiki/Page_2
|
||||
.alias key_repeat_counter $028B
|
||||
.alias key_first_repeat_delay $028C
|
||||
;; bit 0 = shift, 1 = Vendor Key, 2 = Control
|
||||
.alias key_bucky_state $028D
|
||||
.alias key_last_bucky_state $028E
|
||||
.alias keyboard_decoding_ptr $028F
|
||||
.alias enable_case_switch $0291
|
||||
.alias screen_scroll_disable $0292
|
||||
// 0 = cursor keys, insert, delete and space repeat, but nothing else
|
||||
// 128 = all keys repeat
|
||||
// 64 = no keys repeat
|
||||
.label key_repeat_flags = $028A // p58
|
||||
// https://www.c64-wiki.com/wiki/Page_2
|
||||
.label key_repeat_counter = $028B
|
||||
.label key_first_repeat_delay = $028C
|
||||
// bit 0 = shift, 1 = Vendor Key, 2 = Control
|
||||
.label key_bucky_state = $028D
|
||||
.label key_last_bucky_state = $028E
|
||||
.label keyboard_decoding_ptr = $028F
|
||||
.label enable_case_switch = $0291
|
||||
.label screen_scroll_disable = $0292
|
||||
|
||||
;; Under-ROM routines
|
||||
;; (BASIC also includes them. XXX - We should de-duplicate them in a safe manner)
|
||||
.alias missed_nmi_flag $2A7
|
||||
.alias tiny_nmi_handler $2A8
|
||||
.alias peek_under_roms tiny_nmi_handler+peek_under_roms_routine-tiny_nmi_handler_routine
|
||||
.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
|
||||
// Under-ROM routines
|
||||
// (BASIC also includes them. XXX - We should de-duplicate them in a safe manner)
|
||||
.label missed_nmi_flag = $2A7
|
||||
.label tiny_nmi_handler = $2A8
|
||||
.label peek_under_roms = tiny_nmi_handler+peek_under_roms_routine-tiny_nmi_handler_routine
|
||||
.label poke_under_roms = tiny_nmi_handler+poke_under_roms_routine-tiny_nmi_handler_routine
|
||||
.label memmap_allram = tiny_nmi_handler+memmap_allram_routine-tiny_nmi_handler_routine
|
||||
.label memmap_normal = tiny_nmi_handler+memmap_normal_routine-tiny_nmi_handler_routine
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
;; Target-specific hooks
|
||||
// Target-specific hooks
|
||||
|
||||
|
||||
.macro TARGET_HOOK_LOAD
|
||||
.macend
|
||||
.macro TARGET_HOOK_LOAD() {
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
;; Target-specific hooks
|
||||
// Target-specific hooks
|
||||
|
||||
|
||||
.macro TARGET_HOOK_LOAD
|
||||
.macend
|
||||
.macro TARGET_HOOK_LOAD() {
|
||||
}
|
||||
@@ -1,57 +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
|
||||
// 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
|
||||
// Command interface registers
|
||||
.label U64_CONTROL = $DF1C // write
|
||||
.label U64_STATUS = $DF1C // read
|
||||
.label U64_COMMAND_DATA = $DF1D // write
|
||||
.label U64_IDENTIFICATION = $DF1D // read
|
||||
.label U64_RESPONSE_DATA = $DF1E // read only
|
||||
.label U64_STATUS_DATA = $DF1F // read only
|
||||
|
||||
;; Constant for U64_IDENTIFICATION register
|
||||
.alias U64_MAGIC_ID $C9
|
||||
// Constant for U64_IDENTIFICATION register
|
||||
.const 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_CONTROL register
|
||||
.const U64_CTRL_BIT_PUSH_CMD = $01
|
||||
.const U64_CTRL_BIT_DATA_ACC = $02
|
||||
.const U64_CTRL_BIT_ABORT = $04
|
||||
.const 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
|
||||
// Constants for U64_STATUS register
|
||||
.const U64_STAT_BIT_CMD_BUSY = $01
|
||||
.const U64_STAT_BIT_DATA_ACC = $02
|
||||
.const U64_STAT_BIT_ABORT_P = $04
|
||||
.const U64_STAT_BIT_ERROR = $08
|
||||
.const U64_STAT_MASK_STATE = $30 // two bits!
|
||||
.const U64_STAT_BIT_STAT_AV = $40
|
||||
.const U64_STAT_BIT_DATA_AV = $80
|
||||
|
||||
;; Interface targets
|
||||
.alias U64_TARGET_DOS1 $01
|
||||
.alias U64_TARGET_DOS2 $02
|
||||
// Interface targets
|
||||
.const U64_TARGET_DOS1 = $01
|
||||
.const 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 command codes
|
||||
.const U64_DOS_CMD_IDENTIFY = $01
|
||||
.const U64_DOS_CMD_OPEN_FILE = $02
|
||||
.const U64_DOS_CMD_CLOSE_FILE = $03
|
||||
.const U64_DOS_CMD_READ_DATA = $04
|
||||
.const U64_DOS_CMD_WRITE_DATA = $05
|
||||
.const U64_DOS_CMD_FILE_SEEK = $06
|
||||
.const U64_DOS_CMD_FILE_INFO = $07
|
||||
.const U64_DOS_CMD_CHANGE_DIR = $11
|
||||
.const U64_DOS_CMD_GET_PATH = $12
|
||||
.const U64_DOS_CMD_OPEN_DIR = $13
|
||||
.const U64_DOS_CMD_READ_DIR = $14
|
||||
.const U64_DOS_CMD_COPY_UI_PATH = $15
|
||||
.const U64_DOS_CMD_LOAD_REU = $21
|
||||
.const U64_DOS_CMD_SAVE_REU = $22
|
||||
.const 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
|
||||
// DOS file opening constants
|
||||
.const U64_FA_READ = $01
|
||||
.const U64_FA_WRITE = $02
|
||||
.const U64_FA_CREATE_NEW = $03
|
||||
.const U64_FA_CREATE_ALWAYS = $04
|
||||
@@ -1,9 +1,9 @@
|
||||
|
||||
;; Target-specific hooks
|
||||
// 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
|
||||
.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
|
||||
}
|
||||
@@ -1,52 +1,53 @@
|
||||
|
||||
;;
|
||||
;; LOAD routine hook for fast loading via UltiDOS
|
||||
;;
|
||||
//
|
||||
// LOAD routine hook for fast loading via UltiDOS
|
||||
//
|
||||
|
||||
|
||||
u64_load:
|
||||
|
||||
;; First check whether the command interface is enabled
|
||||
// First check whether the command interface is enabled
|
||||
lda U64_IDENTIFICATION
|
||||
cmp #U64_MAGIC_ID
|
||||
beq +
|
||||
beq !+
|
||||
|
||||
u64_load_skip:
|
||||
rts
|
||||
*
|
||||
;; XXX find out which device number softIEC is mapped to
|
||||
!:
|
||||
// XXX find out which device number softIEC is mapped to
|
||||
lda current_device_number
|
||||
cmp #$20 ; for now use device number 32
|
||||
cmp #$20 // for now use device number 32
|
||||
bne u64_load_skip
|
||||
|
||||
;; Takeover the flow completely
|
||||
|
||||
// Takeover the flow completely
|
||||
pla
|
||||
pla
|
||||
|
||||
;; Display SEARCHING FOR + filename
|
||||
// Display SEARCHING FOR + filename
|
||||
jsr lvs_display_searching_for
|
||||
|
||||
;; Whatever the interface was doing - ask to abort it
|
||||
// Whatever the interface was doing - ask to abort it
|
||||
jsr u64_load_abort
|
||||
|
||||
;; Send a command to open the file
|
||||
|
||||
// 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
|
||||
|
||||
// Check status
|
||||
jsr u64_load_check_status
|
||||
bcs lvs_file_not_found_error
|
||||
|
||||
;; Load first two bytes to determine start address
|
||||
// Load first two bytes to determine start address
|
||||
|
||||
// XXX
|
||||
|
||||
;; XXX
|
||||
|
||||
jsr printf
|
||||
.byte "DBG: NOT IMPLEMENTED",$0D,0
|
||||
.text "DBG: NOT IMPLEMENTED"
|
||||
.byte $0D,0
|
||||
|
||||
jmp lvs_wrap_around_error
|
||||
rts
|
||||
@@ -54,77 +55,77 @@ u64_load_skip:
|
||||
u64_load_abort:
|
||||
lda #U64_CTRL_BIT_ABORT
|
||||
sta U64_CONTROL
|
||||
*
|
||||
!:
|
||||
lda U64_STATUS
|
||||
bne -
|
||||
bne !-
|
||||
rts
|
||||
|
||||
u64_load_send_cmd:
|
||||
|
||||
ldx #U64_TARGET_DOS2
|
||||
stx U64_COMMAND_DATA ; target
|
||||
sta U64_COMMAND_DATA ; command code
|
||||
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+
|
||||
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
|
||||
// Push the command for execution
|
||||
lda #U64_CTRL_BIT_PUSH_CMD
|
||||
sta U64_CONTROL
|
||||
;; Wait till it is complete
|
||||
*
|
||||
// Wait till it is complete
|
||||
!:
|
||||
lda U64_STATUS
|
||||
and #U64_STAT_BIT_CMD_BUSY
|
||||
bne -
|
||||
bne !-
|
||||
rts
|
||||
|
||||
u64_load_check_status:
|
||||
;; Wait till status is available
|
||||
// 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
|
||||
// Status is ready - check the first character
|
||||
lda U64_STATUS_DATA
|
||||
jsr JCHROUT ; XXX for test only
|
||||
cmp #$30 ; '0'
|
||||
jsr JCHROUT // XXX for test only
|
||||
cmp #$30 // '0'
|
||||
bne u64_load_check_status_wrong
|
||||
|
||||
;; Check the second status character
|
||||
// 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'
|
||||
jsr JCHROUT // XXX for test only
|
||||
cmp #$30 // '0'
|
||||
beq u64_load_check_status_ok
|
||||
|
||||
;; FALLTROUGH
|
||||
// FALLTROUGH
|
||||
u64_load_check_status_wrong:
|
||||
sec
|
||||
bcs +
|
||||
bcs !+
|
||||
u64_load_check_status_ok:
|
||||
clc
|
||||
*
|
||||
;; Now empty the status queue
|
||||
!:
|
||||
// Now empty the status queue
|
||||
lda U64_STATUS
|
||||
and #U64_STAT_BIT_STAT_AV
|
||||
beq +
|
||||
beq !+
|
||||
lda U64_STATUS_DATA
|
||||
jsr JCHROUT ; XXX for test only
|
||||
jmp -
|
||||
*
|
||||
jsr JCHROUT // XXX for test only
|
||||
jmp !-
|
||||
!:
|
||||
rts
|
||||
+9
-10
@@ -1,15 +1,14 @@
|
||||
|
||||
;;
|
||||
;; 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
|
||||
;;
|
||||
//
|
||||
// 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:
|
||||
ACPTR:
|
||||
jsr kernalstatus_reset
|
||||
jmp iec_rx_byte
|
||||
|
||||
+20
-20
@@ -1,41 +1,41 @@
|
||||
;; We have the following variables:
|
||||
;; cursor_blink_disable
|
||||
;; cursor_blink_countdown
|
||||
;; cursor_saved_character
|
||||
;; cursor_is_visible
|
||||
;; colour_under_cursor
|
||||
// We have the following variables:
|
||||
// cursor_blink_disable
|
||||
// cursor_blink_countdown
|
||||
// cursor_saved_character
|
||||
// cursor_is_visible
|
||||
// colour_under_cursor
|
||||
|
||||
show_cursor_if_enabled:
|
||||
lda cursor_blink_disable
|
||||
beq +
|
||||
beq !+
|
||||
rts
|
||||
* lda cursor_is_visible
|
||||
!: lda cursor_is_visible
|
||||
beq show_cursor
|
||||
rts
|
||||
|
||||
show_cursor:
|
||||
;; Set cursor as though it had just finished the off phase,
|
||||
;; so that the call to blink_cursor paints it
|
||||
// Set cursor as though it had just finished the off phase,
|
||||
// so that the call to blink_cursor paints it
|
||||
lda #$00
|
||||
sta cursor_blink_countdown
|
||||
sta cursor_is_visible
|
||||
jsr blink_cursor
|
||||
;; Then set the timeout to 1 frame, so that the cursor
|
||||
;; blinks under key repeat conditions, like on the original KERNAL
|
||||
// Then set the timeout to 1 frame, so that the cursor
|
||||
// blinks under key repeat conditions, like on the original KERNAL
|
||||
lda #$01
|
||||
sta cursor_blink_countdown
|
||||
rts
|
||||
|
||||
blink_cursor:
|
||||
;; Is the cursor enabled?
|
||||
// Is the cursor enabled?
|
||||
lda cursor_blink_disable
|
||||
bne no_blink_cursor
|
||||
|
||||
;; Do we need to redraw things?
|
||||
// Do we need to redraw things?
|
||||
dec cursor_blink_countdown
|
||||
bpl no_blink_cursor
|
||||
|
||||
;; Check if cursor was visible or not, and toggle
|
||||
// Check if cursor was visible or not, and toggle
|
||||
lda cursor_is_visible
|
||||
bne undraw_cursor
|
||||
draw_cursor:
|
||||
@@ -46,7 +46,7 @@ draw_cursor:
|
||||
sta cursor_saved_character
|
||||
eor #$80
|
||||
sta (current_screen_line_ptr),y
|
||||
;; Also set cursor colour
|
||||
// Also set cursor colour
|
||||
lda (current_screen_line_colour_ptr),y
|
||||
sta colour_under_cursor
|
||||
lda text_colour
|
||||
@@ -68,10 +68,10 @@ undraw_cursor:
|
||||
|
||||
lda #0
|
||||
sta cursor_is_visible
|
||||
;; Fall through
|
||||
// Fall through
|
||||
reset_blink_timer:
|
||||
;; Rest blink counter
|
||||
;; (Compute's Mapping the 64, p39-40)
|
||||
// Rest blink counter
|
||||
// (Compute's Mapping the 64, p39-40)
|
||||
lda #20
|
||||
sta cursor_blink_countdown
|
||||
no_blink_cursor:
|
||||
@@ -80,7 +80,7 @@ no_blink_cursor:
|
||||
disable_cursor:
|
||||
lda #$80
|
||||
sta cursor_blink_disable
|
||||
;; FALL THROUGH
|
||||
// FALL THROUGH
|
||||
hide_cursor_if_visible:
|
||||
lda cursor_is_visible
|
||||
bne undraw_cursor
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
; c64 prg p263
|
||||
// c64 prg p263
|
||||
|
||||
cartridge_check:
|
||||
ldx #$04
|
||||
|
||||
+37
-37
@@ -1,64 +1,64 @@
|
||||
|
||||
;;
|
||||
;; 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
|
||||
;;
|
||||
//
|
||||
// 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 implementation
|
||||
|
||||
chkin_real:
|
||||
|
||||
;; Store Y for preservation
|
||||
// Store Y for preservation
|
||||
tya
|
||||
pha
|
||||
|
||||
;; Reset status
|
||||
// Reset status
|
||||
jsr kernalstatus_reset
|
||||
|
||||
;; First retrieve the FAT/LAT/SAT table index (and check if file is open)
|
||||
// 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
|
||||
// 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
|
||||
beq chkinout_device_not_present // tape not implemented
|
||||
cmp #$02
|
||||
beq chkinout_device_not_present ; RS-232 not implemented
|
||||
beq chkinout_device_not_present // RS-232 not implemented
|
||||
|
||||
;; Fail if the file is open for writing (secondary address 1)
|
||||
// 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
|
||||
// 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
|
||||
jsr TALK
|
||||
bcs chkinout_device_not_present // don't set DFLTN in case of failure
|
||||
|
||||
lda LAT, Y
|
||||
jsr tksa
|
||||
jsr TKSA
|
||||
bcs chkinout_device_not_present
|
||||
|
||||
chkin_set_device:
|
||||
lda FAT,Y
|
||||
sta DFLTN
|
||||
clc ; for success
|
||||
;; FALLTROUGH
|
||||
clc // for success
|
||||
// FALLTROUGH
|
||||
|
||||
;; Common part for booth CHKIN and CKOUT
|
||||
// Common part for booth CHKIN and CKOUT
|
||||
|
||||
chkinout_end:
|
||||
tax
|
||||
@@ -88,54 +88,54 @@ chkinout_file_not_output:
|
||||
tay
|
||||
jmp kernalerror_FILE_NOT_OUTPUT
|
||||
|
||||
;; CKOUT implementation
|
||||
// CKOUT implementation
|
||||
|
||||
ckout_real:
|
||||
|
||||
;; Store Y for preservation
|
||||
// Store Y for preservation
|
||||
tya
|
||||
pha
|
||||
|
||||
;; Reset status
|
||||
// Reset status
|
||||
jsr kernalstatus_reset
|
||||
|
||||
;; First retrieve the FAT/LAT/SAT table index (and check if file is open)
|
||||
// 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
|
||||
// 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
|
||||
beq chkinout_device_not_present // tape not implemented
|
||||
cmp #$02
|
||||
beq chkinout_device_not_present ; RS-232 not implemented
|
||||
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
|
||||
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)
|
||||
// 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
|
||||
// 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
|
||||
jsr LISTEN
|
||||
bcs chkinout_device_not_present // don't set DFLTO in case of failure
|
||||
|
||||
lda LAT, Y
|
||||
jsr second
|
||||
jsr SECOND
|
||||
bcs chkinout_device_not_present
|
||||
|
||||
chkout_set_device:
|
||||
lda FAT,Y
|
||||
sta DFLTO
|
||||
clc ; for success
|
||||
clc // for success
|
||||
|
||||
jmp chkinout_end
|
||||
+60
-60
@@ -1,67 +1,67 @@
|
||||
|
||||
;;
|
||||
;; 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
|
||||
;;
|
||||
//
|
||||
// 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!
|
||||
// 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.
|
||||
// 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_real:
|
||||
|
||||
;; Determine the device number
|
||||
// Determine the device number
|
||||
lda DFLTN
|
||||
|
||||
beq chrin_keyboard ; #$00 - keyboard
|
||||
;; XXX add screen support
|
||||
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
|
||||
jmp lvs_device_not_found_error // not a supported device
|
||||
|
||||
chrin_iec:
|
||||
|
||||
jsr JACPTR
|
||||
bcs chrin_done_fail
|
||||
;; FALLTROUGH
|
||||
// FALLTROUGH
|
||||
|
||||
chrin_done:
|
||||
clc ; indicate success
|
||||
clc // indicate success
|
||||
rts
|
||||
|
||||
chrin_done_fail:
|
||||
sec ; indicate failure
|
||||
sec // indicate failure
|
||||
rts
|
||||
|
||||
chrin_keyboard:
|
||||
|
||||
;; Save X
|
||||
// Save X
|
||||
txa
|
||||
pha
|
||||
|
||||
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.
|
||||
// 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.
|
||||
|
||||
;; Do we have a line of input waiting?
|
||||
// Do we have a line of input waiting?
|
||||
lda keyboard_input_ready
|
||||
beq read_from_keyboard
|
||||
|
||||
;; Yes, we have input waiting at (start_of_keyboard_input)+keyboard_input_ready
|
||||
;; When keyboard_input_ready = end_of_input_line, then we return a carriage return
|
||||
;; and clear the flag
|
||||
// Yes, we have input waiting at (start_of_keyboard_input)+keyboard_input_ready
|
||||
// When keyboard_input_ready = end_of_input_line, then we return a carriage return
|
||||
// and clear the flag
|
||||
cmp end_of_input_line
|
||||
bne not_end_of_input
|
||||
|
||||
;; Return carriage return and clear pending input flag
|
||||
// Return carriage return and clear pending input flag
|
||||
lda #$00
|
||||
sta keyboard_input_ready
|
||||
pla
|
||||
@@ -71,7 +71,7 @@ chrin_repeat:
|
||||
rts
|
||||
|
||||
not_end_of_input:
|
||||
;; Return next byte of waiting input and advance index
|
||||
// Return next byte of waiting input and advance index
|
||||
tay
|
||||
pla
|
||||
tax
|
||||
@@ -80,13 +80,13 @@ not_end_of_input:
|
||||
inc keyboard_input_ready
|
||||
clc
|
||||
rts
|
||||
|
||||
|
||||
read_from_keyboard:
|
||||
|
||||
read_from_keyboard:
|
||||
|
||||
jsr enable_cursor
|
||||
|
||||
;; Wait for a key
|
||||
// Wait for a key
|
||||
lda keys_in_key_buffer
|
||||
beq chrin_repeat
|
||||
|
||||
@@ -100,31 +100,31 @@ read_from_keyboard:
|
||||
|
||||
jsr hide_cursor_if_visible
|
||||
|
||||
;; It was enter.
|
||||
;; Note that we have a line of input to return, and return the first byte thereof
|
||||
;; after computing and storing its length.
|
||||
;; (Compute's Mapping the 64, p96)
|
||||
// It was enter.
|
||||
// Note that we have a line of input to return, and return the first byte thereof
|
||||
// after computing and storing its length.
|
||||
// (Compute's Mapping the 64, p96)
|
||||
|
||||
;; Set pointer to line of input
|
||||
// Set pointer to line of input
|
||||
lda current_screen_line_ptr+0
|
||||
sta start_of_keyboard_input+0
|
||||
lda current_screen_line_ptr+1
|
||||
sta start_of_keyboard_input+1
|
||||
|
||||
;; Calculate length
|
||||
// Calculate length
|
||||
jsr get_current_line_logical_length
|
||||
tay
|
||||
iny
|
||||
* dey
|
||||
!: dey
|
||||
bmi empty_line
|
||||
lda (current_screen_line_ptr),y
|
||||
cmp #$20
|
||||
beq -
|
||||
beq !-
|
||||
iny
|
||||
sty end_of_input_line
|
||||
lda #$01
|
||||
sta keyboard_input_ready
|
||||
;; Return first char of line
|
||||
// Return first char of line
|
||||
ldy #$00
|
||||
pla
|
||||
tax
|
||||
@@ -134,43 +134,43 @@ read_from_keyboard:
|
||||
rts
|
||||
|
||||
empty_line:
|
||||
;; For an empty line, just return the carriage return
|
||||
;; (and don't forget to actually print the carriage return, so that
|
||||
;; the cursor advances and screen scrolls as required)
|
||||
// For an empty line, just return the carriage return
|
||||
// (and don't forget to actually print the carriage return, so that
|
||||
// the cursor advances and screen scrolls as required)
|
||||
pla
|
||||
tax
|
||||
clc
|
||||
lda #$0d
|
||||
rts
|
||||
|
||||
not_enter:
|
||||
;; Print character
|
||||
|
||||
not_enter:
|
||||
// Print character
|
||||
lda keyboard_buffer
|
||||
jsr chrout
|
||||
jsr CHROUT
|
||||
|
||||
jsr pop_keyboard_buffer
|
||||
|
||||
;; Keep looking for input from keyboard until carriage return
|
||||
// Keep looking for input from keyboard until carriage return
|
||||
jmp chrin_repeat
|
||||
|
||||
pop_keyboard_buffer:
|
||||
;; Pop key out of keyboard buffer
|
||||
;; Disable interrupts while reading from keyboard buffer
|
||||
;; so that no race conditions can occur
|
||||
pop_keyboard_buffer:
|
||||
// Pop key out of keyboard buffer
|
||||
// Disable interrupts while reading from keyboard buffer
|
||||
// so that no race conditions can occur
|
||||
sei
|
||||
ldx #$00
|
||||
ldy #$01
|
||||
* lda keyboard_buffer,y
|
||||
!: lda keyboard_buffer,y
|
||||
sta keyboard_buffer,x
|
||||
inx
|
||||
iny
|
||||
cpy key_buffer_size
|
||||
bne -
|
||||
bne !-
|
||||
dec keys_in_key_buffer
|
||||
cli
|
||||
|
||||
rts
|
||||
|
||||
|
||||
screen_code_to_petscii:
|
||||
cmp #$1b
|
||||
bcs not_alpha
|
||||
@@ -185,7 +185,7 @@ not_alpha:
|
||||
|
||||
rts
|
||||
|
||||
not_punctuation:
|
||||
not_punctuation:
|
||||
cmp #$5b
|
||||
bcs not_shifted
|
||||
|
||||
@@ -193,18 +193,18 @@ not_punctuation:
|
||||
adc #$80
|
||||
|
||||
rts
|
||||
|
||||
not_shifted:
|
||||
|
||||
not_shifted:
|
||||
|
||||
cmp #$80
|
||||
bcs not_vendor
|
||||
|
||||
;; $60-$7F -> $A0-$BF
|
||||
// $60-$7F -> $A0-$BF
|
||||
|
||||
clc
|
||||
adc #$40
|
||||
|
||||
;; FALLTROUGH
|
||||
// FALLTROUGH
|
||||
not_vendor:
|
||||
rts
|
||||
|
||||
+253
-253
File diff suppressed because it is too large.
Load diff
+40
-40
@@ -1,24 +1,24 @@
|
||||
|
||||
;;
|
||||
;; 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
|
||||
;;
|
||||
//
|
||||
// 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_real:
|
||||
|
||||
;; According to [CM64], this routine checks for PAL/NTSC. It's definitely not done
|
||||
;; within the 'BRK' part, this can be easily checked - POKE something
|
||||
;; to address 678 on a real C64, press STOP+RESTORE, the value won't change
|
||||
// According to [CM64], this routine checks for PAL/NTSC. It's definitely not done
|
||||
// within the 'BRK' part, this can be easily checked - POKE something
|
||||
// to address 678 on a real C64, press STOP+RESTORE, the value won't change
|
||||
|
||||
;; Detect video system (PAL/NTSC), use Graham's method, as it's short and reliable
|
||||
;; see here: https://codebase64.org/doku.php?id=base:detect_pal_ntsc
|
||||
// Detect video system (PAL/NTSC), use Graham's method, as it's short and reliable
|
||||
// see here: https://codebase64.org/doku.php?id=base:detect_pal_ntsc
|
||||
|
||||
lda #$C8 ; preparation, as the VIC might be uninitialized
|
||||
lda #$C8 // preparation, as the VIC might be uninitialized
|
||||
sta VIC_SCROLX
|
||||
|
||||
cint_w0:
|
||||
@@ -28,18 +28,18 @@ cint_w1:
|
||||
beq cint_w1
|
||||
bmi cint_w0
|
||||
|
||||
;; Result in A, if no interrupt happened during the test:
|
||||
;; #$37 -> 312 rasterlines, PAL, VIC 6569
|
||||
;; #$06 -> 263 rasterlines, NTSC, VIC 6567R8
|
||||
;; #$05 -> 262 rasterlines, NTSC, VIC 6567R56A
|
||||
// Result in A, if no interrupt happened during the test:
|
||||
// #$37 -> 312 rasterlines, PAL, VIC 6569
|
||||
// #$06 -> 263 rasterlines, NTSC, VIC 6567R8
|
||||
// #$05 -> 262 rasterlines, NTSC, VIC 6567R56A
|
||||
|
||||
cmp #$07
|
||||
bcs cint_pal
|
||||
|
||||
cint_ntsc:
|
||||
|
||||
;; NTSC C64 (https://codebase64.org/doku.php?id=base:cpu_clocking),
|
||||
;; is clocked at 1.022727 MHz, so that 1/60s is 17045 CPU cycles
|
||||
// NTSC C64 (https://codebase64.org/doku.php?id=base:cpu_clocking),
|
||||
// is clocked at 1.022727 MHz, so that 1/60s is 17045 CPU cycles
|
||||
|
||||
ldy #<17045
|
||||
ldx #>17045
|
||||
@@ -48,51 +48,51 @@ cint_ntsc:
|
||||
stx CIA1_TIMAHI
|
||||
|
||||
lda #$00
|
||||
beq +
|
||||
beq !+
|
||||
|
||||
cint_pal:
|
||||
|
||||
lda #$01
|
||||
*
|
||||
!:
|
||||
sta PALNTSC
|
||||
|
||||
cint_brk: ; entry for BRK and STOP+RESTORE - XXX, where should it start?
|
||||
cint_brk: // entry for BRK and STOP+RESTORE - XXX, where should it start?
|
||||
|
||||
jsr setup_vicii
|
||||
|
||||
;; Initialise cursor blink flags (Compute's Mapping the 64 p215)
|
||||
// Initialise cursor blink flags (Compute's Mapping the 64 p215)
|
||||
lda #$00
|
||||
sta cursor_blink_disable
|
||||
|
||||
;; Set keyboard decode vector (Compute's Mapping the 64 p215)
|
||||
// Set keyboard decode vector (Compute's Mapping the 64 p215)
|
||||
|
||||
;; Set initial variables for our improved keyboard scan routine
|
||||
lda #$ff
|
||||
// Set initial variables for our improved keyboard scan routine
|
||||
lda #$FF
|
||||
ldx #6
|
||||
* sta BufferOld,x
|
||||
!: sta BufferOld,x
|
||||
dex
|
||||
bpl -
|
||||
bpl !-
|
||||
sta BufferQuantity
|
||||
|
||||
;; Set key repeat delay (Compute's Mapping the 64 p215)
|
||||
;; Making some numbers up here: Repeat every ~1/10th sec
|
||||
;; But require key to be held for ~1/3sec before
|
||||
;; repeating (Compute's Mapping the 64 p58)
|
||||
ldx #22-2 ; Fudge factor to match speed
|
||||
// Set key repeat delay (Compute's Mapping the 64 p215)
|
||||
// Making some numbers up here: Repeat every ~1/10th sec
|
||||
// But require key to be held for ~1/3sec before
|
||||
// repeating (Compute's Mapping the 64 p58)
|
||||
ldx #22-2 // Fudge factor to match speed
|
||||
stx key_first_repeat_delay
|
||||
|
||||
;; Set current colour for text (Compute's Mapping the 64 p215)
|
||||
ldx #$01 ; default is light blue ($0E), but we use a different one
|
||||
// Set current colour for text (Compute's Mapping the 64 p215)
|
||||
ldx #$01 // default is light blue ($0E), but we use a different one
|
||||
stx text_colour
|
||||
|
||||
;; Set maximum keyboard buffer size (Compute's Mapping the 64 p215)
|
||||
// Set maximum keyboard buffer size (Compute's Mapping the 64 p215)
|
||||
ldx #10
|
||||
stx key_buffer_size
|
||||
;; Put non-zero value in enable_case_switch
|
||||
// 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)
|
||||
// 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)
|
||||
// Fallthrough/jump to screen clear routine (Compute's Mapping the 64 p215)
|
||||
jmp clear_screen
|
||||
+14
-14
@@ -1,37 +1,37 @@
|
||||
|
||||
;;
|
||||
;; 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
|
||||
;;
|
||||
//
|
||||
// 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:
|
||||
CIOUT:
|
||||
|
||||
pha
|
||||
lda C3PO
|
||||
bne ciout_send_byte
|
||||
|
||||
;; Nothing to send - set buffer as valid, store byte there
|
||||
// Nothing to send - set buffer as valid, store byte there
|
||||
inc C3PO
|
||||
|
||||
;; Clear carry flag to indicate success
|
||||
// Clear carry flag to indicate success
|
||||
clc
|
||||
|
||||
ciout_store_in_buffer:
|
||||
|
||||
;; Store in the buffer data to be sent next, return
|
||||
// Store in the buffer data to be sent next, return
|
||||
pla
|
||||
sta BSOUR
|
||||
rts
|
||||
|
||||
ciout_send_byte:
|
||||
|
||||
clc ; don't send with EOI
|
||||
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
|
||||
inc C3PO // iec_tx_byte sets it to 0, but we still have something to send
|
||||
jmp ciout_store_in_buffer
|
||||
|
||||
+20
-20
@@ -1,38 +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
|
||||
;;
|
||||
//
|
||||
// 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_real:
|
||||
|
||||
;; Store .Y register
|
||||
// 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
|
||||
*
|
||||
// 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 +
|
||||
beq !+
|
||||
dey
|
||||
lda LAT, y
|
||||
jsr JCLOSE
|
||||
jmp -
|
||||
*
|
||||
;; Restore .Y register
|
||||
jmp !-
|
||||
!:
|
||||
// Restore .Y register
|
||||
pla
|
||||
tay
|
||||
|
||||
;; 'C64 Programmers Reference Guide', page 281, claims it calls CLRCHN too
|
||||
jsr clrchn
|
||||
// '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
|
||||
// Not sure whether original Kernal does so, but it seems sane to also clear possible errors
|
||||
jmp kernalstatus_reset
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
|
||||
|
||||
;; Common ppart of CLOSE and LOAD routines
|
||||
// Common ppart of CLOSE and LOAD routines
|
||||
|
||||
close_load:
|
||||
|
||||
tax
|
||||
|
||||
;; Command drive to stop talking and to close the file
|
||||
jsr untlk
|
||||
// Command drive to stop talking and to close the file
|
||||
jsr UNTLK
|
||||
|
||||
txa
|
||||
jsr listen
|
||||
jsr LISTEN
|
||||
|
||||
lda #$E0 ; CLOSE command
|
||||
lda #$E0 // CLOSE command
|
||||
sta IEC_TMP2
|
||||
jsr iec_tx_command
|
||||
jsr iec_tx_command_finalize
|
||||
|
||||
;; Tell drive to unlisten
|
||||
jsr unlsn
|
||||
// Tell drive to unlisten
|
||||
jsr UNLSN
|
||||
|
||||
rts
|
||||
+21
-21
@@ -1,35 +1,35 @@
|
||||
|
||||
;;
|
||||
;; 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
|
||||
;;
|
||||
//
|
||||
// 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_real:
|
||||
|
||||
;; Handle IEC input device
|
||||
// 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
|
||||
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
|
||||
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
|
||||
// Set output device number to screen
|
||||
lda #$03
|
||||
sta DFLTO
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
;; Clear screen and initialise line link table
|
||||
;; (Compute's Mapping the 64 p215-216)
|
||||
// Clear screen and initialise line link table
|
||||
// (Compute's Mapping the 64 p215-216)
|
||||
|
||||
clear_screen:
|
||||
|
||||
;; Clear line link table
|
||||
;; (Compute's Mapping the 64 p215)
|
||||
// Clear line link table
|
||||
// (Compute's Mapping the 64 p215)
|
||||
|
||||
lda #$00
|
||||
ldy #24
|
||||
@@ -13,27 +13,27 @@ clearscreen_l1:
|
||||
dey
|
||||
bpl clearscreen_l1
|
||||
|
||||
;; Y now = #$FF
|
||||
// Y now = #$FF
|
||||
|
||||
;; Clear screen RAM.
|
||||
;; We should do this at HIBASE, which annoyingly
|
||||
;; is no ZP, so we need to make a vector
|
||||
;; (Compute's Mapping the 64 p216)
|
||||
;; Get pointer to the screen into current_screen_line_ptr
|
||||
;; as it is the first appropriate place for it found when
|
||||
;; searching through the ZP allocations listed in
|
||||
;; Compute's Mapping the 64
|
||||
// Clear screen RAM.
|
||||
// We should do this at HIBASE, which annoyingly
|
||||
// is no ZP, so we need to make a vector
|
||||
// (Compute's Mapping the 64 p216)
|
||||
// Get pointer to the screen into current_screen_line_ptr
|
||||
// as it is the first appropriate place for it found when
|
||||
// searching through the ZP allocations listed in
|
||||
// Compute's Mapping the 64
|
||||
sta current_screen_line_ptr+0
|
||||
lda hibase
|
||||
lda HIBASE
|
||||
sta current_screen_line_ptr+1
|
||||
ldx #$03 ; countdown for pages to update
|
||||
iny ; Y now = #$00
|
||||
lda #$20 ; space character
|
||||
ldx #$03 // countdown for pages to update
|
||||
iny // Y now = #$00
|
||||
lda #$20 // space character
|
||||
clearscreen_l2:
|
||||
sta (current_screen_line_ptr),y
|
||||
iny
|
||||
bne clearscreen_l2
|
||||
;; To draw only 1000 bytes, add 250 to address each time
|
||||
// To draw only 1000 bytes, add 250 to address each time
|
||||
lda current_screen_line_ptr
|
||||
clc
|
||||
adc #<250
|
||||
@@ -41,20 +41,20 @@ clearscreen_l2:
|
||||
lda current_screen_line_ptr+1
|
||||
adc #>250
|
||||
sta current_screen_line_ptr+1
|
||||
lda #$20 ; get space character again
|
||||
lda #$20 // get space character again
|
||||
dex
|
||||
bpl clearscreen_l2
|
||||
|
||||
;; Clear colour RAM
|
||||
;; (Compute's Mapping the 64 p216)
|
||||
// Clear colour RAM
|
||||
// (Compute's Mapping the 64 p216)
|
||||
lda text_colour
|
||||
clearscreen_l3:
|
||||
sta $d800,y
|
||||
sta $d900,y
|
||||
sta $da00,y
|
||||
sta $db00-24,y ; so we only erase 1000 bytes
|
||||
sta $db00-24,y // so we only erase 1000 bytes
|
||||
iny
|
||||
bne clearscreen_l3
|
||||
|
||||
;; (Compute's Mapping the 64 p216)
|
||||
// (Compute's Mapping the 64 p216)
|
||||
jmp home_cursor
|
||||
@@ -1,20 +1,20 @@
|
||||
|
||||
setup_vicii:
|
||||
|
||||
;; Set up default IO values (Compute's Mapping the 64 p215)
|
||||
lda #$1B ; Enable text mode
|
||||
// Set up default IO values (Compute's Mapping the 64 p215)
|
||||
lda #$1B // Enable text mode
|
||||
sta VIC_SCROLY
|
||||
lda #$C8 ; 40 column etc
|
||||
lda #$C8 // 40 column etc
|
||||
sta VIC_SCROLX
|
||||
|
||||
;; Compute's Mapping the 64, p156
|
||||
;; We use a different colour scheme of white text on all blue
|
||||
// Compute's Mapping the 64, p156
|
||||
// We use a different colour scheme of white text on all blue
|
||||
lda #$06
|
||||
sta VIC_EXTCOL
|
||||
sta VIC_BGCOL0
|
||||
|
||||
;; Turn off sprites (observed hanging around after running programs and resetting)
|
||||
// Turn off sprites (observed hanging around after running programs and resetting)
|
||||
lda #$00
|
||||
sta VIC_SPENA
|
||||
|
||||
;;FALLTROUGH
|
||||
// FALLTROUGH
|
||||
+5
-5
@@ -1,7 +1,7 @@
|
||||
|
||||
;; Kernal error codes are described in 'Commodore 64 Programmer's Reference Guide', page 306
|
||||
// Kernal error codes are described in 'Commodore 64 Programmer's Reference Guide', page 306
|
||||
|
||||
kernalerror_ROUTINE_TERMINATED: ; by a STOP key
|
||||
kernalerror_ROUTINE_TERMINATED: // by a STOP key
|
||||
lda #K_ERR_ROUTINE_TERMINATED
|
||||
sec
|
||||
rts
|
||||
@@ -56,20 +56,20 @@ kernalerror_TOP_MEM_RS232:
|
||||
sec
|
||||
rts
|
||||
|
||||
;; Kernal status codes are described in 'Commodore 64 Programmer's Reference Guide', page 292
|
||||
// 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!
|
||||
kernalstatus_TIMEOUT_WRITE: // XXX detect this!
|
||||
lda IOSTATUS
|
||||
ora #K_STS_TIMEOUT_WRITE
|
||||
sta IOSTATUS
|
||||
rts
|
||||
|
||||
kernalstatus_TIMEOUT_READ: ;; XXX detect this!
|
||||
kernalstatus_TIMEOUT_READ: // XXX detect this!
|
||||
lda IOSTATUS
|
||||
ora #K_STS_TIMEOUT_READ
|
||||
sta IOSTATUS
|
||||
|
||||
+14
-14
@@ -1,27 +1,27 @@
|
||||
|
||||
;;
|
||||
;; 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
|
||||
;;
|
||||
//
|
||||
// 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!
|
||||
// XXX currently does not preserve registers, to be fixed!
|
||||
|
||||
getin:
|
||||
GETIN:
|
||||
|
||||
;; Wait for a key
|
||||
// Wait for a key
|
||||
lda keys_in_key_buffer
|
||||
bne +
|
||||
bne !+
|
||||
|
||||
;; Nothing in keyboard buffer to read
|
||||
// Nothing in keyboard buffer to read
|
||||
sec
|
||||
lda #$00
|
||||
rts
|
||||
|
||||
*
|
||||
!:
|
||||
lda keyboard_buffer
|
||||
pha
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
;; Our implementation is longer than the original one,
|
||||
;; placing it here would cause a collision with CHROUT
|
||||
// Our implementation is longer than the original one,
|
||||
// placing it here would cause a collision with CHROUT
|
||||
|
||||
chrin:
|
||||
CHRIN:
|
||||
jmp chrin_real
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
;; Our implementation is longer than the original one,
|
||||
;; placing it here would cause a collision with CHKIN
|
||||
// Our implementation is longer than the original one,
|
||||
// placing it here would cause a collision with CHKIN
|
||||
|
||||
chrout:
|
||||
CHROUT:
|
||||
jmp chrout_real
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
;; In our implementation CHKIN and CKOUT are closely tied,
|
||||
;; placing it here would cause a collision
|
||||
// In our implementation CHKIN and CKOUT are closely tied,
|
||||
// placing it here would cause a collision
|
||||
|
||||
chkin:
|
||||
CHKIN:
|
||||
jmp chkin_real
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
;; In our implementation CHKIN and CKOUT are closely tied,
|
||||
;; placing it here would cause a collision
|
||||
// In our implementation CHKIN and CKOUT are closely tied,
|
||||
// placing it here would cause a collision
|
||||
|
||||
ckout:
|
||||
CKOUT:
|
||||
jmp ckout_real
|
||||
+27
-27
@@ -1,49 +1,49 @@
|
||||
|
||||
;;
|
||||
;; 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
|
||||
;;
|
||||
//
|
||||
// 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:
|
||||
CLOSE:
|
||||
|
||||
;; XXX this needs more testing (opening 10 files at once, closing in various orders, etc) once the code is more mature
|
||||
// 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
|
||||
// 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?
|
||||
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
|
||||
// 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
|
||||
// IEC device
|
||||
|
||||
jsr iec_tx_flush ; make sure no byte is awaiting
|
||||
lda SAT, y ; get secondary address
|
||||
jsr iec_tx_flush // make sure no byte is awaiting
|
||||
lda SAT, y // get secondary address
|
||||
cmp #$60
|
||||
bne +
|
||||
;; workaround for using CLOSE on reading executable - XXX is this a proper way?
|
||||
bne !+
|
||||
// workaround for using CLOSE on reading executable - XXX is this a proper way?
|
||||
jsr close_load
|
||||
jmp close_remove_from_table
|
||||
*
|
||||
ora $E0 ; CLOSE command
|
||||
!:
|
||||
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
|
||||
// Remove channel from the table
|
||||
iny
|
||||
cpy #$0A
|
||||
bpl +
|
||||
bpl !+
|
||||
lda LAT, y
|
||||
sta LAT-1, y
|
||||
lda FAT, y
|
||||
@@ -51,14 +51,14 @@ close_remove_from_table:
|
||||
lda SAT, y
|
||||
sta SAT-1, y
|
||||
jmp close_remove_from_table
|
||||
*
|
||||
;; Decrement the list size variable
|
||||
!:
|
||||
// Decrement the list size variable
|
||||
dec LDTND
|
||||
|
||||
clc ; report success - not sure if original CLOSE does this, but it's nevertheless a good practice
|
||||
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
|
||||
sec // report success - not sure if original CLOSE does this, but it's nevertheless a good practice
|
||||
rts
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
;; Our implementation is longer than the original one,
|
||||
;; placing it here would cause a collision with CLRCHN
|
||||
// Our implementation is longer than the original one,
|
||||
// placing it here would cause a collision with CLRCHN
|
||||
|
||||
clall:
|
||||
CLALL:
|
||||
jmp clall_real
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
;; Our implementation is longer than the original one,
|
||||
;; placing it here would cause a collision with OPEN
|
||||
// Our implementation is longer than the original one,
|
||||
// placing it here would cause a collision with OPEN
|
||||
|
||||
clrchn:
|
||||
CLRCHN:
|
||||
jmp clrchn_real
|
||||
+32
-32
@@ -1,23 +1,23 @@
|
||||
|
||||
;;
|
||||
;; Official Kernal routine, described in:
|
||||
;;
|
||||
;; - [RG64] C64 Programmer's Reference Guide - page 289
|
||||
;; - [CM64] Compute's Mapping the Commodore 64 - page 230/231
|
||||
;;
|
||||
;; CPU registers that has to be preserved (see [RG64]): none
|
||||
;;
|
||||
//
|
||||
// Official Kernal routine, described in:
|
||||
//
|
||||
// - [RG64] C64 Programmer's Reference Guide - page 289
|
||||
// - [CM64] Compute's Mapping the Commodore 64 - page 230/231
|
||||
//
|
||||
// CPU registers that has to be preserved (see [RG64]): none
|
||||
//
|
||||
|
||||
|
||||
open:
|
||||
OPEN:
|
||||
|
||||
;; Reset status
|
||||
// Reset status
|
||||
jsr kernalstatus_reset
|
||||
|
||||
;; Check if the logical file number is unique
|
||||
// Check if the logical file number is unique
|
||||
ldy LDTND
|
||||
*
|
||||
beq +
|
||||
!:
|
||||
beq !+
|
||||
dey
|
||||
lda LAT, y
|
||||
cmp current_logical_filenum
|
||||
@@ -25,23 +25,23 @@ open:
|
||||
jmp kernalerror_FILE_ALREADY_OPEN
|
||||
open_not_yet_open:
|
||||
cpy #$00
|
||||
jmp -
|
||||
*
|
||||
;; Check if we have space in tables
|
||||
jmp !-
|
||||
!:
|
||||
// Check if we have space in tables
|
||||
|
||||
ldy LDTND
|
||||
cpy #$0A
|
||||
bcc open_has_space
|
||||
*
|
||||
;; Table is full
|
||||
!:
|
||||
// Table is full
|
||||
jmp kernalerror_TOO_MANY_OPEN_FILES
|
||||
|
||||
open_has_space:
|
||||
|
||||
;; Update the tables
|
||||
// Update the tables
|
||||
|
||||
;; LAT / FAT / SAT support implemented according to
|
||||
;; 'Compute's Mapping the Commodore 64', page 52
|
||||
// LAT / FAT / SAT support implemented according to
|
||||
// 'Compute's Mapping the Commodore 64', page 52
|
||||
|
||||
lda current_logical_filenum
|
||||
sta LAT, y
|
||||
@@ -53,16 +53,16 @@ open_has_space:
|
||||
iny
|
||||
sty LDTND
|
||||
|
||||
;; Check for command to send
|
||||
// Check for command to send
|
||||
lda FNLEN
|
||||
beq open_done_success
|
||||
|
||||
;; Check for IEC device
|
||||
// Check for IEC device
|
||||
lda current_device_number
|
||||
jsr iec_check_devnum
|
||||
bcc open_iec
|
||||
|
||||
;; FALLTROUGH
|
||||
// FALLTROUGH
|
||||
open_done_success:
|
||||
|
||||
clc
|
||||
@@ -70,21 +70,21 @@ open_done_success:
|
||||
|
||||
open_iec:
|
||||
|
||||
;; We have a command to send to IEC device
|
||||
jsr listen
|
||||
bcc +
|
||||
// We have a command to send to IEC device
|
||||
jsr LISTEN
|
||||
bcc !+
|
||||
jmp kernalerror_DEVICE_NOT_FOUND
|
||||
*
|
||||
!:
|
||||
lda current_secondary_address
|
||||
jsr iec_cmd_open
|
||||
bcc +
|
||||
bcc !+
|
||||
jmp kernalerror_DEVICE_NOT_FOUND
|
||||
*
|
||||
!:
|
||||
|
||||
;; We need our helpers to get to filenames under ROMs or IO area
|
||||
// We need our helpers to get to filenames under ROMs or IO area
|
||||
jsr install_ram_routines
|
||||
|
||||
;; Send command ('file name')
|
||||
// Send command ('file name')
|
||||
jsr lvs_send_file_name
|
||||
|
||||
jmp open_done_success
|
||||
+92
-92
@@ -1,146 +1,146 @@
|
||||
|
||||
;;
|
||||
;; Official Kernal routine, described in:
|
||||
;;
|
||||
;; - [RG64] C64 Programmer's Reference Guide - page 286
|
||||
;; - [CM64] Compute's Mapping the Commodore 64 - page 231
|
||||
;; - IEC reference at http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf
|
||||
;;
|
||||
;; CPU registers that has to be preserved (see [RG64]): none
|
||||
;;
|
||||
//
|
||||
// Official Kernal routine, described in:
|
||||
//
|
||||
// - [RG64] C64 Programmer's Reference Guide - page 286
|
||||
// - [CM64] Compute's Mapping the Commodore 64 - page 231
|
||||
// - IEC reference at http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf
|
||||
//
|
||||
// CPU registers that has to be preserved (see [RG64]): none
|
||||
//
|
||||
|
||||
|
||||
;; Expects that SETLFS and SETNAM are called before hand.
|
||||
;; $YYXX = load address.
|
||||
;; (ignored if SETLFS channel = 1, i.e., like ,8,1)
|
||||
;; If A=1 then VERIFY instead of LOAD.
|
||||
;; On exit, $YYXX is the highest address into which data
|
||||
;; will have been placed.
|
||||
// Expects that SETLFS and SETNAM are called before hand.
|
||||
// $YYXX = load address.
|
||||
// (ignored if SETLFS channel = 1, i.e., like ,8,1)
|
||||
// If A=1 then VERIFY instead of LOAD.
|
||||
// On exit, $YYXX is the highest address into which data
|
||||
// will have been placed.
|
||||
|
||||
;; XXX honor MSGFLG bit 6
|
||||
;; XXX add VERIFY support
|
||||
// XXX honor MSGFLG bit 6
|
||||
// XXX add VERIFY support
|
||||
|
||||
load:
|
||||
LOAD:
|
||||
|
||||
;; Are we loading or verifying?
|
||||
// Are we loading or verifying?
|
||||
sta VERCK
|
||||
|
||||
;; Store start address of LOAD
|
||||
// Store start address of LOAD
|
||||
stx STAL+0
|
||||
sty STAL+1
|
||||
|
||||
;; Reset status
|
||||
// Reset status
|
||||
jsr kernalstatus_reset
|
||||
|
||||
;; We need our helpers to get to filenames under ROMs or IO area
|
||||
// We need our helpers to get to filenames under ROMs or IO area
|
||||
jsr install_ram_routines
|
||||
|
||||
;; Allow platform-specific routine to takeover the flow
|
||||
`TARGET_HOOK_LOAD
|
||||
// Allow platform-specific routine to takeover the flow
|
||||
TARGET_HOOK_LOAD()
|
||||
|
||||
;; Check whether we support the requested device
|
||||
// Check whether we support the requested device
|
||||
lda current_device_number
|
||||
and #$FC
|
||||
bne +
|
||||
jmp lvs_illegal_device_number ; device number below 4, not an IEC device
|
||||
*
|
||||
;; Device numbers above 30 are also illegal (see https://www.pagetable.com/?p=1031),
|
||||
;; as the protocol combines device number with command code int one byte,
|
||||
;; above 30 it is no longer possible (UNLISTEN and UNTALK codes prevent using
|
||||
;; number 31), yet original ROMs show ILLEGAL DEVICE NUMBER error only
|
||||
;; for devices 0-3; in our implementation LISTEN / TALK will cause device
|
||||
;; not present detected for numbers above 30
|
||||
bne !+
|
||||
jmp lvs_illegal_device_number // device number below 4, not an IEC device
|
||||
!:
|
||||
// Device numbers above 30 are also illegal (see https://www.pagetable.com/?p=1031),
|
||||
// as the protocol combines device number with command code int one byte,
|
||||
// above 30 it is no longer possible (UNLISTEN and UNTALK codes prevent using
|
||||
// number 31), yet original ROMs show ILLEGAL DEVICE NUMBER error only
|
||||
// for devices 0-3; in our implementation LISTEN / TALK will cause device
|
||||
// not present detected for numbers above 30
|
||||
|
||||
;; Display SEARCHING FOR + filename
|
||||
// Display SEARCHING FOR + filename
|
||||
jsr lvs_display_searching_for
|
||||
|
||||
;; http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf
|
||||
;; p13, 16; also p16 tells us this routine doesn't mess with the file table
|
||||
;; in the C64, only in the drive.
|
||||
// http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf
|
||||
// p13, 16; also p16 tells us this routine doesn't mess with the file table
|
||||
// in the C64, only in the drive.
|
||||
|
||||
;; Call device to LISTEN (p16)
|
||||
// Call device to LISTEN (p16)
|
||||
lda current_device_number
|
||||
jsr listen
|
||||
bcc +
|
||||
jmp lvs_device_not_found_error ; XXX deduplicate with other jumps in this routine
|
||||
*
|
||||
;; Open channel 0 (reserved for file reading)
|
||||
jsr LISTEN
|
||||
bcc !+
|
||||
jmp lvs_device_not_found_error // XXX deduplicate with other jumps in this routine
|
||||
!:
|
||||
// Open channel 0 (reserved for file reading)
|
||||
lda #$00
|
||||
jsr iec_cmd_open
|
||||
bcc +
|
||||
jmp lvs_device_not_found_error ; XXX deduplicate with other jumps in this routine
|
||||
*
|
||||
;; Send file name
|
||||
bcc !+
|
||||
jmp lvs_device_not_found_error // XXX deduplicate with other jumps in this routine
|
||||
!:
|
||||
// Send file name
|
||||
jsr lvs_send_file_name
|
||||
bcc +
|
||||
jmp lvs_load_verify_error ; XXX deduplicate with other jumps in this routine
|
||||
*
|
||||
;; Now command device to talk (p16)
|
||||
bcc !+
|
||||
jmp lvs_load_verify_error // XXX deduplicate with other jumps in this routine
|
||||
!:
|
||||
// Now command device to talk (p16)
|
||||
lda current_device_number
|
||||
jsr talk
|
||||
bcc +
|
||||
jmp lvs_load_verify_error ; XXX deduplicate with other jumps in this routine
|
||||
*
|
||||
lda #$60 ; open channel / data (p3) , required according to p13
|
||||
jsr TALK
|
||||
bcc !+
|
||||
jmp lvs_load_verify_error // XXX deduplicate with other jumps in this routine
|
||||
!:
|
||||
lda #$60 // open channel / data (p3) , required according to p13
|
||||
sta IEC_TMP2
|
||||
jsr iec_tx_command
|
||||
bcc +
|
||||
jmp lvs_load_verify_error ; XXX deduplicate with other jumps in this routine
|
||||
*
|
||||
;; We are currently talker, so do the IEC turn around so that we
|
||||
;; are the listener (p16)
|
||||
bcc !+
|
||||
jmp lvs_load_verify_error // XXX deduplicate with other jumps in this routine
|
||||
!:
|
||||
// We are currently talker, so do the IEC turn around so that we
|
||||
// are the listener (p16)
|
||||
jsr iec_turnaround_to_listen
|
||||
bcc +
|
||||
jmp lvs_load_verify_error ; XXX deduplicate with other jumps in this routine
|
||||
*
|
||||
;; Get load address and store it if secondary address is zero
|
||||
bcc !+
|
||||
jmp lvs_load_verify_error // XXX deduplicate with other jumps in this routine
|
||||
!:
|
||||
// Get load address and store it if secondary address is zero
|
||||
jsr iec_rx_byte
|
||||
bcc +
|
||||
jmp lvs_file_not_found_error ; XXX deduplicate with other jumps in this routine
|
||||
*
|
||||
bcc !+
|
||||
jmp lvs_file_not_found_error // XXX deduplicate with other jumps in this routine
|
||||
!:
|
||||
ldx current_secondary_address
|
||||
beq +
|
||||
beq !+
|
||||
sta STAL+0
|
||||
*
|
||||
!:
|
||||
jsr iec_rx_byte
|
||||
bcc +
|
||||
jmp lvs_file_not_found_error ; XXX deduplicate with other jumps in this routine
|
||||
*
|
||||
bcc !+
|
||||
jmp lvs_file_not_found_error // XXX deduplicate with other jumps in this routine
|
||||
!:
|
||||
ldx current_secondary_address
|
||||
beq +
|
||||
beq !+
|
||||
sta STAL+1
|
||||
*
|
||||
;; Display start address
|
||||
!:
|
||||
// Display start address
|
||||
jsr lvs_display_loading_verifying
|
||||
|
||||
load_loop:
|
||||
;; We are now ready to receive bytes
|
||||
// We are now ready to receive bytes
|
||||
jsr iec_rx_byte
|
||||
bcc +
|
||||
jmp lvs_load_verify_error ; XXX deduplicate with other jumps in this routine
|
||||
*
|
||||
;; Handle the byte (store in memory / verify)
|
||||
bcc !+
|
||||
jmp lvs_load_verify_error // XXX deduplicate with other jumps in this routine
|
||||
!:
|
||||
// Handle the byte (store in memory / verify)
|
||||
jsr lvs_handle_byte_load_verify
|
||||
bcc +
|
||||
jmp lvs_load_verify_error ; XXX deduplicate with other jumps in this routine
|
||||
*
|
||||
;; Advance pointer to data
|
||||
bcc !+
|
||||
jmp lvs_load_verify_error // XXX deduplicate with other jumps in this routine
|
||||
!:
|
||||
// Advance pointer to data
|
||||
jsr lvs_advance_pointer
|
||||
bcc +
|
||||
bcc !+
|
||||
jmp lvs_wrap_around_error
|
||||
*
|
||||
;; Check for EOI - if so, this was the last byte
|
||||
!:
|
||||
// Check for EOI - if so, this was the last byte
|
||||
lda IOSTATUS
|
||||
and #K_STS_EOI
|
||||
beq load_loop
|
||||
|
||||
;; Display end address
|
||||
// Display end address
|
||||
jsr lvs_display_done
|
||||
|
||||
;; Close file on drive
|
||||
// Close file on drive
|
||||
|
||||
lda current_device_number
|
||||
jsr close_load
|
||||
|
||||
;; Return last address
|
||||
// Return last address
|
||||
jmp lvs_return_last_address
|
||||
+10
-10
@@ -1,13 +1,13 @@
|
||||
|
||||
;;
|
||||
;; Official Kernal routine, described in:
|
||||
;;
|
||||
;; - [RG64] C64 Programmer's Reference Guide - page 293/294
|
||||
;; - [CM64] Compute's Mapping the Commodore 64 - page 231/232
|
||||
;; - IEC reference at http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf
|
||||
;;
|
||||
;; CPU registers that has to be preserved (see [RG64]): none
|
||||
;;
|
||||
//
|
||||
// Official Kernal routine, described in:
|
||||
//
|
||||
// - [RG64] C64 Programmer's Reference Guide - page 293/294
|
||||
// - [CM64] Compute's Mapping the Commodore 64 - page 231/232
|
||||
// - IEC reference at http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf
|
||||
//
|
||||
// CPU registers that has to be preserved (see [RG64]): none
|
||||
//
|
||||
|
||||
save:
|
||||
SAVE:
|
||||
rts
|
||||
+15
-15
@@ -1,24 +1,24 @@
|
||||
|
||||
;;
|
||||
;; Official Kernal routine, described in:
|
||||
;;
|
||||
;; - [RG64] C64 Programmer's Reference Guide - page 301
|
||||
;; - [CM64] Compute's Mapping the Commodore 64 - page 232
|
||||
;;
|
||||
;; CPU registers that has to be preserved (see [RG64]): .Y
|
||||
;;
|
||||
//
|
||||
// Official Kernal routine, described in:
|
||||
//
|
||||
// - [RG64] C64 Programmer's Reference Guide - page 301
|
||||
// - [CM64] Compute's Mapping the Commodore 64 - page 232
|
||||
//
|
||||
// CPU registers that has to be preserved (see [RG64]): .Y
|
||||
//
|
||||
|
||||
stop:
|
||||
;; Bit 7 of STKEY contains the state of the STOP key
|
||||
;; (Compute's Mapping the 64, p27)
|
||||
STOP:
|
||||
// Bit 7 of STKEY contains the state of the STOP key
|
||||
// (Compute's Mapping the 64, p27)
|
||||
|
||||
;; BASIC checks carry flag to indicate STOP or not
|
||||
// BASIC checks carry flag to indicate STOP or not
|
||||
lda STKEY
|
||||
bpl stop_pressed
|
||||
|
||||
;; By trial and error, we know that Z + C = BREAK
|
||||
;; and that neither should be set otherwise
|
||||
lda #$ff
|
||||
// By trial and error, we know that Z + C = BREAK
|
||||
// and that neither should be set otherwise
|
||||
lda #$FF
|
||||
clc
|
||||
rts
|
||||
|
||||
|
||||
+30
-36
@@ -1,70 +1,64 @@
|
||||
|
||||
;;
|
||||
;; Official Kernal routine, described in:
|
||||
;;
|
||||
;; - [RG64] C64 Programmer's Reference Guide - page 293 (RESTOR), 304 (VECTOR)
|
||||
;; - [CM64] Compute's Mapping the Commodore 64 - page 237
|
||||
;;
|
||||
;; CPU registers that has to be preserved (see [RG64]): none
|
||||
;;
|
||||
//
|
||||
// Official Kernal routine, described in:
|
||||
//
|
||||
// - [RG64] C64 Programmer's Reference Guide - page 293 (RESTOR), 304 (VECTOR)
|
||||
// - [CM64] Compute's Mapping the Commodore 64 - page 237
|
||||
//
|
||||
// CPU registers that has to be preserved (see [RG64]): none
|
||||
//
|
||||
|
||||
restor:
|
||||
RESTOR:
|
||||
|
||||
clc ;; clear carry - for writing to system table
|
||||
clc // clear carry - for writing to system table
|
||||
ldx #<vector_defaults
|
||||
ldy #>vector_defaults
|
||||
|
||||
;; FALLTHROUGH
|
||||
// FALLTHROUGH
|
||||
|
||||
vector:
|
||||
VECTOR:
|
||||
|
||||
.scope
|
||||
// Temporary storage location - checked on real C64 that this is the
|
||||
// address originally used; after calling VECTOR and checking zero page
|
||||
// area afterwards, the address could be found there
|
||||
.label _caller_arr_ptr = MEMUS
|
||||
|
||||
;; Temporary storage location - checked on real C64 that this is the
|
||||
;; address originally used; after calling VECTOR and checking zero page
|
||||
;; area afterwards, the address could be found there
|
||||
.alias _caller_arr_ptr MEMUS
|
||||
|
||||
;; According to 'Compute's Mapping the Commodore 64' page 237,
|
||||
;; the CBM implementation does not disable IRQs - yet, the
|
||||
;; 'C64 Programmers Reference Guide' does not contain such
|
||||
;; warning and does not mention any preparations needed, so...
|
||||
;; better safe than sorry, disable the IRQ for the duration
|
||||
;; of vector manipulation
|
||||
// According to 'Compute's Mapping the Commodore 64' page 237,
|
||||
// the CBM implementation does not disable IRQs - yet, the
|
||||
// 'C64 Programmers Reference Guide' does not contain such
|
||||
// warning and does not mention any preparations needed, so...
|
||||
// better safe than sorry, disable the IRQ for the duration
|
||||
// of vector manipulation
|
||||
php
|
||||
cli
|
||||
|
||||
;; Prepare the user data pointer - strange order to reduce risk
|
||||
;; of potential similarity to the original routine
|
||||
// Prepare the user data pointer - strange order to reduce risk
|
||||
// of potential similarity to the original routine
|
||||
sty _caller_arr_ptr + 1
|
||||
stx _caller_arr_ptr + 0
|
||||
|
||||
;; Select routine variant - store or restore vectors
|
||||
// Select routine variant - store or restore vectors
|
||||
ldy #$1F
|
||||
bcc vector_restore
|
||||
|
||||
;; FALLTHROUGH
|
||||
// FALLTHROUGH
|
||||
|
||||
vector_store:
|
||||
*
|
||||
lda CINV, y
|
||||
sta (_caller_arr_ptr), y
|
||||
dey
|
||||
bpl -
|
||||
bpl vector_store
|
||||
|
||||
;; Restore status register (IRQ) before return
|
||||
// Restore status register (IRQ) before return
|
||||
plp
|
||||
rts
|
||||
|
||||
vector_restore:
|
||||
*
|
||||
lda (_caller_arr_ptr), y
|
||||
sta CINV, y
|
||||
dey
|
||||
bpl -
|
||||
bpl vector_restore
|
||||
|
||||
;; Restore status register (IRQ) before return
|
||||
// Restore status register (IRQ) before return
|
||||
plp
|
||||
rts
|
||||
|
||||
.scend
|
||||
+34
-34
@@ -1,34 +1,34 @@
|
||||
|
||||
;;
|
||||
;; 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
|
||||
;;
|
||||
//
|
||||
// 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:
|
||||
IOINIT:
|
||||
|
||||
; Set $00/$01 port mode and value
|
||||
; We want BASIC and KERNAL ROMs mapped, and datasette motor off
|
||||
; (https://www.c64-wiki.com/wiki/Zeropage)
|
||||
;; XXX - Work around VICE bug: Writing $00 before $01 results in rubbish in $01
|
||||
;; after. https://sourceforge.net/p/vice-emu/bugs/1057/
|
||||
// Set $00/$01 port mode and value
|
||||
// We want BASIC and KERNAL ROMs mapped, and datasette motor off
|
||||
// (https://www.c64-wiki.com/wiki/Zeropage)
|
||||
// XXX - Work around VICE bug: Writing $00 before $01 results in rubbish in $01
|
||||
// after. https://sourceforge.net/p/vice-emu/bugs/1057/
|
||||
lda #$27
|
||||
ldx #$2F
|
||||
sta CPU_R6510
|
||||
stx CPU_D6510
|
||||
|
||||
;; Silence the SID chips under common addresses
|
||||
// Silence the SID chips under common addresses
|
||||
|
||||
ldy #$00
|
||||
*
|
||||
;; SIDs under $D4xx
|
||||
!:
|
||||
// SIDs under $D4xx
|
||||
lda SID_SIGVOL, Y
|
||||
and #$F0
|
||||
sta SID_SIGVOL, Y
|
||||
;; SIDs under $D5xx
|
||||
// SIDs under $D5xx
|
||||
lda SID_SIGVOL + $100, Y
|
||||
and #$F0
|
||||
sta SID_SIGVOL + $100, Y
|
||||
@@ -36,24 +36,24 @@ ioinit:
|
||||
clc
|
||||
adc #$20
|
||||
tay
|
||||
bne -
|
||||
bne !-
|
||||
|
||||
;; XXX: calibrate TOD for both CIA's, see here: https://codebase64.org/doku.php?id=base:efficient_tod_initialisation
|
||||
// XXX: calibrate TOD for both CIA's, see here: https://codebase64.org/doku.php?id=base:efficient_tod_initialisation
|
||||
|
||||
;; Enable CIA1 IRQ and ~50Hz timer (https://csdb.dk/forums/?roomid=11&topicid=69037)
|
||||
// Enable CIA1 IRQ and ~50Hz timer (https://csdb.dk/forums/?roomid=11&topicid=69037)
|
||||
lda #$7F
|
||||
sta CIA1_ICR ; disable all
|
||||
sta CIA1_ICR // disable all
|
||||
|
||||
;; Set timer interval to ~1/60th of a second
|
||||
// Set timer interval to ~1/60th of a second
|
||||
|
||||
;; (This value was calculated by running a custom IRQ handler on a C64
|
||||
;; with original KERNAL, and writing the values of $DC04/5 to the screen
|
||||
;; in the IRQ handler to see roughly what value the timers must be set to)
|
||||
;; ldy #<16380
|
||||
;; ldx #>16380
|
||||
// (This value was calculated by running a custom IRQ handler on a C64
|
||||
// with original KERNAL, and writing the values of $DC04/5 to the screen
|
||||
// in the IRQ handler to see roughly what value the timers must be set to)
|
||||
// ldy #<16380
|
||||
// ldx #>16380
|
||||
|
||||
;; PAL C64 (https://codebase64.org/doku.php?id=base:cpu_clocking),
|
||||
;; is clocked at 0.985248 MHz, so that 1/60s is 16421 CPU cycles
|
||||
// PAL C64 (https://codebase64.org/doku.php?id=base:cpu_clocking),
|
||||
// is clocked at 0.985248 MHz, so that 1/60s is 16421 CPU cycles
|
||||
|
||||
ldy #<16421
|
||||
ldx #>16421
|
||||
@@ -61,19 +61,19 @@ ioinit:
|
||||
sty CIA1_TIMALO
|
||||
stx CIA1_TIMAHI
|
||||
|
||||
;; Enable timer interrupt
|
||||
// Enable timer interrupt
|
||||
lda #$81
|
||||
sta CIA1_ICR
|
||||
|
||||
;; Enable timer A to run continuously (http://codebase64.org/doku.php?id=base:timerinterrupts)
|
||||
// Enable timer A to run continuously (http://codebase64.org/doku.php?id=base:timerinterrupts)
|
||||
lda #$11
|
||||
sta CIA1_CRA
|
||||
lda CIA1_ICR
|
||||
|
||||
;; Set DDR on CIA2 for IEC bus, VIC-II banking
|
||||
// Set DDR on CIA2 for IEC bus, VIC-II banking
|
||||
lda #$3B
|
||||
sta CIA2_DDRA
|
||||
|
||||
;; Set IEC bus to its initial idle state
|
||||
// Set IEC bus to its initial idle state
|
||||
jmp iec_set_idle
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
;; Our implementation is longer than the original one,
|
||||
;; placing it here would cause a collision with OPEN
|
||||
// Our implementation is longer than the original one,
|
||||
// placing it here would cause a collision with OPEN
|
||||
|
||||
cint:
|
||||
CINT:
|
||||
jmp cint_real
|
||||
@@ -1,31 +1,63 @@
|
||||
|
||||
;;
|
||||
;; This byte identifies Kernal revision. Sources:
|
||||
;; - [CM64] Compute's Mapping the Commodore 64 (page 242/243)
|
||||
;; - [MM] Marko Mäkelä article, http://www.zimmers.net/anonftp/pub/cbm/firmware/computers/c64/revisions.txt
|
||||
;; - [VICE] Checked with ROMs included in VICE emulator
|
||||
;;
|
||||
;; IDEA: put here a value, that is different from any version currently known, as
|
||||
;; a warning that this is not a Commodore Kernal. Currently known numbers for C64 are:
|
||||
;;
|
||||
;; - $00 - [CM64] then current number [MM] 901227-02 [VICE] C64 Revision 2
|
||||
;; - $03 - [CM64] (not mentionned) [MM] 901227-02, 901227-03 [VICE] C64 Revision 3
|
||||
;; - $43 - [CM64] (not mentionned) [MM] 251104-04 [VICE] SX-64
|
||||
;; - $64 - [CM64] PET64 ROM [MM] (not mentionned) [VICE] PET64
|
||||
;; - $AA - [CM64] first version of ROM [MM] 901227-01 [VICE] C64 Revision 1
|
||||
;;
|
||||
;; Values from unofficial ROMs:
|
||||
;; - $03 - SuperCPU ROM 1.40, 2.04, also unofficial 0.7 ROM from [VICE]
|
||||
;;
|
||||
;; Values from other Commodore machines:
|
||||
;; C128:
|
||||
;; - $01 - see https://www.pagetable.com/?p=1058
|
||||
;; - $02 - unreleased updated ROM, see https://www.pagetable.com/?p=1058
|
||||
;;
|
||||
;; XXX check more unofficial C64 ROMs (JiffyDOS, DolphinDOS, etc.) and other machines
|
||||
;; VIC-20, PET, CBM II, 264 series, C65 prototypes, other sources for C128 ROMs
|
||||
;;
|
||||
|
||||
//
|
||||
// This byte (hex $FF80, dec 65408) identifies Kernal revision on several machines. Although not all
|
||||
// of the, used it for versioning purpose, here is the list of all the values I could find. Sources:
|
||||
// - [CM64] Compute's Mapping the Commodore 64 (page 242/243)
|
||||
// - [MM] Marko Mäkelä article, http://www.zimmers.net/anonftp/pub/cbm/firmware/computers/c64/revisions.txt
|
||||
// - [VICE] Checked with ROMs included in VICE emulator
|
||||
// - [XEMU] Checked with ROMs retrieved by XEMU emulator
|
||||
//
|
||||
// IDEA: put here a value, that is different from any version currently known, as
|
||||
// a warning that this is not a Commodore Kernal or anything already known.
|
||||
//
|
||||
// C64 - values from the official ROMs:
|
||||
// - $00 - [CM64] then current number [MM] 901227-02 [VICE] C64 Revision 2
|
||||
// - $03 - [CM64] (not mentionned) [MM] 901227-02, 901227-03 [VICE] C64 Revision 3
|
||||
// - $43 - [CM64] (not mentionned) [MM] 251104-04 [VICE] SX-64
|
||||
// - $64 - [CM64] PET64 ROM [MM] (not mentionned) [VICE] PET64
|
||||
// - $AA - [CM64] first version of ROM [MM] 901227-01 [VICE] C64 Revision 1
|
||||
//
|
||||
// C64 - values from unofficial 3rd party ROMs:
|
||||
// - $00 - Turbo Trans, Turbo Access, Turbo Process
|
||||
// - $03 - SuperCPU ROM 1.40, 2.04, also unofficial 0.7 ROM from [VICE],
|
||||
// DolphinDOS 2.0, JiffyDOS 6.01, EXOS V3/4,
|
||||
// Datel Mercury V3 US, Datel DOS-ROM V1.2, Datel Turbo ROM II V3.2+,
|
||||
// Turbo Process US,
|
||||
// burst CIA 1/2 Kernal by Albert, SD2IEC Kernal 1.0/2.0/2.1/2.2 by Claus
|
||||
// - $4A - S-JiffyDOS
|
||||
// - $53 - Professional DOS V1, SpeedDOS Plus 2.7
|
||||
// - $C3 - Cockroach Turbo ROM V1
|
||||
//
|
||||
// PET:
|
||||
// - $40 - [VICE] PET 2001-8N
|
||||
// - $A7 - [VICE] PET 30XX
|
||||
// - $AA - [VICE] PET 40XX, PET 80XX, SuperPET
|
||||
//
|
||||
// CBM II:
|
||||
// - $E0 - [VICE] 5x0, 6x0, 7x0 models
|
||||
//
|
||||
// VIC-20:
|
||||
// - $16 - [VICE] all models, also VIC-20 JiffyDOS PAL/NTSC
|
||||
//
|
||||
// 264 family:
|
||||
// - $01 - [VICE] 364
|
||||
// - $05 - [VICE] C16, C116, Plus/4
|
||||
// - $06 - (unofficial) JiffyDOS NTSC
|
||||
// - $81 - [VICE] 232
|
||||
// - $86 - (unofficial) JiffyDOS PAL
|
||||
//
|
||||
// C128:
|
||||
// - $01 - see https://www.pagetable.com/?p=1058
|
||||
// - $02 - unreleased updated ROM, see https://www.pagetable.com/?p=1058
|
||||
//
|
||||
// Commodore prototypes:
|
||||
// - $04 - [XEMU] 64 mode ROM of the C65 prototype, ROM 910111
|
||||
// - $FF - [XEMU] C65 native mode, ROM 910111
|
||||
// - $FF - [XEMU] Commodore LCD
|
||||
//
|
||||
// Non-Commodore machines:
|
||||
// - $FF - Commander X16 (emulator r28)
|
||||
//
|
||||
|
||||
kernal_revision:
|
||||
.byte $FF
|
||||
.byte $FF // XXX possibly change this value (current candidate: $F0), $FF conflicts with other machines
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
; $FFFA - CPU NMI Hanlder
|
||||
; Uncontrovertial as this is also a CPU requirement.
|
||||
// $FFFA - CPU NMI Hanlder
|
||||
// Uncontrovertial as this is also a CPU requirement.
|
||||
|
||||
.word nmi_handler
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
; $FFFC - CPU Reset Vector
|
||||
; Uncontrovertial, as it is a CPU requirement, and nothing else.
|
||||
// $FFFC - CPU Reset Vector
|
||||
// Uncontrovertial, as it is a CPU requirement, and nothing else.
|
||||
|
||||
.word reset_entry
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
; $FFFE - CPU IRQ Vector.
|
||||
; This is non-controvertial, as it is a 6502 CPU requirement, and we just have to point
|
||||
; it to whatever IRQ routine we make.
|
||||
// $FFFE - CPU IRQ Vector.
|
||||
// This is non-controvertial, as it is a 6502 CPU requirement, and we just have to point
|
||||
// it to whatever IRQ routine we make.
|
||||
|
||||
.word irq_handler
|
||||
@@ -1,18 +1,18 @@
|
||||
|
||||
;; Just a helper routines
|
||||
// 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 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
|
||||
*
|
||||
beq find_fls_not_found // table empty
|
||||
!:
|
||||
dey
|
||||
bmi find_fls_not_found ; no more entries
|
||||
bmi find_fls_not_found // no more entries
|
||||
cmp LAT, y
|
||||
bne - ; does not match, try the next one
|
||||
bne !- // does not match, try the next one
|
||||
|
||||
clc
|
||||
rts
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
;; Home the cursor
|
||||
;; (Compute's Mapping the 64 p216)
|
||||
// Home the cursor
|
||||
// (Compute's Mapping the 64 p216)
|
||||
|
||||
home_cursor:
|
||||
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
|
||||
;;
|
||||
;; Checks whether device number (in .A) is a correct IEC device number
|
||||
;;
|
||||
;; Preserves .A, .X and .Y
|
||||
;;
|
||||
//
|
||||
// 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
|
||||
// 0, 1, 2, or 3 are illegal - reserved for non-IEC devices on Commodore
|
||||
cmp #$04
|
||||
bcs +
|
||||
;; FALLTROUGH
|
||||
bcs !+
|
||||
// FALLTROUGH
|
||||
iec_check_devnum_failed:
|
||||
sec ; indicate non-IEC device
|
||||
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
|
||||
!:
|
||||
// 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
|
||||
// Carry is clear here - indicates IEC device
|
||||
rts
|
||||
@@ -1,16 +1,16 @@
|
||||
|
||||
;;
|
||||
;; Kernal internal IEC routine
|
||||
;;
|
||||
;; - https://www.pagetable.com/?p=1031, https://github.com/mist64/cbmbus_doc
|
||||
;;
|
||||
//
|
||||
// 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 +
|
||||
bcc !+
|
||||
jmp kernalerror_FILE_NOT_INPUT
|
||||
*
|
||||
!:
|
||||
ora #$E0
|
||||
|
||||
jmp common_open_close_unlsn_second
|
||||
@@ -1,42 +1,42 @@
|
||||
|
||||
;;
|
||||
;; Kernal internal IEC routine
|
||||
;;
|
||||
;; - https://www.pagetable.com/?p=1031, https://github.com/mist64/cbmbus_doc
|
||||
;;
|
||||
//
|
||||
// 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
|
||||
iec_cmd_open: // similar to TKSA, but without turnaround
|
||||
|
||||
jsr iec_check_channel_openclose
|
||||
bcc +
|
||||
bcc !+
|
||||
jmp kernalerror_FILE_NOT_INPUT
|
||||
*
|
||||
!:
|
||||
ora #$F0
|
||||
|
||||
;; FALLTROUGH
|
||||
// FALLTROUGH
|
||||
|
||||
common_open_close_unlsn_second: ; common part of several commands
|
||||
common_open_close_unlsn_second: // common part of several commands
|
||||
|
||||
sta IEC_TMP2
|
||||
jsr iec_tx_command
|
||||
bcs + ; branch if error
|
||||
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
|
||||
// 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
|
||||
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
|
||||
beq !+
|
||||
sec // mark unsuitable channel number
|
||||
rts
|
||||
*
|
||||
clc ; mark suitable channel number
|
||||
!:
|
||||
clc // mark suitable channel number
|
||||
rts
|
||||
Loaded 100 of 198 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user