CPU-Z80-Disassembler
view release on metacpan or search on metacpan
t/data/zx81.asm view on Meta::CPAN
;
;; HEADER
HEADER:
call BREAK_1 ; routine BREAK-1
jr nc, BREAK_2 ; to BREAK-2
;
;; DELAY-1
DELAY_1:
djnz DELAY_1 ; to DELAY-1
;
dec de ;
ld a, d ;
or e ;
jr nz, HEADER ; back for delay to HEADER
;
;; OUT-NAME
OUT_NAME:
call OUT_BYTE ; routine OUT-BYTE
bit 7, (hl) ; test for inverted bit.
inc hl ; address next character of name.
jr z, OUT_NAME ; back if not inverted to OUT-NAME
;
; now start saving the system variables onwards.
ld hl, VERSN ; set start of area to VERSN thereby
; preserving RAMTOP etc.
;
;; OUT-PROG
OUT_PROG:
call OUT_BYTE ; routine OUT-BYTE
;
call LOAD_SAVE ; routine LOAD/SAVE >>
jr OUT_PROG ; loop back to OUT-PROG
;
; -------------------------
; THE 'OUT-BYTE' SUBROUTINE
; -------------------------
; This subroutine outputs a byte a bit at a time to a domestic tape recorder.
;; OUT-BYTE
OUT_BYTE:
ld e, (hl) ; fetch byte to be saved.
scf ; set carry flag - as a marker.
;
;; EACH-BIT
EACH_BIT:
rl e ; C < 76543210 < C
ret z ; return when the marker bit has passed
; right through. >>
;
sbc a, a ; $FF if set bit or $00 with no carry.
and $05 ; $05 $00
add a, $04 ; $09 $04
ld c, a ; transfer timer to C. a set bit has a longer
; pulse than a reset bit.
;
;; PULSES
PULSES:
out ($FF), a ; pulse to cassette.
ld b, $23 ; set timing constant
;
;; DELAY-2
DELAY_2:
djnz DELAY_2 ; self-loop to DELAY-2
;
call BREAK_1 ; routine BREAK-1 test for BREAK key.
;
;; BREAK-2
BREAK_2:
jr nc, REPORT_D ; forward with break to REPORT-D
;
ld b, $1E ; set timing value.
;
;; DELAY-3
DELAY_3:
djnz DELAY_3 ; self-loop to DELAY-3
;
dec c ; decrement counter
jr nz, PULSES ; loop back to PULSES
;
;; DELAY-4
DELAY_4:
and a ; clear carry for next bit test.
djnz DELAY_4 ; self loop to DELAY-4 (B is zero - 256)
;
jr EACH_BIT ; loop back to EACH-BIT
;
; --------------------------
; THE 'LOAD COMMAND' ROUTINE
; --------------------------
;
;
;; LOAD
LOAD:
call NAME ; routine NAME
;
; DE points to start of name in RAM.
rl d ; pick up carry
rrc d ; carry now in bit 7.
;
;; NEXT-PROG
NEXT_PROG:
call IN_BYTE ; routine IN-BYTE
jr NEXT_PROG ; loop to NEXT-PROG
t/data/zx81.asm view on Meta::CPAN
;; IN-NAME
IN_NAME:
call IN_BYTE ; routine IN-BYTE is sort of recursion for name
; part. received byte in C.
bit 7, d ; is name the null string ?
ld a, c ; transfer byte to A.
jr nz, MATCHING ; forward with null string to MATCHING
;
cp (hl) ; else compare with string in memory.
jr nz, NEXT_PROG ; back with mis-match to NEXT-PROG
; (seemingly out of subroutine but return
; address has been dropped).
;
;
;; MATCHING
MATCHING:
inc hl ; address next character of name
rla ; test for inverted bit.
jr nc, IN_NAME ; back if not to IN-NAME
;
; the name has been matched in full.
; proceed to load the data but first increment the high byte of E_LINE, which
; is one of the system variables to be loaded in. Since the low byte is loaded
; before the high byte, it is possible that, at the in-between stage, a false
; value could cause the load to end prematurely - see LOAD/SAVE check.
inc (iy+$15) ; increment system variable E_LINE_hi.
ld hl, VERSN ; start loading at system variable VERSN.
;
;; IN-PROG
IN_PROG:
ld d, b ; set D to zero as indicator.
call IN_BYTE ; routine IN-BYTE loads a byte
ld (hl), c ; insert assembled byte in memory.
call LOAD_SAVE ; routine LOAD/SAVE >>
jr IN_PROG ; loop back to IN-PROG
;
; ---
; this branch assembles a full byte before exiting normally
; from the IN-BYTE subroutine.
;; GET-BIT
GET_BIT:
push de ; save the
ld e, $94 ; timing value.
;
;; TRAILER
TRAILER:
ld b, $1A ; counter to twenty six.
;
;; COUNTER
COUNTER:
dec e ; decrement the measuring timer.
in a, ($FE) ; read the
rla ;
bit 7, e ;
ld a, e ;
jr c, TRAILER ; loop back with carry to TRAILER
;
djnz COUNTER ; to COUNTER
;
pop de ;
jr nz, BIT_DONE ; to BIT-DONE
;
cp $56 ;
jr nc, NEXT_BIT ; to NEXT-BIT
;
;; BIT-DONE
BIT_DONE:
ccf ; complement carry flag
rl c ;
jr nc, NEXT_BIT ; to NEXT-BIT
;
ret ; return with full byte.
;
; ---
; if break is pressed while loading data then perform a reset.
; if break pressed while waiting for program on tape then OK to break.
;; BREAK-4
BREAK_4:
ld a, d ; transfer indicator to A.
and a ; test for zero.
jr z, RESTART ; back if so to RESTART
;
;
;; REPORT-D
REPORT_D:
rst $08 ; ERROR-1
defb $0C ; Error Report: BREAK - CONT repeats
;
; -----------------------------
; THE 'PROGRAM NAME' SUBROUTINE
; -----------------------------
;
;
;; NAME
NAME:
call SCANNING ; routine SCANNING
ld a, (FLAGS) ; sv FLAGS
add a, a ;
jp m, REPORT_C ; to REPORT-C
;
pop hl ;
ret nc ;
push hl ;
( run in 0.477 second using v1.01-cache-2.11-cpan-39bf76dae61 )