From: Herbert Kleebauer on
Just converted the Erde graphics demo to Linux. Maybe somebody can try it
(use the mouse to fly, press any key or button to exit). The source in a
follow up. You can find the DOS and Windows version here:
ftp://137.193.64.130/pub/assembler/erde.zip


#!/bin/bash
name=erde
echo -n>$name
x=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789123
for (( i=0; i<65; i++ )); do eval _$(( $i/62 ))${x:$i:1}=$(( $i&63 )); done
n=0; m=0
(while read -n 1 c; do
case $c in [A-Za-z0-9+/=])
if [ "$c" == "+" ]; then c=11; elif [ "$c" == "/" ]; then c=12;
elif [ "$c" == "=" ]; then c=13; else c=0$c; fi
e=$d; d=$c ; eval c=\$_$c; n=$(( $n*64+$c )); m=$(( $m+1 ))
if [ "$m" == "4" ]; then
echo -n -e \\$(( ($n>>22&7)*100+($n>>19&7)*10+($n>>16&7) ))>>$name
if [ "$e" != "13" ]; then
echo -n -e \\$(( ($n>>14&7)*100+($n>>11&7)*10+($n>>8&7) ))>>$name; fi
if [ "$d" != "13" ]; then
echo -n -e \\$(( ($n>>6&7) *100+($n>>3&7)*10+($n&7) ))>>$name; fi
n=0; m=0
fi
esac
done)<<"---";
f 0VMRgEBAQAAAAAAAAAAAAIAAwABAAAAdIAECDQAAAAAAAAAA A AAADQAIAACAAAAAAAAA AEA
AA AAAAAAAIAECACABAh4CQAAeAkAAAUAAAAAEAAAAQAAAHgJ AAB 4mQQIeJkECBwBAABk MgYA
BgA AAAAQAACJJbTGCghqAGoBagGJ4bsBAAAAuGYAAADNgIP EDD0B 8P//D4MPAgAAo7j GCghq
E2hk iQQI/zW4xgoIieG7AwAAALhmAAAAzYCDxAw9AfD//w +D4QEAA LiAmQQIugwAAA DoqgYA
AHIoZ okdhpkECGaJNYiZBAjoiQcAAInIjVMDg+L86HwHA ACJ6I1WA4 Pi/OhvBwAAM e2+3McK
CL8ABA AAifCJ+ugPCAAAdPWAPdzHCggBD4V/AQAAAcUB xinHg/0Ict0 Ptx3ixwoI jRydCAAA
ADndcsu +3McKCItGDItWEInR99khyqOQmQQIo7yZBAi jyJkECKPgmQQI o/iZBAi jCJoECKMc
mgQIAdCj xJkECKPkmQQIAdAPt0YYg8ArJPwPtlYdwe IDAcKLBBajlJkEC ItEFh SjnJkECC0A
AcgA0egl/ 3///6PsmQQIuIyZBAi6LAAAAOipBgAAu LiZBAi6CAAAAOiaBg AAu MCZBAi6HAAA
AOiLBgAAuP SZBAi6DAAAAOh8BgAA6LcAAADobwIA ALgAmgQIuhgAAADoYwY A AOiZBgAAgDgA
D4SJAAAAgDg CD4SAAAAAgDgEdHuAOAZ137gYmgQ IuggAAADoMwYAAOhpBgAA gDgAD4RZAAAA
gDgCdFSAOAR0 T4A4AXXji0AUPcgAyAB0qYsNjJ oECI2UATj///+LDZCaBAjB 6 BApwYHi//8A
AIHByAAAAIkVj JoECIHh//8AAIkNkJoECOjOA QAA6Vr///+7AAAAALgBAAA AzY C7AAAAALgN
AAAAzYA9AfD//w +D3f///wwBo5yaBAj8viCa BAi/oJoECIsOg8YECcl0FY sGg8Y EixaDxgSJ
B4PHBAHQ4vfr4jH biJugngUIZrmAgOjYAAA A0O119zH/ioegngUIwOgDi MLQ6gDQ BBCIh6Ce
BghmR3XlZg+2l6Ce BQi5BwAAAL5smgQIrW YBxwKXoJ4FCIDWAGYpx+Lu ZsHqA4iXo J4ECGZH
dc5mD7aHoJ4ECGaDx wMqh6CeBAiA3ABmg +8DZgUgAHkCMcBmg/g/dgK wP4iHoJ4FCG ZHdc3D
PDJ3BYD5BHZBUlC4p0 EAAPclnJoECPc1 iJoECIkVnJoECA+2wcHgAk ghwlgPuiWcmgQ ICXMC
99oB0HgLPf8AAAByBrD /6wIxwFqIg6C eBQjDOM11YFMPtoOgngUIU FMAy1MAywKDoJ4F CIDU
AInC0ehb6In///9bWADP UwDPAoOgng UIgNQAApOgngUIgNYA0ehb 6Gj///8Ay1MAywDPA pOg
ngUIgNYAweoCW4nQ6E3// /9bw9Dp6 JX///8AywDL6Iz///8AzwD P6IP///8oyyjL6Hr/// 8o
zyjP0OHDiy2MmgQIiw2Qmg QIwc0E wckED7fdiM/B7RzB6RyJ6P 7D/sf24Q+2k6CeBAj34on G
uBAAAAAp6FD+y/bhD7aToJ4 ECPf iAcZYgPEP/sH+z/bhD7aToJ4ECPfiAc aJ6P7 D9uEPtpOg
ngQI9+IB8IDEGXMEZrj//6OU mg QIv7SmBwi9ZAAAADX//wIAweAKUFhQMdL 39Y sNjJoECIsd
kJoECMHhCcHjCSnBAcPB6AeJx sHrCDDSicgB8cHoEIj8D7aAoJ4GCIsEhaCa B AiJB4PHBP7K
deBmTYP9BHWzWLIUvhAAAAC5A A IAAE55AjH2iwS1oJoECIkHg8cE4vL+ynXku MgAAAC/rJ4H
CLkAAQAA86u/gAwAAIn+oZCa BAj 30IPgDwHGoZSaBAgx0vf2g8Bko6CeBwgx 0r gAAAEA9/aj
pJ4HCLgAZAAA9yWkngcIweg Qiy2g ngcIKcWJLaymBwi4AKoAAPclpJ4HCMH oEIs toJ4HCCnF
iS2wpgcIweYGiTWongcIg/ 8QdRTHB aCeBwjIAAAAxwWkngcIAAAAAIsNjJ oECMHh DMHmBynx
ix2QmgQIZgH7ZsHjBDH2A w2ongcIic jB6BCIw/7DD7aDoJ4FCP7 LD7aToJ4FCCnQD7fpD6/ F
wfgIhtYB0P80tayiBwiJ BLWsogcI/sM PtoOgngQI/ssPtpOgngQI KdAPt+kPr8XB+AiG1g HQ
9y2kngcIwegQixWgngc IKcKLLLWsngcI iRS1rJ4HCFiB/cgAAAAPj XgAAAA7LLWsngcID 41r
AAAAUFUrBLWsogcImS sstayeBwj3/V1aU VNFOyy1rJ4HCH9IAcIJ7X jwgf3HAAAAfzpm gcoA
wDstsKYHCH4SZoHi/ 787LaymBwh+BWaB8g DAieuG3wHzjRydtKYHCA+ 2zosMjaCaBAi JC+uu
W1lGgf4AAQAAD4Ly /v//g+8QD4VF/v//vrS mBwi5FAAAALjcmQQIuhgA AADoGgEAAI nwugAo
AADoDgEAAGaDBe6 ZBAgKgcYAKAAA4tVmgS3u mQQIyADDUFJXiz20xgoIi weNfIcIi zeDxwSF
9g+EqQAAAIE+SE 9NRXXrgH4EPXXlg8YFg8n/Q YA8DgB1+QnJD4SGAAAAgf kAAQAA d36/vMYK
CPOkuC8uWGGru HV0aG+ruHJpdHmrxgcAu7zGCg gxybgFAAAAzYA9AfD//3N NicO 53McKCLoA
BAAAuAMAAADN gD0ABAAAD4OS+v//icW4BgAAAM2 Ahe10Ir7cxwoIAfUxwGat Zk h0FrkEAAAA
Zq1mwcgIAcb i9jnucuf56yi5AgAAAInLZq1mwcgI Acbi9matZsHICInxicMB3 matZsHICIn1
icb4X1pYw2 CJxYnWagBWVf81uMYKCInhuwkAAAC4Z gAAAM2Ag8QQg/j1dOA9 A fD//w+DBPr/
/ynGdAQBx evNYZDDUVZXoXyZBAiD+CBzO4s1eJkECL /cxwoIiT14mQQIOfd 0CA nAdASJwfOk
ugAEAAAp wo2A3McKCOg+AAAAdQLrNgEFfJkECOu7izV 4mQQIuiAAAACAPg F1EAN WBANWBANW
BANWBDn QcqWJ8CkVfJkECAEVeJkECF9eWcNRU2oAUlD/ NbjGCgiJ4bsKA AAAuGYA AADNgIPE
EFtZg/ j1dBM9AfD//w+DUPn//4XAD4RI+f//wwEAL3Rtc C8uWDExLXVu aXgvWDCQ3 McKCAAA
AABsA AsAAAAAAAAAAAABAAsAAAAAAAAAAAAAAAAAgAKQAQ AAAAAAAAA AAgoAAAAAAA ABAAAA
RQAA AAgAAgAAAAAANwAHAAAAAAAAAAAADQAAAAMAAAD///8 A/4AAAE gCBgoAAAAAAAA AAAAB
CgA AAAAAABgAACoAAwAAAAAAAAAAACkABgAAAAAAAAAAAAAA AAAAA AAAyADIACYAAgAA AAAA
EA AAAGAgIAAEBAQAIAAAAOCgoAABAgIAEAAAAP/g4AD+/f0AQ AAA AABAAAABAgEAQAAAA AAA
Q AABAgIAQAAAAICAgAACAgIAAAAAAAEAAAADAAAAAAEAAAADAA A A////AP3///7//////w AA
6AMAAOgDAAA=
---
chmod +x $name
#############################################################################
From: Herbert Kleebauer on
Herbert Kleebauer wrote:
> The source in a > follow up.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; erde.mac: simple Linux/X graphics demo ;;
;; ;;
;; graphics based on mars.exe by T.J.Clarke ;;
;; X code based on examples by Frank Kotler ;;
;; ;;
;; use mouse to fly, press any key to exit ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


