; ****************************************************************************
;
;                                  ASM-includes
;
; ****************************************************************************

#include <avr/io.h>

; ===== Display

#define WIDTH	30	// number of characters per row (standard 32, max. 34)
#define HEIGHT	26	// number of rows (standard 24, max. 28)

; ===== Bit constants

#define	B0	0x1
#define	B1	0x2
#define	B2	0x4
#define	B3	0x8
#define	B4	0x10
#define	B5	0x20
#define	B6	0x40
#define	B7	0x80
#define	B8	0x100
#define	B9	0x200
#define	B10	0x400
#define	B11	0x800
#define	B12	0x1000
#define	B13	0x2000
#define	B14	0x4000
#define	B15	0x8000
#define B16	0x10000UL
#define B17	0x20000UL
#define B18	0x40000UL
#define	B19	0x80000UL
#define B20	0x100000UL
#define B21	0x200000UL
#define B22	0x400000UL
#define B23	0x800000UL
#define B24	0x1000000UL
#define B25	0x2000000UL
#define B26	0x4000000UL
#define B27	0x8000000UL
#define B28	0x10000000UL
#define B29	0x20000000UL
#define B30	0x40000000UL
#define B31	0x80000000UL

#define BIT(pos) (1<<(pos))

; ===== MOPs

#define	nop2		rjmp	.+0	; [2] shorter form of "nop nop"

; Wait before read from external RAM (needs minimal 3 clock cycles, or 4 clock cycles on lower voltage)
.macro READWAIT
	nop2
	nop2
.endm

; Wait before read from external RAM - without 1 clock cycle
.macro READWAIT1
	nop
	nop2
.endm

; Wait before read from external RAM - without 2 clock cycles
.macro READWAIT2
	nop2
.endm

; Wait before read from external RAM - without 3 clock cycles
.macro READWAIT3
	nop
.endm

; SPI enable/disable (value of SPCR register)
#define SPIEN	(BIT(SPE) | BIT(MSTR) | 0)
#define SPIDIS	(BIT(MSTR) | 0)

; new MCU type
#ifdef atmega8
#define MCU8
#else
#ifdef atmega88
#define MCU88
#else
#error Unsupported MCU!
#endif
#endif

; RAM address and size
#ifdef MCU8
#define RAM_BEG		0x0060	// SRAM begin
#else
#define RAM_BEG		0x0100	// SRAM begin
#endif
#define RAM_END		(RAMEND+1) // SRAM end + 1
#define RAM_SIZE	(RAM_END-RAM_BEG) // SRAM size

#define STACK		RAMEND // end of stack in RAM

; ROM address and  size
#define ROM_BEG		0x0000	// ROM begin
#define ROM_END		(FLASHEND+1) // ROM end + 1
#define ROM_SIZE	(ROM_END-ROM_BEG) // ROM size

; FLASH address and size
#define EEPROM_BEG	0x0000	// EEPROM begin
#define EEPROM_END	(E2END+1) // EEPROM end + 1
#define EEPROM_SIZE	(EEPROM_END-EEPROM_BEG)	// EEPROM size

; selected display (from configuration switch)
#define DISP_VGA2	0	// VGA ... not used
#define DISP_VGA	1	// VGA
#define DISP_NTSC	2	// NTSC
#define DISP_PAL	3	// PAL

#define DISP_TV		2	// TV mode (NTSC or PAL)

; offsets of video configuration structure
#define VC_HEND		0	// (u16) end of horizontal line (=HCYCLES-1, -> ICR1)
#define VC_HSYNCEND	2	// (u16) end of horizontal synchronization pulse (=HSYNCLEN-1, -> OCR1A)
#define VC_VLINES	4	// (u16) vertical lines total (=VLINES, -> VLines)
#define VC_VSYNCBEG	6	// (u16) start of VSYNC (=VLINES-VBP-VSYNCLEN, -> VSyncBeg)
#define VC_VSYNCEND	8	// (u16) end of VSYNC (=VLINES-VBP, -> VSyncEnd)

#define VC_SIZE		10	// size of configuration structure

#define KEYBUF_SIZE	16	// size of keyboard buffer (must be power of 2)
#define KEYBUF_MASK	(KEYBUF_SIZE-1)

