ca65 V2.19 - Git e5f4ca6 Main file : ONLIBASIC.ca65 Current file: ONLIBASIC.ca65 000000r 1 ; 000000r 1 ; Acorn BASIC ONLIBASIC Extension 000000r 1 ; 000000r 1 ; Chris Oddy April 2021 000000r 1 ; 000000r 1 .setcpu "6502" 000000r 1 .listbytes unlimited 000000r 1 ; 000000r 1 ; This source code can create either a System or Atom variant of ONLIBASIC 000000r 1 ; 000000r 1 .define ATOM 1 ; set to 1 for the Atom variant 000000r 1 .define SYSTEM 0 ; set to 1 for the System variant 000000r 1 ; 000000r 1 ; Note the System variant is intended for use with the Teletext VDU only 000000r 1 ; if the 80x25 VDU is used then the graphics features will not work correctly. 000000r 1 ; 000000r 1 ; check valid options selected 000000r 1 .if (ATOM=0 .and SYSTEM=0) .or (ATOM<>0 .and SYSTEM<>0) 000000r 1 .error "Invalid variant options selected" 000000r 1 .endif 000000r 1 ; 000000r 1 ; ****** Zero Page Workspace ****** 000000r 1 ; 000000r 1 ; BASIC Workspace ($00 to $6F) 000000r 1 ; 000000r 1 index := $03 ; index to text pointer (1-byte) 000000r 1 accptr := $04 ; accumulator stack pointer (1-byte) 000000r 1 txtptr := $05 ; text area pointer (2-bytes) 000000r 1 bitst := $0F ; bit state in CLR 000000r 1 acc1 := $16 ; 1st byte of accumulator stack (15-levels) 000000r 1 acc2 := $25 ; 2nd byte of accumulator stack (15-levels) 000000r 1 acc3 := $34 ; 3rd byte of accumulator stack (15-levels) 000000r 1 acc4 := $43 ; 4th byte of accumulator stack (15-levels) 000000r 1 bwork := $52 ; BASIC workspace area 000000r 1 rpatern := $52 ; REACT Function pattern to send (2-bytes) 000000r 1 rmask := $54 ; REACT Function input response mask (2-bytes) 000000r 1 PADRLB := $56 ; PORT Address LSB (1-byte) 000000r 1 PADRMB := pltcnt ; PORT Address MSB (1-byte) 000000r 1 patern1 := $56 ; REACT Function Pattern 1 (4-bytes) 000000r 1 time1 := $5A ; REACT Function Time 1 (4-bytes) 000000r 1 time2 := $5E ; REACT Function Time 2 (4-bytes) 000000r 1 react := $62 ; REACT Function reaction time (result) (4-bytes) 000000r 1 time := $66 ; Centisecond Clock (4-bytes) 000000r 1 rclock := $6A ; base address for 8 RCLK clocks (32-bytes) 000000r 1 ; := $6A-$6D ; clock 0 (4-bytes) 000000r 1 ; := $6E-$71 ; clock 1 (4-bytes) 000000r 1 ; := $72-$75 ; clock 2 (4-bytes) 000000r 1 ; := $76-$79 ; clock 3 (4-bytes) 000000r 1 ; := $7A-$7D ; clock 4 (4-bytes) 000000r 1 ; := $7E-$81 ; clock 5 (4-bytes) 000000r 1 ; := $82-$85 ; clock 6 (4-bytes) 000000r 1 ; := $86-$89 ; clock 7 (4-bytes) 000000r 1 irclk0 := $8A ; IRQ RCLK clock zero mask (1-byte) 000000r 1 irqprt := $8B ; IRQ PORT 0 current state (only used in IRQ) (1-byte) 000000r 1 ; := $8C ; IRQ PORT 1 current state (1-byte) 000000r 1 ; := $8D ; not used (1-byte) 000000r 1 irqpre := $8E ; IRQ PORT 0 previous state (1-byte) 000000r 1 ; := $8F ; IRQ PORT 1 previous state (1-byte) 000000r 1 rclken := $90 ; RCLK clock enabled flags (1-byte) 000000r 1 rqinen := $91 ; RQIN PORT 0 active port lines (1=active) (1-byte) 000000r 1 ; := $92 ; RQIN PORT 1 active port lines (1-byte) 000000r 1 irqsig := $93 ; IRQ routine signalling to HANGUP 000000r 1 ; := $93 ; RCLK clock zero flags (1=clock has reached zero) (1-byte) 000000r 1 ; := $94 ; RQIN PORT 0 port line triggered flags (1=triggered) (1-byte) 000000r 1 ; := $95 ; RQIN PORT 1 port line triggered flags (1-byte) 000000r 1 rqpol := $96 ; PORT 0 RQIN Polarities (0=low to high transition, 1=high to low transition) (2-bytes) 000000r 1 ; := $97 ; PORT 1 RQIN Polarities (1-byte) 000000r 1 rclkmsk := $98 ; IRQ RCLK clock pointer mask (1-byte) 000000r 1 iomask := $99 ; PORT I/O Masks (0 for input, 1 for output) (4-bytes) 000000r 1 ; := $99 ; PORT 0 I/O Mask 000000r 1 ; := $9A ; PORT 1 I/O Mask 000000r 1 ; := $9B ; PORT 2 I/O Mask 000000r 1 ; := $9C ; PORT 3 I/O Mask 000000r 1 ; 000000r 1 BUFFER := $0100 ; Input Buffer (64-bytes) 000000r 1 ; 000000r 1 IRQVEC := $0204 ; vector to IRQ service routine (2-bytes) 000000r 1 ; 000000r 1 RCGOL := $03C5 ; RCLK GO line numbers for each of 8 clocks (LSB) (8-bytes) 000000r 1 RQGOL := $03CD ; RQIN GO line numbers for each of 16 lines of port 0 and 1 (LSB) (16-bytes) 000000r 1 RCGOH := $03DD ; RCLK GO line numbers for each of 8 clocks (MSB) (8-bytes) 000000r 1 RQGOH := $03E5 ; RQIN GO line numbers for each of 16 lines of ports 0 and 1 (MSB) (16-bytes) 000000r 1 ; 000000r 1 ; Used by System Graphics 000000r 1 ; FROM position on screen for plot (4-bytes) 000000r 1 X1L := $52 ; LSB of x 000000r 1 X1M := $53 ; MSB of x 000000r 1 Y1L := $54 ; LSB of y 000000r 1 Y1M := $55 ; MSB of y 000000r 1 xdir := $56 ; Plot direction (1-byte) 000000r 1 pltcnt := $57 ; Plot counter 000000r 1 ; 000000r 1 ; TO position on screen for plot (4-bytes) 000000r 1 X2L := $5A ; LSB of x 000000r 1 X2M := $5B ; MSB of x 000000r 1 Y2L := $5C ; LSB of y 000000r 1 Y2M := $5D ; MSB of y 000000r 1 ; 000000r 1 MODE := $5E ; Plot 0-15 (1-byte) 000000r 1 yofset := $61 ; y pixel offset within a character (1-byte) 000000r 1 ; 000000r 1 ; Current position on screen (4-bytes) 000000r 1 X0L := $03C1 ; LSB of x 000000r 1 X0M := $03C2 ; MSB of x 000000r 1 Y0L := $03C3 ; LSB of y 000000r 1 Y0M := $03C4 ; MSB of y 000000r 1 ; 000000r 1 ; Used by Atom Graphics 000000r 1 XL := $5A ; LSB of x position on screen (1-byte) 000000r 1 XM := $5B ; MSB of x position on screen (1-byte) 000000r 1 YL := $5C ; LSB of y position on screen (1-byte) 000000r 1 YM := $5D ; MSB of y position on screen (1-byte) 000000r 1 doplot := $5E ; Point Plot Routine function 1=set bit, 2=invert bit, else clear bit (1-byte) 000000r 1 pixadr := $5F ; address of pixel to plot (2-bytes) 000000r 1 ; 000000r 1 colour := $03FD ; Colour to Plot (1-byte) 000000r 1 plotl := $03FE ; BASIC Plot Routine address LSB (1-byte) 000000r 1 ploth := $03FF ; BASIC Plot Routine address MSB (1-byte) 000000r 1 ; 000000r 1 ; ****** Hardware Addresses ****** 000000r 1 ; 000000r 1 ; *** 200.000 6502 CPU Board *** 000000r 1 ; 8154 Interface located at $0900 (IC8) 000000r 1 IC8 := $0900 ; Base Address 000000r 1 IC8A := $0920 ; Port A Register (port lines 0 to 7) 000000r 1 IC8B := $0921 ; Port B Register (port lines 8 to 15) 000000r 1 ; 000000r 1 ; 8154 Interface located at $0E20 (IC2) 000000r 1 IC2 := $0E20 000000r 1 IC2B := $0E21 ; 8154 Port B Data Register (keyboard) 000000r 1 ; 000000r 1 ; *** 100.015 Laboratory Interface *** 000000r 1 ; 8154 Interface located at $0900 (IC36 with default link settings) 000000r 1 IC36L := $0900 ; Base Address 000000r 1 IC36LA := $0920 ; Port A Register (port lines 0 to 7) 000000r 1 IC36LB := $0921 ; Port B Register (port lines 8 to 15) 000000r 1 ; 000000r 1 ; 8154 interface located at $1000 (IC36 with alternative link settings) 000000r 1 IC36H := $1000 ; Base Address 000000r 1 IC36HA := $1020 ; Port A Register (port lines 16 to 23) 000000r 1 IC36HB := $1021 ; Port B Register (port lines 24 to 31) 000000r 1 ; 000000r 1 ; *** 100.014 Analogue Interface Board *** 000000r 1 ; The DACs, a pair of National Semiconductors ADC1220, are interfaced via an 8255: 000000r 1 ; DAC 0 bits 0 to 3 via PC0 to PC3 000000r 1 ; bits 4 to 11 via PA0 to PA7 000000r 1 ; DAC 1 bits 0 to 3 via PC1 to PC7 000000r 1 ; bits 4 to 11 via PB0 to PB7 000000r 1 ; 000000r 1 DACPAR := $1A00 ; Port A Register 000000r 1 DACPBR := $1A01 ; Port B Register 000000r 1 DACPCR := $1A02 ; Port C Register 000000r 1 DACCR := $1A03 ; Control Register 000000r 1 ; 000000r 1 ; the 12-bit ADC, a National Semiconductors ADC1210, is interfaced via a 6522: 000000r 1 ; bits 0 to 3 via PB0 to PB3 000000r 1 ; bits 4 to 11 via PA0 to PA7 000000r 1 ; the clock is provided by PB7 000000r 1 ; CA2 provides Start Conversion, a high starts the conversion 000000r 1 ; CA1 signals Conversion Complete when low 000000r 1 ; PB4-6 select 1 of 8 analogue inputs 000000r 1 ; 000000r 1 ADCORB := $1A30 ; Output Register for Port B 000000r 1 ADCORA := $1A31 ; Output Register for Port A 000000r 1 ADCDDB := $1A32 ; Data Direction Register for Port B 000000r 1 ADCT1L := $1A34 ; Timer 1 LSB 000000r 1 ADCT1M := $1A35 ; Timer 1 MSB 000000r 1 ADCACR := $1A3B ; Auxiliary Control Register 000000r 1 ADCPCR := $1A3C ; Peripheral Control Register 000000r 1 ADCIFR := $1A3D ; Interrupt Flag Register 000000r 1 ; 000000r 1 ; ****** Graphics ****** 000000r 1 ; 000000r 1 ; *** System 40x25 (Teletext) VDU Video RAM *** 000000r 1 TELTXT := $0400 ; Screen RAM base address 000000r 1 ; 000000r 1 ; *** Atom Video RAM *** 000000r 1 ;SCREEN := $8000 ; Screen RAM base address 000000r 1 ;SCRENA := $8000 ; 000000r 1 ;SCRENB := $8100 ; 000000r 1 ;SCRMD1 := $8200 ; Graphics Mode 1 000000r 1 ;SCRMD2 := $8400 ; Graphics Mode 2 000000r 1 SCRMD3 := $8600 ; Graphics Mode 3 000000r 1 ;SCRMD4 := $8C00 ; Graphics Mode 4 000000r 1 ; 000000r 1 ; *** Atom 8255 PIA (IC25) *** 000000r 1 IC25A := $B000 ; bits 0-3: keyboard row (output) 000000r 1 ; bits 4-7: graphics mode (output) 000000r 1 IC25B := $B001 ; bits 0-5: keyboard column (input) 000000r 1 ; bit 6: CTRL key (input, active low) 000000r 1 ; bit 7: SHIFT keys (input, active low) 000000r 1 IC25C := $B002 ; bit 0: cassette interface output 000000r 1 ; bit 1: 2.4kHz enable (output) 000000r 1 ; bit 2: loudspeaker output 000000r 1 ; bit 3: not used 000000r 1 ; bit 4: cassette interface 2.4kHz input 000000r 1 ; bit 5: cassette interface input 000000r 1 ; bit 6: REPT key (input, active low) 000000r 1 ; bit 7: 60 Hz sync (low during flyback) 000000r 1 IC25CL := $B003 ; control register, normally $8A: mode 0 000000r 1 ; outputs: port A, port C lower; inputs: port B, port C upper 000000r 1 ; 000000r 1 ; ONLIBASIC PORTs 000000r 1 ; 000000r 1 PORT01 := IC8 ; or IC36L ; uses either IC8 on 6502 or IC36 on Lab Interface (same addresses) 000000r 1 PORT0 := IC8A ; or IC36LA 000000r 1 PORT1 := IC8B ; or IC36LB 000000r 1 PORT23 := IC36H ; uses IC36 on Lab Interface with alternative link settings 000000r 1 PORT2 := IC36HA 000000r 1 PORT3 := IC36HB 000000r 1 ; 000000r 1 .if ATOM=1 000000r 1 KEYBRD := IC25B ; Atom keyboard on IC25 000000r 1 .endif 000000r 1 ; 000000r 1 .if SYSTEM=1 000000r 1 KEYBRD := IC2B ; System Keyboard on IC2 000000r 1 .endif 000000r 1 ; 000000r 1 ; ****** BASIC ROM Links ****** 000000r 1 ; 000000r 1 PARCOM := $C231 ; Parse Comma 000000r 1 NXTCOM := $C2CF ; BASIC Prompt 000000r 1 GETI_W := $C3C8 ; Read Integer into Workspace 000000r 1 MOVA_W := $C3CB ; Move A to Workspace 000000r 1 MOVA_Y := $C3CD ; Move A to Y 000000r 1 EQUEXP := $C4DE ; Parse = 000000r 1 ENDTST := $C4E4 ; Test for End of Statement 000000r 1 ENDCNT := $C558 ; Test for end of present statement and continue execution of next statement 000000r 1 CONT_X := $C55B ; Continue execution at next statement 000000r 1 FNDLNS := $C62E ; Find BASIC line number (number in accumulator) 000000r 1 GETINT := $C8BC ; Get integer constant, variable or expression 000000r 1 BYTE_A := $C97C ; Move to accumulator and clear remainder 000000r 1 MOVY_A := $C99F ; Move 4-byte value at Y to Accumulator 000000r 1 err_29 := $CA1B ; error 29 'Unknown or missing function' 000000r 1 RSTCON := $CBFF ; reset text pointer index, test for Escape 000000r 1 GODEST := $CC1F ; Find Destination Of GOTO or GOSUB 000000r 1 ; 000000r 1 ; OS Calls 000000r 1 ; 000000r 1 OSWRCH := $FFF4 ; WRite CHaracter - sends the byte in A down the output channel 000000r 1 ; 000000r 1 ; ASCII Control Codes 000000r 1 ; 000000r 1 FRMFED := $0C ; Form Feed 000000r 1 CR := $0D ; Carriage Return 000000r 1 SPACE := $20 ; SPACE 000000r 1 ESCAPE := $1B ; ESCAPE 000000r 1 ; 000000r 1 .org $D000 00D000 1 ; 00D000 1 AA 55 .byte $AA,$55 00D002 1 ; 00D002 1 82 D0 .byte Entry2 ; Command Entry Point 00D004 1 7E D0 .byte Entry1 ; Function Entry Point 00D006 1 ; 00D006 1 ; Statements and Functions Table 00D006 1 53 54 41 52 COMTAB: .byte "START",>START,PLOT,DRAW,MOVE,CLEAR,CLII,SEII,REL,KILL,RQIN,RCLK,HANGUP,SET,CLR,DEFPRT,PORT,TIME,