;===========================================================================
seg32
@=$08048000
code_offset=@@
code_addr:

;--------------------------- ELF header -----------------------------------
dc.l $464c457f,$00010101,0,0,$00030002,1,main,$34,0,0,$00200034,2,0
dc.l 1,code_offset,code_addr,code_addr,code_filez,code_memsz,5,4096
dc.l 1,data_offset,data_addr,data_addr,data_filez,data_memsz,6,4096

;--------------------------- code ------------------------------------------

main: move.l r7,stack_ptr ; save initial stack pointer


; ******************** get socket handle ***************************
moveq.l #0,-(sp) ; no protocol specified
moveq.l #1,-(sp) ; 1: SOCK_STREAM (/usr/include/linux/net.h)
moveq.l #1,-(sp) ; 1: AF_UNIX, AF_LOCAL (/usr/include/linux/socket.h)
move.l r7,r2 ; pointer to parameter for "socket"
move.l #1,r3 ; "socket" (/usr/include/linux/net.h)
move.l #102,r0 ; socketcall (/usr/include/asm/unistd.h)
trap #$80
addq.l #3*4,r7 ; free space for parameters
cmp.l #-4095,r0 ; ERROR
bhs.l err
move.l r0,x_handle


; ********** connect socket to /tmp/.X11-unix/X0" ******************
moveq.l #sockaddr_un_l,-(sp)
move.l #sockaddr_un,-(sp) ; (/usr/include/linux/un.h)
move.l x_handle,-(sp) ; socket handle
move.l r7,r2 ; pointer to parameter for "connect"
move.l #3,r3 ; "connect" (/usr/include/linux/net.h)
move.l #102,r0 ; socketcall (/usr/include/asm/unistd.h)
trap #$80
addq.l #3*4,r7 ; free space for parameters
cmp.l #-4095,r0 ; ERROR
bhs.l err


; ******************* send connect message *************************
move.l #send1,r0 ; pointer to connect message
move.l #send1l,r1

bsr.l get_xauth ; try to read .Xauthority
bcs.b _11 ; no success, let's try without auth.

move.w r3,send1+6 ; insert name length
move.w r5,send1+8 ; insert data length

bsr.l x_send ; send header

move.l r2,r0 ; pointer to name
lea.l 3.b(r3),r1 ; pad to a multiple of 4
andq.l #$fffffffc,r1
bsr.l x_send ; send name

move.l r4,r0 ; pointer to data
lea.l 3.b(r5),r1 ; pad to a multiple of 4
andq.l #$fffffffc,r1
_11: bsr.l x_send ; send data

eor.l r4,r4 ; number of total bytes read
move.l #buf2,r5 ; pointer to buffer for next read
move.l #buf2l,r6 ; max. bytes to read

_10: move.l r5,r0
move.l r6,r1
bsr.l x_receive_raw
beq.b _10 ; but we need a reply

cmp.b #1,buf2 ; success
bne.l err ; something went wrong

add.l r0,r4 ; total read bytes
add.l r0,r5 ; pointer to buffer for next read
sub.l r0,r6 ; max. bytes to read
cmpq.l #8,r4 ; at least 8 bytes read?
blo.b _10 ; no, get more

movu.wl buf2+6,r3 ; additional data in 4 bytes
lea.l 8(r3*4),r3 ; total size in bytes
cmp.l r3,r4 ; all read
blo.b _10 ; no, get more

; ******************* calculate id's *******************************
move.l #buf2,r5
move.l $0c.b(r5),r0 ; resource_id_base

move.l $10.b(r5),r1 ; resource_id_mask
move.l r1,r2
neg.l r2
and.l r2,r1 ; resource_id_incr

move.l r0,s2a ; wid for CreateWindow
move.l r0,s3a ; wid for MapWindow
move.l r0,s4a ; wid for CreateDC
move.l r0,s5a ; wid for CreateDC
move.l r0,s6a ; wid for SetInputFocus
move.l r0,s7a ; wid for WrapPointer
move.l r0,s8a ; wid for QueryPointer