; offset of EEPROM configuration structure
#define EE_SEED 	0	// (u8) random seed
#define EE_ROWS		1	// (u8) number of display rows (4..24)
#define EE_COLS		2	// (u8) number of display columns (8..32)
#define EE_HCENTER	3	// (s8) display horizontal center
#define EE_VCENTER	4	// (s8) display vertical center
#define EE_DISPMODE	5	// (u8) selected display mode (DISP_VGA,...)

#define EE_SIZE         8       // size of EEPROM structure

; ===== Offsets in data area Y

; Data area pointed by Y registers (DataStart, size max. 63 bytes)
#define DATA_VLINE	0	// (s16) current vertical line (= next processed video line)
#define DATA_FRAME	2	// (u16) current frame
#define DATA_DISPMODE	4	// (u8) current display mode (DISP_VGA, DISP_PAL, DISP_NTSC)
#define DATA_DISPROWS	5	// (u8) number of displayed rows (only to speed up computations)
#define DATA_VLINES	6	// (s16) total number of vertical lines
#define DATA_VVISIBLE	8	// (s16) number of visible lines
#define DATA_VSYNCBEG	10	// (s16) begin of vertical synchronization pulse
#define DATA_VSYNCEND	12	// (s16) end of vertical synchronization pulse
#define DATA_SNDINC	14	// (u16) sound pulse increment
#define DATA_SNDLEN	16	// (u8) sound length counter
#define DATA_KEYWRITE	17	// (u8) write offset into keyboard buffer
#define DATA_KEYREAD	18	// (u8) read offset from keyboard buffer
#define DATA_KEYRELPREF	19	// (u8) 0xf0=release prefix
#define DATA_KEYSHIFT	20	// (u8) SHIFT is pressed (scan code 0x12 or 0x59)
#define DATA_KEYALT	21	// (u8) ALT is pressed (scan code 0x11)
#define DATA_PAREND	22	// (u8) low of end address of parameters address
#define DATA_CURX	23	// (u8) cursor X coordinate
#define DATA_CURY	24	// (u8) cursor Y coordinate
#define DATA_CURVIS	25	// (u8) 0xff=cursor is visible
#define DATA_CURLINE	26	// (u16) address of current row with cursor
#define DATA_CURADDR	28	// (u16) cursor address
 #define DATA_BOARDEND	30	// (u16) end of board
#define DATA_VARADDR	30	// (u16) variables address
 #define DATA_VAREND	32	// (u16) end of variables
#define DATA_EDITADDR	32	// (u16) edit line address
 #define DATA_EDITEND	34	// (u16) end of edit line
#define DATA_STKADDR	34	// (u16) calculator stack address
 #define DATA_STKEND	36	// (u16) end of calculator stack
#define DATA_MEMTOP	36	// (u16) top of allocated memory address
#define DATA_ERRCODE	38	// (u8) error vode
#define DATA_FLAGS	39	// (u8) flags
#define DATA_EXECLINE	40	// (u16) line number of the current statement
#define DATA_PARADDR	42	// (u16) scanning parameters address
#define DATA_MEMADDR	44	// (u16) pointer to calculator numbers (stack or variables)
#define DATA_CALCPAR	46	// (u8) calculator parameter
#define DATA_OUTBUFNUM	47	// (u8) number of bytes in output buffer

; Offset of pointers
#define OFF_CURLINE 0		// (u16) DATA_CURLINE address of current row with cursor
#define OFF_CURADDR 2		// (u16) DATA_CURADDR cursor address
#define OFF_VARADDR 4		// (u16) DATA_VARADDR variables
#define OFF_EDITADDR 6		// (u16) DATA_EDITADDR edit line, workspace
#define OFF_STKADDR 8		// (u16) DATA_STKADDR calculator stack
#define OFF_MEMTOP 10		// (u16) DATA_MEMTOP end of allocated memory

; ===== Characters

; Character set (characters are ASCII compatible)
;   Pattern pixels:
;	1 2
;	3 4

