adapted to Kick Assembler, some documentation update
This commit is contained in:
1 parent
ae23dbae7b
commit
de27124b4f
198 files changed
+3979
-3774
No files matched your search
+2
-2
@@ -2,9 +2,9 @@
|
|||||||
# Compilation related files
|
# Compilation related files
|
||||||
|
|
||||||
temp.s
|
temp.s
|
||||||
temp.map
|
temp.sym
|
||||||
|
|
||||||
ophis.bin
|
assembler/KickAss*
|
||||||
build/*
|
build/*
|
||||||
|
|
||||||
# Input to the similarity tool - copyrighted material, we can't check it in!
|
# 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
|
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:
|
clean:
|
||||||
@rm -rf build
|
@rm -rf build
|
||||||
@rm -f temp.s
|
@rm -f temp.s
|
||||||
@rm -f temp.map
|
@rm -f temp.sym
|
||||||
@rm -f ophis.bin
|
|
||||||
|
|
||||||
updatebin: build/chargen build/newbasic_generic build/newkern_generic build/newbasic_mega65 build/newkern_mega65 build/newbasic_ultimate64 build/newkern_ultimate64
|
updatebin: build/chargen build/newbasic_generic build/newkern_generic build/newbasic_mega65 build/newkern_mega65 build/newbasic_ultimate64 build/newkern_ultimate64
|
||||||
cp build/chargen bin/chargen.rom
|
cp build/chargen bin/chargen.rom
|
||||||
@@ -81,23 +76,23 @@ build/chargen: $(TOOL_PNGPREPARE) assets/8x8font.png
|
|||||||
|
|
||||||
# Dependencies
|
# Dependencies
|
||||||
|
|
||||||
build/basic_generic/OUT.BIN: Ophis $(TOOLS_LIST) $(SRC_BASIC_generic) build/basic/packed_messages.s
|
build/basic_generic/OUT.BIN: $(TOOLS_LIST) $(SRC_BASIC_generic) build/basic/packed_messages.s
|
||||||
build/kernal_generic/OUT.BIN: Ophis $(TOOLS_LIST) $(SRC_KERNAL_generic)
|
build/kernal_generic/OUT.BIN: $(TOOLS_LIST) $(SRC_KERNAL_generic)
|
||||||
build/newrom_generic: build/basic_generic/OUT.BIN build/kernal_generic/OUT.BIN
|
build/newrom_generic: build/basic_generic/OUT.BIN build/kernal_generic/OUT.BIN
|
||||||
build/newkern_generic: build/newrom_generic Makefile
|
build/newkern_generic: build/newrom_generic Makefile
|
||||||
build/newbasic_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/basic_mega65/OUT.BIN: $(TOOLS_LIST) $(SRC_BASIC_mega65) build/basic/packed_messages.s
|
||||||
build/kernal_mega65/OUT.BIN: Ophis $(TOOLS_LIST) $(SRC_KERNAL_mega65)
|
build/kernal_mega65/OUT.BIN: $(TOOLS_LIST) $(SRC_KERNAL_mega65)
|
||||||
build/newrom_mega65: build/basic_mega65/OUT.BIN build/kernal_mega65/OUT.BIN
|
build/newrom_mega65: build/basic_mega65/OUT.BIN build/kernal_mega65/OUT.BIN
|
||||||
build/newkern_mega65: build/newrom_mega65 Makefile
|
build/newkern_mega65: build/newrom_mega65 Makefile
|
||||||
build/newbasic_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/basic_ultimate64/OUT.BIN: $(TOOLS_LIST) $(SRC_BASIC_ultimate64) build/basic/packed_messages.s
|
||||||
build/kernal_ultimate64/OUT.BIN: Ophis $(TOOLS_LIST) $(SRC_KERNAL_ultimate64)
|
build/kernal_ultimate64/OUT.BIN: $(TOOLS_LIST) $(SRC_KERNAL_ultimate64)
|
||||||
build/newrom_ultimate64: build/basic_ultimate64/OUT.BIN build/kernal_ultimate64/OUT.BIN
|
build/newrom_ultimate64: build/basic_ultimate64/OUT.BIN build/kernal_ultimate64/OUT.BIN
|
||||||
build/newkern_ultimate64: build/newrom_ultimate64 Makefile
|
build/newkern_ultimate64: build/newrom_ultimate64 Makefile
|
||||||
build/newbasic_ultimate64: build/newrom_ultimate64 Makefile
|
build/newbasic_ultimate64: build/newrom_ultimate64 Makefile
|
||||||
|
|
||||||
|
|
||||||
# Rules - BASIC and KERNAL
|
# Rules - BASIC and KERNAL
|
||||||
@@ -107,7 +102,7 @@ build/basic/packed_messages.s: $(TOOL_COMPRESS_TEXT)
|
|||||||
$(TOOL_COMPRESS_TEXT) > build/basic/packed_messages.s
|
$(TOOL_COMPRESS_TEXT) > build/basic/packed_messages.s
|
||||||
|
|
||||||
.PRECIOUS: build/basic_%/OUT.BIN
|
.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_$*
|
@mkdir -p build/basic_$*
|
||||||
@rm -f build/basic_$*/*
|
@rm -f build/basic_$*/*
|
||||||
@for SRC in $(SRC_BASIC_$*); do \
|
@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
|
$(TOOL_PREPROCESS) -d build/basic_$* -l a000 -h e4d2
|
||||||
|
|
||||||
.PRECIOUS: build/kernal_%/OUT.BIN
|
.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_$*
|
@mkdir -p build/kernal_$*
|
||||||
@rm -f build/kernal_$*/*
|
@rm -f build/kernal_$*/*
|
||||||
@for SRC in $(SRC_KERNAL_$*); do \
|
@for SRC in $(SRC_KERNAL_$*); do \
|
||||||
|
|||||||
-1
Submodule Ophis deleted from 15818e7666.
@@ -1,5 +1,6 @@
|
|||||||
# open-roms
|
# 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
|
# 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
|
Status of the various APIs and variables from the original ROMs
|
||||||
|
|
||||||
|
|
||||||
## Page 0
|
## Low memory locations (pages 0 - 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!
|
||||||
|
|
||||||
|
|
||||||
## Pages 2 & 3
|
|
||||||
|
|
||||||
|
|
||||||
TODO
|
|
||||||
|
|
||||||
|
|
||||||
## BASIC
|
## BASIC
|
||||||
@@ -107,7 +101,7 @@ NOTE: Even the 'DONE' routines won't support features described as missing in on
|
|||||||
| `$FFE7` | `CLALL` | DONE | |
|
| `$FFE7` | `CLALL` | DONE | |
|
||||||
| `$FFEA` | `UDTIM` | DONE | |
|
| `$FFEA` | `UDTIM` | DONE | |
|
||||||
| `$FFED` | `SCREEN` | DONE | |
|
| `$FFED` | `SCREEN` | DONE | |
|
||||||
| `$FFF0` | `PLOT` | DONE | |
|
| `$FFF0` | `PLOT` | PARTIAL | cursor blink not handled |
|
||||||
| `$FFF3` | `IOBASE` | DONE | |
|
| `$FFF3` | `IOBASE` | DONE | |
|
||||||
|
|
||||||
<br />
|
<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
|
// Kernal error codes - returned in the A register
|
||||||
;; Described in 'Commodore 64 Programmer's Reference Guide', page 306
|
// Described in 'Commodore 64 Programmer's Reference Guide', page 306
|
||||||
|
|
||||||
.alias K_ERR_ROUTINE_TERMINATED $00
|
.const K_ERR_ROUTINE_TERMINATED = $00
|
||||||
.alias K_ERR_TOO_MANY_OPEN_FILES $01
|
.const K_ERR_TOO_MANY_OPEN_FILES = $01
|
||||||
.alias K_ERR_FILE_ALREADY_OPEN $02
|
.const K_ERR_FILE_ALREADY_OPEN = $02
|
||||||
.alias K_ERR_FILE_NOT_OPEN $03
|
.const K_ERR_FILE_NOT_OPEN = $03
|
||||||
.alias K_ERR_FILE_NOT_FOUND $04
|
.const K_ERR_FILE_NOT_FOUND = $04
|
||||||
.alias K_ERR_DEVICE_NOT_FOUND $05
|
.const K_ERR_DEVICE_NOT_FOUND = $05
|
||||||
.alias K_ERR_FILE_NOT_INPUT $06
|
.const K_ERR_FILE_NOT_INPUT = $06
|
||||||
.alias K_ERR_FILE_NOT_OUTPUT $07
|
.const K_ERR_FILE_NOT_OUTPUT = $07
|
||||||
.alias K_ERR_FILE_NAME_MISSING $08
|
.const K_ERR_FILE_NAME_MISSING = $08
|
||||||
.alias K_ERR_ILLEGAL_DEVICE_NUMBER $09
|
.const K_ERR_ILLEGAL_DEVICE_NUMBER = $09
|
||||||
.alias K_ERR_TOP_MEM_RS232 $F0
|
.const K_ERR_TOP_MEM_RS232 = $F0
|
||||||
|
|
||||||
;; Kernal status codes for READST routine (IOSTATUS)
|
// Kernal status codes for READST routine (IOSTATUS)
|
||||||
;; Described in 'Commodore 64 Programmer's Reference Guide', page 292
|
// Described in 'Commodore 64 Programmer's Reference Guide', page 292
|
||||||
|
|
||||||
;; For IEC devices
|
// For IEC devices
|
||||||
.alias K_STS_TIMEOUT_WRITE $01
|
.const K_STS_TIMEOUT_WRITE = $01
|
||||||
.alias K_STS_TIMEOUT_READ $02
|
.const K_STS_TIMEOUT_READ = $02
|
||||||
.alias K_STS_EOI $40
|
.const K_STS_EOI = $40
|
||||||
.alias K_STS_DEVICE_NOT_FOUND $80
|
.const K_STS_DEVICE_NOT_FOUND = $80
|
||||||
;; For tape deck
|
// For tape deck
|
||||||
.alias K_STS_SHORT_BLOCK $04
|
.const K_STS_SHORT_BLOCK = $04
|
||||||
.alias K_STS_LONG_BLOCK $08
|
.const K_STS_LONG_BLOCK = $08
|
||||||
.alias K_STS_READ_ERROR $10
|
.const K_STS_READ_ERROR = $10
|
||||||
.alias K_STS_CHECKSUM_ERROR $20
|
.const K_STS_CHECKSUM_ERROR = $20
|
||||||
.alias K_STS_END_OF_FILE $40
|
.const K_STS_END_OF_FILE = $40
|
||||||
.alias K_STS_END_OF_TAPE $80
|
.const K_STS_END_OF_TAPE = $80
|
||||||
|
|
||||||
;; BASIC error codes, taken from http://sta.c64.org/cbm64baserr.html
|
// BASIC error codes, taken from http://sta.c64.org/cbm64baserr.html
|
||||||
.alias B_ERR_TOO_MANY_FILES $01
|
.const B_ERR_TOO_MANY_FILES = $01
|
||||||
.alias B_ERR_FILE_OPEN $02
|
.const B_ERR_FILE_OPEN = $02
|
||||||
.alias B_ERR_FILE_NOT_OPEN $03
|
.const B_ERR_FILE_NOT_OPEN = $03
|
||||||
.alias B_ERR_FILE_NOT_FOUND $04
|
.const B_ERR_FILE_NOT_FOUND = $04
|
||||||
.alias B_ERR_DEVICE_NOT_PRESENT $05
|
.const B_ERR_DEVICE_NOT_PRESENT = $05
|
||||||
.alias B_ERR_NOT_INPUT_FILE $06
|
.const B_ERR_NOT_INPUT_FILE = $06
|
||||||
.alias B_ERR_NOT_OUTPUT_FILE $07
|
.const B_ERR_NOT_OUTPUT_FILE = $07
|
||||||
.alias B_ERR_MISSING_FILENAME $08
|
.const B_ERR_MISSING_FILENAME = $08
|
||||||
.alias B_ERR_ILLEGAL_DEVICE_NUMBER $09
|
.const B_ERR_ILLEGAL_DEVICE_NUMBER = $09
|
||||||
.alias B_ERR_NEXT_WITHOUT_FOR $0A
|
.const B_ERR_NEXT_WITHOUT_FOR = $0A
|
||||||
.alias B_ERR_SYNTAX $0B
|
.const B_ERR_SYNTAX = $0B
|
||||||
.alias B_ERR_RETURN_WITHOUT_GOSUB $0C
|
.const B_ERR_RETURN_WITHOUT_GOSUB = $0C
|
||||||
.alias B_ERR_OUT_OF_DATA $0D
|
.const B_ERR_OUT_OF_DATA = $0D
|
||||||
.alias B_ERR_ILLEGAL_QUANTITY $0E
|
.const B_ERR_ILLEGAL_QUANTITY = $0E
|
||||||
.alias B_ERR_OVERFLOW $0F
|
.const B_ERR_OVERFLOW = $0F
|
||||||
.alias B_ERR_OUT_OF_MEMORY $10
|
.const B_ERR_OUT_OF_MEMORY = $10
|
||||||
.alias B_ERR_UNDEFD_STATEMENT $11
|
.const B_ERR_UNDEFD_STATEMENT = $11
|
||||||
.alias B_ERR_BAD_SUBSCRIPT $12
|
.const B_ERR_BAD_SUBSCRIPT = $12
|
||||||
.alias B_ERR_REDIMD_ARRAY $13
|
.const B_ERR_REDIMD_ARRAY = $13
|
||||||
.alias B_ERR_DIVISION_BY_ZERO $14
|
.const B_ERR_DIVISION_BY_ZERO = $14
|
||||||
.alias B_ERR_ILLEGAL_DIRECT $15
|
.const B_ERR_ILLEGAL_DIRECT = $15
|
||||||
.alias B_ERR_TYPE_MISMATCH $16
|
.const B_ERR_TYPE_MISMATCH = $16
|
||||||
.alias B_ERR_STRING_TOO_LONG $17
|
.const B_ERR_STRING_TOO_LONG = $17
|
||||||
.alias B_ERR_FILE_DATA $18
|
.const B_ERR_FILE_DATA = $18
|
||||||
.alias B_ERR_FORMULA_TOO_COMPLEX $19
|
.const B_ERR_FORMULA_TOO_COMPLEX = $19
|
||||||
.alias B_ERR_CANT_CONTINUE $1A
|
.const B_ERR_CANT_CONTINUE = $1A
|
||||||
.alias B_ERR_UNDEFD_FUNCTION $1B
|
.const B_ERR_UNDEFD_FUNCTION = $1B
|
||||||
.alias B_ERR_VERIFY $1C
|
.const B_ERR_VERIFY = $1C
|
||||||
.alias B_ERR_LOAD $1D
|
.const B_ERR_LOAD = $1D
|
||||||
.alias B_ERR_BREAK $1E
|
.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
|
.label CPU_D6510 = $00
|
||||||
.alias CPU_R6510 $01
|
.label CPU_R6510 = $01
|
||||||
|
|
||||||
;; VIC-II registers
|
// VIC-II registers
|
||||||
|
|
||||||
.alias VIC_SP0X $D000
|
.label VIC_SP0X = $D000
|
||||||
.alias VIC_SP0Y $D001
|
.label VIC_SP0Y = $D001
|
||||||
.alias VIC_SP1X $D002
|
.label VIC_SP1X = $D002
|
||||||
.alias VIC_SP1Y $D003
|
.label VIC_SP1Y = $D003
|
||||||
.alias VIC_SP2X $D004
|
.label VIC_SP2X = $D004
|
||||||
.alias VIC_SP2Y $D005
|
.label VIC_SP2Y = $D005
|
||||||
.alias VIC_SP3X $D006
|
.label VIC_SP3X = $D006
|
||||||
.alias VIC_SP3Y $D007
|
.label VIC_SP3Y = $D007
|
||||||
.alias VIC_SP4X $D008
|
.label VIC_SP4X = $D008
|
||||||
.alias VIC_SP4Y $D009
|
.label VIC_SP4Y = $D009
|
||||||
.alias VIC_SP5X $D00A
|
.label VIC_SP5X = $D00A
|
||||||
.alias VIC_SP5Y $D00B
|
.label VIC_SP5Y = $D00B
|
||||||
.alias VIC_SP6X $D00C
|
.label VIC_SP6X = $D00C
|
||||||
.alias VIC_SP6Y $D00D
|
.label VIC_SP6Y = $D00D
|
||||||
.alias VIC_SP7X $D00E
|
.label VIC_SP7X = $D00E
|
||||||
.alias VIC_SP7Y $D00F
|
.label VIC_SP7Y = $D00F
|
||||||
|
|
||||||
.alias VIC_MSIGX $D010
|
.label VIC_MSIGX = $D010
|
||||||
.alias VIC_SCROLY $D011
|
.label VIC_SCROLY = $D011
|
||||||
.alias VIC_RASTER $D012
|
.label VIC_RASTER = $D012
|
||||||
.alias VIC_LPENX $D013
|
.label VIC_LPENX = $D013
|
||||||
.alias VIC_LPENY $D014
|
.label VIC_LPENY = $D014
|
||||||
.alias VIC_SPENA $D015
|
.label VIC_SPENA = $D015
|
||||||
.alias VIC_SCROLX $D016
|
.label VIC_SCROLX = $D016
|
||||||
.alias VIC_YXPAND $D017
|
.label VIC_YXPAND = $D017
|
||||||
.alias VIC_YMCSB $D018
|
.label VIC_YMCSB = $D018
|
||||||
.alias VIC_IRQ $D019
|
.label VIC_IRQ = $D019
|
||||||
.alias VIC_IRQMSK $D01A
|
.label VIC_IRQMSK = $D01A
|
||||||
.alias VIC_SPBGPR $D01B
|
.label VIC_SPBGPR = $D01B
|
||||||
.alias VIC_SPMC $D01C
|
.label VIC_SPMC = $D01C
|
||||||
.alias VIC_XXPAND $D01D
|
.label VIC_XXPAND = $D01D
|
||||||
.alias VIC_SPSPCL $D01E
|
.label VIC_SPSPCL = $D01E
|
||||||
.alias VIC_SPBGCL $D01F
|
.label VIC_SPBGCL = $D01F
|
||||||
|
|
||||||
.alias VIC_EXTCOL $D020
|
.label VIC_EXTCOL = $D020
|
||||||
.alias VIC_BGCOL0 $D021
|
.label VIC_BGCOL0 = $D021
|
||||||
.alias VIC_BGCOL1 $D022
|
.label VIC_BGCOL1 = $D022
|
||||||
.alias VIC_BGCOL2 $D023
|
.label VIC_BGCOL2 = $D023
|
||||||
.alias VIC_BGCOL3 $D024
|
.label VIC_BGCOL3 = $D024
|
||||||
.alias VIC_SPMC0 $D025
|
.label VIC_SPMC0 = $D025
|
||||||
.alias VIC_SPMC1 $D026
|
.label VIC_SPMC1 = $D026
|
||||||
.alias VIC_SP0COL $D027
|
.label VIC_SP0COL = $D027
|
||||||
.alias VIC_SP1COL $D028
|
.label VIC_SP1COL = $D028
|
||||||
.alias VIC_SP2COL $D029
|
.label VIC_SP2COL = $D029
|
||||||
.alias VIC_SP3COL $D02A
|
.label VIC_SP3COL = $D02A
|
||||||
.alias VIC_SP4COL $D02B
|
.label VIC_SP4COL = $D02B
|
||||||
.alias VIC_SP5COL $D02C
|
.label VIC_SP5COL = $D02C
|
||||||
.alias VIC_SP6COL $D02D
|
.label VIC_SP6COL = $D02D
|
||||||
.alias VIC_SP7COL $D02E
|
.label VIC_SP7COL = $D02E
|
||||||
|
|
||||||
;; SID registers
|
// SID registers
|
||||||
|
|
||||||
.alias SID_FRELO1 $D400
|
.label SID_FRELO1 = $D400
|
||||||
.alias SID_FREHI1 $D401
|
.label SID_FREHI1 = $D401
|
||||||
.alias SID_PWLO1 $D402
|
.label SID_PWLO1 = $D402
|
||||||
.alias SID_PWHI1 $D403
|
.label SID_PWHI1 = $D403
|
||||||
.alias SID_VCREG1 $D404
|
.label SID_VCREG1 = $D404
|
||||||
.alias SID_ATDCY1 $D405
|
.label SID_ATDCY1 = $D405
|
||||||
.alias SID_SUREL1 $D406
|
.label SID_SUREL1 = $D406
|
||||||
|
|
||||||
.alias SID_FRELO2 $D407
|
.label SID_FRELO2 = $D407
|
||||||
.alias SID_FREHI2 $D408
|
.label SID_FREHI2 = $D408
|
||||||
.alias SID_PWLO2 $D409
|
.label SID_PWLO2 = $D409
|
||||||
.alias SID_PWHI2 $D40A
|
.label SID_PWHI2 = $D40A
|
||||||
.alias SID_VCREG2 $D40B
|
.label SID_VCREG2 = $D40B
|
||||||
.alias SID_ATDCY2 $D40C
|
.label SID_ATDCY2 = $D40C
|
||||||
.alias SID_SUREL2 $D40D
|
.label SID_SUREL2 = $D40D
|
||||||
|
|
||||||
.alias SID_FRELO3 $D40E
|
.label SID_FRELO3 = $D40E
|
||||||
.alias SID_FREHI3 $D40F
|
.label SID_FREHI3 = $D40F
|
||||||
.alias SID_PWLO3 $D410
|
.label SID_PWLO3 = $D410
|
||||||
.alias SID_PWHI3 $D411
|
.label SID_PWHI3 = $D411
|
||||||
.alias SID_VCREG3 $D412
|
.label SID_VCREG3 = $D412
|
||||||
.alias SID_ATDCY3 $D413
|
.label SID_ATDCY3 = $D413
|
||||||
.alias SID_SUREL3 $D414
|
.label SID_SUREL3 = $D414
|
||||||
|
|
||||||
.alias SID_CUTLO $D415
|
.label SID_CUTLO = $D415
|
||||||
.alias SID_CUTHI $D416
|
.label SID_CUTHI = $D416
|
||||||
.alias SID_RESON $D417
|
.label SID_RESON = $D417
|
||||||
.alias SID_SIGVOL $D418
|
.label SID_SIGVOL = $D418
|
||||||
.alias SID_POTX $D419
|
.label SID_POTX = $D419
|
||||||
.alias SID_POTY $D41A
|
.label SID_POTY = $D41A
|
||||||
.alias SID_RANDOM $D41B
|
.label SID_RANDOM = $D41B
|
||||||
.alias SID_ENV3 $D41C
|
.label SID_ENV3 = $D41C
|
||||||
|
|
||||||
;; CIA #1 registers
|
// CIA #1 registers
|
||||||
|
|
||||||
.alias CIA1_PRA $DC00
|
.label CIA1_PRA = $DC00
|
||||||
.alias CIA1_PRB $DC01
|
.label CIA1_PRB = $DC01
|
||||||
.alias CIA1_DDRA $DC02
|
.label CIA1_DDRA = $DC02
|
||||||
.alias CIA1_DDRB $DC03
|
.label CIA1_DDRB = $DC03
|
||||||
|
|
||||||
.alias CIA1_TIMALO $DC04
|
.label CIA1_TIMALO = $DC04
|
||||||
.alias CIA1_TIMAHI $DC05
|
.label CIA1_TIMAHI = $DC05
|
||||||
.alias CIA1_TIMBLO $DC06
|
.label CIA1_TIMBLO = $DC06
|
||||||
.alias CIA1_TIMBHI $DC07
|
.label CIA1_TIMBHI = $DC07
|
||||||
|
|
||||||
.alias CIA1_TODTEN $DC08
|
.label CIA1_TODTEN = $DC08
|
||||||
.alias CIA1_TODSEC $DC09
|
.label CIA1_TODSEC = $DC09
|
||||||
.alias CIA1_TODMIN $DC0A
|
.label CIA1_TODMIN = $DC0A
|
||||||
.alias CIA1_TODHRS $DC0B
|
.label CIA1_TODHRS = $DC0B
|
||||||
|
|
||||||
.alias CIA1_SDR $DC0C
|
.label CIA1_SDR = $DC0C
|
||||||
.alias CIA1_ICR $DC0D
|
.label CIA1_ICR = $DC0D
|
||||||
.alias CIA1_CRA $DC0E
|
.label CIA1_CRA = $DC0E
|
||||||
.alias CIA1_CRB $DC0F
|
.label CIA1_CRB = $DC0F
|
||||||
|
|
||||||
;; CIA #2 registers
|
// CIA #2 registers
|
||||||
|
|
||||||
.alias CIA2_PRA $DD00 ; VIC bank switching and IEC port
|
.label CIA2_PRA = $DD00 // VIC bank switching and IEC port
|
||||||
.alias CIA2_PRB $DD01
|
.label CIA2_PRB = $DD01
|
||||||
.alias CIA2_DDRA $DD02
|
.label CIA2_DDRA = $DD02
|
||||||
.alias CIA2_DDRB $DD03
|
.label CIA2_DDRB = $DD03
|
||||||
|
|
||||||
.alias CIA2_TIMALO $DD04
|
.label CIA2_TIMALO = $DD04
|
||||||
.alias CIA2_TIMAHI $DD05
|
.label CIA2_TIMAHI = $DD05
|
||||||
.alias CIA2_TIMBLO $DD06
|
.label CIA2_TIMBLO = $DD06
|
||||||
.alias CIA2_TIMBHI $DD07
|
.label CIA2_TIMBHI = $DD07
|
||||||
|
|
||||||
.alias CIA2_TODTEN $DD08
|
.label CIA2_TODTEN = $DD08
|
||||||
.alias CIA2_TODSEC $DD09
|
.label CIA2_TODSEC = $DD09
|
||||||
.alias CIA2_TODMIN $DD0A
|
.label CIA2_TODMIN = $DD0A
|
||||||
.alias CIA2_TODHRS $DD0B
|
.label CIA2_TODHRS = $DD0B
|
||||||
|
|
||||||
.alias CIA2_SDR $DD0C
|
.label CIA2_SDR = $DD0C
|
||||||
.alias CIA2_ICR $DD0D
|
.label CIA2_ICR = $DD0D
|
||||||
.alias CIA2_CRA $DD0E
|
.label CIA2_CRA = $DD0E
|
||||||
.alias CIA2_CRB $DD0F
|
.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)
|
.const 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)
|
.const 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)
|
.const 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)
|
.const 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_DAT_IN = $80 // 0 - low (pulled), 1 - high (released)
|
||||||
@@ -1,98 +1,236 @@
|
|||||||
;;
|
//
|
||||||
;; Names of ZP and low memory locations
|
// Names of ZP and low memory locations:
|
||||||
;; (https://www.c64-wiki.com/wiki/Zeropage)
|
// - 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)
|
||||||
;;
|
//
|
||||||
|
|
||||||
.alias TXTTAB $2B
|
// $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)
|
// Page 0 - Kernal area ($90-$FF)
|
||||||
;;
|
//
|
||||||
|
|
||||||
.alias IOSTATUS $90
|
.label IOSTATUS = $90
|
||||||
.alias STKEY $91 ; Keys down clears bits. STOP - bit 7, C= - bit 6, SPACE - bit 4, CTRL - bit 2
|
.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 --
|
||||||
|
|
||||||
.alias VERCK $93 ; 0 = LOAD, 1 = VERIVY
|
//
|
||||||
|
// Page 1
|
||||||
|
//
|
||||||
|
|
||||||
.alias C3PO $94 ; flag - is BSOUR content valid
|
.label STACK = $100 // $100-$1FF, processor stack
|
||||||
.alias BSOUR $95 ; serial bus buffered output byte
|
|
||||||
|
|
||||||
.alias LDTND $98 ; number of entries in LAT / FAT / SAT tables
|
//
|
||||||
.alias DFLTN $99
|
// Pages 2 & 3
|
||||||
.alias DFLTO $9A
|
//
|
||||||
|
|
||||||
.alias MSGFLG $9D ; bit 6 = error messages, bit 7 = control message
|
.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
|
||||||
|
|
||||||
.alias TIME $A0 ; $A0-$A2, jiffy clock
|
// 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 --
|
||||||
|
|
||||||
.alias IEC_TMP1 $A3 ; temporary variable for tape and IEC
|
.label SAREG = $30C // .A storage, for SYS call
|
||||||
.alias IEC_TMP2 $A4 ; temporary variable for tape and IEC
|
.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 CMP0 $B0 ; $B0-$B1, temporary tape storage, we use it too for BRK instruction address
|
.label USRPOK = $310 // -- NOT IMPLEMENTED -- JMP instruction
|
||||||
|
.label USRADD = $311 // $311-$312 -- NOT IMPLEMENTED --
|
||||||
|
// $313 -- UNUSED -- free for user software
|
||||||
|
|
||||||
.alias FNLEN $B7 ; current file name length
|
// Kernal vectors - interrupts
|
||||||
|
.label CINV = $314 // $314-$315
|
||||||
|
.label CBINV = $316 // $316-$317
|
||||||
|
.label NMINV = $318 // $318-$319
|
||||||
|
|
||||||
.alias FNADDR $BB ; $BB-$BC, current file name pointer
|
// 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 STAL $C1 ; $C1-$C2 LOAD/SAVE start address
|
// $314 $334-$33B -- UNUSED -- free for user software
|
||||||
.alias MEMUS $C3 ; $C3-$C4 temporary address for tape LOAD/SAVE
|
|
||||||
|
|
||||||
;;
|
.label TBUFFR = $33C // $33C-$3FB, -- NOT IMPLEMENTED --, tape buffer
|
||||||
;; Other low memory addresses
|
|
||||||
;;
|
|
||||||
|
|
||||||
.alias BUF $200 ; $200-$250 (81 bytes), BASIC line editor input buffer
|
// $3FC $3FC-$3FF -- UNUSED -- free for user software
|
||||||
|
|
||||||
;; 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
|
|
||||||
|
|
||||||
|
|
||||||
;; Registers for SYS call
|
|
||||||
.alias SAREG $30C
|
|
||||||
.alias SXREG $30D
|
|
||||||
.alias SYREG $30E
|
|
||||||
.alias SPREG $30F
|
|
||||||
|
|
||||||
.alias USRPOK $310 ; JMP instruction
|
|
||||||
.alias USRADD $311 ; $311 - $312
|
|
||||||
|
|
||||||
;; Kernal vectors - interrupts
|
|
||||||
.alias CINV $314
|
|
||||||
.alias CBINV $316
|
|
||||||
.alias NMINV $318
|
|
||||||
|
|
||||||
;; Kernal vectors - routines
|
|
||||||
.alias IOPEN $31A
|
|
||||||
.alias ICLOSE $31C
|
|
||||||
.alias ICHKIN $31E
|
|
||||||
.alias ICKOUT $320
|
|
||||||
.alias ICLRCH $322
|
|
||||||
.alias IBASIN $324
|
|
||||||
.alias IBSOUT $326
|
|
||||||
.alias ISTOP $328
|
|
||||||
.alias IGETIN $32A
|
|
||||||
.alias ICLALL $32C
|
|
||||||
.alias USRCMD $32E
|
|
||||||
.alias ILOAD $330
|
|
||||||
.alias ISAVE $331
|
|
||||||
|
|
||||||
.alias TBUFFR $33C ; $33C-$3FB, tape buffer
|
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
|
|
||||||
;; BASIC startup vector
|
// BASIC startup vectors
|
||||||
|
.label IBASIC_COLD_START = $A000
|
||||||
.alias IBASIC_COLD_START $A000
|
.label IBASIC_WARM_START = $A002
|
||||||
.alias IBASIC_WARM_START $A002
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
;; Cartridge ROM locations
|
// Cartridge ROM locations
|
||||||
.alias ICART_COLD_START $8000 ; $8000-$8001, cartridge cold start vector
|
.label ICART_COLD_START = $8000 // $8000-$8001, cartridge cold start vector
|
||||||
.alias ICART_WARM_START $8002 ; $8002-$8003, cartridge warm start vector (RESTORE key)
|
.label ICART_WARM_START = $8002 // $8002-$8003, cartridge warm start vector (RESTORE key)
|
||||||
.alias CART_SIG $8004 ; 5 bytes, signature for cartridge detection
|
.label CART_SIG = $8004 // $8004-$8008, signature for cartridge detection
|
||||||
@@ -1,41 +1,41 @@
|
|||||||
|
|
||||||
;; Kernal jump table
|
// Kernal jump table
|
||||||
.alias JCINT $FF81
|
.label JCINT = $FF81
|
||||||
.alias JIOINIT $FF84
|
.label JIOINIT = $FF84
|
||||||
.alias JRAMTAS $FF87
|
.label JRAMTAS = $FF87
|
||||||
.alias JRESTOR $FF8A
|
.label JRESTOR = $FF8A
|
||||||
.alias JVECTOR $FF8D
|
.label JVECTOR = $FF8D
|
||||||
.alias JSETMSG $FF90
|
.label JSETMSG = $FF90
|
||||||
.alias JSECOND $FF93
|
.label JSECOND = $FF93
|
||||||
.alias JTKSA $FF96
|
.label JTKSA = $FF96
|
||||||
.alias JMEMTOP $FF99
|
.label JMEMTOP = $FF99
|
||||||
.alias JMEMBOT $FF9C
|
.label JMEMBOT = $FF9C
|
||||||
.alias JSCNKEY $FF9F
|
.label JSCNKEY = $FF9F
|
||||||
.alias JSETTMO $FFA2
|
.label JSETTMO = $FFA2
|
||||||
.alias JACPTR $FFA5
|
.label JACPTR = $FFA5
|
||||||
.alias JCIOUT $FFA8
|
.label JCIOUT = $FFA8
|
||||||
.alias JUNTLK $FFAB
|
.label JUNTLK = $FFAB
|
||||||
.alias JUNLSN $FFAE
|
.label JUNLSN = $FFAE
|
||||||
.alias JLISTEN $FFB1
|
.label JLISTEN = $FFB1
|
||||||
.alias JTALK $FFB4
|
.label JTALK = $FFB4
|
||||||
.alias JREADST $FFB7
|
.label JREADST = $FFB7
|
||||||
.alias JSETFLS $FFBA
|
.label JSETFLS = $FFBA
|
||||||
.alias JSETNAM $FFBD
|
.label JSETNAM = $FFBD
|
||||||
.alias JOPEN $FFC0
|
.label JOPEN = $FFC0
|
||||||
.alias JCLOSE $FFC3
|
.label JCLOSE = $FFC3
|
||||||
.alias JCHKIN $FFC6
|
.label JCHKIN = $FFC6
|
||||||
.alias JCKOUT $FFC9
|
.label JCKOUT = $FFC9
|
||||||
.alias JCLRCHN $FFCC
|
.label JCLRCHN = $FFCC
|
||||||
.alias JCHRIN $FFCF
|
.label JCHRIN = $FFCF
|
||||||
.alias JCHROUT $FFD2
|
.label JCHROUT = $FFD2
|
||||||
.alias JLOAD $FFD5
|
.label JLOAD = $FFD5
|
||||||
.alias JSAVE $FFD8
|
.label JSAVE = $FFD8
|
||||||
.alias JSETTIM $FFDB
|
.label JSETTIM = $FFDB
|
||||||
.alias JRDTIM $FFDE
|
.label JRDTIM = $FFDE
|
||||||
.alias JSTOP $FFE1
|
.label JSTOP = $FFE1
|
||||||
.alias JGETIN $FFE4
|
.label JGETIN = $FFE4
|
||||||
.alias JCLALL $FFE7
|
.label JCLALL = $FFE7
|
||||||
.alias JUDTIM $FFEA
|
.label JUDTIM = $FFEA
|
||||||
.alias JSCREEN $FFED
|
.label JSCREEN = $FFED
|
||||||
.alias JPLOT $FFF0
|
.label JPLOT = $FFF0
|
||||||
.alias JIOBASE $FFF3
|
.label JIOBASE = $FFF3
|
||||||
+115
-113
@@ -1,126 +1,128 @@
|
|||||||
; Names of ZP and low memory locations
|
// Names of ZP and low memory locations
|
||||||
; (Only those for now that we feel the need to implement initially)
|
// (Only those for now that we feel the need to implement initially)
|
||||||
; (https://www.c64-wiki.com/wiki/Zeropage)
|
// (https://www.c64-wiki.com/wiki/Zeropage)
|
||||||
|
|
||||||
.alias tokenise_work1 $7
|
// XXX get rid of this file, use ,aliases_ram_lowmem.s instead
|
||||||
.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
|
|
||||||
|
|
||||||
;; The various pointers that separate memory regions for BASIC storage
|
.label tokenise_work1 = $7
|
||||||
;; We have multiple names for the ones that mark the boundary of regions.
|
.label tokenise_work2 = $8
|
||||||
.alias basic_start_of_text_ptr $2b
|
.label tokenise_work3 = $B
|
||||||
.alias basic_end_of_text_ptr $2d
|
.label tokenise_work4 = $F
|
||||||
.alias basic_start_of_vars_ptr $2d
|
.label basic_line_number = $14
|
||||||
.alias basic_end_of_vars_ptr $2f
|
.label temp_string_ptr = $35
|
||||||
.alias basic_start_of_arrays_ptr $2f
|
.label load_or_verify_or_tokenise_work5 = $C
|
||||||
.alias basic_end_of_arrays_ptr $31
|
.label basic_work22 = $22
|
||||||
.alias basic_start_of_free_space_ptr $31
|
.label basic_work23 = $23
|
||||||
.alias basic_start_of_strings_ptr $33
|
.label basic_work24 = $24
|
||||||
.alias basic_top_of_memory_ptr $37
|
.label basic_work25 = $25
|
||||||
.alias basic_current_line_number $39
|
|
||||||
.alias basic_previous_line_number $3b
|
|
||||||
.alias basic_current_line_ptr $3d
|
|
||||||
|
|
||||||
;; Note that the statement point is in the CHRGET/CHRGOT routine
|
// The various pointers that separate memory regions for BASIC storage
|
||||||
;; in ZP RAM. (Compute's Mapping the 64, p25)
|
// We have multiple names for the ones that mark the boundary of regions.
|
||||||
.alias basic_current_statement_ptr $7a
|
.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
|
||||||
|
|
||||||
.alias basic_numeric_work_area $57 ; $57 - $60 inclusive = 10 bytes
|
// 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
|
||||||
|
|
||||||
;; Floating point accumulator 1 $61 - $68
|
.label basic_numeric_work_area = $57 // $57 - $60 inclusive = 10 bytes
|
||||||
.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
|
|
||||||
|
|
||||||
.alias basic_fac2_exponent $69
|
// Floating point accumulator 1 $61 - $68
|
||||||
.alias basic_fac2_mantissa $6A ; $6A - $6D
|
.label basic_fac1_exponent = $61
|
||||||
.alias basic_fac2_sign $6E
|
.label basic_fac1_mantissa = $62 // $62 - $65
|
||||||
|
.label basic_fac1_sign = $66
|
||||||
|
.label basic_fac1_overflow = $68
|
||||||
|
.label basic_fac1_mantissa_lob = $70
|
||||||
|
|
||||||
;; We also re-use FAC2 for memory move pointers, since
|
.label basic_fac2_exponent = $69
|
||||||
;; we can't be doing calculations while moving memory
|
.label basic_fac2_mantissa = $6A // $6A - $6D
|
||||||
.alias memmove_src $69
|
.label basic_fac2_sign = $6E
|
||||||
.alias memmove_dst $6b
|
|
||||||
.alias memmove_size $6d
|
|
||||||
|
|
||||||
.alias current_file_num $98
|
// We also re-use FAC2 for memory move pointers, since
|
||||||
.alias cassette_buffer_bytes_used $A6
|
// we can't be doing calculations while moving memory
|
||||||
.alias load_or_scroll_temp_pointer $AC
|
.label memmove_src = $69
|
||||||
;; We also use the following for temp colour pointer when scrolling
|
.label memmove_dst = $6b
|
||||||
.alias load_save_verify_end_address $AE
|
.label memmove_size = $6d
|
||||||
|
|
||||||
.alias cassette_buffer_ptr $B2
|
.label current_file_num = $98
|
||||||
.alias current_logical_filenum $B8
|
.label cassette_buffer_bytes_used = $A6
|
||||||
.alias current_secondary_address $B9
|
.label load_or_scroll_temp_pointer = $AC
|
||||||
.alias current_device_number $BA
|
// We also use the following for temp colour pointer when scrolling
|
||||||
.alias current_filename_ptr $BB
|
.label load_save_verify_end_address = $AE
|
||||||
.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
|
|
||||||
|
|
||||||
.alias basic_input_buffer BUF
|
.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
|
||||||
|
|
||||||
; "Compute's Mapping the 64" book
|
.label basic_input_buffer = BUF
|
||||||
.alias keyboard_buffer $0277
|
|
||||||
.alias text_colour $0286 ; p55
|
|
||||||
.alias colour_under_cursor $0287 ; p56
|
|
||||||
.alias key_buffer_size $0289 ; p57
|
|
||||||
|
|
||||||
;; 0 = cursor keys, insert, delete and space repeat, but nothing else
|
// "Compute's Mapping the 64" book
|
||||||
;; 128 = all keys repeat
|
.label keyboard_buffer = $0277
|
||||||
;; 64 = no keys repeat
|
.label text_colour = $0286 // p55
|
||||||
.alias key_repeat_flags $028A ; p58
|
.label colour_under_cursor = $0287 // p56
|
||||||
;; https://www.c64-wiki.com/wiki/Page_2
|
.label key_buffer_size = $0289 // p57
|
||||||
.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
|
|
||||||
|
|
||||||
;; BASIC uses some extra bytes for memory access under ROMs located at $2A7 onwards
|
// 0 = cursor keys, insert, delete and space repeat, but nothing else
|
||||||
;; IRQs are disabled when doing such accesses, and a default NMI handler only increments
|
// 128 = all keys repeat
|
||||||
;; a counter, so that if an NMI occurs, it doesn't crash the machine, but can be captured.
|
// 64 = no keys repeat
|
||||||
.alias missed_nmi_flag $2A7
|
.label key_repeat_flags = $028A // p58
|
||||||
.alias tiny_nmi_handler $2A8
|
// https://www.c64-wiki.com/wiki/Page_2
|
||||||
.alias shift_mem_up tiny_nmi_handler+shift_mem_up_routine-tiny_nmi_handler_routine
|
.label key_repeat_counter = $028B
|
||||||
.alias shift_mem_down tiny_nmi_handler+shift_mem_down_routine-tiny_nmi_handler_routine
|
.label key_first_repeat_delay = $028C
|
||||||
.alias peek_under_roms tiny_nmi_handler+peek_under_roms_routine-tiny_nmi_handler_routine
|
// bit 0 = shift, 1 = Vendor Key, 2 = Control
|
||||||
.alias poke_under_roms tiny_nmi_handler+poke_under_roms_routine-tiny_nmi_handler_routine
|
.label key_bucky_state = $028D
|
||||||
.alias memmap_allram tiny_nmi_handler+memmap_allram_routine-tiny_nmi_handler_routine
|
.label key_last_bucky_state = $028E
|
||||||
.alias memmap_normal tiny_nmi_handler+memmap_normal_routine-tiny_nmi_handler_routine
|
.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 $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, $1f, $20, $9a, $a9, $20, $20, $20, $92, $a1, $1f, $12, $20, $9a, $a9, $20
|
||||||
.byte $20, $20, $7f, $1f, $20, $20, $9a, $a3, $a3, $a3, $a3, $a3, $a3, $a3, $1f, $20
|
.byte $20, $20, $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 $20, $20, $1f, $20, $20, $96, $a3, $a3, $a3, $a3, $1f
|
||||||
.byte $92, $0D, $0D, $05, $00
|
.byte $92, $0D, $0D, $05, $00
|
||||||
|
|
||||||
;; Original Deft-supplied banner
|
// Original Deft-supplied banner
|
||||||
;; .byte $9A,$12,$A3,$A3,$A3,$A3,$A3,$A3,$DF,$9B,$92,$20,$05,$12,$A0,$A0
|
// .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,$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 $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 $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 $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 $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 $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 $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,$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 $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 $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 $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,$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 $12,$DF,$92,$7F,$9B,$20,$9A,$20,$9B,"0.2.0.0",$0D
|
||||||
;; .byte $0D,$05,$92,$00
|
// .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
|
.word basic_cold_start
|
||||||
|
|
||||||
@@ -1,2 +1,3 @@
|
|||||||
;; Compute's Mapping the C64 p88
|
// Compute's Mapping the C64 p88
|
||||||
|
|
||||||
.word basic_warm_start
|
.word basic_warm_start
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
;; Compute's Mapping the 64, p89
|
// Compute's Mapping the 64, p89
|
||||||
;; 8 character name
|
// 8 character name
|
||||||
;; MEGABAS2 = "MEGA BASIC 2"
|
// MEGABAS2 = "MEGA BASIC 2"
|
||||||
|
|
||||||
.byte $4D,$45,$47,$41,$42,$41,$53,$32
|
.byte $4D,$45,$47,$41,$42,$41,$53,$32
|
||||||
|
|
||||||
|
|
||||||
@@ -1,19 +1,19 @@
|
|||||||
;; Print string at $YYAA
|
// Print string at $YYAA
|
||||||
;; Compute's Mapping the 64 p101
|
// Compute's Mapping the 64 p101
|
||||||
|
|
||||||
print_string:
|
print_string:
|
||||||
;; Setup pointer
|
// Setup pointer
|
||||||
sty temp_string_ptr+1
|
sty temp_string_ptr+1
|
||||||
sta temp_string_ptr+0
|
sta temp_string_ptr+0
|
||||||
|
|
||||||
txa
|
txa
|
||||||
pha
|
pha
|
||||||
|
|
||||||
;; Get offset ready
|
// Get offset ready
|
||||||
ldy #$00
|
ldy #$00
|
||||||
|
|
||||||
print_string_loop:
|
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
|
tya
|
||||||
tax
|
tax
|
||||||
|
|
||||||
@@ -28,7 +28,6 @@ print_string_loop:
|
|||||||
iny
|
iny
|
||||||
bne print_string_loop
|
bne print_string_loop
|
||||||
|
|
||||||
|
|
||||||
print_string_end:
|
print_string_end:
|
||||||
|
|
||||||
pla
|
pla
|
||||||
|
|||||||
@@ -1,31 +1,31 @@
|
|||||||
;; BASIC Cold start entry point
|
// BASIC Cold start entry point
|
||||||
;; Compute's Mapping the 64 p211
|
// Compute's Mapping the 64 p211
|
||||||
|
|
||||||
basic_cold_start:
|
basic_cold_start:
|
||||||
;; Setup BASIC vectors at $0300
|
// Setup BASIC vectors at $0300
|
||||||
;; Initialise interpretor
|
// Initialise interpretor
|
||||||
;; Print start up message
|
// Print start up message
|
||||||
|
|
||||||
;; Print coloured part of the message
|
// Print coloured part of the message
|
||||||
;; ldy #>startup_message
|
// ldy #>startup_message
|
||||||
;; lda #<startup_message
|
// lda #<startup_message
|
||||||
;; jsr print_string
|
// jsr print_string
|
||||||
|
|
||||||
|
jsr printf // XXX don't use printf, keep it for debug purposes only
|
||||||
|
|
||||||
jsr printf
|
|
||||||
; Used 217 bytes
|
|
||||||
startup_banner:
|
startup_banner:
|
||||||
|
|
||||||
`TARGET_HOOK_BANNER
|
TARGET_HOOK_BANNER()
|
||||||
|
|
||||||
;; Print PAL/NTSC
|
// Print PAL/NTSC
|
||||||
ldx #30 ; NTSC
|
ldx #30 // NTSC
|
||||||
lda PALNTSC
|
lda PALNTSC
|
||||||
beq +
|
beq !+
|
||||||
ldx #31 ; PAL
|
ldx #31 // PAL
|
||||||
*
|
!:
|
||||||
jsr print_packed_message
|
jsr print_packed_message
|
||||||
|
|
||||||
;; Work out free bytes, and display
|
// Work out free bytes, and display
|
||||||
jsr basic_do_new
|
jsr basic_do_new
|
||||||
lda basic_top_of_memory_ptr+0
|
lda basic_top_of_memory_ptr+0
|
||||||
sec
|
sec
|
||||||
@@ -39,22 +39,21 @@ startup_banner:
|
|||||||
lda #$20
|
lda #$20
|
||||||
jsr JCHROUT
|
jsr JCHROUT
|
||||||
|
|
||||||
;; Print the rest of the start up message
|
// Print the rest of the start up message
|
||||||
ldx #34
|
ldx #34
|
||||||
jsr print_packed_message
|
jsr print_packed_message
|
||||||
|
|
||||||
;; jump into warm start loop
|
// jump into warm start loop
|
||||||
jmp basic_warm_start
|
jmp basic_warm_start
|
||||||
|
|
||||||
|
startup_message: // XXX this is probably not needed anymore
|
||||||
startup_message:
|
// Clear the screen
|
||||||
;; Clear the screen
|
|
||||||
.byte $93
|
.byte $93
|
||||||
;; Vertical bars in different colours
|
// Vertical bars in different colours
|
||||||
.byte $1C,$B4
|
.byte $1C,$B4
|
||||||
.byte $9E,$B5
|
.byte $9E,$B5
|
||||||
.byte $1E,$A1
|
.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 $12,$05,$4D,$45,$47,$41,$92
|
||||||
.byte $42,$41,$53,$49,$43
|
.byte $42,$41,$53,$49,$43
|
||||||
.byte $20,$56,$32,$2e,$30,$2e,$30
|
.byte $20,$56,$32,$2e,$30,$2e,$30
|
||||||
|
|||||||
@@ -1,18 +1,19 @@
|
|||||||
;; Delete the current BASIC line, which is assumed to have already
|
// Delete the current BASIC line, which is assumed to have already
|
||||||
;; been found with basic_find_line.
|
// been found with basic_find_line.
|
||||||
;; Really only consists of copying memory down.
|
// Really only consists of copying memory down.
|
||||||
;; The only complication is that we have to do the copy with ROMs
|
// 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
|
// banked out. Oh, yes, and we have to update all the links in
|
||||||
;; the following basic lines.
|
// the following basic lines.
|
||||||
|
|
||||||
basic_delete_line:
|
basic_delete_line:
|
||||||
|
|
||||||
;; jsr printf
|
// jsr printf
|
||||||
;; .byte "DELETING LINE AT $"
|
// .text "DELETING LINE AT $"
|
||||||
;; .byte $f1,<basic_current_line_ptr,>basic_current_line_ptr
|
// .byte $f1,<basic_current_line_ptr,>basic_current_line_ptr
|
||||||
;; .byte $f0,<basic_current_line_ptr,>basic_current_line_ptr
|
// .byte $f0,<basic_current_line_ptr,>basic_current_line_ptr
|
||||||
;; .byte $0d,0
|
// .byte $0d,0
|
||||||
|
|
||||||
;; Get address of next line
|
// Get address of next line
|
||||||
ldx #<basic_current_line_ptr
|
ldx #<basic_current_line_ptr
|
||||||
ldy #0
|
ldy #0
|
||||||
jsr peek_under_roms
|
jsr peek_under_roms
|
||||||
@@ -21,7 +22,7 @@ basic_delete_line:
|
|||||||
jsr peek_under_roms
|
jsr peek_under_roms
|
||||||
sta tokenise_work4
|
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
|
lda tokenise_work3
|
||||||
sec
|
sec
|
||||||
sbc basic_current_line_ptr+0
|
sbc basic_current_line_ptr+0
|
||||||
@@ -30,31 +31,31 @@ basic_delete_line:
|
|||||||
sbc basic_current_line_ptr+1
|
sbc basic_current_line_ptr+1
|
||||||
sta tokenise_work4
|
sta tokenise_work4
|
||||||
|
|
||||||
;; jsr printf
|
// jsr printf
|
||||||
;; .byte "LINE LENGTH IS $"
|
// .text "LINE LENGTH IS $"
|
||||||
;; .byte $f0,<tokenise_work4,>tokenise_work4
|
// .byte $f0,<tokenise_work4,>tokenise_work4
|
||||||
;; .byte $f0,<tokenise_work3,>tokenise_work3
|
// .byte $f0,<tokenise_work3,>tokenise_work3
|
||||||
;; .byte $0d,0
|
// .byte $0d,0
|
||||||
|
|
||||||
lda tokenise_work4
|
lda tokenise_work4
|
||||||
sbc #0
|
sbc #0
|
||||||
cmp #$00
|
cmp #$00
|
||||||
beq +
|
beq !+
|
||||||
;; Line length is <0 or >255 bytes.
|
// Line length is <0 or >255 bytes.
|
||||||
;; Either way, things are bad, so abort.
|
// Either way, things are bad, so abort.
|
||||||
jmp do_MEMORY_CORRUPT_error
|
jmp do_MEMORY_CORRUPT_error
|
||||||
*
|
!:
|
||||||
;; Length can now be safely assumed to be in the low
|
// Length can now be safely assumed to be in the low
|
||||||
;; byte only, i.e., stored in tokenise_work3
|
// byte only, i.e., stored in tokenise_work3
|
||||||
|
|
||||||
lda tokenise_work3
|
lda tokenise_work3
|
||||||
pha
|
pha
|
||||||
tax
|
tax
|
||||||
|
|
||||||
;; Shuffle everything down
|
// Shuffle everything down
|
||||||
jsr basic_shift_mem_down_and_relink
|
jsr basic_shift_mem_down_and_relink
|
||||||
|
|
||||||
;; Now decrease top of BASIC mem
|
// Now decrease top of BASIC mem
|
||||||
pla
|
pla
|
||||||
sta tokenise_work3
|
sta tokenise_work3
|
||||||
lda basic_end_of_text_ptr+0
|
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:
|
basic_do_error:
|
||||||
;; Save error number
|
// Save error number
|
||||||
txa
|
txa
|
||||||
pha
|
pha
|
||||||
|
|
||||||
;; Print ? at start
|
// Print ? at start
|
||||||
lda #$0d
|
lda #$0D
|
||||||
jsr JCHROUT
|
jsr JCHROUT
|
||||||
lda #$3f
|
lda #$3F
|
||||||
jsr JCHROUT
|
jsr JCHROUT
|
||||||
|
|
||||||
;; Print main part of error message
|
// Print main part of error message
|
||||||
pla
|
pla
|
||||||
tax
|
tax
|
||||||
jsr print_packed_message
|
jsr print_packed_message
|
||||||
|
|
||||||
;; Print ERROR at end
|
// Print ERROR at end
|
||||||
lda #$20
|
lda #$20
|
||||||
jsr JCHROUT
|
jsr JCHROUT
|
||||||
ldx #33
|
ldx #33
|
||||||
jsr print_packed_message
|
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
|
jsr JCHROUT
|
||||||
lda #$0d
|
lda #$0D // XXX do we need this?
|
||||||
jsr JCHROUT
|
jsr JCHROUT
|
||||||
|
|
||||||
;; Reset stack, and go back to main loop
|
// Reset stack, and go back to main loop
|
||||||
ldx #$fe
|
ldx #$FE
|
||||||
txs
|
txs
|
||||||
jmp basic_main_loop
|
jmp basic_main_loop
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,13 +1,13 @@
|
|||||||
;; Jump back into the BASIC execute line loop
|
// Jump back into the BASIC execute line loop
|
||||||
;; after first checking that we have a colon
|
// after first checking that we have a colon
|
||||||
;; or $00 char
|
// or $00 char
|
||||||
|
|
||||||
basic_end_of_statement_check:
|
basic_end_of_statement_check:
|
||||||
ldx #<basic_current_statement_ptr
|
ldx #<basic_current_statement_ptr
|
||||||
ldy #0
|
ldy #0
|
||||||
jsr peek_under_roms
|
jsr peek_under_roms
|
||||||
|
|
||||||
;; Consume any spaces
|
// Consume any spaces
|
||||||
cmp #$20
|
cmp #$20
|
||||||
bne no_space_to_skip
|
bne no_space_to_skip
|
||||||
jsr basic_consume_character
|
jsr basic_consume_character
|
||||||
@@ -15,62 +15,62 @@ basic_end_of_statement_check:
|
|||||||
|
|
||||||
no_space_to_skip:
|
no_space_to_skip:
|
||||||
cmp #$00
|
cmp #$00
|
||||||
beq +
|
beq !+
|
||||||
cmp #$3a
|
cmp #$3a
|
||||||
beq +
|
beq !+
|
||||||
|
|
||||||
;; not end of statement
|
// not end of statement
|
||||||
clc
|
clc
|
||||||
rts
|
rts
|
||||||
*
|
!:
|
||||||
sec
|
sec
|
||||||
rts
|
rts
|
||||||
|
|
||||||
basic_execute_statement:
|
basic_execute_statement:
|
||||||
|
|
||||||
;; Check for RUN/STOP
|
// Check for RUN/STOP
|
||||||
lda STKEY
|
lda STKEY
|
||||||
bmi +
|
bmi !+
|
||||||
jmp basic_do_break
|
jmp basic_do_break
|
||||||
*
|
!:
|
||||||
;; Skip over any white space and :
|
// Skip over any white space and :
|
||||||
ldy #0
|
ldy #0
|
||||||
ldx #<basic_current_statement_ptr
|
ldx #<basic_current_statement_ptr
|
||||||
jsr peek_under_roms
|
jsr peek_under_roms
|
||||||
jsr basic_end_of_statement_check
|
jsr basic_end_of_statement_check
|
||||||
bcs basic_end_of_line
|
bcs basic_end_of_line
|
||||||
|
|
||||||
;; jsr printf
|
// jsr printf
|
||||||
;; .byte "LINE PTR = $"
|
// .text "LINE PTR = $"
|
||||||
;; .byte $f1,<basic_current_line_ptr,>basic_current_line_ptr
|
// .byte $f1,<basic_current_line_ptr,>basic_current_line_ptr
|
||||||
;; .byte $f0,<basic_current_line_ptr,>basic_current_line_ptr
|
// .byte $f0,<basic_current_line_ptr,>basic_current_line_ptr
|
||||||
;; .byte ", STATEMENT PTR = $"
|
// .text ", STATEMENT PTR = $"
|
||||||
;; .byte $f1,<basic_current_statement_ptr,>basic_current_statement_ptr
|
// .byte $f1,<basic_current_statement_ptr,>basic_current_statement_ptr
|
||||||
;; .byte $f0,<basic_current_statement_ptr,>basic_current_statement_ptr
|
// .byte $f0,<basic_current_statement_ptr,>basic_current_statement_ptr
|
||||||
;; .byte $d,0
|
// .byte $d,0
|
||||||
|
|
||||||
;; Go through the line until its end is reached.
|
// Go through the line until its end is reached.
|
||||||
;; If we reach the end are in direct mode, then
|
// If we reach the end are in direct mode, then
|
||||||
;; go back to reading input, else look for the
|
// go back to reading input, else look for the
|
||||||
;; next line, and advance to that, or else
|
// next line, and advance to that, or else
|
||||||
;; return to READY prompt because we have run out
|
// return to READY prompt because we have run out
|
||||||
;; of program.
|
// of program.
|
||||||
|
|
||||||
;; Get next char of program text, even if it is hiding under a ROM or the
|
// Get next char of program text, even if it is hiding under a ROM or the
|
||||||
;; IO area.
|
// IO area.
|
||||||
ldx #<basic_current_statement_ptr
|
ldx #<basic_current_statement_ptr
|
||||||
ldy #0
|
ldy #0
|
||||||
jsr peek_under_roms
|
jsr peek_under_roms
|
||||||
cmp #$00
|
cmp #$00
|
||||||
beq basic_end_of_line
|
beq basic_end_of_line
|
||||||
|
|
||||||
;; The checks should be done in order of frequency, so that we are as
|
// The checks should be done in order of frequency, so that we are as
|
||||||
;; fast as possible.
|
// fast as possible.
|
||||||
|
|
||||||
cmp #$7f
|
cmp #$7f
|
||||||
bcc not_a_token
|
bcc not_a_token
|
||||||
;; It's a token: So get the jump table entry for it, push it on the stack
|
// It's a token: So get the jump table entry for it, push it on the stack
|
||||||
;; and then RTS to start it.
|
// and then RTS to start it.
|
||||||
asl
|
asl
|
||||||
tax
|
tax
|
||||||
lda basic_command_jump_table+1,x
|
lda basic_command_jump_table+1,x
|
||||||
@@ -78,42 +78,42 @@ basic_execute_statement:
|
|||||||
lda basic_command_jump_table+0,x
|
lda basic_command_jump_table+0,x
|
||||||
pha
|
pha
|
||||||
|
|
||||||
;; Now consume the character
|
// Now consume the character
|
||||||
jsr basic_consume_character
|
jsr basic_consume_character
|
||||||
|
|
||||||
rts
|
rts
|
||||||
|
|
||||||
not_a_token:
|
not_a_token:
|
||||||
;; Space, which we can also just ignore
|
// Space, which we can also just ignore
|
||||||
cmp #$20
|
cmp #$20
|
||||||
beq basic_skip_char
|
beq basic_skip_char
|
||||||
;; End of line?
|
// End of line?
|
||||||
cmp #$00
|
cmp #$00
|
||||||
beq basic_end_of_line
|
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
|
cmp #$3a
|
||||||
beq basic_skip_char
|
beq basic_skip_char
|
||||||
|
|
||||||
;; START wedge support
|
// START wedge support
|
||||||
|
|
||||||
;; Are we in direct mode?
|
// Are we in direct mode?
|
||||||
;; DOS Wedge is a hacky solution (inelegant, but convenient),
|
// DOS Wedge is a hacky solution (inelegant, but convenient),
|
||||||
;; BASIC programmers should implement communication with drives
|
// BASIC programmers should implement communication with drives
|
||||||
;; the standard way, handling channels properly. Besides,
|
// the standard way, handling channels properly. Besides,
|
||||||
;; current implementation does not support characters under ROM
|
// current implementation does not support characters under ROM
|
||||||
ldx basic_current_line_number+1
|
ldx basic_current_line_number+1
|
||||||
cpx #$ff
|
cpx #$ff
|
||||||
bne +
|
bne !+
|
||||||
;; We are in direct mode, allow wedge to handle '@' sign
|
// We are in direct mode, allow wedge to handle '@' sign
|
||||||
;; XXX Maybe it should be allowed only as the first command?
|
// XXX Maybe it should be allowed only as the first command?
|
||||||
cmp #$40
|
cmp #$40
|
||||||
bne +
|
bne !+
|
||||||
jsr basic_consume_character
|
jsr basic_consume_character
|
||||||
jmp wedge_dos
|
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
|
jmp do_SYNTAX_error
|
||||||
|
|
||||||
basic_skip_char:
|
basic_skip_char:
|
||||||
@@ -124,14 +124,14 @@ basic_fetch_and_consume_character:
|
|||||||
ldy #0
|
ldy #0
|
||||||
ldx #<basic_current_statement_ptr
|
ldx #<basic_current_statement_ptr
|
||||||
jsr peek_under_roms
|
jsr peek_under_roms
|
||||||
;; FALL THROUGH
|
// FALL THROUGH
|
||||||
|
|
||||||
basic_consume_character:
|
basic_consume_character:
|
||||||
;; Advance basic text pointer
|
// Advance basic text pointer
|
||||||
inc basic_current_statement_ptr+0
|
inc basic_current_statement_ptr+0
|
||||||
bne +
|
bne !+
|
||||||
inc basic_current_statement_ptr+1
|
inc basic_current_statement_ptr+1
|
||||||
*
|
!:
|
||||||
rts
|
rts
|
||||||
|
|
||||||
basic_unconsume_character:
|
basic_unconsume_character:
|
||||||
@@ -146,46 +146,46 @@ basic_unconsume_character:
|
|||||||
|
|
||||||
basic_end_of_line:
|
basic_end_of_line:
|
||||||
|
|
||||||
;; XXX - If not in direct mode, then advance to next line, if there is
|
// XXX - If not in direct mode, then advance to next line, if there is
|
||||||
;; one.
|
// one.
|
||||||
|
|
||||||
;; Are we in direct mode
|
// Are we in direct mode
|
||||||
lda basic_current_line_number+1
|
lda basic_current_line_number+1
|
||||||
cmp #$ff
|
cmp #$ff
|
||||||
bne basic_not_direct_mode
|
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
|
jmp basic_main_loop
|
||||||
|
|
||||||
basic_not_direct_mode:
|
basic_not_direct_mode:
|
||||||
;; Copy line number to previous line number
|
// Copy line number to previous line number
|
||||||
lda basic_current_line_number+0
|
lda basic_current_line_number+0
|
||||||
sta basic_previous_line_number+0
|
sta basic_previous_line_number+0
|
||||||
lda basic_current_line_number+1
|
lda basic_current_line_number+1
|
||||||
sta basic_previous_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
|
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
|
lda basic_current_line_ptr+0
|
||||||
ora basic_current_line_ptr+1
|
ora basic_current_line_ptr+1
|
||||||
bne basic_execute_from_current_line
|
bne basic_execute_from_current_line
|
||||||
|
|
||||||
;; End of program found
|
// End of program found
|
||||||
jmp basic_main_loop
|
jmp basic_main_loop
|
||||||
|
|
||||||
basic_execute_from_current_line:
|
basic_execute_from_current_line:
|
||||||
;; Check if pointer is null, if so, we are at the end of
|
// Check if pointer is null, if so, we are at the end of
|
||||||
;; the program.
|
// the program.
|
||||||
ldy #0
|
ldy #0
|
||||||
ldx #<basic_current_line_ptr
|
ldx #<basic_current_line_ptr
|
||||||
jsr peek_pointer_null_check
|
jsr peek_pointer_null_check
|
||||||
bcs +
|
bcs !+
|
||||||
;; End of program reached
|
// End of program reached
|
||||||
jmp basic_main_loop
|
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
|
lda basic_current_line_ptr+0
|
||||||
clc
|
clc
|
||||||
adc #4
|
adc #4
|
||||||
@@ -194,7 +194,7 @@ basic_execute_from_current_line:
|
|||||||
adc #0
|
adc #0
|
||||||
sta basic_current_statement_ptr+1
|
sta basic_current_statement_ptr+1
|
||||||
|
|
||||||
;; Store line number
|
// Store line number
|
||||||
ldx #<basic_current_line_ptr
|
ldx #<basic_current_line_ptr
|
||||||
ldy #2
|
ldy #2
|
||||||
jsr peek_under_roms
|
jsr peek_under_roms
|
||||||
@@ -206,7 +206,7 @@ basic_execute_from_current_line:
|
|||||||
jmp basic_execute_statement
|
jmp basic_execute_statement
|
||||||
|
|
||||||
basic_command_jump_table:
|
basic_command_jump_table:
|
||||||
;; $80 - $8F
|
// $80 - $8F
|
||||||
.word cmd_end-1
|
.word cmd_end-1
|
||||||
.word cmd_for-1
|
.word cmd_for-1
|
||||||
.word cmd_next-1
|
.word cmd_next-1
|
||||||
@@ -221,10 +221,10 @@ basic_command_jump_table:
|
|||||||
.word cmd_if-1
|
.word cmd_if-1
|
||||||
.word cmd_restore-1
|
.word cmd_restore-1
|
||||||
.word cmd_gosub-1
|
.word cmd_gosub-1
|
||||||
.word cmd_return -1
|
.word cmd_return-1
|
||||||
.word cmd_rem-1
|
.word cmd_rem-1
|
||||||
|
|
||||||
;; $90-$9F
|
// $90-$9F
|
||||||
.word cmd_stop-1
|
.word cmd_stop-1
|
||||||
.word cmd_on-1
|
.word cmd_on-1
|
||||||
.word cmd_wait-1
|
.word cmd_wait-1
|
||||||
@@ -242,7 +242,7 @@ basic_command_jump_table:
|
|||||||
.word cmd_sys-1
|
.word cmd_sys-1
|
||||||
.word cmd_open-1
|
.word cmd_open-1
|
||||||
|
|
||||||
;; $A0-$AF
|
// $A0-$AF
|
||||||
.word cmd_close-1
|
.word cmd_close-1
|
||||||
.word cmd_get-1
|
.word cmd_get-1
|
||||||
.word cmd_new-1
|
.word cmd_new-1
|
||||||
@@ -260,7 +260,7 @@ basic_command_jump_table:
|
|||||||
.word cmd_exponent-1
|
.word cmd_exponent-1
|
||||||
.word cmd_and-1
|
.word cmd_and-1
|
||||||
|
|
||||||
;; $B0-$BF
|
// $B0-$BF
|
||||||
.word cmd_or-1
|
.word cmd_or-1
|
||||||
.word cmd_greater-1
|
.word cmd_greater-1
|
||||||
.word cmd_equal-1
|
.word cmd_equal-1
|
||||||
@@ -278,7 +278,7 @@ basic_command_jump_table:
|
|||||||
.word cmd_cos-1
|
.word cmd_cos-1
|
||||||
.word cmd_sin-1
|
.word cmd_sin-1
|
||||||
|
|
||||||
;; $C0-$CF
|
// $C0-$CF
|
||||||
.word cmd_tan-1
|
.word cmd_tan-1
|
||||||
.word cmd_atn-1
|
.word cmd_atn-1
|
||||||
.word cmd_peek-1
|
.word cmd_peek-1
|
||||||
@@ -291,13 +291,13 @@ basic_command_jump_table:
|
|||||||
.word cmd_right-1
|
.word cmd_right-1
|
||||||
.word cmd_mid-1
|
.word cmd_mid-1
|
||||||
.word cmd_go-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
|
||||||
.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
|
.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
|
||||||
.word cmd_unimplemented-1
|
.word cmd_unimplemented-1
|
||||||
|
|
||||||
;; $E0-$EF
|
// $E0-$EF
|
||||||
.word cmd_unimplemented-1
|
.word cmd_unimplemented-1
|
||||||
.word cmd_unimplemented-1
|
.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
|
||||||
.word cmd_unimplemented-1
|
.word cmd_unimplemented-1
|
||||||
|
|
||||||
;; $F0-$FF
|
// $F0-$FF
|
||||||
.word cmd_unimplemented-1
|
.word cmd_unimplemented-1
|
||||||
.word cmd_unimplemented-1
|
.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
|
.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:
|
basic_find_line:
|
||||||
;; Get pointer to start of BASIC text
|
// Get pointer to start of BASIC text
|
||||||
lda basic_start_of_text_ptr+0
|
lda basic_start_of_text_ptr+0
|
||||||
sta basic_current_line_ptr+0
|
sta basic_current_line_ptr+0
|
||||||
lda basic_start_of_text_ptr+1
|
lda basic_start_of_text_ptr+1
|
||||||
sta basic_current_line_ptr+1
|
sta basic_current_line_ptr+1
|
||||||
|
|
||||||
basic_find_line_loop:
|
basic_find_line_loop:
|
||||||
;; Then search for line number
|
// Then search for line number
|
||||||
;; Line number
|
// Line number
|
||||||
|
|
||||||
ldy #3
|
ldy #3
|
||||||
ldx #<basic_current_line_ptr
|
ldx #<basic_current_line_ptr
|
||||||
jsr peek_under_roms
|
jsr peek_under_roms
|
||||||
cmp basic_line_number+1
|
cmp basic_line_number+1
|
||||||
beq +
|
beq !+
|
||||||
bcs line_num_too_high
|
bcs line_num_too_high
|
||||||
bne not_this_line
|
bne not_this_line
|
||||||
*
|
!:
|
||||||
|
|
||||||
dey
|
dey
|
||||||
jsr peek_under_roms
|
jsr peek_under_roms
|
||||||
cmp basic_line_number+0
|
cmp basic_line_number+0
|
||||||
beq +
|
beq !+
|
||||||
bcs line_num_too_high
|
bcs line_num_too_high
|
||||||
bne not_this_line
|
bne not_this_line
|
||||||
*
|
!:
|
||||||
clc
|
clc
|
||||||
rts
|
rts
|
||||||
not_this_line:
|
not_this_line:
|
||||||
;; Not this line, so advance to next line
|
// Not this line, so advance to next line
|
||||||
ldx #<basic_current_line_ptr
|
ldx #<basic_current_line_ptr
|
||||||
jsr peek_pointer_null_check
|
jsr peek_pointer_null_check
|
||||||
bcs more_lines_exist
|
bcs more_lines_exist
|
||||||
|
|
||||||
;; no more lines exist, return failure
|
// no more lines exist, return failure
|
||||||
line_num_too_high:
|
line_num_too_high:
|
||||||
sec
|
sec
|
||||||
rts
|
rts
|
||||||
more_lines_exist:
|
more_lines_exist:
|
||||||
|
|
||||||
;; XXX - Add program mangled check here to be triggered
|
// XXX - Add program mangled check here to be triggered
|
||||||
;; if the link goes backwards.
|
// if the link goes backwards.
|
||||||
;; Follow link to next line
|
// Follow link to next line
|
||||||
ldy #0
|
ldy #0
|
||||||
ldx #<basic_current_line_ptr
|
ldx #<basic_current_line_ptr
|
||||||
jsr peek_under_roms
|
jsr peek_under_roms
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
;; Advance basic_current_line_ptr by following the
|
// Advance basic_current_line_ptr by following the
|
||||||
;; link to the next line
|
// link to the next line
|
||||||
|
|
||||||
basic_find_next_line:
|
basic_find_next_line:
|
||||||
|
|
||||||
|
|||||||
@@ -1,25 +1,26 @@
|
|||||||
;; Insert the tokenised line stored at $0200.
|
// Insert the tokenised line stored at $0200.
|
||||||
;; First work out where in the list to put it
|
// First work out where in the list to put it
|
||||||
;; (basic_find_line with the line number can be used to work
|
// (basic_find_line with the line number can be used to work
|
||||||
;; out the insertion point, as it should abort once it finds a
|
// out the insertion point, as it should abort once it finds a
|
||||||
;; line number too high).
|
// line number too high).
|
||||||
;; Then all we have to do is push the rest of the BASIC text up,
|
// Then all we have to do is push the rest of the BASIC text up,
|
||||||
;; and update the pointers in all following basic lines.
|
// and update the pointers in all following basic lines.
|
||||||
|
|
||||||
basic_insert_line:
|
basic_insert_line:
|
||||||
|
|
||||||
;; ASSUMES basic_find_line has been called to set the insert point.
|
// 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,
|
// 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
|
// and the zero-terminated line itself. This means 2+2+1 plus length
|
||||||
;; of tokenised string after the line number
|
// of tokenised string after the line number
|
||||||
|
|
||||||
;; But first, remember where the pointer will be, so that we can
|
// But first, remember where the pointer will be, so that we can
|
||||||
;; put the line in there after.
|
// put the line in there after.
|
||||||
|
|
||||||
;; jsr printf
|
// jsr printf
|
||||||
;; .byte "INSERTING LINE AT $"
|
// .text "INSERTING LINE AT $"
|
||||||
;; .byte $f1,<basic_current_line_ptr,>basic_current_line_ptr
|
// .byte $f1,<basic_current_line_ptr,>basic_current_line_ptr
|
||||||
;; .byte $f0,<basic_current_line_ptr,>basic_current_line_ptr
|
// .byte $f0,<basic_current_line_ptr,>basic_current_line_ptr
|
||||||
;; .byte $0d,0
|
// .byte $0d,0
|
||||||
|
|
||||||
lda basic_current_line_ptr+0
|
lda basic_current_line_ptr+0
|
||||||
pha
|
pha
|
||||||
@@ -27,20 +28,20 @@ basic_insert_line:
|
|||||||
|
|
||||||
pha
|
pha
|
||||||
|
|
||||||
;; Get number of bytes in tokenised line after line number
|
// Get number of bytes in tokenised line after line number
|
||||||
lda tokenise_work2
|
lda tokenise_work2
|
||||||
sec
|
sec
|
||||||
sbc tokenise_work1
|
sbc tokenise_work1
|
||||||
;; Add on the four bytes space we need
|
// Add on the four bytes space we need
|
||||||
clc
|
clc
|
||||||
adc #5
|
adc #5
|
||||||
pha
|
pha
|
||||||
tax
|
tax
|
||||||
|
|
||||||
;; Make the space
|
// Make the space
|
||||||
jsr basic_shift_mem_up_and_relink
|
jsr basic_shift_mem_up_and_relink
|
||||||
|
|
||||||
;; Now increase top of BASIC mem
|
// Now increase top of BASIC mem
|
||||||
pla
|
pla
|
||||||
clc
|
clc
|
||||||
adc basic_end_of_text_ptr+0
|
adc basic_end_of_text_ptr+0
|
||||||
@@ -49,13 +50,13 @@ basic_insert_line:
|
|||||||
adc #0
|
adc #0
|
||||||
sta basic_end_of_text_ptr+1
|
sta basic_end_of_text_ptr+1
|
||||||
|
|
||||||
;; Get pointer back
|
// Get pointer back
|
||||||
pla
|
pla
|
||||||
sta basic_current_line_ptr+1
|
sta basic_current_line_ptr+1
|
||||||
pla
|
pla
|
||||||
sta basic_current_line_ptr+0
|
sta basic_current_line_ptr+0
|
||||||
|
|
||||||
;; Write the line number
|
// Write the line number
|
||||||
ldy #2
|
ldy #2
|
||||||
ldx #<basic_current_line_ptr
|
ldx #<basic_current_line_ptr
|
||||||
lda basic_line_number+0
|
lda basic_line_number+0
|
||||||
@@ -64,7 +65,7 @@ basic_insert_line:
|
|||||||
lda basic_line_number+1
|
lda basic_line_number+1
|
||||||
jsr poke_under_roms
|
jsr poke_under_roms
|
||||||
|
|
||||||
;; Now store the line body itself
|
// Now store the line body itself
|
||||||
inc tokenise_work2
|
inc tokenise_work2
|
||||||
line_store_loop:
|
line_store_loop:
|
||||||
ldx tokenise_work1
|
ldx tokenise_work1
|
||||||
|
|||||||
+50
-51
@@ -1,43 +1,43 @@
|
|||||||
basic_main_loop:
|
basic_main_loop:
|
||||||
|
|
||||||
;; XXX - Check if direct or program mode, and get next line of input
|
// XXX - Check if direct or program mode, and get next line of input
|
||||||
;; the appropriate way.
|
// the appropriate way.
|
||||||
;; XXX - For now, it is hard coded to direct mode
|
// XXX - For now, it is hard coded to direct mode
|
||||||
|
|
||||||
;; Tell user we are ready
|
// Tell user we are ready
|
||||||
jsr ready_message
|
jsr ready_message
|
||||||
|
|
||||||
basic_read_next_line:
|
basic_read_next_line:
|
||||||
;; Read a line of input
|
// Read a line of input
|
||||||
ldx #$00
|
ldx #$00
|
||||||
read_line_loop:
|
read_line_loop:
|
||||||
|
|
||||||
jsr $ffcf ; KERNAL CHRIN
|
jsr JCHRIN
|
||||||
bcs read_line_loop
|
bcs read_line_loop
|
||||||
|
|
||||||
cmp #$0d
|
cmp #$0d
|
||||||
beq got_line_of_input
|
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
|
cpx #80
|
||||||
bcc +
|
bcc !+
|
||||||
;; Report STRING TOO LONG error (Compute's Mapping the 64 p93)
|
// Report STRING TOO LONG error (Compute's Mapping the 64 p93)
|
||||||
ldx #22
|
ldx #22
|
||||||
jmp basic_do_error
|
jmp basic_do_error
|
||||||
*
|
!:
|
||||||
sta basic_input_buffer,x
|
sta basic_input_buffer,x
|
||||||
inx
|
inx
|
||||||
jmp read_line_loop
|
jmp read_line_loop
|
||||||
|
|
||||||
got_line_of_input:
|
got_line_of_input:
|
||||||
|
|
||||||
;; Store length of input buffer ready for tokenising
|
// Store length of input buffer ready for tokenising
|
||||||
stx tokenise_work1
|
stx tokenise_work1
|
||||||
|
|
||||||
;; Strip leading spaces from the line
|
// Strip leading spaces from the line
|
||||||
remove_leading_spaces:
|
remove_leading_spaces:
|
||||||
lda $0200
|
lda $0200
|
||||||
cmp #$20
|
cmp #$20
|
||||||
bne +
|
bne !+
|
||||||
ldx #1
|
ldx #1
|
||||||
rsl_l1: lda $0200,x
|
rsl_l1: lda $0200,x
|
||||||
sta $01ff,x
|
sta $01ff,x
|
||||||
@@ -45,40 +45,40 @@ rsl_l1: lda $0200,x
|
|||||||
cpx tokenise_work1
|
cpx tokenise_work1
|
||||||
bne rsl_l1
|
bne rsl_l1
|
||||||
|
|
||||||
;; Reduce length of input by one
|
// Reduce length of input by one
|
||||||
dec tokenise_work1
|
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
|
bne remove_leading_spaces
|
||||||
*
|
!:
|
||||||
;; Do printing of the new line
|
// Do printing of the new line
|
||||||
lda #$0d
|
lda #$0d
|
||||||
jsr JCHROUT
|
jsr JCHROUT
|
||||||
|
|
||||||
;; Ignore empty lines
|
// Ignore empty lines
|
||||||
lda tokenise_work1
|
lda tokenise_work1
|
||||||
beq basic_read_next_line
|
beq basic_read_next_line
|
||||||
|
|
||||||
;; Else, tokenise the line
|
// Else, tokenise the line
|
||||||
jsr tokenise_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
|
lda $0200
|
||||||
cmp #$30
|
cmp #$30
|
||||||
bcc not_a_line
|
bcc not_a_line
|
||||||
cmp #$39
|
cmp #$39
|
||||||
bcs not_a_line
|
bcs not_a_line
|
||||||
|
|
||||||
;; Yes, the line begins with a number.
|
// Yes, the line begins with a number.
|
||||||
;; Parse the line number and check validity
|
// Parse the line number and check validity
|
||||||
|
|
||||||
;; injest_number follows tokenise_work1 as the offset into the line,
|
// injest_number follows tokenise_work1 as the offset into the line,
|
||||||
;; so remember the line length somewhere else for now.
|
// so remember the line length somewhere else for now.
|
||||||
lda tokenise_work1
|
lda tokenise_work1
|
||||||
sta tokenise_work2
|
sta tokenise_work2
|
||||||
lda #$00
|
lda #$00
|
||||||
sta tokenise_work1
|
sta tokenise_work1
|
||||||
|
|
||||||
;; Try to read line number
|
// Try to read line number
|
||||||
lda #<$0200
|
lda #<$0200
|
||||||
sta basic_current_statement_ptr+0
|
sta basic_current_statement_ptr+0
|
||||||
lda #>$0200
|
lda #>$0200
|
||||||
@@ -86,67 +86,66 @@ rsl_l1: lda $0200,x
|
|||||||
|
|
||||||
jsr basic_parse_line_number
|
jsr basic_parse_line_number
|
||||||
|
|
||||||
;; Get pointer to next char
|
// Get pointer to next char
|
||||||
lda basic_current_statement_ptr+0
|
lda basic_current_statement_ptr+0
|
||||||
sta tokenise_work1
|
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
|
ldx tokenise_work1
|
||||||
skip_spaces:
|
skip_spaces:
|
||||||
lda $0200,x
|
lda $0200,x
|
||||||
cmp #$20
|
cmp #$20
|
||||||
bne +
|
bne !+
|
||||||
inx
|
inx
|
||||||
bne skip_spaces
|
bne skip_spaces
|
||||||
* stx tokenise_work1
|
!: stx tokenise_work1
|
||||||
|
|
||||||
;; First, clear all variables, so that we only have to shove BASIC text around.
|
// 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
|
// (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
|
// 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).
|
// memory free, or else it would auto CLR when you ran out of program space).
|
||||||
jsr basic_do_clr
|
jsr basic_do_clr
|
||||||
|
|
||||||
;; Delete line if present
|
// Delete line if present
|
||||||
jsr basic_find_line
|
jsr basic_find_line
|
||||||
|
|
||||||
bcs +
|
bcs !+
|
||||||
|
|
||||||
;; Delete the line, whether we are deleting or
|
// Delete the line, whether we are deleting or
|
||||||
;; replacing the line
|
// replacing the line
|
||||||
jsr basic_delete_line
|
jsr basic_delete_line
|
||||||
*
|
!:
|
||||||
;; Insert new line if non-zero length, i.e., that
|
// Insert new line if non-zero length, i.e., that
|
||||||
;; we are not just deleting the line.
|
// we are not just deleting the line.
|
||||||
lda tokenise_work1
|
lda tokenise_work1
|
||||||
cmp tokenise_work2
|
cmp tokenise_work2
|
||||||
beq +
|
beq !+
|
||||||
jsr basic_insert_line
|
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
|
jmp basic_read_next_line
|
||||||
|
|
||||||
not_a_line:
|
not_a_line:
|
||||||
|
|
||||||
;; Actually interpret the line
|
// Actually interpret the line
|
||||||
|
|
||||||
;; Setup pointer to the statement
|
// Setup pointer to the statement
|
||||||
lda #<$0200
|
lda #<$0200
|
||||||
sta basic_current_statement_ptr+0
|
sta basic_current_statement_ptr+0
|
||||||
lda #>$0200
|
lda #>$0200
|
||||||
sta basic_current_statement_ptr+1
|
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
|
lda #$00
|
||||||
sta basic_current_line_ptr+0
|
sta basic_current_line_ptr+0
|
||||||
sta basic_current_line_ptr+1
|
sta basic_current_line_ptr+1
|
||||||
|
|
||||||
;; Put invalid line number in current line number value,
|
// Put invalid line number in current line number value,
|
||||||
;; so that we know we are in direct mode
|
// so that we know we are in direct mode
|
||||||
;; (Compute's Mapping the 64 p19)
|
// (Compute's Mapping the 64 p19)
|
||||||
lda #$ff
|
lda #$ff
|
||||||
sta basic_current_line_number+1
|
sta basic_current_line_number+1
|
||||||
|
|
||||||
jmp basic_execute_statement
|
jmp basic_execute_statement
|
||||||
|
|
||||||
@@ -3,22 +3,22 @@ basic_parse_line_number:
|
|||||||
|
|
||||||
jsr injest_number
|
jsr injest_number
|
||||||
|
|
||||||
;; Check if the number is a valid line number
|
// Check if the number is a valid line number
|
||||||
;; i.e., 16 bits, no exponent, no decimal
|
// i.e., 16 bits, no exponent, no decimal
|
||||||
lda basic_fac1_mantissa+2
|
lda basic_fac1_mantissa+2
|
||||||
ora basic_fac1_mantissa+3
|
ora basic_fac1_mantissa+3
|
||||||
ora basic_fac1_exponent
|
ora basic_fac1_exponent
|
||||||
beq +
|
beq !+
|
||||||
ml_bad_line_number:
|
ml_bad_line_number:
|
||||||
;; Invalid line number
|
// Invalid line number
|
||||||
jmp do_ILLEGAL_QUANTITY_error
|
jmp do_ILLEGAL_QUANTITY_error
|
||||||
*
|
!:
|
||||||
;; Line number are not allowed to have decimal points in them
|
// Line number are not allowed to have decimal points in them
|
||||||
lda tokenise_work4
|
lda tokenise_work4
|
||||||
cmp #$ff
|
cmp #$FF
|
||||||
bne ml_bad_line_number
|
bne ml_bad_line_number
|
||||||
|
|
||||||
;; Got a valid line number.
|
// Got a valid line number.
|
||||||
lda basic_fac1_mantissa+0
|
lda basic_fac1_mantissa+0
|
||||||
sta basic_line_number+0
|
sta basic_line_number+0
|
||||||
lda basic_fac1_mantissa+1
|
lda basic_fac1_mantissa+1
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
basic_shift_mem_down_and_relink:
|
basic_shift_mem_down_and_relink:
|
||||||
;; Shift memory down to basic_current_line_pointer
|
// Shift memory down to basic_current_line_pointer
|
||||||
;; from X bytes further along.
|
// from X bytes further along.
|
||||||
|
|
||||||
;; Destination is basic_current_line_ptr
|
// Destination is basic_current_line_ptr
|
||||||
lda basic_current_line_ptr+0
|
lda basic_current_line_ptr+0
|
||||||
sta memmove_dst+0
|
sta memmove_dst+0
|
||||||
lda basic_current_line_ptr+1
|
lda basic_current_line_ptr+1
|
||||||
sta memmove_dst+1
|
sta memmove_dst+1
|
||||||
|
|
||||||
;; Source is that plus X
|
// Source is that plus X
|
||||||
txa
|
txa
|
||||||
pha ; also keep for later
|
pha // also keep for later
|
||||||
clc
|
clc
|
||||||
adc basic_current_line_ptr+0
|
adc basic_current_line_ptr+0
|
||||||
sta memmove_src+0
|
sta memmove_src+0
|
||||||
@@ -18,7 +18,7 @@ basic_shift_mem_down_and_relink:
|
|||||||
adc #0
|
adc #0
|
||||||
sta memmove_src+1
|
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
|
lda basic_end_of_text_ptr+0
|
||||||
sec
|
sec
|
||||||
sbc memmove_src+0
|
sbc memmove_src+0
|
||||||
@@ -27,32 +27,32 @@ basic_shift_mem_down_and_relink:
|
|||||||
sbc memmove_src+1
|
sbc memmove_src+1
|
||||||
sta memmove_size+1
|
sta memmove_size+1
|
||||||
|
|
||||||
;; jsr printf
|
// jsr printf
|
||||||
;; .byte "TOP OF BASIC = $"
|
// .text "TOP OF BASIC = $"
|
||||||
;; .byte $f1,<basic_end_of_text_ptr,>basic_end_of_text_ptr
|
// .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 $f0,<basic_end_of_text_ptr,>basic_end_of_text_ptr
|
||||||
;; .byte $0d
|
// .byte $0d
|
||||||
;; .byte "SHIFTING DOWN $"
|
// .text "SHIFTING DOWN $"
|
||||||
;; .byte $f1,<memmove_size,>memmove_size
|
// .byte $f1,<memmove_size,>memmove_size
|
||||||
;; .byte $f0,<memmove_size,>memmove_size
|
// .byte $f0,<memmove_size,>memmove_size
|
||||||
;; .byte " BYTES FROM $"
|
// .text " BYTES FROM $"
|
||||||
;; .byte $f1,<memmove_src,>memmove_src
|
// .byte $f1,<memmove_src,>memmove_src
|
||||||
;; .byte $f0,<memmove_src,>memmove_src
|
// .byte $f0,<memmove_src,>memmove_src
|
||||||
;; .byte " TO $"
|
// .text " TO $"
|
||||||
;; .byte $f1,<memmove_dst,>memmove_dst
|
// .byte $f1,<memmove_dst,>memmove_dst
|
||||||
;; .byte $f0,<memmove_dst,>memmove_dst
|
// .byte $f0,<memmove_dst,>memmove_dst
|
||||||
;; .byte $0d,0
|
// .byte $0d,0
|
||||||
|
|
||||||
;; The copy routine that copies under the ROMs is as simple
|
// The copy routine that copies under the ROMs is as simple
|
||||||
;; as possible to be as small as possible, so we have
|
// as possible to be as small as possible, so we have
|
||||||
;; to adjust the pointers and counts so that the simple
|
// to adjust the pointers and counts so that the simple
|
||||||
;; increment and decrement bounds checks work.
|
// increment and decrement bounds checks work.
|
||||||
|
|
||||||
;; Specifically we want Y pre-set so that the end of the
|
// Specifically we want Y pre-set so that the end of the
|
||||||
;; copy ends when Y = $00.
|
// copy ends when Y = $00.
|
||||||
;; So if copying 1 byte, we want Y=$FF
|
// So if copying 1 byte, we want Y=$FF
|
||||||
;; This means we have to then reduce the source and
|
// This means we have to then reduce the source and
|
||||||
;; target pointers by the same amount
|
// target pointers by the same amount
|
||||||
|
|
||||||
lda memmove_size+0
|
lda memmove_size+0
|
||||||
eor #$ff
|
eor #$ff
|
||||||
@@ -75,50 +75,50 @@ basic_shift_mem_down_and_relink:
|
|||||||
sbc #0
|
sbc #0
|
||||||
sta memmove_dst+1
|
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
|
inc memmove_size+1
|
||||||
|
|
||||||
;; jsr printf
|
// jsr printf
|
||||||
;; .byte "REVISED BOUNDS $"
|
// .text "REVISED BOUNDS $"
|
||||||
;; .byte $f1,<memmove_size,>memmove_size
|
// .byte $f1,<memmove_size,>memmove_size
|
||||||
;; .byte $f0,<memmove_size,>memmove_size
|
// .byte $f0,<memmove_size,>memmove_size
|
||||||
;; .byte " BYTES FROM $"
|
// .text " BYTES FROM $"
|
||||||
;; .byte $f1,<memmove_src,>memmove_src
|
// .byte $f1,<memmove_src,>memmove_src
|
||||||
;; .byte $f0,<memmove_src,>memmove_src
|
// .byte $f0,<memmove_src,>memmove_src
|
||||||
;; .byte " TO $"
|
// .text " TO $"
|
||||||
;; .byte $f1,<memmove_dst,>memmove_dst
|
// .byte $f1,<memmove_dst,>memmove_dst
|
||||||
;; .byte $f0,<memmove_dst,>memmove_dst
|
// .byte $f0,<memmove_dst,>memmove_dst
|
||||||
;; .byte $0d,0
|
// .byte $0d,0
|
||||||
|
|
||||||
;; Get Y value ready for the copy
|
// Get Y value ready for the copy
|
||||||
ldy memmove_size+0
|
ldy memmove_size+0
|
||||||
|
|
||||||
jsr shift_mem_down
|
jsr shift_mem_down
|
||||||
|
|
||||||
;; Get length of deletion back
|
// Get length of deletion back
|
||||||
pla
|
pla
|
||||||
sta tokenise_work3
|
sta tokenise_work3
|
||||||
|
|
||||||
;; Check if we still have any lines left
|
// Check if we still have any lines left
|
||||||
ldy #0
|
ldy #0
|
||||||
ldx #<basic_current_line_ptr
|
ldx #<basic_current_line_ptr
|
||||||
jsr peek_pointer_null_check
|
jsr peek_pointer_null_check
|
||||||
bcs relink_down_next_line
|
bcs relink_down_next_line
|
||||||
;; Nope, so just return
|
// Nope, so just return
|
||||||
clc
|
clc
|
||||||
rts
|
rts
|
||||||
|
|
||||||
|
|
||||||
relink_down_next_line:
|
relink_down_next_line:
|
||||||
;; inc $d020
|
// inc $d020
|
||||||
;; jmp relink_down_next_line
|
// jmp relink_down_next_line
|
||||||
|
|
||||||
;; Subtract tokenise_work3 from the pointer
|
// Subtract tokenise_work3 from the pointer
|
||||||
ldy #0
|
ldy #0
|
||||||
ldx #<basic_current_line_ptr+0
|
ldx #<basic_current_line_ptr+0
|
||||||
jsr peek_under_roms
|
jsr peek_under_roms
|
||||||
sec
|
sec
|
||||||
sbc tokenise_Work3
|
sbc tokenise_work3
|
||||||
sta memmove_src+0
|
sta memmove_src+0
|
||||||
iny
|
iny
|
||||||
jsr peek_under_roms
|
jsr peek_under_roms
|
||||||
@@ -134,13 +134,13 @@ relink_down_next_line:
|
|||||||
jsr poke_under_roms
|
jsr poke_under_roms
|
||||||
|
|
||||||
relink_down_loop:
|
relink_down_loop:
|
||||||
;; Now advance pointer to the next line,
|
// Now advance pointer to the next line,
|
||||||
lda memmove_src+0
|
lda memmove_src+0
|
||||||
sta basic_current_line_ptr+0
|
sta basic_current_line_ptr+0
|
||||||
lda memmove_src+1
|
lda memmove_src+1
|
||||||
sta basic_current_line_ptr+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
|
ldx #<basic_current_line_ptr
|
||||||
jsr peek_pointer_null_check
|
jsr peek_pointer_null_check
|
||||||
bcs relink_down_next_line
|
bcs relink_down_next_line
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
|
|
||||||
|
|
||||||
basic_shift_mem_up_and_relink:
|
basic_shift_mem_up_and_relink:
|
||||||
;; Shift memory up from basic_current_line_ptr
|
// Shift memory up from basic_current_line_ptr
|
||||||
;; X bytes.
|
// X bytes.
|
||||||
|
|
||||||
;; NOTE: Pointers need to be reduced by one, due to the way
|
// NOTE: Pointers need to be reduced by one, due to the way
|
||||||
;; the copyroutine works, so we do that here.
|
// the copyroutine works, so we do that here.
|
||||||
;; Work out end point of destination
|
// Work out end point of destination
|
||||||
txa
|
txa
|
||||||
clc
|
clc
|
||||||
adc basic_end_of_text_ptr+0
|
adc basic_end_of_text_ptr+0
|
||||||
@@ -22,7 +22,7 @@ basic_shift_mem_up_and_relink:
|
|||||||
sbc #0
|
sbc #0
|
||||||
sta memmove_dst+1
|
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
|
lda basic_end_of_text_ptr+0
|
||||||
sec
|
sec
|
||||||
sbc #1
|
sbc #1
|
||||||
@@ -31,7 +31,7 @@ basic_shift_mem_up_and_relink:
|
|||||||
sbc #0
|
sbc #0
|
||||||
sta memmove_src+1
|
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
|
lda basic_end_of_text_ptr+0
|
||||||
sec
|
sec
|
||||||
sbc basic_current_line_ptr+0
|
sbc basic_current_line_ptr+0
|
||||||
@@ -40,25 +40,25 @@ basic_shift_mem_up_and_relink:
|
|||||||
sbc basic_current_line_ptr+1
|
sbc basic_current_line_ptr+1
|
||||||
sta memmove_size+1
|
sta memmove_size+1
|
||||||
|
|
||||||
;; jsr printf
|
// jsr printf
|
||||||
;; .byte "TOP OF BASIC = $"
|
// .text "TOP OF BASIC = $"
|
||||||
;; .byte $f1,<basic_end_of_text_ptr,>basic_end_of_text_ptr
|
// .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 $f0,<basic_end_of_text_ptr,>basic_end_of_text_ptr
|
||||||
;; .byte $0d
|
// .byte $0d
|
||||||
;; .byte "SHIFTING UP $"
|
// .text "SHIFTING UP $"
|
||||||
;; .byte $f1,<memmove_size,>memmove_size
|
// .byte $f1,<memmove_size,>memmove_size
|
||||||
;; .byte $f0,<memmove_size,>memmove_size
|
// .byte $f0,<memmove_size,>memmove_size
|
||||||
;; .byte " BYTES FROM $"
|
// .text " BYTES FROM $"
|
||||||
;; .byte $f1,<memmove_src,>memmove_src
|
// .byte $f1,<memmove_src,>memmove_src
|
||||||
;; .byte $f0,<memmove_src,>memmove_src
|
// .byte $f0,<memmove_src,>memmove_src
|
||||||
;; .byte " TO $"
|
// .text " TO $"
|
||||||
;; .byte $f1,<memmove_dst,>memmove_dst
|
// .byte $f1,<memmove_dst,>memmove_dst
|
||||||
;; .byte $f0,<memmove_dst,>memmove_dst
|
// .byte $f0,<memmove_dst,>memmove_dst
|
||||||
;; .byte $0d,0
|
// .byte $0d,0
|
||||||
|
|
||||||
;; To make life simple for the copy routine that lives in RAM,
|
// 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
|
// we have to adjust the end pointers down one page and set Y to the low
|
||||||
;; byte of the copy size.
|
// byte of the copy size.
|
||||||
lda memmove_src+0
|
lda memmove_src+0
|
||||||
sec
|
sec
|
||||||
sbc memmove_size+0
|
sbc memmove_size+0
|
||||||
@@ -75,35 +75,35 @@ basic_shift_mem_up_and_relink:
|
|||||||
sbc #0
|
sbc #0
|
||||||
sta memmove_dst+1
|
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
|
inc memmove_size+1
|
||||||
|
|
||||||
;; Then set Y to the number offset required
|
// Then set Y to the number offset required
|
||||||
ldy memmove_size+0
|
ldy memmove_size+0
|
||||||
iny
|
iny
|
||||||
|
|
||||||
stx tokenise_work3
|
stx tokenise_work3
|
||||||
|
|
||||||
;; jsr printf
|
// jsr printf
|
||||||
;; .byte "REVISED BOUNDS $"
|
// .text "REVISED BOUNDS $"
|
||||||
;; .byte $f1,<memmove_size,>memmove_size
|
// .byte $f1,<memmove_size,>memmove_size
|
||||||
;; .byte $f0,<memmove_size,>memmove_size
|
// .byte $f0,<memmove_size,>memmove_size
|
||||||
;; .byte " BYTES FROM $"
|
// .text " BYTES FROM $"
|
||||||
;; .byte $f1,<memmove_src,>memmove_src
|
// .byte $f1,<memmove_src,>memmove_src
|
||||||
;; .byte $f0,<memmove_src,>memmove_src
|
// .byte $f0,<memmove_src,>memmove_src
|
||||||
;; .byte " TO $"
|
// .text " TO $"
|
||||||
;; .byte $f1,<memmove_dst,>memmove_dst
|
// .byte $f1,<memmove_dst,>memmove_dst
|
||||||
;; .byte $f0,<memmove_dst,>memmove_dst
|
// .byte $f0,<memmove_dst,>memmove_dst
|
||||||
;; .byte $0d,0
|
// .byte $0d,0
|
||||||
|
|
||||||
;; Do the copy
|
// Do the copy
|
||||||
jsr shift_mem_up
|
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
|
// First, we need to point the current BASIC line
|
||||||
;; pointer to itself, so that we can add the shift
|
// pointer to itself, so that we can add the shift
|
||||||
;; to make it end up pointing to the next line
|
// to make it end up pointing to the next line
|
||||||
ldy #0
|
ldy #0
|
||||||
ldx #<basic_current_line_ptr+0
|
ldx #<basic_current_line_ptr+0
|
||||||
lda 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
|
jsr poke_under_roms
|
||||||
|
|
||||||
relink_up_next_line:
|
relink_up_next_line:
|
||||||
;; inc $d020
|
// inc $d020
|
||||||
;; jmp relink_up_next_line
|
// jmp relink_up_next_line
|
||||||
|
|
||||||
;; Advance pointer by tokenise_word3 bytes
|
// Advance pointer by tokenise_word3 bytes
|
||||||
ldy #0
|
ldy #0
|
||||||
ldx #<basic_current_line_ptr+0
|
ldx #<basic_current_line_ptr+0
|
||||||
jsr peek_under_roms
|
jsr peek_under_roms
|
||||||
@@ -132,20 +132,20 @@ relink_up_next_line:
|
|||||||
adc #0
|
adc #0
|
||||||
sta memmove_src+1
|
sta memmove_src+1
|
||||||
|
|
||||||
;; jsr printf
|
// jsr printf
|
||||||
;; .byte "LINE ADDR = $"
|
// .text "LINE ADDR = $"
|
||||||
;; .byte $f1,<basic_current_line_ptr,>basic_end_of_text_ptr
|
// .byte $f1,<basic_current_line_ptr,>basic_end_of_text_ptr
|
||||||
;; .byte $f0,<basic_current_line_ptr,>basic_end_of_text_ptr
|
// .byte $f0,<basic_current_line_ptr,>basic_end_of_text_ptr
|
||||||
;; .byte $d," BEFORE = $"
|
// .text $d," BEFORE = $"
|
||||||
;; .byte $f1,<memmove_dst,>memmove_dst
|
// .byte $f1,<memmove_dst,>memmove_dst
|
||||||
;; .byte $f0,<memmove_dst,>memmove_dst
|
// .byte $f0,<memmove_dst,>memmove_dst
|
||||||
;; .byte ", AFTER = $"
|
// .text ", AFTER = $"
|
||||||
;; .byte $f1,<memmove_src,>memmove_src
|
// .byte $f1,<memmove_src,>memmove_src
|
||||||
;; .byte $f0,<memmove_src,>memmove_src
|
// .byte $f0,<memmove_src,>memmove_src
|
||||||
;; .byte $d
|
// .byte $d
|
||||||
;; .byte 0
|
// .byte 0
|
||||||
|
|
||||||
;; Write memmove_src back to current line pointer
|
// Write memmove_src back to current line pointer
|
||||||
ldy #0
|
ldy #0
|
||||||
ldx #<basic_current_line_ptr
|
ldx #<basic_current_line_ptr
|
||||||
lda memmove_src+0
|
lda memmove_src+0
|
||||||
@@ -156,13 +156,13 @@ relink_up_next_line:
|
|||||||
|
|
||||||
|
|
||||||
relink_up_loop:
|
relink_up_loop:
|
||||||
;; Now advance pointer to the next line,
|
// Now advance pointer to the next line,
|
||||||
lda memmove_src+0
|
lda memmove_src+0
|
||||||
sta basic_current_line_ptr+0
|
sta basic_current_line_ptr+0
|
||||||
lda memmove_src+1
|
lda memmove_src+1
|
||||||
sta basic_current_line_ptr+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
|
ldx #<basic_current_line_ptr
|
||||||
jsr peek_pointer_null_check
|
jsr peek_pointer_null_check
|
||||||
bcs relink_up_next_line
|
bcs relink_up_next_line
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
;; Clear screen etc, show READY prompt.
|
// Clear screen etc, show READY prompt.
|
||||||
|
|
||||||
basic_warm_start:
|
basic_warm_start:
|
||||||
jsr install_ram_routines
|
jsr install_ram_routines
|
||||||
|
|
||||||
;; If warm start caused by BRK, print it address
|
// If warm start caused by BRK, print it address
|
||||||
lda CMP0
|
lda CMP0
|
||||||
ora CMP0+1
|
ora CMP0+1
|
||||||
beq +
|
beq !+
|
||||||
|
|
||||||
ldx #32
|
ldx #32
|
||||||
jsr print_packed_message
|
jsr print_packed_message
|
||||||
@@ -18,6 +18,6 @@ basic_warm_start:
|
|||||||
lda #$0D
|
lda #$0D
|
||||||
jsr JCHROUT
|
jsr JCHROUT
|
||||||
|
|
||||||
*
|
!:
|
||||||
jmp basic_main_loop
|
jmp basic_main_loop
|
||||||
|
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
;; Skip the gap between $C000-$DFFF
|
// Skip the gap between $C000-$DFFF
|
||||||
.checkpc $C000
|
|
||||||
.advance $DFFF,$00
|
.fill $2000, $00
|
||||||
.checkpc $E000
|
|
||||||
+13
-12
@@ -1,23 +1,24 @@
|
|||||||
cmd_stop:
|
cmd_stop:
|
||||||
basic_do_break:
|
basic_do_break:
|
||||||
jsr printf
|
jsr printf // XXX don't use printf, use packed messages!
|
||||||
.byte "BREAK",0
|
.text "BREAK"
|
||||||
|
.byte 0
|
||||||
|
|
||||||
;; Check for direct mode
|
// Check for direct mode
|
||||||
;; Are we in direct mode
|
// Are we in direct mode
|
||||||
lda basic_current_line_number+1
|
lda basic_current_line_number+1
|
||||||
cmp #$ff
|
cmp #$FF
|
||||||
beq +
|
beq !+
|
||||||
;; Not direct mode
|
// Not direct mode
|
||||||
jsr printf
|
jsr printf // XXX don't use printf, use packed messages!
|
||||||
.byte " IN ",0
|
.text " IN "
|
||||||
|
.byte 0
|
||||||
lda basic_current_line_number+1
|
lda basic_current_line_number+1
|
||||||
ldx basic_current_line_number+0
|
ldx basic_current_line_number+0
|
||||||
jsr print_integer
|
jsr print_integer
|
||||||
|
|
||||||
*
|
!:
|
||||||
lda #$0d
|
lda #$0D
|
||||||
jsr JCHROUT
|
jsr JCHROUT
|
||||||
cmd_end:
|
cmd_end:
|
||||||
jmp basic_main_loop
|
jmp basic_main_loop
|
||||||
|
|
||||||
+26
-26
@@ -1,9 +1,9 @@
|
|||||||
;; LIST basic text.
|
// LIST basic text.
|
||||||
;; XXX - Doesn't currently support line number ranges
|
// XXX - Doesn't currently support line number ranges
|
||||||
|
|
||||||
cmd_list:
|
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
|
lda basic_start_of_text_ptr+0
|
||||||
sta basic_current_line_ptr+0
|
sta basic_current_line_ptr+0
|
||||||
lda basic_start_of_text_ptr+1
|
lda basic_start_of_text_ptr+1
|
||||||
@@ -16,23 +16,23 @@ list_loop:
|
|||||||
cmp #$00
|
cmp #$00
|
||||||
bne list_more_lines
|
bne list_more_lines
|
||||||
|
|
||||||
;; LIST terminates any running program,
|
// LIST terminates any running program,
|
||||||
;; because it has fiddled with the current line pointer.
|
// because it has fiddled with the current line pointer.
|
||||||
;; (Confirmed by testing on a C64)
|
// (Confirmed by testing on a C64)
|
||||||
jmp basic_main_loop
|
jmp basic_main_loop
|
||||||
|
|
||||||
list_more_lines:
|
list_more_lines:
|
||||||
lda STKEY
|
lda STKEY
|
||||||
bmi +
|
bmi !+
|
||||||
jmp basic_do_break
|
jmp basic_do_break
|
||||||
*
|
!:
|
||||||
jsr list_single_line
|
jsr list_single_line
|
||||||
;; Now link to the next line
|
// Now link to the next line
|
||||||
jsr basic_find_next_line
|
jsr basic_find_next_line
|
||||||
jmp list_loop
|
jmp list_loop
|
||||||
|
|
||||||
list_single_line: ; entry point needed by DOS wedge
|
list_single_line: // entry point needed by DOS wedge
|
||||||
;; Print line number
|
// Print line number
|
||||||
ldy #3
|
ldy #3
|
||||||
jsr peek_under_roms
|
jsr peek_under_roms
|
||||||
pha
|
pha
|
||||||
@@ -44,8 +44,8 @@ list_single_line: ; entry point needed by DOS wedge
|
|||||||
lda #$20
|
lda #$20
|
||||||
jsr JCHROUT
|
jsr JCHROUT
|
||||||
|
|
||||||
;; Iterate through printing out the line
|
// Iterate through printing out the line
|
||||||
;; contents
|
// contents
|
||||||
lda #0
|
lda #0
|
||||||
sta quote_mode_flag
|
sta quote_mode_flag
|
||||||
|
|
||||||
@@ -63,34 +63,34 @@ list_print_loop:
|
|||||||
lda #$22
|
lda #$22
|
||||||
jmp list_is_literal
|
jmp list_is_literal
|
||||||
list_not_quote:
|
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
|
ldx quote_mode_flag
|
||||||
bne list_is_literal
|
bne list_is_literal
|
||||||
|
|
||||||
cmp #$7f
|
cmp #$7f
|
||||||
bcc list_is_literal
|
bcc list_is_literal
|
||||||
|
|
||||||
;; Display a token
|
// Display a token
|
||||||
|
|
||||||
;; Save registers
|
// Save registers
|
||||||
tax
|
tax
|
||||||
pha
|
pha
|
||||||
tya
|
tya
|
||||||
pha
|
pha
|
||||||
|
|
||||||
;; Get pointer to compressed keyword list
|
// Get pointer to compressed keyword list
|
||||||
lda #<packed_keywords
|
lda #<packed_keywords
|
||||||
sta temp_string_ptr+0
|
sta temp_string_ptr+0
|
||||||
lda #>packed_keywords
|
lda #>packed_keywords
|
||||||
sta temp_string_ptr+1
|
sta temp_string_ptr+1
|
||||||
|
|
||||||
;; Subtract $80 from token to get offset in word
|
// Subtract $80 from token to get offset in word
|
||||||
;; list
|
// list
|
||||||
txa
|
txa
|
||||||
and #$7f
|
and #$7f
|
||||||
tax
|
tax
|
||||||
|
|
||||||
;; Now ask for it to be printed
|
// Now ask for it to be printed
|
||||||
ldy #$ff
|
ldy #$ff
|
||||||
jsr packed_word_search
|
jsr packed_word_search
|
||||||
|
|
||||||
@@ -100,11 +100,11 @@ list_not_quote:
|
|||||||
|
|
||||||
cmp #$8f
|
cmp #$8f
|
||||||
bne list_not_rem
|
bne list_not_rem
|
||||||
;; REM command locks quote flag on until the end of the line, allowing
|
// REM command locks quote flag on until the end of the line, allowing
|
||||||
;; funny characters in REM statements without problem.
|
// funny characters in REM statements without problem.
|
||||||
inc $0427
|
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
|
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
|
// FALL THROUGH
|
||||||
list_not_rem:
|
list_not_rem:
|
||||||
|
|
||||||
iny
|
iny
|
||||||
@@ -116,10 +116,10 @@ list_is_literal:
|
|||||||
bne list_print_loop
|
bne list_print_loop
|
||||||
|
|
||||||
list_end_of_line:
|
list_end_of_line:
|
||||||
;; Clear reverse flag
|
// Clear reverse flag
|
||||||
lda #$92
|
lda #$92
|
||||||
jsr JCHROUT
|
jsr JCHROUT
|
||||||
;; Print end of line
|
// Print end of line
|
||||||
lda #$0d
|
lda #$0d
|
||||||
jsr JCHROUT
|
jsr JCHROUT
|
||||||
rts
|
rts
|
||||||
|
|||||||
+66
-66
@@ -1,64 +1,64 @@
|
|||||||
cmd_load:
|
cmd_load:
|
||||||
|
|
||||||
;; Parse filename
|
// Parse filename
|
||||||
;; (we can tell the KERNAL where it is in memory directly, since the
|
// (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
|
// 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).
|
// to be able to peek under the ROMs for SAVE and VERIFY).
|
||||||
;; Parse optional device #
|
// Parse optional device #
|
||||||
;; Parse optional secondary address
|
// Parse optional secondary address
|
||||||
|
|
||||||
;; XXX - C64 BASIC apparently doesn't clear variables after a LOAD in the
|
// XXX - C64 BASIC apparently doesn't clear variables after a LOAD in the
|
||||||
;; middle of a program. For safety, we do.
|
// middle of a program. For safety, we do.
|
||||||
jsr basic_do_clr
|
jsr basic_do_clr
|
||||||
|
|
||||||
;; Setup Kernal to print control messages or not
|
// Setup Kernal to print control messages or not
|
||||||
lda #$80 ; display control messages and omit error messages
|
lda #$80 // display control messages and omit error messages
|
||||||
ldx basic_current_line_number+1
|
ldx basic_current_line_number+1
|
||||||
cpx #$FF
|
cpx #$FF
|
||||||
beq +
|
beq !+
|
||||||
lda #$00 ; direct mode - don't display anything
|
lda #$00 // direct mode - don't display anything
|
||||||
*
|
!:
|
||||||
jsr JSETMSG
|
jsr JSETMSG
|
||||||
|
|
||||||
;; Set filename and length
|
// Set filename and length
|
||||||
lda #$00
|
lda #$00
|
||||||
sta FNLEN
|
sta FNLEN
|
||||||
|
|
||||||
;; Without tape support, LOAD must have a filename
|
// Without tape support, LOAD must have a filename
|
||||||
;; (This also skips any leading spaces)
|
// (This also skips any leading spaces)
|
||||||
jsr basic_end_of_statement_check
|
jsr basic_end_of_statement_check
|
||||||
bcc +
|
bcc !+
|
||||||
jmp do_MISSING_FILENAME_error
|
jmp do_MISSING_FILENAME_error
|
||||||
*
|
!:
|
||||||
jsr basic_fetch_and_consume_character
|
jsr basic_fetch_and_consume_character
|
||||||
cmp #$22
|
cmp #$22
|
||||||
beq +
|
beq !+
|
||||||
jmp do_SYNTAX_ERROR
|
jmp do_SYNTAX_error
|
||||||
*
|
!:
|
||||||
;; Filename starts here so set pointer
|
// Filename starts here so set pointer
|
||||||
lda basic_current_statement_ptr+0
|
lda basic_current_statement_ptr+0
|
||||||
sta current_filename_ptr+0
|
sta current_filename_ptr+0
|
||||||
lda basic_current_statement_ptr+1
|
lda basic_current_statement_ptr+1
|
||||||
sta current_filename_ptr+1
|
sta current_filename_ptr+1
|
||||||
|
|
||||||
;; Now search for end of line or closing quote
|
// Now search for end of line or closing quote
|
||||||
;; so that we know the length of the filename
|
// so that we know the length of the filename
|
||||||
getting_filename:
|
getting_filename:
|
||||||
jsr basic_fetch_and_consume_character
|
jsr basic_fetch_and_consume_character
|
||||||
cmp #$22
|
cmp #$22
|
||||||
beq got_filename
|
beq got_filename
|
||||||
cmp #$00
|
cmp #$00
|
||||||
bne +
|
bne !+
|
||||||
jsr basic_unconsume_character
|
jsr basic_unconsume_character
|
||||||
|
|
||||||
jmp got_filename
|
jmp got_filename
|
||||||
*
|
!:
|
||||||
inc FNLEN
|
inc FNLEN
|
||||||
jmp getting_filename
|
jmp getting_filename
|
||||||
|
|
||||||
got_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
|
jsr select_device
|
||||||
stx current_device_number
|
stx current_device_number
|
||||||
jsr injest_comma
|
jsr injest_comma
|
||||||
@@ -66,116 +66,116 @@ got_filename:
|
|||||||
|
|
||||||
jsr basic_parse_line_number
|
jsr basic_parse_line_number
|
||||||
lda basic_line_number+1
|
lda basic_line_number+1
|
||||||
beq +
|
beq !+
|
||||||
jmp do_ILLEGAL_QUANTITY_error
|
jmp do_ILLEGAL_QUANTITY_error
|
||||||
*
|
!:
|
||||||
lda basic_line_number+0
|
lda basic_line_number+0
|
||||||
sta current_device_number
|
sta current_device_number
|
||||||
|
|
||||||
got_devicenumber:
|
got_devicenumber:
|
||||||
|
|
||||||
;; Now fetch the secondary address
|
// Now fetch the secondary address
|
||||||
lda #$00
|
lda #$00
|
||||||
sta current_secondary_address
|
sta current_secondary_address
|
||||||
jsr injest_comma
|
jsr injest_comma
|
||||||
bcs got_secondaryaddress
|
bcs got_secondaryaddress
|
||||||
jsr basic_parse_line_number
|
jsr basic_parse_line_number
|
||||||
lda basic_line_number+1
|
lda basic_line_number+1
|
||||||
bne +
|
bne !+
|
||||||
lda basic_line_number+0
|
lda basic_line_number+0
|
||||||
sta current_secondary_address
|
sta current_secondary_address
|
||||||
jmp got_secondaryaddress
|
jmp got_secondaryaddress
|
||||||
*
|
!:
|
||||||
;; Second parameter is above 255, this can't be a secondary address
|
// Second parameter is above 255, this can't be a secondary address
|
||||||
;; Use it as load address instead
|
// Use it as load address instead
|
||||||
;; XXX temporary syntax, it would be better to use something
|
// XXX temporary syntax, it would be better to use something
|
||||||
;; XXX like 'LOAD"FILE",8 TO 49152'
|
// XXX like 'LOAD"FILE",8 TO 49152'
|
||||||
ldx basic_line_number+0
|
ldx basic_line_number+0
|
||||||
ldy basic_line_number+1
|
ldy basic_line_number+1
|
||||||
bne got_loadaddress
|
bne got_loadaddress
|
||||||
|
|
||||||
got_secondaryaddress:
|
got_secondaryaddress:
|
||||||
ldx #<$0801
|
ldx #<$0801 // XXX use start text vector
|
||||||
ldy #>$0801
|
ldy #>$0801
|
||||||
|
|
||||||
got_loadaddress:
|
got_loadaddress:
|
||||||
lda #$00 ; LOAD not verify
|
lda #$00 // LOAD not verify
|
||||||
jsr via_ILOAD
|
jsr via_ILOAD
|
||||||
bcc +
|
bcc !+
|
||||||
|
|
||||||
;; A = KERNAL error code, which also almost match
|
// A = KERNAL error code, which also almost match
|
||||||
;; basic ERROR codes, so we can just copy the
|
// basic ERROR codes, so we can just copy the
|
||||||
;; error code to X, decrement, and handle normally
|
// error code to X, decrement, and handle normally
|
||||||
tax
|
tax
|
||||||
dex
|
dex
|
||||||
jmp do_basic_error
|
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
|
stx basic_end_of_text_ptr+0
|
||||||
sty basic_end_of_text_ptr+1
|
sty basic_end_of_text_ptr+1
|
||||||
|
|
||||||
;; Now relink the loaded program, as we cannot trust the line
|
// Now relink the loaded program, as we cannot trust the line
|
||||||
;; links supplied. For example, the VICE virtual drive emulation
|
// links supplied. For example, the VICE virtual drive emulation
|
||||||
;; always supplies $0101 as the address of the next line.
|
// always supplies $0101 as the address of the next line.
|
||||||
jsr basic_relink_program
|
jsr basic_relink_program
|
||||||
|
|
||||||
;; After LOADing, we either start the program from the beginning,
|
// After LOADing, we either start the program from the beginning,
|
||||||
;; or go back to the READY prompt if LOAD was called from direct mode.
|
// 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
|
lda basic_start_of_text_ptr+0
|
||||||
sta basic_current_line_ptr+0
|
sta basic_current_line_ptr+0
|
||||||
lda basic_start_of_text_ptr+1
|
lda basic_start_of_text_ptr+1
|
||||||
sta basic_current_line_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
|
jmp basic_main_loop
|
||||||
|
|
||||||
|
|
||||||
basic_relink_program:
|
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
|
lda basic_start_of_text_ptr+0
|
||||||
sta basic_current_line_ptr+0
|
sta basic_current_line_ptr+0
|
||||||
lda basic_start_of_text_ptr+1
|
lda basic_start_of_text_ptr+1
|
||||||
sta basic_current_line_ptr+1
|
sta basic_current_line_ptr+1
|
||||||
|
|
||||||
basic_relink_loop:
|
basic_relink_loop:
|
||||||
;; Is the pointer to the end of the program
|
// Is the pointer to the end of the program
|
||||||
ldy #1
|
ldy #1
|
||||||
ldx #<basic_current_line_ptr+0
|
ldx #<basic_current_line_ptr+0
|
||||||
jsr peek_under_roms
|
jsr peek_under_roms
|
||||||
cmp #$00
|
cmp #$00
|
||||||
bne +
|
bne !+
|
||||||
|
|
||||||
;; End of program
|
// End of program
|
||||||
rts
|
rts
|
||||||
*
|
!:
|
||||||
;; Now search forward to find the end of the line
|
// Now search forward to find the end of the line
|
||||||
;; Skip forward pointer and line number
|
// Skip forward pointer and line number
|
||||||
ldy #4
|
ldy #4
|
||||||
end_of_line_search:
|
end_of_line_search:
|
||||||
ldx #<basic_current_line_ptr+0
|
ldx #<basic_current_line_ptr+0
|
||||||
jsr peek_under_roms
|
jsr peek_under_roms
|
||||||
cmp #$00
|
cmp #$00
|
||||||
beq +
|
beq !+
|
||||||
|
|
||||||
;; Not yet end of line
|
// Not yet end of line
|
||||||
iny
|
iny
|
||||||
bne end_of_line_search
|
bne end_of_line_search
|
||||||
|
|
||||||
;; line too long
|
// line too long
|
||||||
jmp do_STRING_TOO_LONG_error
|
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
|
iny
|
||||||
|
|
||||||
;; Now overwrite the pointer (carefully)
|
// Now overwrite the pointer (carefully)
|
||||||
;;
|
//
|
||||||
tya
|
tya
|
||||||
clc
|
clc
|
||||||
adc basic_current_line_ptr+0
|
adc basic_current_line_ptr+0
|
||||||
|
|||||||
+21
-23
@@ -2,18 +2,18 @@
|
|||||||
cmd_new:
|
cmd_new:
|
||||||
jsr basic_do_new
|
jsr basic_do_new
|
||||||
|
|
||||||
;; NEW command terminates execution
|
// NEW command terminates execution
|
||||||
;; (Confirmed on a C64)
|
// (Confirmed on a C64)
|
||||||
jmp basic_main_loop
|
jmp basic_main_loop
|
||||||
|
|
||||||
cmd_clr:
|
cmd_clr:
|
||||||
jsr basic_do_clr
|
jsr basic_do_clr
|
||||||
;; CLR command does not stop execution
|
// CLR command does not stop execution
|
||||||
;; (Cconfirmed on a c64)
|
// (Cconfirmed on a c64)
|
||||||
jmp basic_execute_statement
|
jmp basic_execute_statement
|
||||||
|
|
||||||
basic_do_new:
|
basic_do_new:
|
||||||
;; Setup pointers to memory storage
|
// Setup pointers to memory storage XXX should depend on text start vector
|
||||||
lda #<$0801
|
lda #<$0801
|
||||||
sta basic_start_of_text_ptr+0
|
sta basic_start_of_text_ptr+0
|
||||||
lda #>$0801
|
lda #>$0801
|
||||||
@@ -22,8 +22,8 @@ basic_do_new:
|
|||||||
lda #<$0803
|
lda #<$0803
|
||||||
sta basic_start_of_vars_ptr+0
|
sta basic_start_of_vars_ptr+0
|
||||||
|
|
||||||
;; Zero line pointer
|
// Zero line pointer
|
||||||
;; XXX - We should also zero $0800, i.e., basic_start_of_text_ptr - 1
|
// XXX - We should also zero $0800, i.e., basic_start_of_text_ptr - 1
|
||||||
ldy #$00
|
ldy #$00
|
||||||
tya
|
tya
|
||||||
sta (basic_start_of_text_ptr),y
|
sta (basic_start_of_text_ptr),y
|
||||||
@@ -31,32 +31,32 @@ basic_do_new:
|
|||||||
sta (basic_start_of_text_ptr),y
|
sta (basic_start_of_text_ptr),y
|
||||||
|
|
||||||
|
|
||||||
;; Get top of memory.
|
// Get top of memory.
|
||||||
;; If a cart is present, then it is $7FFF,
|
// If a cart is present, then it is $7FFF,
|
||||||
;; if not, then it is $F7FF, since we support having
|
// if not, then it is $F7FF, since we support having
|
||||||
;; programs and variables under ROM.
|
// programs and variables under ROM.
|
||||||
;; i.e., we support 56KB RAM for BASIC, keeping some space
|
// i.e., we support 56KB RAM for BASIC, keeping some space
|
||||||
;; free for some optimisation structures, e.g., FOR/NEXT loop
|
// free for some optimisation structures, e.g., FOR/NEXT loop
|
||||||
;; records (without them going on the stack), GOSUB stack
|
// records (without them going on the stack), GOSUB stack
|
||||||
;; (same story), expression value cache?
|
// (same story), expression value cache?
|
||||||
|
|
||||||
sec ; Read, not write value
|
sec // Read, not write value
|
||||||
jsr JMEMTOP
|
jsr JMEMTOP
|
||||||
cpx #$80
|
cpx #$80
|
||||||
beq +
|
beq !+
|
||||||
lda #>$f7ff
|
lda #>$f7ff
|
||||||
.byte $2c
|
.byte $2C
|
||||||
* lda #>$7FFF
|
!: lda #>$7FFF
|
||||||
sta basic_top_of_memory_ptr+1
|
sta basic_top_of_memory_ptr+1
|
||||||
sta basic_start_of_strings_ptr+1
|
sta basic_start_of_strings_ptr+1
|
||||||
lda #<$f7ff
|
lda #<$f7ff
|
||||||
sta basic_top_of_memory_ptr+0
|
sta basic_top_of_memory_ptr+0
|
||||||
sta basic_start_of_strings_ptr+0
|
sta basic_start_of_strings_ptr+0
|
||||||
|
|
||||||
;; FALL THROUGH
|
// FALL THROUGH
|
||||||
|
|
||||||
basic_do_clr:
|
basic_do_clr:
|
||||||
;; Clear variables, arrays and strings
|
// Clear variables, arrays and strings
|
||||||
lda basic_start_of_vars_ptr+0
|
lda basic_start_of_vars_ptr+0
|
||||||
sta basic_start_of_arrays_ptr+0
|
sta basic_start_of_arrays_ptr+0
|
||||||
sta basic_start_of_free_space_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
|
sta basic_start_of_free_space_ptr+1
|
||||||
|
|
||||||
rts
|
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:
|
cmd_rem:
|
||||||
jmp basic_end_of_line
|
jmp basic_end_of_line
|
||||||
+7
-7
@@ -1,21 +1,21 @@
|
|||||||
cmd_run:
|
cmd_run:
|
||||||
;; RUN clears all variables
|
// RUN clears all variables
|
||||||
jsr basic_do_clr
|
jsr basic_do_clr
|
||||||
cmd_goto:
|
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
|
lda basic_start_of_text_ptr+0
|
||||||
sta basic_current_line_ptr+0
|
sta basic_current_line_ptr+0
|
||||||
lda basic_start_of_text_ptr+1
|
lda basic_start_of_text_ptr+1
|
||||||
sta basic_current_line_ptr+1
|
sta basic_current_line_ptr+1
|
||||||
|
|
||||||
jsr basic_end_of_statement_check
|
jsr basic_end_of_statement_check
|
||||||
bcs +
|
bcs !+
|
||||||
|
|
||||||
jsr basic_parse_line_number
|
jsr basic_parse_line_number
|
||||||
jsr basic_find_line
|
jsr basic_find_line
|
||||||
bcc +
|
bcc !+
|
||||||
;; Line doesn't exist, so report error
|
// Line doesn't exist, so report error
|
||||||
jmp do_UNDEFD_STATEMENT_error
|
jmp do_UNDEFD_STATEMENT_error
|
||||||
*
|
!:
|
||||||
;; Run it!
|
// Run it!
|
||||||
jmp basic_execute_from_current_line
|
jmp basic_execute_from_current_line
|
||||||
+8
-8
@@ -1,23 +1,23 @@
|
|||||||
cmd_sys:
|
cmd_sys:
|
||||||
|
|
||||||
jsr basic_end_of_statement_check
|
jsr basic_end_of_statement_check
|
||||||
bcc +
|
bcc !+
|
||||||
|
|
||||||
;; SYS requires an argument
|
// SYS requires an argument
|
||||||
jmp do_SYNTAX_ERROR
|
jmp do_SYNTAX_error
|
||||||
|
|
||||||
*
|
!:
|
||||||
jsr basic_parse_line_number
|
jsr basic_parse_line_number
|
||||||
|
|
||||||
;; setup call
|
// setup call
|
||||||
lda #$4C ;JMP
|
lda #$4C // JMP opcode
|
||||||
sta USRPOK
|
sta USRPOK
|
||||||
lda basic_line_number+0
|
lda basic_line_number+0
|
||||||
sta USRADD+0
|
sta USRADD+0
|
||||||
lda basic_line_number+1
|
lda basic_line_number+1
|
||||||
sta USRADD+1
|
sta USRADD+1
|
||||||
|
|
||||||
;; Setup the register values
|
// Setup the register values
|
||||||
lda SPREG
|
lda SPREG
|
||||||
pha
|
pha
|
||||||
ldy SYREG
|
ldy SYREG
|
||||||
@@ -25,7 +25,7 @@ cmd_sys:
|
|||||||
lda SAREG
|
lda SAREG
|
||||||
plp
|
plp
|
||||||
|
|
||||||
;; Call the routine.
|
// Call the routine.
|
||||||
jsr USRPOK
|
jsr USRPOK
|
||||||
|
|
||||||
jmp basic_execute_statement
|
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_for:
|
||||||
cmd_next:
|
cmd_next:
|
||||||
@@ -13,7 +13,7 @@ cmd_restore:
|
|||||||
cmd_gosub:
|
cmd_gosub:
|
||||||
cmd_return:
|
cmd_return:
|
||||||
|
|
||||||
;; $90-$9F
|
// $90-$9F
|
||||||
cmd_on:
|
cmd_on:
|
||||||
cmd_wait:
|
cmd_wait:
|
||||||
cmd_save:
|
cmd_save:
|
||||||
@@ -26,7 +26,7 @@ cmd_cont:
|
|||||||
cmd_cmd:
|
cmd_cmd:
|
||||||
cmd_open:
|
cmd_open:
|
||||||
|
|
||||||
;; $A0-$AF
|
// $A0-$AF
|
||||||
cmd_close:
|
cmd_close:
|
||||||
cmd_get:
|
cmd_get:
|
||||||
cmd_tab:
|
cmd_tab:
|
||||||
@@ -43,7 +43,7 @@ cmd_div:
|
|||||||
cmd_exponent:
|
cmd_exponent:
|
||||||
cmd_and:
|
cmd_and:
|
||||||
|
|
||||||
;; $B0-$BF
|
// $B0-$BF
|
||||||
cmd_or:
|
cmd_or:
|
||||||
cmd_greater:
|
cmd_greater:
|
||||||
cmd_equal:
|
cmd_equal:
|
||||||
@@ -61,7 +61,7 @@ cmd_exp:
|
|||||||
cmd_cos:
|
cmd_cos:
|
||||||
cmd_sin:
|
cmd_sin:
|
||||||
|
|
||||||
;; $C0-$CF
|
// $C0-$CF
|
||||||
cmd_tan:
|
cmd_tan:
|
||||||
cmd_atn:
|
cmd_atn:
|
||||||
cmd_peek:
|
cmd_peek:
|
||||||
@@ -74,9 +74,9 @@ cmd_left:
|
|||||||
cmd_right:
|
cmd_right:
|
||||||
cmd_mid:
|
cmd_mid:
|
||||||
cmd_go:
|
cmd_go:
|
||||||
;; Undefined tokens
|
|
||||||
|
// Undefined tokens
|
||||||
cmd_unimplemented:
|
cmd_unimplemented:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
jmp do_NOT_IMPLEMENTED_error
|
jmp do_NOT_IMPLEMENTED_error
|
||||||
+55
-54
@@ -1,48 +1,48 @@
|
|||||||
;; As many errors are triggered from many places in the BASIC
|
// As many errors are triggered from many places in the BASIC
|
||||||
;; interprettor, it is important to have an efficicent means of
|
// interprettor, it is important to have an efficicent means of
|
||||||
;; calling them.
|
// calling them.
|
||||||
;; LDX #$nn / jmp do_basic_error
|
// LDX #$nn / jmp do_basic_error
|
||||||
;; is the simplest, but takes 5 bytes.
|
// is the simplest, but takes 5 bytes.
|
||||||
;; Having a direct JMP address for each error is preferable, as
|
// Having a direct JMP address for each error is preferable, as
|
||||||
;; it reduces the overhead to 3 bytes, but at the cost of having
|
// 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
|
// a jump table of some sort. The .byte $2C method can be used
|
||||||
;; to have a set of addresses that each execute a different
|
// to have a set of addresses that each execute a different
|
||||||
;; LDX #$nn command, reducing the cost of the jump table to 3
|
// LDX #$nn command, reducing the cost of the jump table to 3
|
||||||
;; bytes per error number.
|
// bytes per error number.
|
||||||
;; But we can do better with a bit of scullduggery and carnal
|
// But we can do better with a bit of scullduggery and carnal
|
||||||
;; knowledge of ZP usage.
|
// knowledge of ZP usage.
|
||||||
;; The INC $nn opcode is $E6. ZP location $E6 is one of the screen
|
// 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
|
// link addresses. In the original KERNAL, the lower bits of those
|
||||||
;; addresses have meaning, but in our KERNAL, we ignore them, and just
|
// 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,
|
// 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
|
// 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
|
// 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
|
// 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
|
// opcode with some other address as target, but where the byte value
|
||||||
;; of that argument can be safely executed as a CPU instruction.
|
// of that argument can be safely executed as a CPU instruction.
|
||||||
;; NOP = $EA is the obvious choice, as if used as an argument to
|
// NOP = $EA is the obvious choice, as if used as an argument to
|
||||||
;; $E6 will increment location $EA, which is another of the screen
|
// $E6 will increment location $EA, which is another of the screen
|
||||||
;; link addresses.
|
// link addresses.
|
||||||
|
|
||||||
;; This gives a total overhead of 18 bytes + 1 byte per error
|
// This gives a total overhead of 18 bytes + 1 byte per error
|
||||||
;; message. This compares favourably to the 3 bytes per error
|
// message. This compares favourably to the 3 bytes per error
|
||||||
;; message that the $2C method would result in.
|
// message that the $2C method would result in.
|
||||||
|
|
||||||
do_NOT_IMPLEMENTED_error:
|
do_NOT_IMPLEMENTED_error:
|
||||||
.byte $E6
|
.byte $E6
|
||||||
do_MEMORY_CORRUPT_error:
|
do_MEMORY_CORRUPT_error:
|
||||||
.byte $E6
|
.byte $E6
|
||||||
;; the message "BYTES FREE"
|
// the message "BYTES FREE"
|
||||||
.byte $E6
|
.byte $E6
|
||||||
;; the word ERROR
|
// the word ERROR
|
||||||
.byte $E6
|
.byte $E6
|
||||||
;; The word "SAVING"
|
// The word "SAVING"
|
||||||
.byte $E6
|
.byte $E6
|
||||||
;; The word "VERIFYING"
|
// The word "VERIFYING"
|
||||||
.byte $E6
|
.byte $E6
|
||||||
;; The word "LOADING"
|
// The word "LOADING"
|
||||||
.byte $E6
|
.byte $E6
|
||||||
;; The word "READY."
|
// The word "READY."
|
||||||
.byte $E6
|
.byte $E6
|
||||||
do_LOAD_error:
|
do_LOAD_error:
|
||||||
.byte $E6
|
.byte $E6
|
||||||
@@ -103,69 +103,70 @@ do_FILE_OPEN_error:
|
|||||||
do_TO_MANY_FILES_error:
|
do_TO_MANY_FILES_error:
|
||||||
.byte $EA
|
.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
|
lda $E6
|
||||||
pha
|
pha
|
||||||
and #$80
|
and #$80
|
||||||
sta $E6
|
sta $E6
|
||||||
pla
|
pla
|
||||||
;; $E6 has even part
|
// $E6 has even part
|
||||||
asl
|
asl
|
||||||
ora $EA
|
ora $EA
|
||||||
and #$7f
|
and #$7f
|
||||||
tax
|
tax
|
||||||
|
|
||||||
;; Restore $EA to correct value in case the NOP above is used
|
// Restore $EA to correct value in case the NOP above is used
|
||||||
;; as an argument to the preceeding INC $nn (opcode $E6).
|
// as an argument to the preceeding INC $nn (opcode $E6).
|
||||||
LDA $EA
|
lda $EA
|
||||||
and #$80
|
and #$80
|
||||||
sta $EA
|
sta $EA
|
||||||
|
|
||||||
;; FALL THROUGH
|
// FALL THROUGH
|
||||||
|
|
||||||
;; Error # in X
|
// Error # in X
|
||||||
|
|
||||||
do_basic_error:
|
do_basic_error:
|
||||||
;; "?"
|
// "?"
|
||||||
txa
|
txa
|
||||||
pha
|
pha
|
||||||
lda #$0d
|
lda #$0d
|
||||||
jsr $ffd2
|
jsr JCHROUT
|
||||||
lda #$3f
|
lda #$3f
|
||||||
jsr $ffd2
|
jsr JCHROUT
|
||||||
pla
|
pla
|
||||||
tax
|
tax
|
||||||
|
|
||||||
;; Error message text
|
// Error message text
|
||||||
jsr print_packed_message
|
jsr print_packed_message
|
||||||
|
|
||||||
;; A space between error name and word error
|
// A space between error name and word error
|
||||||
lda #$20
|
lda #$20
|
||||||
jsr $ffd2
|
jsr $ffd2
|
||||||
|
|
||||||
;; "ERROR"
|
// "ERROR"
|
||||||
ldx #33
|
ldx #33
|
||||||
jsr print_packed_message
|
jsr print_packed_message
|
||||||
|
|
||||||
lda basic_current_line_number+1
|
lda basic_current_line_number+1
|
||||||
cmp #$ff
|
cmp #$ff
|
||||||
beq +
|
beq !+
|
||||||
|
|
||||||
;; We were in a program, so show IN <line>
|
// We were in a program, so show IN <line>
|
||||||
jsr printf
|
jsr printf // XXX don't use printf, use packed messages
|
||||||
.byte " IN ",0
|
.text " IN "
|
||||||
|
.byte 0
|
||||||
|
|
||||||
lda basic_current_line_number+1
|
lda basic_current_line_number+1
|
||||||
ldx basic_current_line_number+0
|
ldx basic_current_line_number+0
|
||||||
jsr print_integer
|
jsr print_integer
|
||||||
*
|
!:
|
||||||
;; New lines
|
// New lines
|
||||||
lda #$0d
|
lda #$0d
|
||||||
jsr $ffd2
|
jsr $ffd2
|
||||||
lda #$00
|
lda #$00
|
||||||
jsr $ffd2
|
jsr $ffd2
|
||||||
|
|
||||||
;; XXX - Restore stack depth first?
|
// XXX - Restore stack depth first?
|
||||||
|
|
||||||
jmp basic_main_loop
|
jmp basic_main_loop
|
||||||
|
|
||||||
+26
-26
@@ -1,23 +1,23 @@
|
|||||||
;; Multiply Floating Point Accumulator by 10
|
// Multiply Floating Point Accumulator by 10
|
||||||
;; = 8x + 2x
|
// = 8x + 2x
|
||||||
;; Implement by shifting MAC left one bit,
|
// Implement by shifting MAC left one bit,
|
||||||
;; and then keeping that value to add on after
|
// and then keeping that value to add on after
|
||||||
;; shifting two more bits left.
|
// shifting two more bits left.
|
||||||
;; This should be done using basic_fac1_overflow to
|
// This should be done using basic_fac1_overflow to
|
||||||
;; hold the overflow bits, so that the result can
|
// hold the overflow bits, so that the result can
|
||||||
;; be exponent adjusted after, if required.
|
// be exponent adjusted after, if required.
|
||||||
|
|
||||||
fac1_mul10:
|
fac1_mul10:
|
||||||
lda #$00
|
lda #$00
|
||||||
sta basic_fac1_overflow
|
sta basic_fac1_overflow
|
||||||
|
|
||||||
;; Multiply mantissa by 2
|
// Multiply mantissa by 2
|
||||||
jsr fac1_mantissa_mul2
|
jsr fac1_mantissa_mul2
|
||||||
|
|
||||||
;; copy down to BASIC numeric work area at $57
|
// copy down to BASIC numeric work area at $57
|
||||||
;; (basic_numeric_work_area)
|
// (basic_numeric_work_area)
|
||||||
;; (We copy all 7 bytes off the FAC1, so that we have
|
// (We copy all 7 bytes off the FAC1, so that we have
|
||||||
;; the overflow bits, and the copy is as small as possible)
|
// the overflow bits, and the copy is as small as possible)
|
||||||
ldx #7
|
ldx #7
|
||||||
f1m10_l1:
|
f1m10_l1:
|
||||||
lda basic_fac1_mantissa,x
|
lda basic_fac1_mantissa,x
|
||||||
@@ -25,11 +25,11 @@ f1m10_l1:
|
|||||||
dex
|
dex
|
||||||
bpl f1m10_l1
|
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
|
||||||
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
|
ldy #3
|
||||||
ldx #0
|
ldx #0
|
||||||
clc
|
clc
|
||||||
@@ -44,22 +44,22 @@ f1m10_l2:
|
|||||||
adc basic_numeric_work_area+7
|
adc basic_numeric_work_area+7
|
||||||
sta basic_fac1_overflow
|
sta basic_fac1_overflow
|
||||||
|
|
||||||
;; Now shift right and increase exponent until overflow
|
// Now shift right and increase exponent until overflow
|
||||||
;; bits = $00
|
// bits = $00
|
||||||
f1m10_l3:
|
f1m10_l3:
|
||||||
lda basic_fac1_overflow
|
lda basic_fac1_overflow
|
||||||
bne +
|
bne !+
|
||||||
;; All done, return
|
// All done, return
|
||||||
clc
|
clc
|
||||||
rts
|
rts
|
||||||
*
|
!:
|
||||||
;; Divide mantissa by two, and increment exponent
|
// Divide mantissa by two, and increment exponent
|
||||||
jsr fac1_mantissa_div2
|
jsr fac1_mantissa_div2
|
||||||
inc basic_fac1_exponent
|
inc basic_fac1_exponent
|
||||||
lda basic_fac1_exponent
|
lda basic_fac1_exponent
|
||||||
bpl f1m10_l3
|
bpl f1m10_l3
|
||||||
;; Exponent has bit 7 set, so has wrapped.
|
// Exponent has bit 7 set, so has wrapped.
|
||||||
;; = OVERFLOW ERROR
|
// = OVERFLOW ERROR
|
||||||
jmp do_OVERFLOW_error
|
jmp do_OVERFLOW_error
|
||||||
|
|
||||||
fac1_mantissa_mul2:
|
fac1_mantissa_mul2:
|
||||||
@@ -67,8 +67,8 @@ fac1_mantissa_mul2:
|
|||||||
ldx #0
|
ldx #0
|
||||||
clc
|
clc
|
||||||
f1m1_l1:
|
f1m1_l1:
|
||||||
;; Multiply mantissa by 2, and store overflow
|
// Multiply mantissa by 2, and store overflow
|
||||||
;; in basic_fac1_bits
|
// in basic_fac1_bits
|
||||||
lda basic_fac1_mantissa,x
|
lda basic_fac1_mantissa,x
|
||||||
rol
|
rol
|
||||||
sta basic_fac1_mantissa,x
|
sta basic_fac1_mantissa,x
|
||||||
@@ -82,7 +82,7 @@ f1m1_l1:
|
|||||||
rts
|
rts
|
||||||
|
|
||||||
fac1_mantissa_div2:
|
fac1_mantissa_div2:
|
||||||
;; Divide mantissa by 2, including using overflow bits
|
// Divide mantissa by 2, including using overflow bits
|
||||||
clc
|
clc
|
||||||
lda basic_fac1_overflow
|
lda basic_fac1_overflow
|
||||||
ror
|
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:
|
injest_comma:
|
||||||
|
|
||||||
jsr basic_fetch_and_consume_character
|
jsr basic_fetch_and_consume_character
|
||||||
cmp #$2C ; comma character
|
cmp #$2C // comma character
|
||||||
beq injest_comma_found
|
beq injest_comma_found
|
||||||
cmp #$20
|
cmp #$20 // space, can always be skipped
|
||||||
beq injest_comma ; space, can always be skipped
|
beq injest_comma
|
||||||
|
|
||||||
;; not found
|
// not found
|
||||||
jsr basic_unconsume_character
|
jsr basic_unconsume_character
|
||||||
sec
|
sec
|
||||||
rts
|
rts
|
||||||
@@ -17,4 +17,3 @@ injest_comma:
|
|||||||
injest_comma_found:
|
injest_comma_found:
|
||||||
clc
|
clc
|
||||||
rts
|
rts
|
||||||
|
|
||||||
+50
-51
@@ -1,37 +1,37 @@
|
|||||||
;; Parse a number from the input buffer at (basic_current_statement_ptr)
|
// Parse a number from the input buffer at (basic_current_statement_ptr)
|
||||||
;; Result is put into FAC1.
|
// Result is put into FAC1.
|
||||||
;; basic_current_statement_ptr is updated with first position after the number.
|
// basic_current_statement_ptr is updated with first position after the number.
|
||||||
|
|
||||||
;; XXX - Remember decimal position and exponent, and apply them
|
// XXX - Remember decimal position and exponent, and apply them
|
||||||
;; after to produce normalised floating point number.
|
// after to produce normalised floating point number.
|
||||||
|
|
||||||
;; XXX - Doesn't use routines to access memory under ROMs etc.
|
// XXX - Doesn't use routines to access memory under ROMs etc.
|
||||||
;; This is important, because this routine operates on numbers in BASIC text.
|
// This is important, because this routine operates on numbers in BASIC text.
|
||||||
|
|
||||||
ij_not_a_digit:
|
ij_not_a_digit:
|
||||||
;; XXX check for "." or "E"
|
// XXX check for "." or "E"
|
||||||
;; Other chars terminate the accumulation.
|
// Other chars terminate the accumulation.
|
||||||
|
|
||||||
;; Look for exponentiation marker
|
// Look for exponentiation marker
|
||||||
;; XXX - Implement me!
|
// XXX - Implement me!
|
||||||
;; Probably should have a flag so that we know if we are accumulating
|
// Probably should have a flag so that we know if we are accumulating
|
||||||
;; exponent or mantissa digits
|
// exponent or mantissa digits
|
||||||
|
|
||||||
;; Look for decimal point
|
// Look for decimal point
|
||||||
cmp #$2e
|
cmp #$2e
|
||||||
bne ij_not_decimal
|
bne ij_not_decimal
|
||||||
lda tokenise_work4
|
lda tokenise_work4
|
||||||
cmp #$ff
|
cmp #$ff
|
||||||
beq ij_found_decimal
|
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
|
clc
|
||||||
rts
|
rts
|
||||||
|
|
||||||
ij_found_decimal:
|
ij_found_decimal:
|
||||||
;; Found decimal.
|
// Found decimal.
|
||||||
;; Thus start counting digits after the decimal, so that we
|
// Thus start counting digits after the decimal, so that we
|
||||||
;; can do the necessary number of divide by 10s on the final
|
// can do the necessary number of divide by 10s on the final
|
||||||
;; number.
|
// number.
|
||||||
lda #$00
|
lda #$00
|
||||||
sta tokenise_work4
|
sta tokenise_work4
|
||||||
|
|
||||||
@@ -39,31 +39,30 @@ ij_found_decimal:
|
|||||||
|
|
||||||
ij_not_decimal:
|
ij_not_decimal:
|
||||||
|
|
||||||
|
clc
|
||||||
CLC
|
rts
|
||||||
RTS
|
|
||||||
|
|
||||||
injest_number:
|
injest_number:
|
||||||
;; Clear FAC1
|
// Clear FAC1
|
||||||
jsr erase_fac1
|
jsr erase_fac1
|
||||||
|
|
||||||
;; Clear decimal position flag
|
// Clear decimal position flag
|
||||||
lda #$ff
|
lda #$ff
|
||||||
sta tokenise_work4
|
sta tokenise_work4
|
||||||
|
|
||||||
;; Check if leading char is a - sign
|
// Check if leading char is a - sign
|
||||||
;; Note: the - will have been tokenised to $AB
|
// Note: the - will have been tokenised to $AB
|
||||||
;; XXX - implement
|
// XXX - implement
|
||||||
ldy #$00
|
ldy #$00
|
||||||
lda (basic_current_statement_ptr),y
|
lda (basic_current_statement_ptr),y
|
||||||
cmp #$AB
|
cmp #$AB
|
||||||
bne ij_not_minus
|
bne ij_not_minus
|
||||||
|
|
||||||
;; Set sign to negative
|
// Set sign to negative
|
||||||
lda #$ff
|
lda #$ff
|
||||||
sta basic_fac1_sign
|
sta basic_fac1_sign
|
||||||
|
|
||||||
;; Skip over the minus sign
|
// Skip over the minus sign
|
||||||
jsr basic_consume_character
|
jsr basic_consume_character
|
||||||
|
|
||||||
ij_not_minus:
|
ij_not_minus:
|
||||||
@@ -77,43 +76,43 @@ ij_loop1:
|
|||||||
cmp #$3a
|
cmp #$3a
|
||||||
bcs ij_not_a_digit
|
bcs ij_not_a_digit
|
||||||
|
|
||||||
;; It is a digit
|
// It is a digit
|
||||||
|
|
||||||
;; Only add digit if we have not overflowed the accuracy of
|
// Only add digit if we have not overflowed the accuracy of
|
||||||
;; the mantissa
|
// the mantissa
|
||||||
lda basic_fac1_exponent
|
lda basic_fac1_exponent
|
||||||
beq ij_accept_precision
|
beq ij_accept_precision
|
||||||
|
|
||||||
;; We have an extra digit after saturating our precision.
|
// We have an extra digit after saturating our precision.
|
||||||
;; Thus we should ignore the digit, and just multiply the FAC
|
// Thus we should ignore the digit, and just multiply the FAC
|
||||||
;; by 10, but only if we have not seen a decimal point.
|
// by 10, but only if we have not seen a decimal point.
|
||||||
;; If we have seen a decimal point, then we can completely ignore
|
// If we have seen a decimal point, then we can completely ignore
|
||||||
;; the digit, as it is contributing not recordable information
|
// the digit, as it is contributing not recordable information
|
||||||
|
|
||||||
lda tokenise_work4
|
lda tokenise_work4
|
||||||
cmp #$ff
|
cmp #$ff
|
||||||
bne ij_seen_decimal_point
|
bne ij_seen_decimal_point
|
||||||
|
|
||||||
jsr fac1_mul10
|
jsr fac1_mul10
|
||||||
;; Fall through
|
// Fall through
|
||||||
ij_seen_decimal_point:
|
ij_seen_decimal_point:
|
||||||
jmp ij_consider_next_digit
|
jmp ij_consider_next_digit
|
||||||
|
|
||||||
ij_accept_precision:
|
ij_accept_precision:
|
||||||
;; We can accept more precision, so multiply the mantissa by 10, so that
|
// We can accept more precision, so multiply the mantissa by 10, so that
|
||||||
;; we can add the new digit in
|
// we can add the new digit in
|
||||||
jsr fac1_mul10
|
jsr fac1_mul10
|
||||||
|
|
||||||
lda basic_fac1_exponent
|
lda basic_fac1_exponent
|
||||||
bne ij_consider_next_digit
|
bne ij_consider_next_digit
|
||||||
|
|
||||||
;; Get digit
|
// Get digit
|
||||||
ldy #$00
|
ldy #$00
|
||||||
lda (basic_current_statement_ptr),y
|
lda (basic_current_statement_ptr),y
|
||||||
sec
|
sec
|
||||||
sbc #$30
|
sbc #$30
|
||||||
|
|
||||||
;; Add to FAC1 mantissa
|
// Add to FAC1 mantissa
|
||||||
clc
|
clc
|
||||||
adc basic_fac1_mantissa+0
|
adc basic_fac1_mantissa+0
|
||||||
sta basic_fac1_mantissa+0
|
sta basic_fac1_mantissa+0
|
||||||
@@ -127,16 +126,16 @@ ij_loop2:
|
|||||||
dey
|
dey
|
||||||
bne ij_loop2
|
bne ij_loop2
|
||||||
|
|
||||||
bcc +
|
bcc !+
|
||||||
;; Carry set, so we have overflowed.
|
// Carry set, so we have overflowed.
|
||||||
;; We should shift everything right one digit, and increase
|
// We should shift everything right one digit, and increase
|
||||||
;; the exponent by one. The non-zero exponent tells us that we
|
// the exponent by one. The non-zero exponent tells us that we
|
||||||
;; can't fit any more precision in.
|
// can't fit any more precision in.
|
||||||
jsr fac1_mantissa_div2
|
jsr fac1_mantissa_div2
|
||||||
*
|
!:
|
||||||
|
|
||||||
ij_consider_next_digit:
|
ij_consider_next_digit:
|
||||||
;; Consider next digit
|
// Consider next digit
|
||||||
jsr basic_consume_character
|
jsr basic_consume_character
|
||||||
jmp ij_loop1
|
jmp ij_loop1
|
||||||
|
|
||||||
@@ -146,10 +145,10 @@ ij_consider_next_digit:
|
|||||||
erase_fac1:
|
erase_fac1:
|
||||||
lda #$00
|
lda #$00
|
||||||
ldx #8
|
ldx #8
|
||||||
*
|
!:
|
||||||
sta basic_fac1_exponent,x
|
sta basic_fac1_exponent,x
|
||||||
dex
|
dex
|
||||||
bpl -
|
bpl !-
|
||||||
sta basic_fac1_mantissa_lob
|
sta basic_fac1_mantissa_lob
|
||||||
|
|
||||||
rts
|
rts
|
||||||
|
|||||||
+88
-87
@@ -1,76 +1,77 @@
|
|||||||
;; Pack a word using the simple compression scheme.
|
// Pack a word using the simple compression scheme.
|
||||||
;; This has to be the same implementation as in compress_text.c
|
// This has to be the same implementation as in compress_text.c
|
||||||
;; because we compress input lines of BASIC to do the tokenisation.
|
// because we compress input lines of BASIC to do the tokenisation.
|
||||||
;; This allows us to search through the compressed tokens directly
|
// This allows us to search through the compressed tokens directly
|
||||||
;; using the compressed fragment of BASIC, and thus work out the
|
// using the compressed fragment of BASIC, and thus work out the
|
||||||
;; token for a given piece of string.
|
// token for a given piece of string.
|
||||||
;; This also helps ensure that we have an implementation that is totally
|
// This also helps ensure that we have an implementation that is totally
|
||||||
;; different to that of the original C64 BASIC, as well as likely
|
// 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
|
// 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
|
// larger keyword vocabs for BASIC 7 or BASIC 10 compatibility, since the
|
||||||
;; compression and decompression machinery is of fixed size.
|
// compression and decompression machinery is of fixed size.
|
||||||
|
|
||||||
pack_word:
|
pack_word:
|
||||||
;; Inputs:
|
// Inputs:
|
||||||
;; X = offset of string to pack. Address is $0200 + X
|
// X = offset of string to pack. Address is $0200 + X
|
||||||
;; tokenise_work1 = number of bytes to pack
|
// tokenise_work1 = number of bytes to pack
|
||||||
;; tokenise_work2 = packed length of string
|
// tokenise_work2 = packed length of string
|
||||||
|
|
||||||
;; Outputs:
|
// Outputs:
|
||||||
;; Output is written to $0100 (bottom of stack).
|
// Output is written to $0100 (bottom of stack).
|
||||||
|
|
||||||
;; Memory modified:
|
// Memory modified:
|
||||||
;; tokenise_work4 = temporary storage
|
// tokenise_work4 = temporary storage
|
||||||
;; tokenise_work3 = flag for whether we have a nybl prepared or not.
|
// 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
|
// (This can also be checked on exit, to know whether the last byte
|
||||||
;; is incomplete, which is important for searching for abbreviated
|
// is incomplete, which is important for searching for abbreviated
|
||||||
;; key words.)
|
// key words.)
|
||||||
|
|
||||||
|
|
||||||
;; Make sure we have a sane request
|
// Make sure we have a sane request
|
||||||
lda tokenise_work1
|
lda tokenise_work1
|
||||||
bne +
|
bne !+
|
||||||
sec
|
sec
|
||||||
rts
|
rts
|
||||||
*
|
!:
|
||||||
;; Initialise internal variables
|
// Initialise internal variables
|
||||||
lda #$00
|
lda #$00
|
||||||
sta tokenise_work2
|
sta tokenise_work2
|
||||||
sta tokenise_work3
|
sta tokenise_work3
|
||||||
|
|
||||||
pack_char_loop:
|
pack_char_loop:
|
||||||
|
|
||||||
;; Get the next char
|
// Get the next char
|
||||||
lda $0200,x
|
lda $0200,x
|
||||||
|
|
||||||
;; Work out what type of character we have, and thus
|
// Work out what type of character we have, and thus
|
||||||
;; how we need to pack it.
|
// how we need to pack it.
|
||||||
jsr get_packed_char_index
|
jsr get_packed_char_index
|
||||||
|
|
||||||
cmp #$00
|
cmp #$00
|
||||||
bne not_exception_char
|
bne not_exception_char
|
||||||
|
|
||||||
;; Char is an exception char.
|
// Char is an exception char.
|
||||||
;; We need to either finish the previous byte with $xF,
|
// We need to either finish the previous byte with $xF,
|
||||||
;; Or if there is no existing nybl, then we need to output
|
// Or if there is no existing nybl, then we need to output
|
||||||
;; either $FE or $FF, depending on whether this is the last
|
// either $FE or $FF, depending on whether this is the last
|
||||||
;; byte or not
|
// byte or not
|
||||||
|
|
||||||
lda tokenise_work3
|
lda tokenise_work3
|
||||||
bne have_nybl_before_exception_char
|
bne have_nybl_before_exception_char
|
||||||
|
|
||||||
;; No nybl exists before the exception char, so prefix with $FE or $FF
|
// 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
|
// based on whether we are at the end of the input string or not
|
||||||
inx
|
inx
|
||||||
lda tokenise_work1
|
lda tokenise_work1
|
||||||
cmp #$01
|
cmp #$01
|
||||||
beq at_end
|
beq at_end
|
||||||
lda #$FF
|
lda #$FF
|
||||||
.byte $2C
|
.byte $2C
|
||||||
at_end: LDA #$FE
|
at_end:
|
||||||
|
lda #$FE
|
||||||
dex
|
dex
|
||||||
jsr write_unpacked_char
|
jsr write_unpacked_char
|
||||||
;; Fall through
|
// Fall through
|
||||||
|
|
||||||
output_exception_byte:
|
output_exception_byte:
|
||||||
lda $0200,x
|
lda $0200,x
|
||||||
@@ -78,18 +79,18 @@ output_exception_byte:
|
|||||||
jmp consider_next_char
|
jmp consider_next_char
|
||||||
|
|
||||||
have_nybl_before_exception_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
|
ldy tokenise_work2
|
||||||
lda $0100,y
|
lda $0100,y
|
||||||
ora #$0f
|
ora #$0f
|
||||||
sta $0100,y
|
sta $0100,y
|
||||||
inc tokenise_work2
|
inc tokenise_work2
|
||||||
|
|
||||||
;; FALL THROUGH
|
// FALL THROUGH
|
||||||
|
|
||||||
write_literal_and_terminate_if_required:
|
write_literal_and_terminate_if_required:
|
||||||
|
|
||||||
;; Clear have nybl flag
|
// Clear have nybl flag
|
||||||
lda #$00
|
lda #$00
|
||||||
sta tokenise_work3
|
sta tokenise_work3
|
||||||
|
|
||||||
@@ -99,19 +100,19 @@ write_literal_and_terminate_if_required:
|
|||||||
jmp end_string_if_required
|
jmp end_string_if_required
|
||||||
|
|
||||||
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
|
inx
|
||||||
lda tokenise_work1
|
lda tokenise_work1
|
||||||
cmp #$01
|
cmp #$01
|
||||||
beq +
|
beq !+
|
||||||
dex
|
dex
|
||||||
jmp consider_next_char
|
jmp consider_next_char
|
||||||
*
|
!:
|
||||||
dex
|
dex
|
||||||
;; Fall through
|
// Fall through
|
||||||
|
|
||||||
end_string:
|
end_string:
|
||||||
;; Write end of string sequence if required
|
// Write end of string sequence if required
|
||||||
lda #$00
|
lda #$00
|
||||||
jsr write_unpacked_char
|
jsr write_unpacked_char
|
||||||
rts
|
rts
|
||||||
@@ -124,53 +125,53 @@ write_unpacked_char:
|
|||||||
rts
|
rts
|
||||||
|
|
||||||
not_exception_char:
|
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
|
cmp #$10
|
||||||
bcs whole_byte_symbol
|
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
|
ldy tokenise_work3
|
||||||
bne store_low_nybl
|
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
|
||||||
asl
|
asl
|
||||||
asl
|
asl
|
||||||
ldy tokenise_work2
|
ldy tokenise_work2
|
||||||
sta $0100,y
|
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:
|
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
|
ldy tokenise_work2
|
||||||
ora $0100,y
|
ora $0100,y
|
||||||
sta $0100,y
|
sta $0100,y
|
||||||
|
|
||||||
stored_nybl:
|
stored_nybl:
|
||||||
;; Now toggle the nybl flag
|
// Now toggle the nybl flag
|
||||||
lda tokenise_work3
|
lda tokenise_work3
|
||||||
eor #$ff
|
eor #$ff
|
||||||
sta tokenise_work3
|
sta tokenise_work3
|
||||||
;; And advance the offset if we filled this byte up
|
// 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
|
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
|
inc tokenise_work2
|
||||||
|
|
||||||
;; Add termination byte if required
|
// Add termination byte if required
|
||||||
;; (This re-writes the same byte again, which we don't care about)
|
// (This re-writes the same byte again, which we don't care about)
|
||||||
jmp end_string_if_required
|
jmp end_string_if_required
|
||||||
|
|
||||||
whole_byte_symbol:
|
whole_byte_symbol:
|
||||||
;; It's a $Fx symbol.
|
// It's a $Fx symbol.
|
||||||
;; But if we have a nybl to flush, then we handle it like
|
// But if we have a nybl to flush, then we handle it like
|
||||||
;; a full exception character
|
// a full exception character
|
||||||
|
|
||||||
ldy tokenise_work3
|
ldy tokenise_work3
|
||||||
beq nothing_to_flush
|
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
|
ldy tokenise_work2
|
||||||
lda $0100,y
|
lda $0100,y
|
||||||
ora #$0f
|
ora #$0f
|
||||||
@@ -180,30 +181,30 @@ whole_byte_symbol:
|
|||||||
jmp write_literal_and_terminate_if_required
|
jmp write_literal_and_terminate_if_required
|
||||||
|
|
||||||
nothing_to_flush:
|
nothing_to_flush:
|
||||||
;; Write the symbol as it is, or the literal
|
// Write the symbol as it is, or the literal
|
||||||
;; if it has been passed to us via fall-through
|
// if it has been passed to us via fall-through
|
||||||
jsr write_unpacked_char
|
jsr write_unpacked_char
|
||||||
|
|
||||||
jmp end_string_if_required
|
jmp end_string_if_required
|
||||||
|
|
||||||
consider_next_char:
|
consider_next_char:
|
||||||
;; Pack next char
|
// Pack next char
|
||||||
inx
|
inx
|
||||||
dec tokenise_work1
|
dec tokenise_work1
|
||||||
beq +
|
beq !+
|
||||||
jmp pack_char_loop
|
jmp pack_char_loop
|
||||||
*
|
!:
|
||||||
;; Add 1 to length if nybl waiting to be flushed
|
// Add 1 to length if nybl waiting to be flushed
|
||||||
;; (but leave flag set so the caller knows if the
|
// (but leave flag set so the caller knows if the
|
||||||
;; bottom nybl might be different if the string were
|
// bottom nybl might be different if the string were
|
||||||
;; longer).
|
// longer).
|
||||||
lda tokenise_work3
|
lda tokenise_work3
|
||||||
beq +
|
beq !+
|
||||||
inc tokenise_work2
|
inc tokenise_work2
|
||||||
rts
|
rts
|
||||||
*
|
!:
|
||||||
;; Last byte was full, so we need at $00 on the end
|
// Last byte was full, so we need at $00 on the end
|
||||||
;; (unless a $FE token was written 2 bytes ago)
|
// (unless a $FE token was written 2 bytes ago)
|
||||||
ldy tokenise_work2
|
ldy tokenise_work2
|
||||||
iny
|
iny
|
||||||
lda #$00
|
lda #$00
|
||||||
@@ -213,21 +214,21 @@ consider_next_char:
|
|||||||
rts
|
rts
|
||||||
|
|
||||||
get_packed_char_index:
|
get_packed_char_index:
|
||||||
;; Find char in A in the packed char list, and return
|
// Find char in A in the packed char list, and return
|
||||||
;; $1 - $E, $F1 - $FD if the charactar is abbreviable,
|
// $1 - $E, $F1 - $FD if the charactar is abbreviable,
|
||||||
;; or else return $00 if the character has to be stored literally.
|
// 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
|
ldy #$00
|
||||||
find_char_loop:
|
find_char_loop:
|
||||||
cmp packed_message_chars,y
|
cmp packed_message_chars,y
|
||||||
bne not_a_match
|
bne not_a_match
|
||||||
enumerate:
|
enumerate:
|
||||||
;; Is it a nybl abbreviable char?
|
// Is it a nybl abbreviable char?
|
||||||
cpy #14
|
cpy #14
|
||||||
bcs not_nybl_char
|
bcs not_nybl_char
|
||||||
;; Yes, so add 1 and return it
|
// Yes, so add 1 and return it
|
||||||
iny
|
iny
|
||||||
tya
|
tya
|
||||||
rts
|
rts
|
||||||
@@ -235,9 +236,9 @@ enumerate:
|
|||||||
not_nybl_char:
|
not_nybl_char:
|
||||||
cpy #27
|
cpy #27
|
||||||
bcs not_a_match
|
bcs not_a_match
|
||||||
;; It's a $Fx character.
|
// It's a $Fx character.
|
||||||
;; Since the lowest index is $E, and it should be encoded as $F1
|
// Since the lowest index is $E, and it should be encoded as $F1
|
||||||
;; we need to add $E3
|
// we need to add $E3
|
||||||
tya
|
tya
|
||||||
clc
|
clc
|
||||||
adc #$E3
|
adc #$E3
|
||||||
@@ -245,10 +246,10 @@ not_nybl_char:
|
|||||||
|
|
||||||
not_a_match:
|
not_a_match:
|
||||||
iny
|
iny
|
||||||
;; Loop until we find it, or we discover it isn't
|
// Loop until we find it, or we discover it isn't
|
||||||
;; a character with a special encoding
|
// a character with a special encoding
|
||||||
cpy #27
|
cpy #27
|
||||||
bne find_char_loop
|
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
|
lda #$00
|
||||||
rts
|
rts
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
;; Return C=1 if a pointer in BASIC memory space is NULL, else C=0
|
// Return C=1 if a pointer in BASIC memory space is NULL, else C=0
|
||||||
;; X = ZP pointer to check
|
// X = ZP pointer to check
|
||||||
|
|
||||||
peek_pointer_null_check:
|
peek_pointer_null_check:
|
||||||
ldy #$00
|
ldy #$00
|
||||||
@@ -11,7 +11,7 @@ peek_pointer_null_check:
|
|||||||
cmp #$00
|
cmp #$00
|
||||||
bne ptr_not_null
|
bne ptr_not_null
|
||||||
|
|
||||||
;; Pointer is NULL
|
// Pointer is NULL
|
||||||
clc
|
clc
|
||||||
rts
|
rts
|
||||||
ptr_not_null:
|
ptr_not_null:
|
||||||
|
|||||||
+23
-22
@@ -1,26 +1,27 @@
|
|||||||
;; Works similar to $BDCD in original C64 BASIC
|
// Works similar to $BDCD in original C64 BASIC
|
||||||
;; XXX Should eventually get replaced by a more flexible and optimal routine.
|
// XXX Should eventually get replaced by a more flexible and optimal routine.
|
||||||
;; Temp result gets written to $0100-$0104
|
// Temp result gets written to $0100-$0104
|
||||||
|
|
||||||
print_integer:
|
print_integer:
|
||||||
|
|
||||||
pha
|
pha
|
||||||
txa
|
txa
|
||||||
pha
|
pha
|
||||||
|
|
||||||
;; Clear temporary output
|
// Clear temporary output
|
||||||
lda #$00
|
lda #$00
|
||||||
ldy #5
|
ldy #5
|
||||||
* sta $0100,y
|
!: sta $0100,y
|
||||||
dey
|
dey
|
||||||
bpl -
|
bpl !-
|
||||||
|
|
||||||
pla
|
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:
|
lo_loop:
|
||||||
cmp #$7f
|
cmp #$7f
|
||||||
bcc bit_clear
|
bcc bit_clear
|
||||||
|
|
||||||
;; Bit set, so add the digits
|
// Bit set, so add the digits
|
||||||
pha
|
pha
|
||||||
ldx #2
|
ldx #2
|
||||||
clc
|
clc
|
||||||
@@ -45,16 +46,16 @@ next_lo_bit:
|
|||||||
bcc lo_loop
|
bcc lo_loop
|
||||||
|
|
||||||
|
|
||||||
;; Now do the same for upper byte
|
// Now do the same for upper byte
|
||||||
pla
|
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:
|
hi_loop:
|
||||||
cmp #$7f
|
cmp #$7f
|
||||||
bcc bit_clear_hi
|
bcc bit_clear_hi
|
||||||
|
|
||||||
|
|
||||||
;; Bit set, so add the digits
|
// Bit set, so add the digits
|
||||||
pha
|
pha
|
||||||
ldx #4
|
ldx #4
|
||||||
clc
|
clc
|
||||||
@@ -82,12 +83,12 @@ next_hi_bit:
|
|||||||
|
|
||||||
fix_carry:
|
fix_carry:
|
||||||
|
|
||||||
;; Deal with any carries
|
// Deal with any carries
|
||||||
ldx #3
|
ldx #3
|
||||||
carry_fix_loop:
|
carry_fix_loop:
|
||||||
lda $0101,x
|
lda $0101,x
|
||||||
cmp #10
|
cmp #10
|
||||||
bcc +
|
bcc !+
|
||||||
inc $0100,x
|
inc $0100,x
|
||||||
sec
|
sec
|
||||||
sbc #10
|
sbc #10
|
||||||
@@ -95,30 +96,30 @@ carry_fix_loop:
|
|||||||
|
|
||||||
jmp carry_fix_loop
|
jmp carry_fix_loop
|
||||||
|
|
||||||
* dex
|
!: dex
|
||||||
bpl carry_fix_loop
|
bpl carry_fix_loop
|
||||||
|
|
||||||
post_carry:
|
post_carry:
|
||||||
|
|
||||||
;; Got digits.
|
// Got digits.
|
||||||
;; Skip leading zeros, and print the resulting number
|
// Skip leading zeros, and print the resulting number
|
||||||
|
|
||||||
;; Skip leading zeros
|
// Skip leading zeros
|
||||||
ldy #0
|
ldy #0
|
||||||
* lda $0100,y
|
!: lda $0100,y
|
||||||
bne found_start_of_number
|
bne found_start_of_number
|
||||||
iny
|
iny
|
||||||
cpy #4
|
cpy #4
|
||||||
bne -
|
bne !-
|
||||||
|
|
||||||
found_start_of_number:
|
found_start_of_number:
|
||||||
;; Print digits
|
// Print digits
|
||||||
* lda $0100,y
|
!: lda $0100,y
|
||||||
ora #$30
|
ora #$30
|
||||||
jsr JCHROUT
|
jsr JCHROUT
|
||||||
iny
|
iny
|
||||||
cpy #5
|
cpy #5
|
||||||
bne -
|
bne !-
|
||||||
|
|
||||||
|
|
||||||
rts
|
rts
|
||||||
|
|||||||
@@ -1,16 +1,17 @@
|
|||||||
;; This routine prints messages that have been packed
|
// This routine prints messages that have been packed
|
||||||
;; using the make_error_tables program.
|
// using the make_error_tables program.
|
||||||
;; The general idea is to save space in the ROM.
|
// 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:
|
print_packed_message:
|
||||||
;; X = message number
|
// .X = message number
|
||||||
|
|
||||||
lda #$ff
|
lda #$ff
|
||||||
ldy #$ff
|
ldy #$ff
|
||||||
@@ -20,22 +21,22 @@ packed_message_search:
|
|||||||
beq found_message_in_token_stream
|
beq found_message_in_token_stream
|
||||||
lda packed_message_tokens,y
|
lda packed_message_tokens,y
|
||||||
cmp #$ff
|
cmp #$ff
|
||||||
bne +
|
bne !+
|
||||||
dex
|
dex
|
||||||
*
|
!:
|
||||||
cpy #$ff
|
cpy #$ff
|
||||||
bne packed_message_search
|
bne packed_message_search
|
||||||
;; Could not find message
|
// Could not find message
|
||||||
sec
|
sec
|
||||||
rts
|
rts
|
||||||
|
|
||||||
found_message_in_token_stream:
|
found_message_in_token_stream:
|
||||||
;; Now print each word in the message
|
// Now print each word in the message
|
||||||
tya
|
tya
|
||||||
pha
|
pha
|
||||||
lda packed_message_tokens,y
|
lda packed_message_tokens,y
|
||||||
cmp #$ff
|
cmp #$ff
|
||||||
beq +
|
beq !+
|
||||||
jsr print_packed_word
|
jsr print_packed_word
|
||||||
lda #$20
|
lda #$20
|
||||||
jsr JCHROUT
|
jsr JCHROUT
|
||||||
@@ -43,50 +44,50 @@ found_message_in_token_stream:
|
|||||||
tay
|
tay
|
||||||
iny
|
iny
|
||||||
bne found_message_in_token_stream
|
bne found_message_in_token_stream
|
||||||
*
|
!:
|
||||||
pla
|
pla
|
||||||
;; Rub out space at the end
|
// Rub out space at the end
|
||||||
lda #$14
|
lda #$14
|
||||||
jsr JCHROUT
|
jsr JCHROUT
|
||||||
rts
|
rts
|
||||||
|
|
||||||
print_packed_word:
|
print_packed_word:
|
||||||
;; A = the word to print
|
// A = the word to print
|
||||||
tax
|
tax
|
||||||
|
|
||||||
;; Setup pointer to packed words
|
// Setup pointer to packed words
|
||||||
lda #<packed_message_words
|
lda #<packed_message_words
|
||||||
sta temp_string_ptr+0
|
sta temp_string_ptr+0
|
||||||
lda #>packed_message_words
|
lda #>packed_message_words
|
||||||
sta temp_string_ptr+1
|
sta temp_string_ptr+1
|
||||||
|
|
||||||
;; Find the word in the list
|
// Find the word in the list
|
||||||
ldy #$ff
|
ldy #$ff
|
||||||
packed_word_search:
|
packed_word_search:
|
||||||
iny
|
iny
|
||||||
cpx #$00
|
cpx #$00
|
||||||
beq found_packed_word
|
beq found_packed_word
|
||||||
|
|
||||||
;; $x0 is an end of work marker
|
// $x0 is an end of work marker
|
||||||
lda (temp_string_ptr),y
|
lda (temp_string_ptr),y
|
||||||
and #$0f
|
and #$0f
|
||||||
cmp #$00
|
cmp #$00
|
||||||
bne +
|
bne !+
|
||||||
dex
|
dex
|
||||||
*
|
!:
|
||||||
;; $FE $xx is an end of work marker
|
// $FE $xx is an end of work marker
|
||||||
lda (temp_string_ptr),y
|
lda (temp_string_ptr),y
|
||||||
cmp #$fe
|
cmp #$fe
|
||||||
bne +
|
bne !+
|
||||||
dex
|
dex
|
||||||
iny ; skip next byte
|
iny // skip next byte
|
||||||
*
|
!:
|
||||||
cmp #$ff
|
cmp #$ff
|
||||||
bne +
|
bne !+
|
||||||
iny ; skip next byte
|
iny // skip next byte
|
||||||
*
|
!:
|
||||||
|
|
||||||
;; Advance to next page if required
|
// Advance to next page if required
|
||||||
cpy #$ff
|
cpy #$ff
|
||||||
bne packed_word_search
|
bne packed_word_search
|
||||||
inc temp_string_ptr+1
|
inc temp_string_ptr+1
|
||||||
@@ -94,8 +95,8 @@ packed_word_search:
|
|||||||
|
|
||||||
found_packed_word:
|
found_packed_word:
|
||||||
|
|
||||||
;; Get pointer to start of packed word
|
// Get pointer to start of packed word
|
||||||
;; Make sure we don't wrap on a page boundary
|
// Make sure we don't wrap on a page boundary
|
||||||
tya
|
tya
|
||||||
clc
|
clc
|
||||||
adc temp_string_ptr+0
|
adc temp_string_ptr+0
|
||||||
@@ -108,10 +109,10 @@ print_packed_string:
|
|||||||
ldy #$ff
|
ldy #$ff
|
||||||
|
|
||||||
next_packed_word_char:
|
next_packed_word_char:
|
||||||
;; Y = offset into packed word data - 1
|
// .Y = offset into packed word data - 1
|
||||||
iny
|
iny
|
||||||
|
|
||||||
;; Check for end of word
|
// Check for end of word
|
||||||
lda (temp_string_ptr),y
|
lda (temp_string_ptr),y
|
||||||
cmp #$00
|
cmp #$00
|
||||||
beq end_of_packed_word
|
beq end_of_packed_word
|
||||||
@@ -122,31 +123,31 @@ next_packed_word_char:
|
|||||||
and #$f0
|
and #$f0
|
||||||
beq end_of_packed_word
|
beq end_of_packed_word
|
||||||
|
|
||||||
;; Check if it is an uncommon char
|
// Check if it is an uncommon char
|
||||||
lda (temp_string_ptr),y
|
lda (temp_string_ptr),y
|
||||||
and #$f0
|
and #$f0
|
||||||
cmp #$f0
|
cmp #$f0
|
||||||
beq is_uncommon_char
|
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
|
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
|
||||||
lsr
|
lsr
|
||||||
lsr
|
lsr
|
||||||
tax
|
tax
|
||||||
|
|
||||||
;; Save Y so it doesn't get clobbered by CHROUT
|
// Save Y so it doesn't get clobbered by CHROUT
|
||||||
tya
|
tya
|
||||||
pha
|
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
|
lda packed_message_chars-1,x
|
||||||
jsr JCHROUT
|
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
|
pla
|
||||||
tay
|
tay
|
||||||
lda (temp_string_ptr),y
|
lda (temp_string_ptr),y
|
||||||
@@ -156,31 +157,31 @@ next_packed_word_char:
|
|||||||
beq no_lo_nybl_char
|
beq no_lo_nybl_char
|
||||||
|
|
||||||
has_lo_nybl_char:
|
has_lo_nybl_char:
|
||||||
;; We need to print the low nybl char as well
|
// We need to print the low nybl char as well
|
||||||
tax
|
tax
|
||||||
tya
|
tya
|
||||||
pha
|
pha
|
||||||
|
|
||||||
;; Skip lower nybls of $F or $0 in nybl packed
|
// Skip lower nybls of $F or $0 in nybl packed
|
||||||
;; bytes, as these do not encode characters
|
// bytes, as these do not encode characters
|
||||||
cpx #$f
|
cpx #$f
|
||||||
beq +
|
beq !+
|
||||||
has_nybl:
|
has_nybl:
|
||||||
cpx #0
|
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
|
lda packed_message_chars-1,x
|
||||||
jsr JCHROUT
|
jsr JCHROUT
|
||||||
*
|
!:
|
||||||
pla
|
pla
|
||||||
tay
|
tay
|
||||||
;; FALL THROUGH
|
// FALLTHROUGH
|
||||||
|
|
||||||
no_lo_nybl_char:
|
no_lo_nybl_char:
|
||||||
|
|
||||||
;; If current byte has $0F in low nybl, then the next
|
// If current byte has $0F in low nybl, then the next
|
||||||
;; byte is a whole byte.
|
// byte is a whole byte.
|
||||||
lda (temp_string_ptr),y
|
lda (temp_string_ptr),y
|
||||||
and #$0f
|
and #$0f
|
||||||
cmp #$0f
|
cmp #$0f
|
||||||
@@ -190,7 +191,7 @@ ready_for_next_char:
|
|||||||
cpy #$ff
|
cpy #$ff
|
||||||
bne next_packed_word_char
|
bne next_packed_word_char
|
||||||
end_of_packed_word:
|
end_of_packed_word:
|
||||||
;; Hit end of packed data
|
// Hit end of packed data
|
||||||
rts
|
rts
|
||||||
|
|
||||||
last_literal:
|
last_literal:
|
||||||
@@ -202,7 +203,7 @@ next_is_literal_char:
|
|||||||
jmp ready_for_next_char
|
jmp ready_for_next_char
|
||||||
|
|
||||||
unpack_literal_char:
|
unpack_literal_char:
|
||||||
;; Output the literal char, and ready for next char
|
// Output the literal char, and ready for next char
|
||||||
iny
|
iny
|
||||||
tya
|
tya
|
||||||
pha
|
pha
|
||||||
@@ -213,14 +214,14 @@ unpack_literal_char:
|
|||||||
rts
|
rts
|
||||||
|
|
||||||
is_uncommon_char:
|
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
|
lda (temp_string_ptr),y
|
||||||
and #$0f
|
and #$0f
|
||||||
clc
|
clc
|
||||||
adc #14
|
adc #14
|
||||||
|
|
||||||
;; We need to print the low nybl char as well
|
// We need to print the low nybl char as well
|
||||||
tax
|
tax
|
||||||
tya
|
tya
|
||||||
pha
|
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,
|
// Prints the literal zero-terminated string that follows,
|
||||||
;; which may also include special tokens that allow
|
// which may also include special tokens that allow
|
||||||
;; printing of hex byte and word values stored at the indicated
|
// printing of hex byte and word values stored at the indicated
|
||||||
;; addresses.
|
// addresses.
|
||||||
|
|
||||||
;; .byte 1,$byte = display byte as hex
|
// .byte 1,$byte = display byte as hex
|
||||||
;; .byte 2,$low,$hi = display word as hex
|
// .byte 2,$low,$hi = display word as hex
|
||||||
;; .byte $f0+n,$low,$hi = display byte at $hi$lo+n as hex
|
// .byte $f0+n,$low,$hi = display byte at $hi$lo+n as hex
|
||||||
|
|
||||||
printf:
|
printf:
|
||||||
;; Temporary storage is between end of screen at $0400
|
// Temporary storage is between end of screen at $0400
|
||||||
;; and the sprite pointers at $7f8
|
// and the sprite pointers at $7f8
|
||||||
sta $7f0
|
sta $7f0
|
||||||
stx $7f1
|
stx $7f1
|
||||||
sty $7f2
|
sty $7f2
|
||||||
@@ -19,14 +19,14 @@ printf:
|
|||||||
pla
|
pla
|
||||||
sta $7f3
|
sta $7f3
|
||||||
|
|
||||||
;; Set up read routine
|
// Set up read routine
|
||||||
lda #$ad ; LDA $nnnn
|
lda #$ad // LDA $nnnn
|
||||||
sta $7f4
|
sta $7f4
|
||||||
lda #$60
|
lda #$60
|
||||||
sta $7f7 ; RTS
|
sta $7f7 // RTS
|
||||||
|
|
||||||
;; Get PC of caller from the stack, so that
|
// Get PC of caller from the stack, so that
|
||||||
;; we can parse through it
|
// we can parse through it
|
||||||
pla
|
pla
|
||||||
clc
|
clc
|
||||||
adc #$01
|
adc #$01
|
||||||
@@ -39,8 +39,8 @@ printf_loop:
|
|||||||
jsr $7f4
|
jsr $7f4
|
||||||
cmp #$00
|
cmp #$00
|
||||||
bne printf_continues
|
bne printf_continues
|
||||||
;; Put return address on stack and restore
|
// Put return address on stack and restore
|
||||||
;; registers
|
// registers
|
||||||
lda $7f6
|
lda $7f6
|
||||||
pha
|
pha
|
||||||
lda $7f5
|
lda $7f5
|
||||||
@@ -56,33 +56,33 @@ printf_loop:
|
|||||||
printf_continues:
|
printf_continues:
|
||||||
cmp #$01
|
cmp #$01
|
||||||
bne not_hexbyte
|
bne not_hexbyte
|
||||||
;; Print a hex byte
|
// Print a hex byte
|
||||||
|
|
||||||
;; Skip the token
|
// Skip the token
|
||||||
jsr printf_advance
|
jsr printf_advance
|
||||||
;; Read the low byte
|
// Read the low byte
|
||||||
jsr $7f4
|
jsr $7f4
|
||||||
;; Print as hex
|
// Print as hex
|
||||||
jsr printf_printhexbyte
|
jsr printf_printhexbyte
|
||||||
jmp printf_nextchar
|
jmp printf_nextchar
|
||||||
|
|
||||||
not_hexbyte:
|
not_hexbyte:
|
||||||
cmp #$02
|
cmp #$02
|
||||||
bne not_hexword
|
bne not_hexword
|
||||||
;; Print a hex word
|
// Print a hex word
|
||||||
|
|
||||||
;; Skip the token
|
// Skip the token
|
||||||
jsr printf_advance
|
jsr printf_advance
|
||||||
jsr printf_advance
|
jsr printf_advance
|
||||||
;; Read the high byte
|
// Read the high byte
|
||||||
jsr $7f4
|
jsr $7f4
|
||||||
;; Print as hex
|
// Print as hex
|
||||||
jsr printf_printhexbyte
|
jsr printf_printhexbyte
|
||||||
;; Skip the token
|
// Skip the token
|
||||||
jsr printf_retreat
|
jsr printf_retreat
|
||||||
;; Read the low byte
|
// Read the low byte
|
||||||
jsr $7f4
|
jsr $7f4
|
||||||
;; Print as hex
|
// Print as hex
|
||||||
jsr printf_printhexbyte
|
jsr printf_printhexbyte
|
||||||
jsr printf_advance
|
jsr printf_advance
|
||||||
jmp printf_nextchar
|
jmp printf_nextchar
|
||||||
@@ -91,11 +91,11 @@ not_hexword:
|
|||||||
cmp #$f0
|
cmp #$f0
|
||||||
bcc not_pointer
|
bcc not_pointer
|
||||||
|
|
||||||
;; Treat two-byte arg as base address
|
// Treat two-byte arg as base address
|
||||||
;; and lower 4 bits of token as offset from
|
// and lower 4 bits of token as offset from
|
||||||
;; that location.
|
// that location.
|
||||||
|
|
||||||
;; Get offset
|
// Get offset
|
||||||
and #$0f
|
and #$0f
|
||||||
tay
|
tay
|
||||||
|
|
||||||
@@ -111,7 +111,7 @@ not_hexword:
|
|||||||
jmp printf_nextchar
|
jmp printf_nextchar
|
||||||
|
|
||||||
not_pointer:
|
not_pointer:
|
||||||
;; Print character
|
// Print character
|
||||||
jsr JCHROUT
|
jsr JCHROUT
|
||||||
|
|
||||||
printf_nextchar:
|
printf_nextchar:
|
||||||
@@ -120,15 +120,15 @@ printf_nextchar:
|
|||||||
jmp printf_loop
|
jmp printf_loop
|
||||||
|
|
||||||
printf_advance:
|
printf_advance:
|
||||||
;; Advance pointer to next character
|
// Advance pointer to next character
|
||||||
inc $7f5
|
inc $7f5
|
||||||
bne +
|
bne !+
|
||||||
inc $7f6
|
inc $7f6
|
||||||
*
|
!:
|
||||||
rts
|
rts
|
||||||
|
|
||||||
printf_retreat:
|
printf_retreat:
|
||||||
;; Retreat pointer to previous char
|
// Retreat pointer to previous char
|
||||||
lda $7f5
|
lda $7f5
|
||||||
sec
|
sec
|
||||||
sbc #1
|
sbc #1
|
||||||
@@ -139,7 +139,7 @@ printf_retreat:
|
|||||||
rts
|
rts
|
||||||
|
|
||||||
printf_printhexbyte:
|
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
|
sed
|
||||||
pha
|
pha
|
||||||
lsr
|
lsr
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
ready_message:
|
ready_message:
|
||||||
;; See src/make_error_tables.c for packed message handling
|
// See src/make_error_tables.c for packed message handling
|
||||||
;; information.
|
// information.
|
||||||
ldx #29
|
ldx #29
|
||||||
jmp print_packed_message
|
jmp print_packed_message
|
||||||
|
|
||||||
+10
-10
@@ -1,19 +1,19 @@
|
|||||||
|
|
||||||
select_device:
|
select_device:
|
||||||
|
|
||||||
;; Take last device number, make sure it's a drive - 8 or above. Above 30,
|
// 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
|
// although illegal for IEC we also consider a drive, as they exists
|
||||||
;; drivers assigning these numbers to CBM-DOS capable devices - like some
|
// drivers assigning these numbers to CBM-DOS capable devices - like some
|
||||||
;; IEEE-488 carts.
|
// IEEE-488 carts.
|
||||||
;;
|
//
|
||||||
;; If current device is not a drive, set device to 8 (first drive number)
|
// If current device is not a drive, set device to 8 (first drive number)
|
||||||
;; Device number is left in X, for SETFLS Kernal routine
|
// 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
|
ldx current_device_number
|
||||||
cpx #$08
|
cpx #$08
|
||||||
bcs +
|
bcs !+
|
||||||
ldx #$08
|
ldx #$08
|
||||||
*
|
!:
|
||||||
rts
|
rts
|
||||||
+92
-92
@@ -1,18 +1,18 @@
|
|||||||
;; Tokenise a line of BASIC
|
// Tokenise a line of BASIC
|
||||||
;; Stored at $0200
|
// Stored at $0200
|
||||||
;; Length in tokenise_work1
|
// Length in tokenise_work1
|
||||||
|
|
||||||
tokenise_line:
|
tokenise_line:
|
||||||
|
|
||||||
;; We need to consider each offset in the string to see if it matches
|
// 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
|
// 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.
|
// 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.
|
// This means we need separate start and end points to keep track of.
|
||||||
|
|
||||||
;; $0110 = offset into string
|
// $0110 = offset into string
|
||||||
;; $0111 = number of bytes to pack
|
// $0111 = number of bytes to pack
|
||||||
;; $0112 = offset into tokenised output
|
// $0112 = offset into tokenised output
|
||||||
;; $0113 = length of raw string
|
// $0113 = length of raw string
|
||||||
|
|
||||||
lda #$00
|
lda #$00
|
||||||
sta $0110
|
sta $0110
|
||||||
@@ -24,56 +24,56 @@ tokenise_line:
|
|||||||
|
|
||||||
tokenise_char:
|
tokenise_char:
|
||||||
|
|
||||||
;; Check if we have reached end of the line?
|
// Check if we have reached end of the line?
|
||||||
lda $0110
|
lda $0110
|
||||||
cmp $0113
|
cmp $0113
|
||||||
bne +
|
bne !+
|
||||||
|
|
||||||
;; End of line reached
|
// End of line reached
|
||||||
|
|
||||||
;; Finished tokenising line
|
// Finished tokenising line
|
||||||
;; Update tokenise_work1 and terminate with null
|
// Update tokenise_work1 and terminate with null
|
||||||
ldx $0112
|
ldx $0112
|
||||||
lda #$00
|
lda #$00
|
||||||
sta $0200,x
|
sta $0200,x
|
||||||
stx tokenise_work1
|
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
|
lda #$00
|
||||||
sta quote_mode_flag
|
sta quote_mode_flag
|
||||||
rts
|
rts
|
||||||
*
|
!:
|
||||||
;; More to do
|
// More to do
|
||||||
|
|
||||||
;; Maximum keyword length
|
// Maximum keyword length
|
||||||
lda #7
|
lda #7
|
||||||
sta $0111
|
sta $0111
|
||||||
|
|
||||||
tokenise_char_loop:
|
tokenise_char_loop:
|
||||||
;; Pack the word from the start (start = X, raw len = tokenise_work1)
|
// Pack the word from the start (start = X, raw len = tokenise_work1)
|
||||||
;; Returns packed length in tokenise_work2 and writes the packed
|
// Returns packed length in tokenise_work2 and writes the packed
|
||||||
;; word at $0100+
|
// word at $0100+
|
||||||
|
|
||||||
ldx $0110
|
ldx $0110
|
||||||
lda $0200,x
|
lda $0200,x
|
||||||
cmp #$22
|
cmp #$22
|
||||||
bne tk_not_quote
|
bne tk_not_quote
|
||||||
|
|
||||||
;; Quote
|
// Quote
|
||||||
lda quote_mode_flag
|
lda quote_mode_flag
|
||||||
eor #$ff
|
eor #$ff
|
||||||
sta quote_mode_flag
|
sta quote_mode_flag
|
||||||
jmp tk_literal_char
|
jmp tk_literal_char
|
||||||
|
|
||||||
tk_not_quote:
|
tk_not_quote:
|
||||||
;; Check for literal characters in various ranges
|
// Check for literal characters in various ranges
|
||||||
;; (This just speeds the tokeniser up, by avoiding the packed token search
|
// (This just speeds the tokeniser up, by avoiding the packed token search
|
||||||
;; for such characters).
|
// for such characters).
|
||||||
|
|
||||||
;; SPACE and punctuation before +,- and *
|
// SPACE and punctuation before +,- and *
|
||||||
cmp #$2a
|
cmp #$2a
|
||||||
bcc tk_literal_char
|
bcc tk_literal_char
|
||||||
;; Don't try to tokenise digits
|
// Don't try to tokenise digits
|
||||||
cmp #$30
|
cmp #$30
|
||||||
bcc tk_might_be_keyword
|
bcc tk_might_be_keyword
|
||||||
cmp #$3a
|
cmp #$3a
|
||||||
@@ -81,41 +81,41 @@ tk_not_quote:
|
|||||||
jmp tk_literal_char
|
jmp tk_literal_char
|
||||||
|
|
||||||
tk_might_be_keyword:
|
tk_might_be_keyword:
|
||||||
;; Don't tokenise in quote mode
|
// Don't tokenise in quote mode
|
||||||
lda quote_mode_flag
|
lda quote_mode_flag
|
||||||
bne tk_literal_char
|
bne tk_literal_char
|
||||||
|
|
||||||
;; Pack string
|
// Pack string
|
||||||
ldx $0110
|
ldx $0110
|
||||||
lda $0111
|
lda $0111
|
||||||
sta tokenise_work1
|
sta tokenise_work1
|
||||||
|
|
||||||
;; XXX - We should implement an optimisation where we
|
// XXX - We should implement an optimisation where we
|
||||||
;; trim the last symbol of successively, instead of re-packing the word
|
// trim the last symbol of successively, instead of re-packing the word
|
||||||
;; again with one less char each time.
|
// again with one less char each time.
|
||||||
;; XXX - We should limit the word length to the length of interesting chars
|
// XXX - We should limit the word length to the length of interesting chars
|
||||||
;; that are available.
|
// that are available.
|
||||||
|
|
||||||
jsr pack_word
|
jsr pack_word
|
||||||
lda tokenise_work2
|
lda tokenise_work2
|
||||||
cmp #$10
|
cmp #$10
|
||||||
bcc +
|
bcc !+
|
||||||
;; Packed string too long
|
// Packed string too long
|
||||||
jmp do_STRING_TOO_LONG_error
|
jmp do_STRING_TOO_LONG_error
|
||||||
*
|
!:
|
||||||
|
|
||||||
;; Search for it in keywords
|
// Search for it in keywords
|
||||||
jsr keyword_search
|
jsr keyword_search
|
||||||
|
|
||||||
;; Did we find a keyword?
|
// Did we find a keyword?
|
||||||
bcc found_token_in_line
|
bcc found_token_in_line
|
||||||
|
|
||||||
;; Nope, so try shorter
|
// Nope, so try shorter
|
||||||
dec $0111
|
dec $0111
|
||||||
bne tokenise_char_loop
|
bne tokenise_char_loop
|
||||||
|
|
||||||
tk_literal_char:
|
tk_literal_char:
|
||||||
;; Is not a token, so copy to output verbatim
|
// Is not a token, so copy to output verbatim
|
||||||
ldx $0110
|
ldx $0110
|
||||||
ldy $0112
|
ldy $0112
|
||||||
lda $0200,x
|
lda $0200,x
|
||||||
@@ -123,68 +123,68 @@ tk_literal_char:
|
|||||||
inc $0112
|
inc $0112
|
||||||
inc $0110
|
inc $0110
|
||||||
|
|
||||||
;; Tokenise next char
|
// Tokenise next char
|
||||||
jmp tokenise_char
|
jmp tokenise_char
|
||||||
|
|
||||||
found_token_in_line:
|
found_token_in_line:
|
||||||
|
|
||||||
;; Got a token, so write it out
|
// Got a token, so write it out
|
||||||
ldx $0112
|
ldx $0112
|
||||||
sta $0200,x
|
sta $0200,x
|
||||||
inx
|
inx
|
||||||
stx $0112
|
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
|
cmp #$8f
|
||||||
bne not_rem
|
bne not_rem
|
||||||
sta quote_mode_flag
|
sta quote_mode_flag
|
||||||
not_rem:
|
not_rem:
|
||||||
|
|
||||||
;; Now skip over the length of the token
|
// Now skip over the length of the token
|
||||||
lda $0110
|
lda $0110
|
||||||
clc
|
clc
|
||||||
adc $0111
|
adc $0111
|
||||||
sta $0110
|
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
|
jmp tokenise_char
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;; Search for word in keyword list
|
// Search for word in keyword list
|
||||||
;; The packed form is canonical, so we can search for the keyword while
|
// The packed form is canonical, so we can search for the keyword while
|
||||||
;; it remains compressed. This also saves a little time.
|
// it remains compressed. This also saves a little time.
|
||||||
;; Algorithm is simply to find matching first bytes, and then look for
|
// Algorithm is simply to find matching first bytes, and then look for
|
||||||
;; the rest being a match.
|
// the rest being a match.
|
||||||
|
|
||||||
keyword_search:
|
keyword_search:
|
||||||
;; Search for the compressed keyword stored at $0100 in the list
|
// Search for the compressed keyword stored at $0100 in the list
|
||||||
;; of compressed keywords
|
// of compressed keywords
|
||||||
|
|
||||||
;; tokenise_work1 = offset in line of input
|
// tokenise_work1 = offset in line of input
|
||||||
;; tokenise_work2 = length of token we are matching
|
// tokenise_work2 = length of token we are matching
|
||||||
;; tokenise_work3 = offset in token list
|
// tokenise_work3 = offset in token list
|
||||||
;; load_or_verify_or_tokenise_work5 = temporary work space
|
// load_or_verify_or_tokenise_work5 = temporary work space
|
||||||
;; X and Y registers used as temporary space.
|
// X and Y registers used as temporary space.
|
||||||
;; returns C=1 if no matching token, else C=0 and A=token
|
// returns C=1 if no matching token, else C=0 and A=token
|
||||||
|
|
||||||
lda #$00
|
lda #$00
|
||||||
sta tokenise_work1
|
sta tokenise_work1
|
||||||
sta tokenise_work3
|
sta tokenise_work3
|
||||||
next_kw_offset:
|
next_kw_offset:
|
||||||
;; Advance offset in compressed keyword list, to see if a match
|
// Advance offset in compressed keyword list, to see if a match
|
||||||
;; BEGINS here
|
// BEGINS here
|
||||||
|
|
||||||
;; Get count of bytes to compare
|
// Get count of bytes to compare
|
||||||
lda tokenise_work2
|
lda tokenise_work2
|
||||||
sta load_or_verify_or_tokenise_work5
|
sta load_or_verify_or_tokenise_work5
|
||||||
|
|
||||||
;; Load current position
|
// Load current position
|
||||||
ldy tokenise_work3
|
ldy tokenise_work3
|
||||||
ldx tokenise_work1
|
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
|
inc tokenise_work3
|
||||||
lda tokenise_work3
|
lda tokenise_work3
|
||||||
cmp #packed_keyword_table_len
|
cmp #packed_keyword_table_len
|
||||||
@@ -194,75 +194,75 @@ next_in_match:
|
|||||||
lda $0100,x
|
lda $0100,x
|
||||||
cmp packed_keywords,y
|
cmp packed_keywords,y
|
||||||
bne next_kw_offset
|
bne next_kw_offset
|
||||||
;; Advance to next chars in source and target
|
// Advance to next chars in source and target
|
||||||
inx
|
inx
|
||||||
iny
|
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
|
bne next_in_match
|
||||||
|
|
||||||
;; Keyword matches!
|
// Keyword matches!
|
||||||
|
|
||||||
;; Now make sure we started on a keyword boundary
|
// Now make sure we started on a keyword boundary
|
||||||
;; (we know we finished on one, because of the structure of the compressed
|
// (we know we finished on one, because of the structure of the compressed
|
||||||
;; keyword data).
|
// keyword data).
|
||||||
;; Offset 0
|
// Offset 0
|
||||||
;; previous byte is $x0
|
// previous byte is $x0
|
||||||
;; two byte prior is $FE
|
// two byte prior is $FE
|
||||||
|
|
||||||
;; Get offset of first byte of this token
|
// Get offset of first byte of this token
|
||||||
ldx tokenise_work3
|
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
|
cpx #$00
|
||||||
beq word_boundary
|
beq word_boundary
|
||||||
dex
|
dex
|
||||||
;; Previous byte is $x0 end token?
|
// Previous byte is $x0 end token?
|
||||||
lda packed_keywords,x
|
lda packed_keywords,x
|
||||||
and #$0f
|
and #$0f
|
||||||
beq word_boundary
|
beq word_boundary
|
||||||
dex
|
dex
|
||||||
;; Uber-previouss byte is $FE final literal token?
|
// Uber-previouss byte is $FE final literal token?
|
||||||
lda packed_keywords,x
|
lda packed_keywords,x
|
||||||
cmp #$fe
|
cmp #$fe
|
||||||
beq word_boundary
|
beq word_boundary
|
||||||
|
|
||||||
;; Not a word boundary, so ignore
|
// Not a word boundary, so ignore
|
||||||
jmp next_kw_offset
|
jmp next_kw_offset
|
||||||
|
|
||||||
word_boundary:
|
word_boundary:
|
||||||
;; Found a token whose offset is in tokenise_work3
|
// Found a token whose offset is in tokenise_work3
|
||||||
;; Now trace back to the start of the compressed keyword list
|
// Now trace back to the start of the compressed keyword list
|
||||||
;; to work out what keyword number we are, so that we can return
|
// to work out what keyword number we are, so that we can return
|
||||||
;; the token number.
|
// the token number.
|
||||||
|
|
||||||
ldy #$80
|
ldy #$80
|
||||||
|
|
||||||
token_count_loop:
|
token_count_loop:
|
||||||
lda packed_keywords,x
|
lda packed_keywords,x
|
||||||
cmp #$fe
|
cmp #$fe
|
||||||
bne +
|
bne !+
|
||||||
iny
|
iny
|
||||||
*
|
!:
|
||||||
and #$0f
|
and #$0f
|
||||||
cmp #$00
|
cmp #$00
|
||||||
bne +
|
bne !+
|
||||||
iny
|
iny
|
||||||
*
|
!:
|
||||||
cpx #$00
|
cpx #$00
|
||||||
beq +
|
beq !+
|
||||||
dex
|
dex
|
||||||
jmp token_count_loop
|
jmp token_count_loop
|
||||||
*
|
!:
|
||||||
|
|
||||||
tya
|
tya
|
||||||
clc
|
clc
|
||||||
rts
|
rts
|
||||||
|
|
||||||
done_searching_for_token:
|
done_searching_for_token:
|
||||||
;; No token found
|
// No token found
|
||||||
sec
|
sec
|
||||||
lda #$00
|
lda #$00
|
||||||
rts
|
rts
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
;; IMPORTANT:
|
// IMPORTANT:
|
||||||
;; These routines lengths cannot be changed without changing
|
// These routines lengths cannot be changed without changing
|
||||||
;; the aliases for peek_under_roms, poke_under_roms etc
|
// the aliases for peek_under_roms, poke_under_roms etc
|
||||||
;; in ,aliases.s.
|
// in ,aliases.s.
|
||||||
;; Thus those addresses are expressed using formulae.
|
// Thus those addresses are expressed using formulae.
|
||||||
|
|
||||||
install_ram_routines:
|
install_ram_routines:
|
||||||
;; Copy routines into place
|
// Copy routines into place
|
||||||
ldx #ram_routines_len-1
|
ldx #ram_routines_end-ram_routines_start-1
|
||||||
*
|
!:
|
||||||
lda ram_routines_start,x
|
lda ram_routines_start,x
|
||||||
sta tiny_nmi_handler,x
|
sta tiny_nmi_handler,x
|
||||||
dex
|
dex
|
||||||
bpl -
|
bpl !-
|
||||||
|
|
||||||
;; Point NMI handler to tiny_nmi_handler
|
// Point NMI handler to tiny_nmi_handler
|
||||||
lda #<tiny_nmi_handler
|
lda #<tiny_nmi_handler
|
||||||
sta $FFFE
|
sta $FFFE
|
||||||
lda #>tiny_nmi_handler
|
lda #>tiny_nmi_handler
|
||||||
@@ -23,14 +23,14 @@ install_ram_routines:
|
|||||||
|
|
||||||
ram_routines_start:
|
ram_routines_start:
|
||||||
|
|
||||||
;; XXX - Routine order must match that of the KERNAL version of the file.
|
// XXX - Routine order must match that of the KERNAL version of the file.
|
||||||
;; (since it has fewer routines)
|
// (since it has fewer routines)
|
||||||
tiny_nmi_handler_routine:
|
tiny_nmi_handler_routine:
|
||||||
inc missed_nmi_flag
|
inc missed_nmi_flag
|
||||||
rti
|
rti
|
||||||
peek_under_roms_routine:
|
peek_under_roms_routine:
|
||||||
php
|
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
|
stx peek_under_roms+pa-peek_under_roms_routine+1
|
||||||
jsr memmap_allram
|
jsr memmap_allram
|
||||||
pa: lda ($00),y
|
pa: lda ($00),y
|
||||||
@@ -40,7 +40,7 @@ pa: lda ($00),y
|
|||||||
|
|
||||||
poke_under_roms_routine:
|
poke_under_roms_routine:
|
||||||
php
|
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
|
stx poke_under_roms+pb-poke_under_roms_routine+1
|
||||||
jsr memmap_allram
|
jsr memmap_allram
|
||||||
pb: sta ($00),y
|
pb: sta ($00),y
|
||||||
@@ -64,12 +64,12 @@ memmap_allram_routine:
|
|||||||
rts
|
rts
|
||||||
|
|
||||||
shift_mem_up_routine:
|
shift_mem_up_routine:
|
||||||
;; Move memmove_size bytes from memmove_src to memmove_dst,
|
// Move memmove_size bytes from memmove_src to memmove_dst,
|
||||||
;; where memmove_dst > memmove_src
|
// where memmove_dst > memmove_src
|
||||||
;; This means we have to copy from the back end down.
|
// This means we have to copy from the back end down.
|
||||||
;; This routine assumes the pointers are already pointed
|
// This routine assumes the pointers are already pointed
|
||||||
;; to the end of the areas, and that Y is correctly initialised
|
// to the end of the areas, and that Y is correctly initialised
|
||||||
;; to allow the copy to begin.
|
// to allow the copy to begin.
|
||||||
php
|
php
|
||||||
jsr memmap_allram
|
jsr memmap_allram
|
||||||
smu1:
|
smu1:
|
||||||
@@ -85,12 +85,12 @@ smu1:
|
|||||||
jmp memmap_normal
|
jmp memmap_normal
|
||||||
|
|
||||||
shift_mem_down_routine:
|
shift_mem_down_routine:
|
||||||
;; Move memmove_size bytes from memmove_src to memmove_dst,
|
// Move memmove_size bytes from memmove_src to memmove_dst,
|
||||||
;; where memmove_dst > memmove_src
|
// where memmove_dst > memmove_src
|
||||||
;; This means we have to copy from the back end down.
|
// This means we have to copy from the back end down.
|
||||||
;; This routine assumes the pointers are already pointed
|
// This routine assumes the pointers are already pointed
|
||||||
;; to the end of the areas, and that Y is correctly initialised
|
// to the end of the areas, and that Y is correctly initialised
|
||||||
;; to allow the copy to begin.
|
// to allow the copy to begin.
|
||||||
php
|
php
|
||||||
jsr memmap_allram
|
jsr memmap_allram
|
||||||
smd1:
|
smd1:
|
||||||
@@ -105,7 +105,4 @@ smd1:
|
|||||||
plp
|
plp
|
||||||
jmp memmap_normal
|
jmp memmap_normal
|
||||||
|
|
||||||
|
|
||||||
ram_routines_end:
|
ram_routines_end:
|
||||||
.alias ram_routines_len ram_routines_end-ram_routines_start
|
|
||||||
|
|
||||||
+88
-88
@@ -1,161 +1,161 @@
|
|||||||
|
|
||||||
;; START wedge support
|
// START wedge support
|
||||||
|
|
||||||
wedge_dos:
|
wedge_dos:
|
||||||
|
|
||||||
;; Close all the channels, so that wedge has full control
|
// Close all the channels, so that wedge has full control
|
||||||
jsr JCLALL
|
jsr JCLALL
|
||||||
|
|
||||||
;; Set file parameters, channel 15 is a typical one for commands
|
// Set file parameters, channel 15 is a typical one for commands
|
||||||
jsr select_device ; sets X register
|
jsr select_device // sets .X register
|
||||||
lda #$0F
|
lda #$0F
|
||||||
ldy #$0F
|
ldy #$0F
|
||||||
jsr JSETFLS
|
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
|
ldy #$00
|
||||||
lda (basic_current_statement_ptr), y
|
lda (basic_current_statement_ptr), y
|
||||||
bne +
|
bne !+
|
||||||
jmp wedge_dos_status ; XXX try to optimize this, perhaps move 'wedge_dos_status' above?
|
jmp wedge_dos_status // XXX try to optimize this, perhaps move 'wedge_dos_status' above?
|
||||||
*
|
!:
|
||||||
;; Check if asked for a directory
|
// Check if asked for a directory
|
||||||
cmp #$24
|
cmp #$24
|
||||||
bne +
|
bne !+
|
||||||
jmp wedge_dos_directory
|
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
|
cmp #$30
|
||||||
bcc wedge_dos_command ; char code before 0
|
bcc wedge_dos_command // char code before 0
|
||||||
cmp #$3A
|
cmp #$3A
|
||||||
bcs wedge_dos_command ; char code after 9
|
bcs wedge_dos_command // char code after 9
|
||||||
iny
|
iny
|
||||||
lda (basic_current_statement_ptr), y
|
lda (basic_current_statement_ptr), y
|
||||||
beq wedge_dos_change_drive ; end of buffer
|
beq wedge_dos_change_drive // end of buffer
|
||||||
cmp #$20
|
cmp #$20
|
||||||
beq wedge_dos_change_drive
|
beq wedge_dos_change_drive
|
||||||
jmp -
|
jmp !-
|
||||||
|
|
||||||
wedge_dos_command:
|
wedge_dos_command:
|
||||||
|
|
||||||
;; Provide command name
|
// Provide command name
|
||||||
jsr wedge_dos_setnam
|
jsr wedge_dos_setnam
|
||||||
|
|
||||||
jsr JSETNAM
|
jsr JSETNAM
|
||||||
jsr JOPEN
|
jsr JOPEN
|
||||||
bcc +
|
bcc !+
|
||||||
jmp wedge_dos_basic_error ; XXX combine with other such jumps
|
jmp wedge_dos_basic_error // XXX combine with other such jumps
|
||||||
*
|
!:
|
||||||
;; Retrieve status, print it if not OK
|
// Retrieve status, print it if not OK
|
||||||
jsr JCLALL
|
jsr JCLALL
|
||||||
jsr wedge_dos_status_get
|
jsr wedge_dos_status_get
|
||||||
lda BUF+0
|
lda BUF+0
|
||||||
cmp #$30 ; '0'
|
cmp #$30 // '0'
|
||||||
bne wedge_dos_status_print
|
bne wedge_dos_status_print
|
||||||
lda BUF+1
|
lda BUF+1
|
||||||
cmp #$30 ; '0'
|
cmp #$30 // '0'
|
||||||
bne wedge_dos_status_print
|
bne wedge_dos_status_print
|
||||||
|
|
||||||
;; Clean-up and exit
|
// Clean-up and exit
|
||||||
jmp wedge_dos_clean_exit
|
jmp wedge_dos_clean_exit
|
||||||
|
|
||||||
wedge_dos_change_drive:
|
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
|
jsr basic_parse_line_number
|
||||||
lda basic_line_number+1
|
lda basic_line_number+1
|
||||||
beq +
|
beq !+
|
||||||
jmp do_ILLEGAL_QUANTITY_error
|
jmp do_ILLEGAL_QUANTITY_error
|
||||||
*
|
!:
|
||||||
lda basic_line_number+0
|
lda basic_line_number+0
|
||||||
cmp #$08
|
cmp #$08
|
||||||
bpl +
|
bpl !+
|
||||||
bcs +
|
bcs !+
|
||||||
jmp do_ILLEGAL_DEVICE_NUMBER_error
|
jmp do_ILLEGAL_DEVICE_NUMBER_error
|
||||||
*
|
!:
|
||||||
sta current_device_number
|
sta current_device_number
|
||||||
jmp basic_end_of_line
|
jmp basic_end_of_line
|
||||||
|
|
||||||
wedge_dos_status_get:
|
wedge_dos_status_get:
|
||||||
|
|
||||||
;; Here the flow is mostly the same as in the example from
|
// 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
|
// https://codebase64.org/doku.php?id=base:reading_the_error_channel_of_a_disk_drive
|
||||||
|
|
||||||
;; Set remaining file parameters, open the channel
|
// Set remaining file parameters, open the channel
|
||||||
lda #$00 ; empty file name
|
lda #$00 // empty file name
|
||||||
jsr JSETNAM
|
jsr JSETNAM
|
||||||
jsr JOPEN
|
jsr JOPEN
|
||||||
bcc +
|
bcc !+
|
||||||
jmp wedge_dos_basic_error ; XXX combine with other such jumps
|
jmp wedge_dos_basic_error // XXX combine with other such jumps
|
||||||
*
|
!:
|
||||||
|
|
||||||
;; Set channel for input
|
// Set channel for input
|
||||||
ldx #$0F
|
ldx #$0F
|
||||||
jsr JCHKIN
|
jsr JCHKIN
|
||||||
bcc +
|
bcc !+
|
||||||
jmp wedge_dos_basic_error ; XXX combine with other such jumps
|
jmp wedge_dos_basic_error // XXX combine with other such jumps
|
||||||
*
|
!:
|
||||||
|
|
||||||
ldy #$00
|
ldy #$00
|
||||||
*
|
!:
|
||||||
cpy #$50 ; buffer overflow protection
|
cpy #$50 // buffer overflow protection
|
||||||
beq +
|
beq !+
|
||||||
jsr JREADST ; retrieve errors
|
jsr JREADST // retrieve errors
|
||||||
;; XXX error in case of status != EOF
|
// XXX error in case of status != EOF
|
||||||
;; Print out everything retrieved from the drive
|
// Print out everything retrieved from the drive
|
||||||
bne +
|
bne !+
|
||||||
jsr JCHRIN
|
jsr JCHRIN
|
||||||
bcc wedge_dos_x1
|
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:
|
wedge_dos_x1:
|
||||||
sta BUF, y
|
sta BUF, y
|
||||||
iny
|
iny
|
||||||
jmp -
|
jmp !-
|
||||||
*
|
!:
|
||||||
rts
|
rts
|
||||||
|
|
||||||
wedge_dos_status:
|
wedge_dos_status:
|
||||||
jsr wedge_dos_status_get
|
jsr wedge_dos_status_get
|
||||||
;; FALLTROUGH
|
// FALLTROUGH
|
||||||
|
|
||||||
wedge_dos_status_print:
|
wedge_dos_status_print:
|
||||||
|
|
||||||
;; Print buffered status
|
// Print buffered status
|
||||||
ldx #$00
|
ldx #$00
|
||||||
*
|
!:
|
||||||
dey
|
dey
|
||||||
bmi +
|
bmi !+
|
||||||
lda BUF, x
|
lda BUF, x
|
||||||
jsr JCHROUT
|
jsr JCHROUT
|
||||||
inx
|
inx
|
||||||
bne -
|
bne !-
|
||||||
*
|
!:
|
||||||
;; Clean-up and exit
|
// Clean-up and exit
|
||||||
jmp wedge_dos_clean_exit
|
jmp wedge_dos_clean_exit
|
||||||
|
|
||||||
wedge_dos_directory:
|
wedge_dos_directory:
|
||||||
|
|
||||||
;; First change the secondary address to the one suitable for
|
// First change the secondary address to the one suitable for
|
||||||
;; directory loading
|
// directory loading
|
||||||
lda #$00 ; logical device number
|
lda #$00 // logical device number
|
||||||
ldx current_device_number
|
ldx current_device_number
|
||||||
ldy #$60
|
ldy #$60
|
||||||
jsr JSETFLS
|
jsr JSETFLS
|
||||||
|
|
||||||
;; Provide file name
|
// Provide file name
|
||||||
jsr wedge_dos_setnam
|
jsr wedge_dos_setnam
|
||||||
|
|
||||||
;; Open the file
|
// Open the file
|
||||||
jsr JOPEN
|
jsr JOPEN
|
||||||
bcs wedge_dos_basic_error
|
bcs wedge_dos_basic_error
|
||||||
|
|
||||||
;; Set channel for file reading
|
// Set channel for file reading
|
||||||
ldx #$00
|
ldx #$00
|
||||||
jsr JCHKIN
|
jsr JCHKIN
|
||||||
bcs wedge_dos_basic_error
|
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
|
jsr JCHRIN
|
||||||
bcs wedge_dos_basic_error
|
bcs wedge_dos_basic_error
|
||||||
jsr JCHRIN
|
jsr JCHRIN
|
||||||
@@ -163,37 +163,37 @@ wedge_dos_directory:
|
|||||||
|
|
||||||
wedge_dos_directory_line:
|
wedge_dos_directory_line:
|
||||||
|
|
||||||
;; Load a single line, reuse BASIC input buffer
|
// Load a single line, reuse BASIC input buffer
|
||||||
ldy #$FF
|
ldy #$FF
|
||||||
*
|
!:
|
||||||
iny
|
iny
|
||||||
jsr JCHRIN
|
jsr JCHRIN
|
||||||
bcs wedge_dos_basic_error
|
bcs wedge_dos_basic_error
|
||||||
sta BUF, y
|
sta BUF, y
|
||||||
cpy #$50
|
cpy #$50
|
||||||
beq + ; line too long, terminate loading file
|
beq !+ // line too long, terminate loading file
|
||||||
jsr JREADST
|
jsr JREADST
|
||||||
bne + ; end of file
|
bne !+ // end of file
|
||||||
cpy #$04 ; 2 bytes (pointer to next line) + 2 bytes (line number)
|
cpy #$04 // 2 bytes (pointer to next line) + 2 bytes (line number)
|
||||||
bcc -
|
bcc !-
|
||||||
lda BUF, y
|
lda BUF, y
|
||||||
bne -
|
bne !-
|
||||||
;; End of line, but not end of file
|
// End of line, but not end of file
|
||||||
beq wedge_dos_directory_display
|
beq wedge_dos_directory_display
|
||||||
*
|
!:
|
||||||
lda #K_STS_END_OF_FILE
|
lda #K_STS_END_OF_FILE
|
||||||
sta IOSTATUS ; make sure end of file is marked
|
sta IOSTATUS // make sure end of file is marked
|
||||||
;; FALLTROUGH
|
// FALLTROUGH
|
||||||
|
|
||||||
wedge_dos_directory_display:
|
wedge_dos_directory_display:
|
||||||
|
|
||||||
cpy #$05 ; protection against malformed directory
|
cpy #$05 // protection against malformed directory
|
||||||
bcc wedge_dos_clean_exit
|
bcc wedge_dos_clean_exit
|
||||||
|
|
||||||
lda #$00 ; extra protection agains buffer overflow
|
lda #$00 // extra protection agains buffer overflow
|
||||||
sta BUF, y
|
sta BUF, y
|
||||||
|
|
||||||
;; Display line
|
// Display line
|
||||||
ldx #<BUF
|
ldx #<BUF
|
||||||
stx basic_current_line_ptr+0
|
stx basic_current_line_ptr+0
|
||||||
ldx #>BUF
|
ldx #>BUF
|
||||||
@@ -201,14 +201,14 @@ wedge_dos_directory_display:
|
|||||||
ldx #basic_current_line_ptr
|
ldx #basic_current_line_ptr
|
||||||
jsr list_single_line
|
jsr list_single_line
|
||||||
|
|
||||||
;; Read & display next line or quit
|
// Read & display next line or quit
|
||||||
lda IOSTATUS
|
lda IOSTATUS
|
||||||
beq wedge_dos_directory_line
|
beq wedge_dos_directory_line
|
||||||
;; FALLTROUGH
|
// FALLTROUGH
|
||||||
|
|
||||||
wedge_dos_clean_exit:
|
wedge_dos_clean_exit:
|
||||||
jsr JCLALL
|
jsr JCLALL
|
||||||
;; Print new line
|
// Print new line
|
||||||
lda #$0D
|
lda #$0D
|
||||||
jsr JCHROUT
|
jsr JCHROUT
|
||||||
jmp basic_end_of_line
|
jmp basic_end_of_line
|
||||||
@@ -222,17 +222,17 @@ wedge_dos_basic_error:
|
|||||||
jmp do_basic_error
|
jmp do_basic_error
|
||||||
|
|
||||||
wedge_dos_setnam:
|
wedge_dos_setnam:
|
||||||
;; Now determine the length of the 'file' name
|
// Now determine the length of the 'file' name
|
||||||
ldy #$FF
|
ldy #$FF
|
||||||
*
|
!:
|
||||||
iny
|
iny
|
||||||
lda (basic_current_statement_ptr), y
|
lda (basic_current_statement_ptr), y
|
||||||
bne -
|
bne !-
|
||||||
|
|
||||||
;; Set the name to open
|
// Set the name to open
|
||||||
tya
|
tya
|
||||||
ldx basic_current_statement_ptr+0
|
ldx basic_current_statement_ptr+0
|
||||||
ldy basic_current_statement_ptr+1
|
ldy basic_current_statement_ptr+1
|
||||||
jmp JSETNAM
|
jmp JSETNAM
|
||||||
|
|
||||||
;; END wedge support
|
// END wedge support
|
||||||
+70
-68
@@ -1,73 +1,75 @@
|
|||||||
; Names of ZP and low memory locations
|
// Names of ZP and low memory locations
|
||||||
; (Only those of relevance for the KERNAL)
|
// (Only those of relevance for the KERNAL)
|
||||||
; (And only those for now that we feel the need to implement initially)
|
// (And only those for now that we feel the need to implement initially)
|
||||||
; (https://www.c64-wiki.com/wiki/Zeropage)
|
// (https://www.c64-wiki.com/wiki/Zeropage)
|
||||||
|
|
||||||
.alias kernal_load_or_verify_flag $93
|
// XXX get rid of this file, use ,aliases_ram_lowmem.s instead
|
||||||
.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
|
|
||||||
|
|
||||||
; "Compute's Mapping the 64" book
|
.label kernal_load_or_verify_flag = $93
|
||||||
.alias keyboard_buffer $0277
|
.label current_file_num = $98
|
||||||
.alias text_colour $0286 ; p55
|
.label input_device_number = DFLTN
|
||||||
.alias colour_under_cursor $0287 ; p56
|
.label cassette_buffer_bytes_used = $A6
|
||||||
.alias key_buffer_size $0289 ; p57
|
.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
|
||||||
|
|
||||||
;; 0 = cursor keys, insert, delete and space repeat, but nothing else
|
// "Compute's Mapping the 64" book
|
||||||
;; 128 = all keys repeat
|
.label keyboard_buffer = $0277
|
||||||
;; 64 = no keys repeat
|
.label text_colour = $0286 // p55
|
||||||
.alias key_repeat_flags $028A ; p58
|
.label colour_under_cursor = $0287 // p56
|
||||||
;; https://www.c64-wiki.com/wiki/Page_2
|
.label key_buffer_size = $0289 // p57
|
||||||
.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
|
|
||||||
|
|
||||||
;; Under-ROM routines
|
// 0 = cursor keys, insert, delete and space repeat, but nothing else
|
||||||
;; (BASIC also includes them. XXX - We should de-duplicate them in a safe manner)
|
// 128 = all keys repeat
|
||||||
.alias missed_nmi_flag $2A7
|
// 64 = no keys repeat
|
||||||
.alias tiny_nmi_handler $2A8
|
.label key_repeat_flags = $028A // p58
|
||||||
.alias peek_under_roms tiny_nmi_handler+peek_under_roms_routine-tiny_nmi_handler_routine
|
// https://www.c64-wiki.com/wiki/Page_2
|
||||||
.alias poke_under_roms tiny_nmi_handler+poke_under_roms_routine-tiny_nmi_handler_routine
|
.label key_repeat_counter = $028B
|
||||||
.alias memmap_allram tiny_nmi_handler+memmap_allram_routine-tiny_nmi_handler_routine
|
.label key_first_repeat_delay = $028C
|
||||||
.alias memmap_normal tiny_nmi_handler+memmap_normal_routine-tiny_nmi_handler_routine
|
// 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)
|
||||||
|
.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
|
.macro TARGET_HOOK_LOAD() {
|
||||||
.macend
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
;; Target-specific hooks
|
// Target-specific hooks
|
||||||
|
|
||||||
|
|
||||||
.macro TARGET_HOOK_LOAD
|
.macro TARGET_HOOK_LOAD() {
|
||||||
.macend
|
}
|
||||||
@@ -1,57 +1,57 @@
|
|||||||
|
|
||||||
;; Registers according to Ultimate 64 Command Interface description,
|
// Registers according to Ultimate 64 Command Interface description,
|
||||||
;; https://1541u-documentation.readthedocs.io/en/latest/command%20interface.html
|
// 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
|
// and ultimate_dos_v1.0.pdf and command_interface_v1.0.pdf by Gideon Zweijtzer
|
||||||
|
|
||||||
;; Command interface registers
|
// Command interface registers
|
||||||
.alias U64_CONTROL $DF1C ; write
|
.label U64_CONTROL = $DF1C // write
|
||||||
.alias U64_STATUS $DF1C ; read
|
.label U64_STATUS = $DF1C // read
|
||||||
.alias U64_COMMAND_DATA $DF1D ; write
|
.label U64_COMMAND_DATA = $DF1D // write
|
||||||
.alias U64_IDENTIFICATION $DF1D ; read
|
.label U64_IDENTIFICATION = $DF1D // read
|
||||||
.alias U64_RESPONSE_DATA $DF1E ; read only
|
.label U64_RESPONSE_DATA = $DF1E // read only
|
||||||
.alias U64_STATUS_DATA $DF1F ; read only
|
.label U64_STATUS_DATA = $DF1F // read only
|
||||||
|
|
||||||
;; Constant for U64_IDENTIFICATION register
|
// Constant for U64_IDENTIFICATION register
|
||||||
.alias U64_MAGIC_ID $C9
|
.const U64_MAGIC_ID = $C9
|
||||||
|
|
||||||
;; Constants for U64_CONTROL register
|
// Constants for U64_CONTROL register
|
||||||
.alias U64_CTRL_BIT_PUSH_CMD $01
|
.const U64_CTRL_BIT_PUSH_CMD = $01
|
||||||
.alias U64_CTRL_BIT_DATA_ACC $02
|
.const U64_CTRL_BIT_DATA_ACC = $02
|
||||||
.alias U64_CTRL_BIT_ABORT $04
|
.const U64_CTRL_BIT_ABORT = $04
|
||||||
.alias U64_CTRL_BIT_CLR_ERR $08
|
.const U64_CTRL_BIT_CLR_ERR = $08
|
||||||
|
|
||||||
;; Constants for U64_STATUS register
|
// Constants for U64_STATUS register
|
||||||
.alias U64_STAT_BIT_CMD_BUSY $01
|
.const U64_STAT_BIT_CMD_BUSY = $01
|
||||||
.alias U64_STAT_BIT_DATA_ACC $02
|
.const U64_STAT_BIT_DATA_ACC = $02
|
||||||
.alias U64_STAT_BIT_ABORT_P $04
|
.const U64_STAT_BIT_ABORT_P = $04
|
||||||
.alias U64_STAT_BIT_ERROR $08
|
.const U64_STAT_BIT_ERROR = $08
|
||||||
.alias U64_STAT_MASK_STATE $30 ; two bits!
|
.const U64_STAT_MASK_STATE = $30 // two bits!
|
||||||
.alias U64_STAT_BIT_STAT_AV $40
|
.const U64_STAT_BIT_STAT_AV = $40
|
||||||
.alias U64_STAT_BIT_DATA_AV $80
|
.const U64_STAT_BIT_DATA_AV = $80
|
||||||
|
|
||||||
;; Interface targets
|
// Interface targets
|
||||||
.alias U64_TARGET_DOS1 $01
|
.const U64_TARGET_DOS1 = $01
|
||||||
.alias U64_TARGET_DOS2 $02
|
.const U64_TARGET_DOS2 = $02
|
||||||
|
|
||||||
;; DOS command codes
|
// DOS command codes
|
||||||
.alias U64_DOS_CMD_IDENTIFY $01
|
.const U64_DOS_CMD_IDENTIFY = $01
|
||||||
.alias U64_DOS_CMD_OPEN_FILE $02
|
.const U64_DOS_CMD_OPEN_FILE = $02
|
||||||
.alias U64_DOS_CMD_CLOSE_FILE $03
|
.const U64_DOS_CMD_CLOSE_FILE = $03
|
||||||
.alias U64_DOS_CMD_READ_DATA $04
|
.const U64_DOS_CMD_READ_DATA = $04
|
||||||
.alias U64_DOS_CMD_WRITE_DATA $05
|
.const U64_DOS_CMD_WRITE_DATA = $05
|
||||||
.alias U64_DOS_CMD_FILE_SEEK $06
|
.const U64_DOS_CMD_FILE_SEEK = $06
|
||||||
.alias U64_DOS_CMD_FILE_INFO $07
|
.const U64_DOS_CMD_FILE_INFO = $07
|
||||||
.alias U64_DOS_CMD_CHANGE_DIR $11
|
.const U64_DOS_CMD_CHANGE_DIR = $11
|
||||||
.alias U64_DOS_CMD_GET_PATH $12
|
.const U64_DOS_CMD_GET_PATH = $12
|
||||||
.alias U64_DOS_CMD_OPEN_DIR $13
|
.const U64_DOS_CMD_OPEN_DIR = $13
|
||||||
.alias U64_DOS_CMD_READ_DIR $14
|
.const U64_DOS_CMD_READ_DIR = $14
|
||||||
.alias U64_DOS_CMD_COPY_UI_PATH $15
|
.const U64_DOS_CMD_COPY_UI_PATH = $15
|
||||||
.alias U64_DOS_CMD_LOAD_REU $21
|
.const U64_DOS_CMD_LOAD_REU = $21
|
||||||
.alias U64_DOS_CMD_SAVE_REU $22
|
.const U64_DOS_CMD_SAVE_REU = $22
|
||||||
.alias U64_DOS_CMD_ECHO $F0
|
.const U64_DOS_CMD_ECHO = $F0
|
||||||
|
|
||||||
;; DOS file opening constants
|
// DOS file opening constants
|
||||||
.alias U64_FA_READ $01
|
.const U64_FA_READ = $01
|
||||||
.alias U64_FA_WRITE $02
|
.const U64_FA_WRITE = $02
|
||||||
.alias U64_FA_CREATE_NEW $03
|
.const U64_FA_CREATE_NEW = $03
|
||||||
.alias U64_FA_CREATE_ALWAYS $04
|
.const U64_FA_CREATE_ALWAYS = $04
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
|
|
||||||
;; Target-specific hooks
|
// Target-specific hooks
|
||||||
|
|
||||||
|
|
||||||
.macro TARGET_HOOK_LOAD
|
.macro TARGET_HOOK_LOAD() {
|
||||||
;; XXX disabled for now - the current file opening API is not
|
// XXX disabled for now - the current file opening API is not
|
||||||
;; really suitable for easy usage from Kernal
|
// really suitable for easy usage from Kernal
|
||||||
;; jsr u64_load
|
// jsr u64_load
|
||||||
.macend
|
}
|
||||||
@@ -1,35 +1,35 @@
|
|||||||
|
|
||||||
;;
|
//
|
||||||
;; LOAD routine hook for fast loading via UltiDOS
|
// LOAD routine hook for fast loading via UltiDOS
|
||||||
;;
|
//
|
||||||
|
|
||||||
|
|
||||||
u64_load:
|
u64_load:
|
||||||
|
|
||||||
;; First check whether the command interface is enabled
|
// First check whether the command interface is enabled
|
||||||
lda U64_IDENTIFICATION
|
lda U64_IDENTIFICATION
|
||||||
cmp #U64_MAGIC_ID
|
cmp #U64_MAGIC_ID
|
||||||
beq +
|
beq !+
|
||||||
|
|
||||||
u64_load_skip:
|
u64_load_skip:
|
||||||
rts
|
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
|
lda current_device_number
|
||||||
cmp #$20 ; for now use device number 32
|
cmp #$20 // for now use device number 32
|
||||||
bne u64_load_skip
|
bne u64_load_skip
|
||||||
|
|
||||||
;; Takeover the flow completely
|
// Takeover the flow completely
|
||||||
pla
|
pla
|
||||||
pla
|
pla
|
||||||
|
|
||||||
;; Display SEARCHING FOR + filename
|
// Display SEARCHING FOR + filename
|
||||||
jsr lvs_display_searching_for
|
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
|
jsr u64_load_abort
|
||||||
|
|
||||||
;; Send a command to open the file
|
// Send a command to open the file
|
||||||
lda #U64_DOS_CMD_OPEN_FILE
|
lda #U64_DOS_CMD_OPEN_FILE
|
||||||
jsr u64_load_send_cmd
|
jsr u64_load_send_cmd
|
||||||
lda #U64_FA_READ
|
lda #U64_FA_READ
|
||||||
@@ -37,16 +37,17 @@ u64_load_skip:
|
|||||||
jsr u64_load_send_filename
|
jsr u64_load_send_filename
|
||||||
jsr u64_load_finalize_cmd
|
jsr u64_load_finalize_cmd
|
||||||
|
|
||||||
;; Check status
|
// Check status
|
||||||
jsr u64_load_check_status
|
jsr u64_load_check_status
|
||||||
bcs lvs_file_not_found_error
|
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
|
jsr printf
|
||||||
.byte "DBG: NOT IMPLEMENTED",$0D,0
|
.text "DBG: NOT IMPLEMENTED"
|
||||||
|
.byte $0D,0
|
||||||
|
|
||||||
jmp lvs_wrap_around_error
|
jmp lvs_wrap_around_error
|
||||||
rts
|
rts
|
||||||
@@ -54,25 +55,25 @@ u64_load_skip:
|
|||||||
u64_load_abort:
|
u64_load_abort:
|
||||||
lda #U64_CTRL_BIT_ABORT
|
lda #U64_CTRL_BIT_ABORT
|
||||||
sta U64_CONTROL
|
sta U64_CONTROL
|
||||||
*
|
!:
|
||||||
lda U64_STATUS
|
lda U64_STATUS
|
||||||
bne -
|
bne !-
|
||||||
rts
|
rts
|
||||||
|
|
||||||
u64_load_send_cmd:
|
u64_load_send_cmd:
|
||||||
|
|
||||||
ldx #U64_TARGET_DOS2
|
ldx #U64_TARGET_DOS2
|
||||||
stx U64_COMMAND_DATA ; target
|
stx U64_COMMAND_DATA // target
|
||||||
sta U64_COMMAND_DATA ; command code
|
sta U64_COMMAND_DATA // command code
|
||||||
rts
|
rts
|
||||||
|
|
||||||
u64_load_send_filename:
|
u64_load_send_filename:
|
||||||
ldy #0
|
ldy #0
|
||||||
u64_load_send_filename_loop:
|
u64_load_send_filename_loop:
|
||||||
cpy FNLEN
|
cpy FNLEN
|
||||||
bne+
|
bne !+
|
||||||
rts
|
rts
|
||||||
*
|
!:
|
||||||
ldx #<current_filename_ptr
|
ldx #<current_filename_ptr
|
||||||
jsr peek_under_roms
|
jsr peek_under_roms
|
||||||
iny
|
iny
|
||||||
@@ -81,50 +82,50 @@ u64_load_send_filename_loop:
|
|||||||
jmp u64_load_send_filename_loop
|
jmp u64_load_send_filename_loop
|
||||||
|
|
||||||
u64_load_finalize_cmd:
|
u64_load_finalize_cmd:
|
||||||
;; Push the command for execution
|
// Push the command for execution
|
||||||
lda #U64_CTRL_BIT_PUSH_CMD
|
lda #U64_CTRL_BIT_PUSH_CMD
|
||||||
sta U64_CONTROL
|
sta U64_CONTROL
|
||||||
;; Wait till it is complete
|
// Wait till it is complete
|
||||||
*
|
!:
|
||||||
lda U64_STATUS
|
lda U64_STATUS
|
||||||
and #U64_STAT_BIT_CMD_BUSY
|
and #U64_STAT_BIT_CMD_BUSY
|
||||||
bne -
|
bne !-
|
||||||
rts
|
rts
|
||||||
|
|
||||||
u64_load_check_status:
|
u64_load_check_status:
|
||||||
;; Wait till status is available
|
// Wait till status is available
|
||||||
lda U64_STATUS
|
lda U64_STATUS
|
||||||
and #U64_STAT_BIT_STAT_AV
|
and #U64_STAT_BIT_STAT_AV
|
||||||
beq u64_load_check_status
|
beq u64_load_check_status
|
||||||
|
|
||||||
;; Status is ready - check the first character
|
// Status is ready - check the first character
|
||||||
lda U64_STATUS_DATA
|
lda U64_STATUS_DATA
|
||||||
jsr JCHROUT ; XXX for test only
|
jsr JCHROUT // XXX for test only
|
||||||
cmp #$30 ; '0'
|
cmp #$30 // '0'
|
||||||
bne u64_load_check_status_wrong
|
bne u64_load_check_status_wrong
|
||||||
|
|
||||||
;; Check the second status character
|
// Check the second status character
|
||||||
lda U64_STATUS
|
lda U64_STATUS
|
||||||
and #U64_STAT_BIT_STAT_AV
|
and #U64_STAT_BIT_STAT_AV
|
||||||
beq u64_load_check_status_ok
|
beq u64_load_check_status_ok
|
||||||
lda U64_STATUS_DATA
|
lda U64_STATUS_DATA
|
||||||
jsr JCHROUT ; XXX for test only
|
jsr JCHROUT // XXX for test only
|
||||||
cmp #$30 ; '0'
|
cmp #$30 // '0'
|
||||||
beq u64_load_check_status_ok
|
beq u64_load_check_status_ok
|
||||||
|
|
||||||
;; FALLTROUGH
|
// FALLTROUGH
|
||||||
u64_load_check_status_wrong:
|
u64_load_check_status_wrong:
|
||||||
sec
|
sec
|
||||||
bcs +
|
bcs !+
|
||||||
u64_load_check_status_ok:
|
u64_load_check_status_ok:
|
||||||
clc
|
clc
|
||||||
*
|
!:
|
||||||
;; Now empty the status queue
|
// Now empty the status queue
|
||||||
lda U64_STATUS
|
lda U64_STATUS
|
||||||
and #U64_STAT_BIT_STAT_AV
|
and #U64_STAT_BIT_STAT_AV
|
||||||
beq +
|
beq !+
|
||||||
lda U64_STATUS_DATA
|
lda U64_STATUS_DATA
|
||||||
jsr JCHROUT ; XXX for test only
|
jsr JCHROUT // XXX for test only
|
||||||
jmp -
|
jmp !-
|
||||||
*
|
!:
|
||||||
rts
|
rts
|
||||||
+9
-10
@@ -1,15 +1,14 @@
|
|||||||
|
|
||||||
;;
|
//
|
||||||
;; Official Kernal routine, described in:
|
// Official Kernal routine, described in:
|
||||||
;;
|
//
|
||||||
;; - [RG64] C64 Programmer's Reference Guide - page 274
|
// - [RG64] C64 Programmer's Reference Guide - page 274
|
||||||
;; - [CM64] Compute's Mapping the Commodore 64 - page 224/225
|
// - [CM64] Compute's Mapping the Commodore 64 - page 224/225
|
||||||
;;
|
//
|
||||||
;; CPU registers that has to be preserved (see [RG64]): .Y
|
// CPU registers that has to be preserved (see [RG64]): .Y
|
||||||
;;
|
//
|
||||||
|
|
||||||
|
|
||||||
acptr:
|
ACPTR:
|
||||||
jsr kernalstatus_reset
|
jsr kernalstatus_reset
|
||||||
jmp iec_rx_byte
|
jmp iec_rx_byte
|
||||||
|
|
||||||
+20
-20
@@ -1,41 +1,41 @@
|
|||||||
;; We have the following variables:
|
// We have the following variables:
|
||||||
;; cursor_blink_disable
|
// cursor_blink_disable
|
||||||
;; cursor_blink_countdown
|
// cursor_blink_countdown
|
||||||
;; cursor_saved_character
|
// cursor_saved_character
|
||||||
;; cursor_is_visible
|
// cursor_is_visible
|
||||||
;; colour_under_cursor
|
// colour_under_cursor
|
||||||
|
|
||||||
show_cursor_if_enabled:
|
show_cursor_if_enabled:
|
||||||
lda cursor_blink_disable
|
lda cursor_blink_disable
|
||||||
beq +
|
beq !+
|
||||||
rts
|
rts
|
||||||
* lda cursor_is_visible
|
!: lda cursor_is_visible
|
||||||
beq show_cursor
|
beq show_cursor
|
||||||
rts
|
rts
|
||||||
|
|
||||||
show_cursor:
|
show_cursor:
|
||||||
;; Set cursor as though it had just finished the off phase,
|
// Set cursor as though it had just finished the off phase,
|
||||||
;; so that the call to blink_cursor paints it
|
// so that the call to blink_cursor paints it
|
||||||
lda #$00
|
lda #$00
|
||||||
sta cursor_blink_countdown
|
sta cursor_blink_countdown
|
||||||
sta cursor_is_visible
|
sta cursor_is_visible
|
||||||
jsr blink_cursor
|
jsr blink_cursor
|
||||||
;; Then set the timeout to 1 frame, so that the cursor
|
// Then set the timeout to 1 frame, so that the cursor
|
||||||
;; blinks under key repeat conditions, like on the original KERNAL
|
// blinks under key repeat conditions, like on the original KERNAL
|
||||||
lda #$01
|
lda #$01
|
||||||
sta cursor_blink_countdown
|
sta cursor_blink_countdown
|
||||||
rts
|
rts
|
||||||
|
|
||||||
blink_cursor:
|
blink_cursor:
|
||||||
;; Is the cursor enabled?
|
// Is the cursor enabled?
|
||||||
lda cursor_blink_disable
|
lda cursor_blink_disable
|
||||||
bne no_blink_cursor
|
bne no_blink_cursor
|
||||||
|
|
||||||
;; Do we need to redraw things?
|
// Do we need to redraw things?
|
||||||
dec cursor_blink_countdown
|
dec cursor_blink_countdown
|
||||||
bpl no_blink_cursor
|
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
|
lda cursor_is_visible
|
||||||
bne undraw_cursor
|
bne undraw_cursor
|
||||||
draw_cursor:
|
draw_cursor:
|
||||||
@@ -46,7 +46,7 @@ draw_cursor:
|
|||||||
sta cursor_saved_character
|
sta cursor_saved_character
|
||||||
eor #$80
|
eor #$80
|
||||||
sta (current_screen_line_ptr),y
|
sta (current_screen_line_ptr),y
|
||||||
;; Also set cursor colour
|
// Also set cursor colour
|
||||||
lda (current_screen_line_colour_ptr),y
|
lda (current_screen_line_colour_ptr),y
|
||||||
sta colour_under_cursor
|
sta colour_under_cursor
|
||||||
lda text_colour
|
lda text_colour
|
||||||
@@ -68,10 +68,10 @@ undraw_cursor:
|
|||||||
|
|
||||||
lda #0
|
lda #0
|
||||||
sta cursor_is_visible
|
sta cursor_is_visible
|
||||||
;; Fall through
|
// Fall through
|
||||||
reset_blink_timer:
|
reset_blink_timer:
|
||||||
;; Rest blink counter
|
// Rest blink counter
|
||||||
;; (Compute's Mapping the 64, p39-40)
|
// (Compute's Mapping the 64, p39-40)
|
||||||
lda #20
|
lda #20
|
||||||
sta cursor_blink_countdown
|
sta cursor_blink_countdown
|
||||||
no_blink_cursor:
|
no_blink_cursor:
|
||||||
@@ -80,7 +80,7 @@ no_blink_cursor:
|
|||||||
disable_cursor:
|
disable_cursor:
|
||||||
lda #$80
|
lda #$80
|
||||||
sta cursor_blink_disable
|
sta cursor_blink_disable
|
||||||
;; FALL THROUGH
|
// FALL THROUGH
|
||||||
hide_cursor_if_visible:
|
hide_cursor_if_visible:
|
||||||
lda cursor_is_visible
|
lda cursor_is_visible
|
||||||
bne undraw_cursor
|
bne undraw_cursor
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
; c64 prg p263
|
// c64 prg p263
|
||||||
|
|
||||||
cartridge_check:
|
cartridge_check:
|
||||||
ldx #$04
|
ldx #$04
|
||||||
|
|||||||
+37
-37
@@ -1,64 +1,64 @@
|
|||||||
|
|
||||||
;;
|
//
|
||||||
;; Official Kernal routines, described in:
|
// Official Kernal routines, described in:
|
||||||
;;
|
//
|
||||||
;; - [RG64] C64 Programmer's Reference Guide - page 275 (CHKIN) / 276 (CKOUT)
|
// - [RG64] C64 Programmer's Reference Guide - page 275 (CHKIN) / 276 (CKOUT)
|
||||||
;; - [CM64] Compute's Mapping the Commodore 64 - page 229
|
// - [CM64] Compute's Mapping the Commodore 64 - page 229
|
||||||
;;
|
//
|
||||||
;; CPU registers that has to be preserved (see [RG64]): .Y
|
// CPU registers that has to be preserved (see [RG64]): .Y
|
||||||
;;
|
//
|
||||||
|
|
||||||
|
|
||||||
;; CHKIN implementation
|
// CHKIN implementation
|
||||||
|
|
||||||
chkin_real:
|
chkin_real:
|
||||||
|
|
||||||
;; Store Y for preservation
|
// Store Y for preservation
|
||||||
tya
|
tya
|
||||||
pha
|
pha
|
||||||
|
|
||||||
;; Reset status
|
// Reset status
|
||||||
jsr kernalstatus_reset
|
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
|
txa
|
||||||
jsr find_fls
|
jsr find_fls
|
||||||
bcs chkinout_file_not_open
|
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
|
lda FAT,Y
|
||||||
cmp #$01
|
cmp #$01
|
||||||
beq chkinout_device_not_present ; tape not implemented
|
beq chkinout_device_not_present // tape not implemented
|
||||||
cmp #$02
|
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
|
lda LAT, Y
|
||||||
cmp #$01
|
cmp #$01
|
||||||
beq chkinout_file_not_input
|
beq chkinout_file_not_input
|
||||||
|
|
||||||
;; For IEC devices, send TALK + TKSA first
|
// For IEC devices, send TALK + TKSA first
|
||||||
lda FAT,Y
|
lda FAT,Y
|
||||||
jsr iec_check_devnum
|
jsr iec_check_devnum
|
||||||
bcs chkin_set_device
|
bcs chkin_set_device
|
||||||
|
|
||||||
jsr talk
|
jsr TALK
|
||||||
bcs chkinout_device_not_present ; don't set DFLTN in case of failure
|
bcs chkinout_device_not_present // don't set DFLTN in case of failure
|
||||||
|
|
||||||
lda LAT, Y
|
lda LAT, Y
|
||||||
jsr tksa
|
jsr TKSA
|
||||||
bcs chkinout_device_not_present
|
bcs chkinout_device_not_present
|
||||||
|
|
||||||
chkin_set_device:
|
chkin_set_device:
|
||||||
lda FAT,Y
|
lda FAT,Y
|
||||||
sta DFLTN
|
sta DFLTN
|
||||||
clc ; for success
|
clc // for success
|
||||||
;; FALLTROUGH
|
// FALLTROUGH
|
||||||
|
|
||||||
;; Common part for booth CHKIN and CKOUT
|
// Common part for booth CHKIN and CKOUT
|
||||||
|
|
||||||
chkinout_end:
|
chkinout_end:
|
||||||
tax
|
tax
|
||||||
@@ -88,54 +88,54 @@ chkinout_file_not_output:
|
|||||||
tay
|
tay
|
||||||
jmp kernalerror_FILE_NOT_OUTPUT
|
jmp kernalerror_FILE_NOT_OUTPUT
|
||||||
|
|
||||||
;; CKOUT implementation
|
// CKOUT implementation
|
||||||
|
|
||||||
ckout_real:
|
ckout_real:
|
||||||
|
|
||||||
;; Store Y for preservation
|
// Store Y for preservation
|
||||||
tya
|
tya
|
||||||
pha
|
pha
|
||||||
|
|
||||||
;; Reset status
|
// Reset status
|
||||||
jsr kernalstatus_reset
|
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
|
txa
|
||||||
jsr find_fls
|
jsr find_fls
|
||||||
bcs chkinout_file_not_open
|
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
|
lda FAT,Y
|
||||||
cmp #$01
|
cmp #$01
|
||||||
beq chkinout_device_not_present ; tape not implemented
|
beq chkinout_device_not_present // tape not implemented
|
||||||
cmp #$02
|
cmp #$02
|
||||||
beq chkinout_device_not_present ; RS-232 not implemented
|
beq chkinout_device_not_present // RS-232 not implemented
|
||||||
|
|
||||||
cmp #$00
|
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
|
lda LAT, Y
|
||||||
beq chkinout_file_not_output
|
beq chkinout_file_not_output
|
||||||
|
|
||||||
;; For IEC devices, send LISTEN + SECOND first
|
// For IEC devices, send LISTEN + SECOND first
|
||||||
lda FAT,Y
|
lda FAT,Y
|
||||||
jsr iec_check_devnum
|
jsr iec_check_devnum
|
||||||
bcs chkout_set_device
|
bcs chkout_set_device
|
||||||
|
|
||||||
jsr listen
|
jsr LISTEN
|
||||||
bcs chkinout_device_not_present ; don't set DFLTO in case of failure
|
bcs chkinout_device_not_present // don't set DFLTO in case of failure
|
||||||
|
|
||||||
lda LAT, Y
|
lda LAT, Y
|
||||||
jsr second
|
jsr SECOND
|
||||||
bcs chkinout_device_not_present
|
bcs chkinout_device_not_present
|
||||||
|
|
||||||
chkout_set_device:
|
chkout_set_device:
|
||||||
lda FAT,Y
|
lda FAT,Y
|
||||||
sta DFLTO
|
sta DFLTO
|
||||||
clc ; for success
|
clc // for success
|
||||||
|
|
||||||
jmp chkinout_end
|
jmp chkinout_end
|
||||||
+51
-51
@@ -1,67 +1,67 @@
|
|||||||
|
|
||||||
;;
|
//
|
||||||
;; Official Kernal routine, described in:
|
// Official Kernal routine, described in:
|
||||||
;;
|
//
|
||||||
;; - [RG64] C64 Programmer's Reference Guide - page 277/278
|
// - [RG64] C64 Programmer's Reference Guide - page 277/278
|
||||||
;; - [CM64] Compute's Mapping the Commodore 64 - page 228
|
// - [CM64] Compute's Mapping the Commodore 64 - page 228
|
||||||
;;
|
//
|
||||||
;; CPU registers that has to be preserved (see [RG64]): .Y
|
// 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.
|
// Reads a byte of input, unless from keyboard.
|
||||||
;; If from keyboard, then it gets a whole line of input, and returns the first char.
|
// 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.
|
// Repeated calls after that read out the successive bytes of the line of input.
|
||||||
|
|
||||||
chrin_real:
|
chrin_real:
|
||||||
|
|
||||||
;; Determine the device number
|
// Determine the device number
|
||||||
lda DFLTN
|
lda DFLTN
|
||||||
|
|
||||||
beq chrin_keyboard ; #$00 - keyboard
|
beq chrin_keyboard // #$00 - keyboard
|
||||||
;; XXX add screen support
|
// XXX add screen support
|
||||||
|
|
||||||
jsr iec_check_devnum
|
jsr iec_check_devnum
|
||||||
bcc chrin_iec
|
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:
|
chrin_iec:
|
||||||
|
|
||||||
jsr JACPTR
|
jsr JACPTR
|
||||||
bcs chrin_done_fail
|
bcs chrin_done_fail
|
||||||
;; FALLTROUGH
|
// FALLTROUGH
|
||||||
|
|
||||||
chrin_done:
|
chrin_done:
|
||||||
clc ; indicate success
|
clc // indicate success
|
||||||
rts
|
rts
|
||||||
|
|
||||||
chrin_done_fail:
|
chrin_done_fail:
|
||||||
sec ; indicate failure
|
sec // indicate failure
|
||||||
rts
|
rts
|
||||||
|
|
||||||
chrin_keyboard:
|
chrin_keyboard:
|
||||||
|
|
||||||
;; Save X
|
// Save X
|
||||||
txa
|
txa
|
||||||
pha
|
pha
|
||||||
|
|
||||||
chrin_repeat:
|
chrin_repeat:
|
||||||
|
|
||||||
;; Do we have a line of input we are currently returning?
|
// 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.
|
// 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
|
lda keyboard_input_ready
|
||||||
beq read_from_keyboard
|
beq read_from_keyboard
|
||||||
|
|
||||||
;; Yes, we have input waiting at (start_of_keyboard_input)+keyboard_input_ready
|
// 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
|
// When keyboard_input_ready = end_of_input_line, then we return a carriage return
|
||||||
;; and clear the flag
|
// and clear the flag
|
||||||
cmp end_of_input_line
|
cmp end_of_input_line
|
||||||
bne not_end_of_input
|
bne not_end_of_input
|
||||||
|
|
||||||
;; Return carriage return and clear pending input flag
|
// Return carriage return and clear pending input flag
|
||||||
lda #$00
|
lda #$00
|
||||||
sta keyboard_input_ready
|
sta keyboard_input_ready
|
||||||
pla
|
pla
|
||||||
@@ -71,7 +71,7 @@ chrin_repeat:
|
|||||||
rts
|
rts
|
||||||
|
|
||||||
not_end_of_input:
|
not_end_of_input:
|
||||||
;; Return next byte of waiting input and advance index
|
// Return next byte of waiting input and advance index
|
||||||
tay
|
tay
|
||||||
pla
|
pla
|
||||||
tax
|
tax
|
||||||
@@ -86,7 +86,7 @@ read_from_keyboard:
|
|||||||
|
|
||||||
jsr enable_cursor
|
jsr enable_cursor
|
||||||
|
|
||||||
;; Wait for a key
|
// Wait for a key
|
||||||
lda keys_in_key_buffer
|
lda keys_in_key_buffer
|
||||||
beq chrin_repeat
|
beq chrin_repeat
|
||||||
|
|
||||||
@@ -100,31 +100,31 @@ read_from_keyboard:
|
|||||||
|
|
||||||
jsr hide_cursor_if_visible
|
jsr hide_cursor_if_visible
|
||||||
|
|
||||||
;; It was enter.
|
// It was enter.
|
||||||
;; Note that we have a line of input to return, and return the first byte thereof
|
// Note that we have a line of input to return, and return the first byte thereof
|
||||||
;; after computing and storing its length.
|
// after computing and storing its length.
|
||||||
;; (Compute's Mapping the 64, p96)
|
// (Compute's Mapping the 64, p96)
|
||||||
|
|
||||||
;; Set pointer to line of input
|
// Set pointer to line of input
|
||||||
lda current_screen_line_ptr+0
|
lda current_screen_line_ptr+0
|
||||||
sta start_of_keyboard_input+0
|
sta start_of_keyboard_input+0
|
||||||
lda current_screen_line_ptr+1
|
lda current_screen_line_ptr+1
|
||||||
sta start_of_keyboard_input+1
|
sta start_of_keyboard_input+1
|
||||||
|
|
||||||
;; Calculate length
|
// Calculate length
|
||||||
jsr get_current_line_logical_length
|
jsr get_current_line_logical_length
|
||||||
tay
|
tay
|
||||||
iny
|
iny
|
||||||
* dey
|
!: dey
|
||||||
bmi empty_line
|
bmi empty_line
|
||||||
lda (current_screen_line_ptr),y
|
lda (current_screen_line_ptr),y
|
||||||
cmp #$20
|
cmp #$20
|
||||||
beq -
|
beq !-
|
||||||
iny
|
iny
|
||||||
sty end_of_input_line
|
sty end_of_input_line
|
||||||
lda #$01
|
lda #$01
|
||||||
sta keyboard_input_ready
|
sta keyboard_input_ready
|
||||||
;; Return first char of line
|
// Return first char of line
|
||||||
ldy #$00
|
ldy #$00
|
||||||
pla
|
pla
|
||||||
tax
|
tax
|
||||||
@@ -134,9 +134,9 @@ read_from_keyboard:
|
|||||||
rts
|
rts
|
||||||
|
|
||||||
empty_line:
|
empty_line:
|
||||||
;; For an empty line, just return the carriage return
|
// For an empty line, just return the carriage return
|
||||||
;; (and don't forget to actually print the carriage return, so that
|
// (and don't forget to actually print the carriage return, so that
|
||||||
;; the cursor advances and screen scrolls as required)
|
// the cursor advances and screen scrolls as required)
|
||||||
pla
|
pla
|
||||||
tax
|
tax
|
||||||
clc
|
clc
|
||||||
@@ -144,28 +144,28 @@ empty_line:
|
|||||||
rts
|
rts
|
||||||
|
|
||||||
not_enter:
|
not_enter:
|
||||||
;; Print character
|
// Print character
|
||||||
lda keyboard_buffer
|
lda keyboard_buffer
|
||||||
jsr chrout
|
jsr CHROUT
|
||||||
|
|
||||||
jsr pop_keyboard_buffer
|
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
|
jmp chrin_repeat
|
||||||
|
|
||||||
pop_keyboard_buffer:
|
pop_keyboard_buffer:
|
||||||
;; Pop key out of keyboard buffer
|
// Pop key out of keyboard buffer
|
||||||
;; Disable interrupts while reading from keyboard buffer
|
// Disable interrupts while reading from keyboard buffer
|
||||||
;; so that no race conditions can occur
|
// so that no race conditions can occur
|
||||||
sei
|
sei
|
||||||
ldx #$00
|
ldx #$00
|
||||||
ldy #$01
|
ldy #$01
|
||||||
* lda keyboard_buffer,y
|
!: lda keyboard_buffer,y
|
||||||
sta keyboard_buffer,x
|
sta keyboard_buffer,x
|
||||||
inx
|
inx
|
||||||
iny
|
iny
|
||||||
cpy key_buffer_size
|
cpy key_buffer_size
|
||||||
bne -
|
bne !-
|
||||||
dec keys_in_key_buffer
|
dec keys_in_key_buffer
|
||||||
cli
|
cli
|
||||||
|
|
||||||
@@ -199,12 +199,12 @@ not_shifted:
|
|||||||
cmp #$80
|
cmp #$80
|
||||||
bcs not_vendor
|
bcs not_vendor
|
||||||
|
|
||||||
;; $60-$7F -> $A0-$BF
|
// $60-$7F -> $A0-$BF
|
||||||
|
|
||||||
clc
|
clc
|
||||||
adc #$40
|
adc #$40
|
||||||
|
|
||||||
;; FALLTROUGH
|
// FALLTROUGH
|
||||||
not_vendor:
|
not_vendor:
|
||||||
rts
|
rts
|
||||||
|
|
||||||
+223
-223
@@ -1,36 +1,36 @@
|
|||||||
|
|
||||||
;;
|
//
|
||||||
;; Official Kernal routine, described in:
|
// Official Kernal routine, described in:
|
||||||
;;
|
//
|
||||||
;; - [RG64] C64 Programmer's Reference Guide - page 278/279
|
// - [RG64] C64 Programmer's Reference Guide - page 278/279
|
||||||
;; - [CM64] Compute's Mapping the Commodore 64 - page 228
|
// - [CM64] Compute's Mapping the Commodore 64 - page 228
|
||||||
;;
|
//
|
||||||
;; CPU registers that has to be preserved (see [RG64]): .Y
|
// CPU registers that has to be preserved (see [RG64]): .Y
|
||||||
;;
|
//
|
||||||
|
|
||||||
|
|
||||||
chrout_real:
|
chrout_real:
|
||||||
|
|
||||||
sta last_printed_character_ascii
|
sta last_printed_character_ascii
|
||||||
|
|
||||||
;; Save X and Y values
|
// Save X and Y values
|
||||||
;; (Confirmed by writing a test program that X and Y
|
// (Confirmed by writing a test program that X and Y
|
||||||
;; don't get modified, in agreement with C64 PRG's
|
// don't get modified, in agreement with C64 PRG's
|
||||||
;; description of CHROUT)
|
// description of CHROUT)
|
||||||
txa
|
txa
|
||||||
pha
|
pha
|
||||||
tya
|
tya
|
||||||
pha
|
pha
|
||||||
php
|
php
|
||||||
|
|
||||||
;; Determine the device number
|
// Determine the device number
|
||||||
lda DFLTO
|
lda DFLTO
|
||||||
|
|
||||||
cmp #$03 ; screen
|
cmp #$03 // screen
|
||||||
beq chrout_screen
|
beq chrout_screen
|
||||||
|
|
||||||
jsr iec_check_devnum
|
jsr iec_check_devnum
|
||||||
bcs chrout_done_unknown_device ; not a supported device
|
bcs chrout_done_unknown_device // not a supported device
|
||||||
|
|
||||||
chrout_iec:
|
chrout_iec:
|
||||||
|
|
||||||
@@ -38,19 +38,19 @@ chrout_iec:
|
|||||||
jsr JCIOUT
|
jsr JCIOUT
|
||||||
bcc chrout_done
|
bcc chrout_done
|
||||||
|
|
||||||
;; FALLTROUGH
|
// FALLTROUGH
|
||||||
|
|
||||||
chrout_done_fail:
|
chrout_done_fail:
|
||||||
jsr show_cursor_if_enabled
|
jsr show_cursor_if_enabled
|
||||||
|
|
||||||
plp
|
plp
|
||||||
|
|
||||||
;; Restore X and Y
|
// Restore X and Y
|
||||||
pla
|
pla
|
||||||
tay
|
tay
|
||||||
pla
|
pla
|
||||||
tax
|
tax
|
||||||
sec ; indicate failure
|
sec // indicate failure
|
||||||
rts
|
rts
|
||||||
|
|
||||||
chrout_done_unknown_device:
|
chrout_done_unknown_device:
|
||||||
@@ -58,13 +58,13 @@ chrout_done_unknown_device:
|
|||||||
|
|
||||||
plp
|
plp
|
||||||
|
|
||||||
;; Restore X and Y
|
// Restore X and Y
|
||||||
pla
|
pla
|
||||||
tay
|
tay
|
||||||
pla
|
pla
|
||||||
tax
|
tax
|
||||||
|
|
||||||
;; End wioth error
|
// End wioth error
|
||||||
jmp lvs_device_not_found_error
|
jmp lvs_device_not_found_error
|
||||||
|
|
||||||
chrout_done:
|
chrout_done:
|
||||||
@@ -72,43 +72,43 @@ chrout_done:
|
|||||||
|
|
||||||
plp
|
plp
|
||||||
|
|
||||||
;; Restore X and Y
|
// Restore X and Y
|
||||||
pla
|
pla
|
||||||
tay
|
tay
|
||||||
pla
|
pla
|
||||||
tax
|
tax
|
||||||
lda last_printed_character_ascii
|
lda last_printed_character_ascii
|
||||||
clc ; indicate success
|
clc // indicate success
|
||||||
rts
|
rts
|
||||||
|
|
||||||
chrout_screen:
|
chrout_screen:
|
||||||
|
|
||||||
;; Crude implementation of character output
|
// Crude implementation of character output
|
||||||
sei ;; XXX why do we need to disable interrupts?
|
sei // XXX why do we need to disable interrupts?
|
||||||
|
|
||||||
jsr hide_cursor_if_visible
|
jsr hide_cursor_if_visible
|
||||||
|
|
||||||
lda last_printed_character_ascii
|
lda last_printed_character_ascii
|
||||||
tax
|
tax
|
||||||
|
|
||||||
;; Check for special characters
|
// Check for special characters
|
||||||
|
|
||||||
cmp #$00
|
cmp #$00
|
||||||
bne not_00
|
bne not_00
|
||||||
jmp chrout_done
|
jmp chrout_done
|
||||||
not_00:
|
not_00:
|
||||||
|
|
||||||
;; Linefeed (simply ignored)
|
// Linefeed (simply ignored)
|
||||||
;; Trivia: BASIC does CRLF with READY. prompt
|
// Trivia: BASIC does CRLF with READY. prompt
|
||||||
cmp #$0a
|
cmp #$0a
|
||||||
bne not_0a
|
bne not_0a
|
||||||
jmp chrout_done
|
jmp chrout_done
|
||||||
not_0a:
|
not_0a:
|
||||||
|
|
||||||
;; Carriage return
|
// Carriage return
|
||||||
cmp #$0d
|
cmp #$0d
|
||||||
bne not_0d
|
bne not_0d
|
||||||
;; RETURN clears quote and insert modes
|
// RETURN clears quote and insert modes
|
||||||
lda #$00
|
lda #$00
|
||||||
sta quote_mode_flag
|
sta quote_mode_flag
|
||||||
sta insert_mode
|
sta insert_mode
|
||||||
@@ -118,9 +118,9 @@ not_0d:
|
|||||||
cmp #$94
|
cmp #$94
|
||||||
bne not_94
|
bne not_94
|
||||||
|
|
||||||
;; Insert (shift-DELETE)
|
// Insert (shift-DELETE)
|
||||||
|
|
||||||
;; Abort if line already max length, ie 79th char is not a space
|
// Abort if line already max length, ie 79th char is not a space
|
||||||
jsr get_current_line_logical_length
|
jsr get_current_line_logical_length
|
||||||
cmp #79
|
cmp #79
|
||||||
bne definitely_not_too_long
|
bne definitely_not_too_long
|
||||||
@@ -129,11 +129,11 @@ not_0d:
|
|||||||
cmp #$20
|
cmp #$20
|
||||||
beq definitely_not_too_long
|
beq definitely_not_too_long
|
||||||
|
|
||||||
;; Line is too long to extend
|
// Line is too long to extend
|
||||||
jmp chrout_done
|
jmp chrout_done
|
||||||
|
|
||||||
definitely_not_too_long:
|
definitely_not_too_long:
|
||||||
;; Work out if line needs to be expanded, and if so expand it
|
// Work out if line needs to be expanded, and if so expand it
|
||||||
ldy #39
|
ldy #39
|
||||||
lda (current_screen_line_ptr),y
|
lda (current_screen_line_ptr),y
|
||||||
cmp #$20
|
cmp #$20
|
||||||
@@ -142,18 +142,18 @@ definitely_not_too_long:
|
|||||||
jsr screen_grow_logical_line
|
jsr screen_grow_logical_line
|
||||||
|
|
||||||
no_need_to_extend:
|
no_need_to_extend:
|
||||||
;; Shuffle chars towards end of line
|
// Shuffle chars towards end of line
|
||||||
jsr get_current_line_logical_length
|
jsr get_current_line_logical_length
|
||||||
tay
|
tay
|
||||||
*
|
!:
|
||||||
;; Note: While the following routine is obvious to any skilled
|
// Note: While the following routine is obvious to any skilled
|
||||||
;; in the art as the most obvious simple and efficient solution,
|
// in the art as the most obvious simple and efficient solution,
|
||||||
;; if the screen writes are before the colour writes, it results
|
// if the screen writes are before the colour writes, it results
|
||||||
;; in a relatively long verbatim stretch of bytes when compared to
|
// in a relatively long verbatim stretch of bytes when compared to
|
||||||
;; the C64 KERNAL. Thus we have swapped the order, just to reduce
|
// the C64 KERNAL. Thus we have swapped the order, just to reduce
|
||||||
;; the potential for any argument of copyright infringement, even
|
// the potential for any argument of copyright infringement, even
|
||||||
;; though we really don't believe that the routine can be copyrighted
|
// though we really don't believe that the routine can be copyrighted
|
||||||
;; due to the lack of creativity.
|
// due to the lack of creativity.
|
||||||
dey
|
dey
|
||||||
lda (current_screen_line_colour_ptr),y
|
lda (current_screen_line_colour_ptr),y
|
||||||
iny
|
iny
|
||||||
@@ -165,36 +165,36 @@ no_need_to_extend:
|
|||||||
|
|
||||||
dey
|
dey
|
||||||
cpy current_screen_x
|
cpy current_screen_x
|
||||||
bne -
|
bne !-
|
||||||
|
|
||||||
;; Increase insert mode count (which causes quote-mode like behaviour)
|
// Increase insert mode count (which causes quote-mode like behaviour)
|
||||||
inc insert_mode
|
inc insert_mode
|
||||||
|
|
||||||
;; Put space in the inserted gap
|
// Put space in the inserted gap
|
||||||
lda #$20
|
lda #$20
|
||||||
sta (current_screen_line_ptr),y
|
sta (current_screen_line_ptr),y
|
||||||
|
|
||||||
jmp chrout_done
|
jmp chrout_done
|
||||||
not_94:
|
not_94:
|
||||||
|
|
||||||
;; DELETE in insert mode embeds control character
|
// DELETE in insert mode embeds control character
|
||||||
ldx insert_mode
|
ldx insert_mode
|
||||||
bne not_14
|
bne not_14
|
||||||
|
|
||||||
cmp #$14
|
cmp #$14
|
||||||
bne not_14
|
bne not_14
|
||||||
|
|
||||||
;; Delete
|
// Delete
|
||||||
ldx current_screen_x
|
ldx current_screen_x
|
||||||
bne delete_non_zero_column
|
bne delete_non_zero_column
|
||||||
delete_at_column_0:
|
delete_at_column_0:
|
||||||
ldy current_screen_y
|
ldy current_screen_y
|
||||||
bne not_row_0
|
bne not_row_0
|
||||||
;; delete from row 0, col 0 does nothing
|
// delete from row 0, col 0 does nothing
|
||||||
jmp chrout_done
|
jmp chrout_done
|
||||||
not_row_0:
|
not_row_0:
|
||||||
;; Column 0 delete just moves us to the end of the
|
// Column 0 delete just moves us to the end of the
|
||||||
;; previous line, without actually deleting anything
|
// previous line, without actually deleting anything
|
||||||
dec current_screen_y
|
dec current_screen_y
|
||||||
jsr get_current_line_logical_length
|
jsr get_current_line_logical_length
|
||||||
lda logical_line_length
|
lda logical_line_length
|
||||||
@@ -204,13 +204,13 @@ not_row_0:
|
|||||||
jmp chrout_done
|
jmp chrout_done
|
||||||
|
|
||||||
delete_non_zero_column:
|
delete_non_zero_column:
|
||||||
;; Copy rest of line down
|
// Copy rest of line down
|
||||||
jsr get_current_line_logical_length
|
jsr get_current_line_logical_length
|
||||||
ldy current_screen_x
|
ldy current_screen_x
|
||||||
cpy logical_line_length
|
cpy logical_line_length
|
||||||
beq done_delete
|
beq done_delete
|
||||||
dey
|
dey
|
||||||
*
|
!:
|
||||||
iny
|
iny
|
||||||
lda (current_screen_line_ptr),y
|
lda (current_screen_line_ptr),y
|
||||||
dey
|
dey
|
||||||
@@ -221,9 +221,9 @@ delete_non_zero_column:
|
|||||||
sta (current_screen_line_colour_ptr),y
|
sta (current_screen_line_colour_ptr),y
|
||||||
iny
|
iny
|
||||||
cpy logical_line_length
|
cpy logical_line_length
|
||||||
bne -
|
bne !-
|
||||||
|
|
||||||
;; Clear char at end of line
|
// Clear char at end of line
|
||||||
jsr get_current_line_logical_length
|
jsr get_current_line_logical_length
|
||||||
tay
|
tay
|
||||||
lda #$20
|
lda #$20
|
||||||
@@ -234,7 +234,7 @@ done_delete:
|
|||||||
jmp chrout_done
|
jmp chrout_done
|
||||||
not_14:
|
not_14:
|
||||||
|
|
||||||
;; Check for quote mode
|
// Check for quote mode
|
||||||
ldx quote_mode_flag
|
ldx quote_mode_flag
|
||||||
bne is_quote_mode
|
bne is_quote_mode
|
||||||
ldx insert_mode
|
ldx insert_mode
|
||||||
@@ -242,51 +242,51 @@ not_14:
|
|||||||
jmp not_quote_mode
|
jmp not_quote_mode
|
||||||
|
|
||||||
is_quote_mode:
|
is_quote_mode:
|
||||||
;; Is it a control code?
|
// Is it a control code?
|
||||||
;; control codes are $00-$1f and $80-$9f
|
// control codes are $00-$1f and $80-$9f
|
||||||
;; (from reading C64 PRG p379-381)
|
// (from reading C64 PRG p379-381)
|
||||||
;; so we can just check if bits 5 or 6 are set, and if so,
|
// so we can just check if bits 5 or 6 are set, and if so,
|
||||||
;; then it isn't a control character.
|
// then it isn't a control character.
|
||||||
pha
|
pha
|
||||||
and #$60
|
and #$60
|
||||||
bne +
|
bne !+
|
||||||
|
|
||||||
;; Yes, a control code in quote mode means we display it as a reverse character
|
// Yes, a control code in quote mode means we display it as a reverse character
|
||||||
pla
|
pla
|
||||||
|
|
||||||
;; Low control codes are just +$80
|
// Low control codes are just +$80
|
||||||
clc
|
clc
|
||||||
adc #$80
|
adc #$80
|
||||||
;; If it overflowed, then it is a high control code,
|
// If it overflowed, then it is a high control code,
|
||||||
;; so we need to make it be $80 + $40 + char
|
// so we need to make it be $80 + $40 + char
|
||||||
;; as we will have flipped back to just $00 + char, we should
|
// as we will have flipped back to just $00 + char, we should
|
||||||
;; now add $c0 if C is set from overflow
|
// now add $c0 if C is set from overflow
|
||||||
bcc low_ctrl_char
|
bcc low_ctrl_char
|
||||||
adc #$bf ; C=1, so adding $BF + C = add $C0
|
adc #$bf // C=1, so adding $BF + C = add $C0
|
||||||
low_ctrl_char:
|
low_ctrl_char:
|
||||||
jmp output_literal_char
|
jmp output_literal_char
|
||||||
*
|
!:
|
||||||
pla
|
pla
|
||||||
not_quote_mode:
|
not_quote_mode:
|
||||||
|
|
||||||
;; Check for colours
|
// Check for colours
|
||||||
ldx #$f
|
ldx #$f
|
||||||
colour_check_loop:
|
colour_check_loop:
|
||||||
cmp colour_codes,x
|
cmp colour_codes,x
|
||||||
bne +
|
bne !+
|
||||||
stx text_colour
|
stx text_colour
|
||||||
jmp chrout_done
|
jmp chrout_done
|
||||||
* dex
|
!: dex
|
||||||
bpl colour_check_loop
|
bpl colour_check_loop
|
||||||
|
|
||||||
;; Compute's Mapping the 64 p38
|
// Compute's Mapping the 64 p38
|
||||||
cmp #$12
|
cmp #$12
|
||||||
bne not_12
|
bne not_12
|
||||||
lda #$80
|
lda #$80
|
||||||
sta reverse_video_flag
|
sta reverse_video_flag
|
||||||
jmp chrout_done
|
jmp chrout_done
|
||||||
not_12:
|
not_12:
|
||||||
;; Compute's Mapping the 64 p 38
|
// Compute's Mapping the 64 p 38
|
||||||
cmp #$92
|
cmp #$92
|
||||||
bne not_92
|
bne not_92
|
||||||
lda #$00
|
lda #$00
|
||||||
@@ -294,17 +294,17 @@ not_12:
|
|||||||
jmp chrout_done
|
jmp chrout_done
|
||||||
not_92:
|
not_92:
|
||||||
|
|
||||||
;; Check for cursor movement keys
|
// Check for cursor movement keys
|
||||||
cmp #$11
|
cmp #$11
|
||||||
bne not_11
|
bne not_11
|
||||||
lda current_screen_x
|
lda current_screen_x
|
||||||
clc
|
clc
|
||||||
adc #40
|
adc #40
|
||||||
sta current_screen_x
|
sta current_screen_x
|
||||||
;; We need to advance the pointer manually, as normalising
|
// We need to advance the pointer manually, as normalising
|
||||||
;; now will break things. The pointer update is required
|
// now will break things. The pointer update is required
|
||||||
;; so that we can tell if we really are on the bottom phys
|
// so that we can tell if we really are on the bottom phys
|
||||||
;; screen line or not
|
// screen line or not
|
||||||
jsr scroll_up_if_on_last_line
|
jsr scroll_up_if_on_last_line
|
||||||
jsr calculate_screen_line_pointer
|
jsr calculate_screen_line_pointer
|
||||||
jmp chrout_done
|
jmp chrout_done
|
||||||
@@ -331,7 +331,7 @@ not_91:
|
|||||||
jmp chrout_done
|
jmp chrout_done
|
||||||
not_9d:
|
not_9d:
|
||||||
|
|
||||||
;; Home cursor
|
// Home cursor
|
||||||
cmp #$13
|
cmp #$13
|
||||||
bne not_13
|
bne not_13
|
||||||
lda #0
|
lda #0
|
||||||
@@ -341,7 +341,7 @@ not_9d:
|
|||||||
jmp chrout_done
|
jmp chrout_done
|
||||||
not_13:
|
not_13:
|
||||||
|
|
||||||
;; Clear screen
|
// Clear screen
|
||||||
cmp #$93
|
cmp #$93
|
||||||
bne not_clearscreen
|
bne not_clearscreen
|
||||||
jsr clear_screen
|
jsr clear_screen
|
||||||
@@ -349,41 +349,41 @@ not_13:
|
|||||||
|
|
||||||
not_clearscreen:
|
not_clearscreen:
|
||||||
|
|
||||||
;; Convert PETSCII to screen code
|
// Convert PETSCII to screen code
|
||||||
|
|
||||||
;; Don't print other control codes
|
// Don't print other control codes
|
||||||
cmp #$1f
|
cmp #$1f
|
||||||
bcs +
|
bcs !+
|
||||||
jmp chrout_done
|
jmp chrout_done
|
||||||
*
|
!:
|
||||||
|
|
||||||
;; Codes $C0-$DF become $40-$5F
|
// Codes $C0-$DF become $40-$5F
|
||||||
;; But
|
// But
|
||||||
cmp #$e0
|
cmp #$e0
|
||||||
bcs +
|
bcs !+
|
||||||
cmp #$c0
|
cmp #$c0
|
||||||
bcc +
|
bcc !+
|
||||||
|
|
||||||
and #$7f
|
and #$7f
|
||||||
jmp not_high_char
|
jmp not_high_char
|
||||||
|
|
||||||
*
|
!:
|
||||||
;; Range $20-$3F is unchanged
|
// Range $20-$3F is unchanged
|
||||||
cmp #$40
|
cmp #$40
|
||||||
bcc not_high_char
|
bcc not_high_char
|
||||||
|
|
||||||
;; Unshifted letters and symbols from $40-$5F
|
// Unshifted letters and symbols from $40-$5F
|
||||||
;; all end up being -$40
|
// all end up being -$40
|
||||||
;; (C64 PRG p376)
|
// (C64 PRG p376)
|
||||||
|
|
||||||
;; But anything >= $80 needs to be -$40
|
// But anything >= $80 needs to be -$40
|
||||||
;; (C64 PRG p380-381)
|
// (C64 PRG p380-381)
|
||||||
;; And bit 7 should be cleared, only to be
|
// And bit 7 should be cleared, only to be
|
||||||
;; set by reverse video
|
// set by reverse video
|
||||||
sec
|
sec
|
||||||
sbc #$40
|
sbc #$40
|
||||||
|
|
||||||
;; Fix shifted chars by adding $20 again
|
// Fix shifted chars by adding $20 again
|
||||||
cmp #$20
|
cmp #$20
|
||||||
bcc not_high_char
|
bcc not_high_char
|
||||||
cmp #$40
|
cmp #$40
|
||||||
@@ -397,45 +397,45 @@ chrout_l1:
|
|||||||
|
|
||||||
output_literal_char:
|
output_literal_char:
|
||||||
|
|
||||||
;; Write normal character on the screen
|
// Write normal character on the screen
|
||||||
|
|
||||||
pha
|
pha
|
||||||
|
|
||||||
ldy current_screen_x
|
ldy current_screen_x
|
||||||
ora reverse_video_flag ; Compute's Mapping the 64 p38
|
ora reverse_video_flag // Compute's Mapping the 64 p38
|
||||||
sta (current_screen_line_ptr),y
|
sta (current_screen_line_ptr),y
|
||||||
|
|
||||||
;; Decrement number of chars waiting to be inserted
|
// Decrement number of chars waiting to be inserted
|
||||||
lda insert_mode
|
lda insert_mode
|
||||||
beq +
|
beq !+
|
||||||
dec insert_mode
|
dec insert_mode
|
||||||
*
|
!:
|
||||||
pla
|
pla
|
||||||
cmp #$22
|
cmp #$22
|
||||||
bne not_quote
|
bne not_quote
|
||||||
|
|
||||||
;; Toggle quote flag if required
|
// Toggle quote flag if required
|
||||||
lda quote_mode_flag
|
lda quote_mode_flag
|
||||||
eor #$80
|
eor #$80
|
||||||
sta quote_mode_flag
|
sta quote_mode_flag
|
||||||
|
|
||||||
not_quote:
|
not_quote:
|
||||||
|
|
||||||
;; Set colour
|
// Set colour
|
||||||
lda text_colour
|
lda text_colour
|
||||||
sta (current_screen_line_colour_ptr),y
|
sta (current_screen_line_colour_ptr),y
|
||||||
|
|
||||||
;; Advance the column, and scroll screen down if we need
|
// Advance the column, and scroll screen down if we need
|
||||||
;; to insert a 2nd line in this logical line.
|
// to insert a 2nd line in this logical line.
|
||||||
;; (eg Compute's Mapping the 64 p41)
|
// (eg Compute's Mapping the 64 p41)
|
||||||
ldx current_screen_y
|
ldx current_screen_y
|
||||||
iny
|
iny
|
||||||
sty current_screen_x
|
sty current_screen_x
|
||||||
cpy #40
|
cpy #40
|
||||||
bne +
|
bne !+
|
||||||
jsr screen_grow_logical_line
|
jsr screen_grow_logical_line
|
||||||
ldy current_screen_x
|
ldy current_screen_x
|
||||||
*
|
!:
|
||||||
cpy #80
|
cpy #80
|
||||||
bcc no_screen_advance_to_next_line
|
bcc no_screen_advance_to_next_line
|
||||||
lda #0
|
lda #0
|
||||||
@@ -446,35 +446,35 @@ no_screen_advance_to_next_line:
|
|||||||
|
|
||||||
screen_grow_logical_line:
|
screen_grow_logical_line:
|
||||||
ldy current_screen_y
|
ldy current_screen_y
|
||||||
;; Don't grow line if it is already grown
|
// Don't grow line if it is already grown
|
||||||
lda screen_line_link_table,y
|
lda screen_line_link_table,y
|
||||||
bpl +
|
bpl !+
|
||||||
jmp done_grow_line
|
jmp done_grow_line
|
||||||
*
|
!:
|
||||||
lda #$80
|
lda #$80
|
||||||
sta screen_line_link_table,y
|
sta screen_line_link_table,y
|
||||||
|
|
||||||
;; Now make space for the extra line added.
|
// Now make space for the extra line added.
|
||||||
;; If we are on the last physical line of the screen,
|
// If we are on the last physical line of the screen,
|
||||||
;; Then we need to scroll the screen up
|
// Then we need to scroll the screen up
|
||||||
jsr scroll_up_if_on_last_line
|
jsr scroll_up_if_on_last_line
|
||||||
|
|
||||||
;; Scroll screen down to make space
|
// Scroll screen down to make space
|
||||||
;; As we are scrolling down, we start from the end,
|
// As we are scrolling down, we start from the end,
|
||||||
;; and work backwards. We can't be as simple and efficient
|
// and work backwards. We can't be as simple and efficient
|
||||||
;; here as we are for scrolling up, because we don't know
|
// here as we are for scrolling up, because we don't know
|
||||||
;; how much must be scrolled.
|
// how much must be scrolled.
|
||||||
;; Simple solution is to work out how many physical lines
|
// Simple solution is to work out how many physical lines
|
||||||
;; need shifting down, and then move lines at a time after
|
// need shifting down, and then move lines at a time after
|
||||||
;; initialising the pointers to the end area of the screen.
|
// initialising the pointers to the end area of the screen.
|
||||||
ldx #25-2
|
ldx #25-2
|
||||||
ldy #0
|
ldy #0
|
||||||
count_rows_loop:
|
count_rows_loop:
|
||||||
dex
|
dex
|
||||||
lda screen_line_link_table,y
|
lda screen_line_link_table,y
|
||||||
bpl +
|
bpl !+
|
||||||
dex
|
dex
|
||||||
* iny
|
!: iny
|
||||||
cpy current_screen_y
|
cpy current_screen_y
|
||||||
bne count_rows_loop
|
bne count_rows_loop
|
||||||
|
|
||||||
@@ -482,14 +482,14 @@ count_rows_loop:
|
|||||||
beq no_copy_down
|
beq no_copy_down
|
||||||
bmi no_copy_down
|
bmi no_copy_down
|
||||||
|
|
||||||
;; Set pointers to end of screen line, and one line
|
// Set pointers to end of screen line, and one line
|
||||||
;; above. (It is always one physical line, because
|
// above. (It is always one physical line, because
|
||||||
;; this can only happen when expanding a line from 40 to
|
// this can only happen when expanding a line from 40 to
|
||||||
;; 80 characters).
|
// 80 characters).
|
||||||
;; XXX - This is not very efficient, and longer than it
|
// XXX - This is not very efficient, and longer than it
|
||||||
;; needs to be. Better would be to work out size to
|
// needs to be. Better would be to work out size to
|
||||||
;; copy, and count it down in a pointer somewhere, so
|
// copy, and count it down in a pointer somewhere, so
|
||||||
;; that loop iteration logic is simpler.
|
// that loop iteration logic is simpler.
|
||||||
lda HIBASE
|
lda HIBASE
|
||||||
clc
|
clc
|
||||||
adc #3
|
adc #3
|
||||||
@@ -502,7 +502,7 @@ count_rows_loop:
|
|||||||
lda #<$03C0
|
lda #<$03C0
|
||||||
sta current_screen_line_ptr+0
|
sta current_screen_line_ptr+0
|
||||||
sta current_screen_line_colour_ptr+0
|
sta current_screen_line_colour_ptr+0
|
||||||
;; souce address is line above
|
// souce address is line above
|
||||||
sec
|
sec
|
||||||
sbc #40
|
sbc #40
|
||||||
sta load_or_scroll_temp_pointer+0
|
sta load_or_scroll_temp_pointer+0
|
||||||
@@ -518,11 +518,11 @@ cl_inner:
|
|||||||
dey
|
dey
|
||||||
bpl cl_inner
|
bpl cl_inner
|
||||||
|
|
||||||
;; Decrement all pointers by 40
|
// Decrement all pointers by 40
|
||||||
;; Low bytes are in common pairs
|
// Low bytes are in common pairs
|
||||||
|
|
||||||
;; Old source is new destination
|
// Old source is new destination
|
||||||
;; Use different registers to minimise byte similarity with C64 KERNAl
|
// Use different registers to minimise byte similarity with C64 KERNAl
|
||||||
ldy load_or_scroll_temp_pointer+1
|
ldy load_or_scroll_temp_pointer+1
|
||||||
sty current_screen_line_ptr+1
|
sty current_screen_line_ptr+1
|
||||||
lda load_save_verify_end_address+1
|
lda load_save_verify_end_address+1
|
||||||
@@ -531,7 +531,7 @@ cl_inner:
|
|||||||
sty current_screen_line_ptr+0
|
sty current_screen_line_ptr+0
|
||||||
sty current_screen_line_colour_ptr+0
|
sty current_screen_line_colour_ptr+0
|
||||||
|
|
||||||
;; Decrementing source pointers
|
// Decrementing source pointers
|
||||||
lda load_or_scroll_temp_pointer+0
|
lda load_or_scroll_temp_pointer+0
|
||||||
sec
|
sec
|
||||||
sbc #<40
|
sbc #<40
|
||||||
@@ -540,7 +540,7 @@ cl_inner:
|
|||||||
lda load_or_scroll_temp_pointer+1
|
lda load_or_scroll_temp_pointer+1
|
||||||
sbc #>40
|
sbc #>40
|
||||||
sta load_or_scroll_temp_pointer+1
|
sta load_or_scroll_temp_pointer+1
|
||||||
;; convert to screen equivalent
|
// convert to screen equivalent
|
||||||
sec
|
sec
|
||||||
sbc HIBASE
|
sbc HIBASE
|
||||||
clc
|
clc
|
||||||
@@ -553,16 +553,16 @@ cl_inner:
|
|||||||
no_copy_down:
|
no_copy_down:
|
||||||
jsr calculate_screen_line_pointer
|
jsr calculate_screen_line_pointer
|
||||||
|
|
||||||
;; Erase newly inserted line
|
// Erase newly inserted line
|
||||||
ldy #79
|
ldy #79
|
||||||
*
|
!:
|
||||||
lda text_colour
|
lda text_colour
|
||||||
sta (current_screen_line_colour_ptr),y
|
sta (current_screen_line_colour_ptr),y
|
||||||
lda #$20
|
lda #$20
|
||||||
sta (current_screen_line_ptr),y
|
sta (current_screen_line_ptr),y
|
||||||
dey
|
dey
|
||||||
cpy #40
|
cpy #40
|
||||||
bne -
|
bne !-
|
||||||
|
|
||||||
rts
|
rts
|
||||||
|
|
||||||
@@ -572,9 +572,9 @@ not_last_line:
|
|||||||
|
|
||||||
scroll_up_if_on_last_line:
|
scroll_up_if_on_last_line:
|
||||||
|
|
||||||
;; Colour RAM is always in fixed place, so is easiest
|
// Colour RAM is always in fixed place, so is easiest
|
||||||
;; to use to check if we are on the last line.
|
// to use to check if we are on the last line.
|
||||||
;; The last line is at $D800 + 24*40 = $DBC0
|
// The last line is at $D800 + 24*40 = $DBC0
|
||||||
lda current_screen_line_colour_ptr+1
|
lda current_screen_line_colour_ptr+1
|
||||||
cmp #>$DBC0
|
cmp #>$DBC0
|
||||||
bne not_last_line
|
bne not_last_line
|
||||||
@@ -593,13 +593,13 @@ is_last_line:
|
|||||||
|
|
||||||
dec current_screen_y
|
dec current_screen_y
|
||||||
|
|
||||||
;; FALL THROUGH
|
// FALL THROUGH
|
||||||
|
|
||||||
scroll_screen_up:
|
scroll_screen_up:
|
||||||
;; Now scroll the whole screen up either one or two lines
|
// Now scroll the whole screen up either one or two lines
|
||||||
;; based on whether the first screen line is linked or not.
|
// based on whether the first screen line is linked or not.
|
||||||
|
|
||||||
;; Get pointers to start of screen + colour RAM
|
// Get pointers to start of screen + colour RAM
|
||||||
lda HIBASE
|
lda HIBASE
|
||||||
sta current_screen_line_ptr+1
|
sta current_screen_line_ptr+1
|
||||||
sta load_or_scroll_temp_pointer+1
|
sta load_or_scroll_temp_pointer+1
|
||||||
@@ -610,17 +610,17 @@ scroll_screen_up:
|
|||||||
sta current_screen_line_ptr+0
|
sta current_screen_line_ptr+0
|
||||||
sta current_screen_line_colour_ptr+0
|
sta current_screen_line_colour_ptr+0
|
||||||
|
|
||||||
;; Get pointers to screen/colour RAM source
|
// Get pointers to screen/colour RAM source
|
||||||
lda screen_line_link_table+0
|
lda screen_line_link_table+0
|
||||||
bmi +
|
bmi !+
|
||||||
lda #40
|
lda #40
|
||||||
.byte $2C ; BIT $nnnn to skip next instruction
|
.byte $2C // BIT $nnnn to skip next instruction
|
||||||
*
|
!:
|
||||||
lda #80
|
lda #80
|
||||||
sta load_or_scroll_temp_pointer+0
|
sta load_or_scroll_temp_pointer+0
|
||||||
sta load_save_verify_end_address+0
|
sta load_save_verify_end_address+0
|
||||||
|
|
||||||
;; Copy first three pages
|
// Copy first three pages
|
||||||
ldy #$00
|
ldy #$00
|
||||||
ldx #3
|
ldx #3
|
||||||
scroll_copy_loop:
|
scroll_copy_loop:
|
||||||
@@ -639,9 +639,9 @@ scroll_copy_loop:
|
|||||||
dex
|
dex
|
||||||
bne scroll_copy_loop
|
bne scroll_copy_loop
|
||||||
|
|
||||||
;; Copy last partial page
|
// Copy last partial page
|
||||||
;; We need to copy 1000-(3*256)-line length
|
// We need to copy 1000-(3*256)-line length
|
||||||
;; = 232 - line length
|
// = 232 - line length
|
||||||
lda load_or_scroll_temp_pointer+0
|
lda load_or_scroll_temp_pointer+0
|
||||||
lda #232
|
lda #232
|
||||||
sec
|
sec
|
||||||
@@ -656,7 +656,7 @@ scroll_copy_loop2:
|
|||||||
dex
|
dex
|
||||||
bne scroll_copy_loop2
|
bne scroll_copy_loop2
|
||||||
|
|
||||||
;; Fill in scrolled up area
|
// Fill in scrolled up area
|
||||||
ldx load_or_scroll_temp_pointer+0
|
ldx load_or_scroll_temp_pointer+0
|
||||||
scroll_copy_loop3:
|
scroll_copy_loop3:
|
||||||
lda text_colour
|
lda text_colour
|
||||||
@@ -667,7 +667,7 @@ scroll_copy_loop3:
|
|||||||
dex
|
dex
|
||||||
bne scroll_copy_loop3
|
bne scroll_copy_loop3
|
||||||
|
|
||||||
;; Shift line linkage list
|
// Shift line linkage list
|
||||||
ldy #0
|
ldy #0
|
||||||
ldx #24
|
ldx #24
|
||||||
link_copy:
|
link_copy:
|
||||||
@@ -676,10 +676,10 @@ link_copy:
|
|||||||
iny
|
iny
|
||||||
dex
|
dex
|
||||||
bne link_copy
|
bne link_copy
|
||||||
;; Clear line link flag of last line
|
// Clear line link flag of last line
|
||||||
stx screen_line_link_table+24
|
stx screen_line_link_table+24
|
||||||
|
|
||||||
;; Restore correct line pointers
|
// Restore correct line pointers
|
||||||
jsr calculate_screen_line_pointer
|
jsr calculate_screen_line_pointer
|
||||||
|
|
||||||
rts
|
rts
|
||||||
@@ -689,7 +689,7 @@ get_current_line_logical_length:
|
|||||||
lda screen_line_link_table,y
|
lda screen_line_link_table,y
|
||||||
bpl line_not_linked_del
|
bpl line_not_linked_del
|
||||||
lda #79
|
lda #79
|
||||||
.byte $2c ; BIT absolute mode, which we use to skip the next two instruction bytes
|
.byte $2c // BIT absolute mode, which we use to skip the next two instruction bytes
|
||||||
line_not_linked_del:
|
line_not_linked_del:
|
||||||
lda #39
|
lda #39
|
||||||
sta logical_line_length
|
sta logical_line_length
|
||||||
@@ -697,21 +697,21 @@ line_not_linked_del:
|
|||||||
|
|
||||||
screen_advance_to_next_line:
|
screen_advance_to_next_line:
|
||||||
|
|
||||||
;; jsr hide_cursor_if_visible
|
// jsr hide_cursor_if_visible
|
||||||
|
|
||||||
;; Go to start of line
|
// Go to start of line
|
||||||
lda #0
|
lda #0
|
||||||
sta current_screen_x
|
sta current_screen_x
|
||||||
;; Advance line number
|
// Advance line number
|
||||||
ldy current_screen_y
|
ldy current_screen_y
|
||||||
|
|
||||||
;; Do quick fix to line pointer to work out if it is off
|
// Do quick fix to line pointer to work out if it is off
|
||||||
;; the bottom of the screen.
|
// the bottom of the screen.
|
||||||
ldx #40
|
ldx #40
|
||||||
lda screen_line_link_table,y
|
lda screen_line_link_table,y
|
||||||
bmi +
|
bmi !+
|
||||||
.byte $2c
|
.byte $2c
|
||||||
* ldx #80
|
!: ldx #80
|
||||||
txa
|
txa
|
||||||
clc
|
clc
|
||||||
adc current_screen_line_ptr+0
|
adc current_screen_line_ptr+0
|
||||||
@@ -722,22 +722,22 @@ screen_advance_to_next_line:
|
|||||||
|
|
||||||
inc current_screen_y
|
inc current_screen_y
|
||||||
|
|
||||||
;; Check if it will trigger scrolling
|
// Check if it will trigger scrolling
|
||||||
;; Work out if we have gone off the bottom of the screen?
|
// Work out if we have gone off the bottom of the screen?
|
||||||
;; 1040 > 1024, so if high byte of screen pointer is >= (HIBASE+4),
|
// 1040 > 1024, so if high byte of screen pointer is >= (HIBASE+4),
|
||||||
;; then we are off the bottom of the screen
|
// then we are off the bottom of the screen
|
||||||
lda current_screen_line_ptr+1
|
lda current_screen_line_ptr+1
|
||||||
sec
|
sec
|
||||||
sbc HIBASE
|
sbc HIBASE
|
||||||
cmp #3
|
cmp #3
|
||||||
bcc +
|
bcc !+
|
||||||
lda current_screen_line_ptr+0
|
lda current_screen_line_ptr+0
|
||||||
cmp #$e7
|
cmp #$e7
|
||||||
bcc +
|
bcc !+
|
||||||
|
|
||||||
;; Off the bottom of the screen
|
// Off the bottom of the screen
|
||||||
jsr scroll_screen_up
|
jsr scroll_screen_up
|
||||||
*
|
!:
|
||||||
|
|
||||||
jsr calculate_screen_line_pointer
|
jsr calculate_screen_line_pointer
|
||||||
|
|
||||||
@@ -751,38 +751,38 @@ add_40_to_screen_x:
|
|||||||
rts
|
rts
|
||||||
|
|
||||||
normalise_screen_x_y:
|
normalise_screen_x_y:
|
||||||
;; Normalise X and Y values
|
// Normalise X and Y values
|
||||||
|
|
||||||
;; If X < 0, then make X = X + 40 (or 80, if previous line is linked)
|
// If X < 0, then make X = X + 40 (or 80, if previous line is linked)
|
||||||
* lda current_screen_x
|
!: lda current_screen_x
|
||||||
bpl x_not_negative
|
bpl x_not_negative
|
||||||
dec current_screen_y
|
dec current_screen_y
|
||||||
;; Check that we didn't go backwards off the top of the screen
|
// Check that we didn't go backwards off the top of the screen
|
||||||
bpl +
|
bpl !+
|
||||||
lda #0
|
lda #0
|
||||||
sta current_screen_y
|
sta current_screen_y
|
||||||
|
|
||||||
* jsr add_40_to_screen_x
|
!: jsr add_40_to_screen_x
|
||||||
|
|
||||||
;; Check if line is linked, if so, add 40 again
|
// Check if line is linked, if so, add 40 again
|
||||||
ldy current_screen_y
|
ldy current_screen_y
|
||||||
lda screen_line_link_table,y
|
lda screen_line_link_table,y
|
||||||
bpl +
|
bpl !+
|
||||||
jsr add_40_to_screen_x
|
jsr add_40_to_screen_x
|
||||||
*
|
!:
|
||||||
|
|
||||||
x_not_negative:
|
x_not_negative:
|
||||||
;; Work out if X is too big
|
// Work out if X is too big
|
||||||
ldy current_screen_y
|
ldy current_screen_y
|
||||||
lda screen_line_link_table,y
|
lda screen_line_link_table,y
|
||||||
bpl +
|
bpl !+
|
||||||
lda #79
|
lda #79
|
||||||
.byte $2C ; BIT $nnnn, used to skip next instruction
|
.byte $2C // BIT $nnnn, used to skip next instruction
|
||||||
* lda #39
|
!: lda #39
|
||||||
cmp current_screen_x
|
cmp current_screen_x
|
||||||
bcs x_not_too_big
|
bcs x_not_too_big
|
||||||
|
|
||||||
;; X value is too big, so subtract 40 and increment Y
|
// X value is too big, so subtract 40 and increment Y
|
||||||
lda current_screen_x
|
lda current_screen_x
|
||||||
sec
|
sec
|
||||||
sbc #40
|
sbc #40
|
||||||
@@ -791,28 +791,28 @@ x_not_negative:
|
|||||||
|
|
||||||
x_not_too_big:
|
x_not_too_big:
|
||||||
|
|
||||||
;; Make sure Y isn't negative
|
// Make sure Y isn't negative
|
||||||
lda current_screen_y
|
lda current_screen_y
|
||||||
bpl +
|
bpl !+
|
||||||
lda #0
|
lda #0
|
||||||
sta current_screen_y
|
sta current_screen_y
|
||||||
*
|
!:
|
||||||
;; Make sure Y isn't too large for absolute size of
|
// Make sure Y isn't too large for absolute size of
|
||||||
;; screen
|
// screen
|
||||||
cmp #24
|
cmp #24
|
||||||
bcc +
|
bcc !+
|
||||||
lda #24
|
lda #24
|
||||||
sta current_screen_y
|
sta current_screen_y
|
||||||
*
|
!:
|
||||||
;; Make sure Y isn't too much for the screen, taking
|
// Make sure Y isn't too much for the screen, taking
|
||||||
;; into account the line link table
|
// into account the line link table
|
||||||
ldy #24 ; max allowable line
|
ldy #24 // max allowable line
|
||||||
ldx #0
|
ldx #0
|
||||||
link_count_loop:
|
link_count_loop:
|
||||||
lda screen_line_link_table,x
|
lda screen_line_link_table,x
|
||||||
bpl +
|
bpl !+
|
||||||
dey
|
dey
|
||||||
* inx
|
!: inx
|
||||||
cpx #25
|
cpx #25
|
||||||
bne link_count_loop
|
bne link_count_loop
|
||||||
tya
|
tya
|
||||||
@@ -826,29 +826,29 @@ y_ok:
|
|||||||
calculate_screen_line_pointer:
|
calculate_screen_line_pointer:
|
||||||
jsr normalise_screen_x_y
|
jsr normalise_screen_x_y
|
||||||
|
|
||||||
;; Reset pointer to start of screen
|
// Reset pointer to start of screen
|
||||||
lda HIBASE
|
lda HIBASE
|
||||||
sta current_screen_line_ptr+1
|
sta current_screen_line_ptr+1
|
||||||
lda #0
|
lda #0
|
||||||
sta current_screen_line_ptr+0
|
sta current_screen_line_ptr+0
|
||||||
|
|
||||||
;; Add 40 for every line, or 80 if the lines are linked
|
// Add 40 for every line, or 80 if the lines are linked
|
||||||
ldx current_screen_y
|
ldx current_screen_y
|
||||||
|
|
||||||
*
|
!:
|
||||||
;; Stop if we have counted enough lines
|
// Stop if we have counted enough lines
|
||||||
beq +
|
beq !+
|
||||||
|
|
||||||
;; Add 40 or 80 based on whether the line is linked
|
// Add 40 or 80 based on whether the line is linked
|
||||||
;; or not.
|
// or not.
|
||||||
ldy #40
|
ldy #40
|
||||||
;; -1 offset is because we count down from N to 1, not
|
// -1 offset is because we count down from N to 1, not
|
||||||
;; N-1 to 0.
|
// N-1 to 0.
|
||||||
lda screen_line_link_table-1,x
|
lda screen_line_link_table-1,x
|
||||||
bpl cslp_l1
|
bpl cslp_l1
|
||||||
ldy #80
|
ldy #80
|
||||||
cslp_l1:
|
cslp_l1:
|
||||||
;; Add computed line length to pointer value
|
// Add computed line length to pointer value
|
||||||
tya
|
tya
|
||||||
clc
|
clc
|
||||||
adc current_screen_line_ptr+0
|
adc current_screen_line_ptr+0
|
||||||
@@ -857,15 +857,15 @@ cslp_l1:
|
|||||||
adc #0
|
adc #0
|
||||||
sta current_screen_line_ptr+1
|
sta current_screen_line_ptr+1
|
||||||
|
|
||||||
;; Loop back to next line
|
// Loop back to next line
|
||||||
dex
|
dex
|
||||||
jmp -
|
jmp !-
|
||||||
*
|
!:
|
||||||
|
|
||||||
;; FALL THROUGH
|
// FALL THROUGH
|
||||||
|
|
||||||
update_colour_line_pointer:
|
update_colour_line_pointer:
|
||||||
;; Now setup pointer to colour RAM
|
// Now setup pointer to colour RAM
|
||||||
lda current_screen_line_ptr+0
|
lda current_screen_line_ptr+0
|
||||||
sta current_screen_line_colour_ptr+0
|
sta current_screen_line_colour_ptr+0
|
||||||
lda current_screen_line_ptr+1
|
lda current_screen_line_ptr+1
|
||||||
@@ -896,6 +896,6 @@ advance_screen_pointer_40_bytes:
|
|||||||
jmp update_colour_line_pointer
|
jmp update_colour_line_pointer
|
||||||
|
|
||||||
colour_codes:
|
colour_codes:
|
||||||
;; CHR$ codes for the 16 colours
|
// CHR$ codes for the 16 colours
|
||||||
.byte 144,5,28,159,156,30,31,158
|
.byte 144,5,28,159,156,30,31,158
|
||||||
.byte 129,149,150,151,152,153,154,155
|
.byte 129,149,150,151,152,153,154,155
|
||||||
+40
-40
@@ -1,24 +1,24 @@
|
|||||||
|
|
||||||
;;
|
//
|
||||||
;; Official Kernal routine, described in:
|
// Official Kernal routine, described in:
|
||||||
;;
|
//
|
||||||
;; - [RG64] C64 Programmer's Reference Guide - page 280
|
// - [RG64] C64 Programmer's Reference Guide - page 280
|
||||||
;; - [CM64] Compute's Mapping the Commodore 64 - page 242
|
// - [CM64] Compute's Mapping the Commodore 64 - page 242
|
||||||
;;
|
//
|
||||||
;; CPU registers that has to be preserved (see [RG64]): none
|
// CPU registers that has to be preserved (see [RG64]): none
|
||||||
;;
|
//
|
||||||
|
|
||||||
|
|
||||||
cint_real:
|
cint_real:
|
||||||
|
|
||||||
;; According to [CM64], this routine checks for PAL/NTSC. It's definitely not done
|
// 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
|
// 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
|
// 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
|
// 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
|
// 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
|
sta VIC_SCROLX
|
||||||
|
|
||||||
cint_w0:
|
cint_w0:
|
||||||
@@ -28,18 +28,18 @@ cint_w1:
|
|||||||
beq cint_w1
|
beq cint_w1
|
||||||
bmi cint_w0
|
bmi cint_w0
|
||||||
|
|
||||||
;; Result in A, if no interrupt happened during the test:
|
// Result in A, if no interrupt happened during the test:
|
||||||
;; #$37 -> 312 rasterlines, PAL, VIC 6569
|
// #$37 -> 312 rasterlines, PAL, VIC 6569
|
||||||
;; #$06 -> 263 rasterlines, NTSC, VIC 6567R8
|
// #$06 -> 263 rasterlines, NTSC, VIC 6567R8
|
||||||
;; #$05 -> 262 rasterlines, NTSC, VIC 6567R56A
|
// #$05 -> 262 rasterlines, NTSC, VIC 6567R56A
|
||||||
|
|
||||||
cmp #$07
|
cmp #$07
|
||||||
bcs cint_pal
|
bcs cint_pal
|
||||||
|
|
||||||
cint_ntsc:
|
cint_ntsc:
|
||||||
|
|
||||||
;; NTSC C64 (https://codebase64.org/doku.php?id=base:cpu_clocking),
|
// 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
|
// is clocked at 1.022727 MHz, so that 1/60s is 17045 CPU cycles
|
||||||
|
|
||||||
ldy #<17045
|
ldy #<17045
|
||||||
ldx #>17045
|
ldx #>17045
|
||||||
@@ -48,51 +48,51 @@ cint_ntsc:
|
|||||||
stx CIA1_TIMAHI
|
stx CIA1_TIMAHI
|
||||||
|
|
||||||
lda #$00
|
lda #$00
|
||||||
beq +
|
beq !+
|
||||||
|
|
||||||
cint_pal:
|
cint_pal:
|
||||||
|
|
||||||
lda #$01
|
lda #$01
|
||||||
*
|
!:
|
||||||
sta PALNTSC
|
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
|
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
|
lda #$00
|
||||||
sta cursor_blink_disable
|
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
|
// Set initial variables for our improved keyboard scan routine
|
||||||
lda #$ff
|
lda #$FF
|
||||||
ldx #6
|
ldx #6
|
||||||
* sta BufferOld,x
|
!: sta BufferOld,x
|
||||||
dex
|
dex
|
||||||
bpl -
|
bpl !-
|
||||||
sta BufferQuantity
|
sta BufferQuantity
|
||||||
|
|
||||||
;; Set key repeat delay (Compute's Mapping the 64 p215)
|
// Set key repeat delay (Compute's Mapping the 64 p215)
|
||||||
;; Making some numbers up here: Repeat every ~1/10th sec
|
// Making some numbers up here: Repeat every ~1/10th sec
|
||||||
;; But require key to be held for ~1/3sec before
|
// But require key to be held for ~1/3sec before
|
||||||
;; repeating (Compute's Mapping the 64 p58)
|
// repeating (Compute's Mapping the 64 p58)
|
||||||
ldx #22-2 ; Fudge factor to match speed
|
ldx #22-2 // Fudge factor to match speed
|
||||||
stx key_first_repeat_delay
|
stx key_first_repeat_delay
|
||||||
|
|
||||||
;; Set current colour for text (Compute's Mapping the 64 p215)
|
// Set current colour for text (Compute's Mapping the 64 p215)
|
||||||
ldx #$01 ; default is light blue ($0E), but we use a different one
|
ldx #$01 // default is light blue ($0E), but we use a different one
|
||||||
stx text_colour
|
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
|
ldx #10
|
||||||
stx key_buffer_size
|
stx key_buffer_size
|
||||||
;; Put non-zero value in enable_case_switch
|
// Put non-zero value in enable_case_switch
|
||||||
stx 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
|
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
|
jmp clear_screen
|
||||||
+14
-14
@@ -1,37 +1,37 @@
|
|||||||
|
|
||||||
;;
|
//
|
||||||
;; Official Kernal routine, described in:
|
// Official Kernal routine, described in:
|
||||||
;;
|
//
|
||||||
;; - [RG64] C64 Programmer's Reference Guide - page 279/280
|
// - [RG64] C64 Programmer's Reference Guide - page 279/280
|
||||||
;; - [CM64] Compute's Mapping the Commodore 64 - page 224
|
// - [CM64] Compute's Mapping the Commodore 64 - page 224
|
||||||
;;
|
//
|
||||||
;; CPU registers that has to be preserved (see [RG64]): .X, .Y
|
// CPU registers that has to be preserved (see [RG64]): .X, .Y
|
||||||
;;
|
//
|
||||||
|
|
||||||
|
|
||||||
ciout:
|
CIOUT:
|
||||||
|
|
||||||
pha
|
pha
|
||||||
lda C3PO
|
lda C3PO
|
||||||
bne ciout_send_byte
|
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
|
inc C3PO
|
||||||
|
|
||||||
;; Clear carry flag to indicate success
|
// Clear carry flag to indicate success
|
||||||
clc
|
clc
|
||||||
|
|
||||||
ciout_store_in_buffer:
|
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
|
pla
|
||||||
sta BSOUR
|
sta BSOUR
|
||||||
rts
|
rts
|
||||||
|
|
||||||
ciout_send_byte:
|
ciout_send_byte:
|
||||||
|
|
||||||
clc ; don't send with EOI
|
clc // don't send with EOI
|
||||||
jsr iec_tx_byte
|
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
|
jmp ciout_store_in_buffer
|
||||||
|
|
||||||
+20
-20
@@ -1,38 +1,38 @@
|
|||||||
|
|
||||||
;;
|
//
|
||||||
;; Official Kernal routine, described in:
|
// Official Kernal routine, described in:
|
||||||
;;
|
//
|
||||||
;; - [RG64] C64 Programmer's Reference Guide - page 281
|
// - [RG64] C64 Programmer's Reference Guide - page 281
|
||||||
;; - [CM64] Compute's Mapping the Commodore 64 - page 230
|
// - [CM64] Compute's Mapping the Commodore 64 - page 230
|
||||||
;;
|
//
|
||||||
;; CPU registers that has to be preserved (see [RG64]): .Y
|
// CPU registers that has to be preserved (see [RG64]): .Y
|
||||||
;;
|
//
|
||||||
|
|
||||||
|
|
||||||
clall_real:
|
clall_real:
|
||||||
|
|
||||||
;; Store .Y register
|
// Store .Y register
|
||||||
tya
|
tya
|
||||||
pha
|
pha
|
||||||
|
|
||||||
;; Original routine probably just sets LDTND to 0, but this is not really safe,
|
// 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
|
// 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
|
// it's channels, see CLALL description in the IDE64 User's Guide
|
||||||
*
|
!:
|
||||||
ldy LDTND
|
ldy LDTND
|
||||||
beq +
|
beq !+
|
||||||
dey
|
dey
|
||||||
lda LAT, y
|
lda LAT, y
|
||||||
jsr JCLOSE
|
jsr JCLOSE
|
||||||
jmp -
|
jmp !-
|
||||||
*
|
!:
|
||||||
;; Restore .Y register
|
// Restore .Y register
|
||||||
pla
|
pla
|
||||||
tay
|
tay
|
||||||
|
|
||||||
;; 'C64 Programmers Reference Guide', page 281, claims it calls CLRCHN too
|
// 'C64 Programmers Reference Guide', page 281, claims it calls CLRCHN too
|
||||||
jsr clrchn
|
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
|
jmp kernalstatus_reset
|
||||||
|
|
||||||
@@ -1,23 +1,23 @@
|
|||||||
|
|
||||||
|
|
||||||
;; Common ppart of CLOSE and LOAD routines
|
// Common ppart of CLOSE and LOAD routines
|
||||||
|
|
||||||
close_load:
|
close_load:
|
||||||
|
|
||||||
tax
|
tax
|
||||||
|
|
||||||
;; Command drive to stop talking and to close the file
|
// Command drive to stop talking and to close the file
|
||||||
jsr untlk
|
jsr UNTLK
|
||||||
|
|
||||||
txa
|
txa
|
||||||
jsr listen
|
jsr LISTEN
|
||||||
|
|
||||||
lda #$E0 ; CLOSE command
|
lda #$E0 // CLOSE command
|
||||||
sta IEC_TMP2
|
sta IEC_TMP2
|
||||||
jsr iec_tx_command
|
jsr iec_tx_command
|
||||||
jsr iec_tx_command_finalize
|
jsr iec_tx_command_finalize
|
||||||
|
|
||||||
;; Tell drive to unlisten
|
// Tell drive to unlisten
|
||||||
jsr unlsn
|
jsr UNLSN
|
||||||
|
|
||||||
rts
|
rts
|
||||||
+21
-21
@@ -1,35 +1,35 @@
|
|||||||
|
|
||||||
;;
|
//
|
||||||
;; Official Kernal routine, described in:
|
// Official Kernal routine, described in:
|
||||||
;;
|
//
|
||||||
;; - [RG64] C64 Programmer's Reference Guide - page 282
|
// - [RG64] C64 Programmer's Reference Guide - page 282
|
||||||
;; - [CM64] Compute's Mapping the Commodore 64 - page 230
|
// - [CM64] Compute's Mapping the Commodore 64 - page 230
|
||||||
;;
|
//
|
||||||
;; CPU registers that has to be preserved (see [RG64]): .Y
|
// CPU registers that has to be preserved (see [RG64]): .Y
|
||||||
;;
|
//
|
||||||
|
|
||||||
|
|
||||||
clrchn_real:
|
clrchn_real:
|
||||||
|
|
||||||
;; Handle IEC input device
|
// Handle IEC input device
|
||||||
lda DFLTN
|
lda DFLTN
|
||||||
jsr iec_check_devnum
|
jsr iec_check_devnum
|
||||||
bcs +
|
bcs !+
|
||||||
;; Previous device was IEC one - send UNTALK first
|
// Previous device was IEC one - send UNTALK first
|
||||||
jsr untlk
|
jsr UNTLK
|
||||||
*
|
!:
|
||||||
;; Restore output device to default
|
// Restore output device to default
|
||||||
lda DFLTO
|
lda DFLTO
|
||||||
jsr iec_check_devnum
|
jsr iec_check_devnum
|
||||||
bcs +
|
bcs !+
|
||||||
;; Handle IEC output device
|
// Handle IEC output device
|
||||||
jsr unlsn
|
jsr UNLSN
|
||||||
*
|
!:
|
||||||
clrchn_reset: ;; entry needed by CHRIN
|
clrchn_reset: // entry needed by CHRIN
|
||||||
;; Set input device number to keyboard
|
// Set input device number to keyboard
|
||||||
lda #$00
|
lda #$00
|
||||||
sta DFLTN
|
sta DFLTN
|
||||||
;; Set output device number to screen
|
// Set output device number to screen
|
||||||
lda #$03
|
lda #$03
|
||||||
sta DFLTO
|
sta DFLTO
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
;; Clear screen and initialise line link table
|
// Clear screen and initialise line link table
|
||||||
;; (Compute's Mapping the 64 p215-216)
|
// (Compute's Mapping the 64 p215-216)
|
||||||
|
|
||||||
clear_screen:
|
clear_screen:
|
||||||
|
|
||||||
;; Clear line link table
|
// Clear line link table
|
||||||
;; (Compute's Mapping the 64 p215)
|
// (Compute's Mapping the 64 p215)
|
||||||
|
|
||||||
lda #$00
|
lda #$00
|
||||||
ldy #24
|
ldy #24
|
||||||
@@ -13,27 +13,27 @@ clearscreen_l1:
|
|||||||
dey
|
dey
|
||||||
bpl clearscreen_l1
|
bpl clearscreen_l1
|
||||||
|
|
||||||
;; Y now = #$FF
|
// Y now = #$FF
|
||||||
|
|
||||||
;; Clear screen RAM.
|
// Clear screen RAM.
|
||||||
;; We should do this at HIBASE, which annoyingly
|
// We should do this at HIBASE, which annoyingly
|
||||||
;; is no ZP, so we need to make a vector
|
// is no ZP, so we need to make a vector
|
||||||
;; (Compute's Mapping the 64 p216)
|
// (Compute's Mapping the 64 p216)
|
||||||
;; Get pointer to the screen into current_screen_line_ptr
|
// Get pointer to the screen into current_screen_line_ptr
|
||||||
;; as it is the first appropriate place for it found when
|
// as it is the first appropriate place for it found when
|
||||||
;; searching through the ZP allocations listed in
|
// searching through the ZP allocations listed in
|
||||||
;; Compute's Mapping the 64
|
// Compute's Mapping the 64
|
||||||
sta current_screen_line_ptr+0
|
sta current_screen_line_ptr+0
|
||||||
lda hibase
|
lda HIBASE
|
||||||
sta current_screen_line_ptr+1
|
sta current_screen_line_ptr+1
|
||||||
ldx #$03 ; countdown for pages to update
|
ldx #$03 // countdown for pages to update
|
||||||
iny ; Y now = #$00
|
iny // Y now = #$00
|
||||||
lda #$20 ; space character
|
lda #$20 // space character
|
||||||
clearscreen_l2:
|
clearscreen_l2:
|
||||||
sta (current_screen_line_ptr),y
|
sta (current_screen_line_ptr),y
|
||||||
iny
|
iny
|
||||||
bne clearscreen_l2
|
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
|
lda current_screen_line_ptr
|
||||||
clc
|
clc
|
||||||
adc #<250
|
adc #<250
|
||||||
@@ -41,20 +41,20 @@ clearscreen_l2:
|
|||||||
lda current_screen_line_ptr+1
|
lda current_screen_line_ptr+1
|
||||||
adc #>250
|
adc #>250
|
||||||
sta current_screen_line_ptr+1
|
sta current_screen_line_ptr+1
|
||||||
lda #$20 ; get space character again
|
lda #$20 // get space character again
|
||||||
dex
|
dex
|
||||||
bpl clearscreen_l2
|
bpl clearscreen_l2
|
||||||
|
|
||||||
;; Clear colour RAM
|
// Clear colour RAM
|
||||||
;; (Compute's Mapping the 64 p216)
|
// (Compute's Mapping the 64 p216)
|
||||||
lda text_colour
|
lda text_colour
|
||||||
clearscreen_l3:
|
clearscreen_l3:
|
||||||
sta $d800,y
|
sta $d800,y
|
||||||
sta $d900,y
|
sta $d900,y
|
||||||
sta $da00,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
|
iny
|
||||||
bne clearscreen_l3
|
bne clearscreen_l3
|
||||||
|
|
||||||
;; (Compute's Mapping the 64 p216)
|
// (Compute's Mapping the 64 p216)
|
||||||
jmp home_cursor
|
jmp home_cursor
|
||||||
@@ -1,20 +1,20 @@
|
|||||||
|
|
||||||
setup_vicii:
|
setup_vicii:
|
||||||
|
|
||||||
;; Set up default IO values (Compute's Mapping the 64 p215)
|
// Set up default IO values (Compute's Mapping the 64 p215)
|
||||||
lda #$1B ; Enable text mode
|
lda #$1B // Enable text mode
|
||||||
sta VIC_SCROLY
|
sta VIC_SCROLY
|
||||||
lda #$C8 ; 40 column etc
|
lda #$C8 // 40 column etc
|
||||||
sta VIC_SCROLX
|
sta VIC_SCROLX
|
||||||
|
|
||||||
;; Compute's Mapping the 64, p156
|
// Compute's Mapping the 64, p156
|
||||||
;; We use a different colour scheme of white text on all blue
|
// We use a different colour scheme of white text on all blue
|
||||||
lda #$06
|
lda #$06
|
||||||
sta VIC_EXTCOL
|
sta VIC_EXTCOL
|
||||||
sta VIC_BGCOL0
|
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
|
lda #$00
|
||||||
sta VIC_SPENA
|
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
|
lda #K_ERR_ROUTINE_TERMINATED
|
||||||
sec
|
sec
|
||||||
rts
|
rts
|
||||||
@@ -56,20 +56,20 @@ kernalerror_TOP_MEM_RS232:
|
|||||||
sec
|
sec
|
||||||
rts
|
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:
|
kernalstatus_reset:
|
||||||
lda #$00
|
lda #$00
|
||||||
sta IOSTATUS
|
sta IOSTATUS
|
||||||
rts
|
rts
|
||||||
|
|
||||||
kernalstatus_TIMEOUT_WRITE: ;; XXX detect this!
|
kernalstatus_TIMEOUT_WRITE: // XXX detect this!
|
||||||
lda IOSTATUS
|
lda IOSTATUS
|
||||||
ora #K_STS_TIMEOUT_WRITE
|
ora #K_STS_TIMEOUT_WRITE
|
||||||
sta IOSTATUS
|
sta IOSTATUS
|
||||||
rts
|
rts
|
||||||
|
|
||||||
kernalstatus_TIMEOUT_READ: ;; XXX detect this!
|
kernalstatus_TIMEOUT_READ: // XXX detect this!
|
||||||
lda IOSTATUS
|
lda IOSTATUS
|
||||||
ora #K_STS_TIMEOUT_READ
|
ora #K_STS_TIMEOUT_READ
|
||||||
sta IOSTATUS
|
sta IOSTATUS
|
||||||
|
|||||||
+14
-14
@@ -1,27 +1,27 @@
|
|||||||
|
|
||||||
;;
|
//
|
||||||
;; Official Kernal routine, described in:
|
// Official Kernal routine, described in:
|
||||||
;;
|
//
|
||||||
;; - [RG64] C64 Programmer's Reference Guide - page 283
|
// - [RG64] C64 Programmer's Reference Guide - page 283
|
||||||
;; - [CM64] Compute's Mapping the Commodore 64 - page 227/228
|
// - [CM64] Compute's Mapping the Commodore 64 - page 227/228
|
||||||
;;
|
//
|
||||||
;; CPU registers that has to be preserved (see [RG64]): .X, .Y
|
// 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
|
lda keys_in_key_buffer
|
||||||
bne +
|
bne !+
|
||||||
|
|
||||||
;; Nothing in keyboard buffer to read
|
// Nothing in keyboard buffer to read
|
||||||
sec
|
sec
|
||||||
lda #$00
|
lda #$00
|
||||||
rts
|
rts
|
||||||
|
|
||||||
*
|
!:
|
||||||
lda keyboard_buffer
|
lda keyboard_buffer
|
||||||
pha
|
pha
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
;; Our implementation is longer than the original one,
|
// Our implementation is longer than the original one,
|
||||||
;; placing it here would cause a collision with CHROUT
|
// placing it here would cause a collision with CHROUT
|
||||||
|
|
||||||
chrin:
|
CHRIN:
|
||||||
jmp chrin_real
|
jmp chrin_real
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
;; Our implementation is longer than the original one,
|
// Our implementation is longer than the original one,
|
||||||
;; placing it here would cause a collision with CHKIN
|
// placing it here would cause a collision with CHKIN
|
||||||
|
|
||||||
chrout:
|
CHROUT:
|
||||||
jmp chrout_real
|
jmp chrout_real
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
;; In our implementation CHKIN and CKOUT are closely tied,
|
// In our implementation CHKIN and CKOUT are closely tied,
|
||||||
;; placing it here would cause a collision
|
// placing it here would cause a collision
|
||||||
|
|
||||||
chkin:
|
CHKIN:
|
||||||
jmp chkin_real
|
jmp chkin_real
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
;; In our implementation CHKIN and CKOUT are closely tied,
|
// In our implementation CHKIN and CKOUT are closely tied,
|
||||||
;; placing it here would cause a collision
|
// placing it here would cause a collision
|
||||||
|
|
||||||
ckout:
|
CKOUT:
|
||||||
jmp ckout_real
|
jmp ckout_real
|
||||||
+27
-27
@@ -1,49 +1,49 @@
|
|||||||
|
|
||||||
;;
|
//
|
||||||
;; Official Kernal routine, described in:
|
// Official Kernal routine, described in:
|
||||||
;;
|
//
|
||||||
;; - [RG64] C64 Programmer's Reference Guide - page 281/282
|
// - [RG64] C64 Programmer's Reference Guide - page 281/282
|
||||||
;; - [CM64] Compute's Mapping the Commodore 64 - page 229/230
|
// - [CM64] Compute's Mapping the Commodore 64 - page 229/230
|
||||||
;; - https://www.pagetable.com/?p=1031, https://github.com/mist64/cbmbus_doc (IEC command)
|
// - https://www.pagetable.com/?p=1031, https://github.com/mist64/cbmbus_doc (IEC command)
|
||||||
;;
|
//
|
||||||
;; CPU registers that has to be preserved (see [RG64]): none
|
// 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
|
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
|
lda FAT, y
|
||||||
jsr iec_check_devnum
|
jsr iec_check_devnum
|
||||||
bcs close_remove_from_table
|
bcs close_remove_from_table
|
||||||
|
|
||||||
;; IEC device
|
// IEC device
|
||||||
|
|
||||||
jsr iec_tx_flush ; make sure no byte is awaiting
|
jsr iec_tx_flush // make sure no byte is awaiting
|
||||||
lda SAT, y ; get secondary address
|
lda SAT, y // get secondary address
|
||||||
cmp #$60
|
cmp #$60
|
||||||
bne +
|
bne !+
|
||||||
;; workaround for using CLOSE on reading executable - XXX is this a proper way?
|
// workaround for using CLOSE on reading executable - XXX is this a proper way?
|
||||||
jsr close_load
|
jsr close_load
|
||||||
jmp close_remove_from_table
|
jmp close_remove_from_table
|
||||||
*
|
!:
|
||||||
ora $E0 ; CLOSE command
|
ora $E0 // CLOSE command
|
||||||
sta IEC_TMP2
|
sta IEC_TMP2
|
||||||
jsr iec_tx_command
|
jsr iec_tx_command
|
||||||
bcs close_remove_from_table
|
bcs close_remove_from_table
|
||||||
jsr iec_tx_command_finalize
|
jsr iec_tx_command_finalize
|
||||||
|
|
||||||
close_remove_from_table:
|
close_remove_from_table:
|
||||||
;; Remove channel from the table
|
// Remove channel from the table
|
||||||
iny
|
iny
|
||||||
cpy #$0A
|
cpy #$0A
|
||||||
bpl +
|
bpl !+
|
||||||
lda LAT, y
|
lda LAT, y
|
||||||
sta LAT-1, y
|
sta LAT-1, y
|
||||||
lda FAT, y
|
lda FAT, y
|
||||||
@@ -51,14 +51,14 @@ close_remove_from_table:
|
|||||||
lda SAT, y
|
lda SAT, y
|
||||||
sta SAT-1, y
|
sta SAT-1, y
|
||||||
jmp close_remove_from_table
|
jmp close_remove_from_table
|
||||||
*
|
!:
|
||||||
;; Decrement the list size variable
|
// Decrement the list size variable
|
||||||
dec LDTND
|
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
|
rts
|
||||||
|
|
||||||
close_error_not_found:
|
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
|
rts
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
;; Our implementation is longer than the original one,
|
// Our implementation is longer than the original one,
|
||||||
;; placing it here would cause a collision with CLRCHN
|
// placing it here would cause a collision with CLRCHN
|
||||||
|
|
||||||
clall:
|
CLALL:
|
||||||
jmp clall_real
|
jmp clall_real
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
;; Our implementation is longer than the original one,
|
// Our implementation is longer than the original one,
|
||||||
;; placing it here would cause a collision with OPEN
|
// placing it here would cause a collision with OPEN
|
||||||
|
|
||||||
clrchn:
|
CLRCHN:
|
||||||
jmp clrchn_real
|
jmp clrchn_real
|
||||||
+32
-32
@@ -1,23 +1,23 @@
|
|||||||
|
|
||||||
;;
|
//
|
||||||
;; Official Kernal routine, described in:
|
// Official Kernal routine, described in:
|
||||||
;;
|
//
|
||||||
;; - [RG64] C64 Programmer's Reference Guide - page 289
|
// - [RG64] C64 Programmer's Reference Guide - page 289
|
||||||
;; - [CM64] Compute's Mapping the Commodore 64 - page 230/231
|
// - [CM64] Compute's Mapping the Commodore 64 - page 230/231
|
||||||
;;
|
//
|
||||||
;; CPU registers that has to be preserved (see [RG64]): none
|
// CPU registers that has to be preserved (see [RG64]): none
|
||||||
;;
|
//
|
||||||
|
|
||||||
|
|
||||||
open:
|
OPEN:
|
||||||
|
|
||||||
;; Reset status
|
// Reset status
|
||||||
jsr kernalstatus_reset
|
jsr kernalstatus_reset
|
||||||
|
|
||||||
;; Check if the logical file number is unique
|
// Check if the logical file number is unique
|
||||||
ldy LDTND
|
ldy LDTND
|
||||||
*
|
!:
|
||||||
beq +
|
beq !+
|
||||||
dey
|
dey
|
||||||
lda LAT, y
|
lda LAT, y
|
||||||
cmp current_logical_filenum
|
cmp current_logical_filenum
|
||||||
@@ -25,23 +25,23 @@ open:
|
|||||||
jmp kernalerror_FILE_ALREADY_OPEN
|
jmp kernalerror_FILE_ALREADY_OPEN
|
||||||
open_not_yet_open:
|
open_not_yet_open:
|
||||||
cpy #$00
|
cpy #$00
|
||||||
jmp -
|
jmp !-
|
||||||
*
|
!:
|
||||||
;; Check if we have space in tables
|
// Check if we have space in tables
|
||||||
|
|
||||||
ldy LDTND
|
ldy LDTND
|
||||||
cpy #$0A
|
cpy #$0A
|
||||||
bcc open_has_space
|
bcc open_has_space
|
||||||
*
|
!:
|
||||||
;; Table is full
|
// Table is full
|
||||||
jmp kernalerror_TOO_MANY_OPEN_FILES
|
jmp kernalerror_TOO_MANY_OPEN_FILES
|
||||||
|
|
||||||
open_has_space:
|
open_has_space:
|
||||||
|
|
||||||
;; Update the tables
|
// Update the tables
|
||||||
|
|
||||||
;; LAT / FAT / SAT support implemented according to
|
// LAT / FAT / SAT support implemented according to
|
||||||
;; 'Compute's Mapping the Commodore 64', page 52
|
// 'Compute's Mapping the Commodore 64', page 52
|
||||||
|
|
||||||
lda current_logical_filenum
|
lda current_logical_filenum
|
||||||
sta LAT, y
|
sta LAT, y
|
||||||
@@ -53,16 +53,16 @@ open_has_space:
|
|||||||
iny
|
iny
|
||||||
sty LDTND
|
sty LDTND
|
||||||
|
|
||||||
;; Check for command to send
|
// Check for command to send
|
||||||
lda FNLEN
|
lda FNLEN
|
||||||
beq open_done_success
|
beq open_done_success
|
||||||
|
|
||||||
;; Check for IEC device
|
// Check for IEC device
|
||||||
lda current_device_number
|
lda current_device_number
|
||||||
jsr iec_check_devnum
|
jsr iec_check_devnum
|
||||||
bcc open_iec
|
bcc open_iec
|
||||||
|
|
||||||
;; FALLTROUGH
|
// FALLTROUGH
|
||||||
open_done_success:
|
open_done_success:
|
||||||
|
|
||||||
clc
|
clc
|
||||||
@@ -70,21 +70,21 @@ open_done_success:
|
|||||||
|
|
||||||
open_iec:
|
open_iec:
|
||||||
|
|
||||||
;; We have a command to send to IEC device
|
// We have a command to send to IEC device
|
||||||
jsr listen
|
jsr LISTEN
|
||||||
bcc +
|
bcc !+
|
||||||
jmp kernalerror_DEVICE_NOT_FOUND
|
jmp kernalerror_DEVICE_NOT_FOUND
|
||||||
*
|
!:
|
||||||
lda current_secondary_address
|
lda current_secondary_address
|
||||||
jsr iec_cmd_open
|
jsr iec_cmd_open
|
||||||
bcc +
|
bcc !+
|
||||||
jmp kernalerror_DEVICE_NOT_FOUND
|
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
|
jsr install_ram_routines
|
||||||
|
|
||||||
;; Send command ('file name')
|
// Send command ('file name')
|
||||||
jsr lvs_send_file_name
|
jsr lvs_send_file_name
|
||||||
|
|
||||||
jmp open_done_success
|
jmp open_done_success
|
||||||
+92
-92
@@ -1,146 +1,146 @@
|
|||||||
|
|
||||||
;;
|
//
|
||||||
;; Official Kernal routine, described in:
|
// Official Kernal routine, described in:
|
||||||
;;
|
//
|
||||||
;; - [RG64] C64 Programmer's Reference Guide - page 286
|
// - [RG64] C64 Programmer's Reference Guide - page 286
|
||||||
;; - [CM64] Compute's Mapping the Commodore 64 - page 231
|
// - [CM64] Compute's Mapping the Commodore 64 - page 231
|
||||||
;; - IEC reference at http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf
|
// - IEC reference at http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf
|
||||||
;;
|
//
|
||||||
;; CPU registers that has to be preserved (see [RG64]): none
|
// CPU registers that has to be preserved (see [RG64]): none
|
||||||
;;
|
//
|
||||||
|
|
||||||
|
|
||||||
;; Expects that SETLFS and SETNAM are called before hand.
|
// Expects that SETLFS and SETNAM are called before hand.
|
||||||
;; $YYXX = load address.
|
// $YYXX = load address.
|
||||||
;; (ignored if SETLFS channel = 1, i.e., like ,8,1)
|
// (ignored if SETLFS channel = 1, i.e., like ,8,1)
|
||||||
;; If A=1 then VERIFY instead of LOAD.
|
// If A=1 then VERIFY instead of LOAD.
|
||||||
;; On exit, $YYXX is the highest address into which data
|
// On exit, $YYXX is the highest address into which data
|
||||||
;; will have been placed.
|
// will have been placed.
|
||||||
|
|
||||||
;; XXX honor MSGFLG bit 6
|
// XXX honor MSGFLG bit 6
|
||||||
;; XXX add VERIFY support
|
// XXX add VERIFY support
|
||||||
|
|
||||||
load:
|
LOAD:
|
||||||
|
|
||||||
;; Are we loading or verifying?
|
// Are we loading or verifying?
|
||||||
sta VERCK
|
sta VERCK
|
||||||
|
|
||||||
;; Store start address of LOAD
|
// Store start address of LOAD
|
||||||
stx STAL+0
|
stx STAL+0
|
||||||
sty STAL+1
|
sty STAL+1
|
||||||
|
|
||||||
;; Reset status
|
// Reset status
|
||||||
jsr kernalstatus_reset
|
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
|
jsr install_ram_routines
|
||||||
|
|
||||||
;; Allow platform-specific routine to takeover the flow
|
// Allow platform-specific routine to takeover the flow
|
||||||
`TARGET_HOOK_LOAD
|
TARGET_HOOK_LOAD()
|
||||||
|
|
||||||
;; Check whether we support the requested device
|
// Check whether we support the requested device
|
||||||
lda current_device_number
|
lda current_device_number
|
||||||
and #$FC
|
and #$FC
|
||||||
bne +
|
bne !+
|
||||||
jmp lvs_illegal_device_number ; device number below 4, not an IEC device
|
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),
|
// 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,
|
// 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
|
// above 30 it is no longer possible (UNLISTEN and UNTALK codes prevent using
|
||||||
;; number 31), yet original ROMs show ILLEGAL DEVICE NUMBER error only
|
// number 31), yet original ROMs show ILLEGAL DEVICE NUMBER error only
|
||||||
;; for devices 0-3; in our implementation LISTEN / TALK will cause device
|
// for devices 0-3; in our implementation LISTEN / TALK will cause device
|
||||||
;; not present detected for numbers above 30
|
// not present detected for numbers above 30
|
||||||
|
|
||||||
;; Display SEARCHING FOR + filename
|
// Display SEARCHING FOR + filename
|
||||||
jsr lvs_display_searching_for
|
jsr lvs_display_searching_for
|
||||||
|
|
||||||
;; http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf
|
// 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
|
// p13, 16; also p16 tells us this routine doesn't mess with the file table
|
||||||
;; in the C64, only in the drive.
|
// in the C64, only in the drive.
|
||||||
|
|
||||||
;; Call device to LISTEN (p16)
|
// Call device to LISTEN (p16)
|
||||||
lda current_device_number
|
lda current_device_number
|
||||||
jsr listen
|
jsr LISTEN
|
||||||
bcc +
|
bcc !+
|
||||||
jmp lvs_device_not_found_error ; XXX deduplicate with other jumps in this routine
|
jmp lvs_device_not_found_error // XXX deduplicate with other jumps in this routine
|
||||||
*
|
!:
|
||||||
;; Open channel 0 (reserved for file reading)
|
// Open channel 0 (reserved for file reading)
|
||||||
lda #$00
|
lda #$00
|
||||||
jsr iec_cmd_open
|
jsr iec_cmd_open
|
||||||
bcc +
|
bcc !+
|
||||||
jmp lvs_device_not_found_error ; XXX deduplicate with other jumps in this routine
|
jmp lvs_device_not_found_error // XXX deduplicate with other jumps in this routine
|
||||||
*
|
!:
|
||||||
;; Send file name
|
// Send file name
|
||||||
jsr lvs_send_file_name
|
jsr lvs_send_file_name
|
||||||
bcc +
|
bcc !+
|
||||||
jmp lvs_load_verify_error ; XXX deduplicate with other jumps in this routine
|
jmp lvs_load_verify_error // XXX deduplicate with other jumps in this routine
|
||||||
*
|
!:
|
||||||
;; Now command device to talk (p16)
|
// Now command device to talk (p16)
|
||||||
lda current_device_number
|
lda current_device_number
|
||||||
jsr talk
|
jsr TALK
|
||||||
bcc +
|
bcc !+
|
||||||
jmp lvs_load_verify_error ; XXX deduplicate with other jumps in this routine
|
jmp lvs_load_verify_error // XXX deduplicate with other jumps in this routine
|
||||||
*
|
!:
|
||||||
lda #$60 ; open channel / data (p3) , required according to p13
|
lda #$60 // open channel / data (p3) , required according to p13
|
||||||
sta IEC_TMP2
|
sta IEC_TMP2
|
||||||
jsr iec_tx_command
|
jsr iec_tx_command
|
||||||
bcc +
|
bcc !+
|
||||||
jmp lvs_load_verify_error ; XXX deduplicate with other jumps in this routine
|
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
|
// We are currently talker, so do the IEC turn around so that we
|
||||||
;; are the listener (p16)
|
// are the listener (p16)
|
||||||
jsr iec_turnaround_to_listen
|
jsr iec_turnaround_to_listen
|
||||||
bcc +
|
bcc !+
|
||||||
jmp lvs_load_verify_error ; XXX deduplicate with other jumps in this routine
|
jmp lvs_load_verify_error // XXX deduplicate with other jumps in this routine
|
||||||
*
|
!:
|
||||||
;; Get load address and store it if secondary address is zero
|
// Get load address and store it if secondary address is zero
|
||||||
jsr iec_rx_byte
|
jsr iec_rx_byte
|
||||||
bcc +
|
bcc !+
|
||||||
jmp lvs_file_not_found_error ; XXX deduplicate with other jumps in this routine
|
jmp lvs_file_not_found_error // XXX deduplicate with other jumps in this routine
|
||||||
*
|
!:
|
||||||
ldx current_secondary_address
|
ldx current_secondary_address
|
||||||
beq +
|
beq !+
|
||||||
sta STAL+0
|
sta STAL+0
|
||||||
*
|
!:
|
||||||
jsr iec_rx_byte
|
jsr iec_rx_byte
|
||||||
bcc +
|
bcc !+
|
||||||
jmp lvs_file_not_found_error ; XXX deduplicate with other jumps in this routine
|
jmp lvs_file_not_found_error // XXX deduplicate with other jumps in this routine
|
||||||
*
|
!:
|
||||||
ldx current_secondary_address
|
ldx current_secondary_address
|
||||||
beq +
|
beq !+
|
||||||
sta STAL+1
|
sta STAL+1
|
||||||
*
|
!:
|
||||||
;; Display start address
|
// Display start address
|
||||||
jsr lvs_display_loading_verifying
|
jsr lvs_display_loading_verifying
|
||||||
|
|
||||||
load_loop:
|
load_loop:
|
||||||
;; We are now ready to receive bytes
|
// We are now ready to receive bytes
|
||||||
jsr iec_rx_byte
|
jsr iec_rx_byte
|
||||||
bcc +
|
bcc !+
|
||||||
jmp lvs_load_verify_error ; XXX deduplicate with other jumps in this routine
|
jmp lvs_load_verify_error // XXX deduplicate with other jumps in this routine
|
||||||
*
|
!:
|
||||||
;; Handle the byte (store in memory / verify)
|
// Handle the byte (store in memory / verify)
|
||||||
jsr lvs_handle_byte_load_verify
|
jsr lvs_handle_byte_load_verify
|
||||||
bcc +
|
bcc !+
|
||||||
jmp lvs_load_verify_error ; XXX deduplicate with other jumps in this routine
|
jmp lvs_load_verify_error // XXX deduplicate with other jumps in this routine
|
||||||
*
|
!:
|
||||||
;; Advance pointer to data
|
// Advance pointer to data
|
||||||
jsr lvs_advance_pointer
|
jsr lvs_advance_pointer
|
||||||
bcc +
|
bcc !+
|
||||||
jmp lvs_wrap_around_error
|
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
|
lda IOSTATUS
|
||||||
and #K_STS_EOI
|
and #K_STS_EOI
|
||||||
beq load_loop
|
beq load_loop
|
||||||
|
|
||||||
;; Display end address
|
// Display end address
|
||||||
jsr lvs_display_done
|
jsr lvs_display_done
|
||||||
|
|
||||||
;; Close file on drive
|
// Close file on drive
|
||||||
|
|
||||||
lda current_device_number
|
lda current_device_number
|
||||||
jsr close_load
|
jsr close_load
|
||||||
|
|
||||||
;; Return last address
|
// Return last address
|
||||||
jmp lvs_return_last_address
|
jmp lvs_return_last_address
|
||||||
+10
-10
@@ -1,13 +1,13 @@
|
|||||||
|
|
||||||
;;
|
//
|
||||||
;; Official Kernal routine, described in:
|
// Official Kernal routine, described in:
|
||||||
;;
|
//
|
||||||
;; - [RG64] C64 Programmer's Reference Guide - page 293/294
|
// - [RG64] C64 Programmer's Reference Guide - page 293/294
|
||||||
;; - [CM64] Compute's Mapping the Commodore 64 - page 231/232
|
// - [CM64] Compute's Mapping the Commodore 64 - page 231/232
|
||||||
;; - IEC reference at http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf
|
// - IEC reference at http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf
|
||||||
;;
|
//
|
||||||
;; CPU registers that has to be preserved (see [RG64]): none
|
// CPU registers that has to be preserved (see [RG64]): none
|
||||||
;;
|
//
|
||||||
|
|
||||||
save:
|
SAVE:
|
||||||
rts
|
rts
|
||||||
+15
-15
@@ -1,24 +1,24 @@
|
|||||||
|
|
||||||
;;
|
//
|
||||||
;; Official Kernal routine, described in:
|
// Official Kernal routine, described in:
|
||||||
;;
|
//
|
||||||
;; - [RG64] C64 Programmer's Reference Guide - page 301
|
// - [RG64] C64 Programmer's Reference Guide - page 301
|
||||||
;; - [CM64] Compute's Mapping the Commodore 64 - page 232
|
// - [CM64] Compute's Mapping the Commodore 64 - page 232
|
||||||
;;
|
//
|
||||||
;; CPU registers that has to be preserved (see [RG64]): .Y
|
// CPU registers that has to be preserved (see [RG64]): .Y
|
||||||
;;
|
//
|
||||||
|
|
||||||
stop:
|
STOP:
|
||||||
;; Bit 7 of STKEY contains the state of the STOP key
|
// Bit 7 of STKEY contains the state of the STOP key
|
||||||
;; (Compute's Mapping the 64, p27)
|
// (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
|
lda STKEY
|
||||||
bpl stop_pressed
|
bpl stop_pressed
|
||||||
|
|
||||||
;; By trial and error, we know that Z + C = BREAK
|
// By trial and error, we know that Z + C = BREAK
|
||||||
;; and that neither should be set otherwise
|
// and that neither should be set otherwise
|
||||||
lda #$ff
|
lda #$FF
|
||||||
clc
|
clc
|
||||||
rts
|
rts
|
||||||
|
|
||||||
|
|||||||
+30
-36
@@ -1,70 +1,64 @@
|
|||||||
|
|
||||||
;;
|
//
|
||||||
;; Official Kernal routine, described in:
|
// Official Kernal routine, described in:
|
||||||
;;
|
//
|
||||||
;; - [RG64] C64 Programmer's Reference Guide - page 293 (RESTOR), 304 (VECTOR)
|
// - [RG64] C64 Programmer's Reference Guide - page 293 (RESTOR), 304 (VECTOR)
|
||||||
;; - [CM64] Compute's Mapping the Commodore 64 - page 237
|
// - [CM64] Compute's Mapping the Commodore 64 - page 237
|
||||||
;;
|
//
|
||||||
;; CPU registers that has to be preserved (see [RG64]): none
|
// 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
|
ldx #<vector_defaults
|
||||||
ldy #>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
|
// According to 'Compute's Mapping the Commodore 64' page 237,
|
||||||
;; address originally used; after calling VECTOR and checking zero page
|
// the CBM implementation does not disable IRQs - yet, the
|
||||||
;; area afterwards, the address could be found there
|
// 'C64 Programmers Reference Guide' does not contain such
|
||||||
.alias _caller_arr_ptr MEMUS
|
// warning and does not mention any preparations needed, so...
|
||||||
|
// better safe than sorry, disable the IRQ for the duration
|
||||||
;; According to 'Compute's Mapping the Commodore 64' page 237,
|
// of vector manipulation
|
||||||
;; 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
|
php
|
||||||
cli
|
cli
|
||||||
|
|
||||||
;; Prepare the user data pointer - strange order to reduce risk
|
// Prepare the user data pointer - strange order to reduce risk
|
||||||
;; of potential similarity to the original routine
|
// of potential similarity to the original routine
|
||||||
sty _caller_arr_ptr + 1
|
sty _caller_arr_ptr + 1
|
||||||
stx _caller_arr_ptr + 0
|
stx _caller_arr_ptr + 0
|
||||||
|
|
||||||
;; Select routine variant - store or restore vectors
|
// Select routine variant - store or restore vectors
|
||||||
ldy #$1F
|
ldy #$1F
|
||||||
bcc vector_restore
|
bcc vector_restore
|
||||||
|
|
||||||
;; FALLTHROUGH
|
// FALLTHROUGH
|
||||||
|
|
||||||
vector_store:
|
vector_store:
|
||||||
*
|
|
||||||
lda CINV, y
|
lda CINV, y
|
||||||
sta (_caller_arr_ptr), y
|
sta (_caller_arr_ptr), y
|
||||||
dey
|
dey
|
||||||
bpl -
|
bpl vector_store
|
||||||
|
|
||||||
;; Restore status register (IRQ) before return
|
// Restore status register (IRQ) before return
|
||||||
plp
|
plp
|
||||||
rts
|
rts
|
||||||
|
|
||||||
vector_restore:
|
vector_restore:
|
||||||
*
|
|
||||||
lda (_caller_arr_ptr), y
|
lda (_caller_arr_ptr), y
|
||||||
sta CINV, y
|
sta CINV, y
|
||||||
dey
|
dey
|
||||||
bpl -
|
bpl vector_restore
|
||||||
|
|
||||||
;; Restore status register (IRQ) before return
|
// Restore status register (IRQ) before return
|
||||||
plp
|
plp
|
||||||
rts
|
rts
|
||||||
|
|
||||||
.scend
|
|
||||||
+34
-34
@@ -1,34 +1,34 @@
|
|||||||
|
|
||||||
;;
|
//
|
||||||
;; Official Kernal routine, described in:
|
// Official Kernal routine, described in:
|
||||||
;;
|
//
|
||||||
;; - [RG64] C64 Programmer's Reference Guide - page 285
|
// - [RG64] C64 Programmer's Reference Guide - page 285
|
||||||
;; - [CM64] Compute's Mapping the Commodore 64 - page 238
|
// - [CM64] Compute's Mapping the Commodore 64 - page 238
|
||||||
;;
|
//
|
||||||
;; CPU registers that has to be preserved (see [RG64]): none
|
// CPU registers that has to be preserved (see [RG64]): none
|
||||||
;;
|
//
|
||||||
|
|
||||||
ioinit:
|
IOINIT:
|
||||||
|
|
||||||
; Set $00/$01 port mode and value
|
// Set $00/$01 port mode and value
|
||||||
; We want BASIC and KERNAL ROMs mapped, and datasette motor off
|
// We want BASIC and KERNAL ROMs mapped, and datasette motor off
|
||||||
; (https://www.c64-wiki.com/wiki/Zeropage)
|
// (https://www.c64-wiki.com/wiki/Zeropage)
|
||||||
;; XXX - Work around VICE bug: Writing $00 before $01 results in rubbish in $01
|
// XXX - Work around VICE bug: Writing $00 before $01 results in rubbish in $01
|
||||||
;; after. https://sourceforge.net/p/vice-emu/bugs/1057/
|
// after. https://sourceforge.net/p/vice-emu/bugs/1057/
|
||||||
lda #$27
|
lda #$27
|
||||||
ldx #$2F
|
ldx #$2F
|
||||||
sta CPU_R6510
|
sta CPU_R6510
|
||||||
stx CPU_D6510
|
stx CPU_D6510
|
||||||
|
|
||||||
;; Silence the SID chips under common addresses
|
// Silence the SID chips under common addresses
|
||||||
|
|
||||||
ldy #$00
|
ldy #$00
|
||||||
*
|
!:
|
||||||
;; SIDs under $D4xx
|
// SIDs under $D4xx
|
||||||
lda SID_SIGVOL, Y
|
lda SID_SIGVOL, Y
|
||||||
and #$F0
|
and #$F0
|
||||||
sta SID_SIGVOL, Y
|
sta SID_SIGVOL, Y
|
||||||
;; SIDs under $D5xx
|
// SIDs under $D5xx
|
||||||
lda SID_SIGVOL + $100, Y
|
lda SID_SIGVOL + $100, Y
|
||||||
and #$F0
|
and #$F0
|
||||||
sta SID_SIGVOL + $100, Y
|
sta SID_SIGVOL + $100, Y
|
||||||
@@ -36,24 +36,24 @@ ioinit:
|
|||||||
clc
|
clc
|
||||||
adc #$20
|
adc #$20
|
||||||
tay
|
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
|
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
|
// (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
|
// 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)
|
// in the IRQ handler to see roughly what value the timers must be set to)
|
||||||
;; ldy #<16380
|
// ldy #<16380
|
||||||
;; ldx #>16380
|
// ldx #>16380
|
||||||
|
|
||||||
;; PAL C64 (https://codebase64.org/doku.php?id=base:cpu_clocking),
|
// 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
|
// is clocked at 0.985248 MHz, so that 1/60s is 16421 CPU cycles
|
||||||
|
|
||||||
ldy #<16421
|
ldy #<16421
|
||||||
ldx #>16421
|
ldx #>16421
|
||||||
@@ -61,19 +61,19 @@ ioinit:
|
|||||||
sty CIA1_TIMALO
|
sty CIA1_TIMALO
|
||||||
stx CIA1_TIMAHI
|
stx CIA1_TIMAHI
|
||||||
|
|
||||||
;; Enable timer interrupt
|
// Enable timer interrupt
|
||||||
lda #$81
|
lda #$81
|
||||||
sta CIA1_ICR
|
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
|
lda #$11
|
||||||
sta CIA1_CRA
|
sta CIA1_CRA
|
||||||
lda CIA1_ICR
|
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
|
lda #$3B
|
||||||
sta CIA2_DDRA
|
sta CIA2_DDRA
|
||||||
|
|
||||||
;; Set IEC bus to its initial idle state
|
// Set IEC bus to its initial idle state
|
||||||
jmp iec_set_idle
|
jmp iec_set_idle
|
||||||
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
;; Our implementation is longer than the original one,
|
// Our implementation is longer than the original one,
|
||||||
;; placing it here would cause a collision with OPEN
|
// placing it here would cause a collision with OPEN
|
||||||
|
|
||||||
cint:
|
CINT:
|
||||||
jmp cint_real
|
jmp cint_real
|
||||||
@@ -1,31 +1,63 @@
|
|||||||
|
|
||||||
;;
|
//
|
||||||
;; This byte identifies Kernal revision. Sources:
|
// This byte (hex $FF80, dec 65408) identifies Kernal revision on several machines. Although not all
|
||||||
;; - [CM64] Compute's Mapping the Commodore 64 (page 242/243)
|
// of the, used it for versioning purpose, here is the list of all the values I could find. Sources:
|
||||||
;; - [MM] Marko Mäkelä article, http://www.zimmers.net/anonftp/pub/cbm/firmware/computers/c64/revisions.txt
|
// - [CM64] Compute's Mapping the Commodore 64 (page 242/243)
|
||||||
;; - [VICE] Checked with ROMs included in VICE emulator
|
// - [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
|
// - [XEMU] Checked with ROMs retrieved by XEMU emulator
|
||||||
;; a warning that this is not a Commodore Kernal. Currently known numbers for C64 are:
|
//
|
||||||
;;
|
// IDEA: put here a value, that is different from any version currently known, as
|
||||||
;; - $00 - [CM64] then current number [MM] 901227-02 [VICE] C64 Revision 2
|
// a warning that this is not a Commodore Kernal or anything already known.
|
||||||
;; - $03 - [CM64] (not mentionned) [MM] 901227-02, 901227-03 [VICE] C64 Revision 3
|
//
|
||||||
;; - $43 - [CM64] (not mentionned) [MM] 251104-04 [VICE] SX-64
|
// C64 - values from the official ROMs:
|
||||||
;; - $64 - [CM64] PET64 ROM [MM] (not mentionned) [VICE] PET64
|
// - $00 - [CM64] then current number [MM] 901227-02 [VICE] C64 Revision 2
|
||||||
;; - $AA - [CM64] first version of ROM [MM] 901227-01 [VICE] C64 Revision 1
|
// - $03 - [CM64] (not mentionned) [MM] 901227-02, 901227-03 [VICE] C64 Revision 3
|
||||||
;;
|
// - $43 - [CM64] (not mentionned) [MM] 251104-04 [VICE] SX-64
|
||||||
;; Values from unofficial ROMs:
|
// - $64 - [CM64] PET64 ROM [MM] (not mentionned) [VICE] PET64
|
||||||
;; - $03 - SuperCPU ROM 1.40, 2.04, also unofficial 0.7 ROM from [VICE]
|
// - $AA - [CM64] first version of ROM [MM] 901227-01 [VICE] C64 Revision 1
|
||||||
;;
|
//
|
||||||
;; Values from other Commodore machines:
|
// C64 - values from unofficial 3rd party ROMs:
|
||||||
;; C128:
|
// - $00 - Turbo Trans, Turbo Access, Turbo Process
|
||||||
;; - $01 - see https://www.pagetable.com/?p=1058
|
// - $03 - SuperCPU ROM 1.40, 2.04, also unofficial 0.7 ROM from [VICE],
|
||||||
;; - $02 - unreleased updated ROM, see https://www.pagetable.com/?p=1058
|
// DolphinDOS 2.0, JiffyDOS 6.01, EXOS V3/4,
|
||||||
;;
|
// Datel Mercury V3 US, Datel DOS-ROM V1.2, Datel Turbo ROM II V3.2+,
|
||||||
;; XXX check more unofficial C64 ROMs (JiffyDOS, DolphinDOS, etc.) and other machines
|
// Turbo Process US,
|
||||||
;; VIC-20, PET, CBM II, 264 series, C65 prototypes, other sources for C128 ROMs
|
// 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:
|
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
|
// $FFFA - CPU NMI Hanlder
|
||||||
; Uncontrovertial as this is also a CPU requirement.
|
// Uncontrovertial as this is also a CPU requirement.
|
||||||
|
|
||||||
.word nmi_handler
|
.word nmi_handler
|
||||||
+2
-2
@@ -1,4 +1,4 @@
|
|||||||
; $FFFC - CPU Reset Vector
|
// $FFFC - CPU Reset Vector
|
||||||
; Uncontrovertial, as it is a CPU requirement, and nothing else.
|
// Uncontrovertial, as it is a CPU requirement, and nothing else.
|
||||||
|
|
||||||
.word reset_entry
|
.word reset_entry
|
||||||
+3
-3
@@ -1,5 +1,5 @@
|
|||||||
; $FFFE - CPU IRQ Vector.
|
// $FFFE - CPU IRQ Vector.
|
||||||
; This is non-controvertial, as it is a 6502 CPU requirement, and we just have to point
|
// This is non-controvertial, as it is a 6502 CPU requirement, and we just have to point
|
||||||
; it to whatever IRQ routine we make.
|
// it to whatever IRQ routine we make.
|
||||||
|
|
||||||
.word irq_handler
|
.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
|
// Find the LAT / SAT / FAT entry index where LAT corresponds to A, returns index in Y
|
||||||
;; Carry flag set means not found
|
// Carry flag set means not found
|
||||||
|
|
||||||
find_fls:
|
find_fls:
|
||||||
|
|
||||||
ldy LDTND
|
ldy LDTND
|
||||||
beq find_fls_not_found ; table empty
|
beq find_fls_not_found // table empty
|
||||||
*
|
!:
|
||||||
dey
|
dey
|
||||||
bmi find_fls_not_found ; no more entries
|
bmi find_fls_not_found // no more entries
|
||||||
cmp LAT, y
|
cmp LAT, y
|
||||||
bne - ; does not match, try the next one
|
bne !- // does not match, try the next one
|
||||||
|
|
||||||
clc
|
clc
|
||||||
rts
|
rts
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
;; Home the cursor
|
// Home the cursor
|
||||||
;; (Compute's Mapping the 64 p216)
|
// (Compute's Mapping the 64 p216)
|
||||||
|
|
||||||
home_cursor:
|
home_cursor:
|
||||||
|
|
||||||
|
|||||||
@@ -1,22 +1,22 @@
|
|||||||
|
|
||||||
;;
|
//
|
||||||
;; Checks whether device number (in .A) is a correct IEC device number
|
// Checks whether device number (in .A) is a correct IEC device number
|
||||||
;;
|
//
|
||||||
;; Preserves .A, .X and .Y
|
// Preserves .A, .X and .Y
|
||||||
;;
|
//
|
||||||
|
|
||||||
iec_check_devnum:
|
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
|
cmp #$04
|
||||||
bcs +
|
bcs !+
|
||||||
;; FALLTROUGH
|
// FALLTROUGH
|
||||||
iec_check_devnum_failed:
|
iec_check_devnum_failed:
|
||||||
sec ; indicate non-IEC device
|
sec // indicate non-IEC device
|
||||||
rts
|
rts
|
||||||
*
|
!:
|
||||||
;; 31 and above are illegal too, due to IEC command encoding scheme,
|
// 31 and above are illegal too, due to IEC command encoding scheme,
|
||||||
;; see https://www.pagetable.com/?p=1031
|
// see https://www.pagetable.com/?p=1031
|
||||||
cmp #$1F
|
cmp #$1F
|
||||||
bcs iec_check_devnum_failed
|
bcs iec_check_devnum_failed
|
||||||
;; Carry is clear here - indicates IEC device
|
// Carry is clear here - indicates IEC device
|
||||||
rts
|
rts
|
||||||
@@ -1,16 +1,16 @@
|
|||||||
|
|
||||||
;;
|
//
|
||||||
;; Kernal internal IEC routine
|
// Kernal internal IEC routine
|
||||||
;;
|
//
|
||||||
;; - https://www.pagetable.com/?p=1031, https://github.com/mist64/cbmbus_doc
|
// - https://www.pagetable.com/?p=1031, https://github.com/mist64/cbmbus_doc
|
||||||
;;
|
//
|
||||||
|
|
||||||
iec_cmd_close:
|
iec_cmd_close:
|
||||||
|
|
||||||
jsr iec_check_channel_openclose
|
jsr iec_check_channel_openclose
|
||||||
bcc +
|
bcc !+
|
||||||
jmp kernalerror_FILE_NOT_INPUT
|
jmp kernalerror_FILE_NOT_INPUT
|
||||||
*
|
!:
|
||||||
ora #$E0
|
ora #$E0
|
||||||
|
|
||||||
jmp common_open_close_unlsn_second
|
jmp common_open_close_unlsn_second
|
||||||
@@ -1,42 +1,42 @@
|
|||||||
|
|
||||||
;;
|
//
|
||||||
;; Kernal internal IEC routine
|
// Kernal internal IEC routine
|
||||||
;;
|
//
|
||||||
;; - https://www.pagetable.com/?p=1031, https://github.com/mist64/cbmbus_doc
|
// - 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
|
jsr iec_check_channel_openclose
|
||||||
bcc +
|
bcc !+
|
||||||
jmp kernalerror_FILE_NOT_INPUT
|
jmp kernalerror_FILE_NOT_INPUT
|
||||||
*
|
!:
|
||||||
ora #$F0
|
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
|
sta IEC_TMP2
|
||||||
jsr iec_tx_command
|
jsr iec_tx_command
|
||||||
bcs + ; branch if error
|
bcs !+ // branch if error
|
||||||
jmp iec_tx_command_finalize
|
jmp iec_tx_command_finalize
|
||||||
*
|
!:
|
||||||
rts
|
rts
|
||||||
|
|
||||||
iec_check_channel_openclose:
|
iec_check_channel_openclose:
|
||||||
;; Due to OPEN/CLOSE/TKSA/SECOND command encoding (see https://www.pagetable.com/?p=1031),
|
// 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
|
// allowed channels are 0-15; report error if out of range
|
||||||
cmp #$10
|
cmp #$10
|
||||||
bcc +
|
bcc !+
|
||||||
;; Workaround to allow reading executable files and disk directory
|
// Workaround to allow reading executable files and disk directory
|
||||||
;; using OPEN routine - see https://www.pagetable.com/?p=273 for
|
// using OPEN routine - see https://www.pagetable.com/?p=273 for
|
||||||
;; example usage
|
// example usage
|
||||||
cmp #$60
|
cmp #$60
|
||||||
beq +
|
beq !+
|
||||||
sec ; mark unsuitable channel number
|
sec // mark unsuitable channel number
|
||||||
rts
|
rts
|
||||||
*
|
!:
|
||||||
clc ; mark suitable channel number
|
clc // mark suitable channel number
|
||||||
rts
|
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