gigatron/rom/Apps/Apple-1/Apple-1_v2.gcl
2025-01-28 19:17:01 +03:00

1637 lines
85 KiB
Plaintext

{-----------------------------------------------------------------------+
| |
| |
| Apple-1 simulator for Gigatron TTL microcomputer |
| |
| |
+-----------------------------------------------------------------------}
gcl0x
{
References:
Apple-1 Operation Manual:
http://apple1.chez.com/Apple1project/Docs/pdf/AppleI_Manual.pdf
Apple BASIC Users Manual -- October 1976:
https://archive.org/details/apple1_basic_manual
A Number Game for the 6502 -- September 1976:
https://www.applefritter.com/files/Apple1WozDrDobbsMastermind.pdf
Using The Woz Monitor:
https://www.sbprojects.net/projects/apple1/wozmon.php
Original MOS6502 source code for WozMon:
https://github.com/jefftranter/6502/tree/master/asm/wozmon
https://www.sbprojects.com/projects/apple1/wozmon.txt
Eric Smit's disassembly of A1 BASIC:
http://www.brouhaha.com/~eric/retrocomputing/apple/apple1/basic/
Online Apple 1 Emulator (Hit [RESET] to enter WozMon):
https://www.scullinsteel.com/apple1/
Jeff Jetton's 15-puzzle for the Apple-1
https://www.applefritter.com/content/my-first-apple-i-program-15-puzzle
Zero page usage:
$00-$2f (Gigatron)
$30-$33 vIRQ (system)
$34-$3b WozMon, Mini-assembler
$3c-$3f vIRQ (application)
$40-$4c Mini-assembler, Integer BASIC
$4d-$79 Integer BASIC
$7a-$7f _i _j _p for PIA emulation
$80 (Gigatron)
$81-$e9 Integer BASIC
$e0-$ff Stack
Memory map, with reduced (and split) screen memory:
+--------------------------+
|0000-00FF ZEROPAGE+STACK|
|0100-01FF VIDEO+SYSTEM |
|0200-0FFF RAM |
|0200-027F KEYBD BUFFER |
|0C8A-0FDD MINI-ASSEMBLER|
|1060-5DFF SCREEN | 78 scanlines = 11*7+1
|5E00-5FFF PIA EMULATION |
|E000-EFFF A1 BASIC | alias 6000-6FFF -> A1 BASIC
|F060-FEFF SCREEN | alias 7060-7EFF -> 15 scanlines = 2*7+1
|FF00-FFFF APPLE-1 ROM |
| |
|300R MASTERMIND |
|400R 15-PUZZLE |
|EEER MINI-ASSEMBLER |
|C100R MENU |
|E000R INTEGER BASIC |
|E2B3R BASIC WARM START|
+--------------------------+
}
_p=$7a {2 bytes}
_i=$7c {2 bytes}
_j=$7e {2 bytes}
_cursorTimer=$3c
_tmpChar=$3c
_lastKey=$3d
_vCpuState=$3e
_PIA=$30 {Overlap with (otherwise useless) vIRQ-saved vPC}
{-----------------------------------------------------------------------+
| ROM type check |
+-----------------------------------------------------------------------}
*=$200
\romType, \romTypeValue_ROMv5- {Version check >= ROMv5, see Docs/GT1-files.txt}
[if<0 do _frameCount _vPCH: {https://forum.gigatron.io/viewtopic.php?f=4&t=130}
loop]
{-----------------------------------------------------------------------+
| Initialize |
+-----------------------------------------------------------------------}
{ This code runs once and is then reused as the input buffer for wozmon }
$00a0 _sysArgs0= {Clear last pixel row}
$7e60 _sysArgs2=
\SYS_SetMemory_v2_54 _sysFn= 54!!
$1ee _p= {videoTable+119*2} {Pointer, later used as Pos}
[do
$7e _p. {Shared empty pixel line at $7e60}
<_p, 2- <_p. if>=0loop]
$101 {videoTable+1} _p= $60 _p. {Use offsets 96..255 for pixel data, not 0..159}
{The reason is that it makes important}
{ addresses available: $c100, $d010..$d013}
$10ff _p= {Put cursor on right side. This causes an automatic
newline at the first invokation of _CharOut}
&_vIRQ_v5 _i=
&_vIRQ_ENTER _i: {Set vIRQ vector}
254 \frameCount. {First interrupt after at least one full frame}
&_Apple1 _vLR= {Prepare transfer to main loop}
&_PRE_RESET {Start address for 6502 program}
[ret] {Jump to Main (the brackets avoid the
automatic vLR patch by compilegcl.py)}
{-----------------------------------------------------------------------+
| |
| Mastermind |
| |
+-----------------------------------------------------------------------}
*=$300
{
WRITTEN BY STEVE WOZNIAK
PUBLISHED IN DOCTOR DOBBS JOURNAL SEPT 1976
"""MASTERMIND is a number guessing game. In this version the computer
generates a 5-digit, random number where the digits are limited to
0 through 7. The user attemtps to guess the number in the fewest
possible tries. After each guess the computer informs the user as
to how many digits were correct (contained in the random number)
and in the correct position by printing `+' signs, and how many
digits are correct and in the wrong position with `-' signs. The
user is not informed as to exactly which digit positions the `+'
and the `-' signs correspond. A skilled player can usually win in
6 or 7 tries."""
https://www.applefritter.com/files/Apple1WozDrDobbsMastermind.pdf
}
_TRIES=$E2 {[Gigatron] Was: $F2}
_RNDL=$E3 {[Gigatron] Was: $F3}
_RNDH=$E4 {[Gigatron] Was: $F4}
_RND2L=$E5 {[Gigatron] Was: $F5}
_N=$E6 {[Gigatron] Was: $F6}
_N_minus1=$E5
_N_plus5=$EB
_GUESS=$EB {[Gigatron] Was: $FB}
_GUESS_plus4=$EF
_GUESS_plus5=$F0
_MSTMIND=* #_LDXIM_ #$24 {[Gigatron] Include help}
_MSGLP=* #_LDAAX_ ##_MSG_minus1
#_JSR_ ##_ECHO {PRINT 'READY?'}
#_DEX_
#_BNE_ #@_MSGLP
#_STXZ_ #_TRIES {SET TRIES TO ZERO.}
_RNDLP=* #_INCZ_ #_RNDL
#_BNE_ #@_RND2 {FORM 2-BYTE RANDOM NUMBER}
#_INCZ_ #_RNDH {UNTIL KET DOWN.}
_RND2=* #_LDA_ ##_KBDCR
#_BPL_ #@_RNDLP
#_JSR_ ##_CHARIN {CLEAR STROBE.}
_NXTRY=* { #_SEC_ }
{ #_SED_ }
{ #_TXA_ }
{ #_ADCZ_ #_TRIES } {ADD 1 TO TRIES IN DECIMAL MODE}
{ #_STAZ_ #_TRIES }
{ #_CLD_ }
{ vvvvvvvvvvvvvvvvvvvvvvvvvvvvv BCD increment without SED by Michael T. Barry }
#_INCZ_ #_TRIES
#_LDAZ_ #_TRIES
#_ANDIM_ #$F
#_CMPIM_ #10
#_BCS_ #@_NXTRY
{ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ }
_NXTLIN=* #_JSR_ ##_CRLF
#_LDAZ_ #_TRIES {OUTPUT CRLF AND TRIES (IN BCD)}
#_JSR_ ##_PRBYTE
#_LDAIM_ #$A0 {OUTPUT BLANK.}
#_TAY_
#_JSR_ ##_ECHO
#_LDAZ_ #_RNDL
#_STAZ_ #_RND2L
#_LDAZ_ #_RNDH
#_LDXIM_ #$5 {SET ARRAY N TO 5 DIGITS OF}
_DIGEN=* #_STYZX_ #_N_minus1 {RANDOM NUMBER. DIGITS ARE}
#_LDYIM_ #$3 {0 THROUGH 7.}
_BITGEN=* #_LSRA_
#_ROLZ_ #_RND2L
#_ROLZX_ #_N_minus1
#_DEY_
#_BNE_ #@_BITGEN
#_DEX_
#_BNE_ #@_DIGEN
_RDKEY=* #_JSR_ ##_CHARIN
#_JSR_ ##_ECHO
#_EORIM_ #$B0 {CONVERTS DIGITS TO TRUE VALUE.}
#_CMPIM_ #$8 {IF NOT 0 TO 7 THEN REPEAT LINE}
#_BCS_ #@_NXTLIN {WITH SAME TRIES VALUE.}
#_STAZX_ #_GUESS_plus4 {SAVE USER DIGIT.}
#_DEX_
#_CPXIM_ #$FB {DONE 5 DIGITS?}
#_BNE_ #@_RDKEY
#_LDYIM_ #$FB {WIN COUNT (FOR 5 MATCHES).}
#_LDAIM_ #$A0 {PRINT BLANK.}
_PLUS1=* #_JSR_ ##_ECHO
_PLUS2=* #_LDAZX_ #_GUESS_plus5 {DOES GUESS MATCH RANDOM NUMBER}
#_CMPZX_ #_N_plus5 {FOR THIS DIGIT POSITION?}
#_BNE_ #@_PLUS3 {NO, TRY NEXT POSITION}
#_STYZX_ #_N_plus5 {SET DIG OF RAND NUMBER TO $FB}
#_LDAIM_ #$AB {-$FF SO NO 'MINUS' MATCH.}
#_STAZX_ #_GUESS_plus5 {SET DIG OF GUESS TO $AB SO}
#_INY_ {* NO 'MINUS' MATCH.}
#_BNE_ #@_PLUS1 {INCR. WIN COUNTER AND LOOP.}
#_LDXIM_ #$2D {IF WIN, OUTPUT WIN MESSAGE [Gigatron] Include help}
#_BNE_ #@_MSGLP {* AND BEGIN NEW GAME.}
_PLUS3=* #_INX_ {* NEXT DIGIT OF 'PLUS' SCAN.}
#_BNE_ #@_PLUS2
#_LDYIM_ #$FB
_MINUS1=* #_LDXZY_ #_GUESS_plus5 {GET DIGIT OF USER GUESS.}
#_TXA_
#_LDXIM_ #$FB
_MINUS2=* #_CMPZX_ #_N_plus5 {COMP TO DIGIT OF RAND NUMBER.}
#_BNE_ #@_MINUS3 {NO MATCH.}
#_STYZX_ #_N_plus5 {SET RAND DIGIT TO $FB-$FF}
#_LDAIM_ #$AD {SUBSTITUTE $AD FOR GUESS DIGIT}
#_JSR_ ##_ECHO
_MINUS3=* #_INX_ {* NEXT RANDOM DIGIT.}
#_BNE_ #@_MINUS2 {* LOOP.}
#_INY_ {* NEXT USER DIGIT.}
#_BNE_ #@_MINUS1 { LOOP.}
#_BEQ_
_MSG_minus1=*
#@_NXTRY {UPDATE TRIES FOR NEXT LINE.}
_MSG=* #$BF {'?'}
#$D9 {'Y'}
#$C4 {'D'}
#$C1 {'A'}
#$C5 {'E'}
#$D2 {'R'}
#$8D {CR.}
#$8D {CR.}
#$B7 #$AD #$B0 #$A0 #$CD #$CF {'GUESS FIVE DIGITS FROM 0-7'}
#$D2 #$C6 #$A0 #$D3 #$D4 #$C9
#$C7 #$C9 #$C4 #$A0 #$C5 #$D6
#$C9 #$C6 #$A0 #$D3 #$D3 #$C5
#$D5 #$C7
#$8D {CR.}
#$8D {CR.}
#$CE {'N'}
#$C9 {'I'}
#$D7 {'W'}
#$A0 {BLANK}
#$D5 {'U'}
#$CF {'O'}
#$D9 {'Y'}
#$A0 {BLANK}
#$AB {'+'}
_CRLF=* #_LDAIM_ #$8D
#_JMP_ ##_ECHO
_CHARIN=* #_LDA_ ##_KBDCR {WAIT FOR STROBE}
#_BPL_ #@_CHARIN
#_LDA_ ##_KBD {READ KEY AND CLEAR STROBE.}
#_RTS_
{-----------------------------------------------------------------------+
| |
| 15-Puzzle by Jeff Jetton |
| |
+-----------------------------------------------------------------------}
{ v v v v v v v v v v v v Insert 15-PUZZLE image here v v v v v v v v v v v v }
{ Generated by: cd 15puz && ./make.sh }
*=$400
#$d8 #$a2 #$ff #$9a #$a9 #$2a #$85 #$5a #$20 #$55 #$05 #$a9 #$8b #$85 #$58 #$a9
#$06 #$85 #$59 #$20 #$ad #$04 #$20 #$cb #$04 #$d0 #$0e #$a9 #$be #$85 #$58 #$a9
#$06 #$85 #$59 #$20 #$ad #$04 #$20 #$e8 #$04 #$20 #$1f #$06 #$20 #$6a #$05 #$20
#$e8 #$04 #$20 #$a8 #$04 #$20 #$09 #$05 #$20 #$27 #$05 #$20 #$bb #$04 #$c9 #$51
#$d0 #$03 #$4c #$9a #$04 #$20 #$9e #$05 #$a5 #$51 #$c9 #$10 #$d0 #$0a #$c6 #$5d
#$f0 #$b6 #$20 #$38 #$05 #$4c #$3b #$04 #$20 #$e8 #$04 #$20 #$a8 #$04 #$20 #$0c
#$06 #$f0 #$03 #$4c #$35 #$04 #$20 #$43 #$05 #$a9 #$8e #$85 #$58 #$a9 #$07 #$85
#$59 #$20 #$ad #$04 #$a5 #$55 #$20 #$ef #$ff #$a9 #$a3 #$85 #$58 #$a9 #$07 #$85
#$59 #$20 #$ad #$04 #$20 #$27 #$05 #$a9 #$bb #$85 #$58 #$a9 #$07 #$85 #$59 #$20
#$ad #$04 #$20 #$cb #$04 #$d0 #$03 #$4c #$29 #$04 #$a9 #$d0 #$85 #$58 #$a9 #$07
#$85 #$59 #$20 #$ad #$04 #$4c #$00 #$c1 #$a9 #$0d #$4c #$ef #$ff #$a0 #$00 #$b1
#$58 #$f0 #$07 #$20 #$ef #$ff #$c8 #$4c #$af #$04 #$60 #$20 #$de #$04 #$ad #$11
#$d0 #$10 #$f8 #$ad #$10 #$d0 #$29 #$7f #$4c #$ef #$ff #$20 #$bb #$04 #$c9 #$4e
#$f0 #$0a #$c9 #$59 #$f0 #$07 #$20 #$38 #$05 #$4c #$cb #$04 #$ba #$60 #$a5 #$5a
#$0a #$90 #$02 #$49 #$a9 #$85 #$5a #$60 #$20 #$a8 #$04 #$20 #$a8 #$04 #$a2 #$00
#$a0 #$04 #$b5 #$40 #$20 #$ef #$ff #$88 #$d0 #$05 #$a0 #$04 #$20 #$a8 #$04 #$e8
*=$500
#$e0 #$10 #$d0 #$ee #$a9 #$08 #$85 #$5d #$60 #$e6 #$56 #$a5 #$56 #$29 #$0f #$c9
#$0a #$b0 #$f6 #$a5 #$56 #$38 #$e9 #$a0 #$90 #$0c #$85 #$56 #$e6 #$57 #$a5 #$57
#$29 #$0f #$c9 #$0a #$b0 #$f6 #$60 #$a5 #$57 #$f0 #$03 #$20 #$dc #$ff #$a5 #$56
#$20 #$dc #$ff #$a9 #$20 #$4c #$ef #$ff #$a9 #$7a #$85 #$58 #$a9 #$07 #$85 #$59
#$4c #$ad #$04 #$a5 #$5a #$29 #$38 #$aa #$bd #$49 #$06 #$f0 #$07 #$20 #$ef #$ff
#$e8 #$4c #$48 #$05 #$60 #$a9 #$20 #$85 #$4f #$a9 #$0f #$85 #$52 #$a2 #$0f #$a0
#$4f #$98 #$9d #$3f #$00 #$88 #$ca #$d0 #$f8 #$60 #$a9 #$00 #$85 #$56 #$85 #$57
#$85 #$5c #$a6 #$55 #$bd #$13 #$06 #$85 #$5b #$20 #$de #$04 #$a5 #$5a #$29 #$0f
#$18 #$69 #$41 #$c5 #$5c #$f0 #$f2 #$20 #$9e #$05 #$a5 #$51 #$c9 #$10 #$f0 #$e9
#$a5 #$50 #$85 #$5c #$c6 #$5b #$d0 #$e1 #$20 #$0c #$06 #$f0 #$cd #$60 #$85 #$50
#$c9 #$20 #$f0 #$3c #$a2 #$00 #$b5 #$40 #$c5 #$50 #$f0 #$08 #$e8 #$e0 #$10 #$d0
#$f5 #$4c #$e0 #$05 #$86 #$51 #$8a #$29 #$0c #$85 #$53 #$a5 #$52 #$29 #$0c #$c5
#$53 #$d0 #$10 #$8a #$38 #$e5 #$52 #$10 #$05 #$a9 #$ff #$4c #$f2 #$05 #$a9 #$01
#$4c #$f2 #$05 #$8a #$29 #$03 #$85 #$53 #$a5 #$52 #$29 #$03 #$c5 #$53 #$f0 #$05
#$a2 #$10 #$86 #$51 #$60 #$8a #$38 #$e5 #$52 #$10 #$05 #$a9 #$fc #$4c #$f2 #$05
#$a9 #$04 #$85 #$54 #$a5 #$52 #$aa #$18 #$65 #$54 #$a8 #$b9 #$40 #$00 #$95 #$40
*=$600
#$a9 #$20 #$99 #$40 #$00 #$84 #$52 #$c4 #$51 #$d0 #$e9 #$60 #$a2 #$0f #$a9 #$4f
#$85 #$53 #$bd #$3f #$00 #$c5 #$53 #$d0 #$05 #$c6 #$53 #$ca #$d0 #$f4 #$60 #$a9
#$60 #$85 #$58 #$a9 #$07 #$85 #$59 #$20 #$ad #$04 #$20 #$bb #$04 #$85 #$55 #$c9
#$31 #$10 #$03 #$4c #$3e #$06 #$a9 #$35 #$38 #$e5 #$55 #$30 #$01 #$60 #$20 #$38
#$05 #$4c #$2a #$06 #$03 #$09 #$13 #$23 #$ff #$48 #$4f #$4f #$52 #$41 #$59 #$21
#$00 #$48 #$55 #$5a #$5a #$41 #$48 #$21 #$00 #$57 #$4f #$4f #$48 #$4f #$4f #$21
#$00 #$59 #$49 #$50 #$50 #$49 #$45 #$21 #$00 #$53 #$57 #$45 #$45 #$54 #$21 #$00
#$00 #$43 #$4f #$4f #$4c #$21 #$00 #$00 #$00 #$4e #$49 #$43 #$45 #$21 #$00 #$00
#$00 #$47 #$41 #$44 #$5a #$4f #$4f #$4b #$53 #$21 #$00 #$0d #$0d #$31 #$35 #$20
#$50 #$55 #$5a #$5a #$4c #$45 #$20 #$2d #$20 #$42 #$59 #$20 #$4a #$45 #$46 #$46
#$20 #$4a #$45 #$54 #$54 #$4f #$4e #$0d #$0d #$49 #$4e #$53 #$54 #$52 #$55 #$43
#$54 #$49 #$4f #$4e #$53 #$20 #$28 #$59 #$2f #$4e #$29 #$3f #$20 #$00 #$0d #$0d
#$54 #$59 #$50 #$45 #$20 #$41 #$20 #$4c #$45 #$54 #$54 #$45 #$52 #$20 #$4f #$4e
#$20 #$54 #$48 #$45 #$20 #$53 #$41 #$4d #$45 #$0d #$52 #$4f #$57 #$20 #$4f #$52
#$20 #$43 #$4f #$4c #$55 #$4d #$4e #$20 #$41 #$53 #$20 #$54 #$48 #$45 #$20 #$45
#$4d #$50 #$54 #$59 #$0d #$53 #$50 #$41 #$43 #$45 #$20 #$54 #$4f #$20 #$53 #$4c
*=$700
#$49 #$44 #$45 #$20 #$54 #$48 #$41 #$54 #$20 #$4c #$45 #$54 #$54 #$45 #$52 #$0d
#$28 #$41 #$4e #$44 #$20 #$41 #$4e #$59 #$20 #$42 #$45 #$54 #$57 #$45 #$45 #$4e
#$29 #$20 #$54 #$4f #$57 #$41 #$52 #$44 #$53 #$0d #$54 #$48 #$45 #$20 #$53 #$50
#$41 #$43 #$45 #$2e #$20 #$54 #$59 #$50 #$45 #$20 #$51 #$20 #$54 #$4f #$20 #$51
#$55 #$49 #$54 #$2e #$0d #$54 #$48 #$49 #$53 #$20 #$49 #$53 #$20 #$54 #$48 #$45
#$20 #$53 #$4f #$4c #$56 #$45 #$44 #$20 #$50 #$55 #$5a #$5a #$4c #$45 #$3a #$00
#$0d #$44 #$49 #$46 #$46 #$49 #$43 #$55 #$4c #$54 #$59 #$20 #$4c #$45 #$56 #$45
#$4c #$20 #$28 #$31 #$2d #$35 #$29 #$3f #$20 #$00 #$0d #$53 #$4f #$52 #$52 #$59
#$2e #$20 #$54 #$52 #$59 #$20 #$41 #$47 #$41 #$49 #$4e #$3a #$20 #$00 #$20 #$59
#$4f #$55 #$20 #$53 #$4f #$4c #$56 #$45 #$44 #$0d #$41 #$20 #$4c #$45 #$56 #$45
#$4c #$20 #$00 #$20 #$50 #$55 #$5a #$5a #$4c #$45 #$21 #$0d #$0d #$54 #$4f #$54
#$41 #$4c #$20 #$4d #$4f #$56 #$45 #$53 #$3a #$20 #$00 #$0d #$0d #$50 #$4c #$41
#$59 #$20 #$41 #$47 #$41 #$49 #$4e #$20 #$28 #$59 #$2f #$4e #$29 #$3f #$20 #$00
#$0d #$0d #$42 #$59 #$45 #$21 #$0d #$00
{ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ Insert 15-PUZZLE image here ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ }
{-----------------------------------------------------------------------+
| |
| Mini-assembler (and disassembler) |
| |
+-----------------------------------------------------------------------}
*=$be5
_USAGE1=* #_JSR_ ##_ECHO
#_INX_
_USAGE=* #_LDAAX_ ##_USAGE2 { WozMon has X=0 on G }
#_BNE_ #@_USAGE1
{$0BEE} #_JMP_ ##_CMDLINE { BEER. Courtesy Jac Goudsmit }
_USAGE2=* #$0D
`USAGE: #$0D
``!800:P
*=$c00 `HA````ASSEMBLE`1ST #$0D
``!`LDA`#1````ASSEMBLE`NEXT #$0D
``!800L```````DISASSEMBLE #$0D
``!L``````````NEXT`SCREEN #$0D
``!(RETURN)```EXIT #$0D
``BEER````````SKIP`USAGE #0
{
WRITTEN BY STEVE WOZNIAK & ALLEN BAUM
AND PUBLISHED IN DOCTOR DOBBS JOURNAL
SEPT 1976
;======================================
; ** ENHANCED WOZMON EXTENSION **
; MINI-ASSEMBLER AND DISASSEMBLER
; FOR THE APPLE 1 COMPUTER
; BASED ON THE CODE OF STEVE WOZNIAK
; AND ALLEN BAUM, 1976/1977
; MANUALLY AND LOVINGLY ADAPTED BY THE
; HAND OF MICHAEL T. BARRY, 2020
; MODIFICATIONS MADE IN 2020 ARE
; FREE TO USE WITH ATTRIBUTION
; <<< 6502 FOREVER!! >>>
;======================================
Merged and transcribed both sources to the
Apple-1 emulator for Gigatron v6502 by
Marcel van Kervinck 2019/2020
}
*=$c8a
_FORMAT=$40
_LENGTH=$41
_LMNEM=$42
_RMNEM=$43
_PCL=$44
_PCH=$45
_A1L=$46
_A1H=$47
_A2L=$48
_A2H=$49
_A4L=$4a
_A4H=$4b
_FMT=$4c
_LIST=* #_LDAIM_ #12 {was 20} {DISASSEM 20 INSTR}
_LIST1=* #_PHA_ {STACK LOOP COUNTER}
#_JSR_ ##_INSTDSP {DISASSEM ONE INSTR}
#_JSR_ ##_PCADJ {UPDATE VIRTUAL PC}
#_STAZ_ #_PCL
#_STYZ_ #_PCH
#_PLA_ {UPDATE LOOP COUNTER}
#_SEC_
#_SBCIM_ #1
#_BNE_ #@_LIST1 {LOOP FOR 20 INSTRS}
_CMDLINE=* #_JSR_ ##_GETLNZ {INPUT A FRESH LINE}
#_TXA_ {NULL INPUT?}
#_BNE_ #@_CMDLIN2
#_JMP_ ##_GETLINE {YES: BACK TO WOZMON}
_CMDLIN2=* #_LDYIM_ #0 {START AT 1ST CHAR}
#_JSR_ ##_GETNUM {PARSE OPTIONAL ADDR}
#_PHA_
#_TXA_ {EMPTY ADDR FIELD?}
#_BEQ_ #@_CMDLIN3 {YES: USE DEFAULT PC}
_A1PCLP=* #_LDAZX_ #_A1L {ASSUMES X=1}
#_STAZX_ #_PCL {COPY FROM A1 TO PC}
#_DEX_
#_BPL_ #@_A1PCLP
_CMDLIN3=* #_PLA_
#_CMPIM_ #$05 {'L' COMMAND?}
#_BEQ_ #@_LIST {YES: DISASSEMBLE}
#_CMPIM_ #$99 {' ' COMMAND?}
#_BEQ_ #@_ASSEM {YES: ASM AT CURR PC}
#_CMPIM_ #$93 {':' COMMAND?}
#_BNE_ #@_FORM8A {NO: ERROR}
_ASSEM=* #_LDAIM_ #3 {# OF CHARS IN MNEM}
#_STAZ_ #_A1H
_NXTMN=* #_JSR_ ##_GETNSP {GET A MNEM CHAR}
_NXTM=* #_ASLA_
#_SBCIM_ #$BE {SUBTRACT OFFSET}
#_CMPZ_ #$C2 {LEGAL CHAR?}
#_BCC_ #@_FORM8A {NO}
#_ASLA_ {COMPRESS/LT-JUSTIFY}
#_ASLA_
#_LDXIM_ #4
_NXTM2=* #_ASLA_ {DO 5 24-BIT SHIFTS}
#_ROLZ_ #_A4L
#_ROLZ_ #_A4H
#_DEX_
#_BPL_ #@_NXTM2
#_DECZ_ #_A1H {DONE WITH 3 CHARS?}
#_BEQ_ #@_NXTM2 {YES: ONE LAST SHIFT}
#_BPL_ #@_NXTMN {NO}
_FORM1=* #_LDXIM_ #5 {5 CHARS IN ADR MODE}
_FORM2=* #_JSR_ ##_GETNSP {GET 1ST CHR OF ADDR}
#_STYZ_ #_YSAV
#_CMPAX_ ##_CHAR1 {1ST CHR MATCH PATT?}
#_BNE_ #@_FORM3 {NO}
#_JSR_ ##_GETNSP {YES: GET 2ND CHAR}
#_CMPAX_ ##_CHAR2 {MATCHES 2ND HALF?}
#_BEQ_ #@_FORM5 {YES}
#_LDAAX_ ##_CHAR2 {NO: IS 2ND HALF 0?}
#_BEQ_ #@_FORM4 {YES}
#_CMPIM_ #$A4 {NO: 2ND HALF OPT?}
#_BEQ_ #@_FORM4 {YES}
*=$d00
#_LDYZ_ #_YSAV
_FORM3=* #_CLC_ {CLEAR BIT-NO MATCH}
_FORM4=* #_DEY_ {BACK UP 1 CHAR}
_FORM5=* #_ROLZ_ #_FMT {FORM FORMAT BYTE}
#_CPXIM_ #3 {TIME TO CHECK ADDR?}
#_BNE_ #@_FORM7 {NO}
#_JSR_ ##_GETNUM {YES: PARSE IT}
#_LDAZ_ #_A2H
#_BEQ_ #@_FORM6 {HIGH-ORDER BYTE 0?}
#_INX_ {NO: INCR FOR 2-BYTE}
_FORM6=* #_STXZ_ #_L {STORE LENGTH}
#_LDXIM_ #3 {RELOAD FMT INDEX}
#_DEY_ {BACK UP 1 CHAR}
_FORM7=* #_STXZ_ #_A1H {SAVE INDEX}
#_DEX_ {DONE W/FMT CHECK?}
#_BPL_ #@_FORM2 {NO}
#_LDAZ_ #_FMT {YES: PUT LENGTH}
#_ASLA_ {IN LOW BITS}
#_ASLA_
#_ORAZ_ #_L
#_CMPIM_ #$20
#_BCS_ #@_FORM8
#_LDXZ_ #_L
#_BEQ_ #@_FORM8
#_ORAIM_ #$80
_FORM8=* #_STAZ_ #_FMT
#_STYZ_ #_YSAV
#_LDAAY_ ##_IN {GET NEXT NONBLANK}
#_CMPIM_ #$BB {";"} {START OF COMMENT?}
#_BEQ_ #@_TRYNEXT {YES}
#_CMPIM_ #$8D {CR?}
_FORM8A=* #_BNE_ #@_ERR2 {NO: ERROR}
_TRYNEXT=* #_LDAZ_ #_A1H {GET TRIAL OPCODE}
#_JSR_ ##_INSDS2 {GET FMT+LEN FOR IT}
#_TAX_
#_LDAAX_ ##_MNEMR {GET LOWER MNEM BYTE}
#_CMPZ_ #_A4L {MATCH?}
#_BNE_ #@_NEXTOP {NO: TRY NEXT OPCODE}
#_LDAAX_ ##_MNEML {GET UPPER MNEM BYTE}
#_CMPZ_ #_A4H {MATCH?}
#_BNE_ #@_NEXTOP {NO: TRY NEXT OPCODE}
#_LDAZ_ #_FMT
#_LDYZ_ #_FORMAT {GET TRIAL FORMAT}
#_CPYIM_ #$9D {IS IT RELATIVE?}
#_BEQ_ #@_REL {YES}
#_CMPZ_ #_FORMAT {SAME FORMAT?}
#_BEQ_ #@_FINDOP {YES}
_NEXTOP=* #_DECZ_ #_A1H {NO: TRY NEXT OPCODE}
#_BNE_ #@_TRYNEXT
#_INCZ_ #_FMT {NO MORE: TRY LEN=2}
#_DECZ_ #_L {WAS L=2 ALREADY?}
#_BEQ_ #@_TRYNEXT {NO: KEEP TRYING}
_ERR1=* #_LDYZ_ #_YSAV {YES: UNREC. INST}
_ERR2=* #_TYA_
#_TAX_
#_JSR_ ##_CROUT
#_JSR_ ##_PRBL2 {PRINT '^' BELOW THE}
#_LDAIM_ #$DE {"^"} { LAST PARSED CHAR}
#_JSR_ ##_ECHO { TO SHOW ERR POSN}
#_JMP_ ##_CMDLINE {NEXT COMMAND LINE}
_REL=* #_SBCIM_ #$81 {YES: IS FMT COMPAT}
#_LSRA_ { W/RELATIVE MODE?}
#_BNE_ #@_ERR1 {NO: ERROR OUT}
#_LDYZ_ #_A2H
#_LDXZ_ #_A2L {DOUBLE DECREMENT}
#_BNE_ #@_REL2
#_DEY_
_REL2=* #_DEX_
#_TXA_
#_CLC_
#_SBCZ_ #_PCL {CALC ADDR-PC-2}
#_STAZ_ #_A2L
#_BPL_ #@_REL3
#_INY_
_REL3=* #_TYA_
#_SBCZ_ #_PCH
#_BNE_ #@_ERR {ERROR IF TOO FAR}
_FINDOP=* #_LDYZ_ #_LENGTH
_FNDOP2=* #_LDAAY_ ##_A1H {MOVE INST TO (PC)}
#_STAIY_ #_PCL
#_DEY_
#_BPL_ #@_FNDOP2
#_LDAIM_ #1 {DISASSEMBLE RESULT}
#_JMP_ ##_LIST1 {BACK TO CMD LINE}
_INSDS1=* #_LDXZ_ #_PCL {PRINT PCL,H}
#_LDYZ_ #_PCH
#_JSR_ ##_CROUT
#_JSR_ ##_PRNTYX
#_LDYIM_ #0
#_LDAIM_ #$AD {"-"} {PRINT '-'}
#_JSR_ ##_ECHO
#_JSR_ ##_PRBLNK {PRINT 3 BLANKS}
#_LDAIX_ #_PCL {GET OPCODE}
_INSDS2=* #_TAY_
#_LSRA_ {EVEN/ODD TEST}
#_BCC_ #@_IEVEN
#_LSRA_ {* TEST BIT 1}
#_BCS_ #@_ERR {* XXXXXX11 INSTR. INVALID.}
#_CMPIM_ #$22
#_BEQ_ #@_ERR {* 10001001 INSTR. INVALID.}
#_ANDIM_ #$7 {MASK 3 BITS FOR ADDRESS MODE &}
#_ORAIM_ #$80 {* ADD INDEXING OFFSET.}
_IEVEN=* #_LSRA_ {* LSB INTO CARRY FOR}
#_TAX_ {* LEFT/RIGHT TEST BELOW.}
#_LDAAX_ ##_MODE1 {INDEX INTO ADDRESS MODE TABLE.}
#_BCS_ #@_RTMODE {IF CARRY SET USE LSD FOR}
#_LSRA_ {* PRINT FORMAT INDEX}
#_LSRA_
#_LSRA_ {* IF CARRY CLEAR USE MSD.}
#_LSRA_
_RTMODE=* #_ANDIM_ #$F {MASK FOR 4-BIT INDEX.}
#_BNE_ #@_GETFMT {$0 FOR INVALID OP CODES.}
_ERR=* #_LDYIM_ #$80 {SUBSTITUTE $80 FOR INVALID OP,}
#_LDAIM_ #$0 {SET PRINT FORMAT INDEX TO 0}
_GETFMT=* #_TAX_
#_LDAAX_ ##_MODE2 {INDEX INTO PRINT FORMAT TABLE.}
#_STAZ_ #_FORMAT {SAVE FOR ADDRESS FIELD FORMAT.}
#_ANDIM_ #$3 {MASK 2-BIT LENGTH. 0=1-BYTE}
#_STAZ_ #_LENGTH {* 1=2-BYTE, 2=3-BYTE.}
#_TYA_ {* OP CODE.}
#_ANDIM_ #$8F {MASK IT FOR 1XXX1010 TEST.}
#_TAX_ {SAVE IT.}
#_TYA_ {* OP CODE TO 'A' AGAIN.}
#_LDYIM_ #$3
#_CPXIM_ #$8A
#_BEQ_ #@_MNNDX3
_MNNDX1=* #_LSRA_
#_BCC_ #@_MNNDX3 {FORM INDEX INTO MNEMONIC TABLE.}
#_LSRA_
_MNNDX2=* #_LSRA_ {* 1XXX1010 -> 00101XXX}
#_ORAIM_ #$20 {* XXXYYY01 -> 00111XXX}
#_DEY_ {* XXXYYY10 -> 00110XXX}
#_BNE_ #@_MNNDX2 {* XXXYY100 -> 00100XXX}
#_INY_ {* XXXXX000 -> 000XXXXX}
_MNNDX3=* #_DEY_
#_BNE_ #@_MNNDX1
#_RTS_
_INSTDSP=* #_JSR_ ##_INSDS1 {GEN FMT, LEN BYTES}
*=$e00
#_PHA_ {* SAVE MNEMONIC TABLE INDEX.}
_PROP=* #_LDAIY_ #_PCL
#_JSR_ ##_PRBYTE
#_LDXIM_ #$1
_PROPBL=* #_JSR_ ##_PRBL2
#_CPYZ_ #_LENGTH {PRINT INSTR (1 TO 3 BYTES)}
#_INY_ {IN A 12 CHARACTYER FIELD.}
#_BCC_ #@_PROP
#_LDXIM_ #$3 {CHAR COUNT FOR MNEMONIC PRINT.}
#_CPYIM_ #$3
#_BCC_ #@_PROPBL
#_PLA_ {RECOVER MNEMONIC INDEX.}
#_TAY_
#_LDAAY_ ##_MNEML
#_STAZ_ #_LMNEM {FETCH 3-CHAR MNEMONIC}
#_LDAAY_ ##_MNEMR {* (PACKED IN TWO BYTES)}
#_STAZ_ #_RMNEM
_PRMN1=* #_LDAIM_ #$0
#_LDYIM_ #$5
_PRMN2=* #_ASLZ_ #_RMNEM
#_ROLZ_ #_LMNEM {SHIFT 5 BITS OF CHAR INTO 'A'.}
#_ROLA_ {* (CLEAR CARRY)}
#_DEY_
#_BNE_ #@_PRMN2
#_ADCIM_ #$BF {ADD '?' OFFSET.}
#_JSR_ ##_ECHO {OUTPUT A CHAR OR MNEMONIC}
#_DEX_
#_BNE_ #@_PRMN1
#_JSR_ ##_PRBLNK {OUTPUT 3 BLANKS.}
#_LDXIM_ #$6 {COUNT FOR 6 PRINT FORMAT BITS.}
_PRADR1=* #_CPXIM_ #$3
#_BNE_ #@_PRADR3 {IF X=3 THEN PRINT ADDRESS VAL.}
#_LDYZ_ #_LENGTH
#_BEQ_ #@_PRADR3 {NO PRINT IF LENGTH=0.}
_PRADR2=* #_LDAZ_ #_FORMAT
#_CMPIM_ #$E8 {HANDLE REL ADDRESSING MODE}
#_LDAIY_ #_PCL {SPECIAL (PRINT TARGET ADDR)}
#_BCS_ #@_RELADR {* (NOT DISPLACEMENT)}
#_JSR_ ##_PRBYTE {OUTPUT 1- OR 2- BYTE ADDRESS.}
#_DEY_ {MORE SIGNIFICANT BYTE FIRST.}
#_BNE_ #@_PRADR2
_PRADR3=* #_ASLZ_ #_FORMAT {TEST NEXT PRINT FORMAT BIT.}
#_BCC_ #@_PRADR4 {IF 0, DONT PRINT}
#_LDAAX_ ##_CHAR1_minus1 {CORRESPONDING CHAR.}
#_JSR_ ##_ECHO {OUTPUT 1 OR 2 CHARS.}
#_LDAAX_ ##_CHAR2_minus1 {* (IF CHAR FROM CHAR2 IS 0,}
#_BEQ_ #@_PRADR4 {* DON'T FRINT IT)}
#_JSR_ ##_ECHO
_PRADR4=* #_DEX_
#_BNE_ #@_PRADR1
#_RTS_ {*RETURN IF DONE 6 FORMAT BITS.}
_RELADR=* #_JSR_ ##_PCADJ3 {PCL,H + DISPL + 1 TO 'A','Y'.}
#_TAX_
#_INX_
#_BNE_ #@_PRNTYX {* +1 TO 'X','Y'.}
#_INY_
_PRNTYX=* #_TYA_
#_JSR_ ##_PRBYTE {PRINT TARGET ADDRESS OF BRANCH}
_PRNTX=* #_TXA_ {AND RETURN}
#_JMP_ ##_PRBYTE
_PRBLNK=* #_LDXIM_ #$1 {BLANK COUNT [Gigatron] Was: #$3}
_PRBL2=* #_LDAIM_ #$A0
_PRBL3=* #_JSR_ ##_ECHO {OUTPUT A BLANK}
#_DEX_
#_BNE_ #@_PRBL2 {LOOP UNTIL COUNT =0}
#_RTS_
_NOTACR=* #_CMPIM_ #$9B {ESC?}
#_BEQ_ #@_CANCEL {YES: START OVER}
#_JSR_ ##_ECHO {PRINT CHAR}
#_CMPIM_ #$DF {"_"}
#_BEQ_ #@_BCKSPC
#_INX_
#_BPL_ #@_NXTCHAR {128 CHARS MAX}
_CANCEL=* #_LDAIM_ #$DC {"\"}
#_JSR_ ##_ECHO
_GETLNZ=* #_JSR_ ##_CROUT {FRESH LINE}
#_LDAIM_ #$A1 {"!"} {PROMPT CHAR}
#_JSR_ ##_ECHO
#_LDXIM_ #1
_BCKSPC=* #_DEX_
#_BMI_ #@_GETLNZ
_NXTCHAR=* #_BIT_ ##_KBDCR {WAIT FOR KEY PRESS}
#_BPL_ #@_NXTCHAR {NO KEY YET}
#_LDA_ ##_KBD {LOAD CHAR}
#_STAAX_ ##_IN {STORE IN BUFFER}
#_CMPIM_ #$8D {CR?}
#_BNE_ #@_NOTACR {NO: KEEP GOING}
#_RTS_ {YES: X=BUFLEN}
_GETNSP=* #_LDAAY_ ##_IN
#_INY_
#_CMPIM_ #$A0 {" "} {SKIP OVER SPACES}
#_BEQ_ #@_GETNSP
#_RTS_
_CROUT=* #_LDAIM_ #$8D
#_JMP_ ##_ECHO
_GETNUM=* #_LDXIM_ #0 {CLEAR VALID # FLAG}
#_STXZ_ #_A2L {CLEAR A2}
#_STXZ_ #_A2H
#_BEQ_ #@_NXTCHR
_XDIG=* #_LDXIM_ #3
#_ASLA_ {GOT HEX DIGIT,}
#_ASLA_ { SHIFT INTO A2}
#_ASLA_
#_ASLA_
_NXTBIT=* #_ASLA_
#_ROLZ_ #_A2L
#_ROLZ_ #_A2H
#_DEX_ {LEAVE X=$FF IF DIG}
#_BPL_ #@_NXTBIT
_NXTBAS=* #_LDAZX_ #_A2H
#_STAZX_ #_A1H
_NXTBS2=* #_INX_
#_BEQ_ #@_NXTBAS
_NXTCHR=* #_LDAAY_ ##_IN {GET CHAR}
#_INY_ {ADVANCE INDEX}
#_EORIM_ #$B0
#_CMPIM_ #10 {DECIMAL DIGIT?}
#_BCC_ #@_XDIG {YES: ACCUMULATE}
#_ADCIM_ #$88
#_CMPIM_ #$FA {'A'-'F'}
#_BCS_ #@_XDIG {YES: ACCUMULATE}
#_RTS_ {NO: RETURN WITH}
{ X=0: NO NUMBER}
{ X=1: NUMBER}
_XMON=* {$0EEE} #_JMP_ ##_USAGE {[Gigatron] Easy to remember entry point}
_PCADJ=* #_LDAZ_ #_LENGTH {0=1-BYTE, 1=2-BYTE, 2=3-BYTE.}
#_SEC_
_PCADJ3=* #_LDYZ_ #_PCH
#_TAX_ {* TEST DISPL SIGN (FOR REL}
#_BPL_ #@_PCADJ4 {* BRANCH). EXTEND NEG}
#_DEY_ {* BY DECREMENTING PCH.}
_PCADJ4=* #_ADCZ_ #_PCL
#_BCC_ #@_RTS1 {PCL+LENGTH (OR DISPL) +1 TO A.}
#_INY_ {* CARRY INTO Y (PCH)}
_RTS1=* #_RTS_
*=$f00
_MODE1=* #$40 #$2 #$45 #$3
#$D0 #$8 #$40 #$9
#$30 {XXXXXXZ0 INSTRS..}
#$22
#$45 {* Z=0, LEFT HALF-BYTE}
#$33 {* Z=1, RIGHT HALF-BYTE}
#$D0 #$8 #$40 #$9
#$40 #$2 #$45 #$33
#$D0 #$8 #$40 #$9
#$40 #$2 #$45 #$B3
#$D0 #$8 #$40 #$9
#$0 #$22 #$44 #$33
#$D0 #$8C #$44 #$0
#$11 #$22 #$44 #$33
#$D0 #$8C #$44 #$9A
#$10 #$22 #$44 #$33
#$D0 #$8 #$40 #$9
#$10 #$22 #$44 #$33
#$D0 #$8 #$40 #$9
#$62
#$13 {YYXXXZ01 INSTRS.}
#$78
#$A9
_MODE2=* #$0 {ERR}
#$21 {IMM}
#$81 {Z-PAG}
#$82 {ABS}
#$0 {IMPL}
#$0 {ACC}
#$59 {(Z-PAG,X)}
#$4D {(Z-PAG),Y}
#$91 {Z-PAG,X}
#$92 {ABS,X}
#$86 {ABS,Y}
#$4A {(ABS)}
#$85 {Z-PAG,Y}
_CHAR1_minus1=* #$9D {REL}
_CHAR1=* #$AC {','}
#$A9 {')'}
#$AC {','}
#$A3 {'#'}
#$A8 {'('}
_CHAR2_minus1=* #$A4 {'$'}
_CHAR2=* #$D9 {'Y'}
#$0
#$D8 {'X'}
#$A4 {'$'}
#$A4 {'$'}
#$0
_MNEML=* #$1C #$8A #$1C #$23 {XXXXX000 INSTRS.}
#$5D #$8B #$1B #$A1
#$9D #$8A #$1D #$23
#$9D #$8B #$1D #$A1
#$0 #$29 #$19 #$AE
#$69 #$A8 #$19 #$23
#$24 #$53 #$1B #$23
#$24 #$53 #$19 #$A1
#$0 #$1A #$5B #$5B {XXXYY100 INSTRS.}
#$A5 #$69 #$24 #$24
#$AE #$AE #$A8 #$AD {1XXX1010 INSTRS.}
#$29 #$0 #$7C #$0
#$15 #$9C #$6D #$9C {XXXYYY10 INSTRS.}
#$A5 #$69 #$29 #$53
#$84 #$13 #$34 #$11 {XXXYYY01 INSTRS.}
#$A5 #$69 #$23 #$A0
_MNEMR=* #$D8 #$62 #$5A #$48 {XXXXX000 INSTRS}
#$26 #$62 #$94 #$88
#$54 #$44 #$C8 #$54
#$68 #$44 #$E8 #$94
#$0 #$B4 #$8 #$84
#$74 #$B4 #$28 #$6E
#$74 #$F4 #$CC #$4A
#$72 #$F2 #$A4 #$8A
#$0 #$AA #$A2 #$A2 {XXXYY100 INSTRS}
#$74 #$74 #$74 #$72
#$44 #$68 #$B2 #$32 {1XXX1010 INSTRS.}
#$B2 #$0 #$22 #$26
#$1A #$1A #$26 #$26 {XXXYYY10 INSTRS.}
#$72 #$72 #$88 #$C8
#$C4 #$CA #$26 #$48 {XXXYYY01 INSTRS.}
#$44 #$44 #$A2 #$C8
{-----------------------------------------------------------------------+
| vIRQ_ENTER |
+-----------------------------------------------------------------------}
*=$5e00
_vIRQ_ENTER=*
[
{-- Enter interrupt --}
push {Non-leaf function}
_vCpuState= {Save extra vIRQ state information}
{ needed if switching back to v6502}
{-- Handle KBD --}
&_lastKey, _serialRaw^ 255& {First trigger on key changes}
[if<>0
&_KBD _PIA= {Pointer to PIA register $D010}
&_serialRaw, &_lastKey. {"serialLast" isn't useful for this}
255^ [if<>0 255^ {But ignore key releases}
$60- [if>=0 $20-] $60+ {Map to upper case, delete becomes rubout}
10^ [if=0 7] 10^ {Map 10 CR to 13 LF}
26^ [if=0 %0=] 26^ {Attempt BRK on Ctrl-Z; May need retries}
127& 128- {Set bits 7..15}
_PIA: {Update KBD and KBDCR in one go}
]]
{-- Handle DSP --}
&_DSP _PIA= peek {Pointer to PIA register $D012 and fetch}
[if<>0 {Test DSP for non-zero value (instead of bit 7)}
<_tmpChar. {Keep copy for below}
128| &_CharOut! {Emit the character, ensure bit 7 is set}
\vSP, 2+ deek 66+ [if=0 {HACK! If the return address is $ffbe, then eat}
_p 2- _p=] { 2 pixels and let wozmon fit on a small screen}
0 _PIA. {Clear DSP}
&_KBD _PIA= peek {If last key press compares equal to the char}
[if<>0 _tmpChar^ 127&] { that was just emitted (or 0, for wozmon),}
[if=0 _PIA:] { then also clear KBDCR. This is NOT how the}
{ true PIA works, but it fools most programs...}
31 <_cursorTimer.] {Restart the cursor cycle. This prevents it}
{ from getting drawn within the next 10 frames.}
{-- Handle cursor --}
{
Flashing rate and duty cycle are given by the 555 bistable circuit.
From the the schematic:
R1 = 10K
R2 = 10K
C = 25 uF
Giving:
f = 1.44 / ((R1 + 2*R2) * C) = 1.92 Hz = 31.2 frames
T1 = 0.693 * ((R1 + R2) * C) = 346 ms = 20.8 frames
T2 = 0.693 * ( R2 * C) = 173 ms = 10.4 frames
Video taken from the Apple-1 on display at LCM+L:
https://www.youtube.com/watch?v=FtOCumsDtlE
(11 frames on, 5 frames off, taken at 30 fps)
}
<_cursorTimer, 1-
[if<0
$a0 &_CharOut! {` '}
_p 6- _p= {Go back}
30] {31 frames at 60 Hz}
<_cursorTimer.
20^ [if=0 {67% duty cycle}
$c0 &_CharOut! {`@'}
_p 6- _p=] {Go back}
{-- Return from interrupt --}
&_Break_minus2 _PIA= {Restore the vPC damage we did above}
pop
255 \frameCount. {New interrupt in next frame. Note: "255"}
{ *may* cause a race condition and crash!}
\vIRQ_Return &_vCpuState?? {vIRQ return sequence with extra state}
]
{-----------------------------------------------------------------------+
| Startup message |
+-----------------------------------------------------------------------}
_PRE_RESET=*
{Set visible pixel lines in video table}
#_CLC_
#_LDXIM_ #0
#_LDYIM_ #12
_L1=* #_LDAAY_ ##_ROWS
#_STYZ_ #_YSAV
#_LDYIM_ #7
_L2=* #_STAAX_ ##\videoTable
#_ADCIM_ #1
#_INX_
#_INX_
#_DEY_
#_BNE_ #@_L2
#_INX_
#_INX_
#_INX_
#_INX_
#_LDYZ_ #_YSAV
#_DEY_
#_BPL_ #@_L1
{Initialize terminal through "ACI"}
#_JMP_ ##_MENU
_ROWS=* { Page of each row's first pixel line, backwards }
#$77 #$70 #$56 #$4f #$48 #$41 #$3a #$33 #$2c #$25 #$1e #$17 #$10
_BREAK=* #_CLD_
#_CLI_
#_LDXIM_ #$F7
#_TXS_
#_JMP_ ##_ESCAPE
{-----------------------------------------------------------------------+
| Main vCPU loop |
+-----------------------------------------------------------------------}
*=$5f00
_Apple1=*
{
Main loop from the perspective of the Gigatron I/O system.
It is practically doing nothing, just starting v6502 sequences
through the designated SYS call, to transfer control from vCPU
to v6502. When the SYS call returns to vCPU mode (due to a
BRK instruction), fetch the 6502 IRQ vector and start again.
The only other vCPU code is the vertical blank interrupt that
emulates the PIA registers.
}
[do
_v6502_PC= {Reset v6502 PC}
\SYS_Run6502_v4_80 _sysFn=
_Break_minus2=* {To help our overly thrifty vIRQ handler}
80!! {Run 6502 code until BRK}
{_Break=*} {After v6502 BRK instruction, resume here}
$fffe deek {Fake 6502 IRQ}
loop]
{-----------------------------------------------------------------------+
| Character output with automatic scrolling |
+-----------------------------------------------------------------------}
_CharOut=*
[
{Minimalistic terminal output, with bit 7 set}
_i= {Temp park argument here}
6-- {Preserve v6502 state}
_sysArgs0 %0= {v6502_ADL v6502_ADH}
_sysArgs2 %2= {v6502_IR v6502_P}
_sysArgs4 %4= {v6502_Qz v6502_Qn}
\SYS_VDrawBits_134 _sysFn= {Prepare SYS calls}
$3f00 _sysArgs0= {White pen color and clear bitmask}
\sysArgs2. {Clear bitmask}
_i \sysArgs3. {Keep copy of character in sysArgs3}
$8d^ [if<>0 {Test for CR...}
<_p, 251- if>0 0] {...or line wrap}
[if=0
{-------------------------------------------------------------------+
| Newline |
+-------------------------------------------------------------------}
{ Clear cursor symbol }
_p _sysArgs4= {Set drawing position}
255& 251- [if<=0 -5] {Clear 5 or 1 slices depending on margin}
[do
134!! <_sysArgs4++ {Whipes out any `@'}
1+ if<0loop]
{ Find the top text row }
$61 <_p. {Go to start of line, nicely indent by 1 pixel}
$9f+ _i= {i==$100: start of the video table}
peek >_p. {Go to what is now still the top text row}
{ Clear the text row }
_p 2- _sysArgs4= {Set drawing position for clearing}
[do
$700 _sysArgs4+ peek {Preserve pixel on 8th line because of overlap}
1& \sysArgs2. { in 7 line text mode. Assume bit 0 differs.}
134!! {SYS call to draw 8 pixels vertically}
<_sysArgs4++ {Step 1 pixel right}
\sysArgs4, if<>0loop] {Loop until end of pixel line}
{ Scroll everything up by modifying the video indirection table }
[do
_i 18+ _j= {j looks 9 entries ahead of i}
peek \sysArgs2. {Swap scanlines}
_i, _j.
\sysArgs2, _i.
<_i++ <_i++ {Advance to next entry in video table}
<_i, 216^ if<>0loop] {Until all done}
{ The cleared text row has now bubbled down to the bottom }
]
\sysArgs3, $a0- {WozMon sends ASCII with bit 7 set}
[if>=0 {If printable}
{-------------------------------------------------------------------+
| DrawChar |
+-------------------------------------------------------------------}
{ Draw ASCII character (32..127) on screen in 5x8 pixels }
{ and advance cursor position }
64- [if>=0 32-] 14+ {Map ASCII 96..127 to 64..95}
[if<0 50+ _i= \font32up {ASCII 32..81}
else _i= \font82up] {ASCII 82..127}
_j= _i 2<< _i+ {Multiply char code by 5}
_j+ _j= {Add to page address to reach bitmap data}
_p _sysArgs4= {Screen position for character}
6+ _p= {Advance by 6 pixels}
5 [do _i= {Draw character as 5 vertical bit slices}
_j 0?? {Get bit slice as byte from ROM table}
$fe& \sysArgs2. {Clear bottom pixel}
$700 _sysArgs4+ peek {Preserve pixel on 8th line because of overlap}
[if<>0 <\sysArgs2++] { in 7 line text mode. Assumes background is 0.}
134!! {SYS call to draw 8 pixels vertically}
<_j++ <_sysArgs4++ {Advance to next byte}
_i 1- if>0loop] {Looping}
]
%0 _sysArgs0=
%2 _sysArgs2=
%4 _sysArgs4=
6++ ret
]
{-----------------------------------------------------------------------+
| Apple-1 Cassette Interface |
+-----------------------------------------------------------------------}
*=$c100
#_LDAIM_ #$aa {`*' for authenticity}
#_JSR_ ##_ECHO
_MENU=*
#_LDX_ ##_MSG1 {Print welcome message part 1}
_L3=* #_LDAAX_ ##_MSG1
#_JSR_ ##_ECHO
#_DEX_
#_BNE_ #@_L3
#_LDX_ ##_MSG2 {Print welcome message part 2}
_L4=* #_LDAAX_ ##_MSG2
#_JSR_ ##_ECHO
#_DEX_
#_BNE_ #@_L4
_L5=* #_BIT_ ##_DSP {Wait for processing of last char}
#_BMI_ #@_L5
#_JMP_ ##_RESET
_MSG2=* #@_MSG2_END
{ 'CTL-Z WOZMON' }
#$8d #$ce #$cf #$cd #$da #$cf #$d7 #$a0
#$da #$ad #$cc #$d4 #$c3
{ 'E2B3R BASIC WARM START\r' }
#$8d #$d4 #$d2 #$c1 #$d4 #$d3 #$a0 #$cd
#$d2 #$c1 #$d7 #$a0 #$c3 #$c9 #$d3 #$c1
#$c2 #$a0 #$d2 #$b3 #$c2 #$b2 #$c5
{ 'INTEGER BASIC\r' }
#$8d #$c3 #$c9 #$d3 #$c1 #$c2 #$a0 #$d2
#$c5 #$c7 #$c5 #$d4 #$ce #$c9
_MSG2_END=*
*=$c200
_MSG1=* #@_MSG1_END
{ 'E000R ' }
#$a0 #$d2 #$b0 #$b0 #$b0 #$c5
{ 'C100R MENU\r' }
#$8d #$d5 #$ce #$c5 #$cd #$a0 #$d2 #$b0
#$b0 #$b1 #$c3
{ 'EEER MINI-ASSEMBLER\r' }
#$8d #$d2 #$c5 #$cc #$c2 #$cd #$c5 #$d3
#$d3 #$c1 #$ad #$c9 #$ce #$c9 #$cd #$a0
#$a0 #$d2 #$c5 #$c5 #$c5
{ '400R 15-PUZZLE\r' }
#$8d #$c5 #$cc #$da #$da #$d5 #$d0 #$ad
#$b5 #$b1 #$a0 #$a0 #$d2 #$b0 #$b0 #$b4
{ '300R MASTERMIND\r'}
#$8d #$c4 #$ce #$c9 #$cd #$d2 #$c5 #$d4
#$d3 #$c1 #$cd #$a0 #$a0 #$d2 #$b0 #$b0
#$b3
{ 'APPLE-1 ON TTL\r\r' }
#$8d #$8d #$cc #$d4 #$d4 #$a0 #$ce #$cf
#$a0 #$b1 #$ad #$c5 #$cc #$d0 #$d0 #$c1
{ '\r' ... }
#$8d #$8d #$8d
_MSG1_END=*
{
Create message bytes in Python with:
s = 'Message text'
' '.join('#$%02x'%(ord(c)+128) for c in reversed(s))
}
{-----------------------------------------------------------------------+
| PIA init |
+-----------------------------------------------------------------------}
*=$d010 #0 {KBD}
#0 {KBDCR}
#0 {DSP}
#0 {DSPCR}
{-----------------------------------------------------------------------+
| A1 BASIC |
+-----------------------------------------------------------------------}
{ v v v v v v v v v v v v Insert BASIC image here v v v v v v v v v v v v }
{ Generated by: cd a1basic && ./make.sh }
*=$e000
#$4c #$b0 #$e2 #$ad #$11 #$d0 #$10 #$fb #$ad #$10 #$d0 #$60 #$8a #$29 #$20 #$f0
#$23 #$a9 #$a0 #$85 #$44 #$4c #$c9 #$e3 #$a9 #$20 #$c5 #$81 #$b0 #$0c #$a9 #$8d
#$a0 #$07 #$20 #$c9 #$e3 #$a9 #$a0 #$88 #$d0 #$f8 #$a0 #$00 #$b1 #$42 #$e6 #$42
#$d0 #$02 #$e6 #$43 #$60 #$20 #$15 #$e7 #$20 #$76 #$e5 #$a5 #$42 #$c5 #$46 #$a5
#$43 #$e5 #$47 #$b0 #$ef #$20 #$6d #$e0 #$4c #$3b #$e0 #$a5 #$ca #$85 #$42 #$a5
#$cb #$85 #$43 #$a5 #$4c #$85 #$46 #$a5 #$4d #$85 #$47 #$d0 #$de #$20 #$15 #$e7
#$20 #$6d #$e5 #$a5 #$44 #$85 #$42 #$a5 #$45 #$85 #$43 #$b0 #$c7 #$86 #$d8 #$a9
#$a0 #$85 #$82 #$20 #$2a #$e0 #$98 #$85 #$44 #$20 #$2a #$e0 #$aa #$20 #$2a #$e0
#$20 #$1b #$e5 #$20 #$18 #$e0 #$84 #$82 #$aa #$10 #$18 #$0a #$10 #$e9 #$a5 #$44
#$d0 #$03 #$20 #$11 #$e0 #$8a #$20 #$c9 #$e3 #$a9 #$25 #$20 #$1a #$e0 #$aa #$30
#$f5 #$85 #$44 #$c9 #$01 #$d0 #$05 #$a6 #$d8 #$4c #$cd #$e3 #$48 #$84 #$ce #$a2
#$ed #$86 #$cf #$c9 #$51 #$90 #$04 #$c6 #$cf #$e9 #$50 #$48 #$b1 #$ce #$aa #$88
#$b1 #$ce #$10 #$fa #$e0 #$c0 #$b0 #$04 #$e0 #$00 #$30 #$f2 #$aa #$68 #$e9 #$01
#$d0 #$e9 #$24 #$44 #$30 #$03 #$20 #$f8 #$ef #$b1 #$ce #$10 #$10 #$aa #$29 #$3f
#$85 #$44 #$18 #$69 #$a0 #$20 #$c9 #$e3 #$88 #$e0 #$c0 #$90 #$ec #$20 #$0c #$e0
#$68 #$c9 #$5d #$f0 #$a4 #$c9 #$28 #$d0 #$8a #$f0 #$9e #$20 #$18 #$e1 #$95 #$50
*=$e100
#$d5 #$88 #$90 #$11 #$a0 #$2b #$4c #$e0 #$e3 #$20 #$34 #$ee #$d5 #$50 #$90 #$f4
#$20 #$e4 #$ef #$95 #$88 #$4c #$23 #$e8 #$20 #$34 #$ee #$f0 #$e7 #$38 #$e9 #$01
#$60 #$20 #$18 #$e1 #$95 #$50 #$18 #$f5 #$88 #$4c #$02 #$e1 #$a0 #$14 #$d0 #$d6
#$20 #$18 #$e1 #$e8 #$b5 #$50 #$85 #$da #$65 #$ce #$48 #$a8 #$b5 #$88 #$85 #$db
#$65 #$cf #$48 #$c4 #$ca #$e5 #$cb #$b0 #$e3 #$a5 #$da #$69 #$fe #$85 #$da #$a9
#$ff #$a8 #$65 #$db #$85 #$db #$c8 #$b1 #$da #$d9 #$cc #$00 #$d0 #$0f #$98 #$f0
#$f5 #$68 #$91 #$da #$99 #$cc #$00 #$88 #$10 #$f7 #$e8 #$60 #$ea #$a0 #$80 #$d0
#$95 #$a9 #$00 #$20 #$0a #$e7 #$a0 #$02 #$94 #$88 #$20 #$0a #$e7 #$a9 #$bf #$20
#$c9 #$e3 #$a0 #$00 #$20 #$9e #$e2 #$94 #$88 #$ea #$ea #$ea #$b5 #$51 #$85 #$ce
#$b5 #$89 #$85 #$cf #$e8 #$e8 #$20 #$bc #$e1 #$b5 #$4e #$d5 #$86 #$b0 #$15 #$f6
#$4e #$a8 #$b1 #$ce #$b4 #$50 #$c4 #$44 #$90 #$04 #$a0 #$83 #$d0 #$c1 #$91 #$da
#$f6 #$50 #$90 #$e5 #$b4 #$50 #$8a #$91 #$da #$e8 #$e8 #$60 #$b5 #$51 #$85 #$da
#$38 #$e9 #$02 #$85 #$44 #$b5 #$89 #$85 #$db #$e9 #$00 #$85 #$45 #$a0 #$00 #$b1
#$44 #$18 #$e5 #$da #$85 #$44 #$60 #$b5 #$53 #$85 #$ce #$b5 #$8b #$85 #$cf #$b5
#$51 #$85 #$da #$b5 #$89 #$85 #$db #$e8 #$e8 #$e8 #$a0 #$00 #$94 #$88 #$94 #$a8
#$c8 #$94 #$50 #$b5 #$4d #$d5 #$85 #$08 #$48 #$b5 #$4f #$d5 #$87 #$90 #$07 #$68
*=$e200
#$28 #$b0 #$02 #$56 #$50 #$60 #$a8 #$b1 #$ce #$85 #$44 #$68 #$a8 #$28 #$b0 #$f3
#$b1 #$da #$c5 #$44 #$d0 #$ed #$f6 #$4f #$f6 #$4d #$b0 #$d7 #$20 #$d7 #$e1 #$4c
#$36 #$e7 #$20 #$54 #$e2 #$06 #$ce #$26 #$cf #$90 #$0d #$18 #$a5 #$46 #$65 #$da
#$85 #$46 #$a5 #$47 #$65 #$db #$85 #$47 #$88 #$f0 #$09 #$06 #$46 #$26 #$47 #$10
#$e4 #$4c #$7e #$e7 #$a5 #$46 #$20 #$08 #$e7 #$a5 #$47 #$95 #$a8 #$06 #$45 #$90
#$28 #$4c #$6f #$e7 #$a9 #$55 #$85 #$45 #$20 #$5b #$e2 #$a5 #$ce #$85 #$da #$a5
#$cf #$85 #$db #$20 #$15 #$e7 #$84 #$46 #$84 #$47 #$a5 #$cf #$10 #$09 #$ca #$06
#$45 #$20 #$6f #$e7 #$20 #$15 #$e7 #$a0 #$10 #$60 #$20 #$6c #$ee #$f0 #$c5 #$ff
#$c9 #$84 #$d0 #$02 #$46 #$78 #$c9 #$df #$f0 #$11 #$c9 #$9b #$f0 #$06 #$99 #$00
#$02 #$c8 #$10 #$0a #$a0 #$8b #$20 #$c4 #$e3 #$a0 #$01 #$88 #$30 #$f6 #$20 #$03
#$e0 #$ea #$ea #$20 #$c9 #$e3 #$c9 #$8d #$d0 #$d6 #$a9 #$df #$99 #$00 #$02 #$60
#$20 #$d3 #$ef #$20 #$cd #$e3 #$46 #$d9 #$a9 #$be #$20 #$c9 #$e3 #$a0 #$00 #$84
#$82 #$24 #$78 #$10 #$0c #$a6 #$76 #$a5 #$77 #$20 #$1b #$e5 #$a9 #$a0 #$20 #$c9
#$e3 #$a2 #$ff #$9a #$20 #$9e #$e2 #$84 #$e9 #$8a #$85 #$c8 #$a2 #$18 #$20 #$91
#$e4 #$a5 #$c8 #$69 #$00 #$85 #$de #$a9 #$00 #$aa #$69 #$02 #$85 #$df #$a1 #$de
#$29 #$f0 #$c9 #$b0 #$f0 #$03 #$4c #$83 #$e8 #$a0 #$02 #$b1 #$de #$99 #$cd #$00
*=$e300
#$88 #$d0 #$f8 #$20 #$8a #$e3 #$a5 #$e9 #$e5 #$c8 #$c9 #$04 #$f0 #$a8 #$91 #$de
#$a5 #$ca #$f1 #$de #$85 #$44 #$a5 #$cb #$e9 #$00 #$85 #$45 #$a5 #$44 #$c5 #$cc
#$a5 #$45 #$e5 #$cd #$90 #$45 #$a5 #$ca #$f1 #$de #$85 #$46 #$a5 #$cb #$e9 #$00
#$85 #$47 #$b1 #$ca #$91 #$46 #$e6 #$ca #$d0 #$02 #$e6 #$cb #$a5 #$42 #$c5 #$ca
#$a5 #$43 #$e5 #$cb #$b0 #$e0 #$b5 #$44 #$95 #$ca #$ca #$10 #$f9 #$b1 #$de #$a8
#$88 #$b1 #$de #$91 #$46 #$98 #$d0 #$f8 #$24 #$78 #$10 #$09 #$b5 #$77 #$75 #$75
#$95 #$77 #$e8 #$f0 #$f7 #$10 #$7e #$00 #$00 #$00 #$00 #$a0 #$14 #$d0 #$71 #$20
#$15 #$e7 #$a5 #$42 #$85 #$46 #$a5 #$43 #$85 #$47 #$20 #$75 #$e5 #$a5 #$42 #$85
#$44 #$a5 #$43 #$85 #$45 #$d0 #$0e #$20 #$15 #$e7 #$20 #$6d #$e5 #$a5 #$46 #$85
#$42 #$a5 #$47 #$85 #$43 #$a0 #$00 #$a5 #$ca #$c5 #$44 #$a5 #$cb #$e5 #$45 #$b0
#$16 #$a5 #$44 #$d0 #$02 #$c6 #$45 #$c6 #$44 #$a5 #$46 #$d0 #$02 #$c6 #$47 #$c6
#$46 #$b1 #$44 #$91 #$46 #$90 #$e0 #$a5 #$46 #$85 #$ca #$a5 #$47 #$85 #$cb #$60
#$20 #$c9 #$e3 #$c8 #$b9 #$00 #$eb #$30 #$f7 #$c9 #$8d #$d0 #$06 #$a9 #$00 #$85
#$81 #$a9 #$8d #$e6 #$81 #$4c #$ef #$ff #$ea #$ea #$ea #$ea #$ea #$ea #$a0 #$06
#$20 #$d3 #$ee #$24 #$d9 #$30 #$03 #$4c #$b6 #$e2 #$4c #$9a #$eb #$2a #$69 #$a0
#$dd #$00 #$02 #$d0 #$53 #$b1 #$86 #$0a #$30 #$06 #$88 #$b1 #$86 #$30 #$29 #$c8
*=$e400
#$86 #$c8 #$98 #$48 #$a2 #$00 #$a1 #$86 #$aa #$4a #$49 #$48 #$11 #$86 #$c9 #$c0
#$90 #$01 #$e8 #$c8 #$d0 #$f3 #$68 #$a8 #$8a #$4c #$c0 #$e4 #$e6 #$e9 #$a6 #$e9
#$f0 #$bc #$9d #$00 #$02 #$60 #$a6 #$c8 #$a9 #$a0 #$e8 #$dd #$00 #$02 #$b0 #$fa
#$b1 #$86 #$29 #$3f #$4a #$d0 #$b6 #$bd #$00 #$02 #$b0 #$06 #$69 #$3f #$c9 #$1a
#$90 #$6f #$69 #$4f #$c9 #$0a #$90 #$69 #$a6 #$85 #$c8 #$b1 #$86 #$29 #$e0 #$c9
#$20 #$f0 #$7a #$b5 #$b0 #$85 #$c8 #$b5 #$d1 #$85 #$e9 #$88 #$b1 #$86 #$0a #$10
#$fa #$88 #$b0 #$38 #$0a #$30 #$35 #$b4 #$58 #$84 #$87 #$b4 #$90 #$e8 #$10 #$da
#$f0 #$b3 #$c9 #$7e #$b0 #$22 #$ca #$10 #$04 #$a0 #$06 #$10 #$29 #$94 #$90 #$a4
#$87 #$94 #$58 #$a4 #$c8 #$94 #$b0 #$a4 #$e9 #$94 #$d1 #$29 #$1f #$a8 #$b9 #$20
#$ec #$0a #$a8 #$a9 #$76 #$2a #$85 #$87 #$d0 #$01 #$c8 #$c8 #$86 #$85 #$b1 #$86
#$30 #$84 #$d0 #$05 #$a0 #$0e #$4c #$e0 #$e3 #$c9 #$03 #$b0 #$c3 #$4a #$a6 #$c8
#$e8 #$bd #$00 #$02 #$90 #$04 #$c9 #$a2 #$f0 #$0a #$c9 #$df #$f0 #$06 #$86 #$c8
#$20 #$1c #$e4 #$c8 #$88 #$a6 #$85 #$b1 #$86 #$88 #$0a #$10 #$cf #$b4 #$58 #$84
#$87 #$b4 #$90 #$e8 #$b1 #$86 #$29 #$9f #$d0 #$ed #$85 #$72 #$85 #$73 #$98 #$48
#$86 #$85 #$b4 #$d0 #$84 #$c9 #$18 #$a9 #$0a #$85 #$79 #$a2 #$00 #$c8 #$b9 #$00
#$02 #$29 #$0f #$65 #$72 #$48 #$8a #$65 #$73 #$30 #$1c #$aa #$68 #$c6 #$79 #$d0
*=$e500
#$f2 #$85 #$72 #$86 #$73 #$c4 #$e9 #$d0 #$de #$a4 #$c9 #$c8 #$84 #$e9 #$20 #$1c
#$e4 #$68 #$a8 #$a5 #$73 #$b0 #$a9 #$a0 #$00 #$10 #$8b #$85 #$73 #$86 #$72 #$a2
#$04 #$86 #$c9 #$a9 #$b0 #$85 #$79 #$a5 #$72 #$dd #$63 #$e5 #$a5 #$73 #$fd #$68
#$e5 #$90 #$0d #$85 #$73 #$a5 #$72 #$fd #$63 #$e5 #$85 #$72 #$e6 #$79 #$d0 #$e7
#$a5 #$79 #$e8 #$ca #$f0 #$0e #$c9 #$b0 #$f0 #$02 #$85 #$c9 #$24 #$c9 #$30 #$04
#$a5 #$82 #$f0 #$0b #$20 #$c9 #$e3 #$24 #$78 #$10 #$04 #$99 #$00 #$02 #$c8 #$ca
#$10 #$c1 #$60 #$01 #$0a #$64 #$e8 #$10 #$00 #$00 #$00 #$03 #$27 #$a5 #$ca #$85
#$46 #$a5 #$cb #$85 #$47 #$e8 #$a5 #$47 #$85 #$45 #$a5 #$46 #$85 #$44 #$c5 #$4c
#$a5 #$45 #$e5 #$4d #$b0 #$26 #$a0 #$01 #$b1 #$44 #$e5 #$ce #$c8 #$b1 #$44 #$e5
#$cf #$b0 #$19 #$a0 #$00 #$a5 #$46 #$71 #$44 #$85 #$46 #$90 #$03 #$e6 #$47 #$18
#$c8 #$a5 #$ce #$f1 #$44 #$c8 #$a5 #$cf #$f1 #$44 #$b0 #$ca #$60 #$46 #$78 #$a5
#$4c #$85 #$ca #$a5 #$4d #$85 #$cb #$a5 #$4a #$85 #$cc #$a5 #$4b #$85 #$cd #$a9
#$00 #$85 #$83 #$85 #$84 #$85 #$86 #$a9 #$00 #$85 #$1d #$60 #$a5 #$d0 #$69 #$05
#$85 #$d2 #$a5 #$d1 #$69 #$00 #$85 #$d3 #$a5 #$d2 #$c5 #$ca #$a5 #$d3 #$e5 #$cb
#$90 #$03 #$4c #$6b #$e3 #$a5 #$ce #$91 #$d0 #$a5 #$cf #$c8 #$91 #$d0 #$a5 #$d2
#$c8 #$91 #$d0 #$a5 #$d3 #$c8 #$91 #$d0 #$a9 #$00 #$c8 #$91 #$d0 #$c8 #$91 #$d0
*=$e600
#$a5 #$d2 #$85 #$cc #$a5 #$d3 #$85 #$cd #$a5 #$d0 #$90 #$43 #$85 #$ce #$84 #$cf
#$20 #$ff #$e6 #$30 #$0e #$c9 #$40 #$f0 #$0a #$4c #$28 #$e6 #$06 #$c9 #$49 #$d0
#$07 #$a9 #$49 #$85 #$cf #$20 #$ff #$e6 #$a5 #$4b #$85 #$d1 #$a5 #$4a #$85 #$d0
#$c5 #$cc #$a5 #$d1 #$e5 #$cd #$b0 #$94 #$b1 #$d0 #$c8 #$c5 #$ce #$d0 #$06 #$b1
#$d0 #$c5 #$cf #$f0 #$0e #$c8 #$b1 #$d0 #$48 #$c8 #$b1 #$d0 #$85 #$d1 #$68 #$a0
#$00 #$f0 #$db #$a5 #$d0 #$69 #$03 #$20 #$0a #$e7 #$a5 #$d1 #$69 #$00 #$95 #$88
#$a5 #$cf #$c9 #$40 #$d0 #$1c #$88 #$98 #$20 #$0a #$e7 #$88 #$94 #$88 #$a0 #$03
#$f6 #$88 #$c8 #$b1 #$d0 #$30 #$f9 #$10 #$09 #$a9 #$00 #$85 #$d4 #$85 #$d5 #$a2
#$18 #$48 #$a0 #$00 #$b1 #$de #$10 #$18 #$0a #$30 #$81 #$20 #$ff #$e6 #$20 #$08
#$e7 #$20 #$ff #$e6 #$95 #$a8 #$24 #$d4 #$10 #$01 #$ca #$20 #$ff #$e6 #$b0 #$e6
#$c9 #$28 #$d0 #$1f #$a5 #$de #$20 #$0a #$e7 #$a5 #$df #$95 #$88 #$24 #$d4 #$30
#$0b #$a9 #$01 #$20 #$0a #$e7 #$a9 #$00 #$95 #$88 #$f6 #$88 #$20 #$ff #$e6 #$30
#$f9 #$b0 #$d3 #$24 #$d4 #$10 #$06 #$c9 #$04 #$b0 #$d0 #$46 #$d4 #$a8 #$85 #$d6
#$b9 #$98 #$e9 #$29 #$55 #$0a #$85 #$d7 #$68 #$a8 #$b9 #$98 #$e9 #$29 #$aa #$c5
#$d7 #$b0 #$09 #$98 #$48 #$20 #$ff #$e6 #$a5 #$d6 #$90 #$95 #$b9 #$10 #$ea #$85
#$ce #$b9 #$88 #$ea #$85 #$cf #$20 #$fc #$e6 #$4c #$d8 #$e6 #$6c #$ce #$00 #$e6
*=$e700
#$de #$d0 #$02 #$e6 #$df #$b1 #$de #$60 #$94 #$87 #$ca #$30 #$03 #$95 #$50 #$60
#$a0 #$66 #$4c #$e0 #$e3 #$a0 #$00 #$b5 #$50 #$85 #$ce #$b5 #$a8 #$85 #$cf #$b5
#$88 #$f0 #$0e #$85 #$cf #$b1 #$ce #$48 #$c8 #$b1 #$ce #$85 #$cf #$68 #$85 #$ce
#$88 #$e8 #$60 #$20 #$4a #$e7 #$20 #$15 #$e7 #$98 #$20 #$08 #$e7 #$95 #$a8 #$c5
#$ce #$d0 #$06 #$c5 #$cf #$d0 #$02 #$f6 #$50 #$60 #$20 #$82 #$e7 #$20 #$59 #$e7
#$20 #$15 #$e7 #$24 #$cf #$30 #$1b #$ca #$60 #$20 #$15 #$e7 #$a5 #$cf #$d0 #$04
#$a5 #$ce #$f0 #$f3 #$a9 #$ff #$20 #$08 #$e7 #$95 #$a8 #$24 #$cf #$30 #$e9 #$20
#$15 #$e7 #$98 #$38 #$e5 #$ce #$20 #$08 #$e7 #$98 #$e5 #$cf #$50 #$23 #$a0 #$00
#$10 #$90 #$20 #$6f #$e7 #$20 #$15 #$e7 #$a5 #$ce #$85 #$da #$a5 #$cf #$85 #$db
#$20 #$15 #$e7 #$18 #$a5 #$ce #$65 #$da #$20 #$08 #$e7 #$a5 #$cf #$65 #$db #$70
#$dd #$95 #$a8 #$60 #$20 #$15 #$e7 #$a4 #$ce #$f0 #$05 #$88 #$a5 #$cf #$f0 #$0c
#$60 #$a5 #$81 #$09 #$07 #$a8 #$c8 #$a9 #$a0 #$20 #$c9 #$e3 #$c4 #$81 #$b0 #$f7
#$60 #$20 #$b1 #$e7 #$20 #$15 #$e7 #$a5 #$cf #$10 #$0a #$a9 #$ad #$20 #$c9 #$e3
#$20 #$72 #$e7 #$50 #$ef #$88 #$84 #$d5 #$86 #$cf #$a6 #$ce #$20 #$1b #$e5 #$a6
#$cf #$60 #$20 #$15 #$e7 #$a5 #$ce #$85 #$76 #$a5 #$cf #$85 #$77 #$88 #$84 #$78
#$c8 #$a9 #$0a #$85 #$74 #$84 #$75 #$60 #$20 #$15 #$e7 #$a5 #$ce #$a4 #$cf #$10
*=$e800
#$f2 #$20 #$15 #$e7 #$b5 #$50 #$85 #$da #$b5 #$88 #$85 #$db #$a5 #$ce #$91 #$da
#$c8 #$a5 #$cf #$91 #$da #$e8 #$60 #$68 #$68 #$24 #$d5 #$10 #$05 #$20 #$cd #$e3
#$46 #$d5 #$60 #$a0 #$ff #$84 #$d7 #$60 #$20 #$cd #$ef #$f0 #$07 #$a9 #$25 #$85
#$d6 #$88 #$84 #$d4 #$e8 #$60 #$a5 #$ca #$a4 #$cb #$d0 #$5a #$a0 #$41 #$a5 #$84
#$c9 #$08 #$b0 #$5e #$a8 #$e6 #$84 #$a5 #$de #$99 #$00 #$11 #$a5 #$df #$99 #$08
#$11 #$a5 #$dc #$99 #$10 #$11 #$a5 #$dd #$99 #$18 #$11 #$20 #$15 #$e7 #$20 #$6d
#$e5 #$90 #$04 #$a0 #$37 #$d0 #$3b #$a5 #$44 #$a4 #$45 #$85 #$dc #$84 #$dd #$2c
#$11 #$d0 #$30 #$4f #$18 #$69 #$03 #$90 #$01 #$c8 #$a2 #$ff #$86 #$d9 #$9a #$85
#$de #$84 #$df #$20 #$79 #$e6 #$24 #$d9 #$10 #$49 #$18 #$a0 #$00 #$a5 #$dc #$71
#$dc #$a4 #$dd #$90 #$01 #$c8 #$c5 #$4c #$d0 #$d1 #$c4 #$4d #$d0 #$cd #$a0 #$34
#$46 #$d9 #$4c #$e0 #$e3 #$a0 #$4a #$a5 #$84 #$f0 #$f7 #$c6 #$84 #$a8 #$b9 #$0f
#$11 #$85 #$dc #$b9 #$17 #$11 #$85 #$dd #$be #$87 #$00 #$b9 #$07 #$11 #$a8 #$8a
#$4c #$7a #$e8 #$a0 #$63 #$20 #$c4 #$e3 #$a0 #$01 #$b1 #$dc #$aa #$c8 #$b1 #$dc
#$20 #$1b #$e5 #$4c #$b3 #$e2 #$c6 #$83 #$a0 #$5b #$a5 #$83 #$f0 #$c4 #$a8 #$b5
#$50 #$d9 #$ff #$11 #$d0 #$f0 #$b5 #$88 #$d9 #$07 #$12 #$d0 #$e9 #$b9 #$0f #$12
#$85 #$da #$b9 #$17 #$12 #$85 #$db #$20 #$15 #$e7 #$ca #$20 #$93 #$e7 #$20 #$01
*=$e900
#$e8 #$ca #$a4 #$83 #$b9 #$47 #$12 #$95 #$a7 #$b9 #$3f #$12 #$a0 #$00 #$20 #$08
#$e7 #$20 #$82 #$e7 #$20 #$59 #$e7 #$20 #$15 #$e7 #$a4 #$83 #$a5 #$ce #$f0 #$05
#$59 #$17 #$12 #$10 #$12 #$b9 #$1f #$12 #$85 #$dc #$b9 #$27 #$12 #$85 #$dd #$be
#$2f #$12 #$b9 #$37 #$12 #$d0 #$87 #$c6 #$83 #$60 #$a0 #$54 #$a5 #$83 #$c9 #$08
#$f0 #$9a #$e6 #$83 #$a8 #$b5 #$50 #$99 #$00 #$12 #$b5 #$88 #$99 #$08 #$12 #$60
#$20 #$15 #$e7 #$a4 #$83 #$a5 #$ce #$99 #$3f #$12 #$a5 #$cf #$99 #$47 #$12 #$a9
#$01 #$99 #$0f #$12 #$a9 #$00 #$99 #$17 #$12 #$a5 #$dc #$99 #$1f #$12 #$a5 #$dd
#$99 #$27 #$12 #$a5 #$de #$99 #$2f #$12 #$a5 #$df #$99 #$37 #$12 #$60 #$20 #$15
#$e7 #$a4 #$83 #$a5 #$ce #$99 #$0f #$12 #$a5 #$cf #$4c #$66 #$e9 #$00 #$00 #$00
#$00 #$00 #$00 #$00 #$00 #$00 #$00 #$00 #$00 #$00 #$00 #$ab #$03 #$03 #$03 #$03
#$03 #$03 #$03 #$03 #$03 #$03 #$03 #$03 #$03 #$03 #$3f #$3f #$c0 #$c0 #$3c #$3c
#$3c #$3c #$3c #$3c #$3c #$30 #$0f #$c0 #$cc #$ff #$55 #$00 #$ab #$ab #$03 #$03
#$ff #$ff #$55 #$ff #$ff #$55 #$cf #$cf #$cf #$cf #$cf #$ff #$55 #$c3 #$c3 #$c3
#$55 #$f0 #$f0 #$cf #$56 #$56 #$56 #$55 #$ff #$ff #$55 #$03 #$03 #$03 #$03 #$03
#$03 #$03 #$ff #$ff #$ff #$03 #$03 #$03 #$03 #$03 #$03 #$03 #$03 #$03 #$03 #$03
#$03 #$03 #$03 #$03 #$03 #$00 #$ab #$03 #$57 #$03 #$03 #$03 #$03 #$07 #$03 #$03
*=$ea00
#$03 #$03 #$03 #$03 #$03 #$03 #$03 #$03 #$03 #$03 #$aa #$ff #$ff #$ff #$ff #$ff
#$17 #$ff #$ff #$19 #$5d #$35 #$4b #$f2 #$ec #$87 #$6f #$ad #$b7 #$e2 #$f8 #$54
#$80 #$96 #$85 #$82 #$22 #$10 #$33 #$4a #$13 #$06 #$0b #$4a #$01 #$40 #$47 #$7a
#$00 #$ff #$23 #$09 #$5b #$16 #$b6 #$cb #$ff #$ff #$fb #$ff #$ff #$24 #$f6 #$4e
#$59 #$50 #$00 #$ff #$23 #$a3 #$6f #$36 #$23 #$d7 #$1c #$22 #$c2 #$ae #$ba #$23
#$ff #$ff #$21 #$30 #$1e #$03 #$c4 #$20 #$00 #$c1 #$ff #$ff #$ff #$a0 #$30 #$1e
#$a4 #$d3 #$b6 #$bc #$aa #$3a #$01 #$50 #$7e #$d8 #$d8 #$a5 #$3c #$ff #$16 #$5b
#$28 #$03 #$c4 #$1d #$00 #$0c #$4e #$00 #$3e #$00 #$a6 #$b0 #$00 #$bc #$c6 #$57
#$8c #$01 #$27 #$ff #$ff #$ff #$ff #$ff #$e8 #$ff #$ff #$e8 #$e0 #$e0 #$e0 #$ef
#$ef #$e3 #$e3 #$e5 #$e5 #$e7 #$e7 #$ee #$ef #$ef #$e7 #$e7 #$e2 #$ef #$e7 #$e7
#$ec #$ec #$ec #$e7 #$ec #$ec #$ec #$e2 #$00 #$ff #$e8 #$e1 #$e8 #$e8 #$ef #$eb
#$ff #$ff #$e0 #$ff #$ff #$ef #$ee #$ef #$e7 #$e7 #$00 #$ff #$e8 #$e7 #$e7 #$e7
#$e8 #$e1 #$e2 #$ee #$ee #$ee #$ee #$e8 #$ff #$ff #$e1 #$e1 #$ef #$ee #$e7 #$e8
#$ee #$e7 #$ff #$ff #$ff #$ee #$e1 #$ef #$e7 #$e8 #$ef #$ef #$eb #$e9 #$e8 #$e9
#$e9 #$e8 #$e8 #$e8 #$e8 #$ff #$e8 #$e8 #$e8 #$ee #$e7 #$e8 #$ef #$ef #$ee #$ef
#$ee #$ef #$ee #$ee #$ef #$ee #$ee #$ee #$e1 #$e8 #$e8 #$ff #$ff #$ff #$ff #$ff
*=$eb00
#$be #$b3 #$b2 #$b7 #$b6 #$37 #$d4 #$cf #$cf #$a0 #$cc #$cf #$ce #$47 #$d3 #$d9
#$ce #$d4 #$c1 #$58 #$cd #$c5 #$cd #$a0 #$c6 #$d5 #$cc #$4c #$d4 #$cf #$cf #$a0
#$cd #$c1 #$ce #$d9 #$a0 #$d0 #$c1 #$d2 #$c5 #$ce #$53 #$d3 #$d4 #$d2 #$c9 #$ce
#$47 #$ce #$cf #$a0 #$c5 #$ce #$44 #$c2 #$c1 #$c4 #$a0 #$c2 #$d2 #$c1 #$ce #$c3
#$48 #$be #$b8 #$a0 #$c7 #$cf #$d3 #$d5 #$c2 #$53 #$c2 #$c1 #$c4 #$a0 #$d2 #$c5
#$d4 #$d5 #$d2 #$4e #$be #$b8 #$a0 #$c6 #$cf #$d2 #$53 #$c2 #$c1 #$c4 #$a0 #$ce
#$c5 #$d8 #$54 #$d3 #$d4 #$cf #$d0 #$d0 #$c5 #$c4 #$a0 #$c1 #$d4 #$20 #$aa #$aa
#$aa #$20 #$a0 #$c5 #$d2 #$d2 #$0d #$be #$b2 #$b5 #$35 #$d2 #$c1 #$ce #$c7 #$45
#$c4 #$c9 #$4d #$d3 #$d4 #$d2 #$a0 #$cf #$d6 #$c6 #$4c #$dc #$0d #$d2 #$c5 #$d4
#$d9 #$d0 #$c5 #$a0 #$cc #$c9 #$ce #$c5 #$8d #$3f #$46 #$d9 #$90 #$03 #$4c #$c3
#$e8 #$a6 #$cf #$9a #$a6 #$ce #$a0 #$8d #$d0 #$02 #$a0 #$99 #$20 #$c4 #$e3 #$86
#$ce #$ba #$86 #$cf #$a0 #$fe #$84 #$d9 #$c8 #$84 #$c8 #$20 #$99 #$e2 #$84 #$e9
#$a2 #$18 #$a9 #$30 #$20 #$91 #$e4 #$e6 #$d9 #$a6 #$ce #$a4 #$c8 #$0a #$85 #$ce
#$c8 #$b9 #$00 #$02 #$c9 #$74 #$f0 #$d2 #$49 #$b0 #$c9 #$0a #$b0 #$f0 #$c8 #$c8
#$84 #$c8 #$b9 #$00 #$02 #$48 #$b9 #$ff #$01 #$a0 #$00 #$20 #$08 #$e7 #$68 #$95
#$a8 #$a5 #$ce #$c9 #$c7 #$d0 #$03 #$20 #$6f #$e7 #$4c #$01 #$e8 #$ff #$ff #$ff
*=$ec00
#$50 #$20 #$13 #$ec #$d0 #$15 #$20 #$0b #$ec #$d0 #$10 #$20 #$82 #$e7 #$20 #$6f
#$e7 #$50 #$03 #$20 #$82 #$e7 #$20 #$59 #$e7 #$56 #$50 #$4c #$36 #$e7 #$ff #$ff
#$c1 #$ff #$7f #$d1 #$cc #$c7 #$cf #$ce #$c5 #$9a #$98 #$8b #$96 #$95 #$93 #$bf
#$b2 #$32 #$2d #$2b #$bc #$b0 #$ac #$be #$35 #$8e #$61 #$ff #$ff #$ff #$dd #$fb
#$20 #$c9 #$ef #$15 #$4f #$10 #$05 #$20 #$c9 #$ef #$35 #$4f #$95 #$50 #$10 #$cb
#$4c #$c9 #$ef #$40 #$60 #$8d #$60 #$8b #$00 #$7e #$8c #$33 #$00 #$00 #$60 #$03
#$bf #$12 #$00 #$40 #$89 #$c9 #$47 #$9d #$17 #$68 #$9d #$0a #$00 #$40 #$60 #$8d
#$60 #$8b #$00 #$7e #$8c #$3c #$00 #$00 #$60 #$03 #$bf #$1b #$4b #$67 #$b4 #$a1
#$07 #$8c #$07 #$ae #$a9 #$ac #$a8 #$67 #$8c #$07 #$b4 #$af #$ac #$b0 #$67 #$9d
#$b2 #$af #$ac #$af #$a3 #$67 #$8c #$07 #$a5 #$ab #$af #$b0 #$f4 #$ae #$a9 #$b2
#$b0 #$7f #$0e #$27 #$b4 #$ae #$a9 #$b2 #$b0 #$7f #$0e #$28 #$b4 #$ae #$a9 #$b2
#$b0 #$64 #$07 #$a6 #$a9 #$67 #$af #$b4 #$af #$a7 #$78 #$b4 #$a5 #$ac #$78 #$7f
#$02 #$ad #$a5 #$b2 #$67 #$a2 #$b5 #$b3 #$af #$a7 #$ee #$b2 #$b5 #$b4 #$a5 #$b2
#$7e #$8c #$39 #$b4 #$b8 #$a5 #$ae #$67 #$b0 #$a5 #$b4 #$b3 #$27 #$af #$b4 #$07
#$9d #$19 #$b2 #$af #$a6 #$7f #$05 #$37 #$b4 #$b5 #$b0 #$ae #$a9 #$7f #$05 #$28
#$b4 #$b5 #$b0 #$ae #$a9 #$7f #$05 #$2a #$b4 #$b5 #$b0 #$ae #$a9 #$e4 #$ae #$a5
*=$ed00
#$00 #$ff #$ff #$47 #$a2 #$a1 #$b4 #$7f #$0d #$30 #$ad #$a9 #$a4 #$7f #$0d #$23
#$ad #$a9 #$a4 #$67 #$ac #$ac #$a1 #$a3 #$00 #$40 #$80 #$c0 #$c1 #$80 #$00 #$47
#$8c #$68 #$8c #$db #$67 #$9b #$68 #$9b #$50 #$8c #$63 #$8c #$7f #$01 #$51 #$07
#$88 #$29 #$84 #$80 #$c4 #$80 #$57 #$71 #$07 #$88 #$14 #$ed #$a5 #$ad #$af #$ac
#$ed #$a5 #$ad #$a9 #$a8 #$f2 #$af #$ac #$af #$a3 #$71 #$08 #$88 #$ae #$a5 #$ac
#$68 #$83 #$08 #$68 #$9d #$08 #$71 #$07 #$88 #$60 #$76 #$b4 #$af #$ae #$76 #$8d
#$76 #$8b #$51 #$07 #$88 #$19 #$b8 #$a4 #$ae #$b2 #$f2 #$b3 #$b5 #$f3 #$a2 #$a1
#$ee #$a7 #$b3 #$e4 #$ae #$b2 #$eb #$a5 #$a5 #$b0 #$51 #$07 #$88 #$39 #$81 #$c1
#$4f #$7f #$0f #$2f #$00 #$51 #$06 #$88 #$29 #$c2 #$0c #$82 #$57 #$8c #$6a #$8c
#$42 #$ae #$a5 #$a8 #$b4 #$60 #$ae #$a5 #$a8 #$b4 #$4f #$7e #$1e #$35 #$8c #$27
#$51 #$07 #$88 #$09 #$8b #$fe #$e4 #$af #$ad #$f2 #$af #$e4 #$ae #$a1 #$dc #$de
#$9c #$dd #$9c #$de #$dd #$9e #$c3 #$dd #$cf #$ca #$cd #$cb #$00 #$47 #$9d #$ad
#$a5 #$ad #$af #$ac #$76 #$9d #$ad #$a5 #$ad #$a9 #$a8 #$e6 #$a6 #$af #$60 #$8c
#$20 #$af #$b4 #$b5 #$a1 #$f2 #$ac #$a3 #$f2 #$a3 #$b3 #$60 #$8c #$20 #$ac #$a5
#$a4 #$ee #$b5 #$b2 #$60 #$ae #$b5 #$b2 #$f4 #$b3 #$a9 #$ac #$60 #$8c #$20 #$b4
#$b3 #$a9 #$ac #$7a #$7e #$9a #$22 #$20 #$00 #$60 #$03 #$bf #$60 #$03 #$bf #$1f
*=$ee00
#$20 #$b1 #$e7 #$e8 #$e8 #$b5 #$4f #$85 #$da #$b5 #$87 #$85 #$db #$b4 #$4e #$98
#$d5 #$86 #$b0 #$09 #$b1 #$da #$20 #$c9 #$e3 #$c8 #$4c #$0f #$ee #$a9 #$ff #$85
#$d5 #$60 #$e8 #$a9 #$00 #$95 #$88 #$95 #$a8 #$b5 #$87 #$38 #$f5 #$4f #$95 #$50
#$4c #$23 #$e8 #$ff #$20 #$15 #$e7 #$a5 #$cf #$d0 #$28 #$a5 #$ce #$60 #$20 #$34
#$ee #$a4 #$c8 #$c9 #$30 #$b0 #$21 #$c0 #$28 #$b0 #$1d #$60 #$ea #$ea #$20 #$34
#$ee #$60 #$ea #$8a #$a2 #$01 #$b4 #$ce #$94 #$4c #$b4 #$48 #$94 #$ca #$ca #$f0
#$f5 #$aa #$60 #$a0 #$77 #$4c #$e0 #$e3 #$a0 #$7b #$d0 #$f9 #$20 #$54 #$e2 #$a5
#$da #$d0 #$07 #$a5 #$db #$d0 #$03 #$4c #$7e #$e7 #$06 #$ce #$26 #$cf #$26 #$46
#$26 #$47 #$a5 #$46 #$c5 #$da #$a5 #$47 #$e5 #$db #$90 #$0a #$85 #$47 #$a5 #$46
#$e5 #$da #$85 #$46 #$e6 #$ce #$88 #$d0 #$e1 #$60 #$ff #$ff #$ff #$ff #$ff #$ff
#$20 #$15 #$e7 #$6c #$ce #$00 #$a5 #$4c #$d0 #$02 #$c6 #$4d #$c6 #$4c #$a5 #$48
#$d0 #$02 #$c6 #$49 #$c6 #$48 #$a0 #$00 #$b1 #$4c #$91 #$48 #$a5 #$ca #$c5 #$4c
#$a5 #$cb #$e5 #$4d #$90 #$e0 #$4c #$53 #$ee #$c9 #$28 #$b0 #$9b #$a8 #$a5 #$c8
#$60 #$ea #$ea #$98 #$aa #$a0 #$6e #$20 #$c4 #$e3 #$8a #$a8 #$20 #$c4 #$e3 #$a0
#$72 #$4c #$c4 #$e3 #$20 #$15 #$e7 #$06 #$ce #$26 #$cf #$30 #$fa #$b0 #$dc #$d0
#$04 #$c5 #$ce #$b0 #$d6 #$60 #$20 #$15 #$e7 #$b1 #$ce #$94 #$a7 #$4c #$08 #$e7
*=$ef00
#$20 #$34 #$ee #$a5 #$ce #$48 #$20 #$15 #$e7 #$68 #$91 #$ce #$60 #$ff #$ff #$ff
#$20 #$6c #$ee #$a5 #$ce #$85 #$46 #$a5 #$cf #$85 #$47 #$4c #$44 #$e2 #$20 #$e4
#$ee #$4c #$34 #$e1 #$20 #$e4 #$ee #$b4 #$88 #$b5 #$50 #$69 #$fe #$b0 #$01 #$88
#$85 #$da #$84 #$db #$18 #$65 #$ce #$95 #$50 #$98 #$65 #$cf #$95 #$88 #$a0 #$00
#$b5 #$50 #$d1 #$da #$c8 #$b5 #$88 #$f1 #$da #$b0 #$80 #$4c #$23 #$e8 #$20 #$15
#$e7 #$a5 #$4e #$20 #$08 #$e7 #$a5 #$4f #$d0 #$04 #$c5 #$4e #$69 #$00 #$29 #$7f
#$85 #$4f #$95 #$a8 #$a0 #$11 #$a5 #$4f #$0a #$18 #$69 #$40 #$0a #$26 #$4e #$26
#$4f #$88 #$d0 #$f2 #$a5 #$ce #$20 #$08 #$e7 #$a5 #$cf #$95 #$a8 #$4c #$7a #$e2
#$20 #$15 #$e7 #$a4 #$ce #$c4 #$4c #$a5 #$cf #$e5 #$4d #$90 #$1f #$84 #$48 #$a5
#$cf #$85 #$49 #$4c #$b6 #$ee #$20 #$15 #$e7 #$a4 #$ce #$c4 #$ca #$a5 #$cf #$e5
#$cb #$b0 #$09 #$84 #$4a #$a5 #$cf #$85 #$4b #$4c #$b7 #$e5 #$4c #$cb #$ee #$ea
#$ea #$ea #$ea #$20 #$c9 #$ef #$20 #$71 #$e1 #$4c #$bf #$ef #$20 #$03 #$ee #$a9
#$ff #$85 #$c8 #$a9 #$74 #$8d #$00 #$02 #$60 #$20 #$36 #$e7 #$e8 #$20 #$36 #$e7
#$b5 #$50 #$60 #$a9 #$00 #$85 #$4a #$85 #$4c #$a9 #$08 #$85 #$4b #$a9 #$10 #$85
#$4d #$4c #$ad #$e5 #$d5 #$88 #$d0 #$01 #$18 #$4c #$02 #$e1 #$20 #$b7 #$e5 #$4c
#$36 #$e8 #$20 #$b7 #$e5 #$4c #$5b #$e8 #$e0 #$80 #$d0 #$01 #$88 #$4c #$0c #$e0
{ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ Insert BASIC image here ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ }
{-----------------------------------------------------------------------+
| WozMon |
+-----------------------------------------------------------------------}
*=$ff00
{ Original ZP usage is 24.2B, but that's taken by Gigatron }
_XAML=$34 _XAML_minus1=$33
_XAMH=$35
_STL=$36 _STL_minus1=$35
_STH=$37
_L=$38 _L_minus1=$37
_H=$39
_YSAV=$3A
_MODE=$3B
{ Patches with respect to original are marked [Gigatron] }
_IN=$200
_KBD=$D010
_KBDCR=$D011
_DSP=$D012
_DSPCR=$D013
_RESET=* #_CLD_ {Clear decimal arithmetic mode. }
#_CLI_
#_LDYIM_ #$7F {Mask for DSP data direction register. }
#_STY_ ##_DSP
#_LDAIM_ #$A7 {KBD and DSP control register mask. }
#_STA_ ##_KBDCR
#_STA_ ##_DSPCR
_NOTCR=* #_CMPIM_ #$DF {"<-"? }
#_BEQ_ #@_BACKSPACE {Yes. }
#_CMPIM_ #$9B {ESC? }
#_BEQ_ #@_ESCAPE {Yes. }
#_INY_ {Advance text index. }
#_BPL_ #@_NEXTCHAR {Auto ESC if > 127. }
_ESCAPE=* #_LDAIM_ #$DC {"\". }
#_JSR_ ##_ECHO {Output it. }
_GETLINE=* #_LDAIM_ #$8D {CR. }
#_JSR_ ##_ECHO {Output it. }
#_LDYIM_ #$01 {Initiallize text index. }
_BACKSPACE=* #_DEY_ {Back up text index. }
#_BMI_ #@_GETLINE {Beyond start of line, reinitialize. }
_NEXTCHAR=* #_LDA_ ##_KBDCR {Key ready? }
#_BPL_ #@_NEXTCHAR {Loop until ready. }
#_LDA_ ##_KBD {Load character. B7 should be '1'. }
#_STAAY_ ##_IN {Add to text buffer. }
#_JSR_ ##_ECHO {Display character. }
#_CMPIM_ #$8D {CR? }
#_BNE_ #@_NOTCR {No. }
#_LDYIM_ #$FF {Reset text index. }
#_LDAIM_ #$00 {For XAM mode. }
#_TAX_ {0->X. }
_SETSTOR=* #_ASLA_ {Leaves $7B if setting STOR mode. }
_SETMODE=* #_STAZ_ #_MODE {$00 = XAM, $7B= STOR,$AE= BLOK XAM }
_BLSKIP=* #_INY_ {Advance text index. }
_NEXTITEM=* #_LDAAY_ ##_IN {Get character. }
#_CMPIM_ #$8D {CR? }
#_BEQ_ #@_GETLINE {Yes, done this line. }
#_CMPIM_ #$AE {"."? }
#_BCC_ #@_BLSKIP {Skip delimiter. }
#_BEQ_ #@_SETMODE {Yes, BLOCK XAM mode. }
#_CMPIM_ #$BA {":"? }
#_BEQ_ #@_SETSTOR {Yes, set STOR mode. }
#_CMPIM_ #$D2 {"R"? }
#_BEQ_ #@_RUN {Yes, run user program. }
#_STXZ_ #_L {$00->L. }
#_STXZ_ #_H { and H. }
#_STYZ_ #_YSAV {Save Y for comparison. }
_NEXTHEX=* #_LDAAY_ ##_IN {Get character for hex test. }
#_EORIM_ #$B0 {Map digits to $0-9. }
#_CMPIM_ #$0A {Digit? }
#_BCC_ #@_DIG {Yes. }
#_ADCIM_ #$88 {Map letter "A"-"F" to $FA-FF. }
#_CMPIM_ #$FA {Hex letter? }
#_BCC_ #@_NOTHEX {No, character not hex. }
_DIG=* #_ASLA_ { }
#_ASLA_ {Hex digit to MSD of A. }
#_ASLA_ { }
#_ASLA_ { }
#_LDXIM_ #$04 {Shift count. }
_HEXSHIFT=* #_ASLA_ {Hex digit left, MSB to carry. }
#_ROLZ_ #_L {Rotate into LSD. }
#_ROLZ_ #_H {Rotate into MSD's. }
#_DEX_ {Done 4 shifts? }
#_BNE_ #@_HEXSHIFT {No, loop. }
#_INY_ {Advance text index. }
#_BNE_ #@_NEXTHEX {Always taken. Check next character for hex.}
_NOTHEX=* #_CPYZ_ #_YSAV {Check if L, H empty (no hex digits). }
#_BEQ_ #@_ESCAPE {Yes, generate ESC sequence. }
#_BITZ_ #_MODE {Test MODE byte. }
#_BVC_ #@_NOTSTOR {B6 = 0 for STOR, 1 for XAM and BLOCK XAM}
#_LDAZ_ #_L {LSD's of hex data. }
#_STAIX_ #_STL {Store at current 'store index'. }
#_INCZ_ #_STL {Increment store index. }
#_BNE_ #@_NEXTITEM {Get next item. (no carry). }
#_INCZ_ #_STH {Add carry to 'store index' high order. }
_TONEXTITEM=* #_JMP_ ##_NEXTITEM {Get next command item. }
_RUN=* #_JMI_ ##_XAML {Run at current XAM index. }
_NOTSTOR=* #_BMI_ #@_XAMNEXT {B7 = 0 for XAM, 1 for BLOCK XAM. }
#_LDXIM_ #$02 {Byte count. }
_SETADR=* #_LDAZX_ #_L_minus1 {Copy hex data to }
#_STAZX_ #_STL_minus1 { 'store index'. }
#_STAZX_ #_XAML_minus1 {And to 'XAM index'. }
#_DEX_ {Next of 2 bytes. }
#_BNE_ #@_SETADR {Loop unless X = 0. }
_NXTPRNT=* #_BNE_ #@_PRDATA {NE means no address to print. }
#_LDAIM_ #$8D {CR. }
#_JSR_ ##_ECHO {Output it. }
#_LDAZ_ #_XAMH {'Examine index' high-order byte. }
#_JSR_ ##_PRBYTE {Output it in hex format. }
#_LDAZ_ #_XAML {Low-order 'examine index' byte. }
#_JSR_ ##_PRBYTE {Output it in hex format. }
#_LDAIM_ #$BA {":". }
#_JSR_ ##_ECHO {Output it. }
_PRDATA=* #_LDAIM_ #$A0 {Blank. }
#_JSR_ ##_ECHO {Output it. }
#_LDAIX_ #_XAML {Get data byte at 'examine index'. }
#_JSR_ ##_PRBYTE {Output it in hex format. }
_XAMNEXT=* #_STXZ_ #_MODE {0->MODE (XAM mode). }
#_LDAZ_ #_XAML { }
#_CMPZ_ #_L {Compare 'examine index' to hex data. }
#_LDAZ_ #_XAMH { }
#_SBCZ_ #_H { }
#_BCS_ #@_TONEXTITEM {Not less, so no more data to output. }
#_INCZ_ #_XAML { }
#_BNE_ #@_MOD8CHK {Increment 'examine index'. }
#_INCZ_ #_XAMH { }
_MOD8CHK=* #_LDAZ_ #_XAML {Check low-order 'examine index' byte }
#_ANDIM_ #$07 { For MOD 8= 0 }
#_BPL_ #@_NXTPRNT {Always taken. }
_PRBYTE=* #_PHA_ {Save A for LSD. }
#_LSRA_ { }
#_LSRA_ { }
#_LSRA_ {MSD to LSD position. }
#_LSRA_ { }
#_JSR_ ##_PRHEX {Output hex digit. }
#_PLA_ {Restore A. }
_PRHEX=* #_ANDIM_ #$0F {Mask LSD for hex print. }
#_ORAIM_ #$B0 {Add "0". }
#_CMPIM_ #$BA {Digit? }
#_BCC_ #@_ECHO {Yes, output it. }
#_ADCIM_ #$06 {Add offset for letter. }
{[Gigatron] Order reversed for fake PIA: }
_ECHO=* #_STA_ ##_DSP {Output character. Sets DA. }
_WAITECHO=* #_BIT_ ##_DSP {DA bit (B7) cleared yet? }
#_BNE_ #@_WAITECHO {No, wait for display. }
#_RTS_ {Return. }
#$00 #$00 {(unused) }
{FFFA} ##$0000 {(NMI) }
{FFFC} ##_RESET {(RESET) }
{FFFE} ##_BREAK {(IRQ/BRK) }
{-----------------------------------------------------------------------+
| |
+-----------------------------------------------------------------------}