; Control codes
#define CH_NUL		0x00	// invalid character
#define CH_HOME		0x01	// start of row, key Home
#define CH_LEFT		0x02	// kurzor left, key Left
#define CH_BREAK	0x03	// Break program, key Shift+Break (Shift+Pause, Shift+NumLock)
#define CH_LINE		0x04	// insert row, Shift+Enter
#define CH_END		0x05	// end of row, key End
#define CH_PGDN		0x06	// page end, key Page Down
;			0x07
#define CH_BS		0x08	// delete previous character, key BackSpace
#define CH_TB		0x09	// key Tab
#define CH_DOWN		0x0a	// cursor down, key Down
#define CH_DELROW	0x0b	// delete rest of row, key Shift+BackSpace
#define CH_FF		0x0c	// clear screen, key Shift+Scroll
#define CH_ENTER	0x0d	// new line, key Enter
#define CH_RIGHT	0x0e	// kurzor right, key Right
#define CH_BACKTB	0x0f	// key Shift+Tab
;			0x10
#define CH_SCROLLUP	0x11	// scroll screen up, key Scroll
#define CH_PGUP		0x12	// page begin, key Page Up
#define CH_PAU		0x13	// pause program or listing, key Pause
;			0x14
#define CH_UP		0x15	// key Up
#define CH_INSERT	0x16	// insert character, key Insert
;			0x17
;			0x18
#define CH_DELETE	0x19	// delete next character, key Delete
;			0x1a
;			0x1b	// Esc
;			0x1c
#define CH_SHIFT	0x1d	// upper characters, key Shift
#define CH_ALT		0x1e	// inverse characters, key Alt
;			0x1f	// Control

; Printable characters
#define CH_SPC		0x20	// space
#define CH_0000		CH_SPC	// pattern 0000
#define CH_1000		0x21	// pattern 1000
#define CH_QUOT		0x22	// " (string separator)
#define CH_0100		0x23	// pattern 0100
#define CH_DOLLAR	0x24	// $ (string variable)
#define CH_1100		0x25	// pattern 1100
#define CH_POUND	0x26	// pound
#define CH_0010		0x27	// pattern 0010
#define CH_LPAR		0x28	// ( (left parenthesis)
#define CH_RPAR		0x29	// ) (right parenthesis)
#define CH_ASTER	0x2a	// * (multiplication)
#define CH_PLUS		0x2b	// + (addition)
#define CH_COMMA	0x2c	// , (parameter separator, print separator - tabled)
#define CH_MINUS	0x2d	// - (substract or negation)
#define CH_DOT		0x2e	// . (decimal dot)
#define CH_SLASH	0x2f	// / (division)
#define CH_0		0x30	// 0 (number 0)
#define CH_1		0x31	// 1 (number 1)
#define CH_2		0x32	// 2 (number 2)
#define CH_3		0x33	// 3 (number 3)
#define CH_4		0x34	// 4 (number 4)
#define CH_5		0x35	// 5 (number 5)
#define CH_6		0x36	// 6 (number 6)
#define CH_7		0x37	// 7 (number 7)
#define CH_8		0x38	// 8 (number 8)
#define CH_9		0x39	// 9 (number 9)
#define CH_COLON	0x3a	// :
#define CH_SEMI		0x3b	// ; (print separator - immediately)
#define CH_LT		0x3c	// < (less)
#define CH_EQU		0x3d	// = (equal or assign)
#define CH_GR		0x3e	// > (greater)
#define CH_QUERY	0x3f	// ?
#define CH_1010		0x40	// pattern 1010
#define CH_A		0x41	// A
#define CH_B		0x42	// B
#define CH_C		0x43	// C
#define CH_D		0x44	// D
#define CH_E		0x45	// E
#define CH_F		0x46	// F
#define CH_G		0x47	// G
#define CH_H		0x48	// H
#define CH_I		0x49	// I
#define CH_J		0x4a	// J
#define CH_K		0x4b	// K
#define CH_L		0x4c	// L
#define CH_M		0x4d	// M
#define CH_N		0x4e	// N
#define CH_O		0x4f	// O
#define CH_P		0x50	// P
#define CH_Q		0x51	// Q
#define CH_R		0x52	// R
#define CH_S		0x53	// S
#define CH_T		0x54	// T
#define CH_U		0x55	// U
#define CH_V		0x56	// V
#define CH_W		0x57	// W
#define CH_X		0x58	// X
#define CH_Y		0x59	// Y
#define CH_Z		0x5a	// Z
#define CH_0110		0x5b	// pattern 0110
#define CH_1110		0x5c	// pattern 1110
#define CH_GRID		0x5d	// grid
#define CH_GRIDDN	0x5e	// grid down
#define CH_GRIDUP	0x5f	// grid up

