adapted to Kick Assembler, some documentation update

This commit is contained in:
FeralChild64 committed 2019-09-07 12:35:21 +02:00
1 parent ae23dbae7b
commit de27124b4f
198 files changed
+4181 -3976

No files matched your search

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