add.l r1,r0 ; next id
move.l r0,s4b ; cid for CreateDC
move.l r0,s5b ; cid for CreateDC

add.l r1,r0 ; next id
; move.l r0,resource_id_next ; maybe we need more id's later
; move.l r1,resource_id_incr ; maybe we need more id's later


; ******************* get root window id ***************************
movu.wl $18.b(r5),r0 ; length of vendor string
addq.l #$28+3,r0 ; const header length + round vendor length
and.b #$fc,r0 ; round to 4 bytes

movu.bl $1d.b(r5),r1 ; number of FORMATs
lsl.l #3,r1 ; 8 byte for each FORMAT entry
add.l r0,r1 ; offset to root WINDOW id

move.l (r5,r1),r0 ; root window
move.l r0,s2b ; CreateWindow needs root window id

move.l 20.b(r5,r1),r0 ; width/hight of root window
move.l r0,s2x ; create window full size

sub.l #(200<<16)+256,r0
lsr.l #1,r0
and.l #$ffff7fff,r0
move.l r0,s5x ; center drawing


; ******************* send CreatWindow request *********************
move.l #send2,r0
move.l #send2l,r1
bsr.l x_send

; ******************* send MapWindow request ***********************
move.l #send3,r0
move.l #send3l,r1
bsr.l x_send

; ******************* send CreatDC request *************************
move.l #send4,r0
move.l #send4l,r1
bsr.l x_send

; ******************* send SetInputFocust *************************
move.l #send6,r0
move.l #send6l,r1
bsr.l x_send


; ******************** main loop ***************************

bsr.l init
bsr.l zeichne

_40: move.l #send7,r0 ; WrapPointer
move.l #send7l,r1
bsr.l x_send

_50:
bsr.l x_receive
cmp.b #0,(r0) ; error message
beq.l err
cmp.b #2,(r0) ; KeyPress
beq.l ende
cmp.b #4,(r0) ; ButtonPress
beq.b ende

cmp.b #6,(r0) ; MotionNotify
bne.b _50 ; ignor anything else

move.l #send8,r0 ; QueryPointer
move.l #send8l,r1
bsr.l x_send

_60: bsr.l x_receive
cmp.b #0,(r0) ; error message
beq.l err
cmp.b #2,(r0) ; KeyPress
beq.b ende
cmp.b #4,(r0) ; ButtonPress
beq.b ende

cmp.b #1,(r0)
bne.b _60 ; skip any MotionNotify and wait until
; reply for Query pointer (needed for slow CPU)


move.l 20.b(r0),r0 ; win-y, win-x
cmp.l #$00c800c8,r0 ; x=200 y=200
beq.b _50 ; ja
move.l kamera_x,r2 ; kamera_x
lea.l -200(r2,r0),r1 ; kamera_x + (maus_x-200) in low word
move.l kamera_y,r2 ; kamera_y
lsr.l #16,r0 ; maus_y
sub.l r0,r2 ; kamera_y-maus_y
and.l #$0000ffff,r1 ; [kamera_x + (maus_x-200)] % 0xffff
add.l #200,r2 ; kamera_y-(maus_y-200)
move.l r1,kamera_x ; kamera_x
and.l #$0000ffff,r2 ; [kamera_y-(maus_y-200)] & 0xffff
move.l r2,kamera_y ; kamera_y

bsr.l zeichne
br.l _40

err:
ende: move.l #0,r3 ; return code
move.l #1,r0 ; exit
trap #$80


;#######################################################################
;## Start Initialisierung der Datenfelder ##
;#######################################################################

init:
move.l #0,r3 ; NULL pointer
move.l #13,r0 ; time (/usr/include/asm/unistd.h)
trap #$80
cmp.l #-4095,r0 ; ERROR
bhs.l err
or.b #1,r0 ; nicht 0
move.l r0,rand ; als Startwert benutzen
bclr.w #10,sr ; loesche direction flag

;***********************************************************************
;** 256 Farben rgb Tabelle erstellen **
;***********************************************************************


move.l #ftab,r5 ; Tabelle: Anzahl, Startwert, Increment
move.l #f_tab,r6 ; rgb Tabelle
_30: move.l (r5),r2 ; Anzahl
addq.l #4,r5
or.l r2,r2 ; 0?
beq.b _10 ; ja, dann fertig
move.l (r5),r0 ; Sartwert
addq.l #4,r5
move.l (r5),r1 ; Increment
addq.l #4,r5
_20: move.l r0,(r6) ; in rgb Tabelle speichern
addq.l #4,r6
add.l r1,r0 ; + Increment
dbf.l r2,_20 ; Anzahl x durchlaufen
br.b _30
_10:


;***********************************************************************
;** 256x256 fraktales Zufallsfeld tmp(x,y) erzeugen **
;***********************************************************************

make_fraktal: ; Gelaende-Farbe Segment als temporaeren
; Speicher fuer fraktales Feld benutzen

eor.l r3,r3 ; linke unter Ecke des Startquadrats
move.b r3,g_farbe(r3) ; starte mit Hoehe 0 an (0,0)
move.w #$8080,r2 ; m2=Seitenlaenge zu berechnender Quadrate
; r2=halbe aktuelle Seitenlaeng
_10: bsr.l fraktal ; rekursiv aufrufen
lsr.b #1,m2 ; naechst kleinere Granularitaet
bne.b _10


;***********************************************************************
;** Himmel-Farbe aus Tmp-Feld erzeugen: himmel(x,y)=tmp(x,y)*3/16+16 **
;** **
;** Farbe_des_Himmels (x,y) = himmel(x/128,y/128) **
;** **
;***********************************************************************

make_himmel:
eor.l r6,r6
_10: move.b g_farbe(r6),r0
lsr.b #3,r0
move.b r0,r1
lsr.b #1,r1
add.b r1,r0
add.b #16,r0
move.b r0,h_farbe(r6)
inc.w r6
bne.b _10


;***********************************************************************
;** Gelaende-Hoehe aus Temp-Feld durch Glaettung erzeugen: **
;** **
;** erde(x,y)=[tmp(x,y) +tmp(x+1,y)+tmp(x+3,y)+tmp(x,y+1)+ **
;** tmp(x,y+3)+tmp(x,y-1)+tmp(x,y-3)+tmp(x-2,y)]/8 **
;** **
;** Hoehe_des_Gelaende (x,y) = 256 * erde[x/16,y/16] **
;** **
;***********************************************************************

make_erde: ; r6.l=0
_10: movu.bw g_farbe(r6),r1 ; eigener Wert
move.l #7,r2 ; 7 Nachbarwerte
move.l #gtab,r5 ; welche Nachbarn
_20: move.l (r5)+-,r0
add.w r0,r6
add.b g_farbe(r6),r1 ; Nachbarwert addieren
addc.b #0,m1
sub.w r0,r6
dbf.l r2,_20
lsr.w #3,r1 ; durch 8 teilen
move.b r1,g_hoehe(r6) ; abspeichern
inc.w r6
bne.b _10


;***********************************************************************
;** Gelaende-Farbe aus Gelaende-Hoehe erzeugen: **
;** **
;** farbe(x,y)=[erde(x,y)-erde(x+3,y)]+32 min 0 max 63 **
;** **
;** Farbe_des_Gelaende (x,y) = 256 * farbe[x/16,y/16] **
;** **
;***********************************************************************