; ---- start of printable tokens

; Operators I (no leading space, no trailing space)
#define CH_DBLASTER	0x60	// ** (power) (double asterisk)
#define CH_LTEQU	0x61	// <= (less or equal)
#define CH_GREQU	0x62	// >= (greater or equal)
#define CH_NEQU		0x63	// <> (not equal)

; Functions I, without parameter (no leading space, no trailing space)
#define CH_INKEY	0x64	// INKEY$ read text from keyboard
#define CH_MEM		0x65	// MEM free memory
#define CH_PI		0x66	// PI pi number
#define CH_RND		0x67	// RND random number 0<=y<1

; ... Start of tokens with trailing space character
; Functions II, with parameter (no leading space character, print trailing space)
#define CH_ABS		0x68	// ABS absolute value
#define CH_ACS		0x69	// ACS arccosine
#define CH_ASN		0x6a	// ASN arcsine
#define CH_ATN		0x6b	// ATN arctangent
#define CH_CHR		0x6c	// CHR$ character from code 0..255
#define CH_CODE		0x6d	// CODE code from first character
#define CH_COS		0x6e	// COS cosine
#define CH_EXP		0x6f	// EXP natural exponent ex
#define CH_INT		0x70	// INT integer part
#define CH_LEN		0x71	// LEN length of text
#define CH_LN		0x72	// LN natural logarithm
#define CH_SGN		0x73	// SGN sign -1, 0, +1
#define CH_SIN		0x74	// SIN sine
#define CH_SQR		0x75	// SQR square root
#define CH_STR		0x76	// STR$ string from number
#define CH_TAN		0x77	// TAN tangent
#define CH_VAL		0x78	// VAL number from string
#define CH_NOT		0x79	// NOT (no leading space)
; PEEK unsupported
; USR unsupported

; ... Start of tokens with leading space character
; Operators II (print leading space, print trailing space)
#define CH_AND		0x7a	// AND
#define CH_OR		0x7b	// OR

; Statements
#define CH_BEEP		0x7c	// BEEP
#define CH_CLEAR	0x7d	// CLEAR
#define CH_CLS		0x7e	// CLS
#define CH_CONT		0x7f	// CONT
#define CH_DIM		0x80	// DIM
#define CH_FOR		0x81	// FOR
#define CH_GOSUB	0x82	// GOSUB
#define CH_GOTO		0x83	// GOTO
#define CH_IF		0x84	// IF
#define CH_INPUT	0x85	// INPUT
#define CH_LET		0x86	// LET
#define CH_LIST		0x87	// LIST
#define CH_LOAD		0x88	// LOAD
#define CH_NEXT		0x89	// NEXT
#define CH_NEW		0x8a	// NEW
#define CH_PAUSE	0x8b	// PAUSE
#define CH_PLOT		0x8c	// PLOT
#define CH_PRINT	0x8d	// PRINT
#define CH_RAND		0x8e	// RAND
#define CH_REM		0x8f	// REM
#define CH_RETURN	0x90	// RETURN
#define CH_ROWS		0x91	// ROWS
#define CH_RUN		0x92	// RUN
#define CH_SAVE		0x93	// SAVE
#define CH_SCROLL	0x94	// SCROLL
#define CH_STOP		0x95	// STOP
#define CH_UNPLOT	0x96	// UNPLOT
; POKE unsupported

; Specials
#define CH_STEP		0x97	// STEP
#define CH_THEN		0x98	// THEN
#define CH_TO		0x99	// TO
; ... Stop of tokens with leading space character
#define CH_AT		0x9a	// AT
#define CH_TAB		0x9b	// TAB

; ----- end of printable tokens

