TESTER.ASM

Assembly source for MS-DOS 3D engine, 330 lines. Raw file

;	TESTER.ASM - Tester program for LKS 3DOMS.
;	Makes four boxes which share one form, and turns them until Esc is
;	pressed.

.MODEL small
.STACK 1024
.386

JUMPS



;-------- The 3D system.

.CODE

INCLUDE 3DOMS012.INC



;-------- Data.

.DATA

_buffer		dw 0000h	;  Segment of the 64k buffer rendered into.
_universe	dw 0000h	;  Segment of the universe.
_group		dw 0000h	;  Segment of the group holding the boxes.
_form		dw 0000h	;  Segment of the box form.

  ;  Centre for the form and the shape.
_centre		dw 0, 0, 0

  ;  The group: centre, position, rotations and rotation order.  It sits in
  ; front of the viewer and turns the whole scene.
_groupdata	dw 0, 0, 0
		dd 0, 0, -28000
		db 20h, 00h, 00h, RORDER_ZYX

  ;  The four boxes: centre, position, rotations and rotation order.
_objects	dw 0, 0, 0
		dd -8192, -8192, -3072
		db 00h, 00h, 00h, RORDER_XYZ
		dw 0, 0, 0
		dd -8192, 8192, -1024
		db 00h, 00h, 00h, RORDER_XYZ
		dw 0, 0, 0
		dd 8192, 8192, 1024
		db 00h, 00h, 00h, RORDER_XYZ
		dw 0, 0, 0
		dd 8192, -8192, 3072
		db 00h, 00h, 00h, RORDER_XYZ

  ;  The box: 12 faces, two on each side, each in a different grey from the
  ; standard palette.
_faces		dw -4096, 4096, -8192, 4096, -4096, -8192, 4096, 4096, -8192
		db 1Fh, 0
		dw 4096, -4096, -8192, -4096, 4096, -8192, -4096, -4096, -8192
		db 1Eh, 0
		dw 4096, -4096, 8192, -4096, 4096, 8192, 4096, 4096, 8192
		db 1Dh, 0
		dw -4096, -4096, 8192, -4096, 4096, 8192, 4096, -4096, 8192
		db 1Ch, 0
		dw 4096, 4096, 8192, -4096, 4096, -8192, 4096, 4096, -8192
		db 1Bh, 0
		dw -4096, 4096, 8192, -4096, 4096, -8192, 4096, 4096, 8192
		db 1Ah, 0
		dw 4096, -4096, 8192, 4096, -4096, -8192, -4096, -4096, -8192
		db 19h, 0
		dw -4096, -4096, 8192, 4096, -4096, 8192, -4096, -4096, -8192
		db 18h, 0
		dw -4096, 4096, -8192, -4096, 4096, 8192, -4096, -4096, -8192
		db 17h, 0
		dw -4096, -4096, -8192, -4096, 4096, 8192, -4096, -4096, 8192
		db 16h, 0
		dw 4096, 4096, -8192, 4096, -4096, -8192, 4096, 4096, 8192
		db 15h, 0
		dw 4096, -4096, 8192, 4096, 4096, 8192, 4096, -4096, -8192
		db 14h, 0

_msg_title	db 13, 10, 'Tester - LKS 3DOMS tester program.', 13, 10, 13, 10, 0
_msg_heap	db 'Heap: Size = ', 0
_msg_free	db 'h  Free = ', 0
_msg_key	db 'h', 13, 10, 13, 10, 'Press any key...', 0
_msg_nomem	db 'Not enough memory.', 13, 10, 0
_msg_error	db 'ERROR - 3DOMS returned ', 0
_msg_end	db 'h', 13, 10, 0



;-------- Start of code.

.CODE

.STARTUP
  call tester
.EXIT



;-------- Tester.

