Передача параметров функции USR на BASIC

 Давно, когда WOS еще работал и многие программы были доступными, нашел один пример заливки на экране, в котором код был написан на ассемблере и параметры - координаты и цвет передавались при вызове USR. Недавно решил посмотреть на реализацию, дизассемблировал код.

Тут все плохо:

org 7DA0h


sub_7DA0:
rst 18h
cp 2Ch ; ','       ; Fetch the present character
scf
ret nz
push de
rst 20h ; THE 'COLLECT NEXT CHARACTER' RESTART
call 24FBh ; THE 'SCANNING' SUBROUTINE
pop de
and a
ret

sub_7DAD:
call sub_7DA0
ret c
sub_7DB1:
push de
call 2DA2h ; FP-TO-BC
pop de
jr c, loc_7DBD ; Carry flag set on overflow
jr nz, loc_7DBD
ld a, b
and a
ret z
loc_7DBD:
rst 8
db    4 ; 5 out of screen
call sub_7DAD ; entry PRINT USR l,255,1,2
jr nc, loc_7DC6
loc_7DC4:
rst 8
db  19h ; Q Parameter error
loc_7DC6:
ld d, c
call sub_7DA0
jr c, loc_7DC4

На одном форуме нашлось простое решение:

C41D:            ; PRINT USR 50205, x, y
; Busyho kod pro nacteni parametru primo z Basicu
; PRINT USR 50176,X,Y
  rst   #20         ; 1
  call   #24FB         ; 3
  rst   #20         ; 1
  call   #24FB         ; 3
  call   #2DD5         ; 3
  push   af         ; 1
  call   #2DD5         ; 3
  pop   de         ; 1
  ld    e,a         ; 1

А на свалке программ и исходников другое:
Indirect.ASM [code]
SCANNING: equ  $24fb         ;the SCANNING subroutine
FETCHS: equ  $2bf1           ;from calculator stack: AEDCB
CH_ADD: equ  23645
MEMBOT: equ  23698
;Indirect Variable Assignment
;PRINT USR indirect,arg1,op,arg2;
;op indicates which args are indirect assignments:
;   "<" = left, "<>" (SymSh-W) = both, ">" = right, "=" = neither
INDIRECT:
        ld   hl,14
        add  hl,sp
        ld   sp,hl           ;undo USR
        ld   ix,0
GETARG: rst  $20
        call SCANNING
        ld   a,(iy+1)
        push af              ;save (FLAGS) for each arg
        inc  ix
        rst  $18
        cp   ","
        jr   z,GETARG
        push ix
        pop  bc
        ld   a,c             ;A =number of args
        cp   3
        jp   nz,$288b        ;"Q Parameter error" (wrong number of args)

        ld   ix,(CH_ADD)
        rst  $28
        defb $01,$38         ;swap op.arg to top of calc.stack

        pop  bc
        pop  af              ;A =(FLAGS)
        push bc              ;also swap AF on machine stack
        bit  6,a
        jp   nz,$288b        ;"Q Parameter error" (if numeric)

        call FETCHS
        ld   a,(de)          ;A =op.arg char: "<" ">" "<>"
        res  6,(iy+55)       ;use bit 6 in FLAGX  for loop control
        res  5,(iy+48)       ;use bit 5 in FLAGS2 for loop control
        set  6,(iy+48)       ;use bits 6&7 in FLAGS2 for LH&RH
        set  7,(iy+48)       ;to indicate arg indirection
        cp   $c9             ;="<>"?
        jr   z,OPDONE

Второй вариант понятнее.

Комментарии