vbasic
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
vbasic [2020/09/13 02:39] – removed silverdr | vbasic [2022/11/24 09:40] (current) – [DLOFF] silverdr | ||
---|---|---|---|
Line 1: | Line 1: | ||
+ | ====== Introduction ====== | ||
+ | |||
+ | If you followed the [[: | ||
+ | |||
+ | Programming VASYL is definitely easy for seasoned Commodore 64 machine-language programmers who mastered their favourite development toolchain and can spawn another PRG in " | ||
+ | |||
+ | How about some complex graphics effects and augmentation for BASIC programs? We all know that those are not possible without machine code routines stashed somewhere (typically at 49152 upwards) in available RAM. With BeamRacer installed you can still use the same methods. You can POKE or read from storage whatever you need. But you can also load " | ||
+ | |||
+ | At least that was the idea that initially guided us. And yes - it's all there. But to be completely frank we have to admit that once VBASIC matured, we also found it an indispensable tool for developing, testing and debugging not only VASYL programming ideas but for example checking quickly how VIC behaves when treated one or another way, without all the boilerplate code needed to cycle-exactly trigger something. An eye opening and mouth corners rising experience :-) | ||
+ | |||
+ | Summing up - you will appreciate VBASIC for: | ||
+ | |||
+ | * all the additions aimed at helping in low-level programming | ||
+ | * fast-turnaround, | ||
+ | * immediate full access to VASYL' | ||
+ | * lowest barriers to entry into VASYL programming and programming techniques development | ||
+ | * verifying/ | ||
+ | |||
+ | |||
+ | ====== Installation ====== | ||
+ | |||
+ | VBASIC is an integral part of BeamRacer support software. It is currently distributed in binary form of a BASIC loadable PRG file that needs to be RUN after loading. | ||
+ | |||
+ | |||
+ | ====== Initialisation ====== | ||
+ | |||
+ | As part of initialisation process VBASIC installs itself in the RAM area, address of which is normally occupied by BASIC ROM code, and adds additional routines at the very top of memory available for BASIC programs. It also verifies the presence of an installed BeamRacer card and activates it if found. Thanks to that your programs do not need to perform any additional steps to check and activate BeamRacer. Last but not least it adds helper routines and modifies several system variables and vectors. This allows to provide correct information about available memory and enables seamless BASIC programming experience. As a result all the standard behaviour for STOP, STOP/ | ||
+ | |||
+ | ====== Features ====== | ||
+ | |||
+ | There' | ||
+ | |||
+ | ===== Hex all over and around ===== | ||
+ | |||
+ | Before we go into BeamRacer specific stuff – first things first: hexadecimal numbers. BASIC programmers are usually used to having only decimal numbers at their disposal. We didn't want to leave it that way though. We know very well that the more one's skills grow, the more important an easy way of working with hexadecimal addresses and data becomes. Therefore hexadecimal numbers received first-class VBASIC citizenship from day one. | ||
+ | |||
+ | ==== Hexadecimal entry ==== | ||
+ | |||
+ | VBASIC allows up to 16 bit hexadecimal entry wherever appropriate: | ||
+ | |||
+ | <code basic> | ||
+ | 10 POKE 53280,14 | ||
+ | 20 POKE $D021,$0E | ||
+ | 30 PRINT PEEK($D012) | ||
+ | 40 POKE $0400, | ||
+ | 50 POKE 1025, | ||
+ | 60 POKE $C000, | ||
+ | 70 SYS $C000 | ||
+ | 80 PRINT $D000/$10 | ||
+ | </ | ||
+ | |||
+ | etc. are all valid now. So are: | ||
+ | |||
+ | <code basic> | ||
+ | 10 FOR I = $100 TO $1000 STEP $10 | ||
+ | 20 REM DO GREAT STUFF WITH I | ||
+ | 30 NEXT I | ||
+ | </ | ||
+ | |||
+ | ==== Hexadecimal output ==== | ||
+ | |||
+ | Hexadecimal input is one important thing, the other side of the coin is getting your numbers __output__ in hex. VBASIC has you covered there too. | ||
+ | |||
+ | <code basic> | ||
+ | 10 PRINT 49152/16 : REM WE KNOW WE GET 3072 | ||
+ | 20 PRINT 49152/256 &W : REM HUH ? | ||
+ | 30 PRINT HI(49152) &B : REM HUH^2 ? | ||
+ | </ | ||
+ | |||
+ | Any numeric expression can be passed to one of ''&'' | ||
+ | |||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | |||
+ | hexadecimal output. Please note that there is no automatic promotion to higher number of bits. If you enter | ||
+ | |||
+ | <code basic> | ||
+ | PRINT 49152 &B | ||
+ | </ | ||
+ | |||
+ | what you get is only the eight __least__ significant bits as a hexadecimal number. | ||
+ | |||
+ | The same applies for ''& | ||
+ | |||
+ | <code basic> | ||
+ | PRINT 70000 &B | ||
+ | PRINT 70000 &W | ||
+ | PRINT 70000 &L | ||
+ | </ | ||
+ | |||
+ | and you'll get the idea. If you don't explicitly specify the modifier | ||
+ | |||
+ | <code basic> | ||
+ | PRINT 255& | ||
+ | PRINT 256& | ||
+ | PRINT 53248& | ||
+ | PRINT 16777215& | ||
+ | </ | ||
+ | |||
+ | the most appropriate one will be chosen automatically. Values up to 32-bit long are supported. | ||
+ | |||
+ | ===== 16-bit PEEKs and POKEs ===== | ||
+ | |||
+ | PEEKs and especially POKEs are inseparable part of every BASIC programs that strives for utilising graphics capabilities of the computer. Be it bitmapped graphics, be it the the first "up up and away" sprites experience or actually _anything_ beyond the blue-on-blue textual interface the machine powers up with. Built-in support for PEEK and POKE is limited to eight bit values though. VBASIC adds keywords for handling 16 bit values easily. Setting address vectors or pointers is as easy as | ||
+ | |||
+ | <code basic> | ||
+ | DPOKE $C000,$0400 | ||
+ | </ | ||
+ | |||
+ | or | ||
+ | |||
+ | <code basic> | ||
+ | DPOKE 49152,1024 | ||
+ | </ | ||
+ | |||
+ | which in both forms sets a pointer to address 1024 with its LO byte (0) located at 49152 and HI byte (4) at 49153. | ||
+ | |||
+ | Obtaining the starting address of BASIC memory becomes as easy as | ||
+ | |||
+ | <code basic> | ||
+ | PRINT DPEEK(43) | ||
+ | </ | ||
+ | |||
+ | Length of current BASIC program can be retrieved as | ||
+ | |||
+ | <code basic> | ||
+ | PRINT DPEEK(45) - DPEEK(43) - 2 | ||
+ | </ | ||
+ | |||
+ | And the (in)famous | ||
+ | |||
+ | <code basic> | ||
+ | 10 POKE 53280,0 | ||
+ | 20 POKE 53281,0 | ||
+ | </ | ||
+ | |||
+ | sequence becomes | ||
+ | |||
+ | <code basic> | ||
+ | 10 DPOKE 53280,0 | ||
+ | </ | ||
+ | |||
+ | Basically everywhere, where dealing with " | ||
+ | |||
+ | ===== HI and LO bytes ===== | ||
+ | |||
+ | Speaking of HI and LO bytes of an address (or any 16-bit value for that matter) – VBASIC provides functions that simplify working with them too. And they are named… yeah, you guessed that already, didn't you? | ||
+ | |||
+ | <code basic> | ||
+ | 10 PRINT HI(53281) | ||
+ | 20 PRINT LO(53281) | ||
+ | </ | ||
+ | |||
+ | ===== VASYL access and programming ===== | ||
+ | |||
+ | Even if the above mentioned features alone are noteworthy additions to BASIC programming environment, | ||
+ | |||
+ | ==== Automatic BeamRacer activation ==== | ||
+ | |||
+ | As explained in [[: | ||
+ | |||
+ | ==== VASYL programming ==== | ||
+ | |||
+ | VBASIC enables and in some cases simplifies VASYL programming, | ||
+ | |||
+ | === VASYL complex commands === | ||
+ | |||
+ | Certain VASYL programming sequences can be simplified with VBASIC statements, which combine several low level accesses into a single high level directive. The most common and required for virtually every displaylist employing program is the configuration of VASYL PORT register(s), | ||
+ | |||
+ | <code basic> | ||
+ | 10 VCFG 0,0 | ||
+ | </ | ||
+ | |||
+ | which configures | ||
+ | |||
+ | * Conveyor #0 (connected to VASYL PORT #0) | ||
+ | * to point to VASYL memory address 0 ($0000) | ||
+ | * with the default step of 1 | ||
+ | |||
+ | Other examples of such statements are: | ||
+ | |||
+ | <code basic> | ||
+ | 1000 DLON : REM START DISPLAYLIST EXECUTION | ||
+ | </ | ||
+ | <code basic> | ||
+ | 1000 DLOFF : REM STOP DISPLAYLIST EXECUTION | ||
+ | </ | ||
+ | <code basic> | ||
+ | 1000 BANK 3 : REM SET VASYL MEMORY BANK TO 3 | ||
+ | </ | ||
+ | |||
+ | Full list and description can be found in the [[# | ||
+ | |||
+ | === VASYL inline displaylist assembler === | ||
+ | |||
+ | VBASIC provides full support for all VASYL/ | ||
+ | |||
+ | The way BASIC interprets those keywords is tuned for both flexibility and the easiest possible way of transferring displaylists into VASYL local memory. I. e. whenever such keyword is encountered, | ||
+ | |||
+ | === Displaylist disassembler === | ||
+ | |||
+ | Even if creating simple to medium complexity blocks of VASYL programs (aka displaylists) is very easy, having a method for verifying the state of displaylist memory is a hard to overrate feature. Especially at times when things don't work as imagined. For this purpose we equipped VBASIC with a complete displaylist disassembler, | ||
+ | |||
+ | Disassembler is invoked with '' | ||
+ | |||
+ | VLIST [< | ||
+ | |||
+ | ====== Reference ====== | ||
+ | |||
+ | All VBASIC keywords grouped into three categories: | ||
+ | |||
+ | * representing only statements | ||
+ | * representing only functions | ||
+ | * representing both statements and functions | ||
+ | |||
+ | ===== Functions only ===== | ||
+ | |||
+ | Tokens from this group require to be called as functions, with parentheses, | ||
+ | |||
+ | ==== ABOUT ==== | ||
+ | FUNCTION: Returns detailed information about VBASIC and BeamRacer (if the latter is installed) versions | ||
+ | |||
+ | __Synopsis__: | ||
+ | |||
+ | __Examples__: | ||
+ | PRINT ABOUT() | ||
+ | |||
+ | AB$ = ABOUT() | ||
+ | REM NOW DO SOMETHING WITH THE STRING | ||
+ | |||
+ | ==== DPEEK ==== | ||
+ | FUNCTION: Returns " | ||
+ | |||
+ | __Synopsis__: | ||
+ | |||
+ | __Examples__: | ||
+ | BL = DPEEK(45) - DPEEK(43) - 2 : REM GET CURRENT BASIC PROGRAM SIZE IN BYTES | ||
+ | PRINT BL&W : REM PRINT IT AS 16-BIT HEXADECIMAL NUMBER | ||
+ | |||
+ | ==== HI ==== | ||
+ | FUNCTION: Returns " | ||
+ | |||
+ | __Synopsis__: | ||
+ | |||
+ | Where < | ||
+ | |||
+ | __Examples__: | ||
+ | PRINT HI(53281)& | ||
+ | |||
+ | ==== LO ==== | ||
+ | FUNCTION: Returns " | ||
+ | |||
+ | __Synopsis__: | ||
+ | |||
+ | Where < | ||
+ | |||
+ | __Examples__: | ||
+ | PRINT LO(53280)& | ||
+ | |||
+ | ==== VDPEEK ==== | ||
+ | FUNCTION: Returns " | ||
+ | |||
+ | __Synopsis__: | ||
+ | |||
+ | __Examples__: | ||
+ | PRINT VDPEEK($100)& | ||
+ | |||
+ | ==== VPEEK ==== | ||
+ | FUNCTION: Returns 8-bit value from < | ||
+ | |||
+ | __Synopsis__: | ||
+ | |||
+ | __Examples__: | ||
+ | PRINT VPEEK($100) | ||
+ | |||
+ | ===== Statements only ===== | ||
+ | |||
+ | Tokens from this group require to be used as statements with arguments given without parentheses | ||
+ | |||
+ | ==== COPY ==== | ||
+ | ---- | ||
+ | STATEMENT: Copy data between different VASYL RAM regions or between computer' | ||
+ | |||
+ | __Synopsis__: | ||
+ | * TO is the number of configured destination " | ||
+ | * FROM is the number of configured source " | ||
+ | * LENGTH is the number of bytes to be copied | ||
+ | |||
+ | __Discussion__: | ||
+ | |||
+ | There are two " | ||
+ | |||
+ | __Conveyors__: | ||
+ | * 0 - communicates with VASYL memory through [[https:// | ||
+ | * 1 - communicates with VASYL memory through [[https:// | ||
+ | * 2 - communicates with computer' | ||
+ | |||
+ | __Examples__: | ||
+ | VCFG 2,49152,1 : REM ALWAYS CONFIGURE BEFORE USING | ||
+ | VCFG 0,$1000,1 : REM ALWAYS CONFIGURE BEFORE USING | ||
+ | COPY #0,#2,4096: REM STASH CONTENT OF $C000-$CFFF TO VASYL RAM AT $1000 | ||
+ | |||
+ | VCFG 2,49152,1 : REM ALWAYS CONFIGURE BEFORE USING | ||
+ | VCFG 0,$1000,1 : REM ALWAYS CONFIGURE BEFORE USING | ||
+ | COPY #2,#0,4096: REM PULL 4KIB OF DATA FROM VASYL RAM AT $1000 TO MAIN RAM AT $C000 | ||
+ | |||
+ | BANK 1 : REM SET VASYL RAM BANK TO 1 | ||
+ | VCFG 1,0,1 : REM ALWAYS CONFIGURE BEFORE USING | ||
+ | FOR L=0 TO 7 : REM WE NEED EIGHT CHUNKS by 1KIB | ||
+ | VCFG 2,$4000+L,8 : REM ALWAYS CONFIGURE BEFORE USING | ||
+ | COPY # | ||
+ | NEXT L : REM REPEAT UNTIL 8KIB TRANSFERRED | ||
+ | |||
+ | ==== DLOFF ==== | ||
+ | ---- | ||
+ | STATEMENT: Turn off displaylist execution | ||
+ | |||
+ | __Synopsis__: | ||
+ | |||
+ | __Examples__: | ||
+ | 100 DLOFF : REM TURN DISPLAYLIST EXECUTION OFF | ||
+ | |||
+ | ==== DLON ==== | ||
+ | ---- | ||
+ | STATEMENT: Turn on displaylist execution | ||
+ | |||
+ | __Synopsis__: | ||
+ | |||
+ | __Examples__: | ||
+ | <code basic [highlight_lines_extra=" | ||
+ | 100 VCFG 0,0 : REM PORT0, ADDRESS0 | ||
+ | 110 VWAIT $83,0 | ||
+ | 120 VMOV $21,$14 | ||
+ | 130 VDELAYV $28 | ||
+ | 140 VMOV $21,6 | ||
+ | 999 VEND : REM END OF DISPLAYLIST | ||
+ | 1000 DLON : REM START DISPLAYLIST EXECUTION | ||
+ | </ | ||
+ | __Discussion__: | ||
+ | |||
+ | Turning displaylist execution on needs to be done ___after___ the displaylist program is transferred to VASYL memory. It is a common practice to put it right after the displaylist closing '' | ||
+ | |||
+ | |||
+ | ==== DPOKE ==== | ||
+ | ---- | ||
+ | STATEMENT: Double POKE | ||
+ | |||
+ | __Synopsis__: | ||
+ | * ADDRESS is a 16 bit value denoting memory address within Commodore 64 memory | ||
+ | * VALUE is a 16 bit (two byte) value to be " | ||
+ | |||
+ | __Examples__: | ||
+ | DPOKE $1000,32768 : REM STORES $00 AT $1000 AND $80 AT $1001 | ||
+ | |||
+ | DPOKE $10FE, | ||
+ | |||
+ | DPOKE $D020, | ||
+ | |||
+ | ==== LABEL ==== | ||
+ | ---- | ||
+ | STATEMENT: Define a label in displaylist code | ||
+ | |||
+ | __Synopsis__: | ||
+ | * X is a valid integer variable name | ||
+ | |||
+ | __Examples__: | ||
+ | <code basic> | ||
+ | [...] | ||
+ | 130 VSETA 10 | ||
+ | 140 LABEL A% | ||
+ | 150 VMOV $20,0 | ||
+ | 160 VMOV $20,1 | ||
+ | 170 VDECA | ||
+ | 180 VBRA A% | ||
+ | 999 VEND | ||
+ | </ | ||
+ | |||
+ | __Discussion__: | ||
+ | |||
+ | The variable after the '' | ||
+ | |||
+ | ==== VCFG ==== | ||
+ | ---- | ||
+ | STATEMENT: Configure VBASIC' | ||
+ | |||
+ | __Synopsis__: | ||
+ | * CONVEYOR is a valid number of the " | ||
+ | * 0 - communicates with VASYL memory through [[https:// | ||
+ | * 1 - communicates with VASYL memory through [[https:// | ||
+ | * 2 - communicates with computer' | ||
+ | * ADDRESS is a 16 bit value denoting memory address within either currently selected VASYL memory < | ||
+ | * STEP is an optional, signed 8 bit value (-128..127) added to internal counter after each access. If omitted defaults to '' | ||
+ | * BANK is an optional number of VASYL memory bank. If omitted, defaults to currently selected VASYL memory bank. Ignored if given when configuring " | ||
+ | |||
+ | __Examples__: | ||
+ | <code basic> | ||
+ | VCFG 0,0 : REM CONFIGURE CONVEYOR 0 TO POINT TO ADDRESS $0000 WITH STEP 1 | ||
+ | </ | ||
+ | <code basic> | ||
+ | VCFG 0,0,1 : REM CONFIGURE CONVEYOR 0 TO POINT TO ADDRESS $0000 WITH STEP 1 | ||
+ | </ | ||
+ | <code basic> | ||
+ | VCFG 1, | ||
+ | </ | ||
+ | <code basic> | ||
+ | VCFG 2,49152 : REM CONFIGURE CONVEYOR 2 TO POINT TO ADDRESS $C000 IN COMPUTER RAM WITH STEP 1 | ||
+ | </ | ||
+ | |||
+ | ==== VDATA ==== | ||
+ | ---- | ||
+ | |||
+ | STATEMENT: Stores ''< | ||
+ | |||
+ | __Synopsis__: | ||
+ | * DATA is a stream of 8-bit byte values in form of | ||
+ | * comma separated list of numbers in the range of 0..255 (or hexadecimal equivalents $00..$ff) | ||
+ | * valid 8-bit hexadecimal numbers concatenated into single string | ||
+ | |||
+ | __Examples__: | ||
+ | <code BASIC> | ||
+ | 1000 VCFG 1,$200,2 | ||
+ | 1100 VDATA 12,$0d,1 : REM STORE 12 AT $0200, 13 AT $0202 AND 1 AT $0204 | ||
+ | </ | ||
+ | |||
+ | <code BASIC> | ||
+ | 1000 VCFG 1,$200,2 | ||
+ | 1000 VDATA " | ||
+ | </ | ||
+ | |||
+ | __Discussion__: | ||
+ | |||
+ | While CBM BASIC provides '' | ||
+ | |||
+ | <code BASIC> | ||
+ | 100 FOR I=0 TO 7 | ||
+ | 110 READ A | ||
+ | 120 VPOKE $1000+I,A | ||
+ | 130 NEXT I | ||
+ | 140 DATA 0, | ||
+ | </ | ||
+ | |||
+ | this method is both inflexible and leaving much to be desired in terms of speed of execution. Both aspects become especially important when dealing with larger amounts of data. Using '' | ||
+ | |||
+ | <code BASIC> | ||
+ | 100 VCFG 1,$1000 | ||
+ | 110 VDATA 0, | ||
+ | </ | ||
+ | |||
+ | achieves the same results but requires no (slow) BASIC loop, no upfront knowledge of data stream length and moreover allows also a special " | ||
+ | |||
+ | <code BASIC> | ||
+ | 100 VCFG 1,$1000 | ||
+ | 110 VDATA " | ||
+ | </ | ||
+ | |||
+ | ==== VDPOKE ==== | ||
+ | ---- | ||
+ | STATEMENT: Double POKE for VASYL memory | ||
+ | |||
+ | __Synopsis__: | ||
+ | * ADDRESS is a 16 bit value denoting memory address within currently selected VASYL memory < | ||
+ | * VALUE is a 16 bit (two byte) value to be " | ||
+ | |||
+ | __Examples__: | ||
+ | VDPOKE $1000,32768 : REM STORES $00 AT $1000 AND $80 AT $1001 | ||
+ | |||
+ | VDPOKE $10FE, | ||
+ | |||
+ | ==== VLIST ==== | ||
+ | ---- | ||
+ | STATEMENT: Invoke displaylist disassembler | ||
+ | |||
+ | __Synopsis__: | ||
+ | * START inclusive starting address of memory range to be disassembled | ||
+ | * END exclusive end of memory address range to be disassembled | ||
+ | |||
+ | __Examples__: | ||
+ | <code BASIC> | ||
+ | VLIST | ||
+ | </ | ||
+ | <code BASIC> | ||
+ | VLIST 4096 | ||
+ | </ | ||
+ | <code BASIC> | ||
+ | VLIST $100 | ||
+ | </ | ||
+ | <code BASIC> | ||
+ | VLIST 256,512 | ||
+ | </ | ||
+ | |||
+ | __Discussion__: | ||
+ | |||
+ | Disassembler can be invoked in three different ways | ||
+ | - with no arguments | ||
+ | - with one argument | ||
+ | - with two arguments | ||
+ | |||
+ | With no arguments disassembly begins from the next address after the last, previously disassembled one (or $0000 on the first invocation) and outputs full screen less one top and three bottom lines. This allows easy browsing of subsequent memory ranges by simply pressing '' | ||
+ | <code BASIC> | ||
+ | VLIST | ||
+ | </ | ||
+ | When one argument is given, that argument determines the first VASYL memory address to be disassembled. Output is limited to one screen, the same as when no arguments are given | ||
+ | <code BASIC> | ||
+ | VLIST $100 | ||
+ | </ | ||
+ | With two arguments, the second one determines the exclusive end of address range to be disassembled. Output is continuous and scrolling can be slowed down by holding '' | ||
+ | <code BASIC> | ||
+ | VLIST 256,512 | ||
+ | </ | ||
+ | |||
+ | ==== VPOKE ==== | ||
+ | ---- | ||
+ | STATEMENT: VASYL memory equivalent of the regular POKE statement. | ||
+ | |||
+ | __Synopsis__: | ||
+ | * ADDRESS is a 16 bit value denoting memory address within currently [[# | ||
+ | * VALUE is an 8-bit byte value to be " | ||
+ | |||
+ | __Examples__: | ||
+ | <code basic> | ||
+ | VPOKE 4096,128 | ||
+ | </ | ||
+ | <code basic> | ||
+ | VPOKE $100,$FF | ||
+ | </ | ||
+ | |||
+ | ===== Both statements and functions ===== | ||
+ | |||
+ | All the following keywords accept both statement (no parentheses) and function (with parentheses) methods of invocation. Obviously they behave differently depending on whether they are invoked as a statement or as a function | ||
+ | |||
+ | ==== BANK ==== | ||
+ | ---- | ||
+ | STATEMENT: Set current VASYL RAM bank to < | ||
+ | |||
+ | __Synopsis__: | ||
+ | |||
+ | * BANK is an integer number in the range of 0...7, representing VASYL memory bank number to be selected | ||
+ | |||
+ | __Examples__: | ||
+ | BANK 1 | ||
+ | |||
+ | FUNCTION: Returns currently selected VASYL RAM bank | ||
+ | |||
+ | __Synopsis__: | ||
+ | |||
+ | __Examples__: | ||
+ | PRINT BANK() | ||
+ | |||
+ | ==== RACER ==== | ||
+ | ---- | ||
+ | STATEMENT: Set BeamRacer status to <NUM> | ||
+ | |||
+ | __Synopsis__: | ||
+ | |||
+ | Where <NUM> can be 0, 1, 2, 3 meaning | ||
+ | * 0 - BeamRacer inactive | ||
+ | * 1 - BeamRacer active but RUN/ | ||
+ | * 2 - BeamRacer active and automatically reactivated after every RUN/ | ||
+ | * 3 - Disable VBASIC without changing BeamRacer status (VBASIC V1.2 and higher) | ||
+ | |||
+ | __Examples__: | ||
+ | RACER 0 : REM DEACTIVATE BEAMRACER | ||
+ | |||
+ | FUNCTION: Returns current status of BeamRacer | ||
+ | |||
+ | Where returned value can be 0, 1, 2, 255 meaning | ||
+ | * 0 - BeamRacer inactive | ||
+ | * 1 - BeamRacer active but RUN/ | ||
+ | * 2 - BeamRacer active and automatically reactivated after every RUN/ | ||
+ | * 255 - BeamRacer not found | ||
+ | |||
+ | __Synopsis__: | ||
+ | |||
+ | __Examples__: | ||
+ | 100 RS=RACER() | ||
+ | 110 PRINT " | ||
+ | 120 IF RS=0 THEN PRINT " | ||
+ | 130 IF RS=1 THEN PRINT " | ||
+ | 140 IF RS=2 THEN PRINT " | ||
+ | 150 IF RS=255 THEN PRINT "NOT FOUND" | ||
+ | |||
+ | __Discussion__: | ||
+ | |||
+ | When VBASIC is run, and BeamRacer is installed, the status of BeamRacer is set to '' | ||
+ | |||
+ | ==== VBADLINE ==== | ||
+ | ---- | ||
+ | DISPLAYLIST: | ||
+ | |||
+ | STATEMENT: Assembles [[: | ||
+ | |||
+ | __Synopsis__: | ||
+ | * RASTERLINES is a 3-bit integer number in the range 0..7 | ||
+ | |||
+ | __Examples__: | ||
+ | VBADLINE 3 : REM NEXT BADLINE THREE LINES LATER | ||
+ | |||
+ | FUNCTION: Returns assembled [[: | ||
+ | |||
+ | __Synopsis__: | ||
+ | * RASTERLINES is a 3-bit integer number in the range 0..7 | ||
+ | |||
+ | __Examples__: | ||
+ | A = VBADLINE(3) : REM ASSEMBLE AND ASSIGN THE RESULT TO A VARIABLE | ||
+ | |||
+ | __Discussion__: | ||
+ | ==== VBRA ==== | ||
+ | ---- | ||
+ | DISPLAYLIST: | ||
+ | |||
+ | STATEMENT: Assembles [[: | ||
+ | |||
+ | __Synopsis__: | ||
+ | * ADDRESS is a memory address within the -128..127 range from the current one | ||
+ | * OFFSET is an 8-bit signed number from range -128..127 | ||
+ | |||
+ | __Examples__: | ||
+ | <code basic [highlight_lines_extra=" | ||
+ | [...] | ||
+ | 150 VSETA 12 | ||
+ | 160 LABEL A% | ||
+ | [...] | ||
+ | 190 VDECA | ||
+ | 200 VBRA A% | ||
+ | 999 VEND | ||
+ | </ | ||
+ | |||
+ | <code basic [highlight_lines_extra=" | ||
+ | [...] | ||
+ | 200 VBRA 100 : REM CONTINUE AT ADDRESS $64 | ||
+ | 999 VEND | ||
+ | </ | ||
+ | |||
+ | <code basic [highlight_lines_extra=" | ||
+ | [...] | ||
+ | 200 VBRA *-2 : REM INFINITE LOOP | ||
+ | 999 VEND | ||
+ | </ | ||
+ | FUNCTION: Returns assembled [[: | ||
+ | |||
+ | __Synopsis__: | ||
+ | |||
+ | __Examples__: | ||
+ | A = VBRA(*+10): REM ASSEMBLE AND ASSIGN THE RESULT TO A VARIABLE | ||
+ | | ||
+ | __Discussion__: | ||
+ | ==== VDECA ==== | ||
+ | ---- | ||
+ | DISPLAYLIST: | ||
+ | |||
+ | STATEMENT: Assembles [[: | ||
+ | |||
+ | __Synopsis__: | ||
+ | |||
+ | __Examples__: | ||
+ | <code basic [highlight_lines_extra=" | ||
+ | 100 VCFG 0,0 : REM ALWAYS CONFIGURE | ||
+ | 110 VWAIT $33,0 : REM WAIT FOR FIRST PAPER LINE | ||
+ | 120 VSETA 12 : REM TWELVE TIMES | ||
+ | 130 LABEL A% : REM LOOP CODE BEGINS HERE | ||
+ | 140 VMOV $21, 14 : REM LIGHT BLUE | ||
+ | 150 VDELAYV 8 : REM DELAY EIGHT RASTERLINES | ||
+ | 160 VMOV $21, 6 : REM DARK BLUE | ||
+ | 170 VDELAYV 8 : REM DELAY EIGHT RASTERLINES | ||
+ | 180 VDECA : REM DECREMENT COUNTER | ||
+ | 190 VBRA A% : REM LOOP TO LABEL A% UNLESS COUNTER REACHED ZERO | ||
+ | 999 VEND : REM ALWAYS CLOSE DISPLAYLIST OFF | ||
+ | </ | ||
+ | |||
+ | FUNCTION: Returns assembled [[: | ||
+ | |||
+ | __Synopsis__: | ||
+ | |||
+ | __Examples__: | ||
+ | A = VDECA : REM ASSEMBLE AND ASSIGN THE RESULT TO A VARIABLE | ||
+ | |||
+ | ==== VDECB ==== | ||
+ | ---- | ||
+ | DISPLAYLIST: | ||
+ | |||
+ | STATEMENT: Assembles [[: | ||
+ | |||
+ | __Synopsis__: | ||
+ | |||
+ | __Examples__: | ||
+ | VDECB : REM DECREMENT COUNTER B | ||
+ | |||
+ | FUNCTION: Returns assembled [[: | ||
+ | |||
+ | __Synopsis__: | ||
+ | |||
+ | __Examples__: | ||
+ | B = VDECB : REM ASSEMBLE AND ASSIGN THE RESULT TO A VARIABLE | ||
+ | |||
+ | ==== VDELAYH ==== | ||
+ | ---- | ||
+ | DISPLAYLIST: | ||
+ | |||
+ | STATEMENT: Assembles and stores [[: | ||
+ | |||
+ | __Synopsis__: | ||
+ | * CYCLES is a 6-bit integer number in the range 0..63 | ||
+ | |||
+ | __Examples__: | ||
+ | VDELAYH 3 : REM WAIT THREE CYCLES | ||
+ | |||
+ | FUNCTION: Returns assembled [[: | ||
+ | |||
+ | __Synopsis__: | ||
+ | * CYCLES is a 6-bit integer number in the range 0..63 | ||
+ | |||
+ | __Examples__: | ||
+ | PRINT VDELAYH(3)& | ||
+ | |||
+ | __Discussion__: | ||
+ | |||
+ | The ''< | ||
+ | |||
+ | ==== VDELAYV ==== | ||
+ | ---- | ||
+ | DISPLAYLIST: | ||
+ | |||
+ | STATEMENT: Assembles [[: | ||
+ | |||
+ | __Synopsis__: | ||
+ | * RASTERLINES is a 9-bit integer number in the range 0..511 | ||
+ | |||
+ | __Examples__: | ||
+ | VDELAYV $28 : REM WAIT FORTY RASTERLINES | ||
+ | |||
+ | FUNCTION: Returns assembled [[: | ||
+ | |||
+ | __Synopsis__: | ||
+ | * RASTERLINES is a 9-bit integer number in the range 0..511 | ||
+ | |||
+ | __Examples__: | ||
+ | PRINT VDELAYV(200)& | ||
+ | |||
+ | __Discussion__: | ||
+ | |||
+ | Vertical delay AKA '' | ||
+ | <code basic [highlight_lines_extra=" | ||
+ | VCFG 0,0 | ||
+ | VWAIT $50,20 | ||
+ | VDELAYV 10 | ||
+ | VMOV $20,0 | ||
+ | VMOV $20,14 | ||
+ | VEND | ||
+ | </ | ||
+ | |||
+ | will NOT show the expected black dash, even if your display device is capable of showing all of the picture generated by the computer((Professional monitors are typically equipped with " | ||
+ | |||
+ | ==== VEND ==== | ||
+ | ---- | ||
+ | DISPLAYLIST: | ||
+ | |||
+ | STATEMENT: Assembles [[: | ||
+ | |||
+ | __Synopsis__: | ||
+ | |||
+ | __Examples__: | ||
+ | VEND : REM END OF DISPLAYLIST | ||
+ | |||
+ | FUNCTION: Returns assembled [[: | ||
+ | |||
+ | __Synopsis__: | ||
+ | |||
+ | __Examples__: | ||
+ | A = VEND() : REM STORE ASSEMBLED END OF DISPLAYLIST BYTES IN A VARIABLE | ||
+ | |||
+ | ==== VIRQ ==== | ||
+ | ---- | ||
+ | DISPLAYLIST: | ||
+ | |||
+ | STATEMENT: Assembles and stores [[: | ||
+ | |||
+ | __Synopsis__: | ||
+ | |||
+ | __Examples__: | ||
+ | VIRQ : REM TRIGGER INTERRUPT REQUEST | ||
+ | |||
+ | FUNCTION: Returns assembled [[: | ||
+ | |||
+ | __Synopsis__: | ||
+ | |||
+ | __Examples__: | ||
+ | ?VIRQ() : REM PRINT IRQ AS 8-BIT NUMBER | ||
+ | |||
+ | __Discussion__: | ||
+ | |||
+ | Check also [[: | ||
+ | |||
+ | ==== VMASKH ==== | ||
+ | ---- | ||
+ | DISPLAYLIST: | ||
+ | |||
+ | STATEMENT: Assembles and stores [[: | ||
+ | |||
+ | __Synopsis__: | ||
+ | * MASKVALUE is a 6-bit wide bit mask number in the range 0..63 | ||
+ | |||
+ | __Examples__: | ||
+ | VMASKH 7 : REM ONLY THREE LOWER BITS COUNT ON NEXT HORIZONTAL COMPARISON | ||
+ | |||
+ | FUNCTION: Returns [[: | ||
+ | |||
+ | __Synopsis__: | ||
+ | * MASKVALUE is a 6-bit wide bit mask number in the range 0..63 | ||
+ | |||
+ | __Examples__: | ||
+ | ?VMASKH(7) : REM PRINT ASSEMBLED MASKH WITH P BIT CLEARED AND THREE LSB ACTIVE | ||
+ | |||
+ | __Discussion__: | ||
+ | |||
+ | Setting non-standard mask value right before '' | ||
+ | |||
+ | ==== VMASKPH ==== | ||
+ | ---- | ||
+ | DISPLAYLIST: | ||
+ | |||
+ | STATEMENT: Assembles and stores [[: | ||
+ | |||
+ | __Synopsis__: | ||
+ | * MASKVALUE is a 6-bit wide bit mask number in the range 0..63 | ||
+ | |||
+ | __Examples__: | ||
+ | VMASKPH 7 : REM ONLY THREE LOWER BITS COUNT ON HORIZONTAL COMPARISONS | ||
+ | |||
+ | FUNCTION: Returns [[: | ||
+ | |||
+ | __Synopsis__: | ||
+ | * MASKVALUE is a 6-bit wide bit mask number in the range 0..63 | ||
+ | |||
+ | __Examples__: | ||
+ | ?VMASKPH(7) : REM PRINT ASSEMBLED MASKH P BIT SET AND THREE LSB ACTIVE | ||
+ | |||
+ | __Discussion__: | ||
+ | |||
+ | Setting non-standard mask value right before '' | ||
+ | |||
+ | ==== VMASKPV ==== | ||
+ | ---- | ||
+ | DISPLAYLIST: | ||
+ | |||
+ | STATEMENT: Assembles [[: | ||
+ | |||
+ | __Synopsis__: | ||
+ | * MASKVALUE is a 9-bit wide bit mask number in the range 0..511 | ||
+ | |||
+ | __Examples__: | ||
+ | VMASKPV 127 : REM SEVEN LOWER BITS COUNT ON VERTICAL COMPARISONS | ||
+ | |||
+ | FUNCTION: Returns [[: | ||
+ | |||
+ | __Synopsis__: | ||
+ | * MASKVALUE is a 9-bit wide bit mask number in the range 0..511 | ||
+ | |||
+ | __Examples__: | ||
+ | PV = VMASKPV(127) : REM SEVEN LOWER BITS COUNT ON VERTICAL COMPARISONS | ||
+ | |||
+ | __Discussion__: | ||
+ | |||
+ | Setting non-standard mask value right before '' | ||
+ | |||
+ | ==== VMASKV ==== | ||
+ | ---- | ||
+ | DISPLAYLIST: | ||
+ | |||
+ | STATEMENT: Assembles [[: | ||
+ | |||
+ | __Synopsis__: | ||
+ | * MASKVALUE is a 9-bit wide bit mask number in the range 0..511 | ||
+ | |||
+ | __Examples__: | ||
+ | VMASKV 127 : REM SEVEN LOWER BITS COUNT ON NEXT VERTICAL COMPARISON | ||
+ | |||
+ | FUNCTION: Returns [[: | ||
+ | |||
+ | __Synopsis__: | ||
+ | * MASKVALUE is a 9-bit wide bit mask number in the range 0..511 | ||
+ | |||
+ | __Examples__: | ||
+ | V = VMASKV(127) : REM SEVEN LOWER BITS COUNT ON NEXT VERTICAL COMPARISON | ||
+ | |||
+ | __Discussion__: | ||
+ | |||
+ | Setting non-standard mask value right before '' | ||
+ | |||
+ | ==== VMOV ==== | ||
+ | ---- | ||
+ | DISPLAYLIST: | ||
+ | |||
+ | STATEMENT: Assembles [[: | ||
+ | |||
+ | __Synopsis__: | ||
+ | * REGISTER is a 6-bit number in the range 0..63 | ||
+ | * VALUE is an 8-bit number in the range of 0..255 | ||
+ | |||
+ | __Examples__: | ||
+ | VMOV $20,3 : REM SET BORDER COLOUR TO CYAN | ||
+ | |||
+ | VMOV $43,128 : REM STROBE DISPLAYLIST EXECUTION IN ANOTHER BANK | ||
+ | |||
+ | FUNCTION: Returns assembled [[: | ||
+ | |||
+ | __Synopsis__: | ||
+ | * REGISTER is a 6-bit number in the range 0..63 | ||
+ | * VALUE is an 8-bit number in the range of 0..255 | ||
+ | |||
+ | __Examples__: | ||
+ | BR = VMOV($20,3) : REM STORE ASSEMBLED VMOV TO A VARIABLE | ||
+ | |||
+ | SR = VMOV($43, | ||
+ | |||
+ | __Discussion__: | ||
+ | |||
+ | REGISTER can refer to either VIC-II or VASYL register. Depending on REGISTER value falling into one of the three possible ranges it can refer to | ||
+ | - '' | ||
+ | - '' | ||
+ | - '' | ||
+ | |||
+ | Please note that writing to VIC-II and VASYL registers from within a displaylist program differs substantially in the way it is technically executed. Writing to VIC-II registers requires bus access and cannot happen during time periods when VIC occupies the bus completely (e. g. during " | ||
+ | |||
+ | ==== VNOP ==== | ||
+ | ---- | ||
+ | DISPLAYLIST: | ||
+ | |||
+ | STATEMENT: Assembles [[: | ||
+ | |||
+ | __Synopsis__: | ||
+ | |||
+ | __Examples__: | ||
+ | VNOP : REM USE A CYCLE | ||
+ | |||
+ | FUNCTION: Returns assembled [[: | ||
+ | |||
+ | __Synopsis__: | ||
+ | |||
+ | __Examples__: | ||
+ | NP = VNOP() : REM ASSIGN ASSEMBLED VNOP TO A VARIABLE | ||
+ | |||
+ | __Discussion__: | ||
+ | |||
+ | As useless as it looks, among other uses: | ||
+ | * cheap yet precise fine-tuning of displaylist program timing | ||
+ | * displaylist program space reservations | ||
+ | * address alignment of displaylist program sections | ||
+ | * … | ||
+ | can be achieved by careful placement of VNOP opcodes in the displaylist programs. | ||
+ | |||
+ | ==== VSETA ==== | ||
+ | ---- | ||
+ | DISPLAYLIST: | ||
+ | |||
+ | STATEMENT: Assembles [[: | ||
+ | |||
+ | __Synopsis__: | ||
+ | * VALUE is an 8-bit integer number in the range of 0..255 | ||
+ | |||
+ | __Examples__: | ||
+ | VSETA 12 : REM TWELVE TIMES | ||
+ | <code BASIC [highlight_lines_extra=" | ||
+ | 100 VCFG 0,0 : REM ALWAYS CONFIGURE | ||
+ | 110 VWAIT $33,0 : REM WAIT FOR FIRST PAPER LINE | ||
+ | 120 VSETA 12 : REM TWELVE TIMES | ||
+ | 130 VLABEL A% : REM LOOP CODE BEGINS HERE | ||
+ | 140 VMOV $21, 14 : REM LIGHT BLUE | ||
+ | 150 VDELAYV 8 : REM DELAY EIGHT RASTERLINES | ||
+ | 160 VMOV $21, 6 : REM DARK BLUE | ||
+ | 170 VDELAYV 8 : REM DELAY EIGHT RASTERLINES | ||
+ | 180 VDECA : REM DECREMENT COUNTER | ||
+ | 190 VBRA A% : REM LOOP TO LABEL A% UNLESS COUNTER REACHED ZERO | ||
+ | 999 VEND : REM ALWAYS CLOSE DISPLAYLIST OFF | ||
+ | </ | ||
+ | |||
+ | FUNCTION: Returns assembled [[: | ||
+ | |||
+ | __Synopsis__: | ||
+ | * VALUE is an 8-bit integer number in the range of 0..255 | ||
+ | |||
+ | __Examples__: | ||
+ | ? | ||
+ | |||
+ | __Discussion__: | ||
+ | |||
+ | See also [[# | ||
+ | |||
+ | ==== VSETB ==== | ||
+ | ---- | ||
+ | DISPLAYLIST: | ||
+ | |||
+ | STATEMENT: Assemble [[: | ||
+ | |||
+ | __Synopsis__: | ||
+ | * VALUE is an 8-bit integer number in the range of 0..255 | ||
+ | |||
+ | __Examples__: | ||
+ | VSETB 210 | ||
+ | |||
+ | FUNCTION: Returns assembled [[: | ||
+ | |||
+ | __Synopsis__: | ||
+ | * VALUE is an 8-bit integer number in the range of 0..255 | ||
+ | |||
+ | __Examples__: | ||
+ | CNT = VSETB(48) : REM ASSIGN ASSEMBLED SETB TO A VARIABLE | ||
+ | |||
+ | __Discussion__: | ||
+ | |||
+ | See also [[# | ||
+ | |||
+ | ==== VSKIP ==== | ||
+ | ---- | ||
+ | DISPLAYLIST: | ||
+ | |||
+ | STATEMENT: Assembles [[: | ||
+ | |||
+ | __Synopsis__: | ||
+ | |||
+ | __Examples__: | ||
+ | VSKIP : REM SKIP TWO BYTES AFTER NEXT WAIT IF PAST TARGET | ||
+ | |||
+ | FUNCTION: Returns assembled [[: | ||
+ | |||
+ | __Synopsis__: | ||
+ | |||
+ | __Examples__: | ||
+ | ?VSKIP() : REM PRINT ASSEMBLED SKIP VALUE | ||
+ | |||
+ | __Discussion__: | ||
+ | |||
+ | Check also [[: | ||
+ | |||
+ | ==== VWAIT ==== | ||
+ | ---- | ||
+ | DISPLAYLIST: | ||
+ | |||
+ | STATEMENT: Assembles [[: | ||
+ | |||
+ | __Synopsis__: | ||
+ | * H is a 6-bit integer number in the range 0..63 | ||
+ | * V is a 9-bit integer number in the 0..511 range | ||
+ | |||
+ | __Examples__: | ||
+ | VWAIT $26,$0A : REM WAIT UNTIL FIRST VISIBLE CYCLE OF RASTERLINE $26 | ||
+ | |||
+ | |||
+ | FUNCTION: Returns assembled [[: | ||
+ | |||
+ | __Synopsis__: | ||
+ | * H is a 6-bit integer number in the range 0..63 | ||
+ | * V is a 9-bit integer number in the 0..511 range | ||
+ | |||
+ | __Examples__: | ||
+ | WT = VWAIT($26, | ||
+ | |||
+ | __Discussion__: | ||
+ | |||
+ | More information available in the [[: | ||
+ | |||
+ | ==== VWAITBAD ==== | ||
+ | ---- | ||
+ | DISPLAYLIST: | ||
+ | |||
+ | STATEMENT: Assemble [[: | ||
+ | |||
+ | __Synopsis__: | ||
+ | |||
+ | __Examples__: | ||
+ | VWAITBAD : REM WAIT FOR A LINE BEFORE NEXT BADLINE | ||
+ | |||
+ | FUNCTION: Return assembled [[: | ||
+ | |||
+ | __Synopsis__: | ||
+ | |||
+ | __Examples__: | ||
+ | ?VWAITBAD() | ||
+ | |||
+ | __Discussion__: | ||
+ | |||
+ | Check also notes at [[: | ||
+ | |||
+ | ==== VWAITREP ==== | ||
+ | ---- | ||
+ | DISPLAYLIST: | ||
+ | |||
+ | STATEMENT: Assemble [[: | ||
+ | |||
+ | __Synopsis__: | ||
+ | |||
+ | __Examples__: | ||
+ | VWAITREP 0 : REM WAIT FOR PORT 0 TO FINISH REPEATING WRITES | ||
+ | |||
+ | FUNCTION: Returns assembled [[: | ||
+ | |||
+ | __Synopsis__: | ||
+ | |||
+ | __Examples__: | ||
+ | WR = VWAITREP(0) : REM ASSIGN ASSEMBLED WAITREP TO A VARIABLE | ||
+ | |||
+ | __Discussion__: | ||
+ | |||
+ | Check [[: | ||
+ | |||
+ | ==== VXFER ==== | ||
+ | ---- | ||
+ | DISPLAYLIST: | ||
+ | |||
+ | STATEMENT: Assembles [[: | ||
+ | |||
+ | __Synopsis__: | ||
+ | * < | ||
+ | * < | ||
+ | |||
+ | __Examples__: | ||
+ | VXFER $20,1 : REM READ BYTE FROM PORT1 WRITE TO EXTCOL ($D020) | ||
+ | <code basic [highlight_lines_extra=" | ||
+ | 100 REM PREPARE DATA - STORE $00 TO $0F STARTING AT $100 | ||
+ | 110 FOR I=0 TO 15:POKE $100+I, | ||
+ | 120 VCFG 0,0 : REM CONFIGURE PORT0 | ||
+ | 130 REM CONFIGURE PORT1 FROM WITHIN THE DISPLAYLIST | ||
+ | 140 VMOV $38,15:VMOV $39,1 : REM POINT IT TO $10F | ||
+ | 150 VMOV $3A,255 : REM WITH STEP -1 | ||
+ | 160 VSETA 15 : REM OUR COLOUR COUNTER | ||
+ | 170 VWAIT $26,$0A : REM WAIT UNTIL FIRST VISIBLE CYCLE OF RASTERLINE $26 | ||
+ | 180 LABEL A% : REM LOOP TARGET | ||
+ | 190 VXFER $20,1 : REM TRANSFER TO EXTCOL REGISTER FROM PORT1 | ||
+ | 200 VDECA | ||
+ | 210 VBRA A% : REM BRANCH TO PREVIOUSLY DEFINED LABEL | ||
+ | 999 VEND | ||
+ | 1000 DLON | ||
+ | </ | ||
+ | |||
+ | FUNCTION: Returns assembled [[: | ||
+ | |||
+ | __Synopsis__: | ||
+ | * REGISTER is a 7-bit unsigned integer in the range 0..127 | ||
+ | * PORT is a 1-bit unsigned value in the range 0..1 | ||
+ | |||
+ | __Examples__: | ||
+ | ? | ||
+ | |||
+ | __Discussion__: | ||
+ | |||
+ | There are seven bits reserved for REGISTER value, even if currently only numbers in the range of $00..$4e are valid. XFER does not require port to be set for reading. See also [[: | ||
+ | |||
+ | ====== Program Examples ====== | ||
+ | TBD | ||
vbasic.1599989977.txt.gz · Last modified: 2020/09/13 02:39 by silverdr