Browse Source

Move along, nothing to see here

patch
b1ackmai1er 7 years ago
committed by GitHub
parent
commit
f45e316a8c
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      Source/HBIOS/Build.ps1
  2. 300
      Source/HBIOS/eastaegg.asm
  3. 2
      Source/HBIOS/imgpad.asm
  4. 41
      Source/HBIOS/romldr.asm
  5. 4
      Source/HBIOS/std.asm

3
Source/HBIOS/Build.ps1

@ -163,6 +163,7 @@ Copy-Item '..\zsdos\zsdos.bin' 'zsdos.bin'
Asm 'dbgmon'
Asm 'prefix'
Asm 'romldr'
Asm 'eastaegg'
Asm 'nascom'
Asm 'tastybasic'
Asm 'imgpad'
@ -189,7 +190,7 @@ Concat 'prefix.bin','cpm.bin' 'cpm.sys'
Concat 'prefix.bin','zsys.bin' 'zsys.sys'
# Build 32K OS chunk containing the loader, debug monitor, and OS images
Concat 'romldr.bin', 'dbgmon.bin','cpm.bin','zsys.bin', 'imgpad.bin' osimg.bin
Concat 'romldr.bin', 'dbgmon.bin','cpm.bin','zsys.bin', 'eastaegg.bin', 'imgpad.bin' osimg.bin
Concat 'nascom.bin', 'tastybasic.bin', 'imgpad0.bin' osimg1.bin
#

300
Source/HBIOS/eastaegg.asm