; printable tokens
#define TOKEN_FIRST	0x60	// first printable token
#define TOKEN_LAST	0x9b	// last printable token
;#define TOKEN_NUM	(TOKEN_LAST-TOKEN_FIRST+1) // number of printable tokens
#define TOKEN_FIRSTSPC	0x7a	// first token to print leading space
#define TOKEN_LASTSPC	0x99	// last token to print leading space
#define TOKEN_FIRSTTRAIL 0x68	// first token to print trailing space

; Invisible tokens
#define CH_TEXT		0x9c	// text constant (1 byte length + text follow)
#define CH_NUMBER	0x9d	// numeric constant (5 bytes follow)
#define CH_NUMB		0x9e	// byte numeric constant (1 byte follow)
#define CH_NUMW		0x9f	// word numeric constant (2 bytes follow)

; Inverse printable characters 0xa0..0xbf
#define CH_INVSPC	0xa0	// inverse space

; Pixel patterns
;#define CH_0000	0x20	// pattern 0000
;#define CH_1000	0x21	// pattern 1000
;#define CH_0100	0x23	// pattern 0100
;#define CH_1100	0x25	// pattern 1100
;#define CH_0010	0x27	// pattern 0010
;#define CH_1010	0x40	// pattern 1010
;#define CH_0110	0x5b	// pattern 0110
;#define CH_1110	0x5c	// pattern 1110
#define CH_1111		0xa0	// pattern 1111
#define CH_0111		0xa1	// pattern 0111
#define CH_1011		0xa3	// pattern 1011
#define CH_0011		0xa5	// pattern 0011
#define CH_1101		0xa7	// pattern 1101
#define CH_0101		0xc0	// pattern 0101
#define CH_1001		0xdb	// pattern 1001
#define CH_0001		0xdc	// pattern 0001

; Pattern table:
;	CH_0000,
;	CH_0001,
;	CH_0010,
;	CH_0011,
;	CH_0100,
;	CH_0101,
;	CH_0110,
;	CH_0111,
;	CH_1000,
;	CH_1001,
;	CH_1010,
;	CH_1011,
;	CH_1100,
;	CH_1101,
;	CH_1110,
;	CH_1111,

; Commands part 2
;#define CH_MEM		0xe0	// MEM (view memory info)


; ===== Calculator literals