tester:
  mov si, offset _msg_title
  call print

    ;  Give back the memory the program doesn't use, so there is room for the
    ; buffer and the heap.  ES is still the PSP.
  mov bx, sp
  add bx, 15
  shr bx, 4
  mov ax, ss
  add bx, ax
  mov ax, es
  sub bx, ax
  mov ah, 4Ah
  int 21h
  jc tester_nomem

    ;  Allocate the 64k buffer to render into.
  mov ah, 48h
  mov bx, 1000h
  int 21h
  jc tester_nomem
  mov _buffer, ax

    ;  Log on, asking for a heap of between 128k and 512k.  The universe is
    ; the first cell of the heap.
  mov bx, 1000h
  mov dx, 4000h
  call logon_3doms
  jc tester_nomem
  mov _universe, ax

    ;  Show the size of the heap and how much of it is free.
  mov ah, 00h
  int 3Dh
  push dx
  mov si, offset _msg_heap
  call print
  mov ax, cx
  call print_hex
  mov si, offset _msg_free
  call print
  pop ax
  call print_hex

    ;  Make a group in the universe, to turn the whole scene.
  mov ah, 1Ch
  mov si, offset _groupdata
  mov es, _universe
  int 3Dh
  jc tester_error
  mov _group, ax

    ;  Make the box form, with one shape in it.
  mov ah, 20h
  mov bx, offset _centre
  int 3Dh
  jc tester_error
  mov _form, ax
  mov es, ax
  mov ah, 14h
  mov si, offset _centre
  int 3Dh
  jc tester_error

    ;  Add the 12 faces to the shape.
  mov es, ax
  mov si, offset _faces
  mov cx, 12
tester_face:
  mov ah, 10h
  int 3Dh
  jc tester_error
  add si, 20
  loop tester_face

    ;  Make the four objects in the group, and give each one the box form.
  mov si, offset _objects
  mov cx, 4
tester_object:
  mov ah, 18h
  mov es, _group
  int 3Dh
  jc tester_error
  mov es, ax
  mov ah, 1Bh
  mov bx, _form
  int 3Dh
  jc tester_error
  add si, 22
  loop tester_object

    ;  Wait for a key, then switch to 320x200 in 256 colours.
  mov si, offset _msg_key
  call print
  mov ah, 07h
  int 21h
  mov ax, 0013h
  int 10h

tester_loop:
    ;  Clear the buffer to stripes of colours 1 and 0.
  mov es, _buffer
  xor di, di
  mov cx, 16000
  mov eax, 00010001h
  cld
  rep stosd

    ;  Turn the group a little more each frame.
  push ds
  mov ds, _group
  add byte ptr ds: [G_RX], 1
  add byte ptr ds: [G_RY], 2
  add byte ptr ds: [G_RZ], 4
  pop ds

    ;  Render the universe into the buffer.
  push ds
  mov ah, 80h
  mov ds, _universe
  int 3Dh
  pop ds
  jc tester_error

    ;  Wait for the vertical retrace, then copy the buffer to the screen.
  mov dx, 03DAh
tester_retrace:
  in al, dx
  test al, 08h
  jz tester_retrace
  push ds
  mov ds, _buffer
  xor si, si
  mov ax, 0A000h
  mov es, ax
  xor di, di
  mov cx, 16000
  rep movsd
  pop ds

    ;  Carry on until Esc is let go.
  in al, 60h
  cmp al, 81h
  jne tester_loop

    ;  Back to text mode, and log off.
  mov ax, 0003h
  int 10h
  call logoff_3doms
  ret

    ;  3DOMS returned an error: show it and log off.
tester_error:
  push ax
  mov ax, 0003h
  int 10h
  mov si, offset _msg_error
  call print
  pop ax
  call print_hex
  mov si, offset _msg_end
  call print
  call logoff_3doms
  ret

tester_nomem:
  mov si, offset _msg_nomem
  call print
  ret



;-------- Print.

;  Prints the zero-terminated string at DS:SI.

print:
  push ax
  push dx
  push si
print_loop:
  mov dl, [si]
  or dl, dl
  jz print_end
  mov ah, 02h
  int 21h
  inc si
  jmp print_loop
print_end:
  pop si
  pop dx
  pop ax
  ret



;-------- Print_hex.

;  Prints AX as four hex digits.

print_hex:
  push ax
  push bx
  push cx
  push dx
  mov bx, ax
  mov cx, 4
print_hex_loop:
  rol bx, 4
  mov dl, bl
  and dl, 0Fh
  add dl, '0'
  cmp dl, '9'
  jbe print_hex_digit
  add dl, 7
print_hex_digit:
  mov ah, 02h
  int 21h
  loop print_hex_loop
  pop dx
  pop cx
  pop bx
  pop ax
  ret



END