make_farbe: ; r6.l=0
_10: movu.bw g_hoehe(r6),r0
addq.w #3,r6
sub.b g_hoehe(r6),r0
subc.b #0,m0
subq.w #3,r6
add.w #32,r0
bpl.b _20
eor.l r0,r0
_20: cmpq.w #63,r0
bls.b _30
move.b #63,r0
_30: move.b r0,g_farbe(r6)
inc.w r6
bne.b _10
rts.l

;#######################################################################
;## Ende Initialisierung der Datenfelder ##
;#######################################################################



;***********************************************************************
;** Zufallszahlengenerator **
;** **
;** input: r2.b = 2^n 0<=n<=7 **
;** **
;** r0.l = r0.l + random ; -2^(n+1) < random < +2^(n+1) **
;***********************************************************************

random:

cmp.b #50,r0 ; Gelaende ueber 50 wie bisher
bhi.b _11
cmp.b #4,r2 ; fuer r2=1,2,4 keine Zufallszahl
bls.b _31
_11:

move.l r1,-(sp)
move.l r0,-(sp)
move.l #16807,r0
mulu.l rand,r0,r1|r0 ; r1|r0 = rand*16807
divu.l cffff,r1|r0 ; r1 = (rand*16807) mod $ffff
move.l r1,rand

movu.bl r2,r0
lsl.l #2,r0 ; 2^(n+2)
dec.l r0 ;
and.l r0,r1 ; nur Bit (n+1)..0 in r0

move.l (sp)+,r0
btst.l #9,rand ; Bit 9 als Vorzeichen verwenden
bcc.b _10 ; positiv
neg.l r1 ; nein, dann negieren
_10: add.l r1,r0 ; auf altes r0 addieren
bmi.b _20 ; <0
cmp.l #255,r0 ; >255
blo.b _30 ; nein, dann ok
move.b #255,r0 ; hoechstens 255
br.b _30
_20: eor.l r0,r0 ; falls <0 dann 0 setzen
_30: move.l (sp)+,r1
_31: move.b r0,g_farbe(r3) ; als z() abspeichern
rts.l


;***********************************************************************
;** Fraktalgenerator **
;** **
;***********************************************************************


fraktal:
cmp.b r2,m2 ; richtige Aufruftiefe erreicht
bne.b _10 ; nein

move.l r3,-(sp)
movu.bl g_farbe(r3),r0 ; links unten
move.l r0,-(sp)
move.l r3,-(sp)
add.b r2,r3 ; mitte unten
move.l r3,-(sp)
add.b r2,r3 ; rechts unten
add.b g_farbe(r3),r0 ; z(links unten) + z(rechts unten)
addc.b #0,m0
move.l r0,r1 ; z(links unten) + z(rechts unten)
lsr.l #1,r0 ; [z(links unten) + z(rechts unten)] / 2
move.l (sp)+,r3 ; mitte unten

bsr.l random ; + Zufallszahl
; als z(mitte unten) abspeichern
move.l (sp)+,r3 ; links unten

move.l (sp)+,r0 ; z(links unten)
add.b r2,m3 ; links mitte
move.l r3,-(sp)
add.b r2,m3 ; links oben
add.b g_farbe(r3),r0 ; z(links unten) + z(links oben)
addc.b #0,m0
add.b g_farbe(r3),r1 ; z(links unten) + z(rechts unten) +
addc.b #0,m1 ; + z(links oben)
lsr.l #1,r0 ; [z(links unten) + z(links oben)] / 2
move.l (sp)+,r3 ; links mitte
bsr.l random ; + Zufallszahl
; als z(links mitte) abspeichern

add.b r2,r3 ; mitte mitte
move.l r3,-(sp)
add.b r2,r3 ; rechts mitte
add.b r2,m3 ; recht oben
add.b g_farbe(r3),r1 ; z(links unten) + z(rechts unten) +
addc.b #0,m1 ; + z(links oben) + z(recht oben)
lsr.l #2,r1 ; /4
move.l (sp)+,r3 ; mitte mitte
move.l r1,r0
bsr.l random ; + Zufallszahl
; als z(mitte mitte) abspeichern
move.l (sp)+,r3 ; altes r3 zurueck holen
rts.l

_10: lsr.b #1,r2 ; eine Ebene tiefer
bsr.l fraktal ; links unten

add.b r2,r3
add.b r2,r3
bsr.l fraktal ; rechts unten

add.b r2,m3
add.b r2,m3
bsr.l fraktal ; rechts oben

sub.b r2,r3
sub.b r2,r3
bsr.l fraktal ; links oben

sub.b r2,m3
sub.b r2,m3 ; altes r3 zurueck

lsl.b #1,r2 ; altes r2 zurueck
rts.l



;#######################################################################
;## Start Bildergenerierung ##
;#######################################################################


zeichne:

;***********************************************************************
;** Berechen Kamerahoehe: **
;** **
;** x = kamera_x/16 mod 256 y = kamera_y/16 mod 256 **
;** dx = kamera_x mod 16 dy = kamera_y mod 16 **
;** **
;** kamera_z = [erde(x,y) + delta + 25] * 256 **
;** **
;** erde(x,y)+delta = z(x ,y)(16-dx)(16-dy) + z(x+1, y )dx(16-dy) + **
;** z(x,y+1)(16-dx) dy + z(x+1,y+1)dx dy **
;** **
;** **
;***********************************************************************

kamera_hoehe:
move.l kamera_x,r4
move.l kamera_y,r2

ror.l #4,r4 ; r4.b=x
ror.l #4,r2 ; r2.b=y
movu.wl r4,r3
move.b r2,m3 ; r3.l = y*256+x
lsr.l #28,r4 ; r4.l=dx
lsr.l #28,r2 ; r2.l=dy

move.l r4,r0 ; dx
inc.b r3
inc.b m3
mulu.b r2,r0,m0|r0 ; dx*dy
movu.bl g_hoehe(r3),r1 ; erde(x+1,y+1)
mulu.l r1,r0,r1|r0 ; dx*dy*erde(x+1,y+1)
move.l r0,r5

move.l #16,r0
sub.l r4,r0

move.l r0,-(sp)
dec.b r3
mulu.b r2,r0,m0|r0 ; (16-dx)*dy
movu.bl g_hoehe(r3),r1 ; erde(x,y+1)
mulu.l r1,r0,r1|r0 ; (16-dx)*dy*erde(x,y+1)
add.l r0,r5

move.l (sp)+,r0; 16-dx
eor.b #$0f,r2 ; 15-dy
inc.b r2 ; 16-dy
dec.b m3
mulu.b r2,r0,m0|r0 ; (16-dx)*(16-dy)
movu.bl g_hoehe(r3),r1 ; erde(x,y)
mulu.l r1,r0,r1|r0 ; (16-dx)*(16-dy)*erde(x,y)
add.l r0,r5

move.l r4,r0 ; dx
inc.b r3
mulu.b r2,r0,m0|r0 ; dx*(16-dy)
movu.bl g_hoehe(r3),r1 ; erde(x+1,y)
mulu.l r1,r0,r1|r0 ; dx*(16-dy)*erde(x+1,y)
add.l r5,r0