; ... control operations
; .... #define C_JUMPT		0	// 0x00 relative jump if true (redefined to 41 !)
#define C_NOP		0	// 0x00 no function (required by byte align)
#define C_EXC		1	// 0x01 exchange 2 top numbers
#define C_DEL		2	// 0x02 delete top number
; ... 2 operands (binary operations)
#define C_SUB		3	// 0x03 - subtract
#define C_MUL		4	// 0x04 * multiply
#define C_DIV		5	// 0x05 / division
#define C_POW		6	// 0x06 ** power (uses MEM0 MEM1 MEM2 MEM3)
#define C_OR		7	// 0x07 OR
#define C_AND		8	// 0x08 AND
#define C_LTEQ		9	// 0x09 <= (comparison codes are hardcoded in function CalcCmp)
#define C_GREQ		10	// 0x0A >=
#define C_NEQU		11	// 0x0B <>
#define C_GR		12	// 0x0C >
#define C_LT		13	// 0x0D <
#define C_EQU		14	// 0x0E =
#define C_ADD		15	// 0x0F +
#define C_SAND		16	// 0x10 string AND
#define C_SLTEQ		17	// 0x11 string <= (comparison codes are hardcoded in function CalcCmp)
#define C_SGREQ		18	// 0x12 string >=
#define C_SNEQU		19	// 0x13 string <>
#define C_SGR		20	// 0x14 string >
#define C_SLT		21	// 0x15 string <
#define C_SEQU		22	// 0x16 string =
#define C_SADD		23	// 0x17 string +
; ... 1 operand (unary operations)
#define C_NEG		24	// 0x18 unary- (NEG)
#define C_CODE		25	// 0x19 CODE
#define C_VAL		26	// 0x1A VAL
#define C_LEN		27	// 0x1B LEN
#define C_SIN		28	// 0x1C SIN (uses MEM0 MEM1 MEM2)
#define C_COS		29	// 0x1D COS (uses MEM0 MEM1 MEM2)
#define C_TAN		30	// 0x1E TAN (uses MEM0 MEM1 MEM2)
#define C_ASN		31	// 0x1F ASN (uses MEM0 MEM1 MEM2 MEM3)
#define C_ACS		32	// 0x20 ACS (uses MEM0 MEM1 MEM2 MEM3)
#define C_ATN		33	// 0x21 ATN (uses MEM0 MEM1 MEM2)
#define C_LN		34	// 0x22 LN (uses MEM0 MEM1 MEM2)
#define C_EXP		35	// 0x23 EXP (uses MEM0 MEM1 MEM2 MEM3)
#define C_INT		36	// 0x24 INT (uses MEM0)
#define C_SQR		37	// 0x25 SQR (uses MEM0 MEM1 MEM2 MEM3)
#define C_SGN		38	// 0x26 SGN
#define C_ABS		39	// 0x27 ABS
#define C_PEEK		40	// 0x28 PEEK ... unsupported
; .... #define C_USR		41	// 0x29 USR ... unsupported, replaced by C_JUMPT function
#define C_JUMPT		41	// 0x29 relative jump if true (redefined from code 0 !) (warning - offset is relative to next byte, not to offset byte as in ZX81!)
#define C_STR		42	// 0x2A STR$
#define C_CHR		43	// 0x2B CHR$
#define C_NOT		44	// 0x2C NOT
; ... control operations
#define C_DUP		45	// 0x2D duplicate
#define C_MOD		46	// 0x2E modulus (uses MEM0 MEM1)
#define C_JMP		47	// 0x2F relative jump (warning - offset is relative to next byte, not to offset byte as in ZX81!)
#define C_DATA		48	// 0x30 stack data
; Format of 1st byte of the number C_DATA:
;  	B7,B6 = length - 1 (= length 1..4 bytes)
;	B5..B0 = exponent - 80 (range 81..143); if exponent=0 -> get exponent-80 from following byte
;  Follow 1..4 bytes of the number, rest bytes fill with 0.
#define C_LOOP		49	// 0x31 dec jump_nz (warning - offset is relative to next byte, not to offset byte as in ZX81!)
#define C_LT0		50	// 0x32 less 0
#define C_GR0		51	// 0x33 greater 0
#define C_END		52	// 0x34 end calc
#define C_ARG		53	// 0x35 get arg (uses MEM0)
#define C_TRUNC		54	// 0x36 truncate
#define C_TO		55	// 0x37 jump by register value (warning - offset is relative to next byte, not to offset byte as in ZX81!)
#define C_EFP		56	// 0x38 E to fp (uses MEM0 MEM1)
; ... groups (compound literals)
;	bit 7: flag of compound literal
;	bit 5..6: group 0..3
;	bit 0..4: parameter 0..31
#define C_SERIE_GRP	57	// 0x39 series (literal 0x80..0x9f) (uses MEM0 MEM1 MEM2)
#define C_CONSTAB_GRP	58	// 0x3A stack tabled constant (literal 0xa0..0xbf)
#define C_SETMEM_GRP	59	// 0x3B set memory from stack (literal 0xc0..0xdf, parameter is offset of the number, Note: Multiply index from ZX81 by 5)
#define C_GETMEM_GRP	60	// 0x3C get number from memory into stack (literal 0xe0..0xff, parameter is offset of the number, Note: Multiply index from ZX81 by 5)

#define C_UNARY_FIRST	C_NEG	// first unary operation
#define C_GROUP_BASE	C_SERIE_GRP // first group operation

#define C_CONST(len, exp) (((len-1)<<6)+exp-80) // 1st byte of constant (len=length 1..4, exponent must be in range 81..143)
; If exponent is out of range 81..143, then use exponent 80 and real exponent-80 store into next byte.

#define C_SERIE(par) (B7+((C_SERIE_GRP-C_GROUP_BASE)<<5)+par)  // series (par=number of loops)
#define C_CONSTAB(par) (B7+((C_CONSTAB_GRP-C_GROUP_BASE)<<5)+par)  // stack tabled constant (par=offset of constant)
#define C_SETMEM(par) (B7+((C_SETMEM_GRP-C_GROUP_BASE)<<5)+par*5)  // set memory from stack (par=index of number)
#define C_GETMEM(par) (B7+((C_GETMEM_GRP-C_GROUP_BASE)<<5)+par*5)  // get number from memory into stack (par=index of number)