@ -0,0 +1,300 @@
; Adapted from https://rosettacode.org/wiki/Mandelbrot_set#Z80_Assembly
; by Phillip Summers difficultylevelhigh@gmail.com
;
; WBWROM SBV V2 Easteregg
;
; Compute a Mandelbrot set on a simple Z80 computer.
;
; Porting this program to another Z80 platform should be easy and straight-
; forward: The only dependencies on my homebrew machine are the system-calls
; used to print strings and characters. These calls are performed by loading
; IX with the number of the system-call and performing an RST 08. To port this
; program to another operating system just replace these system-calls with
; the appropriate versions. Only three system-calls are used in the following:
; _crlf: Prints a CR/LF, _puts: Prints a 0-terminated string (the adress of
; which is expected in HL), and _putc: Print a single character which is
; expected in A. RST 0 give control back to the monitor.
;
#include "std.asm"
cr .equ 0dh
lf .equ 0ah
eos .equ 00h
.org EGG_LOC
scale .equ 256 ; Do NOT change this - the
; arithmetic routines rely on
; this scaling factor! :-)
divergent .equ scale * 4
ld sp,0fdffh
ld hl, welcome ; Print a welcome message
call _puts
; for (y = <initial_value> ; y <= y_end; y += y_step)
; {
outer_loop ld hl, (y_end) ; Is y <= y_end?
ld de, (y)
and a ; Clear carry
sbc hl, de ; Perform the comparison
jp m, mandel_end ; End of outer loop reached
; for (x = x_start; x <= x_end; x += x_step)
; {
ld hl, (x_start) ; x = x_start
ld (x), hl
inner_loop ld hl, (x_end) ; Is x <= x_end?
ld de, (x)
and a
sbc hl, de
jp m, inner_loop_end ; End of inner loop reached
; z_0 = z_1 = 0;
ld hl, 0
ld (z_0), hl
ld (z_1), hl
; for (iteration = iteration_max; iteration; iteration--)
; {
ld a, (iteration_max)
ld b, a
iteration_loop push bc ; iteration -> stack
; z2 = (z_0 * z_0 - z_1 * z_1) / SCALE;
ld de, (z_1) ; Compute DE HL = z_1 * z_1
ld b,d
ld c,e
call mul_16
ld (z_0_square_low), hl ; z_0 ** 2 is needed later again
ld (z_0_square_high), de
ld de, (z_0) ; Compute DE HL = z_0 * z_0
ld b,d
ld c,e
call mul_16
ld (z_1_square_low), hl ; z_1 ** 2 will be also needed
ld (z_1_square_high), de
and a ; Compute subtraction
ld bc, (z_0_square_low)
sbc hl, bc
ld (scratch_0), hl ; Save lower 16 bit of result
ld h,d
ld l,e
ld bc, (z_0_square_high)
sbc hl, bc
ld bc, (scratch_0) ; HL BC = z_0 ** 2 - z_1 ** 2
ld c, b ; Divide by scale = 256
ld b, l ; Discard the rest
push bc ; We need BC later
; z3 = 2 * z0 * z1 / SCALE;
ld hl, (z_0) ; Compute DE HL = 2 * z_0 * z_1
add hl, hl
ld d,h
ld e,l
ld bc, (z_1)
call mul_16
ld b, e ; Divide by scale (= 256)
ld c, h ; BC contains now z_3
; z1 = z3 + y;
ld hl, (y)
add hl, bc
ld (z_1), hl
; z_0 = z_2 + x;
pop bc ; Here BC is needed again :-)
ld hl, (x)
add hl, bc
ld (z_0), hl
; if (z0 * z0 / SCALE + z1 * z1 / SCALE > 4 * SCALE)
ld hl, (z_0_square_low) ; Use the squares computed
ld de, (z_1_square_low) ; above
add hl, de
ld b,h ; BC contains lower word of sum
ld c,l
ld hl, (z_0_square_high)
ld de, (z_1_square_high)
adc hl, de
ld h, l ; HL now contains (z_0 ** 2 +
ld l, b ; z_1 ** 2) / scale
ld bc, divergent
and a
sbc hl, bc
; break;
jp c, iteration_dec ; No break
pop bc ; Get latest iteration counter
jr iteration_end ; Exit loop
; iteration++;
iteration_dec pop bc ; Get iteration counter
djnz iteration_loop ; We might fall through!
; }
iteration_end
; printf("%c", display[iteration % 7]);
ld a, b
and $7 ; lower three bits only (c = 0)
sbc hl, hl
ld l, a
ld de, display ; Get start of character array
add hl, de ; address and load the
ld a, (hl) ; character to be printed
call _putc ; Print the character
ld de, (x_step) ; x += x_step
ld hl, (x)
add hl, de
ld (x), hl
jp inner_loop
; }
; printf("\n");
inner_loop_end call _putcrlf ; Print a CR/LF pair
ld de, (y_step) ; y += y_step
ld hl, (y)
add hl, de
ld (y), hl ; Store new y-value
jp outer_loop
; }
mandel_end ld hl, finished ; Print finished-message
call _puts
; GET CONSOLE INPUT STATUS VIA HBIOS
waitch LD C,CIODEV_CONSOLE ; CONSOLE UNIT TO C
LD B,BF_CIOIST ; HBIOS FUNC: INPUT STATUS
RST 08 ; HBIOS RETURNS STATUS IN A
; RESTORE REGISTERS (AF IS OUTPUT)
JR Z,waitch
; Return to the loader
LD A,BID_BOOT ; BOOT BANK
LD HL,0 ; ADDRESS ZERO
CALL HB_BNKCALL ; DOES NOT RETURN
HALT
_putcrlf ld hl, crlf
_puts push af
puts0 ld a,(hl)
cp eos
jr z,puts1
call _putc
inc hl
jr puts0
puts1 pop af
ret
_putc PUSH AF
PUSH BC
PUSH DE
PUSH HL
LD E,A ; OUTPUT CHAR TO E
LD C,CIODEV_CONSOLE; CONSOLE UNIT TO C
LD B,BF_CIOOUT ; HBIOS FUNC: OUTPUT CHAR
RST 08 ; HBIOS OUTPUTS CHARACTDR
POP HL
POP DE
POP BC
POP AF
RET
welcome .db "Generating a Mandelbrot set"
.db cr, lf, eos
finished .db "Computation finished."
crlf .db cr, lf, eos
iteration_max .db 10 ; How many iterations
x .dw 0 ; x-coordinate
x_start .dw -2 * scale ; Minimum x-coordinate
x_end .dw 5 * scale / 10 ; Maximum x-coordinate
x_step .dw 4 * scale / 100 ; x-coordinate step-width
y .dw -1 * scale ; Minimum y-coordinate
y_end .dw 1 * scale ; Maximum y-coordinate
y_step .dw 1 * scale / 10 ; y-coordinate step-width
z_0 .dw 0 ;0
z_1 .dw 0 ;0
scratch_0 .dw 0
z_0_square_high .dw 0
z_0_square_low .dw 0
z_1_square_high .dw 0
z_1_square_low .dw 0
display .db " .-+*=#@" ; 8 characters for the display
;
; Compute DEHL = BC * DE (signed): This routine is not too clever but it
; works. It is based on a standard 16-by-16 multiplication routine for unsigned
; integers. At the beginning the sign of the result is determined based on the
; signs of the operands which are negated if necessary. Then the unsigned
; multiplication takes place, followed by negating the result if necessary.
;
mul_16 xor a ; Clear carry and A (-> +)
bit 7, b ; Is BC negative?
jr z, bc_positive ; No
sub c ; A is still zero, complement
ld c, a
ld a, 0
sbc a, b
ld b, a
scf ; Set carry (-> -)
bc_positive bit 7, D ; Is DE negative?
jr z, de_positive ; No
push af ; Remember carry for later!
xor a
sub e
ld e, a
ld a, 0
sbc a, d
ld d, a
pop af ; Restore carry for complement
ccf ; Complement Carry (-> +/-?)
de_positive push af ; Remember state of carry
and a ; Start multiplication
sbc hl, hl
ld a, 16 ; 16 rounds
mul_16_loop add hl, hl
rl e
rl d
jr nc, mul_16_exit
add hl, bc
jr nc, mul_16_exit
inc de
mul_16_exit dec a
jr nz, mul_16_loop
pop af ; Restore carry from beginning
ret nc ; No sign inversion necessary
xor a ; Complement DE HL
sub l
ld l, a
ld a, 0
sbc a, h
ld h, a
ld a, 0
sbc a, e
ld e, a
ld a, 0
sbc a, d
ld d, a
ret
lastbyte .equ $
SLACK .EQU (EGG_END - lastbyte)
.FILL SLACK,'e'
;
.ECHO "EASTEREGG space remaining: "
.ECHO SLACK
.ECHO " bytes.\n"
.end

