OpenCores
URL https://opencores.org/ocsvn/rf6809/rf6809/trunk

Subversion Repositories rf6809

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 3 to Rev 4
    Reverse comparison

Rev 3 → Rev 4

/rf6809/trunk/software/a09/a09.c
0,0 → 1,7048
/* A09, 6809 Assembler.
(C) Copyright 1993,1994 L.C. Benschop.
Parts (C) Copyright 2001-2010 H. Seib.
Mods for 12-bit FPGA core 6809 by R. Finch
 
This version of the program is distributed under the terms and conditions
of the GNU General Public License version 2. See file the COPYING for details.
THERE IS NO WARRANTY ON THIS PROGRAM.
Generates binary image file from the lowest to
the highest address with actually assembled data.
Machine dependencies:
char is 8 bits.
short is 16 bits.
integer arithmetic is twos complement.
syntax:
a09 [-{b|r|s|x|f}filename]|[-c] [-lfilename] [-ooption] [-dsym=value]* sourcefile.
Options
-Vfilename Verilog rommem declaration output
-c suppresses code output
-bfilename binary output file name (default name minus a09 suffix plus .bin)
-rfilename Flex9 RELASMB-compatible output file name (relocatable)
-sfilename s-record output file name (default its a binary file)
-xfilename intel hex output file name (-"-)
-ffilename Flex9 output file name (-"-)
-lfilename list file name (default no listing)
-dsym[=value] define a symbol
-oopt defines an option
recognized pseudoops:
ext defines an external symbol (relocating mode only)
extern -"-
public defines a public symbol (effective in relocating mode only)
macro defines a macro
exitm terminates a macro expansion
endm ends a macro definition
if
ifn
ifc
ifnc
else
endif
dup
endd
org
equ
set
setdp sets direct page in 6809 / 6309 mode
text
fcb
fcw
fdb
fcc
rmb
reg
end
include
title
nam
ttl
sttl
setpg
pag
spc
rep
rpt
repeat
opt define an option (see below for possible options)
err
abs force absolute mode
common
endcom
def
define
enddef
name
symlen
bin, binary includes a binary file at the current position
 
recognized options:
On | Off Meaning
------------------------------------------------------------
PAG | NOP* Page Formatting
CON | NOC* Print skipped conditional code
MAC*| NOM Print macro calling line
EXP | NOE* Print macro expansion lines
SYM*| NOS Print symbol table
MUL*| NMU Print multiple object code lines
LIS*| NOL Print assembler listing
LP1 | NO1* Print Pass 1 Listing
DAT*| NOD Print date in listing
NUM | NON* Print line numbers
INV | NOI* Print invisible lines
TSC | NOT* Strict TSC Compatibility
WAR*| NOW Print warnings
CLL*| NCL Check line length
LFN | NLF* Print long file names
LLL*| NLL List library lines
GAS | NOG* Gnu AS source style compatibility
REL*| NOR Print Relocation table in Relocating mode
M68*| H63 | M00 MC6809 / HD6309 / MC6800 mode
TXT | NTX* Print text table
LPA | LNP* Listing in f9dasm patch format
* denotes default value
 
v0.1 93/11/03 Initial version.
v0.2 94/03/21 Fixed PC relative addressing bug
Added SET, SETDP, INCLUDE. IF/ELSE/ENDIF
No macros yet, and no separate linkable modules.
 
v0.1.X 99/12/20 added Intel hex option (SLB)
 
-- H.Seib Additions: --
 
v0.2.S 01/10/13 converted to readable format
v0.3 01/10/15 added transfer address processing
increased max. #symbols and other constants
(hey, this isn't CP/M anymore :-)
added a bit of intelligence to command line processing
loads file(s) into internal storage prior to processing
(this aids a lot in preventing recursive invocations)
added LIB,LIBRARY pseudoop (same as INCLUDE)
added OPT,OPTION pseudoop
v0.4 01/10/22 added -t switch to increase compatibility with the
TSC FLEX Assembler line, which uses a slightly more
rigid source file format
v0.5 01/10/23 added SETPG, SETLI, PAG, SPC, NAM(TTL,TITLE), STTL, REP(RPT,REPEAT)
v0.6 01/10/23 added EXITM, IFN, IFC, IFNC, DUP, ENDD
v0.7 01/10/29 added REG, ERR, TEXT
v0.8 01/10/30 converted command line handling to -O switch for options
and added a bunch of options
RZB pseudoop added
v0.9 01/11/05 clean-ups, increased TSC FLEX Assembler compatibility
v0.10 01/11/15 ASM and VERSION texts predefined
v0.11 01/11/27 increased TSC FLEX Assembler compatibility (labels made case sensitive)
v0.12 01/11/28 added some convenience mnemonics and simulated 6800 instructions to
increase TSC FLEX Assembler compatibility
v1.02 01/04/11 check for address range overlaps implemented
v1.03 02/09/24 macro parser had an error; corrected
v1.04 02/12/10 error message output adjusted for Visual C++ 6.0 IDE compatibility
added OPT LFN/NLF for that purpose
v1.05 02/12/23 crude form of backwards ORG added to binary output
v1.06 03/06/10 added OPT LLL/NLL to include/suppress listing of LIB lines
v1.07 03/06/23 outsymtable() only starts with a page feed if current line
is is NOT the first line on a page
v1.08 03/07/01 SKIP count for the IF(N) and IF(N)C statements added to
normal statements (i.e., outside macro definitions)
v1.09 05/06/02 some cleanups
added -r format for FLEX9 RELASMB compatible output
added ABS, GLOBAL, EXT, DEFINE, ENDDEF, COMMON, ENDCOM
REL|NOR option added
GAS|NOG option added (rudimentary)
M68|H63 option added
v1.10 05/06/03 made options available as numeric strings
added local label support
added SYMLEN
TXT|NTX option added
v1.11 05/06/06 IFD/IFND directives added
added special checks for "0,-[-]indexreg" and "0,indexreg+[+]"
when determining the postbyte for indexed addressing modes
v1.12 05/06/20 OPT CON|NOC correctly implemented
v1.13 skipped for users that might have an uneasy feeling about
the number "13" >:-)
v1.14 05/08/01 text symbol replacement enhanced; it was a bit TOO general.
Now, &xxx is only treated as a text variable when xxx REALLY
is a text symbol; in all other cases, it's not preprocessed.
Let the assembler engine handle eventual errors.
Thanks to Peter from Australia for pointing this out!
v1.15 05/08/02 only 1 local label was allowed per address; now, as many as
possible can be at the same location.
Thanks to Peter from Australia for pointing this out!
v1.16 05/08/05 SETDP is illegal in relocating mode!
SETDP without any parameter DISABLES Direct mode entirely.
Cured an interesting bug... the following sequence:
ORG 1
LDA TEST
SHIT NOP
ORG 1
TEST RMB 1
caused a phase error; this was caused by the invalid
assumption in scanlabel() that forward references have
a higher memory location than the current address.
Thanks to Peter from Australia for pointing this out!
v1.17 08/08/05 made tests for above problem more rigorous; now ANY forward
reference to a label that's not yet defined is treated as
uncertain.
Removed a nasty bug that caused the following code to produce
incorrect values:
org $8000 (anything >= $8000 will do)
lbl rmb 8
SizeBad equ (*-lbl)/2
OPT NOL changed to OPT NO1 to allow implementing OPT LIS|NOL.
OPT LIS*|NOL added
Thanks to Peter from Australia for pointing these out!
v1.18 09/08/05 backward search for local labels now searches for "<= local
address" instead of "< local address"
Thanks to Peter from Australia for pointing this out!
Added INCD / DECD convenience mnemonics
(realized as ADDD/SUBD 1)
v1.19 10/08/05 Added a bunch of 6800-style mnemonics; if they conflict
with 6809 mnemonics ("INC A" for example), they are only
active in TSC mode
v1.20 16/08/05 changed special checks for
"0,-[-]indexreg" and "0,indexreg+[+]"
to include all known labels and changed the scope to
",[-[-]]indexreg[+[+]]"
v1.21 21/02/06 Bug in "xxx >0,reg" found by Margus Kliimask
v1.22 03/09/08 Addded BIN(ARY) pseudo-op to include binary files
v1.23 13/02/09 6800 code generation added
accept multiple input files (first one defines default
output and listing file names)
v1.24 13/02/09 made compilable with gcc
v1.25 05/03/09 6800 alternate mnemonics work better now
v1.26 14/03/09 assembling DOS format files in Loonix works better now
v1.27 20/01/10 LPA/NLP options added
v1.28 21/04/10 INCD/DECD produced invalid code
 
*/
 
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <malloc.h>
#include <stdarg.h>
#include <stdlib.h>
#include <time.h>
 
/*****************************************************************************/
/* Definitions */
/*****************************************************************************/
 
#define VERSION "1.30"
#define VERSNUM "$011D" /* can be queried as &VERSION */
 
#define UNIX 0 /* set to != 0 for UNIX specials */
 
#define MAX_PASSNO 9
#define MAXLABELS 8192
#define MAXMACROS 1024
#define MAXTEXTS 1024
#define MAXRELOCS 32768
#define MAXIDLEN 32
#define MAXLISTBYTES 7
#define FNLEN 256
#define LINELEN 1024
 
/*****************************************************************************/
/* Line buffer definitions */
/*****************************************************************************/
 
struct linebuf
{
struct linebuf * next; /* pointer to next line */
struct linebuf * prev; /* pointer to previous line */
char *fn; /* pointer to original file name */
long ln; /* line number therein */
unsigned char lvl; /* line level */
unsigned char rel; /* relocation mode */
char txt[1]; /* text buffer */
};
 
char *fnms[128] = {0}; /* we process up to 128 different fls*/
short nfnms; /* # loaded files */
 
/* special bits in lvl : */
#define LINCAT_MACDEF 0x20 /* macro definition */
#define LINCAT_MACEXP 0x40 /* macro expansion */
#define LINCAT_INVISIBLE 0x80 /* does not appear in listing */
#define LINCAT_LVLMASK 0x1F /* mask for line levels (0..31) */
 
struct linebuf *rootline = NULL; /* pointer to 1st line of the file */
struct linebuf *curline = NULL; /* pointer to currently processed ln */
 
/*****************************************************************************/
/* Opcode definitions */
/*****************************************************************************/
 
struct oprecord
{
char * name; /* opcode mnemonic */
unsigned char cat; /* opcode category */
unsigned __int64 code; /* category-dependent additional code*/
unsigned char tgtNdx;
};
 
/* Instruction categories : */
#define OPCAT_ONEBYTE 0x00 /* one byte opcodes NOP */
#define OPCAT_TWOBYTE 0x01 /* two byte opcodes SWI2 */
#define OPCAT_THREEBYTE 0x02 /* three byte opcodes TAB */
#define OPCAT_FOURBYTE 0x03 /* four byte opcodes ABA */
#define OPCAT_IMMBYTE 0x04 /* opcodes w. imm byte ANDCC */
#define OPCAT_LEA 0x05 /* load effective address LEAX */
#define OPCAT_SBRANCH 0x06 /* short branches BGE */
#define OPCAT_LBR2BYTE 0x07 /* long branches 2 byte opc LBGE */
#define OPCAT_LBR1BYTE 0x08 /* long branches 2 byte opc LBRA */
#define OPCAT_ARITH 0x09 /* accumulator instr. ADDA */
#define OPCAT_DBLREG1BYTE 0x0a /* double reg instr 1 byte opc LDX */
#define OPCAT_DBLREG2BYTE 0x0b /* double reg instr 2 byte opc LDY */
#define OPCAT_SINGLEADDR 0x0c /* single address instrs NEG */
#define OPCAT_2REG 0x0d /* 2 register instr TFR,EXG */
#define OPCAT_STACK 0x0e /* stack instr PSHx,PULx */
#define OPCAT_BITDIRECT 0x0f /* direct bitmanipulation AIM */
#define OPCAT_BITTRANS 0x10 /* direct bit transfer BAND */
#define OPCAT_BLOCKTRANS 0x11 /* block transfer TFM */
#define OPCAT_IREG 0x12 /* inter-register operations ADCR */
#define OPCAT_QUADREG1BYTE 0x13 /* quad reg instr 1 byte opc LDQ */
#define OPCAT_2IMMBYTE 0x14 /* 2byte opcode w. imm byte BITMD */
#define OPCAT_2ARITH 0x15 /* 2byte opcode accum. instr. SUBE */
#define OPCAT_ACCARITH 0x16 /* acc. instr. w.explicit acc ADD */
#define OPCAT_IDXEXT 0x17 /* indexed/extended, 6800-style JMP */
#define OPCAT_ACCADDR 0x18 /* single address instrs, 6800 NEG */
#define OPCAT_PSEUDO 0x3f /* pseudo-ops */
#define OPCAT_6309 0x40 /* valid for 6309 only! */
#define OPCAT_NOIMM 0x80 /* immediate not allowed! STD */
 
/* the various Pseudo-Ops */
#define PSEUDO_RMB 0
#define PSEUDO_ELSE 1
#define PSEUDO_END 2
#define PSEUDO_ENDIF 3
#define PSEUDO_ENDM 4
#define PSEUDO_EQU 5
#define PSEUDO_EXT 6
#define PSEUDO_FCB 7
#define PSEUDO_FCC 8
#define PSEUDO_FCW 9
#define PSEUDO_IF 10
#define PSEUDO_MACRO 11
#define PSEUDO_ORG 12
#define PSEUDO_PUB 13
#define PSEUDO_SETDP 14
#define PSEUDO_SET 15
#define PSEUDO_INCLUDE 16
#define PSEUDO_OPT 17
#define PSEUDO_NAM 18
#define PSEUDO_STTL 19
#define PSEUDO_PAG 20
#define PSEUDO_SPC 21
#define PSEUDO_REP 22
#define PSEUDO_SETPG 23
#define PSEUDO_SETLI 24
#define PSEUDO_EXITM 25
#define PSEUDO_IFN 26
#define PSEUDO_IFC 27
#define PSEUDO_IFNC 28
#define PSEUDO_DUP 29
#define PSEUDO_ENDD 30
#define PSEUDO_REG 31
#define PSEUDO_ERR 32
#define PSEUDO_TEXT 33
#define PSEUDO_RZB 34
#define PSEUDO_ABS 35
#define PSEUDO_DEF 36
#define PSEUDO_ENDDEF 37
#define PSEUDO_COMMON 38
#define PSEUDO_ENDCOM 39
#define PSEUDO_NAME 40
#define PSEUDO_SYMLEN 41
#define PSEUDO_IFD 42
#define PSEUDO_IFND 43
#define PSEUDO_BINARY 44
#define PSEUDO_FCDW 45
 
struct oprecord optable09[]=
{
{ "ABA", OPCAT_FOURBYTE, 0x0340040ab0e0LL, 0 },
{ "ABS", OPCAT_PSEUDO, PSEUDO_ABS, 0 },
{ "ABX", OPCAT_ONEBYTE, 0x3a, 0 },
{ "ABY", OPCAT_TWOBYTE, 0x0310a5, 0 },
{ "ADC", OPCAT_ACCARITH, 0x89, 0 },
{ "ADCA", OPCAT_ARITH, 0x89, 0 },
{ "ADCB", OPCAT_ARITH, 0xc9, 0 },
{ "ADCD", OPCAT_6309 |
OPCAT_DBLREG1BYTE, 0x189, 0 },
{ "ADCR", OPCAT_6309 |
OPCAT_IREG, 0x1031, 0 },
{ "ADD", OPCAT_ACCARITH, 0x8b, 0 },
{ "ADDA", OPCAT_ARITH, 0x8b, 0 },
{ "ADDB", OPCAT_ARITH, 0xcb, 0 },
{ "ADDD", OPCAT_DBLREG1BYTE, 0xc3, 0 },
{ "ADDE", OPCAT_6309 |
OPCAT_2ARITH, 0x118b, 0 },
{ "ADDF", OPCAT_6309 |
OPCAT_2ARITH, 0x11cb, 0 },
{ "ADDR", OPCAT_6309 |
OPCAT_IREG, 0x1030, 0 },
{ "ADDW", OPCAT_6309 |
OPCAT_DBLREG2BYTE, 0x108b, 0 },
{ "AIM", OPCAT_6309 |
OPCAT_BITDIRECT, 0x02, 0 },
{ "AND", OPCAT_ACCARITH, 0x84, 0 },
{ "ANDA", OPCAT_ARITH, 0x84, 0 },
{ "ANDB", OPCAT_ARITH, 0xc4, 0 },
{ "ANDCC", OPCAT_IMMBYTE, 0x1c, 0 },
{ "ANDD", OPCAT_6309 |
OPCAT_DBLREG1BYTE, 0x184, 0 },
{ "ANDR", OPCAT_6309 |
OPCAT_IREG, 0x1034, 0 },
{ "ASL", OPCAT_SINGLEADDR, 0x08, 0 },
{ "ASLA", OPCAT_ONEBYTE, 0x48, 0 },
{ "ASLB", OPCAT_ONEBYTE, 0x58, 0 },
{ "ASLD", OPCAT_TWOBYTE, 0x058049, 0 },
{ "ASLD63", OPCAT_6309 |
OPCAT_TWOBYTE, 0x1048, 0 },
{ "ASR", OPCAT_SINGLEADDR, 0x07, 0 },
{ "ASRA", OPCAT_ONEBYTE, 0x47, 0 },
{ "ASRB", OPCAT_ONEBYTE, 0x57, 0 },
{ "ASRD", OPCAT_TWOBYTE, 0x047056, 0 },
{ "ASRD63", OPCAT_6309 |
OPCAT_TWOBYTE, 0x1047, 0 },
{ "BAND", OPCAT_6309 |
OPCAT_BITTRANS, 0x1130, 0 },
{ "BCC", OPCAT_SBRANCH, 0x24, 0 },
{ "BCS", OPCAT_SBRANCH, 0x25, 0 },
{ "BEC", OPCAT_SBRANCH, 0x24, 0 },
{ "BEOR", OPCAT_6309 |
OPCAT_BITTRANS, 0x1134, 0 },
{ "BEQ", OPCAT_SBRANCH, 0x27, 0 },
{ "BES", OPCAT_SBRANCH, 0x25, 0 },
{ "BGE", OPCAT_SBRANCH, 0x2c, 0 },
{ "BGT", OPCAT_SBRANCH, 0x2e, 0 },
{ "BHI", OPCAT_SBRANCH, 0x22, 0 },
{ "BHS", OPCAT_SBRANCH, 0x24, 0 },
{ "BIAND", OPCAT_6309 |
OPCAT_BITTRANS, 0x1131, 0 },
{ "BIEOR", OPCAT_6309 |
OPCAT_BITTRANS, 0x1135, 0 },
{ "BIN", OPCAT_PSEUDO, PSEUDO_BINARY, 0 },
{ "BINARY", OPCAT_PSEUDO, PSEUDO_BINARY, 0 },
{ "BIOR", OPCAT_6309 |
OPCAT_BITTRANS, 0x1133, 0 },
{ "BIT", OPCAT_ACCARITH, 0x85, 0 },
{ "BITA", OPCAT_ARITH, 0x85, 0 },
{ "BITB", OPCAT_ARITH, 0xc5, 0 },
{ "BITD", OPCAT_6309 |
OPCAT_DBLREG1BYTE, 0x185, 0 },
{ "BITMD", OPCAT_6309 |
OPCAT_2IMMBYTE, 0x113c, 0 },
{ "BLE", OPCAT_SBRANCH, 0x2f, 0 },
{ "BLO", OPCAT_SBRANCH, 0x25, 0 },
{ "BLS", OPCAT_SBRANCH, 0x23, 0 },
{ "BLT", OPCAT_SBRANCH, 0x2d, 0 },
{ "BMI", OPCAT_SBRANCH, 0x2b, 0 },
{ "BNE", OPCAT_SBRANCH, 0x26, 0 },
{ "BOR", OPCAT_6309 |
OPCAT_BITTRANS, 0x1132, 0 },
{ "BPL", OPCAT_SBRANCH, 0x2a, 0 },
{ "BRA", OPCAT_SBRANCH, 0x20, 0 },
{ "BRN", OPCAT_SBRANCH, 0x21, 0 },
{ "BSR", OPCAT_SBRANCH, 0x8d, 0 },
{ "BVC", OPCAT_SBRANCH, 0x28, 0 },
{ "BVS", OPCAT_SBRANCH, 0x29, 0 },
{ "CBA", OPCAT_FOURBYTE, 0x0340040a10e0LL, 0 },
{ "CLC", OPCAT_TWOBYTE, 0x1c0fe, 0 },
{ "CLF", OPCAT_TWOBYTE, 0x1c0bf, 0 },
{ "CLI", OPCAT_TWOBYTE, 0x1c0ef, 0 },
{ "CLIF", OPCAT_TWOBYTE, 0x1c0af, 0 },
{ "CLR", OPCAT_SINGLEADDR, 0x0f, 0 },
{ "CLRA", OPCAT_ONEBYTE, 0x4f, 0 },
{ "CLRB", OPCAT_ONEBYTE, 0x5f, 0 },
{ "CLRD", OPCAT_TWOBYTE, 0x4f05f, 0 },
{ "CLRD63", OPCAT_6309 |
OPCAT_TWOBYTE, 0x104f, 0 },
{ "CLRE", OPCAT_6309 |
OPCAT_TWOBYTE, 0x114f, 0 },
{ "CLRF", OPCAT_6309 |
OPCAT_TWOBYTE, 0x115f, 0 },
{ "CLRW", OPCAT_6309 |
OPCAT_TWOBYTE, 0x105f, 0 },
{ "CLV", OPCAT_TWOBYTE, 0x1c0fd, 0 },
{ "CLZ", OPCAT_TWOBYTE, 0x1c0fb, 0 },
{ "CMP", OPCAT_ACCARITH, 0x81, 0 },
{ "CMPA", OPCAT_ARITH, 0x81, 0 },
{ "CMPB", OPCAT_ARITH, 0xc1, 0 },
{ "CMPD", OPCAT_DBLREG1BYTE, 0x183, 0 },
{ "CMPE", OPCAT_6309 |
OPCAT_2ARITH, 0x1181, 0 },
{ "CMPF", OPCAT_6309 |
OPCAT_2ARITH, 0x11c1, 0 },
{ "CMPR", OPCAT_6309 |
OPCAT_IREG, 0x1037, 0 },
{ "CMPS", OPCAT_DBLREG1BYTE, 0x28c, 4 },
{ "CMPU", OPCAT_DBLREG1BYTE, 0x283, 3 },
{ "CMPW", OPCAT_6309 |
OPCAT_DBLREG2BYTE, 0x1081, 0 },
{ "CMPX", OPCAT_DBLREG1BYTE, 0x8c, 1 },
{ "CMPY", OPCAT_DBLREG1BYTE, 0x18c, 2 },
{ "COM", OPCAT_SINGLEADDR, 0x03, 0 },
{ "COMA", OPCAT_ONEBYTE, 0x43, 0 },
{ "COMB", OPCAT_ONEBYTE, 0x53, 0 },
{ "COMD", OPCAT_6309 |
OPCAT_ONEBYTE, 0x143, 0 },
{ "COME", OPCAT_6309 |
OPCAT_TWOBYTE, 0x1143, 0 },
{ "COMF", OPCAT_6309 |
OPCAT_TWOBYTE, 0x1153, 0 },
{ "COMW", OPCAT_6309 |
OPCAT_TWOBYTE, 0x1053, 0 },
{ "COMMON", OPCAT_PSEUDO, PSEUDO_COMMON, 0 },
{ "CPD", OPCAT_DBLREG1BYTE, 0x183, 0 },
{ "CPX", OPCAT_DBLREG1BYTE, 0x8c, 1 },
{ "CPY", OPCAT_DBLREG1BYTE, 0x18c, 2 },
{ "CWAI", OPCAT_IMMBYTE, 0x3c, 0 },
{ "DAA", OPCAT_ONEBYTE, 0x19, 0 },
{ "DEC", OPCAT_SINGLEADDR, 0x0a, 0 },
{ "DECA", OPCAT_ONEBYTE, 0x4a, 0 },
{ "DECB", OPCAT_ONEBYTE, 0x5a, 0 },
{ "DECD", OPCAT_THREEBYTE, 0x083000001LL, 0 },
{ "DECD63", OPCAT_6309 |
OPCAT_TWOBYTE, 0x104a, 0 },
{ "DECE", OPCAT_6309 |
OPCAT_TWOBYTE, 0x114a, 0 },
{ "DECF", OPCAT_6309 |
OPCAT_TWOBYTE, 0x115a, 0 },
{ "DECW", OPCAT_6309 |
OPCAT_TWOBYTE, 0x105a, 0 },
{ "DEF", OPCAT_PSEUDO, PSEUDO_DEF, 0 },
{ "DEFINE", OPCAT_PSEUDO, PSEUDO_DEF, 0 },
{ "DES", OPCAT_TWOBYTE, 0x327ff, 4 },
{ "DEU", OPCAT_TWOBYTE, 0x335ff, 3 },
{ "DEX", OPCAT_TWOBYTE, 0x301ff, 1 },
{ "DEY", OPCAT_TWOBYTE, 0x313ff, 2 },
{ "DIVD", OPCAT_6309 |
OPCAT_2ARITH, 0x118d, 0 },
{ "DIVQ", OPCAT_6309 |
OPCAT_DBLREG2BYTE, 0x118e, 0 },
{ "DUP", OPCAT_PSEUDO, PSEUDO_DUP, 0 },
{ "EIM", OPCAT_6309 |
OPCAT_BITDIRECT, 0x05, 0 },
{ "ELSE", OPCAT_PSEUDO, PSEUDO_ELSE, 0 },
{ "END", OPCAT_PSEUDO, PSEUDO_END, 0 },
{ "ENDCOM", OPCAT_PSEUDO, PSEUDO_ENDCOM, 0 },
{ "ENDD", OPCAT_PSEUDO, PSEUDO_ENDD, 0 },
{ "ENDDEF", OPCAT_PSEUDO, PSEUDO_ENDDEF, 0 },
{ "ENDIF", OPCAT_PSEUDO, PSEUDO_ENDIF, 0 },
{ "ENDM", OPCAT_PSEUDO, PSEUDO_ENDM, 0 },
{ "EOR", OPCAT_ACCARITH, 0x88, 0 },
{ "EORA", OPCAT_ARITH, 0x88, 0 },
{ "EORB", OPCAT_ARITH, 0xc8, 0 },
{ "EORD", OPCAT_6309 |
OPCAT_DBLREG1BYTE, 0x188, 0 },
{ "EORR", OPCAT_6309 |
OPCAT_IREG, 0x1036, 0 },
{ "EQU", OPCAT_PSEUDO, PSEUDO_EQU, 0 },
{ "ERR", OPCAT_PSEUDO, PSEUDO_ERR, 0 },
{ "EXG", OPCAT_2REG, 0x1e, 0 },
{ "EXITM", OPCAT_PSEUDO, PSEUDO_EXITM, 0 },
{ "EXT", OPCAT_PSEUDO, PSEUDO_EXT, 0 },
{ "EXTERN", OPCAT_PSEUDO, PSEUDO_EXT, 0 },
{ "FCB", OPCAT_PSEUDO, PSEUDO_FCB, 0 },
{ "FCC", OPCAT_PSEUDO, PSEUDO_FCC, 0 },
{ "FCDW", OPCAT_PSEUDO, PSEUDO_FCDW, 0 },
{ "FCW", OPCAT_PSEUDO, PSEUDO_FCW, 0 },
{ "FDB", OPCAT_PSEUDO, PSEUDO_FCW, 0 },
{ "GLOBAL", OPCAT_PSEUDO, PSEUDO_PUB, 0 },
{ "IF", OPCAT_PSEUDO, PSEUDO_IF, 0 },
{ "IFC", OPCAT_PSEUDO, PSEUDO_IFC, 0 },
{ "IFD", OPCAT_PSEUDO, PSEUDO_IFD, 0 },
{ "IFN", OPCAT_PSEUDO, PSEUDO_IFN, 0 },
{ "IFNC", OPCAT_PSEUDO, PSEUDO_IFNC, 0 },
{ "IFND", OPCAT_PSEUDO, PSEUDO_IFND, 0 },
{ "INC", OPCAT_SINGLEADDR, 0x0c, 0 },
{ "INCA", OPCAT_ONEBYTE, 0x4c, 0 },
{ "INCB", OPCAT_ONEBYTE, 0x5c, 0 },
{ "INCD", OPCAT_THREEBYTE, 0x0c3000001LL, 0 },
{ "INCD63", OPCAT_6309 |
OPCAT_TWOBYTE, 0x104c, 0 },
{ "INCE", OPCAT_6309 |
OPCAT_TWOBYTE, 0x114c, 0 },
{ "INCF", OPCAT_6309 |
OPCAT_TWOBYTE, 0x115c, 0 },
{ "INCLUDE", OPCAT_PSEUDO, PSEUDO_INCLUDE, 0 },
{ "INCW", OPCAT_6309 |
OPCAT_TWOBYTE, 0x105c, 0 },
{ "INS", OPCAT_TWOBYTE, 0x32601, 4 },
{ "INU", OPCAT_TWOBYTE, 0x33401, 3 },
{ "INX", OPCAT_TWOBYTE, 0x30001, 1 },
{ "INY", OPCAT_TWOBYTE, 0x31201, 2 },
{ "JMP", OPCAT_SINGLEADDR, 0x0e, 0 },
{ "JSR", OPCAT_DBLREG1BYTE, 0x8d, 0 },
{ "LBCC", OPCAT_LBR1BYTE, 0x124, 0 },
{ "LBCS", OPCAT_LBR1BYTE, 0x125, 0 },
{ "LBEC", OPCAT_LBR1BYTE, 0x124, 0 },
{ "LBEQ", OPCAT_LBR1BYTE, 0x127, 0 },
{ "LBES", OPCAT_LBR1BYTE, 0x125, 0 },
{ "LBGE", OPCAT_LBR1BYTE, 0x12c, 0 },
{ "LBGT", OPCAT_LBR1BYTE, 0x12e, 0 },
{ "LBHI", OPCAT_LBR1BYTE, 0x122, 0 },
{ "LBHS", OPCAT_LBR1BYTE, 0x124, 0 },
{ "LBLE", OPCAT_LBR1BYTE, 0x12f, 0 },
{ "LBLO", OPCAT_LBR1BYTE, 0x125, 0 },
{ "LBLS", OPCAT_LBR1BYTE, 0x123, 0 },
{ "LBLT", OPCAT_LBR1BYTE, 0x12d, 0 },
{ "LBMI", OPCAT_LBR1BYTE, 0x12b, 0 },
{ "LBNE", OPCAT_LBR1BYTE, 0x126, 0 },
{ "LBPL", OPCAT_LBR1BYTE, 0x12a, 0 },
{ "LBRA", OPCAT_LBR1BYTE, 0x16, 0 },
{ "LBRN", OPCAT_LBR1BYTE, 0x121, 0 },
{ "LBSR", OPCAT_LBR1BYTE, 0x17, 0 },
{ "LBVC", OPCAT_LBR1BYTE, 0x128, 0 },
{ "LBVS", OPCAT_LBR1BYTE, 0x129, 0 },
{ "LD", OPCAT_ACCARITH, 0x86, 0 },
{ "LDA", OPCAT_ARITH, 0x86, 0 },
{ "LDAA", OPCAT_ARITH, 0x86, 0 },
{ "LDAB", OPCAT_ARITH, 0xc6, 0 },
{ "LDAD", OPCAT_DBLREG1BYTE, 0xcc, 0 },
{ "LDB", OPCAT_ARITH, 0xc6, 0 },
{ "LDBT", OPCAT_6309 |
OPCAT_BITTRANS, 0x1136, 0 },
{ "LDD", OPCAT_DBLREG1BYTE, 0xcc, 0 },
{ "LDE", OPCAT_6309 |
OPCAT_2ARITH, 0x1186, 0 },
{ "LDF", OPCAT_6309 |
OPCAT_2ARITH, 0x11c6, 0 },
{ "LDMD", OPCAT_6309 |
OPCAT_2IMMBYTE, 0x113d, 0 },
{ "LDQ", OPCAT_6309 |
OPCAT_QUADREG1BYTE,0x10cc, 0 },
{ "LDS", OPCAT_DBLREG1BYTE, 0x1ce, 4 },
{ "LDU", OPCAT_DBLREG1BYTE, 0xce, 3 },
{ "LDW", OPCAT_6309 |
OPCAT_DBLREG2BYTE, 0x1086, 0 },
{ "LDX", OPCAT_DBLREG1BYTE, 0x8e, 1 },
{ "LDY", OPCAT_DBLREG1BYTE, 0x18e, 2 },
{ "LEAS", OPCAT_LEA, 0x32, 4 },
{ "LEAU", OPCAT_LEA, 0x33, 3 },
{ "LEAX", OPCAT_LEA, 0x30, 1 },
{ "LEAY", OPCAT_LEA, 0x31, 2 },
{ "LIB", OPCAT_PSEUDO, PSEUDO_INCLUDE, 0 },
{ "LIBRARY", OPCAT_PSEUDO, PSEUDO_INCLUDE, 0 },
{ "LSL", OPCAT_SINGLEADDR, 0x08, 0 },
{ "LSLA", OPCAT_ONEBYTE, 0x48, 0 },
{ "LSLB", OPCAT_ONEBYTE, 0x58, 0 },
{ "LSLD", OPCAT_TWOBYTE, 0x58049, 0 },
{ "LSLD63", OPCAT_6309 |
OPCAT_TWOBYTE, 0x1048, 0 },
{ "LSR", OPCAT_SINGLEADDR, 0x04, 0 },
{ "LSRA", OPCAT_ONEBYTE, 0x44, 0 },
{ "LSRB", OPCAT_ONEBYTE, 0x54, 0 },
{ "LSRD", OPCAT_TWOBYTE, 0x44056, 0 },
{ "LSRD63", OPCAT_6309 |
OPCAT_TWOBYTE, 0x1044, 0 },
{ "LSRW", OPCAT_6309 |
OPCAT_TWOBYTE, 0x1054, 0 },
{ "MACRO", OPCAT_PSEUDO, PSEUDO_MACRO, 0 },
{ "MUL", OPCAT_ONEBYTE, 0x3d, 0 },
{ "MULD", OPCAT_6309 |
OPCAT_DBLREG2BYTE, 0x118f, 0 },
{ "NAM", OPCAT_PSEUDO, PSEUDO_NAM, 0 },
{ "NAME", OPCAT_PSEUDO, PSEUDO_NAME, 0 },
{ "NEG", OPCAT_SINGLEADDR, 0x00, 0 },
{ "NEGA", OPCAT_ONEBYTE, 0x40, 0 },
{ "NEGB", OPCAT_ONEBYTE, 0x50, 0 },
{ "NEGD", OPCAT_6309 |
OPCAT_ONEBYTE, 0x140, 0 },
{ "NOP", OPCAT_ONEBYTE, 0x12, 0 },
{ "OIM", OPCAT_6309 |
OPCAT_BITDIRECT, 0x01, 0 },
{ "OPT", OPCAT_PSEUDO, PSEUDO_OPT, 0 },
{ "OPTION", OPCAT_PSEUDO, PSEUDO_OPT, 0 },
{ "ORA", OPCAT_ARITH, 0x8a, 0 },
{ "ORAA", OPCAT_ARITH, 0x8a, 0 },
{ "ORAB", OPCAT_ARITH, 0xca, 0 },
{ "ORB", OPCAT_ARITH, 0xca, 0 },
{ "ORCC", OPCAT_IMMBYTE, 0x1a, 0 },
{ "ORD", OPCAT_6309 |
OPCAT_DBLREG1BYTE, 0x18a, 0 },
{ "ORG", OPCAT_PSEUDO, PSEUDO_ORG, 0 },
{ "ORR", OPCAT_6309 |
OPCAT_IREG, 0x1035, 0 },
{ "PAG", OPCAT_PSEUDO, PSEUDO_PAG, 0 },
{ "PAGE", OPCAT_PSEUDO, PSEUDO_PAG, 0 },
{ "PSH", OPCAT_STACK, 0x34, 0 },
{ "PSHA", OPCAT_TWOBYTE, 0x34002, 0 },
{ "PSHB", OPCAT_TWOBYTE, 0x34004, 0 },
{ "PSHD", OPCAT_TWOBYTE, 0x34006, 0 },
{ "PSHS", OPCAT_STACK, 0x34, 4 },
{ "PSHSW", OPCAT_6309 |
OPCAT_TWOBYTE, 0x1038, 0 },
{ "PSHU", OPCAT_STACK, 0x36, 3 },
{ "PSHUW", OPCAT_6309 |
OPCAT_TWOBYTE, 0x103a, 0 },
{ "PSHX", OPCAT_TWOBYTE, 0x34010, 1 },
{ "PSHY", OPCAT_TWOBYTE, 0x34020, 2 },
{ "PUB", OPCAT_PSEUDO, PSEUDO_PUB, 0 },
{ "PUBLIC", OPCAT_PSEUDO, PSEUDO_PUB, 0 },
{ "PUL", OPCAT_STACK, 0x35, 0 },
{ "PULA", OPCAT_TWOBYTE, 0x35002, 0 },
{ "PULB", OPCAT_TWOBYTE, 0x35004, 0 },
{ "PULD", OPCAT_TWOBYTE, 0x35006, 0 },
{ "PULS", OPCAT_STACK, 0x35, 4 },
{ "PULSW", OPCAT_6309 |
OPCAT_TWOBYTE, 0x1039, 0 },
{ "PULU", OPCAT_STACK, 0x37, 3 },
{ "PULUW", OPCAT_6309 |
OPCAT_TWOBYTE, 0x103b, 0 },
{ "PULX", OPCAT_TWOBYTE, 0x35010, 1 },
{ "PULY", OPCAT_TWOBYTE, 0x35020, 2 },
{ "REG", OPCAT_PSEUDO, PSEUDO_REG, 0 },
{ "REP", OPCAT_PSEUDO, PSEUDO_REP, 0 },
{ "REPEAT", OPCAT_PSEUDO, PSEUDO_REP, 0 },
{ "RESET", OPCAT_ONEBYTE, 0x3e, 0 },
{ "RMB", OPCAT_PSEUDO, PSEUDO_RMB, 0 },
{ "ROL", OPCAT_SINGLEADDR, 0x09, 0 },
{ "ROLA", OPCAT_ONEBYTE, 0x49, 0 },
{ "ROLB", OPCAT_ONEBYTE, 0x59, 0 },
{ "ROLD", OPCAT_6309 |
OPCAT_ONEBYTE, 0x149, 0 },
{ "ROLW", OPCAT_6309 |
OPCAT_TWOBYTE, 0x1059, 0 },
{ "ROR", OPCAT_SINGLEADDR, 0x06, 0 },
{ "RORA", OPCAT_ONEBYTE, 0x46, 0 },
{ "RORB", OPCAT_ONEBYTE, 0x56, 0 },
{ "RORD", OPCAT_6309 |
OPCAT_ONEBYTE, 0x146, 0 },
{ "RORW", OPCAT_6309 |
OPCAT_TWOBYTE, 0x1056, 0 },
{ "RPT", OPCAT_PSEUDO, PSEUDO_REP, 0 },
{ "RTF", OPCAT_ONEBYTE, 0x38, 0 },
{ "RTI", OPCAT_ONEBYTE, 0x3b, 0 },
{ "RTS", OPCAT_ONEBYTE, 0x39, 0 },
{ "RZB", OPCAT_PSEUDO, PSEUDO_RZB, 0 },
{ "SBA", OPCAT_FOURBYTE, 0x0340040a00e0LL, 0 },
{ "SBC", OPCAT_ACCARITH, 0x82, 0 },
{ "SBCA", OPCAT_ARITH, 0x82, 0 },
{ "SBCB", OPCAT_ARITH, 0xc2, 0 },
{ "SBCD", OPCAT_6309 |
OPCAT_DBLREG1BYTE, 0x182, 0 },
{ "SBCR", OPCAT_6309 |
OPCAT_IREG, 0x1033, 0 },
{ "SEC", OPCAT_TWOBYTE, 0x1a001, 0 },
{ "SEF", OPCAT_TWOBYTE, 0x1a040, 0 },
{ "SEI", OPCAT_TWOBYTE, 0x1a010, 0 },
{ "SEIF", OPCAT_TWOBYTE, 0x1a050, 0 },
{ "SET", OPCAT_PSEUDO, PSEUDO_SET, 0 },
{ "SETDP", OPCAT_PSEUDO, PSEUDO_SETDP, 0 },
{ "SETLI", OPCAT_PSEUDO, PSEUDO_SETLI, 0 },
{ "SETPG", OPCAT_PSEUDO, PSEUDO_SETPG, 0 },
{ "SEV", OPCAT_TWOBYTE, 0x1a002, 0 },
{ "SEX", OPCAT_ONEBYTE, 0x1d, 0 },
{ "SEXW", OPCAT_6309 |
OPCAT_ONEBYTE, 0x14, 0 },
{ "SEZ", OPCAT_TWOBYTE, 0x1a004, 0 },
{ "SPC", OPCAT_PSEUDO, PSEUDO_SPC, 0 },
{ "STA", OPCAT_NOIMM |
OPCAT_ARITH, 0x87, 0 },
{ "STAA", OPCAT_NOIMM |
OPCAT_ARITH, 0x87, 0 },
{ "STAB", OPCAT_NOIMM |
OPCAT_ARITH, 0xc7, 0 },
{ "STAD", OPCAT_NOIMM |
OPCAT_DBLREG1BYTE, 0xcd, 0 },
{ "STB", OPCAT_NOIMM |
OPCAT_ARITH, 0xc7, 0 },
{ "STBT", OPCAT_6309 |
OPCAT_BITTRANS, 0x1137, 0 },
{ "STD", OPCAT_NOIMM |
OPCAT_DBLREG1BYTE, 0xcd, 0 },
{ "STE", OPCAT_NOIMM |
OPCAT_6309 |
OPCAT_2ARITH, 0x1187, 0 },
{ "STF", OPCAT_NOIMM |
OPCAT_6309 |
OPCAT_2ARITH, 0x11c7, 0 },
{ "STQ", OPCAT_NOIMM |
OPCAT_6309 |
OPCAT_QUADREG1BYTE,0x10cd, 0 },
{ "STS", OPCAT_NOIMM |
OPCAT_DBLREG1BYTE, 0x1cf, 4 },
{ "STTL", OPCAT_PSEUDO, PSEUDO_STTL, 0 },
{ "STU", OPCAT_NOIMM |
OPCAT_DBLREG1BYTE, 0xcf, 3 },
{ "STW", OPCAT_NOIMM |
OPCAT_6309 |
OPCAT_DBLREG2BYTE, 0x1087, 0 },
{ "STX", OPCAT_NOIMM |
OPCAT_DBLREG1BYTE, 0x8f, 1 },
{ "STY", OPCAT_NOIMM |
OPCAT_DBLREG1BYTE, 0x18f, 2 },
{ "SUB", OPCAT_ACCARITH, 0x80, 0 },
{ "SUBA", OPCAT_ARITH, 0x80, 0 },
{ "SUBB", OPCAT_ARITH, 0xc0, 0 },
{ "SUBD", OPCAT_DBLREG1BYTE, 0x83, 0 },
{ "SUBE", OPCAT_6309 |
OPCAT_2ARITH, 0x1180, 0 },
{ "SUBF", OPCAT_6309 |
OPCAT_2ARITH, 0x11c0, 0 },
{ "SUBW", OPCAT_6309 |
OPCAT_DBLREG2BYTE, 0x1080, 0 },
{ "SUBR", OPCAT_6309 |
OPCAT_IREG, 0x1032, 0 },
{ "SWI", OPCAT_ONEBYTE, 0x3f, 0 },
{ "SWI2", OPCAT_ONEBYTE, 0x13f, 0 },
{ "SWI3", OPCAT_ONEBYTE, 0x23f, 0 },
{ "SYMLEN", OPCAT_PSEUDO, PSEUDO_SYMLEN, 0 },
{ "SYNC", OPCAT_ONEBYTE, 0x13, 0 },
{ "TAB", OPCAT_THREEBYTE, 0x1f08904d, 0 },
{ "TAP", OPCAT_TWOBYTE, 0x1f08a, 0 },
{ "TBA", OPCAT_THREEBYTE, 0x1f09804dLL, 0 },
{ "TEXT", OPCAT_PSEUDO, PSEUDO_TEXT, 0 },
{ "TFM", OPCAT_6309 |
OPCAT_BLOCKTRANS, 0x1138, 0 },
{ "TFR", OPCAT_2REG, 0x1f, 0 },
{ "TIM", OPCAT_6309 |
OPCAT_BITDIRECT, 0x0b, 0 },
{ "TITLE", OPCAT_PSEUDO, PSEUDO_NAM, 0 },
{ "TPA", OPCAT_TWOBYTE, 0x1f0a8, 0 },
{ "TST", OPCAT_SINGLEADDR, 0x0d, 0 },
{ "TSTA", OPCAT_ONEBYTE, 0x4d, 0 },
{ "TSTB", OPCAT_ONEBYTE, 0x5d, 0 },
{ "TSTD", OPCAT_6309 |
OPCAT_ONEBYTE, 0x14d, 0 },
{ "TSTE", OPCAT_6309 |
OPCAT_TWOBYTE, 0x114d, 0 },
{ "TSTF", OPCAT_6309 |
OPCAT_TWOBYTE, 0x115d, 0 },
{ "TSTW", OPCAT_6309 |
OPCAT_TWOBYTE, 0x105d, 0 },
{ "TSX", OPCAT_TWOBYTE, 0x1f041, 1 },
{ "TSY", OPCAT_FOURBYTE, 0x034040035020LL, 2 }, /* PSHS S/PULS Y */
{ "TTL", OPCAT_PSEUDO, PSEUDO_NAM, 0 },
{ "TXS", OPCAT_TWOBYTE, 0x1f014, 4 },
{ "TYS", OPCAT_FOURBYTE, 0x034020035040LL, 4 }, /* PSHS Y/PULS S */
{ "WAI", OPCAT_TWOBYTE, 0x3c0ff, 0 },
{ "WORD", OPCAT_PSEUDO, PSEUDO_FCW, 0 },
};
 
struct oprecord optable00[]=
{
{ "ABA", OPCAT_ONEBYTE, 0x1b },
{ "ABS", OPCAT_PSEUDO, PSEUDO_ABS },
{ "ADC", OPCAT_ACCARITH, 0x89 },
{ "ADCA", OPCAT_ARITH, 0x89 },
{ "ADCB", OPCAT_ARITH, 0xc9 },
{ "ADD", OPCAT_ACCARITH, 0x8b },
{ "ADDA", OPCAT_ARITH, 0x8b },
{ "ADDB", OPCAT_ARITH, 0xcb },
{ "AND", OPCAT_ACCARITH, 0x84 },
{ "ANDA", OPCAT_ARITH, 0x84 },
{ "ANDB", OPCAT_ARITH, 0xc4 },
{ "ASL", OPCAT_ACCADDR, 0x08 },
{ "ASLA", OPCAT_ONEBYTE, 0x48 },
{ "ASLB", OPCAT_ONEBYTE, 0x58 },
{ "ASR", OPCAT_ACCADDR, 0x07 },
{ "ASRA", OPCAT_ONEBYTE, 0x47 },
{ "ASRB", OPCAT_ONEBYTE, 0x57 },
{ "BCC", OPCAT_SBRANCH, 0x24 },
{ "BCS", OPCAT_SBRANCH, 0x25 },
{ "BEC", OPCAT_SBRANCH, 0x24 },
{ "BEQ", OPCAT_SBRANCH, 0x27 },
{ "BES", OPCAT_SBRANCH, 0x25 },
{ "BGE", OPCAT_SBRANCH, 0x2c },
{ "BGT", OPCAT_SBRANCH, 0x2e },
{ "BHI", OPCAT_SBRANCH, 0x22 },
{ "BHS", OPCAT_SBRANCH, 0x24 },
{ "BIN", OPCAT_PSEUDO, PSEUDO_BINARY },
{ "BINARY", OPCAT_PSEUDO, PSEUDO_BINARY },
{ "BIT", OPCAT_ACCARITH, 0x85 },
{ "BITA", OPCAT_ARITH, 0x85 },
{ "BITB", OPCAT_ARITH, 0xc5 },
{ "BLE", OPCAT_SBRANCH, 0x2f },
{ "BLO", OPCAT_SBRANCH, 0x25 },
{ "BLS", OPCAT_SBRANCH, 0x23 },
{ "BLT", OPCAT_SBRANCH, 0x2d },
{ "BMI", OPCAT_SBRANCH, 0x2b },
{ "BNE", OPCAT_SBRANCH, 0x26 },
{ "BPL", OPCAT_SBRANCH, 0x2a },
{ "BRA", OPCAT_SBRANCH, 0x20 },
{ "BSR", OPCAT_SBRANCH, 0x8d },
{ "BVC", OPCAT_SBRANCH, 0x28 },
{ "BVS", OPCAT_SBRANCH, 0x29 },
{ "CBA", OPCAT_ONEBYTE, 0x11 },
{ "CLC", OPCAT_ONEBYTE, 0x0c },
{ "CLI", OPCAT_ONEBYTE, 0x0e },
{ "CLR", OPCAT_ACCADDR, 0x0f },
{ "CLRA", OPCAT_ONEBYTE, 0x4f },
{ "CLRB", OPCAT_ONEBYTE, 0x5f },
{ "CLV", OPCAT_ONEBYTE, 0x0a },
{ "CMP", OPCAT_ACCARITH, 0x81 },
{ "CMPA", OPCAT_ARITH, 0x81 },
{ "CMPB", OPCAT_ARITH, 0xc1 },
{ "COM", OPCAT_ACCADDR, 0x03 },
{ "COMA", OPCAT_ONEBYTE, 0x43 },
{ "COMB", OPCAT_ONEBYTE, 0x53 },
{ "CPX", OPCAT_DBLREG1BYTE, 0x8c },
{ "DAA", OPCAT_ONEBYTE, 0x19 },
{ "DEC", OPCAT_ACCADDR, 0x0a },
{ "DECA", OPCAT_ONEBYTE, 0x4a },
{ "DECB", OPCAT_ONEBYTE, 0x5a },
{ "DEF", OPCAT_PSEUDO, PSEUDO_DEF },
{ "DEFINE", OPCAT_PSEUDO, PSEUDO_DEF },
{ "DES", OPCAT_ONEBYTE, 0x34 },
{ "DEX", OPCAT_ONEBYTE, 0x09 },
{ "DUP", OPCAT_PSEUDO, PSEUDO_DUP },
{ "ELSE", OPCAT_PSEUDO, PSEUDO_ELSE },
{ "END", OPCAT_PSEUDO, PSEUDO_END },
{ "ENDCOM", OPCAT_PSEUDO, PSEUDO_ENDCOM },
{ "ENDD", OPCAT_PSEUDO, PSEUDO_ENDD },
{ "ENDDEF", OPCAT_PSEUDO, PSEUDO_ENDDEF },
{ "ENDIF", OPCAT_PSEUDO, PSEUDO_ENDIF },
{ "ENDM", OPCAT_PSEUDO, PSEUDO_ENDM },
{ "EOR", OPCAT_ACCARITH, 0x88 },
{ "EORA", OPCAT_ARITH, 0x88 },
{ "EORB", OPCAT_ARITH, 0xc8 },
{ "EQU", OPCAT_PSEUDO, PSEUDO_EQU },
{ "ERR", OPCAT_PSEUDO, PSEUDO_ERR },
{ "EXITM", OPCAT_PSEUDO, PSEUDO_EXITM },
{ "EXT", OPCAT_PSEUDO, PSEUDO_EXT },
{ "EXTERN", OPCAT_PSEUDO, PSEUDO_EXT },
{ "FCB", OPCAT_PSEUDO, PSEUDO_FCB },
{ "FCC", OPCAT_PSEUDO, PSEUDO_FCC },
{ "FCW", OPCAT_PSEUDO, PSEUDO_FCW },
{ "FDB", OPCAT_PSEUDO, PSEUDO_FCW },
{ "GLOBAL", OPCAT_PSEUDO, PSEUDO_PUB },
{ "IF", OPCAT_PSEUDO, PSEUDO_IF },
{ "IFC", OPCAT_PSEUDO, PSEUDO_IFC },
{ "IFD", OPCAT_PSEUDO, PSEUDO_IFD },
{ "IFN", OPCAT_PSEUDO, PSEUDO_IFN },
{ "IFNC", OPCAT_PSEUDO, PSEUDO_IFNC },
{ "IFND", OPCAT_PSEUDO, PSEUDO_IFND },
{ "INC", OPCAT_ACCADDR, 0x0c },
{ "INCA", OPCAT_ONEBYTE, 0x4c },
{ "INCB", OPCAT_ONEBYTE, 0x5c },
{ "INCLUDE", OPCAT_PSEUDO, PSEUDO_INCLUDE },
{ "INS", OPCAT_ONEBYTE, 0x31 },
{ "INX", OPCAT_ONEBYTE, 0x08 },
{ "JMP", OPCAT_IDXEXT, 0x4e },
{ "JSR", OPCAT_IDXEXT, 0x8d },
{ "LDA", OPCAT_ACCARITH, 0x86 },
{ "LDAA", OPCAT_ARITH, 0x86 },
{ "LDAB", OPCAT_ARITH, 0xc6 },
{ "LDB", OPCAT_ARITH, 0xc6 },
{ "LDS", OPCAT_DBLREG1BYTE, 0x8e },
{ "LDX", OPCAT_DBLREG1BYTE, 0xce },
{ "LIB", OPCAT_PSEUDO, PSEUDO_INCLUDE },
{ "LIBRARY", OPCAT_PSEUDO, PSEUDO_INCLUDE },
{ "LSL", OPCAT_ACCADDR, 0x08 },
{ "LSLA", OPCAT_ONEBYTE, 0x48 },
{ "LSLB", OPCAT_ONEBYTE, 0x58 },
{ "LSR", OPCAT_ACCADDR, 0x04 },
{ "LSRA", OPCAT_ONEBYTE, 0x44 },
{ "LSRB", OPCAT_ONEBYTE, 0x54 },
{ "MACRO", OPCAT_PSEUDO, PSEUDO_MACRO },
{ "NAM", OPCAT_PSEUDO, PSEUDO_NAM },
{ "NAME", OPCAT_PSEUDO, PSEUDO_NAME },
{ "NEG", OPCAT_ACCADDR, 0x00 },
{ "NEGA", OPCAT_ONEBYTE, 0x40 },
{ "NEGB", OPCAT_ONEBYTE, 0x50 },
{ "NOP", OPCAT_ONEBYTE, 0x01 },
{ "OPT", OPCAT_PSEUDO, PSEUDO_OPT },
{ "OPTION", OPCAT_PSEUDO, PSEUDO_OPT },
{ "ORA", OPCAT_ARITH, 0x8a },
{ "ORAA", OPCAT_ARITH, 0x8a },
{ "ORAB", OPCAT_ARITH, 0xca },
{ "ORB", OPCAT_ARITH, 0xca },
{ "ORG", OPCAT_PSEUDO, PSEUDO_ORG },
{ "PAG", OPCAT_PSEUDO, PSEUDO_PAG },
{ "PAGE", OPCAT_PSEUDO, PSEUDO_PAG },
{ "PSHA", OPCAT_ONEBYTE, 0x36 },
{ "PSHB", OPCAT_ONEBYTE, 0x37 },
{ "PUB", OPCAT_PSEUDO, PSEUDO_PUB },
{ "PUBLIC", OPCAT_PSEUDO, PSEUDO_PUB },
{ "PULA", OPCAT_ONEBYTE, 0x32 },
{ "PULB", OPCAT_ONEBYTE, 0x33 },
{ "REG", OPCAT_PSEUDO, PSEUDO_REG },
{ "REP", OPCAT_PSEUDO, PSEUDO_REP },
{ "REPEAT", OPCAT_PSEUDO, PSEUDO_REP },
{ "RMB", OPCAT_PSEUDO, PSEUDO_RMB },
{ "ROL", OPCAT_ACCADDR, 0x09 },
{ "ROLA", OPCAT_ONEBYTE, 0x49 },
{ "ROLB", OPCAT_ONEBYTE, 0x59 },
{ "ROR", OPCAT_ACCADDR, 0x06 },
{ "RORA", OPCAT_ONEBYTE, 0x46 },
{ "RORB", OPCAT_ONEBYTE, 0x56 },
{ "RPT", OPCAT_PSEUDO, PSEUDO_REP },
{ "RTI", OPCAT_ONEBYTE, 0x3b },
{ "RTS", OPCAT_ONEBYTE, 0x39 },
{ "RZB", OPCAT_PSEUDO, PSEUDO_RZB },
{ "SBA", OPCAT_ONEBYTE, 0x10 },
{ "SBC", OPCAT_ACCARITH, 0x82 },
{ "SBCA", OPCAT_ARITH, 0x82 },
{ "SBCB", OPCAT_ARITH, 0xc2 },
{ "SEC", OPCAT_ONEBYTE, 0x0d },
{ "SEI", OPCAT_ONEBYTE, 0x0f },
{ "SET", OPCAT_PSEUDO, PSEUDO_SET },
//{ "SETDP", OPCAT_PSEUDO, PSEUDO_SETDP },
{ "SETLI", OPCAT_PSEUDO, PSEUDO_SETLI },
{ "SETPG", OPCAT_PSEUDO, PSEUDO_SETPG },
{ "SEV", OPCAT_ONEBYTE, 0x0b },
{ "SPC", OPCAT_PSEUDO, PSEUDO_SPC },
{ "STA", OPCAT_NOIMM |
OPCAT_ACCARITH, 0x87 },
{ "STAA", OPCAT_NOIMM |
OPCAT_ARITH, 0x87 },
{ "STAB", OPCAT_NOIMM |
OPCAT_ARITH, 0xc7 },
{ "STS", OPCAT_NOIMM |
OPCAT_DBLREG1BYTE, 0x8f },
{ "STTL", OPCAT_PSEUDO, PSEUDO_STTL },
{ "STX", OPCAT_NOIMM |
OPCAT_DBLREG1BYTE, 0xcf },
{ "SUB", OPCAT_ACCARITH, 0x80 },
{ "SUBA", OPCAT_ARITH, 0x80 },
{ "SUBB", OPCAT_ARITH, 0xc0 },
{ "SWI", OPCAT_ONEBYTE, 0x3f },
{ "SYMLEN", OPCAT_PSEUDO, PSEUDO_SYMLEN },
{ "TAB", OPCAT_ONEBYTE, 0x16 },
{ "TAP", OPCAT_ONEBYTE, 0x06 },
{ "TBA", OPCAT_ONEBYTE, 0x17 },
{ "TEXT", OPCAT_PSEUDO, PSEUDO_TEXT },
{ "TITLE", OPCAT_PSEUDO, PSEUDO_NAM },
{ "TPA", OPCAT_ONEBYTE, 0x07 },
{ "TST", OPCAT_ACCADDR, 0x0d },
{ "TSTA", OPCAT_ONEBYTE, 0x4d },
{ "TSTB", OPCAT_ONEBYTE, 0x5d },
{ "TSX", OPCAT_ONEBYTE, 0x30 },
{ "TTL", OPCAT_PSEUDO, PSEUDO_NAM },
{ "TXS", OPCAT_ONEBYTE, 0x35 },
{ "WAI", OPCAT_ONEBYTE, 0x3e },
};
 
/* expression categories...
all zeros is ordinary constant.
bit 1 indicates address within module.
bit 2 indicates external address.
bit 4 indicates this can't be relocated if it's an address.
bit 5 indicates address (if any) is negative.
*/
 
#define EXPRCAT_INTADDR 0x02
#define EXPRCAT_EXTADDR 0x04
#define EXPRCAT_PUBLIC 0x08
#define EXPRCAT_FIXED 0x10
#define EXPRCAT_NEGATIVE 0x20
 
/*****************************************************************************/
/* Symbol definitions */
/*****************************************************************************/
 
struct symrecord
{
char name[MAXIDLEN + 1]; /* symbol name */
char cat; /* symbol category */
char isFar; /* far assumed */
char isFarkw; /* FAR keyword used in symbol definiton */
unsigned value; /* symbol value */
union
{
struct symrecord *parent; /* parent symbol (for COMMON) */
long flags; /* forward reference flag (otherwise)*/
} u;
};
/* symbol categories : */
#define SYMCAT_CONSTANT 0x00 /* constant value (from equ) */
#define SYMCAT_VARIABLE 0x01 /* variable value (from set) */
#define SYMCAT_LABEL 0x02 /* address within module (label) */
#define SYMCAT_VARADDR 0x03 /* variable containing address */
#define SYMCAT_EXTERN 0x04 /* address in other module (extern) */
#define SYMCAT_VAREXTERN 0x05 /* variable containing extern addr. */
#define SYMCAT_UNRESOLVED 0x06 /* unresolved address */
#define SYMCAT_VARUNRESOLVED 0x07 /* var. containing unresolved addr */
#define SYMCAT_PUBLIC 0x08 /* public label */
#define SYMCAT_MACRO 0x09 /* macro definition */
#define SYMCAT_PUBLICUNDEF 0x0A /* public label (yet undefined) */
#define SYMCAT_PARMNAME 0x0B /* parameter name */
#define SYMCAT_EMPTY 0x0D /* empty */
#define SYMCAT_REG 0x0E /* REG directive */
#define SYMCAT_TEXT 0x0F /* /Dsymbol or TEXT label */
#define SYMCAT_COMMONDATA 0x12 /* COMMON Data */
#define SYMCAT_COMMON 0x14 /* COMMON block */
#define SYMCAT_LOCALLABEL 0x22 /* local label */
#define SYMCAT_EMPTYLOCAL 0x26 /* empty local label */
 
/* symbol flags: */
#define SYMFLAG_FORWARD 0x01 /* forward reference */
#define SYMFLAG_PASSED 0x02 /* passed forward reference */
 
long symcounter = 0; /* # currently loaded symbols */
struct symrecord symtable[MAXLABELS]; /* symbol table (fixed size) */
long lclcounter = 0; /* # currently loaded local symbols */
struct symrecord lcltable[MAXLABELS]; /* local symbol table (fixed size) */
/*****************************************************************************/
/* regrecord structure definition */
/*****************************************************************************/
 
struct regrecord
{
char *name; /* name of the register */
unsigned char tfr, psh; /* bit value for tfr and psh/pul */
};
 
/*****************************************************************************/
/* regtable : table of all registers */
/*****************************************************************************/
 
struct regrecord regtable09[]=
{
{ "D", 0x00, 0x06 },
{ "X", 0x01, 0x10 },
{ "Y", 0x02, 0x20 },
{ "U", 0x03, 0x40 },
{ "S", 0x04, 0x40 },
{ "PC", 0x05, 0x80 },
{ "A", 0x08, 0x02 },
{ "B", 0x09, 0x04 },
{ "CC", 0x0a, 0x01 },
{ "CCR", 0x0a, 0x01 },
{ "DP", 0x0b, 0x08 },
{ "DPR", 0x0b, 0x08 },
{ 0, 0, 0 }
};
 
struct regrecord regtable63[]= /* same for HD6309 */
{
{ "D", 0x00, 0x06 },
{ "X", 0x01, 0x10 },
{ "Y", 0x02, 0x20 },
{ "U", 0x03, 0x40 },
{ "S", 0x04, 0x40 },
{ "PC", 0x05, 0x80 },
{ "W", 0x06, 0x00 },
{ "V", 0x07, 0x00 },
{ "A", 0x08, 0x02 },
{ "B", 0x09, 0x04 },
{ "CC", 0x0a, 0x01 },
{ "CCR", 0x0a, 0x01 },
{ "DP", 0x0b, 0x08 },
{ "DPR", 0x0b, 0x08 },
{ "0", 0x0c, 0x00 },
{ "E", 0x0e, 0x00 },
{ "F", 0x0f, 0x00 },
{ 0, 0, 0 }
};
 
struct regrecord regtable00[]=
{
{ "X", 0x01, 0x10 },
{ "S", 0x04, 0x40 },
{ "PC", 0x05, 0x80 },
{ "A", 0x08, 0x02 },
{ "B", 0x09, 0x04 },
{ "CC", 0x0a, 0x01 },
{ "CCR", 0x0a, 0x01 },
{ 0, 0, 0 }
};
 
/*****************************************************************************/
/* bitregtable : table of all bit transfer registers */
/*****************************************************************************/
 
struct regrecord bitregtable09[] =
{
{ "CC", 0x00, 0x00 },
{ "A", 0x01, 0x01 },
{ "B", 0x02, 0x02 },
};
 
struct regrecord bitregtable00[] =
{
{ "CC", 0x00, 0x00 },
{ "A", 0x01, 0x01 },
{ "B", 0x02, 0x02 },
};
 
/*****************************************************************************/
/* relocrecord structure definition */
/*****************************************************************************/
 
struct relocrecord
{
unsigned addr; /* address that needs relocation */
char exprcat; /* expression category */
struct symrecord *sym; /* symbol for relocation */
};
 
long relcounter = 0; /* # currently defined relocations */
struct relocrecord reltable[MAXRELOCS]; /* relocation table (fixed size) */
long relhdrfoff; /* FLEX Relocatable Global Hdr Offset*/
 
/*****************************************************************************/
/* Options definitions */
/*****************************************************************************/
 
#define OPTION_M09 0x00000001L /* MC6809 mode */
#define OPTION_H63 0x00000002L /* HD6309 mode */
#define OPTION_M00 0x00000004L /* MC6800 mode */
#define OPTION_PAG 0x00000008L /* page formatting ON */
#define OPTION_CON 0x00000010L /* print cond. skipped code */
#define OPTION_MAC 0x00000020L /* print macro calling line (default)*/
#define OPTION_EXP 0x00000040L /* print macro expansion lines */
#define OPTION_SYM 0x00000080L /* print symbol table (default) */
#define OPTION_MUL 0x00000100L /* print multiple oc lines (default) */
#define OPTION_LP1 0x00000200L /* print pass 1 listing */
#define OPTION_DAT 0x00000400L /* print date in listing (default) */
#define OPTION_NUM 0x00000800L /* print line numbers */
#define OPTION_INV 0x00001000L /* print invisible lines */
#define OPTION_TSC 0x00002000L /* TSC-compatible source format */
#define OPTION_WAR 0x00004000L /* print warnings */
#define OPTION_CLL 0x00008000L /* check line length (default) */
#define OPTION_LFN 0x00010000L /* print long file names */
#define OPTION_LLL 0x00020000L /* list library lines */
#define OPTION_GAS 0x00040000L /* Gnu AS compatibility */
#define OPTION_REL 0x00080000L /* print relocation table */
#define OPTION_TXT 0x00100000L /* print text table */
#define OPTION_LIS 0x00200000L /* print assembler output listing */
#define OPTION_LPA 0x00400000L /* listing in f9dasm patch format */
#define OPTION_RTF 0x00800000L
#define OPTION_X32 0x01000000L /* 32 bit index registers */
#define OPTION_X16 0x02000000L /* 32 bit index registers */
 
struct
{
char *Name;
unsigned long dwAdd;
unsigned long dwRem;
} Options[] =
{/*Name Add Remove */
{ "PAG", OPTION_PAG, 0 },
{ "NOP", 0, OPTION_PAG },
{ "CON", OPTION_CON, 0 },
{ "NOC", 0, OPTION_CON },
{ "MAC", OPTION_MAC, 0 },
{ "NOM", 0, OPTION_MAC },
{ "EXP", OPTION_EXP, 0 },
{ "NOE", 0, OPTION_EXP },
{ "SYM", OPTION_SYM, 0 },
{ "NOS", 0, OPTION_SYM },
{ "MUL", OPTION_MUL, 0 },
{ "NMU", 0, OPTION_MUL },
{ "LP1", OPTION_LP1, 0 },
{ "NO1", 0, OPTION_LP1 },
{ "DAT", OPTION_DAT, 0 },
{ "NOD", 0, OPTION_DAT },
{ "NUM", OPTION_NUM, 0 },
{ "NON", 0, OPTION_NUM },
{ "INV", OPTION_INV, 0 },
{ "NOI", 0, OPTION_INV },
{ "TSC", OPTION_TSC, 0 },
{ "NOT", 0, OPTION_TSC },
{ "WAR", OPTION_WAR, 0 },
{ "NOW", 0, OPTION_WAR },
{ "CLL", OPTION_CLL, 0 },
{ "NCL", 0, OPTION_CLL },
{ "LFN", OPTION_LFN, 0 },
{ "NLF", 0, OPTION_LFN },
{ "LLL", OPTION_LLL, 0 },
{ "NLL", 0, OPTION_LLL },
{ "GAS", OPTION_GAS, 0 },
{ "NOG", 0, OPTION_GAS },
{ "REL", OPTION_REL, 0 },
{ "NOR", 0, OPTION_REL },
{ "H63", OPTION_H63, OPTION_M09 | OPTION_M00 },
{ "M68", OPTION_M09, OPTION_H63 | OPTION_M00 },
{ "M09", OPTION_M09, OPTION_H63 | OPTION_M00 },
{ "M00", OPTION_M00, OPTION_H63 | OPTION_M09 },
{ "TXT", OPTION_TXT, 0 },
{ "NTX", 0, OPTION_TXT },
{ "LIS", OPTION_LIS, 0 },
{ "NOL", 0, OPTION_LIS },
{ "LPA", OPTION_LPA, OPTION_NUM | OPTION_CLL }, // LPA inhibits NUM / CLL!
{ "NLP", 0, OPTION_LPA },
{ "X32", OPTION_X32, OPTION_X16 },
{ "X16", OPTION_X16, OPTION_X32 }
};
 
unsigned long dwOptions = /* options flags, init to default */
OPTION_M09 |
OPTION_MAC |
OPTION_SYM |
OPTION_MUL |
OPTION_DAT |
OPTION_WAR |
OPTION_CLL |
OPTION_LLL |
OPTION_REL |
OPTION_LIS;
 
/*****************************************************************************/
/* arrays of error/warning messages */
/*****************************************************************************/
/* defined error flags */
#define ERR_OK 0x0000 /* all is well */
#define ERR_EXPR 0x0001 /* Error in expression */
#define ERR_ILLEGAL_ADDR 0x0002 /* Illegal adressing mode */
#define ERR_LABEL_UNDEF 0x0004 /* Undefined label */
#define ERR_LABEL_MULT 0x0008 /* Label multiply defined */
#define ERR_RANGE 0x0010 /* Relative branch out of range */
#define ERR_LABEL_MISSING 0x0020 /* Missing label */
#define ERR_OPTION_UNK 0x0040 /* Option unknown */
#define ERR_MALLOC 0x0080 /* Out of memory */
#define ERR_NESTING 0x0100 /* Nesting not allowed */
#define ERR_RELOCATING 0x0200 /* Statement not valid for reloc mode*/
#define ERR_ERRTXT 0x4000 /* ERR text output */
#define ERR_ILLEGAL_MNEM 0x8000 /* Illegal mnemonic */
 
char *errormsg[]=
{
"Error in expression", /* 1 ERR_EXPR */
"Illegal addressing mode", /* 2 ERR_ILLEGAL_ADDR */
"Undefined label", /* 4 ERR_LABEL_UNDEF */
"Multiple definitions of label", /* 8 ERR_LABEL_MULT */
"Relative branch out of range", /* 16 ERR_RANGE */
"Missing label", /* 32 ERR_LABEL_MISSING */
"Unknown option specified", /* 64 ERR_OPTION_UNK */
"Out of memory", /* 128 ERR_MALLOC */
"Nesting not allowed", /* 256 ERR_NESTING */
"Illegal for current relocation mode",/* 512 ERR_RELOCATING */
"", /* 1024 */
"", /* 2048 */
"", /* 4096 */
"", /* 8192 */
NULL, /* 16384 ERR_ERRTXT (ERR output) */
"Illegal mnemonic" /* 32768 ERR_ILLEGAL_MNEM */
};
 
/* defined warning flags */
#define WRN_OK 0x0000 /* All OK */
#define WRN_OPT 0x0001 /* Long branch in short range */
#define WRN_SYM 0x0002 /* Symbolic text undefined */
#define WRN_AREA 0x0004 /* Area already in use */
#define WRN_AMBIG 0x0008 /* Ambiguous 6800 opcode */
 
char *warningmsg[] =
{
"Long branch within short branch " /* 1 WRN_OPT */
"range could be optimized",
"Symbolic text undefined", /* 2 WRN_SYM */
"Area already in use", /* 4 WRN_AREA */
"Ambiguous 6800 alternate notation", /* 8 WRN_AMBIG */
"", /* 16 */
"", /* 32 */
"", /* 64 */
"", /* 128 */
"", /* 256 */
"", /* 512 */
"", /* 1024 */
"", /* 2048 */
"", /* 4096 */
"", /* 8192 */
"", /* 18384 */
"" /* 32768 */
};
 
/*****************************************************************************/
/* Listing Definitions */
/*****************************************************************************/
 
#define LIST_OFF 0x00 /* listing is generally off */
#define LIST_ON 0x01 /* listing is generally on */
 
char listing = LIST_OFF; /* listing flag */
 
/*****************************************************************************/
/* Global variables */
/*****************************************************************************/
 
FILE *listfile = NULL; /* list file */
FILE *objfile = NULL; /* object file */
char listname[FNLEN + 1]; /* list file name */
char objname[FNLEN + 1]; /* object file name */
char srcname[FNLEN + 1]; /* source file name */
 
/* assembler mode specifics: */
struct oprecord *optable = optable09; /* used op table */
/* size of this table */
int optablesize = sizeof(optable09) / sizeof(optable09[0]);
struct regrecord *regtable = regtable09;/* used register table */
/* used bit register table */
struct regrecord *bitregtable = bitregtable09;
void scanoperands09(struct relocrecord *pp);
void (*scanoperands)(struct relocrecord *) = scanoperands09;
 
char pass; /* Assembler pass = 1 or 2 */
char relocatable = 0; /* relocatable object flag */
char absmode = 1; /* absolute mode */
long global = 0; /* all labels global flag */
long common = 0; /* common definition flag */
struct symrecord * commonsym = NULL; /* current common main symbol */
char terminate; /* termination flag */
char generating; /* code generation flag */
unsigned loccounter,oldlc; /* Location counter */
 
char inpline[LINELEN]; /* Current input line (not expanded) */
char srcline[LINELEN]; /* Current source line */
char * srcptr; /* Pointer to line being parsed */
 
char unknown; /* flag to indicate value unknown */
char certain; /* flag to indicate value is certain at pass 1*/
long error; /* flags indicating errors in current line. */
long errors; /* number of errors in current pass */
long warning; /* flags indicating warnings in current line */
long warnings; /* number of warnings in current pass */
long nTotErrors; /* total # of errors */
long nTotWarnings; /* total # warnings */
char exprcat; /* category of expression being parsed, eg.
label or constant, this is important when
generating relocatable object code. */
 
int maxidlen = MAXIDLEN; /* maximum ID length */
 
char modulename[MAXIDLEN + 1] = ""; /* module name buffer */
char namebuf[MAXIDLEN + 1]; /* name buffer for parsing */
char unamebuf[MAXIDLEN + 1]; /* name buffer in uppercase */
 
char isFar,isFarkw;
int vercount;
char mode;
char isX32;
char isPostIndexed;
 
/* adressing mode: */
#define ADRMODE_IMM 0 /* 0 = immediate */
#define ADRMODE_DIR 1 /* 1 = direct */
#define ADRMODE_EXT 2 /* 2 = extended */
#define ADRMODE_IDX 3 /* 3 = indexed */
#define ADRMODE_POST 4 /* 4 = postbyte */
#define ADRMODE_PCR 5 /* 5 = PC relative (with postbyte) */
#define ADRMODE_IND 6 /* 6 = indirect */
#define ADRMODE_PIN 7 /* 7 = PC relative & indirect */
#define ADRMODE_DBL_IND 8
 
char opsize; /* desired operand size : */
/* 0=dunno,1=5, 2=8, 3=16, 4=32 */
long operand;
unsigned short postbyte;
 
long dpsetting = 0; /* Direct Page Default = 0 */
 
unsigned short codebuf[256];
int codeptr; /* byte offset within instruction */
int suppress; /* 0=no suppress */
/* 1=until ENDIF */
/* 2=until ELSE */
/* 3=until ENDM */
char condline = 0; /* flag whether on conditional line */
int ifcount; /* count of nested IFs within */
/* suppressed text */
 
#define OUT_NONE -1 /* no output */
#define OUT_BIN 0 /* binary output */
#define OUT_SREC 1 /* Motorola S-Records */
#define OUT_IHEX 2 /* Intel Hex Records */
#define OUT_FLEX 3 /* Flex9 ASMB-compatible output */
#define OUT_GAS 4 /* GNU relocation output */
#define OUT_REL 5 /* Flex9 RELASMB output */
#define OUT_VER 6
int outmode = OUT_BIN; /* default to binary output */
 
unsigned hexaddr;
int hexcount;
unsigned short hexbuffer[256];
unsigned int chksum;
unsigned vslide;
 
int nRepNext = 0; /* # repetitions for REP pseudo-op */
int nSkipCount = 0; /* # lines to skip */
 
unsigned short tfradr = 0;
int tfradrset = 0;
 
int nCurLine = 0; /* current output line on page */
int nCurCol = 0; /* current output column on line */
int nCurPage = 0; /* current page # */
int nLinesPerPage = 66; /* # lines on a page */
int nColsPerLine = 200; /* # columns per line */
char szTitle[128] = ""; /* title for listings */
char szSubtitle[128] = ""; /* subtitle for listings */
 
char szBuf1[LINELEN]; /* general-purpose buffers for parse */
char szBuf2[LINELEN];
 
struct linebuf *macros[MAXMACROS]; /* pointers to the macros */
int nMacros = 0; /* # parsed macros */
int inMacro = 0; /* flag whether in macro definition */
 
char *texts[MAXTEXTS]; /* pointers to the texts */
int nPredefinedTexts = 0; /* # predefined texts */
int nTexts = 0; /* # currently defined texts */
 
//unsigned char bUsedBytes[8192] = {0}; /* 1 bit per byte of the address spc */
 
/*****************************************************************************/
/* Necessary forward declarations */
/*****************************************************************************/
 
void processline();
struct linebuf *readfile(char *name, unsigned char lvl, struct linebuf *after);
struct linebuf *readbinary(char *name, unsigned char lvl, struct linebuf *after, struct symrecord *lp);
 
/*****************************************************************************/
/* allocline : allocates a line of text */
/*****************************************************************************/
 
struct linebuf * allocline
(
struct linebuf *prev,
char *fn,
int line,
unsigned char lvl,
char *text
)
{
struct linebuf *pNew = malloc(sizeof(struct linebuf) + strlen(text));
if (!pNew)
return NULL;
pNew->next = (prev) ? prev->next : NULL;
pNew->prev = prev;
if (prev)
prev->next = pNew;
if (pNew->next)
pNew->next->prev = pNew;
pNew->lvl = lvl;
pNew->fn = fn;
pNew->ln = line;
pNew->rel = ' ';
strcpy(pNew->txt, text);
return pNew;
}
 
/*****************************************************************************/
/* expandfn : eventually expands a file name to full-blown path */
/*****************************************************************************/
 
char const *expandfn(char const *fn)
{
#ifdef WIN32
static char szBuf[_MAX_PATH]; /* allocate big buffer */
 
if (dwOptions & OPTION_LFN) /* if long file names wanted */
return _fullpath(szBuf, fn, sizeof(szBuf));
#endif
 
return fn; /* can't do that yet */
}
 
/*****************************************************************************/
/* PageFeed : advances the list file */
/*****************************************************************************/
 
void PageFeed()
{
time_t tim;
struct tm *ltm;
 
time(&tim);
ltm = localtime(&tim);
 
fputc('\x0c', listfile); /* print header */
nCurPage++; /* advance to next page */
fprintf(listfile, "\n\n%-32.32s ", szTitle);
if (dwOptions & OPTION_DAT)
fprintf(listfile,
"%04d-%02d-%02d ",
ltm->tm_year + 1900,
ltm->tm_mon + 1,
ltm->tm_mday);
fprintf(listfile,
"A09 %d Assembler V" VERSION " Page %d\n",
(dwOptions & OPTION_H63) ? 6309 :
(dwOptions & OPTION_M00) ? 6800 :
6809,
nCurPage);
fprintf(listfile, "%-.79s\n\n", szSubtitle);
 
nCurLine = 5; /* remember current line */
nCurCol = 0; /* and reset current column */
}
 
/*****************************************************************************/
/* putlist : puts something to the list file */
/*****************************************************************************/
 
void putlist(char *szFmt, ...)
{
char szList[1024]; /* buffer for 1k list output */
char *p;
 
va_list al;
va_start(al, szFmt);
vsprintf(szList, szFmt, al); /* generate formatted output buffer */
va_end(al);
 
for (p = szList; *p; p++) /* then walk through the buffer */
{
fputc(*p, listfile); /* print out each character */
if (*p == '\n') /* if newline sent */
{
nCurLine++;
nCurCol = 0;
if ((nCurLine >= nLinesPerPage) && /* if beyond # lines per page */
(dwOptions & OPTION_PAG)) /* if pagination activated */
PageFeed(); /* do a page feed */
}
else /* if another character */
{
nCurCol++; /* advance to next column */
if (dwOptions & OPTION_CLL) /* if line length checked */
{
/* check if word would go too far */
if ((nCurCol >= nColsPerLine * 3 / 4) &&
(*p == ' '))
{
int i; /* look whether more delimiters */
char c;
for (i = nCurCol + 1; i < nColsPerLine; i++)
{
c = p[i - nCurCol];
if ((c == '\t') || (c == ' ') || (!c))
break;
}
if (i >= nColsPerLine) /* if no more delimiters, */
nCurCol = nColsPerLine; /* make sure to advance to new line */
}
 
if (nCurCol >= nColsPerLine) /* if it IS too far */
{
putlist("\n"); /* recurse with a newline */
nCurCol = 0;
}
}
}
}
}
 
/*****************************************************************************/
/* findop : finds a mnemonic in table using binary search */
/*****************************************************************************/
 
struct oprecord * findop(char * nm)
{
int lo,hi,i,s;
 
lo = 0;
hi = optablesize - 1;
do
{
i = (lo + hi) / 2;
s = strcmp(optable[i].name, nm);
if (s < 0)
lo = i + 1;
else if (s > 0)
hi = i - 1;
else
break;
} while (hi >= lo);
if (s)
return NULL;
return optable + i;
}
 
/*****************************************************************************/
/* findlocal : finds a local symbol table record */
/*****************************************************************************/
 
struct symrecord * findlocal(struct symrecord *sym, char forward, int insert)
{
static struct symrecord empty = {"", SYMCAT_EMPTYLOCAL, 0, {0}};
int lo,hi,i,j,s;
 
if ((!sym) || /* if no main symbol for that */
((!insert) && /* or not inserting, but */
(sym->cat == SYMCAT_EMPTYLOCAL))) /* yet undefined label */
return sym; /* pass back main symbol */
 
lo = 0; /* do binary search for the thing */
hi = lclcounter - 1;
s = 1;
i = 0;
while (hi >= lo)
{
i = (lo + hi) / 2;
s = lcltable[i].value - loccounter; /* binary search for current address */
if (s < 0)
lo = i + 1;
else if (s > 0)
hi = i - 1;
else /* if found, */
{ /* go to 1st of this value */
while ((i) && (lcltable[i - 1].value == loccounter))
i--;
while ((i < lclcounter) && /* search for the NAME now */
(lcltable[i].value == loccounter))
{
s = strcmp(sym->name, lcltable[i].name);
if (s <= 0)
{
if (s)
i--;
break;
}
i++;
}
if (s) /* if not found, re-set */
{
if (i >= lclcounter)
s = 1;
else
s = lcltable[i].value - loccounter;
}
break;
}
}
 
if (insert) /* if inserting, */
{
if (!s) /* if address is already in use */
{ /* but not the correct label */
if (strcmp(sym->name, lcltable[i].name))
error |= ERR_LABEL_MULT; /* set error */
return lcltable + i; /* return the local symbol */
}
i = (s < 0 ? i + 1 : i);
if (lclcounter == MAXLABELS)
{
printf("%s(%ld): error 25: out of local symbol storage\n",
expandfn(curline->fn), curline->ln);
if (((dwOptions & OPTION_LP1) || pass == MAX_PASSNO) && (listing & LIST_ON))
putlist( "*** Error 25: out of local symbol storage\n");
exit(4);
}
sym->cat = SYMCAT_LOCALLABEL;
for (j = lclcounter; j > i; j--)
lcltable[j] = lcltable[j - 1];
lclcounter++;
strcpy(lcltable[i].name, sym->name);
lcltable[i].cat = SYMCAT_LOCALLABEL;
lcltable[i].value = loccounter;
lcltable[i].u.parent = NULL;
return lcltable + i; /* pass back this symbol */
}
 
if (forward) /* if forward search */
{
i = (s < 0 ? i - 1 : i);
for (; i < lclcounter; i++)
{
if ((!strcmp(lcltable[i].name, sym->name)) &&
(lcltable[i].value > loccounter))
return lcltable + i;
}
}
else /* if backward search */
{
i = (s > 0 ? i + 1 : i);
for (; i >= 0; i--)
{
if ((!strcmp(lcltable[i].name, sym->name)) &&
(lcltable[i].value <= loccounter))
return lcltable + i;
}
}
 
return &empty; /* if not found, return empty label */
}
 
/*****************************************************************************/
/* findsym : finds symbol table record; inserts if not found */
/* uses binary search, maintains sorted table */
/*****************************************************************************/
 
struct symrecord * findsym (char * nm, int insert)
{
int lo,hi,i,j,s;
char islocal = 0, forward = 0;
char name[MAXIDLEN + 1] = "";
/* copy name to internal buffer */
strncpy(name, (nm) ? nm : "", sizeof(name) - 1);
for (i = 0; name[i]; i++) /* determine whether local label */
if ((name[i] < '0') || (name[i] > '9'))
break;
if (i) /* if starting with number */
{
if (!name[i]) /* if ONLY numeric */
islocal = 1; /* this is a local label */
else /* otherwise check direction */
{
switch(toupper(name[i]))
{
case 'B' : /* backward reference ? */
islocal = 2; /* this is a local label reference */
forward = 0;
break;
case 'F' : /* forward reference ? */
islocal = 2; /* this is a local label reference */
forward = 1;
break;
}
if (islocal && name[i + 1]) /* if followed by anything else */
islocal = 0; /* reset flag for local label */
else /* otherwise */
name[i] = 0; /* remove the direction */
}
}
 
lo = 0; /* do binary search for the thing */
hi = symcounter - 1;
s = 1;
i = 0;
while (hi >= lo)
{
i = (lo + hi) / 2;
s = strcmp(symtable[i].name, name);
if (s < 0)
lo = i + 1;
else if (s > 0)
hi = i - 1;
else
break;
}
 
if (s) /* if symbol not found */
{
if (!insert) /* if inserting prohibited, */
return NULL; /* return without pointer */
 
i = (s < 0 ? i + 1 : i);
if (symcounter == MAXLABELS)
{
printf("%s(%ld): error 23: out of symbol storage\n",
expandfn(curline->fn), curline->ln);
if (((dwOptions & OPTION_LP1) || pass == MAX_PASSNO) && (listing & LIST_ON))
putlist( "*** Error 23: out of symbol storage\n");
exit(4);
}
if (commonsym >= symtable + i)
commonsym++;
for (j = 0; j < symcounter; j++)
if (symtable[j].u.parent >= symtable + i)
symtable[j].u.parent++;
for (j = symcounter; j > i; j--)
symtable[j] = symtable[j-1];
symcounter++;
strcpy(symtable[i].name, name);
symtable[i].cat = (islocal) ? SYMCAT_EMPTYLOCAL : SYMCAT_EMPTY;
symtable[i].value = 0;
symtable[i].u.flags = 0;
}
 
if (islocal) /* if searching for a local label */
return findlocal(symtable + i, /* search for the local label */
forward, (islocal < 2));
 
return symtable + i; /* return the found or inserted sym */
}
 
/*****************************************************************************/
/* findsymat : finds 1st symbol fo a given address */
/*****************************************************************************/
 
char *findsymat(unsigned addr)
{
/* since the symbol table is sorted by name, this needs a sequential search */
int i;
for (i = 0; i < symcounter; i++)
if (symtable[i].cat != SYMCAT_EMPTY)
{
if (symtable[i].cat == SYMCAT_TEXT)
continue;
if (symtable[i].value == addr)
return symtable[i].name;
}
return NULL;
}
 
/*****************************************************************************/
/* settext : sets a text symbol */
/*****************************************************************************/
 
int settext(char *namebuf, char *text)
{
struct symrecord *lp = findsym(namebuf, 1);
int len;
int special = 0;
 
if (!lp)
{
error |= ERR_LABEL_UNDEF;
return -1;
}
if (lp->cat != SYMCAT_EMPTY &&
lp->cat != SYMCAT_TEXT)
{
error |= ERR_LABEL_MULT;
return -1;
}
 
if (lp->cat != SYMCAT_EMPTY)
free(texts[lp->value]);
else if (nTexts >= MAXTEXTS)
{
error |= ERR_MALLOC;
return -1;
}
else
{
lp->cat = SYMCAT_TEXT;
lp->value = nTexts++;
}
 
if (!text) /* if NULL input */
text = ""; /* assume empty string */
 
for (len = 0; text[len]; len++)
if ((isspace(text[len])) ||
(text[len] == ','))
special = 1;
if (!len) /* empty string? */
special = 1; /* that's special anyway. */
if (special && len && /* if delimited special string */
(text[0] == '\'' || text[0] == '\"') &&
(text[len - 1] == text[0]))
special = 0; /* forget that "special" flag */
 
len += (special) ? 3 : 1;
texts[lp->value] = malloc(len);
if (texts[lp->value])
{
if (special)
texts[lp->value][0] = '\"';
strcpy(texts[lp->value] + special, text);
if (special)
strcat(texts[lp->value], "\"");
}
 
return lp->value;
}
 
/*****************************************************************************/
/* outsymtable : prints the symbol table */
/*****************************************************************************/
 
void outsymtable()
{
int i,j = 0;
 
if (dwOptions & OPTION_PAG) /* if pagination active, */
{
if (nCurLine > 5) /* if not on 1st line, */
PageFeed(); /* shift to next page */
}
else
putlist("\n");
 
putlist("SYMBOL TABLE");
for (i = 0; i < symcounter; i++)
if (symtable[i].cat != SYMCAT_EMPTY)
{
/* suppress listing of predef texts */
if ((symtable[i].cat == SYMCAT_TEXT) &&
(symtable[i].value < nPredefinedTexts))
continue;
/* if local label */
if (symtable[i].cat == SYMCAT_LOCALLABEL)
{
int k; /* walk local label list */
for (k = 0; k < lclcounter; k++)
if (!strcmp(lcltable[k].name, symtable[i].name))
{
if (j % 4 == 0)
putlist("\n");
putlist( " %9s %02d %08X", lcltable[k].name, lcltable[k].cat,
lcltable[k].value);
j++;
}
}
else /* if normal label */
{
if (j % 4 == 0)
putlist("\n");
putlist( " %9s %02d %08X", symtable[i].name,symtable[i].cat,
symtable[i].value);
j++;
}
}
putlist("\n%d SYMBOLS\n", j);
}
 
/*****************************************************************************/
/* outreltable : prints the relocation table */
/*****************************************************************************/
 
void outreltable()
{
int i,j = 0;
 
if (dwOptions & OPTION_PAG) /* if pagination active, */
{
if (nCurLine > 5) /* if not on 1st line, */
PageFeed(); /* shift to next page */
}
else
putlist("\n");
 
putlist("RELOCATION TABLE");
for (i = 0; i < relcounter; i++)
{
char name[10];
sprintf(name, "%c%-.8s",
(reltable[i].exprcat & EXPRCAT_NEGATIVE) ? '-' : ' ',
reltable[i].sym->name);
if (j % 4 == 0)
putlist("\n");
putlist( " %9s %02d %04X",
name,
reltable[i].sym->cat,
reltable[i].addr);
j++;
}
putlist("\n%d RELOCATIONS\n", j);
}
 
/*****************************************************************************/
/* outtexttable : prints the text table */
/*****************************************************************************/
 
void outtexttable()
{
int i,j = 0;
 
if (dwOptions & OPTION_PAG) /* if pagination active, */
{
if (nCurLine > 5) /* if not on 1st line, */
PageFeed(); /* shift to next page */
}
else
putlist("\n");
 
putlist("TEXT TABLE");
for (i = 0; i < symcounter; i++)
if (symtable[i].cat == SYMCAT_TEXT)
{
/* suppress listing of predef texts */
if (symtable[i].value < nPredefinedTexts)
continue;
putlist("\n %9s %s", symtable[i].name, texts[symtable[i].value]);
j++;
}
putlist("\n%d TEXTS\n", j);
}
 
/*****************************************************************************/
/* findreg : finds a register per name */
/*****************************************************************************/
 
struct regrecord * findreg(char *nm)
{
int i;
for (i = 0; regtable[i].name != NULL; i++)
{
if (strcmp(regtable[i].name,nm) == 0)
return regtable + i;
}
return 0;
}
 
/*****************************************************************************/
/* findreg63 : finds a register per name for HD63 operations */
/*****************************************************************************/
 
struct regrecord * findreg63(char *nm)
{
int i;
for (i = 0; i < (sizeof(regtable63) / sizeof(regtable63[0])); i++)
{
if (strcmp(regtable63[i].name,nm) == 0)
return regtable63 + i;
}
return 0;
}
 
/*****************************************************************************/
/* findbitreg : finds a bit transfer register per name (6309 only) */
/*****************************************************************************/
 
struct regrecord * findbitreg(char *nm)
{
int i;
for (i = 0; i < (sizeof(bitregtable) / sizeof(bitregtable[0])); i++)
{
if (strcmp(bitregtable[i].name,nm) == 0)
return bitregtable + i;
}
return 0;
}
 
/*****************************************************************************/
/* strupr : converts a string to uppercase (crude) */
/*****************************************************************************/
 
char *strupr(char *name)
{
int i;
if (!name)
return name;
for (i = 0; name[i]; i++)
if ((name[i] >= 'a') && (name[i] <= 'z'))
name[i] -= ('a' - 'A');
return name;
}
 
/*****************************************************************************/
/* addreloc : adds a relocation record to the list */
/*****************************************************************************/
 
void addreloc(struct relocrecord *p)
{
struct relocrecord rel = {0}; /* internal copy */
 
if (p) /* if there's a record, */
rel = *p; /* copy to internal */
 
if ((!relocatable) || /* if generating unrelocatable binary*/
(!rel.sym) || /* or no symbol */
(pass == 1)) /* or in pass 1 */
return; /* do nothing here */
 
switch (rel.sym->cat) /* check symbol category */
{
case SYMCAT_PUBLIC : /* public label ? */
case SYMCAT_LABEL : /* normal label ? */
case SYMCAT_EXTERN : /* external symbol ? */
break; /* these are allowed */
case SYMCAT_COMMONDATA : /* Common data ? */
rel.sym = rel.sym->u.parent; /* switch to COMMON block */
break; /* and allow it. */
default : /* anything else */
return; /* isn't */
}
 
if (relcounter >= MAXRELOCS) /* if no more space */
{ /* should NEVER happen... but then...*/
error |= ERR_MALLOC; /* set mem alloc err */
return; /* and get out of here */
}
 
reltable[relcounter++] = rel; /* add relocation record */
 
switch (p->sym->cat) /* do specials... */
{
case SYMCAT_PUBLIC : /* public label ? */
case SYMCAT_LABEL : /* normal label ? */
case SYMCAT_COMMONDATA : /* common data ? */
curline->rel = /* remember there's a relocation */
(p->exprcat & EXPRCAT_NEGATIVE) ? '-' : '+';
break;
case SYMCAT_EXTERN : /* external symbol ? */
curline->rel =
(p->exprcat & EXPRCAT_NEGATIVE) ? 'x' : 'X';
break;
}
 
}
 
/*****************************************************************************/
/* scanname : scans a name from the input buffer */
/*****************************************************************************/
 
void scanname()
{
int i = 0;
char c;
char cValid;
 
while (1)
{
c = *srcptr++;
if ((!(dwOptions & OPTION_TSC)) && /* TSC Assembler is case-sensitive */
(!(dwOptions & OPTION_GAS)) && /* GNU Assembler is case-sensitive */
(c >= 'a' && c <= 'z'))
c -= 32;
cValid = 0; /* check for validity */
if ((c >= '0' && c <= '9') || /* normally, labels may consist of */
(c >= 'A' && c <= 'Z') || /* the characters A..Z,a..z,_ */
(c >= 'a' && c <= 'z') ||
(c == '_'))
cValid = 1;
if (dwOptions & OPTION_GAS) /* for GNU AS compatibility, */
{ /* the following rules apply: */
if ((c == '.') || /* .$ are valid symbol characters */
(c == '$'))
cValid = 1;
}
if (!cValid) /* if invalid character encountered */
break; /* stop here */
 
if (i < maxidlen)
{
namebuf[i] = c;
unamebuf[i] = toupper(c);
i++;
}
}
namebuf[i] = '\0';
unamebuf[i] = '\0';
srcptr--;
}
 
/*****************************************************************************/
/* skipspace : skips whitespace characters */
/*****************************************************************************/
 
void skipspace()
{
char c;
do
{
c = *srcptr++;
} while (c == ' ' || c == '\t');
srcptr--;
}
 
long scanexpr(int, struct relocrecord *);
 
/*****************************************************************************/
/* scandecimal : scans a decimal number */
/*****************************************************************************/
 
long scandecimal()
{
char c;
long t = 0;
c = *srcptr++;
while (isdigit(c))
{
t = t * 10 + c - '0';
c = *srcptr++;
}
srcptr--;
return t;
}
 
/*****************************************************************************/
/* scanhex : scans hex number */
/*****************************************************************************/
 
long scanhex()
{
long t = 0, i = 0;
 
srcptr++;
scanname();
while (unamebuf[i] >= '0' && unamebuf[i] <= 'F')
{
t = t * 16 + unamebuf[i] - '0';
if (unamebuf[i] > '9')
t -= 7;
i++;
}
if (i==0)
error |= ERR_EXPR;
return t;
}
 
/*****************************************************************************/
/* scanchar : scan a character */
/*****************************************************************************/
 
long scanchar()
{
long t;
 
srcptr++;
t = *srcptr;
if (t)
srcptr++;
if (*srcptr == '\'')
srcptr++;
return t;
}
 
/*****************************************************************************/
/* scanbin : scans a binary value */
/*****************************************************************************/
 
long scanbin()
{
char c;
short t = 0;
 
srcptr++;
c = *srcptr++;
while (c == '0' || c == '1')
{
t = t * 2 + c - '0';
c = *srcptr++;
}
srcptr--;
return t;
}
 
/*****************************************************************************/
/* scanoct : scans an octal value */
/*****************************************************************************/
 
long scanoct()
{
char c;
long t = 0;
 
srcptr++;
c = *srcptr++;
while (c >= '0' && c <= '7')
{
t = t * 8 + c - '0';
c = *srcptr++;
}
srcptr--;
return t;
}
 
/*****************************************************************************/
/* scanstring : scans a string into a buffer */
/*****************************************************************************/
 
char * scanstring(char *dest, int nlen)
{
char *s = srcptr;
char *d = dest;
int nInString = 0;
char c;
 
if (*srcptr == '\'' || *srcptr == '\"')
{
nInString = 1;
srcptr++;
}
 
while (*srcptr)
{
if (!nInString &&
(*srcptr == ' ' || *srcptr == ','))
break;
else if (nInString && *s == *srcptr)
{
srcptr++;
break;
}
c = *srcptr++;
if (!nInString && c >= 'a' && c <= 'z')
c -= 32;
*d++ = c;
}
*d = '\0';
 
return dest;
}
 
 
/*****************************************************************************/
/* scanlabel : scans a label */
/*****************************************************************************/
 
unsigned scanlabel(struct relocrecord *pp)
{
struct symrecord * p;
 
scanname();
p = findsym(namebuf, 1);
if (p->cat == SYMCAT_EMPTY)
{
p->cat = SYMCAT_UNRESOLVED;
p->value = 0;
p->u.flags |= SYMFLAG_FORWARD;
}
 
if (p->cat == SYMCAT_MACRO ||
p->cat == SYMCAT_PARMNAME ||
p->cat == SYMCAT_TEXT)
error |= ERR_EXPR;
exprcat = p->cat & (EXPRCAT_PUBLIC | EXPRCAT_EXTADDR | EXPRCAT_INTADDR);
if (exprcat == (EXPRCAT_EXTADDR | EXPRCAT_INTADDR) ||
exprcat == (EXPRCAT_PUBLIC | EXPRCAT_INTADDR))
unknown = 1;
 
#if 1
/* anything that's not yet defined is uncertain in pass 2! */
if ((p->u.flags & (SYMFLAG_FORWARD | SYMFLAG_PASSED)) == SYMFLAG_FORWARD)
certain = 0;
#else
if (((exprcat == EXPRCAT_INTADDR ||
exprcat == EXPRCAT_PUBLIC) &&
// (unsigned short)(p->value) > (unsigned short)loccounter) ||
// (p->u.flags & SYMFLAG_FORWARD)) ||
((p->u.flags & (SYMFLAG_FORWARD | SYMFLAG_PASSED)) == SYMFLAG_FORWARD)) ||
exprcat == EXPRCAT_EXTADDR)
certain = 0;
#endif
if ((!absmode) && /* if in relocating mode */
(exprcat)) /* and this is not a constant */
certain = 0; /* this is NOT certain */
if (exprcat == EXPRCAT_PUBLIC ||
exprcat == (EXPRCAT_EXTADDR | EXPRCAT_INTADDR) ||
exprcat == (EXPRCAT_PUBLIC | EXPRCAT_INTADDR))
exprcat = EXPRCAT_INTADDR;
if (pp)
{
pp->exprcat = exprcat;
pp->sym = p;
}
if (p->isFar)
isFar = 1;
if (p->isFarkw)
isFarkw = 1;
return p->value;
}
/*****************************************************************************/
/* isfactorstart : returns whether passed character possibly starts a factor */
/*****************************************************************************/
 
int isfactorstart(char c)
{
if (isalpha(c))
return 1;
else if (isdigit(c))
return 1;
else switch (c)
{
case '*' :
case '$' :
case '%' :
case '@' :
case '\'' :
case '(' :
case '-' :
case '+' :
case '!' :
case '~' :
return 1;
}
return 0;
}
 
/*****************************************************************************/
/* scanfactor : scans an expression factor */
/*****************************************************************************/
 
long scanfactor(struct relocrecord *p)
{
char c;
long t;
 
if (!(dwOptions & OPTION_TSC))
skipspace();
c = *srcptr;
if (isalpha(c))
return (unsigned)scanlabel(p);
else if (isdigit(c))
{
char *locptr = srcptr; /* watch out for local labels */
char caft;
while ((*locptr >= '0') && /* advance to next nonnumeric */
(*locptr <= '9'))
locptr++;
caft = toupper(*locptr); /* get next character in uppercase */
if ((caft == 'B') || (caft == 'F')) /* if this might be a local reference*/
return scanlabel(p); /* look it up. */
switch (c)
{
case '0' : /* GNU AS bin/oct/hex? */
if (dwOptions & OPTION_GAS) /* if GNU AS extensions, */
{
if (srcptr[1] == 'b') /* if binary value, */
{
srcptr++; /* advance behind 0 */
return scanbin(); /* and treat rest as binary value */
}
else if (srcptr[1] == 'x') /* if hex value, */
{
srcptr++; /* advance behind 0 */
return scanhex(); /* and treat rest as hex value */
}
return scanoct(); /* otherwise treat as octal */
}
/* else fall thru on purpose */
default : /* decimal in any case ? */
return scandecimal();
}
}
else switch (c)
{
case '*' :
srcptr++;
exprcat |= EXPRCAT_INTADDR;
return loccounter;
case '$' :
return scanhex();
case '%' :
return scanbin();
case '@' :
return scanoct();
case '\'' :
return scanchar();
case '(' :
srcptr++;
t = scanexpr(0, p);
if (!(dwOptions & OPTION_TSC))
skipspace();
if (*srcptr == ')')
srcptr++;
else
error |= ERR_EXPR;
return t;
case '-' :
srcptr++;
t = scanfactor(p);
exprcat ^= EXPRCAT_NEGATIVE;
if (p)
p->exprcat ^= EXPRCAT_NEGATIVE;
return -t;
case '+' :
srcptr++;
return scanfactor(p);
case '!' :
srcptr++;
exprcat |= EXPRCAT_FIXED;
return !scanfactor(p);
case '~' :
srcptr++;
exprcat |= EXPRCAT_FIXED;
return ~scanfactor(p);
}
error |= ERR_EXPR;
return 0;
}
 
/*****************************************************************************/
/* some nice macros */
/*****************************************************************************/
 
/*define EXITEVAL { srcptr--; return t; } */
#define EXITEVAL { srcptr--; parsing = 0; break; }
 
#define RESOLVECAT if((oldcat & 15) == 0) oldcat = 0; \
if ((exprcat & 15) == 0)exprcat = 0; \
if ((exprcat == EXPRCAT_INTADDR && \
oldcat == (EXPRCAT_INTADDR | EXPRCAT_NEGATIVE)) || \
(exprcat == (EXPRCAT_INTADDR | EXPRCAT_NEGATIVE)&& \
oldcat == EXPRCAT_INTADDR)) \
{ \
exprcat = 0; \
oldcat = 0; \
} \
exprcat |= oldcat;
/* resolve such cases as constant added to address or difference between
two addresses in same module */
 
/*****************************************************************************/
/* scanexpr : scan expression */
/*****************************************************************************/
 
long scanexpr(int level, struct relocrecord *pp) /* This is what you call _recursive_ descent!!!*/
{
long t, u;
char oldcat,c,parsing=1;
struct relocrecord ip = {0}, p = {0};
 
exprcat = 0;
if (level == 10)
return scanfactor(pp);
t = scanexpr(level + 1, &ip);
/* ip.exprcat = exprcat; */
while (parsing)
{
p.sym = NULL;
if (!(dwOptions & OPTION_TSC))
skipspace();
c = *srcptr++;
switch(c)
{
case '*':
oldcat = exprcat;
t *= scanexpr(10, &p);
exprcat |= oldcat | EXPRCAT_FIXED;
break;
case '/':
oldcat = exprcat;
u = scanexpr(10, &p);
if (u)
t /= u;
else
error |= ERR_EXPR;
exprcat |= oldcat | EXPRCAT_FIXED;
break;
case '%':
oldcat = exprcat;
u = scanexpr(10, &p);
if (u)
t %= u;
else
error |= ERR_EXPR;
exprcat |= oldcat | EXPRCAT_FIXED;
break;
case '+':
if (level == 9)
EXITEVAL
oldcat = exprcat;
t += scanexpr(9, &p);
RESOLVECAT
break;
case '-':
if (level == 9)
EXITEVAL
oldcat = exprcat;
t -= scanexpr(9, &p);
exprcat ^= EXPRCAT_NEGATIVE;
RESOLVECAT
break;
case '<':
if (*(srcptr) == '<')
{
if (level >= 8)
EXITEVAL
srcptr++;
oldcat = exprcat;
t <<= scanexpr(8, &p);
exprcat |= oldcat | EXPRCAT_FIXED;
}
else if (*(srcptr) == '=')
{
if (level >= 7)
EXITEVAL
srcptr++;
oldcat = exprcat;
t = t <= scanexpr(7, &p);
exprcat |= oldcat | EXPRCAT_FIXED;
}
else
{
if (level >= 7)
EXITEVAL
oldcat = exprcat;
t = t < scanexpr(7, &p);
exprcat |= oldcat | EXPRCAT_FIXED;
}
break;
case '>':
if (*(srcptr) == '>')
{
if (level >= 8)
EXITEVAL
srcptr++;
oldcat = exprcat;
t >>= scanexpr(8, &p);
exprcat |= oldcat | EXPRCAT_FIXED;
}
else if (*(srcptr) == '=')
{
if (level>=7)
EXITEVAL
srcptr++;
oldcat = exprcat;
t = t >= scanexpr(7, &p);
exprcat |= oldcat | EXPRCAT_FIXED;
}
else
{
if (level >= 7)
EXITEVAL
oldcat = exprcat;
t = t > scanexpr(7, &p);
exprcat |= oldcat | EXPRCAT_FIXED;
}
break;
case '!':
if (level >= 6 || *srcptr != '=')
EXITEVAL
srcptr++;
oldcat = exprcat;
t = t != scanexpr(6, &p);
exprcat |= oldcat | EXPRCAT_FIXED;
break;
case '=':
if (level >= 6)
EXITEVAL
if (*srcptr == '=')
srcptr++;
oldcat = exprcat;
t = (t == scanexpr(6, &p));
exprcat |= oldcat | EXPRCAT_FIXED;
break;
case '&':
if (level >= 5)
EXITEVAL
oldcat = exprcat;
t &= scanexpr(5, &p);
exprcat |= oldcat | EXPRCAT_FIXED;
break;
case '^':
if (level >= 4)
EXITEVAL
oldcat = exprcat;
t ^= scanexpr(4, &p);
exprcat |= oldcat | EXPRCAT_FIXED;
break;
case '|':
if (level >= 3)
EXITEVAL
oldcat = exprcat;
t |= scanexpr(3, &p);
exprcat |= oldcat | EXPRCAT_FIXED;
break;
default:
EXITEVAL
}
p.exprcat = exprcat;
if (p.sym)
{
if (ip.sym) /* if 2 symbols, cancel 'em */
{
/* a simple safeguard against cancelling local vs. external symbols
or operations between 2 external symbols.
This means that an external symbol has to be the last one in an
expression, or the others have to be paired so that they cancel
each other's effect AND their subexpression has to be parenthesized.*/
if ((ip.sym->cat == SYMCAT_EXTERN) || (p.sym->cat == SYMCAT_EXTERN))
error |= ERR_EXPR;
else
ip.sym = NULL; /* this might be TOO crude... */
}
else /* if new symbol */
ip = p; /* use this one */
}
}
 
*pp = ip;
return t;
}
 
/*****************************************************************************/
/* scanindexreg : scans an index register */
/*****************************************************************************/
 
int scanindexreg()
{
switch (toupper(*srcptr))
{
case 'X':
return 1;
case 'Y':
postbyte |= 0x200;
return 1;
case 'U':
postbyte |= 0x400;
return 1;
case 'S':
postbyte |= 0x600;
return 1;
}
return 0;
}
 
/*****************************************************************************/
/* set3 : sets mode to at least ADRMODE_POST */
/*****************************************************************************/
 
void set3()
{
if (mode < ADRMODE_POST)
mode = ADRMODE_POST;
}
 
/*****************************************************************************/
/* scanspecial : scans for increments */
/*****************************************************************************/
 
void scanspecial()
{
set3();
if (!(dwOptions & OPTION_TSC))
skipspace();
if (*srcptr == '-')
{
srcptr++;
if (*srcptr == '-')
{
srcptr++;
postbyte = 0x803;
}
else
postbyte = 0x802;
 
if ((dwOptions & OPTION_H63) && /* special for ,--W and [,--W] */
(postbyte == 0x803) &&
(toupper(*srcptr) == 'W'))
{
postbyte = (mode == ADRMODE_IND) ? 0x900 : 0x80f;
srcptr++;
}
else if (!scanindexreg())
error |= ERR_ILLEGAL_ADDR;
else
srcptr++;
}
else
{
postbyte = 0x800;
if ((dwOptions & OPTION_H63) && /* special for ,W, [,W], ,W++, [,W++]*/
(toupper(*srcptr) == 'W'))
{
srcptr++; /* advance behind W */
if (*srcptr == '+')
{
srcptr++;
if (*srcptr == '+') /* ,W++ and [,W++] */
{
postbyte = (mode == ADRMODE_IND) ? 0xB00 : 0xA0F;
srcptr++;
}
else
error |= ERR_ILLEGAL_ADDR;
}
else /* ,W and [,W] */
postbyte = (mode == ADRMODE_IND) ? 0x900 : 0x80F;
}
else /* normal index register addressing */
{
if (!scanindexreg())
error |= ERR_ILLEGAL_ADDR;
else
srcptr++;
if (*srcptr == '+')
{
srcptr++;
if (*srcptr == '+')
{
srcptr++;
postbyte += 1;
}
}
else
postbyte += 4;
}
}
}
 
/*****************************************************************************/
/* scanindexed : */
/*****************************************************************************/
 
void scanindexed()
{
set3();
postbyte = 0;
if ((dwOptions & OPTION_H63) && /* special for W as index register */
(toupper(*srcptr) == 'W'))
{
srcptr++;
postbyte = (mode == ADRMODE_IND) ? 0xb00 : 0xa0f;
opsize = 3;
}
else if (scanindexreg())
{
srcptr++;
if (opsize == 0)
{
if (unknown || !certain)
opsize = 3;
else if (operand >= -256 && operand < 256 && mode == ADRMODE_POST)
opsize = 1;
else if (operand >= -2048 && operand < 2048)
opsize = 2;
else if (operand >=-8388608 && operand < 8388608)
opsize = 3;
else
opsize = 4;
}
switch (opsize)
{
case 1:
postbyte += (operand & 511);
opsize = 0;
break;
case 2:
postbyte += 0x808;
break;
case 3:
postbyte += 0x809;
break;
case 4:
postbyte += 0x80A;
break;
}
}
else
{ /*pc relative*/
if (toupper(*srcptr) != 'P')
error |= ERR_ILLEGAL_ADDR;
else
{
srcptr++;
if (toupper(*srcptr) != 'C')
error |= ERR_ILLEGAL_ADDR;
else
{
srcptr++;
if (toupper(*srcptr) == 'R')
srcptr++;
}
}
mode++;
postbyte += 0x80c;
if (opsize == 1)
opsize = 2;
}
}
 
/*****************************************************************************/
/* scanoperands : */
/*****************************************************************************/
 
#define RESTORE { srcptr = oldsrcptr; c = *srcptr; goto dodefault; }
 
void scanoperands09(struct relocrecord *pp)
{
char c, *oldsrcptr, *ptr;
unsigned short accpost, h63 = 0;
unsigned short isIndexed = 0;
 
isFar = 0;
isPostIndexed = 0;
unknown = 0;
opsize = 0;
certain = 1;
scano1:
skipspace();
c = *srcptr;
mode = ADRMODE_IMM;
if (c == '[')
{
c = *++srcptr;
if (c=='[') {
c = *++srcptr;
mode = ADRMODE_DBL_IND;
postbyte = 0x80F;
}
else
mode = ADRMODE_IND;
}
switch (toupper(c))
{
case 'D':
accpost = 0x80b;
accoffset:
oldsrcptr = srcptr;
srcptr++;
if (!(dwOptions & OPTION_TSC))
skipspace();
if (*srcptr != ',')
RESTORE
else
{
isIndexed = 1;
if ((h63) && (!(dwOptions & OPTION_H63)))
error |= ERR_ILLEGAL_ADDR;
postbyte = accpost;
srcptr++;
if (!scanindexreg())
RESTORE
else
{
srcptr++;
set3();
}
}
break;
case 'A':
accpost = 0x806;
goto accoffset;
case 'B':
accpost = 0x805;
goto accoffset;
case 'E':
accpost = 0x807;
h63 = 1;
goto accoffset;
case 'F':
if (toupper(srcptr[1])=='A' && toupper(srcptr[2])=='R' && (srcptr[3]==' '||srcptr[3]=='\t')) {
isFar = 1;
isFarkw = 1;
srcptr += 3;
goto scano1;
}
accpost = 0x80a;
h63 = 1;
goto accoffset;
case 'W' :
accpost = 0x80e;
h63 = 1;
goto accoffset;
case ',':
srcptr++;
scanspecial();
break;
case '#':
if (mode == ADRMODE_IND)
error |= ERR_ILLEGAL_ADDR;
else
mode = ADRMODE_IMM;
srcptr++;
if (*srcptr=='>') {
srcptr++;
operand = (scanexpr(0, pp) >> 24LL) & 0xffffffLL;
isFar = 0;
opsize = 3;
}
else if (*srcptr=='<') {
srcptr++;
operand = scanexpr(0, pp) & 0xffffffLL;
isFar = 0;
opsize = 3;
}
else
operand = scanexpr(0, pp);
break;
case '<':
srcptr++;
if (*srcptr == '<')
{
srcptr++;
opsize = 1;
}
else
opsize = 2;
goto dodefault;
case '>':
srcptr++;
opsize = 3;
/* fall thru on purpose */
default:
dodefault:
operand = scanexpr(0, pp);
if (!(dwOptions & OPTION_TSC))
skipspace();
if (*srcptr == ',')
{
isIndexed = 1;
srcptr++;
if (!(dwOptions & OPTION_TSC))
skipspace();
if ((operand == 0) && /* special for "0,-[-]indexreg */
(!unknown) && (certain) && /* and "0,indexreg[+[+]] */
(opsize < 3) && /* but NOT for ">0,indexreg"! */
((*srcptr == '-') ||
(scanindexreg() /* && (srcptr[1] == '+') */ )))
scanspecial();
else
scanindexed();
}
else
{
if (opsize == 0)
{
if ((unsigned)operand >= 16777216)
opsize = 4;
else
if (unknown || !certain || dpsetting == -1 ||
(unsigned)(operand - dpsetting * 4096) >= 4096)
opsize = 3;
else
opsize = 2;
}
/*
if (opsize == 4) {
if ((operand & 0xff800000) == 0xff800000)
opsize = 3;
else if ((operand & 0xff800000) == 0x0)
opsize = 3;
}
*/
if (opsize == 1)
opsize = 2;
if (mode == ADRMODE_IND)
{
postbyte = 0x80f;
// Why is the following set ?
// opsize = 3;
}
else if (mode == ADRMODE_DBL_IND)
;
else {
switch(opsize) {
case 2: mode = ADRMODE_DIR; break;
case 3: mode = ADRMODE_EXT; break;
// case 4:
case 4: mode = ADRMODE_EXT; isFar = 1; break;
default: mode = opsize - 1;
}
}
}
}
 
if (mode >= ADRMODE_IND)
{
if (!(dwOptions & OPTION_TSC))
skipspace();
if (mode != ADRMODE_DBL_IND)
postbyte |= 0x100;
if (*srcptr != ']')
error |= ERR_ILLEGAL_ADDR;
srcptr++;
if (mode==ADRMODE_DBL_IND) {
if (*srcptr != ']')
error |= ERR_ILLEGAL_ADDR;
srcptr++;
}
}
skipspace();
if (*srcptr==',') {
srcptr++;
isPostIndexed = 1;
scanindexed(); // scanindexed will reset the postbyte
postbyte |= 0x100;
}
else {
if (postbyte==0x90F || postbyte==0x80F)
opsize = 3;
if (mode == ADRMODE_IND || mode==ADRMODE_DBL_IND)
{
/*
if ((postbyte & 0xF)==4) // 0 offset
opsize = 0;
// else if ((postbyte & 0xf)==8 || (postbyte & 0xF)==
else
opsize = 3;
*/
}
}
if (pass > 1 && unknown)
error |= ERR_LABEL_UNDEF;
}
 
void scanoperands00(struct relocrecord *pp)
{
char c, *s = srcptr;
 
unknown = 0;
opsize = 0;
certain = 1;
operand = 0;
skipspace();
c = *srcptr;
mode = ADRMODE_IMM;
switch (toupper(c))
{
case 'X' : /* "X"? */
scanname();
if (!strcmp(unamebuf, "X")) /* if it's "X" alone, */
goto XWithout; /* assume it means "0,X" */
srcptr = s; /* else restore current offset */
goto dodefault; /* and treat as label starting with X*/
case ',': /* ","? */
Indexed :
srcptr++; /* must be followed by "X" */
if (!(dwOptions & OPTION_TSC))
skipspace();
scanname();
if (strcmp(unamebuf, "X")) /* if it's NOT "X" alone, */
{
error |= ERR_ILLEGAL_ADDR;
break;
}
XWithout :
if ((unsigned)operand < 256)
mode = ADRMODE_IDX;
else
error |= ERR_ILLEGAL_ADDR;
break;
case '#':
srcptr++;
operand = scanexpr(0, pp);
break;
case '<':
srcptr++;
if (*srcptr == '<')
{
srcptr++;
opsize = 1;
}
else
opsize = 2;
goto dodefault;
case '>':
srcptr++;
opsize = 3;
/* fall thru on purpose */
default:
dodefault:
operand = scanexpr(0, pp);
if (!(dwOptions & OPTION_TSC))
skipspace();
if (*srcptr == ',')
goto Indexed;
else
{
if (opsize == 0)
{
if (unknown || !certain ||
(unsigned short)(operand) >= 256)
opsize = 3;
else
opsize = 2;
}
if (opsize == 1)
opsize = 2;
mode = opsize - 1;
}
}
 
if (pass > 1 && unknown)
error |= ERR_LABEL_UNDEF;
}
 
/*****************************************************************************/
/* writerelhdr : writes a FLEX Relocatable Format header */
/*****************************************************************************/
 
void writerelhdr(char wcommon)
{
int i;
 
#if 0
struct /* Header Layout */
{
unsigned char Signature; /* Signature (always $03) */
unsigned char flags1; /* Flags 1 */
unsigned datasize; /* size of binary data */
unsigned char unknown1[4]; /* unknown data */
unsigned short extsize; /* size of External table */
unsigned startaddr; /* program start address */
unsigned char unknown2[2]; /* unknown data */
unsigned short globalsize; /* size of global table */
unsigned char unknown3[2]; /* unknown data */
unsigned short namesize; /* length of module name */
unsigned char flags2; /* Flags 2 */
unsigned char unknown4[3]; /* unknown data; filler? */
} hdr;
memset(&hdr, 0, sizeof(hdr));
#endif
 
fputc(0x04, objfile); /* write signature */
 
if (wcommon) /* if writing common data, */
fputc(0x18, objfile); /* Flags1 = $18 */
else if (!absmode) /* if writing Relative data, */
fputc(0x10, objfile); /* Flags1 = $10 */
else /* if writing Absolute data, */
fputc(0x12, objfile); /* Flags1 = $12 */
 
if (wcommon) /* if writing common data */
{ /* write size of data */
// fputc((unsigned char)((commonsym->value >> 24) & 0xff), objfile);
fputc((unsigned char)((commonsym->value >> 16) & 0xff), objfile);
fputc((unsigned char)((commonsym->value >> 8) & 0xff), objfile);
fputc((unsigned char)(commonsym->value & 0xFF), objfile);
}
else /* otherwise */
{ /* write size of binary data */
// fputc((unsigned char)((loccounter >> 24) & 0xff), objfile);
fputc((unsigned char)((loccounter >> 16) & 0xff), objfile);
fputc((unsigned char)((loccounter >> 8) & 0xff), objfile);
fputc((unsigned char)(loccounter & 0xFF), objfile);
}
 
//fputc(0, objfile); /* unknown data */
fputc(0, objfile);
fputc(0, objfile);
fputc(0, objfile);
 
if (wcommon) /* if writing common data */
{ /* external table is empty */
fputc(0, objfile);
fputc(0, objfile);
}
else
{
int extrel = 0; /* # external relocation records */
 
for (i = 0; i < relcounter; i++) /* calc # external symbols */
if ((reltable[i].sym->cat == SYMCAT_EXTERN) ||
(reltable[i].sym->cat == SYMCAT_COMMON))
extrel++;
/* then calculate table size */
extrel = (extrel * 8) + (relcounter * 3);
/* and write it out */
fputc((unsigned char)(extrel >> 8), objfile);
fputc((unsigned char)(extrel & 0xFF), objfile);
}
 
if (wcommon || /* if writing common data */
(!tfradrset)) /* or no transfer address given */
{ /* start address is empty */
// fputc(0, objfile);
fputc(0, objfile);
fputc(0, objfile);
fputc(0, objfile);
}
else /* write transfer address */
{
// fputc((unsigned char)((tfradr >> 24) & 0xff), objfile);
fputc((unsigned char)((tfradr >> 16) & 0xff), objfile);
fputc((unsigned char)((tfradr >> 8) & 0xff), objfile);
fputc((unsigned char)(tfradr & 0xFF), objfile);
}
 
fputc(0, objfile); /* unknown data */
fputc(0, objfile);
 
if (wcommon)
{ /* always 1 Global - the LABEL */
fputc(0, objfile);
fputc(12, objfile);
}
else /* calculate & write out global size */
{
int globals = 0;
for (i = 0; i < symcounter; i++)
if (symtable[i].cat == SYMCAT_PUBLIC)
globals++;
globals *= 12;
fputc((unsigned char)(globals >> 8), objfile);
fputc((unsigned char)(globals & 0xFF), objfile);
}
 
fputc(0, objfile); /* unknown data */
fputc(0, objfile);
 
if (wcommon)
{ /* no name size yet ... */
size_t len;
char name[9] = "";
sprintf(name, "%-.8s", commonsym->name);
strupr(name);
len = strlen(name);
if (len) /* if there, */
len++; /* append a $04 */
fputc((unsigned char)(len >> 8), objfile);
fputc((unsigned char)(len & 0xFF), objfile);
}
else /* write out module name size */
{
size_t len = strlen(modulename);
if (len) /* if there, */
len++; /* append a $04 */
fputc((unsigned char)(len >> 8), objfile);
fputc((unsigned char)(len & 0xFF), objfile);
}
 
if ((!wcommon) && (tfradrset)) /* if transfer address set */
fputc(0x80, objfile); /* write $80 flag */
else
fputc(0, objfile);
 
fputc(0, objfile); /* unknown data */
fputc(0, objfile);
fputc(0, objfile);
}
 
/*****************************************************************************/
/* writerelcommon : writes out all common blocks */
/*****************************************************************************/
 
void writerelcommon()
{
int i, j;
char name[9];
/* work through symbol list */
for (i = 0; i < symcounter; i++)
{
if (symtable[i].cat == SYMCAT_COMMON) /* if that is a common block */
{
commonsym = symtable + i; /* write it out */
writerelhdr(1);
/* then write the global definition */
sprintf(name, "%-8.8s", symtable[i].name);
strupr(name);
fwrite(name, 1, 8, objfile);
if (symtable[i].value >= 65536)
fputc(2, objfile); /* unknown data */
else
fputc(1, objfile); /* unknown data */
// fputc((unsigned char)(symtable[i].value >> 24), objfile);
fputc((unsigned char)(symtable[i].value >> 16), objfile);
fputc((unsigned char)(symtable[i].value >> 8), objfile);
fputc((unsigned char)(symtable[i].value & 0xFF), objfile);
fputc(0x13, objfile); /* unknown flag */
 
/* then write the Common name */
sprintf(name, "%-.8s", symtable[i].name);
strupr(name);
for (j = 0; name[j]; j++)
fputc(name[j], objfile);
fputc(0x04, objfile);
 
j = (int)ftell(objfile); /* fill last sector with zeroes */
while (j % 252)
{
fputc(0, objfile);
j++;
}
}
}
}
 
/*****************************************************************************/
/* writerelext : writes out a FLEX Relocatable External table */
/*****************************************************************************/
 
void writerelext()
{
int i;
char name[9];
unsigned char flags;
 
for (i = 0; i < relcounter; i++) /* write out the external data */
{
// fputc((unsigned char)(reltable[i].addr >> 24), objfile);
fputc((unsigned char)(reltable[i].addr >> 16), objfile);
fputc((unsigned char)(reltable[i].addr >> 8), objfile);
fputc((unsigned char)(reltable[i].addr & 0xFF), objfile);
 
flags = 0x00; /* reset flags */
if (reltable[i].exprcat & EXPRCAT_NEGATIVE)
flags |= 0x20; /* eventually add subtraction flag */
if ((reltable[i].sym->cat == SYMCAT_EXTERN) ||
(reltable[i].sym->cat == SYMCAT_COMMON))
flags |= 0x80; /* eventually add External flag */
fputc(flags, objfile); /* write the flag bytes */
if (flags & 0x80) /* eventually write external symbol */
{
sprintf(name, "%-8.8s", reltable[i].sym->name);
strupr(name);
fwrite(name, 1, 8, objfile);
}
}
}
 
/*****************************************************************************/
/* writerelglobal : writes out FLEX Relocatable Global table */
/*****************************************************************************/
 
void writerelglobal()
{
int i;
char name[9];
 
for (i = 0; i < symcounter; i++) /* write out the global data */
{
if (symtable[i].cat == SYMCAT_PUBLIC)
{
sprintf(name, "%-8.8s", symtable[i].name);
strupr(name);
fwrite(name, 1, 8, objfile);
 
fputc(0, objfile); /* unknown data */
 
// fputc((unsigned char)(symtable[i].value >> 24), objfile);
fputc((unsigned char)(symtable[i].value >> 16), objfile);
fputc((unsigned char)(symtable[i].value >> 8), objfile);
fputc((unsigned char)(symtable[i].value & 0xFF), objfile);
 
fputc(0x02, objfile); /* unknown flag */
}
}
}
 
/*****************************************************************************/
/* writerelmodname : writes out FLEX Relocatable Module Name */
/*****************************************************************************/
 
void writerelmodname()
{
int i;
 
if (!modulename[0])
return;
strupr(modulename);
for (i = 0; modulename[i]; i++)
fputc(modulename[i], objfile);
fputc(0x04, objfile);
}
 
/*****************************************************************************/
/* flushver : write verilog */
/*****************************************************************************/
 
int calcParity(unsigned wd)
{
int nn;
int bit;
int par;
 
par = 0;
for (nn = 0; nn < 32; nn++) {
bit = (wd >> nn) & 1;
par = par ^ bit;
}
return par;
}
 
void flushver()
{
int i;
int chk;
 
if (hexcount)
{
if (objfile)
{
for (i = 0; i < hexcount; i++)
fprintf(objfile, "rommem[%5d] <= 12'h%03X;\r\n", (hexaddr+i) & 0x3fff, hexbuffer[i] & 0xfff);
hexaddr += hexcount;
hexcount = 0;
chksum = 0;
vercount++;
}
}
}
 
/*****************************************************************************/
/* flushhex : write Motorola s-records */
/* Flushes using 12-bit bytes */
/*****************************************************************************/
 
void flushhex()
{
int i;
 
if (hexcount)
{
if (objfile)
{
fprintf(objfile, "S1%03X%06X", (hexcount + 3) & 0xfff, hexaddr & 0xffffff);
for (i = 0; i < hexcount; i++)
fprintf(objfile, "%03X", hexbuffer[i] & 0xfff);
chksum += (hexaddr & 0xfff) + ((hexaddr >> 12) & 0xfff) + hexcount + 3;
fprintf(objfile, "%03X\n", 0xfff - (chksum & 0xfff));
}
hexaddr += hexcount;
hexcount = 0;
chksum = 0;
}
}
 
/*****************************************************************************/
/* flushihex : write Intel hex record */
/*****************************************************************************/
 
void flushihex()
{
int i;
unsigned char *j;
 
if (hexcount)
{
if (objfile)
{
j = &hexbuffer[0];
fprintf(objfile, ":%03X%06X00", hexcount, hexaddr & 0xffffff);
chksum = hexcount + ((hexaddr >> 12) & 0xfff) + (hexaddr & 0xfff);
for (i = 0; i < hexcount; i++, j++)
{
chksum += (*j) & 0xfff;
fprintf(objfile, "%03X", (*j) & 0xfff);
}
fprintf(objfile, "%03X\n", (-(signed)chksum) & 0xfff);
}
hexaddr += hexcount;
hexcount = 0;
chksum = 0;
}
}
 
/*****************************************************************************/
/* flushflex : write FLEX binary record */
/*****************************************************************************/
 
void flushflex()
{
int i;
unsigned short *j;
 
if (hexcount)
{
j = &hexbuffer[0];
if (objfile)
{
fputc(0x02, objfile); /* start of record indicator */
fputc((hexaddr >> 32) & 0xf, /* load address high part */
objfile);
fputc((hexaddr >> 24) & 0xff, /* load address high part */
objfile);
fputc((hexaddr >> 20) & 0xf, /* load address high part */
objfile);
fputc((hexaddr >> 12) & 0xff, /* load address high part */
objfile);
fputc((hexaddr >> 8) & 0xf, objfile); /* load address low part */
fputc(hexaddr & 0xff, objfile); /* load address low part */
fputc((hexcount >> 8) & 0xf, objfile); /* # following data bytes */
fputc(hexcount & 0xff, objfile); /* # following data bytes */
for (i = 0; i < hexcount; i++, j++) { /* then put all data bytes */
fputc(((*j)>>8)&0xff, objfile);
fputc(*j, objfile);
}
}
hexaddr += hexcount; /* set new address */
hexcount = 0; /* reset counter */
}
}
 
/*****************************************************************************/
/* outver : add a byte to verilog output */
/*****************************************************************************/
 
void outver (unsigned short x)
{
if (hexcount==4)
flushver();
hexbuffer[hexcount] = x;
hexcount++;
chksum += x;
}
 
/*****************************************************************************/
/* outhex : add a byte to motorola s-record output */
/*****************************************************************************/
 
void outhex (unsigned short x)
{
if (hexcount == 16)
flushhex();
hexbuffer[hexcount++] = x;
chksum += x;
}
 
/*****************************************************************************/
/* outihex : add a byte to intel hex output */
/*****************************************************************************/
 
void outihex (unsigned short x)
{
if (hexcount == 32)
flushihex();
hexbuffer[hexcount++] = x;
chksum += x;
}
 
/*****************************************************************************/
/* outflex : adds a byte to FLEX output */
/*****************************************************************************/
 
void outflex(unsigned short x)
{
if (hexcount == 255) /* if buffer full */
flushflex(); /* flush it */
hexbuffer[hexcount++] = x; /* then put byte into buffer */
}
 
/*****************************************************************************/
/* outbyte : writes one byte to the output in the selected format */
/*****************************************************************************/
 
void outbyte(unsigned short uc, int off)
{
int nByte = (loccounter + off) / 8;
unsigned short nBitMask = (unsigned short) (1 << ((loccounter + off) % 12));
 
//if (bUsedBytes[nByte] & nBitMask) /* if address already used */
// warning |= WRN_AREA; /* set warning code */
//else /* otherwise */
// bUsedBytes[nByte] |= nBitMask; /* mark it as used */
 
switch (outmode)
{
case OUT_BIN : /* binary file */
fputc((uc >> 8) & 0xf, objfile);
fputc(uc, objfile);
break;
case OUT_REL : /* FLEX Relocatable */
fputc((uc >> 8) & 0xf, objfile);
fputc(uc, objfile);
break;
case OUT_SREC : /* Motorola S-records */
outhex(uc);
break;
case OUT_IHEX : /* Intel Hex */
outihex(uc);
break;
case OUT_FLEX : /* FLEX */
outflex(uc);
break;
case OUT_VER:
outver(uc);
break;
}
}
 
/*****************************************************************************/
/* outbuffer : writes the output to a file in the selected format */
/*****************************************************************************/
 
void outbuffer()
{
int i;
for (i = 0; i < codeptr; i++)
outbyte(codebuf[i], i);
}
 
/*****************************************************************************/
/* report : reports an error */
/*****************************************************************************/
 
void report()
{
int i;
 
for (i = 0; i < 16; i++)
{
if (error & 1)
{
printf("%s(%ld) : error %d: %s in \"%s\"\n",
expandfn(curline->fn), curline->ln, i + 1,
errormsg[i], curline->txt);
if (((dwOptions & OPTION_LP1) || pass == MAX_PASSNO) && (listing & LIST_ON))
putlist( "*** Error %d: %s\n", i + 1, errormsg[i]);
errors++;
}
error >>= 1;
}
 
if ((dwOptions & OPTION_TSC)) /* suppress warning 1 in TSC mode */
warning &= ~WRN_OPT;
 
if (!(dwOptions & OPTION_WAR)) /* reset warnings if not wanted */
warning = WRN_OK;
 
for (i = 0; i < 16; i++)
{
if (warning & 1)
{
printf("%s(%ld) : warning %d: %s in \"%s\"\n",
expandfn(curline->fn), curline->ln, i + 1, warningmsg[i], curline->txt);
if (((dwOptions & OPTION_LP1) || pass == MAX_PASSNO) && (listing & LIST_ON))
putlist( "*** warning %d: %s\n", i + 1, warningmsg[i]);
warnings++;
}
warning >>= 1;
}
}
 
/*****************************************************************************/
/* outlist : lists the code bytes for an instruction */
/*****************************************************************************/
 
void outlist(struct oprecord *op)
{
int i;
 
if ((curline->lvl & LINCAT_INVISIBLE) &&/* don't list invisible lines */
!(dwOptions & OPTION_INV))
return;
 
if ((curline->lvl & LINCAT_MACEXP) && /* don't list macro expansions if */
!(dwOptions & OPTION_EXP)) /* not explicitly requested */
return;
 
if ((curline->lvl & LINCAT_LVLMASK) && /* if level 1..31 */
!(dwOptions & OPTION_LLL)) /* and this is not to be listed */
return;
 
if ((suppress || nSkipCount) && /* if this is conditionally skipped */
!(dwOptions & OPTION_CON)) /* and this is not to be listed */
return;
if ((condline) && /* if this is a condition line */
!(dwOptions & OPTION_CON)) /* and this is not to be listed */
return;
 
if (dwOptions & OPTION_NUM) /* if number output */
putlist("%4d ", curline->ln); /* print out the line number */
 
if (!absmode) /* if in relocating assembler mode */
putlist("%c", curline->rel); /* output relocation information */
 
if (dwOptions & OPTION_LPA) /* if in patch mode */
{
if ((op) && (op->cat == OPCAT_PSEUDO))
{
switch (op->code)
{
case PSEUDO_SETDP :
if (dpsetting >= 0)
putlist("setdp %02X\n", dpsetting);
break;
case PSEUDO_ORG :
putlist("insert %08X \\ ORG $%08X\n", loccounter, loccounter);
break;
case PSEUDO_FCB :
case PSEUDO_FCC :
putlist("data %04X", oldlc);
if (codeptr > 1)
putlist("-%04X", oldlc + codeptr - 1);
putlist("\n");
break;
case PSEUDO_FCW :
putlist("word %04x", oldlc);
if (codeptr > 2)
putlist("-%04X", oldlc + codeptr - 1);
putlist("\n");
break;
case PSEUDO_FCDW :
putlist("dword %08x", oldlc);
if (codeptr > 2)
putlist("-%08X", oldlc + codeptr - 1);
putlist("\n");
break;
}
}
if (codeptr > 0) /* if there are code bytes */
{
char *name = findsymat(oldlc);
if (name)
putlist("label %04X %s\n", oldlc, name);
putlist("patch "); /* write "patch" */
}
else if (*curline->txt)
putlist(" ");
else
putlist("comment %04X", oldlc);
}
else if ((warning & WRN_OPT) && /* excessive branch, TSC style */
(dwOptions & OPTION_TSC) &&
(dwOptions & OPTION_WAR))
putlist(">");
else if (curline->lvl & LINCAT_MACDEF) /* if in macro definition */
putlist("#"); /* prefix line with # */
else if (curline->lvl & LINCAT_MACEXP) /* if in macro expansion */
putlist("+"); /* prefix line with + */
else if (curline->lvl & LINCAT_INVISIBLE)
putlist("-");
else if (curline->txt) /* otherwise */
putlist(" "); /* prefix line with blank */
 
if (codeptr > 0)
putlist("%08X ", oldlc);
else if (*curline->txt)
putlist(" ");
else
{
putlist( "\n");
return;
}
 
for (i = 0; i < codeptr && i < MAXLISTBYTES; i++)
{
if (dwOptions & OPTION_LPA)
putlist("%03X ", codebuf[i]&0xfff);
else
putlist("%03X", codebuf[i]&0xfff);
}
for (; i <= MAXLISTBYTES; i++)
{
if (dwOptions & OPTION_LPA)
putlist(" ");
else
putlist(" ");
}
 
if ((dwOptions & OPTION_LPA) &&
(*curline->txt))
putlist("* ");
 
if (strcmp(curline->txt, srcline) && /* if text inserted */
(dwOptions & OPTION_EXP)) /* and expansion activated */
putlist("%s", curline->txt); /* just print out the source line */
else /* otherwise */
putlist("%s", srcline); /* print possibly expanded line */
 
putlist("\n"); /* send newline */
 
if (codeptr > MAXLISTBYTES && /* if there are additional bytes, */
(dwOptions & OPTION_MUL))
{ /* print them. */
if (dwOptions & OPTION_LPA) /* if in patch mode */
putlist("patch"); /* write "patch" */
for (i = MAXLISTBYTES; i < codeptr; i++)
{
if (!(i % MAXLISTBYTES))
{
if (i != MAXLISTBYTES)
putlist("\n");
if (dwOptions & OPTION_NUM) /* if number output */
putlist(" ");
if (!absmode)
putlist(" ");
putlist(" %08X ", oldlc + i);
}
if (dwOptions & OPTION_LPA) /* if in patch mode */
putlist("%03X ", codebuf[i]&0xfff);
else
putlist("%03X", codebuf[i]&0xfff);
}
putlist("\n");
}
 
if (strcmp(curline->txt, srcline) && /* if text inserted */
(dwOptions & OPTION_EXP)) /* and expansion activated */
{
if (dwOptions & OPTION_NUM)
putlist("%4d ", curline->ln);
if (!absmode)
putlist(" ");
putlist("+ ( %s )\n", srcline);
}
}
 
/*****************************************************************************/
/* setlabel : sets a label */
/*****************************************************************************/
 
void setlabel(struct symrecord * lp)
{
if (lp)
{
lp->isFar = isFar;
lp->isFarkw = isFarkw;
if (lp->cat == SYMCAT_PUBLICUNDEF)
{
lp->cat = SYMCAT_PUBLIC;
lp->value = loccounter;
}
else if (lp->cat == SYMCAT_EMPTYLOCAL)
{
lp->cat = SYMCAT_LOCALLABEL;
}
else if (lp->cat == SYMCAT_LOCALLABEL)
;
else if (lp->cat != SYMCAT_EMPTY && lp->cat != SYMCAT_UNRESOLVED)
{
if ((lp->cat != SYMCAT_LABEL && lp->cat != SYMCAT_PUBLIC) ||
lp->value != loccounter) {
lp->value = loccounter;
if (pass==MAX_PASSNO)
error |= ERR_LABEL_MULT;
}
}
else
{
lp->cat = (global) ? SYMCAT_PUBLIC : SYMCAT_LABEL;
lp->value = loccounter;
}
}
}
 
/*****************************************************************************/
/* putbyte : adds a byte to the instruction code buffer */
/*****************************************************************************/
 
void putbyte(unsigned short b)
{
codebuf[codeptr++] = b; /* and finally put the byte there. */
}
 
/*****************************************************************************/
/* putword : adds a word to the instruction code buffer */
/*****************************************************************************/
 
void putword(unsigned w)
{
putbyte((unsigned short)((w >> 12L) & 0xfffL));
putbyte((unsigned short)(w & 0xfff));
}
 
/*****************************************************************************/
/* putdword : adds a doubleword to the instruction code buffer */
/*****************************************************************************/
 
void putdword(unsigned __int64 d)
{
putbyte((unsigned short)((d >> 36LL) & 0xfffLL));
putbyte((unsigned short)((d >> 24LL) & 0xfffLL));
putbyte((unsigned short)((d >> 12LL) & 0xfffLL));
putbyte((unsigned short)(d & 0xfffLL));
}
 
/*****************************************************************************/
/* doaddress : assemble the right addressing bytes for an instruction */
/*****************************************************************************/
 
void doaddress(struct relocrecord *p)
{
int offs;
int addrelocation = 0;
int isNear = 0;
if (p) /* create relocation record */
p->addr = (unsigned)(loccounter + codeptr);
 
switch (mode)
{
case ADRMODE_IMM :
if (opsize == 2)
putbyte((unsigned short)operand);
else if (opsize == 5) /* LDQ special */
putdword(operand);
else
{
putword((unsigned)operand);
addrelocation = 1;
}
break;
case ADRMODE_DIR :
putbyte((unsigned short)operand);
break;
case ADRMODE_EXT :
if (((codebuf[0] == 0x07e) || /* special for JMP */
(codebuf[0] == 0x0bd) ||
(codebuf[0] == 0x015 && (codebuf[1]==0x07E || codebuf[1]==0x0bd))
) && /* and JSR */
pass > 1)
{
int nDiff = (int)operand - (int)loccounter - 3;
isNear = (operand & 0xFF0000L) == (loccounter & 0xff0000L);
if (((nDiff & 0xff80) == 0x0000) ||
((nDiff & 0xff80) == 0xff80))
warning |= (certain) ? WRN_OPT : 0;
}
if (codebuf[0]==0x015 && codebuf[1]==0x0bd && isFar) {
if (isNear && !isFarkw) {
codebuf[0]=0x0bd;
isFar = 0;
}
else
codebuf[0]=0x0cf;
codeptr--;
}
if (codebuf[0]==0x015 && codebuf[1]==0x07E && isFar) {
if (isNear && !isFarkw) {
codebuf[0]=0x07E;
isFar = 0;
}
else
codebuf[0]=0x08f;
codeptr--;
}
if (isFar) {
putbyte((unsigned short)(operand >> 24));
}
putword((unsigned)operand);
addrelocation = 1;
break;
case ADRMODE_IDX :
putbyte((unsigned short)operand);
break;
case ADRMODE_POST :
case ADRMODE_IND :
case ADRMODE_DBL_IND:
putbyte(postbyte);
switch (opsize)
{
case 2:
putbyte((unsigned short)operand);
break;
case 3:
putword((unsigned)operand);
addrelocation = 1;
break;
case 4:
putbyte((unsigned short)(operand>>24));
putword((unsigned)operand);
addrelocation = 1;
break;
case 5:
putword((unsigned short)(operand>>24));
putword((unsigned)operand);
addrelocation = 1;
break;
}
break;
case ADRMODE_PCR :
case ADRMODE_PIN :
offs = (unsigned)operand - loccounter - codeptr - 2;
if (offs < -2048 || offs >= 2048 || opsize == 3 || unknown || !certain)
{
if ((!unknown) && opsize == 2)
error |= ERR_RANGE;
offs--;
opsize = 3;
postbyte++;
}
putbyte(postbyte);
if (opsize == 3)
{
putword((unsigned)offs);
addrelocation = 1;
}
else
putbyte((unsigned short)offs);
}
 
if (addrelocation)
addreloc(p);
}
 
/*****************************************************************************/
/* onebyte : saves integer as one instruction byte */
/*****************************************************************************/
 
void onebyte(int co)
{
putbyte((unsigned short)co);
}
 
/*****************************************************************************/
/* twobyte : saves integer as two instruction bytes */
/*****************************************************************************/
 
void twobyte(int co)
{
putword((unsigned)co);
}
 
/*****************************************************************************/
/* threebyte : saves long integer as three instruction bytes */
/*****************************************************************************/
 
void threebyte(unsigned __int64 co)
{
putbyte((unsigned short)((co >> 24LL) & 0xfffLL));
putbyte((unsigned short)((co >> 12LL) & 0xfffLL));
putbyte((unsigned short)(co & 0xfffL));
}
 
/*****************************************************************************/
/* fourbyte : saves long integer as four instruction bytes */
/*****************************************************************************/
 
void fourbyte(unsigned __int64 co)
{
putbyte((unsigned short)((co >> 36LL) & 0xfffLL));
putbyte((unsigned short)((co >> 24LL) & 0xfffLL));
putbyte((unsigned short)((co >> 12LL) & 0xfffLL));
putbyte((unsigned short)(co & 0xfffL));
}
 
/*****************************************************************************/
/* oneimm : saves one immediate value */
/*****************************************************************************/
 
void oneimm(int co)
{
struct relocrecord p = {0};
 
scanoperands(&p);
if (mode >= ADRMODE_POST)
error |= ERR_ILLEGAL_ADDR;
putbyte((unsigned short)co);
 
/* addreloc(0, 2, p); */ /* no relocation for immediate op's */
 
putbyte((unsigned short)operand);
}
 
/*****************************************************************************/
/* lea : */
/*****************************************************************************/
 
void lea(int co)
{
struct relocrecord p = {0};
 
scanoperands(&p);
if (isFar)
onebyte(0x015);
onebyte((unsigned short)co);
if (mode == ADRMODE_IMM)
error |= ERR_ILLEGAL_ADDR;
if (mode < ADRMODE_POST)
{
if (isFar)
opsize = 4;
else
opsize = 3;
postbyte = 0x80f;
mode = ADRMODE_POST;
}
doaddress(&p);
}
 
/*****************************************************************************/
/* sbranch : processes a short branch */
/*****************************************************************************/
 
void sbranch(int co)
{
struct relocrecord p = {0};
int offs;
 
scanoperands(&p);
if (mode != ADRMODE_DIR && mode != ADRMODE_EXT)
error |= ERR_ILLEGAL_ADDR;
offs = operand - loccounter - 2;
if (!unknown && (offs < -2048 || offs >= 2048))
error |= ERR_RANGE;
if (pass > 1 && unknown)
error |= ERR_LABEL_UNDEF;
putbyte((unsigned short)co);
putbyte((unsigned short)offs);
}
 
/*****************************************************************************/
/* lbra : does a long branch */
/*****************************************************************************/
 
void lbra(int co)
{
struct relocrecord p = {0};
int nDiff;
 
scanoperands(&p);
if (mode != ADRMODE_DIR && mode != ADRMODE_EXT)
error |= ERR_ILLEGAL_ADDR;
putbyte((unsigned short)co);
 
nDiff = operand - loccounter - 3;
putword((unsigned)nDiff);
if (((nDiff & 0xff8000) == 0x000000) ||
((nDiff & 0xff8000) == 0xff8000))
warning |= (certain) ? WRN_OPT : 0;
}
 
/*****************************************************************************/
/* lbranch : does a long branch */
/*****************************************************************************/
 
void lbranch(int co)
{
struct relocrecord p = {0};
int nDiff;
 
scanoperands(&p);
if (mode != ADRMODE_DIR && mode != ADRMODE_EXT)
error |= ERR_ILLEGAL_ADDR;
putword((unsigned)co);
nDiff = operand - loccounter - 4;
putword((unsigned)nDiff);
if (((nDiff & 0xff8000) == 0x000000) ||
((nDiff & 0xff8000) == 0xff8000))
warning |= (certain) ? WRN_OPT : 0;
}
 
/*****************************************************************************/
/* arith : process arithmetic operation */
/*****************************************************************************/
 
void arith(int co, char noimm)
{
struct relocrecord p = {0};
 
scanoperands(&p);
switch (mode)
{
case ADRMODE_IMM :
if (noimm)
error |= ERR_ILLEGAL_ADDR;
opsize = 2;
putbyte((unsigned short)co);
break;
case ADRMODE_DIR :
putbyte((unsigned short)(co + 0x010));
break;
case ADRMODE_EXT :
if (isFar)
putbyte(0x015);
putbyte((unsigned short)(co + 0x030));
break;
default:
if (isFar)
putbyte(0x015);
if (isPostIndexed)
putbyte(0x01B);
putbyte((unsigned short)(co + 0x020));
}
doaddress(&p);
}
 
/*****************************************************************************/
/* accarith : process arithmetic operation with explicit accumulator */
/*****************************************************************************/
 
void accarith(int co, char noimm, char ignore)
{
char *s = srcptr; /* remember current offset */
char correct = 1; /* flag whether correct */
 
skipspace(); /* skip space */
scanname(); /* get following name */
 
if (strcmp(unamebuf, "A") && /* has to be followed by A or B */
strcmp(unamebuf, "B"))
correct = 0;
 
#if 1
if (*srcptr == ',') /* if directly followed by a comma */
srcptr++; /* skip it */
#else
if (!(dwOptions & OPTION_TSC))
skipspace();
if (*srcptr++ != ',') /* and a comma */
correct = 0;
#endif
 
if (!correct) /* if NOT followed by "A," or "B," */
{
if (ignore) /* if ignoring that, */
srcptr = s; /* go back to parm start */
else /* otherwise */
error |= ERR_EXPR; /* flag as an error */
}
else if (unamebuf[0] == 'B') /* eventually transform to acc.B */
co |= 0x40;
arith(co, noimm); /* then process as arithmetic */
}
 
/*****************************************************************************/
/* idxextarith : indexed / extended arithmetic, 6800 style */
/*****************************************************************************/
 
void idxextarith(int co)
{
struct relocrecord p = {0};
 
scanoperands(&p);
switch (mode)
{
case ADRMODE_IMM :
error |= ERR_ILLEGAL_ADDR;
opsize = 3;
putbyte((unsigned short)co);
break;
case ADRMODE_DIR :
mode = ADRMODE_EXT; /* implicitly convert to extended */
putbyte((unsigned short)(co + 0x030));
break;
case ADRMODE_EXT :
if (isFar)
putbyte(0x015);
putbyte((unsigned short)(co + 0x030));
break;
default:
if (isFar)
putbyte(0x015);
if (isPostIndexed)
putbyte(0x01B);
putbyte((unsigned short)(co + 0x020));
break;
}
doaddress(&p);
}
 
/*****************************************************************************/
/* darith : process direct arithmetic */
/*****************************************************************************/
 
void darith(int co, char noimm, char tgt)
{
struct relocrecord p = {0};
 
scanoperands(&p);
switch (mode)
{
case ADRMODE_IMM :
if (noimm)
error |= ERR_ILLEGAL_ADDR;
if (isX32 && tgt)
opsize = 5;
else
opsize = 3;
putbyte((unsigned short)co);
break;
case ADRMODE_DIR :
putbyte((unsigned short)(co + 0x010));
break;
case ADRMODE_EXT :
if (isFar)
putbyte(0x015);
putbyte((unsigned short)(co + 0x030));
break;
default:
if (isFar)
putbyte(0x015);
if (isPostIndexed)
putbyte(0x01B);
putbyte((unsigned short)(co + 0x020));
break;
}
doaddress(&p);
}
 
/*****************************************************************************/
/* d2arith : process direct word arithmetic */
/*****************************************************************************/
 
void d2arith(int co, char noimm, char tgt)
{
struct relocrecord p = {0};
 
scanoperands(&p);
switch (mode)
{
case ADRMODE_IMM :
if (noimm)
error |= ERR_ILLEGAL_ADDR;
if (isX32 && tgt)
opsize = 5;
else
opsize = 3;
putword((unsigned)co);
break;
case ADRMODE_DIR :
putword((unsigned)(co + 0x010));
break;
case ADRMODE_EXT :
if (isFar) {
putbyte(0x015);
}
putword((unsigned)(co + 0x030));
break;
default:
if (isFar)
putbyte(0x015);
if (isPostIndexed)
putbyte(0x01B);
putword((unsigned)(co + 0x020));
}
doaddress(&p);
}
 
/*****************************************************************************/
/* qarith : process direct doubleword arithmetic */
/*****************************************************************************/
 
void qarith(int co, char noimm)
{
struct relocrecord p = {0};
 
scanoperands(&p);
switch (mode)
{
case ADRMODE_IMM :
if (noimm)
error |= ERR_ILLEGAL_ADDR;
opsize = 5;
putbyte((unsigned short)0xcd); /* this can ONLY be LDQ! */
break;
case ADRMODE_DIR :
putword((unsigned)(co + 0x010));
break;
case ADRMODE_EXT :
putword((unsigned)(co + 0x030));
break;
default:
putword((unsigned)(co + 0x020));
break;
}
doaddress(&p);
}
 
/*****************************************************************************/
/* oneaddr : */
/*****************************************************************************/
 
void oneaddr(int co)
{
struct relocrecord p = {0};
char *s;
 
skipspace();
if ((dwOptions & OPTION_TSC) && /* if TSC mode, check for 6800 */
(co != 0x0e)) /* convenience things */
{
s = srcptr;
scanname(); /* look whether followed by A or B */
if (((!strcmp(unamebuf, "A")) ||
(!strcmp(unamebuf, "B"))) &&
(*srcptr != ',')) /* and NO comma */
{ /* if so, replace by 6809 mnemonic */
warning |= WRN_AMBIG; /* ... but not without a warning */
onebyte(co | ((unamebuf[0] == 'A') ? 0x40 : 0x50));
return;
}
srcptr = s;
}
 
scanoperands(&p);
switch (mode)
{
case ADRMODE_IMM :
error |= ERR_ILLEGAL_ADDR;
break;
case ADRMODE_DIR :
if ((dwOptions & OPTION_M00) && /* on MC6800, a DIRect JMP is not OK */
(co == 0x0e))
error |= ERR_ILLEGAL_ADDR;
else
putbyte((unsigned short)co);
break;
case ADRMODE_EXT :
if (isFar)
putbyte(0x015);
putbyte((unsigned short)(co + 0x70));
break;
default:
if (isFar)
putbyte(0x015);
if (isPostIndexed)
putbyte(0x01B);
putbyte((unsigned short)(co + 0x60));
break;
}
doaddress(&p);
}
 
/*****************************************************************************/
/* accaddr : */
/*****************************************************************************/
 
void accaddr(int co)
{
struct relocrecord p = {0};
char *s;
 
skipspace();
if (dwOptions & OPTION_TSC) /* if TSC mode, check for 6800 */
{
s = srcptr;
scanname(); /* look whether followed by A or B */
if (((!strcmp(unamebuf, "A")) ||
(!strcmp(unamebuf, "B"))) &&
(*srcptr != ',')) /* and NO comma */
{ /* if so, replace */
onebyte(co | ((unamebuf[0] == 'A') ? 0x40 : 0x50));
return;
}
srcptr = s;
}
 
scanoperands(&p);
switch (mode)
{
case ADRMODE_IMM :
error |= ERR_ILLEGAL_ADDR;
break;
case ADRMODE_DIR :
mode = ADRMODE_EXT; /* silently convert to extended */
putbyte((unsigned short)(co + 0x70));
break;
case ADRMODE_EXT :
if (isFar)
putbyte(0x15);
putbyte((unsigned short)(co + 0x70));
break;
default:
if (isFar)
putbyte(0x15);
if (isPostIndexed)
putbyte(0x1B);
putbyte((unsigned short)(co + 0x60));
break;
}
doaddress(&p);
}
 
/*****************************************************************************/
/* tfrexg : */
/*****************************************************************************/
 
void tfrexg(int co)
{
struct regrecord * p;
 
putbyte((unsigned char)co);
skipspace();
scanname();
 
if (dwOptions & OPTION_H63)
p = findreg63(unamebuf);
else
p = findreg(unamebuf);
if (!p)
error |= ERR_ILLEGAL_ADDR;
else
postbyte = (p->tfr) << 4;
skipspace();
if (*srcptr == ',')
srcptr++;
else
error |= ERR_ILLEGAL_ADDR;
skipspace();
scanname();
if ((p = findreg(unamebuf)) == 0)
error |= ERR_ILLEGAL_ADDR;
else
postbyte |= p->tfr;
putbyte(postbyte);
}
 
/*****************************************************************************/
/* pshpul : operates on PSH / PUL mnemonics */
/*****************************************************************************/
 
void pshpul(int co)
{
struct regrecord *p;
struct relocrecord sp = {0};
 
postbyte = 0;
 
skipspace();
if (*srcptr == '#')
{
srcptr++;
if (!(dwOptions & OPTION_TSC))
skipspace();
postbyte = (unsigned short)scanexpr(0, &sp);
}
else do
{
if (*srcptr=='f' || *srcptr=='F') {
if (srcptr[1]=='a' || srcptr[1]=='A') {
if (srcptr[2]=='r' || srcptr[2]=='R') {
if (srcptr[3]==' ' || srcptr[3]=='\t') {
isFar = 1;
srcptr += 4;
}
}
}
}
if (*srcptr == ',')
srcptr++;
if (!(dwOptions & OPTION_TSC))
skipspace();
scanname();
if ((p = findreg(unamebuf)) == 0)
error |= ERR_ILLEGAL_ADDR;
else
postbyte |= p->psh;
if (!(dwOptions & OPTION_TSC))
skipspace();
} while (*srcptr == ',');
if (isFar)
putbyte((unsigned short)0x15);
putbyte((unsigned short)co);
putbyte(postbyte);
}
 
/*****************************************************************************/
/* bitdirect : */
/*****************************************************************************/
 
void bitdirect(int co)
{
struct relocrecord p = {0};
unsigned short dir;
 
skipspace();
if (*srcptr++ != '#')
error |= ERR_EXPR;
dir = (unsigned)scanexpr(0, &p);
if (dir & 0xfff000)
error |= ERR_EXPR;
if (!(dwOptions & OPTION_TSC))
skipspace();
if (*srcptr++ != ',')
error |= ERR_EXPR;
scanoperands(&p);
switch (mode)
{
case ADRMODE_IMM :
error |= ERR_ILLEGAL_ADDR;
break;
case ADRMODE_DIR :
putbyte((unsigned short)co);
break;
case ADRMODE_EXT :
if (isFar)
putbyte(0x15);
putbyte((unsigned short)(co + 0x70));
break;
default:
if (isFar)
putbyte(0x15);
putbyte((unsigned short)(co + 0x60));
break;
}
putbyte((unsigned short)dir);
doaddress(&p);
}
 
/*****************************************************************************/
/* bittrans : */
/*****************************************************************************/
 
void bittrans(int co)
{
struct regrecord *p;
struct relocrecord rp = {0};
long t;
 
putword((unsigned)co);
 
skipspace();
scanname();
if ((p = findbitreg(unamebuf)) == 0)
error |= ERR_ILLEGAL_ADDR;
else
postbyte = (p->tfr) << 6;
if (!(dwOptions & OPTION_TSC))
skipspace();
if (*srcptr == ',')
srcptr++;
else
error |= ERR_ILLEGAL_ADDR;
if (!(dwOptions & OPTION_TSC))
skipspace();
t = scanfactor(&rp);
if (t & 0xfffff8)
error |= ERR_ILLEGAL_ADDR;
else
postbyte |= (t << 3);
if (!(dwOptions & OPTION_TSC))
skipspace();
if (*srcptr == ',')
srcptr++;
else
error |= ERR_ILLEGAL_ADDR;
t = scanfactor(&rp);
if (t & 0xfffff8)
error |= ERR_ILLEGAL_ADDR;
else
postbyte |= t;
putbyte((unsigned short)postbyte);
if (!(dwOptions & OPTION_TSC))
skipspace();
if (*srcptr == ',')
srcptr++;
else
error |= ERR_ILLEGAL_ADDR;
scanoperands(&rp);
switch (mode)
{
case ADRMODE_DIR :
putbyte((unsigned short)operand);
break;
default:
error |= ERR_ILLEGAL_ADDR;
}
}
 
/*****************************************************************************/
/* blocktrans : */
/*****************************************************************************/
 
void blocktrans(int co)
{
char reg1,reg2;
char mode[3] = "";
static char regnames[] = "DXYUS";
static char *modes[] =
{
"++",
"--",
"+",
",+"
};
int i;
 
skipspace();
reg1 = toupper(*srcptr);
for (i = 0; regnames[i]; i++)
if (reg1 == regnames[i])
break;
if (!regnames[i])
error |= ERR_ILLEGAL_ADDR;
else
reg1 = i;
mode[0] = *++srcptr;
if ((mode[0] != '+') && (mode[0] != '-'))
{
if (!(dwOptions & OPTION_TSC))
skipspace();
mode[0] = *srcptr;
}
else
srcptr++;
if (!(dwOptions & OPTION_TSC))
skipspace();
if (*srcptr != ',')
error |= ERR_ILLEGAL_ADDR;
srcptr++;
reg2 = toupper(*srcptr);
for (i = 0; regnames[i]; i++)
if (reg2 == regnames[i])
break;
if (!regnames[i])
error |= ERR_ILLEGAL_ADDR;
else
reg2 = i;
mode[1] = *++srcptr;
if ((mode[1] != '+') && (mode[1] != '-'))
{
if (!(dwOptions & OPTION_TSC))
skipspace();
mode[1] = *srcptr;
}
else
srcptr++;
if ((mode[1] == ';') || (mode[1] == '*') ||
(mode[1] == ' ') || (mode[1] == '\t'))
mode[1] = '\0';
for (i = 0; i < (sizeof(modes) / sizeof(modes[0])); i++)
if (!strcmp(mode, modes[i]))
break;
if (i >= (sizeof(modes) / sizeof(modes[0])))
error |= ERR_ILLEGAL_ADDR;
else
co |= i;
 
putword((unsigned)co);
putbyte((unsigned short)((reg1 << 4) | reg2));
}
 
/*****************************************************************************/
/* expandline : un-tabify current line */
/*****************************************************************************/
 
void expandline()
{
int i, j = 0, k, j1;
 
for (i = 0; i < LINELEN && j < LINELEN; i++)
{
if (inpline[i] == '\n')
{
srcline[j] = 0;
break;
}
else if (inpline[i] == '\t')
{
j1 = j;
for (k = 0; k < 8 - j1 % 8 && j < LINELEN; k++)
srcline[j++] = ' ';
}
else if (inpline[i] == '\r')
{
continue;
}
else
srcline[j++] = inpline[i];
}
srcline[LINELEN - 1] = 0;
}
 
/*****************************************************************************/
/* expandtext : expands all texts in a line */
/*****************************************************************************/
 
void expandtext()
{
char *p;
int i, j = 0;
int doit = 1;
 
for (p = curline->txt; (*p) && (j < LINELEN); )
{
if (*p == '\"')
doit = !doit;
 
if (*p == '\\' && p[1] == '&')
srcline[j++] = *(++p);
else if (*p == '&' &&
(p[1] < '0' || p[1] > '9') &&
doit)
{
struct symrecord *lp;
srcptr = p + 1;
scanname();
lp = findsym(namebuf, 0);
if ((lp) && (*namebuf) && /* if symbol IS a text constant, */
(lp->cat == SYMCAT_TEXT))
{ /* insert its content */
p = srcptr;
for (i = 0; j < LINELEN && texts[lp->value][i]; i++)
srcline[j++] = texts[lp->value][i];
}
else /* otherwise */
srcline[j++] = *p++; /* simply use the '&' and go on. */
}
else
srcline[j++] = *p++;
}
srcline[j >= LINELEN ? LINELEN - 1 : j] = '\0';
}
 
/*****************************************************************************/
/* readfile : reads in a file and recurses through includes */
/*****************************************************************************/
 
struct linebuf *readfile(char *name, unsigned char lvl, struct linebuf *after)
{
FILE *srcfile;
struct linebuf *pNew;
int lineno = 0;
int i;
int nfnidx = -1;
 
for (i = 0; i < nfnms; i++) /* prohibit recursion */
if (!strcmp(name, fnms[i]))
{
nfnidx = i;
break;
}
if (nfnidx < 0)
{
if (nfnms >= (sizeof(fnms) / sizeof(fnms[0])))
{
printf("%s(0) : error 21: nesting level too deep\n", name);
if (((dwOptions & OPTION_LP1) || pass == MAX_PASSNO) && (listing & LIST_ON))
putlist( "*** Error 21: nesting level too deep\n");
exit(4);
}
nfnidx = nfnms++;
}
 
if ((srcfile = fopen(name, "r")) == 0)
{
printf("%s(0) : error 17: cannot open source file\n", name);
if (((dwOptions & OPTION_LP1) || pass == MAX_PASSNO) && (listing & LIST_ON))
putlist( "*** Error 17: cannot open source file\n");
exit(4);
}
if (!fnms[nfnidx]) /* if not yet done, */
fnms[nfnidx] = strdup(name); /* remember the file name */
while (fgets(inpline, LINELEN, srcfile))
{
expandline();
pNew = allocline(after, fnms[nfnidx], ++lineno, lvl, srcline);
if (!pNew)
{
printf("%s(%d) : error 22: memory allocation error\n", name, lineno);
if (((dwOptions & OPTION_LP1) || pass == MAX_PASSNO) && (listing & LIST_ON))
putlist( "*** Error 22: memory allocation error\n");
exit(4);
}
if (!after) /* if 1st line */
rootline = pNew; /* remember it as root */
after = pNew; /* insert behind the new line */
}
fclose(srcfile); /* then close the file */
return after; /* pass back last line inserted */
}
 
/*****************************************************************************/
/* readbinary: reads in a binary file and converts to fcw / fcb lines */
/*****************************************************************************/
 
struct linebuf *readbinary
(
char *name,
unsigned char lvl,
struct linebuf *after,
struct symrecord *lp
)
{
FILE *srcfile;
struct linebuf *pNew;
int lineno = 0;
int i;
int nfnidx = -1;
unsigned char binlin[16];
int binlen;
int fcbstart;
 
for (i = 0; i < nfnms; i++) /* prohibit recursion */
if (!strcmp(name, fnms[i]))
{
nfnidx = i;
break;
}
if (nfnidx < 0)
{
if (nfnms >= (sizeof(fnms) / sizeof(fnms[0])))
{
printf("%s(0) : error 21: nesting level too deep\n", name);
if (((dwOptions & OPTION_LP1) || pass == MAX_PASSNO) && (listing & LIST_ON))
putlist( "*** Error 21: nesting level too deep\n");
exit(4);
}
nfnidx = nfnms++;
}
 
if ((srcfile = fopen(name, "rb")) == 0)
{
printf("%s(0) : error 17: cannot open source file\n", name);
if (((dwOptions & OPTION_LP1) || pass == MAX_PASSNO) && (listing & LIST_ON))
putlist( "*** Error 17: cannot open source file\n");
exit(4);
}
if (!fnms[nfnidx]) /* if not yet done, */
fnms[nfnidx] = strdup(name); /* remember the file name */
while ((binlen = (int)fread(binlin, 1, sizeof(binlin), srcfile)) > 0)
{
sprintf(inpline, "%s", (lineno || (!lp)) ? "" : lp->name);
i = 0;
if ((binlen & (~1)) && (binlen > 7))
{
sprintf(inpline + strlen(inpline), "\tFCW\t" /* , (binlen & 1) ? 'B' : 'W' */);
for (; i < (binlen & ~1); i += 2)
sprintf(inpline + strlen(inpline), "%s$%02X%02X", (i) ? "," : "",
binlin[i], binlin[i + 1]);
expandline();
pNew = allocline(after, fnms[nfnidx], ++lineno, lvl, srcline);
if (!pNew)
{
printf("%s(%d) : error 22: memory allocation error\n", name, lineno);
if (((dwOptions & OPTION_LP1) || pass == MAX_PASSNO) && (listing & LIST_ON))
putlist( "*** Error 22: memory allocation error\n");
exit(4);
}
if (!after) /* if 1st line */
rootline = pNew; /* remember it as root */
after = pNew; /* insert behind the new line */
inpline[0] = '\0'; /* reset input line */
}
if ((binlen & 1) || (binlen <= 7))
{
fcbstart = i;
sprintf(inpline + strlen(inpline), "\tFCB\t");
for (; i < binlen; i++)
sprintf(inpline + strlen(inpline), "%s$%02X", (i > fcbstart) ? "," : "",
binlin[i]);
 
expandline();
pNew = allocline(after, fnms[nfnidx], ++lineno, lvl, srcline);
if (!pNew)
{
printf("%s(%d) : error 22: memory allocation error\n", name, lineno);
if (((dwOptions & OPTION_LP1) || pass == MAX_PASSNO) && (listing & LIST_ON))
putlist( "*** Error 22: memory allocation error\n");
exit(4);
}
if (!after) /* if 1st line */
rootline = pNew; /* remember it as root */
after = pNew; /* insert behind the new line */
}
}
fclose(srcfile); /* then close the file */
return after; /* pass back last line inserted */
}
 
/*****************************************************************************/
/* setoptiontexts : sets up the option text variables */
/*****************************************************************************/
 
void setoptiontexts()
{
int i;
/* walk option list */
for (i = 0; i < (sizeof(Options) / sizeof(Options[0])); i++)
{
if ((dwOptions & Options[i].dwAdd) ||
(!(dwOptions & ~Options[i].dwRem)))
settext(Options[i].Name, "1");
else
settext(Options[i].Name, "0");
}
}
 
/*****************************************************************************/
/* setoption : processes an option string */
/*****************************************************************************/
 
int setoption ( char *szOpt )
{
char iopt[4];
int i;
 
for (i = 0; szOpt[i] && i < sizeof(iopt); i++)
iopt[i] = toupper(szOpt[i]);
if (i >= sizeof(iopt))
i--;
iopt[i] = '\0';
/* search option list */
for (i = 0; i < (sizeof(Options) / sizeof(Options[0])); i++)
{
if (!strcmp(iopt, Options[i].Name)) /* if option found */
{
dwOptions |= Options[i].dwAdd; /* add flags */
dwOptions &= ~Options[i].dwRem; /* and remove flags */
 
switch (Options[i].dwAdd) /* afterprocessing for specials: */
{
case OPTION_M09 : /* switch to MC6809 processor */
optable = optable09;
optablesize = sizeof(optable09) / sizeof(optable09[0]);
regtable = regtable09;
bitregtable = bitregtable09;
scanoperands = scanoperands09;
break;
case OPTION_H63 : /* switch to HD6309 processor */
optable = optable09;
optablesize = sizeof(optable09) / sizeof(optable09[0]);
regtable = regtable63;
bitregtable = bitregtable09;
scanoperands = scanoperands09;
break;
case OPTION_M00 : /* switch to MC6800 processor */
optable = optable00;
optablesize = sizeof(optable00) / sizeof(optable00[0]);
regtable = regtable00;
bitregtable = bitregtable00;
scanoperands = scanoperands00;
break;
}
 
setoptiontexts();
return 0; /* then return OK */
}
}
 
return 1; /* unknown option */
}
 
/*****************************************************************************/
/* pseudoop : processes all known pseudo-ops */
/*****************************************************************************/
 
void pseudoop(int co, struct symrecord * lp)
{
int i, j;
char c;
struct relocrecord p = {0};
 
if (common && /* if in COMMON definition mode */
(co != PSEUDO_ENDCOM) && /* and this is neither ENDCOM */
(co != PSEUDO_RMB)) /* nor RMB */
error |= ERR_EXPR; /* this is an error. */
 
switch (co)
{
case PSEUDO_ABS : /* ABS */
absmode = 1; /* reset mode to absolute */
break;
case PSEUDO_DEF : /* DEFINE */
global++; /* all labels from now on are global */
break;
case PSEUDO_ENDDEF : /* ENDDEF */
if (global) /* all labels from now on are local */
global--;
else
error |= ERR_EXPR; /* must be paired */
break;
case PSEUDO_COMMON : /* label COMMON */
if (absmode) /* if in absolute assembler mode */
error |= ERR_RELOCATING;
if (!lp)
error |= ERR_LABEL_MISSING;
else
lp->cat = SYMCAT_COMMON;
common++; /* go into common mode */
commonsym = lp; /* remember common symbol */
break;
case PSEUDO_ENDCOM : /* ENDCOM */
if (absmode) /* if in absolute assembler mode */
error |= ERR_RELOCATING;
if (common) /* terminate common mode */
common--;
else
error |= ERR_EXPR; /* must be paired */
break;
case PSEUDO_RMB : /* [label] RMB <absolute expression> */
case PSEUDO_RZB : /* [label] RZB <absolute expression> */
operand = scanexpr(0, &p);
if (unknown)
error |= ERR_LABEL_UNDEF;
 
if (common) /* if in common mode */
{
if ((lp->cat != SYMCAT_EMPTY) &&
(lp->cat != SYMCAT_UNRESOLVED) &&
(lp->cat != SYMCAT_COMMONDATA))
error |= ERR_LABEL_MULT;
if (lp->cat != SYMCAT_COMMONDATA) /* if not yet done, */
{
lp->cat = SYMCAT_COMMONDATA; /* set tymbol type */
lp->u.parent = commonsym; /* remember COMMON symbol */
lp->value = commonsym->value; /* remember offset from COMMON symbol*/
commonsym->value += /* append # bytes to reserve to -"- */
(unsigned short)operand;
}
break;
}
 
setlabel(lp);
if (generating && pass == MAX_PASSNO)
{
if (co != 0 || outmode == OUT_BIN)
for (i = 0; i < operand; i++)
outbyte(0, i);
else switch (outmode)
{
case OUT_SREC : /* Motorola S51-09 ? */
flushhex();
break;
case OUT_IHEX : /* Intel Hex ? */
flushihex();
break;
case OUT_FLEX : /* FLEX binary ? */
flushflex();
break;
}
}
loccounter += operand;
hexaddr = loccounter;
break;
case PSEUDO_EQU : /* label EQU x */
nRepNext = 0; /* reset eventual repeat */
operand = scanexpr(0, &p);
if (!lp)
error |= ERR_LABEL_MISSING;
else
{
if (lp->cat == SYMCAT_EMPTY ||
lp->cat == SYMCAT_UNRESOLVED ||
(lp->value == (unsigned)operand &&
pass > 1))
{
if (exprcat == EXPRCAT_INTADDR)
lp->cat = SYMCAT_LABEL;
else
lp->cat = SYMCAT_CONSTANT;
lp->value = (unsigned)operand;
}
else
error |= ERR_LABEL_MULT;
}
break;
case PSEUDO_PUB : /* PUBLIC a[,b[,c...]] */
case PSEUDO_EXT : /* EXTERN a[,b[,c...]] */
nRepNext = 0; /* reset eventual repeat */
skipspace();
while (isalnum(*srcptr))
{
scanname(); /* parse option */
lp = findsym(namebuf, 1); /* look up the symbol */
switch (co)
{
case PSEUDO_PUB : /* PUBLIC a[,b[,c...]] */
if (lp->cat == SYMCAT_EMPTY ||
lp->cat == SYMCAT_UNRESOLVED)
lp->cat = SYMCAT_PUBLICUNDEF;
else if (lp->cat == SYMCAT_LABEL)
lp->cat = SYMCAT_PUBLIC;
else if (lp->cat == SYMCAT_PUBLICUNDEF)
error |= ERR_LABEL_UNDEF;
else if (lp->cat != SYMCAT_PUBLIC)
error |= ERR_LABEL_MULT;
break;
case PSEUDO_EXT : /* EXTERN a[,b[,c...]] */
if (absmode) /* if not in relocating asm mode, */
error |= ERR_RELOCATING; /* set error */
if (lp->cat == SYMCAT_EMPTY ||
lp->cat == SYMCAT_UNRESOLVED)
lp->cat = SYMCAT_EXTERN;
else if (lp->cat != SYMCAT_EXTERN)
error |= ERR_LABEL_MULT;
break;
}
if (*srcptr == ',')
{
srcptr++;
if (!(dwOptions & OPTION_TSC))
skipspace();
}
}
break;
case PSEUDO_FCB : /* [label] FCB expr[,expr...] */
setlabel(lp);
generating = 1;
do
{
if (*srcptr == ',')
srcptr++;
if (!(dwOptions & OPTION_TSC))
skipspace();
if (*srcptr == '\"')
{
srcptr++;
while (*srcptr != '\"' && *srcptr)
putbyte(*srcptr++);
if (*srcptr == '\"')
srcptr++;
}
else
{
putbyte((unsigned short)scanexpr(0, &p));
if (unknown && pass == MAX_PASSNO)
error |= ERR_LABEL_UNDEF;
}
if (!(dwOptions & OPTION_TSC))
skipspace();
} while (*srcptr == ',');
break;
case PSEUDO_FCC : /* [label] FCC expr[,expr...] */
setlabel(lp);
if (!(dwOptions & OPTION_TSC))
skipspace();
if (!(dwOptions & OPTION_TSC)) /* if standard */
{ /* accept ONE sequence with an */
c = *srcptr++; /* arbitrary delimiter character */
while (*srcptr != c && *srcptr)
putbyte(*srcptr++);
if (*srcptr == c)
srcptr++;
}
else /* if TSC extended format */
{ /* accept MORE sequences */
do
{
if (*srcptr == ',')
srcptr++;
if (!(dwOptions & OPTION_TSC))
skipspace();
c = *srcptr;
if ((c == '$') || isalnum(c))
{
putbyte((unsigned short)scanexpr(0, &p));
if (unknown && pass == MAX_PASSNO)
error |= ERR_LABEL_UNDEF;
}
else
{
srcptr++;
while (*srcptr != c && *srcptr)
putbyte(*srcptr++);
if (*srcptr == c)
srcptr++;
}
if (!(dwOptions & OPTION_TSC))
skipspace();
} while (*srcptr == ',');
}
break;
case PSEUDO_FCW : /* [label] FCW,FDB expr[,expr...] */
setlabel(lp);
generating = 1;
do
{
if (*srcptr == ',')
srcptr++;
if (!(dwOptions & OPTION_TSC))
skipspace();
putword((unsigned)scanexpr(0, &p));
if (unknown && pass == MAX_PASSNO)
error |= ERR_LABEL_UNDEF;
if (!(dwOptions & OPTION_TSC))
skipspace();
} while (*srcptr == ',');
break;
case PSEUDO_FCDW: /* [label] FCDW,FDB expr[,expr...] */
setlabel(lp);
generating = 1;
do
{
if (*srcptr == ',')
srcptr++;
if (!(dwOptions & OPTION_TSC))
skipspace();
putdword((unsigned __int64)scanexpr(0, &p));
if (unknown && pass == MAX_PASSNO)
error |= ERR_LABEL_UNDEF;
if (!(dwOptions & OPTION_TSC))
skipspace();
} while (*srcptr == ',');
break;
case PSEUDO_ELSE : /* ELSE */
if (inMacro) /* don't process if in MACRO def. */
break;
nRepNext = 0; /* reset eventual repeat */
suppress = 1;
condline = 1; /* this is a conditional line */
break;
case PSEUDO_ENDIF : /* ENDIF */
if (inMacro) /* don't process if in MACRO def. */
break;
nRepNext = 0; /* reset eventual repeat */
condline = 1; /* this is a conditional line */
break;
case PSEUDO_IF : /* IF <expression>[,<skip>] */
case PSEUDO_IFN : /* IFN <expression>[,<skip>] */
if (inMacro) /* don't process if in MACRO def. */
break;
condline = 1; /* this is a conditional line */
nRepNext = 0; /* reset eventual repeat */
operand = scanexpr(0, &p);
if (unknown)
error |= ERR_LABEL_UNDEF;
if (co == PSEUDO_IFN) /* if IFN */
operand = !operand; /* reverse operand */
if (!(dwOptions & OPTION_TSC))
skipspace();
if (*srcptr == ',') /* skip count? */
{
srcptr++;
if (!(dwOptions & OPTION_TSC))
skipspace();
nSkipCount = scanexpr(0, &p);
if (!operand)
nSkipCount = 0;
}
else if (!operand)
suppress = 2;
break;
case PSEUDO_IFC : /* IFC <string1>,<string2>[,<skip>] */
case PSEUDO_IFNC : /* IFNC <string1>,<string2>[,<skip>] */
if (inMacro) /* don't process if in MACRO def. */
break;
condline = 1; /* this is a conditional line */
if (!(dwOptions & OPTION_TSC))
skipspace();
scanstring(szBuf1, sizeof(szBuf1));
if (!(dwOptions & OPTION_TSC))
skipspace();
if (*srcptr != ',') /* if not on comma */
{
*szBuf2 = '\0'; /* reset 2nd string */
error |= ERR_EXPR; /* set error */
}
else
{
srcptr++;
if (!(dwOptions & OPTION_TSC))
skipspace();
scanstring(szBuf2, sizeof(szBuf2));
if (!(dwOptions & OPTION_TSC))
skipspace();
}
operand = !strcmp(szBuf1, szBuf2);
if (co == PSEUDO_IFNC)
operand = !operand;
if (*srcptr == ',') /* if skip count */
{
srcptr++;
if (!(dwOptions & OPTION_TSC))
skipspace();
nSkipCount = scanexpr(0, &p);
if (!operand)
nSkipCount = 0;
}
else if (!operand)
suppress = 2;
break;
 
case PSEUDO_IFD : /* IFD <symbol>[,skipcount] */
case PSEUDO_IFND : /* IFND <symbol>[,skipcount] */
/* ATTENTION: it is easy to produce phasing errors with these 2, */
/* since symbols are NOT reset when starting pass 2! */
if (inMacro) /* don't process if in MACRO def. */
break;
skipspace();
scanname(); /* parse symbol name */
lp = findsym(namebuf, 0); /* look up the symbol */
if (!(dwOptions & OPTION_TSC))
skipspace();
if (*srcptr == ',') /* if skip count */
{
srcptr++;
if (!(dwOptions & OPTION_TSC))
skipspace();
nSkipCount = scanexpr(0, &p);
if (!lp != (co == PSEUDO_IFND))
nSkipCount = 0;
}
/* if no skip count and NOT matched */
else if (!lp != (co == PSEUDO_IFND))
suppress = 2; /* suppress until ELSE or ENDIF */
condline = 1; /* this is a conditional line */
break;
 
case PSEUDO_ORG : /* ORG <expression> */
nRepNext = 0; /* reset eventual repeat */
operand = scanexpr(0, &p);
if (unknown)
error |= ERR_LABEL_UNDEF;
if (relocatable && /* if in relocating assembler mode */
(!absmode))
{
error |= ERR_RELOCATING; /* set error */
break; /* and ignore */
}
if (generating && pass == MAX_PASSNO)
{
switch (outmode)
{
case OUT_BIN : /* binary output file */
j = (int)(unsigned)operand - (int)loccounter;
if (j > 0) /* if forward gap */
{
for (i = 0; i < j; i++) /* seek forward that many bytes */
fseek(objfile, 1, SEEK_CUR);
}
else /* if backward gap */
{
j = -j;
for (i = 0; i < j; i++) /* seek back that many bytes */
fseek(objfile, -1, SEEK_CUR);
}
break;
case OUT_VER:
flushver();
break;
case OUT_SREC : /* motorola s51-09 */
flushhex();
break;
case OUT_IHEX : /* intel hex format */
flushihex();
break;
case OUT_FLEX : /* FLEX binary */
flushflex();
break;
}
}
loccounter = operand;
hexaddr = loccounter;
break;
case PSEUDO_SETDP : /* SETDP [<abs page value>] */
nRepNext = 0; /* reset eventual repeat */
skipspace();
if ((!*srcptr) || (*srcptr == '*') || (*srcptr == ';'))
operand = -1;
else
operand = scanexpr(0, &p);
if (unknown)
error |= ERR_LABEL_UNDEF;
if (!(operand & 4095))
operand = (unsigned)operand >> 12;
if ((unsigned)operand > 4095)
operand = -1;
if (absmode)
dpsetting = operand;
else
error |= ERR_RELOCATING;
break;
case PSEUDO_SET : /* label SET <non external expr> */
nRepNext = 0; /* reset eventual repeat */
operand = scanexpr(0, &p);
if (!lp)
error |= ERR_LABEL_MISSING;
else
{
if (lp->cat & SYMCAT_VARIABLE ||
lp->cat == SYMCAT_UNRESOLVED)
{
if (exprcat == EXPRCAT_INTADDR)
lp->cat = SYMCAT_VARADDR;
else
lp->cat = SYMCAT_VARIABLE;
lp->value = (unsigned)operand;
}
else
error |= ERR_LABEL_MULT;
}
break;
case PSEUDO_END : /* END [loadaddr] */
nRepNext = 0; /* reset eventual repeat */
if ((curline->lvl & 0x0f) == 0) /* only in outermost level! */
{
skipspace(); /* skip blanks */
if (isfactorstart(*srcptr)) /* if possible transfer address */
{
tfradr = (unsigned) /* get transfer address */
scanexpr(0, &p);
if (error) /* if error in here */
tfradr = 0; /* reset to zero */
else /* otherwise */
tfradrset = 1; /* remember transfer addr. is set */
}
terminate = 1;
}
break;
case PSEUDO_INCLUDE : /* INCLUDE <filename> */
nRepNext = 0; /* reset eventual repeat */
if (inMacro || /* if in macro definition */
(curline->lvl & LINCAT_MACEXP)) /* or macro expansion */
error |= ERR_EXPR; /* this is an error. */
else if (pass == 1) /* otherwise expand if in pass 1 */
{
char fname[FNLEN + 1];
int instring = 0;
char *osrc = srcptr;
 
if ((curline->lvl & 0x0f) == 0x0f)/* if impossible */
{
#if 0
allocline(curline, "NULL", -1, 0x0f,
"Error including file - nesting level too deep");
#endif
error |= ERR_MALLOC; /* set OUT OF MEMORY error */
break;
}
if (!(dwOptions & OPTION_TSC))
skipspace();
if (*srcptr == '\"')
{
srcptr++;
instring = 1;
}
for (i = 0; i < FNLEN; i++)
{
if (*srcptr == 0 ||
(!instring && *srcptr == ' ') ||
*srcptr == '"')
break;
fname[i] = *srcptr++;
}
fname[i] = 0;
curline->lvl |= LINCAT_INVISIBLE; /* preclude listing of INCLUDE line */
readfile(fname, /* append include after current line */
(unsigned char)((curline->lvl & 0x0f) + 1),
curline);
expandtext(); /* re-expand current line */
srcptr = osrc;
}
break;
case PSEUDO_OPT : /* OPT,OPTION option[,option...] */
nRepNext = 0; /* reset eventual repeat */
skipspace();
while (isalnum(*srcptr))
{
scanname(); /* parse option */
if (setoption(unamebuf))
error |= ERR_OPTION_UNK;
if (*srcptr == ',')
{
srcptr++;
if (!(dwOptions & OPTION_TSC))
skipspace();
}
}
break;
case PSEUDO_NAM : /* NAM,TTL <text> */
case PSEUDO_STTL : /* STTL <text> */
nRepNext = 0; /* reset eventual repeat */
if (!(dwOptions & OPTION_TSC))
skipspace();
if (isalnum(*srcptr))
{
char *tgt = (co == PSEUDO_NAM) ? szTitle : szSubtitle;
char *lnblnk = tgt;
int nBytes = 0;
while (*srcptr && nBytes < (sizeof(szTitle) - 1))
{
if (*srcptr != ' ')
lnblnk = tgt;
*tgt++ = *srcptr++;
nBytes++;
}
lnblnk[1] = '\0'; /* terminate after last nonblank */
while (*srcptr) /* skip rest if too long */
srcptr++;
}
break;
case PSEUDO_PAG : /* PAG [<abs expression>] */
if (!(dwOptions & OPTION_TSC))
skipspace();
if (isfactorstart(*srcptr)) /* if possible new page number */
{
int nPage = scanexpr(0, &p); /* get new page # */
if (!error && listfile) /* if valid and writing listfile */
nCurPage = nPage - 1;
else
break;
}
curline->lvl |= LINCAT_INVISIBLE;
if ((listing & LIST_ON) && listfile &&
(dwOptions & OPTION_PAG) &&
(!(curline->lvl & LINCAT_LVLMASK) || (dwOptions & OPTION_LLL)) &&
(pass > 1 || (dwOptions & OPTION_LP1)))
PageFeed();
break;
case PSEUDO_SPC : /* SPC <n[,keep]> */
{
int nSpc = 1, nKeep = 0;
if (!(dwOptions & OPTION_TSC))
skipspace();
if (isfactorstart(*srcptr)) /* if possible new page number */
{
nSpc = scanexpr(0, &p); /* get # space lines */
if (!(dwOptions & OPTION_TSC))
skipspace();
if (*srcptr == ',') /* if followed by , */
{
srcptr++;
if (!(dwOptions & OPTION_TSC))
skipspace();
nKeep = scanexpr(0, &p); /* get # keep lines */
}
if (error)
break;
}
curline->lvl |= LINCAT_INVISIBLE;
if (listing & LIST_ON)
{
if (nSpc > 0) /* if spaces needed */
{
if ((dwOptions & OPTION_PAG) &&
(nCurLine + nSpc + nKeep >= nLinesPerPage))
PageFeed();
else for (; nSpc; nSpc--)
putlist("\n");
}
else if (nKeep &&
(dwOptions & OPTION_PAG) &&
(nCurLine + nKeep >= nLinesPerPage))
PageFeed();
}
}
break;
case PSEUDO_REP : /* REP n */
if (!(dwOptions & OPTION_TSC))
skipspace();
nRepNext = scanexpr(0, &p); /* get # repetitions */
curline->lvl |= LINCAT_INVISIBLE;
break;
case PSEUDO_SETPG : /* SETPG pagelen */
if (!(dwOptions & OPTION_TSC))
skipspace();
nLinesPerPage = scanexpr(0, &p); /* get # lines per page */
if (nLinesPerPage < 10) /* adjust to boundary values */
nLinesPerPage = 10;
else if (nLinesPerPage > 1000)
nLinesPerPage = 1000;
curline->lvl |= LINCAT_INVISIBLE;
break;
case PSEUDO_SETLI : /* SETLI linelen */
if (!(dwOptions & OPTION_TSC))
skipspace();
nColsPerLine = scanexpr(0, &p); /* get # columns per line */
if (nColsPerLine < 40) /* adjust to boundary values */
nColsPerLine = 40;
else if (nColsPerLine > 2000)
nColsPerLine = 2000;
curline->lvl |= LINCAT_INVISIBLE;
break;
case PSEUDO_SYMLEN : /* SYMLEN symbollength */
if (!(dwOptions & OPTION_TSC))
skipspace();
maxidlen = scanexpr(0, &p); /* get # significant ID places */
if (maxidlen < 6) /* adjust to boundary values */
maxidlen = 6;
else if ((outmode == OUT_REL) &&
(maxidlen > 8))
maxidlen = 8;
else if (maxidlen > MAXIDLEN)
maxidlen = MAXIDLEN;
curline->lvl |= LINCAT_INVISIBLE;
break;
case PSEUDO_MACRO : /* label MACRO */
if (!lp) /* a macro NEEDS a label! */
error |= ERR_LABEL_MISSING;
if (lp->cat == SYMCAT_EMPTY)
{
if (nMacros < MAXMACROS) /* if space for another macro defin. */
{
lp->cat = SYMCAT_MACRO; /* remember it's a macro */
macros[nMacros] = curline; /* remember pointer to start line */
lp->value = nMacros++; /* and remember the macro */
}
else
error |= ERR_MALLOC;
}
else if (lp->cat != SYMCAT_MACRO ||
macros[lp->value] != curline)
error |= ERR_LABEL_MULT;
inMacro++;
curline->lvl |= LINCAT_MACDEF;
if (inMacro > 1)
error |= ERR_NESTING;
break;
case PSEUDO_ENDM : /* ENDM */
if (!inMacro)
error |= ERR_EXPR;
else
inMacro--;
break;
case PSEUDO_EXITM : /* EXITM */
if (!inMacro && /* only allowed inside macros */
!(curline->lvl & LINCAT_MACEXP))
error |= ERR_EXPR;
break;
case PSEUDO_REG : /* label REG <register list> */
if (!lp) /* label is mandatory! */
error |= ERR_LABEL_MISSING;
{
struct regrecord *p;
postbyte = 0;
do
{
if (*srcptr == ',')
srcptr++;
if (!(dwOptions & OPTION_TSC))
skipspace();
scanname();
if ((p = findreg(unamebuf)) == 0)
error |= ERR_ILLEGAL_ADDR;
else
postbyte |= p->psh;
if (!(dwOptions & OPTION_TSC))
skipspace();
} while (*srcptr == ',');
if (lp->cat == SYMCAT_EMPTY)
{
lp->cat = SYMCAT_REG;
lp->value = postbyte;
}
else if (lp->cat != SYMCAT_REG ||
lp->value != postbyte)
error |= ERR_LABEL_MULT;
}
break;
case PSEUDO_ERR : /* ERR text? */
if (!(dwOptions & OPTION_TSC))
skipspace();
if (pass != 1) /* ignore in pass 1 */
{
errormsg[14] = srcptr;
error |= ERR_ERRTXT;
}
break;
case PSEUDO_TEXT : /* TEXT text ? */
if (!(dwOptions & OPTION_TSC))
skipspace();
if (!lp) /* label is mandatory! */
error |= ERR_LABEL_MISSING;
else if (lp->cat != SYMCAT_EMPTY && /* and must be text, if there */
lp->cat != SYMCAT_TEXT)
error |= ERR_LABEL_MULT;
else /* if all OK, (re)define text */
settext(lp->name, srcptr);
break;
case PSEUDO_NAME : /* NAME <modulename> ? */
if (!(dwOptions & OPTION_TSC))
skipspace();
scanname();
if (!namebuf[0]) /* name must be given */
error |= ERR_EXPR;
strncpy(modulename, namebuf, 8);
break;
case PSEUDO_BINARY : /* BIN[ARY] <filename> ? */
nRepNext = 0; /* reset eventual repeat */
if (pass == 1) /* expand if in pass 1 */
{
char fname[FNLEN + 1];
int instring = 0;
char *osrc = srcptr;
 
if (!(dwOptions & OPTION_TSC))
skipspace();
if (*srcptr == '\"')
{
srcptr++;
instring = 1;
}
for (i = 0; i < FNLEN; i++)
{
if (*srcptr == 0 ||
(!instring && *srcptr == ' ') ||
*srcptr == '"')
break;
fname[i] = *srcptr++;
}
fname[i] = 0;
curline->lvl |= LINCAT_INVISIBLE; /* preclude listing of BINARY line */
readbinary(fname, /* append binary after current line */
(unsigned char)((curline->lvl & 0x0f) + 1),
curline, lp);
expandtext(); /* re-expand current line */
srcptr = osrc;
}
break;
}
}
 
/*****************************************************************************/
/* macskip : skips a range of macro lines */
/*****************************************************************************/
 
struct linebuf *macskip(struct linebuf *pmac, int nSkips)
{
if (nSkips < 0) /* we need to go to the line BEFORE */
nSkips--; /* the one we need! */
while (nSkips)
{
if (nSkips < 0)
{
if (!pmac->prev)
break;
pmac = pmac->prev;
nSkips++;
}
else
{
if (!pmac->next)
break;
pmac = pmac->next;
nSkips--;
}
}
return pmac;
}
 
/*****************************************************************************/
/* expandmacro : expands a macro definition below the current line */
/*****************************************************************************/
 
void expandmacro(struct symrecord *lp, struct symrecord *lpmac)
{
struct oprecord *op;
char szMacInv[LINELEN]; /* macro invocation line */
char szLine[LINELEN]; /* current macro line */
char *szMacParm[10];
char *s, *d; /* source / destination work pointers*/
char *srcsave = srcptr;
struct linebuf *cursave = curline;
int nMacParms = 1;
int nInString = 0;
int nMacLine = 1; /* current macro line */
/* current macro line */
struct linebuf *pmac = macros[lpmac->value]->next;
struct linebuf *pcur = curline; /* current expanded macro line */
struct linebuf *pdup = NULL; /* DUP start line */
int nDup = 0; /* # repetitions for DUP */
int terminate = 0; /* terminate macro expansion if set */
int skipit = 0; /* skip this line */
int suppress[64] = {0}; /* internal suppression (max.64 lvl) */
int ifcount = 0; /* internal if counter */
struct relocrecord p = {0};
 
if ((listing & LIST_ON) && /* if listing pass 1 */
(dwOptions & OPTION_LIS) &&
(dwOptions & OPTION_LP1))
outlist(NULL); /* show macro invocation BEFORE */
/* processing the expansions */
 
skipspace(); /* skip spaces before macro args */
 
if (!lp) /* if no macro label */
szMacParm[0] = ""; /* set &0 to blank */
else /* otherwise */
szMacParm[0] = lp->name; /* set &0 to line label */
/* initialize all parameters to "" */
for (nMacParms = 1; nMacParms < 10; nMacParms++)
szMacParm[nMacParms] = "";
nMacParms = 1; /* reset # parsed parms to 1 */
 
strcpy(szMacInv, srcptr); /* copy the current line for mangling*/
srcptr = szMacInv; /* set pointer to internal buffer */
do
{
while (*srcptr == ',') /* skip parameter delimiter(s) */
{
*srcptr++ = '\0'; /* delimit & advance behind it */
if (!(dwOptions & OPTION_TSC))
skipspace();
}
/* OK, next string... */
if ((*srcptr == '\'') || /* if delimited string */
(*srcptr == '\"'))
nInString = 1; /* remember we're in delimited strg */
szMacParm[nMacParms] = srcptr++; /* store parameter start pointer */
while (*srcptr) /* walk to end of parameter */
{
if (!nInString &&
((*srcptr == ' ') || (*srcptr == ',')))
break;
else if (nInString &&
*srcptr == *szMacParm[nMacParms])
{
srcptr++;
break;
}
srcptr++;
}
if (*srcptr && *srcptr != ',')
{
*srcptr++ = '\0';
if (!(dwOptions & OPTION_TSC))
skipspace();
}
nMacParms++;
if (nMacParms >= 10)
break;
} while (*srcptr == ',');
 
/*---------------------------------------------------------------------------*/
/* OK, got macro arguments &0...&9 now */
/*---------------------------------------------------------------------------*/
 
while (pmac) /* walk through the macro lines */
{
srcptr = s = pmac->txt;
d = szLine;
op = NULL;
skipit = 0;
 
while (*s) /* first, expand the line */
{
if (*s == '\\' && s[1] == '&')
{
s++;
*d++ = *s++;
}
else if (*s == '&' && s[1] >= '0' && s[1] <= '9')
{
strcpy(d, szMacParm[s[1] - '0']);
s += 2;
d += strlen(d);
}
else
*d++ = *s++;
}
*d = '\0';
 
srcptr = szLine; /* then, look whether code or macro */
if (isalnum(*srcptr))
{
scanname();
lp = findsym(namebuf, 1);
if (*srcptr == ':')
srcptr++;
}
skipspace();
if (isalnum(*srcptr)) /* then parse opcode */
{
scanname();
op = findop(unamebuf);
}
skipspace(); /* and skip to eventual parameter */
 
if (op && op->cat == OPCAT_PSEUDO) /* if pseudo-op */
{
switch (op->code) /* examine for macro expansion */
{
case PSEUDO_ENDM : /* ENDM ? */
terminate = 1; /* terminate macro expansion */
break;
case PSEUDO_EXITM : /* EXITM ? */
if (!suppress[ifcount]) /* if not suppressed */
terminate = 1; /* terminate macro expansion */
break;
case PSEUDO_DUP : /* DUP ? */
if (pdup != NULL) /* nesting not allowed */
error |= ERR_NESTING;
else
{
nDup = scanexpr(0, &p); /* scan the expression */
pdup = pmac; /* remember DUP start line */
if (nDup < 1 || nDup > 255) /* if invalid # repetitions */
{
error |= ERR_EXPR; /* set error here */
nDup = 1;
}
else
skipit = 1; /* skip this line */
}
break;
case PSEUDO_ENDD : /* ENDD ? */
if (!pdup) /* if no DUP defined */
error |= ERR_EXPR; /* can't do that here. */
else
{
nDup--; /* decrement # duplications */
if (!nDup) /* if done, */
pdup = NULL; /* reset dup start */
else /* otherwise */
pmac = pdup; /* reset current line to DUP op */
skipit = 1; /* this line isn't really there */
}
break;
case PSEUDO_IF : /* IF */
case PSEUDO_IFN : /* IFN */
ifcount++; /* increment # ifs */
/* take suppression from higher level*/
suppress[ifcount] = suppress[ifcount - 1];
if (suppress[ifcount]) /* if already suppressed */
suppress[ifcount]++; /* inrease # suppressions */
else /* otherwise evaluate expression */
{
operand = scanexpr(0, &p);
if (unknown)
error |= ERR_LABEL_UNDEF;
if (op->code == PSEUDO_IFN) /* if IFN */
operand = !operand; /* invert operand */
if (!operand) /* if evaulation to zer0 */
suppress[ifcount]++; /* suppress until ELSE or ENDIF */
if (!(dwOptions & OPTION_TSC))
skipspace();
if (*srcptr == ',') /* if skip count passed */
{
int nSkips;
srcptr++;
if (!(dwOptions & OPTION_TSC))
skipspace();
nSkips = scanexpr(0, &p); /* scan skip count */
ifcount--; /* this needs no ENDIF */
if (nSkips < -255 || nSkips > 255 || nSkips == 0)
{
error |= ERR_EXPR;
break;
}
if (operand) /* if evaluation is true */
pmac = macskip(pmac, nSkips); /* then skip the amount of lines */
}
}
skipit = 1; /* don't add this line! */
break;
case PSEUDO_IFC : /* IFC */
case PSEUDO_IFNC : /* IFNC */
ifcount++; /* increment # ifs */
/* take suppression from higher level*/
suppress[ifcount] = suppress[ifcount - 1];
if (suppress[ifcount]) /* if already suppressed */
suppress[ifcount]++; /* inrease # suppressions */
else /* otherwise evaluate expression */
{
if (!(dwOptions & OPTION_TSC))
skipspace();
scanstring(szBuf1, sizeof(szBuf1));
if (!(dwOptions & OPTION_TSC))
skipspace();
if (*srcptr != ',') /* if not on comma */
{
*szBuf2 = '\0'; /* reset 2nd string */
error |= ERR_EXPR; /* set error */
}
else
{
srcptr++;
if (!(dwOptions & OPTION_TSC))
skipspace();
scanstring(szBuf2, sizeof(szBuf2));
}
operand = !strcmp(szBuf1, szBuf2);
if (op->code == PSEUDO_IFNC)
operand = !operand;
if (!operand) /* if evaulation to zer0 */
suppress[ifcount]++; /* suppress until ELSE or ENDIF */
if (!(dwOptions & OPTION_TSC))
skipspace();
if (*srcptr == ',') /* if skip count passed */
{
int nSkips;
srcptr++;
if (!(dwOptions & OPTION_TSC))
skipspace();
nSkips = scanexpr(0, &p); /* scan skip count */
ifcount--; /* this needs no ENDIF */
if (nSkips < -255 || nSkips > 255 || nSkips == 0)
{
error |= ERR_EXPR;
break;
}
if (operand) /* if evaluation is true */
pmac = macskip(pmac, nSkips); /* then skip the amount of lines */
}
}
if (!error)
skipit = 1; /* don't add this line! */
break;
case PSEUDO_ELSE : /* ELSE */
if (!suppress[ifcount]) /* if IF not suppressed */
suppress[ifcount]++; /* suppress ELSE clause */
else /* otherwise */
suppress[ifcount]--; /* decrement suppression */
skipit = 1; /* don't add this line! */
break;
case PSEUDO_ENDIF : /* ENDIF */
if (ifcount)
ifcount--;
if (suppress[ifcount])
suppress[ifcount]--;
skipit = 1; /* don't add this line! */
break;
}
}
 
if (terminate) /* if macro termination needed */
break; /* terminate here */
 
if (!skipit && !suppress[ifcount]) /* if not skipping this one */
{ /* add line to source */
pcur = allocline(pcur, curline->fn, curline->ln, LINCAT_MACEXP, szLine);
if (!pcur)
{
error |= ERR_MALLOC;
break;
}
else
{
curline = pcur;
error = ERR_OK;
warning = WRN_OK;
expandtext();
processline();
}
}
pmac = pmac->next;
}
 
curline = cursave;
expandtext();
srcptr = srcsave; /* restore source pointer */
codeptr = 0;
}
 
/*****************************************************************************/
/* processline : processes a source line */
/*****************************************************************************/
 
void processline()
{
struct symrecord *lp, *lpmac;
struct oprecord *op = NULL;
__int64 co;
short cat;
short c;
char noimm;
 
#if 0
srcptr = curline->txt;
#else
srcptr = srcline;
#endif
 
oldlc = loccounter;
unknown = 0;
certain = 1;
lp = 0;
codeptr = 0;
condline = 0;
isFar = 0;
isFarkw = 0;
 
if (inMacro)
curline->lvl |= LINCAT_MACDEF;
 
if (isalnum(*srcptr)) /* look for label on line start */
{
scanname();
if (stricmp(namebuf, "far")==0) {
isFar = 1;
isFarkw = 1;
while(*srcptr==' ' || *srcptr=='\t') srcptr++;
scanname();
}
lp = findsym(namebuf, 1);
if (*srcptr == ':')
srcptr++;
 
if ((lp) &&
(lp->cat != SYMCAT_COMMONDATA) &&
(lp->u.flags & SYMFLAG_FORWARD))
lp->u.flags |= SYMFLAG_PASSED;
}
skipspace();
if ((isalnum(*srcptr)) ||
((dwOptions & OPTION_GAS) && (*srcptr == '.')))
{
scanname();
if ((dwOptions & OPTION_H63) && /* eventually adjust some mnemonics */
((!strcmp(unamebuf, "ASLD")) || /* that are available in the 6309 */
(!strcmp(unamebuf, "ASRD")) || /* but are implemented as (slower) */
(!strcmp(unamebuf, "LSLD")) || /* convenience instructions on the */
(!strcmp(unamebuf, "LSRD")) || /* 6809 */
(!strcmp(unamebuf, "DECD")) ||
(!strcmp(unamebuf, "INCD")) ||
(!strcmp(unamebuf, "CLRD"))))
strcat(unamebuf, "63");
op = findop(unamebuf);
if (op)
{
if ((dwOptions & OPTION_TSC)) /* if TSC compatible, skip space NOW */
skipspace(); /* since it's not allowed inside arg */
if (op->cat != OPCAT_PSEUDO)
{
setlabel(lp);
generating = 1;
}
co = op->code;
cat = op->cat;
/* only pseudo-ops in common mode! */
if (common && (cat != OPCAT_PSEUDO))
error |= ERR_EXPR;
 
noimm = cat & OPCAT_NOIMM; /* isolate "no immediate possible" */
cat &= ~OPCAT_NOIMM;
if (dwOptions & OPTION_X32)
isX32 = 1;
else
isX32 = 0;
if (dwOptions & OPTION_H63) /* if in HD6309 mode, */
cat &= ~OPCAT_6309; /* mask out the 6309 flag (=allow) */
switch (cat)
{
case OPCAT_ONEBYTE :
onebyte(co);
break;
case OPCAT_TWOBYTE :
twobyte(co);
break;
case OPCAT_THREEBYTE :
threebyte(co);
break;
case OPCAT_FOURBYTE :
fourbyte(co);
break;
case OPCAT_2IMMBYTE : /* 6309 only */
putbyte((unsigned short)(co >> 12LL));
/* fall thru on purpose! */
case OPCAT_IMMBYTE :
oneimm(co);
break;
case OPCAT_LEA :
lea(co);
break;
case OPCAT_SBRANCH :
sbranch(co);
break;
case OPCAT_LBR2BYTE :
lbranch(co);
break;
case OPCAT_LBR1BYTE :
lbra(co);
break;
case OPCAT_2ARITH : /* 6309 only */
putbyte((unsigned short)(co >> 12));
/* fall thru on purpose! */
case OPCAT_ARITH :
arith(co, noimm);
break;
case OPCAT_ACCARITH : /* 6800-style arith */
accarith(co, noimm, 0);
break;
case OPCAT_DBLREG1BYTE :
darith(co, noimm, op->tgtNdx);
break;
case OPCAT_DBLREG2BYTE :
d2arith(co, noimm, op->tgtNdx);
break;
case OPCAT_SINGLEADDR :
oneaddr(co);
break;
case OPCAT_IREG : /* 6309 only */
putbyte((unsigned short)(co >> 12));
/* fall thru on purpose! */
case OPCAT_2REG :
tfrexg(co);
break;
case OPCAT_STACK :
pshpul(co);
break;
case OPCAT_BITDIRECT : /* 6309 only */
bitdirect(co);
break;
case OPCAT_BITTRANS : /* 6309 only */
bittrans(co);
break;
case OPCAT_BLOCKTRANS : /* 6309 only */
blocktrans(co);
break;
case OPCAT_QUADREG1BYTE :
qarith(co, noimm);
break;
case OPCAT_IDXEXT :
idxextarith(co);
break;
case OPCAT_ACCADDR :
accaddr(co);
break;
case OPCAT_PSEUDO :
pseudoop(co, lp);
break;
default :
error |= ERR_ILLEGAL_MNEM;
break;
}
c = *srcptr; /* get current character */
if (((dwOptions & OPTION_TSC) && (c == '*')) ||
((dwOptions & OPTION_GAS) && (c == '|')) ||
(c == ';'))
c = '\0';
if (c != ' ' &&
*(srcptr - 1) != ' ' &&
c != '\0')
error |= ERR_ILLEGAL_ADDR;
}
else
{
lpmac = findsym(namebuf, 0); /* look whether opcode is a macro */
if (lpmac && lpmac->cat == SYMCAT_MACRO)
{
if (pass == 1) /* if in pass 1 */
expandmacro(lp, lpmac); /* expand macro below current line */
}
else
error |= ERR_ILLEGAL_MNEM;
}
}
else
{
nRepNext = 0; /* reset eventual repeat if no code */
setlabel(lp);
}
 
if (inMacro) /* if in macro definition */
{
codeptr = 0; /* ignore the code */
error &= (ERR_MALLOC | ERR_NESTING); /* ignore most errors */
warning &= WRN_SYM; /* ignore most warnings */
}
 
if (pass == MAX_PASSNO)
{
outbuffer();
if ((listing & LIST_ON) &&
(dwOptions & OPTION_LIS))
outlist(op);
}
else if ((listing & LIST_ON) &&
(dwOptions & OPTION_LIS) &&
(dwOptions & OPTION_LP1))
{
if (curline->lvl & LINCAT_MACEXP || /* prevent 2nd listing of macro */
!curline->next || /* since this is done in expansion */
!(curline->next->lvl & LINCAT_MACEXP))
outlist(op);
}
 
if (error || warning)
report();
loccounter += codeptr;
}
 
/*****************************************************************************/
/* suppressline : suppresses a line */
/*****************************************************************************/
 
void suppressline()
{
struct oprecord * op = NULL;
 
srcptr = srcline;
oldlc = loccounter;
codeptr = 0;
condline = 0;
if (nSkipCount > 0)
{
nSkipCount--;
condline = 1; /* this is STILL conditional */
}
else
{
if (isalnum(*srcptr))
{
scanname();
if (*srcptr == ':')
srcptr++;
}
skipspace();
scanname();
op = findop(unamebuf);
if (op && op->cat == OPCAT_PSEUDO) /* examine pseudo-ops in detail */
{
if ((op->code == PSEUDO_IF) || /* IF variants */
(op->code == PSEUDO_IFN) ||
(op->code == PSEUDO_IFC) ||
(op->code == PSEUDO_IFNC) ||
(op->code == PSEUDO_IFD) ||
(op->code == PSEUDO_IFND))
{
ifcount++;
condline = 1; /* this is a conditional line */
}
else if (op->code == PSEUDO_ENDIF) /* ENDIF */
{
if (ifcount > 0)
ifcount--;
else if (suppress == 1 || suppress == 2)
suppress = 0;
condline = 1; /* this is a conditional line */
}
else if (op->code == PSEUDO_ELSE) /* ELSE */
{
if (ifcount == 0 && suppress == 2)
suppress = 0;
condline = 1; /* this is a conditional line */
}
}
}
 
if (((pass == MAX_PASSNO) || (dwOptions & OPTION_LP1)) &&
(listing & LIST_ON) &&
(dwOptions & OPTION_LIS))
outlist(op);
}
 
/*****************************************************************************/
/* usage : prints out correct usage */
/*****************************************************************************/
 
void usage(char *nm)
{
printf("Usage: %s [-option*] srcname*\n",
nm ? nm : "a09");
printf("Available options are:\n");
printf("-B[objname] ........ output to binary file (default)\n");
printf("-F[objname] ........ output to FLEX binary file\n");
/* printf("-G[objname] ........ output Gnu .o format file\n"); */
printf("-R[objname] ........ output to FLEX relocatable object file\n");
printf("-S[objname] ........ output to Motorola S51-09 file\n");
printf("-X[objname] ........ output to Intel Hex file\n");
printf("-L[listname] ....... create listing file \n");
printf("-V[objname]......... output Verilog rommem declarations \n");
printf("-C ................. suppress code output\n");
printf("-Dsymbol[=value] ... predefines a symbol\n");
printf(" for TSC 6809 Assembler compatibility,\n");
printf(" you should only use symbols A through C\n");
printf("-Ooption ........... sets an option (as in OPT pseudoop)\n");
printf("-W ................. suppress warnings\n");
printf("srcname ............ source file name(s)\n");
 
exit(2);
}
 
/*****************************************************************************/
/* getoptions : retrieves the options from the passed argument array */
/*****************************************************************************/
 
void getoptions (int argc, char* argv[])
{
int i, j;
char *ld;
 
for (i = 1; i < argc; i++)
{
#if !UNIX
/* code for DOS / Windows / OS2 */
if ((argv[i][0] == '-') ||
(argv[i][0] == '/'))
#else
/* code for UNIX derivates */
if (argv[i][0] == '-')
#endif
{
for (j = 1; j < (int)strlen(argv[i]); j++)
{
switch (tolower(argv[i][j]))
{
case 'c' : /* suppress code output */
outmode = OUT_NONE;
break;
case 'b' : /* define binary output file */
case 's' : /* define Motorola output file */
case 'x' : /* define Intel Hex output file */
case 'f' : /* define FLEX output file */
case 'r' : /* define FLEX relocatable output f. */
case 'v' :
/* case 'g' : */ /* define GNU output file */
strcpy(objname, /* copy in the name */
argv[i] + j + 1);
switch (tolower(argv[i][j])) /* then set output mode */
{
case 'b' :
outmode = OUT_BIN;
break;
case 's' :
outmode = OUT_SREC;
break;
case 'x' :
outmode = OUT_IHEX;
break;
case 'f' :
outmode = OUT_FLEX;
break;
case 'v':
outmode = OUT_VER;
break;
/*
case 'g' :
outmode = OUT_GAS;
relocatable = 1;
dwOptions |= OPTION_REL;
break;
*/
case 'r' :
outmode = OUT_REL;
maxidlen = 8; /* only 8 significant ID chars! */
relocatable = 1;
absmode = 0;
break;
}
j = strlen(argv[i]); /* advance behind copied name */
break;
case 'l' : /* define listing file */
strcpy(listname, /* copy in the name */
argv[i] + j + 1);
j = strlen(argv[i]); /* advance behind copied name */
listing = LIST_ON; /* remember we're listing */
break;
case 'd' : /* define a symbol ? */
srcptr = argv[i] + j + 1; /* parse in the name */
scanname();
if (!namebuf[0]) /* if no name there */
usage(argv[0]); /* show usage and get out */
if (*srcptr == '=') /* if followed by value */
srcptr++; /* advance behind it */
else /* otherwise go to "" */
srcptr = argv[i] + strlen(argv[i]);
settext(namebuf, srcptr); /* define the symbol */
j = strlen(argv[i]); /* advance behind copied name */
break;
case 'o' : /* option */
if (setoption(argv[i] + j + 1))
usage(argv[0]);
j = strlen(argv[i]); /* advance behind option */
break;
}
}
for (j = i; j < argc; j++) /* remove all consumed arguments */
argv[j] = argv[j + 1];
argc--; /* reduce # arguments */
i--; /* and restart with next one */
}
}
 
if (argc < 2) /* if not at least one filename left */
usage(argv[0]); /* complain & terminate */
 
strcpy(srcname, argv[1]); /* copy it in. */
 
if (!objname[0]) /* if no object name defined */
{
strcpy(objname, srcname); /* copy in the source name */
ld = strrchr(objname, '.'); /* look whether there's a dot in it */
if (!ld) /* if not */
ld = objname + strlen(objname); /* append extension */
switch (outmode) /* which output mode? */
{
case OUT_BIN : /* binary ? */
#if !UNIX
strcpy(ld, ".bin"); /* DOS / Windows / OS2 */
#else
strcpy(ld, ".b"); /* UNIX */
#endif
break;
case OUT_SREC : /* Motorola S51-09 ? */
strcpy(ld, ".s09");
break;
case OUT_IHEX : /* Intel Hex ? */
strcpy(ld, ".hex");
break;
case OUT_FLEX : /* FLEX binary ? */
strcpy(ld, ".bin");
break;
case OUT_GAS : /* GNU relocatable object ? */
strcpy(ld, ".o");
break;
case OUT_REL : /* Flex9 relocatable object ? */
strcpy(ld, ".rel");
break;
case OUT_VER : /* Verilog texr */
strcpy(ld, ".ver");
break;
}
}
 
if ((listing & LIST_ON) && !listname[0])/* if no list file specified */
{
strcpy(listname, srcname); /* copy in the source name */
ld = strrchr(listname, '.'); /* look whether there's a dot in it */
if (!ld) /* if not */
ld = listname + strlen(listname); /* append extension */
strcpy(ld, ".lst"); /* .lst */
}
}
 
/*****************************************************************************/
/* processfile : processes the input file */
/*****************************************************************************/
 
void processfile(struct linebuf *pline)
{
struct linebuf *plast = pline;
vercount = 0;
while (!terminate && pline)
{
curline = pline;
error = ERR_OK;
warning = WRN_OK;
expandtext(); /* expand text symbols */
srcptr = srcline;
if (suppress || nSkipCount)
suppressline();
else
{
if (nRepNext)
{
for (; nRepNext > 0; nRepNext--)
{
processline();
error = ERR_OK;
warning = WRN_OK;
}
nRepNext = 0;
}
else
{
if (pass != 1 ||
!(curline->lvl & LINCAT_MACEXP))
processline();
error = ERR_OK;
warning = WRN_OK;
}
}
plast = pline;
pline = pline->next;
}
 
if (suppress)
{
printf("%s(%ld) : error 18: improperly nested IF statements\n",
expandfn(plast->fn), plast->ln);
if (((dwOptions & OPTION_LP1) || pass == MAX_PASSNO) &&
(listing & LIST_ON))
putlist( "*** Error 18: improperly nested IF statements\n");
errors++;
suppress = 0;
}
 
if (common)
{
printf("%s(%ld) : error 24: improperly nested COMMON statements\n",
expandfn(plast->fn), plast->ln);
if (((dwOptions & OPTION_LP1) || pass == MAX_PASSNO) &&
(listing & LIST_ON))
putlist( "*** Error 24: improperly nested COMMON statements\n");
errors++;
common = 0;
}
}
 
void dopass(int passno, int lastpass)
{
int i;
char buf[4];
sprintf(buf, "%d", passno);
pass = passno;
settext("PASS", buf);
loccounter = 0;
errors = 0;
warnings = 0;
generating = 0;
terminate = 0;
 
for (i = 0; i < symcounter; i++) /* reset all PASSED flags */
if (symtable[i].cat != SYMCAT_COMMONDATA)
symtable[i].u.flags &= ~SYMFLAG_PASSED;
 
if (lastpass) {
if (listing & LIST_ON)
{
if ((dwOptions & OPTION_LP1))
{
if (dwOptions & OPTION_PAG)
PageFeed();
else
putlist("\n");
putlist( "*** Pass 2 ***\n\n");
}
else if (nTotErrors || nTotWarnings)
putlist( "%ld error(s), %ld warning(s) unlisted in pass 1\n",
nTotErrors, nTotWarnings);
}
 
if ((outmode >= OUT_BIN) &&
((objfile = fopen(objname,
((outmode != OUT_SREC) && (outmode != OUT_IHEX)) ? "wb" : "w"))
== 0))
{
printf("%s(0) : error 20: cannot write object file %s\n", srcname, objname);
if (((dwOptions & OPTION_LP1) || pass == MAX_PASSNO) && (listing & LIST_ON))
putlist( "*** Error 20: cannot write object file %s\n", objname);
exit(4);
}
 
if (outmode == OUT_REL) /* if writing FLEX Relocatable */
{
writerelcommon(); /* write out common blocks */
relhdrfoff = ftell(objfile);
writerelhdr(0); /* write out initial header */
}
}
processfile(rootline);
 
if (errors)
{
printf("%ld error(s) in pass %d\n", errors, passno);
nTotErrors += errors;
}
if (warnings)
{
printf("%ld warning(s) in pass %d\n", warnings, passno);
nTotWarnings += warnings;
}
 
}
 
/*****************************************************************************/
/* main : the main function */
/*****************************************************************************/
 
int main (int argc, char *argv[])
{
int i;
struct linebuf *pLastLine = NULL;
 
settext("ASM", "A09"); /* initialize predefined texts */
settext("VERSION", VERSNUM);
settext("PASS", "1");
setoptiontexts();
nPredefinedTexts = nTexts;
 
getoptions(argc, argv);
pass = 1;
error = 0;
warning = 0;
nTotErrors = errors = 0;
nTotWarnings = warnings = 0;
generating = 0;
common = 0;
terminate = 0;
if (!absmode) /* in relocating mode */
dpsetting = -1; /* there IS no Direct Page */
 
printf("A09 Assembler V" VERSION "\n");
 
if ((listing & LIST_ON) &&
((listfile = fopen(listname, "w")) == 0))
{
printf("%s(0) : error 19: Cannot open list file %s\n", srcname, listname);
exit(4);
}
 
for (i = 1; argv[i]; i++) /* read in all source files */
pLastLine = readfile(argv[i], 0, pLastLine);
if (!rootline) /* if no lines in there */
{
printf("%s(0) : error 23: no source lines in file\n", srcname);
if (((dwOptions & OPTION_LP1) || pass == MAX_PASSNO) &&
(listing & LIST_ON))
putlist( "*** Error 23: no source lines in file\n");
exit(4);
}
 
/* Pass 1 - parse all symbols */
if ((listing & LIST_ON) && (dwOptions & OPTION_LP1))
putlist( "*** Pass 1 ***\n\n");
 
processfile(rootline);
if (errors)
{
printf("%ld error(s) in pass 1\n",errors);
if ((listing & LIST_ON) && (dwOptions & OPTION_LP1))
putlist( "%ld error(s) in pass 1.\n", errors);
nTotErrors = errors;
}
if (warnings)
{
printf("%ld warning(s) in pass 1\n", warnings);
if ((listing & LIST_ON) && (dwOptions & OPTION_LP1))
putlist(
"%ld warning(s) in pass 1.\n", warnings);
nTotWarnings = warnings;
}
 
// Resolve potential phasing errors by performing multiple passes.
dopass(2,0);
dopass(3,0);
dopass(4,0);
dopass(5,0);
dopass(6,0);
dopass(7,0);
dopass(8,0);
dopass(9,1);
// /* Pass 2 - generate output */
//settext("PASS", "3");
//loccounter = 0;
//errors = 0;
//warnings = 0;
//generating = 0;
//terminate = 0;
////memset(bUsedBytes, 0, sizeof(bUsedBytes));
//for (i = 0; i < symcounter; i++) /* reset all PASSED flags */
// if (symtable[i].cat != SYMCAT_COMMONDATA)
// symtable[i].u.flags &= ~SYMFLAG_PASSED;
//
//if (listing & LIST_ON)
// {
// if ((dwOptions & OPTION_LP1))
// {
// if (dwOptions & OPTION_PAG)
// PageFeed();
// else
// putlist("\n");
// putlist( "*** Pass 2 ***\n\n");
// }
// else if (nTotErrors || nTotWarnings)
// putlist( "%ld error(s), %ld warning(s) unlisted in pass 1\n",
// nTotErrors, nTotWarnings);
// }
//
//if ((outmode >= OUT_BIN) &&
// ((objfile = fopen(objname,
// ((outmode != OUT_SREC) && (outmode != OUT_IHEX)) ? "wb" : "w"))
// == 0))
// {
// printf("%s(0) : error 20: cannot write object file %s\n", srcname, objname);
// if (((dwOptions & OPTION_LP1) || pass == 2) && (listing & LIST_ON))
// putlist( "*** Error 20: cannot write object file %s\n", objname);
// exit(4);
// }
//
//if (outmode == OUT_REL) /* if writing FLEX Relocatable */
// {
// writerelcommon(); /* write out common blocks */
// relhdrfoff = ftell(objfile);
// writerelhdr(0); /* write out initial header */
// }
//
//processfile(rootline);
//
//if (errors)
// {
// printf("%ld error(s) in pass 2\n", errors);
// nTotErrors += errors;
// }
//if (warnings)
// {
// printf("%ld warning(s) in pass 2\n", warnings);
// nTotWarnings += warnings;
// }
 
if (listing & LIST_ON)
{
if (errors || warnings)
putlist("\n");
if (errors)
putlist( "%ld error(s) in pass 2.\n", errors);
if (warnings)
putlist( "%ld warning(s) in pass 2.\n", warnings);
if (dwOptions & OPTION_SYM)
outsymtable();
if ((relocatable) && (dwOptions & OPTION_REL))
outreltable();
if ((dwOptions & OPTION_TXT) &&
(nPredefinedTexts < nTexts))
outtexttable();
 
putlist( "\n%ld error(s), %ld warning(s)\n",
nTotErrors, nTotWarnings);
fclose(listfile);
}
else
printf("Last assembled address: %04X\n", loccounter - 1);
 
switch (outmode) /* look whether object cleanup needed*/
{
case OUT_VER:
flushver();
break;
case OUT_SREC : /* Motorola S51-09 */
flushhex();
chksum = (tfradr & 0xff) + ((tfradr >> 8) & 0xff) + 3;
fprintf(objfile, "S903%04X%02X\n", tfradr, 0xff - (chksum & 0xff));
break;
case OUT_IHEX : /* Intel Hex */
flushihex();
#if 0
/* put transfer address in here... unfortunately, the official
Intel documentation doesn't allow this mechanism */
chksum = ((tfradr >> 8) & 0xff) + (tfradr & 0xff) + 1;
fprintf(objfile, ":00%04X01%02X\n", tfradr, (-(signed)chksum) & 0xff);
#else
fprintf(objfile, ":00000001FF\n");
#endif
break;
case OUT_FLEX : /* FLEX binary */
flushflex();
if (tfradrset) /* if transfer address set */
{ /* write out transfer address block */
fputc(0x16, objfile);
fputc((tfradr >> 8) & 0xff, objfile);
fputc(tfradr & 0xff, objfile);
}
break;
case OUT_REL : /* FLEX Relocatable */
writerelext(); /* write out External table */
writerelglobal(); /* write out Global table */
writerelmodname(); /* write out Module Name */
 
i = (int)ftell(objfile); /* fill last sector with zeroes */
while (i % 252)
{
fputc(0, objfile);
i++;
}
/* reposition on header */
fseek(objfile, relhdrfoff, SEEK_SET);
writerelhdr(0); /* rewrite completed header */
break;
}
 
if (objfile)
fclose(objfile);
 
if (errors)
unlink(objname);
 
return (errors) ? 1 : 0;
}
/rf6809/trunk/software/boot/boot_rom.asm
0,0 → 1,1527
; ============================================================================
; __
; \\__/ o\ (C) 2013-2022 Robert Finch, Stratford
; \ __ / All rights reserved.
; \/_// robfinch<remove>@opencores.org
; ||
;
;
; This source file is free software: you can redistribute it and/or modify
; it under the terms of the GNU Lesser General Public License as published
; by the Free Software Foundation, either version 3 of the License, or
; (at your option) any later version.
;
; This source file is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with this program. If not, see <http://www.gnu.org/licenses/>.
;
; ============================================================================
;
CR EQU $0D ;ASCII equates
LF EQU $0A
TAB EQU $09
CTRLC EQU $03
CTRLH EQU $08
CTRLI EQU $09
CTRLJ EQU $0A
CTRLK EQU $0B
CTRLM EQU $0D
CTRLS EQU $13
CTRLX EQU $18
XON EQU $11
XOFF EQU $13
 
FIRST_CORE EQU 1
MAX_TASKNO EQU 63
DRAM_BASE EQU $10000000
 
ScreenLocation EQU $10
ColorCodeLocation EQU $14
ScreenLocation2 EQU $18
BlkcpySrc EQU $1C
BlkcpyDst EQU $20
Strptr EQU $24
PICptr EQU $28
; Forth Area
; 0x30-0x60
 
RunningID EQU $800000
 
; Task control blocks, room for 256 tasks
TCB_NxtRdy EQU $00 ; next task on ready / timeout list
TCB_PrvRdy EQU $04 ; previous task on ready / timeout list
TCB_NxtTCB EQU $08
TCB_Timeout EQU $0C
TCB_Priority EQU $10
TCB_MSGPTR_D1 EQU $14
TCB_MSGPTR_D2 EQU $18
TCB_hJCB EQU $1C
TCB_Status EQU $1E
TCB_CursorRow EQU $20
TCB_CursorCol EQU $21
TCB_hWaitMbx EQU $22 ; handle of mailbox task is waiting at
TCB_mbq_next EQU $24 ; mailbox queue next
TCB_mbq_prev EQU $28 ; mailbox queue previous
TCB_iof_next EQU $2C
TCB_iof_prev EQU $30
TCB_SPSave EQU $34 ; TCB_SPSave area
TCB_mmu_map EQU $38
 
KeybdHead EQU $FFFFFC800
KeybdTail EQU $FFFFFC900
KeybdEcho EQU $FFFFFCA00
KeybdBad EQU $FFFFFCB00
KeybdAck EQU $FFFFFCC00
KeybdLocks EQU $FFFFFCD00
KeybdBuffer EQU $FFFFFC000 ; buffer is 16 chars
 
COREID EQU $FFFFFFFE0
MSCOUNT EQU $FFFFFFFE4
LEDS EQU $FFFE60000
TEXTSCR EQU $FFFE00000
TEXTREG EQU $FFFE0DF00
TEXT_COLS EQU 0
TEXT_ROWS EQU 1
TEXT_CURPOS EQU 34
KEYBD EQU $FFFE30400
KEYBDCLR EQU $FFFE30402
PIC EQU $FFFE3F000
SPRITE_CTRL EQU $FFFE10000
SPRITE_EN EQU $3C0
 
BIOS_SCREENS EQU $17000000 ; $17000000 to $171FFFFF
 
; EhBASIC vars:
;
NmiBase EQU $DC
IrqBase EQU $DF
 
; The IO focus list is a doubly linked list formed into a ring.
;
IOFocusNdx EQU $100
IOFocusID EQU $100
 
; These variables use direct page access
CursorRow EQU $110
CursorCol EQU $111
CharColor EQU $112
ScreenColor EQU $113
CursorFlash EQU $114
KeyState1 EQU $120
KeyState2 EQU $121
KeyLED EQU $122
KeybdID EQU $124
 
QNdx0 EQU $780
QNdx1 EQU QNdx0+2
QNdx2 EQU QNdx1+2
QNdx3 EQU QNdx2+2
QNdx4 EQU QNdx3+2
FreeTCB EQU QNdx4+2
TimeoutList EQU FreeTCB+2
FreeMbx EQU RunningTCB + 2
nMailbox EQU FreeMbx + 2
FreeMsg EQU nMailbox + 2
nMsgBlk EQU FreeMsg + 2
 
IrqSource EQU $79A
 
IRQFlag EQU $7C6
 
CharOutVec EQU $800
CharInVec EQU $804
 
; Register save area for monitor
mon_DSAVE EQU $900
mon_XSAVE EQU $902
mon_YSAVE EQU $904
mon_USAVE EQU $906
mon_SSAVE EQU $908
mon_PCSAVE EQU $90A
mon_DPRSAVE EQU $90E
mon_CCRSAVE EQU $90F
 
mon_numwka EQU $910
mon_r1 EQU $920
mon_r2 EQU $922
 
; The ORG directive must set an address a multiple of 4 in order for the Verilog
; output to work correctly.
 
org $FFD0AC
nop
nop
nop
XBLANK
ldb #' '
lbsr OUTCH
rts
 
org $FFD0D0
nop
nop
CRLF
CRLF1:
ldb #CR
lbsr OUTCH
ldb #LF
lbsr OUTCH
rts
 
org $FFD0F0
nop
bra CRLF1
 
org $FFD1DC
ONEKEY
jmp [CharInVec]
 
org $FFD2C0
nop
LETTER
lbsr OUTCH
rts
 
org $FFD2CC
nop
nop
HEX2
lbsr DispByteAsHex
rts
HEX4
lbsr DispWordAsHex
rts
 
org $FFD300
ClearScreenJmp
lbra ClearScreen
org $FFD308
HomeCursorJmp
lbra HomeCursor
 
org $FFE000
 
; Local RAM test routine
; Checkerboard testing.
; There is 70kB of local RAM
; Does not use any RAM including no stack
 
ramtest:
ldy #0
lda #1
sta LEDS
ldd #$AAA555
ramtest1:
std ,y++
cmpy #$C00000
blo ramtest1
; now readback values and compare
ldy #0
ramtest3:
ldd ,y++
cmpd #$AAA555
bne ramerr
cmpy #$C00000
blo ramtest3
lda #2
sta LEDS
jmp ,u
ramerr:
lda #$80
sta LEDS
ldx #TEXTSCR
ldb COREID
abx
lda #'F'
sta ,x
sync
jmp ,u
 
org $FFF000
FDB Monitor
FDB DumRts ; NEXTCMD
FDB INCH
FDB INCHE
FDB INCHEK
FDB OUTCH
FDB PDATA
FDB PCRLF
FDB PSTRNG
FDB DumRts ; LRA
FDB DumRts
FDB DumRts
FDB DumRts
FDB DumRts ; VINIZ
FDB DisplayChar ; VOUTCH
FDB DumRts ; ACINIZ
FDB DumRts ; AOUTCH
 
DumRts:
rts
 
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
 
start:
lda #$55 ; see if we can at least set LEDs
sta LEDS
ldu #st6 ; U = return address
jmp ramtest ; JMP dont JSR
st6:
lds #$3FFF ; boot up stack area
lda COREID
cmpa #FIRST_CORE
; beq st8
; sync ; halt cores other than 2
st8:
; bne skip_init
; bsr romToRam
; ldd #st7 & $FFFF
; tfr d,x
; jmp ,x ; jump to the BIOS now in local RAM
st7:
bsr Delay3s ; give some time for devices to reset
lda #$AA
sta LEDS
lda #2
sta IOFocusID ; core #2 has focus
sta RunningID
lda #$0CE
sta ScreenColor
sta CharColor
bsr ClearScreen
ldd #DisplayChar
std CharOutVec
ldd #DBGGetKey
std CharInVec
ldb COREID
cmpb #FIRST_CORE
beq init
bra skip_init
bra multi_sieve
st3:
lda #$FF
sta LEDS
bra st3
 
; initialize interrupt controller
; first, zero out all the vectors
init:
ldx #128
lda #1 ; set irq(bit0), clear firq (bit1), disable int (bit 6), clear edge sense(bit 7)
ldb #FIRST_CORE ; serving core id
st1:
clr PIC,x ; cause code
sta PIC+1,x
stb PIC+2,x
leax 4,x
cmpx #256
blo st1
; lda #4 ; make the timer interrupt edge sensitive
; sta PIC+4 ; reg #4 is the edge sensitivity setting
; sta PIC ; reg #0 is interrupt enable
 
skip_init:
andcc #$EF ; unmask irq
lda #56
sta TEXTREG+TEXT_COLS
lda #29
sta TEXTREG+TEXT_ROWS
bsr ClearScreen
bsr HomeCursor
lda #5
sta LEDS
ldd #msgStartup
bsr DisplayString
ldx #0
ldd #0
lbsr ShowSprites
lbsr KeybdInit
ldd KeybdID
bsr DispWordAsHex
jmp MonitorStart
 
msgStartup
fcb "rf6809 12-bit System Starting.",CR,LF,0
 
;------------------------------------------------------------------------------
; The checkpoint register must be cleared within 1 second or a NMI interrupt
; will occur. checkpoint should be called with a JSR so that the global ROM
; routine is called.
;
; Modifies:
; none
;------------------------------------------------------------------------------
 
checkpoint:
clr $FFFFFFFE1 ; writing any value will do
rts
 
;------------------------------------------------------------------------------
; Copy the system ROM to local RAM
; Running the code from local RAM is probably an order of magnitude faster
; then running from the global ROM. It also reduces the network traffic to
; run from local RAM.
;
; Modifies:
; d,x,y
;------------------------------------------------------------------------------
 
romToRam:
ldx #$FFC000
ldy #$00C000
romToRam1:
ldd ,x++
std ,y++
cmpx #0
bne romToRam1
rts
 
;------------------------------------------------------------------------------
; Multi-core sieve program.
;------------------------------------------------------------------------------
 
; First fill screen chars with 'P' indicating prime positions
; Each core is responsible for the Nth position where N is the
; core number minus two.
;
multi_sieve:
lda #'P' ; indicate prime
ldb COREID ; find out which core we are
subb #FIRST_CORE
ldx #0 ; start at first char of screen
abx
multi_sieve3:
sta TEXTSCR,x ; store 'P'
leax 8,x ; advance to next position
cmpx #4095
blo multi_sieve3
jsr checkpoint
addb #2 ; start sieve at 2 (core id)
lda #'N' ; flag position value of 'N' for non-prime
multi_sieve2:
ldx #0
abx ; skip the first position - might be prime
multi_sieve1:
abx ; increment
sta TEXTSCR,x
cmpx #4095
blo multi_sieve1
jsr checkpoint
addb #8 ; number of cores working on it
cmpb #4080
blo multi_sieve2
multi_sieve4: ; hang machine
sync
lbra Monitor
 
sieve:
lda #'P' ; indicate prime
ldx #0 ; start at first char of screen
sieve3:
sta TEXTSCR,x ; store 'P'
inx ; advance to next position
cmpx #4095
blo sieve3
ldb #2 ; start sieve at 2
lda #'N' ; flag position value of 'N' for non-prime
sieve2:
ldx #0
abx ; skip the first position - might be prime
sieve1:
abx ; increment
sta TEXTSCR,x
cmpx #4095
blo multi_sieve1
incb ; number of cores working on it
cmpb #4080
blo sieve2
sieve4: ; hang machine
sync
lbra MonitorStart
 
;------------------------------------------------------------------------------
; Three second delay for user convenience and to allow some devices time to
; reset.
;------------------------------------------------------------------------------
 
Delay3s:
ldd #9000000
dly3s1:
cmpb #$FF
bne dly3s2
dly3s2:
sta LEDS
subd #1
bne dly3s1
rts
 
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
ShiftLeft5:
aslb
rola
aslb
rola
aslb
rola
aslb
rola
aslb
rola
rts
 
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
;
CopyVirtualScreenToScreen:
pshs d,x,y,u
bsr GetScreenLocation
tfr d,x
ldy #TEXTSCR
ldu #56*29/2
cv2s1:
ldd ,x++
std ,y++
leau -1,u
cmpu #0
bne cv2s1
; reset the cursor position in the text controller
ldb CursorRow
lda #56
mul
tfr d,x
ldb CursorCol
abx
stx TEXTREG+TEXT_CURPOS
puls d,x,y,u,pc
 
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
;
CopyScreenToVirtualScreen:
pshs d,x,y,u
bsr GetScreenLocation
tfr d,y
ldx #TEXTSCR
ldu #56*29/2
cs2v1:
ldd ,x++
std ,y++
leau -1,u
cmpu #0
bne cs2v1
puls d,x,y,u,pc
 
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
fcb "TEXTSCR "
fcw TextOpen
fcw TextClose
fcw TextRead
fcw TextWrite
fcw TextSeek
 
TextOpen:
rts
TextClose:
rts
TextRead:
rts
TextWrite:
rts
TextSeek:
rts
 
;------------------------------------------------------------------------------
; Clear the screen and the screen color memory
; We clear the screen to give a visual indication that the system
; is working at all.
;
; Modifies:
; none
;------------------------------------------------------------------------------
 
ClearScreen:
pshs d,x,y,u
ldx #56*29
tfr x,u
bsr GetScreenLocation
tfr d,y
ldb #' ' ; space char
cs1:
stb ,y+ ; set text to space
leax -1,x ; decrement x
bne cs1
ldb COREID ; update colors only if we have focus
cmpb IOFocusID
bra cs3
ldy #TEXTSCR+$2000
; lda CharColor
lda #$0CE
tfr u,x ; get back count
cs2:
sta ,y+
leax -1,x ; decrement x
bne cs2
cs3:
puls d,x,y,u,pc
 
;------------------------------------------------------------------------------
; Scroll text on the screen upwards
;
; Modifies:
; none
;------------------------------------------------------------------------------
 
ScrollUp:
pshs d,x,y,u
ldy #(56*29-1)/2 ; y = num chars/2 to move
bsr GetScreenLocation
tfr d,x
tfr d,u
leax 56,x ; x = index to source row
scrup1:
ldd ,x++ ; move 2 characters
std ,u++
leay -1,y
bne scrup1
lda #30
bsr BlankLine
puls d,x,y,u,pc
 
;------------------------------------------------------------------------------
; Blank out a line on the display
;
; Modifies:
; none
; Parameters:
; acca = line number to blank
;------------------------------------------------------------------------------
 
BlankLine:
pshs d,x
pshs a
bsr GetScreenLocation
tfr d,x
puls a
ldb #56 ; b = # chars to blank out from video controller
mul ; d = screen index (row# * #cols)
leax d,x
lda #' '
ldb #56 ; b = # chars to blank out from video controller
blnkln1:
sta ,x+
decb
bne blnkln1
puls d,x,pc
 
;------------------------------------------------------------------------------
; Get the location of the screen memory. The location
; depends on whether or not the task has the output focus.
;
; Modifies:
; d
; Retuns:
; d = screen location
;------------------------------------------------------------------------------
 
GetScreenLocation:
lda COREID ; which core are we?
cmpa IOFocusID ; do we have the IO focus
bne gsl1 ; no, go pick virtual screen address
ldd #TEXTSCR ; yes, we update the real screen
rts
gsl1:
ldd #$7800
rts
 
;------------------------------------------------------------------------------
; HomeCursor
; Set the cursor location to the top left of the screen.
;
; Modifies:
; none
;------------------------------------------------------------------------------
 
HomeCursor:
pshs d,x
clr CursorRow
clr CursorCol
ldb COREID
cmpb IOFocusID
bne hc1
clra
sta TEXTREG+TEXT_CURPOS
hc1:
puls d,x,pc
 
;------------------------------------------------------------------------------
; Update the cursor position in the text controller based on the
; CursorRow,CursorCol.
;
; Modifies:
; none
;------------------------------------------------------------------------------
;
UpdateCursorPos:
pshs d,x
ldb COREID ; update cursor position in text controller
cmpb IOFocusID ; only for the task with the output focus
bne ucp1
lda CursorRow
anda #$3F ; limit of 63 rows
ldb TEXTREG+TEXT_COLS
mul
tfr d,x
ldb CursorCol
abx
stx TEXTREG+TEXT_CURPOS
ucp1:
puls d,x,pc
 
;------------------------------------------------------------------------------
; Calculate screen memory location from CursorRow,CursorCol.
; Also refreshes the cursor location.
;
; Modifies:
; d
; Returns:
; d = screen location
;------------------------------------------------------------------------------
;
CalcScreenLoc:
pshs x
lda CursorRow
ldb #56
mul
tfr d,x
ldb CursorCol
abx
ldb COREID ; update cursor position in text controller
cmpb IOFocusID ; only for the task with the output focus
bne csl1
stx TEXTREG+TEXT_CURPOS
csl1:
bsr GetScreenLocation
leax d,x
tfr x,d
puls x,pc
 
;------------------------------------------------------------------------------
; Display a character on the screen.
; If the task doesn't have the I/O focus then the character is written to
; the virtual screen.
;
; Modifies:
; none
; Parameters:
; accb = char to display
;------------------------------------------------------------------------------
;
DisplayChar:
pshs d,x
cmpb #CR ; carriage return ?
bne dccr
clr CursorCol ; just set cursor column to zero on a CR
bsr UpdateCursorPos
dcx14:
puls d,x,pc
dccr:
cmpb #$91 ; cursor right ?
bne dcx6
lda CursorCol
cmpa #56
bhs dcx7
inca
sta CursorCol
dcx7:
bsr UpdateCursorPos
puls d,x,pc
dcx6:
cmpb #$90 ; cursor up ?
bne dcx8
lda CursorRow
beq dcx7
deca
sta CursorRow
bra dcx7
dcx8:
cmpb #$93 ; cursor left ?
bne dcx9
lda CursorCol
beq dcx7
deca
sta CursorCol
bra dcx7
dcx9:
cmpb #$92 ; cursor down ?
bne dcx10
lda CursorRow
cmpa #29
beq dcx7
inca
sta CursorRow
bra dcx7
dcx10:
cmpb #$94 ; cursor home ?
bne dcx11
lda CursorCol
beq dcx12
clr CursorCol
bra dcx7
dcx12:
clr CursorRow
bra dcx7
dcx11:
cmpb #$99 ; delete ?
bne dcx13
bsr CalcScreenLoc
tfr d,x
lda CursorCol ; acc = cursor column
bra dcx5
dcx13
cmpb #CTRLH ; backspace ?
bne dcx3
lda CursorCol
beq dcx4
deca
sta CursorCol
bsr CalcScreenLoc
dcx5:
ldb 1,x
stb ,x++
inca
cmpa #56
blo dcx5
ldb #' '
leax -1,x
stb ,x
puls d,x,dp,pc
dcx3:
cmpb #LF ; linefeed ?
beq dclf
pshs b
bsr CalcScreenLoc
tfr d,x
puls b
stb ,x
; ToDo character color
; lda CharColor
; sta $2000,x
bsr IncCursorPos
puls d,x,pc
dclf:
bsr IncCursorRow
dcx4:
puls d,x,pc
 
;------------------------------------------------------------------------------
; Increment the cursor position, scroll the screen if needed.
;
; Modifies:
; none
;------------------------------------------------------------------------------
 
IncCursorPos:
pshs d,x
lda CursorCol
inca
sta CursorCol
cmpa #56
blo icc1
clr CursorCol ; column = 0
bra icr1
IncCursorRow:
pshs d,x
icr1:
lda CursorRow
inca
sta CursorRow
cmpa #29
blo icc1
deca ; backup the cursor row, we are scrolling up
sta CursorRow
bsr ScrollUp
icc1:
bsr UpdateCursorPos
icc2:
puls d,x,pc
 
;------------------------------------------------------------------------------
; Display a string on the screen.
;
; Modifies:
; none
; Parameters:
; d = pointer to string
;------------------------------------------------------------------------------
;
DisplayString:
pshs d,x
tfr d,x
dspj1B:
ldb ,x+ ; move string char into acc
beq dsretB ; is it end of string ?
bsr OUTCH ; display character
bra dspj1B
dsretB:
puls d,x,pc
 
DisplayStringCRLF:
pshs d
bsr DisplayString
ldb #CR
bsr OUTCH
ldb #LF
bsr OUTCH
puls d,pc
;
; PRINT CR, LF, STRING
;
PSTRNG
BSR PCRLF
BRA PDATA
PCRLF
PSHS X
LDX #CRLFST
BSR PDATA
PULS X
RTS
 
PRINT
JSR OUTCH
PDATA
LDB ,X+
CMPB #$04
BNE PRINT
RTS
 
CRLFST
fcb CR,LF,4
 
DispDWordAsHex:
bsr DispWordAsHex
exg d,x
bsr DispWordAsHex
exg d,x
rts
 
DispWordAsHex:
exg a,b
bsr DispByteAsHex
exg a,b
bsr DispByteAsHex
rts
 
DispByteAsHex:
pshs b
lsrb
lsrb
lsrb
lsrb
lsrb
lsrb
lsrb
lsrb
bsr DispNyb
puls b
pshs b
lsrb
lsrb
lsrb
lsrb
bsr DispNyb
puls b
 
DispNyb
pshs b
andb #$0F
cmpb #10
blo DispNyb1
addb #'A'-10
bsr OUTCH
puls b,pc
DispNyb1
addb #'0'
bsr OUTCH
puls b,pc
 
;==============================================================================
; Keyboard I/O
;==============================================================================
 
OPT INCLUDE "d:\cores2022\rf6809\software\boot\scancodes.asm"
OPT INCLUDE "d:\cores2022\rf6809\software\boot\keyboard.asm"
 
fcb "KEYBOARD"
fcw KeybdOpen
fcw KeybdClose
fcw KeybdRead
fcw KeybdWrite
fcw KeybdSeek
 
; Keyboard Open:
; Initialize the keyboard buffer head and tail indexes
;
KeybdOpen:
rts
 
; Keyboard Close:
; Nothing to do except maybe clear the keyboard buffer
;
KeybdClose:
rts
;
KeybdRead:
rts
;
KeybdWrite:
rts
 
KeybdSeek:
rts
 
;------------------------------------------------------------------------------
; Check if there is a keyboard character available. If so return true (<0)
; otherwise return false (0) in accb.
;------------------------------------------------------------------------------
;
KeybdCheckForKeyDirect:
bra DBGCheckForKey
 
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
INCH:
ldd #-1 ; block if no key available
bra DBGGetKey
 
INCHE:
bsr INCH
bra INCHEK3
 
INCHEK:
bsr INCH
tst KeybdEcho
beq INCHEK1
INCHEK3:
cmpa #CR
bne INCHEK2
lbsr CRLF
bra INCHEK1
INCHEK2:
bsr DisplayChar
INCHEK1:
rts
 
OUTCH:
jmp [CharOutVec]
 
;------------------------------------------------------------------------------
; r1 0=echo off, non-zero = echo on
;------------------------------------------------------------------------------
;
SetKeyboardEcho:
stb KeybdEcho
rts
 
 
;------------------------------------------------------------------------------
; Parameters:
; x,d bitmap of sprites to enable
;------------------------------------------------------------------------------
 
ShowSprites:
stx SPRITE_CTRL+SPRITE_EN
std SPRITE_CTRL+SPRITE_EN+2
rts
 
;==============================================================================
; System Monitor
;==============================================================================
;
MonitorStart:
ldd #HelpMsg
bsr DisplayString
Monitor:
leas $3FFF ; reset stack pointer
clrb ; turn off keyboard echo
bsr SetKeyboardEcho
; jsr RequestIOFocus
PromptLn:
lbsr CRLF
ldb #'$'
bsr OUTCH
 
; Get characters until a CR is keyed
Prompt3:
ldd #-1 ; block until key present
bsr DBGGetKey
cmpb #CR
beq Prompt1
bsr OUTCH
bra Prompt3
 
; Process the screen line that the CR was keyed on
;
Prompt1:
ldd #$5050
std LEDS
ldb RunningID
cmpb #61
bhi Prompt3
ldd #$5151
std LEDS
clr CursorCol ; go back to the start of the line
bsr CalcScreenLoc ; calc screen memory location
tfr d,y
ldd #$5252
std LEDS
bsr MonGetNonSpace
cmpb #'$'
bne Prompt2 ; skip over '$' prompt character
lda #$5353
std LEDS
bsr MonGetNonSpace
 
; Dispatch based on command character
;
Prompt2:
cmpb #'?' ; $? - display help
bne PromptC
ldd #HelpMsg
bsr DisplayString
bra Monitor
PromptC:
cmpb #'C'
bne PromptD
lbsr ClearScreen
bsr HomeCursor
bra Monitor
PromptD:
cmpb #'D'
bne PromptF
bsr MonGetch
cmpb #'R'
bne Prompt3
bra DumpRegs
PromptF:
cmpb #'F'
bne PromptJ
bsr MonGetch
cmpb #'I'
bne Monitor
bsr MonGetch
cmpb #'G'
bne Monitor
jmp $FE0000
PromptJ:
cmpb #'J'
lbeq jump_to_code
PromptR:
cmpb #'R'
bne Monitor
lbsr ramtest
bra Monitor
 
MonGetch:
ldb ,y
leay 1,y
rts
 
MonGetNonSpace:
bsr MonGetCh
cmpb #' '
beq MonGetNonSpace
cmpb #9 ; tab
beq MonGetNonSpace
rts
 
;------------------------------------------------------------------------------
; Ignore blanks in the input
; Y = text pointer
; D destroyed
;------------------------------------------------------------------------------
;
ignBlanks:
ignBlanks1:
bsr MonGetch
cmpb #' '
beq ignBlanks1
leay -1,y
rts
 
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
GetTwoParams:
bsr ignBlanks
bsr GetHexNumber ; get start address of dump
ldd mon_numwka
std mon_r1
ldd mon_numwka+2
std mon_r1+2
bsr ignBlanks
bsr GetHexNumber ; get end address of dump
ldd mon_numwka
std mon_r2
ldd mon_numwka+2
std mon_r2+2
rts
 
;------------------------------------------------------------------------------
; Get a range, the end must be greater or equal to the start.
;------------------------------------------------------------------------------
GetRange:
bsr GetTwoParams
ldd mon_r2+2
subd mon_r1+2
ldd mon_r2
sbcb mon_r1+1
sbca mon_r1
lbcs DisplayErr
rts
 
shl_numwka:
asl mon_numwka+3
rol mon_numwka+2
rol mon_numwka+1
rol mon_numwka
rts
 
;------------------------------------------------------------------------------
; Get a hexidecimal number. Maximum of nine digits.
; Y = text pointer (updated)
; D = number of digits
; mon_numwka contains number
;------------------------------------------------------------------------------
;
GetHexNumber:
clrd
std mon_numwka
std mon_numwka+2
pshs x
ldx #0 ; max 9 eight digits
gthxn2:
bsr MonGetch
bsr AsciiToHexNybble
cmpb #-1
beq gthxn1
bsr shl_numwka
bsr shl_numwka
bsr shl_numwka
bsr shl_numwka
andb #$0f
orb mon_numwka+3
stb mon_numwka+3
inx
cmpx #9
blo gthxn2
gthxn1:
tfr x,d
puls x,pc
 
;GetDecNumber:
; phx
; push r4
; push r5
; ldx #0
; ld r4,#10
; ld r5,#10
;gtdcn2:
; jsr MonGetch
; jsr AsciiToDecNybble
; cmp #-1
; beq gtdcn1
; mul r2,r2,r5
; add r2,r1
; dec r4
; bne gtdcn2
;gtdcn1:
; txa
; pop r5
; pop r4
; plx
; rts
 
;------------------------------------------------------------------------------
; Convert ASCII character in the range '0' to '9', 'a' to 'f' or 'A' to 'F'
; to a hex nybble.
;------------------------------------------------------------------------------
;
AsciiToHexNybble:
cmpb #'0'
bcc gthx3
cmpb #'9'+1
bcs gthx5
subb #'0'
rts
gthx5:
cmpb #'A'
bcc gthx3
cmpb #'F'+1
bcs gthx6
subb #'A'
addb #10
rts
gthx6:
cmpb #'a'
bcc gthx3
cmpb #'z'+1
bcs gthx3
subb #'a'
addb #10
rts
gthx3:
ldb #-1 ; not a hex number
rts
 
AsciiToDecNybble:
cmpb #'0'
bcc gtdc3
cmpb #'9'+1
bcs gtdc3
subb #'0'
rts
gtdc3:
ldb #-1
rts
 
DisplayErr:
ldx #msgErr
clrd
bsr DisplayStringDX
jmp Monitor
 
DisplayStringDX
std Strptr
stx Strptr+2
jsr DisplayString
rts
 
msgErr:
fcb "**Err",CR,LF,0
 
HelpMsg:
fcb "? = Display help",CR,LF
fcb "CLS = clear screen",CR,LF
; db "S = Boot from SD Card",CR,LF
; db ": = Edit memory bytes",CR,LF
; db "L = Load sector",CR,LF
; db "W = Write sector",CR,LF
fcb "DR = Dump registers",CR,LF
; db "D = Dump memory",CR,LF
; db "F = Fill memory",CR,LF
; db "FL = Dump I/O Focus List",CR,LF
fcb "FIG = start FIG Forth",CR,LF
; db "KILL n = kill task #n",CR,LF
; db "B = start tiny basic",CR,LF
; db "b = start EhBasic 6502",CR,LF
fcb "J = Jump to code",CR,LF
fcb "RAM = test RAM",CR,LF
; db "R[n] = Set register value",CR,LF
; db "r = random lines - test bitmap",CR,LF
; db "e = ethernet test",CR,LF
; db "T = Dump task list",CR,LF
; db "TO = Dump timeout list",CR,LF
; db "TI = display date/time",CR,LF
; db "TEMP = display temperature",CR,LF
; db "P = Piano",CR,LF,0
fcb 0
 
msgRegHeadings
fcb CR,LF," D/AB X Y U S PC DP CCR",CR,LF,0
 
nHEX4:
jsr HEX4
rts
 
nXBLANK:
ldb #' '
bra OUTCH
 
DumpRegs
ldx #msgRegHeadings
ldd #msgRegHeadings>>16
jsr DisplayStringDX
bsr nXBLANK
ldd mon_DSAVE
bsr nHEX4
bsr nXBLANK
ldd mon_XSAVE
bsr nHEX4
bsr nXBLANK
ldd mon_YSAVE
bsr nHEX4
bsr nXBLANK
ldd mon_USAVE
bsr nHEX4
bsr nXBLANK
ldd mon_SSAVE
bsr nHEX4
bsr nXBLANK
ldd mon_PCSAVE
bsr nHEX4
ldd mon_PCSAVE+2
bsr nHEX4
bsr nXBLANK
ldd mon_DPRSAVE
jsr HEX2
bsr nXBLANK
lda mon_CCRSAVE
jsr HEX2
bsr nXBLANK
jmp Monitor
 
; Jump to code
jump_to_code:
bsr GetHexNumber
sei
lds mon_SSAVE
ldd #<jtc_exit
pshs d
ldd #>jtc_exit
pshs b
ldd mon_numwka+2
pshs d
ldd mon_numwka
pshs d
ldd mon_USAVE
pshs d
ldd mon_YSAVE
pshs d
ldd mon_XSAVE
pshs d
lda mon_DPRSave
pshs a
ldd mon_DSAVE
pshs d
lda mon_CCRSAVE
pshs a
puls far ccr,d,dpr,x,y,u,pc
jtc_exit:
pshs ccr
std mon_DSAVE
stx mon_XSAVE
sty mon_YSAVE
stu mon_USAVE
tfr dpr,a
sta mon_DPRSAVE
puls a
sta mon_CCRSAVE
sts mon_SSAVE
lds #$3FFF
; todo set according to coreid
jmp DumpRegs
 
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
swi3_rout:
sei
puls a
sta mon_CCRSAVE
puls D,DPR,X,Y,U
std mon_DSAVE
stx mon_XSAVE
sty mon_YSAVE
stu mon_USAVE
tfr dpr,a
sta mon_DPRSAVE
puls D
std mon_PCSAVE
puls D
std mon_PCSAVE+2
sts mon_SSAVE
lds #$3FFF
cli
jmp DumpRegs
swi3_exit:
sei
lds mon_SSAVE
ldd mon_PCSAVE+2
pshs d
ldd mon_PCSAVE
pshs d
ldu mon_USAVE
ldy mon_YSAVE
ldx mon_XSAVE
pshs x,y,u
lda mon_DPRSAVE
pshs a
ldd mon_DSAVE
pshs d
lda mon_CCRSAVE
pshs a
tfr a,ccr
cli
rti
 
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
irq_rout:
; Reset the edge sense circuit in the PIC
lda #2 ; Timer is IRQ #2
sta PIC+6 ; register 6 is edge sense reset reg
 
sta IrqSource ; stuff a byte indicating the IRQ source for PEEK()
lda IrqBase ; get the IRQ flag byte
lsra
ora IrqBase
anda #$E0
sta IrqBase
 
inc TEXTSCR+110 ; update IRQ live indicator on screen
; flash the cursor
; only bother to flash the cursor for the task with the IO focus.
lda COREID
cmpa IOFocusID
bne tr1a
lda CursorFlash ; test if we want a flashing cursor
beq tr1a
lbsr CalcScreenLoc ; compute cursor location in memory
tfr d,y
lda $2000,y ; get color code $2000 higher in memory
ldb IRQFlag ; get counter
lsrb
lsra
lsra
lsra
lsra
lsrb
rola
lsrb
rola
lsrb
rola
lsrb
rola
sta $E00000,y ; store the color code back to memory
tr1a
rti
 
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
nmi_rout:
ldb COREID
lda #'I'
ldx #TEXTSCR+40
abx
sta ,x
rti
 
org $FFFFF0
nop
nop
fcw swi3_rout
 
org $FFFFF8
fcw irq_rout
fcw start ; SWI
fcw nmi_rout ; NMI
fcw start ; RST
/rf6809/trunk/software/boot/boot_rom.lst
0,0 → 1,2369
0 error(s), 62 warning(s) unlisted in pass 1
; ============================================================================
; __
; \\__/ o\ (C) 2013-2022 Robert Finch, Stratford
; \ __ / All rights reserved.
; \/_// robfinch<remove>@opencores.org
; ||
;
;
; This source file is free software: you can redistribute it and/or modify
; it under the terms of the GNU Lesser General Public License as published
; by the Free Software Foundation, either version 3 of the License, or
; (at your option) any later version.
;
; This source file is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with this program. If not, see <http://www.gnu.org/licenses/>.
;
; ============================================================================
;
CR EQU $0D ;ASCII equates
LF EQU $0A
TAB EQU $09
CTRLC EQU $03
CTRLH EQU $08
CTRLI EQU $09
CTRLJ EQU $0A
CTRLK EQU $0B
CTRLM EQU $0D
CTRLS EQU $13
CTRLX EQU $18
XON EQU $11
XOFF EQU $13
FIRST_CORE EQU 1
MAX_TASKNO EQU 63
DRAM_BASE EQU $10000000
ScreenLocation EQU $10
ColorCodeLocation EQU $14
ScreenLocation2 EQU $18
BlkcpySrc EQU $1C
BlkcpyDst EQU $20
Strptr EQU $24
PICptr EQU $28
; Forth Area
; 0x30-0x60
RunningID EQU $800000
; Task control blocks, room for 256 tasks
TCB_NxtRdy EQU $00 ; next task on ready / timeout list
TCB_PrvRdy EQU $04 ; previous task on ready / timeout list
TCB_NxtTCB EQU $08
TCB_Timeout EQU $0C
TCB_Priority EQU $10
TCB_MSGPTR_D1 EQU $14
TCB_MSGPTR_D2 EQU $18
TCB_hJCB EQU $1C
TCB_Status EQU $1E
TCB_CursorRow EQU $20
TCB_CursorCol EQU $21
TCB_hWaitMbx EQU $22 ; handle of mailbox task is waiting at
TCB_mbq_next EQU $24 ; mailbox queue next
TCB_mbq_prev EQU $28 ; mailbox queue previous
TCB_iof_next EQU $2C
TCB_iof_prev EQU $30
TCB_SPSave EQU $34 ; TCB_SPSave area
TCB_mmu_map EQU $38
KeybdHead EQU $FFFFFC800
KeybdTail EQU $FFFFFC900
KeybdEcho EQU $FFFFFCA00
KeybdBad EQU $FFFFFCB00
KeybdAck EQU $FFFFFCC00
KeybdLocks EQU $FFFFFCD00
KeybdBuffer EQU $FFFFFC000 ; buffer is 16 chars
COREID EQU $FFFFFFFE0
MSCOUNT EQU $FFFFFFFE4
LEDS EQU $FFFE60000
TEXTSCR EQU $FFFE00000
TEXTREG EQU $FFFE0DF00
TEXT_COLS EQU 0
TEXT_ROWS EQU 1
TEXT_CURPOS EQU 34
KEYBD EQU $FFFE30400
KEYBDCLR EQU $FFFE30402
PIC EQU $FFFE3F000
SPRITE_CTRL EQU $FFFE10000
SPRITE_EN EQU $3C0
BIOS_SCREENS EQU $17000000 ; $17000000 to $171FFFFF
; EhBASIC vars:
;
NmiBase EQU $DC
IrqBase EQU $DF
; The IO focus list is a doubly linked list formed into a ring.
;
IOFocusNdx EQU $100
IOFocusID EQU $100
; These variables use direct page access
CursorRow EQU $110
CursorCol EQU $111
CharColor EQU $112
ScreenColor EQU $113
CursorFlash EQU $114
KeyState1 EQU $120
KeyState2 EQU $121
KeyLED EQU $122
KeybdID EQU $124
QNdx0 EQU $780
QNdx1 EQU QNdx0+2
QNdx2 EQU QNdx1+2
QNdx3 EQU QNdx2+2
QNdx4 EQU QNdx3+2
FreeTCB EQU QNdx4+2
TimeoutList EQU FreeTCB+2
FreeMbx EQU RunningTCB + 2
nMailbox EQU FreeMbx + 2
FreeMsg EQU nMailbox + 2
nMsgBlk EQU FreeMsg + 2
IrqSource EQU $79A
IRQFlag EQU $7C6
CharOutVec EQU $800
CharInVec EQU $804
; Register save area for monitor
mon_DSAVE EQU $900
mon_XSAVE EQU $902
mon_YSAVE EQU $904
mon_USAVE EQU $906
mon_SSAVE EQU $908
mon_PCSAVE EQU $90A
mon_DPRSAVE EQU $90E
mon_CCRSAVE EQU $90F
mon_numwka EQU $910
mon_r1 EQU $920
mon_r2 EQU $922
; The ORG directive must set an address a multiple of 4 in order for the Verilog
; output to work correctly.
org $FFD0AC
00FFD0AC 012 nop
00FFD0AD 012 nop
00FFD0AE 012 nop
XBLANK
00FFD0AF 0C6020 ldb #' '
00FFD0B1 0170028C8 lbsr OUTCH
00FFD0B4 039 rts
org $FFD0D0
00FFD0D0 012 nop
00FFD0D1 012 nop
CRLF
CRLF1:
00FFD0D2 0C600D ldb #CR
00FFD0D4 0170028A5 lbsr OUTCH
00FFD0D7 0C600A ldb #LF
00FFD0D9 0170028A0 lbsr OUTCH
00FFD0DC 039 rts
org $FFD0F0
00FFD0F0 012 nop
00FFD0F1 020FDF bra CRLF1
org $FFD1DC
ONEKEY
00FFD1DC 06E90F000804 jmp [CharInVec]
org $FFD2C0
00FFD2C0 012 nop
LETTER
00FFD2C1 0170026B8 lbsr OUTCH
00FFD2C4 039 rts
org $FFD2CC
00FFD2CC 012 nop
00FFD2CD 012 nop
HEX2
00FFD2CE 0170020CC lbsr DispByteAsHex
00FFD2D1 039 rts
HEX4
00FFD2D2 0170020BF lbsr DispWordAsHex
00FFD2D5 039 rts
org $FFD300
ClearScreenJmp
00FFD300 016001ECD lbra ClearScreen
org $FFD308
HomeCursorJmp
00FFD308 016001F36 lbra HomeCursor
org $FFE000
; Local RAM test routine
; Checkerboard testing.
; There is 70kB of local RAM
; Does not use any RAM including no stack
ramtest:
00FFE000 18E000000 ldy #0
00FFE003 086001 lda #1
00FFE005 0150B7FFFE60000 sta LEDS
00FFE00A 0CCAAA555 ldd #$AAA555
ramtest1:
00FFE00D 0EDA01 std ,y++
00FFE00F 18CC00000 cmpy #$C00000
00FFE012 025FF9 blo ramtest1
; now readback values and compare
00FFE014 18E000000 ldy #0
ramtest3:
00FFE017 0ECA01 ldd ,y++
00FFE019 183AAA555 cmpd #$AAA555
00FFE01C 02600E bne ramerr
00FFE01E 18CC00000 cmpy #$C00000
00FFE021 025FF4 blo ramtest3
00FFE023 086002 lda #2
00FFE025 0150B7FFFE60000 sta LEDS
00FFE02A 06EC04 jmp ,u
ramerr:
00FFE02C 086080 lda #$80
00FFE02E 0150B7FFFE60000 sta LEDS
00FFE033 08EE00000 ldx #TEXTSCR
00FFE036 0150F6FFFFFFFE0 ldb COREID
00FFE03B 03A abx
00FFE03C 086046 lda #'F'
00FFE03E 0A7804 sta ,x
00FFE040 013 sync
00FFE041 06EC04 jmp ,u
org $FFF000
00FFF000 FFF996 FDB Monitor
00FFF002 FFF022 FDB DumRts ; NEXTCMD
00FFF004 FFF95E FDB INCH
00FFF006 FFF963 FDB INCHE
00FFF008 FFF967 FDB INCHEK
00FFF00A FFF97C FDB OUTCH
00FFF00C FFF381 FDB PDATA
00FFF00E FFF374 FDB PCRLF
00FFF010 FFF370 FDB PSTRNG
00FFF012 FFF022 FDB DumRts ; LRA
00FFF014 FFF022 FDB DumRts
00FFF016 FFF022 FDB DumRts
00FFF018 FFF022 FDB DumRts
00FFF01A FFF022 FDB DumRts ; VINIZ
00FFF01C FFF29B FDB DisplayChar ; VOUTCH
00FFF01E FFF022 FDB DumRts ; ACINIZ
00FFF020 FFF022 FDB DumRts ; AOUTCH
DumRts:
00FFF022 039 rts
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
start:
00FFF023 086055 lda #$55 ; see if we can at least set LEDs
00FFF025 0150B7FFFE60000 sta LEDS
00FFF02A 0CEFFF030 ldu #st6 ; U = return address
00FFF02D 07EFFE000 jmp ramtest ; JMP dont JSR
st6:
00FFF030 1CE003FFF lds #$3FFF ; boot up stack area
00FFF033 0150B6FFFFFFFE0 lda COREID
00FFF038 081001 cmpa #FIRST_CORE
; beq st8
; sync ; halt cores other than 2
st8:
; bne skip_init
; bsr romToRam
; ldd #st7 & $FFFF
; tfr d,x
; jmp ,x ; jump to the BIOS now in local RAM
st7:
00FFF03A 08D11F bsr Delay3s ; give some time for devices to reset
00FFF03C 0860AA lda #$AA
00FFF03E 0150B7FFFE60000 sta LEDS
00FFF043 086002 lda #2
00FFF045 097100 sta IOFocusID ; core #2 has focus
00FFF047 0B7800000 sta RunningID
00FFF04A 0860CE lda #$0CE
00FFF04C 097113 sta ScreenColor
00FFF04E 097112 sta CharColor
00FFF050 08D17E bsr ClearScreen
00FFF052 0CCFFF29B ldd #DisplayChar
00FFF055 0DD800 std CharOutVec
00FFF057 0CCFFF83B ldd #DBGGetKey
00FFF05A 0DD804 std CharInVec
00FFF05C 0150F6FFFFFFFE0 ldb COREID
00FFF061 0C1001 cmpb #FIRST_CORE
00FFF063 02700D beq init
00FFF065 020025 bra skip_init
00FFF067 02008D bra multi_sieve
st3:
00FFF069 0860FF lda #$FF
00FFF06B 0150B7FFFE60000 sta LEDS
00FFF070 020FF7 bra st3
; initialize interrupt controller
; first, zero out all the vectors
init:
00FFF072 08E000080 ldx #128
00FFF075 086001 lda #1 ; set irq(bit0), clear firq (bit1), disable int (bit 6), clear edge sense(bit 7)
00FFF077 0C6001 ldb #FIRST_CORE ; serving core id
st1:
00FFF079 06F809E3F000 clr PIC,x ; cause code
00FFF07D 0A7809E3F001 sta PIC+1,x
00FFF081 0E7809E3F002 stb PIC+2,x
00FFF085 030004 leax 4,x
00FFF087 08C000100 cmpx #256
00FFF08A 025FED blo st1
; lda #4 ; make the timer interrupt edge sensitive
; sta PIC+4 ; reg #4 is the edge sensitivity setting
; sta PIC ; reg #0 is interrupt enable
skip_init:
00FFF08C 01C0EF andcc #$EF ; unmask irq
00FFF08E 086038 lda #56
00FFF090 0150B7FFFE0DF00 sta TEXTREG+TEXT_COLS
00FFF095 08601D lda #29
00FFF097 0150B7FFFE0DF01 sta TEXTREG+TEXT_ROWS
00FFF09C 08D132 bsr ClearScreen
00FFF09E 08D1A1 bsr HomeCursor
00FFF0A0 086005 lda #5
00FFF0A2 0150B7FFFE60000 sta LEDS
00FFF0A7 0CCFFF0BF ldd #msgStartup
00FFF0AA 08D2A8 bsr DisplayString
00FFF0AC 08E000000 ldx #0
00FFF0AF 0CC000000 ldd #0
00FFF0B2 0170008D1 lbsr ShowSprites
00FFF0B5 017000708 lbsr KeybdInit
00FFF0B8 0DC124 ldd KeybdID
00FFF0BA 08D2D8 bsr DispWordAsHex
00FFF0BC 07EFFF991 jmp MonitorStart
msgStartup
00FFF0BF 072066036038030039020 fcb "rf6809 12-bit System Starting.",CR,LF,0
00FFF0C6 03103202D062069074020
00FFF0CD 05307907307406506D020
00FFF0D4 05307406107207406906E
00FFF0DB 06702E00D00A000
;------------------------------------------------------------------------------
; The checkpoint register must be cleared within 1 second or a NMI interrupt
; will occur. checkpoint should be called with a JSR so that the global ROM
; routine is called.
;
; Modifies:
; none
;------------------------------------------------------------------------------
checkpoint:
00FFF0E0 01507FFFFFFFFE1 clr $FFFFFFFE1 ; writing any value will do
00FFF0E5 039 rts
;------------------------------------------------------------------------------
; Copy the system ROM to local RAM
; Running the code from local RAM is probably an order of magnitude faster
; then running from the global ROM. It also reduces the network traffic to
; run from local RAM.
;
; Modifies:
; d,x,y
;------------------------------------------------------------------------------
romToRam:
00FFF0E6 08EFFC000 ldx #$FFC000
00FFF0E9 18E00C000 ldy #$00C000
romToRam1:
00FFF0EC 0EC801 ldd ,x++
00FFF0EE 0EDA01 std ,y++
00FFF0F0 08C000000 cmpx #0
00FFF0F3 026FF7 bne romToRam1
00FFF0F5 039 rts
;------------------------------------------------------------------------------
; Multi-core sieve program.
;------------------------------------------------------------------------------
; First fill screen chars with 'P' indicating prime positions
; Each core is responsible for the Nth position where N is the
; core number minus two.
;
multi_sieve:
00FFF0F6 086050 lda #'P' ; indicate prime
00FFF0F8 0150F6FFFFFFFE0 ldb COREID ; find out which core we are
00FFF0FD 0C0001 subb #FIRST_CORE
00FFF0FF 08E000000 ldx #0 ; start at first char of screen
00FFF102 03A abx
multi_sieve3:
00FFF103 0A7809E00000 sta TEXTSCR,x ; store 'P'
00FFF107 030008 leax 8,x ; advance to next position
00FFF109 08C000FFF cmpx #4095
00FFF10C 025FF5 blo multi_sieve3
00FFF10E 0BDFFF0E0 jsr checkpoint
*** warning 1: Long branch within short branch range could be optimized
00FFF111 0CB002 addb #2 ; start sieve at 2 (core id)
00FFF113 08604E lda #'N' ; flag position value of 'N' for non-prime
multi_sieve2:
00FFF115 08E000000 ldx #0
00FFF118 03A abx ; skip the first position - might be prime
multi_sieve1:
00FFF119 03A abx ; increment
00FFF11A 0A7809E00000 sta TEXTSCR,x
00FFF11E 08C000FFF cmpx #4095
00FFF121 025FF6 blo multi_sieve1
00FFF123 0BDFFF0E0 jsr checkpoint
*** warning 1: Long branch within short branch range could be optimized
00FFF126 0CB008 addb #8 ; number of cores working on it
00FFF128 0C1FF0 cmpb #4080
00FFF12A 025FE9 blo multi_sieve2
multi_sieve4: ; hang machine
00FFF12C 013 sync
00FFF12D 016000866 lbra Monitor
sieve:
00FFF130 086050 lda #'P' ; indicate prime
00FFF132 08E000000 ldx #0 ; start at first char of screen
sieve3:
00FFF135 0A7809E00000 sta TEXTSCR,x ; store 'P'
00FFF139 030001 inx ; advance to next position
00FFF13B 08C000FFF cmpx #4095
00FFF13E 025FF5 blo sieve3
00FFF140 0C6002 ldb #2 ; start sieve at 2
00FFF142 08604E lda #'N' ; flag position value of 'N' for non-prime
sieve2:
00FFF144 08E000000 ldx #0
00FFF147 03A abx ; skip the first position - might be prime
sieve1:
00FFF148 03A abx ; increment
00FFF149 0A7809E00000 sta TEXTSCR,x
00FFF14D 08C000FFF cmpx #4095
00FFF150 025FC7 blo multi_sieve1
00FFF152 05C incb ; number of cores working on it
00FFF153 0C1FF0 cmpb #4080
00FFF155 025FED blo sieve2
sieve4: ; hang machine
00FFF157 013 sync
00FFF158 016000836 lbra MonitorStart
;------------------------------------------------------------------------------
; Three second delay for user convenience and to allow some devices time to
; reset.
;------------------------------------------------------------------------------
Delay3s:
00FFF15B 0CC895440 ldd #9000000
dly3s1:
00FFF15E 0C10FF cmpb #$FF
00FFF160 026000 bne dly3s2
dly3s2:
00FFF162 0150B7FFFE60000 sta LEDS
00FFF167 083000001 subd #1
00FFF16A 026FF2 bne dly3s1
00FFF16C 039 rts
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
ShiftLeft5:
00FFF16D 058 aslb
00FFF16E 049 rola
00FFF16F 058 aslb
00FFF170 049 rola
00FFF171 058 aslb
00FFF172 049 rola
00FFF173 058 aslb
00FFF174 049 rola
00FFF175 058 aslb
00FFF176 049 rola
00FFF177 039 rts
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
;
CopyVirtualScreenToScreen:
00FFF178 034076 pshs d,x,y,u
00FFF17A 08D0B4 bsr GetScreenLocation
00FFF17C 01F001 tfr d,x
00FFF17E 18EE00000 ldy #TEXTSCR
00FFF181 0CE00032C ldu #56*29/2
cv2s1:
00FFF184 0EC801 ldd ,x++
00FFF186 0EDA01 std ,y++
00FFF188 0335FF leau -1,u
00FFF18A 283000000 cmpu #0
00FFF18D 026FF5 bne cv2s1
; reset the cursor position in the text controller
00FFF18F 0D6110 ldb CursorRow
00FFF191 086038 lda #56
00FFF193 03D mul
00FFF194 01F001 tfr d,x
00FFF196 0D6111 ldb CursorCol
00FFF198 03A abx
00FFF199 0150BFFFFE0DF22 stx TEXTREG+TEXT_CURPOS
00FFF19E 0350F6 puls d,x,y,u,pc
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
;
CopyScreenToVirtualScreen:
00FFF1A0 034076 pshs d,x,y,u
00FFF1A2 08D08C bsr GetScreenLocation
00FFF1A4 01F002 tfr d,y
00FFF1A6 08EE00000 ldx #TEXTSCR
00FFF1A9 0CE00032C ldu #56*29/2
cs2v1:
00FFF1AC 0EC801 ldd ,x++
00FFF1AE 0EDA01 std ,y++
00FFF1B0 0335FF leau -1,u
00FFF1B2 283000000 cmpu #0
00FFF1B5 026FF5 bne cs2v1
00FFF1B7 0350F6 puls d,x,y,u,pc
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
00FFF1B9 054045058054053043052 fcb "TEXTSCR "
00FFF1C0 020
00FFF1C1 FFF1CB fcw TextOpen
00FFF1C3 FFF1CC fcw TextClose
00FFF1C5 FFF1CD fcw TextRead
00FFF1C7 FFF1CE fcw TextWrite
00FFF1C9 FFF1CF fcw TextSeek
TextOpen:
00FFF1CB 039 rts
TextClose:
00FFF1CC 039 rts
TextRead:
00FFF1CD 039 rts
TextWrite:
00FFF1CE 039 rts
TextSeek:
00FFF1CF 039 rts
;------------------------------------------------------------------------------
; Clear the screen and the screen color memory
; We clear the screen to give a visual indication that the system
; is working at all.
;
; Modifies:
; none
;------------------------------------------------------------------------------
ClearScreen:
00FFF1D0 034076 pshs d,x,y,u
00FFF1D2 08E000658 ldx #56*29
00FFF1D5 01F013 tfr x,u
00FFF1D7 08D057 bsr GetScreenLocation
00FFF1D9 01F002 tfr d,y
00FFF1DB 0C6020 ldb #' ' ; space char
cs1:
00FFF1DD 0E7A00 stb ,y+ ; set text to space
00FFF1DF 0301FF leax -1,x ; decrement x
00FFF1E1 026FFA bne cs1
00FFF1E3 0150F6FFFFFFFE0 ldb COREID ; update colors only if we have focus
00FFF1E8 0D1100 cmpb IOFocusID
00FFF1EA 02000D bra cs3
00FFF1EC 18EE02000 ldy #TEXTSCR+$2000
; lda CharColor
00FFF1EF 0860CE lda #$0CE
00FFF1F1 01F031 tfr u,x ; get back count
cs2:
00FFF1F3 0A7A00 sta ,y+
00FFF1F5 0301FF leax -1,x ; decrement x
00FFF1F7 026FFA bne cs2
cs3:
00FFF1F9 0350F6 puls d,x,y,u,pc
;------------------------------------------------------------------------------
; Scroll text on the screen upwards
;
; Modifies:
; none
;------------------------------------------------------------------------------
ScrollUp:
00FFF1FB 034076 pshs d,x,y,u
00FFF1FD 18E00032B ldy #(56*29-1)/2 ; y = num chars/2 to move
00FFF200 08D02E bsr GetScreenLocation
00FFF202 01F001 tfr d,x
00FFF204 01F003 tfr d,u
00FFF206 030038 leax 56,x ; x = index to source row
scrup1:
00FFF208 0EC801 ldd ,x++ ; move 2 characters
00FFF20A 0EDC01 std ,u++
00FFF20C 0313FF leay -1,y
00FFF20E 026FF8 bne scrup1
00FFF210 08601E lda #30
00FFF212 08D002 bsr BlankLine
00FFF214 0350F6 puls d,x,y,u,pc
;------------------------------------------------------------------------------
; Blank out a line on the display
;
; Modifies:
; none
; Parameters:
; acca = line number to blank
;------------------------------------------------------------------------------
BlankLine:
00FFF216 034016 pshs d,x
00FFF218 034002 pshs a
00FFF21A 08D014 bsr GetScreenLocation
00FFF21C 01F001 tfr d,x
00FFF21E 035002 puls a
00FFF220 0C6038 ldb #56 ; b = # chars to blank out from video controller
00FFF222 03D mul ; d = screen index (row# * #cols)
00FFF223 03080B leax d,x
00FFF225 086020 lda #' '
00FFF227 0C6038 ldb #56 ; b = # chars to blank out from video controller
blnkln1:
00FFF229 0A7800 sta ,x+
00FFF22B 05A decb
00FFF22C 026FFB bne blnkln1
00FFF22E 035096 puls d,x,pc
;------------------------------------------------------------------------------
; Get the location of the screen memory. The location
; depends on whether or not the task has the output focus.
;
; Modifies:
; d
; Retuns:
; d = screen location
;------------------------------------------------------------------------------
GetScreenLocation:
00FFF230 0150B6FFFFFFFE0 lda COREID ; which core are we?
00FFF235 091100 cmpa IOFocusID ; do we have the IO focus
00FFF237 026004 bne gsl1 ; no, go pick virtual screen address
00FFF239 0CCE00000 ldd #TEXTSCR ; yes, we update the real screen
00FFF23C 039 rts
gsl1:
00FFF23D 0CC007800 ldd #$7800
00FFF240 039 rts
;------------------------------------------------------------------------------
; HomeCursor
; Set the cursor location to the top left of the screen.
;
; Modifies:
; none
;------------------------------------------------------------------------------
HomeCursor:
00FFF241 034016 pshs d,x
00FFF243 00F110 clr CursorRow
00FFF245 00F111 clr CursorCol
00FFF247 0150F6FFFFFFFE0 ldb COREID
00FFF24C 0D1100 cmpb IOFocusID
00FFF24E 026006 bne hc1
00FFF250 04F clra
00FFF251 0150B7FFFE0DF22 sta TEXTREG+TEXT_CURPOS
hc1:
00FFF256 035096 puls d,x,pc
;------------------------------------------------------------------------------
; Update the cursor position in the text controller based on the
; CursorRow,CursorCol.
;
; Modifies:
; none
;------------------------------------------------------------------------------
;
UpdateCursorPos:
00FFF258 034016 pshs d,x
00FFF25A 0150F6FFFFFFFE0 ldb COREID ; update cursor position in text controller
00FFF25F 0D1100 cmpb IOFocusID ; only for the task with the output focus
00FFF261 026014 bne ucp1
00FFF263 096110 lda CursorRow
00FFF265 08403F anda #$3F ; limit of 63 rows
00FFF267 0150F6FFFE0DF00 ldb TEXTREG+TEXT_COLS
00FFF26C 03D mul
00FFF26D 01F001 tfr d,x
00FFF26F 0D6111 ldb CursorCol
00FFF271 03A abx
00FFF272 0150BFFFFE0DF22 stx TEXTREG+TEXT_CURPOS
ucp1:
00FFF277 035096 puls d,x,pc
;------------------------------------------------------------------------------
; Calculate screen memory location from CursorRow,CursorCol.
; Also refreshes the cursor location.
;
; Modifies:
; d
; Returns:
; d = screen location
;------------------------------------------------------------------------------
;
CalcScreenLoc:
00FFF279 034010 pshs x
00FFF27B 096110 lda CursorRow
00FFF27D 0C6038 ldb #56
00FFF27F 03D mul
00FFF280 01F001 tfr d,x
00FFF282 0D6111 ldb CursorCol
00FFF284 03A abx
00FFF285 0150F6FFFFFFFE0 ldb COREID ; update cursor position in text controller
00FFF28A 0D1100 cmpb IOFocusID ; only for the task with the output focus
00FFF28C 026005 bne csl1
00FFF28E 0150BFFFFE0DF22 stx TEXTREG+TEXT_CURPOS
csl1:
00FFF293 08DF9B bsr GetScreenLocation
00FFF295 03080B leax d,x
00FFF297 01F010 tfr x,d
00FFF299 035090 puls x,pc
;------------------------------------------------------------------------------
; Display a character on the screen.
; If the task doesn't have the I/O focus then the character is written to
; the virtual screen.
;
; Modifies:
; none
; Parameters:
; accb = char to display
;------------------------------------------------------------------------------
;
DisplayChar:
00FFF29B 034016 pshs d,x
00FFF29D 0C100D cmpb #CR ; carriage return ?
00FFF29F 026006 bne dccr
00FFF2A1 00F111 clr CursorCol ; just set cursor column to zero on a CR
00FFF2A3 08DFB3 bsr UpdateCursorPos
dcx14:
00FFF2A5 035096 puls d,x,pc
dccr:
00FFF2A7 0C1091 cmpb #$91 ; cursor right ?
00FFF2A9 02600D bne dcx6
00FFF2AB 096111 lda CursorCol
00FFF2AD 081038 cmpa #56
00FFF2AF 024003 bhs dcx7
00FFF2B1 04C inca
00FFF2B2 097111 sta CursorCol
dcx7:
00FFF2B4 08DFA2 bsr UpdateCursorPos
00FFF2B6 035096 puls d,x,pc
dcx6:
00FFF2B8 0C1090 cmpb #$90 ; cursor up ?
00FFF2BA 026009 bne dcx8
00FFF2BC 096110 lda CursorRow
00FFF2BE 027FF4 beq dcx7
00FFF2C0 04A deca
00FFF2C1 097110 sta CursorRow
00FFF2C3 020FEF bra dcx7
dcx8:
00FFF2C5 0C1093 cmpb #$93 ; cursor left ?
00FFF2C7 026009 bne dcx9
00FFF2C9 096111 lda CursorCol
00FFF2CB 027FE7 beq dcx7
00FFF2CD 04A deca
00FFF2CE 097111 sta CursorCol
00FFF2D0 020FE2 bra dcx7
dcx9:
00FFF2D2 0C1092 cmpb #$92 ; cursor down ?
00FFF2D4 02600B bne dcx10
00FFF2D6 096110 lda CursorRow
00FFF2D8 08101D cmpa #29
00FFF2DA 027FD8 beq dcx7
00FFF2DC 04C inca
00FFF2DD 097110 sta CursorRow
00FFF2DF 020FD3 bra dcx7
dcx10:
00FFF2E1 0C1094 cmpb #$94 ; cursor home ?
00FFF2E3 02600C bne dcx11
00FFF2E5 096111 lda CursorCol
00FFF2E7 027004 beq dcx12
00FFF2E9 00F111 clr CursorCol
00FFF2EB 020FC7 bra dcx7
dcx12:
00FFF2ED 00F110 clr CursorRow
00FFF2EF 020FC3 bra dcx7
dcx11:
00FFF2F1 0C1099 cmpb #$99 ; delete ?
00FFF2F3 026008 bne dcx13
00FFF2F5 08DF82 bsr CalcScreenLoc
00FFF2F7 01F001 tfr d,x
00FFF2F9 096111 lda CursorCol ; acc = cursor column
00FFF2FB 02000D bra dcx5
dcx13
00FFF2FD 0C1008 cmpb #CTRLH ; backspace ?
00FFF2FF 02601A bne dcx3
00FFF301 096111 lda CursorCol
00FFF303 02702A beq dcx4
00FFF305 04A deca
00FFF306 097111 sta CursorCol
00FFF308 08DF6F bsr CalcScreenLoc
dcx5:
00FFF30A 0E6001 ldb 1,x
00FFF30C 0E7801 stb ,x++
00FFF30E 04C inca
00FFF30F 081038 cmpa #56
00FFF311 025FF7 blo dcx5
00FFF313 0C6020 ldb #' '
00FFF315 0301FF leax -1,x
00FFF317 0E7804 stb ,x
00FFF319 03509E puls d,x,dp,pc
dcx3:
00FFF31B 0C100A cmpb #LF ; linefeed ?
00FFF31D 02700E beq dclf
00FFF31F 034004 pshs b
00FFF321 08DF56 bsr CalcScreenLoc
00FFF323 01F001 tfr d,x
00FFF325 035004 puls b
00FFF327 0E7804 stb ,x
; ToDo character color
; lda CharColor
; sta $2000,x
00FFF329 08D006 bsr IncCursorPos
00FFF32B 035096 puls d,x,pc
dclf:
00FFF32D 08D011 bsr IncCursorRow
dcx4:
00FFF32F 035096 puls d,x,pc
;------------------------------------------------------------------------------
; Increment the cursor position, scroll the screen if needed.
;
; Modifies:
; none
;------------------------------------------------------------------------------
IncCursorPos:
00FFF331 034016 pshs d,x
00FFF333 096111 lda CursorCol
00FFF335 04C inca
00FFF336 097111 sta CursorCol
00FFF338 081038 cmpa #56
00FFF33A 025014 blo icc1
00FFF33C 00F111 clr CursorCol ; column = 0
00FFF33E 020002 bra icr1
IncCursorRow:
00FFF340 034016 pshs d,x
icr1:
00FFF342 096110 lda CursorRow
00FFF344 04C inca
00FFF345 097110 sta CursorRow
00FFF347 08101D cmpa #29
00FFF349 025005 blo icc1
00FFF34B 04A deca ; backup the cursor row, we are scrolling up
00FFF34C 097110 sta CursorRow
00FFF34E 08DEAB bsr ScrollUp
icc1:
00FFF350 08DF06 bsr UpdateCursorPos
icc2:
00FFF352 035096 puls d,x,pc
;------------------------------------------------------------------------------
; Display a string on the screen.
;
; Modifies:
; none
; Parameters:
; d = pointer to string
;------------------------------------------------------------------------------
;
DisplayString:
00FFF354 034016 pshs d,x
00FFF356 01F001 tfr d,x
dspj1B:
00FFF358 0E6800 ldb ,x+ ; move string char into acc
00FFF35A 027004 beq dsretB ; is it end of string ?
00FFF35C 08D61E bsr OUTCH ; display character
00FFF35E 020FF8 bra dspj1B
dsretB:
00FFF360 035096 puls d,x,pc
DisplayStringCRLF:
00FFF362 034006 pshs d
00FFF364 08DFEE bsr DisplayString
00FFF366 0C600D ldb #CR
00FFF368 08D612 bsr OUTCH
00FFF36A 0C600A ldb #LF
00FFF36C 08D60E bsr OUTCH
00FFF36E 035086 puls d,pc
;
; PRINT CR, LF, STRING
;
PSTRNG
00FFF370 08D002 BSR PCRLF
00FFF372 02000D BRA PDATA
PCRLF
00FFF374 034010 PSHS X
00FFF376 08EFFF388 LDX #CRLFST
00FFF379 08D006 BSR PDATA
00FFF37B 035010 PULS X
00FFF37D 039 RTS
PRINT
00FFF37E 0BDFFF97C JSR OUTCH
PDATA
00FFF381 0E6800 LDB ,X+
00FFF383 0C1004 CMPB #$04
00FFF385 026FF7 BNE PRINT
00FFF387 039 RTS
CRLFST
00FFF388 00D00A004 fcb CR,LF,4
DispDWordAsHex:
00FFF38B 08D007 bsr DispWordAsHex
00FFF38D 01E001 exg d,x
00FFF38F 08D003 bsr DispWordAsHex
00FFF391 01E001 exg d,x
00FFF393 039 rts
DispWordAsHex:
00FFF394 01E089 exg a,b
00FFF396 08D005 bsr DispByteAsHex
00FFF398 01E089 exg a,b
00FFF39A 08D001 bsr DispByteAsHex
00FFF39C 039 rts
DispByteAsHex:
00FFF39D 034004 pshs b
00FFF39F 054 lsrb
00FFF3A0 054 lsrb
00FFF3A1 054 lsrb
00FFF3A2 054 lsrb
00FFF3A3 054 lsrb
00FFF3A4 054 lsrb
00FFF3A5 054 lsrb
00FFF3A6 054 lsrb
00FFF3A7 08D00C bsr DispNyb
00FFF3A9 035004 puls b
00FFF3AB 034004 pshs b
00FFF3AD 054 lsrb
00FFF3AE 054 lsrb
00FFF3AF 054 lsrb
00FFF3B0 054 lsrb
00FFF3B1 08D002 bsr DispNyb
00FFF3B3 035004 puls b
DispNyb
00FFF3B5 034004 pshs b
00FFF3B7 0C400F andb #$0F
00FFF3B9 0C100A cmpb #10
00FFF3BB 025006 blo DispNyb1
00FFF3BD 0CB037 addb #'A'-10
00FFF3BF 08D5BB bsr OUTCH
00FFF3C1 035084 puls b,pc
DispNyb1
00FFF3C3 0CB030 addb #'0'
00FFF3C5 08D5B5 bsr OUTCH
00FFF3C7 035084 puls b,pc
;==============================================================================
; Keyboard I/O
;==============================================================================
;--------------------------------------------------------------------------
; PS2 scan codes to ascii conversion tables.
;--------------------------------------------------------------------------
;
org (* + 127) & $FFFFFF80
unshiftedScanCodes:
00FFF400 02E0A902E0A50A30A10A2 fcb $2e,$a9,$2e,$a5,$a3,$a1,$a2,$ac
00FFF407 0AC
00FFF408 02E0AA0A80A60A4009060 fcb $2e,$aa,$a8,$a6,$a4,$09,$60,$2e
00FFF40F 02E
00FFF410 02E02E02E02E02E071031 fcb $2e,$2e,$2e,$2e,$2e,$71,$31,$2e
00FFF417 02E
00FFF418 02E02E07A073061077032 fcb $2e,$2e,$7a,$73,$61,$77,$32,$2e
00FFF41F 02E
00FFF420 02E063078064065034033 fcb $2e,$63,$78,$64,$65,$34,$33,$2e
00FFF427 02E
00FFF428 02E020076066074072035 fcb $2e,$20,$76,$66,$74,$72,$35,$2e
00FFF42F 02E
00FFF430 02E06E062068067079036 fcb $2e,$6e,$62,$68,$67,$79,$36,$2e
00FFF437 02E
00FFF438 02E02E06D06A075037038 fcb $2e,$2e,$6d,$6a,$75,$37,$38,$2e
00FFF43F 02E
00FFF440 02E02C06B06906F030039 fcb $2e,$2c,$6b,$69,$6f,$30,$39,$2e
00FFF447 02E
00FFF448 02E02E02F06C03B07002D fcb $2e,$2e,$2f,$6c,$3b,$70,$2d,$2e
00FFF44F 02E
00FFF450 02E02E02702E05B03D02E fcb $2e,$2e,$27,$2e,$5b,$3d,$2e,$2e
00FFF457 02E
00FFF458 0AD02E00D05D02E05C02E fcb $ad,$2e,$0d,$5d,$2e,$5c,$2e,$2e
00FFF45F 02E
00FFF460 02E02E02E02E02E02E008 fcb $2e,$2e,$2e,$2e,$2e,$2e,$08,$2e
00FFF467 02E
00FFF468 02E09502E09309402E02E fcb $2e,$95,$2e,$93,$94,$2e,$2e,$2e
00FFF46F 02E
00FFF470 09807F09202E09109001B fcb $98,$7f,$92,$2e,$91,$90,$1b,$af
00FFF477 0AF
00FFF478 0AB02E09702E02E0960AE fcb $ab,$2e,$97,$2e,$2e,$96,$ae,$2e
00FFF47F 02E
00FFF480 02E02E02E0A702E02E02E fcb $2e,$2e,$2e,$a7,$2e,$2e,$2e,$2e
00FFF487 02E
00FFF488 02E02E02E02E02E02E02E fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
00FFF48F 02E
00FFF490 02E02E02E02E02E02E02E fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
00FFF497 02E
00FFF498 02E02E02E02E02E02E02E fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
00FFF49F 02E
00FFF4A0 02E02E02E02E02E02E02E fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
00FFF4A7 02E
00FFF4A8 02E02E02E02E02E02E02E fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
00FFF4AF 02E
00FFF4B0 02E02E02E02E02E02E02E fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
00FFF4B7 02E
00FFF4B8 02E02E02E02E02E02E02E fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
00FFF4BF 02E
00FFF4C0 02E02E02E02E02E02E02E fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
00FFF4C7 02E
00FFF4C8 02E02E02E02E02E02E02E fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
00FFF4CF 02E
00FFF4D0 02E02E02E02E02E02E02E fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
00FFF4D7 02E
00FFF4D8 02E02E02E02E02E02E02E fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
00FFF4DF 02E
00FFF4E0 02E02E02E02E02E02E02E fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
00FFF4E7 02E
00FFF4E8 02E02E02E02E02E02E02E fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
00FFF4EF 02E
00FFF4F0 02E02E02E02E02E02E02E fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
00FFF4F7 02E
00FFF4F8 02E02E0FA02E02E02E02E fcb $2e,$2e,$fa,$2e,$2e,$2e,$2e,$2e
00FFF4FF 02E
shiftedScanCodes:
00FFF500 02E02E02E02E02E02E02E fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
00FFF507 02E
00FFF508 02E02E02E02E02E00907E fcb $2e,$2e,$2e,$2e,$2e,$09,$7e,$2e
00FFF50F 02E
00FFF510 02E02E02E02E02E051021 fcb $2e,$2e,$2e,$2e,$2e,$51,$21,$2e
00FFF517 02E
00FFF518 02E02E05A053041057040 fcb $2e,$2e,$5a,$53,$41,$57,$40,$2e
00FFF51F 02E
00FFF520 02E043058044045024023 fcb $2e,$43,$58,$44,$45,$24,$23,$2e
00FFF527 02E
00FFF528 02E020056046054052025 fcb $2e,$20,$56,$46,$54,$52,$25,$2e
00FFF52F 02E
00FFF530 02E04E04204804705905E fcb $2e,$4e,$42,$48,$47,$59,$5e,$2e
00FFF537 02E
00FFF538 02E02E04D04A05502602A fcb $2e,$2e,$4d,$4a,$55,$26,$2a,$2e
00FFF53F 02E
00FFF540 02E03C04B04904F029028 fcb $2e,$3c,$4b,$49,$4f,$29,$28,$2e
00FFF547 02E
00FFF548 02E03E03F04C03A05005F fcb $2e,$3e,$3f,$4c,$3a,$50,$5f,$2e
00FFF54F 02E
00FFF550 02E02E02202E07B02B02E fcb $2e,$2e,$22,$2e,$7b,$2b,$2e,$2e
00FFF557 02E
00FFF558 02E02E00D07D02E07C02E fcb $2e,$2e,$0d,$7d,$2e,$7c,$2e,$2e
00FFF55F 02E
00FFF560 02E02E02E02E02E02E008 fcb $2e,$2e,$2e,$2e,$2e,$2e,$08,$2e
00FFF567 02E
00FFF568 02E02E02E02E02E02E02E fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
00FFF56F 02E
00FFF570 02E07F02E02E02E02E01B fcb $2e,$7f,$2e,$2e,$2e,$2e,$1b,$2e
00FFF577 02E
00FFF578 02E02E02E02E02E02E02E fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
00FFF57F 02E
00FFF580 02E02E02E02E02E02E02E fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
00FFF587 02E
00FFF588 02E02E02E02E02E02E02E fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
00FFF58F 02E
00FFF590 02E02E02E02E02E02E02E fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
00FFF597 02E
00FFF598 02E02E02E02E02E02E02E fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
00FFF59F 02E
00FFF5A0 02E02E02E02E02E02E02E fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
00FFF5A7 02E
00FFF5A8 02E02E02E02E02E02E02E fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
00FFF5AF 02E
00FFF5B0 02E02E02E02E02E02E02E fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
00FFF5B7 02E
00FFF5B8 02E02E02E02E02E02E02E fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
00FFF5BF 02E
00FFF5C0 02E02E02E02E02E02E02E fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
00FFF5C7 02E
00FFF5C8 02E02E02E02E02E02E02E fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
00FFF5CF 02E
00FFF5D0 02E02E02E02E02E02E02E fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
00FFF5D7 02E
00FFF5D8 02E02E02E02E02E02E02E fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
00FFF5DF 02E
00FFF5E0 02E02E02E02E02E02E02E fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
00FFF5E7 02E
00FFF5E8 02E02E02E02E02E02E02E fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
00FFF5EF 02E
00FFF5F0 02E02E02E02E02E02E02E fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
00FFF5F7 02E
00FFF5F8 02E02E02E02E02E02E02E fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
00FFF5FF 02E
; control
keybdControlCodes:
00FFF600 02E02E02E02E02E02E02E fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
00FFF607 02E
00FFF608 02E02E02E02E02E00907E fcb $2e,$2e,$2e,$2e,$2e,$09,$7e,$2e
00FFF60F 02E
00FFF610 02E02E02E02E02E011021 fcb $2e,$2e,$2e,$2e,$2e,$11,$21,$2e
00FFF617 02E
00FFF618 02E02E01A013001017040 fcb $2e,$2e,$1a,$13,$01,$17,$40,$2e
00FFF61F 02E
00FFF620 02E003018004005024023 fcb $2e,$03,$18,$04,$05,$24,$23,$2e
00FFF627 02E
00FFF628 02E020016006014012025 fcb $2e,$20,$16,$06,$14,$12,$25,$2e
00FFF62F 02E
00FFF630 02E00E00200800701905E fcb $2e,$0e,$02,$08,$07,$19,$5e,$2e
00FFF637 02E
00FFF638 02E02E00D00A01502602A fcb $2e,$2e,$0d,$0a,$15,$26,$2a,$2e
00FFF63F 02E
00FFF640 02E03C00B00900F029028 fcb $2e,$3c,$0b,$09,$0f,$29,$28,$2e
00FFF647 02E
00FFF648 02E03E03F00C03A01005F fcb $2e,$3e,$3f,$0c,$3a,$10,$5f,$2e
00FFF64F 02E
00FFF650 02E02E02202E07B02B02E fcb $2e,$2e,$22,$2e,$7b,$2b,$2e,$2e
00FFF657 02E
00FFF658 02E02E00D07D02E07C02E fcb $2e,$2e,$0d,$7d,$2e,$7c,$2e,$2e
00FFF65F 02E
00FFF660 02E02E02E02E02E02E008 fcb $2e,$2e,$2e,$2e,$2e,$2e,$08,$2e
00FFF667 02E
00FFF668 02E02E02E02E02E02E02E fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
00FFF66F 02E
00FFF670 02E07F02E02E02E02E01B fcb $2e,$7f,$2e,$2e,$2e,$2e,$1b,$2e
00FFF677 02E
00FFF678 02E02E02E02E02E02E02E fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
00FFF67F 02E
keybdExtendedCodes:
00FFF680 02E02E02E02E0A30A10A2 fcb $2e,$2e,$2e,$2e,$a3,$a1,$a2,$2e
00FFF687 02E
00FFF688 02E02E02E02E02E02E02E fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
00FFF68F 02E
00FFF690 02E02E02E02E02E02E02E fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
00FFF697 02E
00FFF698 02E02E02E02E02E02E02E fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
00FFF69F 02E
00FFF6A0 02E02E02E02E02E02E02E fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
00FFF6A7 02E
00FFF6A8 02E02E02E02E02E02E02E fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
00FFF6AF 02E
00FFF6B0 02E02E02E02E02E02E02E fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
00FFF6B7 02E
00FFF6B8 02E02E02E02E02E02E02E fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
00FFF6BF 02E
00FFF6C0 02E02E02E02E02E02E02E fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
00FFF6C7 02E
00FFF6C8 02E02E02E02E02E02E02E fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
00FFF6CF 02E
00FFF6D0 02E02E02E02E02E02E02E fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
00FFF6D7 02E
00FFF6D8 02E02E02E02E02E02E02E fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
00FFF6DF 02E
00FFF6E0 02E02E02E02E02E02E02E fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
00FFF6E7 02E
00FFF6E8 02E09502E09309402E02E fcb $2e,$95,$2e,$93,$94,$2e,$2e,$2e
00FFF6EF 02E
00FFF6F0 09809909202E09109002E fcb $98,$99,$92,$2e,$91,$90,$2e,$2e
00FFF6F7 02E
00FFF6F8 02E02E09702E02E09602E fcb $2e,$2e,$97,$2e,$2e,$96,$2e,$2e
00FFF6FF 02E
; ============================================================================
; __
; \\__/ o\ (C) 2013-2022 Robert Finch, Waterloo
; \ __ / All rights reserved.
; \/_// robfinch<remove>@opencores.org
; ||
;
;
; Keyboard driver routines to interface to a PS2 style keyboard
; Converts the scancode to ascii
;
; This source file is free software: you can redistribute it and/or modify
; it under the terms of the GNU Lesser General Public License as published
; by the Free Software Foundation, either version 3 of the License, or
; (at your option) any later version.
;
; This source file is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with this program. If not, see <http://www.gnu.org/licenses/>.
;
; ============================================================================
;
SC_F12 EQU $07
SC_C EQU $21
SC_T EQU $2C
SC_Z EQU $1A
SC_DEL EQU $71 ; extend
SC_KEYUP EQU $F0 ; should be $f0
SC_EXTEND EQU $E0
SC_CTRL EQU $14
SC_RSHIFT EQU $59
SC_NUMLOCK EQU $77
SC_SCROLLLOCK EQU $7E
SC_CAPSLOCK EQU $58
SC_ALT EQU $11
;#define SC_LSHIFT EQU $12
;SC_DEL EQU $71 ; extend
;SC_LCTRL EQU $58
SC_TAB EQU $0D
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; Recieve a byte from the keyboard, used after a command is sent to the
; keyboard in order to wait for a response.
;
; Parameters: none
; Returns: accd = recieved byte ($00 to $FF), -1 on timeout
; Modifies: acc
; Stack Space: 2 words
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
KeybdRecvByte:
00FFF700 034010 pshs x
00FFF702 08E000064 ldx #100 ; wait up to 1s
krb3:
00FFF705 08D05A bsr KeybdGetStatus ; wait for response from keyboard
00FFF707 05D tstb
00FFF708 02B00B bmi krb4 ; is input buffer full ? yes, branch
00FFF70A 08D02D bsr Wait10ms ; wait a bit
00FFF70C 0301FF leax -1,x
00FFF70E 026FF5 bne krb3 ; go back and try again
00FFF710 0CCFFFFFF ldd #-1 ; return -1
00FFF713 035090 puls x,pc
krb4:
00FFF715 08D066 bsr KeybdGetScancode
00FFF717 035090 puls x,pc
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; Send a byte to the keyboard.
;
; Parameters: accb byte to send
; Returns: none
; Modifies: none
; Stack Space: 0 words
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
KeybdSendByte:
00FFF719 0150F7FFFE30400 stb KEYBD
00FFF71E 039 rts
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; Wait until the keyboard transmit is complete
;
; Parameters: none
; Returns: r1 = 0 if successful, r1 = -1 timeout
; Modifies: r1
; Stack Space: 3 words
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
KeybdWaitTx:
00FFF71F 034010 pshs x
00FFF721 08E000064 ldx #100 ; wait a max of 1s
kwt1:
00FFF724 08D03B bsr KeybdGetStatus
00FFF726 0C4040 andb #$40 ; check for transmit complete bit; branch if bit set
00FFF728 02600B bne kwt2
00FFF72A 08D00D bsr Wait10ms ; delay a little bit
00FFF72C 0301FF leax -1,x
00FFF72E 026FF4 bne kwt1 ; go back and try again
00FFF730 0CCFFFFFF ldd #-1 ; timed out, return -1
00FFF733 035090 puls x,pc
kwt2:
00FFF735 04F clra ; wait complete, return 0
00FFF736 05F clrb
00FFF737 035090 puls x,pc
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; Wait for 10 ms
;
; Parameters: none
; Returns: none
; Modifies: none
; Stack Space: 2 words
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Wait10ms:
00FFF739 034006 pshs d
00FFF73B 0150B6FFFFFFFE7 lda MSCOUNT+3
W10_0001:
00FFF740 01F089 tfr a,b
00FFF742 0150F0FFFFFFFE7 subb MSCOUNT+3
00FFF747 0C1FFA cmpb #$FFA
00FFF749 022FF5 bhi W10_0001
00FFF74B 035086 puls d,pc
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; Wait for 300 ms (256 ms)
;
; Parameters: none
; Returns: none
; Modifies: none
; Stack Space: 2 words
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Wait300ms:
00FFF74D 034006 pshs d
00FFF74F 0150B6FFFFFFFE7 lda MSCOUNT+3
W300_0001:
00FFF754 01F089 tfr a,b
00FFF756 0150F0FFFFFFFE7 subb MSCOUNT+3
00FFF75B 0C1F00 cmpb #$F00
00FFF75D 022FF5 bhi W300_0001
00FFF75F 035086 puls d,pc
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; Get the keyboard status
;
; Parameters: none
; Returns: d = status
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
KeybdGetStatus:
kbgs3:
00FFF761 0150F6FFFE30401 ldb KEYBD+1
00FFF766 0C5080 bitb #$80
00FFF768 02600E bne kbgs1
00FFF76A 0C5001 bitb #$01 ; check parity error flag
00FFF76C 026002 bne kbgs2
00FFF76E 04F clra
00FFF76F 039 rts
kbgs2:
00FFF770 0C60FE ldb #$FE ; request resend
00FFF772 08DFA5 bsr KeybdSendByte
00FFF774 08DFA9 bsr KeybdWaitTx
00FFF776 020FE9 bra kbgs3
kbgs1: ; return negative status
00FFF778 0CAF00 orb #$F00
00FFF77A 086FFF lda #-1
00FFF77C 039 rts
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; Get the scancode from the keyboard port
;
; Parameters: none
; Returns: acca = scancode
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
KeybdGetScancode:
00FFF77D 04F clra
00FFF77E 0150F6FFFE30400 ldb KEYBD ; get the scan code
00FFF783 01507FFFFE30401 clr KEYBD+1 ; clear receive register (write $00 to status reg)
; The following useful during debug.
; lbsr DispByteAsHex
; pshs b
; ldb #' '
; lbsr OUTCH
; puls b
00FFF788 039 rts
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; Set the LEDs on the keyboard.
;
; Parameters: d LED status to set
; Returns: none
; Modifies: none
; Stack Space: 2 words
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
KeybdSetLED:
00FFF789 034004 pshs b
00FFF78B 0C60ED ldb #$ED ; set LEDs command
00FFF78D 08DF8A bsr KeybdSendByte
00FFF78F 08DF8E bsr KeybdWaitTx
00FFF791 08DF6D bsr KeybdRecvByte ; should be an ack
00FFF793 035004 puls b
00FFF795 08DF82 bsr KeybdSendByte
00FFF797 08DF86 bsr KeybdWaitTx
00FFF799 08DF65 bsr KeybdRecvByte ; should be an ack
00FFF79B 039 rts
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; Get ID - get the keyboards identifier code.
;
; Parameters: none
; Returns: d = $AB83, $00 on fail
; Modifies: d, KeybdID updated
; Stack Space: 2 words
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
KeybdGetID:
00FFF79C 0C60F2 ldb #$F2
00FFF79E 08DF79 bsr KeybdSendByte
00FFF7A0 08DF7D bsr KeybdWaitTx
00FFF7A2 08DF5C bsr KeybdRecvByte
00FFF7A4 0C5080 bitb #$80
00FFF7A6 026014 bne kgnotKbd
00FFF7A8 0C10AB cmpb #$AB
00FFF7AA 026010 bne kgnotKbd
00FFF7AC 08DF52 bsr KeybdRecvByte
00FFF7AE 0C5080 bitb #$80
00FFF7B0 02600A bne kgnotKbd
00FFF7B2 0C1083 cmpb #$83
00FFF7B4 026006 bne kgnotKbd
00FFF7B6 0CC00AB83 ldd #$AB83
kgid1:
00FFF7B9 0DD124 std KeybdID
00FFF7BB 039 rts
kgnotKbd:
00FFF7BC 04F clra
00FFF7BD 05F clrb
00FFF7BE 020FF9 bra kgid1
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; Initialize the keyboard.
;
; Parameters:
; none
; Modifies:
; none
; Returns:
; none
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
KeybdInit:
00FFF7C0 034026 pshs d,y
00FFF7C2 18E000005 ldy #5
kbdi0002:
00FFF7C5 08DF72 bsr Wait10ms
00FFF7C7 01507FFFFE30401 clr KEYBD+1 ; clear receive register (write $00 to status reg)
00FFF7CC 0C6FFF ldb #-1 ; send reset code to keyboard
00FFF7CE 0150F7FFFE30401 stb KEYBD+1 ; write $FF to status reg to clear TX state
00FFF7D3 08DF44 bsr KeybdSendByte ; now write to transmit register
00FFF7D5 08DF48 bsr KeybdWaitTx ; wait until no longer busy
00FFF7D7 08DF27 bsr KeybdRecvByte ; look for an ACK ($FA)
00FFF7D9 0C10FA cmpb #$FA
00FFF7DB 026021 bne kbdiTryAgain
00FFF7DD 08DF21 bsr KeybdRecvByte ; look for BAT completion code ($AA)
00FFF7DF 0C10FC cmpb #$FC ; reset error ?
00FFF7E1 02701B beq kbdiTryAgain
00FFF7E3 0C10AA cmpb #$AA ; reset complete okay ?
00FFF7E5 026017 bne kbdiTryAgain
; After a reset, scan code set #2 should be active
.config:
00FFF7E7 0C60F0 ldb #$F0 ; send scan code select
00FFF7E9 0150F7FFFE60000 stb LEDS
00FFF7EE 08DF29 bsr KeybdSendByte
00FFF7F0 08DF2D bsr KeybdWaitTx
00FFF7F2 05D tstb
00FFF7F3 02B009 bmi kbdiTryAgain
00FFF7F5 08DF09 bsr KeybdRecvByte ; wait for response from keyboard
00FFF7F7 04D tsta
00FFF7F8 02B004 bmi kbdiTryAgain
00FFF7FA 0C10FA cmpb #$FA ; ACK
00FFF7FC 02700C beq kbdi0004
kbdiTryAgain:
00FFF7FE 0313FF dey
00FFF800 026FC3 bne kbdi0002
.keybdErr:
00FFF802 0CCFFF82A ldd #msgBadKeybd
00FFF805 017FFFB5A lbsr DisplayStringCRLF
*** warning 1: Long branch within short branch range could be optimized
00FFF808 020014 bra ledxit
kbdi0004:
00FFF80A 0C6002 ldb #2 ; select scan code set #2
00FFF80C 08DF0B bsr KeybdSendByte
00FFF80E 08DF0F bsr KeybdWaitTx
00FFF810 05D tstb
00FFF811 02BFEB bmi kbdiTryAgain
00FFF813 08DEEB bsr KeybdRecvByte ; wait for response from keyboard
00FFF815 04D tsta
00FFF816 02BFE6 bmi kbdiTryAgain
00FFF818 0C10FA cmpb #$FA
00FFF81A 026FE2 bne kbdiTryAgain
00FFF81C 08DF7E bsr KeybdGetID
ledxit:
00FFF81E 0C6007 ldb #$07
00FFF820 08DF67 bsr KeybdSetLED
00FFF822 08DF29 bsr Wait300ms
00FFF824 0C6000 ldb #$00
00FFF826 08DF61 bsr KeybdSetLED
00FFF828 0350A6 puls d,y,pc
msgBadKeybd:
00FFF82A 04B06507906206F061072 fcb "Keyboard error",0
00FFF831 06402006507207206F072
00FFF838 000
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
DBGCheckForKey:
00FFF839 020F26 bra KeybdGetStatus
; KeyState2 variable bit meanings
;1176543210
; ||||||||+ = shift
; |||||||+- = alt
; ||||||+-- = control
; |||||+--- = numlock
; ||||+---- = capslock
; |||+----- = scrolllock
; ||+------ = <empty>
; |+------- = "
; | = "
; | = "
; | = "
; +-------- = extended
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; Debug versison of keyboard get routine.
;
; Parameters:
; b: 0 = non blocking, otherwise blocking
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
DBGGetKey:
00FFF83B 034010 pshs x
dbgk2:
00FFF83D 034004 pshs b
00FFF83F 08DF20 bsr KeybdGetStatus
00FFF841 0C4080 andb #$80 ; is key available?
00FFF843 035004 puls b
00FFF845 026008 bne dbgk1 ; branch if key
00FFF847 05D tstb ; block?
00FFF848 026FF3 bne dbgk2 ; If no key and blocking - loop
00FFF84A 0CCFFFFFF ldd #-1 ; return -1 if no block and no key
00FFF84D 035090 puls x,pc
dbgk1:
00FFF84F 08DF2C bsr KeybdGetScancode
; lbsr DispByteAsHex
; Make sure there is a small delay between scancode reads
00FFF851 08E000014 ldx #20
dbgk3:
00FFF854 0301FF dex
00FFF856 026FFC bne dbgk3
; switch on scan code
00FFF858 0C10F0 cmpb #SC_KEYUP
00FFF85A 026006 bne dbgk4
00FFF85C 00F120 clr KeyState1 ; make KeyState1 = -1
00FFF85E 000120 neg KeyState1
00FFF860 020FDB bra dbgk2 ; loop back
dbgk4:
00FFF862 0C10E0 cmpb #SC_EXTEND
00FFF864 026008 bne dbgk5
00FFF866 096121 lda KeyState2
00FFF868 08A800 ora #$800
00FFF86A 097121 sta KeyState2
00FFF86C 020FCF bra dbgk2
dbgk5:
00FFF86E 0C1014 cmpb #SC_CTRL
00FFF870 026016 bne dbgkNotCtrl
00FFF872 00D120 tst KeyState1
00FFF874 02B008 bmi dbgk7
00FFF876 096121 lda KeyState2
00FFF878 08A004 ora #4
00FFF87A 097121 sta KeyState2
00FFF87C 020006 bra dbgk8
dbgk7:
00FFF87E 096121 lda KeyState2
00FFF880 084FFB anda #~4
00FFF882 097121 sta KeyState2
dbgk8:
00FFF884 00F120 clr KeyState1
00FFF886 020FB5 bra dbgk2
dbgkNotCtrl:
00FFF888 0C1059 cmpb #SC_RSHIFT
00FFF88A 026016 bne dbgkNotRshift
00FFF88C 00D120 tst KeyState1
00FFF88E 02B008 bmi dbgk9
00FFF890 096121 lda KeyState2
00FFF892 08A001 ora #1
00FFF894 097121 sta KeyState2
00FFF896 020006 bra dbgk10
dbgk9:
00FFF898 096121 lda KeyState2
00FFF89A 084FFE anda #~1
00FFF89C 097121 sta KeyState2
dbgk10:
00FFF89E 00F120 clr KeyState1
00FFF8A0 020F9B bra dbgk2
dbgkNotRshift:
00FFF8A2 0C1077 cmpb #SC_NUMLOCK
00FFF8A4 026013 bne dbgkNotNumlock
00FFF8A6 096121 lda KeyState2
00FFF8A8 088010 eora #16
00FFF8AA 097121 sta KeyState2
00FFF8AC 096122 lda KeyLED
00FFF8AE 088002 eora #2
00FFF8B0 097122 sta KeyLED
00FFF8B2 01F089 tfr a,b
00FFF8B4 04F clra
00FFF8B5 08DED2 bsr KeybdSetLED
00FFF8B7 020F84 bra dbgk2
dbgkNotNumlock:
00FFF8B9 0C1058 cmpb #SC_CAPSLOCK
00FFF8BB 026013 bne dbgkNotCapslock
00FFF8BD 096121 lda KeyState2
00FFF8BF 088020 eora #32
00FFF8C1 097121 sta KeyState2
00FFF8C3 096122 lda KeyLED
00FFF8C5 088004 eora #4
00FFF8C7 097122 sta KeyLED
00FFF8C9 01F089 tfr a,b
00FFF8CB 04F clra
00FFF8CC 08DEBB bsr KeybdSetLED
00FFF8CE 020F6D bra dbgk2
dbgkNotCapslock:
00FFF8D0 0C107E cmpb #SC_SCROLLLOCK
00FFF8D2 026013 bne dbgkNotScrolllock
00FFF8D4 096121 lda KeyState2
00FFF8D6 088040 eora #64
00FFF8D8 097121 sta KeyState2
00FFF8DA 096122 lda KeyLED
00FFF8DC 088001 eora #1
00FFF8DE 097122 sta KeyLED
00FFF8E0 01F089 tfr a,b
00FFF8E2 04F clra
00FFF8E3 08DEA4 bsr KeybdSetLED
00FFF8E5 020F56 bra dbgk2
dbgkNotScrolllock:
00FFF8E7 0C1011 cmpb #SC_ALT
00FFF8E9 026016 bne dbgkNotAlt
00FFF8EB 00D120 tst KeyState1
00FFF8ED 02B008 bmi dbgk11
00FFF8EF 096121 lda KeyState2
00FFF8F1 08A002 ora #2
00FFF8F3 097121 sta KeyState2
00FFF8F5 020006 bra dbgk12
dbgk11:
00FFF8F7 096121 lda KeyState2
00FFF8F9 084FFD anda #~2
00FFF8FB 097121 sta KeyState2
dbgk12:
00FFF8FD 00F120 clr KeyState1
00FFF8FF 020F3C bra dbgk2
dbgkNotAlt:
00FFF901 00D120 tst KeyState1
00FFF903 027004 beq dbgk13
00FFF905 00F120 clr KeyState1
00FFF907 020F34 bra dbgk2
dbgk13:
00FFF909 096121 lda KeyState2 ; Check for CTRL-ALT-DEL
00FFF90B 084006 anda #6
00FFF90D 081006 cmpa #6
00FFF90F 026008 bne dbgk14
00FFF911 0C1071 cmpb #SC_DEL
00FFF913 026004 bne dbgk14
00FFF915 06E90FFFFFFE jmp [$FFFFFE] ; jump to reset vector
dbgk14:
00FFF919 00D121 tst KeyState2 ; extended code?
00FFF91B 02A00B bpl dbgk15
00FFF91D 096121 lda KeyState2
00FFF91F 0847FF anda #$7FF
00FFF921 097121 sta KeyState2
00FFF923 08EFFF680 ldx #keybdExtendedCodes
00FFF926 020017 bra dbgk18
dbgk15:
00FFF928 096121 lda KeyState2 ; Is CTRL down?
00FFF92A 085004 bita #4
00FFF92C 027005 beq dbgk16
00FFF92E 08EFFF600 ldx #keybdControlCodes
00FFF931 02000C bra dbgk18
dbgk16:
00FFF933 085001 bita #1 ; Is shift down?
00FFF935 027005 beq dbgk17
00FFF937 08EFFF500 ldx #shiftedScanCodes
00FFF93A 020003 bra dbgk18
dbgk17:
00FFF93C 08EFFF400 ldx #unshiftedScanCodes
dbgk18:
00FFF93F 03A abx
00FFF940 0E6804 ldb ,x
00FFF942 04F clra
00FFF943 035090 puls x,pc ; and return
00FFF945 04B04505904204F041052 fcb "KEYBOARD"
00FFF94C 044
00FFF94D FFF957 fcw KeybdOpen
00FFF94F FFF958 fcw KeybdClose
00FFF951 FFF959 fcw KeybdRead
00FFF953 FFF95A fcw KeybdWrite
00FFF955 FFF95B fcw KeybdSeek
; Keyboard Open:
; Initialize the keyboard buffer head and tail indexes
;
KeybdOpen:
00FFF957 039 rts
; Keyboard Close:
; Nothing to do except maybe clear the keyboard buffer
;
KeybdClose:
00FFF958 039 rts
;
KeybdRead:
00FFF959 039 rts
;
KeybdWrite:
00FFF95A 039 rts
KeybdSeek:
00FFF95B 039 rts
;------------------------------------------------------------------------------
; Check if there is a keyboard character available. If so return true (<0)
; otherwise return false (0) in accb.
;------------------------------------------------------------------------------
;
KeybdCheckForKeyDirect:
00FFF95C 020EDB bra DBGCheckForKey
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
INCH:
00FFF95E 0CCFFFFFF ldd #-1 ; block if no key available
00FFF961 020ED8 bra DBGGetKey
INCHE:
00FFF963 08DFF9 bsr INCH
00FFF965 020009 bra INCHEK3
INCHEK:
00FFF967 08DFF5 bsr INCH
00FFF969 01507DFFFFFCA00 tst KeybdEcho
00FFF96E 02700B beq INCHEK1
INCHEK3:
00FFF970 08100D cmpa #CR
00FFF972 026005 bne INCHEK2
00FFF974 017FFD75B lbsr CRLF
*** warning 1: Long branch within short branch range could be optimized
00FFF977 020002 bra INCHEK1
INCHEK2:
00FFF979 08D920 bsr DisplayChar
INCHEK1:
00FFF97B 039 rts
OUTCH:
00FFF97C 06E90F000800 jmp [CharOutVec]
;------------------------------------------------------------------------------
; r1 0=echo off, non-zero = echo on
;------------------------------------------------------------------------------
;
SetKeyboardEcho:
00FFF980 0150F7FFFFFCA00 stb KeybdEcho
00FFF985 039 rts
;------------------------------------------------------------------------------
; Parameters:
; x,d bitmap of sprites to enable
;------------------------------------------------------------------------------
ShowSprites:
00FFF986 0150BFFFFE103C0 stx SPRITE_CTRL+SPRITE_EN
00FFF98B 0150FDFFFE103C2 std SPRITE_CTRL+SPRITE_EN+2
00FFF990 039 rts
;==============================================================================
; System Monitor
;==============================================================================
;
MonitorStart:
00FFF991 0CCFFFAEF ldd #HelpMsg
00FFF994 08D9BE bsr DisplayString
Monitor:
00FFF996 03280F003FFF leas $3FFF ; reset stack pointer
00FFF99A 05F clrb ; turn off keyboard echo
00FFF99B 08DFE3 bsr SetKeyboardEcho
; jsr RequestIOFocus
PromptLn:
00FFF99D 017FFD732 lbsr CRLF
*** warning 1: Long branch within short branch range could be optimized
00FFF9A0 0C6024 ldb #'$'
00FFF9A2 08DFD8 bsr OUTCH
; Get characters until a CR is keyed
Prompt3:
00FFF9A4 0CCFFFFFF ldd #-1 ; block until key present
00FFF9A7 08DE92 bsr DBGGetKey
00FFF9A9 0C100D cmpb #CR
00FFF9AB 027004 beq Prompt1
00FFF9AD 08DFCD bsr OUTCH
00FFF9AF 020FF3 bra Prompt3
; Process the screen line that the CR was keyed on
;
Prompt1:
00FFF9B1 0CC005050 ldd #$5050
00FFF9B4 0150FDFFFE60000 std LEDS
00FFF9B9 0F6800000 ldb RunningID
00FFF9BC 0C103D cmpb #61
00FFF9BE 022FE4 bhi Prompt3
00FFF9C0 0CC005151 ldd #$5151
00FFF9C3 0150FDFFFE60000 std LEDS
00FFF9C8 00F111 clr CursorCol ; go back to the start of the line
00FFF9CA 08D8AD bsr CalcScreenLoc ; calc screen memory location
00FFF9CC 01F002 tfr d,y
00FFF9CE 0CC005252 ldd #$5252
00FFF9D1 0150FDFFFE60000 std LEDS
00FFF9D6 08D055 bsr MonGetNonSpace
00FFF9D8 0C1024 cmpb #'$'
00FFF9DA 026009 bne Prompt2 ; skip over '$' prompt character
00FFF9DC 086353 lda #$5353
00FFF9DE 0150FDFFFE60000 std LEDS
00FFF9E3 08D048 bsr MonGetNonSpace
; Dispatch based on command character
;
Prompt2:
00FFF9E5 0C103F cmpb #'?' ; $? - display help
00FFF9E7 026007 bne PromptC
00FFF9E9 0CCFFFAEF ldd #HelpMsg
00FFF9EC 08D966 bsr DisplayString
00FFF9EE 020FA6 bra Monitor
PromptC:
00FFF9F0 0C1043 cmpb #'C'
00FFF9F2 026007 bne PromptD
00FFF9F4 017FFF7D9 lbsr ClearScreen
*** warning 1: Long branch within short branch range could be optimized
00FFF9F7 08D848 bsr HomeCursor
00FFF9F9 020F9B bra Monitor
PromptD:
00FFF9FB 0C1044 cmpb #'D'
00FFF9FD 026008 bne PromptF
00FFF9FF 08D027 bsr MonGetch
00FFFA01 0C1052 cmpb #'R'
00FFFA03 026F9F bne Prompt3
00FFFA05 020193 bra DumpRegs
PromptF:
00FFFA07 0C1046 cmpb #'F'
00FFFA09 02600F bne PromptJ
00FFFA0B 08D01B bsr MonGetch
00FFFA0D 0C1049 cmpb #'I'
00FFFA0F 026F85 bne Monitor
00FFFA11 08D015 bsr MonGetch
00FFFA13 0C1047 cmpb #'G'
00FFFA15 026F7F bne Monitor
00FFFA17 07EFE0000 jmp $FE0000
PromptJ:
00FFFA1A 0C104A cmpb #'J'
00FFFA1C 1270001BF lbeq jump_to_code
PromptR:
00FFFA1F 0C1052 cmpb #'R'
00FFFA21 026F73 bne Monitor
00FFFA23 017FFE5DA lbsr ramtest
*** warning 1: Long branch within short branch range could be optimized
00FFFA26 020F6E bra Monitor
MonGetch:
00FFFA28 0E6A04 ldb ,y
00FFFA2A 031201 leay 1,y
00FFFA2C 039 rts
MonGetNonSpace:
00FFFA2D 08DFF9 bsr MonGetCh
00FFFA2F 0C1020 cmpb #' '
00FFFA31 027FFA beq MonGetNonSpace
00FFFA33 0C1009 cmpb #9 ; tab
00FFFA35 027FF6 beq MonGetNonSpace
00FFFA37 039 rts
;------------------------------------------------------------------------------
; Ignore blanks in the input
; Y = text pointer
; D destroyed
;------------------------------------------------------------------------------
;
ignBlanks:
ignBlanks1:
00FFFA38 08DFEE bsr MonGetch
00FFFA3A 0C1020 cmpb #' '
00FFFA3C 027FFA beq ignBlanks1
00FFFA3E 0313FF leay -1,y
00FFFA40 039 rts
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
GetTwoParams:
00FFFA41 08DFF5 bsr ignBlanks
00FFFA43 08D02E bsr GetHexNumber ; get start address of dump
00FFFA45 0DC910 ldd mon_numwka
00FFFA47 0DD920 std mon_r1
00FFFA49 0DC912 ldd mon_numwka+2
00FFFA4B 0DD922 std mon_r1+2
00FFFA4D 08DFE9 bsr ignBlanks
00FFFA4F 08D022 bsr GetHexNumber ; get end address of dump
00FFFA51 0DC910 ldd mon_numwka
00FFFA53 0DD922 std mon_r2
00FFFA55 0DC912 ldd mon_numwka+2
00FFFA57 0DD924 std mon_r2+2
00FFFA59 039 rts
;------------------------------------------------------------------------------
; Get a range, the end must be greater or equal to the start.
;------------------------------------------------------------------------------
GetRange:
00FFFA5A 08DFE5 bsr GetTwoParams
00FFFA5C 0DC924 ldd mon_r2+2
00FFFA5E 093922 subd mon_r1+2
00FFFA60 0DC922 ldd mon_r2
00FFFA62 0D2921 sbcb mon_r1+1
00FFFA64 092920 sbca mon_r1
00FFFA66 12500006C lbcs DisplayErr
00FFFA69 039 rts
shl_numwka:
00FFFA6A 008913 asl mon_numwka+3
00FFFA6C 009912 rol mon_numwka+2
00FFFA6E 009911 rol mon_numwka+1
00FFFA70 009910 rol mon_numwka
00FFFA72 039 rts
;------------------------------------------------------------------------------
; Get a hexidecimal number. Maximum of nine digits.
; Y = text pointer (updated)
; D = number of digits
; mon_numwka contains number
;------------------------------------------------------------------------------
;
GetHexNumber:
00FFFA73 04F05F clrd
00FFFA75 0DD910 std mon_numwka
00FFFA77 0DD912 std mon_numwka+2
00FFFA79 034010 pshs x
00FFFA7B 08E000000 ldx #0 ; max 9 eight digits
gthxn2:
00FFFA7E 08DFA8 bsr MonGetch
00FFFA80 08D01D bsr AsciiToHexNybble
00FFFA82 0C1FFF cmpb #-1
00FFFA84 027015 beq gthxn1
00FFFA86 08DFE2 bsr shl_numwka
00FFFA88 08DFE0 bsr shl_numwka
00FFFA8A 08DFDE bsr shl_numwka
00FFFA8C 08DFDC bsr shl_numwka
00FFFA8E 0C400F andb #$0f
00FFFA90 0DA913 orb mon_numwka+3
00FFFA92 0D7913 stb mon_numwka+3
00FFFA94 030001 inx
00FFFA96 08C000009 cmpx #9
00FFFA99 025FE3 blo gthxn2
gthxn1:
00FFFA9B 01F010 tfr x,d
00FFFA9D 035090 puls x,pc
;GetDecNumber:
; phx
; push r4
; push r5
; ldx #0
; ld r4,#10
; ld r5,#10
;gtdcn2:
; jsr MonGetch
; jsr AsciiToDecNybble
; cmp #-1
; beq gtdcn1
; mul r2,r2,r5
; add r2,r1
; dec r4
; bne gtdcn2
;gtdcn1:
; txa
; pop r5
; pop r4
; plx
; rts
;------------------------------------------------------------------------------
; Convert ASCII character in the range '0' to '9', 'a' to 'f' or 'A' to 'F'
; to a hex nybble.
;------------------------------------------------------------------------------
;
AsciiToHexNybble:
00FFFA9F 0C1030 cmpb #'0'
00FFFAA1 024021 bcc gthx3
00FFFAA3 0C103A cmpb #'9'+1
00FFFAA5 025003 bcs gthx5
00FFFAA7 0C0030 subb #'0'
00FFFAA9 039 rts
gthx5:
00FFFAAA 0C1041 cmpb #'A'
00FFFAAC 024016 bcc gthx3
00FFFAAE 0C1047 cmpb #'F'+1
00FFFAB0 025005 bcs gthx6
00FFFAB2 0C0041 subb #'A'
00FFFAB4 0CB00A addb #10
00FFFAB6 039 rts
gthx6:
00FFFAB7 0C1061 cmpb #'a'
00FFFAB9 024009 bcc gthx3
00FFFABB 0C107B cmpb #'z'+1
00FFFABD 025005 bcs gthx3
00FFFABF 0C0061 subb #'a'
00FFFAC1 0CB00A addb #10
00FFFAC3 039 rts
gthx3:
00FFFAC4 0C6FFF ldb #-1 ; not a hex number
00FFFAC6 039 rts
AsciiToDecNybble:
00FFFAC7 0C1030 cmpb #'0'
00FFFAC9 024007 bcc gtdc3
00FFFACB 0C103A cmpb #'9'+1
00FFFACD 025003 bcs gtdc3
00FFFACF 0C0030 subb #'0'
00FFFAD1 039 rts
gtdc3:
00FFFAD2 0C6FFF ldb #-1
00FFFAD4 039 rts
DisplayErr:
00FFFAD5 08EFFFAE7 ldx #msgErr
00FFFAD8 04F05F clrd
00FFFADA 08D003 bsr DisplayStringDX
00FFFADC 07EFFF996 jmp Monitor
DisplayStringDX
00FFFADF 0DD024 std Strptr
00FFFAE1 09F026 stx Strptr+2
00FFFAE3 0BDFFF354 jsr DisplayString
00FFFAE6 039 rts
msgErr:
00FFFAE7 02A02A04507207200D00A fcb "**Err",CR,LF,0
00FFFAEE 000
HelpMsg:
00FFFAEF 03F02003D020044069073 fcb "? = Display help",CR,LF
00FFFAF6 07006C061079020068065
00FFFAFD 06C07000D00A
00FFFB01 04304C05302003D020063 fcb "CLS = clear screen",CR,LF
00FFFB08 06C065061072020073063
00FFFB0F 07206506506E00D00A
; db "S = Boot from SD Card",CR,LF
; db ": = Edit memory bytes",CR,LF
; db "L = Load sector",CR,LF
; db "W = Write sector",CR,LF
00FFFB15 04405202003D020044075 fcb "DR = Dump registers",CR,LF
00FFFB1C 06D070020072065067069
00FFFB23 07307406507207300D00A
; db "D = Dump memory",CR,LF
; db "F = Fill memory",CR,LF
; db "FL = Dump I/O Focus List",CR,LF
00FFFB2A 04604904702003D020073 fcb "FIG = start FIG Forth",CR,LF
00FFFB31 074061072074020046049
00FFFB38 04702004606F072074068
00FFFB3F 00D00A
; db "KILL n = kill task #n",CR,LF
; db "B = start tiny basic",CR,LF
; db "b = start EhBasic 6502",CR,LF
00FFFB41 04A02003D02004A07506D fcb "J = Jump to code",CR,LF
00FFFB48 07002007406F02006306F
00FFFB4F 06406500D00A
00FFFB53 05204104D02003D020074 fcb "RAM = test RAM",CR,LF
00FFFB5A 06507307402005204104D
00FFFB61 00D00A
; db "R[n] = Set register value",CR,LF
; db "r = random lines - test bitmap",CR,LF
; db "e = ethernet test",CR,LF
; db "T = Dump task list",CR,LF
; db "TO = Dump timeout list",CR,LF
; db "TI = display date/time",CR,LF
; db "TEMP = display temperature",CR,LF
; db "P = Piano",CR,LF,0
00FFFB63 000 fcb 0
msgRegHeadings
00FFFB64 00D00A02004402F041042 fcb CR,LF," D/AB X Y U S PC DP CCR",CR,LF,0
00FFFB6B 020020020058020020020
00FFFB72 020059020020020020055
00FFFB79 020020020020053020020
00FFFB80 020020020050043020020
00FFFB87 020020044050020043043
00FFFB8E 05200D00A000
nHEX4:
00FFFB92 0BDFFD2D2 jsr HEX4
00FFFB95 039 rts
nXBLANK:
00FFFB96 0C6020 ldb #' '
00FFFB98 020DE2 bra OUTCH
DumpRegs
00FFFB9A 08EFFFB64 ldx #msgRegHeadings
00FFFB9D 0CC0000FF ldd #msgRegHeadings>>16
00FFFBA0 0BDFFFADF jsr DisplayStringDX
00FFFBA3 08DFF1 bsr nXBLANK
00FFFBA5 0DC900 ldd mon_DSAVE
00FFFBA7 08DFE9 bsr nHEX4
00FFFBA9 08DFEB bsr nXBLANK
00FFFBAB 0DC902 ldd mon_XSAVE
00FFFBAD 08DFE3 bsr nHEX4
00FFFBAF 08DFE5 bsr nXBLANK
00FFFBB1 0DC904 ldd mon_YSAVE
00FFFBB3 08DFDD bsr nHEX4
00FFFBB5 08DFDF bsr nXBLANK
00FFFBB7 0DC906 ldd mon_USAVE
00FFFBB9 08DFD7 bsr nHEX4
00FFFBBB 08DFD9 bsr nXBLANK
00FFFBBD 0DC908 ldd mon_SSAVE
00FFFBBF 08DFD1 bsr nHEX4
00FFFBC1 08DFD3 bsr nXBLANK
00FFFBC3 0DC90A ldd mon_PCSAVE
00FFFBC5 08DFCB bsr nHEX4
00FFFBC7 0DC90C ldd mon_PCSAVE+2
00FFFBC9 08DFC7 bsr nHEX4
00FFFBCB 08DFC9 bsr nXBLANK
00FFFBCD 0DC90E ldd mon_DPRSAVE
00FFFBCF 0BDFFD2CE jsr HEX2
00FFFBD2 08DFC2 bsr nXBLANK
00FFFBD4 09690F lda mon_CCRSAVE
00FFFBD6 0BDFFD2CE jsr HEX2
00FFFBD9 08DFBB bsr nXBLANK
00FFFBDB 07EFFF996 jmp Monitor
; Jump to code
jump_to_code:
00FFFBDE 08DE93 bsr GetHexNumber
00FFFBE0 01A010 sei
00FFFBE2 1DE908 lds mon_SSAVE
00FFFBE4 0CCFFFC11 ldd #<jtc_exit
00FFFBE7 034006 pshs d
00FFFBE9 0CC000000 ldd #>jtc_exit
00FFFBEC 034004 pshs b
00FFFBEE 0DC912 ldd mon_numwka+2
00FFFBF0 034006 pshs d
00FFFBF2 0DC910 ldd mon_numwka
00FFFBF4 034006 pshs d
00FFFBF6 0DC906 ldd mon_USAVE
00FFFBF8 034006 pshs d
00FFFBFA 0DC904 ldd mon_YSAVE
00FFFBFC 034006 pshs d
00FFFBFE 0DC902 ldd mon_XSAVE
00FFFC00 034006 pshs d
00FFFC02 09690E lda mon_DPRSave
00FFFC04 034002 pshs a
00FFFC06 0DC900 ldd mon_DSAVE
00FFFC08 034006 pshs d
00FFFC0A 09690F lda mon_CCRSAVE
00FFFC0C 034002 pshs a
00FFFC0E 0150350FF puls far ccr,d,dpr,x,y,u,pc
jtc_exit:
00FFFC11 034001 pshs ccr
00FFFC13 0DD900 std mon_DSAVE
00FFFC15 09F902 stx mon_XSAVE
00FFFC17 19F904 sty mon_YSAVE
00FFFC19 0DF906 stu mon_USAVE
00FFFC1B 01F0B8 tfr dpr,a
00FFFC1D 09790E sta mon_DPRSAVE
00FFFC1F 035002 puls a
00FFFC21 09790F sta mon_CCRSAVE
00FFFC23 1DF908 sts mon_SSAVE
00FFFC25 1CE003FFF lds #$3FFF
; todo set according to coreid
00FFFC28 07EFFFB9A jmp DumpRegs
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
swi3_rout:
00FFFC2B 01A010 sei
00FFFC2D 035002 puls a
00FFFC2F 09790F sta mon_CCRSAVE
00FFFC31 03507E puls D,DPR,X,Y,U
00FFFC33 0DD900 std mon_DSAVE
00FFFC35 09F902 stx mon_XSAVE
00FFFC37 19F904 sty mon_YSAVE
00FFFC39 0DF906 stu mon_USAVE
00FFFC3B 01F0B8 tfr dpr,a
00FFFC3D 09790E sta mon_DPRSAVE
00FFFC3F 035006 puls D
00FFFC41 0DD90A std mon_PCSAVE
00FFFC43 035006 puls D
00FFFC45 0DD90C std mon_PCSAVE+2
00FFFC47 1DF908 sts mon_SSAVE
00FFFC49 1CE003FFF lds #$3FFF
00FFFC4C 01C0EF cli
00FFFC4E 07EFFFB9A jmp DumpRegs
swi3_exit:
00FFFC51 01A010 sei
00FFFC53 1DE908 lds mon_SSAVE
00FFFC55 0DC90C ldd mon_PCSAVE+2
00FFFC57 034006 pshs d
00FFFC59 0DC90A ldd mon_PCSAVE
00FFFC5B 034006 pshs d
00FFFC5D 0DE906 ldu mon_USAVE
00FFFC5F 19E904 ldy mon_YSAVE
00FFFC61 09E902 ldx mon_XSAVE
00FFFC63 034070 pshs x,y,u
00FFFC65 09690E lda mon_DPRSAVE
00FFFC67 034002 pshs a
00FFFC69 0DC900 ldd mon_DSAVE
00FFFC6B 034006 pshs d
00FFFC6D 09690F lda mon_CCRSAVE
00FFFC6F 034002 pshs a
00FFFC71 01F08A tfr a,ccr
00FFFC73 01C0EF cli
00FFFC75 03B rti
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
irq_rout:
; Reset the edge sense circuit in the PIC
00FFFC76 086002 lda #2 ; Timer is IRQ #2
00FFFC78 0150B7FFFE3F006 sta PIC+6 ; register 6 is edge sense reset reg
00FFFC7D 09779A sta IrqSource ; stuff a byte indicating the IRQ source for PEEK()
00FFFC7F 0960DF lda IrqBase ; get the IRQ flag byte
00FFFC81 044 lsra
00FFFC82 09A0DF ora IrqBase
00FFFC84 0840E0 anda #$E0
00FFFC86 0970DF sta IrqBase
00FFFC88 01507CFFFE0006E inc TEXTSCR+110 ; update IRQ live indicator on screen
; flash the cursor
; only bother to flash the cursor for the task with the IO focus.
00FFFC8D 0150B6FFFFFFFE0 lda COREID
00FFFC92 091100 cmpa IOFocusID
00FFFC94 026021 bne tr1a
00FFFC96 096114 lda CursorFlash ; test if we want a flashing cursor
00FFFC98 02701D beq tr1a
00FFFC9A 017FFF5DC lbsr CalcScreenLoc ; compute cursor location in memory
*** warning 1: Long branch within short branch range could be optimized
00FFFC9D 01F002 tfr d,y
00FFFC9F 0A6A09002000 lda $2000,y ; get color code $2000 higher in memory
00FFFCA3 0D67C6 ldb IRQFlag ; get counter
00FFFCA5 054 lsrb
00FFFCA6 044 lsra
00FFFCA7 044 lsra
00FFFCA8 044 lsra
00FFFCA9 044 lsra
00FFFCAA 054 lsrb
00FFFCAB 049 rola
00FFFCAC 054 lsrb
00FFFCAD 049 rola
00FFFCAE 054 lsrb
00FFFCAF 049 rola
00FFFCB0 054 lsrb
00FFFCB1 049 rola
00FFFCB2 0A7A0A000E00000 sta $E00000,y ; store the color code back to memory
tr1a
00FFFCB7 03B rti
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
nmi_rout:
00FFFCB8 0150F6FFFFFFFE0 ldb COREID
00FFFCBD 086049 lda #'I'
00FFFCBF 08EE00028 ldx #TEXTSCR+40
00FFFCC2 03A abx
00FFFCC3 0A7804 sta ,x
00FFFCC5 03B rti
org $FFFFF0
00FFFFF0 012 nop
00FFFFF1 012 nop
00FFFFF2 FFFC2B fcw swi3_rout
org $FFFFF8
00FFFFF8 FFFC76 fcw irq_rout
00FFFFFA FFF023 fcw start ; SWI
00FFFFFC FFFCB8 fcw nmi_rout ; NMI
00FFFFFE FFF023 fcw start ; RST
 
8 warning(s) in pass 2.
 
SYMBOL TABLE
ASCIITODECNYBBLE 02 00FFFAC7 ASCIITOHEXNYBBLE 02 00FFFA9F BIOS_SCREENS 00 17000000 BLANKLINE 02 00FFF216
BLKCPYDST 00 00000020 BLKCPYSRC 00 0000001C BLNKLN1 02 00FFF229 CALCSCREENLOC 02 00FFF279
CHARCOLOR 00 00000112 CHARINVEC 00 00000804 CHAROUTVEC 00 00000800 CHECKPOINT 02 00FFF0E0
CLEARSCREEN 02 00FFF1D0 CLEARSCREENJMP 02 00FFD300 COLORCODELOCATION 00 00000014 COPYSCREENTOVIRTUALSCREEN 02 00FFF1A0
COPYVIRTUALSCREENTOSCREEN 02 00FFF178 COREID 00 FFFFFFE0 CR 00 0000000D CRLF 02 00FFD0D2
CRLF1 02 00FFD0D2 CRLFST 02 00FFF388 CS1 02 00FFF1DD CS2 02 00FFF1F3
CS2V1 02 00FFF1AC CS3 02 00FFF1F9 CSL1 02 00FFF293 CTRLC 00 00000003
CTRLH 00 00000008 CTRLI 00 00000009 CTRLJ 00 0000000A CTRLK 00 0000000B
CTRLM 00 0000000D CTRLS 00 00000013 CTRLX 00 00000018 CURSORCOL 00 00000111
CURSORFLASH 00 00000114 CURSORROW 00 00000110 CV2S1 02 00FFF184 DBGCHECKFORKEY 02 00FFF839
DBGGETKEY 02 00FFF83B DBGK1 02 00FFF84F DBGK10 02 00FFF89E DBGK11 02 00FFF8F7
DBGK12 02 00FFF8FD DBGK13 02 00FFF909 DBGK14 02 00FFF919 DBGK15 02 00FFF928
DBGK16 02 00FFF933 DBGK17 02 00FFF93C DBGK18 02 00FFF93F DBGK2 02 00FFF83D
DBGK3 02 00FFF854 DBGK4 02 00FFF862 DBGK5 02 00FFF86E DBGK7 02 00FFF87E
DBGK8 02 00FFF884 DBGK9 02 00FFF898 DBGKNOTALT 02 00FFF901 DBGKNOTCAPSLOCK 02 00FFF8D0
DBGKNOTCTRL 02 00FFF888 DBGKNOTNUMLOCK 02 00FFF8B9 DBGKNOTRSHIFT 02 00FFF8A2 DBGKNOTSCROLLLOCK 02 00FFF8E7
DCCR 02 00FFF2A7 DCLF 02 00FFF32D DCX10 02 00FFF2E1 DCX11 02 00FFF2F1
DCX12 02 00FFF2ED DCX13 02 00FFF2FD DCX14 02 00FFF2A5 DCX3 02 00FFF31B
DCX4 02 00FFF32F DCX5 02 00FFF30A DCX6 02 00FFF2B8 DCX7 02 00FFF2B4
DCX8 02 00FFF2C5 DCX9 02 00FFF2D2 DELAY3S 02 00FFF15B DISPBYTEASHEX 02 00FFF39D
DISPDWORDASHEX 02 00FFF38B DISPLAYCHAR 02 00FFF29B DISPLAYERR 02 00FFFAD5 DISPLAYSTRING 02 00FFF354
DISPLAYSTRINGCRLF 02 00FFF362 DISPLAYSTRINGDX 02 00FFFADF DISPNYB 02 00FFF3B5 DISPNYB1 02 00FFF3C3
DISPWORDASHEX 02 00FFF394 DLY3S1 02 00FFF15E DLY3S2 02 00FFF162 DRAM_BASE 00 10000000
DSPJ1B 02 00FFF358 DSRETB 02 00FFF360 DUMPREGS 02 00FFFB9A DUMRTS 02 00FFF022
FIRST_CORE 00 00000001 FREEMBX 02 00000002 FREEMSG 02 00000006 FREETCB 00 0000078A
GETHEXNUMBER 02 00FFFA73 GETRANGE 02 00FFFA5A GETSCREENLOCATION 02 00FFF230 GETTWOPARAMS 02 00FFFA41
GSL1 02 00FFF23D GTDC3 02 00FFFAD2 GTHX3 02 00FFFAC4 GTHX5 02 00FFFAAA
GTHX6 02 00FFFAB7 GTHXN1 02 00FFFA9B GTHXN2 02 00FFFA7E HC1 02 00FFF256
HELPMSG 02 00FFFAEF HEX2 02 00FFD2CE HEX4 02 00FFD2D2 HOMECURSOR 02 00FFF241
HOMECURSORJMP 02 00FFD308 ICC1 02 00FFF350 ICC2 02 00FFF352 ICR1 02 00FFF342
IGNBLANKS 02 00FFFA38 IGNBLANKS1 02 00FFFA38 INCCURSORPOS 02 00FFF331 INCCURSORROW 02 00FFF340
INCH 02 00FFF95E INCHE 02 00FFF963 INCHEK 02 00FFF967 INCHEK1 02 00FFF97B
INCHEK2 02 00FFF979 INCHEK3 02 00FFF970 INIT 02 00FFF072 IOFOCUSID 00 00000100
IOFOCUSNDX 00 00000100 IRQBASE 00 000000DF IRQFLAG 00 000007C6 IRQSOURCE 00 0000079A
IRQ_ROUT 02 00FFFC76 JTC_EXIT 02 00FFFC11 JUMP_TO_CODE 02 00FFFBDE KBDI0002 02 00FFF7C5
KBDI0004 02 00FFF80A KBDITRYAGAIN 02 00FFF7FE KBGS1 02 00FFF778 KBGS2 02 00FFF770
KBGS3 02 00FFF761 KEYBD 00 FFE30400 KEYBDACK 00 FFFFCC00 KEYBDBAD 00 FFFFCB00
KEYBDBUFFER 00 FFFFC000 KEYBDCHECKFORKEYDIRECT 02 00FFF95C KEYBDCLOSE 02 00FFF958 KEYBDCLR 00 FFE30402
KEYBDCONTROLCODES 02 00FFF600 KEYBDECHO 00 FFFFCA00 KEYBDEXTENDEDCODES 02 00FFF680 KEYBDGETID 02 00FFF79C
KEYBDGETSCANCODE 02 00FFF77D KEYBDGETSTATUS 02 00FFF761 KEYBDHEAD 00 FFFFC800 KEYBDID 00 00000124
KEYBDINIT 02 00FFF7C0 KEYBDLOCKS 00 FFFFCD00 KEYBDOPEN 02 00FFF957 KEYBDREAD 02 00FFF959
KEYBDRECVBYTE 02 00FFF700 KEYBDSEEK 02 00FFF95B KEYBDSENDBYTE 02 00FFF719 KEYBDSETLED 02 00FFF789
KEYBDTAIL 00 FFFFC900 KEYBDWAITTX 02 00FFF71F KEYBDWRITE 02 00FFF95A KEYLED 00 00000122
KEYSTATE1 00 00000120 KEYSTATE2 00 00000121 KGID1 02 00FFF7B9 KGNOTKBD 02 00FFF7BC
KRB3 02 00FFF705 KRB4 02 00FFF715 KWT1 02 00FFF724 KWT2 02 00FFF735
LEDS 00 FFE60000 LEDXIT 02 00FFF81E LETTER 02 00FFD2C1 LF 00 0000000A
MAX_TASKNO 00 0000003F MONGETCH 02 00FFFA28 MONGETNONSPACE 02 00FFFA2D MONITOR 02 00FFF996
MONITORSTART 02 00FFF991 MON_CCRSAVE 00 0000090F MON_DPRSAVE 00 0000090E MON_DSAVE 00 00000900
MON_NUMWKA 00 00000910 MON_PCSAVE 00 0000090A MON_R1 00 00000920 MON_R2 00 00000922
MON_SSAVE 00 00000908 MON_USAVE 00 00000906 MON_XSAVE 00 00000902 MON_YSAVE 00 00000904
MSCOUNT 00 FFFFFFE4 MSGBADKEYBD 02 00FFF82A MSGERR 02 00FFFAE7 MSGREGHEADINGS 02 00FFFB64
MSGSTARTUP 02 00FFF0BF MULTI_SIEVE 02 00FFF0F6 MULTI_SIEVE1 02 00FFF119 MULTI_SIEVE2 02 00FFF115
MULTI_SIEVE3 02 00FFF103 MULTI_SIEVE4 02 00FFF12C NHEX4 02 00FFFB92 NMAILBOX 02 00000004
NMIBASE 00 000000DC NMI_ROUT 02 00FFFCB8 NMSGBLK 02 00000008 NXBLANK 02 00FFFB96
ONEKEY 02 00FFD1DC OUTCH 02 00FFF97C PCRLF 02 00FFF374 PDATA 02 00FFF381
PIC 00 FFE3F000 PICPTR 00 00000028 PRINT 02 00FFF37E PROMPT1 02 00FFF9B1
PROMPT2 02 00FFF9E5 PROMPT3 02 00FFF9A4 PROMPTC 02 00FFF9F0 PROMPTD 02 00FFF9FB
PROMPTF 02 00FFFA07 PROMPTJ 02 00FFFA1A PROMPTLN 02 00FFF99D PROMPTR 02 00FFFA1F
PSTRNG 02 00FFF370 QNDX0 00 00000780 QNDX1 00 00000782 QNDX2 00 00000784
QNDX3 00 00000786 QNDX4 00 00000788 RAMERR 02 00FFE02C RAMTEST 02 00FFE000
RAMTEST1 02 00FFE00D RAMTEST3 02 00FFE017 ROMTORAM 02 00FFF0E6 ROMTORAM1 02 00FFF0EC
RUNNINGID 00 00800000 RUNNINGTCB 06 00000000 SCREENCOLOR 00 00000113 SCREENLOCATION 00 00000010
SCREENLOCATION2 00 00000018 SCROLLUP 02 00FFF1FB SCRUP1 02 00FFF208 SC_ALT 00 00000011
SC_C 00 00000021 SC_CAPSLOCK 00 00000058 SC_CTRL 00 00000014 SC_DEL 00 00000071
SC_EXTEND 00 000000E0 SC_F12 00 00000007 SC_KEYUP 00 000000F0 SC_NUMLOCK 00 00000077
SC_RSHIFT 00 00000059 SC_SCROLLLOCK 00 0000007E SC_T 00 0000002C SC_TAB 00 0000000D
SC_Z 00 0000001A SETKEYBOARDECHO 02 00FFF980 SHIFTEDSCANCODES 02 00FFF500 SHIFTLEFT5 02 00FFF16D
SHL_NUMWKA 02 00FFFA6A SHOWSPRITES 02 00FFF986 SIEVE 02 00FFF130 SIEVE1 02 00FFF148
SIEVE2 02 00FFF144 SIEVE3 02 00FFF135 SIEVE4 02 00FFF157 SKIP_INIT 02 00FFF08C
SPRITE_CTRL 00 FFE10000 SPRITE_EN 00 000003C0 ST1 02 00FFF079 ST3 02 00FFF069
ST6 02 00FFF030 ST7 02 00FFF03A ST8 02 00FFF03A START 02 00FFF023
STRPTR 00 00000024 SWI3_EXIT 02 00FFFC51 SWI3_ROUT 02 00FFFC2B TAB 00 00000009
TCB_CURSORCOL 00 00000021 TCB_CURSORROW 00 00000020 TCB_HJCB 00 0000001C TCB_HWAITMBX 00 00000022
TCB_IOF_NEXT 00 0000002C TCB_IOF_PREV 00 00000030 TCB_MBQ_NEXT 00 00000024 TCB_MBQ_PREV 00 00000028
TCB_MMU_MAP 00 00000038 TCB_MSGPTR_D1 00 00000014 TCB_MSGPTR_D2 00 00000018 TCB_NXTRDY 00 00000000
TCB_NXTTCB 00 00000008 TCB_PRIORITY 00 00000010 TCB_PRVRDY 00 00000004 TCB_SPSAVE 00 00000034
TCB_STATUS 00 0000001E TCB_TIMEOUT 00 0000000C TEXTCLOSE 02 00FFF1CC TEXTOPEN 02 00FFF1CB
TEXTREAD 02 00FFF1CD TEXTREG 00 FFE0DF00 TEXTSCR 00 FFE00000 TEXTSEEK 02 00FFF1CF
TEXTWRITE 02 00FFF1CE TEXT_COLS 00 00000000 TEXT_CURPOS 00 00000022 TEXT_ROWS 00 00000001
TIMEOUTLIST 00 0000078C TR1A 02 00FFFCB7 UCP1 02 00FFF277 UNSHIFTEDSCANCODES 02 00FFF400
UPDATECURSORPOS 02 00FFF258 W10_0001 02 00FFF740 W300_0001 02 00FFF754 WAIT10MS 02 00FFF739
WAIT300MS 02 00FFF74D XBLANK 02 00FFD0AF XOFF 00 00000013 XON 00 00000011
328 SYMBOLS
 
0 error(s), 70 warning(s)
/rf6809/trunk/software/boot/boot_rom.ver
0,0 → 1,3347
rommem[ 4268] <= 12'h012;
rommem[ 4269] <= 12'h012;
rommem[ 4270] <= 12'h012;
rommem[ 4271] <= 12'h0C6;
rommem[ 4272] <= 12'h020;
rommem[ 4273] <= 12'h017;
rommem[ 4274] <= 12'h002;
rommem[ 4275] <= 12'h8CB;
rommem[ 4276] <= 12'h039;
rommem[ 4304] <= 12'h012;
rommem[ 4305] <= 12'h012;
rommem[ 4306] <= 12'h0C6;
rommem[ 4307] <= 12'h00D;
rommem[ 4308] <= 12'h017;
rommem[ 4309] <= 12'h002;
rommem[ 4310] <= 12'h8A8;
rommem[ 4311] <= 12'h0C6;
rommem[ 4312] <= 12'h00A;
rommem[ 4313] <= 12'h017;
rommem[ 4314] <= 12'h002;
rommem[ 4315] <= 12'h8A3;
rommem[ 4316] <= 12'h039;
rommem[ 4336] <= 12'h012;
rommem[ 4337] <= 12'h020;
rommem[ 4338] <= 12'hFDF;
rommem[ 4572] <= 12'h06E;
rommem[ 4573] <= 12'h90F;
rommem[ 4574] <= 12'h000;
rommem[ 4575] <= 12'h804;
rommem[ 4800] <= 12'h012;
rommem[ 4801] <= 12'h017;
rommem[ 4802] <= 12'h002;
rommem[ 4803] <= 12'h6BB;
rommem[ 4804] <= 12'h039;
rommem[ 4812] <= 12'h012;
rommem[ 4813] <= 12'h012;
rommem[ 4814] <= 12'h017;
rommem[ 4815] <= 12'h002;
rommem[ 4816] <= 12'h0CC;
rommem[ 4817] <= 12'h039;
rommem[ 4818] <= 12'h017;
rommem[ 4819] <= 12'h002;
rommem[ 4820] <= 12'h0BF;
rommem[ 4821] <= 12'h039;
rommem[ 4864] <= 12'h016;
rommem[ 4865] <= 12'h001;
rommem[ 4866] <= 12'hECD;
rommem[ 4872] <= 12'h016;
rommem[ 4873] <= 12'h001;
rommem[ 4874] <= 12'hF36;
rommem[ 8192] <= 12'h18E;
rommem[ 8193] <= 12'h000;
rommem[ 8194] <= 12'h000;
rommem[ 8195] <= 12'h086;
rommem[ 8196] <= 12'h001;
rommem[ 8197] <= 12'h015;
rommem[ 8198] <= 12'h0B7;
rommem[ 8199] <= 12'hFFF;
rommem[ 8200] <= 12'hE60;
rommem[ 8201] <= 12'h000;
rommem[ 8202] <= 12'h0CC;
rommem[ 8203] <= 12'hAAA;
rommem[ 8204] <= 12'h555;
rommem[ 8205] <= 12'h0ED;
rommem[ 8206] <= 12'hA01;
rommem[ 8207] <= 12'h18C;
rommem[ 8208] <= 12'h008;
rommem[ 8209] <= 12'h000;
rommem[ 8210] <= 12'h025;
rommem[ 8211] <= 12'hFF9;
rommem[ 8212] <= 12'h18E;
rommem[ 8213] <= 12'h000;
rommem[ 8214] <= 12'h000;
rommem[ 8215] <= 12'h0EC;
rommem[ 8216] <= 12'hA01;
rommem[ 8217] <= 12'h183;
rommem[ 8218] <= 12'hAAA;
rommem[ 8219] <= 12'h555;
rommem[ 8220] <= 12'h026;
rommem[ 8221] <= 12'h00E;
rommem[ 8222] <= 12'h18C;
rommem[ 8223] <= 12'h008;
rommem[ 8224] <= 12'h000;
rommem[ 8225] <= 12'h025;
rommem[ 8226] <= 12'hFF4;
rommem[ 8227] <= 12'h086;
rommem[ 8228] <= 12'h002;
rommem[ 8229] <= 12'h015;
rommem[ 8230] <= 12'h0B7;
rommem[ 8231] <= 12'hFFF;
rommem[ 8232] <= 12'hE60;
rommem[ 8233] <= 12'h000;
rommem[ 8234] <= 12'h06E;
rommem[ 8235] <= 12'hC04;
rommem[ 8236] <= 12'h086;
rommem[ 8237] <= 12'h080;
rommem[ 8238] <= 12'h015;
rommem[ 8239] <= 12'h0B7;
rommem[ 8240] <= 12'hFFF;
rommem[ 8241] <= 12'hE60;
rommem[ 8242] <= 12'h000;
rommem[ 8243] <= 12'h08E;
rommem[ 8244] <= 12'hE00;
rommem[ 8245] <= 12'h000;
rommem[ 8246] <= 12'h015;
rommem[ 8247] <= 12'h0F6;
rommem[ 8248] <= 12'hFFF;
rommem[ 8249] <= 12'hFFF;
rommem[ 8250] <= 12'hFE0;
rommem[ 8251] <= 12'h03A;
rommem[ 8252] <= 12'h086;
rommem[ 8253] <= 12'h046;
rommem[ 8254] <= 12'h0A7;
rommem[ 8255] <= 12'h804;
rommem[ 8256] <= 12'h013;
rommem[ 8257] <= 12'h06E;
rommem[ 8258] <= 12'hC04;
rommem[12288] <= 12'hFFF;
rommem[12289] <= 12'h999;
rommem[12290] <= 12'hFFF;
rommem[12291] <= 12'h022;
rommem[12292] <= 12'hFFF;
rommem[12293] <= 12'h961;
rommem[12294] <= 12'hFFF;
rommem[12295] <= 12'h966;
rommem[12296] <= 12'hFFF;
rommem[12297] <= 12'h96A;
rommem[12298] <= 12'hFFF;
rommem[12299] <= 12'h97F;
rommem[12300] <= 12'hFFF;
rommem[12301] <= 12'h381;
rommem[12302] <= 12'hFFF;
rommem[12303] <= 12'h374;
rommem[12304] <= 12'hFFF;
rommem[12305] <= 12'h370;
rommem[12306] <= 12'hFFF;
rommem[12307] <= 12'h022;
rommem[12308] <= 12'hFFF;
rommem[12309] <= 12'h022;
rommem[12310] <= 12'hFFF;
rommem[12311] <= 12'h022;
rommem[12312] <= 12'hFFF;
rommem[12313] <= 12'h022;
rommem[12314] <= 12'hFFF;
rommem[12315] <= 12'h022;
rommem[12316] <= 12'hFFF;
rommem[12317] <= 12'h29B;
rommem[12318] <= 12'hFFF;
rommem[12319] <= 12'h022;
rommem[12320] <= 12'hFFF;
rommem[12321] <= 12'h022;
rommem[12322] <= 12'h039;
rommem[12323] <= 12'h086;
rommem[12324] <= 12'h055;
rommem[12325] <= 12'h015;
rommem[12326] <= 12'h0B7;
rommem[12327] <= 12'hFFF;
rommem[12328] <= 12'hE60;
rommem[12329] <= 12'h000;
rommem[12330] <= 12'h0CE;
rommem[12331] <= 12'hFFF;
rommem[12332] <= 12'h030;
rommem[12333] <= 12'h07E;
rommem[12334] <= 12'hFFE;
rommem[12335] <= 12'h000;
rommem[12336] <= 12'h1CE;
rommem[12337] <= 12'h003;
rommem[12338] <= 12'hFFF;
rommem[12339] <= 12'h015;
rommem[12340] <= 12'h0B6;
rommem[12341] <= 12'hFFF;
rommem[12342] <= 12'hFFF;
rommem[12343] <= 12'hFE0;
rommem[12344] <= 12'h081;
rommem[12345] <= 12'h002;
rommem[12346] <= 12'h08D;
rommem[12347] <= 12'h11F;
rommem[12348] <= 12'h086;
rommem[12349] <= 12'h0AA;
rommem[12350] <= 12'h015;
rommem[12351] <= 12'h0B7;
rommem[12352] <= 12'hFFF;
rommem[12353] <= 12'hE60;
rommem[12354] <= 12'h000;
rommem[12355] <= 12'h086;
rommem[12356] <= 12'h002;
rommem[12357] <= 12'h097;
rommem[12358] <= 12'h100;
rommem[12359] <= 12'h0B7;
rommem[12360] <= 12'h800;
rommem[12361] <= 12'h000;
rommem[12362] <= 12'h086;
rommem[12363] <= 12'h0CE;
rommem[12364] <= 12'h097;
rommem[12365] <= 12'h113;
rommem[12366] <= 12'h097;
rommem[12367] <= 12'h112;
rommem[12368] <= 12'h08D;
rommem[12369] <= 12'h17E;
rommem[12370] <= 12'h0CC;
rommem[12371] <= 12'hFFF;
rommem[12372] <= 12'h29B;
rommem[12373] <= 12'h0DD;
rommem[12374] <= 12'h800;
rommem[12375] <= 12'h0CC;
rommem[12376] <= 12'hFFF;
rommem[12377] <= 12'h83B;
rommem[12378] <= 12'h0DD;
rommem[12379] <= 12'h804;
rommem[12380] <= 12'h015;
rommem[12381] <= 12'h0F6;
rommem[12382] <= 12'hFFF;
rommem[12383] <= 12'hFFF;
rommem[12384] <= 12'hFE0;
rommem[12385] <= 12'h0C1;
rommem[12386] <= 12'h002;
rommem[12387] <= 12'h027;
rommem[12388] <= 12'h00D;
rommem[12389] <= 12'h020;
rommem[12390] <= 12'h025;
rommem[12391] <= 12'h020;
rommem[12392] <= 12'h08D;
rommem[12393] <= 12'h086;
rommem[12394] <= 12'h0FF;
rommem[12395] <= 12'h015;
rommem[12396] <= 12'h0B7;
rommem[12397] <= 12'hFFF;
rommem[12398] <= 12'hE60;
rommem[12399] <= 12'h000;
rommem[12400] <= 12'h020;
rommem[12401] <= 12'hFF7;
rommem[12402] <= 12'h08E;
rommem[12403] <= 12'h000;
rommem[12404] <= 12'h080;
rommem[12405] <= 12'h086;
rommem[12406] <= 12'h001;
rommem[12407] <= 12'h0C6;
rommem[12408] <= 12'h002;
rommem[12409] <= 12'h06F;
rommem[12410] <= 12'h809;
rommem[12411] <= 12'hE3F;
rommem[12412] <= 12'h000;
rommem[12413] <= 12'h0A7;
rommem[12414] <= 12'h809;
rommem[12415] <= 12'hE3F;
rommem[12416] <= 12'h001;
rommem[12417] <= 12'h0E7;
rommem[12418] <= 12'h809;
rommem[12419] <= 12'hE3F;
rommem[12420] <= 12'h002;
rommem[12421] <= 12'h030;
rommem[12422] <= 12'h004;
rommem[12423] <= 12'h08C;
rommem[12424] <= 12'h000;
rommem[12425] <= 12'h100;
rommem[12426] <= 12'h025;
rommem[12427] <= 12'hFED;
rommem[12428] <= 12'h01C;
rommem[12429] <= 12'h0EF;
rommem[12430] <= 12'h086;
rommem[12431] <= 12'h038;
rommem[12432] <= 12'h015;
rommem[12433] <= 12'h0B7;
rommem[12434] <= 12'hFFF;
rommem[12435] <= 12'hE0D;
rommem[12436] <= 12'hF00;
rommem[12437] <= 12'h086;
rommem[12438] <= 12'h01D;
rommem[12439] <= 12'h015;
rommem[12440] <= 12'h0B7;
rommem[12441] <= 12'hFFF;
rommem[12442] <= 12'hE0D;
rommem[12443] <= 12'hF01;
rommem[12444] <= 12'h08D;
rommem[12445] <= 12'h132;
rommem[12446] <= 12'h08D;
rommem[12447] <= 12'h1A1;
rommem[12448] <= 12'h086;
rommem[12449] <= 12'h005;
rommem[12450] <= 12'h015;
rommem[12451] <= 12'h0B7;
rommem[12452] <= 12'hFFF;
rommem[12453] <= 12'hE60;
rommem[12454] <= 12'h000;
rommem[12455] <= 12'h0CC;
rommem[12456] <= 12'hFFF;
rommem[12457] <= 12'h0BF;
rommem[12458] <= 12'h08D;
rommem[12459] <= 12'h2A8;
rommem[12460] <= 12'h08E;
rommem[12461] <= 12'h000;
rommem[12462] <= 12'h000;
rommem[12463] <= 12'h0CC;
rommem[12464] <= 12'h000;
rommem[12465] <= 12'h000;
rommem[12466] <= 12'h017;
rommem[12467] <= 12'h000;
rommem[12468] <= 12'h8D4;
rommem[12469] <= 12'h017;
rommem[12470] <= 12'h000;
rommem[12471] <= 12'h708;
rommem[12472] <= 12'h0DC;
rommem[12473] <= 12'h124;
rommem[12474] <= 12'h08D;
rommem[12475] <= 12'h2D8;
rommem[12476] <= 12'h07E;
rommem[12477] <= 12'hFFF;
rommem[12478] <= 12'h994;
rommem[12479] <= 12'h072;
rommem[12480] <= 12'h066;
rommem[12481] <= 12'h036;
rommem[12482] <= 12'h038;
rommem[12483] <= 12'h030;
rommem[12484] <= 12'h039;
rommem[12485] <= 12'h020;
rommem[12486] <= 12'h031;
rommem[12487] <= 12'h032;
rommem[12488] <= 12'h02D;
rommem[12489] <= 12'h062;
rommem[12490] <= 12'h069;
rommem[12491] <= 12'h074;
rommem[12492] <= 12'h020;
rommem[12493] <= 12'h053;
rommem[12494] <= 12'h079;
rommem[12495] <= 12'h073;
rommem[12496] <= 12'h074;
rommem[12497] <= 12'h065;
rommem[12498] <= 12'h06D;
rommem[12499] <= 12'h020;
rommem[12500] <= 12'h053;
rommem[12501] <= 12'h074;
rommem[12502] <= 12'h061;
rommem[12503] <= 12'h072;
rommem[12504] <= 12'h074;
rommem[12505] <= 12'h069;
rommem[12506] <= 12'h06E;
rommem[12507] <= 12'h067;
rommem[12508] <= 12'h02E;
rommem[12509] <= 12'h00D;
rommem[12510] <= 12'h00A;
rommem[12511] <= 12'h000;
rommem[12512] <= 12'h015;
rommem[12513] <= 12'h07F;
rommem[12514] <= 12'hFFF;
rommem[12515] <= 12'hFFF;
rommem[12516] <= 12'hFE1;
rommem[12517] <= 12'h039;
rommem[12518] <= 12'h08E;
rommem[12519] <= 12'hFFC;
rommem[12520] <= 12'h000;
rommem[12521] <= 12'h18E;
rommem[12522] <= 12'h00C;
rommem[12523] <= 12'h000;
rommem[12524] <= 12'h0EC;
rommem[12525] <= 12'h801;
rommem[12526] <= 12'h0ED;
rommem[12527] <= 12'hA01;
rommem[12528] <= 12'h08C;
rommem[12529] <= 12'h000;
rommem[12530] <= 12'h000;
rommem[12531] <= 12'h026;
rommem[12532] <= 12'hFF7;
rommem[12533] <= 12'h039;
rommem[12534] <= 12'h086;
rommem[12535] <= 12'h050;
rommem[12536] <= 12'h015;
rommem[12537] <= 12'h0F6;
rommem[12538] <= 12'hFFF;
rommem[12539] <= 12'hFFF;
rommem[12540] <= 12'hFE0;
rommem[12541] <= 12'h0C0;
rommem[12542] <= 12'h002;
rommem[12543] <= 12'h08E;
rommem[12544] <= 12'h000;
rommem[12545] <= 12'h000;
rommem[12546] <= 12'h03A;
rommem[12547] <= 12'h0A7;
rommem[12548] <= 12'h809;
rommem[12549] <= 12'hE00;
rommem[12550] <= 12'h000;
rommem[12551] <= 12'h030;
rommem[12552] <= 12'h008;
rommem[12553] <= 12'h08C;
rommem[12554] <= 12'h000;
rommem[12555] <= 12'hFFF;
rommem[12556] <= 12'h025;
rommem[12557] <= 12'hFF5;
rommem[12558] <= 12'h0BD;
rommem[12559] <= 12'hFFF;
rommem[12560] <= 12'h0E0;
rommem[12561] <= 12'h0CB;
rommem[12562] <= 12'h002;
rommem[12563] <= 12'h086;
rommem[12564] <= 12'h04E;
rommem[12565] <= 12'h08E;
rommem[12566] <= 12'h000;
rommem[12567] <= 12'h000;
rommem[12568] <= 12'h03A;
rommem[12569] <= 12'h03A;
rommem[12570] <= 12'h0A7;
rommem[12571] <= 12'h809;
rommem[12572] <= 12'hE00;
rommem[12573] <= 12'h000;
rommem[12574] <= 12'h08C;
rommem[12575] <= 12'h000;
rommem[12576] <= 12'hFFF;
rommem[12577] <= 12'h025;
rommem[12578] <= 12'hFF6;
rommem[12579] <= 12'h0BD;
rommem[12580] <= 12'hFFF;
rommem[12581] <= 12'h0E0;
rommem[12582] <= 12'h0CB;
rommem[12583] <= 12'h008;
rommem[12584] <= 12'h0C1;
rommem[12585] <= 12'hFF0;
rommem[12586] <= 12'h025;
rommem[12587] <= 12'hFE9;
rommem[12588] <= 12'h013;
rommem[12589] <= 12'h016;
rommem[12590] <= 12'h000;
rommem[12591] <= 12'h869;
rommem[12592] <= 12'h086;
rommem[12593] <= 12'h050;
rommem[12594] <= 12'h08E;
rommem[12595] <= 12'h000;
rommem[12596] <= 12'h000;
rommem[12597] <= 12'h0A7;
rommem[12598] <= 12'h809;
rommem[12599] <= 12'hE00;
rommem[12600] <= 12'h000;
rommem[12601] <= 12'h030;
rommem[12602] <= 12'h001;
rommem[12603] <= 12'h08C;
rommem[12604] <= 12'h000;
rommem[12605] <= 12'hFFF;
rommem[12606] <= 12'h025;
rommem[12607] <= 12'hFF5;
rommem[12608] <= 12'h0C6;
rommem[12609] <= 12'h002;
rommem[12610] <= 12'h086;
rommem[12611] <= 12'h04E;
rommem[12612] <= 12'h08E;
rommem[12613] <= 12'h000;
rommem[12614] <= 12'h000;
rommem[12615] <= 12'h03A;
rommem[12616] <= 12'h03A;
rommem[12617] <= 12'h0A7;
rommem[12618] <= 12'h809;
rommem[12619] <= 12'hE00;
rommem[12620] <= 12'h000;
rommem[12621] <= 12'h08C;
rommem[12622] <= 12'h000;
rommem[12623] <= 12'hFFF;
rommem[12624] <= 12'h025;
rommem[12625] <= 12'hFC7;
rommem[12626] <= 12'h05C;
rommem[12627] <= 12'h0C1;
rommem[12628] <= 12'hFF0;
rommem[12629] <= 12'h025;
rommem[12630] <= 12'hFED;
rommem[12631] <= 12'h013;
rommem[12632] <= 12'h016;
rommem[12633] <= 12'h000;
rommem[12634] <= 12'h839;
rommem[12635] <= 12'h0CC;
rommem[12636] <= 12'h895;
rommem[12637] <= 12'h440;
rommem[12638] <= 12'h0C1;
rommem[12639] <= 12'h0FF;
rommem[12640] <= 12'h026;
rommem[12641] <= 12'h000;
rommem[12642] <= 12'h015;
rommem[12643] <= 12'h0B7;
rommem[12644] <= 12'hFFF;
rommem[12645] <= 12'hE60;
rommem[12646] <= 12'h000;
rommem[12647] <= 12'h083;
rommem[12648] <= 12'h000;
rommem[12649] <= 12'h001;
rommem[12650] <= 12'h026;
rommem[12651] <= 12'hFF2;
rommem[12652] <= 12'h039;
rommem[12653] <= 12'h058;
rommem[12654] <= 12'h049;
rommem[12655] <= 12'h058;
rommem[12656] <= 12'h049;
rommem[12657] <= 12'h058;
rommem[12658] <= 12'h049;
rommem[12659] <= 12'h058;
rommem[12660] <= 12'h049;
rommem[12661] <= 12'h058;
rommem[12662] <= 12'h049;
rommem[12663] <= 12'h039;
rommem[12664] <= 12'h034;
rommem[12665] <= 12'h076;
rommem[12666] <= 12'h08D;
rommem[12667] <= 12'h0B4;
rommem[12668] <= 12'h01F;
rommem[12669] <= 12'h001;
rommem[12670] <= 12'h18E;
rommem[12671] <= 12'hE00;
rommem[12672] <= 12'h000;
rommem[12673] <= 12'h0CE;
rommem[12674] <= 12'h000;
rommem[12675] <= 12'h32C;
rommem[12676] <= 12'h0EC;
rommem[12677] <= 12'h801;
rommem[12678] <= 12'h0ED;
rommem[12679] <= 12'hA01;
rommem[12680] <= 12'h033;
rommem[12681] <= 12'h5FF;
rommem[12682] <= 12'h283;
rommem[12683] <= 12'h000;
rommem[12684] <= 12'h000;
rommem[12685] <= 12'h026;
rommem[12686] <= 12'hFF5;
rommem[12687] <= 12'h0D6;
rommem[12688] <= 12'h110;
rommem[12689] <= 12'h086;
rommem[12690] <= 12'h038;
rommem[12691] <= 12'h03D;
rommem[12692] <= 12'h01F;
rommem[12693] <= 12'h001;
rommem[12694] <= 12'h0D6;
rommem[12695] <= 12'h111;
rommem[12696] <= 12'h03A;
rommem[12697] <= 12'h015;
rommem[12698] <= 12'h0BF;
rommem[12699] <= 12'hFFF;
rommem[12700] <= 12'hE0D;
rommem[12701] <= 12'hF22;
rommem[12702] <= 12'h035;
rommem[12703] <= 12'h0F6;
rommem[12704] <= 12'h034;
rommem[12705] <= 12'h076;
rommem[12706] <= 12'h08D;
rommem[12707] <= 12'h08C;
rommem[12708] <= 12'h01F;
rommem[12709] <= 12'h002;
rommem[12710] <= 12'h08E;
rommem[12711] <= 12'hE00;
rommem[12712] <= 12'h000;
rommem[12713] <= 12'h0CE;
rommem[12714] <= 12'h000;
rommem[12715] <= 12'h32C;
rommem[12716] <= 12'h0EC;
rommem[12717] <= 12'h801;
rommem[12718] <= 12'h0ED;
rommem[12719] <= 12'hA01;
rommem[12720] <= 12'h033;
rommem[12721] <= 12'h5FF;
rommem[12722] <= 12'h283;
rommem[12723] <= 12'h000;
rommem[12724] <= 12'h000;
rommem[12725] <= 12'h026;
rommem[12726] <= 12'hFF5;
rommem[12727] <= 12'h035;
rommem[12728] <= 12'h0F6;
rommem[12729] <= 12'h054;
rommem[12730] <= 12'h045;
rommem[12731] <= 12'h058;
rommem[12732] <= 12'h054;
rommem[12733] <= 12'h053;
rommem[12734] <= 12'h043;
rommem[12735] <= 12'h052;
rommem[12736] <= 12'h020;
rommem[12737] <= 12'hFFF;
rommem[12738] <= 12'h1CB;
rommem[12739] <= 12'hFFF;
rommem[12740] <= 12'h1CC;
rommem[12741] <= 12'hFFF;
rommem[12742] <= 12'h1CD;
rommem[12743] <= 12'hFFF;
rommem[12744] <= 12'h1CE;
rommem[12745] <= 12'hFFF;
rommem[12746] <= 12'h1CF;
rommem[12747] <= 12'h039;
rommem[12748] <= 12'h039;
rommem[12749] <= 12'h039;
rommem[12750] <= 12'h039;
rommem[12751] <= 12'h039;
rommem[12752] <= 12'h034;
rommem[12753] <= 12'h076;
rommem[12754] <= 12'h08E;
rommem[12755] <= 12'h000;
rommem[12756] <= 12'h658;
rommem[12757] <= 12'h01F;
rommem[12758] <= 12'h013;
rommem[12759] <= 12'h08D;
rommem[12760] <= 12'h057;
rommem[12761] <= 12'h01F;
rommem[12762] <= 12'h002;
rommem[12763] <= 12'h0C6;
rommem[12764] <= 12'h020;
rommem[12765] <= 12'h0E7;
rommem[12766] <= 12'hA00;
rommem[12767] <= 12'h030;
rommem[12768] <= 12'h1FF;
rommem[12769] <= 12'h026;
rommem[12770] <= 12'hFFA;
rommem[12771] <= 12'h015;
rommem[12772] <= 12'h0F6;
rommem[12773] <= 12'hFFF;
rommem[12774] <= 12'hFFF;
rommem[12775] <= 12'hFE0;
rommem[12776] <= 12'h0D1;
rommem[12777] <= 12'h100;
rommem[12778] <= 12'h020;
rommem[12779] <= 12'h00D;
rommem[12780] <= 12'h18E;
rommem[12781] <= 12'hE02;
rommem[12782] <= 12'h000;
rommem[12783] <= 12'h086;
rommem[12784] <= 12'h0CE;
rommem[12785] <= 12'h01F;
rommem[12786] <= 12'h031;
rommem[12787] <= 12'h0A7;
rommem[12788] <= 12'hA00;
rommem[12789] <= 12'h030;
rommem[12790] <= 12'h1FF;
rommem[12791] <= 12'h026;
rommem[12792] <= 12'hFFA;
rommem[12793] <= 12'h035;
rommem[12794] <= 12'h0F6;
rommem[12795] <= 12'h034;
rommem[12796] <= 12'h076;
rommem[12797] <= 12'h18E;
rommem[12798] <= 12'h000;
rommem[12799] <= 12'h32B;
rommem[12800] <= 12'h08D;
rommem[12801] <= 12'h02E;
rommem[12802] <= 12'h01F;
rommem[12803] <= 12'h001;
rommem[12804] <= 12'h01F;
rommem[12805] <= 12'h003;
rommem[12806] <= 12'h030;
rommem[12807] <= 12'h038;
rommem[12808] <= 12'h0EC;
rommem[12809] <= 12'h801;
rommem[12810] <= 12'h0ED;
rommem[12811] <= 12'hC01;
rommem[12812] <= 12'h031;
rommem[12813] <= 12'h3FF;
rommem[12814] <= 12'h026;
rommem[12815] <= 12'hFF8;
rommem[12816] <= 12'h086;
rommem[12817] <= 12'h01E;
rommem[12818] <= 12'h08D;
rommem[12819] <= 12'h002;
rommem[12820] <= 12'h035;
rommem[12821] <= 12'h0F6;
rommem[12822] <= 12'h034;
rommem[12823] <= 12'h016;
rommem[12824] <= 12'h034;
rommem[12825] <= 12'h002;
rommem[12826] <= 12'h08D;
rommem[12827] <= 12'h014;
rommem[12828] <= 12'h01F;
rommem[12829] <= 12'h001;
rommem[12830] <= 12'h035;
rommem[12831] <= 12'h002;
rommem[12832] <= 12'h0C6;
rommem[12833] <= 12'h038;
rommem[12834] <= 12'h03D;
rommem[12835] <= 12'h030;
rommem[12836] <= 12'h80B;
rommem[12837] <= 12'h086;
rommem[12838] <= 12'h020;
rommem[12839] <= 12'h0C6;
rommem[12840] <= 12'h038;
rommem[12841] <= 12'h0A7;
rommem[12842] <= 12'h800;
rommem[12843] <= 12'h05A;
rommem[12844] <= 12'h026;
rommem[12845] <= 12'hFFB;
rommem[12846] <= 12'h035;
rommem[12847] <= 12'h096;
rommem[12848] <= 12'h015;
rommem[12849] <= 12'h0B6;
rommem[12850] <= 12'hFFF;
rommem[12851] <= 12'hFFF;
rommem[12852] <= 12'hFE0;
rommem[12853] <= 12'h091;
rommem[12854] <= 12'h100;
rommem[12855] <= 12'h026;
rommem[12856] <= 12'h004;
rommem[12857] <= 12'h0CC;
rommem[12858] <= 12'hE00;
rommem[12859] <= 12'h000;
rommem[12860] <= 12'h039;
rommem[12861] <= 12'h0CC;
rommem[12862] <= 12'h007;
rommem[12863] <= 12'h800;
rommem[12864] <= 12'h039;
rommem[12865] <= 12'h034;
rommem[12866] <= 12'h016;
rommem[12867] <= 12'h00F;
rommem[12868] <= 12'h110;
rommem[12869] <= 12'h00F;
rommem[12870] <= 12'h111;
rommem[12871] <= 12'h015;
rommem[12872] <= 12'h0F6;
rommem[12873] <= 12'hFFF;
rommem[12874] <= 12'hFFF;
rommem[12875] <= 12'hFE0;
rommem[12876] <= 12'h0D1;
rommem[12877] <= 12'h100;
rommem[12878] <= 12'h026;
rommem[12879] <= 12'h006;
rommem[12880] <= 12'h04F;
rommem[12881] <= 12'h015;
rommem[12882] <= 12'h0B7;
rommem[12883] <= 12'hFFF;
rommem[12884] <= 12'hE0D;
rommem[12885] <= 12'hF22;
rommem[12886] <= 12'h035;
rommem[12887] <= 12'h096;
rommem[12888] <= 12'h034;
rommem[12889] <= 12'h016;
rommem[12890] <= 12'h015;
rommem[12891] <= 12'h0F6;
rommem[12892] <= 12'hFFF;
rommem[12893] <= 12'hFFF;
rommem[12894] <= 12'hFE0;
rommem[12895] <= 12'h0D1;
rommem[12896] <= 12'h100;
rommem[12897] <= 12'h026;
rommem[12898] <= 12'h014;
rommem[12899] <= 12'h096;
rommem[12900] <= 12'h110;
rommem[12901] <= 12'h084;
rommem[12902] <= 12'h03F;
rommem[12903] <= 12'h015;
rommem[12904] <= 12'h0F6;
rommem[12905] <= 12'hFFF;
rommem[12906] <= 12'hE0D;
rommem[12907] <= 12'hF00;
rommem[12908] <= 12'h03D;
rommem[12909] <= 12'h01F;
rommem[12910] <= 12'h001;
rommem[12911] <= 12'h0D6;
rommem[12912] <= 12'h111;
rommem[12913] <= 12'h03A;
rommem[12914] <= 12'h015;
rommem[12915] <= 12'h0BF;
rommem[12916] <= 12'hFFF;
rommem[12917] <= 12'hE0D;
rommem[12918] <= 12'hF22;
rommem[12919] <= 12'h035;
rommem[12920] <= 12'h096;
rommem[12921] <= 12'h034;
rommem[12922] <= 12'h010;
rommem[12923] <= 12'h096;
rommem[12924] <= 12'h110;
rommem[12925] <= 12'h0C6;
rommem[12926] <= 12'h038;
rommem[12927] <= 12'h03D;
rommem[12928] <= 12'h01F;
rommem[12929] <= 12'h001;
rommem[12930] <= 12'h0D6;
rommem[12931] <= 12'h111;
rommem[12932] <= 12'h03A;
rommem[12933] <= 12'h015;
rommem[12934] <= 12'h0F6;
rommem[12935] <= 12'hFFF;
rommem[12936] <= 12'hFFF;
rommem[12937] <= 12'hFE0;
rommem[12938] <= 12'h0D1;
rommem[12939] <= 12'h100;
rommem[12940] <= 12'h026;
rommem[12941] <= 12'h005;
rommem[12942] <= 12'h015;
rommem[12943] <= 12'h0BF;
rommem[12944] <= 12'hFFF;
rommem[12945] <= 12'hE0D;
rommem[12946] <= 12'hF22;
rommem[12947] <= 12'h08D;
rommem[12948] <= 12'hF9B;
rommem[12949] <= 12'h030;
rommem[12950] <= 12'h80B;
rommem[12951] <= 12'h01F;
rommem[12952] <= 12'h010;
rommem[12953] <= 12'h035;
rommem[12954] <= 12'h090;
rommem[12955] <= 12'h034;
rommem[12956] <= 12'h016;
rommem[12957] <= 12'h0C1;
rommem[12958] <= 12'h00D;
rommem[12959] <= 12'h026;
rommem[12960] <= 12'h006;
rommem[12961] <= 12'h00F;
rommem[12962] <= 12'h111;
rommem[12963] <= 12'h08D;
rommem[12964] <= 12'hFB3;
rommem[12965] <= 12'h035;
rommem[12966] <= 12'h096;
rommem[12967] <= 12'h0C1;
rommem[12968] <= 12'h091;
rommem[12969] <= 12'h026;
rommem[12970] <= 12'h00D;
rommem[12971] <= 12'h096;
rommem[12972] <= 12'h111;
rommem[12973] <= 12'h081;
rommem[12974] <= 12'h037;
rommem[12975] <= 12'h024;
rommem[12976] <= 12'h003;
rommem[12977] <= 12'h04C;
rommem[12978] <= 12'h097;
rommem[12979] <= 12'h111;
rommem[12980] <= 12'h08D;
rommem[12981] <= 12'hFA2;
rommem[12982] <= 12'h035;
rommem[12983] <= 12'h096;
rommem[12984] <= 12'h0C1;
rommem[12985] <= 12'h090;
rommem[12986] <= 12'h026;
rommem[12987] <= 12'h009;
rommem[12988] <= 12'h096;
rommem[12989] <= 12'h110;
rommem[12990] <= 12'h027;
rommem[12991] <= 12'hFF4;
rommem[12992] <= 12'h04A;
rommem[12993] <= 12'h097;
rommem[12994] <= 12'h110;
rommem[12995] <= 12'h020;
rommem[12996] <= 12'hFEF;
rommem[12997] <= 12'h0C1;
rommem[12998] <= 12'h093;
rommem[12999] <= 12'h026;
rommem[13000] <= 12'h009;
rommem[13001] <= 12'h096;
rommem[13002] <= 12'h111;
rommem[13003] <= 12'h027;
rommem[13004] <= 12'hFE7;
rommem[13005] <= 12'h04A;
rommem[13006] <= 12'h097;
rommem[13007] <= 12'h111;
rommem[13008] <= 12'h020;
rommem[13009] <= 12'hFE2;
rommem[13010] <= 12'h0C1;
rommem[13011] <= 12'h092;
rommem[13012] <= 12'h026;
rommem[13013] <= 12'h00B;
rommem[13014] <= 12'h096;
rommem[13015] <= 12'h110;
rommem[13016] <= 12'h081;
rommem[13017] <= 12'h01D;
rommem[13018] <= 12'h027;
rommem[13019] <= 12'hFD8;
rommem[13020] <= 12'h04C;
rommem[13021] <= 12'h097;
rommem[13022] <= 12'h110;
rommem[13023] <= 12'h020;
rommem[13024] <= 12'hFD3;
rommem[13025] <= 12'h0C1;
rommem[13026] <= 12'h094;
rommem[13027] <= 12'h026;
rommem[13028] <= 12'h00C;
rommem[13029] <= 12'h096;
rommem[13030] <= 12'h111;
rommem[13031] <= 12'h027;
rommem[13032] <= 12'h004;
rommem[13033] <= 12'h00F;
rommem[13034] <= 12'h111;
rommem[13035] <= 12'h020;
rommem[13036] <= 12'hFC7;
rommem[13037] <= 12'h00F;
rommem[13038] <= 12'h110;
rommem[13039] <= 12'h020;
rommem[13040] <= 12'hFC3;
rommem[13041] <= 12'h0C1;
rommem[13042] <= 12'h099;
rommem[13043] <= 12'h026;
rommem[13044] <= 12'h008;
rommem[13045] <= 12'h08D;
rommem[13046] <= 12'hF82;
rommem[13047] <= 12'h01F;
rommem[13048] <= 12'h001;
rommem[13049] <= 12'h096;
rommem[13050] <= 12'h111;
rommem[13051] <= 12'h020;
rommem[13052] <= 12'h00D;
rommem[13053] <= 12'h0C1;
rommem[13054] <= 12'h008;
rommem[13055] <= 12'h026;
rommem[13056] <= 12'h01A;
rommem[13057] <= 12'h096;
rommem[13058] <= 12'h111;
rommem[13059] <= 12'h027;
rommem[13060] <= 12'h02A;
rommem[13061] <= 12'h04A;
rommem[13062] <= 12'h097;
rommem[13063] <= 12'h111;
rommem[13064] <= 12'h08D;
rommem[13065] <= 12'hF6F;
rommem[13066] <= 12'h0E6;
rommem[13067] <= 12'h001;
rommem[13068] <= 12'h0E7;
rommem[13069] <= 12'h801;
rommem[13070] <= 12'h04C;
rommem[13071] <= 12'h081;
rommem[13072] <= 12'h037;
rommem[13073] <= 12'h025;
rommem[13074] <= 12'hFF7;
rommem[13075] <= 12'h0C6;
rommem[13076] <= 12'h020;
rommem[13077] <= 12'h030;
rommem[13078] <= 12'h1FF;
rommem[13079] <= 12'h0E7;
rommem[13080] <= 12'h804;
rommem[13081] <= 12'h035;
rommem[13082] <= 12'h09E;
rommem[13083] <= 12'h0C1;
rommem[13084] <= 12'h00A;
rommem[13085] <= 12'h027;
rommem[13086] <= 12'h00E;
rommem[13087] <= 12'h034;
rommem[13088] <= 12'h004;
rommem[13089] <= 12'h08D;
rommem[13090] <= 12'hF56;
rommem[13091] <= 12'h01F;
rommem[13092] <= 12'h001;
rommem[13093] <= 12'h035;
rommem[13094] <= 12'h004;
rommem[13095] <= 12'h0E7;
rommem[13096] <= 12'h804;
rommem[13097] <= 12'h08D;
rommem[13098] <= 12'h006;
rommem[13099] <= 12'h035;
rommem[13100] <= 12'h096;
rommem[13101] <= 12'h08D;
rommem[13102] <= 12'h011;
rommem[13103] <= 12'h035;
rommem[13104] <= 12'h096;
rommem[13105] <= 12'h034;
rommem[13106] <= 12'h016;
rommem[13107] <= 12'h096;
rommem[13108] <= 12'h111;
rommem[13109] <= 12'h04C;
rommem[13110] <= 12'h097;
rommem[13111] <= 12'h111;
rommem[13112] <= 12'h081;
rommem[13113] <= 12'h037;
rommem[13114] <= 12'h025;
rommem[13115] <= 12'h014;
rommem[13116] <= 12'h00F;
rommem[13117] <= 12'h111;
rommem[13118] <= 12'h020;
rommem[13119] <= 12'h002;
rommem[13120] <= 12'h034;
rommem[13121] <= 12'h016;
rommem[13122] <= 12'h096;
rommem[13123] <= 12'h110;
rommem[13124] <= 12'h04C;
rommem[13125] <= 12'h097;
rommem[13126] <= 12'h110;
rommem[13127] <= 12'h081;
rommem[13128] <= 12'h01D;
rommem[13129] <= 12'h025;
rommem[13130] <= 12'h005;
rommem[13131] <= 12'h04A;
rommem[13132] <= 12'h097;
rommem[13133] <= 12'h110;
rommem[13134] <= 12'h08D;
rommem[13135] <= 12'hEAB;
rommem[13136] <= 12'h08D;
rommem[13137] <= 12'hF06;
rommem[13138] <= 12'h035;
rommem[13139] <= 12'h096;
rommem[13140] <= 12'h034;
rommem[13141] <= 12'h016;
rommem[13142] <= 12'h01F;
rommem[13143] <= 12'h001;
rommem[13144] <= 12'h0E6;
rommem[13145] <= 12'h800;
rommem[13146] <= 12'h027;
rommem[13147] <= 12'h004;
rommem[13148] <= 12'h08D;
rommem[13149] <= 12'h621;
rommem[13150] <= 12'h020;
rommem[13151] <= 12'hFF8;
rommem[13152] <= 12'h035;
rommem[13153] <= 12'h096;
rommem[13154] <= 12'h034;
rommem[13155] <= 12'h006;
rommem[13156] <= 12'h08D;
rommem[13157] <= 12'hFEE;
rommem[13158] <= 12'h0C6;
rommem[13159] <= 12'h00D;
rommem[13160] <= 12'h08D;
rommem[13161] <= 12'h615;
rommem[13162] <= 12'h0C6;
rommem[13163] <= 12'h00A;
rommem[13164] <= 12'h08D;
rommem[13165] <= 12'h611;
rommem[13166] <= 12'h035;
rommem[13167] <= 12'h086;
rommem[13168] <= 12'h08D;
rommem[13169] <= 12'h002;
rommem[13170] <= 12'h020;
rommem[13171] <= 12'h00D;
rommem[13172] <= 12'h034;
rommem[13173] <= 12'h010;
rommem[13174] <= 12'h08E;
rommem[13175] <= 12'hFFF;
rommem[13176] <= 12'h388;
rommem[13177] <= 12'h08D;
rommem[13178] <= 12'h006;
rommem[13179] <= 12'h035;
rommem[13180] <= 12'h010;
rommem[13181] <= 12'h039;
rommem[13182] <= 12'h0BD;
rommem[13183] <= 12'hFFF;
rommem[13184] <= 12'h97F;
rommem[13185] <= 12'h0E6;
rommem[13186] <= 12'h800;
rommem[13187] <= 12'h0C1;
rommem[13188] <= 12'h004;
rommem[13189] <= 12'h026;
rommem[13190] <= 12'hFF7;
rommem[13191] <= 12'h039;
rommem[13192] <= 12'h00D;
rommem[13193] <= 12'h00A;
rommem[13194] <= 12'h004;
rommem[13195] <= 12'h08D;
rommem[13196] <= 12'h007;
rommem[13197] <= 12'h01E;
rommem[13198] <= 12'h001;
rommem[13199] <= 12'h08D;
rommem[13200] <= 12'h003;
rommem[13201] <= 12'h01E;
rommem[13202] <= 12'h001;
rommem[13203] <= 12'h039;
rommem[13204] <= 12'h01E;
rommem[13205] <= 12'h089;
rommem[13206] <= 12'h08D;
rommem[13207] <= 12'h005;
rommem[13208] <= 12'h01E;
rommem[13209] <= 12'h089;
rommem[13210] <= 12'h08D;
rommem[13211] <= 12'h001;
rommem[13212] <= 12'h039;
rommem[13213] <= 12'h034;
rommem[13214] <= 12'h004;
rommem[13215] <= 12'h054;
rommem[13216] <= 12'h054;
rommem[13217] <= 12'h054;
rommem[13218] <= 12'h054;
rommem[13219] <= 12'h054;
rommem[13220] <= 12'h054;
rommem[13221] <= 12'h054;
rommem[13222] <= 12'h054;
rommem[13223] <= 12'h08D;
rommem[13224] <= 12'h00C;
rommem[13225] <= 12'h035;
rommem[13226] <= 12'h004;
rommem[13227] <= 12'h034;
rommem[13228] <= 12'h004;
rommem[13229] <= 12'h054;
rommem[13230] <= 12'h054;
rommem[13231] <= 12'h054;
rommem[13232] <= 12'h054;
rommem[13233] <= 12'h08D;
rommem[13234] <= 12'h002;
rommem[13235] <= 12'h035;
rommem[13236] <= 12'h004;
rommem[13237] <= 12'h034;
rommem[13238] <= 12'h004;
rommem[13239] <= 12'h0C4;
rommem[13240] <= 12'h00F;
rommem[13241] <= 12'h0C1;
rommem[13242] <= 12'h00A;
rommem[13243] <= 12'h025;
rommem[13244] <= 12'h006;
rommem[13245] <= 12'h0CB;
rommem[13246] <= 12'h037;
rommem[13247] <= 12'h08D;
rommem[13248] <= 12'h5BE;
rommem[13249] <= 12'h035;
rommem[13250] <= 12'h084;
rommem[13251] <= 12'h0CB;
rommem[13252] <= 12'h030;
rommem[13253] <= 12'h08D;
rommem[13254] <= 12'h5B8;
rommem[13255] <= 12'h035;
rommem[13256] <= 12'h084;
rommem[13312] <= 12'h02E;
rommem[13313] <= 12'h0A9;
rommem[13314] <= 12'h02E;
rommem[13315] <= 12'h0A5;
rommem[13316] <= 12'h0A3;
rommem[13317] <= 12'h0A1;
rommem[13318] <= 12'h0A2;
rommem[13319] <= 12'h0AC;
rommem[13320] <= 12'h02E;
rommem[13321] <= 12'h0AA;
rommem[13322] <= 12'h0A8;
rommem[13323] <= 12'h0A6;
rommem[13324] <= 12'h0A4;
rommem[13325] <= 12'h009;
rommem[13326] <= 12'h060;
rommem[13327] <= 12'h02E;
rommem[13328] <= 12'h02E;
rommem[13329] <= 12'h02E;
rommem[13330] <= 12'h02E;
rommem[13331] <= 12'h02E;
rommem[13332] <= 12'h02E;
rommem[13333] <= 12'h071;
rommem[13334] <= 12'h031;
rommem[13335] <= 12'h02E;
rommem[13336] <= 12'h02E;
rommem[13337] <= 12'h02E;
rommem[13338] <= 12'h07A;
rommem[13339] <= 12'h073;
rommem[13340] <= 12'h061;
rommem[13341] <= 12'h077;
rommem[13342] <= 12'h032;
rommem[13343] <= 12'h02E;
rommem[13344] <= 12'h02E;
rommem[13345] <= 12'h063;
rommem[13346] <= 12'h078;
rommem[13347] <= 12'h064;
rommem[13348] <= 12'h065;
rommem[13349] <= 12'h034;
rommem[13350] <= 12'h033;
rommem[13351] <= 12'h02E;
rommem[13352] <= 12'h02E;
rommem[13353] <= 12'h020;
rommem[13354] <= 12'h076;
rommem[13355] <= 12'h066;
rommem[13356] <= 12'h074;
rommem[13357] <= 12'h072;
rommem[13358] <= 12'h035;
rommem[13359] <= 12'h02E;
rommem[13360] <= 12'h02E;
rommem[13361] <= 12'h06E;
rommem[13362] <= 12'h062;
rommem[13363] <= 12'h068;
rommem[13364] <= 12'h067;
rommem[13365] <= 12'h079;
rommem[13366] <= 12'h036;
rommem[13367] <= 12'h02E;
rommem[13368] <= 12'h02E;
rommem[13369] <= 12'h02E;
rommem[13370] <= 12'h06D;
rommem[13371] <= 12'h06A;
rommem[13372] <= 12'h075;
rommem[13373] <= 12'h037;
rommem[13374] <= 12'h038;
rommem[13375] <= 12'h02E;
rommem[13376] <= 12'h02E;
rommem[13377] <= 12'h02C;
rommem[13378] <= 12'h06B;
rommem[13379] <= 12'h069;
rommem[13380] <= 12'h06F;
rommem[13381] <= 12'h030;
rommem[13382] <= 12'h039;
rommem[13383] <= 12'h02E;
rommem[13384] <= 12'h02E;
rommem[13385] <= 12'h02E;
rommem[13386] <= 12'h02F;
rommem[13387] <= 12'h06C;
rommem[13388] <= 12'h03B;
rommem[13389] <= 12'h070;
rommem[13390] <= 12'h02D;
rommem[13391] <= 12'h02E;
rommem[13392] <= 12'h02E;
rommem[13393] <= 12'h02E;
rommem[13394] <= 12'h027;
rommem[13395] <= 12'h02E;
rommem[13396] <= 12'h05B;
rommem[13397] <= 12'h03D;
rommem[13398] <= 12'h02E;
rommem[13399] <= 12'h02E;
rommem[13400] <= 12'h0AD;
rommem[13401] <= 12'h02E;
rommem[13402] <= 12'h00D;
rommem[13403] <= 12'h05D;
rommem[13404] <= 12'h02E;
rommem[13405] <= 12'h05C;
rommem[13406] <= 12'h02E;
rommem[13407] <= 12'h02E;
rommem[13408] <= 12'h02E;
rommem[13409] <= 12'h02E;
rommem[13410] <= 12'h02E;
rommem[13411] <= 12'h02E;
rommem[13412] <= 12'h02E;
rommem[13413] <= 12'h02E;
rommem[13414] <= 12'h008;
rommem[13415] <= 12'h02E;
rommem[13416] <= 12'h02E;
rommem[13417] <= 12'h095;
rommem[13418] <= 12'h02E;
rommem[13419] <= 12'h093;
rommem[13420] <= 12'h094;
rommem[13421] <= 12'h02E;
rommem[13422] <= 12'h02E;
rommem[13423] <= 12'h02E;
rommem[13424] <= 12'h098;
rommem[13425] <= 12'h07F;
rommem[13426] <= 12'h092;
rommem[13427] <= 12'h02E;
rommem[13428] <= 12'h091;
rommem[13429] <= 12'h090;
rommem[13430] <= 12'h01B;
rommem[13431] <= 12'h0AF;
rommem[13432] <= 12'h0AB;
rommem[13433] <= 12'h02E;
rommem[13434] <= 12'h097;
rommem[13435] <= 12'h02E;
rommem[13436] <= 12'h02E;
rommem[13437] <= 12'h096;
rommem[13438] <= 12'h0AE;
rommem[13439] <= 12'h02E;
rommem[13440] <= 12'h02E;
rommem[13441] <= 12'h02E;
rommem[13442] <= 12'h02E;
rommem[13443] <= 12'h0A7;
rommem[13444] <= 12'h02E;
rommem[13445] <= 12'h02E;
rommem[13446] <= 12'h02E;
rommem[13447] <= 12'h02E;
rommem[13448] <= 12'h02E;
rommem[13449] <= 12'h02E;
rommem[13450] <= 12'h02E;
rommem[13451] <= 12'h02E;
rommem[13452] <= 12'h02E;
rommem[13453] <= 12'h02E;
rommem[13454] <= 12'h02E;
rommem[13455] <= 12'h02E;
rommem[13456] <= 12'h02E;
rommem[13457] <= 12'h02E;
rommem[13458] <= 12'h02E;
rommem[13459] <= 12'h02E;
rommem[13460] <= 12'h02E;
rommem[13461] <= 12'h02E;
rommem[13462] <= 12'h02E;
rommem[13463] <= 12'h02E;
rommem[13464] <= 12'h02E;
rommem[13465] <= 12'h02E;
rommem[13466] <= 12'h02E;
rommem[13467] <= 12'h02E;
rommem[13468] <= 12'h02E;
rommem[13469] <= 12'h02E;
rommem[13470] <= 12'h02E;
rommem[13471] <= 12'h02E;
rommem[13472] <= 12'h02E;
rommem[13473] <= 12'h02E;
rommem[13474] <= 12'h02E;
rommem[13475] <= 12'h02E;
rommem[13476] <= 12'h02E;
rommem[13477] <= 12'h02E;
rommem[13478] <= 12'h02E;
rommem[13479] <= 12'h02E;
rommem[13480] <= 12'h02E;
rommem[13481] <= 12'h02E;
rommem[13482] <= 12'h02E;
rommem[13483] <= 12'h02E;
rommem[13484] <= 12'h02E;
rommem[13485] <= 12'h02E;
rommem[13486] <= 12'h02E;
rommem[13487] <= 12'h02E;
rommem[13488] <= 12'h02E;
rommem[13489] <= 12'h02E;
rommem[13490] <= 12'h02E;
rommem[13491] <= 12'h02E;
rommem[13492] <= 12'h02E;
rommem[13493] <= 12'h02E;
rommem[13494] <= 12'h02E;
rommem[13495] <= 12'h02E;
rommem[13496] <= 12'h02E;
rommem[13497] <= 12'h02E;
rommem[13498] <= 12'h02E;
rommem[13499] <= 12'h02E;
rommem[13500] <= 12'h02E;
rommem[13501] <= 12'h02E;
rommem[13502] <= 12'h02E;
rommem[13503] <= 12'h02E;
rommem[13504] <= 12'h02E;
rommem[13505] <= 12'h02E;
rommem[13506] <= 12'h02E;
rommem[13507] <= 12'h02E;
rommem[13508] <= 12'h02E;
rommem[13509] <= 12'h02E;
rommem[13510] <= 12'h02E;
rommem[13511] <= 12'h02E;
rommem[13512] <= 12'h02E;
rommem[13513] <= 12'h02E;
rommem[13514] <= 12'h02E;
rommem[13515] <= 12'h02E;
rommem[13516] <= 12'h02E;
rommem[13517] <= 12'h02E;
rommem[13518] <= 12'h02E;
rommem[13519] <= 12'h02E;
rommem[13520] <= 12'h02E;
rommem[13521] <= 12'h02E;
rommem[13522] <= 12'h02E;
rommem[13523] <= 12'h02E;
rommem[13524] <= 12'h02E;
rommem[13525] <= 12'h02E;
rommem[13526] <= 12'h02E;
rommem[13527] <= 12'h02E;
rommem[13528] <= 12'h02E;
rommem[13529] <= 12'h02E;
rommem[13530] <= 12'h02E;
rommem[13531] <= 12'h02E;
rommem[13532] <= 12'h02E;
rommem[13533] <= 12'h02E;
rommem[13534] <= 12'h02E;
rommem[13535] <= 12'h02E;
rommem[13536] <= 12'h02E;
rommem[13537] <= 12'h02E;
rommem[13538] <= 12'h02E;
rommem[13539] <= 12'h02E;
rommem[13540] <= 12'h02E;
rommem[13541] <= 12'h02E;
rommem[13542] <= 12'h02E;
rommem[13543] <= 12'h02E;
rommem[13544] <= 12'h02E;
rommem[13545] <= 12'h02E;
rommem[13546] <= 12'h02E;
rommem[13547] <= 12'h02E;
rommem[13548] <= 12'h02E;
rommem[13549] <= 12'h02E;
rommem[13550] <= 12'h02E;
rommem[13551] <= 12'h02E;
rommem[13552] <= 12'h02E;
rommem[13553] <= 12'h02E;
rommem[13554] <= 12'h02E;
rommem[13555] <= 12'h02E;
rommem[13556] <= 12'h02E;
rommem[13557] <= 12'h02E;
rommem[13558] <= 12'h02E;
rommem[13559] <= 12'h02E;
rommem[13560] <= 12'h02E;
rommem[13561] <= 12'h02E;
rommem[13562] <= 12'h0FA;
rommem[13563] <= 12'h02E;
rommem[13564] <= 12'h02E;
rommem[13565] <= 12'h02E;
rommem[13566] <= 12'h02E;
rommem[13567] <= 12'h02E;
rommem[13568] <= 12'h02E;
rommem[13569] <= 12'h02E;
rommem[13570] <= 12'h02E;
rommem[13571] <= 12'h02E;
rommem[13572] <= 12'h02E;
rommem[13573] <= 12'h02E;
rommem[13574] <= 12'h02E;
rommem[13575] <= 12'h02E;
rommem[13576] <= 12'h02E;
rommem[13577] <= 12'h02E;
rommem[13578] <= 12'h02E;
rommem[13579] <= 12'h02E;
rommem[13580] <= 12'h02E;
rommem[13581] <= 12'h009;
rommem[13582] <= 12'h07E;
rommem[13583] <= 12'h02E;
rommem[13584] <= 12'h02E;
rommem[13585] <= 12'h02E;
rommem[13586] <= 12'h02E;
rommem[13587] <= 12'h02E;
rommem[13588] <= 12'h02E;
rommem[13589] <= 12'h051;
rommem[13590] <= 12'h021;
rommem[13591] <= 12'h02E;
rommem[13592] <= 12'h02E;
rommem[13593] <= 12'h02E;
rommem[13594] <= 12'h05A;
rommem[13595] <= 12'h053;
rommem[13596] <= 12'h041;
rommem[13597] <= 12'h057;
rommem[13598] <= 12'h040;
rommem[13599] <= 12'h02E;
rommem[13600] <= 12'h02E;
rommem[13601] <= 12'h043;
rommem[13602] <= 12'h058;
rommem[13603] <= 12'h044;
rommem[13604] <= 12'h045;
rommem[13605] <= 12'h024;
rommem[13606] <= 12'h023;
rommem[13607] <= 12'h02E;
rommem[13608] <= 12'h02E;
rommem[13609] <= 12'h020;
rommem[13610] <= 12'h056;
rommem[13611] <= 12'h046;
rommem[13612] <= 12'h054;
rommem[13613] <= 12'h052;
rommem[13614] <= 12'h025;
rommem[13615] <= 12'h02E;
rommem[13616] <= 12'h02E;
rommem[13617] <= 12'h04E;
rommem[13618] <= 12'h042;
rommem[13619] <= 12'h048;
rommem[13620] <= 12'h047;
rommem[13621] <= 12'h059;
rommem[13622] <= 12'h05E;
rommem[13623] <= 12'h02E;
rommem[13624] <= 12'h02E;
rommem[13625] <= 12'h02E;
rommem[13626] <= 12'h04D;
rommem[13627] <= 12'h04A;
rommem[13628] <= 12'h055;
rommem[13629] <= 12'h026;
rommem[13630] <= 12'h02A;
rommem[13631] <= 12'h02E;
rommem[13632] <= 12'h02E;
rommem[13633] <= 12'h03C;
rommem[13634] <= 12'h04B;
rommem[13635] <= 12'h049;
rommem[13636] <= 12'h04F;
rommem[13637] <= 12'h029;
rommem[13638] <= 12'h028;
rommem[13639] <= 12'h02E;
rommem[13640] <= 12'h02E;
rommem[13641] <= 12'h03E;
rommem[13642] <= 12'h03F;
rommem[13643] <= 12'h04C;
rommem[13644] <= 12'h03A;
rommem[13645] <= 12'h050;
rommem[13646] <= 12'h05F;
rommem[13647] <= 12'h02E;
rommem[13648] <= 12'h02E;
rommem[13649] <= 12'h02E;
rommem[13650] <= 12'h022;
rommem[13651] <= 12'h02E;
rommem[13652] <= 12'h07B;
rommem[13653] <= 12'h02B;
rommem[13654] <= 12'h02E;
rommem[13655] <= 12'h02E;
rommem[13656] <= 12'h02E;
rommem[13657] <= 12'h02E;
rommem[13658] <= 12'h00D;
rommem[13659] <= 12'h07D;
rommem[13660] <= 12'h02E;
rommem[13661] <= 12'h07C;
rommem[13662] <= 12'h02E;
rommem[13663] <= 12'h02E;
rommem[13664] <= 12'h02E;
rommem[13665] <= 12'h02E;
rommem[13666] <= 12'h02E;
rommem[13667] <= 12'h02E;
rommem[13668] <= 12'h02E;
rommem[13669] <= 12'h02E;
rommem[13670] <= 12'h008;
rommem[13671] <= 12'h02E;
rommem[13672] <= 12'h02E;
rommem[13673] <= 12'h02E;
rommem[13674] <= 12'h02E;
rommem[13675] <= 12'h02E;
rommem[13676] <= 12'h02E;
rommem[13677] <= 12'h02E;
rommem[13678] <= 12'h02E;
rommem[13679] <= 12'h02E;
rommem[13680] <= 12'h02E;
rommem[13681] <= 12'h07F;
rommem[13682] <= 12'h02E;
rommem[13683] <= 12'h02E;
rommem[13684] <= 12'h02E;
rommem[13685] <= 12'h02E;
rommem[13686] <= 12'h01B;
rommem[13687] <= 12'h02E;
rommem[13688] <= 12'h02E;
rommem[13689] <= 12'h02E;
rommem[13690] <= 12'h02E;
rommem[13691] <= 12'h02E;
rommem[13692] <= 12'h02E;
rommem[13693] <= 12'h02E;
rommem[13694] <= 12'h02E;
rommem[13695] <= 12'h02E;
rommem[13696] <= 12'h02E;
rommem[13697] <= 12'h02E;
rommem[13698] <= 12'h02E;
rommem[13699] <= 12'h02E;
rommem[13700] <= 12'h02E;
rommem[13701] <= 12'h02E;
rommem[13702] <= 12'h02E;
rommem[13703] <= 12'h02E;
rommem[13704] <= 12'h02E;
rommem[13705] <= 12'h02E;
rommem[13706] <= 12'h02E;
rommem[13707] <= 12'h02E;
rommem[13708] <= 12'h02E;
rommem[13709] <= 12'h02E;
rommem[13710] <= 12'h02E;
rommem[13711] <= 12'h02E;
rommem[13712] <= 12'h02E;
rommem[13713] <= 12'h02E;
rommem[13714] <= 12'h02E;
rommem[13715] <= 12'h02E;
rommem[13716] <= 12'h02E;
rommem[13717] <= 12'h02E;
rommem[13718] <= 12'h02E;
rommem[13719] <= 12'h02E;
rommem[13720] <= 12'h02E;
rommem[13721] <= 12'h02E;
rommem[13722] <= 12'h02E;
rommem[13723] <= 12'h02E;
rommem[13724] <= 12'h02E;
rommem[13725] <= 12'h02E;
rommem[13726] <= 12'h02E;
rommem[13727] <= 12'h02E;
rommem[13728] <= 12'h02E;
rommem[13729] <= 12'h02E;
rommem[13730] <= 12'h02E;
rommem[13731] <= 12'h02E;
rommem[13732] <= 12'h02E;
rommem[13733] <= 12'h02E;
rommem[13734] <= 12'h02E;
rommem[13735] <= 12'h02E;
rommem[13736] <= 12'h02E;
rommem[13737] <= 12'h02E;
rommem[13738] <= 12'h02E;
rommem[13739] <= 12'h02E;
rommem[13740] <= 12'h02E;
rommem[13741] <= 12'h02E;
rommem[13742] <= 12'h02E;
rommem[13743] <= 12'h02E;
rommem[13744] <= 12'h02E;
rommem[13745] <= 12'h02E;
rommem[13746] <= 12'h02E;
rommem[13747] <= 12'h02E;
rommem[13748] <= 12'h02E;
rommem[13749] <= 12'h02E;
rommem[13750] <= 12'h02E;
rommem[13751] <= 12'h02E;
rommem[13752] <= 12'h02E;
rommem[13753] <= 12'h02E;
rommem[13754] <= 12'h02E;
rommem[13755] <= 12'h02E;
rommem[13756] <= 12'h02E;
rommem[13757] <= 12'h02E;
rommem[13758] <= 12'h02E;
rommem[13759] <= 12'h02E;
rommem[13760] <= 12'h02E;
rommem[13761] <= 12'h02E;
rommem[13762] <= 12'h02E;
rommem[13763] <= 12'h02E;
rommem[13764] <= 12'h02E;
rommem[13765] <= 12'h02E;
rommem[13766] <= 12'h02E;
rommem[13767] <= 12'h02E;
rommem[13768] <= 12'h02E;
rommem[13769] <= 12'h02E;
rommem[13770] <= 12'h02E;
rommem[13771] <= 12'h02E;
rommem[13772] <= 12'h02E;
rommem[13773] <= 12'h02E;
rommem[13774] <= 12'h02E;
rommem[13775] <= 12'h02E;
rommem[13776] <= 12'h02E;
rommem[13777] <= 12'h02E;
rommem[13778] <= 12'h02E;
rommem[13779] <= 12'h02E;
rommem[13780] <= 12'h02E;
rommem[13781] <= 12'h02E;
rommem[13782] <= 12'h02E;
rommem[13783] <= 12'h02E;
rommem[13784] <= 12'h02E;
rommem[13785] <= 12'h02E;
rommem[13786] <= 12'h02E;
rommem[13787] <= 12'h02E;
rommem[13788] <= 12'h02E;
rommem[13789] <= 12'h02E;
rommem[13790] <= 12'h02E;
rommem[13791] <= 12'h02E;
rommem[13792] <= 12'h02E;
rommem[13793] <= 12'h02E;
rommem[13794] <= 12'h02E;
rommem[13795] <= 12'h02E;
rommem[13796] <= 12'h02E;
rommem[13797] <= 12'h02E;
rommem[13798] <= 12'h02E;
rommem[13799] <= 12'h02E;
rommem[13800] <= 12'h02E;
rommem[13801] <= 12'h02E;
rommem[13802] <= 12'h02E;
rommem[13803] <= 12'h02E;
rommem[13804] <= 12'h02E;
rommem[13805] <= 12'h02E;
rommem[13806] <= 12'h02E;
rommem[13807] <= 12'h02E;
rommem[13808] <= 12'h02E;
rommem[13809] <= 12'h02E;
rommem[13810] <= 12'h02E;
rommem[13811] <= 12'h02E;
rommem[13812] <= 12'h02E;
rommem[13813] <= 12'h02E;
rommem[13814] <= 12'h02E;
rommem[13815] <= 12'h02E;
rommem[13816] <= 12'h02E;
rommem[13817] <= 12'h02E;
rommem[13818] <= 12'h02E;
rommem[13819] <= 12'h02E;
rommem[13820] <= 12'h02E;
rommem[13821] <= 12'h02E;
rommem[13822] <= 12'h02E;
rommem[13823] <= 12'h02E;
rommem[13824] <= 12'h02E;
rommem[13825] <= 12'h02E;
rommem[13826] <= 12'h02E;
rommem[13827] <= 12'h02E;
rommem[13828] <= 12'h02E;
rommem[13829] <= 12'h02E;
rommem[13830] <= 12'h02E;
rommem[13831] <= 12'h02E;
rommem[13832] <= 12'h02E;
rommem[13833] <= 12'h02E;
rommem[13834] <= 12'h02E;
rommem[13835] <= 12'h02E;
rommem[13836] <= 12'h02E;
rommem[13837] <= 12'h009;
rommem[13838] <= 12'h07E;
rommem[13839] <= 12'h02E;
rommem[13840] <= 12'h02E;
rommem[13841] <= 12'h02E;
rommem[13842] <= 12'h02E;
rommem[13843] <= 12'h02E;
rommem[13844] <= 12'h02E;
rommem[13845] <= 12'h011;
rommem[13846] <= 12'h021;
rommem[13847] <= 12'h02E;
rommem[13848] <= 12'h02E;
rommem[13849] <= 12'h02E;
rommem[13850] <= 12'h01A;
rommem[13851] <= 12'h013;
rommem[13852] <= 12'h001;
rommem[13853] <= 12'h017;
rommem[13854] <= 12'h040;
rommem[13855] <= 12'h02E;
rommem[13856] <= 12'h02E;
rommem[13857] <= 12'h003;
rommem[13858] <= 12'h018;
rommem[13859] <= 12'h004;
rommem[13860] <= 12'h005;
rommem[13861] <= 12'h024;
rommem[13862] <= 12'h023;
rommem[13863] <= 12'h02E;
rommem[13864] <= 12'h02E;
rommem[13865] <= 12'h020;
rommem[13866] <= 12'h016;
rommem[13867] <= 12'h006;
rommem[13868] <= 12'h014;
rommem[13869] <= 12'h012;
rommem[13870] <= 12'h025;
rommem[13871] <= 12'h02E;
rommem[13872] <= 12'h02E;
rommem[13873] <= 12'h00E;
rommem[13874] <= 12'h002;
rommem[13875] <= 12'h008;
rommem[13876] <= 12'h007;
rommem[13877] <= 12'h019;
rommem[13878] <= 12'h05E;
rommem[13879] <= 12'h02E;
rommem[13880] <= 12'h02E;
rommem[13881] <= 12'h02E;
rommem[13882] <= 12'h00D;
rommem[13883] <= 12'h00A;
rommem[13884] <= 12'h015;
rommem[13885] <= 12'h026;
rommem[13886] <= 12'h02A;
rommem[13887] <= 12'h02E;
rommem[13888] <= 12'h02E;
rommem[13889] <= 12'h03C;
rommem[13890] <= 12'h00B;
rommem[13891] <= 12'h009;
rommem[13892] <= 12'h00F;
rommem[13893] <= 12'h029;
rommem[13894] <= 12'h028;
rommem[13895] <= 12'h02E;
rommem[13896] <= 12'h02E;
rommem[13897] <= 12'h03E;
rommem[13898] <= 12'h03F;
rommem[13899] <= 12'h00C;
rommem[13900] <= 12'h03A;
rommem[13901] <= 12'h010;
rommem[13902] <= 12'h05F;
rommem[13903] <= 12'h02E;
rommem[13904] <= 12'h02E;
rommem[13905] <= 12'h02E;
rommem[13906] <= 12'h022;
rommem[13907] <= 12'h02E;
rommem[13908] <= 12'h07B;
rommem[13909] <= 12'h02B;
rommem[13910] <= 12'h02E;
rommem[13911] <= 12'h02E;
rommem[13912] <= 12'h02E;
rommem[13913] <= 12'h02E;
rommem[13914] <= 12'h00D;
rommem[13915] <= 12'h07D;
rommem[13916] <= 12'h02E;
rommem[13917] <= 12'h07C;
rommem[13918] <= 12'h02E;
rommem[13919] <= 12'h02E;
rommem[13920] <= 12'h02E;
rommem[13921] <= 12'h02E;
rommem[13922] <= 12'h02E;
rommem[13923] <= 12'h02E;
rommem[13924] <= 12'h02E;
rommem[13925] <= 12'h02E;
rommem[13926] <= 12'h008;
rommem[13927] <= 12'h02E;
rommem[13928] <= 12'h02E;
rommem[13929] <= 12'h02E;
rommem[13930] <= 12'h02E;
rommem[13931] <= 12'h02E;
rommem[13932] <= 12'h02E;
rommem[13933] <= 12'h02E;
rommem[13934] <= 12'h02E;
rommem[13935] <= 12'h02E;
rommem[13936] <= 12'h02E;
rommem[13937] <= 12'h07F;
rommem[13938] <= 12'h02E;
rommem[13939] <= 12'h02E;
rommem[13940] <= 12'h02E;
rommem[13941] <= 12'h02E;
rommem[13942] <= 12'h01B;
rommem[13943] <= 12'h02E;
rommem[13944] <= 12'h02E;
rommem[13945] <= 12'h02E;
rommem[13946] <= 12'h02E;
rommem[13947] <= 12'h02E;
rommem[13948] <= 12'h02E;
rommem[13949] <= 12'h02E;
rommem[13950] <= 12'h02E;
rommem[13951] <= 12'h02E;
rommem[13952] <= 12'h02E;
rommem[13953] <= 12'h02E;
rommem[13954] <= 12'h02E;
rommem[13955] <= 12'h02E;
rommem[13956] <= 12'h0A3;
rommem[13957] <= 12'h0A1;
rommem[13958] <= 12'h0A2;
rommem[13959] <= 12'h02E;
rommem[13960] <= 12'h02E;
rommem[13961] <= 12'h02E;
rommem[13962] <= 12'h02E;
rommem[13963] <= 12'h02E;
rommem[13964] <= 12'h02E;
rommem[13965] <= 12'h02E;
rommem[13966] <= 12'h02E;
rommem[13967] <= 12'h02E;
rommem[13968] <= 12'h02E;
rommem[13969] <= 12'h02E;
rommem[13970] <= 12'h02E;
rommem[13971] <= 12'h02E;
rommem[13972] <= 12'h02E;
rommem[13973] <= 12'h02E;
rommem[13974] <= 12'h02E;
rommem[13975] <= 12'h02E;
rommem[13976] <= 12'h02E;
rommem[13977] <= 12'h02E;
rommem[13978] <= 12'h02E;
rommem[13979] <= 12'h02E;
rommem[13980] <= 12'h02E;
rommem[13981] <= 12'h02E;
rommem[13982] <= 12'h02E;
rommem[13983] <= 12'h02E;
rommem[13984] <= 12'h02E;
rommem[13985] <= 12'h02E;
rommem[13986] <= 12'h02E;
rommem[13987] <= 12'h02E;
rommem[13988] <= 12'h02E;
rommem[13989] <= 12'h02E;
rommem[13990] <= 12'h02E;
rommem[13991] <= 12'h02E;
rommem[13992] <= 12'h02E;
rommem[13993] <= 12'h02E;
rommem[13994] <= 12'h02E;
rommem[13995] <= 12'h02E;
rommem[13996] <= 12'h02E;
rommem[13997] <= 12'h02E;
rommem[13998] <= 12'h02E;
rommem[13999] <= 12'h02E;
rommem[14000] <= 12'h02E;
rommem[14001] <= 12'h02E;
rommem[14002] <= 12'h02E;
rommem[14003] <= 12'h02E;
rommem[14004] <= 12'h02E;
rommem[14005] <= 12'h02E;
rommem[14006] <= 12'h02E;
rommem[14007] <= 12'h02E;
rommem[14008] <= 12'h02E;
rommem[14009] <= 12'h02E;
rommem[14010] <= 12'h02E;
rommem[14011] <= 12'h02E;
rommem[14012] <= 12'h02E;
rommem[14013] <= 12'h02E;
rommem[14014] <= 12'h02E;
rommem[14015] <= 12'h02E;
rommem[14016] <= 12'h02E;
rommem[14017] <= 12'h02E;
rommem[14018] <= 12'h02E;
rommem[14019] <= 12'h02E;
rommem[14020] <= 12'h02E;
rommem[14021] <= 12'h02E;
rommem[14022] <= 12'h02E;
rommem[14023] <= 12'h02E;
rommem[14024] <= 12'h02E;
rommem[14025] <= 12'h02E;
rommem[14026] <= 12'h02E;
rommem[14027] <= 12'h02E;
rommem[14028] <= 12'h02E;
rommem[14029] <= 12'h02E;
rommem[14030] <= 12'h02E;
rommem[14031] <= 12'h02E;
rommem[14032] <= 12'h02E;
rommem[14033] <= 12'h02E;
rommem[14034] <= 12'h02E;
rommem[14035] <= 12'h02E;
rommem[14036] <= 12'h02E;
rommem[14037] <= 12'h02E;
rommem[14038] <= 12'h02E;
rommem[14039] <= 12'h02E;
rommem[14040] <= 12'h02E;
rommem[14041] <= 12'h02E;
rommem[14042] <= 12'h02E;
rommem[14043] <= 12'h02E;
rommem[14044] <= 12'h02E;
rommem[14045] <= 12'h02E;
rommem[14046] <= 12'h02E;
rommem[14047] <= 12'h02E;
rommem[14048] <= 12'h02E;
rommem[14049] <= 12'h02E;
rommem[14050] <= 12'h02E;
rommem[14051] <= 12'h02E;
rommem[14052] <= 12'h02E;
rommem[14053] <= 12'h02E;
rommem[14054] <= 12'h02E;
rommem[14055] <= 12'h02E;
rommem[14056] <= 12'h02E;
rommem[14057] <= 12'h095;
rommem[14058] <= 12'h02E;
rommem[14059] <= 12'h093;
rommem[14060] <= 12'h094;
rommem[14061] <= 12'h02E;
rommem[14062] <= 12'h02E;
rommem[14063] <= 12'h02E;
rommem[14064] <= 12'h098;
rommem[14065] <= 12'h099;
rommem[14066] <= 12'h092;
rommem[14067] <= 12'h02E;
rommem[14068] <= 12'h091;
rommem[14069] <= 12'h090;
rommem[14070] <= 12'h02E;
rommem[14071] <= 12'h02E;
rommem[14072] <= 12'h02E;
rommem[14073] <= 12'h02E;
rommem[14074] <= 12'h097;
rommem[14075] <= 12'h02E;
rommem[14076] <= 12'h02E;
rommem[14077] <= 12'h096;
rommem[14078] <= 12'h02E;
rommem[14079] <= 12'h02E;
rommem[14080] <= 12'h034;
rommem[14081] <= 12'h010;
rommem[14082] <= 12'h08E;
rommem[14083] <= 12'h000;
rommem[14084] <= 12'h064;
rommem[14085] <= 12'h08D;
rommem[14086] <= 12'h05A;
rommem[14087] <= 12'h05D;
rommem[14088] <= 12'h02B;
rommem[14089] <= 12'h00B;
rommem[14090] <= 12'h08D;
rommem[14091] <= 12'h02D;
rommem[14092] <= 12'h030;
rommem[14093] <= 12'h1FF;
rommem[14094] <= 12'h026;
rommem[14095] <= 12'hFF5;
rommem[14096] <= 12'h0CC;
rommem[14097] <= 12'hFFF;
rommem[14098] <= 12'hFFF;
rommem[14099] <= 12'h035;
rommem[14100] <= 12'h090;
rommem[14101] <= 12'h08D;
rommem[14102] <= 12'h066;
rommem[14103] <= 12'h035;
rommem[14104] <= 12'h090;
rommem[14105] <= 12'h015;
rommem[14106] <= 12'h0F7;
rommem[14107] <= 12'hFFF;
rommem[14108] <= 12'hE30;
rommem[14109] <= 12'h400;
rommem[14110] <= 12'h039;
rommem[14111] <= 12'h034;
rommem[14112] <= 12'h010;
rommem[14113] <= 12'h08E;
rommem[14114] <= 12'h000;
rommem[14115] <= 12'h064;
rommem[14116] <= 12'h08D;
rommem[14117] <= 12'h03B;
rommem[14118] <= 12'h0C4;
rommem[14119] <= 12'h040;
rommem[14120] <= 12'h026;
rommem[14121] <= 12'h00B;
rommem[14122] <= 12'h08D;
rommem[14123] <= 12'h00D;
rommem[14124] <= 12'h030;
rommem[14125] <= 12'h1FF;
rommem[14126] <= 12'h026;
rommem[14127] <= 12'hFF4;
rommem[14128] <= 12'h0CC;
rommem[14129] <= 12'hFFF;
rommem[14130] <= 12'hFFF;
rommem[14131] <= 12'h035;
rommem[14132] <= 12'h090;
rommem[14133] <= 12'h04F;
rommem[14134] <= 12'h05F;
rommem[14135] <= 12'h035;
rommem[14136] <= 12'h090;
rommem[14137] <= 12'h034;
rommem[14138] <= 12'h006;
rommem[14139] <= 12'h015;
rommem[14140] <= 12'h0B6;
rommem[14141] <= 12'hFFF;
rommem[14142] <= 12'hFFF;
rommem[14143] <= 12'hFE7;
rommem[14144] <= 12'h01F;
rommem[14145] <= 12'h089;
rommem[14146] <= 12'h015;
rommem[14147] <= 12'h0F0;
rommem[14148] <= 12'hFFF;
rommem[14149] <= 12'hFFF;
rommem[14150] <= 12'hFE7;
rommem[14151] <= 12'h0C1;
rommem[14152] <= 12'hFFA;
rommem[14153] <= 12'h022;
rommem[14154] <= 12'hFF5;
rommem[14155] <= 12'h035;
rommem[14156] <= 12'h086;
rommem[14157] <= 12'h034;
rommem[14158] <= 12'h006;
rommem[14159] <= 12'h015;
rommem[14160] <= 12'h0B6;
rommem[14161] <= 12'hFFF;
rommem[14162] <= 12'hFFF;
rommem[14163] <= 12'hFE7;
rommem[14164] <= 12'h01F;
rommem[14165] <= 12'h089;
rommem[14166] <= 12'h015;
rommem[14167] <= 12'h0F0;
rommem[14168] <= 12'hFFF;
rommem[14169] <= 12'hFFF;
rommem[14170] <= 12'hFE7;
rommem[14171] <= 12'h0C1;
rommem[14172] <= 12'hF00;
rommem[14173] <= 12'h022;
rommem[14174] <= 12'hFF5;
rommem[14175] <= 12'h035;
rommem[14176] <= 12'h086;
rommem[14177] <= 12'h015;
rommem[14178] <= 12'h0F6;
rommem[14179] <= 12'hFFF;
rommem[14180] <= 12'hE30;
rommem[14181] <= 12'h401;
rommem[14182] <= 12'h0C5;
rommem[14183] <= 12'h080;
rommem[14184] <= 12'h026;
rommem[14185] <= 12'h00E;
rommem[14186] <= 12'h0C5;
rommem[14187] <= 12'h001;
rommem[14188] <= 12'h026;
rommem[14189] <= 12'h002;
rommem[14190] <= 12'h04F;
rommem[14191] <= 12'h039;
rommem[14192] <= 12'h0C6;
rommem[14193] <= 12'h0FE;
rommem[14194] <= 12'h08D;
rommem[14195] <= 12'hFA5;
rommem[14196] <= 12'h08D;
rommem[14197] <= 12'hFA9;
rommem[14198] <= 12'h020;
rommem[14199] <= 12'hFE9;
rommem[14200] <= 12'h0CA;
rommem[14201] <= 12'hF00;
rommem[14202] <= 12'h086;
rommem[14203] <= 12'hFFF;
rommem[14204] <= 12'h039;
rommem[14205] <= 12'h04F;
rommem[14206] <= 12'h015;
rommem[14207] <= 12'h0F6;
rommem[14208] <= 12'hFFF;
rommem[14209] <= 12'hE30;
rommem[14210] <= 12'h400;
rommem[14211] <= 12'h015;
rommem[14212] <= 12'h07F;
rommem[14213] <= 12'hFFF;
rommem[14214] <= 12'hE30;
rommem[14215] <= 12'h401;
rommem[14216] <= 12'h039;
rommem[14217] <= 12'h034;
rommem[14218] <= 12'h004;
rommem[14219] <= 12'h0C6;
rommem[14220] <= 12'h0ED;
rommem[14221] <= 12'h08D;
rommem[14222] <= 12'hF8A;
rommem[14223] <= 12'h08D;
rommem[14224] <= 12'hF8E;
rommem[14225] <= 12'h08D;
rommem[14226] <= 12'hF6D;
rommem[14227] <= 12'h035;
rommem[14228] <= 12'h004;
rommem[14229] <= 12'h08D;
rommem[14230] <= 12'hF82;
rommem[14231] <= 12'h08D;
rommem[14232] <= 12'hF86;
rommem[14233] <= 12'h08D;
rommem[14234] <= 12'hF65;
rommem[14235] <= 12'h039;
rommem[14236] <= 12'h0C6;
rommem[14237] <= 12'h0F2;
rommem[14238] <= 12'h08D;
rommem[14239] <= 12'hF79;
rommem[14240] <= 12'h08D;
rommem[14241] <= 12'hF7D;
rommem[14242] <= 12'h08D;
rommem[14243] <= 12'hF5C;
rommem[14244] <= 12'h0C5;
rommem[14245] <= 12'h080;
rommem[14246] <= 12'h026;
rommem[14247] <= 12'h014;
rommem[14248] <= 12'h0C1;
rommem[14249] <= 12'h0AB;
rommem[14250] <= 12'h026;
rommem[14251] <= 12'h010;
rommem[14252] <= 12'h08D;
rommem[14253] <= 12'hF52;
rommem[14254] <= 12'h0C5;
rommem[14255] <= 12'h080;
rommem[14256] <= 12'h026;
rommem[14257] <= 12'h00A;
rommem[14258] <= 12'h0C1;
rommem[14259] <= 12'h083;
rommem[14260] <= 12'h026;
rommem[14261] <= 12'h006;
rommem[14262] <= 12'h0CC;
rommem[14263] <= 12'h00A;
rommem[14264] <= 12'hB83;
rommem[14265] <= 12'h0DD;
rommem[14266] <= 12'h124;
rommem[14267] <= 12'h039;
rommem[14268] <= 12'h04F;
rommem[14269] <= 12'h05F;
rommem[14270] <= 12'h020;
rommem[14271] <= 12'hFF9;
rommem[14272] <= 12'h034;
rommem[14273] <= 12'h026;
rommem[14274] <= 12'h18E;
rommem[14275] <= 12'h000;
rommem[14276] <= 12'h005;
rommem[14277] <= 12'h08D;
rommem[14278] <= 12'hF72;
rommem[14279] <= 12'h015;
rommem[14280] <= 12'h07F;
rommem[14281] <= 12'hFFF;
rommem[14282] <= 12'hE30;
rommem[14283] <= 12'h401;
rommem[14284] <= 12'h0C6;
rommem[14285] <= 12'hFFF;
rommem[14286] <= 12'h015;
rommem[14287] <= 12'h0F7;
rommem[14288] <= 12'hFFF;
rommem[14289] <= 12'hE30;
rommem[14290] <= 12'h401;
rommem[14291] <= 12'h08D;
rommem[14292] <= 12'hF44;
rommem[14293] <= 12'h08D;
rommem[14294] <= 12'hF48;
rommem[14295] <= 12'h08D;
rommem[14296] <= 12'hF27;
rommem[14297] <= 12'h0C1;
rommem[14298] <= 12'h0FA;
rommem[14299] <= 12'h026;
rommem[14300] <= 12'h021;
rommem[14301] <= 12'h08D;
rommem[14302] <= 12'hF21;
rommem[14303] <= 12'h0C1;
rommem[14304] <= 12'h0FC;
rommem[14305] <= 12'h027;
rommem[14306] <= 12'h01B;
rommem[14307] <= 12'h0C1;
rommem[14308] <= 12'h0AA;
rommem[14309] <= 12'h026;
rommem[14310] <= 12'h017;
rommem[14311] <= 12'h0C6;
rommem[14312] <= 12'h0F0;
rommem[14313] <= 12'h015;
rommem[14314] <= 12'h0F7;
rommem[14315] <= 12'hFFF;
rommem[14316] <= 12'hE60;
rommem[14317] <= 12'h000;
rommem[14318] <= 12'h08D;
rommem[14319] <= 12'hF29;
rommem[14320] <= 12'h08D;
rommem[14321] <= 12'hF2D;
rommem[14322] <= 12'h05D;
rommem[14323] <= 12'h02B;
rommem[14324] <= 12'h009;
rommem[14325] <= 12'h08D;
rommem[14326] <= 12'hF09;
rommem[14327] <= 12'h04D;
rommem[14328] <= 12'h02B;
rommem[14329] <= 12'h004;
rommem[14330] <= 12'h0C1;
rommem[14331] <= 12'h0FA;
rommem[14332] <= 12'h027;
rommem[14333] <= 12'h00C;
rommem[14334] <= 12'h031;
rommem[14335] <= 12'h3FF;
rommem[14336] <= 12'h026;
rommem[14337] <= 12'hFC3;
rommem[14338] <= 12'h0CC;
rommem[14339] <= 12'hFFF;
rommem[14340] <= 12'h82A;
rommem[14341] <= 12'h017;
rommem[14342] <= 12'hFFF;
rommem[14343] <= 12'hB5A;
rommem[14344] <= 12'h020;
rommem[14345] <= 12'h014;
rommem[14346] <= 12'h0C6;
rommem[14347] <= 12'h002;
rommem[14348] <= 12'h08D;
rommem[14349] <= 12'hF0B;
rommem[14350] <= 12'h08D;
rommem[14351] <= 12'hF0F;
rommem[14352] <= 12'h05D;
rommem[14353] <= 12'h02B;
rommem[14354] <= 12'hFEB;
rommem[14355] <= 12'h08D;
rommem[14356] <= 12'hEEB;
rommem[14357] <= 12'h04D;
rommem[14358] <= 12'h02B;
rommem[14359] <= 12'hFE6;
rommem[14360] <= 12'h0C1;
rommem[14361] <= 12'h0FA;
rommem[14362] <= 12'h026;
rommem[14363] <= 12'hFE2;
rommem[14364] <= 12'h08D;
rommem[14365] <= 12'hF7E;
rommem[14366] <= 12'h0C6;
rommem[14367] <= 12'h007;
rommem[14368] <= 12'h08D;
rommem[14369] <= 12'hF67;
rommem[14370] <= 12'h08D;
rommem[14371] <= 12'hF29;
rommem[14372] <= 12'h0C6;
rommem[14373] <= 12'h000;
rommem[14374] <= 12'h08D;
rommem[14375] <= 12'hF61;
rommem[14376] <= 12'h035;
rommem[14377] <= 12'h0A6;
rommem[14378] <= 12'h04B;
rommem[14379] <= 12'h065;
rommem[14380] <= 12'h079;
rommem[14381] <= 12'h062;
rommem[14382] <= 12'h06F;
rommem[14383] <= 12'h061;
rommem[14384] <= 12'h072;
rommem[14385] <= 12'h064;
rommem[14386] <= 12'h020;
rommem[14387] <= 12'h065;
rommem[14388] <= 12'h072;
rommem[14389] <= 12'h072;
rommem[14390] <= 12'h06F;
rommem[14391] <= 12'h072;
rommem[14392] <= 12'h000;
rommem[14393] <= 12'h020;
rommem[14394] <= 12'hF26;
rommem[14395] <= 12'h034;
rommem[14396] <= 12'h010;
rommem[14397] <= 12'h034;
rommem[14398] <= 12'h004;
rommem[14399] <= 12'h08D;
rommem[14400] <= 12'hF20;
rommem[14401] <= 12'h0C4;
rommem[14402] <= 12'h080;
rommem[14403] <= 12'h035;
rommem[14404] <= 12'h004;
rommem[14405] <= 12'h026;
rommem[14406] <= 12'h008;
rommem[14407] <= 12'h05D;
rommem[14408] <= 12'h026;
rommem[14409] <= 12'hFF3;
rommem[14410] <= 12'h0CC;
rommem[14411] <= 12'hFFF;
rommem[14412] <= 12'hFFF;
rommem[14413] <= 12'h035;
rommem[14414] <= 12'h090;
rommem[14415] <= 12'h08D;
rommem[14416] <= 12'hF2C;
rommem[14417] <= 12'h017;
rommem[14418] <= 12'hFFF;
rommem[14419] <= 12'hB49;
rommem[14420] <= 12'h08E;
rommem[14421] <= 12'h000;
rommem[14422] <= 12'h014;
rommem[14423] <= 12'h030;
rommem[14424] <= 12'h1FF;
rommem[14425] <= 12'h026;
rommem[14426] <= 12'hFFC;
rommem[14427] <= 12'h0C1;
rommem[14428] <= 12'h0F0;
rommem[14429] <= 12'h026;
rommem[14430] <= 12'h006;
rommem[14431] <= 12'h00F;
rommem[14432] <= 12'h120;
rommem[14433] <= 12'h000;
rommem[14434] <= 12'h120;
rommem[14435] <= 12'h020;
rommem[14436] <= 12'hFD8;
rommem[14437] <= 12'h0C1;
rommem[14438] <= 12'h0E0;
rommem[14439] <= 12'h026;
rommem[14440] <= 12'h008;
rommem[14441] <= 12'h096;
rommem[14442] <= 12'h121;
rommem[14443] <= 12'h08A;
rommem[14444] <= 12'h800;
rommem[14445] <= 12'h097;
rommem[14446] <= 12'h121;
rommem[14447] <= 12'h020;
rommem[14448] <= 12'hFCC;
rommem[14449] <= 12'h0C1;
rommem[14450] <= 12'h014;
rommem[14451] <= 12'h026;
rommem[14452] <= 12'h016;
rommem[14453] <= 12'h00D;
rommem[14454] <= 12'h120;
rommem[14455] <= 12'h02B;
rommem[14456] <= 12'h008;
rommem[14457] <= 12'h096;
rommem[14458] <= 12'h121;
rommem[14459] <= 12'h08A;
rommem[14460] <= 12'h004;
rommem[14461] <= 12'h097;
rommem[14462] <= 12'h121;
rommem[14463] <= 12'h020;
rommem[14464] <= 12'h006;
rommem[14465] <= 12'h096;
rommem[14466] <= 12'h121;
rommem[14467] <= 12'h084;
rommem[14468] <= 12'hFFB;
rommem[14469] <= 12'h097;
rommem[14470] <= 12'h121;
rommem[14471] <= 12'h00F;
rommem[14472] <= 12'h120;
rommem[14473] <= 12'h020;
rommem[14474] <= 12'hFB2;
rommem[14475] <= 12'h0C1;
rommem[14476] <= 12'h059;
rommem[14477] <= 12'h026;
rommem[14478] <= 12'h016;
rommem[14479] <= 12'h00D;
rommem[14480] <= 12'h120;
rommem[14481] <= 12'h02B;
rommem[14482] <= 12'h008;
rommem[14483] <= 12'h096;
rommem[14484] <= 12'h121;
rommem[14485] <= 12'h08A;
rommem[14486] <= 12'h001;
rommem[14487] <= 12'h097;
rommem[14488] <= 12'h121;
rommem[14489] <= 12'h020;
rommem[14490] <= 12'h006;
rommem[14491] <= 12'h096;
rommem[14492] <= 12'h121;
rommem[14493] <= 12'h084;
rommem[14494] <= 12'hFFE;
rommem[14495] <= 12'h097;
rommem[14496] <= 12'h121;
rommem[14497] <= 12'h00F;
rommem[14498] <= 12'h120;
rommem[14499] <= 12'h020;
rommem[14500] <= 12'hF98;
rommem[14501] <= 12'h0C1;
rommem[14502] <= 12'h077;
rommem[14503] <= 12'h026;
rommem[14504] <= 12'h013;
rommem[14505] <= 12'h096;
rommem[14506] <= 12'h121;
rommem[14507] <= 12'h088;
rommem[14508] <= 12'h010;
rommem[14509] <= 12'h097;
rommem[14510] <= 12'h121;
rommem[14511] <= 12'h096;
rommem[14512] <= 12'h122;
rommem[14513] <= 12'h088;
rommem[14514] <= 12'h002;
rommem[14515] <= 12'h097;
rommem[14516] <= 12'h122;
rommem[14517] <= 12'h01F;
rommem[14518] <= 12'h089;
rommem[14519] <= 12'h04F;
rommem[14520] <= 12'h08D;
rommem[14521] <= 12'hECF;
rommem[14522] <= 12'h020;
rommem[14523] <= 12'hF81;
rommem[14524] <= 12'h0C1;
rommem[14525] <= 12'h058;
rommem[14526] <= 12'h026;
rommem[14527] <= 12'h013;
rommem[14528] <= 12'h096;
rommem[14529] <= 12'h121;
rommem[14530] <= 12'h088;
rommem[14531] <= 12'h020;
rommem[14532] <= 12'h097;
rommem[14533] <= 12'h121;
rommem[14534] <= 12'h096;
rommem[14535] <= 12'h122;
rommem[14536] <= 12'h088;
rommem[14537] <= 12'h004;
rommem[14538] <= 12'h097;
rommem[14539] <= 12'h122;
rommem[14540] <= 12'h01F;
rommem[14541] <= 12'h089;
rommem[14542] <= 12'h04F;
rommem[14543] <= 12'h08D;
rommem[14544] <= 12'hEB8;
rommem[14545] <= 12'h020;
rommem[14546] <= 12'hF6A;
rommem[14547] <= 12'h0C1;
rommem[14548] <= 12'h07E;
rommem[14549] <= 12'h026;
rommem[14550] <= 12'h013;
rommem[14551] <= 12'h096;
rommem[14552] <= 12'h121;
rommem[14553] <= 12'h088;
rommem[14554] <= 12'h040;
rommem[14555] <= 12'h097;
rommem[14556] <= 12'h121;
rommem[14557] <= 12'h096;
rommem[14558] <= 12'h122;
rommem[14559] <= 12'h088;
rommem[14560] <= 12'h001;
rommem[14561] <= 12'h097;
rommem[14562] <= 12'h122;
rommem[14563] <= 12'h01F;
rommem[14564] <= 12'h089;
rommem[14565] <= 12'h04F;
rommem[14566] <= 12'h08D;
rommem[14567] <= 12'hEA1;
rommem[14568] <= 12'h020;
rommem[14569] <= 12'hF53;
rommem[14570] <= 12'h0C1;
rommem[14571] <= 12'h011;
rommem[14572] <= 12'h026;
rommem[14573] <= 12'h016;
rommem[14574] <= 12'h00D;
rommem[14575] <= 12'h120;
rommem[14576] <= 12'h02B;
rommem[14577] <= 12'h008;
rommem[14578] <= 12'h096;
rommem[14579] <= 12'h121;
rommem[14580] <= 12'h08A;
rommem[14581] <= 12'h002;
rommem[14582] <= 12'h097;
rommem[14583] <= 12'h121;
rommem[14584] <= 12'h020;
rommem[14585] <= 12'h006;
rommem[14586] <= 12'h096;
rommem[14587] <= 12'h121;
rommem[14588] <= 12'h084;
rommem[14589] <= 12'hFFD;
rommem[14590] <= 12'h097;
rommem[14591] <= 12'h121;
rommem[14592] <= 12'h00F;
rommem[14593] <= 12'h120;
rommem[14594] <= 12'h020;
rommem[14595] <= 12'hF39;
rommem[14596] <= 12'h00D;
rommem[14597] <= 12'h120;
rommem[14598] <= 12'h027;
rommem[14599] <= 12'h004;
rommem[14600] <= 12'h00F;
rommem[14601] <= 12'h120;
rommem[14602] <= 12'h020;
rommem[14603] <= 12'hF31;
rommem[14604] <= 12'h096;
rommem[14605] <= 12'h121;
rommem[14606] <= 12'h084;
rommem[14607] <= 12'h006;
rommem[14608] <= 12'h081;
rommem[14609] <= 12'h006;
rommem[14610] <= 12'h026;
rommem[14611] <= 12'h008;
rommem[14612] <= 12'h0C1;
rommem[14613] <= 12'h071;
rommem[14614] <= 12'h026;
rommem[14615] <= 12'h004;
rommem[14616] <= 12'h06E;
rommem[14617] <= 12'h90F;
rommem[14618] <= 12'hFFF;
rommem[14619] <= 12'hFFE;
rommem[14620] <= 12'h00D;
rommem[14621] <= 12'h121;
rommem[14622] <= 12'h02A;
rommem[14623] <= 12'h00B;
rommem[14624] <= 12'h096;
rommem[14625] <= 12'h121;
rommem[14626] <= 12'h084;
rommem[14627] <= 12'h7FF;
rommem[14628] <= 12'h097;
rommem[14629] <= 12'h121;
rommem[14630] <= 12'h08E;
rommem[14631] <= 12'hFFF;
rommem[14632] <= 12'h680;
rommem[14633] <= 12'h020;
rommem[14634] <= 12'h017;
rommem[14635] <= 12'h096;
rommem[14636] <= 12'h121;
rommem[14637] <= 12'h085;
rommem[14638] <= 12'h004;
rommem[14639] <= 12'h027;
rommem[14640] <= 12'h005;
rommem[14641] <= 12'h08E;
rommem[14642] <= 12'hFFF;
rommem[14643] <= 12'h600;
rommem[14644] <= 12'h020;
rommem[14645] <= 12'h00C;
rommem[14646] <= 12'h085;
rommem[14647] <= 12'h001;
rommem[14648] <= 12'h027;
rommem[14649] <= 12'h005;
rommem[14650] <= 12'h08E;
rommem[14651] <= 12'hFFF;
rommem[14652] <= 12'h500;
rommem[14653] <= 12'h020;
rommem[14654] <= 12'h003;
rommem[14655] <= 12'h08E;
rommem[14656] <= 12'hFFF;
rommem[14657] <= 12'h400;
rommem[14658] <= 12'h03A;
rommem[14659] <= 12'h0E6;
rommem[14660] <= 12'h804;
rommem[14661] <= 12'h04F;
rommem[14662] <= 12'h035;
rommem[14663] <= 12'h090;
rommem[14664] <= 12'h04B;
rommem[14665] <= 12'h045;
rommem[14666] <= 12'h059;
rommem[14667] <= 12'h042;
rommem[14668] <= 12'h04F;
rommem[14669] <= 12'h041;
rommem[14670] <= 12'h052;
rommem[14671] <= 12'h044;
rommem[14672] <= 12'hFFF;
rommem[14673] <= 12'h95A;
rommem[14674] <= 12'hFFF;
rommem[14675] <= 12'h95B;
rommem[14676] <= 12'hFFF;
rommem[14677] <= 12'h95C;
rommem[14678] <= 12'hFFF;
rommem[14679] <= 12'h95D;
rommem[14680] <= 12'hFFF;
rommem[14681] <= 12'h95E;
rommem[14682] <= 12'h039;
rommem[14683] <= 12'h039;
rommem[14684] <= 12'h039;
rommem[14685] <= 12'h039;
rommem[14686] <= 12'h039;
rommem[14687] <= 12'h020;
rommem[14688] <= 12'hED8;
rommem[14689] <= 12'h0CC;
rommem[14690] <= 12'hFFF;
rommem[14691] <= 12'hFFF;
rommem[14692] <= 12'h020;
rommem[14693] <= 12'hED5;
rommem[14694] <= 12'h08D;
rommem[14695] <= 12'hFF9;
rommem[14696] <= 12'h020;
rommem[14697] <= 12'h009;
rommem[14698] <= 12'h08D;
rommem[14699] <= 12'hFF5;
rommem[14700] <= 12'h015;
rommem[14701] <= 12'h07D;
rommem[14702] <= 12'hFFF;
rommem[14703] <= 12'hFFC;
rommem[14704] <= 12'hA00;
rommem[14705] <= 12'h027;
rommem[14706] <= 12'h00B;
rommem[14707] <= 12'h081;
rommem[14708] <= 12'h00D;
rommem[14709] <= 12'h026;
rommem[14710] <= 12'h005;
rommem[14711] <= 12'h017;
rommem[14712] <= 12'hFFD;
rommem[14713] <= 12'h758;
rommem[14714] <= 12'h020;
rommem[14715] <= 12'h002;
rommem[14716] <= 12'h08D;
rommem[14717] <= 12'h91D;
rommem[14718] <= 12'h039;
rommem[14719] <= 12'h06E;
rommem[14720] <= 12'h90F;
rommem[14721] <= 12'h000;
rommem[14722] <= 12'h800;
rommem[14723] <= 12'h015;
rommem[14724] <= 12'h0F7;
rommem[14725] <= 12'hFFF;
rommem[14726] <= 12'hFFC;
rommem[14727] <= 12'hA00;
rommem[14728] <= 12'h039;
rommem[14729] <= 12'h015;
rommem[14730] <= 12'h0BF;
rommem[14731] <= 12'hFFF;
rommem[14732] <= 12'hE10;
rommem[14733] <= 12'h3C0;
rommem[14734] <= 12'h015;
rommem[14735] <= 12'h0FD;
rommem[14736] <= 12'hFFF;
rommem[14737] <= 12'hE10;
rommem[14738] <= 12'h3C2;
rommem[14739] <= 12'h039;
rommem[14740] <= 12'h0CC;
rommem[14741] <= 12'hFFF;
rommem[14742] <= 12'hAF2;
rommem[14743] <= 12'h08D;
rommem[14744] <= 12'h9BB;
rommem[14745] <= 12'h032;
rommem[14746] <= 12'h80F;
rommem[14747] <= 12'h003;
rommem[14748] <= 12'hFFF;
rommem[14749] <= 12'h05F;
rommem[14750] <= 12'h08D;
rommem[14751] <= 12'hFE3;
rommem[14752] <= 12'h017;
rommem[14753] <= 12'hFFD;
rommem[14754] <= 12'h72F;
rommem[14755] <= 12'h0C6;
rommem[14756] <= 12'h024;
rommem[14757] <= 12'h08D;
rommem[14758] <= 12'hFD8;
rommem[14759] <= 12'h0CC;
rommem[14760] <= 12'hFFF;
rommem[14761] <= 12'hFFF;
rommem[14762] <= 12'h08D;
rommem[14763] <= 12'hE8F;
rommem[14764] <= 12'h0C1;
rommem[14765] <= 12'h00D;
rommem[14766] <= 12'h027;
rommem[14767] <= 12'h004;
rommem[14768] <= 12'h08D;
rommem[14769] <= 12'hFCD;
rommem[14770] <= 12'h020;
rommem[14771] <= 12'hFF3;
rommem[14772] <= 12'h0CC;
rommem[14773] <= 12'h005;
rommem[14774] <= 12'h050;
rommem[14775] <= 12'h015;
rommem[14776] <= 12'h0FD;
rommem[14777] <= 12'hFFF;
rommem[14778] <= 12'hE60;
rommem[14779] <= 12'h000;
rommem[14780] <= 12'h0F6;
rommem[14781] <= 12'h800;
rommem[14782] <= 12'h000;
rommem[14783] <= 12'h0C1;
rommem[14784] <= 12'h03D;
rommem[14785] <= 12'h022;
rommem[14786] <= 12'hFE4;
rommem[14787] <= 12'h0CC;
rommem[14788] <= 12'h005;
rommem[14789] <= 12'h151;
rommem[14790] <= 12'h015;
rommem[14791] <= 12'h0FD;
rommem[14792] <= 12'hFFF;
rommem[14793] <= 12'hE60;
rommem[14794] <= 12'h000;
rommem[14795] <= 12'h00F;
rommem[14796] <= 12'h111;
rommem[14797] <= 12'h08D;
rommem[14798] <= 12'h8AA;
rommem[14799] <= 12'h01F;
rommem[14800] <= 12'h002;
rommem[14801] <= 12'h0CC;
rommem[14802] <= 12'h005;
rommem[14803] <= 12'h252;
rommem[14804] <= 12'h015;
rommem[14805] <= 12'h0FD;
rommem[14806] <= 12'hFFF;
rommem[14807] <= 12'hE60;
rommem[14808] <= 12'h000;
rommem[14809] <= 12'h08D;
rommem[14810] <= 12'h055;
rommem[14811] <= 12'h0C1;
rommem[14812] <= 12'h024;
rommem[14813] <= 12'h026;
rommem[14814] <= 12'h009;
rommem[14815] <= 12'h086;
rommem[14816] <= 12'h353;
rommem[14817] <= 12'h015;
rommem[14818] <= 12'h0FD;
rommem[14819] <= 12'hFFF;
rommem[14820] <= 12'hE60;
rommem[14821] <= 12'h000;
rommem[14822] <= 12'h08D;
rommem[14823] <= 12'h048;
rommem[14824] <= 12'h0C1;
rommem[14825] <= 12'h03F;
rommem[14826] <= 12'h026;
rommem[14827] <= 12'h007;
rommem[14828] <= 12'h0CC;
rommem[14829] <= 12'hFFF;
rommem[14830] <= 12'hAF2;
rommem[14831] <= 12'h08D;
rommem[14832] <= 12'h963;
rommem[14833] <= 12'h020;
rommem[14834] <= 12'hFA6;
rommem[14835] <= 12'h0C1;
rommem[14836] <= 12'h043;
rommem[14837] <= 12'h026;
rommem[14838] <= 12'h007;
rommem[14839] <= 12'h017;
rommem[14840] <= 12'hFFF;
rommem[14841] <= 12'h7D6;
rommem[14842] <= 12'h08D;
rommem[14843] <= 12'h845;
rommem[14844] <= 12'h020;
rommem[14845] <= 12'hF9B;
rommem[14846] <= 12'h0C1;
rommem[14847] <= 12'h044;
rommem[14848] <= 12'h026;
rommem[14849] <= 12'h008;
rommem[14850] <= 12'h08D;
rommem[14851] <= 12'h027;
rommem[14852] <= 12'h0C1;
rommem[14853] <= 12'h052;
rommem[14854] <= 12'h026;
rommem[14855] <= 12'hF9F;
rommem[14856] <= 12'h020;
rommem[14857] <= 12'h193;
rommem[14858] <= 12'h0C1;
rommem[14859] <= 12'h046;
rommem[14860] <= 12'h026;
rommem[14861] <= 12'h00F;
rommem[14862] <= 12'h08D;
rommem[14863] <= 12'h01B;
rommem[14864] <= 12'h0C1;
rommem[14865] <= 12'h049;
rommem[14866] <= 12'h026;
rommem[14867] <= 12'hF85;
rommem[14868] <= 12'h08D;
rommem[14869] <= 12'h015;
rommem[14870] <= 12'h0C1;
rommem[14871] <= 12'h047;
rommem[14872] <= 12'h026;
rommem[14873] <= 12'hF7F;
rommem[14874] <= 12'h07E;
rommem[14875] <= 12'hFE0;
rommem[14876] <= 12'h000;
rommem[14877] <= 12'h0C1;
rommem[14878] <= 12'h04A;
rommem[14879] <= 12'h127;
rommem[14880] <= 12'h000;
rommem[14881] <= 12'h1BF;
rommem[14882] <= 12'h0C1;
rommem[14883] <= 12'h052;
rommem[14884] <= 12'h026;
rommem[14885] <= 12'hF73;
rommem[14886] <= 12'h017;
rommem[14887] <= 12'hFFE;
rommem[14888] <= 12'h5D7;
rommem[14889] <= 12'h020;
rommem[14890] <= 12'hF6E;
rommem[14891] <= 12'h0E6;
rommem[14892] <= 12'hA04;
rommem[14893] <= 12'h031;
rommem[14894] <= 12'h201;
rommem[14895] <= 12'h039;
rommem[14896] <= 12'h08D;
rommem[14897] <= 12'hFF9;
rommem[14898] <= 12'h0C1;
rommem[14899] <= 12'h020;
rommem[14900] <= 12'h027;
rommem[14901] <= 12'hFFA;
rommem[14902] <= 12'h0C1;
rommem[14903] <= 12'h009;
rommem[14904] <= 12'h027;
rommem[14905] <= 12'hFF6;
rommem[14906] <= 12'h039;
rommem[14907] <= 12'h08D;
rommem[14908] <= 12'hFEE;
rommem[14909] <= 12'h0C1;
rommem[14910] <= 12'h020;
rommem[14911] <= 12'h027;
rommem[14912] <= 12'hFFA;
rommem[14913] <= 12'h031;
rommem[14914] <= 12'h3FF;
rommem[14915] <= 12'h039;
rommem[14916] <= 12'h08D;
rommem[14917] <= 12'hFF5;
rommem[14918] <= 12'h08D;
rommem[14919] <= 12'h02E;
rommem[14920] <= 12'h0DC;
rommem[14921] <= 12'h910;
rommem[14922] <= 12'h0DD;
rommem[14923] <= 12'h920;
rommem[14924] <= 12'h0DC;
rommem[14925] <= 12'h912;
rommem[14926] <= 12'h0DD;
rommem[14927] <= 12'h922;
rommem[14928] <= 12'h08D;
rommem[14929] <= 12'hFE9;
rommem[14930] <= 12'h08D;
rommem[14931] <= 12'h022;
rommem[14932] <= 12'h0DC;
rommem[14933] <= 12'h910;
rommem[14934] <= 12'h0DD;
rommem[14935] <= 12'h922;
rommem[14936] <= 12'h0DC;
rommem[14937] <= 12'h912;
rommem[14938] <= 12'h0DD;
rommem[14939] <= 12'h924;
rommem[14940] <= 12'h039;
rommem[14941] <= 12'h08D;
rommem[14942] <= 12'hFE5;
rommem[14943] <= 12'h0DC;
rommem[14944] <= 12'h924;
rommem[14945] <= 12'h093;
rommem[14946] <= 12'h922;
rommem[14947] <= 12'h0DC;
rommem[14948] <= 12'h922;
rommem[14949] <= 12'h0D2;
rommem[14950] <= 12'h921;
rommem[14951] <= 12'h092;
rommem[14952] <= 12'h920;
rommem[14953] <= 12'h125;
rommem[14954] <= 12'h000;
rommem[14955] <= 12'h06C;
rommem[14956] <= 12'h039;
rommem[14957] <= 12'h008;
rommem[14958] <= 12'h913;
rommem[14959] <= 12'h009;
rommem[14960] <= 12'h912;
rommem[14961] <= 12'h009;
rommem[14962] <= 12'h911;
rommem[14963] <= 12'h009;
rommem[14964] <= 12'h910;
rommem[14965] <= 12'h039;
rommem[14966] <= 12'h04F;
rommem[14967] <= 12'h05F;
rommem[14968] <= 12'h0DD;
rommem[14969] <= 12'h910;
rommem[14970] <= 12'h0DD;
rommem[14971] <= 12'h912;
rommem[14972] <= 12'h034;
rommem[14973] <= 12'h010;
rommem[14974] <= 12'h08E;
rommem[14975] <= 12'h000;
rommem[14976] <= 12'h000;
rommem[14977] <= 12'h08D;
rommem[14978] <= 12'hFA8;
rommem[14979] <= 12'h08D;
rommem[14980] <= 12'h01D;
rommem[14981] <= 12'h0C1;
rommem[14982] <= 12'hFFF;
rommem[14983] <= 12'h027;
rommem[14984] <= 12'h015;
rommem[14985] <= 12'h08D;
rommem[14986] <= 12'hFE2;
rommem[14987] <= 12'h08D;
rommem[14988] <= 12'hFE0;
rommem[14989] <= 12'h08D;
rommem[14990] <= 12'hFDE;
rommem[14991] <= 12'h08D;
rommem[14992] <= 12'hFDC;
rommem[14993] <= 12'h0C4;
rommem[14994] <= 12'h00F;
rommem[14995] <= 12'h0DA;
rommem[14996] <= 12'h913;
rommem[14997] <= 12'h0D7;
rommem[14998] <= 12'h913;
rommem[14999] <= 12'h030;
rommem[15000] <= 12'h001;
rommem[15001] <= 12'h08C;
rommem[15002] <= 12'h000;
rommem[15003] <= 12'h009;
rommem[15004] <= 12'h025;
rommem[15005] <= 12'hFE3;
rommem[15006] <= 12'h01F;
rommem[15007] <= 12'h010;
rommem[15008] <= 12'h035;
rommem[15009] <= 12'h090;
rommem[15010] <= 12'h0C1;
rommem[15011] <= 12'h030;
rommem[15012] <= 12'h024;
rommem[15013] <= 12'h021;
rommem[15014] <= 12'h0C1;
rommem[15015] <= 12'h03A;
rommem[15016] <= 12'h025;
rommem[15017] <= 12'h003;
rommem[15018] <= 12'h0C0;
rommem[15019] <= 12'h030;
rommem[15020] <= 12'h039;
rommem[15021] <= 12'h0C1;
rommem[15022] <= 12'h041;
rommem[15023] <= 12'h024;
rommem[15024] <= 12'h016;
rommem[15025] <= 12'h0C1;
rommem[15026] <= 12'h047;
rommem[15027] <= 12'h025;
rommem[15028] <= 12'h005;
rommem[15029] <= 12'h0C0;
rommem[15030] <= 12'h041;
rommem[15031] <= 12'h0CB;
rommem[15032] <= 12'h00A;
rommem[15033] <= 12'h039;
rommem[15034] <= 12'h0C1;
rommem[15035] <= 12'h061;
rommem[15036] <= 12'h024;
rommem[15037] <= 12'h009;
rommem[15038] <= 12'h0C1;
rommem[15039] <= 12'h07B;
rommem[15040] <= 12'h025;
rommem[15041] <= 12'h005;
rommem[15042] <= 12'h0C0;
rommem[15043] <= 12'h061;
rommem[15044] <= 12'h0CB;
rommem[15045] <= 12'h00A;
rommem[15046] <= 12'h039;
rommem[15047] <= 12'h0C6;
rommem[15048] <= 12'hFFF;
rommem[15049] <= 12'h039;
rommem[15050] <= 12'h0C1;
rommem[15051] <= 12'h030;
rommem[15052] <= 12'h024;
rommem[15053] <= 12'h007;
rommem[15054] <= 12'h0C1;
rommem[15055] <= 12'h03A;
rommem[15056] <= 12'h025;
rommem[15057] <= 12'h003;
rommem[15058] <= 12'h0C0;
rommem[15059] <= 12'h030;
rommem[15060] <= 12'h039;
rommem[15061] <= 12'h0C6;
rommem[15062] <= 12'hFFF;
rommem[15063] <= 12'h039;
rommem[15064] <= 12'h08E;
rommem[15065] <= 12'hFFF;
rommem[15066] <= 12'hAEA;
rommem[15067] <= 12'h04F;
rommem[15068] <= 12'h05F;
rommem[15069] <= 12'h08D;
rommem[15070] <= 12'h003;
rommem[15071] <= 12'h07E;
rommem[15072] <= 12'hFFF;
rommem[15073] <= 12'h999;
rommem[15074] <= 12'h0DD;
rommem[15075] <= 12'h024;
rommem[15076] <= 12'h09F;
rommem[15077] <= 12'h026;
rommem[15078] <= 12'h0BD;
rommem[15079] <= 12'hFFF;
rommem[15080] <= 12'h354;
rommem[15081] <= 12'h039;
rommem[15082] <= 12'h02A;
rommem[15083] <= 12'h02A;
rommem[15084] <= 12'h045;
rommem[15085] <= 12'h072;
rommem[15086] <= 12'h072;
rommem[15087] <= 12'h00D;
rommem[15088] <= 12'h00A;
rommem[15089] <= 12'h000;
rommem[15090] <= 12'h03F;
rommem[15091] <= 12'h020;
rommem[15092] <= 12'h03D;
rommem[15093] <= 12'h020;
rommem[15094] <= 12'h044;
rommem[15095] <= 12'h069;
rommem[15096] <= 12'h073;
rommem[15097] <= 12'h070;
rommem[15098] <= 12'h06C;
rommem[15099] <= 12'h061;
rommem[15100] <= 12'h079;
rommem[15101] <= 12'h020;
rommem[15102] <= 12'h068;
rommem[15103] <= 12'h065;
rommem[15104] <= 12'h06C;
rommem[15105] <= 12'h070;
rommem[15106] <= 12'h00D;
rommem[15107] <= 12'h00A;
rommem[15108] <= 12'h043;
rommem[15109] <= 12'h04C;
rommem[15110] <= 12'h053;
rommem[15111] <= 12'h020;
rommem[15112] <= 12'h03D;
rommem[15113] <= 12'h020;
rommem[15114] <= 12'h063;
rommem[15115] <= 12'h06C;
rommem[15116] <= 12'h065;
rommem[15117] <= 12'h061;
rommem[15118] <= 12'h072;
rommem[15119] <= 12'h020;
rommem[15120] <= 12'h073;
rommem[15121] <= 12'h063;
rommem[15122] <= 12'h072;
rommem[15123] <= 12'h065;
rommem[15124] <= 12'h065;
rommem[15125] <= 12'h06E;
rommem[15126] <= 12'h00D;
rommem[15127] <= 12'h00A;
rommem[15128] <= 12'h044;
rommem[15129] <= 12'h052;
rommem[15130] <= 12'h020;
rommem[15131] <= 12'h03D;
rommem[15132] <= 12'h020;
rommem[15133] <= 12'h044;
rommem[15134] <= 12'h075;
rommem[15135] <= 12'h06D;
rommem[15136] <= 12'h070;
rommem[15137] <= 12'h020;
rommem[15138] <= 12'h072;
rommem[15139] <= 12'h065;
rommem[15140] <= 12'h067;
rommem[15141] <= 12'h069;
rommem[15142] <= 12'h073;
rommem[15143] <= 12'h074;
rommem[15144] <= 12'h065;
rommem[15145] <= 12'h072;
rommem[15146] <= 12'h073;
rommem[15147] <= 12'h00D;
rommem[15148] <= 12'h00A;
rommem[15149] <= 12'h046;
rommem[15150] <= 12'h049;
rommem[15151] <= 12'h047;
rommem[15152] <= 12'h020;
rommem[15153] <= 12'h03D;
rommem[15154] <= 12'h020;
rommem[15155] <= 12'h073;
rommem[15156] <= 12'h074;
rommem[15157] <= 12'h061;
rommem[15158] <= 12'h072;
rommem[15159] <= 12'h074;
rommem[15160] <= 12'h020;
rommem[15161] <= 12'h046;
rommem[15162] <= 12'h049;
rommem[15163] <= 12'h047;
rommem[15164] <= 12'h020;
rommem[15165] <= 12'h046;
rommem[15166] <= 12'h06F;
rommem[15167] <= 12'h072;
rommem[15168] <= 12'h074;
rommem[15169] <= 12'h068;
rommem[15170] <= 12'h00D;
rommem[15171] <= 12'h00A;
rommem[15172] <= 12'h04A;
rommem[15173] <= 12'h020;
rommem[15174] <= 12'h03D;
rommem[15175] <= 12'h020;
rommem[15176] <= 12'h04A;
rommem[15177] <= 12'h075;
rommem[15178] <= 12'h06D;
rommem[15179] <= 12'h070;
rommem[15180] <= 12'h020;
rommem[15181] <= 12'h074;
rommem[15182] <= 12'h06F;
rommem[15183] <= 12'h020;
rommem[15184] <= 12'h063;
rommem[15185] <= 12'h06F;
rommem[15186] <= 12'h064;
rommem[15187] <= 12'h065;
rommem[15188] <= 12'h00D;
rommem[15189] <= 12'h00A;
rommem[15190] <= 12'h052;
rommem[15191] <= 12'h041;
rommem[15192] <= 12'h04D;
rommem[15193] <= 12'h020;
rommem[15194] <= 12'h03D;
rommem[15195] <= 12'h020;
rommem[15196] <= 12'h074;
rommem[15197] <= 12'h065;
rommem[15198] <= 12'h073;
rommem[15199] <= 12'h074;
rommem[15200] <= 12'h020;
rommem[15201] <= 12'h052;
rommem[15202] <= 12'h041;
rommem[15203] <= 12'h04D;
rommem[15204] <= 12'h00D;
rommem[15205] <= 12'h00A;
rommem[15206] <= 12'h000;
rommem[15207] <= 12'h00D;
rommem[15208] <= 12'h00A;
rommem[15209] <= 12'h020;
rommem[15210] <= 12'h044;
rommem[15211] <= 12'h02F;
rommem[15212] <= 12'h041;
rommem[15213] <= 12'h042;
rommem[15214] <= 12'h020;
rommem[15215] <= 12'h020;
rommem[15216] <= 12'h020;
rommem[15217] <= 12'h058;
rommem[15218] <= 12'h020;
rommem[15219] <= 12'h020;
rommem[15220] <= 12'h020;
rommem[15221] <= 12'h020;
rommem[15222] <= 12'h059;
rommem[15223] <= 12'h020;
rommem[15224] <= 12'h020;
rommem[15225] <= 12'h020;
rommem[15226] <= 12'h020;
rommem[15227] <= 12'h055;
rommem[15228] <= 12'h020;
rommem[15229] <= 12'h020;
rommem[15230] <= 12'h020;
rommem[15231] <= 12'h020;
rommem[15232] <= 12'h053;
rommem[15233] <= 12'h020;
rommem[15234] <= 12'h020;
rommem[15235] <= 12'h020;
rommem[15236] <= 12'h020;
rommem[15237] <= 12'h020;
rommem[15238] <= 12'h050;
rommem[15239] <= 12'h043;
rommem[15240] <= 12'h020;
rommem[15241] <= 12'h020;
rommem[15242] <= 12'h020;
rommem[15243] <= 12'h020;
rommem[15244] <= 12'h044;
rommem[15245] <= 12'h050;
rommem[15246] <= 12'h020;
rommem[15247] <= 12'h043;
rommem[15248] <= 12'h043;
rommem[15249] <= 12'h052;
rommem[15250] <= 12'h00D;
rommem[15251] <= 12'h00A;
rommem[15252] <= 12'h000;
rommem[15253] <= 12'h0BD;
rommem[15254] <= 12'hFFD;
rommem[15255] <= 12'h2D2;
rommem[15256] <= 12'h039;
rommem[15257] <= 12'h0C6;
rommem[15258] <= 12'h020;
rommem[15259] <= 12'h020;
rommem[15260] <= 12'hDE2;
rommem[15261] <= 12'h08E;
rommem[15262] <= 12'hFFF;
rommem[15263] <= 12'hB67;
rommem[15264] <= 12'h0CC;
rommem[15265] <= 12'h000;
rommem[15266] <= 12'h0FF;
rommem[15267] <= 12'h0BD;
rommem[15268] <= 12'hFFF;
rommem[15269] <= 12'hAE2;
rommem[15270] <= 12'h08D;
rommem[15271] <= 12'hFF1;
rommem[15272] <= 12'h0DC;
rommem[15273] <= 12'h900;
rommem[15274] <= 12'h08D;
rommem[15275] <= 12'hFE9;
rommem[15276] <= 12'h08D;
rommem[15277] <= 12'hFEB;
rommem[15278] <= 12'h0DC;
rommem[15279] <= 12'h902;
rommem[15280] <= 12'h08D;
rommem[15281] <= 12'hFE3;
rommem[15282] <= 12'h08D;
rommem[15283] <= 12'hFE5;
rommem[15284] <= 12'h0DC;
rommem[15285] <= 12'h904;
rommem[15286] <= 12'h08D;
rommem[15287] <= 12'hFDD;
rommem[15288] <= 12'h08D;
rommem[15289] <= 12'hFDF;
rommem[15290] <= 12'h0DC;
rommem[15291] <= 12'h906;
rommem[15292] <= 12'h08D;
rommem[15293] <= 12'hFD7;
rommem[15294] <= 12'h08D;
rommem[15295] <= 12'hFD9;
rommem[15296] <= 12'h0DC;
rommem[15297] <= 12'h908;
rommem[15298] <= 12'h08D;
rommem[15299] <= 12'hFD1;
rommem[15300] <= 12'h08D;
rommem[15301] <= 12'hFD3;
rommem[15302] <= 12'h0DC;
rommem[15303] <= 12'h90A;
rommem[15304] <= 12'h08D;
rommem[15305] <= 12'hFCB;
rommem[15306] <= 12'h0DC;
rommem[15307] <= 12'h90C;
rommem[15308] <= 12'h08D;
rommem[15309] <= 12'hFC7;
rommem[15310] <= 12'h08D;
rommem[15311] <= 12'hFC9;
rommem[15312] <= 12'h0DC;
rommem[15313] <= 12'h90E;
rommem[15314] <= 12'h0BD;
rommem[15315] <= 12'hFFD;
rommem[15316] <= 12'h2CE;
rommem[15317] <= 12'h08D;
rommem[15318] <= 12'hFC2;
rommem[15319] <= 12'h096;
rommem[15320] <= 12'h90F;
rommem[15321] <= 12'h0BD;
rommem[15322] <= 12'hFFD;
rommem[15323] <= 12'h2CE;
rommem[15324] <= 12'h08D;
rommem[15325] <= 12'hFBB;
rommem[15326] <= 12'h07E;
rommem[15327] <= 12'hFFF;
rommem[15328] <= 12'h999;
rommem[15329] <= 12'h08D;
rommem[15330] <= 12'hE93;
rommem[15331] <= 12'h01A;
rommem[15332] <= 12'h010;
rommem[15333] <= 12'h1DE;
rommem[15334] <= 12'h908;
rommem[15335] <= 12'h0CC;
rommem[15336] <= 12'hFFF;
rommem[15337] <= 12'hC14;
rommem[15338] <= 12'h034;
rommem[15339] <= 12'h006;
rommem[15340] <= 12'h0CC;
rommem[15341] <= 12'h000;
rommem[15342] <= 12'h000;
rommem[15343] <= 12'h034;
rommem[15344] <= 12'h004;
rommem[15345] <= 12'h0DC;
rommem[15346] <= 12'h912;
rommem[15347] <= 12'h034;
rommem[15348] <= 12'h006;
rommem[15349] <= 12'h0DC;
rommem[15350] <= 12'h910;
rommem[15351] <= 12'h034;
rommem[15352] <= 12'h006;
rommem[15353] <= 12'h0DC;
rommem[15354] <= 12'h906;
rommem[15355] <= 12'h034;
rommem[15356] <= 12'h006;
rommem[15357] <= 12'h0DC;
rommem[15358] <= 12'h904;
rommem[15359] <= 12'h034;
rommem[15360] <= 12'h006;
rommem[15361] <= 12'h0DC;
rommem[15362] <= 12'h902;
rommem[15363] <= 12'h034;
rommem[15364] <= 12'h006;
rommem[15365] <= 12'h096;
rommem[15366] <= 12'h90E;
rommem[15367] <= 12'h034;
rommem[15368] <= 12'h002;
rommem[15369] <= 12'h0DC;
rommem[15370] <= 12'h900;
rommem[15371] <= 12'h034;
rommem[15372] <= 12'h006;
rommem[15373] <= 12'h096;
rommem[15374] <= 12'h90F;
rommem[15375] <= 12'h034;
rommem[15376] <= 12'h002;
rommem[15377] <= 12'h015;
rommem[15378] <= 12'h035;
rommem[15379] <= 12'h0FF;
rommem[15380] <= 12'h034;
rommem[15381] <= 12'h001;
rommem[15382] <= 12'h0DD;
rommem[15383] <= 12'h900;
rommem[15384] <= 12'h09F;
rommem[15385] <= 12'h902;
rommem[15386] <= 12'h19F;
rommem[15387] <= 12'h904;
rommem[15388] <= 12'h0DF;
rommem[15389] <= 12'h906;
rommem[15390] <= 12'h01F;
rommem[15391] <= 12'h0B8;
rommem[15392] <= 12'h097;
rommem[15393] <= 12'h90E;
rommem[15394] <= 12'h035;
rommem[15395] <= 12'h002;
rommem[15396] <= 12'h097;
rommem[15397] <= 12'h90F;
rommem[15398] <= 12'h1DF;
rommem[15399] <= 12'h908;
rommem[15400] <= 12'h1CE;
rommem[15401] <= 12'h003;
rommem[15402] <= 12'hFFF;
rommem[15403] <= 12'h07E;
rommem[15404] <= 12'hFFF;
rommem[15405] <= 12'hB9D;
rommem[15406] <= 12'h01A;
rommem[15407] <= 12'h010;
rommem[15408] <= 12'h035;
rommem[15409] <= 12'h002;
rommem[15410] <= 12'h097;
rommem[15411] <= 12'h90F;
rommem[15412] <= 12'h035;
rommem[15413] <= 12'h07E;
rommem[15414] <= 12'h0DD;
rommem[15415] <= 12'h900;
rommem[15416] <= 12'h09F;
rommem[15417] <= 12'h902;
rommem[15418] <= 12'h19F;
rommem[15419] <= 12'h904;
rommem[15420] <= 12'h0DF;
rommem[15421] <= 12'h906;
rommem[15422] <= 12'h01F;
rommem[15423] <= 12'h0B8;
rommem[15424] <= 12'h097;
rommem[15425] <= 12'h90E;
rommem[15426] <= 12'h035;
rommem[15427] <= 12'h006;
rommem[15428] <= 12'h0DD;
rommem[15429] <= 12'h90A;
rommem[15430] <= 12'h035;
rommem[15431] <= 12'h006;
rommem[15432] <= 12'h0DD;
rommem[15433] <= 12'h90C;
rommem[15434] <= 12'h1DF;
rommem[15435] <= 12'h908;
rommem[15436] <= 12'h1CE;
rommem[15437] <= 12'h003;
rommem[15438] <= 12'hFFF;
rommem[15439] <= 12'h01C;
rommem[15440] <= 12'h0EF;
rommem[15441] <= 12'h07E;
rommem[15442] <= 12'hFFF;
rommem[15443] <= 12'hB9D;
rommem[15444] <= 12'h01A;
rommem[15445] <= 12'h010;
rommem[15446] <= 12'h1DE;
rommem[15447] <= 12'h908;
rommem[15448] <= 12'h0DC;
rommem[15449] <= 12'h90C;
rommem[15450] <= 12'h034;
rommem[15451] <= 12'h006;
rommem[15452] <= 12'h0DC;
rommem[15453] <= 12'h90A;
rommem[15454] <= 12'h034;
rommem[15455] <= 12'h006;
rommem[15456] <= 12'h0DE;
rommem[15457] <= 12'h906;
rommem[15458] <= 12'h19E;
rommem[15459] <= 12'h904;
rommem[15460] <= 12'h09E;
rommem[15461] <= 12'h902;
rommem[15462] <= 12'h034;
rommem[15463] <= 12'h070;
rommem[15464] <= 12'h096;
rommem[15465] <= 12'h90E;
rommem[15466] <= 12'h034;
rommem[15467] <= 12'h002;
rommem[15468] <= 12'h0DC;
rommem[15469] <= 12'h900;
rommem[15470] <= 12'h034;
rommem[15471] <= 12'h006;
rommem[15472] <= 12'h096;
rommem[15473] <= 12'h90F;
rommem[15474] <= 12'h034;
rommem[15475] <= 12'h002;
rommem[15476] <= 12'h01F;
rommem[15477] <= 12'h08A;
rommem[15478] <= 12'h01C;
rommem[15479] <= 12'h0EF;
rommem[15480] <= 12'h03B;
rommem[15481] <= 12'h086;
rommem[15482] <= 12'h002;
rommem[15483] <= 12'h015;
rommem[15484] <= 12'h0B7;
rommem[15485] <= 12'hFFF;
rommem[15486] <= 12'hE3F;
rommem[15487] <= 12'h006;
rommem[15488] <= 12'h097;
rommem[15489] <= 12'h79A;
rommem[15490] <= 12'h096;
rommem[15491] <= 12'h0DF;
rommem[15492] <= 12'h044;
rommem[15493] <= 12'h09A;
rommem[15494] <= 12'h0DF;
rommem[15495] <= 12'h084;
rommem[15496] <= 12'h0E0;
rommem[15497] <= 12'h097;
rommem[15498] <= 12'h0DF;
rommem[15499] <= 12'h015;
rommem[15500] <= 12'h07C;
rommem[15501] <= 12'hFFF;
rommem[15502] <= 12'hE00;
rommem[15503] <= 12'h06E;
rommem[15504] <= 12'h015;
rommem[15505] <= 12'h0B6;
rommem[15506] <= 12'hFFF;
rommem[15507] <= 12'hFFF;
rommem[15508] <= 12'hFE0;
rommem[15509] <= 12'h091;
rommem[15510] <= 12'h100;
rommem[15511] <= 12'h026;
rommem[15512] <= 12'h021;
rommem[15513] <= 12'h096;
rommem[15514] <= 12'h114;
rommem[15515] <= 12'h027;
rommem[15516] <= 12'h01D;
rommem[15517] <= 12'h017;
rommem[15518] <= 12'hFFF;
rommem[15519] <= 12'h5D9;
rommem[15520] <= 12'h01F;
rommem[15521] <= 12'h002;
rommem[15522] <= 12'h0A6;
rommem[15523] <= 12'hA09;
rommem[15524] <= 12'h002;
rommem[15525] <= 12'h000;
rommem[15526] <= 12'h0D6;
rommem[15527] <= 12'h7C6;
rommem[15528] <= 12'h054;
rommem[15529] <= 12'h044;
rommem[15530] <= 12'h044;
rommem[15531] <= 12'h044;
rommem[15532] <= 12'h044;
rommem[15533] <= 12'h054;
rommem[15534] <= 12'h049;
rommem[15535] <= 12'h054;
rommem[15536] <= 12'h049;
rommem[15537] <= 12'h054;
rommem[15538] <= 12'h049;
rommem[15539] <= 12'h054;
rommem[15540] <= 12'h049;
rommem[15541] <= 12'h0A7;
rommem[15542] <= 12'hA0A;
rommem[15543] <= 12'h000;
rommem[15544] <= 12'hE00;
rommem[15545] <= 12'h000;
rommem[15546] <= 12'h03B;
rommem[15547] <= 12'h015;
rommem[15548] <= 12'h0F6;
rommem[15549] <= 12'hFFF;
rommem[15550] <= 12'hFFF;
rommem[15551] <= 12'hFE0;
rommem[15552] <= 12'h086;
rommem[15553] <= 12'h049;
rommem[15554] <= 12'h08E;
rommem[15555] <= 12'hE00;
rommem[15556] <= 12'h028;
rommem[15557] <= 12'h03A;
rommem[15558] <= 12'h0A7;
rommem[15559] <= 12'h804;
rommem[15560] <= 12'h03B;
rommem[16368] <= 12'h012;
rommem[16369] <= 12'h012;
rommem[16370] <= 12'hFFF;
rommem[16371] <= 12'hC2E;
rommem[16376] <= 12'hFFF;
rommem[16377] <= 12'hC79;
rommem[16378] <= 12'hFFF;
rommem[16379] <= 12'h023;
rommem[16380] <= 12'hFFF;
rommem[16381] <= 12'hCBB;
rommem[16382] <= 12'hFFF;
rommem[16383] <= 12'h023;
/rf6809/trunk/software/boot/keyboard.asm
0,0 → 1,509
; ============================================================================
; __
; \\__/ o\ (C) 2013-2022 Robert Finch, Waterloo
; \ __ / All rights reserved.
; \/_// robfinch<remove>@opencores.org
; ||
;
;
; Keyboard driver routines to interface to a PS2 style keyboard
; Converts the scancode to ascii
;
; This source file is free software: you can redistribute it and/or modify
; it under the terms of the GNU Lesser General Public License as published
; by the Free Software Foundation, either version 3 of the License, or
; (at your option) any later version.
;
; This source file is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with this program. If not, see <http://www.gnu.org/licenses/>.
;
; ============================================================================
;
SC_F12 EQU $07
SC_C EQU $21
SC_T EQU $2C
SC_Z EQU $1A
SC_DEL EQU $71 ; extend
SC_KEYUP EQU $F0 ; should be $f0
SC_EXTEND EQU $E0
SC_CTRL EQU $14
SC_RSHIFT EQU $59
SC_NUMLOCK EQU $77
SC_SCROLLLOCK EQU $7E
SC_CAPSLOCK EQU $58
SC_ALT EQU $11
 
;#define SC_LSHIFT EQU $12
;SC_DEL EQU $71 ; extend
;SC_LCTRL EQU $58
 
SC_TAB EQU $0D
 
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; Recieve a byte from the keyboard, used after a command is sent to the
; keyboard in order to wait for a response.
;
; Parameters: none
; Returns: accd = recieved byte ($00 to $FF), -1 on timeout
; Modifies: acc
; Stack Space: 2 words
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
KeybdRecvByte:
pshs x
ldx #100 ; wait up to 1s
krb3:
bsr KeybdGetStatus ; wait for response from keyboard
tstb
bmi krb4 ; is input buffer full ? yes, branch
bsr Wait10ms ; wait a bit
leax -1,x
bne krb3 ; go back and try again
ldd #-1 ; return -1
puls x,pc
krb4:
bsr KeybdGetScancode
puls x,pc
 
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; Send a byte to the keyboard.
;
; Parameters: accb byte to send
; Returns: none
; Modifies: none
; Stack Space: 0 words
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
KeybdSendByte:
stb KEYBD
rts
 
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; Wait until the keyboard transmit is complete
;
; Parameters: none
; Returns: r1 = 0 if successful, r1 = -1 timeout
; Modifies: r1
; Stack Space: 3 words
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
KeybdWaitTx:
pshs x
ldx #100 ; wait a max of 1s
kwt1:
bsr KeybdGetStatus
andb #$40 ; check for transmit complete bit; branch if bit set
bne kwt2
bsr Wait10ms ; delay a little bit
leax -1,x
bne kwt1 ; go back and try again
ldd #-1 ; timed out, return -1
puls x,pc
kwt2:
clra ; wait complete, return 0
clrb
puls x,pc
 
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; Wait for 10 ms
;
; Parameters: none
; Returns: none
; Modifies: none
; Stack Space: 2 words
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Wait10ms:
pshs d
lda MSCOUNT+3
W10_0001:
tfr a,b
subb MSCOUNT+3
cmpb #$FFA
bhi W10_0001
puls d,pc
 
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; Wait for 300 ms (256 ms)
;
; Parameters: none
; Returns: none
; Modifies: none
; Stack Space: 2 words
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Wait300ms:
pshs d
lda MSCOUNT+3
W300_0001:
tfr a,b
subb MSCOUNT+3
cmpb #$F00
bhi W300_0001
puls d,pc
 
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; Get the keyboard status
;
; Parameters: none
; Returns: d = status
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
KeybdGetStatus:
kbgs3:
ldb KEYBD+1
bitb #$80
bne kbgs1
bitb #$01 ; check parity error flag
bne kbgs2
clra
rts
kbgs2:
ldb #$FE ; request resend
bsr KeybdSendByte
bsr KeybdWaitTx
bra kbgs3
kbgs1: ; return negative status
orb #$F00
lda #-1
rts
 
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; Get the scancode from the keyboard port
;
; Parameters: none
; Returns: acca = scancode
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
KeybdGetScancode:
clra
ldb KEYBD ; get the scan code
clr KEYBD+1 ; clear receive register (write $00 to status reg)
; The following useful during debug.
; lbsr DispByteAsHex
; pshs b
; ldb #' '
; lbsr OUTCH
; puls b
rts
 
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; Set the LEDs on the keyboard.
;
; Parameters: d LED status to set
; Returns: none
; Modifies: none
; Stack Space: 2 words
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
KeybdSetLED:
pshs b
ldb #$ED ; set LEDs command
bsr KeybdSendByte
bsr KeybdWaitTx
bsr KeybdRecvByte ; should be an ack
puls b
bsr KeybdSendByte
bsr KeybdWaitTx
bsr KeybdRecvByte ; should be an ack
rts
 
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; Get ID - get the keyboards identifier code.
;
; Parameters: none
; Returns: d = $AB83, $00 on fail
; Modifies: d, KeybdID updated
; Stack Space: 2 words
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
KeybdGetID:
ldb #$F2
bsr KeybdSendByte
bsr KeybdWaitTx
bsr KeybdRecvByte
bitb #$80
bne kgnotKbd
cmpb #$AB
bne kgnotKbd
bsr KeybdRecvByte
bitb #$80
bne kgnotKbd
cmpb #$83
bne kgnotKbd
ldd #$AB83
kgid1:
std KeybdID
rts
kgnotKbd:
clra
clrb
bra kgid1
 
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; Initialize the keyboard.
;
; Parameters:
; none
; Modifies:
; none
; Returns:
; none
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
KeybdInit:
pshs d,y
ldy #5
kbdi0002:
bsr Wait10ms
clr KEYBD+1 ; clear receive register (write $00 to status reg)
ldb #-1 ; send reset code to keyboard
stb KEYBD+1 ; write $FF to status reg to clear TX state
bsr KeybdSendByte ; now write to transmit register
bsr KeybdWaitTx ; wait until no longer busy
bsr KeybdRecvByte ; look for an ACK ($FA)
cmpb #$FA
bne kbdiTryAgain
bsr KeybdRecvByte ; look for BAT completion code ($AA)
cmpb #$FC ; reset error ?
beq kbdiTryAgain
cmpb #$AA ; reset complete okay ?
bne kbdiTryAgain
 
; After a reset, scan code set #2 should be active
.config:
ldb #$F0 ; send scan code select
stb LEDS
bsr KeybdSendByte
bsr KeybdWaitTx
tstb
bmi kbdiTryAgain
bsr KeybdRecvByte ; wait for response from keyboard
tsta
bmi kbdiTryAgain
cmpb #$FA ; ACK
beq kbdi0004
kbdiTryAgain:
dey
bne kbdi0002
.keybdErr:
ldd #msgBadKeybd
lbsr DisplayStringCRLF
bra ledxit
kbdi0004:
ldb #2 ; select scan code set #2
bsr KeybdSendByte
bsr KeybdWaitTx
tstb
bmi kbdiTryAgain
bsr KeybdRecvByte ; wait for response from keyboard
tsta
bmi kbdiTryAgain
cmpb #$FA
bne kbdiTryAgain
bsr KeybdGetID
ledxit:
ldb #$07
bsr KeybdSetLED
bsr Wait300ms
ldb #$00
bsr KeybdSetLED
puls d,y,pc
 
msgBadKeybd:
fcb "Keyboard error",0
 
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
DBGCheckForKey:
bra KeybdGetStatus
 
 
; KeyState2 variable bit meanings
;1176543210
; ||||||||+ = shift
; |||||||+- = alt
; ||||||+-- = control
; |||||+--- = numlock
; ||||+---- = capslock
; |||+----- = scrolllock
; ||+------ = <empty>
; |+------- = "
; | = "
; | = "
; | = "
; +-------- = extended
 
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; Debug versison of keyboard get routine.
;
; Parameters:
; b: 0 = non blocking, otherwise blocking
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
DBGGetKey:
pshs x
dbgk2:
pshs b
bsr KeybdGetStatus
andb #$80 ; is key available?
puls b
bne dbgk1 ; branch if key
tstb ; block?
bne dbgk2 ; If no key and blocking - loop
ldd #-1 ; return -1 if no block and no key
puls x,pc
dbgk1:
bsr KeybdGetScancode
; lbsr DispByteAsHex
; Make sure there is a small delay between scancode reads
ldx #20
dbgk3:
dex
bne dbgk3
; switch on scan code
cmpb #SC_KEYUP
bne dbgk4
clr KeyState1 ; make KeyState1 = -1
neg KeyState1
bra dbgk2 ; loop back
dbgk4:
cmpb #SC_EXTEND
bne dbgk5
lda KeyState2
ora #$800
sta KeyState2
bra dbgk2
dbgk5:
cmpb #SC_CTRL
bne dbgkNotCtrl
tst KeyState1
bmi dbgk7
lda KeyState2
ora #4
sta KeyState2
bra dbgk8
dbgk7:
lda KeyState2
anda #~4
sta KeyState2
dbgk8:
clr KeyState1
bra dbgk2
dbgkNotCtrl:
cmpb #SC_RSHIFT
bne dbgkNotRshift
tst KeyState1
bmi dbgk9
lda KeyState2
ora #1
sta KeyState2
bra dbgk10
dbgk9:
lda KeyState2
anda #~1
sta KeyState2
dbgk10:
clr KeyState1
bra dbgk2
dbgkNotRshift:
cmpb #SC_NUMLOCK
bne dbgkNotNumlock
lda KeyState2
eora #16
sta KeyState2
lda KeyLED
eora #2
sta KeyLED
tfr a,b
clra
bsr KeybdSetLED
bra dbgk2
dbgkNotNumlock:
cmpb #SC_CAPSLOCK
bne dbgkNotCapslock
lda KeyState2
eora #32
sta KeyState2
lda KeyLED
eora #4
sta KeyLED
tfr a,b
clra
bsr KeybdSetLED
bra dbgk2
dbgkNotCapslock:
cmpb #SC_SCROLLLOCK
bne dbgkNotScrolllock
lda KeyState2
eora #64
sta KeyState2
lda KeyLED
eora #1
sta KeyLED
tfr a,b
clra
bsr KeybdSetLED
bra dbgk2
dbgkNotScrolllock:
cmpb #SC_ALT
bne dbgkNotAlt
tst KeyState1
bmi dbgk11
lda KeyState2
ora #2
sta KeyState2
bra dbgk12
dbgk11:
lda KeyState2
anda #~2
sta KeyState2
dbgk12:
clr KeyState1
bra dbgk2
dbgkNotAlt:
tst KeyState1
beq dbgk13
clr KeyState1
bra dbgk2
dbgk13:
lda KeyState2 ; Check for CTRL-ALT-DEL
anda #6
cmpa #6
bne dbgk14
cmpb #SC_DEL
bne dbgk14
jmp [$FFFFFE] ; jump to reset vector
dbgk14:
tst KeyState2 ; extended code?
bpl dbgk15
lda KeyState2
anda #$7FF
sta KeyState2
ldx #keybdExtendedCodes
bra dbgk18
dbgk15:
lda KeyState2 ; Is CTRL down?
bita #4
beq dbgk16
ldx #keybdControlCodes
bra dbgk18
dbgk16:
bita #1 ; Is shift down?
beq dbgk17
ldx #shiftedScanCodes
bra dbgk18
dbgk17:
ldx #unshiftedScanCodes
dbgk18:
abx
ldb ,x
clra
puls x,pc ; and return
/rf6809/trunk/software/boot/scancodes.asm
0,0 → 1,113
;--------------------------------------------------------------------------
; PS2 scan codes to ascii conversion tables.
;--------------------------------------------------------------------------
;
org (* + 127) & $FFFFFF80
 
unshiftedScanCodes:
fcb $2e,$a9,$2e,$a5,$a3,$a1,$a2,$ac
fcb $2e,$aa,$a8,$a6,$a4,$09,$60,$2e
fcb $2e,$2e,$2e,$2e,$2e,$71,$31,$2e
fcb $2e,$2e,$7a,$73,$61,$77,$32,$2e
fcb $2e,$63,$78,$64,$65,$34,$33,$2e
fcb $2e,$20,$76,$66,$74,$72,$35,$2e
fcb $2e,$6e,$62,$68,$67,$79,$36,$2e
fcb $2e,$2e,$6d,$6a,$75,$37,$38,$2e
fcb $2e,$2c,$6b,$69,$6f,$30,$39,$2e
fcb $2e,$2e,$2f,$6c,$3b,$70,$2d,$2e
fcb $2e,$2e,$27,$2e,$5b,$3d,$2e,$2e
fcb $ad,$2e,$0d,$5d,$2e,$5c,$2e,$2e
fcb $2e,$2e,$2e,$2e,$2e,$2e,$08,$2e
fcb $2e,$95,$2e,$93,$94,$2e,$2e,$2e
fcb $98,$7f,$92,$2e,$91,$90,$1b,$af
fcb $ab,$2e,$97,$2e,$2e,$96,$ae,$2e
 
fcb $2e,$2e,$2e,$a7,$2e,$2e,$2e,$2e
fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
fcb $2e,$2e,$fa,$2e,$2e,$2e,$2e,$2e
 
shiftedScanCodes:
fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
fcb $2e,$2e,$2e,$2e,$2e,$09,$7e,$2e
fcb $2e,$2e,$2e,$2e,$2e,$51,$21,$2e
fcb $2e,$2e,$5a,$53,$41,$57,$40,$2e
fcb $2e,$43,$58,$44,$45,$24,$23,$2e
fcb $2e,$20,$56,$46,$54,$52,$25,$2e
fcb $2e,$4e,$42,$48,$47,$59,$5e,$2e
fcb $2e,$2e,$4d,$4a,$55,$26,$2a,$2e
fcb $2e,$3c,$4b,$49,$4f,$29,$28,$2e
fcb $2e,$3e,$3f,$4c,$3a,$50,$5f,$2e
fcb $2e,$2e,$22,$2e,$7b,$2b,$2e,$2e
fcb $2e,$2e,$0d,$7d,$2e,$7c,$2e,$2e
fcb $2e,$2e,$2e,$2e,$2e,$2e,$08,$2e
fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
fcb $2e,$7f,$2e,$2e,$2e,$2e,$1b,$2e
fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
 
fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
 
; control
keybdControlCodes:
fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
fcb $2e,$2e,$2e,$2e,$2e,$09,$7e,$2e
fcb $2e,$2e,$2e,$2e,$2e,$11,$21,$2e
fcb $2e,$2e,$1a,$13,$01,$17,$40,$2e
fcb $2e,$03,$18,$04,$05,$24,$23,$2e
fcb $2e,$20,$16,$06,$14,$12,$25,$2e
fcb $2e,$0e,$02,$08,$07,$19,$5e,$2e
fcb $2e,$2e,$0d,$0a,$15,$26,$2a,$2e
fcb $2e,$3c,$0b,$09,$0f,$29,$28,$2e
fcb $2e,$3e,$3f,$0c,$3a,$10,$5f,$2e
fcb $2e,$2e,$22,$2e,$7b,$2b,$2e,$2e
fcb $2e,$2e,$0d,$7d,$2e,$7c,$2e,$2e
fcb $2e,$2e,$2e,$2e,$2e,$2e,$08,$2e
fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
fcb $2e,$7f,$2e,$2e,$2e,$2e,$1b,$2e
fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
 
keybdExtendedCodes:
fcb $2e,$2e,$2e,$2e,$a3,$a1,$a2,$2e
fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
fcb $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
fcb $2e,$95,$2e,$93,$94,$2e,$2e,$2e
fcb $98,$99,$92,$2e,$91,$90,$2e,$2e
fcb $2e,$2e,$97,$2e,$2e,$96,$2e,$2e
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.