; Offsets of constants
#define CONST_0		0	// (3) offset of constant 0
#define CONST_1		3	// (2) offset of constant 1
#define CONST_05	5	// (2) offset of constant 0.5
#define CONST_10	7	// (2) offset of constant 10
#define CONST_PI2	9	// (5) offset of constant pi/2

#define CONST_2		14	// (2) offset of constant 2 (not used)

; Stack reserve
#define STACKRES	34	// video interrupt 15 bytes, DispNum 14 bytes

; Program line (offset and length is aligned to 2 bytes)
#define PG_LINE_L	0	// (u8) line number low
#define PG_LINE_H	1	// (u8) line number high + line length
				// 	B0..B3: line length/2 (2..32 bytes)
				//	B4..B7: line number high 4 bits (line number is 1..4094)
#define PG_CODE		2	// (0..30 bytes, even number)
; Code is aligned to 2 bytes, may be finished by a space character

; error codes (reported code will be incremented by 1)
#define ERR_OK		-1	// 0xff '0' OK
#define ERR_NEXTFOR	0	// 0x00 '1' NEXT without FOR
#define ERR_VARNFND	1	// 0x01 '2' Variable not found
#define ERR_SUBSCR	2	// 0x02 '3' Subscript out of range
#define ERR_MEM		3	// 0x03 '4' Out of memory
#define ERR_OUTSCREEN	4	// 0x04 '5' Out of screen
#define ERR_OVERFLOW	5	// 0x05 '6' Arithmetic overflow
#define ERR_RETGOSUB	6	// 0x06 '7' RETURN without GOSUB
#define ERR_INPUTCMD	7	// 0x07 '8' INPUT as a command
#define ERR_STOP	8	// 0x08 '9' STOP statement
#define ERR_INVARG	9	// 0x09 'A' Invalid argument
#define ERR_INTOUT	10	// 0x0a 'B' Integer out of range
#define ERR_INVEXP	11	// 0x0b 'C' Invalid expression
#define ERR_BREAK	12	// 0x0c 'D' BREAK interrupt
#define ERR_OUTDATA	13	// 0x0d 'E' Out of DATA (READ past end of DATA)
#define ERR_NONAME	14	// 0x0e 'F' No program name supplied
#define ERR_PROGMEM	15	// 0x0f 'G' Out of program memory

;#define ERR_NOROOM	15	// 0x0f 'G' No room for line
;#define ERR_STOPINPUT	16	// 0x10 'H' STOP in INPUT
;#define ERR_FORNEXT	17	// 0x11 'I' FOR without NEXT
;#define ERR_INVIO	18	// 0x12 'J' Invalid I/O device (undocumented)
;#define ERR_INVCOLOR	19	// 0x13 'K' Invalid colour
;....#define ERR_BREAK	20	// 0x14 'L' BREAK into program (BREAK pressed)
;#define ERR_RAMTOP	21	// 0x15 'M' RAMTOP no good
;#define ERR_LOST	22	// 0x16 'N' Statement lost
;#define ERR_INVSTREAM	23	// 0x17 'O' Invalid stream (undocumented)
;#define ERR_FNDEF	24	// 0x18 'P' FN without DEF
;#define ERR_PARERR	25	// 0x19 'Q' Parameter error (user-defined function was given wrong number of arguments or bad type)
;#define ERR_TAPEERR	26	// 0x1a 'R' Tape loading error

#define FLOAT_SIZE	5	// size of float number

#define EXPBIAS		0x81	// exponent bias

#define ENDVARS		0x80	// mark end of variables

#define NUMMAXLEN	16	// max. length of printed float number

#define ROWMAX		4094	// max. row number
#define ROWSTOP		4095	// number of stop row in EEPROM (= 0x0fff)


#if 0
Programovy radek:
0: (1) cislo radku HIGH (pokud je < 0x40)
1: (1) cislo radku LOW
2: (1) delka (bez tohoto zahlavi) (pole max. 50, tj. index 0..50)
4: (x) text


(000,001) 0x00..0x3f: programovy radek
	Ciselna konstanta je v programu ulozena v binarni forme, prefix znak $7E (=CH_NUMBER) nasledovany 5 bajty
