
; ******** Source: basic_tms.asm
     1                          ; Troy's HBC-56 - BASIC
     2                          ;
     3                          ; Copyright (c) 2021 Troy Schrapel
     4                          ;
     5                          ; This code is licensed under the MIT license
     6                          ;
     7                          ; https://github.com/visrealm/hbc-56
     8                          ;
     9                          
    10                          

; ******** Source: basic_hbc56_core.asm
     1                          ; Troy's HBC-56 - BASIC
     2                          ;
     3                          ; Copyright (c) 2021 Troy Schrapel
     4                          ;
     5                          ; This code is licensed under the MIT license
     6                          ;
     7                          ; https://github.com/visrealm/hbc-56
     8                          ;
     9                          

; ******** Source: ../kernel\hbc56kernel.inc
     1                          ; 6502 - HBC-56 Kernel Include file for user code
     2                          ;
     3                          ; Copyright (c) 2021 Troy Schrapel
     4                          ;
     5                          ; This code is licensed under the MIT license
     6                          ;
     7                          ; https://github.com/visrealm/hbc-56
     8                          ;
     9                          ;
    10                          
    11                          !cpu w65c02
    12                          !initmem $FF
    13                          cputype = $65c02
    14                          

; ******** Source: ../kernel\kernel.o.lmap
     1                          	HBC56_RST_VECTOR	= $f177	; ?
     2                          	AY_ENV_SHAPE_SAW1	= $8	; unused
     3                          	tmsConsoleBackspace	= $ea63	; ?
     4                          	NES_RAM_SIZE	= $1
     5                          	UART_ZP_START	= $28
     6                          	TMS_LT_RED	= $9	; unused
     7                          	UART_STATUS_RCVR_OVERRUN	= $20	; unused
     8                          	HBC56_TMP	= $7ca2
     9                          	KB_SCANCODE_ESC	= $76	; unused
    10                          	AY_ENV_SHAPE_SAW2	= $c	; unused
    11                          	TMS_GFX_TILE_WIDTH	= $8
    12                          	LCD_RAM_END	= $7b58
    13                          	TMS_SPRITE_SIZE	= $8
    14                          	KB_SCANCODE_ARROW_RIGHT	= $f4	; unused
    15                          	KB_CAPS_LOCK	= $8
    16                          	KB_EXT_KEY	= $e0
    17                          	VIA_RAM_SIZE	= $1
    18                          	HBC56_VSYNC_CALLBACK	= $7cb9
    19                          	isLower	= $e000
    20                          	TMS_R1_SPRITE_MAG2	= $1	; unused
    21                          	KB_BUFFER_MASK	= $f
    22                          	KB_SCANCODE_SLASH_FORWARD	= $4a	; unused
    23                          	AY_PORTB	= $f	; unused
    24                          	TMS_R1_RAM_16K	= $80
    25                          	AY_PORTA	= $e	; unused
    26                          	TMS_R1_SPRITE_MAG1	= $0	; unused
    27                          	TMS_FPS	= $3c
    28                          	kbInit	= $eb3b
    29                          	VIA_TMP	= $7c58	; unused
    30                          	tmsSetAddressNextRow	= $e586	; unused
    31                          	UART_IRQ_BIT	= $4
    32                          	tmsModeText	= $e6b8	; unused
    33                          	VIA_REG_IFR	= $d
    34                          	_tmsSendKb	= $e71b	; ?
    35                          	UART_STATUS_RX_REG_FULL	= $1
    36                          	tmsReg1SetFields	= $e5e5
    37                          	BITMAP_ZP_START	= $1e
    38                          	JMP_OPCODE	= $4c
    39                          	hbc56IntHandler	= $f0f6
    40                          	TILEMAP_RAM_START	= $7a00
    41                          	KB_SCANCODE_SCROLL_LOCK	= $7e	; unused
    42                          	KB_RAM_END	= $7c9c
    43                          	AY_ENV_SHAPE_HOLD	= $1
    44                          	TMS_R0_MODE_GRAPHICS_II	= $2
    45                          	KB_SHIFT_LEFT_MAP_BYTE	= $2
    46                          	VIA_IO_ADDR_IFR	= $7ffd	; unused
    47                          	VIA_IO_ADDR_T1C_H	= $7ff5	; unused
    48                          	MEMORY_ZP_END	= $32
    49                          	TMS_R1_SPRITE_8	= $0	; unused
    50                          	VIA_REG_T1L_H	= $7
    51                          	KB_SCANCODE_PRTSCR	= $92	; unused
    52                          	KB_SCANCODE_SLASH_BACK	= $5d	; unused
    53                          	VIA_IO_ADDR_T1C_L	= $7ff4	; unused
    54                          	AY_WRITE	= $1
    55                          	UART_STATUS_CARRIER_DETECT	= $4	; unused
    56                          	VIA_REG_T1L_L	= $6
    57                          	KB_PRESSED_MAP	= $7c76
    58                          	TMS9918_ZP_START	= $24
    59                          	tmsDecPosConsole	= $e941
    60                          	UART_CTL_WORD_8BIT_1SB	= $14	; unused
    61                          	HBC56_CONSOLE_FLAG_LCD	= $20	; unused
    62                          	TMS_CYAN	= $7
    63                          	HBC56_TITLE	= $ee10
    64                          	memcpyMultiPage	= $e0bf	; unused
    65                          	KB_SCANCODE_NUM_LOCK	= $77	; unused
    66                          	TILEMAP_RAM_END	= $7b16
    67                          	VIA_DIR_OUTPUT	= $ff	; unused
    68                          	KB_BUFFER_TAIL	= $7c65
    69                          	tmsSetRegister	= $e5bc
    70                          	hbc56Tms9918Int	= $f127	; ?
    71                          	KB_SCANCODE_NUMPAD_ENTER	= $da	; unused
    72                          	UART_STATUS_TX_REG_EMPTY	= $2
    73                          	UART_RX_BUFFER_XOFF_SIZE	= $c0
    74                          	KB_FLAGS	= $7c5c
    75                          	HBC56_NMI_VECTOR	= $7e04
    76                          	KB_SCANCODE_SQUARE_LEFT	= $54	; unused
    77                          	BITMAP_ZP_END	= $24
    78                          	UART_CTL_CLOCK_DIV_64	= $2
    79                          	toUpper	= $e06b	; unused
    80                          	VIA_IO_ADDR	= $7ff0
    81                          	tableBitsFromLeft	= $e150	; unused
    82                          	NES_TMP	= $7c9c	; unused
    83                          	HBC56_META_TITLE_END	= $7cb7
    84                          	uartFlowCtrlXoff	= $eac4	; ?
    85                          	SFXMAN_RAM_START	= $7c59
    86                          	uartInWait	= $eacd
    87                          	uartOutString	= $eb11	; unused
    88                          	RTI_OPCODE	= $40
    89                          	KB_SCANCODE_PAGE_UP	= $fd	; unused
    90                          	AY_ENV_SHAPE_FADE_OUT	= $9	; unused
    91                          	tmsModeBitmap	= $e623	; unused
    92                          	TMS_VRAM_SPRITE_ATTR_ADDRESS	= $3b00
    93                          	NOTE_FREQ_AS8	= 7458.619999999999890860635787248611	; unused
    94                          	HBC56_TMP_Y	= $7ca5
    95                          	KB_SCANCODE_TILDE	= $e	; unused
    96                          	HBC56_TITLE_LEN	= $1a
    97                          	UART_IO_PORT	= $20
    98                          	TMS9918_RAM_END	= $7b58
    99                          	AY_S0_ADDR	= $7f40	; unused
   100                          	TMS9918_ZP_SIZE	= $2
   101                          	HBC56_TMP_X	= $7ca4
   102                          	NOTE_FREQ_AS5	= 932.330000000000040927261579781771	; unused
   103                          	TMS_MED_GREEN	= $2	; unused
   104                          	TMS_WHITE	= $f
   105                          	KB_SCANCODE_WINDOWS_RIGHT	= $a7	; unused
   106                          	HBC56_KERNEL_ZP_END	= $36
   107                          	AY_S1_WRITE	= $7f45	; unused
   108                          	NOTE_FREQ_AS4	= 466.160000000000025011104298755527	; unused
   109                          	VIA_REG_DDR_B	= $2
   110                          	NOTE_FREQ_AS7	= 3729.309999999999945430317893624306	; unused
   111                          	TMS_TMP_ADDRESS	= $24
   112                          	KB_SCANCODE_PERIOD	= $49	; unused
   113                          	VIA_REG_DDR_A	= $3
   114                          	tableBitFromLeft	= $e130
   115                          	NOTE_FREQ_AS6	= 1864.660000000000081854523159563541	; unused
   116                          	AY_NOISE_GEN	= $6	; unused
   117                          	NOTE_FREQ_AS1	= 58.270000000000003126388037344441	; unused
   118                          	AY_S0_WRITE	= $7f41	; unused
   119                          	NOTE_FREQ_AS0	= 29.140000000000000568434188608080	; unused
   120                          	tmsSetAddressRead	= $e5a8
   121                          	VIA_RAM_START	= $7c58
   122                          	NOTE_FREQ_AS3	= 233.080000000000012505552149377763	; unused
   123                          	UART_RX_BUFFER_TAIL	= $29
   124                          	tmsSetPatternRead	= $e9dc	; unused
   125                          	AY_S1_ADDR	= $7f44	; unused
   126                          	NOTE_FREQ_AS2	= 116.540000000000006252776074688882	; unused
   127                          	UART_RX_BUFFER	= $7b58
   128                          	TMS_R1_SPRITE_16	= $2	; unused
   129                          	TMS_GFX_PIXELS_Y	= $c0	; unused
   130                          	TMS_GFX_PIXELS_X	= $100	; unused
   131                          	KB_SCANCODE_NUMPAD_MULTIPLY	= $7c	; unused
   132                          	HBC56_DISABLE_SFXMAN	= $1
   133                          	tmsSetAddressWrite	= $e592
   134                          	TMS_MAGENTA	= $d	; unused
   135                          	LCD_IO_PORT	= $2	; unused
   136                          	tmsConsoleScrollLine	= $e8ac
   137                          	KB_SCANCODE_CTRL_RIGHT	= $94	; unused
   138                          	_tmsSendEmptyPage	= $e75a
   139                          	KB_BUFFER_SIZE	= $10
   140                          	KB_SCANCODE_COMMA	= $41	; unused
   141                          	HBC56_TITLE_TEXT	= $ee10
   142                          	AY_R10	= $a
   143                          	AY_IO_PORT	= $40
   144                          	AY_R11	= $b
   145                          	NES_LEFT	= $2	; unused
   146                          	AY_R12	= $c
   147                          	TMS_R1_DISP_BLANK	= $0	; unused
   148                          	KB_NUM_LOCK	= $10	; unused
   149                          	hbc56LogoPatt	= $ee92
   150                          	kernelMain	= $f177	; ?
   151                          	AY_R13	= $d
   152                          	hbc56LogoPattEnd	= $f00a	; unused
   153                          	ASCII_CR	= $d	; unused
   154                          	AY_R14	= $e
   155                          	KB_SCANCODE_PAGE_DOWN	= $fa	; unused
   156                          	kbIntHandler	= $eb76
   157                          	IO_PORT_BASE_ADDRESS	= $7f00
   158                          	AY_R15	= $f
   159                          	isDigit	= $e01e
   160                          	AY_R16	= $10	; unused
   161                          	HAVE_TMS9918	= $1
   162                          	UART_CTL_MASTER_RESET	= $3
   163                          	AY_R17	= $11	; unused
   164                          	KB_SCANCODE_TAB	= $d	; unused
   165                          	HBC56_KERNEL_ZP_START	= $18
   166                          	TMS9918_IRQ_BIT	= $1
   167                          	HBC56_BORDER	= $4
   168                          	TMS_R1_MODE_MULTICOLOR	= $8
   169                          	TMS_R0_MODE_MULTICOLOR	= $0
   170                          	TMS_DK_BLUE	= $4
   171                          	TMS_VRAM_SPRITE_PATT_ADDRESS	= $1800
   172                          	HBC56_CONSOLE_FLAG_NOWAIT	= $10
   173                          	KB_SCANCODE_ENTER	= $5a	; unused
   174                          	KB_IO_PORT	= $80
   175                          	AY_ENV_SHAPE_ATTACK	= $4
   176                          	UART_STATUS_IRQ	= $80	; unused
   177                          	NES_DOWN	= $4	; unused
   178                          	tmsReg1ClearFields	= $e5ef
   179                          	NES_SELECT	= $20	; unused
   180                          	hbc56Stop	= $f2e2
   181                          	UART_RX_BUFFER_SIZE	= $100
   182                          	KB_BUFFER	= $7c66
   183                          	DEFAULT_HBC56_NMI_VECTOR	= $ffe0	; unused
   184                          	NES1_IO_ADDR	= $7f82
   185                          	UART_CTL_WORD_7BIT_OPB_1SB	= $c	; unused
   186                          	KB_SCANCODE_NUMPAD_PLUS	= $79	; unused
   187                          	NES2_IO_ADDR	= $7f83
   188                          	BITMAP_RAM_END	= $7b26
   189                          	KB_SCANCODE_F2	= $6	; unused
   190                          	HBC56_TITLE_TEXT_LEN	= $1a
   191                          	NES_UP	= $8	; unused
   192                          	KB_SCANCODE_F3	= $4	; unused
   193                          	VIA_DIR_INPUT	= $0	; unused
   194                          	DELAY_L	= $34
   195                          	TMS_TXT_TILES_X	= $28
   196                          	ASCII_BACKSPACE	= $8	; unused
   197                          	TMS_TXT_TILES_Y	= $18
   198                          	KB_SCANCODE_F1	= $5	; unused
   199                          	KB_SCANCODE_SEMICOLON	= $4c	; unused
   200                          	KB_SCANCODE_F6	= $b	; unused
   201                          	TMS_R1_DISP_ACTIVE	= $40
   202                          	tmsInitColorTable	= $e7d3
   203                          	KB_SCANCODE_F7	= $83	; unused
   204                          	KB_SCANCODE_HOME	= $ec	; unused
   205                          	DELAY_H	= $35
   206                          	KB_SCANCODE_F4	= $c	; unused
   207                          	tmsSetPosTmpAddress	= $e86a
   208                          	uartInNoWait	= $ead7	; unused
   209                          	hbc56Reset	= $f2df	; unused
   210                          	KB_SCANCODE_F5	= $3	; unused
   211                          	hbc56CustomDelayMs	= $f2e6	; unused
   212                          	_tmsWaitReg	= $e582
   213                          	uartOut	= $eafa	; ?
   214                          	KB_TMP_X	= $7c5d
   215                          	KB_SCANCODE_F8	= $a	; unused
   216                          	HBC56_KERNEL_RAM_START	= $7a00
   217                          	KB_TMP_Y	= $7c5e	; unused
   218                          	KB_SCANCODE_F9	= $1	; unused
   219                          	tmsConsolePrint	= $ea2c	; unused
   220                          	tmsConsoleCls	= $e95e	; unused
   221                          	uartIrq	= $ea95
   222                          	TMS_BLACK	= $1
   223                          	HBC56_META_TITLE	= $7ca6
   224                          	KB_SCANCODE_SQUARE_RIGHT	= $5b	; unused
   225                          	tmsConsoleNewline	= $ea3c	; ?
   226                          	AY_S1	= $7f44
   227                          	NOTE_FREQ_C8	= 4186.010000000000218278728425502777	; unused
   228                          	KB_IRQ_BIT	= $2
   229                          	tmsModeGraphicsII	= $e697	; unused
   230                          	AY_S0	= $7f40
   231                          	NOTE_FREQ_A8	= $1b80	; unused
   232                          	HBC56_TICKS	= $7c9f
   233                          	HBC56_SECONDS_H	= $7ca1
   234                          	memcpySinglePage	= $e0a3	; unused
   235                          	tmsModeGraphicsI	= $e610
   236                          	NOTE_FREQ_G8	= 6271.930000000000291038304567337036	; unused
   237                          	AY_ADDR	= $0
   238                          	NOTE_FREQ_E8	= 5274.039999999999963620211929082870	; unused
   239                          	TMS_R1_RAM_4K	= $0	; unused
   240                          	AY_ENV_SHAPE_ALTERNATE	= $2
   241                          	NOTE_FREQ_DS8	= 4978.029999999999745341483503580093	; unused
   242                          	tmsInitEntireColorTable	= $e7d1	; ?
   243                          	TMS_GREY	= $e
   244                          	NES_B	= $40	; unused
   245                          	HBC56_SECONDS_L	= $7ca0
   246                          	AY_PSG1	= $4
   247                          	UART_CTL_WORD_7BIT_EPB_1SB	= $8	; unused
   248                          	NES_A	= $80	; unused
   249                          	TMS9918_IO_PORT	= $10
   250                          	UART_RAM_END	= $7c58
   251                          	AY_PSG0	= $0
   252                          	UART_FLOWCTRL_XON	= $11
   253                          	DEFAULT_HBC56_RST_VECTOR	= $8000
   254                          	NOTE_FREQ_C0	= 16.350000000000001421085471520200	; unused
   255                          	NOTE_FREQ_A1	= $37	; unused
   256                          	NOTE_FREQ_G2	= $62	; unused
   257                          	NOTE_FREQ_E3	= 164.810000000000002273736754432321
   258                          	NOTE_FREQ_DS4	= 311.129999999999995452526491135359	; unused
   259                          	KB_SCANCODE_CTRL_LEFT	= $14	; unused
   260                          	NOTE_FREQ_A0	= 27.500000000000000000000000000000	; unused
   261                          	NOTE_FREQ_E2	= 82.409999999999996589394868351519	; unused
   262                          	NOTE_FREQ_DS5	= 622.250000000000000000000000000000	; unused
   263                          	tmsReg0ClearFields	= $e5dd
   264                          	UART_STATUS_CLEAR_TO_SEND	= $8	; unused
   265                          	NOTE_FREQ_G3	= $c4	; unused
   266                          	NOTE_FREQ_C1	= 32.700000000000002842170943040401	; unused
   267                          	NOTE_FREQ_G0	= 24.500000000000000000000000000000	; unused
   268                          	NOTE_FREQ_E1	= 41.200000000000002842170943040401	; unused
   269                          	NOTE_FREQ_DS6	= 1244.509999999999990905052982270718	; unused
   270                          	UART_DATA	= $7f21
   271                          	VIA_IO_ADDR_T2C_H	= $7ff9	; unused
   272                          	NOTE_FREQ_C2	= 65.409999999999996589394868351519	; unused
   273                          	NOTE_FREQ_A3	= $dc	; unused
   274                          	NOTE_FREQ_E0	= 20.600000000000001421085471520200	; unused
   275                          	NOTE_FREQ_DS7	= 2489.019999999999981810105964541435	; unused
   276                          	TMS9918_TMP_BUFFER	= $7b30
   277                          	NOTE_FREQ_G1	= $31	; unused
   278                          	NOTE_FREQ_A2	= $6e	; unused
   279                          	NOTE_FREQ_C3	= 130.810000000000002273736754432321	; unused
   280                          	UART_ZP_END	= $2c
   281                          	NOTE_FREQ_DS0	= 19.449999999999999289457264239900	; unused
   282                          	NOTE_FREQ_C4	= 261.629999999999995452526491135359	; unused
   283                          	NOTE_FREQ_A5	= $370	; unused
   284                          	NOTE_FREQ_G6	= 1567.980000000000018189894035458565	; unused
   285                          	NOTE_FREQ_E7	= 2637.019999999999981810105964541435	; unused
   286                          	NOTE_FREQ_DS1	= 38.890000000000000568434188608080	; unused
   287                          	HAVE_KEYBOARD	= $1
   288                          	NOTE_FREQ_A4	= $1b8	; unused
   289                          	NOTE_FREQ_E6	= 1318.509999999999990905052982270718	; unused
   290                          	hbc56HighBell	= $f260	; ?
   291                          	NOTE_FREQ_G7	= 3135.960000000000036379788070917130	; unused
   292                          	NOTE_FREQ_C5	= 523.250000000000000000000000000000	; unused
   293                          	tmsConsoleHome	= $e961	; unused
   294                          	NOTE_FREQ_DS2	= 77.780000000000001136868377216160	; unused
   295                          	NOTE_FREQ_G4	= $188	; unused
   296                          	NOTE_FREQ_E5	= 659.250000000000000000000000000000	; unused
   297                          	VIA_IO_ADDR_T2C_L	= $7ff8	; unused
   298                          	NOTE_FREQ_C6	= 1046.500000000000000000000000000000	; unused
   299                          	NOTE_FREQ_A7	= $dc0	; unused
   300                          	BCD_RAM_START	= $7c59
   301                          	HBC56_META_TITLE_MAX_LEN	= $10
   302                          	isDigitX	= $e030	; unused
   303                          	NOTE_FREQ_DS3	= 155.560000000000002273736754432321	; unused
   304                          	NOTE_FREQ_E4	= 329.629999999999995452526491135359	; unused
   305                          	NOTE_FREQ_G5	= 783.990000000000009094947017729282	; unused
   306                          	NOTE_FREQ_A6	= $6e0	; unused
   307                          	NOTE_FREQ_C7	= $82d	; unused
   308                          	VIA_RAM_END	= $7c59
   309                          	AY_INACTIVE	= $3	; unused
   310                          	TMS_SPRITE_SIZE2X	= $10	; unused
   311                          	tmsSetPosWriteText	= $e97a	; ?
   312                          	KB_SCANCODE_F11	= $78	; unused
   313                          	AY_S0_READ	= $7f42	; unused
   314                          	tmsInitTextTable	= $e7ad	; ?
   315                          	KB_SCANCODE_F10	= $9	; unused
   316                          	VIA_REG_PORT_A	= $1
   317                          	KB_SCANCODE_NUMPAD_PERIOD	= $71	; unused
   318                          	VIA_REG_PORT_B	= $0
   319                          	KB_SCANCODE_F12	= $7	; unused
   320                          	kbNextScancode	= $ec94
   321                          	KB_SCANCODE_WINDOWS_LEFT	= $9f	; unused
   322                          	BCD_RAM_END	= $7c5c
   323                          	ASCII_RETURN	= $a	; unused
   324                          	TMS_R1_INT_ENABLE	= $20
   325                          	UART_CTL_WORD_8BIT_OPAR_1SB	= $1c	; unused
   326                          	isSpace	= $e049	; unused
   327                          	hbc56BootScreen	= $f00a
   328                          	AY_S1_READ	= $7f46	; unused
   329                          	KB_SCANCODE_END	= $e9	; unused
   330                          	TMS_GFX_TILE_HEIGHT	= $8
   331                          	KB_SCANCODE_SHIFT_RIGHT	= $59
   332                          	TMS_LT_BLUE	= $5	; unused
   333                          	TMS_R0_EXT_VDP_ENABLE	= $1	; unused
   334                          	uartOutNoBsCheck	= $eb00	; ?
   335                          	KB_SCANCODE_ALT_LEFT	= $11	; unused
   336                          	HBC56_INT_VECTOR	= $7e00
   337                          	VIA_REG_IER	= $e
   338                          	tmsIncPosConsole	= $e920
   339                          	INT_IO_PORT	= $df
   340                          	KB_PRESSED_MAP_BYTES	= $20
   341                          	VIA_REG_ACR	= $b
   342                          	STR_ADDR_H	= $33
   343                          	NES_RAM_END	= $7c9f
   344                          	memsetSinglePage	= $e101
   345                          	TMS_FONT_DATA	= $e271
   346                          	tmsSetPatternTmpAddressII	= $e98a	; unused
   347                          	kbWaitForScancode	= $ec7f
   348                          	tmsReg0SetFields	= $e5d3
   349                          	tmsPrint	= $e9e2
   350                          	KB_SCANCODE_APOS	= $52	; unused
   351                          	STR_ADDR_L	= $32
   352                          	tmsSetPosConsole	= $e967
   353                          	KB_SHIFT_RIGHT_MAP_BYTE	= $b
   354                          	AY_CLOCK_FREQ	= $1e8480
   355                          	tmsSetBackground	= $e5cf
   356                          	TMS_R1_MODE_GRAPHICS_II	= $0
   357                          	UART_RX_BUFFER_XON_SIZE	= $4
   358                          	VIA_IO_ADDR_ACR	= $7ffb	; unused
   359                          	uartFlowCtrlXon	= $eab9	; ?
   360                          	VIA_IO_ADDR_IER	= $7ffe	; unused
   361                          	ASCII_BELL	= $7	; unused
   362                          	BCD_TMP3	= $7c5b
   363                          	TMS_MED_RED	= $8	; unused
   364                          	UART_CTL_WORD_8BIT_EPAR_1SB	= $18	; unused
   365                          	BCD_TMP2	= $7c5a
   366                          	LCD_ZP_END	= $28
   367                          	toLower	= $e073	; unused
   368                          	BCD_TMP1	= $7c59
   369                          	MEM_SRC	= $2e
   370                          	AY_ENABLES	= $7
   371                          	UART_CTL_WORD_7BIT_OPB_2SB	= $4	; unused
   372                          	LCD_RAM_START	= $7b58
   373                          	TMS_LT_GREEN	= $3	; unused
   374                          	_tmsWaitData	= $e579
   375                          	tmsSetColorTmpAddressII	= $e986	; unused
   376                          	HAVE_MATH_INC	= $1
   377                          	KB_SCANCODE_B	= $32	; unused
   378                          	hbc56Bell	= $f292	; unused
   379                          	KB_SCANCODE_C	= $21	; unused
   380                          	TMS_TXT_PIXELS_X	= $f0	; unused
   381                          	HBC56_KERNEL_RAM_SIZE	= $2bd	; unused
   382                          	TMS_TXT_PIXELS_Y	= $c0	; unused
   383                          	KB_SCANCODE_A	= $1c	; unused
   384                          	TMS_GFX_TILES_Y	= $18
   385                          	KB_PRESSED_MAP_SIZE	= $fe	; unused
   386                          	KB_SCANCODE_F	= $2b	; unused
   387                          	kbIsPressed	= $ec62	; unused
   388                          	TMS_R0_MODE_TEXT	= $0
   389                          	TMS_GFX_TILES_X	= $20
   390                          	KB_SCANCODE_G	= $34	; unused
   391                          	HBC56_DISABLE_LCD	= $1
   392                          	TMS_R0_MODE_GRAPHICS_I	= $0
   393                          	tmsSetSpriteTmpAddress	= $e861	; unused
   394                          	KB_CB_RELEASED	= $7c61
   395                          	KB_SCANCODE_D	= $23	; unused
   396                          	TMS_R1_MODE_GRAPHICS_I	= $0
   397                          	KB_SCANCODE_E	= $24	; unused
   398                          	TILEMAP_ZP_START	= $18
   399                          	KB_SHIFT_DOWN	= $1	; unused
   400                          	KB_SCANCODE_J	= $3b	; unused
   401                          	KB_CB_PRESSED	= $7c5f
   402                          	KB_SCANCODE_K	= $42	; unused
   403                          	KB_SHIFT_RIGHT_MAP_BIT	= $40
   404                          	HBC56_CONSOLE_FLAGS	= $7ca3
   405                          	AY_ENV_SHAPE	= $d
   406                          	KB_SCANCODE_H	= $33	; unused
   407                          	kbReadAscii	= $ecfc	; unused
   408                          	KB_BUFFER_HEAD	= $7c64
   409                          	KB_SCANCODE_I	= $43	; unused
   410                          	viaIntHandler	= $ee0d
   411                          	KB_SCANCODE_N	= $31	; unused
   412                          	tmsTileXyAtPixelXy	= $e827	; unused
   413                          	UART_CTL_CLOCK_DIV_16	= $1	; unused
   414                          	nesWaitForPress	= $eb1e
   415                          	hbc56LogoInd	= $ee50
   416                          	KB_SCANCODE_O	= $44	; unused
   417                          	memcpyMultiPagePort	= $e0e1	; unused
   418                          	KB_SCANCODE_L	= $4b	; unused
   419                          	bin2bcd8	= $e07b	; unused
   420                          	KB_SCANCODE_M	= $3a	; unused
   421                          	KB_SCANCODE_ARROW_UP	= $f5	; unused
   422                          	UART_RX_BUFFER_HEAD	= $28
   423                          	KB_SCANCODE_R	= $2d	; unused
   424                          	_tmsSendPage	= $e724	; ?
   425                          	tmsSetPosWrite	= $e96d	; unused
   426                          	KB_SCANCODE_S	= $1b	; unused
   427                          	KB_SCANCODE_P	= $4d	; unused
   428                          	TMS_DK_RED	= $6	; unused
   429                          	KB_SCANCODE_Q	= $15	; unused
   430                          	NOTE_FREQ_GS8	= 6644.880000000000109139364212751389	; unused
   431                          	KB_CURRENT_STATE	= $7c63
   432                          	KB_SCANCODE_V	= $2a	; unused
   433                          	NOTE_FREQ_CS8	= 4434.920000000000072759576141834259	; unused
   434                          	KB_SCANCODE_W	= $1d	; unused
   435                          	HBC56_CONSOLE_FLAG_NES	= $40
   436                          	UART_CTL_WORD_7BIT_EPB_2SB	= $0	; unused
   437                          	kbScancodeToAscii	= $eca9
   438                          	KB_SCANCODE_T	= $2c	; unused
   439                          	KB_SHIFT_LEFT_MAP_BIT	= $20
   440                          	TMS_TRANSPARENT	= $0	; unused
   441                          	KB_SCANCODE_U	= $3c	; unused
   442                          	SFXMAN_RAM_END	= $7c59
   443                          	NOTE_FREQ_GS4	= 415.300000000000011368683772161603	; unused
   444                          	tmsSendBytes	= $e75e
   445                          	NOTE_FREQ_CS5	= 554.370000000000004547473508864641	; unused
   446                          	VIA_REG_T2C_H	= $9
   447                          	KB_SCANCODE_Z	= $1a	; unused
   448                          	LCD_ZP_START	= $28
   449                          	NOTE_FREQ_CS4	= 277.180000000000006821210263296962	; unused
   450                          	NOTE_FREQ_GS5	= 830.610000000000013642420526593924	; unused
   451                          	KB_SCANCODE_MINUS	= $4e	; unused
   452                          	isUpper	= $e00c
   453                          	TMS_VRAM_NAME_ADDRESS	= $3800
   454                          	UART_IRQ	= $3
   455                          	NES_RAM_START	= $7c9c
   456                          	NOTE_FREQ_GS6	= 1661.220000000000027284841053187847	; unused
   457                          	NOTE_FREQ_CS7	= 2217.460000000000036379788070917130	; unused
   458                          	KB_SCANCODE_X	= $22	; unused
   459                          	KB_SCANCODE_PAUSE	= $e1
   460                          	KB_IO_ADDR	= $7f80
   461                          	memcpySinglePagePort	= $e0b1	; unused
   462                          	NOTE_FREQ_CS6	= 1108.730000000000018189894035458565	; unused
   463                          	NOTE_FREQ_GS7	= 3322.440000000000054569682106375694	; unused
   464                          	TMS_REGISTER_DATA	= $e571
   465                          	TMS_MODEL	= $26be
   466                          	KB_SCANCODE_Y	= $35	; unused
   467                          	NOTE_FREQ_GS0	= 25.960000000000000852651282912120	; unused
   468                          	NOTE_FREQ_CS1	= 34.649999999999998578914528479800	; unused
   469                          	VIA_REG_T2C_L	= $8
   470                          	ROM_BANK_REG	= $8	; unused
   471                          	HBC56_USER_ZP_START	= $36	; unused
   472                          	NOTE_FREQ_CS0	= 17.320000000000000284217094304040	; unused
   473                          	NOTE_FREQ_GS1	= 51.909999999999996589394868351519	; unused
   474                          	UART_CTL_RX_INT_ENABLE	= $80
   475                          	KB_SCANCODE_CAPS_LOCK	= $58
   476                          	tableInvBitFromRight	= $e148	; unused
   477                          	tmsInitPattTable	= $e76d	; ?
   478                          	TMS9918_IRQ	= $1
   479                          	HBC56_CONSOLE_FLAG_CURSOR	= $80	; unused
   480                          	NOTE_FREQ_GS2	= 103.829999999999998294697434175760	; unused
   481                          	NOTE_FREQ_CS3	= 138.590000000000003410605131648481	; unused
   482                          	tmsModeMulticolor	= $e6cb	; unused
   483                          	NOTE_FREQ_CS2	= 69.299999999999997157829056959599	; unused
   484                          	NOTE_FREQ_GS3	= 207.650000000000005684341886080801	; unused
   485                          	KB_IRQ	= $2
   486                          	VIA_IO_PORT	= $f0
   487                          	HBC56_VIA_CALLBACK	= $7cbb
   488                          	_tmsSendX8	= $e726
   489                          	KB_SCANCODE_NUMPAD_5	= $73	; unused
   490                          	AY_CHA	= $0
   491                          	KB_SCANCODE_ALT_RIGHT_	= $91	; unused
   492                          	KB_SCANCODE_NUMPAD_4	= $6b	; unused
   493                          	AY_CHB	= $1
   494                          	KB_RAM_SIZE	= $3a
   495                          	tmsSetPatternWrite	= $e9d6	; unused
   496                          	KB_SCANCODE_NUMPAD_7	= $6c	; unused
   497                          	UART_RAM_START	= $7b58
   498                          	AY_CHC	= $2
   499                          	KB_SCANCODE_NUMPAD_6	= $74	; unused
   500                          	MEMORY_ZP_SIZE	= $6
   501                          	KB_SCANCODE_NUMPAD_1	= $69	; unused
   502                          	KEY_MAP_SHIFTED	= $ed8d	; ?
   503                          	AY_READ	= $2
   504                          	KB_SCANCODE_NUMPAD_0	= $70	; unused
   505                          	KB_SCANCODE_NUMPAD_3	= $7a	; unused
   506                          	HBC56_LOGO	= $4
   507                          	VIA_IRQ	= $5
   508                          	tableBitFromRight	= $e140	; unused
   509                          	KB_SCANCODE_NUMPAD_2	= $72	; unused
   510                          	TMS9918_CONSOLE_LINE_LEN	= $7b2b
   511                          	KB_SCANCODE_NUMPAD_MINUS	= $7b	; unused
   512                          	BITMAP_RAM_START	= $7b16
   513                          	uartInit	= $ea79	; unused
   514                          	hbc56CustomDelay	= $ffe3
   515                          	UART_STATUS_FRAMING_ERROR	= $10	; unused
   516                          	HBC56_BACKGROUND	= $f
   517                          	AY_ENV_SHAPE_FADE_IN_STOP	= $4	; unused
   518                          	HAVE_UART	= $1
   519                          	MEM_DST	= $2c
   520                          	TMS_DK_YELLOW	= $a	; unused
   521                          	UART_STATUS_PARITY_ERROR	= $40	; unused
   522                          	KB_SCANCODE_NUMPAD_9	= $7d	; unused
   523                          	KB_SCANCODE_NUMPAD_8	= $75	; unused
   524                          	AY_CHN	= $3	; unused
   525                          	AY_ENV_SHAPE_TRIANGLE	= $e	; unused
   526                          	hbc56Delay	= $ffe1
   527                          	tableInvBitFromLeft	= $e138
   528                          	KB_SCANCODE_2	= $1e	; unused
   529                          	AY_CHB_TONE_H	= $3	; unused
   530                          	KB_SCANCODE_3	= $26	; unused
   531                          	kbResetCallbacks	= $eb65	; unused
   532                          	NES_IO_PORT	= $82
   533                          	TMS9918_RAM_SIZE	= $32
   534                          	KB_SCANCODE_0	= $45	; unused
   535                          	TMS9918_RAM_START	= $7b26
   536                          	AY_CHA_TONE_L	= $0
   537                          	AY_CHC_TONE_H	= $5	; unused
   538                          	AY_ENV_SHAPE_CONTINUE	= $8
   539                          	KB_SCANCODE_1	= $16	; unused
   540                          	HBC56_TEXT	= $4
   541                          	HBC56_META_VECTOR	= $dffc
   542                          	cputype	= $65c02	; unused
   543                          	KB_SCANCODE_6	= $36	; unused
   544                          	HBC56_KERNEL_RAM_END	= $7cbd
   545                          	AY_CHB_TONE_L	= $2	; unused
   546                          	KB_SCANCODE_7	= $3d	; unused
   547                          	AY_ENV_SHAPE_FADE_IN	= $d	; unused
   548                          	tmsModeReset	= $e5f7
   549                          	KB_SCANCODE_DELETE	= $f1	; unused
   550                          	KB_SCANCODE_4	= $25	; unused
   551                          	KB_SCANCODE_MENU	= $af	; unused
   552                          	KB_SCANCODE_SPACEBAR	= $29	; unused
   553                          	AY_CHA_TONE_H	= $1
   554                          	AY_CHC_TONE_L	= $4	; unused
   555                          	KB_SCANCODE_5	= $2e	; unused
   556                          	MEMORY_ZP_START	= $2c
   557                          	tmsSetPosRead	= $e980	; unused
   558                          	nes1Pressed	= $eb2b	; unused
   559                          	VIA_REG_T1C_H	= $5
   560                          	INT_CTRL_ADDRESS	= $7fdf
   561                          	STR_ADDR	= $32
   562                          	AY_ENV_PERIOD_H	= $c
   563                          	tmsHex8	= $e834	; unused
   564                          	VIA_IO_ADDR_T1L_H	= $7ff7	; unused
   565                          	TILEMAP_ZP_END	= $1e
   566                          	KEY_MAP	= $ed0d	; ?
   567                          	KB_SCANCODE_8	= $3e	; unused
   568                          	KB_RAM_START	= $7c5c
   569                          	KB_SCANCODE_9	= $46	; unused
   570                          	VIA_REG_T1C_L	= $4
   571                          	AY_ENV_PERIOD_L	= $b
   572                          	KB_CTRL_DOWN	= $2	; unused
   573                          	KB_PAUSE_KEY	= $e1
   574                          	VIA_IO_ADDR_T1L_L	= $7ff6	; unused
   575                          	NES_RIGHT	= $1	; unused
   576                          	nes2Pressed	= $eb33	; unused
   577                          	MEM_LEN	= $30
   578                          	VIA_IO_ADDR_PORT_A	= $7ff1	; unused
   579                          	UART_CTL_WORD_8BIT_2SB	= $10
   580                          	NES_START	= $10	; unused
   581                          	HBC56_META_TITLE_LEN	= $7cb8
   582                          	memsetMultiPage	= $e10d	; unused
   583                          	UART_REG	= $7f20
   584                          	LCD_MODEL	= $3240	; unused
   585                          	KB_SCANCODE_SHIFT_LEFT	= $12
   586                          	VIA_IO_ADDR_PORT_B	= $7ff0	; unused
   587                          	isAlNum	= $e02a	; unused
   588                          	AY_CHA_AMPL	= $8
   589                          	LAST_MODULE_RAM_END	= $7c9f
   590                          	TMS_R1_MODE_TEXT	= $10
   591                          	tmsConsoleOut	= $e9f5
   592                          	TMS9918_REG	= $7f11
   593                          	KB_SCANCODE_NUMPAD_DIVIDE	= $ca	; unused
   594                          	DEFAULT_HBC56_INT_VECTOR	= $ffe0
   595                          	VIA_IRQ_BIT	= $10
   596                          	TMS_VRAM_PATT_ADDRESS	= $2000
   597                          	KB_SCANCODE_EQUAL	= $55	; unused
   598                          	KB_RELEASE	= $f0
   599                          	tmsInitSpriteTable	= $e7f2	; ?
   600                          	KB_SCANCODE_ARROW_DOWN	= $f2	; unused
   601                          	UART_RX_BUFFER_BYTES	= $2a
   602                          	isAlpha	= $e018
   603                          	ayInit	= $e158
   604                          	TMS9918_RAM	= $7f10
   605                          	UART_RX_FLAGS	= $2b
   606                          	AY_R1	= $1
   607                          	NOTE_FREQ_B8	= 7902.130000000000109139364212751389	; unused
   608                          	KB_STATUS_ADDR	= $7f81
   609                          	AY_R0	= $0
   610                          	AY_R3	= $3
   611                          	NOTE_FREQ_F8	= 5587.649999999999636202119290828705	; unused
   612                          	AY_R2	= $2
   613                          	NOTE_FREQ_D8	= 4698.630000000000109139364212751389	; unused
   614                          	TMS_DK_GREEN	= $c	; unused
   615                          	AY_R5	= $5
   616                          	AY_CHC_AMPL	= $a	; unused
   617                          	NOTE_FREQ_FS8	= 5919.909999999999854480847716331482	; unused
   618                          	AY_R4	= $4
   619                          	AY_R7	= $7
   620                          	KB_ALT_DOWN	= $4	; unused
   621                          	AY_R6	= $6
   622                          	TMS_TXT_TILE_HEIGHT	= $8
   623                          	AY_R9	= $9
   624                          	NOTE_FREQ_B0	= 30.870000000000000994759830064140	; unused
   625                          	NOTE_FREQ_F2	= 87.310000000000002273736754432321	; unused
   626                          	NOTE_FREQ_D3	= 146.830000000000012505552149377763	; unused
   627                          	NOTE_FREQ_FS4	= 369.990000000000009094947017729282	; unused
   628                          	TMS_VRAM_COLOR_ADDRESS+2	= $0
   629                          	tmsSetPatternTmpAddressBank1	= $e9c0	; unused
   630                          	VIA_IO_ADDR_DDR_A	= $7ff3	; unused
   631                          	AY_R8	= $8
   632                          	NOTE_FREQ_B1	= 61.740000000000001989519660128281	; unused
   633                          	NOTE_FREQ_D2	= 73.420000000000001705302565824240	; unused
   634                          	NOTE_FREQ_FS5	= 739.990000000000009094947017729282	; unused
   635                          	UART_FLOWCTRL_XOFF	= $13
   636                          	TMS_R0_EXT_VDP_DISABLE	= $0
   637                          	tmsSetPatternTmpAddressBank0	= $e9a3	; unused
   638                          	NOTE_FREQ_F3	= 174.610000000000013642420526593924	; unused
   639                          	NOTE_FREQ_F0	= 21.829999999999998294697434175760	; unused
   640                          	NOTE_FREQ_D1	= 36.710000000000000852651282912120	; unused
   641                          	NOTE_FREQ_FS6	= 1479.980000000000018189894035458565	; unused
   642                          	TMS9918_CONSOLE_Y	= $7b29
   643                          	TMS_LT_YELLOW	= $b	; unused
   644                          	KB_SCANCODE_ARROW_LEFT	= $eb	; unused
   645                          	NOTE_FREQ_B2	= 123.469999999999998863131622783840	; unused
   646                          	NOTE_FREQ_D0	= 18.350000000000001421085471520200	; unused
   647                          	NOTE_FREQ_FS7	= 2959.960000000000036379788070917130	; unused
   648                          	TMS9918_CONSOLE_X	= $7b28
   649                          	tmsSetPatternTmpAddressBank2	= $e9cb	; unused
   650                          	VIA_IO_ADDR_DDR_B	= $7ff2	; unused
   651                          	NOTE_FREQ_F1	= 43.649999999999998578914528479800	; unused
   652                          	NOTE_FREQ_B3	= 246.939999999999997726263245567679	; unused
   653                          	HBC56_KERNEL_START	= $e000
   654                          	TMS9918_ZP_END	= $28
   655                          	HAVE_AY3891X	= $1
   656                          	NOTE_FREQ_FS0	= 23.120000000000000994759830064140	; unused
   657                          	TMS_R1_INT_DISABLE	= $0	; unused
   658                          	AY_CHB_AMPL	= $9	; unused
   659                          	NOTE_FREQ_B4	= 493.879999999999995452526491135359	; unused
   660                          	NOTE_FREQ_F6	= 1396.910000000000081854523159563541	; unused
   661                          	NOTE_FREQ_D7	= 2349.320000000000163709046319127083	; unused
   662                          	NOTE_FREQ_FS1	= 46.250000000000000000000000000000	; unused
   663                          	NOTE_FREQ_B5	= 987.769999999999981810105964541435	; unused
   664                          	NOTE_FREQ_D6	= 1174.660000000000081854523159563541	; unused
   665                          	TMS_TXT_TILE_WIDTH	= $6
   666                          	tmsSetPosTmpAddressText	= $e887
   667                          	tmsSetPatternTmpAddress	= $e9a3
   668                          	NOTE_FREQ_F7	= 2793.829999999999927240423858165741	; unused
   669                          	NOTE_FREQ_FS2	= 92.500000000000000000000000000000	; unused
   670                          	NOTE_FREQ_F4	= 349.230000000000018189894035458565	; unused
   671                          	NOTE_FREQ_D5	= 587.330000000000040927261579781771	; unused
   672                          	LOGO_BUFFER	= $3000	; unused
   673                          	NOTE_FREQ_B6	= 1975.529999999999972715158946812153	; unused
   674                          	TMS9918_CONSOLE_SIZE_X	= $7b2a
   675                          	KB_SCANCODE_BACKSPACE	= $66	; unused
   676                          	NOTE_FREQ_FS3	= $b9	; unused
   677                          	NOTE_FREQ_D4	= 293.660000000000025011104298755527	; unused
   678                          	tmsInit	= $e6d9
   679                          	NOTE_FREQ_F5	= 698.460000000000036379788070917130
   680                          	NOTE_FREQ_B7	= 3951.070000000000163709046319127083	; unused
   681                          	KB_SCANCODE_INSERT	= $f0	; unused

; ******** Source: ../kernel\hbc56kernel.inc
    15                          
    16                          

; ******** Source: ../lib\ut\math.inc
     1                          ; 6502
     2                          ;
     3                          ; Math macros
     4                          ;
     5                          ; Copyright (c) 2020 Troy Schrapel
     6                          ;
     7                          ; This code is licensed under the MIT license
     8                          ;
     9                          ; https://github.com/visrealm/hbc-56
    10                          ;
    11                          ;
    12                          
    13                          HAVE_MATH_INC = 1
    14                          
    15                          !macro lsr2 {
    16                                  lsr
    17                                  lsr
    18                          }
    19                          
    20                          !macro lsr3 {
    21                                  +lsr2
    22                                  lsr
    23                          }
    24                          
    25                          !macro lsr4 {
    26                                  +lsr3
    27                                  lsr
    28                          }
    29                          
    30                          !macro lsr5 {
    31                                  +lsr4
    32                                  lsr
    33                          }
    34                          
    35                          !macro lsr6 {
    36                                  +lsr5
    37                                  lsr
    38                          }
    39                          
    40                          !macro lsr7 {
    41                                  +lsr6
    42                                  lsr
    43                          }
    44                          
    45                          !macro div2   { lsr }
    46                          !macro div4   { +lsr2 }
    47                          !macro div8   { +lsr3 }
    48                          !macro div16  { +lsr4 }
    49                          !macro div32  { +lsr5 }
    50                          !macro div64  { +lsr6 }
    51                          !macro div128 { +lsr7 }
    52                          
    53                          !macro asl2 {
    54                                  asl
    55                                  asl
    56                          }
    57                          
    58                          !macro asl3 {
    59                                  +asl2
    60                                  asl
    61                          }
    62                          
    63                          !macro asl4 {
    64                                  +asl3
    65                                  asl
    66                          }
    67                          
    68                          !macro asl5 {
    69                                  +asl4
    70                                  asl
    71                          }
    72                          
    73                          !macro asl6 {
    74                                  +asl5
    75                                  asl
    76                          }
    77                          
    78                          !macro asl7 {
    79                                  +asl6
    80                                  asl
    81                          }
    82                          
    83                          !macro mul2   { asl }
    84                          !macro mul4   { +asl2 }
    85                          !macro mul8   { +asl3 }
    86                          !macro mul16  { +asl4 }
    87                          !macro mul32  { +asl5 }
    88                          !macro mul64  { +asl6 }
    89                          !macro mul128 { +asl7 }
    90                          
    91                          
    92                          
    93                          ; -----------------------------------------------------------------------------
    94                          ; +dec16: decement a 16-bit value
    95                          ; -----------------------------------------------------------------------------
    96                          ; Inputs:
    97                          ;  addr: address containing LSB of value to decrement
    98                          ; -----------------------------------------------------------------------------
    99                          !macro dec16 .addr {
   100                            lda .addr
   101                            bne +
   102                            dec .addr + 1
   103                          +
   104                            dec .addr
   105                          }
   106                          
   107                          ; -----------------------------------------------------------------------------
   108                          ; +inc16: increment a 16-bit value
   109                          ; -----------------------------------------------------------------------------
   110                          ; Inputs:
   111                          ;  addr: address containing LSB of value to increment
   112                          ; -----------------------------------------------------------------------------
   113                          !macro inc16 .addr {
   114                            inc .addr
   115                            bne +
   116                            inc .addr + 1
   117                          +
   118                          }
   119                          
   120                          ; -----------------------------------------------------------------------------
   121                          ; +cmp16: compare two 16-bit values in memory
   122                          ; -----------------------------------------------------------------------------
   123                          ; Inputs:
   124                          ;  left:  address containing LSB of left value to comapre
   125                          ;  right: address containing LSB of right value to comapre
   126                          ; Outputs:
   127                          ;  C set if right < left
   128                          ;  Z set if right == left
   129                          ; -----------------------------------------------------------------------------
   130                          !macro cmp16 .left, .right {
   131                            lda .left + 1
   132                            cmp .right + 1
   133                          	bne +
   134                          	lda .left
   135                          	cmp .right
   136                          +
   137                          }
   138                          
   139                          ; -----------------------------------------------------------------------------
   140                          ; +cmp16: compare two 16-bit values in memory
   141                          ; -----------------------------------------------------------------------------
   142                          ; Inputs:
   143                          ;  value: immediate value to compare
   144                          ;  x:     msb
   145                          ;  a:     lsb
   146                          ; -----------------------------------------------------------------------------
   147                          !macro cmp16xa .value {
   148                            cpx #>.value
   149                          	bne .doneCmpXa
   150                          	cmp #<.value
   151                          .doneCmpXa
   152                          }
   153                          
   154                          ; -----------------------------------------------------------------------------
   155                          ; +sub16: subtract 16 bit numbers
   156                          ; -----------------------------------------------------------------------------
   157                          ; Inputs:
   158                          ;  left:  address containing LSB of left value
   159                          ;  right: address containing LSB of right value
   160                          ; Outputs:
   161                          ;  res:   address containing LSB of result
   162                          ; -----------------------------------------------------------------------------
   163                          !macro sub16 .left, .right, .res {
   164                            sec
   165                            lda .left
   166                            sbc .right
   167                            sta .res
   168                            lda .left + 1
   169                            sbc .right + 1
   170                            sta .res + 1
   171                          }
   172                          
   173                          ; -----------------------------------------------------------------------------
   174                          ; +sub16: subtract 16 bit numbers - result in ax registers
   175                          ; -----------------------------------------------------------------------------
   176                          ; Inputs:
   177                          ;  left:  address containing LSB of left value
   178                          ;  right: address containing LSB of right value
   179                          ; Outputs:
   180                          ;  a:     result msb
   181                          ;  x:     result lsb
   182                          ; -----------------------------------------------------------------------------
   183                          !macro sub16 .left, .right {
   184                            sec
   185                            lda .left
   186                            sbc .right
   187                            tax
   188                            lda .left + 1
   189                            sbc .right + 1
   190                          }
   191                          
   192                          
   193                          ; -----------------------------------------------------------------------------
   194                          ; +add16: add 16 bit numbers - result in ax registers
   195                          ; -----------------------------------------------------------------------------
   196                          ; Inputs:
   197                          ;  left:  address containing LSB of left value
   198                          ;  right: address containing LSB of right value
   199                          ; Outputs:
   200                          ;  a:     result msb
   201                          ;  x:     result lsb
   202                          ; -----------------------------------------------------------------------------
   203                          !macro add16 .left, .right {
   204                            clc
   205                            lda .left
   206                            adc .right
   207                            tax
   208                            lda .left + 1
   209                            adc .right + 1
   210                          }
   211                          
   212                          
   213                          ; -----------------------------------------------------------------------------
   214                          ; +add16Imm: add 16 bit numbers - result stored to res
   215                          ; -----------------------------------------------------------------------------
   216                          ; Inputs:
   217                          ;  left:  address containing LSB of left value
   218                          ;  imm:   immediate value to add
   219                          ; Outputs:
   220                          ;  res: address to store result
   221                          ; -----------------------------------------------------------------------------
   222                          !macro add16Imm .left, .imm, .res {
   223                            clc
   224                            lda .left
   225                            adc #<.imm
   226                            sta .res
   227                            lda .left + 1
   228                            adc #>.imm
   229                            sta .res + 1
   230                          }
   231                          
   232                          
   233                          ; -----------------------------------------------------------------------------
   234                          ; +subImm8From16: subtract an 8 bit number from a 16 bit number
   235                          ; -----------------------------------------------------------------------------
   236                          ; Inputs:
   237                          ;  left:  address containing LSB of left value
   238                          ;  right: immediate 8-bit value
   239                          ; Outputs:
   240                          ;  res:   address containing LSB of result
   241                          ; -----------------------------------------------------------------------------
   242                          !macro subImm8From16 .left, .right, .res {
   243                            sec
   244                            lda .left
   245                            sbc #.right
   246                            sta .res
   247                            lda .left + 1
   248                            sbc #0
   249                            sta .res + 1
   250                          }
   251                          
   252                          ; -----------------------------------------------------------------------------
   253                          ; +incBcd: increment a BCD byte (inc instruction doesn't work in bcd mode)
   254                          ; -----------------------------------------------------------------------------
   255                          ; Inputs:
   256                          ;  addr:  address containing BCD value
   257                          ; -----------------------------------------------------------------------------
   258                          !macro incBcd .addr {
   259                            lda .addr
   260                            sed
   261                            clc
   262                            adc #1
   263                            cld
   264                            sta .addr
   265                          }
   266                          
   267                          ; -----------------------------------------------------------------------------
   268                          ; +decBcd: decrement a BCD byte (inc instruction doesn't work in bcd mode)
   269                          ; -----------------------------------------------------------------------------
   270                          ; Inputs:
   271                          ;  addr:  address containing BCD value
   272                          ; -----------------------------------------------------------------------------
   273                          !macro decBcd .addr {
   274                            lda .addr
   275                            sed
   276                            sec
   277                            sbc #1
   278                            cld
   279                            sta .addr

; ******** Source: ../kernel\hbc56kernel.inc
    17                          

; ******** Source: ../lib\ut\memory.inc
     1                          ; 6502
     2                          ;
     3                          ; Memory subroutines and macros
     4                          ;
     5                          ; Copyright (c) 2020 Troy Schrapel
     6                          ;
     7                          ; This code is licensed under the MIT license
     8                          ;
     9                          ; https://github.com/visrealm/hbc-56
    10                          ;
    11                          ;
    12                          
    13                          ; -----------------------------------------------------------------------------
    14                          ; store16: Write a 16-bit immediate value to memory
    15                          ; -----------------------------------------------------------------------------
    16                          ; Inputs:
    17                          ;	.dst: destination address
    18                          ;	.val16: 16-bit value
    19                          ; -----------------------------------------------------------------------------
    20                          !macro store16 .dst, .val16 {
    21                                  lda #<.val16
    22                                  sta .addr
    23                                  lda #>.val16
    24                                  sta .addr + 1
    25                          }
    26                          
    27                          ; -----------------------------------------------------------------------------
    28                          ; memcpy: Copy a fixed number of bytes from .src to dest
    29                          ; -----------------------------------------------------------------------------
    30                          ; Inputs:
    31                          ;	.src: source address
    32                          ;	.dst: destination address
    33                          ;	.cnt: number of bytes
    34                          ; -----------------------------------------------------------------------------
    35                          !macro memcpy .dst, .src, .cnt {
    36                          !if .cnt <= 0 {
    37                          	!error "memcpy: invalid count: ", .cnt
    38                          } else if .cnt <= 8 {
    39                          	!for i, 0, .cnt - 1 {
    40                          		lda .src + i
    41                          		sta .dst + i
    42                          	}
    43                          } else { !if .cnt <= 256 {
    44                          	ldx #0
    45                          -
    46                          	lda .src, x
    47                          	sta .dst, x
    48                          	inx
    49                          	cpx #(.cnt & $ff)	
    50                          	bne -
    51                          } else {
    52                          	lda #<.src
    53                          	sta MEM_SRC
    54                          	lda #>.src
    55                          	sta MEM_SRC + 1
    56                          
    57                          	lda #<.dst
    58                          	sta MEM_DST
    59                          	lda #>.dst
    60                          	sta MEM_DST + 1
    61                          
    62                          
    63                          		lda #<.cnt
    64                          		sta MEM_LEN
    65                          		lda #>.cnt
    66                          		sta MEM_LEN + 1
    67                          		jsr memcpyMultiPage
    68                          	}
    69                          }
    70                          }
    71                          
    72                          !macro setMemCpySrc .src {
    73                          	lda #<.src
    74                          	sta MEM_SRC
    75                          	lda #>.src
    76                          	sta MEM_SRC + 1
    77                          }
    78                          
    79                          !macro setMemCpyDst .dst {
    80                          	lda #<.dst
    81                          	sta MEM_DST
    82                          	lda #>.dst
    83                          	sta MEM_DST + 1
    84                          }
    85                          
    86                          !macro setMemCpySrcInd .srcRef {
    87                          	lda .srcRef
    88                          	sta MEM_SRC
    89                          	lda .srcRef + 1
    90                          	sta MEM_SRC + 1
    91                          }
    92                          
    93                          !macro setMemCpyDstInd .dstRef {
    94                          	lda .dstRef
    95                          	sta MEM_DST
    96                          	lda .dstRef + 1
    97                          	sta MEM_DST + 1
    98                          }
    99                          
   100                          !macro memcpySinglePage .bytes {
   101                          
   102                          	!if .bytes <= 0 {
   103                          		!error "memcpySinglePage: invalid count: ", .bytes
   104                          	}	
   105                          
   106                          	ldy #.bytes
   107                          	jsr memcpySinglePage
   108                          }
   109                          
   110                          
   111                          ; -----------------------------------------------------------------------------
   112                          ; memcpyPort: Copy a fixed number of bytes from .src ram to dest port
   113                          ; -----------------------------------------------------------------------------
   114                          ; Inputs:
   115                          ;	.src: source address
   116                          ;	.dst: destination address
   117                          ;	.cnt: number of bytes
   118                          ; -----------------------------------------------------------------------------
   119                          !macro memcpyPort .dst, .src, .cnt {
   120                          	!if .cnt <= 0 {
   121                          		!error "memcpyPort: invalid count: ", .cnt
   122                          	}
   123                          	
   124                          	lda #<.src
   125                          	sta MEM_SRC
   126                          	lda #>.src
   127                          	sta MEM_SRC + 1
   128                          
   129                          	lda #<.dst
   130                          	sta MEM_DST
   131                          	lda #>.dst
   132                          	sta MEM_DST + 1
   133                          
   134                          	!if .cnt <= 256 {
   135                          		ldy #<.cnt					
   136                          		jsr memcpySinglePagePort
   137                          	} else {
   138                          		lda #<.cnt
   139                          		sta MEM_LEN
   140                          		lda #>.cnt
   141                          		sta MEM_LEN + 1
   142                          		jsr memcpyMultiPagePort
   143                          	}
   144                          }
   145                          
   146                          !zone {
   147                          
   148                          ; -----------------------------------------------------------------------------
   149                          ; memset: Set a fixed number of bytes to a single value
   150                          ; -----------------------------------------------------------------------------
   151                          ; Inputs:
   152                          ;	.dst: destination address
   153                          ;	val: the byte value
   154                          ;	.cnt: number of bytes
   155                          ; -----------------------------------------------------------------------------
   156                          !macro memset .dst, .val, .cnt {
   157                          !if .cnt <= 0 {
   158                          	!error "memset: invalid count: ", .cnt
   159                          } else if .cnt <= 8 {
   160                          	lda #.val
   161                          	!for i, 0, .cnt - 1 {
   162                          	sta .dst + i
   163                          	}
   164                          } else if .cnt <= 256 {
   165                          	ldx #<.cnt
   166                          	lda #.val
   167                          -
   168                          	dex
   169                          	sta .dst, x
   170                          	cpx #0
   171                          	bne -
   172                          } else {
   173                          	lda #<.dst
   174                          	sta MEM_DST
   175                          	lda #>.dst
   176                          	sta MEM_DST + 1
   177                          	lda #<.cnt
   178                          	sta MEM_LEN
   179                          	lda #>.cnt
   180                          	sta MEM_LEN + 1
   181                          	lda #.val
   182                          	jsr memsetMultiPage
   183                          }
   184                          }
   185                          
   186                          

; ******** Source: ../kernel\hbc56kernel.inc
    18                          

; ******** Source: ../lib\gfx\tms9918.inc
     1                          ; 6502 - TMS9918 VDP Macros
     2                          ;
     3                          ; Copyright (c) 2021 Troy Schrapel
     4                          ;
     5                          ; This code is licensed under the MIT license
     6                          ;
     7                          ; https://github.com/visrealm/hbc-56
     8                          ;
     9                          
    10                          
    11                          
    12                          
    13                          ; -----------------------------------------------------------------------------
    14                          ; tmsWaitReg: Not sure how much delay we need so make a macro for now
    15                          ; -----------------------------------------------------------------------------
    16                          !macro tmsWaitReg {
    17                                  jsr _tmsWaitReg
    18                          }
    19                          
    20                          ; -----------------------------------------------------------------------------
    21                          ; tmsWaitData: Not sure how much delay we need so make a macro for now
    22                          ; -----------------------------------------------------------------------------
    23                          !macro tmsWaitData {
    24                                  jsr _tmsWaitData
    25                          }
    26                          
    27                          ; -----------------------------------------------------------------------------
    28                          ; tmsSetAddressWrite: Set an address in the TMS9918
    29                          ; -----------------------------------------------------------------------------
    30                          !macro tmsSetAddressWrite .addr {
    31                                  +tmsSetAddressRead ($4000 | .addr)
    32                          }
    33                          
    34                          ; -----------------------------------------------------------------------------
    35                          ; tmsSetAddressRead: Set an address to read from the TMS9918
    36                          ; -----------------------------------------------------------------------------
    37                          !macro tmsSetAddressRead .addr {
    38                                  php
    39                                  sei             ; we can't be interrupted here
    40                                  lda #<(.addr)
    41                                  sta TMS9918_REG
    42                                  +tmsWaitReg
    43                                  lda #>(.addr)
    44                                  sta TMS9918_REG
    45                                  +tmsWaitReg
    46                                  plp
    47                          }
    48                          
    49                          ; -----------------------------------------------------------------------------
    50                          ; tmsGet: Get a byte of data from the TMS9918
    51                          ; -----------------------------------------------------------------------------
    52                          !macro tmsGet {
    53                                  lda TMS9918_RAM
    54                                  +tmsWaitData
    55                          }
    56                          
    57                          ; -----------------------------------------------------------------------------
    58                          ; tmsPut: Send a byte of data to the TMS9918
    59                          ; -----------------------------------------------------------------------------
    60                          !macro tmsPut .byte {
    61                                  lda #(.byte & 0xff)
    62                                  +tmsPut
    63                          }
    64                          
    65                          
    66                          ; -----------------------------------------------------------------------------
    67                          ; tmsPut: Send a byte (A) of data to the TMS9918
    68                          ; -----------------------------------------------------------------------------
    69                          !macro tmsPut {
    70                                  sta TMS9918_RAM
    71                                  +tmsWaitData
    72                          }
    73                          
    74                          ; -----------------------------------------------------------------------------
    75                          ; tmsSetColor: Set current fg/bg color
    76                          ; -----------------------------------------------------------------------------
    77                          !macro tmsSetColor .color {
    78                                  lda #.color
    79                                  jsr tmsSetBackground
    80                          }
    81                          
    82                          ; -----------------------------------------------------------------------------
    83                          ; tmsSetColorFgBg: Set current fg/bg color
    84                          ; -----------------------------------------------------------------------------
    85                          !macro tmsSetColorFgBg .fg, .bg {
    86                                  +tmsColorFgBg .fg, .bg
    87                                  jsr tmsSetBackground
    88                          }
    89                          
    90                          ; -----------------------------------------------------------------------------
    91                          ; byteTmsColorFgBg: Output a data byte
    92                          ; -----------------------------------------------------------------------------
    93                          !macro byteTmsColorFgBg .fg, .bg {
    94                          !byte (.fg << 4 | .bg)
    95                          }
    96                          
    97                          
    98                          ; -----------------------------------------------------------------------------
    99                          ; tmsDisableOutput: Disable the TMS9918 output
   100                          ; -----------------------------------------------------------------------------
   101                          !macro tmsDisableOutput {
   102                                  lda #TMS_R1_DISP_ACTIVE
   103                                  jsr tmsReg1ClearFields
   104                          }
   105                          
   106                          ; -----------------------------------------------------------------------------
   107                          ; tmsEnableOutput: Enable the TMS9918 output
   108                          ; -----------------------------------------------------------------------------
   109                          !macro tmsEnableOutput {
   110                                  lda #TMS_R1_DISP_ACTIVE
   111                                  jsr tmsReg1SetFields
   112                          }
   113                          
   114                          ; -
   115                          !macro tmsEnableInterrupts {
   116                                  lda #TMS_R1_INT_ENABLE
   117                                  jsr tmsReg1SetFields
   118                          }
   119                          
   120                          !macro tmsDisableInterrupts {
   121                                  lda #TMS_R1_INT_ENABLE
   122                                  jsr tmsReg1ClearFields
   123                          }
   124                          
   125                          !macro tmsConsoleOut .char {
   126                                  lda #.char
   127                                  jsr tmsConsoleOut
   128                          }
   129                          
   130                          
   131                          ; -----------------------------------------------------------------------------
   132                          ; tmsConsolePrintAddr: Print text to console
   133                          ; -----------------------------------------------------------------------------
   134                          ; Inputs:
   135                          ;  textAddr: Address of null-terminated string to print
   136                          ; -----------------------------------------------------------------------------
   137                          !macro tmsConsolePrintAddr .textAddr {
   138                                  lda #<.textAddr
   139                                  sta STR_ADDR_L
   140                                  lda #>.textAddr
   141                                  sta STR_ADDR_H
   142                                  jsr tmsConsolePrint        
   143                          }
   144                          
   145                          ; -----------------------------------------------------------------------------
   146                          ; tmsConsolePrint: Print immediate text to console
   147                          ; -----------------------------------------------------------------------------
   148                          ; Inputs:
   149                          ;  str: String to print
   150                          ; -----------------------------------------------------------------------------
   151                          !macro tmsConsolePrint .str {
   152                          	jmp .afterText
   153                          .textAddr
   154                          	!text .str,0
   155                          .afterText        
   156                                  +tmsConsolePrintAddr .textAddr
   157                          }
   158                          
   159                          ; -----------------------------------------------------------------------------
   160                          ; +tmsColorFgBg: Set A to the given FG / BG color
   161                          ; -----------------------------------------------------------------------------
   162                          !macro tmsColorFgBg .fg, .bg {
   163                                  lda #(.fg << 4 | .bg)
   164                          }
   165                          
   166                          ; -----------------------------------------------------------------------------
   167                          ; tmsReadStatus: Read status - clear interrupt
   168                          ; -----------------------------------------------------------------------------
   169                          !macro tmsReadStatus  {
   170                                  bit TMS9918_REG
   171                          }
   172                          
   173                          ; -----------------------------------------------------------------------------
   174                          ; tmsSendData: Send # bytes from .sourceAddr to tms9918 data port
   175                          ; -----------------------------------------------------------------------------
   176                          !macro tmsSendData .sourceAddr, .numBytes {
   177                                  lda #<.sourceAddr
   178                                  sta TMS_TMP_ADDRESS
   179                                  lda #>.sourceAddr
   180                                  sta TMS_TMP_ADDRESS + 1
   181                          
   182                                  !if .numBytes < 256 {
   183                                          ldx #.numBytes
   184                                          jsr tmsSendBytes
   185                                  } else {
   186                                          !do while .numBytes > 0 {
   187                                                  !if .numBytes > 255 {
   188                                                          ldx #0
   189                                                          !set .numBytes = .numBytes - 256
   190                                                  } else {
   191                                                          ldx #.numBytes
   192                                                          !set .numBytes = 0
   193                                                  }
   194                                                  jsr tmsSendBytes
   195                                                  inc TMS_TMP_ADDRESS + 1
   196                                          }
   197                                  }
   198                          
   199                          }
   200                          
   201                          ; -----------------------------------------------------------------------------
   202                          ; tmsSendDataRpt: Send # bytes from .sourceAddr to tms9918 data port .rpt times
   203                          ; -----------------------------------------------------------------------------
   204                          !macro tmsSendDataRpt .sourceAddr, .numBytes, .rpt {
   205                                  lda #<.sourceAddr
   206                                  sta TMS_TMP_ADDRESS
   207                                  lda #>.sourceAddr
   208                                  sta TMS_TMP_ADDRESS + 1
   209                          
   210                                  !if .numBytes < 256 {
   211                                          !if .rpt < 5 {
   212                                                  !for i,1,.rpt {
   213                                                          ldx #.numBytes
   214                                                          jsr tmsSendBytes
   215                                                  }
   216                                          } else {
   217                                                  lda #.rpt
   218                                                  sta TMS9918_TMP_BUFFER
   219                          -
   220                                                  ldx #.numBytes
   221                                                  jsr tmsSendBytes
   222                                                  dec TMS9918_TMP_BUFFER
   223                                                  bne -
   224                                          }
   225                                  } else {
   226                                          !error "tmsSendDataRpt supports <256 bytes only"
   227                                  }
   228                          }
   229                          
   230                          
   231                          ; -----------------------------------------------------------------------------
   232                          ; tmsPutRpt: Send value .rpt times
   233                          ; -----------------------------------------------------------------------------
   234                          !macro tmsPutRpt .value, .rpt {
   235                                  ldx #.rpt
   236                                  lda #.value
   237                          -
   238                                  +tmsPut
   239                                  dex
   240                                  bne -
   241                          }
   242                          
   243                          !macro tmsPutSeq .from, .count {
   244                                  lda #.from
   245                          -
   246                                  +tmsPut
   247                                  inc
   248                                  cmp #<(.from + .count)
   249                                  bne -
   250                          }
   251                          
   252                          !macro tmsSetSourceAddressInd .addr {
   253                          	lda .addr
   254                          	sta TMS_TMP_ADDRESS
   255                          	lda .addr + 1
   256                          	sta TMS_TMP_ADDRESS + 1
   257                          }
   258                          
   259                          !macro tmsSetSourceAddressIndOffset .addr, .offset {
   260                                  clc
   261                          	lda .addr
   262                                  adc #<.offset
   263                          	sta TMS_TMP_ADDRESS
   264                          	lda .addr + 1
   265                                  adc #>.offset
   266                          	sta TMS_TMP_ADDRESS + 1
   267                          }
   268                          
   269                          
   270                          !macro tmsSendBytes .bytes {
   271                                  ldx #.bytes
   272                                  jsr tmsSendBytes
   273                          }
   274                          
   275                          
   276                          ; -----------------------------------------------------------------------------
   277                          ; tmsSetAddrPattTable: Initialise address for font table
   278                          ; -----------------------------------------------------------------------------
   279                          !macro tmsSetAddrPattTable {
   280                                  +tmsSetAddrPattTable 0
   281                          }
   282                          
   283                          ; -----------------------------------------------------------------------------
   284                          ; tmsSetAddrPattTable: Initialise address for pattern table
   285                          ; -----------------------------------------------------------------------------
   286                          !macro tmsSetAddrPattTable .ind {
   287                                  +tmsSetAddressWrite TMS_VRAM_PATT_ADDRESS + (8 * .ind)
   288                          }
   289                          
   290                          ; -----------------------------------------------------------------------------
   291                          ; tmsSetAddrPattTable: Initialise address for pattern table
   292                          ; -----------------------------------------------------------------------------
   293                          !macro tmsSetAddrPattTable .ind, .row {
   294                                  +tmsSetAddressWrite TMS_VRAM_PATT_ADDRESS + (8 * .ind) + .row
   295                          }
   296                          
   297                          ; -----------------------------------------------------------------------------
   298                          ; tmsSetAddrPattTableIIBank0: Initialise address for pattern table
   299                          ; -----------------------------------------------------------------------------
   300                          !macro tmsSetAddrPattTableIIBank0 .ind {
   301                                  +tmsSetAddrPattTable .ind
   302                          }
   303                          
   304                          ; -----------------------------------------------------------------------------
   305                          ; tmsSetAddrPattTableIIBank1: Initialise address for pattern table
   306                          ; -----------------------------------------------------------------------------
   307                          !macro tmsSetAddrPattTableIIBank1 .ind {
   308                                  +tmsSetAddrPattTable 256 + .ind
   309                          }
   310                          
   311                          ; -----------------------------------------------------------------------------
   312                          ; tmsSetAddrPattTableIIBank2: Initialise address for pattern table
   313                          ; -----------------------------------------------------------------------------
   314                          !macro tmsSetAddrPattTableIIBank2 .ind {
   315                                  +tmsSetAddrPattTable 512 + .ind
   316                          }
   317                          
   318                          ; -----------------------------------------------------------------------------
   319                          ; tmsSetAddrPattTableRead: Initialise address for pattern table to read
   320                          ; -----------------------------------------------------------------------------
   321                          !macro tmsSetAddrPattTableRead .ind {
   322                                  +tmsSetAddressRead TMS_VRAM_PATT_ADDRESS + (8 * .ind)
   323                          }
   324                          
   325                          ; -----------------------------------------------------------------------------
   326                          ; tmsSetAddrPattTableRowRead: Initialise address for pattern table to read
   327                          ; -----------------------------------------------------------------------------
   328                          !macro tmsSetAddrPattTableRead .ind, .row {
   329                                  +tmsSetAddressRead TMS_VRAM_PATT_ADDRESS + (8 * .ind) + .row
   330                          }
   331                          
   332                          ; -----------------------------------------------------------------------------
   333                          ; tmsUpdateFont: Update the pattern table with a given font
   334                          ; -----------------------------------------------------------------------------
   335                          !macro tmsUpdateFont .fontAddr {
   336                                  +tmsSetAddrPattTable 32
   337                                  +tmsSendData .fontAddr, $300
   338                          }
   339                          
   340                          ; -----------------------------------------------------------------------------
   341                          ; tmsSetAddrNameTable: Initialise address for base (text) table
   342                          ; -----------------------------------------------------------------------------
   343                          !macro tmsSetAddrNameTable {
   344                                  +tmsSetAddressWrite TMS_VRAM_NAME_ADDRESS
   345                          }
   346                          
   347                          ; -----------------------------------------------------------------------------
   348                          ; tmsSetAddrColorTable: Initialise address for color table
   349                          ; -----------------------------------------------------------------------------
   350                          !macro tmsSetAddrColorTable {
   351                                  +tmsSetAddressWrite TMS_VRAM_COLOR_ADDRESS
   352                          }
   353                          
   354                          ; -----------------------------------------------------------------------------
   355                          ; tmsSetAddrColorTable: Initialise address for color table index
   356                          ; -----------------------------------------------------------------------------
   357                          !macro tmsSetAddrColorTable .ind {
   358                                  +tmsSetAddressWrite TMS_VRAM_COLOR_ADDRESS + .ind
   359                          }
   360                          
   361                          ; -----------------------------------------------------------------------------
   362                          ; tmsSetAddrColorTableII: Initialise address for color table index (mode II)
   363                          ; -----------------------------------------------------------------------------
   364                          !macro tmsSetAddrColorTableII .ind {
   365                                  +tmsSetAddressWrite TMS_VRAM_COLOR_ADDRESS + .ind * 8
   366                          }
   367                          
   368                          ; -----------------------------------------------------------------------------
   369                          ; tmsSetAddrColorTableIIBank0: Initialise address for color table index (mode II)
   370                          ; -----------------------------------------------------------------------------
   371                          !macro tmsSetAddrColorTableIIBank0 .ind {
   372                                  +tmsSetAddrColorTableII .ind
   373                          }
   374                          
   375                          ; -----------------------------------------------------------------------------
   376                          ; tmsSetAddrColorTableIIBank1: Initialise address for color table index (mode II)
   377                          ; -----------------------------------------------------------------------------
   378                          !macro tmsSetAddrColorTableIIBank1 .ind {
   379                                  +tmsSetAddrColorTableII 256 + .ind
   380                          }
   381                          
   382                          ; -----------------------------------------------------------------------------
   383                          ; tmsSetAddrColorTableIIBank2: Initialise address for color table index (mode II)
   384                          ; -----------------------------------------------------------------------------
   385                          !macro tmsSetAddrColorTableIIBank2 .ind {
   386                                  +tmsSetAddrColorTableII 512 + .ind
   387                          }
   388                          
   389                          ; -----------------------------------------------------------------------------
   390                          ; tmsSetAddrSpriteAttrTable: Initialise address for sprite attributes table
   391                          ; -----------------------------------------------------------------------------
   392                          !macro tmsSetAddrSpriteAttrTable {
   393                                  +tmsSetAddrSpriteAttrTable 0
   394                          }
   395                          
   396                          ; -----------------------------------------------------------------------------
   397                          ; tmsSetAddrSpriteAttrTable: Initialise address for sprite attributes table
   398                          ; -----------------------------------------------------------------------------
   399                          !macro tmsSetAddrSpriteAttrTable .index {
   400                                  +tmsSetAddressWrite TMS_VRAM_SPRITE_ATTR_ADDRESS + .index * 4
   401                          }
   402                          
   403                          ; -----------------------------------------------------------------------------
   404                          ; tmsSetAddrSpritePattTable: Initialise address for sprite pattern table
   405                          ; -----------------------------------------------------------------------------
   406                          !macro tmsSetAddrSpritePattTable {
   407                                  +tmsSetAddrSpritePattTable 0
   408                          }
   409                          
   410                          ; -----------------------------------------------------------------------------
   411                          ; tmsSetAddrSpritePattTable: Initialise address for sprite pattern table
   412                          ; -----------------------------------------------------------------------------
   413                          !macro tmsSetAddrSpritePattTable .index {
   414                                  +tmsSetAddressWrite TMS_VRAM_SPRITE_PATT_ADDRESS + .index * 8
   415                          }
   416                          
   417                          
   418                          ; -----------------------------------------------------------------------------
   419                          ; tmsCreateSpritePattern: Create a sprite pattern (.spriteDataAddr is 8 bytes)
   420                          ; -----------------------------------------------------------------------------
   421                          !macro tmsCreateSpritePattern .pattInd, .spriteDataAddr {
   422                          
   423                                  
   424                          
   425                                  ; sprite pattern table
   426                                  +tmsSetAddrSpritePattTable .pattInd
   427                          
   428                                  ldx #0
   429                          -
   430                                  lda .spriteDataAddr,x
   431                                  +tmsPut
   432                                  inx
   433                                  cpx #8
   434                          
   435                                  
   436                          
   437                                  bne -
   438                          }
   439                          
   440                          ; -----------------------------------------------------------------------------
   441                          ; tmsCreateSpritePatternQuad: Create a (size 1) sprite pattern 
   442                          ;   (.spriteDataAddr is 32 bytes)
   443                          ; -----------------------------------------------------------------------------
   444                          !macro tmsCreateSpritePatternQuad .pattInd, .spriteDataAddr {
   445                          
   446                                  
   447                          
   448                                  ; sprite pattern table
   449                                  +tmsSetAddrSpritePattTable .pattInd * 4
   450                          
   451                                  ldx #0
   452                          -
   453                                  lda .spriteDataAddr,x
   454                                  +tmsPut 
   455                                  inx
   456                                  cpx #32
   457                          
   458                                  
   459                          
   460                                  bne -
   461                          }
   462                          
   463                          
   464                          !macro tmsCreateSpritePatternImm .ind, .b0, .b1, .b2, .b3, .b4, .b5, .b6, .b7 {
   465                          
   466                                  ; sprite pattern table
   467                                  +tmsSetAddrSpritePattTable .ind
   468                                  +tmsPut .b0
   469                                  +tmsPut .b2
   470                                  +tmsPut .b2
   471                                  +tmsPut .b3
   472                                  +tmsPut .b4
   473                                  +tmsPut .b5
   474                                  +tmsPut .b6
   475                                  +tmsPut .b7
   476                          }
   477                          
   478                          !macro tmsCreatePatternImm .ind, .b0, .b1, .b2, .b3, .b4, .b5, .b6, .b7 {
   479                          
   480                                  ; sprite pattern table
   481                                  +tmsSetAddrPattTable .ind
   482                                  +tmsPut .b0
   483                                  +tmsPut .b2
   484                                  +tmsPut .b2
   485                                  +tmsPut .b3
   486                                  +tmsPut .b4
   487                                  +tmsPut .b5
   488                                  +tmsPut .b6
   489                                  +tmsPut .b7
   490                          }
   491                          
   492                          
   493                          ; -----------------------------------------------------------------------------
   494                          ; tmsCreateSprite: Create a sprite
   495                          ; -----------------------------------------------------------------------------
   496                          !macro tmsCreateSprite .ind, .pattInd, .xPos, .yPos, .color {
   497                          
   498                                  ; sprite attr table
   499                                  +tmsSetAddrSpriteAttrTable .ind
   500                          
   501                                  +tmsPut .yPos
   502                                  +tmsPut .xPos
   503                                  +tmsPut .pattInd
   504                                  +tmsPut .color
   505                          }
   506                          
   507                          ; -----------------------------------------------------------------------------
   508                          ; tmsSpritePos: Set a sprite position
   509                          ; -----------------------------------------------------------------------------
   510                          !macro tmsSpritePos .ind, .xPos, .yPos {
   511                                  
   512                          
   513                                  ; sprite attr table
   514                                  +tmsSetAddrSpriteAttrTable .ind
   515                          
   516                                  +tmsPut .yPos
   517                                  +tmsPut .xPos        
   518                          }
   519                          
   520                          
   521                          ; -----------------------------------------------------------------------------
   522                          ; tmsSetLastSprite: Mark a sprite as the last sprite (set next ypos to )
   523                          ; -----------------------------------------------------------------------------
   524                          !macro tmsSetLastSprite .ind {
   525                                  +tmsSpritePos .ind + 1, 0, $d0
   526                          }
   527                          
   528                          
   529                          ; -----------------------------------------------------------------------------
   530                          ; tmsSpritePosXYReg: Set a sprite position from x/y registers
   531                          ; -----------------------------------------------------------------------------
   532                          !macro tmsSpritePosXYReg .ind {
   533                                  
   534                          
   535                                  ; sprite attr table
   536                                  +tmsSetAddrSpriteAttrTable .ind
   537                          
   538                                  tya
   539                                  +tmsPut 
   540                                  txa
   541                                  +tmsPut 
   542                          }
   543                          
   544                          
   545                          ; -----------------------------------------------------------------------------
   546                          ; tmsSetAddrSpriteColor: Change a sprite color
   547                          ; -----------------------------------------------------------------------------
   548                          !macro tmsSetAddrSpriteColor .ind {
   549                          
   550                                  ; sprite attr table
   551                                  +tmsSetAddressWrite TMS_VRAM_SPRITE_ATTR_ADDRESS + (.ind * 4) + 3
   552                          }
   553                          ; -----------------------------------------------------------------------------
   554                          ; tmsSpriteColor: Change a sprite color
   555                          ; -----------------------------------------------------------------------------
   556                          !macro tmsSpriteColor .ind, .color {
   557                          
   558                                  +tmsSetAddrSpriteColor .ind
   559                          
   560                                  +tmsPut .color
   561                          }
   562                          
   563                          
   564                          ; -----------------------------------------------------------------------------
   565                          ; tmsSetPosWrite: Set cursor position
   566                          ; -----------------------------------------------------------------------------
   567                          !macro tmsSetPosWrite .x, .y {
   568                                  +tmsSetAddressWrite (TMS_VRAM_NAME_ADDRESS + .y * 32 + .x)
   569                          }
   570                          
   571                          ; -----------------------------------------------------------------------------
   572                          ; tmsSetPosRead: Set read cursor position
   573                          ; -----------------------------------------------------------------------------
   574                          !macro tmsSetPosRead .x, .y {
   575                                  +tmsSetAddressRead (TMS_VRAM_NAME_ADDRESS + .y * 32 + .x)
   576                          }
   577                          
   578                          ; -----------------------------------------------------------------------------
   579                          ; tmsPrint: Print immediate text
   580                          ; -----------------------------------------------------------------------------
   581                          ; Inputs:
   582                          ;  str: String to print
   583                          ;  x: x position
   584                          ;  y: y position
   585                          ; -----------------------------------------------------------------------------
   586                          !macro tmsPrint .str, .x, .y {
   587                          	jmp .afterText
   588                          .textAddr
   589                          	!text .str,0
   590                          .afterText        
   591                          
   592                                  +tmsSetPosWrite .x, .y
   593                          
   594                                  lda #<.textAddr
   595                                  sta STR_ADDR_L
   596                                  lda #>.textAddr
   597                                  sta STR_ADDR_H
   598                                  jsr tmsPrint        
   599                          }
   600                          
   601                          
   602                          ; -----------------------------------------------------------------------------
   603                          ; tmsPrintCentre: Print centre-aligned immediate text
   604                          ; -----------------------------------------------------------------------------
   605                          ; Inputs:
   606                          ;  str: String to print
   607                          ;  y: y position
   608                          ; -----------------------------------------------------------------------------
   609                          !macro tmsPrintCentre .str, .y {
   610                          	jmp .afterText
   611                          .textAddr
   612                          	!text .str,0
   613                          .afterText        
   614                          
   615                                  +tmsSetPosWrite (32 - ((.afterText - 1) - .textAddr)) / 2, .y
   616                          
   617                                  lda #<.textAddr
   618                                  sta STR_ADDR_L
   619                                  lda #>.textAddr
   620                                  sta STR_ADDR_H
   621                                  jsr tmsPrint        
   622                          }
   623                          
   624                          
   625                          ; -----------------------------------------------------------------------------
   626                          ; tmsPrintZ: Print text
   627                          ; -----------------------------------------------------------------------------
   628                          ; Inputs:
   629                          ;  str: Address of zero-terminated string to print
   630                          ;  x: x position
   631                          ;  y: y position
   632                          ; -----------------------------------------------------------------------------
   633                          !macro tmsPrintZ .textAddr, .x, .y {
   634                                  +tmsSetPosWrite .x, .y
   635                          
   636                                  lda #<.textAddr
   637                                  sta STR_ADDR_L
   638                                  lda #>.textAddr
   639                                  sta STR_ADDR_H
   640                                  jsr tmsPrint        
   641                          }

; ******** Source: ../kernel\hbc56kernel.inc
    19                          

; ******** Source: ../lib\gfx\tilemap.inc
     1                          ; 6502 - Tilemap
     2                          ;
     3                          ; Copyright (c) 2021 Troy Schrapel
     4                          ;
     5                          ; This code is licensed under the MIT license
     6                          ;
     7                          ; https://github.com/visrealm/hbc-56
     8                          ;
     9                          ;
    10                          
    11                          
    12                          
    13                          !macro tilemapCreate .tilemapStructAddr, .bufferAddr, .tilesetAddr, .sizeFlags, .tileSizePx, .invertAddr, .dirtyAddr {
    14                          	!if <.tilesetAddr != 0 { !error "tilemapCreate: Tileset address must be page-aligned",.tilesetAddr }
    15                          	!if >.tilesetAddr < 3 { !error "tilemapCreate: Tileset address must be greater than $2ff",.tilesetAddr }
    16                          	!if <.bufferAddr != 0 { !error "tilemapCreate: Buffer address must be page-aligned",.bufferAddr }
    17                          	!if >.bufferAddr < 3 { !error "tilemapCreate: Buffer address must be greater than $2ff",.bufferAddr }
    18                          	!if .invertAddr != 0 and <.invertAddr != 0  {!error "tilemapCreate: Invert address must be page-aligned", .invertAddr}
    19                          	!if .invertAddr != 0 and >.invertAddr < 3  {!error "tilemapCreate: Invert address must be greater than $2ff", .invertAddr}
    20                          	!if .dirtyAddr != 0 and <.dirtyAddr != 0  {!error "tilemapCreate: Dirty address must be page-aligned", .dirtyAddr}
    21                          	!if .dirtyAddr != 0 and >.dirtyAddr < 3  {!error "tilemapCreate: Dirty address must be greater than $2ff", .dirtyAddr}
    22                          	!if .tileSizePx != 4 and .tileSizePx != 8 {!error "tilemapCreate: Tile size must be 4 or 8 pixels",.tileSizePx}
    23                          
    24                          	lda #<.tilemapStructAddr
    25                          	sta TILEMAP_ADDR
    26                          	lda #>.tilemapStructAddr
    27                          	sta TILEMAP_ADDR + 1
    28                          
    29                          	lda #>.bufferAddr
    30                          	sta .tilemapStructAddr + TILEMAP_BUFFER_ADDR
    31                          	lda #.sizeFlags
    32                          	sta .tilemapStructAddr + TILEMAP_SIZE
    33                          	lda #>.tilesetAddr
    34                          	sta .tilemapStructAddr + TILEMAP_TILES_ADDR
    35                          	lda #>.invertAddr
    36                          	sta .tilemapStructAddr + TILEMAP_INVERT_ADDR
    37                          	lda #>.dirtyAddr
    38                          	sta .tilemapStructAddr + TILEMAP_DIRTY_ADDR
    39                          	lda #.tileSizePx
    40                          	sta .tilemapStructAddr + TILEMAP_TILE_SIZE_PX
    41                          
    42                          	jsr tilemapInit
    43                          }
    44                          
    45                          !macro tilemapCreateDefault .sizeFlags, .tilesetAddr {
    46                          	+tilemapCreate TILEMAP_FIXED_ADDRESS, TILEMAP_DEFAULT_BUFFER_ADDRESS, .tilesetAddr, .sizeFlags, 8, $0, $0
    47                          }
    48                          
    49                          !macro tilemapSetActive .tilemapStructAddr {
    50                          	lda #<.tilemapStructAddr
    51                          	sta TILEMAP_ADDR
    52                          	lda #>.tilemapStructAddr
    53                          	sta TILEMAP_ADDR + 1
    54                          
    55                          	jsr tilemapSetActive

; ******** Source: ../kernel\hbc56kernel.inc
    20                          

; ******** Source: ../lib\lcd\lcd.inc
     1                          ; 6502 LCD Macros - HBC-56
     2                          ;
     3                          ; Copyright (c) 2021 Troy Schrapel
     4                          ;
     5                          ; This code is licensed under the MIT license
     6                          ;
     7                          ; https://github.com/visrealm/hbc-56
     8                          ;
     9                          
    10                          ; -----------------------------------------------------------------------------
    11                          ; lcdPrint: Print immediate text
    12                          ; -----------------------------------------------------------------------------
    13                          ; Inputs:
    14                          ;  str: String to print
    15                          ; -----------------------------------------------------------------------------
    16                          !macro lcdPrint str {
    17                          	jmp +
    18                          .textAddr
    19                          	!text str,0
    20                          +
    21                          	lda #<.textAddr
    22                          	sta STR_ADDR_L
    23                          	lda #>.textAddr
    24                          	sta STR_ADDR_H
    25                          	jsr lcdPrint
    26                          }
    27                          
    28                          
    29                          ; -----------------------------------------------------------------------------
    30                          ; lcdChar: Print immediate character
    31                          ; -----------------------------------------------------------------------------
    32                          ; Inputs:
    33                          ;  c: Character to print
    34                          ; -----------------------------------------------------------------------------
    35                          !macro lcdChar c {
    36                          	pha
    37                          	lda #c
    38                          	jsr lcdChar
    39                          	pla
    40                          }
    41                          
    42                          
    43                          ; -----------------------------------------------------------------------------
    44                          ; lcdConsolePrint: Print immediate text to console
    45                          ; -----------------------------------------------------------------------------
    46                          ; Inputs:
    47                          ;  str: String to print
    48                          ; -----------------------------------------------------------------------------
    49                          !macro lcdConsolePrint .str {
    50                          	jmp .afterText
    51                          .textAddr
    52                          	!text .str,0
    53                          .afterText        
    54                          
    55                                  lda #<.textAddr
    56                                  sta STR_ADDR_L
    57                                  lda #>.textAddr
    58                                  sta STR_ADDR_H
    59                                  jsr lcdConsolePrint        

; ******** Source: ../kernel\hbc56kernel.inc
    21                          

; ******** Source: ../lib\inp\nes.inc
     1                          ; 6502 NES Controller Macros - HBC-56
     2                          ;
     3                          ; Copyright (c) 2021 Troy Schrapel
     4                          ;
     5                          ; This code is licensed under the MIT license
     6                          ;
     7                          ; https://github.com/visrealm/hbc-56
     8                          ;
     9                          ; Dependencies:
    10                          ;  - hbc56.asm
    11                          
    12                          
    13                          !macro nes1BranchIfPressed .buttonMask, .addr {
    14                                  pha
    15                                  lda #(.buttonMask)
    16                                  jsr nes1Pressed
    17                                  pla
    18                                  bcs .addr
    19                          }
    20                          
    21                          !macro nes1BranchIfNotPressed .buttonMask, .addr {
    22                                  pha
    23                                  lda #(.buttonMask)
    24                                  jsr nes1Pressed
    25                                  pla
    26                                  bcc .addr
    27                          }
    28                          
    29                          !macro nes2BranchIfPressed .buttonMask, addr {
    30                                  pha
    31                                  lda #(.buttonMask)
    32                                  jsr nes2Pressed
    33                                  pla
    34                                  bcs addr
    35                          }
    36                          
    37                          !macro nes2BranchIfNotPressed .buttonMask, addr {
    38                                  pha
    39                                  lda #(.buttonMask)
    40                                  jsr nes2Pressed
    41                                  pla
    42                                  bcc addr
    43                          }

; ******** Source: ../kernel\hbc56kernel.inc
    22                          

; ******** Source: ../lib\inp\keyboard.inc
     1                          ; 6502 KB Controller Macros - HBC-56
     2                          ;
     3                          ; Copyright (c) 2021 Troy Schrapel
     4                          ;
     5                          ; This code is licensed under the MIT license
     6                          ;
     7                          ; https://github.com/visrealm/hbc-56
     8                          ;
     9                          ; Dependencies:
    10                          ;  - hbc56.asm
    11                          
    12                          
    13                          !macro kbBranchIfNotPressed .scancode, .addr {
    14                                  ldx #.scancode
    15                                  jsr kbReadAscii
    16                                  beq .addr
    17                          }
    18                          
    19                          !macro kbBranchIfPressed .scancode, .addr {
    20                                  ldx #.scancode
    21                                  jsr kbIsPressed
    22                                  bne .addr
    23                          }
    24                          
    25                          !macro kbSetEventHandlerPressed .cb {
    26                                  lda #<.cb
    27                                  sta KB_CB_PRESSED
    28                                  lda #>.cb
    29                                  sta KB_CB_PRESSED + 1
    30                          }
    31                          
    32                          !macro kbSetEventHandlerReleased .cb {
    33                                  lda #<.cb
    34                                  sta KB_CB_RELEASED
    35                                  lda #>.cb
    36                                  sta KB_CB_RELEASED + 1

; ******** Source: ../kernel\hbc56kernel.inc
    23                          

; ******** Source: ../lib\sfx\ay3891x.inc
     1                          ; 6502 - AY-3-819x PSG
     2                          ;
     3                          ; Copyright (c) 2021 Troy Schrapel
     4                          ;
     5                          ; This code is licensed under the MIT license
     6                          ;
     7                          ; https://github.com/visrealm/hbc-56
     8                          ;
     9                          
    10                          
    11                          
    12                          !macro ayWrite .dev, .reg, .val {
    13                                  lda #.reg
    14                                  sta IO_PORT_BASE_ADDRESS | AY_IO_PORT | AY_ADDR | .dev
    15                                  lda #.val
    16                                  sta IO_PORT_BASE_ADDRESS | AY_IO_PORT | AY_WRITE | .dev
    17                          }        
    18                          
    19                          !macro ayRead .dev, .reg {
    20                                  lda #.reg
    21                                  sta IO_PORT_BASE_ADDRESS | AY_IO_PORT | AY_ADDR | .dev
    22                                  lda IO_PORT_BASE_ADDRESS | AY_IO_PORT | AY_READ | .dev
    23                          }        
    24                          
    25                          
    26                          !macro ayWriteX .dev, .reg {
    27                                  lda #.reg
    28                                  sta IO_PORT_BASE_ADDRESS | AY_IO_PORT | AY_ADDR | .dev
    29                                  stx IO_PORT_BASE_ADDRESS | AY_IO_PORT | AY_WRITE | .dev
    30                          }
    31                          
    32                          !macro ayWriteA .dev, .reg {
    33                                  ldx #.reg
    34                                  stx IO_PORT_BASE_ADDRESS | AY_IO_PORT | AY_ADDR | .dev
    35                                  sta IO_PORT_BASE_ADDRESS | AY_IO_PORT | AY_WRITE | .dev
    36                          }
    37                          
    38                          !macro ayPlayNote .dev, .chan, .freq {
    39                                  !if .freq <= 0 {
    40                                          .val = 0
    41                                  } else {
    42                                          .val = AY_CLOCK_FREQ / (32.0 * .freq)
    43                                  }
    44                                  +ayWrite .dev, AY_CHA_TONE_L + (.chan * 2), <.val
    45                                  +ayWrite .dev, AY_CHA_TONE_H + (.chan * 2), >.val
    46                          }
    47                          
    48                          !macro ayToneWord .freq {
    49                                  !word (AY_CLOCK_FREQ / (32.0 * .freq))
    50                          }
    51                          
    52                          !macro ayToneByteL .freq {
    53                                  !byte <(AY_CLOCK_FREQ / (32.0 * .freq))
    54                          }
    55                          
    56                          !macro ayToneByteH .freq {
    57                                  !byte >(AY_CLOCK_FREQ / (32.0 * .freq))
    58                          }
    59                          
    60                          
    61                          !macro ayToneEnable .dev, .chan {
    62                                  +ayRead .dev, AY_ENABLES
    63                                  and #!($01 << .chan)
    64                                  +ayWriteA .dev, AY_ENABLES
    65                          }
    66                          
    67                          !macro ayToneDisable .dev, .chan {
    68                                  +ayRead .dev, AY_ENABLES
    69                                  ora #($01 << .chan)
    70                                  +ayWriteA .dev, AY_ENABLES
    71                          }
    72                          
    73                          !macro ayNoiseEnable .dev, .chan {
    74                                  +ayRead .dev, AY_ENABLES
    75                                  eor #($08 << .chan)
    76                                  +ayWriteA .dev, AY_ENABLES
    77                          }
    78                          
    79                          !macro ayNoiseDisable .dev, .chan {
    80                                  +ayRead .dev, AY_ENABLES
    81                                  ora #($08 << .chan)
    82                                  +ayWriteA .dev, AY_ENABLES
    83                          }
    84                          
    85                          !macro aySetVolume .dev, .chan, .vol {
    86                                  +ayWrite .dev, (AY_CHA_AMPL + .chan), (.vol >> 4)
    87                          }
    88                          
    89                          !macro aySetVolumeEnvelope .dev, .chan {
    90                                  +ayWrite .dev, (AY_CHA_AMPL + .chan), $10
    91                          }
    92                          
    93                          !macro aySetEnvelopePeriod .dev, .period {
    94                                  +ayWrite .dev, AY_ENV_PERIOD_L, <.period
    95                                  +ayWrite .dev, AY_ENV_PERIOD_H, >.period
    96                          }
    97                          
    98                          !macro aySetEnvShape .dev, .shape {
    99                                  +ayWrite .dev, AY_ENV_SHAPE, .shape
   100                          }
   101                          
   102                          !macro aySetNoise .dev, .freq {
   103                                  +ayWrite .dev, AY_ENV_SHAPE, .freq >> 3
   104                          }
   105                          
   106                          !macro ayStop .dev, .chan {
   107                                  +ayPlayNote .dev, .chan, 0
   108                          }

; ******** Source: ../kernel\hbc56kernel.inc
    24                          

; ******** Source: ../lib\ser\uart.inc
     1                          ; 6502 - MC68B50 UART Macros
     2                          ;
     3                          ; Copyright (c) 2021 Troy Schrapel
     4                          ;
     5                          ; This code is licensed under the MIT license
     6                          ;
     7                          ; https://github.com/visrealm/hbc-56
     8                          ;
     9                          
    10                          ; -----------------------------------------------------------------------------
    11                          ; uartOutStringAddr: Output a string to the uart
    12                          ; -----------------------------------------------------------------------------
    13                          ; Inputs:
    14                          ;  .addr: Address of null-terminated string to print
    15                          ; -----------------------------------------------------------------------------
    16                          !macro uartOutStringAddr .addr {
    17                                  lda #<.addr
    18                                  sta STR_ADDR_L
    19                                  lda #>.addr
    20                                  sta STR_ADDR_H
    21                                  jsr uartOutString        
    22                          }
    23                          
    24                          
    25                          ; -----------------------------------------------------------------------------
    26                          ; uartOutString: Output an immediate string to the uart
    27                          ; -----------------------------------------------------------------------------
    28                          ; Inputs:
    29                          ;  .str: String to output
    30                          ; -----------------------------------------------------------------------------
    31                          !macro uartOutString .str {
    32                          	jmp @afterText
    33                          @textAddr
    34                          	!text .str,0
    35                          @afterText        
    36                                  +uartOutStringAddr @textAddr
    37                          }
    38                          

; ******** Source: ../kernel\hbc56kernel.inc
    25                          

; ******** Source: ../kernel\kernel.inc
     1                          ; 6502 - HBC-56 Kernel Macros
     2                          ;
     3                          ; Copyright (c) 2021 Troy Schrapel
     4                          ;
     5                          ; This code is licensed under the MIT license
     6                          ;
     7                          ; https://github.com/visrealm/hbc-56
     8                          ;
     9                          ;
    10                          
    11                          !macro setIntHandler .address {
    12                                  lda #<.address
    13                                  sta HBC56_INT_VECTOR + 1
    14                                  lda #>.address
    15                                  sta HBC56_INT_VECTOR + 2
    16                                  lda #JMP_OPCODE
    17                                  sta HBC56_INT_VECTOR
    18                          }
    19                          
    20                          !macro setNmiHandler .address {
    21                                  lda #<.address
    22                                  sta HBC56_NMI_VECTOR + 1
    23                                  lda #>.address
    24                                  sta HBC56_NMI_VECTOR + 2
    25                                  lda #JMP_OPCODE
    26                                  sta HBC56_NMI_VECTOR
    27                          }
    28                          
    29                          !macro setHbcMetaNES {
    30                                  lda #HBC56_CONSOLE_FLAG_NES
    31                                  ora HBC56_CONSOLE_FLAGS
    32                                  sta HBC56_CONSOLE_FLAGS
    33                          }
    34                          
    35                          !macro setHbcMetaNoWait {
    36                                  lda #HBC56_CONSOLE_FLAG_NOWAIT
    37                                  ora HBC56_CONSOLE_FLAGS
    38                                  sta HBC56_CONSOLE_FLAGS
    39                          }
    40                          
    41                          
    42                          !macro hbc56SetVsyncCallback .vsync {
    43                                  lda #<.vsync
    44                                  sta HBC56_VSYNC_CALLBACK
    45                                  lda #>.vsync
    46                                  sta HBC56_VSYNC_CALLBACK + 1
    47                          }
    48                          
    49                          !macro hbc56SetViaCallback .cb {
    50                                  lda #<.cb
    51                                  sta HBC56_VIA_CALLBACK
    52                                  lda #>.cb
    53                                  sta HBC56_VIA_CALLBACK + 1
    54                          }
    55                          
    56                          
    57                          !macro setHbcMetaTitle .titleStr {
    58                                  jmp .hbcMetaTitleOut
    59                          .titleStrLabel:
    60                                  !text .titleStr
    61                          .titleStrLabelLen = * - .titleStrLabel
    62                                  !byte 0 ; nul terminator for game name
    63                          
    64                          !if .titleStrLabelLen > HBC56_META_TITLE_MAX_LEN {
    65                                  !error "setHbcMetaTitle: Title metadata limited to ",HBC56_META_TITLE_MAX_LEN,"bytes"
    66                          }
    67                          .hbcMetaTitleOut:
    68                                  +memcpy HBC56_META_TITLE + (HBC56_META_TITLE_MAX_LEN-.titleStrLabelLen)/2, .titleStrLabel, .titleStrLabelLen
    69                                  lda #.titleStrLabelLen
    70                                  sta HBC56_META_TITLE_LEN
    71                          }
    72                          
    73                          !macro consoleEnableCursor {
    74                                  lda HBC56_CONSOLE_FLAGS
    75                                  ora #HBC56_CONSOLE_FLAG_CURSOR
    76                                  sta HBC56_CONSOLE_FLAGS
    77                          }
    78                          
    79                          !macro consoleDisableCursor {
    80                                  lda HBC56_CONSOLE_FLAGS
    81                                  and #!HBC56_CONSOLE_FLAG_CURSOR & $ff
    82                                  sta HBC56_CONSOLE_FLAGS
    83                          }
    84                          
    85                          !macro consoleLCDMode {
    86                                  lda HBC56_CONSOLE_FLAGS
    87                                  ora #HBC56_CONSOLE_FLAG_LCD
    88                                  sta HBC56_CONSOLE_FLAGS
    89                          }
    90                          
    91                          !macro setBreakpoint {
    92                                 !byte $db 
    93                          }
    94                          
    95                          !macro hbc56CustomDelay .delay {
    96                                  ldy #.delay
    97                                  jsr hbc56CustomDelay
    98                          }
    99                          
   100                          !macro hbc56DelayUs .us {
   101                          !if .us = 1 {
   102                                  nop
   103                                  nop
   104                          }
   105                          }
   106                          !macro hbc56DelayMs .ms {
   107                                  lda #<.ms
   108                                  sta DELAY_L
   109                                  lda #>.ms
   110                                  sta DELAY_H
   111                          
   112                                  jsr hbc56CustomDelayMs

; ******** Source: ../kernel\hbc56kernel.inc
    26                          
    27                          
    28                          !ifndef HBC_56_EXCLUDE_KERNEL_ROM {
    29                          
    30                                  ; if the program requires the kernal image
    31                                  ; then... include it
    32                          
    33                                  *=HBC56_META_VECTOR
    34                                  !ifdef hbc56Meta {
    35  dffc 4c0eb9                             jmp hbc56Meta
    36                                  } else {
    37                                          rts
    38                                  }
    39                          
    40                                  *=HBC56_KERNEL_START
    41  e000 c9619005c97b9002...        !bin "kernel.o"
    42                          
    43                                  *=DEFAULT_HBC56_RST_VECTOR
    44  8000 4c8eb8                     jmp hbc56Main
    45                          
    46                          } else {
    47                          
    48                                  ; otherwise, place the program in RAM
    49                          
    50                                  *=$0400

; ******** Source: basic_hbc56_core.asm
    11                          

; ******** Source: ehbasic\basic.asm
     1                          
     2                          ; Enhanced BASIC to assemble under 6502 simulator, $ver 2.22
     3                          
     4                          ; $E7E1 $E7CF $E7C6 $E7D3 $E7D1 $E7D5 $E7CF $E81E $E825
     5                          
     6                          ; 2.00	new revision numbers start here
     7                          ; 2.01	fixed LCASE$() and UCASE$()
     8                          ; 2.02	new get value routine done
     9                          ; 2.03	changed RND() to galoise method
    10                          ; 2.04	fixed SPC()
    11                          ; 2.05	new get value routine fixed
    12                          ; 2.06	changed USR() code
    13                          ; 2.07	fixed STR$()
    14                          ; 2.08	changed INPUT and READ to remove need for $00 start to input buffer
    15                          ; 2.09	fixed RND()
    16                          ; 2.10	integrated missed changes from an earlier version
    17                          ; 2.20	added ELSE to IF .. THEN and fixed IF .. GOTO <statement> to cause error
    18                          ; 2.21	fixed IF .. THEN RETURN to not cause error
    19                          ; 2.22	fixed RND() breaking the get byte routine
    20                          
    21                          ; zero page use ..
    22                          
    23                          LAB_WARM 		= $00		; BASIC warm start entry point
    24                          Wrmjpl 		= LAB_WARM+1; BASIC warm start vector jump low byte
    25                          Wrmjph 		= LAB_WARM+2; BASIC warm start vector jump high byte
    26                          
    27                          Usrjmp		= $0A		; USR function JMP address
    28                          Usrjpl		= Usrjmp+1	; USR function JMP vector low byte
    29                          Usrjph		= Usrjmp+2	; USR function JMP vector high byte
    30                          Nullct		= $0D		; nulls output after each line
    31                          TPos			= $0E		; BASIC terminal position byte
    32                          TWidth		= $0F		; BASIC terminal width byte
    33                          Iclim			= $10		; input column limit
    34                          Itempl		= $11		; temporary integer low byte
    35                          Itemph		= Itempl+1	; temporary integer high byte
    36                          
    37                          nums_1		= Itempl	; number to bin/hex string convert MSB
    38                          nums_2		= nums_1+1	; number to bin/hex string convert
    39                          nums_3		= nums_1+2	; number to bin/hex string convert LSB
    40                          
    41                          Srchc			= $5B		; search character
    42                          Temp3			= Srchc	; temp byte used in number routines
    43                          Scnquo		= $5C		; scan-between-quotes flag
    44                          Asrch			= Scnquo	; alt search character
    45                          
    46                          XOAw_l		= Srchc	; eXclusive OR, OR and AND word low byte
    47                          XOAw_h		= Scnquo	; eXclusive OR, OR and AND word high byte
    48                          
    49                          Ibptr			= $5D		; input buffer pointer
    50                          Dimcnt		= Ibptr	; # of dimensions
    51                          Tindx			= Ibptr	; token index
    52                          
    53                          Defdim		= $5E		; default DIM flag
    54                          Dtypef		= $5F		; data type flag, $FF=string, $00=numeric
    55                          Oquote		= $60		; open quote flag (b7) (Flag: DATA scan; LIST quote; memory)
    56                          Gclctd		= $60		; garbage collected flag
    57                          Sufnxf		= $61		; subscript/FNX flag, 1xxx xxx = FN(0xxx xxx)
    58                          Imode			= $62		; input mode flag, $00=INPUT, $80=READ
    59                          
    60                          Cflag			= $63		; comparison evaluation flag
    61                          
    62                          TabSiz		= $64		; TAB step size (was input flag)
    63                          
    64                          next_s		= $65		; next descriptor stack address
    65                          
    66                          					; these two bytes form a word pointer to the item
    67                          					; currently on top of the descriptor stack
    68                          last_sl		= $66		; last descriptor stack address low byte
    69                          last_sh		= $67		; last descriptor stack address high byte (always $00)
    70                          
    71                          des_sk		= $68		; descriptor stack start address (temp strings)
    72                          
    73                          ;			= $70		; End of descriptor stack
    74                          
    75                          ut1_pl		= $71		; utility pointer 1 low byte
    76                          ut1_ph		= ut1_pl+1	; utility pointer 1 high byte
    77                          ut2_pl		= $73		; utility pointer 2 low byte
    78                          ut2_ph		= ut2_pl+1	; utility pointer 2 high byte
    79                          
    80                          Temp_2		= ut1_pl	; temp byte for block move	
    81                          
    82                          FACt_1		= $75		; FAC temp mantissa1
    83                          FACt_2		= FACt_1+1	; FAC temp mantissa2
    84                          FACt_3		= FACt_2+1	; FAC temp mantissa3
    85                          
    86                          dims_l		= FACt_2	; array dimension size low byte
    87                          dims_h		= FACt_3	; array dimension size high byte
    88                          
    89                          TempB			= $78		; temp page 0 byte
    90                          
    91                          Smeml			= $79		; start of mem low byte		(Start-of-Basic)
    92                          Smemh			= Smeml+1	; start of mem high byte	(Start-of-Basic)
    93                          Svarl			= $7B		; start of vars low byte	(Start-of-Variables)
    94                          Svarh			= Svarl+1	; start of vars high byte	(Start-of-Variables)
    95                          Sarryl		= $7D		; var mem end low byte		(Start-of-Arrays)
    96                          Sarryh		= Sarryl+1	; var mem end high byte		(Start-of-Arrays)
    97                          Earryl		= $7F		; array mem end low byte	(End-of-Arrays)
    98                          Earryh		= Earryl+1	; array mem end high byte	(End-of-Arrays)
    99                          Sstorl		= $81		; string storage low byte	(String storage (moving down))
   100                          Sstorh		= Sstorl+1	; string storage high byte	(String storage (moving down))
   101                          Sutill		= $83		; string utility ptr low byte
   102                          Sutilh		= Sutill+1	; string utility ptr high byte
   103                          Ememl			= $85		; end of mem low byte		(Limit-of-memory)
   104                          Ememh			= Ememl+1	; end of mem high byte		(Limit-of-memory)
   105                          Clinel		= $87		; current line low byte		(Basic line number)
   106                          Clineh		= Clinel+1	; current line high byte	(Basic line number)
   107                          Blinel		= $89		; break line low byte		(Previous Basic line number)
   108                          Blineh		= Blinel+1	; break line high byte		(Previous Basic line number)
   109                          
   110                          Cpntrl		= $8B		; continue pointer low byte
   111                          Cpntrh		= Cpntrl+1	; continue pointer high byte
   112                          
   113                          Dlinel		= $8D		; current DATA line low byte
   114                          Dlineh		= Dlinel+1	; current DATA line high byte
   115                          
   116                          Dptrl			= $8F		; DATA pointer low byte
   117                          Dptrh			= Dptrl+1	; DATA pointer high byte
   118                          
   119                          Rdptrl		= $91		; read pointer low byte
   120                          Rdptrh		= Rdptrl+1	; read pointer high byte
   121                          
   122                          Varnm1		= $93		; current var name 1st byte
   123                          Varnm2		= Varnm1+1	; current var name 2nd byte
   124                          
   125                          Cvaral		= $95		; current var address low byte
   126                          Cvarah		= Cvaral+1	; current var address high byte
   127                          
   128                          Frnxtl		= $97		; var pointer for FOR/NEXT low byte
   129                          Frnxth		= Frnxtl+1	; var pointer for FOR/NEXT high byte
   130                          
   131                          Tidx1			= Frnxtl	; temp line index
   132                          
   133                          Lvarpl		= Frnxtl	; let var pointer low byte
   134                          Lvarph		= Frnxth	; let var pointer high byte
   135                          
   136                          prstk			= $99		; precedence stacked flag
   137                          
   138                          comp_f		= $9B		; compare function flag, bits 0,1 and 2 used
   139                          					; bit 2 set if >
   140                          					; bit 1 set if =
   141                          					; bit 0 set if <
   142                          
   143                          func_l		= $9C		; function pointer low byte
   144                          func_h		= func_l+1	; function pointer high byte
   145                          
   146                          garb_l		= func_l	; garbage collection working pointer low byte
   147                          garb_h		= func_h	; garbage collection working pointer high byte
   148                          
   149                          des_2l		= $9E		; string descriptor_2 pointer low byte
   150                          des_2h		= des_2l+1	; string descriptor_2 pointer high byte
   151                          
   152                          g_step		= $A0		; garbage collect step size
   153                          
   154                          Fnxjmp		= $A1		; jump vector for functions
   155                          Fnxjpl		= Fnxjmp+1	; functions jump vector low byte
   156                          Fnxjph		= Fnxjmp+2	; functions jump vector high byte
   157                          
   158                          g_indx		= Fnxjpl	; garbage collect temp index
   159                          
   160                          FAC2_r		= $A3		; FAC2 rounding byte
   161                          
   162                          Adatal		= $A4		; array data pointer low byte
   163                          Adatah		= Adatal+1	; array data pointer high  byte
   164                          
   165                          Nbendl		= Adatal	; new block end pointer low byte
   166                          Nbendh		= Adatah	; new block end pointer high  byte
   167                          
   168                          Obendl		= $A6		; old block end pointer low byte
   169                          Obendh		= Obendl+1	; old block end pointer high  byte
   170                          
   171                          numexp		= $A8		; string to float number exponent count
   172                          expcnt		= $A9		; string to float exponent count
   173                          
   174                          numbit		= numexp	; bit count for array element calculations
   175                          
   176                          numdpf		= $AA		; string to float decimal point flag
   177                          expneg		= $AB		; string to float eval exponent -ve flag
   178                          
   179                          Astrtl		= numdpf	; array start pointer low byte
   180                          Astrth		= expneg	; array start pointer high  byte
   181                          
   182                          Histrl		= numdpf	; highest string low byte
   183                          Histrh		= expneg	; highest string high  byte
   184                          
   185                          Baslnl		= numdpf	; BASIC search line pointer low byte
   186                          Baslnh		= expneg	; BASIC search line pointer high  byte
   187                          
   188                          Fvar_l		= numdpf	; find/found variable pointer low byte
   189                          Fvar_h		= expneg	; find/found variable pointer high  byte
   190                          
   191                          Ostrtl		= numdpf	; old block start pointer low byte
   192                          Ostrth		= expneg	; old block start pointer high  byte
   193                          
   194                          Vrschl		= numdpf	; variable search pointer low byte
   195                          Vrschh		= expneg	; variable search pointer high  byte
   196                          
   197                          FAC1_e		= $AC		; FAC1 exponent
   198                          FAC1_1		= FAC1_e+1	; FAC1 mantissa1
   199                          FAC1_2		= FAC1_e+2	; FAC1 mantissa2
   200                          FAC1_3		= FAC1_e+3	; FAC1 mantissa3
   201                          FAC1_s		= FAC1_e+4	; FAC1 sign (b7)
   202                          
   203                          str_ln		= FAC1_e	; string length
   204                          str_pl		= FAC1_1	; string pointer low byte
   205                          str_ph		= FAC1_2	; string pointer high byte
   206                          
   207                          des_pl		= FAC1_2	; string descriptor pointer low byte
   208                          des_ph		= FAC1_3	; string descriptor pointer high byte
   209                          
   210                          mids_l		= FAC1_3	; MID$ string temp length byte
   211                          
   212                          negnum		= $B1		; string to float eval -ve flag
   213                          numcon		= $B1		; series evaluation constant count
   214                          
   215                          FAC1_o		= $B2		; FAC1 overflow byte
   216                          
   217                          FAC2_e		= $B3		; FAC2 exponent
   218                          FAC2_1		= FAC2_e+1	; FAC2 mantissa1
   219                          FAC2_2		= FAC2_e+2	; FAC2 mantissa2
   220                          FAC2_3		= FAC2_e+3	; FAC2 mantissa3
   221                          FAC2_s		= FAC2_e+4	; FAC2 sign (b7)
   222                          
   223                          FAC_sc		= $B8		; FAC sign comparison, Acc#1 vs #2
   224                          FAC1_r		= $B9		; FAC1 rounding byte
   225                          
   226                          ssptr_l		= FAC_sc	; string start pointer low byte
   227                          ssptr_h		= FAC1_r	; string start pointer high byte
   228                          
   229                          sdescr		= FAC_sc	; string descriptor pointer
   230                          
   231                          csidx			= $BA		; line crunch save index
   232                          Asptl			= csidx	; array size/pointer low byte
   233                          Aspth			= $BB		; array size/pointer high byte
   234                          
   235                          Btmpl			= Asptl	; BASIC pointer temp low byte
   236                          Btmph			= Aspth	; BASIC pointer temp low byte
   237                          
   238                          Cptrl			= Asptl	; BASIC pointer temp low byte
   239                          Cptrh			= Aspth	; BASIC pointer temp low byte
   240                          
   241                          Sendl			= Asptl	; BASIC pointer temp low byte
   242                          Sendh			= Aspth	; BASIC pointer temp low byte
   243                          
   244                          LAB_IGBY		= $BC		; get next BASIC byte subroutine
   245                          
   246                          LAB_GBYT		= $C2		; get current BASIC byte subroutine
   247                          Bpntrl		= $C3		; BASIC execute (get byte) pointer low byte
   248                          Bpntrh		= Bpntrl+1	; BASIC execute (get byte) pointer high byte
   249                          
   250                          ;			= $D7		; end of get BASIC char subroutine
   251                          
   252                          Rbyte4		= $D8		; extra PRNG byte
   253                          Rbyte1		= Rbyte4+1	; most significant PRNG byte
   254                          Rbyte2		= Rbyte4+2	; middle PRNG byte
   255                          Rbyte3		= Rbyte4+3	; least significant PRNG byte
   256                          
   257                          NmiBase		= $DC		; NMI handler enabled/setup/triggered flags
   258                          					; bit	function
   259                          					; ===	========
   260                          					; 7	interrupt enabled
   261                          					; 6	interrupt setup
   262                          					; 5	interrupt happened
   263                          ;			= $DD		; NMI handler addr low byte
   264                          ;			= $DE		; NMI handler addr high byte
   265                          IrqBase		= $DF		; IRQ handler enabled/setup/triggered flags
   266                          ;			= $E0		; IRQ handler addr low byte
   267                          ;			= $E1		; IRQ handler addr high byte
   268                          
   269                          ;			= $DE		; unused
   270                          ;			= $DF		; unused
   271                          ;			= $E0		; unused
   272                          ;			= $E1		; unused
   273                          ;			= $E2		; unused
   274                          ;			= $E3		; unused
   275                          ;			= $E4		; unused
   276                          ;			= $E5		; unused
   277                          ;			= $E6		; unused
   278                          ;			= $E7		; unused
   279                          ;			= $E8		; unused
   280                          ;			= $E9		; unused
   281                          ;			= $EA		; unused
   282                          ;			= $EB		; unused
   283                          ;			= $EC		; unused
   284                          ;			= $ED		; unused
   285                          ;			= $EE		; unused
   286                          
   287                          Decss			= $E2		; number to decimal string start
   288                          Decssp1		= Decss+1	; number to decimal string start
   289                          
   290                          ;			= $FF		; decimal string end
   291                          
   292                          ; token values needed for BASIC
   293                          
   294                          ; primary command tokens (can start a statement)
   295                          
   296                          TK_END		= $80			; END token
   297                          TK_FOR		= TK_END+1		; FOR token
   298                          TK_NEXT		= TK_FOR+1		; NEXT token
   299                          TK_DATA		= TK_NEXT+1		; DATA token
   300                          TK_INPUT		= TK_DATA+1		; INPUT token
   301                          TK_DIM		= TK_INPUT+1	; DIM token
   302                          TK_READ		= TK_DIM+1		; READ token
   303                          TK_LET		= TK_READ+1		; LET token
   304                          TK_DEC		= TK_LET+1		; DEC token
   305                          TK_GOTO		= TK_DEC+1		; GOTO token
   306                          TK_RUN		= TK_GOTO+1		; RUN token
   307                          TK_IF			= TK_RUN+1		; IF token
   308                          TK_RESTORE		= TK_IF+1		; RESTORE token
   309                          TK_GOSUB		= TK_RESTORE+1	; GOSUB token
   310                          TK_RETIRQ		= TK_GOSUB+1	; RETIRQ token
   311                          TK_RETNMI		= TK_RETIRQ+1	; RETNMI token
   312                          TK_RETURN		= TK_RETNMI+1	; RETURN token
   313                          TK_REM		= TK_RETURN+1	; REM token
   314                          TK_STOP		= TK_REM+1		; STOP token
   315                          TK_ON			= TK_STOP+1		; ON token
   316                          TK_NULL		= TK_ON+1		; NULL token
   317                          TK_INC		= TK_NULL+1		; INC token
   318                          TK_WAIT		= TK_INC+1		; WAIT token
   319                          TK_LOAD		= TK_WAIT+1		; LOAD token
   320                          TK_SAVE		= TK_LOAD+1		; SAVE token
   321                          TK_DEF		= TK_SAVE+1		; DEF token
   322                          TK_POKE		= TK_DEF+1		; POKE token
   323                          TK_DOKE		= TK_POKE+1		; DOKE token
   324                          TK_DISPLAY	= TK_DOKE+1		; DISPLAY token
   325                          TK_PLOT		= TK_DISPLAY+1		; PLOT token
   326                          TK_UNPLOT	= TK_PLOT+1		; UNPLOT token
   327                          TK_CALL		= TK_UNPLOT+1		; CALL token
   328                          TK_DO			= TK_CALL+1		; DO token
   329                          TK_LOOP		= TK_DO+1		; LOOP token
   330                          TK_PRINT		= TK_LOOP+1		; PRINT token
   331                          TK_CONT		= TK_PRINT+1	; CONT token
   332                          TK_LIST		= TK_CONT+1		; LIST token
   333                          TK_CLEAR		= TK_LIST+1		; CLEAR token
   334                          TK_NEW		= TK_CLEAR+1	; NEW token
   335                          TK_WIDTH		= TK_NEW+1		; WIDTH token
   336                          TK_GET		= TK_WIDTH+1	; GET token
   337                          TK_SWAP		= TK_GET+1		; SWAP token
   338                          TK_BITSET		= TK_SWAP+1		; BITSET token
   339                          TK_BITCLR		= TK_BITSET+1	; BITCLR token
   340                          TK_CLS                  = TK_BITCLR+1
   341                          TK_COLOR		= TK_CLS+1
   342                          TK_IRQ		= TK_COLOR+1	; IRQ token
   343                          TK_NMI		= TK_IRQ+1		; NMI token
   344                          
   345                          ; secondary command tokens, can't start a statement
   346                          
   347                          TK_TAB		= TK_NMI+1		; TAB token
   348                          TK_ELSE		= TK_TAB+1		; ELSE token
   349                          TK_TO			= TK_ELSE+1		; TO token
   350                          TK_FN			= TK_TO+1		; FN token
   351                          TK_SPC		= TK_FN+1		; SPC token
   352                          TK_THEN		= TK_SPC+1		; THEN token
   353                          TK_NOT		= TK_THEN+1		; NOT token
   354                          TK_STEP		= TK_NOT+1		; STEP token
   355                          TK_UNTIL		= TK_STEP+1		; UNTIL token
   356                          TK_WHILE		= TK_UNTIL+1	; WHILE token
   357                          TK_OFF		= TK_WHILE+1	; OFF token
   358                          
   359                          ; opperator tokens
   360                          
   361                          TK_PLUS		= TK_OFF+1		; + token
   362                          TK_MINUS		= TK_PLUS+1		; - token
   363                          TK_MUL		= TK_MINUS+1	; * token
   364                          TK_DIV		= TK_MUL+1		; / token
   365                          TK_POWER		= TK_DIV+1		; ^ token
   366                          TK_AND		= TK_POWER+1	; AND token
   367                          TK_EOR		= TK_AND+1		; EOR token
   368                          TK_OR			= TK_EOR+1		; OR token
   369                          TK_RSHIFT		= TK_OR+1		; RSHIFT token
   370                          TK_LSHIFT		= TK_RSHIFT+1	; LSHIFT token
   371                          TK_GT			= TK_LSHIFT+1	; > token
   372                          TK_EQUAL		= TK_GT+1		; = token
   373                          TK_LT			= TK_EQUAL+1	; < token
   374                          
   375                          ; functions tokens
   376                          
   377                          TK_SGN		= TK_LT+1		; SGN token
   378                          TK_INT		= TK_SGN+1		; INT token
   379                          TK_ABS		= TK_INT+1		; ABS token
   380                          TK_USR		= TK_ABS+1		; USR token
   381                          TK_FRE		= TK_USR+1		; FRE token
   382                          TK_POS		= TK_FRE+1		; POS token
   383                          TK_SQR		= TK_POS+1		; SQR token
   384                          TK_RND		= TK_SQR+1		; RND token
   385                          TK_LOG		= TK_RND+1		; LOG token
   386                          TK_EXP		= TK_LOG+1		; EXP token
   387                          TK_COS		= TK_EXP+1		; COS token
   388                          TK_SIN		= TK_COS+1		; SIN token
   389                          TK_TAN		= TK_SIN+1		; TAN token
   390                          TK_ATN		= TK_TAN+1		; ATN token
   391                          TK_PEEK		= TK_ATN+1		; PEEK token
   392                          TK_DEEK		= TK_PEEK+1		; DEEK token
   393                          TK_SADD		= TK_DEEK+1		; SADD token
   394                          TK_LEN		= TK_SADD+1		; LEN token
   395                          TK_STRS		= TK_LEN+1		; STR$ token
   396                          TK_VAL		= TK_STRS+1		; VAL token
   397                          TK_ASC		= TK_VAL+1		; ASC token
   398                          TK_UCASES		= TK_ASC+1		; UCASE$ token
   399                          TK_LCASES		= TK_UCASES+1	; LCASE$ token
   400                          TK_CHRS		= TK_LCASES+1	; CHR$ token
   401                          TK_HEXS		= TK_CHRS+1		; HEX$ token
   402                          TK_BINS		= TK_HEXS+1		; BIN$ token
   403                          TK_BITTST		= TK_BINS+1		; BITTST token
   404                          TK_MAX		= TK_BITTST+1	; MAX token
   405                          TK_MIN		= TK_MAX+1		; MIN token
   406                          TK_PI			= TK_MIN+1		; PI token
   407                          TK_TWOPI		= TK_PI+1		; TWOPI token
   408                          TK_VPTR		= TK_TWOPI+1	; VARPTR token
   409                          TK_LEFTS		= TK_VPTR+1		; LEFT$ token
   410                          TK_RIGHTS		= TK_LEFTS+1	; RIGHT$ token
   411                          TK_MIDS		= TK_RIGHTS+1	; MID$ token
   412                          
   413                          ; offsets from a base of X or Y
   414                          
   415                          PLUS_0		= $00		; X or Y plus 0
   416                          PLUS_1		= $01		; X or Y plus 1
   417                          PLUS_2		= $02		; X or Y plus 2
   418                          PLUS_3		= $03		; X or Y plus 3
   419                          
   420                          LAB_STAK		= $0100	; stack bottom, no offset
   421                          
   422                          LAB_SKFE		= LAB_STAK+$FE
   423                          					; flushed stack address
   424                          LAB_SKFF		= LAB_STAK+$FF
   425                          					; flushed stack address
   426                          
   427                          ccflag		= $0300	; BASIC CTRL-C flag, 00 = enabled, 01 = dis
   428                          ccbyte		= ccflag+1	; BASIC CTRL-C byte
   429                          ccnull		= ccbyte+1	; BASIC CTRL-C byte timeout
   430                          
   431                          VEC_CC		= ccnull+1	; ctrl c check vector
   432                          
   433                          VEC_IN		= VEC_CC+2	; input vector
   434                          VEC_OUT		= VEC_IN+2	; output vector
   435                          VEC_LD		= VEC_OUT+2	; load vector
   436                          VEC_SV		= VEC_LD+2	; save vector
   437                          
   438                          ; Ibuffs can now be anywhere in RAM, ensure that the max length is < $80
   439                          
   440                          Ibuffs		= IRQ_vec+$14
   441                          					; start of input buffer after IRQ/NMI code
   442                          Ibuffe		= Ibuffs+$47; end of input buffer
   443                          
   444                          Ram_base	= $0400	; start of user RAM (set as needed, should be page aligned)
   445                          Ram_top		= $7000	; end of user RAM+1 (set as needed, should be page aligned)
   446                          
   447                          ; This start can be changed to suit your system
   448                          
   449                          *=$9000
   450                          
   451                          ; For convenience, put jump here to reset location so it can be
   452                          ; run from the load address.
   453                          
   454  9000 4c8eb8             JMP	RES_vec
   455                          
   456                          ; BASIC cold start entry point
   457                          
   458                          ; new page 2 initialisation, copy block to ccflag on
   459                          
   460                          LAB_COLD
   461  9003 a004               	LDY	#PG2_TABE-PG2_TABS-1
   462                          					; byte count-1
   463                          LAB_2D13
   464  9005 b915b1             	LDA	PG2_TABS,Y		; get byte
   465  9008 990003             	STA	ccflag,Y		; store in page 2
   466  900b 88                 	DEY				; decrement count
   467  900c 10f7               	BPL	LAB_2D13		; loop if not done
   468                          
   469  900e a2ff               	LDX	#$FF			; set byte
   470  9010 8688               	STX	Clineh		; set current line high byte (set immediate mode)
   471  9012 9a                 	TXS				; reset stack pointer
   472                          
   473  9013 a94c               	LDA	#$4C			; code for JMP
   474  9015 85a1               	STA	Fnxjmp		; save for jump vector for functions
   475                          
   476                          ; copy block from LAB_2CEE to $00BC - $00D3
   477                          
   478  9017 a21c               	LDX	#StrTab-LAB_2CEE	; set byte count
   479                          LAB_2D4E
   480  9019 bd19b1             	LDA	LAB_2CEE-1,X	; get byte from table
   481  901c 95bb               	STA	LAB_IGBY-1,X	; save byte in page zero
   482  901e ca                 	DEX				; decrement count
   483  901f d0f8               	BNE	LAB_2D4E		; loop if not all done
   484                          
   485                          ; copy block from StrTab to $0000 - $0012
   486                          
   487                          LAB_GMEM
   488  9021 a212               	LDX	#EndTab-StrTab-1	; set byte count-1
   489                          TabLoop
   490  9023 bd36b1             	LDA	StrTab,X		; get byte from table
   491  9026 9500               	STA	PLUS_0,X		; save byte in page zero
   492  9028 ca                 	DEX				; decrement count
   493  9029 10f8               	BPL	TabLoop		; loop if not all done
   494                          
   495                          ; set-up start values
   496                          
   497  902b a900               	LDA	#$00			; clear A
   498  902d 85dc               	STA	NmiBase		; clear NMI handler enabled flag
   499  902f 85df               	STA	IrqBase		; clear IRQ handler enabled flag
   500  9031 85b2               	STA	FAC1_o		; clear FAC1 overflow byte
   501  9033 8567               	STA	last_sh		; clear descriptor stack top item pointer high byte
   502                          
   503  9035 a90e               	LDA	#$0E			; set default tab size
   504  9037 8564               	STA	TabSiz		; save it
   505  9039 a903               	LDA	#$03			; set garbage collect step size for descriptor stack
   506  903b 85a0               	STA	g_step		; save it
   507  903d a268               	LDX	#des_sk		; descriptor stack start
   508  903f 8665               	STX	next_s		; set descriptor stack pointer
   509                          
   510  9041 a900               	lda #$00
   511  9043 8511               	sta Itempl
   512  9045 a968               	lda #$68
   513  9047 8512               	sta Itemph	; 16KB
   514                          
   515  9049 4c6490                     JMP LAB_2D93    ; Skip memory question
   516                          
   517  904c 20ae98             	JSR	LAB_CRLF		; print CR/LF
   518  904f a949               	LDA	#<LAB_MSZM		; point to memory size message (low addr)
   519  9051 a0b1               	LDY	#>LAB_MSZM		; point to memory size message (high addr)
   520  9053 20ea98             	JSR	LAB_18C3		; print null terminated string from memory
   521  9056 204b92             	JSR	LAB_INLN		; print "? " and get BASIC input
   522  9059 86c3               	STX	Bpntrl		; set BASIC execute pointer low byte
   523  905b 84c4               	STY	Bpntrh		; set BASIC execute pointer high byte
   524  905d 20c200             	JSR	LAB_GBYT		; get last byte back
   525                          
   526  9060 d01f               	BNE	LAB_2DAA		; branch if not null (user typed something)
   527                          
   528  9062 a000               	LDY	#$00			; else clear Y
   529                          					; character was null so get memory size the hard way
   530                          					; we get here with Y=0 and Itempl/h = Ram_base
   531                          LAB_2D93
   532  9064 e611               	INC	Itempl		; increment temporary integer low byte
   533  9066 d008               	BNE	LAB_2D99		; branch if no overflow
   534                          
   535  9068 e612               	INC	Itemph		; increment temporary integer high byte
   536  906a a512               	LDA	Itemph		; get high byte
   537  906c c970               	CMP	#>Ram_top		; compare with top of RAM+1
   538  906e f01d               	BEQ	LAB_2DB6		; branch if match (end of user RAM)
   539                          
   540                          LAB_2D99
   541  9070 a955               	LDA	#$55			; set test byte
   542  9072 9111               	STA	(Itempl),Y		; save via temporary integer
   543  9074 d111               	CMP	(Itempl),Y		; compare via temporary integer
   544  9076 d015               	BNE	LAB_2DB6		; branch if fail
   545                          
   546  9078 0a                 	ASL				; shift test byte left (now $AA)
   547  9079 9111               	STA	(Itempl),Y		; save via temporary integer
   548  907b d111               	CMP	(Itempl),Y		; compare via temporary integer
   549  907d f0e5               	BEQ	LAB_2D93		; if ok go do next byte
   550                          
   551  907f d00c               	BNE	LAB_2DB6		; branch if fail
   552                          
   553                          LAB_2DAA
   554  9081 20bda9             	JSR	LAB_2887		; get FAC1 from string
   555  9084 a5ac               	LDA	FAC1_e		; get FAC1 exponent
   556  9086 c998               	CMP	#$98			; compare with exponent = 2^24
   557  9088 b097               	BCS	LAB_GMEM		; if too large go try again
   558                          
   559  908a 200ea5             	JSR	LAB_F2FU		; save integer part of FAC1 in temporary integer
   560                          					; (no range check)
   561                          
   562                          LAB_2DB6
   563  908d a511               	LDA	Itempl		; get temporary integer low byte
   564  908f a412               	LDY	Itemph		; get temporary integer high byte
   565  9091 c001               	CPY	#<Ram_base+1	; compare with start of RAM+$100 high byte
   566  9093 908c               	BCC	LAB_GMEM		; if too small go try again
   567                          
   568                          
   569                          ; uncomment these lines if you want to check on the high limit of memory. Note if
   570                          ; Ram_top is set too low then this will fail. default is ignore it and assume the
   571                          ; users know what they're doing!
   572                          
   573                          ;	CPY	#>Ram_top		; compare with top of RAM high byte
   574                          ;	BCC	MEM_OK		; branch if < RAM top
   575                          
   576                          ;	BNE	LAB_GMEM		; if too large go try again
   577                          					; else was = so compare low bytes
   578                          ;	CMP	#<Ram_top		; compare with top of RAM low byte
   579                          ;	BEQ	MEM_OK		; branch if = RAM top
   580                          
   581                          ;	BCS	LAB_GMEM		; if too large go try again
   582                          
   583                          ;MEM_OK
   584  9095 8585               	STA	Ememl			; set end of mem low byte
   585  9097 8486               	STY	Ememh			; set end of mem high byte
   586  9099 8581               	STA	Sstorl		; set bottom of string space low byte
   587  909b 8482               	STY	Sstorh		; set bottom of string space high byte
   588                          
   589  909d a000               	LDY	#<Ram_base		; set start addr low byte
   590  909f a204               	LDX	#>Ram_base		; set start addr high byte
   591  90a1 8479               	STY	Smeml			; save start of mem low byte
   592  90a3 867a               	STX	Smemh			; save start of mem high byte
   593                          
   594                          ; this line is only needed if Ram_base is not $xx00
   595                          
   596                          ;	LDY	#$00			; clear Y
   597  90a5 98                 	TYA				; clear A
   598  90a6 9179               	STA	(Smeml),Y		; clear first byte
   599  90a8 e679               	INC	Smeml			; increment start of mem low byte
   600                          
   601                          ; these two lines are only needed if Ram_base is $xxFF
   602                          
   603                          ;	BNE	LAB_2E05		; branch if no rollover
   604                          
   605                          ;	INC	Smemh			; increment start of mem high byte
   606                          LAB_2E05
   607                          	;JSR	LAB_CRLF		; print CR/LF
   608  90aa 206793             	JSR	LAB_1463		; do "NEW" and "CLEAR"
   609  90ad a585               	LDA	Ememl			; get end of mem low byte
   610  90af 38                 	SEC				; set carry for subtract
   611  90b0 e579               	SBC	Smeml			; subtract start of mem low byte
   612  90b2 aa                 	TAX				; copy to X
   613  90b3 a586               	LDA	Ememh			; get end of mem high byte
   614  90b5 e57a               	SBC	Smemh			; subtract start of mem high byte
   615                          
   616                          ; TS: Don't print free RAM
   617                          ;	JSR	LAB_295E		; print XA as unsigned integer (bytes free)
   618                          
   619  90b7 20ae98             	JSR	LAB_CRLF		; print CR/LF
   620  90ba a958               	LDA	#<LAB_SMSG		; point to sign-on message (low addr)
   621  90bc a0b1               	LDY	#>LAB_SMSG		; point to sign-on message (high addr)
   622  90be 20ea98             	JSR	LAB_18C3		; print null terminated string from memory
   623  90c1 a965               	LDA	#<LAB_1274		; warm start vector low byte
   624  90c3 a091               	LDY	#>LAB_1274		; warm start vector high byte
   625  90c5 8501               	STA	Wrmjpl		; save warm start vector low byte
   626  90c7 8402               	STY	Wrmjph		; save warm start vector high byte
   627  90c9 6c0100             	JMP	(Wrmjpl)		; go do warm start
   628                          
   629                          ; open up space in memory
   630                          ; move (Ostrtl)-(Obendl) to new block ending at (Nbendl)
   631                          
   632                          ; Nbendl,Nbendh - new block end address (A/Y)
   633                          ; Obendl,Obendh - old block end address
   634                          ; Ostrtl,Ostrth - old block start address
   635                          
   636                          ; returns with ..
   637                          
   638                          ; Nbendl,Nbendh - new block start address (high byte - $100)
   639                          ; Obendl,Obendh - old block start address (high byte - $100)
   640                          ; Ostrtl,Ostrth - old block start address (unchanged)
   641                          
   642                          LAB_11CF
   643  90cc 201691             	JSR	LAB_121F		; check available memory, "Out of memory" error if no room
   644                          					; addr to check is in AY (low/high)
   645  90cf 857f               	STA	Earryl		; save new array mem end low byte
   646  90d1 8480               	STY	Earryh		; save new array mem end high byte
   647                          
   648                          ; open up space in memory
   649                          ; move (Ostrtl)-(Obendl) to new block ending at (Nbendl)
   650                          ; don't set array end
   651                          
   652                          LAB_11D6
   653  90d3 38                 	SEC				; set carry for subtract
   654  90d4 a5a6               	LDA	Obendl		; get block end low byte
   655  90d6 e5aa               	SBC	Ostrtl		; subtract block start low byte
   656  90d8 a8                 	TAY				; copy MOD(block length/$100) byte to Y
   657  90d9 a5a7               	LDA	Obendh		; get block end high byte
   658  90db e5ab               	SBC	Ostrth		; subtract block start high byte
   659  90dd aa                 	TAX				; copy block length high byte to X
   660  90de e8                 	INX				; +1 to allow for count=0 exit
   661  90df 98                 	TYA				; copy block length low byte to A
   662  90e0 f024               	BEQ	LAB_120A		; branch if length low byte=0
   663                          
   664                          					; block is (X-1)*256+Y bytes, do the Y bytes first
   665                          
   666  90e2 38                 	SEC				; set carry for add + 1, two's complement
   667  90e3 49ff               	EOR	#$FF			; invert low byte for subtract
   668  90e5 65a6               	ADC	Obendl		; add block end low byte
   669                          
   670  90e7 85a6               	STA	Obendl		; save corrected old block end low byte
   671  90e9 b003               	BCS	LAB_11F3		; branch if no underflow
   672                          
   673  90eb c6a7               	DEC	Obendh		; else decrement block end high byte
   674  90ed 38                 	SEC				; set carry for add + 1, two's complement
   675                          LAB_11F3
   676  90ee 98                 	TYA				; get MOD(block length/$100) byte
   677  90ef 49ff               	EOR	#$FF			; invert low byte for subtract
   678  90f1 65a4               	ADC	Nbendl		; add destination end low byte
   679  90f3 85a4               	STA	Nbendl		; save modified new block end low byte
   680  90f5 b008               	BCS	LAB_1203		; branch if no underflow
   681                          
   682  90f7 c6a5               	DEC	Nbendh		; else decrement block end high byte
   683  90f9 9004               	BCC	LAB_1203		; branch always
   684                          
   685                          LAB_11FF
   686  90fb b1a6               	LDA	(Obendl),Y		; get byte from source
   687  90fd 91a4               	STA	(Nbendl),Y		; copy byte to destination
   688                          LAB_1203
   689  90ff 88                 	DEY				; decrement index
   690  9100 d0f9               	BNE	LAB_11FF		; loop until Y=0
   691                          
   692                          					; now do Y=0 indexed byte
   693  9102 b1a6               	LDA	(Obendl),Y		; get byte from source
   694  9104 91a4               	STA	(Nbendl),Y		; save byte to destination
   695                          LAB_120A
   696  9106 c6a7               	DEC	Obendh		; decrement source pointer high byte
   697  9108 c6a5               	DEC	Nbendh		; decrement destination pointer high byte
   698  910a ca                 	DEX				; decrement block count
   699  910b d0f2               	BNE	LAB_1203		; loop until count = $0
   700                          
   701  910d 60                 	RTS
   702                          
   703                          ; check room on stack for A bytes
   704                          ; stack too deep? do OM error
   705                          
   706                          LAB_1212
   707  910e 8578               	STA	TempB			; save result in temp byte
   708  9110 ba                 	TSX				; copy stack
   709  9111 e478               	CPX	TempB			; compare new "limit" with stack
   710  9113 9030               	BCC	LAB_OMER		; if stack < limit do "Out of memory" error then warm start
   711                          
   712  9115 60                 	RTS
   713                          
   714                          ; check available memory, "Out of memory" error if no room
   715                          ; addr to check is in AY (low/high)
   716                          
   717                          LAB_121F
   718  9116 c482               	CPY	Sstorh		; compare bottom of string mem high byte
   719  9118 902a               	BCC	LAB_124B		; if less then exit (is ok)
   720                          
   721  911a d004               	BNE	LAB_1229		; skip next test if greater (tested <)
   722                          
   723                          					; high byte was =, now do low byte
   724  911c c581               	CMP	Sstorl		; compare with bottom of string mem low byte
   725  911e 9024               	BCC	LAB_124B		; if less then exit (is ok)
   726                          
   727                          					; addr is > string storage ptr (oops!)
   728                          LAB_1229
   729  9120 48                 	PHA				; push addr low byte
   730  9121 a208               	LDX	#$08			; set index to save Adatal to expneg inclusive
   731  9123 98                 	TYA				; copy addr high byte (to push on stack)
   732                          
   733                          					; save misc numeric work area
   734                          LAB_122D
   735  9124 48                 	PHA				; push byte
   736  9125 b5a3               	LDA	Adatal-1,X		; get byte from Adatal to expneg ( ,$00 not pushed)
   737  9127 ca                 	DEX				; decrement index
   738  9128 10fa               	BPL	LAB_122D		; loop until all done
   739                          
   740  912a 20f6a1             	JSR	LAB_GARB		; garbage collection routine
   741                          
   742                          					; restore misc numeric work area
   743  912d a200               	LDX	#$00			; clear the index to restore bytes
   744                          LAB_1238
   745  912f 68                 	PLA				; pop byte
   746  9130 95a4               	STA	Adatal,X		; save byte to Adatal to expneg
   747  9132 e8                 	INX				; increment index
   748  9133 e008               	CPX	#$08			; compare with end + 1
   749  9135 30f8               	BMI	LAB_1238		; loop if more to do
   750                          
   751  9137 68                 	PLA				; pop addr high byte
   752  9138 a8                 	TAY				; copy back to Y
   753  9139 68                 	PLA				; pop addr low byte
   754  913a c482               	CPY	Sstorh		; compare bottom of string mem high byte
   755  913c 9006               	BCC	LAB_124B		; if less then exit (is ok)
   756                          
   757  913e d005               	BNE	LAB_OMER		; if greater do "Out of memory" error then warm start
   758                          
   759                          					; high byte was =, now do low byte
   760  9140 c581               	CMP	Sstorl		; compare with bottom of string mem low byte
   761  9142 b001               	BCS	LAB_OMER		; if >= do "Out of memory" error then warm start
   762                          
   763                          					; ok exit, carry clear
   764                          LAB_124B
   765  9144 60                 	RTS
   766                          
   767                          ; do "Out of memory" error then warm start
   768                          
   769                          LAB_OMER
   770  9145 a20c               	LDX	#$0C			; error code $0C ("Out of memory" error)
   771                          
   772                          ; do error #X, then warm start
   773                          
   774                          LAB_XERR
   775  9147 20ae98             	JSR	LAB_CRLF		; print CR/LF
   776                          
   777  914a bdffb6             	LDA	LAB_BAER,X		; get error message pointer low byte
   778  914d bc00b7             	LDY	LAB_BAER+1,X	; get error message pointer high byte
   779  9150 20ea98             	JSR	LAB_18C3		; print null terminated string from memory
   780                          
   781  9153 20a093             	JSR	LAB_1491		; flush stack and clear continue flag
   782  9156 a94d               	LDA	#<LAB_EMSG		; point to " Error" low addr
   783  9158 a0b8               	LDY	#>LAB_EMSG		; point to " Error" high addr
   784                          LAB_1269
   785  915a 20ea98             	JSR	LAB_18C3		; print null terminated string from memory
   786  915d a488               	LDY	Clineh		; get current line high byte
   787  915f c8                 	INY				; increment it
   788  9160 f003               	BEQ	LAB_1274		; go do warm start (was immediate mode)
   789                          
   790                          					; else print line number
   791  9162 208eaa             	JSR	LAB_2953		; print " in line [LINE #]"
   792                          
   793                          ; BASIC warm start entry point
   794                          ; wait for Basic command
   795                          
   796                          LAB_1274
   797                          				; clear ON IRQ/NMI bytes
   798  9165 a900               	LDA	#$00		; clear A
   799  9167 85df               	STA	IrqBase		; clear enabled byte
   800  9169 85dc               	STA	NmiBase		; clear enabled byte
   801  916b a95f               	LDA	#<LAB_RMSG		; point to "Ready" message low byte
   802  916d a0b8               	LDY	#>LAB_RMSG		; point to "Ready" message high byte
   803                          
   804  916f 20ea98             	JSR	LAB_18C3		; go do print string
   805                          
   806                          ; wait for Basic command (no "Ready")
   807                          
   808                          LAB_127D
   809  9172 205892             	JSR	LAB_1357		; call for BASIC input
   810                          LAB_1280
   811  9175 86c3               	STX	Bpntrl		; set BASIC execute pointer low byte
   812  9177 84c4               	STY	Bpntrh		; set BASIC execute pointer high byte
   813  9179 20c200             	JSR	LAB_GBYT		; scan memory
   814  917c f0f4               	BEQ	LAB_127D		; loop while null
   815                          
   816                          ; got to interpret input line now ..
   817                          
   818  917e a2ff               	LDX	#$FF			; current line to null value
   819  9180 8688               	STX	Clineh		; set current line high byte
   820  9182 9006               	BCC	LAB_1295		; branch if numeric character (handle new BASIC line)
   821                          
   822                          					; no line number .. immediate mode
   823  9184 208992             	JSR	LAB_13A6		; crunch keywords into Basic tokens
   824  9187 4c0a95             	JMP	LAB_15F6		; go scan and interpret code
   825                          
   826                          ; handle new BASIC line
   827                          
   828                          LAB_1295
   829  918a 207197             	JSR	LAB_GFPN		; get fixed-point number into temp integer
   830  918d 208992             	JSR	LAB_13A6		; crunch keywords into Basic tokens
   831  9190 845d               	STY	Ibptr			; save index pointer to end of crunched line
   832  9192 203b93             	JSR	LAB_SSLN		; search BASIC for temp integer line number
   833  9195 9044               	BCC	LAB_12E6		; branch if not found
   834                          
   835                          					; aroooogah! line # already exists! delete it
   836  9197 a001               	LDY	#$01			; set index to next line pointer high byte
   837  9199 b1aa               	LDA	(Baslnl),Y		; get next line pointer high byte
   838  919b 8572               	STA	ut1_ph		; save it
   839  919d a57b               	LDA	Svarl			; get start of vars low byte
   840  919f 8571               	STA	ut1_pl		; save it
   841  91a1 a5ab               	LDA	Baslnh		; get found line pointer high byte
   842  91a3 8574               	STA	ut2_ph		; save it
   843  91a5 a5aa               	LDA	Baslnl		; get found line pointer low byte
   844  91a7 88                 	DEY				; decrement index
   845  91a8 f1aa               	SBC	(Baslnl),Y		; subtract next line pointer low byte
   846  91aa 18                 	CLC				; clear carry for add
   847  91ab 657b               	ADC	Svarl			; add start of vars low byte
   848  91ad 857b               	STA	Svarl			; save new start of vars low byte
   849  91af 8573               	STA	ut2_pl		; save destination pointer low byte
   850  91b1 a57c               	LDA	Svarh			; get start of vars high byte
   851  91b3 69ff               	ADC	#$FF			; -1 + carry
   852  91b5 857c               	STA	Svarh			; save start of vars high byte
   853  91b7 e5ab               	SBC	Baslnh		; subtract found line pointer high byte
   854  91b9 aa                 	TAX				; copy to block count
   855  91ba 38                 	SEC				; set carry for subtract
   856  91bb a5aa               	LDA	Baslnl		; get found line pointer low byte
   857  91bd e57b               	SBC	Svarl			; subtract start of vars low byte
   858  91bf a8                 	TAY				; copy to bytes in first block count
   859  91c0 b003               	BCS	LAB_12D0		; branch if overflow
   860                          
   861  91c2 e8                 	INX				; increment block count (correct for =0 loop exit)
   862  91c3 c674               	DEC	ut2_ph		; decrement destination high byte
   863                          LAB_12D0
   864  91c5 18                 	CLC				; clear carry for add
   865  91c6 6571               	ADC	ut1_pl		; add source pointer low byte
   866  91c8 9003               	BCC	LAB_12D8		; branch if no overflow
   867                          
   868  91ca c672               	DEC	ut1_ph		; else decrement source pointer high byte
   869  91cc 18                 	CLC				; clear carry
   870                          
   871                          					; close up memory to delete old line
   872                          LAB_12D8
   873  91cd b171               	LDA	(ut1_pl),Y		; get byte from source
   874  91cf 9173               	STA	(ut2_pl),Y		; copy to destination
   875  91d1 c8                 	INY				; increment index
   876  91d2 d0f9               	BNE	LAB_12D8		; while <> 0 do this block
   877                          
   878  91d4 e672               	INC	ut1_ph		; increment source pointer high byte
   879  91d6 e674               	INC	ut2_ph		; increment destination pointer high byte
   880  91d8 ca                 	DEX				; decrement block count
   881  91d9 d0f2               	BNE	LAB_12D8		; loop until all done
   882                          
   883                          					; got new line in buffer and no existing same #
   884                          LAB_12E6
   885  91db ad2103             	LDA	Ibuffs		; get byte from start of input buffer
   886  91de f03f               	BEQ	LAB_1319		; if null line just go flush stack/vars and exit
   887                          
   888                          					; got new line and it isn't empty line
   889  91e0 a585               	LDA	Ememl			; get end of mem low byte
   890  91e2 a486               	LDY	Ememh			; get end of mem high byte
   891  91e4 8581               	STA	Sstorl		; set bottom of string space low byte
   892  91e6 8482               	STY	Sstorh		; set bottom of string space high byte
   893  91e8 a57b               	LDA	Svarl			; get start of vars low byte	(end of BASIC)
   894  91ea 85a6               	STA	Obendl		; save old block end low byte
   895  91ec a47c               	LDY	Svarh			; get start of vars high byte	(end of BASIC)
   896  91ee 84a7               	STY	Obendh		; save old block end high byte
   897  91f0 655d               	ADC	Ibptr			; add input buffer pointer	(also buffer length)
   898  91f2 9001               	BCC	LAB_1301		; branch if no overflow from add
   899                          
   900  91f4 c8                 	INY				; else increment high byte
   901                          LAB_1301
   902  91f5 85a4               	STA	Nbendl		; save new block end low byte	(move to, low byte)
   903  91f7 84a5               	STY	Nbendh		; save new block end high byte
   904  91f9 20cc90             	JSR	LAB_11CF		; open up space in memory
   905                          					; old start pointer Ostrtl,Ostrth set by the find line call
   906  91fc a57f               	LDA	Earryl		; get array mem end low byte
   907  91fe a480               	LDY	Earryh		; get array mem end high byte
   908  9200 857b               	STA	Svarl			; save start of vars low byte
   909  9202 847c               	STY	Svarh			; save start of vars high byte
   910  9204 a45d               	LDY	Ibptr			; get input buffer pointer	(also buffer length)
   911  9206 88                 	DEY				; adjust for loop type
   912                          LAB_1311
   913  9207 b91d03             	LDA	Ibuffs-4,Y		; get byte from crunched line
   914  920a 91aa               	STA	(Baslnl),Y		; save it to program memory
   915  920c 88                 	DEY				; decrement count
   916  920d c003               	CPY	#$03			; compare with first byte-1
   917  920f d0f6               	BNE	LAB_1311		; continue while count <> 3
   918                          
   919  9211 a512               	LDA	Itemph		; get line # high byte
   920  9213 91aa               	STA	(Baslnl),Y		; save it to program memory
   921  9215 88                 	DEY				; decrement count
   922  9216 a511               	LDA	Itempl		; get line # low byte
   923  9218 91aa               	STA	(Baslnl),Y		; save it to program memory
   924  921a 88                 	DEY				; decrement count
   925  921b a9ff               	LDA	#$FF			; set byte to allow chain rebuild. if you didn't set this
   926                          					; byte then a zero already here would stop the chain rebuild
   927                          					; as it would think it was the [EOT] marker.
   928  921d 91aa               	STA	(Baslnl),Y		; save it to program memory
   929                          
   930                          LAB_1319
   931  921f 207c93             	JSR	LAB_1477		; reset execution to start, clear vars and flush stack
   932  9222 a679               	LDX	Smeml			; get start of mem low byte
   933  9224 a57a               	LDA	Smemh			; get start of mem high byte
   934  9226 a001               	LDY	#$01			; index to high byte of next line pointer
   935                          LAB_1325
   936  9228 8671               	STX	ut1_pl		; set line start pointer low byte
   937  922a 8572               	STA	ut1_ph		; set line start pointer high byte
   938  922c b171               	LDA	(ut1_pl),Y		; get it
   939  922e f018               	BEQ	LAB_133E		; exit if end of program
   940                          
   941                          ; rebuild chaining of Basic lines
   942                          
   943  9230 a004               	LDY	#$04			; point to first code byte of line
   944                          					; there is always 1 byte + [EOL] as null entries are deleted
   945                          LAB_1330
   946  9232 c8                 	INY				; next code byte
   947  9233 b171               	LDA	(ut1_pl),Y		; get byte
   948  9235 d0fb               	BNE	LAB_1330		; loop if not [EOL]
   949                          
   950  9237 38                 	SEC				; set carry for add + 1
   951  9238 98                 	TYA				; copy end index
   952  9239 6571               	ADC	ut1_pl		; add to line start pointer low byte
   953  923b aa                 	TAX				; copy to X
   954  923c a000               	LDY	#$00			; clear index, point to this line's next line pointer
   955  923e 9171               	STA	(ut1_pl),Y		; set next line pointer low byte
   956  9240 98                 	TYA				; clear A
   957  9241 6572               	ADC	ut1_ph		; add line start pointer high byte + carry
   958  9243 c8                 	INY				; increment index to high byte
   959  9244 9171               	STA	(ut1_pl),Y		; save next line pointer low byte
   960  9246 90e0               	BCC	LAB_1325		; go do next line, branch always, carry clear
   961                          
   962                          
   963                          LAB_133E
   964  9248 4c7291             	JMP	LAB_127D		; else we just wait for Basic command, no "Ready"
   965                          
   966                          ; print "? " and get BASIC input
   967                          
   968                          LAB_INLN
   969  924b 200299             	JSR	LAB_18E3		; print "?" character
   970  924e 20ff98             	JSR	LAB_18E0		; print " "
   971  9251 d005               	BNE	LAB_1357		; call for BASIC input and return
   972                          
   973                          ; receive line from keyboard
   974                          
   975                          					; $08 as delete key (BACKSPACE on standard keyboard)
   976                          LAB_134B
   977  9253 200499             	JSR	LAB_PRNA		; go print the character
   978  9256 ca                 	DEX				; decrement the buffer counter (delete)
   979  9257 2c                 	!text	$2C			; make LDX into BIT abs
   980                          
   981                          ; call for BASIC input (main entry point)
   982                          
   983                          LAB_1357
   984  9258 a200               	LDX	#$00			; clear BASIC line buffer pointer
   985                          LAB_1359
   986  925a 2009b1             	JSR	V_INPT		; call scan input device
   987  925d 90fb               	BCC	LAB_1359		; loop if no byte
   988                          
   989  925f f0f9               	BEQ	LAB_1359		; loop until valid input (ignore NULLs)
   990                          
   991  9261 c907               	CMP	#$07			; compare with [BELL]
   992  9263 f010               	BEQ	LAB_1378		; branch if [BELL]
   993                          
   994  9265 c90d               	CMP	#$0D			; compare with [CR]
   995  9267 f019               	BEQ	LAB_1384		; do CR/LF exit if [CR]
   996                          
   997  9269 e000               	CPX	#$00			; compare pointer with $00
   998  926b d004               	BNE	LAB_1374		; branch if not empty
   999                          
  1000                          ; next two lines ignore any non print character and [SPACE] if input buffer empty
  1001                          
  1002  926d c921               	CMP	#$21			; compare with [SP]+1
  1003  926f 90e9               	BCC	LAB_1359		; if < ignore character
  1004                          
  1005                          LAB_1374
  1006  9271 c908               	CMP	#$08			; compare with [BACKSPACE] (delete last character)
  1007  9273 f0de               	BEQ	LAB_134B		; go delete last character
  1008                          
  1009                          LAB_1378
  1010  9275 e047               	CPX	#Ibuffe-Ibuffs	; compare character count with max
  1011  9277 b00c               	BCS	LAB_138E		; skip store and do [BELL] if buffer full
  1012                          
  1013  9279 9d2103             	STA	Ibuffs,X		; else store in buffer
  1014  927c e8                 	INX				; increment pointer
  1015                          LAB_137F
  1016  927d 200499             	JSR	LAB_PRNA		; go print the character
  1017  9280 d0d8               	BNE	LAB_1359		; always loop for next character
  1018                          
  1019                          LAB_1384
  1020  9282 4ca598             	JMP	LAB_1866		; do CR/LF exit to BASIC
  1021                          
  1022                          ; announce buffer full
  1023                          
  1024                          LAB_138E
  1025  9285 a907               	LDA	#$07			; [BELL] character into A
  1026  9287 d0f4               	BNE	LAB_137F		; go print the [BELL] but ignore input character
  1027                          					; branch always
  1028                          
  1029                          ; crunch keywords into Basic tokens
  1030                          ; position independent buffer version ..
  1031                          ; faster, dictionary search version ....
  1032                          
  1033                          LAB_13A6
  1034  9289 a0ff                     LDY   #$FF              ; set save index (makes for easy math later)
  1035                          
  1036  928b 38                       SEC                     ; set carry for subtract
  1037  928c a5c3                     LDA   Bpntrl            ; get basic execute pointer low byte
  1038  928e e921                     SBC   #<Ibuffs          ; subtract input buffer start pointer
  1039  9290 aa                       TAX                     ; copy result to X (index past line # if any)
  1040                          
  1041  9291 8660                     STX   Oquote            ; clear open quote/DATA flag
  1042                          LAB_13AC
  1043  9293 bd2103                   LDA   Ibuffs,X          ; get byte from input buffer
  1044  9296 f05d                     BEQ   LAB_13EC          ; if null save byte then exit
  1045                          
  1046                          ; Applied case sensitivity patch from 
  1047                          ; https://github.com/Klaus2m5/6502_EhBASIC_V2.22/blob/master/mixed_case_keywords_mod.txt
  1048                          ;
  1049                          ; *** begin patch: lower case token recognition V2 ***
  1050                          ; ***              WARNING! changes documented behavior!
  1051                          ; *** add
  1052  9298 c97b                     CMP   #'{'              ; convert lower to upper case
  1053  929a b059                     BCS   LAB_13EC          ; is above lower case
  1054  929c c961                     CMP   #'a'
  1055  929e 9002                     BCC   PATCH_LC          ; is below lower case
  1056  92a0 29df                     AND   #$DF              ; mask lower case bit
  1057                                
  1058                          PATCH_LC
  1059                          ; *** end
  1060                             
  1061  92a2 c95f                     CMP   #'_'              ; compare with "_"
  1062  92a4 b04f                     BCS   LAB_13EC          ; if >= go save byte then continue crunching
  1063                          
  1064  92a6 c93c                     CMP   #'<'              ; compare with "<"
  1065  92a8 b00e                     BCS   LAB_13CC          ; if >= go crunch now
  1066                          
  1067  92aa c930                     CMP   #'0'              ; compare with "0"
  1068  92ac b047                     BCS   LAB_13EC          ; if >= go save byte then continue crunching
  1069                          
  1070  92ae 855c                     STA   Scnquo            ; save buffer byte as search character
  1071  92b0 c922                     CMP   #$22              ; is it quote character?
  1072  92b2 f063                     BEQ   LAB_1410          ; branch if so (copy quoted string)
  1073                          
  1074  92b4 c92a                     CMP   #'*'              ; compare with "*"
  1075  92b6 903d                     BCC   LAB_13EC          ; if < go save byte then continue crunching
  1076                          
  1077                                                        ; else crunch now
  1078                          LAB_13CC
  1079  92b8 2460                     BIT   Oquote            ; get open quote/DATA token flag
  1080  92ba 7039                     BVS   LAB_13EC          ; branch if b6 of Oquote set (was DATA)
  1081                                                        ; go save byte then continue crunching
  1082                          
  1083  92bc 8678                     STX   TempB             ; save buffer read index
  1084  92be 84ba                     STY   csidx             ; copy buffer save index
  1085  92c0 a039                     LDY   #<TAB_1STC        ; get keyword first character table low address
  1086  92c2 8473                     STY   ut2_pl            ; save pointer low byte
  1087  92c4 a0b3                     LDY   #>TAB_1STC        ; get keyword first character table high address
  1088  92c6 8474                     STY   ut2_ph            ; save pointer high byte
  1089  92c8 a000                     LDY   #$00              ; clear table pointer
  1090                          
  1091                          LAB_13D0
  1092  92ca d173                     CMP   (ut2_pl),Y        ; compare with keyword first character table byte
  1093  92cc f005                     BEQ   LAB_13D1          ; go do word_table_chr if match
  1094                          
  1095                          ; *** replace
  1096                          ;      BCC   LAB_13EA          ; if < keyword first character table byte go restore
  1097                          ; *** with
  1098  92ce 905b                     BCC   PATCH_LC2         ; if < keyword first character table byte go restore
  1099                          ; *** end
  1100                                                        ; Y and save to crunched
  1101                          
  1102  92d0 c8                       INY                     ; else increment pointer
  1103  92d1 d0f7                     BNE   LAB_13D0          ; and loop (branch always)
  1104                          
  1105                          ; have matched first character of some keyword
  1106                          
  1107                          LAB_13D1
  1108  92d3 98                       TYA                     ; copy matching index
  1109  92d4 0a                       ASL                     ; *2 (bytes per pointer)
  1110  92d5 aa                       TAX                     ; copy to new index
  1111  92d6 bd57b3                   LDA   TAB_CHRT,X        ; get keyword table pointer low byte
  1112  92d9 8573                     STA   ut2_pl            ; save pointer low byte
  1113  92db bd58b3                   LDA   TAB_CHRT+1,X      ; get keyword table pointer high byte
  1114  92de 8574                     STA   ut2_ph            ; save pointer high byte
  1115                          
  1116  92e0 a0ff                     LDY   #$FF              ; clear table pointer (make -1 for start)
  1117                          
  1118  92e2 a678                     LDX   TempB             ; restore buffer read index
  1119                          
  1120                          LAB_13D6
  1121  92e4 c8                       INY                     ; next table byte
  1122  92e5 b173                     LDA   (ut2_pl),Y        ; get byte from table
  1123                          LAB_13D8
  1124  92e7 300a                     BMI   LAB_13EA          ; all bytes matched so go save token
  1125                          
  1126  92e9 e8                       INX                     ; next buffer byte
  1127                          ; *** replace
  1128                          ;      CMP   Ibuffs,X          ; compare with byte from input buffer
  1129                          ; *** with
  1130  92ea 5d2103                   EOR     Ibuffs,x        ; check bits against table
  1131  92ed 29df                     AND     #$DF            ; DF masks the upper/lower case bit
  1132                          ; *** end      
  1133  92ef f0f3                     BEQ   LAB_13D6          ; go compare next if match
  1134                          
  1135  92f1 d02b                     BNE   LAB_1417          ; branch if >< (not found keyword)
  1136                          
  1137                          LAB_13EA
  1138  92f3 a4ba                     LDY   csidx             ; restore save index
  1139                          
  1140                                                        ; save crunched to output
  1141                          LAB_13EC
  1142  92f5 e8                       INX                     ; increment buffer index (to next input byte)
  1143  92f6 c8                       INY                     ; increment save index (to next output byte)
  1144  92f7 992103                   STA   Ibuffs,Y          ; save byte to output
  1145  92fa c900                     CMP   #$00              ; set the flags, set carry
  1146  92fc f032                     BEQ   LAB_142A          ; do exit if was null [EOL]
  1147                          
  1148                                                        ; A holds token or byte here
  1149  92fe e93a                     SBC   #':'              ; subtract ":" (carry set by CMP #00)
  1150  9300 f004                     BEQ   LAB_13FF          ; branch if it was ":" (is now $00)
  1151                          
  1152                                                        ; A now holds token-$3A
  1153  9302 c949                     CMP   #TK_DATA-$3A      ; compare with DATA token - $3A
  1154  9304 d002                     BNE   LAB_1401          ; branch if not DATA
  1155                          
  1156                                                        ; token was : or DATA
  1157                          LAB_13FF
  1158  9306 8560                     STA   Oquote            ; save token-$3A (clear for ":", TK_DATA-$3A for DATA)
  1159                          LAB_1401
  1160  9308 4957                     EOR   #TK_REM-$3A       ; effectively subtract REM token offset
  1161  930a d087                     BNE   LAB_13AC          ; If wasn't REM then go crunch rest of line
  1162                          
  1163  930c 855c                     STA   Asrch             ; else was REM so set search for [EOL]
  1164                          
  1165                                                        ; loop for REM, "..." etc.
  1166                          
  1167                          LAB_1408
  1168  930e bd2103                   LDA   Ibuffs,X          ; get byte from input buffer
  1169  9311 f0e2                     BEQ   LAB_13EC          ; branch if null [EOL]
  1170                          
  1171  9313 c55c                     CMP   Asrch             ; compare with stored character
  1172  9315 f0de                     BEQ   LAB_13EC          ; branch if match (end quote)
  1173                          
  1174                                                        ; entry for copy string in quotes, don't crunch
  1175                          LAB_1410
  1176  9317 c8                       INY                     ; increment buffer save index
  1177  9318 992103                   STA   Ibuffs,Y          ; save byte to output
  1178  931b e8                       INX                     ; increment buffer read index
  1179  931c d0f0                     BNE   LAB_1408          ; loop while <> 0 (should never be 0!)
  1180                          
  1181                                                        ; not found keyword this go
  1182                          LAB_1417
  1183  931e a678                     LDX   TempB             ; compare has failed, restore buffer index (start byte!)
  1184                          
  1185                                                        ; now find the end of this word in the table
  1186                          LAB_141B
  1187  9320 b173                     LDA   (ut2_pl),Y        ; get table byte
  1188  9322 08                       PHP                     ; save status
  1189  9323 c8                       INY                     ; increment table index
  1190  9324 28                       PLP                     ; restore byte status
  1191  9325 10f9                     BPL   LAB_141B          ; if not end of keyword go do next
  1192                          
  1193  9327 b173                     LDA   (ut2_pl),Y        ; get byte from keyword table
  1194  9329 d0bc                     BNE   LAB_13D8          ; go test next word if not zero byte (end of table)
  1195                          
  1196                                                        ; reached end of table with no match
  1197                          ; *** add label
  1198                          PATCH_LC2
  1199                          ; *** end
  1200                          ; *** end   patch: lower case token recognition V2 ***
  1201                          
  1202  932b bd2103                   LDA   Ibuffs,X          ; restore byte from input buffer
  1203  932e 10c3                     BPL   LAB_13EA          ; branch always (all bytes in buffer are $00-$7F)
  1204                                                        ; go save byte in output and continue crunching
  1205                          
  1206                                                        ; reached [EOL]
  1207                          LAB_142A
  1208  9330 c8                       INY                     ; increment pointer
  1209  9331 c8                       INY                     ; increment pointer (makes it next line pointer high byte)
  1210  9332 992103                   STA   Ibuffs,Y          ; save [EOL] (marks [EOT] in immediate mode)
  1211  9335 c8                       INY                     ; adjust for line copy
  1212  9336 c8                       INY                     ; adjust for line copy
  1213  9337 c8                       INY                     ; adjust for line copy
  1214  9338 c6c3                     DEC   Bpntrl            ; allow for increment (change if buffer starts at $xxFF)
  1215  933a 60                       RTS
  1216                          
  1217                          ; search Basic for temp integer line number from start of mem
  1218                          
  1219                          LAB_SSLN
  1220  933b a579               	LDA	Smeml			; get start of mem low byte
  1221  933d a67a               	LDX	Smemh			; get start of mem high byte
  1222                          
  1223                          ; search Basic for temp integer line number from AX
  1224                          ; returns carry set if found
  1225                          ; returns Baslnl/Baslnh pointer to found or next higher (not found) line
  1226                          
  1227                          ; old 541 new 507
  1228                          
  1229                          LAB_SHLN
  1230  933f a001               	LDY	#$01			; set index
  1231  9341 85aa               	STA	Baslnl		; save low byte as current
  1232  9343 86ab               	STX	Baslnh		; save high byte as current
  1233  9345 b1aa               	LDA	(Baslnl),Y		; get pointer high byte from addr
  1234  9347 f01a               	BEQ	LAB_145F		; pointer was zero so we're done, do 'not found' exit
  1235                          
  1236  9349 a003               	LDY	#$03			; set index to line # high byte
  1237  934b b1aa               	LDA	(Baslnl),Y		; get line # high byte
  1238  934d 88                 	DEY				; decrement index (point to low byte)
  1239  934e c512               	CMP	Itemph		; compare with temporary integer high byte
  1240  9350 d004               	BNE	LAB_1455		; if <> skip low byte check
  1241                          
  1242  9352 b1aa               	LDA	(Baslnl),Y		; get line # low byte
  1243  9354 c511               	CMP	Itempl		; compare with temporary integer low byte
  1244                          LAB_1455
  1245  9356 b009               	BCS	LAB_145E		; else if temp < this line, exit (passed line#)
  1246                          
  1247                          LAB_1456
  1248  9358 88                 	DEY				; decrement index to next line ptr high byte
  1249  9359 b1aa               	LDA	(Baslnl),Y		; get next line pointer high byte
  1250  935b aa                 	TAX				; copy to X
  1251  935c 88                 	DEY				; decrement index to next line ptr low byte
  1252  935d b1aa               	LDA	(Baslnl),Y		; get next line pointer low byte
  1253  935f 90de               	BCC	LAB_SHLN		; go search for line # in temp (Itempl/Itemph) from AX
  1254                          					; (carry always clear)
  1255                          
  1256                          LAB_145E
  1257  9361 f001               	BEQ	LAB_1460		; exit if temp = found line #, carry is set
  1258                          
  1259                          LAB_145F
  1260  9363 18                 	CLC				; clear found flag
  1261                          LAB_1460
  1262  9364 60                 	RTS
  1263                          
  1264                          ; perform NEW
  1265                          
  1266                          LAB_NEW
  1267  9365 d0fd               	BNE	LAB_1460		; exit if not end of statement (to do syntax error)
  1268                          
  1269                          LAB_1463
  1270  9367 a900               	LDA	#$00			; clear A
  1271  9369 a8                 	TAY				; clear Y
  1272  936a 9179               	STA	(Smeml),Y		; clear first line, next line pointer, low byte
  1273  936c c8                 	INY				; increment index
  1274  936d 9179               	STA	(Smeml),Y		; clear first line, next line pointer, high byte
  1275  936f 18                 	CLC				; clear carry
  1276  9370 a579               	LDA	Smeml			; get start of mem low byte
  1277  9372 6902               	ADC	#$02			; calculate end of BASIC low byte
  1278  9374 857b               	STA	Svarl			; save start of vars low byte
  1279  9376 a57a               	LDA	Smemh			; get start of mem high byte
  1280  9378 6900               	ADC	#$00			; add any carry
  1281  937a 857c               	STA	Svarh			; save start of vars high byte
  1282                          
  1283                          ; reset execution to start, clear vars and flush stack
  1284                          
  1285                          LAB_1477
  1286  937c 18                 	CLC				; clear carry
  1287  937d a579               	LDA	Smeml			; get start of mem low byte
  1288  937f 69ff               	ADC	#$FF			; -1
  1289  9381 85c3               	STA	Bpntrl		; save BASIC execute pointer low byte
  1290  9383 a57a               	LDA	Smemh			; get start of mem high byte
  1291  9385 69ff               	ADC	#$FF			; -1+carry
  1292  9387 85c4               	STA	Bpntrh		; save BASIC execute pointer high byte
  1293                          
  1294                          ; "CLEAR" command gets here
  1295                          
  1296                          LAB_147A
  1297  9389 a585               	LDA	Ememl			; get end of mem low byte
  1298  938b a486               	LDY	Ememh			; get end of mem high byte
  1299  938d 8581               	STA	Sstorl		; set bottom of string space low byte
  1300  938f 8482               	STY	Sstorh		; set bottom of string space high byte
  1301  9391 a57b               	LDA	Svarl			; get start of vars low byte
  1302  9393 a47c               	LDY	Svarh			; get start of vars high byte
  1303  9395 857d               	STA	Sarryl		; save var mem end low byte
  1304  9397 847e               	STY	Sarryh		; save var mem end high byte
  1305  9399 857f               	STA	Earryl		; save array mem end low byte
  1306  939b 8480               	STY	Earryh		; save array mem end high byte
  1307  939d 206095             	JSR	LAB_161A		; perform RESTORE command
  1308                          
  1309                          ; flush stack and clear continue flag
  1310                          
  1311                          LAB_1491
  1312  93a0 a268               	LDX	#des_sk		; set descriptor stack pointer
  1313  93a2 8665               	STX	next_s		; save descriptor stack pointer
  1314  93a4 68                 	PLA				; pull return address low byte
  1315  93a5 aa                 	TAX				; copy return address low byte
  1316  93a6 68                 	PLA				; pull return address high byte
  1317  93a7 8efe01             	STX	LAB_SKFE		; save to cleared stack
  1318  93aa 8dff01             	STA	LAB_SKFF		; save to cleared stack
  1319  93ad a2fd               	LDX	#$FD			; new stack pointer
  1320  93af 9a                 	TXS				; reset stack
  1321  93b0 a900               	LDA	#$00			; clear byte
  1322  93b2 858c               	STA	Cpntrh		; clear continue pointer high byte
  1323  93b4 8561               	STA	Sufnxf		; clear subscript/FNX flag
  1324                          LAB_14A6
  1325  93b6 60                 	RTS
  1326                          
  1327                          ; perform CLEAR
  1328                          
  1329                          LAB_CLEAR
  1330  93b7 f0d0               	BEQ	LAB_147A		; if no following token go do "CLEAR"
  1331                          
  1332                          					; else there was a following token (go do syntax error)
  1333  93b9 60                 	RTS
  1334                          
  1335                          ; perform LIST [n][-m]
  1336                          ; bigger, faster version (a _lot_ faster)
  1337                          
  1338                          LAB_LIST
  1339  93ba 9006               	BCC	LAB_14BD		; branch if next character numeric (LIST n..)
  1340                          
  1341  93bc f004               	BEQ	LAB_14BD		; branch if next character [NULL] (LIST)
  1342                          
  1343  93be c9bc               	CMP	#TK_MINUS		; compare with token for -
  1344  93c0 d0f4               	BNE	LAB_14A6		; exit if not - (LIST -m)
  1345                          
  1346                          					; LIST [[n][-m]]
  1347                          					; this bit sets the n , if present, as the start and end
  1348                          LAB_14BD
  1349  93c2 207197             	JSR	LAB_GFPN		; get fixed-point number into temp integer
  1350  93c5 203b93             	JSR	LAB_SSLN		; search BASIC for temp integer line number
  1351                          					; (pointer in Baslnl/Baslnh)
  1352  93c8 20c200             	JSR	LAB_GBYT		; scan memory
  1353  93cb f00c               	BEQ	LAB_14D4		; branch if no more characters
  1354                          
  1355                          					; this bit checks the - is present
  1356  93cd c9bc               	CMP	#TK_MINUS		; compare with token for -
  1357  93cf d093               	BNE	LAB_1460		; return if not "-" (will be Syntax error)
  1358                          
  1359                          					; LIST [n]-m
  1360                          					; the - was there so set m as the end value
  1361  93d1 20bc00             	JSR	LAB_IGBY		; increment and scan memory
  1362  93d4 207197             	JSR	LAB_GFPN		; get fixed-point number into temp integer
  1363  93d7 d08b               	BNE	LAB_1460		; exit if not ok
  1364                          
  1365                          LAB_14D4
  1366  93d9 a511               	LDA	Itempl		; get temporary integer low byte
  1367  93db 0512               	ORA	Itemph		; OR temporary integer high byte
  1368  93dd d006               	BNE	LAB_14E2		; branch if start set
  1369                          
  1370  93df a9ff               	LDA	#$FF			; set for -1
  1371  93e1 8511               	STA	Itempl		; set temporary integer low byte
  1372  93e3 8512               	STA	Itemph		; set temporary integer high byte
  1373                          LAB_14E2
  1374  93e5 a001               	LDY	#$01			; set index for line
  1375  93e7 8460               	STY	Oquote		; clear open quote flag
  1376  93e9 20ae98             	JSR	LAB_CRLF		; print CR/LF
  1377  93ec b1aa               	LDA	(Baslnl),Y		; get next line pointer high byte
  1378                          					; pointer initially set by search at LAB_14BD
  1379  93ee f03e               	BEQ	LAB_152B		; if null all done so exit
  1380  93f0 202b95             	JSR	LAB_1629		; do CRTL-C check vector
  1381                          
  1382  93f3 c8                 	INY				; increment index for line
  1383  93f4 b1aa               	LDA	(Baslnl),Y		; get line # low byte
  1384  93f6 aa                 	TAX				; copy to X
  1385  93f7 c8                 	INY				; increment index
  1386  93f8 b1aa               	LDA	(Baslnl),Y		; get line # high byte
  1387  93fa c512               	CMP	Itemph		; compare with temporary integer high byte
  1388  93fc d004               	BNE	LAB_14FF		; branch if no high byte match
  1389                          
  1390  93fe e411               	CPX	Itempl		; compare with temporary integer low byte
  1391  9400 f002               	BEQ	LAB_1501		; branch if = last line to do (< will pass next branch)
  1392                          
  1393                          LAB_14FF				; else ..
  1394  9402 b02a               	BCS	LAB_152B		; if greater all done so exit
  1395                          
  1396                          LAB_1501
  1397  9404 8497               	STY	Tidx1			; save index for line
  1398  9406 2099aa             	JSR	LAB_295E		; print XA as unsigned integer
  1399  9409 a920               	LDA	#$20			; space is the next character
  1400                          LAB_1508
  1401  940b a497               	LDY	Tidx1			; get index for line
  1402  940d 297f               	AND	#$7F			; mask top out bit of character
  1403                          LAB_150C
  1404  940f 200499             	JSR	LAB_PRNA		; go print the character
  1405  9412 c922               	CMP	#$22			; was it " character
  1406  9414 d006               	BNE	LAB_1519		; branch if not
  1407                          
  1408                          					; we are either entering or leaving a pair of quotes
  1409  9416 a560               	LDA	Oquote		; get open quote flag
  1410  9418 49ff               	EOR	#$FF			; toggle it
  1411  941a 8560               	STA	Oquote		; save it back
  1412                          LAB_1519
  1413  941c c8                 	INY				; increment index
  1414  941d b1aa               	LDA	(Baslnl),Y		; get next byte
  1415  941f d00e               	BNE	LAB_152E		; branch if not [EOL] (go print character)
  1416  9421 a8                 	TAY				; else clear index
  1417  9422 b1aa               	LDA	(Baslnl),Y		; get next line pointer low byte
  1418  9424 aa                 	TAX				; copy to X
  1419  9425 c8                 	INY				; increment index
  1420  9426 b1aa               	LDA	(Baslnl),Y		; get next line pointer high byte
  1421  9428 86aa               	STX	Baslnl		; set pointer to line low byte
  1422  942a 85ab               	STA	Baslnh		; set pointer to line high byte
  1423  942c d0b7               	BNE	LAB_14E2		; go do next line if not [EOT]
  1424                          					; else ..
  1425                          LAB_152B
  1426  942e 60                 	RTS
  1427                          
  1428                          LAB_152E
  1429  942f 10de               	BPL	LAB_150C		; just go print it if not token byte
  1430                          
  1431                          					; else was token byte so uncrunch it (maybe)
  1432  9431 2460               	BIT	Oquote		; test the open quote flag
  1433  9433 30da               	BMI	LAB_150C		; just go print character if open quote set
  1434                          
  1435  9435 a2b5               	LDX	#>LAB_KEYT		; get table address high byte
  1436  9437 0a                 	ASL				; *2
  1437  9438 0a                 	ASL				; *4
  1438  9439 9002               	BCC	LAB_152F		; branch if no carry
  1439                          
  1440  943b e8                 	INX				; else increment high byte
  1441  943c 18                 	CLC				; clear carry for add
  1442                          LAB_152F
  1443  943d 6953               	ADC	#<LAB_KEYT		; add low byte
  1444  943f 9001               	BCC	LAB_1530		; branch if no carry
  1445                          
  1446  9441 e8                 	INX				; else increment high byte
  1447                          LAB_1530
  1448  9442 8573               	STA	ut2_pl		; save table pointer low byte
  1449  9444 8674               	STX	ut2_ph		; save table pointer high byte
  1450  9446 8497               	STY	Tidx1			; save index for line
  1451  9448 a000               	LDY	#$00			; clear index
  1452  944a b173               	LDA	(ut2_pl),Y		; get length
  1453  944c aa                 	TAX				; copy length
  1454  944d c8                 	INY				; increment index
  1455  944e b173               	LDA	(ut2_pl),Y		; get 1st character
  1456  9450 ca                 	DEX				; decrement length
  1457  9451 f0b8               	BEQ	LAB_1508		; if no more characters exit and print
  1458                          
  1459  9453 200499             	JSR	LAB_PRNA		; go print the character
  1460  9456 c8                 	INY				; increment index
  1461  9457 b173               	LDA	(ut2_pl),Y		; get keyword address low byte
  1462  9459 48                 	PHA				; save it for now
  1463  945a c8                 	INY				; increment index
  1464  945b b173               	LDA	(ut2_pl),Y		; get keyword address high byte
  1465  945d a000               	LDY	#$00
  1466  945f 8574               	STA	ut2_ph		; save keyword pointer high byte
  1467  9461 68                 	PLA				; pull low byte
  1468  9462 8573               	STA	ut2_pl		; save keyword pointer low byte
  1469                          LAB_1540
  1470  9464 b173               	LDA	(ut2_pl),Y		; get character
  1471  9466 ca                 	DEX				; decrement character count
  1472  9467 f0a2               	BEQ	LAB_1508		; if last character exit and print
  1473                          
  1474  9469 200499             	JSR	LAB_PRNA		; go print the character
  1475  946c c8                 	INY				; increment index
  1476  946d d0f5               	BNE	LAB_1540		; loop for next character
  1477                          
  1478                          ; perform FOR
  1479                          
  1480                          LAB_FOR
  1481  946f a980               	LDA	#$80			; set FNX
  1482  9471 8561               	STA	Sufnxf		; set subscript/FNX flag
  1483  9473 20d097             	JSR	LAB_LET		; go do LET
  1484  9476 68                 	PLA				; pull return address
  1485  9477 68                 	PLA				; pull return address
  1486  9478 a910               	LDA	#$10			; we need 16d bytes !
  1487  947a 200e91             	JSR	LAB_1212		; check room on stack for A bytes
  1488  947d 20b996             	JSR	LAB_SNBS		; scan for next BASIC statement ([:] or [EOL])
  1489  9480 18                 	CLC				; clear carry for add
  1490  9481 98                 	TYA				; copy index to A
  1491  9482 65c3               	ADC	Bpntrl		; add BASIC execute pointer low byte
  1492  9484 48                 	PHA				; push onto stack
  1493  9485 a5c4               	LDA	Bpntrh		; get BASIC execute pointer high byte
  1494  9487 6900               	ADC	#$00			; add carry
  1495  9489 48                 	PHA				; push onto stack
  1496  948a a588               	LDA	Clineh		; get current line high byte
  1497  948c 48                 	PHA				; push onto stack
  1498  948d a587               	LDA	Clinel		; get current line low byte
  1499  948f 48                 	PHA				; push onto stack
  1500  9490 a9b2               	LDA	#TK_TO		; get "TO" token
  1501  9492 20089c             	JSR	LAB_SCCA		; scan for CHR$(A) , else do syntax error then warm start
  1502  9495 20e79a             	JSR	LAB_CTNM		; check if source is numeric, else do type mismatch
  1503  9498 20e49a             	JSR	LAB_EVNM		; evaluate expression and check is numeric,
  1504                          					; else do type mismatch
  1505  949b a5b0               	LDA	FAC1_s		; get FAC1 sign (b7)
  1506  949d 097f               	ORA	#$7F			; set all non sign bits
  1507  949f 25ad               	AND	FAC1_1		; and FAC1 mantissa1
  1508  94a1 85ad               	STA	FAC1_1		; save FAC1 mantissa1
  1509  94a3 a9ae               	LDA	#<LAB_159F		; set return address low byte
  1510  94a5 a094               	LDY	#>LAB_159F		; set return address high byte
  1511  94a7 8571               	STA	ut1_pl		; save return address low byte
  1512  94a9 8472               	STY	ut1_ph		; save return address high byte
  1513  94ab 4c9b9b             	JMP	LAB_1B66		; round FAC1 and put on stack (returns to next instruction)
  1514                          
  1515                          LAB_159F
  1516  94ae a9ff               	LDA	#<LAB_259C		; set 1 pointer low addr (default step size)
  1517  94b0 a0b1               	LDY	#>LAB_259C		; set 1 pointer high addr
  1518  94b2 2094a8             	JSR	LAB_UFAC		; unpack memory (AY) into FAC1
  1519  94b5 20c200             	JSR	LAB_GBYT		; scan memory
  1520  94b8 c9b7               	CMP	#TK_STEP		; compare with STEP token
  1521  94ba d006               	BNE	LAB_15B3		; jump if not "STEP"
  1522                          
  1523                          					;.was step so ..
  1524  94bc 20bc00             	JSR	LAB_IGBY		; increment and scan memory
  1525  94bf 20e49a             	JSR	LAB_EVNM		; evaluate expression and check is numeric,
  1526                          					; else do type mismatch
  1527                          LAB_15B3
  1528  94c2 2000a9             	JSR	LAB_27CA		; return A=FF,C=1/-ve A=01,C=0/+ve
  1529  94c5 85b0               	STA	FAC1_s		; set FAC1 sign (b7)
  1530                          					; this is +1 for +ve step and -1 for -ve step, in NEXT we
  1531                          					; compare the FOR value and the TO value and return +1 if
  1532                          					; FOR > TO, 0 if FOR = TO and -1 if FOR < TO. the value
  1533                          					; here (+/-1) is then compared to that result and if they
  1534                          					; are the same (+ve and FOR > TO or -ve and FOR < TO) then
  1535                          					; the loop is done
  1536  94c7 20909b             	JSR	LAB_1B5B		; push sign, round FAC1 and put on stack
  1537  94ca a598               	LDA	Frnxth		; get var pointer for FOR/NEXT high byte
  1538  94cc 48                 	PHA				; push on stack
  1539  94cd a597               	LDA	Frnxtl		; get var pointer for FOR/NEXT low byte
  1540  94cf 48                 	PHA				; push on stack
  1541  94d0 a981               	LDA	#TK_FOR		; get FOR token
  1542  94d2 48                 	PHA				; push on stack
  1543                          
  1544                          ; interpreter inner loop
  1545                          
  1546                          LAB_15C2
  1547  94d3 202b95             	JSR	LAB_1629		; do CRTL-C check vector
  1548  94d6 a5c3               	LDA	Bpntrl		; get BASIC execute pointer low byte
  1549  94d8 a4c4               	LDY	Bpntrh		; get BASIC execute pointer high byte
  1550                          
  1551  94da a688               	LDX	Clineh		; continue line is $FFxx for immediate mode
  1552                          					; ($00xx for RUN from immediate mode)
  1553  94dc e8                 	INX				; increment it (now $00 if immediate mode)
  1554  94dd f004               	BEQ	LAB_15D1		; branch if null (immediate mode)
  1555                          
  1556  94df 858b               	STA	Cpntrl		; save continue pointer low byte
  1557  94e1 848c               	STY	Cpntrh		; save continue pointer high byte
  1558                          LAB_15D1
  1559  94e3 a000               	LDY	#$00			; clear index
  1560  94e5 b1c3               	LDA	(Bpntrl),Y		; get next byte
  1561  94e7 f007               	BEQ	LAB_15DC		; branch if null [EOL]
  1562                          
  1563  94e9 c93a               	CMP	#':'			; compare with ":"
  1564  94eb f01d               	BEQ	LAB_15F6		; branch if = (statement separator)
  1565                          
  1566                          LAB_15D9
  1567  94ed 4c199c             	JMP	LAB_SNER		; else syntax error then warm start
  1568                          
  1569                          					; have reached [EOL]
  1570                          LAB_15DC
  1571  94f0 a002               	LDY	#$02			; set index
  1572  94f2 b1c3               	LDA	(Bpntrl),Y		; get next line pointer high byte
  1573  94f4 18                 	CLC				; clear carry for no "BREAK" message
  1574  94f5 f056               	BEQ	LAB_1651		; if null go to immediate mode (was immediate or [EOT]
  1575                          					; marker)
  1576                          
  1577  94f7 c8                 	INY				; increment index
  1578  94f8 b1c3               	LDA	(Bpntrl),Y		; get line # low byte
  1579  94fa 8587               	STA	Clinel		; save current line low byte
  1580  94fc c8                 	INY				; increment index
  1581  94fd b1c3               	LDA	(Bpntrl),Y		; get line # high byte
  1582  94ff 8588               	STA	Clineh		; save current line high byte
  1583  9501 98                 	TYA				; A now = 4
  1584  9502 65c3               	ADC	Bpntrl		; add BASIC execute pointer low byte
  1585  9504 85c3               	STA	Bpntrl		; save BASIC execute pointer low byte
  1586  9506 9002               	BCC	LAB_15F6		; branch if no overflow
  1587                          
  1588  9508 e6c4               	INC	Bpntrh		; else increment BASIC execute pointer high byte
  1589                          LAB_15F6
  1590  950a 20bc00             	JSR	LAB_IGBY		; increment and scan memory
  1591                          
  1592                          LAB_15F9
  1593  950d 201395             	JSR	LAB_15FF		; go interpret BASIC code from (Bpntrl)
  1594                          
  1595                          LAB_15FC
  1596  9510 4cd394             	JMP	LAB_15C2		; loop
  1597                          
  1598                          ; interpret BASIC code from (Bpntrl)
  1599                          
  1600                          LAB_15FF
  1601  9513 f059               	BEQ	LAB_1628		; exit if zero [EOL]
  1602                          
  1603                          LAB_1602
  1604  9515 0a                 	ASL				; *2 bytes per vector and normalise token
  1605  9516 b003               	BCS	LAB_1609		; branch if was token
  1606                          
  1607  9518 4cd097             	JMP	LAB_LET		; else go do implied LET
  1608                          
  1609                          LAB_1609
  1610  951b c960               	CMP	#(TK_TAB-$80)*2	; compare normalised token * 2 with TAB
  1611  951d b0ce               	BCS	LAB_15D9		; branch if A>=TAB (do syntax error then warm start)
  1612                          					; only tokens before TAB can start a line
  1613  951f a8                 	TAY				; copy to index
  1614  9520 b927b2             	LDA	LAB_CTBL+1,Y	; get vector high byte
  1615  9523 48                 	PHA				; onto stack
  1616  9524 b926b2             	LDA	LAB_CTBL,Y		; get vector low byte
  1617  9527 48                 	PHA				; onto stack
  1618  9528 4cbc00             	JMP	LAB_IGBY		; jump to increment and scan memory
  1619                          					; then "return" to vector
  1620                          
  1621                          ; CTRL-C check jump. this is called as a subroutine but exits back via a jump if a
  1622                          ; key press is detected.
  1623                          
  1624                          LAB_1629
  1625  952b 6c0303             	JMP	(VEC_CC)		; ctrl c check vector
  1626                          
  1627                          ; if there was a key press it gets back here ..
  1628                          
  1629                          LAB_1636
  1630  952e c903               	CMP	#$03			; compare with CTRL-C
  1631                          
  1632                          ; perform STOP
  1633                          
  1634                          LAB_STOP
  1635  9530 b001               	BCS	LAB_163B		; branch if token follows STOP
  1636                          					; else just END
  1637                          ; END
  1638                          
  1639                          LAB_END
  1640  9532 18                 	CLC				; clear the carry, indicate a normal program end
  1641                          LAB_163B
  1642  9533 d06c               	BNE	LAB_167A		; if wasn't CTRL-C or there is a following byte return
  1643                          
  1644  9535 a5c4               	LDA	Bpntrh		; get the BASIC execute pointer high byte
  1645  9537 4903               	EOR	#>Ibuffs		; compare with buffer address high byte (Cb unchanged)
  1646  9539 f010               	BEQ	LAB_164F		; branch if the BASIC pointer is in the input buffer
  1647                          					; (can't continue in immediate mode)
  1648                          
  1649                          					; else ..
  1650  953b 4903               	EOR	#>Ibuffs		; correct the bits
  1651  953d a4c3               	LDY	Bpntrl		; get BASIC execute pointer low byte
  1652  953f 848b               	STY	Cpntrl		; save continue pointer low byte
  1653  9541 858c               	STA	Cpntrh		; save continue pointer high byte
  1654                          LAB_1647
  1655  9543 a587               	LDA	Clinel		; get current line low byte
  1656  9545 a488               	LDY	Clineh		; get current line high byte
  1657  9547 8589               	STA	Blinel		; save break line low byte
  1658  9549 848a               	STY	Blineh		; save break line high byte
  1659                          LAB_164F
  1660  954b 68                 	PLA				; pull return address low
  1661  954c 68                 	PLA				; pull return address high
  1662                          LAB_1651
  1663  954d 08                 	php
  1664  954e 20ccb8             	jsr hbc56SetupDisplay
  1665  9551 28                 	plp
  1666  9552 9007               	BCC	LAB_165E		; if was program end just do warm start
  1667                          
  1668                          					; else ..
  1669  9554 a946               	LDA	#<LAB_BMSG		; point to "Break" low byte
  1670  9556 a0b8               	LDY	#>LAB_BMSG		; point to "Break" high byte
  1671  9558 4c5a91             	JMP	LAB_1269		; print "Break" and do warm start
  1672                          
  1673                          LAB_165E
  1674  955b 4c6591             	JMP	LAB_1274		; go do warm start
  1675                          
  1676                          ; perform RESTORE
  1677                          
  1678                          LAB_RESTORE
  1679  955e d00f               	BNE	LAB_RESTOREn	; branch if next character not null (RESTORE n)
  1680                          
  1681                          LAB_161A
  1682  9560 38                 	SEC				; set carry for subtract
  1683  9561 a579               	LDA	Smeml			; get start of mem low byte
  1684  9563 e901               	SBC	#$01			; -1
  1685  9565 a47a               	LDY	Smemh			; get start of mem high byte
  1686  9567 b001               	BCS	LAB_1624		; branch if no underflow
  1687                          
  1688                          LAB_uflow
  1689  9569 88                 	DEY				; else decrement high byte
  1690                          LAB_1624
  1691  956a 858f               	STA	Dptrl			; save DATA pointer low byte
  1692  956c 8490               	STY	Dptrh			; save DATA pointer high byte
  1693                          LAB_1628
  1694  956e 60                 	RTS
  1695                          
  1696                          					; is RESTORE n
  1697                          LAB_RESTOREn
  1698  956f 207197             	JSR	LAB_GFPN		; get fixed-point number into temp integer
  1699  9572 20bc96             	JSR	LAB_SNBL		; scan for next BASIC line
  1700  9575 a588               	LDA	Clineh		; get current line high byte
  1701  9577 c512               	CMP	Itemph		; compare with temporary integer high byte
  1702  9579 b00b               	BCS	LAB_reset_search	; branch if >= (start search from beginning)
  1703                          
  1704  957b 98                 	TYA				; else copy line index to A
  1705  957c 38                 	SEC				; set carry (+1)
  1706  957d 65c3               	ADC	Bpntrl		; add BASIC execute pointer low byte
  1707  957f a6c4               	LDX	Bpntrh		; get BASIC execute pointer high byte
  1708  9581 9007               	BCC	LAB_go_search	; branch if no overflow to high byte
  1709                          
  1710  9583 e8                 	INX				; increment high byte
  1711  9584 b004               	BCS	LAB_go_search	; branch always (can never be carry clear)
  1712                          
  1713                          ; search for line # in temp (Itempl/Itemph) from start of mem pointer (Smeml)
  1714                          
  1715                          LAB_reset_search
  1716  9586 a579               	LDA	Smeml			; get start of mem low byte
  1717  9588 a67a               	LDX	Smemh			; get start of mem high byte
  1718                          
  1719                          ; search for line # in temp (Itempl/Itemph) from (AX)
  1720                          
  1721                          LAB_go_search
  1722                          
  1723  958a 203f93             	JSR	LAB_SHLN		; search Basic for temp integer line number from AX
  1724  958d b003               	BCS	LAB_line_found	; if carry set go set pointer
  1725                          
  1726  958f 4c8e96             	JMP	LAB_16F7		; else go do "Undefined statement" error
  1727                          
  1728                          LAB_line_found
  1729                          					; carry already set for subtract
  1730  9592 a5aa               	LDA	Baslnl		; get pointer low byte
  1731  9594 e901               	SBC	#$01			; -1
  1732  9596 a4ab               	LDY	Baslnh		; get pointer high byte
  1733  9598 b0d0               	BCS	LAB_1624		; branch if no underflow (save DATA pointer and return)
  1734                          
  1735  959a 90cd               	BCC	LAB_uflow		; else decrement high byte then save DATA pointer and
  1736                          					; return (branch always)
  1737                          
  1738                          ; perform NULL
  1739                          
  1740                          LAB_NULL
  1741  959c 20a3a4             	JSR	LAB_GTBY		; get byte parameter
  1742  959f 860d               	STX	Nullct		; save new NULL count
  1743                          LAB_167A
  1744  95a1 60                 	RTS
  1745                          
  1746                          ; perform CONT
  1747                          
  1748                          LAB_CONT
  1749  95a2 d0fd               	BNE	LAB_167A		; if following byte exit to do syntax error
  1750                          
  1751  95a4 a48c               	LDY	Cpntrh		; get continue pointer high byte
  1752  95a6 d005               	BNE	LAB_166C		; go do continue if we can
  1753                          
  1754  95a8 a21e               	LDX	#$1E			; error code $1E ("Can't continue" error)
  1755  95aa 4c4791             	JMP	LAB_XERR		; do error #X, then warm start
  1756                          
  1757                          					; we can continue so ..
  1758                          LAB_166C
  1759  95ad a993               	LDA	#TK_ON		; set token for ON
  1760  95af 202baf             	JSR	LAB_IRQ		; set IRQ flags
  1761  95b2 a993               	LDA	#TK_ON		; set token for ON
  1762  95b4 202eaf             	JSR	LAB_NMI		; set NMI flags
  1763                          
  1764  95b7 84c4               	STY	Bpntrh		; save BASIC execute pointer high byte
  1765  95b9 a58b               	LDA	Cpntrl		; get continue pointer low byte
  1766  95bb 85c3               	STA	Bpntrl		; save BASIC execute pointer low byte
  1767  95bd a589               	LDA	Blinel		; get break line low byte
  1768  95bf a48a               	LDY	Blineh		; get break line high byte
  1769  95c1 8587               	STA	Clinel		; set current line low byte
  1770  95c3 8488               	STY	Clineh		; set current line high byte
  1771  95c5 60                 	RTS
  1772                          
  1773                          ; perform RUN
  1774                          
  1775                          LAB_RUN
  1776  95c6 d003               	BNE	LAB_1696		; branch if RUN n
  1777  95c8 4c7c93             	JMP	LAB_1477		; reset execution to start, clear variables, flush stack and
  1778                          					; return
  1779                          
  1780                          ; does RUN n
  1781                          
  1782                          LAB_1696
  1783  95cb 208993             	JSR	LAB_147A		; go do "CLEAR"
  1784  95ce f02e               	BEQ	LAB_16B0		; get n and do GOTO n (branch always as CLEAR sets Z=1)
  1785                          
  1786                          ; perform DO
  1787                          
  1788                          LAB_DO
  1789  95d0 a905               	LDA	#$05			; need 5 bytes for DO
  1790  95d2 200e91             	JSR	LAB_1212		; check room on stack for A bytes
  1791  95d5 a5c4               	LDA	Bpntrh		; get BASIC execute pointer high byte
  1792  95d7 48                 	PHA				; push on stack
  1793  95d8 a5c3               	LDA	Bpntrl		; get BASIC execute pointer low byte
  1794  95da 48                 	PHA				; push on stack
  1795  95db a588               	LDA	Clineh		; get current line high byte
  1796  95dd 48                 	PHA				; push on stack
  1797  95de a587               	LDA	Clinel		; get current line low byte
  1798  95e0 48                 	PHA				; push on stack
  1799  95e1 a9a0               	LDA	#TK_DO		; token for DO
  1800  95e3 48                 	PHA				; push on stack
  1801  95e4 20c200             	JSR	LAB_GBYT		; scan memory
  1802  95e7 4cd394             	JMP	LAB_15C2		; go do interpreter inner loop
  1803                          
  1804                          ; perform GOSUB
  1805                          
  1806                          LAB_GOSUB
  1807  95ea a905               	LDA	#$05			; need 5 bytes for GOSUB
  1808  95ec 200e91             	JSR	LAB_1212		; check room on stack for A bytes
  1809  95ef a5c4               	LDA	Bpntrh		; get BASIC execute pointer high byte
  1810  95f1 48                 	PHA				; push on stack
  1811  95f2 a5c3               	LDA	Bpntrl		; get BASIC execute pointer low byte
  1812  95f4 48                 	PHA				; push on stack
  1813  95f5 a588               	LDA	Clineh		; get current line high byte
  1814  95f7 48                 	PHA				; push on stack
  1815  95f8 a587               	LDA	Clinel		; get current line low byte
  1816  95fa 48                 	PHA				; push on stack
  1817  95fb a98d               	LDA	#TK_GOSUB		; token for GOSUB
  1818  95fd 48                 	PHA				; push on stack
  1819                          LAB_16B0
  1820  95fe 20c200             	JSR	LAB_GBYT		; scan memory
  1821  9601 200796             	JSR	LAB_GOTO		; perform GOTO n
  1822  9604 4cd394             	JMP	LAB_15C2		; go do interpreter inner loop
  1823                          					; (can't RTS, we used the stack!)
  1824                          
  1825                          ; perform GOTO
  1826                          
  1827                          LAB_GOTO
  1828  9607 207197             	JSR	LAB_GFPN		; get fixed-point number into temp integer
  1829  960a 20bc96             	JSR	LAB_SNBL		; scan for next BASIC line
  1830  960d a588               	LDA	Clineh		; get current line high byte
  1831  960f c512               	CMP	Itemph		; compare with temporary integer high byte
  1832  9611 b00b               	BCS	LAB_16D0		; branch if >= (start search from beginning)
  1833                          
  1834  9613 98                 	TYA				; else copy line index to A
  1835  9614 38                 	SEC				; set carry (+1)
  1836  9615 65c3               	ADC	Bpntrl		; add BASIC execute pointer low byte
  1837  9617 a6c4               	LDX	Bpntrh		; get BASIC execute pointer high byte
  1838  9619 9007               	BCC	LAB_16D4		; branch if no overflow to high byte
  1839                          
  1840  961b e8                 	INX				; increment high byte
  1841  961c b004               	BCS	LAB_16D4		; branch always (can never be carry)
  1842                          
  1843                          ; search for line # in temp (Itempl/Itemph) from start of mem pointer (Smeml)
  1844                          
  1845                          LAB_16D0
  1846  961e a579               	LDA	Smeml			; get start of mem low byte
  1847  9620 a67a               	LDX	Smemh			; get start of mem high byte
  1848                          
  1849                          ; search for line # in temp (Itempl/Itemph) from (AX)
  1850                          
  1851                          LAB_16D4
  1852  9622 203f93             	JSR	LAB_SHLN		; search Basic for temp integer line number from AX
  1853  9625 9067               	BCC	LAB_16F7		; if carry clear go do "Undefined statement" error
  1854                          					; (unspecified statement)
  1855                          
  1856                          					; carry already set for subtract
  1857  9627 a5aa               	LDA	Baslnl		; get pointer low byte
  1858  9629 e901               	SBC	#$01			; -1
  1859  962b 85c3               	STA	Bpntrl		; save BASIC execute pointer low byte
  1860  962d a5ab               	LDA	Baslnh		; get pointer high byte
  1861  962f e900               	SBC	#$00			; subtract carry
  1862  9631 85c4               	STA	Bpntrh		; save BASIC execute pointer high byte
  1863                          LAB_16E5
  1864  9633 60                 	RTS
  1865                          
  1866                          LAB_DONOK
  1867  9634 a222               	LDX	#$22			; error code $22 ("LOOP without DO" error)
  1868  9636 4c4791             	JMP	LAB_XERR		; do error #X, then warm start
  1869                          
  1870                          ; perform LOOP
  1871                          
  1872                          LAB_LOOP
  1873  9639 a8                 	TAY				; save following token
  1874  963a ba                 	TSX				; copy stack pointer
  1875  963b bd0301             	LDA	LAB_STAK+3,X	; get token byte from stack
  1876  963e c9a0               	CMP	#TK_DO		; compare with DO token
  1877  9640 d0f2               	BNE	LAB_DONOK		; branch if no matching DO
  1878                          
  1879  9642 e8                 	INX				; dump calling routine return address
  1880  9643 e8                 	INX				; dump calling routine return address
  1881  9644 9a                 	TXS				; correct stack
  1882  9645 98                 	TYA				; get saved following token back
  1883  9646 f020               	BEQ	LoopAlways		; if no following token loop forever
  1884                          					; (stack pointer in X)
  1885                          
  1886  9648 c93a               	CMP	#':'			; could be ':'
  1887  964a f01c               	BEQ	LoopAlways		; if :... loop forever
  1888                          
  1889  964c e9b8               	SBC	#TK_UNTIL		; subtract token for UNTIL, we know carry is set here
  1890  964e aa                 	TAX				; copy to X (if it was UNTIL then Y will be correct)
  1891  964f f004               	BEQ	DoRest		; branch if was UNTIL
  1892                          
  1893  9651 ca                 	DEX				; decrement result
  1894  9652 d062               	BNE	LAB_16FC		; if not WHILE go do syntax error and warm start
  1895                          					; only if the token was WHILE will this fail
  1896                          
  1897  9654 ca                 	DEX				; set invert result byte
  1898                          DoRest
  1899  9655 8698               	STX	Frnxth		; save invert result byte
  1900  9657 20bc00             	JSR	LAB_IGBY		; increment and scan memory
  1901  965a 20f89a             	JSR	LAB_EVEX		; evaluate expression
  1902  965d a5ac               	LDA	FAC1_e		; get FAC1 exponent
  1903  965f f002               	BEQ	DoCmp			; if =0 go do straight compare
  1904                          
  1905  9661 a9ff               	LDA	#$FF			; else set all bits
  1906                          DoCmp
  1907  9663 ba                 	TSX				; copy stack pointer
  1908  9664 4598               	EOR	Frnxth		; EOR with invert byte
  1909  9666 d01a               	BNE	LoopDone		; if <> 0 clear stack and back to interpreter loop
  1910                          
  1911                          					; loop condition wasn't met so do it again
  1912                          LoopAlways
  1913  9668 bd0201             	LDA	LAB_STAK+2,X	; get current line low byte
  1914  966b 8587               	STA	Clinel		; save current line low byte
  1915  966d bd0301             	LDA	LAB_STAK+3,X	; get current line high byte
  1916  9670 8588               	STA	Clineh		; save current line high byte
  1917  9672 bd0401             	LDA	LAB_STAK+4,X	; get BASIC execute pointer low byte
  1918  9675 85c3               	STA	Bpntrl		; save BASIC execute pointer low byte
  1919  9677 bd0501             	LDA	LAB_STAK+5,X	; get BASIC execute pointer high byte
  1920  967a 85c4               	STA	Bpntrh		; save BASIC execute pointer high byte
  1921  967c 20c200             	JSR	LAB_GBYT		; scan memory
  1922  967f 4cd394             	JMP	LAB_15C2		; go do interpreter inner loop
  1923                          
  1924                          					; clear stack and back to interpreter loop
  1925                          LoopDone
  1926  9682 e8                 	INX				; dump DO token
  1927  9683 e8                 	INX				; dump current line low byte
  1928  9684 e8                 	INX				; dump current line high byte
  1929  9685 e8                 	INX				; dump BASIC execute pointer low byte
  1930  9686 e8                 	INX				; dump BASIC execute pointer high byte
  1931  9687 9a                 	TXS				; correct stack
  1932  9688 4ca896             	JMP	LAB_DATA		; go perform DATA (find : or [EOL])
  1933                          
  1934                          ; do the return without gosub error
  1935                          
  1936                          LAB_16F4
  1937  968b a204               	LDX	#$04			; error code $04 ("RETURN without GOSUB" error)
  1938  968d 2c                 	!text	$2C			; makes next line BIT LAB_0EA2
  1939                          
  1940                          LAB_16F7				; do undefined statement error
  1941  968e a20e               	LDX	#$0E			; error code $0E ("Undefined statement" error)
  1942  9690 4c4791             	JMP	LAB_XERR		; do error #X, then warm start
  1943                          
  1944                          ; perform RETURN
  1945                          
  1946                          LAB_RETURN
  1947  9693 d09e               	BNE	LAB_16E5		; exit if following token (to allow syntax error)
  1948                          
  1949                          LAB_16E8
  1950  9695 68                 	PLA				; dump calling routine return address
  1951  9696 68                 	PLA				; dump calling routine return address
  1952  9697 68                 	PLA				; pull token
  1953  9698 c98d               	CMP	#TK_GOSUB		; compare with GOSUB token
  1954  969a d0ef               	BNE	LAB_16F4		; branch if no matching GOSUB
  1955                          
  1956                          LAB_16FF
  1957  969c 68                 	PLA				; pull current line low byte
  1958  969d 8587               	STA	Clinel		; save current line low byte
  1959  969f 68                 	PLA				; pull current line high byte
  1960  96a0 8588               	STA	Clineh		; save current line high byte
  1961  96a2 68                 	PLA				; pull BASIC execute pointer low byte
  1962  96a3 85c3               	STA	Bpntrl		; save BASIC execute pointer low byte
  1963  96a5 68                 	PLA				; pull BASIC execute pointer high byte
  1964  96a6 85c4               	STA	Bpntrh		; save BASIC execute pointer high byte
  1965                          
  1966                          					; now do the DATA statement as we could be returning into
  1967                          					; the middle of an ON <var> GOSUB n,m,p,q line
  1968                          					; (the return address used by the DATA statement is the one
  1969                          					; pushed before the GOSUB was executed!)
  1970                          
  1971                          ; perform DATA
  1972                          
  1973                          LAB_DATA
  1974  96a8 20b996             	JSR	LAB_SNBS		; scan for next BASIC statement ([:] or [EOL])
  1975                          
  1976                          					; set BASIC execute pointer
  1977                          LAB_170F
  1978  96ab 98                 	TYA				; copy index to A
  1979  96ac 18                 	CLC				; clear carry for add
  1980  96ad 65c3               	ADC	Bpntrl		; add BASIC execute pointer low byte
  1981  96af 85c3               	STA	Bpntrl		; save BASIC execute pointer low byte
  1982  96b1 9002               	BCC	LAB_1719		; skip next if no carry
  1983                          
  1984  96b3 e6c4               	INC	Bpntrh		; else increment BASIC execute pointer high byte
  1985                          LAB_1719
  1986  96b5 60                 	RTS
  1987                          
  1988                          LAB_16FC
  1989  96b6 4c199c             	JMP	LAB_SNER		; do syntax error then warm start
  1990                          
  1991                          ; scan for next BASIC statement ([:] or [EOL])
  1992                          ; returns Y as index to [:] or [EOL]
  1993                          
  1994                          LAB_SNBS
  1995  96b9 a23a               	LDX	#':'			; set look for character = ":"
  1996  96bb 2c                 	!text	$2C			; makes next line BIT $00A2
  1997                          
  1998                          ; scan for next BASIC line
  1999                          ; returns Y as index to [EOL]
  2000                          
  2001                          LAB_SNBL
  2002  96bc a200               	LDX	#$00			; set alt search character = [EOL]
  2003  96be a000               	LDY	#$00			; set search character = [EOL]
  2004  96c0 845c               	STY	Asrch			; store search character
  2005                          LAB_1725
  2006  96c2 8a                 	TXA				; get alt search character
  2007  96c3 455c               	EOR	Asrch			; toggle search character, effectively swap with $00
  2008  96c5 855c               	STA	Asrch			; save swapped search character
  2009                          LAB_172D
  2010  96c7 b1c3               	LDA	(Bpntrl),Y		; get next byte
  2011  96c9 f0ea               	BEQ	LAB_1719		; exit if null [EOL]
  2012                          
  2013  96cb c55c               	CMP	Asrch			; compare with search character
  2014  96cd f0e6               	BEQ	LAB_1719		; exit if found
  2015                          
  2016  96cf c8                 	INY				; increment index
  2017  96d0 c922               	CMP	#$22			; compare current character with open quote
  2018  96d2 d0f3               	BNE	LAB_172D		; if not open quote go get next character
  2019                          
  2020  96d4 f0ec               	BEQ	LAB_1725		; if found go swap search character for alt search character
  2021                          
  2022                          ; perform IF
  2023                          
  2024                          LAB_IF
  2025  96d6 20f89a             	JSR	LAB_EVEX		; evaluate the expression
  2026  96d9 20c200             	JSR	LAB_GBYT		; scan memory
  2027  96dc c9b5               	CMP	#TK_THEN		; compare with THEN token
  2028  96de f011               	BEQ	LAB_174B		; if it was THEN go do IF
  2029                          
  2030                          					; wasn't IF .. THEN so must be IF .. GOTO
  2031  96e0 c989               	CMP	#TK_GOTO		; compare with GOTO token
  2032  96e2 d0d2               	BNE	LAB_16FC		; if it wasn't GOTO go do syntax error
  2033                          
  2034  96e4 a6c3               	LDX	Bpntrl		; save the basic pointer low byte
  2035  96e6 a4c4               	LDY	Bpntrh		; save the basic pointer high byte
  2036  96e8 20bc00             	JSR	LAB_IGBY		; increment and scan memory
  2037  96eb b0c9               	BCS	LAB_16FC		; if not numeric go do syntax error
  2038                          
  2039  96ed 86c3               	STX	Bpntrl		; restore the basic pointer low byte
  2040  96ef 84c4               	STY	Bpntrh		; restore the basic pointer high byte
  2041                          LAB_174B
  2042  96f1 a5ac               	LDA	FAC1_e		; get FAC1 exponent
  2043  96f3 f01b               	BEQ	LAB_174E		; if the result was zero go look for an ELSE
  2044                          
  2045  96f5 20bc00             	JSR	LAB_IGBY		; else increment and scan memory
  2046  96f8 b003               	BCS	LAB_174D		; if not numeric go do var or keyword
  2047                          
  2048                          LAB_174C
  2049  96fa 4c0796             	JMP	LAB_GOTO		; else was numeric so do GOTO n
  2050                          
  2051                          					; is var or keyword
  2052                          LAB_174D
  2053  96fd c990               	CMP	#TK_RETURN		; compare the byte with the token for RETURN
  2054  96ff d003               	BNE	LAB_174G		; if it wasn't RETURN go interpret BASIC code from (Bpntrl)
  2055                          					; and return to this code to process any following code
  2056                          
  2057  9701 4c1595             	JMP	LAB_1602		; else it was RETURN so interpret BASIC code from (Bpntrl)
  2058                          					; but don't return here
  2059                          
  2060                          LAB_174G
  2061  9704 201395             	JSR	LAB_15FF		; interpret BASIC code from (Bpntrl)
  2062                          
  2063                          ; the IF was executed and there may be a following ELSE so the code needs to return
  2064                          ; here to check and ignore the ELSE if present
  2065                          
  2066  9707 a000               	LDY	#$00			; clear the index
  2067  9709 b1c3               	LDA	(Bpntrl),Y		; get the next BASIC byte
  2068  970b c9b1               	CMP	#TK_ELSE		; compare it with the token for ELSE
  2069  970d f099               	BEQ	LAB_DATA		; if ELSE ignore the following statement
  2070                          
  2071                          ; there was no ELSE so continue execution of IF <expr> THEN <stat> [: <stat>]. any
  2072                          ; following ELSE will, correctly, cause a syntax error
  2073                          
  2074  970f 60                 	RTS				; else return to the interpreter inner loop
  2075                          
  2076                          ; perform ELSE after IF
  2077                          
  2078                          LAB_174E
  2079  9710 a000               	LDY	#$00			; clear the BASIC byte index
  2080  9712 a201               	LDX	#$01			; clear the nesting depth
  2081                          LAB_1750
  2082  9714 c8                 	INY				; increment the BASIC byte index
  2083  9715 b1c3               	LDA	(Bpntrl),Y		; get the next BASIC byte
  2084  9717 f00f               	BEQ	LAB_1753		; if EOL go add the pointer and return
  2085                          
  2086  9719 c98b               	CMP	#TK_IF		; compare the byte with the token for IF
  2087  971b d003               	BNE	LAB_1752		; if not IF token skip the depth increment
  2088                          
  2089  971d e8                 	INX				; else increment the nesting depth ..
  2090  971e d0f4               	BNE	LAB_1750		; .. and continue looking
  2091                          
  2092                          LAB_1752
  2093  9720 c9b1               	CMP	#TK_ELSE		; compare the byte with the token for ELSE
  2094  9722 d0f0               	BNE	LAB_1750		; if not ELSE token continue looking
  2095                          
  2096  9724 ca                 	DEX				; was ELSE so decrement the nesting depth
  2097  9725 d0ed               	BNE	LAB_1750		; loop if still nested
  2098                          
  2099  9727 c8                 	INY				; increment the BASIC byte index past the ELSE
  2100                          
  2101                          ; found the matching ELSE, now do <{n|statement}>
  2102                          
  2103                          LAB_1753
  2104  9728 98                 	TYA				; else copy line index to A
  2105  9729 18                 	CLC				; clear carry for add
  2106  972a 65c3               	ADC	Bpntrl		; add the BASIC execute pointer low byte
  2107  972c 85c3               	STA	Bpntrl		; save the BASIC execute pointer low byte
  2108  972e 9002               	BCC	LAB_1754		; branch if no overflow to high byte
  2109                          
  2110  9730 e6c4               	INC	Bpntrh		; else increment the BASIC execute pointer high byte
  2111                          LAB_1754
  2112  9732 20c200             	JSR	LAB_GBYT		; scan memory
  2113  9735 90c3               	BCC	LAB_174C		; if numeric do GOTO n
  2114                          					; the code will return to the interpreter loop at the
  2115                          					; tail end of the GOTO <n>
  2116                          
  2117  9737 4c1395             	JMP	LAB_15FF		; interpret BASIC code from (Bpntrl)
  2118                          					; the code will return to the interpreter loop at the
  2119                          					; tail end of the <statement>
  2120                          
  2121                          ; perform REM, skip (rest of) line
  2122                          
  2123                          LAB_REM
  2124  973a 20bc96             	JSR	LAB_SNBL		; scan for next BASIC line
  2125  973d 4cab96             	JMP	LAB_170F		; go set BASIC execute pointer and return, branch always
  2126                          
  2127                          LAB_16FD
  2128  9740 4c199c             	JMP	LAB_SNER		; do syntax error then warm start
  2129                          
  2130                          ; perform ON
  2131                          
  2132                          LAB_ON
  2133  9743 c9ae               	CMP	#TK_IRQ		; was it IRQ token ?
  2134  9745 d003               	BNE	LAB_NOIN		; if not go check NMI
  2135                          
  2136  9747 4c4faf             	JMP	LAB_SIRQ		; else go set-up IRQ
  2137                          
  2138                          LAB_NOIN
  2139  974a c9af               	CMP	#TK_NMI		; was it NMI token ?
  2140  974c d003               	BNE	LAB_NONM		; if not go do normal ON command
  2141                          
  2142  974e 4c53af             	JMP	LAB_SNMI		; else go set-up NMI
  2143                          
  2144                          LAB_NONM
  2145  9751 20a3a4             	JSR	LAB_GTBY		; get byte parameter
  2146  9754 48                 	PHA				; push GOTO/GOSUB token
  2147  9755 c98d               	CMP	#TK_GOSUB		; compare with GOSUB token
  2148  9757 f004               	BEQ	LAB_176B		; branch if GOSUB
  2149                          
  2150  9759 c989               	CMP	#TK_GOTO		; compare with GOTO token
  2151                          LAB_1767
  2152  975b d0e3               	BNE	LAB_16FD		; if not GOTO do syntax error then warm start
  2153                          
  2154                          
  2155                          ; next character was GOTO or GOSUB
  2156                          
  2157                          LAB_176B
  2158  975d c6af               	DEC	FAC1_3		; decrement index (byte value)
  2159  975f d004               	BNE	LAB_1773		; branch if not zero
  2160                          
  2161  9761 68                 	PLA				; pull GOTO/GOSUB token
  2162  9762 4c1595             	JMP	LAB_1602		; go execute it
  2163                          
  2164                          LAB_1773
  2165  9765 20bc00             	JSR	LAB_IGBY		; increment and scan memory
  2166  9768 207197             	JSR	LAB_GFPN		; get fixed-point number into temp integer (skip this n)
  2167                          					; (we could LDX #',' and JSR LAB_SNBL+2, then we
  2168                          					; just BNE LAB_176B for the loop. should be quicker ..
  2169                          					; no we can't, what if we meet a colon or [EOL]?)
  2170  976b c92c               	CMP	#$2C			; compare next character with ","
  2171  976d f0ee               	BEQ	LAB_176B		; loop if ","
  2172                          
  2173                          LAB_177E
  2174  976f 68                 	PLA				; else pull keyword token (run out of options)
  2175                          					; also dump +/-1 pointer low byte and exit
  2176                          LAB_177F
  2177  9770 60                 	RTS
  2178                          
  2179                          ; takes n * 106 + 11 cycles where n is the number of digits
  2180                          
  2181                          ; get fixed-point number into temp integer
  2182                          
  2183                          LAB_GFPN
  2184  9771 a200               	LDX	#$00			; clear reg
  2185  9773 8611               	STX	Itempl		; clear temporary integer low byte
  2186                          LAB_1785
  2187  9775 8612               	STX	Itemph		; save temporary integer high byte
  2188  9777 b0f7               	BCS	LAB_177F		; return if carry set, end of scan, character was
  2189                          					; not 0-9
  2190                          
  2191  9779 e019               	CPX	#$19			; compare high byte with $19
  2192  977b a8                 	TAY				; ensure Zb = 0 if the branch is taken
  2193  977c b0dd               	BCS	LAB_1767		; branch if >=, makes max line # 63999 because next
  2194                          					; bit does *$0A, = 64000, compare at target will fail
  2195                          					; and do syntax error
  2196                          
  2197  977e e92f               	SBC	#'0'-1		; subtract "0", $2F + carry, from byte
  2198  9780 a8                 	TAY				; copy binary digit
  2199  9781 a511               	LDA	Itempl		; get temporary integer low byte
  2200  9783 0a                 	ASL				; *2 low byte
  2201  9784 2612               	ROL	Itemph		; *2 high byte
  2202  9786 0a                 	ASL				; *2 low byte
  2203  9787 2612               	ROL	Itemph		; *2 high byte, *4
  2204  9789 6511               	ADC	Itempl		; + low byte, *5
  2205  978b 8511               	STA	Itempl		; save it
  2206  978d 8a                 	TXA				; get high byte copy to A
  2207  978e 6512               	ADC	Itemph		; + high byte, *5
  2208  9790 0611               	ASL	Itempl		; *2 low byte, *10d
  2209  9792 2a                 	ROL				; *2 high byte, *10d
  2210  9793 aa                 	TAX				; copy high byte back to X
  2211  9794 98                 	TYA				; get binary digit back
  2212  9795 6511               	ADC	Itempl		; add number low byte
  2213  9797 8511               	STA	Itempl		; save number low byte
  2214  9799 9001               	BCC	LAB_17B3		; if no overflow to high byte get next character
  2215                          
  2216  979b e8                 	INX				; else increment high byte
  2217                          LAB_17B3
  2218  979c 20bc00             	JSR	LAB_IGBY		; increment and scan memory
  2219  979f 4c7597             	JMP	LAB_1785		; loop for next character
  2220                          
  2221                          ; perform DEC
  2222                          
  2223                          LAB_DEC
  2224  97a2 a903               	LDA	#<LAB_2AFD		; set -1 pointer low byte
  2225  97a4 2c                 	!text	$2C			; BIT abs to skip the LDA below
  2226                          
  2227                          ; perform INC
  2228                          
  2229                          LAB_INC
  2230  97a5 a9ff               	LDA	#<LAB_259C		; set 1 pointer low byte
  2231                          LAB_17B5
  2232  97a7 48                 	PHA				; save +/-1 pointer low byte
  2233                          LAB_17B7
  2234  97a8 20c19d             	JSR	LAB_GVAR		; get var address
  2235  97ab a65f               	LDX	Dtypef		; get data type flag, $FF=string, $00=numeric
  2236  97ad 301e               	BMI	IncrErr		; exit if string
  2237                          
  2238  97af 8597               	STA	Lvarpl		; save var address low byte
  2239  97b1 8498               	STY	Lvarph		; save var address high byte
  2240  97b3 2094a8             	JSR	LAB_UFAC		; unpack memory (AY) into FAC1
  2241  97b6 68                 	PLA				; get +/-1 pointer low byte
  2242  97b7 48                 	PHA				; save +/-1 pointer low byte
  2243  97b8 a0b1               	LDY	#>LAB_259C		; set +/-1 pointer high byte (both the same)
  2244  97ba 20d5a5             	JSR	LAB_246C		; add (AY) to FAC1
  2245  97bd 20baa8             	JSR	LAB_PFAC		; pack FAC1 into variable (Lvarpl)
  2246                          
  2247  97c0 20c200             	JSR	LAB_GBYT		; scan memory
  2248  97c3 c92c               	CMP	#','			; compare with ","
  2249  97c5 d0a8               	BNE	LAB_177E		; exit if not "," (either end or error)
  2250                          
  2251                          					; was "," so another INCR variable to do
  2252  97c7 20bc00             	JSR	LAB_IGBY		; increment and scan memory
  2253  97ca 4ca897             	JMP	LAB_17B7		; go do next var
  2254                          
  2255                          IncrErr
  2256  97cd 4cf39a             	JMP	LAB_1ABC		; do "Type mismatch" error then warm start
  2257                          
  2258                          ; perform LET
  2259                          
  2260                          LAB_LET
  2261  97d0 20c19d             	JSR	LAB_GVAR		; get var address
  2262  97d3 8597               	STA	Lvarpl		; save var address low byte
  2263  97d5 8498               	STY	Lvarph		; save var address high byte
  2264  97d7 a9c6               	LDA	#TK_EQUAL		; get = token
  2265  97d9 20089c             	JSR	LAB_SCCA		; scan for CHR$(A), else do syntax error then warm start
  2266  97dc a55f               	LDA	Dtypef		; get data type flag, $FF=string, $00=numeric
  2267  97de 48                 	PHA				; push data type flag
  2268  97df 20f89a             	JSR	LAB_EVEX		; evaluate expression
  2269  97e2 68                 	PLA				; pop data type flag
  2270  97e3 2a                 	ROL				; set carry if type = string
  2271  97e4 20ea9a             	JSR	LAB_CKTM		; type match check, set C for string
  2272  97e7 d003               	BNE	LAB_17D5		; branch if string
  2273                          
  2274  97e9 4cbaa8             	JMP	LAB_PFAC		; pack FAC1 into variable (Lvarpl) and return
  2275                          
  2276                          ; string LET
  2277                          
  2278                          LAB_17D5
  2279  97ec a002               	LDY	#$02			; set index to pointer high byte
  2280  97ee b1ae               	LDA	(des_pl),Y		; get string pointer high byte
  2281  97f0 c582               	CMP	Sstorh		; compare bottom of string space high byte
  2282  97f2 9017               	BCC	LAB_17F4		; if less assign value and exit (was in program memory)
  2283                          
  2284  97f4 d007               	BNE	LAB_17E6		; branch if >
  2285                          					; else was equal so compare low bytes
  2286  97f6 88                 	DEY				; decrement index
  2287  97f7 b1ae               	LDA	(des_pl),Y		; get pointer low byte
  2288  97f9 c581               	CMP	Sstorl		; compare bottom of string space low byte
  2289  97fb 900e               	BCC	LAB_17F4		; if less assign value and exit (was in program memory)
  2290                          
  2291                          					; pointer was >= to bottom of string space pointer
  2292                          LAB_17E6
  2293  97fd a4af               	LDY	des_ph		; get descriptor pointer high byte
  2294  97ff c47c               	CPY	Svarh			; compare start of vars high byte
  2295  9801 9008               	BCC	LAB_17F4		; branch if less (descriptor is on stack)
  2296                          
  2297  9803 d00d               	BNE	LAB_17FB		; branch if greater (descriptor is not on stack)
  2298                          
  2299                          					; else high bytes were equal so ..
  2300  9805 a5ae               	LDA	des_pl		; get descriptor pointer low byte
  2301  9807 c57b               	CMP	Svarl			; compare start of vars low byte
  2302  9809 b007               	BCS	LAB_17FB		; branch if >= (descriptor is not on stack)
  2303                          
  2304                          LAB_17F4
  2305  980b a5ae               	LDA	des_pl		; get descriptor pointer low byte
  2306  980d a4af               	LDY	des_ph		; get descriptor pointer high byte
  2307  980f 4c2898             	JMP	LAB_1811		; clean stack, copy descriptor to variable and return
  2308                          
  2309                          					; make space and copy string
  2310                          LAB_17FB
  2311  9812 a000               	LDY	#$00			; index to length
  2312  9814 b1ae               	LDA	(des_pl),Y		; get string length
  2313  9816 2049a1             	JSR	LAB_209C		; copy string
  2314  9819 a59e               	LDA	des_2l		; get descriptor pointer low byte
  2315  981b a49f               	LDY	des_2h		; get descriptor pointer high byte
  2316  981d 85b8               	STA	ssptr_l		; save descriptor pointer low byte
  2317  981f 84b9               	STY	ssptr_h		; save descriptor pointer high byte
  2318  9821 2028a3             	JSR	LAB_228A		; copy string from descriptor (sdescr) to (Sutill)
  2319  9824 a9ac               	LDA	#<FAC1_e		; set descriptor pointer low byte
  2320  9826 a000               	LDY	#>FAC1_e		; get descriptor pointer high byte
  2321                          
  2322                          					; clean stack and assign value to string variable
  2323                          LAB_1811
  2324  9828 859e               	STA	des_2l		; save descriptor_2 pointer low byte
  2325  982a 849f               	STY	des_2h		; save descriptor_2 pointer high byte
  2326  982c 208aa3             	JSR	LAB_22EB		; clean descriptor stack, YA = pointer
  2327  982f a000               	LDY	#$00			; index to length
  2328  9831 b19e               	LDA	(des_2l),Y		; get string length
  2329  9833 9197               	STA	(Lvarpl),Y		; copy to let string variable
  2330  9835 c8                 	INY				; index to string pointer low byte
  2331  9836 b19e               	LDA	(des_2l),Y		; get string pointer low byte
  2332  9838 9197               	STA	(Lvarpl),Y		; copy to let string variable
  2333  983a c8                 	INY				; index to string pointer high byte
  2334  983b b19e               	LDA	(des_2l),Y		; get string pointer high byte
  2335  983d 9197               	STA	(Lvarpl),Y		; copy to let string variable
  2336  983f 60                 	RTS
  2337                          
  2338                          ; perform GET
  2339                          
  2340                          LAB_GET
  2341  9840 20c19d             	JSR	LAB_GVAR		; get var address
  2342  9843 8597               	STA	Lvarpl		; save var address low byte
  2343  9845 8498               	STY	Lvarph		; save var address high byte
  2344  9847 2017af             	JSR	INGET			; get input byte
  2345  984a a65f               	LDX	Dtypef		; get data type flag, $FF=string, $00=numeric
  2346  984c 3007               	BMI	LAB_GETS		; go get string character
  2347                          
  2348                          					; was numeric get
  2349  984e a8                 	TAY				; copy character to Y
  2350  984f 207da0             	JSR	LAB_1FD0		; convert Y to byte in FAC1
  2351  9852 4cbaa8             	JMP	LAB_PFAC		; pack FAC1 into variable (Lvarpl) and return
  2352                          
  2353                          LAB_GETS
  2354  9855 48                 	PHA				; save character
  2355  9856 a901               	LDA	#$01			; string is single byte
  2356  9858 b001               	BCS	LAB_IsByte		; branch if byte received
  2357                          
  2358  985a 68                 	PLA				; string is null
  2359                          LAB_IsByte
  2360  985b 2051a1             	JSR	LAB_MSSP		; make string space A bytes long A=$AC=length,
  2361                          					; X=$AD=Sutill=ptr low byte, Y=$AE=Sutilh=ptr high byte
  2362  985e f005               	BEQ	LAB_NoSt		; skip store if null string
  2363                          
  2364  9860 68                 	PLA				; get character back
  2365  9861 a000               	LDY	#$00			; clear index
  2366  9863 91ad               	STA	(str_pl),Y		; save byte in string (byte IS string!)
  2367                          LAB_NoSt
  2368  9865 209ca1             	JSR	LAB_RTST		; check for space on descriptor stack then put address
  2369                          					; and length on descriptor stack and update stack pointers
  2370                          
  2371  9868 4cec97             	JMP	LAB_17D5		; do string LET and return
  2372                          
  2373                          ; perform PRINT
  2374                          
  2375                          LAB_1829
  2376  986b 20ed98             	JSR	LAB_18C6		; print string from Sutill/Sutilh
  2377                          LAB_182C
  2378  986e 20c200             	JSR	LAB_GBYT		; scan memory
  2379                          
  2380                          ; PRINT
  2381                          
  2382                          LAB_PRINT
  2383  9871 f03b               	BEQ	LAB_CRLF		; if nothing following just print CR/LF
  2384                          
  2385                          LAB_1831
  2386  9873 c9b0               	CMP	#TK_TAB		; compare with TAB( token
  2387  9875 f051               	BEQ	LAB_18A2		; go do TAB/SPC
  2388                          
  2389  9877 c9b4               	CMP	#TK_SPC		; compare with SPC( token
  2390  9879 f04d               	BEQ	LAB_18A2		; go do TAB/SPC
  2391                          
  2392  987b c92c               	CMP	#','			; compare with ","
  2393  987d f033               	BEQ	LAB_188B		; go do move to next TAB mark
  2394                          
  2395  987f c93b               	CMP	#';'			; compare with ";"
  2396  9881 f061               	BEQ	LAB_18BD		; if ";" continue with PRINT processing
  2397                          
  2398  9883 20f89a             	JSR	LAB_EVEX		; evaluate expression
  2399  9886 245f               	BIT	Dtypef		; test data type flag, $FF=string, $00=numeric
  2400  9888 30e1               	BMI	LAB_1829		; branch if string
  2401                          
  2402  988a 20acaa             	JSR	LAB_296E		; convert FAC1 to string
  2403  988d 205ba1             	JSR	LAB_20AE		; print " terminated string to Sutill/Sutilh
  2404  9890 a000               	LDY	#$00			; clear index
  2405                          
  2406                          ; don't check fit if terminal width byte is zero
  2407                          
  2408  9892 a50f               	LDA	TWidth		; get terminal width byte
  2409  9894 f00a               	BEQ	LAB_185E		; skip check if zero
  2410                          
  2411  9896 38                 	SEC				; set carry for subtract
  2412  9897 e50e               	SBC	TPos			; subtract terminal position
  2413  9899 f1ae               	SBC	(des_pl),Y		; subtract string length
  2414  989b b003               	BCS	LAB_185E		; branch if less than terminal width
  2415                          
  2416  989d 20ae98             	JSR	LAB_CRLF		; else print CR/LF
  2417                          LAB_185E
  2418  98a0 20ed98             	JSR	LAB_18C6		; print string from Sutill/Sutilh
  2419  98a3 f0c9               	BEQ	LAB_182C		; always go continue processing line
  2420                          
  2421                          ; CR/LF return to BASIC from BASIC input handler
  2422                          
  2423                          LAB_1866
  2424  98a5 a900               	LDA	#$00			; clear byte
  2425  98a7 9d2103             	STA	Ibuffs,X		; null terminate input
  2426  98aa a221               	LDX	#<Ibuffs		; set X to buffer start-1 low byte
  2427  98ac a003               	LDY	#>Ibuffs		; set Y to buffer start-1 high byte
  2428                          
  2429                          ; print CR/LF
  2430                          
  2431                          LAB_CRLF
  2432                          	;LDA	#$0D			; load [CR]
  2433                          	;JSR	LAB_PRNA		; go print the character
  2434  98ae a90a               	LDA	#$0A			; load [LF]
  2435  98b0 d052               	BNE	LAB_PRNA		; go print the character and return, branch always
  2436                          
  2437                          LAB_188B
  2438  98b2 a50e               	LDA	TPos			; get terminal position
  2439  98b4 c510               	CMP	Iclim			; compare with input column limit
  2440  98b6 9005               	BCC	LAB_1897		; branch if less
  2441                          
  2442  98b8 20ae98             	JSR	LAB_CRLF		; else print CR/LF (next line)
  2443  98bb d027               	BNE	LAB_18BD		; continue with PRINT processing (branch always)
  2444                          
  2445                          LAB_1897
  2446  98bd 38                 	SEC				; set carry for subtract
  2447                          LAB_1898
  2448  98be e564               	SBC	TabSiz		; subtract TAB size
  2449  98c0 b0fc               	BCS	LAB_1898		; loop if result was +ve
  2450                          
  2451  98c2 49ff               	EOR	#$FF			; complement it
  2452  98c4 6901               	ADC	#$01			; +1 (twos complement)
  2453  98c6 d012               	BNE	LAB_18B6		; always print A spaces (result is never $00)
  2454                          
  2455                          					; do TAB/SPC
  2456                          LAB_18A2
  2457  98c8 48                 	PHA				; save token
  2458  98c9 20a0a4             	JSR	LAB_SGBY		; scan and get byte parameter
  2459  98cc c929               	CMP	#$29			; is next character )
  2460  98ce d07b               	BNE	LAB_1910		; if not do syntax error then warm start
  2461                          
  2462  98d0 68                 	PLA				; get token back
  2463  98d1 c9b0               	CMP	#TK_TAB		; was it TAB ?
  2464  98d3 d006               	BNE	LAB_18B7		; if not go do SPC
  2465                          
  2466                          					; calculate TAB offset
  2467  98d5 8a                 	TXA				; copy integer value to A
  2468  98d6 e50e               	SBC	TPos			; subtract terminal position
  2469  98d8 900a               	BCC	LAB_18BD		; branch if result was < 0 (can't TAB backwards)
  2470                          
  2471                          					; print A spaces
  2472                          LAB_18B6
  2473  98da aa                 	TAX				; copy result to X
  2474                          LAB_18B7
  2475  98db 8a                 	TXA				; set flags on size for SPC
  2476  98dc f006               	BEQ	LAB_18BD		; branch if result was = $0, already here
  2477                          
  2478                          					; print X spaces
  2479                          LAB_18BA
  2480  98de 20ff98             	JSR	LAB_18E0		; print " "
  2481  98e1 ca                 	DEX				; decrement count
  2482  98e2 d0fa               	BNE	LAB_18BA		; loop if not all done
  2483                          
  2484                          					; continue with PRINT processing
  2485                          LAB_18BD
  2486  98e4 20bc00             	JSR	LAB_IGBY		; increment and scan memory
  2487  98e7 d08a               	BNE	LAB_1831		; if more to print go do it
  2488                          
  2489  98e9 60                 	RTS
  2490                          
  2491                          ; print null terminated string from memory
  2492                          
  2493                          LAB_18C3
  2494  98ea 205ba1             	JSR	LAB_20AE		; print " terminated string to Sutill/Sutilh
  2495                          
  2496                          ; print string from Sutill/Sutilh
  2497                          
  2498                          LAB_18C6
  2499  98ed 2055a3             	JSR	LAB_22B6		; pop string off descriptor stack, or from top of string
  2500                          					; space returns with A = length, X=$71=pointer low byte,
  2501                          					; Y=$72=pointer high byte
  2502  98f0 a000               	LDY	#$00			; reset index
  2503  98f2 aa                 	TAX				; copy length to X
  2504  98f3 f049               	BEQ	LAB_188C		; exit (RTS) if null string
  2505                          
  2506                          LAB_18CD
  2507                          
  2508  98f5 b171               	LDA	(ut1_pl),Y		; get next byte
  2509  98f7 200499             	JSR	LAB_PRNA		; go print the character
  2510  98fa c8                 	INY				; increment index
  2511  98fb ca                 	DEX				; decrement count
  2512  98fc d0f7               	BNE	LAB_18CD		; loop if not done yet
  2513                          
  2514  98fe 60                 	RTS
  2515                          
  2516                          					; Print single format character
  2517                          ; print " "
  2518                          
  2519                          LAB_18E0
  2520  98ff a920               	LDA	#$20			; load " "
  2521  9901 2c                 	!text	$2C			; change next line to BIT LAB_3FA9
  2522                          
  2523                          ; print "?" character
  2524                          
  2525                          LAB_18E3
  2526  9902 a93f               	LDA	#$3F			; load "?" character
  2527                          
  2528                          ; print character in A
  2529                          ; now includes the null handler
  2530                          ; also includes infinite line length code
  2531                          ; note! some routines expect this one to exit with Zb=0
  2532                          
  2533                          LAB_PRNA
  2534  9904 c920               	CMP	#' '			; compare with " "
  2535  9906 9019               	BCC	LAB_18F9		; branch if less (non printing)
  2536                          
  2537                          					; else printable character
  2538  9908 48                 	PHA				; save the character
  2539                          
  2540                          ; don't check fit if terminal width byte is zero
  2541                          
  2542  9909 a50f               	LDA	TWidth		; get terminal width
  2543  990b d00a               	BNE	LAB_18F0		; branch if not zero (not infinite length)
  2544                          
  2545                          ; is "infinite line" so check TAB position
  2546                          
  2547  990d a50e               	LDA	TPos			; get position
  2548  990f e564               	SBC	TabSiz		; subtract TAB size, carry set by CMP #$20 above
  2549  9911 d00b               	BNE	LAB_18F7		; skip reset if different
  2550                          
  2551  9913 850e               	STA	TPos			; else reset position
  2552  9915 f007               	BEQ	LAB_18F7		; go print character
  2553                          
  2554                          LAB_18F0
  2555  9917 c50e               	CMP	TPos			; compare with terminal character position
  2556  9919 d003               	BNE	LAB_18F7		; branch if not at end of line
  2557                          
  2558  991b 20ae98             	JSR	LAB_CRLF		; else print CR/LF
  2559                          LAB_18F7
  2560  991e e60e               	INC	TPos			; increment terminal position
  2561  9920 68                 	PLA				; get character back
  2562                          LAB_18F9
  2563  9921 200cb1             	JSR	V_OUTP		; output byte via output vector
  2564  9924 c90d               	CMP	#$0D			; compare with [CR]
  2565  9926 d014               	BNE	LAB_188A		; branch if not [CR]
  2566                          
  2567                          					; else print nullct nulls after the [CR]
  2568  9928 8678               	STX	TempB			; save buffer index
  2569  992a a60d               	LDX	Nullct		; get null count
  2570  992c f00a               	BEQ	LAB_1886		; branch if no nulls
  2571                          
  2572  992e a900               	LDA	#$00			; load [NULL]
  2573                          LAB_1880
  2574  9930 200499             	JSR	LAB_PRNA		; go print the character
  2575  9933 ca                 	DEX				; decrement count
  2576  9934 d0fa               	BNE	LAB_1880		; loop if not all done
  2577                          
  2578  9936 a90d               	LDA	#$0D			; restore the character (and set the flags)
  2579                          LAB_1886
  2580  9938 860e               	STX	TPos			; clear terminal position (X always = zero when we get here)
  2581  993a a678               	LDX	TempB			; restore buffer index
  2582                          LAB_188A
  2583  993c 29ff               	AND	#$FF			; set the flags
  2584                          LAB_188C
  2585  993e 60                 	RTS
  2586                          
  2587                          ; handle bad input data
  2588                          
  2589                          LAB_1904
  2590  993f a562               	LDA	Imode			; get input mode flag, $00=INPUT, $00=READ
  2591  9941 100b               	BPL	LAB_1913		; branch if INPUT (go do redo)
  2592                          
  2593  9943 a58d               	LDA	Dlinel		; get current DATA line low byte
  2594  9945 a48e               	LDY	Dlineh		; get current DATA line high byte
  2595  9947 8587               	STA	Clinel		; save current line low byte
  2596  9949 8488               	STY	Clineh		; save current line high byte
  2597                          LAB_1910
  2598  994b 4c199c             	JMP	LAB_SNER		; do syntax error then warm start
  2599                          
  2600                          					; mode was INPUT
  2601                          LAB_1913
  2602  994e a97b               	LDA	#<LAB_REDO		; point to redo message (low addr)
  2603  9950 a0b8               	LDY	#>LAB_REDO		; point to redo message (high addr)
  2604  9952 20ea98             	JSR	LAB_18C3		; print null terminated string from memory
  2605  9955 a58b               	LDA	Cpntrl		; get continue pointer low byte
  2606  9957 a48c               	LDY	Cpntrh		; get continue pointer high byte
  2607  9959 85c3               	STA	Bpntrl		; save BASIC execute pointer low byte
  2608  995b 84c4               	STY	Bpntrh		; save BASIC execute pointer high byte
  2609  995d 60                 	RTS
  2610                          
  2611                          ; perform INPUT
  2612                          
  2613                          LAB_INPUT
  2614  995e c922               	CMP	#$22			; compare next byte with open quote
  2615  9960 d00b               	BNE	LAB_1934		; branch if no prompt string
  2616                          
  2617  9962 20d59b             	JSR	LAB_1BC1		; print "..." string
  2618  9965 a93b               	LDA	#$3B			; load A with ";"
  2619  9967 20089c             	JSR	LAB_SCCA		; scan for CHR$(A), else do syntax error then warm start
  2620  996a 20ed98             	JSR	LAB_18C6		; print string from Sutill/Sutilh
  2621                          
  2622                          					; done with prompt, now get data
  2623                          LAB_1934
  2624  996d 2081a0             	JSR	LAB_CKRN		; check not Direct, back here if ok
  2625  9970 204b92             	JSR	LAB_INLN		; print "? " and get BASIC input
  2626  9973 a900               	LDA	#$00			; set mode = INPUT
  2627  9975 cd2103             	CMP	Ibuffs		; test first byte in buffer
  2628  9978 d00a               	BNE	LAB_1953		; branch if not null input
  2629                          
  2630  997a 18                 	CLC				; was null input so clear carry to exit program
  2631  997b 4c4395             	JMP	LAB_1647		; go do BREAK exit
  2632                          
  2633                          ; perform READ
  2634                          
  2635                          LAB_READ
  2636  997e a68f               	LDX	Dptrl			; get DATA pointer low byte
  2637  9980 a490               	LDY	Dptrh			; get DATA pointer high byte
  2638  9982 a980               	LDA	#$80			; set mode = READ
  2639                          
  2640                          LAB_1953
  2641  9984 8562               	STA	Imode			; set input mode flag, $00=INPUT, $80=READ
  2642  9986 8691               	STX	Rdptrl		; save READ pointer low byte
  2643  9988 8492               	STY	Rdptrh		; save READ pointer high byte
  2644                          
  2645                          					; READ or INPUT next variable from list
  2646                          LAB_195B
  2647  998a 20c19d             	JSR	LAB_GVAR		; get (var) address
  2648  998d 8597               	STA	Lvarpl		; save address low byte
  2649  998f 8498               	STY	Lvarph		; save address high byte
  2650  9991 a5c3               	LDA	Bpntrl		; get BASIC execute pointer low byte
  2651  9993 a4c4               	LDY	Bpntrh		; get BASIC execute pointer high byte
  2652  9995 8511               	STA	Itempl		; save as temporary integer low byte
  2653  9997 8412               	STY	Itemph		; save as temporary integer high byte
  2654  9999 a691               	LDX	Rdptrl		; get READ pointer low byte
  2655  999b a492               	LDY	Rdptrh		; get READ pointer high byte
  2656  999d 86c3               	STX	Bpntrl		; set BASIC execute pointer low byte
  2657  999f 84c4               	STY	Bpntrh		; set BASIC execute pointer high byte
  2658  99a1 20c200             	JSR	LAB_GBYT		; scan memory
  2659  99a4 d011               	BNE	LAB_1988		; branch if not null
  2660                          
  2661                          					; pointer was to null entry
  2662  99a6 2462               	BIT	Imode			; test input mode flag, $00=INPUT, $80=READ
  2663  99a8 3065               	BMI	LAB_19DD		; branch if READ
  2664                          
  2665                          					; mode was INPUT
  2666  99aa 200299             	JSR	LAB_18E3		; print "?" character (double ? for extended input)
  2667  99ad 204b92             	JSR	LAB_INLN		; print "? " and get BASIC input
  2668  99b0 86c3               	STX	Bpntrl		; set BASIC execute pointer low byte
  2669  99b2 84c4               	STY	Bpntrh		; set BASIC execute pointer high byte
  2670                          LAB_1985
  2671  99b4 20c200             	JSR	LAB_GBYT		; scan memory
  2672                          LAB_1988
  2673  99b7 245f               	BIT	Dtypef		; test data type flag, $FF=string, $00=numeric
  2674  99b9 1024               	BPL	LAB_19B0		; branch if numeric
  2675                          
  2676                          					; else get string
  2677  99bb 855b               	STA	Srchc			; save search character
  2678  99bd c922               	CMP	#$22			; was it " ?
  2679  99bf f007               	BEQ	LAB_1999		; branch if so
  2680                          
  2681  99c1 a93a               	LDA	#':'			; else search character is ":"
  2682  99c3 855b               	STA	Srchc			; set new search character
  2683  99c5 a92c               	LDA	#','			; other search character is ","
  2684  99c7 18                 	CLC				; clear carry for add
  2685                          LAB_1999
  2686  99c8 855c               	STA	Asrch			; set second search character
  2687  99ca a5c3               	LDA	Bpntrl		; get BASIC execute pointer low byte
  2688  99cc a4c4               	LDY	Bpntrh		; get BASIC execute pointer high byte
  2689                          
  2690  99ce 6900               	ADC	#$00			; c is =1 if we came via the BEQ LAB_1999, else =0
  2691  99d0 9001               	BCC	LAB_19A4		; branch if no execute pointer low byte rollover
  2692                          
  2693  99d2 c8                 	INY				; else increment high byte
  2694                          LAB_19A4
  2695  99d3 2061a1             	JSR	LAB_20B4		; print Srchc or Asrch terminated string to Sutill/Sutilh
  2696  99d6 20e6a4             	JSR	LAB_23F3		; restore BASIC execute pointer from temp (Btmpl/Btmph)
  2697  99d9 20ec97             	JSR	LAB_17D5		; go do string LET
  2698  99dc 4ce599             	JMP	LAB_19B6		; go check string terminator
  2699                          
  2700                          					; get numeric INPUT
  2701                          LAB_19B0
  2702  99df 20bda9             	JSR	LAB_2887		; get FAC1 from string
  2703  99e2 20baa8             	JSR	LAB_PFAC		; pack FAC1 into (Lvarpl)
  2704                          LAB_19B6
  2705  99e5 20c200             	JSR	LAB_GBYT		; scan memory
  2706  99e8 f00a               	BEQ	LAB_19C5		; branch if null (last entry)
  2707                          
  2708  99ea c92c               	CMP	#','			; else compare with ","
  2709  99ec f003               	BEQ	LAB_19C2		; branch if ","
  2710                          
  2711  99ee 4c3f99             	JMP	LAB_1904		; else go handle bad input data
  2712                          
  2713                          					; got good input data
  2714                          LAB_19C2
  2715  99f1 20bc00             	JSR	LAB_IGBY		; increment and scan memory
  2716                          LAB_19C5
  2717  99f4 a5c3               	LDA	Bpntrl		; get BASIC execute pointer low byte (temp READ/INPUT ptr)
  2718  99f6 a4c4               	LDY	Bpntrh		; get BASIC execute pointer high byte (temp READ/INPUT ptr)
  2719  99f8 8591               	STA	Rdptrl		; save for now
  2720  99fa 8492               	STY	Rdptrh		; save for now
  2721  99fc a511               	LDA	Itempl		; get temporary integer low byte (temp BASIC execute ptr)
  2722  99fe a412               	LDY	Itemph		; get temporary integer high byte (temp BASIC execute ptr)
  2723  9a00 85c3               	STA	Bpntrl		; set BASIC execute pointer low byte
  2724  9a02 84c4               	STY	Bpntrh		; set BASIC execute pointer high byte
  2725  9a04 20c200             	JSR	LAB_GBYT		; scan memory
  2726  9a07 f02c               	BEQ	LAB_1A03		; if null go do extra ignored message
  2727                          
  2728  9a09 20159c             	JSR	LAB_1C01		; else scan for "," , else do syntax error then warm start
  2729  9a0c 4c8a99             	JMP	LAB_195B		; go INPUT next variable from list
  2730                          
  2731                          					; find next DATA statement or do "Out of DATA" error
  2732                          LAB_19DD
  2733  9a0f 20b996             	JSR	LAB_SNBS		; scan for next BASIC statement ([:] or [EOL])
  2734  9a12 c8                 	INY				; increment index
  2735  9a13 aa                 	TAX				; copy character ([:] or [EOL])
  2736  9a14 d012               	BNE	LAB_19F6		; branch if [:]
  2737                          
  2738  9a16 a206               	LDX	#$06			; set for "Out of DATA" error
  2739  9a18 c8                 	INY				; increment index, now points to next line pointer high byte
  2740  9a19 b1c3               	LDA	(Bpntrl),Y		; get next line pointer high byte
  2741  9a1b f073               	BEQ	LAB_1A54		; branch if end (eventually does error X)
  2742                          
  2743  9a1d c8                 	INY				; increment index
  2744  9a1e b1c3               	LDA	(Bpntrl),Y		; get next line # low byte
  2745  9a20 858d               	STA	Dlinel		; save current DATA line low byte
  2746  9a22 c8                 	INY				; increment index
  2747  9a23 b1c3               	LDA	(Bpntrl),Y		; get next line # high byte
  2748  9a25 c8                 	INY				; increment index
  2749  9a26 858e               	STA	Dlineh		; save current DATA line high byte
  2750                          LAB_19F6
  2751  9a28 b1c3               	LDA	(Bpntrl),Y		; get byte
  2752  9a2a c8                 	INY				; increment index
  2753  9a2b aa                 	TAX				; copy to X
  2754  9a2c 20ab96             	JSR	LAB_170F		; set BASIC execute pointer
  2755  9a2f e083               	CPX	#TK_DATA		; compare with "DATA" token
  2756  9a31 f081               	BEQ	LAB_1985		; was "DATA" so go do next READ
  2757                          
  2758  9a33 d0da               	BNE	LAB_19DD		; go find next statement if not "DATA"
  2759                          
  2760                          ; end of INPUT/READ routine
  2761                          
  2762                          LAB_1A03
  2763  9a35 a591               	LDA	Rdptrl		; get temp READ pointer low byte
  2764  9a37 a492               	LDY	Rdptrh		; get temp READ pointer high byte
  2765  9a39 a662               	LDX	Imode			; get input mode flag, $00=INPUT, $80=READ
  2766  9a3b 1003               	BPL	LAB_1A0E		; branch if INPUT
  2767                          
  2768  9a3d 4c6a95             	JMP	LAB_1624		; save AY as DATA pointer and return
  2769                          
  2770                          					; we were getting INPUT
  2771                          LAB_1A0E
  2772  9a40 a000               	LDY	#$00			; clear index
  2773  9a42 b191               	LDA	(Rdptrl),Y		; get next byte
  2774  9a44 d001               	BNE	LAB_1A1B		; error if not end of INPUT
  2775                          
  2776  9a46 60                 	RTS
  2777                          
  2778                          					; user typed too much
  2779                          LAB_1A1B
  2780  9a47 a96a               	LDA	#<LAB_IMSG		; point to extra ignored message (low addr)
  2781  9a49 a0b8               	LDY	#>LAB_IMSG		; point to extra ignored message (high addr)
  2782  9a4b 4cea98             	JMP	LAB_18C3		; print null terminated string from memory and return
  2783                          
  2784                          ; search the stack for FOR activity
  2785                          ; exit with z=1 if FOR else exit with z=0
  2786                          
  2787                          LAB_11A1
  2788  9a4e ba                 	TSX				; copy stack pointer
  2789  9a4f e8                 	INX				; +1 pass return address
  2790  9a50 e8                 	INX				; +2 pass return address
  2791  9a51 e8                 	INX				; +3 pass calling routine return address
  2792  9a52 e8                 	INX				; +4 pass calling routine return address
  2793                          LAB_11A6
  2794  9a53 bd0101             	LDA	LAB_STAK+1,X	; get token byte from stack
  2795  9a56 c981               	CMP	#TK_FOR		; is it FOR token
  2796  9a58 d021               	BNE	LAB_11CE		; exit if not FOR token
  2797                          
  2798                          					; was FOR token
  2799  9a5a a598               	LDA	Frnxth		; get var pointer for FOR/NEXT high byte
  2800  9a5c d00a               	BNE	LAB_11BB		; branch if not null
  2801                          
  2802  9a5e bd0201             	LDA	LAB_STAK+2,X	; get FOR variable pointer low byte
  2803  9a61 8597               	STA	Frnxtl		; save var pointer for FOR/NEXT low byte
  2804  9a63 bd0301             	LDA	LAB_STAK+3,X	; get FOR variable pointer high byte
  2805  9a66 8598               	STA	Frnxth		; save var pointer for FOR/NEXT high byte
  2806                          LAB_11BB
  2807  9a68 dd0301             	CMP	LAB_STAK+3,X	; compare var pointer with stacked var pointer (high byte)
  2808  9a6b d007               	BNE	LAB_11C7		; branch if no match
  2809                          
  2810  9a6d a597               	LDA	Frnxtl		; get var pointer for FOR/NEXT low byte
  2811  9a6f dd0201             	CMP	LAB_STAK+2,X	; compare var pointer with stacked var pointer (low byte)
  2812  9a72 f007               	BEQ	LAB_11CE		; exit if match found
  2813                          
  2814                          LAB_11C7
  2815  9a74 8a                 	TXA				; copy index
  2816  9a75 18                 	CLC				; clear carry for add
  2817  9a76 6910               	ADC	#$10			; add FOR stack use size
  2818  9a78 aa                 	TAX				; copy back to index
  2819  9a79 d0d8               	BNE	LAB_11A6		; loop if not at start of stack
  2820                          
  2821                          LAB_11CE
  2822  9a7b 60                 	RTS
  2823                          
  2824                          ; perform NEXT
  2825                          
  2826                          LAB_NEXT
  2827  9a7c d004               	BNE	LAB_1A46		; branch if NEXT var
  2828                          
  2829  9a7e a000               	LDY	#$00			; else clear Y
  2830  9a80 f003               	BEQ	LAB_1A49		; branch always (no variable to search for)
  2831                          
  2832                          ; NEXT var
  2833                          
  2834                          LAB_1A46
  2835  9a82 20c19d             	JSR	LAB_GVAR		; get variable address
  2836                          LAB_1A49
  2837  9a85 8597               	STA	Frnxtl		; store variable pointer low byte
  2838  9a87 8498               	STY	Frnxth		; store variable pointer high byte
  2839                          					; (both cleared if no variable defined)
  2840  9a89 204e9a             	JSR	LAB_11A1		; search the stack for FOR activity
  2841  9a8c f004               	BEQ	LAB_1A56		; branch if found
  2842                          
  2843  9a8e a200               	LDX	#$00			; else set error $00 ("NEXT without FOR" error)
  2844                          LAB_1A54
  2845  9a90 f063               	BEQ	LAB_1ABE		; do error #X, then warm start
  2846                          
  2847                          LAB_1A56
  2848  9a92 9a                 	TXS				; set stack pointer, X set by search, dumps return addresses
  2849                          
  2850  9a93 8a                 	TXA				; copy stack pointer
  2851  9a94 38                 	SEC				; set carry for subtract
  2852  9a95 e9f7               	SBC	#$F7			; point to TO var
  2853  9a97 8573               	STA	ut2_pl		; save pointer to TO var for compare
  2854  9a99 69fb               	ADC	#$FB			; point to STEP var
  2855                          
  2856  9a9b a001               	LDY	#>LAB_STAK		; point to stack page high byte
  2857  9a9d 2094a8             	JSR	LAB_UFAC		; unpack memory (STEP value) into FAC1
  2858  9aa0 ba                 	TSX				; get stack pointer back
  2859  9aa1 bd0801             	LDA	LAB_STAK+8,X	; get step sign
  2860  9aa4 85b0               	STA	FAC1_s		; save FAC1 sign (b7)
  2861  9aa6 a597               	LDA	Frnxtl		; get FOR variable pointer low byte
  2862  9aa8 a498               	LDY	Frnxth		; get FOR variable pointer high byte
  2863  9aaa 20d5a5             	JSR	LAB_246C		; add (FOR variable) to FAC1
  2864  9aad 20baa8             	JSR	LAB_PFAC		; pack FAC1 into (FOR variable)
  2865  9ab0 a001               	LDY	#>LAB_STAK		; point to stack page high byte
  2866  9ab2 2030a9             	JSR	LAB_27FA		; compare FAC1 with (Y,ut2_pl) (TO value)
  2867  9ab5 ba                 	TSX				; get stack pointer back
  2868  9ab6 dd0801             	CMP	LAB_STAK+8,X	; compare step sign
  2869  9ab9 f017               	BEQ	LAB_1A9B		; branch if = (loop complete)
  2870                          
  2871                          					; loop back and do it all again
  2872  9abb bd0d01             	LDA	LAB_STAK+$0D,X	; get FOR line low byte
  2873  9abe 8587               	STA	Clinel		; save current line low byte
  2874  9ac0 bd0e01             	LDA	LAB_STAK+$0E,X	; get FOR line high byte
  2875  9ac3 8588               	STA	Clineh		; save current line high byte
  2876  9ac5 bd1001             	LDA	LAB_STAK+$10,X	; get BASIC execute pointer low byte
  2877  9ac8 85c3               	STA	Bpntrl		; save BASIC execute pointer low byte
  2878  9aca bd0f01             	LDA	LAB_STAK+$0F,X	; get BASIC execute pointer high byte
  2879  9acd 85c4               	STA	Bpntrh		; save BASIC execute pointer high byte
  2880                          LAB_1A98
  2881  9acf 4cd394             	JMP	LAB_15C2		; go do interpreter inner loop
  2882                          
  2883                          					; loop complete so carry on
  2884                          LAB_1A9B
  2885  9ad2 8a                 	TXA				; stack copy to A
  2886  9ad3 690f               	ADC	#$0F			; add $10 ($0F+carry) to dump FOR structure
  2887  9ad5 aa                 	TAX				; copy back to index
  2888  9ad6 9a                 	TXS				; copy to stack pointer
  2889  9ad7 20c200             	JSR	LAB_GBYT		; scan memory
  2890  9ada c92c               	CMP	#','			; compare with ","
  2891  9adc d0f1               	BNE	LAB_1A98		; branch if not "," (go do interpreter inner loop)
  2892                          
  2893                          					; was "," so another NEXT variable to do
  2894  9ade 20bc00             	JSR	LAB_IGBY		; else increment and scan memory
  2895  9ae1 20829a             	JSR	LAB_1A46		; do NEXT (var)
  2896                          
  2897                          ; evaluate expression and check is numeric, else do type mismatch
  2898                          
  2899                          LAB_EVNM
  2900  9ae4 20f89a             	JSR	LAB_EVEX		; evaluate expression
  2901                          
  2902                          ; check if source is numeric, else do type mismatch
  2903                          
  2904                          LAB_CTNM
  2905  9ae7 18                 	CLC				; destination is numeric
  2906  9ae8 24                 	!text	$24			; makes next line BIT $38
  2907                          
  2908                          ; check if source is string, else do type mismatch
  2909                          
  2910                          LAB_CTST
  2911  9ae9 38                 	SEC				; required type is string
  2912                          
  2913                          ; type match check, set C for string, clear C for numeric
  2914                          
  2915                          LAB_CKTM
  2916  9aea 245f               	BIT	Dtypef		; test data type flag, $FF=string, $00=numeric
  2917  9aec 3003               	BMI	LAB_1ABA		; branch if data type is string
  2918                          
  2919                          					; else data type was numeric
  2920  9aee b003               	BCS	LAB_1ABC		; if required type is string do type mismatch error
  2921                          LAB_1AB9
  2922  9af0 60                 	RTS
  2923                          
  2924                          					; data type was string, now check required type
  2925                          LAB_1ABA
  2926  9af1 b0fd               	BCS	LAB_1AB9		; exit if required type is string
  2927                          
  2928                          					; else do type mismatch error
  2929                          LAB_1ABC
  2930  9af3 a218               	LDX	#$18			; error code $18 ("Type mismatch" error)
  2931                          LAB_1ABE
  2932  9af5 4c4791             	JMP	LAB_XERR		; do error #X, then warm start
  2933                          
  2934                          ; evaluate expression
  2935                          
  2936                          LAB_EVEX
  2937  9af8 a6c3               	LDX	Bpntrl		; get BASIC execute pointer low byte
  2938  9afa d002               	BNE	LAB_1AC7		; skip next if not zero
  2939                          
  2940  9afc c6c4               	DEC	Bpntrh		; else decrement BASIC execute pointer high byte
  2941                          LAB_1AC7
  2942  9afe c6c3               	DEC	Bpntrl		; decrement BASIC execute pointer low byte
  2943                          
  2944                          LAB_EVEZ
  2945  9b00 a900               	LDA	#$00			; set null precedence (flag done)
  2946                          LAB_1ACC
  2947  9b02 48                 	PHA				; push precedence byte
  2948  9b03 a902               	LDA	#$02			; 2 bytes
  2949  9b05 200e91             	JSR	LAB_1212		; check room on stack for A bytes
  2950  9b08 20e49b             	JSR	LAB_GVAL		; get value from line
  2951  9b0b a900               	LDA	#$00			; clear A
  2952  9b0d 859b               	STA	comp_f		; clear compare function flag
  2953                          LAB_1ADB
  2954  9b0f 20c200             	JSR	LAB_GBYT		; scan memory
  2955                          LAB_1ADE
  2956  9b12 38                 	SEC				; set carry for subtract
  2957  9b13 e9c5               	SBC	#TK_GT		; subtract token for > (lowest comparison function)
  2958  9b15 9017               	BCC	LAB_1AFA		; branch if < TK_GT
  2959                          
  2960  9b17 c903               	CMP	#$03			; compare with ">" to "<" tokens
  2961  9b19 b013               	BCS	LAB_1AFA		; branch if >= TK_SGN (highest evaluation function +1)
  2962                          
  2963                          					; was token for > = or < (A = 0, 1 or 2)
  2964  9b1b c901               	CMP	#$01			; compare with token for =
  2965  9b1d 2a                 	ROL				; *2, b0 = carry (=1 if token was = or <)
  2966                          					; (A = 0, 3 or 5)
  2967  9b1e 4901               	EOR	#$01			; toggle b0
  2968                          					; (A = 1, 2 or 4. 1 if >, 2 if =, 4 if <)
  2969  9b20 459b               	EOR	comp_f		; EOR with compare function flag bits
  2970  9b22 c59b               	CMP	comp_f		; compare with compare function flag
  2971  9b24 9067               	BCC	LAB_1B53		; if <(comp_f) do syntax error then warm start
  2972                          					; was more than one <, = or >)
  2973                          
  2974  9b26 859b               	STA	comp_f		; save new compare function flag
  2975  9b28 20bc00             	JSR	LAB_IGBY		; increment and scan memory
  2976  9b2b 4c129b             	JMP	LAB_1ADE		; go do next character
  2977                          
  2978                          					; token is < ">" or > "<" tokens
  2979                          LAB_1AFA
  2980  9b2e a69b               	LDX	comp_f		; get compare function flag
  2981  9b30 d02c               	BNE	LAB_1B2A		; branch if compare function
  2982                          
  2983  9b32 b079               	BCS	LAB_1B78		; go do functions
  2984                          
  2985                          					; else was <  TK_GT so is operator or lower
  2986  9b34 690a               	ADC	#TK_GT-TK_PLUS	; add # of operators (+, -, *, /, ^, AND, OR or EOR)
  2987  9b36 9075               	BCC	LAB_1B78		; branch if < + operator
  2988                          
  2989                          					; carry was set so token was +, -, *, /, ^, AND, OR or EOR
  2990  9b38 d007               	BNE	LAB_1B0B		; branch if not + token
  2991                          
  2992  9b3a 245f               	BIT	Dtypef		; test data type flag, $FF=string, $00=numeric
  2993  9b3c 1003               	BPL	LAB_1B0B		; branch if not string
  2994                          
  2995                          					; will only be $00 if type is string and token was +
  2996  9b3e 4ceba2             	JMP	LAB_224D		; add strings, string 1 is in descriptor des_pl, string 2
  2997                          					; is in line, and return
  2998                          
  2999                          LAB_1B0B
  3000  9b41 8571               	STA	ut1_pl		; save it
  3001  9b43 0a                 	ASL				; *2
  3002  9b44 6571               	ADC	ut1_pl		; *3
  3003  9b46 a8                 	TAY				; copy to index
  3004                          LAB_1B13
  3005  9b47 68                 	PLA				; pull previous precedence
  3006  9b48 d912b3             	CMP	LAB_OPPT,Y		; compare with precedence byte
  3007  9b4b b065               	BCS	LAB_1B7D		; branch if A >=
  3008                          
  3009  9b4d 20e79a             	JSR	LAB_CTNM		; check if source is numeric, else do type mismatch
  3010                          LAB_1B1C
  3011  9b50 48                 	PHA				; save precedence
  3012                          LAB_1B1D
  3013  9b51 20799b             	JSR	LAB_1B43		; get vector, execute function then continue evaluation
  3014  9b54 68                 	PLA				; restore precedence
  3015  9b55 a499               	LDY	prstk			; get precedence stacked flag
  3016  9b57 1019               	BPL	LAB_1B3C		; branch if stacked values
  3017                          
  3018  9b59 aa                 	TAX				; copy precedence (set flags)
  3019  9b5a f076               	BEQ	LAB_1B9D		; exit if done
  3020                          
  3021  9b5c d05d               	BNE	LAB_1B86		; else pop FAC2 and return, branch always
  3022                          
  3023                          LAB_1B2A
  3024  9b5e 265f               	ROL	Dtypef		; shift data type flag into Cb
  3025  9b60 8a                 	TXA				; copy compare function flag
  3026  9b61 855f               	STA	Dtypef		; clear data type flag, X is 0xxx xxxx
  3027  9b63 2a                 	ROL				; shift data type into compare function byte b0
  3028  9b64 a6c3               	LDX	Bpntrl		; get BASIC execute pointer low byte
  3029  9b66 d002               	BNE	LAB_1B34		; branch if no underflow
  3030                          
  3031  9b68 c6c4               	DEC	Bpntrh		; else decrement BASIC execute pointer high byte
  3032                          LAB_1B34
  3033  9b6a c6c3               	DEC	Bpntrl		; decrement BASIC execute pointer low byte
  3034                          TK_LT_PLUS	= TK_LT-TK_PLUS
  3035  9b6c a024               	LDY	#TK_LT_PLUS*3	; set offset to last operator entry
  3036  9b6e 859b               	STA	comp_f		; save new compare function flag
  3037  9b70 d0d5               	BNE	LAB_1B13		; branch always
  3038                          
  3039                          LAB_1B3C
  3040  9b72 d912b3             	CMP	LAB_OPPT,Y		;.compare with stacked function precedence
  3041  9b75 b044               	BCS	LAB_1B86		; branch if A >=, pop FAC2 and return
  3042                          
  3043  9b77 90d7               	BCC	LAB_1B1C		; branch always
  3044                          
  3045                          ;.get vector, execute function then continue evaluation
  3046                          
  3047                          LAB_1B43
  3048  9b79 b914b3             	LDA	LAB_OPPT+2,Y	; get function vector high byte
  3049  9b7c 48                 	PHA				; onto stack
  3050  9b7d b913b3             	LDA	LAB_OPPT+1,Y	; get function vector low byte
  3051  9b80 48                 	PHA				; onto stack
  3052                          					; now push sign, round FAC1 and put on stack
  3053  9b81 20909b             	JSR	LAB_1B5B		; function will return here, then the next RTS will call
  3054                          					; the function
  3055  9b84 a59b               	LDA	comp_f		; get compare function flag
  3056  9b86 48                 	PHA				; push compare evaluation byte
  3057  9b87 b912b3             	LDA	LAB_OPPT,Y		; get precedence byte
  3058  9b8a 4c029b             	JMP	LAB_1ACC		; continue evaluating expression
  3059                          
  3060                          LAB_1B53
  3061  9b8d 4c199c             	JMP	LAB_SNER		; do syntax error then warm start
  3062                          
  3063                          ; push sign, round FAC1 and put on stack
  3064                          
  3065                          LAB_1B5B
  3066  9b90 68                 	PLA				; get return addr low byte
  3067  9b91 8571               	STA	ut1_pl		; save it
  3068  9b93 e671               	INC	ut1_pl		; increment it (was ret-1 pushed? yes!)
  3069                          					; note! no check is made on the high byte! if the calling
  3070                          					; routine assembles to a page edge then this all goes
  3071                          					; horribly wrong !!!
  3072  9b95 68                 	PLA				; get return addr high byte
  3073  9b96 8572               	STA	ut1_ph		; save it
  3074  9b98 a5b0               	LDA	FAC1_s		; get FAC1 sign (b7)
  3075  9b9a 48                 	PHA				; push sign
  3076                          
  3077                          ; round FAC1 and put on stack
  3078                          
  3079                          LAB_1B66
  3080  9b9b 20f0a8             	JSR	LAB_27BA		; round FAC1
  3081  9b9e a5af               	LDA	FAC1_3		; get FAC1 mantissa3
  3082  9ba0 48                 	PHA				; push on stack
  3083  9ba1 a5ae               	LDA	FAC1_2		; get FAC1 mantissa2
  3084  9ba3 48                 	PHA				; push on stack
  3085  9ba4 a5ad               	LDA	FAC1_1		; get FAC1 mantissa1
  3086  9ba6 48                 	PHA				; push on stack
  3087  9ba7 a5ac               	LDA	FAC1_e		; get FAC1 exponent
  3088  9ba9 48                 	PHA				; push on stack
  3089  9baa 6c7100             	JMP	(ut1_pl)		; return, sort of
  3090                          
  3091                          ; do functions
  3092                          
  3093                          LAB_1B78
  3094  9bad a0ff               	LDY	#$FF			; flag function
  3095  9baf 68                 	PLA				; pull precedence byte
  3096                          LAB_1B7B
  3097  9bb0 f020               	BEQ	LAB_1B9D		; exit if done
  3098                          
  3099                          LAB_1B7D
  3100  9bb2 c964               	CMP	#$64			; compare previous precedence with $64
  3101  9bb4 f003               	BEQ	LAB_1B84		; branch if was $64 (< function)
  3102                          
  3103  9bb6 20e79a             	JSR	LAB_CTNM		; check if source is numeric, else do type mismatch
  3104                          LAB_1B84
  3105  9bb9 8499               	STY	prstk			; save precedence stacked flag
  3106                          
  3107                          					; pop FAC2 and return
  3108                          LAB_1B86
  3109  9bbb 68                 	PLA				; pop byte
  3110  9bbc 4a                 	LSR				; shift out comparison evaluation lowest bit
  3111  9bbd 8563               	STA	Cflag			; save comparison evaluation flag
  3112  9bbf 68                 	PLA				; pop exponent
  3113  9bc0 85b3               	STA	FAC2_e		; save FAC2 exponent
  3114  9bc2 68                 	PLA				; pop mantissa1
  3115  9bc3 85b4               	STA	FAC2_1		; save FAC2 mantissa1
  3116  9bc5 68                 	PLA				; pop mantissa2
  3117  9bc6 85b5               	STA	FAC2_2		; save FAC2 mantissa2
  3118  9bc8 68                 	PLA				; pop mantissa3
  3119  9bc9 85b6               	STA	FAC2_3		; save FAC2 mantissa3
  3120  9bcb 68                 	PLA				; pop sign
  3121  9bcc 85b7               	STA	FAC2_s		; save FAC2 sign (b7)
  3122  9bce 45b0               	EOR	FAC1_s		; EOR FAC1 sign (b7)
  3123  9bd0 85b8               	STA	FAC_sc		; save sign compare (FAC1 EOR FAC2)
  3124                          LAB_1B9D
  3125  9bd2 a5ac               	LDA	FAC1_e		; get FAC1 exponent
  3126  9bd4 60                 	RTS
  3127                          
  3128                          ; print "..." string to string util area
  3129                          
  3130                          LAB_1BC1
  3131  9bd5 a5c3               	LDA	Bpntrl		; get BASIC execute pointer low byte
  3132  9bd7 a4c4               	LDY	Bpntrh		; get BASIC execute pointer high byte
  3133  9bd9 6900               	ADC	#$00			; add carry to low byte
  3134  9bdb 9001               	BCC	LAB_1BCA		; branch if no overflow
  3135                          
  3136  9bdd c8                 	INY				; increment high byte
  3137                          LAB_1BCA
  3138  9bde 205ba1             	JSR	LAB_20AE		; print " terminated string to Sutill/Sutilh
  3139  9be1 4ce6a4             	JMP	LAB_23F3		; restore BASIC execute pointer from temp and return
  3140                          
  3141                          ; get value from line
  3142                          
  3143                          LAB_GVAL
  3144  9be4 20bc00             	JSR	LAB_IGBY		; increment and scan memory
  3145  9be7 b003               	BCS	LAB_1BAC		; branch if not numeric character
  3146                          
  3147                          					; else numeric string found (e.g. 123)
  3148                          LAB_1BA9
  3149  9be9 4cbda9             	JMP	LAB_2887		; get FAC1 from string and return
  3150                          
  3151                          ; get value from line .. continued
  3152                          
  3153                          					; wasn't a number so ..
  3154                          LAB_1BAC
  3155  9bec aa                 	TAX				; set the flags
  3156  9bed 302f               	BMI	LAB_1BD0		; if -ve go test token values
  3157                          
  3158                          					; else it is either a string, number, variable or (<expr>)
  3159  9bef c924               	CMP	#'$'			; compare with "$"
  3160  9bf1 f0f6               	BEQ	LAB_1BA9		; branch if "$", hex number
  3161                          
  3162  9bf3 c925               	CMP	#'%'			; else compare with "%"
  3163  9bf5 f0f2               	BEQ	LAB_1BA9		; branch if "%", binary number
  3164                          
  3165  9bf7 c92e               	CMP	#'.'			; compare with "."
  3166  9bf9 f0ee               	BEQ	LAB_1BA9		; if so get FAC1 from string and return (e.g. was .123)
  3167                          
  3168                          					; it wasn't any sort of number so ..
  3169  9bfb c922               	CMP	#$22			; compare with "
  3170  9bfd f0d6               	BEQ	LAB_1BC1		; branch if open quote
  3171                          
  3172                          					; wasn't any sort of number so ..
  3173                          
  3174                          ; evaluate expression within parentheses
  3175                          
  3176  9bff c928               	CMP	#'('			; compare with "("
  3177  9c01 d04f               	BNE	LAB_1C18		; if not "(" get (var), return value in FAC1 and $ flag
  3178                          
  3179                          LAB_1BF7
  3180  9c03 20009b             	JSR	LAB_EVEZ		; evaluate expression, no decrement
  3181                          
  3182                          ; all the 'scan for' routines return the character after the sought character
  3183                          
  3184                          ; scan for ")" , else do syntax error then warm start
  3185                          
  3186                          LAB_1BFB
  3187  9c06 a929               	LDA	#$29			; load A with ")"
  3188                          
  3189                          ; scan for CHR$(A) , else do syntax error then warm start
  3190                          
  3191                          LAB_SCCA
  3192  9c08 a000               	LDY	#$00			; clear index
  3193  9c0a d1c3               	CMP	(Bpntrl),Y		; check next byte is = A
  3194  9c0c d00b               	BNE	LAB_SNER		; if not do syntax error then warm start
  3195                          
  3196  9c0e 4cbc00             	JMP	LAB_IGBY		; increment and scan memory then return
  3197                          
  3198                          ; scan for "(" , else do syntax error then warm start
  3199                          
  3200                          LAB_1BFE
  3201  9c11 a928               	LDA	#$28			; load A with "("
  3202  9c13 d0f3               	BNE	LAB_SCCA		; scan for CHR$(A), else do syntax error then warm start
  3203                          					; (branch always)
  3204                          
  3205                          ; scan for "," , else do syntax error then warm start
  3206                          
  3207                          LAB_1C01
  3208  9c15 a92c               	LDA	#$2C			; load A with ","
  3209  9c17 d0ef               	BNE	LAB_SCCA		; scan for CHR$(A), else do syntax error then warm start
  3210                          					; (branch always)
  3211                          
  3212                          ; syntax error then warm start
  3213                          
  3214                          LAB_SNER
  3215  9c19 a202               	LDX	#$02			; error code $02 ("Syntax" error)
  3216  9c1b 4c4791             	JMP	LAB_XERR		; do error #X, then warm start
  3217                          
  3218                          ; get value from line .. continued
  3219                          ; do tokens
  3220                          
  3221                          LAB_1BD0
  3222  9c1e c9bc               	CMP	#TK_MINUS		; compare with token for -
  3223  9c20 f029               	BEQ	LAB_1C11		; branch if - token (do set-up for functions)
  3224                          
  3225                          					; wasn't -n so ..
  3226  9c22 c9bb               	CMP	#TK_PLUS		; compare with token for +
  3227  9c24 f0be               	BEQ	LAB_GVAL		; branch if + token (+n = n so ignore leading +)
  3228                          
  3229  9c26 c9b6               	CMP	#TK_NOT		; compare with token for NOT
  3230  9c28 d013               	BNE	LAB_1BE7		; branch if not token for NOT
  3231                          
  3232                          					; was NOT token
  3233                          TK_EQUAL_PLUS	= TK_EQUAL-TK_PLUS
  3234  9c2a a021               	LDY	#TK_EQUAL_PLUS*3	; offset to NOT function
  3235  9c2c d01f               	BNE	LAB_1C13		; do set-up for function then execute (branch always)
  3236                          
  3237                          ; do = compare
  3238                          
  3239                          LAB_EQUAL
  3240  9c2e 20bd9e             	JSR	LAB_EVIR		; evaluate integer expression (no sign check)
  3241  9c31 a5af               	LDA	FAC1_3		; get FAC1 mantissa3
  3242  9c33 49ff               	EOR	#$FF			; invert it
  3243  9c35 a8                 	TAY				; copy it
  3244  9c36 a5ae               	LDA	FAC1_2		; get FAC1 mantissa2
  3245  9c38 49ff               	EOR	#$FF			; invert it
  3246  9c3a 4c70a0             	JMP	LAB_AYFC		; save and convert integer AY to FAC1 and return
  3247                          
  3248                          ; get value from line .. continued
  3249                          
  3250                          					; wasn't +, -, or NOT so ..
  3251                          LAB_1BE7
  3252  9c3d c9b3               	CMP	#TK_FN		; compare with token for FN
  3253  9c3f d003               	BNE	LAB_1BEE		; branch if not token for FN
  3254                          
  3255  9c41 4ccba0             	JMP	LAB_201E		; go evaluate FNx
  3256                          
  3257                          ; get value from line .. continued
  3258                          
  3259                          					; wasn't +, -, NOT or FN so ..
  3260                          LAB_1BEE
  3261  9c44 e9c8               	SBC	#TK_SGN		; subtract with token for SGN
  3262  9c46 b019               	BCS	LAB_1C27		; if a function token go do it
  3263                          
  3264  9c48 4c199c             	JMP	LAB_SNER		; else do syntax error
  3265                          
  3266                          ; set-up for functions
  3267                          
  3268                          LAB_1C11
  3269                          TK_GT_PLUS	= TK_GT-TK_PLUS
  3270  9c4b a01e               	LDY	#TK_GT_PLUS*3	; set offset from base to > operator
  3271                          LAB_1C13
  3272  9c4d 68                 	PLA				; dump return address low byte
  3273  9c4e 68                 	PLA				; dump return address high byte
  3274  9c4f 4c519b             	JMP	LAB_1B1D		; execute function then continue evaluation
  3275                          
  3276                          ; variable name set-up
  3277                          ; get (var), return value in FAC_1 and $ flag
  3278                          
  3279                          LAB_1C18
  3280  9c52 20c19d             	JSR	LAB_GVAR		; get (var) address
  3281  9c55 85ae               	STA	FAC1_2		; save address low byte in FAC1 mantissa2
  3282  9c57 84af               	STY	FAC1_3		; save address high byte in FAC1 mantissa3
  3283  9c59 a65f               	LDX	Dtypef		; get data type flag, $FF=string, $00=numeric
  3284  9c5b 3003               	BMI	LAB_1C25		; if string then return (does RTS)
  3285                          
  3286                          LAB_1C24
  3287  9c5d 4c94a8             	JMP	LAB_UFAC		; unpack memory (AY) into FAC1
  3288                          
  3289                          LAB_1C25
  3290  9c60 60                 	RTS
  3291                          
  3292                          ; get value from line .. continued
  3293                          ; only functions left so ..
  3294                          
  3295                          ; set up function references
  3296                          
  3297                          ; new for V2.0+ this replaces a lot of IF .. THEN .. ELSEIF .. THEN .. that was needed
  3298                          ; to process function calls. now the function vector is computed and pushed on the stack
  3299                          ; and the preprocess offset is read. if the preprocess offset is non zero then the vector
  3300                          ; is calculated and the routine called, if not this routine just does RTS. whichever
  3301                          ; happens the RTS at the end of this routine, or the end of the preprocess routine, calls
  3302                          ; the function code
  3303                          
  3304                          ; this also removes some less than elegant code that was used to bypass type checking
  3305                          ; for functions that returned strings
  3306                          
  3307                          LAB_1C27
  3308  9c61 0a                 	ASL				; *2 (2 bytes per function address)
  3309  9c62 a8                 	TAY				; copy to index
  3310                          
  3311  9c63 b9cdb2             	LDA	LAB_FTBM,Y		; get function jump vector high byte
  3312  9c66 48                 	PHA				; push functions jump vector high byte
  3313  9c67 b9ccb2             	LDA	LAB_FTBL,Y		; get function jump vector low byte
  3314  9c6a 48                 	PHA				; push functions jump vector low byte
  3315                          
  3316  9c6b b987b2             	LDA	LAB_FTPM,Y		; get function pre process vector high byte
  3317  9c6e f005               	BEQ	LAB_1C56		; skip pre process if null vector
  3318                          
  3319  9c70 48                 	PHA				; push functions pre process vector high byte
  3320  9c71 b986b2             	LDA	LAB_FTPL,Y		; get function pre process vector low byte
  3321  9c74 48                 	PHA				; push functions pre process vector low byte
  3322                          
  3323                          LAB_1C56
  3324  9c75 60                 	RTS				; do function, or pre process, call
  3325                          
  3326                          ; process string expression in parenthesis
  3327                          
  3328                          LAB_PPFS
  3329  9c76 20039c             	JSR	LAB_1BF7		; process expression in parenthesis
  3330  9c79 4ce99a             	JMP	LAB_CTST		; check if source is string then do function,
  3331                          					; else do type mismatch
  3332                          
  3333                          ; process numeric expression in parenthesis
  3334                          
  3335                          LAB_PPFN
  3336  9c7c 20039c             	JSR	LAB_1BF7		; process expression in parenthesis
  3337  9c7f 4ce79a             	JMP	LAB_CTNM		; check if source is numeric then do function,
  3338                          					; else do type mismatch
  3339                          
  3340                          ; set numeric data type and increment BASIC execute pointer
  3341                          
  3342                          LAB_PPBI
  3343  9c82 465f               	LSR	Dtypef		; clear data type flag, $FF=string, $00=numeric
  3344  9c84 4cbc00             	JMP	LAB_IGBY		; increment and scan memory then do function
  3345                          
  3346                          ; process string for LEFT$, RIGHT$ or MID$
  3347                          
  3348                          LAB_LRMS
  3349  9c87 20009b             	JSR	LAB_EVEZ		; evaluate (should be string) expression
  3350  9c8a 20159c             	JSR	LAB_1C01		; scan for ",", else do syntax error then warm start
  3351  9c8d 20e99a             	JSR	LAB_CTST		; check if source is string, else do type mismatch
  3352                          
  3353  9c90 68                 	PLA				; get function jump vector low byte
  3354  9c91 aa                 	TAX				; save functions jump vector low byte
  3355  9c92 68                 	PLA				; get function jump vector high byte
  3356  9c93 a8                 	TAY				; save functions jump vector high byte
  3357  9c94 a5af               	LDA	des_ph		; get descriptor pointer high byte
  3358  9c96 48                 	PHA				; push string pointer high byte
  3359  9c97 a5ae               	LDA	des_pl		; get descriptor pointer low byte
  3360  9c99 48                 	PHA				; push string pointer low byte
  3361  9c9a 98                 	TYA				; get function jump vector high byte back
  3362  9c9b 48                 	PHA				; save functions jump vector high byte
  3363  9c9c 8a                 	TXA				; get function jump vector low byte back
  3364  9c9d 48                 	PHA				; save functions jump vector low byte
  3365  9c9e 20a3a4             	JSR	LAB_GTBY		; get byte parameter
  3366  9ca1 8a                 	TXA				; copy byte parameter to A
  3367  9ca2 60                 	RTS				; go do function
  3368                          
  3369                          ; process numeric expression(s) for BIN$ or HEX$
  3370                          
  3371                          LAB_BHSS
  3372  9ca3 20009b             	JSR	LAB_EVEZ		; process expression
  3373  9ca6 20e79a             	JSR	LAB_CTNM		; check if source is numeric, else do type mismatch
  3374  9ca9 a5ac               	LDA	FAC1_e		; get FAC1 exponent
  3375  9cab c998               	CMP	#$98			; compare with exponent = 2^24
  3376  9cad b020               	BCS	LAB_BHER		; branch if n>=2^24 (is too big)
  3377                          
  3378  9caf 2067a9             	JSR	LAB_2831		; convert FAC1 floating-to-fixed
  3379  9cb2 a202               	LDX	#$02			; 3 bytes to do
  3380                          LAB_CFAC
  3381  9cb4 b5ad               	LDA	FAC1_1,X		; get byte from FAC1
  3382  9cb6 9511               	STA	nums_1,X		; save byte to temp
  3383  9cb8 ca                 	DEX				; decrement index
  3384  9cb9 10f9               	BPL	LAB_CFAC		; copy FAC1 mantissa to temp
  3385                          
  3386  9cbb 20c200             	JSR	LAB_GBYT		; get next BASIC byte
  3387  9cbe a200               	LDX	#$00			; set default to no leading "0"s
  3388  9cc0 c929               	CMP	#')'			; compare with close bracket
  3389  9cc2 f00a               	BEQ	LAB_1C54		; if ")" go do rest of function
  3390                          
  3391  9cc4 20f5a4             	JSR	LAB_SCGB		; scan for "," and get byte
  3392  9cc7 20c200             	JSR	LAB_GBYT		; get last byte back
  3393  9cca c929               	CMP	#')'			; is next character )
  3394  9ccc d001               	BNE	LAB_BHER		; if not ")" go do error
  3395                          
  3396                          LAB_1C54
  3397  9cce 60                 	RTS				; else do function
  3398                          
  3399                          LAB_BHER
  3400  9ccf 4c409f             	JMP	LAB_FCER		; do function call error then warm start
  3401                          
  3402                          ; perform EOR
  3403                          
  3404                          ; added operator format is the same as AND or OR, precedence is the same as OR
  3405                          
  3406                          ; this bit worked first time but it took a while to sort out the operator table
  3407                          ; pointers and offsets afterwards!
  3408                          
  3409                          LAB_EOR
  3410  9cd2 20f99c             	JSR	GetFirst		; get first integer expression (no sign check)
  3411  9cd5 455b               	EOR	XOAw_l		; EOR with expression 1 low byte
  3412  9cd7 a8                 	TAY				; save in Y
  3413  9cd8 a5ae               	LDA	FAC1_2		; get FAC1 mantissa2
  3414  9cda 455c               	EOR	XOAw_h		; EOR with expression 1 high byte
  3415  9cdc 4c70a0             	JMP	LAB_AYFC		; save and convert integer AY to FAC1 and return
  3416                          
  3417                          ; perform OR
  3418                          
  3419                          LAB_OR
  3420  9cdf 20f99c             	JSR	GetFirst		; get first integer expression (no sign check)
  3421  9ce2 055b               	ORA	XOAw_l		; OR with expression 1 low byte
  3422  9ce4 a8                 	TAY				; save in Y
  3423  9ce5 a5ae               	LDA	FAC1_2		; get FAC1 mantissa2
  3424  9ce7 055c               	ORA	XOAw_h		; OR with expression 1 high byte
  3425  9ce9 4c70a0             	JMP	LAB_AYFC		; save and convert integer AY to FAC1 and return
  3426                          
  3427                          ; perform AND
  3428                          
  3429                          LAB_AND
  3430  9cec 20f99c             	JSR	GetFirst		; get first integer expression (no sign check)
  3431  9cef 255b               	AND	XOAw_l		; AND with expression 1 low byte
  3432  9cf1 a8                 	TAY				; save in Y
  3433  9cf2 a5ae               	LDA	FAC1_2		; get FAC1 mantissa2
  3434  9cf4 255c               	AND	XOAw_h		; AND with expression 1 high byte
  3435  9cf6 4c70a0             	JMP	LAB_AYFC		; save and convert integer AY to FAC1 and return
  3436                          
  3437                          ; get first value for OR, AND or EOR
  3438                          
  3439                          GetFirst
  3440  9cf9 20bd9e             	JSR	LAB_EVIR		; evaluate integer expression (no sign check)
  3441  9cfc a5ae               	LDA	FAC1_2		; get FAC1 mantissa2
  3442  9cfe 855c               	STA	XOAw_h		; save it
  3443  9d00 a5af               	LDA	FAC1_3		; get FAC1 mantissa3
  3444  9d02 855b               	STA	XOAw_l		; save it
  3445  9d04 20daa5             	JSR	LAB_279B		; copy FAC2 to FAC1 (get 2nd value in expression)
  3446  9d07 20bd9e             	JSR	LAB_EVIR		; evaluate integer expression (no sign check)
  3447  9d0a a5af               	LDA	FAC1_3		; get FAC1 mantissa3
  3448                          LAB_1C95
  3449  9d0c 60                 	RTS
  3450                          
  3451                          ; perform comparisons
  3452                          
  3453                          ; do < compare
  3454                          
  3455                          LAB_LTHAN
  3456  9d0d 20ea9a             	JSR	LAB_CKTM		; type match check, set C for string
  3457  9d10 b013               	BCS	LAB_1CAE		; branch if string
  3458                          
  3459                          					; do numeric < compare
  3460  9d12 a5b7               	LDA	FAC2_s		; get FAC2 sign (b7)
  3461  9d14 097f               	ORA	#$7F			; set all non sign bits
  3462  9d16 25b4               	AND	FAC2_1		; and FAC2 mantissa1 (AND in sign bit)
  3463  9d18 85b4               	STA	FAC2_1		; save FAC2 mantissa1
  3464  9d1a a9b3               	LDA	#<FAC2_e		; set pointer low byte to FAC2
  3465  9d1c a000               	LDY	#>FAC2_e		; set pointer high byte to FAC2
  3466  9d1e 202ea9             	JSR	LAB_27F8		; compare FAC1 with FAC2 (AY)
  3467  9d21 aa                 	TAX				; copy result
  3468  9d22 4c569d             	JMP	LAB_1CE1		; go evaluate result
  3469                          
  3470                          					; do string < compare
  3471                          LAB_1CAE
  3472  9d25 465f               	LSR	Dtypef		; clear data type flag, $FF=string, $00=numeric
  3473  9d27 c69b               	DEC	comp_f		; clear < bit in compare function flag
  3474  9d29 2055a3             	JSR	LAB_22B6		; pop string off descriptor stack, or from top of string
  3475                          					; space returns with A = length, X=pointer low byte,
  3476                          					; Y=pointer high byte
  3477  9d2c 85ac               	STA	str_ln		; save length
  3478  9d2e 86ad               	STX	str_pl		; save string pointer low byte
  3479  9d30 84ae               	STY	str_ph		; save string pointer high byte
  3480  9d32 a5b5               	LDA	FAC2_2		; get descriptor pointer low byte
  3481  9d34 a4b6               	LDY	FAC2_3		; get descriptor pointer high byte
  3482  9d36 2059a3             	JSR	LAB_22BA		; pop (YA) descriptor off stack or from top of string space
  3483                          					; returns with A = length, X=pointer low byte,
  3484                          					; Y=pointer high byte
  3485  9d39 86b5               	STX	FAC2_2		; save string pointer low byte
  3486  9d3b 84b6               	STY	FAC2_3		; save string pointer high byte
  3487  9d3d aa                 	TAX				; copy length
  3488  9d3e 38                 	SEC				; set carry for subtract
  3489  9d3f e5ac               	SBC	str_ln		; subtract string 1 length
  3490  9d41 f008               	BEQ	LAB_1CD6		; branch if str 1 length = string 2 length
  3491                          
  3492  9d43 a901               	LDA	#$01			; set str 1 length > string 2 length
  3493  9d45 9004               	BCC	LAB_1CD6		; branch if so
  3494                          
  3495  9d47 a6ac               	LDX	str_ln		; get string 1 length
  3496  9d49 a9ff               	LDA	#$FF			; set str 1 length < string 2 length
  3497                          LAB_1CD6
  3498  9d4b 85b0               	STA	FAC1_s		; save length compare
  3499  9d4d a0ff               	LDY	#$FF			; set index
  3500  9d4f e8                 	INX				; adjust for loop
  3501                          LAB_1CDB
  3502  9d50 c8                 	INY				; increment index
  3503  9d51 ca                 	DEX				; decrement count
  3504  9d52 d007               	BNE	LAB_1CE6		; branch if still bytes to do
  3505                          
  3506  9d54 a6b0               	LDX	FAC1_s		; get length compare back
  3507                          LAB_1CE1
  3508  9d56 300f               	BMI	LAB_1CF2		; branch if str 1 < str 2
  3509                          
  3510  9d58 18                 	CLC				; flag str 1 <= str 2
  3511  9d59 900c               	BCC	LAB_1CF2		; go evaluate result
  3512                          
  3513                          LAB_1CE6
  3514  9d5b b1b5               	LDA	(FAC2_2),Y		; get string 2 byte
  3515  9d5d d1ad               	CMP	(FAC1_1),Y		; compare with string 1 byte
  3516  9d5f f0ef               	BEQ	LAB_1CDB		; loop if bytes =
  3517                          
  3518  9d61 a2ff               	LDX	#$FF			; set str 1 < string 2
  3519  9d63 b002               	BCS	LAB_1CF2		; branch if so
  3520                          
  3521  9d65 a201               	LDX	#$01			;  set str 1 > string 2
  3522                          LAB_1CF2
  3523  9d67 e8                 	INX				; x = 0, 1 or 2
  3524  9d68 8a                 	TXA				; copy to A
  3525  9d69 2a                 	ROL				; *2 (1, 2 or 4)
  3526  9d6a 2563               	AND	Cflag			; AND with comparison evaluation flag
  3527  9d6c f002               	BEQ	LAB_1CFB		; branch if 0 (compare is false)
  3528                          
  3529  9d6e a9ff               	LDA	#$FF			; else set result true
  3530                          LAB_1CFB
  3531  9d70 4c11a9             	JMP	LAB_27DB		; save A as integer byte and return
  3532                          
  3533                          LAB_1CFE
  3534  9d73 20159c             	JSR	LAB_1C01		; scan for ",", else do syntax error then warm start
  3535                          
  3536                          ; perform DIM
  3537                          
  3538                          LAB_DIM
  3539  9d76 aa                 	TAX				; copy "DIM" flag to X
  3540  9d77 20c69d             	JSR	LAB_1D10		; search for variable
  3541  9d7a 20c200             	JSR	LAB_GBYT		; scan memory
  3542  9d7d d0f4               	BNE	LAB_1CFE		; scan for "," and loop if not null
  3543                          
  3544  9d7f 60                 	RTS
  3545                          
  3546                          ; perform << (left shift)
  3547                          
  3548                          LAB_LSHIFT
  3549  9d80 20b69d             	JSR	GetPair		; get integer expression and byte (no sign check)
  3550  9d83 a5ae               	LDA	FAC1_2		; get expression high byte
  3551  9d85 a678               	LDX	TempB			; get shift count
  3552  9d87 f022               	BEQ	NoShift		; branch if zero
  3553                          
  3554  9d89 e010               	CPX	#$10			; compare bit count with 16d
  3555  9d8b b023               	BCS	TooBig		; branch if >=
  3556                          
  3557                          Ls_loop
  3558  9d8d 06af               	ASL	FAC1_3		; shift low byte
  3559  9d8f 2a                 	ROL				; shift high byte
  3560  9d90 ca                 	DEX				; decrement bit count
  3561  9d91 d0fa               	BNE	Ls_loop		; loop if shift not complete
  3562                          
  3563  9d93 a4af               	LDY	FAC1_3		; get expression low byte
  3564  9d95 4c70a0             	JMP	LAB_AYFC		; save and convert integer AY to FAC1 and return
  3565                          
  3566                          ; perform >> (right shift)
  3567                          
  3568                          LAB_RSHIFT
  3569  9d98 20b69d             	JSR	GetPair		; get integer expression and byte (no sign check)
  3570  9d9b a5ae               	LDA	FAC1_2		; get expression high byte
  3571  9d9d a678               	LDX	TempB			; get shift count
  3572  9d9f f00a               	BEQ	NoShift		; branch if zero
  3573                          
  3574  9da1 e010               	CPX	#$10			; compare bit count with 16d
  3575  9da3 b00b               	BCS	TooBig		; branch if >=
  3576                          
  3577                          Rs_loop
  3578  9da5 4a                 	LSR				; shift high byte
  3579  9da6 66af               	ROR	FAC1_3		; shift low byte
  3580  9da8 ca                 	DEX				; decrement bit count
  3581  9da9 d0fa               	BNE	Rs_loop		; loop if shift not complete
  3582                          
  3583                          NoShift
  3584  9dab a4af               	LDY	FAC1_3		; get expression low byte
  3585  9dad 4c70a0             	JMP	LAB_AYFC		; save and convert integer AY to FAC1 and return
  3586                          
  3587                          TooBig
  3588  9db0 a900               	LDA	#$00			; clear high byte
  3589  9db2 a8                 	TAY				; copy to low byte
  3590  9db3 4c70a0             	JMP	LAB_AYFC		; save and convert integer AY to FAC1 and return
  3591                          
  3592                          GetPair
  3593  9db6 20a6a4             	JSR	LAB_EVBY		; evaluate byte expression, result in X
  3594  9db9 8678               	STX	TempB			; save it
  3595  9dbb 20daa5             	JSR	LAB_279B		; copy FAC2 to FAC1 (get 2nd value in expression)
  3596  9dbe 4cbd9e             	JMP	LAB_EVIR		; evaluate integer expression (no sign check)
  3597                          
  3598                          ; search for variable
  3599                          
  3600                          ; return pointer to variable in Cvaral/Cvarah
  3601                          
  3602                          LAB_GVAR
  3603  9dc1 a200               	LDX	#$00			; set DIM flag = $00
  3604  9dc3 20c200             	JSR	LAB_GBYT		; scan memory (1st character)
  3605                          LAB_1D10
  3606  9dc6 865e               	STX	Defdim		; save DIM flag
  3607                          LAB_1D12
  3608  9dc8 8593               	STA	Varnm1		; save 1st character
  3609  9dca 297f               	AND	#$7F			; clear FN flag bit
  3610  9dcc 20359e             	JSR	LAB_CASC		; check byte, return C=0 if<"A" or >"Z"
  3611  9dcf b003               	BCS	LAB_1D1F		; branch if ok
  3612                          
  3613  9dd1 4c199c             	JMP	LAB_SNER		; else syntax error then warm start
  3614                          
  3615                          					; was variable name so ..
  3616                          LAB_1D1F
  3617  9dd4 a200               	LDX	#$00			; clear 2nd character temp
  3618  9dd6 865f               	STX	Dtypef		; clear data type flag, $FF=string, $00=numeric
  3619  9dd8 20bc00             	JSR	LAB_IGBY		; increment and scan memory (2nd character)
  3620  9ddb 9005               	BCC	LAB_1D2D		; branch if character = "0"-"9" (ok)
  3621                          
  3622                          					; 2nd character wasn't "0" to "9" so ..
  3623  9ddd 20359e             	JSR	LAB_CASC		; check byte, return C=0 if<"A" or >"Z"
  3624  9de0 900b               	BCC	LAB_1D38		; branch if <"A" or >"Z" (go check if string)
  3625                          
  3626                          LAB_1D2D
  3627  9de2 aa                 	TAX				; copy 2nd character
  3628                          
  3629                          					; ignore further (valid) characters in the variable name
  3630                          LAB_1D2E
  3631  9de3 20bc00             	JSR	LAB_IGBY		; increment and scan memory (3rd character)
  3632  9de6 90fb               	BCC	LAB_1D2E		; loop if character = "0"-"9" (ignore)
  3633                          
  3634  9de8 20359e             	JSR	LAB_CASC		; check byte, return C=0 if<"A" or >"Z"
  3635  9deb b0f6               	BCS	LAB_1D2E		; loop if character = "A"-"Z" (ignore)
  3636                          
  3637                          					; check if string variable
  3638                          LAB_1D38
  3639  9ded c924               	CMP	#'$'			; compare with "$"
  3640  9def d00b               	BNE	LAB_1D47		; branch if not string
  3641                          
  3642                          ; to introduce a new variable type (% suffix for integers say) then this branch
  3643                          ; will need to go to that check and then that branch, if it fails, go to LAB_1D47
  3644                          
  3645                          					; type is string
  3646  9df1 a9ff               	LDA	#$FF			; set data type = string
  3647  9df3 855f               	STA	Dtypef		; set data type flag, $FF=string, $00=numeric
  3648  9df5 8a                 	TXA				; get 2nd character back
  3649  9df6 0980               	ORA	#$80			; set top bit (indicate string var)
  3650  9df8 aa                 	TAX				; copy back to 2nd character temp
  3651  9df9 20bc00             	JSR	LAB_IGBY		; increment and scan memory
  3652                          
  3653                          ; after we have determined the variable type we need to come back here to determine
  3654                          ; if it's an array of type. this would plug in a%(b[,c[,d]])) integer arrays nicely
  3655                          
  3656                          
  3657                          LAB_1D47				; gets here with character after var name in A
  3658  9dfc 8694               	STX	Varnm2		; save 2nd character
  3659  9dfe 0561               	ORA	Sufnxf		; or with subscript/FNX flag (or FN name)
  3660  9e00 c928               	CMP	#'('			; compare with "("
  3661  9e02 d003               	BNE	LAB_1D53		; branch if not "("
  3662                          
  3663  9e04 4ccf9e             	JMP	LAB_1E17		; go find, or make, array
  3664                          
  3665                          ; either find or create var
  3666                          ; var name (1st two characters only!) is in Varnm1,Varnm2
  3667                          
  3668                          					; variable name wasn't var(... so look for plain var
  3669                          LAB_1D53
  3670  9e07 a900               	LDA	#$00			; clear A
  3671  9e09 8561               	STA	Sufnxf		; clear subscript/FNX flag
  3672  9e0b a57b               	LDA	Svarl			; get start of vars low byte
  3673  9e0d a67c               	LDX	Svarh			; get start of vars high byte
  3674  9e0f a000               	LDY	#$00			; clear index
  3675                          LAB_1D5D
  3676  9e11 86ab               	STX	Vrschh		; save search address high byte
  3677                          LAB_1D5F
  3678  9e13 85aa               	STA	Vrschl		; save search address low byte
  3679  9e15 e47e               	CPX	Sarryh		; compare high address with var space end
  3680  9e17 d004               	BNE	LAB_1D69		; skip next compare if <>
  3681                          
  3682                          					; high addresses were = so compare low addresses
  3683  9e19 c57d               	CMP	Sarryl		; compare low address with var space end
  3684  9e1b f02c               	BEQ	LAB_1D8B		; if not found go make new var
  3685                          
  3686                          LAB_1D69
  3687  9e1d a593               	LDA	Varnm1		; get 1st character of var to find
  3688  9e1f d1aa               	CMP	(Vrschl),Y		; compare with variable name 1st character
  3689  9e21 d008               	BNE	LAB_1D77		; branch if no match
  3690                          
  3691                          					; 1st characters match so compare 2nd characters
  3692  9e23 a594               	LDA	Varnm2		; get 2nd character of var to find
  3693  9e25 c8                 	INY				; index to point to variable name 2nd character
  3694  9e26 d1aa               	CMP	(Vrschl),Y		; compare with variable name 2nd character
  3695  9e28 f069               	BEQ	LAB_1DD7		; branch if match (found var)
  3696                          
  3697  9e2a 88                 	DEY				; else decrement index (now = $00)
  3698                          LAB_1D77
  3699  9e2b 18                 	CLC				; clear carry for add
  3700  9e2c a5aa               	LDA	Vrschl		; get search address low byte
  3701  9e2e 6906               	ADC	#$06			; +6 (offset to next var name)
  3702  9e30 90e1               	BCC	LAB_1D5F		; loop if no overflow to high byte
  3703                          
  3704  9e32 e8                 	INX				; else increment high byte
  3705  9e33 d0dc               	BNE	LAB_1D5D		; loop always (RAM doesn't extend to $FFFF !)
  3706                          
  3707                          ; check byte, return C=0 if<"A" or >"Z" or "a" to "z"
  3708                          
  3709                          LAB_CASC
  3710  9e35 c961               	CMP	#'a'			; compare with "a"
  3711  9e37 b00a               	BCS	LAB_1D83		; go check <"z"+1
  3712                          
  3713                          ; check byte, return C=0 if<"A" or >"Z"
  3714                          
  3715                          LAB_1D82
  3716  9e39 c941               	CMP	#'A'			; compare with "A"
  3717  9e3b 9005               	BCC	LAB_1D8A		; exit if less
  3718                          
  3719                          					; carry is set
  3720  9e3d e95b               	SBC	#$5B			; subtract "Z"+1
  3721  9e3f 38                 	SEC				; set carry
  3722  9e40 e9a5               	SBC	#$A5			; subtract $A5 (restore byte)
  3723                          					; carry clear if byte>$5A
  3724                          LAB_1D8A
  3725  9e42 60                 	RTS
  3726                          
  3727                          LAB_1D83
  3728  9e43 e97b               	SBC	#$7B			; subtract "z"+1
  3729  9e45 38                 	SEC				; set carry
  3730  9e46 e985               	SBC	#$85			; subtract $85 (restore byte)
  3731                          					; carry clear if byte>$7A
  3732  9e48 60                 	RTS
  3733                          
  3734                          					; reached end of variable mem without match
  3735                          					; .. so create new variable
  3736                          LAB_1D8B
  3737  9e49 68                 	PLA				; pop return address low byte
  3738  9e4a 48                 	PHA				; push return address low byte
  3739                          LAB_1C18p2	= LAB_1C18+2
  3740  9e4b c954               	CMP	#<LAB_1C18p2	; compare with expected calling routine return low byte
  3741  9e4d d005               	BNE	LAB_1D98		; if not get (var) go create new var
  3742                          
  3743                          ; This will only drop through if the call was from LAB_1C18 and is only called
  3744                          ; from there if it is searching for a variable from the RHS of a LET a=b statement
  3745                          ; it prevents the creation of variables not assigned a value.
  3746                          
  3747                          ; value returned by this is either numeric zero (exponent byte is $00) or null string
  3748                          ; (descriptor length byte is $00). in fact a pointer to any $00 byte would have done.
  3749                          
  3750                          ; doing this saves 6 bytes of variable memory and 168 machine cycles of time
  3751                          
  3752                          ; this is where you would put the undefined variable error call e.g.
  3753                          
  3754                          ;					; variable doesn't exist so flag error
  3755                          ;	LDX	#$24			; error code $24 ("undefined variable" error)
  3756                          ;	JMP	LAB_XERR		; do error #X then warm start
  3757                          
  3758                          ; the above code has been tested and works a treat! (it replaces the three code lines
  3759                          ; below)
  3760                          
  3761                          					; else return dummy null value
  3762  9e4f a900               	LDA	#<LAB_1D96		; low byte point to $00,$00
  3763                          					; (uses part of misc constants table)
  3764  9e51 a0b2               	LDY	#>LAB_1D96		; high byte point to $00,$00
  3765  9e53 60                 	RTS
  3766                          
  3767                          					; create new numeric variable
  3768                          LAB_1D98
  3769  9e54 a57d               	LDA	Sarryl		; get var mem end low byte
  3770  9e56 a47e               	LDY	Sarryh		; get var mem end high byte
  3771  9e58 85aa               	STA	Ostrtl		; save old block start low byte
  3772  9e5a 84ab               	STY	Ostrth		; save old block start high byte
  3773  9e5c a57f               	LDA	Earryl		; get array mem end low byte
  3774  9e5e a480               	LDY	Earryh		; get array mem end high byte
  3775  9e60 85a6               	STA	Obendl		; save old block end low byte
  3776  9e62 84a7               	STY	Obendh		; save old block end high byte
  3777  9e64 18                 	CLC				; clear carry for add
  3778  9e65 6906               	ADC	#$06			; +6 (space for one var)
  3779  9e67 9001               	BCC	LAB_1DAE		; branch if no overflow to high byte
  3780                          
  3781  9e69 c8                 	INY				; else increment high byte
  3782                          LAB_1DAE
  3783  9e6a 85a4               	STA	Nbendl		; set new block end low byte
  3784  9e6c 84a5               	STY	Nbendh		; set new block end high byte
  3785  9e6e 20cc90             	JSR	LAB_11CF		; open up space in memory
  3786  9e71 a5a4               	LDA	Nbendl		; get new start low byte
  3787  9e73 a4a5               	LDY	Nbendh		; get new start high byte (-$100)
  3788  9e75 c8                 	INY				; correct high byte
  3789  9e76 857d               	STA	Sarryl		; save new var mem end low byte
  3790  9e78 847e               	STY	Sarryh		; save new var mem end high byte
  3791  9e7a a000               	LDY	#$00			; clear index
  3792  9e7c a593               	LDA	Varnm1		; get var name 1st character
  3793  9e7e 91aa               	STA	(Vrschl),Y		; save var name 1st character
  3794  9e80 c8                 	INY				; increment index
  3795  9e81 a594               	LDA	Varnm2		; get var name 2nd character
  3796  9e83 91aa               	STA	(Vrschl),Y		; save var name 2nd character
  3797  9e85 a900               	LDA	#$00			; clear A
  3798  9e87 c8                 	INY				; increment index
  3799  9e88 91aa               	STA	(Vrschl),Y		; initialise var byte
  3800  9e8a c8                 	INY				; increment index
  3801  9e8b 91aa               	STA	(Vrschl),Y		; initialise var byte
  3802  9e8d c8                 	INY				; increment index
  3803  9e8e 91aa               	STA	(Vrschl),Y		; initialise var byte
  3804  9e90 c8                 	INY				; increment index
  3805  9e91 91aa               	STA	(Vrschl),Y		; initialise var byte
  3806                          
  3807                          					; found a match for var ((Vrschl) = ptr)
  3808                          LAB_1DD7
  3809  9e93 a5aa               	LDA	Vrschl		; get var address low byte
  3810  9e95 18                 	CLC				; clear carry for add
  3811  9e96 6902               	ADC	#$02			; +2 (offset past var name bytes)
  3812  9e98 a4ab               	LDY	Vrschh		; get var address high byte
  3813  9e9a 9001               	BCC	LAB_1DE1		; branch if no overflow from add
  3814                          
  3815  9e9c c8                 	INY				; else increment high byte
  3816                          LAB_1DE1
  3817  9e9d 8595               	STA	Cvaral		; save current var address low byte
  3818  9e9f 8496               	STY	Cvarah		; save current var address high byte
  3819  9ea1 60                 	RTS
  3820                          
  3821                          ; set-up array pointer (Adatal/h) to first element in array
  3822                          ; set Adatal,Adatah to Astrtl,Astrth+2*Dimcnt+#$05
  3823                          
  3824                          LAB_1DE6
  3825  9ea2 a55d               	LDA	Dimcnt		; get # of dimensions (1, 2 or 3)
  3826  9ea4 0a                 	ASL				; *2 (also clears the carry !)
  3827  9ea5 6905               	ADC	#$05			; +5 (result is 7, 9 or 11 here)
  3828  9ea7 65aa               	ADC	Astrtl		; add array start pointer low byte
  3829  9ea9 a4ab               	LDY	Astrth		; get array pointer high byte
  3830  9eab 9001               	BCC	LAB_1DF2		; branch if no overflow
  3831                          
  3832  9ead c8                 	INY				; else increment high byte
  3833                          LAB_1DF2
  3834  9eae 85a4               	STA	Adatal		; save array data pointer low byte
  3835  9eb0 84a5               	STY	Adatah		; save array data pointer high byte
  3836  9eb2 60                 	RTS
  3837                          
  3838                          ; evaluate integer expression
  3839                          
  3840                          LAB_EVIN
  3841  9eb3 20bc00             	JSR	LAB_IGBY		; increment and scan memory
  3842  9eb6 20e49a             	JSR	LAB_EVNM		; evaluate expression and check is numeric,
  3843                          					; else do type mismatch
  3844                          
  3845                          ; evaluate integer expression (no check)
  3846                          
  3847                          LAB_EVPI
  3848  9eb9 a5b0               	LDA	FAC1_s		; get FAC1 sign (b7)
  3849  9ebb 300d               	BMI	LAB_1E12		; do function call error if -ve
  3850                          
  3851                          ; evaluate integer expression (no sign check)
  3852                          
  3853                          LAB_EVIR
  3854  9ebd a5ac               	LDA	FAC1_e		; get FAC1 exponent
  3855  9ebf c990               	CMP	#$90			; compare with exponent = 2^16 (n>2^15)
  3856  9ec1 9009               	BCC	LAB_1E14		; branch if n<2^16 (is ok)
  3857                          
  3858  9ec3 a907               	LDA	#<LAB_1DF7		; set pointer low byte to -32768
  3859  9ec5 a0b2               	LDY	#>LAB_1DF7		; set pointer high byte to -32768
  3860  9ec7 202ea9             	JSR	LAB_27F8		; compare FAC1 with (AY)
  3861                          LAB_1E12
  3862  9eca d074               	BNE	LAB_FCER		; if <> do function call error then warm start
  3863                          
  3864                          LAB_1E14
  3865  9ecc 4c67a9             	JMP	LAB_2831		; convert FAC1 floating-to-fixed and return
  3866                          
  3867                          ; find or make array
  3868                          
  3869                          LAB_1E17
  3870  9ecf a55e               	LDA	Defdim		; get DIM flag
  3871  9ed1 48                 	PHA				; push it
  3872  9ed2 a55f               	LDA	Dtypef		; get data type flag, $FF=string, $00=numeric
  3873  9ed4 48                 	PHA				; push it
  3874  9ed5 a000               	LDY	#$00			; clear dimensions count
  3875                          
  3876                          ; now get the array dimension(s) and stack it (them) before the data type and DIM flag
  3877                          
  3878                          LAB_1E1F
  3879  9ed7 98                 	TYA				; copy dimensions count
  3880  9ed8 48                 	PHA				; save it
  3881  9ed9 a594               	LDA	Varnm2		; get array name 2nd byte
  3882  9edb 48                 	PHA				; save it
  3883  9edc a593               	LDA	Varnm1		; get array name 1st byte
  3884  9ede 48                 	PHA				; save it
  3885  9edf 20b39e             	JSR	LAB_EVIN		; evaluate integer expression
  3886  9ee2 68                 	PLA				; pull array name 1st byte
  3887  9ee3 8593               	STA	Varnm1		; restore array name 1st byte
  3888  9ee5 68                 	PLA				; pull array name 2nd byte
  3889  9ee6 8594               	STA	Varnm2		; restore array name 2nd byte
  3890  9ee8 68                 	PLA				; pull dimensions count
  3891  9ee9 a8                 	TAY				; restore it
  3892  9eea ba                 	TSX				; copy stack pointer
  3893  9eeb bd0201             	LDA	LAB_STAK+2,X	; get DIM flag
  3894  9eee 48                 	PHA				; push it
  3895  9eef bd0101             	LDA	LAB_STAK+1,X	; get data type flag
  3896  9ef2 48                 	PHA				; push it
  3897  9ef3 a5ae               	LDA	FAC1_2		; get this dimension size high byte
  3898  9ef5 9d0201             	STA	LAB_STAK+2,X	; stack before flag bytes
  3899  9ef8 a5af               	LDA	FAC1_3		; get this dimension size low byte
  3900  9efa 9d0101             	STA	LAB_STAK+1,X	; stack before flag bytes
  3901  9efd c8                 	INY				; increment dimensions count
  3902  9efe 20c200             	JSR	LAB_GBYT		; scan memory
  3903  9f01 c92c               	CMP	#','			; compare with ","
  3904  9f03 f0d2               	BEQ	LAB_1E1F		; if found go do next dimension
  3905                          
  3906  9f05 845d               	STY	Dimcnt		; store dimensions count
  3907  9f07 20069c             	JSR	LAB_1BFB		; scan for ")" , else do syntax error then warm start
  3908  9f0a 68                 	PLA				; pull data type flag
  3909  9f0b 855f               	STA	Dtypef		; restore data type flag, $FF=string, $00=numeric
  3910  9f0d 68                 	PLA				; pull DIM flag
  3911  9f0e 855e               	STA	Defdim		; restore DIM flag
  3912  9f10 a67d               	LDX	Sarryl		; get array mem start low byte
  3913  9f12 a57e               	LDA	Sarryh		; get array mem start high byte
  3914                          
  3915                          ; now check to see if we are at the end of array memory (we would be if there were
  3916                          ; no arrays).
  3917                          
  3918                          LAB_1E5C
  3919  9f14 86aa               	STX	Astrtl		; save as array start pointer low byte
  3920  9f16 85ab               	STA	Astrth		; save as array start pointer high byte
  3921  9f18 c580               	CMP	Earryh		; compare with array mem end high byte
  3922  9f1a d004               	BNE	LAB_1E68		; branch if not reached array mem end
  3923                          
  3924  9f1c e47f               	CPX	Earryl		; else compare with array mem end low byte
  3925  9f1e f039               	BEQ	LAB_1EA1		; go build array if not found
  3926                          
  3927                          					; search for array
  3928                          LAB_1E68
  3929  9f20 a000               	LDY	#$00			; clear index
  3930  9f22 b1aa               	LDA	(Astrtl),Y		; get array name first byte
  3931  9f24 c8                 	INY				; increment index to second name byte
  3932  9f25 c593               	CMP	Varnm1		; compare with this array name first byte
  3933  9f27 d006               	BNE	LAB_1E77		; branch if no match
  3934                          
  3935  9f29 a594               	LDA	Varnm2		; else get this array name second byte
  3936  9f2b d1aa               	CMP	(Astrtl),Y		; compare with array name second byte
  3937  9f2d f016               	BEQ	LAB_1E8D		; array found so branch
  3938                          
  3939                          					; no match
  3940                          LAB_1E77
  3941  9f2f c8                 	INY				; increment index
  3942  9f30 b1aa               	LDA	(Astrtl),Y		; get array size low byte
  3943  9f32 18                 	CLC				; clear carry for add
  3944  9f33 65aa               	ADC	Astrtl		; add array start pointer low byte
  3945  9f35 aa                 	TAX				; copy low byte to X
  3946  9f36 c8                 	INY				; increment index
  3947  9f37 b1aa               	LDA	(Astrtl),Y		; get array size high byte
  3948  9f39 65ab               	ADC	Astrth		; add array mem pointer high byte
  3949  9f3b 90d7               	BCC	LAB_1E5C		; if no overflow go check next array
  3950                          
  3951                          ; do array bounds error
  3952                          
  3953                          LAB_1E85
  3954  9f3d a210               	LDX	#$10			; error code $10 ("Array bounds" error)
  3955  9f3f 2c                 	!text	$2C			; makes next bit BIT LAB_08A2
  3956                          
  3957                          ; do function call error
  3958                          
  3959                          LAB_FCER
  3960  9f40 a208               	LDX	#$08			; error code $08 ("Function call" error)
  3961                          LAB_1E8A
  3962  9f42 4c4791             	JMP	LAB_XERR		; do error #X, then warm start
  3963                          
  3964                          					; found array, are we trying to dimension it?
  3965                          LAB_1E8D
  3966  9f45 a212               	LDX	#$12			; set error $12 ("Double dimension" error)
  3967  9f47 a55e               	LDA	Defdim		; get DIM flag
  3968  9f49 d0f7               	BNE	LAB_1E8A		; if we are trying to dimension it do error #X, then warm
  3969                          					; start
  3970                          
  3971                          ; found the array and we're not dimensioning it so we must find an element in it
  3972                          
  3973  9f4b 20a29e             	JSR	LAB_1DE6		; set-up array pointer (Adatal/h) to first element in array
  3974                          					; (Astrtl,Astrth points to start of array)
  3975  9f4e a55d               	LDA	Dimcnt		; get dimensions count
  3976  9f50 a004               	LDY	#$04			; set index to array's # of dimensions
  3977  9f52 d1aa               	CMP	(Astrtl),Y		; compare with no of dimensions
  3978  9f54 d0e7               	BNE	LAB_1E85		; if wrong do array bounds error, could do "Wrong
  3979                          					; dimensions" error here .. if we want a different
  3980                          					; error message
  3981                          
  3982  9f56 4cdc9f             	JMP	LAB_1F28		; found array so go get element
  3983                          					; (could jump to LAB_1F28 as all LAB_1F24 does is take
  3984                          					; Dimcnt and save it at (Astrtl),Y which is already the
  3985                          					; same or we would have taken the BNE)
  3986                          
  3987                          					; array not found, so build it
  3988                          LAB_1EA1
  3989  9f59 20a29e             	JSR	LAB_1DE6		; set-up array pointer (Adatal/h) to first element in array
  3990                          					; (Astrtl,Astrth points to start of array)
  3991  9f5c 201691             	JSR	LAB_121F		; check available memory, "Out of memory" error if no room
  3992                          					; addr to check is in AY (low/high)
  3993  9f5f a000               	LDY	#$00			; clear Y (don't need to clear A)
  3994  9f61 84bb               	STY	Aspth			; clear array data size high byte
  3995  9f63 a593               	LDA	Varnm1		; get variable name 1st byte
  3996  9f65 91aa               	STA	(Astrtl),Y		; save array name 1st byte
  3997  9f67 c8                 	INY				; increment index
  3998  9f68 a594               	LDA	Varnm2		; get variable name 2nd byte
  3999  9f6a 91aa               	STA	(Astrtl),Y		; save array name 2nd byte
  4000  9f6c a55d               	LDA	Dimcnt		; get dimensions count
  4001  9f6e a004               	LDY	#$04			; index to dimension count
  4002  9f70 84ba               	STY	Asptl			; set array data size low byte (four bytes per element)
  4003  9f72 91aa               	STA	(Astrtl),Y		; set array's dimensions count
  4004                          
  4005                          					; now calculate the size of the data space for the array
  4006  9f74 18                 	CLC				; clear carry for add (clear on subsequent loops)
  4007                          LAB_1EC0
  4008  9f75 a20b               	LDX	#$0B			; set default dimension value low byte
  4009  9f77 a900               	LDA	#$00			; set default dimension value high byte
  4010  9f79 245e               	BIT	Defdim		; test default DIM flag
  4011  9f7b 5007               	BVC	LAB_1ED0		; branch if b6 of Defdim is clear
  4012                          
  4013  9f7d 68                 	PLA				; else pull dimension value low byte
  4014  9f7e 6901               	ADC	#$01			; +1 (allow for zeroeth element)
  4015  9f80 aa                 	TAX				; copy low byte to X
  4016  9f81 68                 	PLA				; pull dimension value high byte
  4017  9f82 6900               	ADC	#$00			; add carry from low byte
  4018                          
  4019                          LAB_1ED0
  4020  9f84 c8                 	INY				; index to dimension value high byte
  4021  9f85 91aa               	STA	(Astrtl),Y		; save dimension value high byte
  4022  9f87 c8                 	INY				; index to dimension value high byte
  4023  9f88 8a                 	TXA				; get dimension value low byte
  4024  9f89 91aa               	STA	(Astrtl),Y		; save dimension value low byte
  4025  9f8b 202ba0             	JSR	LAB_1F7C		; does XY = (Astrtl),Y * (Asptl)
  4026  9f8e 86ba               	STX	Asptl			; save array data size low byte
  4027  9f90 85bb               	STA	Aspth			; save array data size high byte
  4028  9f92 a471               	LDY	ut1_pl		; restore index (saved by subroutine)
  4029  9f94 c65d               	DEC	Dimcnt		; decrement dimensions count
  4030  9f96 d0dd               	BNE	LAB_1EC0		; loop while not = 0
  4031                          
  4032  9f98 65a5               	ADC	Adatah		; add size high byte to first element high byte
  4033                          					; (carry is always clear here)
  4034  9f9a b05d               	BCS	LAB_1F45		; if overflow go do "Out of memory" error
  4035                          
  4036  9f9c 85a5               	STA	Adatah		; save end of array high byte
  4037  9f9e a8                 	TAY				; copy end high byte to Y
  4038  9f9f 8a                 	TXA				; get array size low byte
  4039  9fa0 65a4               	ADC	Adatal		; add array start low byte
  4040  9fa2 9003               	BCC	LAB_1EF3		; branch if no carry
  4041                          
  4042  9fa4 c8                 	INY				; else increment end of array high byte
  4043  9fa5 f052               	BEQ	LAB_1F45		; if overflow go do "Out of memory" error
  4044                          
  4045                          					; set-up mostly complete, now zero the array
  4046                          LAB_1EF3
  4047  9fa7 201691             	JSR	LAB_121F		; check available memory, "Out of memory" error if no room
  4048                          					; addr to check is in AY (low/high)
  4049  9faa 857f               	STA	Earryl		; save array mem end low byte
  4050  9fac 8480               	STY	Earryh		; save array mem end high byte
  4051  9fae a900               	LDA	#$00			; clear byte for array clear
  4052  9fb0 e6bb               	INC	Aspth			; increment array size high byte (now block count)
  4053  9fb2 a4ba               	LDY	Asptl			; get array size low byte (now index to block)
  4054  9fb4 f005               	BEQ	LAB_1F07		; branch if low byte = $00
  4055                          
  4056                          LAB_1F02
  4057  9fb6 88                 	DEY				; decrement index (do 0 to n-1)
  4058  9fb7 91a4               	STA	(Adatal),Y		; zero byte
  4059  9fb9 d0fb               	BNE	LAB_1F02		; loop until this block done
  4060                          
  4061                          LAB_1F07
  4062  9fbb c6a5               	DEC	Adatah		; decrement array pointer high byte
  4063  9fbd c6bb               	DEC	Aspth			; decrement block count high byte
  4064  9fbf d0f5               	BNE	LAB_1F02		; loop until all blocks done
  4065                          
  4066  9fc1 e6a5               	INC	Adatah		; correct for last loop
  4067  9fc3 38                 	SEC				; set carry for subtract
  4068  9fc4 a002               	LDY	#$02			; index to array size low byte
  4069  9fc6 a57f               	LDA	Earryl		; get array mem end low byte
  4070  9fc8 e5aa               	SBC	Astrtl		; subtract array start low byte
  4071  9fca 91aa               	STA	(Astrtl),Y		; save array size low byte
  4072  9fcc c8                 	INY				; index to array size high byte
  4073  9fcd a580               	LDA	Earryh		; get array mem end high byte
  4074  9fcf e5ab               	SBC	Astrth		; subtract array start high byte
  4075  9fd1 91aa               	STA	(Astrtl),Y		; save array size high byte
  4076  9fd3 a55e               	LDA	Defdim		; get default DIM flag
  4077  9fd5 d053               	BNE	LAB_1F7B		; exit (RET) if this was a DIM command
  4078                          
  4079                          					; else, find element
  4080  9fd7 c8                 	INY				; index to # of dimensions
  4081                          
  4082                          LAB_1F24
  4083  9fd8 b1aa               	LDA	(Astrtl),Y		; get array's dimension count
  4084  9fda 855d               	STA	Dimcnt		; save it
  4085                          
  4086                          ; we have found, or built, the array. now we need to find the element
  4087                          
  4088                          LAB_1F28
  4089  9fdc a900               	LDA	#$00			; clear byte
  4090  9fde 85ba               	STA	Asptl			; clear array data pointer low byte
  4091                          LAB_1F2C
  4092  9fe0 85bb               	STA	Aspth			; save array data pointer high byte
  4093  9fe2 c8                 	INY				; increment index (point to array bound high byte)
  4094  9fe3 68                 	PLA				; pull array index low byte
  4095  9fe4 aa                 	TAX				; copy to X
  4096  9fe5 85ae               	STA	FAC1_2		; save index low byte to FAC1 mantissa2
  4097  9fe7 68                 	PLA				; pull array index high byte
  4098  9fe8 85af               	STA	FAC1_3		; save index high byte to FAC1 mantissa3
  4099  9fea d1aa               	CMP	(Astrtl),Y		; compare with array bound high byte
  4100  9fec 900e               	BCC	LAB_1F48		; branch if within bounds
  4101                          
  4102  9fee d006               	BNE	LAB_1F42		; if outside bounds do array bounds error
  4103                          
  4104                          					; else high byte was = so test low bytes
  4105  9ff0 c8                 	INY				; index to array bound low byte
  4106  9ff1 8a                 	TXA				; get array index low byte
  4107  9ff2 d1aa               	CMP	(Astrtl),Y		; compare with array bound low byte
  4108  9ff4 9007               	BCC	LAB_1F49		; branch if within bounds
  4109                          
  4110                          LAB_1F42
  4111  9ff6 4c3d9f             	JMP	LAB_1E85		; else do array bounds error
  4112                          
  4113                          LAB_1F45
  4114  9ff9 4c4591             	JMP	LAB_OMER		; do "Out of memory" error then warm start
  4115                          
  4116                          LAB_1F48
  4117  9ffc c8                 	INY				; index to array bound low byte
  4118                          LAB_1F49
  4119  9ffd a5bb               	LDA	Aspth			; get array data pointer high byte
  4120  9fff 05ba               	ORA	Asptl			; OR with array data pointer low byte
  4121  a001 f00a               	BEQ	LAB_1F5A		; branch if array data pointer = null (skip multiply)
  4122                          
  4123  a003 202ba0             	JSR	LAB_1F7C		; does XY = (Astrtl),Y * (Asptl)
  4124  a006 8a                 	TXA				; get result low byte
  4125  a007 65ae               	ADC	FAC1_2		; add index low byte from FAC1 mantissa2
  4126  a009 aa                 	TAX				; save result low byte
  4127  a00a 98                 	TYA				; get result high byte
  4128  a00b a471               	LDY	ut1_pl		; restore index
  4129                          LAB_1F5A
  4130  a00d 65af               	ADC	FAC1_3		; add index high byte from FAC1 mantissa3
  4131  a00f 86ba               	STX	Asptl			; save array data pointer low byte
  4132  a011 c65d               	DEC	Dimcnt		; decrement dimensions count
  4133  a013 d0cb               	BNE	LAB_1F2C		; loop if dimensions still to do
  4134                          
  4135  a015 06ba               	ASL	Asptl			; array data pointer low byte * 2
  4136  a017 2a                 	ROL				; array data pointer high byte * 2
  4137  a018 06ba               	ASL	Asptl			; array data pointer low byte * 4
  4138  a01a 2a                 	ROL				; array data pointer high byte * 4
  4139  a01b a8                 	TAY				; copy high byte
  4140  a01c a5ba               	LDA	Asptl			; get low byte
  4141  a01e 65a4               	ADC	Adatal		; add array data start pointer low byte
  4142  a020 8595               	STA	Cvaral		; save as current var address low byte
  4143  a022 98                 	TYA				; get high byte back
  4144  a023 65a5               	ADC	Adatah		; add array data start pointer high byte
  4145  a025 8596               	STA	Cvarah		; save as current var address high byte
  4146  a027 a8                 	TAY				; copy high byte to Y
  4147  a028 a595               	LDA	Cvaral		; get current var address low byte
  4148                          LAB_1F7B
  4149  a02a 60                 	RTS
  4150                          
  4151                          ; does XY = (Astrtl),Y * (Asptl)
  4152                          
  4153                          LAB_1F7C
  4154  a02b 8471               	STY	ut1_pl		; save index
  4155  a02d b1aa               	LDA	(Astrtl),Y		; get dimension size low byte
  4156  a02f 8576               	STA	dims_l		; save dimension size low byte
  4157  a031 88                 	DEY				; decrement index
  4158  a032 b1aa               	LDA	(Astrtl),Y		; get dimension size high byte
  4159  a034 8577               	STA	dims_h		; save dimension size high byte
  4160                          
  4161  a036 a910               	LDA	#$10			; count = $10 (16 bit multiply)
  4162  a038 85a8               	STA	numbit		; save bit count
  4163  a03a a200               	LDX	#$00			; clear result low byte
  4164  a03c a000               	LDY	#$00			; clear result high byte
  4165                          LAB_1F8F
  4166  a03e 8a                 	TXA				; get result low byte
  4167  a03f 0a                 	ASL				; *2
  4168  a040 aa                 	TAX				; save result low byte
  4169  a041 98                 	TYA				; get result high byte
  4170  a042 2a                 	ROL				; *2
  4171  a043 a8                 	TAY				; save result high byte
  4172  a044 b0b3               	BCS	LAB_1F45		; if overflow go do "Out of memory" error
  4173                          
  4174  a046 06ba               	ASL	Asptl			; shift multiplier low byte
  4175  a048 26bb               	ROL	Aspth			; shift multiplier high byte
  4176  a04a 900b               	BCC	LAB_1FA8		; skip add if no carry
  4177                          
  4178  a04c 18                 	CLC				; else clear carry for add
  4179  a04d 8a                 	TXA				; get result low byte
  4180  a04e 6576               	ADC	dims_l		; add dimension size low byte
  4181  a050 aa                 	TAX				; save result low byte
  4182  a051 98                 	TYA				; get result high byte
  4183  a052 6577               	ADC	dims_h		; add dimension size high byte
  4184  a054 a8                 	TAY				; save result high byte
  4185  a055 b0a2               	BCS	LAB_1F45		; if overflow go do "Out of memory" error
  4186                          
  4187                          LAB_1FA8
  4188  a057 c6a8               	DEC	numbit		; decrement bit count
  4189  a059 d0e3               	BNE	LAB_1F8F		; loop until all done
  4190                          
  4191  a05b 60                 	RTS
  4192                          
  4193                          ; perform FRE()
  4194                          
  4195                          LAB_FRE
  4196  a05c a55f               	LDA	Dtypef		; get data type flag, $FF=string, $00=numeric
  4197  a05e 1003               	BPL	LAB_1FB4		; branch if numeric
  4198                          
  4199  a060 2055a3             	JSR	LAB_22B6		; pop string off descriptor stack, or from top of string
  4200                          					; space returns with A = length, X=$71=pointer low byte,
  4201                          					; Y=$72=pointer high byte
  4202                          
  4203                          					; FRE(n) was numeric so do this
  4204                          LAB_1FB4
  4205  a063 20f6a1             	JSR	LAB_GARB		; go do garbage collection
  4206  a066 38                 	SEC				; set carry for subtract
  4207  a067 a581               	LDA	Sstorl		; get bottom of string space low byte
  4208  a069 e57f               	SBC	Earryl		; subtract array mem end low byte
  4209  a06b a8                 	TAY				; copy result to Y
  4210  a06c a582               	LDA	Sstorh		; get bottom of string space high byte
  4211  a06e e580               	SBC	Earryh		; subtract array mem end high byte
  4212                          
  4213                          ; save and convert integer AY to FAC1
  4214                          
  4215                          LAB_AYFC
  4216  a070 465f               	LSR	Dtypef		; clear data type flag, $FF=string, $00=numeric
  4217  a072 85ad               	STA	FAC1_1		; save FAC1 mantissa1
  4218  a074 84ae               	STY	FAC1_2		; save FAC1 mantissa2
  4219  a076 a290               	LDX	#$90			; set exponent=2^16 (integer)
  4220  a078 4c19a9             	JMP	LAB_27E3		; set exp=X, clear FAC1_3, normalise and return
  4221                          
  4222                          ; perform POS()
  4223                          
  4224                          LAB_POS
  4225  a07b a40e               	LDY	TPos			; get terminal position
  4226                          
  4227                          ; convert Y to byte in FAC1
  4228                          
  4229                          LAB_1FD0
  4230  a07d a900               	LDA	#$00			; clear high byte
  4231  a07f f0ef               	BEQ	LAB_AYFC		; always save and convert integer AY to FAC1 and return
  4232                          
  4233                          ; check not Direct (used by DEF and INPUT)
  4234                          
  4235                          LAB_CKRN
  4236  a081 a688               	LDX	Clineh		; get current line high byte
  4237  a083 e8                 	INX				; increment it
  4238  a084 d0a4               	BNE	LAB_1F7B		; return if can continue not direct mode
  4239                          
  4240                          					; else do illegal direct error
  4241                          LAB_1FD9
  4242  a086 a216               	LDX	#$16			; error code $16 ("Illegal direct" error)
  4243                          LAB_1FDB
  4244  a088 4c4791             	JMP	LAB_XERR		; go do error #X, then warm start
  4245                          
  4246                          ; perform DEF
  4247                          
  4248                          LAB_DEF
  4249  a08b 20bca0             	JSR	LAB_200B		; check FNx syntax
  4250  a08e 859c               	STA	func_l		; save function pointer low byte
  4251  a090 849d               	STY	func_h		; save function pointer high byte
  4252  a092 2081a0             	JSR	LAB_CKRN		; check not Direct (back here if ok)
  4253  a095 20119c             	JSR	LAB_1BFE		; scan for "(" , else do syntax error then warm start
  4254  a098 a980               	LDA	#$80			; set flag for FNx
  4255  a09a 8561               	STA	Sufnxf		; save subscript/FNx flag
  4256  a09c 20c19d             	JSR	LAB_GVAR		; get (var) address
  4257  a09f 20e79a             	JSR	LAB_CTNM		; check if source is numeric, else do type mismatch
  4258  a0a2 20069c             	JSR	LAB_1BFB		; scan for ")" , else do syntax error then warm start
  4259  a0a5 a9c6               	LDA	#TK_EQUAL		; get = token
  4260  a0a7 20089c             	JSR	LAB_SCCA		; scan for CHR$(A), else do syntax error then warm start
  4261  a0aa a596               	LDA	Cvarah		; get current var address high byte
  4262  a0ac 48                 	PHA				; push it
  4263  a0ad a595               	LDA	Cvaral		; get current var address low byte
  4264  a0af 48                 	PHA				; push it
  4265  a0b0 a5c4               	LDA	Bpntrh		; get BASIC execute pointer high byte
  4266  a0b2 48                 	PHA				; push it
  4267  a0b3 a5c3               	LDA	Bpntrl		; get BASIC execute pointer low byte
  4268  a0b5 48                 	PHA				; push it
  4269  a0b6 20a896             	JSR	LAB_DATA		; go perform DATA
  4270  a0b9 4c2ba1             	JMP	LAB_207A		; put execute pointer and variable pointer into function
  4271                          					; and return
  4272                          
  4273                          ; check FNx syntax
  4274                          
  4275                          LAB_200B
  4276  a0bc a9b3               	LDA	#TK_FN		; get FN" token
  4277  a0be 20089c             	JSR	LAB_SCCA		; scan for CHR$(A) , else do syntax error then warm start
  4278                          					; return character after A
  4279  a0c1 0980               	ORA	#$80			; set FN flag bit
  4280  a0c3 8561               	STA	Sufnxf		; save FN flag so array variable test fails
  4281  a0c5 20c89d             	JSR	LAB_1D12		; search for FN variable
  4282  a0c8 4ce79a             	JMP	LAB_CTNM		; check if source is numeric and return, else do type
  4283                          					; mismatch
  4284                          
  4285                          					; Evaluate FNx
  4286                          LAB_201E
  4287  a0cb 20bca0             	JSR	LAB_200B		; check FNx syntax
  4288  a0ce 48                 	PHA				; push function pointer low byte
  4289  a0cf 98                 	TYA				; copy function pointer high byte
  4290  a0d0 48                 	PHA				; push function pointer high byte
  4291  a0d1 20119c             	JSR	LAB_1BFE		; scan for "(", else do syntax error then warm start
  4292  a0d4 20f89a             	JSR	LAB_EVEX		; evaluate expression
  4293  a0d7 20069c             	JSR	LAB_1BFB		; scan for ")", else do syntax error then warm start
  4294  a0da 20e79a             	JSR	LAB_CTNM		; check if source is numeric, else do type mismatch
  4295  a0dd 68                 	PLA				; pop function pointer high byte
  4296  a0de 859d               	STA	func_h		; restore it
  4297  a0e0 68                 	PLA				; pop function pointer low byte
  4298  a0e1 859c               	STA	func_l		; restore it
  4299  a0e3 a220               	LDX	#$20			; error code $20 ("Undefined function" error)
  4300  a0e5 a003               	LDY	#$03			; index to variable pointer high byte
  4301  a0e7 b19c               	LDA	(func_l),Y		; get variable pointer high byte
  4302  a0e9 f09d               	BEQ	LAB_1FDB		; if zero go do undefined function error
  4303                          
  4304  a0eb 8596               	STA	Cvarah		; save variable address high byte
  4305  a0ed 88                 	DEY				; index to variable address low byte
  4306  a0ee b19c               	LDA	(func_l),Y		; get variable address low byte
  4307  a0f0 8595               	STA	Cvaral		; save variable address low byte
  4308  a0f2 aa                 	TAX				; copy address low byte
  4309                          
  4310                          					; now stack the function variable value before use
  4311  a0f3 c8                 	INY				; index to mantissa_3
  4312                          LAB_2043
  4313  a0f4 b195               	LDA	(Cvaral),Y		; get byte from variable
  4314  a0f6 48                 	PHA				; stack it
  4315  a0f7 88                 	DEY				; decrement index
  4316  a0f8 10fa               	BPL	LAB_2043		; loop until variable stacked
  4317                          
  4318  a0fa a496               	LDY	Cvarah		; get variable address high byte
  4319  a0fc 20bea8             	JSR	LAB_2778		; pack FAC1 (function expression value) into (XY)
  4320                          					; (function variable), return Y=0, always
  4321  a0ff a5c4               	LDA	Bpntrh		; get BASIC execute pointer high byte
  4322  a101 48                 	PHA				; push it
  4323  a102 a5c3               	LDA	Bpntrl		; get BASIC execute pointer low byte
  4324  a104 48                 	PHA				; push it
  4325  a105 b19c               	LDA	(func_l),Y		; get function execute pointer low byte
  4326  a107 85c3               	STA	Bpntrl		; save as BASIC execute pointer low byte
  4327  a109 c8                 	INY				; index to high byte
  4328  a10a b19c               	LDA	(func_l),Y		; get function execute pointer high byte
  4329  a10c 85c4               	STA	Bpntrh		; save as BASIC execute pointer high byte
  4330  a10e a596               	LDA	Cvarah		; get variable address high byte
  4331  a110 48                 	PHA				; push it
  4332  a111 a595               	LDA	Cvaral		; get variable address low byte
  4333  a113 48                 	PHA				; push it
  4334  a114 20e49a             	JSR	LAB_EVNM		; evaluate expression and check is numeric,
  4335                          					; else do type mismatch
  4336  a117 68                 	PLA				; pull variable address low byte
  4337  a118 859c               	STA	func_l		; save variable address low byte
  4338  a11a 68                 	PLA				; pull variable address high byte
  4339  a11b 859d               	STA	func_h		; save variable address high byte
  4340  a11d 20c200             	JSR	LAB_GBYT		; scan memory
  4341  a120 f003               	BEQ	LAB_2074		; branch if null (should be [EOL] marker)
  4342                          
  4343  a122 4c199c             	JMP	LAB_SNER		; else syntax error then warm start
  4344                          
  4345                          ; restore Bpntrl,Bpntrh and function variable from stack
  4346                          
  4347                          LAB_2074
  4348  a125 68                 	PLA				; pull BASIC execute pointer low byte
  4349  a126 85c3               	STA	Bpntrl		; restore BASIC execute pointer low byte
  4350  a128 68                 	PLA				; pull BASIC execute pointer high byte
  4351  a129 85c4               	STA	Bpntrh		; restore BASIC execute pointer high byte
  4352                          
  4353                          ; put execute pointer and variable pointer into function
  4354                          
  4355                          LAB_207A
  4356  a12b a000               	LDY	#$00			; clear index
  4357  a12d 68                 	PLA				; pull BASIC execute pointer low byte
  4358  a12e 919c               	STA	(func_l),Y		; save to function
  4359  a130 c8                 	INY				; increment index
  4360  a131 68                 	PLA				; pull BASIC execute pointer high byte
  4361  a132 919c               	STA	(func_l),Y		; save to function
  4362  a134 c8                 	INY				; increment index
  4363  a135 68                 	PLA				; pull current var address low byte
  4364  a136 919c               	STA	(func_l),Y		; save to function
  4365  a138 c8                 	INY				; increment index
  4366  a139 68                 	PLA				; pull current var address high byte
  4367  a13a 919c               	STA	(func_l),Y		; save to function
  4368  a13c 60                 	RTS
  4369                          
  4370                          ; perform STR$()
  4371                          
  4372                          LAB_STRS
  4373  a13d 20e79a             	JSR	LAB_CTNM		; check if source is numeric, else do type mismatch
  4374  a140 20acaa             	JSR	LAB_296E		; convert FAC1 to string
  4375  a143 a9e3               	LDA	#<Decssp1		; set result string low pointer
  4376  a145 a000               	LDY	#>Decssp1		; set result string high pointer
  4377  a147 f012               	BEQ	LAB_20AE		; print null terminated string to Sutill/Sutilh
  4378                          
  4379                          ; Do string vector
  4380                          ; copy des_pl/h to des_2l/h and make string space A bytes long
  4381                          
  4382                          LAB_209C
  4383  a149 a6ae               	LDX	des_pl		; get descriptor pointer low byte
  4384  a14b a4af               	LDY	des_ph		; get descriptor pointer high byte
  4385  a14d 869e               	STX	des_2l		; save descriptor pointer low byte
  4386  a14f 849f               	STY	des_2h		; save descriptor pointer high byte
  4387                          
  4388                          ; make string space A bytes long
  4389                          ; A=length, X=Sutill=ptr low byte, Y=Sutilh=ptr high byte
  4390                          
  4391                          LAB_MSSP
  4392  a151 20c4a1             	JSR	LAB_2115		; make space in string memory for string A long
  4393                          					; return X=Sutill=ptr low byte, Y=Sutilh=ptr high byte
  4394  a154 86ad               	STX	str_pl		; save string pointer low byte
  4395  a156 84ae               	STY	str_ph		; save string pointer high byte
  4396  a158 85ac               	STA	str_ln		; save length
  4397  a15a 60                 	RTS
  4398                          
  4399                          ; Scan, set up string
  4400                          ; print " terminated string to Sutill/Sutilh
  4401                          
  4402                          LAB_20AE
  4403  a15b a222               	LDX	#$22			; set terminator to "
  4404  a15d 865b               	STX	Srchc			; set search character (terminator 1)
  4405  a15f 865c               	STX	Asrch			; set terminator 2
  4406                          
  4407                          ; print [Srchc] or [Asrch] terminated string to Sutill/Sutilh
  4408                          ; source is AY
  4409                          
  4410                          LAB_20B4
  4411  a161 85b8               	STA	ssptr_l		; store string start low byte
  4412  a163 84b9               	STY	ssptr_h		; store string start high byte
  4413  a165 85ad               	STA	str_pl		; save string pointer low byte
  4414  a167 84ae               	STY	str_ph		; save string pointer high byte
  4415  a169 a0ff               	LDY	#$FF			; set length to -1
  4416                          LAB_20BE
  4417  a16b c8                 	INY				; increment length
  4418  a16c b1b8               	LDA	(ssptr_l),Y		; get byte from string
  4419  a16e f00c               	BEQ	LAB_20CF		; exit loop if null byte [EOS]
  4420                          
  4421  a170 c55b               	CMP	Srchc			; compare with search character (terminator 1)
  4422  a172 f004               	BEQ	LAB_20CB		; branch if terminator
  4423                          
  4424  a174 c55c               	CMP	Asrch			; compare with terminator 2
  4425  a176 d0f3               	BNE	LAB_20BE		; loop if not terminator 2
  4426                          
  4427                          LAB_20CB
  4428  a178 c922               	CMP	#$22			; compare with "
  4429  a17a f001               	BEQ	LAB_20D0		; branch if " (carry set if = !)
  4430                          
  4431                          LAB_20CF
  4432  a17c 18                 	CLC				; clear carry for add (only if [EOL] terminated string)
  4433                          LAB_20D0
  4434  a17d 84ac               	STY	str_ln		; save length in FAC1 exponent
  4435  a17f 98                 	TYA				; copy length to A
  4436  a180 65b8               	ADC	ssptr_l		; add string start low byte
  4437  a182 85ba               	STA	Sendl			; save string end low byte
  4438  a184 a6b9               	LDX	ssptr_h		; get string start high byte
  4439  a186 9001               	BCC	LAB_20DC		; branch if no low byte overflow
  4440                          
  4441  a188 e8                 	INX				; else increment high byte
  4442                          LAB_20DC
  4443  a189 86bb               	STX	Sendh			; save string end high byte
  4444  a18b a5b9               	LDA	ssptr_h		; get string start high byte
  4445  a18d c904               	CMP	#>Ram_base		; compare with start of program memory
  4446  a18f b00b               	BCS	LAB_RTST		; branch if not in utility area
  4447                          
  4448                          					; string in utility area, move to string memory
  4449  a191 98                 	TYA				; copy length to A
  4450  a192 2049a1             	JSR	LAB_209C		; copy des_pl/h to des_2l/h and make string space A bytes
  4451                          					; long
  4452  a195 a6b8               	LDX	ssptr_l		; get string start low byte
  4453  a197 a4b9               	LDY	ssptr_h		; get string start high byte
  4454  a199 2036a3             	JSR	LAB_2298		; store string A bytes long from XY to (Sutill)
  4455                          
  4456                          ; check for space on descriptor stack then ..
  4457                          ; put string address and length on descriptor stack and update stack pointers
  4458                          
  4459                          LAB_RTST
  4460  a19c a665               	LDX	next_s		; get string stack pointer
  4461  a19e e071               	CPX	#des_sk+$09		; compare with max+1
  4462  a1a0 d005               	BNE	LAB_20F8		; branch if space on string stack
  4463                          
  4464                          					; else do string too complex error
  4465  a1a2 a21c               	LDX	#$1C			; error code $1C ("String too complex" error)
  4466                          LAB_20F5
  4467  a1a4 4c4791             	JMP	LAB_XERR		; do error #X, then warm start
  4468                          
  4469                          ; put string address and length on descriptor stack and update stack pointers
  4470                          
  4471                          LAB_20F8
  4472  a1a7 a5ac               	LDA	str_ln		; get string length
  4473  a1a9 9500               	STA	PLUS_0,X		; put on string stack
  4474  a1ab a5ad               	LDA	str_pl		; get string pointer low byte
  4475  a1ad 9501               	STA	PLUS_1,X		; put on string stack
  4476  a1af a5ae               	LDA	str_ph		; get string pointer high byte
  4477  a1b1 9502               	STA	PLUS_2,X		; put on string stack
  4478  a1b3 a000               	LDY	#$00			; clear Y
  4479  a1b5 86ae               	STX	des_pl		; save string descriptor pointer low byte
  4480  a1b7 84af               	STY	des_ph		; save string descriptor pointer high byte (always $00)
  4481  a1b9 88                 	DEY				; Y = $FF
  4482  a1ba 845f               	STY	Dtypef		; save data type flag, $FF=string
  4483  a1bc 8666               	STX	last_sl		; save old stack pointer (current top item)
  4484  a1be e8                 	INX				; update stack pointer
  4485  a1bf e8                 	INX				; update stack pointer
  4486  a1c0 e8                 	INX				; update stack pointer
  4487  a1c1 8665               	STX	next_s		; save new top item value
  4488  a1c3 60                 	RTS
  4489                          
  4490                          ; Build descriptor
  4491                          ; make space in string memory for string A long
  4492                          ; return X=Sutill=ptr low byte, Y=Sutill=ptr high byte
  4493                          
  4494                          LAB_2115
  4495  a1c4 4660               	LSR	Gclctd		; clear garbage collected flag (b7)
  4496                          
  4497                          					; make space for string A long
  4498                          LAB_2117
  4499  a1c6 48                 	PHA				; save string length
  4500  a1c7 49ff               	EOR	#$FF			; complement it
  4501  a1c9 38                 	SEC				; set carry for subtract (twos comp add)
  4502  a1ca 6581               	ADC	Sstorl		; add bottom of string space low byte (subtract length)
  4503  a1cc a482               	LDY	Sstorh		; get bottom of string space high byte
  4504  a1ce b001               	BCS	LAB_2122		; skip decrement if no underflow
  4505                          
  4506  a1d0 88                 	DEY				; decrement bottom of string space high byte
  4507                          LAB_2122
  4508  a1d1 c480               	CPY	Earryh		; compare with array mem end high byte
  4509  a1d3 9011               	BCC	LAB_2137		; do out of memory error if less
  4510                          
  4511  a1d5 d004               	BNE	LAB_212C		; if not = skip next test
  4512                          
  4513  a1d7 c57f               	CMP	Earryl		; compare with array mem end low byte
  4514  a1d9 900b               	BCC	LAB_2137		; do out of memory error if less
  4515                          
  4516                          LAB_212C
  4517  a1db 8581               	STA	Sstorl		; save bottom of string space low byte
  4518  a1dd 8482               	STY	Sstorh		; save bottom of string space high byte
  4519  a1df 8583               	STA	Sutill		; save string utility ptr low byte
  4520  a1e1 8484               	STY	Sutilh		; save string utility ptr high byte
  4521  a1e3 aa                 	TAX				; copy low byte to X
  4522  a1e4 68                 	PLA				; get string length back
  4523  a1e5 60                 	RTS
  4524                          
  4525                          LAB_2137
  4526  a1e6 a20c               	LDX	#$0C			; error code $0C ("Out of memory" error)
  4527  a1e8 a560               	LDA	Gclctd		; get garbage collected flag
  4528  a1ea 30b8               	BMI	LAB_20F5		; if set then do error code X
  4529                          
  4530  a1ec 20f6a1             	JSR	LAB_GARB		; else go do garbage collection
  4531  a1ef a980               	LDA	#$80			; flag for garbage collected
  4532  a1f1 8560               	STA	Gclctd		; set garbage collected flag
  4533  a1f3 68                 	PLA				; pull length
  4534  a1f4 d0d0               	BNE	LAB_2117		; go try again (loop always, length should never be = $00)
  4535                          
  4536                          ; garbage collection routine
  4537                          
  4538                          LAB_GARB
  4539  a1f6 a685               	LDX	Ememl			; get end of mem low byte
  4540  a1f8 a586               	LDA	Ememh			; get end of mem high byte
  4541                          
  4542                          ; re-run routine from last ending
  4543                          
  4544                          LAB_214B
  4545  a1fa 8681               	STX	Sstorl		; set string storage low byte
  4546  a1fc 8582               	STA	Sstorh		; set string storage high byte
  4547  a1fe a000               	LDY	#$00			; clear index
  4548  a200 849d               	STY	garb_h		; clear working pointer high byte (flag no strings to move)
  4549  a202 a57f               	LDA	Earryl		; get array mem end low byte
  4550  a204 a680               	LDX	Earryh		; get array mem end high byte
  4551  a206 85aa               	STA	Histrl		; save as highest string low byte
  4552  a208 86ab               	STX	Histrh		; save as highest string high byte
  4553  a20a a968               	LDA	#des_sk		; set descriptor stack pointer
  4554  a20c 8571               	STA	ut1_pl		; save descriptor stack pointer low byte
  4555  a20e 8472               	STY	ut1_ph		; save descriptor stack pointer high byte ($00)
  4556                          LAB_2161
  4557  a210 c565               	CMP	next_s		; compare with descriptor stack pointer
  4558  a212 f005               	BEQ	LAB_216A		; branch if =
  4559                          
  4560  a214 207aa2             	JSR	LAB_21D7		; go garbage collect descriptor stack
  4561  a217 f0f7               	BEQ	LAB_2161		; loop always
  4562                          
  4563                          					; done stacked strings, now do string vars
  4564                          LAB_216A
  4565  a219 06a0               	ASL	g_step		; set step size = $06
  4566  a21b a57b               	LDA	Svarl			; get start of vars low byte
  4567  a21d a67c               	LDX	Svarh			; get start of vars high byte
  4568  a21f 8571               	STA	ut1_pl		; save as pointer low byte
  4569  a221 8672               	STX	ut1_ph		; save as pointer high byte
  4570                          LAB_2176
  4571  a223 e47e               	CPX	Sarryh		; compare start of arrays high byte
  4572  a225 d004               	BNE	LAB_217E		; branch if no high byte match
  4573                          
  4574  a227 c57d               	CMP	Sarryl		; else compare start of arrays low byte
  4575  a229 f005               	BEQ	LAB_2183		; branch if = var mem end
  4576                          
  4577                          LAB_217E
  4578  a22b 2074a2             	JSR	LAB_21D1		; go garbage collect strings
  4579  a22e f0f3               	BEQ	LAB_2176		; loop always
  4580                          
  4581                          					; done string vars, now do string arrays
  4582                          LAB_2183
  4583  a230 85a4               	STA	Nbendl		; save start of arrays low byte as working pointer
  4584  a232 86a5               	STX	Nbendh		; save start of arrays high byte as working pointer
  4585  a234 a904               	LDA	#$04			; set step size
  4586  a236 85a0               	STA	g_step		; save step size
  4587                          LAB_218B
  4588  a238 a5a4               	LDA	Nbendl		; get pointer low byte
  4589  a23a a6a5               	LDX	Nbendh		; get pointer high byte
  4590                          LAB_218F
  4591  a23c e480               	CPX	Earryh		; compare with array mem end high byte
  4592  a23e d004               	BNE	LAB_219A		; branch if not at end
  4593                          
  4594  a240 c57f               	CMP	Earryl		; else compare with array mem end low byte
  4595  a242 f075               	BEQ	LAB_2216		; tidy up and exit if at end
  4596                          
  4597                          LAB_219A
  4598  a244 8571               	STA	ut1_pl		; save pointer low byte
  4599  a246 8672               	STX	ut1_ph		; save pointer high byte
  4600  a248 a002               	LDY	#$02			; set index
  4601  a24a b171               	LDA	(ut1_pl),Y		; get array size low byte
  4602  a24c 65a4               	ADC	Nbendl		; add start of this array low byte
  4603  a24e 85a4               	STA	Nbendl		; save start of next array low byte
  4604  a250 c8                 	INY				; increment index
  4605  a251 b171               	LDA	(ut1_pl),Y		; get array size high byte
  4606  a253 65a5               	ADC	Nbendh		; add start of this array high byte
  4607  a255 85a5               	STA	Nbendh		; save start of next array high byte
  4608  a257 a001               	LDY	#$01			; set index
  4609  a259 b171               	LDA	(ut1_pl),Y		; get name second byte
  4610  a25b 10db               	BPL	LAB_218B		; skip if not string array
  4611                          
  4612                          ; was string array so ..
  4613                          
  4614  a25d a004               	LDY	#$04			; set index
  4615  a25f b171               	LDA	(ut1_pl),Y		; get # of dimensions
  4616  a261 0a                 	ASL				; *2
  4617  a262 6905               	ADC	#$05			; +5 (array header size)
  4618  a264 20aca2             	JSR	LAB_2208		; go set up for first element
  4619                          LAB_21C4
  4620  a267 e4a5               	CPX	Nbendh		; compare with start of next array high byte
  4621  a269 d004               	BNE	LAB_21CC		; branch if <> (go do this array)
  4622                          
  4623  a26b c5a4               	CMP	Nbendl		; else compare element pointer low byte with next array
  4624                          					; low byte
  4625  a26d f0cd               	BEQ	LAB_218F		; if equal then go do next array
  4626                          
  4627                          LAB_21CC
  4628  a26f 207aa2             	JSR	LAB_21D7		; go defrag array strings
  4629  a272 f0f3               	BEQ	LAB_21C4		; go do next array string (loop always)
  4630                          
  4631                          ; defrag string variables
  4632                          ; enter with XA = variable pointer
  4633                          ; return with XA = next variable pointer
  4634                          
  4635                          LAB_21D1
  4636  a274 c8                 	INY				; increment index (Y was $00)
  4637  a275 b171               	LDA	(ut1_pl),Y		; get var name byte 2
  4638  a277 1030               	BPL	LAB_2206		; if not string, step pointer to next var and return
  4639                          
  4640  a279 c8                 	INY				; else increment index
  4641                          LAB_21D7
  4642  a27a b171               	LDA	(ut1_pl),Y		; get string length
  4643  a27c f02b               	BEQ	LAB_2206		; if null, step pointer to next string and return
  4644                          
  4645  a27e c8                 	INY				; else increment index
  4646  a27f b171               	LDA	(ut1_pl),Y		; get string pointer low byte
  4647  a281 aa                 	TAX				; copy to X
  4648  a282 c8                 	INY				; increment index
  4649  a283 b171               	LDA	(ut1_pl),Y		; get string pointer high byte
  4650  a285 c582               	CMP	Sstorh		; compare bottom of string space high byte
  4651  a287 9006               	BCC	LAB_21EC		; branch if less
  4652                          
  4653  a289 d01e               	BNE	LAB_2206		; if greater, step pointer to next string and return
  4654                          
  4655                          					; high bytes were = so compare low bytes
  4656  a28b e481               	CPX	Sstorl		; compare bottom of string space low byte
  4657  a28d b01a               	BCS	LAB_2206		; if >=, step pointer to next string and return
  4658                          
  4659                          					; string pointer is < string storage pointer (pos in mem)
  4660                          LAB_21EC
  4661  a28f c5ab               	CMP	Histrh		; compare to highest string high byte
  4662  a291 9017               	BCC	LAB_2207		; if <, step pointer to next string and return
  4663                          
  4664  a293 d004               	BNE	LAB_21F6		; if > update pointers, step to next and return
  4665                          
  4666                          					; high bytes were = so compare low bytes
  4667  a295 e4aa               	CPX	Histrl		; compare to highest string low byte
  4668  a297 9011               	BCC	LAB_2207		; if <, step pointer to next string and return
  4669                          
  4670                          					; string is in string memory space
  4671                          LAB_21F6
  4672  a299 86aa               	STX	Histrl		; save as new highest string low byte
  4673  a29b 85ab               	STA	Histrh		; save as new highest string high byte
  4674  a29d a571               	LDA	ut1_pl		; get start of vars(descriptors) low byte
  4675  a29f a672               	LDX	ut1_ph		; get start of vars(descriptors) high byte
  4676  a2a1 859c               	STA	garb_l		; save as working pointer low byte
  4677  a2a3 869d               	STX	garb_h		; save as working pointer high byte
  4678  a2a5 88                 	DEY				; decrement index DIFFERS
  4679  a2a6 88                 	DEY				; decrement index (should point to descriptor start)
  4680  a2a7 84a2               	STY	g_indx		; save index pointer
  4681                          
  4682                          					; step pointer to next string
  4683                          LAB_2206
  4684  a2a9 18                 	CLC				; clear carry for add
  4685                          LAB_2207
  4686  a2aa a5a0               	LDA	g_step		; get step size
  4687                          LAB_2208
  4688  a2ac 6571               	ADC	ut1_pl		; add pointer low byte
  4689  a2ae 8571               	STA	ut1_pl		; save pointer low byte
  4690  a2b0 9002               	BCC	LAB_2211		; branch if no overflow
  4691                          
  4692  a2b2 e672               	INC	ut1_ph		; else increment high byte
  4693                          LAB_2211
  4694  a2b4 a672               	LDX	ut1_ph		; get pointer high byte
  4695  a2b6 a000               	LDY	#$00			; clear Y
  4696  a2b8 60                 	RTS
  4697                          
  4698                          ; search complete, now either exit or set-up and move string
  4699                          
  4700                          LAB_2216
  4701  a2b9 c6a0               	DEC	g_step		; decrement step size (now $03 for descriptor stack)
  4702  a2bb a69d               	LDX	garb_h		; get string to move high byte
  4703  a2bd f0f5               	BEQ	LAB_2211		; exit if nothing to move
  4704                          
  4705  a2bf a4a2               	LDY	g_indx		; get index byte back (points to descriptor)
  4706  a2c1 18                 	CLC				; clear carry for add
  4707  a2c2 b19c               	LDA	(garb_l),Y		; get string length
  4708  a2c4 65aa               	ADC	Histrl		; add highest string low byte
  4709  a2c6 85a6               	STA	Obendl		; save old block end low pointer
  4710  a2c8 a5ab               	LDA	Histrh		; get highest string high byte
  4711  a2ca 6900               	ADC	#$00			; add any carry
  4712  a2cc 85a7               	STA	Obendh		; save old block end high byte
  4713  a2ce a581               	LDA	Sstorl		; get bottom of string space low byte
  4714  a2d0 a682               	LDX	Sstorh		; get bottom of string space high byte
  4715  a2d2 85a4               	STA	Nbendl		; save new block end low byte
  4716  a2d4 86a5               	STX	Nbendh		; save new block end high byte
  4717  a2d6 20d390             	JSR	LAB_11D6		; open up space in memory, don't set array end
  4718  a2d9 a4a2               	LDY	g_indx		; get index byte
  4719  a2db c8                 	INY				; point to descriptor low byte
  4720  a2dc a5a4               	LDA	Nbendl		; get string pointer low byte
  4721  a2de 919c               	STA	(garb_l),Y		; save new string pointer low byte
  4722  a2e0 aa                 	TAX				; copy string pointer low byte
  4723  a2e1 e6a5               	INC	Nbendh		; correct high byte (move sets high byte -1)
  4724  a2e3 a5a5               	LDA	Nbendh		; get new string pointer high byte
  4725  a2e5 c8                 	INY				; point to descriptor high byte
  4726  a2e6 919c               	STA	(garb_l),Y		; save new string pointer high byte
  4727  a2e8 4cfaa1             	JMP	LAB_214B		; re-run routine from last ending
  4728                          					; (but don't collect this string)
  4729                          
  4730                          ; concatenate
  4731                          ; add strings, string 1 is in descriptor des_pl, string 2 is in line
  4732                          
  4733                          LAB_224D
  4734  a2eb a5af               	LDA	des_ph		; get descriptor pointer high byte
  4735  a2ed 48                 	PHA				; put on stack
  4736  a2ee a5ae               	LDA	des_pl		; get descriptor pointer low byte
  4737  a2f0 48                 	PHA				; put on stack
  4738  a2f1 20e49b             	JSR	LAB_GVAL		; get value from line
  4739  a2f4 20e99a             	JSR	LAB_CTST		; check if source is string, else do type mismatch
  4740  a2f7 68                 	PLA				; get descriptor pointer low byte back
  4741  a2f8 85b8               	STA	ssptr_l		; set pointer low byte
  4742  a2fa 68                 	PLA				; get descriptor pointer high byte back
  4743  a2fb 85b9               	STA	ssptr_h		; set pointer high byte
  4744  a2fd a000               	LDY	#$00			; clear index
  4745  a2ff b1b8               	LDA	(ssptr_l),Y		; get length_1 from descriptor
  4746  a301 18                 	CLC				; clear carry for add
  4747  a302 71ae               	ADC	(des_pl),Y		; add length_2
  4748  a304 9005               	BCC	LAB_226D		; branch if no overflow
  4749                          
  4750  a306 a21a               	LDX	#$1A			; else set error code $1A ("String too long" error)
  4751  a308 4c4791             	JMP	LAB_XERR		; do error #X, then warm start
  4752                          
  4753                          LAB_226D
  4754  a30b 2049a1             	JSR	LAB_209C		; copy des_pl/h to des_2l/h and make string space A bytes
  4755                          					; long
  4756  a30e 2028a3             	JSR	LAB_228A		; copy string from descriptor (sdescr) to (Sutill)
  4757  a311 a59e               	LDA	des_2l		; get descriptor pointer low byte
  4758  a313 a49f               	LDY	des_2h		; get descriptor pointer high byte
  4759  a315 2059a3             	JSR	LAB_22BA		; pop (YA) descriptor off stack or from top of string space
  4760                          					; returns with A = length, ut1_pl = pointer low byte,
  4761                          					; ut1_ph = pointer high byte
  4762  a318 203aa3             	JSR	LAB_229C		; store string A bytes long from (ut1_pl) to (Sutill)
  4763  a31b a5b8               	LDA	ssptr_l		;.set descriptor pointer low byte
  4764  a31d a4b9               	LDY	ssptr_h		;.set descriptor pointer high byte
  4765  a31f 2059a3             	JSR	LAB_22BA		; pop (YA) descriptor off stack or from top of string space
  4766                          					; returns with A = length, X=ut1_pl=pointer low byte,
  4767                          					; Y=ut1_ph=pointer high byte
  4768  a322 209ca1             	JSR	LAB_RTST		; check for space on descriptor stack then put string
  4769                          					; address and length on descriptor stack and update stack
  4770                          					; pointers
  4771  a325 4c0f9b             	JMP	LAB_1ADB		;.continue evaluation
  4772                          
  4773                          ; copy string from descriptor (sdescr) to (Sutill)
  4774                          
  4775                          LAB_228A
  4776  a328 a000               	LDY	#$00			; clear index
  4777  a32a b1b8               	LDA	(sdescr),Y		; get string length
  4778  a32c 48                 	PHA				; save on stack
  4779  a32d c8                 	INY				; increment index
  4780  a32e b1b8               	LDA	(sdescr),Y		; get source string pointer low byte
  4781  a330 aa                 	TAX				; copy to X
  4782  a331 c8                 	INY				; increment index
  4783  a332 b1b8               	LDA	(sdescr),Y		; get source string pointer high byte
  4784  a334 a8                 	TAY				; copy to Y
  4785  a335 68                 	PLA				; get length back
  4786                          
  4787                          ; store string A bytes long from YX to (Sutill)
  4788                          
  4789                          LAB_2298
  4790  a336 8671               	STX	ut1_pl		; save source string pointer low byte
  4791  a338 8472               	STY	ut1_ph		; save source string pointer high byte
  4792                          
  4793                          ; store string A bytes long from (ut1_pl) to (Sutill)
  4794                          
  4795                          LAB_229C
  4796  a33a aa                 	TAX				; copy length to index (don't count with Y)
  4797  a33b f014               	BEQ	LAB_22B2		; branch if = $0 (null string) no need to add zero length
  4798                          
  4799  a33d a000               	LDY	#$00			; zero pointer (copy forward)
  4800                          LAB_22A0
  4801  a33f b171               	LDA	(ut1_pl),Y		; get source byte
  4802  a341 9183               	STA	(Sutill),Y		; save destination byte
  4803                          
  4804  a343 c8                 	INY				; increment index
  4805  a344 ca                 	DEX				; decrement counter
  4806  a345 d0f8               	BNE	LAB_22A0		; loop while <> 0
  4807                          
  4808  a347 98                 	TYA				; restore length from Y
  4809                          LAB_22A9
  4810  a348 18                 	CLC				; clear carry for add
  4811  a349 6583               	ADC	Sutill		; add string utility ptr low byte
  4812  a34b 8583               	STA	Sutill		; save string utility ptr low byte
  4813  a34d 9002               	BCC	LAB_22B2		; branch if no carry
  4814                          
  4815  a34f e684               	INC	Sutilh		; else increment string utility ptr high byte
  4816                          LAB_22B2
  4817  a351 60                 	RTS
  4818                          
  4819                          ; evaluate string
  4820                          
  4821                          LAB_EVST
  4822  a352 20e99a             	JSR	LAB_CTST		; check if source is string, else do type mismatch
  4823                          
  4824                          ; pop string off descriptor stack, or from top of string space
  4825                          ; returns with A = length, X=pointer low byte, Y=pointer high byte
  4826                          
  4827                          LAB_22B6
  4828  a355 a5ae               	LDA	des_pl		; get descriptor pointer low byte
  4829  a357 a4af               	LDY	des_ph		; get descriptor pointer high byte
  4830                          
  4831                          ; pop (YA) descriptor off stack or from top of string space
  4832                          ; returns with A = length, X=ut1_pl=pointer low byte, Y=ut1_ph=pointer high byte
  4833                          
  4834                          LAB_22BA
  4835  a359 8571               	STA	ut1_pl		; save descriptor pointer low byte
  4836  a35b 8472               	STY	ut1_ph		; save descriptor pointer high byte
  4837  a35d 208aa3             	JSR	LAB_22EB		; clean descriptor stack, YA = pointer
  4838  a360 08                 	PHP				; save status flags
  4839  a361 a000               	LDY	#$00			; clear index
  4840  a363 b171               	LDA	(ut1_pl),Y		; get length from string descriptor
  4841  a365 48                 	PHA				; put on stack
  4842  a366 c8                 	INY				; increment index
  4843  a367 b171               	LDA	(ut1_pl),Y		; get string pointer low byte from descriptor
  4844  a369 aa                 	TAX				; copy to X
  4845  a36a c8                 	INY				; increment index
  4846  a36b b171               	LDA	(ut1_pl),Y		; get string pointer high byte from descriptor
  4847  a36d a8                 	TAY				; copy to Y
  4848  a36e 68                 	PLA				; get string length back
  4849  a36f 28                 	PLP				; restore status
  4850  a370 d013               	BNE	LAB_22E6		; branch if pointer <> last_sl,last_sh
  4851                          
  4852  a372 c482               	CPY	Sstorh		; compare bottom of string space high byte
  4853  a374 d00f               	BNE	LAB_22E6		; branch if <>
  4854                          
  4855  a376 e481               	CPX	Sstorl		; else compare bottom of string space low byte
  4856  a378 d00b               	BNE	LAB_22E6		; branch if <>
  4857                          
  4858  a37a 48                 	PHA				; save string length
  4859  a37b 18                 	CLC				; clear carry for add
  4860  a37c 6581               	ADC	Sstorl		; add bottom of string space low byte
  4861  a37e 8581               	STA	Sstorl		; save bottom of string space low byte
  4862  a380 9002               	BCC	LAB_22E5		; skip increment if no overflow
  4863                          
  4864  a382 e682               	INC	Sstorh		; increment bottom of string space high byte
  4865                          LAB_22E5
  4866  a384 68                 	PLA				; restore string length
  4867                          LAB_22E6
  4868  a385 8671               	STX	ut1_pl		; save string pointer low byte
  4869  a387 8472               	STY	ut1_ph		; save string pointer high byte
  4870  a389 60                 	RTS
  4871                          
  4872                          ; clean descriptor stack, YA = pointer
  4873                          ; checks if AY is on the descriptor stack, if so does a stack discard
  4874                          
  4875                          LAB_22EB
  4876  a38a c467               	CPY	last_sh		; compare pointer high byte
  4877  a38c d00c               	BNE	LAB_22FB		; exit if <>
  4878                          
  4879  a38e c566               	CMP	last_sl		; compare pointer low byte
  4880  a390 d008               	BNE	LAB_22FB		; exit if <>
  4881                          
  4882  a392 8565               	STA	next_s		; save descriptor stack pointer
  4883  a394 e903               	SBC	#$03			; -3
  4884  a396 8566               	STA	last_sl		; save low byte -3
  4885  a398 a000               	LDY	#$00			; clear high byte
  4886                          LAB_22FB
  4887  a39a 60                 	RTS
  4888                          
  4889                          ; perform CHR$()
  4890                          
  4891                          LAB_CHRS
  4892  a39b 20a6a4             	JSR	LAB_EVBY		; evaluate byte expression, result in X
  4893  a39e 8a                 	TXA				; copy to A
  4894  a39f 48                 	PHA				; save character
  4895  a3a0 a901               	LDA	#$01			; string is single byte
  4896  a3a2 2051a1             	JSR	LAB_MSSP		; make string space A bytes long A=$AC=length,
  4897                          					; X=$AD=Sutill=ptr low byte, Y=$AE=Sutilh=ptr high byte
  4898  a3a5 68                 	PLA				; get character back
  4899  a3a6 a000               	LDY	#$00			; clear index
  4900  a3a8 91ad               	STA	(str_pl),Y		; save byte in string (byte IS string!)
  4901  a3aa 4c9ca1             	JMP	LAB_RTST		; check for space on descriptor stack then put string
  4902                          					; address and length on descriptor stack and update stack
  4903                          					; pointers
  4904                          
  4905                          ; perform LEFT$()
  4906                          
  4907                          LAB_LEFT
  4908  a3ad 48                 	PHA				; push byte parameter
  4909  a3ae 200ea4             	JSR	LAB_236F		; pull string data and byte parameter from stack
  4910                          					; return pointer in des_2l/h, byte in A (and X), Y=0
  4911  a3b1 d19e               	CMP	(des_2l),Y		; compare byte parameter with string length
  4912  a3b3 98                 	TYA				; clear A
  4913  a3b4 f009               	BEQ	LAB_2316		; go do string copy (branch always)
  4914                          
  4915                          ; perform RIGHT$()
  4916                          
  4917                          LAB_RIGHT
  4918  a3b6 48                 	PHA				; push byte parameter
  4919  a3b7 200ea4             	JSR	LAB_236F		; pull string data and byte parameter from stack
  4920                          					; return pointer in des_2l/h, byte in A (and X), Y=0
  4921  a3ba 18                 	CLC				; clear carry for add-1
  4922  a3bb f19e               	SBC	(des_2l),Y		; subtract string length
  4923  a3bd 49ff               	EOR	#$FF			; invert it (A=LEN(expression$)-l)
  4924                          
  4925                          LAB_2316
  4926  a3bf 9004               	BCC	LAB_231C		; branch if string length > byte parameter
  4927                          
  4928  a3c1 b19e               	LDA	(des_2l),Y		; else make parameter = length
  4929  a3c3 aa                 	TAX				; copy to byte parameter copy
  4930  a3c4 98                 	TYA				; clear string start offset
  4931                          LAB_231C
  4932  a3c5 48                 	PHA				; save string start offset
  4933                          LAB_231D
  4934  a3c6 8a                 	TXA				; copy byte parameter (or string length if <)
  4935                          LAB_231E
  4936  a3c7 48                 	PHA				; save string length
  4937  a3c8 2051a1             	JSR	LAB_MSSP		; make string space A bytes long A=$AC=length,
  4938                          					; X=$AD=Sutill=ptr low byte, Y=$AE=Sutilh=ptr high byte
  4939  a3cb a59e               	LDA	des_2l		; get descriptor pointer low byte
  4940  a3cd a49f               	LDY	des_2h		; get descriptor pointer high byte
  4941  a3cf 2059a3             	JSR	LAB_22BA		; pop (YA) descriptor off stack or from top of string space
  4942                          					; returns with A = length, X=ut1_pl=pointer low byte,
  4943                          					; Y=ut1_ph=pointer high byte
  4944  a3d2 68                 	PLA				; get string length back
  4945  a3d3 a8                 	TAY				; copy length to Y
  4946  a3d4 68                 	PLA				; get string start offset back
  4947  a3d5 18                 	CLC				; clear carry for add
  4948  a3d6 6571               	ADC	ut1_pl		; add start offset to string start pointer low byte
  4949  a3d8 8571               	STA	ut1_pl		; save string start pointer low byte
  4950  a3da 9002               	BCC	LAB_2335		; branch if no overflow
  4951                          
  4952  a3dc e672               	INC	ut1_ph		; else increment string start pointer high byte
  4953                          LAB_2335
  4954  a3de 98                 	TYA				; copy length to A
  4955  a3df 203aa3             	JSR	LAB_229C		; store string A bytes long from (ut1_pl) to (Sutill)
  4956  a3e2 4c9ca1             	JMP	LAB_RTST		; check for space on descriptor stack then put string
  4957                          					; address and length on descriptor stack and update stack
  4958                          					; pointers
  4959                          
  4960                          ; perform MID$()
  4961                          
  4962                          LAB_MIDS
  4963  a3e5 48                 	PHA				; push byte parameter
  4964  a3e6 a9ff               	LDA	#$FF			; set default length = 255
  4965  a3e8 85af               	STA	mids_l		; save default length
  4966  a3ea 20c200             	JSR	LAB_GBYT		; scan memory
  4967  a3ed c929               	CMP	#')'			; compare with ")"
  4968  a3ef f006               	BEQ	LAB_2358		; branch if = ")" (skip second byte get)
  4969                          
  4970  a3f1 20159c             	JSR	LAB_1C01		; scan for "," , else do syntax error then warm start
  4971  a3f4 20a3a4             	JSR	LAB_GTBY		; get byte parameter (use copy in mids_l)
  4972                          LAB_2358
  4973  a3f7 200ea4             	JSR	LAB_236F		; pull string data and byte parameter from stack
  4974                          					; return pointer in des_2l/h, byte in A (and X), Y=0
  4975  a3fa ca                 	DEX				; decrement start index
  4976  a3fb 8a                 	TXA				; copy to A
  4977  a3fc 48                 	PHA				; save string start offset
  4978  a3fd 18                 	CLC				; clear carry for sub-1
  4979  a3fe a200               	LDX	#$00			; clear output string length
  4980  a400 f19e               	SBC	(des_2l),Y		; subtract string length
  4981  a402 b0c2               	BCS	LAB_231D		; if start>string length go do null string
  4982                          
  4983  a404 49ff               	EOR	#$FF			; complement -length
  4984  a406 c5af               	CMP	mids_l		; compare byte parameter
  4985  a408 90bd               	BCC	LAB_231E		; if length>remaining string go do RIGHT$
  4986                          
  4987  a40a a5af               	LDA	mids_l		; get length byte
  4988  a40c b0b9               	BCS	LAB_231E		; go do string copy (branch always)
  4989                          
  4990                          ; pull string data and byte parameter from stack
  4991                          ; return pointer in des_2l/h, byte in A (and X), Y=0
  4992                          
  4993                          LAB_236F
  4994  a40e 20069c             	JSR	LAB_1BFB		; scan for ")" , else do syntax error then warm start
  4995  a411 68                 	PLA				; pull return address low byte (return address)
  4996  a412 85a2               	STA	Fnxjpl		; save functions jump vector low byte
  4997  a414 68                 	PLA				; pull return address high byte (return address)
  4998  a415 85a3               	STA	Fnxjph		; save functions jump vector high byte
  4999  a417 68                 	PLA				; pull byte parameter
  5000  a418 aa                 	TAX				; copy byte parameter to X
  5001  a419 68                 	PLA				; pull string pointer low byte
  5002  a41a 859e               	STA	des_2l		; save it
  5003  a41c 68                 	PLA				; pull string pointer high byte
  5004  a41d 859f               	STA	des_2h		; save it
  5005  a41f a000               	LDY	#$00			; clear index
  5006  a421 8a                 	TXA				; copy byte parameter
  5007  a422 f079               	BEQ	LAB_23A8		; if null do function call error then warm start
  5008                          
  5009  a424 e6a2               	INC	Fnxjpl		; increment function jump vector low byte
  5010                          					; (JSR pushes return addr-1. this is all very nice
  5011                          					; but will go tits up if either call is on a page
  5012                          					; boundary!)
  5013  a426 6ca200             	JMP	(Fnxjpl)		; in effect, RTS
  5014                          
  5015                          ; perform LCASE$()
  5016                          
  5017                          LAB_LCASE
  5018  a429 2052a3             	JSR	LAB_EVST		; evaluate string
  5019  a42c 85ac               	STA	str_ln		; set string length
  5020  a42e a8                 	TAY				; copy length to Y
  5021  a42f f038               	BEQ	NoString		; branch if null string
  5022                          
  5023  a431 2051a1             	JSR	LAB_MSSP		; make string space A bytes long A=length,
  5024                          					; X=Sutill=ptr low byte, Y=Sutilh=ptr high byte
  5025  a434 86ad               	STX	str_pl		; save string pointer low byte
  5026  a436 84ae               	STY	str_ph		; save string pointer high byte
  5027  a438 a8                 	TAY				; get string length back
  5028                          
  5029                          LC_loop
  5030  a439 88                 	DEY				; decrement index
  5031  a43a b171               	LDA	(ut1_pl),Y		; get byte from string
  5032  a43c 20399e             	JSR	LAB_1D82		; is character "A" to "Z"
  5033  a43f 9002               	BCC	NoUcase		; branch if not upper case alpha
  5034                          
  5035  a441 0920               	ORA	#$20			; convert upper to lower case
  5036                          NoUcase
  5037  a443 9183               	STA	(Sutill),Y		; save byte back to string
  5038  a445 98                 	TYA				; test index
  5039  a446 d0f1               	BNE	LC_loop		; loop if not all done
  5040                          
  5041  a448 f01f               	BEQ	NoString		; tidy up and exit, branch always
  5042                          
  5043                          ; perform UCASE$()
  5044                          
  5045                          LAB_UCASE
  5046  a44a 2052a3             	JSR	LAB_EVST		; evaluate string
  5047  a44d 85ac               	STA	str_ln		; set string length
  5048  a44f a8                 	TAY				; copy length to Y
  5049  a450 f017               	BEQ	NoString		; branch if null string
  5050                          
  5051  a452 2051a1             	JSR	LAB_MSSP		; make string space A bytes long A=length,
  5052                          					; X=Sutill=ptr low byte, Y=Sutilh=ptr high byte
  5053  a455 86ad               	STX	str_pl		; save string pointer low byte
  5054  a457 84ae               	STY	str_ph		; save string pointer high byte
  5055  a459 a8                 	TAY				; get string length back
  5056                          
  5057                          UC_loop
  5058  a45a 88                 	DEY				; decrement index
  5059  a45b b171               	LDA	(ut1_pl),Y		; get byte from string
  5060  a45d 20359e             	JSR	LAB_CASC		; is character "a" to "z" (or "A" to "Z")
  5061  a460 9002               	BCC	NoLcase		; branch if not alpha
  5062                          
  5063  a462 29df               	AND	#$DF			; convert lower to upper case
  5064                          NoLcase
  5065  a464 9183               	STA	(Sutill),Y		; save byte back to string
  5066  a466 98                 	TYA				; test index
  5067  a467 d0f1               	BNE	UC_loop		; loop if not all done
  5068                          
  5069                          NoString
  5070  a469 4c9ca1             	JMP	LAB_RTST		; check for space on descriptor stack then put string
  5071                          					; address and length on descriptor stack and update stack
  5072                          					; pointers
  5073                          
  5074                          ; perform SADD()
  5075                          
  5076                          LAB_SADD
  5077  a46c 20bc00             	JSR	LAB_IGBY		; increment and scan memory
  5078  a46f 20c19d             	JSR	LAB_GVAR		; get var address
  5079                          
  5080  a472 20069c             	JSR	LAB_1BFB		; scan for ")", else do syntax error then warm start
  5081  a475 20e99a             	JSR	LAB_CTST		; check if source is string, else do type mismatch
  5082                          
  5083  a478 a002               	LDY	#$02			; index to string pointer high byte
  5084  a47a b195               	LDA	(Cvaral),Y		; get string pointer high byte
  5085  a47c aa                 	TAX				; copy string pointer high byte to X
  5086  a47d 88                 	DEY				; index to string pointer low byte
  5087  a47e b195               	LDA	(Cvaral),Y		; get string pointer low byte
  5088  a480 a8                 	TAY				; copy string pointer low byte to Y
  5089  a481 8a                 	TXA				; copy string pointer high byte to A
  5090  a482 4c70a0             	JMP	LAB_AYFC		; save and convert integer AY to FAC1 and return
  5091                          
  5092                          ; perform LEN()
  5093                          
  5094                          LAB_LENS
  5095  a485 208ba4             	JSR	LAB_ESGL		; evaluate string, get length in A (and Y)
  5096  a488 4c7da0             	JMP	LAB_1FD0		; convert Y to byte in FAC1 and return
  5097                          
  5098                          ; evaluate string, get length in Y
  5099                          
  5100                          LAB_ESGL
  5101  a48b 2052a3             	JSR	LAB_EVST		; evaluate string
  5102  a48e a8                 	TAY				; copy length to Y
  5103  a48f 60                 	RTS
  5104                          
  5105                          ; perform ASC()
  5106                          
  5107                          LAB_ASC
  5108  a490 208ba4             	JSR	LAB_ESGL		; evaluate string, get length in A (and Y)
  5109  a493 f008               	BEQ	LAB_23A8		; if null do function call error then warm start
  5110                          
  5111  a495 a000               	LDY	#$00			; set index to first character
  5112  a497 b171               	LDA	(ut1_pl),Y		; get byte
  5113  a499 a8                 	TAY				; copy to Y
  5114  a49a 4c7da0             	JMP	LAB_1FD0		; convert Y to byte in FAC1 and return
  5115                          
  5116                          ; do function call error then warm start
  5117                          
  5118                          LAB_23A8
  5119  a49d 4c409f             	JMP	LAB_FCER		; do function call error then warm start
  5120                          
  5121                          ; scan and get byte parameter
  5122                          
  5123                          LAB_SGBY
  5124  a4a0 20bc00             	JSR	LAB_IGBY		; increment and scan memory
  5125                          
  5126                          ; get byte parameter
  5127                          
  5128                          LAB_GTBY
  5129  a4a3 20e49a             	JSR	LAB_EVNM		; evaluate expression and check is numeric,
  5130                          					; else do type mismatch
  5131                          
  5132                          ; evaluate byte expression, result in X
  5133                          
  5134                          LAB_EVBY
  5135  a4a6 20b99e             	JSR	LAB_EVPI		; evaluate integer expression (no check)
  5136                          
  5137  a4a9 a4ae               	LDY	FAC1_2		; get FAC1 mantissa2
  5138  a4ab d0f0               	BNE	LAB_23A8		; if top byte <> 0 do function call error then warm start
  5139                          
  5140  a4ad a6af               	LDX	FAC1_3		; get FAC1 mantissa3
  5141  a4af 4cc200             	JMP	LAB_GBYT		; scan memory and return
  5142                          
  5143                          ; perform VAL()
  5144                          
  5145                          LAB_VAL
  5146  a4b2 208ba4             	JSR	LAB_ESGL		; evaluate string, get length in A (and Y)
  5147  a4b5 d003               	BNE	LAB_23C5		; branch if not null string
  5148                          
  5149                          					; string was null so set result = $00
  5150  a4b7 4c67a6             	JMP	LAB_24F1		; clear FAC1 exponent and sign and return
  5151                          
  5152                          LAB_23C5
  5153  a4ba a6c3               	LDX	Bpntrl		; get BASIC execute pointer low byte
  5154  a4bc a4c4               	LDY	Bpntrh		; get BASIC execute pointer high byte
  5155  a4be 86ba               	STX	Btmpl			; save BASIC execute pointer low byte
  5156  a4c0 84bb               	STY	Btmph			; save BASIC execute pointer high byte
  5157  a4c2 a671               	LDX	ut1_pl		; get string pointer low byte
  5158  a4c4 86c3               	STX	Bpntrl		; save as BASIC execute pointer low byte
  5159  a4c6 18                 	CLC				; clear carry
  5160  a4c7 6571               	ADC	ut1_pl		; add string length
  5161  a4c9 8573               	STA	ut2_pl		; save string end low byte
  5162  a4cb a572               	LDA	ut1_ph		; get string pointer high byte
  5163  a4cd 85c4               	STA	Bpntrh		; save as BASIC execute pointer high byte
  5164  a4cf 6900               	ADC	#$00			; add carry to high byte
  5165  a4d1 8574               	STA	ut2_ph		; save string end high byte
  5166  a4d3 a000               	LDY	#$00			; set index to $00
  5167  a4d5 b173               	LDA	(ut2_pl),Y		; get string end +1 byte
  5168  a4d7 48                 	PHA				; push it
  5169  a4d8 98                 	TYA				; clear A
  5170  a4d9 9173               	STA	(ut2_pl),Y		; terminate string with $00
  5171  a4db 20c200             	JSR	LAB_GBYT		; scan memory
  5172  a4de 20bda9             	JSR	LAB_2887		; get FAC1 from string
  5173  a4e1 68                 	PLA				; restore string end +1 byte
  5174  a4e2 a000               	LDY	#$00			; set index to zero
  5175  a4e4 9173               	STA	(ut2_pl),Y		; put string end byte back
  5176                          
  5177                          ; restore BASIC execute pointer from temp (Btmpl/Btmph)
  5178                          
  5179                          LAB_23F3
  5180  a4e6 a6ba               	LDX	Btmpl			; get BASIC execute pointer low byte back
  5181  a4e8 a4bb               	LDY	Btmph			; get BASIC execute pointer high byte back
  5182  a4ea 86c3               	STX	Bpntrl		; save BASIC execute pointer low byte
  5183  a4ec 84c4               	STY	Bpntrh		; save BASIC execute pointer high byte
  5184  a4ee 60                 	RTS
  5185                          
  5186                          ; get two parameters for POKE or WAIT
  5187                          
  5188                          LAB_GADB
  5189  a4ef 20e49a             	JSR	LAB_EVNM		; evaluate expression and check is numeric,
  5190                          					; else do type mismatch
  5191  a4f2 2008a5             	JSR	LAB_F2FX		; save integer part of FAC1 in temporary integer
  5192                          
  5193                          ; scan for "," and get byte, else do Syntax error then warm start
  5194                          
  5195                          LAB_SCGB
  5196  a4f5 20159c             	JSR	LAB_1C01		; scan for "," , else do syntax error then warm start
  5197  a4f8 a512               	LDA	Itemph		; save temporary integer high byte
  5198  a4fa 48                 	PHA				; on stack
  5199  a4fb a511               	LDA	Itempl		; save temporary integer low byte
  5200  a4fd 48                 	PHA				; on stack
  5201  a4fe 20a3a4             	JSR	LAB_GTBY		; get byte parameter
  5202  a501 68                 	PLA				; pull low byte
  5203  a502 8511               	STA	Itempl		; restore temporary integer low byte
  5204  a504 68                 	PLA				; pull high byte
  5205  a505 8512               	STA	Itemph		; restore temporary integer high byte
  5206  a507 60                 	RTS
  5207                          
  5208                          ; convert float to fixed routine. accepts any value that fits in 24 bits, +ve or
  5209                          ; -ve and converts it into a right truncated integer in Itempl and Itemph
  5210                          
  5211                          ; save unsigned 16 bit integer part of FAC1 in temporary integer
  5212                          
  5213                          LAB_F2FX
  5214  a508 a5ac               	LDA	FAC1_e		; get FAC1 exponent
  5215  a50a c998               	CMP	#$98			; compare with exponent = 2^24
  5216  a50c b08f               	BCS	LAB_23A8		; if >= do function call error then warm start
  5217                          
  5218                          LAB_F2FU
  5219  a50e 2067a9             	JSR	LAB_2831		; convert FAC1 floating-to-fixed
  5220  a511 a5ae               	LDA	FAC1_2		; get FAC1 mantissa2
  5221  a513 a4af               	LDY	FAC1_3		; get FAC1 mantissa3
  5222  a515 8411               	STY	Itempl		; save temporary integer low byte
  5223  a517 8512               	STA	Itemph		; save temporary integer high byte
  5224  a519 60                 	RTS
  5225                          
  5226                          ; perform PEEK()
  5227                          
  5228                          LAB_PEEK
  5229  a51a 2008a5             	JSR	LAB_F2FX		; save integer part of FAC1 in temporary integer
  5230  a51d a200               	LDX	#$00			; clear index
  5231  a51f a111               	LDA	(Itempl,X)		; get byte via temporary integer (addr)
  5232  a521 a8                 	TAY				; copy byte to Y
  5233  a522 4c7da0             	JMP	LAB_1FD0		; convert Y to byte in FAC1 and return
  5234                          
  5235                          ; perform POKE
  5236                          
  5237                          LAB_POKE
  5238  a525 20efa4             	JSR	LAB_GADB		; get two parameters for POKE or WAIT
  5239  a528 8a                 	TXA				; copy byte argument to A
  5240  a529 a200               	LDX	#$00			; clear index
  5241  a52b 8111               	STA	(Itempl,X)		; save byte via temporary integer (addr)
  5242  a52d 60                 	RTS
  5243                          
  5244                          ; perform DEEK()
  5245                          
  5246                          LAB_DEEK
  5247  a52e 2008a5             	JSR	LAB_F2FX		; save integer part of FAC1 in temporary integer
  5248  a531 a200               	LDX	#$00			; clear index
  5249  a533 a111               	LDA	(Itempl,X)		; PEEK low byte
  5250  a535 a8                 	TAY				; copy to Y
  5251  a536 e611               	INC	Itempl		; increment pointer low byte
  5252  a538 d002               	BNE	Deekh			; skip high increment if no rollover
  5253                          
  5254  a53a e612               	INC	Itemph		; increment pointer high byte
  5255                          Deekh
  5256  a53c a111               	LDA	(Itempl,X)		; PEEK high byte
  5257  a53e 4c70a0             	JMP	LAB_AYFC		; save and convert integer AY to FAC1 and return
  5258                          
  5259                          ; perform DOKE
  5260                          
  5261                          LAB_DOKE
  5262  a541 20e49a             	JSR	LAB_EVNM		; evaluate expression and check is numeric,
  5263                          					; else do type mismatch
  5264  a544 2008a5             	JSR	LAB_F2FX		; convert floating-to-fixed
  5265                          
  5266  a547 8497               	STY	Frnxtl		; save pointer low byte (float to fixed returns word in AY)
  5267  a549 8598               	STA	Frnxth		; save pointer high byte
  5268                          
  5269  a54b 20159c             	JSR	LAB_1C01		; scan for "," , else do syntax error then warm start
  5270  a54e 20e49a             	JSR	LAB_EVNM		; evaluate expression and check is numeric,
  5271                          					; else do type mismatch
  5272  a551 2008a5             	JSR	LAB_F2FX		; convert floating-to-fixed
  5273                          
  5274  a554 98                 	TYA				; copy value low byte (float to fixed returns word in AY)
  5275  a555 a200               	LDX	#$00			; clear index
  5276  a557 8197               	STA	(Frnxtl,X)		; POKE low byte
  5277  a559 e697               	INC	Frnxtl		; increment pointer low byte
  5278  a55b d002               	BNE	Dokeh			; skip high increment if no rollover
  5279                          
  5280  a55d e698               	INC	Frnxth		; increment pointer high byte
  5281                          Dokeh
  5282  a55f a512               	LDA	Itemph		; get value high byte
  5283  a561 8197               	STA	(Frnxtl,X)		; POKE high byte
  5284  a563 4cc200             	JMP	LAB_GBYT		; scan memory and return
  5285                          
  5286                          ; perform SWAP
  5287                          
  5288                          LAB_SWAP
  5289  a566 20c19d             	JSR	LAB_GVAR		; get var1 address
  5290  a569 8597               	STA	Lvarpl		; save var1 address low byte
  5291  a56b 8498               	STY	Lvarph		; save var1 address high byte
  5292  a56d a55f               	LDA	Dtypef		; get data type flag, $FF=string, $00=numeric
  5293  a56f 48                 	PHA				; save data type flag
  5294                          
  5295  a570 20159c             	JSR	LAB_1C01		; scan for "," , else do syntax error then warm start
  5296  a573 20c19d             	JSR	LAB_GVAR		; get var2 address (pointer in Cvaral/h)
  5297  a576 68                 	PLA				; pull var1 data type flag
  5298  a577 455f               	EOR	Dtypef		; compare with var2 data type
  5299  a579 1010               	BPL	SwapErr		; exit if not both the same type
  5300                          
  5301  a57b a003               	LDY	#$03			; four bytes to swap (either value or descriptor+1)
  5302                          SwapLp
  5303  a57d b197               	LDA	(Lvarpl),Y		; get byte from var1
  5304  a57f aa                 	TAX				; save var1 byte
  5305  a580 b195               	LDA	(Cvaral),Y		; get byte from var2
  5306  a582 9197               	STA	(Lvarpl),Y		; save byte to var1
  5307  a584 8a                 	TXA				; restore var1 byte
  5308  a585 9195               	STA	(Cvaral),Y		; save byte to var2
  5309  a587 88                 	DEY				; decrement index
  5310  a588 10f3               	BPL	SwapLp		; loop until done
  5311                          
  5312  a58a 60                 	RTS
  5313                          
  5314                          SwapErr
  5315  a58b 4cf39a             	JMP	LAB_1ABC		; do "Type mismatch" error then warm start
  5316                          
  5317                          ; perform CALL
  5318                          
  5319                          LAB_CALL
  5320  a58e 20e49a             	JSR	LAB_EVNM		; evaluate expression and check is numeric,
  5321                          					; else do type mismatch
  5322  a591 2008a5             	JSR	LAB_F2FX		; convert floating-to-fixed
  5323  a594 a9a5               	LDA	#>CallExit		; set return address high byte
  5324  a596 48                 	PHA				; put on stack
  5325  a597 a99c               	LDA	#<CallExit-1	; set return address low byte
  5326  a599 48                 	PHA				; put on stack
  5327  a59a 6c1100             	JMP	(Itempl)		; do indirect jump to user routine
  5328                          
  5329                          ; if the called routine exits correctly then it will return to here. this will then get
  5330                          ; the next byte for the interpreter and return
  5331                          
  5332                          CallExit
  5333  a59d 4cc200             	JMP	LAB_GBYT		; scan memory and return
  5334                          
  5335                          ; perform WAIT
  5336                          
  5337                          LAB_WAIT
  5338  a5a0 20efa4             	JSR	LAB_GADB		; get two parameters for POKE or WAIT
  5339  a5a3 8697               	STX	Frnxtl		; save byte
  5340  a5a5 a200               	LDX	#$00			; clear mask
  5341  a5a7 20c200             	JSR	LAB_GBYT		; scan memory
  5342  a5aa f003               	BEQ	LAB_2441		; skip if no third argument
  5343                          
  5344  a5ac 20f5a4             	JSR	LAB_SCGB		; scan for "," and get byte, else SN error then warm start
  5345                          LAB_2441
  5346  a5af 8698               	STX	Frnxth		; save EOR argument
  5347                          LAB_2445
  5348  a5b1 b111               	LDA	(Itempl),Y		; get byte via temporary integer (addr)
  5349  a5b3 4598               	EOR	Frnxth		; EOR with second argument (mask)
  5350  a5b5 2597               	AND	Frnxtl		; AND with first argument (byte)
  5351  a5b7 f0f8               	BEQ	LAB_2445		; loop if result is zero
  5352                          
  5353                          LAB_244D
  5354  a5b9 60                 	RTS
  5355                          
  5356                          ; perform subtraction, FAC1 from (AY)
  5357                          
  5358                          LAB_2455
  5359  a5ba 20a2a7             	JSR	LAB_264D		; unpack memory (AY) into FAC2
  5360                          
  5361                          ; perform subtraction, FAC1 from FAC2
  5362                          
  5363                          LAB_SUBTRACT
  5364  a5bd a5b0               	LDA	FAC1_s		; get FAC1 sign (b7)
  5365  a5bf 49ff               	EOR	#$FF			; complement it
  5366  a5c1 85b0               	STA	FAC1_s		; save FAC1 sign (b7)
  5367  a5c3 45b7               	EOR	FAC2_s		; EOR with FAC2 sign (b7)
  5368  a5c5 85b8               	STA	FAC_sc		; save sign compare (FAC1 EOR FAC2)
  5369  a5c7 a5ac               	LDA	FAC1_e		; get FAC1 exponent
  5370  a5c9 4cd8a5             	JMP	LAB_ADD		; go add FAC2 to FAC1
  5371                          
  5372                          ; perform addition
  5373                          
  5374                          LAB_2467
  5375  a5cc 20f1a6             	JSR	LAB_257B		; shift FACX A times right (>8 shifts)
  5376  a5cf 904d               	BCC	LAB_24A8		;.go subtract mantissas
  5377                          
  5378                          ; add 0.5 to FAC1
  5379                          
  5380                          LAB_244E
  5381  a5d1 a908               	LDA	#<LAB_2A96		; set 0.5 pointer low byte
  5382  a5d3 a0b2               	LDY	#>LAB_2A96		; set 0.5 pointer high byte
  5383                          
  5384                          ; add (AY) to FAC1
  5385                          
  5386                          LAB_246C
  5387  a5d5 20a2a7             	JSR	LAB_264D		; unpack memory (AY) into FAC2
  5388                          
  5389                          ; add FAC2 to FAC1
  5390                          
  5391                          LAB_ADD
  5392  a5d8 d010               	BNE	LAB_2474		; branch if FAC1 was not zero
  5393                          
  5394                          ; copy FAC2 to FAC1
  5395                          
  5396                          LAB_279B
  5397  a5da a5b7               	LDA	FAC2_s		; get FAC2 sign (b7)
  5398                          
  5399                          ; save FAC1 sign and copy ABS(FAC2) to FAC1
  5400                          
  5401                          LAB_279D
  5402  a5dc 85b0               	STA	FAC1_s		; save FAC1 sign (b7)
  5403  a5de a204               	LDX	#$04			; 4 bytes to copy
  5404                          LAB_27A1
  5405  a5e0 b5b2               	LDA	FAC1_o,X		; get byte from FAC2,X
  5406  a5e2 95ab               	STA	FAC1_e-1,X		; save byte at FAC1,X
  5407  a5e4 ca                 	DEX				; decrement count
  5408  a5e5 d0f9               	BNE	LAB_27A1		; loop if not all done
  5409                          
  5410  a5e7 86b9               	STX	FAC1_r		; clear FAC1 rounding byte
  5411  a5e9 60                 	RTS
  5412                          
  5413                          					; FAC1 is non zero
  5414                          LAB_2474
  5415  a5ea a6b9               	LDX	FAC1_r		; get FAC1 rounding byte
  5416  a5ec 86a3               	STX	FAC2_r		; save as FAC2 rounding byte
  5417  a5ee a2b3               	LDX	#FAC2_e		; set index to FAC2 exponent addr
  5418  a5f0 a5b3               	LDA	FAC2_e		; get FAC2 exponent
  5419                          LAB_247C
  5420  a5f2 a8                 	TAY				; copy exponent
  5421  a5f3 f0c4               	BEQ	LAB_244D		; exit if zero
  5422                          
  5423  a5f5 38                 	SEC				; set carry for subtract
  5424  a5f6 e5ac               	SBC	FAC1_e		; subtract FAC1 exponent
  5425  a5f8 f024               	BEQ	LAB_24A8		; branch if = (go add mantissa)
  5426                          
  5427  a5fa 9012               	BCC	LAB_2498		; branch if <
  5428                          
  5429                          					; FAC2>FAC1
  5430  a5fc 84ac               	STY	FAC1_e		; save FAC1 exponent
  5431  a5fe a4b7               	LDY	FAC2_s		; get FAC2 sign (b7)
  5432  a600 84b0               	STY	FAC1_s		; save FAC1 sign (b7)
  5433  a602 49ff               	EOR	#$FF			; complement A
  5434  a604 6900               	ADC	#$00			; +1 (twos complement, carry is set)
  5435  a606 a000               	LDY	#$00			; clear Y
  5436  a608 84a3               	STY	FAC2_r		; clear FAC2 rounding byte
  5437  a60a a2ac               	LDX	#FAC1_e		; set index to FAC1 exponent addr
  5438  a60c d004               	BNE	LAB_249C		; branch always
  5439                          
  5440                          LAB_2498
  5441  a60e a000               	LDY	#$00			; clear Y
  5442  a610 84b9               	STY	FAC1_r		; clear FAC1 rounding byte
  5443                          LAB_249C
  5444  a612 c9f9               	CMP	#$F9			; compare exponent diff with $F9
  5445  a614 30b6               	BMI	LAB_2467		; branch if range $79-$F8
  5446                          
  5447  a616 a8                 	TAY				; copy exponent difference to Y
  5448  a617 a5b9               	LDA	FAC1_r		; get FAC1 rounding byte
  5449  a619 5601               	LSR	PLUS_1,X		; shift FAC? mantissa1
  5450  a61b 2008a7             	JSR	LAB_2592		; shift FACX Y times right
  5451                          
  5452                          					; exponents are equal now do mantissa subtract
  5453                          LAB_24A8
  5454  a61e 24b8               	BIT	FAC_sc		; test sign compare (FAC1 EOR FAC2)
  5455  a620 104c               	BPL	LAB_24F8		; if = add FAC2 mantissa to FAC1 mantissa and return
  5456                          
  5457  a622 a0ac               	LDY	#FAC1_e		; set index to FAC1 exponent addr
  5458  a624 e0b3               	CPX	#FAC2_e		; compare X to FAC2 exponent addr
  5459  a626 f002               	BEQ	LAB_24B4		; branch if =
  5460                          
  5461  a628 a0b3               	LDY	#FAC2_e		; else set index to FAC2 exponent addr
  5462                          
  5463                          					; subtract smaller from bigger (take sign of bigger)
  5464                          LAB_24B4
  5465  a62a 38                 	SEC				; set carry for subtract
  5466  a62b 49ff               	EOR	#$FF			; ones complement A
  5467  a62d 65a3               	ADC	FAC2_r		; add FAC2 rounding byte
  5468  a62f 85b9               	STA	FAC1_r		; save FAC1 rounding byte
  5469  a631 b90300             	LDA	PLUS_3,Y		; get FACY mantissa3
  5470  a634 f503               	SBC	PLUS_3,X		; subtract FACX mantissa3
  5471  a636 85af               	STA	FAC1_3		; save FAC1 mantissa3
  5472  a638 b90200             	LDA	PLUS_2,Y		; get FACY mantissa2
  5473  a63b f502               	SBC	PLUS_2,X		; subtract FACX mantissa2
  5474  a63d 85ae               	STA	FAC1_2		; save FAC1 mantissa2
  5475  a63f b90100             	LDA	PLUS_1,Y		; get FACY mantissa1
  5476  a642 f501               	SBC	PLUS_1,X		; subtract FACX mantissa1
  5477  a644 85ad               	STA	FAC1_1		; save FAC1 mantissa1
  5478                          
  5479                          ; do ABS and normalise FAC1
  5480                          
  5481                          LAB_24D0
  5482  a646 b003               	BCS	LAB_24D5		; branch if number is +ve
  5483                          
  5484  a648 20ada6             	JSR	LAB_2537		; negate FAC1
  5485                          
  5486                          ; normalise FAC1
  5487                          
  5488                          LAB_24D5
  5489  a64b a000               	LDY	#$00			; clear Y
  5490  a64d 98                 	TYA				; clear A
  5491  a64e 18                 	CLC				; clear carry for add
  5492                          LAB_24D9
  5493  a64f a6ad               	LDX	FAC1_1		; get FAC1 mantissa1
  5494  a651 d03e               	BNE	LAB_251B		; if not zero normalise FAC1
  5495                          
  5496  a653 a6ae               	LDX	FAC1_2		; get FAC1 mantissa2
  5497  a655 86ad               	STX	FAC1_1		; save FAC1 mantissa1
  5498  a657 a6af               	LDX	FAC1_3		; get FAC1 mantissa3
  5499  a659 86ae               	STX	FAC1_2		; save FAC1 mantissa2
  5500  a65b a6b9               	LDX	FAC1_r		; get FAC1 rounding byte
  5501  a65d 86af               	STX	FAC1_3		; save FAC1 mantissa3
  5502  a65f 84b9               	STY	FAC1_r		; clear FAC1 rounding byte
  5503  a661 6908               	ADC	#$08			; add x to exponent offset
  5504  a663 c918               	CMP	#$18			; compare with $18 (max offset, all bits would be =0)
  5505  a665 d0e8               	BNE	LAB_24D9		; loop if not max
  5506                          
  5507                          ; clear FAC1 exponent and sign
  5508                          
  5509                          LAB_24F1
  5510  a667 a900               	LDA	#$00			; clear A
  5511                          LAB_24F3
  5512  a669 85ac               	STA	FAC1_e		; set FAC1 exponent
  5513                          
  5514                          ; save FAC1 sign
  5515                          
  5516                          LAB_24F5
  5517  a66b 85b0               	STA	FAC1_s		; save FAC1 sign (b7)
  5518  a66d 60                 	RTS
  5519                          
  5520                          ; add FAC2 mantissa to FAC1 mantissa
  5521                          
  5522                          LAB_24F8
  5523  a66e 65a3               	ADC	FAC2_r		; add FAC2 rounding byte
  5524  a670 85b9               	STA	FAC1_r		; save FAC1 rounding byte
  5525  a672 a5af               	LDA	FAC1_3		; get FAC1 mantissa3
  5526  a674 65b6               	ADC	FAC2_3		; add FAC2 mantissa3
  5527  a676 85af               	STA	FAC1_3		; save FAC1 mantissa3
  5528  a678 a5ae               	LDA	FAC1_2		; get FAC1 mantissa2
  5529  a67a 65b5               	ADC	FAC2_2		; add FAC2 mantissa2
  5530  a67c 85ae               	STA	FAC1_2		; save FAC1 mantissa2
  5531  a67e a5ad               	LDA	FAC1_1		; get FAC1 mantissa1
  5532  a680 65b4               	ADC	FAC2_1		; add FAC2 mantissa1
  5533  a682 85ad               	STA	FAC1_1		; save FAC1 mantissa1
  5534  a684 b01a               	BCS	LAB_252A		; if carry then normalise FAC1 for C=1
  5535                          
  5536  a686 60                 	RTS				; else just exit
  5537                          
  5538                          LAB_2511
  5539  a687 6901               	ADC	#$01			; add 1 to exponent offset
  5540  a689 06b9               	ASL	FAC1_r		; shift FAC1 rounding byte
  5541  a68b 26af               	ROL	FAC1_3		; shift FAC1 mantissa3
  5542  a68d 26ae               	ROL	FAC1_2		; shift FAC1 mantissa2
  5543  a68f 26ad               	ROL	FAC1_1		; shift FAC1 mantissa1
  5544                          
  5545                          ; normalise FAC1
  5546                          
  5547                          LAB_251B
  5548  a691 10f4               	BPL	LAB_2511		; loop if not normalised
  5549                          
  5550  a693 38                 	SEC				; set carry for subtract
  5551  a694 e5ac               	SBC	FAC1_e		; subtract FAC1 exponent
  5552  a696 b0cf               	BCS	LAB_24F1		; branch if underflow (set result = $0)
  5553                          
  5554  a698 49ff               	EOR	#$FF			; complement exponent
  5555  a69a 6901               	ADC	#$01			; +1 (twos complement)
  5556  a69c 85ac               	STA	FAC1_e		; save FAC1 exponent
  5557                          
  5558                          ; test and normalise FAC1 for C=0/1
  5559                          
  5560                          LAB_2528
  5561  a69e 900c               	BCC	LAB_2536		; exit if no overflow
  5562                          
  5563                          ; normalise FAC1 for C=1
  5564                          
  5565                          LAB_252A
  5566  a6a0 e6ac               	INC	FAC1_e		; increment FAC1 exponent
  5567  a6a2 f036               	BEQ	LAB_2564		; if zero do overflow error and warm start
  5568                          
  5569  a6a4 66ad               	ROR	FAC1_1		; shift FAC1 mantissa1
  5570  a6a6 66ae               	ROR	FAC1_2		; shift FAC1 mantissa2
  5571  a6a8 66af               	ROR	FAC1_3		; shift FAC1 mantissa3
  5572  a6aa 66b9               	ROR	FAC1_r		; shift FAC1 rounding byte
  5573                          LAB_2536
  5574  a6ac 60                 	RTS
  5575                          
  5576                          ; negate FAC1
  5577                          
  5578                          LAB_2537
  5579  a6ad a5b0               	LDA	FAC1_s		; get FAC1 sign (b7)
  5580  a6af 49ff               	EOR	#$FF			; complement it
  5581  a6b1 85b0               	STA	FAC1_s		; save FAC1 sign (b7)
  5582                          
  5583                          ; twos complement FAC1 mantissa
  5584                          
  5585                          LAB_253D
  5586  a6b3 a5ad               	LDA	FAC1_1		; get FAC1 mantissa1
  5587  a6b5 49ff               	EOR	#$FF			; complement it
  5588  a6b7 85ad               	STA	FAC1_1		; save FAC1 mantissa1
  5589  a6b9 a5ae               	LDA	FAC1_2		; get FAC1 mantissa2
  5590  a6bb 49ff               	EOR	#$FF			; complement it
  5591  a6bd 85ae               	STA	FAC1_2		; save FAC1 mantissa2
  5592  a6bf a5af               	LDA	FAC1_3		; get FAC1 mantissa3
  5593  a6c1 49ff               	EOR	#$FF			; complement it
  5594  a6c3 85af               	STA	FAC1_3		; save FAC1 mantissa3
  5595  a6c5 a5b9               	LDA	FAC1_r		; get FAC1 rounding byte
  5596  a6c7 49ff               	EOR	#$FF			; complement it
  5597  a6c9 85b9               	STA	FAC1_r		; save FAC1 rounding byte
  5598  a6cb e6b9               	INC	FAC1_r		; increment FAC1 rounding byte
  5599  a6cd d00a               	BNE	LAB_2563		; exit if no overflow
  5600                          
  5601                          ; increment FAC1 mantissa
  5602                          
  5603                          LAB_2559
  5604  a6cf e6af               	INC	FAC1_3		; increment FAC1 mantissa3
  5605  a6d1 d006               	BNE	LAB_2563		; finished if no rollover
  5606                          
  5607  a6d3 e6ae               	INC	FAC1_2		; increment FAC1 mantissa2
  5608  a6d5 d002               	BNE	LAB_2563		; finished if no rollover
  5609                          
  5610  a6d7 e6ad               	INC	FAC1_1		; increment FAC1 mantissa1
  5611                          LAB_2563
  5612  a6d9 60                 	RTS
  5613                          
  5614                          ; do overflow error (overflow exit)
  5615                          
  5616                          LAB_2564
  5617  a6da a20a               	LDX	#$0A			; error code $0A ("Overflow" error)
  5618  a6dc 4c4791             	JMP	LAB_XERR		; do error #X, then warm start
  5619                          
  5620                          ; shift FCAtemp << A+8 times
  5621                          
  5622                          LAB_2569
  5623  a6df a274               	LDX	#FACt_1-1		; set offset to FACtemp
  5624                          LAB_256B
  5625  a6e1 b403               	LDY	PLUS_3,X		; get FACX mantissa3
  5626  a6e3 84b9               	STY	FAC1_r		; save as FAC1 rounding byte
  5627  a6e5 b402               	LDY	PLUS_2,X		; get FACX mantissa2
  5628  a6e7 9403               	STY	PLUS_3,X		; save FACX mantissa3
  5629  a6e9 b401               	LDY	PLUS_1,X		; get FACX mantissa1
  5630  a6eb 9402               	STY	PLUS_2,X		; save FACX mantissa2
  5631  a6ed a4b2               	LDY	FAC1_o		; get FAC1 overflow byte
  5632  a6ef 9401               	STY	PLUS_1,X		; save FACX mantissa1
  5633                          
  5634                          ; shift FACX -A times right (> 8 shifts)
  5635                          
  5636                          LAB_257B
  5637  a6f1 6908               	ADC	#$08			; add 8 to shift count
  5638  a6f3 30ec               	BMI	LAB_256B		; go do 8 shift if still -ve
  5639                          
  5640  a6f5 f0ea               	BEQ	LAB_256B		; go do 8 shift if zero
  5641                          
  5642  a6f7 e908               	SBC	#$08			; else subtract 8 again
  5643  a6f9 a8                 	TAY				; save count to Y
  5644  a6fa a5b9               	LDA	FAC1_r		; get FAC1 rounding byte
  5645  a6fc b012               	BCS	LAB_259A		;.
  5646                          
  5647                          LAB_2588
  5648  a6fe 1601               	ASL	PLUS_1,X		; shift FACX mantissa1
  5649  a700 9002               	BCC	LAB_258E		; branch if +ve
  5650                          
  5651  a702 f601               	INC	PLUS_1,X		; this sets b7 eventually
  5652                          LAB_258E
  5653  a704 7601               	ROR	PLUS_1,X		; shift FACX mantissa1 (correct for ASL)
  5654  a706 7601               	ROR	PLUS_1,X		; shift FACX mantissa1 (put carry in b7)
  5655                          
  5656                          ; shift FACX Y times right
  5657                          
  5658                          LAB_2592
  5659  a708 7602               	ROR	PLUS_2,X		; shift FACX mantissa2
  5660  a70a 7603               	ROR	PLUS_3,X		; shift FACX mantissa3
  5661  a70c 6a                 	ROR				; shift FACX rounding byte
  5662  a70d c8                 	INY				; increment exponent diff
  5663  a70e d0ee               	BNE	LAB_2588		; branch if range adjust not complete
  5664                          
  5665                          LAB_259A
  5666  a710 18                 	CLC				; just clear it
  5667  a711 60                 	RTS
  5668                          
  5669                          ; perform LOG()
  5670                          
  5671                          LAB_LOG
  5672  a712 2000a9             	JSR	LAB_27CA		; test sign and zero
  5673  a715 f002               	BEQ	LAB_25C4		; if zero do function call error then warm start
  5674                          
  5675  a717 1003               	BPL	LAB_25C7		; skip error if +ve
  5676                          
  5677                          LAB_25C4
  5678  a719 4c409f             	JMP	LAB_FCER		; do function call error then warm start (-ve)
  5679                          
  5680                          LAB_25C7
  5681  a71c a5ac               	LDA	FAC1_e		; get FAC1 exponent
  5682  a71e e97f               	SBC	#$7F			; normalise it
  5683  a720 48                 	PHA				; save it
  5684  a721 a980               	LDA	#$80			; set exponent to zero
  5685  a723 85ac               	STA	FAC1_e		; save FAC1 exponent
  5686  a725 a988               	LDA	#<LAB_25AD		; set 1/root2 pointer low byte
  5687  a727 a0b1               	LDY	#>LAB_25AD		; set 1/root2 pointer high byte
  5688  a729 20d5a5             	JSR	LAB_246C		; add (AY) to FAC1 (1/root2)
  5689  a72c a98c               	LDA	#<LAB_25B1		; set root2 pointer low byte
  5690  a72e a0b1               	LDY	#>LAB_25B1		; set root2 pointer high byte
  5691  a730 2018a8             	JSR	LAB_26CA		; convert AY and do (AY)/FAC1 (root2/(x+(1/root2)))
  5692  a733 a9ff               	LDA	#<LAB_259C		; set 1 pointer low byte
  5693  a735 a0b1               	LDY	#>LAB_259C		; set 1 pointer high byte
  5694  a737 20baa5             	JSR	LAB_2455		; subtract (AY) from FAC1 ((root2/(x+(1/root2)))-1)
  5695  a73a a97b               	LDA	#<LAB_25A0		; set pointer low byte to counter
  5696  a73c a0b1               	LDY	#>LAB_25A0		; set pointer high byte to counter
  5697  a73e 2068ac             	JSR	LAB_2B6E		; ^2 then series evaluation
  5698  a741 a990               	LDA	#<LAB_25B5		; set -0.5 pointer low byte
  5699  a743 a0b1               	LDY	#>LAB_25B5		; set -0.5 pointer high byte
  5700  a745 20d5a5             	JSR	LAB_246C		; add (AY) to FAC1
  5701  a748 68                 	PLA				; restore FAC1 exponent
  5702  a749 205caa             	JSR	LAB_2912		; evaluate new ASCII digit
  5703  a74c a994               	LDA	#<LAB_25B9		; set LOG(2) pointer low byte
  5704  a74e a0b1               	LDY	#>LAB_25B9		; set LOG(2) pointer high byte
  5705                          
  5706                          ; do convert AY, FCA1*(AY)
  5707                          
  5708                          LAB_25FB
  5709  a750 20a2a7             	JSR	LAB_264D		; unpack memory (AY) into FAC2
  5710                          LAB_MULTIPLY
  5711  a753 f04c               	BEQ	LAB_264C		; exit if zero
  5712                          
  5713  a755 20c8a7             	JSR	LAB_2673		; test and adjust accumulators
  5714  a758 a900               	LDA	#$00			; clear A
  5715  a75a 8575               	STA	FACt_1		; clear temp mantissa1
  5716  a75c 8576               	STA	FACt_2		; clear temp mantissa2
  5717  a75e 8577               	STA	FACt_3		; clear temp mantissa3
  5718  a760 a5b9               	LDA	FAC1_r		; get FAC1 rounding byte
  5719  a762 2077a7             	JSR	LAB_2622		; go do shift/add FAC2
  5720  a765 a5af               	LDA	FAC1_3		; get FAC1 mantissa3
  5721  a767 2077a7             	JSR	LAB_2622		; go do shift/add FAC2
  5722  a76a a5ae               	LDA	FAC1_2		; get FAC1 mantissa2
  5723  a76c 2077a7             	JSR	LAB_2622		; go do shift/add FAC2
  5724  a76f a5ad               	LDA	FAC1_1		; get FAC1 mantissa1
  5725  a771 207ca7             	JSR	LAB_2627		; go do shift/add FAC2
  5726  a774 4c85a8             	JMP	LAB_273C		; copy temp to FAC1, normalise and return
  5727                          
  5728                          LAB_2622
  5729  a777 d003               	BNE	LAB_2627		; branch if byte <> zero
  5730                          
  5731  a779 4cdfa6             	JMP	LAB_2569		; shift FCAtemp << A+8 times
  5732                          
  5733                          					; else do shift and add
  5734                          LAB_2627
  5735  a77c 4a                 	LSR				; shift byte
  5736  a77d 0980               	ORA	#$80			; set top bit (mark for 8 times)
  5737                          LAB_262A
  5738  a77f a8                 	TAY				; copy result
  5739  a780 9013               	BCC	LAB_2640		; skip next if bit was zero
  5740                          
  5741  a782 18                 	CLC				; clear carry for add
  5742  a783 a577               	LDA	FACt_3		; get temp mantissa3
  5743  a785 65b6               	ADC	FAC2_3		; add FAC2 mantissa3
  5744  a787 8577               	STA	FACt_3		; save temp mantissa3
  5745  a789 a576               	LDA	FACt_2		; get temp mantissa2
  5746  a78b 65b5               	ADC	FAC2_2		; add FAC2 mantissa2
  5747  a78d 8576               	STA	FACt_2		; save temp mantissa2
  5748  a78f a575               	LDA	FACt_1		; get temp mantissa1
  5749  a791 65b4               	ADC	FAC2_1		; add FAC2 mantissa1
  5750  a793 8575               	STA	FACt_1		; save temp mantissa1
  5751                          LAB_2640
  5752  a795 6675               	ROR	FACt_1		; shift temp mantissa1
  5753  a797 6676               	ROR	FACt_2		; shift temp mantissa2
  5754  a799 6677               	ROR	FACt_3		; shift temp mantissa3
  5755  a79b 66b9               	ROR	FAC1_r		; shift temp rounding byte
  5756  a79d 98                 	TYA				; get byte back
  5757  a79e 4a                 	LSR				; shift byte
  5758  a79f d0de               	BNE	LAB_262A		; loop if all bits not done
  5759                          
  5760                          LAB_264C
  5761  a7a1 60                 	RTS
  5762                          
  5763                          ; unpack memory (AY) into FAC2
  5764                          
  5765                          LAB_264D
  5766  a7a2 8571               	STA	ut1_pl		; save pointer low byte
  5767  a7a4 8472               	STY	ut1_ph		; save pointer high byte
  5768  a7a6 a003               	LDY	#$03			; 4 bytes to get (0-3)
  5769  a7a8 b171               	LDA	(ut1_pl),Y		; get mantissa3
  5770  a7aa 85b6               	STA	FAC2_3		; save FAC2 mantissa3
  5771  a7ac 88                 	DEY				; decrement index
  5772  a7ad b171               	LDA	(ut1_pl),Y		; get mantissa2
  5773  a7af 85b5               	STA	FAC2_2		; save FAC2 mantissa2
  5774  a7b1 88                 	DEY				; decrement index
  5775  a7b2 b171               	LDA	(ut1_pl),Y		; get mantissa1+sign
  5776  a7b4 85b7               	STA	FAC2_s		; save FAC2 sign (b7)
  5777  a7b6 45b0               	EOR	FAC1_s		; EOR with FAC1 sign (b7)
  5778  a7b8 85b8               	STA	FAC_sc		; save sign compare (FAC1 EOR FAC2)
  5779  a7ba a5b7               	LDA	FAC2_s		; recover FAC2 sign (b7)
  5780  a7bc 0980               	ORA	#$80			; set 1xxx xxx (set normal bit)
  5781  a7be 85b4               	STA	FAC2_1		; save FAC2 mantissa1
  5782  a7c0 88                 	DEY				; decrement index
  5783  a7c1 b171               	LDA	(ut1_pl),Y		; get exponent byte
  5784  a7c3 85b3               	STA	FAC2_e		; save FAC2 exponent
  5785  a7c5 a5ac               	LDA	FAC1_e		; get FAC1 exponent
  5786  a7c7 60                 	RTS
  5787                          
  5788                          ; test and adjust accumulators
  5789                          
  5790                          LAB_2673
  5791  a7c8 a5b3               	LDA	FAC2_e		; get FAC2 exponent
  5792                          LAB_2675
  5793  a7ca f01d               	BEQ	LAB_2696		; branch if FAC2 = $00 (handle underflow)
  5794                          
  5795  a7cc 18                 	CLC				; clear carry for add
  5796  a7cd 65ac               	ADC	FAC1_e		; add FAC1 exponent
  5797  a7cf 9004               	BCC	LAB_2680		; branch if sum of exponents <$0100
  5798                          
  5799  a7d1 3031               	BMI	LAB_269B		; do overflow error
  5800                          
  5801  a7d3 18                 	CLC				; clear carry for the add
  5802  a7d4 2c                 	!text	$2C			; makes next line BIT $1410
  5803                          LAB_2680
  5804  a7d5 1012               	BPL	LAB_2696		; if +ve go handle underflow
  5805                          
  5806  a7d7 6980               	ADC	#$80			; adjust exponent
  5807  a7d9 85ac               	STA	FAC1_e		; save FAC1 exponent
  5808  a7db d003               	BNE	LAB_268B		; branch if not zero
  5809                          
  5810  a7dd 4c6ba6             	JMP	LAB_24F5		; save FAC1 sign and return
  5811                          
  5812                          LAB_268B
  5813  a7e0 a5b8               	LDA	FAC_sc		; get sign compare (FAC1 EOR FAC2)
  5814  a7e2 85b0               	STA	FAC1_s		; save FAC1 sign (b7)
  5815                          LAB_268F
  5816  a7e4 60                 	RTS
  5817                          
  5818                          ; handle overflow and underflow
  5819                          
  5820                          LAB_2690
  5821  a7e5 a5b0               	LDA	FAC1_s		; get FAC1 sign (b7)
  5822  a7e7 101b               	BPL	LAB_269B		; do overflow error
  5823                          
  5824                          					; handle underflow
  5825                          LAB_2696
  5826  a7e9 68                 	PLA				; pop return address low byte
  5827  a7ea 68                 	PLA				; pop return address high byte
  5828  a7eb 4c67a6             	JMP	LAB_24F1		; clear FAC1 exponent and sign and return
  5829                          
  5830                          ; multiply by 10
  5831                          
  5832                          LAB_269E
  5833  a7ee 20e1a8             	JSR	LAB_27AB		; round and copy FAC1 to FAC2
  5834  a7f1 aa                 	TAX				; copy exponent (set the flags)
  5835  a7f2 f0f0               	BEQ	LAB_268F		; exit if zero
  5836                          
  5837  a7f4 18                 	CLC				; clear carry for add
  5838  a7f5 6902               	ADC	#$02			; add two to exponent (*4)
  5839  a7f7 b00b               	BCS	LAB_269B		; do overflow error if > $FF
  5840                          
  5841  a7f9 a200               	LDX	#$00			; clear byte
  5842  a7fb 86b8               	STX	FAC_sc		; clear sign compare (FAC1 EOR FAC2)
  5843  a7fd 20f2a5             	JSR	LAB_247C		; add FAC2 to FAC1 (*5)
  5844  a800 e6ac               	INC	FAC1_e		; increment FAC1 exponent (*10)
  5845  a802 d0e0               	BNE	LAB_268F		; if non zero just do RTS
  5846                          
  5847                          LAB_269B
  5848  a804 4cdaa6             	JMP	LAB_2564		; do overflow error and warm start
  5849                          
  5850                          ; divide by 10
  5851                          
  5852                          LAB_26B9
  5853  a807 20e1a8             	JSR	LAB_27AB		; round and copy FAC1 to FAC2
  5854  a80a a910               	LDA	#<LAB_26B5		; set pointer to 10d low addr
  5855  a80c a0b2               	LDY	#>LAB_26B5		; set pointer to 10d high addr
  5856  a80e a200               	LDX	#$00			; clear sign
  5857                          
  5858                          ; divide by (AY) (X=sign)
  5859                          
  5860                          LAB_26C2
  5861  a810 86b8               	STX	FAC_sc		; save sign compare (FAC1 EOR FAC2)
  5862  a812 2094a8             	JSR	LAB_UFAC		; unpack memory (AY) into FAC1
  5863  a815 4c1ba8             	JMP	LAB_DIVIDE		; do FAC2/FAC1
  5864                          
  5865                          					; Perform divide-by
  5866                          ; convert AY and do (AY)/FAC1
  5867                          
  5868                          LAB_26CA
  5869  a818 20a2a7             	JSR	LAB_264D		; unpack memory (AY) into FAC2
  5870                          
  5871                          					; Perform divide-into
  5872                          LAB_DIVIDE
  5873  a81b f063               	BEQ	LAB_2737		; if zero go do /0 error
  5874                          
  5875  a81d 20f0a8             	JSR	LAB_27BA		; round FAC1
  5876  a820 a900               	LDA	#$00			; clear A
  5877  a822 38                 	SEC				; set carry for subtract
  5878  a823 e5ac               	SBC	FAC1_e		; subtract FAC1 exponent (2s complement)
  5879  a825 85ac               	STA	FAC1_e		; save FAC1 exponent
  5880  a827 20c8a7             	JSR	LAB_2673		; test and adjust accumulators
  5881  a82a e6ac               	INC	FAC1_e		; increment FAC1 exponent
  5882  a82c f0d6               	BEQ	LAB_269B		; if zero do overflow error
  5883                          
  5884  a82e a2ff               	LDX	#$FF			; set index for pre increment
  5885  a830 a901               	LDA	#$01			; set bit to flag byte save
  5886                          LAB_26E4
  5887  a832 a4b4               	LDY	FAC2_1		; get FAC2 mantissa1
  5888  a834 c4ad               	CPY	FAC1_1		; compare FAC1 mantissa1
  5889  a836 d00a               	BNE	LAB_26F4		; branch if <>
  5890                          
  5891  a838 a4b5               	LDY	FAC2_2		; get FAC2 mantissa2
  5892  a83a c4ae               	CPY	FAC1_2		; compare FAC1 mantissa2
  5893  a83c d004               	BNE	LAB_26F4		; branch if <>
  5894                          
  5895  a83e a4b6               	LDY	FAC2_3		; get FAC2 mantissa3
  5896  a840 c4af               	CPY	FAC1_3		; compare FAC1 mantissa3
  5897                          LAB_26F4
  5898  a842 08                 	PHP				; save FAC2-FAC1 compare status
  5899  a843 2a                 	ROL				; shift the result byte
  5900  a844 900e               	BCC	LAB_2702		; if no carry skip the byte save
  5901                          
  5902  a846 a001               	LDY	#$01			; set bit to flag byte save
  5903  a848 e8                 	INX				; else increment the index to FACt
  5904  a849 e002               	CPX	#$02			; compare with the index to FACt_3
  5905  a84b 3004               	BMI	LAB_2701		; if not last byte just go save it
  5906                          
  5907  a84d d028               	BNE	LAB_272B		; if all done go save FAC1 rounding byte, normalise and
  5908                          					; return
  5909                          
  5910  a84f a040               	LDY	#$40			; set bit to flag byte save for the rounding byte
  5911                          LAB_2701
  5912  a851 9575               	STA	FACt_1,X		; write result byte to FACt_1 + index
  5913  a853 98                 	TYA				; copy the next save byte flag
  5914                          LAB_2702
  5915  a854 28                 	PLP				; restore FAC2-FAC1 compare status
  5916  a855 9014               	BCC	LAB_2704		; if FAC2 < FAC1 then skip the subtract
  5917                          
  5918  a857 a8                 	TAY				; save FAC2-FAC1 compare status
  5919  a858 a5b6               	LDA	FAC2_3		; get FAC2 mantissa3
  5920  a85a e5af               	SBC	FAC1_3		; subtract FAC1 mantissa3
  5921  a85c 85b6               	STA	FAC2_3		; save FAC2 mantissa3
  5922  a85e a5b5               	LDA	FAC2_2		; get FAC2 mantissa2
  5923  a860 e5ae               	SBC	FAC1_2		; subtract FAC1 mantissa2
  5924  a862 85b5               	STA	FAC2_2		; save FAC2 mantissa2
  5925  a864 a5b4               	LDA	FAC2_1		; get FAC2 mantissa1
  5926  a866 e5ad               	SBC	FAC1_1		; subtract FAC1 mantissa1
  5927  a868 85b4               	STA	FAC2_1		; save FAC2 mantissa1
  5928  a86a 98                 	TYA				; restore FAC2-FAC1 compare status
  5929                          
  5930                          					; FAC2 = FAC2*2
  5931                          LAB_2704
  5932  a86b 06b6               	ASL	FAC2_3		; shift FAC2 mantissa3
  5933  a86d 26b5               	ROL	FAC2_2		; shift FAC2 mantissa2
  5934  a86f 26b4               	ROL	FAC2_1		; shift FAC2 mantissa1
  5935  a871 b0cf               	BCS	LAB_26F4		; loop with no compare
  5936                          
  5937  a873 30bd               	BMI	LAB_26E4		; loop with compare
  5938                          
  5939  a875 10cb               	BPL	LAB_26F4		; loop always with no compare
  5940                          
  5941                          ; do A<<6, save as FAC1 rounding byte, normalise and return
  5942                          
  5943                          LAB_272B
  5944  a877 4a                 	LSR				; shift b1 - b0 ..
  5945  a878 6a                 	ROR				; ..
  5946  a879 6a                 	ROR				; .. to b7 - b6
  5947  a87a 85b9               	STA	FAC1_r		; save FAC1 rounding byte
  5948  a87c 28                 	PLP				; dump FAC2-FAC1 compare status
  5949  a87d 4c85a8             	JMP	LAB_273C		; copy temp to FAC1, normalise and return
  5950                          
  5951                          ; do "Divide by zero" error
  5952                          
  5953                          LAB_2737
  5954  a880 a214               	LDX	#$14			; error code $14 ("Divide by zero" error)
  5955  a882 4c4791             	JMP	LAB_XERR		; do error #X, then warm start
  5956                          
  5957                          ; copy temp to FAC1 and normalise
  5958                          
  5959                          LAB_273C
  5960  a885 a575               	LDA	FACt_1		; get temp mantissa1
  5961  a887 85ad               	STA	FAC1_1		; save FAC1 mantissa1
  5962  a889 a576               	LDA	FACt_2		; get temp mantissa2
  5963  a88b 85ae               	STA	FAC1_2		; save FAC1 mantissa2
  5964  a88d a577               	LDA	FACt_3		; get temp mantissa3
  5965  a88f 85af               	STA	FAC1_3		; save FAC1 mantissa3
  5966  a891 4c4ba6             	JMP	LAB_24D5		; normalise FAC1 and return
  5967                          
  5968                          ; unpack memory (AY) into FAC1
  5969                          
  5970                          LAB_UFAC
  5971  a894 8571               	STA	ut1_pl		; save pointer low byte
  5972  a896 8472               	STY	ut1_ph		; save pointer high byte
  5973  a898 a003               	LDY	#$03			; 4 bytes to do
  5974  a89a b171               	LDA	(ut1_pl),Y		; get last byte
  5975  a89c 85af               	STA	FAC1_3		; save FAC1 mantissa3
  5976  a89e 88                 	DEY				; decrement index
  5977  a89f b171               	LDA	(ut1_pl),Y		; get last-1 byte
  5978  a8a1 85ae               	STA	FAC1_2		; save FAC1 mantissa2
  5979  a8a3 88                 	DEY				; decrement index
  5980  a8a4 b171               	LDA	(ut1_pl),Y		; get second byte
  5981  a8a6 85b0               	STA	FAC1_s		; save FAC1 sign (b7)
  5982  a8a8 0980               	ORA	#$80			; set 1xxx xxxx (add normal bit)
  5983  a8aa 85ad               	STA	FAC1_1		; save FAC1 mantissa1
  5984  a8ac 88                 	DEY				; decrement index
  5985  a8ad b171               	LDA	(ut1_pl),Y		; get first byte (exponent)
  5986  a8af 85ac               	STA	FAC1_e		; save FAC1 exponent
  5987  a8b1 84b9               	STY	FAC1_r		; clear FAC1 rounding byte
  5988  a8b3 60                 	RTS
  5989                          
  5990                          ; pack FAC1 into Adatal
  5991                          
  5992                          LAB_276E
  5993  a8b4 a2a4               	LDX	#<Adatal		; set pointer low byte
  5994                          LAB_2770
  5995  a8b6 a000               	LDY	#>Adatal		; set pointer high byte
  5996  a8b8 f004               	BEQ	LAB_2778		; pack FAC1 into (XY) and return
  5997                          
  5998                          ; pack FAC1 into (Lvarpl)
  5999                          
  6000                          LAB_PFAC
  6001  a8ba a697               	LDX	Lvarpl		; get destination pointer low byte
  6002  a8bc a498               	LDY	Lvarph		; get destination pointer high byte
  6003                          
  6004                          ; pack FAC1 into (XY)
  6005                          
  6006                          LAB_2778
  6007  a8be 20f0a8             	JSR	LAB_27BA		; round FAC1
  6008  a8c1 8671               	STX	ut1_pl		; save pointer low byte
  6009  a8c3 8472               	STY	ut1_ph		; save pointer high byte
  6010  a8c5 a003               	LDY	#$03			; set index
  6011  a8c7 a5af               	LDA	FAC1_3		; get FAC1 mantissa3
  6012  a8c9 9171               	STA	(ut1_pl),Y		; store in destination
  6013  a8cb 88                 	DEY				; decrement index
  6014  a8cc a5ae               	LDA	FAC1_2		; get FAC1 mantissa2
  6015  a8ce 9171               	STA	(ut1_pl),Y		; store in destination
  6016  a8d0 88                 	DEY				; decrement index
  6017  a8d1 a5b0               	LDA	FAC1_s		; get FAC1 sign (b7)
  6018  a8d3 097f               	ORA	#$7F			; set bits x111 1111
  6019  a8d5 25ad               	AND	FAC1_1		; AND in FAC1 mantissa1
  6020  a8d7 9171               	STA	(ut1_pl),Y		; store in destination
  6021  a8d9 88                 	DEY				; decrement index
  6022  a8da a5ac               	LDA	FAC1_e		; get FAC1 exponent
  6023  a8dc 9171               	STA	(ut1_pl),Y		; store in destination
  6024  a8de 84b9               	STY	FAC1_r		; clear FAC1 rounding byte
  6025  a8e0 60                 	RTS
  6026                          
  6027                          ; round and copy FAC1 to FAC2
  6028                          
  6029                          LAB_27AB
  6030  a8e1 20f0a8             	JSR	LAB_27BA		; round FAC1
  6031                          
  6032                          ; copy FAC1 to FAC2
  6033                          
  6034                          LAB_27AE
  6035  a8e4 a205               	LDX	#$05			; 5 bytes to copy
  6036                          LAB_27B0
  6037  a8e6 b5ab               	LDA	FAC1_e-1,X		; get byte from FAC1,X
  6038  a8e8 95b2               	STA	FAC1_o,X		; save byte at FAC2,X
  6039  a8ea ca                 	DEX				; decrement count
  6040  a8eb d0f9               	BNE	LAB_27B0		; loop if not all done
  6041                          
  6042  a8ed 86b9               	STX	FAC1_r		; clear FAC1 rounding byte
  6043                          LAB_27B9
  6044  a8ef 60                 	RTS
  6045                          
  6046                          ; round FAC1
  6047                          
  6048                          LAB_27BA
  6049  a8f0 a5ac               	LDA	FAC1_e		; get FAC1 exponent
  6050  a8f2 f0fb               	BEQ	LAB_27B9		; exit if zero
  6051                          
  6052  a8f4 06b9               	ASL	FAC1_r		; shift FAC1 rounding byte
  6053  a8f6 90f7               	BCC	LAB_27B9		; exit if no overflow
  6054                          
  6055                          ; round FAC1 (no check)
  6056                          
  6057                          LAB_27C2
  6058  a8f8 20cfa6             	JSR	LAB_2559		; increment FAC1 mantissa
  6059  a8fb d0f2               	BNE	LAB_27B9		; branch if no overflow
  6060                          
  6061  a8fd 4ca0a6             	JMP	LAB_252A		; normalise FAC1 for C=1 and return
  6062                          
  6063                          ; get FAC1 sign
  6064                          ; return A=FF,C=1/-ve A=01,C=0/+ve
  6065                          
  6066                          LAB_27CA
  6067  a900 a5ac               	LDA	FAC1_e		; get FAC1 exponent
  6068  a902 f009               	BEQ	LAB_27D7		; exit if zero (already correct SGN(0)=0)
  6069                          
  6070                          ; return A=FF,C=1/-ve A=01,C=0/+ve
  6071                          ; no = 0 check
  6072                          
  6073                          LAB_27CE
  6074  a904 a5b0               	LDA	FAC1_s		; else get FAC1 sign (b7)
  6075                          
  6076                          ; return A=FF,C=1/-ve A=01,C=0/+ve
  6077                          ; no = 0 check, sign in A
  6078                          
  6079                          LAB_27D0
  6080  a906 2a                 	ROL				; move sign bit to carry
  6081  a907 a9ff               	LDA	#$FF			; set byte for -ve result
  6082  a909 b002               	BCS	LAB_27D7		; return if sign was set (-ve)
  6083                          
  6084  a90b a901               	LDA	#$01			; else set byte for +ve result
  6085                          LAB_27D7
  6086  a90d 60                 	RTS
  6087                          
  6088                          ; perform SGN()
  6089                          
  6090                          LAB_SGN
  6091  a90e 2000a9             	JSR	LAB_27CA		; get FAC1 sign
  6092                          					; return A=$FF/-ve A=$01/+ve
  6093                          ; save A as integer byte
  6094                          
  6095                          LAB_27DB
  6096  a911 85ad               	STA	FAC1_1		; save FAC1 mantissa1
  6097  a913 a900               	LDA	#$00			; clear A
  6098  a915 85ae               	STA	FAC1_2		; clear FAC1 mantissa2
  6099  a917 a288               	LDX	#$88			; set exponent
  6100                          
  6101                          ; set exp=X, clearFAC1 mantissa3 and normalise
  6102                          
  6103                          LAB_27E3
  6104  a919 a5ad               	LDA	FAC1_1		; get FAC1 mantissa1
  6105  a91b 49ff               	EOR	#$FF			; complement it
  6106  a91d 2a                 	ROL				; sign bit into carry
  6107                          
  6108                          ; set exp=X, clearFAC1 mantissa3 and normalise
  6109                          
  6110                          LAB_STFA
  6111  a91e a900               	LDA	#$00			; clear A
  6112  a920 85af               	STA	FAC1_3		; clear FAC1 mantissa3
  6113  a922 86ac               	STX	FAC1_e		; set FAC1 exponent
  6114  a924 85b9               	STA	FAC1_r		; clear FAC1 rounding byte
  6115  a926 85b0               	STA	FAC1_s		; clear FAC1 sign (b7)
  6116  a928 4c46a6             	JMP	LAB_24D0		; do ABS and normalise FAC1
  6117                          
  6118                          ; perform ABS()
  6119                          
  6120                          LAB_ABS
  6121  a92b 46b0               	LSR	FAC1_s		; clear FAC1 sign (put zero in b7)
  6122  a92d 60                 	RTS
  6123                          
  6124                          ; compare FAC1 with (AY)
  6125                          ; returns A=$00 if FAC1 = (AY)
  6126                          ; returns A=$01 if FAC1 > (AY)
  6127                          ; returns A=$FF if FAC1 < (AY)
  6128                          
  6129                          LAB_27F8
  6130  a92e 8573               	STA	ut2_pl		; save pointer low byte
  6131                          LAB_27FA
  6132  a930 8474               	STY	ut2_ph		; save pointer high byte
  6133  a932 a000               	LDY	#$00			; clear index
  6134  a934 b173               	LDA	(ut2_pl),Y		; get exponent
  6135  a936 c8                 	INY				; increment index
  6136  a937 aa                 	TAX				; copy (AY) exponent to X
  6137  a938 f0c6               	BEQ	LAB_27CA		; branch if (AY) exponent=0 and get FAC1 sign
  6138                          					; A=FF,C=1/-ve A=01,C=0/+ve
  6139                          
  6140  a93a b173               	LDA	(ut2_pl),Y		; get (AY) mantissa1 (with sign)
  6141  a93c 45b0               	EOR	FAC1_s		; EOR FAC1 sign (b7)
  6142  a93e 30c4               	BMI	LAB_27CE		; if signs <> do return A=FF,C=1/-ve
  6143                          					; A=01,C=0/+ve and return
  6144                          
  6145  a940 e4ac               	CPX	FAC1_e		; compare (AY) exponent with FAC1 exponent
  6146  a942 d01a               	BNE	LAB_2828		; branch if different
  6147                          
  6148  a944 b173               	LDA	(ut2_pl),Y		; get (AY) mantissa1 (with sign)
  6149  a946 0980               	ORA	#$80			; normalise top bit
  6150  a948 c5ad               	CMP	FAC1_1		; compare with FAC1 mantissa1
  6151  a94a d012               	BNE	LAB_2828		; branch if different
  6152                          
  6153  a94c c8                 	INY				; increment index
  6154  a94d b173               	LDA	(ut2_pl),Y		; get mantissa2
  6155  a94f c5ae               	CMP	FAC1_2		; compare with FAC1 mantissa2
  6156  a951 d00b               	BNE	LAB_2828		; branch if different
  6157                          
  6158  a953 c8                 	INY				; increment index
  6159  a954 a97f               	LDA	#$7F			; set for 1/2 value rounding byte
  6160  a956 c5b9               	CMP	FAC1_r		; compare with FAC1 rounding byte (set carry)
  6161  a958 b173               	LDA	(ut2_pl),Y		; get mantissa3
  6162  a95a e5af               	SBC	FAC1_3		; subtract FAC1 mantissa3
  6163  a95c f028               	BEQ	LAB_2850		; exit if mantissa3 equal
  6164                          
  6165                          ; gets here if number <> FAC1
  6166                          
  6167                          LAB_2828
  6168  a95e a5b0               	LDA	FAC1_s		; get FAC1 sign (b7)
  6169  a960 9002               	BCC	LAB_282E		; branch if FAC1 > (AY)
  6170                          
  6171  a962 49ff               	EOR	#$FF			; else toggle FAC1 sign
  6172                          LAB_282E
  6173  a964 4c06a9             	JMP	LAB_27D0		; return A=FF,C=1/-ve A=01,C=0/+ve
  6174                          
  6175                          ; convert FAC1 floating-to-fixed
  6176                          
  6177                          LAB_2831
  6178  a967 a5ac               	LDA	FAC1_e		; get FAC1 exponent
  6179  a969 f04a               	BEQ	LAB_287F		; if zero go clear FAC1 and return
  6180                          
  6181  a96b 38                 	SEC				; set carry for subtract
  6182  a96c e998               	SBC	#$98			; subtract maximum integer range exponent
  6183  a96e 24b0               	BIT	FAC1_s		; test FAC1 sign (b7)
  6184  a970 1009               	BPL	LAB_2845		; branch if FAC1 +ve
  6185                          
  6186                          					; FAC1 was -ve
  6187  a972 aa                 	TAX				; copy subtracted exponent
  6188  a973 a9ff               	LDA	#$FF			; overflow for -ve number
  6189  a975 85b2               	STA	FAC1_o		; set FAC1 overflow byte
  6190  a977 20b3a6             	JSR	LAB_253D		; twos complement FAC1 mantissa
  6191  a97a 8a                 	TXA				; restore subtracted exponent
  6192                          LAB_2845
  6193  a97b a2ac               	LDX	#FAC1_e		; set index to FAC1
  6194  a97d c9f9               	CMP	#$F9			; compare exponent result
  6195  a97f 1006               	BPL	LAB_2851		; if < 8 shifts shift FAC1 A times right and return
  6196                          
  6197  a981 20f1a6             	JSR	LAB_257B		; shift FAC1 A times right (> 8 shifts)
  6198  a984 84b2               	STY	FAC1_o		; clear FAC1 overflow byte
  6199                          LAB_2850
  6200  a986 60                 	RTS
  6201                          
  6202                          ; shift FAC1 A times right
  6203                          
  6204                          LAB_2851
  6205  a987 a8                 	TAY				; copy shift count
  6206  a988 a5b0               	LDA	FAC1_s		; get FAC1 sign (b7)
  6207  a98a 2980               	AND	#$80			; mask sign bit only (x000 0000)
  6208  a98c 46ad               	LSR	FAC1_1		; shift FAC1 mantissa1
  6209  a98e 05ad               	ORA	FAC1_1		; OR sign in b7 FAC1 mantissa1
  6210  a990 85ad               	STA	FAC1_1		; save FAC1 mantissa1
  6211  a992 2008a7             	JSR	LAB_2592		; shift FAC1 Y times right
  6212  a995 84b2               	STY	FAC1_o		; clear FAC1 overflow byte
  6213  a997 60                 	RTS
  6214                          
  6215                          ; perform INT()
  6216                          
  6217                          LAB_INT
  6218  a998 a5ac               	LDA	FAC1_e		; get FAC1 exponent
  6219  a99a c998               	CMP	#$98			; compare with max int
  6220  a99c b01e               	BCS	LAB_2886		; exit if >= (already int, too big for fractional part!)
  6221                          
  6222  a99e 2067a9             	JSR	LAB_2831		; convert FAC1 floating-to-fixed
  6223  a9a1 84b9               	STY	FAC1_r		; save FAC1 rounding byte
  6224  a9a3 a5b0               	LDA	FAC1_s		; get FAC1 sign (b7)
  6225  a9a5 84b0               	STY	FAC1_s		; save FAC1 sign (b7)
  6226  a9a7 4980               	EOR	#$80			; toggle FAC1 sign
  6227  a9a9 2a                 	ROL				; shift into carry
  6228  a9aa a998               	LDA	#$98			; set new exponent
  6229  a9ac 85ac               	STA	FAC1_e		; save FAC1 exponent
  6230  a9ae a5af               	LDA	FAC1_3		; get FAC1 mantissa3
  6231  a9b0 855b               	STA	Temp3			; save for EXP() function
  6232  a9b2 4c46a6             	JMP	LAB_24D0		; do ABS and normalise FAC1
  6233                          
  6234                          ; clear FAC1 and return
  6235                          
  6236                          LAB_287F
  6237  a9b5 85ad               	STA	FAC1_1		; clear FAC1 mantissa1
  6238  a9b7 85ae               	STA	FAC1_2		; clear FAC1 mantissa2
  6239  a9b9 85af               	STA	FAC1_3		; clear FAC1 mantissa3
  6240  a9bb a8                 	TAY				; clear Y
  6241                          LAB_2886
  6242  a9bc 60                 	RTS
  6243                          
  6244                          ; get FAC1 from string
  6245                          ; this routine now handles hex and binary values from strings
  6246                          ; starting with "$" and "%" respectively
  6247                          
  6248                          LAB_2887
  6249  a9bd a000               	LDY	#$00			; clear Y
  6250  a9bf 845f               	STY	Dtypef		; clear data type flag, $FF=string, $00=numeric
  6251  a9c1 a209               	LDX	#$09			; set index
  6252                          LAB_288B
  6253  a9c3 94a8               	STY	numexp,X		; clear byte
  6254  a9c5 ca                 	DEX				; decrement index
  6255  a9c6 10fb               	BPL	LAB_288B		; loop until numexp to negnum (and FAC1) = $00
  6256                          
  6257  a9c8 907f               	BCC	LAB_28FE		; branch if 1st character numeric
  6258                          
  6259                          ; get FAC1 from string .. first character wasn't numeric
  6260                          
  6261  a9ca c92d               	CMP	#'-'			; else compare with "-"
  6262  a9cc d004               	BNE	LAB_289A		; branch if not "-"
  6263                          
  6264  a9ce 86b1               	STX	negnum		; set flag for -ve number (X = $FF)
  6265  a9d0 f004               	BEQ	LAB_289C		; branch always (go scan and check for hex/bin)
  6266                          
  6267                          ; get FAC1 from string .. first character wasn't numeric or -
  6268                          
  6269                          LAB_289A
  6270  a9d2 c92b               	CMP	#'+'			; else compare with "+"
  6271  a9d4 d005               	BNE	LAB_289D		; branch if not "+" (go check for hex/bin)
  6272                          
  6273                          ; was "+" or "-" to start, so get next character
  6274                          
  6275                          LAB_289C
  6276  a9d6 20bc00             	JSR	LAB_IGBY		; increment and scan memory
  6277  a9d9 906e               	BCC	LAB_28FE		; branch if numeric character
  6278                          
  6279                          ; code here for hex and binary numbers
  6280                          
  6281                          LAB_289D
  6282  a9db c924               	CMP	#'$'			; else compare with "$"
  6283  a9dd d003               	BNE	LAB_NHEX		; branch if not "$"
  6284                          
  6285  a9df 4c85ae             	JMP	LAB_CHEX		; branch if "$"
  6286                          
  6287                          LAB_NHEX
  6288  a9e2 c925               	CMP	#'%'			; else compare with "%"
  6289  a9e4 d008               	BNE	LAB_28A3		; branch if not "%" (continue original code)
  6290                          
  6291  a9e6 4cb3ae             	JMP	LAB_CBIN		; branch if "%"
  6292                          
  6293                          LAB_289E
  6294  a9e9 20bc00             	JSR	LAB_IGBY		; increment and scan memory (ignore + or get next number)
  6295                          LAB_28A1
  6296  a9ec 905b               	BCC	LAB_28FE		; branch if numeric character
  6297                          
  6298                          ; get FAC1 from string .. character wasn't numeric, -, +, hex or binary
  6299                          
  6300                          LAB_28A3
  6301  a9ee c92e               	CMP	#'.'			; else compare with "."
  6302  a9f0 f02e               	BEQ	LAB_28D5		; branch if "."
  6303                          
  6304                          ; get FAC1 from string .. character wasn't numeric, -, + or .
  6305                          
  6306  a9f2 c945               	CMP	#'E'			; else compare with "E"
  6307  a9f4 d030               	BNE	LAB_28DB		; branch if not "E"
  6308                          
  6309                          					; was "E" so evaluate exponential part
  6310  a9f6 20bc00             	JSR	LAB_IGBY		; increment and scan memory
  6311  a9f9 9017               	BCC	LAB_28C7		; branch if numeric character
  6312                          
  6313  a9fb c9bc               	CMP	#TK_MINUS		; else compare with token for -
  6314  a9fd f00e               	BEQ	LAB_28C2		; branch if token for -
  6315                          
  6316  a9ff c92d               	CMP	#'-'			; else compare with "-"
  6317  aa01 f00a               	BEQ	LAB_28C2		; branch if "-"
  6318                          
  6319  aa03 c9bb               	CMP	#TK_PLUS		; else compare with token for +
  6320  aa05 f008               	BEQ	LAB_28C4		; branch if token for +
  6321                          
  6322  aa07 c92b               	CMP	#'+'			; else compare with "+"
  6323  aa09 f004               	BEQ	LAB_28C4		; branch if "+"
  6324                          
  6325  aa0b d007               	BNE	LAB_28C9		; branch always
  6326                          
  6327                          LAB_28C2
  6328  aa0d 66ab               	ROR	expneg		; set exponent -ve flag (C, which=1, into b7)
  6329                          LAB_28C4
  6330  aa0f 20bc00             	JSR	LAB_IGBY		; increment and scan memory
  6331                          LAB_28C7
  6332  aa12 905b               	BCC	LAB_2925		; branch if numeric character
  6333                          
  6334                          LAB_28C9
  6335  aa14 24ab               	BIT	expneg		; test exponent -ve flag
  6336  aa16 100e               	BPL	LAB_28DB		; if +ve go evaluate exponent
  6337                          
  6338                          					; else do exponent = -exponent 
  6339  aa18 a900               	LDA	#$00			; clear result
  6340  aa1a 38                 	SEC				; set carry for subtract
  6341  aa1b e5a9               	SBC	expcnt		; subtract exponent byte
  6342  aa1d 4c28aa             	JMP	LAB_28DD		; go evaluate exponent
  6343                          
  6344                          LAB_28D5
  6345  aa20 66aa               	ROR	numdpf		; set decimal point flag
  6346  aa22 24aa               	BIT	numdpf		; test decimal point flag
  6347  aa24 50c3               	BVC	LAB_289E		; branch if only one decimal point so far
  6348                          
  6349                          					; evaluate exponent
  6350                          LAB_28DB
  6351  aa26 a5a9               	LDA	expcnt		; get exponent count byte
  6352                          LAB_28DD
  6353  aa28 38                 	SEC				; set carry for subtract
  6354  aa29 e5a8               	SBC	numexp		; subtract numerator exponent
  6355  aa2b 85a9               	STA	expcnt		; save exponent count byte
  6356  aa2d f012               	BEQ	LAB_28F6		; branch if no adjustment
  6357                          
  6358  aa2f 1009               	BPL	LAB_28EF		; else if +ve go do FAC1*10^expcnt
  6359                          
  6360                          					; else go do FAC1/10^(0-expcnt)
  6361                          LAB_28E6
  6362  aa31 2007a8             	JSR	LAB_26B9		; divide by 10
  6363  aa34 e6a9               	INC	expcnt		; increment exponent count byte
  6364  aa36 d0f9               	BNE	LAB_28E6		; loop until all done
  6365                          
  6366  aa38 f007               	BEQ	LAB_28F6		; branch always
  6367                          
  6368                          LAB_28EF
  6369  aa3a 20eea7             	JSR	LAB_269E		; multiply by 10
  6370  aa3d c6a9               	DEC	expcnt		; decrement exponent count byte
  6371  aa3f d0f9               	BNE	LAB_28EF		; loop until all done
  6372                          
  6373                          LAB_28F6
  6374  aa41 a5b1               	LDA	negnum		; get -ve flag
  6375  aa43 3001               	BMI	LAB_28FB		; if -ve do - FAC1 and return
  6376                          
  6377  aa45 60                 	RTS
  6378                          
  6379                          ; do - FAC1 and return
  6380                          
  6381                          LAB_28FB
  6382  aa46 4c0bac             	JMP	LAB_GTHAN		; do - FAC1 and return
  6383                          
  6384                          ; do unsigned FAC1*10+number
  6385                          
  6386                          LAB_28FE
  6387  aa49 48                 	PHA				; save character
  6388  aa4a 24aa               	BIT	numdpf		; test decimal point flag
  6389  aa4c 1002               	BPL	LAB_2905		; skip exponent increment if not set
  6390                          
  6391  aa4e e6a8               	INC	numexp		; else increment number exponent
  6392                          LAB_2905
  6393  aa50 20eea7             	JSR	LAB_269E		; multiply FAC1 by 10
  6394  aa53 68                 	PLA				; restore character
  6395  aa54 290f               	AND	#$0F			; convert to binary
  6396  aa56 205caa             	JSR	LAB_2912		; evaluate new ASCII digit
  6397  aa59 4ce9a9             	JMP	LAB_289E		; go do next character
  6398                          
  6399                          ; evaluate new ASCII digit
  6400                          
  6401                          LAB_2912
  6402  aa5c 48                 	PHA				; save digit
  6403  aa5d 20e1a8             	JSR	LAB_27AB		; round and copy FAC1 to FAC2
  6404  aa60 68                 	PLA				; restore digit
  6405  aa61 2011a9             	JSR	LAB_27DB		; save A as integer byte
  6406  aa64 a5b7               	LDA	FAC2_s		; get FAC2 sign (b7)
  6407  aa66 45b0               	EOR	FAC1_s		; toggle with FAC1 sign (b7)
  6408  aa68 85b8               	STA	FAC_sc		; save sign compare (FAC1 EOR FAC2)
  6409  aa6a a6ac               	LDX	FAC1_e		; get FAC1 exponent
  6410  aa6c 4cd8a5             	JMP	LAB_ADD		; add FAC2 to FAC1 and return
  6411                          
  6412                          ; evaluate next character of exponential part of number
  6413                          
  6414                          LAB_2925
  6415  aa6f a5a9               	LDA	expcnt		; get exponent count byte
  6416  aa71 c90a               	CMP	#$0A			; compare with 10 decimal
  6417  aa73 9009               	BCC	LAB_2934		; branch if less
  6418                          
  6419  aa75 a964               	LDA	#$64			; make all -ve exponents = -100 decimal (causes underflow)
  6420  aa77 24ab               	BIT	expneg		; test exponent -ve flag
  6421  aa79 300e               	BMI	LAB_2942		; branch if -ve
  6422                          
  6423  aa7b 4cdaa6             	JMP	LAB_2564		; else do overflow error
  6424                          
  6425                          LAB_2934
  6426  aa7e 0a                 	ASL				; * 2
  6427  aa7f 0a                 	ASL				; * 4
  6428  aa80 65a9               	ADC	expcnt		; * 5
  6429  aa82 0a                 	ASL				; * 10
  6430  aa83 a000               	LDY	#$00			; set index
  6431  aa85 71c3               	ADC	(Bpntrl),Y		; add character (will be $30 too much!)
  6432  aa87 e92f               	SBC	#'0'-1		; convert character to binary
  6433                          LAB_2942
  6434  aa89 85a9               	STA	expcnt		; save exponent count byte
  6435  aa8b 4c0faa             	JMP	LAB_28C4		; go get next character
  6436                          
  6437                          ; print " in line [LINE #]"
  6438                          
  6439                          LAB_2953
  6440  aa8e a955               	LDA	#<LAB_LMSG		; point to " in line " message low byte
  6441  aa90 a0b8               	LDY	#>LAB_LMSG		; point to " in line " message high byte
  6442  aa92 20ea98             	JSR	LAB_18C3		; print null terminated string from memory
  6443                          
  6444                          					; print Basic line #
  6445  aa95 a588               	LDA	Clineh		; get current line high byte
  6446  aa97 a687               	LDX	Clinel		; get current line low byte
  6447                          
  6448                          ; print XA as unsigned integer
  6449                          
  6450                          LAB_295E
  6451  aa99 85ad               	STA	FAC1_1		; save low byte as FAC1 mantissa1
  6452  aa9b 86ae               	STX	FAC1_2		; save high byte as FAC1 mantissa2
  6453  aa9d a290               	LDX	#$90			; set exponent to 16d bits
  6454  aa9f 38                 	SEC				; set integer is +ve flag
  6455  aaa0 201ea9             	JSR	LAB_STFA		; set exp=X, clearFAC1 mantissa3 and normalise
  6456  aaa3 a000               	LDY	#$00			; clear index
  6457  aaa5 98                 	TYA				; clear A
  6458  aaa6 20b9aa             	JSR	LAB_297B		; convert FAC1 to string, skip sign character save
  6459  aaa9 4cea98             	JMP	LAB_18C3		; print null terminated string from memory and return
  6460                          
  6461                          ; convert FAC1 to ASCII string result in (AY)
  6462                          ; not any more, moved scratchpad to page 0
  6463                          
  6464                          LAB_296E
  6465  aaac a001               	LDY	#$01			; set index = 1
  6466  aaae a920               	LDA	#$20			; character = " " (assume +ve)
  6467  aab0 24b0               	BIT	FAC1_s		; test FAC1 sign (b7)
  6468  aab2 1002               	BPL	LAB_2978		; branch if +ve
  6469                          
  6470  aab4 a92d               	LDA	#$2D			; else character = "-"
  6471                          LAB_2978
  6472  aab6 99e200             	STA	Decss,Y		; save leading character (" " or "-")
  6473                          LAB_297B
  6474  aab9 85b0               	STA	FAC1_s		; clear FAC1 sign (b7)
  6475  aabb 84ba               	STY	Sendl			; save index
  6476  aabd c8                 	INY				; increment index
  6477  aabe a6ac               	LDX	FAC1_e		; get FAC1 exponent
  6478  aac0 d005               	BNE	LAB_2989		; branch if FAC1<>0
  6479                          
  6480                          					; exponent was $00 so FAC1 is 0
  6481  aac2 a930               	LDA	#'0'			; set character = "0"
  6482  aac4 4cc5ab             	JMP	LAB_2A89		; save last character, [EOT] and exit
  6483                          
  6484                          					; FAC1 is some non zero value
  6485                          LAB_2989
  6486  aac7 a900               	LDA	#$00			; clear (number exponent count)
  6487  aac9 e081               	CPX	#$81			; compare FAC1 exponent with $81 (>1.00000)
  6488                          
  6489  aacb b009               	BCS	LAB_299A		; branch if FAC1=>1
  6490                          
  6491                          					; FAC1<1
  6492  aacd a9a0               	LDA	#<LAB_294F		; set pointer low byte to 1,000,000
  6493  aacf a0b1               	LDY	#>LAB_294F		; set pointer high byte to 1,000,000
  6494  aad1 2050a7             	JSR	LAB_25FB		; do convert AY, FCA1*(AY)
  6495  aad4 a9fa               	LDA	#$FA			; set number exponent count (-6)
  6496                          LAB_299A
  6497  aad6 85a8               	STA	numexp		; save number exponent count
  6498                          LAB_299C
  6499  aad8 a99c               	LDA	#<LAB_294B		; set pointer low byte to 999999.4375 (max before sci note)
  6500  aada a0b1               	LDY	#>LAB_294B		; set pointer high byte to 999999.4375
  6501  aadc 202ea9             	JSR	LAB_27F8		; compare FAC1 with (AY)
  6502  aadf f01e               	BEQ	LAB_29C3		; exit if FAC1 = (AY)
  6503                          
  6504  aae1 1012               	BPL	LAB_29B9		; go do /10 if FAC1 > (AY)
  6505                          
  6506                          					; FAC1 < (AY)
  6507                          LAB_29A7
  6508  aae3 a998               	LDA	#<LAB_2947		; set pointer low byte to 99999.9375
  6509  aae5 a0b1               	LDY	#>LAB_2947		; set pointer high byte to 99999.9375
  6510  aae7 202ea9             	JSR	LAB_27F8		; compare FAC1 with (AY)
  6511  aaea f002               	BEQ	LAB_29B2		; branch if FAC1 = (AY) (allow decimal places)
  6512                          
  6513  aaec 100e               	BPL	LAB_29C0		; branch if FAC1 > (AY) (no decimal places)
  6514                          
  6515                          					; FAC1 <= (AY)
  6516                          LAB_29B2
  6517  aaee 20eea7             	JSR	LAB_269E		; multiply by 10
  6518  aaf1 c6a8               	DEC	numexp		; decrement number exponent count
  6519  aaf3 d0ee               	BNE	LAB_29A7		; go test again (branch always)
  6520                          
  6521                          LAB_29B9
  6522  aaf5 2007a8             	JSR	LAB_26B9		; divide by 10
  6523  aaf8 e6a8               	INC	numexp		; increment number exponent count
  6524  aafa d0dc               	BNE	LAB_299C		; go test again (branch always)
  6525                          
  6526                          ; now we have just the digits to do
  6527                          
  6528                          LAB_29C0
  6529  aafc 20d1a5             	JSR	LAB_244E		; add 0.5 to FAC1 (round FAC1)
  6530                          LAB_29C3
  6531  aaff 2067a9             	JSR	LAB_2831		; convert FAC1 floating-to-fixed
  6532  ab02 a201               	LDX	#$01			; set default digits before dp = 1
  6533  ab04 a5a8               	LDA	numexp		; get number exponent count
  6534  ab06 18                 	CLC				; clear carry for add
  6535  ab07 6907               	ADC	#$07			; up to 6 digits before point
  6536  ab09 3009               	BMI	LAB_29D8		; if -ve then 1 digit before dp
  6537                          
  6538  ab0b c908               	CMP	#$08			; A>=8 if n>=1E6
  6539  ab0d b006               	BCS	LAB_29D9		; branch if >= $08
  6540                          
  6541                          					; carry is clear
  6542  ab0f 69ff               	ADC	#$FF			; take 1 from digit count
  6543  ab11 aa                 	TAX				; copy to A
  6544  ab12 a902               	LDA	#$02			;.set exponent adjust
  6545                          LAB_29D8
  6546  ab14 38                 	SEC				; set carry for subtract
  6547                          LAB_29D9
  6548  ab15 e902               	SBC	#$02			; -2
  6549  ab17 85a9               	STA	expcnt		;.save exponent adjust
  6550  ab19 86a8               	STX	numexp		; save digits before dp count
  6551  ab1b 8a                 	TXA				; copy to A
  6552  ab1c f002               	BEQ	LAB_29E4		; branch if no digits before dp
  6553                          
  6554  ab1e 1013               	BPL	LAB_29F7		; branch if digits before dp
  6555                          
  6556                          LAB_29E4
  6557  ab20 a4ba               	LDY	Sendl			; get output string index
  6558  ab22 a92e               	LDA	#$2E			; character "."
  6559  ab24 c8                 	INY				; increment index
  6560  ab25 99e200             	STA	Decss,Y		; save to output string
  6561  ab28 8a                 	TXA				;.
  6562  ab29 f006               	BEQ	LAB_29F5		;.
  6563                          
  6564  ab2b a930               	LDA	#'0'			; character "0"
  6565  ab2d c8                 	INY				; increment index
  6566  ab2e 99e200             	STA	Decss,Y		; save to output string
  6567                          LAB_29F5
  6568  ab31 84ba               	STY	Sendl			; save output string index
  6569                          LAB_29F7
  6570  ab33 a000               	LDY	#$00			; clear index (point to 100,000)
  6571  ab35 a280               	LDX	#$80			; 
  6572                          LAB_29FB
  6573  ab37 a5af               	LDA	FAC1_3		; get FAC1 mantissa3
  6574  ab39 18                 	CLC				; clear carry for add
  6575  ab3a 7916b2             	ADC	LAB_2A9C,Y		; add -ve LSB
  6576  ab3d 85af               	STA	FAC1_3		; save FAC1 mantissa3
  6577  ab3f a5ae               	LDA	FAC1_2		; get FAC1 mantissa2
  6578  ab41 7915b2             	ADC	LAB_2A9B,Y		; add -ve NMSB
  6579  ab44 85ae               	STA	FAC1_2		; save FAC1 mantissa2
  6580  ab46 a5ad               	LDA	FAC1_1		; get FAC1 mantissa1
  6581  ab48 7914b2             	ADC	LAB_2A9A,Y		; add -ve MSB
  6582  ab4b 85ad               	STA	FAC1_1		; save FAC1 mantissa1
  6583  ab4d e8                 	INX				; 
  6584  ab4e b004               	BCS	LAB_2A18		; 
  6585                          
  6586  ab50 10e5               	BPL	LAB_29FB		; not -ve so try again
  6587                          
  6588  ab52 3002               	BMI	LAB_2A1A		; 
  6589                          
  6590                          LAB_2A18
  6591  ab54 30e1               	BMI	LAB_29FB		; 
  6592                          
  6593                          LAB_2A1A
  6594  ab56 8a                 	TXA				; 
  6595  ab57 9004               	BCC	LAB_2A21		; 
  6596                          
  6597  ab59 49ff               	EOR	#$FF			; 
  6598  ab5b 690a               	ADC	#$0A			; 
  6599                          LAB_2A21
  6600  ab5d 692f               	ADC	#'0'-1		; add "0"-1 to result
  6601  ab5f c8                 	INY				; increment index ..
  6602  ab60 c8                 	INY				; .. to next less ..
  6603  ab61 c8                 	INY				; .. power of ten
  6604  ab62 8495               	STY	Cvaral		; save as current var address low byte
  6605  ab64 a4ba               	LDY	Sendl			; get output string index
  6606  ab66 c8                 	INY				; increment output string index
  6607  ab67 aa                 	TAX				; copy character to X
  6608  ab68 297f               	AND	#$7F			; mask out top bit
  6609  ab6a 99e200             	STA	Decss,Y		; save to output string
  6610  ab6d c6a8               	DEC	numexp		; decrement # of characters before the dp
  6611  ab6f d006               	BNE	LAB_2A3B		; branch if still characters to do
  6612                          
  6613                          					; else output the point
  6614  ab71 a92e               	LDA	#$2E			; character "."
  6615  ab73 c8                 	INY				; increment output string index
  6616  ab74 99e200             	STA	Decss,Y		; save to output string
  6617                          LAB_2A3B
  6618  ab77 84ba               	STY	Sendl			; save output string index
  6619  ab79 a495               	LDY	Cvaral		; get current var address low byte
  6620  ab7b 8a                 	TXA				; get character back
  6621  ab7c 49ff               	EOR	#$FF			; 
  6622  ab7e 2980               	AND	#$80			; 
  6623  ab80 aa                 	TAX				; 
  6624  ab81 c012               	CPY	#$12			; compare index with max
  6625  ab83 d0b2               	BNE	LAB_29FB		; loop if not max
  6626                          
  6627                          					; now remove trailing zeroes
  6628  ab85 a4ba               	LDY	Sendl			; get output string index
  6629                          LAB_2A4B
  6630  ab87 b9e200             	LDA	Decss,Y		; get character from output string
  6631  ab8a 88                 	DEY				; decrement output string index
  6632  ab8b c930               	CMP	#'0'			; compare with "0"
  6633  ab8d f0f8               	BEQ	LAB_2A4B		; loop until non "0" character found
  6634                          
  6635  ab8f c92e               	CMP	#'.'			; compare with "."
  6636  ab91 f001               	BEQ	LAB_2A58		; branch if was dp
  6637                          
  6638                          					; restore last character
  6639  ab93 c8                 	INY				; increment output string index
  6640                          LAB_2A58
  6641  ab94 a92b               	LDA	#$2B			; character "+"
  6642  ab96 a6a9               	LDX	expcnt		; get exponent count
  6643  ab98 f02e               	BEQ	LAB_2A8C		; if zero go set null terminator and exit
  6644                          
  6645                          					; exponent isn't zero so write exponent
  6646  ab9a 1008               	BPL	LAB_2A68		; branch if exponent count +ve
  6647                          
  6648  ab9c a900               	LDA	#$00			; clear A
  6649  ab9e 38                 	SEC				; set carry for subtract
  6650  ab9f e5a9               	SBC	expcnt		; subtract exponent count adjust (convert -ve to +ve)
  6651  aba1 aa                 	TAX				; copy exponent count to X
  6652  aba2 a92d               	LDA	#'-'			; character "-"
  6653                          LAB_2A68
  6654  aba4 99e400             	STA	Decss+2,Y		; save to output string
  6655  aba7 a945               	LDA	#$45			; character "E"
  6656  aba9 99e300             	STA	Decss+1,Y		; save exponent sign to output string
  6657  abac 8a                 	TXA				; get exponent count back
  6658  abad a22f               	LDX	#'0'-1		; one less than "0" character
  6659  abaf 38                 	SEC				; set carry for subtract
  6660                          LAB_2A74
  6661  abb0 e8                 	INX				; increment 10's character
  6662  abb1 e90a               	SBC	#$0A			;.subtract 10 from exponent count
  6663  abb3 b0fb               	BCS	LAB_2A74		; loop while still >= 0
  6664                          
  6665  abb5 693a               	ADC	#':'			; add character ":" ($30+$0A, result is 10 less that value)
  6666  abb7 99e600             	STA	Decss+4,Y		; save to output string
  6667  abba 8a                 	TXA				; copy 10's character
  6668  abbb 99e500             	STA	Decss+3,Y		; save to output string
  6669  abbe a900               	LDA	#$00			; set null terminator
  6670  abc0 99e700             	STA	Decss+5,Y		; save to output string
  6671  abc3 f008               	BEQ	LAB_2A91		; go set string pointer (AY) and exit (branch always)
  6672                          
  6673                          					; save last character, [EOT] and exit
  6674                          LAB_2A89
  6675  abc5 99e200             	STA	Decss,Y		; save last character to output string
  6676                          
  6677                          					; set null terminator and exit
  6678                          LAB_2A8C
  6679  abc8 a900               	LDA	#$00			; set null terminator
  6680  abca 99e300             	STA	Decss+1,Y		; save after last character
  6681                          
  6682                          					; set string pointer (AY) and exit
  6683                          LAB_2A91
  6684  abcd a9e3               	LDA	#<Decssp1		; set result string low pointer
  6685  abcf a000               	LDY	#>Decssp1		; set result string high pointer
  6686  abd1 60                 	RTS
  6687                          
  6688                          ; perform power function
  6689                          
  6690                          LAB_POWER
  6691  abd2 f042               	BEQ	LAB_EXP		; go do  EXP()
  6692                          
  6693  abd4 a5b3               	LDA	FAC2_e		; get FAC2 exponent
  6694  abd6 d003               	BNE	LAB_2ABF		; branch if FAC2<>0
  6695                          
  6696  abd8 4c69a6             	JMP	LAB_24F3		; clear FAC1 exponent and sign and return
  6697                          
  6698                          LAB_2ABF
  6699  abdb a29c               	LDX	#<func_l		; set destination pointer low byte
  6700  abdd a000               	LDY	#>func_l		; set destination pointer high byte
  6701  abdf 20bea8             	JSR	LAB_2778		; pack FAC1 into (XY)
  6702  abe2 a5b7               	LDA	FAC2_s		; get FAC2 sign (b7)
  6703  abe4 100f               	BPL	LAB_2AD9		; branch if FAC2>0
  6704                          
  6705                          					; else FAC2 is -ve and can only be raised to an
  6706                          					; integer power which gives an x +j0 result
  6707  abe6 2098a9             	JSR	LAB_INT		; perform INT
  6708  abe9 a99c               	LDA	#<func_l		; set source pointer low byte
  6709  abeb a000               	LDY	#>func_l		; set source pointer high byte
  6710  abed 202ea9             	JSR	LAB_27F8		; compare FAC1 with (AY)
  6711  abf0 d003               	BNE	LAB_2AD9		; branch if FAC1 <> (AY) to allow Function Call error
  6712                          					; this will leave FAC1 -ve and cause a Function Call
  6713                          					; error when LOG() is called
  6714                          
  6715  abf2 98                 	TYA				; clear sign b7
  6716  abf3 a45b               	LDY	Temp3			; save mantissa 3 from INT() function as sign in Y
  6717                          					; for possible later negation, b0
  6718                          LAB_2AD9
  6719  abf5 20dca5             	JSR	LAB_279D		; save FAC1 sign and copy ABS(FAC2) to FAC1
  6720  abf8 98                 	TYA				; copy sign back ..
  6721  abf9 48                 	PHA				; .. and save it
  6722  abfa 2012a7             	JSR	LAB_LOG		; do LOG(n)
  6723  abfd a99c               	LDA	#<garb_l		; set pointer low byte
  6724  abff a000               	LDY	#>garb_l		; set pointer high byte
  6725  ac01 2050a7             	JSR	LAB_25FB		; do convert AY, FCA1*(AY) (square the value)
  6726  ac04 2016ac             	JSR	LAB_EXP		; go do EXP(n)
  6727  ac07 68                 	PLA				; pull sign from stack
  6728  ac08 4a                 	LSR				; b0 is to be tested, shift to Cb
  6729  ac09 900a               	BCC	LAB_2AF9		; if no bit then exit
  6730                          
  6731                          					; Perform negation
  6732                          ; do - FAC1
  6733                          
  6734                          LAB_GTHAN
  6735  ac0b a5ac               	LDA	FAC1_e		; get FAC1 exponent
  6736  ac0d f006               	BEQ	LAB_2AF9		; exit if FAC1_e = $00
  6737                          
  6738  ac0f a5b0               	LDA	FAC1_s		; get FAC1 sign (b7)
  6739  ac11 49ff               	EOR	#$FF			; complement it
  6740  ac13 85b0               	STA	FAC1_s		; save FAC1 sign (b7)
  6741                          LAB_2AF9
  6742  ac15 60                 	RTS
  6743                          
  6744                          ; perform EXP()	(x^e)
  6745                          
  6746                          LAB_EXP
  6747  ac16 a9a4               	LDA	#<LAB_2AFA		; set 1.443 pointer low byte
  6748  ac18 a0b1               	LDY	#>LAB_2AFA		; set 1.443 pointer high byte
  6749  ac1a 2050a7             	JSR	LAB_25FB		; do convert AY, FCA1*(AY)
  6750  ac1d a5b9               	LDA	FAC1_r		; get FAC1 rounding byte
  6751  ac1f 6950               	ADC	#$50			; +$50/$100
  6752  ac21 9003               	BCC	LAB_2B2B		; skip rounding if no carry
  6753                          
  6754  ac23 20f8a8             	JSR	LAB_27C2		; round FAC1 (no check)
  6755                          LAB_2B2B
  6756  ac26 85a3               	STA	FAC2_r		; save FAC2 rounding byte
  6757  ac28 20e4a8             	JSR	LAB_27AE		; copy FAC1 to FAC2
  6758  ac2b a5ac               	LDA	FAC1_e		; get FAC1 exponent
  6759  ac2d c988               	CMP	#$88			; compare with EXP limit (256d)
  6760  ac2f 9003               	BCC	LAB_2B39		; branch if less
  6761                          
  6762                          LAB_2B36
  6763  ac31 20e5a7             	JSR	LAB_2690		; handle overflow and underflow
  6764                          LAB_2B39
  6765  ac34 2098a9             	JSR	LAB_INT		; perform INT
  6766  ac37 a55b               	LDA	Temp3			; get mantissa 3 from INT() function
  6767  ac39 18                 	CLC				; clear carry for add
  6768  ac3a 6981               	ADC	#$81			; normalise +1
  6769  ac3c f0f3               	BEQ	LAB_2B36		; if $00 go handle overflow
  6770                          
  6771  ac3e 38                 	SEC				; set carry for subtract
  6772  ac3f e901               	SBC	#$01			; now correct for exponent
  6773  ac41 48                 	PHA				; save FAC2 exponent
  6774                          
  6775                          					; swap FAC1 and FAC2
  6776  ac42 a204               	LDX	#$04			; 4 bytes to do
  6777                          LAB_2B49
  6778  ac44 b5b3               	LDA	FAC2_e,X		; get FAC2,X
  6779  ac46 b4ac               	LDY	FAC1_e,X		; get FAC1,X
  6780  ac48 95ac               	STA	FAC1_e,X		; save FAC1,X
  6781  ac4a 94b3               	STY	FAC2_e,X		; save FAC2,X
  6782  ac4c ca                 	DEX				; decrement count/index
  6783  ac4d 10f5               	BPL	LAB_2B49		; loop if not all done
  6784                          
  6785  ac4f a5a3               	LDA	FAC2_r		; get FAC2 rounding byte
  6786  ac51 85b9               	STA	FAC1_r		; save as FAC1 rounding byte
  6787  ac53 20bda5             	JSR	LAB_SUBTRACT	; perform subtraction, FAC2 from FAC1
  6788  ac56 200bac             	JSR	LAB_GTHAN		; do - FAC1
  6789  ac59 a9a8               	LDA	#<LAB_2AFE		; set counter pointer low byte
  6790  ac5b a0b1               	LDY	#>LAB_2AFE		; set counter pointer high byte
  6791  ac5d 207eac             	JSR	LAB_2B84		; go do series evaluation
  6792  ac60 a900               	LDA	#$00			; clear A
  6793  ac62 85b8               	STA	FAC_sc		; clear sign compare (FAC1 EOR FAC2)
  6794  ac64 68                 	PLA				;.get saved FAC2 exponent
  6795  ac65 4ccaa7             	JMP	LAB_2675		; test and adjust accumulators and return
  6796                          
  6797                          ; ^2 then series evaluation
  6798                          
  6799                          LAB_2B6E
  6800  ac68 85ba               	STA	Cptrl			; save count pointer low byte
  6801  ac6a 84bb               	STY	Cptrh			; save count pointer high byte
  6802  ac6c 20b4a8             	JSR	LAB_276E		; pack FAC1 into Adatal
  6803  ac6f a9a4               	LDA	#<Adatal		; set pointer low byte (Y already $00)
  6804  ac71 2050a7             	JSR	LAB_25FB		; do convert AY, FCA1*(AY)
  6805  ac74 2082ac             	JSR	LAB_2B88		; go do series evaluation
  6806  ac77 a9a4               	LDA	#<Adatal		; pointer to original # low byte
  6807  ac79 a000               	LDY	#>Adatal		; pointer to original # high byte
  6808  ac7b 4c50a7             	JMP	LAB_25FB		; do convert AY, FCA1*(AY) and return
  6809                          
  6810                          ; series evaluation
  6811                          
  6812                          LAB_2B84
  6813  ac7e 85ba               	STA	Cptrl			; save count pointer low byte
  6814  ac80 84bb               	STY	Cptrh			; save count pointer high byte
  6815                          LAB_2B88
  6816  ac82 a2a8               	LDX	#<numexp		; set pointer low byte
  6817  ac84 20b6a8             	JSR	LAB_2770		; set pointer high byte and pack FAC1 into numexp
  6818  ac87 b1ba               	LDA	(Cptrl),Y		; get constants count
  6819  ac89 85b1               	STA	numcon		; save constants count
  6820  ac8b a4ba               	LDY	Cptrl			; get count pointer low byte
  6821  ac8d c8                 	INY				; increment it (now constants pointer)
  6822  ac8e 98                 	TYA				; copy it
  6823  ac8f d002               	BNE	LAB_2B97		; skip next if no overflow
  6824                          
  6825  ac91 e6bb               	INC	Cptrh			; else increment high byte
  6826                          LAB_2B97
  6827  ac93 85ba               	STA	Cptrl			; save low byte
  6828  ac95 a4bb               	LDY	Cptrh			; get high byte
  6829                          LAB_2B9B
  6830  ac97 2050a7             	JSR	LAB_25FB		; do convert AY, FCA1*(AY)
  6831  ac9a a5ba               	LDA	Cptrl			; get constants pointer low byte
  6832  ac9c a4bb               	LDY	Cptrh			; get constants pointer high byte
  6833  ac9e 18                 	CLC				; clear carry for add
  6834  ac9f 6904               	ADC	#$04			; +4 to  low pointer (4 bytes per constant)
  6835  aca1 9001               	BCC	LAB_2BA8		; skip next if no overflow
  6836                          
  6837  aca3 c8                 	INY				; increment high byte
  6838                          LAB_2BA8
  6839  aca4 85ba               	STA	Cptrl			; save pointer low byte
  6840  aca6 84bb               	STY	Cptrh			; save pointer high byte
  6841  aca8 20d5a5             	JSR	LAB_246C		; add (AY) to FAC1
  6842  acab a9a8               	LDA	#<numexp		; set pointer low byte to partial @ numexp
  6843  acad a000               	LDY	#>numexp		; set pointer high byte to partial @ numexp
  6844  acaf c6b1               	DEC	numcon		; decrement constants count
  6845  acb1 d0e4               	BNE	LAB_2B9B		; loop until all done
  6846                          
  6847  acb3 60                 	RTS
  6848                          
  6849                          ; RND(n), 32 bit Galoise version. make n=0 for 19th next number in sequence or n<>0
  6850                          ; to get 19th next number in sequence after seed n. This version of the PRNG uses
  6851                          ; the Galois method and a sample of 65536 bytes produced gives the following values.
  6852                          
  6853                          ; Entropy = 7.997442 bits per byte
  6854                          ; Optimum compression would reduce these 65536 bytes by 0 percent
  6855                          
  6856                          ; Chi square distribution for 65536 samples is 232.01, and
  6857                          ; randomly would exceed this value 75.00 percent of the time
  6858                          
  6859                          ; Arithmetic mean value of data bytes is 127.6724, 127.5 would be random
  6860                          ; Monte Carlo value for Pi is 3.122871269, error 0.60 percent
  6861                          ; Serial correlation coefficient is -0.000370, totally uncorrelated would be 0.0
  6862                          
  6863                          LAB_RND
  6864  acb4 a5ac               	LDA	FAC1_e		; get FAC1 exponent
  6865  acb6 f007               	BEQ	NextPRN		; do next random # if zero
  6866                          
  6867                          					; else get seed into random number store
  6868  acb8 a2d8               	LDX	#Rbyte4		; set PRNG pointer low byte
  6869  acba a000               	LDY	#$00			; set PRNG pointer high byte
  6870  acbc 20bea8             	JSR	LAB_2778		; pack FAC1 into (XY)
  6871                          NextPRN
  6872  acbf a2af               	LDX	#$AF			; set EOR byte
  6873  acc1 a013               	LDY	#$13			; do this nineteen times
  6874                          LoopPRN
  6875  acc3 06d9               	ASL	Rbyte1		; shift PRNG most significant byte
  6876  acc5 26da               	ROL	Rbyte2		; shift PRNG middle byte
  6877  acc7 26db               	ROL	Rbyte3		; shift PRNG least significant byte
  6878  acc9 26d8               	ROL	Rbyte4		; shift PRNG extra byte
  6879  accb 9005               	BCC	Ninc1			; branch if bit 32 clear
  6880                          
  6881  accd 8a                 	TXA				; set EOR byte
  6882  acce 45d9               	EOR	Rbyte1		; EOR PRNG extra byte
  6883  acd0 85d9               	STA	Rbyte1		; save new PRNG extra byte
  6884                          Ninc1
  6885  acd2 88                 	DEY				; decrement loop count
  6886  acd3 d0ee               	BNE	LoopPRN		; loop if not all done
  6887                          
  6888  acd5 a202               	LDX	#$02			; three bytes to copy
  6889                          CopyPRNG
  6890  acd7 b5d9               	LDA	Rbyte1,X		; get PRNG byte
  6891  acd9 95ad               	STA	FAC1_1,X		; save FAC1 byte
  6892  acdb ca                 	DEX
  6893  acdc 10f9               	BPL	CopyPRNG		; loop if not complete
  6894                          
  6895  acde a980               	LDA	#$80			; set the exponent
  6896  ace0 85ac               	STA	FAC1_e		; save FAC1 exponent
  6897                          
  6898  ace2 0a                 	ASL				; clear A
  6899  ace3 85b0               	STA	FAC1_s		; save FAC1 sign
  6900                          
  6901  ace5 4c4ba6             	JMP	LAB_24D5		; normalise FAC1 and return
  6902                          
  6903                          ; perform COS()
  6904                          
  6905                          LAB_COS
  6906  ace8 a9c5               	LDA	#<LAB_2C78		; set (pi/2) pointer low byte
  6907  acea a0b1               	LDY	#>LAB_2C78		; set (pi/2) pointer high byte
  6908  acec 20d5a5             	JSR	LAB_246C		; add (AY) to FAC1
  6909                          
  6910                          ; perform SIN()
  6911                          
  6912                          LAB_SIN
  6913  acef 20e1a8             	JSR	LAB_27AB		; round and copy FAC1 to FAC2
  6914  acf2 a9da               	LDA	#<LAB_2C7C		; set (2*pi) pointer low byte
  6915  acf4 a0b1               	LDY	#>LAB_2C7C		; set (2*pi) pointer high byte
  6916  acf6 a6b7               	LDX	FAC2_s		; get FAC2 sign (b7)
  6917  acf8 2010a8             	JSR	LAB_26C2		; divide by (AY) (X=sign)
  6918  acfb 20e1a8             	JSR	LAB_27AB		; round and copy FAC1 to FAC2
  6919  acfe 2098a9             	JSR	LAB_INT		; perform INT
  6920  ad01 a900               	LDA	#$00			; clear byte
  6921  ad03 85b8               	STA	FAC_sc		; clear sign compare (FAC1 EOR FAC2)
  6922  ad05 20bda5             	JSR	LAB_SUBTRACT	; perform subtraction, FAC2 from FAC1
  6923  ad08 a90c               	LDA	#<LAB_2C80		; set 0.25 pointer low byte
  6924  ad0a a0b2               	LDY	#>LAB_2C80		; set 0.25 pointer high byte
  6925  ad0c 20baa5             	JSR	LAB_2455		; perform subtraction, (AY) from FAC1
  6926  ad0f a5b0               	LDA	FAC1_s		; get FAC1 sign (b7)
  6927  ad11 48                 	PHA				; save FAC1 sign
  6928  ad12 100d               	BPL	LAB_2C35		; branch if +ve
  6929                          
  6930                          					; FAC1 sign was -ve
  6931  ad14 20d1a5             	JSR	LAB_244E		; add 0.5 to FAC1
  6932  ad17 a5b0               	LDA	FAC1_s		; get FAC1 sign (b7)
  6933  ad19 3009               	BMI	LAB_2C38		; branch if -ve
  6934                          
  6935  ad1b a563               	LDA	Cflag			; get comparison evaluation flag
  6936  ad1d 49ff               	EOR	#$FF			; toggle flag
  6937  ad1f 8563               	STA	Cflag			; save comparison evaluation flag
  6938                          LAB_2C35
  6939  ad21 200bac             	JSR	LAB_GTHAN		; do - FAC1
  6940                          LAB_2C38
  6941  ad24 a90c               	LDA	#<LAB_2C80		; set 0.25 pointer low byte
  6942  ad26 a0b2               	LDY	#>LAB_2C80		; set 0.25 pointer high byte
  6943  ad28 20d5a5             	JSR	LAB_246C		; add (AY) to FAC1
  6944  ad2b 68                 	PLA				; restore FAC1 sign
  6945  ad2c 1003               	BPL	LAB_2C45		; branch if was +ve
  6946                          
  6947                          					; else correct FAC1
  6948  ad2e 200bac             	JSR	LAB_GTHAN		; do - FAC1
  6949                          LAB_2C45
  6950  ad31 a9c9               	LDA	#<LAB_2C84		; set pointer low byte to counter
  6951  ad33 a0b1               	LDY	#>LAB_2C84		; set pointer high byte to counter
  6952  ad35 4c68ac             	JMP	LAB_2B6E		; ^2 then series evaluation and return
  6953                          
  6954                          ; perform TAN()
  6955                          
  6956                          LAB_TAN
  6957  ad38 20b4a8             	JSR	LAB_276E		; pack FAC1 into Adatal
  6958  ad3b a900               	LDA	#$00			; clear byte
  6959  ad3d 8563               	STA	Cflag			; clear comparison evaluation flag
  6960  ad3f 20efac             	JSR	LAB_SIN		; go do SIN(n)
  6961  ad42 a29c               	LDX	#<func_l		; set sin(n) pointer low byte
  6962  ad44 a000               	LDY	#>func_l		; set sin(n) pointer high byte
  6963  ad46 20bea8             	JSR	LAB_2778		; pack FAC1 into (XY)
  6964  ad49 a9a4               	LDA	#<Adatal		; set n pointer low addr
  6965  ad4b a000               	LDY	#>Adatal		; set n pointer high addr
  6966  ad4d 2094a8             	JSR	LAB_UFAC		; unpack memory (AY) into FAC1
  6967  ad50 a900               	LDA	#$00			; clear byte
  6968  ad52 85b0               	STA	FAC1_s		; clear FAC1 sign (b7)
  6969  ad54 a563               	LDA	Cflag			; get comparison evaluation flag
  6970  ad56 2060ad             	JSR	LAB_2C74		; save flag and go do series evaluation
  6971                          
  6972  ad59 a99c               	LDA	#<func_l		; set sin(n) pointer low byte
  6973  ad5b a000               	LDY	#>func_l		; set sin(n) pointer high byte
  6974  ad5d 4c18a8             	JMP	LAB_26CA		; convert AY and do (AY)/FAC1
  6975                          
  6976                          LAB_2C74
  6977  ad60 48                 	PHA				; save comparison evaluation flag
  6978  ad61 4c21ad             	JMP	LAB_2C35		; go do series evaluation
  6979                          
  6980                          ; perform USR()
  6981                          
  6982                          LAB_USR
  6983  ad64 200a00             	JSR	Usrjmp		; call user code
  6984  ad67 4c069c             	JMP	LAB_1BFB		; scan for ")", else do syntax error then warm start
  6985                          
  6986                          ; perform ATN()
  6987                          
  6988                          LAB_ATN
  6989  ad6a a5b0               	LDA	FAC1_s		; get FAC1 sign (b7)
  6990  ad6c 48                 	PHA				; save sign
  6991  ad6d 1003               	BPL	LAB_2CA1		; branch if +ve
  6992                          
  6993  ad6f 200bac             	JSR	LAB_GTHAN		; else do - FAC1
  6994                          LAB_2CA1
  6995  ad72 a5ac               	LDA	FAC1_e		; get FAC1 exponent
  6996  ad74 48                 	PHA				; push exponent
  6997  ad75 c981               	CMP	#$81			; compare with 1
  6998  ad77 9007               	BCC	LAB_2CAF		; branch if FAC1<1
  6999                          
  7000  ad79 a9ff               	LDA	#<LAB_259C		; set 1 pointer low byte
  7001  ad7b a0b1               	LDY	#>LAB_259C		; set 1 pointer high byte
  7002  ad7d 2018a8             	JSR	LAB_26CA		; convert AY and do (AY)/FAC1
  7003                          LAB_2CAF
  7004  ad80 a9de               	LDA	#<LAB_2CC9		; set pointer low byte to counter
  7005  ad82 a0b1               	LDY	#>LAB_2CC9		; set pointer high byte to counter
  7006  ad84 2068ac             	JSR	LAB_2B6E		; ^2 then series evaluation
  7007  ad87 68                 	PLA				; restore old FAC1 exponent
  7008  ad88 c981               	CMP	#$81			; compare with 1
  7009  ad8a 9007               	BCC	LAB_2CC2		; branch if FAC1<1
  7010                          
  7011  ad8c a9c5               	LDA	#<LAB_2C78		; set (pi/2) pointer low byte
  7012  ad8e a0b1               	LDY	#>LAB_2C78		; set (pi/2) pointer high byte
  7013  ad90 20baa5             	JSR	LAB_2455		; perform subtraction, (AY) from FAC1
  7014                          LAB_2CC2
  7015  ad93 68                 	PLA				; restore FAC1 sign
  7016  ad94 1016               	BPL	LAB_2D04		; exit if was +ve
  7017                          
  7018  ad96 4c0bac             	JMP	LAB_GTHAN		; else do - FAC1 and return
  7019                          
  7020                          ; perform BITSET
  7021                          
  7022                          LAB_BITSET
  7023  ad99 20efa4             	JSR	LAB_GADB		; get two parameters for POKE or WAIT
  7024  ad9c e008               	CPX	#$08			; only 0 to 7 are allowed
  7025  ad9e b020               	BCS	FCError		; branch if > 7
  7026                          
  7027  ada0 a900               	LDA	#$00			; clear A
  7028  ada2 38                 	SEC				; set the carry
  7029                          S_Bits
  7030  ada3 2a                 	ROL				; shift bit
  7031  ada4 ca                 	DEX				; decrement bit number
  7032  ada5 10fc               	BPL	S_Bits		; loop if still +ve
  7033                          
  7034  ada7 e8                 	INX				; make X = $00
  7035  ada8 0111               	ORA	(Itempl,X)		; or with byte via temporary integer (addr)
  7036  adaa 8111               	STA	(Itempl,X)		; save byte via temporary integer (addr)
  7037                          LAB_2D04
  7038  adac 60                 	RTS
  7039                          
  7040                          ; perform BITCLR
  7041                          
  7042                          LAB_BITCLR
  7043  adad 20efa4             	JSR	LAB_GADB		; get two parameters for POKE or WAIT
  7044  adb0 e008               	CPX	#$08			; only 0 to 7 are allowed
  7045  adb2 b00c               	BCS	FCError		; branch if > 7
  7046                          
  7047  adb4 a9ff               	LDA	#$FF			; set A
  7048                          S_Bitc
  7049  adb6 2a                 	ROL				; shift bit
  7050  adb7 ca                 	DEX				; decrement bit number
  7051  adb8 10fc               	BPL	S_Bitc		; loop if still +ve
  7052                          
  7053  adba e8                 	INX				; make X = $00
  7054  adbb 2111               	AND	(Itempl,X)		; and with byte via temporary integer (addr)
  7055  adbd 8111               	STA	(Itempl,X)		; save byte via temporary integer (addr)
  7056  adbf 60                 	RTS
  7057                          
  7058                          FCError
  7059  adc0 4c409f             	JMP	LAB_FCER		; do function call error then warm start
  7060                          
  7061                          ; perform BITTST()
  7062                          
  7063                          LAB_BTST
  7064  adc3 20bc00             	JSR	LAB_IGBY		; increment BASIC pointer
  7065  adc6 20efa4             	JSR	LAB_GADB		; get two parameters for POKE or WAIT
  7066  adc9 e008               	CPX	#$08			; only 0 to 7 are allowed
  7067  adcb b0f3               	BCS	FCError		; branch if > 7
  7068                          
  7069  adcd 20c200             	JSR	LAB_GBYT		; get next BASIC byte
  7070  add0 c929               	CMP	#')'			; is next character ")"
  7071  add2 f003               	BEQ	TST_OK		; if ")" go do rest of function
  7072                          
  7073  add4 4c199c             	JMP	LAB_SNER		; do syntax error then warm start
  7074                          
  7075                          TST_OK
  7076  add7 20bc00             	JSR	LAB_IGBY		; update BASIC execute pointer (to character past ")")
  7077  adda a900               	LDA	#$00			; clear A
  7078  addc 38                 	SEC				; set the carry
  7079                          T_Bits
  7080  addd 2a                 	ROL				; shift bit
  7081  adde ca                 	DEX				; decrement bit number
  7082  addf 10fc               	BPL	T_Bits		; loop if still +ve
  7083                          
  7084  ade1 e8                 	INX				; make X = $00
  7085  ade2 2111               	AND	(Itempl,X)		; AND with byte via temporary integer (addr)
  7086  ade4 f002               	BEQ	LAB_NOTT		; branch if zero (already correct)
  7087                          
  7088  ade6 a9ff               	LDA	#$FF			; set for -1 result
  7089                          LAB_NOTT
  7090  ade8 4c11a9             	JMP	LAB_27DB		; go do SGN tail
  7091                          
  7092                          ; perform BIN$()
  7093                          
  7094                          LAB_BINS
  7095  adeb e019               	CPX	#$19			; max + 1
  7096  aded b048               	BCS	BinFErr		; exit if too big ( > or = )
  7097                          
  7098  adef 8678               	STX	TempB			; save # of characters ($00 = leading zero remove)
  7099  adf1 a918               	LDA	#$18			; need A byte long space
  7100  adf3 2051a1             	JSR	LAB_MSSP		; make string space A bytes long
  7101  adf6 a017               	LDY	#$17			; set index
  7102  adf8 a218               	LDX	#$18			; character count
  7103                          NextB1
  7104  adfa 4611               	LSR	nums_1		; shift highest byte
  7105  adfc 6612               	ROR	nums_2		; shift middle byte
  7106  adfe 6613               	ROR	nums_3		; shift lowest byte bit 0 to carry
  7107  ae00 8a                 	TXA				; load with "0"/2
  7108  ae01 2a                 	ROL				; shift in carry
  7109  ae02 91ad               	STA	(str_pl),Y		; save to temp string + index
  7110  ae04 88                 	DEY				; decrement index
  7111  ae05 10f3               	BPL	NextB1		; loop if not done
  7112                          
  7113  ae07 a578               	LDA	TempB			; get # of characters
  7114  ae09 f00a               	BEQ	EndBHS		; branch if truncate
  7115                          
  7116  ae0b aa                 	TAX				; copy length to X
  7117  ae0c 38                 	SEC				; set carry for add !
  7118  ae0d 49ff               	EOR	#$FF			; 1's complement
  7119  ae0f 6918               	ADC	#$18			; add 24d
  7120  ae11 f01c               	BEQ	GoPr2			; if zero print whole string
  7121                          
  7122  ae13 d00f               	BNE	GoPr1			; else go make output string
  7123                          	
  7124                          ; this is the exit code and is also used by HEX$()
  7125                          ; truncate string to remove leading "0"s
  7126                          
  7127                          EndBHS
  7128  ae15 a8                 	TAY				; clear index (A=0, X=length here)
  7129                          NextB2
  7130  ae16 b1ad               	LDA	(str_pl),Y		; get character from string
  7131  ae18 c930               	CMP	#'0'			; compare with "0"
  7132  ae1a d007               	BNE	GoPr			; if not "0" then go print string from here
  7133                          
  7134  ae1c ca                 	DEX				; decrement character count
  7135  ae1d f003               	BEQ	GoPr3			; if zero then end of string so go print it
  7136                          
  7137  ae1f c8                 	INY				; else increment index
  7138  ae20 10f4               	BPL	NextB2		; loop always
  7139                          
  7140                          ; make fixed length output string - ignore overflows!
  7141                          
  7142                          GoPr3
  7143  ae22 e8                 	INX				; need at least 1 character
  7144                          GoPr
  7145  ae23 98                 	TYA				; copy result
  7146                          GoPr1
  7147  ae24 18                 	CLC				; clear carry for add
  7148  ae25 65ad               	ADC	str_pl		; add low address
  7149  ae27 85ad               	STA	str_pl		; save low address
  7150  ae29 a900               	LDA	#$00			; do high byte
  7151  ae2b 65ae               	ADC	str_ph		; add high address
  7152  ae2d 85ae               	STA	str_ph		; save high address
  7153                          GoPr2
  7154  ae2f 86ac               	STX	str_ln		; X holds string length
  7155  ae31 20bc00             	JSR	LAB_IGBY		; update BASIC execute pointer (to character past ")")
  7156  ae34 4c9ca1             	JMP	LAB_RTST		; check for space on descriptor stack then put address
  7157                          					; and length on descriptor stack and update stack pointers
  7158                          
  7159                          BinFErr
  7160  ae37 4c409f             	JMP	LAB_FCER		; do function call error then warm start
  7161                          
  7162                          ; perform HEX$()
  7163                          
  7164                          LAB_HEXS
  7165  ae3a e007               	CPX	#$07			; max + 1
  7166  ae3c b0f9               	BCS	BinFErr		; exit if too big ( > or = )
  7167                          
  7168  ae3e 8678               	STX	TempB			; save # of characters
  7169                          
  7170  ae40 a906               	LDA	#$06			; need 6 bytes for string
  7171  ae42 2051a1             	JSR	LAB_MSSP		; make string space A bytes long
  7172  ae45 a005               	LDY	#$05			; set string index
  7173                          
  7174  ae47 f8                 	SED				; need decimal mode for nibble convert
  7175  ae48 a513               	LDA	nums_3		; get lowest byte
  7176  ae4a 2068ae             	JSR	LAB_A2HX		; convert A to ASCII hex byte and output
  7177  ae4d a512               	LDA	nums_2		; get middle byte
  7178  ae4f 2068ae             	JSR	LAB_A2HX		; convert A to ASCII hex byte and output
  7179  ae52 a511               	LDA	nums_1		; get highest byte
  7180  ae54 2068ae             	JSR	LAB_A2HX		; convert A to ASCII hex byte and output
  7181  ae57 d8                 	CLD				; back to binary
  7182                          
  7183  ae58 a206               	LDX	#$06			; character count
  7184  ae5a a578               	LDA	TempB			; get # of characters
  7185  ae5c f0b7               	BEQ	EndBHS		; branch if truncate
  7186                          
  7187  ae5e aa                 	TAX				; copy length to X
  7188  ae5f 38                 	SEC				; set carry for add !
  7189  ae60 49ff               	EOR	#$FF			; 1's complement
  7190  ae62 6906               	ADC	#$06			; add 6d
  7191  ae64 f0c9               	BEQ	GoPr2			; if zero print whole string
  7192                          
  7193  ae66 d0bc               	BNE	GoPr1			; else go make output string (branch always)
  7194                          
  7195                          ; convert A to ASCII hex byte and output .. note set decimal mode before calling
  7196                          
  7197                          LAB_A2HX
  7198  ae68 aa                 	TAX				; save byte
  7199  ae69 290f               	AND	#$0F			; mask off top bits
  7200  ae6b 2073ae             	JSR	LAB_AL2X		; convert low nibble to ASCII and output
  7201  ae6e 8a                 	TXA				; get byte back
  7202  ae6f 4a                 	LSR				; /2	shift high nibble to low nibble
  7203  ae70 4a                 	LSR				; /4
  7204  ae71 4a                 	LSR				; /8
  7205  ae72 4a                 	LSR				; /16
  7206                          LAB_AL2X
  7207  ae73 c90a               	CMP	#$0A			; set carry for +1 if >9
  7208  ae75 6930               	ADC	#'0'			; add ASCII "0"
  7209  ae77 91ad               	STA	(str_pl),Y		; save to temp string
  7210  ae79 88                 	DEY				; decrement counter
  7211  ae7a 60                 	RTS
  7212                          
  7213                          LAB_NLTO
  7214  ae7b 85ac               	STA	FAC1_e		; save FAC1 exponent
  7215  ae7d a900               	LDA	#$00			; clear sign compare
  7216                          LAB_MLTE
  7217  ae7f 85b8               	STA	FAC_sc		; save sign compare (FAC1 EOR FAC2)
  7218  ae81 8a                 	TXA				; restore character
  7219  ae82 205caa             	JSR	LAB_2912		; evaluate new ASCII digit
  7220                          
  7221                          ; gets here if the first character was "$" for hex
  7222                          ; get hex number
  7223                          
  7224                          LAB_CHEX
  7225  ae85 20bc00             	JSR	LAB_IGBY		; increment and scan memory
  7226  ae88 900a               	BCC	LAB_ISHN		; branch if numeric character
  7227                          
  7228  ae8a 0920               	ORA	#$20			; case convert, allow "A" to "F" and "a" to "f"
  7229  ae8c e961               	SBC	#'a'			; subtract "a" (carry set here)
  7230  ae8e c906               	CMP	#$06			; compare normalised with $06 (max+1)
  7231  ae90 b02a               	BCS	LAB_EXCH		; exit if >"f" or <"0"
  7232                          
  7233  ae92 690a               	ADC	#$0A			; convert to nibble
  7234                          LAB_ISHN
  7235  ae94 290f               	AND	#$0F			; convert to binary
  7236  ae96 aa                 	TAX				; save nibble
  7237  ae97 a5ac               	LDA	FAC1_e		; get FAC1 exponent
  7238  ae99 f0e4               	BEQ	LAB_MLTE		; skip multiply if zero
  7239                          
  7240  ae9b 6904               	ADC	#$04			; add four to exponent (*16 - carry clear here)
  7241  ae9d 90dc               	BCC	LAB_NLTO		; if no overflow do evaluate digit
  7242                          
  7243                          LAB_MLTO
  7244  ae9f 4cdaa6             	JMP	LAB_2564		; do overflow error and warm start
  7245                          
  7246                          LAB_NXCH
  7247  aea2 aa                 	TAX				; save bit
  7248  aea3 a5ac               	LDA	FAC1_e		; get FAC1 exponent
  7249  aea5 f006               	BEQ	LAB_MLBT		; skip multiply if zero
  7250                          
  7251  aea7 e6ac               	INC	FAC1_e		; increment FAC1 exponent (*2)
  7252  aea9 f0f4               	BEQ	LAB_MLTO		; do overflow error if = $00
  7253                          
  7254  aeab a900               	LDA	#$00			; clear sign compare
  7255                          LAB_MLBT
  7256  aead 85b8               	STA	FAC_sc		; save sign compare (FAC1 EOR FAC2)
  7257  aeaf 8a                 	TXA				; restore bit
  7258  aeb0 205caa             	JSR	LAB_2912		; evaluate new ASCII digit
  7259                          
  7260                          ; gets here if the first character was  "%" for binary
  7261                          ; get binary number
  7262                          
  7263                          LAB_CBIN
  7264  aeb3 20bc00             	JSR	LAB_IGBY		; increment and scan memory
  7265  aeb6 4930               	EOR	#'0'			; convert "0" to 0 etc.
  7266  aeb8 c902               	CMP	#$02			; compare with max+1
  7267  aeba 90e6               	BCC	LAB_NXCH		; branch exit if < 2
  7268                          
  7269                          LAB_EXCH
  7270  aebc 4c41aa             	JMP	LAB_28F6		; evaluate -ve flag and return
  7271                          
  7272                          ; ctrl-c check routine. includes limited "life" byte save for INGET routine
  7273                          ; now also the code that checks to see if an interrupt has occurred
  7274                          
  7275                          CTRLC
  7276  aebf ad0003             	LDA	ccflag		; get [CTRL-C] check flag
  7277  aec2 d018               	BNE	LAB_FBA2		; exit if inhibited
  7278                          
  7279  aec4 2009b1             	JSR	V_INPT		; scan input device
  7280  aec7 900b               	BCC	LAB_FBA0		; exit if buffer empty
  7281                          
  7282  aec9 8d0103             	STA	ccbyte		; save received byte
  7283  aecc a220               	LDX	#$20			; "life" timer for bytes
  7284  aece 8e0203             	STX	ccnull		; set countdown
  7285  aed1 4c2e95             	JMP	LAB_1636		; return to BASIC
  7286                          
  7287                          LAB_FBA0
  7288  aed4 ae0203             	LDX	ccnull		; get countdown byte
  7289  aed7 f003               	BEQ	LAB_FBA2		; exit if finished
  7290                          
  7291  aed9 ce0203             	DEC	ccnull		; else decrement countdown
  7292                          LAB_FBA2
  7293  aedc a2dc               	LDX	#NmiBase		; set pointer to NMI values
  7294  aede 20e7ae             	JSR	LAB_CKIN		; go check interrupt
  7295  aee1 a2df               	LDX	#IrqBase		; set pointer to IRQ values
  7296  aee3 20e7ae             	JSR	LAB_CKIN		; go check interrupt
  7297                          LAB_CRTS
  7298  aee6 60                 	RTS
  7299                          
  7300                          ; check whichever interrupt is indexed by X
  7301                          
  7302                          LAB_CKIN
  7303  aee7 b500               	LDA	PLUS_0,X		; get interrupt flag byte
  7304  aee9 10fb               	BPL	LAB_CRTS		; branch if interrupt not enabled
  7305                          
  7306                          ; we disable the interrupt here and make two new commands RETIRQ and RETNMI to
  7307                          ; automatically enable the interrupt when we exit
  7308                          
  7309  aeeb 0a                 	ASL				; move happened bit to setup bit
  7310  aeec 2940               	AND	#$40			; mask happened bits
  7311  aeee f0f6               	BEQ	LAB_CRTS		; if no interrupt then exit
  7312                          
  7313  aef0 9500               	STA	PLUS_0,X		; save interrupt flag byte
  7314                          
  7315  aef2 8a                 	TXA				; copy index ..
  7316  aef3 a8                 	TAY				; .. to Y
  7317                          
  7318  aef4 68                 	PLA				; dump return address low byte, call from CTRL-C
  7319  aef5 68                 	PLA				; dump return address high byte
  7320                          
  7321  aef6 a905               	LDA	#$05			; need 5 bytes for GOSUB
  7322  aef8 200e91             	JSR	LAB_1212		; check room on stack for A bytes
  7323  aefb a5c4               	LDA	Bpntrh		; get BASIC execute pointer high byte
  7324  aefd 48                 	PHA				; push on stack
  7325  aefe a5c3               	LDA	Bpntrl		; get BASIC execute pointer low byte
  7326  af00 48                 	PHA				; push on stack
  7327  af01 a588               	LDA	Clineh		; get current line high byte
  7328  af03 48                 	PHA				; push on stack
  7329  af04 a587               	LDA	Clinel		; get current line low byte
  7330  af06 48                 	PHA				; push on stack
  7331  af07 a98d               	LDA	#TK_GOSUB		; token for GOSUB
  7332  af09 48                 	PHA				; push on stack
  7333                          
  7334  af0a b90100             	LDA	PLUS_1,Y		; get interrupt code pointer low byte
  7335  af0d 85c3               	STA	Bpntrl		; save as BASIC execute pointer low byte
  7336  af0f b90200             	LDA	PLUS_2,Y		; get interrupt code pointer high byte
  7337  af12 85c4               	STA	Bpntrh		; save as BASIC execute pointer high byte
  7338                          
  7339  af14 4cd394             	JMP	LAB_15C2		; go do interpreter inner loop
  7340                          					; can't RTS, we used the stack! the RTS from the ctrl-c
  7341                          					; check will be taken when the RETIRQ/RETNMI/RETURN is
  7342                          					; executed at the end of the subroutine
  7343                          
  7344                          ; get byte from input device, no waiting
  7345                          ; returns with carry set if byte in A
  7346                          
  7347                          INGET
  7348  af17 2009b1             	JSR	V_INPT		; call scan input device
  7349  af1a b009               	BCS	LAB_FB95		; if byte go reset timer
  7350                          
  7351  af1c ad0203             	LDA	ccnull		; get countdown
  7352  af1f f009               	BEQ	LAB_FB96		; exit if empty
  7353                          
  7354  af21 ad0103             	LDA	ccbyte		; get last received byte
  7355  af24 38                 	SEC				; flag we got a byte
  7356                          LAB_FB95
  7357  af25 a200               	LDX	#$00			; clear X
  7358  af27 8e0203             	STX	ccnull		; clear timer because we got a byte
  7359                          LAB_FB96
  7360  af2a 60                 	RTS
  7361                          
  7362                          ; these routines only enable the interrupts if the set-up flag is set
  7363                          ; if not they have no effect
  7364                          
  7365                          ; perform IRQ {ON|OFF|CLEAR}
  7366                          
  7367                          LAB_IRQ
  7368  af2b a2df               	LDX	#IrqBase		; set pointer to IRQ values
  7369  af2d 2c                 	!text	$2C			; make next line BIT abs.
  7370                          
  7371                          ; perform NMI {ON|OFF|CLEAR}
  7372                          
  7373                          LAB_NMI
  7374  af2e a2dc               	LDX	#NmiBase		; set pointer to NMI values
  7375  af30 c993               	CMP	#TK_ON		; compare with token for ON
  7376  af32 f011               	BEQ	LAB_INON		; go turn on interrupt
  7377                          
  7378  af34 c9ba               	CMP	#TK_OFF		; compare with token for OFF
  7379  af36 f007               	BEQ	LAB_IOFF		; go turn off interrupt
  7380                          
  7381  af38 49a5               	EOR	#TK_CLEAR		; compare with token for CLEAR, A = $00 if = TK_CLEAR
  7382  af3a f00e               	BEQ	LAB_INEX		; go clear interrupt flags and return
  7383                          
  7384  af3c 4c199c             	JMP	LAB_SNER		; do syntax error then warm start
  7385                          
  7386                          LAB_IOFF
  7387  af3f a97f               	LDA	#$7F			; clear A
  7388  af41 3500               	AND	PLUS_0,X		; AND with interrupt setup flag
  7389  af43 1005               	BPL	LAB_INEX		; go clear interrupt enabled flag and return
  7390                          
  7391                          LAB_INON
  7392  af45 b500               	LDA	PLUS_0,X		; get interrupt setup flag
  7393  af47 0a                 	ASL				; Shift bit to enabled flag
  7394  af48 1500               	ORA	PLUS_0,X		; OR with flag byte
  7395                          LAB_INEX
  7396  af4a 9500               	STA	PLUS_0,X		; save interrupt flag byte
  7397  af4c 4cbc00             	JMP	LAB_IGBY		; update BASIC execute pointer and return
  7398                          
  7399                          ; these routines set up the pointers and flags for the interrupt routines
  7400                          ; note that the interrupts are also enabled by these commands
  7401                          
  7402                          ; perform ON IRQ
  7403                          
  7404                          LAB_SIRQ
  7405  af4f 58                 	CLI				; enable interrupts
  7406  af50 a2df               	LDX	#IrqBase		; set pointer to IRQ values
  7407  af52 2c                 	!text	$2C			; make next line BIT abs.
  7408                          
  7409                          ; perform ON NMI
  7410                          
  7411                          LAB_SNMI
  7412  af53 a2dc               	LDX	#NmiBase		; set pointer to NMI values
  7413                          
  7414  af55 8678               	STX	TempB			; save interrupt pointer
  7415  af57 20bc00             	JSR	LAB_IGBY		; increment and scan memory (past token)
  7416  af5a 207197             	JSR	LAB_GFPN		; get fixed-point number into temp integer
  7417  af5d a579               	LDA	Smeml			; get start of mem low byte
  7418  af5f a67a               	LDX	Smemh			; get start of mem high byte
  7419  af61 203f93             	JSR	LAB_SHLN		; search Basic for temp integer line number from AX
  7420  af64 b003               	BCS	LAB_LFND		; if carry set go set-up interrupt
  7421                          
  7422  af66 4c8e96             	JMP	LAB_16F7		; else go do "Undefined statement" error and warm start
  7423                          
  7424                          LAB_LFND
  7425  af69 a678               	LDX	TempB			; get interrupt pointer
  7426  af6b a5aa               	LDA	Baslnl		; get pointer low byte
  7427  af6d e901               	SBC	#$01			; -1 (carry already set for subtract)
  7428  af6f 9501               	STA	PLUS_1,X		; save as interrupt pointer low byte
  7429  af71 a5ab               	LDA	Baslnh		; get pointer high byte
  7430  af73 e900               	SBC	#$00			; subtract carry
  7431  af75 9502               	STA	PLUS_2,X		; save as interrupt pointer high byte
  7432                          
  7433  af77 a9c0               	LDA	#$C0			; set interrupt enabled/setup bits
  7434  af79 9500               	STA	PLUS_0,X		; set interrupt flags
  7435                          LAB_IRTS
  7436  af7b 60                 	RTS
  7437                          
  7438                          ; return from IRQ service, restores the enabled flag.
  7439                          
  7440                          ; perform RETIRQ
  7441                          
  7442                          LAB_RETIRQ
  7443  af7c d0fd               	BNE	LAB_IRTS		; exit if following token (to allow syntax error)
  7444                          
  7445  af7e a5df               	LDA	IrqBase		; get interrupt flags
  7446  af80 0a                 	ASL				; copy setup to enabled (b7)
  7447  af81 05df               	ORA	IrqBase		; OR in setup flag
  7448  af83 85df               	STA	IrqBase		; save enabled flag
  7449  af85 4c9596             	JMP	LAB_16E8		; go do rest of RETURN
  7450                          
  7451                          ; return from NMI service, restores the enabled flag.
  7452                          
  7453                          ; perform RETNMI
  7454                          
  7455                          LAB_RETNMI
  7456  af88 d0f1               	BNE	LAB_IRTS		; exit if following token (to allow syntax error)
  7457                          
  7458  af8a a5dc               	LDA	NmiBase		; get set-up flag
  7459  af8c 0a                 	ASL				; copy setup to enabled (b7)
  7460  af8d 05dc               	ORA	NmiBase		; OR in setup flag
  7461  af8f 85dc               	STA	NmiBase		; save enabled flag
  7462  af91 4c9596             	JMP	LAB_16E8		; go do rest of RETURN
  7463                          
  7464                          ; MAX() MIN() pre process
  7465                          
  7466                          LAB_MMPP
  7467  af94 20009b             	JSR	LAB_EVEZ		; process expression
  7468  af97 4ce79a             	JMP	LAB_CTNM		; check if source is numeric, else do type mismatch
  7469                          
  7470                          ; perform MAX()
  7471                          
  7472                          LAB_MAX
  7473  af9a 20c8af             	JSR	LAB_PHFA		; push FAC1, evaluate expression,
  7474                          					; pull FAC2 and compare with FAC1
  7475  af9d 10fb               	BPL	LAB_MAX		; branch if no swap to do
  7476                          
  7477  af9f a5b4               	LDA	FAC2_1		; get FAC2 mantissa1
  7478  afa1 0980               	ORA	#$80			; set top bit (clear sign from compare)
  7479  afa3 85b4               	STA	FAC2_1		; save FAC2 mantissa1
  7480  afa5 20daa5             	JSR	LAB_279B		; copy FAC2 to FAC1
  7481  afa8 f0f0               	BEQ	LAB_MAX		; go do next (branch always)
  7482                          
  7483                          ; perform MIN()
  7484                          
  7485                          LAB_MIN
  7486  afaa 20c8af             	JSR	LAB_PHFA		; push FAC1, evaluate expression,
  7487                          					; pull FAC2 and compare with FAC1
  7488  afad 30fb               	BMI	LAB_MIN		; branch if no swap to do
  7489                          
  7490  afaf f0f9               	BEQ	LAB_MIN		; branch if no swap to do
  7491                          
  7492  afb1 a5b4               	LDA	FAC2_1		; get FAC2 mantissa1
  7493  afb3 0980               	ORA	#$80			; set top bit (clear sign from compare)
  7494  afb5 85b4               	STA	FAC2_1		; save FAC2 mantissa1
  7495  afb7 20daa5             	JSR	LAB_279B		; copy FAC2 to FAC1
  7496  afba f0ee               	BEQ	LAB_MIN		; go do next (branch always)
  7497                          
  7498                          ; exit routine. don't bother returning to the loop code
  7499                          ; check for correct exit, else so syntax error
  7500                          
  7501                          LAB_MMEC
  7502  afbc c929               	CMP	#')'			; is it end of function?
  7503  afbe d005               	BNE	LAB_MMSE		; if not do MAX MIN syntax error
  7504                          
  7505  afc0 68                 	PLA				; dump return address low byte
  7506  afc1 68                 	PLA				; dump return address high byte
  7507  afc2 4cbc00             	JMP	LAB_IGBY		; update BASIC execute pointer (to chr past ")")
  7508                          
  7509                          LAB_MMSE
  7510  afc5 4c199c             	JMP	LAB_SNER		; do syntax error then warm start
  7511                          
  7512                          ; check for next, evaluate and return or exit
  7513                          ; this is the routine that does most of the work
  7514                          
  7515                          LAB_PHFA
  7516  afc8 20c200             	JSR	LAB_GBYT		; get next BASIC byte
  7517  afcb c92c               	CMP	#','			; is there more ?
  7518  afcd d0ed               	BNE	LAB_MMEC		; if not go do end check
  7519                          
  7520                          					; push FAC1
  7521  afcf 20f0a8             	JSR	LAB_27BA		; round FAC1
  7522  afd2 a5b0               	LDA	FAC1_s		; get FAC1 sign
  7523  afd4 097f               	ORA	#$7F			; set all non sign bits
  7524  afd6 25ad               	AND	FAC1_1		; AND FAC1 mantissa1 (AND in sign bit)
  7525  afd8 48                 	PHA				; push on stack
  7526  afd9 a5ae               	LDA	FAC1_2		; get FAC1 mantissa2
  7527  afdb 48                 	PHA				; push on stack
  7528  afdc a5af               	LDA	FAC1_3		; get FAC1 mantissa3
  7529  afde 48                 	PHA				; push on stack
  7530  afdf a5ac               	LDA	FAC1_e		; get FAC1 exponent
  7531  afe1 48                 	PHA				; push on stack
  7532                          
  7533  afe2 20bc00             	JSR	LAB_IGBY		; scan and get next BASIC byte (after ",")
  7534  afe5 20e49a             	JSR	LAB_EVNM		; evaluate expression and check is numeric,
  7535                          					; else do type mismatch
  7536                          
  7537                          					; pop FAC2 (MAX/MIN expression so far)
  7538  afe8 68                 	PLA				; pop exponent
  7539  afe9 85b3               	STA	FAC2_e		; save FAC2 exponent
  7540  afeb 68                 	PLA				; pop mantissa3
  7541  afec 85b6               	STA	FAC2_3		; save FAC2 mantissa3
  7542  afee 68                 	PLA				; pop mantissa1
  7543  afef 85b5               	STA	FAC2_2		; save FAC2 mantissa2
  7544  aff1 68                 	PLA				; pop sign/mantissa1
  7545  aff2 85b4               	STA	FAC2_1		; save FAC2 sign/mantissa1
  7546  aff4 85b7               	STA	FAC2_s		; save FAC2 sign
  7547                          
  7548                          					; compare FAC1 with (packed) FAC2
  7549  aff6 a9b3               	LDA	#<FAC2_e		; set pointer low byte to FAC2
  7550  aff8 a000               	LDY	#>FAC2_e		; set pointer high byte to FAC2
  7551  affa 4c2ea9             	JMP	LAB_27F8		; compare FAC1 with FAC2 (AY) and return
  7552                          					; returns A=$00 if FAC1 = (AY)
  7553                          					; returns A=$01 if FAC1 > (AY)
  7554                          					; returns A=$FF if FAC1 < (AY)
  7555                          
  7556                          ; perform WIDTH
  7557                          
  7558                          LAB_WDTH
  7559  affd c92c               	CMP	#','			; is next byte ","
  7560  afff f01b               	BEQ	LAB_TBSZ		; if so do tab size
  7561                          
  7562  b001 20a3a4             	JSR	LAB_GTBY		; get byte parameter
  7563  b004 8a                 	TXA				; copy width to A
  7564  b005 f00a               	BEQ	LAB_NSTT		; branch if set for infinite line
  7565                          
  7566  b007 e010               	CPX	#$10			; else make min width = 16d
  7567  b009 9045               	BCC	TabErr		; if less do function call error and exit
  7568                          
  7569                          ; this next compare ensures that we can't exit WIDTH via an error leaving the
  7570                          ; tab size greater than the line length.
  7571                          
  7572  b00b e464               	CPX	TabSiz		; compare with tab size
  7573  b00d b002               	BCS	LAB_NSTT		; branch if >= tab size
  7574                          
  7575  b00f 8664               	STX	TabSiz		; else make tab size = terminal width
  7576                          LAB_NSTT
  7577  b011 860f               	STX	TWidth		; set the terminal width
  7578  b013 20c200             	JSR	LAB_GBYT		; get BASIC byte back
  7579  b016 f01a               	BEQ	WExit			; exit if no following
  7580                          
  7581  b018 c92c               	CMP	#','			; else is it ","
  7582  b01a d0a9               	BNE	LAB_MMSE		; if not do syntax error
  7583                          
  7584                          LAB_TBSZ
  7585  b01c 20a0a4             	JSR	LAB_SGBY		; scan and get byte parameter
  7586  b01f 8a                 	TXA				; copy TAB size
  7587  b020 302e               	BMI	TabErr		; if >127 do function call error and exit
  7588                          
  7589  b022 e001               	CPX	#$01			; compare with min-1
  7590  b024 902a               	BCC	TabErr		; if <=1 do function call error and exit
  7591                          
  7592  b026 a50f               	LDA	TWidth		; set flags for width
  7593  b028 f006               	BEQ	LAB_SVTB		; skip check if infinite line
  7594                          
  7595  b02a e40f               	CPX	TWidth		; compare TAB with width
  7596  b02c f002               	BEQ	LAB_SVTB		; ok if =
  7597                          
  7598  b02e b020               	BCS	TabErr		; branch if too big
  7599                          
  7600                          LAB_SVTB
  7601  b030 8664               	STX	TabSiz		; save TAB size
  7602                          
  7603                          ; calculate tab column limit from TAB size. The Iclim is set to the last tab
  7604                          ; position on a line that still has at least one whole tab width between it
  7605                          ; and the end of the line.
  7606                          
  7607                          WExit
  7608  b032 a50f               	LDA	TWidth		; get width
  7609  b034 f006               	BEQ	LAB_SULP		; branch if infinite line
  7610                          
  7611  b036 c564               	CMP	TabSiz		; compare with tab size
  7612  b038 b003               	BCS	LAB_WDLP		; branch if >= tab size
  7613                          
  7614  b03a 8564               	STA	TabSiz		; else make tab size = terminal width
  7615                          LAB_SULP
  7616  b03c 38                 	SEC				; set carry for subtract
  7617                          LAB_WDLP
  7618  b03d e564               	SBC	TabSiz		; subtract tab size
  7619  b03f b0fc               	BCS	LAB_WDLP		; loop while no borrow
  7620                          
  7621  b041 6564               	ADC	TabSiz		; add tab size back
  7622  b043 18                 	CLC				; clear carry for add
  7623  b044 6564               	ADC	TabSiz		; add tab size back again
  7624  b046 8510               	STA	Iclim			; save for now
  7625  b048 a50f               	LDA	TWidth		; get width back
  7626  b04a 38                 	SEC				; set carry for subtract
  7627  b04b e510               	SBC	Iclim			; subtract remainder
  7628  b04d 8510               	STA	Iclim			; save tab column limit
  7629                          LAB_NOSQ
  7630  b04f 60                 	RTS
  7631                          
  7632                          TabErr
  7633  b050 4c409f             	JMP	LAB_FCER		; do function call error then warm start
  7634                          
  7635                          ; perform SQR()
  7636                          
  7637                          LAB_SQR
  7638  b053 a5b0               	LDA	FAC1_s		; get FAC1 sign
  7639  b055 30f9               	BMI	TabErr		; if -ve do function call error
  7640                          
  7641  b057 a5ac               	LDA	FAC1_e		; get exponent
  7642  b059 f0f4               	BEQ	LAB_NOSQ		; if zero just return
  7643                          
  7644                          					; else do root
  7645  b05b 20e1a8             	JSR	LAB_27AB		; round and copy FAC1 to FAC2
  7646  b05e a900               	LDA	#$00			; clear A
  7647                          
  7648  b060 8577               	STA	FACt_3		; clear remainder
  7649  b062 8576               	STA	FACt_2		; ..
  7650  b064 8575               	STA	FACt_1		; ..
  7651  b066 8578               	STA	TempB			; ..
  7652                          
  7653  b068 85af               	STA	FAC1_3		; clear root
  7654  b06a 85ae               	STA	FAC1_2		; ..
  7655  b06c 85ad               	STA	FAC1_1		; ..
  7656                          
  7657  b06e a218               	LDX	#$18			; 24 pairs of bits to do
  7658  b070 a5b3               	LDA	FAC2_e		; get exponent
  7659  b072 4a                 	LSR				; check odd/even
  7660  b073 b00e               	BCS	LAB_SQE2		; if odd only 1 shift first time
  7661                          
  7662                          LAB_SQE1
  7663  b075 06b6               	ASL	FAC2_3		; shift highest bit of number ..
  7664  b077 26b5               	ROL	FAC2_2		; ..
  7665  b079 26b4               	ROL	FAC2_1		; ..
  7666  b07b 2677               	ROL	FACt_3		; .. into remainder
  7667  b07d 2676               	ROL	FACt_2		; ..
  7668  b07f 2675               	ROL	FACt_1		; ..
  7669  b081 2678               	ROL	TempB			; .. never overflows
  7670                          LAB_SQE2
  7671  b083 06b6               	ASL	FAC2_3		; shift highest bit of number ..
  7672  b085 26b5               	ROL	FAC2_2		; ..
  7673  b087 26b4               	ROL	FAC2_1		; ..
  7674  b089 2677               	ROL	FACt_3		; .. into remainder
  7675  b08b 2676               	ROL	FACt_2		; ..
  7676  b08d 2675               	ROL	FACt_1		; ..
  7677  b08f 2678               	ROL	TempB			; .. never overflows
  7678                          
  7679  b091 06af               	ASL	FAC1_3		; root = root * 2
  7680  b093 26ae               	ROL	FAC1_2		; ..
  7681  b095 26ad               	ROL	FAC1_1		; .. never overflows
  7682                          
  7683  b097 a5af               	LDA	FAC1_3		; get root low byte
  7684  b099 2a                 	ROL				; *2
  7685  b09a 855b               	STA	Temp3			; save partial low byte
  7686  b09c a5ae               	LDA	FAC1_2		; get root low mid byte
  7687  b09e 2a                 	ROL				; *2
  7688  b09f 855c               	STA	Temp3+1		; save partial low mid byte
  7689  b0a1 a5ad               	LDA	FAC1_1		; get root high mid byte
  7690  b0a3 2a                 	ROL				; *2
  7691  b0a4 855d               	STA	Temp3+2		; save partial high mid byte
  7692  b0a6 a900               	LDA	#$00			; get root high byte (always $00)
  7693  b0a8 2a                 	ROL				; *2
  7694  b0a9 855e               	STA	Temp3+3		; save partial high byte
  7695                          
  7696                          					; carry clear for subtract +1
  7697  b0ab a577               	LDA	FACt_3		; get remainder low byte
  7698  b0ad e55b               	SBC	Temp3			; subtract partial low byte
  7699  b0af 855b               	STA	Temp3			; save partial low byte
  7700                          
  7701  b0b1 a576               	LDA	FACt_2		; get remainder low mid byte
  7702  b0b3 e55c               	SBC	Temp3+1		; subtract partial low mid byte
  7703  b0b5 855c               	STA	Temp3+1		; save partial low mid byte
  7704                          
  7705  b0b7 a575               	LDA	FACt_1		; get remainder high mid byte
  7706  b0b9 e55d               	SBC	Temp3+2		; subtract partial high mid byte
  7707  b0bb a8                 	TAY				; copy partial high mid byte
  7708                          
  7709  b0bc a578               	LDA	TempB			; get remainder high byte
  7710  b0be e55e               	SBC	Temp3+3		; subtract partial high byte
  7711  b0c0 900e               	BCC	LAB_SQNS		; skip sub if remainder smaller
  7712                          
  7713  b0c2 8578               	STA	TempB			; save remainder high byte
  7714                          
  7715  b0c4 8475               	STY	FACt_1		; save remainder high mid byte
  7716                          
  7717  b0c6 a55c               	LDA	Temp3+1		; get remainder low mid byte
  7718  b0c8 8576               	STA	FACt_2		; save remainder low mid byte
  7719                          
  7720  b0ca a55b               	LDA	Temp3			; get partial low byte
  7721  b0cc 8577               	STA	FACt_3		; save remainder low byte
  7722                          
  7723  b0ce e6af               	INC	FAC1_3		; increment root low byte (never any rollover)
  7724                          LAB_SQNS
  7725  b0d0 ca                 	DEX				; decrement bit pair count
  7726  b0d1 d0a2               	BNE	LAB_SQE1		; loop if not all done
  7727                          
  7728  b0d3 38                 	SEC				; set carry for subtract
  7729  b0d4 a5b3               	LDA	FAC2_e		; get exponent
  7730  b0d6 e980               	SBC	#$80			; normalise
  7731  b0d8 6a                 	ROR				; /2 and re-bias to $80
  7732  b0d9 6900               	ADC	#$00			; add bit zero back in (allow for half shift)
  7733  b0db 85ac               	STA	FAC1_e		; save it
  7734  b0dd 4c4ba6             	JMP	LAB_24D5		; normalise FAC1 and return
  7735                          
  7736                          ; perform VARPTR()
  7737                          
  7738                          LAB_VARPTR
  7739  b0e0 20bc00             	JSR	LAB_IGBY		; increment and scan memory
  7740  b0e3 20c19d             	JSR	LAB_GVAR		; get var address
  7741  b0e6 20069c             	JSR	LAB_1BFB		; scan for ")" , else do syntax error then warm start
  7742  b0e9 a495               	LDY	Cvaral		; get var address low byte
  7743  b0eb a596               	LDA	Cvarah		; get var address high byte
  7744  b0ed 4c70a0             	JMP	LAB_AYFC		; save and convert integer AY to FAC1 and return
  7745                          
  7746                          ; perform PI
  7747                          
  7748                          LAB_PI
  7749  b0f0 a9da               	LDA	#<LAB_2C7C		; set (2*pi) pointer low byte
  7750  b0f2 a0b1               	LDY	#>LAB_2C7C		; set (2*pi) pointer high byte
  7751  b0f4 2094a8             	JSR	LAB_UFAC		; unpack memory (AY) into FAC1
  7752  b0f7 c6ac               	DEC	FAC1_e		; make result = PI
  7753  b0f9 60                 	RTS
  7754                          
  7755                          ; perform TWOPI
  7756                          
  7757                          LAB_TWOPI
  7758  b0fa a9da               	LDA	#<LAB_2C7C		; set (2*pi) pointer low byte
  7759  b0fc a0b1               	LDY	#>LAB_2C7C		; set (2*pi) pointer high byte
  7760  b0fe 4c94a8             	JMP	LAB_UFAC		; unpack memory (AY) into FAC1 and return
  7761                          
  7762                          
  7763                          ; unplot a pixel
  7764                          LAB_UNPLOT:
  7765  b101 20efa4             	jsr LAB_GADB ; get two parameters
  7766  b104 8a                 	txa
  7767  b105 a8                 	tay
  7768  b106 a611               	ldx Itempl
  7769                                  
  7770  b108 60                 	rts;jmp doUnPlot
  7771                          
  7772                          ; system dependant i/o vectors
  7773                          ; these are in RAM and are set by the monitor at start-up
  7774                          
  7775                          V_INPT
  7776  b109 6c0503             	JMP	(VEC_IN)		; non halting scan input device
  7777                          V_OUTP
  7778  b10c 6c0703             	JMP	(VEC_OUT)		; send byte to output device
  7779                          V_LOAD
  7780  b10f 6c0903             	JMP	(VEC_LD)		; load BASIC program
  7781                          V_SAVE
  7782  b112 6c0b03             	JMP	(VEC_SV)		; save BASIC program
  7783                          
  7784                          ; The rest are tables messages and code for RAM
  7785                          
  7786                          ; the rest of the code is tables and BASIC start-up code
  7787                          
  7788                          PG2_TABS
  7789  b115 00                 	!text	$00			; ctrl-c flag		-	$00 = enabled
  7790  b116 00                 	!text	$00			; ctrl-c byte		-	GET needs this
  7791  b117 00                 	!text	$00			; ctrl-c byte timeout	-	GET needs this
  7792  b118 bfae               	!word	CTRLC			; ctrl c check vector
  7793                          ;	!word	xxxx			; non halting key input	-	monitor to set this
  7794                          ;	!word	xxxx			; output vector		-	monitor to set this
  7795                          ;	!word	xxxx			; load vector		-	monitor to set this
  7796                          ;	!word	xxxx			; save vector		-	monitor to set this
  7797                          PG2_TABE
  7798                          
  7799                          ; character get subroutine for zero page
  7800                          
  7801                          ; For a 1.8432MHz 6502 including the JSR and RTS
  7802                          ; fastest (>=":")	=  29 cycles =  15.7uS
  7803                          ; slowest (<":")	=  40 cycles =  21.7uS
  7804                          ; space skip	= +21 cycles = +11.4uS
  7805                          ; inc across page	=  +4 cycles =  +2.2uS
  7806                          
  7807                          ; the target address for the LDA at LAB_2CF4 becomes the BASIC execute pointer once the
  7808                          ; block is copied to it's destination, any non zero page address will do at assembly
  7809                          ; time, to assemble a three byte instruction.
  7810                          
  7811                          ; page 0 initialisation table from $BC
  7812                          ; increment and scan memory
  7813                          
  7814                          LAB_2CEE
  7815  b11a e6c3               	INC	Bpntrl		; increment BASIC execute pointer low byte
  7816  b11c d002               	BNE	LAB_2CF4		; branch if no carry
  7817                          					; else
  7818  b11e e6c4               	INC	Bpntrh		; increment BASIC execute pointer high byte
  7819                          
  7820                          ; page 0 initialisation table from $C2
  7821                          ; scan memory
  7822                          
  7823                          LAB_2CF4
  7824  b120 adffff             	LDA	$FFFF			; get byte to scan (addr set by call routine)
  7825  b123 c9b1               	CMP	#TK_ELSE		; compare with the token for ELSE
  7826  b125 f00e               	BEQ	LAB_2D05		; exit if ELSE, not numeric, carry set
  7827                          
  7828  b127 c93a               	CMP	#':'			; compare with ":"
  7829  b129 b00a               	BCS	LAB_2D05		; exit if >= ":", not numeric, carry set
  7830                          
  7831  b12b c920               	CMP	#' '			; compare with " "
  7832  b12d f0eb               	BEQ	LAB_2CEE		; if " " go do next
  7833                          
  7834  b12f 38                 	SEC				; set carry for SBC
  7835  b130 e930               	SBC	#'0'			; subtract "0"
  7836  b132 38                 	SEC				; set carry for SBC
  7837  b133 e9d0               	SBC	#$D0			; subtract -"0"
  7838                          					; clear carry if byte = "0"-"9"
  7839                          LAB_2D05
  7840  b135 60                 	RTS
  7841                          
  7842                          ; page zero initialisation table $00-$12 inclusive
  7843                          
  7844                          StrTab
  7845  b136 4c                 	!text	$4C			; JMP opcode
  7846  b137 0390               	!word LAB_COLD		; initial warm start vector (cold start)
  7847                          
  7848  b139 00                 	!text	$00			; these bytes are not used by BASIC
  7849  b13a 0000               	!word	$0000			; 
  7850  b13c 0000               	!word	$0000			; 
  7851  b13e 0000               	!word	$0000			; 
  7852                          
  7853  b140 4c                 	!text	$4C			; JMP opcode
  7854  b141 409f               	!word	LAB_FCER		; initial user function vector ("Function call" error)
  7855  b143 00                 	!text	$00			; default NULL count
  7856  b144 00                 	!text	$00			; clear terminal position
  7857  b145 00                 	!text	$00			; default terminal width byte
  7858  b146 f2                 	!text	$F2			; default limit for TAB = 14
  7859  b147 0004               	!word	Ram_base		; start of user RAM
  7860                          EndTab
  7861                          
  7862                          LAB_MSZM
  7863  b149 0d0a4d656d6f7279...	!text	$0D,$0A,"Memory size ",$00
  7864                          
  7865                          LAB_SMSG
  7866  b158 200a0a202a2a2045...	!text	" ",$0A,$0A," ** EhBASIC for HBC-56 v2.22 **",$00
  7867                          
  7868                          ; numeric constants and series
  7869                          
  7870                          					; constants and series for LOG(n)
  7871                          LAB_25A0
  7872  b17b 02                 	!text	$02			; counter
  7873  b17c 80195662           	!text	$80,$19,$56,$62	; 0.59898
  7874  b180 807622f3           	!text	$80,$76,$22,$F3	; 0.96147
  7875                          ;##	!text	$80,$76,$22,$F1	; 0.96147
  7876  b184 8238aa40           	!text	$82,$38,$AA,$40	; 2.88539
  7877                          ;##	!text	$82,$38,$AA,$45	; 2.88539
  7878                          
  7879                          LAB_25AD
  7880  b188 803504f3           	!text	$80,$35,$04,$F3	; 0.70711	1/root 2
  7881                          LAB_25B1
  7882  b18c 813504f3           	!text	$81,$35,$04,$F3	; 1.41421	root 2
  7883                          LAB_25B5
  7884  b190 80800000           	!text	$80,$80,$00,$00	; -0.5
  7885                          LAB_25B9
  7886  b194 80317218           	!text	$80,$31,$72,$18	; 0.69315	LOG(2)
  7887                          
  7888                          					; numeric PRINT constants
  7889                          LAB_2947
  7890  b198 91434ff8           	!text	$91,$43,$4F,$F8	; 99999.9375 (max value with at least one decimal)
  7891                          LAB_294B
  7892  b19c 947423f7           	!text	$94,$74,$23,$F7	; 999999.4375 (max value before scientific notation)
  7893                          LAB_294F
  7894  b1a0 94742400           	!text	$94,$74,$24,$00	; 1000000
  7895                          
  7896                          					; EXP(n) constants and series
  7897                          LAB_2AFA
  7898  b1a4 8138aa3b           	!text	$81,$38,$AA,$3B	; 1.4427	(1/LOG base 2 e)
  7899                          LAB_2AFE
  7900  b1a8 06                 	!text	$06			; counter
  7901  b1a9 7463908c           	!text	$74,$63,$90,$8C	; 2.17023e-4
  7902  b1ad 77230cab           	!text	$77,$23,$0C,$AB	; 0.00124
  7903  b1b1 7a1e9400           	!text	$7A,$1E,$94,$00	; 0.00968
  7904  b1b5 7c634280           	!text	$7C,$63,$42,$80	; 0.05548
  7905  b1b9 7e75fed0           	!text	$7E,$75,$FE,$D0	; 0.24023
  7906  b1bd 80317215           	!text	$80,$31,$72,$15	; 0.69315
  7907  b1c1 81000000           	!text	$81,$00,$00,$00	; 1.00000
  7908                          
  7909                          ;##	!text	$07			; counter
  7910                          ;##	!text	$74,$94,$2E,$40	; -1/7! (-1/5040)
  7911                          ;##	!text	$77,$2E,$4F,$70	;  1/6! ( 1/720)
  7912                          ;##	!text	$7A,$88,$02,$6E	; -1/5! (-1/120)
  7913                          ;##	!text	$7C,$2A,$A0,$E6	;  1/4! ( 1/24)
  7914                          ;##	!text	$7E,$AA,$AA,$50	; -1/3! (-1/6)
  7915                          ;##	!text	$7F,$7F,$FF,$FF	;  1/2! ( 1/2)
  7916                          ;##	!text	$81,$80,$00,$00	; -1/1! (-1/1)
  7917                          ;##	!text	$81,$00,$00,$00	;  1/0! ( 1/1)
  7918                          
  7919                          					; trigonometric constants and series
  7920                          LAB_2C78
  7921  b1c5 81490fdb           	!text	$81,$49,$0F,$DB	; 1.570796371 (pi/2) as floating #
  7922                          LAB_2C84
  7923  b1c9 04                 	!text	$04			; counter
  7924  b1ca 861ed7fb           	!text	$86,$1E,$D7,$FB	; 39.7109
  7925                          ;##	!text	$86,$1E,$D7,$BA	; 39.7109
  7926  b1ce 87992665           	!text	$87,$99,$26,$65	;-76.575
  7927                          ;##	!text	$87,$99,$26,$64	;-76.575
  7928  b1d2 87233458           	!text	$87,$23,$34,$58	; 81.6022
  7929  b1d6 86a55de1           	!text	$86,$A5,$5D,$E1	;-41.3417
  7930                          ;##	!text	$86,$A5,$5D,$E0	;-41.3417
  7931                          LAB_2C7C
  7932  b1da 83490fdb           	!text	$83,$49,$0F,$DB	; 6.28319 (2*pi) as floating #
  7933                          ;##	!text	$83,$49,$0F,$DA	; 6.28319 (2*pi) as floating #
  7934                          
  7935                          LAB_2CC9
  7936  b1de 08                 	!text	$08			; counter
  7937  b1df 783ac537           	!text	$78,$3A,$C5,$37	; 0.00285
  7938  b1e3 7b83a25c           	!text	$7B,$83,$A2,$5C	;-0.0160686
  7939  b1e7 7c2edd4d           	!text	$7C,$2E,$DD,$4D	; 0.0426915
  7940  b1eb 7d99b01e           	!text	$7D,$99,$B0,$1E	;-0.0750429
  7941  b1ef 7d59ed24           	!text	$7D,$59,$ED,$24	; 0.106409
  7942  b1f3 7e917200           	!text	$7E,$91,$72,$00	;-0.142036
  7943  b1f7 7e4cb973           	!text	$7E,$4C,$B9,$73	; 0.199926
  7944  b1fb 7faaaa53           	!text	$7F,$AA,$AA,$53	;-0.333331
  7945                          
  7946                          ;##	!text	$08			; counter
  7947                          ;##	!text	$78,$3B,$D7,$4A	; 1/17
  7948                          ;##	!text	$7B,$84,$6E,$02	;-1/15
  7949                          ;##	!text	$7C,$2F,$C1,$FE	; 1/13
  7950                          ;##	!text	$7D,$9A,$31,$74	;-1/11
  7951                          ;##	!text	$7D,$5A,$3D,$84	; 1/9
  7952                          ;##	!text	$7E,$91,$7F,$C8	;-1/7
  7953                          ;##	!text	$7E,$4C,$BB,$E4	; 1/5
  7954                          ;##	!text	$7F,$AA,$AA,$6C	;-1/3
  7955                          
  7956                          LAB_1D96	= *+1			; $00,$00 used for undefined variables
  7957                          LAB_259C
  7958  b1ff 81000000           	!text	$81,$00,$00,$00	; 1.000000, used for INC
  7959                          LAB_2AFD
  7960  b203 81800000           	!text	$81,$80,$00,$00	; -1.00000, used for DEC. must be on the same page as +1.00
  7961                          
  7962                          					; misc constants
  7963                          LAB_1DF7
  7964  b207 90                 	!text	$90			;-32768 (uses first three bytes from 0.5)
  7965                          LAB_2A96
  7966  b208 80000000           	!text	$80,$00,$00,$00	; 0.5
  7967                          LAB_2C80
  7968  b20c 7f000000           	!text	$7F,$00,$00,$00	; 0.25
  7969                          LAB_26B5
  7970  b210 84200000           	!text	$84,$20,$00,$00	; 10.0000 divide by 10 constant
  7971                          
  7972                          ; This table is used in converting numbers to ASCII.
  7973                          
  7974                          LAB_2A9A
  7975                          LAB_2A9B = LAB_2A9A+1
  7976                          LAB_2A9C = LAB_2A9B+1
  7977  b214 fe7960             	!text	$FE,$79,$60		; -100000
  7978  b217 002710             	!text	$00,$27,$10		; 10000
  7979  b21a fffc18             	!text	$FF,$FC,$18		; -1000
  7980  b21d 000064             	!text	$00,$00,$64		; 100
  7981  b220 fffff6             	!text	$FF,$FF,$F6		; -10
  7982  b223 000001             	!text	$00,$00,$01		; 1
  7983                          
  7984                          LAB_CTBL
  7985  b226 3195               	!word	LAB_END-1		; END
  7986  b228 6e94               	!word	LAB_FOR-1		; FOR
  7987  b22a 7b9a               	!word	LAB_NEXT-1		; NEXT
  7988  b22c a796               	!word	LAB_DATA-1		; DATA
  7989  b22e 5d99               	!word	LAB_INPUT-1		; INPUT
  7990  b230 759d               	!word	LAB_DIM-1		; DIM
  7991  b232 7d99               	!word	LAB_READ-1		; READ
  7992  b234 cf97               	!word	LAB_LET-1		; LET
  7993  b236 a197               	!word	LAB_DEC-1		; DEC			new command
  7994  b238 0696               	!word	LAB_GOTO-1		; GOTO
  7995  b23a c595               	!word	LAB_RUN-1		; RUN
  7996  b23c d596               	!word	LAB_IF-1		; IF
  7997  b23e 5d95               	!word	LAB_RESTORE-1	; RESTORE		modified command
  7998  b240 e995               	!word	LAB_GOSUB-1		; GOSUB
  7999  b242 7baf               	!word	LAB_RETIRQ-1	; RETIRQ		new command
  8000  b244 87af               	!word	LAB_RETNMI-1	; RETNMI		new command
  8001  b246 9296               	!word	LAB_RETURN-1	; RETURN
  8002  b248 3997               	!word	LAB_REM-1		; REM
  8003  b24a 2f95               	!word	LAB_STOP-1		; STOP
  8004  b24c 4297               	!word	LAB_ON-1		; ON			modified command
  8005  b24e 9b95               	!word	LAB_NULL-1		; NULL		modified command
  8006  b250 a497               	!word	LAB_INC-1		; INC			new command
  8007  b252 9fa5               	!word	LAB_WAIT-1		; WAIT
  8008  b254 0eb1               	!word	V_LOAD-1		; LOAD
  8009  b256 11b1               	!word	V_SAVE-1		; SAVE
  8010  b258 8aa0               	!word	LAB_DEF-1		; DEF
  8011  b25a 24a5               	!word	LAB_POKE-1		; POKE
  8012  b25c 40a5               	!word	LAB_DOKE-1		; DOKE		new command
  8013  b25e 50b9               	!word	basicDisplay-1		; DISPLAY	HBC-56 command
  8014  b260 6ab9               	!word	basicPlot-1		; PLOT		HBC-56 command
  8015  b262 00b1               	!word	LAB_UNPLOT-1		; UNPLOT	HBC-56 command
  8016  b264 8da5               	!word	LAB_CALL-1		; CALL		new command
  8017  b266 cf95               	!word	LAB_DO-1		; DO			new command
  8018  b268 3896               	!word	LAB_LOOP-1		; LOOP		new command
  8019  b26a 7098               	!word	LAB_PRINT-1		; PRINT
  8020  b26c a195               	!word	LAB_CONT-1		; CONT
  8021  b26e b993               	!word	LAB_LIST-1		; LIST
  8022  b270 b693               	!word	LAB_CLEAR-1		; CLEAR
  8023  b272 6493               	!word	LAB_NEW-1		; NEW
  8024  b274 fcaf               	!word	LAB_WDTH-1		; WIDTH		new command
  8025  b276 3f98               	!word	LAB_GET-1		; GET			new command
  8026  b278 65a5               	!word	LAB_SWAP-1		; SWAP		new command
  8027  b27a 98ad               	!word	LAB_BITSET-1	; BITSET		new command
  8028  b27c acad               	!word	LAB_BITCLR-1	; BITCLR		new command
  8029  b27e 5de9               	!word	tmsConsoleCls-1	; CLS
  8030  b280 3ab9               	!word	basicColor-1	; COLOR
  8031  b282 2aaf               	!word	LAB_IRQ-1		; IRQ			new command
  8032  b284 2daf               	!word	LAB_NMI-1		; NMI			new command
  8033                          
  8034                          ; function pre process routine table
  8035                          
  8036                          LAB_FTPL
  8037                          LAB_FTPM	= LAB_FTPL+$01
  8038  b286 7b9c               	!word	LAB_PPFN-1		; SGN(n)	process numeric expression in ()
  8039  b288 7b9c               	!word	LAB_PPFN-1		; INT(n)		"
  8040  b28a 7b9c               	!word	LAB_PPFN-1		; ABS(n)		"
  8041  b28c ff9a               	!word	LAB_EVEZ-1		; USR(x)	process any expression
  8042  b28e 029c               	!word	LAB_1BF7-1		; FRE(x)		"
  8043  b290 029c               	!word	LAB_1BF7-1		; POS(x)		"
  8044  b292 7b9c               	!word	LAB_PPFN-1		; SQR(n)	process numeric expression in ()
  8045  b294 7b9c               	!word	LAB_PPFN-1		; RND(n)		"
  8046  b296 7b9c               	!word	LAB_PPFN-1		; LOG(n)		"
  8047  b298 7b9c               	!word	LAB_PPFN-1		; EXP(n)		"
  8048  b29a 7b9c               	!word	LAB_PPFN-1		; COS(n)		"
  8049  b29c 7b9c               	!word	LAB_PPFN-1		; SIN(n)		"
  8050  b29e 7b9c               	!word	LAB_PPFN-1		; TAN(n)		"
  8051  b2a0 7b9c               	!word	LAB_PPFN-1		; ATN(n)		"
  8052  b2a2 7b9c               	!word	LAB_PPFN-1		; PEEK(n)		"
  8053  b2a4 7b9c               	!word	LAB_PPFN-1		; DEEK(n)		"
  8054  b2a6 0000               	!word	$0000			; SADD()	none
  8055  b2a8 759c               	!word	LAB_PPFS-1		; LEN($)	process string expression in ()
  8056  b2aa 7b9c               	!word	LAB_PPFN-1		; STR$(n)	process numeric expression in ()
  8057  b2ac 759c               	!word	LAB_PPFS-1		; VAL($)	process string expression in ()
  8058  b2ae 759c               	!word	LAB_PPFS-1		; ASC($)		"
  8059  b2b0 759c               	!word	LAB_PPFS-1		; UCASE$($)		"
  8060  b2b2 759c               	!word	LAB_PPFS-1		; LCASE$($)		"
  8061  b2b4 7b9c               	!word	LAB_PPFN-1		; CHR$(n)	process numeric expression in ()
  8062  b2b6 a29c               	!word	LAB_BHSS-1		; HEX$(n)		"
  8063  b2b8 a29c               	!word	LAB_BHSS-1		; BIN$(n)		"
  8064  b2ba 0000               	!word	$0000			; BITTST()	none
  8065  b2bc 93af               	!word	LAB_MMPP-1		; MAX()	process numeric expression
  8066  b2be 93af               	!word	LAB_MMPP-1		; MIN()		"
  8067  b2c0 819c               	!word	LAB_PPBI-1		; PI		advance pointer
  8068  b2c2 819c               	!word	LAB_PPBI-1		; TWOPI		"
  8069  b2c4 0000               	!word	$0000			; VARPTR()	none
  8070  b2c6 869c               	!word	LAB_LRMS-1		; LEFT$()	process string expression
  8071  b2c8 869c               	!word	LAB_LRMS-1		; RIGHT$()		"
  8072  b2ca 869c               	!word	LAB_LRMS-1		; MID$()		"
  8073                          
  8074                          ; action addresses for functions
  8075                          
  8076                          LAB_FTBL
  8077                          LAB_FTBM	= LAB_FTBL+$01
  8078  b2cc 0da9               	!word	LAB_SGN-1		; SGN()
  8079  b2ce 97a9               	!word	LAB_INT-1		; INT()
  8080  b2d0 2aa9               	!word	LAB_ABS-1		; ABS()
  8081  b2d2 63ad               	!word	LAB_USR-1		; USR()
  8082  b2d4 5ba0               	!word	LAB_FRE-1		; FRE()
  8083  b2d6 7aa0               	!word	LAB_POS-1		; POS()
  8084  b2d8 52b0               	!word	LAB_SQR-1		; SQR()
  8085  b2da b3ac               	!word	LAB_RND-1		; RND()		modified function
  8086  b2dc 11a7               	!word	LAB_LOG-1		; LOG()
  8087  b2de 15ac               	!word	LAB_EXP-1		; EXP()
  8088  b2e0 e7ac               	!word	LAB_COS-1		; COS()
  8089  b2e2 eeac               	!word	LAB_SIN-1		; SIN()
  8090  b2e4 37ad               	!word	LAB_TAN-1		; TAN()
  8091  b2e6 69ad               	!word	LAB_ATN-1		; ATN()
  8092  b2e8 19a5               	!word	LAB_PEEK-1		; PEEK()
  8093  b2ea 2da5               	!word	LAB_DEEK-1		; DEEK()		new function
  8094  b2ec 6ba4               	!word	LAB_SADD-1		; SADD()		new function
  8095  b2ee 84a4               	!word	LAB_LENS-1		; LEN()
  8096  b2f0 3ca1               	!word	LAB_STRS-1		; STR$()
  8097  b2f2 b1a4               	!word	LAB_VAL-1		; VAL()
  8098  b2f4 8fa4               	!word	LAB_ASC-1		; ASC()
  8099  b2f6 49a4               	!word	LAB_UCASE-1		; UCASE$()		new function
  8100  b2f8 28a4               	!word	LAB_LCASE-1		; LCASE$()		new function
  8101  b2fa 9aa3               	!word	LAB_CHRS-1		; CHR$()
  8102  b2fc 39ae               	!word	LAB_HEXS-1		; HEX$()		new function
  8103  b2fe eaad               	!word	LAB_BINS-1		; BIN$()		new function
  8104  b300 c2ad               	!word	LAB_BTST-1		; BITTST()		new function
  8105  b302 99af               	!word	LAB_MAX-1		; MAX()		new function
  8106  b304 a9af               	!word	LAB_MIN-1		; MIN()		new function
  8107  b306 efb0               	!word	LAB_PI-1		; PI			new function
  8108  b308 f9b0               	!word	LAB_TWOPI-1		; TWOPI		new function
  8109  b30a dfb0               	!word	LAB_VARPTR-1	; VARPTR()		new function
  8110  b30c aca3               	!word	LAB_LEFT-1		; LEFT$()
  8111  b30e b5a3               	!word	LAB_RIGHT-1		; RIGHT$()
  8112  b310 e4a3               	!word	LAB_MIDS-1		; MID$()
  8113                          
  8114                          ; hierarchy and action addresses for operator
  8115                          
  8116                          LAB_OPPT
  8117  b312 79                 	!text	$79			; +
  8118  b313 d7a5               	!word	LAB_ADD-1
  8119  b315 79                 	!text	$79			; -
  8120  b316 bca5               	!word	LAB_SUBTRACT-1
  8121  b318 7b                 	!text	$7B			; *
  8122  b319 52a7               	!word	LAB_MULTIPLY-1
  8123  b31b 7b                 	!text	$7B			; /
  8124  b31c 1aa8               	!word	LAB_DIVIDE-1
  8125  b31e 7f                 	!text	$7F			; ^
  8126  b31f d1ab               	!word	LAB_POWER-1
  8127  b321 50                 	!text	$50			; AND
  8128  b322 eb9c               	!word	LAB_AND-1
  8129  b324 46                 	!text	$46			; EOR			new operator
  8130  b325 d19c               	!word	LAB_EOR-1
  8131  b327 46                 	!text	$46			; OR
  8132  b328 de9c               	!word	LAB_OR-1
  8133  b32a 56                 	!text	$56			; >>			new operator
  8134  b32b 979d               	!word	LAB_RSHIFT-1
  8135  b32d 56                 	!text	$56			; <<			new operator
  8136  b32e 7f9d               	!word	LAB_LSHIFT-1
  8137  b330 7d                 	!text	$7D			; >
  8138  b331 0aac               	!word	LAB_GTHAN-1
  8139  b333 5a                 	!text	$5A			; =
  8140  b334 2d9c               	!word	LAB_EQUAL-1
  8141  b336 64                 	!text	$64			; <
  8142  b337 0c9d               	!word	LAB_LTHAN-1
  8143                          
  8144                          ; keywords start with ..
  8145                          ; this is the first character table and must be in alphabetic order
  8146                          
  8147                          TAB_1STC
  8148  b339 2a                 	!text	"*"
  8149  b33a 2b                 	!text	"+"
  8150  b33b 2d                 	!text	"-"
  8151  b33c 2f                 	!text	"/"
  8152  b33d 3c                 	!text	"<"
  8153  b33e 3d                 	!text	"="
  8154  b33f 3e                 	!text	">"
  8155  b340 3f                 	!text	"?"
  8156  b341 41                 	!text	"A"
  8157  b342 42                 	!text	"B"
  8158  b343 43                 	!text	"C"
  8159  b344 44                 	!text	"D"
  8160  b345 45                 	!text	"E"
  8161  b346 46                 	!text	"F"
  8162  b347 47                 	!text	"G"
  8163  b348 48                 	!text	"H"
  8164  b349 49                 	!text	"I"
  8165  b34a 4c                 	!text	"L"
  8166  b34b 4d                 	!text	"M"
  8167  b34c 4e                 	!text	"N"
  8168  b34d 4f                 	!text	"O"
  8169  b34e 50                 	!text	"P"
  8170  b34f 52                 	!text	"R"
  8171  b350 53                 	!text	"S"
  8172  b351 54                 	!text	"T"
  8173  b352 55                 	!text	"U"
  8174  b353 56                 	!text	"V"
  8175  b354 57                 	!text	"W"
  8176  b355 5e                 	!text	"^"
  8177  b356 00                 	!text	$00			; table terminator
  8178                          
  8179                          ; pointers to keyword tables
  8180                          
  8181                          TAB_CHRT
  8182  b357 91b3               	!word	TAB_STAR		; table for "*"
  8183  b359 93b3               	!word	TAB_PLUS		; table for "+"
  8184  b35b 95b3               	!word	TAB_MNUS		; table for "-"
  8185  b35d 97b3               	!word	TAB_SLAS		; table for "/"
  8186  b35f 99b3               	!word	TAB_LESS		; table for "<"
  8187  b361 9db3               	!word	TAB_EQUL		; table for "="
  8188  b363 9fb3               	!word	TAB_MORE		; table for ">"
  8189  b365 a3b3               	!word	TAB_QEST		; table for "?"
  8190  b367 a5b3               	!word	TAB_ASCA		; table for "A"
  8191  b369 b5b3               	!word	TAB_ASCB		; table for "B"
  8192  b36b ceb3               	!word	TAB_ASCC		; table for "C"
  8193  b36d edb3               	!word	TAB_ASCD		; table for "D"
  8194  b36f 0db4               	!word	TAB_ASCE		; table for "E"
  8195  b371 1cb4               	!word	TAB_ASCF		; table for "F"
  8196  b373 26b4               	!word	TAB_ASCG		; table for "G"
  8197  b375 33b4               	!word	TAB_ASCH		; table for "H"
  8198  b377 39b4               	!word	TAB_ASCI		; table for "I"
  8199  b379 4bb4               	!word	TAB_ASCL		; table for "L"
  8200  b37b 70b4               	!word	TAB_ASCM		; table for "M"
  8201  b37d 7eb4               	!word	TAB_ASCN		; table for "N"
  8202  b37f 90b4               	!word	TAB_ASCO		; table for "O"
  8203  b381 98b4               	!word	TAB_ASCP		; table for "P"
  8204  b383 b1b4               	!word	TAB_ASCR		; table for "R"
  8205  b385 e0b4               	!word	TAB_ASCS		; table for "S"
  8206  b387 0bb5               	!word	TAB_ASCT		; table for "T"
  8207  b389 1fb5               	!word	TAB_ASCU		; table for "U"
  8208  b38b 36b5               	!word	TAB_ASCV		; table for "V"
  8209  b38d 42b5               	!word	TAB_ASCW		; table for "W"
  8210  b38f 51b5               	!word	TAB_POWR		; table for "^"
  8211                          
  8212                          ; tables for each start character, note if a longer keyword with the same start
  8213                          ; letters as a shorter one exists then it must come first, else the list is in
  8214                          ; alphabetical order as follows ..
  8215                          
  8216                          ; [keyword,token
  8217                          ; [keyword,token]]
  8218                          ; end marker (#$00)
  8219                          
  8220                          TAB_STAR
  8221  b391 bd00               	!text TK_MUL,$00		; *
  8222                          TAB_PLUS
  8223  b393 bb00               	!text TK_PLUS,$00		; +
  8224                          TAB_MNUS
  8225  b395 bc00               	!text TK_MINUS,$00	; -
  8226                          TAB_SLAS
  8227  b397 be00               	!text TK_DIV,$00		; /
  8228                          TAB_LESS
  8229                          LBB_LSHIFT
  8230  b399 3cc4               	!text	"<",TK_LSHIFT	; <<	note - "<<" must come before "<"
  8231  b39b c7                 	!text TK_LT			; <
  8232  b39c 00                 	!text	$00
  8233                          TAB_EQUL
  8234  b39d c600               	!text TK_EQUAL,$00	; =
  8235                          TAB_MORE
  8236                          LBB_RSHIFT
  8237  b39f 3ec3               	!text	">",TK_RSHIFT	; >>	note - ">>" must come before ">"
  8238  b3a1 c5                 	!text TK_GT			; >
  8239  b3a2 00                 	!text	$00
  8240                          TAB_QEST
  8241  b3a3 a200               	!text TK_PRINT,$00	; ?
  8242                          TAB_ASCA
  8243                          LBB_ABS
  8244  b3a5 425328ca           	!text	"BS(",TK_ABS	; ABS(
  8245                          LBB_AND
  8246  b3a9 4e44c0             	!text	"ND",TK_AND		; AND
  8247                          LBB_ASC
  8248  b3ac 534328dc           	!text	"SC(",TK_ASC	; ASC(
  8249                          LBB_ATN
  8250  b3b0 544e28d5           	!text	"TN(",TK_ATN	; ATN(
  8251  b3b4 00                 	!text	$00
  8252                          TAB_ASCB
  8253                          LBB_BINS
  8254  b3b5 494e2428e1         	!text	"IN$(",TK_BINS	; BIN$(
  8255                          LBB_BITCLR
  8256  b3ba 4954434c52ab       	!text	"ITCLR",TK_BITCLR	; BITCLR
  8257                          LBB_BITSET
  8258  b3c0 4954534554aa       	!text	"ITSET",TK_BITSET	; BITSET
  8259                          LBB_BITTST
  8260  b3c6 495454535428e2     	!text	"ITTST(",TK_BITTST
  8261                          					; BITTST(
  8262  b3cd 00                 	!text	$00
  8263                          TAB_ASCC
  8264                          LBB_CALL
  8265  b3ce 414c4c9f           	!text	"ALL",TK_CALL	; CALL
  8266                          LBB_CHRS
  8267  b3d2 48522428df         	!text	"HR$(",TK_CHRS	; CHR$(
  8268                          LBB_CLEAR
  8269  b3d7 4c454152a5         	!text	"LEAR",TK_CLEAR	; CLEAR
  8270                          LBB_CLS
  8271  b3dc 4c53ac             	!text	"LS",TK_CLS	; CLS
  8272                          LBB_COLOR
  8273  b3df 4f4c4f52ad         	!text	"OLOR",TK_COLOR	; COLOR
  8274                          LBB_CONT
  8275  b3e4 4f4e54a3           	!text	"ONT",TK_CONT	; CONT
  8276                          LBB_COS
  8277  b3e8 4f5328d2           	!text	"OS(",TK_COS	; COS(
  8278  b3ec 00                 	!text	$00
  8279                          TAB_ASCD
  8280                          LBB_DATA
  8281  b3ed 41544183           	!text	"ATA",TK_DATA	; DATA
  8282                          LBB_DEC
  8283  b3f1 454388             	!text	"EC",TK_DEC		; DEC
  8284                          LBB_DEEK
  8285  b3f4 45454b28d7         	!text	"EEK(",TK_DEEK	; DEEK(
  8286                          LBB_DEF
  8287  b3f9 454699             	!text	"EF",TK_DEF		; DEF
  8288                          LBB_DIM
  8289  b3fc 494d85             	!text	"IM",TK_DIM		; DIM
  8290                          LBB_DOKE
  8291  b3ff 4f4b459b           	!text	"OKE",TK_DOKE	; DOKE note - "DOKE" must come before "DO"
  8292                          LBB_DO
  8293  b403 4fa0               	!text	"O",TK_DO		; DO
  8294                          LBB_DISPLAY
  8295  b405 4953504c41599c     	!text	"ISPLAY",TK_DISPLAY	; DISPLAY	HBC-56 command
  8296  b40c 00                 	!text	$00
  8297                          TAB_ASCE
  8298                          LBB_ELSE
  8299  b40d 4c5345b1           	!text	"LSE",TK_ELSE	; ELSE
  8300                          LBB_END
  8301  b411 4e4480             	!text	"ND",TK_END		; END
  8302                          LBB_EOR
  8303  b414 4f52c1             	!text	"OR",TK_EOR		; EOR
  8304                          LBB_EXP
  8305  b417 585028d1           	!text	"XP(",TK_EXP	; EXP(
  8306  b41b 00                 	!text	$00
  8307                          TAB_ASCF
  8308                          LBB_FN
  8309  b41c 4eb3               	!text	"N",TK_FN		; FN
  8310                          LBB_FOR
  8311  b41e 4f5281             	!text	"OR",TK_FOR		; FOR
  8312                          LBB_FRE
  8313  b421 524528cc           	!text	"RE(",TK_FRE	; FRE(
  8314  b425 00                 	!text	$00
  8315                          TAB_ASCG
  8316                          LBB_GET
  8317  b426 4554a8             	!text	"ET",TK_GET		; GET
  8318                          LBB_GOSUB
  8319  b429 4f5355428d         	!text	"OSUB",TK_GOSUB	; GOSUB
  8320                          LBB_GOTO
  8321  b42e 4f544f89           	!text	"OTO",TK_GOTO	; GOTO
  8322  b432 00                 	!text	$00
  8323                          TAB_ASCH
  8324                          LBB_HEXS
  8325  b433 45582428e0         	!text	"EX$(",TK_HEXS	; HEX$(
  8326  b438 00                 	!text	$00
  8327                          TAB_ASCI
  8328                          LBB_IF
  8329  b439 468b               	!text	"F",TK_IF		; IF
  8330                          LBB_INC
  8331  b43b 4e4395             	!text	"NC",TK_INC		; INC
  8332                          LBB_INPUT
  8333  b43e 4e50555484         	!text	"NPUT",TK_INPUT	; INPUT
  8334                          LBB_INT
  8335  b443 4e5428c9           	!text	"NT(",TK_INT	; INT(
  8336                          LBB_IRQ
  8337  b447 5251ae             	!text	"RQ",TK_IRQ		; IRQ
  8338  b44a 00                 	!text	$00
  8339                          TAB_ASCL
  8340                          LBB_LCASES
  8341  b44b 434153452428de     	!text	"CASE$(",TK_LCASES
  8342                          					; LCASE$(
  8343                          LBB_LEFTS
  8344  b452 4546542428e8       	!text	"EFT$(",TK_LEFTS	; LEFT$(
  8345                          LBB_LEN
  8346  b458 454e28d9           	!text	"EN(",TK_LEN	; LEN(
  8347                          LBB_LET
  8348  b45c 455487             	!text	"ET",TK_LET		; LET
  8349                          LBB_LIST
  8350  b45f 495354a4           	!text	"IST",TK_LIST	; LIST
  8351                          LBB_LOAD
  8352  b463 4f414497           	!text	"OAD",TK_LOAD	; LOAD
  8353                          LBB_LOG
  8354  b467 4f4728d0           	!text	"OG(",TK_LOG	; LOG(
  8355                          LBB_LOOP
  8356  b46b 4f4f50a1           	!text	"OOP",TK_LOOP	; LOOP
  8357  b46f 00                 	!text	$00
  8358                          TAB_ASCM
  8359                          LBB_MAX
  8360  b470 415828e3           	!text	"AX(",TK_MAX	; MAX(
  8361                          LBB_MIDS
  8362  b474 49442428ea         	!text	"ID$(",TK_MIDS	; MID$(
  8363                          LBB_MIN
  8364  b479 494e28e4           	!text	"IN(",TK_MIN	; MIN(
  8365  b47d 00                 	!text	$00
  8366                          TAB_ASCN
  8367                          LBB_NEW
  8368  b47e 4557a6             	!text	"EW",TK_NEW		; NEW
  8369                          LBB_NEXT
  8370  b481 45585482           	!text	"EXT",TK_NEXT	; NEXT
  8371                          LBB_NMI
  8372  b485 4d49af             	!text	"MI",TK_NMI		; NMI
  8373                          LBB_NOT
  8374  b488 4f54b6             	!text	"OT",TK_NOT		; NOT
  8375                          LBB_NULL
  8376  b48b 554c4c94           	!text	"ULL",TK_NULL	; NULL
  8377  b48f 00                 	!text	$00
  8378                          TAB_ASCO
  8379                          LBB_OFF
  8380  b490 4646ba             	!text	"FF",TK_OFF		; OFF
  8381                          LBB_ON
  8382  b493 4e93               	!text	"N",TK_ON		; ON
  8383                          LBB_OR
  8384  b495 52c2               	!text	"R",TK_OR		; OR
  8385  b497 00                 	!text	$00
  8386                          TAB_ASCP
  8387                          LBB_PEEK
  8388  b498 45454b28d6         	!text	"EEK(",TK_PEEK	; PEEK(
  8389                          LBB_PI
  8390  b49d 49e5               	!text	"I",TK_PI		; PI
  8391                          LBB_PLOT
  8392  b49f 4c4f549d           	!text	"LOT",TK_PLOT		; PLOT
  8393                          LBB_POKE
  8394  b4a3 4f4b459a           	!text	"OKE",TK_POKE	; POKE
  8395                          LBB_POS
  8396  b4a7 4f5328cd           	!text	"OS(",TK_POS	; POS(
  8397                          LBB_PRINT
  8398  b4ab 52494e54a2         	!text	"RINT",TK_PRINT	; PRINT
  8399  b4b0 00                 	!text	$00
  8400                          TAB_ASCR
  8401                          LBB_READ
  8402  b4b1 45414486           	!text	"EAD",TK_READ	; READ
  8403                          LBB_REM
  8404  b4b5 454d91             	!text	"EM",TK_REM		; REM
  8405                          LBB_RESTORE
  8406  b4b8 4553544f52458c     	!text	"ESTORE",TK_RESTORE
  8407                          					; RESTORE
  8408                          LBB_RETIRQ
  8409  b4bf 45544952518e       	!text	"ETIRQ",TK_RETIRQ	; RETIRQ
  8410                          LBB_RETNMI
  8411  b4c5 45544e4d498f       	!text	"ETNMI",TK_RETNMI	; RETNMI
  8412                          LBB_RETURN
  8413  b4cb 455455524e90       	!text	"ETURN",TK_RETURN	; RETURN
  8414                          LBB_RIGHTS
  8415  b4d1 494748542428e9     	!text	"IGHT$(",TK_RIGHTS
  8416                          					; RIGHT$(
  8417                          LBB_RND
  8418  b4d8 4e4428cf           	!text	"ND(",TK_RND	; RND(
  8419                          LBB_RUN
  8420  b4dc 554e8a             	!text	"UN",TK_RUN		; RUN
  8421  b4df 00                 	!text	$00
  8422                          TAB_ASCS
  8423                          LBB_SADD
  8424  b4e0 41444428d8         	!text	"ADD(",TK_SADD	; SADD(
  8425                          LBB_SAVE
  8426  b4e5 41564598           	!text	"AVE",TK_SAVE	; SAVE
  8427                          LBB_SGN
  8428  b4e9 474e28c8           	!text	"GN(",TK_SGN	; SGN(
  8429                          LBB_SIN
  8430  b4ed 494e28d3           	!text	"IN(",TK_SIN	; SIN(
  8431                          LBB_SPC
  8432  b4f1 504328b4           	!text	"PC(",TK_SPC	; SPC(
  8433                          LBB_SQR
  8434  b4f5 515228ce           	!text	"QR(",TK_SQR	; SQR(
  8435                          LBB_STEP
  8436  b4f9 544550b7           	!text	"TEP",TK_STEP	; STEP
  8437                          LBB_STOP
  8438  b4fd 544f5092           	!text	"TOP",TK_STOP	; STOP
  8439                          LBB_STRS
  8440  b501 54522428da         	!text	"TR$(",TK_STRS	; STR$(
  8441                          LBB_SWAP
  8442  b506 574150a9           	!text	"WAP",TK_SWAP	; SWAP
  8443  b50a 00                 	!text	$00
  8444                          TAB_ASCT
  8445                          LBB_TAB
  8446  b50b 414228b0           	!text	"AB(",TK_TAB	; TAB(
  8447                          LBB_TAN
  8448  b50f 414e28d4           	!text	"AN(",TK_TAN	; TAN(
  8449                          LBB_THEN
  8450  b513 48454eb5           	!text	"HEN",TK_THEN	; THEN
  8451                          LBB_TO
  8452  b517 4fb2               	!text	"O",TK_TO		; TO
  8453                          LBB_TWOPI
  8454  b519 574f5049e6         	!text	"WOPI",TK_TWOPI	; TWOPI
  8455  b51e 00                 	!text	$00
  8456                          TAB_ASCU
  8457                          LBB_UCASES
  8458  b51f 434153452428dd     	!text	"CASE$(",TK_UCASES
  8459                          					; UCASE$(
  8460                          LBB_UNPLOT
  8461  b526 4e504c4f549e       	!text	"NPLOT",TK_UNPLOT	; UNPLOT
  8462                          LBB_UNTIL
  8463  b52c 4e54494cb8         	!text	"NTIL",TK_UNTIL	; UNTIL
  8464                          LBB_USR
  8465  b531 535228cb           	!text	"SR(",TK_USR	; USR(
  8466  b535 00                 	!text	$00
  8467                          TAB_ASCV
  8468                          LBB_VAL
  8469  b536 414c28db           	!text	"AL(",TK_VAL	; VAL(
  8470                          LBB_VPTR
  8471  b53a 415250545228e7     	!text	"ARPTR(",TK_VPTR	; VARPTR(
  8472  b541 00                 	!text	$00
  8473                          TAB_ASCW
  8474                          LBB_WAIT
  8475  b542 41495496           	!text	"AIT",TK_WAIT	; WAIT
  8476                          LBB_WHILE
  8477  b546 48494c45b9         	!text	"HILE",TK_WHILE	; WHILE
  8478                          LBB_WIDTH
  8479  b54b 49445448a7         	!text	"IDTH",TK_WIDTH	; WIDTH
  8480  b550 00                 	!text	$00
  8481                          TAB_POWR
  8482  b551 bf00               	!text	TK_POWER,$00	; ^
  8483                          
  8484                          ; new decode table for LIST
  8485                          ; Table is ..
  8486                          ; byte - keyword length, keyword first character
  8487                          ; word - pointer to rest of keyword from dictionary
  8488                          
  8489                          ; note if length is 1 then the pointer is ignored
  8490                          
  8491                          LAB_KEYT
  8492  b553 0345               	!text	3,'E'
  8493  b555 11b4               	!word	LBB_END		; END
  8494  b557 0346               	!text	3,'F'
  8495  b559 1eb4               	!word	LBB_FOR		; FOR
  8496  b55b 044e               	!text	4,'N'
  8497  b55d 81b4               	!word	LBB_NEXT		; NEXT
  8498  b55f 0444               	!text	4,'D'
  8499  b561 edb3               	!word	LBB_DATA		; DATA
  8500  b563 0549               	!text	5,'I'
  8501  b565 3eb4               	!word	LBB_INPUT		; INPUT
  8502  b567 0344               	!text	3,'D'
  8503  b569 fcb3               	!word	LBB_DIM		; DIM
  8504  b56b 0452               	!text	4,'R'
  8505  b56d b1b4               	!word	LBB_READ		; READ
  8506  b56f 034c               	!text	3,'L'
  8507  b571 5cb4               	!word	LBB_LET		; LET
  8508  b573 0344               	!text	3,'D'
  8509  b575 f1b3               	!word	LBB_DEC		; DEC
  8510  b577 0447               	!text	4,'G'
  8511  b579 2eb4               	!word	LBB_GOTO		; GOTO
  8512  b57b 0352               	!text	3,'R'
  8513  b57d dcb4               	!word	LBB_RUN		; RUN
  8514  b57f 0249               	!text	2,'I'
  8515  b581 39b4               	!word	LBB_IF		; IF
  8516  b583 0752               	!text	7,'R'
  8517  b585 b8b4               	!word	LBB_RESTORE		; RESTORE
  8518  b587 0547               	!text	5,'G'
  8519  b589 29b4               	!word	LBB_GOSUB		; GOSUB
  8520  b58b 0652               	!text	6,'R'
  8521  b58d bfb4               	!word	LBB_RETIRQ		; RETIRQ
  8522  b58f 0652               	!text	6,'R'
  8523  b591 c5b4               	!word	LBB_RETNMI		; RETNMI
  8524  b593 0652               	!text	6,'R'
  8525  b595 cbb4               	!word	LBB_RETURN		; RETURN
  8526  b597 0352               	!text	3,'R'
  8527  b599 b5b4               	!word	LBB_REM		; REM
  8528  b59b 0453               	!text	4,'S'
  8529  b59d fdb4               	!word	LBB_STOP		; STOP
  8530  b59f 024f               	!text	2,'O'
  8531  b5a1 93b4               	!word	LBB_ON		; ON
  8532  b5a3 044e               	!text	4,'N'
  8533  b5a5 8bb4               	!word	LBB_NULL		; NULL
  8534  b5a7 0349               	!text	3,'I'
  8535  b5a9 3bb4               	!word	LBB_INC		; INC
  8536  b5ab 0457               	!text	4,'W'
  8537  b5ad 42b5               	!word	LBB_WAIT		; WAIT
  8538  b5af 044c               	!text	4,'L'
  8539  b5b1 63b4               	!word	LBB_LOAD		; LOAD
  8540  b5b3 0453               	!text	4,'S'
  8541  b5b5 e5b4               	!word	LBB_SAVE		; SAVE
  8542  b5b7 0344               	!text	3,'D'
  8543  b5b9 f9b3               	!word	LBB_DEF		; DEF
  8544  b5bb 0450               	!text	4,'P'
  8545  b5bd a3b4               	!word	LBB_POKE		; POKE
  8546  b5bf 0444               	!text	4,'D'
  8547  b5c1 ffb3               	!word	LBB_DOKE		; DOKE
  8548  b5c3 0744               	!text	7,'D'
  8549  b5c5 05b4               	!word	LBB_DISPLAY		; DISPLAY
  8550  b5c7 0450               	!text	4,'P'
  8551  b5c9 9fb4               	!word	LBB_PLOT		; PLOT
  8552  b5cb 0655               	!text	6,'U'
  8553  b5cd 26b5               	!word	LBB_UNPLOT		; UNPLOT
  8554  b5cf 0443               	!text	4,'C'
  8555  b5d1 ceb3               	!word	LBB_CALL		; CALL
  8556  b5d3 0244               	!text	2,'D'
  8557  b5d5 03b4               	!word	LBB_DO		; DO
  8558  b5d7 044c               	!text	4,'L'
  8559  b5d9 6bb4               	!word	LBB_LOOP		; LOOP
  8560  b5db 0550               	!text	5,'P'
  8561  b5dd abb4               	!word	LBB_PRINT		; PRINT
  8562  b5df 0443               	!text	4,'C'
  8563  b5e1 e4b3               	!word	LBB_CONT		; CONT
  8564  b5e3 044c               	!text	4,'L'
  8565  b5e5 5fb4               	!word	LBB_LIST		; LIST
  8566  b5e7 0543               	!text	5,'C'
  8567  b5e9 d7b3               	!word	LBB_CLEAR		; CLEAR
  8568  b5eb 034e               	!text	3,'N'
  8569  b5ed 7eb4               	!word	LBB_NEW		; NEW
  8570  b5ef 0557               	!text	5,'W'
  8571  b5f1 4bb5               	!word	LBB_WIDTH		; WIDTH
  8572  b5f3 0347               	!text	3,'G'
  8573  b5f5 26b4               	!word	LBB_GET		; GET
  8574  b5f7 0453               	!text	4,'S'
  8575  b5f9 06b5               	!word	LBB_SWAP		; SWAP
  8576  b5fb 0642               	!text	6,'B'
  8577  b5fd c0b3               	!word	LBB_BITSET		; BITSET
  8578  b5ff 0642               	!text	6,'B'
  8579  b601 bab3               	!word	LBB_BITCLR		; BITCLR
  8580  b603 0343               	!text	3,'C'
  8581  b605 dcb3               	!word	LBB_CLS			; CLS
  8582  b607 0543               	!text	5,'C'
  8583  b609 dfb3               	!word	LBB_COLOR		; COLOR
  8584  b60b 0349               	!text	3,'I'
  8585  b60d 47b4               	!word	LBB_IRQ		; IRQ
  8586  b60f 034e               	!text	3,'N'
  8587  b611 85b4               	!word	LBB_NMI		; NMI
  8588                          
  8589                          ; secondary commands (can't start a statement)
  8590                          
  8591  b613 0454               	!text	4,'T'
  8592  b615 0bb5               	!word	LBB_TAB		; TAB
  8593  b617 0445               	!text	4,'E'
  8594  b619 0db4               	!word	LBB_ELSE		; ELSE
  8595  b61b 0254               	!text	2,'T'
  8596  b61d 17b5               	!word	LBB_TO		; TO
  8597  b61f 0246               	!text	2,'F'
  8598  b621 1cb4               	!word	LBB_FN		; FN
  8599  b623 0453               	!text	4,'S'
  8600  b625 f1b4               	!word	LBB_SPC		; SPC
  8601  b627 0454               	!text	4,'T'
  8602  b629 13b5               	!word	LBB_THEN		; THEN
  8603  b62b 034e               	!text	3,'N'
  8604  b62d 88b4               	!word	LBB_NOT		; NOT
  8605  b62f 0453               	!text	4,'S'
  8606  b631 f9b4               	!word	LBB_STEP		; STEP
  8607  b633 0555               	!text	5,'U'
  8608  b635 2cb5               	!word	LBB_UNTIL		; UNTIL
  8609  b637 0557               	!text	5,'W'
  8610  b639 46b5               	!word	LBB_WHILE		; WHILE
  8611  b63b 034f               	!text	3,'O'
  8612  b63d 90b4               	!word	LBB_OFF		; OFF
  8613                          
  8614                          ; opperators
  8615                          
  8616  b63f 012b               	!text	1,'+'
  8617  b641 0000               	!word	$0000			; +
  8618  b643 012d               	!text	1,'-'
  8619  b645 0000               	!word	$0000			; -
  8620  b647 012a               	!text	1,'*'
  8621  b649 0000               	!word	$0000			; *
  8622  b64b 012f               	!text	1,'/'
  8623  b64d 0000               	!word	$0000			; /
  8624  b64f 015e               	!text	1,'^'
  8625  b651 0000               	!word	$0000			; ^
  8626  b653 0341               	!text	3,'A'
  8627  b655 a9b3               	!word	LBB_AND		; AND
  8628  b657 0345               	!text	3,'E'
  8629  b659 14b4               	!word	LBB_EOR		; EOR
  8630  b65b 024f               	!text	2,'O'
  8631  b65d 95b4               	!word	LBB_OR		; OR
  8632  b65f 023e               	!text	2,'>'
  8633  b661 9fb3               	!word	LBB_RSHIFT		; >>
  8634  b663 023c               	!text	2,'<'
  8635  b665 99b3               	!word	LBB_LSHIFT		; <<
  8636  b667 013e               	!text	1,'>'
  8637  b669 0000               	!word	$0000			; >
  8638  b66b 013d               	!text	1,'='
  8639  b66d 0000               	!word	$0000			; =
  8640  b66f 013c               	!text	1,'<'
  8641  b671 0000               	!word	$0000			; <
  8642                          
  8643                          ; functions
  8644                          
  8645  b673 0453               	!text	4,'S'			;
  8646  b675 e9b4               	!word	LBB_SGN		; SGN
  8647  b677 0449               	!text	4,'I'			;
  8648  b679 43b4               	!word	LBB_INT		; INT
  8649  b67b 0441               	!text	4,'A'			;
  8650  b67d a5b3               	!word	LBB_ABS		; ABS
  8651  b67f 0455               	!text	4,'U'			;
  8652  b681 31b5               	!word	LBB_USR		; USR
  8653  b683 0446               	!text	4,'F'			;
  8654  b685 21b4               	!word	LBB_FRE		; FRE
  8655  b687 0450               	!text	4,'P'			;
  8656  b689 a7b4               	!word	LBB_POS		; POS
  8657  b68b 0453               	!text	4,'S'			;
  8658  b68d f5b4               	!word	LBB_SQR		; SQR
  8659  b68f 0452               	!text	4,'R'			;
  8660  b691 d8b4               	!word	LBB_RND		; RND
  8661  b693 044c               	!text	4,'L'			;
  8662  b695 67b4               	!word	LBB_LOG		; LOG
  8663  b697 0445               	!text	4,'E'			;
  8664  b699 17b4               	!word	LBB_EXP		; EXP
  8665  b69b 0443               	!text	4,'C'			;
  8666  b69d e8b3               	!word	LBB_COS		; COS
  8667  b69f 0453               	!text	4,'S'			;
  8668  b6a1 edb4               	!word	LBB_SIN		; SIN
  8669  b6a3 0454               	!text	4,'T'			;
  8670  b6a5 0fb5               	!word	LBB_TAN		; TAN
  8671  b6a7 0441               	!text	4,'A'			;
  8672  b6a9 b0b3               	!word	LBB_ATN		; ATN
  8673  b6ab 0550               	!text	5,'P'			;
  8674  b6ad 98b4               	!word	LBB_PEEK		; PEEK
  8675  b6af 0544               	!text	5,'D'			;
  8676  b6b1 f4b3               	!word	LBB_DEEK		; DEEK
  8677  b6b3 0553               	!text	5,'S'			;
  8678  b6b5 e0b4               	!word	LBB_SADD		; SADD
  8679  b6b7 044c               	!text	4,'L'			;
  8680  b6b9 58b4               	!word	LBB_LEN		; LEN
  8681  b6bb 0553               	!text	5,'S'			;
  8682  b6bd 01b5               	!word	LBB_STRS		; STR$
  8683  b6bf 0456               	!text	4,'V'			;
  8684  b6c1 36b5               	!word	LBB_VAL		; VAL
  8685  b6c3 0441               	!text	4,'A'			;
  8686  b6c5 acb3               	!word	LBB_ASC		; ASC
  8687  b6c7 0755               	!text	7,'U'			;
  8688  b6c9 1fb5               	!word	LBB_UCASES		; UCASE$
  8689  b6cb 074c               	!text	7,'L'			;
  8690  b6cd 4bb4               	!word	LBB_LCASES		; LCASE$
  8691  b6cf 0543               	!text	5,'C'			;
  8692  b6d1 d2b3               	!word	LBB_CHRS		; CHR$
  8693  b6d3 0548               	!text	5,'H'			;
  8694  b6d5 33b4               	!word	LBB_HEXS		; HEX$
  8695  b6d7 0542               	!text	5,'B'			;
  8696  b6d9 b5b3               	!word	LBB_BINS		; BIN$
  8697  b6db 0742               	!text	7,'B'			;
  8698  b6dd c6b3               	!word	LBB_BITTST		; BITTST
  8699  b6df 044d               	!text	4,'M'			;
  8700  b6e1 70b4               	!word	LBB_MAX		; MAX
  8701  b6e3 044d               	!text	4,'M'			;
  8702  b6e5 79b4               	!word	LBB_MIN		; MIN
  8703  b6e7 0250               	!text	2,'P'			;
  8704  b6e9 9db4               	!word	LBB_PI		; PI
  8705  b6eb 0554               	!text	5,'T'			;
  8706  b6ed 19b5               	!word	LBB_TWOPI		; TWOPI
  8707  b6ef 0756               	!text	7,'V'			;
  8708  b6f1 3ab5               	!word	LBB_VPTR		; VARPTR
  8709  b6f3 064c               	!text	6,'L'			;
  8710  b6f5 52b4               	!word	LBB_LEFTS		; LEFT$
  8711  b6f7 0752               	!text	7,'R'			;
  8712  b6f9 d1b4               	!word	LBB_RIGHTS		; RIGHT$
  8713  b6fb 054d               	!text	5,'M'			;
  8714  b6fd 74b4               	!word	LBB_MIDS		; MID$
  8715                          
  8716                          ; BASIC messages, mostly error messages
  8717                          
  8718                          LAB_BAER
  8719  b6ff 23b7               	!word	ERR_NF		;$00 NEXT without FOR
  8720  b701 35b7               	!word	ERR_SN		;$02 syntax
  8721  b703 3db7               	!word	ERR_RG		;$04 RETURN without GOSUB
  8722  b705 53b7               	!word	ERR_OD		;$06 out of data
  8723  b707 60b7               	!word	ERR_FC		;$08 function call
  8724  b709 6fb7               	!word	ERR_OV		;$0A overflow
  8725  b70b 79b7               	!word	ERR_OM		;$0C out of memory
  8726  b70d 88b7               	!word	ERR_US		;$0E undefined statement
  8727  b70f 9db7               	!word	ERR_BS		;$10 array bounds
  8728  b711 abb7               	!word	ERR_DD		;$12 double dimension array
  8729  b713 bdb7               	!word	ERR_D0		;$14 divide by 0
  8730  b715 cdb7               	!word	ERR_ID		;$16 illegal direct
  8731  b717 ddb7               	!word	ERR_TM		;$18 type mismatch
  8732  b719 ecb7               	!word	ERR_LS		;$1A long string
  8733  b71b fdb7               	!word	ERR_ST		;$1C string too complex
  8734  b71d 11b8               	!word	ERR_CN		;$1E continue error
  8735  b71f 21b8               	!word	ERR_UF		;$20 undefined function
  8736  b721 35b8               	!word ERR_LD		;$22 LOOP without DO
  8737                          
  8738                          ; I may implement these two errors to force definition of variables and
  8739                          ; dimensioning of arrays before use.
  8740                          
  8741                          ;	!word ERR_UV		;$24 undefined variable
  8742                          
  8743                          ; the above error has been tested and works (see code and comments below LAB_1D8B)
  8744                          
  8745                          ;	!word ERR_UA		;$26 undimensioned array
  8746                          
  8747  b723 204e455854207769...ERR_NF	!text	" NEXT without FOR",$00
  8748  b735 2053796e74617800   ERR_SN	!text	" Syntax",$00
  8749  b73d 2052455455524e20...ERR_RG	!text	" RETURN without GOSUB",$00
  8750  b753 204f7574206f6620...ERR_OD	!text	" Out of DATA",$00
  8751  b760 2046756e6374696f...ERR_FC	!text	" Function call",$00
  8752  b76f 204f766572666c6f...ERR_OV	!text	" Overflow",$00
  8753  b779 204f7574206f6620...ERR_OM	!text	" Out of memory",$00
  8754  b788 20556e646566696e...ERR_US	!text	" Undefined statement",$00
  8755  b79d 2041727261792062...ERR_BS	!text	" Array bounds",$00
  8756  b7ab 20446f75626c6520...ERR_DD	!text	" Double dimension",$00
  8757  b7bd 2044697669646520...ERR_D0	!text	" Divide by zero",$00
  8758  b7cd 20496c6c6567616c...ERR_ID	!text	" Illegal direct",$00
  8759  b7dd 2054797065206d69...ERR_TM	!text	" Type mismatch",$00
  8760  b7ec 20537472696e6720...ERR_LS	!text	" String too long",$00
  8761  b7fd 20537472696e6720...ERR_ST	!text	" String too complex",$00
  8762  b811 2043616e27742063...ERR_CN	!text	" Can't continue",$00
  8763  b821 20556e646566696e...ERR_UF	!text	" Undefined function",$00
  8764  b835 204c4f4f50207769...ERR_LD	!text	" LOOP without DO",$00
  8765                          
  8766                          ;ERR_UV	!text	"Undefined variable",$00
  8767                          
  8768                          ; the above error has been tested and works (see code and comments below LAB_1D8B)
  8769                          
  8770                          ;ERR_UA	!text	"Undimensioned array",$00
  8771                          
  8772  b846 07427265616b00     LAB_BMSG	!text	$07, "Break",$00
  8773  b84d 07204572726f7200   LAB_EMSG	!text	$07, " Error",$00
  8774  b855 20696e206c696e65...LAB_LMSG	!text	" in line ",$00
  8775  b85f 0a0a205265616479...LAB_RMSG	!text	$0A,$0A," Ready",$0A,$0A,$00
  8776                          
  8777  b86a 2045787472612069...LAB_IMSG	!text	" Extra ignored",$0D,$0A,$00
  8778  b87b 205265646f206672...LAB_REDO	!text	" Redo from start",$0D,$0A,$00
  8779                          

; ******** Source: basic_hbc56_core.asm
    12                                 ; EhBASIC
    13                          
    14                          ; For saving registers
    15                          SAVE_X          = HBC56_USER_ZP_START
    16                          SAVE_Y          = HBC56_USER_ZP_START + 1
    17                          SAVE_A          = HBC56_USER_ZP_START + 2
    18                          
    19                          BASIC_XPOS = HBC56_USER_ZP_START + 4
    20                          BASIC_YPOS = HBC56_USER_ZP_START + 5
    21                          BASIC_COLOR = HBC56_USER_ZP_START + 6
    22                          
    23                          ; put the IRQ and NMI code in RAM so that it can be changed
    24                          IRQ_vec         = VEC_SV+2      ; IRQ code vector
    25                          NMI_vec         = IRQ_vec+$0A   ; NMI code vector
    26                          
    27                          ; -----------------------------------------------------------------------------
    28                          ; main entry point
    29                          ; -----------------------------------------------------------------------------
    30                          hbc56Main:
    31                          RES_vec:
    32  b88e a94f                       +tmsColorFgBg FG, BG
    33  b890 853c                       sta BASIC_COLOR
    34  b892 20ccb8                     jsr hbc56SetupDisplay
    35                          
    36                                  ; copy I/O vectors
    37  b895 a009                       ldy #END_CODE - LAB_vec - 1    ; set index/count
    38                          LAB_stlp
    39  b897 b9a6b8                     lda LAB_vec, Y         ; get byte from interrupt code
    40  b89a 990303                     sta VEC_CC, Y            ; save to RAM
    41  b89d 88                         dey
    42  b89e 10f7                       bpl LAB_stlp
    43                          
    44  b8a0 58                         cli                        ; enable interrupts
    45                          
    46  b8a1 4c0390                     jmp LAB_COLD
    47                          
    48                          ; -----------------------------------------------------------------------------
    49                          ; hybc56Load - EhBASIC load subroutine (for HBC-56)   (TBA)
    50                          ; -----------------------------------------------------------------------------
    51                          hbc56Load
    52  b8a4 60                         rts
    53                          
    54                          ; -----------------------------------------------------------------------------
    55                          ; hybc56Save - EhBASIC save subroutine (for HBC-56)   (TBA)
    56                          ; -----------------------------------------------------------------------------
    57                          hbc56Save
    58  b8a5 60                         rts
    59                          
    60                          ; -----------------------------------------------------------------------------
    61                          ; vector table - gets copied to VEC_IN in RAM
    62                          ; -----------------------------------------------------------------------------
    63                          LAB_vec
    64  b8a6 b0b8                   !word    hbc56In         ; check for break (Ctrl+C)
    65  b8a8 b0b8                   !word    hbc56In            ; byte in from keyboard
    66  b8aa f4b8                   !word    hbc56Out           ; byte out to screen
    67  b8ac a4b8                   !word    hbc56Load          ; load vector for EhBASIC
    68  b8ae a5b8                   !word    hbc56Save          ; save vector for EhBASIC
    69                          
    70                          END_CODE        ; so we know when to stop copying

; ******** Source: basic_tms.asm
    11                                      ; core basic
    12                          

; ******** Source: drivers\input.asm
     1                          ; Troy's HBC-56 - BASIC - Input
     2                          ;
     3                          ; Copyright (c) 2021 Troy Schrapel
     4                          ;
     5                          ; This code is licensed under the MIT license
     6                          ;
     7                          ; https://github.com/visrealm/hbc-56
     8                          ;
     9                          
    10                          
    11                          ; -----------------------------------------------------------------------------
    12                          ; hbc56In - EhBASIC input subroutine (for HBC-56) - must not block
    13                          ; -----------------------------------------------------------------------------
    14                          ; Outputs:      A - ASCII character captured from keyboard
    15                          ;               C - Flag set if key captured, clear if no key pressed
    16                          ; -----------------------------------------------------------------------------
    17                          hbc56In
    18  b8b0 da                         phx
    19                          
    20  b8b1 a221                       ldx #$21        ; check ctrl+c
    21  b8b3 2062ec                     jsr kbIsPressed
    22  b8b6 f00f                       beq @notPressed
    23  b8b8 a214                       ldx #$14
    24  b8ba 2062ec                     jsr kbIsPressed
    25  b8bd f008                       beq @notPressed
    26  b8bf fa                         plx
    27  b8c0 20fcec                     jsr kbReadAscii
    28  b8c3 a903                       lda #$03
    29  b8c5 38                         sec
    30  b8c6 60                         rts
    31                          @notPressed
    32  b8c7 fa                         plx
    33                          
    34  b8c8 20fcec                     jsr kbReadAscii ; HBC-56 keyboard routine can be used directly
    35                                                  ; we could just use it directly in the vector 
    36                                                  ; table, but it's here for clarity
    37  b8cb 60                         rts

; ******** Source: basic_tms.asm
    13                                                 ; input routines

; ******** Source: drivers\output_tms9918.asm
     1                          ; Troy's HBC-56 - BASIC - Output (TMS9918)
     2                          ;
     3                          ; Copyright (c) 2021 Troy Schrapel
     4                          ;
     5                          ; This code is licensed under the MIT license
     6                          ;
     7                          ; https://github.com/visrealm/hbc-56
     8                          ;
     9                          
    10                          FG     = TMS_DK_BLUE
    11                          BG     = TMS_WHITE
    12                          BORDER = TMS_DK_BLUE
    13                          
    14                          ; -----------------------------------------------------------------------------
    15                          ; hbc56SetupDisplay - Setup the display (TMS9918)
    16                          ; -----------------------------------------------------------------------------
    17                          hbc56SetupDisplay:
    18  b8cc 08                         php
    19  b8cd 78                         sei
    20                          
    21  b8ce 2010e6                     jsr tmsModeGraphicsI
    22                          
    23  b8d1 a9f4                       +tmsColorFgBg BG, BORDER
    24  b8d3 20cfe5                     jsr tmsSetBackground
    25  b8d6 a94f                       +tmsColorFgBg FG, BG
    26  b8d8 a53c                       lda BASIC_COLOR
    27  b8da 20d1e7                     jsr tmsInitEntireColorTable
    28                          
    29  b8dd 206de7                     jsr tmsInitPattTable
    30                          
    31  b8e0 a92020e5e5                 +tmsEnableInterrupts    ; gives us the console cursor, etc.
    32  b8e5 a94020e5e5                 +tmsEnableOutput
    33                          
    34  b8ea ada37c09808da37c           +consoleEnableCursor
    35  b8f2 28                         plp
    36                          
    37  b8f3 60                         rts
    38                          
    39                          
    40                          ; -----------------------------------------------------------------------------
    41                          ; hbc56Out - EhBASIC output subroutine (for HBC-56 TMS9918)
    42                          ; -----------------------------------------------------------------------------
    43                          ; Inputs:       A - ASCII character (or code) to output
    44                          ; Outputs:      A - must be maintained
    45                          ; -----------------------------------------------------------------------------
    46                          hbc56Out:
    47  b8f4 8636                       stx SAVE_X              ; save registers
    48  b8f6 8437                       sty SAVE_Y
    49  b8f8 8538                       sta SAVE_A
    50                          
    51  b8fa c907                       cmp #$07        ; bell (error beep)
    52  b8fc f00a                       beq .bellOut
    53                          
    54                                  ; output 'A' to console
    55  b8fe 20f5e9                     jsr tmsConsoleOut
    56                          
    57                          .endOut:
    58  b901 a636                       ldx SAVE_X              ; restore registers
    59  b903 a437                       ldy SAVE_Y
    60  b905 a538                       lda SAVE_A
    61  b907 60                         rts
    62                          
    63                          .bellOut
    64  b908 2092f2                     jsr hbc56Bell

; ******** Source: basic_tms.asm
    14  b90b 4c01b9                           ; output routines
    15                          
    16                          
    17                          ; -----------------------------------------------------------------------------
    18                          ; metadata for the HBC-56 kernel
    19                          ; -----------------------------------------------------------------------------
    20                          hbc56Meta:      
    21  b90e 4c17b94241534943...        +setHbcMetaTitle "BASIC"
    22  b93a 60                         rts
    23                          

; ******** Source: functions\basic_functions.asm
     1                          ; Troy's HBC-56 - Custom BASIC functions
     2                          ;
     3                          ; Copyright (c) 2023 Troy Schrapel
     4                          ;
     5                          ; This code is licensed under the MIT license
     6                          ;
     7                          ; https://github.com/visrealm/hbc-56
     8                          ;
     9                          
    10                          ; CALL COLOR,$ab 
    11                          
    12                          basicColor:
    13  b93b 20a3a4                     jsr LAB_GTBY
    14  b93e 8a                         txa
    15  b93f 853c                       sta BASIC_COLOR
    16                                  
    17  b941 08                         php
    18  b942 78                         sei
    19  b943 20d3e7                     jsr tmsInitColorTable
    20  b946 28                         plp
    21  b947 60                         rts
    22                          
    23                          modeTable:
    24  b948 b8e610e623e6       !word tmsModeText,tmsModeGraphicsI,tmsModeBitmap
    25                          
    26                          doMode:
    27  b94e 7c48b9                     jmp (modeTable, x)
    28                          
    29                          basicDisplay:
    30  b951 08                         php
    31  b952 78                         sei
    32  b953 20a3a4                     jsr LAB_GTBY
    33  b956 8a                         txa
    34  b957 c903                       cmp #3
    35  b959 b00c                       bcs basicErrorHandler
    36  b95b 0a                         asl
    37  b95c aa                         tax
    38  b95d 204eb9                     jsr doMode
    39                          
    40  b960 a53c                       lda BASIC_COLOR
    41  b962 20d3e7                     jsr tmsInitColorTable
    42  b965 28                         plp
    43  b966 60                         rts
    44                                  
    45                          basicErrorHandler:
    46  b967 28                         plp
    47  b968 4c409f                     jmp LAB_FCER
    48                          
    49                          basicPlot:
    50  b96b 20efa4                     jsr LAB_GADB
    51  b96e 863b                       stx BASIC_YPOS
    52  b970 a611                       ldx Itempl
    53  b972 863a                       stx BASIC_XPOS
    54  b974 a43b                       ldy BASIC_YPOS
    55                          
    56  b976 08                         php
    57  b977 78                         sei
    58                          
    59  b978 208ae9                     jsr tmsSetPatternTmpAddressII
    60  b97b 20a8e5                     jsr tmsSetAddressRead
    61                                  
    62  b97e a53a                       lda BASIC_XPOS
    63  b980 2907                       and #07
    64  b982 aa                         tax
    65  b983 ad107f2079e5               +tmsGet
    66                          
    67  b989 1d30e1                     ora tableBitFromLeft, x
    68  b98c 48                         pha
    69  b98d 2092e5                     jsr tmsSetAddressWrite
    70  b990 68                         pla
    71  b991 8d107f2079e5               +tmsPut
    72                          
    73  b997 a63a                       ldx BASIC_XPOS
    74  b999 a43b                       ldy BASIC_YPOS
    75                          
    76  b99b 2086e9                     jsr tmsSetColorTmpAddressII
    77  b99e 2092e5                     jsr tmsSetAddressWrite
    78  b9a1 a53c                       lda BASIC_COLOR
    79  b9a3 8d107f2079e5               +tmsPut
    80                          
    81  b9a9 28                         plp
    82                          
    83  b9aa 60                         rts
    84                          
    85                          
    86                          
    87                          
    88                          

; ******** Source: functions\jump_table.asm
     1                          *=$c000
     2                          
     3  c000 4c5ee9             CLS: jmp tmsConsoleCls

; ******** Source: basic_tms.asm
    24  c003 4c3bb9                ; custom functions

; ******** Source: kernel.asm
     1                          ; 6502 - HBC-56 Kernel
     2                          ;
     3                          ; Copyright (c) 2021 Troy Schrapel
     4                          ;
     5                          ; This code is licensed under the MIT license
     6                          ;
     7                          ; https://github.com/visrealm/hbc-56
     8                          ;
     9                          ;
    10                          
    11                          HBC56_INT_VECTOR = $7e00
    12                          HBC56_NMI_VECTOR = $7e04
    13                          HBC56_RST_VECTOR = kernelMain
    14                          
    15                          HBC56_KERNEL_START = $e000
    16                          HBC56_META_VECTOR  = HBC56_KERNEL_START-4
    17                          
    18                          RTI_OPCODE = $40
    19                          JMP_OPCODE = $4c
    20                          
    21                          ; -------------------------
    22                          ; I/O devices
    23                          ; -------------------------
    24                          LCD_IO_PORT             = $02
    25                          TMS9918_IO_PORT         = $10
    26                          UART_IO_PORT            = $20
    27                          AY_IO_PORT              = $40
    28                          KB_IO_PORT              = $80
    29                          NES_IO_PORT             = $82
    30                          INT_IO_PORT             = $df
    31                          VIA_IO_PORT             = $f0
    32                          ROM_BANK_REG            = $08
    33                          
    34                          ; -------------------------
    35                          ; Kernel Zero Page
    36                          ; -------------------------
    37                          HBC56_KERNEL_ZP_START   = $18
    38                          
    39                          TILEMAP_ZP_START        = HBC56_KERNEL_ZP_START
    40                          TILEMAP_ZP_END          = TILEMAP_ZP_START + 6
    41                          
    42                          BITMAP_ZP_START         = TILEMAP_ZP_END
    43                          BITMAP_ZP_END           = BITMAP_ZP_START + 6
    44                          
    45                          !ifdef HBC56_DISABLE_TMS9918 { .TMS_ZP_SIZE = 0 } else { .TMS_ZP_SIZE = 4 }
    46                          TMS9918_ZP_START        = BITMAP_ZP_END
    47                          TMS9918_ZP_END          = TMS9918_ZP_START + .TMS_ZP_SIZE
    48                          
    49                          !ifdef HBC56_DISABLE_LCD { .LCD_ZP_SIZE = 0 } else { .LCD_ZP_SIZE = 2 }
    50                          LCD_ZP_START            = TMS9918_ZP_END
    51                          LCD_ZP_END              = LCD_ZP_START + .LCD_ZP_SIZE
    52                          
    53                          !ifdef HBC56_DISABLE_UART { .UART_ZP_SIZE = 0 } else { .UART_ZP_SIZE = 4 }
    54                          UART_ZP_START            = LCD_ZP_END
    55                          UART_ZP_END              = UART_ZP_START + .UART_ZP_SIZE
    56                          
    57                          MEMORY_ZP_START         = UART_ZP_END
    58                          MEMORY_ZP_END           = MEMORY_ZP_START + 6
    59                          
    60                          STR_ADDR                = MEMORY_ZP_END
    61                          STR_ADDR_L              = MEMORY_ZP_END
    62                          STR_ADDR_H              = MEMORY_ZP_END + 1
    63                          
    64                          DELAY_L                 = STR_ADDR_H + 1
    65                          DELAY_H                 = DELAY_L + 1
    66                          
    67                          HBC56_KERNEL_ZP_END     = DELAY_H + 1
    68                          HBC56_USER_ZP_START     = HBC56_KERNEL_ZP_END
    69                          
    70                          ;!warn "Total ZP used: ",STR_ADDR_H-HBC56_KERNEL_ZP_START
    71                          
    72                          
    73                          !ifndef HAVE_TMS9918 { HBC56_DISABLE_SFXMAN=1 }
    74                          
    75                          ; -------------------------
    76                          ; Kernel RAM
    77                          ; -------------------------
    78                          HBC56_KERNEL_RAM_START  = $7a00
    79                          
    80                          TILEMAP_RAM_START       = HBC56_KERNEL_RAM_START
    81                          TILEMAP_RAM_END         = TILEMAP_RAM_START + $116
    82                          
    83                          BITMAP_RAM_START        = TILEMAP_RAM_END
    84                          BITMAP_RAM_END          = BITMAP_RAM_START + 16
    85                          
    86                          !ifdef HBC56_DISABLE_TMS9918 { .TMS_RAM_SIZE = 0 } else { .TMS_RAM_SIZE = 50 }
    87                          TMS9918_RAM_START       = BITMAP_RAM_END
    88                          TMS9918_RAM_END         = TMS9918_RAM_START + .TMS_RAM_SIZE
    89                          
    90                          !ifdef HBC56_DISABLE_LCD { .LCD_RAM_SIZE = 0 } else { .LCD_RAM_SIZE = 42 }
    91                          LCD_RAM_START           = TMS9918_RAM_END
    92                          LCD_RAM_END             = LCD_RAM_START + .LCD_RAM_SIZE
    93                          
    94                          !ifdef HBC56_DISABLE_UART { .UART_RAM_SIZE = 0 } else { .UART_RAM_SIZE = 256 }
    95                          UART_RAM_START            = LCD_RAM_END
    96                          UART_RAM_END              = UART_RAM_START + .UART_RAM_SIZE
    97                          
    98                          VIA_RAM_START             = UART_RAM_END
    99                          VIA_RAM_END               = VIA_RAM_START + 1
   100                          
   101                          !ifdef HBC56_DISABLE_SFXMAN { .SFXMAN_RAM_SIZE = 0 } else { .SFXMAN_RAM_SIZE = 18 }
   102                          SFXMAN_RAM_START        = VIA_RAM_END
   103                          SFXMAN_RAM_END          = SFXMAN_RAM_START + .SFXMAN_RAM_SIZE
   104                          
   105                          BCD_RAM_START           = SFXMAN_RAM_END
   106                          BCD_RAM_END             = BCD_RAM_START + 3
   107                          
   108                          KB_RAM_START            = BCD_RAM_END
   109                          KB_RAM_END              = KB_RAM_START + 64
   110                          
   111                          NES_RAM_START            = KB_RAM_END
   112                          NES_RAM_END              = NES_RAM_START + 3
   113                          
   114                          LAST_MODULE_RAM_END     = NES_RAM_END
   115                          
   116                          HBC56_TICKS             = LAST_MODULE_RAM_END
   117                          HBC56_SECONDS_L         = LAST_MODULE_RAM_END + 1
   118                          HBC56_SECONDS_H         = LAST_MODULE_RAM_END + 2
   119                          HBC56_TMP               = LAST_MODULE_RAM_END + 3
   120                          
   121                          HBC56_CONSOLE_FLAGS     = LAST_MODULE_RAM_END + 4
   122                          HBC56_CONSOLE_FLAG_CURSOR = $80
   123                          HBC56_CONSOLE_FLAG_NES    = $40
   124                          HBC56_CONSOLE_FLAG_LCD    = $20
   125                          HBC56_CONSOLE_FLAG_NOWAIT = $10
   126                          
   127                          HBC56_TMP_X             = LAST_MODULE_RAM_END + 5
   128                          HBC56_TMP_Y             = LAST_MODULE_RAM_END + 6
   129                          
   130                          HBC56_META_TITLE_MAX_LEN = 16
   131                          HBC56_META_TITLE        = LAST_MODULE_RAM_END + 7
   132                          HBC56_META_TITLE_END    = HBC56_META_TITLE + HBC56_META_TITLE_MAX_LEN + 1
   133                          HBC56_META_TITLE_LEN    = HBC56_META_TITLE_END + 1
   134                          
   135                          ; callback function on vsync
   136                          HBC56_VSYNC_CALLBACK = HBC56_META_TITLE_LEN + 1
   137                          HBC56_VIA_CALLBACK   = HBC56_VSYNC_CALLBACK + 2
   138                          
   139                          
   140                          HBC56_KERNEL_RAM_END    = HBC56_VIA_CALLBACK + 2
   141                          HBC56_KERNEL_RAM_SIZE   = HBC56_KERNEL_RAM_END - HBC56_KERNEL_RAM_START
   142                          ;!warn "Total RAM used: ",HBC56_KERNEL_RAM_SIZE
   143                          

; ******** Source: ../lib\hbc56.asm
     1                          ; 6502 - HBC-56
     2                          ;
     3                          ; Copyright (c) 2021 Troy Schrapel
     4                          ;
     5                          ; This code is licensed under the MIT license
     6                          ;
     7                          ; https://github.com/visrealm/hbc-56
     8                          ;
     9                          ;
    10                          
    11                          !cpu w65c02
    12                          !initmem $FF
    13                          cputype = $65c02
    14                          

; ******** Source: ../lib\hbc56.inc
     1                          ; 6502 - HBC-56
     2                          ;
     3                          ; Copyright (c) 2021 Troy Schrapel
     4                          ;
     5                          ; This code is licensed under the MIT license
     6                          ;
     7                          ; https://github.com/visrealm/hbc-56
     8                          ;
     9                          ;
    10                          
    11                          ; Base address of the 256 IO port memory range
    12                          IO_PORT_BASE_ADDRESS	= $7f00
    13                          
    14                          
    15                          ; -------------------------
    16                          ; ASCII constants
    17                          ; -------------------------
    18                          ASCII_RETURN    = $0A
    19                          ASCII_CR        = $0D
    20                          ASCII_BACKSPACE = $08
    21                          ASCII_BELL      = $07

; ******** Source: ../lib\hbc56.asm
    16                          
    17                          DEFAULT_HBC56_NMI_VECTOR = $FFE0
    18                          DEFAULT_HBC56_RST_VECTOR = $8000
    19                          DEFAULT_HBC56_INT_VECTOR = $FFE0
    20                          
    21                          !macro hbc56Title .title {
    22                          HBC56_TITLE_TEXT:
    23                                  !text .title
    24                          HBC56_TITLE_TEXT_LEN = * - HBC56_TITLE_TEXT
    25                                  !byte 0 ; nul terminator for game name
    26                          }
    27                          
    28                          *=DEFAULT_HBC56_INT_VECTOR
    29  ffe0 40                         rti
    30                          
    31                          hbc56Delay:
    32  ffe1 a000               	ldy #0
    33                          hbc56CustomDelay:
    34  ffe3 a200               	ldx #0
    35                          -
    36  ffe5 ca                 	dex
    37  ffe6 d0fd               	bne -
    38  ffe8 a200               	ldx #0
    39  ffea 88                 	dey
    40  ffeb d0f8               	bne -
    41  ffed 60                 	rts
    42                          
    43                          *=$FFFA
    44  fffa 047e               !ifdef HBC56_NMI_VECTOR { !word HBC56_NMI_VECTOR } else { !word DEFAULT_HBC56_NMI_VECTOR }
    45  fffc 77f1               !ifdef HBC56_RST_VECTOR { !word HBC56_RST_VECTOR } else { !word DEFAULT_HBC56_RST_VECTOR }
    46  fffe 007e               !ifdef HBC56_INT_VECTOR { !word HBC56_INT_VECTOR } else { !word DEFAULT_HBC56_INT_VECTOR }
    47                          
    48                          
    49                          *=DEFAULT_HBC56_RST_VECTOR

; ******** Source: kernel.asm
   144                          
   145                          *=HBC56_KERNEL_START
   146                          

; ******** Source: ../lib\ut\ascii.asm
     1                          ; 6502 - ASCII subroutines
     2                          ;
     3                          ; Copyright (c) 2022 Troy Schrapel
     4                          ;
     5                          ; This code is licensed under the MIT license
     6                          ;
     7                          ; https://github.com/visrealm/hbc-56
     8                          ;
     9                          ;
    10                          
    11                          ; -----------------------------------------------------------------------------
    12                          ; isLower: Is the ASCII character a lower-case letter (a-z)
    13                          ; -----------------------------------------------------------------------------
    14                          ; Inputs:
    15                          ;   A: ASCII character
    16                          ; Outputs:
    17                          ;   Carry set if lower case, carry clear if not lower case
    18                          ; -----------------------------------------------------------------------------
    19                          isLower:
    20  e000 c961                       cmp #'a'
    21  e002 9005                       bcc @notLower   ; less than 'a'?
    22  e004 c97b                       cmp #'z' + 1
    23  e006 9002                       bcc @isLower    ; less than or equal 'z'?
    24  e008 18                         clc
    25                          @notLower:
    26  e009 60                         rts
    27                          
    28                          @isLower
    29  e00a 38                         sec
    30  e00b 60                         rts
    31                          
    32                          
    33                          ; -----------------------------------------------------------------------------
    34                          ; isUpper: Is the ASCII character a upper-case letter (A-Z)
    35                          ; -----------------------------------------------------------------------------
    36                          ; Inputs:
    37                          ;   A: ASCII character
    38                          ; Outputs:
    39                          ;   Carry set if upper case, carry clear if not upper case
    40                          ; -----------------------------------------------------------------------------
    41                          isUpper:
    42  e00c c941                       cmp #'A'
    43  e00e 9005                       bcc @notUpper   ; less than 'A'?
    44  e010 c95b                       cmp #'Z' + 1
    45  e012 9002                       bcc @isUpper    ; less than or equal 'Z'?
    46  e014 18                         clc
    47                          @notUpper:
    48  e015 60                         rts
    49                          
    50                          @isUpper
    51  e016 38                         sec
    52  e017 60                         rts
    53                          
    54                          ; -----------------------------------------------------------------------------
    55                          ; isAlpha: Is the ASCII character alphanumeric (A-Z, a-z)
    56                          ; -----------------------------------------------------------------------------
    57                          ; Inputs:
    58                          ;   A: ASCII character
    59                          ; Outputs:
    60                          ;   Carry set if alpha, carry clear if not alpha
    61                          ; -----------------------------------------------------------------------------
    62                          isAlpha:
    63  e018 2000e0                     jsr isLower
    64  e01b 90ef                       bcc isUpper
    65  e01d 60                         rts
    66                          
    67                          
    68                          ; -----------------------------------------------------------------------------
    69                          ; isDigit: Is the ASCII character a decimal digit (0-9)
    70                          ; -----------------------------------------------------------------------------
    71                          ; Inputs:
    72                          ;   A: ASCII character
    73                          ; Outputs:
    74                          ;   Carry set if digit, carry clear if not digit
    75                          ; -----------------------------------------------------------------------------
    76                          isDigit:
    77  e01e c930                       cmp #'0'
    78  e020 9005                       bcc @notDigit    ; less than '0'?
    79  e022 c93a                       cmp #'9' + 1
    80  e024 9002                       bcc @isDigit     ; less than or equal '9'?
    81  e026 18                         clc
    82                          
    83                          @notDigit:
    84  e027 60                         rts
    85                          
    86                          @isDigit
    87  e028 38                         sec
    88  e029 60                         rts
    89                          
    90                          
    91                          ; -----------------------------------------------------------------------------
    92                          ; isAlNum: Is the ASCII character alphanumeric (A-Z, a-z, 0-9)
    93                          ; -----------------------------------------------------------------------------
    94                          ; Inputs:
    95                          ;   A: ASCII character
    96                          ; Outputs:
    97                          ;   Carry set if alphanumeric, carry clear if not alphanumeric
    98                          ; -----------------------------------------------------------------------------
    99                          isAlNum:
   100  e02a 2018e0                     jsr isAlpha
   101  e02d 90ef                       bcc isDigit
   102  e02f 60                         rts
   103                          
   104                          ; -----------------------------------------------------------------------------
   105                          ; isDigitX: Is the ASCII character a hex digit (A-F, a-f, 0-9)
   106                          ; -----------------------------------------------------------------------------
   107                          ; Inputs:
   108                          ;   A: ASCII character
   109                          ; Outputs:
   110                          ;   Carry set if hexadecimal, carry clear if not hexadecimal
   111                          ; -----------------------------------------------------------------------------
   112                          isDigitX:
   113  e030 201ee0                     jsr isDigit
   114  e033 b013                       bcs @endIsDigitX
   115  e035 c941                       cmp #'A'
   116  e037 900d                       bcc @notHexDigit   ; less than 'A'?
   117  e039 c947                       cmp #'F' + 1
   118  e03b 900a                       bcc @isHexDigit    ; less than or equal 'F'?
   119  e03d c961                       cmp #'a'
   120  e03f 9005                       bcc @notHexDigit   ; less than 'a'?
   121  e041 c967                       cmp #'f' + 1
   122  e043 9002                       bcc @isHexDigit    ; less than or equal 'f'?
   123  e045 18                         clc
   124                          @notHexDigit:
   125  e046 60                         rts
   126                          
   127                          @isHexDigit
   128  e047 38                         sec
   129                          
   130                          @endIsDigitX
   131  e048 60                         rts
   132                          
   133                          
   134                          ; -----------------------------------------------------------------------------
   135                          ; isSpace: Is the ASCII character a whitespace character?
   136                          ; -----------------------------------------------------------------------------
   137                          ; Inputs:
   138                          ;   A: ASCII character
   139                          ; Outputs:
   140                          ;   Carry set if space, carry clear if not space
   141                          ; -----------------------------------------------------------------------------
   142                          isSpace:
   143  e049 c920                       cmp #' '
   144  e04b f01c                       beq @isSpace
   145  e04d b018                       bcs @notSpace
   146  e04f c90a                       cmp #'\n'
   147  e051 f016                       beq @isSpace
   148  e053 c90d                       cmp #'\r'
   149  e055 f012                       beq @isSpace
   150  e057 c909                       cmp #'\t'
   151  e059 f00e                       beq @isSpace
   152  e05b c90d                       cmp #'\r'
   153  e05d f00a                       beq @isSpace
   154  e05f c90b                       cmp #$0b
   155  e061 f006                       beq @isSpace
   156  e063 c90c                       cmp #$0c
   157  e065 f002                       beq @isSpace
   158                          
   159                          @notSpace:
   160  e067 18                         clc
   161  e068 60                         rts
   162                          
   163                          @isSpace
   164  e069 38                         sec
   165  e06a 60                         rts
   166                          
   167                          ; -----------------------------------------------------------------------------
   168                          ; toUpper: convert an ascii character to upper case
   169                          ; -----------------------------------------------------------------------------
   170                          ; Inputs:
   171                          ;   A: ascii character
   172                          ; Outputs:
   173                          ;   A: upper case ascii character
   174                          ;   C: set if character was converted
   175                          ; -----------------------------------------------------------------------------
   176                          toUpper:
   177  e06b 2000e0                     jsr isLower
   178  e06e 9002                       bcc @endToUpper
   179  e070 4920                       eor #$20        ; convert (subtract $20)
   180                          
   181                          @endToUpper
   182  e072 60                         rts        
   183                          
   184                          ; -----------------------------------------------------------------------------
   185                          ; toLower: convert an ascii character to lower case
   186                          ; -----------------------------------------------------------------------------
   187                          ; Inputs:
   188                          ;   A: ascii character
   189                          ; Outputs:
   190                          ;   A: lower case ascii character
   191                          ;   C: set if character was converted
   192                          ; -----------------------------------------------------------------------------
   193                          toLower:
   194  e073 200ce0                     jsr isUpper
   195  e076 9002                       bcc @endToUpper
   196                          
   197  e078 0920                       ora #$20        ; convert (add $20)
   198                          
   199                          @endToUpper

; ******** Source: kernel.asm
   147  e07a 60                 

; ******** Source: ../lib\ut\bcd.asm
     1                          ; 6502 - BCD subroutines
     2                          ;
     3                          ; Copyright (c) 2020 Troy Schrapel
     4                          ;
     5                          ; This code is licensed under the MIT license
     6                          ;
     7                          ; https://github.com/visrealm/hbc-56
     8                          ;
     9                          ;
    10                          
    11                          
    12                          !ifndef BCD_RAM_START { BCD_RAM_START = $7810
    13                                  !warn "BCD_RAM_START not provided. Defaulting to ", BCD_RAM_START
    14                          }
    15                          
    16                          ; -------------------------
    17                          ; High RAM
    18                          ; -------------------------
    19                          BCD_TMP1	= BCD_RAM_START
    20                          BCD_TMP2	= BCD_RAM_START + 1
    21                          BCD_TMP3	= BCD_RAM_START + 2
    22                          .BCD_RAM_SIZE	= 3
    23                          
    24                          !if BCD_RAM_END < (BCD_RAM_START + .BCD_RAM_SIZE) {
    25                          	!error "BCD_RAM requires ",BCD_RAM_SIZE," bytes. Allocated ",BCD_RAM_END - BCD_RAM_START
    26                          }
    27                          
    28                          
    29                          ; -----------------------------------------------------------------------------
    30                          ; bin2bcd8: convert an unsigned byte to a 2-digit bcd value
    31                          ; -----------------------------------------------------------------------------
    32                          ; Inputs:
    33                          ;   A: value
    34                          ; Outputs:
    35                          ;   BCD value in R8
    36                          ; -----------------------------------------------------------------------------
    37                          bin2bcd8:
    38  e07b 8d597c               sta BCD_TMP1
    39  e07e a900                 lda #0
    40  e080 8d5a7c               sta BCD_TMP2
    41  e083 8d5b7c               sta BCD_TMP3
    42  e086 a208                 ldx #8 
    43  e088 f8                   sed    
    44                          .loop:
    45  e089 0e597c               asl BCD_TMP1
    46  e08c ad5a7c               lda BCD_TMP2
    47  e08f 6d5a7c               adc BCD_TMP2
    48  e092 8d5a7c               sta BCD_TMP2
    49  e095 ad5b7c               lda BCD_TMP3
    50  e098 6d5b7c               adc BCD_TMP3
    51  e09b 8d5b7c               sta BCD_TMP3
    52  e09e ca                   dex
    53  e09f d0e8                 bne .loop
    54  e0a1 d8                   cld   
    55  e0a2 60                   rts
    56                          

; ******** Source: kernel.asm
   148                          

; ******** Source: ../lib\ut\memory.asm
     1                          ; 6502
     2                          ;
     3                          ; Memory subroutines and macros
     4                          ;
     5                          ; Copyright (c) 2020 Troy Schrapel
     6                          ;
     7                          ; This code is licensed under the MIT license
     8                          ;
     9                          ; https://github.com/visrealm/hbc-56
    10                          ;
    11                          ;
    12                          

; ******** Source: ../lib\ut\memory.inc
     1                          ; 6502
     2                          ;
     3                          ; Memory subroutines and macros
     4                          ;
     5                          ; Copyright (c) 2020 Troy Schrapel
     6                          ;
     7                          ; This code is licensed under the MIT license
     8                          ;
     9                          ; https://github.com/visrealm/hbc-56
    10                          ;
    11                          ;
    12                          
    13                          ; -----------------------------------------------------------------------------
    14                          ; store16: Write a 16-bit immediate value to memory
    15                          ; -----------------------------------------------------------------------------
    16                          ; Inputs:
    17                          ;	.dst: destination address
    18                          ;	.val16: 16-bit value
    19                          ; -----------------------------------------------------------------------------
    20                          !macro store16 .dst, .val16 {
    21                                  lda #<.val16
    22                                  sta .addr
    23                                  lda #>.val16
    24                                  sta .addr + 1
    25                          }
    26                          
    27                          ; -----------------------------------------------------------------------------
    28                          ; memcpy: Copy a fixed number of bytes from .src to dest
    29                          ; -----------------------------------------------------------------------------
    30                          ; Inputs:
    31                          ;	.src: source address
    32                          ;	.dst: destination address
    33                          ;	.cnt: number of bytes
    34                          ; -----------------------------------------------------------------------------
    35                          !macro memcpy .dst, .src, .cnt {
    36                          !if .cnt <= 0 {
    37                          	!error "memcpy: invalid count: ", .cnt
    38                          } else if .cnt <= 8 {
    39                          	!for i, 0, .cnt - 1 {
    40                          		lda .src + i
    41                          		sta .dst + i
    42                          	}
    43                          } else { !if .cnt <= 256 {
    44                          	ldx #0
    45                          -
    46                          	lda .src, x
    47                          	sta .dst, x
    48                          	inx
    49                          	cpx #(.cnt & $ff)	
    50                          	bne -
    51                          } else {
    52                          	lda #<.src
    53                          	sta MEM_SRC
    54                          	lda #>.src
    55                          	sta MEM_SRC + 1
    56                          
    57                          	lda #<.dst
    58                          	sta MEM_DST
    59                          	lda #>.dst
    60                          	sta MEM_DST + 1
    61                          
    62                          
    63                          		lda #<.cnt
    64                          		sta MEM_LEN
    65                          		lda #>.cnt
    66                          		sta MEM_LEN + 1
    67                          		jsr memcpyMultiPage
    68                          	}
    69                          }
    70                          }
    71                          
    72                          !macro setMemCpySrc .src {
    73                          	lda #<.src
    74                          	sta MEM_SRC
    75                          	lda #>.src
    76                          	sta MEM_SRC + 1
    77                          }
    78                          
    79                          !macro setMemCpyDst .dst {
    80                          	lda #<.dst
    81                          	sta MEM_DST
    82                          	lda #>.dst
    83                          	sta MEM_DST + 1
    84                          }
    85                          
    86                          !macro setMemCpySrcInd .srcRef {
    87                          	lda .srcRef
    88                          	sta MEM_SRC
    89                          	lda .srcRef + 1
    90                          	sta MEM_SRC + 1
    91                          }
    92                          
    93                          !macro setMemCpyDstInd .dstRef {
    94                          	lda .dstRef
    95                          	sta MEM_DST
    96                          	lda .dstRef + 1
    97                          	sta MEM_DST + 1
    98                          }
    99                          
   100                          !macro memcpySinglePage .bytes {
   101                          
   102                          	!if .bytes <= 0 {
   103                          		!error "memcpySinglePage: invalid count: ", .bytes
   104                          	}	
   105                          
   106                          	ldy #.bytes
   107                          	jsr memcpySinglePage
   108                          }
   109                          
   110                          
   111                          ; -----------------------------------------------------------------------------
   112                          ; memcpyPort: Copy a fixed number of bytes from .src ram to dest port
   113                          ; -----------------------------------------------------------------------------
   114                          ; Inputs:
   115                          ;	.src: source address
   116                          ;	.dst: destination address
   117                          ;	.cnt: number of bytes
   118                          ; -----------------------------------------------------------------------------
   119                          !macro memcpyPort .dst, .src, .cnt {
   120                          	!if .cnt <= 0 {
   121                          		!error "memcpyPort: invalid count: ", .cnt
   122                          	}
   123                          	
   124                          	lda #<.src
   125                          	sta MEM_SRC
   126                          	lda #>.src
   127                          	sta MEM_SRC + 1
   128                          
   129                          	lda #<.dst
   130                          	sta MEM_DST
   131                          	lda #>.dst
   132                          	sta MEM_DST + 1
   133                          
   134                          	!if .cnt <= 256 {
   135                          		ldy #<.cnt					
   136                          		jsr memcpySinglePagePort
   137                          	} else {
   138                          		lda #<.cnt
   139                          		sta MEM_LEN
   140                          		lda #>.cnt
   141                          		sta MEM_LEN + 1
   142                          		jsr memcpyMultiPagePort
   143                          	}
   144                          }
   145                          
   146                          !zone {
   147                          
   148                          ; -----------------------------------------------------------------------------
   149                          ; memset: Set a fixed number of bytes to a single value
   150                          ; -----------------------------------------------------------------------------
   151                          ; Inputs:
   152                          ;	.dst: destination address
   153                          ;	val: the byte value
   154                          ;	.cnt: number of bytes
   155                          ; -----------------------------------------------------------------------------
   156                          !macro memset .dst, .val, .cnt {
   157                          !if .cnt <= 0 {
   158                          	!error "memset: invalid count: ", .cnt
   159                          } else if .cnt <= 8 {
   160                          	lda #.val
   161                          	!for i, 0, .cnt - 1 {
   162                          	sta .dst + i
   163                          	}
   164                          } else if .cnt <= 256 {
   165                          	ldx #<.cnt
   166                          	lda #.val
   167                          -
   168                          	dex
   169                          	sta .dst, x
   170                          	cpx #0
   171                          	bne -
   172                          } else {
   173                          	lda #<.dst
   174                          	sta MEM_DST
   175                          	lda #>.dst
   176                          	sta MEM_DST + 1
   177                          	lda #<.cnt
   178                          	sta MEM_LEN
   179                          	lda #>.cnt
   180                          	sta MEM_LEN + 1
   181                          	lda #.val
   182                          	jsr memsetMultiPage
   183                          }
   184                          }
   185                          
   186                          

; ******** Source: ../lib\ut\memory.asm
    14                          
    15                          
    16                          !ifndef MEMORY_ZP_START { MEMORY_ZP_START = $48
    17                                  !warn "MEMORY_ZP_START not provided. Defaulting to ", MEMORY_ZP_START
    18                          }
    19                          
    20                          ; -------------------------
    21                          ; Zero page
    22                          ; -------------------------
    23                          MEM_DST	= MEMORY_ZP_START
    24                          MEM_SRC	= MEMORY_ZP_START + 2
    25                          MEM_LEN	= MEMORY_ZP_START + 4
    26                          MEMORY_ZP_SIZE	= 6
    27                          
    28                          
    29                          !if MEMORY_ZP_END < (MEMORY_ZP_START + MEMORY_ZP_SIZE) {
    30                          	!error "MEMORY_ZP requires ",MEMORY_ZP_SIZE," bytes. Allocated ",MEMORY_ZP_END - MEMORY_ZP_START
    31                          }
    32                          
    33                          ; -----------------------------------------------------------------------------
    34                          ; memcpySinglePage: Copy up to 255 bytes 
    35                          ; -----------------------------------------------------------------------------
    36                          ; Inputs:
    37                          ;	MEM_SRC: src address
    38                          ;	MEM_DST: dst address
    39                          ;	Y:	bytes
    40                          ; -----------------------------------------------------------------------------
    41                          memcpySinglePage:
    42  e0a3 c000               	cpy #0
    43  e0a5 f009               	beq .endMemcpySinglePage
    44                          -
    45  e0a7 88                 	dey
    46  e0a8 b12e               	lda (MEM_SRC), Y
    47  e0aa 912c               	sta (MEM_DST), Y
    48  e0ac c000               	cpy #0
    49  e0ae d0f7               	bne -
    50                          .endMemcpySinglePage:
    51  e0b0 60                 	rts
    52                          ; -----------------------------------------------------------------------------
    53                          
    54                          
    55                          
    56                          ; -----------------------------------------------------------------------------
    57                          ; memcpySinglePagePort: Copy up to 255 bytes 
    58                          ; -----------------------------------------------------------------------------
    59                          ; Inputs:
    60                          ;	MEM_SRC: src address
    61                          ;	MEM_DST: dst address (port)
    62                          ;	Y:	bytes
    63                          ; -----------------------------------------------------------------------------
    64                          memcpySinglePagePort:
    65  e0b1 c000               	cpy #0
    66  e0b3 f009               	beq .endMemcpySinglePagePort
    67                          -
    68  e0b5 88                 	dey
    69  e0b6 b12e               	lda (MEM_SRC), Y
    70  e0b8 852c               	sta MEM_DST
    71  e0ba c000               	cpy #0
    72  e0bc d0f7               	bne -
    73                          .endMemcpySinglePagePort
    74  e0be 60                 	rts
    75                          ; -----------------------------------------------------------------------------
    76                          
    77                          
    78                          
    79                          ; -----------------------------------------------------------------------------
    80                          ; memcpyMultiPage: Copy an up to 2^15 bytes 
    81                          ; -----------------------------------------------------------------------------
    82                          ; Inputs:
    83                          ;	MEM_SRC: src address
    84                          ;	MEM_DST: dst address
    85                          ;	MEM_LEN: length
    86                          ; -----------------------------------------------------------------------------
    87                          memcpyMultiPage:
    88                          
    89                          !ifdef ALLOW_SELF_MODIFYING_CODE {
    90                          	lda MEM_SRC
    91                          	sta .loadIns + 1
    92                          	lda MEM_SRC + 1
    93                          	sta .loadIns + 2
    94                          
    95                          	lda MEM_DST
    96                          	sta .storeIns + 1
    97                          	lda MEM_DST + 1
    98                          	sta .storeIns + 2
    99                          
   100                          .loadIns:
   101                          	lda SELF_MODIFY_ADDR, Y
   102                          	
   103                          .storeIns:
   104                          	sta SELF_MODIFY_ADDR, Y
   105                          	dey
   106                          	bne .loadIns
   107                          	inc .loadIns + 2
   108                          	inc .storeIns + 2
   109                          	dex
   110                          	bne .loadIns
   111                          } else {
   112  e0bf a000               	ldy #0
   113  e0c1 a631               	ldx MEM_LEN + 1
   114                          - 
   115  e0c3 b12e               	lda (MEM_SRC),y ; could unroll to any power of 2
   116  e0c5 912c               	sta (MEM_DST),y
   117  e0c7 c8                 	iny
   118  e0c8 d0f9               	bne -
   119  e0ca ca                 	dex
   120  e0cb f007               	beq .memcpyMultiPageRemaining
   121  e0cd e62f               	inc MEM_SRC + 1
   122  e0cf e62d               	inc MEM_DST + 1
   123  e0d1 4cc3e0             	jmp -
   124                          .memcpyMultiPageRemaining ; remaining bytes
   125  e0d4 a630               	ldx MEM_LEN
   126  e0d6 f008               	beq .memcpyMultiPageEnd
   127                          - ; X bytes
   128  e0d8 b12e               	lda (MEM_SRC),y
   129  e0da 912c               	sta (MEM_DST),y
   130  e0dc c8                 	iny
   131  e0dd ca                 	dex
   132  e0de d0f8               	bne -
   133                          .memcpyMultiPageEnd
   134                          }
   135                          
   136  e0e0 60                 	rts
   137                          ; -----------------------------------------------------------------------------
   138                          
   139                          
   140                          ; -----------------------------------------------------------------------------
   141                          ; memcpyMultiPagePort: Copy an up to 2^15 bytes 
   142                          ; -----------------------------------------------------------------------------
   143                          ; Inputs:
   144                          ;	MEM_SRC: src address
   145                          ;	MEM_DST: dst address (port)
   146                          ;	MEM_LEN: length
   147                          ; -----------------------------------------------------------------------------
   148                          memcpyMultiPagePort:
   149                          
   150  e0e1 a000               	ldy #0
   151  e0e3 a631               	ldx MEM_LEN + 1
   152                          - 
   153  e0e5 b12e               	lda (MEM_SRC),y ; could unroll to any power of 2
   154  e0e7 852c               	sta MEM_DST
   155  e0e9 c8                 	iny
   156  e0ea d0f9               	bne -
   157  e0ec ca                 	dex
   158  e0ed f005               	beq .memcpyMultiPagePortRemaining
   159  e0ef e62f               	inc MEM_SRC + 1
   160  e0f1 4ce5e0             	jmp -
   161                          .memcpyMultiPagePortRemaining ; remaining bytes
   162  e0f4 a630               	ldx MEM_LEN
   163  e0f6 f008               	beq .memcpyMultiPagePortEnd
   164                          - ; X bytes
   165  e0f8 b12e               	lda (MEM_SRC),y
   166  e0fa 852c               	sta MEM_DST
   167  e0fc c8                 	iny
   168  e0fd ca                 	dex
   169  e0fe d0f8               	bne -
   170                          .memcpyMultiPagePortEnd
   171  e100 60                 	rts
   172                          ; -----------------------------------------------------------------------------
   173                          
   174                          
   175                          ; -----------------------------------------------------------------------------
   176                          ; memsetSinglePage: set a block of memory data
   177                          ; -----------------------------------------------------------------------------
   178                          ; Inputs:
   179                          ;	 A:	value to set
   180                          ;	 MEM_DST: start address
   181                          ;	 Y:	bytes
   182                          ; -----------------------------------------------------------------------------
   183                          memsetSinglePage:
   184  e101 c000               	cpy #0
   185  e103 f007               	beq .doneCpy
   186                          -
   187  e105 88                 	dey
   188  e106 912c               	sta (MEM_DST), y
   189  e108 c000               	cpy #0
   190  e10a d0f9               	bne -
   191                          .doneCpy
   192  e10c 60                 	rts
   193                          
   194                          
   195                          ; -----------------------------------------------------------------------------
   196                          ; memsetMultiPage: set a block of memory data
   197                          ; -----------------------------------------------------------------------------
   198                          ; Inputs:
   199                          ;	 A: value
   200                          ;	 MEM_DST: start address
   201                          ;	 MEM_LEN: length
   202                          ; -----------------------------------------------------------------------------
   203                          memsetMultiPage:
   204  e10d a631               	ldx MEM_LEN + 1
   205  e10f d005               	bne .doneSet
   206  e111 a430               	ldy MEM_LEN
   207  e113 4c01e1             	jmp memsetSinglePage
   208                          .doneSet
   209  e116 a000               	ldy #0
   210                          - 
   211  e118 912c               	sta (MEM_DST),y ; could unroll to any power of 2
   212  e11a c8                 	iny
   213  e11b d0fb               	bne -
   214  e11d ca                 	dex
   215  e11e f005               	beq .doneSet2
   216  e120 e62d               	inc MEM_DST + 1
   217  e122 4c18e1             	jmp -
   218                          .doneSet2 ; remaining bytes
   219  e125 a630               	ldx MEM_LEN
   220  e127 f006               	beq .doneSet3
   221                          - ; X bytes
   222  e129 912c               	sta (MEM_DST),y
   223  e12b c8                 	iny
   224  e12c ca                 	dex
   225  e12d d0fa               	bne -
   226                          .doneSet3
   227  e12f 60                 	rts

; ******** Source: kernel.asm
   149                          

; ******** Source: ../lib\ut\tables.asm
     1                          ; 6502 - Useful tables
     2                          ;
     3                          ; Copyright (c) 2022 Troy Schrapel
     4                          ;
     5                          ; This code is licensed under the MIT license
     6                          ;
     7                          ; https://github.com/visrealm/hbc-56
     8                          ;
     9                          ;
    10                          
    11                          tableBitFromLeft:
    12  e130 8040201008040201   !byte $80,$40,$20,$10,$08,$04,$02,$01
    13                          tableInvBitFromLeft:
    14  e138 7fbfdfeff7fbfdfe   !byte $7f,$bf,$df,$ef,$f7,$fb,$fd,$fe
    15                          tableBitFromRight:
    16  e140 0102040810204080   !byte $01,$02,$04,$08,$10,$20,$40,$80
    17                          tableInvBitFromRight:
    18  e148 fefdfbf7efdfbf7f   !byte $fe,$fd,$fb,$f7,$ef,$df,$bf,$7f
    19                          tableBitsFromLeft:
    20  e150 80c0e0f0f8fcfeff   !byte $80,$c0,$e0,$f0,$f8,$fc,$fe,$ff

; ******** Source: kernel.asm
   150                          
   151                          
   152                          !ifndef HBC56_DISABLE_AY3891X {

; ******** Source: ../lib\sfx\ay3891x.asm
     1                          ; 6502 - AY-3-819x PSG
     2                          ;
     3                          ; Copyright (c) 2021 Troy Schrapel
     4                          ;
     5                          ; This code is licensed under the MIT license
     6                          ;
     7                          ; https://github.com/visrealm/hbc-56
     8                          ;
     9                          

; ******** Source: ../lib\sfx\ay3891x.inc
     1                          ; 6502 - AY-3-819x PSG
     2                          ;
     3                          ; Copyright (c) 2021 Troy Schrapel
     4                          ;
     5                          ; This code is licensed under the MIT license
     6                          ;
     7                          ; https://github.com/visrealm/hbc-56
     8                          ;
     9                          
    10                          
    11                          
    12                          !macro ayWrite .dev, .reg, .val {
    13                                  lda #.reg
    14                                  sta IO_PORT_BASE_ADDRESS | AY_IO_PORT | AY_ADDR | .dev
    15                                  lda #.val
    16                                  sta IO_PORT_BASE_ADDRESS | AY_IO_PORT | AY_WRITE | .dev
    17                          }        
    18                          
    19                          !macro ayRead .dev, .reg {
    20                                  lda #.reg
    21                                  sta IO_PORT_BASE_ADDRESS | AY_IO_PORT | AY_ADDR | .dev
    22                                  lda IO_PORT_BASE_ADDRESS | AY_IO_PORT | AY_READ | .dev
    23                          }        
    24                          
    25                          
    26                          !macro ayWriteX .dev, .reg {
    27                                  lda #.reg
    28                                  sta IO_PORT_BASE_ADDRESS | AY_IO_PORT | AY_ADDR | .dev
    29                                  stx IO_PORT_BASE_ADDRESS | AY_IO_PORT | AY_WRITE | .dev
    30                          }
    31                          
    32                          !macro ayWriteA .dev, .reg {
    33                                  ldx #.reg
    34                                  stx IO_PORT_BASE_ADDRESS | AY_IO_PORT | AY_ADDR | .dev
    35                                  sta IO_PORT_BASE_ADDRESS | AY_IO_PORT | AY_WRITE | .dev
    36                          }
    37                          
    38                          !macro ayPlayNote .dev, .chan, .freq {
    39                                  !if .freq <= 0 {
    40                                          .val = 0
    41                                  } else {
    42                                          .val = AY_CLOCK_FREQ / (32.0 * .freq)
    43                                  }
    44                                  +ayWrite .dev, AY_CHA_TONE_L + (.chan * 2), <.val
    45                                  +ayWrite .dev, AY_CHA_TONE_H + (.chan * 2), >.val
    46                          }
    47                          
    48                          !macro ayToneWord .freq {
    49                                  !word (AY_CLOCK_FREQ / (32.0 * .freq))
    50                          }
    51                          
    52                          !macro ayToneByteL .freq {
    53                                  !byte <(AY_CLOCK_FREQ / (32.0 * .freq))
    54                          }
    55                          
    56                          !macro ayToneByteH .freq {
    57                                  !byte >(AY_CLOCK_FREQ / (32.0 * .freq))
    58                          }
    59                          
    60                          
    61                          !macro ayToneEnable .dev, .chan {
    62                                  +ayRead .dev, AY_ENABLES
    63                                  and #!($01 << .chan)
    64                                  +ayWriteA .dev, AY_ENABLES
    65                          }
    66                          
    67                          !macro ayToneDisable .dev, .chan {
    68                                  +ayRead .dev, AY_ENABLES
    69                                  ora #($01 << .chan)
    70                                  +ayWriteA .dev, AY_ENABLES
    71                          }
    72                          
    73                          !macro ayNoiseEnable .dev, .chan {
    74                                  +ayRead .dev, AY_ENABLES
    75                                  eor #($08 << .chan)
    76                                  +ayWriteA .dev, AY_ENABLES
    77                          }
    78                          
    79                          !macro ayNoiseDisable .dev, .chan {
    80                                  +ayRead .dev, AY_ENABLES
    81                                  ora #($08 << .chan)
    82                                  +ayWriteA .dev, AY_ENABLES
    83                          }
    84                          
    85                          !macro aySetVolume .dev, .chan, .vol {
    86                                  +ayWrite .dev, (AY_CHA_AMPL + .chan), (.vol >> 4)
    87                          }
    88                          
    89                          !macro aySetVolumeEnvelope .dev, .chan {
    90                                  +ayWrite .dev, (AY_CHA_AMPL + .chan), $10
    91                          }
    92                          
    93                          !macro aySetEnvelopePeriod .dev, .period {
    94                                  +ayWrite .dev, AY_ENV_PERIOD_L, <.period
    95                                  +ayWrite .dev, AY_ENV_PERIOD_H, >.period
    96                          }
    97                          
    98                          !macro aySetEnvShape .dev, .shape {
    99                                  +ayWrite .dev, AY_ENV_SHAPE, .shape
   100                          }
   101                          
   102                          !macro aySetNoise .dev, .freq {
   103                                  +ayWrite .dev, AY_ENV_SHAPE, .freq >> 3
   104                          }
   105                          
   106                          !macro ayStop .dev, .chan {
   107                                  +ayPlayNote .dev, .chan, 0
   108                          }

; ******** Source: ../lib\sfx\ay3891x.asm
    10                          
    11                          
    12                          
    13                          !ifndef AY_IO_PORT { AY_IO_PORT = $40
    14                                  !warn "AY_IO_PORT not provided. Defaulting to ", AY_IO_PORT
    15                          }
    16                          
    17                          HAVE_AY3891X = 1
    18                          
    19                          ; -------------------------
    20                          ; Constants
    21                          ; -------------------------
    22                          AY_PSG0 = $00
    23                          AY_PSG1 = $04
    24                          
    25                          ; IO Ports
    26                          AY_S0 = IO_PORT_BASE_ADDRESS | AY_IO_PORT | AY_PSG0
    27                          AY_S1 = IO_PORT_BASE_ADDRESS | AY_IO_PORT | AY_PSG1
    28                          
    29                          AY_INACTIVE = $03
    30                          AY_READ     = $02
    31                          AY_WRITE    = $01
    32                          AY_ADDR     = $00
    33                          
    34                          AY_S0_READ  = AY_S0 | AY_READ
    35                          AY_S0_WRITE = AY_S0 | AY_WRITE
    36                          AY_S0_ADDR  = AY_S0 | AY_ADDR
    37                          
    38                          AY_S1_READ  = AY_S1 | AY_READ
    39                          AY_S1_WRITE = AY_S1 | AY_WRITE
    40                          AY_S1_ADDR  = AY_S1 | AY_ADDR
    41                          
    42                          ; Registers
    43                          AY_R0 = 0
    44                          AY_R1 = 1
    45                          AY_R2 = 2
    46                          AY_R3 = 3
    47                          AY_R4 = 4
    48                          AY_R5 = 5
    49                          AY_R6 = 6
    50                          AY_R7 = 7
    51                          AY_R8 = 8
    52                          AY_R9 = 9
    53                          AY_R10 = 10
    54                          AY_R11 = 11
    55                          AY_R12 = 12
    56                          AY_R13 = 13
    57                          AY_R14 = 14
    58                          AY_R15 = 15
    59                          AY_R16 = 16
    60                          AY_R17 = 17
    61                          
    62                          AY_CHA = 0
    63                          AY_CHB = 1
    64                          AY_CHC = 2
    65                          AY_CHN = 3
    66                          
    67                          AY_CHA_TONE_L   = AY_R0
    68                          AY_CHA_TONE_H   = AY_R1
    69                          AY_CHB_TONE_L   = AY_R2
    70                          AY_CHB_TONE_H   = AY_R3
    71                          AY_CHC_TONE_L   = AY_R4
    72                          AY_CHC_TONE_H   = AY_R5
    73                          AY_NOISE_GEN    = AY_R6
    74                          AY_ENABLES      = AY_R7
    75                          AY_CHA_AMPL     = AY_R8
    76                          AY_CHB_AMPL     = AY_R9
    77                          AY_CHC_AMPL     = AY_R10
    78                          AY_ENV_PERIOD_L = AY_R11
    79                          AY_ENV_PERIOD_H = AY_R12
    80                          AY_ENV_SHAPE    = AY_R13
    81                          AY_PORTA        = AY_R14
    82                          AY_PORTB        = AY_R15
    83                          
    84                          AY_ENV_SHAPE_CONTINUE  = $08
    85                          AY_ENV_SHAPE_ATTACK    = $04
    86                          AY_ENV_SHAPE_ALTERNATE = $02
    87                          AY_ENV_SHAPE_HOLD      = $01
    88                          
    89                          ;  /\  /\  /\  /\  /\ 
    90                          ; /  \/  \/  \/  \/  \
    91                          AY_ENV_SHAPE_TRIANGLE     = (AY_ENV_SHAPE_CONTINUE | AY_ENV_SHAPE_ATTACK | AY_ENV_SHAPE_ALTERNATE)
    92                          
    93                          ;  /------------------
    94                          ; /
    95                          AY_ENV_SHAPE_FADE_IN      = (AY_ENV_SHAPE_CONTINUE | AY_ENV_SHAPE_ATTACK | AY_ENV_SHAPE_HOLD)
    96                          
    97                          ; \
    98                          ;  \__________________
    99                          AY_ENV_SHAPE_FADE_OUT     = (AY_ENV_SHAPE_CONTINUE | AY_ENV_SHAPE_HOLD)
   100                          
   101                          ; \ |\ |\ |\ |\ |\ |\ |
   102                          ;  \| \| \| \| \| \| \|
   103                          AY_ENV_SHAPE_SAW1         = (AY_ENV_SHAPE_CONTINUE)
   104                          
   105                          ;  /| /| /| /| /| /| /|
   106                          ; / |/ |/ |/ |/ |/ |/ |
   107                          AY_ENV_SHAPE_SAW2         = (AY_ENV_SHAPE_CONTINUE | AY_ENV_SHAPE_ATTACK)
   108                          
   109                          ;  /|
   110                          ; / |__________________
   111                          AY_ENV_SHAPE_FADE_IN_STOP = (AY_ENV_SHAPE_ATTACK)
   112                          
   113                          
   114                          AY_CLOCK_FREQ   = 2000000
   115                          
   116                          ayInit:
   117                                  ; disable everything
   118  e158 a9078d407fa9ff8d...        +ayWrite AY_PSG0, AY_ENABLES, $ff
   119  e162 a9078d447fa9ff8d...        +ayWrite AY_PSG1, AY_ENABLES, $ff
   120                          
   121  e16c a9088d407fa9008d...        +aySetVolume AY_PSG0, AY_CHA, 0
   122  e176 a9098d407fa9008d...        +aySetVolume AY_PSG0, AY_CHB, 0
   123  e180 a90a8d407fa9008d...        +aySetVolume AY_PSG0, AY_CHC, 0
   124                          
   125  e18a a9008d407fa9008d...        +ayPlayNote AY_PSG0, AY_CHA, 0
   126  e19e a9028d407fa9008d...        +ayPlayNote AY_PSG0, AY_CHB, 0
   127  e1b2 a9048d407fa9008d...        +ayPlayNote AY_PSG0, AY_CHC, 0
   128                          
   129  e1c6 a90b8d407fa9008d...        +aySetEnvelopePeriod AY_PSG0, 0
   130  e1da a90d8d407fa9008d...        +aySetEnvShape AY_PSG0, 0
   131  e1e4 a90d8d407fa9008d...        +aySetNoise  AY_PSG0, 0
   132                          
   133  e1ee a9088d447fa9008d...        +aySetVolume AY_PSG1, AY_CHA, 0
   134  e1f8 a9098d447fa9008d...        +aySetVolume AY_PSG1, AY_CHB, 0
   135  e202 a90a8d447fa9008d...        +aySetVolume AY_PSG1, AY_CHC, 0
   136                          
   137  e20c a9008d447fa9008d...        +ayPlayNote AY_PSG1, AY_CHA, 0
   138  e220 a9028d447fa9008d...        +ayPlayNote AY_PSG1, AY_CHB, 0
   139  e234 a9048d447fa9008d...        +ayPlayNote AY_PSG1, AY_CHC, 0
   140                          
   141  e248 a90b8d447fa9008d...        +aySetEnvelopePeriod AY_PSG1, 0
   142  e25c a90d8d447fa9008d...        +aySetEnvShape AY_PSG1, 0
   143  e266 a90d8d447fa9008d...        +aySetNoise  AY_PSG1, 0
   144  e270 60                         rts
   145                          
   146                          ; Note frequencies from https://pages.mtu.edu/~suits/notefreqs.html
   147                          
   148                          NOTE_FREQ_C0  = 16.35
   149                          NOTE_FREQ_CS0 = 17.32
   150                          NOTE_FREQ_D0  = 18.35
   151                          NOTE_FREQ_DS0 = 19.45
   152                          NOTE_FREQ_E0  = 20.6
   153                          NOTE_FREQ_F0  = 21.83
   154                          NOTE_FREQ_FS0 = 23.12
   155                          NOTE_FREQ_G0  = 24.5
   156                          NOTE_FREQ_GS0 = 25.96
   157                          NOTE_FREQ_A0  = 27.5
   158                          NOTE_FREQ_AS0 = 29.14
   159                          NOTE_FREQ_B0  = 30.87
   160                          NOTE_FREQ_C1  = 32.7
   161                          NOTE_FREQ_CS1 = 34.65
   162                          NOTE_FREQ_D1  = 36.71
   163                          NOTE_FREQ_DS1 = 38.89
   164                          NOTE_FREQ_E1  = 41.2
   165                          NOTE_FREQ_F1  = 43.65
   166                          NOTE_FREQ_FS1 = 46.25
   167                          NOTE_FREQ_G1  = 49
   168                          NOTE_FREQ_GS1 = 51.91
   169                          NOTE_FREQ_A1  = 55
   170                          NOTE_FREQ_AS1 = 58.27
   171                          NOTE_FREQ_B1  = 61.74
   172                          NOTE_FREQ_C2  = 65.41
   173                          NOTE_FREQ_CS2 = 69.3
   174                          NOTE_FREQ_D2  = 73.42
   175                          NOTE_FREQ_DS2 = 77.78
   176                          NOTE_FREQ_E2  = 82.41
   177                          NOTE_FREQ_F2  = 87.31
   178                          NOTE_FREQ_FS2 = 92.5
   179                          NOTE_FREQ_G2  = 98
   180                          NOTE_FREQ_GS2 = 103.83
   181                          NOTE_FREQ_A2  = 110
   182                          NOTE_FREQ_AS2 = 116.54
   183                          NOTE_FREQ_B2  = 123.47
   184                          NOTE_FREQ_C3  = 130.81
   185                          NOTE_FREQ_CS3 = 138.59
   186                          NOTE_FREQ_D3  = 146.83
   187                          NOTE_FREQ_DS3 = 155.56
   188                          NOTE_FREQ_E3  = 164.81
   189                          NOTE_FREQ_F3  = 174.61
   190                          NOTE_FREQ_FS3 = 185
   191                          NOTE_FREQ_G3  = 196
   192                          NOTE_FREQ_GS3 = 207.65
   193                          NOTE_FREQ_A3  = 220
   194                          NOTE_FREQ_AS3 = 233.08
   195                          NOTE_FREQ_B3  = 246.94
   196                          NOTE_FREQ_C4  = 261.63
   197                          NOTE_FREQ_CS4 = 277.18
   198                          NOTE_FREQ_D4  = 293.66
   199                          NOTE_FREQ_DS4 = 311.13
   200                          NOTE_FREQ_E4  = 329.63
   201                          NOTE_FREQ_F4  = 349.23
   202                          NOTE_FREQ_FS4 = 369.99
   203                          NOTE_FREQ_G4  = 392
   204                          NOTE_FREQ_GS4 = 415.3
   205                          NOTE_FREQ_A4  = 440
   206                          NOTE_FREQ_AS4 = 466.16
   207                          NOTE_FREQ_B4  = 493.88
   208                          NOTE_FREQ_C5  = 523.25
   209                          NOTE_FREQ_CS5 = 554.37
   210                          NOTE_FREQ_D5  = 587.33
   211                          NOTE_FREQ_DS5 = 622.25
   212                          NOTE_FREQ_E5  = 659.25
   213                          NOTE_FREQ_F5  = 698.46
   214                          NOTE_FREQ_FS5 = 739.99
   215                          NOTE_FREQ_G5  = 783.99
   216                          NOTE_FREQ_GS5 = 830.61
   217                          NOTE_FREQ_A5  = 880
   218                          NOTE_FREQ_AS5 = 932.33
   219                          NOTE_FREQ_B5  = 987.77
   220                          NOTE_FREQ_C6  = 1046.5
   221                          NOTE_FREQ_CS6 = 1108.73
   222                          NOTE_FREQ_D6  = 1174.66
   223                          NOTE_FREQ_DS6 = 1244.51
   224                          NOTE_FREQ_E6  = 1318.51
   225                          NOTE_FREQ_F6  = 1396.91
   226                          NOTE_FREQ_FS6 = 1479.98
   227                          NOTE_FREQ_G6  = 1567.98
   228                          NOTE_FREQ_GS6 = 1661.22
   229                          NOTE_FREQ_A6  = 1760
   230                          NOTE_FREQ_AS6 = 1864.66
   231                          NOTE_FREQ_B6  = 1975.53
   232                          NOTE_FREQ_C7  = 2093
   233                          NOTE_FREQ_CS7 = 2217.46
   234                          NOTE_FREQ_D7  = 2349.32
   235                          NOTE_FREQ_DS7 = 2489.02
   236                          NOTE_FREQ_E7  = 2637.02
   237                          NOTE_FREQ_F7  = 2793.83
   238                          NOTE_FREQ_FS7 = 2959.96
   239                          NOTE_FREQ_G7  = 3135.96
   240                          NOTE_FREQ_GS7 = 3322.44
   241                          NOTE_FREQ_A7  = 3520
   242                          NOTE_FREQ_AS7 = 3729.31
   243                          NOTE_FREQ_B7  = 3951.07
   244                          NOTE_FREQ_C8  = 4186.01
   245                          NOTE_FREQ_CS8 = 4434.92
   246                          NOTE_FREQ_D8  = 4698.63
   247                          NOTE_FREQ_DS8 = 4978.03
   248                          NOTE_FREQ_E8  = 5274.04
   249                          NOTE_FREQ_F8  = 5587.65
   250                          NOTE_FREQ_FS8 = 5919.91
   251                          NOTE_FREQ_G8  = 6271.93
   252                          NOTE_FREQ_GS8 = 6644.88
   253                          NOTE_FREQ_A8  = 7040
   254                          NOTE_FREQ_AS8 = 7458.62
   255                          NOTE_FREQ_B8  = 7902.13

; ******** Source: kernel.asm
   153                          
   154                          }
   155                          
   156                          !ifndef HBC56_DISABLE_TMS9918 {
   157                                  !ifndef TMS_MODEL { TMS_MODEL = 9918 }

; ******** Source: ../lib\gfx\tms9918.asm
     1                          ; 6502 - TMS9918 VDP
     2                          ;
     3                          ; Copyright (c) 2021 Troy Schrapel
     4                          ;
     5                          ; This code is licensed under the MIT license
     6                          ;
     7                          ; https://github.com/visrealm/hbc-56
     8                          ;
     9                          

; ******** Source: ../lib\hbc56.inc
     1                          ; 6502 - HBC-56
     2                          ;
     3                          ; Copyright (c) 2021 Troy Schrapel
     4                          ;
     5                          ; This code is licensed under the MIT license
     6                          ;
     7                          ; https://github.com/visrealm/hbc-56
     8                          ;
     9                          ;
    10                          
    11                          ; Base address of the 256 IO port memory range
    12                          IO_PORT_BASE_ADDRESS	= $7f00
    13                          
    14                          
    15                          ; -------------------------
    16                          ; ASCII constants
    17                          ; -------------------------
    18                          ASCII_RETURN    = $0A
    19                          ASCII_CR        = $0D
    20                          ASCII_BACKSPACE = $08
    21                          ASCII_BELL      = $07

; ******** Source: ../lib\gfx\tms9918.asm
    10                          
    11                          
    12                          !ifndef HAVE_MATH_INC { !src "ut/math.inc" }

; ******** Source: ../lib\gfx\tms9918.inc
     1                          ; 6502 - TMS9918 VDP Macros
     2                          ;
     3                          ; Copyright (c) 2021 Troy Schrapel
     4                          ;
     5                          ; This code is licensed under the MIT license
     6                          ;
     7                          ; https://github.com/visrealm/hbc-56
     8                          ;
     9                          
    10                          
    11                          
    12                          
    13                          ; -----------------------------------------------------------------------------
    14                          ; tmsWaitReg: Not sure how much delay we need so make a macro for now
    15                          ; -----------------------------------------------------------------------------
    16                          !macro tmsWaitReg {
    17                                  jsr _tmsWaitReg
    18                          }
    19                          
    20                          ; -----------------------------------------------------------------------------
    21                          ; tmsWaitData: Not sure how much delay we need so make a macro for now
    22                          ; -----------------------------------------------------------------------------
    23                          !macro tmsWaitData {
    24                                  jsr _tmsWaitData
    25                          }
    26                          
    27                          ; -----------------------------------------------------------------------------
    28                          ; tmsSetAddressWrite: Set an address in the TMS9918
    29                          ; -----------------------------------------------------------------------------
    30                          !macro tmsSetAddressWrite .addr {
    31                                  +tmsSetAddressRead ($4000 | .addr)
    32                          }
    33                          
    34                          ; -----------------------------------------------------------------------------
    35                          ; tmsSetAddressRead: Set an address to read from the TMS9918
    36                          ; -----------------------------------------------------------------------------
    37                          !macro tmsSetAddressRead .addr {
    38                                  php
    39                                  sei             ; we can't be interrupted here
    40                                  lda #<(.addr)
    41                                  sta TMS9918_REG
    42                                  +tmsWaitReg
    43                                  lda #>(.addr)
    44                                  sta TMS9918_REG
    45                                  +tmsWaitReg
    46                                  plp
    47                          }
    48                          
    49                          ; -----------------------------------------------------------------------------
    50                          ; tmsGet: Get a byte of data from the TMS9918
    51                          ; -----------------------------------------------------------------------------
    52                          !macro tmsGet {
    53                                  lda TMS9918_RAM
    54                                  +tmsWaitData
    55                          }
    56                          
    57                          ; -----------------------------------------------------------------------------
    58                          ; tmsPut: Send a byte of data to the TMS9918
    59                          ; -----------------------------------------------------------------------------
    60                          !macro tmsPut .byte {
    61                                  lda #(.byte & 0xff)
    62                                  +tmsPut
    63                          }
    64                          
    65                          
    66                          ; -----------------------------------------------------------------------------
    67                          ; tmsPut: Send a byte (A) of data to the TMS9918
    68                          ; -----------------------------------------------------------------------------
    69                          !macro tmsPut {
    70                                  sta TMS9918_RAM
    71                                  +tmsWaitData
    72                          }
    73                          
    74                          ; -----------------------------------------------------------------------------
    75                          ; tmsSetColor: Set current fg/bg color
    76                          ; -----------------------------------------------------------------------------
    77                          !macro tmsSetColor .color {
    78                                  lda #.color
    79                                  jsr tmsSetBackground
    80                          }
    81                          
    82                          ; -----------------------------------------------------------------------------
    83                          ; tmsSetColorFgBg: Set current fg/bg color
    84                          ; -----------------------------------------------------------------------------
    85                          !macro tmsSetColorFgBg .fg, .bg {
    86                                  +tmsColorFgBg .fg, .bg
    87                                  jsr tmsSetBackground
    88                          }
    89                          
    90                          ; -----------------------------------------------------------------------------
    91                          ; byteTmsColorFgBg: Output a data byte
    92                          ; -----------------------------------------------------------------------------
    93                          !macro byteTmsColorFgBg .fg, .bg {
    94                          !byte (.fg << 4 | .bg)
    95                          }
    96                          
    97                          
    98                          ; -----------------------------------------------------------------------------
    99                          ; tmsDisableOutput: Disable the TMS9918 output
   100                          ; -----------------------------------------------------------------------------
   101                          !macro tmsDisableOutput {
   102                                  lda #TMS_R1_DISP_ACTIVE
   103                                  jsr tmsReg1ClearFields
   104                          }
   105                          
   106                          ; -----------------------------------------------------------------------------
   107                          ; tmsEnableOutput: Enable the TMS9918 output
   108                          ; -----------------------------------------------------------------------------
   109                          !macro tmsEnableOutput {
   110                                  lda #TMS_R1_DISP_ACTIVE
   111                                  jsr tmsReg1SetFields
   112                          }
   113                          
   114                          ; -
   115                          !macro tmsEnableInterrupts {
   116                                  lda #TMS_R1_INT_ENABLE
   117                                  jsr tmsReg1SetFields
   118                          }
   119                          
   120                          !macro tmsDisableInterrupts {
   121                                  lda #TMS_R1_INT_ENABLE
   122                                  jsr tmsReg1ClearFields
   123                          }
   124                          
   125                          !macro tmsConsoleOut .char {
   126                                  lda #.char
   127                                  jsr tmsConsoleOut
   128                          }
   129                          
   130                          
   131                          ; -----------------------------------------------------------------------------
   132                          ; tmsConsolePrintAddr: Print text to console
   133                          ; -----------------------------------------------------------------------------
   134                          ; Inputs:
   135                          ;  textAddr: Address of null-terminated string to print
   136                          ; -----------------------------------------------------------------------------
   137                          !macro tmsConsolePrintAddr .textAddr {
   138                                  lda #<.textAddr
   139                                  sta STR_ADDR_L
   140                                  lda #>.textAddr
   141                                  sta STR_ADDR_H
   142                                  jsr tmsConsolePrint        
   143                          }
   144                          
   145                          ; -----------------------------------------------------------------------------
   146                          ; tmsConsolePrint: Print immediate text to console
   147                          ; -----------------------------------------------------------------------------
   148                          ; Inputs:
   149                          ;  str: String to print
   150                          ; -----------------------------------------------------------------------------
   151                          !macro tmsConsolePrint .str {
   152                          	jmp .afterText
   153                          .textAddr
   154                          	!text .str,0
   155                          .afterText        
   156                                  +tmsConsolePrintAddr .textAddr
   157                          }
   158                          
   159                          ; -----------------------------------------------------------------------------
   160                          ; +tmsColorFgBg: Set A to the given FG / BG color
   161                          ; -----------------------------------------------------------------------------
   162                          !macro tmsColorFgBg .fg, .bg {
   163                                  lda #(.fg << 4 | .bg)
   164                          }
   165                          
   166                          ; -----------------------------------------------------------------------------
   167                          ; tmsReadStatus: Read status - clear interrupt
   168                          ; -----------------------------------------------------------------------------
   169                          !macro tmsReadStatus  {
   170                                  bit TMS9918_REG
   171                          }
   172                          
   173                          ; -----------------------------------------------------------------------------
   174                          ; tmsSendData: Send # bytes from .sourceAddr to tms9918 data port
   175                          ; -----------------------------------------------------------------------------
   176                          !macro tmsSendData .sourceAddr, .numBytes {
   177                                  lda #<.sourceAddr
   178                                  sta TMS_TMP_ADDRESS
   179                                  lda #>.sourceAddr
   180                                  sta TMS_TMP_ADDRESS + 1
   181                          
   182                                  !if .numBytes < 256 {
   183                                          ldx #.numBytes
   184                                          jsr tmsSendBytes
   185                                  } else {
   186                                          !do while .numBytes > 0 {
   187                                                  !if .numBytes > 255 {
   188                                                          ldx #0
   189                                                          !set .numBytes = .numBytes - 256
   190                                                  } else {
   191                                                          ldx #.numBytes
   192                                                          !set .numBytes = 0
   193                                                  }
   194                                                  jsr tmsSendBytes
   195                                                  inc TMS_TMP_ADDRESS + 1
   196                                          }
   197                                  }
   198                          
   199                          }
   200                          
   201                          ; -----------------------------------------------------------------------------
   202                          ; tmsSendDataRpt: Send # bytes from .sourceAddr to tms9918 data port .rpt times
   203                          ; -----------------------------------------------------------------------------
   204                          !macro tmsSendDataRpt .sourceAddr, .numBytes, .rpt {
   205                                  lda #<.sourceAddr
   206                                  sta TMS_TMP_ADDRESS
   207                                  lda #>.sourceAddr
   208                                  sta TMS_TMP_ADDRESS + 1
   209                          
   210                                  !if .numBytes < 256 {
   211                                          !if .rpt < 5 {
   212                                                  !for i,1,.rpt {
   213                                                          ldx #.numBytes
   214                                                          jsr tmsSendBytes
   215                                                  }
   216                                          } else {
   217                                                  lda #.rpt
   218                                                  sta TMS9918_TMP_BUFFER
   219                          -
   220                                                  ldx #.numBytes
   221                                                  jsr tmsSendBytes
   222                                                  dec TMS9918_TMP_BUFFER
   223                                                  bne -
   224                                          }
   225                                  } else {
   226                                          !error "tmsSendDataRpt supports <256 bytes only"
   227                                  }
   228                          }
   229                          
   230                          
   231                          ; -----------------------------------------------------------------------------
   232                          ; tmsPutRpt: Send value .rpt times
   233                          ; -----------------------------------------------------------------------------
   234                          !macro tmsPutRpt .value, .rpt {
   235                                  ldx #.rpt
   236                                  lda #.value
   237                          -
   238                                  +tmsPut
   239                                  dex
   240                                  bne -
   241                          }
   242                          
   243                          !macro tmsPutSeq .from, .count {
   244                                  lda #.from
   245                          -
   246                                  +tmsPut
   247                                  inc
   248                                  cmp #<(.from + .count)
   249                                  bne -
   250                          }
   251                          
   252                          !macro tmsSetSourceAddressInd .addr {
   253                          	lda .addr
   254                          	sta TMS_TMP_ADDRESS
   255                          	lda .addr + 1
   256                          	sta TMS_TMP_ADDRESS + 1
   257                          }
   258                          
   259                          !macro tmsSetSourceAddressIndOffset .addr, .offset {
   260                                  clc
   261                          	lda .addr
   262                                  adc #<.offset
   263                          	sta TMS_TMP_ADDRESS
   264                          	lda .addr + 1
   265                                  adc #>.offset
   266                          	sta TMS_TMP_ADDRESS + 1
   267                          }
   268                          
   269                          
   270                          !macro tmsSendBytes .bytes {
   271                                  ldx #.bytes
   272                                  jsr tmsSendBytes
   273                          }
   274                          
   275                          
   276                          ; -----------------------------------------------------------------------------
   277                          ; tmsSetAddrPattTable: Initialise address for font table
   278                          ; -----------------------------------------------------------------------------
   279                          !macro tmsSetAddrPattTable {
   280                                  +tmsSetAddrPattTable 0
   281                          }
   282                          
   283                          ; -----------------------------------------------------------------------------
   284                          ; tmsSetAddrPattTable: Initialise address for pattern table
   285                          ; -----------------------------------------------------------------------------
   286                          !macro tmsSetAddrPattTable .ind {
   287                                  +tmsSetAddressWrite TMS_VRAM_PATT_ADDRESS + (8 * .ind)
   288                          }
   289                          
   290                          ; -----------------------------------------------------------------------------
   291                          ; tmsSetAddrPattTable: Initialise address for pattern table
   292                          ; -----------------------------------------------------------------------------
   293                          !macro tmsSetAddrPattTable .ind, .row {
   294                                  +tmsSetAddressWrite TMS_VRAM_PATT_ADDRESS + (8 * .ind) + .row
   295                          }
   296                          
   297                          ; -----------------------------------------------------------------------------
   298                          ; tmsSetAddrPattTableIIBank0: Initialise address for pattern table
   299                          ; -----------------------------------------------------------------------------
   300                          !macro tmsSetAddrPattTableIIBank0 .ind {
   301                                  +tmsSetAddrPattTable .ind
   302                          }
   303                          
   304                          ; -----------------------------------------------------------------------------
   305                          ; tmsSetAddrPattTableIIBank1: Initialise address for pattern table
   306                          ; -----------------------------------------------------------------------------
   307                          !macro tmsSetAddrPattTableIIBank1 .ind {
   308                                  +tmsSetAddrPattTable 256 + .ind
   309                          }
   310                          
   311                          ; -----------------------------------------------------------------------------
   312                          ; tmsSetAddrPattTableIIBank2: Initialise address for pattern table
   313                          ; -----------------------------------------------------------------------------
   314                          !macro tmsSetAddrPattTableIIBank2 .ind {
   315                                  +tmsSetAddrPattTable 512 + .ind
   316                          }
   317                          
   318                          ; -----------------------------------------------------------------------------
   319                          ; tmsSetAddrPattTableRead: Initialise address for pattern table to read
   320                          ; -----------------------------------------------------------------------------
   321                          !macro tmsSetAddrPattTableRead .ind {
   322                                  +tmsSetAddressRead TMS_VRAM_PATT_ADDRESS + (8 * .ind)
   323                          }
   324                          
   325                          ; -----------------------------------------------------------------------------
   326                          ; tmsSetAddrPattTableRowRead: Initialise address for pattern table to read
   327                          ; -----------------------------------------------------------------------------
   328                          !macro tmsSetAddrPattTableRead .ind, .row {
   329                                  +tmsSetAddressRead TMS_VRAM_PATT_ADDRESS + (8 * .ind) + .row
   330                          }
   331                          
   332                          ; -----------------------------------------------------------------------------
   333                          ; tmsUpdateFont: Update the pattern table with a given font
   334                          ; -----------------------------------------------------------------------------
   335                          !macro tmsUpdateFont .fontAddr {
   336                                  +tmsSetAddrPattTable 32
   337                                  +tmsSendData .fontAddr, $300
   338                          }
   339                          
   340                          ; -----------------------------------------------------------------------------
   341                          ; tmsSetAddrNameTable: Initialise address for base (text) table
   342                          ; -----------------------------------------------------------------------------
   343                          !macro tmsSetAddrNameTable {
   344                                  +tmsSetAddressWrite TMS_VRAM_NAME_ADDRESS
   345                          }
   346                          
   347                          ; -----------------------------------------------------------------------------
   348                          ; tmsSetAddrColorTable: Initialise address for color table
   349                          ; -----------------------------------------------------------------------------
   350                          !macro tmsSetAddrColorTable {
   351                                  +tmsSetAddressWrite TMS_VRAM_COLOR_ADDRESS
   352                          }
   353                          
   354                          ; -----------------------------------------------------------------------------
   355                          ; tmsSetAddrColorTable: Initialise address for color table index
   356                          ; -----------------------------------------------------------------------------
   357                          !macro tmsSetAddrColorTable .ind {
   358                                  +tmsSetAddressWrite TMS_VRAM_COLOR_ADDRESS + .ind
   359                          }
   360                          
   361                          ; -----------------------------------------------------------------------------
   362                          ; tmsSetAddrColorTableII: Initialise address for color table index (mode II)
   363                          ; -----------------------------------------------------------------------------
   364                          !macro tmsSetAddrColorTableII .ind {
   365                                  +tmsSetAddressWrite TMS_VRAM_COLOR_ADDRESS + .ind * 8
   366                          }
   367                          
   368                          ; -----------------------------------------------------------------------------
   369                          ; tmsSetAddrColorTableIIBank0: Initialise address for color table index (mode II)
   370                          ; -----------------------------------------------------------------------------
   371                          !macro tmsSetAddrColorTableIIBank0 .ind {
   372                                  +tmsSetAddrColorTableII .ind
   373                          }
   374                          
   375                          ; -----------------------------------------------------------------------------
   376                          ; tmsSetAddrColorTableIIBank1: Initialise address for color table index (mode II)
   377                          ; -----------------------------------------------------------------------------
   378                          !macro tmsSetAddrColorTableIIBank1 .ind {
   379                                  +tmsSetAddrColorTableII 256 + .ind
   380                          }
   381                          
   382                          ; -----------------------------------------------------------------------------
   383                          ; tmsSetAddrColorTableIIBank2: Initialise address for color table index (mode II)
   384                          ; -----------------------------------------------------------------------------
   385                          !macro tmsSetAddrColorTableIIBank2 .ind {
   386                                  +tmsSetAddrColorTableII 512 + .ind
   387                          }
   388                          
   389                          ; -----------------------------------------------------------------------------
   390                          ; tmsSetAddrSpriteAttrTable: Initialise address for sprite attributes table
   391                          ; -----------------------------------------------------------------------------
   392                          !macro tmsSetAddrSpriteAttrTable {
   393                                  +tmsSetAddrSpriteAttrTable 0
   394                          }
   395                          
   396                          ; -----------------------------------------------------------------------------
   397                          ; tmsSetAddrSpriteAttrTable: Initialise address for sprite attributes table
   398                          ; -----------------------------------------------------------------------------
   399                          !macro tmsSetAddrSpriteAttrTable .index {
   400                                  +tmsSetAddressWrite TMS_VRAM_SPRITE_ATTR_ADDRESS + .index * 4
   401                          }
   402                          
   403                          ; -----------------------------------------------------------------------------
   404                          ; tmsSetAddrSpritePattTable: Initialise address for sprite pattern table
   405                          ; -----------------------------------------------------------------------------
   406                          !macro tmsSetAddrSpritePattTable {
   407                                  +tmsSetAddrSpritePattTable 0
   408                          }
   409                          
   410                          ; -----------------------------------------------------------------------------
   411                          ; tmsSetAddrSpritePattTable: Initialise address for sprite pattern table
   412                          ; -----------------------------------------------------------------------------
   413                          !macro tmsSetAddrSpritePattTable .index {
   414                                  +tmsSetAddressWrite TMS_VRAM_SPRITE_PATT_ADDRESS + .index * 8
   415                          }
   416                          
   417                          
   418                          ; -----------------------------------------------------------------------------
   419                          ; tmsCreateSpritePattern: Create a sprite pattern (.spriteDataAddr is 8 bytes)
   420                          ; -----------------------------------------------------------------------------
   421                          !macro tmsCreateSpritePattern .pattInd, .spriteDataAddr {
   422                          
   423                                  
   424                          
   425                                  ; sprite pattern table
   426                                  +tmsSetAddrSpritePattTable .pattInd
   427                          
   428                                  ldx #0
   429                          -
   430                                  lda .spriteDataAddr,x
   431                                  +tmsPut
   432                                  inx
   433                                  cpx #8
   434                          
   435                                  
   436                          
   437                                  bne -
   438                          }
   439                          
   440                          ; -----------------------------------------------------------------------------
   441                          ; tmsCreateSpritePatternQuad: Create a (size 1) sprite pattern 
   442                          ;   (.spriteDataAddr is 32 bytes)
   443                          ; -----------------------------------------------------------------------------
   444                          !macro tmsCreateSpritePatternQuad .pattInd, .spriteDataAddr {
   445                          
   446                                  
   447                          
   448                                  ; sprite pattern table
   449                                  +tmsSetAddrSpritePattTable .pattInd * 4
   450                          
   451                                  ldx #0
   452                          -
   453                                  lda .spriteDataAddr,x
   454                                  +tmsPut 
   455                                  inx
   456                                  cpx #32
   457                          
   458                                  
   459                          
   460                                  bne -
   461                          }
   462                          
   463                          
   464                          !macro tmsCreateSpritePatternImm .ind, .b0, .b1, .b2, .b3, .b4, .b5, .b6, .b7 {
   465                          
   466                                  ; sprite pattern table
   467                                  +tmsSetAddrSpritePattTable .ind
   468                                  +tmsPut .b0
   469                                  +tmsPut .b2
   470                                  +tmsPut .b2
   471                                  +tmsPut .b3
   472                                  +tmsPut .b4
   473                                  +tmsPut .b5
   474                                  +tmsPut .b6
   475                                  +tmsPut .b7
   476                          }
   477                          
   478                          !macro tmsCreatePatternImm .ind, .b0, .b1, .b2, .b3, .b4, .b5, .b6, .b7 {
   479                          
   480                                  ; sprite pattern table
   481                                  +tmsSetAddrPattTable .ind
   482                                  +tmsPut .b0
   483                                  +tmsPut .b2
   484                                  +tmsPut .b2
   485                                  +tmsPut .b3
   486                                  +tmsPut .b4
   487                                  +tmsPut .b5
   488                                  +tmsPut .b6
   489                                  +tmsPut .b7
   490                          }
   491                          
   492                          
   493                          ; -----------------------------------------------------------------------------
   494                          ; tmsCreateSprite: Create a sprite
   495                          ; -----------------------------------------------------------------------------
   496                          !macro tmsCreateSprite .ind, .pattInd, .xPos, .yPos, .color {
   497                          
   498                                  ; sprite attr table
   499                                  +tmsSetAddrSpriteAttrTable .ind
   500                          
   501                                  +tmsPut .yPos
   502                                  +tmsPut .xPos
   503                                  +tmsPut .pattInd
   504                                  +tmsPut .color
   505                          }
   506                          
   507                          ; -----------------------------------------------------------------------------
   508                          ; tmsSpritePos: Set a sprite position
   509                          ; -----------------------------------------------------------------------------
   510                          !macro tmsSpritePos .ind, .xPos, .yPos {
   511                                  
   512                          
   513                                  ; sprite attr table
   514                                  +tmsSetAddrSpriteAttrTable .ind
   515                          
   516                                  +tmsPut .yPos
   517                                  +tmsPut .xPos        
   518                          }
   519                          
   520                          
   521                          ; -----------------------------------------------------------------------------
   522                          ; tmsSetLastSprite: Mark a sprite as the last sprite (set next ypos to )
   523                          ; -----------------------------------------------------------------------------
   524                          !macro tmsSetLastSprite .ind {
   525                                  +tmsSpritePos .ind + 1, 0, $d0
   526                          }
   527                          
   528                          
   529                          ; -----------------------------------------------------------------------------
   530                          ; tmsSpritePosXYReg: Set a sprite position from x/y registers
   531                          ; -----------------------------------------------------------------------------
   532                          !macro tmsSpritePosXYReg .ind {
   533                                  
   534                          
   535                                  ; sprite attr table
   536                                  +tmsSetAddrSpriteAttrTable .ind
   537                          
   538                                  tya
   539                                  +tmsPut 
   540                                  txa
   541                                  +tmsPut 
   542                          }
   543                          
   544                          
   545                          ; -----------------------------------------------------------------------------
   546                          ; tmsSetAddrSpriteColor: Change a sprite color
   547                          ; -----------------------------------------------------------------------------
   548                          !macro tmsSetAddrSpriteColor .ind {
   549                          
   550                                  ; sprite attr table
   551                                  +tmsSetAddressWrite TMS_VRAM_SPRITE_ATTR_ADDRESS + (.ind * 4) + 3
   552                          }
   553                          ; -----------------------------------------------------------------------------
   554                          ; tmsSpriteColor: Change a sprite color
   555                          ; -----------------------------------------------------------------------------
   556                          !macro tmsSpriteColor .ind, .color {
   557                          
   558                                  +tmsSetAddrSpriteColor .ind
   559                          
   560                                  +tmsPut .color
   561                          }
   562                          
   563                          
   564                          ; -----------------------------------------------------------------------------
   565                          ; tmsSetPosWrite: Set cursor position
   566                          ; -----------------------------------------------------------------------------
   567                          !macro tmsSetPosWrite .x, .y {
   568                                  +tmsSetAddressWrite (TMS_VRAM_NAME_ADDRESS + .y * 32 + .x)
   569                          }
   570                          
   571                          ; -----------------------------------------------------------------------------
   572                          ; tmsSetPosRead: Set read cursor position
   573                          ; -----------------------------------------------------------------------------
   574                          !macro tmsSetPosRead .x, .y {
   575                                  +tmsSetAddressRead (TMS_VRAM_NAME_ADDRESS + .y * 32 + .x)
   576                          }
   577                          
   578                          ; -----------------------------------------------------------------------------
   579                          ; tmsPrint: Print immediate text
   580                          ; -----------------------------------------------------------------------------
   581                          ; Inputs:
   582                          ;  str: String to print
   583                          ;  x: x position
   584                          ;  y: y position
   585                          ; -----------------------------------------------------------------------------
   586                          !macro tmsPrint .str, .x, .y {
   587                          	jmp .afterText
   588                          .textAddr
   589                          	!text .str,0
   590                          .afterText        
   591                          
   592                                  +tmsSetPosWrite .x, .y
   593                          
   594                                  lda #<.textAddr
   595                                  sta STR_ADDR_L
   596                                  lda #>.textAddr
   597                                  sta STR_ADDR_H
   598                                  jsr tmsPrint        
   599                          }
   600                          
   601                          
   602                          ; -----------------------------------------------------------------------------
   603                          ; tmsPrintCentre: Print centre-aligned immediate text
   604                          ; -----------------------------------------------------------------------------
   605                          ; Inputs:
   606                          ;  str: String to print
   607                          ;  y: y position
   608                          ; -----------------------------------------------------------------------------
   609                          !macro tmsPrintCentre .str, .y {
   610                          	jmp .afterText
   611                          .textAddr
   612                          	!text .str,0
   613                          .afterText        
   614                          
   615                                  +tmsSetPosWrite (32 - ((.afterText - 1) - .textAddr)) / 2, .y
   616                          
   617                                  lda #<.textAddr
   618                                  sta STR_ADDR_L
   619                                  lda #>.textAddr
   620                                  sta STR_ADDR_H
   621                                  jsr tmsPrint        
   622                          }
   623                          
   624                          
   625                          ; -----------------------------------------------------------------------------
   626                          ; tmsPrintZ: Print text
   627                          ; -----------------------------------------------------------------------------
   628                          ; Inputs:
   629                          ;  str: Address of zero-terminated string to print
   630                          ;  x: x position
   631                          ;  y: y position
   632                          ; -----------------------------------------------------------------------------
   633                          !macro tmsPrintZ .textAddr, .x, .y {
   634                                  +tmsSetPosWrite .x, .y
   635                          
   636                                  lda #<.textAddr
   637                                  sta STR_ADDR_L
   638                                  lda #>.textAddr
   639                                  sta STR_ADDR_H
   640                                  jsr tmsPrint        
   641                          }

; ******** Source: ../lib\gfx\tms9918.asm
    13                          
    14                          
    15                          TMS_FONT_DATA:

; ******** Source: ../lib\gfx\fonts\hbc56font.asm
     1                          ; 6502 - HBC-56 Font
     2                          ;
     3                          ; Copyright (c) 2021 Troy Schrapel
     4                          ;
     5                          ; This code is licensed under the MIT license
     6                          ;
     7                          ; https://github.com/visrealm/hbc-56
     8                          ;
     9                          
    10                          
    11                          
    12                          
    13                          
    14                          
    15                          
    16                          
    17                          
    18                          
    19                          
    20                          
    21                          
    22                          
    23                          
    24                          
    25                          
    26                          
    27                          
    28                          
    29                          
    30                          
    31                          
    32  e271 0000000000000000   !byte $00,$00,$00,$00,$00,$00,$00,$00 ; <SPACE>
    33  e279 1818181818001800   !byte $18,$18,$18,$18,$18,$00,$18,$00 ; !
    34  e281 6c6c6c0000000000   !byte $6C,$6C,$6C,$00,$00,$00,$00,$00 ; "
    35  e289 6c6cfe6cfe6c6c00   !byte $6C,$6C,$FE,$6C,$FE,$6C,$6C,$00 ; #
    36  e291 187ec07c06fc1800   !byte $18,$7E,$C0,$7C,$06,$FC,$18,$00 ; $
    37  e299 00c6cc183066c600   !byte $00,$C6,$CC,$18,$30,$66,$C6,$00 ; %
    38  e2a1 386c3876dccc7600   !byte $38,$6C,$38,$76,$DC,$CC,$76,$00 ; &
    39  e2a9 3030600000000000   !byte $30,$30,$60,$00,$00,$00,$00,$00 ; '
    40  e2b1 0c18303030180c00   !byte $0C,$18,$30,$30,$30,$18,$0C,$00 ; (
    41  e2b9 30180c0c0c183000   !byte $30,$18,$0C,$0C,$0C,$18,$30,$00 ; )
    42  e2c1 00663cff3c660000   !byte $00,$66,$3C,$FF,$3C,$66,$00,$00 ; *
    43  e2c9 0018187e18180000   !byte $00,$18,$18,$7E,$18,$18,$00,$00 ; +
    44  e2d1 0000000000181830   !byte $00,$00,$00,$00,$00,$18,$18,$30 ; ,
    45  e2d9 0000007e00000000   !byte $00,$00,$00,$7E,$00,$00,$00,$00 ; -
    46  e2e1 0000000000181800   !byte $00,$00,$00,$00,$00,$18,$18,$00 ; .
    47  e2e9 060c183060c08000   !byte $06,$0C,$18,$30,$60,$C0,$80,$00 ; /
    48  e2f1 7ccedef6e6c67c00   !byte $7C,$CE,$DE,$F6,$E6,$C6,$7C,$00 ; 0
    49  e2f9 1838181818187e00   !byte $18,$38,$18,$18,$18,$18,$7E,$00 ; 1
    50  e301 7cc6067cc0c0fe00   !byte $7C,$C6,$06,$7C,$C0,$C0,$FE,$00 ; 2
    51  e309 fc06063c0606fc00   !byte $FC,$06,$06,$3C,$06,$06,$FC,$00 ; 3
    52  e311 0cccccccfe0c0c00   !byte $0C,$CC,$CC,$CC,$FE,$0C,$0C,$00 ; 4
    53  e319 fec0fc0606c67c00   !byte $FE,$C0,$FC,$06,$06,$C6,$7C,$00 ; 5
    54  e321 7cc0c0fcc6c67c00   !byte $7C,$C0,$C0,$FC,$C6,$C6,$7C,$00 ; 6
    55  e329 fe06060c18303000   !byte $FE,$06,$06,$0C,$18,$30,$30,$00 ; 7
    56  e331 7cc6c67cc6c67c00   !byte $7C,$C6,$C6,$7C,$C6,$C6,$7C,$00 ; 8
    57  e339 7cc6c67e06067c00   !byte $7C,$C6,$C6,$7E,$06,$06,$7C,$00 ; 9
    58  e341 0018180000181800   !byte $00,$18,$18,$00,$00,$18,$18,$00 ; :
    59  e349 0018180000181830   !byte $00,$18,$18,$00,$00,$18,$18,$30 ; ;
    60  e351 0c18306030180c00   !byte $0C,$18,$30,$60,$30,$18,$0C,$00 ; <
    61  e359 00007e007e000000   !byte $00,$00,$7E,$00,$7E,$00,$00,$00 ; =
    62  e361 30180c060c183000   !byte $30,$18,$0C,$06,$0C,$18,$30,$00 ; >
    63  e369 3c660c1818001800   !byte $3C,$66,$0C,$18,$18,$00,$18,$00 ; ?
    64  e371 7cc6dededec07e00   !byte $7C,$C6,$DE,$DE,$DE,$C0,$7E,$00 ; @
    65  e379 386cc6c6fec6c600   !byte $38,$6C,$C6,$C6,$FE,$C6,$C6,$00 ; A
    66  e381 fcc6c6fcc6c6fc00   !byte $FC,$C6,$C6,$FC,$C6,$C6,$FC,$00 ; B
    67  e389 7cc6c0c0c0c67c00   !byte $7C,$C6,$C0,$C0,$C0,$C6,$7C,$00 ; C
    68  e391 f8ccc6c6c6ccf800   !byte $F8,$CC,$C6,$C6,$C6,$CC,$F8,$00 ; D
    69  e399 fec0c0f8c0c0fe00   !byte $FE,$C0,$C0,$F8,$C0,$C0,$FE,$00 ; E
    70  e3a1 fec0c0f8c0c0c000   !byte $FE,$C0,$C0,$F8,$C0,$C0,$C0,$00 ; F
    71  e3a9 7cc6c0c0cec67c00   !byte $7C,$C6,$C0,$C0,$CE,$C6,$7C,$00 ; G
    72  e3b1 c6c6c6fec6c6c600   !byte $C6,$C6,$C6,$FE,$C6,$C6,$C6,$00 ; H
    73  e3b9 7e18181818187e00   !byte $7E,$18,$18,$18,$18,$18,$7E,$00 ; I
    74  e3c1 0606060606c67c00   !byte $06,$06,$06,$06,$06,$C6,$7C,$00 ; J
    75  e3c9 c6ccd8f0d8ccc600   !byte $C6,$CC,$D8,$F0,$D8,$CC,$C6,$00 ; K
    76  e3d1 c0c0c0c0c0c0fe00   !byte $C0,$C0,$C0,$C0,$C0,$C0,$FE,$00 ; L
    77  e3d9 c6eefefed6c6c600   !byte $C6,$EE,$FE,$FE,$D6,$C6,$C6,$00 ; M
    78  e3e1 c6e6f6decec6c600   !byte $C6,$E6,$F6,$DE,$CE,$C6,$C6,$00 ; N
    79  e3e9 7cc6c6c6c6c67c00   !byte $7C,$C6,$C6,$C6,$C6,$C6,$7C,$00 ; O
    80  e3f1 fcc6c6fcc0c0c000   !byte $FC,$C6,$C6,$FC,$C0,$C0,$C0,$00 ; P
    81  e3f9 7cc6c6c6d6de7c06   !byte $7C,$C6,$C6,$C6,$D6,$DE,$7C,$06 ; Q
    82  e401 fcc6c6fcd8ccc600   !byte $FC,$C6,$C6,$FC,$D8,$CC,$C6,$00 ; R
    83  e409 7cc6c07c06c67c00   !byte $7C,$C6,$C0,$7C,$06,$C6,$7C,$00 ; S
    84  e411 ff18181818181800   !byte $FF,$18,$18,$18,$18,$18,$18,$00 ; T
    85  e419 c6c6c6c6c6c6fe00   !byte $C6,$C6,$C6,$C6,$C6,$C6,$FE,$00 ; U
    86  e421 c6c6c6c6c67c3800   !byte $C6,$C6,$C6,$C6,$C6,$7C,$38,$00 ; V
    87  e429 c6c6c6c6d6fe6c00   !byte $C6,$C6,$C6,$C6,$D6,$FE,$6C,$00 ; W
    88  e431 c6c66c386cc6c600   !byte $C6,$C6,$6C,$38,$6C,$C6,$C6,$00 ; X
    89  e439 c6c6c67c1830e000   !byte $C6,$C6,$C6,$7C,$18,$30,$E0,$00 ; Y
    90  e441 fe060c183060fe00   !byte $FE,$06,$0C,$18,$30,$60,$FE,$00 ; Z
    91  e449 3c30303030303c00   !byte $3C,$30,$30,$30,$30,$30,$3C,$00 ; [
    92  e451 c06030180c060200   !byte $C0,$60,$30,$18,$0C,$06,$02,$00 ; \
    93  e459 3c0c0c0c0c0c3c00   !byte $3C,$0C,$0C,$0C,$0C,$0C,$3C,$00 ; ]
    94  e461 10386cc600000000   !byte $10,$38,$6C,$C6,$00,$00,$00,$00 ; ^
    95  e469 00000000000000ff   !byte $00,$00,$00,$00,$00,$00,$00,$FF ; _
    96  e471 18180c0000000000   !byte $18,$18,$0C,$00,$00,$00,$00,$00 ; `
    97  e479 00007c067ec67e00   !byte $00,$00,$7C,$06,$7E,$C6,$7E,$00 ; a
    98  e481 c0c0c0fcc6c6fc00   !byte $C0,$C0,$C0,$FC,$C6,$C6,$FC,$00 ; b
    99  e489 00007cc6c0c67c00   !byte $00,$00,$7C,$C6,$C0,$C6,$7C,$00 ; c
   100  e491 0606067ec6c67e00   !byte $06,$06,$06,$7E,$C6,$C6,$7E,$00 ; d
   101  e499 00007cc6fec07c00   !byte $00,$00,$7C,$C6,$FE,$C0,$7C,$00 ; e
   102  e4a1 1c36307830307800   !byte $1C,$36,$30,$78,$30,$30,$78,$00 ; f
   103  e4a9 00007ec6c67e06fc   !byte $00,$00,$7E,$C6,$C6,$7E,$06,$FC ; g
   104  e4b1 c0c0fcc6c6c6c600   !byte $C0,$C0,$FC,$C6,$C6,$C6,$C6,$00 ; h
   105  e4b9 1800381818183c00   !byte $18,$00,$38,$18,$18,$18,$3C,$00 ; i
   106  e4c1 060006060606c67c   !byte $06,$00,$06,$06,$06,$06,$C6,$7C ; j
   107  e4c9 c0c0ccd8f8ccc600   !byte $C0,$C0,$CC,$D8,$F8,$CC,$C6,$00 ; k
   108  e4d1 3818181818183c00   !byte $38,$18,$18,$18,$18,$18,$3C,$00 ; l
   109  e4d9 0000ccfefed6d600   !byte $00,$00,$CC,$FE,$FE,$D6,$D6,$00 ; m
   110  e4e1 0000fcc6c6c6c600   !byte $00,$00,$FC,$C6,$C6,$C6,$C6,$00 ; n
   111  e4e9 00007cc6c6c67c00   !byte $00,$00,$7C,$C6,$C6,$C6,$7C,$00 ; o
   112  e4f1 0000fcc6c6fcc0c0   !byte $00,$00,$FC,$C6,$C6,$FC,$C0,$C0 ; p
   113  e4f9 00007ec6c67e0606   !byte $00,$00,$7E,$C6,$C6,$7E,$06,$06 ; q
   114  e501 0000fcc6c0c0c000   !byte $00,$00,$FC,$C6,$C0,$C0,$C0,$00 ; r
   115  e509 00007ec07c06fc00   !byte $00,$00,$7E,$C0,$7C,$06,$FC,$00 ; s
   116  e511 18187e1818180e00   !byte $18,$18,$7E,$18,$18,$18,$0E,$00 ; t
   117  e519 0000c6c6c6c67e00   !byte $00,$00,$C6,$C6,$C6,$C6,$7E,$00 ; u
   118  e521 0000c6c6c67c3800   !byte $00,$00,$C6,$C6,$C6,$7C,$38,$00 ; v
   119  e529 0000c6c6d6fe6c00   !byte $00,$00,$C6,$C6,$D6,$FE,$6C,$00 ; w
   120  e531 0000c66c386cc600   !byte $00,$00,$C6,$6C,$38,$6C,$C6,$00 ; x
   121  e539 0000c6c6c67e06fc   !byte $00,$00,$C6,$C6,$C6,$7E,$06,$FC ; y
   122  e541 0000fe0c3860fe00   !byte $00,$00,$FE,$0C,$38,$60,$FE,$00 ; z
   123  e549 0e18187018180e00   !byte $0E,$18,$18,$70,$18,$18,$0E,$00 ; {
   124  e551 1818180018181800   !byte $18,$18,$18,$00,$18,$18,$18,$00 ; |
   125  e559 7018180e18187000   !byte $70,$18,$18,$0E,$18,$18,$70,$00 ; }
   126  e561 76dc000000000000   !byte $76,$DC,$00,$00,$00,$00,$00,$00 ; ~

; ******** Source: ../lib\gfx\tms9918.asm
    16  e569 ffffffffffffffff   
    17                          
    18                          HAVE_TMS9918 = 1
    19                          
    20                          ; -------------------------
    21                          ; Constants
    22                          ; -------------------------
    23                          !ifndef TMS9918_IO_PORT { TMS9918_IO_PORT = $10
    24                                  !warn "TMS9918_IO_PORT not provided. Defaulting to ", TMS9918_IO_PORT
    25                          }
    26                          
    27                          !ifndef TMS9918_ZP_START { TMS9918_ZP_START = $30
    28                                  !warn "TMS9918_ZP_START not provided. Defaulting to ", TMS9918_ZP_START
    29                          }
    30                          
    31                          !ifndef TMS9918_RAM_START { TMS9918_RAM_START = $7ba0
    32                                  !warn "TMS9918_RAM_START not provided. Defaulting to ", TMS9918_RAM_START
    33                          }
    34                          
    35                          ; -----------------------------------------------------------------------------
    36                          ; Zero page
    37                          ; -----------------------------------------------------------------------------
    38                          TMS_TMP_ADDRESS         = TMS9918_ZP_START      ; 2 bytes
    39                          TMS9918_ZP_SIZE         = 2                     ; LAST ZP ADDRESS
    40                          
    41                          ; -----------------------------------------------------------------------------
    42                          ; High RAM
    43                          ; -----------------------------------------------------------------------------
    44                          .TMS9918_REG0_SHADOW_ADDR = TMS9918_RAM_START
    45                          .TMS9918_REG1_SHADOW_ADDR = TMS9918_RAM_START + 1
    46                          
    47                          TMS9918_CONSOLE_X         = TMS9918_RAM_START + 2
    48                          TMS9918_CONSOLE_Y         = TMS9918_RAM_START + 3
    49                          TMS9918_CONSOLE_SIZE_X    = TMS9918_RAM_START + 4
    50                          TMS9918_CONSOLE_LINE_LEN  = TMS9918_RAM_START + 5
    51                          .TMS9918_REGX             = TMS9918_RAM_START + 6
    52                          .TMS9918_REGY             = TMS9918_RAM_START + 7
    53                          .TMS9918_TMP_READ_ROW     = TMS9918_RAM_START + 8
    54                          .TMS9918_TMP_WRITE_ROW    = TMS9918_RAM_START + 9
    55                          
    56                          TMS9918_TMP_BUFFER        = TMS9918_RAM_START + 10 ; 40 bytes 
    57                          TMS9918_RAM_SIZE          = 50
    58                          
    59                          
    60                          
    61                          !if TMS9918_ZP_END < (TMS9918_ZP_START + TMS9918_ZP_SIZE) {
    62                          	!error "TMS9918_ZP requires ",TMS9918_ZP_SIZE," bytes. Allocated ",TMS9918_ZP_END - TMS9918_ZP_START
    63                          }
    64                          
    65                          !if TMS9918_RAM_END < (TMS9918_RAM_START + TMS9918_RAM_SIZE) {
    66                          	!error "TMS9918_RAM requires ",.TMS9918_RAM_SIZE," bytes. Allocated ",TMS9918_RAM_END - TMS9918_RAM_START
    67                          }
    68                          
    69                          
    70                          ; IO Ports
    71                          TMS9918_RAM     = IO_PORT_BASE_ADDRESS | TMS9918_IO_PORT
    72                          TMS9918_REG     = IO_PORT_BASE_ADDRESS | TMS9918_IO_PORT | $01
    73                          
    74                          
    75                          ; -----------------------------------------------------------------------------
    76                          ; VRAM addresses
    77                          ; -----------------------------------------------------------------------------
    78                          TMS_VRAM_NAME_ADDRESS           = $3800
    79                          TMS_VRAM_COLOR_ADDRESS          = $0000
    80                          TMS_VRAM_PATT_ADDRESS           = $2000
    81                          TMS_VRAM_SPRITE_ATTR_ADDRESS    = $3B00
    82                          TMS_VRAM_SPRITE_PATT_ADDRESS    = $1800
    83                          
    84                          ; -----------------------------------------------------------------------------
    85                          ; Register values
    86                          ; -----------------------------------------------------------------------------
    87                          TMS_R0_MODE_GRAPHICS_I          = $00
    88                          TMS_R0_MODE_GRAPHICS_II         = $02
    89                          TMS_R0_MODE_MULTICOLOR          = $00
    90                          TMS_R0_MODE_TEXT                = $00
    91                          TMS_R0_EXT_VDP_ENABLE           = $01
    92                          TMS_R0_EXT_VDP_DISABLE          = $00
    93                          
    94                          TMS_R1_RAM_16K                  = $80
    95                          TMS_R1_RAM_4K                   = $00
    96                          TMS_R1_DISP_BLANK               = $00
    97                          TMS_R1_DISP_ACTIVE              = $40
    98                          TMS_R1_INT_ENABLE               = $20
    99                          TMS_R1_INT_DISABLE              = $00
   100                          TMS_R1_MODE_GRAPHICS_I          = $00
   101                          TMS_R1_MODE_GRAPHICS_II         = $00
   102                          TMS_R1_MODE_MULTICOLOR          = $08
   103                          TMS_R1_MODE_TEXT                = $10
   104                          TMS_R1_SPRITE_8                 = $00
   105                          TMS_R1_SPRITE_16                = $02
   106                          TMS_R1_SPRITE_MAG1              = $00
   107                          TMS_R1_SPRITE_MAG2              = $01
   108                          
   109                          ; -----------------------------------------------------------------------------
   110                          ; Color palette
   111                          ; -----------------------------------------------------------------------------
   112                          TMS_TRANSPARENT         = $00
   113                          TMS_BLACK               = $01
   114                          TMS_MED_GREEN           = $02
   115                          TMS_LT_GREEN            = $03
   116                          TMS_DK_BLUE             = $04
   117                          TMS_LT_BLUE             = $05
   118                          TMS_DK_RED              = $06
   119                          TMS_CYAN                = $07
   120                          TMS_MED_RED             = $08
   121                          TMS_LT_RED              = $09
   122                          TMS_DK_YELLOW           = $0a
   123                          TMS_LT_YELLOW           = $0b
   124                          TMS_DK_GREEN            = $0c
   125                          TMS_MAGENTA             = $0d
   126                          TMS_GREY                = $0e
   127                          TMS_WHITE               = $0f
   128                          
   129                          TMS_GFX_TILE_WIDTH      = 8
   130                          TMS_GFX_TILE_HEIGHT     = 8
   131                          TMS_GFX_TILES_X         = 32
   132                          TMS_GFX_TILES_Y         = 24
   133                          TMS_GFX_PIXELS_X        = TMS_GFX_TILES_X * TMS_GFX_TILE_WIDTH
   134                          TMS_GFX_PIXELS_Y        = TMS_GFX_TILES_Y * TMS_GFX_TILE_HEIGHT
   135                          
   136                          TMS_TXT_TILE_WIDTH      = 6
   137                          TMS_TXT_TILE_HEIGHT     = 8
   138                          TMS_TXT_TILES_X         = 40
   139                          TMS_TXT_TILES_Y         = 24
   140                          TMS_TXT_PIXELS_X        = TMS_TXT_TILES_X * TMS_TXT_TILE_WIDTH
   141                          TMS_TXT_PIXELS_Y        = TMS_TXT_TILES_Y * TMS_TXT_TILE_HEIGHT
   142                          
   143                          TMS_SPRITE_SIZE         = 8
   144                          TMS_SPRITE_SIZE2X       = TMS_SPRITE_SIZE * 2
   145                          
   146                          !ifndef TMS_MODEL {
   147                          	!warn "Set TMS_MODEL to one of: 9918, 9929. Defaulting to 9918"
   148                          	TMS_MODEL = 9918
   149                          } 
   150                          
   151                          ; -------------------------
   152                          ; Constants
   153                          ; -------------------------
   154                          
   155                          !if TMS_MODEL = 9918 {
   156                          	TMS_FPS = 60
   157                          } else { !if TMS_MODEL = 9929 {
   158                          	TMS_FPS = 50
   159                          } else {
   160                          	!error "Unknown TMS_MODEL. Must be one of: 9918 or 9929"
   161                          }}
   162                          
   163                          ; -----------------------------------------------------------------------------
   164                          ; Default register values
   165                          ; -----------------------------------------------------------------------------
   166                          TMS_REGISTER_DATA:
   167  e571 00                 !byte TMS_R0_EXT_VDP_DISABLE
   168  e572 80                 !byte TMS_R1_RAM_16K
   169  e573 0e                 !byte TMS_VRAM_NAME_ADDRESS >> 10
   170  e574 00                 !byte TMS_VRAM_COLOR_ADDRESS >> 6
   171  e575 04                 !byte TMS_VRAM_PATT_ADDRESS >> 11
   172  e576 76                 !byte TMS_VRAM_SPRITE_ATTR_ADDRESS >> 7
   173  e577 03                 !byte TMS_VRAM_SPRITE_PATT_ADDRESS >> 11
   174  e578 11                 !byte TMS_BLACK << 4 | TMS_BLACK
   175                          
   176                          
   177                          ; -----------------------------------------------------------------------------
   178                          ; Delay subroutines required for TMS9918 CPU access windows
   179                          ; -----------------------------------------------------------------------------
   180                          ;      CONDITION          MODE    VDP DELAY       WAIT TIME          TOTAL TIME
   181                          ; -----------------------------------------------------------------------------
   182                          ;  Active Display Area   Text        2uS          0 - 1.1uS           2 - 3.1uS      
   183                          ;  Active Display Area   GFX I, II   2uS          0 - 5.95uS          2 - 8uS      
   184                          ;  4300uS after VSYNC    All         2uS             0uS                2uS      
   185                          ;  Reg 1 Blank Bit 0     All         2uS             0uS                2uS      
   186                          ;  Active Display Area   Multicolor  2uS          0 - 1.5uS           2 - 3.5uS      
   187                          ; -----------------------------------------------------------------------------
   188                          _tmsWaitData:
   189  e579 ea                         nop
   190  e57a ea                         nop
   191  e57b ea                         nop
   192  e57c ea                         nop
   193  e57d ea                         nop
   194  e57e ea                         nop
   195  e57f ea                         nop
   196  e580 ea                         nop
   197  e581 ea                         nop
   198                          _tmsWaitReg:
   199  e582 ea                         nop
   200  e583 ea                         nop
   201  e584 ea                         nop
   202  e585 60                         rts
   203                          
   204                          tmsSetAddressNextRow:
   205  e586 a524                       lda TMS_TMP_ADDRESS
   206  e588 18                         clc
   207  e589 6920                       adc #32
   208  e58b 8524                       sta TMS_TMP_ADDRESS
   209  e58d 9002                       bcc +
   210  e58f e625                       inc TMS_TMP_ADDRESS + 1
   211                          +
   212  e591 60                         rts
   213                          
   214                          ; -----------------------------------------------------------------------------
   215                          ; tmsSetAddressWrite: Set an address in the TMS9918 
   216                          ; -----------------------------------------------------------------------------
   217                          ; TMS_TMP_ADDRESS: Address to set
   218                          ; -----------------------------------------------------------------------------
   219                          tmsSetAddressWrite:
   220  e592 08                         php
   221  e593 78                         sei                     ; we can't be interrupted here
   222  e594 a524                       lda TMS_TMP_ADDRESS
   223  e596 8d117f                     sta TMS9918_REG
   224  e599 2082e5                     +tmsWaitReg
   225  e59c a525                       lda TMS_TMP_ADDRESS + 1
   226  e59e 0940                       ora #$40
   227  e5a0 8d117f                     sta TMS9918_REG
   228  e5a3 2082e5                     +tmsWaitReg
   229  e5a6 28                         plp
   230  e5a7 60                         rts
   231                          
   232                          ; -----------------------------------------------------------------------------
   233                          ; tmsSetAddressRead: Set an address to read from the TMS9918 
   234                          ; -----------------------------------------------------------------------------
   235                          ; TMS_TMP_ADDRESS: Address to read
   236                          ; -----------------------------------------------------------------------------
   237                          tmsSetAddressRead:
   238  e5a8 08                         php
   239  e5a9 78                         sei                     ; we can't be interrupted here
   240  e5aa a524                       lda TMS_TMP_ADDRESS
   241  e5ac 8d117f                     sta TMS9918_REG
   242  e5af 2082e5                     +tmsWaitReg
   243  e5b2 a525                       lda TMS_TMP_ADDRESS + 1
   244  e5b4 8d117f                     sta TMS9918_REG
   245  e5b7 2082e5                     +tmsWaitReg
   246  e5ba 28                         plp
   247  e5bb 60                         rts
   248                          
   249                          
   250                          ; -----------------------------------------------------------------------------
   251                          ; tmsSetRegister: Set a register value
   252                          ; -----------------------------------------------------------------------------
   253                          ; Inputs:
   254                          ;  A: The value to set
   255                          ;  X: The register (0 - 7)
   256                          ; -----------------------------------------------------------------------------
   257                          tmsSetRegister:
   258  e5bc 08                         php
   259  e5bd 78                         sei             ; we can't be interrupted here
   260  e5be 8d117f                     sta TMS9918_REG
   261  e5c1 2082e5                     +tmsWaitReg
   262  e5c4 8a                         txa
   263  e5c5 0980                       ora #$80
   264  e5c7 8d117f                     sta TMS9918_REG
   265  e5ca 2082e5                     +tmsWaitReg
   266  e5cd 28                         plp
   267  e5ce 60                         rts
   268                          
   269                          ; -----------------------------------------------------------------------------
   270                          ; tmsSetBackground: Set the background color (R7)
   271                          ; -----------------------------------------------------------------------------
   272                          ; Outputs:
   273                          ;  A: Color. High nibble = FG. Low nibble = BG
   274                          ; -----------------------------------------------------------------------------
   275                          tmsSetBackground:
   276  e5cf a207                       ldx #7
   277  e5d1 d0e9                       bne tmsSetRegister
   278                          
   279                          ; -----------------------------------------------------------------------------
   280                          ; tmsReg0Set: Set register 0
   281                          ; -----------------------------------------------------------------------------
   282                          ; Outputs:
   283                          ;  A: Field values to set (will be OR'd with existing Reg0)
   284                          ; -----------------------------------------------------------------------------
   285                          tmsReg0SetFields:
   286  e5d3 0d267b                     ora .TMS9918_REG0_SHADOW_ADDR
   287                          .tmsReg0SetFields:
   288  e5d6 8d267b                     sta .TMS9918_REG0_SHADOW_ADDR
   289  e5d9 a200                       ldx #0
   290  e5db f0df                       beq tmsSetRegister
   291                                  
   292                          ; -----------------------------------------------------------------------------
   293                          ; tmsReg0Clear: Clear register 0 
   294                          ; -----------------------------------------------------------------------------
   295                          ; Outputs:
   296                          ;  A: Field values to cleared (will be XOR'd with existing Reg0)
   297                          ; -----------------------------------------------------------------------------
   298                          tmsReg0ClearFields:
   299  e5dd 49ff                       eor #$ff
   300  e5df 2d267b                     and .TMS9918_REG0_SHADOW_ADDR
   301  e5e2 4cd6e5                     jmp .tmsReg0SetFields
   302                          
   303                          
   304                          ; -----------------------------------------------------------------------------
   305                          ; tmsReg1Set: Set register 0
   306                          ; -----------------------------------------------------------------------------
   307                          ; Outputs:
   308                          ;  A: Field values to set (will be OR'd with existing Reg1)
   309                          ; -----------------------------------------------------------------------------
   310                          tmsReg1SetFields:
   311  e5e5 0d277b                     ora .TMS9918_REG1_SHADOW_ADDR
   312                          .tmsReg1SetFields:
   313  e5e8 8d277b                     sta .TMS9918_REG1_SHADOW_ADDR
   314  e5eb a201                       ldx #1
   315  e5ed d0cd                       bne tmsSetRegister
   316                                  
   317                          ; -----------------------------------------------------------------------------
   318                          ; tmsReg1Clear: Clear register 1
   319                          ; -----------------------------------------------------------------------------
   320                          ; Outputs:
   321                          ;  A: Field values to cleared (will be XOR'd with existing Reg1)
   322                          ; -----------------------------------------------------------------------------
   323                          tmsReg1ClearFields:
   324  e5ef 49ff                       eor #$ff
   325  e5f1 2d277b                     and .TMS9918_REG1_SHADOW_ADDR
   326  e5f4 4ce8e5                     jmp .tmsReg1SetFields
   327                          
   328                          
   329                          ; -----------------------------------------------------------------------------
   330                          ; tmsModeReset: Reset graphics Mode
   331                          ; -----------------------------------------------------------------------------
   332                          tmsModeReset:
   333  e5f7 a903                       lda #$03
   334  e5f9 20dde5                     jsr tmsReg0ClearFields
   335                          
   336  e5fc a918                       lda #$18
   337  e5fe 20efe5                     jsr tmsReg1ClearFields
   338                          
   339                                  ; if we were in Graphics II, then we need to reset
   340                                  ; the color and pattern table addresses
   341  e601 a900                       lda #<(TMS_VRAM_COLOR_ADDRESS >> 6)
   342  e603 a203                       ldx #3
   343  e605 20bce5                     jsr tmsSetRegister
   344                          
   345  e608 a904                       lda #<(TMS_VRAM_PATT_ADDRESS >> 11)
   346  e60a a204                       ldx #4
   347  e60c 20bce5                     jsr tmsSetRegister
   348  e60f 60                         rts
   349                          
   350                          ; -----------------------------------------------------------------------------
   351                          ; tmsModeGraphicsI: Set up for Graphics I mode
   352                          ; -----------------------------------------------------------------------------
   353                          tmsModeGraphicsI:
   354  e610 20f7e5                     jsr tmsModeReset
   355                          
   356  e613 a900                       lda #TMS_R0_MODE_GRAPHICS_I
   357  e615 20d3e5                     jsr tmsReg0SetFields
   358                          
   359  e618 a900                       lda #TMS_R1_MODE_GRAPHICS_I
   360  e61a 20e5e5                     jsr tmsReg1SetFields
   361                          
   362  e61d a920                       lda #32
   363  e61f 8d2a7b                     sta TMS9918_CONSOLE_SIZE_X
   364  e622 60                         rts
   365                          
   366                          ; -----------------------------------------------------------------------------
   367                          ; tmsModeBitmap: Set up for Graphics II mode and set up name table for bitmap
   368                          ; -----------------------------------------------------------------------------
   369                          tmsModeBitmap:
   370  e623 08                         php
   371  e624 78                         sei
   372                                          ; clear the name table
   373  e625 0878a9008d117f20...        +tmsSetAddrNameTable
   374  e638 a003                       ldy #3
   375  e63a a900                       lda #0
   376                          -
   377  e63c 8d107f2079e5               +tmsPut
   378  e642 1a                         inc
   379  e643 d0f7                       bne -
   380  e645 88                         dey
   381  e646 d0f4                       bne -
   382                          
   383                                  ; set all color table entries to transparent
   384  e648 0878a9008d117f20...        +tmsSetAddrColorTable
   385  e65b a9f1                       +tmsColorFgBg TMS_WHITE, TMS_BLACK
   386  e65d 201be7                     jsr _tmsSendKb
   387  e660 201be7                     jsr _tmsSendKb
   388  e663 201be7                     jsr _tmsSendKb
   389  e666 201be7                     jsr _tmsSendKb
   390  e669 201be7                     jsr _tmsSendKb
   391  e66c 201be7                     jsr _tmsSendKb        
   392                          
   393                                  ; clear the pattern table
   394  e66f 0878a9008d117f20...        +tmsSetAddrPattTable
   395  e682 a900                       lda #0
   396  e684 201be7                     jsr _tmsSendKb
   397  e687 201be7                     jsr _tmsSendKb
   398  e68a 201be7                     jsr _tmsSendKb
   399  e68d 201be7                     jsr _tmsSendKb
   400  e690 201be7                     jsr _tmsSendKb
   401  e693 201be7                     jsr _tmsSendKb
   402                          
   403  e696 28                         plp
   404                                  
   405                                  ; flow on through
   406                          
   407                          ; -----------------------------------------------------------------------------
   408                          ; tmsModeGraphicsII: Set up for Graphics II mode
   409                          ; -----------------------------------------------------------------------------
   410                          tmsModeGraphicsII:
   411  e697 20f7e5                     jsr tmsModeReset
   412                          
   413  e69a a902                       lda #TMS_R0_MODE_GRAPHICS_II
   414  e69c 20d3e5                     jsr tmsReg0SetFields
   415                          
   416  e69f a900                       lda #TMS_R1_MODE_GRAPHICS_II
   417  e6a1 20e5e5                     jsr tmsReg1SetFields
   418                          
   419                                  ; in Graphics II, Registers 3 and 4 work differently
   420                                  ;
   421                                  ; reg3 - Color table
   422                                  ;   $7f = $0000
   423                                  ;   $ff = $2000
   424                                  ;
   425                                  ; reg4 - Pattern table
   426                                  ;  $03 = $0000
   427                                  ;  $07 = $2000
   428                          
   429                                  ; set color table to $0000
   430  e6a4 a97f                       lda #$7f
   431  e6a6 a203                       ldx #3
   432  e6a8 20bce5                     jsr tmsSetRegister
   433                          
   434                                  ; set pattern table to $2000
   435  e6ab a907                       lda #$07
   436  e6ad a204                       ldx #4
   437  e6af 20bce5                     jsr tmsSetRegister
   438                          
   439  e6b2 a920                       lda #32
   440  e6b4 8d2a7b                     sta TMS9918_CONSOLE_SIZE_X
   441                          
   442  e6b7 60                         rts
   443                          
   444                          ; -----------------------------------------------------------------------------
   445                          ; tmsModeText: Set up for Text mode
   446                          ; -----------------------------------------------------------------------------
   447                          tmsModeText:
   448  e6b8 20f7e5                     jsr tmsModeReset
   449                          
   450  e6bb a900                       lda #TMS_R0_MODE_TEXT
   451  e6bd 20d3e5                     jsr tmsReg0SetFields
   452                          
   453  e6c0 a910                       lda #TMS_R1_MODE_TEXT
   454  e6c2 20e5e5                     jsr tmsReg1SetFields
   455                          
   456  e6c5 a928                       lda #40
   457  e6c7 8d2a7b                     sta TMS9918_CONSOLE_SIZE_X
   458                          
   459  e6ca 60                         rts
   460                          
   461                          ; -----------------------------------------------------------------------------
   462                          ; tmsModeMulticolor: Set up for Multicolor mode
   463                          ; -----------------------------------------------------------------------------
   464                          tmsModeMulticolor:
   465  e6cb 20f7e5                     jsr tmsModeReset
   466                          
   467  e6ce a900                       lda #TMS_R0_MODE_MULTICOLOR
   468  e6d0 20d3e5                     jsr tmsReg0SetFields
   469                          
   470  e6d3 a908                       lda #TMS_R1_MODE_MULTICOLOR
   471  e6d5 20e5e5                     jsr tmsReg1SetFields
   472  e6d8 60                         rts
   473                          
   474                          ; -----------------------------------------------------------------------------
   475                          ; tmsInit: Initialise the registers
   476                          ; -----------------------------------------------------------------------------
   477                          tmsInit:
   478  e6d9 08                         php
   479  e6da 78                         sei                             ; we can't be interrupted here
   480  e6db ad71e5                     lda TMS_REGISTER_DATA
   481  e6de 8d267b                     sta .TMS9918_REG0_SHADOW_ADDR
   482  e6e1 ad72e5                     lda TMS_REGISTER_DATA + 1
   483  e6e4 8d277b                     sta .TMS9918_REG1_SHADOW_ADDR
   484                          
   485  e6e7 a900                       lda #0
   486  e6e9 8d287b                     sta TMS9918_CONSOLE_X
   487  e6ec 8d297b                     sta TMS9918_CONSOLE_Y
   488                          
   489                                  ; set up the registers
   490  e6ef a200                       ldx #0
   491                          
   492                          @regLoop
   493  e6f1 bd71e5                             lda TMS_REGISTER_DATA, x
   494  e6f4 8d117f                             sta TMS9918_REG
   495  e6f7 2082e5                             +tmsWaitReg
   496  e6fa 8a                                 txa
   497  e6fb 0980                               ora #$80
   498  e6fd 8d117f                             sta TMS9918_REG
   499  e700 2082e5                             +tmsWaitReg
   500  e703 e8                                 inx
   501  e704 e008                               cpx #8
   502  e706 d0e9                               bne @regLoop
   503                                  
   504  e708 2010e6                     jsr tmsModeGraphicsI
   505                          
   506                                  ; load all data into VRAM
   507  e70b 206de7                     jsr tmsInitPattTable
   508                          
   509  e70e 20ade7                     jsr tmsInitTextTable
   510                                  
   511  e711 a917                       +tmsColorFgBg TMS_BLACK, TMS_CYAN
   512  e713 20d1e7                     jsr tmsInitEntireColorTable
   513                          
   514  e716 20f2e7                     jsr tmsInitSpriteTable
   515                          
   516  e719 28                         plp
   517                                  
   518  e71a 60                         rts
   519                          
   520                          ; -----------------------------------------------------------------------------
   521                          ; _tmsSendPage: Send A for a kilobyte
   522                          ; -----------------------------------------------------------------------------
   523                          _tmsSendKb
   524  e71b 2024e7                     jsr _tmsSendPage
   525  e71e 2024e7                     jsr _tmsSendPage
   526  e721 2024e7                     jsr _tmsSendPage
   527                                  ; flow through
   528                                  
   529                          ; -----------------------------------------------------------------------------
   530                          ; _tmsSendPage: Send A for a whole page
   531                          ; -----------------------------------------------------------------------------
   532                          _tmsSendPage:
   533  e724 a220                       ldx #32
   534                          _tmsSendX8:
   535  e726 8d107f2079e5               +tmsPut
   536  e72c 8d107f2079e5               +tmsPut
   537  e732 8d107f2079e5               +tmsPut
   538  e738 8d107f2079e5               +tmsPut
   539  e73e 8d107f2079e5               +tmsPut
   540  e744 8d107f2079e5               +tmsPut
   541  e74a 8d107f2079e5               +tmsPut
   542  e750 8d107f2079e5               +tmsPut
   543  e756 ca                         dex
   544  e757 d0cd                       bne _tmsSendX8
   545  e759 60                         rts
   546                          
   547                          ; -----------------------------------------------------------------------------
   548                          ; _tmsSendEmptyPage: Send an empty page of data
   549                          ; -----------------------------------------------------------------------------
   550                          _tmsSendEmptyPage:
   551  e75a a900                       lda #0
   552  e75c f0c6                       beq _tmsSendPage ; rts in here
   553                          
   554                          ; -----------------------------------------------------------------------------
   555                          ; tmsSendBytes: Send bytes to the TMS (up to 1 page)
   556                          ; -----------------------------------------------------------------------------
   557                          ; Inputs:
   558                          ;   TMS_TMP_ADDRESS:    Holds source address
   559                          ;   X:                  Number of bytes (1 to 256)
   560                          ; -----------------------------------------------------------------------------
   561                          tmsSendBytes:
   562  e75e a000                       ldy #0
   563                          -
   564  e760 b124                       lda (TMS_TMP_ADDRESS), Y
   565  e762 8d107f2079e5               +tmsPut
   566  e768 c8                         iny
   567  e769 ca                         dex
   568  e76a d0f4                       bne -
   569  e76c 60                         rts
   570                          
   571                          ; -----------------------------------------------------------------------------
   572                          ; tmsInitPattTable: Initialise the pattern table
   573                          ; -----------------------------------------------------------------------------
   574                          tmsInitPattTable:
   575                                  
   576                          
   577                                  ; pattern table
   578  e76d 0878a9008d117f20...        +tmsSetAddrPattTable
   579                          
   580                                  ; (0 - 31) all empty
   581  e780 205ae7                     jsr _tmsSendEmptyPage
   582                          
   583  e783 a9718524a9e28525...        +tmsSendData TMS_FONT_DATA, $300
   584                          
   585                                  ; (128 - 159) all empty
   586  e7a0 205ae7                     jsr _tmsSendEmptyPage
   587                          
   588                                  ; (160 - 191) all empty
   589  e7a3 205ae7                     jsr _tmsSendEmptyPage
   590                          
   591                                  ; (192 - 223) all empty
   592  e7a6 205ae7                     jsr _tmsSendEmptyPage
   593                          
   594                                  ; (224 - 255) all empty
   595  e7a9 205ae7                     jsr _tmsSendEmptyPage
   596                          
   597                                  
   598                          
   599  e7ac 60                         rts
   600                          
   601                          ; -----------------------------------------------------------------------------
   602                          ; tmsInitTextTable: Initialise the text (tilemap) table
   603                          ; -----------------------------------------------------------------------------
   604                          tmsInitTextTable:
   605                                  
   606                          
   607                                  ; text table table
   608  e7ad 0878a9008d117f20...        +tmsSetAddrNameTable
   609                          
   610                          
   611  e7c0 18                         clc
   612  e7c1 ad2a7b                     lda TMS9918_CONSOLE_SIZE_X
   613  e7c4 6d2a7b                     adc TMS9918_CONSOLE_SIZE_X
   614  e7c7 6d2a7b                     adc TMS9918_CONSOLE_SIZE_X
   615  e7ca aa                         tax
   616  e7cb a900                       lda #0
   617  e7cd 2026e7                     jsr _tmsSendX8
   618                          
   619  e7d0 60                         rts
   620                          
   621                          
   622                          ; -----------------------------------------------------------------------------
   623                          ; tmsInitEntireColorTable: Initialise the full color table
   624                          ; -----------------------------------------------------------------------------
   625                          ; Inputs:
   626                          ;   A: Color (fg/bg) to initialise
   627                          
   628                          tmsInitEntireColorTable:
   629  e7d1 a220                       ldx #32
   630                          
   631                          ; tmsInitColorTable: Initialise the color table
   632                          
   633                          ; Inputs:
   634                          ;   A: Color (fg/bg) to initialise
   635                          ;   X: Number of elements to initialise (1 to 32)
   636                          ; -----------------------------------------------------------------------------
   637                          tmsInitColorTable:
   638                                  
   639  e7d3 48                         pha
   640                          
   641                                  ; color table
   642  e7d4 0878a9008d117f20...        +tmsSetAddrColorTable
   643                          
   644  e7e7 68                         pla
   645                          -
   646  e7e8 8d107f2079e5               +tmsPut
   647  e7ee ca                         dex
   648  e7ef d0f7                       bne -
   649                          
   650  e7f1 60                         rts
   651                          
   652                          ; -----------------------------------------------------------------------------
   653                          ; tmsInitSpriteTable: Initialise the sprite table
   654                          ; -----------------------------------------------------------------------------
   655                          tmsInitSpriteTable:
   656                                  
   657                          
   658                                  ; sprites table
   659  e7f2 0878a9008d117f20...        +tmsSetAddrSpriteAttrTable
   660                          
   661  e805 a220                       ldx #32
   662                          -
   663                                  ; Vertical position
   664  e807 a9d08d107f2079e5           +tmsPut $D0        ; 208 ($D0) stops processing of sprites
   665  e80f a9008d107f2079e5           +tmsPut $00        ; Horizontal position
   666                          
   667                                  ; Index (A still 0)
   668  e817 8d107f2079e5               +tmsPut
   669                                  ; Early Clock / Color  (A still 0)
   670  e81d 8d107f2079e5               +tmsPut
   671  e823 ca                         dex
   672  e824 d0e1                       bne -
   673                          
   674                                  
   675                          
   676  e826 60                         rts
   677                          
   678                          ; -----------------------------------------------------------------------------
   679                          ; tmsTileXyAtPixelXy: Return tile position at pixel position
   680                          ; -----------------------------------------------------------------------------
   681                          ; Inputs:
   682                          ;  X: Pixel position X
   683                          ;  Y: Pixel position Y
   684                          ; Outputs:
   685                          ;  X: Tile position X
   686                          ;  Y: Tile position Y
   687                          ; -----------------------------------------------------------------------------
   688                          tmsTileXyAtPixelXy:
   689  e827 48                         pha
   690  e828 8a                         txa
   691  e829 4a4a4a                     +div8
   692  e82c aa                         tax
   693                          
   694  e82d 98                         tya
   695  e82e 4a4a4a                     +div8
   696  e831 a8                         tay
   697  e832 68                         pla
   698  e833 60                         rts
   699                          
   700                          ; -----------------------------------------------------------------------------
   701                          ; tmsHex8: Output an 8-bit byte as hexadecimal
   702                          ; -----------------------------------------------------------------------------
   703                          ; Inputs:
   704                          ;  A: The value to output
   705                          ; -----------------------------------------------------------------------------
   706                          tmsHex8:
   707  e834 48                 	pha
   708  e835 4a4a4a4a                   +lsr4
   709  e839 aa                 	tax
   710  e83a bd51e8             	lda .H2, x
   711  e83d 8d107f2079e5               +tmsPut 
   712  e843 68                 	pla
   713  e844 290f               	and #$0f
   714  e846 aa                 	tax
   715  e847 bd51e8             	lda .H2, x
   716  e84a 8d107f2079e5               +tmsPut 
   717                                  
   718  e850 60                 	rts
   719                          
   720  e851 3031323334353637....H2 !text "0123456789abcdef"
   721                          
   722                          
   723                          ; -----------------------------------------------------------------------------
   724                          ; tmsSetSpriteTmpAddress: Set TMS_TMP_ADDRESS for a given sprite attributes
   725                          ; -----------------------------------------------------------------------------
   726                          ; Inputs:
   727                          ;   A: sprite index (0-31)
   728                          ; -----------------------------------------------------------------------------
   729                          tmsSetSpriteTmpAddress:
   730  e861 0a                         asl
   731  e862 0a                         asl
   732  e863 8524                       sta TMS_TMP_ADDRESS
   733                          
   734  e865 a93b                       lda #>TMS_VRAM_SPRITE_ATTR_ADDRESS
   735  e867 8525                       sta TMS_TMP_ADDRESS + 1
   736  e869 60                         rts
   737                          
   738                          ; -----------------------------------------------------------------------------
   739                          ; tmsSetPosTmpAddress: Set TMS_TMP_ADDRESS for a given text position
   740                          ; -----------------------------------------------------------------------------
   741                          ; Inputs:
   742                          ;   X: X position (0 - 31)
   743                          ;   Y: Y position (0 - 23)
   744                          ; -----------------------------------------------------------------------------
   745                          tmsSetPosTmpAddress:
   746  e86a a938                       lda #>TMS_VRAM_NAME_ADDRESS
   747  e86c 8525                       sta TMS_TMP_ADDRESS + 1
   748                                  
   749                                  ; this can be better. rotate and save, perhaps
   750                          
   751  e86e 98                         tya
   752  e86f 4a4a4a                     +div8
   753  e872 18                         clc
   754  e873 6525                       adc TMS_TMP_ADDRESS + 1
   755  e875 8525                       sta TMS_TMP_ADDRESS + 1
   756  e877 98                         tya
   757  e878 2907                       and #$07
   758  e87a 0a0a0a0a0a                 +mul32
   759  e87f 8524                       sta TMS_TMP_ADDRESS
   760  e881 8a                         txa
   761  e882 0524                       ora TMS_TMP_ADDRESS
   762  e884 8524                       sta TMS_TMP_ADDRESS
   763  e886 60                         rts
   764                          
   765                          ; -----------------------------------------------------------------------------
   766                          ; tmsSetPosTmpAddressText: Set TMS_TMP_ADDRESS for a given text position
   767                          ; -----------------------------------------------------------------------------
   768                          ; Inputs:
   769                          ;   X: X position (0 - 39)
   770                          ;   Y: Y position (0 - 23)
   771                          ; -----------------------------------------------------------------------------
   772                          tmsSetPosTmpAddressText:
   773  e887 a938                       lda #>TMS_VRAM_NAME_ADDRESS
   774  e889 8525                       sta TMS_TMP_ADDRESS + 1
   775  e88b a900                       lda #<TMS_VRAM_NAME_ADDRESS
   776  e88d 8524                       sta TMS_TMP_ADDRESS
   777                          
   778                          .tmsSetPosTmpAddressTextLoop
   779  e88f c000                       cpy #0
   780  e891 f00e                       beq ++
   781  e893 18                         clc
   782  e894 a524                       lda TMS_TMP_ADDRESS
   783  e896 6928                       adc #40
   784  e898 8524                       sta TMS_TMP_ADDRESS
   785  e89a 9002                       bcc +
   786  e89c e625                       inc TMS_TMP_ADDRESS + 1
   787                          +
   788  e89e 88                         dey
   789  e89f d0ee                       bne .tmsSetPosTmpAddressTextLoop
   790                          ++
   791  e8a1 18                         clc
   792  e8a2 8a                         txa
   793  e8a3 6524                       adc TMS_TMP_ADDRESS
   794  e8a5 8524                       sta TMS_TMP_ADDRESS
   795  e8a7 9002                       bcc +
   796  e8a9 e625                       inc TMS_TMP_ADDRESS + 1
   797                          +
   798  e8ab 60                         rts
   799                          
   800                          
   801                          tmsConsoleScrollLine:
   802  e8ac a900                       lda #0
   803  e8ae 8d2f7b                     sta .TMS9918_TMP_WRITE_ROW
   804  e8b1 a901                       lda #1
   805  e8b3 8d2e7b                     sta .TMS9918_TMP_READ_ROW
   806                          .nextRow:
   807                          
   808  e8b6 ac2e7b                     ldy .TMS9918_TMP_READ_ROW
   809  e8b9 a200                       ldx #0
   810  e8bb a928                       lda #40
   811  e8bd cd2a7b                     cmp TMS9918_CONSOLE_SIZE_X
   812  e8c0 f006                       beq +
   813  e8c2 206ae8                     jsr tmsSetPosTmpAddress
   814  e8c5 4ccbe8                     jmp ++
   815                          +
   816  e8c8 2087e8                     jsr tmsSetPosTmpAddressText
   817                          ++
   818  e8cb 20a8e5                     jsr tmsSetAddressRead
   819                          
   820  e8ce 20fce8                     jsr .tmsBufferIn
   821                          
   822  e8d1 a200                       ldx #0
   823  e8d3 ac2f7b                     ldy .TMS9918_TMP_WRITE_ROW
   824  e8d6 a200                       ldx #0
   825  e8d8 a928                       lda #40
   826  e8da cd2a7b                     cmp TMS9918_CONSOLE_SIZE_X
   827  e8dd f006                       beq +
   828  e8df 206ae8                     jsr tmsSetPosTmpAddress
   829  e8e2 4ce8e8                     jmp ++
   830                          +
   831  e8e5 2087e8                     jsr tmsSetPosTmpAddressText
   832                          ++
   833  e8e8 2092e5                     jsr tmsSetAddressWrite
   834                          
   835  e8eb 200ee9                     jsr .tmsBufferOut
   836                          
   837                          
   838  e8ee ee2f7b                     inc .TMS9918_TMP_WRITE_ROW
   839  e8f1 ee2e7b                     inc .TMS9918_TMP_READ_ROW
   840                          
   841  e8f4 ad2e7b                     lda .TMS9918_TMP_READ_ROW
   842  e8f7 c919                       cmp #25
   843                          
   844  e8f9 d0bb                       bne .nextRow
   845                          
   846                          
   847                                  ; copy to buffer 32 bytes at a time, write back  24 rows for gfx, 30 "rows" for text
   848  e8fb 60                         rts
   849                          
   850                          .tmsBufferIn:
   851  e8fc a200                       ldx #0
   852                          -
   853  e8fe ad107f2079e5               +tmsGet
   854  e904 9d307b                     sta TMS9918_TMP_BUFFER, x
   855  e907 e8                         inx
   856  e908 ec2a7b                     cpx TMS9918_CONSOLE_SIZE_X
   857  e90b d0f1                       bne -
   858  e90d 60                         rts
   859                          
   860                          .tmsBufferOut:
   861  e90e a200                       ldx #0
   862                          
   863                          -
   864  e910 bd307b                     lda TMS9918_TMP_BUFFER, x
   865  e913 8d107f2079e5               +tmsPut
   866  e919 e8                         inx
   867  e91a ec2a7b                     cpx TMS9918_CONSOLE_SIZE_X
   868  e91d d0f1                       bne -
   869  e91f 60                         rts
   870                          
   871                          ; -----------------------------------------------------------------------------
   872                          ; tmsIncPosConsole: Increment console position
   873                          ; -----------------------------------------------------------------------------
   874                          tmsIncPosConsole:
   875  e920 ee287b                     inc TMS9918_CONSOLE_X
   876  e923 ad287b                     lda TMS9918_CONSOLE_X
   877  e926 cd2a7b                     cmp TMS9918_CONSOLE_SIZE_X
   878  e929 d008                       bne +
   879  e92b a900                       lda #0
   880  e92d 8d287b                     sta TMS9918_CONSOLE_X
   881  e930 ee297b                     inc TMS9918_CONSOLE_Y
   882                          +
   883  e933 ad297b                     lda TMS9918_CONSOLE_Y
   884  e936 c918                       cmp #24
   885  e938 9006                       bcc +
   886  e93a ce297b                     dec TMS9918_CONSOLE_Y
   887  e93d 4cace8                     jmp tmsConsoleScrollLine
   888                          +
   889  e940 60                         rts
   890                          
   891                          
   892                          ; -----------------------------------------------------------------------------
   893                          ; tmsDecPosConsole: Increment console position
   894                          ; -----------------------------------------------------------------------------
   895                          tmsDecPosConsole:
   896  e941 ce287b                     dec TMS9918_CONSOLE_X
   897  e944 1017                       bpl ++
   898  e946 ad2a7b                     lda TMS9918_CONSOLE_SIZE_X
   899  e949 8d287b                     sta TMS9918_CONSOLE_X
   900  e94c ce287b                     dec TMS9918_CONSOLE_X
   901  e94f a900                       lda #0
   902  e951 cd297b                     cmp TMS9918_CONSOLE_Y
   903  e954 d004                       bne +
   904  e956 8d287b                     sta TMS9918_CONSOLE_X
   905  e959 60                         rts        
   906                          +
   907  e95a ce297b                     dec TMS9918_CONSOLE_Y
   908                          ++
   909  e95d 60                         rts
   910                          
   911                          ; -----------------------------------------------------------------------------
   912                          ; tmsConsoleCls: Clear the screen and reset the console location
   913                          ; -----------------------------------------------------------------------------
   914                          tmsConsoleCls:
   915  e95e 20ade7                     jsr tmsInitTextTable
   916                          
   917                                  ; flow through
   918                          
   919                          ; -----------------------------------------------------------------------------
   920                          ; tmsConsoleHome: Set cursor position top left
   921                          ; -----------------------------------------------------------------------------
   922                          tmsConsoleHome:
   923  e961 9c287b                     stz TMS9918_CONSOLE_X
   924  e964 9c297b                     stz TMS9918_CONSOLE_Y
   925                          
   926                                  ; flow through
   927                          
   928                          ; -----------------------------------------------------------------------------
   929                          ; tmsSetPosConsole: Set cursor position to console position
   930                          ; -----------------------------------------------------------------------------
   931                          tmsSetPosConsole:
   932  e967 ae287b                     ldx TMS9918_CONSOLE_X
   933  e96a ac297b                     ldy TMS9918_CONSOLE_Y
   934                          
   935                                  ; flow through
   936                          
   937                          ; -----------------------------------------------------------------------------
   938                          ; tmsSetPosWrite: Set cursor position
   939                          ; -----------------------------------------------------------------------------
   940                          ; Inputs:
   941                          ;   X: X position (0 - 31)
   942                          ;   Y: Y position (0 - 23)
   943                          ; -----------------------------------------------------------------------------
   944                          tmsSetPosWrite:
   945  e96d a910                       lda #TMS_R1_MODE_TEXT
   946  e96f 2c277b                     bit .TMS9918_REG1_SHADOW_ADDR
   947  e972 d006                       bne tmsSetPosWriteText
   948  e974 206ae8                     jsr tmsSetPosTmpAddress
   949  e977 4c92e5                     jmp tmsSetAddressWrite
   950                          
   951                          ; -----------------------------------------------------------------------------
   952                          ; tmsSetPosWrite: Set cursor position (text mode)
   953                          ; -----------------------------------------------------------------------------
   954                          ; Inputs:
   955                          ;   X: X position (0 - 39)
   956                          ;   Y: Y position (0 - 23)
   957                          ; -----------------------------------------------------------------------------
   958                          tmsSetPosWriteText:
   959  e97a 2087e8                     jsr tmsSetPosTmpAddressText
   960  e97d 4c92e5                     jmp tmsSetAddressWrite
   961                          
   962                          ; -----------------------------------------------------------------------------
   963                          ; tmsSetPosRead: Set cursor position to read from
   964                          ; -----------------------------------------------------------------------------
   965                          ; Inputs:
   966                          ;   X: X position (0 - 31)
   967                          ;   Y: Y position (0 - 23)
   968                          ; -----------------------------------------------------------------------------
   969                          tmsSetPosRead:
   970  e980 206ae8                     jsr tmsSetPosTmpAddress
   971  e983 4ca8e5                     jmp tmsSetAddressRead
   972                          ; -----------------------------------------------------------------------------
   973                          ; tmsSetColorTmpAddressII: Set TMS_TMP_ADDRESS for a given mode II color definition
   974                          ; -----------------------------------------------------------------------------
   975                          ; Inputs:
   976                          ;   X: X position
   977                          ;   Y: Y position
   978                          ; -----------------------------------------------------------------------------
   979                          tmsSetColorTmpAddressII:
   980  e986 a900                       lda #>TMS_VRAM_COLOR_ADDRESS
   981  e988 8002                       bra .addXYToAddress
   982                          
   983                          ; -----------------------------------------------------------------------------
   984                          ; tmsSetPatternTmpAddress: Set TMS_TMP_ADDRESS for a given mode II pattern definition
   985                          ; -----------------------------------------------------------------------------
   986                          ; Inputs:
   987                          ;   X: X position
   988                          ;   Y: Y position
   989                          ; -----------------------------------------------------------------------------
   990                          tmsSetPatternTmpAddressII:
   991  e98a a920                       lda #>TMS_VRAM_PATT_ADDRESS
   992                          
   993                          .addXYToAddress:
   994  e98c 8525                       sta TMS_TMP_ADDRESS + 1
   995                          
   996  e98e 98                         tya
   997  e98f 4a4a4a                     +lsr3
   998  e992 0525                       ora TMS_TMP_ADDRESS + 1
   999  e994 8525                       sta TMS_TMP_ADDRESS + 1
  1000                          
  1001  e996 8a                         txa
  1002  e997 29f8                       and #$f8
  1003  e999 8524                       sta TMS_TMP_ADDRESS
  1004                          
  1005  e99b 98                         tya
  1006  e99c 2907                       and #$07
  1007  e99e 0524                       ora TMS_TMP_ADDRESS
  1008  e9a0 8524                       sta TMS_TMP_ADDRESS
  1009                          
  1010  e9a2 60                         rts
  1011                          
  1012                          ; -----------------------------------------------------------------------------
  1013                          ; tmsSetPatternTmpAddress: Set TMS_TMP_ADDRESS for a given pattern definition
  1014                          ; -----------------------------------------------------------------------------
  1015                          ; Inputs:
  1016                          ;   A: Pattern number
  1017                          ;   Y: Y offset (row) in the pattern
  1018                          ; -----------------------------------------------------------------------------
  1019                          tmsSetPatternTmpAddressBank0:
  1020                          tmsSetPatternTmpAddress:
  1021  e9a3 48                         pha
  1022  e9a4 a920                       lda #>TMS_VRAM_PATT_ADDRESS
  1023  e9a6 8525                       sta TMS_TMP_ADDRESS + 1
  1024                                  
  1025  e9a8 68                         pla
  1026  e9a9 48                         pha
  1027                          
  1028  e9aa 4a4a4a4a4a                 +div32
  1029  e9af 18                         clc
  1030  e9b0 6525                       adc TMS_TMP_ADDRESS + 1
  1031  e9b2 8525                       sta TMS_TMP_ADDRESS + 1
  1032  e9b4 68                         pla
  1033  e9b5 0a0a0a                     +mul8
  1034  e9b8 8524                       sta TMS_TMP_ADDRESS
  1035  e9ba 98                         tya
  1036  e9bb 0524                       ora TMS_TMP_ADDRESS
  1037  e9bd 8524                       sta TMS_TMP_ADDRESS
  1038  e9bf 60                         rts
  1039                          
  1040                          ; -----------------------------------------------------------------------------
  1041                          ; tmsSetPatternTmpAddressBank1: Set TMS_TMP_ADDRESS for a given pattern 
  1042                          ;                               definition in bank 1 (GFX II)
  1043                          ; -----------------------------------------------------------------------------
  1044                          ; Inputs:
  1045                          ;   A: Pattern number
  1046                          ;   Y: Y offset (row) in the pattern
  1047                          ; -----------------------------------------------------------------------------
  1048                          tmsSetPatternTmpAddressBank1:
  1049  e9c0 20a3e9                     jsr tmsSetPatternTmpAddress
  1050  e9c3 a525                       lda TMS_TMP_ADDRESS + 1
  1051  e9c5 18                         clc
  1052  e9c6 6908                       adc #8
  1053  e9c8 8525                       sta TMS_TMP_ADDRESS + 1
  1054  e9ca 60                         rts
  1055                          
  1056                          ; -----------------------------------------------------------------------------
  1057                          ; tmsSetPatternTmpAddressBank2: Set TMS_TMP_ADDRESS for a given pattern 
  1058                          ;                               definition in bank 2 (GFX II)
  1059                          ; -----------------------------------------------------------------------------
  1060                          ; Inputs:
  1061                          ;   A: Pattern number
  1062                          ;   Y: Y offset (row) in the pattern
  1063                          ; -----------------------------------------------------------------------------
  1064                          tmsSetPatternTmpAddressBank2:
  1065  e9cb 20a3e9                     jsr tmsSetPatternTmpAddress
  1066  e9ce a525                       lda TMS_TMP_ADDRESS + 1
  1067  e9d0 18                         clc
  1068  e9d1 6910                       adc #16
  1069  e9d3 8525                       sta TMS_TMP_ADDRESS + 1
  1070  e9d5 60                         rts        
  1071                          
  1072                          ; -----------------------------------------------------------------------------
  1073                          ; tmsSetPatternWrite: Set pattern definition to write to
  1074                          ; -----------------------------------------------------------------------------
  1075                          ; Inputs:
  1076                          ;   A: Pattern number
  1077                          ;   Y: Y offset (row) in the pattern
  1078                          ; -----------------------------------------------------------------------------
  1079                          tmsSetPatternWrite:
  1080  e9d6 20a3e9                     jsr tmsSetPatternTmpAddress
  1081  e9d9 4c92e5                     jmp tmsSetAddressWrite
  1082                          
  1083                          ; -----------------------------------------------------------------------------
  1084                          ; tmsSetPatternRead: Set pattern definition to read from
  1085                          ; -----------------------------------------------------------------------------
  1086                          ; Inputs:
  1087                          ;   A: Pattern number
  1088                          ;   Y: Y offset (row) in the pattern
  1089                          ; -----------------------------------------------------------------------------
  1090                          tmsSetPatternRead:
  1091  e9dc 20a3e9                     jsr tmsSetPatternTmpAddress
  1092  e9df 4ca8e5                     jmp tmsSetAddressRead
  1093                          
  1094                          
  1095                          ; -----------------------------------------------------------------------------
  1096                          ; tmsPrint: Print a null-terminated string
  1097                          ; -----------------------------------------------------------------------------
  1098                          ; Inputs:
  1099                          ;  STR_ADDR: Contains address of null-terminated string
  1100                          ; Prerequisites:
  1101                          ;  TMS address already set using +tmsSetAddressWrite
  1102                          ; -----------------------------------------------------------------------------
  1103                          tmsPrint:
  1104  e9e2 a000               	ldy #0
  1105                          -
  1106  e9e4 2079e5             	+tmsWaitData
  1107  e9e7 b132               	lda (STR_ADDR), y
  1108  e9e9 f009               	beq +
  1109  e9eb 8d107f2079e5               +tmsPut 
  1110  e9f1 c8                 	iny
  1111  e9f2 d0f0               	bne -
  1112                          +
  1113  e9f4 60                 	rts
  1114                          
  1115                          
  1116                          ; -----------------------------------------------------------------------------
  1117                          ; tmsConsoleOut: Print a null-terminated string
  1118                          ; -----------------------------------------------------------------------------
  1119                          ; Inputs:
  1120                          ;  'A': Character to output to console
  1121                          ; -----------------------------------------------------------------------------
  1122                          tmsConsoleOut:
  1123  e9f5 8e2c7b                     stx .TMS9918_REGX
  1124  e9f8 8c2d7b                     sty .TMS9918_REGY
  1125  e9fb 08                         php
  1126  e9fc 78                         sei
  1127  e9fd c90d                       cmp #$0d ; enter
  1128  e9ff f021                       beq .tmsConsoleNewline
  1129  ea01 c90a                       cmp #$0a ; enter
  1130  ea03 f01d                       beq .tmsConsoleNewline
  1131                          
  1132  ea05 c908                       cmp #$08 ; backspace
  1133  ea07 f01e                       beq .tmsConsoleBackspace
  1134                          
  1135  ea09 48                         pha
  1136  ea0a 2067e9                     jsr tmsSetPosConsole
  1137  ea0d 68                         pla
  1138  ea0e 8d107f2079e5               +tmsPut
  1139  ea14 2020e9                     jsr tmsIncPosConsole
  1140  ea17 ee2b7b                     inc TMS9918_CONSOLE_LINE_LEN
  1141                          
  1142                          .endConsoleOut
  1143  ea1a 28                         plp
  1144  ea1b ac2d7b                     ldy .TMS9918_REGY
  1145  ea1e ae2c7b                     ldx .TMS9918_REGX
  1146  ea21 60                         rts
  1147                          
  1148                          .tmsConsoleNewline
  1149  ea22 203cea                     jsr tmsConsoleNewline
  1150  ea25 80f3                       bra .endConsoleOut
  1151                          
  1152                          .tmsConsoleBackspace
  1153  ea27 2063ea                     jsr tmsConsoleBackspace
  1154  ea2a 80ee                       bra .endConsoleOut
  1155                          
  1156                          
  1157                          ; -----------------------------------------------------------------------------
  1158                          ; tmsConsolePrint: Print a null-terminated string (console mode)
  1159                          ; -----------------------------------------------------------------------------
  1160                          ; Inputs:
  1161                          ;  STR_ADDR: Contains address of null-terminated string
  1162                          ; Prerequisites:
  1163                          ;  TMS address already set using +tmsSetAddressWrite
  1164                          ; -----------------------------------------------------------------------------
  1165                          tmsConsolePrint:
  1166  ea2c a000               	ldy #0
  1167                          -
  1168  ea2e 2079e5             	+tmsWaitData
  1169  ea31 b132               	lda (STR_ADDR), y
  1170  ea33 f006               	beq +
  1171  ea35 20f5e9                     jsr tmsConsoleOut
  1172  ea38 c8                 	iny
  1173  ea39 d0f3               	bne -
  1174                          +
  1175  ea3b 60                 	rts
  1176                          
  1177                          ; -----------------------------------------------------------------------------
  1178                          ; tmsConsoleNewline: Output a newline to the console (scrolls if on last line)
  1179                          ; -----------------------------------------------------------------------------
  1180                          tmsConsoleNewline:
  1181  ea3c 2067e9                     jsr tmsSetPosConsole
  1182  ea3f a9208d107f2079e5           +tmsPut ' '
  1183  ea47 ad287b                     lda TMS9918_CONSOLE_X
  1184  ea4a d008                       bne +
  1185  ea4c ad2b7b                     lda TMS9918_CONSOLE_LINE_LEN
  1186  ea4f f003                       beq +
  1187  ea51 60                         rts
  1188  ea52 f000                       beq +
  1189                          +
  1190  ea54 ad2a7b                     lda TMS9918_CONSOLE_SIZE_X
  1191  ea57 8d287b                     sta TMS9918_CONSOLE_X
  1192  ea5a ce287b                     dec TMS9918_CONSOLE_X
  1193  ea5d 9c2b7b                     stz TMS9918_CONSOLE_LINE_LEN
  1194  ea60 4c20e9                     jmp tmsIncPosConsole
  1195                          
  1196                          
  1197                          ; -----------------------------------------------------------------------------
  1198                          ; tmsConsoleBackspace: Output a backspace to the console
  1199                          ; -----------------------------------------------------------------------------
  1200                          tmsConsoleBackspace:
  1201  ea63 2041e9                     jsr tmsDecPosConsole
  1202  ea66 a92020f5e9                 +tmsConsoleOut ' '
  1203  ea6b a9208d107f2079e5           +tmsPut ' '
  1204  ea73 ce2b7b                     dec TMS9918_CONSOLE_LINE_LEN
  1205  ea76 4c41e9                     jmp tmsDecPosConsole

; ******** Source: kernel.asm
   158                          
   159                          }
   160                          
   161                          !ifndef HBC56_DISABLE_SFXMAN {
   162                                  !src "sfx/sfxman.asm"
   163                          }
   164                          
   165                          !ifndef HBC56_DISABLE_LCD {
   166                                  !ifndef LCD_MODEL { LCD_MODEL = 12864 }
   167                                  !src "gfx/bitmap.asm"
   168                                  !src "lcd/lcd.asm"
   169                                  !src "gfx/tilemap.asm"
   170                          }
   171                          
   172                          !ifndef HBC56_DISABLE_UART {

; ******** Source: ../lib\ser\uart.asm
     1                          ; 6502 - MC68B50 UART
     2                          ;
     3                          ; Copyright (c) 2021 Troy Schrapel
     4                          ;
     5                          ; This code is licensed under the MIT license
     6                          ;
     7                          ; https://github.com/visrealm/hbc-56
     8                          ;
     9                          
    10                          HAVE_UART = 1
    11                          
    12                          ; -------------------------
    13                          ; Constants
    14                          ; -------------------------
    15                          !ifndef UART_IO_PORT { UART_IO_PORT = $20
    16                                  !warn "UART_IO_PORT not provided. Defaulting to ", UART_IO_PORT
    17                          }
    18                          
    19                          !ifndef UART_ZP_START { UART_ZP_START = $40
    20                                  !warn "UART_ZP_START not provided. Defaulting to ", UART_ZP_START
    21                          }
    22                          
    23                          !ifndef UART_RAM_START { UART_RAM_START = $7c80
    24                                  !warn "UART_RAM_START not provided. Defaulting to ", UART_RAM_START
    25                          }
    26                          
    27                          
    28                          ; -----------------------------------------------------------------------------
    29                          ; Zero page
    30                          ; -----------------------------------------------------------------------------
    31                          UART_RX_BUFFER_HEAD  = UART_ZP_START            ; head of circular buffer
    32                          UART_RX_BUFFER_TAIL  = UART_ZP_START + 1        ; tail of circular buffer
    33                          UART_RX_BUFFER_BYTES = UART_ZP_START + 2        ; bytes in buffer
    34                          UART_RX_FLAGS        = UART_ZP_START + 3        ; flags
    35                          @UART_ZP_END         = UART_ZP_START + 4
    36                          
    37                          !if (.UART_ZP_SIZE < @UART_ZP_END - UART_ZP_START) {
    38                                  !error "UART ZP allocation insufficient. Allocated: ", .UART_ZP_SIZE, " Require: ", (@UART_ZP_END - UART_ZP_START)
    39                          }
    40                          
    41                          ; -----------------------------------------------------------------------------
    42                          ; High RAM
    43                          ; -----------------------------------------------------------------------------
    44                          UART_RX_BUFFER       = UART_RAM_START
    45                          UART_RX_BUFFER_SIZE  = $100
    46                          
    47                          @UART_RAM_END        = UART_RAM_START + UART_RX_BUFFER_SIZE
    48                          
    49                          !if (.UART_RAM_SIZE < @UART_RAM_END - UART_RAM_START) {
    50                                  !error "UART RAM allocation insufficient. Allocated: ", .UART_RAM_SIZE, " Require: ", (@UART_RAM_END - UART_RAM_START)
    51                          }
    52                          
    53                          
    54                          ; IO Ports
    55                          UART_REG      = IO_PORT_BASE_ADDRESS | UART_IO_PORT
    56                          UART_DATA     = IO_PORT_BASE_ADDRESS | UART_IO_PORT | $01
    57                          
    58                          ; -----------------------------------------------------------------------------
    59                          ; Constants
    60                          ; -----------------------------------------------------------------------------
    61                          UART_CTL_MASTER_RESET       = %00000011
    62                          UART_CTL_CLOCK_DIV_16       = %00000001
    63                          UART_CTL_CLOCK_DIV_64       = %00000010
    64                          UART_CTL_WORD_7BIT_EPB_2SB  = %00000000
    65                          UART_CTL_WORD_7BIT_OPB_2SB  = %00000100
    66                          UART_CTL_WORD_7BIT_EPB_1SB  = %00001000
    67                          UART_CTL_WORD_7BIT_OPB_1SB  = %00001100
    68                          UART_CTL_WORD_8BIT_2SB      = %00010000
    69                          UART_CTL_WORD_8BIT_1SB      = %00010100
    70                          UART_CTL_WORD_8BIT_EPAR_1SB = %00011000
    71                          UART_CTL_WORD_8BIT_OPAR_1SB = %00011100
    72                          UART_CTL_RX_INT_ENABLE      = %10000000
    73                          
    74                          UART_STATUS_RX_REG_FULL     = %00000001
    75                          UART_STATUS_TX_REG_EMPTY    = %00000010
    76                          UART_STATUS_CARRIER_DETECT  = %00000100
    77                          UART_STATUS_CLEAR_TO_SEND   = %00001000
    78                          UART_STATUS_FRAMING_ERROR   = %00010000
    79                          UART_STATUS_RCVR_OVERRUN    = %00100000
    80                          UART_STATUS_PARITY_ERROR    = %01000000
    81                          UART_STATUS_IRQ             = %10000000
    82                          
    83                          UART_FLOWCTRL_XON           = $11
    84                          UART_FLOWCTRL_XOFF          = $13
    85                          
    86                          UART_RX_BUFFER_XOFF_SIZE    = 192
    87                          UART_RX_BUFFER_XON_SIZE     = 4
    88                          
    89                          
    90                          ; -----------------------------------------------------------------------------
    91                          ; uartInit: Initialise the UART
    92                          ; -----------------------------------------------------------------------------
    93                          uartInit:
    94  ea79 a900                       lda #0
    95  ea7b 8528                       sta UART_RX_BUFFER_HEAD
    96  ea7d 8529                       sta UART_RX_BUFFER_TAIL
    97  ea7f 852a                       sta UART_RX_BUFFER_BYTES
    98  ea81 852b                       sta UART_RX_FLAGS
    99                          
   100  ea83 a903                       lda #UART_CTL_MASTER_RESET
   101  ea85 8d207f                     sta UART_REG
   102  ea88 ea                         nop
   103  ea89 ea                         nop
   104                          
   105  ea8a a992                       lda #(UART_CTL_CLOCK_DIV_64 | UART_CTL_WORD_8BIT_2SB | UART_CTL_RX_INT_ENABLE)
   106  ea8c 8d207f                     sta UART_REG
   107  ea8f ea                         nop
   108  ea90 ea                         nop
   109                          
   110  ea91 20b9ea                     jsr uartFlowCtrlXon
   111                          
   112  ea94 60                         rts
   113                          
   114                          ; -----------------------------------------------------------------------------
   115                          ; uartIrq: Standard UART IRQ handler
   116                          ; -----------------------------------------------------------------------------
   117                          uartIrq:
   118  ea95 a901                       lda #UART_STATUS_RX_REG_FULL
   119  ea97 2c207f                     bit UART_REG
   120  ea9a f01c                       beq @endFlowControlCheck
   121  ea9c ea                         nop
   122  ea9d ea                         nop
   123                          
   124  ea9e da                         phx
   125  ea9f a628                       ldx UART_RX_BUFFER_HEAD
   126  eaa1 ad217f                     lda UART_DATA
   127  eaa4 9d587b                     sta UART_RX_BUFFER, x
   128  eaa7 e628                       inc UART_RX_BUFFER_HEAD
   129  eaa9 e62a                       inc UART_RX_BUFFER_BYTES
   130  eaab fa                         plx
   131                          
   132                          @flowControlCheck
   133                                  ; check flow control
   134  eaac ff2b09                     bbs7 UART_RX_FLAGS, @endFlowControlCheck    ; if already xoff, just leave
   135  eaaf a9c0                       lda #UART_RX_BUFFER_XOFF_SIZE               ; otherwise, should we ask for xoff?
   136  eab1 c52a                       cmp UART_RX_BUFFER_BYTES
   137  eab3 b003                       bcs @endFlowControlCheck                    ; all good
   138  eab5 20c4ea                     jsr uartFlowCtrlXoff                        ; stop please.
   139                          
   140                          @endFlowControlCheck
   141  eab8 60                         rts
   142                          
   143                          ; -----------------------------------------------------------------------------
   144                          ; uartFlowCtrlXon: Allow client to send data
   145                          ; -----------------------------------------------------------------------------
   146                          uartFlowCtrlXon:
   147  eab9 772b                       rmb7 UART_RX_FLAGS        
   148  eabb a911                       lda #UART_FLOWCTRL_XON
   149  eabd ea                         nop
   150  eabe ea                         nop
   151  eabf ea                         nop
   152  eac0 ea                         nop
   153  eac1 4cfaea                     jmp uartOut
   154                          
   155                          ; -----------------------------------------------------------------------------
   156                          ; uartFlowCtrlXoff: Stop client to sending data
   157                          ; -----------------------------------------------------------------------------
   158                          uartFlowCtrlXoff
   159  eac4 f72b                       smb7 UART_RX_FLAGS
   160  eac6 a913                       lda #UART_FLOWCTRL_XOFF
   161  eac8 ea                         nop
   162  eac9 ea                         nop
   163  eaca 4c00eb                     jmp uartOutNoBsCheck
   164                          
   165                          ; -----------------------------------------------------------------------------
   166                          ; uartInWait: Input a byte from the UART (wait forever)
   167                          ; -----------------------------------------------------------------------------
   168                          ; Outputs:
   169                          ;   A: Value of the buffer
   170                          ; -----------------------------------------------------------------------------
   171                          uartInWait:
   172  eacd a528                       lda UART_RX_BUFFER_HEAD
   173  eacf c529                       cmp UART_RX_BUFFER_TAIL
   174  ead1 f0fa                       beq uartInWait
   175  ead3 08                         php
   176  ead4 78                         sei
   177  ead5 8008                       bra .uartIncheckFlowControl
   178                          
   179                          ; -----------------------------------------------------------------------------
   180                          ; uartInNoWait: Input a byte from the UART (don't wait)
   181                          ; -----------------------------------------------------------------------------
   182                          ; Outputs:
   183                          ;   A: Value of the buffer
   184                          ;   C: Set if a byte is read
   185                          ; -----------------------------------------------------------------------------
   186                          uartInNoWait:
   187  ead7 08                         php
   188  ead8 78                         sei
   189  ead9 a528                       lda UART_RX_BUFFER_HEAD
   190  eadb c529                       cmp UART_RX_BUFFER_TAIL
   191  eadd f018                       beq @noData
   192                          
   193                          .uartIncheckFlowControl
   194                                  ; check flow control
   195  eadf 7f2b09                     bbr7 UART_RX_FLAGS, @readUartValue  ; if already xon, just exit again
   196  eae2 a904                       lda #UART_RX_BUFFER_XON_SIZE        ; otherwise, should we ask for xon?
   197  eae4 c52a                       cmp UART_RX_BUFFER_BYTES
   198  eae6 9003                       bcc @readUartValue                  ; all good
   199  eae8 20b9ea                     jsr uartFlowCtrlXon                 ; continue sending please.
   200                          
   201                          @readUartValue
   202  eaeb a629                       ldx UART_RX_BUFFER_TAIL
   203  eaed bd587b                     lda UART_RX_BUFFER, x
   204  eaf0 e629                       inc UART_RX_BUFFER_TAIL
   205  eaf2 c62a                       dec UART_RX_BUFFER_BYTES
   206  eaf4 28                         plp
   207  eaf5 38                         sec
   208  eaf6 60                         rts
   209                          @noData
   210  eaf7 28                         plp
   211  eaf8 18                         clc
   212  eaf9 60                         rts
   213                          
   214                          
   215                          ; -----------------------------------------------------------------------------
   216                          ; uartOut: Output a byte to the UART
   217                          ; -----------------------------------------------------------------------------
   218                          ; Inputs:
   219                          ;   A: Value to output
   220                          ; -----------------------------------------------------------------------------
   221                          uartOut:
   222  eafa c908                       cmp #$08        ; bs
   223  eafc d002                       bne uartOutNoBsCheck
   224  eafe a97f                       lda #$7f        ; del
   225                          uartOutNoBsCheck:
   226  eb00 48                         pha
   227  eb01 a902                       lda #UART_STATUS_TX_REG_EMPTY
   228                          
   229                          @aciaTestSend
   230  eb03 2c207f                     bit UART_REG
   231  eb06 ea                         nop
   232  eb07 ea                         nop
   233  eb08 d002                       bne +
   234  eb0a 80f7                       bra @aciaTestSend
   235                          
   236                          +
   237  eb0c 68                         pla
   238  eb0d 8d217f                     sta UART_DATA
   239  eb10 60                         rts
   240                          
   241                          
   242                          ; -----------------------------------------------------------------------------
   243                          ; uartOutString: Output a string to the UART
   244                          ; -----------------------------------------------------------------------------
   245                          ; Inputs:
   246                          ;   A: Value to output
   247                          ; -----------------------------------------------------------------------------
   248                          uartOutString:
   249  eb11 a000               	ldy #0
   250                          -
   251  eb13 b132               	lda (STR_ADDR), y
   252  eb15 f006               	beq +
   253  eb17 2000eb                     jsr uartOutNoBsCheck
   254  eb1a c8                 	iny
   255  eb1b d0f6               	bne -
   256                          +
   257  eb1d 60                         rts

; ******** Source: kernel.asm
   173                          
   174                          }
   175                          
   176                          !ifndef HBC56_DISABLE_NES {

; ******** Source: ../lib\inp\nes.asm
     1                          ; 6502 NES Controllers - HBC-56
     2                          ;
     3                          ; Copyright (c) 2021 Troy Schrapel
     4                          ;
     5                          ; This code is licensed under the MIT license
     6                          ;
     7                          ; https://github.com/visrealm/hbc-56
     8                          ;
     9                          
    10                          
    11                          !ifndef NES_IO_PORT { NES_IO_PORT = $82
    12                                  !warn "NES_IO_PORT not provided. Defaulting to ", NES_IO_PORT
    13                          }
    14                          
    15                          !ifndef NES_RAM_START { NES_RAM_START = $7ea1
    16                                  !warn "NES_RAM_START not provided. Defaulting to ", NES_RAM_START
    17                          }
    18                          
    19                          ; -------------------------
    20                          ; High RAM
    21                          ; -------------------------
    22                          NES_TMP        = NES_RAM_START
    23                          NES_RAM_SIZE   = 1
    24                          
    25                          
    26                          !if NES_RAM_END < (NES_RAM_START + NES_RAM_SIZE) {
    27                          	!error "NES_RAM requires ",NES_RAM_SIZE," bytes. Allocated ",NES_RAM_END - NES_RAM_START
    28                          }
    29                          
    30                          
    31                          ; IO Ports
    32                          NES1_IO_ADDR     = IO_PORT_BASE_ADDRESS | NES_IO_PORT
    33                          NES2_IO_ADDR     = IO_PORT_BASE_ADDRESS | NES_IO_PORT | $01
    34                          
    35                          
    36                          NES_RIGHT       = %00000001
    37                          NES_LEFT        = %00000010
    38                          NES_DOWN        = %00000100
    39                          NES_UP          = %00001000
    40                          NES_START       = %00010000
    41                          NES_SELECT      = %00100000
    42                          NES_B           = %01000000
    43                          NES_A           = %10000000
    44                          
    45                          ; -----------------------------------------------------------------------------
    46                          ; nesWaitForPress: Wait for a NES button press (either port)
    47                          ; -----------------------------------------------------------------------------
    48                          nesWaitForPress:
    49  eb1e a9ff                       lda #$ff
    50                          @notPressed
    51  eb20 cd827f                     cmp NES1_IO_ADDR
    52  eb23 d005                       bne @pressed
    53  eb25 cd837f                     cmp NES2_IO_ADDR
    54  eb28 f0f6                       beq @notPressed
    55                          @pressed
    56  eb2a 60                         rts
    57                          
    58                          ; -----------------------------------------------------------------------------
    59                          ; nes1Pressed: Is a button pressed?
    60                          ; -----------------------------------------------------------------------------
    61                          ; Inputs:
    62                          ;   A: Button to test
    63                          ; Outputs:
    64                          ;   Carry set if pressed, Carry clear if not
    65                          nes1Pressed:
    66  eb2b 2c827f                     bit NES1_IO_ADDR
    67  eb2e 18                         clc
    68  eb2f d001                       bne +
    69  eb31 38                         sec
    70                          +
    71  eb32 60                         rts
    72                          
    73                          ; -----------------------------------------------------------------------------
    74                          ; nes2Pressed: Is a button pressed?
    75                          ; -----------------------------------------------------------------------------
    76                          ; Inputs:
    77                          ;   A: Button to test
    78                          ; Outputs:
    79                          ;   Carry set if pressed, Carry clear if not
    80                          nes2Pressed:
    81  eb33 2c837f                     bit NES2_IO_ADDR
    82  eb36 18                         clc
    83  eb37 d001                       bne +
    84  eb39 38                         sec
    85                          +
    86  eb3a 60                         rts
    87                          
    88                          
    89                          
    90                          

; ******** Source: kernel.asm
   177                          
   178                          }
   179                          
   180                          !ifndef HBC56_DISABLE_KEYBOARD {

; ******** Source: ../lib\inp\keyboard.asm
     1                          ; 6502 KB Controller - HBC-56
     2                          ;
     3                          ; Copyright (c) 2021 Troy Schrapel
     4                          ;
     5                          ; This code is licensed under the MIT license
     6                          ;
     7                          ; https://github@com/visrealm/hbc-56
     8                          ;
     9                          
    10                          !ifndef HAVE_MATH_INC { !src "ut/math.inc" }
    11                          
    12                          HAVE_KEYBOARD = 1
    13                          
    14                          ; -------------------------
    15                          ; Constants
    16                          ; -------------------------
    17                          !ifndef KB_IO_PORT { KB_IO_PORT = $80
    18                                  !warn "KB_IO_PORT not provided@ Defaulting to ", KB_IO_PORT
    19                          }
    20                          
    21                          !ifndef KB_RAM_START { KB_RAM_START = $7ea1
    22                                  !warn "KB_RAM_START not provided@ Defaulting to ", KB_RAM_START
    23                          }
    24                          
    25                          ; -------------------------
    26                          ; High RAM
    27                          ; -------------------------
    28                          KB_FLAGS          = KB_RAM_START
    29                          KB_TMP_X          = KB_RAM_START + 1
    30                          KB_TMP_Y          = KB_RAM_START + 2
    31                          KB_CB_PRESSED     = KB_RAM_START + 3
    32                          KB_CB_RELEASED    = KB_RAM_START + 5
    33                          KB_CURRENT_STATE  = KB_RAM_START + 7
    34                          KB_BUFFER_HEAD    = KB_RAM_START + 8         ; head of circular buffer
    35                          KB_BUFFER_TAIL    = KB_RAM_START + 9         ; tail of circular buffer
    36                          KB_BUFFER         = KB_RAM_START + 10
    37                          KB_BUFFER_SIZE    = (1 << 4)
    38                          KB_BUFFER_MASK    = KB_BUFFER_SIZE - 1
    39                          KB_PRESSED_MAP    = KB_BUFFER + KB_BUFFER_SIZE
    40                          
    41                          KB_PRESSED_MAP_SIZE = $fd + 1
    42                          KB_PRESSED_MAP_BYTES = 32
    43                          
    44                          KB_RAM_SIZE     = (KB_PRESSED_MAP + KB_PRESSED_MAP_BYTES) - KB_RAM_START
    45                          
    46                          
    47                          !if KB_RAM_END < (KB_RAM_START + KB_RAM_SIZE) {
    48                          	!error "KB_RAM requires ",KB_RAM_SIZE," bytes@ Allocated ",KB_RAM_END - KB_RAM_START
    49                          }
    50                          
    51                          ; -------------------------
    52                          ; Contants
    53                          ; -------------------------
    54                          KB_SHIFT_DOWN   = %00000001
    55                          KB_CTRL_DOWN    = %00000010
    56                          KB_ALT_DOWN     = %00000100
    57                          KB_CAPS_LOCK    = %00001000
    58                          KB_NUM_LOCK     = %00010000
    59                          
    60                          KB_RELEASE      = $f0
    61                          KB_EXT_KEY      = $e0
    62                          KB_PAUSE_KEY    = $e1
    63                          
    64                          KB_SCANCODE_0 = $45
    65                          KB_SCANCODE_1 = $16
    66                          KB_SCANCODE_2 = $1E
    67                          KB_SCANCODE_3 = $26
    68                          KB_SCANCODE_4 = $25
    69                          KB_SCANCODE_5 = $2E
    70                          KB_SCANCODE_6 = $36
    71                          KB_SCANCODE_7 = $3D
    72                          KB_SCANCODE_8 = $3E
    73                          KB_SCANCODE_9 = $46
    74                          KB_SCANCODE_A = $1C
    75                          KB_SCANCODE_B = $32
    76                          KB_SCANCODE_C = $21
    77                          KB_SCANCODE_D = $23
    78                          KB_SCANCODE_E = $24
    79                          KB_SCANCODE_F = $2B
    80                          KB_SCANCODE_G = $34
    81                          KB_SCANCODE_H = $33
    82                          KB_SCANCODE_I = $43
    83                          KB_SCANCODE_J = $3B
    84                          KB_SCANCODE_K = $42
    85                          KB_SCANCODE_L = $4B
    86                          KB_SCANCODE_M = $3A
    87                          KB_SCANCODE_N = $31
    88                          KB_SCANCODE_O = $44
    89                          KB_SCANCODE_P = $4D
    90                          KB_SCANCODE_Q = $15
    91                          KB_SCANCODE_R = $2D
    92                          KB_SCANCODE_S = $1B
    93                          KB_SCANCODE_T = $2C
    94                          KB_SCANCODE_U = $3C
    95                          KB_SCANCODE_V = $2A
    96                          KB_SCANCODE_W = $1D
    97                          KB_SCANCODE_X = $22
    98                          KB_SCANCODE_Y = $35
    99                          KB_SCANCODE_Z = $1A
   100                          KB_SCANCODE_F1 = $05
   101                          KB_SCANCODE_F2 = $06
   102                          KB_SCANCODE_F3 = $04
   103                          KB_SCANCODE_F4 = $0C
   104                          KB_SCANCODE_F5 = $03
   105                          KB_SCANCODE_F6 = $0B
   106                          KB_SCANCODE_F7 = $83
   107                          KB_SCANCODE_F8 = $0A
   108                          KB_SCANCODE_F9 = $01
   109                          KB_SCANCODE_F10 = $09
   110                          KB_SCANCODE_F11 = $78
   111                          KB_SCANCODE_F12 = $07
   112                          KB_SCANCODE_NUMPAD_0 = $70
   113                          KB_SCANCODE_NUMPAD_1 = $69
   114                          KB_SCANCODE_NUMPAD_2 = $72
   115                          KB_SCANCODE_NUMPAD_3 = $7A
   116                          KB_SCANCODE_NUMPAD_4 = $6B
   117                          KB_SCANCODE_NUMPAD_5 = $73
   118                          KB_SCANCODE_NUMPAD_6 = $74
   119                          KB_SCANCODE_NUMPAD_7 = $6C
   120                          KB_SCANCODE_NUMPAD_8 = $75
   121                          KB_SCANCODE_NUMPAD_9 = $7D
   122                          KB_SCANCODE_NUMPAD_DIVIDE = $CA
   123                          KB_SCANCODE_NUMPAD_ENTER = $DA
   124                          KB_SCANCODE_NUMPAD_MINUS = $7B
   125                          KB_SCANCODE_NUMPAD_MULTIPLY = $7C
   126                          KB_SCANCODE_NUMPAD_PERIOD = $71
   127                          KB_SCANCODE_NUMPAD_PLUS = $79
   128                          KB_SCANCODE_NUM_LOCK = $77
   129                          KB_SCANCODE_ALT_LEFT = $11
   130                          KB_SCANCODE_ALT_RIGHT_ = $91
   131                          KB_SCANCODE_APOS = $52
   132                          KB_SCANCODE_ARROW_DOWN = $F2
   133                          KB_SCANCODE_ARROW_LEFT = $EB
   134                          KB_SCANCODE_ARROW_RIGHT = $F4
   135                          KB_SCANCODE_ARROW_UP = $F5
   136                          KB_SCANCODE_BACKSPACE = $66
   137                          KB_SCANCODE_CAPS_LOCK = $58
   138                          KB_SCANCODE_COMMA = $41
   139                          KB_SCANCODE_CTRL_LEFT = $14
   140                          KB_SCANCODE_CTRL_RIGHT = $94
   141                          KB_SCANCODE_DELETE = $F1
   142                          KB_SCANCODE_END = $E9
   143                          KB_SCANCODE_ENTER = $5A
   144                          KB_SCANCODE_EQUAL = $55
   145                          KB_SCANCODE_ESC = $76
   146                          KB_SCANCODE_HOME = $EC
   147                          KB_SCANCODE_INSERT = $F0
   148                          KB_SCANCODE_MENU = $AF
   149                          KB_SCANCODE_MINUS = $4E
   150                          KB_SCANCODE_PAGE_DOWN = $FA
   151                          KB_SCANCODE_PAGE_UP = $FD
   152                          KB_SCANCODE_PAUSE = $E1
   153                          KB_SCANCODE_PERIOD = $49
   154                          KB_SCANCODE_PRTSCR = $92
   155                          KB_SCANCODE_SCROLL_LOCK = $7E
   156                          KB_SCANCODE_SEMICOLON = $4C
   157                          KB_SCANCODE_SHIFT_LEFT = $12
   158                          KB_SCANCODE_SHIFT_RIGHT = $59
   159                          KB_SCANCODE_SLASH_BACK = $5D
   160                          KB_SCANCODE_SLASH_FORWARD = $4A
   161                          KB_SCANCODE_SPACEBAR = $29
   162                          KB_SCANCODE_SQUARE_LEFT = $54
   163                          KB_SCANCODE_SQUARE_RIGHT = $5B
   164                          KB_SCANCODE_TAB = $0D
   165                          KB_SCANCODE_TILDE = $0E
   166                          KB_SCANCODE_WINDOWS_LEFT = $9F
   167                          KB_SCANCODE_WINDOWS_RIGHT = $A7
   168                          
   169                          
   170                          KB_SHIFT_LEFT_MAP_BYTE = KB_SCANCODE_SHIFT_LEFT >> 3
   171                          KB_SHIFT_LEFT_MAP_BIT  = $80 >> (KB_SCANCODE_SHIFT_LEFT & $07)
   172                          
   173                          KB_SHIFT_RIGHT_MAP_BYTE = KB_SCANCODE_SHIFT_RIGHT >> 3
   174                          KB_SHIFT_RIGHT_MAP_BIT  = $80 >> (KB_SCANCODE_SHIFT_RIGHT & $07)
   175                          
   176                          
   177                          ; IO Ports
   178                          KB_IO_ADDR         = IO_PORT_BASE_ADDRESS | KB_IO_PORT
   179                          KB_STATUS_ADDR     = IO_PORT_BASE_ADDRESS | KB_IO_PORT | $01
   180                          
   181                          ; -----------------------------------------------------------------------------
   182                          ; kbInit: Initialise the keyboard
   183                          ; -----------------------------------------------------------------------------
   184                          kbInit:
   185  eb3b a900                       lda #$00
   186  eb3d 8d5c7c                     sta KB_FLAGS
   187                          
   188  eb40 a210                       ldx #16 ;buffer size
   189                                  
   190                                  ; ensure the hardware keyboard buffer is clear
   191                          -
   192  eb42 8e5d7c                     stx KB_TMP_X
   193  eb45 20f6eb                     jsr .kbReadByte
   194  eb48 ae5d7c                     ldx KB_TMP_X
   195  eb4b ca                         dex
   196  eb4c d0f4                       bne -
   197                          
   198  eb4e a220a900ca9d767c...        +memset KB_PRESSED_MAP, 0, KB_PRESSED_MAP_BYTES
   199                          
   200  eb5a 9c647c                     stz KB_BUFFER_HEAD
   201  eb5d 9c657c                     stz KB_BUFFER_TAIL
   202                          
   203  eb60 a900                       lda #.KB_STATE_DEFAULT
   204  eb62 8d637c                     sta KB_CURRENT_STATE
   205                          
   206                                  ; flow through
   207                          
   208                          kbResetCallbacks:
   209  eb65 a975                       lda #<.kbDummyCb
   210  eb67 8d5f7c                     sta KB_CB_PRESSED
   211  eb6a 8d617c                     sta KB_CB_RELEASED
   212                                  
   213  eb6d a9eb                       lda #>.kbDummyCb
   214  eb6f 8d607c                     sta KB_CB_PRESSED + 1
   215  eb72 8d627c                     sta KB_CB_RELEASED + 1
   216                          
   217                                  ; flow through
   218                          
   219                          .kbDummyCb:
   220  eb75 60                         rts
   221                          
   222                          ; -----------------------------------------------------------------------------
   223                          ; kbIntHandler: Standard keyboard interrupt handler
   224                          ; -----------------------------------------------------------------------------
   225                          kbIntHandler:
   226  eb76 20f6eb                     jsr .kbReadByte
   227  eb79 e000                       cpx #0
   228  eb7b f0f8                       beq .kbDummyCb
   229                          
   230  eb7d 8a                         txa     ; acc now holds scancode
   231                          
   232  eb7e ae637c                     ldx KB_CURRENT_STATE
   233                          
   234  eb81 7c84eb                     jmp (.kbStateHandlers, x)
   235                          
   236                          .KB_STATE_DEFAULT          = 0
   237                          .KB_STATE_RELEASE          = 2
   238                          .KB_STATE_EXTENDED         = 4
   239                          .KB_STATE_EXTENDED_RELEASE = 6
   240                          .KB_STATE_PAUSE_SEQ        = 8
   241                          
   242                          .kbStateHandlers:
   243  eb84 8eebb4ebc1ebb2eb...!word .stdKeyHandler, .relKeyHandler, .extKeyHandler, .extRelKeyHandler, .pauseKeyHandler
   244                          
   245                          ; default scancode handler
   246                          .stdKeyHandler
   247  eb8e c9f0                       cmp #KB_RELEASE
   248  eb90 d006                       bne +
   249  eb92 a902                       lda #.KB_STATE_RELEASE
   250  eb94 8d637c                     sta KB_CURRENT_STATE
   251  eb97 60                         rts
   252                          +
   253  eb98 c9e0                       cmp #KB_EXT_KEY
   254  eb9a d006                       bne +
   255  eb9c a904                       lda #.KB_STATE_EXTENDED
   256  eb9e 8d637c                     sta KB_CURRENT_STATE
   257  eba1 60                         rts
   258                          +
   259  eba2 c9e1                       cmp #KB_PAUSE_KEY
   260  eba4 d006                       bne +
   261  eba6 a908                       lda #.KB_STATE_PAUSE_SEQ
   262  eba8 8d637c                     sta KB_CURRENT_STATE
   263  ebab 60                         rts
   264                          +
   265                                  ; a regular key was pressed 
   266                                  ; TODO: bit field rather than a byte per key?
   267  ebac 2008ec                     jsr .kbSetKey
   268                          
   269  ebaf 6c5f7c                     jmp (KB_CB_PRESSED)
   270                                  ; subroutine returns above
   271                          
   272                          ; extended release scancode handler
   273                          .extRelKeyHandler:
   274  ebb2 0980                       ora #$80
   275                                  ; flow through
   276                          
   277                          ;  release scancode handler
   278                          .relKeyHandler:
   279  ebb4 aa                         tax
   280  ebb5 203dec                     jsr .kbClearKey
   281                          
   282  ebb8 a900                       lda #.KB_STATE_DEFAULT
   283  ebba 8d637c                     sta KB_CURRENT_STATE
   284  ebbd 8a                         txa
   285                          
   286  ebbe 6c617c                     jmp (KB_CB_RELEASED)
   287                          
   288                          ; extended scancode handler
   289                          .extKeyHandler:
   290  ebc1 c9f0                       cmp #KB_RELEASE
   291  ebc3 d006                       bne +
   292  ebc5 a906                       lda #.KB_STATE_EXTENDED_RELEASE
   293  ebc7 8d637c                     sta KB_CURRENT_STATE
   294  ebca 60                         rts
   295                          +
   296  ebcb 0980                       ora #$80
   297                                  
   298  ebcd 2008ec                     jsr .kbSetKey
   299                          
   300  ebd0 a900                       lda #.KB_STATE_DEFAULT
   301  ebd2 8d637c                     sta KB_CURRENT_STATE
   302  ebd5 8a                         txa
   303                          
   304  ebd6 6c5f7c                     jmp (KB_CB_PRESSED)
   305                          
   306                          ; pause/break sequence scancode handler
   307                          .pauseKeyHandler:
   308  ebd9 c977                       cmp #$77
   309  ebdb d018                       bne @notLastByte
   310  ebdd aa                         tax
   311  ebde ad577d                     lda KB_PRESSED_MAP + KB_SCANCODE_PAUSE
   312  ebe1 d006                       bne +
   313  ebe3 8e577d                     stx KB_PRESSED_MAP + KB_SCANCODE_PAUSE
   314  ebe6 6c5f7c                     jmp (KB_CB_PRESSED)
   315                          +
   316  ebe9 9c577d                     stz KB_PRESSED_MAP + KB_SCANCODE_PAUSE
   317                          
   318  ebec a900                       lda #.KB_STATE_DEFAULT
   319  ebee 8d637c                     sta KB_CURRENT_STATE
   320  ebf1 8a                         txa
   321                          
   322  ebf2 6c617c                     jmp (KB_CB_RELEASED)
   323                          
   324                          @notLastByte
   325  ebf5 60                         rts
   326                          
   327                          ; -----------------------------------------------------------------------------
   328                          ; Outputs:
   329                          ;   A: Value of the KB Status (0 if no key)
   330                          ;   X: PS/2 Scancode byte
   331                          ; -----------------------------------------------------------------------------
   332                          .kbReadByte:        
   333  ebf6 a200                       ldx #0
   334  ebf8 a904                       lda #$04
   335  ebfa 2c817f                     bit KB_STATUS_ADDR
   336  ebfd f008                       beq @end
   337                          
   338  ebff a020                       ldy #32         ; TODO: this could probably be smaller
   339                          -
   340  ec01 88                 	dey
   341  ec02 d0fd               	bne -
   342                          
   343  ec04 ae807f                     ldx KB_IO_ADDR
   344                          @end
   345  ec07 60                         rts
   346                          
   347                          
   348                          ; -----------------------------------------------------------------------------
   349                          ; .kbSetKey: Set a key is pressed in KB_PRESSED_MAP
   350                          ; Inputs:
   351                          ;    A - scancode
   352                          ; -----------------------------------------------------------------------------
   353                          .kbSetKey:
   354  ec08 ae647c                     ldx KB_BUFFER_HEAD      ; store at head of buffer
   355  ec0b 9d667c                     sta KB_BUFFER, x
   356                          
   357  ec0e 8d5d7c                     sta KB_TMP_X            ; find byte in map
   358  ec11 4a4a4a                     +lsr3
   359  ec14 aa                         tax
   360  ec15 ad5d7c                     lda KB_TMP_X
   361  ec18 2907                       and #$07
   362  ec1a a8                         tay
   363  ec1b bd767c                     lda KB_PRESSED_MAP, x
   364  ec1e 1930e1                     ora tableBitFromLeft, y ; set bit in map byte
   365  ec21 9d767c                     sta KB_PRESSED_MAP, x   ; update map
   366                          
   367                                  ; check for toggle keys
   368  ec24 ae5d7c                     ldx KB_TMP_X
   369  ec27 e058                       cpx #KB_SCANCODE_CAPS_LOCK
   370  ec29 d008                       bne +
   371  ec2b a908                       lda #KB_CAPS_LOCK
   372  ec2d 4d5c7c                     eor KB_FLAGS
   373  ec30 8d5c7c                     sta KB_FLAGS
   374                          +
   375                          
   376  ec33 ad647c                     lda KB_BUFFER_HEAD      ; increment (and mask) buffer head
   377  ec36 1a                         inc
   378  ec37 290f                       and #KB_BUFFER_MASK
   379  ec39 8d647c                     sta KB_BUFFER_HEAD
   380  ec3c 60                         rts
   381                          
   382                          ; -----------------------------------------------------------------------------
   383                          ; .kbClearKey: Clear a key is pressed in KB_PRESSED_MAP
   384                          ; Inputs:
   385                          ;    A - scancode
   386                          ; -----------------------------------------------------------------------------
   387                          .kbClearKey:
   388  ec3d 8d5d7c                     sta KB_TMP_X
   389  ec40 4a4a4a                     +lsr3
   390  ec43 aa                         tax
   391  ec44 ad5d7c                     lda KB_TMP_X
   392  ec47 2907                       and #$07
   393  ec49 a8                         tay
   394  ec4a bd767c                     lda KB_PRESSED_MAP, x
   395  ec4d 3938e1                     and tableInvBitFromLeft, y
   396  ec50 9d767c                     sta KB_PRESSED_MAP, x
   397  ec53 60                         rts
   398                          
   399                          
   400                          ; -----------------------------------------------------------------------------
   401                          ; .kbPopTail: Pop a scancode from the tail of the buffer
   402                          ; Inputs:
   403                          ;    A - scancode
   404                          ; -----------------------------------------------------------------------------
   405                          .kbPopTail:
   406  ec54 ad657c                     lda KB_BUFFER_TAIL
   407  ec57 aa                         tax
   408  ec58 1a                         inc
   409  ec59 290f                       and #KB_BUFFER_MASK
   410  ec5b 8d657c                     sta KB_BUFFER_TAIL
   411  ec5e bd667c                     lda KB_BUFFER, x
   412  ec61 60                         rts
   413                          
   414                          ; -----------------------------------------------------------------------------
   415                          ; kbIsPressed: Is a key pressed right now?
   416                          ; Inputs:
   417                          ;    X - scancode
   418                          ; Returns:
   419                          ;    Z - clear if pressed, set if not pressed
   420                          ; -----------------------------------------------------------------------------
   421                          kbIsPressed:
   422  ec62 08                         php
   423  ec63 78                         sei
   424  ec64 8e5d7c                     stx KB_TMP_X
   425  ec67 8a                         txa
   426  ec68 4a4a4a                     +lsr3
   427  ec6b aa                         tax
   428  ec6c ad5d7c                     lda KB_TMP_X
   429  ec6f 2907                       and #$07
   430  ec71 a8                         tay
   431  ec72 b930e1                     lda tableBitFromLeft, y
   432  ec75 3d767c                     and KB_PRESSED_MAP, x
   433  ec78 ae5d7c                     ldx KB_TMP_X
   434  ec7b 28                         plp
   435  ec7c c900                       cmp #0
   436  ec7e 60                         rts
   437                          
   438                          
   439                          ; -----------------------------------------------------------------------------
   440                          ; kbWaitForScancode: Wait for a key press
   441                          ; Returns:
   442                          ;    A - scancode
   443                          ; -----------------------------------------------------------------------------
   444                          kbWaitForScancode:
   445  ec7f 08                         php
   446  ec80 78                         sei        
   447  ec81 38                         sec
   448  ec82 ad647c                     lda KB_BUFFER_HEAD
   449  ec85 ed657c                     sbc KB_BUFFER_TAIL
   450  ec88 28                         plp
   451  ec89 c900                       cmp #0
   452  ec8b f0f2                       beq kbWaitForScancode
   453  ec8d 08                         php
   454  ec8e 78                         sei
   455  ec8f 2054ec                     jsr .kbPopTail
   456  ec92 28                         plp
   457  ec93 60                         rts
   458                          
   459                          ; -----------------------------------------------------------------------------
   460                          ; kbNextScancode: Return the next scancode in the buffer or zero if empty
   461                          ; Returns:
   462                          ;    A - scancode (or zero)
   463                          ; -----------------------------------------------------------------------------
   464                          kbNextScancode:
   465  ec94 08                         php
   466  ec95 78                         sei
   467  ec96 ad647c                     lda KB_BUFFER_HEAD
   468  ec99 cd657c                     cmp KB_BUFFER_TAIL
   469  ec9c f007                       beq @noScancode
   470  ec9e 2054ec                     jsr .kbPopTail
   471  eca1 28                         plp
   472  eca2 c900                       cmp #0
   473  eca4 60                         rts
   474                          
   475                          @noScancode
   476  eca5 28                         plp
   477  eca6 a900                       lda #0
   478  eca8 60                         rts
   479                          
   480                          ; -----------------------------------------------------------------------------
   481                          ; kbScancodeToAscii: Convert a scancode to ascii. shift/caps lock is honoured
   482                          ; Inputs:
   483                          ;    A - scancode (or zero)
   484                          ; Returns:
   485                          ;    A - ascii character
   486                          ;    C - set if valid character in A
   487                          ; -----------------------------------------------------------------------------
   488                          kbScancodeToAscii:
   489  eca9 da                         phx
   490  ecaa 8d5d7c                     sta KB_TMP_X
   491  ecad 18                         clc
   492  ecae 1002                       bpl +
   493  ecb0 fa                         plx
   494  ecb1 60                         rts
   495                          +
   496  ecb2 08                         php
   497  ecb3 78                         sei
   498  ecb4 a202                       ldx #KB_SHIFT_LEFT_MAP_BYTE
   499  ecb6 a920                       lda #KB_SHIFT_LEFT_MAP_BIT
   500  ecb8 3c767c                     bit KB_PRESSED_MAP, x
   501  ecbb f003                       beq +
   502  ecbd 38                         sec
   503  ecbe 800a                       bra @doneShiftCheck
   504                          +
   505                          
   506  ecc0 a20b                       ldx #KB_SHIFT_RIGHT_MAP_BYTE
   507  ecc2 a940                       lda #KB_SHIFT_RIGHT_MAP_BIT
   508  ecc4 3c767c                     bit KB_PRESSED_MAP, x
   509  ecc7 f001                       beq +
   510  ecc9 38                         sec
   511                          +
   512                          
   513                          @doneShiftCheck:
   514  ecca b008                       bcs @shiftedKeys:
   515  eccc ae5d7c                     ldx KB_TMP_X
   516  eccf bd0ded                     lda KEY_MAP, x
   517  ecd2 8006                       bra @end
   518                          
   519                          @shiftedKeys:
   520  ecd4 ae5d7c                     ldx KB_TMP_X
   521  ecd7 bd8ded                     lda KEY_MAP_SHIFTED, x
   522                          
   523                          @end
   524  ecda 2018e0                     jsr isAlpha
   525  ecdd 9014                       bcc @afterAlphaCheck
   526  ecdf 8d5d7c                     sta KB_TMP_X
   527  ece2 a908                       lda #KB_CAPS_LOCK
   528  ece4 2d5c7c                     and KB_FLAGS
   529  ece7 f007                       beq +
   530  ece9 ad5d7c                     lda KB_TMP_X
   531  ecec 4920                       eor #$20
   532  ecee 8003                       bra @afterAlphaCheck
   533                          +
   534  ecf0 ad5d7c                     lda KB_TMP_X
   535                          @afterAlphaCheck
   536  ecf3 28                         plp
   537  ecf4 fa                         plx
   538  ecf5 c9ff                       cmp #$ff
   539  ecf7 38                         sec
   540  ecf8 d001                       bne +
   541  ecfa 18                         clc
   542                          +        
   543  ecfb 60                         rts
   544                          
   545                          ; -----------------------------------------------------------------------------
   546                          ; kbReadAscii: Read an ASCII caharacter from the keyboard queue
   547                          ; Returns:
   548                          ;    A - ascii character
   549                          ;    C - set if valid character in A
   550                          ; -----------------------------------------------------------------------------
   551                          kbReadAscii:
   552  ecfc 08                         php
   553  ecfd 78                         sei
   554  ecfe da                         phx
   555  ecff 2094ec                     jsr kbNextScancode
   556  ed02 f005                       beq @noKey
   557  ed04 fa                         plx
   558  ed05 28                         plp
   559  ed06 4ca9ec                     jmp kbScancodeToAscii
   560                          @noKey
   561  ed09 fa                         plx
   562  ed0a 28                         plp
   563  ed0b 18                         clc
   564  ed0c 60                         rts
   565                          
   566                          
   567                          KEY_MAP:
   568                          ;      0   1   2   3   4   5   6   7   8   9   a   b   c   d   e   f
   569  ed0d ffffffffffffffff...!byte $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$09,$60,$ff; 0
   570  ed1d ffffffffff7131ff...!byte $ff,$ff,$ff,$ff,$ff,$71,$31,$ff,$ff,$ff,$7a,$73,$61,$77,$32,$ff; 1
   571  ed2d ff637864653433ff...!byte $ff,$63,$78,$64,$65,$34,$33,$ff,$ff,$20,$76,$66,$74,$72,$35,$ff; 2
   572  ed3d ff6e6268677936ff...!byte $ff,$6e,$62,$68,$67,$79,$36,$ff,$ff,$ff,$6d,$6a,$75,$37,$38,$ff; 3
   573  ed4d ff2c6b696f3039ff...!byte $ff,$2c,$6b,$69,$6f,$30,$39,$ff,$ff,$2e,$2f,$6c,$3b,$70,$2d,$ff; 4
   574  ed5d ffff27ff5b3dffff...!byte $ff,$ff,$27,$ff,$5b,$3d,$ff,$ff,$ff,$ff,$0d,$5d,$ff,$5c,$ff,$ff; 5
   575  ed6d ffffffffffff08ff...!byte $ff,$ff,$ff,$ff,$ff,$ff,$08,$ff,$ff,$31,$ff,$34,$37,$ff,$ff,$ff; 6
   576  ed7d 30ff323536381bff...!byte $30,$ff,$32,$35,$36,$38,$1b,$ff,$ff,$ff,$33,$2d,$ff,$39,$ff,$ff; 7
   577                          
   578                          KEY_MAP_SHIFTED:
   579                          ;      0   1   2   3   4   5   6   7   8   9   a   b   c   d   e   f
   580  ed8d ffffffffffffffff...!byte $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$09,$7e,$ff; 0
   581  ed9d ffffffffff5121ff...!byte $ff,$ff,$ff,$ff,$ff,$51,$21,$ff,$ff,$ff,$5a,$53,$41,$57,$40,$ff; 1
   582  edad ff435844452423ff...!byte $ff,$43,$58,$44,$45,$24,$23,$ff,$ff,$20,$56,$46,$54,$52,$25,$ff; 2
   583  edbd ff4e424847595eff...!byte $ff,$4e,$42,$48,$47,$59,$5e,$ff,$ff,$ff,$4d,$4a,$55,$26,$2a,$ff; 3
   584  edcd ff3c4b494f2928ff...!byte $ff,$3c,$4b,$49,$4f,$29,$28,$ff,$ff,$3e,$3f,$4c,$3a,$50,$5f,$ff; 4
   585  eddd ffff22ff7b2bffff...!byte $ff,$ff,$22,$ff,$7b,$2b,$ff,$ff,$ff,$ff,$0d,$7d,$ff,$7c,$ff,$ff; 5
   586  eded ffffffffffff08ff...!byte $ff,$ff,$ff,$ff,$ff,$ff,$08,$ff,$ff,$31,$ff,$34,$37,$ff,$ff,$ff; 6
   587  edfd 30ff323536381bff...!byte $30,$ff,$32,$35,$36,$38,$1b,$ff,$ff,$ff,$33,$2d,$ff,$39,$ff,$ff; 7

; ******** Source: kernel.asm
   181                          
   182                          }
   183                          

; ******** Source: ../lib\io\via.asm
     1                          ; 65(C)22 VIA - HBC-56
     2                          ;
     3                          ; Copyright (c) 2022 Troy Schrapel
     4                          ;
     5                          ; This code is licensed under the MIT license
     6                          ;
     7                          ; https://github.com/visrealm/hbc-56
     8                          ;
     9                          
    10                          
    11                          !ifndef VIA_IO_PORT { VIA_IO_PORT = $f0
    12                                  !warn "VIA_IO_PORT not provided. Defaulting to ", VIA_IO_PORT
    13                          }
    14                          
    15                          !ifndef VIA_RAM_START { VIA_RAM_START = $7d80
    16                                  !warn "VIA_RAM_START not provided. Defaulting to ", VIA_RAM_START
    17                          }
    18                          
    19                          ; -------------------------
    20                          ; High RAM
    21                          ; -------------------------
    22                          VIA_TMP        = VIA_RAM_START
    23                          VIA_RAM_SIZE   = 1
    24                          
    25                          
    26                          !if VIA_RAM_END < (VIA_RAM_START + VIA_RAM_SIZE) {
    27                          	!error "VIA_RAM requires ",VIA_RAM_SIZE," bytes. Allocated ",VIA_RAM_END - VIA_RAM_START
    28                          }
    29                          
    30                          
    31                          VIA_REG_PORT_B  = $00
    32                          VIA_REG_PORT_A  = $01
    33                          VIA_REG_DDR_B   = $02
    34                          VIA_REG_DDR_A   = $03
    35                          VIA_REG_T1C_L   = $04
    36                          VIA_REG_T1C_H   = $05
    37                          VIA_REG_T1L_L   = $06
    38                          VIA_REG_T1L_H   = $07
    39                          VIA_REG_T2C_L   = $08
    40                          VIA_REG_T2C_H   = $09
    41                          VIA_REG_ACR     = $0b
    42                          VIA_REG_IFR     = $0d
    43                          VIA_REG_IER     = $0e
    44                          
    45                          ; IO Ports
    46                          VIA_IO_ADDR     = IO_PORT_BASE_ADDRESS | VIA_IO_PORT
    47                          
    48                          VIA_IO_ADDR_PORT_B      = VIA_IO_ADDR | VIA_REG_PORT_B
    49                          VIA_IO_ADDR_PORT_A      = VIA_IO_ADDR | VIA_REG_PORT_A
    50                          VIA_IO_ADDR_DDR_B       = VIA_IO_ADDR | VIA_REG_DDR_B
    51                          VIA_IO_ADDR_DDR_A       = VIA_IO_ADDR | VIA_REG_DDR_A
    52                          VIA_IO_ADDR_T1C_L       = VIA_IO_ADDR | VIA_REG_T1C_L
    53                          VIA_IO_ADDR_T1C_H       = VIA_IO_ADDR | VIA_REG_T1C_H
    54                          VIA_IO_ADDR_T1L_L       = VIA_IO_ADDR | VIA_REG_T1L_L
    55                          VIA_IO_ADDR_T1L_H       = VIA_IO_ADDR | VIA_REG_T1L_H
    56                          VIA_IO_ADDR_T2C_L       = VIA_IO_ADDR | VIA_REG_T2C_L
    57                          VIA_IO_ADDR_T2C_H       = VIA_IO_ADDR | VIA_REG_T2C_H
    58                          VIA_IO_ADDR_ACR         = VIA_IO_ADDR | VIA_REG_ACR
    59                          VIA_IO_ADDR_IFR         = VIA_IO_ADDR | VIA_REG_IFR
    60                          VIA_IO_ADDR_IER         = VIA_IO_ADDR | VIA_REG_IER
    61                          
    62                          ; Constants
    63                          VIA_DIR_INPUT   = $00
    64                          VIA_DIR_OUTPUT  = $ff
    65                          
    66                          
    67                          
    68                          viaIntHandler:
    69  ee0d 6cbb7c                     jmp (HBC56_VIA_CALLBACK)

; ******** Source: kernel.asm
   184                          
   185                          
   186  ee10 6769746875622e63...+hbc56Title "github.com/visrealm/hbc-56"
   187                          

; ******** Source: bootscreen.asm
     1                          ; 6502 - HBC-56 - Memory tests
     2                          ;
     3                          ; Copyright (c) 2021 Troy Schrapel
     4                          ;
     5                          ; This code is licensed under the MIT license
     6                          ;
     7                          ; https://github.com/visrealm/hbc-56
     8                          ;
     9                          ;
    10                          
    11                          ; can be anywhere. we own the place at this stage
    12                          LOGO_BUFFER = $3000     
    13                          
    14                          !ifdef HAVE_TMS9918 {
    15                                  HBC56_BORDER     = TMS_DK_BLUE 
    16                                  HBC56_BACKGROUND = TMS_WHITE
    17                                  HBC56_LOGO       = TMS_DK_BLUE 
    18                                  HBC56_TEXT       = TMS_DK_BLUE
    19                          }
    20                          
    21                          !ifdef HBC56_TITLE_TEXT {
    22                                  HBC56_TITLE     = HBC56_TITLE_TEXT
    23                                  HBC56_TITLE_LEN = HBC56_TITLE_TEXT_LEN
    24                          }
    25                          
    26                          .HBC56_PRESS_ANY_KEY_TEXT:
    27  ee2b 505245535320414e...        !text "PRESS ANY KEY...",0
    28                          .HBC56_PRESS_ANY_KEY_TEXT_LEN = *-.HBC56_PRESS_ANY_KEY_TEXT-1
    29                          
    30                          .HBC56_PRESS_ANY_NES_TEXT:
    31  ee3c 5052455353204120...        !text "PRESS A TO BEGIN...",0
    32                          .HBC56_PRESS_ANY_NES_TEXT_LEN = *-.HBC56_PRESS_ANY_NES_TEXT-1
    33                          
    34                          !ifdef HAVE_GRAPHICS_LCD {
    35                                  !align 255, 0
    36                          hbc56FontLcd:
    37                                  !bin "lcd/fonts/c64-alnum.bin"
    38                          hbc56LogoLcd:
    39                                  !bin "res/hbc56lcd.bin"
    40                          }
    41                          
    42                          !ifdef HAVE_TMS9918 {
    43                          hbc56LogoInd:
    44  ee50 c8c9cacbcccdcecf...        !bin "res/hbc56boot.ind"
    45                          hbc56LogoPatt:
    46  ee92 fefefefefefefefe...        !bin "res/hbc56boot.patt"
    47                          hbc56LogoPattEnd:        
    48                          }
    49                          
    50                          hbc56BootScreen:
    51                          
    52                          !ifdef HAVE_TMS9918 {
    53  f00a 0878a9108d117f20...        +tmsSetAddrColorTable 16
    54  f01d a94f                       +tmsColorFgBg HBC56_LOGO, HBC56_BACKGROUND
    55  f01f a202                       ldx #2
    56  f021 2026e7                     jsr _tmsSendX8
    57  f024 a94f                       +tmsColorFgBg HBC56_TEXT, HBC56_BACKGROUND
    58  f026 a210                       ldx #16
    59  f028 20d3e7                     jsr tmsInitColorTable
    60                          
    61  f02b 0878a9a58d117f20...        +tmsSetPosWrite 5,5
    62  f03e a9508524a9ee8525...        +tmsSendData hbc56LogoInd, 22
    63  f04b 0878a9c58d117f20...        +tmsSetPosWrite 5,6
    64  f05e a9668524a9ee8525...        +tmsSendData hbc56LogoInd + 22, 22
    65  f06b 0878a9e58d117f20...        +tmsSetPosWrite 5,7
    66  f07e a97c8524a9ee8525...        +tmsSendData hbc56LogoInd + 44, 22
    67                          
    68  f08b 0878a9408d117f20...        +tmsSetAddrPattTable 200
    69  f09e a9928524a9ee8525...        +tmsSendData hbc56LogoPatt, $178
    70                          
    71  f0b4 0878a9c88d117f20...        +tmsPrintZ HBC56_META_TITLE, 8, 14
    72                          
    73                          
    74                                  !ifdef HBC56_TITLE_TEXT {
    75  f0d2 0878a9c38d117f20...                +tmsPrintZ HBC56_TITLE, (32 - HBC56_TITLE_LEN) / 2, 22
    76                                  }
    77                          
    78  f0f0 a9e4                       +tmsColorFgBg TMS_GREY, HBC56_BORDER
    79  f0f2 20cfe5                     jsr tmsSetBackground
    80                          }
    81                          
    82                          !ifdef HAVE_LCD {
    83                                  jsr lcdDetect
    84                                  bcc @noLcd
    85                                  !ifdef HAVE_GRAPHICS_LCD {
    86                                          jsr lcdGraphicsMode
    87                                          +memset LOGO_BUFFER, $00, 1024
    88                                          +memcpy LOGO_BUFFER + 128, hbc56LogoLcd, 256
    89                                          lda #>LOGO_BUFFER
    90                                          sta BITMAP_ADDR_H
    91                                          jsr lcdImage
    92                          
    93                                          +memset LOGO_BUFFER, $0, 128
    94                                          +tilemapCreateDefault (TILEMAP_SIZE_X_16 | TILEMAP_SIZE_Y_8), hbc56FontLcd-(32*8)
    95                                          +memset TILEMAP_DEFAULT_BUFFER_ADDRESS, ' ', 128
    96                          
    97                                          +memcpy TILEMAP_DEFAULT_BUFFER_ADDRESS + 16*4, HBC56_META_TITLE, 16
    98                          
    99                                          ldy #4
   100                                          jsr tilemapRenderRowToLcd
   101                          
   102                                  } else {
   103                                          !if LCD_ROWS > 2 { +lcdPrint "\n" }
   104                                          !if LCD_COLUMNS > 16 { +lcdPrint "  " }
   105                                          +lcdPrint "     HBC-56\n"
   106                                          !if LCD_COLUMNS > 16 { +lcdPrint "  " }
   107                                          lda #<HBC56_META_TITLE
   108                                          sta STR_ADDR_L
   109                                          lda #>HBC56_META_TITLE
   110                                          sta STR_ADDR_H
   111                                          !if LCD_ROWS = 2 {
   112                                                  jsr lcdLineTwo
   113                                          }                
   114                                          jsr lcdPrint
   115                                          !if LCD_ROWS = 2 {
   116                                                  jsr lcdLineTwo
   117                                          } else {
   118                                                  jsr lcdLineThree
   119                                          }                
   120                                          !if LCD_COLUMNS > 16 { +lcdConsolePrint "  " }
   121                                  }
   122                          @noLcd:
   123                          }
   124  f0f5 60                         rts

; ******** Source: kernel.asm
   188                          

; ******** Source: kernel.inc
     1                          ; 6502 - HBC-56 Kernel Macros
     2                          ;
     3                          ; Copyright (c) 2021 Troy Schrapel
     4                          ;
     5                          ; This code is licensed under the MIT license
     6                          ;
     7                          ; https://github.com/visrealm/hbc-56
     8                          ;
     9                          ;
    10                          
    11                          !macro setIntHandler .address {
    12                                  lda #<.address
    13                                  sta HBC56_INT_VECTOR + 1
    14                                  lda #>.address
    15                                  sta HBC56_INT_VECTOR + 2
    16                                  lda #JMP_OPCODE
    17                                  sta HBC56_INT_VECTOR
    18                          }
    19                          
    20                          !macro setNmiHandler .address {
    21                                  lda #<.address
    22                                  sta HBC56_NMI_VECTOR + 1
    23                                  lda #>.address
    24                                  sta HBC56_NMI_VECTOR + 2
    25                                  lda #JMP_OPCODE
    26                                  sta HBC56_NMI_VECTOR
    27                          }
    28                          
    29                          !macro setHbcMetaNES {
    30                                  lda #HBC56_CONSOLE_FLAG_NES
    31                                  ora HBC56_CONSOLE_FLAGS
    32                                  sta HBC56_CONSOLE_FLAGS
    33                          }
    34                          
    35                          !macro setHbcMetaNoWait {
    36                                  lda #HBC56_CONSOLE_FLAG_NOWAIT
    37                                  ora HBC56_CONSOLE_FLAGS
    38                                  sta HBC56_CONSOLE_FLAGS
    39                          }
    40                          
    41                          
    42                          !macro hbc56SetVsyncCallback .vsync {
    43                                  lda #<.vsync
    44                                  sta HBC56_VSYNC_CALLBACK
    45                                  lda #>.vsync
    46                                  sta HBC56_VSYNC_CALLBACK + 1
    47                          }
    48                          
    49                          !macro hbc56SetViaCallback .cb {
    50                                  lda #<.cb
    51                                  sta HBC56_VIA_CALLBACK
    52                                  lda #>.cb
    53                                  sta HBC56_VIA_CALLBACK + 1
    54                          }
    55                          
    56                          
    57                          !macro setHbcMetaTitle .titleStr {
    58                                  jmp .hbcMetaTitleOut
    59                          .titleStrLabel:
    60                                  !text .titleStr
    61                          .titleStrLabelLen = * - .titleStrLabel
    62                                  !byte 0 ; nul terminator for game name
    63                          
    64                          !if .titleStrLabelLen > HBC56_META_TITLE_MAX_LEN {
    65                                  !error "setHbcMetaTitle: Title metadata limited to ",HBC56_META_TITLE_MAX_LEN,"bytes"
    66                          }
    67                          .hbcMetaTitleOut:
    68                                  +memcpy HBC56_META_TITLE + (HBC56_META_TITLE_MAX_LEN-.titleStrLabelLen)/2, .titleStrLabel, .titleStrLabelLen
    69                                  lda #.titleStrLabelLen
    70                                  sta HBC56_META_TITLE_LEN
    71                          }
    72                          
    73                          !macro consoleEnableCursor {
    74                                  lda HBC56_CONSOLE_FLAGS
    75                                  ora #HBC56_CONSOLE_FLAG_CURSOR
    76                                  sta HBC56_CONSOLE_FLAGS
    77                          }
    78                          
    79                          !macro consoleDisableCursor {
    80                                  lda HBC56_CONSOLE_FLAGS
    81                                  and #!HBC56_CONSOLE_FLAG_CURSOR & $ff
    82                                  sta HBC56_CONSOLE_FLAGS
    83                          }
    84                          
    85                          !macro consoleLCDMode {
    86                                  lda HBC56_CONSOLE_FLAGS
    87                                  ora #HBC56_CONSOLE_FLAG_LCD
    88                                  sta HBC56_CONSOLE_FLAGS
    89                          }
    90                          
    91                          !macro setBreakpoint {
    92                                 !byte $db 
    93                          }
    94                          
    95                          !macro hbc56CustomDelay .delay {
    96                                  ldy #.delay
    97                                  jsr hbc56CustomDelay
    98                          }
    99                          
   100                          !macro hbc56DelayUs .us {
   101                          !if .us = 1 {
   102                                  nop
   103                                  nop
   104                          }
   105                          }
   106                          !macro hbc56DelayMs .ms {
   107                                  lda #<.ms
   108                                  sta DELAY_L
   109                                  lda #>.ms
   110                                  sta DELAY_H
   111                          
   112                                  jsr hbc56CustomDelayMs

; ******** Source: kernel.asm
   189                          

; ******** Source: interrupts.asm
     1                          ; 6502 - HBC-56 Kernel Interrupt Handling
     2                          ;
     3                          ; Copyright (c) 2021 Troy Schrapel
     4                          ;
     5                          ; This code is licensed under the MIT license
     6                          ;
     7                          ; https://github.com/visrealm/hbc-56
     8                          ;
     9                          ;
    10                          
    11                          ; -------------------------
    12                          ; Interrupts
    13                          ; -------------------------
    14                          TMS9918_IRQ            = 1      ; /INT
    15                          KB_IRQ                 = 2      ; RES1
    16                          UART_IRQ               = 3      ; RES2
    17                          VIA_IRQ                = 5      ; Onboard
    18                          
    19                          TMS9918_IRQ_BIT = (1 << (TMS9918_IRQ - 1))
    20                          KB_IRQ_BIT      = (1 << (KB_IRQ - 1))
    21                          UART_IRQ_BIT    = (1 << (UART_IRQ - 1))
    22                          VIA_IRQ_BIT     = (1 << (VIA_IRQ - 1))
    23                          
    24                          INT_CTRL_ADDRESS    = IO_PORT_BASE_ADDRESS | INT_IO_PORT
    25                          
    26                          ; -----------------------------------------------------------------------------
    27                          ; HBC-56 Interrupt handler
    28                          ; -----------------------------------------------------------------------------
    29                          hbc56IntHandler:
    30  f0f6 48                         pha
    31  f0f7 da                         phx
    32  f0f8 5a                         phy
    33                          
    34  f0f9 addf7f                     lda INT_CTRL_ADDRESS
    35                          
    36                          !ifdef HAVE_UART {
    37  f0fc 8904                       bit #UART_IRQ_BIT
    38  f0fe f005                       beq +
    39  f100 2095ea                     jsr uartIrq        
    40  f103 801e                       bra @endIntHandler
    41                          +
    42                          }
    43                          
    44                          !ifdef HAVE_TMS9918 {
    45  f105 8901                       bit #TMS9918_IRQ_BIT
    46  f107 f008                       beq +
    47  f109 2027f1                     jsr hbc56Tms9918Int
    48  f10c 2c117f                     +tmsReadStatus
    49  f10f 8012                       bra @endIntHandler
    50                          +
    51                          }
    52                          
    53  f111 8910                       bit #VIA_IRQ_BIT
    54  f113 f005                       beq +
    55  f115 200dee                     jsr viaIntHandler
    56  f118 8009                       bra @endIntHandler
    57                          +
    58                          
    59                          !ifdef HAVE_KEYBOARD {
    60  f11a 8902                       bit #KB_IRQ_BIT
    61  f11c f005                       beq +
    62  f11e 2076eb                     jsr kbIntHandler
    63  f121 8000                       bra @endIntHandler
    64                          +
    65                          }
    66                                  
    67                          @endIntHandler:
    68  f123 7a                         ply
    69  f124 fa                         plx
    70  f125 68                         pla      
    71  f126 40                         rti
    72                          
    73                          
    74                          
    75                          ; -----------------------------------------------------------------------------
    76                          ; HBC-56 TMS9918 VSYNC Interrupt handler
    77                          ; -----------------------------------------------------------------------------
    78                          !ifdef HAVE_TMS9918 {
    79                          hbc56Tms9918Int:
    80                          
    81                                  ; update ticks and seconds
    82  f127 ee9f7c                     inc HBC56_TICKS
    83  f12a ad9f7c                     lda HBC56_TICKS
    84  f12d c93c                       cmp #TMS_FPS
    85  f12f d00d                       bne +
    86  f131 a900                       lda #0
    87  f133 8d9f7c                     sta HBC56_TICKS
    88  f136 eea07cd003eea17c           +inc16 HBC56_SECONDS_L
    89                          +
    90                                  ; "tick" for sfx manager
    91                                  !ifdef HAVE_SFX_MAN {
    92                                          jsr sfxManTick
    93                                  }
    94                          
    95                                  ; handle console if enabled
    96  f13e 2ca37c                     bit HBC56_CONSOLE_FLAGS
    97  f141 1003                       bpl +
    98  f143 2049f1                     jsr .consoleVsyncCallback
    99                          +
   100                          
   101                                  ; rely on callback rts to return
   102  f146 6cb97c                     jmp (HBC56_VSYNC_CALLBACK)
   103                          
   104                          
   105                          ; -----------------------------------------------------------------------------
   106                          ; HBC-56 TMS9918 Console update
   107                          ; -----------------------------------------------------------------------------
   108                          .consoleVsyncCallback:
   109                          
   110  f149 ad9f7c                     lda HBC56_TICKS
   111  f14c f007                       beq .doCursor
   112  f14e c91e                       cmp #30
   113  f150 f003                       beq .doCursor
   114  f152 4c76f1                     jmp @endConsoleCallback
   115                          
   116                          .doCursor:
   117  f155 8ea47c                     stx HBC56_TMP_X
   118  f158 8ca57c                     sty HBC56_TMP_Y
   119  f15b 2067e9                     jsr tmsSetPosConsole
   120  f15e ad9f7c                     lda HBC56_TICKS
   121  f161 f00b                       beq +
   122  f163 a920                       lda #' '
   123  f165 8d107f2079e5               +tmsPut
   124  f16b 4c76f1                     jmp @endConsoleCallback
   125                          + 
   126  f16e a97f                       lda #$7f
   127  f170 8d107f2079e5               +tmsPut
   128                          
   129                          @endConsoleCallback
   130                          
   131                          .nullCallbackFunction:
   132  f176 60                         rts
   133                          }

; ******** Source: kernel.asm
   190                          
   191                          
   192                          ; -----------------------------------------------------------------------------
   193                          ; HBC-56 Main entry point (reset vector)
   194                          ; -----------------------------------------------------------------------------
   195                          kernelMain:
   196  f177 78                         sei
   197  f178 d8                         cld     ; make sure we're not in decimal mode
   198  f179 a2ff                       ldx #$ff
   199  f17b 9a                         txs
   200                                  
   201  f17c a940                       lda #RTI_OPCODE
   202  f17e 8d007e                     sta HBC56_INT_VECTOR
   203  f181 8d047e                     sta HBC56_NMI_VECTOR
   204                          
   205  f184 a210a920ca9da67c...        +memset HBC56_META_TITLE, ' ', HBC56_META_TITLE_MAX_LEN
   206                          
   207  f190 a900                       lda #0
   208  f192 8d9f7c                     sta HBC56_TICKS
   209  f195 8da07c                     sta HBC56_SECONDS_L
   210  f198 8da17c                     sta HBC56_SECONDS_H
   211  f19b 8da37c                     sta HBC56_CONSOLE_FLAGS
   212                          
   213  f19e 8db67c                     sta HBC56_META_TITLE + HBC56_META_TITLE_MAX_LEN
   214                          
   215                          
   216  f1a1 20fcdf                     jsr HBC56_META_VECTOR   ; user program metadata
   217                          
   218                                  !ifdef HAVE_KEYBOARD {
   219  f1a4 203beb                             jsr kbInit
   220                                  }
   221                          
   222                                  !ifdef HAVE_AY3891X {
   223  f1a7 2058e1                             jsr ayInit
   224                                  }
   225                          
   226                                  !ifdef HAVE_SFXMAN {
   227                                          jsr sfxManInit  ; requires TMS interrupts
   228                                  }
   229                          
   230                                  !ifdef HAVE_TMS9918 {
   231  f1aa 20d9e6                             jsr tmsInit
   232                          
   233  f1ad a94020efe5                         +tmsDisableOutput
   234                          
   235                                          ; dummy callback
   236  f1b2 a9768db97ca9f18d...                +hbc56SetVsyncCallback .nullCallbackFunction
   237                                  }
   238                          
   239  f1bc a9768dbb7ca9f18d...        +hbc56SetViaCallback .nullCallbackFunction
   240                          
   241                                  !ifdef HAVE_LCD {
   242                                          jsr lcdDetect
   243                                          bcc @noLcd1                
   244                                          jsr lcdInit
   245                                          jsr hbc56Delay
   246                                          jsr lcdDisplayOn
   247                                          jsr hbc56Delay
   248                          @noLcd1:
   249                                  }
   250                          
   251  f1c6 200af0                     jsr hbc56BootScreen
   252                          
   253  f1c9 a9f68d017ea9f08d...        +setIntHandler hbc56IntHandler
   254                          
   255                                  !ifdef HAVE_TMS9918 {
   256  f1d8 a94020e5e5                         +tmsEnableOutput
   257  f1dd a92020efe5                         +tmsDisableInterrupts
   258                                  }
   259                          
   260  f1e2 a914                       lda #20
   261  f1e4 8da27c                     sta HBC56_TMP
   262                          -
   263  f1e7 20e1ff                     jsr hbc56Delay
   264  f1ea cea27c                     dec HBC56_TMP
   265  f1ed d0f8                       bne -
   266                                 
   267                                  !ifdef HAVE_TMS9918 {
   268  f1ef a92020e5e5                         +tmsEnableInterrupts
   269                                  }
   270  f1f4 58                         cli
   271                          
   272  f1f5 2060f2                     jsr hbc56HighBell
   273                          
   274  f1f8 a910                       lda #HBC56_CONSOLE_FLAG_NOWAIT
   275  f1fa 2ca37c                     bit HBC56_CONSOLE_FLAGS
   276  f1fd d050                       bne .afterInput
   277                          
   278  f1ff a940                       lda #HBC56_CONSOLE_FLAG_NES
   279  f201 2da37c                     and HBC56_CONSOLE_FLAGS
   280  f204 f026                       beq .keyboardInput
   281                          
   282                          
   283                                  ; NES input
   284  f206 78                         sei
   285                                  !ifdef HAVE_TMS9918 {
   286  f207 0878a9268d117f20...                +tmsPrintZ .HBC56_PRESS_ANY_NES_TEXT, (32 - .HBC56_PRESS_ANY_NES_TEXT_LEN) / 2, 17
   287                                  }
   288                          
   289                                  !ifdef HAVE_LCD {
   290                                          jsr lcdDetect
   291                                          bcc @noLcd2
   292                                          !ifdef HAVE_GRAPHICS_LCD {
   293                                                  +memcpy TILEMAP_DEFAULT_BUFFER_ADDRESS + 16*6, .HBC56_PRESS_ANY_NES_TEXT, 16
   294                                                  ldy #6
   295                                                  jsr tilemapRenderRowToLcd
   296                                          } else {
   297                                                  lda #<.HBC56_PRESS_ANY_NES_TEXT
   298                                                  sta STR_ADDR_L
   299                                                  lda #>.HBC56_PRESS_ANY_NES_TEXT
   300                                                  sta STR_ADDR_H
   301                                                  jsr lcdPrint
   302                                          }
   303                          @noLcd2:
   304                                  }
   305  f225 58                         cli
   306  f226 201eeb                     jsr nesWaitForPress
   307  f229 4c4ff2                     jmp .afterInput
   308                          
   309                          .keyboardInput
   310                          !ifdef HAVE_KEYBOARD {
   311                                  ; Keyboard  input
   312  f22c 78                         sei
   313                                  !ifdef HAVE_TMS9918 {
   314  f22d 0878a9288d117f20...                +tmsPrintZ .HBC56_PRESS_ANY_KEY_TEXT, (32 - .HBC56_PRESS_ANY_KEY_TEXT_LEN) / 2, 17
   315                                  }
   316                          
   317                                  !ifdef HAVE_LCD {
   318                                          jsr lcdDetect
   319                                          bcc @noLcd3
   320                                          !ifdef HAVE_GRAPHICS_LCD {
   321                                                  +memcpy TILEMAP_DEFAULT_BUFFER_ADDRESS + 16*6, .HBC56_PRESS_ANY_KEY_TEXT, 16
   322                                                  ldy #6
   323                                                  jsr tilemapRenderRowToLcd
   324                                          } else {
   325                                                  lda #<.HBC56_PRESS_ANY_KEY_TEXT
   326                                                  sta STR_ADDR_L
   327                                                  lda #>.HBC56_PRESS_ANY_KEY_TEXT
   328                                                  sta STR_ADDR_H
   329                                                  jsr lcdPrint        
   330                                          }
   331                          @noLcd3:
   332                                  }
   333  f24b 58                         cli
   334  f24c 207fec                     jsr kbWaitForScancode
   335                          }
   336                          
   337                          .afterInput
   338                          
   339                                  !ifdef HAVE_LCD {
   340                                          ;jsr lcdDetect
   341                                          ;bcc @noLcd4
   342                                          jsr lcdInit
   343                                          !ifdef HAVE_GRAPHICS_LCD {
   344                                                  jsr lcdTextMode
   345                                          }
   346                                          jsr lcdClear
   347                                          jsr lcdHome
   348                          @noLcd4:
   349                                  }
   350                          
   351                                  !ifdef HAVE_TMS9918 {
   352  f24f 20ade7                             jsr tmsInitTextTable ; clear output
   353  f252 a94020efe5                         +tmsDisableOutput
   354  f257 a92020efe5                         +tmsDisableInterrupts
   355                                  }
   356                                  ; no interrupts until the user code says so
   357  f25c 78                         sei
   358                          
   359  f25d 200080                     jsr DEFAULT_HBC56_RST_VECTOR
   360                          
   361                          ; -----------------------------------------------------------------------------
   362                          ; Beep (higher tone)
   363                          ; -----------------------------------------------------------------------------
   364                          hbc56HighBell:
   365                                  !ifdef HAVE_AY3891X {
   366  f260 a9078d407fad427f...                +ayToneEnable AY_PSG0, AY_CHC
   367  f272 a90a8d407fa90f8d...                +aySetVolume AY_PSG0, AY_CHC, $ff
   368  f27c a9048d407fa9598d...                +ayPlayNote AY_PSG0, AY_CHC, NOTE_FREQ_F5
   369                                  }
   370  f290 8032                       bra .noteTimeout
   371                          
   372                          ; -----------------------------------------------------------------------------
   373                          ; Beep (lower tone)
   374                          ; -----------------------------------------------------------------------------
   375                          hbc56Bell:
   376                                  !ifdef HAVE_AY3891X {
   377  f292 a9078d407fad427f...                +ayToneEnable AY_PSG0, AY_CHC
   378  f2a4 a90a8d407fa90f8d...                +aySetVolume AY_PSG0, AY_CHC, $ff
   379  f2ae a9048d407fa97b8d...                +ayPlayNote AY_PSG0, AY_CHC, NOTE_FREQ_E3
   380                                  }
   381  f2c2 8000                       bra .noteTimeout
   382                          
   383                          .noteTimeout
   384                                  !ifdef HAVE_SFXMAN {
   385                                          lda HBC56_CONSOLE_FLAGS
   386                                          and #HBC56_CONSOLE_FLAG_LCD
   387                                          bne @skipSfxMan
   388                                          +sfxManSetChannelTimeout  AY_PSG0, AY_CHC, 0.16
   389                                          rts
   390                                  }
   391                          @skipSfxMan
   392                                  !ifdef HAVE_AY3891X {
   393  f2c4 20e1ff                             jsr hbc56Delay
   394  f2c7 20e1ff                             jsr hbc56Delay
   395  f2ca a9048d407fa9008d...                +ayStop AY_PSG0, AY_CHC
   396                                  }
   397                          
   398  f2de 60                         rts
   399                          
   400                          ; -----------------------------------------------------------------------------
   401                          ; Software reset
   402                          ; -----------------------------------------------------------------------------
   403                          hbc56Reset:
   404  f2df 4c77f1                     jmp kernelMain
   405                          
   406                          ; -----------------------------------------------------------------------------
   407                          ; Stop (loop forever)
   408                          ; -----------------------------------------------------------------------------
   409                          hbc56Stop:
   410  f2e2 cb                         wai
   411  f2e3 4ce2f2                     jmp hbc56Stop
   412                          
   413                          ; -----------------------------------------------------------------------------
   414                          ; Delay function
   415                          ; -----------------------------------------------------------------------------
   416                          hbc56CustomDelayMs:
   417  f2e6 e635                       inc DELAY_H
   418                          -
   419  f2e8 a003                       ldy #3
   420  f2ea 20e3ff                     jsr hbc56CustomDelay
   421  f2ed c634               	dec DELAY_L
   422  f2ef d0f7               	bne -
   423  f2f1 a900               	lda #0
   424  f2f3 8534                       sta DELAY_L
   425  f2f5 c635               	dec DELAY_H
   426  f2f7 d0ef               	bne -
   427  f2f9 60                 	rts
   428                          
   429                          
   430                          ;!warn "Kernel size: ", *-$f000
