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 unpack import 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:KEYOFF 20 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 -- ___________________________________ Demoscene-Produktionen: 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. |