add.b #25,m0 ; Kamera 25 ueber Gelaende
bcc.b _10 ; aber nicht groesser
move.w #$ffff,r0 ; als $ffff
_10: move.l r0,kamera_z ; kamera-hoehe -> kamera_z.w, r0.w


;***********************************************************************
;** Himmel zeichnen **
;***********************************************************************
;** **
;** Der Bildschirm befindet sich ZWEI y-Einheiten vor der Kamera **
;** **
;** **
;** y-z-Ebene: **
;** **
;** **
;** ------------------------------+------ Himmel **
;** /^ **
;** / | **
;** / | **
;** / | **
;** / | 2*2^16 **
;** / | **
;** / | **
;** / v **
;** ............./................+....... 2^16-1 **
;** / | **
;** +------/-Kamera | **
;** | +--/---Bildschirm | **
;** v v/ | 99 **
;** x---------------------------+- <- Bildschirmzeile 100 **
;** yabst ^ 101 **
;** | Kamera-z **
;** v **
;** .............................+....... Null-Linie **
;** **
;** **
;** **
;** x-y-Ebene: **
;** **
;** /^ **
;** / | **
;** / | **
;** / |xlinks = yabst **
;** / | **
;** / |128 Bildschirmpixel entsprechen yabst **
;** / | 1 Bildschirmpixel entspricht dx=yabst/128 **
;** / | **
;** / yabst v **
;** x---------+------ **
;** \ ^ **
;** \ | **
;** \ | **
;** \ | **
;** \ |xrechts = yabst **
;** \ | **
;** \ | **
;** \ | **
;** \v **
;** **
;***********************************************************************

disp_himmel: ; r0.l = kamera-hoehe

move.l #screen,r6
move.l #100,r4 ; Himmel von Bildschirmmitte + 100 Zeilen
; bis Bildschirmmitte + 5 Zeilen

eor.l #$2ffff,r0 ; 2^16-1-kamera_z
lsl.l #10,r0 ; [2*2^16 + (2^16-1 - kamera_z)] * 2^10
move.l r0,-(sp) ; (himmel-kamera_z) * 2^10

_30: move.l (sp)+,r0 ; (himmel-kamera_z) * 2^10
move.l r0,-(sp)

eor.l r1,r1 ; zabst/ybild=yabst/2 -->
divu.l r4,r1|r0 ; zabst*2^10/ybild = yabst*2^9

move.l kamera_x,r2
move.l kamera_y,r3
lsl.l #9,r2 ; kamera_x * 2^9
lsl.l #9,r3 ; kamera_y * 2^9

sub.l r0,r2 ; (kamera_x-yabst)*2^9 = xmin *2^9
add.l r0,r3 ; (kamera_y+yabst)*2^9 = y *2^9
lsr.l #7,r0 ; yabst*2^9 / 128 = dx*2^9
move.l r0,r5
lsr.l #8,r3 ; m3=[y*2^9]hi

eor.b r1,r1
_10: move.l r2,r0 ; x
add.l r5,r2 ; x=x+dx
lsr.l #16,r0 ; r0=[x*2^9]hi
move.b m3,m0 ; r3.l = index in h_farbe
movu.bl h_farbe(r0),r0
move.l f_tab(r0*4),r0 ; rgb Wert holen
move.l r0,(r6)
addq.l #4,r6

dec.b r1 ; alle 256 Spalten einer Zeile?
bne.b _10 ; nein

dec.w r4 ; naechste Zeile
cmpq.l #4,r4 ; bei Bildschirmmitte+5 angekommen?
bne.b _30 ; nein
move.l (sp)+,r0


move.b #40/2,r1 ; dann noch 40 Bildschirmzeilen Wasser
move.l #16,r5 ; Sarte mit Farbe 15

_20: move.l #256*2,r2 ; 2 Zeilen mit gleicher Farbe
dec.l r5 ; naechste Farbe
bpl.b _40 ; >0, dann ok
eor.l r5,r5 ; sonst 0 setzen
_40: move.l f_tab(r5*4),r0 ; rgb Wert holen
move.l r0,(r6)
addq.l #4,r6

dbf.l r2,_40 ; 2 Zeilen
dec.b r1 ; alle 20*2 Zeilen
bne.b _20 ; nein



;***********************************************************************
;** Erde zeichnen **
;***********************************************************************
;** **
;** Der Bildschirm befindet sich EINE y-Einheiten vor der Kamera **
;** **
;** **
;** y-z-Ebene: **
;** **
;** **
;** +-- Kamera **
;** |+- Bildschirm **
;** vv 99 **
;** x---------------------- <- Bildschirmzeile 100 **
;** \ yabst | 101 **
;** \ | **
;** \ | **
;** \ | Kamera-z **
;** \ | **
;** \ | **
;** \ | **
;** ........................\....... Null-Linie **
;** **
;** **
;** **
;** x-y-Ebene: **
;** **
;** /^ **
;** / | **
;** / | **
;** / |xlinks = 2*yabst **
;** / | **
;** / |128 Bildschirmpixel entsprechen 2*yabst **
;** / | 1 Bildschirmpixel entspricht dx=yabst/64 **
;** / | **
;** / yabst v **
;** x---------+------ **
;** \ ^ **
;** \ | **
;** \ | **
;** \ | **
;** \ |xrechts = 2*yabst **
;** \ | **
;** \ | **
;** \ | **
;** \v **
;** **
;***********************************************************************
disp_erde:
move.l #200,r0 ; zalt[0..255] mit Wert>199
move.l #z_alt,r6 ; vorbesetzen
move.l #256,r2 ; r2.w=256
rep_r2 move.l r0,(r6)+-{s1}

move.l #200*16,r6 ; 200 y-Schnitte darstellen
_80: move.l r6,r5 ; yabst

move.l kamera_y,r0 ; Kamera y-Position
not.l r0
andq.l #$0f,r0 ; 15 - die letzten 4 Bits
add.l r0,r5 ; yabst entsprechend korrigieren

move.l kamera_z,r0 ; Kamera z-Position
eor.l r1,r1 ; Hoehe Kamera ueber Nullebene in
divu.l r5,r1|r0 ; Bildschirmpixel -> r0
addq.l #100,r0 ; + Bilschirmmitte
move.l r0,snull ; in snull speichern

