| 292 09.11.2024, 12:11 Uhr
 Dresdenboy
 
 
 
 
 | Es ist Wochenende und Zeit für mal wieder etwas Code, und zwar ein vereinfachtes, etwas optimiertes Plasma (noch nicht optisch poliert), mehr zur Demonstration der "Toolchain", um ASM-Code u. ggf. generierte Tabellen in DATA-Zeilen zu wandeln. 
 Benötigt werden für das Beispiel ein ASM-Listing (für den Arnold Assembler wg. Ausgabeformat), namens plasma_bic.asm:
 
 
 | Quellcode: |  | ; b: charloop; hl: ptr to sine/charmap
 ;     charmap at h+1 -> inc/dec h?
 ;     or charmap at de, d as Y pointer with 25 different char/color tables located at xx00h to (xx+24)00h
 ;     and with loop end comparison (e.g. for SF=1)
 
 cpu    z80
 org  0d6d8h
 
 ld hl,sine    ; address of data
 ld a,49h      ; CURS
 out (99h),a   ;
 ld a,0        ; EAD
 out (98h),a
 out (98h),a
 ld a,20h      ; WDAT words
 out (99h),a   ;
 ld c, 25
 .lineloop:
 ld b, 40
 .charloop:
 ld a,b        ; 4 X
 .ofs1:
 add a,0       ; 7 X+Y+ofs1 (self modified)
 add a,c       ; 4 X+Y
 ld l,a        ; 4
 ld d,(hl)     ; 7 d = sin(X+44) in a 256 elements table
 ld a,c        ; 4 Y
 .ofs2:
 add a,0       ; 7 Y+ofs2 (self modified)
 ld l,a        ; 4
 ld a,(hl)     ; 7 a = sin(Y*3/2+34) in a 256 elements table
 sub a,d       ; 4 (sin(Y*3/2+34) + sin(X+44))
 and 62        ; 7 map to 16 color words
 inc h         ; 4
 ld l,a        ; 4
 ld a,(hl)     ; 7 6*(4+7) -> 66 C
 out (98h),a   ; 11
 inc hl        ; 6
 ld a,(hl)     ; 7
 out (98h),a   ; 11
 dec h         ; 4
 djnz .charloop ; 13/8 -> 66+47 = 113 -> 33.2 fps, with just color attribute 90 -> 41.6 fps (outer loop not calculated), unrolled: 77 -> 48.7 fps
 dec c         ; 4
 jr nz,.lineloop ;
 ld a,(frame)
 inc a
 ld (frame),a
 ld l, a        ; use as pointer into sine table
 ld a, (hl)
 ld (.ofs1+1),a
 ret
 
 org 0d800h
 sine:   ; actually 4 full sine waves, but get replaced by half frequency ones in the Python tool
 db 03Fh,045h,04Bh,051h,057h,05Dh,062h,067h,06Ch,070h,073h,077h,079h,07Bh,07Dh,07Eh,07Eh,07Eh,07Dh,07Bh,079h,077h,073h
 db 070h,06Ch,067h,062h,05Dh,057h,051h,04Bh,045h,03Fh,039h,033h,02Dh,027h,021h,01Ch,017h,012h,0Eh,0Bh,07h,05h,03h,01h,0
 db 0,0,1,3,5,7,0Bh,0Eh,012h,017h,01Ch,021h,027h,02Dh,033h,039h
 db 03Fh,045h,04Bh,051h,057h,05Dh,062h,067h,06Ch,070h,073h,077h,079h,07Bh,07Dh,07Eh,07Eh,07Eh,07Dh,07Bh,079h,077h,073h
 db 070h,06Ch,067h,062h,05Dh,057h,051h,04Bh,045h,03Fh,039h,033h,02Dh,027h,021h,01Ch,017h,012h,0Eh,0Bh,07h,05h,03h,01h,0
 db 0,0,1,3,5,7,0Bh,0Eh,012h,017h,01Ch,021h,027h,02Dh,033h,039h
 db 03Fh,045h,04Bh,051h,057h,05Dh,062h,067h,06Ch,070h,073h,077h,079h,07Bh,07Dh,07Eh,07Eh,07Eh,07Dh,07Bh,079h,077h,073h
 db 070h,06Ch,067h,062h,05Dh,057h,051h,04Bh,045h,03Fh,039h,033h,02Dh,027h,021h,01Ch,017h,012h,0Eh,0Bh,07h,05h,03h,01h,0
 db 0,0,1,3,5,7,0Bh,0Eh,012h,017h,01Ch,021h,027h,02Dh,033h,039h
 db 03Fh,045h,04Bh,051h,057h,05Dh,062h,067h,06Ch,070h,073h,077h,079h,07Bh,07Dh,07Eh,07Eh,07Eh,07Dh,07Bh,079h,077h,073h
 db 070h,06Ch,067h,062h,05Dh,057h,051h,04Bh,045h,03Fh,039h,033h,02Dh,027h,021h,01Ch,017h,012h,0Eh,0Bh,07h,05h,03h,01h,0
 db 0,0,1,3,5,7,0Bh,0Eh,012h,017h,01Ch,021h,027h,02Dh,033h,039h
 
 chartable: ; 32 pairs of character code and color attribute
 db 0B0h,05h,0B1h,05h,0B2h,024h,0B1h,024h,0B2h,081h,0DBh,01h,0B0h,029h,0B1h,029h,0DBh,029h,0B1h,023h,0DBh,023h,0B1h
 db 6Bh,0DBh,06Bh,0B1h,04Bh,0B0h,04Bh,0B1h,042h,0B1h,04Ah,0DBh,04Ah,0B2h,0CAh,0B1h,04Eh,0DBh,04Eh,0B1h,0CEh,0B1h,08Eh
 db 0B1h,0CCh,0B1h,08Ch,0B0h,08Ch,0DBh,04h,0B1h,088h,0B2h,088h,0DBh,08h,0B1h,08h,0B0h,8
 
 frame:    db 0
 
 | 
 
 
 und ein Python-Script, auszuführen mit richtigem Pfad für die Binärdatei "plasma_bic.p":
 
 
 | Quellcode: |  | from struct import unpackimport math
 
 print('10 SCREEN 0:LOCATE,,0:CLS:KEYOFF')
 print('20 A=55000!:DEFUSR0=A')
 print('30 READX$: IF X$<>"*" THEN POKEA,VAL("&H"+X$):PRINT ".";:A=A+1:GOTO 30')
 print('40 A=&HD800')
 print('50 READX$: IF X$<>"*" THEN POKEA,VAL("&H"+X$):PRINT ".";:A=A+1:GOTO 50')
 print('60 X=USR0(0):GOTO 60')
 
 linenumber = 1000
 activesegment = 0
 
 with open("plasma_bic.p","rb") as bf:
 header = bf.read(2)
 marker = bf.read(1)[0]
 while marker != 0:
 if marker == 0x81:
 hdr, seg, gran, start, size = unpack("<BBBIH",bf.read(9))
 data = bytearray(bf.read(size))
 if activesegment == 1: # sin table and character LUT
 for s in range (0, 256):
 data[s] = int(math.sin(s*0.0245437*2)*63+63.5)
 i = 0
 endmark = ""
 while size>i:
 if size-i<=20:
 endmark=",*"
 print(linenumber,"DATA", ",".join([hex(d)[2:] for d in data[i:min(size,i+20)]])+endmark)
 linenumber=linenumber+10
 i=i+20
 activesegment = activesegment + 1
 marker = bf.read(1)[0]
 
 | 
 
 
 Letzteres sollte dann auf der Konsole dies ausgeben, was man natürlich auch in eine Textdatei umleiten kann:
 
 
 | Quellcode: |  | 10 SCREEN 0:LOCATE,,0:CLS:KEYOFF20 A=55000!:DEFUSR0=A
 30 READX$: IF X$<>"*" THEN POKEA,VAL("&H"+X$):PRINT ".";:A=A+1:GOTO 30
 40 A=&HD800
 50 READX$: IF X$<>"*" THEN POKEA,VAL("&H"+X$):PRINT ".";:A=A+1:GOTO 50
 60 X=USR0(0):GOTO 60
 1000 DATA 21,0,d8,3e,49,d3,99,3e,0,d3,98,d3,98,3e,20,d3,99,e,19,6
 1010 DATA 28,78,81,87,c6,0,6f,56,79,c6,0,6f,7e,92,e6,3e,24,6f,7e,d3
 1020 DATA 98,23,7e,d3,98,25,10,e5,d,20,e0,3a,40,d9,3c,32,40,d9,6f,7e
 1030 DATA 32,f1,d6,c9,*
 1040 DATA 3f,42,45,48,4b,4e,51,54,57,5a,5d,5f,62,65,67,69,6c,6e,70,72
 1050 DATA 73,75,77,78,79,7a,7b,7c,7d,7d,7e,7e,7e,7e,7e,7d,7d,7c,7b,7a
 1060 DATA 79,78,77,75,73,72,70,6e,6c,69,67,65,62,5f,5d,5a,57,54,51,4e
 1070 DATA 4b,48,45,42,3f,3c,39,36,33,30,2d,2a,27,24,21,1f,1c,19,17,15
 1080 DATA 12,10,e,c,b,9,7,6,5,4,3,2,1,1,0,0,0,0,0,1
 1090 DATA 1,2,3,4,5,6,7,9,b,c,e,10,12,15,17,19,1c,1f,21,24
 1100 DATA 27,2a,2d,30,33,36,39,3c,3f,42,45,48,4b,4e,51,54,57,5a,5d,5f
 1110 DATA 62,65,67,69,6c,6e,70,72,73,75,77,78,79,7a,7b,7c,7d,7d,7e,7e
 1120 DATA 7e,7e,7e,7d,7d,7c,7b,7a,79,78,77,75,73,72,70,6e,6c,69,67,65
 1130 DATA 62,5f,5d,5a,57,54,51,4e,4b,48,45,42,3f,3c,39,36,33,30,2d,2a
 1140 DATA 27,24,21,1f,1c,19,17,15,12,10,e,c,b,9,7,6,5,4,3,2
 1150 DATA 1,1,0,0,0,0,0,1,1,2,3,4,5,6,7,9,b,c,e,10
 1160 DATA 12,15,17,19,1c,1f,21,24,27,2a,2d,30,33,36,39,3c,b0,5,b1,5
 1170 DATA b2,24,b1,24,b2,81,db,1,b0,29,b1,29,db,29,b1,23,db,23,b1,6b
 1180 DATA db,6b,b1,4b,b0,4b,b1,42,b1,4a,db,4a,b2,ca,b1,4e,db,4e,b1,ce
 1190 DATA b1,8e,b1,cc,b1,8c,b0,8c,db,4,b1,88,b2,88,db,8,b1,8,b0,8
 1200 DATA 0,*
 
 | 
 
 
 Die 2 org-Adressen im asm-Listing entsprechen den im RBASIC hinterlegten Startadressen 55000 und 0d800h.
 
 VG,
 Matthias
 --
 ___________________________________
 Produktionen im Rahmen der "The Computer Art Community" (Demoszene): https://demozoo.org/sceners/64936/, YT-Kanal: https://www.youtube.com/@4lpha0ne/videos
 Programmierung seit '86 in BASIC: KC85/3, C64, A1200, PC | ASM: LC-80, C64, KC87, A1200, NeoGeo, PC, Mega 65, µC | Turbo Pascal: BIC, PC | C: RS/6000, Alpha, PC, µC | C++, Java, Javascript, Rust, Lua, Perl, PHP u.a. auf PC
 HW: LC-80, BIC A5105 komplett, KC87, KC85/2-4, KCC, C64s, C16, Plus/4s, A500s, A1200, Mega 65, ESP32s, RasPis, PCs, Laptops, MR 610, ...
 Dieser Beitrag wurde am 09.11.2024 um 12:31 Uhr von Dresdenboy editiert.
 |