10 REM sg84demo.bas by KMRH 19880516 20 REM This program demonstrates how commands can be defined, 30 REM in compiled BASIC, to drive the SG84. 100 EXCLUDE SCAN 120 SG84% = &0F90 : ACRTC% = SG84% + 0 132 SREG% = ACRTC% + 0: AREG% = ACRTC% + 0 134 DREG% = ACRTC% + 1: DMAREG% ACRTC% + 2 150 PALETTE% = SG84% + 4 160 PAREG% = PALETTE% + 0: PDREG% = PALETTE% + 1: PMREG% = PALETTE% + 2 500 ccrh% = 2: ccr1% = 0: omrh% &C0: omr1% = &18: dcrh% = &40: dcr1% = &01 540 hsr% = &C710: hdr% = &0F9F: vsr% = &0138: vdr% = &1114: bcr% = 0 560 sswr1% = &0100: sar1h% = &0000: sar1l% = 0 572 mwr1% = 162 : cdr% = &C000: zfr% = &0000 800 xres% = 648 : yres% = 256 810 pix_word% = 4: curs_f lag% = 0 830 store_col% = 0: store_scr% = 0: winxstart% = 0: winystart% = 0 890 magx% = 1 : magy% = 1: opm% = 3 950 DIM store_cur(2,3): off% = 0: on% = 1: debugging% = 0 955 DIM X%(2), Y%(2), dX%(2), dY%(2): REM for test3 960 DIM qx%(2, 128), qy%(2, 128): REM global 972 go
1020 DEF wr_bd(reg%,byte%) 1022 OUT AREG%, reg%: OUT DREG%, byte%
1030 DEF wr_wd(word%) 1040 OUT DREG%, ((word% AND &FF00)/ 256 AND &FF): OUT DREG%, word%
1080 DEF wr(word%) 1090 LOCAL c% 1100 OUT AREG%, 0 1110 WHILE NOT INP(SREG%) BIT 1 1120 c% = c% + 1: IF c% = 3000 THEN PRINT "wr_fifo timeout ":STOP 1140 WEND 1145 IF debugging% THEN PRINT "wr fifo: "; ~word%, word% 1150 OUT DREG%, ((word% AND &FF00)/ 256 AND &FF): OUT DREG%, word%
1170 DEF wr_par(par%,word%) 1180 wr((par% AND &1F) + &0800): wr(word%)
1200 DEF rd% 1210 LOCAL c%, word% 1220 OUT AREG%, 0 1230 WHILE NOT INP(SREG%) BIT 2 1240 c% = c% + 1: IF c% 3000 THEN PRINT "rd timeout ":STOP 1260 WEND 1270 word% = INP(DREG%) * 256 + INP(DREG%) 1274 IF debugging% THEN PRINT "rd fifo: ";word% 1280 = word%
1290 DEF rd_par(par%) 1300 wr((par% AND &1F) + &0C00) 1310 = rd%
1320 DEF set_ptr 1330 dph% = rd_par(&10) 1340 dpl% = rd_par(&11) 1350 wr_par(&0C, (dph% AND &FFF0)) 1360 wr_par(&0D, (dp1% AND &FFF0))
1380 DEF rel_off 1390 re110% = 0: re112% = 0: re1% 0
1420 DEF rel_on 1430 re110% &0400: re112% = &1000: rel% = 1
1500 DEF ORG(dph%,dp1%) 1510 wr(&0400): wr(dph%): wr(dp1%)
1530 DEF WPR(reg%,word%) l540 wr(&0800 + (reg% AND &1F)): wr(word%)
1560 DEF RPR(reg%) 1570 wr(&0C00 + (reg% AND &1F)) 1580 = rd%
1820 DEF RD 1830 wr(&4400) 1840 = rd%
1880 DEF MOD(word%) 1890 wr(&4C00 + MM%): wr(word%)
1910 DEF CLR(D%,AX%,AY%) 1920 wr(a5800): wr(D%): wr(AX%): wr(AY%)
2130 DEF MOVE(x%,y%) 2140 wr(&8000 + re110%): wr(x%): wr(y%)
J100 SG84
2170 DEF ALINE (x%,y%) 2180 wr(&8800 + rel10% + area% + col% + opm%): wr(x%): wryly%)
2210 DEF RCT(x%,y%) 2220 wr(&9000 + rel10% + area% + col% + opm%): wr(x%): wr(y%)
2380 DEF ELPS(a%,b%,dx% ) 2390 wr( &AC00 + c% + area% + col% + opm% ) 2400 wr( a% ): wr( b% ): wr( dx% )
2610 DEF DOT 2620 wr(&CC00 + area% + col% + opm%)
2720 DEF blck(x%,y%) 2724 set_ptr 2730 CLR(store_co1%, x%/pix_word%, -y%)
2740 DEF colr(col%) 2750 WHEN pix_word% 2760 IS 4 THEN col% = col% AND &000F: store_co1% = col% * &1111 2780 IS = 2 THEN col% = col% AND &00FF: store_co1% = col% * &0101 2790 ELSE PRINT "illegal pix_word% value ! " 3000 ENDWHEN 3010 wr_par(0, store_co1%): REM set both colr registers 3020 wr_par(1, store_co1%)
3030 DEF colrset(colno%,red%,green%,blue%) 3040 OUT PAREG%, colno% 3050 OUT PDREG%, red% 3060 OUT PDREG%, green% 3070 OUT PDREG%, blue%
3080 DEF curs(x%,y%) 3090 MOVE(x%, y%) 3100 IF curs_flag% THEN set_curs
3110 DEF curson(onoff%) 3120 OUT AREG%, CDR% 3130 WHEN onoff% 3140 IS = 0 THEN OUT DREG%, &80: curs_f lag% 0 3150 ELSE OUT DREG%, &AD: curs_flag% = 1 3152 ENDWHEN
3200 DEF set_curs 3610 ALINE (x%, y%) 3620 DOT 3630 IF curs_flag% THEN curs(x%,y%)
3670 DEF origin(screen%,org): REM do 32 bit org * 16 in two steps 3690 LOCAL DPH%, DPL% 3700 DPL% = org * 16 3710 DPH% = ( screen% * &4000 ) + ( org / &01000 AND &FF ) 3720 ORG(DPH%,DPL%)
4999 DEF go 5000 gr_mode(4) 5006 set_palette 5010 rel_off 5510 origin(1,origin0) 5512 wr_par(&C8, 0) :wr_par(&09, -32767) 5516 wr_par(&0A, 639):wr_par(&0B, 32767) 5520 curs(0, 0) 5530 colr(2): cls 5532 test1: test2: test1: test2: test3
5535 DEF test2 5540 MOVE( 300, -128 ) 5550 FOR radius% = 200 TO 2 STEP -1 5560 colr(radius%) 5570 circ(radius%, 1) 5580 NEXT radius%
6000 DEF test1 6002 FOR size% = 250 TO 1 STEP -1 6004 MOVE(0,0) 6005 colr(size%) 6010 RCT(size%*2, -size%) 6020 NEXT size%
6030 DEF test3 6032 colr(4): cls: MOVE(0,0) 6033 FOR n% = 1 TO 2 6034 FOR ptr% = 0 TO &7F: qx%(n%,ptr%) = 0: qy%(n%,ptr%)=0: NEXT ptr% 6036 NEXT n% 6038 X%(1)=20: Y%(1)=20; X%(2)=300: Y%(2) = 100 6040 dX%(1) = -4: dY%(1)= -2: dX%(2) = 2: dY%(2)= 3: colr(7)
6045 WHILE KBD 0 6047 draw_object: REM leaving shift register 6062 FOR n% = 1 TO 2 6063 IF X%(n%) < 0 THEN dX%(n%) = -dX%(n%): REM bounce 6070 IF X%(n%) > xres% THEN dX%(n%) = -dX%(n%) 6073 IF Y%(n%) < 0 THEN dY%(n%) = -dY%(n%) 6081 IF Y%(n%) > yres% THEN dY%(n%) = -dY%(n%) 6085 X%(n%) = X%(n%) + dX%(n%): REM update points 6086 Y%(n%) = Y%<n%) + dY%(n%) 6087 qx%(n%, ptr%) - X%(n%): REM queue in 6088 qy%(n%, ptr%) = Y%(n%) 6090 NEXT n%
6091 draw_object: REM just entered shift register 6092 ptr% ptr% + 1 AND &7F 6120 WEND 6125 EXCLUDE SCAN
6130 DEF draw_object 6140 MOVE (ax%(1, ptr%), -qy%(l,ptr%)): ALINE (qx%(2, ptr%), qy%(2,ptr%))
9000 DEF set_palette 9010 OUT PMREG%, mask%: OUT PAREG%, 0 9020 FOR major% = 0 TO &F8 STEP 8 9030 FOR minor% 0 TO 7 9040 OUT PDREG%, (minor% BIT 2 ) * 63 9041 OUT PDREG%, (minor% BIT 1 ) * 63 9042 OUT PDREG%, (minor% BIT 0 ) * 63 9050 NEXT minor% 9060 NEXT major%
9200 DEF init_acrtc 9210 wr_bd(2, &80) 9230 wr_bd(2, ccrh%>: wr_bd(3, ccr1%) 9240 wr_bd(4, omrh%): wr_bd(5, omr1%) 9250 wr_bd(6, dcrh%): wr_bd(7, dcr1%) 9260 OUT AREG%, &82 9262 wr_wd(hsr%): wr_wd(hdr%) 9265 wr_wd(vsr%): wr_wd(vdr%): wz_wd(sswz1%) 9280 OUT AREG%, &90: wr_wd(bcr%) 9290 OUT AREG%, &CA: wr_wd(mwr1%): wr_wd(sazlh%): wr_wd(sar11%) 9300 OUT AREG%, &DA: wr_wd(mwz3%) 9310 OUT AREG%, &E8: wr_wd(cdr%): wr_wd(zfr%)
This program does not implement all possible graphics commands, but merely a subset which serves to demonstrate the capabilities of the SG84. The ACRTC is initialised, followed by some drawing.
A series of squares and circles are drawn and undrawn, followed by an endless series of lines which are drawn between two points bouncing off the edges of the screen. Each line exists for a predetermined time before being undrawn, to prevent old lines obscuring new ones.
120-160 Define hardware register addresses 500-960 Define global system variables 1020-1022 wr_bd Write byte to specified register 1030-1040 wr_wd Write word to data register. 1080-1150 wr Write word to FIFO 1170-1180 wr_par Write word to specified parameter via FIFO 1200-1280 rd Read word from FIFO 1290-1310 rd_par Read parameter 1320-1360 set_ptr Set display RAM address pointer 1380-1390 rel_off Turn relative drawing off 1420-1430 rel_on Turn relative drawing on
The ARCTC commands below are described in detail in the Hitachi ACRTC manual. Not all commands have been defined in the program, as not all are used. Those which can be either relative or absolute are modified by flags fixed by the rel_on and rel_off commands above.
1500-1510 ORG Origin command 1530-1540 WPR Write word to specified parameter register 0-1F 1560-1580 RPR Read word from specified parameter register 0-1F 1820-1840 RD Read a word of data from the display memory 1880-1890 MOD Modify a word of data from the display memory 1910-1920 CLR Clear rectangle of display memory 2130-2140 MOVE Move current pointer to new X-Y position 2170-2180 ALINE Draws line 2210-2220 RCT Draws rectangle 2380-2400 ELPS Draws ellipse 2610-2620 DOT Draws a single pixel
The commands below build the primitive ACRTC commands into higher level commands.
2720-2730 blck Fills a block of pixels (to nearest word boundary) with current colour 2740-3020 colr Sets current drawing logical colour 3030-3070 colrset Sets physical red/green/blue values of a logical colour 3080-3100 curs Sets cursor x,y position 3110-3152 curson Switches cursor on or off 3200-3630 set curs Draws line and puts cursor at current x,y 3670-3720 origin Set origin address in display memory. 4999-5532 go Run test sequence