eor.l r1,r1 ; Vergroesserungsfaktor (H�ehe einer
move.l #$10000,r0 ; Z-Einheit auf dem Bildschirm = 1/yabst
divu.l r5,r1|r0 ; r0 = (1/yabst) * 2^16
move.l r0,vfakt ; in vfakt speichern

move.l #100<<8,r0
mulu.l vfakt,r0,r1|r0
lsr.l #16,r0
move.l snull,r4
sub.l r0,r4
move.l r4,hoehe100

move.l #170<<8,r0
mulu.l vfakt,r0,r1|r0
lsr.l #16,r0
move.l snull,r4
sub.l r0,r4
move.l r4,hoehe170

lsl.l #6,r5 ; yabst * 2^6 = dx * 2^12
move.l r5,dx
cmpq.l #16,r6 ; letzter Schleifendurchlauf
bne.b _11 ; nein
move.l #200,snull ; ja, dann Nullebene > 199
move.l #0,vfakt ; und Vergroesserungsfaktor = 0

_11: move.l kamera_x,r2 ; Kamera x-Position
lsl.l #12,r2 ; xpos * 2^12
lsl.l #7,r5 ; (128 * dx) * 2^12 = xlinks * 2^12
sub.l r5,r2 ; xstart * 2^12 = (xkamera-xlinks)*2^12

move.l kamera_y,r3 ; Kamera y-Position
add.w r6,r3 ; + Abstand = y
lsl.w #4,r3 ; r3.l= 0|0|y/16|?


eor.l r5,r5 ; 256 Bildschirmpixel pro Zeile
; r3.l= 0|0|y/16|?
; r2.l = (xpos/16)*2^16 = xpos*2^12 = xpos_lo
_60: add.l dx,r2 ; neues x *2^12
move.l r2,r0
lsr.l #16,r0 ; x/16
move.b r0,r3 ; r3.l = 0 | 0 | y/16 | x/16

inc.b r3
movu.bl g_farbe(r3),r0 ; f[(x/16)+1 , (ykamera+yabst)/16] / 2^8
dec.b r3
movu.bl g_farbe(r3),r1 ; - f[(x/16) , (ykamera+yabst)/16] / 2^8
sub.l r1,r0 ; = fdiff / 2^8
movu.wl r2,r4 ; lo word x
muls.l r4,r0,r0 ; * fdiff
asr.l #8,r0 ; /256
exg.b r1,m1 ; r1.l= 0|0|f|0
add.l r1,r0 ; r0.l= 0|0|f|df

move.l f_alt(r5*4),-(sp) ; falt auf Stack
move.l r0,f_alt(r5*4) ; fneu speichern
; keinesfalls exg verwenden! Programm wird
; um Faktor 3 langsamer!!
; exg.l r0,f_alt(r5*4)
; move.l r0,-(sp)
inc.b r3
movu.bl g_hoehe(r3),r0 ; z[(x/16)+1 , (ykamera+yabst)/16] / 2^8
dec.b r3
movu.bl g_hoehe(r3),r1 ; - z[(x/16) , (ykamera+yabst)/16] / 2^8
sub.l r1,r0 ; = zdiff / 2^8
movu.wl r2,r4 ; lo word x
muls.l r4,r0,r0 ; * zdiff
asr.l #8,r0 ; /256
exg.b r1,m1 ; r1.l= 0|0|z|0
add.l r1,r0 ; r0.l= 0|0|z|dz
muls.l vfakt,r0,r1|r0 ; Pixelhoehe<<16
lsr.l #16,r0 ; Pixelhoehe
move.l snull,r1 ; Nullline
sub.l r0,r1 ; zneu=Bildschirmzeile

move.l z_alt(r5*4),r4 ; r4 = zalt
move.l r1,z_alt(r5*4) ; zneu speichern
; keinesfalls exg verwenden! Programm wird
; um Faktor 3 langsamer!!

move.l (sp)+,r0 ; falt
cmp.l #200,r4 ; zu tief
bge.l _20 ; ja
cmp.l z_alt(r5*4),r4 ; zalt >= zneu
bge.l _20 ; ja, dann unsichtbar

move.l r0,-(sp)
move.l r4,-(sp)
sub.l f_alt(r5*4),r0 ; falt-fneu
ext.l r0,r1|r0
sub.l z_alt(r5*4),r4 ; zalt-zneu
divs.l r4,r1|r0 ; df=(falt-fneu)(zalt-zneu)
move.l (sp)+,r4 ; zalt
move.l (sp)+,r1 ; falt

move.l r2,-(sp)
move.l r3,-(sp)
_31: inc.l r4 ; z=z+1
cmp.l z_alt(r5*4),r4 ; z>zneu
bgt.b _43 ; ja, dann fertig
add.l r0,r1 ; f=f+df
or.l r4,r4 ; noch uebrer Bildschirm
bmi.b _31 ; ja, dann nichts zeichnen aber weiter machen
cmp.l #199,r4 ; Bildschirmende erreicht
bgt.b _43 ; ja, dann fertig
or.w #$c000,r1 ; Schnee
cmp.l hoehe170,r4 ; z ubers Schneelinie
ble.b _23 ; dann Farbe ok
and.w #$bfff,r1 ; Fels
cmp.l hoehe100,r4 ; z ueber Felslinie
ble.b _23 ; ja, dann Farbe ok
eor.w #$c000,r1 ; Gras

_23: move.l r4,r3 ; 0<=z<=199
exg.b r3,m3 ; 0|0|z|0
add.l r5,r3 ; 0|0|z|x = index in screen[256*200]
lea.l screen(r3*4),r3 ; 4 byte pro Eintrag

movu.bl m1,r2 ; Farbe
move.l f_tab(r2*4),r2 ; rgb-Werte
move.l r2,(r3)
br.b _31

_43: move.l (sp)+,r3 ; y
move.l (sp)+,r2 ; x
_20: inc.l r5 ; naechste Spalte
cmp.l #256,r5 ; alle 256 Bildschirmspalten
blo.l _60 ; nein
subq.l #16,r6 ; naechster y-Schnitt
bne.l _80

;***********************************************************************
;** auf Bildschirm kopieren **
;***********************************************************************


display:move.l #screen,r5
move.l #20,r2 ; we use 20 parts to make each <16k
_10: move.l #send5,r0
move.l #send5l,r1
bsr.l x_send ; send header
move.l r5,r0
move.l #256*10*4,r1 ; size of one part
bsr.l x_send ; send data
addq.w #10,s5y ; update y pos for next part
add.l #256*10*4,r5 ; update source pointer for next part
dbf.l r2,_10
sub.w #20*10,s5y ; restore original y position
rts.l



;#######################################################################
;## Ende Bildergenerierung ##
;#######################################################################


;**********************************************************
;******** read cookie from $home/.Xauthority **************
;**********************************************************
; *
; input: stack_ptr: original sp at program start *
; output: C=0: cookie found in $home/.Xauthority *
; r2: pointer to protocol name *
; r3: length of protocol name *
; r4: pointer to protocol data *
; r5: length of protocol data *
; C=1: nothing found *
; r2/r3/r4/r5 undefined *
; *
; typedef struct xauth { *
; unsigned short family; *
; unsigned short address_length; *
; char *address; *
; unsigned short number_length; *
; char *number; *
; unsigned short name_length; *
; char *name; *
; unsigned short data_length; *
; char *data; *
; } Xauth; *
;**********************************************************

get_xauth:
move.l r0,-(sp)
move.l r1,-(sp)
move.l r6,-(sp)

move.l stack_ptr,r6 ; original stack pointer at program start
move.l (r6),r0 ; number of arguments
lea.l 8.b(r6,r0*4),r6 ; skip arguments + trailing null pointer

_20: move.l (r6),r5 ; pointer to next env variable
addq.l #4,r6
tst.l r5,r5 ; no more env variables
beq.l _notfound
cmp.l #'EMOH',(r5) ; HOME found?
bne.b _20 ; no, try next
cmp.b #'=',4.b(r5) ; HOME= found?
bne.b _20 ; no, try next
addq.l #5,r5 ; start of HOME path
orq.l #-1,r2
_30: inc.l r2 ; count length of HOME path
cmp.b #0,(r5,r2)
bne.b _30

or.l r2,r2 ; at least one char long?
beq.l _notfound ; no, HOME is empty
cmp.l #256,r2 ; more than 256 charcters
bhi.b _notfound ; somebody tries a buffer overflow
move.l #fname,r6 ; buffer for filename
rep_r2 move.b (r5)+-,(r6)+-{s1} ; copy HOME path
move.l #'aX./',r0 ; add .Xauthority
move.l r0,(r6)+-{s1}
move.l #'ohtu',r0
move.l r0,(r6)+-{s1}
move.l #'ytir',r0
move.l r0,(r6)+-{s1}
move.b #0,(r6) ; and a trailing 0

move.l #fname,r3
eor.l r2,r2 ; readonly
move.l #5,r0 ; open
trap #$80

cmp.l #-4095,r0 ; file open error?
bhs.b _notfound ; yes

move.l r0,r3 ; file handle
move.l #buf2,r2
move.l #buf2l,r1 ; read 1024 byte
move.l #3,r0 ; read
trap #$80

cmp.l #buf2l,r0
bhs.l err ; .Xauthority >= 1024 byte
move.l r0,r4 ; bytes read

move.l #6,r0 ; close
trap #$80

tst.l r4,r4 ; file empty
beq.b _notfound

move.l #buf2,r5
add.l r5,r4 ; end of read data
eor.l r0,r0 ; delete upper 16 bit of r0

_60: move.w (r5)+-,r0 ; family
dec.w r0
beq.b _40 ; 1=FamilyLocal

move.l #4,r2 ; skip entry
_50: move.w (r5)+-,r0
ror.w #8,r0 ; big -> little endian
add.l r0,r5
dbf.l r2,_50
cmp.l r4,r5 ; more data
blo.b _60 ; try next entry

_notfound:
bset.w #0,sr ; set Carry
br.b _70

_40: move.l #2,r2
move.l r2,r3
_41: move.w (r5)+-,r0 ; size of data
ror.w #8,r0 ; big endian <-> little endian
add.l r0,r5 ; skip address/number
dbf.l r2,_41

_42: move.w (r5)+-,r0 ; size of protocol name
ror.w #8,r0 ; big endian <-> little endian
move.l r5,r2 ; pointer to protocol name
move.l r0,r3 ; size of protocol name
add.l r3,r5 ; skip name

move.w (r5)+-,r0 ; size of protocol data
ror.w #8,r0 ; big endian <-> little endian
move.l r5,r4 ; pointer to protocol data
move.l r0,r5 ; size of protocol data
bclr.w #0,sr ; clear carry
_70: move.l (sp)+,r6
move.l (sp)+,r1
move.l (sp)+,r0
rts.l


;**********************************************************
;******** send message to X server **************
;**********************************************************
; input: r0: pointer to message *
; r1: length of message *
;**********************************************************
x_send: movem.l r0-r7,-(sp)
move.l r0,r4 ; pointer to next byte of message
move.l r1,r5 ; remaining bytes to send

_20: moveq.l #0,-(sp) ; flags
move.l r5,-(sp) ; length
move.l r4,-(sp) ; pointer to data
move.l x_handle,-(sp) ; socket handle
move.l r7,r2 ; pointer to parameter for "send"
move.l #9,r3 ; "send" (/usr/include/linux/net.h)
move.l #102,r0 ; socketcall (/usr/include/asm/unistd.h)
trap #$80
addq.l #4*4,r7 ; free space for parameters

cmpq.l #-11,r0 ; EAGAIN:
beq.b _20 ; message couldn't be sent, try again

cmp.l #-4095,r0 ; ERROR
bhs.l err

sub.l r0,r5 ; remaining bytes to send
beq.b _30 ; nothing, all sent
add.l r0,r4 ; pointer to remaining message
br.b _20 ; send rest of message

_30: movem.l (sp)+,r0-r7
rts.l


;**********************************************************
;******** receive ONE message from X server **********
;**********************************************************
; input: none *
; output: Z=1: no complete message available *
; r0/r1 undefined *
; Z=0: r0: pointer to message data *
; r1: size of data *
;**********************************************************
x_receive:
move.l r2,-(sp)
move.l r5,-(sp)
move.l r6,-(sp)
_00: move.l buf2_rest,r0 ; still something in read buffer?
cmpq.l #32,r0 ; a message has at least 32 bytes
bhs.b _10 ; maybe it is a complete message

_30: move.l buf2_ptr,r5 ; start of message
move.l #buf2,r6 ; start of buffer
move.l r6,buf2_ptr ; we copy message to top of buffer
cmp.l r5,r6 ; already at top of buffer
beq.b _50 ; then nothing to copy
or.l r0,r0 ; nothing in buffer
beq.b _50 ; then also nothing to copy
move.l r0,r2 ; copy to top of buffer
rep_r2 move.b (r5)+-,(r6)+-{s1}

_50: move.l #buf2l,r1 ; let's try to get some more data
sub.l r0,r1 ; not more bytes than space is left in the buf
lea.l buf2(r0),r0 ; append it here
bsr.l x_receive_raw
bne.b _20 ; we could read something
br.b _100 ; return with Z=1

_20: add.l r0,buf2_rest ; now we have a few more bytes in the buffer
br.b _00 ; let's try again

_10: move.l buf2_ptr,r5 ; let's test if it is a complete meesage
move.l #32,r1 ; error/reply/event base length
cmp.b #1,(r5) ; reply message
bne.b _40 ; no, then event/error messages (always 32 byte)
add.l 4.b(r5),r1 ; + additional data for reply
add.l 4.b(r5),r1 ; + additional data for reply
add.l 4.b(r5),r1 ; + additional data for reply
add.l 4.b(r5),r1 ; + additional data for reply
cmp.l r1,r0 ; complete reply in buffer
blo.b _30 ; no, let's try to get more
_40: move.l r5,r0 ; pointer to data
sub.l r1,buf2_rest ; new rest
add.l r1,buf2_ptr ; pointer to next data; clear Z flag
_100: move.l (sp)+,r6
move.l (sp)+,r5
move.l (sp)+,r2
rts.l

;**********************************************************
;******** read data from X server **********
;**********************************************************
; input: r0: pointer to read buffer *
; r1: size of buffer *
; output: Z=1: nothing to read *
; Z=0: r0 bytes read *
;**********************************************************
x_receive_raw:
move.l r2,-(sp)
move.l r3,-(sp)

moveq.l #0,-(sp) ; flags
move.l r1,-(sp) ; number of bytes to read
move.l r0,-(sp) ; pointer to buffer
move.l x_handle,-(sp) ; socket handle
move.l r7,r2 ; pointer to parameter for "recv"
move.l #10,r3 ; "recv" (/usr/include/linux/net.h)
move.l #102,r0 ; socketcall (/usr/include/asm/unistd.h)
trap #$80
addq.l #4*4,r7 ; free space for parameters
move.l (sp)+,r3
move.l (sp)+,r2
cmpq.l #-11,r0 ; EAGAIN: no message available -> Z=1
beq.b _10

cmp.l #-4095,r0 ; ERROR
bhs.l err

tst.l r0,r0 ; 0: NULL message -> Window close?
beq.l ende

_10: rts.l




;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


;--------------------------- constant data ---------------------------------
even 4,$90

sockaddr_un:
dc.w 1 ; 1: AF_UNIX, AF_LOCAL (/usr/include/linux/socket.h)
dc.b "/tmp/.X11-unix/X0"
sockaddr_un_l= @-sockaddr_un
even 4,$90

;---------------------------------------------------------------------------

code_filez=@@-code_offset
code_memsz= @-code_addr
even 4
@=(@+4095)/4096*4096+(@@\4096)
data_offset=@@
data_addr:

;--------------------------- initialized data ------------------------------
buf2_ptr: dc.l buf2
buf2_rest: dc.l 0

; Connection Setup
send1: dc.b $6c,0 ; LSB first
dc.w 11,0 ; major/minor version
dc.w 0,0 ; length of protocol name/data
dc.w 0 ; unused
send1l=@-send1

; Create Window
send2: dc.b 1 ; opcode for Create Window
dc.b 0 ; depth from parent
dc.w send2l/4; request length
s2a: dc.l 0 ; wid (has to be calculated)
s2b: dc.l 0 ; parent (has to be calculated)
dc.w 0 ; x
dc.w 0 ; y
s2x: dc.w 640 ; with
s2y: dc.w 400 ; higth
dc.w 0 ; border-width
dc.w 0 ; class: CopyFromParent
dc.l 0 ; visual: CopyFromParent
dc.l $a02 ; value-mask: background-pixel 2
; + override-redirect 200
; + event-mask 800
dc.l $000000 ; background: black
dc.b 1 ; override-redirect = true
dc.b 0,0,0 ; pad
dc.l $45 ; event_mask: KeyPress 1
; +ButtenPress 4
; +PointerMotion 40
send2l=((@-send2)+3) & $fffffffc

; Map Window
send3: dc.b 8 ; opcode for Map Window
dc.b 0 ; unused
dc.w send3l/4; request length
s3a: dc.l 0 ; wid (has to be calculated)
send3l=@-send3


; Create GC
send4: dc.b 55 ; opcode for CreateGC
dc.b 0 ; unused
dc.w send4l/4; request length
s4b: dc.l 0 ; cid (has to be calculated)
s4a: dc.l 0 ; wid (has to be calculated)
dc.l 1+4+8 ; function+foreground+background
dc.l 3 ; function=copy
dc.l $ffffff ; foreground: white
dc.l $0080ff ; background: light blue
send4l=@-send4
; Put Image
send5: dc.b 72 ; opcode for PutImage
dc.b 2 ; ZPixmap
dc.w send5l/4+256*10*4/4; request length
s5a: dc.l 0 ; wid (has to be calculated)
s5b: dc.l 0 ; cid (has to be calculated)
dc.w 256 ; width
dc.w 200/20 ; hight; we send 20 parts each 10240 byte (<16k)
s5x: dc.w 0 ; dest-x (inserted later)
s5y: dc.w 0 ; dest-y (inserted later)
dc.b 0 ; left-pad
dc.b 24 ; depth
dc.w 0 ; unused
send5l=@-send5

; Set Input Focus
send6: dc.b 42 ; opcode for SetInputFocus
dc.b 0 ; revert-to None
dc.w send6l/4; request length
s6a: dc.l 0 ; wid (has to be calculated)
dc.l 0 ; timestamp CurrentTime
send6l=@-send6

; Wrap Pointer
send7: dc.b 41 ; opcode for WrapPointer
dc.b 0 ; unused
dc.w send7l/4; request length
dc.l 0 ; src_window
s7a: dc.l 0 ; dst_window wid (has to be calculated)
dc.w 0,0,0,0 ; srx- x,y,width,hight
dc.w $c8,$c8 ; dsr- x,y (200,200)
send7l=@-send7

; Query Pointer
send8: dc.b 38 ; opcode for QueryPointer
dc.b 0 ; unused
dc.w send8l/4; request length
s8a: dc.l 0 ; wid (has to be calculated)
send8l=@-send8


even4

ftab: dc.l 16,$202060,$040404
dc.l 32,$a0a0e0,$020201
dc.l 16,$e0e0ff,$fdfdfe
dc.l 64,$004000,$010201
dc.l 64,$400000,$020201
dc.l 64,$808080,$020202,0

gtab: dc.l $0001,$0003,$0100,$0300,-$0100,-$0300,-$0002
cffff: dc.l $0000ffff

kamera_x: dc.l 1000
kamera_y: dc.l 1000

;--------------------------- uninitialized data ----------------------------

kamera_z: blk.l 1
blackbrush: blk.l 1
rand: blk.l 1
f_tab: blk.l 256
g_hoehe: blk.b 256*256
g_farbe: blk.b 256*256
h_farbe: blk.b 256*256

snull: blk.l 1
vfakt: blk.l 1
dx: blk.l 1
z_alt: blk.l 256
f_alt: blk.l 256
hoehe100: blk.l 1
hoehe170: blk.l 1



screen: blk.l 256*200 ; bitmap
stack_ptr: blk.l 1
x_handle: blk.l 1
fname: blk.b 256+32
buf2: blk.b 1024
buf2l=@-buf2

;---------------------------------------------------------------------------

data_filez=@@-data_offset
data_memsz= @-data_addr

;===========================================================================
From: Frank Kotler on
Herbert Kleebauer wrote:
> Just converted the Erde graphics demo to Linux. Maybe somebody can try it
> (use the mouse to fly, press any key or button to exit).

Works beautifully here! (I didn't use the script - built it with Lindela
from the source). Nice work! Thanks, Herbert!

Best,
Frank

From: Herbert Kleebauer on
Frank Kotler wrote:
> Herbert Kleebauer wrote:
> > Just converted the Erde graphics demo to Linux. Maybe somebody can try it
> > (use the mouse to fly, press any key or button to exit).
>
> Works beautifully here!

Only minor changes were necessary to convert it from Windows
to Linux. Two remaining small problems, maybe you know an answer:

- Does Linux provide a random number? Had to use the time
as a workaround.

- Is there an easy way to hide the cursor without the need to
define a new cursor?


> (I didn't use the script - built it with Lindela
> from the source). Nice work! Thanks, Herbert!

Then you should fix a bug (or download the latest version).
After 14 year of usage, I found that the generated code for
"rotate left byte" is wrong.

_rolb:
get_operand(operand);
dec_operand(operand,&op1);
if (cmps(operand,"#1")) i=1; else i=0;
get_operand(operand);
dec_boperand(operand,&op2);

if ( i && op2.nr >= 3 && op2.nr <= 30 )
{adr_pre(&op2);
seg_pre(&op2);
aus_byte(0xd0);
mod__sib(3,&op2); <- replace by: mod__sib(0,&op2);
goto nextline;
}
From: santosh on
Herbert Kleebauer wrote:

> Frank Kotler wrote:
>> Herbert Kleebauer wrote:
>> > Just converted the Erde graphics demo to Linux. Maybe somebody can try
>> > it (use the mouse to fly, press any key or button to exit).
>>
>> Works beautifully here!
>
> Only minor changes were necessary to convert it from Windows
> to Linux. Two remaining small problems, maybe you know an answer:
>
> - Does Linux provide a random number? Had to use the time
> as a workaround.

Yes just read from /dev/random and/or /dev/urandom.

<snip>