(010) 0x46..0x5f: string promenna, nasleduje word delka
(011) 0x66..0x7f: 1-znakova ciselna promenna, nasleduje 5 bajtu cislo
0x80: oznaceni konce pole promennych
(100) 0x86..0x9f: pole ciselnych promennych, nasleduje WORD s delkou,
		byte s poctem dimenzi D, D x word dimenze, elementy po 5 bajtech
(101) 0xa6..0xbf: viceznakova ciselna promenna, posledni pismeno nastaveny bit 7, nasleduje 5 bajtu cislo
(110) 0xc6..0xcf: pole znaku, nasleduje WORD pocet elementu,
		byte s poctem dimenzi D, D x word dimenze, elementy po 1 bajtu
(111) 0xe6..0xff: promenna FOR-NEXT, nasleduje 5 B hodnota, 5 B limit, 5 B krok, 2 B radek loop


nejvyssi 3 bity jsou typ, nizsich 5 bitu je pismeno 1..26 = A..Z

B7=je delka
B6=viceznakove jmeno
B5


0 program
2 1-znak string (delka)
3 1-znak cislo (5 B)
4 1-znak pole cisel (delka)
5 viceznakove cislo (5 B)
7 1-znak for-next

6 1-znak pole znaku (delka)


#endif





; ===== Registers
; Y = reserved as pointer to data area
; R0, R1 = temporary, result of multiplication, destroyed
#define R_ZERO	R2	// '0' register
#define R_ONE	R3	// '1' register
#define R_LITL	R4	// literal pointer LOW (must be LOW to R_LITH)
#define R_LITH	R5	// literal pointer HIGH (must be HIGH to R_LITL)
#define R_MINUS	R6	// '-1' (0xff) register

; Registers of functions ADD, SUB, NUL and DIV
#define R_EXH	r27	// result exponent HIGH (=XH), must be HIGH to R_EXL
#define R_EXL	r26	// result exponent LOW (=XL), must be LOW to R_EXH

#define R_MTT	R_EXH	// temporary register in function CalcMul and CalcDiv (loop counter, must be = R_EXH)

#define R_AT1	r25	// temporary register in function CalcPrepAdd
#define R_AT2	r24	// temporary register in function CalcPrepAdd
#define R_AT3	r23	// temporary register in function CalcPrepAdd
#define R_AT4	r20	// temporary register in function CalcPrepAdd

#define R_AX2	r22	// 2nd number exponent in function ADD/SUB, number of shifts in CalcAddShift
#define R_AX1	r21	// 1st number exponent in function ADD/SUB

#define R_MT2	r25	// temporary result in function CalcMul and CalcDiv, must be HIGH to R_MT3
#define R_MT3	r24	// temporary result in function CalcMul and CalcDiv, must be LOW to R_MT2
#define R_MT4	r23	// temporary result in function CalcMul and CalcDiv, must be HIGH to R_MT5
#define R_MT5	r22	// temporary result in function CalcMul and CalcDiv, must be LOW to R_MT4

#define R_MT	r22	// temporary register in function CalcPrepMul
#define R_MS	r21	// temporary sign in function CalcMul, CalcDiv and CalcPrepMul, temporary loop counter in CalcMul

; 1st number and result - pointed by Z
#define R_M1	r20	// 1st number and result, 1st byte, exponent or sign
#define R_M2	r19	// 1st number and result, 2nd byte, must be HIGH to R_M3
#define R_M3	r18	// 1st number and result, 3rd byte, must be LOW to R_M2
#define R_M4	r17	// 1st number and result, 4th byte, must be HIGH to R_M5
#define R_M5	r16	// 1st number and result, 5th byte, must be LOW to R_M4

#define R_M6	r15	// result extra byte of mantissa in function MUL

; 2nd number - pointed by X, will be deleted
#define R_N1	r14	// 2nd number, 1st byte, exponent
#define R_N2	r13	// 2nd number, 2nd byte
#define R_N3	r12	// 2nd number, 3rd byte
#define R_N4	r11	// 2nd number, 4th byte
#define R_N5	r10	// 2nd number, 5th byte
