Compare commits
31 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ed639a4825 | ||
|
|
6683e3f308 | ||
|
|
2c95cb317b | ||
|
|
6b04ebcf20 | ||
|
|
89b00b236f | ||
|
|
ca257b7736 | ||
|
|
edd649e76f | ||
|
|
249a1aecaa | ||
|
|
0cc5cb48c4 | ||
|
|
81eaf30249 | ||
|
|
162936722e | ||
|
|
baba399bec | ||
|
|
12cde3c592 | ||
|
|
1d80964835 | ||
|
|
a27e7041a1 | ||
|
|
b6b7f09527 | ||
|
|
52398fecf7 | ||
|
|
1d58a51d0c | ||
|
|
1b2f4b8c9a | ||
|
|
04f477ccad | ||
|
|
8116edd7a9 | ||
|
|
a1dae93e56 | ||
|
|
2eb35055e7 | ||
|
|
ddd58fcb87 | ||
|
|
e39c5eb99e | ||
|
|
0afc0df22a | ||
|
|
23bd5666c1 | ||
|
|
b14b904990 | ||
|
|
2513ac6065 | ||
|
|
367cefeb73 | ||
|
|
c84b18b9d2 |
38 changed files with 7396 additions and 17425 deletions
86
README.md
86
README.md
|
|
@ -1,31 +1,71 @@
|
|||
# Ultimate Commodore 64 Reference
|
||||
# Ultimate Commodore 64 BASIC & KERNAL ROM Disassembly
|
||||
|
||||
This project collects C64 reference material in a machine readable format and maintains a set of scripts to present these on the web.
|
||||
This project maintains six commented disassemblies of the C64 ROM (BASIC and KERNAL), five in English and one in German.
|
||||
|
||||
The most current web version can be found at [pagetable.com/c64disasm](http://pagetable.com/c64disasm).
|
||||
The txt files are the parsable master versions that can be used to create more rich representations.
|
||||
|
||||
* KERNAL & BASIC ROM Disassembly
|
||||
* [original Microsoft BASIC source](c64disasm/c64disasm_ms.txt)
|
||||
* [original Commodore KERNAL source](c64disasm/c64disasm_cbm.txt)
|
||||
* [disassembly by Lee Davison](c64disasm/c64disasm_en.txt)
|
||||
* [BASIC disassembly by Bob Sander-Cederlof](c64disasm/c64disasm_sc.txt)
|
||||
* [disassembly from Commodore-64-intern-Buch](c64disasm/c64disasm_de.txt) (German)
|
||||
* [disassembly by Magnus Nyman](c64disasm/c64disasm_mn.txt)
|
||||
* [disassembly by Marko Mäkelä](c64disasm/c64disasm_mm.txt)
|
||||
* Memory Map
|
||||
* ["Mapping the Commodore 64" by Sheldon Leemon](c64mem/c64mem_mapc64.txt)
|
||||
* ["Memory Map mit Wandervorschlägen" by Dr. H. Hauck](c64mem/c64mem_64er.txt) (German)
|
||||
* ["Commodore-64-intern-Buch"](c64mem/c64mem_64intern.txt) (German)
|
||||
* [reference by Joe Forster/STA](c64mem/c64mem_sta.txt)
|
||||
* [comments in the original Microsoft & Commodore Source](c64mem/c64mem_src.txt)
|
||||
* ["C64 Programmer's Reference Guide"](c64mem/c64mem_prg.txt)
|
||||
* ["64map"](c64mem/c64mem_64map.txt)
|
||||
* [reference by Jim Butterfield](c64mem/c64mem_jb.txt)
|
||||
## c64disasm_ms.txt
|
||||
|
||||
## Credits
|
||||
This is CBMBASIC only. The comments have been taken from
|
||||
|
||||
The files have been collected, converted, formatted and edited by [Michael Steil](mailto:mist64@mac.com).
|
||||
*Microsoft's original BASIC for M6502 source, [pagetable.com/?p=774](http://www.pagetable.com/?p=774)*
|
||||
|
||||
Converted and formatted by Michael Steil <mist64@mac.com>
|
||||
|
||||
## c64disasm_cbm.txt
|
||||
|
||||
This is KERNAL only. The comments have been taken from
|
||||
|
||||
*The original C64 KERNAL source by Commodore (901227-03), [pagetable.com/?p=894](http://www.pagetable.com/?p=894), [github.com/mist64/cbmsrc](https://github.com/mist64/cbmsrc)*
|
||||
|
||||
Converted and formatted by Michael Steil <mist64@mac.com>
|
||||
|
||||
## c64disasm_en.txt
|
||||
|
||||
The comments have been taken from
|
||||
|
||||
*The almost completely commented C64 ROM disassembly. V1.01 Lee Davison 2012*
|
||||
|
||||
Converted and formatted by Michael Steil <mist64@mac.com>
|
||||
|
||||
## c64disasm_sc.txt
|
||||
|
||||
This is CBMBASIC only. The comments have been taken from
|
||||
|
||||
*Bob Sander-Cederlof: S-C DocuMentor for Applesoft, [txbobsc.com/scsc/scdocumentor](http://www.txbobsc.com/scsc/scdocumentor/)*
|
||||
|
||||
Converted and adapted from Applesoft to CBMBASIC, as well as formatted by Michael Steil <mist64@mac.com>
|
||||
|
||||
## c64disasm_de.txt
|
||||
|
||||
The comments have been taken from
|
||||
|
||||
*Baloui, Said. Das neue Commodore-64-intern-Buch. Düsseldorf: Data-Becker, 1990. ISBN 3890113079*
|
||||
|
||||
OCRed and formatted by Michael Steil <mist64@mac.com>
|
||||
|
||||
## c64disasm_mn.txt
|
||||
|
||||
The comments have been taken from
|
||||
|
||||
*JIFFYDOS version 6.01/version 6.02 by Magnus Nyman (Harlekin/FairLight)*
|
||||
|
||||
Converted and formatted by Michael Steil <mist64@mac.com>
|
||||
|
||||
## c64disasm_mm.txt
|
||||
|
||||
The comments have been taken from
|
||||
|
||||
*Commodore 64 BASIC/KERNAL ROM Disassembly Version 1.0 (June 1994), by Marko Mäkelä*
|
||||
|
||||
Converted and formatted by Michael Steil <mist64@mac.com>
|
||||
|
||||
## Side-by-side HTML version
|
||||
|
||||
combine.py creates a cross-referenced HTML from all commentaries.
|
||||
|
||||
The most current version can be found at [pagetable.com/c64disasm](http://pagetable.com/c64disasm)
|
||||
|
||||
## Contributing
|
||||
|
||||
Extensions, corrections (typos as well as content), translations etc. welcome.
|
||||
Corrections (typos as well as content), translations etc. welcome.
|
||||
|
|
|
|||
|
|
@ -1,273 +0,0 @@
|
|||
#!/usr/bin/python3
|
||||
|
||||
import html, re, os
|
||||
|
||||
filenames = [
|
||||
"c64disasm_ms.txt;c64disasm_cbm.txt",
|
||||
"c64disasm_de.txt",
|
||||
"c64disasm_en.txt",
|
||||
"c64disasm_sc.txt",
|
||||
"c64disasm_mn.txt",
|
||||
"c64disasm_mm.txt"
|
||||
]
|
||||
names = [
|
||||
"Microsoft/Commodore Source",
|
||||
"Data Becker [German]",
|
||||
"Lee Davison",
|
||||
"Bob Sander-Cederlof [BASIC only]",
|
||||
"Magnus Nyman [KERNAL only]",
|
||||
"Marko Mäkelä"
|
||||
]
|
||||
links = [
|
||||
"https://github.com/mist64/cbmsrc",
|
||||
"https://www.pagetable.com/?p=1015",
|
||||
"https://www.pagetable.com/?p=726",
|
||||
"https://www.pagetable.com/?p=728",
|
||||
"https://www.telecomm.at/documents/Jiffydos_Romlisting.doc",
|
||||
"http://www.unusedino.de/ec64/technical/misc/c64/romlisting.html"
|
||||
]
|
||||
descriptions = [
|
||||
"The original M6502 BASIC source by Microsoft (KIM-1 version, not everything lines up, Commodore extensions are missing, but lots of comments by the original authors)<br/>and the original C64 KERNAL source by Commodore (lots of comments by the original authors)",
|
||||
"German-language comments from <i>Das neue Commodore-64-intern-Buch</i> by Data Becker, ISBN 3890113079. Some minor corrections have been made.",
|
||||
"Comments from <i>The almost completely commented C64 ROM disassembly V1.01</i> by Lee Davison. Some minor corrections have been made.",
|
||||
"Comments adapted from <i>S-C DocuMentor for Applesoft</i> by Bob Sander-Cederlof, for the version of Microsoft BASIC that shipped with the Apple II.",
|
||||
"Comments from <i>JIFFYDOS version 6.01/version 6.02</i> by Magnus Nyman (Harlekin/FairLight), which were written for the JiffyDOS KERNAL, so some serial code and all tape code is missing comments.",
|
||||
"Comments from the <i>Commodore 64 BASIC/KERNAL ROM Disassembly Version 1.0 (June 1994)</i> by Marko Mäkelä."
|
||||
]
|
||||
|
||||
def cross_reference(string, symbols):
|
||||
hex_numbers = re.findall(r'(?<!#)\$[0-9A-F][0-9A-F]+', string)
|
||||
for hex_number in hex_numbers:
|
||||
dec_number = int(hex_number[1:], 16)
|
||||
if dec_number < 0x0400:
|
||||
string = string.replace(hex_number, "<a href=\"../c64mem/#" + '{:04X}'.format(dec_number) + "\">" + hex_number + "</a>")
|
||||
elif (dec_number >= 0xa000 and dec_number <= 0xbfff) or (dec_number >= 0xe000 and dec_number <= 0xffff):
|
||||
string = string.replace(hex_number, "<a href=\"#" + hex_number[1:] + "\">" + hex_number + "</a>")
|
||||
|
||||
for symbol in symbols:
|
||||
string = re.sub('\\b' + symbol + '\\b', '<a href="../c64mem/#' + symbol + '">' + symbol + '</a>', string)
|
||||
|
||||
return string
|
||||
|
||||
asm_donor_index = 1
|
||||
source_index = 0 # we treat the Microsoft/Commodore source differently
|
||||
|
||||
f = os.popen("git log -1 --pretty=format:%h .")
|
||||
revision = f.read()
|
||||
f = os.popen("git log -1 --date=short --pretty=format:%cd .")
|
||||
date = f.read()
|
||||
|
||||
symbols = []
|
||||
symbol_lines = [line.rstrip() for line in open('../c64mem/c64mem_src.txt')]
|
||||
for line in symbol_lines:
|
||||
if line.startswith('#') or line.startswith('-'):
|
||||
continue
|
||||
symbol = line[13:19].rstrip()
|
||||
if symbol != '':
|
||||
symbols.append(symbol)
|
||||
symbols = set(symbols)
|
||||
|
||||
data = []
|
||||
linenumber = []
|
||||
address = []
|
||||
for filename in filenames:
|
||||
d = []
|
||||
for f in filename.split(";"):
|
||||
d += [line.rstrip() for line in open(f)]
|
||||
data.append(d)
|
||||
linenumber.append(0)
|
||||
address.append(0)
|
||||
files = len(filenames)
|
||||
|
||||
asmaddress = 0
|
||||
asmlinenumber = 0
|
||||
|
||||
for i in range(0, files):
|
||||
while True:
|
||||
line = data[i][linenumber[i]]
|
||||
if len(line) > 0 and line[0] == '.':
|
||||
break
|
||||
linenumber[i] = linenumber[i] + 1
|
||||
|
||||
|
||||
print('<meta http-equiv="Content-type" content="text/html; charset=utf-8" />')
|
||||
print('<html>')
|
||||
print('<head>')
|
||||
print('<title>BASIC & KERNAL ROM Disassembly | Ultimate C64 Reference</title>')
|
||||
print('')
|
||||
print('<script language="javascript">')
|
||||
print(' window.onload = init;')
|
||||
print(' function init() {')
|
||||
print(' var tbl = document.getElementById("disassembly_table");')
|
||||
print(' for (var i = 0; i < ' + str(len(filenames)) + '; i++) {')
|
||||
print(' var key = "com.pagetable.c64disasm.column_" + i;')
|
||||
print(' var element_name = "checkbox_" + i;')
|
||||
print(' var checked = localStorage.getItem(key) != "hidden";')
|
||||
print(' document.getElementById(element_name).checked = checked;')
|
||||
print(' hideCol(i, checked);')
|
||||
print(' }')
|
||||
print(' }')
|
||||
print(' function hideCol(col, checked) {')
|
||||
print(' var tbl = document.getElementById("disassembly_table");')
|
||||
print(' for (var i = 0; i < tbl.rows.length; i++) {')
|
||||
print(' tbl.rows[i].cells[col+1].style.display = checked ? "" : "none";')
|
||||
print(' }')
|
||||
print(' var key = "com.pagetable.c64disasm.column_" + col;')
|
||||
print(' if (checked) {')
|
||||
print(' localStorage.removeItem(key);')
|
||||
print(' } else {')
|
||||
print(' localStorage.setItem(key, "hidden");')
|
||||
print(' }')
|
||||
print(' }')
|
||||
print('</script>')
|
||||
print('')
|
||||
print('<link rel="stylesheet" href="../style.css">')
|
||||
print('<style type="text/css">')
|
||||
print('')
|
||||
print('h3 {')
|
||||
print(' font-family: serif;')
|
||||
print('}')
|
||||
print('')
|
||||
print('.com {')
|
||||
print(' white-space: pre;')
|
||||
print('}')
|
||||
print('')
|
||||
print('div.disassembly_container {')
|
||||
print(' padding: 1em 0em 1em 16em;')
|
||||
print(' overflow: scroll;')
|
||||
print('}')
|
||||
print('')
|
||||
print('table.disassembly_table td, table.disassembly_table th {')
|
||||
print(' font-family: monospace;')
|
||||
print('}')
|
||||
print('')
|
||||
print('table.disassembly_table th.left_column {')
|
||||
print(' width: 18em;')
|
||||
print('}')
|
||||
print('')
|
||||
print('</style>')
|
||||
print('</head>')
|
||||
print('<body>')
|
||||
|
||||
# http://tholman.com/github-corners/
|
||||
print('<a href="https://github.com/mist64/c64ref" class="github-corner" aria-label="View source on GitHub"><svg width="80" height="80" viewBox="0 0 250 250" style="fill:var(--main-color); color:#fff; position: absolute; top: 0; border: 0; right: 0;" aria-hidden="true"><path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path></svg></a><style>.github-corner:hover .octo-arm{animation:octocat-wave 560ms ease-in-out}@keyframes octocat-wave{0%,100%{transform:rotate(0)}20%,60%{transform:rotate(-25deg)}40%,80%{transform:rotate(10deg)}}@media (max-width:500px){.github-corner:hover .octo-arm{animation:none}.github-corner .octo-arm{animation:octocat-wave 560ms ease-in-out}}</style>')
|
||||
|
||||
print('<div class="topnav">')
|
||||
print(' <h1>Ultimate Commodore 64 Reference</h1> ')
|
||||
#print(' <a href="#">KERNAL API</a><!-- kernal/ -->')
|
||||
print(' <a class="active" href="../c64disasm/">ROM Disassembly</a><!-- c64disasm/ -->')
|
||||
print(' <a href="../c64mem/">Memory Map</a><!-- c64mem/ -->')
|
||||
#print(' <a href="#">I/O Map</a><!-- c64io/ -->')
|
||||
#print(' <a href="#">6502 CPU</a><!-- 6502/ -->')
|
||||
print('</div>')
|
||||
|
||||
print('<div class="body">')
|
||||
print('<h1>C64 BASIC & KERNAL ROM Disassembly</h1>')
|
||||
|
||||
print('<p><i>by <a href="http://www.pagetable.com/">Michael Steil</a>, <a href="https://github.com/mist64/c64ref">github.com/mist64/c64ref</a>. Revision ' + revision + ', ' + date + '</i></p>')
|
||||
|
||||
print('<b>This allows you to view different commentaries side-by-side. You can enable/disable individual columns:</b><br/><br/>')
|
||||
print('<table class="checkbox_table">')
|
||||
for i in range(0, len(filenames)):
|
||||
print('<tr><td><input type="checkbox" id="checkbox_' + str(i) + '" checked onclick="hideCol(' + str(i) + ', document.getElementById(\'checkbox_' + str(i) + '\').checked);" /></td><td style="white-space: nowrap;"><b><a href="' + links[i] + '">' + names[i] + '</a></b><td>' + descriptions[i] + '</td></tr>')
|
||||
print('</table>')
|
||||
|
||||
print('<div class="disassembly_container">')
|
||||
print('<table id="disassembly_table" class="disassembly_table">')
|
||||
|
||||
print('<tr>')
|
||||
print('<th class="left_column">Disassembly</th>')
|
||||
for i in range(0, files):
|
||||
print('<th class="top_row">' + names[i] + '</th>')
|
||||
print('</tr>')
|
||||
|
||||
count = 0
|
||||
while(True):
|
||||
count += 1
|
||||
# if count > 80:
|
||||
# break
|
||||
|
||||
for i in range(0, files):
|
||||
if linenumber[i] >= len(data[i]):
|
||||
continue
|
||||
while len(data[i][linenumber[i]]) > 0 and (data[i][linenumber[i]][0] == '-' or data[i][linenumber[i]][0] == '#'):
|
||||
linenumber[i] = linenumber[i] + 1
|
||||
|
||||
if asmlinenumber >= len(data[asm_donor_index]):
|
||||
break
|
||||
|
||||
asm = data[asm_donor_index][asmlinenumber][0:32].rstrip()
|
||||
asmlinenumber = asmlinenumber + 1
|
||||
|
||||
if len(asm) == 0:
|
||||
continue
|
||||
if asm[0] == '#' or asm[0] == '-':
|
||||
continue
|
||||
|
||||
has_address = False
|
||||
if asm[0] == '.':
|
||||
hexaddress = asm[2:6]
|
||||
asmaddress = int(hexaddress, 16)
|
||||
has_address = True
|
||||
|
||||
asm = cross_reference(asm, symbols)
|
||||
|
||||
print('<tr>')
|
||||
print('<th class="left_column">')
|
||||
if has_address:
|
||||
print('<a name="' + hexaddress + '" />')
|
||||
print('<span class="com">' + asm + '</span></th>')
|
||||
|
||||
for i in range(0, files):
|
||||
print('<td>')
|
||||
comments = []
|
||||
while True:
|
||||
if linenumber[i] >= len(data[i]):
|
||||
break
|
||||
|
||||
line = data[i][linenumber[i]]
|
||||
|
||||
if line.startswith('.'):
|
||||
address[i] = int(line[2:6], 16)
|
||||
if address[i] > asmaddress:
|
||||
break
|
||||
comment = line[32:]
|
||||
comment = html.escape(comment)
|
||||
|
||||
comment = cross_reference(comment, symbols)
|
||||
|
||||
if comment.startswith('***'):
|
||||
comment = '<h3>' + comment[3:] + '</h3>'
|
||||
elif comment.startswith('SUBTTL'):
|
||||
comment = '<h3>' + comment[6:] + '</h3>'
|
||||
elif comment.startswith('.LIB '):
|
||||
comment = '<h3>' + comment + '</h3>'
|
||||
else:
|
||||
scomment = comment.lstrip()
|
||||
|
||||
if scomment.startswith(';'):
|
||||
comment = '<b>' + comment + '</b>'
|
||||
|
||||
if len(comment) != 0:
|
||||
comment = '<span class="com">' + comment + '</span><br />'
|
||||
|
||||
if len(comment) != 0:
|
||||
comments.append(comment)
|
||||
|
||||
linenumber[i] = linenumber[i] + 1
|
||||
|
||||
if len(comments):
|
||||
for comment in comments:
|
||||
print(comment)
|
||||
else:
|
||||
print(' ')
|
||||
|
||||
print('</td>')
|
||||
print('</tr>')
|
||||
|
||||
print('</table>')
|
||||
print('</div>')
|
||||
print('</div>')
|
||||
print('</body>')
|
||||
print('</html>')
|
||||
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
- CBMBASIC and KERNAL
|
||||
-
|
||||
- The comments have been taken from
|
||||
- Baloui, Brückmann, Englisch, Felt, Gelfand, Gerits, Krsnik:
|
||||
- Baloui, Said.
|
||||
- Das neue Commodore-64-intern-Buch.
|
||||
- Düsseldorf: Data-Becker, 1990.
|
||||
- ISBN 3890113079
|
||||
|
|
@ -11,10 +11,6 @@
|
|||
- up perfectly, so make sure the machine code matches the assembly
|
||||
- code in the respective lines your looking at.
|
||||
-
|
||||
- The range $E0F9-$E261 was taken from
|
||||
- The original C64 BASIC source by Commodore
|
||||
- https://github.com/mist64/cbmsrc
|
||||
-
|
||||
- Converted and formatted by Michael Steil <mist64@mac.com>
|
||||
-
|
||||
- Corrections (formatting, lining up) welcome at:
|
||||
|
|
@ -6754,239 +6750,167 @@
|
|||
.,E0F4 A0 00 LDY #$00
|
||||
.,E0F6 4C D4 BB JMP $BBD4 GMOVMF: JMP MOVMF ;PUT NEW ONE INTO MEMORY.
|
||||
|
||||
.,E0F9 C9 F0 CMP #$F0 EREXIT CMP #$F0 ;CHECK FOR SPECIAL CASE
|
||||
.,E0FB D0 07 BNE $E104 BNE EREXIX
|
||||
; TOP OF MEMORY HAS CHANGED
|
||||
.,E0FD 84 38 STY $38 STY MEMSIZ+1
|
||||
.,E0FF 86 37 STX $37 STX MEMSIZ
|
||||
.,E101 4C 63 A6 JMP $A663 JMP CLEART ;ACT AS IF HE TYPED CLEAR
|
||||
.,E104 AA TAX EREXIX TAX ;SET TERMINATION FLAGS
|
||||
.,E105 D0 02 BNE $E109 BNE EREXIY
|
||||
.,E107 A2 1E LDX #$1E LDX #ERBRK ;BREAK ERROR
|
||||
.,E109 4C 37 A4 JMP $A437 EREXIY JMP ERROR ;NORMAL ERROR
|
||||
|
||||
CLSCHN =$FFCC
|
||||
|
||||
.,E10C 20 D2 FF JSR $FFD2 OUTCH JSR $FFD2
|
||||
.,E10F B0 E8 BCS $E0F9 BCS EREXIT
|
||||
.,E111 60 RTS RTS
|
||||
.,E112 20 CF FF JSR $FFCF INCHR JSR $FFCF
|
||||
.,E115 B0 E2 BCS $E0F9 BCS EREXIT
|
||||
.,E117 60 RTS RTS
|
||||
|
||||
CCALL =$FFE7
|
||||
|
||||
SETTIM =$FFDB
|
||||
RDTIM =$FFDE
|
||||
|
||||
.,E118 20 AD E4 JSR $E4AD COOUT JSR PPACH ; GO OUT TO SAVE .A FOR PRINT# PATCH
|
||||
.,E11B B0 DC BCS $E0F9 BCS EREXIT
|
||||
.,E11D 60 RTS RTS
|
||||
|
||||
.,E11E 20 C6 FF JSR $FFC6 COIN JSR $FFC6
|
||||
.,E121 B0 D6 BCS $E0F9 BCS EREXIT
|
||||
.,E123 60 RTS RTS
|
||||
|
||||
READST =$FFB7
|
||||
|
||||
.,E124 20 E4 FF JSR $FFE4 CGETL JSR $FFE4
|
||||
.,E127 B0 D0 BCS $E0F9 BCS EREXIT
|
||||
.,E129 60 RTS RTS
|
||||
|
||||
RDBAS =$FFF3
|
||||
|
||||
SETMSG =$FF90
|
||||
|
||||
PLOT =$FFF0
|
||||
|
||||
.,E12A 20 8A AD JSR $AD8A CSYS JSR FRMNUM ;EVAL FORMULA
|
||||
.,E12D 20 F7 B7 JSR $B7F7 JSR GETADR ;CONVERT TO INT. ADDR
|
||||
.,E130 A9 E1 LDA #$E1 LDA #>CSYSRZ ;PUSH RETURN ADDRESS
|
||||
.,E132 48 PHA PHA
|
||||
.,E133 A9 46 LDA #$46 LDA #<CSYSRZ
|
||||
.,E135 48 PHA PHA
|
||||
.,E136 AD 0F 03 LDA $030F LDA SPREG ;STATUS REG
|
||||
.,E139 48 PHA PHA
|
||||
.,E13A AD 0C 03 LDA $030C LDA SAREG ;LOAD 6502 REGS
|
||||
.,E13D AE 0D 03 LDX $030D LDX SXREG
|
||||
.,E140 AC 0E 03 LDY $030E LDY SYREG
|
||||
.,E143 28 PLP PLP ;LOAD 6502 STATUS REG
|
||||
.,E144 6C 14 00 JMP ($0014) JMP (LINNUM) ;GO DO IT
|
||||
CSYSRZ =*-1 ;RETURN TO HERE
|
||||
.,E147 08 PHP PHP ;SAVE STATUS REG
|
||||
.,E148 8D 0C 03 STA $030C STA SAREG ;SAVE 6502 REGS
|
||||
.,E14B 8E 0D 03 STX $030D STX SXREG
|
||||
.,E14E 8C 0E 03 STY $030E STY SYREG
|
||||
.,E151 68 PLA PLA ;GET STATUS REG
|
||||
.,E152 8D 0F 03 STA $030F STA SPREG
|
||||
.,E155 60 RTS RTS ;RETURN TO SYSTEM
|
||||
|
||||
.,E156 20 D4 E1 JSR $E1D4 CSAVE JSR PLSV ;PARSE PARMS
|
||||
.,E159 A6 2D LDX $2D LDX VARTAB ;END SAVE ADDR
|
||||
.,E15B A4 2E LDY $2E LDY VARTAB+1
|
||||
.,E15D A9 2B LDA #$2B LDA #<TXTTAB ;INDIRECT WITH START ADDRESS
|
||||
.,E15F 20 D8 FF JSR $FFD8 JSR $FFD8 ;SAVE IT
|
||||
.,E162 B0 95 BCS $E0F9 BCS EREXIT
|
||||
.,E164 60 RTS RTS
|
||||
|
||||
.,E165 A9 01 LDA #$01 CVERF LDA #1 ;VERIFY FLAG
|
||||
.:E167 2C .BYTE $2C .BYT $2C ;SKIP TWO BYTES
|
||||
|
||||
.,E168 A9 00 LDA #$00 CLOAD LDA #0 ;LOAD FLAG
|
||||
.,E16A 85 0A STA $0A STA VERCK
|
||||
.,E16C 20 D4 E1 JSR $E1D4 JSR PLSV ;PARSE PARAMETERS
|
||||
;
|
||||
CLD10 ; JSR $FFE1 ;CHECK RUN/STOP
|
||||
; CMP #$FF ;DONE YET?
|
||||
; BNE CLD10 ;STILL BOUNCING
|
||||
.,E16F A5 0A LDA $0A LDA VERCK
|
||||
.,E171 A6 2B LDX $2B LDX TXTTAB ;.X AND .Y HAVE ALT...
|
||||
.,E173 A4 2C LDY $2C LDY TXTTAB+1 ;...LOAD ADDRESS
|
||||
.,E175 20 D5 FF JSR $FFD5 JSR $FFD5 ;LOAD IT
|
||||
.,E178 B0 57 BCS $E1D1 BCS JERXIT ;PROBLEMS
|
||||
;
|
||||
.,E17A A5 0A LDA $0A LDA VERCK
|
||||
.,E17C F0 17 BEQ $E195 BEQ CLD50 ;WAS LOAD
|
||||
;
|
||||
;FINISH VERIFY
|
||||
;
|
||||
.,E17E A2 1C LDX #$1C LDX #ERVFY ;ASSUME ERROR
|
||||
.,E180 20 B7 FF JSR $FFB7 JSR $FFB7 ;READ STATUS
|
||||
.,E183 29 10 AND #$10 AND #$10 ;CHECK ERROR
|
||||
.,E185 D0 17 BNE $E19E BNE CLD55 ;REPLACES BEQ *+5/JMP ERROR
|
||||
;
|
||||
;PRINT VERIFY 'OK' IF DIRECT
|
||||
;
|
||||
.,E187 A5 7A LDA $7A LDA TXTPTR
|
||||
.,E189 C9 02 CMP #$02 CMP #BUFPAG
|
||||
.,E18B F0 07 BEQ $E194 BEQ CLD20
|
||||
.,E18D A9 64 LDA #$64 LDA #<OKMSG
|
||||
.,E18F A0 A3 LDY #$A3 LDY #>OKMSG
|
||||
.,E191 4C 1E AB JMP $AB1E JMP STROUT
|
||||
;
|
||||
.,E194 60 RTS CLD20 RTS
|
||||
|
||||
;
|
||||
;FINISH LOAD
|
||||
;
|
||||
.,E195 20 B7 FF JSR $FFB7 CLD50 JSR $FFB7 ;READ STATUS
|
||||
.,E198 29 BF AND #$BF AND #$FF-$40 ;CLEAR E.O.I.
|
||||
.,E19A F0 05 BEQ $E1A1 BEQ CLD60 ;WAS O.K.
|
||||
.,E19C A2 1D LDX #$1D LDX #ERLOAD
|
||||
.,E19E 4C 37 A4 JMP $A437 CLD55 JMP ERROR
|
||||
;
|
||||
.,E1A1 A5 7B LDA $7B CLD60 LDA TXTPTR+1
|
||||
.,E1A3 C9 02 CMP #$02 CMP #BUFPAG ;DIRECT?
|
||||
.,E1A5 D0 0E BNE $E1B5 BNE CLD70 ;NO...
|
||||
;
|
||||
.,E1A7 86 2D STX $2D STX VARTAB
|
||||
.,E1A9 84 2E STY $2E STY VARTAB+1 ;END LOAD ADDRESS
|
||||
.,E1AB A9 76 LDA #$76 LDA #<REDDY
|
||||
.,E1AD A0 A3 LDY #$A3 LDY #>REDDY
|
||||
.,E1AF 20 1E AB JSR $AB1E JSR STROUT
|
||||
.,E1B2 4C 2A A5 JMP $A52A JMP FINI
|
||||
;
|
||||
;PROGRAM LOAD
|
||||
;
|
||||
.,E1B5 20 8E A6 JSR $A68E CLD70 JSR STXTPT
|
||||
.,E1B8 20 33 A5 JSR $A533 JSR LNKPRG
|
||||
.,E1BB 4C 77 A6 JMP $A677 JMP FLOAD
|
||||
|
||||
.,E1BE 20 19 E2 JSR $E219 COPEN JSR PAOC ;PARSE STATEMENT
|
||||
.,E1C1 20 C0 FF JSR $FFC0 JSR $FFC0 ;OPEN IT
|
||||
.,E1C4 B0 0B BCS $E1D1 BCS JERXIT ;BAD STUFF OR MEMSIZ CHANGE
|
||||
.,E1C6 60 RTS RTS ;A.O.K.
|
||||
|
||||
.,E1C7 20 19 E2 JSR $E219 CCLOS JSR PAOC ;PARSE STATEMENT
|
||||
.,E1CA A5 49 LDA $49 LDA ANDMSK ;GET LA
|
||||
.,E1CC 20 C3 FF JSR $FFC3 JSR $FFC3 ;CLOSE IT
|
||||
.,E1CF 90 C3 BCC $E194 BCC CLD20 ;IT'S OKAY...NO MEMSIZE CHANGE
|
||||
;
|
||||
.,E1D1 4C F9 E0 JMP $E0F9 JERXIT JMP EREXIT
|
||||
|
||||
;
|
||||
;PARSE LOAD AND SAVE COMMANDS
|
||||
;
|
||||
PLSV
|
||||
;DEFAULT FILE NAME
|
||||
;
|
||||
.,E1D4 A9 00 LDA #$00 LDA #0 ;LENGTH=0
|
||||
.,E1D6 20 BD FF JSR $FFBD JSR $FFBD
|
||||
;
|
||||
;DEFAULT DEVICE #
|
||||
;
|
||||
.,E1D9 A2 01 LDX #$01 LDX #1 ;DEVICE #1
|
||||
.,E1DB A0 00 LDY #$00 LDY #0 ;COMMAND 0
|
||||
.,E1DD 20 BA FF JSR $FFBA JSR $FFBA
|
||||
;
|
||||
.,E1E0 20 06 E2 JSR $E206 JSR PAOC20 ;BY-PASS JUNK
|
||||
.,E1E3 20 57 E2 JSR $E257 JSR PAOC15 ;GET/SET FILE NAME
|
||||
.,E1E6 20 06 E2 JSR $E206 JSR PAOC20 ;BY-PASS JUNK
|
||||
.,E1E9 20 00 E2 JSR $E200 JSR PLSV7 ;GET ',FA'
|
||||
.,E1EC A0 00 LDY #$00 LDY #0 ;COMMAND 0
|
||||
.,E1EE 86 49 STX $49 STX ANDMSK
|
||||
.,E1F0 20 BA FF JSR $FFBA JSR $FFBA
|
||||
.,E1F3 20 06 E2 JSR $E206 JSR PAOC20 ;BY-PASS JUNK
|
||||
.,E1F6 20 00 E2 JSR $E200 JSR PLSV7 ;GET ',SA'
|
||||
.,E1F9 8A TXA TXA ;NEW COMMAND
|
||||
.,E1FA A8 TAY TAY
|
||||
.,E1FB A6 49 LDX $49 LDX ANDMSK ;DEVICE #
|
||||
.,E1FD 4C BA FF JMP $FFBA JMP $FFBA
|
||||
|
||||
;LOOK FOR COMMA FOLLOWED BY BYTE
|
||||
.,E200 20 0E E2 JSR $E20E PLSV7 JSR PAOC30
|
||||
.,E203 4C 9E B7 JMP $B79E JMP GETBYT
|
||||
|
||||
;SKIP RETURN IF NEXT CHAR IS END
|
||||
;
|
||||
.,E206 20 79 00 JSR $0079 PAOC20 JSR CHRGOT
|
||||
.,E209 D0 02 BNE $E20D BNE PAOCX
|
||||
.,E20B 68 PLA PLA
|
||||
.,E20C 68 PLA PLA
|
||||
.,E20D 60 RTS PAOCX RTS
|
||||
|
||||
;CHECK FOR COMMA AND GOOD STUFF
|
||||
;
|
||||
.,E20E 20 FD AE JSR $AEFD PAOC30 JSR CHKCOM ;CHECK COMMA
|
||||
.,E211 20 79 00 JSR $0079 PAOC32 JSR CHRGOT ;GET CURRENT
|
||||
.,E214 D0 F7 BNE $E20D BNE PAOCX ;IS O.K.
|
||||
.,E216 4C 08 AF JMP $AF08 PAOC40 JMP SNERR ;BAD...END OF LINE
|
||||
|
||||
;PARSE OPEN/CLOSE
|
||||
;
|
||||
.,E219 A9 00 LDA #$00 PAOC LDA #0
|
||||
.,E21B 20 BD FF JSR $FFBD JSR $FFBD ;DEFAULT FILE NAME
|
||||
;
|
||||
.,E21E 20 11 E2 JSR $E211 JSR PAOC32 ;MUST GOT SOMETHING
|
||||
.,E221 20 9E B7 JSR $B79E JSR GETBYT ;GET LA
|
||||
.,E224 86 49 STX $49 STX ANDMSK
|
||||
.,E226 8A TXA TXA
|
||||
.,E227 A2 01 LDX #$01 LDX #1 ;DEFAULT DEVICE
|
||||
.,E229 A0 00 LDY #$00 LDY #0 ;DEFAULT COMMAND
|
||||
.,E22B 20 BA FF JSR $FFBA JSR $FFBA ;STORE IT
|
||||
.,E22E 20 06 E2 JSR $E206 JSR PAOC20 ;SKIP JUNK
|
||||
.,E231 20 00 E2 JSR $E200 JSR PLSV7
|
||||
.,E234 86 4A STX $4A STX EORMSK
|
||||
.,E236 A0 00 LDY #$00 LDY #0 ;DEFAULT COMMAND
|
||||
.,E238 A5 49 LDA $49 LDA ANDMSK ;GET LA
|
||||
.,E23A E0 03 CPX #$03 CPX #3
|
||||
.,E23C 90 01 BCC $E23F BCC PAOC5
|
||||
.,E23E 88 DEY DEY ;DEFAULT IEEE TO $FF
|
||||
.,E23F 20 BA FF JSR $FFBA PAOC5 JSR $FFBA ;STORE THEM
|
||||
.,E242 20 06 E2 JSR $E206 JSR PAOC20 ;SKIP JUNK
|
||||
.,E245 20 00 E2 JSR $E200 JSR PLSV7 ;GET SA
|
||||
.,E248 8A TXA TXA
|
||||
.,E249 A8 TAY TAY
|
||||
.,E24A A6 4A LDX $4A LDX EORMSK
|
||||
.,E24C A5 49 LDA $49 LDA ANDMSK
|
||||
.,E24E 20 BA FF JSR $FFBA JSR $FFBA ;SET UP REAL EVEYTHING
|
||||
.,E251 20 06 E2 JSR $E206 PAOC7 JSR PAOC20
|
||||
.,E254 20 0E E2 JSR $E20E JSR PAOC30
|
||||
.,E257 20 9E AD JSR $AD9E PAOC15 JSR FRMEVL
|
||||
.,E25A 20 A3 B6 JSR $B6A3 JSR FRESTR ;LENGTH IN .A
|
||||
.,E25D A6 22 LDX $22 LDX INDEX1
|
||||
.,E25F A4 23 LDY $23 LDY INDEX1+1
|
||||
.,E261 4C BD FF JMP $FFBD JMP $FFBD
|
||||
.,E0F9 C9 F0 CMP #$F0
|
||||
.,E0FB D0 07 BNE $E104
|
||||
.,E0FD 84 38 STY $38
|
||||
.,E0FF 86 37 STX $37
|
||||
.,E101 4C 63 A6 JMP $A663
|
||||
.,E104 AA TAX
|
||||
.,E105 D0 02 BNE $E109
|
||||
.,E107 A2 1E LDX #$1E
|
||||
.,E109 4C 37 A4 JMP $A437
|
||||
.,E10C 20 D2 FF JSR $FFD2
|
||||
.,E10F B0 E8 BCS $E0F9
|
||||
.,E111 60 RTS
|
||||
.,E112 20 CF FF JSR $FFCF
|
||||
.,E115 B0 E2 BCS $E0F9
|
||||
.,E117 60 RTS
|
||||
.,E118 20 AD E4 JSR $E4AD
|
||||
.,E11B B0 DC BCS $E0F9
|
||||
.,E11D 60 RTS
|
||||
.,E11E 20 C6 FF JSR $FFC6
|
||||
.,E121 B0 D6 BCS $E0F9
|
||||
.,E123 60 RTS
|
||||
.,E124 20 E4 FF JSR $FFE4
|
||||
.,E127 B0 D0 BCS $E0F9
|
||||
.,E129 60 RTS
|
||||
.,E12A 20 8A AD JSR $AD8A
|
||||
.,E12D 20 F7 B7 JSR $B7F7
|
||||
.,E130 A9 E1 LDA #$E1
|
||||
.,E132 48 PHA
|
||||
.,E133 A9 46 LDA #$46
|
||||
.,E135 48 PHA
|
||||
.,E136 AD 0F 03 LDA $030F
|
||||
.,E139 48 PHA
|
||||
.,E13A AD 0C 03 LDA $030C
|
||||
.,E13D AE 0D 03 LDX $030D
|
||||
.,E140 AC 0E 03 LDY $030E
|
||||
.,E143 28 PLP
|
||||
.,E144 6C 14 00 JMP ($0014)
|
||||
.,E147 08 PHP
|
||||
.,E148 8D 0C 03 STA $030C
|
||||
.,E14B 8E 0D 03 STX $030D
|
||||
.,E14E 8C 0E 03 STY $030E
|
||||
.,E151 68 PLA
|
||||
.,E152 8D 0F 03 STA $030F
|
||||
.,E155 60 RTS
|
||||
.,E156 20 D4 E1 JSR $E1D4
|
||||
.,E159 A6 2D LDX $2D
|
||||
.,E15B A4 2E LDY $2E
|
||||
.,E15D A9 2B LDA #$2B
|
||||
.,E15F 20 D8 FF JSR $FFD8
|
||||
.,E162 B0 95 BCS $E0F9
|
||||
.,E164 60 RTS
|
||||
.,E165 A9 01 LDA #$01
|
||||
.:E167 2C .BYTE $2C
|
||||
.,E168 A9 00 LDA #$00
|
||||
.,E16A 85 0A STA $0A
|
||||
.,E16C 20 D4 E1 JSR $E1D4
|
||||
.,E16F A5 0A LDA $0A
|
||||
.,E171 A6 2B LDX $2B
|
||||
.,E173 A4 2C LDY $2C
|
||||
.,E175 20 D5 FF JSR $FFD5
|
||||
.,E178 B0 57 BCS $E1D1
|
||||
.,E17A A5 0A LDA $0A
|
||||
.,E17C F0 17 BEQ $E195
|
||||
.,E17E A2 1C LDX #$1C
|
||||
.,E180 20 B7 FF JSR $FFB7
|
||||
.,E183 29 10 AND #$10
|
||||
.,E185 D0 17 BNE $E19E
|
||||
.,E187 A5 7A LDA $7A
|
||||
.,E189 C9 02 CMP #$02
|
||||
.,E18B F0 07 BEQ $E194
|
||||
.,E18D A9 64 LDA #$64
|
||||
.,E18F A0 A3 LDY #$A3
|
||||
.,E191 4C 1E AB JMP $AB1E
|
||||
.,E194 60 RTS
|
||||
.,E195 20 B7 FF JSR $FFB7
|
||||
.,E198 29 BF AND #$BF
|
||||
.,E19A F0 05 BEQ $E1A1
|
||||
.,E19C A2 1D LDX #$1D
|
||||
.,E19E 4C 37 A4 JMP $A437
|
||||
.,E1A1 A5 7B LDA $7B
|
||||
.,E1A3 C9 02 CMP #$02
|
||||
.,E1A5 D0 0E BNE $E1B5
|
||||
.,E1A7 86 2D STX $2D
|
||||
.,E1A9 84 2E STY $2E
|
||||
.,E1AB A9 76 LDA #$76
|
||||
.,E1AD A0 A3 LDY #$A3
|
||||
.,E1AF 20 1E AB JSR $AB1E
|
||||
.,E1B2 4C 2A A5 JMP $A52A
|
||||
.,E1B5 20 8E A6 JSR $A68E
|
||||
.,E1B8 20 33 A5 JSR $A533
|
||||
.,E1BB 4C 77 A6 JMP $A677
|
||||
.,E1BE 20 19 E2 JSR $E219
|
||||
.,E1C1 20 C0 FF JSR $FFC0
|
||||
.,E1C4 B0 0B BCS $E1D1
|
||||
.,E1C6 60 RTS
|
||||
.,E1C7 20 19 E2 JSR $E219
|
||||
.,E1CA A5 49 LDA $49
|
||||
.,E1CC 20 C3 FF JSR $FFC3
|
||||
.,E1CF 90 C3 BCC $E194
|
||||
.,E1D1 4C F9 E0 JMP $E0F9
|
||||
.,E1D4 A9 00 LDA #$00
|
||||
.,E1D6 20 BD FF JSR $FFBD
|
||||
.,E1D9 A2 01 LDX #$01
|
||||
.,E1DB A0 00 LDY #$00
|
||||
.,E1DD 20 BA FF JSR $FFBA
|
||||
.,E1E0 20 06 E2 JSR $E206
|
||||
.,E1E3 20 57 E2 JSR $E257
|
||||
.,E1E6 20 06 E2 JSR $E206
|
||||
.,E1E9 20 00 E2 JSR $E200
|
||||
.,E1EC A0 00 LDY #$00
|
||||
.,E1EE 86 49 STX $49
|
||||
.,E1F0 20 BA FF JSR $FFBA
|
||||
.,E1F3 20 06 E2 JSR $E206
|
||||
.,E1F6 20 00 E2 JSR $E200
|
||||
.,E1F9 8A TXA
|
||||
.,E1FA A8 TAY
|
||||
.,E1FB A6 49 LDX $49
|
||||
.,E1FD 4C BA FF JMP $FFBA
|
||||
.,E200 20 0E E2 JSR $E20E
|
||||
.,E203 4C 9E B7 JMP $B79E
|
||||
.,E206 20 79 00 JSR $0079
|
||||
.,E209 D0 02 BNE $E20D
|
||||
.,E20B 68 PLA
|
||||
.,E20C 68 PLA
|
||||
.,E20D 60 RTS
|
||||
.,E20E 20 FD AE JSR $AEFD
|
||||
.,E211 20 79 00 JSR $0079
|
||||
.,E214 D0 F7 BNE $E20D
|
||||
.,E216 4C 08 AF JMP $AF08
|
||||
.,E219 A9 00 LDA #$00
|
||||
.,E21B 20 BD FF JSR $FFBD
|
||||
.,E21E 20 11 E2 JSR $E211
|
||||
.,E221 20 9E B7 JSR $B79E
|
||||
.,E224 86 49 STX $49
|
||||
.,E226 8A TXA
|
||||
.,E227 A2 01 LDX #$01
|
||||
.,E229 A0 00 LDY #$00
|
||||
.,E22B 20 BA FF JSR $FFBA
|
||||
.,E22E 20 06 E2 JSR $E206
|
||||
.,E231 20 00 E2 JSR $E200
|
||||
.,E234 86 4A STX $4A
|
||||
.,E236 A0 00 LDY #$00
|
||||
.,E238 A5 49 LDA $49
|
||||
.,E23A E0 03 CPX #$03
|
||||
.,E23C 90 01 BCC $E23F
|
||||
.,E23E 88 DEY
|
||||
.,E23F 20 BA FF JSR $FFBA
|
||||
.,E242 20 06 E2 JSR $E206
|
||||
.,E245 20 00 E2 JSR $E200
|
||||
.,E248 8A TXA
|
||||
.,E249 A8 TAY
|
||||
.,E24A A6 4A LDX $4A
|
||||
.,E24C A5 49 LDA $49
|
||||
.,E24E 20 BA FF JSR $FFBA
|
||||
.,E251 20 06 E2 JSR $E206
|
||||
.,E254 20 0E E2 JSR $E20E
|
||||
.,E257 20 9E AD JSR $AD9E
|
||||
.,E25A 20 A3 B6 JSR $B6A3
|
||||
.,E25D A6 22 LDX $22
|
||||
.,E25F A4 23 LDY $23
|
||||
.,E261 4C BD FF JMP $FFBD
|
||||
|
||||
PAGE
|
||||
SUBTTL SINE, COSINE AND TANGENT FUNCTIONS.
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,373 +0,0 @@
|
|||
- C64 I/O Map (Programmer's Reference Guide)
|
||||
-
|
||||
- C64PRG10.TXT
|
||||
-
|
||||
- practically the same:
|
||||
- 64MAP10.TXT/Commodore_64_IO_Maps.doc
|
||||
- 64MAP10.TXT/Commodore_64_Memory_Maps.txt
|
||||
------------------------------------------------------------
|
||||
-
|
||||
# [...]
|
||||
|
||||
0000 0 7-0 MOS 6510 Data Direction
|
||||
Register (xx101111)
|
||||
Bit= 1: Output, Bit=0:
|
||||
Input, x=Don't Care
|
||||
|
||||
0001 1 MOS 6510 Micro-Processor
|
||||
On-Chip I/O Port
|
||||
0 /LORAM Signal (0=Switch BASIC ROM Out)
|
||||
1 /HIRAM Signal (0=Switch Kernal ROM Out)
|
||||
2 /CHAREN Signal (0=Switch Char. ROM In)
|
||||
3 Cassette Data Output Line
|
||||
4 Cassette Switch Sense: 1 = Switch Closed
|
||||
5 Cassette Motor Control 0 = ON, 1 = OFF
|
||||
6-7 Undefined
|
||||
|
||||
|
||||
D000-D02E 53248-54271 MOS 6566 VIDEO INTERFACE CONTROLLER
|
||||
(VIC)
|
||||
|
||||
D000 53248 Sprite 0 X Pos
|
||||
D001 53249 Sprite 0 Y Pos
|
||||
D002 53250 Sprite 1 X Pos
|
||||
D003 53251 Sprite 1 Y Pos
|
||||
D004 53252 Sprite 2 X Pos
|
||||
D005 53253 Sprite 2 Y Pos
|
||||
D006 53254 Sprite 3 X Pos
|
||||
D007 53255 Sprite 3 Y Pos
|
||||
D008 53256 Sprite 4 X Pos
|
||||
D009 53257 Sprite 4 Y Pos
|
||||
D00A 53258 Sprite 5 X Pos
|
||||
D00B 53259 Sprite 5 Y Pos
|
||||
D00C 53260 Sprite 6 X Pos
|
||||
D00D 53261 Sprite 6 Y Pos
|
||||
D00E 53262 Sprite 7 X Pos
|
||||
D00F 53263 Sprite 7 Y Pos
|
||||
D010 53264 Sprites 0-7 X Pos (msb of X coord.)
|
||||
D011 53265 VIC Control Register
|
||||
7 Raster Compare: (Bit 8) See 53266
|
||||
6 Extended Color Text Mode 1 = Enable
|
||||
5 Bit Map Mode. 1 = Enable
|
||||
4 Blank Screen to Border Color: 0 = Blank
|
||||
3 Select 24/25 Row Text Display: 1=25 Rows
|
||||
2-0 Smooth Scroll to Y Dot-Position (0-7)
|
||||
|
||||
D012 53266 Read Raster/Write Raster Value for
|
||||
Compare IRQ
|
||||
D013 53267 Light-Pen Latch X Pos
|
||||
D014 53268 Light-Pen Latch Y Pos
|
||||
D015 53269 Sprite display Enable: 1 = Enable
|
||||
D016 53270 VIC Control Register
|
||||
7-6 Unused
|
||||
5 ALWAYS SET THIS BIT TO 0 !
|
||||
4 Multi-Color Mode: 1 = Enable (Text or
|
||||
Bit-Map)
|
||||
3 Select 38/40 Column Text Display:
|
||||
1 = 40 Cols
|
||||
2-0 Smooth Scroll to X Pos
|
||||
|
||||
D017 53271 Sprites 0-7 Expand 2x Vertical (Y)
|
||||
D018 53272 VIC Memory Control Register
|
||||
7-4 Video Matrix Base Address (inside VIC)
|
||||
3-1 Character Dot-Data Base Address (inside
|
||||
VIC)
|
||||
0 Select upper/lower Character Set
|
||||
|
||||
D019 53273 VIC Interrupt Flag Register (Bit = 1:
|
||||
IRQ Occurred)
|
||||
7 Set on Any Enabled VIC IRQ Condition
|
||||
3 Light-Pen Triggered IRQ Flag
|
||||
2 Sprite to Sprite Collision IRQ Flag
|
||||
1 Sprite to Background Collision IRQ Flag
|
||||
0 Raster Compare IRQ Flag
|
||||
|
||||
D01A 53274 IRQ Mask Register: 1 = Interrupt Enabled
|
||||
D01B 53275 Sprite to Background Display Priority:
|
||||
1 = Sprite
|
||||
D01C 53276 Sprites 0-7 Multi-Color Mode Select:
|
||||
1 = M.C.M.
|
||||
D01D 53277 Sprites 0-7 Expand 2x Horizontal (X)
|
||||
D01E 53278 Sprite to Sprite Collision Detect
|
||||
D01F 53279 Sprite to Background Collision Detect
|
||||
D020 53280 Border Color
|
||||
D021 53281 Background Color 0
|
||||
D022 53282 Background Color 1
|
||||
D023 53283 Background Color 2
|
||||
D024 53284 Background Color 3
|
||||
D025 53285 Sprite Multi-Color Register 0
|
||||
D026 53286 Sprite Multi-Color Register 1
|
||||
D027 53287 Sprite 0 Color
|
||||
D028 53288 Sprite 1 Color
|
||||
D029 53289 Sprite 2 Color
|
||||
D02A 53290 Sprite 3 Color
|
||||
D02B 53291 Sprite 4 Color
|
||||
D02C 53292 Sprite 5 Color
|
||||
D02D 53293 Sprite 6 Color
|
||||
D02E 53294 Sprite 7 Color
|
||||
|
||||
|
||||
D400-D7FF 54272-55295 MOS 6581 SOUND INTERFACE DEVICE (SID)
|
||||
|
||||
D400 54272 Voice 1: Frequency Control - Low-Byte
|
||||
D401 54273 Voice 1: Frequency Control - High-Byte
|
||||
D402 54274 Voice 1: Pulse Waveform Width - Low-Byte
|
||||
D403 54275 7-4 Unused
|
||||
3-0 Voice 1: Pulse Waveform Width - High-
|
||||
Nybble
|
||||
|
||||
D404 54276 Voice 1: Control Register
|
||||
7 Select Random Noise Waveform, 1 = On
|
||||
6 Select Pulse Waveform, 1 = On
|
||||
5 Select Sawtooth Waveform, 1 = On
|
||||
4 Select Triangle Waveform, 1 = On
|
||||
3 Test Bit: 1 = Disable Oscillator 1
|
||||
2 Ring Modulate Osc. 1 with Osc. 3 Output,
|
||||
1 = On
|
||||
1 Synchronize Osc.1 with Osc.3 Frequency,
|
||||
1 = On
|
||||
0 Gate Bit: 1 = Start Att/Dec/Sus,
|
||||
0 = Start Release
|
||||
|
||||
D405 54277 Envelope Generator 1: Attack/Decay Cycle
|
||||
Control
|
||||
7-4 Select Attack Cycle Duration: 0-15
|
||||
3-0 Select Decay Cycle Duration: 0-15
|
||||
|
||||
D406 54278 Envelope Generator 1: Sustain/Release
|
||||
Cycle Control
|
||||
7-4 Select Sustain Cycle Duration: 0-15
|
||||
3-0 Select Release Cycle Duration: 0-15
|
||||
|
||||
D407 54279 Voice 2: Frequency Control - Low-Byte
|
||||
D408 54280 Voice 2: Frequency Control - High-Byte
|
||||
D409 54281 Voice 2: Pulse Waveform Width - Low-Byte
|
||||
D40A 54282 7-4 Unused
|
||||
3-0 Voice 2: Pulse Waveform Width - High-
|
||||
Nybble
|
||||
|
||||
D40B 54283 Voice 2: Control Register
|
||||
7 Select Random Noise Waveform, 1 = On
|
||||
6 Select Pulse Waveform, 1 = On
|
||||
5 Select Sawtooth Waveform, 1 = On
|
||||
4 Select Triangle Waveform, 1 = On
|
||||
3 Test Bit: 1 = Disable Oscillator 1
|
||||
2 Ring Modulate Osc. 2 with Osc. 1 Output,
|
||||
1 = On
|
||||
1 Synchronize Osc.2 with Osc. 1 Frequency,
|
||||
1 = On
|
||||
0 Gate Bit: 1 = Start Att/Dec/Sus,
|
||||
0 = Start Release
|
||||
|
||||
D40C 54284 Envelope Generator 2: Attack / Decay
|
||||
Cycle Control
|
||||
7-4 Select Attack Cycle Duration: 0-15
|
||||
3-0 Select Decay Cycle Duration: 0-15
|
||||
|
||||
D40D 54285 Envelope Generator 2: Sustain / Release
|
||||
Cycle Control
|
||||
7-4 Select Sustain Cycle Duration: 0-15
|
||||
3-0 Select Release Cycle Duration: 0-15
|
||||
|
||||
D40E 54286 Voice 3: Frequency Control - Low-Byte
|
||||
D40F 54287 Voice 3: Frequency Control - High-Byte
|
||||
D410 54288 Voice 3: Pulse Waveform Width - Low-Byte
|
||||
D411 54289 7-4 Unused
|
||||
3-0 Voice 3: Pulse Waveform Width - High-
|
||||
Nybble
|
||||
|
||||
D412 54290 Voice 3: Control Register
|
||||
7 Select Random Noise Waveform, 1 = On
|
||||
6 Select Pulse Waveform, 1 = On
|
||||
5 Select Sawtooth Waveform, 1 = On
|
||||
4 Select Triangle Waveform, 1 = On
|
||||
3 Test Bit: 1 = Disable Oscillator 1
|
||||
2 Ring Modulate Osc. 3 with Osc. 2 Output,
|
||||
1 = On
|
||||
1 Synchronize Osc. 3 with Osc.2 Frequency,
|
||||
1 = On
|
||||
0 Gate Bit: 1 = Start Att/Dec/Sus,
|
||||
0 = Start Release
|
||||
|
||||
D413 54291 Envelope Generator 3: Attack/Decay Cycle
|
||||
Control
|
||||
7-4 Select Attack Cycle Duration: 0-15
|
||||
3-0 Select Decay Cycle Duration: 0-15
|
||||
|
||||
D414 54285 Envelope Generator 3: Sustain / Release
|
||||
Cycle Control
|
||||
7-4 Select Sustain Cycle Duration: 0-15
|
||||
3-0 Select Release Cycle Duration: 0-15
|
||||
|
||||
D415 54293 Filter Cutoff Frequency: Low-Nybble
|
||||
(Bits 2-0)
|
||||
D416 54294 Filter Cutoff Frequency: High-Byte
|
||||
D417 54295 Filter Resonance Control / Voice Input
|
||||
Control
|
||||
7-4 Select Filter Resonance: 0-15
|
||||
3 Filter External Input: 1 = Yes, 0 = No
|
||||
2 Filter Voice 3 Output: 1 = Yes, 0 = No
|
||||
Filter Voice 2 Output: 1 = Yes, 0 = No
|
||||
0 Filter Voice 1 Output: 1 = Yes, 0 = No
|
||||
|
||||
D418 54296 Select Filter Mode and Volume
|
||||
7 Cut-Off Voice 3 Output: 1 = Off, 0 = On
|
||||
6 Select Filter High-Pass Mode: 1 = On
|
||||
5 Select Filter Band-Pass Mode: 1 = On
|
||||
4 Select Filter Low-Pass Mode: 1 = On
|
||||
3-0 Select Output Volume: 0-15
|
||||
|
||||
D419 54297 Analog/Digital Converter: Game Paddle 1
|
||||
(0-255)
|
||||
D41A 54298 Analog/Digital Converter: Game Paddle 2
|
||||
(0-255)
|
||||
D41B 54299 Oscillator 3 Random Number Generator
|
||||
D41C 54230 Envelope Generator 3 Output
|
||||
D500-D7FF 54528-55295 SID IMAGES
|
||||
D800-DBFF 55296-56319 Color RAM (Nybbles)
|
||||
|
||||
DC00-DCFF 56320-56575 MOS 6526 Complex Interface Adapter
|
||||
(CIA) #1
|
||||
|
||||
DC00 56320 Data Port A (Keyboard, Joystick,
|
||||
Paddles, Light-Pen)
|
||||
7-0 Write Keyboard Column Values for
|
||||
Keyboard Scan
|
||||
7-6 Read Paddles on Port A / B (01 = Port A,
|
||||
10 = Port B)
|
||||
4 Joystick A Fire Button: 1 = Fire
|
||||
3-2 Paddle Fire Buttons
|
||||
3-0 Joystick A Direction (0-15)
|
||||
|
||||
DC01 56321 Data Port B (Keyboard, Joystick,
|
||||
Paddles): Game Port 1
|
||||
7-0 Read Keyboard Row Values for Keyboard
|
||||
Scan
|
||||
7 Timer B Toggle/Pulse Output
|
||||
6 Timer A: Toggle/Pulse Output
|
||||
4 Joystick 1 Fire Button: 1 = Fire
|
||||
3-2 Paddle Fire Buttons
|
||||
3-0 Joystick 1 Direction
|
||||
|
||||
DC02 56322 Data Direction Register - Port A (56320)
|
||||
DC03 56323 Data Direction Register - Port B (56321)
|
||||
DC04 56324 Timer A: Low-Byte
|
||||
DC05 56325 Timer A: High-Byte
|
||||
DC06 56326 Timer B: Low-Byte
|
||||
DC07 56327 Timer B: High-Byte
|
||||
|
||||
DC08 56328 Time-of-Day Clock: 1/10 Seconds
|
||||
DC09 56329 Time-of-Day Clock: Seconds
|
||||
DC0A 56330 Time-of-Day Clock: Minutes
|
||||
DC0B 56331 Time-of-Day Clock: Hours + AM/PM Flag
|
||||
(Bit 7)
|
||||
DC0C 56332 Synchronous Serial I/O Data Buffer
|
||||
DC0D 56333 CIA Interrupt Control Register
|
||||
(Read IRQs/Write Mask)
|
||||
7 IRQ Flag (1 = IRQ Occurred) / Set-
|
||||
Clear Flag
|
||||
4 FLAG1 IRQ (Cassette Read / Serial Bus
|
||||
SRQ Input)
|
||||
3 Serial Port Interrupt
|
||||
2 Time-of-Day Clock Alarm Interrupt
|
||||
1 Timer B Interrupt
|
||||
0 Timer A Interrupt
|
||||
|
||||
DC0E 56334 CIA Control Register A
|
||||
7 Time-of-Day Clock Frequency: 1 = 50 Hz,
|
||||
0 = 60 Hz
|
||||
6 Serial Port I/O Mode Output, 0 = Input
|
||||
|
||||
5 Timer A Counts: 1 = CNT Signals,
|
||||
0 = System 02 Clock
|
||||
4 Force Load Timer A: 1 = Yes
|
||||
3 Timer A Run Mode: 1 = One-Shot,
|
||||
0 = Continuous
|
||||
2 Timer A Output Mode to PB6: 1 = Toggle,
|
||||
0 = Pulse
|
||||
1 Timer A Output on PB6: 1 = Yes, 0 = No
|
||||
0 Start/Stop Timer A: 1 = Start, 0 = Stop
|
||||
|
||||
DC0F 56335 CIA Control Register B
|
||||
7 Set Alarm/TOD-Clock: 1 = Alarm,
|
||||
0 = Clock
|
||||
6-5 Timer B Mode Select:
|
||||
00 = Count System 02 Clock Pulses
|
||||
01 = Count Positive CNT Transitions
|
||||
10 = Count Timer A Underflow Pulses
|
||||
11 = Count Timer A Underflows While
|
||||
CNT Positive
|
||||
4-0 Same as CIA Control Reg. A - for Timer B
|
||||
|
||||
DD00-DDFF 56576-56831 MOS 6526 Complex Interface Adapter
|
||||
(CIA) #2
|
||||
|
||||
DD00 56576 Data Port A (Serial Bus, RS-232, VIC
|
||||
Memory Control)
|
||||
7 Serial Bus Data Input
|
||||
6 Serial Bus Clock Pulse Input
|
||||
5 Serial Bus Data Output
|
||||
4 Serial Bus Clock Pulse Output
|
||||
3 Serial Bus ATN Signal Output
|
||||
2 RS-232 Data Output (User Port)
|
||||
1-0 VIC Chip System Memory Bank Select
|
||||
(Default = 11)
|
||||
|
||||
DD01 56577 Data Port B (User Port, RS-232)
|
||||
7 User / RS-232 Data Set Ready
|
||||
6 User / RS-232 Clear to Send
|
||||
5 User
|
||||
4 User / RS-232 Carrier Detect
|
||||
3 User / RS-232 Ring Indicator
|
||||
2 User / RS-232 Data Terminal Ready
|
||||
1 User / RS-232 Request to Send
|
||||
0 User / RS-232 Received Data
|
||||
|
||||
DD02 56578 Data Direction Register - Port A
|
||||
DD03 56579 Data Direction Register - Port B
|
||||
DD04 56580 Timer A: Low-Byte
|
||||
DD05 56581 Timer A: High-Byte
|
||||
DD06 56582 Timer B: Low-Byte
|
||||
DD07 56583 Timer B: High-Byte
|
||||
DD08 56584 Time-of-Day Clock: 1/10 Seconds
|
||||
DD09 56585 Time-of-Day Clock: Seconds
|
||||
DD0A 56586 Time-of-Day Clock: Minutes
|
||||
DD0B 56587 Time-of-Day Clock: Hours + AM/PM Flag
|
||||
(Bit 7)
|
||||
DD0C 56588 Synchronous Serial I/O Data Buffer
|
||||
DD0D 56589 CIA Interrupt Control Register (Read
|
||||
NMls/Write Mask)
|
||||
7 NMI Flag (1 = NMI Occurred) / Set-
|
||||
Clear Flag
|
||||
4 FLAG1 NMI (User/RS-232 Received Data
|
||||
Input)
|
||||
3 Serial Port Interrupt
|
||||
1 Timer B Interrupt
|
||||
0 Timer A Interrupt
|
||||
|
||||
DD0E 56590 CIA Control Register A
|
||||
7 Time-of-Day Clock Frequency: 1 = 50 Hz,
|
||||
0 = 60 Hz
|
||||
6 Serial Port I/O Mode Output, 0 = Input
|
||||
5 Timer A Counts: 1 = CNT Signals,
|
||||
0 = System 02 Clock
|
||||
4 Force Load Timer A: 1 = Yes
|
||||
3 Timer A Run Mode: 1 = One-Shot,
|
||||
0 = Continuous
|
||||
2 Timer A Output Mode to PB6: 1 = Toggle,
|
||||
0 = Pulse
|
||||
1 Timer A Output on PB6: 1 = Yes, 0 = No
|
||||
0 Start/Stop Timer A: 1 = Start, 0 = Stop
|
||||
|
||||
DD0F 56591 CIA Control Register B
|
||||
7 Set Alarm/TOD-Clock: 1=Alarm, 0=Clock
|
||||
6-5 Timer B Mode Select:
|
||||
00 = Count System 02 Clock Pulses
|
||||
01 = Count Positive CNT Transitions
|
||||
10 = Count Timer A Underflow Pulses
|
||||
11 = Count Timer A Underflows While
|
||||
CNT Positive
|
||||
4-0 Same as CIA Control Reg. A - for Timer B
|
||||
|
||||
DE00-DEFF 56832-57087 Reserved for Future I/O Expansion
|
||||
DF00-DFFF 57088-57343 Reserved for Future I/O Expansion
|
||||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -1,322 +0,0 @@
|
|||
- C64 RAM Map (64MAP10.TXT)
|
||||
-
|
||||
- Anonymous
|
||||
- Commodore_64_Memory_Maps.txt
|
||||
- in: 64MAP10.TXT, which states ftp://arnold.hiof.no/programs
|
||||
- as the original source
|
||||
-
|
||||
- Corrections (typos as well as content), translations etc.
|
||||
- welcome at: https://github.com/mist64/c64disasm
|
||||
-
|
||||
------------------------------------------------------------
|
||||
-
|
||||
# This plain text file is formatted so that it can be automatically
|
||||
# parsed in order to create cross-references etc.
|
||||
# * Lines starting with "-" is top-level information. The first line
|
||||
# is the title. Lines starting with "--" are separators.
|
||||
# * Lines starting with "#" are internal comments.
|
||||
# * Hex addresses start at column 0.
|
||||
# * Symbols start at column 13.
|
||||
# * The description starts at column 21.
|
||||
# * All lines of the description until the first blank line are
|
||||
# combined into the heading.
|
||||
# * A '.' character at the end of a heading line represents a hard
|
||||
# line break.
|
||||
# * The remaining text is in MarkDown format.
|
||||
# * All addresses are 4 digits and have a leading '$'.
|
||||
# The encoding is UTF-8.
|
||||
|
||||
$0000 D6510 6510 On-chip Data Direction Register.
|
||||
$0001 R6510 6510 On-chip 8-bit Input/Output Register.
|
||||
$0002 Unused. Free for user programs.
|
||||
$0003-$0004 ADRAY1 Jump Vector: Convert FAC to Integer in (A/Y)
|
||||
($B1AA).
|
||||
$0005-$0006 ADRAY2 Jump Vector: Convert Integer in (A/Y) to
|
||||
Floating point in (FAC); ($B391).
|
||||
$0007-$0008 Temporary Integer during OR/AND.
|
||||
$0007 CHARAC Search Character/Temporary Integer during INT.
|
||||
$0008 ENDCHR Flag: Scan for Quote at end of String.
|
||||
$0009 TRMPOS Screen Column for last TAB.
|
||||
$000A VERCK Flag: 0 = Load, 1 = Verify.
|
||||
$000B COUNT Input Buffer Pointer/Number of Subscripts.
|
||||
$000C DIMFLG Flag: Default Array dimension.
|
||||
$000D VALTYP Data type Flag: $00 = Numeric, $FF = String.
|
||||
$000E INTFLG Data type Flag: $00 = Floating point, $80 =
|
||||
Integer.
|
||||
$000F GARBFL Flag: DATA scan/List Quote/Garbage collection.
|
||||
$0010 SUBFLG Flag: Subscript reference/User Function call.
|
||||
$0011 INPFLG Input Flag: $00 = INPUT, $40 = GET, $98 =
|
||||
READ.
|
||||
$0012 TANSGN Flag: TAN sign/Comparative result.
|
||||
$0013 CHANNL File number of current Input Device.
|
||||
$0014-$0015 LINNUM Temporary: Integer value.
|
||||
$0016 TEMPPT Pointer: Temporary String Stack.
|
||||
$0017-$0018 LASTPT Last temporary String Address.
|
||||
$0019-$0021 TEMPST Stack for temporary Strings.
|
||||
$0022-$0025 INDEX Utility Pointer Area.
|
||||
$0022-$0023 INDEX1 First Utility Pointer.
|
||||
$0024-$0025 INDEX2 Secong Utility Pointer.
|
||||
$0026-$002A RES Floating point product of Multiply and
|
||||
Divide.
|
||||
$002B-$002C TXTTAB Pointer: Start of BASIC Text Area ($0801).
|
||||
$002D-$002E VARTAB Pointer: Start of BASIC Variables.
|
||||
$002F-$0030 ARYTAB Pointer: Start of BASIC Arrays.
|
||||
$0031-$0032 STREND Pointer: End of BASIC Arrays + 1.
|
||||
$0033-$0034 FRETOP Pointer: Bottom of String space.
|
||||
$0035-$0036 FRESPC Utility String Pointer.
|
||||
$0037-$0038 MEMSIZ Pointer: Highest Address available to BASIC
|
||||
($A000).
|
||||
$0039-$003A CURLIN Current BASIC Line number.
|
||||
$003B-$003C OLDLIN Previous BASIC Line number.
|
||||
$003D-$003E OLDTXT Pointer: BASIC Statement for CONT.
|
||||
$003F-$0040 DATLIN Current DATA Line number.
|
||||
$0041-$0042 DATPTR Pointer: Used by READ - current DATA Item
|
||||
Address.
|
||||
$0043-$0044 INPPTR Pointer: Temporary storage of Pointer during
|
||||
INPUT Routine.
|
||||
$0045-$0046 VARNAM Name of Variable being sought in Variable
|
||||
Table.
|
||||
$0047-$0048 VARPNT Pointer: to value of (VARNAM) if Integer, to
|
||||
descriptor if String.
|
||||
$0049-$004A FORPNT Pointer: Index Variable for FOR/NEXT loop.
|
||||
$004B-$004C VARTXT Temporary storage for TXTPTR during READ,
|
||||
INPUT and GET.
|
||||
$004D OPMASK Mask used during FRMEVL.
|
||||
$004E-$0052 TEMPF3 Temporary storage for FLPT value.
|
||||
$0053 FOUR6 Length of String Variable during Garbege
|
||||
collection.
|
||||
$0054-$0056 JMPER Jump Vector used in Function Evaluation -
|
||||
JMP followed by Address ($4C,$LB,$MB).
|
||||
$0057-$005B TEMPF1 Temporary storage for FLPT value.
|
||||
$005C-$0060 TEMPF2 Temporary storage for FLPT value.
|
||||
$0061-$0066 FAC Main Floating point Accumulator.
|
||||
$0061 FACEXP FAC Exponent.
|
||||
$0062-$0065 FACHO FAC Mantissa.
|
||||
$0066 FACSGN FAC Sign.
|
||||
$0067 SGNFLG Pointer: Series Evaluation Constant.
|
||||
$0068 BITS Bit Overflow Area during normalisation
|
||||
Routine.
|
||||
$0069-$006E ARG Auxiliary Floating point Accumulator.
|
||||
$0069 ARGEXP AFAC Exponent.
|
||||
$006A-$006D AFAC Mantissa.
|
||||
$006E ARGSGN AFAC Sign.
|
||||
$006F ARISGN Sign of result of Arithmetic Evaluation.
|
||||
$0070 FACOV FAC low-order rounding.
|
||||
$0071-$0072 FBUFPT Pointer: Used during CRUNCH/ASCII conversion.
|
||||
$0073-$008A CHRGET Subroutine: Get next Byte of BASIC Text.
|
||||
|
||||
,0073 INC $7A
|
||||
,0075 BNE $0079
|
||||
,0077 INC $7B
|
||||
,0079 LDA $0801
|
||||
,007C CMP #$3A
|
||||
,007E BCS $008A
|
||||
,0080 CMP #$20
|
||||
,0082 BEQ $0073
|
||||
,0084 SEC
|
||||
,0085 SBC #$30
|
||||
,0087 SEC
|
||||
,0088 SBC #$D0
|
||||
,008A RTS
|
||||
|
||||
$0079 CHRGOT Entry to Get same Byte again.
|
||||
$007A-$007B TXTPTR Pointer: Current Byte of BASIC Text.
|
||||
$008B-$008F RNDX Floating RND Function Seed Value.
|
||||
$0090 STATUS Kernal I/O Status Word ST.
|
||||
$0091 STKEY Flag: $7F = STOP key.
|
||||
$0092 SVXT Timing Constant for Tape.
|
||||
$0093 VERCK Flag: 0 = Load, 1 = Verify.
|
||||
$0094 C3P0 Flag: Serial Bus - Output Character buffered.
|
||||
$0095 BSOUR Buffered Character for Serial Bus.
|
||||
$0096 SYNO Cassette Sync. number.
|
||||
$0097 XSAV Temporary storage of X Register during CHRIN.
|
||||
Temporary storage of Y Register during RS232
|
||||
fetch.
|
||||
$0098 LDTND Number of Open Files/Index to File Table.
|
||||
$0099 DFLTN Default Input Device (0).
|
||||
$009A DFLTO Default Output Device (3).
|
||||
$009B PRTY Parity of Byte Output to Tape.
|
||||
$009C DPSW Flag: Byte received from Tape.
|
||||
$009D MSGFLG Flag: $00 = Program mode: Suppress Error
|
||||
Messages, $40 = Kernal Error Messages only,
|
||||
$80 = Direct mode: Full Error Messages.
|
||||
$009E PTR1 Tape Error log pass 1.
|
||||
$009E T1 Index to Cassette File name/Header ID for
|
||||
Tape write.
|
||||
$009F PTR2 Tape Error log pass 2.
|
||||
$00A0-$00A2 TIME Real-time jiffy Clock (Updated by IRQ
|
||||
Interrupt approx. every 1/60 of Second);
|
||||
Update Routine: UDTIMK ($F69B).
|
||||
$00A3 Bit Counter Tape Read or Write/Serial Bus
|
||||
EOI (End Of Input) Flag.
|
||||
$00A4 Pulse Counter Tape Read or Write/Serial Bus
|
||||
shift Counter.
|
||||
$00A5 CNTDN Tape Synchronising count down.
|
||||
$00A6 BUFPT Pointer: Tape I/O buffer.
|
||||
$00A7 INBIT RS232 temporary for received Bit/Tape
|
||||
temporary.
|
||||
$00A8 BITCI RS232 Input Bit count/Tape temporary.
|
||||
$00A9 RINONE RS232 Flag: Start Bit check/Tape temporary.
|
||||
$00AA RIDATA RS232 Input Byte Buffer/Tape temporary.
|
||||
$00AB RIPRTY RS232 Input parity/Tape temporary.
|
||||
$00AC-$00AD Pointer: Tape Buffer/Screen scrolling.
|
||||
$00AE-$00AF Tape End Address/End of Program.
|
||||
$00B0-$00B1 Tape timing Constants.
|
||||
$00B2-$00B3 TAPE1 Pointer: Start Address of Tape Buffer ($033C).
|
||||
$00B4 BITTS RS232 Write bit count/Tape Read timing Flag.
|
||||
$00B5 NXTBIT RS232 Next Bit to send/Tape Read - End of
|
||||
Tape.
|
||||
$00B6 RODATA RS232 Output Byte Buffer/Tape Read Error Flag.
|
||||
$00B7 FNLEN Number of Characters in Filename.
|
||||
$00B8 LA Current File - Logical File number.
|
||||
$00B9 SA Current File - Secondary Address.
|
||||
$00BA FA Current File - First Address (Device number).
|
||||
OPEN LA,FA,SA; OPEN 1,8,15,"I0":CLOSE 1
|
||||
$00BB-$00BC FNADR Pointer: Current File name Address.
|
||||
$00BD ROPRTY RS232 Output Parity/Tape Byte to be Input or
|
||||
Output.
|
||||
$00BE FSBLK Tape Input/Output Block count.
|
||||
$00BF MYCH Serial Word Buffer.
|
||||
$00C0 CAS1 Tape Motor Switch.
|
||||
$00C1-$00C2 STAL Start Address for LOAD and Cassette Write.
|
||||
$00C3-$00C4 MEMUSS Pointer: Type 3 Tape LOAD and general use.
|
||||
$00C5 LSTX Matrix value of last Key pressed; No Key = $40.
|
||||
$00C6 NDX Number of Characters in Keyboard Buffer
|
||||
queue.
|
||||
$00C7 RVS Flag: Reverse On/Off; On = $01, Off = $00.
|
||||
$00C8 INDX Pointer: End of Line for Input (Used to
|
||||
suppress trailing spaces).
|
||||
$00C9-$00CA Cursor X/Y (Line/Column) position at start of
|
||||
Input.
|
||||
$00CB SFDX Flag: Print shifted Characters.
|
||||
$00CC BLNSW Flag: Cursor blink; $00 = Enabled, $01 =
|
||||
Disabled.
|
||||
$00CD BLNCT Timer: Count down for Cursor blink toggle.
|
||||
$00CE GDBLN Character under Cursor while Cursor Inverted.
|
||||
$00CF BLNON Flag: Cursor Status; $00 = Off, $01 = On.
|
||||
$00D0 CRSW Flag: Input from Screen = $03, or Keyboard =
|
||||
$00.
|
||||
$00D1-$00D2 PNT Pointer: Current Screen Line Address.
|
||||
$00D3 PNTR Cursor Column on current Line, including
|
||||
Wrap-round Line, if any.
|
||||
$00D4 QTSW Flag: Editor in Quote Mode; $00 = Not.
|
||||
$00D5 LNMX Current logical Line length: 39 or 79.
|
||||
$00D6 TBLX Current Screen Line number of Cursor.
|
||||
$00D7 DATA Screen value of current Input Character/Last
|
||||
Character Output.
|
||||
$00D8 INSRT Count of number of inserts outstanding.
|
||||
$00D9-$00F2 LDTB1 Screen Line link Table/Editor temporaries.
|
||||
High Byte of Line Screen Memory Location.
|
||||
$00F3-$00F4 USER Pointer: Current Colour RAM Location.
|
||||
$00F5-$00F6 KEYTAB Vector: Current Keyboard decoding Table.
|
||||
($EB81)
|
||||
$00F7-$00F8 RIBUF RS232 Input Buffer Pointer.
|
||||
$00F9-$00FA ROBUF RS232 Output Buffer Pointer.
|
||||
$00FB-$00FE FREKZP Free Zero Page space for User Programs.
|
||||
$00FF-$010A Assembly Area for Floating point to ASCII
|
||||
conversion.
|
||||
$0100-$01FF 6510 Hardware Stack Area.
|
||||
$0100-$013E BAD Tape Input Error log.
|
||||
$013F-$01FF BASIC Stack Area.
|
||||
$0200-$0258 BUF BASIC Input Buffer (Input Line from Screen).
|
||||
$0259-$0262 LAT Kernal Table: Active logical File numbers.
|
||||
$0263-$026C FAT Kernal Table: Active File First Addresses
|
||||
(Device numbers).
|
||||
$026D-$0276 SAT Kernal Table: Active File Secondary
|
||||
Addresses.
|
||||
$0277-$0280 KEYD Keyboard Buffer Queue (FIFO).
|
||||
$0281-$0282 MEMSTR Pointer: Bottom of Memory for Operating
|
||||
System ($0800).
|
||||
$0283-$0284 MEMSIZ Pointer: Top of Memory for Operating
|
||||
System ($A000).
|
||||
$0285 TIMOUT Serial IEEE Bus timeout defeat Flag.
|
||||
$0286 COLOR Current Character Colour code.
|
||||
$0287 GDCOL Background Colour under Cursor.
|
||||
$0288 HIBASE High Byte of Screen Memory Address ($04).
|
||||
$0289 XMAX Maximum number of Bytes in Keyboard
|
||||
Buffer ($0A).
|
||||
$028A RPTFLG Flag: Repeat keys; $00 = Cursors, INST/DEL &
|
||||
Space repeat, $40 no Keys repeat, $80 all
|
||||
Keys repeat ($00).
|
||||
$028B KOUNT Repeat Key: Speed Counter ($04).
|
||||
$028C DELAY Repeat Key: First repeat delay Counter ($10).
|
||||
$028D SHFLAG Flag: Shift Keys: Bit 1 = Shift, Bit 2 = CBM,
|
||||
Bit 3 = CTRL; ($00 = None, $01 = Shift, etc.).
|
||||
$028E LSTSHF Last Shift Key used for debouncing.
|
||||
$028F-$0290 KEYLOG Vector: Routine to determine Keyboard table
|
||||
to use based on Shift Key Pattern ($EB48).
|
||||
$0291 MODE Flag: Upper/Lower Case change: $00 = Disabled,
|
||||
$80 = Enabled ($00).
|
||||
$0292 AUTODN Flag: Auto scroll down: $00 = Disabled ($00).
|
||||
$0293 M51CTR RS232 Pseudo 6551 control Register Image.
|
||||
$0294 M51CDR RS232 Pseudo 6551 command Register Image.
|
||||
$0295-$0296 M51AJB RS232 Non-standard Bits/Second.
|
||||
$0297 RSSTAT RS232 Pseudo 6551 Status Register Image.
|
||||
$0298 BITNUM RS232 Number of Bits left to send.
|
||||
$0299-$029A BAUDOF RS232 Baud Rate; Full Bit time microseconds.
|
||||
$029B RIDBE RS232 Index to End of Input Buffer.
|
||||
$029C RIDBS RS232 Pointer: High Byte of Address of Input
|
||||
Buffer.
|
||||
$029D RODBS RS232 Pointer: High Byte of Address of Output
|
||||
Buffer.
|
||||
$029E RODBE RS232 Index to End of Output Buffer.
|
||||
$029F-$02A0 IRQTMP Temporary store for IRQ Vector during Tape
|
||||
operations.
|
||||
$02A1 ENABL RS232 Enables.
|
||||
$02A2 CASTON TOD sense during Tape I/O.
|
||||
$02A3 KIKA26 Temporary storage during Tape READ.
|
||||
$02A4 STUPID Temporary D1IRQ Indicator during Tape READ.
|
||||
$02A5 LINTMP Temporary for Line Index.
|
||||
$02A6 PALNTS Flag: TV Standard: $00 = NTSC, $01 = PAL.
|
||||
$02A7-$02FF Unused.
|
||||
$0300-$0301 IERROR Vector: Indirect entry to BASIC Error
|
||||
Message, (X) points to Message ($E38B).
|
||||
$0302-$0303 IMAIN Vector: Indirect entry to BASIC Input Line
|
||||
and Decode ($A483).
|
||||
$0304-$0305 ICRNCH Vector: Indirect entry to BASIC Tokenise
|
||||
Routine ($A57C).
|
||||
$0306-$0307 IQPLOP Vector: Indirect entry to BASIC LIST
|
||||
Routine ($A71A).
|
||||
$0308-$0309 IGONE Vector: Indirect entry to BASIC Character
|
||||
dispatch Routine ($A7E4).
|
||||
$030A-$030B IEVAL Vector: Indirect entry to BASIC Token
|
||||
evaluation ($AE86).
|
||||
$030C SAREG Storage for 6510 Accumulator during SYS.
|
||||
$030D SXREG Storage for 6510 X-Register during SYS.
|
||||
$030E SYREG Storage for 6510 Y-Register during SYS.
|
||||
$030F SPREG Storage for 6510 Status Register during SYS.
|
||||
$0310 USR Function JMP Instruction ($4C).
|
||||
$0311-$0312 USRADD USR Address ($LB,$MB).
|
||||
$0313 Unused.
|
||||
$0314-$0315 CINV Vector: Hardware IRQ Interrupt Address ($EA31).
|
||||
$0316-$0317 CBINV Vector: BRK Instruction Interrupt Address
|
||||
($FE66).
|
||||
$0318-$0319 NMINV Vector: Hardware NMI Interrupt Address ($FE47).
|
||||
$031A-$031B IOPEN Vector: Indirect entry to Kernal OPEN
|
||||
Routine ($F34A).
|
||||
$031C-$031D ICLOSE Vector: Indirect entry to Kernal CLOSE
|
||||
Routine ($F291).
|
||||
$031E-$031F ICHKIN Vector: Indirect entry to Kernal CHKIN
|
||||
Routine ($F20E).
|
||||
$0320-$0321 ICKOUT Vector: Indirect entry to Kernal CHKOUT
|
||||
Routine ($F250).
|
||||
$0322-$0323 ICLRCH Vector: Indirect entry to Kernal CLRCHN
|
||||
Routine ($F333).
|
||||
$0324-$0325 IBASIN Vector: Indirect entry to Kernal CHRIN
|
||||
Routine ($F157).
|
||||
$0326-$0327 IBSOUT Vector: Indirect entry to Kernal CHROUT
|
||||
Routine ($F1CA).
|
||||
$0328-$0329 ISTOP Vector: Indirect entry to Kernal STOP
|
||||
Routine ($F6ED).
|
||||
$032A-$032B IGETIN Vector: Indirect entry to Kernal GETIN
|
||||
Routine ($F13E).
|
||||
$032C-$032D ICLALL Vector: Indirect entry to Kernal CLALL
|
||||
Routine ($F32F).
|
||||
$032E-$032F USRCMD User Defined Vector ($FE66).
|
||||
$0330-$0331 ILOAD Vector: Indirect entry to Kernal LOAD
|
||||
Routine ($F4A5).
|
||||
$0332-$0333 ISAVE Vector: Indirect entry to Kernal SAVE
|
||||
Routine ($F5ED).
|
||||
$0334-$033B Unused.
|
||||
$033C-$03FB TBUFFR Tape I/O Buffer.
|
||||
$03FC-$03FF Unused.
|
||||
|
|
@ -1,221 +0,0 @@
|
|||
- C64 RAM Map (Jim Butterfield)
|
||||
-
|
||||
- Butterfield, Jim [compiled by]:
|
||||
- COMMODORE 64 MEMORY MAP
|
||||
- Classic Computer Magazine Archive COMPUTE! issue 29, October 1982, p.150
|
||||
-
|
||||
- https://www.atarimagazines.com/compute/issue29/394_1_COMMODORE_64_MEMORY_MAP.php
|
||||
- https://www.atariarchives.org/mlb/appendix_b.php
|
||||
- https://archive.org/details/1982-10-compute-magazine/page/n153/mode/2up
|
||||
-
|
||||
- Corrections (typos as well as content), translations etc.
|
||||
- welcome at: https://github.com/mist64/c64disasm
|
||||
-
|
||||
------------------------------------------------------------
|
||||
-
|
||||
# This plain text file is formatted so that it can be automatically
|
||||
# parsed in order to create cross-references etc.
|
||||
# * Lines starting with "-" is top-level information. The first line
|
||||
# is the title. Lines starting with "--" are separators.
|
||||
# * Lines starting with "#" are internal comments.
|
||||
# * Hex addresses start at column 0.
|
||||
# * Symbols start at column 13.
|
||||
# * The description starts at column 21.
|
||||
# * All lines of the description until the first blank line are
|
||||
# combined into the heading.
|
||||
# * A '.' character at the end of a heading line represents a hard
|
||||
# line break.
|
||||
# * The remaining text is in MarkDown format.
|
||||
# * All addresses are 4 digits and have a leading '$'.
|
||||
# The encoding is UTF-8.
|
||||
|
||||
$0000 D6510 Chip directional register
|
||||
$0001 R6510 Chip I/O; memory & tape control
|
||||
$0003-$0004 ADRAY1 Float-Fixed vector
|
||||
$0005-$0006 ADRAY2 Fixed-Float vector
|
||||
$0007 CHARAC Search character
|
||||
$0008 ENDCHR Scan-quotes flag
|
||||
$0009 TRMPOS TAB column save
|
||||
$000A VERCK 0 = LOAD, 1 = VERIFY
|
||||
$000B COUNT Input buffer pointer/# subscrpt
|
||||
$000C DIMFLG Default DIM flag
|
||||
$000D VALTYP Type : FF = string, 00 = numeric
|
||||
$000E INTFLG Type : 80 = integer, 00 = floating point
|
||||
$000F GARBFL DATA scan/LIST quote/memry flag
|
||||
$0010 SUBFLG Subscript/FNx flag
|
||||
$0011 INPFLG 0 = INPUT; $40 = GET; $98 = READ
|
||||
$0012 TANSGN ATN sign/Comparison eval flag
|
||||
$0013 CHANNL Current I/O prompt flag
|
||||
$0014-$0015 LINNUM Integer value
|
||||
$0016 TEMPPT Pointer : temporary strg stack
|
||||
$0017-$0018 LASTPT Last temp string vector
|
||||
$0019-$0021 TEMPST Stack for temporary strings
|
||||
$0022-$0025 INDEX Utility pointer area
|
||||
$0026-$002A RES Product area for multiplication
|
||||
$002B-$002C TXTTAB Pointer : Start-of-Basic
|
||||
$002D-$002E VARTAB Pointer : Start-of-Variables
|
||||
$002F-$0030 ARYTAB Pointer : Start-of-Arrays
|
||||
$0031-$0032 STREND Pointer : End-of-Arrays
|
||||
$0033-$0034 FRETOP Pointer : String-storage(moving down)
|
||||
$0035-$0036 FRESPC Utility string pointer
|
||||
$0037-$0038 MEMSIZ Pointer : Limit-of-memory
|
||||
$0039-$003A CURLIN Current Basic line number
|
||||
$003B-$003C OLDLIN Previous Basic line number
|
||||
$003D-$003E OLDTXT Pointer : Basic statement for CONT
|
||||
$003F-$0040 DATLIN Current DATA line number
|
||||
$0041-$0042 DATPTR Current DATA address
|
||||
$0043-$0044 INPPTR Input vector
|
||||
$0045-$0046 VARNAM Current variable name
|
||||
$0047-$0048 VARPNT Current variable address
|
||||
$0049-$004A FORPNT Variable pointer for FOR/NEXT
|
||||
$004B-$004C VARTXT Y-save; op-save; Basic pointer save
|
||||
$004D OPMASK Comparison symbol accumulator
|
||||
$004E-$0053 Misc work area, pointer, etc
|
||||
$0054-$0056 JMPER Jump vector for functions
|
||||
$0057-$0060 Misc numeric work area
|
||||
$0061 FACEXP Accum#l : Exponent
|
||||
$0062-$0065 FACHO Accum#l : Mantissa
|
||||
$0066 FACSGN Accum#l : Sign
|
||||
$0067 SGNFLG Series evaluation constant pointer
|
||||
$0068 BITS Accum#l hi-order (over flow)
|
||||
$0069-$006E ARG Accum#2 : Exponent, etc.
|
||||
$006F ARISGN Sign comparison, Acc#l vs #2
|
||||
$0070 FACOV Accum#l lo-order (rounding)
|
||||
$0071-$0072 FBUFPT Cassette buff len/Series pointer
|
||||
$0073-$008A CHRGET CHRGET subroutine; get Basic char
|
||||
$007A-$007B TXTPTR Basic pointer (within subrtn)
|
||||
$008B-$008F RNDX RND seed value
|
||||
$0090 STATUS Status word ST
|
||||
$0091 STKEY Keyswitch PIA : STOP and RVS flags
|
||||
$0092 SVXT Timing constant for tape
|
||||
$0093 VERCK Load = 0, Verify = l
|
||||
$0094 C3P0 Serial output : deferred char flag
|
||||
$0095 BSOUR Serial deferred character
|
||||
$0096 SYNO Tape EOT received
|
||||
$0097 XSAV Register save
|
||||
$0098 LDTND How many open files
|
||||
$0099 DFLTN Input device, normally 0
|
||||
$009A DFLTO Output CMD device, normally 3
|
||||
$009B PRTY Tape character parity
|
||||
$009C DPSW Byte-received flag
|
||||
$009D MSGFLG Direct = $80/RUN = 0 output control
|
||||
$009E PTR1 Tp Pass 1 error log/char buffer
|
||||
$009F PTR2 Tp Pass 2 err log corrected
|
||||
$00A0-$00A2 TIME Jiffy Clock HML
|
||||
$00A3 R2D2 Serial bit count/EOI flag
|
||||
$00A4 FIRT Cycle count
|
||||
$00A5 CNTDN Countdown, tape write/bit count
|
||||
$00A6 BUFPT Tape buffer pointer
|
||||
$00A7 INBIT Tp Wrt ldr count/Rd pass/inbit
|
||||
$00A8 BITCI Tp Wrt new byte/Rd error/inbit cnt
|
||||
$00A9 RINONE Wrt start bit/Rd bit err/stbit
|
||||
$00AA RIDATA Tp Scan; Cnt; Ld; End/byte assy
|
||||
$00AB RIPRTY Wr lead length/Rd checksum/parity
|
||||
$00AC-$00AD Pointer : tape bufr, scrolling
|
||||
$00AE-$00AF Tape end adds/End of program
|
||||
$00B0-$00B1 Tape timing constants
|
||||
$00B2-$00B3 TAPE1 Pntr : start of tape buffer
|
||||
$00B4 BITTS l = Tp timer enabled; bit count
|
||||
$00B5 NXTBIT Tp EOT/RS232 next bit to send
|
||||
$00B6 RODATA Read character error/outbyte buf
|
||||
$00B7 FNLEN # characters in file name
|
||||
$00B8 LA Current logical file
|
||||
$00B9 SA Current secndy address
|
||||
$00BA FA Current device
|
||||
$00BB-$00BC FNADR Pointer to file name
|
||||
$00BD ROPRTY Wr shift word/Rd input char
|
||||
$00BE FSBLK # blocks remaining to Wr/Rd
|
||||
$00BF MYCH Serial word buffer
|
||||
$00C0 CAS1 Tape motor interlock
|
||||
$00C1-$00C2 STAL I/O start address
|
||||
$00C3-$00C4 MEMUSS Kernel setup pointer
|
||||
$00C5 LSTX Last key pressed
|
||||
$00C6 NDX # chars in keybd buffer
|
||||
$00C7 RVS Screen reverse flag
|
||||
$00C8 INDX End-of-line for input pointer
|
||||
$00C9-$00CA Input cursor log (row, column)
|
||||
$00CB SFDX Which key : 64 if no key
|
||||
$00CC BLNSW 0 = flash cursor
|
||||
$00CD BLNCT Cursor timing countdown
|
||||
$00CE GDBLN Character under cursor
|
||||
$00CF BLNON Cursor in blink phase
|
||||
$00D0 CRSW Input from screen/from keyboard
|
||||
$00D1-$00D2 PNT Pointer to screen line
|
||||
$00D3 PNTR Position of cursor on above line
|
||||
$00D4 QTSW 0 = direct cursor, else programmed
|
||||
$00D5 LNMX Current screen line length
|
||||
$00D6 TBLX Row where curosr lives
|
||||
$00D7 DATA Last inkey/checksum/buffer
|
||||
$00D8 INSRT # of INSERTs outstanding
|
||||
$00D9-$00F2 LDTB1 Screen line link table
|
||||
$00F3-$00F4 USER Screen color pointer
|
||||
$00F5-$00F6 KEYTAB Keyboard pointer
|
||||
$00F7-$00F8 RIBUF RS-232 Rev pntr
|
||||
$00F9-$00FA ROBUF RS-232 Tx pntr
|
||||
$00FF-$010A BASZPT Floating to ASCII work area
|
||||
$0100-$01FF Processor stack area
|
||||
$0100-$013E BAD Tape error log
|
||||
$0200-$0258 BUF Basic input buffer
|
||||
$0259-$0262 LAT Logical file table
|
||||
$0263-$026C FAT Device # table
|
||||
$026D-$0276 SAT Sec Adds table
|
||||
$0277-$0280 KEYD Keybd buffer
|
||||
$0281-$0282 MEMSTR Start of Basic Memory
|
||||
$0283-$0284 MEMSIZ Top of Basic Memory
|
||||
$0285 TIMOUT Serial bus timeout flag
|
||||
$0286 COLOR Current color code
|
||||
$0287 GDCOL Color under cursor
|
||||
$0288 HIBASE Screen memory page
|
||||
$0289 XMAX Max size of keybd buffer
|
||||
$028A RPTFLG Repeat all keys
|
||||
$028B KOUNT Repeat speed counter
|
||||
$028C DELAY Repeat delay counter
|
||||
$028D SHFLAG Keyboard Shift/Control flag
|
||||
$028E LSTSHF Last shift pattern
|
||||
$028F-$0290 KEYLOG Keyboard table setup pointer
|
||||
$0291 MODE Keyboard shift mode
|
||||
$0292 AUTODN 0 = scroll enable
|
||||
$0293 M51CTR RS-232 control reg
|
||||
$0294 M51CDR RS-232 command reg
|
||||
$0295-$0296 M51AJB Bit timing
|
||||
$0297 RSSTAT RS-232 status
|
||||
$0298 BITNUM # bits to send
|
||||
$0299-$029A BAUDOF RS-232 speed/code
|
||||
$029B RIDBE RS232 receive pointer
|
||||
$029C RIDBS RS232 input pointer
|
||||
$029D RODBS RS232 transmit pointer
|
||||
$029E RODBE RS232 output pointer
|
||||
$029F-$02A0 IRQTMP IRQ save during tape I/O
|
||||
$02A1 ENABL CIA 2 (NMI) Interrupt Control
|
||||
$02A2 CASTON CIA 1 Timer A control log
|
||||
$02A3 KIKA26 CIA 1 Interrupt Log
|
||||
$02A4 STUPID CIA 1 Timer A enabled flag
|
||||
$02A5 LINTMP Screen row marker
|
||||
$0300-$0301 IERROR Error message link
|
||||
$0302-$0303 IMAIN Basic warm start link
|
||||
$0304-$0305 ICRNCH Crunch Basic tokens link
|
||||
$0306-$0307 IQPLOP Print tokens link
|
||||
$0308-$0309 IGONE Start new Basic code link
|
||||
$030A-$030B IEVAL Get arithmetic element link
|
||||
$030C SAREG SYS A-reg save
|
||||
$030D SXREG SYS X-reg save
|
||||
$030E SYREG SYS Y-reg save
|
||||
$030F SPREG SYS status reg save
|
||||
$0310-$0312 USRPOK USR function jump ($B248)
|
||||
$0314-$0315 CINV Hardware interrupt vector ($EA31)
|
||||
$0316-$0317 CBINV Break interrupt vector ($FE66)
|
||||
$0318-$0319 NMINV NMI interrupt vector ($FE47)
|
||||
$031A-$031B IOPEN OPEN vector ($F34A)
|
||||
$031C-$031D ICLOSE CLOSE vector ($F291)
|
||||
$031E-$031F ICHKIN Set - input vector ($F20E)
|
||||
$0320-$0321 ICKOUT Set - output vector ($F250)
|
||||
$0322-$0323 ICLRCH Restore I/0 vector ($F333)
|
||||
$0324-$0325 IBASIN INPUT vector ($F157)
|
||||
$0326-$0327 IBSOUT Output vector ($F1CA)
|
||||
$0328-$0329 ISTOP Test-STOP vector ($F6ED)
|
||||
$032A-$032B IGETIN GET vector ($F13E)
|
||||
$032C-$032D ICLALL Abort I/o vector ($F32F)
|
||||
$032E-$032F USRCMD Warm start vector ($FE66)
|
||||
$0330-$0331 ILOAD LOAD link ($F4A5)
|
||||
$0332-$0333 ISAVE SAVE link ($F5ED)
|
||||
$033C-$03FB TBUFFR Cassette buffer
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,240 +0,0 @@
|
|||
- C64 RAM Map (Programmer's Reference Guide)
|
||||
-
|
||||
- Commodore 64 Programmer's Reference Guide
|
||||
- Indianapolis: Howard W. Sams & Co., Inc, 1982.
|
||||
- ISBN 0-672-22056-3
|
||||
-
|
||||
- C64PRG10.TXT, June 1996, etext #46
|
||||
- converted to etext by
|
||||
- Ville Muikkula
|
||||
- Jouko Valta
|
||||
-
|
||||
- Corrections (typos as well as content), translations etc.
|
||||
- welcome at: https://github.com/mist64/c64disasm
|
||||
-
|
||||
----------------------------------------------
|
||||
-
|
||||
# This plain text file is formatted so that it can be automatically
|
||||
# parsed in order to create cross-references etc.
|
||||
# * Lines starting with "-" is top-level information. The first line
|
||||
# is the title. Lines starting with "--" are separators.
|
||||
# * Lines starting with "#" are internal comments.
|
||||
# * Hex addresses start at column 0.
|
||||
# * Symbols start at column 13.
|
||||
# * The description starts at column 21.
|
||||
# * All lines of the description until the first blank line are
|
||||
# combined into the heading.
|
||||
# * A '.' character at the end of a heading line represents a hard
|
||||
# line break.
|
||||
# * The remaining text is in MarkDown format.
|
||||
# * All addresses are 4 digits and have a leading '$'.
|
||||
# The encoding is UTF-8.
|
||||
|
||||
$0000 D6510 6510 On-Chip Data-Direction Register
|
||||
$0001 R6510 6510 On-Chip 8-Bit Input/Output Register
|
||||
$0002 Unused
|
||||
$0003-$0004 ADRAY1 Jump Vector: Convert Floating-Integer
|
||||
$0005-$0006 ADRAY2 Jump Vector: Convert Integer--Floating
|
||||
$0007 CHARAC Search Character
|
||||
$0008 ENDCHR Flag: Scan for Quote at End of String
|
||||
$0009 TRMPOS Screen Column From Last TAB
|
||||
$000A VERCK Flag: 0 = Load, 1 = Verify
|
||||
$000B COUNT Input Buffer Pointer / No. of Subscripts
|
||||
$000C DIMFLG Flag: Default Array DiMension
|
||||
$000D VALTYP Data Type: $FF = String, $00 = Numeric
|
||||
$000E INTFLG Data Type: $80 = Integer, $00 = Floating
|
||||
$000F GARBFL Flag: DATA scan/LIST quote/Garbage Coll
|
||||
$0010 SUBFLG Flag: Subscript Ref / User Function Call
|
||||
$0011 INPFLG Flag: $00 = INPUT, $40 = GET, $98 = READ
|
||||
$0012 TANSGN Flag TAN sign / Comparison Result
|
||||
$0013 Flag: INPUT Prompt
|
||||
$0014-$0015 LINNUM Temp: Integer Value
|
||||
$0016 TEMPPT Pointer Temporary String
|
||||
$0017-$0018 LASTPT Last Temp String Address
|
||||
$0019-$0021 TEMPST Stack for Temporary Strings
|
||||
$0022-$0025 INDEX Utility Pointer Area
|
||||
$0022-$0023 INDEX1 First Utility Pointer.
|
||||
$0024-$0025 INDEX2 Second Utility Pointer.
|
||||
$0026-$002A RES Floating-Point Product of Multiply
|
||||
$002B-$002C TXTTAB Pointer: Start of BASIC Text
|
||||
$002D-$002E VARTAB Pointer: Start of BASIC Variables
|
||||
$002F-$0030 ARYTAB Pointer: Start of BASIC Arrays
|
||||
$0031-$0032 STREND Pointer End of BASIC Arrays (+1)
|
||||
$0033-$0034 FRETOP Pointer: Bottom of String Storage
|
||||
$0035-$0036 FRESPC Utility String Pointer
|
||||
$0037-$0038 MEMSIZ Pointer: Highest Address Used by BASIC
|
||||
$0039-$003A CURLIN Current BASIC Line Number
|
||||
$003B-$003C OLDLIN Previous BASIC Line Number
|
||||
$003D-$003E OLDTXT Pointer: BASIC Statement for CONT
|
||||
$003F-$0040 DATLIN Current DATA Line Number
|
||||
$0041-$0042 DATPTR Pointer: Current DATA Item Address
|
||||
$0043-$0044 INPPTR Vector: INPUT Routine
|
||||
$0045-$0046 VARNAM Current BASIC Variable Name
|
||||
$0047-$0048 VARPNT Pointer: Current BASIC Variable Data
|
||||
$0049-$004A FORPNT Pointer: Index Variable for FOR/NEXT
|
||||
$004B-$0060 Temp Pointer / Data Area
|
||||
$004B-$004C VARTXT Temporary storage for TXTPTR during
|
||||
READ, INPUT and GET.
|
||||
$004D OPMASK Mask used during FRMEVL.
|
||||
$004E-$0052 TEMPF3 Temporary storage for FLPT value.
|
||||
$0053 FOUR6 Length of String Variable during Garbage
|
||||
collection.
|
||||
$0054-$0056 JMPER Jump Vector used in Function Evaluation-
|
||||
JMP followed by Address ($4C,$LB,$MB).
|
||||
$0057-$005B TEMPF1 Temporary storage for FLPT value.
|
||||
$005C-$0060 TEMPF2 Temporary storage for FLPT value.
|
||||
$0061 FACEXP Floating-Point Accumulator #1: Exponent
|
||||
$0062-$0065 FACHO Floating Accum. #1: Mantissa
|
||||
$0066 FACSGN Floating Accum. #1: Sign
|
||||
$0067 SGNFLG Pointer: Series Evaluation Constant
|
||||
$0068 BITS Floating Accum. #1: Overflow Digit
|
||||
$0069 ARGEXP Floating-Point Accumulator #2: Exponent
|
||||
$006A-$006D Floating Accum. #2: Mantissa
|
||||
$006E ARGSGN Floating Accum. #2: Sign
|
||||
$006F ARISGN Sign Comparison Result: Accum. # 1 vs #2
|
||||
$0070 FACOV Floating Accum. #1. Low-Order (Rounding)
|
||||
$0071-$0072 FBUFPT Pointer: Cassette Buffer
|
||||
$0073-$008A CHRGET Subroutine: Get Next Byte of BASIC Text
|
||||
$0079 CHRGOT Entry to Get Same Byte of Text Again
|
||||
$007A-$007B TXTPTR Pointer: Current Byte of BASIC Text
|
||||
$008B-$008F RNDX Floating RND Function Seed Value
|
||||
$0090 STATUS Kernal I/O Status Word: ST
|
||||
$0091 STKEY Flag: STOP key / RVS key
|
||||
$0092 SVXT Timing Constant for Tape
|
||||
$0093 VERCK Flag: 0 = Load, 1 = Verify
|
||||
$0094 C3P0 Flag: Serial Bus-Output Char. Buffered
|
||||
$0095 BSOUR Buffered Character for Serial Bus
|
||||
$0096 SYNO Cassette Sync No.
|
||||
$0097 Temp Data Area
|
||||
$0098 LDTND No. of Open Files / Index to File Table
|
||||
$0099 DFLTN Default Input Device (0)
|
||||
$009A DFLTO Default Output (CMD) Device (3)
|
||||
$009B PRTY Tape Character Parity
|
||||
$009C DPSW Flag: Tape Byte-Received
|
||||
$009D MSGFLG Flag: $80 = Direct Mode, $00 = Program
|
||||
$009E PTR1 Tape Pass 1 Error Log
|
||||
$009F PTR2 Tape Pass 2 Error Log
|
||||
$00A0-$00A2 TIME Real-Time Jiffy Clock (approx) 1/60 Sec
|
||||
$00A3-$00A4 Temp Data Area
|
||||
$00A5 CNTDN Cassette Sync Countdown
|
||||
$00A6 BUFPT Pointer: Tape I/O Buffer
|
||||
$00A7 INBIT RS-232 Input Bits / Cassette Temp
|
||||
$00A8 BITCI RS-232 Input Bit Count / Cassette Temp
|
||||
$00A9 RINONE RS-232 Flag: Check for Start Bit
|
||||
$00AA RIDATA RS-232 Input Byte Buffer/Cassette Temp
|
||||
$00AB RIPRTY RS-232 Input Parity / Cassette Short Cnt
|
||||
$00AC-$00AD Pointer: Tape Buffer/ Screen Scrolling
|
||||
$00AE-$00AF Tape End Addresses/End of Program
|
||||
$00B0-$00B1 Tape Timing Constants
|
||||
$00B2-$00B3 TAPE1 Pointer: Start of Tape Buffer
|
||||
$00B4 BITTS RS-232 Out Bit Count / Cassette Temp
|
||||
$00B5 NXTBIT RS-232 Next Bit to Send/ Tape EOT Flag
|
||||
$00B6 RODATA RS-232 Out Byte Buffer
|
||||
$00B7 FNLEN Length of Current File Name
|
||||
$00B8 LA Current Logical File Number
|
||||
$00B9 SA Current Secondary Address
|
||||
$00BA FA Current Device Number
|
||||
$00BB-$00BC FNADR Pointer: Current File Name
|
||||
$00BD ROPRTY RS-232 Out Parity / Cassette Temp
|
||||
$00BE FSBLK Cassette Read / Write Block Count
|
||||
$00BF MYCH Serial Word Buffer
|
||||
$00C0 CAS1 Tape Motor Interlock
|
||||
$00C1-$00C2 STAL I/O Start Address
|
||||
$00C3-$00C4 MEMUSS Tape Load Temps
|
||||
$00C5 LSTX Current Key Pressed: CHR$(n) 0 = No Key
|
||||
$00C6 NDX No. of Chars. in Keyboard Buffer (Queue)
|
||||
$00C7 RVS Flag: Reverse Chars. - 1=Yes, 0=No Used
|
||||
$00C8 INDX Pointer: End of Logical Line for INPUT
|
||||
$00C9-$00CA Cursor X-Y Pos. at Start of INPUT
|
||||
$00CB SFDX Flag: Print Shifted Chars.
|
||||
$00CC BLNSW Cursor Blink enable: 0 = Flash Cursor
|
||||
$00CD BLNCT Timer: Countdown to Toggle Cursor
|
||||
$00CE GDBLN Character Under Cursor
|
||||
$00CF BLNON Flag: Last Cursor Blink On/Off
|
||||
$00D0 CRSW Flag: INPUT or GET from Keyboard
|
||||
$00D1-$00D2 PNT Pointer: Current Screen Line Address
|
||||
$00D3 PNTR Cursor Column on Current Line
|
||||
$00D4 QTSW Flag: Editor in Quote Mode, $00 = NO
|
||||
$00D5 LNMX Physical Screen Line Length
|
||||
$00D6 TBLX Current Cursor Physical Line Number
|
||||
$00D7 Temp Data Area
|
||||
$00D8 INSRT Flag: Insert Mode, >0 = # INSTs
|
||||
$00D9-$00F2 LDTB1 Screen Line Link Table / Editor Temps
|
||||
$00F3-$00F4 USER Pointer: Current Screen Color RAM loc.
|
||||
$00F5-$00F6 KEYTAB Vector Keyboard Decode Table
|
||||
$00F7-$00F8 RIBUF RS-232 Input Buffer Pointer
|
||||
$00F9-$00FA ROBUF RS-232 Output Buffer Pointer
|
||||
$00FB-$00FE FREKZP Free 0-Page Space for User Programs
|
||||
$00FF-$010A BASZPT Floating to String Work Area
|
||||
$0100-$01FF Micro-Processor System Stack Area
|
||||
$0100-$013E BAD Tape Input Error Log
|
||||
$0200-$0258 BUF System INPUT Buffer
|
||||
$0259-$0262 LAT KERNAL Table: Active Logical File No's.
|
||||
$0263-$026C FAT KERNAL Table: Device No. for Each File
|
||||
$026D-$0276 SAT KERNAL Table: Second Address Each File
|
||||
$0277-$0280 KEYD Keyboard Buffer Queue (FIFO)
|
||||
$0281-$0282 MEMSTR Pointer: Bottom of Memory for O.S.
|
||||
$0283-$0284 MEMSIZ Pointer: Top of Memory for O.S.
|
||||
$0285 TIMOUT Flag: Kernal Variable for IEEE Timeout
|
||||
$0286 COLOR Current Character Color Code
|
||||
$0287 GDCOL Background Color Under Cursor
|
||||
$0288 HIBASE Top of Screen Memory (Page)
|
||||
$0289 XMAX Size of Keyboard Buffer
|
||||
$028A RPTFLG Flag: REPEAT Key Used, $80 = Repeat
|
||||
$028B KOUNT Repeat Speed Counter
|
||||
$028C DELAY Repeat Delay Counter
|
||||
$028D SHFLAG Flag: Keyboard SHIFT Key/CTRL Key/C= Key
|
||||
$028E LSTSHF Last Keyboard Shift Pattern
|
||||
$028F-$0290 KEYLOG Vector: Keyboard Table Setup
|
||||
$0291 MODE Flag: $00=Disable SHIFT Keys, $80=Enable
|
||||
$0292 AUTODN Flag: Auto Scroll Down, 0 = ON
|
||||
$0293 M51CTR RS-232: 6551 Control Register Image
|
||||
$0294 M51CDR RS-232: 6551 Command Register Image
|
||||
$0295-$0296 M51AJB RS-232 Non-Standard BPS (Time/2-100) USA
|
||||
$0297 RSSTAT RS-232: 6551 Status Register Image
|
||||
$0298 BITNUM RS-232 Number of Bits Left to Send
|
||||
$0299-$029A BAUDOF RS-232 Baud Rate: Full Bit Time (us)
|
||||
$029B RIDBE RS-232 Index to End of Input Buffer
|
||||
$029C RIDBS RS-232 Start of Input Buffer (Page)
|
||||
$029D RODBS RS-232 Start of Output Buffer (Page)
|
||||
$029E RODBE RS-232 Index to End of Output Buffer
|
||||
$029F-$02A0 IRQTMP Holds IRQ Vector During Tape I/O
|
||||
$02A1 ENABL RS-232 Enables
|
||||
$02A2 TOD Sense During Cassette I/O
|
||||
$02A3 Temp Storage For Cassette Read
|
||||
$02A4 Temp D1 IRQ Indicator For Cassette Read
|
||||
$02A5 Temp For Line Index
|
||||
$02A6 PAL/NTSC Flag, 0= NTSC, 1 = PAL
|
||||
$02A7-$02FF Unused
|
||||
$0300-$0301 IERROR Vector: Print BASIC Error Message
|
||||
$0302-$0303 IMAIN Vector: BASIC Warm Start
|
||||
$0304-$0305 ICRNCH Vector: Tokenize BASIC Text
|
||||
$0306-$0307 IQPLOP Vector: BASIC Text LIST
|
||||
$0308-$0309 IGONE Vector: BASIC Char. Dispatch
|
||||
$030A-$030B IEVAL Vector: BASIC Token Evaluation
|
||||
$030C SAREG Storage for 6502 .A Register
|
||||
$030D SXREG Storage for 5502 .X Register
|
||||
$030E SYREG Storage for 6502 .Y Register
|
||||
$030F SPREG Storage for 6502 .SP Register
|
||||
$0310 USR Function Jump Instr (4C)
|
||||
$0311-$0312 USRADD USR Address Low Byte / High Byte
|
||||
$0313 Unused
|
||||
$0314-$0315 CINV Vector: Hardware Interrupt
|
||||
$0316-$0317 CBINV Vector: BRK Instr. Interrupt
|
||||
$0318-$0319 NMINV Vector: Non-Maskable Interrupt
|
||||
$031A-$031B IOPEN KERNAL OPEN Routine Vector
|
||||
$031C-$031D ICLOSE KERNAL CLOSE Routine Vector
|
||||
$031E-$031F ICHKIN KERNAL CHKIN Routine
|
||||
$0320-$0321 ICKOUT KERNAL CHKOUT Routine
|
||||
$0322-$0323 ICLRCH KERNAL CLRCHN Routine Vector
|
||||
$0324-$0325 IBASIN KERNAL CHRIN Routine
|
||||
$0326-$0327 IBSOUT KERNAL CHROUT Routine
|
||||
$0328-$0329 ISTOP KERNAL STOP Routine Vector
|
||||
$032A-$032B IGETIN KERNAL GETIN Routine
|
||||
$032C-$032D ICLALL KERNAL CLALL Routine Vector
|
||||
$032E-$032F USRCMD User-Defined Vector
|
||||
$0330-$0331 ILOAD KERNAL LOAD Routine
|
||||
$0332-$0333 ISAVE KERNAL SAVE Routine Vector
|
||||
$0334-$033B Unused
|
||||
$033C-$03FB TBUFFR Tape I/O Buffer
|
||||
$03FC-$03FF Unused
|
||||
|
|
@ -1,668 +0,0 @@
|
|||
- C64 RAM Map (Microsoft/Commodore)
|
||||
-
|
||||
- The labels and descriptions have been taken from
|
||||
- Microsoft's original BASIC for M6502 source
|
||||
- and
|
||||
- The original C64 KERNAL source by Commodore (901227-03)
|
||||
- https://github.com/mist64/cbmsrc
|
||||
-
|
||||
- Converted and formatted by Michael Steil <mist64@mac.com>
|
||||
-
|
||||
- Corrections (typos as well as content), translations etc.
|
||||
- welcome at: https://github.com/mist64/c64disasm
|
||||
-
|
||||
------------------------------------------------------------
|
||||
-
|
||||
# This plain text file is formatted so that it can be automatically
|
||||
# parsed in order to create cross-references etc.
|
||||
# * Lines starting with "-" is top-level information. The first line
|
||||
# is the title. Lines starting with "--" are separators.
|
||||
# * Lines starting with "#" are internal comments.
|
||||
# * Hex addresses start at column 0.
|
||||
# * Symbols start at column 13.
|
||||
# * The description starts at column 21.
|
||||
# * All lines of the description until the first blank line are
|
||||
# combined into the heading.
|
||||
# * A '.' character at the end of a heading line represents a hard
|
||||
# line break.
|
||||
# * The remaining text is in MarkDown format.
|
||||
# * All addresses are 4 digits and have a leading '$'.
|
||||
# The encoding is UTF-8.
|
||||
|
||||
#
|
||||
# KERNAL
|
||||
#
|
||||
|
||||
$0000 D6510 6510 data direction register
|
||||
$0001 R6510 6510 data register
|
||||
|
||||
#
|
||||
# BASIC
|
||||
#
|
||||
|
||||
$0003-$0004 ADRAY1 Store here the addr of the
|
||||
routine to turn the FAC into a
|
||||
two byte signed integer in [Y,A]
|
||||
|
||||
$0005-$0006 ADRAY2 Store here the addr of the
|
||||
routine to convert [Y,A] to a floating
|
||||
point number in the FAC.
|
||||
|
||||
$0007 CHARAC A delimiting character.
|
||||
|
||||
$0007 INTEGR A one-byte integer from "QINT".
|
||||
|
||||
$0008 ENDCHR The other delimiting character.
|
||||
|
||||
$0009 TRMPOS Position of terminal carriage.
|
||||
|
||||
$000B COUNT A general counter.
|
||||
|
||||
$000C DIMFLG
|
||||
|
||||
In getting a pointer to a variable
|
||||
it is important to remember whether it
|
||||
is being done for "dim" or not.
|
||||
|
||||
DIMFLG and VALTYP must be
|
||||
consecutive locations.
|
||||
|
||||
$000D VALTYP The type indicator.
|
||||
|
||||
0=numeric 1=string.
|
||||
|
||||
$000E INTFLG Tells if integer.
|
||||
|
||||
$000F GARBFL Whether to do garbage collection.
|
||||
|
||||
$000F DORES Whether can or can't crunch res'd words.
|
||||
|
||||
Turned on when "data"
|
||||
being scanned by crunch so unquoted
|
||||
strings won't be crunched.
|
||||
|
||||
$0010 SUBFLG Flag whether sub'd variable allowed.
|
||||
|
||||
"FOR" and user-defined function
|
||||
pointer fetching turn
|
||||
this on before calling "PTRGET"
|
||||
so arrays won't be detected.
|
||||
"STKINI" and "PTRGET" clear it.
|
||||
Also disallows integers there.
|
||||
|
||||
$0011 INPFLG Flags whether we are doing "INPUT"
|
||||
or "READ".
|
||||
|
||||
$0012 TANSGN Used in determining sign of tangent.
|
||||
|
||||
$0012 DOMASK Mask in use by relation operations.
|
||||
|
||||
$0013 CHANNL Holds channel number.
|
||||
|
||||
$0014-$0015 LINNUM Location to store line number before BUF
|
||||
so that "BLTUC" can store it all away at once.
|
||||
|
||||
A comma (preload or from ROM)
|
||||
used by input statement since the
|
||||
data pointer always starts on a
|
||||
comma or terminator.
|
||||
|
||||
$0014-$0015 POKER Set up location used by POKE.
|
||||
|
||||
Temporary for input and read code
|
||||
|
||||
$0016 TEMPPT Pointer at first free temp descriptor.
|
||||
|
||||
Initialized to point to TEMPST.
|
||||
|
||||
$0017-$0018 LASTPT Pointer to last-used string temporary.
|
||||
|
||||
$0019-$0021 TEMPST Storage for NUMTMP temp descriptors.
|
||||
|
||||
$0022-$0025 INDEX Indexes.
|
||||
|
||||
$0022-$0023 INDEX1
|
||||
|
||||
$0024-$0025 INDEX2
|
||||
|
||||
$0026 RESHO Result of multiplier and divider.
|
||||
|
||||
$0027 RESMOH One more byte.
|
||||
|
||||
$0028 RESMO
|
||||
|
||||
$0028 ADDEND Temporary used by "UMULT".
|
||||
|
||||
$0029 RESLO
|
||||
|
||||
$002B-$002C TXTTAB Pointer to beginning of text.
|
||||
|
||||
Doesn't change after being
|
||||
setup by "INIT".
|
||||
|
||||
$002D-$002E VARTAB Pointer to start of simple
|
||||
variable space.
|
||||
|
||||
Updated whenever the size of the
|
||||
program changes, set to [TXTTAB]
|
||||
by "SCRATCH" ("NEW").
|
||||
|
||||
$002F-$0030 ARYTAB Pointer to beginning of array
|
||||
table.
|
||||
|
||||
Incremented by 6 whenever
|
||||
a new simple variable is found, and
|
||||
set to [VARTAB] by "CLEARC".
|
||||
|
||||
$0031-$0032 STREND End of storage in use.
|
||||
|
||||
Increased whenever a new array
|
||||
or simple variable is encountered.
|
||||
set to [VARTAB] by "CLEARC".
|
||||
|
||||
$0033-$0034 FRETOP Top of string free space.
|
||||
|
||||
$0035-$0036 FRESPC Pointer to new string.
|
||||
|
||||
$0037-$0038 MEMSIZ Highest location in memory.
|
||||
|
||||
$0039-$003A CURLIN Current line #.
|
||||
|
||||
Set to 0,255 for direct statements.
|
||||
|
||||
$003B-$003C OLDLIN Old line number
|
||||
|
||||
Set up by ^C,"STOP"
|
||||
or "END" in a program.
|
||||
|
||||
$003D-$003E OLDTXT Old text pointer.
|
||||
|
||||
Points at statement to be exec'd next.
|
||||
|
||||
$003F-$0040 DATLIN Data line # -- remember for errors.
|
||||
|
||||
$0041-$0042 DATPTR Pointer to data.
|
||||
|
||||
Initialized to point
|
||||
at the zero in front of [TXTTAB]
|
||||
by "RESTORE" which is called by "CLEARC".
|
||||
updated by execution of a "READ".
|
||||
|
||||
$0043-$0044 INPPTR This remembers where input is coming from.
|
||||
|
||||
$0045-$0046 VARNAM Variable's name is stored here.
|
||||
|
||||
$0047-$0048 VARPNT Pointer to variable in memory.
|
||||
|
||||
$0047 FDECPT Pointer into power of tens of "FOUT".
|
||||
|
||||
$0049-$004A FORPNT A variable's pointer for "FOR" loops
|
||||
and "LET" statements.
|
||||
|
||||
$0049 LSTPNT Pntr to list string.
|
||||
|
||||
$0049 ANDMSK The mask used by WAIT for ANDing.
|
||||
|
||||
$004A EORMSK The mask for EORing in wait.
|
||||
|
||||
$004B-$004C OPPTR Pointer to current op's entry in "OPTAB".
|
||||
|
||||
$004B VARTXT Pointer into list of variables.
|
||||
|
||||
$004D OPMASK Mask created by current operator.
|
||||
|
||||
$004E-$0052 TEMPF3 A third FAC temporary (4 bytes).
|
||||
|
||||
$004E-$004F DEFPNT Pointer used in function definition.
|
||||
|
||||
$004E GRBPNT Another used in garbage collection.
|
||||
|
||||
$0050-$0052 DSCPNT Pointer to a string descriptor.
|
||||
|
||||
$0053 FOUR6 Variable constant used by garb collect.
|
||||
|
||||
$0054-$0056 JMPER
|
||||
|
||||
$0055 SIZE
|
||||
|
||||
$0056 OLDOV The old overflow.
|
||||
|
||||
$0057-$005B TEMPF1
|
||||
|
||||
$0058 HIGHDS Destination of highest element in BLT.
|
||||
|
||||
$005A HIGHTR Source of highest element to move.
|
||||
|
||||
$005C-$0060 TEMPF2
|
||||
|
||||
$005D LOWDS Location of last byte transferred into.
|
||||
|
||||
$005F LOWTR Last thing to move in BLT.
|
||||
|
||||
$0058 ARYPNT A pointer used in array building.
|
||||
|
||||
$005F GRBTOP A pointer used in garbage collection.
|
||||
|
||||
$005D DECCNT Number of places before decimal point.
|
||||
|
||||
$005E TENEXP Has a DPT been input?
|
||||
|
||||
$005F DPTFLG Base ten exponent.
|
||||
|
||||
$0060 EXPSGN Sign of base ten exponent.
|
||||
|
||||
$0061-$0066 FAC The floating accumulator
|
||||
|
||||
$0061 FACEXP
|
||||
|
||||
$0061 DSCTMP This is where temp descs are built.
|
||||
|
||||
$0062 FACHO Most significant byte of mantissa.
|
||||
|
||||
$0063 FACMOH One more.
|
||||
|
||||
$0064 FACMO Middle order of mantissa.
|
||||
|
||||
$0064 INDICE Indice is set up here by "QINT".
|
||||
|
||||
$0065 FACLO Least sig byte of mantissa.
|
||||
|
||||
$0066 FACSGN Sign of FAC (0 or -1) when unpacked.
|
||||
|
||||
$0067 SGNFLG Sign of FAC is preserved bere by "FIN".
|
||||
|
||||
$0067 DEGREE A count used by polynomials.
|
||||
|
||||
$0068 BITS Something for "SHIFTR" to use.
|
||||
|
||||
$0069-$006E The floating argument (unpacked)
|
||||
|
||||
$0069 ARGEXP
|
||||
|
||||
$006A ARGHO
|
||||
|
||||
$006B ARGMOH
|
||||
|
||||
$006C ARGMO
|
||||
|
||||
$006D ARGLO
|
||||
|
||||
$006E ARGSGN
|
||||
|
||||
$006F ARISGN A sign reflecting the result.
|
||||
|
||||
$006F-$0070 STRNG1 Pointer to a string or descriptor.
|
||||
|
||||
$0070 FACOV Overflow byte of the FAC.
|
||||
|
||||
$0071-$0072 FBUFPT Pointer into FBUFFR used by FOUT.
|
||||
|
||||
$0071-$0072 BUFPTR Pointer to buf used by "CRUNCH".
|
||||
|
||||
$0071-$0072 STRNG2 Pointer to string or desc.
|
||||
|
||||
$0071-$0072 POLYPT Pointer into polynomial coefficients.
|
||||
|
||||
$0071-$0072 CURTOL Absolute linear index is formed here.
|
||||
|
||||
$0073-$008A CHRGET RAM code.
|
||||
|
||||
This code gets changed throughout execution.
|
||||
It is made to be fast this way.
|
||||
Also, [X] and [Y] are not disturbed.
|
||||
|
||||
"CHRGET" using [TXTPTR] as the current text pntr,
|
||||
fetches a new character into ACCA after incrementing [TXTPTR]
|
||||
and sets condition codes according to what's in ACCA.
|
||||
|
||||
* not C = numeric ("0" thru "9")
|
||||
* Z = ":" or end-of-line (a null)
|
||||
|
||||
[ACCA] = new char.
|
||||
|
||||
[TXTPTR]=[TXTPTR]+1
|
||||
|
||||
The following exists in ROM if ROM exists and is loaded
|
||||
down here by init. Otherwise it is just loaded into this
|
||||
RAM like all the rest of RAM is loaded.
|
||||
|
||||
$008B-$008F RNDX
|
||||
|
||||
#
|
||||
# KERNAL
|
||||
#
|
||||
|
||||
$0090 STATUS I/O operation status byte
|
||||
|
||||
$0091 STKEY STOP key flag
|
||||
|
||||
$0092 SVXT Cassette: temp used to adjust software servo
|
||||
|
||||
$0093 VERCK Cassette: verify or load flag (Z - loading)
|
||||
|
||||
$0094 C3P0 IEEE buffered char flag
|
||||
|
||||
$0095 BSOUR Char buffer for IEEE
|
||||
|
||||
$0096 SYNO Cassette: flags if we have block SYNC (16 zero dipoles)
|
||||
|
||||
$0097 XSAV Temp for BASIN
|
||||
|
||||
$0098 LDTND Index to logical file
|
||||
|
||||
$0099 DFLTN Default input device #
|
||||
|
||||
$009A DFLTO Default output device #
|
||||
|
||||
$009B PRTY Cassette: holds current calculated parity bit
|
||||
|
||||
$009C DPSW Cassette: if NZ then expecting LL/L combination that ends a byte
|
||||
|
||||
$009D MSGFLG OS message flag
|
||||
|
||||
$009E PTR1 Cassette: count of read locations in error (pointer into bad, max 61)
|
||||
|
||||
$009E T1 Temporary 1
|
||||
|
||||
$009F PTR2 Cassette: count of re-read locations (pointer into bad, during re-read)
|
||||
|
||||
$009F T2 Temporary 2
|
||||
|
||||
$00A0-$00A2 TIME 24 hour clock in 1/60th seconds
|
||||
|
||||
$00A3 R2D2 Serial bus usage
|
||||
|
||||
$00A3 PCNTR Cassette: counts down from 8-0 for data then to ff for parity
|
||||
|
||||
$00A4 BSOUR1 Temp used by serial routine
|
||||
|
||||
$00A4 FIRT Cassette: used to indicate which half of dipole we're in
|
||||
|
||||
$00A5 COUNT Temp used by serial routine
|
||||
|
||||
$00A5 CNTDN Cassette sync countdown
|
||||
|
||||
$00A6 BUFPT Cassette buffer pointer
|
||||
|
||||
$00A7 INBIT RS-232 rcvr input bit storage
|
||||
|
||||
$00A7 SHCNL Cassette: holds FSBLK, used to direct routines, because of exit case
|
||||
|
||||
$00A8 BITCI RS-232 rcvr bit count in
|
||||
|
||||
$00A8 RER Cassette: flags errors (if Z then no error)
|
||||
|
||||
$00A9 RINONE RS-232 rcvr flag for start bit check
|
||||
|
||||
$00A9 REZ Cassette: counts zeros (if Z then correct # of dipoles)
|
||||
|
||||
$00AA RIDATA RS-232 rcvr byte buffer
|
||||
|
||||
$00AA RDFLG Cassette: holds function mode
|
||||
|
||||
MI - waiting for block SYNC
|
||||
VS - in data block reading data
|
||||
NE - waiting for byte SYNC
|
||||
|
||||
$00AB RIPRTY RS-232 rcvr parity storage
|
||||
|
||||
$00AB SHCNH Cassette: short cnt; left over from debugging
|
||||
|
||||
$00AC SAL Cassette: indirect to data storage area
|
||||
|
||||
$00AD SAH
|
||||
|
||||
$00AE EAL
|
||||
|
||||
$00AF EAH
|
||||
|
||||
$00B0 CMP0 Cassette: software servo (+/- adjust to time calcs)
|
||||
|
||||
$00B1 TEMP Cassette: used to hold dipole time during type calculations
|
||||
|
||||
$00B2-$00B3 TAPE1 Address of tape buffer #1y.
|
||||
|
||||
$00B4 BITTS RS-232 trns bit count
|
||||
|
||||
$00B4 SNSW1 Cassette: flags if we have byte SYNC (a longlong)
|
||||
|
||||
$00B5 NXTBIT RS-232 trns next bit to be sent
|
||||
|
||||
$00B5 DIFF Cassette: used to preserve SYNO (outside of bit routines)
|
||||
|
||||
$00B6 RODATA RS-232 trns byte buffer
|
||||
|
||||
$00B6 PRP Cassette: has combined error values from bit routines
|
||||
|
||||
$00B7 FNLEN Length current file n str
|
||||
|
||||
$00B8 LA Current file logical addr
|
||||
|
||||
$00B9 SA Current file 2nd addr
|
||||
|
||||
$00BA FA Current file primary addr
|
||||
|
||||
$00BB-$00BC FNADR Addr current file name str
|
||||
|
||||
$00BD ROPRTY RS-232 trns parity buffer
|
||||
|
||||
$00BD OCHAR
|
||||
|
||||
$00BE FSBLK Cassette: indicate which block we're looking at (0 to exit)
|
||||
|
||||
$00BF MYCH Cassette: holds input byte being built
|
||||
|
||||
$00C0 CAS1 Cassette manual/controlled switch
|
||||
|
||||
$00C1 TMP0
|
||||
|
||||
$00C1 STAL
|
||||
|
||||
$00C2 STAH
|
||||
|
||||
$00C3-$00C4 MEMUSS Cassette load temps (2 bytes)
|
||||
|
||||
$00C3-$00C4 TMP2
|
||||
|
||||
$00C5 LSTX Key scan index
|
||||
|
||||
$00C6 NDX Index to keyboard q
|
||||
|
||||
$00C7 RVS RVS field on flag
|
||||
|
||||
$00C8 INDX
|
||||
|
||||
$00C9 LSXP X pos at start
|
||||
|
||||
$00CA LSTP
|
||||
|
||||
$00CB SFDX SHIFT mode on print
|
||||
|
||||
$00CC BLNSW Cursor blink enab
|
||||
|
||||
$00CD BLNCT Count to toggle cur
|
||||
|
||||
$00CE GDBLN Char before cursor
|
||||
|
||||
$00CF BLNON On/off blink flag
|
||||
|
||||
$00D0 CRSW INPUT vs GET flag
|
||||
|
||||
$00D1-$00D2 PNT Pointer to row
|
||||
|
||||
$00D3 PNTR Pointer to column
|
||||
|
||||
$00D4 QTSW Quote switch
|
||||
|
||||
$00D5 LNMX 40/80 max positon
|
||||
|
||||
$00D6 TBLX
|
||||
|
||||
$00D7 DATA Cassette: holds most recent dipole bit value
|
||||
|
||||
$00D8 INSRT Insert mode flag
|
||||
|
||||
$00D9-$00F2 LDTB1 Line flags+endspace
|
||||
|
||||
$00F3-$00F4 USER Screen editor color IP
|
||||
|
||||
$00F5-$00F6 KEYTAB Keyscan table indirect
|
||||
|
||||
$00F7-$00F8 RIBUF RS-232 input buffer pointer
|
||||
|
||||
$00F9-$00FA ROBUF RS-232 output buffer pointer
|
||||
|
||||
$00FB-$00FE FREKZP Free KERNAL zero page 9/24/80
|
||||
|
||||
$00FF-$010A BASZPT Location ($00FF) used by BASIC
|
||||
|
||||
$0100-$013E BAD Cassette: storage space for bad read locations (bottom of stack)
|
||||
|
||||
#
|
||||
# BASIC
|
||||
#
|
||||
|
||||
$0200-$0258 BUF BASIC/MONITOR buffer
|
||||
|
||||
Type-in stored here.
|
||||
Direct statements execute out of
|
||||
here. Remember "INPUT" smashes buf.
|
||||
Must be on page zero
|
||||
or assignment of string
|
||||
values in direct statements won't copy
|
||||
into string space -- which it must.
|
||||
N.B.: Two nonzero bytes must precede "BUFLNM".
|
||||
|
||||
#
|
||||
# KERNAL
|
||||
#
|
||||
|
||||
$0259-$0262 LAT Logical file numbers
|
||||
|
||||
$0263-$026C FAT Primary device numbers
|
||||
|
||||
$026D-$0276 SAT Secondary addresses
|
||||
|
||||
$0277-$0280 KEYD IRQ keyboard buffer
|
||||
|
||||
$0281-$0282 MEMSTR Start of memory
|
||||
|
||||
$0283-$0284 MEMSIZ Top of memory
|
||||
|
||||
$0285 TIMOUT IEEE timeout flag
|
||||
|
||||
$0286 COLOR Active color nybble
|
||||
|
||||
$0287 GDCOL Original color before cursor
|
||||
|
||||
$0288 HIBASE Base location of screen (top)
|
||||
|
||||
$0289 XMAX
|
||||
|
||||
$028A RPTFLG Key repeat flag
|
||||
|
||||
$028B KOUNT
|
||||
|
||||
$028C DELAY
|
||||
|
||||
$028D SHFLAG SHIFT flag byte
|
||||
|
||||
$028E LSTSHF Last SHIFT pattern
|
||||
|
||||
$028F-$0290 KEYLOG Indirect for keyboard table setup
|
||||
|
||||
$0291 MODE 0-PET mode, 1-cattacanna
|
||||
|
||||
$0292 AUTODN Auto scroll down flag(=0 on,<>0 off)
|
||||
|
||||
$0293 M51CTR 6551 control register
|
||||
|
||||
$0294 M51CDR 6551 command register
|
||||
|
||||
$0295-$0296 M51AJB Non standard (bittime/2-100)
|
||||
|
||||
$0297 RSSTAT RS-232 status register
|
||||
|
||||
$0298 BITNUM Number of bits to send (fast response)
|
||||
|
||||
$0299-$029A BAUDOF Baud rate full bit time (created by open)
|
||||
|
||||
$029B RIDBE Input buffer index to end
|
||||
|
||||
$029C RIDBS Input buffer pointer to start
|
||||
|
||||
$029D RODBS Output buffer index to start
|
||||
|
||||
$029E RODBE Output buffer index to end
|
||||
|
||||
$029F-$02A0 IRQTMP Holds irq during tape ops
|
||||
|
||||
$02A1 ENABL RS-232 enables (replaces ier)
|
||||
|
||||
$02A2 CASTON TOD sense during cassettes
|
||||
|
||||
$02A3 KIKA26 Cassette: holds old D1ICR after clear on read
|
||||
|
||||
$02A4 STUPID Cassette: hold indicator (NZ - no T1IRQ yet) for T1IRQ
|
||||
|
||||
$02A5 LINTMP Temporary for line index
|
||||
|
||||
$02A6 PALNTS PAL vs NTSC flag 0=NTSC 1=PAL
|
||||
|
||||
#
|
||||
# BASIC
|
||||
#
|
||||
|
||||
$0300-$0301 IERROR indirect ERROR (output error in .X)
|
||||
$0302-$0303 IMAIN indirect MAIN (system direct loop)
|
||||
$0304-$0305 ICRNCH indirect CRUNCH (tokenization routine)
|
||||
$0306-$0307 IQPLOP indirect LIST (char list)
|
||||
$0308-$0309 IGONE indirect GONE (char dispatch)
|
||||
$030A-$030B IEVAL indirect EVAL (symbol evaluation)
|
||||
$030C SAREG .A reg
|
||||
$030D SXREG .X reg
|
||||
$030E SYREG .Y reg
|
||||
$030F SPREG .P reg
|
||||
$0310-$0312 USRPOK user function dispatch
|
||||
|
||||
#
|
||||
# KERNAL
|
||||
#
|
||||
|
||||
$0314-$0315 CINV IRQ RAM vector
|
||||
|
||||
$0316-$0317 CBINV BRK instr RAM vector
|
||||
|
||||
$0318-$0319 NMINV NMI RAM vector
|
||||
|
||||
$031A-$032D Indirects for code
|
||||
|
||||
Conforms to KERNAL spec 8/19/80
|
||||
|
||||
$031A-$031B IOPEN
|
||||
|
||||
$031C-$031D ICLOSE
|
||||
|
||||
$031E-$031F ICHKIN
|
||||
|
||||
$0320-$0321 ICKOUT
|
||||
|
||||
$0322-$0323 ICLRCH
|
||||
|
||||
$0324-$0325 IBASIN
|
||||
|
||||
$0326-$0327 IBSOUT
|
||||
|
||||
$0328-$0329 ISTOP
|
||||
|
||||
$032A-$032B IGETIN
|
||||
|
||||
$032C-$032D ICLALL
|
||||
|
||||
$032E-$032F USRCMD
|
||||
|
||||
$0330-$0331 ILOAD
|
||||
|
||||
$0332-$0333 ISAVE savesp
|
||||
|
||||
$033C-$03FB TBUFFR cassette data b
|
||||
|
|
@ -1,894 +0,0 @@
|
|||
- C64 RAM Map (STA)
|
||||
-
|
||||
- Joe Forster/STA:
|
||||
- Commodore 64 memory map
|
||||
- http://sta.c64.org/cbm64mem.html
|
||||
-
|
||||
- edited by awsm.de // @awsm9000
|
||||
- http://www.awsm.de/mem64/
|
||||
-
|
||||
- Corrections (typos as well as content), translations etc.
|
||||
- welcome at: https://github.com/mist64/c64disasm
|
||||
-
|
||||
------------------------------------------------------------
|
||||
-
|
||||
# This plain text file is formatted so that it can be automatically
|
||||
# parsed in order to create cross-references etc.
|
||||
# * Lines starting with "-" is top-level information. The first line
|
||||
# is the title. Lines starting with "--" are separators.
|
||||
# * Lines starting with "#" are internal comments.
|
||||
# * Hex addresses start at column 0.
|
||||
# * Symbols start at column 13.
|
||||
# * The description starts at column 21.
|
||||
# * All lines of the description until the first blank line are
|
||||
# combined into the heading.
|
||||
# * A '.' character at the end of a heading line represents a hard
|
||||
# line break.
|
||||
# * The remaining text is in MarkDown format.
|
||||
# * All addresses are 4 digits and have a leading '$'.
|
||||
# The encoding is UTF-8.
|
||||
|
||||
$0000 D6510 Processor port data direction register
|
||||
|
||||
Bits:
|
||||
|
||||
* Bit #x: 0 = Bit #x in processor port can only be read; 1 = Bit #x in processor port can be read and written.
|
||||
|
||||
Default: $2F, %00101111.
|
||||
|
||||
$0001 R6510 Processor port
|
||||
|
||||
Bits:
|
||||
|
||||
* Bits #0-#2: Configuration for memory areas $A000-$BFFF, $D000-$DFFF and $E000-$FFFF. Values:
|
||||
* %x00: RAM visible in all three areas.
|
||||
* %x01: RAM visible at $A000-$BFFF and $E000-$FFFF.
|
||||
* %x10: RAM visible at $A000-$BFFF; KERNAL ROM visible at $E000-$FFFF.
|
||||
* %x11: BASIC ROM visible at $A000-$BFFF; KERNAL ROM visible at $E000-$FFFF.
|
||||
* %0xx: Character ROM visible at $D000-$DFFF. (Except for the value %000, see above.)
|
||||
* %1xx: I/O area visible at $D000-$DFFF. (Except for the value %100, see above.)
|
||||
* Bit #3: Datasette output signal level.
|
||||
* Bit #4: Datasette button status; 0 = One or more of PLAY, RECORD, F.FWD or REW pressed; 1 = No button is pressed.
|
||||
* Bit #5: Datasette motor control; 0 = On; 1 = Off.
|
||||
|
||||
Default: $37, %00110111.
|
||||
|
||||
$0002 Unused
|
||||
|
||||
$0003-$0004 ADRAY1 Unused.
|
||||
|
||||
Default: $B1AA, execution address of routine converting floating point to integer.
|
||||
|
||||
$0005-$0006 ADRAY2 Unused.
|
||||
|
||||
Default: $B391, execution address of routine converting integer to floating point.
|
||||
|
||||
$0007 CHARAC Byte being searched for during various operations.
|
||||
Current digit of number being input.
|
||||
|
||||
$0007 INTEGR Low byte of first integer operand during AND and OR.
|
||||
Low byte of integer-format FAC during INT().
|
||||
|
||||
$0008 ENDCHR Byte being search for during various operations.
|
||||
Current byte of BASIC line during tokenization.
|
||||
High byte of first integer operand during AND and OR.
|
||||
|
||||
$0009 TRMPOS Current column number during SPC() and TAB().
|
||||
|
||||
$000A VERCK LOAD/VERIFY switch
|
||||
|
||||
Values:
|
||||
|
||||
* $00: LOAD.
|
||||
* $01-$FF: VERIFY.
|
||||
|
||||
$000B COUNT Current token during tokenization.
|
||||
Length of BASIC line during insertion of line.
|
||||
AND/OR switch; $00 = AND; $FF = OR.
|
||||
Number of dimensions during array operations.
|
||||
|
||||
$000C DIMFLG Switch for array operations
|
||||
|
||||
Values:
|
||||
|
||||
* $00: Operation was not called by DIM.
|
||||
* $40-$7F: Operation was called by DIM.
|
||||
|
||||
$000D VALTYP Current expression type
|
||||
|
||||
Values:
|
||||
|
||||
* $00: Numerical.
|
||||
* $FF: String.
|
||||
|
||||
$000E INTFLG Current numerical expression type
|
||||
|
||||
Bits:
|
||||
|
||||
* Bit #7: 0 = Floating point; 1 = Integer.
|
||||
|
||||
$000F GARBFL Garbage collection indicator during memory allocation for string variable; $00-$7F = There was no garbage collection yet; $80 = Garbage collection already took place.
|
||||
|
||||
$000F DORES Quotation mode switch during tokenization; Bit #6: 0 = Normal mode; 1 = Quotation mode.
|
||||
Quotation mode switch during LIST; $01 = Normal mode; $FE = Quotation mode.
|
||||
|
||||
$0010 SUBFLG Switch during fetch of variable name
|
||||
|
||||
Values:
|
||||
|
||||
* $00: Integer variables are accepted.
|
||||
* $01-$FF: Integer variables are not accepted.
|
||||
|
||||
$0011 INPFLG GET/INPUT/READ switch
|
||||
|
||||
Values:
|
||||
|
||||
* $00: INPUT.
|
||||
* $40: GET.
|
||||
* $98: READ.
|
||||
|
||||
$0012 TANSGN Sign during SIN() and TAN()
|
||||
|
||||
Values:
|
||||
|
||||
* $00: Positive.
|
||||
* $FF: Negative.
|
||||
|
||||
$0013 CHANNL Current I/O device number.
|
||||
|
||||
Default: $00, keyboard for input and screen for output.
|
||||
|
||||
$0014-$0015 LINNUM Line number during GOSUB, GOTO and RUN.
|
||||
Second line number during LIST.
|
||||
|
||||
$0014-$0015 POKER Memory address during PEEK, POKE, SYS and WAIT.
|
||||
|
||||
$0016 TEMPPT Pointer to next expression in string stack
|
||||
|
||||
Values: $19; $1C; $1F; $22.
|
||||
|
||||
Default: $19.
|
||||
|
||||
$0017-$0018 LASTPT Pointer to previous expression in string stack.
|
||||
|
||||
$0019-$0021 TEMPST String stack, temporary area for processing string expressions (9 bytes, 3 entries).
|
||||
|
||||
$0022-$0025 INDEX Temporary area for various operations (4 bytes).
|
||||
|
||||
$0026-$002A RES Auxiliary arithmetical register for division and multiplication (4 bytes).
|
||||
|
||||
$002B-$002C TXTTAB Pointer to beginning of BASIC area.
|
||||
|
||||
Default: $0801, 2049.
|
||||
|
||||
$002D-$002E VARTAB Pointer to beginning of variable area.
|
||||
|
||||
(End of program plus 1.)
|
||||
|
||||
$002F-$0030 ARYTAB Pointer to beginning of array variable area.
|
||||
|
||||
$0031-$0032 STREND Pointer to end of array variable area.
|
||||
|
||||
$0033-$0034 FRETOP Pointer to beginning of string variable area.
|
||||
|
||||
(Grows downwards from end of BASIC area.)
|
||||
|
||||
$0035-$0036 FRESPC Pointer to memory allocated for current string variable.
|
||||
|
||||
$0037-$0038 MEMSIZ Pointer to end of BASIC area.
|
||||
|
||||
Default: $A000, 40960.
|
||||
|
||||
$0039-$003A CURLIN Current BASIC line number
|
||||
|
||||
Values:
|
||||
|
||||
* $0000-$F9FF, 0-63999: Line number.
|
||||
* $FF00-$FFFF: Direct mode, no BASIC program is being executed.
|
||||
|
||||
$003B-$003C OLDLIN Current BASIC line number for CONT.
|
||||
|
||||
$003D-$003E OLDTXT Pointer to next BASIC instruction for CONT
|
||||
|
||||
Values:
|
||||
|
||||
* $0000-$00FF: CONT'ing is not possible.
|
||||
* $0100-$FFFF: Pointer to next BASIC instruction.
|
||||
|
||||
$003F-$0040 DATLIN BASIC line number of current DATA item for READ.
|
||||
|
||||
$0041-$0042 DATPTR Pointer to next DATA item for READ.
|
||||
|
||||
$0043-$0044 INPPTR Pointer to input result during GET, INPUT and READ.
|
||||
|
||||
$0045-$0046 VARNAM Name and type of current variable
|
||||
|
||||
Bits:
|
||||
|
||||
* $0045 bits #0-#6: First character of variable name.
|
||||
* $0046 bits #0-#6: Second character of variable name; $00 = Variable name consists of only one character.
|
||||
* $0045 bit #7 and $0046 bit #7:
|
||||
* %00: Floating-point variable.
|
||||
* %01: String variable.
|
||||
* %10: FN function, created with DEF FN.
|
||||
* %11: Integer variable.
|
||||
|
||||
$0047-$0048 VARPNT Pointer to value of current variable or FN function.
|
||||
|
||||
$0049-$004A FORPNT Pointer to value of current variable during LET.
|
||||
|
||||
$0049 ANDMSK Value of second parameter during WAIT.
|
||||
Logical number during CLOSE and CLOSE
|
||||
Device number of LOAD, SAVE and VERIFY.
|
||||
|
||||
$004A EORMSK Value of third parameter during WAIT.
|
||||
Device number during OPEN.
|
||||
|
||||
$004B-$004C VARTXT Temporary area for saving original pointer to current BASIC instruction during GET, INPUT and READ.
|
||||
|
||||
$004D OPMASK Comparison operator indicator
|
||||
|
||||
Bits:
|
||||
|
||||
* Bit #1: 1 = ">" (greater than) is present in expression.
|
||||
* Bit #2: 1 = "=" (equal to) is present in expression.
|
||||
* Bit #3: 1 = "<" (less than) is present in expression.
|
||||
|
||||
$004E-$004F Pointer to current FN function.
|
||||
|
||||
$0050-$0052 DSCPNT Pointer to current string variable during memory allocation.
|
||||
|
||||
$0053 FOUR6 Step size of garbage collection
|
||||
|
||||
Values: $03; $07.
|
||||
|
||||
$0054-$0056 JMPER JMP ABS machine instruction, jump to current BASIC function.
|
||||
|
||||
$0055-$0056 Execution address of current BASIC function.
|
||||
|
||||
$0057-$005B TEMPF1 Arithmetic register #3 (5 bytes).
|
||||
|
||||
$005C-$0060 TEMPF2 Arithmetic register #4 (5 bytes).
|
||||
|
||||
$0061-$0066 FAC FAC, arithmetic register #1 (5 bytes).
|
||||
|
||||
$0066 FACSGN Sign of FAC
|
||||
|
||||
Bits:
|
||||
|
||||
* Bit #7: 0 = Positive; 1 = Negative.
|
||||
|
||||
$0067 SGNFLG Number of degrees during polynomial evaluation.
|
||||
|
||||
$0068 BITS Temporary area for various operations.
|
||||
|
||||
$0069-$006E ARG, arithmetic register #2 (5 bytes).
|
||||
|
||||
$006E ARGSGN Sign of ARG
|
||||
|
||||
Bits:
|
||||
|
||||
* Bit #7: 0 = Positive; 1 = Negative.
|
||||
|
||||
$006F-$0070 STRNG1 Pointer to first string expression during string comparison.
|
||||
|
||||
$0071-$0072 STRNG2 Temporary area for saving original pointer to current BASIC instruction during VAL().
|
||||
|
||||
$0071-$0072 POLYPT Pointer to current item of polynomial table during polynomial evaluation.
|
||||
|
||||
$0071-$0072 CURTOL Auxiliary pointer during array operations.
|
||||
|
||||
$0073-$008A CHRGET CHRGET. Machine code routine to read next byte from BASIC program or direct command (24 bytes).
|
||||
|
||||
$0079 CHRGOT CHRGOT. Read current byte from BASIC program or direct command.
|
||||
|
||||
007A-$007B Pointer to current byte in BASIC program or direct command.
|
||||
|
||||
$008B-$008F RNDX Previous result of RND().
|
||||
|
||||
$0090 STATUS Value of ST variable, device status for serial bus and datasette input/output
|
||||
|
||||
Serial bus bits:
|
||||
|
||||
* Bit #0: Transfer direction during which the timeout occured; 0 = Input; 1 = Output.
|
||||
* Bit #1: 1 = Timeout occurred.
|
||||
* Bit #4: 1 = VERIFY error occurred (only during VERIFY), the file read from the device did not match that in the memory.
|
||||
* Bit #6: 1 = End of file has been reached.
|
||||
* Bit #7: 1 = Device is not present.
|
||||
|
||||
Datasette bits:
|
||||
|
||||
* Bit #2: 1 = Block is too short (shorter than 192 bytes).
|
||||
* Bit #3: 1 = Block is too long (longer than 192 bytes).
|
||||
* Bit #4: 1 = Not all bytes read with error during pass 1 could be corrected during pass 2, or a VERIFY error occurred, the file read from the device did not match that in the memory.
|
||||
* Bit #5: 1 = Checksum error occurred.
|
||||
* Bit #6: 1 = End of file has been reached (only during reading data files).
|
||||
|
||||
$0091 STKEY Stop key indicator
|
||||
|
||||
Values:
|
||||
|
||||
* $7F: Stop key is pressed.
|
||||
* $FF: Stop key is not pressed.
|
||||
|
||||
$0092 SVXT Unknown. (Timing constant during datasette input.)
|
||||
|
||||
$0093 VERCK LOAD/VERIFY switch
|
||||
|
||||
Values:
|
||||
|
||||
* $00: LOAD.
|
||||
* $01-$FF: VERIFY.
|
||||
|
||||
$0094 C3P0 Serial bus output cache status
|
||||
|
||||
Bits:
|
||||
|
||||
* Bit #7: 1 = Output cache dirty, must transfer cache contents upon next output to serial bus.
|
||||
|
||||
$0095 BSOUR Serial bus output cache, previous byte to be sent to serial bus.
|
||||
|
||||
$0096 SYNO Unknown. (End of tape indicator during datasette input/output.)
|
||||
|
||||
$0097 XSAV Temporary area for saving original value of Y register during input from RS232.
|
||||
Temporary area for saving original value of X register during input from datasette.
|
||||
|
||||
$0098 LDTND Number of files currently open
|
||||
|
||||
Values: $00-$0A, 0-10.
|
||||
|
||||
$0099 DFLTN Current input device number.
|
||||
|
||||
Default: $00, keyboard.
|
||||
|
||||
$009A DFLTO Current output device number.
|
||||
|
||||
Default: $03, screen.
|
||||
|
||||
$009B PRTY Unknown. (Parity bit during datasette input/output.)
|
||||
|
||||
$009C DPSW Unknown. (Byte ready indicator during datasette input/output.)
|
||||
|
||||
$009D MSGFLG System error display switch
|
||||
|
||||
Bits:
|
||||
|
||||
* Bit #6: 0 = Suppress I/O error messages; 1 = Display them.
|
||||
* Bit #7: 0 = Suppress system messages; 1 = Display them.
|
||||
|
||||
$009E PTR1 Error counter during LOAD from datasette.
|
||||
|
||||
Values: $00-$3E, 0-62.
|
||||
|
||||
$009E T1 Block header type during datasette input/output.
|
||||
Length of file name during datasette input/output.
|
||||
Byte to be put into output buffer during RS232 and datasette output.
|
||||
|
||||
$009F PTR2 Error correction counter during LOAD from datasette.
|
||||
|
||||
Values: $00-$3E, 0-62.
|
||||
|
||||
$009F T2 Auxiliary counter for writing file name into datasette buffer.
|
||||
Auxiliary counter for comparing requested file name with file name read from datasette during datasette input.
|
||||
|
||||
$00A0-$00A2 TIME Value of TI variable, time of day, increased by 1 every 1/60 second (on PAL machines)
|
||||
|
||||
Values: $000000-$4F19FF, 0-518399 (on PAL machines).
|
||||
|
||||
$00A3 R2D2 EOI switch during serial bus output
|
||||
|
||||
Bits:
|
||||
|
||||
* Bit #7: 0 = Send byte right after handshake; 1 = Do EOI delay first.
|
||||
|
||||
Bit counter during datasette output.
|
||||
|
||||
$00A4 FIRT Byte buffer during serial bus input.
|
||||
Parity during datasette input/output.
|
||||
|
||||
$00A5 CNTDN Bit counter during serial bus input/output.
|
||||
Counter for sync mark during datasette output.
|
||||
|
||||
$00A6 BUFPT Offset of current byte in datasette buffer.
|
||||
|
||||
$00A7 INBIT Bit buffer during RS232 input.
|
||||
|
||||
$00A8 BITCI Bit counter during RS232 input.
|
||||
|
||||
$00A9 RINONE Stop bit switch during RS232 input
|
||||
|
||||
Values:
|
||||
|
||||
* $00: Data bit.
|
||||
* $01-$FF: Stop bit.
|
||||
|
||||
$00AA RIDATA Byte buffer during RS232 input.
|
||||
|
||||
$00AB RIPRTY Parity during RS232 input.
|
||||
Computed block checksum during datasette input.
|
||||
|
||||
$00AC-$00AD Start address for SAVE to serial bus.
|
||||
Pointer to current byte during SAVE to serial bus or datasette.
|
||||
Pointer to line in screen memory to be scrolled during scrolling the screen.
|
||||
|
||||
$00AE-$00AF Load address read from input file and pointer to current byte during LOAD/VERIFY from serial bus.
|
||||
End address after LOAD/VERIFY from serial bus or datasette.
|
||||
End address for SAVE to serial bus or datasette.
|
||||
Pointer to line in Color RAM to be scrolled during scrolling the screen.
|
||||
|
||||
$00B0-$00B1 Unknown.
|
||||
|
||||
$00B2-$00B3 TAPE1 Pointer to datasette buffer.
|
||||
|
||||
Default: $033C, 828.
|
||||
|
||||
$00B4 BITTS Bit counter and stop bit switch during RS232 output
|
||||
|
||||
Bits:
|
||||
|
||||
* Bits #0-#6: Bit count.
|
||||
* Bit #7: 0 = Data bit; 1 = Stop bit.
|
||||
|
||||
Bit counter during datasette input/output.
|
||||
|
||||
$00B5 NXTBIT Bit buffer (in bit #2) during RS232 output.
|
||||
|
||||
$00B6 RODATA Byte buffer during RS232 output.
|
||||
|
||||
$00B7 FNLEN Length of file name or disk command; first parameter of LOAD, SAVE and VERIFY or fourth parameter of OPEN
|
||||
|
||||
Values:
|
||||
|
||||
* $00: No parameter.
|
||||
* $01-$FF: Parameter length.
|
||||
|
||||
$00B8 LA Logical number of current file.
|
||||
|
||||
$00B9 SA Secondary address of current file.
|
||||
|
||||
$00BA FA Device number of current file.
|
||||
|
||||
$00BB-$00BC FNADR Pointer to current file name or disk command; first parameter of LOAD, SAVE and VERIFY or fourth parameter of OPEN.
|
||||
|
||||
$00BD ROPRTY Parity during RS232 output.
|
||||
Byte buffer during datasette input/output.
|
||||
|
||||
$00BE FSBLK Block counter during datasette input/output.
|
||||
|
||||
$00BF MYCH Unknown.
|
||||
|
||||
$00C0 CAS1 Datasette motor switch
|
||||
|
||||
Values:
|
||||
|
||||
* $00: No button was pressed, motor has been switched off. If a button is pressed on the datasette, must switch motor on.
|
||||
* $01-$FF: Motor is on.
|
||||
|
||||
$00C1-$00C2 STAL Start address during SAVE to serial bus, LOAD and VERIFY from datasette and SAVE to datasette.
|
||||
Pointer to current byte during memory test.
|
||||
|
||||
$00C3-$00C4 MEMUSS Start address for a secondary address of 0 for LOAD and VERIFY from serial bus or datasette.
|
||||
Pointer to ROM table of default vectors during initialization of I/O vectors.
|
||||
|
||||
$00C5 LSTX Matrix code of key previously pressed
|
||||
|
||||
Values:
|
||||
|
||||
* $00-$3F: Keyboard matrix code.
|
||||
* $40: No key was pressed at the time of previous check.
|
||||
|
||||
$00C6 NDX Length of keyboard buffer
|
||||
|
||||
Values:
|
||||
|
||||
* $00, 0: Buffer is empty.
|
||||
* $01-$0A, 1-10: Buffer length.
|
||||
|
||||
$00C7 RVS Reverse mode switch
|
||||
|
||||
Values:
|
||||
|
||||
* $00: Normal mode.
|
||||
* $12: Reverse mode.
|
||||
|
||||
$00C8 INDX Length of line minus 1 during screen input. Values: $27, 39; $4F, 79.
|
||||
|
||||
$00C9 LSXP Cursor row during screen input. Values: $00-$18, 0-24.
|
||||
|
||||
$00CA Cursor column during screen input. Values: $00-$27, 0-39.
|
||||
|
||||
|
||||
$00CB SFDX Matrix code of key currently being pressed
|
||||
|
||||
Values:
|
||||
|
||||
* $00-$3F: Keyboard matrix code.
|
||||
* $40: No key is currently pressed.
|
||||
|
||||
$00CC BLNSW Cursor visibility switch
|
||||
|
||||
Values:
|
||||
|
||||
* $00: Cursor is on.
|
||||
* $01-$FF: Cursor is off.
|
||||
|
||||
$00CD BLNCT Delay counter for changing cursor phase
|
||||
|
||||
Values:
|
||||
|
||||
* $00, 0: Must change cursor phase.
|
||||
* $01-$14, 1-20: Delay.
|
||||
|
||||
$00CE GDBLN Screen code of character under cursor.
|
||||
|
||||
$00CF BLNON Cursor phase switch
|
||||
|
||||
Values:
|
||||
|
||||
* $00: Cursor off phase, original character visible.
|
||||
* $01: Cursor on phase, reverse character visible.
|
||||
|
||||
$00D0 CRSW End of line switch during screen input
|
||||
|
||||
Values:
|
||||
|
||||
* $00: Return character reached, end of line.
|
||||
* $01-$FF: Still reading characters from line.
|
||||
|
||||
$00D1-$00D2 PNT Pointer to current line in screen memory.
|
||||
|
||||
$00D3 PNTR Current cursor column. Values: $00-$27, 0-39.
|
||||
|
||||
$00D4 QTSW Quotation mode switch
|
||||
|
||||
Values:
|
||||
|
||||
* $00: Normal mode.
|
||||
* $01: Quotation mode.
|
||||
|
||||
$00D5 LNMX Length of current screen line minus 1. Values: $27, 39; $4F, 79.
|
||||
|
||||
$00D6 TBLX Current cursor row. Values: $00-$18, 0-24.
|
||||
|
||||
$00D7 DATA PETSCII code of character during screen input/output.
|
||||
Bit buffer during datasette input.
|
||||
Block checksum during datasette output.
|
||||
|
||||
$00D8 INSRT Number of insertions
|
||||
|
||||
Values:
|
||||
|
||||
* $00: No insertions made, normal mode, control codes change screen layout or behavior.
|
||||
* $01-$FF: Number of insertions, when inputting this many character next, those must be turned into control codes, similarly to quotation mode.
|
||||
|
||||
$00D9-$00F2 LDTB1 High byte of pointers to each line in screen memory (25 bytes)
|
||||
|
||||
Values:
|
||||
|
||||
* $00-$7F: Pointer high byte.
|
||||
* $80-$FF: No pointer, line is an extension of previous line on screen.
|
||||
|
||||
$00F3-$00F4 USER Pointer to current line in Color RAM.
|
||||
|
||||
$00F5-$00F6 KEYTAB Pointer to current conversion table during conversion from keyboard matrix codes to PETSCII codes.
|
||||
|
||||
$00F7-$00F8 RIBUF Pointer to RS232 input buffer
|
||||
|
||||
Values:
|
||||
|
||||
* $0000-$00FF: No buffer defined, a new buffer must be allocated upon RS232 input.
|
||||
* $0100-$FFFF: Buffer pointer.
|
||||
|
||||
$00F9-$00FA ROBUF Pointer to RS232 output buffer
|
||||
|
||||
Values:
|
||||
|
||||
* $0000-$00FF: No buffer defined, a new buffer must be allocated upon RS232 output.
|
||||
* $0100-$FFFF: Buffer pointer.
|
||||
|
||||
$00FB-$00FE FREKZP Unused (4 bytes).
|
||||
|
||||
$00FF-$010A BASZPT Buffer for conversion from floating point to string (12 bytes.)
|
||||
|
||||
$0100-$01FF Processor stack. Also used for storing data related to FOR and GOSUB.
|
||||
|
||||
$0100-$013D BAD Pointers to bytes read with error during datasette input (62 bytes, 31 entries).
|
||||
|
||||
$0200-$0258 BUF Input buffer, storage area for data read from screen (89 bytes).
|
||||
|
||||
$0259-$0262 LAT Logical numbers assigned to files (10 bytes, 10 entries).
|
||||
|
||||
$0263-$026C FAT Device numbers assigned to files (10 bytes, 10 entries).
|
||||
|
||||
$026D-$0276 SAT Secondary addresses assigned to files (10 bytes, 10 entries).
|
||||
|
||||
$0277-$0280 KEYD Keyboard buffer (10 bytes, 10 entries).
|
||||
|
||||
$0281-$0282 MEMSTR Pointer to beginning of BASIC area after memory test.
|
||||
|
||||
Default: $0800, 2048.
|
||||
|
||||
$0283-$0284 MEMSIZ Pointer to end of BASIC area after memory test.
|
||||
|
||||
Default: $A000, 40960.
|
||||
|
||||
$0285 TIMOUT Unused. (Serial bus timeout.)
|
||||
|
||||
$0286 COLOR Current color, cursor color
|
||||
|
||||
Values: $00-$0F, 0-15.
|
||||
|
||||
$0287 GDCOL Color of character under cursor
|
||||
|
||||
Values: $00-$0F, 0-15.
|
||||
|
||||
$0288 HIBASE High byte of pointer to screen memory for screen input/output.
|
||||
|
||||
Default: $04, $0400, 1024.
|
||||
|
||||
$0289 XMAX Maximum length of keyboard buffer
|
||||
|
||||
Values:
|
||||
|
||||
* $00, 0: No buffer.
|
||||
* $01-$0F, 1-15: Buffer size.
|
||||
|
||||
$028A RPTFLG Keyboard repeat switch
|
||||
|
||||
Bits:
|
||||
|
||||
* Bits #6-#7:
|
||||
* %00 = Only cursor up/down, cursor left/right, Insert/Delete and Space repeat
|
||||
* %01 = No key repeats
|
||||
* %1x = All keys repeat.
|
||||
|
||||
$028B KOUNT Delay counter during repeat sequence, for delaying between successive repeats
|
||||
|
||||
Values:
|
||||
|
||||
* $00, 0: Must repeat key.
|
||||
* $01-$04, 1-4: Delay repetition.
|
||||
|
||||
$028C DELAY Repeat sequence delay counter, for delaying before first repetition
|
||||
|
||||
Values:
|
||||
|
||||
* $00, 0: Must start repeat sequence.
|
||||
* $01-$10, 1-16: Delay repeat sequence.
|
||||
|
||||
$028D SHFLAG Shift key indicator
|
||||
|
||||
Bits:
|
||||
|
||||
* Bit #0: 1 = One or more of left Shift, right Shift or Shift Lock is currently being pressed or locked.
|
||||
* Bit #1: 1 = Commodore is currently being pressed.
|
||||
* Bit #2: 1 = Control is currently being pressed.
|
||||
|
||||
$028E LSTSHF Previous value of shift key indicator
|
||||
|
||||
Bits:
|
||||
|
||||
* Bit #0: 1 = One or more of left Shift, right Shift or Shift Lock was pressed or locked at the time of previous check.
|
||||
* Bit #1: 1 = Commodore was pressed at the time of previous check.
|
||||
* Bit #2: 1 = Control was pressed at the time of previous check.
|
||||
|
||||
$028F-$0290 KEYLOG Execution address of routine that, based on the status of shift keys, sets the pointer at memory address $00F5-$00F6 to the appropriate conversion table for converting keyboard matrix codes to PETSCII codes.
|
||||
|
||||
Default: $EB48.
|
||||
|
||||
$0291 MODE Commodore-Shift switch
|
||||
|
||||
Bits:
|
||||
|
||||
* Bit #7: 0 = Commodore-Shift is disabled; 1 = Commodore-Shift is enabled, the key combination will toggle between the uppercase/graphics and lowercase/uppercase character set.
|
||||
|
||||
$0292 AUTODN Scroll direction switch during scrolling the screen
|
||||
|
||||
Values:
|
||||
|
||||
* $00: Insertion of line before current line, current line and all lines below it must be scrolled 1 line downwards.
|
||||
* $01-$FF: Bottom of screen reached, complete screen must be scrolled 1 line upwards.
|
||||
|
||||
$0293 M51CTR RS232 control register
|
||||
|
||||
Bits:
|
||||
|
||||
* Bits #0-#3: Baud rate, transfer speed. Values:
|
||||
* %0000: User specified.
|
||||
* %0001: 50 bit/s.
|
||||
* %0010: 75 bit/s.
|
||||
* %0011: 110 bit/s.
|
||||
* %0100: 150 bit/s.
|
||||
* %0101: 300 bit/s.
|
||||
* %0110: 600 bit/s.
|
||||
* %0111: 1200 bit/s.
|
||||
* %1000: 2400 bit/s.
|
||||
* %1001: 1800 bit/s.
|
||||
* %1010: 2400 bit/s.
|
||||
* %1011: 3600 bit/s.
|
||||
* %1100: 4800 bit/s.
|
||||
* %1101: 7200 bit/s.
|
||||
* %1110: 9600 bit/s.
|
||||
* %1111: 19200 bit/s.
|
||||
* Bits #5-#6: Byte size, number of data bits per byte; %00 = 8; %01 = 7, %10 = 6; %11 = 5.
|
||||
* Bit #7: Number of stop bits; 0 = 1 stop bit; 1 = 2 stop bits.
|
||||
|
||||
$0294 M51CDR RS232 command register
|
||||
|
||||
Bits:
|
||||
|
||||
* Bit #0: Synchronization type; 0 = 3 lines; 1 = X lines.
|
||||
* Bit #4: Transmission type; 0 = Duplex; 1 = Half duplex.
|
||||
* Bits #5-#7: Parity mode. Values:
|
||||
* %xx0: No parity check, bit #7 does not exist.
|
||||
* %001: Odd parity.
|
||||
* %011: Even parity.
|
||||
* %101: No parity check, bit #7 is always 1.
|
||||
* %111: No parity check, bit #7 is always 0.
|
||||
|
||||
$0295-$0296 M51AJB Default value of RS232 output timer, based on baud rate
|
||||
|
||||
(Must be filled with actual value before RS232 input/output if baud rate is "user specified" in RS232 control register, memory address $0293.)
|
||||
|
||||
|
||||
$0297 RSSTAT Value of ST variable, device status for RS232 input/output
|
||||
|
||||
Bits:
|
||||
|
||||
* Bit #0: 1 = Parity error occurred.
|
||||
* Bit #1: 1 = Frame error, a stop bit with the value of 0, occurred.
|
||||
* Bit #2: 1 = Input buffer underflow occurred, too much data has arrived but it has not been read from the buffer in time.
|
||||
* Bit #3: 1 = Input buffer is empty, nothing to read.
|
||||
* Bit #4: 0 = Sender is Clear To Send; 1 = Sender is not ready to send data to receiver.
|
||||
* Bit #6: 0 = Receiver reports Data Set Ready; 1 = Receiver is not ready to receive data.
|
||||
* Bit #7: 1 = Carrier loss, a stop bit and a data byte both with the value of 0, detected.
|
||||
|
||||
$0298 BITNUM RS232 byte size, number of data bits per data byte, default value for bit counters.
|
||||
|
||||
$0299-$029A BAUDOF Default value of RS232 input timer, based on baud rate
|
||||
|
||||
(Calculated automatically from default value of RS232 output timer, at memory address $0295-$0296.)
|
||||
|
||||
$029B RIDBE Offset of byte received in RS232 input buffer.
|
||||
|
||||
$029C RIDBS Offset of current byte in RS232 input buffer.
|
||||
|
||||
$029D RODBS Offset of byte to send in RS232 output buffer.
|
||||
|
||||
$029E RODBE Offset of current byte in RS232 output buffer.
|
||||
|
||||
$029F-$02A0 IRQTMP Temporary area for saving pointer to original interrupt service routine during datasette input output
|
||||
|
||||
Values:
|
||||
|
||||
* $0000-$00FF: No datasette input/output took place yet or original pointer has been already restored.
|
||||
* $0100-$FFFF: Original pointer, datasette input/output currently in progress.
|
||||
|
||||
$02A1 ENABL Temporary area for saving original value of CIA#2 interrupt control register, at memory address $DD0D, during RS232 input/output.
|
||||
|
||||
$02A2 CASTON Temporary area for saving original value of CIA#1 timer #1 control register, at memory address $DC0E, during datasette input/output.
|
||||
|
||||
$02A3-$02A4 Unknown.
|
||||
|
||||
$02A5 LINTMP Number of line currently being scrolled during scrolling the screen.
|
||||
|
||||
$02A6 PALNTS PAL/NTSC switch, for selecting RS232 baud rate from the proper table
|
||||
|
||||
Values:
|
||||
|
||||
* $00: NTSC.
|
||||
* $01: PAL.
|
||||
|
||||
$02A7-$02FF Unused (89 bytes).
|
||||
|
||||
$0300-$0301 IERROR Execution address of warm reset, displaying optional BASIC error message and entering BASIC idle loop.
|
||||
|
||||
Default: $E38B.
|
||||
|
||||
$0302-$0303 IMAIN Execution address of BASIC idle loop.
|
||||
|
||||
Default: $A483.
|
||||
|
||||
$0304-$0305 ICRNCH Execution address of BASIC line tokenizater routine.
|
||||
|
||||
Default: $A57C.
|
||||
|
||||
$0306-$0307 IQPLOP Execution address of BASIC token decoder routine.
|
||||
|
||||
Default: $A71A.
|
||||
|
||||
$0308-$0309 IGONE Execution address of BASIC instruction executor routine.
|
||||
|
||||
Default: $A7E4.
|
||||
|
||||
$030A-$030B IEVAL Execution address of routine reading next item of BASIC expression.
|
||||
|
||||
Default: $AE86.
|
||||
|
||||
$030C SAREG Default value of register A for SYS.
|
||||
Value of register A after SYS.
|
||||
|
||||
$030D SXREG Default value of register X for SYS.
|
||||
Value of register X after SYS.
|
||||
|
||||
$030E SYREG Default value of register Y for SYS.
|
||||
Value of register Y after SYS.
|
||||
|
||||
$030F SPREG Default value of status register for SYS.
|
||||
Value of status register after SYS.
|
||||
|
||||
$0310-$0312 USRPOK JMP ABS machine instruction, jump to USR() function.
|
||||
|
||||
$0311-$0312 USRADD Execution address of USR() function.
|
||||
|
||||
$0313 Unused.
|
||||
|
||||
$0314-$0315 CINV Execution address of interrupt service routine.
|
||||
|
||||
Default: $EA31.
|
||||
|
||||
$0316-$0317 CBINV Execution address of BRK service routine.
|
||||
|
||||
Default: $FE66.
|
||||
|
||||
$0318-$0319 NMINV Execution address of non-maskable interrupt service routine.
|
||||
|
||||
Default: $FE47.
|
||||
|
||||
$031A-$031B IOPEN Execution address of OPEN, routine opening files.
|
||||
|
||||
Default: $F34A.
|
||||
|
||||
$031C-$031D ICLOSE Execution address of CLOSE, routine closing files.
|
||||
|
||||
Default: $F291.
|
||||
|
||||
$031E-$031F ICHKIN Execution address of CHKIN, routine defining file as default input.
|
||||
|
||||
Default: $F20E.
|
||||
|
||||
$0320-$0321 ICKOUT Execution address of CHKOUT, routine defining file as default output.
|
||||
|
||||
Default: $F250.
|
||||
|
||||
$0322-$0323 ICLRCH Execution address of CLRCHN, routine initializating input/output.
|
||||
|
||||
Default: $F333.
|
||||
|
||||
$0324-$0325 IBASIN Execution address of CHRIN, data input routine, except for keyboard and RS232 input.
|
||||
|
||||
Default: $F157.
|
||||
|
||||
$0326-$0327 IBSOUT Execution address of CHROUT, general purpose data output routine.
|
||||
|
||||
Default: $F1CA.
|
||||
|
||||
$0328-$0329 ISTOP Execution address of STOP, routine checking the status of Stop key indicator, at memory address $0091.
|
||||
|
||||
Default: $F6ED.
|
||||
|
||||
$032A-$032B IGETIN Execution address of GETIN, general purpose data input routine.
|
||||
|
||||
Default: $F13E.
|
||||
|
||||
$032C-$032D ICLALL Execution address of CLALL, routine initializing input/output and clearing all file assignment tables.
|
||||
|
||||
Default: $F32F.
|
||||
|
||||
$032E-$032F USRCMD Unused.
|
||||
|
||||
Default: $FE66.
|
||||
|
||||
$0330-$0331 ILOAD Execution address of LOAD, routine loading files.
|
||||
|
||||
Default: $F4A5.
|
||||
|
||||
$0332-$0333 ISAVE Execution address of SAVE, routine saving files.
|
||||
|
||||
Default: $F5ED.
|
||||
|
||||
$0334-$033B Unused (8 bytes).
|
||||
|
||||
$033C-$03FB TBUFFR Datasette buffer (192 bytes).
|
||||
|
||||
$03FC-$03FF Unused (4 bytes).
|
||||
|
|
@ -1,449 +0,0 @@
|
|||
#!/usr/bin/python3
|
||||
|
||||
import re, os
|
||||
import pprint
|
||||
import markdown
|
||||
|
||||
filenames = [
|
||||
'c64mem_mapc64.txt',
|
||||
'c64mem_64er.txt',
|
||||
'c64mem_64intern.txt',
|
||||
'c64mem_sta.txt',
|
||||
'c64mem_src.txt',
|
||||
'c64mem_prg.txt',
|
||||
'c64mem_64map.txt',
|
||||
'c64mem_jb.txt',
|
||||
]
|
||||
names = [
|
||||
'Mapping the Commodore 64',
|
||||
'64\'er [German]',
|
||||
'Data Becker [German]',
|
||||
'Joe Forster/STA',
|
||||
'Microsoft/Commodore Source',
|
||||
'Programmer\'s Reference Guide',
|
||||
'64map',
|
||||
'Jim Butterfield',
|
||||
]
|
||||
links = [
|
||||
'http://unusedino.de/ec64/technical/project64/mapping_c64.html',
|
||||
'https://archive.org/details/64er_sonderheft_1986_07/page/n6/mode/2up',
|
||||
'https://www.pagetable.com/?p=1015',
|
||||
'http://www.awsm.de/mem64/',
|
||||
'https://github.com/mist64/cbmsrc',
|
||||
'http://www.zimmers.net/cbmpics/cbm/c64/c64prg.txt',
|
||||
'http://unusedino.de/ec64/technical/project64/memory_maps.html',
|
||||
'https://www.atarimagazines.com/compute/issue29/394_1_COMMODORE_64_MEMORY_MAP.php',
|
||||
]
|
||||
descriptions = [
|
||||
'Reference from <i>Mapping the Commodore 64</i> by Sheldon Leemon, ISBN 0-942386-23-X.',
|
||||
'German-language reference from <i>Memory Map mit Wandervorschlägen</i> by Dr. H. Hauck, in 64\'er Sonderheft 1986/07.',
|
||||
'German-language reference from <i>Das neue Commodore-64-intern-Buch</i> by Data Becker, ISBN 3890113079.',
|
||||
'Reference by Joe Forster/STA, with awsm\'s changes applied.',
|
||||
'Comments from the original M6502 BASIC source by Microsoft and the original C64 KERNAL source by Commodore',
|
||||
'Reference from <i>Commodore 64 Programmer\'s Reference Guide</i>.',
|
||||
'Reference as found in "Commodore_64_Memory_Maps.txt" by anonymous.',
|
||||
'Reference by Jim Butterfield in COMPUTE! #29 (October 1982).',
|
||||
]
|
||||
|
||||
|
||||
def cross_reference(string):
|
||||
hex_numbers = re.findall(r'\$[0-9A-F][0-9A-F][0-9A-F][0-9A-F]', string)
|
||||
for hex_number in hex_numbers:
|
||||
dec_number = int(hex_number[1:], 16)
|
||||
if dec_number < 0x0400:
|
||||
if dec_number < 0x100:
|
||||
formatted_hex_number = '${:02X}'.format(dec_number)
|
||||
else:
|
||||
formatted_hex_number = '${:04X}'.format(dec_number)
|
||||
string = string.replace(hex_number, '<a href="#' + '{:04X}'.format(dec_number) + '">' + formatted_hex_number + '</a>')
|
||||
elif (dec_number >= 0xa000 and dec_number <= 0xbfff) or (dec_number >= 0xe000 and dec_number <= 0xffff):
|
||||
string = string.replace(hex_number, '<a href="../c64disasm/#' + '{:04X}'.format(dec_number) + '">' + hex_number + '</a>')
|
||||
|
||||
return string
|
||||
|
||||
|
||||
|
||||
f = os.popen('git log -1 --pretty=format:%h .')
|
||||
revision = f.read()
|
||||
f = os.popen('git log -1 --date=short --pretty=format:%cd .')
|
||||
date = f.read()
|
||||
|
||||
data = []
|
||||
linenumber = []
|
||||
address = []
|
||||
for filename in filenames:
|
||||
d = []
|
||||
for f in filename.split(';'):
|
||||
d += [line.rstrip() for line in open(f)]
|
||||
data.append(d)
|
||||
linenumber.append(0)
|
||||
address.append(0)
|
||||
files = len(filenames)
|
||||
|
||||
for i in range(0, files):
|
||||
while True:
|
||||
line = data[i][linenumber[i]]
|
||||
if len(line) > 0 and line[0] == '$':
|
||||
break
|
||||
linenumber[i] = linenumber[i] + 1
|
||||
|
||||
print('<meta http-equiv="Content-type" content="text/html; charset=utf-8" />')
|
||||
print('<html>')
|
||||
print('<head>')
|
||||
print('<title>Memory Map | Ultimate C64 Reference</title>')
|
||||
print('')
|
||||
print('<script language="javascript">')
|
||||
print(' window.onload = init;')
|
||||
print(' function init() {')
|
||||
print(' var tbl = document.getElementById("disassembly_table");')
|
||||
print(' for (var i = 0; i < ' + str(len(filenames)) + '; i++) {')
|
||||
print(' var key = "com.pagetable.c64mem.column_" + i;')
|
||||
print(' var element_name = "checkbox_" + i;')
|
||||
print(' var checked = localStorage.getItem(key) != "hidden";')
|
||||
print(' document.getElementById(element_name).checked = checked;')
|
||||
print(' hideCol(i, checked);')
|
||||
print(' }')
|
||||
print(' var key = "com.pagetable.c64mem.column_decimal";')
|
||||
print(' var element_name = "checkbox_decimal";')
|
||||
print(' var visible = localStorage.getItem(key) == "visible";')
|
||||
print(' document.getElementById(element_name).checked = visible;')
|
||||
print(' toggleDecimal(visible);')
|
||||
print(' }')
|
||||
print(' function toggleDecimal(visible) {')
|
||||
print(' var tbl = document.getElementById("disassembly_table");')
|
||||
print(' for (var i = 0; i < tbl.rows.length; i++) {')
|
||||
print(' tbl.rows[i].cells[2].style.display = visible ? "" : "none";')
|
||||
print(' }')
|
||||
print(' var key = "com.pagetable.c64mem.column_decimal";')
|
||||
print(' var cnt = document.getElementById("disassembly_container");')
|
||||
print(' if (visible) {')
|
||||
print(' cnt.className = "disassembly_container_with_dec";')
|
||||
print(' localStorage.setItem(key, "visible");')
|
||||
print(' } else {')
|
||||
print(' cnt.className = "disassembly_container_no_dec";')
|
||||
print(' localStorage.removeItem(key);')
|
||||
print(' }')
|
||||
print(' }')
|
||||
print(' function hideCol(col, checked) {')
|
||||
print(' var tbl = document.getElementById("disassembly_table");')
|
||||
print(' for (var i = 0; i < tbl.rows.length; i++) {')
|
||||
print(' tbl.rows[i].cells[col+3].style.display = checked ? "" : "none";') # data columns start at index 3
|
||||
print(' }')
|
||||
print(' var key = "com.pagetable.c64mem.column_" + col;')
|
||||
print(' if (checked) {')
|
||||
print(' localStorage.removeItem(key);')
|
||||
print(' } else {')
|
||||
print(' localStorage.setItem(key, "hidden");')
|
||||
print(' }')
|
||||
print(' }')
|
||||
print(' function openAll() {')
|
||||
print(' var elems = document.getElementsByTagName("details");')
|
||||
print(' document.getElementById("toggle_details_button").innerHTML = "Hide All Details";')
|
||||
print(' document.getElementById("toggle_details_button").setAttribute("onClick", "javascript: closeAll();");')
|
||||
print('')
|
||||
print(' for (let item of elems) {')
|
||||
print(' item.setAttribute("open", true);')
|
||||
print(' }')
|
||||
print(' }')
|
||||
print('')
|
||||
print(' function closeAll() { ')
|
||||
print(' var elems = document.getElementsByTagName("details");')
|
||||
print(' document.getElementById("toggle_details_button").setAttribute("onClick", "javascript: openAll();" );')
|
||||
print(' document.getElementById("toggle_details_button").innerHTML = "Expand All Details"; ')
|
||||
print(' ')
|
||||
print(' for (let item of elems) {')
|
||||
print(' item.removeAttribute("open");')
|
||||
print(' }')
|
||||
print(' }')
|
||||
print('</script>')
|
||||
print('')
|
||||
|
||||
print('<link rel="stylesheet" href="../style.css">')
|
||||
|
||||
address_width=6.4
|
||||
label_width=4
|
||||
decimal_width=5
|
||||
|
||||
print('<style type="text/css">')
|
||||
print('')
|
||||
print('div.disassembly_container_with_dec {')
|
||||
print(' padding: 1em 0em 1em ' + str(address_width + label_width + decimal_width + 1.6) + 'em;')
|
||||
print(' overflow: scroll;')
|
||||
print('}')
|
||||
print('')
|
||||
print('div.disassembly_container_no_dec {')
|
||||
print(' padding: 1em 0em 1em ' + str(address_width + label_width + 0.9) + 'em;')
|
||||
print(' overflow: scroll;')
|
||||
print('}')
|
||||
print('')
|
||||
print('table.disassembly_table>tbody>tr>td, table.disassembly_table>tbody>tr>th.top_row {')
|
||||
print(' min-width: 30em;')
|
||||
print(' max-width: 40em;')
|
||||
print('}')
|
||||
print('')
|
||||
print('table.disassembly_table th.left_column {')
|
||||
print(' width: '+ str(address_width) +'em;')
|
||||
print('}')
|
||||
print('')
|
||||
print('table.disassembly_table th.label_column {')
|
||||
print(' width: ' + str(label_width) +'em;')
|
||||
print(' left: ' + str(address_width + 3) + 'em;')
|
||||
print(' z-index: 12;')
|
||||
print(' font-family: monospace;')
|
||||
print(' text-align: center;')
|
||||
print(' color: yellow;')
|
||||
print('}')
|
||||
print('')
|
||||
print('table.disassembly_table th.decimal_column {')
|
||||
print(' width: ' + str(decimal_width) + 'em;')
|
||||
print(' left: ' + str(address_width + label_width + 1.2) + 'em;')
|
||||
print(' z-index: 13;')
|
||||
print('}')
|
||||
print('')
|
||||
print('details {')
|
||||
print(' font-family: serif;')
|
||||
print('}')
|
||||
print('summary {')
|
||||
print(' font-family: Helvetica;')
|
||||
print('}')
|
||||
print('')
|
||||
print('</style>')
|
||||
print('</head>')
|
||||
print('<body>')
|
||||
|
||||
# http://tholman.com/github-corners/
|
||||
print('<a href="https://github.com/mist64/c64ref" class="github-corner" aria-label="View source on GitHub"><svg width="80" height="80" viewBox="0 0 250 250" style="fill:var(--main-color); color:#fff; position: absolute; top: 0; border: 0; right: 0;" aria-hidden="true"><path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path></svg></a><style>.github-corner:hover .octo-arm{animation:octocat-wave 560ms ease-in-out}@keyframes octocat-wave{0%,100%{transform:rotate(0)}20%,60%{transform:rotate(-25deg)}40%,80%{transform:rotate(10deg)}}@media (max-width:500px){.github-corner:hover .octo-arm{animation:none}.github-corner .octo-arm{animation:octocat-wave 560ms ease-in-out}}</style>')
|
||||
|
||||
print('<div class="topnav">')
|
||||
print(' <h1>Ultimate Commodore 64 Reference</h1> ')
|
||||
#print(' <a href="#">KERNAL API</a><!-- kernal/ -->')
|
||||
print(' <a href="../c64disasm/">ROM Disassembly</a><!-- c64disasm/ -->')
|
||||
print(' <a class="active" href="../c64mem/">Memory Map</a><!-- c64mem/ -->')
|
||||
#print(' <a href="#">I/O Map</a><!-- c64io/ -->')
|
||||
#print(' <a href="#">6502 CPU</a><!-- 6502/ -->')
|
||||
print('</div>')
|
||||
|
||||
print('<div class="body">')
|
||||
print('<h1>C64 Memory Map</h1>')
|
||||
|
||||
print('<p><i>by <a href="http://www.pagetable.com/">Michael Steil</a>, <a href="https://github.com/mist64/c64ref">github.com/mist64/c64ref</a>. Revision ' + revision + ', ' + date + '</i></p>')
|
||||
|
||||
print('<b>This allows you to view different commentaries side-by-side. You can enable/disable individual columns:</b><br/><br/>')
|
||||
print('<table class="checkbox_table">')
|
||||
for i in range(0, len(filenames)):
|
||||
print('<tr><td><input type="checkbox" id="checkbox_' + str(i) + '" checked onclick="hideCol(' + str(i) + ', document.getElementById(\'checkbox_' + str(i) + '\').checked);" /></td><td style="white-space: nowrap;"><b><a href="' + links[i] + '">' + names[i] + '</a></b><td>' + descriptions[i] + '</td></tr>')
|
||||
print('</table>')
|
||||
|
||||
print('<p>')
|
||||
print('<input type="checkbox" id="checkbox_decimal" name="checkbox_decimal" onclick="toggleDecimal(document.getElementById(\'checkbox_decimal\').checked);">')
|
||||
print('<label for="checkbox_decimal">Show Decimal Address</label></input>')
|
||||
print('<br />')
|
||||
print('<button id="toggle_details_button" onclick="closeAll()">Hide All Details</button>')
|
||||
print('</p>')
|
||||
|
||||
print('<div class="disassembly_container_no_dec" id="disassembly_container">')
|
||||
print('<table id="disassembly_table" class="disassembly_table">')
|
||||
|
||||
print('<tr>')
|
||||
print('<th class="left_column">Address</th>')
|
||||
print('<th class="label_column">Symbol</th>')
|
||||
print('<th class="decimal_column">Decimal</th>')
|
||||
for i in range(0, files):
|
||||
print('<th class="top_row">' + names[i] + '</th>')
|
||||
print('</tr>')
|
||||
|
||||
count = 0
|
||||
last_address1 = None
|
||||
last_address2 = None
|
||||
while(True):
|
||||
count += 1
|
||||
# if count > 80:
|
||||
# break
|
||||
|
||||
# make linenumber[] point to next line for all files
|
||||
for i in range(0, files):
|
||||
if linenumber[i] >= len(data[i]):
|
||||
continue
|
||||
while len(data[i][linenumber[i]]) > 0 and (data[i][linenumber[i]][0] == '-' or data[i][linenumber[i]][0] == '#'):
|
||||
linenumber[i] = linenumber[i] + 1
|
||||
|
||||
list_address1 = []
|
||||
list_address2 = []
|
||||
list_symbol = []
|
||||
for i in range(0, files):
|
||||
if linenumber[i] >= len(data[i]):
|
||||
continue
|
||||
line = data[i][linenumber[i]]
|
||||
address1 = line[1:5]
|
||||
address1 = int(address1, 16)
|
||||
address2 = line[7:11]
|
||||
if len(address2.rstrip()) != 0:
|
||||
address2 = int(address2, 16)
|
||||
else:
|
||||
address2 = None
|
||||
symbol = line[13:19].rstrip()
|
||||
list_address1.append(address1)
|
||||
list_address2.append(address2)
|
||||
list_symbol.append(symbol)
|
||||
|
||||
# reached end of all files?
|
||||
if len(list_address1) == 0:
|
||||
break
|
||||
|
||||
# the next address is the lowest one from all source
|
||||
address1 = min(list_address1)
|
||||
|
||||
# the longest range wins
|
||||
address2 = None
|
||||
symbol = None
|
||||
good_symbols = []
|
||||
for i in range(0, len(list_address1)):
|
||||
if list_address1[i] == address1 and (address2 == None or (list_address2[i] != None and list_address2[i] > address2)):
|
||||
address2 = list_address2[i]
|
||||
|
||||
# get symbols of longest range
|
||||
for i in range(0, len(list_address1)):
|
||||
if list_address1[i] == address1 and list_address2[i] == address2 and list_symbol[i] != '':
|
||||
good_symbols.append(list_symbol[i])
|
||||
#print('xxx', address1, address2, good_symbols)
|
||||
|
||||
if len(good_symbols) != 0:
|
||||
symbol = good_symbols[0]
|
||||
else:
|
||||
symbol = ''
|
||||
|
||||
print('<tr>')
|
||||
|
||||
# print address
|
||||
anchors = ''
|
||||
if address2 is not None:
|
||||
r = range(address1, address2 + 1)
|
||||
else:
|
||||
r = range(address1, address1 + 1)
|
||||
for address in r:
|
||||
anchors += '<a name="{:04X}"/>'.format(address)
|
||||
if address1 == last_address1 and address2 == last_address2:
|
||||
print('<th class="left_column" style="visibility:hidden;"> ' + anchors + ' </th>')
|
||||
else:
|
||||
hex_range = '${:04X}'.format(address1)
|
||||
if address2 != None:
|
||||
hex_range += '-${:04X}'.format(address2)
|
||||
print('<th class="left_column"> ' + anchors + hex_range + ' </th>')
|
||||
|
||||
# print symbol
|
||||
if len(symbol) == 0:
|
||||
print('<th class="label_column" style="visibility:hidden;"> </th>')
|
||||
else:
|
||||
print('<th class="label_column">' + symbol + ' <a name="' + symbol + '"/> </th>')
|
||||
|
||||
# print decimal
|
||||
if address1 == last_address1 and address2 == last_address2:
|
||||
print('<th class="decimal_column" style="visibility:hidden;"> </th>')
|
||||
else:
|
||||
dec_range = str(address1)
|
||||
if address2 != None:
|
||||
dec_range += '-' + str(address2)
|
||||
print('<th class="decimal_column"> ' + dec_range + ' </th>')
|
||||
|
||||
last_address1 = address1
|
||||
last_address2 = address2
|
||||
|
||||
for i in range(0, files):
|
||||
print('<td>')
|
||||
headings = []
|
||||
comments = []
|
||||
has_seen_blank_line = False
|
||||
is_first_line = True
|
||||
while True:
|
||||
if linenumber[i] >= len(data[i]):
|
||||
break
|
||||
|
||||
line = data[i][linenumber[i]]
|
||||
|
||||
if line.startswith('$'):
|
||||
if not is_first_line:
|
||||
# next address; stop here
|
||||
break
|
||||
|
||||
# compare whether this address matches
|
||||
cmp_address1 = line[1:5]
|
||||
cmp_address1 = int(cmp_address1, 16)
|
||||
cmp_address2 = line[7:11]
|
||||
if len(cmp_address2.rstrip()) != 0:
|
||||
cmp_address2 = int(cmp_address2, 16)
|
||||
else:
|
||||
cmp_address2 = None
|
||||
cmp_symbol = line[13:19].rstrip()
|
||||
if cmp_address1 != address1 or cmp_address2 != address2 or (cmp_symbol != symbol and cmp_symbol != ''):
|
||||
break
|
||||
|
||||
is_first_line = False
|
||||
comment = line[21:]
|
||||
# print(comment)
|
||||
|
||||
if not has_seen_blank_line:
|
||||
if len(comment.lstrip()) == 0:
|
||||
has_seen_blank_line = True
|
||||
else:
|
||||
headings.append(comment)
|
||||
else:
|
||||
scomment = comment.lstrip()
|
||||
comment = comment + '\n'
|
||||
comments.append(comment)
|
||||
|
||||
linenumber[i] += 1
|
||||
|
||||
while len(comments) > 0 and comments[-1] == '\n':
|
||||
comments = comments[0:-1]
|
||||
|
||||
#print('xxx',headings,comments)
|
||||
|
||||
is_collapsible = len(comments) and not (len(comments) == 1 and comments[0].isspace())
|
||||
if is_collapsible:
|
||||
print('<details open>')
|
||||
|
||||
if len(headings) or is_collapsible:
|
||||
print('<b>')
|
||||
all_text = ''
|
||||
if is_collapsible:
|
||||
print('<summary>')
|
||||
if not len(headings):
|
||||
print('…')
|
||||
previous_heading = ''
|
||||
for heading in headings:
|
||||
if previous_heading.endswith('.'):
|
||||
heading = '<br/>' + heading
|
||||
html_heading = markdown.markdown(heading)
|
||||
html_heading.replace('<p>', '')
|
||||
html_heading.replace('</p>', '')
|
||||
all_text += heading + ' '
|
||||
previous_heading = heading
|
||||
all_text = cross_reference(all_text)
|
||||
print(all_text)
|
||||
print('</b>')
|
||||
if is_collapsible:
|
||||
print('</summary>')
|
||||
else:
|
||||
print(' ')
|
||||
|
||||
if len(comments):
|
||||
all_text = ''
|
||||
for comment in comments:
|
||||
all_text += comment
|
||||
all_text = markdown.markdown(all_text, extensions=['tables', 'sane_lists'])
|
||||
all_text = cross_reference(all_text)
|
||||
print(all_text)
|
||||
else:
|
||||
print(' ')
|
||||
|
||||
if is_collapsible:
|
||||
print('</details>')
|
||||
|
||||
print('</td>')
|
||||
print('</tr>')
|
||||
|
||||
print('</table>')
|
||||
print('</div>')
|
||||
print('</div>')
|
||||
print('</body>')
|
||||
print('</html>')
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import os
|
||||
import pprint
|
||||
|
||||
with open('c64mem_64intern.txt', 'r') as f:
|
||||
lines = f.read().split('\n')
|
||||
|
||||
with open('symbols.txt', 'r') as f:
|
||||
sym = f.read().split('\n')
|
||||
|
||||
symbols = {}
|
||||
|
||||
for s in sym:
|
||||
if not s.startswith('$'):
|
||||
continue
|
||||
address = s[1:5]
|
||||
name = s[6:12]
|
||||
symbols[address] = name
|
||||
|
||||
#pprint.pprint(symbols)
|
||||
|
||||
for line in lines:
|
||||
if line.startswith('-') or line.startswith('#') or len(line) == 0:
|
||||
print(line)
|
||||
continue
|
||||
|
||||
if not line.startswith('$'):
|
||||
print(line)
|
||||
continue
|
||||
address = line[0:13]
|
||||
start_address = line[1:5]
|
||||
description = line[21:]
|
||||
if start_address in symbols:
|
||||
symbol = (symbols[start_address] + " ")[:8]
|
||||
else:
|
||||
symbol = " "
|
||||
print(address + symbol + description)
|
||||
|
||||
|
|
@ -1,207 +0,0 @@
|
|||
$0000 D6510
|
||||
$0001 R6510
|
||||
#0002 # unnamed in Programmer's Reference Manual; part of "BLANK0" 3 (!) byte register area in BASIC source
|
||||
$0003 ADRAY1
|
||||
$0005 ADRAY2
|
||||
$0007 CHARAC # also INTEGR
|
||||
$0008 ENDCHR
|
||||
$0009 TRMPOS
|
||||
$000A VERCK
|
||||
$000B COUNT
|
||||
$000C DIMFLG
|
||||
$000D VALTYP
|
||||
$000E INTFLG
|
||||
$000F GARBFL
|
||||
$0010 SUBFLG
|
||||
$0011 INPFLG
|
||||
$0012 TANSGN
|
||||
$0013 CHANNL # unnamed in Programmer's Reference Manual
|
||||
$0014 LINNUM
|
||||
$0016 TEMPPT
|
||||
$0017 LASTPT
|
||||
$0019 TEMPST
|
||||
$0022 INDEX
|
||||
$0022 INDEX1
|
||||
$0024 INDEX2
|
||||
$0026 RESHO
|
||||
$002B TXTTAB
|
||||
$002D VARTAB
|
||||
$002F ARYTAB
|
||||
$0031 STREND
|
||||
$0033 FRETOP
|
||||
$0035 FRESPC
|
||||
$0037 MEMSIZ
|
||||
$0039 CURLIN
|
||||
$003B OLDLIN
|
||||
$003D OLDTXT
|
||||
$003F DATLIN
|
||||
$0041 DATPTR
|
||||
$0043 INPPTR
|
||||
$0045 VARNAM
|
||||
$0047 VARPNT
|
||||
$0049 FORPNT
|
||||
$004B OPPTR
|
||||
$004B VARTXT
|
||||
$004D OPMASK
|
||||
$004E DEFPNT
|
||||
$004E TEMPF3
|
||||
$0050 DSCPNT
|
||||
$0053 FOUR6
|
||||
$0054 JMPER
|
||||
$0057 TEMPF1
|
||||
$005C TEMPF2
|
||||
$0061 FAC
|
||||
$0061 FACEXP
|
||||
$0062 FACHO
|
||||
$0066 FACSGN
|
||||
$0067 SGNFLG
|
||||
$0068 BITS
|
||||
$0069 ARGEXP # aka ARG, AFAC, FAC2
|
||||
$006A ARGHO
|
||||
$006E ARGSGN
|
||||
$006F ARISGN
|
||||
$0070 FACOV
|
||||
$0071 FBUFPT
|
||||
$0073 CHRGET
|
||||
$0079 CHRGOT
|
||||
$007A TXTPTR
|
||||
$008B RNDX
|
||||
$0090 STATUS
|
||||
$0091 STKEY
|
||||
$0092 SVXT
|
||||
$0093 VERCK
|
||||
$0094 C3P0
|
||||
$0095 BSOUR
|
||||
$0096 SYNO
|
||||
$0097 XSAV # unnamed in Programmer's Reference Manual
|
||||
$0098 LDTND
|
||||
$0099 DFLTN
|
||||
$009A DFLTO
|
||||
$009B PRTY
|
||||
$009C DPSW
|
||||
$009D MSGFLG
|
||||
$009E PTR1
|
||||
$009F PTR2
|
||||
$00A0 TIME
|
||||
$00A3 PCNTR # unnamed in Programmer's Reference Manual
|
||||
$00A3 R2D2 # unnamed in Programmer's Reference Manual
|
||||
$00A4 BSOUR1 # unnamed in Programmer's Reference Manual
|
||||
$00A4 FIRT # unnamed in Programmer's Reference Manual
|
||||
$00A5 CNTDN
|
||||
$00A6 BUFPT
|
||||
$00A7 INBIT
|
||||
$00A8 BITCI
|
||||
$00A9 RINONE
|
||||
$00AA RIDATA
|
||||
$00AB RIPRTY
|
||||
$00AC SAL
|
||||
$00AE EAL
|
||||
$00B0 CMP0
|
||||
$00B2 TAPE1
|
||||
$00B4 BITTS
|
||||
$00B5 NXTBIT
|
||||
$00B6 RODATA
|
||||
$00B7 FNLEN
|
||||
$00B8 LA
|
||||
$00B9 SA
|
||||
$00BA FA
|
||||
$00BB FNADR
|
||||
$00BD ROPRTY
|
||||
$00BE FSBLK
|
||||
$00BF MYCH
|
||||
$00C0 CAS1
|
||||
$00C1 STAL
|
||||
$00C3 MEMUSS
|
||||
$00C5 LSTX
|
||||
$00C6 NDX
|
||||
$00C7 RVS
|
||||
$00C8 INDX
|
||||
$00C9 LSXP
|
||||
$00CB SFDX
|
||||
$00CC BLNSW
|
||||
$00CD BLNCT
|
||||
$00CE GDBLN
|
||||
$00CF BLNON
|
||||
$00D0 CRSW
|
||||
$00D1 PNT
|
||||
$00D3 PNTR
|
||||
$00D4 QTSW
|
||||
$00D5 LNMX
|
||||
$00D6 TBLX
|
||||
$00D7 DATA # unnamed in Programmer's Reference Manual
|
||||
$00D8 INSRT
|
||||
$00D9 LDTB1
|
||||
$00F3 USER
|
||||
$00F5 KEYTAB
|
||||
$00F7 RIBUF
|
||||
$00F9 ROBUF
|
||||
$00FB FREKZP
|
||||
$00FF BASZPT
|
||||
$0100 BAD
|
||||
$0200 BUF
|
||||
$0259 LAT
|
||||
$0263 FAT
|
||||
$026D SAT
|
||||
$0277 KEYD
|
||||
$0281 MEMSTR
|
||||
$0283 MEMSIZ
|
||||
$0285 TIMOUT
|
||||
$0286 COLOR
|
||||
$0287 GDCOL
|
||||
$0288 HIBASE
|
||||
$0289 XMAX
|
||||
$028A RPTFLG
|
||||
$028B KOUNT
|
||||
$028C DELAY
|
||||
$028D SHFLAG
|
||||
$028E LSTSHF
|
||||
$028F KEYLOG
|
||||
$0291 MODE
|
||||
$0292 AUTODN
|
||||
$0293 M51CTR
|
||||
$0294 M51CDR
|
||||
$0295 M51AJB
|
||||
$0297 RSSTAT
|
||||
$0298 BITNUM
|
||||
$0299 BAUDOF
|
||||
$029B RIDBE
|
||||
$029C RIDBS
|
||||
$029D RODBS
|
||||
$029E RODBE
|
||||
$029F IRQTMP
|
||||
$02A1 ENABL
|
||||
$02A2 CASTON # unnamed in Programmer's Reference Manual
|
||||
$02A3 KIKA26 # unnamed in Programmer's Reference Manual
|
||||
$02A4 STUPID # unnamed in Programmer's Reference Manual
|
||||
$02A5 LINTMP # unnamed in Programmer's Reference Manual
|
||||
$02A6 PALNTS # unnamed in Programmer's Reference Manual
|
||||
$0300 IERROR
|
||||
$0302 IMAIN
|
||||
$0304 ICRNCH
|
||||
$0306 IQPLOP
|
||||
$0308 IGONE
|
||||
$030A IEVAL
|
||||
$030C SAREG
|
||||
$030D SXREG
|
||||
$030E SYREG
|
||||
$030F SPREG
|
||||
$0310 USRPOK
|
||||
$0311 USRADD # from Programmer's Reference Manual; not in KERNAL/BASIC source!
|
||||
$0314 CINV
|
||||
$0316 CBINV
|
||||
$0318 NMINV
|
||||
$031A IOPEN
|
||||
$031C ICLOSE
|
||||
$031E ICHKIN
|
||||
$0320 ICKOUT
|
||||
$0322 ICLRCH
|
||||
$0324 IBASIN
|
||||
$0326 IBSOUT
|
||||
$0328 ISTOP
|
||||
$032A IGETIN
|
||||
$032C ICLALL
|
||||
$032E USRCMD
|
||||
$0330 ILOAD
|
||||
$0332 ISAVE
|
||||
$033C TBUFFR
|
||||
$0400 VICSCN
|
||||
|
|
@ -1,769 +0,0 @@
|
|||
# Texteinschub Nr. 1: Der USR-Befehl
|
||||
|
||||
Hand aufs Herz: Haben Sie USR schon einmal benutzt? Ohne Zweifel gehört dieser Befehl zu den seltenen. Ich will ihn daher hier kurz erläutern. USR hat dieselbe Funktion wie SYS, nämlich aus einem Basic-Programm direkt in ein Maschinenprogramm zu springen und dort solange weiterzufahren, bis mit dem Befehl RTS (entspricht dem Basic-Befehl RETURN) in das Basic-Programm zurückgesprungen wird. Die Sprungadresse in das Maschinenprogramm steht bei SYS gleich hinter dem Befehl.
|
||||
|
||||
Bei USR muß die Adresse zuerst in die Speicherzellen 1 und 2 (aha!!) gePOKEt werden.
|
||||
|
||||
Beispiel - Sprung auf 56524 ($DCCC):
|
||||
|
||||
* mit SYS: `SYS 56524`
|
||||
* mit USR: `POKE 1,204:P0KE 2,220:X=USR(Y)`
|
||||
|
||||
Kein Wunder, daß USR selten benutzt wird. Aber erstens ist er durch das POKEn der Low-/High-Byte-Darstellung aufgebläht und zweitens hat er auch wesentlich mehr Fähigkeiten als SYS.
|
||||
|
||||
Sein Argument, im obigen Beispiel also das »Y«, wird nämlich zuerst in den »Fließkomma-Akkumulator« FAC 1 (Floating Point Accumulator Nr. 1) gebracht, der sich in den Speicherzellen 97 bis 102 ($61 bis $66) befindet. Da wir ihn auf unserer Reise durch den Speicher noch treffen werden, brauche ich jetzt nicht näher darauf einzugehen. Wichtig ist lediglich, daß der Wert von »Y« dann vom angesprungenen Maschinenprogramm verarbeitet werden kann. Das Resultat kommt dann wieder in diesen FAC 1 und steht als Wert von X (siehe Beispiel oben) dem Basic- Programm zur Verfügung.
|
||||
|
||||
Mit USR kann man also Variable ins Maschinenprogramm zur Bearbeitung und zurück transferieren - und das ist der Unterschied zum SYS-Befehl. Ich möchte das an einem kleinen Beispiel demonstrieren. Statt allerdings ein Maschinenprogramm selbst zu schreiben, verwende ich beziehungsweise springe ich auf eine Routine des Betriebssystems, welches Werte des FAC 1 für mathematische Operationen verwendet.
|
||||
|
||||
Als mathematische Operation wähle ich das eingebaute Programm für INT, welches im VC 20 ab Speicherzelle 56524 ($DCCC) steht, im C 64 steht es ab 48332 ($BCCC). Dieses wollen wir verwenden:
|
||||
|
||||
In Zeile 10 definieren wir einen Wert für die Variable X, der in das Maschinenprogramm gebracht werden soll. Mit Zeile 20 bringen wir die Startadresse des Maschinenprogramms in die Speicherzellen 1 und 2.
|
||||
|
||||
Laut Kochrezept teilen wir die Adresse 56524 auf in ein Low- Byte = 204 und ein High-Byte = 220.
|
||||
|
||||
Der Befehl in Zeile 30 löst den ganzen USR-Vorgang aus, Zeile 40 gibt uns das Resultat.
|
||||
|
||||
10 Y=14.35
|
||||
20 POKE l,204:P0KE 2,220 30 X=USR(Y)
|
||||
40 PRINT X
|
||||
|
||||
Hinweis: Entsprechend der anderen Adresse 48332 lautet die Zeile 20 beim C 64:
|
||||
|
||||
20 POKE 785,204:POKE 786,188
|
||||
|
||||
Nach RUN erhalten wirdas Resultat 14, wie das Gesetz für INT es befiehlt. Natürlich hätten wir gleich PRINT INT (14.35) schreiben können, aber ich wollte ja nur demonstrieren. Der eigentliche Wert des USR-Befehls kommt hauptsächlich bei selbstgeschriebenen Maschinenprogrammen zum Zuge.
|
||||
|
||||
Sie können zur Übung im obigen Programm statt INT auch COS verwenden, indem Sie auf die Adresse 57935 ($E261) beziehungsweise beim C 64 auf 57938 ($E264) springen. Der Vergleich mit dem Basic-Befehl COS muß dasselbe Resultat ergeben.
|
||||
|
||||
Wer hat gemerkt, daß wir überhaupt nichts mit der Speicherzelle 0 gemacht haben, obwohl sie doch beim USR angeblich beteiligt ist?
|
||||
|
||||
Sie ist es wirklich, doch ohne unser Zutun. In diese Adresse wird beim Einschalten des Computers die Zahl 76 ($4C) geschrieben. Das ist der Code für den Maschinenbefehl »JMP«, der soviel bedeutet wie GOTO. Bei USR springt nämlich das Programm auf die Speicherzelle 0, findet dort den Sprungbefehl und in den nachfolgenden Zellen 1 und 2 die Sprungadresse - und führt den Sprung auch gleich aus.
|
||||
|
||||
# Texteinschub Nr. 2: Die Low-/High-Byte-Darstellung
|
||||
|
||||
Eine Speicherzelle der kleinen Commodore-Computer VC 20 und C 64 hat eine Länge von 8 Bit = 1 Byte. Mit diesen 8 Bit können Zahlen von 0 bis 255 ($00FF) dargestellt werden. Zur Darstellung von Zahlen über 255 verwenden wir die Low-/High- Byte-Methode.
|
||||
|
||||
Wir hängen einfach zwei Speicherzellen zusammen, mit deren 16 Bit wir Zahlen bis maximal 65535 ($FFFF) darstellen können. Die maximale Zahl 65535 ist übrigens auch die höchste Adresse des gesamten Speichers - was natürlich kein Zufall ist.
|
||||
|
||||
Ich will Ihnen jetzt zeigen, wie eine Dezimalzahl auf zwei 8-Bit- Speicherzellen verteilt wird, und umgekehrt, wie aus 2 Byte eine Dezimalzahl gebildet wird.
|
||||
|
||||
Schauen Sie sich das folgende Beispiel an:
|
||||
|
||||
DEZIMAL 47491
|
||||
DUALZAHL 1011 | 1001 | 1000 | 0011
|
||||
HEX $ B | 9 | 8 | 3
|
||||
HIGH-BYTE 185 | -
|
||||
LOW-BYTE - | 131
|
||||
|
||||
Wir gehen von der Dezimalzahl 47491 aus. Ihre duale Darstellung mit 16 Bit - 1011100110000011 - teilen wir einfach in der Mitte und erhalten damit zwei neue Dual-Zahlen mit je 8 Bit = 1 Byte. Das linke Byte nennen wir »High-Byte«, da es den höheren Teil derGesamtzahl darstellt. Das rechte Byte heißt entsprechend »Low-Byte«.
|
||||
|
||||
Jedes der beiden Bytes kann für sich allein in einer Speicherzelle untergebracht werden, in der natürlich dann der dezimale Wert des Bytes steht.
|
||||
|
||||
In der Tabelle habe ich zur Vollständigkeit noch die hexadezimalen Werte eingefügt, die sehr schön zeigen, daß der Vorteil dieserZahlendarstellung darin liegt, daß jede Einzelziffer der 4-Bit-Dualzahl entspricht, genau so wie jede Zweiergruppe dem Byte (sowohl in Dual-, als auch in Dezimaldarstellung) und die vierstellige Zahl der großen Dezimal- und Dualzahl entspricht.
|
||||
|
||||
Zur Umrechnung der Low-/High-Bytes empfehle Ich folgende Kochrezepte:
|
||||
|
||||
## Dezimal in Low-/High-Byte
|
||||
|
||||
47491:256 = 185 (High-Byte), Rest 131 (Low-Byte)
|
||||
|
||||
Der Rest fällt bei der Division per Hand automatisch an. Mit dem (Taschen-)Rechner erhält man den Rest durch:
|
||||
|
||||
185*256-47491 = -131
|
||||
|
||||
## Low-/High-Byte in Dezimal
|
||||
|
||||
High-Byte * 256 + Low Byte = Dezimal
|
||||
185 * 256 + 131 = 47491
|
||||
|
||||
Wichtige Regel: Die Mikroprozessoren von VC 20 und C64 verlangen, daß immer das Low-Byte vor dem High-Byte kommen muß. Die Zahl wird sozusagen von rechts nach links gelesen (131/185).
|
||||
|
||||
# Texteinschub Nr. 3: Manipuliertes Basic
|
||||
Wie Sie durch PRINT PEEK (1) selbst leicht feststellen, steht nach dem Einschalten des Computers im Register 1 die Zahl 55. In dualer Darstellung ist das 110111. Das entspricht dem in der ersten Zeile derTabelle 2 dargestellten »Normalzustand« der einzelnen Bits.
|
||||
|
||||
Vergleichen Sie es bitte mit der Auflistung am Anfang der Beschreibung der Speicherzelle 1. Die in Tabelle 2 dargestellten Bits sind also die rechten drei Bits der Zelle 1.
|
||||
|
||||
Lassen wir die Bits 3, 4 und 5 unverändert, ergeben die acht Kombinationen der Tabelle 2 die Zahlen 55 bis 48. Durch den Befehl POKE 1,54 können wir nun den Basic-Übersetzer aus- schalten und 8 KByte Speicher gewinnen. Nur nutzt uns das nicht viel, denn was tun - ohne Basic! Es gibt aber doch eine Anwendung. Zuvor will ich Ihnen aber noch beweisen, daß wir tatsächlich den Block A auf RAM umschalten. Der Trick besteht darin, den Basic-Übersetzer vom ROM in den darunter liegenden RAM umzuladen. Wenn er tatsächlich in RAM steht, müßten wir ihn durch POKEn verändern können zu einem Privat-Basic. Geben Sie direkt ein:
|
||||
|
||||
FOR J=40960 TO 49151: POKE J,PEEK(J): NEXT J
|
||||
|
||||
POKE J, PEEK (J) - das sieht dümmer aus als es ist. Die »Doppeldecker-Speicher« erlauben nämlich ein PEEKen nur aus dem ROM-Bereich. Ein hineinPOKEn dagegen geht nur in den RAM-Teil. Von dort aber kann er - wie gerade gesagt - nicht herausgelesen werden, es sei denn, wir schalten um!
|
||||
|
||||
Merken Sie was? Die Zeile oben liest also den Inhalt des Basic- ROMs und schreibt ihn in den RAM mit identischen Adressen. Die Ausführung der Zeile braucht einige Zeit. Wenn der Cursor wieder blinkt, schalten wir das RAM ein mit:
|
||||
|
||||
POKE 1,54
|
||||
|
||||
Wir merken natürlich noch keinen Unterschied, denn das RAM-Basic ist ja noch dasselbe.
|
||||
|
||||
Doch nun werden wir es verändern. In der Speicherzelle 41220 steht das »P« für den Befehl PRINT mit dem ASCII-Codewert 80. Dieses P ersetzen wir durch ein »G« (ASCII-Code = 71).
|
||||
|
||||
POKE41220,71
|
||||
|
||||
Versuchen Sie bitte, mit dem (nicht durch »?« abgekürzten) PRINT-Befehl ein Zeichen auf den Bildschirm zu drucken. Es wird Ihnen nicht gelingen, denn der Befehl heißt jetzt:
|
||||
|
||||
GRINT "A"
|
||||
|
||||
was beweist, daß das Basic jetzt im RAM steht. Das Umdefinieren von Befehlen Ist natürlich wenig sinnvoll. Aber wer die Maschinenprogramme des Basic kennt, kann sie auf diese Weise ändern, erweitern, einschränken, solange er sich auf in sich geschlossene Teile beschränkt.
|
||||
|
||||
Eine inzwischen oft zitierte Anwendung stammt von Jim Butterfield, den es begreiflicherweise stört, daß der Befehl ASC, welcher den ASCII-Code eines Strings erzeugt, bei einem Null- String das Programm mit ILLEGAL QUANTITY ERROR beendet. Versuchen Sie es:
|
||||
|
||||
`PRINT ASC ("A")` ergibt die Zahl 65.
|
||||
|
||||
`PRINT ASC (" ")` hat die obige Fehlermeldung zur Folge.
|
||||
|
||||
Wenn Basic im RAM steht, können wir das ändern:
|
||||
|
||||
POKE 46991,5
|
||||
|
||||
Die Wiederholung des Befehls PRINT ASC (””) ergibt jetzt 0 - und, was das Wichtige ist, das Programm läuft weiter.
|
||||
|
||||
Durch zusätzliches Umladen des Speicherblocks E und anschließendes Umschalten mit POKE 1,53 ist auch das Betriebssystem veränderbar - ein weites Feld für fortgeschrittene Programmierer in Maschinensprache.
|
||||
|
||||
Die wohl wichtigste Anwendung der Umschaltmethode wird den Maschinen-Programmierern geboten, die dadurch eine kostenlose Speichererweiterung von 16 KByte erhalten. Bei gleichzeitiger Verwendung von Basic und Maschinenprogramm kann die Umschaltung besonders vorteilhaft eingesetzt werden. Das Umschaltprogramm muß dann aber ebenfalls in Maschinensprache geschrieben sein und darf nicht im Umschaltbereich liegen.
|
||||
|
||||
Das Umschalten von den Ein-/Ausgabe-Registern des Blocks D mit POKE 1,51 erlaubt, die Bitmuster der fest programmierten Zeichen aus dem Zeichen-ROM auszulesen, in einen freien RAM-Bereich zu bringen und dort dann nach eigenen Vorstellungen zu verändern.
|
||||
|
||||
|
||||
# Texteinschub Nr. 4: Zeiger, Vektoren und Flaggen
|
||||
|
||||
Zeiger und Vektoren sind Zahlenwerte, die jeweils in zwei benachbarten Speicherzellen stehen und in der Low-/High-Byte-Darstellung eine Adresse bilden.
|
||||
|
||||
Wir sprechen von einem »Zeiger«, wenn diese Adresse den Beginn von gespeicherten Daten angibt.
|
||||
|
||||
Ein »Vektor« zeigt ebenfalls auf eine Anfangsadresse, allerdings auf die eines Maschinenprogramms. Diese Unterscheidung wird leider nicht immer ganz eindeutig angewendet.
|
||||
|
||||
Eine »Flagge« besteht aus einem Zahlenwert in einer Speicherzelle, die von einem Programm dort abgelegt wird, um sich das Resultat einer Operation zu merken, beziehungsweise um es für eine spätere Verwendung bereitzuhalten.
|
||||
|
||||
|
||||
# Texteinschub Nr. 5: Die Zahlendarstellung bei den Commodore-Computern
|
||||
|
||||
## Gleitkomma-Zahlen
|
||||
|
||||
Für diejenigen Leser, die das Thema der Zahlendarstellung in den Commodore-Handbüchern großzügig übersprungen haben, stelle ich es hier noch einmal vor.
|
||||
|
||||
Sie kennen die gängigen vier Zahlentypen:
|
||||
|
||||
* ganze Zahlen: 15, 21, 244
|
||||
* Brüche; 2/3, 26/8, 15/14
|
||||
* negative Zahlen: -15, -255
|
||||
* positive Zahlen: 10, 5, 123
|
||||
|
||||
Ganze Zahlen bereiten uns und dem Computer keine Probleme.
|
||||
|
||||
Bei Brüchen sieht es schon anders aus. Erinnern Sie sich an
|
||||
die Bruchrechnungsstunden in der Schule? Wieviel ist 51/52 + 3/4!!!
|
||||
|
||||
Ohne lange zu überlegen, rechnen wir natürlich um, 51/52 = 0,9807692 und 3/4 = 0,75; addiert ist das Resultat 1,7307692 - und schon sind Sie mitten in den Gleitkomma-Zahlen.
|
||||
|
||||
Bei obigem Beispiel gleitet allerdings noch nichts. Bei sehr großen oder aber auch sehr kleinen Bruch-Zahlen reicht uns - und einem Computer - nicht der Platz, um sie darzustellen. Die Zahl 0,000000000000000123 sprengt jeden normalen Rahmen.
|
||||
|
||||
Daher schreiben wir sie anders. Wir lassen das Komma nach rechts gleiten, bis es die erste Ziffer, die von 0 verschieden ist, findet und für jede Null, die es passiert, multiplizieren wir die Zahl mit 10.
|
||||
|
||||
Die Zahl oben sieht dann so aus: 0,123 x 10 hoch 15 (eine 1 mit 15 Nullen).
|
||||
|
||||
Die Grundzahl vorn heißt »Mantisse«, die 10 mit Hochzahl heißt »Exponent«.
|
||||
|
||||
Alle Commodore-Computer verarbeiten intern alle Zahlen in dieser Darstellung, also als Gleitkommazahl.
|
||||
|
||||
|
||||
# Texteinschub Nr. 6: Was ist ein Stapelspeicher (Stack)?
|
||||
|
||||
Der normale Arbeitsspeicher des Computers, auf englisch »Random Access Memory« oder kurz RAM genannt, hat für jede Speicherzelle eine eigene Adresse, die beim Schreiben in den Speicher oder beim Lesen aus dem Speicher angegeben werden muß.
|
||||
|
||||
Als Analogie möge eine Aktenablage dienen, bei der jeder Akt (Brief, Papier, Zeichnung) in einen Ordner kommt, mit Nummer versehen.
|
||||
|
||||
Um einen Akt herauszuholen, muß man die Nummer (Adresse) kennen, unter der er abgelegt ist.
|
||||
|
||||
Ein Stapelspeicher, auf englisch »Stack« genannt, funktioniert wie eine Aktenablage, bel der jeder Akt einfach oben auf einen Stapel gelegt wird, daher der Name. Diese Ablage erfolgt ohne Kennzeichnung oder Nummer, einfach immer der Reihe nach.
|
||||
|
||||
Einen Akt kann man aus einem Stapelspeicher nicht beliebig herausholen, da immer nur der oberste Akt zugänglich ist.
|
||||
|
||||
Die Methode der Stapelspeicher bietet sich überall dort an, wo es auf die Reihenfolge der gespeicherten Daten ankommt. Basic merkt sich zum Beispiel der Reihe nach die Adressen, von denen aus mit GOSUB ein Unterprogramm angesprungen wird. Wenn mehrere GOSUBs hintereinander eingesetzt werden, liegt auf dem Stapel Immer die letzte Absprungadresse bereit zum Rücksprung.
|
||||
|
||||
Ein Stapelspeicher hat demnach nur eine einzige Adresse, die sowohl zum Abspeichern als auch zum Auslesen dieselbe Ist.
|
||||
|
||||
Voraussetzung eines Stapelspeichers ist natürlich eine Routine, welche alle gespeicherten Daten im Stapelspeicher um einen Platz weiterschiebt, wenn eine neue Information »oben auf den Stapel gelegt wird«.
|
||||
|
||||
Das Basic der Commodore-Computer verwendet mehrere dieser Stapelspeicher.
|
||||
Die Programmiersprache Forth ist völlig auf dem Prinzip des Stapelspeichers aufgebaut.
|
||||
|
||||
|
||||
# Texteinschub Nr. 7: Der sichtbare Basic-Speicher
|
||||
|
||||
Wenn wir den Variablen A die Adresse des Speicherbeginns der Basic-Programme zuordnen und dann mit einer FOR..NEXT- Schleife den Inhalt dieser und der nächsten 100 Speicherplätze ausdrucken, sehen wir in dezimaler Darstellung die ersten 101 Zahlenwerte, mit denen der Computer ein Basic-Programm speichert.
|
||||
|
||||
Ein Verbiegen des Zeigers in Speicherzelle 43/44 kann auf diese Weise in seiner Wirkung sichtbar gemacht werden.
|
||||
|
||||
Als Demo-Programm wähle ich zwei Zeilen, welche die Zahlen 1 bis 9 und die Buchstaben A bis I ausdrucken.
|
||||
|
||||
10 PRINT "123456789"
|
||||
20 PRINT "ABCDEFGHI"
|
||||
100 A=2049 : REM*C 64
|
||||
4097 : REM*VC 20 ohne Erweiterung
|
||||
1025 : REM*VC 20 mit 3 KByte
|
||||
4609 : REM*VC 20 mit 8 KByte oder mehr
|
||||
110 PRINT CHR$(l47)
|
||||
|
||||
Zeile 100 definiert den Speicheranfang. Zeile 110 löscht den Bildschirm.
|
||||
|
||||
120 FOR J=A T0 A+100
|
||||
130 PRINT PEEK (J);
|
||||
140 NEXT J
|
||||
|
||||
Die Befehle in den Zeilen 120 bis 140 drucken den Inhalt der ersten 101 Zellen dieses Basic-Programms aus. SAVEn Sie bitte dieses kleine Programm, denn wir brauchen es noch einmal. Dann geht es los mit RUN. In Bild 3 ist der Bildschirm-Ausdruck des VC 20 mit 8 KByte dargestellt, der des C 64 zeigt praktisch dieselbe Information.
|
||||
Überspringen Sie bitte zunächst die ersten beiden Zahlen. Die dritte und vierte Zahl ist 10 und 0. Das ist (als Low- und High- Byte) die Nummer der ersten Zeile des Basic-Programms. Dann folgt 153, das ist der interne Codewert für PRINT. Diese Codes für alle Basic-Befehlswörter heißen »TOKEN«, sie sind im Texteinschub Nr. 32 angegeben.
|
||||
|
||||
Die nächste Zahl auf dem Bildschirm ist die 34, sie ist der ASCII*Code für den Gänsefuß. Danach folgen in aufsteigender Reihenfolge die ASCII-Codes der Ziffern 1 (48) bis 9 (57). Danach sehen Sie wieder den Gänsefuß (34). Schließlich kommt eine Null als Abstandszeichen zur nächsten Basic-Zeile.
|
||||
|
||||
Machen Sie bitte folgendes Experiment: Ausgehend von der Adresse der ersten auf dem Bildschirm ausgedruckten Speicherzellen - zum Beispiel 4609 beim VC 20 mit 8 KByte - zählen Sie die Zellen weiter bis zur Abgrenzungs-Null. In meinem Beispiel steht die Null in Zeile 4625. Das heißt, daß die nächste Basic-Zeile in 4626 anfängt. Und das ist genau die Zahl, die in den ersten beiden Zellen steht, die wir vorhin übersprungen haben; in meinem Beispiel steht da 18 18. Machen wir die Probe: 18 + 256 * 18 = 4626.
|
||||
|
||||
Jede Basic-Zeile im Speicher beginnt also mit der Adresse der nächsten Zeile (sie heißt Koppeladresse) und endet mit einer Null.
|
||||
|
||||
Ab 4626 folgt dann die nächste Koppeladresse, danach mit 20 0 die Zeilennummer, und Sie erkennen jetzt sicher die Codes der Angaben von Zeile 20 wieder.
|
||||
|
||||
So, jetzt wollen wir den Zeiger in 43 und 44 verbiegen. Ich schlage vor, daß wir den Basic-Beginn um zehn Adressen höher schieben. Sie müssen jetzt die in Zeile 100 oben verwendete Zahl für A in die High-/Low-Byte-Darstellung umrechnen und das Low-Byte um 10 erhöhen. Dieses Zahlenpaar POKEn wir in die Zellen 43 und 44. Vorher müssen wir aber noch in Zelle (A + 10) -1 eine Abstands-Null POKEn.
|
||||
|
||||
Wir geben diese Befehlssequenz im Direktmodus ein:
|
||||
|
||||
* für den C 64:
|
||||
|
||||
POKE 2058,0:POKE 43,11:POKE 44,8:NEW
|
||||
|
||||
* für den VC 20 (GV):
|
||||
|
||||
POKE 5006,0:P0KE 43,143:POKE 44,19:NEW
|
||||
|
||||
* für den VC 20 (= 3 KByte):
|
||||
|
||||
POKE 1034,0:P0KE 43,11:POKE 44,4:NEW
|
||||
|
||||
* für den VC 20(> 8KByte)
|
||||
|
||||
POKE 4618,0:P0KE 43,H:POKE 44,18: NEW
|
||||
|
||||
Jetzt ist der Anfang des Basic-Speichers versetzt. Um das zu prüfen, geben wir das kleine Programm von oben nochmal ein und lassen es mit RUN laufen. Der resultierende Bildschirmausdruck ist in Bild 4 dargestellt.
|
||||
|
||||
Die ersten Zahlen sind genauso wie vorher. Es sind auch die Reste von vorher, da wir den Speicher nicht auf Null gesetzt haben. Aber zählen Sie bitte die ersten zehn Adressen hoch. Da finden Sie unser Programm von vorhin genau wieder, beginnend mit der Abstands-Null. Aber Vorsicht, lassen Sie sich nicht verwirren, denn die Koppeladressen sind natürlich jetzt auch jeweils um 10 höher. Aber hinter den Koppeladressen finden wir wieder unser Programm, in gleicher Weise dargestellt wie beim ersten Mal. Da der Zeiger in 43 und 44 von allen entsprechenden Routinen des Übersetzers und des Betriebssystems abgefragt wird, läuft ein verschobenes Programm fehlerfrei, solange natürlich der Zeiger nicht wieder verändert wird.
|
||||
|
||||
|
||||
# Texteinschub Nr. 8: Normale Variable in Basic
|
||||
|
||||
Alle Daten, die in einem Basic-Programm nicht in Form von READ-DATA-Anweisungen vorkommen, werden als »Variable« unmittelbar nach dem Basic-Programm abgespeichert. Wir unterscheiden dabei zwei Typen:
|
||||
|
||||
* normale Variable
|
||||
* Felder (Arrays)
|
||||
|
||||
Wir betrachten hier nur die »normalen« Variablen.
|
||||
|
||||
Sie erscheinen in dem Speicherbereich, dessen Beginn durch den Zeiger in den Zellen 45 und 46 und dessen Ende durch den Zeiger in 47 und 48 angegeben wird, in derselben Reihenfolge, in welcher sie während des Ablaufes des Basic-Programms auf- treten. Wenn Basic dann auf eine der bereits definierten (und abgespeicherten) Variablen zurückgreifen soll, muß es den gesamten Variablenbereich von Anfang an absuchen, bis es den Namen der gesuchten Variablen gefunden hat. Wenn diese Variable ganz am Ende des Bereiches steht, kann dieser Suchprozeß recht lange dauern.
|
||||
|
||||
## Regel 1:
|
||||
|
||||
Häufig vorkommende Variable sollen am Anfang des Variablenbereichs stehen. Das wird dadurch erreicht, daß sie als erste Variable in einem Programm »definiert« werden. Falls sie erst später im Programm gebraucht werden (aber dann häufig), werden sie trotzdem am Anfang des Programms angegeben, notfalls mit einem beliebigen Wert, der später dann keine Rolle mehr spielt und ersetzt wird. Man nennt das einen »Dummy«-Wert.
|
||||
|
||||
Die Felder-Variablen stehen direkt nach den »normalen« Variablen. Auch hier kann der gewiefte Programmierer Gutes tun. Wenn nämlich nach einer Definition eines Feldes später im Programm noch normale Variable dazukommen, ist natürlich zuerst kein Platz für sie da. Das Betriebssystem des Computers muß erst alle Felder-Variablen weiterschieben, bevor die Neuankömmlinge in dem dadurch erweiterten Variablenbereich gespeichert werden können. Auch das kostet unnötig viel Zeit.
|
||||
|
||||
## Regel 2:
|
||||
|
||||
Alle normalen Variablen sollen als erste in einem Programm definiert werden. Wer also drauflos programmiert, sollte zumindest am Ende das Programm so umbauen, daß diese simple Regel erfüllt wird.
|
||||
|
||||
|
||||
# Texteinschub Nr. 9: Darstellung der normalen Variablen im Speicher
|
||||
|
||||
Die normalen Variablen kommen in drei Arten vor:
|
||||
|
||||
* ganzzahlige Variablen
|
||||
* Gleitkomma-Variablen
|
||||
* String-Variablen (Zeichenketten)
|
||||
|
||||
Der Unterschied zwischen den drei Typen ist in den Commodore-Handbüchern gut erklärt, und ich verzichte hier auf eine Wiederholung. Ich will vielmehr direkt zeigen, wie die Variablen im Speicher abgelegt sind.
|
||||
|
||||
Wir können den Speicher direkt sichtbar machen.
|
||||
|
||||
Einmal geht das in Maschinencode mittels eines Monitors beziehungsweise Disassemblers.
|
||||
|
||||
Zum anderen aber geht das auch in Basic und zwar mit folgendem Trick, den ich Th. und M.L. Beyer (MC 10/1983) abgeschaut habe.
|
||||
|
||||
Wir verlegen den Beginn des Basic-Variablenspeichers einfach auf den Beginn des Bildschirmspeichers. Auf diese Weise können wir zwar kein vernünftiges Programm laufen lassen, aber alle direkt eingegebenen Variablen-Definitionen werden sofort sichtbar, weil sie eben im Bildschirmspeicher stehen.
|
||||
|
||||
Wir erreichen die Verlegung des Speichers durch »Verbiegen« der Zeiger in den Zellen 45 und 46 und 47 und 48. Die Bedeutung dieser Zeiger ist ja im Kurs erklärt.
|
||||
|
||||
Die Speicherverlegung beziehungsweise die Methode dazu ist für den C 64 anders als für den VC 20.
|
||||
|
||||
## VC 20:
|
||||
|
||||
Alle Angaben gelten für den VC 20 ohne Speichererweiterung, also ziehen Sie bitte alle Speichermodule heraus. Der Speicherbereich für Programme und deren Variablen beginnt jetzt ab Adresse 4096, das ist Block 1 im Bild 5. Der Bildschirmspeicher beginnt ab 7680. Wir verlegen jetzt den Bildschirmspeicher in den Block 1, so daß er ebenfalls ab Adresse 4096 beginnt. Danach müssen wir noch eine Farbe - am besten Schwarz - in den Farbspeicher POKEn, der in dieser neuen Konfiguration von 37888 bis 38399 liegt. Warum das so Ist, erklärt Christoph Sauer in seinem Aufsatz »Der gläserne VC 20«, Teil 4, im 64'er 1/85, Seite 131.
|
||||
|
||||
Das High-Byte der Adresse, in welcher der Bildschirmspeicher beginnt, steht in der Speicherzelle 648. Sie können das jederzeit mit PRINT PEEK(648) nachprüfen. Umgekehrt können wir eine Zahl hineinPOKEn, wodurch der Bildschirmspeicher verschoben wird. In unserem Fall erhalten wir das High-Byte für 4096 durch 4096/256 = 16.
|
||||
|
||||
Machen Sie jetzt bitte folgende Schritte:
|
||||
|
||||
1) direkt eingeben: POKE 648,l6(RETURN),
|
||||
2) RUN/STOP und RESTORE drücken, bis der Cursor wieder da ist,
|
||||
3) direkt eingeben:
|
||||
|
||||
FOR J = 37888 TO 38399: POKE J,0: NEXT J (RETURN),
|
||||
|
||||
4) mit der DELETE-Taste (nicht mit CLR !) den ganzen Text des Bildschirms löschen,
|
||||
5) mit dem Cursor etwa acht Zeilen nach unten gehen,
|
||||
6) mit der Commodore- und SHIFT-Taste zusammen auf die Groß- und Kleinschrift umstellen.
|
||||
|
||||
Schritt 1 und 3 habe ich oben schon erklärt. Schritt 4 ist nicht absolut notwendig, aber ein leerer Bildschirm ist für uns besser. Die CLR-Taste würde Schritt 3 zunichte machen. Schritt 5 erlaubt uns, weiter unter auf dem Bildschirm Variablen einzugeben, ohne den oberen Teil vollzuschreiben. Schritt 6 schließlich erleichtert das Erkennen der Variablen-Darstelllung.
|
||||
|
||||
## C 64:
|
||||
|
||||
Beim C 64 beginnt der Bildschirmspeicher ab 1024. In Low-/ High-Byte-Darstellung ist das 0/4 (1024/256=4, Rest 0). Geben Sie bitte direkt ein:
|
||||
|
||||
POKE 46,4 :POKE 48,4
|
||||
|
||||
Das Low-Byte in 45 und 47 können wir weglassen, da es ja in beiden Fällen 0 ist. Diese Methode gilt für alle neueren C 64, bei denen direkt ein Zeichen in den Bildschirmspeicher gePOKEt werden kann, ohne sich um die Zeichenfarbe kümmern zu müssen. Es gibt noch einige C 64 mit älteren Betriebssystemen, bei denen die Zeichenfarbe auch angegeben werden muß. Hier gilt:
|
||||
|
||||
FOR J = 0 TO 1000:POKE 55296*3,14:NEXT J
|
||||
|
||||
## Alles weitere gilt für beide Computertypen gleich
|
||||
|
||||
Wenn Sie jetzt den Bildschirm löschen, den Cursor ungefähr in die Mitte des Bildschirms fahren und wiederum direkt eingeben:
|
||||
|
||||
`VARIABLE = 3` und die RETURN-Taste drücken, dann erscheinen oben sieben Zeichen. Bitte schalten Sie mit der SHIFT- und Commodore-Taste auf den zweiten Zeichensatz um, jetzt können wir besser lesen.
|
||||
|
||||
Aus anderen Kursen wissen Sie wahrscheinlich, daß Variable mit 7 Byte dargestellt werden. In der Tat sehen wir oben die ersten beiden Buchstaben des Variablennamens VA und fünf weitere Zeichen. Wir wollen aber systematisch vorgehen und uns zuerst die ganzzahligen Variablen anschauen.
|
||||
|
||||
### Ganzzahl-Variable
|
||||
|
||||
Wiederholen Sie bitte den Vorgang (Löschen, Cursor auf Mitte, 2. Zeichensatz). Jetzt geben Sie eine Ganzzahl-Variable ein:
|
||||
|
||||
VA%=3
|
||||
|
||||
Nach RETURN sehen wir als erstes Zeichen ein reverses V, dann ein reverses A, den Klammeraffen @, das kleine c und nochmals drei @. Die beiden ersten Zeichen des Variablennamens (besteht er nur aus einem Zeichen, wird mit einer 0 aufgefüllt) werden mit ihrem ASCII-Code eingegeben, zu dem bei Ganzzahl-Variablen zur Kennzeichnung einer solchen die Zahl 128 addiert wird.
|
||||
|
||||
Schauen Sie in einer ASCII-Tabelle (64’er, Ausgabe 7/84) nach: Das V hat 86, um 128 erhöht gibt das 214. Wir arbeiten hier aber im Bildschirmspeicher, der die Zahlen auf seine eigene Weise interpretiert, nämlich als Bildschirmcode. Der Bildschirmcode-Tabelle entnehmen wir das Zeichen für den Wert 214 und das ist das invertierte V. Für das A können Sie das selbst nachvollziehen.
|
||||
|
||||
Also: In unserer Darstellung erkennen wir Ganzzahl-Variable an den invertierten Zeichen des Namens.
|
||||
|
||||
Das 3. und 4. Zeichen sind das High- und Low-Byte des Variablenwertes und zwar im Bildschirmcode. In unserem Beispiel der 3 ist das High-Byte 0, also der Klammeraffe @, das Low-Byte 3, also das c. Die restlichen drei Byte sind mit 0 aufgefüllt.
|
||||
|
||||
Wenn Sie mit dem Cursor auf die 3 fahren, es mit einer 5 überschreiben und RETURN drücken, verwandelt sich das c in ein e. Beim Überschreiben mit 255 erscheint als 4. Byte das Zeichen für den Bildschirmcode 255. Beim Überschreiben mit 257 ändern sich beide Bytes. Das 3. (High-)Byte springt auf a (=1), das 4. (Low-)Byte ebenfalls auf a. Nun, 1 * 256+1 = 257.
|
||||
|
||||
Während, wie bewiesen, das Low-Byte von 0 bis 255 gehen kann, sind beim High-Byte nur Werte zwischen 0 und 127 zugelassen. Die Werte ab 128 signalisieren negative Zahlen. Probieren Sie es aus:
|
||||
|
||||
127 * 256+255=32767
|
||||
|
||||
Ein Überschreiben mit 32767 resultiert in einer Darstellung der Zeichen für den Bildschirmcode 127 und 255. Der Wert 32768 wird nicht mehr akzeptiert. Dasselbe machen wir noch schnell für negative Zahlen.
|
||||
|
||||
Überschreiben Sie bitte die letzte Zahl mit 0. Wie zu erwarten war, sind Byte 4 und 5 jetzt 0 (Klammeraffe).
|
||||
|
||||
Wenn Sie jetzt mit -1 überschreiben, erscheint für beide Bytes das Zeichen mit dem Bildschirmcode 255. Bei -2 sehen wir die Zeichen mit den Code-Werten 255 und 254.
|
||||
|
||||
Sie sehen also, daß die negativen Zahlen für ganzzahlige Variable sozusagen vom Ende der Tabelle her dargestellt werden, wobei die höchste negative Zahl wieder 32767 ist. Diese »Rückwärtszählung« ist bedingt durch die Methode der negativen Zahlendarstellung im Zweierkomplement. Der Platz und die Gelegenheit verbieten es mir, näher darauf einzugehen. Aber ich glaube, unser kleines Experiment hat Ihnen zumindest von der Darstellung her den Zusammenhang gezeigt. In Bild 6 ist diese Darstellung der ganzzahligen Variablen im Speicher wiedergegeben.
|
||||
|
||||
| 1 | 2 | 3 | 4 | 5 6 7 |
|
||||
|---------|---------|--------|--------|---------|
|
||||
| Erstes | Zweites | High- | Low- | |
|
||||
|-------------------|-----------------|---------|
|
||||
| Zeichen des | Byte des Varia- | 0 0 0 |
|
||||
| Variablen-Namens | blenwertes | |
|
||||
| (ASCII-Wert + 128)| | |
|
||||
|
||||
Bild 6. So stehen ganzzahlige Variable im Speicher
|
||||
|
||||
### Gleitkomma-Variable
|
||||
|
||||
Ich hoffe, Sie verzeihen mir, wenn ich diese Darstellung an dieser Stelle überspringe. Sie ist nämlich nicht ganz leicht zu verstehen, und ich möchte sie lieber dann im Detail erklären, wenn wir zur Diskussion der Speicherzellen 97 bis 101, nämlich des Gleitkomma-Akkumulators kommen. Da geht es in einem Stück. Als Vorgeschmack gebe ich jetzt in Bild 7 nur die Zusammenfassung an.
|
||||
|
||||
| 1 | 2 | 3 | 4 5 6 7 |
|
||||
|---------|---------|----------|--------------------------|
|
||||
| Erstes | Zweites | | |
|
||||
|-------------------| | Mantisse mit Genauig- |
|
||||
| Zeichen des | Exponent | keit von 32 Dualstellen, |
|
||||
| Variablen-Namens | + 129 | 1. Bit des 1. Bytes ist |
|
||||
| (ASCII-Wert) | | das Vorzeichen |
|
||||
|
||||
Bild 7. Gleitkomma-Variable
|
||||
|
||||
### String-Variable
|
||||
|
||||
Zuerst ist es erforderlich, den Computer in den Anfangszustand zurückzusetzen. Wenn Sie einen RESET-Schalter haben, bitte diesen drücken, sonst aber aus- und einschalten. Wir geben nach Löschen des Bildschirms in der unteren Hälfte direkt ein:
|
||||
|
||||
ZX$="A" <RETURN>
|
||||
|
||||
Wir erhalten ein Z, ein invertiertes X, ein kleines a, ein grafisches Zeichen, eine Leerstelle und zwei Klammeraffen.
|
||||
|
||||
Fahren Sie bitte jetzt mit dem Cursor auf das A und ändern den String um in BC. Nach RETURN verwandelt sich das a in das b, das 4. Zeichen ändert sich ebenfalls. Die ersten beiden Zeichen sind also wieder der Name der Variable.
|
||||
|
||||
Um zu kennzeichnen, daß es eine String-Variable ist, erscheint das 2. Zeichen des Namens invertiert. Wie oben entsteht es dadurch, daß zum ASCII-Code die Zahl 128 addiert wird. Diese Zahl wird aber wieder als Bildschirmcode interpretiert und entsprechend angezeigt (vergleichen Sie es mit den ASCII- und Bildschirmcode-Tabellen).
|
||||
|
||||
Das 3. Zeichen gibt die Länge des Strings an, also im ersten Fall mit a (=1 im Bildschirmcode), im 2. Fall mit b (=2). Zeichen 4 und 5 geben als Low- und High-Byte die Adresse an, bei der begonnen wird, den Text des Strings zu speichern. Das können wir nachprüfen.
|
||||
|
||||
Wir hatten die beiden Fälle:
|
||||
|
||||
1. ZX$ = ”A": 4. Zeichen: (Bildschirmcode: 255) und 5. Zeichen: (Bildschirmcode 156) ergibt als Adresse 40959.
|
||||
2. ZX$ = ”BC": 4. Zeichen: (Bildschirmcode 253) und 5. Zeichen: (Bildschirmcode 156) ergibt als Adresse 40957.
|
||||
|
||||
Der Text der Zeichenketten wird am Ende des Arbeitsspeichers (40959 beim C 64, 7679 beim VC 20 ohne Erweiterung) abgelegt und zwar von hinten nach vorn.
|
||||
|
||||
Mit `PRINT PEEK(40957);PEEK(40958);PEEK(40959)` drucken wir den Inhalt dieser Speicherzellen aus und erhalten: 66 67 65. Im ASCII-Code ist das: B C A. Die Zusammenfassung für String-Variable (Bild 8) sieht so aus:
|
||||
|
||||
| 1 | 2 | 3 | 4 | 5 | 6 7 |
|
||||
|---------|---------|---------|---------|---------|------|
|
||||
| Erstes | Zweites | | High- | Low- | 0 0 |
|
||||
|-------------------| Anzahl |---------|---------| |
|
||||
| Zeichen des | der | Byte der Adresse, | |
|
||||
| Variablen-Namens | Zeichen | ab welcher der | |
|
||||
| ASCII- | ASCII- | des | Text des Strings | |
|
||||
| Wert | Wert+128| Strings | abgespeichert ist | |
|
||||
|
||||
Bild 8. String-Variable
|
||||
|
||||
## Texteinschub Nr. 10: Felder in Basic
|
||||
|
||||
Zur Wiederholung: Es gibt zwei Arten von Variablen, normale Variable und Felder. Jede der beiden Arten ihrerseits kann aus Gleitkomma-Zahlen, ganzen Zahlen oder Zeichenketten bestehen.
|
||||
|
||||
Eine normale Variable kann immer nur einen Wert haben, ein Feld enthält gleichzeitig viele Werte, alle unter demselben Variablen-Namen.
|
||||
|
||||
Wir können uns ein Feld mit dem Namen KARLSTRASSE als eine Liste vorstellen, in der jedes Element zwar auch den Namen Karlstraße hat, sich aber von den anderen Elementen durch eine eigene Hausnummer unterscheidet. Jede Variable in einer Hausnummer hat einen bestimmten Wert.
|
||||
|
||||
Während eine normale Variable einfach mit A=3 einen Wert zugewiesen bekommt, muß ein Feld erst definiert werden, nämlich wie viele Elemente es enthält. Wir machen das mit dem Befehl
|
||||
|
||||
DIM KARLSTRASSE (12)
|
||||
|
||||
Dieses Feld hat 13 Elemente (von 0 bis 12). Jedem Element kann nun ein Variablenwert zugewiesen werden durch
|
||||
|
||||
KARLSTRASSE (0)=25
|
||||
KARLSTRASSE (1)=56
|
||||
|
||||
Das Feld KARLSTRASSE hat in der Klammer nur eine Zahl, man sagt, es hat nur eine Dimension.
|
||||
|
||||
Ein zweidimensionales Feld entspricht einem Schachbrett, mit Zahlen in der einen und Buchstaben in der anderen Dimension. Wir definieren es mit:
|
||||
|
||||
DIM AX (7,7)
|
||||
|
||||
AX ist der Name, jede Dimension hat acht Elemente, insgesamt kann das Feld 64 Werte enthalten.
|
||||
|
||||
Ein dreidimensionales Feld entspricht einem Quader, oder bei gleicher Elementenzahl pro Dimension (Seite) einem Würfel. Dieses wird dimensioniert mit
|
||||
|
||||
DIM BY (125,6,2)
|
||||
|
||||
Die Anzahl der Dimensionen wird nur begrenzt durch den verfügbaren Speicherplatz. Wieviel Bytes pro Feld gebraucht wer- den, entnehmen Sie bitte der Erklärung bei der Darstellung der Feld-Variablen (Texteinschub Nr. 11).
|
||||
|
||||
Ein Feld, das wie bisher gezeigt dimensioniert wird, enthält Gleitkomma-Zahlen.
|
||||
|
||||
Ein Feld mit ganzen Zahlen wird durch das Zeichen % nach dem Namen gekennzeichnet, also:
|
||||
|
||||
DIM CZ%(.,.,.)
|
||||
|
||||
Ein Feld mit Zeichenketten dagegen hat nach dem Namen das übliche Zeichen $, also:
|
||||
|
||||
DIM DT$(..,..,..)
|
||||
|
||||
»Wozu brauche ich Felder, wenn ich auch normale Variable verwenden kann?«, werden Sie vielleicht noch fragen.
|
||||
|
||||
Felder haben den großen Vorteil, daß immer dann, wenn viele Variable in einem Programm vorkommen, die alle einen gewissen Zusammenhang haben, viel Speicherplatz gespart werden kann.
|
||||
|
||||
Eine normale Variable braucht 7 Byte, eine Feld-Variable nur 5 oder bei ganzen Zahlen sogar nur 2 Byte. Zugegeben, vorher steht noch ein längerer Kopf, aber halt nur einmal. Und das zahlt sich bei vielen Variablen sehr rasch aus.
|
||||
|
||||
Und schließlich muß ich noch darauf hinweisen, daß die »Hausnummern« oder Indizes der Elemente innerhalb eines Programms durch mathematische Operationen verändert und manipuliert werden können. Aber das ist natürlich höhere Programmierkunst und geht über diese kurze Einführung hinaus.
|
||||
|
||||
|
||||
# Texteinschub Nr. 11: Darstellung der Felder-(Array-)Variablen im Speicher
|
||||
|
||||
Die Felder-Variablen kommen in drei Arten vor:
|
||||
|
||||
* als ganze Zahlen,
|
||||
* als Gleitkomma-Zahlen,
|
||||
* als Zeichenketten.
|
||||
|
||||
Sie sind in dem Texteinschub Nr. 10 »Felder in Basic« kurz beschrieben.
|
||||
|
||||
Wir wollen sie uns hier mit den Methoden anschauen, welche ich für den C 64 und für den VC 20 in dem Texteinschub Nr. 9 »Darstellung der normalen Variablen im Speicher« beschrieben habe.
|
||||
|
||||
Beim C 64 ist allerdings ein Zusatz dabei. Sie müssen, am besten gleich am Anfang, noch eingeben:
|
||||
|
||||
POKE 44,4:NEW
|
||||
|
||||
Ein eventuell auftretender SYNTAX ERROR soll uns nicht weiter stören.
|
||||
|
||||
Wenn Sie also das jeweilige Kochrezept ausgeführt und damit den Bildschirm- und den Variablenspeicher auf dieselbe Adresse gelegt haben, können wir anfangen.
|
||||
|
||||
## Gleitkomma-Feld
|
||||
|
||||
Geben Sie direkt ein:
|
||||
|
||||
DIM AB(1,2,3)
|
||||
|
||||
Wir dimensionieren also ein Feld mit dem Namen AB, es hat drei Dimensionen, die erste Dimension hat zwei (0,1) Werte, die zweite hat drei und die dritte hat vier Werte. Sobald Sie die RETURN-Taste drücken, erscheint das Feld auf dem Bildschirm. Wir sehen folgende Zeichen: A, B, invertiertesC , @ c @ d @ c @ b plus 120 Klammeraffen @.
|
||||
|
||||
Die ersten zwei Stellen sind der Name des Feldes in der Darstellung für Gleitkomma-Variable, wie in der letzten Folge beschrieben wurde. Die dritte und vierte Stelle geben im Bildschirmcode als Low- und High-Byte die Länge des Feldes an (das inverse C = 131, das © = 0, bitte nachzählen). Die fünfte Stelle zeigt die Anzahl der Dimensionen (c = 3) an. Ab der sechsten Stelle stehen die Anzahl der Elemente der Dimension (diesmal als High- und Low-Byte) und zwar beginnend mit der letzten Dimension. In unserem Falle ist das also in Stelle 6 und 7 ein @ und d (0 - 3 =4=d), Stelle 8 und 9 sind dasselbe für die zweite Dimension und schließlich Stelle 10 und 11 für die erste Dimension (0 - 1=2=b). Danach folgen entsprechend der Anzahl der dimensionierten Elemente (2*3*4=24) 6 Byte pro Element (24*5=120), die vorerst auf 0 = @ stehen, die aber mit den Werten der Elemente aufgefüllt werden.
|
||||
|
||||
Dieses Auffüllen wollen wir nachvollziehen. Geben Sie bitte direkt ein:
|
||||
|
||||
AB(0,0,0)=5
|
||||
|
||||
Wir weisen damit dem allerersten Element des Feldes den Wert 5 zu.
|
||||
|
||||
In der oberen Darstellung des Feldes AB ändern sich dadurch Byte 12 und 13. Das neu erschienene inverse C und die Leerstelle mit den drei nachfolgenden @ ist die Gleitkomma- Darstellung (Mantisse und Exponent) der Zahl 5. Auf diese Darstellung werde ich später im Verlauf dieses Kurses bei der Besprechung der Speicherzelle 97 noch genauer eingehen.
|
||||
|
||||
Wenn wir jetzt (durch Überschreiben der vorigen Anweisung) zusätzlich noch eingeben:
|
||||
|
||||
AB(1,0,0)=6
|
||||
|
||||
erreichen wir eine entsprechende Änderung der Bytes 17 und 18, also des zweiten Elements des Feldes.
|
||||
|
||||
In Bild 9 sind die Stellen eines Gleitkomma-Feldes grafisch dargestellt.
|
||||
|
||||
1 2 3 4 5 6 7 / a b c d e
|
||||
|---------|---------|------|------|--------|------|------|-\ |------|------|---------|---|---|---|---|-->
|
||||
| Erstes | Zweites | Low | High | | High | Low | / | High | Low | |
|
||||
| | Byte | Anzahl | Byte | \ | Byte |Exponent Mantisse |
|
||||
| Zeichen des |-------------| der |-------------| / |-------------| +125 |
|
||||
| Feld-Namens | Länge des | Dimen- | Anzahl der | \ | Anzahl der | des 1. Elements| des 2. Elements
|
||||
| | Feldes | sionen | Elemente | / | Elemente | |
|
||||
| | | | der letzten | \ | der ersten | |
|
||||
| | | | Dimension | / | Dimension | |
|
||||
|---------|---------|------|------|--------|-------------|-\-|-------------|---------|---|---|---|---|-->
|
||||
|<----------------------- KOPF ----------------------->| /
|
||||
|
||||
Bild 9. Gleitkomma-Feld
|
||||
|
||||
## Ganzzahliges Feld
|
||||
|
||||
Im Vergleich zu dem Gleitkomma-Feld dimensionieren wir als nächstes ein ganzzahliges Feld:
|
||||
|
||||
DIM AB%(l,2,3)
|
||||
|
||||
Jetzt erscheint auf dem Bildschirm gleich anschließend an das erste Feld eine neue Darstellung: invertiertes A, invertiertes B, ;, @, c@, d, @, c, @b plus 48 Klammeraffen @.
|
||||
|
||||
Die ersten 11 Byte haben dieselbe Bedeutung wie beim Gleitkomma-Feld, aber nur deswegen, weil wir dieselben drei Dimensionen mit identischer Elementenzahl dimensioniert haben. Bei mehr Dimensionen wäre dieser Kopf natürlich länger. Die inverse Darstellung des Feldnamens signalisiert ein ganzzahliges Feld. Die dritte Stelle zeigt das »;« - im Bildschirmcode ist das die 59. In der Tat ist das Feld nur 59 Byte lang, also wesentlich weniger als das Gleitkomma-Feld. Die 2 * 3 * 4=24 Elemente benötigen in der Ganzzahl-Darstellung nur je 2 Byte (24*2=48+11=59). Womit bewiesen ist, daß eine Ganzzahl- Darstellung mit dem Zeichen % erheblich Speicherplatz spart - allerdings nur bei Feldern!
|
||||
|
||||
Jetzt wollen wir noch den Inhalt des Feldes füllen, so wie vorher mit:
|
||||
|
||||
AB%(0,0,0)=5
|
||||
|
||||
... und prompt ändert sich Byte Nummer 13 in ein e (e = 5).
|
||||
|
||||
Eine Eingabe für das zweite Element:
|
||||
|
||||
AB$(1,0,0)=6
|
||||
|
||||
verändert das 15. Byte in ein f.
|
||||
|
||||
In Bild 10 ist der Inhalt eines Ganzzahl-Feldes grafisch dargestellt.
|
||||
|
||||
1 2 3 4 \ a b c d
|
||||
|---|---|---|---|--/--|------|------|------|------|-->
|
||||
| \ | Low | High | Low | High |
|
||||
| / | Byte | Byte |
|
||||
| KOPF \ |-------------|-------------|
|
||||
| (wie in Bild 2) / | | |
|
||||
| \ | des | des | des
|
||||
| / | 1. Elements | 2. Elements | 2. Elements
|
||||
| \ | | |
|
||||
|---|---|---|---|--/--|------|------|------|------|->
|
||||
\
|
||||
|
||||
Bild 10. Ganzzahliges Feld
|
||||
|
||||
## Felder mit Zeichenketten
|
||||
|
||||
Die Dimensionierung eines Feldes mit Zeichenketten sieht so aus:
|
||||
|
||||
DIM AB$(1,2,3)
|
||||
|
||||
Auf dem Bildschirm erscheint jetzt ein Feld:
|
||||
|
||||
Auch hier zeigen die ersten elf Stellen dieselbe Information wie bei den anderen Feldern. Zur Kennzeichnung des Zeichenketten-Feldes ist das zweite Zeichen des Feldnamens invers dargestellt. Zeichen 3 und 4 geben wieder die Länge des Feldes an. Das S hat den Bildschirmcode 83. (Vorsicht! Da wir im Groß-/Kleinbuchstaben-Modus sind, müssen wir die jeweils rechte Seite der Spalten in der Code-Tabelle nehmen). Die Länge 83 minus 11 Kopfstellen ergibt 72 Byte, geteilt durch 24 (2*3*4 = 24 Elemente) erhalten wir 3 Byte zur Darstellung eines Elements.
|
||||
|
||||
Das erste Byte gibt die Länge der Zeichenkette an, das zweite und dritte Byte (Low-/High-Byte) die Adresse, ab der die Zeichenkette im vierten Block gespeichert ist.
|
||||
|
||||
Die Methode ist also dieselbe wie bei den »normalen« Zeichenketten-Variablen. Das wollen wir uns auch noch ansehen. Geben Sie direkt ein:
|
||||
|
||||
AB$(0,0,0) = "AAAAAA"
|
||||
|
||||
In der Darstellung des Feldes ändern sich dadurch die Stellen 12, 13 und 14 und wir sehen
|
||||
|
||||
* beim C 64:
|
||||
* beim VC 20:
|
||||
|
||||
Im Bildschirm steht dafür:
|
||||
|
||||
* C 64: 6 250 159 das heißt 6 Zeichen, ab Adresse 250+159*256=40959
|
||||
* VC 20: 6 250 29 das heißt 6 Zeichen, ab Adresse 250+29*256=7674
|
||||
|
||||
Jetzt weisen wir dem letzten Element auch noch eine Zeichenkette zu:
|
||||
|
||||
AB$(1,2,3)="BB"
|
||||
|
||||
Die letzten drei Stellen des Feldes ändern sich ebenfalls, wobei die erste mit dem b eine Zeichenkettenlänge von 2 angibt, dementsprechend muß die Anfangsadresse um 2 niedriger sein als die vorher definierte Kette: Das Low-Byte 250 - 2 = 248, in der Codetabelle finden wir dafür das, was auch im Feld steht. Das High-Byte bleibt unverändert.
|
||||
|
||||
Bild 11 zeigt die grafische Darstellung des Zeichenketten-Feldes.
|
||||
|
||||
Als letztes zeige ich Ihnen noch die im vierten Block gespeicherten Zeichenketten. Wir drucken einfach den CHR$-Wert der in den betreffenden Speicherzellen stehenden Codezahlen aus mit:
|
||||
|
||||
* VC 20:
|
||||
|
||||
FOR I=248 TO 255:PRINT CHR$(PEEK(29*256+I));:NEXT
|
||||
|
||||
* C 64:
|
||||
|
||||
FOR I=248 TO 255:PRINTCHR$(PEEK(159*256+I));:NEXT
|
||||
|
||||
... und wir erhalten die beiden Zeichenketten in umgekehrter Reihenfolge, also vom Speicherende her eingespeichert. Interessant ist, daß sich vor die Felder - wenn Sie sie noch auf dem Bildschirm hatten - die neu definierte Gleitkomma-Variable l@ geschoben hat. Auch das ist eine Demonstration des Speicherverfahrens der Variablen, genauso wie ich es Ihnen in der letzten Folge erklärt habe.
|
||||
|
||||
1 2 3 4 \ a b c d e f
|
||||
|---|---|---|---|--/--|----------|-------|-------|-----|-----|-----|-->
|
||||
| \ | Länge | Low | High | |
|
||||
| / | der | Byte | |
|
||||
| KOPF \ | Zeichen- |---------------| |
|
||||
| (wie in Bild 2) / | kette der Adresse, | |
|
||||
| \ | ab der der | |
|
||||
| / | String ge- | |
|
||||
| \ | | speichert ist | |
|
||||
|---|---|---|---|--/--|--------------------------|-----------------|-->
|
||||
\ |<--- 1. Element --->|<- 2. Element ->|
|
||||
|
||||
Bild 11. Zeichenketten-Feld
|
||||
|
||||
|
||||
## Texteinschub Nr. 12: Darstellung der Variablen einer selbstdefinierten Funktion
|
||||
|
||||
Ich habe Ihnen gezeigt, wie im Programmspeicher abgelegte normale Variablen und Felder-Variablen sichtbar gemacht werden können. Damit konnten wir den Aufbau und die Darstellung der einzelnen Variablenarten studieren.
|
||||
|
||||
Heute will ich einen weiteren Variablentyp vorstellen, nämlich den der selbstdefinierten Funktionen.
|
||||
|
||||
Sie erinnern sich vielleicht, mit dem Basic-Befehl »DEF FN (Name)(Variable)« können wir komplizierte Funktionen selbst erfinden, definieren und später als »FN (Name)(Variable)< weiter verarbeiten. Diesen Typ wollen wir uns anschauen, wie er im Speicher steht.
|
||||
|
||||
Im Prinzip verwenden wir dieselben Methoden zur Sichtbarmachung wie die letzten Male.
|
||||
|
||||
Aber ein Unterschied kommt noch dazu. Der Befehl DEF kann leider nicht direkt eingegeben werden, sondern muß immer als Teil einer Programmzeile mit einer Zeilennummer versehen sein.
|
||||
|
||||
Deshalb schreiben wir zuerst ein kleines Programm zur Definition der Funktion plus Variable, bevor wir den Variablenspeicher mit dem Bildschirmspeicher zusammenlegen:
|
||||
|
||||
10 DEF FNAA(X)=3*SIN(X)+COS(X)
|
||||
20 X=5
|
||||
30 PRINT FNAA(X)
|
||||
|
||||
Die Funktion hat also den Namen »AA«. Bevor wir weitermachen, überprüfen Sie bitte mit RUN, ob alles stimmt. Nun wird der Speicher verschoben.
|
||||
|
||||
**Für den C 64 gilt:**
|
||||
|
||||
1. POKE 46,4:POKE 48,4
|
||||
2. Bildschirm löschen mit CLR-Taste
|
||||
3. Cursor auf die Mitte fahren
|
||||
4. LIST (es erscheint das Programm)
|
||||
5. auf den 2. Zeichensatz umschalten (mit C= und SHIFTTaste)
|
||||
6. RUN
|
||||
|
||||
**Für den VC 20 (ohne. Erweiterung) gilt:**
|
||||
|
||||
Nur den Bildschirm auf 4096 zu verschieben, wie das letzte Mal, geht diesmal nicht, da wir ja für DEF ein kleines Programm schreiben müssen.
|
||||
|
||||
Also legen wir Bild- und Variablenspeicher ab Adresse 5120 (5120/256=20).
|
||||
|
||||
1. POKE 46,20:CLR
|
||||
2. POKE 648,20
|
||||
3. STOP/RESTORE-Tasten, bis Cursor wieder da ist
|
||||
4. Bildschirm löschen mit CLR-Taste
|
||||
5. dfe ersten vier bis sechs Zeilen mit SPACE-Taste überfahren
|
||||
6. Cursor ein paar Zeilen nach unten
|
||||
7. LIST (es erscheint das Programm)
|
||||
8. mit Commodore- und SHIFTTaste auf 2. Zeichensatz umschalten
|
||||
9. RUN
|
||||
|
||||
Wir sehen jetzt oben zwei Gruppen mit je sieben Zeichen, wie üblich.
|
||||
|
||||
Die erste Gruppe stellt die Funktion FNAA(x) dar. Sie ist gekennzeichnet durch das invertierte erste Zeichen des Namens, während das zweite Zeichen normal erscheint.
|
||||
|
||||
Das dritte und vierte Zeichen gibt in Low-/High-Byte- Darstellung (im Bildschirmcode) die Adresse an, ab der die Funktion FNAA(x) im Programmspeicher abgelegt ist. Mit `PEEK (3. Zeichen)+256*PEEK (4. Zeichen)` kann das abgefragt werden.
|
||||
|
||||
Das fünfte und sechste Zeichen nennt die Adresse, an welcher der Zahlenwert der Funktions-Variablen X anfängt. Das siebente Zeichen schließlich ist das erste Zeichen der Funktion selbst (in unserem Beispiel die 3).
|
||||
|
||||
Die zweite Gruppe beschreibt die Variable X der Funktion. Die normale Darstellung der beiden ersten Zeichen, die den Namen darstellen, gibt uns an, daß es sich um eine Gleitkomma-Variable handelt, deren Wert als Mantisse und Exponent dargestellt ist. Der Aufbau einer Funktion ist in Bild 12 zusammengefaßt:
|
||||
|
||||
| 1 | 2 | 3 | 4 | 5 | 6 | 7 |
|
||||
|---------|---------|---------|---------|----------|----------|---------|
|
||||
| Erstes | Zweites | Low- | High- | Low- | High- | |
|
||||
|-------------------|---------|---------|----------|----------|---------|
|
||||
| Zeichen des | Byte der Adresse, | Byte der Adresse, | 1. Zei- |
|
||||
| Funktionsnamens | ab der die | ab dem der jewei- | chen |
|
||||
|---------|---------| Funktion abge- | lige Wert der Funk- | der |
|
||||
| ASCII- | ASCII- | speichert ist | tionsvariablen X | Funk- |
|
||||
| Wert+128| Wert | | abgespeichert ist | tion |
|
||||
|
||||
Bild 12. Selbstdefinierte Funktion
|
||||
|
||||
|
||||
# Texteinschub Nr. 13: Wie zufällig sind Zufallszahlen?
|
||||
|
||||
Der Befehl RND(X) ergibt eine Zufallszahl zwischen 0 und 1 - so steht es im Commodore-Handbuch.
|
||||
|
||||
Eine Zufallszahl ist definitionsgemäß rein dem Zufall überlassen. Ihr Wert kann nicht vorhergesehen werden. Wie kann aber ein Computer, in dem alle Vorgehensweisen und Arbeitsschritte fest vorprogrammiert sind, eine zufällige Zahl erzeugen? Die Commodore-Computer machen das so:
|
||||
|
||||
Der Befehl RND nimmt eine bestimmte Ausgangszahl (auf die ich noch näher eingehen werde), auf englisch »seed« = Samen genannt, multipliziert sie mit 11879546.4 und zählt 3.92767778 * 10^8 dazu. Die 5 Byte der resultierenden Gleitkommazahl werden miteinander vertauscht und in einen positiven Bruch umgewandelt. Diese Manipulation ergibt die »Zufallszahl«, die als neuer »Samen« in den Speicherzellen 139 bis 143 gespeichert wird.
|
||||
|
||||
Es ist sicher einzusehen, daß die Zufälligkeit nicht sehr hoch sein kann, es sei denn, die oben genannte und noch nicht erklärte Ausgangszahl ist zufällig.
|
||||
|
||||
Die erste Ausgangszahl hängt vom »Argument« des RND(X)-Befehls ab, das heißt vom Wert X, der in der Klammer dahinter steht. Es gibt drei Möglichkeiten für das Argument:
|
||||
|
||||
* eine positive Zahl (egal, welcher Wert)
|
||||
* eine negative Zahl
|
||||
* die Zahl 0
|
||||
|
||||
## Eine positive Zahl
|
||||
|
||||
zum Beispiel RND (1) oder RND(56) nimmt als Samen die Zahl 0.811635157, die beim Einschalten des Computers als 5-Byte- Gleitkommazahl in die Speicherzellen 139 bis 143 geschrieben worden ist. In den fünf Zellen stehen die Zahlen 128, 79, 199, 82, 88.
|
||||
|
||||
Daraus folgt aber, daß nach dem Einschalten des Computers mit RND(1) immer dieselbe Sequenz von Zufallszahlen erzeugt wird. Schalten Sie bitte den Computer aus und ein und geben Sie ein:
|
||||
|
||||
10 PRINT RND(1):G0T0 10
|
||||
|
||||
Notieren Sie die ersten paar Zahlen und wiederholen Sie mit Aus-/Einschalten die Prozedur. Sie werden immer dieselben Zahlen sehen.
|
||||
|
||||
Zum Austesten von Programmen mit bekannten Zahlensequenzen ist diese Methode sicher wichtig, aber echte Zufallszahlen sind das nicht!
|
||||
|
||||
## Eine negative Zahl
|
||||
|
||||
zum Beispiel RND(-1)oder RND(-95) bringt als erstes das Argument selbst (in meinem Beispiel -1 oder -95) als Gleitkommazahl in die Speicherzellen 139 bis 143, von wo sie als Samen den schon beschriebenen Manipulationen unterworfen wird. Nur - mit einem bestimmten negativen Argument erhalten Sie immer dieselbe Zufallszahl. Probieren Sie es aus: PRINT RND(-2) ergibt immer dieselbe Zahl.
|
||||
|
||||
Es mag Fälle geben, wo die Vorgabe des allerersten Samens wünschenswert ist. Ich will aber von zufälligen Zählen sprechen. Wir können diese Methode des negativen Arguments dadurch verbessern, daß wir als Argument selbst eine Zufallszahl nehmen.
|
||||
|
||||
Als derartige Zahl bietet sich der Wert der inneren Uhr TI an, die beim Einschalten des Computers losläuft und 60mal in der Sekunde weitergestellt wird. Da kein Mensch wissen kann, welchen Wert die UhrTI gerade hat, kommt der Befehl RND(-TI) dem absoluten Zufall schon sehr nahe.
|
||||
|
||||
## Das Argument (0)
|
||||
|
||||
verwendet eine andere Methode. Als Samen nimmt er eine sich ständig ändernde Zahl, die beim VC 20 aus vier Registerinhalten des VIC-lnterface-Bausteins genommen werden. Beim C 64 wird es ähnlich gemacht, nur ist der VIC-Baustein ein anderer Typ.
|
||||
|
||||
Mit derselben Methode nach dem Einschalten wie im ersten Fall oben können Sie das leicht überprüfen.
|
||||
|
||||
Ich habe eingangs zitiert, daß RND(X) eine Zahl zwischen 0 und 1 erzeugt; das gilt aber nur für ein positives Argument. Wenn Sie hingegen eine Zufallszahl innerhalb eines ganz bestimmten Bereiches brauchen, müssen Sie anders vorgehen.
|
||||
|
||||
## Kochrezept Nr. 1
|
||||
|
||||
Mit folgender Formel ist derZahlenbereich beliebig vorgebbar: `X=(RND(1)*A)+B`
|
||||
|
||||
* Die Zahl A gibt einen Bereich von 0 bis A vor.
|
||||
* Die Zahl B legt den untersten Wert des Bereiches fest.
|
||||
|
||||
Beispiele:
|
||||
|
||||
* `10 PRINT (RND(1)*6)+1:GOTO 10` erzeugt Zahlen von 1 bis 6
|
||||
* `10 PRINT (RND(1)*52)+1:G0T0 10` erzeugt Zahlen von 1 bis 52
|
||||
* `10 PRINT (RND(1)*6)+10:G0T0 10` erzeugt Zahlen von 10 bis 16
|
||||
|
||||
Mit dem Vorschalten der Funktion INT vor den Befehl RND werden die Zufallszahlen auf ganze Zahlen beschränkt.
|
||||
|
||||
10 PRINT INT (RND(1)*6)+10:GOTO 10
|
||||
|
||||
Noch einmal: Zufallszahlen innerhalb bestimmter Zahlenbereiche sind gekoppelt mit einem positiven Argument. Wir haben aber gesehen, daß gerade so keine echten Zufallszahlen erzeugt werden. Deshalb brauchen wir noch ein zweites Kochrezept.
|
||||
|
||||
## Kochrezept Nr. 2
|
||||
|
||||
Wenn Sie in einem Programm nach dem Einschalten des Computers immer neue Zufallszahlen brauchen, ist es empfehlenswert, für die allererste Zufallszahl RND(-TI) oder RND(0) zu verwenden, dann aber mit RND(1) fortzufahren.
|
||||
|
||||
Dasselbe gilt, wenn ein Programm wegen INPUT oder WAIT eine Pause hat. Nach der Pause sollte zuerst ein neuer Ausgangswert genommen werden.
|
||||
|
||||
Als letztes will ich noch beschreiben, wie man Zufallszahlen innerhalb von Maschinenprogrammen erzeugen kann.
|
||||
|
||||
Im Betriebssystem steht natürlich eine Routine für den Befehl RND. Im C 64 beginnt sie ab 57495 ($E097), im VC 20 ab 57492 ($E094).
|
||||
|
||||
Der Ausgangswert (Samen) wird dabei aus dem Gleitkomma-Akkumulator Nr. 1 geholt, dessen Vorzeichen oder Wert 0 das weitere Vorgehen der Routine bestimmt.
|
||||
|
||||
Sie müssen also den Samen in den Akkumulator Nr. 1 laden und dann mit JSR auf die RND-Routine springen. Als Resultat können Sie einen oder mehrere Werte der Zellen 140 bis 143 verwenden und nach Belieben weiterverarbeiten.
|
||||
341
combine.py
Executable file
341
combine.py
Executable file
|
|
@ -0,0 +1,341 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
import cgi, re, os
|
||||
|
||||
filenames = [
|
||||
"c64disasm_ms.txt;c64disasm_cbm.txt",
|
||||
"c64disasm_de.txt",
|
||||
"c64disasm_en.txt",
|
||||
"c64disasm_sc.txt",
|
||||
"c64disasm_mn.txt",
|
||||
"c64disasm_mm.txt"
|
||||
]
|
||||
names = [
|
||||
"Microsoft/Commodore Source",
|
||||
"Data Becker [German]",
|
||||
"Lee Davison",
|
||||
"Bob Sander-Cederlof [BASIC only]",
|
||||
"Magnus Nyman [KERNAL only]",
|
||||
"Marko Mäkelä"
|
||||
]
|
||||
links = [
|
||||
"https://github.com/mist64/cbmsrc",
|
||||
"https://www.pagetable.com/?p=1015",
|
||||
"https://www.pagetable.com/?p=726",
|
||||
"https://www.pagetable.com/?p=728",
|
||||
"https://www.telecomm.at/documents/Jiffydos_Romlisting.doc",
|
||||
"http://www.unusedino.de/ec64/technical/misc/c64/romlisting.html"
|
||||
]
|
||||
descriptions = [
|
||||
"The original M6502 BASIC source by Microsoft (KIM-1 version, not everything lines up, Commodore extensions are missing, but lots of comments by the original authors)<br/>and the original C64 KERNAL source by Commodore (lots of comments by the original authors)",
|
||||
"German-language comments from <i>Das neue Commodore-64-intern-Buch</i> by Data Becker, ISBN 3890113079. Some minor corrections have been made.",
|
||||
"Comments from <i>The almost completely commented C64 ROM disassembly V1.01</i> by Lee Davison. Some minor corrections have been made.",
|
||||
"Comments adapted from <i>S-C DocuMentor for Applesoft</i> by Bob Sander-Cederlof, for the version of Microsoft BASIC that shipped with the Apple II.",
|
||||
"Comments from <i>JIFFYDOS version 6.01/version 6.02</i> by Magnus Nyman (Harlekin/FairLight), which were written for the JiffyDOS KERNAL, so some serial code and all tape code is missing comments.",
|
||||
"Comments from the <i>Commodore 64 BASIC/KERNAL ROM Disassembly Version 1.0 (June 1994)</i> by Marko Mäkelä."
|
||||
]
|
||||
|
||||
|
||||
titlecolor = ["017100", "004D7F", "99195E", "F8BA00", "B51700", "017B76"]
|
||||
darkcolor = ["D8F2CB", "C6E2FC", "BFB7E8", "FCF6CD", "F4D2E3", "D2F6F0"]
|
||||
lightcolor = ["E5F2DF","E3F0FC","D5D1E8","FCFAE6","F5E4EC","E1F5F2"]
|
||||
|
||||
asm_donor_index = 1
|
||||
source_index = 0 # we treat the Microsoft/Commodore source differently
|
||||
|
||||
f = os.popen("git log -1 --pretty=format:%h .")
|
||||
revision = f.read()
|
||||
f = os.popen("git log -1 --date=short --pretty=format:%cd .")
|
||||
date = f.read()
|
||||
|
||||
data = []
|
||||
linenumber = []
|
||||
address = []
|
||||
for filename in filenames:
|
||||
d = []
|
||||
for f in filename.split(";"):
|
||||
d += [line.rstrip() for line in open(f)]
|
||||
data.append(d)
|
||||
linenumber.append(0)
|
||||
address.append(0)
|
||||
files = len(filenames)
|
||||
|
||||
asmaddress = 0
|
||||
asmlinenumber = 0
|
||||
|
||||
for i in range(0, files):
|
||||
while True:
|
||||
line = data[i][linenumber[i]]
|
||||
if len(line) > 0 and line[0] == '.':
|
||||
break
|
||||
linenumber[i] = linenumber[i] + 1
|
||||
|
||||
|
||||
print '<meta http-equiv="Content-type" content="text/html; charset=utf-8" />'
|
||||
print '<title>Ultimate Commodore 64 BASIC & KERNAL ROM Disassembly</title>'
|
||||
print ''
|
||||
print '<script language="javascript">'
|
||||
print ' window.onload = init;'
|
||||
print ' function init() {'
|
||||
print ' var tbl = document.getElementById("disassembly_table");'
|
||||
print ' for (var i = 0; i < ' + str(len(filenames)) + '; i++) {'
|
||||
print ' var key = "column_" + i;'
|
||||
print ' var element_name = "checkbox_" + i;'
|
||||
print ' var checked = localStorage.getItem(key) != "hidden";'
|
||||
print ' document.getElementById(element_name).checked = checked;'
|
||||
print ' hideCol(i, checked);'
|
||||
print ' }'
|
||||
print ' }'
|
||||
print ' function hideCol(col, checked) {'
|
||||
print ' var tbl = document.getElementById("disassembly_table");'
|
||||
print ' for (var i = 0; i < tbl.rows.length; i++) {'
|
||||
print ' tbl.rows[i].cells[col+1].style.display = checked ? "" : "none";'
|
||||
print ' }'
|
||||
print ' var key = "column_" + col;'
|
||||
print ' if (checked) {'
|
||||
print ' localStorage.removeItem(key);'
|
||||
print ' } else {'
|
||||
print ' localStorage.setItem(key, "hidden");'
|
||||
print ' }'
|
||||
print ' }'
|
||||
print '</script>'
|
||||
print ''
|
||||
# http://tholman.com/github-corners/
|
||||
print '<a href="https://github.com/mist64/c64disasm" class="github-corner" aria-label="View source on GitHub"><svg width="80" height="80" viewBox="0 0 250 250" style="fill:#004080; color:#fff; position: absolute; top: 0; border: 0; right: 0;" aria-hidden="true"><path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path></svg></a><style>.github-corner:hover .octo-arm{animation:octocat-wave 560ms ease-in-out}@keyframes octocat-wave{0%,100%{transform:rotate(0)}20%,60%{transform:rotate(-25deg)}40%,80%{transform:rotate(10deg)}}@media (max-width:500px){.github-corner:hover .octo-arm{animation:none}.github-corner .octo-arm{animation:octocat-wave 560ms ease-in-out}}</style>'
|
||||
print '<style type="text/css">'
|
||||
print ''
|
||||
print 'body {'
|
||||
print ' background: #e0f0ff;'
|
||||
print ' color: #004080;'
|
||||
print ' font-family: Helvetica'
|
||||
print '}'
|
||||
print ''
|
||||
print 'a {'
|
||||
print ' color: #0060a0;'
|
||||
print '}'
|
||||
print ''
|
||||
print 'h3 {'
|
||||
print ' font-family: serif;'
|
||||
print '}'
|
||||
print ''
|
||||
print '.com {'
|
||||
print ' white-space: pre;'
|
||||
print '}'
|
||||
print ''
|
||||
print 'th.com {'
|
||||
print ' font-weight: bold;'
|
||||
print '}'
|
||||
print ''
|
||||
print 'div {'
|
||||
print ' padding: 1em;'
|
||||
print '}'
|
||||
print ''
|
||||
print 'div.disassembly_container {'
|
||||
print ' padding: 1em 0em 1em 16em;'
|
||||
print ' overflow: scroll;'
|
||||
print '}'
|
||||
print ''
|
||||
print 'table {'
|
||||
print ' border-collapse: collapse;'
|
||||
print ' border: solid 1px #0060a0;'
|
||||
print ' color: black;'
|
||||
print '}'
|
||||
print ''
|
||||
print 'tr, td, th {'
|
||||
print ' margin: 0px;'
|
||||
print ' text-align:left;'
|
||||
print ' vertical-align: text-top;'
|
||||
print '}'
|
||||
print ''
|
||||
print 'table.disassembly_table {'
|
||||
print ' border: solid grey;'
|
||||
print ' border-width:0px 0px 1px 0px;'
|
||||
print '}'
|
||||
print ''
|
||||
print 'table.disassembly_table td, table.disassembly_table th {'
|
||||
print ' padding: 2px 4px;'
|
||||
print ' border: solid grey;'
|
||||
print ' border-width:0px 1px 0px 1px;'
|
||||
print ' font-family: monospace;'
|
||||
print '}'
|
||||
print ''
|
||||
print 'table.disassembly_table th.top_row {'
|
||||
print ' border-width: 1px;'
|
||||
print ' color: #e0f0ff;'
|
||||
print '}'
|
||||
print ''
|
||||
print 'table.disassembly_table th.left_column {'
|
||||
print ' position: absolute;'
|
||||
print ' width: 18em;'
|
||||
print ' left: 8px;'
|
||||
print ' z-index: 11;'
|
||||
print ' border: 1px solid #000;'
|
||||
print ' border-radius: 2px;'
|
||||
print ' color: #e0f0ff;'
|
||||
print ' background: #0060a0;'
|
||||
print '}'
|
||||
print ''
|
||||
print 'table.disassembly_table th.left_column a {'
|
||||
print ' color: #e0f0ff;'
|
||||
print '}'
|
||||
print ''
|
||||
|
||||
for i in range(0, len(filenames)):
|
||||
print 'table.disassembly_table th.top_row:nth-of-type(' + str(i+2) + ') {'
|
||||
print ' background: #' + titlecolor[i] + ';'
|
||||
print '}'
|
||||
print ''
|
||||
print 'table.disassembly_table tr td:nth-of-type(' + str(i+1) + ') {'
|
||||
print ' background: #' + darkcolor[i] + ';'
|
||||
print '}'
|
||||
print ''
|
||||
print 'table.disassembly_table tr:nth-child(even) td:nth-of-type(' + str(i+1) + ') {'
|
||||
print ' background: #' + lightcolor[i] + ';'
|
||||
print '}'
|
||||
print ''
|
||||
print 'table.checkbox_table tr:nth-of-type(' + str(i+1) + ') {'
|
||||
print ' background: #' + lightcolor[i] + ';'
|
||||
print '}'
|
||||
print ''
|
||||
print 'table.checkbox_table tr:nth-of-type(' + str(i+1) + ') td:nth-of-type(2) {'
|
||||
print ' background: #' + titlecolor[i] + ';'
|
||||
print '}'
|
||||
print ''
|
||||
|
||||
print 'table.disassembly_table tr {'
|
||||
print ' background: #f0f0f0;'
|
||||
print '}'
|
||||
print ''
|
||||
print 'table.disassembly_table tr:nth-child(even) {'
|
||||
print ' background: #ffffff;'
|
||||
print '}'
|
||||
print ''
|
||||
print 'table.checkbox_table {'
|
||||
print ' border-color: #0060a0;'
|
||||
print '}'
|
||||
print ''
|
||||
print 'table.checkbox_table a {'
|
||||
print ' color: #e0f0ff;'
|
||||
print '}'
|
||||
print ''
|
||||
print 'table.checkbox_table tr, table.checkbox_table td {'
|
||||
print ' padding: 4px 8px;'
|
||||
print ' border: solid #0060a0;'
|
||||
print ' border-width:1px 0px 1px 0px;'
|
||||
print '}'
|
||||
print ''
|
||||
print '</style>'
|
||||
print '<body>'
|
||||
|
||||
print '<h1>Ultimate Commodore 64 BASIC & KERNAL ROM Disassembly</h1>'
|
||||
|
||||
print '<p><i>by <a href="http://www.pagetable.com/">Michael Steil</a>, <a href="https://github.com/mist64/c64disasm">github.com/mist64/c64disasm</a>. Revision ' + revision + ', ' + date + '</i></p>'
|
||||
|
||||
print '<b>This allows you to view different commentaries side-by-side. You can enable/disable individual columns:</b><br/><br/>'
|
||||
print '<table class="checkbox_table">'
|
||||
for i in range(0, len(filenames)):
|
||||
print '<tr><td><input type="checkbox" id="checkbox_' + str(i) + '" checked onclick="hideCol(' + str(i) + ', document.getElementById(\'checkbox_' + str(i) + '\').checked);" /></td><td style="white-space: nowrap;"><b><a href="' + links[i] + '">' + names[i] + '</a></b><td>' + descriptions[i] + '</td></tr>'
|
||||
print '</table>'
|
||||
|
||||
print '<div class="disassembly_container">'
|
||||
print '<table id="disassembly_table" class="disassembly_table">'
|
||||
|
||||
print '<tr>'
|
||||
print '<th class="left_column">Disassembly</th>'
|
||||
for i in range(0, files):
|
||||
print '<th class="top_row">' + names[i] + '</th>'
|
||||
print '</tr>'
|
||||
|
||||
count = 0
|
||||
while(True):
|
||||
count += 1
|
||||
# if count > 80:
|
||||
# break
|
||||
|
||||
for i in range(0, files):
|
||||
if linenumber[i] >= len(data[i]):
|
||||
continue
|
||||
while len(data[i][linenumber[i]]) > 0 and (data[i][linenumber[i]][0] == '-' or data[i][linenumber[i]][0] == '#'):
|
||||
linenumber[i] = linenumber[i] + 1
|
||||
|
||||
if asmlinenumber >= len(data[asm_donor_index]):
|
||||
break
|
||||
|
||||
asm = data[asm_donor_index][asmlinenumber][0:32].rstrip()
|
||||
asmlinenumber = asmlinenumber + 1
|
||||
|
||||
if len(asm) == 0:
|
||||
continue
|
||||
if asm[0] == '#' or asm[0] == '-':
|
||||
continue
|
||||
|
||||
has_address = False
|
||||
if asm[0] == '.':
|
||||
hexaddress = asm[2:6]
|
||||
asmaddress = int(hexaddress, 16)
|
||||
has_address = True
|
||||
|
||||
hex_numbers = re.findall(r'\$[0-9A-F][0-9A-F][0-9A-F][0-9A-F]', asm)
|
||||
for hex_number in hex_numbers:
|
||||
if (hex_number[1] == 'A' or hex_number[1] == 'B' or hex_number[1] == 'E' or hex_number[1] == 'F'):
|
||||
asm = asm.replace(hex_number, "<a href=\"#" + hex_number[1:] + "\">" + hex_number + "</a>")
|
||||
|
||||
print '<tr>'
|
||||
print '<th class="left_column">'
|
||||
if has_address:
|
||||
print "<a name=\"" + hexaddress + "\"/>"
|
||||
print '<span class="com">' + asm + '</span></th>'
|
||||
|
||||
for i in range(0, files):
|
||||
print '<td>'
|
||||
comments = []
|
||||
while True:
|
||||
if linenumber[i] >= len(data[i]):
|
||||
break
|
||||
|
||||
line = data[i][linenumber[i]]
|
||||
|
||||
if line.startswith('.'):
|
||||
address[i] = int(line[2:6], 16)
|
||||
if address[i] > asmaddress:
|
||||
break
|
||||
comment = line[32:]
|
||||
comment = cgi.escape(comment)
|
||||
|
||||
hex_numbers = re.findall(r'\$[0-9A-F][0-9A-F][0-9A-F][0-9A-F]', comment)
|
||||
for hex_number in hex_numbers:
|
||||
if (hex_number[1] == 'A' or hex_number[1] == 'B' or hex_number[1] == 'E' or hex_number[1] == 'F'):
|
||||
comment = comment.replace(hex_number, "<a href=\"#" + hex_number[1:] + "\">" + hex_number + "</a>")
|
||||
|
||||
if comment.startswith('***'):
|
||||
comment = '<h3>' + comment[3:] + '</h3>'
|
||||
elif comment.startswith('SUBTTL'):
|
||||
comment = '<h3>' + comment[6:] + '</h3>'
|
||||
elif comment.startswith('.LIB '):
|
||||
comment = '<h3>' + comment + '</h3>'
|
||||
else:
|
||||
scomment = comment.lstrip()
|
||||
|
||||
if scomment.startswith(';'):
|
||||
comment = '<b>' + comment + '</b>'
|
||||
|
||||
if len(comment) != 0:
|
||||
comment = '<span class="com">' + comment + '</span><br />'
|
||||
|
||||
if len(comment) != 0:
|
||||
comments.append(comment)
|
||||
|
||||
linenumber[i] = linenumber[i] + 1
|
||||
|
||||
if len(comments):
|
||||
for comment in comments:
|
||||
print comment
|
||||
else:
|
||||
print ' '
|
||||
|
||||
print "</td>"
|
||||
print "</tr>"
|
||||
|
||||
print '</table>'
|
||||
print '</div>'
|
||||
print '</body>'
|
||||
53
kernal/generate.py
Executable file
53
kernal/generate.py
Executable file
|
|
@ -0,0 +1,53 @@
|
|||
#!/usr/bin/python3
|
||||
|
||||
import markdown
|
||||
import re
|
||||
|
||||
#lines = [line.rstrip() for line in open("kernal_prg.txt")]
|
||||
lines = [line.rstrip() for line in open("kernal_128intern.txt")]
|
||||
|
||||
calls_raw = []
|
||||
call_lines = None
|
||||
for line in lines:
|
||||
if line.startswith('#') or line.startswith('-'):
|
||||
continue
|
||||
if line.startswith('$'):
|
||||
if call_lines is not None:
|
||||
calls_raw.append(call_lines)
|
||||
call_lines = []
|
||||
|
||||
if call_lines is not None:
|
||||
call_lines.append(line)
|
||||
|
||||
calls = []
|
||||
names = []
|
||||
for call_lines in calls_raw:
|
||||
title = call_lines[0]
|
||||
address = title[1:5]
|
||||
name = title[7:13].rstrip()
|
||||
summary = title[15:]
|
||||
call_lines_stripped = []
|
||||
for call_line in call_lines[1:]:
|
||||
call_lines_stripped.append(call_line[15:])
|
||||
calls.append((address, name, summary, call_lines_stripped))
|
||||
names.append(name)
|
||||
|
||||
print('<table border=1>')
|
||||
|
||||
for (address, name, summary, lines) in calls:
|
||||
print('<tr>')
|
||||
print('<td>$' + address + '</td>')
|
||||
print('<td><a name="' + name + '">' + name + '</td>')
|
||||
print('<td><details open><summary>' + summary + '</summary>')
|
||||
all_text = '\n'.join(lines)
|
||||
html = markdown.markdown(all_text, extensions=['tables' , 'sane_lists'])
|
||||
for replace_name in names:
|
||||
if replace_name != name:
|
||||
html = re.sub('\\b' + replace_name + '\\b', '<a href="#"' + replace_name + '">' + replace_name + '</a>', html)
|
||||
print(html + '</details></td>')
|
||||
|
||||
|
||||
|
||||
print('</tr>')
|
||||
|
||||
print('</table>')
|
||||
547
kernal/kernal_128intern.txt
Normal file
547
kernal/kernal_128intern.txt
Normal file
|
|
@ -0,0 +1,547 @@
|
|||
-
|
||||
- Schieb, Thrun, Wobel: Commodore 128 intern
|
||||
- ISBN 3-89011-098-3
|
||||
-
|
||||
|
||||
$FF81 CINIT Video-Controller und Editor initialisieren
|
||||
|
||||
Es werden die Funktionstasten auf Standard
|
||||
gelegt, beide Video-Controller initialisiert und der 40/80-
|
||||
Zeichen-Modus in Abhängigkeit der 40/80-Zeichen-Taste
|
||||
eingeschaltet. Weiterhin werden der Tastaturbuffer gelöscht
|
||||
sowie alle Flags rückgesetzt und ein CLRCH ausgeführt.
|
||||
|
||||
$FF84 IOINIT Initialisierung der Ein/Ausgabegeräte
|
||||
|
||||
Die Ein/Ausgabegeräte werden initialisiert, d.h.
|
||||
die RESET-Leitung auf dem IEC-Bus wird aktiviert. Ange-
|
||||
schlossene Drucker werden in den Anfangszustand versetzt und
|
||||
die Floppy löscht ihre Kanäle - hört sich also an, als ob sie
|
||||
gerade eingeschaltet worden wäre.
|
||||
|
||||
$FF87 RAMTAS BASIC-Warmstart
|
||||
|
||||
Diese Routine initialisiert die Zeropage, setzt die
|
||||
Zeiger für SYSTOP und SYSBOT (also die Speicherunter- und -
|
||||
obergrenze), setzt die Zeiger für die RS-232-Ein/Ausgabebuffer
|
||||
und den Kassettenbuffer zurück.
|
||||
|
||||
$FF8A RESTOR Systemvektoren initialisieren
|
||||
|
||||
Es werden die Systemvektoren ab Adresse $0314
|
||||
bis $0332 (inkl.) auf Normalwert gesetzt. Diese Routine sollte
|
||||
aufgerufen werden, wenn Sie zu viele Vektoren verbogen und
|
||||
die Übersicht verloren haben oder wenn Sie beispielsweise ein
|
||||
Erweiterungspaket ausschalten wollen. Diese Routine ruft die
|
||||
folgende VECTOR-Routine mit gelöschtem CARRY auf.
|
||||
|
||||
$FF8D VECTOR Systemvektoren kopieren oder rücksetzen
|
||||
|
||||
Diese Routine kopiert die 16 Vektoren ab $0314
|
||||
in den durch das X- (Low) und Y-Register (High) definierten
|
||||
Speicher, sofern das CARRY-Flag gesetzt ist. Bei gelöschtem
|
||||
CARRY-Flag werden die Vektoren ab $0314 mit dem durch das
|
||||
X- und Y-Register angegebenen Bereich geladen.
|
||||
|
||||
**Eingabeparameter**: .X, .Y, CARRY
|
||||
|
||||
**Beispiel**:
|
||||
|
||||
LDX #$00 ;Lo-Byte von $1000
|
||||
LDY #$10 ;Hi-Byte von $1000
|
||||
CLC ;Lösche Carry zum Kopieren ($1000)->($0314)
|
||||
JSR $FF80 ;Belege Vektoren neu
|
||||
|
||||
$FF90 SETMSG DOS-Meldungen ermöglichen/verhindern
|
||||
|
||||
Die Routine speichert den Wert des <Akku> in
|
||||
der Zeropage-Adresse $9D. Sollen Systemmeldungen ausgegeben
|
||||
werden, so ist das Bit 7 des <Akkus> zu setzen. Ist $9D positiv,
|
||||
so werden Systemmeldungen verhindert.
|
||||
|
||||
**Eingabeparameter**: .A
|
||||
|
||||
$FF93 SECND Sekundäradresse nach LISTEN senden
|
||||
|
||||
Es wird die zu sendende Sekundäradresse im
|
||||
<Akku> übergeben. Die Routine gibt den <Akku> dann als
|
||||
Sekundäradresse auf dem IEC-Bus aus.
|
||||
|
||||
**Eingabeparameter**: .A
|
||||
|
||||
**Beispiel**:
|
||||
|
||||
;LISTEN wurde gesendet
|
||||
LDA #$F0 ;Sekadr. 0 bei CLOSE
|
||||
JSR $FF93 ;Sekundaradresse senden
|
||||
|
||||
$FF96 TKSA Sekundäradresse nach TALK senden
|
||||
|
||||
Adäquat zu der vorhergehenden Routine sendet
|
||||
diese Routine die Sekundäradresse - übergeben im <Akku> -
|
||||
nach erfolgtem TALK-Signal an den IEC-Bus.
|
||||
|
||||
**Eingabeparameter**: .A
|
||||
|
||||
$FF99 MEMTOP Setzen/Holen der Speicherobergrenze
|
||||
|
||||
Ist das CARRY-Flag gesetzt, so wird im X-
|
||||
Register (Lo) und Y-Register (Hi) die maximal verfügbare
|
||||
Speicherstelle übergeben. Wird die Routine mit gelöschtem
|
||||
CARRY angesprungen, so wird die Speicherobergrenze mit den
|
||||
beiden Registern belegt.
|
||||
|
||||
**Eingabeparameter**: .X, .Y (bei gelöschtem CARRY), CARRY
|
||||
|
||||
**Ausgabeparameter**: .X, .Y (bei gesetztem CARRY)
|
||||
|
||||
**Beispiel**:
|
||||
|
||||
;Auslesen der Speicherobergrenze
|
||||
SEC ;Auslesen der Obergrenze
|
||||
JSR $FF99 ;Hole Obergrenze
|
||||
STX $FC ;zwischenspeichern
|
||||
STY $FD ;zwischenspeichern
|
||||
LDX #$00 ;Lo-Byte von $1000
|
||||
LDY #$10 ;Hi-Byte von $1000
|
||||
CLC ;Flag zum Setzen des MEMTOP
|
||||
JSR $FF99 ;Setze Speicherobergrenze
|
||||
|
||||
$FF9C MEMBOT Setzen/Holen der Speicheruntergrenze
|
||||
|
||||
Genauso wie bei der Routine MEMTOP wird bei
|
||||
gelöschtem CARRY-Flag die Untergrenze des verfügbaren
|
||||
Speichers mit den beiden Registern X ^Lo) und Y (Hi) belegt.
|
||||
Ist das CARRY-Flag gesetzt, so wird die Speicheruntergrenze
|
||||
ausgelesen und in den beiden Registern übergeben.
|
||||
|
||||
**Eingabeparameter**: .X, .Y (bei gelöschtem CARRY), CARRY
|
||||
|
||||
**Ausgabeparameter**: .X, .Y (bei gesetztem CARRY)
|
||||
|
||||
$FF9F KEY Ermitteln gedrückter Tasten
|
||||
|
||||
Diese Routine ist elementar zur Tastatur-
|
||||
dekodierung. Die Tastatur wird auf eine gedrückte Taste anhand
|
||||
der Tastaturdekodiertabellen überprüft. Wird eine gedrückte
|
||||
Taste ermittelt, so wird der ASCII-Wert errechnet und dieser
|
||||
dem Tastaturbuffer (ab $034A) hinzugefügt.
|
||||
|
||||
$FFA2 SETTMO Setzen des Timeout-Flags für IEEE
|
||||
|
||||
Die Routine speichert den im <Akku> überge-
|
||||
benen Wert als Timeout-Flag für die IEEE-Routinen an Adresse
|
||||
$0A0E. Um den Timeout in den IEEE-Routinen zu
|
||||
ermöglichen, muß das Bit 7 des <Akkus> gesetzt sein.
|
||||
|
||||
**Eingabeparameter**: .A
|
||||
|
||||
$FFA5 ACPTR Holt ein Byte vom seriellen Bus
|
||||
|
||||
Die Routine holt ein Byte vom seriellen IEC-Bus.
|
||||
Das geholte Zeichen wird im Akku übergeben. Das Statusbyte
|
||||
ST an $90 wird entsprechend der Aktion gesetzt.
|
||||
|
||||
**Ausgabeparameter**: .A
|
||||
|
||||
$FFA8 CIOUT Ausgabe eines Zeichens auf IEC-Bus
|
||||
|
||||
Diese Routine ist das Gegenstück zu ACPTR. Das
|
||||
im <Akku> übergebene Zeichen wird auf dem lEC-Bus ausge-
|
||||
geben. Auch hier wird das Statusbyte ST an $90 entsprechend
|
||||
der Aktion geändert.
|
||||
|
||||
**Eingabeparameter**: .A
|
||||
|
||||
$FFAB UNTLK UNTALK auf lEC-Bus senden
|
||||
|
||||
Diese Routine wird beim Schließen bzw. Umlegen
|
||||
eines Eingabekanals aufgerufen. Sie bringt das zum Reden
|
||||
(TALK) gebrachte Gerät zum Schweigen.
|
||||
|
||||
$FFAE UNLSN UNLISTEN auf IEC-Bus senden
|
||||
|
||||
Entsprechend zu UNTALK wird bei dieser
|
||||
Routine ein empfangendes Gerät vorerst abgeschaltet. Dies wird
|
||||
beim Schließen oder Umlegen eines Ausgabekanals gemacht.
|
||||
|
||||
$FFB1 LISTN Senden von LISTEN an ein Gerät
|
||||
|
||||
Es wird ein am IEC-Bus angeschlossenes Gerät
|
||||
zum Empfang aufgefordert. Dazu wird das Signal LISTEN über
|
||||
den IEC-Bus geschickt. Im <Akku> wird die Geräteadresse des
|
||||
anzusprechenden Gerätes übergeben. Beispielsweise wird bei
|
||||
einem Drucker ein LISTEN gesendet, bevor die Zeichen zur
|
||||
Ausgabe über den IEC-Bus wandern. Wenn Sie LISTEN ver-
|
||||
wenden, so müssen Sie die auszugebenden Zeichen über die
|
||||
Routine CIOUT ausgeben (nicht über BSOUTÜ). Zum Schließen
|
||||
des Kanals verwenden Sie dann die Routine UNLISTEN. Es
|
||||
kann immer nur ein Gerät am IEC-Bus aktiv sein. Um diese
|
||||
komplizierten Arbeiten zu vereinfachen, können Sie im
|
||||
Betriebssystem Kanäle öffnen und schließen. BSOUT und
|
||||
BASIN übernehmen dann das Senden von LISTEN und
|
||||
UNLISTEN sowie TALK und UNTALK.
|
||||
|
||||
**Eingabeparameter**: .A
|
||||
|
||||
**Beispiel**:
|
||||
|
||||
;LISTEN an Drucker senden
|
||||
LDA #$24 ;Geräteadresse Drucker & LISTEN ein
|
||||
JSR $FFB1
|
||||
|
||||
$FFB4 TALK Senden von TALK an ein Gerät
|
||||
|
||||
Entsprechend der Routine LISTN sendet diese
|
||||
Routine das Kommando TALK an ein beliebiges Gerät. Die
|
||||
Geräteadresse ist im <Akku> zu übergeben. Das Kommando
|
||||
TALK fordert ein am IEC-Bus angeschlossenes Gerät zum
|
||||
Reden, also zum Senden von Informationen auf.
|
||||
|
||||
**Eingabeparameter**: .A
|
||||
|
||||
$FFB7 READST Holen des I/O-Statusbytes
|
||||
|
||||
Es wird der aktuelle Systemstatus im <Akku>
|
||||
zurückgegeben. Ist die RS232 aktiv, so wird das Statusbyte
|
||||
übergeben und direkt im Speicher gelöscht. Sollten Sie also das
|
||||
Statusbyte öfters benötigen, so speichern Sie es zwischen. Ist ein
|
||||
anderer als der RS232-Kanal geöffnet, so wird das Statusbyte
|
||||
von Adresse $90 übergeben.
|
||||
|
||||
**Ausgabeparameter**: .A
|
||||
|
||||
$FFBA SETLFS Fileparameter setzen
|
||||
|
||||
Diese Routine wird überall dort benötigt, wo man
|
||||
Files öffnen muß. Man übergibt die logische File-nummer im
|
||||
<Akku>, die Geräteadresse im X-Register und die Sekun-
|
||||
däradresse im Y-Register. Die Routine speichert diese Werte an
|
||||
den Zeropage-Adressen $B8 bis $BA ab.
|
||||
|
||||
**Eingabeparameter**: .A, .X, .Y
|
||||
|
||||
$FFBD SETNAM Setzen der Filenamenparameter
|
||||
|
||||
In der Routine werden die Informationen für den
|
||||
Filenamen in der Zeropage gespeichert. Diese Angaben sind alle
|
||||
vor dem Öffnen eines Kanales zu machen. Im <Akku> wird die
|
||||
Länge des Filenamens übergeben, im X-Register das Lo-Byte
|
||||
der Adresse und im Y-Register das Hi-Byte der Adresse, an der
|
||||
der Filename gespeichert ist. Ferner müssen Sie mit der
|
||||
SETBNK-Routine die Konfigurationsindizes für den Filenamen
|
||||
und den zu bearbeitenden Speicherbereich übergeben.
|
||||
|
||||
**Eingabeparameter**: .A, .X, .Y
|
||||
|
||||
**Beispiel**:
|
||||
|
||||
;Eröffnen eines des Directory-Files auf Diskette
|
||||
LDA #$0C ;Bereich im RAM-Bank 0
|
||||
TAX ;Filename auch in RAM-Bank 0
|
||||
JSR $FF68 ;SETBNK aufrufen
|
||||
LDA #$01 ;Logische Filenummer
|
||||
LDX #$08 ;Geräteadresse
|
||||
LDY #$00 ;Sekundäradresse für Lesen
|
||||
JSR $FFBA ;SETLFS
|
||||
LDA #$01 ;Länge des Filenamens
|
||||
LDX #$00 ;Lo-Byte der Adresse, an der der
|
||||
LDY #$10 ;Filename gespeichert ist ($1000)
|
||||
JSR $FFBD ;SETNAM
|
||||
JSR $FFC0 ;OPEN - Öffnen des Kanals
|
||||
|
||||
und an Adresse $1000:
|
||||
|
||||
01000 24 ....
|
||||
|
||||
$FFC0 OPEN Öffnen einer Datei
|
||||
|
||||
Es wird die durch die Routinen SETNAM,
|
||||
SETLFS und SETBNK definierte Datei in die Liste der
|
||||
logischen Filenummern aufgenommen. Erst ab diesem Augen-
|
||||
blick können die logischen Filenummern bei den Routinen
|
||||
CKOUT und CHKIN angegeben werden. Beachten Sie, daß Sie
|
||||
maximal neun Files auf einmal öffnen können.
|
||||
|
||||
$FFC3 CLOSE Schließen einer logischen Datei
|
||||
|
||||
Es wird die im <Akku> übergebene logische Datei
|
||||
geschlossen. Dabei werden alle gespeicherten Werte wie
|
||||
Geräteadresse, Sekundäradresse etc. in der dafür vorgesehenen
|
||||
Tabelle gelöscht. Ist die Aktion nicht problemlos verlaufen, so
|
||||
wird das CARRY-Flag gesetzt.
|
||||
|
||||
**Eingabeparameter**: .A
|
||||
|
||||
**Ausgabeparameter**: CARRY
|
||||
|
||||
**Beispiel**:
|
||||
|
||||
;Beispiel für CLOSE
|
||||
LDA #$01 ;Schließen der Beispieldatei von SETNAM
|
||||
JSR $FFC3 ;CLOSE ausführen
|
||||
BCS Error ;Fehler aufgetreten
|
||||
|
||||
$FFC6 CHKIN Logische Datei als Eingabekanal definieren
|
||||
|
||||
Im X-Register wird die logische Dateinummer
|
||||
übergeben, die als Eingabekanal benutzt werden soll. Die ange-
|
||||
gebene logische Dateinummer muß natürlich bereits mit dem
|
||||
OPEN-Kommando geöffnet worden sein. Wird nach dem Aufruf
|
||||
des CHKIN-Kommandos die BASIN-Routine aufgerufen, so
|
||||
erfolgt die Eingabe nicht von Tastatur, sondern von dem
|
||||
geöffneten Gerät; dies kann beispielsweise die Floppy sein. Zu
|
||||
beachten ist, daß zum Einlesen von Tastatur kein CHKIN not-
|
||||
wendig ist, da die Tastatur Standard-Eingabegerät ist. Nach
|
||||
einem CLOSE oder CLRCH ist die Tastatur automatisch wieder
|
||||
das Eingabegerät. Auch bei dieser Routine wird das CARRY als
|
||||
OK-Flag benutzt.
|
||||
|
||||
**Eingabeparameter**: .X
|
||||
|
||||
**Ausgabeparameter**: CARRY
|
||||
|
||||
**Beispiel**:
|
||||
|
||||
;Einlesen der Directory
|
||||
JSR DIROP ;OPEN 1,8,0,"$" (selbstdefinierte Routine)
|
||||
LDX #$01 ;LFN der eröffneten Datei
|
||||
JSR $FFC6 ;CHKIN ausführen
|
||||
JSR $FFCF ;BASIN - Zeichen holen
|
||||
|
||||
$FFC9 CKOUT Logische Datei als Ausgabedatei definieren
|
||||
|
||||
Entsprechend zu CHKIN definiert diese Routine
|
||||
ein im X-Register zu übergebene Datei als Ausgabedatei. Die
|
||||
Datei muß ordnungsgemäß geöffnet worden sein, beispielsweise
|
||||
würde eine Datei, die mit OPEN l,8,0,"$" geöffnet wurde und
|
||||
mit CKOUT als Ausgabedatei definiert werden soll, einen
|
||||
Fehler hervorrufen, weil diese Datei zum Lesen und nicht zum
|
||||
Schreiben geöffnet wurde. Nach Definition einer Ausgabedatei
|
||||
ist nicht mehr der Bildschirm, sondern die definierte Datei
|
||||
Ausgabegerät. Alle über BSOUT auzugebenen Zeichen werden
|
||||
an dieses Gerät gesandt. Das CARRY-Flag dient als Fehlermel-
|
||||
der. Ist es gelöscht, war die Aktion erfolgreich.
|
||||
|
||||
**Eingabeparameter**: .X
|
||||
|
||||
**Ausgabeparameter**: CARRY
|
||||
|
||||
$FFCC CLRCH Ein/Ausgabekanäle schließen
|
||||
|
||||
Diese Routine löscht evtl, mit CHKIN und/oder
|
||||
CKOUT definierte Ein- und Ausgabedateien. Es wird an das
|
||||
Eingabegerät ein UNTALK und an das Ausgabegerät ein
|
||||
UNLISTEN gesendet. Der Bildschirm ist wieder Ausgabe- und
|
||||
die Tastatur Eingabegerät. Die Dateien werden nicht geschlossen,
|
||||
es erfolgt also kein CLOSE. Es werden weder Ein- noch
|
||||
Ausgabeparameter übergeben.
|
||||
|
||||
$FFCF BASIN Ein Zeichen von Eingabekanal holen
|
||||
|
||||
Die eröffnete und mit CHKIN als Eingabedatei
|
||||
definierte Datei (sonst Tastatur) übergibt ein Zeichen im
|
||||
<Akku>.
|
||||
|
||||
**Ausgabeparameter**: .A
|
||||
|
||||
$FFD2 BSOUT Ein Zeichen auf Ausgabekanal ausgeben
|
||||
|
||||
Es wird das im <Akku> übergebene Zeichen auf
|
||||
die eröffnete und mit CKOUT als Ausgabedatei definierte Datei
|
||||
ausgegeben. Ist der Bildschirm Ausgabedatei (Default), so wird
|
||||
das ASCII-Zeichen in den darzustellenden POKE-Code
|
||||
umgerechnet (ein recht aufwendiges Verfahren. Interessierte
|
||||
sollten sich den entsprechenden Teil im Kernal im C-Bereich
|
||||
ansehen).
|
||||
|
||||
**Eingabeparameter**: .A
|
||||
|
||||
**Beispiel**:
|
||||
|
||||
;Wechseln des 40/80-Zeichen-Modus
|
||||
LDA #$1B ;<ESC>
|
||||
JSR BSOUT ;$FFD2, Zeichen ausgeben
|
||||
LDA #"X" ;<ESC>-X zum Uechseln des Bildschirmstatus
|
||||
JSR BSOUT ;ausgeben
|
||||
|
||||
(Es gibt allerdings eine spezielle Routine, die man anspringen
|
||||
kann)
|
||||
|
||||
$FFD5 LOADSP Laden einer Datei in den Speicher
|
||||
|
||||
Bevor mit LOADSP eine Datei geladen werden
|
||||
kann, muß das Gerät, die Sekundäradresse, der Filename etc.
|
||||
durch die Routinen SETLFS, SETNAM und SETBNK definiert
|
||||
worden sein. Im X- (Lo) und Y-Register (Hi) wird die Adresse
|
||||
angegeben, ab der die zu ladende Datei abgelegt werden soll.
|
||||
|
||||
**Eingabeparameter**: .X, .Y
|
||||
|
||||
**Beispiel**:
|
||||
|
||||
;Laden eines Overlay o.ä.
|
||||
JSR PREP ;SETLFS, SETBNK, SETNAM etc.
|
||||
LDX #$00 ;Lo-Byte von $1000
|
||||
LDY #$10 ;Hi-Byte von $1000 (Ladeadresse)
|
||||
JSR $FFD5 ;Lade Datei ab $1000
|
||||
|
||||
$FFD8 SAVESP Abspeichern eines Bereiches auf Datei
|
||||
|
||||
Diese Routine speichert einen Speicherbereich auf
|
||||
eine Datei (Diskette, Kassette) ab. Dazu muß man, wie bei der
|
||||
LOADSP-Routine, zunächst Geräteadresse, Sekundäradresse,
|
||||
RAM-Bank, Filename etc. durch die Routinen SETBNK,
|
||||
SETLFS und SETNAM definieren. Im Akku wird die Zeropage-
|
||||
Adresse angegeben, an der die Anfangsadresse des abzu-
|
||||
speichernden Bereiches steht. Im X- (Lo) und Y-Register (Hi)
|
||||
wird entsprechend die Endadresse des abzuspeichernden
|
||||
Bereiches angegeben.
|
||||
|
||||
**Eingabeparameter**: .A, .X, .Y, Zeropage
|
||||
|
||||
**Beispiel**:
|
||||
|
||||
;Abspeichern des Bereiches $1000 bis $1100
|
||||
JSR PREP ;SETLFS, SETNAM, SETBNK etc. aufrufen
|
||||
LDA #$00 ;Lo-Byte von $1000
|
||||
STA $FC ;in Zeropage speichern
|
||||
LDA #$10 ;Hi-Byte von $1000
|
||||
STA $FD ;in Zeropage speichern
|
||||
LDA #$FC ;der Pointer befindet sich an $FC
|
||||
LDX #$00 ;Lo-Byte der Endadresse $1100
|
||||
LDY #$11 ;Hi-Byte der Endadresse $1100
|
||||
JSR $FFD8 ;SAVESP - Speichern des Bereiches $1000-$1100
|
||||
|
||||
$FFDB SETTIM Setzen der Systemuhr TI
|
||||
|
||||
Die Routine setzt die Systemuhr TI, die ab
|
||||
Adresse $A0 definiert ist. Diese Uhr wird von der Kernal-IRQ-
|
||||
Routine gesteuert und ist nicht sehr genau. Legen Sie auf eine
|
||||
genauere Uhr Wert, so benutzen Sie die Timer in den beiden
|
||||
CIAs. (Siehe auch entsprechendes Kapitel) Das höchstwertige
|
||||
Byte der 24-Stunden-Uhr wird im Y-Register übergeben.
|
||||
|
||||
**Eingabeparameter**: .A, .X, .Y
|
||||
|
||||
**Beispiel**:
|
||||
|
||||
;Rücksetzen der Systemuhr
|
||||
LDA #$00 ;Rücksetzen bedeutet
|
||||
TAY ;auf 0,0,0 setzen
|
||||
TAX ;Alle drei Register auf null
|
||||
JSR $FFDB ;SETTIM
|
||||
|
||||
$FFDE RDTIM Auslesen der Systemuhr
|
||||
|
||||
Diese Routine liest die 24-Stunden-Uhr aus und
|
||||
übergibt die drei Bytes den Registern Y (höchstwertig), X und
|
||||
<Akku> (niederwertig).
|
||||
|
||||
**Ausgabeparameter**: .A, .X, .Y
|
||||
|
||||
**Beispiel**:
|
||||
|
||||
;Auslesen der 24-Stunden-Uhr
|
||||
JSR $FFDE ;RDTIM aufrufen
|
||||
STY $FC ;MSB merken
|
||||
STX $FD ;mittleres Byte merken
|
||||
STA $FE ;LSB merken
|
||||
|
||||
$FFE1 STOP Abfrage der Stop-Taste
|
||||
|
||||
Wenn bis zum letzten IRQ-Aufruf die Stop-Taste
|
||||
betätigt worden ist, so wird das ZERO-Flag gesetzt und es wird
|
||||
ein CLRCH ausgeführt. Wurde die Stop-Taste nicht betätigt, so
|
||||
wird das ZERO-Flag gelöscht.
|
||||
|
||||
**Ausgabeparameter**: ZERO-Flag
|
||||
|
||||
**Beispiel**:
|
||||
|
||||
;Auf STOP prüfen
|
||||
JSR $FFE1 ;STOP-Taste gedrückt?
|
||||
BEQ Jawoll ;Ist gedrückt
|
||||
|
||||
$FFE4 GETIN Holt ein Zeichen aus Tastaturbuffer oder RS232
|
||||
|
||||
Holt von der definierten Eingabedatei ein
|
||||
Zeichen. Ist kein Zeichen bereit gestellt, so wird der <Akku>
|
||||
mit null übergeben.
|
||||
|
||||
**Ausgabeparameter**: .A
|
||||
|
||||
$FFE7 CLALL Alle offenen Dateien schließen
|
||||
|
||||
Alle mittels OPEN eröffneten Dateien werden
|
||||
geschlossen oder besser gelöscht - es wird nämlich kein CLOSE
|
||||
ausgeführt. Beispielsweise bei offenen Floppy-Dateien kann dies
|
||||
sehr ärgerlich sein (WRITE FILE OPEN ERROR ist eine
|
||||
Konsequenz). Ferner wird nach dem Löschen der logischen
|
||||
Dateien ein CLRCH (s.o.) ausgeführt. CLALL ist also mit Vor-
|
||||
sicht anzuwenden.
|
||||
|
||||
$FFEA LIDTIM Systemuhr anpassen (updaten)
|
||||
|
||||
Diese Routine wird vornehmlich von der IRQ-
|
||||
Routine aufgerufen. Es wird die Drei-Byte-24-Stunden-Uhr um
|
||||
eine Einheit hochgezählt.
|
||||
|
||||
$FFED SCRORG Größe des aktuellen Fensters holen
|
||||
|
||||
Die Routine SCRORG holt die aktuellen
|
||||
Fensterwerte in die Register. Der <Akku> enthält nach dem
|
||||
Aufruf die maximale Spaltenzahl, im Y-Register befindet sich
|
||||
die Anzahl der Zeilen im Fenster und im X-Register die Anzahl
|
||||
der Spalten des Fensters.
|
||||
|
||||
**Ausgabeparameter**: .A, .X, .Y
|
||||
|
||||
$FFF0 PLOT Cursor-Position holen/setzen
|
||||
|
||||
Je nach Zustand des CARRY-Flags wird entweder
|
||||
die Cursorposition geholt oder gesetzt. X- und Y-Register sind
|
||||
auf jeden Fall die Kommunikationsregister. Das Y-Register
|
||||
definiert die Zeile (Erste Zeile im Fenster ist null) und das X-
|
||||
Register die Spalte des Cursors. Ist das CARRY-Flag gesetzt, so
|
||||
wird die aktuelle Cursorpostion im Fenster in X- und Y-
|
||||
Register zurückgegeben.
|
||||
|
||||
**Eingabeparameter**: .X, .Y, CARRY
|
||||
|
||||
**Beispiel**:
|
||||
|
||||
;Einen Stern (*) in die Fenstermitte setzen
|
||||
JSR $FFED ;SCRORG aufrufen
|
||||
TXA ;Spaltenzahl nach <Akku>
|
||||
LSR A ;Divisiondurch zwei (Mitte)
|
||||
TAX ;und als Spalte wieder nach X
|
||||
TYA ;Zeilenzahl nach <Akku>
|
||||
LSR A ;Divisiondurch zwei (Mitte)
|
||||
TAY ;und wieder als Zeile nach Y
|
||||
CLC ;Gelöschtes Carry=Setzen Cursorposition
|
||||
JSR $FFF0 ;Setze Cursorposition
|
||||
LDA #"*" ;<Akku> mit Stern laden
|
||||
JSR $FFD2 ;und ausgeben.
|
||||
|
||||
$FFF3 IOBASE Holt die Basisadresse des I/O-Bereiches
|
||||
|
||||
Es wird die Adresse des Ein- und Ausgabebe-
|
||||
reiches in X- (Lo) und Y-Register (Hi) übergeben. Diese
|
||||
Adresse ist beim C128 natürlich immer $D000. Für spätere
|
||||
Erweiterungen bzw. Verschiebungen ist es aus Kompatibilitäts-
|
||||
gründen ratsam, diese Routine in die Software mit zu integrieren
|
||||
und sich darauf zu beziehen.
|
||||
|
||||
**Ausgabeparameter**: .X, .Y
|
||||
|
||||
**Beispiel**:
|
||||
|
||||
;Anfang des Programmes:
|
||||
JSR $FFF3 ;IOBASE
|
||||
STX $FD ;Lo-Byte merken
|
||||
STY $FE ;Hi-Byte merken
|
||||
|
||||
Im Programm bezieht man diese Adresse dann wie folgt ein:
|
||||
|
||||
STA ($FD),Y ;In I/O-Bereich
|
||||
99
kernal/kernal_64intern.txt
Normal file
99
kernal/kernal_64intern.txt
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
$FF81 Video-Reset
|
||||
|
||||
$FF84 CIAs initialisieren
|
||||
|
||||
$FF87 RAM löschen/testen
|
||||
|
||||
$FF8A I/O initialisieren
|
||||
|
||||
$FF8D I/O Vektoren initialisieren
|
||||
|
||||
$FF90 Setzt Flag für Ausgabe von Systemmeldung
|
||||
|
||||
$FF93 schickt Sekundäradresse nach einem LISTEN-Befehl
|
||||
auf den IEC-Bus
|
||||
|
||||
$FF96 schickt Sekundäradresse nach einem TALK-Befehl
|
||||
auf den IEC-Bus
|
||||
|
||||
$FF99 holt bei gesetzem Carry-Flag die höchste RAM-
|
||||
Adresse nach X und Y, bei gelöschtem Carry-
|
||||
Flag wird die Adresse von X und Y gesetzt.
|
||||
|
||||
$FF9C dieselbe Funktion wie $FF99, jedoch für den
|
||||
RAM-Anfang
|
||||
|
||||
$FF9F fragt die Tastatur ab
|
||||
|
||||
$FFA2 setzt das Time-out-Flag für den IEC-Bus
|
||||
|
||||
$FFA5 holt ein Byte vom IEC-Bus in den Akku
|
||||
|
||||
$FFA8 gibt ein Byte aus dem Akku an den IEC-Bus aus
|
||||
|
||||
$FFAB sendet UNTALK-Befehl auf den IEC-Bus
|
||||
|
||||
$FFAE sendet UNLISTEN-Befehl auf den IEC-Bus
|
||||
|
||||
$FFB1 sendet LISTEN-Befehl auf den IEC-Bus
|
||||
|
||||
$FFB4 sendet TALK-Befehl zum IEC-Bus
|
||||
|
||||
$FFB7 holt das Statuswort in den Akku
|
||||
|
||||
$FFBA setzt die Fileparameter, Akku muß logische
|
||||
Filenummer enthalten, X = Gerätenummer und
|
||||
Y = Sekundäradresse
|
||||
|
||||
$FFBD setzt Parameter des Filenamens, Akku muß
|
||||
Länge des Namens enthalten, X und Y enthalten
|
||||
die Adresse des Filenamens (Low- und High-Byte)
|
||||
|
||||
$FFC0 OPEN-Befehl, öffnet logische Datei
|
||||
|
||||
$FFC3 CLOSE-Befehl, schließt logischeDatei,
|
||||
Akku muß logische Filenummer enthalten
|
||||
|
||||
$FFC6 CHKIN setzt folgende Eingabe auf logische
|
||||
Datei, die in X übergeben wird.
|
||||
Die logische Datei muß vorher mit der
|
||||
OPEN-Routine geöffnet werden.
|
||||
|
||||
$FFC9 CKOUT setzt folgende Ausgabe auf logische
|
||||
Datei, die in X übergeben wird.
|
||||
Die logische Datei muß vorher mit der
|
||||
OPEN-Routine geöffnet werden.
|
||||
|
||||
$FFCC CLRCH setzt die Ein- und Ausgabe wieder
|
||||
auf Standard (Tastatur/Bildschirm)
|
||||
|
||||
$FFCF BASIN Eingabe, holt ein Zeichen in den Akku
|
||||
|
||||
$FFD2 BSOUT Ausgabe, gibt Zeichen im Akku aus
|
||||
|
||||
$FFD5 LOAD, lädt Programm in den Speicher
|
||||
|
||||
$FFD8 SAVE, speichert Programm ab
|
||||
|
||||
$FFDE setzt die laufende Zeit neu
|
||||
|
||||
$FFE1 holt die laufende Zeit fragt die STOP-Taste ab
|
||||
|
||||
$FFE4 GET, holt ein Zeichen in den Akku
|
||||
|
||||
$FFE7 CLALL, setzt a lle Ein-/Ausgabekanäle
|
||||
zurück, die Dateien werden jedoch
|
||||
nicht geschlossen
|
||||
|
||||
$FFEA erhöht die laufende Zeit um eine
|
||||
sechzigstel Sekunde
|
||||
|
||||
$FFED SCREEN holt die Anzahl der Zeilen und
|
||||
Spalten des Bildschirms
|
||||
|
||||
$FFF0 bei gelöschtem Carry-Flag wird der Cursor
|
||||
auf die Position X/Y gesetzt, bei gesetztem
|
||||
Carry-Flag wird die Cursorposition nach X/Y
|
||||
geholt (X-Reg = Zeile, Y-Reg = Spalte)
|
||||
|
||||
$FFF3 holt die Startadresse des I/O-Bausteins
|
||||
299
kernal/kernal_ct.txt
Normal file
299
kernal/kernal_ct.txt
Normal file
|
|
@ -0,0 +1,299 @@
|
|||
-
|
||||
- Craig Taylor: Kernal 64 / 128
|
||||
- C=Hacking, Volume 1, Issue 3; July 15, 1992
|
||||
-
|
||||
|
||||
$FF81 CINT Setup VIC, screen values, (128: 8563)...
|
||||
|
||||
Registers In : None.
|
||||
Registers Out : None.
|
||||
Memory Changed: Screen Editor Locations.
|
||||
|
||||
$FF84 IOINIT Initializes pertinant display and i/o devices
|
||||
|
||||
Registers In : C64: None. | C128: $0A04/bit 7
|
||||
| 0 - Full Setup.
|
||||
| 1 - Partial Setup. (no 8563 char)
|
||||
Registers Out : .A, .X, .Y destroyed.
|
||||
Memory Changed: CIA's, VIC, 8502 port, (C128: also optionally 8563).
|
||||
Note : This routine automatically distinguishes a PAL system from a
|
||||
NTSC system and sets PALCNT accordingly for use in the
|
||||
time routines.
|
||||
|
||||
$FF87 RAMTAS Clears Z-Page, Sets RS-232 buffers, top/bot Ram.
|
||||
|
||||
Registers In : None.
|
||||
Registers Out : .A, .X, .Y destroyed.
|
||||
Memory Changed: Z-Page, Rs-232 buffers, top/bot Ram ptrs
|
||||
|
||||
$FF8D VECTOR Copies / Stores KERNAL indirect RAM vectors.
|
||||
|
||||
Registers In : .C = 0 (Set KERNAL Vectors) | .C = 1 (Duplicate KERNAL vectors)
|
||||
.XY = address of vectors | .XY = address of user vectors
|
||||
Registers Out : .A, .Y destroyed | .A, .Y destroyed.
|
||||
Memory Changed: KERNAL Vectors changed | Vectors written to .XY
|
||||
Note : This routine is rarely used, usually the vectors are directly
|
||||
changed themselves. The vectors, in order, are :
|
||||
|
||||
C128: IRQ,BRK,NMI,OPEN,CLOSE,CHKIN,CHKOUT,CLRCH,BASIN,BSOUT
|
||||
STOP,GETIN,CLALL,EXMON (monitor),LOAD,SAVE
|
||||
C64 : IRQ,BRK,NMI,OPEN,CLOSE,CHKIN,CHKOUT,CLRCH,BASIN,BSOUT
|
||||
STOP,GETIN,CLALL,USRCMD (not used),LOAD,SAVE
|
||||
|
||||
$FF90 SETMSG Set control of KERNAL control and error messages.
|
||||
|
||||
Registers In : .A bit 7 = KERNAL Control Messages (1 = on)
|
||||
bit 6 = KERNAL Error Messages (1 = on)
|
||||
Registers Out : None.
|
||||
Note : KERNAL Control messages are those defined as Loading, Found etc
|
||||
... KERNAL Error messages are I/O ERROR # messages which are
|
||||
listed as follows:
|
||||
|
||||
$FF93 SECND Sends secondary address to device after a LISTN
|
||||
|
||||
Registers In : .A = secondary address
|
||||
Registers Out : .A used.
|
||||
Memory Changed: None.
|
||||
Note : Low level serial I/O - recommended use OPEN,CLOSE,CHROUT etc..
|
||||
|
||||
$FF96 TKSA Sends secondary address to device after TALK
|
||||
|
||||
Registers In : .A = secondary address.
|
||||
Registers Out : .A used.
|
||||
Memory Changed: None.
|
||||
Note : Low level serial I/O - recommended use OPEN,CLOSE,CHROUT etc..
|
||||
|
||||
$FF99 MEMTOP Read or Set top of System Ram
|
||||
|
||||
Registers In : .C = 1 (Read MemTop) | .C = 0 (Set MemTop)
|
||||
| .XY = top of memory
|
||||
Registers Out : .XY = top of memory | None.
|
||||
Memory Changed: None. | Top of memory changed.
|
||||
Note : On the C=128, this routine refers to the top of BANK 0 RAM, not
|
||||
BANK 1 RAM.
|
||||
|
||||
$FF9C MEMBOT Read or Set bottom of System Ram
|
||||
|
||||
Registers In : .C = 1 (Read MemBot) | .C = 0 (Set MemBot)
|
||||
| .XY = bottom of memory.
|
||||
Registers Out : .XY = bottom of memory | None.
|
||||
Memory Changed: None. | Bottom of Memory changed.
|
||||
Note : On the C=128, this routine refers to the bottom of BANK 0 RAM,
|
||||
not, BANK 1 RAM.
|
||||
|
||||
$FF9F KEY Scans Keyboard
|
||||
|
||||
Registers In : None.
|
||||
Registers Out : None.
|
||||
Memory Changed: Relevant System Keyboard Values
|
||||
|
||||
$FFA2 SETMO
|
||||
|
||||
This is a routine who's code never made it into any versions
|
||||
of the KERNAL on the C64, Vic-20 and C128. Thus it is of no
|
||||
pratical use.
|
||||
|
||||
$FFA5 ACPTR Get byte from current talker.
|
||||
|
||||
Registers In : None.
|
||||
Registers Out : .A = data byte.
|
||||
Memory Changed: None.
|
||||
Note : Low level serial I/O - recommended use OPEN,CLOSE,CHROUT etc..
|
||||
|
||||
$FFA8 CIOUT Output byte to current listener.
|
||||
|
||||
Registers In : .A = byte.
|
||||
Registers Out : .A used.
|
||||
Memory Changed: None.
|
||||
Note : Low level serial I/O - recommended use OPEN,CLOSE,CHROUT etc..
|
||||
|
||||
$FFAB UNTLK Commands current TALK device to stop TALKING.
|
||||
|
||||
Registers In : None.
|
||||
Registers Out : .A used.
|
||||
Memory Changed: None.
|
||||
Note : Low level serial I/O - recommended use OPEN,CLOSE,CHROUT etc..
|
||||
|
||||
$FFAE UNLSN Commands current listening device to stop listening.
|
||||
|
||||
Registers In : None.
|
||||
Registers Out : .A used.
|
||||
Memory Changed: None.
|
||||
Note : Low level serial I/O - recommended use OPEN,CLOSE,CHROUT etc..
|
||||
|
||||
$FFB1 LISTN Commands device to begin listening.
|
||||
|
||||
Registers In : .A = device #.
|
||||
Registers Out : .A used.
|
||||
Note : Low level serial I/O - recommended use OPEN,CLOSE,CHROUT etc..
|
||||
|
||||
$FFB4 TALK Commands device to begin talking.
|
||||
|
||||
Registers In : .A = device #.
|
||||
Registers Out : .A used.
|
||||
Memory Changed: None.
|
||||
Note : Low level serial I/O - recommended use OPEN,CLOSE,CHROUT etc..
|
||||
|
||||
$FFB7 READSS Return I/O status byte.
|
||||
|
||||
Registers In : None.
|
||||
Registers Out : .A = status byte. (see section on ERROR messages).
|
||||
Memory Changed: None.
|
||||
|
||||
$FFBA SETLFS Set logical file #, device #, secondary # for I/O.
|
||||
|
||||
Registers In : .A = logical file #, .X = device #, .Y = secondary #
|
||||
Registers Out : None.
|
||||
Memory Changed: None.
|
||||
|
||||
$FFBD SETNAM Sets pointer to filename in preperation for OPEN.
|
||||
|
||||
Registers In : .A = string length, .XY = string address.
|
||||
Registers Out : None.
|
||||
Memory Changed: None.
|
||||
Note : To specify _no_ filename specify a length of 0.
|
||||
|
||||
$FFC0 OPEN Open up file that has been setup by SETNAM,SETLFS
|
||||
|
||||
Registers In : None.
|
||||
Registers Out : .A = error code, .X,.Y destroyed.
|
||||
.C = 1 if error.
|
||||
Memory Changed: None.
|
||||
|
||||
$FFC3 CLOSE Close a logical file.
|
||||
|
||||
Registers In : .A = logical file #.
|
||||
Registers Out : .A = error code, .X,.Y destroyed.
|
||||
.C = 1 if error
|
||||
Memory Changed: None.
|
||||
|
||||
$FFC6 CHKIN Sets input channel.
|
||||
|
||||
Registers In : .X = logical file #.
|
||||
Registers Out : .A = error code, .X,.Y destroyed.
|
||||
.C = 1 if error
|
||||
Memory Changed: None.
|
||||
|
||||
$FFC9 CHKOUT Sets output channel.
|
||||
|
||||
Registers In : .X = logical file #.
|
||||
Registers Out : .A = error code, .X,.Y destroyed.
|
||||
.C = 1 if error
|
||||
Memory Changed: None.
|
||||
|
||||
$FFCC CLRCH Restore default input and output channels.
|
||||
|
||||
Registers In : None.
|
||||
Registers Out : .A, .X used.
|
||||
Memory Changed: None.
|
||||
|
||||
$FFCF BASIN Read character from current input channel.
|
||||
|
||||
Cassette - Returned one character a time from cassette buffer.
|
||||
Rs-232 - Return one character at a time, waiting until
|
||||
character is ready.
|
||||
Serial - Returned one character at time, waiting if nessc.
|
||||
Screen - Read from current cursor position.
|
||||
Keyboard - Read characters as a string, then return them
|
||||
individually upon each call until all characters
|
||||
have been passed ($0d is the EOL).
|
||||
|
||||
Registers In : None.
|
||||
Registers Out : .A = character or error code, .C = 1 if error.
|
||||
Memory Changed: None.
|
||||
|
||||
$FFD2 BSOUT Output byte to current channel
|
||||
|
||||
Registers In : .A = Byte
|
||||
Registers Out : .C = 1 if ERROR (examine READST)
|
||||
Memory Changed: Dependent upon current device.
|
||||
|
||||
$FFD5 LOAD Loads file into memory (setup via SETLFS,SETNAM)..
|
||||
|
||||
Registers In : .A = 0 - Load, Non-0 = Verify
|
||||
.XY = load address (if secondary address = 0)
|
||||
Registers Out : .A = error code .C = 1 if error.
|
||||
.XY = ending address
|
||||
Memory Changed: As per registers / data file.
|
||||
|
||||
$FFD8 SAVE Save section of memory to a file.
|
||||
|
||||
Registers In : .A = Z-page ptr to start adress
|
||||
.XY = end address
|
||||
Registers Out : .A = error code, .C = 1 if error.
|
||||
.XY = used.
|
||||
Memory Changed: None.
|
||||
|
||||
$FFDB SETTIM Set internal clock (TI$).
|
||||
|
||||
Registers In : .AXY - Clock value in jiffies (1/60 secs).
|
||||
Registers Out : None.
|
||||
Memory Changed: Relevant system time locations set.
|
||||
|
||||
$FFDE RDTIM Reads internal clock (TI$)
|
||||
|
||||
Registers In : None.
|
||||
Registers Out : .AXY - Clock value in jiffies (1/60 secs).
|
||||
Memory Changed: None.
|
||||
|
||||
$FFE1 STOP Scans STOP key.
|
||||
|
||||
Registers In : None.
|
||||
Registers Out : .A = last keyboard row, .X = destroyed (if stop key)
|
||||
Memory Changed: None.
|
||||
Note : The last keyboard row is as follows:
|
||||
.A -> | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0
|
||||
KEY: |STOP |Q |C= |SPACE|2 |CTRL |<- |1
|
||||
|
||||
$FFE4 GETIN Read buffered data from file.
|
||||
|
||||
Keyboard - Read from keyboard buffer, else return null ($00).
|
||||
Rs-232 - Read from Rs-232 buffer, else null is returned.
|
||||
Serial - See BASIN
|
||||
Cassette - See BASIN
|
||||
Screen - See BASIN
|
||||
Registers In : None.
|
||||
Registers Out : .A = character, .C = 1 if error.
|
||||
.XY = used.
|
||||
Memory Changed: None.
|
||||
|
||||
$FFE7 CLALL Close all open files and channels.
|
||||
|
||||
Registers In : None.
|
||||
Registers Out : .AX used.
|
||||
Memory Changed: None.
|
||||
Note : This routine does not _actually_ close the files, rather it
|
||||
removes their prescense from the file tables held in memory.
|
||||
It's recommended to use close to close files instead of using
|
||||
this routine.
|
||||
|
||||
|
||||
$FFEA UDTIME Update internal (TI$) clock by 1 jiffie (1/60 sec).
|
||||
|
||||
Registers In : None.
|
||||
Registers Out : .A,.X destroyed.
|
||||
Memory Changed: Relevant system time locations changed.
|
||||
|
||||
$FFED SCRORG Returns current window/screen size
|
||||
|
||||
Registers In : None.
|
||||
Registers Out : .X - Window Row Max
|
||||
.Y - Window Col Max
|
||||
.A - Screen Col Max (128 only, 64 unchanged)
|
||||
Memory Changed: None
|
||||
|
||||
$FFF0 PLOT Read or set cursor position.
|
||||
|
||||
Registers In : .C = 1 (Read) | .C = 0 (Set)
|
||||
None. | .X = Col
|
||||
| .Y = Row
|
||||
Registers Out : .C = 1 (Read) | .C = 0 (Set)
|
||||
.X = Current Col | None.
|
||||
.Y = Current Row |
|
||||
Memory Changed: None | Screen Editor Locations.
|
||||
|
||||
$FFF3 IOBASE Returns base of I/O Block
|
||||
|
||||
Registers In : None.
|
||||
Registers Out : .XY = address of I/O block ($D000)
|
||||
Memory Changed: Screen Editor Locations.
|
||||
1901
kernal/kernal_dh.txt
Normal file
1901
kernal/kernal_dh.txt
Normal file
File diff suppressed because it is too large
Load diff
173
kernal/kernal_fk.txt
Normal file
173
kernal/kernal_fk.txt
Normal file
|
|
@ -0,0 +1,173 @@
|
|||
-
|
||||
- C64 KERNAL jump table, composed by Frank Kontros (jeno@kontr.uzhgorod.ua).
|
||||
- http://www.zimmers.net/anonftp/pub/cbm/c64/programming/documents/c64-kernal.txt
|
||||
-
|
||||
|
||||
$FF81 CINT init VIC & screen editor
|
||||
|
||||
- - - - - - A X Y
|
||||
|
||||
$FF84 IOINIT initialize CIA & IRQ
|
||||
|
||||
- - - - - - A X Y
|
||||
|
||||
$FF87 RAMTAS RAM test & search RAM end
|
||||
|
||||
- - - - - - A X Y
|
||||
|
||||
$FF8A RESTOR restore default I/O vectors
|
||||
|
||||
- - - - - - A - Y
|
||||
|
||||
$FF8D VECTOR read/set I/O vectors
|
||||
|
||||
in: C=0 moves from Y/X to vectors - X Y - X - A - Y
|
||||
C=1 moves vectors to Y/X - X Y - X - A - Y
|
||||
|
||||
$FF90 SETMSG enable/disable KERNAL messages
|
||||
|
||||
in: A bit7=1 error msgs on A - - - - - A - -
|
||||
bit6=1 control msgs on
|
||||
|
||||
$FF93 SECOND send secondary addr after listen
|
||||
|
||||
in: A=secondary address A - - - - - A - -
|
||||
|
||||
$FF96 TKSA send secondary addr after talk
|
||||
|
||||
in: A=secondary address A - - - - - A - -
|
||||
|
||||
$FF99 MEMTOP read/set top of memory
|
||||
|
||||
in: C=0; Y/X address - X Y - X Y - - -
|
||||
out:C=1; Y/X address - - - - X Y - X Y
|
||||
|
||||
$FF9C MEMBOT read/set bottom of memory
|
||||
|
||||
in: C=0; Y/X address - X Y - X Y - - -
|
||||
out:C=1; Y/X address - - - - X Y - X Y
|
||||
|
||||
$FF9F SCNKEY scan keyboard
|
||||
|
||||
- - - - - - A X Y
|
||||
|
||||
$FFA2 SETTMO set IEEE timeout
|
||||
|
||||
in: A bit7=1 disable, bit7=0 enable A - - A - - - - -
|
||||
|
||||
$FFA5 ACPTR input byte from SERIAL
|
||||
|
||||
out:A=byte, C=1 and ST=2 if timeout - - - A - - A - -
|
||||
|
||||
$FFA8 CIOUT output byte to SERIAL
|
||||
|
||||
in: A=byte, C=1 and ST=3 if timeout A - - A - - - - -
|
||||
|
||||
$FFAB UNTLK untalk all SERIAL devices
|
||||
- - - - - - A - -
|
||||
|
||||
$FFAE UNLSN unlisten all SERIAL devices
|
||||
- - - - - - A - -
|
||||
|
||||
$FFB1 LISTEN make SERIAL device listen
|
||||
|
||||
in: A=device number A - - - - - A - -
|
||||
|
||||
$FFB4 TALK make SERIAL device talk
|
||||
|
||||
in: A=device number A - - - - - A - -
|
||||
|
||||
$FFB7 READST read I/O status byte
|
||||
|
||||
out:A=status byte - - - A - - A - -
|
||||
|
||||
$FFBA SETLFS set file parameters
|
||||
|
||||
in: A=logical file number A X Y A X Y - - -
|
||||
X=device number
|
||||
Y=secondary addr
|
||||
|
||||
$FFBD SETNAM set file name
|
||||
|
||||
in: A=length of filename A X Y A X Y - - -
|
||||
Y/X=pointer to name addr
|
||||
|
||||
$FFC0 OPEN open log.file after SETLFS,SETNAM
|
||||
|
||||
out:A=error# if C=1 - - - - - - A X Y
|
||||
|
||||
$FFC3 CLOSE close a logical file
|
||||
|
||||
in: A=logical file number A - - - - - A X Y
|
||||
|
||||
$FFC6 CHKIN open channel for input
|
||||
|
||||
in: X=logical file number - X - - - - A X -
|
||||
|
||||
$FFC9 CHKOUT open channel for output
|
||||
|
||||
in: X=logical file number - X - - - - A X -
|
||||
|
||||
$FFCC CLRCHN restore default devices
|
||||
|
||||
- - - - - - A X -
|
||||
|
||||
$FFCF CHRIN input character
|
||||
|
||||
out:A=character, C=1 and ST=error - - - A - - A - -
|
||||
|
||||
$FFD2 CHROUT output character
|
||||
|
||||
in: A=character, C=1 and ST=error A - - A - - - - -
|
||||
|
||||
$FFD5 LOAD load after call SETLFS,SETNAM
|
||||
|
||||
in: A=0 load, a=1 verify A X Y A X Y A X Y
|
||||
Y/X = dest.addr if sec.addr=0
|
||||
|
||||
$FFD8 SAVE save after call SETLFS,SETNAM
|
||||
|
||||
in: A=zero page pointer to start.addr A X Y - - - A X Y
|
||||
Y/X=ending address
|
||||
|
||||
$FFDB SETTIM set jiffy clock
|
||||
|
||||
in: A=MSB, X=middle, Y=LSB A X Y - - - - - -
|
||||
|
||||
$FFDE RDTIM read jiffy clock
|
||||
|
||||
out:A=MSB, X=middle, Y=LSB - - - A X Y A X Y
|
||||
|
||||
$FFE1 STOP check stop key
|
||||
|
||||
out:Z=0 if STOP not used; X unchanged - - - A - - A - -
|
||||
Z=1 if STOP used; X changed - - - A - - A X -
|
||||
A=last line of keyboard matrix
|
||||
|
||||
$FFE4 GETIN get a byte from channel
|
||||
|
||||
out:keyboard:A=0 if puffer empty - - - A - - A X Y
|
||||
RS232:status byte - - - A - - A - -
|
||||
serial:status byte - - - A - - A - -
|
||||
tape:status byte - - - A - - A - Y
|
||||
|
||||
$FFE7 CLALL close or abort all files
|
||||
|
||||
- - - - - - A X -
|
||||
|
||||
$FFEA UDTIM update jiffy clock
|
||||
|
||||
- - - - - - A X -
|
||||
|
||||
$FFED SCREEN return screen size
|
||||
|
||||
out:X=columns, Y=rows - - - - X Y - X Y
|
||||
|
||||
$FFF0 PLOT read/set cursor position
|
||||
|
||||
in: C=0, X=row, Y=column - X Y - X Y - - -
|
||||
out:C=1, X=row, Y=column - - - - X Y - X Y
|
||||
|
||||
$FFF3 IOBASE returns the addr of I/O devices
|
||||
|
||||
out:Y/X=addr($DC00) - - - - X Y - X Y
|
||||
416
kernal/kernal_ld.txt
Normal file
416
kernal/kernal_ld.txt
Normal file
|
|
@ -0,0 +1,416 @@
|
|||
-
|
||||
- The almost completely commented C64 ROM disassembly. V1.01 Lee Davison 2012
|
||||
-
|
||||
|
||||
$FF81 initialise VIC and screen editor
|
||||
|
||||
|
||||
|
||||
$FF84 initialise SID, CIA and IRQ, unused
|
||||
|
||||
|
||||
|
||||
$FF87 RAM test and find RAM end
|
||||
|
||||
|
||||
|
||||
$FF8A restore default I/O vectors
|
||||
|
||||
This routine restores the default values of all system vectors used in KERNAL and
|
||||
BASIC routines and interrupts.
|
||||
|
||||
|
||||
|
||||
$FF8D read/set vectored I/O
|
||||
|
||||
This routine manages all system vector jump addresses stored in RAM. Calling this
|
||||
routine with the carry bit set will store the current contents of the RAM vectors
|
||||
in a list pointed to by the X and Y registers. When this routine is called with
|
||||
the carry bit clear, the user list pointed to by the X and Y registers is copied
|
||||
to the system RAM vectors.
|
||||
|
||||
NOTE: This routine requires caution in its use. The best way to use it is to first
|
||||
read the entire vector contents into the user area, alter the desired vectors and
|
||||
then copy the contents back to the system vectors.
|
||||
|
||||
|
||||
|
||||
$FF90 control kernal messages
|
||||
|
||||
This routine controls the printing of error and control messages by the KERNAL.
|
||||
Either print error messages or print control messages can be selected by setting
|
||||
the accumulator when the routine is called.
|
||||
|
||||
FILE NOT FOUND is an example of an error message. PRESS PLAY ON CASSETTE is an
|
||||
example of a control message.
|
||||
|
||||
Bits 6 and 7 of this value determine where the message will come from. If bit 7
|
||||
is set one of the error messages from the KERNAL will be printed. If bit 6 is set
|
||||
a control message will be printed.
|
||||
|
||||
|
||||
$FF93 send secondary address after LISTEN
|
||||
|
||||
This routine is used to send a secondary address to an I/O device after a call to
|
||||
the LISTEN routine is made and the device commanded to LISTEN. The routine cannot
|
||||
be used to send a secondary address after a call to the TALK routine.
|
||||
|
||||
A secondary address is usually used to give set-up information to a device before
|
||||
I/O operations begin.
|
||||
|
||||
When a secondary address is to be sent to a device on the serial bus the address
|
||||
must first be ORed with $60.
|
||||
|
||||
|
||||
$FF96 send secondary address after TALK
|
||||
|
||||
This routine transmits a secondary address on the serial bus for a TALK device.
|
||||
This routine must be called with a number between 4 and 31 in the accumulator.
|
||||
The routine will send this number as a secondary address command over the serial
|
||||
bus. This routine can only be called after a call to the TALK routine. It will
|
||||
not work after a LISTEN.
|
||||
|
||||
|
||||
$FF99 read/set the top of memory
|
||||
|
||||
This routine is used to read and set the top of RAM. When this routine is called
|
||||
with the carry bit set the pointer to the top of RAM will be loaded into XY. When
|
||||
this routine is called with the carry bit clear XY will be saved as the top of
|
||||
memory pointer changing the top of memory.
|
||||
|
||||
|
||||
$FF9C read/set the bottom of memory
|
||||
|
||||
This routine is used to read and set the bottom of RAM. When this routine is
|
||||
called with the carry bit set the pointer to the bottom of RAM will be loaded
|
||||
into XY. When this routine is called with the carry bit clear XY will be saved as
|
||||
the bottom of memory pointer changing the bottom of memory.
|
||||
|
||||
|
||||
$FF9F scan the keyboard
|
||||
|
||||
This routine will scan the keyboard and check for pressed keys. It is the same
|
||||
routine called by the interrupt handler. If a key is down, its ASCII value is
|
||||
placed in the keyboard queue.
|
||||
|
||||
|
||||
$FFA2 set timeout on serial bus
|
||||
|
||||
This routine sets the timeout flag for the serial bus. When the timeout flag is
|
||||
set, the computer will wait for a device on the serial port for 64 milliseconds.
|
||||
If the device does not respond to the computer's DAV signal within that time the
|
||||
computer will recognize an error condition and leave the handshake sequence. When
|
||||
this routine is called and the accumulator contains a 0 in bit 7, timeouts are
|
||||
enabled. A 1 in bit 7 will disable the timeouts.
|
||||
|
||||
NOTE: The the timeout feature is used to communicate that a disk file is not found
|
||||
on an attempt to OPEN a file.
|
||||
|
||||
|
||||
$FFA5 input byte from serial bus
|
||||
|
||||
This routine reads a byte of data from the serial bus using full handshaking. the
|
||||
data is returned in the accumulator. before using this routine the TALK routine,
|
||||
$FFB4, must have been called first to command the device on the serial bus to
|
||||
send data on the bus. if the input device needs a secondary command it must be sent
|
||||
by using the TKSA routine, $FF96, before calling this routine.
|
||||
|
||||
Errors are returned in the status word which can be read by calling the READST
|
||||
routine, $FFB7.
|
||||
|
||||
|
||||
$FFA8 output a byte to serial bus
|
||||
|
||||
This routine is used to send information to devices on the serial bus. A call to
|
||||
this routine will put a data byte onto the serial bus using full handshaking.
|
||||
Before this routine is called the LISTEN routine, $FFB1, must be used to
|
||||
command a device on the serial bus to get ready to receive data.
|
||||
|
||||
The accumulator is loaded with a byte to output as data on the serial bus. A
|
||||
device must be listening or the status word will return a timeout. This routine
|
||||
always buffers one character. So when a call to the UNLISTEN routine, $FFAE,
|
||||
is made to end the data transmission, the buffered character is sent with EOI
|
||||
set. Then the UNLISTEN command is sent to the device.
|
||||
|
||||
|
||||
$FFAB command serial bus to UNTALK
|
||||
|
||||
This routine will transmit an UNTALK command on the serial bus. All devices
|
||||
previously set to TALK will stop sending data when this command is received.
|
||||
|
||||
|
||||
$FFAE command serial bus to UNLISTEN
|
||||
|
||||
This routine commands all devices on the serial bus to stop receiving data from
|
||||
the computer. Calling this routine results in an UNLISTEN command being transmitted
|
||||
on the serial bus. Only devices previously commanded to listen will be affected.
|
||||
|
||||
This routine is normally used after the computer is finished sending data to
|
||||
external devices. Sending the UNLISTEN will command the listening devices to get
|
||||
off the serial bus so it can be used for other purposes.
|
||||
|
||||
|
||||
$FFB1 command devices on the serial bus to LISTEN
|
||||
|
||||
This routine will command a device on the serial bus to receive data. The
|
||||
accumulator must be loaded with a device number between 4 and 31 before calling
|
||||
this routine. LISTEN convert this to a listen address then transmit this data as
|
||||
a command on the serial bus. The specified device will then go into listen mode
|
||||
and be ready to accept information.
|
||||
|
||||
|
||||
$FFB4 command serial bus device to TALK
|
||||
|
||||
To use this routine the accumulator must first be loaded with a device number
|
||||
between 4 and 30. When called this routine converts this device number to a talk
|
||||
address. Then this data is transmitted as a command on the Serial bus.
|
||||
|
||||
|
||||
$FFB7 read I/O status word
|
||||
|
||||
This routine returns the current status of the I/O device in the accumulator. The
|
||||
routine is usually called after new communication to an I/O device. The routine
|
||||
will give information about device status, or errors that have occurred during the
|
||||
I/O operation.
|
||||
|
||||
|
||||
$FFBA set logical, first and second addresses
|
||||
|
||||
This routine will set the logical file number, device address, and secondary
|
||||
address, command number, for other KERNAL routines.
|
||||
|
||||
the logical file number is used by the system as a key to the file table created
|
||||
by the OPEN file routine. Device addresses can range from 0 to 30. The following
|
||||
codes are used by the computer to stand for the following CBM devices:
|
||||
|
||||
| ADDRESS | DEVICE |
|
||||
|---------|---------------------------|
|
||||
| 0 | Keyboard |
|
||||
| 1 | Cassette #1 |
|
||||
| 2 | RS-232C device |
|
||||
| 3 | CRT display |
|
||||
| 4 | Serial bus printer |
|
||||
| 8 | CBM Serial bus disk drive |
|
||||
|
||||
Device numbers of four or greater automatically refer to devices on the serial
|
||||
bus.
|
||||
|
||||
A command to the device is sent as a secondary address on the serial bus after
|
||||
the device number is sent during the serial attention handshaking sequence. If
|
||||
no secondary address is to be sent Y should be set to $FF.
|
||||
|
||||
|
||||
$FFBD set the filename
|
||||
|
||||
This routine is used to set up the file name for the OPEN, SAVE, or LOAD routines.
|
||||
The accumulator must be loaded with the length of the file and XY with the pointer
|
||||
to file name, X being th low byte. The address can be any valid memory address in
|
||||
the system where a string of characters for the file name is stored. If no file
|
||||
name desired the accumulator must be set to 0, representing a zero file length,
|
||||
in that case XY may be set to any memory address.
|
||||
|
||||
|
||||
$FFC0 open a logical file
|
||||
|
||||
This routine is used to open a logical file. Once the logical file is set up it
|
||||
can be used for input/output operations. Most of the I/O KERNAL routines call on
|
||||
this routine to create the logical files to operate on. No arguments need to be
|
||||
set up to use this routine, but both the SETLFS, $FFBA, and SETNAM, $FFBD,
|
||||
KERNAL routines must be called before using this routine.
|
||||
|
||||
|
||||
|
||||
$FFC3 close a specified logical file
|
||||
|
||||
This routine is used to close a logical file after all I/O operations have been
|
||||
completed on that file. This routine is called after the accumulator is loaded
|
||||
with the logical file number to be closed, the same number used when the file was
|
||||
opened using the OPEN routine.
|
||||
|
||||
|
||||
$FFC6 open channel for input
|
||||
|
||||
Any logical file that has already been opened by the OPEN routine, $FFC0, can be
|
||||
defined as an input channel by this routine. the device on the channel must be an
|
||||
input device or an error will occur and the routine will abort.
|
||||
|
||||
If you are getting data from anywhere other than the keyboard, this routine must be
|
||||
called before using either the CHRIN routine, $FFCF, or the GETIN routine,
|
||||
$FFE4. if you are getting data from the keyboard and no other input channels are
|
||||
open then the calls to this routine and to the OPEN routine, $FFC0, are not needed.
|
||||
|
||||
When used with a device on the serial bus this routine will automatically send the
|
||||
listen address specified by the OPEN routine, $FFC0, and any secondary address.
|
||||
|
||||
Possible errors are:
|
||||
|
||||
* 3 : file not open
|
||||
* 5 : device not present
|
||||
* 6 : file is not an input file
|
||||
|
||||
|
||||
$FFC9 open channel for output
|
||||
|
||||
Any logical file that has already been opened by the OPEN routine, $FFC0, can be
|
||||
defined as an output channel by this routine the device on the channel must be an
|
||||
output device or an error will occur and the routine will abort.
|
||||
|
||||
If you are sending data to anywhere other than the screen this routine must be
|
||||
called before using the CHROUT routine, $FFD2. if you are sending data to the
|
||||
screen and no other output channels are open then the calls to this routine and to
|
||||
the OPEN routine, $FFC0, are not needed.
|
||||
|
||||
When used with a device on the serial bus this routine will automatically send the
|
||||
listen address specified by the OPEN routine, $FFC0, and any secondary address.
|
||||
|
||||
Possible errors are:
|
||||
|
||||
* 3 : file not open
|
||||
* 5 : device not present
|
||||
* 7 : file is not an output file
|
||||
|
||||
|
||||
$FFCC close input and output channels
|
||||
|
||||
This routine is called to clear all open channels and restore the I/O channels to
|
||||
their original default values. It is usually called after opening other I/O
|
||||
channels and using them for input/output operations. The default input device is
|
||||
0, the keyboard. The default output device is 3, the screen.
|
||||
|
||||
If one of the channels to be closed is to the serial port, an UNTALK signal is sent
|
||||
first to clear the input channel or an UNLISTEN is sent to clear the output channel.
|
||||
By not calling this routine and leaving listener(s) active on the serial bus,
|
||||
several devices can receive the same data from the VIC at the same time. One way to
|
||||
take advantage of this would be to command the printer to TALK and the disk to
|
||||
LISTEN. This would allow direct printing of a disk file.
|
||||
|
||||
|
||||
$FFCF input character from channel
|
||||
|
||||
This routine will get a byte of data from the channel already set up as the input
|
||||
channel by the CHKIN routine, $FFC6.
|
||||
|
||||
If CHKIN, $FFC6, has not been used to define another input channel the data is
|
||||
expected to be from the keyboard. the data byte is returned in the accumulator. the
|
||||
channel remains open after the call.
|
||||
|
||||
Input from the keyboard is handled in a special way. first, the cursor is turned on
|
||||
and it will blink until a carriage return is typed on the keyboard. all characters
|
||||
on the logical line, up to 80 characters, will be stored in the BASIC input buffer.
|
||||
then the characters can be returned one at a time by calling this routine once for
|
||||
each character. when the carriage return is returned the entire line has been
|
||||
processed. the next time this routine is called the whole process begins again.
|
||||
|
||||
|
||||
$FFD2 output character to channel
|
||||
|
||||
This routine will output a character to an already opened channel. Use the OPEN
|
||||
routine, $FFC0, and the CHKOUT routine, $FFC9, to set up the output channel
|
||||
before calling this routine. If these calls are omitted, data will be sent to the
|
||||
default output device, device 3, the screen. The data byte to be output is loaded
|
||||
into the accumulator, and this routine is called. The data is then sent to the
|
||||
specified output device. The channel is left open after the call.
|
||||
|
||||
NOTE: Care must be taken when using routine to send data to a serial device since
|
||||
data will be sent to all open output channels on the bus. Unless this is desired,
|
||||
all open output channels on the serial bus other than the actually intended
|
||||
destination channel must be closed by a call to the KERNAL close channel routine.
|
||||
|
||||
|
||||
$FFD5 load RAM from a device
|
||||
|
||||
This routine will load data bytes from any input device directly into the memory
|
||||
of the computer. It can also be used for a verify operation comparing data from a
|
||||
device with the data already in memory, leaving the data stored in RAM unchanged.
|
||||
|
||||
The accumulator must be set to 0 for a load operation or 1 for a verify. If the
|
||||
input device was OPENed with a secondary address of 0 the header information from
|
||||
device will be ignored. In this case XY must contain the starting address for the
|
||||
load. If the device was addressed with a secondary address of 1 or 2 the data will
|
||||
load into memory starting at the location specified by the header. This routine
|
||||
returns the address of the highest RAM location which was loaded.
|
||||
|
||||
Before this routine can be called, the SETLFS, $FFBA, and SETNAM, $FFBD,
|
||||
routines must be called.
|
||||
|
||||
|
||||
$FFD8 save RAM to a device
|
||||
|
||||
This routine saves a section of memory. Memory is saved from an indirect address
|
||||
on page 0 specified by A, to the address stored in XY, to a logical file. The
|
||||
SETLFS, $FFBA, and SETNAM, $FFBD, routines must be used before calling this
|
||||
routine. However, a file name is not required to SAVE to device 1, the cassette.
|
||||
Any attempt to save to other devices without using a file name results in an error.
|
||||
|
||||
NOTE: device 0, the keyboard, and device 3, the screen, cannot be SAVEd to. If
|
||||
the attempt is made, an error will occur, and the SAVE stopped.
|
||||
|
||||
|
||||
$FFDB set the real time clock
|
||||
|
||||
The system clock is maintained by an interrupt routine that updates the clock
|
||||
every 1/60th of a second. The clock is three bytes long which gives the capability
|
||||
to count from zero up to 5,184,000 jiffies - 24 hours plus one jiffy. At that point
|
||||
the clock resets to zero. Before calling this routine to set the clock the new time,
|
||||
in jiffies, should be in YXA, the accumulator containing the most significant byte.
|
||||
|
||||
|
||||
$FFDE read the real time clock
|
||||
|
||||
This routine returns the time, in jiffies, in AXY. The accumulator contains the
|
||||
most significant byte.
|
||||
|
||||
|
||||
$FFE1 scan the stop key
|
||||
|
||||
If the STOP key on the keyboard is pressed when this routine is called the Z flag
|
||||
will be set. All other flags remain unchanged. If the STOP key is not pressed then
|
||||
the accumulator will contain a byte representing the last row of the keyboard scan.
|
||||
|
||||
The user can also check for certain other keys this way.
|
||||
|
||||
|
||||
$FFE4 get character from input device
|
||||
|
||||
In practice this routine operates identically to the CHRIN routine, $FFCF,
|
||||
for all devices except for the keyboard. If the keyboard is the current input
|
||||
device this routine will get one character from the keyboard buffer. It depends
|
||||
on the IRQ routine to read the keyboard and put characters into the buffer.
|
||||
|
||||
If the keyboard buffer is empty the value returned in the accumulator will be zero.
|
||||
|
||||
|
||||
$FFE7 close all channels and files
|
||||
|
||||
This routine closes all open files. When this routine is called, the pointers into
|
||||
the open file table are reset, closing all files. Also the routine automatically
|
||||
resets the I/O channels.
|
||||
|
||||
|
||||
$FFEA increment real time clock
|
||||
|
||||
This routine updates the system clock. Normally this routine is called by the
|
||||
normal KERNAL interrupt routine every 1/60th of a second. If the user program
|
||||
processes its own interrupts this routine must be called to update the time. Also,
|
||||
the STOP key routine must be called if the stop key is to remain functional.
|
||||
|
||||
|
||||
$FFED return X,Y organization of screen
|
||||
|
||||
This routine returns the x,y organisation of the screen in X,Y
|
||||
|
||||
|
||||
$FFF0 read/set X,Y cursor position
|
||||
|
||||
This routine, when called with the carry flag set, loads the current position of
|
||||
the cursor on the screen into the X and Y registers. X is the column number of
|
||||
the cursor location and Y is the row number of the cursor. A call with the carry
|
||||
bit clear moves the cursor to the position determined by the X and Y registers.
|
||||
|
||||
|
||||
$FFF3 return the base address of the I/O devices
|
||||
|
||||
This routine will set XY to the address of the memory section where the memory
|
||||
mapped I/O devices are located. This address can then be used with an offset to
|
||||
access the memory mapped I/O devices in the computer.
|
||||
|
||||
438
kernal/kernal_mapc64.txt
Normal file
438
kernal/kernal_mapc64.txt
Normal file
|
|
@ -0,0 +1,438 @@
|
|||
$FF81 CINT Initialize Screen Editor and VIC-II Chip
|
||||
|
||||
The start of the routine appears to be a patch that was added to later
|
||||
versions of the Kernal. It first calls the old routine at 58648
|
||||
($E518). This initializes the VIC-II chip to the default values, sets
|
||||
the keyboard as the input device and the screen as the output device,
|
||||
initializes the cursor flash variables, builds the screen line link
|
||||
table, clears the screen, and homes the cursor. The new code then
|
||||
checks the VIC Interrupt register to see if the conditions for a
|
||||
Raster Compare IRQ have been fulfilled. Since the Raster Register was
|
||||
initialized to 311, that can only occur when using a PAL system (NTSC
|
||||
screens do not have that many scan lines). The PAL/NTSC register at
|
||||
678 ($2A6) is set on the basis of the outcome of this test. The CIA
|
||||
#1 Timer A is then set to cause an IRQ interrupt every sixtieth of a
|
||||
second, using the prescaler figures for a PAL or NTSC system, as
|
||||
appropriate.
|
||||
|
||||
$FF84 IOINIT Initialize CIA I/O Devices
|
||||
|
||||
This routine intializes the Complex Interface Adapter (CIA)
|
||||
devices, and turns the volume of the SID chip off. As part of this
|
||||
initialization, it sets CIA #1 Timer A to cause an IRQ interrupt every
|
||||
sixtieth of a second.
|
||||
|
||||
$FF87 RAMTAS Perform RAM Test and Set Pointers to the Top and Bottom of RAM
|
||||
|
||||
This routine performs a number of initialization tasks.
|
||||
|
||||
First, it clears Pages 0, 2, and 3 of memory to zeros. Next, it sets
|
||||
the tape buffer pointer to address 828 ($33C), and performs a
|
||||
nondestructive test of RAM from 1024 ($400) up. When it reaches a
|
||||
non-RAM address (presumably the BASIC ROM at 40960 ($A000)), that
|
||||
address is placed in the top of memory pointer at 643-4 ($283-4). The
|
||||
bottom of memory pointer at 641-2 ($281-2) is set to point to address
|
||||
2048 ($800), which is the beginning of BASIC program text. Finally,
|
||||
the pointer to screen memory at 648 ($288) is set to 4, which lets the
|
||||
Operating System know that screen memory starts at 1024 ($400).
|
||||
|
||||
$FF8A RESTOR Restore RAM Vectors for Default I/O Routines
|
||||
|
||||
This routine sets the values for the 16 RAM vectors to the interrupt and
|
||||
important Kernal I/O routines in the table that starts at 788 ($314)
|
||||
to the standard values held in the ROM table at 64816 ($FD30).
|
||||
|
||||
$FF8D VECTOR Set the RAM Vector Table from the Table Pointed to by .X and .Y
|
||||
|
||||
This routine is used to read or change the values for the 16 RAM vectors to the
|
||||
interrupt and important Kernal I/O routines in the table that starts
|
||||
at 788 ($314). If the Carry flag is set when the routine is called,
|
||||
the current value of the 16 vectors will be stored at a table whose
|
||||
address is pointed to by the values in the .X and .Y registers. If
|
||||
the Carry flag is cleared, the RAM vectors will be loaded from the
|
||||
table whose address is pointed to by the .X and .Y registers. Since
|
||||
this routine can change the vectors for the IRQ and NMI interrupts,
|
||||
you might expect that the Interrupt disable flag would be set at its
|
||||
beginning. Such is not the case, however, and therefore it would be
|
||||
wise to execute an SEI before calling it and a CLI afterwards (as the
|
||||
power-on RESET routine does) just to be safe.
|
||||
|
||||
$FF90 SETMSG Set the Message Control Flag
|
||||
|
||||
This routine controls the printing of error messages and control
|
||||
messages by the Kernal. It Bit 6 is seto to 1 (bit value of 64),
|
||||
Kernal control messages can be printed. These messages include
|
||||
SEARCHING FOR, LOADING, and the like. If Bit 6 is cleared to 0, these
|
||||
messages will not be printed (BASIC will clear this bit when a program
|
||||
is running so that the messages do not appear when I/O is performed
|
||||
from a program). Setting Bit 6 will not suppress the PRESS PLAY ON
|
||||
TAPE or PRESS PLAY & RECORD messages, however.
|
||||
|
||||
If Bit 7 is set to 1 (bit value of 128), Kernal error messages can be
|
||||
printed. If Bit 7 is set to 0, those error messages (for example, I/O
|
||||
ERROR #nn) will be suppressed. Note that BASIC has its own set of
|
||||
error messages (such as FILE NOT FOUND ERROR) which it uses in
|
||||
preference to the Kernal's message.
|
||||
|
||||
$FF93 SECOND Send a Secondary Address to a Device on the Serial Bus after LISTEN
|
||||
|
||||
This routine sends a secondary address from the
|
||||
Accumulator to the device on the serial bus that has just been
|
||||
commanded to LISTEN. This is usually done to give the device more
|
||||
particular instructions on how the I/O is to be carried out before
|
||||
information is sent.
|
||||
|
||||
$FF96 TKSA Send a Secondary Address to a Device on the Serial Bus after TALK
|
||||
|
||||
This routine sends a secondary address from the
|
||||
Accumulator to the device on the serial bus that has just been
|
||||
commanded to TALK. This is usually done to give the device more
|
||||
particular instructions on how the I/O is to be carried out before
|
||||
information is sent.
|
||||
|
||||
$FF99 MEMTOP Read/Set Top of RAM Pointer
|
||||
|
||||
This routine can be used to either read or set the top of RAM pointer. If
|
||||
called with the Carry flag set, the address in the pointer will be
|
||||
loaded into the .X and .Y registers. If called with the Carry flag
|
||||
cleared, the pointer will be changed to the address found in the .X
|
||||
and .Y registers.
|
||||
|
||||
$FF9C MEMBOT Read/Set Bottom of RAM Pointer
|
||||
|
||||
This routine can be used to either read or set the bottom of RAM pointer. If
|
||||
called with the Carry flag set, the address in the pointer willbe
|
||||
loaded into the .X and .Y registers. If called with the Carry flag
|
||||
cleared, the pointer will be changed to the address found in the .X
|
||||
and .Y registers.
|
||||
|
||||
$FF9F SCNKEY Read the Keyboard
|
||||
|
||||
This subroutine is called by the IRQ interrupt handler above to read
|
||||
the keyboard device which is connected to CIA #1 (see entry for 56320
|
||||
($DC00) for details on how to read the keyboard).
|
||||
|
||||
This routine returns the keycode of the key
|
||||
currently being pressed in 203 ($CB), sets the shift/control flag if
|
||||
appropriate, and jumps through the vector at 655 ($28F) to the routine
|
||||
that sets up the proper table to translate the keycode to PETASCII.
|
||||
It concludes with the next routine, which places the PETASCII value of
|
||||
the character in the keyboard buffer.
|
||||
|
||||
$FFA2 SETTMO Set Time-Out Flag for IEEE Bus
|
||||
|
||||
This routine sets the time-out flag for the IEEE bus. When timeouts
|
||||
are enabled, the Commodore will wait for a device for 64 milliseconds,
|
||||
and if it does not receive a response to its signal it will issue a
|
||||
time-out error. Loading the Accumulator with a value less than 128
|
||||
and calling this routine will enable time-outs, while using a value
|
||||
over 128 will disable time-outs.
|
||||
|
||||
This routine is for use only with the Commodore IEEE add-on card,
|
||||
which at the time of this writing was not yet available.
|
||||
|
||||
$FFA5 ACPTR Receive a Byte of Data from a Device on the Serial Bus
|
||||
|
||||
When called, this routine will get a byte of data from
|
||||
the current TALKer on the serial bus and store it in the Accumulator.
|
||||
In order to receive the data, the device must have previously been
|
||||
sent a command to TALK and a secondary address if it needs one.
|
||||
|
||||
$FFA8 CIOUT Send a Byte to an I/O Device over the Serial Bus
|
||||
|
||||
This routine's purpose is to send a byte of data over
|
||||
the serial bus. In order for the data to be received, the serial
|
||||
device must have first been commanded to LISTEN and been given a
|
||||
secondary address if necessary. This routine always buffers the
|
||||
current character, and defers sending it until the next byte is
|
||||
buffered. When the UNLISTEN command is sent, the last byte will be
|
||||
sent with an End or Identify (EOI).
|
||||
|
||||
$FFAB UNTLK Send UNTALK to a Device on the Serial Bus
|
||||
|
||||
When called, this routine sends the UNTALK code (95, $5F) on the
|
||||
serial bus. This commands any TALKer on the bus to stop sending data.
|
||||
|
||||
$FFAE UNLSN Send UNLISTED to a Device on the Serial Bus
|
||||
|
||||
This routine sends the UNLISTEN code (63, $3F) on the serial
|
||||
bus. This commands any LISTENers to get off the serial bus, and frees
|
||||
up the bus for other users.
|
||||
|
||||
$FFB1 LISTEN Send LISTEN to a Device on the Serial Bus
|
||||
|
||||
When called, this routine ORs the device number in the
|
||||
Accumulator with the LISTEN code (32, $20) and sends it on the serial
|
||||
bus. This commands the device to LISTEN.
|
||||
|
||||
$FFB4 TALK Send TALK to a Device on the Serial Bus
|
||||
|
||||
When called, this routine ORs the device number in the
|
||||
Accumulator with the TALK code (64, $40) and sends it on the serial
|
||||
bus. This commands the device to TALK.
|
||||
|
||||
$FFB7 READST Read the I/O Status Word
|
||||
|
||||
Whenever an I/O error occurs, a bit of the Status Word is set to
|
||||
indicate what the problem was. This routine allows you to read the
|
||||
status word (it is returned in the Accumulator). If the device was
|
||||
the RS-232, its status register is read and cleared to zero. For the
|
||||
meanings of the various status codes, see the entry for location 144
|
||||
($90) or 663 ($297) for the RS-232 device.
|
||||
|
||||
$FFBA SETLFS Set Logical File Number, Device Number, and Secondary Address
|
||||
|
||||
This routine stores the value in the Accumulator in the location which holds the
|
||||
current logical file number, the value in the .X register is put in
|
||||
the location that holds the current device number, and the value in
|
||||
the .Y register is stored in the location that holds the current
|
||||
secondary address. If no secondary address is used, the .Y register
|
||||
should be set to 255 ($FF). It is necessary to set the values of the
|
||||
current file number, device number, and secondary address before you
|
||||
OPEN a file, or LOAD or SAVE.
|
||||
|
||||
$FFBD SETNAM Set Filename Parameters
|
||||
|
||||
This routine puts the value in the Accumulator into the location which stores
|
||||
the number of characters in the filename, and sets the pointer to the
|
||||
address of the ASCII text of the filename from the .X and .Y
|
||||
registers. This sets up the filename for the OPEN, LOAD, or SAVE
|
||||
routine.
|
||||
|
||||
$FFC0 OPEN Open a Logical I/O File
|
||||
|
||||
The routine jumps through a RAM vector at 794 ($31A). This routine
|
||||
assigns a logical file to a device, so that it can be used for
|
||||
Input/Output operations. In order to specify the logical file number,
|
||||
the device number, and the secondary address if any, the SETLFS
|
||||
routine must first be called. Likewise, in order to designate the
|
||||
filename, the SETNAM routine must be used first. After these two
|
||||
routines are called, OPEN is then called.
|
||||
|
||||
$FFC3 CLOSE Close a Logical I/O File
|
||||
|
||||
The routine jumps through a RAM vector at 796 ($31C). It is used to
|
||||
close a logical file after all I/O operations involving that file have
|
||||
been completed. This is accomplished by loading the Accumulator with
|
||||
the logical file number of the file to be closed, and calling this
|
||||
routine.
|
||||
|
||||
Closing an RS-232 file will de-allocate space at the top of memory for
|
||||
the receiving and trasmit buffers. Closing a cassette file that was
|
||||
opened for writing will force the last block to be written to
|
||||
cassette, even if it is not a full 192 bytes. Closing a serial bus
|
||||
device will send an UNLISTEN command on the bus. Remember, it is
|
||||
necessary to properly CLOSE a cassette or disk data file in order to
|
||||
retrieve the file later.
|
||||
|
||||
For all types of files, CLOSE removes the file's entry from the tables
|
||||
of logical files, device, and secondary address at 601, 611, and 621
|
||||
($259, $263, $26D), and moves all higher entries in the table down one
|
||||
space.
|
||||
|
||||
$FFC6 CHKIN Designate a Logical File As the Current Input Channel
|
||||
|
||||
The routine jumps through a RAM vector at 798 ($31E). If you wish to
|
||||
get data from any device other than the keyboard, this routine must be
|
||||
called after OPENing the device, before you can get a data byte with
|
||||
the CHRIN or GETIN routine. When called, the routine will designate
|
||||
the logical file whose file number is in the .X register as the
|
||||
current file, its device as the current device, and its secondary
|
||||
address as the current secondary address. If the device on the
|
||||
channel is a serial device, which requires a TALK command and
|
||||
sometimes a secondary address, this routine will send them over the
|
||||
serial bus.
|
||||
|
||||
$FFC9 CHKOUT Designate a Logical File As the Current Output Channel
|
||||
|
||||
The routine jumps through a RAM vector at 800 ($320). If you wish to
|
||||
output data to any device other than the screen, this routine must be
|
||||
called after OPENing the device, and before you output a data byte
|
||||
with the CHROUT routine. When called, the routine will designate the
|
||||
logical file whose file number is in the .X register as the current
|
||||
file, its device as the current device, and its secondary address as
|
||||
the current secondary address. If the device on the channel uses the
|
||||
serial bus, and therefore requires a LISTEN command and possibly a
|
||||
secondary address, this information will be sent on the bus.
|
||||
|
||||
$FFCC CLRCHN Restore Current Input and Output Devices to the Default Devices
|
||||
|
||||
The routine jumps through a RAM vector at 802 ($322). It sets the
|
||||
current input device to the keyboard, and the current output device to
|
||||
the screen. Also, if the current input device was formerly a serial
|
||||
device, the routine sends it an UNTALK command on the serial bus, and
|
||||
if a serial device was formerly the current output device, the routine
|
||||
sends it an UNLISTEN command.
|
||||
|
||||
$FFCF CHRIN Input a Character from the Current Device
|
||||
|
||||
The routine jumps through a RAM vector at 804 ($324). Its function is
|
||||
to get a character from the current input device (whose device number
|
||||
is stored at 153 ($99)). This device must first have been OPENed and
|
||||
then designated as the input channel by the CHKIN routine.
|
||||
|
||||
When this routine is called, the next byte of data available from this
|
||||
device is returned in the Accumulator. The only exception is the
|
||||
routine for the keyboard device (which is the default input device).
|
||||
It the keyboard is the current input device, this routine blinks the
|
||||
cursor, fetches characters from the keyboard buffer, and echoes them
|
||||
to the screen until a carriage return is encountered. When a carriage
|
||||
return is round, the routine sets a flag to indicate the length of the
|
||||
last logical line before the return character, and reads the first
|
||||
character of this logical line from the screen.
|
||||
|
||||
Subsequent calls to this routine will cause the next character in the
|
||||
line to be read from the screen and returned in the Accumulator, until
|
||||
the carriage return character is returned to indicate the end of the
|
||||
line. Any call after this character is received will start the whole
|
||||
process over again.
|
||||
|
||||
Note that only the last logical line before the carriage return is
|
||||
used. Any time you type in more than 80 characters, a new logical
|
||||
line is started. This routine will ignore any characters on the old
|
||||
logical line, and process only the most recent 80-character group.
|
||||
|
||||
$FFD2 CHROUT Output a Byte
|
||||
|
||||
The routine jumps through a RAM vector at 806 ($326).
|
||||
It is probably one of the best known and most used Kernal routines,
|
||||
because it sends the character in the Accumulator to the current
|
||||
output device. Unless a device has been OPENed and designated as the
|
||||
current output channel using the CHKOUT routine, the character is
|
||||
printed to the screen, which is the default output device. If the
|
||||
cassette is the current device, outputting a byte will only add it to
|
||||
the buffer. No actual transmission of data will occur until the
|
||||
192-byte buffer is full.
|
||||
|
||||
$FFD5 LOAD Load RAM from a Device
|
||||
|
||||
The routine jumps through a RAM vector at 816 ($330). LOAD is used to
|
||||
transfer data froma device directly to RAM. It can also be used to
|
||||
verify RAM, comparing its contents to those of a disk or tape file.
|
||||
To choose between these operations you must set the Accumulator with a
|
||||
0 for LOAD, or a 1 for VERIFY.
|
||||
|
||||
Since the LOAD routine performs an OPEN, it must be preceded by a call
|
||||
to the SETLFS routine to specify the logical file number, device
|
||||
number, and secondary address, and a call to the SETNAM routine to
|
||||
specify the filename (a LOAD from tape can be performed without a
|
||||
filename being specified). Then the .X and .Y registers should be set
|
||||
with the starting address for the load, and the LOAD routine called.
|
||||
If the secondary address specified was a 1, this starting address will
|
||||
be ignored, and the header information will be used to supply the load
|
||||
address. If the secondary address was a 0, the address supplied by
|
||||
the call will be used. In either case, upon return from the
|
||||
subroutine, the .X and .Y registers will contain the address of the
|
||||
highest RAM location that was loaded.
|
||||
|
||||
$FFD8 SAVE Save RAM to a Device
|
||||
|
||||
The routine jumps through a RAM vector at 818 ($332). SAVE is used to
|
||||
transfer data directly from RAM to an I/O device. Since the SAVE
|
||||
routine performs an OPEN, it must be preceded by a call to the SETLFS
|
||||
routine to specify the logical file number, device number, and
|
||||
secondary address, and a call to the SETNAM routine to specify the
|
||||
filename (although a SAVE to the cassette can be performed without
|
||||
giving a filename). A Page 0 pointer to the starting address of the
|
||||
area to be saved should be set up, with the low byte of the address
|
||||
first. The accumulator should be loaded with the Page 0 offset of
|
||||
that pointer, then the .X and .Y registers should be set with the
|
||||
ending address for the save, and the SAVE routine called.
|
||||
|
||||
$FFDB SETTIM Set the Software Clock from the .A, .X, and .Y Registers
|
||||
|
||||
This routine performs the reverse operation from RDTIM, storing the value in the
|
||||
.Y register into location 160 ($A0), the .X register into 161 ($A1),
|
||||
and the Accumulator into 162 ($A2). Interrupts are first disabled, to
|
||||
make sure that the clock will not be updated while being set.
|
||||
|
||||
$FFDE RDTIM Read the Time From the Software Clock into the .A, .X, and .Y Registers
|
||||
|
||||
It reads the software clock (which counts sixtieths of a second) into
|
||||
the internal registers. The .Y register contains the most significant
|
||||
byte (from location 160 ($A0)), the .X register contains the middle
|
||||
byte (from location 161 ($A1)), and the Accumulator contains the least
|
||||
significant byte (from location 162 ($A2)).
|
||||
|
||||
$FFE1 STOP Test STOP Key
|
||||
|
||||
This routine is vectored through RAM at 808 ($328). The routine checks to see
|
||||
if the STOP key was pressed during the last UDTIM call. If it was,
|
||||
the Zero flag is set to 1, the CLRCHN routine is called to set the
|
||||
input and output devices back to the keyboard and screen, and the
|
||||
keyboard queue is emptied.
|
||||
|
||||
$FFE4 GETIN Get One Byte from the Input Device
|
||||
|
||||
The routine jumps through a RAM vector at 810 ($32A).
|
||||
Its function is to get a character from the current input device
|
||||
(whose device number is stored at 153 ($99)). In practive, it
|
||||
operates identically to the CHRIN routine below for all devices except
|
||||
for the keyboard. If the keyboard is the current input device, this
|
||||
routine gets one character from the keyboard buffer at 631 ($277). It
|
||||
depends on the IRQ interrupt routine to rad the keyboard and put
|
||||
characters into the buffer.
|
||||
|
||||
$FFE7 CLALL Close All Logical I/O Files
|
||||
|
||||
The routine jumps through a RAM vector at 812 ($32C). It closes all
|
||||
open files, by resetting the index into open files at 152 ($98) to
|
||||
zero. It then falls through to the next routine, which restores the
|
||||
default I/O devices.
|
||||
|
||||
$FFEA UDTIM Update the Software Clock and Check for the STOP Key
|
||||
|
||||
This routine is normally called by the IRQ interrupt handler once every sixtieth
|
||||
of a second. It adds one to the value in the three-byte software
|
||||
jiffy clock at 160-162 ($A0-$A2), and sets the clock back to zero when
|
||||
it reaches the 24 hour point. In addition, it scans the keyboard row
|
||||
in which the STOP key is located, and stores the current value of that
|
||||
key in location 145 ($91). This variable is used by the STOP routine
|
||||
which checks for the STOP key.
|
||||
|
||||
$FFED SCREEN Store Number of Screen Rows and Columns in .Y and .X
|
||||
|
||||
When called, this subroutine returns the number of screen columns in
|
||||
the .X register, and the number of screen rows in .Y. Thus, a program
|
||||
can detect the screen format of the machine on which it is running,
|
||||
and make sure that text output is formatted accordingly.
|
||||
|
||||
The present version of this routine loads the .X register with 40
|
||||
($28) and the .Y register with 25 ($19).
|
||||
|
||||
$FFF0 PLOT Read/Set Location of the Cursor
|
||||
|
||||
The routine allows the user to read or set the position of the cursor.
|
||||
If the carry flag is set with the SEC instruction before calling this
|
||||
subroutine, cursor column (X position) will be returned in the .X
|
||||
register, and the cursor row (Y position) will be returned in the .Y
|
||||
register. If the carry flag is cleared with a CLC instruction before
|
||||
entering this routine, and the .Y and .X registers are loaded with the
|
||||
desired row and column positions respectively, this routine will set
|
||||
the cursor position accordingly.
|
||||
|
||||
The current read routine loads .X and .Y from locations 214 ($D6) and
|
||||
211 ($D3) respectively. The cursor set routine stores .X and .Y in
|
||||
these locations, and calls the routine that sets the screen pointers
|
||||
at 58732 ($E56C).
|
||||
|
||||
The user can access this routine from BASIC by loading the .X, .Y, and
|
||||
.P register values desired to the save area starting at 780 ($30C).
|
||||
|
||||
$FFF3 IOBASE Store Base Address of Memory-Mapped I/O Devices in .X and .Y Registers
|
||||
|
||||
When called, this routine sets the .X register to the low byte of the
|
||||
base address of the memory-mapped I/O devices, and puts the high byte
|
||||
in the .Y register. This allows a user to set up a zero-page pointer
|
||||
to the device, and to load and store indirectly through that pointer.
|
||||
A program which uses this method, rather than directly accessing such
|
||||
devices could be made to function without change on future Commodore
|
||||
models, even though the I/O chips may be addressed at different
|
||||
locations. This of course assumes that the CIA or a similar chip will
|
||||
be used. This routine is of limited value for creating software that
|
||||
is compatible with both the VIC-20 and the 64 because of the
|
||||
differences in the VIA I/O chip that the VIC uses.
|
||||
|
||||
The current version of this routine loads the .X register with a 0,
|
||||
and the .Y register with 220 ($DC), thus pointing to CIA #1, which is
|
||||
at 56320 ($DC00).
|
||||
939
kernal/kernal_mlr.txt
Normal file
939
kernal/kernal_mlr.txt
Normal file
|
|
@ -0,0 +1,939 @@
|
|||
-
|
||||
- Heimarck, Todd D; Parrish, Patrick:
|
||||
- Machine language routines for the Commodore 64 and 128
|
||||
-
|
||||
|
||||
$FFA5 ACPTR
|
||||
|
||||
This low-level I/O routine retrieves a byte from a serial device
|
||||
without checking for a previous I/O error. If the operation is
|
||||
successful, the accumulator will hold the byte received from
|
||||
the device. The contents of .X and .Y are preserved. The suc-
|
||||
cess of the operation will be indicated by the value in the se-
|
||||
rial status flag upon return. (See READST for details.)
|
||||
|
||||
For the routine to function properly, the serial device
|
||||
must currently be a talker on the serial bus, which requires a
|
||||
number of setup steps. Generally, it's preferable to use the
|
||||
higher-level CHRFN routine instead.
|
||||
|
||||
$FFC6 CHKIN
|
||||
|
||||
This routine specifies a logical file as the source of input in
|
||||
preparation for using the CHRIN or GETIN routines. The logi-
|
||||
cal file should be opened before this routine is called. (See the
|
||||
OPEN routine.) The desired logical file number should be in
|
||||
.X when this routine is called. The contents of .Y are un-
|
||||
affected, but the accumulator value will be changed.
|
||||
|
||||
The routine sets the input channel (location $99) to the
|
||||
device number for the specified file. If the device is RS-232
|
||||
(device number 2), the CTA #2 interrupts for RS-232 reception
|
||||
are enabled. Ef a serial device (device number 4 or greater) was
|
||||
specified, the device is made a talker on the serial bus,
|
||||
|
||||
If the file is successfully set for input, the status-register
|
||||
carry bit will be clear upon return. If carry is set, the operation
|
||||
was unsuccessful and the accumulator will contain a Kernal
|
||||
error-code value indicating which error occurred. Possible er-
|
||||
ror codes include 3 (fiLe was not open), 5 (device did not re-
|
||||
spond), and 6 (file was not opened for input). The RS-232 and
|
||||
serial status-flag locations also reflect the success of operations
|
||||
for those devices. (See READST for details.)
|
||||
|
||||
The JMP to the CEDGN execution routine is by way of the
|
||||
ICHKDN indirect vector at 798-799 ($031E-$031F). You can
|
||||
modify the actions of CHfQN by changing the vector to point
|
||||
to a routine of your own.
|
||||
|
||||
$FFC9 CHKOUT
|
||||
|
||||
This routine (some Commodore references call it CKOUT)
|
||||
specifies a logical file as the recipient of output in preparation
|
||||
for using the CHROUT routine. The logical file should be
|
||||
opened before this routine is called. (See the OPEN routine.)
|
||||
The desired logical file number should be in .X when this rou-
|
||||
tine is called. The contents of .Y are unaffected, but the accu-
|
||||
mulator will be changed.
|
||||
|
||||
The routine sets the output channel (location $9A) to the
|
||||
device number for the specified file. If the device is RS-232
|
||||
(device number 2), the routine also enables the CLA #2 inter-
|
||||
rupts for RS-232 transmission. fi a serial device (device num-
|
||||
ber 4 or greater) is specified, the device is also made a listener
|
||||
on the serial bus.
|
||||
|
||||
If the file is successfully set for output, the status-register
|
||||
carry bit will be clear upon return. If the carry is set, the op-
|
||||
eration was unsuccessful, and the accumulator will contain a
|
||||
Kernal error-code value indicating which error occurred. Pos-
|
||||
sible error codes include 3 (file was not open), 5 (device did
|
||||
not respond), and 7 (file was not opened for output). The RS-
|
||||
232 and serial status-flag locations also reflect the success of
|
||||
operations for those devices. (See READST for details.)
|
||||
|
||||
The JMP to the CHKOUT execution routine is by way of
|
||||
the ICKOUT indirect vector at $0320-$0321. You can modify
|
||||
the actions of the routine by changing the vector to point to a
|
||||
routine of your own.
|
||||
|
||||
$FFCF CHRIN
|
||||
|
||||
This high-level I/O routine (some Commodore references may
|
||||
call it BASIN) receives a byte from the logical file currently
|
||||
specified for input (to change the default input device, see
|
||||
CHKIN above). Except to use the routine to retrieve input
|
||||
from the keyboard when the system is set for default I/O, you
|
||||
must open a logical file to the desired device and specify the
|
||||
file as the input source before calling this routine. (See the
|
||||
OPEN and CHKIN routines.)
|
||||
|
||||
For keyboard input (device 0), the routine accepts
|
||||
keypresses until RETURN is pressed, and then returns charac-
|
||||
ters from the input string one at a time on each subsequent
|
||||
call. The character code for RETURN, 13, is returned when the
|
||||
end of an input string is reached. (The Kernal GETIN routine
|
||||
is better for retrieving individual keypresses.)
|
||||
|
||||
For tape (device 1), the routine retrieves the next character
|
||||
from the cassette buffer. If all characters have been read from
|
||||
the buffer, the next data block is read from tape into the
|
||||
buffer.
|
||||
|
||||
For RS-232 (device 2), the routine returns the next avail-
|
||||
able character from the RS-232 input buffer. If the buffer is
|
||||
empty, the routine waits until a character is received—unless
|
||||
the RS-232 status flag indicates that the DSR signal from the
|
||||
external device is missing, in which case a RETURN character
|
||||
code, 13, is returned.
|
||||
|
||||
CHRIN from the screen (device 3) retrieves characters one
|
||||
at a time from the current screen line, ending with a RETURN
|
||||
character code when the last nonspace character on the logical
|
||||
line is reached. (Note that CHRIN from the screen does not
|
||||
work properly in the original version of the 128 Kernal.) For
|
||||
serial devices (device numbers 4 and higher), the routine re-
|
||||
turns the next available character from the serial bus, unless
|
||||
the serial status flag contains a nonzero value. In that case, the
|
||||
RETURN character code is returned.
|
||||
|
||||
For all input devices, the received byte will be in the
|
||||
accumulator upon return. The contents of .X and .Y are pre-
|
||||
served during input from the keyboard, screen, or RS-232. For
|
||||
input from tape, only .X is preserved. For input from serial de-
|
||||
vices, only .Y is preserved. For input from the screen, key-
|
||||
board, or serial devices, the status-register carry bit will always
|
||||
be clear upon return. For tape input, the carry bit will be clear
|
||||
unless the operation was aborted by pressing the RUN/STOP
|
||||
key. For tape, serial, or RS-232 input, the success of the opera-
|
||||
tion will be indicated by the value in the status-flag location.
|
||||
(See the entry for READST.) The RS-232 portion of the orig-
|
||||
inal 128 version of CHRRsJ has a bug: The carry bit will be set
|
||||
if a byte was successfully received, and will be clear only if
|
||||
the DSR signal is missing—the opposite of the settings for the
|
||||
64. It's better to judge the success of an RS-232 operation by
|
||||
the value in the status-flag location rather than by the carry-
|
||||
bit setting. (See the READST routine.)
|
||||
|
||||
TheJMP to the CHREN execution routine is by way of the
|
||||
ICHRfN indirect vector at $0324-$0325. You can modify the
|
||||
actions of the routine by changing the vector to point to a rou-
|
||||
tine of your own.
|
||||
|
||||
$FFD2 CHROUT
|
||||
|
||||
This routine (some Commodore references call it BSOUT)
|
||||
sends a byte to the logical file currently specified for output.
|
||||
Except to send output to the screen when the system is set for
|
||||
default I/O, you must open a logical file to the desired device
|
||||
and specify the file as the output target before calling this rou-
|
||||
tine. (See the OPEN and CHKOUT routines.)
|
||||
|
||||
For output to tape (device 1), the character is stored at the
|
||||
next available position in the cassette buffer. When the buffer
|
||||
is full, the data block is written to tape.
|
||||
|
||||
For output to RS-232 (device 2), the character is stored in
|
||||
the next available position in the RS-232 output buffer, if the
|
||||
buffer is full, the routine waits until a character is sent.
|
||||
|
||||
For output to the screen (device 3), the character is
|
||||
printed at the current cursor position. For serial devices (device
|
||||
numbers 4 and higher), the CIOUT routine is called.
|
||||
|
||||
Regardless of the output device, the contents of the accu-
|
||||
mulator, .X, and .Y are preserved during this routine. The
|
||||
status-register carry bit will always be clear upon return, un-
|
||||
less output to tape is aborted by pressing the RUN/STOP key.
|
||||
(In that case, the accumulator will also be set to 0, setting the
|
||||
status-register Z bit as well.) For tape, serial, or RS-232 output,
|
||||
the success of the operation will be indicated by the value in
|
||||
the status flag. (See READST for details.)
|
||||
|
||||
The JMP to the CHROUT execution routine is by way of
|
||||
the ICHROUT indirect vector at $0326-$0327. You can modify
|
||||
the actions of the routine by changing the vector to point to a
|
||||
routine of your own.
|
||||
|
||||
$FF81 CINT
|
||||
|
||||
This routine initializes all RAM locations used by the screen
|
||||
editor, returning screen memory to its default position and set-
|
||||
ting default screen and border colors. The routine also clears
|
||||
the screen and homes the cursor. All processor registers are
|
||||
affected.
|
||||
|
||||
For the 64 only, this routine initializes all VIC chip reg-
|
||||
isters to their default values (that's done during the Kernal
|
||||
IOINIT routine in the 128). For the 128, CINT clears both dis-
|
||||
plays and redirects printing to the display indicated by the po-
|
||||
sition of the 40/80 DISPLAY key. The 128 routine also sets
|
||||
SID volume to zero and resets programmable function keys to
|
||||
their default definitions. It does not, however, reinitialize the
|
||||
80-column character set. (That's also part of IOINIT.)
|
||||
|
||||
$FFA8 CIOUT
|
||||
|
||||
This low-level I/O routine sends a byte to a serial device. The
|
||||
accumulator should hold the byte to be sent. All register val-
|
||||
ues are preserved. The success of the operation will be in-
|
||||
dicated by the value in the serial status flag. (See READST for
|
||||
details.)
|
||||
|
||||
For the routine to function properly, the target serial de-
|
||||
vice must currently he a listener on the serial bus, which re-
|
||||
quires a number of setup steps. However, if you have already
|
||||
performed all the preparatory steps necessary for CHROUT to
|
||||
a serial device, then you can freely substitute CIOUT for
|
||||
CHROUT, since, for a serial device, CHROUT simply jumps to
|
||||
the CIOUT routine.
|
||||
|
||||
$FFE7 CLALL
|
||||
|
||||
This routine resets the number of open files (location $98) to
|
||||
zero, then falls through into the CLRCH routine to reset de-
|
||||
fault t/O. The contents of .A and .X are changed, but .Y is
|
||||
unaffected.
|
||||
|
||||
Despite its name, the routine doesn't actually close any
|
||||
files that may be open to tape, disk, or RS-232 devices. Un-
|
||||
closed files may cause problems, particularly on disks, so this
|
||||
routine is of limited usefulness. The 128 Kernal provides an
|
||||
alternate routine that does properly close all files open to a se-
|
||||
rial device. (See CLOSE_ALL.)
|
||||
|
||||
The JMP to the CLALL execution routine is by way of the
|
||||
JCLALL indirect vector at $032C-$032D. You can modify the
|
||||
actions of the routine by changing the vector to point to a rou-
|
||||
tine of your own.
|
||||
|
||||
$FFC3 CLOSE
|
||||
|
||||
This routine closes a specified logical file. Call the routine with
|
||||
the accumulator holding the number of the logical file to be
|
||||
closed. If no file with the specified logical file number is cur-
|
||||
rently open, no action is taken and no error is indicated. If a
|
||||
file with the specified number is open, its entry in the logical
|
||||
file number, device number, and secondary address tables will
|
||||
be removed. For RS-232 files, the driving CLA #2 interrupts will
|
||||
also be disabled. For tape files, the final block of data will be
|
||||
written to tape (followed by an end-of-tape marker, if one was
|
||||
specified). For disk files, the EOI sequence will be performed.
|
||||
|
||||
The 128 version of the routine offers a special close func-
|
||||
tion for disk files: Ff this routine is called with the status-
|
||||
register carry bit set, and if the device number for the file is 8
|
||||
or greater, and if the file was opened with a secondary address
|
||||
of 15, then the EOI sequence is skipped. (The table entries for
|
||||
the file are deleted, but that's all.) This solves a problem in
|
||||
earlier versions of the Kernal for disk files opened with a
|
||||
secondary address of 15, the command channel to the drive.
|
||||
An attempt to close the command channel will result in an
|
||||
EOI sequence that closes all files currently open to the drive,
|
||||
not just the command-channel file, This special mode allows
|
||||
the command-channel file to be closed without disturbing
|
||||
other files that may be open to the drive.
|
||||
|
||||
The JMP to the CLOSE execution routine is by way of the
|
||||
ICLOSE indirect vector at $031C-$031D. You can modify the
|
||||
actions of the routine by changing the vector to point to a rou-
|
||||
tine of your own.
|
||||
|
||||
$FFCC CLRCHN
|
||||
|
||||
This routine restores the default I/O sources for the operating
|
||||
system. The output channel (location $9A) is reset to device 3,
|
||||
the video display. (If the previous output channel was a serial
|
||||
device, it is sent an UNLISTEN command.) The input channel
|
||||
(location $99) is reset to device 0, the keyboard, (if the pre-
|
||||
vious input channel was a serial device, it is sent an UNTALK
|
||||
command.) The contents of .X and .A are changed, but .Y is
|
||||
unaffected.
|
||||
|
||||
The JMP to the CLRCHN execution routine is by way of
|
||||
the lCLRCH indirect vector at $0322-$0323. You can modify
|
||||
the actions of the routine by changing the vector to point to a
|
||||
routine of your own.
|
||||
|
||||
$FFE4 GETIN
|
||||
|
||||
This routine retrieves a single character from the current input
|
||||
device. The routine first checks to see whether the input de-
|
||||
vice number is 0 (keyboard) or 2 (RS-232). If it's not either of
|
||||
these, the Kernal CHRIN routine is called instead. For key-
|
||||
board or RS-232, the retrieved character will be in the accu-
|
||||
mulator upon return, and the status-register carry bit wall be
|
||||
clear. If no character is available, the accumulator will contain
|
||||
0. (CHREM, by contrast, will wait for a character.) The contents
|
||||
of .Y are unaffected, but .X will be changed. For RS-232, bit 3
|
||||
of the status flag will also be set if no characters are available.
|
||||
(See READST for details.)
|
||||
|
||||
The JMP to the GETIN execution routine is by way of the
|
||||
IGETIN indirect vector at $032A-$032B. You can modify the
|
||||
actions of the routine by changing the vector to point to a rou-
|
||||
tine of your own.
|
||||
|
||||
$FFF3 IOBASE
|
||||
|
||||
This routine returns a constant 1/0 chip base-address value in
|
||||
.X (low byte) and .Y (high byte). The accumulator is un-
|
||||
affected. For the 64, the value returned is $DCOO—the address
|
||||
of CLA #1. For the 128, the value is $D000—the address of
|
||||
the VIC chip.
|
||||
|
||||
$FF84 IOINIT
|
||||
|
||||
This routine initializes the CIA chips' registers to their default
|
||||
values, along with related RAM locations. All processor reg-
|
||||
isters are affected. For the 128, the routine also initiatizes the
|
||||
VIC and VDC chip registers (a step which is part of the Kernal
|
||||
CINT routine on the 64). In addition, the 128 routine sets all
|
||||
SID chip registers to zero and calls the Kernal DLCHR routine
|
||||
to initiahze the character set for the 80-column chip.
|
||||
|
||||
$FFB1 LISTEN
|
||||
|
||||
This low-level serial I/O routine sends a LISTEN command to
|
||||
a specified serial device. Call the routine with the accumulator
|
||||
holding the device number (4-31) of the serial device to re-
|
||||
ceive the command. The contents of .A and .X will be changed;
|
||||
.Y is unaffected. The success of the operation will be indicated
|
||||
by the value in the serial status flag upon return. (See
|
||||
READST for details.)
|
||||
|
||||
$FFD5 LOAD
|
||||
|
||||
This routine loads a program file from tape or disk into a
|
||||
specified area of memory, or verifies a program file against the
|
||||
contents of a specified area of memory. A number of prepara-
|
||||
tory routines must be called before LOAD: SETLFS, SETNAM,
|
||||
and (for the 128 only) SETBNK. See the discussions of those
|
||||
routines for details.
|
||||
|
||||
SETLFS establishes the device number and secondary ad-
|
||||
dress for the operation. fThe logical file number isn't significant
|
||||
for loading or verifying.) The secondary-address value deter-
|
||||
mines whether the load/verify will be absolute or relocating.
|
||||
If bit 0 of the secondary address is %0 (if the value is 0 or any
|
||||
even number, for example), a relocating load will be performed:
|
||||
The file will be loaded starting at the address specified in .X
|
||||
and .Y. If the bit is %1 (if the value is 1 or any odd number,
|
||||
for example), an absolute load will be performed: The data
|
||||
will be loaded starting at the address specified in the file itself.
|
||||
For tape files, the secondary-address specification can be over-
|
||||
ridden by the file's internal type specification. Nonrelocatable
|
||||
tape program files always load at their absolute address,
|
||||
regardless of the secondary address.
|
||||
|
||||
When calling the LOAD routine, the accumulator should
|
||||
hold the operation type value (0 for a load, or any nonzero
|
||||
value for a verify). If the secondary address specifies a relocat-
|
||||
ing load, the starting address at which data is to be loaded
|
||||
should be stored in .X (low byte) and .Y (high byte). The val-
|
||||
ues of .X and .Y are irrelevant for an absolute load.
|
||||
|
||||
The status-register carry bit will be clear upon return if
|
||||
the file was successfully loaded, or set if an error occurred or if
|
||||
the RUN/STOP key was pressed to abort the load. When
|
||||
carry is se t upon return, the accumulator will hold a Kernal er-
|
||||
ror-code value indicating the problem. Possible error codes in-
|
||||
clude 4 (file was not found), 5 (device was not present), 8 (no
|
||||
name was specified for a serial load), 9 (an illegal device num-
|
||||
ber was specified).
|
||||
|
||||
On the 128 only, the load will be aborted if it extends be-
|
||||
yond address $FEFF. This prevents corruption of the MMU
|
||||
configuration register at $FFQ0. Ln this case, an error code of
|
||||
16 will be returned. The success of the operation will also be
|
||||
indicated by the value in the tape/serial status flag. (See
|
||||
READST for details.)
|
||||
|
||||
$FF9C MEMBOT
|
||||
$FF99 MEMTOP
|
||||
|
||||
These routines read or set the Kernal's bottom-of-memory
|
||||
pointer and top-of-memory pointer, respectively. (The bottom-
|
||||
of-memory pointer is at locations $0281-$0282 for the 64 or
|
||||
$0A05-$0A06 for the 128; the top-of-memory pointer is at
|
||||
locations $0283-$0284 for the 64 or $0A07-$0A08 for the
|
||||
128.) To read the pointer, call the routine with the carry flag
|
||||
set; the pointer value will be returned in .X (low byte) and .Y
|
||||
(high byte). To set the pointer, call the routine with the carry
|
||||
flag clear and with .X and .Y containing the low and high
|
||||
bytes, respectively, of the desired pointer value.
|
||||
|
||||
$FFC0 OPEN
|
||||
|
||||
This routine opens a logical file to a specified device in
|
||||
preparation for input or output. At least one preparatory step
|
||||
is required before the standard OPEN routine is called:
|
||||
SETLFS must be called to establish the logical file number, de-
|
||||
vice number, and secondary address, For tape (device 1), RS-
|
||||
232 (device 2), or serial (device 4 or higher), SETNAM is also
|
||||
required to specify the length and address of the associated
|
||||
filename. Tor the 128, SETBNK must be called to establish the
|
||||
bank number where the filename can he found.
|
||||
|
||||
It is not necessary to load any registers before calling
|
||||
OPEN, and all processor register values may be changed dur-
|
||||
ing the routine. The carry will be clear if the file was success-
|
||||
fully opened, or it will be set if it could not be opened. When
|
||||
carry is set upon return, the accumulator will hold an error
|
||||
code indicating the problem. Possible error-code values in-
|
||||
clude 1 (ten files—the maximum allowed—are already open),
|
||||
2 (a currently open file already uses the specified logical file
|
||||
number), and 5 (specified device did not respond). The RS-232
|
||||
and tape/serial status flags will also reflect the success of the
|
||||
operation for those devices, (See READST for details.)
|
||||
|
||||
On the 128, there is an exception to the carry-bit rule. Be-
|
||||
cause of a bug in the 128's RS-232 OPEN routine, carry will
|
||||
be set if the RS-232 device is present when x-line handshaking
|
||||
is used (if the DSR line is high), or clear if the device is ab-
|
||||
sent—the opposite of the proper setting.
|
||||
|
||||
The JMP to the OPEN execution routine is by way of the
|
||||
IOPEN indirect vector $031A-$031B. You can modify the ac-
|
||||
tions of the routine by changing the vector to point to a rou-
|
||||
tine of your own,
|
||||
|
||||
$FFF0 PLOT
|
||||
|
||||
This routine reads or sets the cursor position on the active dis-
|
||||
play, if it is called with the status-register carry bit clear, the
|
||||
value in .X specifies the new cursor row (vertical position),
|
||||
and the value in .Y specifies the column (horizontal position).
|
||||
The carry bit will be set upon return if the specified column or
|
||||
row values are beyond the right or bottom margins of the cur-
|
||||
rent output window, or it will be clear if the cursor was
|
||||
successfully positioned.
|
||||
|
||||
If the routine is called with the carry bit set, the row num-
|
||||
ber for the current cursor position is returned in .X and the
|
||||
current column number is returned in .Y. For the Commodore
|
||||
128, the cursor position will be relative to the home position
|
||||
of the current output window rather than to the upper left cor-
|
||||
ner of the screen. Of course, in the case of a full-screen output
|
||||
window—the default condition—the upper left comer of the
|
||||
screen is the home position of the window,
|
||||
|
||||
$FF87 RAMTAS
|
||||
|
||||
This routine clears zero-page RAM (locations $02-$FF) and
|
||||
initializes Kernal memory pointers in zero page. For the 64
|
||||
only, the routine also clears pages 2 and 3 (locations
|
||||
$0200-$03FF), tests all RAM locations from $0400 upwards
|
||||
until ROM is encountered, and sets the top-of-memory
|
||||
pointer. For the 128, the routine sets the BASIC restart vector
|
||||
($OAOO) to point to BASIC's cold-start entry address, $4000.
|
||||
|
||||
$FFDE RDTIM
|
||||
|
||||
This routine returns the current value of the jiffy dock. The
|
||||
dock value corresponds to the number of jiffies (1 /60-second
|
||||
intervals) that have elapsed since the system was turned on or
|
||||
reset, or the number of jiffies since midnight if the dock value
|
||||
has been set. The low byte of the clock value (location $A2) is
|
||||
returned in .A, the middle byte (location $A1) in .X, and the
|
||||
high byte loocation $A0) in .Y.
|
||||
|
||||
$FFB7 READST
|
||||
|
||||
This routine (some Commodore references call it READSS) re-
|
||||
turns the status of the most recent I/O operation. The status
|
||||
value will be in the accumulator upon return; the contents of
|
||||
.X and .Y are unaffected. If the current device number is 2 (in-
|
||||
dicating an RS-232 operation), the status value is retrieved
|
||||
from the RS-232 status flag (location $0297 for the 64 or
|
||||
$0A14 for the 128), and the flag is cleared. Otherwise, the sta-
|
||||
tus value is retrieved from the tape/serial status flag (location
|
||||
$90). That flag is not cleared after being read.
|
||||
|
||||
| Bit | Value | Meaning if set Serial | Meaning if set Tape | Meaning if set RS-232 |
|
||||
|-----|---------|-----------------------|---------------------------------------|--------------------------|
|
||||
| 0 | 1/$01 | write timeout | | parity error |
|
||||
| 1 | 2/$02 | read timeout | | framing error |
|
||||
| 2 | 4/$04 | | short block | receiver buffer overflow |
|
||||
| 3 | 8/$08 | | long block | receiver buffet empty |
|
||||
| 4 | 16/$10 | verify mismatch | unrecoverable read or verify mismatch | CTS missing |
|
||||
| | | | | |
|
||||
| 5 | 32/$20 | | checksum mismatch | |
|
||||
| 6 | 64/$40 | EOI (end of file) | end of file | DSR missing |
|
||||
| 7 | 128/$80 | device nol present | end of tape | break |
|
||||
|
||||
$FF8A RESTOR
|
||||
|
||||
This routine resets the Kernal indirect vectors ($0314-$0333)
|
||||
to their default values. All processor registers are affected.
|
||||
|
||||
$FFD8 SAVE
|
||||
|
||||
This routine saves the contents of a block of memory to disk
|
||||
or tape. It could be a BASIC or ML program, but it doesn't
|
||||
have to be. A number of preparatory routines must be called
|
||||
first: SETLFS, SETNAM, and (for the 128 only) SETBNK. See
|
||||
the discussions of those routines for details.
|
||||
|
||||
SETLFS establishes the device number and secondary ad-
|
||||
dress for the operation. (The logical file number isn't signifi-
|
||||
cant for saving.) The secondary address is irrelevant for saves
|
||||
to serial devices, but for tape it specifies the header type. If bit
|
||||
0 of the secondary address value is %1 (if the value is 1, for
|
||||
example), the data will be stored in a nonrelocatable file—one
|
||||
that will always load to the same memory address from which
|
||||
it was saved. Otherwise, the data will be stored in a file that
|
||||
can be loaded to another location. If bit 1 of the secondary ad-
|
||||
dress is %1 (if the value is 2 or 3, for example), the file will be
|
||||
followed by an end-of-tape marker.
|
||||
|
||||
Before calling SAVE, you must also set up a two-byte
|
||||
zero-page pointer containing the starting address of the block
|
||||
of memory to be saved and then store the address of the zero-
|
||||
page pointer in the accumulator. The ending address (plus
|
||||
one) for the save should be stored in .X (low byte) and .Y
|
||||
(high byte). To save the entire contents of the desired area, it's
|
||||
important to remember that .X and .Y must hold an address
|
||||
that is one location beyond the desired ending address.
|
||||
|
||||
When the save is complete, the carry will be clear if the
|
||||
file was successfully saved, or set if an error occurred (or if the
|
||||
RUN/STOP key was pressed to abort the save). When carry is
|
||||
set upon return, the accumulator will hold the Kernal error
|
||||
code indicating the problem. Possible error-code values in-
|
||||
clude 5 (serial device was not present), 8 (no name was speci-
|
||||
fied for a serial save), and 9 (an illegal device number was
|
||||
specified). The success of the operation will also be indicated
|
||||
by the value in the tape/serial status flag. (See READST for
|
||||
details.)
|
||||
|
||||
$FF9F SCNKEY
|
||||
|
||||
This routine scans the keyboard matrix to determine which
|
||||
keys, if any, are currently pressed. The standard KQ service
|
||||
routine calls SCNKEY, so it's not usually necessary to call it
|
||||
explicitly to read the keyboard. The character code for the key
|
||||
currently pressed is loaded into the keyboard buffer, from
|
||||
where it can be retrieved using the Kernal GETIN routine. The
|
||||
matrix code of the keypress read during this routine can also
|
||||
be read in location $CB (64) or $D4 (128), and the status of
|
||||
the shift keys can be read in location $028D (64) or $D3 (128).
|
||||
|
||||
$FFED SCREEN
|
||||
|
||||
This routine (Commodore 128 literature calls it SCRORG) re-
|
||||
turns information on the size of the screen display. For the 64,
|
||||
the routine always returns the same values—the screen width
|
||||
in columns (40) in .X and the screen height in rows (25) in .Y.
|
||||
The accumulator is unaffected. For the 128, the values returned
|
||||
reflect the size of the current output window. The X register
|
||||
will contain in the current window the number of columns mi-
|
||||
nus one, and .Y will contain the number of rows minus one.
|
||||
The accumulator will hold the maximum column number for
|
||||
the display currently active (39 for the 40-column screen or 79
|
||||
for the 80-column screen).
|
||||
|
||||
$FF93 SECOND
|
||||
|
||||
This low-level serial I/O routine sends a secondary address to
|
||||
a device which has been commanded to listen. The value in
|
||||
the serial status flag upon return will indicate whether the op-
|
||||
eration was successful.
|
||||
|
||||
$FFBA SETLFS
|
||||
|
||||
This routine assigns the logical file number (location $B8), de-
|
||||
vice number (location $BA), and secondary address location
|
||||
$B9) for the current I/O operation. Call the routine with the
|
||||
accumulator holding the logical file number, .X holding the
|
||||
device number, and .Y holding the secondary address. All reg-
|
||||
ister values are preserved during the routine. Refer to the
|
||||
LOAD and SAVE routines for the special significance of the
|
||||
secondary address in those cases. When OPENing files to se-
|
||||
rial devices, it's vital that each logical file have a unique
|
||||
secondary address, In the 128 Kernal, the LKUPLA and
|
||||
LKUPSA routines can be used to find unused logical file num-
|
||||
bers and secondary addresses.
|
||||
|
||||
$FF90 SETMSG
|
||||
|
||||
SETMSG sets the value of the Kernal message flag (location
|
||||
$9D). Call the routine with the accumulator holding the de-
|
||||
sired flag value (.X and .Y are unaffected,) Valid flag values
|
||||
are 0 (no Kernal messages are displayed), 64 (only error mes-
|
||||
sages are displayed), 128 (only control messages—PRESS
|
||||
PLAY ON TAPE, for example—are displayed), and 192 (both
|
||||
error and control messages are displayed).
|
||||
|
||||
$FFBD SETNAM
|
||||
|
||||
This routine assigns the length (location $B7) and address
|
||||
locations $BB-$BC) of the filename for the current I/O opera-
|
||||
tion. Call the routine with the length of the filename in .A and
|
||||
the address of the first character of the name in .X (low byte)
|
||||
and .Y (high byte). If no name is used for the current opera-
|
||||
tion, load the accumulator with 0; the values in .X and .Y are
|
||||
then irrelevant, All register values are preserved during this
|
||||
routine.
|
||||
|
||||
$FFDB SETTIM
|
||||
|
||||
This routine sets the value in the software jiffy dock. The
|
||||
value in the accumulator is transferred to the low byte (loca-
|
||||
tion $A2), the value in .X to the middle byte (location $A1),
|
||||
and the value in .Y to the high byte (location $A0). The speci-
|
||||
fied value should be less than $4F1A01, which corresponds to
|
||||
24:00:00 hours.
|
||||
|
||||
$FFA2 SETTMO
|
||||
|
||||
The SETTMO routine stores the contents of the accumulator in
|
||||
the fEEE timeout flag. (.X and .Y are unaffected.) This routine
|
||||
is superfluous, since the flag isn't used by any 64 or 128 ROM
|
||||
routine. It is present merely to maintain consistency with pre-
|
||||
vious versions of the Kernal. For the 64, the flag location is
|
||||
$0285; for the 128, it's at $0A0E.
|
||||
|
||||
$FFE1 STOP
|
||||
|
||||
This routine checks whether the RUN/STOP key is currently
|
||||
pressed. It returns with the status-register Z bit clear if the key
|
||||
is not pressed, or with the bit set if it is pressed. Additionally,
|
||||
if RUN/STOP is pressed the CLRCH routine is called to re-
|
||||
store default I/O channels, and the count of keys in the key-
|
||||
board buffer is reset to zero.
|
||||
The JMP to the STOP execution routine is by way of the
|
||||
ISTOP indirect vector at $0328-$0329. You can modify the ac-
|
||||
tions of the routine by changing the vector to point to a rou-
|
||||
tine of your own.
|
||||
|
||||
$FFB4 TALK
|
||||
|
||||
This low-level 1/0 routine sends a TALK command to a serial
|
||||
device, Call the routine with the accumulator holding the
|
||||
number (4-31) of the device. The success of the operation will
|
||||
be indicated by the value in the serial status flag upon return,
|
||||
(See READST for details.)
|
||||
|
||||
$FF96 TKSA
|
||||
|
||||
This low-level serial 1/0 routine sends a secondary address to
|
||||
a device which has previously been commanded to taLk. The
|
||||
success of the operation will be indicated by the value in the
|
||||
serial status flag upon return. (See READST for details.)
|
||||
|
||||
$FFEA UDTIM
|
||||
|
||||
This routine increments the software jiffy dock and scans the
|
||||
keyboard column containing the RUN/STOP key. (The 128
|
||||
version of the routine also decrements a countdown timer.)
|
||||
This routine is normally called every 1 /60 second as part of
|
||||
the standard lRQ service routine.
|
||||
|
||||
$FFAE UNLSN
|
||||
|
||||
This low-level I/O routine sends an UNLISTEN command to
|
||||
aH devices on the serial bus. Any devices which are currently
|
||||
listeners will cease accepting data.
|
||||
|
||||
$FFAB UNTLK
|
||||
|
||||
This low-level 1/0 routine sends an UNTALK command to all
|
||||
devices on the serial bus. Any devices which are currently
|
||||
talkers will cease sending data.
|
||||
|
||||
$FF8D VECTOR
|
||||
|
||||
This routine can be used either to store the current values of
|
||||
Kernal indirect vectors at $0314-$0333 or to write new values
|
||||
to the vectors. When calling this routine, .X and .Y should be
|
||||
loaded with the address of a 32-byte table (low byte in .X,
|
||||
high byte in .Y). If the status-register carry bit is clear when
|
||||
the routine is called, the vectors will be loaded with the values
|
||||
from the table. If carry is set, the 16 two-byte address values
|
||||
currently in the vectors will be copied to the table.
|
||||
New 128 Kernal Jump Table
|
||||
Locations $FF47-$FF7F comprise a new table of jump vectors
|
||||
to routines found in Commodore 128 ROM, but not in the
|
||||
Commodore 64.
|
||||
|
||||
$FF53 BOOT_CALL
|
||||
|
||||
This routine attempts to load and execute boot sectors from a
|
||||
specified disk drive. Call the routine with .X holding the de-
|
||||
vice number for the drive (usually 8) and with the accu-
|
||||
mulator holding the character code corresponding to the drive
|
||||
number—not the actual drive number. The single drive in
|
||||
1541 and 1571 units is drive 0; in this case, use 48, the charac-
|
||||
ter code for zero. If the specified drive is not present or is
|
||||
tumed off, or if the disk in the drive does not contain a valid
|
||||
boot sector, the routine will return with the status-register
|
||||
carry bit set. If a boot sector is found, it will be loaded into
|
||||
locations $0B00-$0BFF. Additional boot sectors may be loaded
|
||||
into other areas of memory, and the boot code may not return
|
||||
to this routine.
|
||||
|
||||
$FF4A CLOSE_ALL
|
||||
|
||||
This routine closes all files currently opened to a specified de-
|
||||
vice, providing an improved version of CLALL. Enter the rou-
|
||||
tine with the accumulator holding the number of the device
|
||||
on which files are to be closed. Lf the specified device is the
|
||||
current input or output device, the input or output channel
|
||||
will be reset to the default device (screen or keyboard). If all
|
||||
files to the device were successfully closed, the status-register
|
||||
carry bit w01 clear upon return. A set carry bit indicates that a
|
||||
device error occurred.
|
||||
|
||||
$FF4D C64_MODE
|
||||
|
||||
This is the equivalent of the BASIC command GO 64. It per-
|
||||
forms an immediate cold start of 64 mode. To get back to 128
|
||||
mode, it is necessary to reset the computer, or to tum it off
|
||||
and back on.
|
||||
|
||||
$FF62 DLCHR
|
||||
|
||||
This routine copies character shape data for both standard
|
||||
ROM character sets into the VDC video chip's private block of
|
||||
RAM, providing character definitions for the 80-column dis-
|
||||
play. (The VDC has no character ROM.) This routine is also
|
||||
called as part of IOEMFI for the 128.
|
||||
|
||||
$FF50 DMA_CALL
|
||||
|
||||
This routine passes a command to a DMA (Direct Memory Ac-
|
||||
cess) device. The DMA device will then take control of the
|
||||
system to execute the command. The routine is written to sup-
|
||||
port the REC (RAM Expansion Controller) chip in the 1700
|
||||
and 1750 Memory Expansion Modules, the only DMA periph-
|
||||
erals currently available. Call the routine with .Y holding the
|
||||
command for the DMA device and .X holding the bank number
|
||||
for the operation. Other preparatory steps may be required,
|
||||
depending on the command.
|
||||
|
||||
$FF6B GETCFG
|
||||
|
||||
This routine translates a bank number (0-15) into the
|
||||
corresponding MMU register setting to configure the system
|
||||
for that bank. Call the routine with .X holding the bank num-
|
||||
ber. Upon return, the accumulator will hold the corresponding
|
||||
MMU configuration register value. (.Y is unaffected.) Once you
|
||||
have this value, you can store it into $FF00 to change banks.
|
||||
The input bank number is not checked for validity, and a
|
||||
number outside the acceptable range will return a meaningless
|
||||
value.
|
||||
|
||||
$FF7A INDCMP
|
||||
|
||||
This routine compares .A to the number held in a memory
|
||||
location in a specified bank. In preparing to call EMDCMP,
|
||||
load a two-byte zero-page pointer with the address of the
|
||||
location with which the accumulator is to be compared (or
|
||||
with the base location if a series of bytes is to be compared),
|
||||
then store the address of this pointer in location $02C8. Call
|
||||
the routine with the accumulator holding the byte to be com-
|
||||
pared, .X holding the bank number (0-15) for the target loca-
|
||||
tion, and .Y holding an offset value which will be added to
|
||||
the address in the pointer. (Load .Y with 0 if no offset is de-
|
||||
sired.) Upon return, the accumulator will still hold the byte
|
||||
value, and the status-register N, Z, and C (carry) bits will re-
|
||||
flect the result of the comparison. The value in .Y will also be
|
||||
preserved, but it is necessary to reload .X with the bank num-
|
||||
ber before every call to this routine. You can compare up to
|
||||
256 sequential locations without changing the address in the
|
||||
zero-page pointer by simply incrementing .Y between calls.
|
||||
|
||||
$FF74 INDFET
|
||||
|
||||
This routine reads the contents of a location in a specified
|
||||
bank. Prior to calling this routine; you must load a two-byte
|
||||
zero-page pointer with the address of the location to be read
|
||||
(or with the base location if a series of bytes is to be read).
|
||||
|
||||
Call the routine with the accumulator holding the address
|
||||
of the zero-page pointer, .X holding the bank number (0-15)
|
||||
for the target location, and .Y holding an offset value which
|
||||
will be added to the address in the pointer. (Load .Y with 0 if
|
||||
no offset is desired.) Upon return, the accumulator will hold
|
||||
the byte from the specified address. The value in .Y is not
|
||||
changed.
|
||||
|
||||
To read from a series of locations, it is necessary to reload
|
||||
the accumulator and .X values before every call to this routine,
|
||||
but you can read up to 256 sequential locations without
|
||||
changing the address in the zero-page pointer by incrementing
|
||||
.Y between calls.
|
||||
|
||||
$FF77 INDSTA
|
||||
|
||||
This routine stores a value at an address in a specified bank.
|
||||
Before calling the routine, you must load a two-byte zero-page
|
||||
pointer with the address of the location at which the byte is to
|
||||
be stored (or with the base location if a series of bytes is to be
|
||||
stored), and then store the address of this pointer in location
|
||||
$02B9. Call the routine with the accumulator holding the byte
|
||||
to be stored, .X holding the bank number (0-15) for the target
|
||||
location, and .Y holding an offset value which will be added
|
||||
to the address in the pointer. (Load Y with 0 if no offset is de-
|
||||
sired.) Upon return, the accumulator will still hold the byte
|
||||
value; .Y is also preserved. To write to a series of locations,
|
||||
you must reload .X with the bank number before every call,
|
||||
but you can write to up to 256 sequential locations without
|
||||
changing the address in the zero-page pointer by simply in-
|
||||
crementing .Y between calls.
|
||||
|
||||
$FF71 JMPFAR
|
||||
|
||||
JMPFAR jumps to a routine in a specified bank, with no return
|
||||
to the calling bank. Prior to calling this routine, you must store
|
||||
the bank number (0-15) of the target routine in location 2 and
|
||||
the address of the target routine in locations 3-4 in high-
|
||||
byte/low-byte order, opposite from the usual arrangement.
|
||||
Load location 5 with the value you want placed in the status
|
||||
register when the target routine is entered. (The behavior of
|
||||
many operating-system routines is influenced by the status-
|
||||
register setting, particularly the state of the carry bit. Load 5
|
||||
with the value 0 to clear carry or with 1 to set carry.) To pass
|
||||
other register values, store the desired accumulator value in
|
||||
location 6, the value for .X in 7, and the value for .Y in 8.
|
||||
|
||||
$FF6E JSRFAR
|
||||
|
||||
This routine jumps to a subroutine in a specified bank and re-
|
||||
turns to the calling routine in bank 15. Prior to calling this
|
||||
routine, you must store the bank number (0-15) of the target
|
||||
routine in location 2 and the address of the target routine in
|
||||
locations 3-4 (in high-byte/low-byte order, opposite from the
|
||||
usual arrangement). Load location 5 with the value you want
|
||||
placed in the status register when the target routine is called.
|
||||
(The behavior of many operating system routines is influenced
|
||||
by the status-register setting, particularly the state of the carry
|
||||
bit. Load 5 with the value 0 to clear carry, or with 1 to set
|
||||
carry.) To pass other register values to the routine you will be
|
||||
calling, store the desired accumulator value in location 6, the
|
||||
value for .X in 7, and the value for .Y in 8. Upon return, loca-
|
||||
tion 5 will hold the status-register value at the time of exit, 6
|
||||
will hold the accumulator value, 7 will hold the .X value, 8
|
||||
will hold the .Y value, and 9 will hold the stack-pointer value.
|
||||
The system is always configured for bank 15 upon exit.
|
||||
|
||||
$FF59 LKUPLA
|
||||
|
||||
This routine checks whether a specified logical file number is
|
||||
currently used. Call the routine with the accumulator holding
|
||||
the logical-file-number value in question. If that file number is
|
||||
available, the carry bit will be set upon return. (The logical file
|
||||
number will still be in the accumulator.) However, if the num-
|
||||
ber is used for a currently open file, then the carry bit will be
|
||||
clear upon return, the accumulator will still hold the logical
|
||||
file number, .X will hold the corresponding device number,
|
||||
and .Y will hold the corresponding secondary address.
|
||||
|
||||
$FF5C LKUPSA
|
||||
|
||||
This routine checks whether a specified secondary address is
|
||||
currently in use. Call the routine with .Y holding the secondary-
|
||||
address value in question. If that secondary address is not
|
||||
currently used, the status-register carry bit will be set upon re-
|
||||
turn. (The secondary-address value will still be in .Y.) How-
|
||||
ever, ii the number is used for a currently open file, the carry
|
||||
bit will be clear upon return, .Y will still hold the secondary
|
||||
address, the accumulator will hold the associated logical file
|
||||
number, and .X will hold the corresponding device number.
|
||||
|
||||
$FF65 PFKEY
|
||||
|
||||
When you turn on the 128, its function keys are predefined.
|
||||
Pressing F3 prints DIRECTORY, F7 holds the LIST command,
|
||||
and so on. The PFKEY Kernal routine assigns a new definition
|
||||
to one of the 10 programmable function keys (F1-F8, SHIFT-
|
||||
RUN/STOP, and HELP).
|
||||
|
||||
Call the routine with the accumulator holding the address
|
||||
of a three-byte zero-page string descriptor, .X holding the key
|
||||
number (1-10), and .Y holding the length of the new defi-
|
||||
nition string. The first two bytes of the descriptor in zero page
|
||||
should contain the address of the definition string (in the
|
||||
usual low-byte/high-byte order); the final byte should hold
|
||||
the bank number where the definition string is located. PFKEY
|
||||
doesn't check the key number for validity; a value outside the
|
||||
acceptable range may garble existing definitions. Upon return,
|
||||
the carry bit will be clear if the new definition was success-
|
||||
fully added, or set if there was insufficient room in the defi-
|
||||
nition table for the new definition.
|
||||
|
||||
$FF56 PHOENIX
|
||||
|
||||
This routine initializes function ROMs and attempts to boot a
|
||||
disk from the default drive. The presence of function ROMs in
|
||||
cartridges or in the 128's spare ROM socket is recorded during
|
||||
the power-on/reset sequence. This routine initializes the func-
|
||||
tion ROMs by calling their recorded cold-start entry addresses.
|
||||
If ROMs are present, they may or may not return to this rou-
|
||||
tine, depending on the initialization steps performed. If no
|
||||
ROMs are present, or if all ROMs return after initialization,
|
||||
the routine attempts to boot a disk in drive 0 of device 8 using
|
||||
the BOOT_CALL routine,
|
||||
|
||||
$FF7D PRIMM
|
||||
|
||||
This routine prints the string of character codes which im-
|
||||
mediately follows the JSR to this routine. (You must always
|
||||
call this routine with JSR, never with JMP. Only JSR places the
|
||||
required address information on the stack.) The routine contin-
|
||||
ues printing bytes as character codes until a byte containing
|
||||
zero is encountered. When the ending marker is found, the
|
||||
routine returns to the address immediately following the zero
|
||||
byte. All registers (.A, .X, and .Y) are preserved during this
|
||||
routine.
|
||||
|
||||
$FF68 SETBNK
|
||||
|
||||
This Kernal routine establishes the current memory bank from
|
||||
which data will be read or to which data will be written dur-
|
||||
ing load/save operations, as well as the bank where the file-
|
||||
name for the I/O operations can be found. Call the routine
|
||||
with the accumulator holding the bank number for data and
|
||||
.X holding the bank for the filename. All registers (.A, .X, and
|
||||
.Y) are preserved during this routine.
|
||||
|
||||
$FF47 SPIN_SPOUT
|
||||
|
||||
This low-level serial I/O routine sets up the serial bus for fast
|
||||
(burst mode) communications. Unless you're writing a custom
|
||||
data-transfer routine, it's not necessary to call this routine
|
||||
explicitly. All higher-level serial 1/0 routines already include
|
||||
this setup step. The routine should be called with the status-
|
||||
register carry bit clear to establish fast serial input or with the
|
||||
bit set to establish fast serial output.
|
||||
|
||||
$FF5F SWAPPER
|
||||
|
||||
This routine switches active screen displays. The active display
|
||||
is the one which has a live cursor, and to which screen
|
||||
CHROUT output is directed. The routine exchanges the active
|
||||
and inactive screen-editor variable tables, tab-stop bitmaps,
|
||||
and line-link bitmaps; and it toggles the active screen flag
|
||||
(location $D7). The routine doesn't physically tum either
|
||||
video chip on or off—both chips always remain enabled.
|
||||
412
kernal/kernal_pm.txt
Normal file
412
kernal/kernal_pm.txt
Normal file
|
|
@ -0,0 +1,412 @@
|
|||
-
|
||||
- https://www.atarimagazines.com/compute/issue40/cracking_the_kernal.php
|
||||
- Peter Marcotty: Cracking The Kernal
|
||||
- COMPUTE! #40, September 1983, pp. 268-274
|
||||
-
|
||||
- Descriptions of RESTOR, SAVE, SCNKEY and SCREEN are missing from
|
||||
- the original source.
|
||||
-
|
||||
|
||||
$FFA5 ACPTR Input byte from serial port.
|
||||
|
||||
ACPTR is used to get data off the serial bus. TALK and TKSA must be called first.
|
||||
|
||||
;Get a byte from the serial bus.
|
||||
JSR ACPTR
|
||||
STA $0800
|
||||
;This example only shows the end result; call TALK and TKSA first.
|
||||
|
||||
$FFC6 CHKIN Open channel for input.
|
||||
|
||||
CHKIN is used to define any OPENed file as an input file. OPEN must be called first.
|
||||
|
||||
;Define logical file #2 as an input channel.
|
||||
LDX #2
|
||||
JSR CHKIN
|
||||
;The X register designates which file #.
|
||||
|
||||
$FFC9 CHKOUT Open channel for output.
|
||||
|
||||
CHKOUT. Just like CHKIN, but it defines the file for output. OPEN must be called first.
|
||||
|
||||
;Define logical file #4 as an output file.
|
||||
LDX #4
|
||||
JSR CHKOUT
|
||||
;Once again the X register defines the file #.
|
||||
|
||||
$FFCF CHRIN Input character from channel.
|
||||
|
||||
CHRIN will get a character from the current input device. Calling OPEN and CHKIN can change the input device.
|
||||
|
||||
;Store a typed string to the screen.
|
||||
LDY #$00
|
||||
LOOP JSR CHKIN
|
||||
STA $0800,Y
|
||||
INY
|
||||
CMP #$0D
|
||||
BNE LOOP
|
||||
RTS
|
||||
;This example is like an INPUT statement. Try running it.
|
||||
|
||||
$FFD2 CHROUT Output character to channel.
|
||||
|
||||
CHROUT. Load the accumulator with your number and call. OPEN and CHKOUT will change the output device.
|
||||
|
||||
;Duplicate the command of CMD 4:PRINT "A";
|
||||
LDX #4
|
||||
JSR CHKOUT
|
||||
LDA #'A
|
||||
JSR CHROUT
|
||||
RTS
|
||||
;The letter A is printed to the screen; call OPEN first for the printer.
|
||||
|
||||
$FFAB CIOUT Output byte to serial port.
|
||||
|
||||
CIOUT will send data to the serial bus. LISTEN and SECOND must be called first. Call UNLSN to finish up neatly.
|
||||
|
||||
;Send the letter X to the serial bus.
|
||||
LDA #'X
|
||||
JSR CIOUT
|
||||
RTS
|
||||
;The accumulator is used to transfer the data.
|
||||
|
||||
$FF81 CINT Initialize screen editor.
|
||||
|
||||
CINT resets the 6567 video controller chip and the screen editor.
|
||||
|
||||
;Reset the 6567 chip and the 6566 VIC chip.
|
||||
JSR CINT
|
||||
RTS
|
||||
;Basically, just like pressing the STOP and RESTORE keys.
|
||||
|
||||
$FFE7 CLALL Close all channels and files.
|
||||
|
||||
CLALL really does what its name implies-it closes all files and resets all channels.
|
||||
|
||||
;Close all files.
|
||||
JSR CLALL
|
||||
RTS
|
||||
;The CLRCHN routine is called automatically.
|
||||
|
||||
$FFC3 CLOSE Close a specified logical file.
|
||||
|
||||
CLOSE. This routine will CLOSE any logical file that has been OPENed.
|
||||
|
||||
Close logical file #2.
|
||||
LDA #2
|
||||
JSR CLOSE
|
||||
;The accumulator designates the file #.
|
||||
|
||||
$FFCC CLRCHN Close input and output channels.
|
||||
|
||||
CLRCHN resets all channels and I/O registers - the input to keyboard and the output to screen.
|
||||
|
||||
;Restore default values to I/O devices.
|
||||
JSR CLRCHN
|
||||
RTS
|
||||
;The accumulator and the X register are altered.
|
||||
|
||||
$FFE4 GETIN Get character from keyboard buffer.
|
||||
|
||||
GETIN will get one piece of data from the input device. OPEN and CHKIN can be used to change the input device.
|
||||
|
||||
;Wait for a key to be pressed.
|
||||
WAIT JSR GETIN
|
||||
CMP #0
|
||||
BEQ WAIT
|
||||
;If the serial bus is used, then all registers are altered.
|
||||
|
||||
$FFF3 IOBASE Return base address of I/O devices.
|
||||
|
||||
IOBASE returns the low and high bytes of the starting address of the I/O devices in the X and Y registers.
|
||||
|
||||
;Set the Data Direction Register of the user port to 0 (input).
|
||||
JSR IOBASE
|
||||
STX POINT
|
||||
STY POINT+1
|
||||
LDY #2
|
||||
LDA #0
|
||||
STA (POINT),Y
|
||||
;POINT is a zero-page address used to access the DDR indirectly.
|
||||
|
||||
$FF84 IOINIT Initialize input/output.
|
||||
|
||||
IOINIT initializes all I/O devices and routines. It is part of the system's powering-up routine.
|
||||
|
||||
;Initialize all I/O devices.
|
||||
JSR IOINIT
|
||||
RTS
|
||||
;All registers are altered.
|
||||
|
||||
$FFB1 LISTEN Command devices on serial bus to LISTEN.
|
||||
|
||||
LISTEN will command any device on the serial bus to receive data.
|
||||
|
||||
;Command device #8 to listen.
|
||||
LDA #8
|
||||
JSR
|
||||
LISTEN
|
||||
;The accumulator designates the device #.
|
||||
|
||||
$FFD5 LOAD Load RAM from a device.
|
||||
|
||||
LOAD. The computer will perform either the LOAD or the VERIFY command. If the ac cumulator is a 1, then LOAD; if 0, then verify.
|
||||
|
||||
;Load a program into memory.
|
||||
LDA #$08
|
||||
LDX #$02
|
||||
LDY #$00
|
||||
JSR SETLFS
|
||||
LDA #$04
|
||||
LDX #L,NAME
|
||||
LDY #H,NAME
|
||||
JSR SETNAM
|
||||
LDA #$00
|
||||
LDY #$20
|
||||
JSR LOAD
|
||||
RTS
|
||||
NAME .BY 'FILE'
|
||||
;Program 'FILE' will be loaded into memory starting at 8192 decimal, X being the low byte and Y being the high byte for the load.
|
||||
|
||||
$FF9C MEMBOT Read/set bottom of memory.
|
||||
|
||||
MEMBOT. If the carry bit is set, then the low byte and the high byte of RAM are returned in the X and Y registers. If the carry bit is clear, the bottom of RAM is set to the X and Y registers.
|
||||
|
||||
;Move bottom of memory up one page.
|
||||
SEC
|
||||
JSR MEMBOT
|
||||
INY
|
||||
CLC
|
||||
JSR MEMBOT
|
||||
RTS
|
||||
;The accumulator is left alone.
|
||||
|
||||
$FF99 MEMTOP Read/set top of memory.
|
||||
|
||||
MEMTOP. Same principle as MEMBOT, except the top of RAM is affected.
|
||||
|
||||
;Protect 1K of memory from BASIC.
|
||||
SEC
|
||||
JSR MEMTOP
|
||||
DEY
|
||||
CLC
|
||||
JSR MEMTOP
|
||||
;The accumulator is left alone.
|
||||
|
||||
$FFC0 OPEN Open a logical file.
|
||||
|
||||
OPEN. After SETLFS and SETNAM have been called, you can OPEN a logical file.
|
||||
|
||||
;Duplicate the command OPEN 15,8,15,'I/O'
|
||||
LDA #3
|
||||
LDX #L,NAME
|
||||
LDY #H,NAME
|
||||
JSR SETNAM
|
||||
LDA #15
|
||||
LDX #8
|
||||
LDY #15
|
||||
JSR SETLFS
|
||||
JSR OPEN
|
||||
RTS
|
||||
NAME .BY 'I/O'
|
||||
;OPEN opens the current name file with the current LFS.
|
||||
|
||||
$FFF0 PLOT Read/set X,Y cursor position.
|
||||
|
||||
PLOT. If the carry bit of the accumulator is set, then the cursor X,Y is returned in the Y and X registers. If the carry bit is clear, then the cursor is moved to X,Y as determined by the Y and X registers.
|
||||
|
||||
;Move cursor to row 12, column 20 (12,20).
|
||||
LDX #12
|
||||
LDY #20
|
||||
CLC
|
||||
JSR PLOT
|
||||
;The cursor is now in the middle of the screen.
|
||||
|
||||
$FF87 RAMTAS Initialize RAM, reset tape buffer.
|
||||
|
||||
RAMTAS is used to test RAM, reset the top and bottom of memory pointers, clear $0000 to $0101 and $0200 to $03FF, and set the screen memory to $0400.
|
||||
|
||||
;Do RAM test.
|
||||
JSR RAMTAS
|
||||
RTS
|
||||
;All registers are altered.
|
||||
|
||||
$FFDE RDTIM Read realtime clock.
|
||||
|
||||
RDTIM. Locations 160-162 are transferred, in order, to the Y and X registers and the accumulator.
|
||||
|
||||
;Store system clock to screen.
|
||||
JSR RDTIM
|
||||
STA 1026
|
||||
STX 1025
|
||||
STY 1024
|
||||
;The system clock can be translated as hours/minutes/ seconds.
|
||||
|
||||
$FFB7 READST Read I/O status word.
|
||||
|
||||
READST. When called, READST returns the status of the I/O devices. Any error code can be translated as operator error.
|
||||
|
||||
;Check for read error.
|
||||
JSR READST
|
||||
CMP #16
|
||||
BEQ ERROR
|
||||
;In this case, if the accumulator is 16, a read error occurred.
|
||||
|
||||
$FF8A RESTOR Restore I/O default vectors.
|
||||
|
||||
$FFDE SAVE Save RAM to device.
|
||||
|
||||
$FF9F SCNKEY Scan keyboard.
|
||||
|
||||
$FFED SCREEN Return X,Y organization of screen.
|
||||
|
||||
SCREEN returns the number of columns and rows the screen has in the X and Y registers.
|
||||
|
||||
;Determine the screen size.
|
||||
JSR SCREEN
|
||||
STX MAXCOL
|
||||
STY MAXROW
|
||||
RTS
|
||||
;SCREEN allows further compatibility between the 64, the VIC-20, and future versions of the 64.
|
||||
|
||||
$FF93 SECOND Send secondary address after LISTEN.
|
||||
|
||||
SECOND. After LISTEN has been called, a SECONDary address may be sent.
|
||||
|
||||
;Address device #8 with secondary address #15.
|
||||
LDA #8
|
||||
JSR LISTEN
|
||||
LDA #15
|
||||
JSR SECOND
|
||||
;The accumulator designates the address number.
|
||||
|
||||
$FFBA SETLFS Set logical, first, and second address.
|
||||
|
||||
SETLFS stands for SET Logical address, File address, and Secondary address. After SETLFS is called, OPEN may be called.
|
||||
|
||||
;Set logical file #1, device #8, secondary address of 15.
|
||||
LDA #1
|
||||
LDX #8
|
||||
LDY #15
|
||||
JSR SETLFS
|
||||
;If OPEN is called, the command will be OPEN 1,8,15.
|
||||
|
||||
$FF90 SETMSG Control Kernal messages.
|
||||
|
||||
SETMSG. Depending on the accumulator, either error messages, control messages, or neither is printed.
|
||||
|
||||
;Turn on control messages.
|
||||
LDA #$40
|
||||
JSR SETMSG
|
||||
RTS
|
||||
;A 128 is for error messages; a zero, for turning both off.
|
||||
|
||||
$FFBD SETNAM Set filename.
|
||||
|
||||
SETNAM. In order to access the OPEN, LOAD, or SAVE routines, SETNAM must be called first.
|
||||
|
||||
;SETNAM will prepare the disk drive for'FILE#1'.
|
||||
LDA #6
|
||||
LDX #L,NAME
|
||||
LDY #H,NAME
|
||||
JSR SETNAM
|
||||
NAME.BY 'FILE#l'
|
||||
;Accumulator is file length, X is low byte, and Y is high byte.
|
||||
|
||||
$FFDB SETTIM Set realtime clock.
|
||||
|
||||
SETTIM is the opposite of RDTIM: it SETs the system clock instead of ReaDing it.
|
||||
|
||||
;Set system clock to 10 minutes =3600 jiffies.
|
||||
LDA #0
|
||||
LDX #L,3600
|
||||
LDY #H,3600
|
||||
JSR SETTIM
|
||||
;This allows very accurate timing for many things.
|
||||
|
||||
$FFA2 SETTMO Set time-out on serial bus.
|
||||
|
||||
SETTMO is used only with an IEEE add-on card to access the serial bus.
|
||||
|
||||
;Disable time-outs on serial bus.
|
||||
LDA #0
|
||||
JSR SETTMO
|
||||
;To enable time-outs, set the accumulator to a 128 and call SETTMO.
|
||||
|
||||
$FFE1 STOP Check for STOP key.
|
||||
|
||||
STOP will set the Z flag of the accumulator if the STOP key was pressed.
|
||||
|
||||
;Check for STOP key being pressed.
|
||||
WAIT JSR STOP
|
||||
BNE WAIT
|
||||
RTS
|
||||
;STOP must be called if the STOP key is to remain functional.
|
||||
|
||||
$FFB4 TALK Command serial bus device to TALK.
|
||||
|
||||
TALK. This routine will command a device on the serial bus to send data.
|
||||
|
||||
;Command device #8 to TALK.
|
||||
LDA #8
|
||||
JSR TALK
|
||||
RTS
|
||||
;The accumulator designates the file number.
|
||||
|
||||
$FF96 TKSA Send secondary address after TALK.
|
||||
|
||||
TKSA is used to send a secondary address for a TALK device. TALK must be called first.
|
||||
|
||||
;Signal device #4 to talk with command #7.
|
||||
LDA #4
|
||||
JSR TALK
|
||||
LDA #7
|
||||
JSR TKSA
|
||||
RTS
|
||||
;This example will tell the printer to print in uppercase.
|
||||
|
||||
$FFEA UDTIM Increment realtime clock.
|
||||
|
||||
UDTIM. If you are using your own interrupt system, you can update the system clock by calling UDTIM.
|
||||
|
||||
;Update the system clock.
|
||||
JSR UDTIM
|
||||
RTS
|
||||
;It is useful to call UDTIM before calling STOP.
|
||||
|
||||
$FFAE UNLSN Command serial bus to UNLISTEN.
|
||||
|
||||
UNLSN commands all devices on the serial bus to stop receiving data.
|
||||
|
||||
;Command the serial bus to UNLiSteN.
|
||||
JSR UNLSN
|
||||
RTS
|
||||
;The serial bus can now be used for other things.
|
||||
|
||||
$FFAB UNTLK Command serial bus to UNTALK.
|
||||
|
||||
UNTLK. All devices previously set to TALK will stop sending data.
|
||||
|
||||
;Command serial bus to stop sending data.
|
||||
JSR UNTLK
|
||||
RTS
|
||||
;Sending UNTLK commands all talking devices to get off the serial bus.
|
||||
|
||||
$FF8D VECTOR Read/set vectored I/O.
|
||||
|
||||
VECTOR. If the carry bit of the accumulator is set, the start of a list of the current contents of the RAM vectors is returned in the X and Y registers. If the carry bit is clear, there the user list pointed to by the X and Y registers is transferred to the system RAM vectors.
|
||||
|
||||
;Change the input routines to new system.
|
||||
SEC
|
||||
JSR VECTOR
|
||||
LDA #L,MYINP
|
||||
STA USER+10
|
||||
LDA #H,MYINP
|
||||
STA USER+11
|
||||
LDX #L,USER
|
||||
LDY #H,USER
|
||||
CLC
|
||||
JSR VECTOR
|
||||
RTS
|
||||
USER .DE 26
|
||||
;The new input list can start anywhere. USER is the location for temporary strings, and 35-36 is the utility pointer area.
|
||||
1280
kernal/kernal_prg.txt
Normal file
1280
kernal/kernal_prg.txt
Normal file
File diff suppressed because it is too large
Load diff
273
kernal/kernal_sta.txt
Normal file
273
kernal/kernal_sta.txt
Normal file
|
|
@ -0,0 +1,273 @@
|
|||
$FF81 SCINIT Initialize VIC; restore default input/output to keyboard/screen; clear screen; set PAL/NTSC switch and interrupt timer.
|
||||
|
||||
Input: –
|
||||
Output: –
|
||||
Used registers: A, X, Y.
|
||||
Real address: $FF5B.
|
||||
|
||||
$FF84 IOINIT Initialize CIA's, SID volume; setup memory configuration; set and start interrupt timer.
|
||||
|
||||
Input: –
|
||||
Output: –
|
||||
Used registers: A, X.
|
||||
Real address: $FDA3.
|
||||
|
||||
$FF87 RAMTAS Clear memory addresses $0002-$0101 and $0200-$03FF; run memory test and set start and end address of BASIC work area accordingly; set screen memory to $0400 and datasette buffer to $033C.
|
||||
|
||||
Input: –
|
||||
Output: –
|
||||
Used registers: A, X, Y.
|
||||
Real address: $FD50.
|
||||
|
||||
$FF8A RESTOR Fill vector table at memory addresses $0314-$0333 with default values.
|
||||
|
||||
Input: –
|
||||
Output: –
|
||||
Used registers: –
|
||||
Real address: $FD15.
|
||||
|
||||
$FF8D VECTOR Copy vector table at memory addresses $0314-$0333 from or into user table.
|
||||
|
||||
Input: Carry: 0 = Copy user table into vector table, 1 = Copy vector table into user table; X/Y = Pointer to user table.
|
||||
Output: –
|
||||
Used registers: A, Y.
|
||||
Real address: $FD1A.
|
||||
|
||||
$FF90 SETMSG Set system error display switch at memory address $009D.
|
||||
|
||||
Input: A = Switch value.
|
||||
Output: –
|
||||
Used registers: –
|
||||
Real address: $FE18.
|
||||
|
||||
$FF93 LSTNSA Send LISTEN secondary address to serial bus. (Must call LISTEN beforehands.)
|
||||
|
||||
Input: A = Secondary address.
|
||||
Output: –
|
||||
Used registers: A.
|
||||
Real address: $EDB9.
|
||||
|
||||
$FF96 TALKSA Send TALK secondary address to serial bus. (Must call TALK beforehands.)
|
||||
|
||||
Input: A = Secondary address.
|
||||
Output: –
|
||||
Used registers: A.
|
||||
Real address: $EDC7.
|
||||
|
||||
$FF99 MEMBOT Save or restore start address of BASIC work area.
|
||||
|
||||
Input: Carry: 0 = Restore from input, 1 = Save to output; X/Y = Address (if Carry = 0).
|
||||
Output: X/Y = Address (if Carry = 1).
|
||||
Used registers: X, Y.
|
||||
Real address: $FE25.
|
||||
|
||||
$FF9C MEMTOP Save or restore end address of BASIC work area.
|
||||
|
||||
Input: Carry: 0 = Restore from input, 1 = Save to output; X/Y = Address (if Carry = 0).
|
||||
Output: X/Y = Address (if Carry = 1).
|
||||
Used registers: X, Y.
|
||||
Real address: $FE34.
|
||||
|
||||
$FF9F SCNKEY Query keyboard; put current matrix code into memory address $00CB, current status of shift keys into memory address $028D and PETSCII code into keyboard buffer.
|
||||
|
||||
Input: –
|
||||
Output: –
|
||||
Used registers: A, X, Y.
|
||||
Real address: $EA87.
|
||||
|
||||
$FFA2 SETTMO Unknown. (Set serial bus timeout.)
|
||||
|
||||
Input: A = Timeout value.
|
||||
Output: –
|
||||
Used registers: –
|
||||
Real address: $FE21.
|
||||
|
||||
$FFA5 IECIN Read byte from serial bus. (Must call TALK and TALKSA beforehands.)
|
||||
|
||||
Input: –
|
||||
Output: A = Byte read.
|
||||
Used registers: A.
|
||||
Real address: $EE13.
|
||||
|
||||
$FFA8 IECOUT Write byte to serial bus. (Must call LISTEN and LSTNSA beforehands.)
|
||||
|
||||
Input: A = Byte to write.
|
||||
Output: –
|
||||
Used registers: –
|
||||
Real address: $EDDD.
|
||||
|
||||
$FFAB UNTALK Send UNTALK command to serial bus.
|
||||
|
||||
Input: –
|
||||
Output: –
|
||||
Used registers: A.
|
||||
Real address: $EDEF.
|
||||
|
||||
$FFAE UNLSTN Send UNLISTEN command to serial bus.
|
||||
|
||||
Input: –
|
||||
Output: –
|
||||
Used registers: A.
|
||||
Real address: $EDFE.
|
||||
|
||||
$FFB1 LISTEN Send LISTEN command to serial bus.
|
||||
|
||||
Input: A = Device number.
|
||||
Output: –
|
||||
Used registers: A.
|
||||
Real address: $ED0C.
|
||||
|
||||
$FFB4 TALK Send TALK command to serial bus.
|
||||
|
||||
Input: A = Device number.
|
||||
Output: –
|
||||
Used registers: A.
|
||||
Real address: $ED09.
|
||||
|
||||
$FFB7 READST Fetch status of current input/output device, value of ST variable. (For RS232, status is cleared.)
|
||||
|
||||
Input: –
|
||||
Output: A = Device status.
|
||||
Used registers: A.
|
||||
Real address: $FE07.
|
||||
|
||||
$FFBA SETLFS Set file parameters.
|
||||
|
||||
Input: A = Logical number; X = Device number; Y = Secondary address.
|
||||
Output: –
|
||||
Used registers: –
|
||||
Real address: $FE00.
|
||||
|
||||
$FFBD SETNAM Set file name parameters.
|
||||
|
||||
Input: A = File name length; X/Y = Pointer to file name.
|
||||
Output: –
|
||||
Used registers: –
|
||||
Real address: $FDF9.
|
||||
|
||||
$FFC0 OPEN Open file. (Must call SETLFS and SETNAM beforehands.)
|
||||
|
||||
Input: –
|
||||
Output: –
|
||||
Used registers: A, X, Y.
|
||||
Real address: ($031A), $F34A.
|
||||
|
||||
$FFC3 CLOSE Close file.
|
||||
|
||||
Input: A = Logical number.
|
||||
Output: –
|
||||
Used registers: A, X, Y.
|
||||
Real address: ($031C), $F291.
|
||||
|
||||
$FFC6 CHKIN Define file as default input. (Must call OPEN beforehands.)
|
||||
|
||||
Input: X = Logical number.
|
||||
Output: –
|
||||
Used registers: A, X.
|
||||
Real address: ($031E), $F20E.
|
||||
|
||||
$FFC9 CHKOUT Define file as default output. (Must call OPEN beforehands.)
|
||||
|
||||
Input: X = Logical number.
|
||||
Output: –
|
||||
Used registers: A, X.
|
||||
Real address: ($0320), $F250.
|
||||
|
||||
$FFCC CLRCHN Close default input/output files (for serial bus, send UNTALK and/or UNLISTEN); restore default input/output to keyboard/screen.
|
||||
|
||||
Input: –
|
||||
Output: –
|
||||
Used registers: A, X.
|
||||
Real address: ($0322), $F333.
|
||||
|
||||
$FFCF CHRIN Read byte from default input (for keyboard, read a line from the screen). (If not keyboard, must call OPEN and CHKIN beforehands.)
|
||||
|
||||
Input: –
|
||||
Output: A = Byte read.
|
||||
Used registers: A, Y.
|
||||
Real address: ($0324), $F157.
|
||||
|
||||
$FFD2 CHROUT Write byte to default output. (If not screen, must call OPEN and CHKOUT beforehands.)
|
||||
|
||||
Input: A = Byte to write.
|
||||
Output: –
|
||||
Used registers: –
|
||||
Real address: ($0326), $F1CA.
|
||||
|
||||
$FFD5 LOAD Load or verify file. (Must call SETLFS and SETNAM beforehands.)
|
||||
|
||||
Input: A: 0 = Load, 1-255 = Verify; X/Y = Load address (if secondary address = 0).
|
||||
Output: Carry: 0 = No errors, 1 = Error; A = KERNAL error code (if Carry = 1); X/Y = Address of last byte loaded/verified (if Carry = 0).
|
||||
Used registers: A, X, Y.
|
||||
Real address: $F49E.
|
||||
|
||||
$FFD8 SAVE Save file. (Must call SETLFS and SETNAM beforehands.)
|
||||
|
||||
Input: A = Address of zero page register holding start address of memory area to save; X/Y = End address of memory area plus 1.
|
||||
Output: Carry: 0 = No errors, 1 = Error; A = KERNAL error code (if Carry = 1).
|
||||
Used registers: A, X, Y.
|
||||
Real address: $F5DD.
|
||||
|
||||
$FFDB SETTIM Set Time of Day, at memory address $00A0-$00A2.
|
||||
|
||||
Input: A/X/Y = New TOD value.
|
||||
Output: –
|
||||
Used registers: –
|
||||
Real address: $F6E4.
|
||||
|
||||
$FFDE RDTIM read Time of Day, at memory address $00A0-$00A2.
|
||||
|
||||
Input: –
|
||||
Output: A/X/Y = Current TOD value.
|
||||
Used registers: A, X, Y.
|
||||
Real address: $F6DD.
|
||||
|
||||
$FFE1 STOP Query Stop key indicator, at memory address $0091; if pressed, call CLRCHN and clear keyboard buffer.
|
||||
|
||||
Input: –
|
||||
Output: Zero: 0 = Not pressed, 1 = Pressed; Carry: 1 = Pressed.
|
||||
Used registers: A, X.
|
||||
Real address: ($0328), $F6ED.
|
||||
|
||||
$FFE4 GETIN Read byte from default input. (If not keyboard, must call OPEN and CHKIN beforehands.)
|
||||
|
||||
Input: –
|
||||
Output: A = Byte read.
|
||||
Used registers: A, X, Y.
|
||||
Real address: ($032A), $F13E.
|
||||
|
||||
$FFE7 CLALL Clear file table; call CLRCHN.
|
||||
|
||||
Input: –
|
||||
Output: –
|
||||
Used registers: A, X.
|
||||
Real address: ($032C), $F32F.
|
||||
|
||||
$FFEA UDTIM Update Time of Day, at memory address $00A0-$00A2, and Stop key indicator, at memory address $0091.
|
||||
|
||||
Input: –
|
||||
Output: –
|
||||
Used registers: A, X.
|
||||
Real address: $F69B.
|
||||
|
||||
$FFED SCREEN Fetch number of screen rows and columns.
|
||||
|
||||
Input: –
|
||||
Output: X = Number of columns (40); Y = Number of rows (25).
|
||||
Used registers: X, Y.
|
||||
Real address: $E505.
|
||||
|
||||
$FFF0 PLOT Save or restore cursor position.
|
||||
|
||||
Input: Carry: 0 = Restore from input, 1 = Save to output; X = Cursor column (if Carry = 0); Y = Cursor row (if Carry = 0).
|
||||
Output: X = Cursor column (if Carry = 1); Y = Cursor row (if Carry = 1).
|
||||
Used registers: X, Y.
|
||||
Real address: $E50A.
|
||||
|
||||
$FFF3 IOBASE Fetch CIA #1 base address.
|
||||
|
||||
Input: –
|
||||
Output: X/Y = CIA #1 base address ($DC00).
|
||||
Used registers: X, Y.
|
||||
Real address: $E500.
|
||||
|
||||
252
style.css
252
style.css
|
|
@ -1,252 +0,0 @@
|
|||
|
||||
/* Colors */
|
||||
|
||||
:root {
|
||||
--main-background: #e0f0ff;
|
||||
--main-color: #004080;
|
||||
|
||||
--highlight-background: #006ad5;
|
||||
|
||||
--border-color: #0060a0;
|
||||
|
||||
--title-color-1: #017100;
|
||||
--title-color-2: #004D7F;
|
||||
--title-color-3: #99195E;
|
||||
--title-color-4: #F8BA00;
|
||||
--title-color-5: #B51700;
|
||||
--title-color-6: #017B76;
|
||||
--title-color-7: #595959;
|
||||
--title-color-8: #714a00;
|
||||
|
||||
--dark-color-1: #D8F2CB;
|
||||
--dark-color-2: #C6E2FC;
|
||||
--dark-color-3: #BFB7E8;
|
||||
--dark-color-4: #FCF6CD;
|
||||
--dark-color-5: #F4D2E3;
|
||||
--dark-color-6: #D2F6F0;
|
||||
--dark-color-7: #E0E0E0;
|
||||
--dark-color-8: #F2E4CB;
|
||||
|
||||
--light-color-1: #E5F2DF;
|
||||
--light-color-2: #E3F0FC;
|
||||
--light-color-3: #D5D1E8;
|
||||
--light-color-4: #FCFAE6;
|
||||
--light-color-5: #F5E4EC;
|
||||
--light-color-6: #E1F5F2;
|
||||
--light-color-7: #EDEDED;
|
||||
--light-color-8: #F2EBDF;
|
||||
}
|
||||
|
||||
|
||||
/**/
|
||||
|
||||
body {
|
||||
background: var(--main-background);
|
||||
color: var(--main-color);
|
||||
font-family: Helvetica;
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--border-color);
|
||||
}
|
||||
|
||||
div {
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
div.body {
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
|
||||
/* Navigation */
|
||||
|
||||
.topnav {
|
||||
background-color: #333;
|
||||
overflow: hidden;
|
||||
padding: 0px;
|
||||
border-bottom: solid 2px var(--main-color);
|
||||
}
|
||||
|
||||
.topnav a, .topnav h1 {
|
||||
float: left;
|
||||
text-align: center;
|
||||
padding: 14px 16px;
|
||||
margin: 0px;
|
||||
text-decoration: none;
|
||||
font-size: 17px;
|
||||
}
|
||||
|
||||
.topnav a {
|
||||
color: white;
|
||||
border-right:solid 1px var(--main-background);
|
||||
}
|
||||
|
||||
.topnav h1 {
|
||||
color: black;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.topnav a:hover {
|
||||
background-color: var(--main-background);
|
||||
color: black;
|
||||
}
|
||||
|
||||
.topnav a.active {
|
||||
background-color: var(--highlight-background);
|
||||
color: white;
|
||||
}
|
||||
|
||||
/* Tables */
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border: solid 1px var(--border-color);
|
||||
color: black;
|
||||
}
|
||||
|
||||
tr, td, th {
|
||||
margin: 0px;
|
||||
text-align:left;
|
||||
vertical-align: text-top;
|
||||
}
|
||||
|
||||
th.com {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
|
||||
/* Overview Table */
|
||||
|
||||
table.checkbox_table tr, table.checkbox_table td {
|
||||
padding: 4px 8px;
|
||||
border: solid var(--border-color);
|
||||
border-width:1px 0px 1px 0px;
|
||||
}
|
||||
|
||||
table.checkbox_table a {
|
||||
color: var(--main-background);
|
||||
}
|
||||
|
||||
|
||||
/* Overview Table: Multicolor */
|
||||
|
||||
table.checkbox_table tr:nth-of-type(1) { background: var(--light-color-1); }
|
||||
table.checkbox_table tr:nth-of-type(1) td:nth-of-type(2) { background: var(--title-color-1);}
|
||||
|
||||
table.checkbox_table tr:nth-of-type(2) { background: var(--light-color-2); }
|
||||
table.checkbox_table tr:nth-of-type(2) td:nth-of-type(2) { background: var(--title-color-2); }
|
||||
|
||||
table.checkbox_table tr:nth-of-type(3) { background: var(--light-color-3); }
|
||||
table.checkbox_table tr:nth-of-type(3) td:nth-of-type(2) { background: var(--title-color-3); }
|
||||
|
||||
table.checkbox_table tr:nth-of-type(4) { background: var(--light-color-4); }
|
||||
table.checkbox_table tr:nth-of-type(4) td:nth-of-type(2) { background: var(--title-color-4); }
|
||||
|
||||
table.checkbox_table tr:nth-of-type(5) { background: var(--light-color-5); }
|
||||
table.checkbox_table tr:nth-of-type(5) td:nth-of-type(2) { background: var(--title-color-5); }
|
||||
|
||||
table.checkbox_table tr:nth-of-type(6) { background: var(--light-color-6); }
|
||||
table.checkbox_table tr:nth-of-type(6) td:nth-of-type(2) { background: var(--title-color-6); }
|
||||
|
||||
table.checkbox_table tr:nth-of-type(7) { background: var(--light-color-7); }
|
||||
table.checkbox_table tr:nth-of-type(7) td:nth-of-type(2) { background: var(--title-color-7); }
|
||||
|
||||
table.checkbox_table tr:nth-of-type(8) { background: var(--light-color-8); }
|
||||
table.checkbox_table tr:nth-of-type(8) td:nth-of-type(2) { background: var(--title-color-8); }
|
||||
|
||||
|
||||
/* Main Table */
|
||||
|
||||
|
||||
table.disassembly_table {
|
||||
border: solid grey;
|
||||
border-width:0px 0px 1px 0px;
|
||||
}
|
||||
|
||||
table.disassembly_table td, table.disassembly_table th {
|
||||
padding: 2px 4px;
|
||||
border: solid grey;
|
||||
border-width:0px 1px 0px 1px;
|
||||
}
|
||||
|
||||
|
||||
table.disassembly_table th.left_column,
|
||||
table.disassembly_table th.label_column,
|
||||
table.disassembly_table th.decimal_column {
|
||||
position: absolute;
|
||||
border: 1px solid #000;
|
||||
border-radius: 2px;
|
||||
color: var(--main-background);
|
||||
background: var(--border-color);
|
||||
}
|
||||
|
||||
|
||||
table.disassembly_table th.left_column {
|
||||
left: 8px;
|
||||
z-index: 11;
|
||||
}
|
||||
|
||||
|
||||
th.left_column a {
|
||||
color: var(--main-background);
|
||||
}
|
||||
|
||||
th.left_column a:target {
|
||||
color: yellow;
|
||||
text-shadow: 0px 1px black;
|
||||
}
|
||||
|
||||
/*
|
||||
th.left_column a:target::before {
|
||||
content: "▹";
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
table.disassembly_table th.top_row {
|
||||
color: var(--main-background);
|
||||
border-width: 1px;
|
||||
}
|
||||
|
||||
table.disassembly_table tr { background: #f0f0f0; }
|
||||
table.disassembly_table tr:nth-child(even) { background: #ffffff; }
|
||||
|
||||
|
||||
/* Main Table: Multicolor */
|
||||
|
||||
table.disassembly_table th:nth-child(1 of .top_row) { background: var(--title-color-1); }
|
||||
table.disassembly_table th:nth-child(2 of .top_row) { background: var(--title-color-2); }
|
||||
table.disassembly_table th:nth-child(3 of .top_row) { background: var(--title-color-3); }
|
||||
table.disassembly_table th:nth-child(4 of .top_row) { background: var(--title-color-4); }
|
||||
table.disassembly_table th:nth-child(5 of .top_row) { background: var(--title-color-5); }
|
||||
table.disassembly_table th:nth-child(6 of .top_row) { background: var(--title-color-6); }
|
||||
table.disassembly_table th:nth-child(7 of .top_row) { background: var(--title-color-7); }
|
||||
table.disassembly_table th:nth-child(8 of .top_row) { background: var(--title-color-8); }
|
||||
|
||||
|
||||
table.disassembly_table tr td:nth-of-type(1) { background: var(--dark-color-1); }
|
||||
table.disassembly_table tr:nth-child(even) td:nth-of-type(1) { background: var(--light-color-1); }
|
||||
|
||||
table.disassembly_table tr td:nth-of-type(2) { background: var(--dark-color-2); }
|
||||
table.disassembly_table tr:nth-child(even) td:nth-of-type(2) { background: var(--light-color-2); }
|
||||
|
||||
table.disassembly_table tr td:nth-of-type(3) { background: var(--dark-color-3); }
|
||||
table.disassembly_table tr:nth-child(even) td:nth-of-type(3) { background: var(--light-color-3); }
|
||||
|
||||
table.disassembly_table tr td:nth-of-type(4) { background: var(--dark-color-4); }
|
||||
table.disassembly_table tr:nth-child(even) td:nth-of-type(4) { background: var(--light-color-4); }
|
||||
|
||||
table.disassembly_table tr td:nth-of-type(5) { background: var(--dark-color-5); }
|
||||
table.disassembly_table tr:nth-child(even) td:nth-of-type(5) { background: var(--light-color-5); }
|
||||
|
||||
table.disassembly_table tr td:nth-of-type(6) { background: var(--dark-color-6); }
|
||||
table.disassembly_table tr:nth-child(even) td:nth-of-type(6) { background: var(--light-color-6); }
|
||||
|
||||
table.disassembly_table tr td:nth-of-type(7) { background: var(--dark-color-7); }
|
||||
table.disassembly_table tr:nth-child(even) td:nth-of-type(7) { background: var(--light-color-7); }
|
||||
|
||||
table.disassembly_table tr td:nth-of-type(8) { background: var(--dark-color-8); }
|
||||
table.disassembly_table tr:nth-child(even) td:nth-of-type(8) { background: var(--light-color-8); }
|
||||
|
||||
Loading…
Reference in a new issue