2
Source/HBIOS/imgpad.asm

@ -1,6 +1,6 @@
#INCLUDE "std.asm"
;
SLACK .EQU ($8000-LDR_SIZ-MON_SIZ-SYS_SIZ-SYS_SIZ)
SLACK .EQU ($8000-LDR_SIZ-MON_SIZ-SYS_SIZ-SYS_SIZ-EGG_SIZ)
.FILL SLACK,00H
;
MON_STACK .EQU $

41
Source/HBIOS/romldr.asm

@ -13,6 +13,7 @@
MONIMG .EQU $0A00 ;SIZE 1000 > 0A00-1A00
CPMIMG .EQU $1A00 ;SIZE 3000 > 1A00-4A00
ZSYSIMG .EQU $4A00 ;SIZE 3000 > 4A00-7A00
EGGIMG .EQU $7A00 ;SIZE 0200 > 7A00-7C00
;
; osimg1.bin
;
@ -20,22 +21,6 @@ BASIMG .EQU $0000 ;SIZE 2000 > 0000-2000
TBCIMG .EQU $2000 ;SIZE 0900 > 2000-2900
;
INT_IM1 .EQU $FF00
;
;----------------------------------------------------------
; NAME NAME OF ROM 8 CHAR
; BANK WHICH ROM BANK THE IMAGE IS IN.
; IMAGE LOCATION OF IMAGE IN 32K ROM BANK.
; LOCATION WHERE IMAGE NEEDS TO BE COPIED TO IN RAM.
; EXECUTE ADDRESS TO START EXECUTING.
;
;ROMTBL .DB "B","BASIC $", 0, BASIMG, BAS_LOC, BAS_SIZ, BASE_LOC
; .DB "C","CP/M $", 0,
; .DB "F","FORTH $", 1,
; .DB "Z","ZSYSTEM$", 1,
;
;
; .DB "MONITOR$", 0,
;
.ORG 0
@ -176,6 +161,8 @@ DB_BOOTLOOP:
JP Z,GOBASIC
CP 'C' ; CP/M BOOT FROM ROM
JP Z,GOCPM
CP 'E' ; CP/M BOOT FROM ROM
JP Z,GOEASTA
CP 'M' ; MONITOR
JP Z,GOMONSER
; CP 'L' ; LIST DRIVES
@ -238,6 +225,8 @@ DB_DSKYEND:
JP Z,GOBASIC
CP 'C' ; CP/M BOOT FROM ROM
JP Z,GOCPM
CP 'E' ; CP/M BOOT FROM ROM
JP Z,GOEASTA
CP 'M' ; MONITOR
JP Z,GOMONSER
; CP 'L' ; LIST DRIVES
@ -283,7 +272,7 @@ GOBASIC:
LD HL,BAS_LOC
JP CHAIN
; LD HL,BAS_LOC
; LD HL,BAS_LOC ; FIRST BANK CODE
; PUSH HL
; LD DE,STR_BOOTBAS ; DE POINTS TO MESSAGE
; CALL WRITESTR ; WRITE IT TO CONSOLE
@ -293,7 +282,21 @@ GOBASIC:
; LD BC,BAS_SIZ ; BC := BASIC SIZE
; LDIR ; COPY BASIC CODE TO EXEC ADDRESS
; POP HL ; RECOVER ENTRY ADDRESS
; JR CHAIN ; AND CHAIN TO IT
; JR CHAIN ; AND CHAIN TO IT
GOEASTA:
LD HL,EGG_LOC
PUSH HL
LD DE,STR_LAUNCH ; DE POINTS TO MESSAGE
CALL WRITESTR ; WRITE IT TO CONSOLE
; COPY IMAGE TO EXEC ADDRESS
LD HL,EGGIMG ; HL := BASIC IMAGE ADDRESS
LD DE,EGG_LOC ; DE := BASIC EXEC ADDRESS
LD BC,EGG_SIZ ; BC := BASIC SIZE
LDIR ; COPY BASIC CODE TO EXEC ADDRESS
POP HL ; RECOVER ENTRY ADDRESS
JR CHAIN ; AND CHAIN TO IT
GOTBAS:
LD DE,STR_BOOTTBC ; DE POINTS TO MESSAGE
@ -315,7 +318,7 @@ GOTBAS:
LD HL,TBC_LOC
JP CHAIN
; LD HL,TBC_LOC
; LD HL,TBC_LOC ; FIRST BANK CODE
; PUSH HL
; LD DE,STR_BOOTTBC ; DE POINTS TO MESSAGE
; CALL WRITESTR ; WRITE IT TO CONSOLE

4
Source/HBIOS/std.asm

@ -378,6 +378,10 @@ TBC_LOC .EQU $0A00 ; TASTYBASIC
TBC_SIZ .EQU $0900
TBC_END .EQU TBC_LOC + TBC_SIZ
EGG_LOC .EQU $0A00 ; EASTER EGG
EGG_SIZ .EQU $0200
EGG_END .EQU EGG_LOC + EGG_SIZ
MON_DSKY .EQU MON_LOC + (0 * 3) ; MONITOR ENTRY (DSKY)
MON_SERIAL .EQU MON_LOC + (1 * 3) ; MONITOR ENTRY (SERIAL PORT)
;

Loading…
Cancel
Save